From 6bceb451760945d68e505c3bb0398b1467a34d35 Mon Sep 17 00:00:00 2001 From: Ren Chen Date: Wed, 12 Jul 2023 16:17:09 +0800 Subject: [PATCH 0001/4498] usb: hid: Call the report proto callback function when the reset occurs This commit changes the protocol callback function is invoked if the HID protocol changed due to reset. Signed-off-by: Ren Chen --- subsys/usb/device/class/hid/core.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/subsys/usb/device/class/hid/core.c b/subsys/usb/device/class/hid/core.c index d05fdae723e..cbe792d6668 100644 --- a/subsys/usb/device/class/hid/core.c +++ b/subsys/usb/device/class/hid/core.c @@ -354,13 +354,22 @@ static void hid_do_status_cb(struct hid_device_info *dev_data, case USB_DC_ERROR: LOG_INF("Device error"); break; - case USB_DC_RESET: + case USB_DC_RESET: { LOG_INF("Device reset detected"); dev_data->configured = false; dev_data->suspended = false; #ifdef CONFIG_USB_HID_BOOT_PROTOCOL + const struct device *dev = dev_data->common.dev; + uint8_t prev = dev_data->protocol; + dev_data->protocol = HID_PROTOCOL_REPORT; + if (prev != HID_PROTOCOL_REPORT) { + if (dev_data->ops && dev_data->ops->protocol_change) { + dev_data->ops->protocol_change(dev, dev_data->protocol); + } + } #endif + } #ifdef CONFIG_USB_DEVICE_SOF hid_clear_idle_ctx(dev_data); #endif From c262ff5be0add940101b276027ec4662e217a10e Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Thu, 13 Oct 2022 11:43:09 -0400 Subject: [PATCH 0002/4498] boards: arm: xmc45_relax_kit: Add memory regions to linker Add memory regions to linker. Signed-off-by: Andriy Gelman --- boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts | 10 ++++++++++ dts/arm/infineon/xmc4500_F100x1024.dtsi | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts index a6fe5e5942c..ec05ae1aa78 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts @@ -57,6 +57,16 @@ }; }; +&psram1 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "PSRAM1"; +}; + +&dsram2 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "DSRAM2"; +}; + &flash_controller { status = "okay"; }; diff --git a/dts/arm/infineon/xmc4500_F100x1024.dtsi b/dts/arm/infineon/xmc4500_F100x1024.dtsi index a085ce5816d..8a84230511d 100644 --- a/dts/arm/infineon/xmc4500_F100x1024.dtsi +++ b/dts/arm/infineon/xmc4500_F100x1024.dtsi @@ -9,7 +9,6 @@ #include / { - /* TODO: Add psram1 & dsram2 to MEMORY layout of linker */ psram1: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 DT_SIZE_K(64)>; From 09577b0a0e2780caef68f07e61fe30ecfd9f41cf Mon Sep 17 00:00:00 2001 From: Warren Buffer Date: Thu, 31 Aug 2023 12:52:39 +0300 Subject: [PATCH 0003/4498] soc: Added support for EFR32MG12P433F1024GM68 Added devicetree and Kconfig for EFR32MG12P433F1024GM68, needed for the BRD4170A radio board by Silicon Labs. Signed-off-by: Warren Buffer --- dts/arm/silabs/efr32mg12p433f1024gm68.dtsi | 25 +++++++++++++++++++ .../efr32mg12p/Kconfig.defconfig.series | 1 + soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc | 4 +++ 3 files changed, 30 insertions(+) create mode 100644 dts/arm/silabs/efr32mg12p433f1024gm68.dtsi diff --git a/dts/arm/silabs/efr32mg12p433f1024gm68.dtsi b/dts/arm/silabs/efr32mg12p433f1024gm68.dtsi new file mode 100644 index 00000000000..dea50625ec9 --- /dev/null +++ b/dts/arm/silabs/efr32mg12p433f1024gm68.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + soc { + compatible = "silabs,efr32mg12p433f1024gm68", "silabs,efr32mg12p", "silabs,efr32", + "simple-bus"; + + flash-controller@400e0000 { + flash0: flash@0 { + reg = <0 DT_SIZE_K(1024)>; + }; + }; + }; +}; diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.series index b2f1e845813..a6881d77861 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES config SOC_PART_NUMBER default "EFR32MG12P332F1024GL125" if SOC_PART_NUMBER_EFR32MG12P332F1024GL125 + default "EFR32MG12P433F1024GM68" if SOC_PART_NUMBER_EFR32MG12P433F1024GM68 config NUM_IRQS # must be >= the highest interrupt number used diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc index 7a42a57a186..8f2f260730d 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc @@ -6,3 +6,7 @@ config SOC_PART_NUMBER_EFR32MG12P332F1024GL125 bool depends on SOC_SERIES_EFR32MG12P + +config SOC_PART_NUMBER_EFR32MG12P433F1024GM68 + bool + depends on SOC_SERIES_EFR32MG12P From 17978182d27ddaafb85e6ca07b638ab5ba205a54 Mon Sep 17 00:00:00 2001 From: Warren Buffer Date: Thu, 31 Aug 2023 12:55:16 +0300 Subject: [PATCH 0004/4498] boards: arm: Added support for Silicon Labs BRD4170A Added support for Silicon Labs' BRD4170A Radio Board, based on the EFR32MG12P SoC. Signed-off-by: Warren Buffer --- boards/arm/efr32_radio/Kconfig.board | 6 ++ boards/arm/efr32_radio/Kconfig.defconfig | 1 + boards/arm/efr32_radio/board.cmake | 2 + .../arm/efr32_radio/efr32_radio_brd4170a.dts | 62 +++++++++++++++++++ .../arm/efr32_radio/efr32_radio_brd4170a.yaml | 20 ++++++ .../efr32_radio_brd4170a_defconfig | 13 ++++ 6 files changed, 104 insertions(+) create mode 100644 boards/arm/efr32_radio/efr32_radio_brd4170a.dts create mode 100644 boards/arm/efr32_radio/efr32_radio_brd4170a.yaml create mode 100644 boards/arm/efr32_radio/efr32_radio_brd4170a_defconfig diff --git a/boards/arm/efr32_radio/Kconfig.board b/boards/arm/efr32_radio/Kconfig.board index 6a9175aa9c3..6104a3884f0 100644 --- a/boards/arm/efr32_radio/Kconfig.board +++ b/boards/arm/efr32_radio/Kconfig.board @@ -11,6 +11,12 @@ config BOARD_EFR32_RADIO_BRD4104A select BOARD_EFR32_RADIO select SOC_PART_NUMBER_EFR32BG13P632F512GM48 +config BOARD_EFR32_RADIO_BRD4170A + bool "Silicon Labs BRD4170A (Mighty Gecko Radio Board)" + depends on SOC_SERIES_EFR32MG12P + select BOARD_EFR32_RADIO + select SOC_PART_NUMBER_EFR32MG12P433F1024GM68 + config BOARD_EFR32_RADIO_BRD4250B bool "Silicon Labs BRD4250B (Flex Gecko Radio Board)" depends on SOC_SERIES_EFR32FG1P diff --git a/boards/arm/efr32_radio/Kconfig.defconfig b/boards/arm/efr32_radio/Kconfig.defconfig index cf4be7c9dde..2ed602da2eb 100644 --- a/boards/arm/efr32_radio/Kconfig.defconfig +++ b/boards/arm/efr32_radio/Kconfig.defconfig @@ -8,6 +8,7 @@ if BOARD_EFR32_RADIO config BOARD default "efr32_radio_brd4104a" if BOARD_EFR32_RADIO_BRD4104A + default "efr32_radio_brd4170a" if BOARD_EFR32_RADIO_BRD4170A default "efr32_radio_brd4250b" if BOARD_EFR32_RADIO_BRD4250B default "efr32_radio_brd4180a" if BOARD_EFR32_RADIO_BRD4180A default "efr32_radio_brd4187c" if BOARD_EFR32_RADIO_BRD4187C diff --git a/boards/arm/efr32_radio/board.cmake b/boards/arm/efr32_radio/board.cmake index c43175d6b01..95eaa403fcb 100644 --- a/boards/arm/efr32_radio/board.cmake +++ b/boards/arm/efr32_radio/board.cmake @@ -6,6 +6,8 @@ if(CONFIG_BOARD_EFR32_RADIO_BRD4104A) board_runner_args(jlink "--device=EFR32BG13PxxxF512") elseif(CONFIG_BOARD_EFR32_RADIO_BRD4250B) board_runner_args(jlink "--device=EFR32FG1PxxxF256") +elseif(CONFIG_BOARD_EFR32_RADIO_BRD4170A) +board_runner_args(jlink "--device=EFR32MG12PxxxF1024") elseif(CONFIG_BOARD_EFR32_RADIO_BRD4180A) board_runner_args(jlink "--device=EFR32MG21AxxxF1024") elseif(CONFIG_BOARD_EFR32_RADIO_BRD4187C) diff --git a/boards/arm/efr32_radio/efr32_radio_brd4170a.dts b/boards/arm/efr32_radio/efr32_radio_brd4170a.dts new file mode 100644 index 00000000000..effd66a8515 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4170a.dts @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 Piotr Mienkowski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "efr32_radio.dtsi" + +/ { + model = "Silicon Labs BRD4170A (Mighty Gecko Radio Board)"; + compatible = "silabs,efr32_radio_brd4170a", "silabs,efr32mg12p"; + + aliases { + spi-flash0 = &mx25r80; + }; +}; + +&cpu0 { + clock-frequency = <38400000>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 32 kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x00008000>; + read-only; + }; + + /* Reserve 220 kB for the application in slot 0 */ + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 0x00037000>; + }; + + /* Reserve 220 kB for the application in slot 1 */ + slot1_partition: partition@3f000 { + label = "image-1"; + reg = <0x0003f000 0x00037000>; + }; + + /* Reserve 32 kB for the scratch partition */ + scratch_partition: partition@76000 { + label = "image-scratch"; + reg = <0x00076000 0x00008000>; + }; + + /* Set 8Kb of storage at the end of the 512KB of flash */ + storage_partition: partition@7e000 { + label = "storage"; + reg = <0x0007e000 0x00002000>; + }; + + }; +}; diff --git a/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml new file mode 100644 index 00000000000..6a231fa7db1 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml @@ -0,0 +1,20 @@ +identifier: efr32_radio_brd4170a +name: BRD4170A +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio + - nvs + - spi + - uart + - watchdog +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/efr32_radio/efr32_radio_brd4170a_defconfig b/boards/arm/efr32_radio/efr32_radio_brd4170a_defconfig new file mode 100644 index 00000000000..32222b89b31 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4170a_defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_SOC_SERIES_EFR32MG12P=y +CONFIG_BOARD_EFR32_RADIO_BRD4170A=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 +CONFIG_CMU_HFCLK_HFXO=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y From 610125418f794cc25c607fd3fa8a854f1f9aa565 Mon Sep 17 00:00:00 2001 From: Warren Buffer Date: Thu, 31 Aug 2023 14:32:00 +0300 Subject: [PATCH 0005/4498] boards: arm: efr32_radio_brd4170a: Added docs Added documentation for Silicon Labs' BRD4170A Radio board Signed-off-by: Warren Buffer --- boards/arm/efr32_radio/doc/brd4170a.rst | 109 ++++++++++++++++++ .../efr32_radio/doc/efr32mg12-slwrb4170a.jpg | Bin 0 -> 27302 bytes boards/arm/efr32_radio/doc/index.rst | 1 + 3 files changed, 110 insertions(+) create mode 100644 boards/arm/efr32_radio/doc/brd4170a.rst create mode 100644 boards/arm/efr32_radio/doc/efr32mg12-slwrb4170a.jpg diff --git a/boards/arm/efr32_radio/doc/brd4170a.rst b/boards/arm/efr32_radio/doc/brd4170a.rst new file mode 100644 index 00000000000..9924c2b1d1a --- /dev/null +++ b/boards/arm/efr32_radio/doc/brd4170a.rst @@ -0,0 +1,109 @@ +.. _efr32_radio_brd4170a: + +EFR32 BRD4170A (SLWRB4170A) +########################### + +Overview +******** + +The EFR32MG12 Mighty Gecko Radio Board contains a Wireless System-On-Chip +from the EFR32MG12 family built on an ARM Cortex®-M4F processor with excellent +low power capabilities. + +.. figure:: efr32mg12-slwrb4170a.jpg + :align: center + :alt: SLWRB4170A Mighty Gecko Radio Board + + SLWRB4170A (image courtesy of Silicon Labs) + +The BRD4170A a.k.a. SLWRB4170A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. + +Hardware +******** + +- EFR32MG12P433F1024GM68 Mighty Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 1024 kB +- RAM: 256 kB +- Transmit power: up to +19 dBm +- Operation frequency: 2.4 GHz and Sub-Ghz +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32MG12 SoC and BRD4170A board, refer to these +documents: + +- `EFR32MG12 Website`_ +- `EFR32MG12 Datasheet`_ +- `EFR32xG12 Reference Manual`_ +- `BRD4170A User Guide`_ + +Supported Features +================== + +Please refer to +:ref:`EFR32 Radio Board Supported Features ` +for details of the configuration and common features supported by the +efr32_radio_brd4170a board. + +The default configuration can be found in the defconfig file: + + ``boards/arm/efr32_radio/efr32_radio_brd4170a_defconfig`` + +System Clock +============ + +The EFR32MG12P SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32MG12P SoC has four USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Please refer to +:ref:`Programming and Debugging EFR32 Radio Board ` +for details on the supported debug interfaces. + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4170A radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: efr32_radio_brd4170a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! efr32_radio_brd4170a + + +.. _EFR32MG12 Website: + https://www.silabs.com/wireless/zigbee/efr32mg12-series-1-socs + +.. _EFR32MG12 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf + +.. _EFR32xG12 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf + +.. _BRD4170A User Guide: + https://www.silabs.com/documents/public/user-guides/ug342-brd4170a-user-guide.pdf diff --git a/boards/arm/efr32_radio/doc/efr32mg12-slwrb4170a.jpg b/boards/arm/efr32_radio/doc/efr32mg12-slwrb4170a.jpg new file mode 100644 index 0000000000000000000000000000000000000000..516438918cb3bfb3099573b7271674c8ffb24b8a GIT binary patch literal 27302 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 Date: Fri, 1 Sep 2023 13:55:07 +0300 Subject: [PATCH 0006/4498] arch: riscv: Trap handler alignment configuration RISC-V Spec requires minimum alignment of trap handling code to be dependent from MTVEC.BASE field size. Minimum alignment for RISC-V platforms is 4 bytes, but maximum is platform or application-specific. Currently there is no common approach to align the trap handling code for RISC-V and some platforms use custom wrappers to align _isr_wrapper properly. This change introduces a generic solution, CONFIG_RISCV_TRAP_HANDLER_ALIGNMENT configuration option which sets the alignment of a RISC-V trap handling code. The existing custom solutions for some platforms remain operational, since the default alignment is set to minimal possible (4 bytes) and will be overloaded by potentially larger alignment of custom solutions. Signed-off-by: Alexander Razinkov --- arch/riscv/Kconfig | 9 +++++++++ arch/riscv/core/isr.S | 3 +++ 2 files changed, 12 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index c008d4184a0..a1cefcbdf43 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -323,6 +323,15 @@ config CMSIS_V2_THREAD_MAX_STACK_SIZE config ARCH_IRQ_VECTOR_TABLE_ALIGN default 256 +config RISCV_TRAP_HANDLER_ALIGNMENT + int "Alignment of RISC-V trap handler in bytes" + default 4 + help + This value configures the alignment of RISC-V trap handling + code. The requirement for a particular alignment arises from + the format of MTVEC register which is RISC-V platform-specific. + The minimum alignment is 4 bytes according to the Spec. + config GEN_IRQ_VECTOR_TABLE select RISCV_VECTORED_MODE if SOC_FAMILY_RISCV_PRIVILEGED diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 75e3ef2e02d..ab90d2b1d1e 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -103,6 +103,9 @@ GTEXT(_isr_wrapper) */ SECTION_FUNC(exception.entry, _isr_wrapper) +/* Provide requested alignment, which depends e.g. on MTVEC format */ +.balign CONFIG_RISCV_TRAP_HANDLER_ALIGNMENT + #ifdef CONFIG_USERSPACE /* retrieve address of _current_cpu preserving s0 */ csrrw s0, mscratch, s0 From ad498aa55006954e72f65e05923f274931157b7e Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Mon, 4 Sep 2023 10:35:30 +0200 Subject: [PATCH 0007/4498] usb: device: hid: remove CONFIG_USB_HID_PROTOCOL_CODE Kconfig option USB_HID_PROTOCOL_CODE, deprecated in v2.6, is finally removed. Signed-off-by: Johann Fischer --- doc/releases/release-notes-3.5.rst | 3 +++ subsys/usb/device/class/hid/Kconfig | 9 --------- subsys/usb/device/class/hid/core.c | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 1c2a38edcf2..53d4d2d9172 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -263,6 +263,9 @@ Networking USB *** +* USB device HID + * Kconfig option USB_HID_PROTOCOL_CODE, deprecated in v2.6, is finally removed. + Devicetree ********** diff --git a/subsys/usb/device/class/hid/Kconfig b/subsys/usb/device/class/hid/Kconfig index 4afcc83368d..c95b8038261 100644 --- a/subsys/usb/device/class/hid/Kconfig +++ b/subsys/usb/device/class/hid/Kconfig @@ -65,13 +65,4 @@ config USB_HID_BOOT_PROTOCOL See Chapter 4.2 of Device Class Definition for Human Interface Devices 1.11 for more information. -config USB_HID_PROTOCOL_CODE - int "HID Boot Interface protocol code (DEPRECATED)" - default 0 - range 0 2 - depends on USB_HID_BOOT_PROTOCOL - help - This option is deprecated. - Please use usb_hid_set_proto_code() instead. - endif # USB_DEVICE_HID diff --git a/subsys/usb/device/class/hid/core.c b/subsys/usb/device/class/hid/core.c index cbe792d6668..442f1a4a0f0 100644 --- a/subsys/usb/device/class/hid/core.c +++ b/subsys/usb/device/class/hid/core.c @@ -59,7 +59,7 @@ struct usb_hid_config { .bNumEndpoints = 1, \ .bInterfaceClass = USB_BCC_HID, \ .bInterfaceSubClass = 1, \ - .bInterfaceProtocol = CONFIG_USB_HID_PROTOCOL_CODE, \ + .bInterfaceProtocol = 0, \ .iInterface = 0, \ } #else From 2c95b6944f5b19208ea0c86d3a4b41a0fafe9a60 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Tue, 5 Sep 2023 14:01:16 +0200 Subject: [PATCH 0008/4498] scripts: tests: twister: Testsuite test fix Previous tests didn't take b48c3cd into account. This fix restores previously passing tests. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_testsuite.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/scripts/tests/twister/test_testsuite.py b/scripts/tests/twister/test_testsuite.py index 49f19d0d0f8..3e12323d723 100644 --- a/scripts/tests/twister/test_testsuite.py +++ b/scripts/tests/twister/test_testsuite.py @@ -429,7 +429,8 @@ def test_get_search_area_boundary( ( os.path.join('dummy', 'path'), ['testsuite_file_1', 'testsuite_file_2'], - ['src_dir_file_1', 'src_dir_file_2'], + ['src_dir_file_1', 'src_dir_file_2', 'src_dir_file_3'], + {'src_dir_file_1': 1000, 'src_dir_file_2': 2000, 'src_dir_file_3': 0}, { 'testsuite_file_1': ScanPathResult( matches = ['test_a', 'b'], @@ -449,11 +450,12 @@ def test_get_search_area_boundary( ztest_suite_names = ['feature_b'] ), 'src_dir_file_2': ValueError, + 'src_dir_file_3': ValueError, }, [ 'testsuite_file_2: can\'t find: dummy exception', 'testsuite_file_1: dummy warning', - 'src_dir_file_2: can\'t find: dummy exception', + 'src_dir_file_2: error parsing source file: dummy exception', ], None, (['a', 'b', 'test_a', 'test_b'], ['feature_a', 'feature_b']) @@ -462,6 +464,7 @@ def test_get_search_area_boundary( os.path.join('dummy', 'path'), [], ['src_dir_file'], + {'src_dir_file': 1000}, { 'src_dir_file': ScanPathResult( matches = ['test_b', 'a'], @@ -486,6 +489,7 @@ def test_get_search_area_boundary( os.path.join('dummy', 'path'), [], ['src_dir_file'], + {'src_dir_file': 100}, { 'src_dir_file': ScanPathResult( matches = ['test_b', 'a'], @@ -504,13 +508,13 @@ def test_get_search_area_boundary( @pytest.mark.parametrize( - 'testsuite_path, testsuite_glob, src_dir_glob, scanpathresults,' \ + 'testsuite_path, testsuite_glob, src_dir_glob, sizes, scanpathresults,' \ ' expected_logs, expected_exception, expected', TESTDATA_7, ids=[ 'valid', 'warning in src dir', - 'register with run error' + 'register with run error', ] ) def test_scan_testsuite_path( @@ -518,6 +522,7 @@ def test_scan_testsuite_path( testsuite_path, testsuite_glob, src_dir_glob, + sizes, scanpathresults, expected_logs, expected_exception, @@ -540,9 +545,16 @@ def mock_sf(filename, *args, **kwargs): raise scanpathresults[filename]('dummy exception') return scanpathresults[filename] + def mock_stat(filename, *args, **kwargs): + result = mock.Mock() + type(result).st_size = sizes[filename] + + return result + with mock.patch('twisterlib.testsuite._find_src_dir_path', mock_fsdp), \ mock.patch('glob.glob', mock_glob), \ mock.patch('twisterlib.testsuite.scan_file', mock_sf), \ + mock.patch('os.stat', mock_stat), \ pytest.raises(type(expected_exception)) if \ expected_exception else nullcontext() as exception: result = scan_testsuite_path(testsuite_path) From 9b29c2cf33350e4ea41863dd8ecbce7ef37b0de4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 15 Aug 2023 11:51:13 +0000 Subject: [PATCH 0009/4498] west: add entries for missing modules Add maintainer entries for two missing modules. Signed-off-by: Fabio Baltieri --- MAINTAINERS.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8d581406981..0a446919631 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2902,6 +2902,15 @@ West: labels: - "area: West" +"West project: acpica": + status: maintained + maintainers: + - najumon1980 + files: + - modules/acpica/ + labels: + - manifest-acpica + "West project: canopennode": status: maintained maintainers: @@ -3009,6 +3018,15 @@ West: labels: - "platform: ESP32" +"West project: hal_ethos_u": + status: maintained + maintainers: + - kristofer-jonsson-arm + files: + - modules/hal_ethos_u/ + labels: + - manifest-hal_ethos_u + "West project: hal_gigadevice": status: maintained maintainers: From dd4ef7d2b5e15d53d3fa5a1566a7463319315495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Jakie=C5=82a?= Date: Tue, 1 Aug 2023 12:58:05 +0000 Subject: [PATCH 0010/4498] drivers: sensor: Add PM support to LM75 digital temperature sensor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for device power management. When the sensor is not powered, the fetch function will fail. When the sensor is not connected to a power domain, it will behave as usual. Signed-off-by: Albert Jakieła --- drivers/sensor/lm75/lm75.c | 59 +++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/lm75/lm75.c b/drivers/sensor/lm75/lm75.c index 5e117bb9b7c..e01a691a58e 100644 --- a/drivers/sensor/lm75/lm75.c +++ b/drivers/sensor/lm75/lm75.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include LOG_MODULE_REGISTER(LM75, CONFIG_SENSOR_LOG_LEVEL); @@ -62,14 +64,26 @@ static int lm75_sample_fetch(const struct device *dev, { struct lm75_data *data = dev->data; const struct lm75_config *cfg = dev->config; + enum pm_device_state pm_state; + int ret; + + (void)pm_device_state_get(dev, &pm_state); + if (pm_state != PM_DEVICE_STATE_ACTIVE) { + ret = -EIO; + return ret; + } switch (chan) { case SENSOR_CHAN_ALL: case SENSOR_CHAN_AMBIENT_TEMP: - return lm75_fetch_temp(cfg, data); + ret = lm75_fetch_temp(cfg, data); + break; default: - return -ENOTSUP; + ret = -ENOTSUP; + break; } + + return ret; } static int lm75_channel_get(const struct device *dev, @@ -96,21 +110,52 @@ static const struct sensor_driver_api lm75_driver_api = { int lm75_init(const struct device *dev) { const struct lm75_config *cfg = dev->config; + int ret = 0; - if (device_is_ready(cfg->i2c.bus)) { - return 0; + if (!device_is_ready(cfg->i2c.bus)) { + LOG_ERR("I2C dev not ready"); + return -ENODEV; } - LOG_ERR("I2C dev not ready"); - return -ENODEV; +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_init_suspended(dev); + + ret = pm_device_runtime_enable(dev); + if (ret < 0 && ret != -ENOTSUP) { + LOG_ERR("Failed to enable runtime power management"); + return ret; + } +#endif + + return ret; } +#ifdef CONFIG_PM_DEVICE + +static int lm75_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_RESUME: + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_SUSPEND: + break; + default: + return -ENOTSUP; + } + + return 0; +} + +#endif + #define LM75_INST(inst) \ static struct lm75_data lm75_data_##inst; \ static const struct lm75_config lm75_config_##inst = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ }; \ -SENSOR_DEVICE_DT_INST_DEFINE(inst, lm75_init, NULL, &lm75_data_##inst, \ +PM_DEVICE_DT_INST_DEFINE(inst, lm75_pm_action); \ +SENSOR_DEVICE_DT_INST_DEFINE(inst, lm75_init, PM_DEVICE_DT_INST_GET(inst), &lm75_data_##inst, \ &lm75_config_##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &lm75_driver_api); From 6bf26a1590b7f94a1baefcf8be280296341cad27 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 5 Sep 2023 09:06:46 +0200 Subject: [PATCH 0011/4498] west.yml: update modules/hal/st with new sensor/vl53l1x version Update the ../modules/hal/st/sensor/vl53l1x to version 2.4.5 Signed-off-by: Francois Ramu --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 727d6d807ab..a87d3ab9b09 100644 --- a/west.yml +++ b/west.yml @@ -224,7 +224,7 @@ manifest: groups: - hal - name: hal_st - revision: 9b128caf3e7b2e750169b880e83f210ea2213473 + revision: fb8e79d1a261fd02aadff7c142729f1954163cf3 path: modules/hal/st groups: - hal From fa4f15a7d52810df9c0b765c6f4565011e3908d0 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Tue, 5 Sep 2023 22:54:50 +0200 Subject: [PATCH 0012/4498] tests: net: conn_mgr_monitor: increase stack size Fixes the broken conn_mgr_monitor test. Signed-off-by: Florian Grandel --- tests/net/conn_mgr_monitor/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/net/conn_mgr_monitor/prj.conf b/tests/net/conn_mgr_monitor/prj.conf index 1e60d8327ed..f68f3f09fdc 100644 --- a/tests/net/conn_mgr_monitor/prj.conf +++ b/tests/net/conn_mgr_monitor/prj.conf @@ -23,6 +23,7 @@ CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y +CONFIG_NET_MGMT_EVENT_STACK_SIZE=1024 # Enable for help debugging this test suite: # CONFIG_NET_LOG=y From a92008c17d13a902705da8caf787f9e9deb5ed26 Mon Sep 17 00:00:00 2001 From: Richard Wheatley Date: Tue, 5 Sep 2023 09:54:39 -0500 Subject: [PATCH 0013/4498] soc: arm: ambiq: apollo4: add simobuck init to apollo4 init Adds comments and simobuck init function for low power. Signed-off-by: Richard Wheatley --- soc/arm/ambiq/apollo4x/soc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soc/arm/ambiq/apollo4x/soc.c b/soc/arm/ambiq/apollo4x/soc.c index 30288ad12c3..225f5013441 100644 --- a/soc/arm/ambiq/apollo4x/soc.c +++ b/soc/arm/ambiq/apollo4x/soc.c @@ -10,7 +10,14 @@ static int arm_apollo4_init(void) { + + /* Initialize for low power in the power control block */ am_hal_pwrctrl_low_power_init(); + + /* Enable SIMOBUCK for the Apollo4 Family */ + am_hal_pwrctrl_control(AM_HAL_PWRCTRL_CONTROL_SIMOBUCK_INIT, 0); + + /* Disable the RTC. */ am_hal_rtc_osc_disable(); return 0; From aa608d016d18e7714e9d718040b0e82dca76d16b Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 30 Aug 2023 15:38:45 +0200 Subject: [PATCH 0014/4498] manifest: Update TF-M with shared boot data fix Update TF-M version with fix for build with shared boot data enabled, i.e. CONFIG_TFM_MCUBOOT_DATA_SHARING=y. Regression from: 485fa940aacb2ae810dd722366f46386d93839ca Signed-off-by: Joakim Andersson --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a87d3ab9b09..ece58ad1d97 100644 --- a/west.yml +++ b/west.yml @@ -331,7 +331,7 @@ manifest: groups: - debug - name: trusted-firmware-m - revision: 8b6146261fe2c0ad61154e20c7e338601eae2208 + revision: b168d92c7ed3c77c94d7ce3362bdde5dbffe8424 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 95ac71893c62b317eba9f1f899e67c0f7fa12f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Thu, 31 Aug 2023 14:43:43 +0200 Subject: [PATCH 0015/4498] Bluetooth: Test: Add tests to reproduce SMP issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test reproduce two issues, #59788 and #61465. Signed-off-by: Théo Battrel --- tests/bsim/bluetooth/host/compile.sh | 1 + .../security_changed_callback/CMakeLists.txt | 18 ++ .../security_changed_callback/prj.conf | 24 +++ .../src/bs_bt_utils.c | 188 ++++++++++++++++++ .../src/bs_bt_utils.h | 79 ++++++++ .../security_changed_callback/src/central.c | 39 ++++ .../security_changed_callback/src/main.c | 47 +++++ .../src/peripheral.c | 108 ++++++++++ .../test_scripts/_compile.sh | 18 ++ .../test_scripts/security_changed_callback.sh | 35 ++++ 10 files changed, 557 insertions(+) create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/prj.conf create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.c create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.h create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/src/central.c create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/src/main.c create mode 100644 tests/bsim/bluetooth/host/security/security_changed_callback/src/peripheral.c create mode 100755 tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/security_changed_callback.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index a54dbd26507..6dcdddc3406 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -70,6 +70,7 @@ app=tests/bsim/bluetooth/host/security/bond_per_connection compile app=tests/bsim/bluetooth/host/security/ccc_update compile app=tests/bsim/bluetooth/host/security/ccc_update conf_file=prj_2.conf compile app=tests/bsim/bluetooth/host/security/id_addr_update compile +app=tests/bsim/bluetooth/host/security/security_changed_callback compile app=tests/bsim/bluetooth/host/id/settings compile diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/CMakeLists.txt b/tests/bsim/bluetooth/host/security/security_changed_callback/CMakeLists.txt new file mode 100644 index 00000000000..e6dcda9d49a --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_security_changed_callback) + +target_sources(app PRIVATE + src/bs_bt_utils.c + src/central.c + src/main.c + src/peripheral.c +) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/prj.conf b/tests/bsim/bluetooth/host/security/security_changed_callback/prj.conf new file mode 100644 index 00000000000..abf1bd7ffb7 --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/prj.conf @@ -0,0 +1,24 @@ +CONFIG_BT_TESTING=y + +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y + +CONFIG_BT_SMP=y +CONFIG_BT_PRIVACY=y + +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_NVS=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS_NVS=y + +CONFIG_ASSERT=y + +CONFIG_LOG=y +CONFIG_BT_SMP_LOG_LEVEL_DBG=y + +CONFIG_THREAD_NAME=y +CONFIG_LOG_THREAD_ID_PREFIX=y diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.c new file mode 100644 index 00000000000..3f9fabe544a --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_bt_utils.h" + +#include +#include + +LOG_MODULE_REGISTER(bs_bt_utils, LOG_LEVEL_DBG); + +#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * 1000000) +#define TEST_TIMEOUT_SIMULATED BS_SECONDS(60) + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +DEFINE_FLAG(flag_is_connected); +struct bt_conn *g_conn; + +void wait_connected(void) +{ + LOG_DBG("Wait for connection..."); + WAIT_FOR_FLAG(flag_is_connected); +} + +void wait_disconnected(void) +{ + WAIT_FOR_FLAG_UNSET(flag_is_connected); +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + LOG_DBG("security changed"); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + UNSET_FLAG(flag_is_connected); +} + +static void connected(struct bt_conn *conn, uint8_t err) +{ + ASSERT((!g_conn || (conn == g_conn)), "Unexpected new connection."); + + if (!g_conn) { + g_conn = bt_conn_ref(conn); + } + + if (err != 0) { + clear_g_conn(); + return; + } + + SET_FLAG(flag_is_connected); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, + .security_changed = security_changed, +}; + +void clear_g_conn(void) +{ + struct bt_conn *conn; + + conn = g_conn; + g_conn = NULL; + ASSERT(conn, "Test error: No g_conn!\n"); + bt_conn_unref(conn); +} + +/* The following flags are raised by events and lowered by test code. */ +DEFINE_FLAG(flag_pairing_complete); +DEFINE_FLAG(flag_bonded); +DEFINE_FLAG(flag_not_bonded); + +static void pairing_complete(struct bt_conn *conn, bool bonded) +{ + LOG_INF("pairing complete"); + SET_FLAG(flag_pairing_complete); + + if (bonded) { + SET_FLAG(flag_bonded); + LOG_DBG("Bonded status: true"); + } else { + SET_FLAG(flag_not_bonded); + LOG_DBG("Bonded status: false"); + } +} + +static void pairing_failed(struct bt_conn *conn, enum bt_security_err err) +{ + LOG_INF("Pairing failed"); +} + +static struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { + .pairing_complete = pairing_complete, + .pairing_failed = pairing_failed, +}; + +void bs_bt_utils_setup(void) +{ + int err; + + err = bt_enable(NULL); + ASSERT(!err, "bt_enable failed.\n"); + err = bt_conn_auth_info_cb_register(&bt_conn_auth_info_cb); + ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); + + err = settings_load(); + if (err) { + FAIL("Settings load failed (err %d)\n", err); + } +} + +static void stop_scan_and_connect(const bt_addr_le_t *addr, + int8_t rssi, + uint8_t type, + struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + int err; + + if (g_conn != NULL) { + return; + } + + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Got scan result, connecting.. dst %s, RSSI %d\n", addr_str, rssi); + + err = bt_le_scan_stop(); + ASSERT(!err, "Err bt_le_scan_stop %d", err); + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn); + ASSERT(!err, "Err bt_conn_le_create %d", err); +} + +void scan_connect_to_first_result(void) +{ + int err; + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, stop_scan_and_connect); + ASSERT(!err, "Err bt_le_scan_start %d", err); +} + +void set_security(bt_security_t sec) +{ + int err; + + err = bt_conn_set_security(g_conn, sec); + ASSERT(!err, "Err bt_conn_set_security %d", err); +} + +void advertise_connectable(int id, bt_addr_le_t *directed_dst) +{ + int err; + struct bt_le_adv_param param = {}; + + param.id = id; + param.interval_min = 0x0020; + param.interval_max = 0x4000; + param.options |= BT_LE_ADV_OPT_ONE_TIME; + param.options |= BT_LE_ADV_OPT_CONNECTABLE; + + if (directed_dst) { + param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; + param.peer = directed_dst; + } + + err = bt_le_adv_start(¶m, NULL, 0, NULL, 0); + ASSERT(err == 0, "Advertising failed to start (err %d)\n", err); +} diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.h new file mode 100644 index 00000000000..ed6cea0d5ef --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/src/bs_bt_utils.h @@ -0,0 +1,79 @@ +/** + * Common functions and helpers for BSIM tests + * + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_tracing.h" +#include "bs_types.h" +#include "bstests.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern enum bst_result_t bst_result; + +#define DECLARE_FLAG(flag) extern atomic_t flag +#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG_UNSET(flag) \ + while ((bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define TAKE_FLAG(flag) \ + while (!(bool)atomic_cas(&flag, true, false)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define GET_FLAG(flag) (bool)atomic_get(&flag) + +#define ASSERT(expr, ...) \ + do { \ + if (!(expr)) { \ + FAIL(__VA_ARGS__); \ + } \ + } while (0) + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +void test_tick(bs_time_t HW_device_time); +void test_init(void); + +DECLARE_FLAG(flag_pairing_complete); +DECLARE_FLAG(flag_bonded); +DECLARE_FLAG(flag_not_bonded); + +extern struct bt_conn *g_conn; +void wait_connected(void); +void wait_disconnected(void); +void clear_g_conn(void); +void bs_bt_utils_setup(void); +void scan_connect_to_first_result(void); +void set_security(bt_security_t sec); +void advertise_connectable(int id, bt_addr_le_t *directed_dst); +void set_bondable(bool enable); diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/src/central.c b/tests/bsim/bluetooth/host/security/security_changed_callback/src/central.c new file mode 100644 index 00000000000..abf896d8618 --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/src/central.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#include "bs_bt_utils.h" + +LOG_MODULE_REGISTER(test_central, LOG_LEVEL_DBG); + +BUILD_ASSERT(CONFIG_BT_BONDABLE, "CONFIG_BT_BONDABLE must be enabled by default."); + +void central(void) +{ + LOG_DBG("===== Central ====="); + + bs_bt_utils_setup(); + + scan_connect_to_first_result(); + wait_connected(); + set_security(BT_SECURITY_L2); + + TAKE_FLAG(flag_pairing_complete); + TAKE_FLAG(flag_bonded); + + LOG_DBG("Wait for disconnection..."); + wait_disconnected(); + + clear_g_conn(); + + PASS("PASS\n"); +} diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/src/main.c b/tests/bsim/bluetooth/host/security/security_changed_callback/src/main.c new file mode 100644 index 00000000000..07bf437f8fa --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/src/main.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_bt_utils.h" +#include "bstests.h" + +void central(void); +void peripheral_unpair_in_sec_cb(void); +void peripheral_disconnect_in_sec_cb(void); + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "central", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = central, + }, + { + .test_id = "peripheral_unpair_in_sec_cb", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = peripheral_unpair_in_sec_cb, + }, + { + .test_id = "peripheral_disconnect_in_sec_cb", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = peripheral_disconnect_in_sec_cb, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/src/peripheral.c b/tests/bsim/bluetooth/host/security/security_changed_callback/src/peripheral.c new file mode 100644 index 00000000000..56c351efb05 --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/src/peripheral.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include + +#include "bs_bt_utils.h" + +LOG_MODULE_REGISTER(test_peripheral, LOG_LEVEL_DBG); + +BUILD_ASSERT(CONFIG_BT_BONDABLE, "CONFIG_BT_BONDABLE must be enabled by default."); + +static void pairing_complete_unpair(struct bt_conn *conn, bool bonded) +{ + FAIL("Pairing succeed\n"); +} + +static void peripheral_security_changed_unpair(struct bt_conn *conn, + bt_security_t level, + enum bt_security_err err) +{ + /* Try to trigger fault here */ + k_msleep(2000); + LOG_INF("remove pairing..."); + bt_unpair(BT_ID_DEFAULT, bt_conn_get_dst(conn)); + LOG_DBG("unpaired"); +} + +void peripheral_unpair_in_sec_cb(void) +{ + LOG_DBG("===== Peripheral (will trigger unpair in sec changed cb) ====="); + + int err; + struct bt_conn_cb peripheral_cb = {}; + struct bt_conn_auth_info_cb peripheral_auth_info_cb = {}; + + /* Call `bt_unpair` in security changed callback */ + + peripheral_cb.security_changed = peripheral_security_changed_unpair; + peripheral_auth_info_cb.pairing_complete = pairing_complete_unpair; + + bs_bt_utils_setup(); + + bt_conn_cb_register(&peripheral_cb); + err = bt_conn_auth_info_cb_register(&peripheral_auth_info_cb); + ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); + + advertise_connectable(BT_ID_DEFAULT, NULL); + wait_connected(); + + wait_disconnected(); + + clear_g_conn(); + + PASS("PASS\n"); +} + +static void pairing_failed_disconnect(struct bt_conn *conn, enum bt_security_err err) +{ + FAIL("Pairing failed\n"); +} + +static void peripheral_security_changed_disconnect(struct bt_conn *conn, + bt_security_t level, + enum bt_security_err err) +{ + /* Try to trigger fault here */ + k_msleep(2000); + LOG_INF("disconnecting..."); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); +} + +void peripheral_disconnect_in_sec_cb(void) +{ + LOG_DBG("===== Peripheral (will trigger unpair in sec changed cb) ====="); + + int err; + struct bt_conn_cb peripheral_cb = {}; + struct bt_conn_auth_info_cb peripheral_auth_info_cb = {}; + + /* Disconnect in security changed callback */ + + peripheral_cb.security_changed = peripheral_security_changed_disconnect; + peripheral_auth_info_cb.pairing_failed = pairing_failed_disconnect; + + bs_bt_utils_setup(); + + bt_conn_cb_register(&peripheral_cb); + err = bt_conn_auth_info_cb_register(&peripheral_auth_info_cb); + ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); + + advertise_connectable(BT_ID_DEFAULT, NULL); + wait_connected(); + + wait_disconnected(); + + clear_g_conn(); + + PASS("PASS\n"); +} diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/_compile.sh new file mode 100755 index 00000000000..a7d3a9c569f --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/_compile.sh @@ -0,0 +1,18 @@ +#!/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu + +# Terminate running simulations (if any) +${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh + +test_name='security_changed_callback' + +: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" +bsim_bin="${BSIM_OUT_PATH}/bin" +BOARD="${BOARD:-nrf52_bsim}" +test_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_security_${test_name}_prj_conf" + +west build -b nrf52_bsim -d build && \ + cp -v build/zephyr/zephyr.exe "${test_exe}" diff --git a/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/security_changed_callback.sh b/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/security_changed_callback.sh new file mode 100755 index 00000000000..122ba43e12f --- /dev/null +++ b/tests/bsim/bluetooth/host/security/security_changed_callback/test_scripts/security_changed_callback.sh @@ -0,0 +1,35 @@ +#!/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_name='security_changed_callback' +test_exe="bs_${BOARD}_tests_bsim_bluetooth_host_security_${test_name}_prj_conf" +simulation_id="${test_name}" +verbosity_level=2 +EXECUTE_TIMEOUT=30 + +cd ${BSIM_OUT_PATH}/bin + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral_disconnect_in_sec_cb + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=60e6 + +wait_for_background_jobs + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral_unpair_in_sec_cb + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=60e6 + +wait_for_background_jobs From 8bd36fc58955a210ede018c90e5993cca402472f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Fri, 1 Sep 2023 10:26:05 +0200 Subject: [PATCH 0016/4498] Bluetooth: Host: Fixes SMP issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the bonding information has been cleared before pairing had a chance to complete (probably by the application), indicate this by setting an appropriate log message. Also check that keys exist before calling `bt_keys_store`. Fixes #59788 and #61465 Signed-off-by: Théo Battrel --- subsys/bluetooth/host/smp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index add06660bf6..cccf95adf8e 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -1650,11 +1650,11 @@ static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) LOG_DBG("got status 0x%x", status); - if (conn->state != BT_CONN_CONNECTED) { - /* If disconnection has been triggered in between the security update - * and the call to this function we need to abort the pairing. + if (conn->le.keys == NULL) { + /* We can get here if the application calls `bt_unpair` in the + * `security_changed` callback. */ - LOG_WRN("Not connected!"); + LOG_WRN("The in-progress pairing has been deleted!"); status = BT_SMP_ERR_UNSPECIFIED; } @@ -1677,7 +1677,7 @@ static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) bt_keys_show_sniffer_info(conn->le.keys, NULL); } - if (bond_flag) { + if (bond_flag && conn->le.keys) { bt_keys_store(conn->le.keys); } From 2a472b8b477ce4f46c88978d0970ea6cb65dea15 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 1 Sep 2023 15:17:52 +0200 Subject: [PATCH 0017/4498] Bluetooth: Mesh: Fix Opcode Aggregator Server compilation Remove ifdef around `srcs` and let linker exclude it when Opcode Aggregator Client model is not enabled. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/op_agg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/subsys/bluetooth/mesh/op_agg.c b/subsys/bluetooth/mesh/op_agg.c index 4f6baacc898..1580c7f0847 100644 --- a/subsys/bluetooth/mesh/op_agg.c +++ b/subsys/bluetooth/mesh/op_agg.c @@ -17,10 +17,7 @@ LOG_MODULE_REGISTER(bt_mesh_op_agg); #define LENGTH_SHORT_MAX BIT_MASK(7) NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); - -#if IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX); -#endif static struct op_agg_ctx agg_ctx = { .sdu = &sdu, From d36b7f4de0b2feec55a5fcca30dec608cb7df8ad Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 1 Sep 2023 15:19:13 +0200 Subject: [PATCH 0018/4498] Bluetooth: Mesh: Fix Solicitation RPL PDU Server compilation A pointer to the key struct should be passed after the PSA support has been added. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/solicitation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index 3f639fbf0d6..1bf9f9a465a 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -153,12 +153,12 @@ static bool sol_pdu_decrypt(struct bt_mesh_subnet *sub, void *data) net_buf_simple_init(out, 0); net_buf_simple_add_mem(out, in->data, in->len); - err = bt_mesh_net_obfuscate(out->data, 0, sub->keys[i].msg.privacy); + err = bt_mesh_net_obfuscate(out->data, 0, &sub->keys[i].msg.privacy); if (err) { LOG_DBG("obfuscation err %d", err); continue; } - err = bt_mesh_net_decrypt(sub->keys[i].msg.enc, out, + err = bt_mesh_net_decrypt(&sub->keys[i].msg.enc, out, 0, BT_MESH_NONCE_SOLICITATION); if (!err) { LOG_DBG("Decrypted PDU %s", bt_hex(out->data, out->len)); From ab9da956b0057fe3473ed75856a652a57883c95d Mon Sep 17 00:00:00 2001 From: Yves Vandervennet Date: Fri, 1 Sep 2023 10:59:17 -0500 Subject: [PATCH 0019/4498] nxp: mimxrt1170: add support for NXP's LinkServer LinkServer is NXP's tool to flash and debug on MCU's. This patch expands support for LinkServer to MIMXRT1170. There is one limitation with flashing and debugging the SoC's seciond core (COrtex M4) that will be addressed with a future submission. Signed-off-by: Yves Vandervennet --- boards/arm/mimxrt1170_evk/board.cmake | 25 ++++++++++++---- scripts/west_commands/runners/linkserver.py | 32 +++++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/boards/arm/mimxrt1170_evk/board.cmake b/boards/arm/mimxrt1170_evk/board.cmake index e743455b20d..d543dce8821 100644 --- a/boards/arm/mimxrt1170_evk/board.cmake +++ b/boards/arm/mimxrt1170_evk/board.cmake @@ -5,13 +5,28 @@ # if(CONFIG_SOC_MIMXRT1176_CM7 OR CONFIG_SECOND_CORE_MCUX) -board_runner_args(pyocd "--target=mimxrt1170_cm7") -board_runner_args(jlink "--device=MIMXRT1176xxxA_M7" "--reset-after-load") + board_runner_args(pyocd "--target=mimxrt1170_cm7") + board_runner_args(jlink "--device=MIMXRT1176xxxA_M7" "--reset-after-load") + + if(CONFIG_BOARD_MIMXRT1170_EVK_CM7) + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVK") + elseif(CONFIG_BOARD_MIMXRT1170_EVKB_CM7) + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVKB") + endif() + + board_runner_args(linkserver "--core=cm7") elseif(CONFIG_SOC_MIMXRT1176_CM4) -board_runner_args(pyocd "--target=mimxrt1170_cm4") -# Note: Please use JLINK above V7.50 (Only support run cm4 image when debugging due to default boot core on board is cm7 core) -board_runner_args(jlink "--device=MIMXRT1176xxxA_M4") + board_runner_args(pyocd "--target=mimxrt1170_cm4") + # Note: Please use JLINK above V7.50 (Only support run cm4 image when debugging due to default boot core on board is cm7 core) + board_runner_args(jlink "--device=MIMXRT1176xxxA_M4") + if(CONFIG_BOARD_MIMXRT1170_EVK_CM4) + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVK") + elseif(CONFIG_BOARD_MIMXRT1170_EVKB_CM4) + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVKB") + endif() + board_runner_args(linkserver "--core=cm4") endif() include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) diff --git a/scripts/west_commands/runners/linkserver.py b/scripts/west_commands/runners/linkserver.py index 10833618fa1..5108d780aeb 100644 --- a/scripts/west_commands/runners/linkserver.py +++ b/scripts/west_commands/runners/linkserver.py @@ -22,7 +22,7 @@ class LinkServerBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for NXP Linkserver''' - def __init__(self, cfg, device, + def __init__(self, cfg, device, core, linkserver=DEFAULT_LINKSERVER_EXE, dt_flash=True, erase=True, probe=1, @@ -39,6 +39,7 @@ def __init__(self, cfg, device, self.elf_name = cfg.elf_file self.gdb_cmd = cfg.gdb if cfg.gdb else None self.device = device + self.core = core self.linkserver = linkserver self.dt_flash = dt_flash self.erase = erase @@ -68,6 +69,8 @@ def capabilities(cls): def do_add_parser(cls, parser): parser.add_argument('--device', required=True, help='device name') + parser.add_argument('--core', required=False, help='core of the device') + parser.add_argument('--probe', default=1, help='interface to use (index, no serial number), default is 1') @@ -92,7 +95,7 @@ def do_add_parser(cls, parser): @classmethod def do_create(cls, cfg, args): - return LinkServerBinaryRunner(cfg, args.device, + return LinkServerBinaryRunner(cfg, args.device, args.core, linkserver=args.linkserver, dt_flash=args.dt_flash, erase=args.erase, @@ -120,14 +123,22 @@ def do_run(self, command, **kwargs): if command == 'flash': self.flash(**kwargs) else: + if self.core is not None: + _cmd_core = [ "-c", self.core ] + else: + _cmd_core = [] + linkserver_cmd = ([self.linkserver] + ["gdbserver"] + ["--probe", "#"+str(self.probe) ] + ["--gdb-port", str(self.gdb_port )] + ["--semihost-port", str(self.semihost_port) ] + - self.override_cli + + _cmd_core + + self.override_cli + [self.device]) + self.logger.debug(f'LinkServer cmd: + {linkserver_cmd}') + if command in ('debug', 'attach'): if self.elf_name is None or not os.path.isfile(self.elf_name): raise ValueError('Cannot debug; elf file required') @@ -153,8 +164,13 @@ def do_run(self, command, **kwargs): def do_erase(self, **kwargs): + if self.core is not None: + _cmd_core = ":"+self.core + else: + _cmd_core = "" + linkserver_cmd = ([self.linkserver, "flash"] + ["--probe", "#"+str(self.probe)] + - [self.device] + ["erase"]) + [self.device+_cmd_core] + ["erase"]) self.logger.debug("flash erase command = " + str(linkserver_cmd)) self.check_call(linkserver_cmd) @@ -170,7 +186,13 @@ def _build_override_cli(self): def flash(self, **kwargs): - linkserver_cmd = ([self.linkserver, "flash"] + ["--probe", "#"+str(self.probe)] + self.override_cli + [self.device]) + if self.core is not None: + _cmd_core = ":"+self.core + else: + _cmd_core = "" + + linkserver_cmd = ([self.linkserver, "flash"] + ["--probe", "#"+str(self.probe)] + self.override_cli + [self.device+_cmd_core]) + self.logger.debug(f'LinkServer cmd: + {linkserver_cmd}') if self.erase: self.do_erase() From 1477865a7a1ee6c1a869265d949ab63669dfe597 Mon Sep 17 00:00:00 2001 From: Yves Vandervennet Date: Fri, 1 Sep 2023 11:41:36 -0500 Subject: [PATCH 0020/4498] linkserver: doc: updates for NXP's mimxrt1170 This commit adds the documentation details for the linkserver support on rt1170. Signed-off-by: Yves Vandervennet --- boards/arm/mimxrt1170_evk/doc/index.rst | 102 ++++++++++++++++-------- doc/develop/flash_debug/host-tools.rst | 25 ++++-- doc/develop/flash_debug/probes.rst | 61 ++++++++++++++ 3 files changed, 148 insertions(+), 40 deletions(-) diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index 90f192c3870..51d5053e360 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -1,4 +1,4 @@ -.. _mimxrt1170_evk: +.. _mimxrt1170_evk: NXP MIMXRT1170-EVK/EVKB ####################### @@ -9,7 +9,7 @@ Overview The dual core i.MX RT1170 runs on the Cortex-M7 core at 1 GHz and on the Cortex-M4 at 400 MHz. The i.MX RT1170 MCU offers support over a wide temperature range and is qualified for consumer, industrial and automotive markets. Zephyr -supports the initial revision of this EVK, as well as EVK rev B. +supports the initial revision of this EVK, as well as rev EVKB. .. image:: mimxrt1170_evk.jpg :align: center @@ -59,7 +59,7 @@ Hardware - Debug - JTAG 20-pin connector - - OpenSDA with DAPLink + - on-board debugger - Sensor @@ -90,16 +90,17 @@ This platform has the following external memories: | Device | Controller | Status | +====================+============+=====================================+ | W9825G6KH | SEMC | Enabled via device configuration | -| | | data block, which sets up SEMC at | -| | | boot time | +| SDRAM | | data (DCD) block, which sets up | +| | | the SEMC at boot time | +--------------------+------------+-------------------------------------+ -| IS25WP128 | FLEXSPI | Enabled via flash configurationn | -| (RT1170 EVK) | | block, which sets up FLEXSPI at | -| | | boot time. | +| IS25WP128 | FLEXSPI | Enabled via flash configuration | +| QSPI flash | | block (FCB), which sets up the | +| (RT1170 EVK) | | FLEXSPI at boot time. | +--------------------+------------+-------------------------------------+ -| W25Q512NWEIQ | FLEXSPI | Enabled via flash configurationn | -| (RT1170 EVKB) | | block, which sets up FLEXSPI at | -| | | boot time. Supported for XIP only. | +| W25Q512NWEIQ | FLEXSPI | Enabled via flash configuration | +| QSPI flash | | block (FCB), which sets up the | +| (RT1170 EVKB) | | FLEXSPI at boot time. Supported for | +| | | XIP only. | +--------------------+------------+-------------------------------------+ Supported Features @@ -123,6 +124,8 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | COUNTER | on-chip | gpt | Supported | Supported | +-----------+------------+-------------------------------------+-----------------+-----------------+ +| TIMER | on-chip | gpt | Supported | Supported | ++-----------+------------+-------------------------------------+-----------------+-----------------+ | CAN | on-chip | flexcan | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ | SPI | on-chip | spi | Supported (M7) | Supported | @@ -139,11 +142,10 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | DMA | on-chip | dma | Supported | Supported | +-----------+------------+-------------------------------------+-----------------+-----------------+ -| GPT | on-chip | gpt | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ | WATCHDOG | on-chip | watchdog | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ -| ENET | on-chip | ethernet | Supported (M7) | No support | +| ENET | on-chip | ethernet - 10/100M (ENET_QOS or | Supported (M7) | No support | +| ENET1G | | GigE not supported yet) | | | +-----------+------------+-------------------------------------+-----------------+-----------------+ | SAI | on-chip | i2s | Supported | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ @@ -165,10 +167,9 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) | SDHC | on-chip | SD host controller | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ -The default configuration can be found in the defconfig file: +The default configuration can be found in the defconfig files: ``boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7_defconfig`` - -Other hardware features are not currently supported by the port. +``boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7_defconfig`` Connections and I/Os ==================== @@ -310,33 +311,62 @@ secondary core should be placed into a loop, then a debugger can be attached Configuring a Debug Probe ========================= -A debug probe is used for both flashing and debugging the board. This board is -configured by default to use the :ref:`opensda-daplink-onboard-debug-probe`, -however the :ref:`pyocd-debug-host-tools` do not yet support programming the -external flashes on this board so you must reconfigure the board for one of the -following debug probes instead. +A debug probe is used for both flashing and debugging the board. The on-board +debugger listed below works with the LinkServer runner by default, or can be +reprogrammed with JLink firmware. +- MIMXRT1170-EVKB: :ref:`mcu-link-cmsis-onboard-debug-probe` +- MIMXRT1170-EVK: :ref:`opensda-daplink-onboard-debug-probe` .. _Using J-Link RT1170: Using J-Link --------------------------------- -Install the :ref:`jlink-debug-host-tools` and make sure they are in your search -path. +JLink is the default runner for this board. Install the +:ref:`jlink-debug-host-tools` and make sure they are in your search path. There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or :ref:`jlink-external-debug-probe` can be attached to the -EVK. See `Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. +EVK. See `Using J-Link with MIMXRT1170-EVKB`_ or +`Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. + +.. _Using LinkServer RT1170: + +Using LinkServer +---------------------------------- + +Known limitations with LinkServer and these boards include: +- ``west debug`` does not yet work correctly, and the application image is not +properly written to the memory. `NXP MCUXpresso for Visual Studio Code`_ +can be used to debug Zephyr applications with LinkServer. +- ``west flash`` will not write images to non-flash locations. The flash +command only works when all data in the image is written to flash memory +regions. + +Install the :ref:`linkserver-debug-host-tools` and make sure they are in your +search path. LinkServer works with the default CMSIS-DAP firmware included in +the on-board debugger. + +Use the ``-r linkserver`` option with West to use the LinkServer runner. + +.. code-block:: console + + west flash -r linkserver + Configuring a Console ===================== -Regardless of your choice in debug probe, we will use the OpenSDA -microcontroller as a usb-to-serial adapter for the serial console. Check that -jumpers J5 and J8 are **on** (they are on by default when boards ship from -the factory) to connect UART signals to the OpenSDA microcontroller. +We will use the on-board debugger +microcontroller as a usb-to-serial adapter for the serial console. The following +jumper settings are default on these boards, and are required to connect the +UART signals to the USB bridge circuit: +- MIMXRT1170-EVKB: JP2 open (default) +- MIMXRT1170-EVK: J31 and J32 shorted (default) -Connect a USB cable from your PC to J11. +Connect a USB cable from your PC to the on-board debugger USB port: +- MIMXRT1170-EVKB: J86 +- MIMXRT1170-EVK: J11 Use the following settings with your serial terminal of choice (minicom, putty, etc.): @@ -351,7 +381,7 @@ Flashing Here is an example for the :ref:`hello_world` application. -Before power on the board, make sure SW1 is set to 0001b +Before powering the board, make sure SW1 is set to 0001b .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -364,7 +394,7 @@ see the following message in the terminal: .. code-block:: console - ***** Booting Zephyr OS v2.4.0-xxxx-xxxxxxxxxxxxx ***** + ***** Booting Zephyr OS v3.4.0-xxxx-xxxxxxxxxxxxx ***** Hello World! mimxrt1170_evk_cm7 Debugging @@ -382,7 +412,7 @@ should see the following message in the terminal: .. code-block:: console - ***** Booting Zephyr OS v2.4.0-xxxx-xxxxxxxxxxxxx ***** + ***** Booting Zephyr OS v3.4.0-xxxx-xxxxxxxxxxxxx ***** Hello World! mimxrt1170_evk_cm7 .. _MIMXRT1170-EVK Website: @@ -403,5 +433,11 @@ should see the following message in the terminal: .. _Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK: https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Using-J-Link-with-MIMXRT1160-EVK-or-MIMXRT1170-EVK/ta-p/1529760 +.. _Using J-Link with MIMXRT1170-EVKB: + https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Using-J-Link-with-MIMXRT1170-EVKB/ta-p/1715138 + .. _AN13264: https://www.nxp.com/docs/en/application-note/AN13264.pdf + +.. _NXP MCUXpresso for Visual Studio Code: + https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-for-visual-studio-code:MCUXPRESSO-VSC diff --git a/doc/develop/flash_debug/host-tools.rst b/doc/develop/flash_debug/host-tools.rst index e93ee618f55..981c89ce686 100644 --- a/doc/develop/flash_debug/host-tools.rst +++ b/doc/develop/flash_debug/host-tools.rst @@ -206,17 +206,20 @@ LinkServer Debug Host Tools Linkserver is a utility for launching and managing GDB servers for NXP debug probes, which also provides a command-line target flash programming capabilities. -Linkserver can be used with NXP MCUXpresso for Visual Studio Code implementation, +Linkserver can be used with the `NXP MCUXpresso for Visual Studio Code`_ implementation, with custom debug configurations based on GNU tools or as part of a headless solution -for continuous integration and test. Linkserver can be used with MCU-Link, LPC-Link2, +for continuous integration and test. LinkServer can be used with MCU-Link, LPC-Link2, LPC11U35-based and OpenSDA based standalone or on-board debug probes from NXP. -The Linkserver installer also includes the firmware update utilities for MCU-Link and -the LPCScrypt utility for use with LPC-Link2. Linkserver can also be installed using -the MCUXpresso Installer. + +NXP recommends installing LinkServer by using NXP's `MCUXpresso Installer`_. +This method will also install the tools supporting the debug probes below, +including NXP's MCU-Link and LPCScrypt tools. LinkServer is compatible with the following debug probes: - :ref:`lpclink2-cmsis-onboard-debug-probe` +- :ref:`mcu-link-cmsis-onboard-debug-probe` +- :ref:`opensda-daplink-onboard-debug-probe` Supported west commands: @@ -234,13 +237,14 @@ Notes: LinkServer probes -2. Use the LinkServer west runner ``--probe`` option to pass the probe index. +2. With multiple debug probes attached to the host, use the +LinkServer west runner ``--probe`` option to pass the probe index. .. code-block:: console west flash --runner=linkserver --probe=3 -3. device specific settings can be overridden with the west runner for LinkServer with +3. Device-specific settings can be overridden with the west runner for LinkServer with the option '--override'. May be used multiple times. The format is dictated by LinkServer, e.g.: @@ -265,6 +269,7 @@ These debug host tools are compatible with the following debug probes: - :ref:`lpclink2-jlink-onboard-debug-probe` - :ref:`opensda-jlink-onboard-debug-probe` +- :ref:`mcu-link-jlink-onboard-debug-probe` - :ref:`jlink-external-debug-probe` - :ref:`stlink-v21-onboard-debug-probe` @@ -405,3 +410,9 @@ To enable Zephyr RTOS awareness follow the steps described in .. _BOSSA official releases: https://github.com/shumatech/BOSSA/releases + +.. _NXP MCUXpresso for Visual Studio Code: + https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-for-visual-studio-code:MCUXPRESSO-VSC + +.. _MCUXpresso Installer: + https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe diff --git a/doc/develop/flash_debug/probes.rst b/doc/develop/flash_debug/probes.rst index 78a068d6ac4..83f355aadba 100644 --- a/doc/develop/flash_debug/probes.rst +++ b/doc/develop/flash_debug/probes.rst @@ -58,6 +58,64 @@ onboard debug probe may have limitations, such as lack of support for advanced debuggers or high-speed tracing. You may need to adjust jumpers to prevent the onboard debug probe from interfering with the external debug probe. +.. _mcu-link-cmsis-onboard-debug-probe: + +MCU-Link CMSIS-DAP Onboard Debug Probe +*************************************** + +The CMSIS-DAP debug probes allow debugging from any compatible toolchain, +including IAR EWARM, Keil MDK, NXP’s MCUXpresso IDE and +MCUXpresso extension for VS Code. In addition to debug probe functionality, the +MCU-Link probes may also provide: + +1. SWO trace end point: this virtual device is used by MCUXpresso to retrieve + SWO trace data. See the MCUXpresso IDE documentation for more information. +#. Virtual COM (VCOM) port / UART bridge connected to the target processor +#. USB to UART, SPI and/or I2C interfaces (depending on MCU-Link + type/implementation) +#. Energy measurements of the target MCU + +This debug probe is compatible with the following debug host tools: + +- :ref:`linkserver-debug-host-tools` + +This probe is realized by programming the MCU-Link microcontroller with the +CMSIS-DAP MCU-Link firmware, which is already installed by default. NXP +recommends using NXP's `MCUXpresso Installer`_, which installs both the MCU-Link +host tools plus the :ref:`linkserver-debug-host-tools`. + +1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU + jumper, then powering up the board. + +#. Run the ``program_CMSIS`` script, found in the installed MCU-Link ``scripts`` + folder. + +#. Remove the DFU jumper and power cycle the board. + +.. _mcu-link-jlink-onboard-debug-probe: + +MCU-Link JLink Onboard Debug Probe +************************************ + +The MCU-Link J-Link is an onboard debug probe and usb-to-serial adapter +supported on many NXP development boards. + +This debug probe is compatible with the following debug host tools: + +- :ref:`jlink-debug-host-tools` + +These probes do not have JLink firmware installed by default, and must be +updated. NXP recommends using NXP's `MCUXpresso Installer`_, which installs both +the :ref:`jlink-debug-host-tools` plus the MCU-Link host tools. + +1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU + jumper, then powering up the board. + +#. Run the ``program_JLINK`` script, found in the installed MCU-Link ``scripts`` + folder. + +#. Remove the DFU jumper and power cycle the board. + .. _lpclink2-cmsis-onboard-debug-probe: LPC-LINK2 CMSIS DAP Onboard Debug Probe @@ -341,3 +399,6 @@ option. For more information about twister and available options, see .. _STM32CubeProgrammer Tool: https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _MCUXpresso Installer: + https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe From c2647ff24b776bd028649bc9cb7b611448a4a27b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 5 Sep 2023 08:55:32 +0200 Subject: [PATCH 0021/4498] subsys/modem/backend: Correct async UART backend close The backend currently returns the pipe closed event immediately after calling uart_rx_disable() which is not the correct behavior. the pipe closed event should be called when the UART_RX_DISABLED event is raised by the UART driver. With this fix, back-to-back open/close/open... will work as expected, where before the second open would often fail since the UART was not actually disabled yet. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/backends/Kconfig | 8 ++++++++ .../modem/backends/modem_backend_uart_async.c | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/subsys/modem/backends/Kconfig b/subsys/modem/backends/Kconfig index f2b45d9285c..1d3e3144a91 100644 --- a/subsys/modem/backends/Kconfig +++ b/subsys/modem/backends/Kconfig @@ -21,4 +21,12 @@ config MODEM_BACKEND_UART_ASYNC bool "Modem UART backend module async implementation" default y if UART_ASYNC_API +if MODEM_BACKEND_UART_ASYNC + +config MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS + int "Modem UART async transmit timeout in milliseconds" + default 100 + +endif + endif # MODEM_BACKEND_UART diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index a10822a6ae5..c5349a0b52c 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -17,8 +17,6 @@ LOG_MODULE_DECLARE(modem_backend_uart); #define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT (2) #define MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT (3) -#define MODEM_BACKEND_UART_ASYNC_BLOCK_MIN_SIZE (8) - static void modem_backend_uart_async_flush(struct modem_backend_uart *backend) { uint8_t c; @@ -62,6 +60,11 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, break; + case UART_TX_ABORTED: + LOG_WRN("Transmit aborted"); + atomic_clear_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT); + case UART_RX_BUF_REQUEST: if (!atomic_test_and_set_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT)) { @@ -116,8 +119,13 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, k_work_submit(&backend->receive_ready_work); break; - case UART_TX_ABORTED: - LOG_WRN("Transmit aborted"); + case UART_RX_DISABLED: + modem_pipe_notify_closed(&backend->pipe); + break; + + case UART_RX_STOPPED: + LOG_WRN("Receive stopped for reasons: %u", (uint8_t)evt->data.rx_stop.reason); + break; default: break; @@ -176,7 +184,7 @@ static int modem_backend_uart_async_transmit(void *data, const uint8_t *buf, siz memcpy(backend->async.transmit_buf, buf, bytes_to_transmit); ret = uart_tx(backend->uart, backend->async.transmit_buf, bytes_to_transmit, - SYS_FOREVER_US); + CONFIG_MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS * 1000L); if (ret < 0) { LOG_WRN("Failed to start async transmit"); @@ -220,7 +228,6 @@ static int modem_backend_uart_async_close(void *data) struct modem_backend_uart *backend = (struct modem_backend_uart *)data; uart_rx_disable(backend->uart); - modem_pipe_notify_closed(&backend->pipe); return 0; } From 2d2d3ececd0781be6e3ad3cda97d9d44a510dfd0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 5 Sep 2023 09:20:32 +0200 Subject: [PATCH 0022/4498] drivers/modem/modem_cellular.c: Improve bus pipe usage This commit improves the usage of the bus pipe (connected to UART) to only open it when the modem is actually powered and ready, not when leaving the idle state. This ensures the pipe is flushed before sending the init script, and re-enables the UART driver if it is disabled due to errors. While building a test platform based on the nRF9160 and a Quectel BG95, it was discovered that the nRF9160 correctly throws UART errors if the RX is enabled while the UART RX line is low (which was due to the modem being powered down). The improvements should also help help remove the " modem_chat: receive buffer overrun" warning which would occur during startup as the pipe was opened, but nothing was receiving the data, causing the buffer to overflow. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/modem_cellular.c | 108 ++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 41 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index b72adcafc6f..9cad08332a7 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -50,6 +50,8 @@ enum modem_cellular_event { MODEM_CELLULAR_EVENT_TIMEOUT, MODEM_CELLULAR_EVENT_REGISTERED, MODEM_CELLULAR_EVENT_DEREGISTERED, + MODEM_CELLULAR_EVENT_BUS_OPENED, + MODEM_CELLULAR_EVENT_BUS_CLOSED, }; struct modem_cellular_data { @@ -172,6 +174,10 @@ static const char *modem_cellular_event_str(enum modem_cellular_event event) return "registered"; case MODEM_CELLULAR_EVENT_DEREGISTERED: return "deregistered"; + case MODEM_CELLULAR_EVENT_BUS_OPENED: + return "bus opened"; + case MODEM_CELLULAR_EVENT_BUS_CLOSED: + return "bus closed"; } return ""; @@ -191,6 +197,26 @@ static void modem_cellular_delegate_event(struct modem_cellular_data *data, static void modem_cellular_event_handler(struct modem_cellular_data *data, enum modem_cellular_event evt); +static void modem_cellular_bus_pipe_handler(struct modem_pipe *pipe, + enum modem_pipe_event event, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_OPENED); + break; + + case MODEM_PIPE_EVENT_CLOSED: + modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_CLOSED); + break; + + default: + break; + } +} + static void modem_cellular_dlci1_pipe_handler(struct modem_pipe *pipe, enum modem_pipe_event event, void *user_data) @@ -401,7 +427,7 @@ static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data) modem_chat_release(&data->chat); modem_ppp_release(data->ppp); modem_cmux_release(&data->cmux); - modem_pipe_close(data->uart_pipe); + modem_pipe_close_async(data->uart_pipe); k_sem_give(&data->suspended_sem); return 0; } @@ -447,10 +473,6 @@ static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data) gpio_pin_set_dt(&config->reset_gpio, 0); } - if (modem_pipe_open(data->uart_pipe) < 0) { - return -EAGAIN; - } - return 0; } @@ -556,14 +578,8 @@ static void modem_cellular_await_power_on_event_handler(struct modem_cellular_da static int modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data *data) { - const struct modem_cellular_config *config = - (const struct modem_cellular_config *)data->dev->config; - - if (modem_chat_attach(&data->chat, data->uart_pipe) < 0) { - return -EAGAIN; - } - - return modem_chat_script_run(&data->chat, config->init_chat_script); + modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data); + return modem_pipe_open_async(data->uart_pipe); } static void modem_cellular_run_init_script_event_handler(struct modem_cellular_data *data, @@ -573,10 +589,21 @@ static void modem_cellular_run_init_script_event_handler(struct modem_cellular_d (const struct modem_cellular_config *)data->dev->config; switch (evt) { + case MODEM_CELLULAR_EVENT_BUS_OPENED: + modem_chat_attach(&data->chat, data->uart_pipe); + modem_chat_script_run(&data->chat, config->init_chat_script); + break; + case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: net_if_set_link_addr(modem_ppp_get_iface(data->ppp), data->imei, ARRAY_SIZE(data->imei), NET_LINK_UNKNOWN); + modem_chat_release(&data->chat); + modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data); + modem_pipe_close_async(data->uart_pipe); + break; + + case MODEM_CELLULAR_EVENT_BUS_CLOSED: modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CONNECT_CMUX); break; @@ -603,19 +630,13 @@ static void modem_cellular_run_init_script_event_handler(struct modem_cellular_d } } -static int modem_cellular_on_run_init_script_state_leave(struct modem_cellular_data *data) -{ - modem_chat_release(&data->chat); - return 0; -} - static int modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data *data) { - if (modem_cmux_attach(&data->cmux, data->uart_pipe) < 0) { - return -EAGAIN; - } - - modem_cellular_start_timer(data, K_MSEC(500)); + /* + * Allow modem to switch bus into CMUX mode. Some modems disable UART RX while + * switching, resulting in UART RX errors as bus is no longer pulled up by modem. + */ + modem_cellular_start_timer(data, K_MSEC(100)); return 0; } @@ -624,6 +645,11 @@ static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data { switch (evt) { case MODEM_CELLULAR_EVENT_TIMEOUT: + modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data); + modem_pipe_open_async(data->uart_pipe); + + case MODEM_CELLULAR_EVENT_BUS_OPENED: + modem_cmux_attach(&data->cmux, data->uart_pipe); modem_cmux_connect_async(&data->cmux); break; @@ -700,20 +726,23 @@ static int modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data * static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data) { - const struct modem_cellular_config *config = - (const struct modem_cellular_config *)data->dev->config; - - if (modem_chat_attach(&data->chat, data->dlci1_pipe) < 0) { - return -EAGAIN; - } - - return modem_chat_script_run(&data->chat, config->dial_chat_script); + /* Allow modem time to enter command mode before running dial script */ + modem_cellular_start_timer(data, K_MSEC(100)); + return 0; } static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_data *data, enum modem_cellular_event evt) { + const struct modem_cellular_config *config = + (const struct modem_cellular_config *)data->dev->config; + switch (evt) { + case MODEM_CELLULAR_EVENT_TIMEOUT: + modem_chat_attach(&data->chat, data->dlci1_pipe); + modem_chat_script_run(&data->chat, config->dial_chat_script); + break; + case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED); break; @@ -792,6 +821,7 @@ static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data * static int modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data *data) { + modem_pipe_close_async(data->uart_pipe); modem_cellular_start_timer(data, K_MSEC(2000)); return 0; } @@ -965,10 +995,6 @@ static int modem_cellular_on_state_leave(struct modem_cellular_data *data) ret = modem_cellular_on_power_on_pulse_state_leave(data); break; - case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT: - ret = modem_cellular_on_run_init_script_state_leave(data); - break; - case MODEM_CELLULAR_STATE_OPEN_DLCI1: ret = modem_cellular_on_open_dlci1_state_leave(data); break; @@ -1262,7 +1288,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 100)); + 0)); MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1298,7 +1324,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 100)); + 0)); MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_init_chat_script, zephyr_gsm_ppp_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1334,7 +1360,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 100)); + 0)); MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1370,7 +1396,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 100)); + 0)); MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1406,7 +1432,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 100)); + 0)); MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); From 83af7349f34b9e5a21a56688244ea8383908b3d8 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 5 Sep 2023 16:35:12 +0300 Subject: [PATCH 0023/4498] boards: x86: Remove unneeded board check When building EFI is desired for all board variants, remove unneeded board check. Signed-off-by: Andrei Emeltchenko --- boards/x86/intel_adl/CMakeLists.txt | 2 +- boards/x86/intel_ehl/CMakeLists.txt | 2 +- boards/x86/intel_rpl/CMakeLists.txt | 2 +- boards/x86/up_squared/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/x86/intel_adl/CMakeLists.txt b/boards/x86/intel_adl/CMakeLists.txt index 118b256013a..2dc5afcc323 100644 --- a/boards/x86/intel_adl/CMakeLists.txt +++ b/boards/x86/intel_adl/CMakeLists.txt @@ -1,5 +1,5 @@ # Create an EFI image -if((CONFIG_BOARD_INTEL_ADL_CRB OR CONFIG_BOARD_INTEL_ADL_RVP) AND CONFIG_BUILD_OUTPUT_EFI) +if(CONFIG_BUILD_OUTPUT_EFI) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py -c ${CMAKE_C_COMPILER} diff --git a/boards/x86/intel_ehl/CMakeLists.txt b/boards/x86/intel_ehl/CMakeLists.txt index 11a5e70608a..2dc5afcc323 100644 --- a/boards/x86/intel_ehl/CMakeLists.txt +++ b/boards/x86/intel_ehl/CMakeLists.txt @@ -1,5 +1,5 @@ # Create an EFI image -if(CONFIG_BOARD_INTEL_EHL_CRB AND CONFIG_BUILD_OUTPUT_EFI) +if(CONFIG_BUILD_OUTPUT_EFI) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py -c ${CMAKE_C_COMPILER} diff --git a/boards/x86/intel_rpl/CMakeLists.txt b/boards/x86/intel_rpl/CMakeLists.txt index 184ac384c2f..2dc5afcc323 100644 --- a/boards/x86/intel_rpl/CMakeLists.txt +++ b/boards/x86/intel_rpl/CMakeLists.txt @@ -1,5 +1,5 @@ # Create an EFI image -if(CONFIG_BOARD_INTEL_RPL_S_CRB AND CONFIG_BUILD_OUTPUT_EFI) +if(CONFIG_BUILD_OUTPUT_EFI) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py -c ${CMAKE_C_COMPILER} diff --git a/boards/x86/up_squared/CMakeLists.txt b/boards/x86/up_squared/CMakeLists.txt index 57eef4eabe1..2dc5afcc323 100644 --- a/boards/x86/up_squared/CMakeLists.txt +++ b/boards/x86/up_squared/CMakeLists.txt @@ -1,5 +1,5 @@ # Create an EFI image -if(CONFIG_BOARD_UP_SQUARED AND CONFIG_BUILD_OUTPUT_EFI) +if(CONFIG_BUILD_OUTPUT_EFI) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py -c ${CMAKE_C_COMPILER} From eee426742b8a79313f46c95546e9ecdb4e942a93 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 4 Sep 2023 15:16:36 +0100 Subject: [PATCH 0024/4498] manifest: update loramac-node Update loramac-node to include one more shadow variable fix. Signed-off-by: Fabio Baltieri --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ece58ad1d97..3cd299b480a 100644 --- a/west.yml +++ b/west.yml @@ -267,7 +267,7 @@ manifest: - fs revision: ca583fd297ceb48bced3c2548600dc615d67af24 - name: loramac-node - revision: 3029c9f304bf46a6e5205f3c8455dbc23108efec + revision: 466089c8726397e3fb68ee611d82712f6e14aa55 path: modules/lib/loramac-node - name: lvgl revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd From e5e2f2fad8ceb736988363555e4dfae73e97c6eb Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Mon, 21 Aug 2023 15:31:34 +0700 Subject: [PATCH 0025/4498] drivers: misc: add NXP S32 eMIOS driver This PR adds a misc driver for NXP S32 eMIOS peripheral. eMIOS provides multiple unified channels (UCs), there are several channels can be used as reference timebase (master bus) for other channels. At this time, the driver does initialize global configuration for eMIOS Signed-off-by: Dat Nguyen Duy --- drivers/misc/CMakeLists.txt | 1 + drivers/misc/Kconfig | 1 + drivers/misc/nxp_s32_emios/CMakeLists.txt | 8 ++ drivers/misc/nxp_s32_emios/Kconfig | 22 ++++ drivers/misc/nxp_s32_emios/nxp_s32_emios.c | 105 ++++++++++++++++ dts/arm/nxp/nxp_s32k344_m7.dtsi | 138 +++++++++++++++++++++ dts/bindings/misc/nxp,s32-emios.yaml | 101 +++++++++++++++ 7 files changed, 376 insertions(+) create mode 100644 drivers/misc/nxp_s32_emios/CMakeLists.txt create mode 100644 drivers/misc/nxp_s32_emios/Kconfig create mode 100644 drivers/misc/nxp_s32_emios/nxp_s32_emios.c create mode 100644 dts/bindings/misc/nxp,s32-emios.yaml diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index da3ee6da541..62b53f4f1ce 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory_ifdef(CONFIG_ARM_ETHOS_U ethos_u) add_subdirectory_ifdef(CONFIG_FT800 ft8xx) add_subdirectory_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb) add_subdirectory_ifdef(CONFIG_PIO_RPI_PICO pio_rpi_pico) +add_subdirectory_ifdef(CONFIG_NXP_S32_EMIOS nxp_s32_emios) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e8137dcc131..342d9fb70f9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -8,5 +8,6 @@ menu "Miscellaneous Drivers" source "drivers/misc/ft8xx/Kconfig" source "drivers/misc/grove_lcd_rgb/Kconfig" source "drivers/misc/pio_rpi_pico/Kconfig" +source "drivers/misc/nxp_s32_emios/Kconfig" endmenu diff --git a/drivers/misc/nxp_s32_emios/CMakeLists.txt b/drivers/misc/nxp_s32_emios/CMakeLists.txt new file mode 100644 index 00000000000..72320bb5eae --- /dev/null +++ b/drivers/misc/nxp_s32_emios/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_NXP_S32_EMIOS + nxp_s32_emios.c +) diff --git a/drivers/misc/nxp_s32_emios/Kconfig b/drivers/misc/nxp_s32_emios/Kconfig new file mode 100644 index 00000000000..83f60cf70d2 --- /dev/null +++ b/drivers/misc/nxp_s32_emios/Kconfig @@ -0,0 +1,22 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config NXP_S32_EMIOS + bool "NXP S32 eMIOS drivers" + depends on DT_HAS_NXP_S32_EMIOS_ENABLED + help + Enable drivers for NXP S32 EMIOS + +if NXP_S32_EMIOS + +module = NXP_S32_EMIOS +module-str = NXP S32 eMIOS +source "subsys/logging/Kconfig.template.log_config" + +config NXP_S32_EMIOS_INIT_PRIORITY + int "NXP S32 eMIOS initialization priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + System initialization priority for NXP S32 eMIOS drivers. + +endif diff --git a/drivers/misc/nxp_s32_emios/nxp_s32_emios.c b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c new file mode 100644 index 00000000000..fd0a8c891ae --- /dev/null +++ b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c @@ -0,0 +1,105 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define LOG_MODULE_NAME nxp_s32_emios +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_NXP_S32_EMIOS_LOG_LEVEL); + +#include + +#define DT_DRV_COMPAT nxp_s32_emios + +struct nxp_s32_emios_config { + uint8_t instance; + Emios_Mcl_Ip_ConfigType *mcl_info; +}; + +static int nxp_s32_emios_init(const struct device *dev) +{ + const struct nxp_s32_emios_config *config = dev->config; + + if (Emios_Mcl_Ip_Init(config->instance, config->mcl_info)) { + LOG_ERR("Could not initialize eMIOS"); + return -EINVAL; + } + + return 0; +} + +#define MAX_MASTER_BUS_PERIOD 65535U +#define MIN_MASTER_BUS_PERIOD 2U +#define MAX_GLOB_PRESCALER 256U +#define MIN_GLOB_PRESCALER 1U + +#define NXP_S32_EMIOS_MASTER_BUS_MODE(mode) DT_CAT(EMIOS_IP_, mode) + +#define NXP_S32_EMIOS_INSTANCE_CHECK(idx, n) \ + ((DT_INST_REG_ADDR(n) == IP_EMIOS_##idx##_BASE) ? idx : 0) + +#define NXP_S32_EMIOS_GET_INSTANCE(n) \ + LISTIFY(__DEBRACKET eMIOS_INSTANCE_COUNT, NXP_S32_EMIOS_INSTANCE_CHECK, (|), n) + +#define NXP_S32_EMIOS_GENERATE_GLOBAL_CONFIG(n) \ + BUILD_ASSERT(IN_RANGE(DT_INST_PROP(n, clock_divider), \ + MIN_GLOB_PRESCALER, MAX_GLOB_PRESCALER), \ + "Divider for eMIOS global prescaler is out of range"); \ + const Emios_Ip_GlobalConfigType nxp_s32_emios_##n##_global_config = { \ + .allowDebugMode = true, \ + .clkDivVal = DT_INST_PROP(n, clock_divider) - 1U, \ + .enableGlobalTimeBase = true \ + }; + +#define NXP_S32_EMIOS_MASTER_BUS_VERIFY(node_id) \ + BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), \ + MIN_MASTER_BUS_PERIOD, MAX_MASTER_BUS_PERIOD), \ + "Node "DT_NODE_PATH(node_id)": period is out of range"); + +#define NXP_S32_EMIOS_MASTER_BUS_CONFIG(node_id) \ + { \ + .hwChannel = DT_PROP(node_id, channel), \ + .defaultPeriod = DT_PROP(node_id, period), \ + .masterBusPrescaler = DT_PROP(node_id, prescaler) - 1, \ + .allowDebugMode = DT_PROP(node_id, freeze), \ + .masterMode = NXP_S32_EMIOS_MASTER_BUS_MODE(DT_STRING_TOKEN(node_id, mode)), \ + .masterBusAltPrescaler = 0, \ + }, + +#define NXP_S32_EMIOS_GENERATE_MASTER_BUS_CONFIG(n) \ + DT_FOREACH_CHILD_STATUS_OKAY(DT_INST_CHILD(n, master_bus), \ + NXP_S32_EMIOS_MASTER_BUS_VERIFY) \ + const Emios_Ip_MasterBusConfigType nxp_s32_emios_##n##_master_bus_config[] = { \ + DT_FOREACH_CHILD_STATUS_OKAY(DT_INST_CHILD(n, master_bus), \ + NXP_S32_EMIOS_MASTER_BUS_CONFIG) \ + }; + +#define NXP_S32_EMIOS_GENERATE_CONFIG(n) \ + NXP_S32_EMIOS_GENERATE_GLOBAL_CONFIG(n) \ + NXP_S32_EMIOS_GENERATE_MASTER_BUS_CONFIG(n) \ + const Emios_Mcl_Ip_ConfigType nxp_s32_emios_##n##_mcl_config = { \ + .channelsNumber = ARRAY_SIZE(nxp_s32_emios_##n##_master_bus_config), \ + .emiosGlobalConfig = &nxp_s32_emios_##n##_global_config, \ + .masterBusConfig = &nxp_s32_emios_##n##_master_bus_config \ + }; + +#define NXP_S32_EMIOS_INIT_DEVICE(n) \ + NXP_S32_EMIOS_GENERATE_CONFIG(n) \ + const struct nxp_s32_emios_config nxp_s32_emios_##n##_config = { \ + .instance = NXP_S32_EMIOS_GET_INSTANCE(n), \ + .mcl_info = (Emios_Mcl_Ip_ConfigType *)&nxp_s32_emios_##n##_mcl_config, \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + &nxp_s32_emios_init, \ + NULL, \ + NULL, \ + &nxp_s32_emios_##n##_config, \ + POST_KERNEL, \ + CONFIG_NXP_S32_EMIOS_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(NXP_S32_EMIOS_INIT_DEVICE) diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 4f8708defff..31a4c1453d5 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -597,6 +597,144 @@ interrupt-names = "common", "tx", "rx", "safety"; status = "disabled"; }; + + emios0: emios@40088000 { + compatible = "nxp,s32-emios"; + reg = <0x40088000 0x4000>; + clocks = <&clock NXP_S32_EMIOS0_CLK>; + interrupts = <61 0>, <62 0>, <63 0>, + <64 0>, <65 0>, <66 0>; + status = "disabled"; + + master_bus { + emios0_bus_a: emios0_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0x07FFFFF>; + status = "disabled"; + }; + + emios0_bus_b: emios0_bus_b { + channel = <0>; + bus-type = "BUS_B"; + channel-mask = <0x00000FE>; + status = "disabled"; + }; + + emios0_bus_c: emios0_bus_c { + channel = <8>; + bus-type = "BUS_C"; + channel-mask = <0x0000FE00>; + status = "disabled"; + }; + + emios0_bus_d: emios0_bus_d { + channel = <16>; + bus-type = "BUS_D"; + channel-mask = <0x00FE0000>; + status = "disabled"; + }; + + emios0_bus_f: emios0_bus_f { + channel = <22>; + bus-type = "BUS_F"; + channel-mask = <0x0BFFFFF>; + status = "disabled"; + }; + }; + }; + + emios1: emios@4008c000 { + compatible = "nxp,s32-emios"; + reg = <0x4008c000 0x4000>; + clocks = <&clock NXP_S32_EMIOS1_CLK>; + interrupts = <69 0>, <70 0>, <71 0>, + <72 0>, <73 0>, <74 0>; + status = "disabled"; + + master_bus { + emios1_bus_a: emios1_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0x07FFFFF>; + status = "disabled"; + }; + + emios1_bus_b: emios1_bus_b { + channel = <0>; + bus-type = "BUS_B"; + channel-mask = <0x00000FE>; + status = "disabled"; + }; + + emios1_bus_c: emios1_bus_c { + channel = <8>; + bus-type = "BUS_C"; + channel-mask = <0x0000FE00>; + status = "disabled"; + }; + + emios1_bus_d: emios1_bus_d { + channel = <16>; + bus-type = "BUS_D"; + channel-mask = <0x00FE0000>; + status = "disabled"; + }; + + emios1_bus_f: emios1_bus_f { + channel = <22>; + channel-mask = <0x0BFFFFF>; + bus-type = "BUS_F"; + status = "disabled"; + }; + }; + }; + + emios2: emios@40090000 { + compatible = "nxp,s32-emios"; + reg = <0x40090000 0x4000>; + clocks = <&clock NXP_S32_EMIOS2_CLK>; + interrupts = <77 0>, <78 0>, <79 0>, + <80 0>, <81 0>, <82 0>; + status = "disabled"; + + master_bus { + emios2_bus_a: emios2_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0x07FFFFF>; + status = "disabled"; + }; + + emios2_bus_b: emios2_bus_b { + channel = <0>; + bus-type = "BUS_B"; + channel-mask = <0x00000FE>; + status = "disabled"; + }; + + emios2_bus_c: emios2_bus_c { + channel = <8>; + bus-type = "BUS_C"; + channel-mask = <0x0000FE00>; + status = "disabled"; + }; + + emios2_bus_d: emios2_bus_d { + channel = <16>; + bus-type = "BUS_D"; + channel-mask = <0x00FE0000>; + status = "disabled"; + }; + + emios2_bus_f: emios2_bus_f { + channel = <22>; + bus-type = "BUS_F"; + channel-mask = <0x0BFFFFF>; + status = "disabled"; + }; + }; + }; }; }; diff --git a/dts/bindings/misc/nxp,s32-emios.yaml b/dts/bindings/misc/nxp,s32-emios.yaml new file mode 100644 index 00000000000..b08c7f6596d --- /dev/null +++ b/dts/bindings/misc/nxp,s32-emios.yaml @@ -0,0 +1,101 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP S32 Enhanced Modular IO SubSystem (eMIOS) node for S32 SoCs. + eMIOS provides independent unified channels (UCs), some of channels + have internal counter that either can be used independently or used + as a reference timebase (master bus) for other channels. + +compatible: "nxp,s32-emios" + +include: [base.yaml] + +properties: + reg: + required: true + + clock-divider: + type: int + required: true + description: | + Clock divider value for the global prescaler. Could be in range [1 ... 256] + +child-binding: + child-binding: + description: | + Node for eMIOS master bus. Each channel is capable to become a master bus has + a node defined in root devicetree but is disabled by default. To allow using + the master bus, the devicetree node should be enabled and dts properties + should be configured as required by application. + + For example, to enable bus A of eMIOS instance 0 that can be used as timebase + for channels from 0 to 22, freezed in debug mode: + master_bus { + emios0_bus_a: emios0_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0x07FFFFF>; + prescaler = <1>; + period = <65535>; + mode = ; + freeze; + status = "okay"; + }; + }; + + properties: + channel: + type: int + required: true + description: | + Channel identifier for the master bus. + + channel-mask: + type: int + required: true + description: | + A channel mask for channels that by hardware design can use this master bus + as timebase for the operation, lsb is channel 0. The mask bit for this master bus + must always 0 because a master bus should not do other thing than a base timer. + + prescaler: + type: int + required: true + description: | + Clock divider value for internal UC prescaler. + Clock for internal counter = (eMIOS clock / global prescaler) / internal prescaler. + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] + + bus-type: + type: string + required: true + description: | + Master bus type. + enum: + - "BUS_A" + - "BUS_B" + - "BUS_C" + - "BUS_D" + - "BUS_E" + - "BUS_F" + + mode: + type: string + required: true + description: | + Master bus mode. + enum: + - "MCB_UP_COUNTER" + - "MCB_UP_DOWN_COUNTER" + + period: + type: int + required: true + description: | + Default period (in ticks) for master bus at boot time. This determines PWM period + for channels use this bus as reference timebase. Could be in range [2 ... 65535] + + freeze: + type: boolean + description: Freeze internal counter when the chip enters Debug mode. From 92f3fb79fe53f06c6889e336f32a8010de455860 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Mon, 19 Jun 2023 16:33:09 +0700 Subject: [PATCH 0026/4498] drivers: pwm: introduce PWM driver for NXP S32 EMIOS This introduces PWM driver with supporting PWM output APIs based on NXP S32 EMIOS peripheral. This supports three mode: OPWFMB, OPWMCB and OPWMB. OPWFMB uses internal counter, the new period and duty cycle takes effect immediately. OPWMCB and OPWMB use external counter as timebase, changing PWM period at runtime will impact to all channels share the same timebase. Also the new period and duty cycle take effect in next period boundary of the timebase Signed-off-by: Dat Nguyen Duy --- drivers/pwm/CMakeLists.txt | 1 + drivers/pwm/Kconfig | 2 + drivers/pwm/Kconfig.nxp_s32_emios | 11 + drivers/pwm/pwm_nxp_s32_emios.c | 403 ++++++++++++++++++++++++ dts/arm/nxp/nxp_s32k344_m7.dtsi | 18 ++ dts/bindings/pwm/nxp,s32-emios-pwm.yaml | 155 +++++++++ 6 files changed, 590 insertions(+) create mode 100644 drivers/pwm/Kconfig.nxp_s32_emios create mode 100644 drivers/pwm/pwm_nxp_s32_emios.c create mode 100644 dts/bindings/pwm/nxp,s32-emios-pwm.yaml diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 308a2f5b142..2bf100aceb2 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -39,6 +39,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU4 pwm_xmc4xxx_ccu4.c) zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU8 pwm_xmc4xxx_ccu8.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_CTIMER pwm_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_NUMAKER pwm_numaker.c) +zephyr_library_sources_ifdef(CONFIG_PWM_NXP_S32_EMIOS pwm_nxp_s32_emios.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c) zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 184cbcc7cc0..ff9856d9d57 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -99,4 +99,6 @@ source "drivers/pwm/Kconfig.mcux_ctimer" source "drivers/pwm/Kconfig.numaker" +source "drivers/pwm/Kconfig.nxp_s32_emios" + endif # PWM diff --git a/drivers/pwm/Kconfig.nxp_s32_emios b/drivers/pwm/Kconfig.nxp_s32_emios new file mode 100644 index 00000000000..363e676822e --- /dev/null +++ b/drivers/pwm/Kconfig.nxp_s32_emios @@ -0,0 +1,11 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config PWM_NXP_S32_EMIOS + bool "NXP S32 PWM-eMIOS driver" + default y + depends on DT_HAS_NXP_S32_EMIOS_PWM_ENABLED + select NXP_S32_EMIOS + select NOCACHE_MEMORY + help + Enable support for the NXP S32 PWM-eMIOS. diff --git a/drivers/pwm/pwm_nxp_s32_emios.c b/drivers/pwm/pwm_nxp_s32_emios.c new file mode 100644 index 00000000000..f090ba70e88 --- /dev/null +++ b/drivers/pwm/pwm_nxp_s32_emios.c @@ -0,0 +1,403 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE_NAME nxp_s32_emios_pwm +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_s32_emios_pwm + +/* + * Need to fill to this array at runtime, cannot do at build time like + * the HAL over configuration tool due to limitation of the integration + */ +extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT]; + +struct pwm_nxp_s32_data { + uint32_t emios_clk; +}; + +struct pwm_nxp_s32_pulse_info { + uint8_t pwm_pulse_channels; + Emios_Pwm_Ip_ChannelConfigType *pwm_info; +}; + +struct pwm_nxp_s32_config { + eMIOS_Type *base; + uint8_t instance; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + const struct pinctrl_dev_config *pincfg; + struct pwm_nxp_s32_pulse_info *pulse_info; +}; + +#ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED +static int pwm_nxp_s32_set_cycles_internal_timebase(uint8_t instance, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles) +{ + bool need_update = false; + + if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || + (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { + LOG_ERR("period_cycles is out of range"); + return -EINVAL; + } + + if (Emios_Pwm_Ip_GetPeriod(instance, channel) != period_cycles) { + Emios_Pwm_Ip_SetPeriod(instance, channel, period_cycles); + need_update = true; + } + + if (Emios_Pwm_Ip_GetDutyCycle(instance, channel) != pulse_cycles) { + need_update = true; + if (Emios_Pwm_Ip_SetDutyCycle(instance, channel, pulse_cycles)) { + LOG_ERR("Cannot set pulse cycles"); + return -EIO; + } + } + + if (need_update) { + /* Force match so that the new period, duty cycle takes effect immediately */ + Emios_Pwm_Ip_ForceMatchTrailingEdge(instance, channel, true); + } + + return 0; +} +#endif + +#if defined(EMIOS_PWM_IP_MODE_OPWMCB_USED) || defined(EMIOS_PWM_IP_MODE_OPWMB_USED) +static int pwm_nxp_s32_set_cycles_external_timebase(uint8_t instance, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles) +{ + uint8_t master_channel; + + if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || + (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { + LOG_ERR("period_cycles is out of range"); + return -EINVAL; + } + + if (Emios_Pwm_Ip_GetPeriod(instance, channel) != period_cycles) { + /* + * This mode uses internal counter, so change period and cycle + * don't effect to the others + */ + master_channel = Emios_Pwm_Ip_GetMasterBusChannel(instance, channel); + + if (Emios_Mcl_Ip_SetCounterBusPeriod(instance, master_channel, period_cycles)) { + LOG_ERR("Cannot set counter period"); + return -EIO; + } + } + + if (Emios_Pwm_Ip_GetDutyCycle(instance, channel) != pulse_cycles) { + if (Emios_Pwm_Ip_SetDutyCycle(instance, channel, pulse_cycles)) { + LOG_ERR("Cannot set pulse cycles"); + return -EIO; + } + } + + return 0; +} +#endif + +static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_nxp_s32_config *config = dev->config; + + Emios_Pwm_Ip_PwmModeType mode; + + if (channel >= EMIOS_PWM_IP_CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + mode = Emios_Pwm_Ip_GetChannelMode(config->instance, channel); + if (mode == EMIOS_PWM_IP_MODE_NODEFINE) { + LOG_ERR("Channel %d is not configured for PWM", channel); + return -EINVAL; + } + + if (flags) { + LOG_ERR("Only support configuring output polarity at boot time"); + return -ENOTSUP; + } + + switch (mode) { +#ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED + case EMIOS_PWM_IP_MODE_OPWFMB_FLAG: + return pwm_nxp_s32_set_cycles_internal_timebase(config->instance, channel, + period_cycles, pulse_cycles); +#endif + +#ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED + case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG: + case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG: + if ((period_cycles % 2)) { + LOG_ERR("OPWMCB mode: period must be an even number"); + return -EINVAL; + } + + return pwm_nxp_s32_set_cycles_external_timebase(config->instance, channel, + (period_cycles + 2) / 2, + pulse_cycles); +#endif + +#if defined(EMIOS_PWM_IP_MODE_OPWMB_USED) + case EMIOS_PWM_IP_MODE_OPWMB_FLAG: + if ((Emios_Pwm_Ip_GetPhaseShift(config->instance, channel) + + pulse_cycles) > period_cycles) { + LOG_ERR("OPWMB mode: new duty cycle + phase shift must <= new period"); + return -EINVAL; + } + + return pwm_nxp_s32_set_cycles_external_timebase(config->instance, channel, + period_cycles, pulse_cycles); +#endif + + default: + /* Never reach here */ + break; + } + + return 0; +} + +static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, + uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + uint8_t internal_prescaler, global_prescaler, master_bus; + + if (Emios_Pwm_Ip_GetChannelMode(config->instance, channel) == EMIOS_PWM_IP_MODE_NODEFINE) { + LOG_ERR("Channel %d is not configured for PWM", channel); + return -EINVAL; + } + + master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel); + internal_prescaler = (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCEXTPRE_MASK) >> + eMIOS_C2_UCEXTPRE_SHIFT; + + /* Clock source for internal prescaler is from either eMIOS or eMIOS / global prescaler */ + if (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCPRECLK_MASK) { + *cycles = data->emios_clk / (internal_prescaler + 1); + } else { + global_prescaler = (config->base->MCR & eMIOS_MCR_GPRE_MASK) >> + eMIOS_MCR_GPRE_SHIFT; + *cycles = data->emios_clk / ((internal_prescaler + 1) * (global_prescaler + 1)); + } + + return 0; +} + +static int pwm_nxp_s32_init(const struct device *dev) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + const Emios_Pwm_Ip_ChannelConfigType *pwm_info; + int err = 0; + uint8_t ch_id; + + static uint8_t logic_ch; + + if (!device_is_ready(config->clock_dev)) { + return -ENODEV; + } + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &data->emios_clk)) { + return -EINVAL; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) { + pwm_info = &config->pulse_info->pwm_info[ch_id]; + eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++; + Emios_Pwm_Ip_InitChannel(config->instance, pwm_info); + } + + return err; +} + +static const struct pwm_driver_api pwm_nxp_s32_driver_api = { + .set_cycles = pwm_nxp_s32_set_cycles, + .get_cycles_per_sec = pwm_nxp_s32_get_cycles_per_sec, +}; + +/* Macros used to glue devicetree with RTD's definition */ +#define BUS_A EMIOS_PWM_IP_BUS_A +#define BUS_B EMIOS_PWM_IP_BUS_BCDE +#define BUS_C EMIOS_PWM_IP_BUS_BCDE +#define BUS_D EMIOS_PWM_IP_BUS_BCDE +#define BUS_E EMIOS_PWM_IP_BUS_BCDE +#define BUS_F EMIOS_PWM_IP_BUS_F + +#define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_, mode, _FLAG) +#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode) +#define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode) + +/* + * If timebase is configured in MCB up/down count mode: pwm period = (2 * master bus's period - 2) + */ +#define EMIOS_PWM_PERIOD_TIME_BASE(node_id) \ + COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, mode, MCB_UP_DOWN_COUNTER), \ + (2 * DT_PROP_BY_PHANDLE(node_id, master_bus, period) - 2), \ + (DT_PROP_BY_PHANDLE(node_id, master_bus, period))) + +#define EMIOS_PWM_IS_MODE_OPWFMB(node_id) \ + DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWFMB) + +#define EMIOS_PWM_IS_MODE_OPWMCB(node_id) \ + UTIL_OR(DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_TRAIL_EDGE), \ + DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_LEAD_EDGE)) \ + +#define EMIOS_PWM_IS_MODE_OPWMB(node_id) \ + DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMB) + +#define EMIOS_PWM_VERIFY_MASTER_BUS(node_id) \ + BUILD_ASSERT(BIT(DT_PROP(node_id, channel)) & \ + DT_PROP_BY_PHANDLE(node_id, master_bus, channel_mask), \ + "Node "DT_NODE_PATH(node_id)": invalid master bus"); + +#define EMIOS_PWM_LOG(node_id, msg) \ + DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \ + +#define EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id) \ + BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, period), \ + EMIOS_PWM_LOG(node_id, "period must be configured")); \ + BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), EMIOS_PWM_IP_MIN_CNT_VAL + 1, \ + EMIOS_PWM_IP_MAX_CNT_VAL), \ + EMIOS_PWM_LOG(node_id, "period is out of range")); \ + BUILD_ASSERT(DT_PROP(node_id, duty_cycle) <= DT_PROP(node_id, period), \ + EMIOS_PWM_LOG(node_id, "duty-cycle must <= period")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, master_bus), \ + EMIOS_PWM_LOG(node_id, "master-bus must not be configured")); \ + BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ + EMIOS_PWM_LOG(node_id, "dead-time must not be configured")); \ + BUILD_ASSERT(DT_PROP(node_id, phase_shift) == 0, \ + EMIOS_PWM_LOG(node_id, "phase-shift must not be configured")); + +#define EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id) \ + BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, \ + MCB_UP_DOWN_COUNTER), \ + EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up-down")); \ + BUILD_ASSERT((DT_PROP(node_id, duty_cycle) + DT_PROP(node_id, dead_time)) <= \ + EMIOS_PWM_PERIOD_TIME_BASE(node_id), \ + EMIOS_PWM_LOG(node_id, "duty-cycle + dead-time must <= period")); \ + BUILD_ASSERT(DT_PROP(node_id, dead_time) <= DT_PROP(node_id, duty_cycle), \ + EMIOS_PWM_LOG(node_id, "dead-time must <= duty-cycle")); \ + BUILD_ASSERT(DT_PROP(node_id, phase_shift) == 0, \ + EMIOS_PWM_LOG(node_id, "phase-shift must not be configured")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ + EMIOS_PWM_LOG(node_id, "period must not be configured," \ + " driver takes the value from master bus")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ + EMIOS_PWM_LOG(node_id, "prescaler must not be configured," \ + " driver takes the value from master bus")); \ + BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ + EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \ + " always use prescalered source")); \ + +#define EMIOS_PWM_VERIFY_MODE_OPWMB(node_id) \ + BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ + EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ + EMIOS_PWM_LOG(node_id, "period must not be configured," \ + " driver takes the value from master bus")); \ + BUILD_ASSERT((DT_PROP(node_id, duty_cycle) + DT_PROP(node_id, phase_shift)) <= \ + EMIOS_PWM_PERIOD_TIME_BASE(node_id), \ + EMIOS_PWM_LOG(node_id, "duty-cycle + phase-shift must <= period")); \ + BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ + EMIOS_PWM_LOG(node_id, "dead-time must not be configured")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ + EMIOS_PWM_LOG(node_id, "prescaler must not be configured")); \ + BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ + EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \ + " always use prescalered source")); \ + +#define EMIOS_PWM_VERIFY_CONFIG(node_id) \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ + (EMIOS_PWM_VERIFY_MASTER_BUS(node_id))) \ + IF_ENABLED(EMIOS_PWM_IS_MODE_OPWFMB(node_id), \ + (EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id))) \ + IF_ENABLED(EMIOS_PWM_IS_MODE_OPWMCB(node_id), \ + (EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id))) \ + IF_ENABLED(EMIOS_PWM_IS_MODE_OPWMB(node_id), \ + (EMIOS_PWM_VERIFY_MODE_OPWMB(node_id))) \ + +#define EMIOS_PWM_CONFIG(node_id) \ + { \ + .ChannelId = DT_PROP(node_id, channel), \ + .Mode = EMIOS_PWM_MODE(DT_STRING_TOKEN(node_id, pwm_mode)), \ + .InternalPsSrc = EMIOS_PWM_PS_SRC(DT_STRING_TOKEN(node_id, prescaler_src)), \ + .InternalPs = DT_PROP_OR(node_id, prescaler, \ + DT_PROP_BY_PHANDLE(node_id, master_bus, prescaler)) - 1,\ + .Timebase = DT_STRING_TOKEN_OR(DT_PHANDLE(node_id, master_bus), bus_type, \ + EMIOS_PWM_IP_BUS_INTERNAL), \ + .PhaseShift = DT_PROP(node_id, phase_shift), \ + .DeadTime = DT_PROP(node_id, dead_time), \ + .OutputDisableSource = EMIOS_PWM_IP_OUTPUT_DISABLE_NONE, \ + .OutputPolarity = EMIOS_PWM_POLARITY(DT_STRING_TOKEN(node_id, polarity)), \ + .DebugMode = DT_PROP(node_id, freeze), \ + .PeriodCount = DT_PROP_OR(node_id, period, EMIOS_PWM_PERIOD_TIME_BASE(node_id)),\ + .DutyCycle = DT_PROP(node_id, duty_cycle), \ + }, + +#define EMIOS_PWM_GENERATE_CONFIG(n) \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_VERIFY_CONFIG) \ + const Emios_Pwm_Ip_ChannelConfigType emios_pwm_##n##_init[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_CONFIG) \ + }; \ + const struct pwm_nxp_s32_pulse_info emios_pwm_##n##_info = { \ + .pwm_pulse_channels = ARRAY_SIZE(emios_pwm_##n##_init), \ + .pwm_info = (Emios_Pwm_Ip_ChannelConfigType *)emios_pwm_##n##_init, \ + }; + +#define EMIOS_NXP_S32_INSTANCE_CHECK(idx, node_id) \ + ((DT_REG_ADDR(node_id) == IP_EMIOS_##idx##_BASE) ? idx : 0) + +#define EMIOS_NXP_S32_GET_INSTANCE(node_id) \ + LISTIFY(__DEBRACKET eMIOS_INSTANCE_COUNT, EMIOS_NXP_S32_INSTANCE_CHECK, (|), node_id) + +#define PWM_NXP_S32_INIT_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + EMIOS_PWM_GENERATE_CONFIG(n) \ + static const struct pwm_nxp_s32_config pwm_nxp_s32_config_##n = { \ + .base = (eMIOS_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .instance = EMIOS_NXP_S32_GET_INSTANCE(DT_INST_PARENT(n)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \ + .clock_subsys = (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name),\ + .pulse_info = (struct pwm_nxp_s32_pulse_info *)&emios_pwm_##n##_info, \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n) \ + }; \ + static struct pwm_nxp_s32_data pwm_nxp_s32_data_##n; \ + DEVICE_DT_INST_DEFINE(n, \ + &pwm_nxp_s32_init, \ + NULL, \ + &pwm_nxp_s32_data_##n, \ + &pwm_nxp_s32_config_##n, \ + POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, \ + &pwm_nxp_s32_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_NXP_S32_INIT_DEVICE) diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 31a4c1453d5..b5f7549bea8 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -642,6 +642,12 @@ status = "disabled"; }; }; + + pwm { + compatible = "nxp,s32-emios-pwm"; + #pwm-cells = <2>; + status = "disabled"; + }; }; emios1: emios@4008c000 { @@ -688,6 +694,12 @@ status = "disabled"; }; }; + + pwm { + compatible = "nxp,s32-emios-pwm"; + #pwm-cells = <2>; + status = "disabled"; + }; }; emios2: emios@40090000 { @@ -734,6 +746,12 @@ status = "disabled"; }; }; + + pwm { + compatible = "nxp,s32-emios-pwm"; + #pwm-cells = <2>; + status = "disabled"; + }; }; }; }; diff --git a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml new file mode 100644 index 00000000000..17ed23f9e46 --- /dev/null +++ b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml @@ -0,0 +1,155 @@ +description: | + NXP S32 eMIOS PWM node for S32 SoCs. Each channel in eMIOS can be configured + to use for PWM operation. There are several PWM modes supported by this module, + some modes only support on channels that have internal counter, some modes + require to use a reference timebase from a master bus. + + For example to configuring eMIOS instance 0 with channel 0 for mode OPWFMB, channel 1 + for mode OPWMB and channel 2 for mode OPWMCB with deadtime inserted at leading edge: + emios0_pwm: pwm { + pwm_0 { + channel = <0>; + pwm-mode = "MODE_OPWFMB"; + prescaler = <8>; + period = <65534>; + duty-cycle = <32768>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_1 { + channel = <1>; + master-bus = <&emios1_bus_a>; + pwm-mode = "MODE_OPWMB"; + duty-cycle = <32768>; + phase-shift = <100>; + polarity = "ACTIVE_LOW"; + }; + + pwm_2 { + channel = <2>; + master-bus = <&emios1_bus_b>; + pwm-mode = "MODE_OPWMCB_LEAD_EDGE"; + duty-cycle = <32768>; + dead-time = <100>; + polarity = "ACTIVE_LOW"; + }; + }; + + OPWMB and OPWMCB modes use reference timebase, the master bus is chosen over + phandle 'master-bus'. For OPWMB mode, PWM's period is master bus's period and + is 2 * master bus's period - 2 for OPWMCB mode. Please notice that the devicetree + node for master bus should be enabled and configured for using, please see + 'nxp,s32-emios' bindings. + +compatible: "nxp,s32-emios-pwm" + +include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true + + "#pwm-cells": + const: 2 + +pwm-cells: + - channel + # Period in terms of nanoseconds + - period + +child-binding: + description: | + eMIOS PWM channel configuration. + + properties: + channel: + type: int + required: true + description: eMIOS PWM channel + + master-bus: + type: phandle + description: | + A phandle to master-bus node that will be used as external timebase + for current channel, this can be bypassed if internal counter is used + for PWM operation. + + pwm-mode: + type: string + required: true + description: | + Select PWM mode: + - OPWFMB: provides waveforms with variable duty cycle and frequency, + this mode uses internal counter. + + - OPWMB: generate pulses with programmable leading and trailing + edge placement. The period is determined by period of + an external counter driven in MCB Up Mode. Changing PWM period + at runtime will impact to all channels share the same timebase. + The new period and cycle take effect in next period boundary. + + - OPWMCB: generates a center aligned PWM with dead time insertion to the + leading or trailing edge. The period is determined by period of + an external counter driven in MCB Up Down Mode. Changing PWM period + at runtime will impact to all channels share the same timebase, + The new period and cycle take effect in next period boundary. + enum: + - "MODE_OPWFMB" + - "MODE_OPWMB" + - "MODE_OPWMCB_TRAIL_EDGE" + - "MODE_OPWMCB_LEAD_EDGE" + + polarity: + type: string + required: true + description: | + Output polarity for PWM channel. + enum: + - "ACTIVE_LOW" + - "ACTIVE_HIGH" + + duty-cycle: + type: int + required: true + description: | + Duty-cycle (in ticks) for PWM channel at boot time. + + period: + type: int + description: | + Period (in ticks) for OPWFMB at boot time. Period for the rest + of PWM mode depends on period's master bus. Must be in range [2 ... 65535]. + + freeze: + type: boolean + description: Freeze individual internal counter when the chip enters Debug mode. + + prescaler-src: + type: string + default: "PRESCALED_CLOCK" + description: | + Select clock source for internal counter prescaler. + enum: + - "PRESCALED_CLOCK" # Clock source = eMIOS clock / (global prescaler) + - "MODULE_CLOCK" # Clock source = eMIOS clock + + prescaler: + type: int + description: | + The clock divider for internal counter prescaler. + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] + + dead-time: + type: int + default: 0 + description: | + Dead time (in ticks) for PWM channel in OPWMCB mode. + + phase-shift: + type: int + default: 0 + description: | + Phase Shift (in ticks) for PWM channel in OPWMB mode. From b92ad4b56aadf4c3998cf2ea513905af3e640974 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Mon, 26 Jun 2023 12:55:23 +0700 Subject: [PATCH 0027/4498] boards: mr_canhubk3: enable NXP S32 EMIOS PWM In this board, there are eight PWM channels from EMIOS 0 CH0 --> EMIOS 0 CH7 that can be used to generate PWM pulse to outside of the board. Moreover, there are three RGB leds that can use PWM pins for blinking, faded leds Signed-off-by: Dat Nguyen Duy --- boards/arm/mr_canhubk3/doc/index.rst | 1 + .../arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi | 18 ++ boards/arm/mr_canhubk3/mr_canhubk3.dts | 176 ++++++++++++++++++ boards/arm/mr_canhubk3/mr_canhubk3.yaml | 1 + .../drivers/led_pwm/boards/mr_canhubk3.conf | 6 + west.yml | 2 +- 6 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/led_pwm/boards/mr_canhubk3.conf diff --git a/boards/arm/mr_canhubk3/doc/index.rst b/boards/arm/mr_canhubk3/doc/index.rst index bc7add3c112..1bd71a064c3 100644 --- a/boards/arm/mr_canhubk3/doc/index.rst +++ b/boards/arm/mr_canhubk3/doc/index.rst @@ -56,6 +56,7 @@ ADC SAR on-chip adc LPSPI on-chip spi WDT FS26 SBC watchdog EMAC on-chip ethernet +eMIOS on-chip pwm ============ ========== ================================ The default configuration can be found in the Kconfig file diff --git a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi index 459215510cc..65f5fe77e8b 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi +++ b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi @@ -267,6 +267,24 @@ pinmux = , , ; + }; + }; + + emios0_default: emios0_default { + group1 { + pinmux = , , + , , + , , + , , + ; + output-enable; + }; + }; + + emios1_default: emios1_default { + group1 { + pinmux = , + ; output-enable; }; }; diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index f472eb0fe1c..ba271d7af3d 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -9,6 +9,7 @@ #include #include #include +#include #include "mr_canhubk3-pinctrl.dtsi" / { @@ -34,6 +35,12 @@ sw0 = &user_button_1; sw1 = &user_button_2; watchdog0 = &fs26_wdt; + /* For pwm test suites */ + pwm-0 = &emios0_pwm; + red-pwm-led = &user_led1_red_pwm; + green-pwm-led = &user_led1_green_pwm; + blue-pwm-led = &user_led1_blue_pwm; + pwm-led0 = &user_led1_blue_pwm; }; leds { @@ -52,6 +59,23 @@ }; }; + /* gpio-leds and pwm-leds are the same RGB LED and cannot be used at the same time. */ + pwmleds { + compatible = "pwm-leds"; + + user_led1_blue_pwm: user_led1_blue { + pwms = <&emios1_pwm 5 PWM_MSEC(20)>; + }; + + user_led1_green_pwm: user_led1_green { + pwms = <&emios1_pwm 10 PWM_MSEC(20)>; + }; + + user_led1_red_pwm: user_led1_red { + pwms = <&emios0_pwm 19 PWM_MSEC(20)>; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button_1: button_0 { @@ -378,3 +402,155 @@ full-duplex; }; }; + +&emios0 { + clock-divider = <200>; + status = "okay"; + + master_bus { + /* + * Timebase for PWM led, setting clock 50KHz for internal counter, + * default period is 1000 cycles <-> 20ms. + */ + emios0_bus_a { + mode = "MCB_UP_COUNTER"; + prescaler = <16>; + period = <1000>; + status = "okay"; + }; + }; + + emios0_pwm: pwm { + pinctrl-0 = <&emios0_default>; + pinctrl-names = "default"; + status = "okay"; + + /* Default clock for internal counter for PWM channel 0-7 is 100Khz */ + pwm_0 { + channel = <0>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_1 { + channel = <1>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_2 { + channel = <2>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_3 { + channel = <3>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_4 { + channel = <4>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_5 { + channel = <5>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_6 { + channel = <6>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + pwm_7 { + channel = <7>; + pwm-mode = "MODE_OPWFMB"; + period = <65535>; + duty-cycle = <0>; + prescaler = <8>; + polarity = "ACTIVE_HIGH"; + }; + + rgb_red { + channel = <19>; + master-bus = <&emios0_bus_a>; + duty-cycle = <0>; + pwm-mode = "MODE_OPWMB"; + polarity = "ACTIVE_LOW"; + }; + }; +}; + +&emios1 { + clock-divider = <200>; + status = "okay"; + + master_bus { + /* + * Timebase for PWM led, setting clock 50KHz for internal counter, + * default period is 1000 cycles <-> 20ms. + */ + emios1_bus_a { + prescaler = <16>; + mode = "MCB_UP_COUNTER"; + period = <1000>; + status = "okay"; + }; + + emios1_bus_f { + prescaler = <16>; + mode = "MCB_UP_COUNTER"; + period = <1000>; + status = "okay"; + }; + }; + + emios1_pwm: pwm { + pinctrl-0 = <&emios1_default>; + pinctrl-names = "default"; + status = "okay"; + + rgb_green { + channel = <10>; + master-bus = <&emios1_bus_a>; + duty-cycle = <0>; + pwm-mode = "MODE_OPWMB"; + polarity = "ACTIVE_LOW"; + }; + + rgb_blue { + channel = <5>; + master-bus = <&emios1_bus_f>; + duty-cycle = <0>; + pwm-mode = "MODE_OPWMB"; + polarity = "ACTIVE_LOW"; + }; + }; +}; diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.yaml b/boards/arm/mr_canhubk3/mr_canhubk3.yaml index d60d59838cc..a9d1ebf7c86 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.yaml +++ b/boards/arm/mr_canhubk3/mr_canhubk3.yaml @@ -18,3 +18,4 @@ supported: - spi - watchdog - netif:eth + - pwm diff --git a/samples/drivers/led_pwm/boards/mr_canhubk3.conf b/samples/drivers/led_pwm/boards/mr_canhubk3.conf new file mode 100644 index 00000000000..e42e5613d05 --- /dev/null +++ b/samples/drivers/led_pwm/boards/mr_canhubk3.conf @@ -0,0 +1,6 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +# Due to gpio-leds and pwm-leds are the same RGB LEDs so should not be used +# at the same time, need to disable this config when using pwm-leds. +CONFIG_LED_GPIO=n diff --git a/west.yml b/west.yml index 3cd299b480a..3a6e9c5c874 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: b0274481021b6343740f1970ef167d65ea67d30b + revision: 0ef57e8ee40f02f1dce4b4ad666c55885f941703 path: modules/hal/nxp groups: - hal From 168791e08ab2705f278333286f4e86be8b0540da Mon Sep 17 00:00:00 2001 From: Diogo Correia Date: Wed, 16 Aug 2023 16:24:17 +0100 Subject: [PATCH 0028/4498] winc1500: fix undefined declarations LOG_LEVEL > LOG_LEVEL_OFF guards were protecting a couple of function declarations. These functions were being used without taking this fact into consideration. These guards are now applied around the stack_stats() function only. Signed-off-by: Diogo Correia --- drivers/wifi/winc1500/wifi_winc1500.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 26488293628..758e776bf7c 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -158,11 +158,11 @@ struct winc1500_data { static struct winc1500_data w1500_data; #if LOG_LEVEL > LOG_LEVEL_OFF - static void stack_stats(void) { log_stack_usage(&winc1500_thread_data); } +#endif /* LOG_LEVEL > LOG_LEVEL_OFF */ static char *socket_error_string(int8_t err) { @@ -285,8 +285,6 @@ static char *socket_message_to_string(uint8_t message) } } -#endif /* LOG_LEVEL > LOG_LEVEL_OFF */ - /** * This function is called when the socket is to be opened. */ @@ -773,8 +771,9 @@ static void winc1500_wifi_cb(uint8_t message_type, void *pvMsg) default: break; } - +#if LOG_LEVEL > LOG_LEVEL_OFF stack_stats(); +#endif /* LOG_LEVEL > LOG_LEVEL_OFF */ } static void handle_socket_msg_connect(struct socket_data *sd, void *pvMsg) @@ -962,8 +961,9 @@ static void winc1500_socket_cb(SOCKET sock, uint8 message, void *pvMsg) break; } - +#if LOG_LEVEL > LOG_LEVEL_OFF stack_stats(); +#endif /* LOG_LEVEL > LOG_LEVEL_OFF */ } static void winc1500_thread(void) From d8fab9e4357a674a3b74dd697d938eae28bfb9bc Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Thu, 24 Aug 2023 11:06:29 +0100 Subject: [PATCH 0029/4498] stm32h7: spi: Add SPI loopback tests for 16 bits frames Enable these tests only for H7 and if DMA is not enabled, as running them with DMA would require modifying the dmamux configuration in devicetree to move half-words instead of bytes. Signed-off-by: Daniel Gaston Ochoa --- tests/drivers/spi/spi_loopback/src/spi.c | 64 +++++++++++++++++--- tests/drivers/spi/spi_loopback/testcase.yaml | 1 + 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index 62896fbcecf..a1904395847 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -25,21 +25,26 @@ LOG_MODULE_REGISTER(spi_loopback); #define MODE_LOOP 0 #endif -#define SPI_OP SPI_OP_MODE_MASTER | SPI_MODE_CPOL | MODE_LOOP | \ - SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE +#define SPI_OP(frame_size) SPI_OP_MODE_MASTER | SPI_MODE_CPOL | MODE_LOOP | \ + SPI_MODE_CPHA | SPI_WORD_SET(frame_size) | SPI_LINES_SINGLE -static struct spi_dt_spec spi_fast = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP, 0); -static struct spi_dt_spec spi_slow = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP, 0); +static struct spi_dt_spec spi_fast = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP(8), 0); +static struct spi_dt_spec spi_slow = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP(8), 0); + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) +static __used struct spi_dt_spec spi_fast_16 = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP(16), 0); +static __used struct spi_dt_spec spi_slow_16 = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP(16), 0); +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ /* to run this test, connect MOSI pin to the MISO of the SPI */ #define STACK_SIZE 512 -#define BUF_SIZE 17 +#define BUF_SIZE 18 #define BUF2_SIZE 36 #if CONFIG_NOCACHE_MEMORY -static const char tx_data[BUF_SIZE] = "0123456789abcdef\0"; +static const char tx_data[BUF_SIZE] = "0123456789abcdef-\0"; static __aligned(32) char buffer_tx[BUF_SIZE] __used __attribute__((__section__(".nocache"))); static __aligned(32) char buffer_rx[BUF_SIZE] __used __attribute__((__section__(".nocache"))); static const char tx2_data[BUF2_SIZE] = "Thequickbrownfoxjumpsoverthelazydog\0"; @@ -47,7 +52,7 @@ static __aligned(32) char buffer2_tx[BUF2_SIZE] __used __attribute__((__section_ static __aligned(32) char buffer2_rx[BUF2_SIZE] __used __attribute__((__section__(".nocache"))); #else /* this src memory shall be in RAM to support using as a DMA source pointer.*/ -static uint8_t buffer_tx[] = "0123456789abcdef\0"; +static uint8_t buffer_tx[] = "0123456789abcdef-\0"; static uint8_t buffer_rx[BUF_SIZE] = {}; static uint8_t buffer2_tx[] = "Thequickbrownfoxjumpsoverthelazydog\0"; @@ -577,6 +582,51 @@ ZTEST(spi_loopback, test_spi_loopback) goto end; } +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + +/* 16 bits DMA test require to change dmamux config. by adding: + * STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS + */ +#ifndef CONFIG_SPI_STM32_DMA + + zassert_true(spi_is_ready_dt(&spi_slow_16), + "Slow spi lookback (16 bits) device is not ready"); + + LOG_INF("SPI test slow config (16 bits)"); + + if (spi_complete_multiple(&spi_slow_16) || + spi_complete_loop(&spi_slow_16) || + spi_null_tx_buf(&spi_slow_16) || + spi_rx_half_start(&spi_slow_16) || + spi_rx_half_end(&spi_slow_16) || + spi_rx_every_4(&spi_slow_16) +#if (CONFIG_SPI_ASYNC) + || spi_async_call(&spi_slow_16) +#endif /* (CONFIG_SPI_ASYNC) */ + ) { + goto end; + } + + zassert_true(spi_is_ready_dt(&spi_fast_16), + "Fast spi lookback (16 bits) device is not ready"); + + LOG_INF("SPI test fast config (16 bits)"); + + if (spi_complete_multiple(&spi_fast_16) || + spi_complete_loop(&spi_fast_16) || + spi_null_tx_buf(&spi_fast_16) || + spi_rx_half_start(&spi_fast_16) || + spi_rx_half_end(&spi_fast_16) || + spi_rx_every_4(&spi_fast_16) +#if (CONFIG_SPI_ASYNC) + || spi_async_call(&spi_fast_16) +#endif /* (CONFIG_SPI_ASYNC) */ + ) { + goto end; + } +#endif /* CONFIG_SPI_STM32_DMA */ +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ + if (spi_resource_lock_test(&spi_slow, &spi_fast)) { goto end; } diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index 42e649fed22..a71f2d9b885 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -44,6 +44,7 @@ tests: - nucleo_l152re - nucleo_wl55jc - nucleo_h743zi + - nucleo_h753zi - stm32h573i_dk integration_platforms: - nucleo_g474re From 7ca35f94eeb94a398b61f0257b5fb637f88609ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 30 Aug 2023 08:18:49 +0700 Subject: [PATCH 0030/4498] mr_canhubk3: add missing pinmux settings for SW2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GPIO pin for `sw2` was missing to be configured as input for external interrupts. Signed-off-by: Manuel Argüelles --- boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi index 65f5fe77e8b..1c3ff008508 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi +++ b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi @@ -9,7 +9,7 @@ &pinctrl { eirq0_default: eirq0_default { group1 { - pinmux = , ; + pinmux = , , ; input-enable; }; }; From 3c5f3da4d862489b72bf120ea1974553afe79b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 30 Aug 2023 08:46:55 +0200 Subject: [PATCH 0031/4498] doc: Add Sphinx extension for code samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a new Sphinx extension for both a code-sample directive and role. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 308 +++++++++++++++++++++++++++++++ doc/_static/css/custom.css | 15 ++ doc/conf.py | 1 + 3 files changed, 324 insertions(+) create mode 100644 doc/_extensions/zephyr/domain.py diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py new file mode 100644 index 00000000000..1b5cce28bab --- /dev/null +++ b/doc/_extensions/zephyr/domain.py @@ -0,0 +1,308 @@ +""" +Zephyr Extension +################ + +Copyright (c) 2023 The Linux Foundation +SPDX-License-Identifier: Apache-2.0 + +Introduction +============ + +This extension adds a new ``zephyr`` domain for handling the documentation of various entities +specific to the Zephyr RTOS project (ex. code samples). + +Directives +---------- + +- ``zephyr:code-sample::`` - Defines a code sample. + The directive takes an ID as the main argument, and accepts ``:name:`` (human-readable short name + of the sample) and ``:relevant-api:`` (a space separated list of Doxygen group(s) for APIs the + code sample is a good showcase of) as options. + The content of the directive is used as the description of the code sample. + + Example: + + ``` + .. zephyr:code-sample:: blinky + :name: Blinky + :relevant-api: gpio_interface + + Blink an LED forever using the GPIO API. + ``` + +Roles +----- + +- ``:zephyr:code-sample:`` - References a code sample. + The role takes the ID of the code sample as the argument. The role renders as a link to the code + sample, and the link text is the name of the code sample (or a custom text if an explicit name is + provided). + + Example: + + ``` + Check out :zephyr:code-sample:`sample-foo` for an example of how to use the foo API. You may + also be interested in :zephyr:code-sample:`this one `. + ``` + +""" +from typing import Any, Dict, Iterator, List, Tuple + +from breathe.directives.content_block import DoxygenGroupDirective +from docutils import nodes +from docutils.nodes import Node +from docutils.parsers.rst import Directive, directives +from sphinx import addnodes +from sphinx.domains import Domain, ObjType +from sphinx.roles import XRefRole +from sphinx.transforms import SphinxTransform +from sphinx.transforms.post_transforms import SphinxPostTransform +from sphinx.util import logging +from sphinx.util.nodes import NodeMatcher, make_refnode + +__version__ = "0.1.0" + +logger = logging.getLogger(__name__) + + +class CodeSampleNode(nodes.Element): + pass + + +class RelatedCodeSamplesNode(nodes.Element): + pass + + +class ConvertCodeSampleNode(SphinxTransform): + default_priority = 100 + + def apply(self): + matcher = NodeMatcher(CodeSampleNode) + for node in self.document.traverse(matcher): + self.convert_node(node) + + def convert_node(self, node): + """ + Transforms a `CodeSampleNode` into a `nodes.section` named after the code sample name. + + Moves all sibling nodes that are after the `CodeSampleNode` in the documement under this new + section. + """ + parent = node.parent + siblings_to_move = [] + if parent is not None: + index = parent.index(node) + siblings_to_move = parent.children[index + 1 :] + + # TODO remove once all :ref:`sample-xyz` have migrated to :zephyr:code-sample:`xyz` + # as this is the recommended way to reference code samples going forward. + self.env.app.env.domaindata["std"]["labels"][node["id"]] = ( + self.env.docname, + node["id"], + node["name"], + ) + self.env.app.env.domaindata["std"]["anonlabels"][node["id"]] = ( + self.env.docname, + node["id"], + ) + + # Create a new section + new_section = nodes.section(ids=[node["id"]]) + new_section += nodes.title(text=node["name"]) + + # Move existing content from the custom node to the new section + new_section.extend(node.children) + + # Move the sibling nodes under the new section + new_section.extend(siblings_to_move) + + # Replace the custom node with the new section + node.replace_self(new_section) + + # Remove the moved siblings from their original parent + for sibling in siblings_to_move: + parent.remove(sibling) + + +class ProcessRelatedCodeSamplesNode(SphinxPostTransform): + default_priority = 5 # before ReferencesResolver + + def run(self, **kwargs: Any) -> None: + matcher = NodeMatcher(RelatedCodeSamplesNode) + for node in self.document.traverse(matcher): + id = node["id"] # the ID of the node is the name of the doxygen group for which we + # want to list related code samples + + code_samples = self.env.domaindata["zephyr"]["code-samples"].values() + # Filter out code samples that don't reference this doxygen group + code_samples = [ + code_sample for code_sample in code_samples if id in code_sample["relevant-api"] + ] + + if len(code_samples) > 0: + admonition = nodes.admonition() + admonition += nodes.title(text="Related code samples") + admonition["classes"].append("related-code-samples") + sample_ul = nodes.bullet_list() + for code_sample in sorted(code_samples, key=lambda x: x["name"]): + sample_para = nodes.paragraph() + sample_xref = addnodes.pending_xref( + "", + refdomain="zephyr", + reftype="code-sample", + reftarget=code_sample["id"], + refwarn=True, + ) + sample_xref += nodes.inline(text=code_sample["name"]) + sample_para += sample_xref + sample_para += nodes.inline(text=" - ") + sample_para += nodes.inline(text=code_sample["description"].astext()) + sample_li = nodes.list_item() + sample_li += sample_para + sample_ul += sample_li + admonition += sample_ul + + # replace node with the newly created admonition + node.replace_self(admonition) + else: + # remove node if there are no code samples + node.replace_self([]) + + +class CodeSampleDirective(Directive): + """ + A directive for creating a code sample node in the Zephyr documentation. + """ + + required_arguments = 1 # ID + optional_arguments = 0 + option_spec = {"name": directives.unchanged, "relevant-api": directives.unchanged} + has_content = True + + def run(self): + code_sample_id = self.arguments[0] + env = self.state.document.settings.env + code_samples = env.domaindata["zephyr"]["code-samples"] + + if code_sample_id in code_samples: + logger.warning( + f"Code sample {code_sample_id} already exists. " + f"Other instance in {code_samples[code_sample_id]['docname']}", + location=(env.docname, self.lineno), + ) + + name = self.options.get("name", code_sample_id) + relevant_api_list = self.options.get("relevant-api", "").split() + + # Create a node for description and populate it with parsed content + description_node = nodes.container(ids=[f"{code_sample_id}-description"]) + self.state.nested_parse(self.content, self.content_offset, description_node) + + code_sample = { + "id": code_sample_id, + "name": name, + "description": description_node, + "relevant-api": relevant_api_list, + "docname": env.docname, + } + + domain = env.get_domain("zephyr") + domain.add_code_sample(code_sample) + + # Create an instance of the custom node + code_sample_node = CodeSampleNode() + code_sample_node["id"] = code_sample_id + code_sample_node["name"] = name + + return [code_sample_node] + + +class ZephyrDomain(Domain): + """Zephyr domain""" + + name = "zephyr" + label = "Zephyr Project" + + roles = { + "code-sample": XRefRole(innernodeclass=nodes.inline), + } + + directives = {"code-sample": CodeSampleDirective} + + object_types: Dict[str, ObjType] = { + "code-sample": ObjType("code sample", "code-sample"), + } + + initial_data: Dict[str, Any] = {"code-samples": {}} + + def clear_doc(self, docname: str) -> None: + self.data["code-samples"] = { + sample_id: sample_data + for sample_id, sample_data in self.data["code-samples"].items() + if sample_data["docname"] != docname + } + + def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + self.data["code-samples"].update(otherdata["code-samples"]) + + def get_objects(self): + for _, code_sample in self.data["code-samples"].items(): + yield ( + code_sample["name"], + code_sample["name"], + "code sample", + code_sample["docname"], + code_sample["id"], + 1, + ) + + # used by Sphinx Immaterial theme + def get_object_synopses(self) -> Iterator[Tuple[Tuple[str, str], str]]: + for _, code_sample in self.data["code-samples"].items(): + yield ( + (code_sample["docname"], code_sample["id"]), + code_sample["description"].astext(), + ) + + def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): + if type == "code-sample": + code_sample_info = self.data["code-samples"].get(target) + if code_sample_info: + if not node.get("refexplicit"): + contnode = [nodes.Text(code_sample_info["name"])] + + return make_refnode( + builder, + fromdocname, + code_sample_info["docname"], + code_sample_info["id"], + contnode, + code_sample_info["description"], + ) + + def add_code_sample(self, code_sample): + self.data["code-samples"][code_sample["id"]] = code_sample + + +class CustomDoxygenGroupDirective(DoxygenGroupDirective): + """Monkey patch for Breathe's DoxygenGroupDirective.""" + + def run(self) -> List[Node]: + nodes = super().run() + return [RelatedCodeSamplesNode(id=self.arguments[0]), *nodes] + + +def setup(app): + app.add_domain(ZephyrDomain) + + app.add_transform(ConvertCodeSampleNode) + app.add_post_transform(ProcessRelatedCodeSamplesNode) + + # monkey-patching of Breathe's DoxygenGroupDirective + app.add_directive("doxygengroup", CustomDoxygenGroupDirective, override=True) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index da9f379d41d..30d8607f9dc 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -544,6 +544,21 @@ a.internal:visited code.literal { color: var(--admonition-tip-title-color); } +/* Admonition tweaks - sphinx_togglebutton */ + +.rst-content .admonition.toggle { + overflow: visible; +} + +.rst-content .admonition.toggle button { + display: inline-flex; +} + +.rst-content .admonition.toggle .tb-icon { + height: 1em; + width: 1em; +} + /* Keyboard shortcuts tweaks */ kbd, .kbd, .rst-content :not(dl.option-list) > :not(dt):not(kbd):not(.kbd) > kbd, diff --git a/doc/conf.py b/doc/conf.py index 551bb599b0a..53825924818 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -85,6 +85,7 @@ "notfound.extension", "sphinx_copybutton", "zephyr.external_content", + "zephyr.domain", ] # Only use SVG converter when it is really needed, e.g. LaTeX. From e7829752ae5db73a384ce59aecba71024e85489e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 5 Sep 2023 18:57:22 +0200 Subject: [PATCH 0032/4498] doc: Update sample.tmpl with new directive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the sample.tmpl file so that it encourages people to use the new :zephyr:code-sample: directive. Signed-off-by: Benjamin Cabé --- doc/templates/sample.tmpl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/templates/sample.tmpl b/doc/templates/sample.tmpl index c3b59b89904..e8560b03c46 100644 --- a/doc/templates/sample.tmpl +++ b/doc/templates/sample.tmpl @@ -1,11 +1,13 @@ -.. _descriptive_title_link_name: +.. zephyr:code-sample:: a_unique_id_for_the_sample + :name: A descriptive short name for the sample + :relevant-api: space-separated list of Doxygen groups of APIs this sample is a good showcase of -[A Descriptive Title] -##################### + Short text description of the sample. It is recommended to word this as if you were completing + the sentence "This code sample shows how to ..."). Overview ******** -[A short description about the sample and what it does] +[A longer description about the sample and what it does] Requirements ************ From 5832f6ed5fc5049f2f94368370f845c46bd1ecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 30 Aug 2023 08:53:43 +0200 Subject: [PATCH 0033/4498] doc: Use new Sphinx extension for code samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new code-sample directive and roles in a few places to demonstrate how it works. Signed-off-by: Benjamin Cabé --- boards/arm/nrf52_adafruit_feather/doc/index.rst | 2 +- samples/basic/blinky/README.rst | 9 +++++---- samples/basic/blinky_pwm/README.rst | 12 ++++++------ samples/basic/button/README.rst | 9 +++++---- samples/basic/fade_led/README.rst | 2 +- samples/basic/hash_map/README.rst | 7 ++++--- samples/bluetooth/encrypted_advertising/README.rst | 4 ++-- .../kernel/condition_variables/condvar/README.rst | 9 +++++---- samples/synchronization/README.rst | 7 ++++--- 9 files changed, 33 insertions(+), 28 deletions(-) diff --git a/boards/arm/nrf52_adafruit_feather/doc/index.rst b/boards/arm/nrf52_adafruit_feather/doc/index.rst index 38e6fd50f22..281dbb48d5e 100644 --- a/boards/arm/nrf52_adafruit_feather/doc/index.rst +++ b/boards/arm/nrf52_adafruit_feather/doc/index.rst @@ -169,7 +169,7 @@ the board are working properly with Zephyr: - :ref:`blinky-sample` - :ref:`button-sample` - :ref:`fade-led-sample` -- :ref:`blink-led-sample` +- :ref:`pwm-blinky-sample` - :ref:`96b_carbon_multi_thread_blinky` You can build and flash the examples to make sure Zephyr is running correctly on diff --git a/samples/basic/blinky/README.rst b/samples/basic/blinky/README.rst index 6c30bef1af7..22a1c96b9f7 100644 --- a/samples/basic/blinky/README.rst +++ b/samples/basic/blinky/README.rst @@ -1,7 +1,8 @@ -.. _blinky-sample: +.. zephyr:code-sample:: blinky-sample + :name: Blinky + :relevant-api: gpio_interface -Blinky -###### + Blink an LED forever using the GPIO API. Overview ******** @@ -15,7 +16,7 @@ The source code shows how to: #. Configure the GPIO pin as an output #. Toggle the pin forever -See :ref:`pwm-blinky-sample` for a similar sample that uses the PWM API instead. +See :zephyr:code-sample:`pwm-blinky-sample` for a similar sample that uses the PWM API instead. .. _blinky-sample-requirements: diff --git a/samples/basic/blinky_pwm/README.rst b/samples/basic/blinky_pwm/README.rst index ec59a6b3a97..638b7597d27 100644 --- a/samples/basic/blinky_pwm/README.rst +++ b/samples/basic/blinky_pwm/README.rst @@ -1,14 +1,14 @@ -.. _blink-led-sample: -.. _pwm-blinky-sample: +.. zephyr:code-sample:: pwm-blinky-sample + :name: PWM Blinky + :relevant-api: pwm_interface -PWM Blinky -########## + Blink an LED using the PWM API. Overview ******** -This application blinks a LED using the :ref:`PWM API `. See -:ref:`blinky-sample` for a GPIO-based sample. +This application blinks an LED using the :ref:`PWM API `. See +:zephyr:code-sample:`blinky-sample` for a GPIO-based sample. The LED starts blinking at a 1 Hz frequency. The frequency doubles every 4 seconds until it reaches 128 Hz. The frequency will then be halved every 4 diff --git a/samples/basic/button/README.rst b/samples/basic/button/README.rst index 5b17ee4eadb..3d487375df9 100644 --- a/samples/basic/button/README.rst +++ b/samples/basic/button/README.rst @@ -1,7 +1,8 @@ -.. _button-sample: +.. zephyr:code-sample:: button-sample + :name: Button + :relevant-api: gpio_interface -Button -###### + Handle GPIO inputs with interrupts. Overview ******** @@ -27,7 +28,7 @@ You may see additional build errors if the ``sw0`` alias exists, but is not properly defined. The sample additionally supports an optional ``led0`` devicetree alias. This is -the same alias used by the :ref:`blinky-sample`. If this is provided, the LED +the same alias used by the :zephyr:code-sample:`blinky-sample`. If this is provided, the LED will be turned on when the button is pressed, and turned off off when it is released. diff --git a/samples/basic/fade_led/README.rst b/samples/basic/fade_led/README.rst index d86f0f2edfb..5ea1a4cf732 100644 --- a/samples/basic/fade_led/README.rst +++ b/samples/basic/fade_led/README.rst @@ -18,7 +18,7 @@ Requirements and Wiring *********************** This sample has the same requirements and wiring considerations as the -:ref:`pwm-blinky-sample`. +:zephyr:code-sample:`pwm-blinky-sample`. Building and Running ******************** diff --git a/samples/basic/hash_map/README.rst b/samples/basic/hash_map/README.rst index 5126e826d23..977a558e0c0 100644 --- a/samples/basic/hash_map/README.rst +++ b/samples/basic/hash_map/README.rst @@ -1,7 +1,8 @@ -.. _system_hashmap: +.. zephyr:code-sample:: system_hashmap + :name: System Hashmap + :relevant-api: hashmap_apis -System Hashmap -############## + Insert, replace, and remove entries in a hashmap. Overview ******** diff --git a/samples/bluetooth/encrypted_advertising/README.rst b/samples/bluetooth/encrypted_advertising/README.rst index 170fcbfaab5..01e38890f32 100644 --- a/samples/bluetooth/encrypted_advertising/README.rst +++ b/samples/bluetooth/encrypted_advertising/README.rst @@ -25,8 +25,8 @@ Requirements ************ * Two boards with Bluetooth Low Energy support -* Two boards with a push button connected via a GPIO pin, see :ref:`Button - sample ` for more details +* Two boards with a push button connected via a GPIO pin, see :zephyr:code-sample:`button-sample` + for more details Building and Running ******************** diff --git a/samples/kernel/condition_variables/condvar/README.rst b/samples/kernel/condition_variables/condvar/README.rst index 79a41f870b2..51f4cf0beb2 100644 --- a/samples/kernel/condition_variables/condvar/README.rst +++ b/samples/kernel/condition_variables/condvar/README.rst @@ -1,12 +1,13 @@ -.. _samples_kernel_condvar: +.. zephyr:code-sample:: kernel-condvar + :name: Condition Variables + :relevant-api: condvar_apis -Condition Variables -################### + Manipulate condition variables in a multithreaded application. Overview ******** -This sample demonstrates the usage of condition variables in a +This sample demonstrates the usage of :ref:`condition variables ` in a multithreaded application. Condition variables are used with a mutex to signal changing states (conditions) from one thread to another thread. A thread uses a condition variable to wait for a condition to diff --git a/samples/synchronization/README.rst b/samples/synchronization/README.rst index f45d3d42d3e..d67d93ec0b0 100644 --- a/samples/synchronization/README.rst +++ b/samples/synchronization/README.rst @@ -1,7 +1,8 @@ -.. _synchronization_sample: +.. zephyr:code-sample:: synchronization_sample + :name: Synchronization Sample + :relevant-api: thread_apis semaphore_apis -Synchronization Sample -###################### + Manipulate basic kernel synchronization primitives. Overview ******** From b2977b7657ed8e446c46cf89758616ca035ace96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 30 Aug 2023 09:26:48 +0200 Subject: [PATCH 0034/4498] doc: Make code-samples admonition collapsible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use sphinx-toggle to make "Related code samples" collapsible. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 2 ++ doc/conf.py | 1 + doc/requirements.txt | 1 + 3 files changed, 4 insertions(+) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 1b5cce28bab..769b1b8a73c 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -142,7 +142,9 @@ def run(self, **kwargs: Any) -> None: if len(code_samples) > 0: admonition = nodes.admonition() admonition += nodes.title(text="Related code samples") + admonition["collapsible"] = "" # used by sphinx-immaterial theme admonition["classes"].append("related-code-samples") + admonition["classes"].append("dropdown") # used by sphinx-togglebutton extension sample_ul = nodes.bullet_list() for code_sample in sorted(code_samples, key=lambda x: x["name"]): sample_para = nodes.paragraph() diff --git a/doc/conf.py b/doc/conf.py index 53825924818..05e4eb3d803 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -84,6 +84,7 @@ "zephyr.vcs_link", "notfound.extension", "sphinx_copybutton", + "sphinx_togglebutton", "zephyr.external_content", "zephyr.domain", ] diff --git a/doc/requirements.txt b/doc/requirements.txt index 2d90048e16f..45bb461e518 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -8,6 +8,7 @@ sphinxcontrib-svg2pdfconverter pygments>=2.9 sphinx-notfound-page sphinx-copybutton +sphinx-togglebutton # YAML validation. Used by zephyr_module. PyYAML>=5.1 From a15752c79cba648541b87fd54d58379daa61c6db Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 29 Aug 2023 07:44:54 +0100 Subject: [PATCH 0035/4498] mgmt: mcumgr: Split mgmt defines to new file This splits defines to a separate file, which are commonly needed by out-of-tree projects whereby the full MCUmgr include cannot be used due to undefined types being used. Signed-off-by: Jamie McCrae --- include/zephyr/mgmt/mcumgr/mgmt/mgmt.h | 119 +------------- .../zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h | 150 ++++++++++++++++++ 2 files changed, 151 insertions(+), 118 deletions(-) create mode 100644 include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h index eb9ecfcf2a9..e681ea2b939 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -23,124 +24,6 @@ extern "C" { * @{ */ -/** - * Used at end of MCUmgr handlers to return an error if the message size limit was reached, - * or OK if it was not - */ -#define MGMT_RETURN_CHECK(ok) ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE - -/** Opcodes; encoded in first byte of header. */ -enum mcumgr_op_t { - /** Read op-code */ - MGMT_OP_READ = 0, - - /** Read response op-code */ - MGMT_OP_READ_RSP, - - /** Write op-code */ - MGMT_OP_WRITE, - - /** Write response op-code */ - MGMT_OP_WRITE_RSP, -}; - -/** - * MCUmgr groups. The first 64 groups are reserved for system level mcumgr - * commands. Per-user commands are then defined after group 64. - */ -enum mcumgr_group_t { - /** OS (operating system) group */ - MGMT_GROUP_ID_OS = 0, - - /** Image management group, used for uploading firmware images */ - MGMT_GROUP_ID_IMAGE, - - /** Statistic management group, used for retieving statistics */ - MGMT_GROUP_ID_STAT, - - /** Settings management (config) group, used for reading/writing settings */ - MGMT_GROUP_ID_SETTINGS, - - /** Log management group (unused) */ - MGMT_GROUP_ID_LOG, - - /** Crash group (unused) */ - MGMT_GROUP_ID_CRASH, - - /** Split image management group (unused) */ - MGMT_GROUP_ID_SPLIT, - - /** Run group (unused) */ - MGMT_GROUP_ID_RUN, - - /** FS (file system) group, used for performing file IO operations */ - MGMT_GROUP_ID_FS, - - /** Shell management group, used for executing shell commands */ - MGMT_GROUP_ID_SHELL, - - /** User groups defined from 64 onwards */ - MGMT_GROUP_ID_PERUSER = 64, - - /** Zephyr-specific groups decrease from PERUSER to avoid collision with upstream and - * user-defined groups. - * Zephyr-specific: Basic group - */ - ZEPHYR_MGMT_GRP_BASIC = (MGMT_GROUP_ID_PERUSER - 1), -}; - -/** - * MCUmgr error codes. - */ -enum mcumgr_err_t { - /** No error (success). */ - MGMT_ERR_EOK = 0, - - /** Unknown error. */ - MGMT_ERR_EUNKNOWN, - - /** Insufficient memory (likely not enough space for CBOR object). */ - MGMT_ERR_ENOMEM, - - /** Error in input value. */ - MGMT_ERR_EINVAL, - - /** Operation timed out. */ - MGMT_ERR_ETIMEOUT, - - /** No such file/entry. */ - MGMT_ERR_ENOENT, - - /** Current state disallows command. */ - MGMT_ERR_EBADSTATE, - - /** Response too large. */ - MGMT_ERR_EMSGSIZE, - - /** Command not supported. */ - MGMT_ERR_ENOTSUP, - - /** Corrupt */ - MGMT_ERR_ECORRUPT, - - /** Command blocked by processing of other command */ - MGMT_ERR_EBUSY, - - /** Access to specific function, command or resource denied */ - MGMT_ERR_EACCESSDENIED, - - /** Requested SMP MCUmgr protocol version is not supported (too old) */ - MGMT_ERR_UNSUPPORTED_TOO_OLD, - - /** Requested SMP MCUmgr protocol version is not supported (too new) */ - MGMT_ERR_UNSUPPORTED_TOO_NEW, - - /** User errors defined from 256 onwards */ - MGMT_ERR_EPERUSER = 256 -}; - -#define MGMT_HDR_SIZE 8 - /** @typedef mgmt_alloc_rsp_fn * @brief Allocates a buffer suitable for holding a response. * diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h new file mode 100644 index 00000000000..2f33b6d22a1 --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018-2021 mcumgr authors + * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_MGMT_MGMT_DEFINES_ +#define H_MGMT_MGMT_DEFINES_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief MCUmgr mgmt API + * @defgroup mcumgr_mgmt_api MCUmgr mgmt API + * @ingroup mcumgr + * @{ + */ + +/** + * Used at end of MCUmgr handlers to return an error if the message size limit was reached, + * or OK if it was not + */ +#define MGMT_RETURN_CHECK(ok) ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE + +/** Opcodes; encoded in first byte of header. */ +enum mcumgr_op_t { + /** Read op-code */ + MGMT_OP_READ = 0, + + /** Read response op-code */ + MGMT_OP_READ_RSP, + + /** Write op-code */ + MGMT_OP_WRITE, + + /** Write response op-code */ + MGMT_OP_WRITE_RSP, +}; + +/** + * MCUmgr groups. The first 64 groups are reserved for system level mcumgr + * commands. Per-user commands are then defined after group 64. + */ +enum mcumgr_group_t { + /** OS (operating system) group */ + MGMT_GROUP_ID_OS = 0, + + /** Image management group, used for uploading firmware images */ + MGMT_GROUP_ID_IMAGE, + + /** Statistic management group, used for retieving statistics */ + MGMT_GROUP_ID_STAT, + + /** Settings management (config) group, used for reading/writing settings */ + MGMT_GROUP_ID_SETTINGS, + + /** Log management group (unused) */ + MGMT_GROUP_ID_LOG, + + /** Crash group (unused) */ + MGMT_GROUP_ID_CRASH, + + /** Split image management group (unused) */ + MGMT_GROUP_ID_SPLIT, + + /** Run group (unused) */ + MGMT_GROUP_ID_RUN, + + /** FS (file system) group, used for performing file IO operations */ + MGMT_GROUP_ID_FS, + + /** Shell management group, used for executing shell commands */ + MGMT_GROUP_ID_SHELL, + + /** User groups defined from 64 onwards */ + MGMT_GROUP_ID_PERUSER = 64, + + /** Zephyr-specific groups decrease from PERUSER to avoid collision with upstream and + * user-defined groups. + * Zephyr-specific: Basic group + */ + ZEPHYR_MGMT_GRP_BASIC = (MGMT_GROUP_ID_PERUSER - 1), +}; + +/** + * MCUmgr error codes. + */ +enum mcumgr_err_t { + /** No error (success). */ + MGMT_ERR_EOK = 0, + + /** Unknown error. */ + MGMT_ERR_EUNKNOWN, + + /** Insufficient memory (likely not enough space for CBOR object). */ + MGMT_ERR_ENOMEM, + + /** Error in input value. */ + MGMT_ERR_EINVAL, + + /** Operation timed out. */ + MGMT_ERR_ETIMEOUT, + + /** No such file/entry. */ + MGMT_ERR_ENOENT, + + /** Current state disallows command. */ + MGMT_ERR_EBADSTATE, + + /** Response too large. */ + MGMT_ERR_EMSGSIZE, + + /** Command not supported. */ + MGMT_ERR_ENOTSUP, + + /** Corrupt */ + MGMT_ERR_ECORRUPT, + + /** Command blocked by processing of other command */ + MGMT_ERR_EBUSY, + + /** Access to specific function, command or resource denied */ + MGMT_ERR_EACCESSDENIED, + + /** Requested SMP MCUmgr protocol version is not supported (too old) */ + MGMT_ERR_UNSUPPORTED_TOO_OLD, + + /** Requested SMP MCUmgr protocol version is not supported (too new) */ + MGMT_ERR_UNSUPPORTED_TOO_NEW, + + /** User errors defined from 256 onwards */ + MGMT_ERR_EPERUSER = 256 +}; + +#define MGMT_HDR_SIZE 8 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* MGMT_MGMT_DEFINES_H_ */ From 76be0d28ddb210559b7bd5c991133abfa3116040 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 29 Aug 2023 07:46:48 +0100 Subject: [PATCH 0036/4498] west.yaml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 9bf7ce8c5fe8152836a6e00bd4444153bd950342 Brings following Zephyr relevant fixes: - 9bf7ce8 zephyr: Fix build for non-arm archs - e188dbb zephyr: Fix boot serial extensions Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3a6e9c5c874..420db368b5a 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 11ecbf639d826c084973beed709a63d51d9b684e + revision: 9bf7ce8c5fe8152836a6e00bd4444153bd950342 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From 01a6ecb6bf4cef76bfd042eb5ab351347a1444f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 10:06:38 +0200 Subject: [PATCH 0037/4498] Bluetooth: Mesh: Send od priv proxy with devkey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the mesh 1.1 spec, section 4.4.14.1: “. The access layer security on the On-Demand Private Proxy Client model shall use the device key of the node supporting the On-Demand Private Proxy Server model.“ This commit alters the API and implementation to reflect this. Signed-off-by: Anders Storrø --- include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h | 11 ++++++----- subsys/bluetooth/mesh/od_priv_proxy_cli.c | 12 +++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h index 89e63c177a0..f9734d78d3e 100644 --- a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h +++ b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h @@ -47,7 +47,6 @@ struct bt_mesh_od_priv_proxy_cli { _bt_mesh_od_priv_proxy_cli_op, NULL, cli_data, \ &_bt_mesh_od_priv_proxy_cli_cb) - /** @brief Get the target's On-Demand Private GATT Proxy state. * * This method can be used asynchronously by setting @p val_rsp as NULL. @@ -57,12 +56,13 @@ struct bt_mesh_od_priv_proxy_cli { * To process the response arguments of an async method, register * the @c od_status callback in @c bt_mesh_od_priv_proxy_cli struct. * - * @param ctx Message context for the message. + * @param net_idx Network index to encrypt with. + * @param addr Target node address. * @param val_rsp Response buffer for On-Demand Private GATT Proxy value. * * @return 0 on success, or (negative) error code otherwise. */ -int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val_rsp); +int bt_mesh_od_priv_proxy_cli_get(uint16_t net_idx, uint16_t addr, uint8_t *val_rsp); /** @brief Set the target's On-Demand Private GATT Proxy state. * @@ -73,13 +73,14 @@ int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val_rsp) * To process the response arguments of an async method, register * the @c od_status callback in @c bt_mesh_od_priv_proxy_cli struct. * - * @param ctx Message context for the message. + * @param net_idx Network index to encrypt with. + * @param addr Target node address. * @param val On-Demand Private GATT Proxy state to be set * @param val_rsp Response buffer for On-Demand Private GATT Proxy value. * * @return 0 on success, or (negative) error code otherwise. */ -int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint8_t *val_rsp); +int bt_mesh_od_priv_proxy_cli_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *val_rsp); /** @brief Set the transmission timeout value. * diff --git a/subsys/bluetooth/mesh/od_priv_proxy_cli.c b/subsys/bluetooth/mesh/od_priv_proxy_cli.c index 3dc8722ff72..67f5ac961ad 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_cli.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_cli.c @@ -54,23 +54,25 @@ const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_cli_op[] = { BT_MESH_MODEL_OP_END }; -int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val) +int bt_mesh_od_priv_proxy_cli_get(uint16_t net_idx, uint16_t addr, uint8_t *val_rsp) { + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp = { .ack = &cli->ack_ctx, .op = OP_OD_PRIV_PROXY_STATUS, - .user_data = val, + .user_data = val_rsp, .timeout = msg_timeout, }; BT_MESH_MODEL_BUF_DEFINE(msg, OP_OD_PRIV_PROXY_GET, 0); bt_mesh_model_msg_init(&msg, OP_OD_PRIV_PROXY_GET); - return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val ? &rsp : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, val_rsp ? &rsp : NULL); } -int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint8_t *val_rsp) +int bt_mesh_od_priv_proxy_cli_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *val_rsp) { + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp = { .ack = &cli->ack_ctx, .op = OP_OD_PRIV_PROXY_STATUS, @@ -83,7 +85,7 @@ int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint net_buf_simple_add_u8(&msg, val); - return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val_rsp ? &rsp : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, val_rsp ? &rsp : NULL); } void bt_mesh_od_priv_proxy_cli_timeout_set(int32_t timeout) From 2f05af891de21b93bd21902155452bfc988dfcba Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 31 Jul 2023 10:31:25 +0100 Subject: [PATCH 0038/4498] doc: services: device_mgmt: smp: Add SMP version 2 details Adds SMP version 2 error response details to the documentation. Signed-off-by: Jamie McCrae --- .../device_mgmt/smp_groups/smp_group_0.rst | 395 +++++++++++++----- .../device_mgmt/smp_groups/smp_group_1.rst | 238 ++++++----- .../device_mgmt/smp_groups/smp_group_2.rst | 102 +++-- .../device_mgmt/smp_groups/smp_group_8.rst | 306 +++++++++----- .../device_mgmt/smp_groups/smp_group_9.rst | 51 ++- doc/services/device_mgmt/smp_protocol.rst | 44 +- 6 files changed, 783 insertions(+), 353 deletions(-) diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index 839b0e06be3..761f2a4df43 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -62,7 +62,7 @@ where: :align: center +-----------------------+---------------------------------------------------+ - | "d" | string to be replied by echo service | + | "d" | string to be replied by echo service. | +-----------------------+---------------------------------------------------+ Echo response @@ -91,23 +91,44 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+-----------------------------------------------+ - | "r" | Replying echo string | - +-----------------------+-----------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+-----------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "r" | replying echo string. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ Task statistics command *********************** @@ -168,41 +189,62 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+-----------------------------------------------+ - | | string identifying task | - +-----------------------+-----------------------------------------------+ - | "prio" | task priority | - +-----------------------+-----------------------------------------------+ - | "tid" | numeric task ID | - +-----------------------+-----------------------------------------------+ - | "state" | numeric task state | - +-----------------------+-----------------------------------------------+ - | "stkuse" | task's/thread's stack usage | - +-----------------------+-----------------------------------------------+ - | "stksiz" | task's/thread's stack size | - +-----------------------+-----------------------------------------------+ - | "cswcnt" | task's/thread's context switches | - +-----------------------+-----------------------------------------------+ - | "runtime" | task's/thread's runtime in "ticks" | - +-----------------------+-----------------------------------------------+ - | "last_checkin" | set to 0 by Zephyr | - +-----------------------+-----------------------------------------------+ - | "next_checkin" | set to 0 by Zephyr | - +-----------------------+-----------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+-----------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | | string identifying task. | + +------------------+-------------------------------------------------------------------------+ + | "prio" | task priority. | + +------------------+-------------------------------------------------------------------------+ + | "tid" | numeric task ID. | + +------------------+-------------------------------------------------------------------------+ + | "state" | numeric task state. | + +------------------+-------------------------------------------------------------------------+ + | "stkuse" | task's/thread's stack usage. | + +------------------+-------------------------------------------------------------------------+ + | "stksiz" | task's/thread's stack size. | + +------------------+-------------------------------------------------------------------------+ + | "cswcnt" | task's/thread's context switches. | + +------------------+-------------------------------------------------------------------------+ + | "runtime" | task's/thread's runtime in "ticks". | + +------------------+-------------------------------------------------------------------------+ + | "last_checkin" | set to 0 by Zephyr. | + +------------------+-------------------------------------------------------------------------+ + | "next_checkin" | set to 0 by Zephyr. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ .. note:: The unit for "stkuse" and "stksiz" is system dependent and in case of Zephyr @@ -260,33 +302,53 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+--------------------------------------------------+ - | | string representing the pool name, used as a key | - | | for dictionary with pool statistics data | - +-----------------------+--------------------------------------------------+ - | "blksiz" | size of the memory blocks in the pool | - +-----------------------+--------------------------------------------------+ - | "nblks" | number of blocks in the pool | - +-----------------------+--------------------------------------------------+ - | "nfree" | number of free blocks | - +-----------------------+--------------------------------------------------+ - | "min" | lowest number of free blocks the pool reached | - | | during run-time | - +-----------------------+--------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+--------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | | string representing the pool name, used as a key for dictionary with | + | | pool statistics data. | + +------------------+-------------------------------------------------------------------------+ + | "blksiz" | size of the memory block in the pool. | + +------------------+-------------------------------------------------------------------------+ + | "nblks" | number of blocks in the pool. | + +------------------+-------------------------------------------------------------------------+ + | "nfree" | number of free blocks. | + +------------------+-------------------------------------------------------------------------+ + | "min" | lowest number of free blocks the pool reached during run-time. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ Date-time command ***************** @@ -342,24 +404,44 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------+ - | "datetime" | String in format | - | | yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ | - +-----------------------+---------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t`; | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "datetime" | String in format: ``yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ``. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ Date-time set @@ -394,10 +476,9 @@ where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | "datetime" | String in format | - | | yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ | - +-----------------------+---------------------------------------------------+ + +---------------+----------------------------------------------------------+ + | "datetime" | String in format: ``yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ``. | + +---------------+----------------------------------------------------------+ Date-time set response ---------------------- @@ -416,21 +497,42 @@ Date-time set response header fields: The command sends an empty CBOR map as data if successful. In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ System reset ************ @@ -460,7 +562,7 @@ System reset request header fields: Normally the command sends an empty CBOR map as data, but if a previous reset attempt has responded with "rc" equal to :c:enum:`MGMT_ERR_EBUSY` then the -following map may be send to force a reset: +following map may be sent to force a reset: .. code-block:: none @@ -495,21 +597,42 @@ System reset response header fields The command sends an empty CBOR map as data if successful. In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t`; | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ MCUmgr Parameters ***************** @@ -557,26 +680,46 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+--------------------------------------------------+ - | "buf_size" | Single SMP buffer size, this includes SMP header | - | | and CBOR payload | - +-----------------------+--------------------------------------------------+ - | "buf_count" | Number of SMP buffers supported | - +-----------------------+--------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t`; | - | | only appears if non-zero (error condition). | - +-----------------------+--------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "buf_size" | Single SMP buffer size, this includes SMP header and CBOR payload. | + +------------------+-------------------------------------------------------------------------+ + | "buf_count" | Number of SMP buffers supported. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ .. _mcumgr_os_application_info: @@ -649,23 +792,51 @@ OS/Application info response header fields | ``1`` | ``0`` | ``7`` | +--------+--------------+----------------+ -CBOR data of response: +CBOR data of successful response: .. code-block:: none { (str)"output" : (str) - (opt,str)"rc" : (int) } +In case of error the CBOR data takes the form: + +.. tabs:: + + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } + where: .. table:: :align: center - +--------------+-----------------------------------------------+ - | "output" | Text response including requested parameters. | - +--------------+-----------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +--------------+-----------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "output" | Text response including requested parameters. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ diff --git a/doc/services/device_mgmt/smp_groups/smp_group_1.rst b/doc/services/device_mgmt/smp_groups/smp_group_1.rst index 7f5ffa171dd..819d8330149 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_1.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_1.rst @@ -127,73 +127,85 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - (str,opt)"rsn" : (str) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + (str,opt)"rsn" : (str) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | "image" | semi-optional image number; the field is not | - | | required when only one image is supported by | - | | running application | - +-----------------------+---------------------------------------------------+ - | "slot" | slot number within "image"; each image has two | - | | slots : primary (running one) = 0 and secondary | - | | (for DFU dual-bank purposes) = 1 | - +-----------------------+---------------------------------------------------+ - | "version" | string representing image version, as set with | - | | ``imgtool`` | - +-----------------------+---------------------------------------------------+ - | "hash" | SHA256 hash of the image header and body. Note | - | | that this will not be the same as the SHA256 of | - | | the whole file, it is the field in the MCUboot | - | | TLV section that contains a hash of the data | - | | which is used for signature verification | - | | purposes. This field is optional but only | - | | optional when using MCUboot's serial recovery | - | | feature with one pair of image slots, Kconfig | - | | :kconfig:option:`CONFIG_BOOT_SERIAL_IMG_GRP_HASH` | - | | can be disabled to remove support for hashes in | - | | this configuration. MCUmgr in applications must | - | | support sending hashes. | - | | | - | | .. note:: | - | | See ``IMAGE_TLV_SHA256`` in the MCUboot image | - | | format documentation link below. | - +-----------------------+---------------------------------------------------+ - | "bootable" | true if image has bootable flag set; | - | | this field does not have to be present if false | - +-----------------------+---------------------------------------------------+ - | "pending" | true if image is set for next swap | - | | this field does not have to be present if false | - +-----------------------+---------------------------------------------------+ - | "confirmed" | true if image has been confirmed | - | | this field does not have to be present if false | - +-----------------------+---------------------------------------------------+ - | "active" | true if image is currently active application | - | | this field does not have to be present if false | - +-----------------------+---------------------------------------------------+ - | "permanent" | true if image is to stay in primary slot after | - | | next boot | - | | this field does not have to be present if false | - +-----------------------+---------------------------------------------------+ - | "splitStatus" | states whether loader of split image is compatible| - | | with application part; this is unused by Zephyr | - +-----------------------+---------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------------+ - | "rsn" | optional string that clarifies reason for an | - | | error; specifically useful for error code ``1``, | - | | unknown error | - +-----------------------+---------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "image" | semi-optional image number; the field is not required when only one | + | | image is supported by the running application. | + +------------------+-------------------------------------------------------------------------+ + | "slot" | slot number within "image"; each image has two slots : primary (running | + | | one) = 0 and secondary (for DFU dual-bank purposes) = 1. | + +------------------+-------------------------------------------------------------------------+ + | "version" | string representing image version, as set with ``imgtool``. | + +------------------+-------------------------------------------------------------------------+ + | "hash" | SHA256 hash of the image header and body. Note that this will not be | + | | the same as the SHA256 of the whole file, it is the field in the | + | | MCUboot TLV section that contains a hash of the data which is used for | + | | signature verification purposes. This field is optional but only | + | | optional when using MCUboot's serial recovery feature with one pair of | + | | image slots, Kconfig :kconfig:option:`CONFIG_BOOT_SERIAL_IMG_GRP_HASH` | + | | can be disabled to remove support for hashes in this configuration. | + | | MCUmgr in applications must support sending hashes. | + | | | + | | .. note:: | + | | See ``IMAGE_TLV_SHA256`` in the MCUboot image format documentation | + | | link below. | + +------------------+-------------------------------------------------------------------------+ + | "bootable" | true if image has bootable flag set; this field does not have to be | + | | present if false. | + +------------------+-------------------------------------------------------------------------+ + | "pending" | true if image is set for next swap; this field does not have to be | + | | present if false. | + +------------------+-------------------------------------------------------------------------+ + | "confirmed" | true if image has been confirmed; this field does not have to be | + | | present if false. | + +------------------+-------------------------------------------------------------------------+ + | "active" | true if image is currently active application; this field does not have | + | | to be present if false. | + +------------------+-------------------------------------------------------------------------+ + | "permanent" | true if image is to stay in primary slot after the next boot; this | + | | does not have to be present if false. | + +------------------+-------------------------------------------------------------------------+ + | "splitStatus" | states whether loader of split image is compatible with application | + | | part; this is unused by Zephyr. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rsn" | optional string that clarifies reason for an error; specifically useful | + | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + +------------------+-------------------------------------------------------------------------+ .. note:: For more information on how does image/slots function, please refer to @@ -351,34 +363,52 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - (str,opt)"rsn" : (str) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + (str,opt)"rsn" : (str) + } where: .. table:: :align: center - +-----------------------+-----------------------------------------------------+ - | "off" | offset of last successfully written byte of update. | - +-----------------------+-----------------------------------------------------+ - | "match" | indicates if the uploaded data successfully matches | - | | the provided SHA256 hash or not, only sent in the | - | | final packet if | - | | :kconfig:option:`CONFIG_IMG_ENABLE_IMAGE_CHECK` is | - | | enabled. | - +-----------------------+-----------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` only | - | | appears if non-zero (error condition). | - +-----------------------+-----------------------------------------------------+ - | "rsn" | Optional string that clarifies reason for an error; | - | | specifically useful for error code ``1``, unknown | - | | error. | - +-----------------------+-----------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "off" | offset of last successfully written byte of update. | + +------------------+-------------------------------------------------------------------------+ + | "match" | indicates if the uploaded data successfully matches the provided SHA256 | + | | hash or not, only sent in the final packet if | + | | :kconfig:option:`CONFIG_IMG_ENABLE_IMAGE_CHECK` is enabled. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rsn" | optional string that clarifies reason for an error; specifically useful | + | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + +------------------+-------------------------------------------------------------------------+ The "off" field is only included in responses to successfully processed requests; if "rc" is negative then "off" may not appear. @@ -441,26 +471,46 @@ Image erase response header fields: The command sends an empty CBOR map as data if successful. In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - (str,opt)"rsn" : (str) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + (str,opt)"rsn" : (str) + } where: .. table:: :align: center - +-----------------------+--------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+--------------------------------------------------+ - | "rsn" | Optional string that clarifies reason for an | - | | error; specifically useful when rc value is | - | | :c:enum:`MGMT_ERR_EUNKNOWN` | - +-----------------------+--------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rsn" | optional string that clarifies reason for an error; specifically useful | + | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + +------------------+-------------------------------------------------------------------------+ .. note:: Response from Zephyr running device may have "rc" value of diff --git a/doc/services/device_mgmt/smp_groups/smp_group_2.rst b/doc/services/device_mgmt/smp_groups/smp_group_2.rst index 7d2c5bd853c..1528a9611fe 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_2.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_2.rst @@ -55,7 +55,7 @@ where: :align: center +-----------------------+---------------------------------------------------+ - | "name" | is group name | + | "name" | group name. | +-----------------------+---------------------------------------------------+ Statistics: group data response @@ -86,31 +86,51 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none - { - (str)"rc" : (int) - } +.. tabs:: + + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | "name" | this is name of group the response contains data | - | | for | - +-----------------------+---------------------------------------------------+ - | "fields" | this is map of entries within groups that consists| - | | of pairs where entry name is mapped to value it | - | | represents in statistics | - +-----------------------+---------------------------------------------------+ - | | single entry to value mapping; value is hardcoded | - | | to unsigned integer type, in a CBOR meaning | - +-----------------------+---------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "name" | this is name of group the response contains data for. | + +------------------+-------------------------------------------------------------------------+ + | "fields" | this is map of entries within groups that consists of pairs where the | + | | entry name is mapped to value it represents in statistics. | + +------------------+-------------------------------------------------------------------------+ + | | single entry to value mapping; value is hardcoded to unsigned integer | + | | type, in a CBOR meaning. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ Statistics: list of groups ************************** @@ -164,21 +184,43 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none - { - (str)"rc" : (int) - } +.. tabs:: + + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | "stat_list" | array of strings representing group names; this | - | | array may be empty if there are no groups | - +-----------------------+---------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "stat_list" | array of strings representing group names; this array may be empty if | + | | there are no groups. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ diff --git a/doc/services/device_mgmt/smp_groups/smp_group_8.rst b/doc/services/device_mgmt/smp_groups/smp_group_8.rst index d86208346f8..502a5757169 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_8.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_8.rst @@ -112,32 +112,49 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+--------------------------------------------------+ - | "off" | offset the response is for | - +-----------------------+--------------------------------------------------+ - | "data" | chunk of data read from file; it is CBOR encoded | - | | stream of bytes with embedded size; | - | | "data" appears only in responses where "rc" is 0 | - +-----------------------+--------------------------------------------------+ - | "len" | length of file, this field is only mandatory | - | | when "off" is 0 | - +-----------------------+--------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+--------------------------------------------------+ - -In case when "rc" is not 0, success, the other fields will not appear. + +------------------+-------------------------------------------------------------------------+ + | "off" | offset the response is for. | + +------------------+-------------------------------------------------------------------------+ + | "data" | chunk of data read from file; it is CBOR encoded stream of bytes with | + | | embedded size; "data" appears only in responses where "rc" is 0. | + +------------------+-------------------------------------------------------------------------+ + | "len" | length of file, this field is only mandatory when "off" is 0. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ File upload *********** @@ -204,15 +221,15 @@ where: :align: center +-----------------------+---------------------------------------------------+ - | "off" | offset to start/continue upload at | + | "off" | offset to start/continue upload at. | +-----------------------+---------------------------------------------------+ | "data" | chunk of data to write to the file; | - | | it is CBOR encoded with length embedded | + | | it is CBOR encoded with length embedded. | +-----------------------+---------------------------------------------------+ - | "name" | absolute path to a file | + | "name" | absolute path to a file. | +-----------------------+---------------------------------------------------+ | "len" | length of file, this field is only mandatory | - | | when "off" is 0 | + | | when "off" is 0. | +-----------------------+---------------------------------------------------+ File upload response @@ -239,23 +256,44 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. .. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------+ - | "off" | offset of last successfully written data. | - +-----------------------+---------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "off" | offset of last successfully written data. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ File status *********** @@ -291,7 +329,7 @@ where: :align: center +-----------------------+---------------------------------------------------+ - | "name" | absolute path to a file | + | "name" | absolute path to a file. | +-----------------------+---------------------------------------------------+ File status response @@ -318,25 +356,44 @@ CBOR data of successful response: In case of error the CBOR data takes form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------+ - | "len" | length of file (in bytes) | - +-----------------------+---------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+---------------------------------------------+ - -In case when "rc" is not 0, success, the other fields will not appear. + +------------------+-------------------------------------------------------------------------+ + | "len" | length of file (in bytes). | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ File hash/checksum ****************** @@ -381,18 +438,18 @@ where: :align: center +-----------------------+---------------------------------------------------+ - | "name" | absolute path to a file | + | "name" | absolute path to a file. | +-----------------------+---------------------------------------------------+ | "type" | type of hash/checksum to perform | | | :ref:`mcumgr_group_8_hash_checksum_types` or omit | - | | to use default | + | | to use default. | +-----------------------+---------------------------------------------------+ | "off" | offset to start hash/checksum calculation at | - | | (optional, 0 if not provided) | + | | (optional, 0 if not provided). | +-----------------------+---------------------------------------------------+ | "len" | maximum length of data to read from file to | | | generate hash/checksum with (optional, full file | - | | size if not provided) | + | | size if not provided). | +-----------------------+---------------------------------------------------+ .. _mcumgr_group_8_hash_checksum_types: @@ -441,34 +498,52 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+--------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+--------------------------------------------------+ - | "type" | type of hash/checksum that was performed | - | | :ref:`mcumgr_group_8_hash_checksum_types` | - +-----------------------+--------------------------------------------------+ - | "off" | offset that hash/checksum calculation started at | - | | (only present if off is not 0) | - +-----------------------+--------------------------------------------------+ - | "len" | length of input data used for hash/checksum | - | | generation (in bytes) | - +-----------------------+--------------------------------------------------+ - | "output" | output hash/checksum | - +-----------------------+--------------------------------------------------+ - -In case when "rc" is not 0, success, the other fields will not appear. + +------------------+-------------------------------------------------------------------------+ + | "type" | type of hash/checksum that was performed | + | | :ref:`mcumgr_group_8_hash_checksum_types`. | + +------------------+-------------------------------------------------------------------------+ + | "off" | offset that hash/checksum calculation started at (only present if not | + | | 0). | + +------------------+-------------------------------------------------------------------------+ + | "len" | length of input data used for hash/checksum generation (in bytes). | + +------------------+-------------------------------------------------------------------------+ + | "output" | output hash/checksum. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ Supported file hash/checksum types ********************************** @@ -523,28 +598,50 @@ CBOR data of successful response: In case of error the CBOR data takes form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | | name of the hash/checksum type | - | | :ref:`mcumgr_group_8_hash_checksum_types` | - +-----------------------+---------------------------------------------------+ - | "format" | format that the hash/checksum returns where 0 is | - | | for numerical and 1 is for byte array. | - +-----------------------+---------------------------------------------------+ - | "size" | size (in bytes) of output hash/checksum response. | - +-----------------------+---------------------------------------------------+ - -In case when "rc" is not 0, success, the other fields will not appear. + +----------------------+-------------------------------------------------------------------------+ + | | name of the hash/checksum type | + | | :ref:`mcumgr_group_8_hash_checksum_types`. | + +----------------------+-------------------------------------------------------------------------+ + | "format" | format that the hash/checksum returns where 0 is for numerical and 1 is | + | | for byte array. | + +----------------------+-------------------------------------------------------------------------+ + | "size" | size (in bytes) of output hash/checksum response. | + +----------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +----------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +----------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +----------------------+-------------------------------------------------------------------------+ File close ********** @@ -585,18 +682,39 @@ File close response header: The command sends an empty CBOR map as data if successful. In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+------------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ diff --git a/doc/services/device_mgmt/smp_groups/smp_group_9.rst b/doc/services/device_mgmt/smp_groups/smp_group_9.rst index 615a364e812..7e857f70a0d 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_9.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_9.rst @@ -56,11 +56,11 @@ where: +-----------------------+---------------------------------------------------+ | "argv" | array consisting of strings representing command | - | | and its arguments | + | | and its arguments. | +-----------------------+---------------------------------------------------+ - | | command to be executed | + | | command to be executed. | +-----------------------+---------------------------------------------------+ - | | optional arguments to command | + | | optional arguments to command. | +-----------------------+---------------------------------------------------+ Shell command line execute response @@ -88,25 +88,46 @@ CBOR data of successful response: In case of error the CBOR data takes the form: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+-----------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - | | only appears if non-zero (error condition). | - +-----------------------+-----------------------------------------------+ - | "o" | command output | - +-----------------------+-----------------------------------------------+ - | "ret" | return code from shell command execution | - +-----------------------+-----------------------------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "o" | command output. | + +------------------+-------------------------------------------------------------------------+ + | "ret" | return code from shell command execution. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ .. note:: In older versions of Zephyr, "rc" was used for both the mcumgr status code diff --git a/doc/services/device_mgmt/smp_protocol.rst b/doc/services/device_mgmt/smp_protocol.rst index 4524b830b0a..44c30f32d29 100644 --- a/doc/services/device_mgmt/smp_protocol.rst +++ b/doc/services/device_mgmt/smp_protocol.rst @@ -163,22 +163,50 @@ non-responsive. Minimal response SMP data ========================= -Minimal response is CBOR directory: +Minimal response is: -.. code-block:: none +.. tabs:: - { - (str)"rc" : (int) - } + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } where: .. table:: :align: center - +-----------------------+--------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` | - +-----------------------+--------------------------+ + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + +Note that in the case of a successful command, an empty map will be returned (``rc``/``err`` is +only returned if there is an error condition, therefore if only an empty map is returned or a +response lacks these, the request can be considered as being successful. For SMP version 2, +errors relating to SMP itself that are not group specific will still be returned as ``rc`` +errors, SMP version 2 clients must therefore be able to handle both types of errors. Specifications of management groups supported by Zephyr ******************************************************* From 774da57db90c53121d7d282092f246bb73b18c52 Mon Sep 17 00:00:00 2001 From: Rick Talbott Date: Fri, 23 Jun 2023 16:20:33 -0600 Subject: [PATCH 0039/4498] shell: Add shell command command rem Added the shell comment command. Signed-off-by: Rick Talbott --- subsys/shell/shell_cmds.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsys/shell/shell_cmds.c b/subsys/shell/shell_cmds.c index 101f2fe5a61..10a9d6f418f 100644 --- a/subsys/shell/shell_cmds.c +++ b/subsys/shell/shell_cmds.c @@ -12,6 +12,7 @@ #include "shell_vt100.h" #define SHELL_MSG_CMD_NOT_SUPPORTED "Command not supported.\n" +#define SHELL_HELP_COMMENT "Ignore lines beginning with 'rem '" #define SHELL_HELP_RETVAL "Print return value of most recent command" #define SHELL_HELP_CLEAR "Clear screen." #define SHELL_HELP_BACKENDS "List active shell backends.\n" @@ -202,6 +203,15 @@ static int terminal_size_get(const struct shell *sh) return ret_val; } +static int cmd_comment(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return 0; +} + static int cmd_clear(const struct shell *sh, size_t argc, char **argv) { ARG_UNUSED(argv); @@ -530,6 +540,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_resize, SHELL_SUBCMD_SET_END ); +SHELL_COND_CMD_REGISTER(CONFIG_SHELL_VT100_COMMANDS, rem, NULL, + SHELL_HELP_COMMENT, cmd_comment); SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_VT100_COMMANDS, clear, NULL, SHELL_HELP_CLEAR, cmd_clear, 1, 0); SHELL_CMD_REGISTER(shell, &m_sub_shell, SHELL_HELP_SHELL, NULL); From 9fb6c9ddd7adac3e2fba6005dda751b9c276509c Mon Sep 17 00:00:00 2001 From: Yuchao Guo Date: Sat, 8 Jul 2023 21:41:55 +0800 Subject: [PATCH 0040/4498] west: runners: uf2: Add more fstype check for is_uf2_partition During testing it was found that if the partition type was displayed as msdos it could not be detected correctly, so this partition type determination was added. Signed-off-by: Yuchao Guo --- scripts/west_commands/runners/uf2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/runners/uf2.py b/scripts/west_commands/runners/uf2.py index 7cb5eced390..87db248c7bf 100644 --- a/scripts/west_commands/runners/uf2.py +++ b/scripts/west_commands/runners/uf2.py @@ -49,7 +49,7 @@ def get_uf2_info_path(part) -> Path: @staticmethod def is_uf2_partition(part): try: - return ((part.fstype in ['vfat', 'FAT']) and + return ((part.fstype in ['vfat', 'FAT', 'msdos']) and UF2BinaryRunner.get_uf2_info_path(part).is_file()) except PermissionError: return False From af03d374f5d38a1c0aee96b3121886034863a402 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 4 Sep 2023 19:26:38 +0000 Subject: [PATCH 0041/4498] manifest: Update SOF tree with zephyr related fixes - Updates with a patch fixing CONTAINER_OF issues by Fabio. - init.h include fixes by Gerlad Signed-off-by: Anas Nashif --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 420db368b5a..83cb644b9fb 100644 --- a/west.yml +++ b/west.yml @@ -314,7 +314,7 @@ manifest: groups: - debug - name: sof - revision: ee40f61b5725b6615f1abea4a78cc4d90ce144b8 + revision: e32b825cd6447342b9a308284ccea33b5d249e9f path: modules/audio/sof - name: tflite-micro revision: 9156d050927012da87079064db59d07f03b8baf6 From 82abe486467aacb3a6e550f4493d53ce826f7941 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Tue, 5 Sep 2023 22:08:16 +0200 Subject: [PATCH 0042/4498] MAINTAINERS: IEEE 802.15.4 When IEEE 802.15.4 maintainership was updated in ec98555f42 the L2 part was missed. Proposes to assign both L1 and L2 to the same persons. Signed-off-by: Florian Grandel --- MAINTAINERS.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 0a446919631..ce4a649c356 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1992,10 +1992,9 @@ Networking: "Networking: Native IEEE 802.15.4": status: maintained maintainers: - - tbursztyka + - fgrandel collaborators: - rlubos - - fgrandel - jukkar files: - doc/connectivity/networking/api/ieee802154.rst From 105a254f4daf04404abdec51adadc5e446979743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 13 Jul 2023 12:19:35 +0200 Subject: [PATCH 0043/4498] drivers: codec: doc: Fix Doxygen comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a few missing brief descriptions + fixed existing ones to use proper Javadoc-style comments. Signed-off-by: Benjamin Cabé --- include/zephyr/audio/codec.h | 71 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/include/zephyr/audio/codec.h b/include/zephyr/audio/codec.h index e65b00d87f3..18a26a01adb 100644 --- a/include/zephyr/audio/codec.h +++ b/include/zephyr/audio/codec.h @@ -32,64 +32,65 @@ extern "C" { * PCM audio sample rates */ typedef enum { - AUDIO_PCM_RATE_8K = 8000, - AUDIO_PCM_RATE_16K = 16000, - AUDIO_PCM_RATE_24K = 24000, - AUDIO_PCM_RATE_32K = 32000, - AUDIO_PCM_RATE_44P1K = 44100, - AUDIO_PCM_RATE_48K = 48000, - AUDIO_PCM_RATE_96K = 96000, - AUDIO_PCM_RATE_192K = 192000, + AUDIO_PCM_RATE_8K = 8000, /**< 8 kHz sample rate */ + AUDIO_PCM_RATE_16K = 16000, /**< 16 kHz sample rate */ + AUDIO_PCM_RATE_24K = 24000, /**< 24 kHz sample rate */ + AUDIO_PCM_RATE_32K = 32000, /**< 32 kHz sample rate */ + AUDIO_PCM_RATE_44P1K = 44100, /**< 44.1 kHz sample rate */ + AUDIO_PCM_RATE_48K = 48000, /**< 48 kHz sample rate */ + AUDIO_PCM_RATE_96K = 96000, /**< 96 kHz sample rate */ + AUDIO_PCM_RATE_192K = 192000, /**< 192 kHz sample rate */ } audio_pcm_rate_t; /** * PCM audio sample bit widths */ typedef enum { - AUDIO_PCM_WIDTH_16_BITS = 16, - AUDIO_PCM_WIDTH_20_BITS = 20, - AUDIO_PCM_WIDTH_24_BITS = 24, - AUDIO_PCM_WIDTH_32_BITS = 32, + AUDIO_PCM_WIDTH_16_BITS = 16, /**< 16-bit sample width */ + AUDIO_PCM_WIDTH_20_BITS = 20, /**< 20-bit sample width */ + AUDIO_PCM_WIDTH_24_BITS = 24, /**< 24-bit sample width */ + AUDIO_PCM_WIDTH_32_BITS = 32, /**< 32-bit sample width */ } audio_pcm_width_t; /** * Digital Audio Interface (DAI) type */ typedef enum { - AUDIO_DAI_TYPE_I2S, /* I2S Interface */ - AUDIO_DAI_TYPE_INVALID, /* Other interfaces can be added here */ + AUDIO_DAI_TYPE_I2S, /**< I2S Interface */ + AUDIO_DAI_TYPE_INVALID, /**< Other interfaces can be added here */ } audio_dai_type_t; /** - * Codec properties that can be set by audio_codec_set_property() + * Codec properties that can be set by audio_codec_set_property(). */ typedef enum { - AUDIO_PROPERTY_OUTPUT_VOLUME, - AUDIO_PROPERTY_OUTPUT_MUTE, + AUDIO_PROPERTY_OUTPUT_VOLUME, /**< Output volume */ + AUDIO_PROPERTY_OUTPUT_MUTE, /**< Output mute/unmute */ } audio_property_t; /** - * Audio channel identifiers to use in audio_codec_set_property() + * Audio channel identifiers to use in audio_codec_set_property(). */ typedef enum { - AUDIO_CHANNEL_FRONT_LEFT, - AUDIO_CHANNEL_FRONT_RIGHT, - AUDIO_CHANNEL_LFE, - AUDIO_CHANNEL_FRONT_CENTER, - AUDIO_CHANNEL_REAR_LEFT, - AUDIO_CHANNEL_REAR_RIGHT, - AUDIO_CHANNEL_REAR_CENTER, - AUDIO_CHANNEL_SIDE_LEFT, - AUDIO_CHANNEL_SIDE_RIGHT, - AUDIO_CHANNEL_ALL, + AUDIO_CHANNEL_FRONT_LEFT, /**< Front left channel */ + AUDIO_CHANNEL_FRONT_RIGHT, /**< Front right channel */ + AUDIO_CHANNEL_LFE, /**< Low frequency effect channel */ + AUDIO_CHANNEL_FRONT_CENTER, /**< Front center channel */ + AUDIO_CHANNEL_REAR_LEFT, /**< Rear left channel */ + AUDIO_CHANNEL_REAR_RIGHT, /**< Rear right channel */ + AUDIO_CHANNEL_REAR_CENTER, /**< Rear center channel */ + AUDIO_CHANNEL_SIDE_LEFT, /**< Side left channel */ + AUDIO_CHANNEL_SIDE_RIGHT, /**< Side right channel */ + AUDIO_CHANNEL_ALL, /**< All channels */ } audio_channel_t; /** - * Digital Audio Interface Configuration + * @brief Digital Audio Interface Configuration. + * * Configuration is dependent on DAI type */ typedef union { - struct i2s_config i2s; /* I2S configuration */ + struct i2s_config i2s; /**< I2S configuration */ /* Other DAI types go here */ } audio_dai_cfg_t; @@ -97,17 +98,17 @@ typedef union { * Codec configuration parameters */ struct audio_codec_cfg { - uint32_t mclk_freq; /* MCLK input frequency in Hz */ - audio_dai_type_t dai_type; /* Digital interface type */ - audio_dai_cfg_t dai_cfg; /* DAI configuration info */ + uint32_t mclk_freq; /**< MCLK input frequency in Hz */ + audio_dai_type_t dai_type; /**< Digital interface type */ + audio_dai_cfg_t dai_cfg; /**< DAI configuration info */ }; /** * Codec property values */ typedef union { - int vol; /* Volume level in 0.5dB resolution */ - bool mute; /* mute if true, unmute if false */ + int vol; /**< Volume level in 0.5dB resolution */ + bool mute; /**< Mute if @a true, unmute if @a false */ } audio_property_value_t; /** From f9192a2e4a78cdd91df65d59eadad8701603bdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 13 Jul 2023 16:09:49 +0200 Subject: [PATCH 0044/4498] drivers: dmic: doc: Cleanup Doxygen documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed several comments that were not proper Doxygen ones, causing documentation for this file to be incomplete. Signed-off-by: Benjamin Cabé --- include/zephyr/audio/dmic.h | 137 ++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 59 deletions(-) diff --git a/include/zephyr/audio/dmic.h b/include/zephyr/audio/dmic.h index 78e996c9b06..e6736b8676c 100644 --- a/include/zephyr/audio/dmic.h +++ b/include/zephyr/audio/dmic.h @@ -43,110 +43,129 @@ extern "C" { * DMIC driver states */ enum dmic_state { - DMIC_STATE_UNINIT, /* Uninitialized */ - DMIC_STATE_INITIALIZED, /* Initialized */ - DMIC_STATE_CONFIGURED, /* Configured */ - DMIC_STATE_ACTIVE, /* Active */ - DMIC_STATE_PAUSED, /* Paused */ + DMIC_STATE_UNINIT, /**< Uninitialized */ + DMIC_STATE_INITIALIZED, /**< Initialized */ + DMIC_STATE_CONFIGURED, /**< Configured */ + DMIC_STATE_ACTIVE, /**< Active */ + DMIC_STATE_PAUSED, /**< Paused */ }; /** * DMIC driver trigger commands */ enum dmic_trigger { - DMIC_TRIGGER_STOP, /* stop stream */ - DMIC_TRIGGER_START, /* start stream */ - DMIC_TRIGGER_PAUSE, /* pause the stream */ - DMIC_TRIGGER_RELEASE, /* release paused stream */ - DMIC_TRIGGER_RESET, /* reset */ + DMIC_TRIGGER_STOP, /**< Stop stream */ + DMIC_TRIGGER_START, /**< Start stream */ + DMIC_TRIGGER_PAUSE, /**< Pause stream */ + DMIC_TRIGGER_RELEASE, /**< Release paused stream */ + DMIC_TRIGGER_RESET, /**< Reset stream */ }; /** * PDM Channels LEFT / RIGHT */ enum pdm_lr { - PDM_CHAN_LEFT, - PDM_CHAN_RIGHT, + PDM_CHAN_LEFT, /**< Left channel */ + PDM_CHAN_RIGHT, /**< Right channel */ }; /** * PDM Input/Output signal configuration */ struct pdm_io_cfg { - /* parameters global to all PDM controllers */ - - /* minimum clock frequency supported by the mic */ + /** + * @name Parameters common to all PDM controllers + *@{ + */ + /** Minimum clock frequency supported by the mic */ uint32_t min_pdm_clk_freq; - /* maximum clock frequency supported by the mic */ + /** Maximum clock frequency supported by the mic */ uint32_t max_pdm_clk_freq; - /* minimum duty cycle in % supported by the mic */ + /** Minimum duty cycle in % supported by the mic */ uint8_t min_pdm_clk_dc; - /* maximum duty cycle in % supported by the mic */ + /** Maximum duty cycle in % supported by the mic */ uint8_t max_pdm_clk_dc; + /** + * @} + */ - /* parameters unique to each PDM controller */ - - /* Bit mask to optionally invert PDM clock */ + /** + * @name Parameters unique to each PDM controller + * @{ + */ + /** Bit mask to optionally invert PDM clock */ uint8_t pdm_clk_pol; - /* Bit mask to optionally invert mic data */ + /** Bit mask to optionally invert mic data */ uint8_t pdm_data_pol; - /* Collection of clock skew values for each PDM port */ + /** Collection of clock skew values for each PDM port */ uint32_t pdm_clk_skew; + /** + * @} + */ }; /** * Configuration of the PCM streams to be output by the PDM hardware + * + * @note if either \ref pcm_rate or \ref pcm_width is set to 0 for a stream, + * the stream would be disabled */ struct pcm_stream_cfg { - /* - * if either rate or width is set to 0 for a stream, - * the stream would be disabled - */ - - /* PCM sample rate of stream */ + /** PCM sample rate of stream */ uint32_t pcm_rate; - /* PCM sample width of stream */ + /** PCM sample width of stream */ uint8_t pcm_width; - /* PCM sample block size per transfer */ + /** PCM sample block size per transfer */ uint16_t block_size; - /* SLAB for DMIC driver to allocate buffers for stream */ + /** SLAB for DMIC driver to allocate buffers for stream */ struct k_mem_slab *mem_slab; }; /** * Mapping/ordering of the PDM channels to logical PCM output channel + * + * Since each controller can have 2 audio channels (stereo), + * there can be a total of 8x2=16 channels. The actual number of channels + * shall be described in \ref act_num_chan. + * + * If 2 streams are enabled, the channel order will be the same for + * both streams. + * + * Each channel is described as a 4-bit number, the least significant + * bit indicates LEFT/RIGHT selection of the PDM controller. + * + * The most significant 3 bits indicate the PDM controller number: + * - bits 0-3 are for channel 0, bit 0 indicates LEFT or RIGHT + * - bits 4-7 are for channel 1, bit 4 indicates LEFT or RIGHT + * and so on. + * + * CONSTRAINT: The LEFT and RIGHT channels of EACH PDM controller needs + * to be adjacent to each other. */ struct pdm_chan_cfg { - /* - * mapping of PDM controller and mic channel to logical channel - * since each controller can have 2 audio channels (stereo), - * there can be total of 8x2=16 channels. - * The actual number of channels shall be described in - * pcm_stream_cfg.num_chan. - * if 2 streams are enabled, the channel order will be the same for - * both streams - * Each channel is described as a 4 bit number, the least significant - * bit indicates LEFT/RIGHT selection of the PDM controller. - * The most significant 3 bits indicate the PDM controller number. - * bits 0-3 are for channel 0, bit 0 indicates LEFT or RIGHT - * bits 4-7 are for channel 1, bit 4 indicates LEFT or RIGHT - * and so on. - * CONSTRAINT: The LEFT and RIGHT channels of EACH PDM controller needs - * to be adjacent to each other. + /** + * @name Requested channel map + * @{ + */ + uint32_t req_chan_map_lo; /**< Channels 0 to 7 */ + uint32_t req_chan_map_hi; /**< Channels 8 to 15 */ + /** @} */ + + /** + * @name Actual channel map that the driver could configure + * @{ */ - /* Requested channel map */ - uint32_t req_chan_map_lo; /* Channels 0 to 7 */ - uint32_t req_chan_map_hi; /* Channels 8 to 15 */ - /* Actual channel map that the driver could configure */ - uint32_t act_chan_map_lo; /* Channels 0 to 7 */ - uint32_t act_chan_map_hi; /* Channels 8 to 15 */ - /* requested number of channels */ + uint32_t act_chan_map_lo; /**< Channels 0 to 7 */ + uint32_t act_chan_map_hi; /**< Channels 8 to 15 */ + /** @} */ + + /** Requested number of channels */ uint8_t req_num_chan; - /* Actual number of channels that the driver could configure */ + /** Actual number of channels that the driver could configure */ uint8_t act_num_chan; - /* requested number of streams for each channel */ + /** Requested number of streams for each channel */ uint8_t req_num_streams; - /* Actual number of streams that the driver could configure */ + /** Actual number of streams that the driver could configure */ uint8_t act_num_streams; }; @@ -155,7 +174,7 @@ struct pdm_chan_cfg { */ struct dmic_cfg { struct pdm_io_cfg io; - /* + /** * Array of pcm_stream_cfg for application to provide * configuration for each stream */ From abf26affe0241142d4264b9e054802f2aa7600e6 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 14 Jul 2023 15:15:21 -0600 Subject: [PATCH 0045/4498] doc: Add instructions for installing Python dependencies The Python dependencies specific to building the documentation were recently removed from the common requirements. Point users to the documentation generation instructions and provide details on installing the doc specific dependencies. Signed-off-by: Keith Short --- doc/contribute/documentation/generation.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index 3701e860138..7e985dbda65 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -93,6 +93,13 @@ as described below: .. group-tab:: Linux + Common to all Linux installations, install the Python dependencies + required to build the documentation: + + .. code-block:: console + + pip install -r ~/zephyrproject/zephyr/doc/requirements.txt + On Ubuntu Linux: .. code-block:: console @@ -122,6 +129,12 @@ as described below: .. group-tab:: macOS + Install the Python dependencies required to build the documentation: + + .. code-block:: console + + pip install -r ~/zephyrproject/zephyr/doc/requirements.txt + Use ``brew`` and ``tlmgr`` to install the tools: .. code-block:: console @@ -132,6 +145,12 @@ as described below: .. group-tab:: Windows + Install the Python dependencies required to build the documentation: + + .. code-block:: console + + pip install -r %HOMEPATH$\zephyrproject\zephyr\doc\requirements.txt + Open a ``cmd.exe`` window as **Administrator** and run the following command: .. code-block:: console From 868450ce53e5685efc3d9c59050042d1aeaa0d61 Mon Sep 17 00:00:00 2001 From: Andrei Hutanu Date: Wed, 19 Jul 2023 17:30:09 +0200 Subject: [PATCH 0046/4498] docs: develop: ztest: fix for ztest example build the Test Framework example present in documentation does not work out of the box and has to be slightly modified. This is an attempt to fix the example so it would just work directly from documentation. Signed-off-by: Andrei Hutanu --- doc/develop/test/ztest.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/develop/test/ztest.rst b/doc/develop/test/ztest.rst index 535bab232d0..1eff49906bf 100644 --- a/doc/develop/test/ztest.rst +++ b/doc/develop/test/ztest.rst @@ -83,7 +83,7 @@ This is achieved via fixtures in the following way: static void *my_suite_setup(void) { /* Allocate the fixture with 256 byte buffer */ - struct my_suite_fixture *fixture = k_malloc(sizeof(struct my_suite_fixture) + 255); + struct my_suite_fixture *fixture = malloc(sizeof(struct my_suite_fixture) + 255); zassume_not_null(fixture, NULL); fixture->max_size = 256; @@ -100,7 +100,7 @@ This is achieved via fixtures in the following way: static void my_suite_teardown(void *f) { - k_free(f); + free(f); } ZTEST_SUITE(my_suite, NULL, my_suite_setup, my_suite_before, NULL, my_suite_teardown); @@ -132,14 +132,14 @@ nature of the code, it's possible to annotate the test as such. For example: ZTEST_SUITE(my_suite, NULL, NULL, NULL, NULL, NULL); - ZTEST_EXPECT_FAIL(my_suite, test_fail) + ZTEST_EXPECT_FAIL(my_suite, test_fail); ZTEST(my_suite, test_fail) { /** This will fail the test */ zassert_true(false, NULL); } - ZTEST_EXPECT_SKIP(my_suite, test_skip) + ZTEST_EXPECT_SKIP(my_suite, test_skip); ZTEST(my_suite, test_skip) { /** This will skip the test */ From b01739da6f9da40631ca317760d94b0224eb2404 Mon Sep 17 00:00:00 2001 From: Nicolas VINCENT Date: Tue, 18 Jul 2023 16:45:15 +0200 Subject: [PATCH 0047/4498] doc: shell: Update docstring regarding dictionnary The dictionary is a triplet, update generated documentation accordingly. Signed-off-by: Nicolas VINCENT --- include/zephyr/shell/shell.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 437169fd281..d75814e08b9 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -530,7 +530,7 @@ static int UTIL_CAT(UTIL_CAT(cmd_dict_, UTIL_CAT(_handler, _)), \ * @param[in] _name Name of the dictionary subcommand set * @param[in] _handler Command handler common for all dictionary commands. * @see shell_dict_cmd_handler - * @param[in] ... Dictionary pairs: (command_syntax, value). Value will be + * @param[in] ... Dictionary triplets: (command_syntax, value, helper). Value will be * passed to the _handler as user data. * * Example usage: From d7846de5482f21d042b77f04c8d051259da1b4f5 Mon Sep 17 00:00:00 2001 From: Armin Brauns Date: Wed, 19 Jul 2023 08:15:04 +0000 Subject: [PATCH 0048/4498] assert: check format arguments for correctness This instructs the compiler to check that arguments to __ASSERT/__ASSERT_NO_MSG are valid for printf. Signed-off-by: Armin Brauns --- include/zephyr/sys/__assert.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sys/__assert.h b/include/zephyr/sys/__assert.h index 1fa0b86daa8..fc0b9476ea6 100644 --- a/include/zephyr/sys/__assert.h +++ b/include/zephyr/sys/__assert.h @@ -26,7 +26,7 @@ extern "C" { #endif /* Wrapper around printk to avoid including printk.h in assert.h */ -void assert_print(const char *fmt, ...); +void __printf_like(1, 2) assert_print(const char *fmt, ...); #ifdef __cplusplus } From 990b421b094fde194b92afc6694db2b0113ccf16 Mon Sep 17 00:00:00 2001 From: Andrew McLachlan Date: Wed, 6 Sep 2023 09:28:38 +0100 Subject: [PATCH 0049/4498] ci: Run greeting workflow on zephyrproject-rtos/zephyr. Only run first time contributor check on zephyrproject-rtos/zephyr. Signed-off-by: Andrew McLachlan --- .github/workflows/greet_first_time_contributor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/greet_first_time_contributor.yml b/.github/workflows/greet_first_time_contributor.yml index 0c078026692..8ed7157975a 100644 --- a/.github/workflows/greet_first_time_contributor.yml +++ b/.github/workflows/greet_first_time_contributor.yml @@ -9,6 +9,8 @@ on: jobs: check_for_first_interaction: runs-on: ubuntu-22.04 + if: github.repository == 'zephyrproject-rtos/zephyr' + steps: - uses: actions/checkout@v3 - uses: zephyrproject-rtos/action-first-interaction@v1.1.1-zephyr-3 From 0af777013283a9de760ac638d237dcbcf16c2bb3 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Tue, 5 Sep 2023 13:28:51 +0200 Subject: [PATCH 0050/4498] scripts: tests: twister: Mixin test Simple test checking whether our method for skipping unwanted test classes works. Signed-off-by: Lukasz Mrugala --- .../twister/test_data/mixins/test_to_ignore.py | 5 +++++ scripts/tests/twister/test_mixins.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 scripts/tests/twister/test_data/mixins/test_to_ignore.py create mode 100644 scripts/tests/twister/test_mixins.py diff --git a/scripts/tests/twister/test_data/mixins/test_to_ignore.py b/scripts/tests/twister/test_data/mixins/test_to_ignore.py new file mode 100644 index 00000000000..49381293a8b --- /dev/null +++ b/scripts/tests/twister/test_data/mixins/test_to_ignore.py @@ -0,0 +1,5 @@ +from twisterlib.mixins import DisablePyTestCollectionMixin + +class TestClassToIgnore(DisablePyTestCollectionMixin): + def test_to_ignore(self): + assert False diff --git a/scripts/tests/twister/test_mixins.py b/scripts/tests/twister/test_mixins.py new file mode 100644 index 00000000000..94e91dcd4ec --- /dev/null +++ b/scripts/tests/twister/test_mixins.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for the mixins class +""" + +import os +import pytest + + +def test_disable_pytest_test_collection(test_data): + test_path = os.path.join(test_data, 'mixins') + + return_code = pytest.main([test_path]) + + assert return_code == 5 From bc97d8fb1e40328ab32da108508e83e9d8792bf0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 3 Aug 2023 10:56:41 +0100 Subject: [PATCH 0051/4498] twister: Add support for required snippets Adds support for twister to require using snippets on tests Signed-off-by: Jamie McCrae --- .../pylib/twister/twisterlib/config_parser.py | 1 + scripts/pylib/twister/twisterlib/runner.py | 4 ++ scripts/pylib/twister/twisterlib/testplan.py | 42 +++++++++++++++++++ scripts/schemas/twister/testsuite-schema.yaml | 10 +++++ scripts/snippets.py | 16 +++++++ scripts/twister | 3 ++ scripts/west_commands/build.py | 11 ++++- 7 files changed, 86 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index c822e9dfc77..f431e2d57c2 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -48,6 +48,7 @@ class TwisterConfigParser: "extra_conf_files": {"type": "list", "default": []}, "extra_overlay_confs" : {"type": "list", "default": []}, "extra_dtc_overlay_files": {"type": "list", "default": []}, + "required_snippets": {"type": "list"}, "build_only": {"type": "bool", "default": False}, "build_on_all": {"type": "bool", "default": False}, "skip": {"type": "bool", "default": False}, diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index ad93145db38..bbbdb18d05a 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -359,6 +359,10 @@ def run_cmake(self, args="", filter_stages=[]): cmake_opts = ['-DBOARD={}'.format(self.platform.name)] cmake_args.extend(cmake_opts) + if self.instance.testsuite.required_snippets: + cmake_opts = ['-DSNIPPET={}'.format(';'.join(self.instance.testsuite.required_snippets))] + cmake_args.extend(cmake_opts) + cmake = shutil.which('cmake') cmd = [cmake] + cmake_args diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 85340885dbb..1d9c625b28a 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -16,6 +16,8 @@ import copy import shutil import random +import snippets +from pathlib import Path logger = logging.getLogger('twister') logger.setLevel(logging.DEBUG) @@ -819,6 +821,46 @@ def apply_filters(self, **kwargs): if plat.only_tags and not set(plat.only_tags) & ts.tags: instance.add_filter("Excluded tags per platform (only_tags)", Filters.PLATFORM) + if ts.required_snippets: + missing_snippet = False + snippet_args = {"snippets": ts.required_snippets} + found_snippets = snippets.find_snippets_in_roots(snippet_args, [Path(ZEPHYR_BASE), Path(ts.source_dir)]) + + # Search and check that all required snippet files are found + for this_snippet in snippet_args['snippets']: + if this_snippet not in found_snippets: + logger.error(f"Can't find snippet '%s' for test '%s'", this_snippet, ts.name) + instance.status = "error" + instance.reason = f"Snippet {this_snippet} not found" + missing_snippet = True + break + + if not missing_snippet: + # Look for required snippets and check that they are applicable for these + # platforms/boards + for this_snippet in found_snippets: + matched_snippet_board = False + + # If the "appends" key is present with at least one entry then this + # snippet applies to all boards and further platform-specific checks + # are not required + if found_snippets[this_snippet].appends: + continue + + for this_board in found_snippets[this_snippet].board2appends: + if this_board.startswith('/'): + match = re.search(this_board[1:-1], plat.name) + if match is not None: + matched_snippet_board = True + break + elif this_board == plat.name: + matched_snippet_board = True + break + + if matched_snippet_board is False: + instance.add_filter("Snippet not supported", Filters.PLATFORM) + break + # platform_key is a list of unique platform attributes that form a unique key a test # will match against to determine if it should be scheduled to run. A key containing a # field name that the platform does not have will filter the platform. diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 4d67fe71706..116c1a43379 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -145,6 +145,11 @@ mapping: matching: "all" sequence: - type: str + "required_snippets": + type: seq + required: false + sequence: + - type: str "tags": type: any required: false @@ -243,6 +248,11 @@ mapping: "extra_sections": type: any required: false + "required_snippets": + type: seq + required: false + sequence: + - type: str "filter": type: str required: false diff --git a/scripts/snippets.py b/scripts/snippets.py index 9662f3edcec..78ab896e85b 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -238,6 +238,22 @@ def process_snippets(args: argparse.Namespace) -> Snippets: return snippets +def find_snippets_in_roots(requested_snippets, snippet_roots) -> Snippets: + '''Process snippet.yml files under each *snippet_root* + by recursive search. Return a Snippets object describing + the results of the search. + ''' + # This will contain information about all the snippets + # we discover in each snippet_root element. + snippets = Snippets(requested=requested_snippets) + + # Process each path in snippet_root in order, adjusting + # snippets as needed for each one. + for root in snippet_roots: + process_snippets_in(root, snippets) + + return snippets + def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: '''Process snippet.yml files in *root_dir*, updating *snippets* as needed.''' diff --git a/scripts/twister b/scripts/twister index 0f5e622011f..f41349871ed 100755 --- a/scripts/twister +++ b/scripts/twister @@ -44,6 +44,9 @@ pairs: Extra configuration options to be merged with a master prj.conf when building or running the test case. + required_snippets: + Snippets that must be applied for the test case to run. + sysbuild: (default False) If true, build the sample using the sysbuild infrastructure. Filtering will only be enabled for the main project, and is not supported for diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 65dbe963cd4..bcc5106f8ca 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -293,6 +293,7 @@ def _parse_test_item(self, test_item): extra_dtc_overlay_files = [] extra_overlay_confs = [] extra_conf_files = [] + required_snippets = [] for section in [common, item]: if not section: continue @@ -302,7 +303,8 @@ def _parse_test_item(self, test_item): 'extra_configs', 'extra_conf_files', 'extra_overlay_confs', - 'extra_dtc_overlay_files' + 'extra_dtc_overlay_files', + 'required_snippets' ]: extra = section.get(data) if not extra: @@ -325,6 +327,9 @@ def _parse_test_item(self, test_item): elif data == 'extra_dtc_overlay_files': extra_dtc_overlay_files.extend(arg_list) continue + elif data == 'required_snippets': + required_snippets.extend(arg_list) + continue if self.args.cmake_opts: self.args.cmake_opts.extend(args) @@ -343,6 +348,10 @@ def _parse_test_item(self, test_item): if extra_overlay_confs: args.append(f"OVERLAY_CONFIG=\"{';'.join(extra_overlay_confs)}\"") + + if required_snippets: + args.append(f"SNIPPET=\"{';'.join(required_snippets)}\"") + # Build the final argument list args_expanded = ["-D{}".format(a.replace('"', '')) for a in args] From 1b2abf3c83a68ac5f62383aac187ef97f29bccaf Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 16 Aug 2023 10:11:14 +0100 Subject: [PATCH 0052/4498] tests: twister: Add tests for required_snippets functionality Adds 2 tests which check required_snippet functionality works. Signed-off-by: Jamie McCrae --- .../tests/test_d/snippets/dummy/dummy.conf | 1 + .../tests/test_d/snippets/dummy/snippet.yml | 5 ++ scripts/tests/twister/test_testplan_class.py | 63 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/dummy.conf create mode 100644 scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/snippet.yml diff --git a/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/dummy.conf b/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/dummy.conf new file mode 100644 index 00000000000..72b91bc12be --- /dev/null +++ b/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/dummy.conf @@ -0,0 +1 @@ +CONFIG_BOOT_BANNER=n diff --git a/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/snippet.yml b/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/snippet.yml new file mode 100644 index 00000000000..05c65f733fd --- /dev/null +++ b/scripts/tests/twister/test_data/testsuites/tests/test_d/snippets/dummy/snippet.yml @@ -0,0 +1,5 @@ +name: dummy +boards: + demo_board_2: + append: + EXTRA_CONF_FILE: dummy.conf diff --git a/scripts/tests/twister/test_testplan_class.py b/scripts/tests/twister/test_testplan_class.py index 7fdd5f02b4d..f825bc82710 100644 --- a/scripts/tests/twister/test_testplan_class.py +++ b/scripts/tests/twister/test_testplan_class.py @@ -342,3 +342,66 @@ def test_quarantine(class_testplan, platforms_list, test_data, assert instance.reason == "Quarantine: " + expected_val[testname] else: assert not instance.status + +def test_required_snippets_app(class_testplan, all_testsuites_dict, platforms_list): + """ Testing required_snippets function of TestPlan class in Twister + Ensure that app snippets work and are only applied to boards that support the snippet + """ + plan = class_testplan + testsuite = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1') + plan.platforms = platforms_list + plan.platform_names = [p.name for p in platforms_list] + plan.testsuites = {'scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1': testsuite} + + for _, testcase in plan.testsuites.items(): + testcase.exclude_platform = [] + testcase.required_snippets = ['dummy'] + testcase.build_on_all = True + + plan.apply_filters() + + filtered_instances = list(filter(lambda item: item.status == "filtered", plan.instances.values())) + for d in filtered_instances: + assert d.reason == "Snippet not supported" + +def test_required_snippets_global(class_testplan, all_testsuites_dict, platforms_list): + """ Testing required_snippets function of TestPlan class in Twister + Ensure that global snippets work and application does not fail + """ + plan = class_testplan + testsuite = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_1') + plan.platforms = platforms_list + plan.platform_names = [p.name for p in platforms_list] + plan.testsuites = {'scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_1': testsuite} + + for _, testcase in plan.testsuites.items(): + testcase.exclude_platform = [] + testcase.required_snippets = ['cdc-acm-console'] + testcase.build_on_all = True + + plan.apply_filters() + + filtered_instances = list(filter(lambda item: item.status == "filtered", plan.instances.values())) + assert len(filtered_instances) == 0 + +def test_required_snippets_multiple(class_testplan, all_testsuites_dict, platforms_list): + """ Testing required_snippets function of TestPlan class in Twister + Ensure that multiple snippets can be used and are applied + """ + plan = class_testplan + testsuite = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1') + plan.platforms = platforms_list + plan.platform_names = [p.name for p in platforms_list] + plan.testsuites = {'scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1': testsuite} + + for _, testcase in plan.testsuites.items(): + testcase.exclude_platform = [] + testcase.required_snippets = ['dummy', 'cdc-acm-console'] + testcase.build_on_all = True + + plan.apply_filters() + + filtered_instances = list(filter(lambda item: item.status == "filtered", plan.instances.values())) + assert len(filtered_instances) == 2 + for d in filtered_instances: + assert d.reason == "Snippet not supported" From 9509831e1d3150bbd665702d41ae58246ea9aa73 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 18 Aug 2023 12:34:08 +0100 Subject: [PATCH 0053/4498] doc: release: 3.5: Add note on required_snippets twister addition Adds a note that twister now supports applying snippets Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 53d4d2d9172..3612c6d8ae5 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -111,6 +111,10 @@ Build system and infrastructure * Added support for CodeChecker +* Twister now supports ``required_snippets`` in testsuite .yml files, this can + be used to include a snippet when a test is ran (and exclude any boards from + running that the snippet cannot be applied to). + Drivers and Sensors ******************* From e6d5b3f9a6decceae6f7d4a23e71c6726d130cc4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 21 Aug 2023 08:23:55 +0100 Subject: [PATCH 0054/4498] doc: twister: Add details on required_snippets Adds information on the new required_snippets feature Signed-off-by: Jamie McCrae --- doc/develop/test/twister.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index a29890c7899..48c86ca899d 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -616,6 +616,24 @@ filter: Would match it. +required_snippets: + :ref:`Snippets ` are supported in twister for test cases that + require them. As with normal applications, twister supports using the base + zephyr snippet directory and test application directory for finding + snippets. Listed snippets will filter supported tests for boards (snippets + must be compatible with a board for the test to run on them, they are not + optional). + + The following is an example yaml file with 2 required snippets. + + :: + + tests: + snippet.example: + required_snippets: + - cdc-acm-console + - user-snippet-example + The set of test cases that actually run depends on directives in the testcase filed and options passed in on the command line. If there is any confusion, running with -v or examining the discard report From 7188f925f9aa85c4aaeab45fe9f0e91694881e8d Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Fri, 7 Jul 2023 22:56:09 -0400 Subject: [PATCH 0055/4498] logging: fix timestamp scaling with 64-bit timestamp In default_get_timestamp(), sys_clock_tick_get() is returned when CONFIG_LOG_TIMESTAMP_64BIT=y. The timestamp frequency should reflect this. Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com> --- subsys/logging/log_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index 8e7f739d0c4..8322732d434 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -237,8 +237,9 @@ void log_core_init(void) if (sys_clock_hw_cycles_per_sec() > 1000000) { log_set_timestamp_func(default_lf_get_timestamp, 1000U); } else { - log_set_timestamp_func(default_get_timestamp, - sys_clock_hw_cycles_per_sec()); + uint32_t freq = IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ? + CONFIG_SYS_CLOCK_TICKS_PER_SEC : sys_clock_hw_cycles_per_sec(); + log_set_timestamp_func(default_get_timestamp, freq); } if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) { From 4aac1756a956a4e9048987096547d2b2adabcb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Fri, 31 Mar 2023 18:41:54 +0200 Subject: [PATCH 0056/4498] i2c: use device instead of name for i2c dump messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit changes the parameter of i2c_dump_msgs function from string name to pointer to the device structure. It allows for comparison of device pointers and allow to use the printed device name in i2c shell commands. Signed-off-by: Michał Barnaś --- drivers/eeprom/eeprom_at2x_emul.c | 2 +- drivers/fuel_gauge/max17048/emul_max17048.c | 2 +- drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c | 2 +- drivers/i2c/Kconfig | 1 + drivers/i2c/i2c_common.c | 6 +++--- drivers/sensor/akm09918c/akm09918c_emul.c | 2 +- drivers/sensor/bmi160/emul_bmi160.c | 2 +- drivers/usb/bc12/emul_bc12_pi3usb9201.c | 2 +- include/zephyr/drivers/i2c.h | 16 ++++++++-------- 9 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/eeprom/eeprom_at2x_emul.c b/drivers/eeprom/eeprom_at2x_emul.c index 25d079dfa6d..91033c02b4a 100644 --- a/drivers/eeprom/eeprom_at2x_emul.c +++ b/drivers/eeprom/eeprom_at2x_emul.c @@ -81,7 +81,7 @@ static int at24_emul_transfer(const struct emul *target, struct i2c_msg *msgs, return -EIO; } - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 1: if (msgs->flags & I2C_MSG_READ) { diff --git a/drivers/fuel_gauge/max17048/emul_max17048.c b/drivers/fuel_gauge/max17048/emul_max17048.c index 3ae1565cb47..a3a09f4c03e 100644 --- a/drivers/fuel_gauge/max17048/emul_max17048.c +++ b/drivers/fuel_gauge/max17048/emul_max17048.c @@ -75,7 +75,7 @@ static int max17048_emul_transfer_i2c(const struct emul *target, struct i2c_msg __ASSERT_NO_MSG(msgs && num_msgs); - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 2: if (msgs->flags & I2C_MSG_READ) { diff --git a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c index c84a73e75ff..64668d54307 100644 --- a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c @@ -233,7 +233,7 @@ static int sbs_gauge_emul_transfer_i2c(const struct emul *target, struct i2c_msg __ASSERT_NO_MSG(msgs && num_msgs); - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 2: if (msgs->flags & I2C_MSG_READ) { diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 655d7f6e0bc..8ae217f82bf 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -32,6 +32,7 @@ config I2C_STATS config I2C_DUMP_MESSAGES bool "Log all I2C transactions" depends on LOG + depends on I2C_LOG_LEVEL_DBG help Dump every I2C transaction to the system log as debug level log messages. diff --git a/drivers/i2c/i2c_common.c b/drivers/i2c/i2c_common.c index aaae974add8..6094ed12c77 100644 --- a/drivers/i2c/i2c_common.c +++ b/drivers/i2c/i2c_common.c @@ -25,10 +25,10 @@ void z_i2c_transfer_signal_cb(const struct device *dev, } #endif -void i2c_dump_msgs_rw(const char *name, const struct i2c_msg *msgs, - uint8_t num_msgs, uint16_t addr, bool dump_read) +void i2c_dump_msgs_rw(const struct device *dev, const struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr, bool dump_read) { - LOG_DBG("I2C msg: %s, addr=%x", name, addr); + LOG_DBG("I2C msg: %s, addr=%x", dev->name, addr); for (unsigned int i = 0; i < num_msgs; i++) { const struct i2c_msg *msg = &msgs[i]; const bool is_read = msg->flags & I2C_MSG_READ; diff --git a/drivers/sensor/akm09918c/akm09918c_emul.c b/drivers/sensor/akm09918c/akm09918c_emul.c index 2112acc8c00..a8ce27fd3d3 100644 --- a/drivers/sensor/akm09918c/akm09918c_emul.c +++ b/drivers/sensor/akm09918c/akm09918c_emul.c @@ -76,7 +76,7 @@ static int akm09918c_emul_transfer_i2c(const struct emul *target, struct i2c_msg { struct akm09918c_emul_data *data = target->data; - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); if (num_msgs < 1) { LOG_ERR("Invalid number of messages: %d", num_msgs); diff --git a/drivers/sensor/bmi160/emul_bmi160.c b/drivers/sensor/bmi160/emul_bmi160.c index 78fe6d3ef88..3870346cd30 100644 --- a/drivers/sensor/bmi160/emul_bmi160.c +++ b/drivers/sensor/bmi160/emul_bmi160.c @@ -241,7 +241,7 @@ static int bmi160_emul_transfer_i2c(const struct emul *target, struct i2c_msg *m __ASSERT_NO_MSG(msgs && num_msgs); - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 2: if (msgs->flags & I2C_MSG_READ) { diff --git a/drivers/usb/bc12/emul_bc12_pi3usb9201.c b/drivers/usb/bc12/emul_bc12_pi3usb9201.c index 6d6842939cd..f798d4d9ac0 100644 --- a/drivers/usb/bc12/emul_bc12_pi3usb9201.c +++ b/drivers/usb/bc12/emul_bc12_pi3usb9201.c @@ -192,7 +192,7 @@ static int pi3usb9201_emul_transfer(const struct emul *target, struct i2c_msg *m return -EIO; } - i2c_dump_msgs("emul", msgs, num_msgs, addr); + i2c_dump_msgs(target->dev, msgs, num_msgs, addr); /* Only single byte register access permitted. Write operations must * consist of 2 write bytes: register offset, register data. Read diff --git a/include/zephyr/drivers/i2c.h b/include/zephyr/drivers/i2c.h index 95d0cf1e9c1..c3ea9bb43eb 100644 --- a/include/zephyr/drivers/i2c.h +++ b/include/zephyr/drivers/i2c.h @@ -488,33 +488,33 @@ static inline bool i2c_is_ready_dt(const struct i2c_dt_spec *spec) * D: R len=01: 6c * @endcode * - * @param name Name of this dump, displayed at the top. + * @param dev Target for the messages being sent. Its name will be printed in the log. * @param msgs Array of messages to dump. * @param num_msgs Number of messages to dump. * @param addr Address of the I2C target device. * @param dump_read Dump data from I2C reads, otherwise only writes have data dumped. */ -void i2c_dump_msgs_rw(const char *name, const struct i2c_msg *msgs, - uint8_t num_msgs, uint16_t addr, bool dump_read); +void i2c_dump_msgs_rw(const struct device *dev, const struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr, bool dump_read); /** * @brief Dump out an I2C message, before it is executed. * * This is equivalent to: * - * i2c_dump_msgs_rw(name, msgs, num_msgs, addr, false); + * i2c_dump_msgs_rw(dev, msgs, num_msgs, addr, false); * * The read messages' data isn't dumped. * - * @param name Name of this dump, displayed at the top. + * @param dev Target for the messages being sent. Its name will be printed in the log. * @param msgs Array of messages to dump. * @param num_msgs Number of messages to dump. * @param addr Address of the I2C target device. */ -static inline void i2c_dump_msgs(const char *name, const struct i2c_msg *msgs, +static inline void i2c_dump_msgs(const struct device *dev, const struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr) { - i2c_dump_msgs_rw(name, msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(dev, msgs, num_msgs, addr, false); } #if defined(CONFIG_I2C_STATS) || defined(__DOXYGEN__) @@ -772,7 +772,7 @@ static inline int z_impl_i2c_transfer(const struct device *dev, i2c_xfer_stats(dev, msgs, num_msgs); if (IS_ENABLED(CONFIG_I2C_DUMP_MESSAGES)) { - i2c_dump_msgs_rw(dev->name, msgs, num_msgs, addr, true); + i2c_dump_msgs_rw(dev, msgs, num_msgs, addr, true); } return res; From 4c49d095fcff2087db32a6477398e946104af47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Fri, 31 Mar 2023 18:44:40 +0200 Subject: [PATCH 0057/4498] i2c: improve the message dumps messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit changes the format of printed messages to align the following strings and make it more readable. Signed-off-by: Michał Barnaś --- drivers/i2c/i2c_common.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/i2c_common.c b/drivers/i2c/i2c_common.c index 6094ed12c77..616e15a2d03 100644 --- a/drivers/i2c/i2c_common.c +++ b/drivers/i2c/i2c_common.c @@ -35,15 +35,13 @@ void i2c_dump_msgs_rw(const struct device *dev, const struct i2c_msg *msgs, uint const bool dump_data = dump_read || !is_read; if (msg->len == 1 && dump_data) { - LOG_DBG(" %c %s%s len=01: %02x", is_read ? 'R' : 'W', - msg->flags & I2C_MSG_RESTART ? "Sr " : "", - msg->flags & I2C_MSG_STOP ? "P" : "", - msg->buf[0]); + LOG_DBG(" %c %2s %1s len=01: %02x", is_read ? 'R' : 'W', + msg->flags & I2C_MSG_RESTART ? "Sr" : "", + msg->flags & I2C_MSG_STOP ? "P" : "", msg->buf[0]); } else { - LOG_DBG(" %c %s%s len=%02x: ", is_read ? 'R' : 'W', - msg->flags & I2C_MSG_RESTART ? "Sr " : "", - msg->flags & I2C_MSG_STOP ? "P" : "", - msg->len); + LOG_DBG(" %c %2s %1s len=%02x: ", is_read ? 'R' : 'W', + msg->flags & I2C_MSG_RESTART ? "Sr" : "", + msg->flags & I2C_MSG_STOP ? "P" : "", msg->len); if (dump_data) { LOG_HEXDUMP_DBG(msg->buf, msg->len, "contents:"); } From 2bc7dcdc2e2aef411dacef40e558ccaa32546fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Fri, 31 Mar 2023 18:57:46 +0200 Subject: [PATCH 0058/4498] i2c: add filtering of i2c dumped messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds option to dump i2c messages of only specified devices. It makes it easier to debug communication of specific i2c device instead of logging all i2c communication. The filter of devices is specifiec in device-tree using the node with "zephyr,i2c-dump-filter" compatible string. Example of device-tree node: i2c-dump-filter { compatible = "zephyr,i2c-dump-filter"; devices = < &display0 >, < &sensor3 >; }; Signed-off-by: Michał Barnaś --- drivers/i2c/Kconfig | 16 +++++++++- drivers/i2c/i2c_common.c | 30 +++++++++++++++++++ .../i2c/zephyr,i2c-dump-allowlist.yaml | 16 ++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/i2c/zephyr,i2c-dump-allowlist.yaml diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 8ae217f82bf..5f62fbb4eb1 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -30,12 +30,26 @@ config I2C_STATS Enable I2C Stats. config I2C_DUMP_MESSAGES - bool "Log all I2C transactions" + bool "Log I2C transactions" depends on LOG depends on I2C_LOG_LEVEL_DBG help Dump every I2C transaction to the system log as debug level log messages. +config I2C_DUMP_MESSAGES_ALLOWLIST + bool "Use allowlist for logging of I2C transactions" + depends on I2C_DUMP_MESSAGES + depends on DT_HAS_ZEPHYR_I2C_DUMP_ALLOWLIST_ENABLED + help + Use allowlist to specify which devices transactions should be logged. + The allowlist is defined in the devicetree using the compatible string of + "zephyr,i2c-dump-allowlist" and phandles to the devices that need to be traced. + Example of devicetree node: + i2c-dump-allowlist { + compatible = "zephyr,i2c-dump-allowlist"; + devices = < &display0 >, < &sensor3 >; + }; + config I2C_CALLBACK bool "I2C asynchronous callback API" help diff --git a/drivers/i2c/i2c_common.c b/drivers/i2c/i2c_common.c index 616e15a2d03..93986d6f58d 100644 --- a/drivers/i2c/i2c_common.c +++ b/drivers/i2c/i2c_common.c @@ -25,9 +25,39 @@ void z_i2c_transfer_signal_cb(const struct device *dev, } #endif +#ifdef CONFIG_I2C_DUMP_MESSAGES_ALLOWLIST +#define DEF_BUS_WITH_ADDR(node, prop, idx) I2C_DT_SPEC_GET(DT_PHANDLE_BY_IDX(node, prop, idx)), +#define DEF_ALLOWLIST_DEV(node) DT_FOREACH_PROP_ELEM(node, devices, DEF_BUS_WITH_ADDR) + +struct i2c_dt_spec messages_allowlist[] = { + DT_FOREACH_STATUS_OKAY(zephyr_i2c_dump_allowlist, DEF_ALLOWLIST_DEV)}; + +#undef DEF_ALLOWLIST_DEV +#undef DEF_BUS_WITH_ADDR +#endif + void i2c_dump_msgs_rw(const struct device *dev, const struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr, bool dump_read) { +#ifdef CONFIG_I2C_DUMP_MESSAGES_ALLOWLIST + bool found_dev = 0; + + for (int a = 0; a < ARRAY_SIZE(messages_allowlist); a++) { + struct i2c_dt_spec *allowed = &messages_allowlist[a]; + + if (dev != allowed->bus || addr != allowed->addr) { + continue; + } else { + found_dev = 1; + break; + } + } + + if (!found_dev) { + return; + } +#endif + LOG_DBG("I2C msg: %s, addr=%x", dev->name, addr); for (unsigned int i = 0; i < num_msgs; i++) { const struct i2c_msg *msg = &msgs[i]; diff --git a/dts/bindings/i2c/zephyr,i2c-dump-allowlist.yaml b/dts/bindings/i2c/zephyr,i2c-dump-allowlist.yaml new file mode 100644 index 00000000000..b1657aa7459 --- /dev/null +++ b/dts/bindings/i2c/zephyr,i2c-dump-allowlist.yaml @@ -0,0 +1,16 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: Devices allowlist for i2c messages dump + +compatible: "zephyr,i2c-dump-allowlist" + +include: base.yaml + +properties: + status: + const: "okay" + + devices: + required: true + type: phandles From 528a14329a8966e47a51610dd429a0e2481ca862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Thu, 3 Aug 2023 14:16:59 +0200 Subject: [PATCH 0059/4498] doc: fix missing and remove obsolete links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix text that should be linking to the URLs but was missing the link reference and remove the obsolete links. Signed-off-by: Michał Barnaś --- doc/develop/application/index.rst | 4 +--- doc/develop/modules.rst | 9 ++++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index 7307d6c572c..d37e4bc635c 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -431,7 +431,7 @@ should know about. * :makevar:`SHIELD`: see :ref:`shields` -* :makevar:`ZEPHYR_MODULES`: A CMake list containing absolute paths of +* :makevar:`ZEPHYR_MODULES`: A `CMake list`_ containing absolute paths of additional directories with source code, Kconfig, etc. that should be used in the application build. See :ref:`modules` for details. If you set this variable, it must be a complete list of all modules to use, as the build @@ -1579,6 +1579,4 @@ CONFIG_DEBUG_THREAD_INFO=y in your application. .. _GNU MCU Eclipse plug-ins: https://gnu-mcu-eclipse.github.io/plugins/install/ .. _pyOCD v0.11.0: https://github.com/mbedmicro/pyOCD/releases/tag/v0.11.0 .. _CMake list: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#lists -.. _add_subdirectory(): https://cmake.org/cmake/help/latest/command/add_subdirectory.html -.. _using Chocolatey: https://chocolatey.org/packages/RapidEE .. _example-application: https://github.com/zephyrproject-rtos/example-application diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index 5ee6648d329..45167585cd6 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -276,7 +276,7 @@ The merging of pull requests in the main branch of a module repository must be coupled with the corresponding manifest file update in the zephyr main tree. -**Issue Reporting:** GitHub issues are intentionally disabled in module +**Issue Reporting:** `GitHub issues`_ are intentionally disabled in module repositories, in favor of a centralized policy for issue reporting. Tickets concerning, for example, bugs or enhancements in modules shall be opened in the main @@ -625,7 +625,7 @@ variables. For example: include(${ZEPHYR_CURRENT_MODULE_DIR}/cmake/code.cmake) -It is possible to append values to a Zephyr CMake list variable from the module's first +It is possible to append values to a Zephyr `CMake list`_ variable from the module's first CMakeLists.txt file. To do so, append the value to the list and then set the list in the PARENT_SCOPE of the CMakeLists.txt file. For example, to append ``bar`` to the ``FOO_LIST`` variable in the @@ -671,7 +671,7 @@ example: include(${SYSBUILD_CURRENT_MODULE_DIR}/cmake/code.cmake) -It is possible to append values to a Zephyr CMake list variable from the +It is possible to append values to a Zephyr `CMake list`_ variable from the module's first CMakeLists.txt file. To do so, append the value to the list and then set the list in the PARENT_SCOPE of the CMakeLists.txt file. For example, to append ``bar`` to the @@ -794,7 +794,7 @@ Create a ``MODULE_EXT_ROOT`` with the following structure └── Kconfig and then build your application by specifying ``-DMODULE_EXT_ROOT`` parameter to -the CMake build system. The ``MODULE_EXT_ROOT`` accepts a CMake list of roots as +the CMake build system. The ``MODULE_EXT_ROOT`` accepts a `CMake list`_ of roots as argument. A Zephyr module can automatically be added to the ``MODULE_EXT_ROOT`` @@ -1151,5 +1151,4 @@ revision needs to be changed to the commit hash from the module repository. .. _CMake list: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#lists .. _add_subdirectory(): https://cmake.org/cmake/help/latest/command/add_subdirectory.html - .. _GitHub issues: https://github.com/zephyrproject-rtos/zephyr/issues From 8f01cb81471f90bd60e274455583df62aec139fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Thu, 3 Aug 2023 14:20:11 +0200 Subject: [PATCH 0060/4498] doc: extract the documentation about debugging to another file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the chapters about Application Debugging and Debugging using Eclipse to another file for easier search and to allow more debugging chapters to be inserted here. Signed-off-by: Michał Barnaś --- doc/develop/application/index.rst | 290 ----------------------------- doc/develop/debug/index.rst | 293 ++++++++++++++++++++++++++++++ doc/develop/index.rst | 1 + 3 files changed, 294 insertions(+), 290 deletions(-) create mode 100644 doc/develop/debug/index.rst diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index d37e4bc635c..0dae0d288e0 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -1054,169 +1054,6 @@ again. target name, for example ``west build -t run_qemu`` or ``ninja run_qemu`` for QEMU. -.. _application_debugging: - -Application Debugging -********************* - -This section is a quick hands-on reference to start debugging your -application with QEMU. Most content in this section is already covered in -`QEMU`_ and `GNU_Debugger`_ reference manuals. - -.. _QEMU: http://wiki.qemu.org/Main_Page - -.. _GNU_Debugger: http://www.gnu.org/software/gdb - -In this quick reference, you'll find shortcuts, specific environmental -variables, and parameters that can help you to quickly set up your debugging -environment. - -The simplest way to debug an application running in QEMU is using the GNU -Debugger and setting a local GDB server in your development system through QEMU. - -You will need an :abbr:`ELF (Executable and Linkable Format)` binary image for -debugging purposes. The build system generates the image in the build -directory. By default, the kernel binary name is :file:`zephyr.elf`. The name -can be changed using :kconfig:option:`CONFIG_KERNEL_BIN_NAME`. - -GDB server -========== - -We will use the standard 1234 TCP port to open a :abbr:`GDB (GNU Debugger)` -server instance. This port number can be changed for a port that best suits the -development environment. There are multiple ways to do this. Each way starts a -QEMU instance with the processor halted at startup and with a GDB server -instance listening for a connection. - -Running QEMU directly -~~~~~~~~~~~~~~~~~~~~~ - -You can run QEMU to listen for a "gdb connection" before it starts executing any -code to debug it. - -.. code-block:: bash - - qemu -s -S - -will setup Qemu to listen on port 1234 and wait for a GDB connection to it. - -The options used above have the following meaning: - -* ``-S`` Do not start CPU at startup; rather, you must type 'c' in the - monitor. -* ``-s`` Shorthand for :literal:`-gdb tcp::1234`: open a GDB server on - TCP port 1234. - - -Running QEMU via :command:`ninja` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Run the following inside the build directory of an application: - -.. code-block:: console - - ninja debugserver - -QEMU will write the console output to the path specified in -:makevar:`${QEMU_PIPE}` via CMake, typically :file:`qemu-fifo` within the build -directory. You may monitor this file during the run with :command:`tail -f -qemu-fifo`. - -Running QEMU via :command:`west` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Run the following from your project root: - -.. code-block:: console - - west build -t debugserver_qemu - -QEMU will write the console output to the terminal from which you invoked -:command:`west`. - -Configuring the :command:`gdbserver` listening device -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Kconfig option :kconfig:option:`CONFIG_QEMU_GDBSERVER_LISTEN_DEV` controls -the listening device, which can be a TCP port number or a path to a character -device. GDB releases 9.0 and newer also support Unix domain sockets. - -If the option is unset, then the QEMU invocation will lack a ``-s`` or a -``-gdb`` parameter. You can then use the :envvar:`QEMU_EXTRA_FLAGS` shell -environment variable to pass in your own listen device configuration. - -GDB client -========== - -Connect to the server by running :command:`gdb` and giving these commands: - -.. code-block:: bash - - $ path/to/gdb path/to/zephyr.elf - (gdb) target remote localhost:1234 - (gdb) dir ZEPHYR_BASE - -.. note:: - - Substitute the correct :ref:`ZEPHYR_BASE ` for your - system. - -You can use a local GDB configuration :file:`.gdbinit` to initialize your GDB -instance on every run. Your home directory is a typical location for -:file:`.gdbinit`, but you can configure GDB to load from other locations, -including the directory from which you invoked :command:`gdb`. This example -file performs the same configuration as above: - -.. code-block:: none - - target remote localhost:1234 - dir ZEPHYR_BASE - -Alternate interfaces -~~~~~~~~~~~~~~~~~~~~ - -GDB provides a curses-based interface that runs in the terminal. Pass the ``--tui`` -option when invoking :command:`gdb` or give the ``tui enable`` command within -:command:`gdb`. - -.. note:: - - The GDB version on your development system might not support the ``--tui`` - option. Please make sure you use the GDB binary from the SDK which - corresponds to the toolchain that has been used to build the binary. - -Finally, the command below connects to the GDB server using the :abbr:`DDD -(Data Display Debugger)`, a graphical frontend for GDB. The following command -loads the symbol table from the ELF binary file, in this instance, -:file:`zephyr.elf`. - -.. code-block:: bash - - ddd --gdb --debugger "gdb zephyr.elf" - -Both commands execute :command:`gdb`. The command name might -change depending on the toolchain you are using and your cross-development -tools. - -:command:`ddd` may not be installed in your -development system by default. Follow your system instructions to install -it. For example, use :command:`sudo apt-get install ddd` on an Ubuntu system. - -Debugging -========= - -As configured above, when you connect the GDB client, the application will be -stopped at system startup. You may set breakpoints, step through code, etc. as -when running the application directly within :command:`gdb`. - -.. note:: - - :command:`gdb` will not print the system console output as the application runs, - unlike when you run a native application in GDB directly. If you just - :command:`continue` after connecting the client, the application will run, - but nothing will appear to happen. Check the console output as described - above. - .. _custom_board_definition: Custom Board, Devicetree and SOC Definitions @@ -1449,134 +1286,7 @@ Cache variable: :goals: build :compact: - - -Debug with Eclipse -****************** - -Overview -======== - -CMake supports generating a project description file that can be imported into -the Eclipse Integrated Development Environment (IDE) and used for graphical -debugging. - -The `GNU MCU Eclipse plug-ins`_ provide a mechanism to debug ARM projects in -Eclipse with pyOCD, Segger J-Link, and OpenOCD debugging tools. - -The following tutorial demonstrates how to debug a Zephyr application in -Eclipse with pyOCD in Windows. It assumes you have already installed the GCC -ARM Embedded toolchain and pyOCD. - -Set Up the Eclipse Development Environment -========================================== - -#. Download and install `Eclipse IDE for C/C++ Developers`_. - -#. In Eclipse, install the GNU MCU Eclipse plug-ins by opening the menu - ``Window->Eclipse Marketplace...``, searching for ``GNU MCU Eclipse``, and - clicking ``Install`` on the matching result. - -#. Configure the path to the pyOCD GDB server by opening the menu - ``Window->Preferences``, navigating to ``MCU``, and setting the ``Global - pyOCD Path``. - -Generate and Import an Eclipse Project -====================================== - -#. Set up a GNU Arm Embedded toolchain as described in - :ref:`toolchain_gnuarmemb`. - -#. Navigate to a folder outside of the Zephyr tree to build your application. - - .. code-block:: console - - # On Windows - cd %userprofile% - - .. note:: - If the build directory is a subdirectory of the source directory, as is - usually done in Zephyr, CMake will warn: - - "The build directory is a subdirectory of the source directory. - - This is not supported well by Eclipse. It is strongly recommended to use - a build directory which is a sibling of the source directory." - -#. Configure your application with CMake and build it with ninja. Note the - different CMake generator specified by the ``-G"Eclipse CDT4 - Ninja"`` - argument. This will generate an Eclipse project description file, - :file:`.project`, in addition to the usual ninja build files. - - .. zephyr-app-commands:: - :tool: all - :app: %ZEPHYR_BASE%\samples\synchronization - :host-os: win - :board: frdm_k64f - :gen-args: -G"Eclipse CDT4 - Ninja" - :goals: build - :compact: - -#. In Eclipse, import your generated project by opening the menu - ``File->Import...`` and selecting the option ``Existing Projects into - Workspace``. Browse to your application build directory in the choice, - ``Select root directory:``. Check the box for your project in the list of - projects found and click the ``Finish`` button. - -Create a Debugger Configuration -=============================== - -#. Open the menu ``Run->Debug Configurations...``. - -#. Select ``GDB PyOCD Debugging``, click the ``New`` button, and configure the - following options: - - - In the Main tab: - - - Project: ``my_zephyr_app@build`` - - C/C++ Application: :file:`zephyr/zephyr.elf` - - - In the Debugger tab: - - - pyOCD Setup - - - Executable path: :file:`${pyocd_path}\\${pyocd_executable}` - - Uncheck "Allocate console for semihosting" - - - Board Setup - - - Bus speed: 8000000 Hz - - Uncheck "Enable semihosting" - - - GDB Client Setup - - - Executable path example (use your ``GNUARMEMB_TOOLCHAIN_PATH``): - :file:`C:\\gcc-arm-none-eabi-6_2017-q2-update\\bin\\arm-none-eabi-gdb.exe` - - - In the SVD Path tab: - - - File path: :file:`\\modules\\hal\\nxp\\mcux\\devices\\MK64F12\\MK64F12.xml` - - .. note:: - This is optional. It provides the SoC's memory-mapped register - addresses and bitfields to the debugger. - -#. Click the ``Debug`` button to start debugging. - -RTOS Awareness -============== - -Support for Zephyr RTOS awareness is implemented in `pyOCD v0.11.0`_ and later. -It is compatible with GDB PyOCD Debugging in Eclipse, but you must enable -CONFIG_DEBUG_THREAD_INFO=y in your application. - - - .. _CMake: https://www.cmake.org .. _CMake introduction: https://cmake.org/cmake/help/latest/manual/cmake.1.html#description -.. _Eclipse IDE for C/C++ Developers: https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/oxygen2 -.. _GNU MCU Eclipse plug-ins: https://gnu-mcu-eclipse.github.io/plugins/install/ -.. _pyOCD v0.11.0: https://github.com/mbedmicro/pyOCD/releases/tag/v0.11.0 .. _CMake list: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#lists .. _example-application: https://github.com/zephyrproject-rtos/example-application diff --git a/doc/develop/debug/index.rst b/doc/develop/debug/index.rst new file mode 100644 index 00000000000..27722464bf0 --- /dev/null +++ b/doc/develop/debug/index.rst @@ -0,0 +1,293 @@ +.. _develop_debug: + +Debugging +######### + +.. _application_debugging: + +Application Debugging +********************* + +This section is a quick hands-on reference to start debugging your +application with QEMU. Most content in this section is already covered in +`QEMU`_ and `GNU_Debugger`_ reference manuals. + +.. _QEMU: http://wiki.qemu.org/Main_Page + +.. _GNU_Debugger: http://www.gnu.org/software/gdb + +In this quick reference, you'll find shortcuts, specific environmental +variables, and parameters that can help you to quickly set up your debugging +environment. + +The simplest way to debug an application running in QEMU is using the GNU +Debugger and setting a local GDB server in your development system through QEMU. + +You will need an :abbr:`ELF (Executable and Linkable Format)` binary image for +debugging purposes. The build system generates the image in the build +directory. By default, the kernel binary name is :file:`zephyr.elf`. The name +can be changed using :kconfig:option:`CONFIG_KERNEL_BIN_NAME`. + +GDB server +========== + +We will use the standard 1234 TCP port to open a :abbr:`GDB (GNU Debugger)` +server instance. This port number can be changed for a port that best suits the +development environment. There are multiple ways to do this. Each way starts a +QEMU instance with the processor halted at startup and with a GDB server +instance listening for a connection. + +Running QEMU directly +~~~~~~~~~~~~~~~~~~~~~ + +You can run QEMU to listen for a "gdb connection" before it starts executing any +code to debug it. + +.. code-block:: bash + + qemu -s -S + +will setup Qemu to listen on port 1234 and wait for a GDB connection to it. + +The options used above have the following meaning: + +* ``-S`` Do not start CPU at startup; rather, you must type 'c' in the + monitor. +* ``-s`` Shorthand for :literal:`-gdb tcp::1234`: open a GDB server on + TCP port 1234. + + +Running QEMU via :command:`ninja` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the following inside the build directory of an application: + +.. code-block:: console + + ninja debugserver + +QEMU will write the console output to the path specified in +:makevar:`${QEMU_PIPE}` via CMake, typically :file:`qemu-fifo` within the build +directory. You may monitor this file during the run with :command:`tail -f +qemu-fifo`. + +Running QEMU via :command:`west` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the following from your project root: + +.. code-block:: console + + west build -t debugserver_qemu + +QEMU will write the console output to the terminal from which you invoked +:command:`west`. + +Configuring the :command:`gdbserver` listening device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Kconfig option :kconfig:option:`CONFIG_QEMU_GDBSERVER_LISTEN_DEV` controls +the listening device, which can be a TCP port number or a path to a character +device. GDB releases 9.0 and newer also support Unix domain sockets. + +If the option is unset, then the QEMU invocation will lack a ``-s`` or a +``-gdb`` parameter. You can then use the :envvar:`QEMU_EXTRA_FLAGS` shell +environment variable to pass in your own listen device configuration. + +GDB client +========== + +Connect to the server by running :command:`gdb` and giving these commands: + +.. code-block:: bash + + $ path/to/gdb path/to/zephyr.elf + (gdb) target remote localhost:1234 + (gdb) dir ZEPHYR_BASE + +.. note:: + + Substitute the correct :ref:`ZEPHYR_BASE ` for your + system. + +You can use a local GDB configuration :file:`.gdbinit` to initialize your GDB +instance on every run. Your home directory is a typical location for +:file:`.gdbinit`, but you can configure GDB to load from other locations, +including the directory from which you invoked :command:`gdb`. This example +file performs the same configuration as above: + +.. code-block:: none + + target remote localhost:1234 + dir ZEPHYR_BASE + +Alternate interfaces +~~~~~~~~~~~~~~~~~~~~ + +GDB provides a curses-based interface that runs in the terminal. Pass the ``--tui`` +option when invoking :command:`gdb` or give the ``tui enable`` command within +:command:`gdb`. + +.. note:: + + The GDB version on your development system might not support the ``--tui`` + option. Please make sure you use the GDB binary from the SDK which + corresponds to the toolchain that has been used to build the binary. + +Finally, the command below connects to the GDB server using the :abbr:`DDD +(Data Display Debugger)`, a graphical frontend for GDB. The following command +loads the symbol table from the ELF binary file, in this instance, +:file:`zephyr.elf`. + +.. code-block:: bash + + ddd --gdb --debugger "gdb zephyr.elf" + +Both commands execute :command:`gdb`. The command name might +change depending on the toolchain you are using and your cross-development +tools. + +:command:`ddd` may not be installed in your +development system by default. Follow your system instructions to install +it. For example, use :command:`sudo apt-get install ddd` on an Ubuntu system. + +Debugging +========= + +As configured above, when you connect the GDB client, the application will be +stopped at system startup. You may set breakpoints, step through code, etc. as +when running the application directly within :command:`gdb`. + +.. note:: + + :command:`gdb` will not print the system console output as the application runs, + unlike when you run a native application in GDB directly. If you just + :command:`continue` after connecting the client, the application will run, + but nothing will appear to happen. Check the console output as described + above. + +Debug with Eclipse +****************** + +Overview +======== + +CMake supports generating a project description file that can be imported into +the Eclipse Integrated Development Environment (IDE) and used for graphical +debugging. + +The `GNU MCU Eclipse plug-ins`_ provide a mechanism to debug ARM projects in +Eclipse with pyOCD, Segger J-Link, and OpenOCD debugging tools. + +The following tutorial demonstrates how to debug a Zephyr application in +Eclipse with pyOCD in Windows. It assumes you have already installed the GCC +ARM Embedded toolchain and pyOCD. + +Set Up the Eclipse Development Environment +========================================== + +#. Download and install `Eclipse IDE for C/C++ Developers`_. + +#. In Eclipse, install the `GNU MCU Eclipse plug-ins`_ by opening the menu + ``Window->Eclipse Marketplace...``, searching for ``GNU MCU Eclipse``, and + clicking ``Install`` on the matching result. + +#. Configure the path to the pyOCD GDB server by opening the menu + ``Window->Preferences``, navigating to ``MCU``, and setting the ``Global + pyOCD Path``. + +Generate and Import an Eclipse Project +====================================== + +#. Set up a GNU Arm Embedded toolchain as described in + :ref:`toolchain_gnuarmemb`. + +#. Navigate to a folder outside of the Zephyr tree to build your application. + + .. code-block:: console + + # On Windows + cd %userprofile% + + .. note:: + If the build directory is a subdirectory of the source directory, as is + usually done in Zephyr, CMake will warn: + + "The build directory is a subdirectory of the source directory. + + This is not supported well by Eclipse. It is strongly recommended to use + a build directory which is a sibling of the source directory." + +#. Configure your application with CMake and build it with ninja. Note the + different CMake generator specified by the ``-G"Eclipse CDT4 - Ninja"`` + argument. This will generate an Eclipse project description file, + :file:`.project`, in addition to the usual ninja build files. + + .. zephyr-app-commands:: + :tool: all + :app: %ZEPHYR_BASE%\samples\synchronization + :host-os: win + :board: frdm_k64f + :gen-args: -G"Eclipse CDT4 - Ninja" + :goals: build + :compact: + +#. In Eclipse, import your generated project by opening the menu + ``File->Import...`` and selecting the option ``Existing Projects into + Workspace``. Browse to your application build directory in the choice, + ``Select root directory:``. Check the box for your project in the list of + projects found and click the ``Finish`` button. + +Create a Debugger Configuration +=============================== + +#. Open the menu ``Run->Debug Configurations...``. + +#. Select ``GDB PyOCD Debugging``, click the ``New`` button, and configure the + following options: + + - In the Main tab: + + - Project: ``my_zephyr_app@build`` + - C/C++ Application: :file:`zephyr/zephyr.elf` + + - In the Debugger tab: + + - pyOCD Setup + + - Executable path: :file:`${pyocd_path}\\${pyocd_executable}` + - Uncheck "Allocate console for semihosting" + + - Board Setup + + - Bus speed: 8000000 Hz + - Uncheck "Enable semihosting" + + - GDB Client Setup + + - Executable path example (use your ``GNUARMEMB_TOOLCHAIN_PATH``): + :file:`C:\\gcc-arm-none-eabi-6_2017-q2-update\\bin\\arm-none-eabi-gdb.exe` + + - In the SVD Path tab: + + - File path: :file:`\\modules\\hal\\nxp\\mcux\\devices\\MK64F12\\MK64F12.xml` + + .. note:: + This is optional. It provides the SoC's memory-mapped register + addresses and bitfields to the debugger. + +#. Click the ``Debug`` button to start debugging. + +RTOS Awareness +============== + +Support for Zephyr RTOS awareness is implemented in `pyOCD v0.11.0`_ and later. +It is compatible with GDB PyOCD Debugging in Eclipse, but you must enable +CONFIG_DEBUG_THREAD_INFO=y in your application. + + + +.. _Eclipse IDE for C/C++ Developers: https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/oxygen2 +.. _GNU MCU Eclipse plug-ins: https://gnu-mcu-eclipse.github.io/plugins/install/ +.. _pyOCD v0.11.0: https://github.com/mbedmicro/pyOCD/releases/tag/v0.11.0 diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 25efad6cfcb..7067ea5653c 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -10,6 +10,7 @@ Developing with Zephyr beyond-GSG.rst env_vars.rst application/index.rst + debug/index.rst api/index.rst languages/index.rst optimizations/index From 9b2b964616d0f04f39a6e2725ed463a8e610a83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Thu, 3 Aug 2023 14:40:22 +0200 Subject: [PATCH 0061/4498] doc: add documenatation about I2C_DUMP_MESSAGES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the documentation about I2C_DUMP_MESSAGES and about the I2C_DUMP_MESSAGES_FILTER in the develop/debug/index.rst doc file. Signed-off-by: Michał Barnaś --- doc/develop/debug/index.rst | 73 +++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/doc/develop/debug/index.rst b/doc/develop/debug/index.rst index 27722464bf0..a7afdab8c31 100644 --- a/doc/develop/debug/index.rst +++ b/doc/develop/debug/index.rst @@ -286,6 +286,79 @@ Support for Zephyr RTOS awareness is implemented in `pyOCD v0.11.0`_ and later. It is compatible with GDB PyOCD Debugging in Eclipse, but you must enable CONFIG_DEBUG_THREAD_INFO=y in your application. +Debugging I2C communication +*************************** + +There is a possibility to log all or some of the I2C transactions done by the application. +This feature is enabled by the Kconfig option :kconfig:option:`CONFIG_I2C_DUMP_MESSAGES`, but it +uses the ``LOG_DBG`` function to print the contents so the +:kconfig:option:`CONFIG_I2C_LOG_LEVEL_DBG` option must also be enabled. + +The sample output of the dump looks like this:: + + D: I2C msg: io_i2c_ctrl7_port0, addr=50 + D: W len=01: 00 + D: R Sr P len=08: + D: contents: + D: 43 42 41 00 00 00 00 00 |CBA..... + +The first line indicates the I2C controller and the target address of the transaction. +In above example, the I2C controller is named ``io_i2c_ctrl7_port0`` and the target device address +is ``0x50`` + +.. note:: + + the address, length and contents values are in hexadecimal, but lack the ``0x`` prefix + +Next lines contain messages, both sent and received. The contents of write messages is +always shown, while the content of read messages is controlled by a parameter to the +function ``i2c_dump_msgs_rw``. This function is available for use by user, but is also +called internally by ``i2c_transfer`` API function with read content dump enabled. +Before the length parameter, the header of the message is printed using abbreviations: + + - W - write message + - R - read message + - Sr - restart bit + - P - stop bit + +The above example shows one write message with byte ``0x00`` representing the address of register to +read from the I2C target. After that the log shows the length of received message and following +that, the bytes read from the target ``43 42 41 00 00 00 00 00``. +The content dump consist of both the hex and ASCII representation. + +Filtering the I2C communication dump +==================================== + +By default, all I2C communication is logged between all I2C controllers and I2C targets. +It may litter the log with unrelated devices and make it difficult to effectively debug the +communication with a device of interest. + +Enable the Kconfig option :kconfig:option:`CONFIG_I2C_DUMP_MESSAGES_ALLOWLIST` to create an +allowlist of I2C targets to log. +The allowlist of devices is configured using the devicetree, for example:: + + / { + i2c { + display0: some-display@a { + ... + }; + sensor3: some-sensor@b { + ... + }; + }; + + i2c-dump-allowlist { + compatible = "zephyr,i2c-dump-allowlist"; + devices = < &display0 >, < &sensor3 >; + }; + }; + +The filters nodes are identified by the compatible string with ``zephyr,i2c-dump-allowlist`` value. +The devices are selected using the ``devices`` property with phandles to the devices on the I2C bus. + +In the above example, the communication with device ``display0`` and ``sensor3`` will be displayed +in the log. + .. _Eclipse IDE for C/C++ Developers: https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/oxygen2 From 718fe844c2f5c7bc3d6364913f08f9542a3ec44a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Tue, 5 Sep 2023 18:23:45 +0200 Subject: [PATCH 0062/4498] net: l2: ieee802154: pkt: fix cpp build failure CPP needs an additional cast. Fixes: #62282 Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154_pkt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index 23921467d96..a1dca472448 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -92,7 +92,7 @@ static inline void *net_pkt_cb(struct net_pkt *pkt); static inline struct net_pkt_cb_ieee802154 *net_pkt_cb_ieee802154(struct net_pkt *pkt) { - return net_pkt_cb(pkt); + return (struct net_pkt_cb_ieee802154 *)net_pkt_cb(pkt); }; static inline uint8_t net_pkt_ieee802154_lqi(struct net_pkt *pkt) From 4d7cef6f339ee6fa627c219b2d221a2151049efb Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 4 Sep 2023 13:28:24 +0200 Subject: [PATCH 0063/4498] bluetooth: tester: Reenable PACS characteristics After recent refactors some PACS characteristics have to be enabled with CONFIG_ variables. Signed-off-by: Magdalena Kasenberg --- tests/bluetooth/tester/overlay-le-audio.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index c482c64b5dc..eb52ea8e56e 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -29,6 +29,11 @@ CONFIG_BT_ISO_MAX_CHAN=4 # PACS CONFIG_BT_PAC_SNK_LOC_WRITEABLE=y CONFIG_BT_PAC_SRC_LOC_WRITEABLE=y +CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE=y +CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE=y +CONFIG_BT_PAC_SNK_NOTIFIABLE=y +CONFIG_BT_PAC_SRC_NOTIFIABLE=y +CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE=y # Volume Offset Control Service CONFIG_BT_VOCS_MAX_INSTANCE_COUNT=2 From a477bddc59901912a6f176658bcab20ced229e10 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 6 Sep 2023 15:44:48 +0000 Subject: [PATCH 0064/4498] kernel: dynamic: add missing assert argument Add a missing assert argument, fixes: zephyrproject/zephyr/kernel/dynamic.c: In function 'dyn_cb': zephyrproject/zephyr/include/zephyr/sys/__assert.h:44:52: warning: format '%p' expects a matching 'void *' argument [-Wformat=] That started to break the build since: d7846de548 assert: check format arguments for correctness Signed-off-by: Fabio Baltieri --- kernel/dynamic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/dynamic.c b/kernel/dynamic.c index 23e64e802b5..5215e83fa77 100644 --- a/kernel/dynamic.c +++ b/kernel/dynamic.c @@ -112,7 +112,8 @@ static void dyn_cb(const struct k_thread *thread, void *user_data) struct dyn_cb_data *const data = (struct dyn_cb_data *)user_data; if (data->stack == (k_thread_stack_t *)thread->stack_info.start) { - __ASSERT(data->tid == NULL, "stack %p is associated with more than one thread!"); + __ASSERT(data->tid == NULL, "stack %p is associated with more than one thread!", + (void *)thread->stack_info.start); data->tid = (k_tid_t)thread; } } From 58b927eb70eda1764cdd79a9f7cdf2fdc5faf119 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 6 Sep 2023 17:01:36 +0000 Subject: [PATCH 0065/4498] samples: philosophers: fix wrong assert type zephyrproject/zephyr/samples/philosophers/src/main.c: In function 'philosopher': zephyrproject/zephyr/include/zephyr/sys/__assert.h:44:52: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'stack_data_t' {aka 'long unsigned int'} [-Wformat=] Signed-off-by: Fabio Baltieri --- samples/philosophers/src/phil_obj_abstract.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/philosophers/src/phil_obj_abstract.h b/samples/philosophers/src/phil_obj_abstract.h index 9277ce8a1e7..e749a3f8d49 100644 --- a/samples/philosophers/src/phil_obj_abstract.h +++ b/samples/philosophers/src/phil_obj_abstract.h @@ -87,7 +87,7 @@ #endif #define take(x) do { \ stack_data_t data; k_stack_pop(x, &data, K_FOREVER); \ - __ASSERT(data == MAGIC, "data was %x\n", data); \ + __ASSERT(data == MAGIC, "data was %lx\n", data); \ } while ((0)) #define drop(x) k_stack_push(x, MAGIC) #define fork_type_str "stacks" From 8446afbca6ce21e4632e9bc31054464279d408e6 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 11:55:09 +0200 Subject: [PATCH 0066/4498] CODEOWNERS: Add owners to tests/bluetooth/audio Add owners to tests/bluetooth/audio based on existing owners for /tests/bluetooth/ The owners are based on the owners of /tests/bsim/bluetooth/audio/ Signed-off-by: Emil Gydesen --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 25cf3791114..07b4941cab2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -903,6 +903,7 @@ scripts/build/gen_image_info.py @tejlmand /tests/benchmarks/cmsis_dsp/ @stephanosio /tests/boards/native_posix/ @aescolar @daor-oti /tests/bluetooth/ @alwa-nordic @jhedberg @Vudentz @sjanc +/tests/bluetooth/audio/ @jhedberg @Vudentz @wopu-ot @Thalley /tests/bluetooth/controller/ @cvinayak @thoh-ot @kruithofa @erbr-ot @sjanc @ppryga /tests/bsim/bluetooth/ @alwa-nordic @jhedberg @Vudentz @wopu-ot /tests/bsim/bluetooth/audio/ @jhedberg @Vudentz @wopu-ot @Thalley From 3ecb4916b58d04366b0c2acdb61de260abab2661 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 11:56:48 +0200 Subject: [PATCH 0067/4498] MAINTAINERS: Add tests/bluetooth/audio/ to Bluetooth Audio Add tests/bluetooth/audio/ to Bluetooth Audio and Bluetooth to properly label changes and add Thalley as maintainer of them. Signed-off-by: Emil Gydesen --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index ce4a649c356..51db64aa7ba 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -228,6 +228,7 @@ Bluetooth: - tests/bluetooth/host*/ - tests/bluetooth/mesh_*/ - tests/bluetooth/mesh/ + - tests/bluetooth/audio/ - tests/bsim/bluetooth/mesh/ - tests/bluetooth/shell/audio* labels: @@ -315,6 +316,7 @@ Bluetooth Audio: files: - subsys/bluetooth/audio/ - include/zephyr/bluetooth/audio/ + - tests/bluetooth/audio/ - tests/bsim/bluetooth/audio/ - tests/bluetooth/shell/audio* labels: From 1732651062a90486a430744d1864489413ead60f Mon Sep 17 00:00:00 2001 From: Hein Wessels Date: Thu, 1 Jun 2023 08:29:59 +0200 Subject: [PATCH 0068/4498] drivers: pwm: stm32: support capturing on four channels Previously the pwm capture only support capturing on channel 1 and 2, because the slave mode controller was used, which uses the signal TIxFP which is not available for channel 3 and 4. This commit adds optional support for four channel capturing by changing the method of capturing PWM signals to not use the slave mode controller to reset the counter register. Instead the counter is reset in the ISR. This will result in a slight loss of accuracy but is still within an acceptable range. Co-authored-by: Jeroen van Dooren Signed-off-by: Hein Wessels --- drivers/pwm/pwm_stm32.c | 364 +++++++++++++++++++---------- dts/bindings/pwm/st,stm32-pwm.yaml | 8 + 2 files changed, 249 insertions(+), 123 deletions(-) diff --git a/drivers/pwm/pwm_stm32.c b/drivers/pwm/pwm_stm32.c index 44f021a874d..ca989facd5d 100644 --- a/drivers/pwm/pwm_stm32.c +++ b/drivers/pwm/pwm_stm32.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Linaro Limited. * Copyright (c) 2020 Teslabs Engineering S.L. + * Copyright (c) 2023 Nobleo Technology * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,6 +34,22 @@ LOG_MODULE_REGISTER(pwm_stm32, CONFIG_PWM_LOG_LEVEL); #endif #ifdef CONFIG_PWM_CAPTURE + +/** + * @brief Capture state when in 4-channel support mode + */ +enum capture_state { + CAPTURE_STATE_IDLE = 0, + CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT = 1, + CAPTURE_STATE_WAIT_FOR_PULSE_START = 2, + CAPTURE_STATE_WAIT_FOR_PERIOD_END = 3 +}; + +/** Return the complimentary channel number + * that is used to capture the end of the pulse. + */ +static const uint32_t complimentary_channel[] = {0, 2, 1, 4, 3}; + struct pwm_stm32_capture_data { pwm_capture_callback_handler_t callback; void *user_data; @@ -43,9 +60,16 @@ struct pwm_stm32_capture_data { bool capture_period; bool capture_pulse; bool continuous; + uint8_t channel; + + /* only used when four_channel_capture_support */ + enum capture_state state; }; -/* first capture is always nonsense, second is nonsense when polarity changed */ +/* When PWM capture is done by resetting the counter with UIF then the + * first capture is always nonsense, second is nonsense when polarity changed + * This is not the case when using four-channel-support. + */ #define SKIPPED_PWM_CAPTURES 2u #endif /*CONFIG_PWM_CAPTURE*/ @@ -70,6 +94,7 @@ struct pwm_stm32_config { const struct pinctrl_dev_config *pcfg; #ifdef CONFIG_PWM_CAPTURE void (*irq_config_func)(const struct device *dev); + const bool four_channel_capture_support; #endif /* CONFIG_PWM_CAPTURE */ }; @@ -115,6 +140,51 @@ static void (*const set_timer_compare[TIMER_MAX_CH])(TIM_TypeDef *, #endif }; +/** Channel to capture get function mapping. */ +#if !defined(CONFIG_SOC_SERIES_STM32F1X) && \ + !defined(CONFIG_SOC_SERIES_STM32F4X) && \ + !defined(CONFIG_SOC_SERIES_STM32G4X) && \ + !defined(CONFIG_SOC_SERIES_STM32MP1X) +static uint32_t __maybe_unused (*const get_channel_capture[])(const TIM_TypeDef *) = { +#else +static uint32_t __maybe_unused (*const get_channel_capture[])(TIM_TypeDef *) = { +#endif + LL_TIM_IC_GetCaptureCH1, LL_TIM_IC_GetCaptureCH2, + LL_TIM_IC_GetCaptureCH3, LL_TIM_IC_GetCaptureCH4 +}; + + +/** Channel to enable capture interrupt mapping. */ +static void __maybe_unused (*const enable_capture_interrupt[])(TIM_TypeDef *) = { + LL_TIM_EnableIT_CC1, LL_TIM_EnableIT_CC2, + LL_TIM_EnableIT_CC3, LL_TIM_EnableIT_CC4 +}; + +/** Channel to disable capture interrupt mapping. */ +static void __maybe_unused (*const disable_capture_interrupt[])(TIM_TypeDef *) = { + LL_TIM_DisableIT_CC1, LL_TIM_DisableIT_CC2, + LL_TIM_DisableIT_CC3, LL_TIM_DisableIT_CC4 +}; + +/** Channel to is capture active flag mapping. */ +#if !defined(CONFIG_SOC_SERIES_STM32F1X) && \ + !defined(CONFIG_SOC_SERIES_STM32F4X) && \ + !defined(CONFIG_SOC_SERIES_STM32G4X) && \ + !defined(CONFIG_SOC_SERIES_STM32MP1X) +static uint32_t __maybe_unused (*const is_capture_active[])(const TIM_TypeDef *) = { +#else +static uint32_t __maybe_unused (*const is_capture_active[])(TIM_TypeDef *) = { +#endif + LL_TIM_IsActiveFlag_CC1, LL_TIM_IsActiveFlag_CC2, + LL_TIM_IsActiveFlag_CC3, LL_TIM_IsActiveFlag_CC4 +}; + +/** Channel to clearing capture flag mapping. */ +static void __maybe_unused (*const clear_capture_interrupt[])(TIM_TypeDef *) = { + LL_TIM_ClearFlag_CC1, LL_TIM_ClearFlag_CC2, + LL_TIM_ClearFlag_CC3, LL_TIM_ClearFlag_CC4 +}; + /** * Obtain LL polarity from PWM flags. * @@ -270,12 +340,10 @@ static int pwm_stm32_set_cycles(const struct device *dev, uint32_t channel, } #ifdef CONFIG_PWM_CAPTURE - if ((channel == 1u) || (channel == 2u)) { - if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || - LL_TIM_IsEnabledIT_CC2(cfg->timer)) { - LOG_ERR("Cannot set PWM output, capture in progress"); - return -EBUSY; - } + if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || + LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { + LOG_ERR("Cannot set PWM output, capture in progress"); + return -EBUSY; } #endif /* CONFIG_PWM_CAPTURE */ @@ -391,8 +459,8 @@ static int pwm_stm32_set_cycles(const struct device *dev, uint32_t channel, } #ifdef CONFIG_PWM_CAPTURE -static int init_capture_channel(const struct device *dev, uint32_t channel, - pwm_flags_t flags, uint32_t ll_channel) +static int init_capture_channels(const struct device *dev, uint32_t channel, + pwm_flags_t flags) { const struct pwm_stm32_config *cfg = dev->config; bool is_inverted = (flags & PWM_POLARITY_MASK) == PWM_POLARITY_INVERTED; @@ -402,30 +470,21 @@ static int init_capture_channel(const struct device *dev, uint32_t channel, ic.ICPrescaler = TIM_ICPSC_DIV1; ic.ICFilter = LL_TIM_IC_FILTER_FDIV1; - if (ll_channel == LL_TIM_CHANNEL_CH1) { - if (channel == 1u) { - ic.ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; - ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_FALLING - : LL_TIM_IC_POLARITY_RISING; - } else { - ic.ICActiveInput = LL_TIM_ACTIVEINPUT_INDIRECTTI; - ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_RISING - : LL_TIM_IC_POLARITY_FALLING; - } - } else { - if (channel == 1u) { - ic.ICActiveInput = LL_TIM_ACTIVEINPUT_INDIRECTTI; - ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_RISING - : LL_TIM_IC_POLARITY_FALLING; - } else { - ic.ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; - ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_FALLING - : LL_TIM_IC_POLARITY_RISING; - } + /* Setup main channel */ + ic.ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_FALLING : LL_TIM_IC_POLARITY_RISING; + + if (LL_TIM_IC_Init(cfg->timer, ch2ll[channel - 1], &ic) != SUCCESS) { + LOG_ERR("Could not initialize main channel for PWM capture"); + return -EIO; } - if (LL_TIM_IC_Init(cfg->timer, ll_channel, &ic) != SUCCESS) { - LOG_ERR("Could not initialize channel for PWM capture"); + /* Setup complimentary channel */ + ic.ICActiveInput = LL_TIM_ACTIVEINPUT_INDIRECTTI; + ic.ICPolarity = is_inverted ? LL_TIM_IC_POLARITY_RISING : LL_TIM_IC_POLARITY_FALLING; + + if (LL_TIM_IC_Init(cfg->timer, ch2ll[complimentary_channel[channel] - 1], &ic) != SUCCESS) { + LOG_ERR("Could not initialize complimentary channel for PWM capture"); return -EIO; } @@ -437,12 +496,17 @@ static int pwm_stm32_configure_capture(const struct device *dev, pwm_capture_callback_handler_t cb, void *user_data) { - /* - * Capture is implemented using the slave mode controller. - * This allows for high accuracy, but only CH1 and CH2 are supported. - * Alternatively all channels could be supported with ISR based resets. - * This is currently not implemented! + * Capture is implemented in two different ways, depending on the + * four-channel-capture-support setting in the node. + * - Two Channel Support: + * Only two channels (1 and 2) are available for capture. It uses + * the slave mode controller to reset the counter on each edge. + * - Four Channel Support: + * All four channels are available for capture. Instead of the + * slave mode controller it uses the ISR to reset the counter. + * This is slightly less accurate, but still within acceptable + * bounds. */ const struct pwm_stm32_config *cfg = dev->config; @@ -450,14 +514,21 @@ static int pwm_stm32_configure_capture(const struct device *dev, struct pwm_stm32_capture_data *cpt = &data->capture; int ret; - if ((channel != 1u) && (channel != 2u)) { - LOG_ERR("PWM capture only supported on first two channels"); - return -ENOTSUP; + if (!cfg->four_channel_capture_support) { + if ((channel != 1u) && (channel != 2u)) { + LOG_ERR("PWM capture only supported on first two channels"); + return -ENOTSUP; + } + } else { + if ((channel < 1u) || (channel > 4u)) { + LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); + return -ENOTSUP; + } } - if (LL_TIM_IsEnabledIT_CC1(cfg->timer) - || LL_TIM_IsEnabledIT_CC2(cfg->timer)) { - LOG_ERR("PWM Capture already in progress"); + if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || + LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { + LOG_ERR("PWM capture already in progress"); return -EBUSY; } @@ -466,7 +537,8 @@ static int pwm_stm32_configure_capture(const struct device *dev, return -EINVAL; } - if (!IS_TIM_SLAVE_INSTANCE(cfg->timer)) { + if (!cfg->four_channel_capture_support && !IS_TIM_SLAVE_INSTANCE(cfg->timer)) { + /* slave mode is only used when not in four channel mode */ LOG_ERR("Timer does not support slave mode for PWM capture"); return -ENOTSUP; } @@ -480,22 +552,19 @@ static int pwm_stm32_configure_capture(const struct device *dev, /* Prevents faulty behavior while making changes */ LL_TIM_SetSlaveMode(cfg->timer, LL_TIM_SLAVEMODE_DISABLED); - ret = init_capture_channel(dev, channel, flags, LL_TIM_CHANNEL_CH1); - if (ret < 0) { - return ret; - } - - ret = init_capture_channel(dev, channel, flags, LL_TIM_CHANNEL_CH2); + ret = init_capture_channels(dev, channel, flags); if (ret < 0) { return ret; } - if (channel == 1u) { - LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI1FP1); - } else { - LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI2FP2); + if (!cfg->four_channel_capture_support) { + if (channel == 1u) { + LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI1FP1); + } else { + LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI2FP2); + } + LL_TIM_SetSlaveMode(cfg->timer, LL_TIM_SLAVEMODE_RESET); } - LL_TIM_SetSlaveMode(cfg->timer, LL_TIM_SLAVEMODE_RESET); LL_TIM_EnableARRPreload(cfg->timer); if (!IS_TIM_32B_COUNTER_INSTANCE(cfg->timer)) { @@ -512,14 +581,22 @@ static int pwm_stm32_enable_capture(const struct device *dev, uint32_t channel) { const struct pwm_stm32_config *cfg = dev->config; struct pwm_stm32_data *data = dev->data; + struct pwm_stm32_capture_data *cpt = &data->capture; - if ((channel != 1u) && (channel != 2u)) { - LOG_ERR("PWM capture only supported on first two channels"); - return -EINVAL; + if (!cfg->four_channel_capture_support) { + if ((channel != 1u) && (channel != 2u)) { + LOG_ERR("PWM capture only supported on first two channels"); + return -ENOTSUP; + } + } else { + if ((channel < 1u) || (channel > 4u)) { + LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); + return -ENOTSUP; + } } - if (LL_TIM_IsEnabledIT_CC1(cfg->timer) - || LL_TIM_IsEnabledIT_CC2(cfg->timer)) { + if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || + LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { LOG_ERR("PWM capture already active"); return -EBUSY; } @@ -529,21 +606,22 @@ static int pwm_stm32_enable_capture(const struct device *dev, uint32_t channel) return -EINVAL; } - data->capture.skip_irq = SKIPPED_PWM_CAPTURES; + cpt->channel = channel; + cpt->state = CAPTURE_STATE_WAIT_FOR_PULSE_START; + data->capture.skip_irq = cfg->four_channel_capture_support ? 0 : SKIPPED_PWM_CAPTURES; data->capture.overflows = 0u; - LL_TIM_ClearFlag_CC1(cfg->timer); - LL_TIM_ClearFlag_CC2(cfg->timer); + + clear_capture_interrupt[channel - 1](cfg->timer); LL_TIM_ClearFlag_UPDATE(cfg->timer); LL_TIM_SetUpdateSource(cfg->timer, LL_TIM_UPDATESOURCE_COUNTER); - if (channel == 1u) { - LL_TIM_EnableIT_CC1(cfg->timer); - } else { - LL_TIM_EnableIT_CC2(cfg->timer); - } + + enable_capture_interrupt[channel - 1](cfg->timer); + + LL_TIM_CC_EnableChannel(cfg->timer, ch2ll[channel - 1]); + LL_TIM_CC_EnableChannel(cfg->timer, ch2ll[complimentary_channel[channel] - 1]); LL_TIM_EnableIT_UPDATE(cfg->timer); - LL_TIM_CC_EnableChannel(cfg->timer, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(cfg->timer, LL_TIM_CHANNEL_CH2); + LL_TIM_GenerateEvent_UPDATE(cfg->timer); return 0; } @@ -552,37 +630,27 @@ static int pwm_stm32_disable_capture(const struct device *dev, uint32_t channel) { const struct pwm_stm32_config *cfg = dev->config; - if ((channel != 1u) && (channel != 2u)) { - LOG_ERR("PWM capture only supported on first two channels"); - return -EINVAL; + if (!cfg->four_channel_capture_support) { + if ((channel != 1u) && (channel != 2u)) { + LOG_ERR("PWM capture only supported on first two channels"); + return -ENOTSUP; + } + } else { + if ((channel < 1u) || (channel > 4u)) { + LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); + return -ENOTSUP; + } } LL_TIM_SetUpdateSource(cfg->timer, LL_TIM_UPDATESOURCE_REGULAR); - if (channel == 1u) { - LL_TIM_DisableIT_CC1(cfg->timer); - } else { - LL_TIM_DisableIT_CC2(cfg->timer); - } - LL_TIM_DisableIT_UPDATE(cfg->timer); - LL_TIM_CC_DisableChannel(cfg->timer, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_DisableChannel(cfg->timer, LL_TIM_CHANNEL_CH2); - return 0; -} + disable_capture_interrupt[channel - 1](cfg->timer); -static void get_pwm_capture(const struct device *dev, uint32_t channel) -{ - const struct pwm_stm32_config *cfg = dev->config; - struct pwm_stm32_data *data = dev->data; - struct pwm_stm32_capture_data *cpt = &data->capture; + LL_TIM_DisableIT_UPDATE(cfg->timer); + LL_TIM_CC_DisableChannel(cfg->timer, ch2ll[channel - 1]); + LL_TIM_CC_DisableChannel(cfg->timer, ch2ll[complimentary_channel[channel] - 1]); - if (channel == 1u) { - cpt->period = LL_TIM_IC_GetCaptureCH1(cfg->timer); - cpt->pulse = LL_TIM_IC_GetCaptureCH2(cfg->timer); - } else { - cpt->period = LL_TIM_IC_GetCaptureCH2(cfg->timer); - cpt->pulse = LL_TIM_IC_GetCaptureCH1(cfg->timer); - } + return 0; } static void pwm_stm32_isr(const struct device *dev) @@ -591,52 +659,101 @@ static void pwm_stm32_isr(const struct device *dev) struct pwm_stm32_data *data = dev->data; struct pwm_stm32_capture_data *cpt = &data->capture; int status = 0; - uint32_t in_ch = LL_TIM_IsEnabledIT_CC1(cfg->timer) ? 1u : 2u; - if (cpt->skip_irq == 0u) { + if (cpt->skip_irq != 0u) { if (LL_TIM_IsActiveFlag_UPDATE(cfg->timer)) { LL_TIM_ClearFlag_UPDATE(cfg->timer); - cpt->overflows++; } if (LL_TIM_IsActiveFlag_CC1(cfg->timer) - || LL_TIM_IsActiveFlag_CC2(cfg->timer)) { + || LL_TIM_IsActiveFlag_CC2(cfg->timer) + || LL_TIM_IsActiveFlag_CC3(cfg->timer) + || LL_TIM_IsActiveFlag_CC4(cfg->timer)) { LL_TIM_ClearFlag_CC1(cfg->timer); LL_TIM_ClearFlag_CC2(cfg->timer); + LL_TIM_ClearFlag_CC3(cfg->timer); + LL_TIM_ClearFlag_CC4(cfg->timer); + cpt->skip_irq--; + } - get_pwm_capture(dev, in_ch); + return; + } - if (cpt->overflows) { - LOG_ERR("counter overflow during PWM capture"); - status = -ERANGE; - } + if (LL_TIM_IsActiveFlag_UPDATE(cfg->timer)) { + LL_TIM_ClearFlag_UPDATE(cfg->timer); + if (cfg->four_channel_capture_support && + cpt->state == CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT) { + /* Special handling of UPDATE event in case it's triggered */ + cpt->state = CAPTURE_STATE_WAIT_FOR_PERIOD_END; + } else { + cpt->overflows++; + } + } - if (!cpt->continuous) { - pwm_stm32_disable_capture(dev, in_ch); - } else { - cpt->overflows = 0u; - } + if (!cfg->four_channel_capture_support) { + if (is_capture_active[cpt->channel - 1](cfg->timer) || + is_capture_active[complimentary_channel[cpt->channel] - 1](cfg->timer)) { + clear_capture_interrupt[cpt->channel - 1](cfg->timer); + clear_capture_interrupt + [complimentary_channel[cpt->channel] - 1](cfg->timer); - if (cpt->callback != NULL) { - cpt->callback(dev, in_ch, - cpt->capture_period ? cpt->period : 0u, - cpt->capture_pulse ? cpt->pulse : 0u, - status, cpt->user_data); - } + cpt->period = get_channel_capture[cpt->channel - 1](cfg->timer); + cpt->pulse = get_channel_capture + [complimentary_channel[cpt->channel] - 1](cfg->timer); } } else { - if (LL_TIM_IsActiveFlag_UPDATE(cfg->timer)) { - LL_TIM_ClearFlag_UPDATE(cfg->timer); + if (cpt->state == CAPTURE_STATE_WAIT_FOR_PULSE_START && + is_capture_active[cpt->channel - 1](cfg->timer)) { + /* Reset the counter manually instead of automatically by HW + * This sets the pulse-start at 0 and makes the pulse-end + * and period related to that number. Sure we loose some + * accuracy but it's within acceptable range. + * + * This is done through an UPDATE event to also reset + * the prescalar. This could look like an overflow event + * and might therefore require special handling. + */ + cpt->state = CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT; + LL_TIM_GenerateEvent_UPDATE(cfg->timer); + + } else if ((cpt->state == CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT || + cpt->state == CAPTURE_STATE_WAIT_FOR_PERIOD_END) && + is_capture_active[cpt->channel - 1](cfg->timer)) { + cpt->state = CAPTURE_STATE_IDLE; + /* The end of the period. Both capture channels should now contain + * the timer value when the pulse and period ended respectively. + */ + cpt->pulse = get_channel_capture[complimentary_channel[cpt->channel] - 1] + (cfg->timer); + cpt->period = get_channel_capture[cpt->channel - 1](cfg->timer); } - if (LL_TIM_IsActiveFlag_CC1(cfg->timer) - || LL_TIM_IsActiveFlag_CC2(cfg->timer)) { - LL_TIM_ClearFlag_CC1(cfg->timer); - LL_TIM_ClearFlag_CC2(cfg->timer); - cpt->skip_irq--; + clear_capture_interrupt[cpt->channel - 1](cfg->timer); + + if (cpt->state != CAPTURE_STATE_IDLE) { + /* Still waiting for a complete capture */ + return; + } + + if (cpt->overflows) { + LOG_ERR("counter overflow during PWM capture"); + status = -ERANGE; } } + + if (!cpt->continuous) { + pwm_stm32_disable_capture(dev, cpt->channel); + } else { + cpt->overflows = 0u; + cpt->state = CAPTURE_STATE_WAIT_FOR_PULSE_START; + } + + if (cpt->callback != NULL) { + cpt->callback(dev, cpt->channel, cpt->capture_period ? cpt->period : 0u, + cpt->capture_pulse ? cpt->pulse : 0u, status, cpt->user_data); + } } + #endif /* CONFIG_PWM_CAPTURE */ static int pwm_stm32_get_cycles_per_sec(const struct device *dev, @@ -755,8 +872,9 @@ static void pwm_stm32_irq_config_func_##index(const struct device *dev) \ (IRQ_CONNECT_AND_ENABLE_DEFAULT(index)) \ ); \ } -#define CAPTURE_INIT(index) \ - .irq_config_func = pwm_stm32_irq_config_func_##index +#define CAPTURE_INIT(index) \ + .irq_config_func = pwm_stm32_irq_config_func_##index, \ + .four_channel_capture_support = DT_INST_PROP(index, four_channel_capture_support) #else #define IRQ_CONFIG_FUNC(index) #define CAPTURE_INIT(index) diff --git a/dts/bindings/pwm/st,stm32-pwm.yaml b/dts/bindings/pwm/st,stm32-pwm.yaml index 26d758ec7af..cf61c257971 100644 --- a/dts/bindings/pwm/st,stm32-pwm.yaml +++ b/dts/bindings/pwm/st,stm32-pwm.yaml @@ -11,6 +11,14 @@ properties: pinctrl-names: required: true + four-channel-capture-support: + type: boolean + description: | + Add support to capture on four channels. This is less accurate than + the default 2 channel support because the counter is reset by + interrupt instead of slave-mode controller. This option can also + be used as alternative for timers that does not support slave mode. + "#pwm-cells": const: 3 description: | From 582995359a10add2925cbe00b82523f585c936f7 Mon Sep 17 00:00:00 2001 From: Hein Wessels Date: Thu, 1 Jun 2023 08:33:21 +0200 Subject: [PATCH 0069/4498] tests: drivers: pwm_capture: nucleo_h743zi: add four channel capture At least one of this test cases in pwm_capture needs to verify the working of four-channel-capture-support. Signed-off-by: Hein Wessels --- tests/drivers/pwm/pwm_loopback/boards/nucleo_h743zi.overlay | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/drivers/pwm/pwm_loopback/boards/nucleo_h743zi.overlay b/tests/drivers/pwm/pwm_loopback/boards/nucleo_h743zi.overlay index 5007b962ec9..7ebf049ee13 100644 --- a/tests/drivers/pwm/pwm_loopback/boards/nucleo_h743zi.overlay +++ b/tests/drivers/pwm/pwm_loopback/boards/nucleo_h743zi.overlay @@ -31,5 +31,10 @@ status = "okay"; pinctrl-0 = <&tim5_ch1_pa0>; /* CN11 PIN28 */ pinctrl-names = "default"; + + /* At least one of the test devices need to verify + * the four-channel-capture-support in this test. + */ + four-channel-capture-support; }; }; From e5ec893c003bd127e81c93822c8199f4c2f82e94 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Sun, 2 Jul 2023 14:04:55 +0530 Subject: [PATCH 0070/4498] lib: acpi: add support for MAD table and DMAR table add support for retrieve MAD and DMAR table information. Provided two new interface namely acpi_dmar_entry_get() and acpi_drhd_get() for retrieve DMA Remapping Reporting and DMA-remapping hardware unit definition (DRDH). Signed-off-by: Najumon B.A --- include/zephyr/acpi/acpi.h | 67 ++++++++++++- lib/acpi/Kconfig | 6 +- lib/acpi/acpi.c | 176 ++++++++++++++++++++++++++++++++-- lib/acpi/acpi_shell.c | 12 +-- modules/acpica/CMakeLists.txt | 32 ++++--- modules/acpica/Kconfig | 6 ++ 6 files changed, 264 insertions(+), 35 deletions(-) diff --git a/include/zephyr/acpi/acpi.h b/include/zephyr/acpi/acpi.h index dc6a25c8ea8..77a1f2e9527 100644 --- a/include/zephyr/acpi/acpi.h +++ b/include/zephyr/acpi/acpi.h @@ -10,6 +10,11 @@ #define ACPI_RES_INVALID ACPI_RESOURCE_TYPE_MAX +#define ACPI_DRHD_FLAG_INCLUDE_PCI_ALL BIT(0) +#define ACPI_DMAR_FLAG_INTR_REMAP BIT(0) +#define ACPI_DMAR_FLAG_X2APIC_OPT_OUT BIT(1) +#define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN BIT(2) + struct acpi_dev { ACPI_HANDLE handle; char *path; @@ -19,6 +24,22 @@ struct acpi_dev { ACPI_DEVICE_INFO *dev_info; }; +union acpi_dmar_id { + struct { + uint16_t function: 3; + uint16_t device: 5; + uint16_t bus: 8; + } bits; + + uint16_t raw; +}; + +struct acpi_mcfg { + struct acpi_table_header header; + uint64_t _reserved; + struct acpi_mcfg_allocation pci_segs[]; +} __packed; + /** * @brief Retrieve a legacy interrupt number for a PCI device. * @@ -62,8 +83,7 @@ int acpi_current_resource_free(ACPI_RESOURCE *res); * @param rt_size the the size of IRQ routing table * @return return 0 on success or error code */ -int acpi_get_irq_routing_table(char *bus_name, - ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size); +int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size); /** * @brief Parse resource table for a given resource type. @@ -117,9 +137,48 @@ int acpi_device_type_get(ACPI_RESOURCE *res); * * @param signature pointer to the 4-character ACPI signature for the requested table * @param inst instance number for the requested table - * @param acpi_table pointer to the acpi table + * @return acpi_table pointer to the acpi table on success else return NULL + */ +void *acpi_table_get(char *signature, int inst); + +/** + * @brief retrieve acpi MAD table for the given type. + * + * @param type type of requested MAD table + * @param tables pointer to the MAD table + * @param num_inst number of instance for the requested table + * @return return 0 on success or error code + */ +int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num_inst); + +/** + * @brief retrieve DMA remapping structure for the given type. + * + * @param type type of remapping structure + * @param tables pointer to the dmar id structure * @return return 0 on success or error code */ -int acpi_table_get(char *signature, int inst, void **acpi_table); +int acpi_dmar_entry_get(enum AcpiDmarType type, + struct acpi_subtable_header **tables); +/** + * @brief retrieve acpi DRHD info for the given scope. + * + * @param scope scope of requested DHRD table + * @param dev_scope pointer to the sub table (optional) + * @param dmar_id pointer to the DHRD info + * @param num_inst number of instance for the requested table + * @param max_inst maximum number of entry for the given dmar_id buffer + * @return return 0 on success or error code + */ +int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *dev_scope, + union acpi_dmar_id *dmar_id, int *num_inst, int max_inst); + +/** + * @brief Retrieve lapic info for a specific cpu. + * + * @param cpu_num the cpu number + * @return lapic info on success or NULL + */ +struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num); #endif diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index 366dfa66782..022eb083c84 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -40,10 +40,10 @@ config ACPI_INIT_PRIORITY boot time init level for acpi driver. config ACPI_MAX_INIT_TABLES - int "acpi table size" - default 16 + int "maximum table entries" + default 128 help - acpi table size. + maximum number of table entries. endif # ACPI diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index e8948b51e17..d8f91d01ce8 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -39,7 +39,6 @@ static int check_init_status(void) } if (bus_ctx.status == AE_NOT_CONFIGURED) { - LOG_DBG("ACPI init\n"); ret = acpi_init(); } else { LOG_ERR("ACPI init was not success\n"); @@ -252,8 +251,10 @@ static int acpi_get_irq_table(struct acpi *bus, char *bus_name, if (!bus->pci_prt_table[i].SourceIndex) { break; } - /* mark the PRT irq numbers as reserved. */ - arch_irq_set_used(bus->pci_prt_table[i].SourceIndex); + if (IS_ENABLED(CONFIG_X86_64)) { + /* mark the PRT irq numbers as reserved. */ + arch_irq_set_used(bus->pci_prt_table[i].SourceIndex); + } } return 0; @@ -624,7 +625,7 @@ struct acpi_dev *acpi_device_by_index_get(int index) return index < bus_ctx.num_dev ? &bus_ctx.child_dev[index] : NULL; } -int acpi_table_get(char *signature, int inst, void **acpi_table) +void *acpi_table_get(char *signature, int inst) { int status; ACPI_TABLE_HEADER *table; @@ -632,18 +633,179 @@ int acpi_table_get(char *signature, int inst, void **acpi_table) if (!bus_ctx.early_init) { status = acpi_early_init(); if (status) { - LOG_ERR("ACPI early int failed"); - return status; + LOG_ERR("ACPI early init failed"); + return NULL; } } status = AcpiGetTable(signature, inst, &table); if (ACPI_FAILURE(status)) { LOG_ERR("ACPI get table failed: %d", status); + return NULL; + } + + return (void *)table; +} + +static uint32_t acpi_get_subtable_entry_num(int type, struct acpi_subtable_header *subtable, + uintptr_t offset, uintptr_t base, uint32_t madt_len) +{ + uint32_t subtable_cnt = 0; + + while (offset < madt_len) { + if (type == subtable->Type) { + subtable_cnt++; + } + offset += subtable->Length; + subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset); + + if (!subtable->Length) { + break; + } + } + + return subtable_cnt; +} + +int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num_inst) +{ + struct acpi_table_header *madt = acpi_table_get("APIC", 0); + uintptr_t base = POINTER_TO_UINT(madt); + uintptr_t offset = sizeof(ACPI_TABLE_MADT); + struct acpi_subtable_header *subtable; + + if (!madt) { return -EIO; } - *acpi_table = table; + subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset); + while (offset < madt->Length) { + + if (type == subtable->Type) { + *tables = subtable; + *num_inst = acpi_get_subtable_entry_num(type, subtable, offset, base, + madt->Length); + return 0; + } + + offset += subtable->Length; + subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset); + } + + return -ENODEV; +} + +int acpi_dmar_entry_get(enum AcpiDmarType type, struct acpi_subtable_header **tables) +{ + struct acpi_table_dmar *dmar = acpi_table_get("DMAR", 0); + uintptr_t base = POINTER_TO_UINT(dmar); + uintptr_t offset = sizeof(ACPI_TABLE_DMAR); + struct acpi_dmar_header *subtable; + + if (!dmar) { + LOG_ERR("error on get DMAR table\n"); + return -EIO; + } + + subtable = ACPI_ADD_PTR(ACPI_DMAR_HEADER, base, offset); + while (offset < dmar->Header.Length) { + if (type == subtable->Type) { + *tables = (struct acpi_subtable_header *)subtable; + return 0; + } + offset += subtable->Length; + subtable = ACPI_ADD_PTR(ACPI_DMAR_HEADER, base, offset); + } + + return -ENODEV; +} + +int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *dev_scope, + union acpi_dmar_id *dmar_id, int *num_inst, int max_inst) +{ + uintptr_t offset = sizeof(ACPI_DMAR_HARDWARE_UNIT); + uint32_t i = 0; + struct acpi_dmar_header *drdh; + struct acpi_dmar_device_scope *subtable; + struct acpi_dmar_pci_path *dev_path; + int ret; + uintptr_t base; + int scope_size; + + ret = acpi_dmar_entry_get(ACPI_DMAR_TYPE_HARDWARE_UNIT, + (struct acpi_subtable_header **)&drdh); + if (ret) { + LOG_ERR("Error on retrieve DMAR table\n"); + return ret; + } + + scope_size = drdh->Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); + base = (uintptr_t)((uintptr_t)drdh + offset); + + offset = 0; + + while (scope_size) { + int num_path; + + subtable = ACPI_ADD_PTR(ACPI_DMAR_DEVICE_SCOPE, base, offset); + if (!subtable->Length) { + break; + } + + if (scope == subtable->EntryType) { + num_path = (subtable->Length - 6u) / 2u; + dev_path = ACPI_ADD_PTR(ACPI_DMAR_PCI_PATH, subtable, + sizeof(ACPI_DMAR_DEVICE_SCOPE)); + + while (num_path--) { + if (i >= max_inst) { + LOG_ERR("DHRD not enough buffer size\n"); + return -ENOBUFS; + } + dmar_id[i].bits.bus = subtable->Bus; + dmar_id[i].bits.device = dev_path[i].Device; + dmar_id[i].bits.function = dev_path[i].Function; + i++; + } + break; + } + + offset += subtable->Length; + + if (scope_size < subtable->Length) { + break; + } + scope_size -= subtable->Length; + } + + *num_inst = i; + if (!i) { + LOG_ERR("Error on retrieve DRHD Info\n"); + return -ENODEV; + } + + if (dev_scope && subtable) { + memcpy(dev_scope, subtable, sizeof(struct acpi_dmar_device_scope)); + } return 0; } + +struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num) +{ + struct acpi_madt_local_apic *lapic; + int cpu_cnt; + + if (acpi_madt_entry_get(ACPI_MADT_TYPE_LOCAL_APIC, (ACPI_SUBTABLE_HEADER **)&lapic, + &cpu_cnt)) { + /* Error on MAD table. */ + return NULL; + } + + if ((cpu_num >= cpu_cnt) || !(lapic[cpu_num].LapicFlags & 1u)) { + /* Proccessor not enabled. */ + return NULL; + } + + return &lapic[cpu_num]; +} diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index 570bb18d821..c6c5d5ed60d 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -91,7 +92,7 @@ static void dump_dev_res(const struct shell *sh, ACPI_RESOURCE *res_lst) shell_print(sh, "\nACPI_RESOURCE_TYPE_ADDRESS32\n\n"); shell_print(sh, "Minimum:%x, Maximum:%x\n", add_res->Address.Minimum, - add_res->Address.Maximum); + add_res->Address.Maximum); break; case ACPI_RESOURCE_TYPE_ADDRESS64: ACPI_RESOURCE_ADDRESS64 * add_res64 = &res->Data.Address64; @@ -237,7 +238,6 @@ static int enum_dev(const struct shell *sh, size_t argc, char **argv) static int read_table(const struct shell *sh, size_t argc, char **argv) { - int status; ACPI_TABLE_HEADER *table; if (argc < 2) { @@ -246,10 +246,10 @@ static int read_table(const struct shell *sh, size_t argc, char **argv) shell_print(sh, "ACPI Table Name: %s\n", argv[1]); - status = acpi_table_get(argv[1], 0, (void **)&table); - if (status) { - shell_error(sh, "ACPI get table failed: %d\n", status); - return status; + table = acpi_table_get(argv[1], 0); + if (!table) { + shell_error(sh, "ACPI get table failed\n"); + return -EIO; } shell_print(sh, "ACPI Table Info:\n"); diff --git a/modules/acpica/CMakeLists.txt b/modules/acpica/CMakeLists.txt index 29f685e0266..17aed310448 100644 --- a/modules/acpica/CMakeLists.txt +++ b/modules/acpica/CMakeLists.txt @@ -29,6 +29,7 @@ if (CONFIG_ACPI) get_filename_component(libname "${SRC_DIR}/common/" NAME) +if (CONFIG_ACPI_DSDT_SUPPORT) zephyr_library_sources( ${COMP_DIR}/dispatcher/dsargs.c ${COMP_DIR}/dispatcher/dscontrol.c @@ -46,7 +47,6 @@ if (CONFIG_ACPI) ${COMP_DIR}/dispatcher/dswload2.c ${COMP_DIR}/dispatcher/dswscope.c ${COMP_DIR}/dispatcher/dswstate.c - ${COMP_DIR}/events/evhandler.c ${COMP_DIR}/events/evmisc.c ${COMP_DIR}/events/evregion.c @@ -113,6 +113,22 @@ if (CONFIG_ACPI) ${COMP_DIR}/parser/psutils.c ${COMP_DIR}/parser/pswalk.c ${COMP_DIR}/parser/psxface.c + ${COMP_DIR}/resources/rsxface.c + ${COMP_DIR}/resources/rsutils.c + ${COMP_DIR}/resources/rsaddr.c + ${COMP_DIR}/resources/rscalc.c + ${COMP_DIR}/resources/rscreate.c + ${COMP_DIR}/resources/rsdumpinfo.c + ${COMP_DIR}/resources/rsinfo.c + ${COMP_DIR}/resources/rsio.c + ${COMP_DIR}/resources/rsirq.c + ${COMP_DIR}/resources/rslist.c + ${COMP_DIR}/resources/rsmemory.c + ${COMP_DIR}/resources/rsmisc.c + ${COMP_DIR}/resources/rsserial.c + ) +endif (CONFIG_ACPI_DSDT_SUPPORT) + zephyr_library_sources( ${COMP_DIR}/tables/tbdata.c ${COMP_DIR}/tables/tbfadt.c ${COMP_DIR}/tables/tbfind.c @@ -158,20 +174,6 @@ if (CONFIG_ACPI) ${COMP_DIR}/utilities/utxfinit.c ${COMP_DIR}/utilities/utresdecode.c ${COMP_DIR}/hardware/hwvalid.c - ${COMP_DIR}/resources/rsxface.c - ${COMP_DIR}/resources/rsutils.c - ${COMP_DIR}/resources/rsaddr.c - ${COMP_DIR}/resources/rscalc.c - ${COMP_DIR}/resources/rscreate.c - ${COMP_DIR}/resources/rsdumpinfo.c - ${COMP_DIR}/resources/rsinfo.c - ${COMP_DIR}/resources/rsio.c - ${COMP_DIR}/resources/rsirq.c - ${COMP_DIR}/resources/rslist.c - ${COMP_DIR}/resources/rsmemory.c - ${COMP_DIR}/resources/rsmisc.c - ${COMP_DIR}/resources/rsserial.c - ${SRC_DIR}/os_specific/service_layers/oszephyr.c ) endif (CONFIG_ACPI) diff --git a/modules/acpica/Kconfig b/modules/acpica/Kconfig index 07d6d24c278..29153cd78dd 100644 --- a/modules/acpica/Kconfig +++ b/modules/acpica/Kconfig @@ -6,4 +6,10 @@ config ACPI menu "ACPI driver support" +config ACPI_DSDT_SUPPORT + bool "Build source code for DSDT ACPICA support" + default y if PCIE + help + Build source code for DSDT support + endmenu From a68204d8b8e2bfa4b2516814eefac56f4478bab4 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Sun, 2 Jul 2023 15:27:24 +0530 Subject: [PATCH 0071/4498] arch: x86: update with new acpica lib interface The old acpi implimentation is replaced with acpica interface and updated x86 arch porting with the new interface. Signed-off-by: Najumon B.A --- arch/x86/Kconfig | 10 +- arch/x86/core/CMakeLists.txt | 2 +- arch/x86/core/intel64/cpu.c | 13 +- arch/x86/core/legacy_bios.c | 53 ++++++ arch/x86/core/pcie.c | 22 +-- arch/x86/core/prep_c.c | 2 +- drivers/interrupt_controller/intc_ioapic.c | 12 +- include/zephyr/acpi/acpi_osal.h | 16 ++ include/zephyr/arch/x86/acpi.h | 204 --------------------- include/zephyr/arch/x86/legacy_bios.h | 12 ++ include/zephyr/arch/x86/x86_acpi_osal.h | 29 +++ 11 files changed, 141 insertions(+), 234 deletions(-) create mode 100644 arch/x86/core/legacy_bios.c create mode 100644 include/zephyr/acpi/acpi_osal.h delete mode 100644 include/zephyr/arch/x86/acpi.h create mode 100644 include/zephyr/arch/x86/legacy_bios.h create mode 100644 include/zephyr/arch/x86/x86_acpi_osal.h diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5f22707aed9..d7ccfca7ecd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -227,22 +227,16 @@ choice Reboot via the RST_CNT register, going back to BIOS. endchoice -config X86_ACPI - bool "ACPI (Advanced Configuration and Power Interface) support" - depends on X86_PC_COMPATIBLE - help - Allow retrieval of platform configuration at runtime. - config PCIE_MMIO_CFG bool "Use MMIO PCI configuration space access" - select X86_ACPI + select ACPI help Selects the use of the memory-mapped PCI Express Extended Configuration Space instead of the traditional 0xCF8/0xCFC IO Port registers. config KERNEL_VM_SIZE - default 0x40000000 if X86_ACPI + default 0x40000000 if ACPI config X86_PC_COMPATIBLE bool diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt index 4c4bfa98fe9..9268dc4cf4d 100644 --- a/arch/x86/core/CMakeLists.txt +++ b/arch/x86/core/CMakeLists.txt @@ -15,7 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_PCIE pcie.c) zephyr_library_sources_ifdef(CONFIG_REBOOT_RST_CNT reboot_rst_cnt.c) zephyr_library_sources_ifdef(CONFIG_MULTIBOOT_INFO multiboot.c) zephyr_library_sources_ifdef(CONFIG_X86_EFI efi.c) -zephyr_library_sources_ifdef(CONFIG_X86_ACPI acpi.c) +zephyr_library_sources_ifdef(CONFIG_ACPI legacy_bios.c) zephyr_library_sources_ifdef(CONFIG_X86_MMU x86_mmu.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.c) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index 80e9e65b90d..db8b69b0d1e 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 4, "Only supports max 4 CPUs"); @@ -142,13 +142,12 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, uint8_t vector = ((unsigned long) x86_ap_start) >> 12; uint8_t apic_id; - if (IS_ENABLED(CONFIG_X86_ACPI)) { - struct acpi_cpu *cpu; + if (IS_ENABLED(CONFIG_ACPI)) { + struct acpi_madt_local_apic *lapic = acpi_local_apic_get(cpu_num); - cpu = z_acpi_get_cpu(cpu_num); - if (cpu != NULL) { - /* We update the apic_id, x86_ap_start will need it. */ - x86_cpu_loapics[cpu_num] = cpu->apic_id; + if (lapic != NULL) { + /* We update the apic_id, __start will need it. */ + x86_cpu_loapics[cpu_num] = lapic->Id; } } diff --git a/arch/x86/core/legacy_bios.c b/arch/x86/core/legacy_bios.c new file mode 100644 index 00000000000..6a7159a9b1c --- /dev/null +++ b/arch/x86/core/legacy_bios.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define DATA_SIZE_K(n) (n * 1024u) +#define RSDP_SIGNATURE ((uint64_t)0x2052545020445352) +#define EBDA_ADD (0x040e) +#define BIOS_RODATA_ADD (0xe0000) +#define BIOS_EXT_DATA_LOW (0x80000UL) +#define BIOS_EXT_DATA_HIGH (0x100000UL) + +static uintptr_t bios_search_rsdp_buff(uintptr_t search_phy_add, uint32_t search_length) +{ + uint64_t *search_buff; + + z_phys_map((uint8_t **)&search_buff, search_phy_add, search_length, 0); + if (!search_buff) { + return 0; + } + + for (int i = 0; i < search_length / 8u; i++) { + if (search_buff[i] == RSDP_SIGNATURE) { + z_phys_unmap((uint8_t *)search_buff, search_length); + return (search_phy_add + (i * 8u)); + } + } + z_phys_unmap((uint8_t *)search_buff, search_length); + + return 0; +} + +void *bios_acpi_rsdp_get(void) +{ + uint8_t *bios_ext_data, *zero_page_base; + uintptr_t search_phy_add, rsdp_phy_add; + + z_phys_map(&zero_page_base, 0, DATA_SIZE_K(4u), 0); + bios_ext_data = EBDA_ADD + zero_page_base; + search_phy_add = (uintptr_t)((*(uint16_t *)bios_ext_data) << 4u); + z_phys_unmap(zero_page_base, DATA_SIZE_K(4u)); + + if ((search_phy_add >= BIOS_EXT_DATA_LOW) && (search_phy_add < BIOS_EXT_DATA_HIGH)) { + rsdp_phy_add = bios_search_rsdp_buff(search_phy_add, DATA_SIZE_K(1u)); + if (rsdp_phy_add) { + return (void *)rsdp_phy_add; + } + } + return (void *)bios_search_rsdp_buff(BIOS_RODATA_ADD, DATA_SIZE_K(128u)); +} diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index 47b78f990c1..5c1e83725bb 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -8,8 +8,8 @@ #include #include -#ifdef CONFIG_X86_ACPI -#include +#ifdef CONFIG_ACPI +#include #endif #ifdef CONFIG_PCIE_MSI @@ -35,26 +35,26 @@ static bool do_pcie_mmio_cfg; static void pcie_mm_init(void) { -#ifdef CONFIG_X86_ACPI - struct acpi_mcfg *m = z_acpi_find_table(ACPI_MCFG_SIGNATURE); +#ifdef CONFIG_ACPI + struct acpi_mcfg *m = acpi_table_get("MCFG", 0); if (m != NULL) { - int n = (m->sdt.length - sizeof(*m)) / sizeof(m->pci_segs[0]); + int n = (m->header.Length - sizeof(*m)) / sizeof(m->pci_segs[0]); for (int i = 0; i < n && i < MAX_PCI_BUS_SEGMENTS; i++) { size_t size; uintptr_t phys_addr; - bus_segs[i].start_bus = m->pci_segs[i].start_bus; - bus_segs[i].n_buses = 1 + m->pci_segs[i].end_bus - - m->pci_segs[i].start_bus; + bus_segs[i].start_bus = m->pci_segs[i].StartBusNumber; + bus_segs[i].n_buses = + 1 + m->pci_segs[i].EndBusNumber - m->pci_segs[i].StartBusNumber; - phys_addr = m->pci_segs[i].base_addr; + phys_addr = m->pci_segs[i].Address; /* 32 devices & 8 functions per bus, 4k per device */ size = bus_segs[i].n_buses * (32 * 8 * 4096); - device_map((mm_reg_t *)&bus_segs[i].mmio, phys_addr, - size, K_MEM_CACHE_NONE); + device_map((mm_reg_t *)&bus_segs[i].mmio, phys_addr, size, + K_MEM_CACHE_NONE); } do_pcie_mmio_cfg = true; diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index 70c3e844756..ffb4d6b019a 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/interrupt_controller/intc_ioapic.c b/drivers/interrupt_controller/intc_ioapic.c index f889d0d2295..424f1d5332c 100644 --- a/drivers/interrupt_controller/intc_ioapic.c +++ b/drivers/interrupt_controller/intc_ioapic.c @@ -120,7 +120,7 @@ static void IoApicRedUpdateLo(unsigned int irq, uint32_t value, !defined(CONFIG_INTEL_VTD_ICTL_XAPIC_PASSTHROUGH) #include -#include +#include static const struct device *const vtd = DEVICE_DT_GET_OR_NULL(DT_INST(0, intel_vt_d)); @@ -129,11 +129,19 @@ static uint16_t ioapic_id; static bool get_vtd(void) { + union acpi_dmar_id *dmar_id; + int inst_cnt; + if (vtd != NULL) { return true; } - ioapic_id = z_acpi_get_dev_id_from_dmar(ACPI_DRHD_DEV_SCOPE_IOAPIC); + /* Assume only one PCH in system (say client platform). */ + if (!acpi_drhd_get(ACPI_DMAR_SCOPE_TYPE_IOAPIC, NULL, &dmar_id, &inst_cnt, 1u)) { + return false; + } + + ioapic_id = dmar_id->raw; return vtd == NULL ? false : true; } diff --git a/include/zephyr/acpi/acpi_osal.h b/include/zephyr/acpi/acpi_osal.h new file mode 100644 index 00000000000..92e0180bc45 --- /dev/null +++ b/include/zephyr/acpi/acpi_osal.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ + +#if defined(CONFIG_X86 || CONFIG_X86_64) +#include "zephyr/acpi/x86_acpi_osal.h" +#else +#error "Currently only x86 Architecture support ACPI !!" +#endif + +#endif /* ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ */ diff --git a/include/zephyr/arch/x86/acpi.h b/include/zephyr/arch/x86/acpi.h deleted file mode 100644 index df4a5dcc089..00000000000 --- a/include/zephyr/arch/x86/acpi.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_ARCH_X86_ACPI_H -#define ZEPHYR_INCLUDE_ARCH_X86_ACPI_H - -#ifndef _ASMLANGUAGE - -#define ACPI_RSDP_SIGNATURE 0x2052545020445352 /* == "RSD PTR " */ - -/* Root System Description Pointer */ -struct acpi_rsdp { - char signature[8]; - uint8_t chksum; - char oem_id[6]; - uint8_t revision; - uint32_t rsdt_ptr; - uint32_t length; - uint64_t xsdt_ptr; - uint8_t ext_chksum; - uint8_t _reserved[3]; -} __packed; - -/* Standard table header */ -struct acpi_sdt { - uint32_t signature; - uint32_t length; - uint8_t revision; - uint8_t chksum; - char oem_id[6]; - char oem_table_id[8]; - uint32_t oem_revision; - uint32_t creator_id; - uint32_t creator_revision; -} __packed; - -/* Root System Description Table */ -struct acpi_rsdt { - struct acpi_sdt sdt; - uint32_t table_ptrs[]; -} __packed; - -/* eXtended System Descriptor Table */ -struct acpi_xsdt { - struct acpi_sdt sdt; - uint64_t table_ptrs[]; -} __packed; - -/* MCFG table storing MMIO addresses for PCI configuration space */ - -#define ACPI_MCFG_SIGNATURE 0x4746434d /* 'MCFG' */ - -struct acpi_mcfg { - struct acpi_sdt sdt; - uint64_t _reserved; - struct { - uint64_t base_addr; - uint16_t seg_group_num; - uint8_t start_bus; - uint8_t end_bus; - } pci_segs[]; -} __packed; - -/* MADT table storing IO-APIC and multiprocessor configuration */ - -#define ACPI_MADT_SIGNATURE 0x43495041 /* 'APIC' */ - -struct acpi_madt_entry { - uint8_t type; /* See ACPI_MADT_ENTRY_* below */ - uint8_t length; -} __packed; - -#define ACPI_MADT_ENTRY_CPU 0 - -struct acpi_madt { - struct acpi_sdt sdt; - uint32_t loapic; /* local APIC MMIO address */ - uint32_t flags; /* see ACPI_MADT_FLAGS_* below */ - struct acpi_madt_entry entries[]; -} __packed; - -#define ACPI_MADT_FLAGS_PICS 0x01 /* legacy 8259s installed */ - -struct acpi_cpu { - struct acpi_madt_entry entry; - uint8_t acpi_id; - uint8_t apic_id; /* local APIC ID */ - uint8_t flags; /* see ACPI_CPU_FLAGS_* below */ -} __packed; - -#define ACPI_CPU_FLAGS_ENABLED 0x01 - -/* Generic DMA Remapping entry structure part */ -struct acpi_dmar_entry { - uint16_t type; /* See ACPI_DMAR_TYPE_* below */ - uint16_t length; -} __packed; - -#define ACPI_DMAR_TYPE_DRHD 0 /* DMA Remapping Hardware Unit Definition */ -#define ACPI_DMAR_TYPE_RMRR 1 /* Do not care atm (legacy usage) */ -#define ACPI_DMAR_TYPE_ATSR 2 /* Do not care atm (PCIE ATS support) */ -#define ACPI_DMAR_TYPE_RHSA 3 /* Do not care atm (NUMA specific ) */ -#define ACPI_DMAR_TYPE_ANDD 4 /* Do not care atm (ACPI DSDT related) */ -#define ACPI_DMAR_TYPE_SACT 5 /* Do not care atm */ - -/* PCI Device/Function Pair (forming the BDF, with start_bus_num below) */ -struct acpi_dmar_dev_path { - uint8_t device; - uint8_t function; -} __packed; - -#define ACPI_DMAR_DEV_PATH_SIZE 2 - -/* DMA Remapping Device Scope */ -struct acpi_dmar_dev_scope { - uint8_t type; /* See ACPI_DRHD_DEV_SCOPE_* below */ - uint8_t length; /* 6 + X where X is Path attribute size */ - uint16_t _reserved; - uint8_t enumeration_id; - uint8_t start_bus_num; /* PCI bus, forming BDF with each Path below */ - struct acpi_dmar_dev_path path[]; /* One is at least always found */ -} __packed; - -#define ACPI_DMAR_DEV_SCOPE_MIN_SIZE 6 - -#define ACPI_DRHD_DEV_SCOPE_PCI_EPD 0x01 -#define ACPI_DRHD_DEV_SCOPE_PCI_SUB_H 0x02 -#define ACPI_DRHD_DEV_SCOPE_IOAPIC 0x03 -#define ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET 0x04 -#define ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV 0x05 - -struct acpi_drhd { - struct acpi_dmar_entry entry; - uint8_t flags; /* See ACPI_DRHD_FLAG_* below */ - uint8_t _reserved; - uint16_t segment_num; /* Associated PCI segment */ - uint64_t base_address; /* Base address of the remapping hw */ - struct acpi_dmar_dev_scope device_scope[]; -} __packed; - -#define ACPI_DRHD_MIN_SIZE 16 - -#define ACPI_DRHD_FLAG_INCLUDE_PCI_ALL BIT(0) - -#define ACPI_DMAR_SIGNATURE 0x52414D44 /* 'DMAR' */ - -#define ACPI_DMAR_FLAG_INTR_REMAP BIT(0) -#define ACPI_DMAR_FLAG_X2APIC_OPT_OUT BIT(1) -#define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN BIT(2) - -/* DMA Remapping reporting structure */ -struct acpi_dmar { - struct acpi_sdt sdt; - uint8_t host_addr_width; - uint8_t flags; - uint8_t _reserved[10]; - struct acpi_dmar_entry remap_entries[]; -} __packed; - -union acpi_dmar_id { - struct { - uint16_t function : 3; - uint16_t device : 5; - uint16_t bus : 8; - } bits; - - uint16_t raw; -}; - -#if defined(CONFIG_X86_ACPI) - -void *z_acpi_find_table(uint32_t signature); - -struct acpi_cpu *z_acpi_get_cpu(int n); - -struct acpi_dmar *z_acpi_find_dmar(void); - -struct acpi_drhd *z_acpi_find_drhds(int *n); - -struct acpi_dmar_dev_scope *z_acpi_get_drhd_dev_scopes(struct acpi_drhd *drhd, - int *n); - -struct acpi_dmar_dev_path * -z_acpi_get_dev_scope_paths(struct acpi_dmar_dev_scope *dev_scope, int *n); - -uint16_t z_acpi_get_dev_id_from_dmar(uint8_t dev_scope_type); - -#else /* CONFIG_X86_ACPI */ - -#define z_acpi_find_table(...) NULL -#define z_acpi_get_cpu(...) NULL -#define z_acpi_find_dmar(...) NULL -#define z_acpi_find_drhds(...) NULL -#define z_acpi_get_drhd_dev_scopes(...) NULL -#define z_acpi_get_dev_scope_paths(...) NULL -#define z_acpi_get_dev_id_from_dmar(...) USHRT_MAX - -#endif /* CONFIG_X86_ACPI */ - -#endif /* _ASMLANGUAGE */ - -#endif /* ZEPHYR_INCLUDE_ARCH_X86_ACPI_H */ diff --git a/include/zephyr/arch/x86/legacy_bios.h b/include/zephyr/arch/x86/legacy_bios.h new file mode 100644 index 00000000000..a5abd67d8c5 --- /dev/null +++ b/include/zephyr/arch/x86/legacy_bios.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ + +void *bios_acpi_rsdp_get(void); + +#endif /* ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ */ diff --git a/include/zephyr/arch/x86/x86_acpi_osal.h b/include/zephyr/arch/x86/x86_acpi_osal.h new file mode 100644 index 00000000000..8f742b024b7 --- /dev/null +++ b/include/zephyr/arch/x86/x86_acpi_osal.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ + +#if defined(CONFIG_X86_EFI) +static inline void *acpi_rsdp_get(void) +{ + void *rsdp = efi_get_acpi_rsdp(); + + if (!rsdp) { + rsdp = bios_acpi_rsdp_get(); + } + + return rsdp; +} +#else +static inline void *acpi_rsdp_get(void) +{ + return bios_acpi_rsdp_get(); +} +#endif /* CONFIG_X86_EFI */ +#endif /* ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ */ From 7597bc1de438e65f5790a28585b423228c9435a0 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Sun, 2 Jul 2023 15:34:45 +0530 Subject: [PATCH 0072/4498] test: arch: x86: update with new acpica interface modified existing x86 tests app with the new acpica interface Signed-off-by: Najumon B.A --- tests/arch/x86/info/CMakeLists.txt | 2 +- tests/arch/x86/info/prj.conf | 2 +- tests/arch/x86/info/src/acpi.c | 122 +++++++++--------- tests/boot/uefi/prj.conf | 2 +- .../disk/disk_access/boards/qemu_x86_64.conf | 2 +- .../disk_performance/boards/qemu_x86_64.conf | 2 +- 6 files changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/arch/x86/info/CMakeLists.txt b/tests/arch/x86/info/CMakeLists.txt index a8c8dcdf1ad..7a6c14f12d3 100644 --- a/tests/arch/x86/info/CMakeLists.txt +++ b/tests/arch/x86/info/CMakeLists.txt @@ -8,6 +8,6 @@ project(x86_info) target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/timer.c) -target_sources_ifdef(CONFIG_X86_ACPI app PRIVATE src/acpi.c) +target_sources_ifdef(CONFIG_ACPI app PRIVATE src/acpi.c) target_sources_ifdef(CONFIG_MULTIBOOT app PRIVATE src/multiboot.c) target_sources_ifdef(CONFIG_X86_MEMMAP app PRIVATE src/memmap.c) diff --git a/tests/arch/x86/info/prj.conf b/tests/arch/x86/info/prj.conf index 4e89c3de68a..bb56a340a7e 100644 --- a/tests/arch/x86/info/prj.conf +++ b/tests/arch/x86/info/prj.conf @@ -1,4 +1,4 @@ -CONFIG_X86_ACPI=y +CONFIG_ACPI=y CONFIG_MULTIBOOT_INFO=y CONFIG_MULTIBOOT_MEMMAP=y CONFIG_COUNTER=y diff --git a/tests/arch/x86/info/src/acpi.c b/tests/arch/x86/info/src/acpi.c index e8501bc3ef2..4271710ba22 100644 --- a/tests/arch/x86/info/src/acpi.c +++ b/tests/arch/x86/info/src/acpi.c @@ -4,30 +4,33 @@ */ #include -#include +#include -static void vtd_dev_scope_info(struct acpi_dmar_dev_scope *dev_scope) +static const uint32_t dmar_scope[] = {ACPI_DMAR_SCOPE_TYPE_ENDPOINT, ACPI_DMAR_SCOPE_TYPE_BRIDGE, + ACPI_DMAR_SCOPE_TYPE_IOAPIC, ACPI_DMAR_SCOPE_TYPE_HPET, + ACPI_DMAR_SCOPE_TYPE_NAMESPACE}; + +static void vtd_dev_scope_info(int type, struct acpi_dmar_device_scope *dev_scope, + union acpi_dmar_id *dmar_id, int num_inst) { - struct acpi_dmar_dev_path *path; - uint16_t id; - int n_path; + int i = 0; printk("\t\t\t. Type: "); - switch (dev_scope->type) { - case ACPI_DRHD_DEV_SCOPE_PCI_EPD: + switch (type) { + case ACPI_DMAR_SCOPE_TYPE_ENDPOINT: printk("PCI Endpoint"); break; - case ACPI_DRHD_DEV_SCOPE_PCI_SUB_H: + case ACPI_DMAR_SCOPE_TYPE_BRIDGE: printk("PCI Sub-hierarchy"); break; - case ACPI_DRHD_DEV_SCOPE_IOAPIC: - printk("IOAPIC"); + case ACPI_DMAR_SCOPE_TYPE_IOAPIC: + break; - case ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET: + case ACPI_DMAR_SCOPE_TYPE_HPET: printk("MSI Capable HPET"); break; - case ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV: + case ACPI_DMAR_SCOPE_TYPE_NAMESPACE: printk("ACPI name-space enumerated"); break; default: @@ -35,33 +38,26 @@ static void vtd_dev_scope_info(struct acpi_dmar_dev_scope *dev_scope) return; } - id = z_acpi_get_dev_id_from_dmar(dev_scope->type); - if (id != USHRT_MAX) { - printk(" ID 0x%x", id); - } - printk("\n"); - printk("\t\t\t. Enumeration ID %u\n", dev_scope->enumeration_id); - printk("\t\t\t. PCI Bus %u\n", dev_scope->start_bus_num); + printk("\t\t\t. Enumeration ID %u\n", dev_scope->EnumerationId); + printk("\t\t\t. PCI Bus %u\n", dev_scope->Bus); - path = z_acpi_get_dev_scope_paths(dev_scope, &n_path); - for (; n_path > 0; n_path--) { - printk("\t\t\t. Path D:%u F:%u\n", - path->device, path->function); - path = (struct acpi_dmar_dev_path *)(POINTER_TO_UINT(path) + - ACPI_DMAR_DEV_PATH_SIZE); + for (; num_inst > 0; num_inst--, i++) { + printk("Info: Bus: %d, dev:%d, fun:%d\n", dmar_id[i].bits.bus, + dmar_id[i].bits.device, dmar_id[i].bits.function); } printk("\n"); } -static void vtd_drhd_info(struct acpi_drhd *drhd) +static void vtd_drhd_info(struct acpi_dmar_hardware_unit *drhd) { - struct acpi_dmar_dev_scope *dev_scope; - int n_ds, i; + struct acpi_dmar_device_scope dev_scope; + union acpi_dmar_id dmar_id[4]; + int num_inst, i; - if (drhd->flags & ACPI_DRHD_FLAG_INCLUDE_PCI_ALL) { + if (drhd->Flags & ACPI_DRHD_FLAG_INCLUDE_PCI_ALL) { printk("\t\t- Includes all PCI devices"); } else { printk("\t\t- Includes only listed PCI devices"); @@ -69,20 +65,19 @@ static void vtd_drhd_info(struct acpi_drhd *drhd) printk(" under given Segment\n"); - printk("\t\t- Segment number %u\n", drhd->segment_num); - printk("\t\t- Base Address 0x%llx\n", drhd->base_address); - - dev_scope = z_acpi_get_drhd_dev_scopes(drhd, &n_ds); - if (dev_scope == NULL) { - printk("\t\t- No device scopes\n"); - return; - } + printk("\t\t- Segment number %u\n", drhd->Segment); + printk("\t\t- Base Address 0x%llx\n", drhd->Address); printk("\t\t- Device Scopes:\n"); - for (i = 0; i < n_ds; i++) { - vtd_dev_scope_info(dev_scope); - dev_scope = (struct acpi_dmar_dev_scope *)( - POINTER_TO_UINT(dev_scope) + dev_scope->length); + for (i = 0; i < 5; i++) { + if (acpi_drhd_get(dmar_scope[i], &dev_scope, dmar_id, &num_inst, 4u)) { + printk(" No DRHD entry found for scope type:%d\n", dmar_scope[i]); + continue; + } + + printk("Found DRHD entry: %d\n", i); + + vtd_dev_scope_info(dmar_scope[i], &dev_scope, dmar_id, num_inst); } printk("\n"); @@ -90,9 +85,10 @@ static void vtd_drhd_info(struct acpi_drhd *drhd) static void vtd_info(void) { - struct acpi_dmar *dmar; + struct acpi_table_dmar *dmar; + struct acpi_dmar_hardware_unit *drhd; - dmar = z_acpi_find_dmar(); + dmar = acpi_table_get("DMAR", 0); if (dmar == NULL) { printk("\tIntel VT-D not supported or exposed\n"); return; @@ -101,27 +97,22 @@ static void vtd_info(void) printk("\tIntel VT-D Supported:\n"); printk("\t-> X2APIC "); - if (dmar->flags & ACPI_DMAR_FLAG_X2APIC_OPT_OUT) { + if (dmar->Flags & ACPI_DMAR_FLAG_X2APIC_OPT_OUT) { printk("should be opted out\n"); } else { printk("does not need to be opted out\n"); } - if (dmar->flags & ACPI_DMAR_FLAG_INTR_REMAP) { - struct acpi_drhd *drhd; - int hw_n, i; + if (dmar->Flags & ACPI_DMAR_FLAG_INTR_REMAP) { printk("\t-> Interrupt remapping supported\n"); - drhd = z_acpi_find_drhds(&hw_n); - printk("\t-> %u remapping hardware found:\n", hw_n); - - for (i = 0; i < hw_n; i++) { - printk("\t\tDRHD %u:\n", i); - vtd_drhd_info(drhd); - drhd = (struct acpi_drhd *)(POINTER_TO_UINT(drhd) + - drhd->entry.length); + if (acpi_dmar_entry_get(ACPI_DMAR_TYPE_HARDWARE_UNIT, + (struct acpi_subtable_header **)&drhd)) { + printk("error in retrieve DHRD!!\n"); + return; } + vtd_drhd_info(drhd); } else { printk("\t-> Interrupt remapping not supported\n"); } @@ -129,10 +120,20 @@ static void vtd_info(void) void acpi(void) { - int nr_cpus; + int nr_cpus = 0, i, inst_cnt; + struct acpi_madt_local_apic *lapic; - for (nr_cpus = 0; z_acpi_get_cpu(nr_cpus); ++nr_cpus) { - /* count number of CPUs present */ + if (acpi_madt_entry_get(ACPI_MADT_TYPE_LOCAL_APIC, (ACPI_SUBTABLE_HEADER **)&lapic, + &inst_cnt)) { + printk("error on get MAD table\n"); + return; + } + + /* count number of CPUs present which are enabled*/ + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + if (lapic[i].LapicFlags & 1u) { + nr_cpus++; + } } if (nr_cpus == 0) { @@ -140,9 +141,8 @@ void acpi(void) } else { printk("ACPI: %d CPUs found\n", nr_cpus); - for (int i = 0; i < nr_cpus; ++i) { - struct acpi_cpu *cpu = z_acpi_get_cpu(i); - printk("\tCPU #%d: APIC ID 0x%02x\n", i, cpu->apic_id); + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; ++i) { + printk("\tCPU #%d: APIC ID 0x%02x\n", i, lapic[i].Id); } } diff --git a/tests/boot/uefi/prj.conf b/tests/boot/uefi/prj.conf index 17df3666c72..48ca509cdd5 100644 --- a/tests/boot/uefi/prj.conf +++ b/tests/boot/uefi/prj.conf @@ -1,4 +1,4 @@ CONFIG_QEMU_UEFI_BOOT=y CONFIG_BUILD_OUTPUT_EFI=y CONFIG_SRAM_SIZE=204800 -CONFIG_X86_ACPI=y +CONFIG_ACPI=y diff --git a/tests/drivers/disk/disk_access/boards/qemu_x86_64.conf b/tests/drivers/disk/disk_access/boards/qemu_x86_64.conf index 9760440e93b..0c14f763bf9 100644 --- a/tests/drivers/disk/disk_access/boards/qemu_x86_64.conf +++ b/tests/drivers/disk/disk_access/boards/qemu_x86_64.conf @@ -1,4 +1,4 @@ -CONFIG_X86_ACPI=y +CONFIG_ACPI=y CONFIG_PCIE=y CONFIG_PCIE_MSI=y CONFIG_PCIE_MSI_X=y diff --git a/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf b/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf index 9760440e93b..0c14f763bf9 100644 --- a/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf +++ b/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf @@ -1,4 +1,4 @@ -CONFIG_X86_ACPI=y +CONFIG_ACPI=y CONFIG_PCIE=y CONFIG_PCIE_MSI=y CONFIG_PCIE_MSI_X=y From ff1afd97e1e2e14a7f5eaceed7dddf258a27306b Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Sun, 2 Jul 2023 15:41:15 +0530 Subject: [PATCH 0073/4498] board: qemu_x86: update with new acpica interface update qemu, up_squared, acrn and ehl platform board config with new acpica interface Signed-off-by: Najumon B.A --- boards/x86/acrn/Kconfig.defconfig | 4 ++++ boards/x86/intel_ehl/Kconfig.defconfig | 4 ++++ boards/x86/qemu_x86/Kconfig.defconfig | 8 ++++++++ boards/x86/qemu_x86/board.cmake | 2 +- boards/x86/qemu_x86/qemu_x86.dts | 2 +- boards/x86/up_squared/Kconfig.defconfig | 4 ++++ 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/boards/x86/acrn/Kconfig.defconfig b/boards/x86/acrn/Kconfig.defconfig index af0a294d422..0216875583c 100644 --- a/boards/x86/acrn/Kconfig.defconfig +++ b/boards/x86/acrn/Kconfig.defconfig @@ -10,4 +10,8 @@ config BOARD config MP_MAX_NUM_CPUS default 2 +config HEAP_MEM_POOL_SIZE + default 32768 if ACPI + depends on KERNEL_MEM_POOL + endif diff --git a/boards/x86/intel_ehl/Kconfig.defconfig b/boards/x86/intel_ehl/Kconfig.defconfig index d2745ed436e..d0a9aa7093b 100644 --- a/boards/x86/intel_ehl/Kconfig.defconfig +++ b/boards/x86/intel_ehl/Kconfig.defconfig @@ -19,6 +19,10 @@ config SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN default n endif +config HEAP_MEM_POOL_SIZE + default 32768 if ACPI + depends on KERNEL_MEM_POOL + # TSC on this board is 1.9 GHz, HPET and APIC are 19.2 MHz config SYS_CLOCK_HW_CYCLES_PER_SEC default 1900000000 if APIC_TSC_DEADLINE_TIMER diff --git a/boards/x86/qemu_x86/Kconfig.defconfig b/boards/x86/qemu_x86/Kconfig.defconfig index 0866657a7c3..1ea60480f64 100644 --- a/boards/x86/qemu_x86/Kconfig.defconfig +++ b/boards/x86/qemu_x86/Kconfig.defconfig @@ -24,6 +24,10 @@ config FLASH_SIMULATOR config KERNEL_VM_SIZE default 0x10000000 if ACPI +config HEAP_MEM_POOL_SIZE + default 32768 if ACPI + depends on KERNEL_MEM_POOL + config MULTIBOOT default y @@ -49,6 +53,10 @@ config BOARD config KERNEL_VM_SIZE default 0x10000000 if ACPI +config HEAP_MEM_POOL_SIZE + default 32768 if ACPI + depends on KERNEL_MEM_POOL + endif # BOARD_QEMU_X86_64 if BOARD_QEMU_X86_LAKEMONT diff --git a/boards/x86/qemu_x86/board.cmake b/boards/x86/qemu_x86/board.cmake index 214d85ecc87..934b078154e 100644 --- a/boards/x86/qemu_x86/board.cmake +++ b/boards/x86/qemu_x86/board.cmake @@ -66,7 +66,7 @@ set(QEMU_FLAGS_${ARCH} -nographic ) -if(NOT CONFIG_X86_ACPI) +if(NOT CONFIG_ACPI) list(APPEND QEMU_FLAGS_${ARCH} -no-acpi) endif() diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 62fc4dff7a7..806e1cad8b4 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -8,7 +8,7 @@ #define DT_DRAM_BASE 0 #endif #ifndef DT_DRAM_SIZE -#define DT_DRAM_SIZE DT_SIZE_K(4096) +#define DT_DRAM_SIZE DT_SIZE_M(32) #endif #define DT_FLASH_SIZE DT_SIZE_K(4096) diff --git a/boards/x86/up_squared/Kconfig.defconfig b/boards/x86/up_squared/Kconfig.defconfig index 87d1f169ec5..659ecc336ef 100644 --- a/boards/x86/up_squared/Kconfig.defconfig +++ b/boards/x86/up_squared/Kconfig.defconfig @@ -8,6 +8,10 @@ config BOARD config MP_MAX_NUM_CPUS default 2 if BOARD_UP_SQUARED +config HEAP_MEM_POOL_SIZE + default 32768 if ACPI + depends on KERNEL_MEM_POOL + config BUILD_OUTPUT_STRIPPED default y From 351243ea90b2df7395dc32eee23f8ba5a99cebe6 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Thu, 31 Aug 2023 14:34:33 +0530 Subject: [PATCH 0074/4498] modules: lib: acpica: update west to fetch acpica PR 882 update west to fetch acpica PR 882 for running CI job. This is a temp commit to verify CI job and will update with latest commit once acpica PR get merged into mainline. Signed-off-by: Najumon B.A --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 83cb644b9fb..71f54a88d01 100644 --- a/west.yml +++ b/west.yml @@ -30,7 +30,7 @@ manifest: # Please add items below based on alphabetical order projects: - name: acpica - revision: f16a0b4d0f0edd7b78a332fcf507be2187fac21e + revision: 0333c2af13179f9b33d495cf7cb9a509f751cbb1 path: modules/lib/acpica - name: bsim repo-path: babblesim-manifest From 592da93644b80ac2dc62f31ca0ca4c8d2ae4770c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 6 Jul 2023 19:43:48 +0200 Subject: [PATCH 0075/4498] Bluetooth: CAP: Add minimum metadata len req for CAP CAP requires setting the streaming context in the metadata, which requires 4 octets of metadata, so the metadata for CAP must be greater than or equal to 4. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/Kconfig.cap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/audio/Kconfig.cap b/subsys/bluetooth/audio/Kconfig.cap index 64762a86572..9fdc1506c3d 100644 --- a/subsys/bluetooth/audio/Kconfig.cap +++ b/subsys/bluetooth/audio/Kconfig.cap @@ -11,6 +11,7 @@ config BT_CAP config BT_CAP_ACCEPTOR bool "Common Audio Profile Acceptor Role Support [EXPERIMENTAL]" depends on BT_BAP_UNICAST_SERVER || (BT_BAP_BROADCAST_SINK && BT_BAP_SCAN_DELEGATOR) + depends on BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE >= 4 select EXPERIMENTAL help Enabling this will enable the CAP Acceptor role. This instantiates the @@ -30,6 +31,7 @@ config BT_CAP_ACCEPTOR_SET_MEMBER config BT_CAP_INITIATOR bool "Common Audio Profile Initiator Role Support [EXPERIMENTAL]" depends on (BT_BAP_UNICAST_CLIENT && BT_CSIP_SET_COORDINATOR) || BT_BAP_BROADCAST_SOURCE + depends on BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE >= 4 select EXPERIMENTAL help Enabling this will enable the CAP Initiator role. From f020aa41fcf84303a517fb3e3603d4a03d6d3ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Tue, 1 Aug 2023 12:07:12 +0000 Subject: [PATCH 0076/4498] dts: bindings: Add fintek vendor prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add vendor prefix for Feature Integration Technology Inc. Signed-off-by: Paweł Anikiel --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index c38c3db55ac..a2af2b9249a 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -213,6 +213,7 @@ fcs Fairchild Semiconductor feixin Shenzhen Feixin Photoelectic Co., Ltd feiyang Shenzhen Fly Young Technology Co.,LTD. fii Foxconn Industrial Internet +fintek Feature Integration Technology Inc. firefly Firefly focaltech FocalTech Systems Co.,Ltd frida Shenzhen Frida LCD Co., Ltd. From 43668c6416d9bd7237d59d9f1414852f7cc56db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Tue, 1 Aug 2023 12:09:27 +0000 Subject: [PATCH 0077/4498] drivers: sensor: Add F75303 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add driver for F75303 temperature sensor IC. Signed-off-by: Paweł Anikiel --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/f75303/CMakeLists.txt | 5 + drivers/sensor/f75303/Kconfig | 22 +++ drivers/sensor/f75303/f75303.c | 198 ++++++++++++++++++++++++ drivers/sensor/f75303/f75303.h | 30 ++++ drivers/sensor/f75303/f75303_emul.c | 176 +++++++++++++++++++++ dts/bindings/sensor/fintek,f75303.yaml | 10 ++ include/zephyr/drivers/sensor/f75303.h | 17 ++ tests/drivers/build_all/sensor/i2c.dtsi | 5 + 10 files changed, 465 insertions(+) create mode 100644 drivers/sensor/f75303/CMakeLists.txt create mode 100644 drivers/sensor/f75303/Kconfig create mode 100644 drivers/sensor/f75303/f75303.c create mode 100644 drivers/sensor/f75303/f75303.h create mode 100644 drivers/sensor/f75303/f75303_emul.c create mode 100644 dts/bindings/sensor/fintek,f75303.yaml create mode 100644 include/zephyr/drivers/sensor/f75303.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 5839ea12e97..b3696bde3a2 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -32,6 +32,7 @@ add_subdirectory_ifdef(CONFIG_DPS310 dps310) add_subdirectory_ifdef(CONFIG_DS18B20 ds18b20) add_subdirectory_ifdef(CONFIG_ENS210 ens210) add_subdirectory_ifdef(CONFIG_ESP32_TEMP esp32_temp) +add_subdirectory_ifdef(CONFIG_F75303 f75303) add_subdirectory_ifdef(CONFIG_FDC2X1X fdc2x1x) add_subdirectory_ifdef(CONFIG_FXAS21002 fxas21002) add_subdirectory_ifdef(CONFIG_FXOS8700 fxos8700) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 8311b4b4bf4..cfb9d88b38c 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -88,6 +88,7 @@ source "drivers/sensor/dps310/Kconfig" source "drivers/sensor/ds18b20/Kconfig" source "drivers/sensor/ens210/Kconfig" source "drivers/sensor/esp32_temp/Kconfig" +source "drivers/sensor/f75303/Kconfig" source "drivers/sensor/fdc2x1x/Kconfig" source "drivers/sensor/fxas21002/Kconfig" source "drivers/sensor/fxos8700/Kconfig" diff --git a/drivers/sensor/f75303/CMakeLists.txt b/drivers/sensor/f75303/CMakeLists.txt new file mode 100644 index 00000000000..9441b13f054 --- /dev/null +++ b/drivers/sensor/f75303/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(f75303.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_F75303 f75303_emul.c) diff --git a/drivers/sensor/f75303/Kconfig b/drivers/sensor/f75303/Kconfig new file mode 100644 index 00000000000..31c3865275d --- /dev/null +++ b/drivers/sensor/f75303/Kconfig @@ -0,0 +1,22 @@ +# F75303 temperature sensor configuration options + +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config F75303 + bool "F75303 Temperature Sensor" + default y + depends on DT_HAS_FINTEK_F75303_ENABLED + select I2C + help + Enable the driver for Fintek F75303 Temperature Sensor. + This device has three temperature channels - one local (on-chip), + and two remote. + +config EMUL_F75303 + bool "Emulator for F75303" + default y + depends on F75303 + depends on EMUL + help + Enable the hardware emulator for F75303 Temperature Sensor. diff --git a/drivers/sensor/f75303/f75303.c b/drivers/sensor/f75303/f75303.c new file mode 100644 index 00000000000..dd656fc26e0 --- /dev/null +++ b/drivers/sensor/f75303/f75303.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT fintek_f75303 + +#include +#include +#include +#include +#include +#include +#include +#include "f75303.h" + +#define F75303_SAMPLE_INT_SHIFT 3 +#define F75303_SAMPLE_FRAC_MASK GENMASK(2, 0) +#define F75303_SAMPLE_MICROCELSIUS_PER_BIT 125000 + +LOG_MODULE_REGISTER(F75303, CONFIG_SENSOR_LOG_LEVEL); + +static int f75303_fetch(const struct i2c_dt_spec *i2c, + uint8_t off_h, uint8_t off_l, uint16_t *sample) +{ + uint8_t val_h; + uint8_t val_l; + int res; + + res = i2c_reg_read_byte_dt(i2c, off_h, &val_h); + if (res) { + return res; + } + + res = i2c_reg_read_byte_dt(i2c, off_l, &val_l); + if (res) { + return res; + } + + *sample = val_h << 3 | val_l >> 5; + + return 0; +} + +static int f75303_fetch_local(const struct device *dev) +{ + struct f75303_data *data = dev->data; + const struct f75303_config *config = dev->config; + + return f75303_fetch(&config->i2c, + F75303_LOCAL_TEMP_H, + F75303_LOCAL_TEMP_L, + &data->sample_local); +} + +static int f75303_fetch_remote1(const struct device *dev) +{ + struct f75303_data *data = dev->data; + const struct f75303_config *config = dev->config; + + return f75303_fetch(&config->i2c, + F75303_REMOTE1_TEMP_H, + F75303_REMOTE1_TEMP_L, + &data->sample_remote1); +} + +static int f75303_fetch_remote2(const struct device *dev) +{ + struct f75303_data *data = dev->data; + const struct f75303_config *config = dev->config; + + return f75303_fetch(&config->i2c, + F75303_REMOTE2_TEMP_H, + F75303_REMOTE2_TEMP_L, + &data->sample_remote2); +} + +static int f75303_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + enum pm_device_state pm_state; + int res; + + (void)pm_device_state_get(dev, &pm_state); + if (pm_state != PM_DEVICE_STATE_ACTIVE) { + return -EIO; + } + + switch ((uint32_t)chan) { + case SENSOR_CHAN_ALL: + res = f75303_fetch_local(dev); + if (res) { + break; + } + res = f75303_fetch_remote1(dev); + if (res) { + break; + } + res = f75303_fetch_remote2(dev); + break; + case SENSOR_CHAN_AMBIENT_TEMP: + return f75303_fetch_local(dev); + case SENSOR_CHAN_F75303_REMOTE1: + return f75303_fetch_remote1(dev); + case SENSOR_CHAN_F75303_REMOTE2: + return f75303_fetch_remote2(dev); + default: + return -ENOTSUP; + } + + return res; +} + +static int f75303_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct f75303_data *data = dev->data; + uint16_t sample; + + switch ((uint32_t)chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + sample = data->sample_local; + break; + case SENSOR_CHAN_F75303_REMOTE1: + sample = data->sample_remote1; + break; + case SENSOR_CHAN_F75303_REMOTE2: + sample = data->sample_remote2; + break; + default: + return -ENOTSUP; + } + + /* + * The reading is given in steps of 0.125 degrees celsius, i.e. the + * temperature in degrees celsius is equal to sample / 8. + */ + val->val1 = sample >> F75303_SAMPLE_INT_SHIFT; + val->val2 = (sample & F75303_SAMPLE_FRAC_MASK) * F75303_SAMPLE_MICROCELSIUS_PER_BIT; + + return 0; +} + +static const struct sensor_driver_api f75303_driver_api = { + .sample_fetch = f75303_sample_fetch, + .channel_get = f75303_channel_get, +}; + +static int f75303_init(const struct device *dev) +{ + const struct f75303_config *config = dev->config; + int res = 0; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_init_suspended(dev); + + res = pm_device_runtime_enable(dev); + if (res) { + LOG_ERR("Failed to enable runtime power management"); + } +#endif + + return res; +} + +#ifdef CONFIG_PM_DEVICE +static int f75303_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_RESUME: + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_SUSPEND: + return 0; + default: + return -ENOTSUP; + } +} +#endif + +#define F75303_INST(inst) \ + static struct f75303_data f75303_data_##inst; \ + static const struct f75303_config f75303_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, f75303_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, f75303_init, PM_DEVICE_DT_INST_GET(inst), \ + &f75303_data_##inst, &f75303_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &f75303_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(F75303_INST) diff --git a/drivers/sensor/f75303/f75303.h b/drivers/sensor/f75303/f75303.h new file mode 100644 index 00000000000..8b7ceb64748 --- /dev/null +++ b/drivers/sensor/f75303/f75303.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_F75303_F75303_H_ +#define ZEPHYR_DRIVERS_SENSOR_F75303_F75303_H_ + +#include +#include + +#define F75303_LOCAL_TEMP_H 0x00 +#define F75303_REMOTE1_TEMP_H 0x01 +#define F75303_REMOTE1_TEMP_L 0x10 +#define F75303_REMOTE2_TEMP_H 0x23 +#define F75303_REMOTE2_TEMP_L 0x24 +#define F75303_LOCAL_TEMP_L 0x29 + +struct f75303_data { + uint16_t sample_local; + uint16_t sample_remote1; + uint16_t sample_remote2; +}; + +struct f75303_config { + struct i2c_dt_spec i2c; +}; + +#endif diff --git a/drivers/sensor/f75303/f75303_emul.c b/drivers/sensor/f75303/f75303_emul.c new file mode 100644 index 00000000000..7b55e46bbab --- /dev/null +++ b/drivers/sensor/f75303/f75303_emul.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT fintek_f75303 + +#include +#include +#include +#include +#include +#include +#include +#include "f75303.h" + +LOG_MODULE_DECLARE(F75303, CONFIG_SENSOR_LOG_LEVEL); + +#define NUM_REGS 128 + +struct f75303_emul_data { + uint8_t reg[NUM_REGS]; +}; + +struct f75303_emul_cfg { +}; + +static void f75303_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val) +{ + struct f75303_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg < NUM_REGS); + data->reg[reg] = val; +} + +static uint8_t f75303_emul_get_reg(const struct emul *target, uint8_t reg) +{ + struct f75303_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg < NUM_REGS); + return data->reg[reg]; +} + +static void f75303_emul_reset(const struct emul *target) +{ + struct f75303_emul_data *data = target->data; + + memset(data->reg, 0, NUM_REGS); +} + +static int f75303_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, + int num_msgs, int addr) +{ + /* Largely copied from emul_bmi160.c */ + unsigned int val; + int reg; + + __ASSERT_NO_MSG(msgs && num_msgs); + + i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + switch (num_msgs) { + case 2: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len != 1) { + LOG_ERR("Unexpected msg0 length %d", msgs->len); + return -EIO; + } + reg = msgs->buf[0]; + + /* Now process the 'read' part of the message */ + msgs++; + if (msgs->flags & I2C_MSG_READ) { + switch (msgs->len) { + case 1: + val = f75303_emul_get_reg(target, reg); + msgs->buf[0] = val; + break; + default: + LOG_ERR("Unexpected msg1 length %d", msgs->len); + return -EIO; + } + } else { + if (msgs->len != 1) { + LOG_ERR("Unexpected msg1 length %d", msgs->len); + } + f75303_emul_set_reg(target, reg, msgs->buf[0]); + } + break; + default: + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + + return 0; +} + +static int f75303_emul_init(const struct emul *target, const struct device *parent) +{ + f75303_emul_reset(target); + return 0; +} + +static int f75303_emul_set_channel(const struct emul *target, enum sensor_channel chan, + q31_t value, int8_t shift) +{ + struct f75303_emul_data *data = target->data; + int64_t scaled_value; + int32_t millicelsius; + int32_t reg_value; + uint8_t reg_h, reg_l; + + switch ((int32_t)chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + reg_h = F75303_LOCAL_TEMP_H; + reg_l = F75303_LOCAL_TEMP_L; + break; + case SENSOR_CHAN_F75303_REMOTE1: + reg_h = F75303_REMOTE1_TEMP_H; + reg_l = F75303_REMOTE1_TEMP_L; + break; + case SENSOR_CHAN_F75303_REMOTE2: + reg_h = F75303_REMOTE2_TEMP_H; + reg_l = F75303_REMOTE2_TEMP_L; + break; + default: + return -ENOTSUP; + } + + scaled_value = (int64_t)value << shift; + millicelsius = scaled_value * 1000 / ((int64_t)INT32_MAX + 1); + reg_value = CLAMP(millicelsius / 125, 0, 0x7ff); + + data->reg[reg_h] = reg_value >> 3; + data->reg[reg_l] = (reg_value & 0x7) << 5; + + return 0; +} + +static int f75303_emul_get_sample_range(const struct emul *target, enum sensor_channel chan, + q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift) +{ + if (chan != SENSOR_CHAN_AMBIENT_TEMP && + chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE1 && + chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE2) { + return -ENOTSUP; + } + + *shift = 8; + *lower = 0; + *upper = (int64_t)(255.875 * ((int64_t)INT32_MAX + 1)) >> *shift; + *epsilon = (int64_t)(0.125 * ((int64_t)INT32_MAX + 1)) >> *shift; + + return 0; +} + +static const struct i2c_emul_api f75303_emul_api_i2c = { + .transfer = f75303_emul_transfer_i2c, +}; + +static const struct emul_sensor_backend_api f75303_emul_api_sensor = { + .set_channel = f75303_emul_set_channel, + .get_sample_range = f75303_emul_get_sample_range, +}; + + +#define F75303_EMUL(n) \ + const struct f75303_emul_cfg f75303_emul_cfg_##n; \ + struct f75303_emul_data f75303_emul_data_##n; \ + EMUL_DT_INST_DEFINE(n, f75303_emul_init, &f75303_emul_data_##n, \ + &f75303_emul_cfg_##n, &f75303_emul_api_i2c, \ + &f75303_emul_api_sensor); + +DT_INST_FOREACH_STATUS_OKAY(F75303_EMUL) diff --git a/dts/bindings/sensor/fintek,f75303.yaml b/dts/bindings/sensor/fintek,f75303.yaml new file mode 100644 index 00000000000..842aa25bd18 --- /dev/null +++ b/dts/bindings/sensor/fintek,f75303.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: | + F75303 temperature sensor IC. This device has three temperature + channels - one local (on-chip), and two remote. + +compatible: "fintek,f75303" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/include/zephyr/drivers/sensor/f75303.h b/include/zephyr/drivers/sensor/f75303.h new file mode 100644 index 00000000000..3865e8f7e72 --- /dev/null +++ b/include/zephyr/drivers/sensor/f75303.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_F75303_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_F75303_H_ + +#include + +/* F75303 specific channels */ +enum sensor_channel_f75303 { + SENSOR_CHAN_F75303_REMOTE1 = SENSOR_CHAN_PRIV_START, + SENSOR_CHAN_F75303_REMOTE2, +}; + +#endif diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index fd957bc5b9b..6beea40d494 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -740,3 +740,8 @@ test_i2c_ist8310@6f { reg = <0x6f>; status = "okay"; }; + +test_i2c_f75303: f75303@70 { + compatible = "fintek,f75303"; + reg = <0x70>; +}; From 5de9203af3695e891d68459284a4a6d2e5b6d7ae Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Fri, 4 Aug 2023 17:28:31 +0800 Subject: [PATCH 0078/4498] ITE: drivers/i2c/target: Cleanup the clear status flow of I2C target IT8XXX2_I2C_STR is a register of read-only, non-writable to clear. Here we can set hardware reset bit in the IT8XXX2_I2C_CTR register to clear the status of IT8XXX2_I2C_STR. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_enhance.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index d15b9cb0bf9..9565510e96a 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -966,10 +966,11 @@ static void target_i2c_isr(const struct device *dev) /* Any error */ if (target_status & E_TARGET_ANY_ERROR) { - /* Hardware reset */ - IT8XXX2_I2C_CTR(base) |= IT8XXX2_I2C_HALT; + goto end; + } + /* Interrupt pending */ - } else if (target_status & IT8XXX2_I2C_INT_PEND) { + if (target_status & IT8XXX2_I2C_INT_PEND) { uint8_t interrupt_status = IT8XXX2_I2C_IRQ_ST(base); /* Byte counter enable */ @@ -1021,14 +1022,13 @@ static void target_i2c_isr(const struct device *dev) if (interrupt_status & IT8XXX2_I2C_P_CLR) { /* Transfer done callback function */ target_cb->stop(data->target_cfg); - /* Hardware reset */ - IT8XXX2_I2C_CTR(base) |= IT8XXX2_I2C_HALT; } /* Write clear the peripheral status */ IT8XXX2_I2C_IRQ_ST(base) = interrupt_status; } - /* Write clear the target status */ - IT8XXX2_I2C_STR(base) = target_status; +end: + /* Hardware reset */ + IT8XXX2_I2C_CTR(base) |= IT8XXX2_I2C_HALT; } #endif From 3ae9a358fbe6d0d9144184e68885d85dc40e9531 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Wed, 2 Aug 2023 16:58:01 +0800 Subject: [PATCH 0079/4498] ITE: drivers/i2c/target: Disable the timeout setting Disable the timeout setting when both the clock and data are in a low state. This allows for I2C host clock stretching without a timeout limit. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_enhance.c | 8 +++----- soc/riscv/riscv-ite/common/chip_chipregs.h | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index 9565510e96a..81ba7fb0b28 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -1222,11 +1222,9 @@ static int i2c_enhance_target_register(const struct device *dev, /* Software reset */ IT8XXX2_I2C_DHTR(base) |= IT8XXX2_I2C_SOFT_RST; IT8XXX2_I2C_DHTR(base) &= ~IT8XXX2_I2C_SOFT_RST; - /* - * Set time out register. - * I2C D/E/F clock/data low timeout. - */ - IT8XXX2_I2C_TOR(base) = I2C_CLK_LOW_TIMEOUT; + /* Disable the timeout setting when clock/data are in a low state */ + IT8XXX2_I2C_TO_ARB_ST(base) &= ~(IT8XXX2_I2C_SCL_TIMEOUT_EN | + IT8XXX2_I2C_SDA_TIMEOUT_EN); /* Bit stretching */ IT8XXX2_I2C_TOS(base) |= IT8XXX2_I2C_CLK_STRETCH; /* Peripheral address(8-bit) */ diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h index 1fccd45853b..a3659182959 100644 --- a/soc/riscv/riscv-ite/common/chip_chipregs.h +++ b/soc/riscv/riscv-ite/common/chip_chipregs.h @@ -1347,6 +1347,9 @@ enum chip_pll_mode { /* 0x13: Nack Status */ #define IT8XXX2_I2C_NST_CNS BIT(7) #define IT8XXX2_I2C_NST_ID_NACK BIT(3) +/* 0x18: Timeout and Arbiter Status */ +#define IT8XXX2_I2C_SCL_TIMEOUT_EN BIT(7) +#define IT8XXX2_I2C_SDA_TIMEOUT_EN BIT(6) /* 0x19: Error Status */ #define IT8XXX2_I2C_ERR_ST_DEV1_EIRQ BIT(0) /* 0x1B: Finish Status */ From 8a779fc706b41aae3671c6d6ef333b9b2d2d61de Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 12 Dec 2022 15:46:25 +0800 Subject: [PATCH 0080/4498] ITE: drivers/i2c/target: Introduce I2C target transfer using PIO mode Introduce I2C target transfer using the PIO mode. Add an option "target-pio-mode" in the yaml file, determined by the DTS, to dictate whether I2C target transfer uses the PIO mode. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_enhance.c | 251 ++++++++++++++------- dts/bindings/i2c/ite,enhance-i2c.yaml | 6 + soc/riscv/riscv-ite/common/chip_chipregs.h | 2 + 3 files changed, 178 insertions(+), 81 deletions(-) diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index 81ba7fb0b28..a499c81bf0a 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -72,6 +72,7 @@ struct i2c_enhance_config { uint8_t prescale_scl_low; uint32_t clock_gate_offset; bool target_enable; + bool target_pio_mode; }; enum i2c_pin_fun { @@ -137,6 +138,7 @@ struct i2c_enhance_data { #ifdef CONFIG_I2C_TARGET struct i2c_target_config *target_cfg; uint32_t buffer_size; + int target_nack; bool target_attached; #endif union { @@ -209,6 +211,7 @@ enum i2c_reset_cause { I2C_RC_TIMEOUT, }; +#ifdef CONFIG_I2C_TARGET enum enhanced_i2c_target_status { /* Time out error */ E_TARGET_TMOE = 0x08, @@ -217,6 +220,7 @@ enum enhanced_i2c_target_status { /* Time out or lost arbitration */ E_TARGET_ANY_ERROR = (E_TARGET_TMOE | E_TARGET_ARB), }; +#endif static int i2c_parsing_return_value(const struct device *dev) { @@ -381,6 +385,8 @@ static int enhanced_i2c_error(const struct device *dev) } else if ((i2c_str & E_HOSTA_BDS_AND_ACK) == E_HOSTA_BDS) { if (IT8XXX2_I2C_CTR(base) & E_ACK) { data->err = E_HOSTA_ACK; + /* STOP */ + IT8XXX2_I2C_CTR(base) = E_FINISH; } } @@ -955,10 +961,104 @@ static int i2c_enhance_transfer(const struct device *dev, } #ifdef CONFIG_I2C_TARGET -static void target_i2c_isr(const struct device *dev) +static void target_i2c_isr_dma(const struct device *dev, + uint8_t interrupt_status) { struct i2c_enhance_data *data = dev->data; + const struct i2c_enhance_config *config = dev->config; + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; struct i2c_target_dma_buffer *target_buffer = &data->target_buffer; + uint8_t *base = config->base; + + /* Byte counter enable */ + if (interrupt_status & IT8XXX2_I2C_IDW_CLR) { + IT8XXX2_I2C_BYTE_CNT_L(base) |= + (IT8XXX2_I2C_DMA_ADDR_RELOAD | + IT8XXX2_I2C_BYTE_CNT_ENABLE); + } + /* The number of received data exceeds the byte counter setting */ + if (interrupt_status & IT8XXX2_I2C_CNT_HOLD) { + LOG_ERR("The excess data written starts " + "from the memory address:%p", + target_buffer->in_buffer + + CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE); + } + /* Controller to write data */ + if (interrupt_status & IT8XXX2_I2C_SLVDATAFLG) { + /* Number of receive data in target mode */ + data->buffer_size = + ((IT8XXX2_I2C_SLV_NUM_H(base) << 8) | + IT8XXX2_I2C_SLV_NUM_L(base)) + 1; + + /* Write data done callback function */ + target_cb->buf_write_received(data->target_cfg, + target_buffer->in_buffer, data->buffer_size); + } + /* Controller to read data */ + if (interrupt_status & IT8XXX2_I2C_IDR_CLR) { + uint32_t len; + uint8_t *rdata = NULL; + + /* Clear byte counter setting */ + IT8XXX2_I2C_BYTE_CNT_L(base) &= + ~(IT8XXX2_I2C_DMA_ADDR_RELOAD | + IT8XXX2_I2C_BYTE_CNT_ENABLE); + /* Read data callback function */ + target_cb->buf_read_requested(data->target_cfg, + &rdata, &len); + + if (len > CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE) { + LOG_ERR("The bufffer size exceeds " + "I2C_TARGET_IT8XXX2_MAX_BUF_SIZE: len=%d", + len); + } else { + memcpy(target_buffer->out_buffer, rdata, len); + } + } +} + +static int target_i2c_isr_pio(const struct device *dev, + uint8_t interrupt_status, + uint8_t target_status) +{ + struct i2c_enhance_data *data = dev->data; + const struct i2c_enhance_config *config = dev->config; + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + uint8_t *base = config->base; + uint8_t val; + + /* Target ID write flag */ + if (interrupt_status & IT8XXX2_I2C_IDW_CLR) { + ret = target_cb->write_requested(data->target_cfg); + } + /* Target ID read flag */ + else if (interrupt_status & IT8XXX2_I2C_IDR_CLR) { + if (!target_cb->read_requested(data->target_cfg, &val)) { + IT8XXX2_I2C_DTR(base) = val; + } + } + /* Byte transfer done */ + else if (target_status & IT8XXX2_I2C_BYTE_DONE) { + /* Read of write */ + if (target_status & IT8XXX2_I2C_RW) { + /* Host receiving, target transmitting */ + if (!target_cb->read_processed(data->target_cfg, &val)) { + IT8XXX2_I2C_DTR(base) = val; + } + } else { + /* Host transmitting, target receiving */ + val = IT8XXX2_I2C_DRR(base); + ret = target_cb->write_received(data->target_cfg, val); + } + } + + return ret; +} + +static void target_i2c_isr(const struct device *dev) +{ + struct i2c_enhance_data *data = dev->data; const struct i2c_enhance_config *config = dev->config; const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; uint8_t *base = config->base; @@ -973,55 +1073,27 @@ static void target_i2c_isr(const struct device *dev) if (target_status & IT8XXX2_I2C_INT_PEND) { uint8_t interrupt_status = IT8XXX2_I2C_IRQ_ST(base); - /* Byte counter enable */ - if (interrupt_status & IT8XXX2_I2C_IDW_CLR) { - IT8XXX2_I2C_BYTE_CNT_L(base) |= - (IT8XXX2_I2C_DMA_ADDR_RELOAD | - IT8XXX2_I2C_BYTE_CNT_ENABLE); - } - /* The number of received data exceeds the byte counter setting */ - if (interrupt_status & IT8XXX2_I2C_CNT_HOLD) { - LOG_ERR("The excess data written starts " - "from the memory address:%p", - target_buffer->in_buffer + - CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE); - } - /* Controller to write data */ - if (interrupt_status & IT8XXX2_I2C_SLVDATAFLG) { - /* Number of receive data in target mode */ - data->buffer_size = - ((IT8XXX2_I2C_SLV_NUM_H(base) << 8) | - IT8XXX2_I2C_SLV_NUM_L(base)) + 1; - - /* Write data done callback function */ - target_cb->buf_write_received(data->target_cfg, - target_buffer->in_buffer, data->buffer_size); - } - /* Controller to read data */ - if (interrupt_status & IT8XXX2_I2C_IDR_CLR) { - uint32_t len; - uint8_t *rdata = NULL; - - /* Clear byte counter setting */ - IT8XXX2_I2C_BYTE_CNT_L(base) &= - ~(IT8XXX2_I2C_DMA_ADDR_RELOAD | - IT8XXX2_I2C_BYTE_CNT_ENABLE); - /* Read data callback function */ - target_cb->buf_read_requested(data->target_cfg, - &rdata, &len); - - if (len > CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE) { - LOG_ERR("The bufffer size exceeds " - "I2C_TARGET_IT8XXX2_MAX_BUF_SIZE: len=%d", - len); - } else { - memcpy(target_buffer->out_buffer, rdata, len); + /* Determine whether the transaction uses PIO or DMA mode */ + if (config->target_pio_mode) { + if (target_i2c_isr_pio(dev, interrupt_status, target_status) < 0) { + /* NACK */ + IT8XXX2_I2C_CTR(base) &= ~IT8XXX2_I2C_ACK; + IT8XXX2_I2C_CTR(base) |= IT8XXX2_I2C_HALT; + data->target_nack = 1; } + } else { + target_i2c_isr_dma(dev, interrupt_status); } /* Peripheral finish */ if (interrupt_status & IT8XXX2_I2C_P_CLR) { /* Transfer done callback function */ target_cb->stop(data->target_cfg); + + if (data->target_nack) { + /* Set acknowledge */ + IT8XXX2_I2C_CTR(base) |= IT8XXX2_I2C_ACK; + data->target_nack = 0; + } } /* Write clear the peripheral status */ IT8XXX2_I2C_IRQ_ST(base) = interrupt_status; @@ -1200,8 +1272,6 @@ static int i2c_enhance_target_register(const struct device *dev, { const struct i2c_enhance_config *config = dev->config; struct i2c_enhance_data *data = dev->data; - struct i2c_target_dma_buffer *target_buffer = &data->target_buffer; - uint32_t in_data_addr, out_data_addr; uint8_t *base = config->base; if (!target_cfg) { @@ -1235,44 +1305,59 @@ static int i2c_enhance_target_register(const struct device *dev, /* Interrupt status write clear */ IT8XXX2_I2C_IRQ_ST(base) = 0xff; - /* Clear read and write data buffer of DMA */ - memset(target_buffer->in_buffer, 0, CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE); - memset(target_buffer->out_buffer, 0, CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE); + /* I2C target initial configuration of PIO mode */ + if (config->target_pio_mode) { + /* Block to enter power policy. */ + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - in_data_addr = (uint32_t)target_buffer->in_buffer & 0xffffff; - out_data_addr = (uint32_t)target_buffer->out_buffer & 0xffffff; - /* - * DMA write target address register - * for high order byte - */ - IT8XXX2_I2C_RAMH2A(base) = in_data_addr >> 16; - IT8XXX2_I2C_RAMHA(base) = in_data_addr >> 8; - IT8XXX2_I2C_RAMLA(base) = in_data_addr; - /* - * DMA read target address register - * for high order byte - */ - IT8XXX2_I2C_CMD_ADDH2(base) = out_data_addr >> 16; - IT8XXX2_I2C_RAMHA2(base) = out_data_addr >> 8; - IT8XXX2_I2C_RAMLA2(base) = out_data_addr; + /* I2C module enable */ + IT8XXX2_I2C_CTR1(base) = IT8XXX2_I2C_MDL_EN; + /* I2C target initial configuration of DMA mode */ + } else { + struct i2c_target_dma_buffer *target_buffer = &data->target_buffer; + uint32_t in_data_addr, out_data_addr; + int buf_size = CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE; - /* Byte counter setting */ - /* This register indicates byte count[10:3]. */ - IT8XXX2_I2C_BYTE_CNT_H(base) = CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE >> 3; - /* This register indicates byte count[2:0]. */ - IT8XXX2_I2C_BYTE_CNT_L(base) = CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE & - GENMASK(2, 0); + /* Clear read and write data buffer of DMA */ + memset(target_buffer->in_buffer, 0, buf_size); + memset(target_buffer->out_buffer, 0, buf_size); - /* - * The EC processor(CPU) cannot be in the k_cpu_idle() and power - * policy during the transactions with the CQ mode(DMA mode). - * Otherwise, the EC processor would be clock gated. - */ - chip_block_idle(); - pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + in_data_addr = (uint32_t)target_buffer->in_buffer & 0xffffff; + out_data_addr = (uint32_t)target_buffer->out_buffer & 0xffffff; + /* + * DMA write target address register + * for high order byte + */ + IT8XXX2_I2C_RAMH2A(base) = in_data_addr >> 16; + IT8XXX2_I2C_RAMHA(base) = in_data_addr >> 8; + IT8XXX2_I2C_RAMLA(base) = in_data_addr; + /* + * DMA read target address register + * for high order byte + */ + IT8XXX2_I2C_CMD_ADDH2(base) = out_data_addr >> 16; + IT8XXX2_I2C_RAMHA2(base) = out_data_addr >> 8; + IT8XXX2_I2C_RAMLA2(base) = out_data_addr; + + /* Byte counter setting */ + /* This register indicates byte count[10:3]. */ + IT8XXX2_I2C_BYTE_CNT_H(base) = + CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE >> 3; + /* This register indicates byte count[2:0]. */ + IT8XXX2_I2C_BYTE_CNT_L(base) = + CONFIG_I2C_TARGET_IT8XXX2_MAX_BUF_SIZE & GENMASK(2, 0); + + /* + * The EC processor(CPU) cannot be in the k_cpu_idle() and power + * policy during the transactions with the CQ mode(DMA mode). + * Otherwise, the EC processor would be clock gated. + */ + chip_block_idle(); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - /* I2C module enable and command queue mode */ - IT8XXX2_I2C_CTR1(base) = IT8XXX2_I2C_COMQ_EN | IT8XXX2_I2C_MDL_EN; + /* I2C module enable and command queue mode */ + IT8XXX2_I2C_CTR1(base) = IT8XXX2_I2C_COMQ_EN | IT8XXX2_I2C_MDL_EN; + } ite_intc_isr_clear(config->i2c_irq_base); irq_enable(config->i2c_irq_base); @@ -1294,10 +1379,13 @@ static int i2c_enhance_target_unregister(const struct device *dev, /* Permit to enter power policy and idle mode. */ pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - chip_permit_idle(); + if (!config->target_pio_mode) { + chip_permit_idle(); + } data->target_cfg = NULL; data->target_attached = false; + data->target_nack = 0; return 0; } @@ -1343,6 +1431,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_I2C_TARGET_BUFFER_MODE), .clock_gate_offset = DT_INST_PROP(inst, clock_gate_offset), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .target_enable = DT_INST_PROP(inst, target_enable), \ + .target_pio_mode = DT_INST_PROP(inst, target_pio_mode), \ }; \ \ static struct i2c_enhance_data i2c_enhance_data_##inst; \ diff --git a/dts/bindings/i2c/ite,enhance-i2c.yaml b/dts/bindings/i2c/ite,enhance-i2c.yaml index 98e3e4ec46b..446f3f09aea 100644 --- a/dts/bindings/i2c/ite,enhance-i2c.yaml +++ b/dts/bindings/i2c/ite,enhance-i2c.yaml @@ -24,3 +24,9 @@ properties: This option is used when the I2C target is enabled. It is necessary to prevent the target port from being configured with I2C host related initialization. + + target-pio-mode: + type: boolean + description: | + This option is used when the I2C target is enabled and it can + support PIO mode for I2C target transfer. diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h index a3659182959..17e1fa11b7a 100644 --- a/soc/riscv/riscv-ite/common/chip_chipregs.h +++ b/soc/riscv/riscv-ite/common/chip_chipregs.h @@ -1321,6 +1321,8 @@ enum chip_pll_mode { /* 0x55: Slave A FIFO Control */ #define IT8XXX2_SMB_HSAPE BIT(1) /* 0x03: Status Register */ +#define IT8XXX2_I2C_BYTE_DONE BIT(7) +#define IT8XXX2_I2C_RW BIT(2) #define IT8XXX2_I2C_INT_PEND BIT(1) /* 0x04: Data Hold Time */ #define IT8XXX2_I2C_SOFT_RST BIT(7) From 32a9d13d61eec18cb91209b63552cf597f89d9ec Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 30 Aug 2023 14:09:14 -0600 Subject: [PATCH 0081/4498] samples: tfm: Update tag to run tests on module change A recent change #61718, adds support to the twister build to check for manifest changes, and run tests using tags based on the modules that have changed. The tfm tests have an existing tag `tfm` to select these tests, but the above patch uses a tag named after the module, trusted-firmware-m. To make this work, add `trusted-firmware-m` in addition to the existing tag `tfm` so that these tests will run whenever the tfm module is updated. Signed-off-by: David Brown --- samples/tfm_integration/psa_crypto/sample.yaml | 7 ++++++- samples/tfm_integration/psa_protected_storage/sample.yaml | 4 +++- samples/tfm_integration/tfm_ipc/sample.yaml | 2 ++ samples/tfm_integration/tfm_psa_test/sample.yaml | 4 +++- samples/tfm_integration/tfm_regression_test/sample.yaml | 4 +++- samples/tfm_integration/tfm_secure_partition/sample.yaml | 8 ++++++-- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/samples/tfm_integration/psa_crypto/sample.yaml b/samples/tfm_integration/psa_crypto/sample.yaml index d76eb6a2378..c78e2068265 100644 --- a/samples/tfm_integration/psa_crypto/sample.yaml +++ b/samples/tfm_integration/psa_crypto/sample.yaml @@ -5,7 +5,12 @@ sample: name: PSA crypto example tests: sample.psa_crypto: - tags: introduction tfm crypto csr + tags: + - introduction + - tfm + - trusted-firmware-m + - crypto + - csr platform_allow: mps2_an521_ns v2m_musca_s1_ns nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns stm32l562e_dk_ns bl5340_dvk_cpuapp_ns diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index 444f75c2a78..b4321ed28b6 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -28,4 +28,6 @@ common: tests: sample.tfm.protected_storage: - tags: tfm + tags: + - tfm + - trusted-firmware-m diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index 968ad517ebd..00d05c8bf68 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -7,6 +7,7 @@ tests: tags: - introduction - tfm + - trusted-firmware-m platform_allow: - mps2_an521_ns - nrf5340dk_nrf5340_cpuapp_ns @@ -30,6 +31,7 @@ tests: tags: - introduction - tfm + - trusted-firmware-m platform_allow: mps2_an521_ns extra_configs: - CONFIG_TFM_BL2=n diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index 43c8c45c735..b39441ac199 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -1,5 +1,7 @@ common: - tags: tfm + tags: + - tfm + - trusted-firmware-m platform_allow: - mps2_an521_ns - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index c9ebbcf67ec..4a67ad00f6f 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -1,5 +1,7 @@ common: - tags: tfm + tags: + - tfm + - trusted-firmware-m platform_allow: - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/tfm_integration/tfm_secure_partition/sample.yaml b/samples/tfm_integration/tfm_secure_partition/sample.yaml index 5c9a1a94f5e..331162dd94d 100644 --- a/samples/tfm_integration/tfm_secure_partition/sample.yaml +++ b/samples/tfm_integration/tfm_secure_partition/sample.yaml @@ -1,5 +1,7 @@ common: - tags: tfm + tags: + - tfm + - trusted-firmware-m platform_allow: - mps2_an521_ns - v2m_musca_s1_ns @@ -22,4 +24,6 @@ sample: tests: sample.tfm.secure_partition: - tags: tfm + tags: + - tfm + - trusted-firmware-m From a5e70cd40d23281bbf913549de75058d8d58bcb9 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 30 Aug 2023 14:15:53 -0600 Subject: [PATCH 0082/4498] samples: tfm: Also test tfm when mcuboot changes In addition to running the tfm tests when the trusted-firmware-m module changes, most of the tests also use MCUboot, which comes from our module. Add the mcuboot tag to each of these tests, except for the single test that explicitly builds without using MCUboot. Signed-off-by: David Brown --- samples/tfm_integration/psa_crypto/sample.yaml | 1 + samples/tfm_integration/psa_protected_storage/sample.yaml | 1 + samples/tfm_integration/tfm_ipc/sample.yaml | 1 + samples/tfm_integration/tfm_psa_test/sample.yaml | 1 + samples/tfm_integration/tfm_regression_test/sample.yaml | 1 + samples/tfm_integration/tfm_secure_partition/sample.yaml | 1 + 6 files changed, 6 insertions(+) diff --git a/samples/tfm_integration/psa_crypto/sample.yaml b/samples/tfm_integration/psa_crypto/sample.yaml index c78e2068265..fb2dd5f37f5 100644 --- a/samples/tfm_integration/psa_crypto/sample.yaml +++ b/samples/tfm_integration/psa_crypto/sample.yaml @@ -11,6 +11,7 @@ tests: - trusted-firmware-m - crypto - csr + - mcuboot platform_allow: mps2_an521_ns v2m_musca_s1_ns nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns stm32l562e_dk_ns bl5340_dvk_cpuapp_ns diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index b4321ed28b6..a55f60da404 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -31,3 +31,4 @@ tests: tags: - tfm - trusted-firmware-m + - mcuboot diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index 00d05c8bf68..664618aa6e2 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -8,6 +8,7 @@ tests: - introduction - tfm - trusted-firmware-m + - mcuboot platform_allow: - mps2_an521_ns - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index b39441ac199..d41a567d12d 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -2,6 +2,7 @@ common: tags: - tfm - trusted-firmware-m + - mcuboot platform_allow: - mps2_an521_ns - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index 4a67ad00f6f..8d5412b812c 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -2,6 +2,7 @@ common: tags: - tfm - trusted-firmware-m + - mcuboot platform_allow: - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/tfm_integration/tfm_secure_partition/sample.yaml b/samples/tfm_integration/tfm_secure_partition/sample.yaml index 331162dd94d..31652b12efc 100644 --- a/samples/tfm_integration/tfm_secure_partition/sample.yaml +++ b/samples/tfm_integration/tfm_secure_partition/sample.yaml @@ -27,3 +27,4 @@ tests: tags: - tfm - trusted-firmware-m + - mcuboot From 7c80473e0a06851f826f4018af348d04ae57e401 Mon Sep 17 00:00:00 2001 From: David Brown Date: Tue, 5 Sep 2023 10:56:36 -0600 Subject: [PATCH 0083/4498] samples: tfm: Remove old 'tfm' tag To avoid confusion having both a 'tfm' and a 'trusted-firmware-m' tag, remove the old 'tfm' tag entirely. Any external test frameworks that are using the 'tfm' tag will need to be changed to account for this. Signed-off-by: David Brown --- samples/tfm_integration/psa_crypto/sample.yaml | 1 - samples/tfm_integration/psa_protected_storage/sample.yaml | 1 - samples/tfm_integration/tfm_ipc/sample.yaml | 2 -- samples/tfm_integration/tfm_psa_test/sample.yaml | 1 - samples/tfm_integration/tfm_regression_test/sample.yaml | 1 - samples/tfm_integration/tfm_secure_partition/sample.yaml | 2 -- 6 files changed, 8 deletions(-) diff --git a/samples/tfm_integration/psa_crypto/sample.yaml b/samples/tfm_integration/psa_crypto/sample.yaml index fb2dd5f37f5..45c9940b021 100644 --- a/samples/tfm_integration/psa_crypto/sample.yaml +++ b/samples/tfm_integration/psa_crypto/sample.yaml @@ -7,7 +7,6 @@ tests: sample.psa_crypto: tags: - introduction - - tfm - trusted-firmware-m - crypto - csr diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index a55f60da404..83ddde86758 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -29,6 +29,5 @@ common: tests: sample.tfm.protected_storage: tags: - - tfm - trusted-firmware-m - mcuboot diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index 664618aa6e2..4537b5c48dc 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -6,7 +6,6 @@ tests: sample.tfm_ipc: tags: - introduction - - tfm - trusted-firmware-m - mcuboot platform_allow: @@ -31,7 +30,6 @@ tests: sample.tfm_ipc.no_bl2: tags: - introduction - - tfm - trusted-firmware-m platform_allow: mps2_an521_ns extra_configs: diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index d41a567d12d..6eea76dc157 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -1,6 +1,5 @@ common: tags: - - tfm - trusted-firmware-m - mcuboot platform_allow: diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index 8d5412b812c..12e0810fb96 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -1,6 +1,5 @@ common: tags: - - tfm - trusted-firmware-m - mcuboot platform_allow: diff --git a/samples/tfm_integration/tfm_secure_partition/sample.yaml b/samples/tfm_integration/tfm_secure_partition/sample.yaml index 31652b12efc..06cb3bc2e96 100644 --- a/samples/tfm_integration/tfm_secure_partition/sample.yaml +++ b/samples/tfm_integration/tfm_secure_partition/sample.yaml @@ -1,6 +1,5 @@ common: tags: - - tfm - trusted-firmware-m platform_allow: - mps2_an521_ns @@ -25,6 +24,5 @@ sample: tests: sample.tfm.secure_partition: tags: - - tfm - trusted-firmware-m - mcuboot From f13791d5baf2edb6263f7a484b4faa77df1e2997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 30 Aug 2023 16:14:19 +0200 Subject: [PATCH 0084/4498] canbus: isotp: use flags for configuration in isotp_msg_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous design with dedicated bits in the structure required a user to explicitly set each bit. Using one flags variable allows to extend the features more easily in the future and avoids breaking existing code. This change is particularly useful for the FDF and BRS flags required for CAN-FD support. See also previous similar change for the CAN driver in f8a88cdb2791fe40b3021f1275fe250c2c17dcf3 Signed-off-by: Martin Jäger --- include/zephyr/canbus/isotp.h | 29 ++++++++++++---- samples/subsys/canbus/isotp/src/main.c | 8 ----- subsys/canbus/isotp/isotp.c | 34 ++++++++++--------- .../canbus/isotp/conformance/src/main.c | 23 ++++--------- .../canbus/isotp/implementation/src/main.c | 5 +-- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/include/zephyr/canbus/isotp.h b/include/zephyr/canbus/isotp.h index 6ce32c48edb..b975837915f 100644 --- a/include/zephyr/canbus/isotp.h +++ b/include/zephyr/canbus/isotp.h @@ -128,6 +128,27 @@ extern "C" { #endif +/** + * @name ISO-TP message ID flags + * @anchor ISOTP_MSG_FLAGS + * + * @{ + */ + +/** Message uses ISO-TP extended addressing (first payload byte of CAN frame) */ +#define ISOTP_MSG_EXT_ADDR BIT(0) + +/** + * Message uses ISO-TP fixed addressing (according to SAE J1939). Only valid in combination with + * ``ISOTP_MSG_IDE``. + */ +#define ISOTP_MSG_FIXED_ADDR BIT(1) + +/** Message uses extended (29-bit) CAN ID */ +#define ISOTP_MSG_IDE BIT(2) + +/** @} */ + /** * @brief ISO-TP message id struct * @@ -146,12 +167,8 @@ struct isotp_msg_id { }; /** ISO-TP extended address (if used) */ uint8_t ext_addr; - /** Indicates the CAN identifier type (0 for standard or 1 for extended) */ - uint8_t ide : 1; - /** Indicates if ISO-TP extended addressing is used */ - uint8_t use_ext_addr : 1; - /** Indicates if ISO-TP fixed addressing (acc. to SAE J1939) is used */ - uint8_t use_fixed_addr : 1; + /** Flags. @see @ref ISOTP_MSG_FLAGS. */ + uint8_t flags; }; /* diff --git a/samples/subsys/canbus/isotp/src/main.c b/samples/subsys/canbus/isotp/src/main.c index 8fbd43e28ac..0a37654fd3d 100644 --- a/samples/subsys/canbus/isotp/src/main.c +++ b/samples/subsys/canbus/isotp/src/main.c @@ -12,23 +12,15 @@ const struct isotp_fc_opts fc_opts_0_5 = {.bs = 0, .stmin = 5}; const struct isotp_msg_id rx_addr_8_0 = { .std_id = 0x80, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id tx_addr_8_0 = { .std_id = 0x180, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id rx_addr_0_5 = { .std_id = 0x01, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id tx_addr_0_5 = { .std_id = 0x101, - .ide = 0, - .use_ext_addr = 0 }; const struct device *can_dev; diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 85b28ebe1f7..4a55deb76db 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -118,7 +118,7 @@ static inline uint32_t receive_get_sf_length(struct net_buf *buf) static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) { struct can_frame frame = { - .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0, + .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, .id = ctx->tx_addr.ext_id }; uint8_t *data = frame.data; @@ -127,7 +127,7 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) __ASSERT_NO_MSG(!(fs & ISOTP_PCI_TYPE_MASK)); - if (ctx->tx_addr.use_ext_addr) { + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { *data++ = ctx->tx_addr.ext_addr; } @@ -374,13 +374,13 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) uint8_t payload_len; uint32_t rx_sa; /* ISO-TP fixed source address (if used) */ - if (ctx->rx_addr.use_ext_addr) { + if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { if (frame->data[index++] != ctx->rx_addr.ext_addr) { return; } } - if (ctx->rx_addr.use_fixed_addr) { + if ((ctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { /* store actual CAN ID used by the sender */ ctx->rx_addr.ext_id = frame->id; /* replace TX target address with RX source address */ @@ -465,7 +465,7 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) int index = 0; uint32_t data_len; - if (ctx->rx_addr.use_ext_addr) { + if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { if (frame->data[index++] != ctx->rx_addr.ext_addr) { return; } @@ -557,14 +557,15 @@ static inline int attach_ff_filter(struct isotp_recv_ctx *ctx) { uint32_t mask; - if (ctx->rx_addr.use_fixed_addr) { + if ((ctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { mask = ISOTP_FIXED_ADDR_RX_MASK; } else { mask = CAN_EXT_ID_MASK; } struct can_filter filter = { - .flags = CAN_FILTER_DATA | ((ctx->rx_addr.ide != 0) ? CAN_FILTER_IDE : 0), + .flags = CAN_FILTER_DATA | + ((ctx->rx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0), .id = ctx->rx_addr.ext_id, .mask = mask }; @@ -755,7 +756,7 @@ static void send_process_fc(struct isotp_send_ctx *ctx, { uint8_t *data = frame->data; - if (ctx->rx_addr.use_ext_addr) { + if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { if (ctx->rx_addr.ext_addr != *data++) { return; } @@ -854,7 +855,7 @@ static void pull_data_ctx(struct isotp_send_ctx *ctx, size_t len) static inline int send_sf(struct isotp_send_ctx *ctx) { struct can_frame frame = { - .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0, + .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, .id = ctx->tx_addr.ext_id }; size_t len = get_ctx_data_length(ctx); @@ -865,7 +866,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx) data = get_data_ctx(ctx); pull_data_ctx(ctx, len); - if (ctx->tx_addr.use_ext_addr) { + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { frame.data[index++] = ctx->tx_addr.ext_addr; } @@ -895,7 +896,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx) static inline int send_ff(struct isotp_send_ctx *ctx) { struct can_frame frame = { - .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0, + .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, .id = ctx->tx_addr.ext_id, .dlc = ISOTP_CAN_DL }; @@ -904,7 +905,7 @@ static inline int send_ff(struct isotp_send_ctx *ctx) int ret; const uint8_t *data; - if (ctx->tx_addr.use_ext_addr) { + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { frame.data[index++] = ctx->tx_addr.ext_addr; } @@ -936,7 +937,7 @@ static inline int send_ff(struct isotp_send_ctx *ctx) static inline int send_cf(struct isotp_send_ctx *ctx) { struct can_frame frame = { - .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0, + .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, .id = ctx->tx_addr.ext_id, }; int index = 0; @@ -945,7 +946,7 @@ static inline int send_cf(struct isotp_send_ctx *ctx) int rem_len; const uint8_t *data; - if (ctx->tx_addr.use_ext_addr) { + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { frame.data[index++] = ctx->tx_addr.ext_addr; } @@ -1116,7 +1117,8 @@ static void send_work_handler(struct k_work *item) static inline int attach_fc_filter(struct isotp_send_ctx *ctx) { struct can_filter filter = { - .flags = CAN_FILTER_DATA | ((ctx->rx_addr.ide != 0) ? CAN_FILTER_IDE : 0), + .flags = CAN_FILTER_DATA | + ((ctx->rx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0), .id = ctx->rx_addr.ext_id, .mask = CAN_EXT_ID_MASK }; @@ -1164,7 +1166,7 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, len = get_ctx_data_length(ctx); LOG_DBG("Send %zu bytes to addr 0x%x and listen on 0x%x", len, ctx->tx_addr.ext_id, ctx->rx_addr.ext_id); - if (len > ISOTP_CAN_DL - (tx_addr->use_ext_addr ? 2 : 1)) { + if (len > ISOTP_CAN_DL - ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0 ? 2 : 1)) { ret = attach_fc_filter(ctx); if (ret) { LOG_ERR("Can't attach fc filter: %d", ret); diff --git a/tests/subsys/canbus/isotp/conformance/src/main.c b/tests/subsys/canbus/isotp/conformance/src/main.c index 0993ef52d7d..ea55fbb7c52 100644 --- a/tests/subsys/canbus/isotp/conformance/src/main.c +++ b/tests/subsys/canbus/isotp/conformance/src/main.c @@ -72,43 +72,34 @@ const struct isotp_fc_opts fc_opts_single = { .bs = 0, .stmin = 0 }; + const struct isotp_msg_id rx_addr = { .std_id = 0x10, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id tx_addr = { .std_id = 0x11, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id rx_addr_ext = { .std_id = 0x10, - .ide = 0, - .use_ext_addr = 1, - .ext_addr = EXT_ADDR + .ext_addr = EXT_ADDR, + .flags = ISOTP_MSG_EXT_ADDR, }; const struct isotp_msg_id tx_addr_ext = { .std_id = 0x11, - .ide = 0, - .use_ext_addr = 1, - .ext_addr = EXT_ADDR + .ext_addr = EXT_ADDR, + .flags = ISOTP_MSG_EXT_ADDR, }; const struct isotp_msg_id rx_addr_fixed = { .ext_id = 0x18DA0201, - .ide = 1, - .use_ext_addr = 0, - .use_fixed_addr = 1 + .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE, }; const struct isotp_msg_id tx_addr_fixed = { .ext_id = 0x18DA0102, - .ide = 1, - .use_ext_addr = 0, - .use_fixed_addr = 1 + .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE, }; const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); diff --git a/tests/subsys/canbus/isotp/implementation/src/main.c b/tests/subsys/canbus/isotp/implementation/src/main.c index 1c597f64ec7..bbc2cadb6ce 100644 --- a/tests/subsys/canbus/isotp/implementation/src/main.c +++ b/tests/subsys/canbus/isotp/implementation/src/main.c @@ -35,15 +35,12 @@ const struct isotp_fc_opts fc_opts_single = { .bs = 0, .stmin = 1 }; + const struct isotp_msg_id rx_addr = { .std_id = 0x10, - .ide = 0, - .use_ext_addr = 0 }; const struct isotp_msg_id tx_addr = { .std_id = 0x11, - .ide = 0, - .use_ext_addr = 0 }; struct isotp_recv_ctx recv_ctx; From 111db23d0a0d22730b54ef270bfc8c2d5a811313 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 5 Sep 2023 16:50:57 +0200 Subject: [PATCH 0085/4498] net: mgmt: Fix memory corruption in wait_on_iface The net_mgmt subsystem offers a function which waits (blocks) until a specified net event occurs. An event callback is pushed to the stack, then added to the net_mgmt_event_callback list. If the event occurs, the net_mgmt thread calls the callback and deletes the callback from the list. However, if the event does not occur within the timeout specified when invoking mgmt_event_wait_call() the function will return, corrupting the callback structure the stack is reused. This PR fixes the issue by deleting the callback before exiting in case the event does not occur. Signed-off-by: Bjarki Arge Andreasen --- subsys/net/ip/net_mgmt.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/subsys/net/ip/net_mgmt.c b/subsys/net/ip/net_mgmt.c index 94dac5ef6ef..4ae67a8aeda 100644 --- a/subsys/net/ip/net_mgmt.c +++ b/subsys/net/ip/net_mgmt.c @@ -236,29 +236,32 @@ static int mgmt_event_wait_call(struct net_if *iface, net_mgmt_add_event_callback(&sync); ret = k_sem_take(sync.sync_call, timeout); - if (ret == -EAGAIN) { - ret = -ETIMEDOUT; - } else { - if (!ret) { - if (raised_event) { - *raised_event = sync.raised_event; - } + if (ret < 0) { + if (ret == -EAGAIN) { + ret = -ETIMEDOUT; + } - if (event_iface) { - *event_iface = sync_data.iface; - } + net_mgmt_del_event_callback(&sync); + return ret; + } + + if (raised_event) { + *raised_event = sync.raised_event; + } + + if (event_iface) { + *event_iface = sync_data.iface; + } #ifdef CONFIG_NET_MGMT_EVENT_INFO - if (info) { - *info = sync.info; + if (info) { + *info = sync.info; - if (info_length) { - *info_length = sync.info_length; - } - } -#endif /* CONFIG_NET_MGMT_EVENT_INFO */ + if (info_length) { + *info_length = sync.info_length; } } +#endif /* CONFIG_NET_MGMT_EVENT_INFO */ return ret; } From fb003d1aa80cac2db7ae87c83f862760f5c8e895 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 6 Sep 2023 10:39:02 +0000 Subject: [PATCH 0086/4498] scripts: check_init_priorities: add priority to the file debug print Log the device priority on the file debug output print, this is convenient to list out all the defined devices and their priority, even if they don't depend on each other. Signed-off-by: Fabio Baltieri --- scripts/build/check_init_priorities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 4036d8984b5..8e743fa5323 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -205,9 +205,9 @@ def __init__(self, build_dir, edt_pickle_path, log): obj = ZephyrObjectFile(file) if obj.defined_devices: self._objs.append(obj) - for dev in obj.defined_devices: + for dev, prio in obj.defined_devices.items(): dev_path = self._ord2node[dev].path - self.log.debug(f"{file}: {dev_path}") + self.log.debug(f"{file}: {dev_path} {prio}") self._dev_priorities = {} for obj in self._objs: From 16870cd664463006b02ec8abace312b2fdc776db Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 1 Sep 2023 09:23:05 +0200 Subject: [PATCH 0087/4498] tests: net: tcp: Add test case for SYN/RST+ACK scenario Add TCP test case which verifies that if RST+ACK packet is received during TCP handshake, the connection is brought down and net_context_connect() fails. Signed-off-by: Robert Lubos --- tests/net/tcp/src/main.c | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tests/net/tcp/src/main.c b/tests/net/tcp/src/main.c index e076f0d8a47..d30aa8b9bd1 100644 --- a/tests/net/tcp/src/main.c +++ b/tests/net/tcp/src/main.c @@ -124,6 +124,7 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt); static void handle_client_test(sa_family_t af, struct tcphdr *th); static void handle_server_test(sa_family_t af, struct tcphdr *th); static void handle_syn_resend(void); +static void handle_syn_rst_ack(sa_family_t af, struct tcphdr *th); static void handle_client_fin_wait_2_test(sa_family_t af, struct tcphdr *th); static void handle_client_closing_test(sa_family_t af, struct tcphdr *th); static void handle_data_fin1_test(sa_family_t af, struct tcphdr *th); @@ -333,6 +334,13 @@ static struct net_pkt *prepare_syn_ack_packet(sa_family_t af, uint16_t src_port, NULL, 0U); } +static struct net_pkt *prepare_rst_ack_packet(sa_family_t af, uint16_t src_port, + uint16_t dst_port) +{ + return tester_prepare_tcp_pkt(af, src_port, dst_port, RST | ACK, + NULL, 0U); +} + static struct net_pkt *prepare_ack_packet(sa_family_t af, uint16_t src_port, uint16_t dst_port) { @@ -430,6 +438,9 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt) case 11: handle_data_during_fin1_test(net_pkt_family(pkt), &th); break; + case 12: + handle_syn_rst_ack(net_pkt_family(pkt), &th); + break; default: zassert_true(false, "Undefined test case"); } @@ -1003,6 +1014,68 @@ ZTEST(net_tcp, test_client_syn_resend) net_context_put(ctx); } +static void handle_syn_rst_ack(sa_family_t af, struct tcphdr *th) +{ + struct net_pkt *reply; + int ret; + + switch (t_state) { + case T_SYN: + test_verify_flags(th, SYN); + seq = 0U; + ack = ntohl(th->th_seq) + 1U; + reply = prepare_rst_ack_packet(af, htons(MY_PORT), + th->th_sport); + t_state = T_CLOSING; + break; + default: + return; + } + + ret = net_recv_data(net_iface, reply); + if (ret < 0) { + goto fail; + } + + return; +fail: + zassert_true(false, "%s failed", __func__); +} + +/* Test case scenario IPv4 + * send SYN, + * peer replies RST+ACK, + * net_context_connect should report an error + */ +ZTEST(net_tcp, test_client_syn_rst_ack) +{ + struct net_context *ctx; + int ret; + + t_state = T_SYN; + test_case_no = 12; + seq = ack = 0; + + ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ctx); + if (ret < 0) { + zassert_true(false, "Failed to get net_context"); + } + + net_context_ref(ctx); + + ret = net_context_connect(ctx, (struct sockaddr *)&peer_addr_s, + sizeof(struct sockaddr_in), + NULL, + K_MSEC(1000), NULL); + + zassert_true(ret < 0, "Connect successful on RST+ACK"); + zassert_not_equal(net_context_get_state(ctx), NET_CONTEXT_CONNECTED, + "Context should not be connected"); + + net_context_put(ctx); +} + + static void handle_client_fin_wait_2_test(sa_family_t af, struct tcphdr *th) { struct net_pkt *reply; From 370096e4f5b3dc9c9565b0d9322e94c58803a9d3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 1 Sep 2023 09:25:27 +0200 Subject: [PATCH 0088/4498] net: tcp: Fix goto condition in case of RST/packet error In case RST packet is received or malformed packet is received, the TCP should not proceed with the state machine execution (which may process the invalid packet) but rather jump directly to exit, where the connection will be closed. Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index c90f7b92c20..ad9cd1e4c98 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2276,7 +2276,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto next_state; + goto out; } if (FL(&fl, &, RST)) { @@ -2292,7 +2292,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) net_stats_update_tcp_seg_rst(net_pkt_iface(pkt)); do_close = true; close_status = -ECONNRESET; - goto next_state; + goto out; } if (tcp_options_len && !tcp_options_check(&conn->recv_options, pkt, @@ -2301,7 +2301,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto next_state; + goto out; } if (th && (conn->state != TCP_LISTEN) && (conn->state != TCP_SYN_SENT) && @@ -2316,7 +2316,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto next_state; + goto out; } if (th) { @@ -2904,6 +2904,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_state_to_str(conn->state, true)); } +out: if (pkt) { if (verdict == NET_OK) { net_pkt_unref(pkt); From 811b0bd8fb5d4ce5cc9f663c4dfabdd8285c3adc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 7 Sep 2023 11:21:29 +0200 Subject: [PATCH 0089/4498] samples: tfm: Fix test definition 32a9d13d61eec18cb91209b63552cf597f89d9ec introduced a new required tag for this test which the integration platform does not "support" causing the testplan generation to error out. Fix it by removing the offending tag from the test. Signed-off-by: Alberto Escolar Piedras --- samples/tfm_integration/psa_protected_storage/sample.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index 83ddde86758..26f16f76100 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -29,5 +29,4 @@ common: tests: sample.tfm.protected_storage: tags: - - trusted-firmware-m - mcuboot From c15ec57e6e7fb64922e5f9aa3e1bc14457e90233 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Thu, 7 Sep 2023 12:05:59 +0200 Subject: [PATCH 0090/4498] Revert "samples: tfm: Fix test definition" This reverts commit 811b0bd8fb5d4ce5cc9f663c4dfabdd8285c3adc. Signed-off-by: Maciej Perkowski --- samples/tfm_integration/psa_protected_storage/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index 26f16f76100..83ddde86758 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -29,4 +29,5 @@ common: tests: sample.tfm.protected_storage: tags: + - trusted-firmware-m - mcuboot From 97a77438113fca119680c7c719a006751f5059c9 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Thu, 7 Sep 2023 12:07:55 +0200 Subject: [PATCH 0091/4498] boards: Allow mps2_an521_ns to execute tfm tests Allow mps2_an521_ns to execute tests with trusted-firmware-m tag. Resolve an error when this platform is selected as an integration platform in tests marked with the given tag. Fixes: #62380 Signed-off-by: Maciej Perkowski --- boards/arm/mps2_an521/mps2_an521_ns.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/mps2_an521/mps2_an521_ns.yaml b/boards/arm/mps2_an521/mps2_an521_ns.yaml index 08388be71f2..bf8d5edc243 100644 --- a/boards/arm/mps2_an521/mps2_an521_ns.yaml +++ b/boards/arm/mps2_an521/mps2_an521_ns.yaml @@ -16,3 +16,4 @@ testing: - kernel - tfm - userspace + - trusted-firmware-m From 02afefe34aa1f347b9206e0f6edd674cdbaedf59 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 09:59:56 +0000 Subject: [PATCH 0092/4498] sensor: f75303: fix i2c_dump_msgs_rw argument i2c_dump_msgs_rw argument should be the device pointer. Signed-off-by: Fabio Baltieri --- drivers/sensor/f75303/f75303_emul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/f75303/f75303_emul.c b/drivers/sensor/f75303/f75303_emul.c index 7b55e46bbab..3e33a7b6f7b 100644 --- a/drivers/sensor/f75303/f75303_emul.c +++ b/drivers/sensor/f75303/f75303_emul.c @@ -57,7 +57,7 @@ static int f75303_emul_transfer_i2c(const struct emul *target, struct i2c_msg *m __ASSERT_NO_MSG(msgs && num_msgs); - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 2: if (msgs->flags & I2C_MSG_READ) { From 79ab982f468096f6c06776a93fe154ca35d33f8f Mon Sep 17 00:00:00 2001 From: Morten Priess Date: Thu, 29 Jun 2023 09:16:26 +0200 Subject: [PATCH 0093/4498] Bluetooth: controller: Introduce config for avoiding SDU fragmentation The CIS Central uses the algorithm described in BT Core 5.4 Vol 6, Part G, Section 2.2 to calculate the Max_PDU value for framed mode. However, HAP needs the Max_PDU to be calculated according to "Core enhancement for ISOAL CR" coming with the "Atlanta" update. With this update, the fragmentation is controlled via a parameter at CIG creation. Enabling CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION will set the ISO_Interval to 7.5 ms for a 10 ms framed CIG, and calculate Max_PDU to 45/65 for 16/24 kHz. Signed-off-by: Morten Priess --- subsys/bluetooth/controller/Kconfig | 11 ++++ .../controller/ll_sw/ull_central_iso.c | 59 ++++++++++++++----- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 404d89cbf06..cfa265f595b 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -902,6 +902,17 @@ config BT_CTLR_CONN_ISO_STREAMS_MAX_FT help Maximum number of CIS flush timeout events. +config BT_CTLR_CONN_ISO_AVOID_SEGMENTATION + bool "Avoid SDU fragmentation for framed mode" + depends on BT_CTLR_CENTRAL_ISO + help + When creating a CIG, the Max_PDU size is calculated according to BT + Core 5.4 Vol 6, Part G, Section 2.2. However, HAP specifies a need for + avoiding segmentation by forcing the Max_PDU to the appropriate value. + Since there is no way to control the Max_PDU using the non-test + interface, the config provides a way to force the Max_PDU to Max_SDU + + 5 (header + offset). + config BT_CTLR_ISO bool default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 0c7a8e5ef35..49ab4909e3e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -234,6 +234,15 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) cig->iso_interval = BT_HCI_ISO_INTERVAL_MIN; } +#if defined(CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION) + /* Check if this is a HAP usecase which requires higher link bandwidth to ensure + * segmentation is not invoked in ISO-AL. + */ + if (cig->central.framing && cig->c_sdu_interval == 10000U) { + cig->iso_interval = 6; /* 7500 us */ + } +#endif + if (!cig->central.framing && (cig->c_sdu_interval % ISO_INT_UNIT_US)) { /* Framing not requested but requirement for unframed is not met. Force * CIG into framed mode. @@ -1131,29 +1140,51 @@ static void set_bn_max_pdu(bool framed, uint32_t iso_interval, uint8_t *max_pdu) { if (framed) { - uint32_t ceil_f_x_max_sdu; - uint16_t max_pdu_bn1; - uint32_t max_drift; + uint32_t max_drift_us; uint32_t ceil_f; - /* Framed (From ES-18002): + /* BT Core 5.4 Vol 6, Part G, Section 2.2: * Max_PDU >= ((ceil(F) x 5 + ceil(F x Max_SDU)) / BN) + 2 * F = (1 + MaxDrift) x ISO_Interval / SDU_Interval * SegmentationHeader + TimeOffset = 5 bytes * Continuation header = 2 bytes * MaxDrift (Max. allowed SDU delivery timing drift) = 100 ppm */ - max_drift = DIV_ROUND_UP(SDU_MAX_DRIFT_PPM * sdu_interval, 1000000U); - ceil_f = DIV_ROUND_UP(iso_interval + max_drift, sdu_interval); - ceil_f_x_max_sdu = DIV_ROUND_UP(max_sdu * (iso_interval + max_drift), - sdu_interval); - - /* Strategy: Keep lowest possible BN. - * TODO: Implement other strategies, possibly as policies. + max_drift_us = DIV_ROUND_UP(SDU_MAX_DRIFT_PPM * sdu_interval, USEC_PER_SEC); + ceil_f = DIV_ROUND_UP((USEC_PER_SEC + max_drift_us) * (uint64_t)iso_interval, + USEC_PER_SEC * (uint64_t)sdu_interval); + if (false) { +#if defined(CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION) + /* To avoid segmentation according to HAP, if the ISO_Interval is less than + * the SDU_Interval, we assume BN=1 and calculate the Max_PDU as: + * Max_PDU = celi(F / BN) x (5 / Max_SDU) + * + * This is in accordance with the "Core enhancement for ISOAL CR". + * + * This ensures that the drift can be contained in the difference between + * SDU_Interval and link bandwidth. For BN=1, ceil(F) == ceil(F/BN). */ - max_pdu_bn1 = ceil_f * 5 + ceil_f_x_max_sdu; - *bn = DIV_ROUND_UP(max_pdu_bn1, LL_CIS_OCTETS_TX_MAX); - *max_pdu = DIV_ROUND_UP(max_pdu_bn1, *bn) + 2; + } else if (iso_interval < sdu_interval) { + *bn = 1; + *max_pdu = ceil_f * (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE + + max_sdu); +#endif + } else { + uint32_t ceil_f_x_max_sdu; + uint16_t max_pdu_bn1; + + ceil_f_x_max_sdu = DIV_ROUND_UP(max_sdu * ((USEC_PER_SEC + max_drift_us) * + (uint64_t)iso_interval), + USEC_PER_SEC * (uint64_t)sdu_interval); + + /* Strategy: Keep lowest possible BN. + * TODO: Implement other strategies, possibly as policies. + */ + max_pdu_bn1 = ceil_f * (PDU_ISO_SEG_HDR_SIZE + + PDU_ISO_SEG_TIMEOFFSET_SIZE) + ceil_f_x_max_sdu; + *bn = DIV_ROUND_UP(max_pdu_bn1, LL_CIS_OCTETS_TX_MAX); + *max_pdu = DIV_ROUND_UP(max_pdu_bn1, *bn) + PDU_ISO_SEG_HDR_SIZE; + } } else { /* For unframed, ISO_Interval must be N x SDU_Interval */ LL_ASSERT(iso_interval % sdu_interval == 0); From 22fbd73fab83a6f4f012221d00d4d445b1c5096e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 26 Aug 2023 17:13:24 +0100 Subject: [PATCH 0094/4498] sensor: max17055: fix v_empty setting Fix the whole v_empty setting code, this was using a wrong scaling factor, but also incorrectly clearing the recovery voltage part of the register. Change the code to read the previous value and mask out the bits not used by VE. Signed-off-by: Fabio Baltieri --- drivers/sensor/max17055/max17055.c | 34 ++++++++++++++++++++++++------ drivers/sensor/max17055/max17055.h | 1 + 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/max17055/max17055.c b/drivers/sensor/max17055/max17055.c index a50069643af..c2db8255623 100644 --- a/drivers/sensor/max17055/max17055.c +++ b/drivers/sensor/max17055/max17055.c @@ -112,14 +112,23 @@ static int capacity_to_max17055(unsigned int rsense_mohms, uint16_t val_mha) } /** - * @brief Convert voltage in millivolts to MAX17055 units + * @brief Update empty voltage target in v_empty * + * @param v_empty The register value to update * @param val_mv Value in millivolts to convert - * @return corresponding value in MAX17055 units, ready to write to a register + * @return 0 on success, -EINVAL on invalid val_mv */ -static int voltage_mV_to_max17055(uint16_t val_mv) +static int max17055_update_vempty(uint16_t *v_empty, uint16_t val_mv) { - return (val_mv * 16) * 10 / 8; /* * 1.25 */ + uint32_t val = (val_mv / 10) << 7; + + if (val & ~VEMPTY_VE) { + return -EINVAL; + } + + *v_empty = (*v_empty & ~VEMPTY_VE) | (uint16_t)val; + + return 0; } static void set_millis(struct sensor_value *val, int val_millis) @@ -338,27 +347,38 @@ static int max17055_write_config(const struct device *dev) uint16_t d_qacc = design_capacity / 32; uint16_t d_pacc = d_qacc * 44138 / design_capacity; uint16_t i_chg_term = current_ma_to_max17055(config->rsense_mohms, config->i_chg_term); - uint16_t v_empty = voltage_mV_to_max17055(config->v_empty); + uint16_t v_empty; LOG_DBG("Writing configuration parameters"); - LOG_DBG("DesignCap: %u, dQAcc: %u, IChgTerm: %u, VEmpty: %u, dPAcc: %u", - design_capacity, d_qacc, i_chg_term, v_empty, d_pacc); + LOG_DBG("DesignCap: %u, dQAcc: %u, IChgTerm: %u, dPAcc: %u", + design_capacity, d_qacc, i_chg_term, d_pacc); if (max17055_reg_write(dev, DESIGN_CAP, design_capacity)) { return -EIO; } + if (max17055_reg_write(dev, D_QACC, d_qacc)) { return -EIO; } + if (max17055_reg_write(dev, ICHG_TERM, i_chg_term)) { return -EIO; } + + if (max17055_reg_read(dev, V_EMPTY, &v_empty)) { + return -EIO; + } + if (max17055_update_vempty(&v_empty, config->v_empty)) { + return -EINVAL; + } if (max17055_reg_write(dev, V_EMPTY, v_empty)) { return -EIO; } + if (max17055_reg_write(dev, D_PACC, d_pacc)) { return -EIO; } + if (max17055_reg_write(dev, MODEL_CFG, MODELCFG_REFRESH)) { return -EIO; } diff --git a/drivers/sensor/max17055/max17055.h b/drivers/sensor/max17055/max17055.h index 476b8663ec5..38bf100f0d9 100644 --- a/drivers/sensor/max17055/max17055.h +++ b/drivers/sensor/max17055/max17055.h @@ -41,6 +41,7 @@ enum { SOFT_WAKEUP_CLEAR = 0x0000, SOFT_WAKEUP_WAKEUP = 0x0090, STATUS_POR = 0x0002, + VEMPTY_VE = 0xff80, }; struct max17055_data { From 9ae9df8b6f058f42a4a9d60492f06864656ab13f Mon Sep 17 00:00:00 2001 From: Alexander Razinkov Date: Wed, 30 Aug 2023 18:05:55 +0300 Subject: [PATCH 0095/4498] kernel: spinlock: k_spin_is_locked introduction Currently spinlock internals are directly accessed from the tests. This way the test becomes bound to the particular spinlock implementation. To remove this unnecessary dependency the distinct API to check if spinlock is locked is introduced. k_spin_is_locked should be used for the spinlock testing only, so the scope of this API is intentionally restricted. Signed-off-by: Alexander Razinkov --- include/zephyr/spinlock.h | 14 ++++++++++++++ tests/kernel/spinlock/src/main.c | 10 +++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/zephyr/spinlock.h b/include/zephyr/spinlock.h index d97bda761d5..823ff7eea68 100644 --- a/include/zephyr/spinlock.h +++ b/include/zephyr/spinlock.h @@ -265,6 +265,20 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, * @cond INTERNAL_HIDDEN */ +#if defined(CONFIG_SMP) && defined(CONFIG_TEST) +/* + * @brief Checks if spinlock is held by some CPU, including the local CPU. + * This API shouldn't be used outside the tests for spinlock + * + * @param l A pointer to the spinlock + * @retval true - if spinlock is held by some CPU; false - otherwise + */ +static ALWAYS_INLINE bool z_spin_is_locked(struct k_spinlock *l) +{ + return l->locked; +} +#endif + /* Internal function: releases the lock, but leaves local interrupts disabled */ static ALWAYS_INLINE void k_spin_release(struct k_spinlock *l) { diff --git a/tests/kernel/spinlock/src/main.c b/tests/kernel/spinlock/src/main.c index 88d3ba8733d..656e986d4cd 100644 --- a/tests/kernel/spinlock/src/main.c +++ b/tests/kernel/spinlock/src/main.c @@ -44,15 +44,15 @@ ZTEST(spinlock, test_spinlock_basic) k_spinlock_key_t key; static struct k_spinlock l; - zassert_true(!l.locked, "Spinlock initialized to locked"); + zassert_true(!z_spin_is_locked(&l), "Spinlock initialized to locked"); key = k_spin_lock(&l); - zassert_true(l.locked, "Spinlock failed to lock"); + zassert_true(z_spin_is_locked(&l), "Spinlock failed to lock"); k_spin_unlock(&l, key); - zassert_true(!l.locked, "Spinlock failed to unlock"); + zassert_true(!z_spin_is_locked(&l), "Spinlock failed to unlock"); } void bounce_once(int id, bool trylock) @@ -164,7 +164,7 @@ ZTEST(spinlock, test_spinlock_mutual_exclusion) key = k_spin_lock(&lock_runtime); - zassert_true(lock_runtime.locked, "Spinlock failed to lock"); + zassert_true(z_spin_is_locked(&lock_runtime), "Spinlock failed to lock"); /* check irq has not locked */ zassert_true(arch_irq_unlocked(key.key), @@ -184,7 +184,7 @@ ZTEST(spinlock, test_spinlock_mutual_exclusion) k_spin_unlock(&lock_runtime, key); - zassert_true(!lock_runtime.locked, "Spinlock failed to unlock"); + zassert_true(!z_spin_is_locked(&lock_runtime), "Spinlock failed to unlock"); } void trylock_fn(void *p1, void *p2, void *p3) From 0371708ba4d067319c4a66f33489ebec8aedd0fc Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Sep 2023 12:15:29 +0200 Subject: [PATCH 0096/4498] boards: arm: (mimx|vmu_)rt1170: fix documentation issues - Remove duplicated labels (not sure why they were not spotted by doc CI?) - Fix titles Signed-off-by: Gerard Marull-Paretas --- boards/arm/mimxrt1170_evk/doc/index.rst | 8 ++------ boards/arm/vmu_rt1170/doc/index.rst | 4 +--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index 51d5053e360..1582861ffc9 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -317,10 +317,8 @@ reprogrammed with JLink firmware. - MIMXRT1170-EVKB: :ref:`mcu-link-cmsis-onboard-debug-probe` - MIMXRT1170-EVK: :ref:`opensda-daplink-onboard-debug-probe` -.. _Using J-Link RT1170: - Using J-Link ---------------------------------- +------------ JLink is the default runner for this board. Install the :ref:`jlink-debug-host-tools` and make sure they are in your search path. @@ -330,10 +328,8 @@ J-Link firmware, or :ref:`jlink-external-debug-probe` can be attached to the EVK. See `Using J-Link with MIMXRT1170-EVKB`_ or `Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. -.. _Using LinkServer RT1170: - Using LinkServer ----------------------------------- +---------------- Known limitations with LinkServer and these boards include: - ``west debug`` does not yet work correctly, and the application image is not diff --git a/boards/arm/vmu_rt1170/doc/index.rst b/boards/arm/vmu_rt1170/doc/index.rst index 3514bf15893..28d57464b4f 100644 --- a/boards/arm/vmu_rt1170/doc/index.rst +++ b/boards/arm/vmu_rt1170/doc/index.rst @@ -216,10 +216,8 @@ Configuring a Debug Probe A debug probe is used for both flashing and debugging the board. -.. _Using J-Link RT1170: - Using J-Link ---------------------------------- +------------ Install the :ref:`jlink-debug-host-tools` and make sure they are in your search path. From 54f8c2b98b85d814fa0f75d983e04be21ebace17 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 13 Jul 2023 11:06:44 +0200 Subject: [PATCH 0097/4498] dts: bindings: dac: add AD56xx Add bindings for the DACs AD56xx. Signed-off-by: Benedikt Schmidt --- dts/bindings/dac/adi,ad5628.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5648.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5668.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5672.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5674.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5676.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5679.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5684.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5686.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5687.yaml | 8 ++++++++ dts/bindings/dac/adi,ad5689.yaml | 8 ++++++++ dts/bindings/dac/adi,ad56xx-base.yaml | 15 +++++++++++++++ 12 files changed, 103 insertions(+) create mode 100644 dts/bindings/dac/adi,ad5628.yaml create mode 100644 dts/bindings/dac/adi,ad5648.yaml create mode 100644 dts/bindings/dac/adi,ad5668.yaml create mode 100644 dts/bindings/dac/adi,ad5672.yaml create mode 100644 dts/bindings/dac/adi,ad5674.yaml create mode 100644 dts/bindings/dac/adi,ad5676.yaml create mode 100644 dts/bindings/dac/adi,ad5679.yaml create mode 100644 dts/bindings/dac/adi,ad5684.yaml create mode 100644 dts/bindings/dac/adi,ad5686.yaml create mode 100644 dts/bindings/dac/adi,ad5687.yaml create mode 100644 dts/bindings/dac/adi,ad5689.yaml create mode 100644 dts/bindings/dac/adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5628.yaml b/dts/bindings/dac/adi,ad5628.yaml new file mode 100644 index 00000000000..409a45bbfde --- /dev/null +++ b/dts/bindings/dac/adi,ad5628.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 12-Bit 8-channel SPI DAC + +compatible: "adi,ad5628" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5648.yaml b/dts/bindings/dac/adi,ad5648.yaml new file mode 100644 index 00000000000..0f6d16909a1 --- /dev/null +++ b/dts/bindings/dac/adi,ad5648.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 14-Bit 8-channel SPI DAC + +compatible: "adi,ad5648" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5668.yaml b/dts/bindings/dac/adi,ad5668.yaml new file mode 100644 index 00000000000..7ddc906ed01 --- /dev/null +++ b/dts/bindings/dac/adi,ad5668.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 16-Bit 8-channel SPI DAC + +compatible: "adi,ad5668" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5672.yaml b/dts/bindings/dac/adi,ad5672.yaml new file mode 100644 index 00000000000..7e987faf1e5 --- /dev/null +++ b/dts/bindings/dac/adi,ad5672.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 12-Bit 8-channel SPI DAC + +compatible: "adi,ad5672" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5674.yaml b/dts/bindings/dac/adi,ad5674.yaml new file mode 100644 index 00000000000..9ee6883dfb9 --- /dev/null +++ b/dts/bindings/dac/adi,ad5674.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 12-Bit 16-channel SPI DAC + +compatible: "adi,ad5674" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5676.yaml b/dts/bindings/dac/adi,ad5676.yaml new file mode 100644 index 00000000000..2c9a21448e0 --- /dev/null +++ b/dts/bindings/dac/adi,ad5676.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 16-Bit 8-channel SPI DAC + +compatible: "adi,ad5676" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5679.yaml b/dts/bindings/dac/adi,ad5679.yaml new file mode 100644 index 00000000000..ad6d8594e4b --- /dev/null +++ b/dts/bindings/dac/adi,ad5679.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 16-Bit 16-channel SPI DAC + +compatible: "adi,ad5679" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5684.yaml b/dts/bindings/dac/adi,ad5684.yaml new file mode 100644 index 00000000000..c7709ffebf0 --- /dev/null +++ b/dts/bindings/dac/adi,ad5684.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 12-Bit 4-channel SPI DAC + +compatible: "adi,ad5684" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5686.yaml b/dts/bindings/dac/adi,ad5686.yaml new file mode 100644 index 00000000000..eb950d8b5c1 --- /dev/null +++ b/dts/bindings/dac/adi,ad5686.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 16-Bit 4-channel SPI DAC + +compatible: "adi,ad5686" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5687.yaml b/dts/bindings/dac/adi,ad5687.yaml new file mode 100644 index 00000000000..998498cff7e --- /dev/null +++ b/dts/bindings/dac/adi,ad5687.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 12-Bit 2-channel SPI DAC + +compatible: "adi,ad5687" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad5689.yaml b/dts/bindings/dac/adi,ad5689.yaml new file mode 100644 index 00000000000..b897f3ed37d --- /dev/null +++ b/dts/bindings/dac/adi,ad5689.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices 16-Bit 2-channel SPI DAC + +compatible: "adi,ad5689" + +include: adi,ad56xx-base.yaml diff --git a/dts/bindings/dac/adi,ad56xx-base.yaml b/dts/bindings/dac/adi,ad56xx-base.yaml new file mode 100644 index 00000000000..68043f46115 --- /dev/null +++ b/dts/bindings/dac/adi,ad56xx-base.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +include: [dac-controller.yaml, spi-device.yaml] + +properties: + "#io-channel-cells": + const: 1 + + reset-gpios: + type: phandle-array + description: "GPIO for reset" + +io-channel-cells: + - output From 536f8ae9cd8505b4aad88983845bc0a37fe15e7d Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 13 Jul 2023 12:31:17 +0200 Subject: [PATCH 0098/4498] drivers: dac: add driver for AD568xx Implement a driver for the DAC AD56xx series. Signed-off-by: Benedikt Schmidt --- drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig | 2 + drivers/dac/Kconfig.ad56xx | 33 ++++ drivers/dac/dac_ad56xx.c | 328 +++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 drivers/dac/Kconfig.ad56xx create mode 100644 drivers/dac/dac_ad56xx.c diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index 5689bea3086..7cce3c8e7cb 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -17,4 +17,5 @@ zephyr_library_sources_ifdef(CONFIG_DAC_MCP4725 dac_mcp4725.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCP4728 dac_mcp4728.c) zephyr_library_sources_ifdef(CONFIG_DAC_GD32 dac_gd32.c) zephyr_library_sources_ifdef(CONFIG_DAC_ESP32 dac_esp32.c) +zephyr_library_sources_ifdef(CONFIG_DAC_AD56XX dac_ad56xx.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE dac_handlers.c) diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index 77b0db902bf..6449032fa48 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -52,4 +52,6 @@ source "drivers/dac/Kconfig.gd32" source "drivers/dac/Kconfig.esp32" +source "drivers/dac/Kconfig.ad56xx" + endif # DAC diff --git a/drivers/dac/Kconfig.ad56xx b/drivers/dac/Kconfig.ad56xx new file mode 100644 index 00000000000..7ce2be653f6 --- /dev/null +++ b/drivers/dac/Kconfig.ad56xx @@ -0,0 +1,33 @@ +# DAC configuration options + +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# +# SPDX-License-Identifier: Apache-2.0 + +config DAC_AD56XX + bool "Analog Devices AD56xx DAC driver" + default y + select SPI + depends on DT_HAS_ADI_AD5628_ENABLED \ + || DT_HAS_ADI_AD5648_ENABLED \ + || DT_HAS_ADI_AD5668_ENABLED \ + || DT_HAS_ADI_AD5672_ENABLED \ + || DT_HAS_ADI_AD5674_ENABLED \ + || DT_HAS_ADI_AD5676_ENABLED \ + || DT_HAS_ADI_AD5679_ENABLED \ + || DT_HAS_ADI_AD5684_ENABLED \ + || DT_HAS_ADI_AD5686_ENABLED \ + || DT_HAS_ADI_AD5687_ENABLED \ + || DT_HAS_ADI_AD5689_ENABLED + help + Enable the driver for the Analog Devices AD56xx DAC + +if DAC_AD56XX + +config DAC_AD56XX_INIT_PRIORITY + int "Init priority" + default 80 + help + Analog Devices AD56xx DAC device driver initialization priority. + +endif # DAC_AD56XX diff --git a/drivers/dac/dac_ad56xx.c b/drivers/dac/dac_ad56xx.c new file mode 100644 index 00000000000..fe523288294 --- /dev/null +++ b/drivers/dac/dac_ad56xx.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(dac_ad56xx, CONFIG_DAC_LOG_LEVEL); + +/* + * These values are actually all way less than 1us, but we can only + * wait with 1us precision. + * + * This should be checked when new types of this series are added to + * this implementation. + */ +#define DAC_AD56XX_MINIMUM_PULSE_WIDTH_LOW_IN_US 1 +#define DAC_AD56XX_PULSE_ACTIVATION_TIME_IN_US 1 + +enum ad56xx_command { + AD56XX_CMD_WRITE_UPDATE_CHANNEL = 3, + AD56XX_CMD_SOFTWARE_RESET = 6, +}; + +struct ad56xx_config { + struct spi_dt_spec bus; + const struct gpio_dt_spec gpio_reset; + uint8_t resolution; + + const uint8_t *channel_addresses; + size_t channel_count; +}; + +struct ad56xx_data { +}; + +static int ad56xx_write_command(const struct device *dev, enum ad56xx_command command, + uint8_t address, uint16_t value) +{ + const struct ad56xx_config *config = dev->config; + uint8_t buffer_tx[3]; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + buffer_tx[0] = (command << 4) | address; + value = value << (16 - config->resolution); + sys_put_be16(value, buffer_tx + 1); + + LOG_DBG("sending to DAC %s command 0x%02X, address 0x%02X and value 0x%04X", dev->name, + command, address, value); + int result = spi_transceive_dt(&config->bus, &tx, &rx); + + if (result != 0) { + LOG_ERR("spi_transceive failed with error %i", result); + return result; + } + + return 0; +} + +static int ad56xx_channel_setup(const struct device *dev, const struct dac_channel_cfg *channel_cfg) +{ + const struct ad56xx_config *config = dev->config; + + if (channel_cfg->channel_id >= config->channel_count) { + LOG_ERR("invalid channel %i", channel_cfg->channel_id); + return -EINVAL; + } + + if (channel_cfg->resolution != config->resolution) { + LOG_ERR("invalid resolution %i", channel_cfg->resolution); + return -EINVAL; + } + + return 0; +} + +static int ad56xx_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + const struct ad56xx_config *config = dev->config; + + if (value > BIT(config->resolution) - 1) { + LOG_ERR("invalid value %i", value); + return -EINVAL; + } + + if (channel > config->channel_count) { + LOG_ERR("invalid channel %i", channel); + return -EINVAL; + } + + return ad56xx_write_command(dev, AD56XX_CMD_WRITE_UPDATE_CHANNEL, + config->channel_addresses[channel], value); +} + +static int ad56xx_init(const struct device *dev) +{ + const struct ad56xx_config *config = dev->config; + int result; + + if (!spi_is_ready_dt(&config->bus)) { + LOG_ERR("SPI bus %s not ready", config->bus.bus->name); + return -ENODEV; + } + + if (config->gpio_reset.port != NULL) { + LOG_DBG("reset %s with GPIO", dev->name); + result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); + if (result != 0) { + LOG_ERR("failed to initialize GPIO for reset"); + return result; + } + + k_busy_wait(DAC_AD56XX_MINIMUM_PULSE_WIDTH_LOW_IN_US); + gpio_pin_set_dt(&config->gpio_reset, 0); + } else { + LOG_DBG("reset %s with command", dev->name); + result = ad56xx_write_command(dev, AD56XX_CMD_SOFTWARE_RESET, 0, 0); + if (result != 0) { + LOG_ERR("failed to send reset command"); + return result; + } + } + + /* + * The pulse activation time is actually defined to start together + * with the pulse start. To be on the safe side we add the wait time + * on top of the actual pulse. + */ + k_busy_wait(DAC_AD56XX_PULSE_ACTIVATION_TIME_IN_US); + + return 0; +} + +static const struct dac_driver_api ad56xx_driver_api = { + .channel_setup = ad56xx_channel_setup, + .write_value = ad56xx_write_value, +}; + +BUILD_ASSERT(CONFIG_DAC_AD56XX_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, + "CONFIG_DAC_AD56XX_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY"); + +#define DAC_AD56XX_INST_DEFINE(index, name, res, channels, channels_count) \ + static struct ad56xx_data data_##name##_##index; \ + static const struct ad56xx_config config_##name##_##index = { \ + .bus = SPI_DT_SPEC_INST_GET( \ + index, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ + .resolution = res, \ + .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(index, reset_gpios, {0}), \ + .channel_addresses = channels, \ + .channel_count = channels_count, \ + }; \ + DEVICE_DT_INST_DEFINE(index, ad56xx_init, NULL, &data_##name##_##index, \ + &config_##name##_##index, POST_KERNEL, \ + CONFIG_DAC_AD56XX_INIT_PRIORITY, &ad56xx_driver_api); + +#define DT_DRV_COMPAT adi_ad5628 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5628_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, +}; +#define DAC_AD5628_RESOLUTION 12 +#define DAC_AD5628_CHANNELS ad5628_channels +#define DAC_AD5628_CHANNEL_COUNT ARRAY_SIZE(ad5628_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5628_RESOLUTION, + DAC_AD5628_CHANNELS, DAC_AD5628_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5648 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5648_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, +}; +#define DAC_AD5648_RESOLUTION 14 +#define DAC_AD5648_CHANNELS ad5648_channels +#define DAC_AD5648_CHANNEL_COUNT ARRAY_SIZE(ad5648_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5648_RESOLUTION, + DAC_AD5648_CHANNELS, DAC_AD5648_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5668 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5668_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, +}; +#define DAC_AD5668_RESOLUTION 16 +#define DAC_AD5668_CHANNELS ad5668_channels +#define DAC_AD5668_CHANNEL_COUNT ARRAY_SIZE(ad5668_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5668_RESOLUTION, + DAC_AD5668_CHANNELS, DAC_AD5668_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5672 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5672_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, +}; +#define DAC_AD5672_RESOLUTION 12 +#define DAC_AD5672_CHANNELS ad5672_channels +#define DAC_AD5672_CHANNEL_COUNT ARRAY_SIZE(ad5672_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5672_RESOLUTION, + DAC_AD5672_CHANNELS, DAC_AD5672_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5674 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5674_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; +#define DAC_AD5674_RESOLUTION 12 +#define DAC_AD5674_CHANNELS ad5674_channels +#define DAC_AD5674_CHANNEL_COUNT ARRAY_SIZE(ad5674_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5674_RESOLUTION, + DAC_AD5674_CHANNELS, DAC_AD5674_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5676 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5676_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, +}; +#define DAC_AD5676_RESOLUTION 16 +#define DAC_AD5676_CHANNELS ad5676_channels +#define DAC_AD5676_CHANNEL_COUNT ARRAY_SIZE(ad5676_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5676_RESOLUTION, + DAC_AD5676_CHANNELS, DAC_AD5676_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5679 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5679_channels[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; +#define DAC_AD5679_RESOLUTION 16 +#define DAC_AD5679_CHANNELS ad5679_channels +#define DAC_AD5679_CHANNEL_COUNT ARRAY_SIZE(ad5679_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5679_RESOLUTION, + DAC_AD5679_CHANNELS, DAC_AD5679_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5684 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5684_channels[] = { + 1, + 2, + 4, + 8, +}; +#define DAC_AD5684_RESOLUTION 12 +#define DAC_AD5684_CHANNELS ad5684_channels +#define DAC_AD5684_CHANNEL_COUNT ARRAY_SIZE(ad5684_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5684_RESOLUTION, + DAC_AD5684_CHANNELS, DAC_AD5684_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5686 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5686_channels[] = { + 1, + 2, + 4, + 8, +}; +#define DAC_AD5686_RESOLUTION 16 +#define DAC_AD5686_CHANNELS ad5686_channels +#define DAC_AD5686_CHANNEL_COUNT ARRAY_SIZE(ad5686_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5686_RESOLUTION, + DAC_AD5686_CHANNELS, DAC_AD5686_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5687 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5687_channels[] = { + 1, + 8, +}; +#define DAC_AD5687_RESOLUTION 12 +#define DAC_AD5687_CHANNELS ad5687_channels +#define DAC_AD5687_CHANNEL_COUNT ARRAY_SIZE(ad5687_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5687_RESOLUTION, + DAC_AD5687_CHANNELS, DAC_AD5687_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT adi_ad5689 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +static const uint8_t ad5689_channels[] = { + 1, + 8, +}; +#define DAC_AD5689_RESOLUTION 16 +#define DAC_AD5689_CHANNELS ad5689_channels +#define DAC_AD5689_CHANNEL_COUNT ARRAY_SIZE(ad5689_channels) +DT_INST_FOREACH_STATUS_OKAY_VARGS(DAC_AD56XX_INST_DEFINE, DT_DRV_COMPAT, DAC_AD5689_RESOLUTION, + DAC_AD5689_CHANNELS, DAC_AD5689_CHANNEL_COUNT) +#endif +#undef DT_DRV_COMPAT From ac025594478dd9c0afba95e70772e247bbf1868e Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 13 Jul 2023 12:34:53 +0200 Subject: [PATCH 0099/4498] tests: drivers: dac: add AD56xx Add instances of the DACs AD56xx to the build all tests. Signed-off-by: Benedikt Schmidt --- tests/drivers/build_all/dac/app.overlay | 99 +++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tests/drivers/build_all/dac/app.overlay b/tests/drivers/build_all/dac/app.overlay index c1e91469744..40218f7949d 100644 --- a/tests/drivers/build_all/dac/app.overlay +++ b/tests/drivers/build_all/dac/app.overlay @@ -68,6 +68,17 @@ /* one entry for every devices at spi.dtsi */ cs-gpios = <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, @@ -134,6 +145,94 @@ spi-max-frequency = <0>; #io-channel-cells = <1>; }; + + test_spi_ad5628: ad5628@5 { + compatible = "adi,ad5628"; + reg = <0x5>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5648: ad5648@6 { + compatible = "adi,ad5648"; + reg = <0x6>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5668: ad5668@7 { + compatible = "adi,ad5668"; + reg = <0x7>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5672: ad5672@8 { + compatible = "adi,ad5672"; + reg = <0x8>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5674: ad5674@9 { + compatible = "adi,ad5674"; + reg = <0x9>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5676: ad5676@A { + compatible = "adi,ad5676"; + reg = <0xA>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5679: ad5679@B { + compatible = "adi,ad5679"; + reg = <0xB>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5684: ad5684@C { + compatible = "adi,ad5684"; + reg = <0xC>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5686: ad5686@D { + compatible = "adi,ad5686"; + reg = <0xD>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5687: ad5687@E { + compatible = "adi,ad5687"; + reg = <0xE>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; + + test_spi_ad5689: ad5689@F { + compatible = "adi,ad5689"; + reg = <0xF>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + }; }; }; }; From 8d956b85ba35be858d428df9b7ba747ee5c7f6d8 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 3 Aug 2023 12:05:48 +0200 Subject: [PATCH 0100/4498] CODEOWNERS: add codeowner of AD56XX Add myself as codeowner of the DAC driver for the AD56XX. Signed-off-by: Benedikt Schmidt --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 07b4941cab2..81ae75325d9 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -271,6 +271,7 @@ /drivers/display/*rm68200* @mmahadevan108 /drivers/display/display_ili9342c.* @extremegtx /drivers/dac/ @martinjaeger +/drivers/dac/*ad56xx* @benediktibk /drivers/dai/ @kv2019i @marcinszkudlinski @abonislawski /drivers/dai/intel/ @kv2019i @marcinszkudlinski @abonislawski /drivers/dai/intel/ssp/ @kv2019i @marcinszkudlinski @abonislawski @@ -615,6 +616,7 @@ /dts/bindings/gpio/*bd8lb600fs* @benediktibk /dts/bindings/gpio/*ads114s0x* @benediktibk /dts/bindings/pwm/*max31790* @benediktibk +/dts/bindings/dac/*ad56* @benediktibk /dts/common/ @galak /include/ @nashif @carlescufi @galak @MaureenHelm /include/zephyr/drivers/*/*litex* @mateusz-holenko @kgugala @pgielda From 98e104fe3dc856f73624627c2d11a05989bdc72f Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Sat, 26 Nov 2022 12:16:12 +0100 Subject: [PATCH 0101/4498] soc: cc13x2_cc26x2: disable CCFG when building MCUboot chain-loaded images The 'CCFG' (Customer Configuration) occupies 88 bytes in topmost flash sector (8 KiB) and is by default always included in the final image. This disables including CCFG part when building images for chain-loading by the MCUboot bootloader. Signed-off-by: Piotr Dymacz --- soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series b/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series index d5defae07b0..b7d26a70539 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series @@ -13,7 +13,7 @@ config SOC_SERIES_CC13X2_CC26X2 select CPU_HAS_FPU select SOC_FAMILY_TISIMPLELINK select HAS_CC13X2_CC26X2_SDK - select HAS_TI_CCFG + select HAS_TI_CCFG if !BOOTLOADER_MCUBOOT select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_PM select HAS_POWEROFF From 57fa44c8a751caeaade390f5261baf2bee6a88be Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Sat, 26 Nov 2022 12:51:01 +0100 Subject: [PATCH 0102/4498] boards: arm: cc1352*/cc26x2r1: define flash partitions for MCUboot This introduces partitions layout for the internal flash and includes 'zephyr,code-partition' property in 'chosen' node, in DTS files of the following boards with the Texas Instruments SimpleLink CC13x2/CC26x2 MCU family: - CC1352P1 LaunchXL (CC1352P) - CC1352R1 LaunchXL (CC1352R) - CC1352R SensorTag (CC1352R) - CC26x2R1 LaunchXL (CC2652R) The flash layout is defined as below (the same for all boards): - boot_partition: 40 KiB (0xa000) - slot0_partition: 136 KiB (0x22000) - slot1_partition: 136 KiB (0x22000) - storage_partition: 32 KiB (0x8000) - unused: 8 KiB (0x2000) All partitions are aligned on the internal flash sector size (8 KiB), last sector is left unused as it contains 'CCFG' (defined as 88-bytes partition in MCU's DTSI). This change allows to use listed boards with MCUboot bootloader. Signed-off-by: Piotr Dymacz --- .../cc1352p1_launchxl/cc1352p1_launchxl.dts | 32 +++++++++++++++++++ .../cc1352r1_launchxl/cc1352r1_launchxl.dts | 32 +++++++++++++++++++ .../cc1352r_sensortag/cc1352r_sensortag.dts | 32 +++++++++++++++++++ .../cc26x2r1_launchxl/cc26x2r1_launchxl.dts | 32 +++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts index 2e6b6193e66..7d0613fafe8 100644 --- a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts @@ -29,6 +29,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,ieee802154 = &ieee802154; + zephyr,code-partition = &slot0_partition; }; /** @@ -84,6 +85,37 @@ }; }; +&flash0 { + partitions { + /* 40 KiB (0xa000) for MCUboot */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000a000>; + }; + + /* 136 KiB (0x22000) per slot for application */ + slot0_partition: partition@a000 { + label = "image-0"; + reg = <0x0000a000 0x00022000>; + }; + + slot1_partition: partition@2c000 { + label = "image-1"; + reg = <0x0002c000 0x00022000>; + }; + + /* 32 KiB (0x8000) for storage */ + storage_partition: partition@4e000 { + label = "storage"; + reg = <0x0004e000 0x00008000>; + }; + + /* CCFG (customer configuration area) is located in uppermost + * flash sector (0x2000/8 KiB @ 0x56000), keep it unused. + */ + }; +}; + &cpu0 { clock-frequency = <48000000>; }; diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts index dd48944cc0f..20bdedddf88 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts @@ -31,6 +31,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,ieee802154 = &ieee802154; + zephyr,code-partition = &slot0_partition; }; leds { @@ -60,6 +61,37 @@ }; }; +&flash0 { + partitions { + /* 40 KiB (0xa000) for MCUboot */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000a000>; + }; + + /* 136 KiB (0x22000) per slot for application */ + slot0_partition: partition@a000 { + label = "image-0"; + reg = <0x0000a000 0x00022000>; + }; + + slot1_partition: partition@2c000 { + label = "image-1"; + reg = <0x0002c000 0x00022000>; + }; + + /* 32 KiB (0x8000) for storage */ + storage_partition: partition@4e000 { + label = "storage"; + reg = <0x0004e000 0x00008000>; + }; + + /* CCFG (customer configuration area) is located in uppermost + * flash sector (0x2000/8 KiB @ 0x56000), keep it unused. + */ + }; +}; + &cpu0 { clock-frequency = <48000000>; }; diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts index 179efb3c096..ffa4711eee9 100644 --- a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts @@ -37,6 +37,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,ieee802154 = &ieee802154; + zephyr,code-partition = &slot0_partition; }; leds { @@ -70,6 +71,37 @@ }; }; +&flash0 { + partitions { + /* 40 KiB (0xa000) for MCUboot */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000a000>; + }; + + /* 136 KiB (0x22000) per slot for application */ + slot0_partition: partition@a000 { + label = "image-0"; + reg = <0x0000a000 0x00022000>; + }; + + slot1_partition: partition@2c000 { + label = "image-1"; + reg = <0x0002c000 0x00022000>; + }; + + /* 32 KiB (0x8000) for storage */ + storage_partition: partition@4e000 { + label = "storage"; + reg = <0x0004e000 0x00008000>; + }; + + /* CCFG (customer configuration area) is located in uppermost + * flash sector (0x2000/8 KiB @ 0x56000), keep it unused. + */ + }; +}; + &cpu0 { clock-frequency = <48000000>; }; diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts index 0245c43f622..a0d8183f485 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts @@ -30,6 +30,7 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,code-partition = &slot0_partition; }; leds { @@ -59,6 +60,37 @@ }; }; +&flash0 { + partitions { + /* 40 KiB (0xa000) for MCUboot */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000a000>; + }; + + /* 136 KiB (0x22000) per slot for application */ + slot0_partition: partition@a000 { + label = "image-0"; + reg = <0x0000a000 0x00022000>; + }; + + slot1_partition: partition@2c000 { + label = "image-1"; + reg = <0x0002c000 0x00022000>; + }; + + /* 32 KiB (0x8000) for storage */ + storage_partition: partition@4e000 { + label = "storage"; + reg = <0x0004e000 0x00008000>; + }; + + /* CCFG (customer configuration area) is located in uppermost + * flash sector (0x2000/8 KiB @ 0x56000), keep it unused. + */ + }; +}; + &cpu0 { clock-frequency = <48000000>; }; From 4d678207b778c6aff09d8e2a11f1e47a160c432a Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Sun, 3 Sep 2023 23:31:24 +0200 Subject: [PATCH 0103/4498] boards: arm: cc1352*/cc26x2r1: add mcuboot-{led0,button0} aliases This adds DT aliases for LED and button used in recovery mode of the MCUboot bootloader, on the following CC13x2/CC26x2 based boards: - CC1352P1 LaunchXL (CC1352P) - CC1352R1 LaunchXL (CC1352R) - CC1352R SensorTag (CC1352R) - CC26x2R1 LaunchXL (CC2652R) For all boards a red LED and second button (not the one used by the TI ROM bootloader) was selected. Signed-off-by: Piotr Dymacz --- boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts | 2 ++ boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts | 2 ++ boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts | 2 ++ boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts | 2 ++ 4 files changed, 8 insertions(+) diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts index 7d0613fafe8..9fcc6da57da 100644 --- a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts @@ -21,6 +21,8 @@ sw0 = &btn0; sw1 = &btn1; watchdog0 = &wdt0; + mcuboot-led0 = &led1; + mcuboot-button0 = &btn1; }; chosen { diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts index 20bdedddf88..53e5a08a365 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts @@ -23,6 +23,8 @@ sw0 = &btn0; sw1 = &btn1; watchdog0 = &wdt0; + mcuboot-led0 = &led1; + mcuboot-button0 = &btn1; }; chosen { diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts index ffa4711eee9..b79e4854f73 100644 --- a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts @@ -29,6 +29,8 @@ sensor2 = &sensor2; accel0 = &sensor1; watchdog0 = &wdt0; + mcuboot-led0 = &led1; + mcuboot-button0 = &btn1; }; chosen { diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts index a0d8183f485..00b5c7d0507 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts @@ -23,6 +23,8 @@ sw0 = &btn0; sw1 = &btn1; watchdog0 = &wdt0; + mcuboot-led0 = &led1; + mcuboot-button0 = &btn1; }; chosen { From 2c2124de76a273c139914569444daa434b63a864 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 13:50:38 +0000 Subject: [PATCH 0104/4498] samples: timer_synchronization: exclude qemu_arc_hs5x Exclude qemu_arc_hs5x from the test, seems to fail since f0daf90. Other ARC platform works so let's exclude this one while the issue is investigated. Link: https://github.com/zephyrproject-rtos/zephyr/issues/62405 Signed-off-by: Fabio Baltieri --- .../portability/cmsis_rtos_v2/timer_synchronization/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml index 61c1a2079fe..7b7103cfb9e 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml +++ b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml @@ -4,6 +4,8 @@ tests: sample.portability.cmsis_rtos_v2.timer_synchronization: integration_platforms: - native_posix + platform_exclude: + - qemu_arc_hs5x # See issue #62405 tags: cmsis_rtos min_ram: 32 min_flash: 34 From a7adb06ff48bc0c2d8f6dde7615622e427d902c9 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Tue, 28 Mar 2023 17:58:20 -0500 Subject: [PATCH 0105/4498] charger: Initial charger dedicated API Add initial charger driver API with the most basic of native_posix driver tests. Signed-off-by: Ricardo Rivera-Matos --- drivers/charger/charger_handlers.c | 38 ++++++ include/zephyr/drivers/charger.h | 184 +++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 drivers/charger/charger_handlers.c create mode 100644 include/zephyr/drivers/charger.h diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c new file mode 100644 index 00000000000..7b658249a84 --- /dev/null +++ b/drivers/charger/charger_handlers.c @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static inline int z_vrfy_charger_get_prop(const struct device *dev, const charger_prop_t prop, + union charger_propval *val) +{ + union charger_propval k_val; + + Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, get_property)); + + int ret = z_impl_charger_get_prop(dev, prop, &k_val); + + Z_OOPS(z_user_to_copy(val, &k_val, sizeof(union charger_propval))); + + return ret; +} + +#include + +static inline int z_vrfy_charger_set_prop(const struct device *dev, const charger_prop_t prop, + const union charger_propval *val) +{ + union charger_propval k_val; + + Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, set_property)); + + Z_OOPS(z_user_from_copy(&k_val, val, sizeof(union charger_propval))); + + return z_impl_charger_set_prop(dev, prop, &k_val); +} + +#include diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h new file mode 100644 index 00000000000..8e72ae03b0b --- /dev/null +++ b/include/zephyr/drivers/charger.h @@ -0,0 +1,184 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ + +/** + * @brief Charger Interface + * @defgroup charger_interface Charger Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Runtime Dynamic Battery Parameters + */ +enum charger_property { + /** Indicates if external supply is present for the charger. */ + /** Value should be of type enum charger_online */ + CHARGER_PROP_ONLINE = 0, + /** Reports whether or not a battery is present. */ + /** Value should be of type bool*/ + CHARGER_PROP_PRESENT, + /** Represents the charging status of the charger. */ + /** Value should be of type enum charger_status */ + CHARGER_PROP_STATUS, + /** Reserved to demark end of common charger properties */ + CHARGER_PROP_COMMON_COUNT, + /** + * Reserved to demark downstream custom properties - use this value as the actual value may + * change over future versions of this API + */ + CHARGER_PROP_CUSTOM_BEGIN = CHARGER_PROP_COMMON_COUNT + 1, + /** Reserved to demark end of valid enum properties */ + CHARGER_PROP_MAX = UINT16_MAX, +}; + +/** + * @typedef charger_prop_t + * @brief A charger property's identifier + * + * See charger_property for a list of identifiers + */ +typedef uint16_t charger_prop_t; + +/** + * @brief External supply states + */ +enum charger_online { + /** External supply not present */ + CHARGER_ONLINE_OFFLINE = 0, + /** External supply is present and of fixed output */ + CHARGER_ONLINE_FIXED, + /** External supply is present and of programmable output*/ + CHARGER_ONLINE_PROGRAMMABLE, +}; + +/** + * @brief Charging states + */ +enum charger_status { + /** Charging device state is unknown */ + CHARGER_STATUS_UNKNOWN = 0, + /** Charging device is charging a battery */ + CHARGER_STATUS_CHARGING, + /** Charging device is not able to charge a battery */ + CHARGER_STATUS_DISCHARGING, + /** Charging device is not charging a battery */ + CHARGER_STATUS_NOT_CHARGING, + /** The battery is full and the charging device will not attempt charging */ + CHARGER_STATUS_FULL, +}; + +/** + * @brief container for a charger_property value + * + */ +union charger_propval { + /* Fields have the format: */ + /* CHARGER_PROPERTY_FIELD */ + /* type property_field; */ + + /** CHARGER_PROP_ONLINE */ + enum charger_online online; + /** CHARGER_PROP_PRESENT */ + bool present; + /** CHARGER_PROP_STATUS */ + enum charger_status status; +}; + +/** + * @typedef charger_get_property_t + * @brief Callback API for getting a charger property. + * + * See charger_get_property() for argument description + */ +typedef int (*charger_get_property_t)(const struct device *dev, const charger_prop_t prop, + union charger_propval *val); + +/** + * @typedef charger_set_property_t + * @brief Callback API for setting a charger property. + * + * See charger_set_property() for argument description + */ +typedef int (*charger_set_property_t)(const struct device *dev, const charger_prop_t prop, + const union charger_propval *val); + +/** + * @brief Charging device API + * + * Caching is entirely on the onus of the client + */ +__subsystem struct charger_driver_api { + charger_get_property_t get_property; + charger_set_property_t set_property; +}; + +/** + * @brief Fetch a battery charger property + * + * @param dev Pointer to the battery charger device + * @param prop Charger property to get + * @param val Pointer to charger_propval union + * + * @retval 0 if successful + * @retval < 0 if getting property failed + */ +__syscall int charger_get_prop(const struct device *dev, const charger_prop_t prop, + union charger_propval *val); + +static inline int z_impl_charger_get_prop(const struct device *dev, const charger_prop_t prop, + union charger_propval *val) +{ + const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; + + return api->get_property(dev, prop, val); +} + +/** + * @brief Set a battery charger property + * + * @param dev Pointer to the battery charger device + * @param prop Charger property to set + * @param val Pointer to charger_propval union + * + * @retval 0 if successful + * @retval < 0 if setting property failed + */ +__syscall int charger_set_prop(const struct device *dev, const charger_prop_t prop, + const union charger_propval *val); + +static inline int z_impl_charger_set_prop(const struct device *dev, const charger_prop_t prop, + const union charger_propval *val) +{ + const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; + + return api->set_property(dev, prop, val); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ */ From aee815f19d85cfa70bb67318c11713c63e593384 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 31 Mar 2023 13:43:51 -0500 Subject: [PATCH 0106/4498] charger: Sample sbs charger driver with tests Adds a sample sbs charger driver and basics tests. Signed-off-by: Ricardo Rivera-Matos --- drivers/CMakeLists.txt | 1 + drivers/Kconfig | 1 + drivers/charger/CMakeLists.txt | 8 + drivers/charger/Kconfig | 24 +++ drivers/charger/Kconfig.sbs_charger | 19 ++ drivers/charger/emul_sbs_charger.c | 141 +++++++++++++++ drivers/charger/sbs_charger.c | 171 ++++++++++++++++++ drivers/charger/sbs_charger.h | 20 ++ dts/bindings/charger/sbs,sbs-charger.yaml | 11 ++ .../charger/sbs_charger/CMakeLists.txt | 8 + .../sbs_charger/boards/emulated_board.conf | 4 + .../sbs_charger/boards/emulated_board.overlay | 28 +++ .../sbs_charger/boards/qemu_cortex_a53.conf | 4 + .../boards/qemu_cortex_a53.overlay | 32 ++++ tests/drivers/charger/sbs_charger/prj.conf | 6 + .../sbs_charger/src/test_sbs_charger.c | 77 ++++++++ .../drivers/charger/sbs_charger/testcase.yaml | 34 ++++ 17 files changed, 589 insertions(+) create mode 100644 drivers/charger/CMakeLists.txt create mode 100644 drivers/charger/Kconfig create mode 100644 drivers/charger/Kconfig.sbs_charger create mode 100644 drivers/charger/emul_sbs_charger.c create mode 100644 drivers/charger/sbs_charger.c create mode 100644 drivers/charger/sbs_charger.h create mode 100644 dts/bindings/charger/sbs,sbs-charger.yaml create mode 100644 tests/drivers/charger/sbs_charger/CMakeLists.txt create mode 100644 tests/drivers/charger/sbs_charger/boards/emulated_board.conf create mode 100644 tests/drivers/charger/sbs_charger/boards/emulated_board.overlay create mode 100644 tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf create mode 100644 tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay create mode 100644 tests/drivers/charger/sbs_charger/prj.conf create mode 100644 tests/drivers/charger/sbs_charger/src/test_sbs_charger.c create mode 100644 tests/drivers/charger/sbs_charger/testcase.yaml diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 749285d29a3..b255b2b638e 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth) add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache) add_subdirectory_ifdef(CONFIG_CAN can) add_subdirectory_ifdef(CONFIG_CLOCK_CONTROL clock_control) +add_subdirectory_ifdef(CONFIG_CHARGER charger) add_subdirectory_ifdef(CONFIG_CONSOLE console) add_subdirectory_ifdef(CONFIG_COREDUMP_DEVICE coredump) add_subdirectory_ifdef(CONFIG_COUNTER counter) diff --git a/drivers/Kconfig b/drivers/Kconfig index 0a369875f6f..2468fe77bd1 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -12,6 +12,7 @@ source "drivers/bbram/Kconfig" source "drivers/bluetooth/Kconfig" source "drivers/cache/Kconfig" source "drivers/can/Kconfig" +source "drivers/charger/Kconfig" source "drivers/clock_control/Kconfig" source "drivers/console/Kconfig" source "drivers/coredump/Kconfig" diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt new file mode 100644 index 00000000000..6b4b36ae61a --- /dev/null +++ b/drivers/charger/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) + +zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig new file mode 100644 index 00000000000..532a0a4545d --- /dev/null +++ b/drivers/charger/Kconfig @@ -0,0 +1,24 @@ +# Copyright 2023 Cirrus Logic, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig CHARGER + bool "Battery charger drivers" + help + Enable battery charger driver configuration. + +if CHARGER + +module = CHARGER +module-str = charger +source "subsys/logging/Kconfig.template.log_config" + +config CHARGER_INIT_PRIORITY + int "Battery charger init priority" + default 90 + help + Battery charger initialization priority. + +source "drivers/charger/Kconfig.sbs_charger" + +endif # CHARGER diff --git a/drivers/charger/Kconfig.sbs_charger b/drivers/charger/Kconfig.sbs_charger new file mode 100644 index 00000000000..4c59c95a9e5 --- /dev/null +++ b/drivers/charger/Kconfig.sbs_charger @@ -0,0 +1,19 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SBS_CHARGER + bool "Smart Battery Charger" + default y + depends on DT_HAS_SBS_SBS_CHARGER_ENABLED + select I2C + help + Enable I2C-based/SMBus-based driver for a Smart Battery Charger. + +config EMUL_SBS_CHARGER + bool "Emulate an SBS 1.1 compliant smart battery charger" + default y + depends on EMUL + depends on SBS_CHARGER + help + It provides reading which follow a simple sequence, thus allowing + test code to check that things are working as expected. diff --git a/drivers/charger/emul_sbs_charger.c b/drivers/charger/emul_sbs_charger.c new file mode 100644 index 00000000000..35ed3a6f471 --- /dev/null +++ b/drivers/charger/emul_sbs_charger.c @@ -0,0 +1,141 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Emulator for SBS 1.1 compliant smart battery charger. + */ + +#define DT_DRV_COMPAT sbs_sbs_charger + +#include +#include +#include +#include +#include +#include + +#include "sbs_charger.h" + +LOG_MODULE_REGISTER(sbs_sbs_charger); + +/** Static configuration for the emulator */ +struct sbs_charger_emul_cfg { + /** I2C address of emulator */ + uint16_t addr; +}; + +static int emul_sbs_charger_reg_write(const struct emul *target, int reg, int val) +{ + LOG_INF("write %x = %x", reg, val); + switch (reg) { + default: + LOG_ERR("Unknown write %x", reg); + return -EIO; + } + + return 0; +} + +static int emul_sbs_charger_reg_read(const struct emul *target, int reg, int *val) +{ + switch (reg) { + case SBS_CHARGER_REG_SPEC_INFO: + case SBS_CHARGER_REG_CHARGER_MODE: + case SBS_CHARGER_REG_STATUS: + case SBS_CHARGER_REG_ALARM_WARNING: + /* Arbitrary stub value. */ + *val = 1; + break; + default: + LOG_ERR("Unknown register 0x%x read", reg); + return -EIO; + } + LOG_INF("read 0x%x = 0x%x", reg, *val); + + return 0; +} + +static int sbs_charger_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, + int num_msgs, int addr) +{ + /* Largely copied from emul_sbs_gauge.c */ + struct sbs_charger_emul_data *data; + unsigned int val; + int reg; + int rc; + + data = target->data; + + i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + switch (num_msgs) { + case 2: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len != 1) { + LOG_ERR("Unexpected msg0 length %d", msgs->len); + return -EIO; + } + reg = msgs->buf[0]; + + /* Now process the 'read' part of the message */ + msgs++; + if (msgs->flags & I2C_MSG_READ) { + switch (msgs->len - 1) { + case 1: + rc = emul_sbs_charger_reg_read(target, reg, &val); + if (rc) { + /* Return before writing bad value to message buffer */ + return rc; + } + + /* SBS uses SMBus, which sends data in little-endian format. */ + sys_put_le16(val, msgs->buf); + break; + default: + LOG_ERR("Unexpected msg1 length %d", msgs->len); + return -EIO; + } + } else { + /* We write a word (2 bytes by the SBS spec) */ + if (msgs->len != 2) { + LOG_ERR("Unexpected msg1 length %d", msgs->len); + } + uint16_t value = sys_get_le16(msgs->buf); + + rc = emul_sbs_charger_reg_write(target, reg, value); + } + break; + default: + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + + return rc; +} + +static const struct i2c_emul_api sbs_charger_emul_api_i2c = { + .transfer = sbs_charger_emul_transfer_i2c, +}; + +static int emul_sbs_sbs_charger_init(const struct emul *target, const struct device *parent) +{ + ARG_UNUSED(target); + ARG_UNUSED(parent); + + return 0; +} + +/* + * Main instantiation macro. SBS Charger Emulator only implemented for I2C + */ +#define SBS_CHARGER_EMUL(n) \ + static const struct sbs_charger_emul_cfg sbs_charger_emul_cfg_##n = { \ + .addr = DT_INST_REG_ADDR(n), \ + }; \ + EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_charger_init, NULL, &sbs_charger_emul_cfg_##n, \ + &sbs_charger_emul_api_i2c, NULL) + +DT_INST_FOREACH_STATUS_OKAY(SBS_CHARGER_EMUL) diff --git a/drivers/charger/sbs_charger.c b/drivers/charger/sbs_charger.c new file mode 100644 index 00000000000..7cdc99b2a73 --- /dev/null +++ b/drivers/charger/sbs_charger.c @@ -0,0 +1,171 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sbs_sbs_charger + +#include +#include +#include +#include + +#include "sbs_charger.h" + +struct sbs_charger_config { + struct i2c_dt_spec i2c; +}; + +LOG_MODULE_REGISTER(sbs_charger); + +static int sbs_cmd_reg_read(const struct device *dev, uint8_t reg_addr, uint16_t *val) +{ + const struct sbs_charger_config *cfg; + uint8_t i2c_data[2]; + int status; + + cfg = dev->config; + status = i2c_burst_read_dt(&cfg->i2c, reg_addr, i2c_data, sizeof(i2c_data)); + if (status < 0) { + LOG_ERR("Unable to read register"); + return status; + } + + *val = sys_get_le16(i2c_data); + + return 0; +} + +static int sbs_cmd_reg_write(const struct device *dev, uint8_t reg_addr, uint16_t val) +{ + const struct sbs_charger_config *config = dev->config; + uint8_t buf[2]; + + sys_put_le16(val, buf); + + return i2c_burst_write_dt(&config->i2c, reg_addr, buf, sizeof(buf)); +} + +static int sbs_cmd_reg_update(const struct device *dev, uint8_t reg_addr, uint16_t mask, + uint16_t val) +{ + uint16_t old_val, new_val; + int ret; + + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, &old_val); + if (ret < 0) { + return ret; + } + + new_val = (old_val & ~mask) | (val & mask); + if (new_val == old_val) { + return 0; + } + + return sbs_cmd_reg_write(dev, reg_addr, new_val); +} + +static int sbs_charger_get_prop(const struct device *dev, const charger_prop_t prop, + union charger_propval *val) +{ + uint16_t reg_val; + int ret; + + switch (prop) { + case CHARGER_PROP_ONLINE: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, ®_val); + if (ret < 0) { + return ret; + } + + if (reg_val & SBS_CHARGER_STATUS_AC_PRESENT) { + val->online = CHARGER_ONLINE_FIXED; + } else { + val->online = CHARGER_ONLINE_OFFLINE; + } + + return 0; + case CHARGER_PROP_PRESENT: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, ®_val); + if (ret < 0) { + return ret; + } + + if (reg_val & SBS_CHARGER_STATUS_BATTERY_PRESENT) { + val->present = true; + } else { + val->present = false; + } + + return 0; + case CHARGER_PROP_STATUS: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, ®_val); + if (ret < 0) { + return ret; + } + + if (!(reg_val & SBS_CHARGER_STATUS_BATTERY_PRESENT)) { + val->status = CHARGER_STATUS_NOT_CHARGING; + } else if (reg_val & SBS_CHARGER_STATUS_AC_PRESENT && + !(reg_val & SBS_CHARGER_STATUS_CHARGE_INHIBITED)) { + val->status = CHARGER_STATUS_CHARGING; + } else { + val->status = CHARGER_STATUS_DISCHARGING; + } + + return 0; + default: + return -ENOTSUP; + } +} + +static int sbs_charger_set_prop(const struct device *dev, const charger_prop_t prop, + const union charger_propval *val) +{ + uint16_t reg_val = 0; + + switch (prop) { + case CHARGER_PROP_STATUS: + if (val->status != CHARGER_STATUS_CHARGING) { + reg_val = SBS_CHARGER_MODE_INHIBIT_CHARGE; + } + return sbs_cmd_reg_update(dev, SBS_CHARGER_REG_CHARGER_MODE, + SBS_CHARGER_MODE_INHIBIT_CHARGE, reg_val); + default: + return -ENOTSUP; + } +} + +/** + * @brief initialize the charger + * + * @return 0 for success + */ +static int sbs_charger_init(const struct device *dev) +{ + const struct sbs_charger_config *cfg = dev->config; + + if (!i2c_is_ready_dt(&cfg->i2c)) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + return 0; +} + +static const struct charger_driver_api sbs_charger_driver_api = { + .get_property = &sbs_charger_get_prop, + .set_property = &sbs_charger_set_prop, +}; + +#define SBS_CHARGER_INIT(inst) \ + \ + static const struct sbs_charger_config sbs_charger_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &sbs_charger_init, NULL, NULL, &sbs_charger_config_##inst, \ + POST_KERNEL, CONFIG_CHARGER_INIT_PRIORITY, &sbs_charger_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SBS_CHARGER_INIT) diff --git a/drivers/charger/sbs_charger.h b/drivers/charger/sbs_charger.h new file mode 100644 index 00000000000..abaf08e25fc --- /dev/null +++ b/drivers/charger/sbs_charger.h @@ -0,0 +1,20 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define SBS_CHARGER_REG_SPEC_INFO 0x11 +#define SBS_CHARGER_REG_CHARGER_MODE 0x12 +#define SBS_CHARGER_REG_STATUS 0x13 +#define SBS_CHARGER_REG_ALARM_WARNING 0x16 + +#define SBS_CHARGER_MODE_INHIBIT_CHARGE BIT(0) + +#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0) +#define SBS_CHARGER_STATUS_RES_COLD BIT(9) +#define SBS_CHARGER_STATUS_RES_HOT BIT(10) +#define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14) +#define SBS_CHARGER_STATUS_AC_PRESENT BIT(15) + +#define SBS_CHARGER_POLL_TIME 500 diff --git a/dts/bindings/charger/sbs,sbs-charger.yaml b/dts/bindings/charger/sbs,sbs-charger.yaml new file mode 100644 index 00000000000..526d796f2cc --- /dev/null +++ b/dts/bindings/charger/sbs,sbs-charger.yaml @@ -0,0 +1,11 @@ +# +# Copyright 2023 Cirrus Logic, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: SBS 1.1 compliant charger (http://www.sbs-forum.org/specs) + +compatible: "sbs,sbs-charger" + +include: [i2c-device.yaml] diff --git a/tests/drivers/charger/sbs_charger/CMakeLists.txt b/tests/drivers/charger/sbs_charger/CMakeLists.txt new file mode 100644 index 00000000000..2c1dfa0e021 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +FILE(GLOB app_sources src/test_sbs_charger.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/charger/sbs_charger/boards/emulated_board.conf b/tests/drivers/charger/sbs_charger/boards/emulated_board.conf new file mode 100644 index 00000000000..ed85179e5cb --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/emulated_board.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y diff --git a/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay b/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay new file mode 100644 index 00000000000..a4684a78a96 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + fake_i2c_bus: i2c@100 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x100 4>; + }; +}; + +&fake_i2c_bus { + clock-frequency = ; + compatible = "zephyr,i2c-emul-controller"; + smartcharger0: smartcharger@b { + compatible = "sbs,sbs-charger"; + reg = <0x0B>; + status = "okay"; + }; +}; diff --git a/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf new file mode 100644 index 00000000000..ed85179e5cb --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y diff --git a/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay new file mode 100644 index 00000000000..cd29ddf8284 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + fake_i2c_bus: i2c@100 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + /* + * qemu_cortex_a53 SoC requires a 64 bit child addresses (reg properties) + * See its /soc #address-cells & #size-cells properties. + */ + reg = <0x0 0x100 0 4>; + }; +}; + +&fake_i2c_bus { + clock-frequency = ; + compatible = "zephyr,i2c-emul-controller"; + smartcharger0: smartcharger@b { + compatible = "sbs,sbs-charger"; + reg = <0x0B>; + status = "okay"; + }; +}; diff --git a/tests/drivers/charger/sbs_charger/prj.conf b/tests/drivers/charger/sbs_charger/prj.conf new file mode 100644 index 00000000000..be0b77722e0 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/prj.conf @@ -0,0 +1,6 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_TEST_USERSPACE=y +CONFIG_LOG=y + +CONFIG_CHARGER=y diff --git a/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c b/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c new file mode 100644 index 00000000000..9b2b9e66900 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c @@ -0,0 +1,77 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sbs_charger_fixture { + const struct device *dev; + const struct charger_driver_api *api; +}; + +static void *sbs_charger_setup(void) +{ + static ZTEST_DMEM struct sbs_charger_fixture fixture; + + fixture.dev = DEVICE_DT_GET_ANY(sbs_sbs_charger); + + k_object_access_all_grant(fixture.dev); + + zassert_true(device_is_ready(fixture.dev), "Charger not found"); + + return &fixture; +} + +ZTEST_USER_F(sbs_charger, test_get_prop_failed_returns_negative) +{ + /* Grab a bogus property */ + charger_prop_t prop = CHARGER_PROP_MAX; + union charger_propval val = {0}; + + int ret = charger_get_prop(fixture->dev, prop, &val); + + zassert_equal(ret, -ENOTSUP, "Getting bad property %d has a good status.", prop); +} + +ZTEST_USER_F(sbs_charger, test_get_prop_success_returns_zero) +{ + /* Validate what props are supported by the driver */ + charger_prop_t prop = CHARGER_PROP_ONLINE; + union charger_propval val = {0}; + + int ret = charger_get_prop(fixture->dev, prop, &val); + + zassert_equal(ret, 0, "Getting good property %d has a good status.", prop); +} + +ZTEST_USER_F(sbs_charger, test_set_prop_failed_returns_negative) +{ + /* Set a bogus property */ + charger_prop_t prop = CHARGER_PROP_MAX; + union charger_propval val = {0}; + + int ret = charger_set_prop(fixture->dev, prop, &val); + + zassert_equal(ret, -ENOTSUP, "Setting bad property %d has a good status.", prop); +} + +ZTEST_USER_F(sbs_charger, test_set_prop_success_returns_zero) +{ + union charger_propval val = {.status = CHARGER_STATUS_NOT_CHARGING}; + charger_prop_t prop = CHARGER_PROP_STATUS; + + int ret = charger_set_prop(fixture->dev, prop, &val); + + zassert_equal(ret, 0, "Setting good property %d has a good status.", prop); +} + +ZTEST_SUITE(sbs_charger, NULL, sbs_charger_setup, NULL, NULL, NULL); diff --git a/tests/drivers/charger/sbs_charger/testcase.yaml b/tests/drivers/charger/sbs_charger/testcase.yaml new file mode 100644 index 00000000000..680f0b6caa3 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/testcase.yaml @@ -0,0 +1,34 @@ +tests: + # section.subsection + drivers.sbs_charger.emulated: + tags: drivers charger + filter: > + dt_compat_enabled("sbs,sbs-charger") and + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + extra_args: + CONF_FILE="prj.conf;boards/emulated_board.conf" + DTC_OVERLAY_FILE="boards/emulated_board.overlay" + platform_exclude: + qemu_cortex_a53 + qemu_cortex_a53_smp + qemu_kvm_arm64 + xenvm + xenvm_gicv3 + hifive_unmatched + rcar_h3ulcb_ca57 + rcar_salvator_xs_m3 + numaker_pfm_m467 + drivers.sbs_charger.emulated_64_bit_i2c_addr: + tags: drivers charger + filter: > + dt_compat_enabled("sbs,sbs-charger") and + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + platform_allow: + qemu_cortex_a53 + qemu_cortex_a53_smp + qemu_kvm_arm64 + xenvm + xenvm_gicv3 + extra_args: + CONF_FILE="prj.conf;boards/qemu_cortex_a53.conf" + DTC_OVERLAY_FILE="boards/qemu_cortex_a53.overlay" From a6270352903322d9c98664628a37bcf67cbd1aaa Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Mon, 3 Apr 2023 11:10:44 -0500 Subject: [PATCH 0107/4498] charger: Adds basic stub API doc Adds a short stub doc as a placeholder for future documentation in the charger API. Signed-off-by: Ricardo Rivera-Matos --- doc/develop/api/overview.rst | 4 ++++ doc/hardware/peripherals/charger.rst | 29 ++++++++++++++++++++++++++++ doc/hardware/peripherals/index.rst | 1 + 3 files changed, 34 insertions(+) create mode 100644 doc/hardware/peripherals/charger.rst diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index c071e286b56..90935584621 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -57,6 +57,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Stable - 1.14 + * - :ref:`charger_api` + - Experimental + - 3.5 + * - :ref:`counter_api` - Unstable - 1.14 diff --git a/doc/hardware/peripherals/charger.rst b/doc/hardware/peripherals/charger.rst new file mode 100644 index 00000000000..a3e2c177e3e --- /dev/null +++ b/doc/hardware/peripherals/charger.rst @@ -0,0 +1,29 @@ +.. _charger_api: + +Chargers +######## + +The charger subsystem exposes an API to uniformly access battery charger devices. Currently, +only reading data is supported. + +Basic Operation +*************** + +Properties +========== + +Fundamentally, a property is a configurable setting, state, or quantity that a charger device can +measure. + +Chargers typically support multiple properties, such as temperature readings of the battery-pack +or present-time current/voltage. + +Properties are fetched using a client allocated array of :c:struct:`charger_get_property`. This +array is then populated by values as according to its `property_type` field. + +.. _charger_api_reference: + +API Reference +************* + +.. doxygengroup:: charger_interface diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 6e59ca3c44f..6de39a8a7b2 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -17,6 +17,7 @@ Peripherals bc12.rst clock_control.rst canbus/index.rst + charger.rst coredump.rst counter.rst dac.rst From 766af4cc0c4bc0d1950c4815e39b9d9ad478c839 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 22 Aug 2023 14:00:21 +0200 Subject: [PATCH 0108/4498] drivers: gpio: Smartbond: correct gpio init level Init level for GPIO drivers is set PRE_KERNEL_1. Smartbond(tm) driver had it set to POST_KERNEL by accident. Signed-off-by: Jerzy Kasenberg --- drivers/gpio/gpio_smartbond.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_smartbond.c b/drivers/gpio/gpio_smartbond.c index 8bfa4f8d9a1..ae640e31b2e 100644 --- a/drivers/gpio/gpio_smartbond.c +++ b/drivers/gpio/gpio_smartbond.c @@ -283,7 +283,7 @@ static const struct gpio_driver_api gpio_smartbond_drv_api_funcs = { NULL, \ &gpio_smartbond_p##id##_data, \ &gpio_smartbond_p##id##_config, \ - POST_KERNEL, \ + PRE_KERNEL_1, \ CONFIG_GPIO_INIT_PRIORITY, \ &gpio_smartbond_drv_api_funcs); From a9b44e08dfc0930585cb074c0b8dd653476ab0bb Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 22 Aug 2023 13:39:54 +0200 Subject: [PATCH 0109/4498] drivers: gpio: Smartbond: add support for both edge triggers Hardware supports only one edge for GPIO interrupt. This adds software implementation that hides hardware restriction. With this change user code can use GPIO_INT_TRIG_BOTH and does not have to do it in application code. Signed-off-by: Jerzy Kasenberg --- drivers/gpio/gpio_smartbond.c | 44 +++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio_smartbond.c b/drivers/gpio/gpio_smartbond.c index ae640e31b2e..8996690ccb4 100644 --- a/drivers/gpio/gpio_smartbond.c +++ b/drivers/gpio/gpio_smartbond.c @@ -56,6 +56,8 @@ struct gpio_smartbond_wkup_regs { struct gpio_smartbond_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; + /* Pins that are configured for both edges (handled by software) */ + gpio_port_pins_t both_edges_pins; sys_slist_t callbacks; }; @@ -184,12 +186,30 @@ static int gpio_smartbond_port_toggle_bits(const struct device *dev, return 0; } +static void gpio_smartbond_arm_next_edge_interrupt(const struct device *dev, + uint32_t pin_mask) +{ + const struct gpio_smartbond_config *config = dev->config; + uint32_t pin_value; + + do { + pin_value = config->data_regs->data & pin_mask; + if (pin_value) { + config->wkup_regs->pol |= pin_mask; + } else { + config->wkup_regs->pol &= ~pin_mask; + } + } while (pin_value != (config->data_regs->data & pin_mask)); +} + static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { const struct gpio_smartbond_config *config = dev->config; + struct gpio_smartbond_data *data = dev->data; + uint32_t pin_mask = BIT(pin); /* Not supported by hardware */ if (mode == GPIO_INT_MODE_LEVEL) { @@ -202,16 +222,15 @@ static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, } else { if (trig == GPIO_INT_TRIG_BOTH) { /* Not supported by hardware */ - return -ENOTSUP; - } - - if (trig == GPIO_INT_TRIG_HIGH) { - config->wkup_regs->pol &= ~BIT(pin); + data->both_edges_pins |= pin_mask; + gpio_smartbond_arm_next_edge_interrupt(dev, pin_mask); + } else if (trig == GPIO_INT_TRIG_HIGH) { + config->wkup_regs->pol &= ~pin_mask; } else { - config->wkup_regs->pol |= BIT(pin); + config->wkup_regs->pol |= pin_mask; } - config->wkup_regs->sel |= BIT(pin); + config->wkup_regs->sel |= pin_mask; } return 0; @@ -230,10 +249,21 @@ static void gpio_smartbond_isr(const struct device *dev) const struct gpio_smartbond_config *config = dev->config; struct gpio_smartbond_data *data = dev->data; uint32_t stat; + uint32_t two_edge_triggered; WAKEUP->WKUP_RESET_IRQ_REG = WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Msk; stat = config->wkup_regs->status; + + two_edge_triggered = stat & data->both_edges_pins; + while (two_edge_triggered) { + int pos = find_lsb_set(two_edge_triggered) - 1; + + two_edge_triggered &= ~BIT(pos); + /* Re-arm for other edge */ + gpio_smartbond_arm_next_edge_interrupt(dev, BIT(pos)); + } + config->wkup_regs->clear = stat; gpio_fire_callbacks(&data->callbacks, dev, stat); From 48c56cebaa4c75be806306e4e885db52987975f1 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 22 Aug 2023 14:42:00 +0200 Subject: [PATCH 0110/4498] drivers: gpio: Smartbond: Add pdc support This change allows to have GPIO interrupts configured that will work while chip enters low power modes where PD_COM is turned off. PDC controller can wake up system on GPIO changes even when PD_COM is off. This is done by adding PDC entries that will wakeup Cortex-M33 at the same time when WAKEUP controller is programmed to handle GPIO state changes. Signed-off-by: Jerzy Kasenberg --- drivers/gpio/gpio_smartbond.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_smartbond.c b/drivers/gpio/gpio_smartbond.c index 8996690ccb4..81ce31296f2 100644 --- a/drivers/gpio/gpio_smartbond.c +++ b/drivers/gpio/gpio_smartbond.c @@ -13,6 +13,7 @@ #include #include +#include #define GPIO_MODE_RESET 0x200 @@ -68,6 +69,8 @@ struct gpio_smartbond_config { volatile uint32_t *mode_regs; volatile struct gpio_smartbond_latch_regs *latch_regs; volatile struct gpio_smartbond_wkup_regs *wkup_regs; + /* Value of TRIG_SELECT for PDC_CTRLx_REG entry */ + uint8_t wkup_trig_select; }; static void gpio_smartbond_wkup_init(void) @@ -210,15 +213,26 @@ static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, const struct gpio_smartbond_config *config = dev->config; struct gpio_smartbond_data *data = dev->data; uint32_t pin_mask = BIT(pin); +#if CONFIG_PM + int trig_select_id = (config->wkup_trig_select << 5) | pin; + int pdc_ix; +#endif /* Not supported by hardware */ if (mode == GPIO_INT_MODE_LEVEL) { return -ENOTSUP; } +#if CONFIG_PM + pdc_ix = da1469x_pdc_find(trig_select_id, MCU_PDC_MASTER_M33, MCU_PDC_EN_XTAL); +#endif if (mode == GPIO_INT_MODE_DISABLED) { - config->wkup_regs->sel &= ~BIT(pin); - config->wkup_regs->clear = BIT(pin); + config->wkup_regs->sel &= ~pin_mask; + config->wkup_regs->clear = pin_mask; + data->both_edges_pins &= ~pin_mask; +#if CONFIG_PM + da1469x_pdc_del(pdc_ix); +#endif } else { if (trig == GPIO_INT_TRIG_BOTH) { /* Not supported by hardware */ @@ -231,6 +245,15 @@ static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, } config->wkup_regs->sel |= pin_mask; +#if CONFIG_PM + if (pdc_ix < 0) { + pdc_ix = da1469x_pdc_add(trig_select_id, MCU_PDC_MASTER_M33, + MCU_PDC_EN_XTAL); + } + if (pdc_ix < 0) { + return -ENOMEM; + } +#endif } return 0; @@ -294,6 +317,7 @@ static const struct gpio_driver_api gpio_smartbond_drv_api_funcs = { DT_INST_REG_ADDR_BY_NAME(id, latch), \ .wkup_regs = (volatile struct gpio_smartbond_wkup_regs *) \ DT_INST_REG_ADDR_BY_NAME(id, wkup), \ + .wkup_trig_select = id, \ }; \ \ static struct gpio_smartbond_data gpio_smartbond_p##id##_data; \ From 9c5dafed95ee6d96fbe28d0e5dc20b674bb62fbe Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sun, 27 Aug 2023 23:20:34 +0100 Subject: [PATCH 0111/4498] util: add type checking to CONTAINER_OF Add a SAME_TYPE checking macro and use it to add type validation to CONTAINER_OF. This is inspired by the Linux container_of implementation. The check is inhibited when using C++ as __builtin_types_compatible_p is not available there. Signed-off-by: Fabio Baltieri --- include/zephyr/sys/util.h | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index e2c3f9d4fb5..db5d85eeb41 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -15,6 +15,7 @@ #define ZEPHYR_INCLUDE_SYS_UTIL_H_ #include +#include /* needs to be outside _ASMLANGUAGE so 'true' and 'false' can turn * into '1' and '0' for asm or linker scripts @@ -201,6 +202,27 @@ extern "C" { (POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) / sizeof((array)[0]); \ }) +/** + * @brief Validate if two entities have a compatible type + * + * @param a the first entity to be compared + * @param a the second entity to be compared + * @return 1 if the two elements are compatible, 0 if they are not + */ +#define SAME_TYPE(a, b) __builtin_types_compatible_p(__typeof__(a), __typeof__(b)) + +/** + * @brief Validate CONTAINER_OF parameters, only applies to C mode. + */ +#ifndef __cplusplus +#define CONTAINER_OF_VALIDATE(ptr, type, field) \ + BUILD_ASSERT(SAME_TYPE(*(ptr), ((type *)0)->field) || \ + SAME_TYPE(*(ptr), void), \ + "pointer type mismatch in CONTAINER_OF"); +#else +#define CONTAINER_OF_VALIDATE(ptr, type, field) +#endif + /** * @brief Get a pointer to a structure containing the element * @@ -222,8 +244,11 @@ extern "C" { * @param field the name of the field within the struct @p ptr points to * @return a pointer to the structure that contains @p ptr */ -#define CONTAINER_OF(ptr, type, field) \ - ((type *)(((char *)(ptr)) - offsetof(type, field))) +#define CONTAINER_OF(ptr, type, field) \ + ({ \ + CONTAINER_OF_VALIDATE(ptr, type, field) \ + ((type *)(((char *)(ptr)) - offsetof(type, field))); \ + }) /** * @brief Value of @p x rounded up to the next multiple of @p align. From 22bde976e5e6eea26d3d6c830a668a96dddd4680 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Thu, 7 Sep 2023 10:13:56 +0200 Subject: [PATCH 0112/4498] Bluetooth: l2cap: validate `reconfigure` packet length The specification only allows up to 5 16-bit CIDs in this PDU. Enforce it. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/l2cap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 7203faf8b2f..2af255a622e 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -1363,6 +1363,12 @@ static void le_ecred_reconf_req(struct bt_l2cap *l2cap, uint8_t ident, goto response; } + /* The specification only allows up to 5 CIDs in this packet */ + if (buf->len > (L2CAP_ECRED_CHAN_MAX_PER_REQ * sizeof(scid))) { + result = BT_L2CAP_RECONF_OTHER_UNACCEPT; + goto response; + } + while (buf->len >= sizeof(scid)) { struct bt_l2cap_chan *chan; scid = net_buf_pull_le16(buf); From 603b49b70a1b937e37537612e44272a4716bc130 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Sep 2023 12:27:07 +0200 Subject: [PATCH 0113/4498] drivers: gpio: pin_interrupt_configure is optional Some GPIO controllers do not support interrupts, so allow drivers to not provide this operation. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/drivers/gpio.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 3d77108b853..1b3fed68cfc 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -846,6 +846,7 @@ static inline bool gpio_is_ready_dt(const struct gpio_dt_spec *spec) * @param flags Interrupt configuration flags as defined by GPIO_INT_*. * * @retval 0 If successful. + * @retval -ENOSYS If the operation is not implemented by the driver. * @retval -ENOTSUP If any of the configuration options is not supported * (unless otherwise directed by flag documentation). * @retval -EINVAL Invalid argument. @@ -871,6 +872,10 @@ static inline int z_impl_gpio_pin_interrupt_configure(const struct device *port, enum gpio_int_trig trig; enum gpio_int_mode mode; + if (api->pin_interrupt_configure == NULL) { + return -ENOSYS; + } + __ASSERT((flags & (GPIO_INT_DISABLE | GPIO_INT_ENABLE)) != (GPIO_INT_DISABLE | GPIO_INT_ENABLE), "Cannot both enable and disable interrupts"); From b03ef6c8baa004b2741b984b4eda042013459f0b Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Sep 2023 12:29:11 +0200 Subject: [PATCH 0114/4498] drivers: gpio: gpio_add|remove_callback: s/ENOTSUP/ENOSYS -ENOSYS is the right error code to be returned if an op is not implemented by a driver. Also clarify the documentation. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/drivers/gpio.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 1b3fed68cfc..2d0b1fa133e 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -1700,7 +1700,9 @@ static inline void gpio_init_callback(struct gpio_callback *callback, * @brief Add an application callback. * @param port Pointer to the device structure for the driver instance. * @param callback A valid Application's callback structure pointer. - * @return 0 if successful, negative errno code on failure. + * @retval 0 If successful + * @retval -ENOSYS If driver does not implement the operation + * @retval -errno Other negative errno code on failure. * * @note Callbacks may be added to the device from within a callback * handler invocation, but whether they are invoked for the current @@ -1715,7 +1717,7 @@ static inline int gpio_add_callback(const struct device *port, (const struct gpio_driver_api *)port->api; if (api->manage_callback == NULL) { - return -ENOTSUP; + return -ENOSYS; } return api->manage_callback(port, callback, true); @@ -1742,7 +1744,9 @@ static inline int gpio_add_callback_dt(const struct gpio_dt_spec *spec, * @brief Remove an application callback. * @param port Pointer to the device structure for the driver instance. * @param callback A valid application's callback structure pointer. - * @return 0 if successful, negative errno code on failure. + * @retval 0 If successful + * @retval -ENOSYS If driver does not implement the operation + * @retval -errno Other negative errno code on failure. * * @warning It is explicitly permitted, within a callback handler, to * remove the registration for the callback that is running, i.e. @p @@ -1761,7 +1765,7 @@ static inline int gpio_remove_callback(const struct device *port, (const struct gpio_driver_api *)port->api; if (api->manage_callback == NULL) { - return -ENOTSUP; + return -ENOSYS; } return api->manage_callback(port, callback, false); From 35500e4d151d2e21e60a18d2358a0de3c4049cee Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Sep 2023 12:32:39 +0200 Subject: [PATCH 0115/4498] drivers: gpio: gpio_get_pending_int: s/ENOTSUP/ENOSYS Because -ENOSYS is the right error code to be used if op is not implemented. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/drivers/gpio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 2d0b1fa133e..99d6d677a65 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -1800,6 +1800,7 @@ static inline int gpio_remove_callback_dt(const struct gpio_dt_spec *spec, * * @retval status != 0 if at least one gpio interrupt is pending. * @retval 0 if no gpio interrupt is pending. + * @retval -ENOSYS If driver does not implement the operation */ __syscall int gpio_get_pending_int(const struct device *dev); @@ -1809,7 +1810,7 @@ static inline int z_impl_gpio_get_pending_int(const struct device *dev) (const struct gpio_driver_api *)dev->api; if (api->get_pending_int == NULL) { - return -ENOTSUP; + return -ENOSYS; } return api->get_pending_int(dev); From 64968d74024ab4d43de731c1e7c265869c63f2a0 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Sep 2023 12:50:06 +0200 Subject: [PATCH 0116/4498] drivers: gpio: fix optional operations usage Only provide implementations for optional operations if needed. This patch deletes quite a few dummy `pin_interrupt_configure` ops (now optional), and adjusts ifdeffery on some drivers so that optional ops are only provided if they implement real functionality. Signed-off-by: Gerard Marull-Paretas --- drivers/gpio/gpio_ads114s0x.c | 12 ------------ drivers/gpio/gpio_axp192.c | 12 ------------ drivers/gpio/gpio_bd8lb600fs.c | 7 ------- drivers/gpio/gpio_creg_gpio.c | 9 --------- drivers/gpio/gpio_cy8c95xx.c | 9 --------- drivers/gpio/gpio_fxl6408.c | 10 ---------- drivers/gpio/gpio_lmp90xxx.c | 14 -------------- drivers/gpio/gpio_mcp23s17.c | 9 --------- drivers/gpio/gpio_mmio32.c | 13 ------------- drivers/gpio/gpio_neorv32.c | 14 -------------- drivers/gpio/gpio_npm1300.c | 12 ------------ drivers/gpio/gpio_npm6001.c | 14 -------------- drivers/gpio/gpio_nxp_s32.c | 29 +++-------------------------- drivers/gpio/gpio_pca95xx.c | 14 ++------------ drivers/gpio/gpio_sc18im704.c | 12 ------------ drivers/gpio/gpio_sn74hc595.c | 11 ----------- drivers/gpio/gpio_stmpe1600.c | 9 --------- drivers/gpio/gpio_sx1509b.c | 11 +++-------- drivers/gpio/gpio_test.c | 23 ----------------------- drivers/gpio/gpio_xlnx_axi.c | 4 +++- drivers/gpio/gpio_xmc4xxx.c | 15 +++++---------- 21 files changed, 16 insertions(+), 247 deletions(-) diff --git a/drivers/gpio/gpio_ads114s0x.c b/drivers/gpio/gpio_ads114s0x.c index 79383d38154..13f4f7f1266 100644 --- a/drivers/gpio/gpio_ads114s0x.c +++ b/drivers/gpio/gpio_ads114s0x.c @@ -106,17 +106,6 @@ static int gpio_ads114s0x_port_toggle_bits(const struct device *dev, gpio_port_p return ads114s0x_gpio_port_toggle_bits(config->parent, pins); } -static int gpio_ads114s0x_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static int gpio_ads114s0x_init(const struct device *dev) { const struct gpio_ads114s0x_config *config = dev->config; @@ -135,7 +124,6 @@ static const struct gpio_driver_api gpio_ads114s0x_api = { .port_set_bits_raw = gpio_ads114s0x_port_set_bits_raw, .port_clear_bits_raw = gpio_ads114s0x_port_clear_bits_raw, .port_toggle_bits = gpio_ads114s0x_port_toggle_bits, - .pin_interrupt_configure = gpio_ads114s0x_pin_interrupt_configure, .port_get_raw = gpio_ads114s0x_port_get_raw, }; diff --git a/drivers/gpio/gpio_axp192.c b/drivers/gpio/gpio_axp192.c index ee75fe9b276..95625d99dfe 100644 --- a/drivers/gpio/gpio_axp192.c +++ b/drivers/gpio/gpio_axp192.c @@ -159,17 +159,6 @@ static int gpio_axp192_port_toggle_bits(const struct device *dev, gpio_port_pins return ret; } -static int gpio_axp192_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - #ifdef CONFIG_GPIO_GET_CONFIG static int gpio_axp192_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *out_flags) { @@ -276,7 +265,6 @@ static const struct gpio_driver_api gpio_axp192_api = { .port_set_bits_raw = gpio_axp192_port_set_bits_raw, .port_clear_bits_raw = gpio_axp192_port_clear_bits_raw, .port_toggle_bits = gpio_axp192_port_toggle_bits, - .pin_interrupt_configure = gpio_axp192_pin_interrupt_configure, .manage_callback = gpio_axp192_manage_callback, #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_axp192_port_get_direction, diff --git a/drivers/gpio/gpio_bd8lb600fs.c b/drivers/gpio/gpio_bd8lb600fs.c index 555a63b91fd..30ae851d90b 100644 --- a/drivers/gpio/gpio_bd8lb600fs.c +++ b/drivers/gpio/gpio_bd8lb600fs.c @@ -193,12 +193,6 @@ static int bd8lb600fs_port_toggle_bits(const struct device *dev, uint32_t mask) return result; } -static int bd8lb600fs_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - static const struct gpio_driver_api api_table = { .pin_configure = bd8lb600fs_pin_configure, .port_get_raw = bd8lb600fs_port_get_raw, @@ -206,7 +200,6 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = bd8lb600fs_port_set_bits_raw, .port_clear_bits_raw = bd8lb600fs_port_clear_bits_raw, .port_toggle_bits = bd8lb600fs_port_toggle_bits, - .pin_interrupt_configure = bd8lb600fs_pin_interrupt_configure, }; static int bd8lb600fs_init(const struct device *dev) diff --git a/drivers/gpio/gpio_creg_gpio.c b/drivers/gpio/gpio_creg_gpio.c index 05b09184df9..1b9f4d63a50 100644 --- a/drivers/gpio/gpio_creg_gpio.c +++ b/drivers/gpio/gpio_creg_gpio.c @@ -104,14 +104,6 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } -static int pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - static int pin_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) @@ -163,7 +155,6 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, - .pin_interrupt_configure = pin_interrupt_configure, }; static const struct creg_gpio_config creg_gpio_cfg = { diff --git a/drivers/gpio/gpio_cy8c95xx.c b/drivers/gpio/gpio_cy8c95xx.c index b540a7b96bf..155bfb4988a 100644 --- a/drivers/gpio/gpio_cy8c95xx.c +++ b/drivers/gpio/gpio_cy8c95xx.c @@ -214,14 +214,6 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } -static int pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - /** * @brief Initialization function of CY8C95XX * @@ -277,7 +269,6 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, - .pin_interrupt_configure = pin_interrupt_configure, }; static struct k_sem cy8c95xx_lock = Z_SEM_INITIALIZER(cy8c95xx_lock, 1, 1); diff --git a/drivers/gpio/gpio_fxl6408.c b/drivers/gpio/gpio_fxl6408.c index 164a4396c13..7352390e371 100644 --- a/drivers/gpio/gpio_fxl6408.c +++ b/drivers/gpio/gpio_fxl6408.c @@ -377,15 +377,6 @@ static int gpio_fxl6408_port_toggle_bits(const struct device *dev, return ret; } -static int gpio_fxl6408_pin_interrupt_configure(const struct device *port, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - LOG_DBG("Pin interrupts not supported."); - return -ENOTSUP; -} - int gpio_fxl6408_init(const struct device *dev) { struct gpio_fxl6408_drv_data *const drv_data = @@ -409,7 +400,6 @@ static const struct gpio_driver_api gpio_fxl_driver = { .port_set_bits_raw = gpio_fxl6408_port_set_bits_raw, .port_clear_bits_raw = gpio_fxl6408_port_clear_bits_raw, .port_toggle_bits = gpio_fxl6408_port_toggle_bits, - .pin_interrupt_configure = gpio_fxl6408_pin_interrupt_configure }; #define GPIO_FXL6408_DEVICE_INSTANCE(inst) \ diff --git a/drivers/gpio/gpio_lmp90xxx.c b/drivers/gpio/gpio_lmp90xxx.c index 1bd99d88cf2..2514ef35211 100644 --- a/drivers/gpio/gpio_lmp90xxx.c +++ b/drivers/gpio/gpio_lmp90xxx.c @@ -122,19 +122,6 @@ static int gpio_lmp90xxx_port_toggle_bits(const struct device *dev, return lmp90xxx_gpio_port_toggle_bits(config->parent, pins); } -static int gpio_lmp90xxx_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static int gpio_lmp90xxx_init(const struct device *dev) { const struct gpio_lmp90xxx_config *config = dev->config; @@ -154,7 +141,6 @@ static const struct gpio_driver_api gpio_lmp90xxx_api = { .port_set_bits_raw = gpio_lmp90xxx_port_set_bits_raw, .port_clear_bits_raw = gpio_lmp90xxx_port_clear_bits_raw, .port_toggle_bits = gpio_lmp90xxx_port_toggle_bits, - .pin_interrupt_configure = gpio_lmp90xxx_pin_interrupt_configure, .port_get_raw = gpio_lmp90xxx_port_get_raw, }; diff --git a/drivers/gpio/gpio_mcp23s17.c b/drivers/gpio/gpio_mcp23s17.c index 96a266fdf6d..4849c3a02fe 100644 --- a/drivers/gpio/gpio_mcp23s17.c +++ b/drivers/gpio/gpio_mcp23s17.c @@ -340,14 +340,6 @@ static int mcp23s17_port_toggle_bits(const struct device *dev, uint32_t mask) return ret; } -static int mcp23s17_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - static const struct gpio_driver_api api_table = { .pin_configure = mcp23s17_config, .port_get_raw = mcp23s17_port_get_raw, @@ -355,7 +347,6 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = mcp23s17_port_set_bits_raw, .port_clear_bits_raw = mcp23s17_port_clear_bits_raw, .port_toggle_bits = mcp23s17_port_toggle_bits, - .pin_interrupt_configure = mcp23s17_pin_interrupt_configure, }; static int mcp23s17_init(const struct device *dev) diff --git a/drivers/gpio/gpio_mmio32.c b/drivers/gpio/gpio_mmio32.c index e9e58373b5b..0fe5e9fedd8 100644 --- a/drivers/gpio/gpio_mmio32.c +++ b/drivers/gpio/gpio_mmio32.c @@ -147,18 +147,6 @@ static int gpio_mmio32_port_toggle_bits(const struct device *dev, return 0; } -static int gpio_mmio32_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - if (mode != GPIO_INT_MODE_DISABLED) { - return -ENOTSUP; - } - - return 0; -} - const struct gpio_driver_api gpio_mmio32_api = { .pin_configure = gpio_mmio32_config, .port_get_raw = gpio_mmio32_port_get_raw, @@ -166,7 +154,6 @@ const struct gpio_driver_api gpio_mmio32_api = { .port_set_bits_raw = gpio_mmio32_port_set_bits_raw, .port_clear_bits_raw = gpio_mmio32_port_clear_bits_raw, .port_toggle_bits = gpio_mmio32_port_toggle_bits, - .pin_interrupt_configure = gpio_mmio32_pin_interrupt_configure, }; int gpio_mmio32_init(const struct device *dev) diff --git a/drivers/gpio/gpio_neorv32.c b/drivers/gpio/gpio_neorv32.c index b448962bde7..b14c51c1471 100644 --- a/drivers/gpio/gpio_neorv32.c +++ b/drivers/gpio/gpio_neorv32.c @@ -151,19 +151,6 @@ static int neorv32_gpio_port_toggle_bits(const struct device *dev, return 0; } -static int neorv32_gpio_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static int neorv32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set) @@ -215,7 +202,6 @@ static const struct gpio_driver_api neorv32_gpio_driver_api = { .port_set_bits_raw = neorv32_gpio_port_set_bits_raw, .port_clear_bits_raw = neorv32_gpio_port_clear_bits_raw, .port_toggle_bits = neorv32_gpio_port_toggle_bits, - .pin_interrupt_configure = neorv32_gpio_pin_interrupt_configure, .manage_callback = neorv32_gpio_manage_callback, .get_pending_int = neorv32_gpio_get_pending_int, }; diff --git a/drivers/gpio/gpio_npm1300.c b/drivers/gpio/gpio_npm1300.c index 37e7f99c936..65c3cdd6fda 100644 --- a/drivers/gpio/gpio_npm1300.c +++ b/drivers/gpio/gpio_npm1300.c @@ -185,17 +185,6 @@ static int gpio_npm1300_port_toggle_bits(const struct device *dev, gpio_port_pin return gpio_npm1300_port_set_masked_raw(dev, pins, ~value); } -static int gpio_npm1300_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static const struct gpio_driver_api gpio_npm1300_api = { .pin_configure = gpio_npm1300_configure, .port_get_raw = gpio_npm1300_port_get_raw, @@ -203,7 +192,6 @@ static const struct gpio_driver_api gpio_npm1300_api = { .port_set_bits_raw = gpio_npm1300_port_set_bits_raw, .port_clear_bits_raw = gpio_npm1300_port_clear_bits_raw, .port_toggle_bits = gpio_npm1300_port_toggle_bits, - .pin_interrupt_configure = gpio_npm1300_pin_interrupt_configure, }; static int gpio_npm1300_init(const struct device *dev) diff --git a/drivers/gpio/gpio_npm6001.c b/drivers/gpio/gpio_npm6001.c index 98bd4db49e0..f722c4275d6 100644 --- a/drivers/gpio/gpio_npm6001.c +++ b/drivers/gpio/gpio_npm6001.c @@ -192,19 +192,6 @@ static int gpio_npm6001_port_toggle_bits(const struct device *dev, ~val & NPM6001_PIN_MSK); } -static int gpio_npm6001_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static const struct gpio_driver_api gpio_npm6001_api = { .pin_configure = gpio_npm6001_configure, .port_get_raw = gpio_npm6001_port_get_raw, @@ -212,7 +199,6 @@ static const struct gpio_driver_api gpio_npm6001_api = { .port_set_bits_raw = gpio_npm6001_port_set_bits_raw, .port_clear_bits_raw = gpio_npm6001_port_clear_bits_raw, .port_toggle_bits = gpio_npm6001_port_toggle_bits, - .pin_interrupt_configure = gpio_npm6001_pin_interrupt_configure, }; static int gpio_npm6001_init(const struct device *dev) diff --git a/drivers/gpio/gpio_nxp_s32.c b/drivers/gpio/gpio_nxp_s32.c index 3bdf9f4599d..de5dbd39dd7 100644 --- a/drivers/gpio/gpio_nxp_s32.c +++ b/drivers/gpio/gpio_nxp_s32.c @@ -205,14 +205,12 @@ static void nxp_s32_gpio_isr(uint8_t pin, void *arg) gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); } -#endif /* CONFIG_NXP_S32_EIRQ */ static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { -#ifdef CONFIG_NXP_S32_EIRQ const struct gpio_nxp_s32_config *config = dev->config; const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; @@ -255,35 +253,18 @@ static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, } return 0; -#else - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -#endif } static int nxp_s32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set) { -#ifdef CONFIG_NXP_S32_EIRQ struct gpio_nxp_s32_data *data = dev->data; return gpio_manage_callback(&data->callbacks, cb, set); -#else - ARG_UNUSED(dev); - ARG_UNUSED(cb); - ARG_UNUSED(set); - - return -ENOTSUP; -#endif } static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) { -#ifdef CONFIG_NXP_S32_EIRQ const struct gpio_nxp_s32_config *config = dev->config; const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; @@ -300,14 +281,8 @@ static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) * that GPIO port belongs to */ return eirq_nxp_s32_get_pending(eirq_info->eirq_dev); - -#else - ARG_UNUSED(dev); - - return -ENOTSUP; -#endif } - +#endif /* CONFIG_NXP_S32_EIRQ */ #ifdef CONFIG_GPIO_GET_CONFIG static int nxp_s32_gpio_pin_get_config(const struct device *dev, @@ -400,9 +375,11 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { .port_set_bits_raw = nxp_s32_gpio_port_set_bits_raw, .port_clear_bits_raw = nxp_s32_gpio_port_clear_bits_raw, .port_toggle_bits = nxp_s32_gpio_port_toggle_bits, +#ifdef CONFIG_NXP_S32_EIRQ .pin_interrupt_configure = nxp_s32_gpio_pin_interrupt_configure, .manage_callback = nxp_s32_gpio_manage_callback, .get_pending_int = nxp_s32_gpio_get_pending_int, +#endif #ifdef CONFIG_GPIO_GET_CONFIG .pin_get_config = nxp_s32_gpio_pin_get_config, #endif diff --git a/drivers/gpio/gpio_pca95xx.c b/drivers/gpio/gpio_pca95xx.c index 66b21fd5b88..f8489128332 100644 --- a/drivers/gpio/gpio_pca95xx.c +++ b/drivers/gpio/gpio_pca95xx.c @@ -644,7 +644,6 @@ static void gpio_pca95xx_interrupt_callback(const struct device *dev, /* Cannot read PCA95xx registers from ISR context, queue worker */ k_work_submit(&drv_data->interrupt_worker); } -#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, @@ -652,13 +651,6 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, enum gpio_int_trig trig) { int ret = 0; - - if (!IS_ENABLED(CONFIG_GPIO_PCA95XX_INTERRUPT) - && (mode != GPIO_INT_MODE_DISABLED)) { - return -ENOTSUP; - } - -#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT const struct gpio_pca95xx_config * const config = dev->config; struct gpio_pca95xx_drv_data * const drv_data = (struct gpio_pca95xx_drv_data * const)dev->data; @@ -742,11 +734,9 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, err: k_sem_give(&drv_data->lock); -#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ return ret; } -#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT static int gpio_pca95xx_manage_callback(const struct device *dev, struct gpio_callback *callback, bool set) @@ -766,7 +756,7 @@ static int gpio_pca95xx_manage_callback(const struct device *dev, k_sem_give(&drv_data->lock); return 0; } -#endif +#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = { .pin_configure = gpio_pca95xx_config, @@ -775,8 +765,8 @@ static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = { .port_set_bits_raw = gpio_pca95xx_port_set_bits_raw, .port_clear_bits_raw = gpio_pca95xx_port_clear_bits_raw, .port_toggle_bits = gpio_pca95xx_port_toggle_bits, - .pin_interrupt_configure = gpio_pca95xx_pin_interrupt_configure, #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT + .pin_interrupt_configure = gpio_pca95xx_pin_interrupt_configure, .manage_callback = gpio_pca95xx_manage_callback, #endif }; diff --git a/drivers/gpio/gpio_sc18im704.c b/drivers/gpio/gpio_sc18im704.c index 96fd56cadb6..c45e9d51a60 100644 --- a/drivers/gpio/gpio_sc18im704.c +++ b/drivers/gpio/gpio_sc18im704.c @@ -239,17 +239,6 @@ static int gpio_sc18im_port_toggle_bits(const struct device *port, gpio_port_pin return gpio_sc18im_port_set_raw(port, 0, 0, (uint8_t)pins); } -static int gpio_sc18im_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - ARG_UNUSED(port); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -} - static int gpio_sc18im_init(const struct device *dev) { const struct gpio_sc18im_config *cfg = dev->config; @@ -272,7 +261,6 @@ static const struct gpio_driver_api gpio_sc18im_driver_api = { .port_set_bits_raw = gpio_sc18im_port_set_bits_raw, .port_clear_bits_raw = gpio_sc18im_port_clear_bits_raw, .port_toggle_bits = gpio_sc18im_port_toggle_bits, - .pin_interrupt_configure = gpio_sc18im_pin_interrupt_configure, }; #define CHECK_COMPAT(node) \ diff --git a/drivers/gpio/gpio_sn74hc595.c b/drivers/gpio/gpio_sn74hc595.c index 38f5de94d38..16eb35bb690 100644 --- a/drivers/gpio/gpio_sn74hc595.c +++ b/drivers/gpio/gpio_sn74hc595.c @@ -134,16 +134,6 @@ static int gpio_sn74hc595_port_toggle_bits(const struct device *dev, uint32_t ma return ret; } -static int gpio_sn74hc595_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, - enum gpio_int_mode mode, enum gpio_int_trig trig) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - return -ENOTSUP; -} - static const struct gpio_driver_api gpio_sn74hc595_drv_api_funcs = { .pin_configure = gpio_sn74hc595_config, .port_get_raw = gpio_sn74hc595_port_get_raw, @@ -151,7 +141,6 @@ static const struct gpio_driver_api gpio_sn74hc595_drv_api_funcs = { .port_set_bits_raw = gpio_sn74hc595_port_set_bits_raw, .port_clear_bits_raw = gpio_sn74hc595_port_clear_bits_raw, .port_toggle_bits = gpio_sn74hc595_port_toggle_bits, - .pin_interrupt_configure = gpio_sn74hc595_pin_interrupt_configure, }; /** diff --git a/drivers/gpio/gpio_stmpe1600.c b/drivers/gpio/gpio_stmpe1600.c index 518b41c7c57..2331fdf9fed 100644 --- a/drivers/gpio/gpio_stmpe1600.c +++ b/drivers/gpio/gpio_stmpe1600.c @@ -249,14 +249,6 @@ static int stmpe1600_port_toggle_bits(const struct device *dev, uint32_t mask) return ret; } -static int stmpe1600_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - static int stmpe1600_init(const struct device *dev) { const struct stmpe1600_config *const config = dev->config; @@ -300,7 +292,6 @@ static const struct gpio_driver_api stmpe1600_drv_api = { .port_set_bits_raw = stmpe1600_port_set_bits_raw, .port_clear_bits_raw = stmpe1600_port_clear_bits_raw, .port_toggle_bits = stmpe1600_port_toggle_bits, - .pin_interrupt_configure = stmpe1600_pin_interrupt_configure, }; #define STMPE1600_INIT(inst) \ diff --git a/drivers/gpio/gpio_sx1509b.c b/drivers/gpio/gpio_sx1509b.c index c62f803e307..b8ecdf4d772 100644 --- a/drivers/gpio/gpio_sx1509b.c +++ b/drivers/gpio/gpio_sx1509b.c @@ -468,6 +468,7 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } +#ifdef CONFIG_GPIO_SX1509B_INTERRUPT static int pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, @@ -475,12 +476,6 @@ static int pin_interrupt_configure(const struct device *dev, { int rc = 0; - if (!IS_ENABLED(CONFIG_GPIO_SX1509B_INTERRUPT) - && (mode != GPIO_INT_MODE_DISABLED)) { - return -ENOTSUP; - } - -#ifdef CONFIG_GPIO_SX1509B_INTERRUPT /* Device does not support level-triggered interrupts. */ if (mode == GPIO_INT_MODE_LEVEL) { return -ENOTSUP; @@ -531,10 +526,10 @@ static int pin_interrupt_configure(const struct device *dev, rc = i2c_write_dt(&cfg->bus, &irq_buf.reg, sizeof(irq_buf)); k_sem_give(&drv_data->lock); -#endif /* CONFIG_GPIO_SX1509B_INTERRUPT */ return rc; } +#endif /* CONFIG_GPIO_SX1509B_INTERRUPT */ /** * @brief Initialization function of SX1509B @@ -647,8 +642,8 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, - .pin_interrupt_configure = pin_interrupt_configure, #ifdef CONFIG_GPIO_SX1509B_INTERRUPT + .pin_interrupt_configure = pin_interrupt_configure, .manage_callback = gpio_sx1509b_manage_callback, #endif }; diff --git a/drivers/gpio/gpio_test.c b/drivers/gpio/gpio_test.c index 192028acac0..3befab37fc2 100644 --- a/drivers/gpio/gpio_test.c +++ b/drivers/gpio/gpio_test.c @@ -63,26 +63,6 @@ static int vnd_gpio_port_toggle_bits(const struct device *port, return -ENOTSUP; } -static int vnd_gpio_pin_interrupt_configure(const struct device *port, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) -{ - return -ENOTSUP; -} - -static int vnd_gpio_manage_callback(const struct device *port, - struct gpio_callback *cb, - bool set) -{ - return -ENOTSUP; -} - -static uint32_t vnd_gpio_get_pending_int(const struct device *dev) -{ - return 0; -} - static const struct gpio_driver_api vnd_gpio_api = { .pin_configure = vnd_gpio_pin_configure, .port_get_raw = vnd_gpio_port_get_raw, @@ -90,9 +70,6 @@ static const struct gpio_driver_api vnd_gpio_api = { .port_set_bits_raw = vnd_gpio_port_set_bits_raw, .port_clear_bits_raw = vnd_gpio_port_clear_bits_raw, .port_toggle_bits = vnd_gpio_port_toggle_bits, - .pin_interrupt_configure = vnd_gpio_pin_interrupt_configure, - .manage_callback = vnd_gpio_manage_callback, - .get_pending_int = vnd_gpio_get_pending_int }; #define VND_GPIO_INIT(n) \ diff --git a/drivers/gpio/gpio_xlnx_axi.c b/drivers/gpio/gpio_xlnx_axi.c index 99e9e350aa2..f070e691e5d 100644 --- a/drivers/gpio/gpio_xlnx_axi.c +++ b/drivers/gpio/gpio_xlnx_axi.c @@ -198,6 +198,7 @@ static int gpio_xlnx_axi_port_toggle_bits(const struct device *dev, gpio_port_pi return 0; } +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) /** * Enables interrupts for the given pins on the channel * The axi gpio can only enable interrupts for an entire port, so we need to track @@ -206,7 +207,6 @@ static int gpio_xlnx_axi_port_toggle_bits(const struct device *dev, gpio_port_pi static int gpio_xlnx_axi_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) const struct gpio_xlnx_axi_config *config = dev->config; struct gpio_xlnx_axi_data *data = dev->data; const uint32_t pin_mask = BIT(pin); @@ -390,9 +390,11 @@ static const struct gpio_driver_api gpio_xlnx_axi_driver_api = { .port_set_bits_raw = gpio_xlnx_axi_port_set_bits_raw, .port_clear_bits_raw = gpio_xlnx_axi_port_clear_bits_raw, .port_toggle_bits = gpio_xlnx_axi_port_toggle_bits, +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) .pin_interrupt_configure = gpio_xlnx_axi_pin_interrupt_configure, .manage_callback = gpio_xlnx_axi_manage_callback, .get_pending_int = gpio_xlnx_axi_get_pending_int, +#endif }; #define GPIO_XLNX_AXI_GPIO2_HAS_COMPAT_STATUS_OKAY(n) \ diff --git a/drivers/gpio/gpio_xmc4xxx.c b/drivers/gpio/gpio_xmc4xxx.c index 29462308481..d90f68d3b32 100644 --- a/drivers/gpio/gpio_xmc4xxx.c +++ b/drivers/gpio/gpio_xmc4xxx.c @@ -117,10 +117,10 @@ static void gpio_xmc4xxx_isr(const struct device *dev, int pin) } #endif +#ifdef CONFIG_XMC4XXX_INTC static int gpio_xmc4xxx_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { -#if defined(CONFIG_XMC4XXX_INTC) const struct gpio_xmc4xxx_config *config = dev->config; int port_id = PORT_TO_PORT_ID(config->port); @@ -132,15 +132,8 @@ static int gpio_xmc4xxx_pin_interrupt_configure(const struct device *dev, gpio_p } else { return -EINVAL; } -#else - ARG_UNUSED(dev); - ARG_UNUSED(pin); - ARG_UNUSED(mode); - ARG_UNUSED(trig); - - return -ENOTSUP; -#endif } +#endif static int gpio_xmc4xxx_get_raw(const struct device *dev, gpio_port_value_t *value) { @@ -215,8 +208,10 @@ static const struct gpio_driver_api gpio_xmc4xxx_driver_api = { .port_set_bits_raw = gpio_xmc4xxx_set_bits_raw, .port_clear_bits_raw = gpio_xmc4xxx_clear_bits_raw, .port_toggle_bits = gpio_xmc4xxx_toggle_bits, +#ifdef CONFIG_XMC4XXX_INTC .pin_interrupt_configure = gpio_xmc4xxx_pin_interrupt_configure, - .manage_callback = IS_ENABLED(CONFIG_XMC4XXX_INTC) ? gpio_xmc4xxx_manage_callback : NULL, + .manage_callback = gpio_xmc4xxx_manage_callback, +#endif }; #define GPIO_XMC4XXX_INIT(index) \ From 2c8dbc4e8b67266cb18f9e1c3ac62e539d1cac23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 14:17:18 +0200 Subject: [PATCH 0117/4498] esp32: samples: Use esp32_devkitc_wroom board instead of esp32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following #58454, fixed a few remaining references to old "virtual" esp32 board. Signed-off-by: Benjamin Cabé --- samples/boards/esp32/deep_sleep/README.rst | 2 +- samples/boards/esp32/light_sleep/README.rst | 2 +- samples/drivers/ipm/ipm_esp32/README.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/boards/esp32/deep_sleep/README.rst b/samples/boards/esp32/deep_sleep/README.rst index 97bf2902dcd..a5de4def742 100644 --- a/samples/boards/esp32/deep_sleep/README.rst +++ b/samples/boards/esp32/deep_sleep/README.rst @@ -51,7 +51,7 @@ Building, Flashing and Running .. zephyr-app-commands:: :zephyr-app: samples/boards/esp32/deep_sleep - :board: esp32 + :board: esp32_devkitc_wroom :goals: build flash :compact: diff --git a/samples/boards/esp32/light_sleep/README.rst b/samples/boards/esp32/light_sleep/README.rst index 3afc3ba82a2..581e9a352b9 100644 --- a/samples/boards/esp32/light_sleep/README.rst +++ b/samples/boards/esp32/light_sleep/README.rst @@ -31,7 +31,7 @@ Building, Flashing and Running .. zephyr-app-commands:: :zephyr-app: samples/boards/esp32/light_sleep - :board: esp32 + :board: esp32_devkitc_wroom :goals: build flash :compact: diff --git a/samples/drivers/ipm/ipm_esp32/README.rst b/samples/drivers/ipm/ipm_esp32/README.rst index 6c1e793baf6..f3501e15910 100644 --- a/samples/drivers/ipm/ipm_esp32/README.rst +++ b/samples/drivers/ipm/ipm_esp32/README.rst @@ -25,7 +25,7 @@ Build the ESP32 IPM sample code as follows: .. zephyr-app-commands:: :zephyr-app: samples/drivers/ipm/ipm_esp32 - :board: esp32 + :board: esp32_devkitc_wroom :goals: build :compact: From c03d0f83c82c8b4900fb7a55818c3baeb98fd317 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 18:35:27 +0000 Subject: [PATCH 0118/4498] drivers: charger: fix i2c_dump_msgs_rw argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: zephyr/drivers/charger/emul_sbs_charger.c:70:26: warning: passing argument 1 of ‘i2c_dump_msgs_rw’ from incompatible pointer type [-Wincompatible-pointer-types] Signed-off-by: Fabio Baltieri --- drivers/charger/emul_sbs_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/charger/emul_sbs_charger.c b/drivers/charger/emul_sbs_charger.c index 35ed3a6f471..34d432c8fbb 100644 --- a/drivers/charger/emul_sbs_charger.c +++ b/drivers/charger/emul_sbs_charger.c @@ -67,7 +67,7 @@ static int sbs_charger_emul_transfer_i2c(const struct emul *target, struct i2c_m data = target->data; - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 2: if (msgs->flags & I2C_MSG_READ) { From 723c4c45dc8149f39bd32366e4821228650d05d3 Mon Sep 17 00:00:00 2001 From: Piotr Zierhoffer Date: Thu, 7 Sep 2023 10:36:33 +0200 Subject: [PATCH 0119/4498] dts/arm/nuvoton: Add compat strings to NPCX SoCs Compat strings in SoCs allow tools to identify hardware described in flattened device trees. Signed-off-by: Piotr Zierhoffer --- dts/arm/nuvoton/npcx/npcx4.dtsi | 2 ++ dts/arm/nuvoton/npcx/npcx7.dtsi | 2 ++ dts/arm/nuvoton/npcx/npcx9.dtsi | 2 ++ 3 files changed, 6 insertions(+) diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index cbad55d0df3..d8c0307c4fd 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -59,6 +59,8 @@ }; soc { + compatible = "nuvoton,npcx4", "nuvoton,npcx", "simple-bus"; + /* Specific soc devices in npcx4 series */ itims: timer@400b0000 { compatible = "nuvoton,npcx-itim-timer"; diff --git a/dts/arm/nuvoton/npcx/npcx7.dtsi b/dts/arm/nuvoton/npcx/npcx7.dtsi index 7181592c84c..cad37d8ca66 100644 --- a/dts/arm/nuvoton/npcx/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7.dtsi @@ -57,6 +57,8 @@ }; soc { + compatible = "nuvoton,npcx7", "nuvoton,npcx", "simple-bus"; + /* Specific soc devices in npcx7 series */ itims: timer@400bc000 { compatible = "nuvoton,npcx-itim-timer"; diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi index 14b74e6c262..6561ba7b6dd 100644 --- a/dts/arm/nuvoton/npcx/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9.dtsi @@ -58,6 +58,8 @@ }; soc { + compatible = "nuvoton,npcx9", "nuvoton,npcx", "simple-bus"; + /* Specific soc devices in npcx9 series */ itims: timer@400b0000 { compatible = "nuvoton,npcx-itim-timer"; From c9c6676bddca89deb88d0dd5af2946772b46aa5a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 4 Sep 2023 09:35:57 +0200 Subject: [PATCH 0120/4498] doc: sys: atomic: improve bitset accessor doc Removes an ambivalence in return value description. Signed-off-by: Florian Grandel --- include/zephyr/sys/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sys/atomic.h b/include/zephyr/sys/atomic.h index 2521a6fff98..bcb122bf38a 100644 --- a/include/zephyr/sys/atomic.h +++ b/include/zephyr/sys/atomic.h @@ -147,7 +147,7 @@ static inline bool atomic_test_bit(const atomic_t *target, int bit) * @param target Address of atomic variable or array. * @param bit Bit number (starting from 0). * - * @return true if the bit was set, false if it wasn't. + * @return false if the bit was already cleared, true if it wasn't. */ static inline bool atomic_test_and_clear_bit(atomic_t *target, int bit) { @@ -171,7 +171,7 @@ static inline bool atomic_test_and_clear_bit(atomic_t *target, int bit) * @param target Address of atomic variable or array. * @param bit Bit number (starting from 0). * - * @return true if the bit was set, false if it wasn't. + * @return true if the bit was already set, false if it wasn't. */ static inline bool atomic_test_and_set_bit(atomic_t *target, int bit) { From f7e5a103b66aa04e2c56354947ed836ba0e5e608 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 4 Sep 2023 09:34:05 +0200 Subject: [PATCH 0121/4498] drivers: serial: uart_cc13xx_cc26xx: fix race Fixing a race in tx/rx_constrained flag access. Signed-off-by: Florian Grandel --- drivers/serial/uart_cc13xx_cc26xx.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/serial/uart_cc13xx_cc26xx.c b/drivers/serial/uart_cc13xx_cc26xx.c index f47fdd0bbc9..e5bbf40b394 100644 --- a/drivers/serial/uart_cc13xx_cc26xx.c +++ b/drivers/serial/uart_cc13xx_cc26xx.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,12 @@ struct uart_cc13xx_cc26xx_config { uint32_t sys_clk_freq; }; +enum uart_cc13xx_cc26xx_pm_locks { + UART_CC13XX_CC26XX_PM_LOCK_TX, + UART_CC13XX_CC26XX_PM_LOCK_RX, + UART_CC13XX_CC26XX_PM_LOCK_COUNT, +}; + struct uart_cc13xx_cc26xx_data { struct uart_config uart_config; const struct pinctrl_dev_config *pcfg; @@ -35,8 +42,7 @@ struct uart_cc13xx_cc26xx_data { #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_PM Power_NotifyObj postNotify; - bool tx_constrained; - bool rx_constrained; + ATOMIC_DEFINE(pm_lock, UART_CC13XX_CC26XX_PM_LOCK_COUNT); #endif }; @@ -240,7 +246,7 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (!data->tx_constrained) { + if (!atomic_test_and_set_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX)) { /* * When tx irq is enabled, it is implicit that we are expecting * to transmit using the uart, hence we should no longer go @@ -252,7 +258,6 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev) * would interfere with a transfer. */ pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->tx_constrained = true; } #endif @@ -268,9 +273,8 @@ static void uart_cc13xx_cc26xx_irq_tx_disable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (data->tx_constrained) { + if (atomic_test_and_clear_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX)) { pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->tx_constrained = false; } #endif } @@ -294,9 +298,8 @@ static void uart_cc13xx_cc26xx_irq_rx_enable(const struct device *dev) * to receive from the uart, hence we can no longer go into * standby. */ - if (!data->rx_constrained) { + if (!atomic_test_and_set_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX)) { pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->rx_constrained = true; } #endif @@ -310,9 +313,8 @@ static void uart_cc13xx_cc26xx_irq_rx_disable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (data->rx_constrained) { + if (atomic_test_and_clear_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX)) { pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->rx_constrained = false; } #endif @@ -497,8 +499,8 @@ static const struct uart_driver_api uart_cc13xx_cc26xx_driver_api = { do { \ struct uart_cc13xx_cc26xx_data *dev_data = dev->data; \ \ - dev_data->rx_constrained = false; \ - dev_data->tx_constrained = false; \ + atomic_clear_bit(dev_data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX); \ + atomic_clear_bit(dev_data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX); \ \ /* Set Power dependencies */ \ if (DT_INST_REG_ADDR(n) == 0x40001000) { \ From 7140b6f9c10ee2f9583529ab648fe11aa59d7d91 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 18:29:15 +0000 Subject: [PATCH 0122/4498] modules: lvgl: initialize lvgl_heap_init from lvgl_init Call lvgl_heap_init from lvgl_init rather than using two separate SYS_INIT, this sensures that the heap is initialized correctly regardless of the relation between CONFIG_KERNEL_INIT_PRIORITY_DEFAULT and CONFIG_APPLICATION_INIT_PRIORITY. Signed-off-by: Fabio Baltieri --- modules/lvgl/lvgl.c | 8 +++++++- modules/lvgl/lvgl_mem.c | 5 +---- modules/lvgl/lvgl_mem.h | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/lvgl/lvgl.c b/modules/lvgl/lvgl.c index 46c575e2245..ec242924e0a 100644 --- a/modules/lvgl/lvgl.c +++ b/modules/lvgl/lvgl.c @@ -11,6 +11,9 @@ #ifdef CONFIG_LV_Z_USE_FILESYSTEM #include "lvgl_fs.h" #endif +#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP +#include "lvgl_mem.h" +#endif #include LV_MEM_CUSTOM_INCLUDE #define LOG_LEVEL CONFIG_LV_LOG_LEVEL @@ -190,7 +193,6 @@ static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver) static int lvgl_init(void) { - const struct device *display_dev = DEVICE_DT_GET(DISPLAY_NODE); int err = 0; @@ -200,6 +202,10 @@ static int lvgl_init(void) return -ENODEV; } +#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP + lvgl_heap_init(); +#endif + #if CONFIG_LV_LOG_LEVEL != 0 lv_log_register_print_cb(lvgl_log); #endif diff --git a/modules/lvgl/lvgl_mem.c b/modules/lvgl/lvgl_mem.c index f41ede520cb..ab6c912847f 100644 --- a/modules/lvgl/lvgl_mem.c +++ b/modules/lvgl/lvgl_mem.c @@ -58,10 +58,7 @@ void lvgl_print_heap_info(bool dump_chunks) k_spin_unlock(&lvgl_heap_lock, key); } -static int lvgl_heap_init(void) +void lvgl_heap_init(void) { sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], HEAP_BYTES); - return 0; } - -SYS_INIT(lvgl_heap_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/modules/lvgl/lvgl_mem.h b/modules/lvgl/lvgl_mem.h index 7e66581c0ff..02dea4537a0 100644 --- a/modules/lvgl/lvgl_mem.h +++ b/modules/lvgl/lvgl_mem.h @@ -22,6 +22,8 @@ void lvgl_free(void *ptr); void lvgl_print_heap_info(bool dump_chunks); +void lvgl_heap_init(void); + #ifdef __cplusplus } #endif From c26679be4223ae4f3c0e8866069425b84884488a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 23:14:13 +0200 Subject: [PATCH 0123/4498] samples: net: cloud: drop Google Cloud IoT Core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google Cloud IoT Core has been retired on August 16, 2023. Removed the sample and the link to it in a previous release note. Added a redirect to other IoT cloud samples. Signed-off-by: Benjamin Cabé --- doc/_scripts/redirects.py | 1 + doc/releases/release-notes-1.14.rst | 2 +- .../net/cloud/google_iot_mqtt/CMakeLists.txt | 20 - samples/net/cloud/google_iot_mqtt/Kconfig | 33 -- samples/net/cloud/google_iot_mqtt/README.rst | 64 --- samples/net/cloud/google_iot_mqtt/prj.conf | 64 --- samples/net/cloud/google_iot_mqtt/sample.yaml | 19 - samples/net/cloud/google_iot_mqtt/src/dhcp.c | 66 --- samples/net/cloud/google_iot_mqtt/src/dhcp.h | 14 - .../cloud/google_iot_mqtt/src/globalsign.inc | 107 ----- samples/net/cloud/google_iot_mqtt/src/main.c | 79 ---- .../src/private_info/.gitignore | 4 - .../src/private_info/create_keys.py | 116 ----- .../src/private_info/test_key.c | 112 ----- .../net/cloud/google_iot_mqtt/src/protocol.c | 407 ------------------ .../net/cloud/google_iot_mqtt/src/protocol.h | 18 - .../src/tls_config/user-tls-conf.h | 5 - 17 files changed, 2 insertions(+), 1129 deletions(-) delete mode 100644 samples/net/cloud/google_iot_mqtt/CMakeLists.txt delete mode 100644 samples/net/cloud/google_iot_mqtt/Kconfig delete mode 100644 samples/net/cloud/google_iot_mqtt/README.rst delete mode 100644 samples/net/cloud/google_iot_mqtt/prj.conf delete mode 100644 samples/net/cloud/google_iot_mqtt/sample.yaml delete mode 100644 samples/net/cloud/google_iot_mqtt/src/dhcp.c delete mode 100644 samples/net/cloud/google_iot_mqtt/src/dhcp.h delete mode 100644 samples/net/cloud/google_iot_mqtt/src/globalsign.inc delete mode 100644 samples/net/cloud/google_iot_mqtt/src/main.c delete mode 100644 samples/net/cloud/google_iot_mqtt/src/private_info/.gitignore delete mode 100755 samples/net/cloud/google_iot_mqtt/src/private_info/create_keys.py delete mode 100644 samples/net/cloud/google_iot_mqtt/src/private_info/test_key.c delete mode 100644 samples/net/cloud/google_iot_mqtt/src/protocol.c delete mode 100644 samples/net/cloud/google_iot_mqtt/src/protocol.h delete mode 100644 samples/net/cloud/google_iot_mqtt/src/tls_config/user-tls-conf.h diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index 6b4825c6c91..8c9120e9899 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -163,4 +163,5 @@ ('reference/usermode/overview', 'kernel/usermode/overview'), ('reference/usermode/syscalls', 'kernel/usermode/syscalls'), ('reference/util/index', 'kernel/util/index'), + ('samples/net/cloud/google_iot_mqtt', 'samples/net/cloud'), ] diff --git a/doc/releases/release-notes-1.14.rst b/doc/releases/release-notes-1.14.rst index d7d14a8499e..32393436194 100644 --- a/doc/releases/release-notes-1.14.rst +++ b/doc/releases/release-notes-1.14.rst @@ -858,7 +858,7 @@ Networking * Added support for SOCKS5 proxy in MQTT client. * Added support for IPSO Timer object in LWM2M. * Added support for receiving gratuitous ARP request. -* Added :ref:`sample application ` for Google IoT Cloud. +* Added sample application for Google IoT Cloud. * :ref:`Network interface ` numbering starts now from 1 for POSIX compatibility. * :ref:`OpenThread ` enhancements. diff --git a/samples/net/cloud/google_iot_mqtt/CMakeLists.txt b/samples/net/cloud/google_iot_mqtt/CMakeLists.txt deleted file mode 100644 index 6fd930b57ec..00000000000 --- a/samples/net/cloud/google_iot_mqtt/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(google_iot_mqtt) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) -zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/tls_config) - -if(USE_DUMMY_KEY) - target_sources(app PRIVATE ${APPLICATION_SOURCE_DIR}/src/private_info/test_key.c) -else() - if(NOT EXISTS ${APPLICATION_SOURCE_DIR}/src/private_info/key.c) - message(FATAL_ERROR "!!!!!! Generate key file before continuing. See README !!!!!") - endif() - - target_sources(app PRIVATE ${APPLICATION_SOURCE_DIR}/src/private_info/key.c) -endif() diff --git a/samples/net/cloud/google_iot_mqtt/Kconfig b/samples/net/cloud/google_iot_mqtt/Kconfig deleted file mode 100644 index 5bcba2e2d19..00000000000 --- a/samples/net/cloud/google_iot_mqtt/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -# Private config options for Google Cloud IOT application - -# Copyright (c) 2018 Linaro -# SPDX-License-Identifier: Apache-2.0 - -mainmenu "Google IOT MQTT/TLS sample application" - -config CLOUD_CLIENT_ID - string "Client ID string" - default "put client string here" - help - Set required client string that matches Google Cloud project - -config CLOUD_AUDIENCE - string "Audience string" - default "put audience string here" - help - Set required audience string that matches Google Cloud project - -config CLOUD_SUBSCRIBE_CONFIG - string "Subscription string for config" - default "put subscription string here" - help - Set required subscription string that matches Google Cloud project - config item. - -config CLOUD_PUBLISH_TOPIC - string "Publish topic string" - default "put topic string here" - help - Set publish topics string that matches Google Cloud project - -source "Kconfig.zephyr" diff --git a/samples/net/cloud/google_iot_mqtt/README.rst b/samples/net/cloud/google_iot_mqtt/README.rst deleted file mode 100644 index e82736f4c0c..00000000000 --- a/samples/net/cloud/google_iot_mqtt/README.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _google-iot-mqtt-sample: - -Google IOT MQTT Sample -###################### - -Overview -******** - -This sample application demonstrates a "full stack" application. This -currently is able to - -- Acquire a DHCPv4 lease. -- Connect to an SNTP server and acquire current time -- Establish a TLS connection with the Google IOT Cloud servers -- Publish data to the Google IOT Cloud -- Send/Receive keep alive / pings from cloud server - -The source code for this sample application can be found at: -:zephyr_file:`samples/net/cloud/google_iot_mqtt`. - -Requirements -************ -- Entropy source -- Google IOT Cloud account -- Google IOT Cloud credentials and required information -- Network connectivity - -Building and Running -******************** -This application has been built and tested on the NXP FRDMK64F. RSA or -ECDSA certs/keys are required to authenticate to the Google IOT Cloud. -The application includes a key creation script. - -Run the ``create_keys.py`` script in the -``samples/net/cloud/google_iot_mqtt/src/private_info/`` directory. -Be sure that they key type generated (RSA or ECDSA) matches your -config of either :code:`JWT_SIGN_RSA` or :code:`JWT_SIGN_ECDSA`. - -Users will also be required to configure the following Kconfig options -based on their Google Cloud IOT project. The following values come -from the Google Cloud Platform itself: - -- PROJECT_ID: When you select your project at the top of the UI, it - should have a "name", and there should be an ID field as well. This - seems to be two words and a number, separated by hyphens. -- REGION: The Region shows in the list of registries for your - registry. And example is "us-central1". -- REGISTRY_ID: Each registry has an id. This is a string given when - creating the registry. -- DEVICE_ID: A name given for each device. When viewing the table of - devices, this will be shown. - -From these values, the config values can be set using the following -template: - -.. code-block:: kconfig - - CLOUD_CLIENT_ID="projects/PROJECT_ID/locations/REGION/registries/REGISTRY_ID/devices/DEVICE_ID" - CLOUD_AUDIENCE="PROJECT_ID" - CLOUD_SUBSCRIBE_CONFIG="/devices/DEVICE_ID/config" - CLOUD_PUBLISH_TOPIC="/devices/DEVICE_ID/state" - -See `Google Cloud MQTT Documentation -`_. diff --git a/samples/net/cloud/google_iot_mqtt/prj.conf b/samples/net/cloud/google_iot_mqtt/prj.conf deleted file mode 100644 index 6abb2eb7061..00000000000 --- a/samples/net/cloud/google_iot_mqtt/prj.conf +++ /dev/null @@ -1,64 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NET_IPV6=n -CONFIG_NET_IPV4=y -CONFIG_NET_UDP=y -CONFIG_NET_TCP=y -CONFIG_NET_DHCPV4=y -CONFIG_STDOUT_CONSOLE=y - -CONFIG_NET_PKT_RX_COUNT=4 -CONFIG_NET_PKT_TX_COUNT=4 -CONFIG_NET_BUF_RX_COUNT=12 -CONFIG_NET_BUF_TX_COUNT=12 - -CONFIG_INIT_STACKS=y - -CONFIG_JWT=y -CONFIG_JWT_SIGN_ECDSA=y - -CONFIG_NET_MGMT=y -CONFIG_NET_MGMT_EVENT=y - -CONFIG_LOG=y - -# This shouldn't need to be set, but isn't selected properly. -CONFIG_NEWLIB_LIBC=y - -CONFIG_DNS_SERVER_IP_ADDRESSES=y -CONFIG_DNS_SERVER1="8.8.8.8" - -CONFIG_DNS_RESOLVER=y -CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2 -CONFIG_SNTP=y - -CONFIG_SLIP_STATISTICS=n - -CONFIG_HW_STACK_PROTECTION=y -CONFIG_MAIN_STACK_SIZE=4096 - -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 - -CONFIG_PTHREAD_IPC=n -CONFIG_NET_SOCKETS=y -CONFIG_MQTT_LIB=y -CONFIG_MQTT_LIB_TLS=y -CONFIG_NET_SOCKETS_SOCKOPT_TLS=y - - -# Enable MBEDTLS -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_BUILTIN=y - -CONFIG_NET_SOCKETS_POSIX_NAMES=y - -CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=56240 -CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y -CONFIG_MBEDTLS_USER_CONFIG_FILE="user-tls-conf.h" - -# Please see README.rst in this directory for instructions -# on where to get the values for these config entries. -CONFIG_CLOUD_CLIENT_ID="projects//locations//registries//devices/" -CONFIG_CLOUD_AUDIENCE="" -CONFIG_CLOUD_SUBSCRIBE_CONFIG="/devices//config" -CONFIG_CLOUD_PUBLISH_TOPIC="/devices//state" diff --git a/samples/net/cloud/google_iot_mqtt/sample.yaml b/samples/net/cloud/google_iot_mqtt/sample.yaml deleted file mode 100644 index 25830576aed..00000000000 --- a/samples/net/cloud/google_iot_mqtt/sample.yaml +++ /dev/null @@ -1,19 +0,0 @@ -sample: - description: MQTT sample app to Google IoT cloud - name: google_iot_mqtt -common: - tags: - - net - - mqtt - - cloud - harness: net - filter: TOOLCHAIN_HAS_NEWLIB == 1 - extra_args: USE_DUMMY_KEY=1 -tests: - sample.net.cloud.google_iot_mqtt: - depends_on: netif - platform_allow: - - frdm_k64f - - qemu_x86 - integration_platforms: - - qemu_x86 diff --git a/samples/net/cloud/google_iot_mqtt/src/dhcp.c b/samples/net/cloud/google_iot_mqtt/src/dhcp.c deleted file mode 100644 index bc06cb424b2..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/dhcp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* DHCPv4 client startup. */ - -/* - * Copyright (c) 2018 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -LOG_MODULE_DECLARE(net_google_iot_mqtt, LOG_LEVEL_DBG); - -#include - -#include -#include -#include -#include - -static struct net_mgmt_event_callback mgmt_cb; - -/* Semaphore to indicate a lease has been acquired. */ -static K_SEM_DEFINE(got_address, 0, 1); - -static void handler(struct net_mgmt_event_callback *cb, - uint32_t mgmt_event, - struct net_if *iface) -{ - int i; - bool notified = false; - - if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) { - return; - } - - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - - if (iface->config.ip.ipv4->unicast[i].addr_type != - NET_ADDR_DHCP) { - continue; - } - - if (!notified) { - k_sem_give(&got_address); - notified = true; - } - break; - } -} - -/** - * Start a DHCP client, and wait for a lease to be acquired. - */ -void app_dhcpv4_startup(void) -{ - LOG_INF("starting DHCPv4"); - - net_mgmt_init_event_callback(&mgmt_cb, handler, - NET_EVENT_IPV4_ADDR_ADD); - net_mgmt_add_event_callback(&mgmt_cb); - - net_dhcpv4_start(net_if_get_default()); - - /* Wait for a lease. */ - k_sem_take(&got_address, K_FOREVER); -} diff --git a/samples/net/cloud/google_iot_mqtt/src/dhcp.h b/samples/net/cloud/google_iot_mqtt/src/dhcp.h deleted file mode 100644 index 3760d46c5f7..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/dhcp.h +++ /dev/null @@ -1,14 +0,0 @@ -/* DHCPv4 client startup. */ - -/* - * Copyright (c) 2018 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __DHCP_H__ -#define __DHCP_H__ - -void app_dhcpv4_startup(void); - -#endif /* not __DHCP_H__ */ diff --git a/samples/net/cloud/google_iot_mqtt/src/globalsign.inc b/samples/net/cloud/google_iot_mqtt/src/globalsign.inc deleted file mode 100644 index e1424bc483b..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/globalsign.inc +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - * - * vim: ft=c - * - * Generated from downloading GlobalSign Root Certificate R2 from - * https://aboutssl.org/globalsign-root-certificates-licensing-and-use/ - * and extracting the following information using openssl: - * - * openssl x509 -in GlobalSign_Root_CA_-_R2.pem -inform pem -noout -C - */ -/* subject:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ -/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ -/* -unsigned char XXX_subject_name[78]={ -0x30,0x4C,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F, -0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20, -0x2D,0x20,0x52,0x32,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47, -0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55, -0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -}; -unsigned char XXX_public_key[294]={ -0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01, -0x00,0xA6,0xCF,0x24,0x0E,0xBE,0x2E,0x6F,0x28,0x99,0x45,0x42,0xC4,0xAB,0x3E,0x21, -0x54,0x9B,0x0B,0xD3,0x7F,0x84,0x70,0xFA,0x12,0xB3,0xCB,0xBF,0x87,0x5F,0xC6,0x7F, -0x86,0xD3,0xB2,0x30,0x5C,0xD6,0xFD,0xAD,0xF1,0x7B,0xDC,0xE5,0xF8,0x60,0x96,0x09, -0x92,0x10,0xF5,0xD0,0x53,0xDE,0xFB,0x7B,0x7E,0x73,0x88,0xAC,0x52,0x88,0x7B,0x4A, -0xA6,0xCA,0x49,0xA6,0x5E,0xA8,0xA7,0x8C,0x5A,0x11,0xBC,0x7A,0x82,0xEB,0xBE,0x8C, -0xE9,0xB3,0xAC,0x96,0x25,0x07,0x97,0x4A,0x99,0x2A,0x07,0x2F,0xB4,0x1E,0x77,0xBF, -0x8A,0x0F,0xB5,0x02,0x7C,0x1B,0x96,0xB8,0xC5,0xB9,0x3A,0x2C,0xBC,0xD6,0x12,0xB9, -0xEB,0x59,0x7D,0xE2,0xD0,0x06,0x86,0x5F,0x5E,0x49,0x6A,0xB5,0x39,0x5E,0x88,0x34, -0xEC,0xBC,0x78,0x0C,0x08,0x98,0x84,0x6C,0xA8,0xCD,0x4B,0xB4,0xA0,0x7D,0x0C,0x79, -0x4D,0xF0,0xB8,0x2D,0xCB,0x21,0xCA,0xD5,0x6C,0x5B,0x7D,0xE1,0xA0,0x29,0x84,0xA1, -0xF9,0xD3,0x94,0x49,0xCB,0x24,0x62,0x91,0x20,0xBC,0xDD,0x0B,0xD5,0xD9,0xCC,0xF9, -0xEA,0x27,0x0A,0x2B,0x73,0x91,0xC6,0x9D,0x1B,0xAC,0xC8,0xCB,0xE8,0xE0,0xA0,0xF4, -0x2F,0x90,0x8B,0x4D,0xFB,0xB0,0x36,0x1B,0xF6,0x19,0x7A,0x85,0xE0,0x6D,0xF2,0x61, -0x13,0x88,0x5C,0x9F,0xE0,0x93,0x0A,0x51,0x97,0x8A,0x5A,0xCE,0xAF,0xAB,0xD5,0xF7, -0xAA,0x09,0xAA,0x60,0xBD,0xDC,0xD9,0x5F,0xDF,0x72,0xA9,0x60,0x13,0x5E,0x00,0x01, -0xC9,0x4A,0xFA,0x3F,0xA4,0xEA,0x07,0x03,0x21,0x02,0x8E,0x82,0xCA,0x03,0xC2,0x9B, -0x8F,0x02,0x03,0x01,0x00,0x01, -}; -*/ -unsigned char globalsign_certificate[958]={ -0x30,0x82,0x03,0xBA,0x30,0x82,0x02,0xA2,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x04, -0x00,0x00,0x00,0x00,0x01,0x0F,0x86,0x26,0xE6,0x0D,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06, -0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,0x13,0x30, -0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69, -0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F, -0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x31, -0x35,0x30,0x38,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32,0x31,0x35, -0x30,0x38,0x30,0x30,0x30,0x30,0x5A,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06,0x03,0x55, -0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52, -0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,0x13,0x30,0x11,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61, -0x6C,0x53,0x69,0x67,0x6E,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01, -0x0A,0x02,0x82,0x01,0x01,0x00,0xA6,0xCF,0x24,0x0E,0xBE,0x2E,0x6F,0x28,0x99,0x45, -0x42,0xC4,0xAB,0x3E,0x21,0x54,0x9B,0x0B,0xD3,0x7F,0x84,0x70,0xFA,0x12,0xB3,0xCB, -0xBF,0x87,0x5F,0xC6,0x7F,0x86,0xD3,0xB2,0x30,0x5C,0xD6,0xFD,0xAD,0xF1,0x7B,0xDC, -0xE5,0xF8,0x60,0x96,0x09,0x92,0x10,0xF5,0xD0,0x53,0xDE,0xFB,0x7B,0x7E,0x73,0x88, -0xAC,0x52,0x88,0x7B,0x4A,0xA6,0xCA,0x49,0xA6,0x5E,0xA8,0xA7,0x8C,0x5A,0x11,0xBC, -0x7A,0x82,0xEB,0xBE,0x8C,0xE9,0xB3,0xAC,0x96,0x25,0x07,0x97,0x4A,0x99,0x2A,0x07, -0x2F,0xB4,0x1E,0x77,0xBF,0x8A,0x0F,0xB5,0x02,0x7C,0x1B,0x96,0xB8,0xC5,0xB9,0x3A, -0x2C,0xBC,0xD6,0x12,0xB9,0xEB,0x59,0x7D,0xE2,0xD0,0x06,0x86,0x5F,0x5E,0x49,0x6A, -0xB5,0x39,0x5E,0x88,0x34,0xEC,0xBC,0x78,0x0C,0x08,0x98,0x84,0x6C,0xA8,0xCD,0x4B, -0xB4,0xA0,0x7D,0x0C,0x79,0x4D,0xF0,0xB8,0x2D,0xCB,0x21,0xCA,0xD5,0x6C,0x5B,0x7D, -0xE1,0xA0,0x29,0x84,0xA1,0xF9,0xD3,0x94,0x49,0xCB,0x24,0x62,0x91,0x20,0xBC,0xDD, -0x0B,0xD5,0xD9,0xCC,0xF9,0xEA,0x27,0x0A,0x2B,0x73,0x91,0xC6,0x9D,0x1B,0xAC,0xC8, -0xCB,0xE8,0xE0,0xA0,0xF4,0x2F,0x90,0x8B,0x4D,0xFB,0xB0,0x36,0x1B,0xF6,0x19,0x7A, -0x85,0xE0,0x6D,0xF2,0x61,0x13,0x88,0x5C,0x9F,0xE0,0x93,0x0A,0x51,0x97,0x8A,0x5A, -0xCE,0xAF,0xAB,0xD5,0xF7,0xAA,0x09,0xAA,0x60,0xBD,0xDC,0xD9,0x5F,0xDF,0x72,0xA9, -0x60,0x13,0x5E,0x00,0x01,0xC9,0x4A,0xFA,0x3F,0xA4,0xEA,0x07,0x03,0x21,0x02,0x8E, -0x82,0xCA,0x03,0xC2,0x9B,0x8F,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9C,0x30,0x81, -0x99,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9B,0xE2,0x07, -0x57,0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86, -0x2E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29, -0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x67, -0x6C,0x6F,0x62,0x61,0x6C,0x73,0x69,0x67,0x6E,0x2E,0x6E,0x65,0x74,0x2F,0x72,0x6F, -0x6F,0x74,0x2D,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, -0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57,0x67,0x1C,0x1E,0xC0,0x6A,0x06, -0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x99,0x81, -0x53,0x87,0x1C,0x68,0x97,0x86,0x91,0xEC,0xE0,0x4A,0xB8,0x44,0x0B,0xAB,0x81,0xAC, -0x27,0x4F,0xD6,0xC1,0xB8,0x1C,0x43,0x78,0xB3,0x0C,0x9A,0xFC,0xEA,0x2C,0x3C,0x6E, -0x61,0x1B,0x4D,0x4B,0x29,0xF5,0x9F,0x05,0x1D,0x26,0xC1,0xB8,0xE9,0x83,0x00,0x62, -0x45,0xB6,0xA9,0x08,0x93,0xB9,0xA9,0x33,0x4B,0x18,0x9A,0xC2,0xF8,0x87,0x88,0x4E, -0xDB,0xDD,0x71,0x34,0x1A,0xC1,0x54,0xDA,0x46,0x3F,0xE0,0xD3,0x2A,0xAB,0x6D,0x54, -0x22,0xF5,0x3A,0x62,0xCD,0x20,0x6F,0xBA,0x29,0x89,0xD7,0xDD,0x91,0xEE,0xD3,0x5C, -0xA2,0x3E,0xA1,0x5B,0x41,0xF5,0xDF,0xE5,0x64,0x43,0x2D,0xE9,0xD5,0x39,0xAB,0xD2, -0xA2,0xDF,0xB7,0x8B,0xD0,0xC0,0x80,0x19,0x1C,0x45,0xC0,0x2D,0x8C,0xE8,0xF8,0x2D, -0xA4,0x74,0x56,0x49,0xC5,0x05,0xB5,0x4F,0x15,0xDE,0x6E,0x44,0x78,0x39,0x87,0xA8, -0x7E,0xBB,0xF3,0x79,0x18,0x91,0xBB,0xF4,0x6F,0x9D,0xC1,0xF0,0x8C,0x35,0x8C,0x5D, -0x01,0xFB,0xC3,0x6D,0xB9,0xEF,0x44,0x6D,0x79,0x46,0x31,0x7E,0x0A,0xFE,0xA9,0x82, -0xC1,0xFF,0xEF,0xAB,0x6E,0x20,0xC4,0x50,0xC9,0x5F,0x9D,0x4D,0x9B,0x17,0x8C,0x0C, -0xE5,0x01,0xC9,0xA0,0x41,0x6A,0x73,0x53,0xFA,0xA5,0x50,0xB4,0x6E,0x25,0x0F,0xFB, -0x4C,0x18,0xF4,0xFD,0x52,0xD9,0x8E,0x69,0xB1,0xE8,0x11,0x0F,0xDE,0x88,0xD8,0xFB, -0x1D,0x49,0xF7,0xAA,0xDE,0x95,0xCF,0x20,0x78,0xC2,0x60,0x12,0xDB,0x25,0x40,0x8C, -0x6A,0xFC,0x7E,0x42,0x38,0x40,0x64,0x12,0xF7,0x9E,0x81,0xE1,0x93,0x2E, -}; diff --git a/samples/net/cloud/google_iot_mqtt/src/main.c b/samples/net/cloud/google_iot_mqtt/src/main.c deleted file mode 100644 index 1cd93febf1a..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/main.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Full-stack IoT client example. */ - -/* - * Copyright (c) 2018 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "dhcp.h" -#include "protocol.h" - -#include -#include -#include - -#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL -#include - -LOG_MODULE_REGISTER(net_google_iot_mqtt, LOG_LEVEL_INF); - -/* This comes from newlib. */ -#include -#include - -int64_t time_base; - -int do_sntp(void) -{ - int rc; - struct sntp_time sntp_time; - char time_str[sizeof("1970-01-01T00:00:00")]; - - LOG_INF("Sending NTP request for current time:"); - - rc = sntp_simple("time.google.com", SYS_FOREVER_MS, &sntp_time); - if (rc == 0) { - time_base = sntp_time.seconds * MSEC_PER_SEC - k_uptime_get(); - - /* Convert time to make sure. */ - time_t now = sntp_time.seconds; - struct tm now_tm; - - gmtime_r(&now, &now_tm); - strftime(time_str, sizeof(time_str), "%FT%T", &now_tm); - LOG_INF(" Acquired time: %s", time_str); - - } else { - LOG_ERR(" Failed to acquire SNTP, code %d\n", rc); - } - return rc; -} - -/* - * Things that make sense in a demo app that would need to be more - * robust in a real application: - * - * - DHCP happens once. If it fails, or we change networks, the - * network will just stop working. - * - */ -int main(void) -{ - LOG_INF("Main entered"); - - app_dhcpv4_startup(); - - LOG_INF("Should have DHCPv4 lease at this point."); - - /* early return if we failed to acquire time */ - if (do_sntp() != 0) { - LOG_ERR("Failed to get NTP time"); - return 0; - } - - mqtt_startup("mqtt.googleapis.com", 8883); - return 0; -} diff --git a/samples/net/cloud/google_iot_mqtt/src/private_info/.gitignore b/samples/net/cloud/google_iot_mqtt/src/private_info/.gitignore deleted file mode 100644 index 29bda8c1ec4..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/private_info/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*-cert.pem -*-private.pem -*.der -key.c diff --git a/samples/net/cloud/google_iot_mqtt/src/private_info/create_keys.py b/samples/net/cloud/google_iot_mqtt/src/private_info/create_keys.py deleted file mode 100755 index cb0fbeb3bd2..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/private_info/create_keys.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2018 Linaro -# -# SPDX-License-Identifier: Apache-2.0 - -import sys -import subprocess -import argparse - -def parse_args(): - global args - - parser = argparse.ArgumentParser(description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) - - parser.add_argument( - "-d", "--device", required=True, - help="Name of device") - - parser.add_argument( - "-e", "--ecdsa", required=False, - action='store_true', - help="Use elliptic curve") - - parser.add_argument( - "-r", "--rsa", required=False, - action='store_true', - help="Use RSA") - - args = parser.parse_args() - -split_string = lambda x, n: [x[i:i+n] for i in range(0, len(x), n)] - -def main(): - parse_args() - - fd = open("key.c", "w") - - pem_file = args.device + "-private.pem" - cert_file = args.device + "-cert.pem" - der_file = args.device + "-private.der" - - if args.ecdsa: - print("Generating ecdsa private key") - try: - subprocess.call(["openssl", "ecparam", "-noout", "-name", "prime256v1", "-genkey", - "-out", pem_file]) - - except subprocess.CalledProcessError as e: - print(e.output) - else: - print("Generating rsa private key") - try: - subprocess.call(["openssl", "genrsa", "-out", pem_file, "2048"]) - - except subprocess.CalledProcessError as e: - print(e.output) - - print("Generating certificate") - - try: - subprocess.check_call(["openssl", "req", "-new", "-x509", "-key", pem_file, "-out", - cert_file, "-days", "1000000", "-subj", "/CN=" + args.device]) - - except subprocess.CalledProcessError as e: - print(e.output) - - - if args.ecdsa: - print("Parsing ECDSA private key") - o = subprocess.Popen(["openssl", "asn1parse", "-in", pem_file, - "-offset", "5", "-length", "34"], stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - - if o.returncode == 0: - sys.exit("failed to parse ECDSA private key") - - tmp = o.communicate()[0].decode('ascii').split(":")[3].lower().strip() - - if o.returncode: - sys.exit("failed to parse ECDSA private key") - - tmp = split_string(tmp, 2) - output = ["0x" + s for s in tmp] - output = ', '.join(output) - - else: - print("Parsing RSA private key and generating DER output") - try: - subprocess.call(["openssl", "pkcs8", "-nocrypt", "-topk8", - "-inform", "pem", "-outform", "der", "-in", pem_file, "-out", - der_file]) - - except subprocess.CalledProcessError as e: - print(e.output) - - der_fd = open(der_file, "r") - o = subprocess.Popen(["xxd", "-i"], stdin=der_fd, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - - output = o.communicate()[0].decode('ascii') - - if o.returncode: - sys.exit("failed to parse RSA private key") - - print("Generating key.c") - fd.write("unsigned char zepfull_private_der[] = {\n") - key_len = len(output.split(',')) - fd.write(output) - fd.write("};\n\n") - - fd.write("unsigned int zepfull_private_der_len = " + str(key_len) + ";\n") - -if __name__ == "__main__": - main() diff --git a/samples/net/cloud/google_iot_mqtt/src/private_info/test_key.c b/samples/net/cloud/google_iot_mqtt/src/private_info/test_key.c deleted file mode 100644 index 14baccb56d2..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/private_info/test_key.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -unsigned char zepfull_private_der[] = { - 0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, - 0x01, 0x00, 0xc7, 0xa1, 0x91, 0x8d, 0x6c, 0xed, 0x88, 0xbe, 0x23, 0x01, - 0x4a, 0x49, 0x64, 0x3f, 0x45, 0xe7, 0x1e, 0xab, 0x3e, 0xf4, 0x60, 0xaf, - 0x64, 0x60, 0xda, 0x5e, 0xf8, 0xfe, 0x5b, 0xd0, 0x49, 0x61, 0xd9, 0x1e, - 0x7d, 0xb1, 0xaf, 0xf4, 0x32, 0xa1, 0x54, 0xf7, 0xce, 0x3f, 0xaa, 0x7d, - 0x93, 0xef, 0x96, 0xa5, 0x84, 0x8b, 0x1c, 0xd5, 0x31, 0x67, 0xc7, 0xcd, - 0xd0, 0x17, 0xa3, 0xbf, 0x75, 0xae, 0x4b, 0x26, 0xc2, 0x82, 0x1f, 0x1f, - 0x40, 0xfd, 0xd0, 0xdd, 0x89, 0x64, 0x6b, 0xed, 0x83, 0xd9, 0x33, 0xfc, - 0x2d, 0xec, 0x7a, 0xfb, 0x9b, 0x12, 0xae, 0x65, 0x8b, 0x8d, 0x9d, 0x85, - 0x2b, 0x34, 0x42, 0xa6, 0x59, 0x74, 0x08, 0x34, 0xaa, 0x66, 0xf2, 0x52, - 0xac, 0xbf, 0xe2, 0x55, 0x2e, 0x64, 0xb0, 0x04, 0x2d, 0xa6, 0x0f, 0xe0, - 0xc1, 0xf2, 0x48, 0x21, 0x9b, 0x5d, 0x96, 0x36, 0x0a, 0xeb, 0xfa, 0xdf, - 0xcb, 0xc7, 0x95, 0x86, 0xec, 0x85, 0xd8, 0xa3, 0xb9, 0xc4, 0x6f, 0x9f, - 0xb3, 0x52, 0xec, 0xc3, 0xae, 0x7b, 0x51, 0x4e, 0x76, 0x6c, 0x59, 0xdc, - 0x05, 0xb1, 0x20, 0xdc, 0x4f, 0x21, 0x57, 0x19, 0x93, 0x42, 0x1b, 0xf2, - 0x38, 0x84, 0x15, 0xf3, 0x5a, 0xe6, 0x9c, 0x5c, 0xff, 0x8b, 0x7a, 0x09, - 0x66, 0x96, 0xa4, 0x53, 0x00, 0xb0, 0x75, 0xac, 0xdb, 0xb2, 0xa4, 0x5d, - 0x18, 0x7d, 0x76, 0xf6, 0xc5, 0x69, 0x37, 0x6b, 0xfd, 0xc4, 0x56, 0x01, - 0x13, 0xf7, 0x7d, 0xcd, 0xf7, 0x3b, 0xa8, 0xec, 0x11, 0x95, 0x53, 0x25, - 0x5e, 0x99, 0xb9, 0x13, 0xf9, 0xa8, 0x68, 0x25, 0x23, 0x2c, 0x36, 0xc7, - 0xb6, 0x39, 0x7f, 0xe9, 0xf9, 0x70, 0x2b, 0x29, 0xbc, 0x70, 0xe9, 0x7a, - 0x00, 0xd2, 0x76, 0xa1, 0xef, 0x3c, 0x98, 0x71, 0x77, 0xbb, 0xcd, 0x83, - 0xf2, 0x3a, 0x7a, 0x5e, 0xc0, 0x27, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, - 0x82, 0x01, 0x01, 0x00, 0xb8, 0xf8, 0x67, 0x99, 0x16, 0xf8, 0xf0, 0xde, - 0xdc, 0x28, 0x71, 0xe0, 0x96, 0xd6, 0x59, 0xba, 0xd0, 0x9b, 0xf3, 0x75, - 0x13, 0xb0, 0xef, 0xdd, 0x1d, 0xf9, 0x29, 0xd4, 0xe4, 0xd5, 0x95, 0x68, - 0xe8, 0x78, 0x6c, 0x16, 0x9b, 0xe6, 0x34, 0x93, 0x6f, 0xdb, 0x3c, 0x6b, - 0x99, 0x59, 0x4a, 0x1d, 0x91, 0x04, 0x44, 0x4f, 0x71, 0xa3, 0xc8, 0x67, - 0x54, 0xa6, 0xca, 0xcd, 0x5c, 0x98, 0x26, 0x3e, 0x1c, 0xbc, 0x09, 0x35, - 0xf0, 0x08, 0x51, 0x7b, 0xdc, 0x6f, 0xa8, 0xc2, 0x37, 0x8e, 0x97, 0xc0, - 0x45, 0x7e, 0xc0, 0x3e, 0x81, 0xa5, 0x68, 0x06, 0x63, 0x39, 0x0b, 0x99, - 0x67, 0xfe, 0xe0, 0x0d, 0x48, 0x44, 0x42, 0x56, 0x54, 0xd4, 0x17, 0x9f, - 0xd3, 0x9f, 0xef, 0x18, 0xcc, 0x6a, 0x08, 0xd6, 0x9a, 0x91, 0x04, 0x8a, - 0xfd, 0xe3, 0x4f, 0x51, 0x62, 0xac, 0x60, 0xfc, 0xd2, 0x15, 0xb8, 0xff, - 0x53, 0x3e, 0xc0, 0x07, 0xe3, 0x75, 0x42, 0xbe, 0x35, 0x1b, 0x7e, 0xf5, - 0x00, 0x1a, 0x26, 0x10, 0x89, 0xb4, 0x8c, 0x21, 0x54, 0xb5, 0x1e, 0x1a, - 0x23, 0x32, 0xaf, 0x80, 0x38, 0x0a, 0xfa, 0xc0, 0x17, 0xb1, 0x49, 0x92, - 0xfa, 0x08, 0x15, 0x02, 0xa6, 0xe3, 0x36, 0x57, 0x03, 0xbd, 0x56, 0xd2, - 0x24, 0xaf, 0xb9, 0x45, 0xd0, 0x43, 0x16, 0xd1, 0x78, 0x86, 0x2e, 0xae, - 0xf6, 0xac, 0x1d, 0x0b, 0x03, 0xac, 0x90, 0x0d, 0x5d, 0xbe, 0xc0, 0xc0, - 0x9e, 0x30, 0x38, 0x9b, 0x61, 0x7b, 0x51, 0x39, 0xc2, 0x3d, 0x30, 0x85, - 0xf2, 0x33, 0x94, 0x53, 0xb0, 0x5a, 0x12, 0x72, 0xeb, 0x30, 0xb2, 0x8c, - 0x66, 0xec, 0xc2, 0x1f, 0x4d, 0xa5, 0x67, 0x20, 0xde, 0x3b, 0x05, 0x72, - 0xe9, 0x0e, 0x77, 0x1f, 0x3f, 0xd8, 0x8a, 0x77, 0x5c, 0x4c, 0xc0, 0x81, - 0xf2, 0xe3, 0x41, 0x96, 0x94, 0xa6, 0xe5, 0xc1, 0x02, 0x81, 0x81, 0x00, - 0xe3, 0xd3, 0x76, 0x49, 0x5f, 0x18, 0x58, 0x74, 0x31, 0x37, 0xca, 0xfa, - 0x42, 0x39, 0x74, 0x61, 0x4b, 0xec, 0x0c, 0x14, 0xc7, 0xfa, 0xff, 0xe5, - 0xa4, 0xb0, 0x33, 0xba, 0x7b, 0x0a, 0x02, 0xf4, 0x07, 0x6e, 0xf3, 0xbe, - 0xde, 0xe6, 0x1b, 0xb3, 0x72, 0xbf, 0x10, 0x82, 0x3b, 0xf5, 0x1d, 0x9f, - 0x43, 0x0d, 0x0a, 0x42, 0xcf, 0x1a, 0xbd, 0x94, 0x65, 0xb9, 0xdc, 0x73, - 0x9b, 0xbe, 0xda, 0xc9, 0xb9, 0xa6, 0x65, 0x99, 0x48, 0xae, 0xa8, 0x62, - 0xe3, 0xc2, 0xe1, 0x53, 0x57, 0x01, 0x06, 0xa3, 0x63, 0xac, 0x3c, 0x7e, - 0x32, 0xa1, 0xf7, 0xbf, 0x73, 0xec, 0x38, 0x0e, 0x4d, 0x9b, 0x88, 0x94, - 0x5f, 0xbc, 0x1d, 0x8d, 0xd1, 0xff, 0x2d, 0x84, 0x73, 0x67, 0x24, 0x91, - 0x34, 0x65, 0xa9, 0xec, 0x70, 0x0d, 0x50, 0x52, 0x0d, 0xee, 0x94, 0x6a, - 0x43, 0xd9, 0x66, 0x57, 0x9e, 0x04, 0x2e, 0xa9, 0x02, 0x81, 0x81, 0x00, - 0xe0, 0x51, 0x82, 0x81, 0xb0, 0x47, 0xcc, 0xf7, 0xb3, 0xc2, 0x1e, 0xc7, - 0xc0, 0xc5, 0x35, 0xcf, 0x3e, 0xc7, 0x40, 0xa3, 0x01, 0x18, 0x4b, 0x8b, - 0x8a, 0xbd, 0x6c, 0x21, 0x9d, 0xf7, 0x73, 0xc6, 0x92, 0x04, 0x6e, 0x5a, - 0xf8, 0x89, 0x42, 0x1f, 0x27, 0x26, 0x9c, 0x00, 0x22, 0x0f, 0xa4, 0xbe, - 0xc9, 0x96, 0x20, 0xb5, 0xaa, 0xa7, 0x3e, 0x1d, 0xa2, 0x23, 0x3a, 0xa6, - 0x80, 0x1d, 0x52, 0xbb, 0xf2, 0xe8, 0x2d, 0x84, 0xa1, 0x81, 0x75, 0x6c, - 0x60, 0xc9, 0x39, 0x15, 0xaa, 0x6c, 0x56, 0x0a, 0x08, 0x24, 0x3f, 0xda, - 0xd4, 0x62, 0xed, 0xf2, 0x59, 0x10, 0x34, 0x14, 0xfa, 0x91, 0x08, 0x80, - 0xb2, 0x90, 0xba, 0x0f, 0x39, 0x45, 0x84, 0x69, 0x4a, 0xce, 0xbc, 0x71, - 0x24, 0x49, 0x4e, 0x53, 0x26, 0xd7, 0x38, 0x79, 0x05, 0xf7, 0x57, 0x7a, - 0x43, 0xd0, 0x55, 0xb6, 0xc1, 0x0b, 0xca, 0x4f, 0x02, 0x81, 0x80, 0x77, - 0x43, 0xc7, 0xf4, 0x78, 0xf7, 0xc1, 0xb6, 0x71, 0xdd, 0x87, 0x40, 0xa3, - 0x52, 0x78, 0x7e, 0x46, 0xc4, 0x77, 0x3e, 0x99, 0xc1, 0xe8, 0x1c, 0x4b, - 0xae, 0x82, 0x25, 0xe9, 0x2b, 0x40, 0x88, 0x87, 0x2b, 0xaa, 0x26, 0x0d, - 0x81, 0xe0, 0x96, 0x7c, 0x47, 0x51, 0x59, 0x1c, 0x12, 0x21, 0x43, 0xb2, - 0x52, 0x2d, 0x40, 0xf4, 0x32, 0x47, 0x74, 0x5c, 0x1c, 0x84, 0x2f, 0x71, - 0x24, 0xe4, 0x5c, 0x1d, 0xf7, 0xe1, 0xcf, 0xf0, 0xa0, 0x9e, 0x3d, 0xc6, - 0x85, 0xca, 0x77, 0x5a, 0x60, 0x8b, 0x1d, 0x15, 0x9c, 0xa0, 0xbe, 0x5f, - 0xbb, 0x32, 0x7a, 0xe3, 0x30, 0x91, 0xd7, 0xcb, 0x00, 0xd4, 0xea, 0xf7, - 0x82, 0xfe, 0xe5, 0xb3, 0x3d, 0x26, 0x92, 0xe3, 0xe6, 0xe6, 0xd9, 0xac, - 0xd8, 0x5b, 0xb0, 0x0e, 0xa8, 0xa9, 0x97, 0x8a, 0xfb, 0x8e, 0x6e, 0x62, - 0xbe, 0x78, 0x38, 0xfd, 0xdb, 0xaa, 0xa1, 0x02, 0x81, 0x81, 0x00, 0x93, - 0x65, 0x1b, 0xc3, 0x09, 0xc8, 0xf4, 0x26, 0xa3, 0x08, 0x5f, 0xdf, 0x53, - 0x8c, 0x82, 0x22, 0x0e, 0x97, 0x30, 0xa2, 0xab, 0x1a, 0x82, 0xb1, 0x4b, - 0x55, 0xd2, 0x52, 0x78, 0x90, 0xdb, 0x93, 0x53, 0xe8, 0xf3, 0x76, 0x75, - 0x2f, 0x03, 0xb2, 0xa2, 0xb0, 0x1c, 0xfb, 0x7d, 0x66, 0x18, 0x13, 0x81, - 0x34, 0x53, 0x83, 0xeb, 0x81, 0x7f, 0x30, 0x4b, 0x94, 0xa8, 0x7a, 0x35, - 0x5e, 0x8f, 0x39, 0x8e, 0x8f, 0xff, 0x30, 0xd2, 0x4a, 0xd5, 0x94, 0x84, - 0x38, 0x54, 0x79, 0x27, 0x05, 0x8e, 0xb7, 0x82, 0xc8, 0x06, 0xe9, 0x4c, - 0x7b, 0x40, 0xec, 0xe8, 0x96, 0xdc, 0x12, 0x18, 0xde, 0xe9, 0xde, 0x5e, - 0xf6, 0xf8, 0x3a, 0xfe, 0x9f, 0xee, 0x34, 0x9d, 0x82, 0x20, 0x92, 0x9b, - 0x8c, 0x4b, 0x9a, 0x19, 0xc0, 0x7b, 0x8c, 0x12, 0x5e, 0x87, 0x2d, 0x80, - 0x97, 0xc9, 0x6a, 0x8f, 0x88, 0xa6, 0xc3, 0x02, 0x81, 0x80, 0x4b, 0x44, - 0xe8, 0xb7, 0x47, 0xb0, 0x59, 0xf1, 0x58, 0x4e, 0x3f, 0x51, 0x37, 0x63, - 0xe0, 0xc5, 0xad, 0xf9, 0x32, 0x8d, 0x8f, 0xa4, 0xa6, 0xd3, 0x8e, 0x01, - 0xf4, 0xc0, 0xbd, 0x8e, 0x2d, 0xd7, 0x99, 0xf7, 0x23, 0x2d, 0x36, 0xd8, - 0xc9, 0x9e, 0xc0, 0x63, 0x00, 0xb1, 0xe7, 0xb6, 0xab, 0x0c, 0x95, 0x17, - 0xe3, 0x7c, 0x86, 0x64, 0x0c, 0x06, 0x00, 0x10, 0x8a, 0x23, 0x14, 0x1b, - 0xa6, 0xdb, 0xc9, 0xcc, 0xcb, 0x96, 0xcd, 0x38, 0x77, 0xa5, 0xb1, 0x02, - 0xf7, 0x49, 0x87, 0x1d, 0x6a, 0x2b, 0xfb, 0x40, 0x6b, 0x03, 0x4d, 0x04, - 0xdf, 0xed, 0x16, 0x1b, 0xbe, 0x3c, 0x03, 0xca, 0x68, 0x3f, 0x4c, 0x28, - 0xfc, 0x99, 0xf0, 0xdd, 0x23, 0x51, 0xc0, 0x87, 0x85, 0x17, 0xa9, 0x1f, - 0x18, 0xe0, 0x10, 0xd6, 0xca, 0xbf, 0xb6, 0x5c, 0x0c, 0xce, 0x4d, 0x2e, - 0x9e, 0x75, 0xf0, 0x71, 0xe0, 0x01 -}; - -unsigned int zepfull_private_der_len = 1218; diff --git a/samples/net/cloud/google_iot_mqtt/src/protocol.c b/samples/net/cloud/google_iot_mqtt/src/protocol.c deleted file mode 100644 index 7e62253583a..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/protocol.c +++ /dev/null @@ -1,407 +0,0 @@ -/* Protocol implementation. */ -/* - * Copyright (c) 2018-2019 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -LOG_MODULE_DECLARE(net_google_iot_mqtt, LOG_LEVEL_DBG); -#include "protocol.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -extern int64_t time_base; - -/* private key information */ -extern unsigned char zepfull_private_der[]; -extern unsigned int zepfull_private_der_len; - -/* - * This is the hard-coded root certificate that we accept. - */ -#include "globalsign.inc" - -static uint8_t client_id[] = CONFIG_CLOUD_CLIENT_ID; -static uint8_t client_username[] = "none"; -static uint8_t pub_topic[] = CONFIG_CLOUD_PUBLISH_TOPIC; - -static struct mqtt_publish_param pub_data; - -static uint8_t token[512]; - -static bool connected; -static uint64_t next_alive; - -/* The mqtt client struct */ -static struct mqtt_client client_ctx; - -/* MQTT Broker details. */ -static struct sockaddr_storage broker; - -/* Buffers for MQTT client. */ -static uint8_t rx_buffer[1024]; -static uint8_t tx_buffer[1024]; - -static sec_tag_t m_sec_tags[] = { -#if defined(MBEDTLS_X509_CRT_PARSE_C) - 1, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - APP_PSK_TAG, -#endif -}; - -/* Zephyr implementation of POSIX `time`. Has to be called k_time - * because time is already taken by newlib. The clock will be set by - * the SNTP client when it receives the time. We make no attempt to - * adjust it smoothly, and it should not be used for measuring - * intervals. Use `k_uptime_get()` directly for that. Also the - * time_t defined by newlib is a signed 32-bit value, and will - * overflow in 2037. - */ -time_t my_k_time(time_t *ptr) -{ - int64_t stamp; - time_t now; - - stamp = k_uptime_get(); - now = (time_t)((stamp + time_base) / 1000); - - if (ptr) { - *ptr = now; - } - - return now; -} - -void mqtt_subscribe_config(struct mqtt_client *const client) -{ -#ifdef CONFIG_CLOUD_SUBSCRIBE_CONFIG - /* subscribe to config information */ - struct mqtt_topic subs_topic = { - .topic = { - .utf8 = CONFIG_CLOUD_SUBSCRIBE_CONFIG, - .size = strlen(CONFIG_CLOUD_SUBSCRIBE_CONFIG) - }, - .qos = MQTT_QOS_1_AT_LEAST_ONCE - }; - const struct mqtt_subscription_list subs_list = { - .list = &subs_topic, - .list_count = 1U, - .message_id = 1U - }; - int err; - - err = mqtt_subscribe(client, &subs_list); - if (err) { - LOG_ERR("Failed to subscribe to %s item, error %d", - subs_topic.topic.utf8, err); - } -#endif -} - -void mqtt_evt_handler(struct mqtt_client *const client, - const struct mqtt_evt *evt) -{ - switch (evt->type) { - case MQTT_EVT_SUBACK: - LOG_INF("SUBACK packet id: %u", evt->param.suback.message_id); - break; - - case MQTT_EVT_UNSUBACK: - LOG_INF("UNSUBACK packet id: %u", - evt->param.suback.message_id); - break; - - case MQTT_EVT_CONNACK: - if (evt->result != 0) { - LOG_ERR("MQTT connect failed %d", evt->result); - break; - } - - connected = true; - LOG_INF("MQTT client connected!"); - - mqtt_subscribe_config(client); - - break; - - case MQTT_EVT_DISCONNECT: - LOG_INF("MQTT client disconnected %d", evt->result); - - connected = false; - - break; - -#ifdef CONFIG_CLOUD_SUBSCRIBE_CONFIG - case MQTT_EVT_PUBLISH: { - const struct mqtt_publish_param *pub = &evt->param.publish; - uint8_t d[33]; - int len = pub->message.payload.len; - int bytes_read; - - LOG_INF("MQTT publish received %d, %d bytes", - evt->result, len); - LOG_INF(" id: %d, qos: %d", - pub->message_id, - pub->message.topic.qos); - LOG_INF(" item: %s", - pub->message.topic.topic.utf8); - - /* assuming the config message is textual */ - while (len) { - bytes_read = mqtt_read_publish_payload_blocking( - client, d, - len >= 32 ? 32 : len); - if (bytes_read < 0) { - LOG_ERR("failure to read payload"); - break; - } - - d[bytes_read] = '\0'; - LOG_INF(" payload: %s", d); - len -= bytes_read; - } - - /* for MQTT_QOS_0_AT_MOST_ONCE no acknowledgment needed */ - if (pub->message.topic.qos == MQTT_QOS_1_AT_LEAST_ONCE) { - struct mqtt_puback_param puback = { - .message_id = pub->message_id - }; - - mqtt_publish_qos1_ack(client, &puback); - } - break; - } -#endif - - case MQTT_EVT_PUBACK: - if (evt->result != 0) { - LOG_ERR("MQTT PUBACK error %d", evt->result); - break; - } - - /* increment message id for when we send next message */ - pub_data.message_id += 1U; - LOG_INF("PUBACK packet id: %u", - evt->param.puback.message_id); - break; - - default: - LOG_INF("MQTT event received %d", evt->type); - break; - } -} - -static int wait_for_input(int timeout) -{ - int res; - struct zsock_pollfd fds[1] = { - [0] = {.fd = client_ctx.transport.tls.sock, - .events = ZSOCK_POLLIN, - .revents = 0}, - }; - - res = zsock_poll(fds, 1, timeout); - if (res < 0) { - LOG_ERR("poll read event error"); - return -errno; - } - - return res; -} - -#define ALIVE_TIME (60 * MSEC_PER_SEC) - -static struct mqtt_utf8 password = { - .utf8 = token -}; - -static struct mqtt_utf8 username = { - .utf8 = client_username, - .size = sizeof(client_username) -}; - -void mqtt_startup(char *hostname, int port) -{ - int err, cnt; - char pub_msg[64]; - struct sockaddr_in *broker4 = (struct sockaddr_in *)&broker; - struct mqtt_client *client = &client_ctx; - struct jwt_builder jb; - static struct zsock_addrinfo hints; - struct zsock_addrinfo *haddr; - int res = 0; - int retries = 5; - - mbedtls_platform_set_time(my_k_time); - - err = tls_credential_add(1, TLS_CREDENTIAL_CA_CERTIFICATE, - globalsign_certificate, - sizeof(globalsign_certificate)); - if (err < 0) { - LOG_ERR("Failed to register public certificate: %d", err); - } - - while (retries) { - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - cnt = 0; - while ((err = getaddrinfo("mqtt.googleapis.com", "8883", &hints, - &haddr)) && cnt < 3) { - LOG_ERR("Unable to get address for broker, retrying"); - cnt++; - } - - if (err != 0) { - LOG_ERR("Unable to get address for broker, error %d", - err); - return; - } - LOG_INF("DNS resolved for mqtt.googleapis.com:8883"); - - mqtt_client_init(client); - - time_t now = my_k_time(NULL); - - res = jwt_init_builder(&jb, token, sizeof(token)); - if (res != 0) { - LOG_ERR("Error with JWT token"); - return; - } - - res = jwt_add_payload(&jb, now + 60 * 60, now, - CONFIG_CLOUD_AUDIENCE); - if (res != 0) { - LOG_ERR("Error with JWT token"); - return; - } - - res = jwt_sign(&jb, zepfull_private_der, - zepfull_private_der_len); - - if (res != 0) { - LOG_ERR("Error with JWT token"); - return; - } - - - broker4->sin_family = AF_INET; - broker4->sin_port = htons(port); - net_ipaddr_copy(&broker4->sin_addr, - &net_sin(haddr->ai_addr)->sin_addr); - - /* MQTT client configuration */ - client->broker = &broker; - client->evt_cb = mqtt_evt_handler; - client->client_id.utf8 = client_id; - client->client_id.size = strlen(client_id); - client->password = &password; - password.size = jwt_payload_len(&jb); - client->user_name = &username; - client->protocol_version = MQTT_VERSION_3_1_1; - - /* MQTT buffers configuration */ - client->rx_buf = rx_buffer; - client->rx_buf_size = sizeof(rx_buffer); - client->tx_buf = tx_buffer; - client->tx_buf_size = sizeof(tx_buffer); - - /* MQTT transport configuration */ - client->transport.type = MQTT_TRANSPORT_SECURE; - - struct mqtt_sec_config *tls_config = - &client->transport.tls.config; - - tls_config->peer_verify = TLS_PEER_VERIFY_REQUIRED; - tls_config->cipher_list = NULL; - tls_config->sec_tag_list = m_sec_tags; - tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags); - tls_config->hostname = hostname; - - LOG_INF("Connecting to host: %s", hostname); - err = mqtt_connect(client); - if (err != 0) { - LOG_ERR("could not connect, error %d", err); - mqtt_disconnect(client); - retries--; - k_msleep(ALIVE_TIME); - continue; - } - - if (wait_for_input(5 * MSEC_PER_SEC) > 0) { - mqtt_input(client); - if (!connected) { - LOG_ERR("failed to connect to mqtt_broker"); - mqtt_disconnect(client); - retries--; - k_msleep(ALIVE_TIME); - continue; - } else { - break; - } - } else { - LOG_ERR("failed to connect to mqtt broker"); - mqtt_disconnect(client); - retries--; - k_msleep(ALIVE_TIME); - continue; - } - } - - if (!connected) { - LOG_ERR("Failed to connect to client, aborting"); - return; - } - - /* initialize publish structure */ - pub_data.message.topic.topic.utf8 = pub_topic; - pub_data.message.topic.topic.size = strlen(pub_topic); - pub_data.message.topic.qos = MQTT_QOS_1_AT_LEAST_ONCE; - pub_data.message.payload.data = (uint8_t *)pub_msg; - pub_data.message_id = 1U; - pub_data.dup_flag = 0U; - pub_data.retain_flag = 1U; - - mqtt_live(client); - - next_alive = k_uptime_get() + ALIVE_TIME; - - while (1) { - LOG_INF("Publishing data"); - sprintf(pub_msg, "%s: %d\n", "payload", pub_data.message_id); - pub_data.message.payload.len = strlen(pub_msg); - err = mqtt_publish(client, &pub_data); - if (err) { - LOG_ERR("could not publish, error %d", err); - break; - } - - /* idle and process messages */ - while (k_uptime_get() < next_alive) { - LOG_INF("... idling ..."); - if (wait_for_input(5 * MSEC_PER_SEC) > 0) { - mqtt_input(client); - } - } - - mqtt_live(client); - next_alive += ALIVE_TIME; - } -} diff --git a/samples/net/cloud/google_iot_mqtt/src/protocol.h b/samples/net/cloud/google_iot_mqtt/src/protocol.h deleted file mode 100644 index 9378688c933..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/protocol.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Ltd - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * MQTT-based cloud protocol engine. - */ - -#ifndef PROTOCOL_H__ -#define PROTOCOL_H__ - -#include - -void mqtt_startup(char *hostname, int port); - -#endif diff --git a/samples/net/cloud/google_iot_mqtt/src/tls_config/user-tls-conf.h b/samples/net/cloud/google_iot_mqtt/src/tls_config/user-tls-conf.h deleted file mode 100644 index 035f2b062ec..00000000000 --- a/samples/net/cloud/google_iot_mqtt/src/tls_config/user-tls-conf.h +++ /dev/null @@ -1,5 +0,0 @@ -#define MBEDTLS_AES_ROM_TABLES - -#define MBEDTLS_HAVE_TIME -#define MBEDTLS_HAVE_TIME_DATE -#define MBEDTLS_PLATFORM_TIME_ALT From faa8bb5bb866346787b66e122505b7babbc0c506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 16:49:02 +0200 Subject: [PATCH 0124/4498] samples: remove leftovers from current_sensing sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove leftovers of a code sample that was (only partially) deleted with PR #35538 Signed-off-by: Benjamin Cabé --- samples/drivers/current_sensing/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 samples/drivers/current_sensing/CMakeLists.txt diff --git a/samples/drivers/current_sensing/CMakeLists.txt b/samples/drivers/current_sensing/CMakeLists.txt deleted file mode 100644 index 280fd63bace..00000000000 --- a/samples/drivers/current_sensing/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(current_sensing) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) From 6b05af6e4389cf10415b7c3bd83c0dd45b10ed26 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 5 Sep 2023 01:47:48 +0530 Subject: [PATCH 0125/4498] twister: handle quotes for configuration options Add support handling quotes for configuration options in extra args by escaping them properly instead of removing the quotes altogether. For other options in extra_args quotes are removes as usual. Add similar support in west build command also. Add a unit test to check this functionality. Signed-off-by: Chaitanya Tata --- scripts/pylib/twister/twisterlib/runner.py | 10 ++++++++-- scripts/tests/twister/test_runner.py | 5 +++-- scripts/west_commands/build.py | 6 +++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index bbbdb18d05a..ef41084cdd4 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -978,9 +978,15 @@ def report_out(self, results): sys.stdout.flush() @staticmethod - def cmake_assemble_args(args, handler, extra_conf_files, extra_overlay_confs, + def cmake_assemble_args(extra_args, handler, extra_conf_files, extra_overlay_confs, extra_dtc_overlay_files, cmake_extra_args, build_dir): + # Retain quotes around config options + config_options = [arg for arg in extra_args if arg.startswith("CONFIG_")] + args = [arg for arg in extra_args if not arg.startswith("CONFIG_")] + + args_expanded = ["-D{}".format(a.replace('"', '\"')) for a in config_options] + if handler.ready: args.extend(handler.args) @@ -1003,7 +1009,7 @@ def cmake_assemble_args(args, handler, extra_conf_files, extra_overlay_confs, args.append("OVERLAY_CONFIG=\"%s\"" % (" ".join(overlays))) # Build the final argument list - args_expanded = ["-D{}".format(a.replace('"', '\"')) for a in cmake_extra_args] + args_expanded.extend(["-D{}".format(a.replace('"', '\"')) for a in cmake_extra_args]) args_expanded.extend(["-D{}".format(a.replace('"', '')) for a in args]) return args_expanded diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 7540da04394..37c02b6d17b 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -90,7 +90,7 @@ class MockHandler: handler.ready = True assert(ProjectBuilder.cmake_assemble_args( - ["basearg1"], + ["basearg1", "CONFIG_t=\"test\"", "SNIPPET_t=\"test\""], handler, ["a.conf;b.conf", "c.conf"], ["extra_overlay.conf"], @@ -98,8 +98,9 @@ class MockHandler: ["cmake1=foo", "cmake2=bar"], "/builddir/", ) == [ + "-DCONFIG_t=\"test\"", "-Dcmake1=foo", "-Dcmake2=bar", - "-Dbasearg1", + "-Dbasearg1", "-DSNIPPET_t=test", "-Dhandler_arg1", "-Dhandler_arg2", "-DCONF_FILE=a.conf;b.conf;c.conf", "-DDTC_OVERLAY_FILE=x.overlay;y.overlay;z.overlay", diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index bcc5106f8ca..f7a605f4d7f 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -317,7 +317,11 @@ def _parse_test_item(self, test_item): if data == 'extra_configs': args = ["-D{}".format(arg.replace('"', '\"')) for arg in arg_list] elif data == 'extra_args': - args = ["-D{}".format(arg.replace('"', '')) for arg in arg_list] + # Retain quotes around config options + config_options = [arg for arg in arg_list if arg.startswith("CONFIG_")] + non_config_options = [arg for arg in arg_list if not arg.startswith("CONFIG_")] + args = ["-D{}".format(a.replace('"', '\"')) for a in config_options] + args.extend(["-D{}".format(arg.replace('"', '')) for arg in non_config_options]) elif data == 'extra_conf_files': extra_conf_files.extend(arg_list) continue From 20b81a865d38207cd67ba981a8aa8c38baba3470 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 27 Aug 2023 06:47:52 -0400 Subject: [PATCH 0126/4498] twister: support scanning for ztests in subdirectories Previously, only the main src/ directories was scanned for ZTest testsuite names and tests. This allows us to place test sources in subdirectories as well. Signed-off-by: Christopher Friedt --- scripts/pylib/twister/twisterlib/testsuite.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index 3f4a71e4a8c..bdd681699ff 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -256,6 +256,28 @@ def _find_ztest_testcases(search_area, testcase_regex): return testcase_names, warnings +def find_c_files_in(path: str, extensions: list = ['c', 'cpp', 'cxx', 'cc']) -> list: + """ + Find C or C++ sources in the directory specified by "path" + """ + if not os.path.isdir(path): + return [] + + # back up previous CWD + oldpwd = os.getcwd() + os.chdir(path) + + filenames = [] + for ext in extensions: + # glob.glob('**/*.c') does not pick up the base directory + filenames += [os.path.join(path, x) for x in glob.glob(f'*.{ext}')] + # glob matches in subdirectories too + filenames += [os.path.join(path, x) for x in glob.glob(f'**/*.{ext}')] + + # restore previous CWD + os.chdir(oldpwd) + + return filenames def scan_testsuite_path(testsuite_path): subcases = [] @@ -265,7 +287,7 @@ def scan_testsuite_path(testsuite_path): ztest_suite_names = [] src_dir_path = _find_src_dir_path(testsuite_path) - for filename in glob.glob(os.path.join(src_dir_path, "*.c*")): + for filename in find_c_files_in(src_dir_path): if os.stat(filename).st_size == 0: continue try: @@ -288,7 +310,7 @@ def scan_testsuite_path(testsuite_path): except ValueError as e: logger.error("%s: error parsing source file: %s" % (filename, e)) - for filename in glob.glob(os.path.join(testsuite_path, "*.c*")): + for filename in find_c_files_in(testsuite_path): try: result: ScanPathResult = scan_file(filename) if result.warnings: From d218b20643d6ff93bef580d2147bd0b706e6bf3f Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 4 Aug 2023 19:17:41 +0200 Subject: [PATCH 0127/4498] tracing: make API tracing configurable So far only object tracing/tracking could be individually disabled (e.g. CONFIG_TRACING_SEMAPHORE=n). Now tracing of any API may be disabled (e.g. CONFIG_TRACING_PM=n). Signed-off-by: Florian Grandel --- include/zephyr/tracing/tracing_macros.h | 51 +++++++++++++++++-------- subsys/tracing/Kconfig | 12 ++++++ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/include/zephyr/tracing/tracing_macros.h b/include/zephyr/tracing/tracing_macros.h index 5f0f871aac7..7ed990617d5 100644 --- a/include/zephyr/tracing/tracing_macros.h +++ b/include/zephyr/tracing/tracing_macros.h @@ -6,6 +6,8 @@ #ifndef ZEPHYR_INCLUDE_TRACING_TRACING_MACROS_H_ #define ZEPHYR_INCLUDE_TRACING_TRACING_MACROS_H_ +#include + #if !defined(CONFIG_TRACING) && !defined(__DOXYGEN__) #define SYS_PORT_TRACING_FUNC(type, func, ...) do { } while (false) @@ -73,6 +75,7 @@ #define sys_port_trace_type_mask_k_thread(trace_call) trace_call #else #define sys_port_trace_type_mask_k_thread(trace_call) + #define sys_port_trace_k_thread_is_disabled 1 #endif #if defined(CONFIG_TRACING_WORK) @@ -173,6 +176,29 @@ #define sys_port_trace_type_mask_k_event(trace_call) #endif +#ifndef CONFIG_TRACING_POLLING + #define sys_port_trace_k_poll_api_is_disabled 1 + #define sys_port_trace_k_work_poll_is_disabled 1 +#endif + +#ifndef CONFIG_TRACING_PM + #define sys_port_trace_pm_is_disabled 1 +#endif + +/* + * We cannot positively enumerate all traced APIs, as applications may trace + * arbitrary custom APIs we know nothing about. Therefore we demand that tracing + * of an API must be actively disabled. + * + * This contrasts with object tracing/tracking as all traceable objects are well + * known, see the SYS_PORT_TRACING_TYPE_MASK approach below. + */ +#define _SYS_PORT_TRACE_IS_DISABLED(type) sys_port_trace_##type##_is_disabled +#define _SYS_PORT_TRACE_WRAP(func, ...) do { func(__VA_ARGS__); } while (false) +#define _SYS_PORT_TRACE_IF_NOT_DISABLED(type, func, ...) \ + COND_CODE_1(_SYS_PORT_TRACE_IS_DISABLED(type), (), \ + (_SYS_PORT_TRACE_WRAP(func, __VA_ARGS__))) + /** @endcond */ /** @@ -194,10 +220,8 @@ * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. * @param ... Additional parameters relevant to the tracing call */ -#define SYS_PORT_TRACING_FUNC(type, func, ...) \ - do { \ - _SYS_PORT_TRACING_FUNC(type, func)(__VA_ARGS__); \ - } while (false) +#define SYS_PORT_TRACING_FUNC(type, func, ...) \ + _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC(type, func), __VA_ARGS__) /** * @brief Tracing macro for the entry into a function that might or might not return @@ -209,10 +233,8 @@ * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. * @param ... Additional parameters relevant to the tracing call */ -#define SYS_PORT_TRACING_FUNC_ENTER(type, func, ...) \ - do { \ - _SYS_PORT_TRACING_FUNC_ENTER(type, func)(__VA_ARGS__); \ - } while (false) +#define SYS_PORT_TRACING_FUNC_ENTER(type, func, ...) \ + _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_ENTER(type, func), __VA_ARGS__) /** * @brief Tracing macro for when a function blocks during its execution. @@ -223,10 +245,9 @@ * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. * @param ... Additional parameters relevant to the tracing call */ -#define SYS_PORT_TRACING_FUNC_BLOCKING(type, func, ...) \ - do { \ - _SYS_PORT_TRACING_FUNC_BLOCKING(type, func)(__VA_ARGS__); \ - } while (false) +#define SYS_PORT_TRACING_FUNC_BLOCKING(type, func, ...) \ + _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_BLOCKING(type, func), \ + __VA_ARGS__) /** * @brief Tracing macro for when a function ends its execution. Potential return values @@ -238,10 +259,8 @@ * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. * @param ... Additional parameters relevant to the tracing call */ -#define SYS_PORT_TRACING_FUNC_EXIT(type, func, ...) \ - do { \ - _SYS_PORT_TRACING_FUNC_EXIT(type, func)(__VA_ARGS__); \ - } while (false) +#define SYS_PORT_TRACING_FUNC_EXIT(type, func, ...) \ + _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_EXIT(type, func), __VA_ARGS__) /** * @brief Tracing macro for the initialization of an object. diff --git a/subsys/tracing/Kconfig b/subsys/tracing/Kconfig index dd36635244d..31d1637cd60 100644 --- a/subsys/tracing/Kconfig +++ b/subsys/tracing/Kconfig @@ -308,6 +308,18 @@ config TRACING_EVENT help Enable tracing Events. +config TRACING_POLLING + bool "Tracing Polling" + default y + help + Enable tracing Work Polling and Polling API. + +config TRACING_PM + bool "Tracing Power Management" + default y + help + Enable tracing Power Management. + endmenu # Tracing Configuration endif From 96954acfff334b8e874af12e993c7433d445428a Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 18 Aug 2023 23:32:02 +0200 Subject: [PATCH 0128/4498] bluetooth: audio: Add API to get MICP service ATT handles This is needed for upper tester. Signed-off-by: Piotr Narajowski --- subsys/bluetooth/audio/micp_internal.h | 36 ++++++++++++++++++++++++++ subsys/bluetooth/audio/micp_mic_ctlr.c | 21 ++------------- 2 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 subsys/bluetooth/audio/micp_internal.h diff --git a/subsys/bluetooth/audio/micp_internal.h b/subsys/bluetooth/audio/micp_internal.h new file mode 100644 index 00000000000..a68aaca7cdf --- /dev/null +++ b/subsys/bluetooth/audio/micp_internal.h @@ -0,0 +1,36 @@ +/** @file + * @brief Internal APIs for Bluetooth MICP. + */ + +/* + * Copyright (c) 2020 Bose Corporation + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MICP_INTERNAL_ +#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MICP_INTERNAL_ + +#include +#include + +struct bt_micp_mic_ctlr { + uint16_t start_handle; + uint16_t end_handle; + uint16_t mute_handle; + struct bt_gatt_subscribe_params mute_sub_params; + struct bt_gatt_discover_params mute_sub_disc_params; + + bool busy; + uint8_t mute_val_buf[1]; /* Mute value is a single octet */ + struct bt_gatt_write_params write_params; + struct bt_gatt_read_params read_params; + struct bt_gatt_discover_params discover_params; + struct bt_conn *conn; + + uint8_t aics_inst_cnt; + struct bt_aics *aics[CONFIG_BT_AICS_CLIENT_MAX_INSTANCE_COUNT]; +}; + +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MICP_INTERNAL_ */ diff --git a/subsys/bluetooth/audio/micp_mic_ctlr.c b/subsys/bluetooth/audio/micp_mic_ctlr.c index 3599287fdd5..55fa6c3c5db 100644 --- a/subsys/bluetooth/audio/micp_mic_ctlr.c +++ b/subsys/bluetooth/audio/micp_mic_ctlr.c @@ -19,9 +19,10 @@ #include #include #include - #include +#include "micp_internal.h" + LOG_MODULE_REGISTER(bt_micp_mic_ctlr, CONFIG_BT_MICP_MIC_CTLR_LOG_LEVEL); #include "common/bt_str.h" @@ -29,24 +30,6 @@ LOG_MODULE_REGISTER(bt_micp_mic_ctlr, CONFIG_BT_MICP_MIC_CTLR_LOG_LEVEL); /* Callback functions */ static struct bt_micp_mic_ctlr_cb *micp_mic_ctlr_cb; -struct bt_micp_mic_ctlr { - uint16_t start_handle; - uint16_t end_handle; - uint16_t mute_handle; - struct bt_gatt_subscribe_params mute_sub_params; - struct bt_gatt_discover_params mute_sub_disc_params; - - bool busy; - uint8_t mute_val_buf[1]; /* Mute value is a single octet */ - struct bt_gatt_write_params write_params; - struct bt_gatt_read_params read_params; - struct bt_gatt_discover_params discover_params; - struct bt_conn *conn; - - uint8_t aics_inst_cnt; - struct bt_aics *aics[CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST]; -}; - static struct bt_micp_mic_ctlr mic_ctlrs[CONFIG_BT_MAX_CONN]; static struct bt_uuid *mics_uuid = BT_UUID_MICS; From 925a8b65d5a85819089b5dfcfd1bf78b9c88f7c3 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 18 Aug 2023 23:32:02 +0200 Subject: [PATCH 0129/4498] bluetooth: tester: MICP Client tests Add support for MICP Client tests. Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/CMakeLists.txt | 8 + tests/bluetooth/tester/overlay-le-audio.conf | 6 + tests/bluetooth/tester/src/btp/btp.h | 2 + tests/bluetooth/tester/src/btp/btp_aics.h | 106 +++- tests/bluetooth/tester/src/btp/btp_micp.h | 47 ++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_aics.c | 566 +++++++++++++++++++ tests/bluetooth/tester/src/btp_core.c | 9 + tests/bluetooth/tester/src/btp_micp.c | 264 +++++++++ tests/bluetooth/tester/src/btp_vcp.c | 318 ++--------- 10 files changed, 1051 insertions(+), 278 deletions(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_micp.h create mode 100644 tests/bluetooth/tester/src/btp_aics.c create mode 100644 tests/bluetooth/tester/src/btp_micp.c diff --git a/tests/bluetooth/tester/CMakeLists.txt b/tests/bluetooth/tester/CMakeLists.txt index fb8f9114e41..71dbe85c2b3 100644 --- a/tests/bluetooth/tester/CMakeLists.txt +++ b/tests/bluetooth/tester/CMakeLists.txt @@ -43,3 +43,11 @@ endif() if (CONFIG_BT_CSIP_SET_MEMBER) target_sources(app PRIVATE src/btp_csis.c) endif() + +if(CONFIG_BT_MICP_MIC_DEV) + target_sources(app PRIVATE src/btp_micp.c) +endif() + +if(CONFIG_BT_AICS) + target_sources(app PRIVATE src/btp_aics.c) +endif() diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index eb52ea8e56e..3a94bf77d7a 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -19,6 +19,12 @@ CONFIG_BT_BUF_CMD_TX_SIZE=255 # were freed too slow. The bt_bap_stream_ops.configured callback comes earlier. CONFIG_BT_L2CAP_TX_BUF_COUNT=4 +# MICP +CONFIG_BT_MICP_MIC_DEV=y +CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT=1 +CONFIG_BT_MICP_MIC_CTLR=y +CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST=1 + # ASCS CONFIG_BT_ASCS_ASE_SNK_COUNT=2 CONFIG_BT_ASCS_ASE_SRC_COUNT=2 diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index 5c0384c0b9f..f925308fbc1 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -25,6 +25,7 @@ #include "btp_bap.h" #include "btp_has.h" #include "btp_csis.h" +#include "btp_micp.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -48,6 +49,7 @@ #define BTP_SERVICE_ID_ASCS 13 #define BTP_SERVICE_ID_BAP 14 #define BTP_SERVICE_ID_HAS 15 +#define BTP_SERVICE_ID_MICP 16 #define BTP_SERVICE_ID_CSIS 17 #define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CSIS diff --git a/tests/bluetooth/tester/src/btp/btp_aics.h b/tests/bluetooth/tester/src/btp/btp_aics.h index 41a52390591..0f3cba97a0e 100644 --- a/tests/bluetooth/tester/src/btp/btp_aics.h +++ b/tests/bluetooth/tester/src/btp/btp_aics.h @@ -7,29 +7,125 @@ */ #include +#include /*AICS service */ +struct btp_aics_instance { + /** Number of Audio Input Control Service instances */ + uint8_t aics_cnt; + /** Array of pointers to Audio Input Control Service instances */ + struct bt_aics **aics; +}; + +extern struct bt_aics_cb aics_client_cb; +extern struct btp_aics_instance aics_client_instance; +extern struct btp_aics_instance aics_server_instance; +void btp_send_aics_state_changed_ev(struct bt_conn *conn); +void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uint8_t mode); +void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t units, int8_t minimum, + int8_t maximum); +void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t input_type); +void btp_send_aics_status_ev(struct bt_conn *conn, bool active); +void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t data_len, char *description); + #define BTP_AICS_READ_SUPPORTED_COMMANDS 0x01 struct btp_aics_read_supported_commands_rp { uint8_t data[0]; } __packed; +/* AICS client/server commands */ #define BTP_AICS_SET_GAIN 0x02 struct btp_aics_set_gain_cmd { + bt_addr_le_t address; int8_t gain; } __packed; #define BTP_AICS_MUTE 0x03 +struct btp_aics_mute_cmd { + bt_addr_le_t address; +} __packed; + #define BTP_AICS_UNMUTE 0x04 -#define BTP_AICS_MAN_GAIN 0x05 -#define BTP_AICS_AUTO_GAIN 0x06 -#define BTP_AICS_MAN_GAIN_ONLY 0x07 -#define BTP_AICS_AUTO_GAIN_ONLY 0x08 +struct btp_aics_unmute_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_MAN_GAIN_SET 0x05 +struct btp_aics_manual_gain_cmd { + bt_addr_le_t address; +} __packed; -#define BTP_AICS_DESCRIPTION 0x09 +#define BTP_AICS_AUTO_GAIN_SET 0x06 +struct btp_aics_auto_gain_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_SET_MAN_GAIN_ONLY 0x07 +#define BTP_AICS_SET_AUTO_GAIN_ONLY 0x08 +#define BTP_AICS_AUDIO_DESCRIPTION_SET 0x09 struct btp_aics_audio_desc_cmd { uint8_t desc_len; uint8_t desc[0]; } __packed; #define BTP_AICS_MUTE_DISABLE 0x0a +#define BTP_AICS_GAIN_SETTING_PROP_GET 0x0b +struct btp_aics_gain_setting_prop_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_TYPE_GET 0x0c +struct btp_aics_type_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_STATUS_GET 0x0d +struct btp_aics_status_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_STATE_GET 0x0e +struct btp_aics_state_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_AICS_DESCRIPTION_GET 0x0f +struct btp_aics_desc_cmd { + bt_addr_le_t address; +} __packed; + +/* AICS events */ +#define BTP_AICS_STATE_EV 0x80 +struct btp_aics_state_ev { + bt_addr_le_t address; + int8_t gain; + uint8_t mute; + uint8_t mode; +} __packed; + +#define BTP_GAIN_SETTING_PROPERTIES_EV 0x81 +struct btp_gain_setting_properties_ev { + bt_addr_le_t address; + uint8_t units; + int8_t minimum; + int8_t maximum; +} __packed; + +#define BTP_AICS_INPUT_TYPE_EV 0x82 +struct btp_aics_input_type_ev { + bt_addr_le_t address; + uint8_t input_type; +} __packed; + +#define BTP_AICS_STATUS_EV 0x83 +struct btp_aics_status_ev { + bt_addr_le_t address; + bool active; +} __packed; + +#define BTP_AICS_DESCRIPTION_EV 0x84 +struct btp_aics_description_ev { + bt_addr_le_t address; + uint8_t data_len; + char data[0]; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/btp_micp.h b/tests/bluetooth/tester/src/btp/btp_micp.h new file mode 100644 index 00000000000..000e879e5f4 --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_micp.h @@ -0,0 +1,47 @@ +/* btp_micp.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* MICP commands */ +#define BTP_MICP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_micp_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MICP_CTLR_DISCOVER 0x02 +struct btp_micp_discover_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_CTLR_MUTE_READ 0x03 +struct btp_micp_mute_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_CTLR_MUTE 0x04 +struct btp_micp_mute_cmd { + bt_addr_le_t address; +} __packed; + +/* MICP events */ +#define BTP_MICP_DISCOVERED_EV 0x80 +struct btp_micp_discovered_ev { + bt_addr_le_t address; + uint16_t mute_handle; + uint16_t state_handle; + uint16_t gain_handle; + uint16_t type_handle; + uint16_t status_handle; + uint16_t control_handle; + uint16_t desc_handle; +} __packed; + +#define BTP_MICP_MUTE_STATE_EV 0x81 +struct btp_micp_mute_state_ev { + bt_addr_le_t address; + uint8_t mute; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index b30eee70d44..e3ba93b0de7 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -92,3 +92,6 @@ uint8_t tester_unregister_has(void); uint8_t tester_init_csis(void); uint8_t tester_unregister_csis(void); + +uint8_t tester_init_micp(void); +uint8_t tester_unregister_micp(void); diff --git a/tests/bluetooth/tester/src/btp_aics.c b/tests/bluetooth/tester/src/btp_aics.c new file mode 100644 index 00000000000..185053ab00b --- /dev/null +++ b/tests/bluetooth/tester/src/btp_aics.c @@ -0,0 +1,566 @@ +/* btp_aics.c - Bluetooth AICS Tester */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bap_endpoint.h" +#include "btp/btp.h" + +#define LOG_MODULE_NAME bttester_aics +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); + +#define BT_AICS_MAX_INPUT_DESCRIPTION_SIZE 16 +#define BT_AICS_MAX_OUTPUT_DESCRIPTION_SIZE 16 + +struct btp_aics_instance aics_client_instance; +struct btp_aics_instance aics_server_instance; + +static struct net_buf_simple *rx_ev_buf = NET_BUF_SIMPLE(BT_AICS_MAX_INPUT_DESCRIPTION_SIZE + + sizeof(struct btp_aics_description_ev)); + +static uint8_t aics_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + struct btp_aics_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_AICS_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_AICS_SET_GAIN); + tester_set_bit(rp->data, BTP_AICS_MUTE); + tester_set_bit(rp->data, BTP_AICS_UNMUTE); + tester_set_bit(rp->data, BTP_AICS_MAN_GAIN_SET); + tester_set_bit(rp->data, BTP_AICS_AUTO_GAIN_SET); + tester_set_bit(rp->data, BTP_AICS_SET_MAN_GAIN_ONLY); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_AICS_SET_AUTO_GAIN_ONLY); + tester_set_bit(rp->data, BTP_AICS_AUDIO_DESCRIPTION_SET); + tester_set_bit(rp->data, BTP_AICS_MUTE_DISABLE); + tester_set_bit(rp->data, BTP_AICS_GAIN_SETTING_PROP_GET); + tester_set_bit(rp->data, BTP_AICS_TYPE_GET); + tester_set_bit(rp->data, BTP_AICS_STATUS_GET); + tester_set_bit(rp->data, BTP_AICS_STATE_GET); + + /* octet 2 */ + tester_set_bit(rp->data, BTP_AICS_DESCRIPTION_GET); + + *rsp_len = sizeof(*rp) + 2; + + return BTP_STATUS_SUCCESS; +} + +void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uint8_t mode) +{ + struct btp_aics_state_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.gain = gain; + ev.mute = mute; + ev.mode = mode; + + tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_STATE_EV, &ev, sizeof(ev)); +} + +void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t units, int8_t minimum, + int8_t maximum) +{ + struct btp_gain_setting_properties_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.units = units; + ev.minimum = minimum; + ev.maximum = maximum; + + tester_event(BTP_SERVICE_ID_AICS, BTP_GAIN_SETTING_PROPERTIES_EV, &ev, sizeof(ev)); +} + +void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t input_type) +{ + struct btp_aics_input_type_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.input_type = input_type; + + tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_INPUT_TYPE_EV, &ev, sizeof(ev)); +} + +void btp_send_aics_status_ev(struct bt_conn *conn, bool active) +{ + struct btp_aics_status_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.active = active; + + tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_STATUS_EV, &ev, sizeof(ev)); +} + +void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t data_len, char *description) +{ + struct btp_aics_description_ev *ev; + + net_buf_simple_init(rx_ev_buf, 0); + + ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev)); + + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); + + ev->data_len = data_len; + memcpy(ev->data, description, data_len); + + tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_DESCRIPTION_EV, ev, sizeof(*ev) + data_len); +} + +static uint8_t aics_set_gain(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_set_gain_cmd *cp = cmd; + + LOG_DBG("AICS set gain %d", cp->gain); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_gain_set(aics_client_instance.aics[0], cp->gain) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_gain_set(aics_server_instance.aics[i], cp->gain) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_unmute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_unmute_cmd *cp = cmd; + + LOG_DBG("AICS Unmute"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_unmute(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_unmute(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_mute_cmd *cp = cmd; + + LOG_DBG("AICS Mute"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_mute(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_mute(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_state_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_state_cmd *cp = cmd; + + LOG_DBG("AICS State"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_state_get(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_state_get(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_type_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_type_cmd *cp = cmd; + + LOG_DBG("AICS Type"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_type_get(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_type_get(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_status_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_status_cmd *cp = cmd; + + LOG_DBG("AICS Status"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_status_get(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_status_get(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_gain_setting_prop_get(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_aics_gain_setting_prop_cmd *cp = cmd; + + LOG_DBG("AICS Gain settings properties"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_gain_setting_get(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_gain_setting_get(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_man_gain_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_manual_gain_cmd *cp = cmd; + + LOG_DBG("AICS set manual gain mode"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_manual_gain_set(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_manual_gain_set(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_auto_gain_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_auto_gain_cmd *cp = cmd; + + LOG_DBG("AICS set automatic gain mode"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_automatic_gain_set(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_automatic_gain_set(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_set_man_gain_only(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + LOG_DBG("AICS manual gain only set"); + + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_gain_set_manual_only(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_set_auto_gain_only(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + LOG_DBG("AICS auto gain only set"); + + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_gain_set_auto_only(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_mute_disable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS disable mute"); + + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_disable_mute(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_desc_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_audio_desc_cmd *cp = cmd; + char description[BT_AICS_MAX_INPUT_DESCRIPTION_SIZE]; + + LOG_DBG("AICS set description"); + + if (cmd_len < sizeof(*cp) || cmd_len != sizeof(*cp) + cp->desc_len) { + return BTP_STATUS_FAILED; + } + + if (cp->desc_len >= sizeof(description)) { + return BTP_STATUS_FAILED; + } + + if (cp->desc_len > (BT_AICS_MAX_INPUT_DESCRIPTION_SIZE - 1)) { + return BTP_STATUS_FAILED; + } + + memcpy(description, cp->desc, cp->desc_len); + description[cp->desc_len] = '\0'; + + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_description_set(aics_server_instance.aics[i], description) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t aics_desc_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_aics_desc_cmd *cp = cmd; + + LOG_DBG("AICS Description"); + + if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) { + if (bt_aics_description_get(aics_client_instance.aics[0]) != 0) { + return BTP_STATUS_FAILED; + } + } else { + for (uint8_t i = 0; i < aics_server_instance.aics_cnt; i++) { + if (bt_aics_description_get(aics_server_instance.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + } + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler aics_handlers[] = { + { + .opcode = BTP_AICS_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = aics_supported_commands, + }, + { + .opcode = BTP_AICS_SET_GAIN, + .expect_len = sizeof(struct btp_aics_set_gain_cmd), + .func = aics_set_gain, + }, + { + .opcode = BTP_AICS_MUTE, + .expect_len = sizeof(struct btp_aics_mute_cmd), + .func = aics_mute, + }, + { + .opcode = BTP_AICS_UNMUTE, + .expect_len = sizeof(struct btp_aics_unmute_cmd), + .func = aics_unmute, + }, + { + .opcode = BTP_AICS_GAIN_SETTING_PROP_GET, + .expect_len = sizeof(struct btp_aics_gain_setting_prop_cmd), + .func = aics_gain_setting_prop_get, + }, + { + .opcode = BTP_AICS_MUTE_DISABLE, + .expect_len = 0, + .func = aics_mute_disable, + }, + { + .opcode = BTP_AICS_MAN_GAIN_SET, + .expect_len = sizeof(struct btp_aics_manual_gain_cmd), + .func = aics_man_gain_set, + }, + { + .opcode = BTP_AICS_AUTO_GAIN_SET, + .expect_len = sizeof(struct btp_aics_auto_gain_cmd), + .func = aics_auto_gain_set, + }, + { + .opcode = BTP_AICS_SET_AUTO_GAIN_ONLY, + .expect_len = 0, + .func = aics_set_auto_gain_only, + }, + { + .opcode = BTP_AICS_SET_MAN_GAIN_ONLY, + .expect_len = 0, + .func = aics_set_man_gain_only, + }, + { + .opcode = BTP_AICS_AUDIO_DESCRIPTION_SET, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = aics_desc_set, + }, + { + .opcode = BTP_AICS_DESCRIPTION_GET, + .expect_len = sizeof(struct btp_aics_desc_cmd), + .func = aics_desc_get, + }, + { + .opcode = BTP_AICS_TYPE_GET, + .expect_len = sizeof(struct btp_aics_type_cmd), + .func = aics_type_get, + }, + { + .opcode = BTP_AICS_STATUS_GET, + .expect_len = sizeof(struct btp_aics_status_cmd), + .func = aics_status_get, + }, + { + .opcode = BTP_AICS_STATE_GET, + .expect_len = sizeof(struct btp_aics_state_cmd), + .func = aics_state_get, + }, +}; + +static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, uint8_t mute, uint8_t mode) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + btp_send_aics_state_ev(conn, gain, mute, mode); + + LOG_DBG("AICS state callback (%d)", err); +} + +static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, int8_t minimum, + int8_t maximum) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + btp_send_gain_setting_properties_ev(conn, units, minimum, maximum); + + LOG_DBG("AICS gain setting callback (%d)", err); +} + +static void aics_input_type_cb(struct bt_aics *inst, int err, uint8_t input_type) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + btp_send_aics_input_type_event(conn, input_type); + + LOG_DBG("AICS input type callback (%d)", err); +} + +static void aics_status_cb(struct bt_aics *inst, int err, bool active) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + btp_send_aics_status_ev(conn, active); + + LOG_DBG("AICS status callback (%d)", err); +} + +static void aics_description_cb(struct bt_aics *inst, int err, char *description) +{ + struct bt_conn *conn; + uint8_t data_len = strlen(description); + + bt_aics_client_conn_get(inst, &conn); + btp_send_aics_description_ev(conn, data_len, description); + + LOG_DBG("AICS description callback (%d)", err); +} + +struct bt_aics_cb aics_client_cb = { + .state = aics_state_cb, + .gain_setting = aics_gain_setting_cb, + .type = aics_input_type_cb, + .status = aics_status_cb, + .description = aics_description_cb, +}; + +uint8_t tester_init_aics(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_AICS, aics_handlers, + ARRAY_SIZE(aics_handlers)); + + return tester_init_vcs(); +} + +uint8_t tester_unregister_aics(void) +{ + return BTP_STATUS_SUCCESS; +} diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 36f92619bfc..e1dafb09351 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -80,6 +80,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_CSIP_SET_MEMBER) tester_set_bit(rp->data, BTP_SERVICE_ID_CSIS); #endif /* CONFIG_BT_CSIP_SET_MEMBER */ +#if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) + tester_set_bit(rp->data, BTP_SERVICE_ID_MICP); +#endif /* CONFIG_BT_MICP_MIC_DEV */ *rsp_len = sizeof(*rp) + 2; @@ -145,6 +148,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; + case BTP_SERVICE_ID_MICP: + status = tester_init_micp(); + break; #endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: @@ -228,6 +234,9 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_unregister_bap(); break; + case BTP_SERVICE_ID_MICP: + status = tester_unregister_micp(); + break; #endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: diff --git a/tests/bluetooth/tester/src/btp_micp.c b/tests/bluetooth/tester/src/btp_micp.c new file mode 100644 index 00000000000..52b071469af --- /dev/null +++ b/tests/bluetooth/tester/src/btp_micp.c @@ -0,0 +1,264 @@ +/* btp_micp.c - Bluetooth MICP Tester */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include <../../subsys/bluetooth/audio/micp_internal.h> +#include <../../subsys/bluetooth/audio/aics_internal.h> + +#include "bap_endpoint.h" +#include "btp/btp.h" + +#define LOG_MODULE_NAME bttester_micp +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); + +static struct bt_micp_mic_ctlr *mic_ctlr; + +#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) +static struct bt_micp_included micp_included; +struct chrc_handles { + uint16_t mute_handle; + uint16_t state_handle; + uint16_t gain_handle; + uint16_t type_handle; + uint16_t status_handle; + uint16_t control_handle; + uint16_t desc_handle; +}; +struct chrc_handles micp_handles; +extern struct btp_aics_instance aics_client_instance; +extern struct bt_aics_cb aics_client_cb; +#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ + +static void btp_send_micp_found_ev(struct bt_conn *conn, const struct chrc_handles *micp_handles) +{ + struct btp_micp_discovered_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.mute_handle = sys_cpu_to_le16(micp_handles->mute_handle); + ev.state_handle = sys_cpu_to_le16(micp_handles->state_handle); + ev.gain_handle = sys_cpu_to_le16(micp_handles->gain_handle); + ev.type_handle = sys_cpu_to_le16(micp_handles->type_handle); + ev.status_handle = sys_cpu_to_le16(micp_handles->status_handle); + ev.control_handle = sys_cpu_to_le16(micp_handles->control_handle); + ev.desc_handle = sys_cpu_to_le16(micp_handles->desc_handle); + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_DISCOVERED_EV, &ev, sizeof(ev)); +} + +static void btp_send_micp_mute_state_ev(struct bt_conn *conn, uint8_t mute) +{ + struct btp_micp_mute_state_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.mute = mute; + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_MUTE_STATE_EV, &ev, sizeof(ev)); +} + +static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, uint8_t mute) +{ + struct bt_conn *conn; + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute); + + LOG_DBG("MICP Mute cb (%d)", err); +} + +static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err) +{ + struct bt_conn *conn; + uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute_state); + + LOG_DBG("MICP Mute Written cb (%d))", err); +} + +static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err) +{ + struct bt_conn *conn; + uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute_state); + + LOG_DBG("MICP Mute Unwritten cb (%d))", err); +} + +static void micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, + uint8_t aics_count) +{ + struct bt_conn *conn; + + if (err) { + LOG_DBG("Discovery failed (%d)", err); + return; + } + + LOG_DBG("Discovery done with %u AICS", + aics_count); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + +#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) + if (bt_micp_mic_ctlr_included_get(mic_ctlr, &micp_included) != 0) { + LOG_DBG("Could not get included services"); + memset(&micp_handles, 0, sizeof(micp_handles)); + } else { + aics_client_instance.aics_cnt = micp_included.aics_cnt; + aics_client_instance.aics = micp_included.aics; + bt_aics_client_cb_register(aics_client_instance.aics[0], &aics_client_cb); + + micp_handles.state_handle = micp_included.aics[0]->cli.state_handle; + micp_handles.gain_handle = micp_included.aics[0]->cli.gain_handle; + micp_handles.type_handle = micp_included.aics[0]->cli.type_handle; + micp_handles.status_handle = micp_included.aics[0]->cli.status_handle; + micp_handles.control_handle = micp_included.aics[0]->cli.control_handle; + micp_handles.desc_handle = micp_included.aics[0]->cli.desc_handle; + } +#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ + + micp_handles.mute_handle = mic_ctlr->mute_handle; + btp_send_micp_found_ev(conn, &micp_handles); +} + +static struct bt_micp_mic_ctlr_cb micp_cbs = { + .discover = micp_mic_ctlr_discover_cb, + .mute = micp_mic_ctlr_mute_cb, + .mute_written = micp_mic_ctlr_mute_written_cb, + .unmute_written = micp_mic_ctlr_unmute_written_cb, +}; + +static uint8_t micp_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + struct btp_micp_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_MICP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_MICP_CTLR_DISCOVER); + tester_set_bit(rp->data, BTP_MICP_CTLR_MUTE_READ); + tester_set_bit(rp->data, BTP_MICP_CTLR_MUTE); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_discover(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_micp_discover_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_micp_mic_ctlr_discover(conn, &mic_ctlr); + if (err) { + LOG_DBG("Fail: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_mute_read(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("Read mute"); + + err = bt_micp_mic_ctlr_mute_get(mic_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("MICP Mute"); + + err = bt_micp_mic_ctlr_mute(mic_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler micp_handlers[] = { + { + .opcode = BTP_MICP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = micp_supported_commands, + }, + { + .opcode = BTP_MICP_CTLR_DISCOVER, + .expect_len = sizeof(struct btp_micp_discover_cmd), + .func = micp_discover, + }, + { + .opcode = BTP_MICP_CTLR_MUTE_READ, + .expect_len = sizeof(struct btp_micp_mute_read_cmd), + .func = micp_mute_read, + }, + { + .opcode = BTP_MICP_CTLR_MUTE, + .expect_len = sizeof(struct btp_micp_mute_cmd), + .func = micp_mute, + } +}; + +uint8_t tester_init_micp(void) +{ + int err; + + err = bt_micp_mic_ctlr_cb_register(&micp_cbs); + + if (err) { + LOG_DBG("Failed to register callbacks: %d", err); + return BTP_STATUS_FAILED; + } + + tester_register_command_handlers(BTP_SERVICE_ID_MICP, micp_handlers, + ARRAY_SIZE(micp_handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_micp(void) +{ + (void)bt_micp_mic_ctlr_cb_register(NULL); + return BTP_STATUS_SUCCESS; +} diff --git a/tests/bluetooth/tester/src/btp_vcp.c b/tests/bluetooth/tester/src/btp_vcp.c index 744adf8ddc1..a0000b29c51 100644 --- a/tests/bluetooth/tester/src/btp_vcp.c +++ b/tests/bluetooth/tester/src/btp_vcp.c @@ -15,6 +15,8 @@ #include "zephyr/bluetooth/audio/vocs.h" #include "zephyr/sys/util.h" +#include <../../subsys/bluetooth/audio/micp_internal.h> +#include <../../subsys/bluetooth/audio/aics_internal.h> #include #define LOG_MODULE_NAME bttester_vcp LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); @@ -26,6 +28,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); static struct bt_vcp_vol_rend_register_param vcp_register_param; static struct bt_vcp_included included; +extern struct btp_aics_instance aics_server_instance; /* Volume Control Service */ static uint8_t vcs_supported_commands(const void *cmd, uint16_t cmd_len, @@ -157,265 +160,6 @@ static const struct btp_handler vcs_handlers[] = { }, }; -/* Audio Input Control Service */ -static uint8_t aics_supported_commands(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct btp_aics_read_supported_commands_rp *rp = rsp; - - /* octet 0 */ - tester_set_bit(rp->data, BTP_AICS_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_AICS_SET_GAIN); - tester_set_bit(rp->data, BTP_AICS_MUTE); - tester_set_bit(rp->data, BTP_AICS_UNMUTE); - tester_set_bit(rp->data, BTP_AICS_MUTE_DISABLE); - tester_set_bit(rp->data, BTP_AICS_MAN_GAIN); - tester_set_bit(rp->data, BTP_AICS_AUTO_GAIN); - tester_set_bit(rp->data, BTP_AICS_MAN_GAIN_ONLY); - tester_set_bit(rp->data, BTP_AICS_AUTO_GAIN_ONLY); - - /* octet 1 */ - tester_set_bit(rp->data, BTP_AICS_DESCRIPTION); - - *rsp_len = sizeof(*rp) + 2; - - return BTP_STATUS_SUCCESS; -} - -static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, - uint8_t mute, uint8_t mode) -{ - LOG_DBG("AICS state callback (%d)", err); -} - -static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, - int8_t minimum, int8_t maximum) -{ - LOG_DBG("AICS gain setting callback (%d)", err); -} - -static void aics_input_type_cb(struct bt_aics *inst, int err, - uint8_t input_type) -{ - LOG_DBG("AICS input type callback (%d)", err); -} - -static void aics_status_cb(struct bt_aics *inst, int err, bool active) -{ - LOG_DBG("AICS status callback (%d)", err); -} - -static void aics_description_cb(struct bt_aics *inst, int err, - char *description) -{ - LOG_DBG("AICS description callback (%d)", err); -} - -static struct bt_aics_cb aics_cb = { - .state = aics_state_cb, - .gain_setting = aics_gain_setting_cb, - .type = aics_input_type_cb, - .status = aics_status_cb, - .description = aics_description_cb -}; - -static uint8_t aics_set_gain(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_aics_set_gain_cmd *cp = cmd; - - LOG_DBG("AICS set gain %d", cp->gain); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_gain_set(included.aics[0], cp->gain) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_mute(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS mute"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_mute(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_mute_disable(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS mute disable"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_disable_mute(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_unmute(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS unmute"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_unmute(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_man_gain(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS manual gain set"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_manual_gain_set(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_auto_gain(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS auto gain set"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_automatic_gain_set(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_auto_gain_only(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS auto gain only set"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_gain_set_auto_only(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_man_gain_only(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("AICS manual gain only set"); - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_gain_set_manual_only(included.aics[i]) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t aics_desc(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_aics_audio_desc_cmd *cp = cmd; - char description[BT_AICS_MAX_INPUT_DESCRIPTION_SIZE]; - - LOG_DBG("AICS description"); - - if (cmd_len < sizeof(*cp) || - cmd_len != sizeof(*cp) + cp->desc_len) { - return BTP_STATUS_FAILED; - } - - if (cp->desc_len >= sizeof(description)) { - return BTP_STATUS_FAILED; - } - - memcpy(description, cp->desc, cp->desc_len); - description[cp->desc_len] = '\0'; - - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT; i++) { - if (bt_aics_description_set(included.aics[i], description) != 0) { - return BTP_STATUS_FAILED; - } - } - - return BTP_STATUS_SUCCESS; -} - -static const struct btp_handler aics_handlers[] = { - { - .opcode = BTP_AICS_READ_SUPPORTED_COMMANDS, - .index = BTP_INDEX_NONE, - .expect_len = 0, - .func = aics_supported_commands, - }, - { - .opcode = BTP_AICS_SET_GAIN, - .expect_len = sizeof(struct btp_aics_set_gain_cmd), - .func = aics_set_gain, - }, - { - .opcode = BTP_AICS_MUTE, - .expect_len = 0, - .func = aics_mute, - }, - { - .opcode = BTP_AICS_UNMUTE, - .expect_len = 0, - .func = aics_unmute, - }, - { - .opcode = BTP_AICS_MUTE_DISABLE, - .expect_len = 0, - .func = aics_mute_disable, - }, - { - .opcode = BTP_AICS_MAN_GAIN, - .expect_len = 0, - .func = aics_man_gain, - }, - { - .opcode = BTP_AICS_AUTO_GAIN, - .expect_len = 0, - .func = aics_auto_gain, - }, - { - .opcode = BTP_AICS_AUTO_GAIN_ONLY, - .expect_len = 0, - .func = aics_auto_gain_only, - }, - { - .opcode = BTP_AICS_MAN_GAIN_ONLY, - .expect_len = 0, - .func = aics_man_gain_only, - }, - { - .opcode = BTP_AICS_DESCRIPTION, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = aics_desc, - }, -}; - /* Volume Offset Control Service */ static uint8_t vocs_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -515,6 +259,44 @@ static const struct btp_handler vocs_handlers[] = { }, }; +/* AICS Callbacks */ +static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, + uint8_t mute, uint8_t mode) +{ + LOG_DBG("AICS state callback (%d)", err); +} + +static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, + int8_t minimum, int8_t maximum) +{ + LOG_DBG("AICS gain setting callback (%d)", err); +} + +static void aics_input_type_cb(struct bt_aics *inst, int err, + uint8_t input_type) +{ + LOG_DBG("AICS input type callback (%d)", err); +} + +static void aics_status_cb(struct bt_aics *inst, int err, bool active) +{ + LOG_DBG("AICS status callback (%d)", err); +} + +static void aics_description_cb(struct bt_aics *inst, int err, + char *description) +{ + LOG_DBG("AICS description callback (%d)", err); +} + +struct bt_aics_cb aics_server_cb = { + .state = aics_state_cb, + .gain_setting = aics_gain_setting_cb, + .type = aics_input_type_cb, + .status = aics_status_cb, + .description = aics_description_cb, +}; + /* General profile handling */ static void set_register_params(uint8_t gain_mode) { @@ -545,7 +327,7 @@ static void set_register_params(uint8_t gain_mode) vcp_register_param.aics_param[i].units = 1; vcp_register_param.aics_param[i].min_gain = 0; vcp_register_param.aics_param[i].max_gain = 100; - vcp_register_param.aics_param[i].cb = &aics_cb; + vcp_register_param.aics_param[i].cb = &aics_server_cb; } vcp_register_param.step = 1; @@ -570,6 +352,9 @@ uint8_t tester_init_vcs(void) return BTP_STATUS_FAILED; } + aics_server_instance.aics_cnt = included.aics_cnt; + aics_server_instance.aics = included.aics; + tester_register_command_handlers(BTP_SERVICE_ID_VCS, vcs_handlers, ARRAY_SIZE(vcs_handlers)); @@ -581,19 +366,6 @@ uint8_t tester_unregister_vcs(void) return BTP_STATUS_SUCCESS; } -uint8_t tester_init_aics(void) -{ - tester_register_command_handlers(BTP_SERVICE_ID_AICS, aics_handlers, - ARRAY_SIZE(aics_handlers)); - - return tester_init_vcs(); -} - -uint8_t tester_unregister_aics(void) -{ - return BTP_STATUS_SUCCESS; -} - uint8_t tester_init_vocs(void) { tester_register_command_handlers(BTP_SERVICE_ID_VOCS, vocs_handlers, From a5f4beccd2f6a6bd3df5e7f23e2d4770c2b3a063 Mon Sep 17 00:00:00 2001 From: Jiang Wei W Date: Fri, 4 Aug 2023 11:42:10 +0800 Subject: [PATCH 0130/4498] drivers: ipm: add init version of sedi ipm driver add init version of sedi ipm driver Signed-off-by: Jiang Wei W --- drivers/ipm/CMakeLists.txt | 4 +- drivers/ipm/Kconfig | 1 + drivers/ipm/Kconfig.sedi | 11 + drivers/ipm/ipm_sedi.c | 297 +++++++++++++++++++++++++++ drivers/ipm/ipm_sedi.h | 49 +++++ dts/bindings/ipm/intel,sedi-ipm.yaml | 21 ++ dts/x86/intel/intel_ish5.dtsi | 10 + 7 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 drivers/ipm/Kconfig.sedi create mode 100644 drivers/ipm/ipm_sedi.c create mode 100644 drivers/ipm/ipm_sedi.h create mode 100644 dts/bindings/ipm/intel,sedi-ipm.yaml diff --git a/drivers/ipm/CMakeLists.txt b/drivers/ipm/CMakeLists.txt index f2d37bb67c9..dbc8affc7c2 100644 --- a/drivers/ipm/CMakeLists.txt +++ b/drivers/ipm/CMakeLists.txt @@ -13,7 +13,9 @@ zephyr_library_sources_ifdef(CONFIG_IPM_NRFX ipm_nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_IPM_CAVS_IDC ipm_cavs_idc.c) zephyr_library_sources_ifdef(CONFIG_IPM_STM32_HSEM ipm_stm32_hsem.c) zephyr_library_sources_ifdef(CONFIG_IPM_CAVS_HOST ipm_cavs_host.c) +zephyr_library_sources_ifdef(CONFIG_IPM_SEDI ipm_sedi.c) +zephyr_library_sources_ifdef(CONFIG_IPM_IVSHMEM ipm_ivshmem.c) zephyr_library_sources_ifdef(CONFIG_ESP32_SOFT_IPM ipm_esp32.c) zephyr_library_sources_ifdef(CONFIG_XLNX_IPI ipm_xlnx_ipi.c) + zephyr_library_sources_ifdef(CONFIG_USERSPACE ipm_handlers.c) -zephyr_library_sources_ifdef(CONFIG_IPM_IVSHMEM ipm_ivshmem.c) diff --git a/drivers/ipm/Kconfig b/drivers/ipm/Kconfig index 17c92b7e241..81c64202427 100644 --- a/drivers/ipm/Kconfig +++ b/drivers/ipm/Kconfig @@ -60,6 +60,7 @@ source "drivers/ipm/Kconfig.imx" source "drivers/ipm/Kconfig.stm32" source "drivers/ipm/Kconfig.intel_adsp" source "drivers/ipm/Kconfig.ivshmem" +source "drivers/ipm/Kconfig.sedi" module = IPM diff --git a/drivers/ipm/Kconfig.sedi b/drivers/ipm/Kconfig.sedi new file mode 100644 index 00000000000..bbb347dd5f4 --- /dev/null +++ b/drivers/ipm/Kconfig.sedi @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Intel Corporation + +config IPM_SEDI + bool "Intel SEDI IPM Driver" + default y if DT_HAS_INTEL_SEDI_IPM_ENABLED + select IPM_CALLBACK_ASYNC + help + This option enables the Intel SEDI IPM(IPC) driver. + This driver is simply a shim driver built upon the SEDI + bare metal IPC driver in the hal-intel module diff --git a/drivers/ipm/ipm_sedi.c b/drivers/ipm/ipm_sedi.c new file mode 100644 index 00000000000..04a48029c6d --- /dev/null +++ b/drivers/ipm/ipm_sedi.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_sedi_ipm + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(ipm_sedi, CONFIG_IPM_LOG_LEVEL); + +#include "ipm_sedi.h" + +extern void sedi_ipc_isr(IN sedi_ipc_t ipc_device); + +static void set_ipm_dev_busy(const struct device *dev, bool is_write) +{ + struct ipm_sedi_context *ipm = dev->data; + unsigned int key = irq_lock(); + + atomic_set_bit(&ipm->status, is_write ? IPM_WRITE_BUSY_BIT : IPM_READ_BUSY_BIT); + pm_device_busy_set(dev); + irq_unlock(key); +} + +static void clear_ipm_dev_busy(const struct device *dev, bool is_write) +{ + struct ipm_sedi_context *ipm = dev->data; + unsigned int key = irq_lock(); + + atomic_clear_bit(&ipm->status, is_write ? IPM_WRITE_BUSY_BIT : IPM_READ_BUSY_BIT); + if ((!atomic_test_bit(&ipm->status, IPM_WRITE_BUSY_BIT)) + && (!atomic_test_bit(&ipm->status, IPM_READ_BUSY_BIT))) { + pm_device_busy_clear(dev); + } + irq_unlock(key); +} + +static void ipm_event_dispose(IN sedi_ipc_t device, IN uint32_t event, INOUT void *params) +{ + const struct device *dev = (const struct device *)params; + struct ipm_sedi_context *ipm = dev->data; + uint32_t drbl_in = 0, len; + + LOG_DBG("dev: %u, event: %u", device, event); + switch (event) { + case SEDI_IPC_EVENT_MSG_IN: + if (ipm->rx_msg_notify_cb != NULL) { + set_ipm_dev_busy(dev, false); + sedi_ipc_read_dbl(device, &drbl_in); + len = IPC_HEADER_GET_LENGTH(drbl_in); + sedi_ipc_read_msg(device, ipm->incoming_data_buf, len); + ipm->rx_msg_notify_cb(dev, + ipm->rx_msg_notify_cb_data, + drbl_in, ipm->incoming_data_buf); + } else { + LOG_WRN("no handler for ipm new msg"); + } + break; + case SEDI_IPC_EVENT_MSG_PEER_ACKED: + if (atomic_test_bit(&ipm->status, IPM_WRITE_IN_PROC_BIT)) { + k_sem_give(&ipm->device_write_msg_sem); + } else { + LOG_WRN("no sending in progress, got an ack"); + } + break; + default: + return; + } +} + +static int ipm_init(const struct device *dev) +{ + /* allocate resource and context*/ + const struct ipm_sedi_config_t *info = dev->config; + sedi_ipc_t device = info->ipc_device; + struct ipm_sedi_context *ipm = dev->data; + + info->irq_config(); + k_sem_init(&ipm->device_write_msg_sem, 0, 1); + k_mutex_init(&ipm->device_write_lock); + ipm->status = 0; + + sedi_ipc_init(device, ipm_event_dispose, (void *)dev); + atomic_set_bit(&ipm->status, IPM_PEER_READY_BIT); + LOG_DBG("ipm driver initialized on device: %p", dev); + return 0; +} + +static int ipm_send_isr(const struct device *dev, + uint32_t drbl, + const void *msg, + int msg_size) +{ + const struct ipm_sedi_config_t *info = dev->config; + sedi_ipc_t device = info->ipc_device; + uint32_t drbl_acked = 0; + + sedi_ipc_write_msg(device, (uint8_t *)msg, + (uint32_t)msg_size); + sedi_ipc_write_dbl(device, drbl); + do { + sedi_ipc_read_ack_drbl(device, &drbl_acked); + } while ((drbl_acked & BIT(IPC_BUSY_BIT)) == 0); + + return 0; +} + +static int ipm_sedi_send(const struct device *dev, + int wait, + uint32_t drbl, + const void *msg, + int msg_size) +{ + __ASSERT((dev != NULL), "bad params\n"); + const struct ipm_sedi_config_t *info = dev->config; + struct ipm_sedi_context *ipm = dev->data; + sedi_ipc_t device = info->ipc_device; + int ret, sedi_ret; + + /* check params, check status */ + if ((msg_size > IPC_DATA_LEN_MAX) || ((msg_size > 0) && (msg == NULL)) || + ((drbl & BIT(IPC_BUSY_BIT)) == 0)) { + LOG_ERR("bad params when sending ipm msg on device: %p", dev); + return -EINVAL; + } + + if (wait == 0) { + LOG_ERR("not support no wait mode when sending ipm msg"); + return -ENOTSUP; + } + + if (k_is_in_isr()) { + return ipm_send_isr(dev, drbl, msg, msg_size); + } + + k_mutex_lock(&ipm->device_write_lock, K_FOREVER); + set_ipm_dev_busy(dev, true); + + if (!atomic_test_bit(&ipm->status, IPM_PEER_READY_BIT)) { + LOG_WRN("peer is not ready"); + ret = -EBUSY; + goto write_err; + } + + /* write data regs */ + if (msg_size > 0) { + sedi_ret = sedi_ipc_write_msg(device, (uint8_t *)msg, + (uint32_t)msg_size); + if (sedi_ret != SEDI_DRIVER_OK) { + LOG_ERR("ipm write data fail on device: %p", dev); + ret = -EBUSY; + goto write_err; + } + } + + atomic_set_bit(&ipm->status, IPM_WRITE_IN_PROC_BIT); + /* write drbl regs to interrupt peer*/ + sedi_ret = sedi_ipc_write_dbl(device, drbl); + + if (sedi_ret != SEDI_DRIVER_OK) { + LOG_ERR("ipm write doorbell fail on device: %p", dev); + ret = -EBUSY; + goto func_out; + } + + /* wait for busy-bit-consumed interrupt */ + ret = k_sem_take(&ipm->device_write_msg_sem, K_MSEC(IPM_TIMEOUT_MS)); + if (ret) { + LOG_WRN("ipm write timeout on device: %p", dev); + sedi_ipc_write_dbl(device, 0); + } + +func_out: + atomic_clear_bit(&ipm->status, IPM_WRITE_IN_PROC_BIT); + +write_err: + clear_ipm_dev_busy(dev, true); + k_mutex_unlock(&ipm->device_write_lock); + if (ret == 0) { + LOG_DBG("ipm wrote a new message on device: %p, drbl=%08x", + dev, drbl); + } + return ret; +} + +static void ipm_sedi_register_callback(const struct device *dev, ipm_callback_t cb, + void *user_data) +{ + __ASSERT((dev != NULL), "bad params\n"); + + struct ipm_sedi_context *ipm = dev->data; + + if (cb == NULL) { + LOG_ERR("bad params when add ipm callback on device: %p", dev); + return; + } + + if (ipm->rx_msg_notify_cb == NULL) { + ipm->rx_msg_notify_cb = cb; + ipm->rx_msg_notify_cb_data = user_data; + } else { + LOG_ERR("ipm rx callback already exists on device: %p", dev); + } +} + +static void ipm_sedi_complete(const struct device *dev) +{ + int ret; + + __ASSERT((dev != NULL), "bad params\n"); + + const struct ipm_sedi_config_t *info = dev->config; + sedi_ipc_t device = info->ipc_device; + + ret = sedi_ipc_send_ack_drbl(device, 0); + if (ret != SEDI_DRIVER_OK) { + LOG_ERR("ipm send ack drl fail on device: %p", dev); + } + + clear_ipm_dev_busy(dev, false); +} + +static int ipm_sedi_get_max_data_size(const struct device *ipmdev) +{ + ARG_UNUSED(ipmdev); + return IPC_DATA_LEN_MAX; +} + +static uint32_t ipm_sedi_get_max_id(const struct device *ipmdev) +{ + ARG_UNUSED(ipmdev); + return UINT32_MAX; +} + +static int ipm_sedi_set_enable(const struct device *dev, int enable) +{ + __ASSERT((dev != NULL), "bad params\n"); + + const struct ipm_sedi_config_t *info = dev->config; + + if (enable) { + irq_enable(info->irq_num); + } else { + irq_disable(info->irq_num); + } + return 0; +} + +#if defined(CONFIG_PM_DEVICE) +static int ipm_power_ctrl(const struct device *dev, + enum pm_device_action action) +{ + return 0; +} +#endif + +static const struct ipm_driver_api ipm_funcs = { + .send = ipm_sedi_send, + .register_callback = ipm_sedi_register_callback, + .max_data_size_get = ipm_sedi_get_max_data_size, + .max_id_val_get = ipm_sedi_get_max_id, + .complete = ipm_sedi_complete, + .set_enabled = ipm_sedi_set_enable +}; + +#define IPM_SEDI_DEV_DEFINE(n) \ + static struct ipm_sedi_context ipm_data_##n; \ + static void ipm_##n##_irq_config(void); \ + static const struct ipm_sedi_config_t ipm_config_##n = { \ + .ipc_device = DT_INST_PROP(n, peripheral_id), \ + .irq_num = DT_INST_IRQN(n), \ + .irq_config = ipm_##n##_irq_config, \ + }; \ + static void ipm_##n##_irq_config(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), sedi_ipc_isr, \ + DT_INST_PROP(n, peripheral_id), \ + DT_INST_IRQ(n, sense)); \ + } \ + PM_DEVICE_DT_DEFINE(DT_NODELABEL(ipm##n), ipm_power_ctrl); \ + DEVICE_DT_INST_DEFINE(n, \ + &ipm_init, \ + PM_DEVICE_DT_GET(DT_NODELABEL(ipm##n)), \ + &ipm_data_##n, \ + &ipm_config_##n, \ + POST_KERNEL, \ + 0, \ + &ipm_funcs); + +DT_INST_FOREACH_STATUS_OKAY(IPM_SEDI_DEV_DEFINE) diff --git a/drivers/ipm/ipm_sedi.h b/drivers/ipm/ipm_sedi.h new file mode 100644 index 00000000000..bb1e945c2c2 --- /dev/null +++ b/drivers/ipm/ipm_sedi.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __DRIVERS_IPM_SEDI_H +#define __DRIVERS_IPM_SEDI_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "sedi_driver_common.h" +#include "sedi_driver_ipc.h" +#include "zephyr/sys/atomic.h" + +/* + * bit 31 indicates whether message is valid, and could generate interrupt + * while set/clear + */ +#define IPC_BUSY_BIT 31 + +#define IPM_WRITE_IN_PROC_BIT 0 +#define IPM_WRITE_BUSY_BIT 1 +#define IPM_READ_BUSY_BIT 2 +#define IPM_PEER_READY_BIT 3 + +#define IPM_TIMEOUT_MS 1000 + +struct ipm_sedi_config_t { + sedi_ipc_t ipc_device; + int32_t irq_num; + void (*irq_config)(void); +}; + +struct ipm_sedi_context { + ipm_callback_t rx_msg_notify_cb; + void *rx_msg_notify_cb_data; + uint8_t incoming_data_buf[IPC_DATA_LEN_MAX]; + struct k_sem device_write_msg_sem; + struct k_mutex device_write_lock; + atomic_t status; + uint32_t power_status; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __DRIVERS_IPM_SEDI_H */ diff --git a/dts/bindings/ipm/intel,sedi-ipm.yaml b/dts/bindings/ipm/intel,sedi-ipm.yaml new file mode 100644 index 00000000000..48acb7d9b70 --- /dev/null +++ b/dts/bindings/ipm/intel,sedi-ipm.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: INTEL SEDI IPM controller. + +compatible: "intel,sedi-ipm" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + peripheral-id: + type: int + required: true + description: sedi instance id of ipm diff --git a/dts/x86/intel/intel_ish5.dtsi b/dts/x86/intel/intel_ish5.dtsi index fece4af299f..51f15907bef 100644 --- a/dts/x86/intel/intel_ish5.dtsi +++ b/dts/x86/intel/intel_ish5.dtsi @@ -95,6 +95,16 @@ status = "okay"; }; + ipmhost: ipm@4100000 { + compatible = "intel,sedi-ipm"; + reg = <0x4100000 0x1000>; + peripheral-id = <0>; + interrupt-parent = <&intc>; + interrupts = <0 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "okay"; + }; + uart0: uart@8100000 { compatible = "intel,sedi-uart"; reg = <0x08100000 0x1000>; From 7e66bb1e09c5832a14d4b0636ef3f6fdf74a2239 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 18 Aug 2023 10:32:19 +0200 Subject: [PATCH 0131/4498] Bluetooth: ISO: Reject disconnecting pending CIS as peripheral As per the core spec, the CIS is not allowed to disconnect a CIS if it is pending (i.e. in the connecting state). Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/iso.h | 13 ++++++++++--- subsys/bluetooth/host/iso.c | 8 ++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index b9fc3e549dc..05b9b0fbed9 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -808,10 +808,17 @@ int bt_iso_cig_terminate(struct bt_iso_cig *cig); */ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count); -/** @brief Disconnect ISO channel +/** @brief Disconnect connected ISO channel + * + * Disconnect connected ISO channel. + * + * If the device is a central and the connection is pending it will be + * canceled and as a result the channel bt_iso_chan_ops.disconnected() callback is called. + * + * If the device is a peripheral and the connection is pending it will be rejected, as a peripheral + * shall wait for a CIS Established event (which may trigger a bt_iso_chan_ops.disconnected() + * callback in case of an error). * - * Disconnect ISO channel, if the connection is pending it will be - * canceled and as a result the channel disconnected() callback is called. * Regarding to input parameter, to get details see reference description * to bt_iso_chan_connect() API above. * diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index f8df05e32d9..2bae70abc15 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -970,6 +970,14 @@ int bt_iso_chan_disconnect(struct bt_iso_chan *chan) return -EALREADY; } + if (IS_ENABLED(CONFIG_BT_ISO_PERIPHERAL) && chan->iso->role == BT_HCI_ROLE_PERIPHERAL && + chan->state == BT_ISO_STATE_CONNECTING) { + /* A CIS peripheral is not allowed to disconnect a CIS in the connecting state - It + * has to wait for a CIS Established event + */ + return -EAGAIN; + } + err = bt_conn_disconnect(chan->iso, BT_HCI_ERR_REMOTE_USER_TERM_CONN); if (err == 0) { bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTING); From 1e50132237cb92f6b56026b733eb02bbb49d35c4 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 5 Sep 2023 15:48:20 +0200 Subject: [PATCH 0132/4498] Bluetooth: ISO: Handle central disc of pending CIS If the central disconnects a CIS while it is being established, then we receive both a CIS established event with BT_HCI_ERR_OP_CANCELLED_BY_HOST and a disconnect complete event. In this case we should not call bt_iso_disconnected in the CIS established event handler, as that will also be called from the disconnect complete event handler. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/iso.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 2bae70abc15..af408b9dd98 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -1035,8 +1035,14 @@ void hci_le_cis_established(struct net_buf *buf) /* ISO connection handles are already assigned at this point */ iso = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ISO); if (!iso) { - LOG_ERR("No connection found for handle %u", handle); - bt_conn_unref(iso); + /* If it is a local disconnect, then we may have received the disconnect complete + * event before this event, and in which case we do not expect to find the CIS + * object + */ + if (evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) { + LOG_ERR("No connection found for handle %u", handle); + } + return; } @@ -1107,10 +1113,11 @@ void hci_le_cis_established(struct net_buf *buf) bt_conn_set_state(iso, BT_CONN_CONNECTED); bt_conn_unref(iso); return; - } + } else if (evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) { + iso->err = evt->status; + bt_iso_disconnected(iso); + } /* else we wait for disconnect event */ - iso->err = evt->status; - bt_iso_disconnected(iso); bt_conn_unref(iso); } From 72ee4f75ef74011c33b50981fe8eb331f9bb4fed Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Mon, 22 May 2023 23:30:08 -0700 Subject: [PATCH 0133/4498] driver: adc: npcx: add multi-device support in npcx adc driver Add multi-device support in npcx adc driver since there is more than one adc module in npcx4 series. And each adc's reference voltage might be different, this CL introduces the `vref-mv` prop. to select its own reference voltage. Signed-off-by: Mulin Chao Signed-off-by: Kate Yen --- drivers/adc/adc_npcx.c | 232 +++++++++++------- .../nuvoton_adc_cmp_npcx/adc_cmp_npcx.c | 4 +- dts/arm/nuvoton/npcx/npcx.dtsi | 1 + dts/arm/nuvoton/npcx/npcx4.dtsi | 14 ++ dts/bindings/adc/nuvoton,npcx-adc.yaml | 4 + .../zephyr/drivers/adc/adc_npcx_threshold.h | 4 +- soc/arm/nuvoton_npcx/common/reg/reg_def.h | 10 +- 7 files changed, 180 insertions(+), 89 deletions(-) diff --git a/drivers/adc/adc_npcx.c b/drivers/adc/adc_npcx.c index 4bd81c9ef37..119a61f72aa 100644 --- a/drivers/adc/adc_npcx.c +++ b/drivers/adc/adc_npcx.c @@ -28,23 +28,24 @@ LOG_MODULE_REGISTER(adc_npcx, CONFIG_ADC_LOG_LEVEL); #define ADC_REGULAR_GENDLY_VAL 0x0100 #define ADC_REGULAR_MEAST_VAL 0x0001 -/* ADC channel number */ -#define NPCX_ADC_CH_COUNT DT_INST_PROP(0, channel_count) - /* ADC targeted operating frequency (2MHz) */ #define NPCX_ADC_CLK 2000000 -/* ADC internal reference voltage (Unit:mV) */ -#define NPCX_ADC_VREF_VOL 2816 - /* ADC conversion mode */ #define NPCX_ADC_CHN_CONVERSION_MODE 0 #define NPCX_ADC_SCAN_CONVERSION_MODE 1 +/* Max channel number to be converted in ADCCS */ +#define NPCX_ADCCS_MAX_CHANNEL_COUNT 16 + #define ADC_NPCX_THRVAL_RESOLUTION 10 #define ADC_NPCX_THRVAL_MAX BIT_MASK(ADC_NPCX_THRVAL_RESOLUTION) +/* ADC threshold detection registers */ #define THRCTL(dev, ctl_no) (*((volatile uint16_t *) npcx_thrctl_reg(dev, ctl_no))) +#ifdef CONFIG_SOC_SERIES_NPCX4 +#define THEN(dev) (*((volatile uint16_t *) npcx_then_reg(dev))) +#endif /* Device config */ struct adc_npcx_config { @@ -52,10 +53,14 @@ struct adc_npcx_config { uintptr_t base; /* clock configuration */ struct npcx_clk_cfg clk_cfg; + /* the number of ADC channels */ + const uint8_t channel_count; /* amount of thresholds supported */ const uint8_t threshold_count; /* threshold control register offset */ const uint16_t threshold_reg_offset; + /* routine for configuring ADC's ISR */ + void (*irq_cfg_func)(void); const struct pinctrl_dev_config *pcfg; }; @@ -88,7 +93,7 @@ struct adc_npcx_threshold_data { * channels being used in repetitive mode in order to set ADC registers * back to threshold detection when adc_npcx_read is completed. */ - uint16_t repetitive_channels; + uint32_t repetitive_channels; /* * While threshold interruption is enabled, adc_npcx_read must disable * all active threshold running to avoid race condition, this variable @@ -98,11 +103,6 @@ struct adc_npcx_threshold_data { /* This array holds current configuration for each threshold. */ struct adc_npcx_threshold_control control[DT_INST_PROP(0, threshold_count)]; - /* - * Pointer of work queue thread to be notified when threshold assertion - * occurs. - */ - struct k_work_q *work_q; }; /* Driver data */ @@ -115,7 +115,7 @@ struct adc_npcx_data { * Bit-mask indicating the channels to be included in each sampling * of this sequence. */ - uint16_t channels; + uint32_t channels; /* ADC Device pointer used in api functions */ const struct device *adc_dev; uint16_t *buffer; @@ -129,6 +129,12 @@ struct adc_npcx_data { #endif }; +/* + * Pointer of internal work queue thread to be notified when threshold assertion + * occurs if CONFIG_ADC_CMP_NPCX_WORKQUEUE is enabled. + */ +struct k_work_q *work_q; + /* Driver convenience defines */ #define HAL_INSTANCE(dev) ((struct adc_reg *)((const struct adc_npcx_config *)(dev)->config)->base) @@ -150,6 +156,20 @@ static void adc_npcx_pm_policy_state_lock_put(struct adc_npcx_data *data) } #endif +static inline void adc_npcx_config_channels(const struct device *dev, uint32_t channels) +{ + const struct adc_npcx_config *config = dev->config; + struct adc_reg *const inst = HAL_INSTANCE(dev); + + inst->ADCCS = channels & BIT_MASK(NPCX_ADCCS_MAX_CHANNEL_COUNT); + + /* Only npcx4 and later series support over 16 ADC channels */ + if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) { + inst->ADCCS2 = (channels >> NPCX_ADCCS_MAX_CHANNEL_COUNT) & + BIT_MASK(NPCX_ADCCS_MAX_CHANNEL_COUNT); + } +} + static inline uint32_t npcx_thrctl_reg(const struct device *dev, uint32_t ctl_no) { @@ -158,6 +178,34 @@ static inline uint32_t npcx_thrctl_reg(const struct device *dev, return (config->base + config->threshold_reg_offset) + (ctl_no - 1) * 2; } +#ifdef CONFIG_SOC_SERIES_NPCX4 +static inline uint32_t npcx_then_reg(const struct device *dev) +{ + const struct adc_npcx_config *config = dev->config; + + return (config->base + config->threshold_reg_offset + 0x10); +} +#endif + +static inline void adc_npcx_enable_threshold_detect(const struct device *dev, uint8_t th_sel, + bool enable) +{ + if (enable) { +#ifdef CONFIG_SOC_SERIES_NPCX4 + THEN(dev) |= BIT(th_sel); +#else + THRCTL(dev, (th_sel + 1)) |= BIT(NPCX_THRCTL_THEN); +#endif + + } else { +#ifdef CONFIG_SOC_SERIES_NPCX4 + THEN(dev) &= ~BIT(th_sel); +#else + THRCTL(dev, (th_sel + 1)) &= ~BIT(NPCX_THRCTL_THEN); +#endif + } +} + static void adc_npcx_isr(const struct device *dev) { const struct adc_npcx_config *config = dev->config; @@ -198,12 +246,12 @@ static void adc_npcx_isr(const struct device *dev) if (IS_ENABLED(CONFIG_ADC_CMP_NPCX) && t_data->active_thresholds) { /* Set repetitive channels back */ - inst->ADCCS = t_data->repetitive_channels; + adc_npcx_config_channels(dev, t_data->repetitive_channels); /* Start conversion */ inst->ADCCNF |= BIT(NPCX_ADCCNF_START); } else { /* Disable all channels */ - inst->ADCCS = 0; + adc_npcx_config_channels(dev, 0); /* Turn off ADC */ inst->ADCCNF &= ~(BIT(NPCX_ADCCNF_ADCEN)); @@ -231,9 +279,8 @@ static void adc_npcx_isr(const struct device *dev) inst->THRCTS = thrcts; if (t_data->control[i].work) { /* Notify work thread */ - k_work_submit_to_queue(t_data->work_q ? - t_data->work_q : &k_sys_work_q, - t_data->control[i].work); + k_work_submit_to_queue(work_q ? work_q : &k_sys_work_q, + t_data->control[i].work); } } } @@ -246,11 +293,12 @@ static void adc_npcx_isr(const struct device *dev) static int adc_npcx_validate_buffer_size(const struct device *dev, const struct adc_sequence *sequence) { + const struct adc_npcx_config *config = dev->config; uint8_t channels = 0; uint32_t mask; size_t needed; - for (mask = BIT(NPCX_ADC_CH_COUNT - 1); mask != 0; mask >>= 1) { + for (mask = BIT(config->channel_count - 1); mask != 0; mask >>= 1) { if (mask & sequence->channels) { channels++; } @@ -270,6 +318,7 @@ static int adc_npcx_validate_buffer_size(const struct device *dev, static void adc_npcx_start_scan(const struct device *dev) { + const struct adc_npcx_config *config = dev->config; struct adc_npcx_data *const data = dev->data; struct adc_reg *const inst = HAL_INSTANCE(dev); @@ -286,7 +335,7 @@ static void adc_npcx_start_scan(const struct device *dev) inst->ADCSTS |= BIT(NPCX_ADCSTS_EOCCEV); /* Update selected channels in scan mode by channels mask */ - inst->ADCCS |= data->channels; + adc_npcx_config_channels(dev, data->channels); /* Select 'Scan' Conversion mode. */ SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, @@ -298,18 +347,24 @@ static void adc_npcx_start_scan(const struct device *dev) /* Start conversion */ inst->ADCCNF |= BIT(NPCX_ADCCNF_START); - LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS are (%04X,%04X)\n", + if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) { + LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS, ADCCS2 are " + "(%04X,%04X,%04X)\n", inst->ADCCNF, inst->ADCCS, inst->ADCCS2); + } else { + LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS are (%04X,%04X)\n", inst->ADCCNF, inst->ADCCS); + } } static int adc_npcx_start_read(const struct device *dev, const struct adc_sequence *sequence) { + const struct adc_npcx_config *config = dev->config; struct adc_npcx_data *const data = dev->data; int error = 0; if (!sequence->channels || - (sequence->channels & ~BIT_MASK(NPCX_ADC_CH_COUNT))) { + (sequence->channels & ~BIT_MASK(config->channel_count))) { LOG_ERR("Invalid ADC channels"); return -EINVAL; } @@ -364,9 +419,10 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, static int adc_npcx_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg) { + const struct adc_npcx_config *config = dev->config; uint8_t channel_id = channel_cfg->channel_id; - if (channel_id >= NPCX_ADC_CH_COUNT) { + if (channel_id >= config->channel_count) { LOG_ERR("Invalid channel %d", channel_id); return -EINVAL; } @@ -443,18 +499,21 @@ static void adc_npcx_set_repetitive(const struct device *dev, int chnsel, /* Set ADC conversion code to SW conversion mode */ SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, NPCX_ADC_SCAN_CONVERSION_MODE); - /* Update number of channel to be converted */ - inst->ADCCS |= BIT(chnsel); + + /* Add selected ADC channel to be converted */ + t_data->repetitive_channels |= BIT(chnsel); + adc_npcx_config_channels(dev, t_data->repetitive_channels); + /* Set conversion type to repetitive (runs continuously) */ inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCRPTC); - t_data->repetitive_channels |= BIT(chnsel); /* Start conversion */ inst->ADCCNF |= BIT(NPCX_ADCCNF_START); } else { - inst->ADCCS &= ~BIT(chnsel); - + /* Remove selected ADC channel to be converted */ t_data->repetitive_channels &= ~BIT(chnsel); + adc_npcx_config_channels(dev, t_data->repetitive_channels); + if (!t_data->repetitive_channels) { /* No thesholdd active left, disable repetitive mode */ inst->ADCCNF &= ~BIT(NPCX_ADCCNF_ADCRPTC); @@ -493,7 +552,7 @@ int adc_npcx_threshold_ctrl_set_param(const struct device *dev, adc_context_lock(&data->ctx, false, NULL); switch (param->type) { case ADC_NPCX_THRESHOLD_PARAM_CHNSEL: - if (param->val >= NPCX_ADC_CH_COUNT) { + if (param->val >= config->channel_count) { ret = -EINVAL; break; } @@ -530,6 +589,7 @@ static int adc_npcx_threshold_ctrl_setup(const struct device *dev, const uint8_t th_sel) { struct adc_npcx_data *const data = dev->data; + struct adc_driver_api *api = (struct adc_driver_api *)dev->api; struct adc_npcx_threshold_data *const t_data = data->threshold_data; const struct adc_npcx_config *config = dev->config; struct adc_npcx_threshold_control *const t_ctrl = @@ -548,8 +608,8 @@ static int adc_npcx_threshold_ctrl_setup(const struct device *dev, return -EBUSY; } - if (t_ctrl->chnsel >= NPCX_ADC_CH_COUNT || - t_ctrl->thrval >= NPCX_ADC_VREF_VOL || + if (t_ctrl->chnsel >= config->channel_count || + t_ctrl->thrval >= api->ref_internal || t_ctrl->thrval == 0 || t_ctrl->work == 0) { adc_context_release(&data->ctx, 0); LOG_ERR("Threshold selected (%d) is not configured!", th_sel); @@ -576,6 +636,7 @@ static int adc_npcx_threshold_enable_irq(const struct device *dev, const uint8_t th_sel) { struct adc_reg *const inst = HAL_INSTANCE(dev); + struct adc_driver_api *api = (struct adc_driver_api *)dev->api; struct adc_npcx_data *const data = dev->data; const struct adc_npcx_config *config = dev->config; struct adc_npcx_threshold_data *const t_data = data->threshold_data; @@ -589,8 +650,8 @@ static int adc_npcx_threshold_enable_irq(const struct device *dev, } adc_context_lock(&data->ctx, false, NULL); - if (t_ctrl->chnsel >= NPCX_ADC_CH_COUNT || - t_ctrl->thrval >= NPCX_ADC_VREF_VOL || + if (t_ctrl->chnsel >= config->channel_count || + t_ctrl->thrval >= api->ref_internal || t_ctrl->thrval == 0 || t_ctrl->work == 0) { adc_context_release(&data->ctx, 0); LOG_ERR("Threshold selected (%d) is not configured!", th_sel); @@ -604,7 +665,7 @@ static int adc_npcx_threshold_enable_irq(const struct device *dev, thrcts = inst->THRCTS & ~GENMASK(config->threshold_count - 1, 0); /* Enable threshold detection */ - THRCTL(dev, (th_sel + 1)) |= BIT(NPCX_THRCTL_THEN); + adc_npcx_enable_threshold_detect(dev, th_sel, true); /* clear threshold status */ thrcts |= BIT(th_sel); @@ -652,7 +713,7 @@ int adc_npcx_threshold_disable_irq(const struct device *dev, inst->THRCTS = thrcts; /* Disable threshold detection */ - THRCTL(dev, (th_sel + 1)) &= ~BIT(NPCX_THRCTL_THEN); + adc_npcx_enable_threshold_detect(dev, th_sel, false); /* Update active threshold */ t_data->active_thresholds &= ~BIT(th_sel); @@ -687,53 +748,24 @@ int adc_npcx_threshold_ctrl_enable(const struct device *dev, uint8_t th_sel, return ret; } -int adc_npcx_threshold_mv_to_thrval(uint32_t val_mv, uint32_t *thrval) +int adc_npcx_threshold_mv_to_thrval(const struct device *dev, uint32_t val_mv, + uint32_t *thrval) { + struct adc_driver_api *api = (struct adc_driver_api *)dev->api; + if (!IS_ENABLED(CONFIG_ADC_CMP_NPCX)) { return -EOPNOTSUPP; } - if (val_mv >= NPCX_ADC_VREF_VOL) { + if (val_mv >= api->ref_internal) { return -EINVAL; } *thrval = (val_mv << ADC_NPCX_THRVAL_RESOLUTION) / - NPCX_ADC_VREF_VOL; + api->ref_internal; return 0; } -/* ADC driver registration */ -static const struct adc_driver_api adc_npcx_driver_api = { - .channel_setup = adc_npcx_channel_setup, - .read = adc_npcx_read, -#if defined(CONFIG_ADC_ASYNC) - .read_async = adc_npcx_read_async, -#endif - .ref_internal = NPCX_ADC_VREF_VOL, -}; - -static int adc_npcx_init(const struct device *dev); - -PINCTRL_DT_INST_DEFINE(0); -BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, - "only one 'nuvoton_npcx_adc' compatible node may be present"); - -static const struct adc_npcx_config adc_npcx_cfg_0 = { - .base = DT_INST_REG_ADDR(0), - .clk_cfg = NPCX_DT_CLK_CFG_ITEM(0), - .threshold_count = DT_INST_PROP(0, threshold_count), - .threshold_reg_offset = DT_INST_PROP(0, threshold_reg_offset), - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), -}; - -static struct adc_npcx_threshold_data threshold_data_0; - -static struct adc_npcx_data adc_npcx_data_0 = { - ADC_CONTEXT_INIT_TIMER(adc_npcx_data_0, ctx), - ADC_CONTEXT_INIT_LOCK(adc_npcx_data_0, ctx), - ADC_CONTEXT_INIT_SYNC(adc_npcx_data_0, ctx), -}; - #if defined(CONFIG_ADC_CMP_NPCX_WORKQUEUE) struct k_work_q adc_npcx_work_q; @@ -752,20 +784,13 @@ static int adc_npcx_init_cmp_work_q(void) K_KERNEL_STACK_SIZEOF(adc_npcx_work_q_stack), CONFIG_ADC_CMP_NPCX_WORKQUEUE_PRIORITY, &cfg); - threshold_data_0.work_q = &adc_npcx_work_q; + work_q = &adc_npcx_work_q; return 0; } SYS_INIT(adc_npcx_init_cmp_work_q, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY); #endif -DEVICE_DT_INST_DEFINE(0, - adc_npcx_init, NULL, - &adc_npcx_data_0, &adc_npcx_cfg_0, - PRE_KERNEL_1, - CONFIG_ADC_INIT_PRIORITY, - &adc_npcx_driver_api); - static int adc_npcx_init(const struct device *dev) { const struct adc_npcx_config *const config = dev->config; @@ -814,14 +839,8 @@ static int adc_npcx_init(const struct device *dev) inst->GENDLY = ADC_REGULAR_GENDLY_VAL; inst->MEAST = ADC_REGULAR_MEAST_VAL; - if (IS_ENABLED(CONFIG_ADC_CMP_NPCX)) { - data->threshold_data = &threshold_data_0; - } - /* Configure ADC interrupt and enable it */ - IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), adc_npcx_isr, - DEVICE_DT_INST_GET(0), 0); - irq_enable(DT_INST_IRQN(0)); + config->irq_cfg_func(); /* Initialize mutex of ADC channels */ adc_context_unlock_unconditionally(&data->ctx); @@ -835,3 +854,46 @@ static int adc_npcx_init(const struct device *dev) return 0; } + +#define NPCX_ADC_INIT(n) \ + \ + static void adc_npcx_irq_cfg_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + adc_npcx_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + static const struct adc_driver_api adc_npcx_driver_api_##n = { \ + .channel_setup = adc_npcx_channel_setup, \ + .read = adc_npcx_read, \ + .ref_internal = DT_INST_PROP(n, vref_mv), \ + IF_ENABLED(CONFIG_ADC_ASYNC, \ + (.read_async = adc_npcx_read_async,)) \ + }; \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct adc_npcx_config adc_npcx_cfg_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \ + .channel_count = DT_INST_PROP(n, channel_count), \ + .threshold_count = DT_INST_PROP(n, threshold_count), \ + .threshold_reg_offset = DT_INST_PROP(n, threshold_reg_offset), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .irq_cfg_func = adc_npcx_irq_cfg_func_##n, \ + }; \ + static struct adc_npcx_threshold_data threshold_data_##n; \ + static struct adc_npcx_data adc_npcx_data_##n = { \ + ADC_CONTEXT_INIT_TIMER(adc_npcx_data_##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(adc_npcx_data_##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_npcx_data_##n, ctx), \ + .threshold_data = &threshold_data_##n, \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + adc_npcx_init, NULL, \ + &adc_npcx_data_##n, &adc_npcx_cfg_##n, \ + PRE_KERNEL_1, CONFIG_ADC_INIT_PRIORITY, \ + &adc_npcx_driver_api_##n); + +DT_INST_FOREACH_STATUS_OKAY(NPCX_ADC_INIT) diff --git a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c index 1aa694f6b46..5294c8fd3b9 100644 --- a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c +++ b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c @@ -92,7 +92,7 @@ static int adc_cmp_npcx_init(const struct device *dev) if (config->thr_mv != ADC_CMP_NPCX_UNDEFINED) { param.type = ADC_NPCX_THRESHOLD_PARAM_THVAL; /* Convert from millivolts to ADC raw register value */ - ret = adc_npcx_threshold_mv_to_thrval(config->thr_mv, + ret = adc_npcx_threshold_mv_to_thrval(config->adc, config->thr_mv, ¶m.val); if (ret) { goto init_error; @@ -135,7 +135,7 @@ static int adc_cmp_npcx_set_threshold(const struct device *dev, bool is_upper, param.type = ADC_NPCX_THRESHOLD_PARAM_THVAL; if (is_mv) { - ret = adc_npcx_threshold_mv_to_thrval(value, ¶m.val); + ret = adc_npcx_threshold_mv_to_thrval(config->adc, value, ¶m.val); if (ret) { return ret; } diff --git a/dts/arm/nuvoton/npcx/npcx.dtsi b/dts/arm/nuvoton/npcx/npcx.dtsi index 46abbb44e87..c1a77c4fe69 100644 --- a/dts/arm/nuvoton/npcx/npcx.dtsi +++ b/dts/arm/nuvoton/npcx/npcx.dtsi @@ -350,6 +350,7 @@ reg = <0x400d1000 0x2000>; interrupts = <10 3>; clocks = <&pcc NPCX_CLOCK_BUS_APB1 NPCX_PWDWN_CTL4 4>; + vref-mv = <2816>; status = "disabled"; }; diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index d8c0307c4fd..d1b5c7439e1 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -263,6 +263,20 @@ threshold-count = <6>; }; + /* ADC1 which reference voltage is AVCC */ + adc1: adc@400d5000 { + compatible = "nuvoton,npcx-adc"; + #io-channel-cells = <1>; + reg = <0x400d5000 0x2000>; + interrupts = <22 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB1 NPCX_PWDWN_CTL4 3>; + vref-mv = <3300>; + channel-count = <26>; + threshold-reg-offset = <0x80>; + threshold-count = <6>; + status = "disabled"; + }; + /* FIU0 configuration in npcx4 series */ qspi_fiu0: quadspi@40020000 { clocks = <&pcc NPCX_CLOCK_BUS_FIU0 NPCX_PWDWN_CTL8 5>; diff --git a/dts/bindings/adc/nuvoton,npcx-adc.yaml b/dts/bindings/adc/nuvoton,npcx-adc.yaml index 78701bdc81a..11c4d1c21dc 100644 --- a/dts/bindings/adc/nuvoton,npcx-adc.yaml +++ b/dts/bindings/adc/nuvoton,npcx-adc.yaml @@ -16,6 +16,10 @@ properties: required: true pinctrl-names: required: true + vref-mv: + type: int + required: true + description: ADC reference voltage (Unit:mV) channel-count: type: int required: true diff --git a/include/zephyr/drivers/adc/adc_npcx_threshold.h b/include/zephyr/drivers/adc/adc_npcx_threshold.h index 0d2b3954a44..4254baa4582 100644 --- a/include/zephyr/drivers/adc/adc_npcx_threshold.h +++ b/include/zephyr/drivers/adc/adc_npcx_threshold.h @@ -41,13 +41,15 @@ struct adc_npcx_threshold_param { * @note This function is available only if @kconfig{CONFIG_ADC_CMP_NPCX} * is selected. * + * @param dev Pointer to the device structure for the driver instance. * @param val_mv Input value in millivolts to be converted. * @param thrval Pointer of variable to hold the result of conversion. * * @returns 0 on success, negative result if input cannot be converted due to * overflow. */ -int adc_npcx_threshold_mv_to_thrval(uint32_t val_mv, uint32_t *thrval); +int adc_npcx_threshold_mv_to_thrval(const struct device *dev, uint32_t val_mv, + uint32_t *thrval); /** * @brief Set ADC threshold parameter. diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index afcb0597f1e..3f50d364950 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -566,7 +566,9 @@ struct adc_reg { volatile uint16_t ASCADD; /* 0x008: ADC Scan Channels Select */ volatile uint16_t ADCCS; - volatile uint8_t reserved1[16]; + /* 0x00A: ADC Scan Channels Select 2 */ + volatile uint16_t ADCCS2; + volatile uint8_t reserved1[14]; /* 0x01A: Threshold Status */ volatile uint16_t THRCTS; volatile uint8_t reserved2[4]; @@ -604,10 +606,16 @@ static inline uint32_t npcx_chndat_offset(uint32_t ch) #define NPCX_ADCCNF_STOP 11 #define NPCX_CHNDAT_CHDAT_FIELD FIELD(0, 10) #define NPCX_CHNDAT_NEW 15 +#ifdef CONFIG_SOC_SERIES_NPCX4 +#define NPCX_THRCTL_L_H 15 +#define NPCX_THRCTL_CHNSEL FIELD(10, 5) +#define NPCX_THRCTL_THRVAL FIELD(0, 10) +#else #define NPCX_THRCTL_THEN 15 #define NPCX_THRCTL_L_H 14 #define NPCX_THRCTL_CHNSEL FIELD(10, 4) #define NPCX_THRCTL_THRVAL FIELD(0, 10) +#endif #define NPCX_THRCTS_ADC_WKEN 15 #define NPCX_THRCTS_THR3_IEN 10 #define NPCX_THRCTS_THR2_IEN 9 From d2892c1123b6afd39eeafac375d87cd3d5166f66 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Mon, 28 Aug 2023 23:53:25 -0700 Subject: [PATCH 0134/4498] driver: sensor: npcx: add 'thr-sel' prop. for adc comparator Add `thr-sel` prop. to select the relevant threshold register for adc comparator since there're two adc modules in npcx4 series. Signed-off-by: Kate Yen Signed-off-by: Mulin Chao --- drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c | 2 +- dts/bindings/sensor/nuvoton,adc-cmp.yaml | 13 ++++++++++++- include/zephyr/drivers/sensor/adc_cmp_npcx.h | 13 +++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c index 5294c8fd3b9..ff1871e8a40 100644 --- a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c +++ b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c @@ -256,7 +256,7 @@ static const struct sensor_driver_api adc_cmp_npcx_api = { static const struct adc_cmp_npcx_config adc_cmp_npcx_config_##inst = {\ .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \ .chnsel = DT_INST_IO_CHANNELS_INPUT(inst), \ - .th_sel = inst, \ + .th_sel = DT_INST_STRING_TOKEN_OR(inst, thr_sel, inst), \ .thr_mv = DT_INST_PROP_OR(inst, threshold_mv, \ ADC_CMP_NPCX_UNDEFINED), \ .comparison = DT_INST_STRING_TOKEN_OR(inst, \ diff --git a/dts/bindings/sensor/nuvoton,adc-cmp.yaml b/dts/bindings/sensor/nuvoton,adc-cmp.yaml index 769304b25b2..40d0e1b6e0c 100644 --- a/dts/bindings/sensor/nuvoton,adc-cmp.yaml +++ b/dts/bindings/sensor/nuvoton,adc-cmp.yaml @@ -1,6 +1,5 @@ # Copyright (c) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - description: | This will perform signal comparision with threshold established. @@ -28,3 +27,15 @@ properties: enum: - ADC_CMP_NPCX_GREATER - ADC_CMP_NPCX_LESS_OR_EQUAL + + thr-sel: + type: string + description: | + Determines the register for threshold control and event. + enum: + - ADC_CMP_NPCX_THRCTL1 + - ADC_CMP_NPCX_THRCTL2 + - ADC_CMP_NPCX_THRCTL3 + - ADC_CMP_NPCX_THRCTL4 + - ADC_CMP_NPCX_THRCTL5 + - ADC_CMP_NPCX_THRCTL6 diff --git a/include/zephyr/drivers/sensor/adc_cmp_npcx.h b/include/zephyr/drivers/sensor/adc_cmp_npcx.h index fc66fd80a11..5e986dd1be7 100644 --- a/include/zephyr/drivers/sensor/adc_cmp_npcx.h +++ b/include/zephyr/drivers/sensor/adc_cmp_npcx.h @@ -12,6 +12,19 @@ enum adc_cmp_npcx_comparison { ADC_CMP_NPCX_LESS_OR_EQUAL, }; +/* Supported ADC threshold controllers in NPCX series */ +enum npcx_adc_cmp_thrctl { + ADC_CMP_NPCX_THRCTL1, + ADC_CMP_NPCX_THRCTL2, + ADC_CMP_NPCX_THRCTL3, +#if !defined(CONFIG_SOC_SERIES_NPCX7) + ADC_CMP_NPCX_THRCTL4, + ADC_CMP_NPCX_THRCTL5, + ADC_CMP_NPCX_THRCTL6, +#endif + ADC_CMP_NPCX_THRCTL_COUNT, +}; + enum adc_cmp_npcx_sensor_attribute { SENSOR_ATTR_LOWER_VOLTAGE_THRESH = SENSOR_ATTR_PRIV_START, SENSOR_ATTR_UPPER_VOLTAGE_THRESH, From eacdadf270929ff6bafbff227b1b681a17b55a4a Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Thu, 24 Aug 2023 00:50:55 -0700 Subject: [PATCH 0135/4498] driver: adc: npcx: remove `threshold-reg-offset` DT property Remove `threshold-reg-offset` DT property and implement them with static inline functions in `reg_def.h` Signed-off-by: Mulin Chao --- drivers/adc/adc_npcx.c | 44 ++++++----------------- dts/arm/nuvoton/npcx/npcx4.dtsi | 2 -- dts/arm/nuvoton/npcx/npcx7.dtsi | 1 - dts/arm/nuvoton/npcx/npcx9.dtsi | 1 - dts/bindings/adc/nuvoton,npcx-adc.yaml | 4 --- soc/arm/nuvoton_npcx/common/reg/reg_def.h | 22 ++++++++++++ 6 files changed, 32 insertions(+), 42 deletions(-) diff --git a/drivers/adc/adc_npcx.c b/drivers/adc/adc_npcx.c index 119a61f72aa..6a5a1ad802a 100644 --- a/drivers/adc/adc_npcx.c +++ b/drivers/adc/adc_npcx.c @@ -41,12 +41,6 @@ LOG_MODULE_REGISTER(adc_npcx, CONFIG_ADC_LOG_LEVEL); #define ADC_NPCX_THRVAL_RESOLUTION 10 #define ADC_NPCX_THRVAL_MAX BIT_MASK(ADC_NPCX_THRVAL_RESOLUTION) -/* ADC threshold detection registers */ -#define THRCTL(dev, ctl_no) (*((volatile uint16_t *) npcx_thrctl_reg(dev, ctl_no))) -#ifdef CONFIG_SOC_SERIES_NPCX4 -#define THEN(dev) (*((volatile uint16_t *) npcx_then_reg(dev))) -#endif - /* Device config */ struct adc_npcx_config { /* adc controller base address */ @@ -57,8 +51,6 @@ struct adc_npcx_config { const uint8_t channel_count; /* amount of thresholds supported */ const uint8_t threshold_count; - /* threshold control register offset */ - const uint16_t threshold_reg_offset; /* routine for configuring ADC's ISR */ void (*irq_cfg_func)(void); const struct pinctrl_dev_config *pcfg; @@ -170,38 +162,23 @@ static inline void adc_npcx_config_channels(const struct device *dev, uint32_t c } } -static inline uint32_t npcx_thrctl_reg(const struct device *dev, - uint32_t ctl_no) -{ - const struct adc_npcx_config *config = dev->config; - - return (config->base + config->threshold_reg_offset) + (ctl_no - 1) * 2; -} - -#ifdef CONFIG_SOC_SERIES_NPCX4 -static inline uint32_t npcx_then_reg(const struct device *dev) -{ - const struct adc_npcx_config *config = dev->config; - - return (config->base + config->threshold_reg_offset + 0x10); -} -#endif - static inline void adc_npcx_enable_threshold_detect(const struct device *dev, uint8_t th_sel, bool enable) { + const struct adc_npcx_config *config = dev->config; + if (enable) { #ifdef CONFIG_SOC_SERIES_NPCX4 - THEN(dev) |= BIT(th_sel); + THEN(config->base) |= BIT(th_sel); #else - THRCTL(dev, (th_sel + 1)) |= BIT(NPCX_THRCTL_THEN); + THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_THEN); #endif } else { #ifdef CONFIG_SOC_SERIES_NPCX4 - THEN(dev) &= ~BIT(th_sel); + THEN(config->base) &= ~BIT(th_sel); #else - THRCTL(dev, (th_sel + 1)) &= ~BIT(NPCX_THRCTL_THEN); + THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_THEN); #endif } } @@ -616,16 +593,16 @@ static int adc_npcx_threshold_ctrl_setup(const struct device *dev, return -EINVAL; } - SET_FIELD(THRCTL(dev, (th_sel + 1)), + SET_FIELD(THRCTL(config->base, th_sel), NPCX_THRCTL_CHNSEL, t_ctrl->chnsel); if (t_ctrl->l_h) { - THRCTL(dev, (th_sel + 1)) |= BIT(NPCX_THRCTL_L_H); + THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_L_H); } else { - THRCTL(dev, (th_sel + 1)) &= ~BIT(NPCX_THRCTL_L_H); + THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_L_H); } /* Set the threshold value. */ - SET_FIELD(THRCTL(dev, (th_sel + 1)), NPCX_THRCTL_THRVAL, + SET_FIELD(THRCTL(config->base, th_sel), NPCX_THRCTL_THRVAL, t_ctrl->thrval); adc_context_release(&data->ctx, 0); @@ -879,7 +856,6 @@ static int adc_npcx_init(const struct device *dev) .clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \ .channel_count = DT_INST_PROP(n, channel_count), \ .threshold_count = DT_INST_PROP(n, threshold_count), \ - .threshold_reg_offset = DT_INST_PROP(n, threshold_reg_offset), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .irq_cfg_func = adc_npcx_irq_cfg_func_##n, \ }; \ diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index d1b5c7439e1..56adb416d01 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -259,7 +259,6 @@ /* ADC0 comparator configuration in npcx4 series */ adc0: adc@400d1000 { channel-count = <26>; - threshold-reg-offset = <0x80>; threshold-count = <6>; }; @@ -272,7 +271,6 @@ clocks = <&pcc NPCX_CLOCK_BUS_APB1 NPCX_PWDWN_CTL4 3>; vref-mv = <3300>; channel-count = <26>; - threshold-reg-offset = <0x80>; threshold-count = <6>; status = "disabled"; }; diff --git a/dts/arm/nuvoton/npcx/npcx7.dtsi b/dts/arm/nuvoton/npcx/npcx7.dtsi index cad37d8ca66..529d5bdef35 100644 --- a/dts/arm/nuvoton/npcx/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7.dtsi @@ -237,7 +237,6 @@ /* ADC0 comparator configuration in npcx7 series */ adc0: adc@400d1000 { channel-count = <10>; - threshold-reg-offset = <0x14>; threshold-count = <3>; }; diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi index 6561ba7b6dd..18a1278de57 100644 --- a/dts/arm/nuvoton/npcx/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9.dtsi @@ -258,7 +258,6 @@ /* ADC0 comparator configuration in npcx9 series */ adc0: adc@400d1000 { channel-count = <12>; - threshold-reg-offset = <0x60>; threshold-count = <6>; }; diff --git a/dts/bindings/adc/nuvoton,npcx-adc.yaml b/dts/bindings/adc/nuvoton,npcx-adc.yaml index 11c4d1c21dc..50d37d19d80 100644 --- a/dts/bindings/adc/nuvoton,npcx-adc.yaml +++ b/dts/bindings/adc/nuvoton,npcx-adc.yaml @@ -24,10 +24,6 @@ properties: type: int required: true description: the number of ADC channels - threshold-reg-offset: - type: int - required: true - description: the offset of threshold detector register address threshold-count: type: int required: true diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 3f50d364950..794bb5545bb 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -581,12 +581,34 @@ struct adc_reg { volatile uint16_t MEAST; }; +/* ADC internal inline functions for multi-registers */ static inline uint32_t npcx_chndat_offset(uint32_t ch) { return 0x40 + ch * 2; } +static inline uint32_t npcx_thr_base(void) +{ + if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { + return 0x014; + } else if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX9)) { + return 0x060; + } else { /* NPCX4 and later series */ + return 0x080; + } +} + +static inline uint32_t npcx_thrctl_offset(uint32_t ctrl) +{ + return npcx_thr_base() + ctrl * 2; +} + #define CHNDAT(base, ch) (*(volatile uint16_t *)((base) + npcx_chndat_offset(ch))) +#define THRCTL(base, ctrl) \ + (*(volatile uint16_t *)(base + npcx_thrctl_offset(ctrl))) +#ifdef CONFIG_SOC_SERIES_NPCX4 +#define THEN(base) (*(volatile uint16_t *)(base + 0x90)) +#endif /* ADC register fields */ #define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) From 3d713a42e8266c3f00e42289e965f8013b3cce47 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 29 Aug 2023 18:54:21 +0100 Subject: [PATCH 0136/4498] display: ssd1306: add some init delay Seems like the SSD1306 controller needs a bit of time after power up before it can take i2c commands. This causes problems with microcontrollers that have no other delays in the startup sequence, like rpi_pico. There's currently no good way of modeling this in Zephyr right now, and there's also no clear indication of how much time the device needs in the datasheet that I could find, but it seems like 10ms is enough for that to start reliably so add a delay in the ssd1306 init function to ensure that at least that time has passed from system power up. Signed-off-by: Fabio Baltieri --- drivers/display/ssd1306.c | 6 +++++- dts/bindings/display/solomon,ssd1306fb-common.yaml | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 34166a2be9a..489f02c597b 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -56,6 +56,7 @@ struct ssd1306_config { struct gpio_dt_spec data_cmd; #endif struct gpio_dt_spec reset; + int ready_time_ms; }; struct ssd1306_data { @@ -403,6 +404,8 @@ static int ssd1306_init(const struct device *dev) LOG_DBG(""); + k_sleep(K_TIMEOUT_ABS_MS(config->ready_time_ms)); + if (!ssd1306_bus_ready(dev)) { LOG_ERR("Bus device %s not ready!", config->bus.bus->name); return -EINVAL; @@ -434,7 +437,8 @@ static const struct ssd1306_config ssd1306_config = { 0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0), .data_cmd = GPIO_DT_SPEC_INST_GET(0, data_cmd_gpios), #endif - .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }) + .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), + .ready_time_ms = DT_INST_PROP(0, ready_time_ms), }; static struct ssd1306_data ssd1306_driver; diff --git a/dts/bindings/display/solomon,ssd1306fb-common.yaml b/dts/bindings/display/solomon,ssd1306fb-common.yaml index a4949953bc6..bba993a58c8 100644 --- a/dts/bindings/display/solomon,ssd1306fb-common.yaml +++ b/dts/bindings/display/solomon,ssd1306fb-common.yaml @@ -48,3 +48,11 @@ properties: The RESET pin of SSD1306 is active low. If connected directly the MCU pin should be configured as active low. + + ready-time-ms: + type: int + default: 10 + description: | + Time it takes for the device from power up to become responsive and + accepting commands. Defaults to 10ms (found by trial and error) if not + provided. From 8db11e6a0a22d6344d87f01536c60c527ca28200 Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 30 Aug 2023 12:34:56 +0200 Subject: [PATCH 0137/4498] drivers: spi: Add Ambiq MSPI driver This commit adds MSPI driver for Apollo4 SoCs. Signed-off-by: Mateusz Sierszulski --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig.ambiq | 9 ++ drivers/spi/mspi_ambiq.c | 253 +++++++++++++++++++++++++++++++ dts/bindings/spi/ambiq,mspi.yaml | 18 +++ modules/hal_ambiq/Kconfig | 5 + west.yml | 2 +- 6 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 drivers/spi/mspi_ambiq.c create mode 100644 dts/bindings/spi/ambiq,mspi.yaml diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index b9b2cd814f9..0eaea3714b8 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_OPENTITAN spi_opentitan.c) zephyr_library_sources_ifdef(CONFIG_SPI_NUMAKER spi_numaker.c) zephyr_library_sources_ifdef(CONFIG_SPI_AMBIQ spi_ambiq.c) zephyr_library_sources_ifdef(CONFIG_SPI_RPI_PICO_PIO spi_rpi_pico_pio.c) +zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ mspi_ambiq.c) zephyr_library_sources_ifdef(CONFIG_SPI_RTIO spi_rtio.c) zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c) diff --git a/drivers/spi/Kconfig.ambiq b/drivers/spi/Kconfig.ambiq index 130b6575136..15eaf7463a4 100644 --- a/drivers/spi/Kconfig.ambiq +++ b/drivers/spi/Kconfig.ambiq @@ -13,3 +13,12 @@ config SPI_AMBIQ select AMBIQ_HAL_USE_SPI help Enable driver for Ambiq SPI. + +config MSPI_AMBIQ + bool "AMBIQ MSPI driver" + default y + depends on DT_HAS_AMBIQ_MSPI_ENABLED + select AMBIQ_HAL + select AMBIQ_HAL_USE_MSPI + help + Enable driver for Ambiq MSPI. diff --git a/drivers/spi/mspi_ambiq.c b/drivers/spi/mspi_ambiq.c new file mode 100644 index 00000000000..03ad8b2c0ac --- /dev/null +++ b/drivers/spi/mspi_ambiq.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ambiq_mspi + +#include +LOG_MODULE_REGISTER(mspi_ambiq); + +#include +#include +#include + +#include "spi_context.h" +#include + +#define SPI_WORD_SIZE 8 +#define MSPI_MAX_FREQ 96000000 +#define MSPI_TIMEOUT_US 1000000 +#define PWRCTRL_MAX_WAIT_US 5 +#define MSPI_BUSY BIT(2) + +typedef int (*ambiq_mspi_pwr_func_t)(void); + +struct mspi_ambiq_config { + uint32_t base; + int size; + uint32_t clock_freq; + const struct pinctrl_dev_config *pcfg; + ambiq_mspi_pwr_func_t pwr_func; +}; + +struct mspi_ambiq_data { + struct spi_context ctx; + void *mspiHandle; + am_hal_mspi_dev_config_t mspicfg; +}; + +static int mspi_set_freq(uint32_t freq) +{ + uint32_t d = MSPI_MAX_FREQ / freq; + + switch (d) { + case AM_HAL_MSPI_CLK_96MHZ: + case AM_HAL_MSPI_CLK_48MHZ: + case AM_HAL_MSPI_CLK_32MHZ: + case AM_HAL_MSPI_CLK_24MHZ: + case AM_HAL_MSPI_CLK_16MHZ: + case AM_HAL_MSPI_CLK_12MHZ: + case AM_HAL_MSPI_CLK_8MHZ: + case AM_HAL_MSPI_CLK_6MHZ: + case AM_HAL_MSPI_CLK_4MHZ: + case AM_HAL_MSPI_CLK_3MHZ: + break; + default: + LOG_ERR("Frequency not supported!"); + d = AM_HAL_MSPI_CLK_INVALID; + break; + } + + return d; +} + +static int mspi_config(const struct device *dev, const struct spi_config *config) +{ + struct mspi_ambiq_data *data = dev->data; + int ret; + am_hal_mspi_dev_config_t mspicfg = {0}; + + if (config->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(config->operation) != 8) { + LOG_ERR("Word size must be %d", SPI_WORD_SIZE); + return -ENOTSUP; + } + + if ((config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Only single mode is currently supported"); + return -ENOTSUP; + } + + if (config->operation & SPI_LOCK_ON) { + LOG_ERR("Lock On not supported"); + return -ENOTSUP; + } + + if (config->operation & SPI_TRANSFER_LSB) { + LOG_ERR("LSB first not supported"); + return -ENOTSUP; + } + + if (config->operation & (SPI_MODE_CPOL | SPI_MODE_CPHA)) { + if (config->operation & (SPI_MODE_CPOL && SPI_MODE_CPHA)) { + mspicfg.eSpiMode = AM_HAL_MSPI_SPI_MODE_3; + } else if (config->operation & SPI_MODE_CPOL) { + mspicfg.eSpiMode = AM_HAL_MSPI_SPI_MODE_2; + } else if (config->operation & SPI_MODE_CPHA) { + mspicfg.eSpiMode = AM_HAL_MSPI_SPI_MODE_1; + } else { + mspicfg.eSpiMode = AM_HAL_MSPI_SPI_MODE_0; + } + } + + mspicfg.eClockFreq = mspi_set_freq(config->frequency); + if (mspicfg.eClockFreq == AM_HAL_MSPI_CLK_INVALID) { + return -ENOTSUP; + } + + mspicfg.eDeviceConfig = AM_HAL_MSPI_FLASH_SERIAL_CE0; + + ret = am_hal_mspi_disable(data->mspiHandle); + if (ret) { + return ret; + } + + ret = am_hal_mspi_device_configure(data->mspiHandle, &mspicfg); + if (ret) { + return ret; + } + + ret = am_hal_mspi_enable(data->mspiHandle); + + + return ret; +} + +static int mspi_ambiq_xfer(const struct device *dev, const struct spi_config *config) +{ + struct mspi_ambiq_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + int ret; + + am_hal_mspi_pio_transfer_t trans = {0}; + + trans.bSendAddr = true; + trans.bSendInstr = true; + trans.ui16DeviceInstr = *ctx->tx_buf; + spi_context_update_tx(ctx, 1, 1); + trans.ui32DeviceAddr = *ctx->tx_buf; + + if (ctx->rx_buf != NULL) { + spi_context_update_rx(ctx, 1, ctx->rx_len); + trans.eDirection = AM_HAL_MSPI_RX; + trans.pui32Buffer = (uint32_t *)ctx->rx_buf; + trans.ui32NumBytes = ctx->rx_len; + + } else if (ctx->tx_buf != NULL) { + spi_context_update_tx(ctx, 1, 1); + trans.eDirection = AM_HAL_MSPI_TX; + trans.pui32Buffer = (uint32_t *)ctx->tx_buf; + trans.ui32NumBytes = ctx->tx_len; + } + + ret = am_hal_mspi_blocking_transfer(data->mspiHandle, &trans, MSPI_TIMEOUT_US); + + spi_context_complete(ctx, dev, 0); + + return ret; +} + +static int mspi_ambiq_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + struct mspi_ambiq_data *data = dev->data; + + int ret = mspi_config(dev, config); + + if (ret) { + return ret; + } + + if (!tx_bufs && !rx_bufs) { + return 0; + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + ret = mspi_ambiq_xfer(dev, config); + + return ret; +} + +static int mspi_ambiq_release(const struct device *dev, const struct spi_config *config) +{ + const struct mspi_ambiq_config *cfg = dev->config; + + if (sys_read32(cfg->base) & MSPI_BUSY) { + return -EBUSY; + } + + return 0; +} + +static struct spi_driver_api mspi_ambiq_driver_api = { + .transceive = mspi_ambiq_transceive, + .release = mspi_ambiq_release, +}; + +static int mspi_ambiq_init(const struct device *dev) +{ + struct mspi_ambiq_data *data = dev->data; + const struct mspi_ambiq_config *cfg = dev->config; + am_hal_mspi_config_t mspiCfg = {0}; + + mspiCfg.pTCB = NULL; + + int ret = am_hal_mspi_initialize((cfg->base - REG_MSPI_BASEADDR) / (cfg->size * 4), + &data->mspiHandle); + if (ret) { + return ret; + } + + ret = cfg->pwr_func(); + + ret = am_hal_mspi_configure(data->mspiHandle, &mspiCfg); + if (ret) { + return ret; + } + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + + return ret; +} + +#define AMBIQ_MSPI_DEFINE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static int pwr_on_ambiq_mspi_##n(void) \ + { \ + uint32_t addr = DT_REG_ADDR(DT_INST_PHANDLE(n, ambiq_pwrcfg)) + \ + DT_INST_PHA(n, ambiq_pwrcfg, offset); \ + sys_write32((sys_read32(addr) | DT_INST_PHA(n, ambiq_pwrcfg, mask)), addr); \ + k_busy_wait(PWRCTRL_MAX_WAIT_US); \ + return 0; \ + } \ + static struct mspi_ambiq_data mspi_ambiq_data##n = { \ + SPI_CONTEXT_INIT_SYNC(mspi_ambiq_data##n, ctx)}; \ + static const struct mspi_ambiq_config mspi_ambiq_config##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .size = DT_INST_REG_SIZE(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .pwr_func = pwr_on_ambiq_mspi_##n, \ + }; \ + DEVICE_DT_INST_DEFINE(n, mspi_ambiq_init, NULL, &mspi_ambiq_data##n, \ + &mspi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &mspi_ambiq_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(AMBIQ_MSPI_DEFINE) diff --git a/dts/bindings/spi/ambiq,mspi.yaml b/dts/bindings/spi/ambiq,mspi.yaml new file mode 100644 index 00000000000..0c48f6605e6 --- /dev/null +++ b/dts/bindings/spi/ambiq,mspi.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq MSPI + +compatible: "ambiq,mspi" + +include: [spi-controller.yaml, pinctrl-device.yaml, ambiq-pwrcfg.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + ambiq,pwrcfg: + required: true diff --git a/modules/hal_ambiq/Kconfig b/modules/hal_ambiq/Kconfig index b6029f0592c..28c19e9a587 100644 --- a/modules/hal_ambiq/Kconfig +++ b/modules/hal_ambiq/Kconfig @@ -40,4 +40,9 @@ config AMBIQ_HAL_USE_SPI help Use the SPI driver from Ambiq HAL +config AMBIQ_HAL_USE_MSPI + bool + help + Use the MSPI driver from Ambiq HAL + endif # AMBIQ_HAL diff --git a/west.yml b/west.yml index 71f54a88d01..da27a1bc4d1 100644 --- a/west.yml +++ b/west.yml @@ -142,7 +142,7 @@ manifest: groups: - hal - name: hal_ambiq - revision: fbb1618df8b0946cc2abea817309dc85fe051c21 + revision: 0e15e4becd49c40cb054672d9525eccfe98b440f path: modules/hal/ambiq groups: - hal From 15d1110d88751ba9468294f1b899cabba0779ecf Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 30 Aug 2023 12:35:07 +0200 Subject: [PATCH 0138/4498] dts: arm: ambiq: Add MSPI instances to SoC This commit instantiates the MSPI peripherals. Signed-off-by: Mateusz Sierszulski --- dts/arm/ambiq/ambiq_apollo4p.dtsi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dts/arm/ambiq/ambiq_apollo4p.dtsi b/dts/arm/ambiq/ambiq_apollo4p.dtsi index f0d2675379f..3f722ae282f 100644 --- a/dts/arm/ambiq/ambiq_apollo4p.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p.dtsi @@ -173,6 +173,36 @@ ambiq,pwrcfg = <&pwrcfg 0x4 0x100>; }; + mspi0: spi@40060000 { + compatible = "ambiq,mspi"; + reg = <0x40060000 0x400>; + interrupts = <20 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x4000>; + }; + + mspi1: spi@40061000 { + compatible = "ambiq,mspi"; + reg = <0x40061000 0x400>; + interrupts = <21 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x8000>; + }; + + mspi2: spi@40062000 { + compatible = "ambiq,mspi"; + reg = <0x40062000 0x400>; + interrupts = <22 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x10000>; + }; + pinctrl: pin-controller@40010000 { compatible = "ambiq,apollo4-pinctrl"; reg = <0x40010000 0x800>; From e68de5baccba6cf4509bd2a40b41589135063e1d Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 30 Aug 2023 12:35:16 +0200 Subject: [PATCH 0139/4498] boards: arm: apollo4p_evb: Enable MSPI This commit enables MSPI instance for apollo4p_evb board. Also adds pin configuration for each instance. Signed-off-by: Mateusz Sierszulski --- .../apollo4p_evb/apollo4p_evb-pinctrl.dtsi | 39 +++++++++++++++++++ boards/arm/apollo4p_evb/apollo4p_evb.dts | 6 +++ 2 files changed, 45 insertions(+) diff --git a/boards/arm/apollo4p_evb/apollo4p_evb-pinctrl.dtsi b/boards/arm/apollo4p_evb/apollo4p_evb-pinctrl.dtsi index 47e74b21c74..abc9f9c9c54 100644 --- a/boards/arm/apollo4p_evb/apollo4p_evb-pinctrl.dtsi +++ b/boards/arm/apollo4p_evb/apollo4p_evb-pinctrl.dtsi @@ -161,4 +161,43 @@ ambiq,iom-nce-module = <28>; }; }; + mspi0_default: mspi0_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <32>; + }; + }; + mspi1_default: mspi1_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <34>; + }; + }; + mspi2_default: mspi2_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <36>; + }; + }; }; diff --git a/boards/arm/apollo4p_evb/apollo4p_evb.dts b/boards/arm/apollo4p_evb/apollo4p_evb.dts index aae84876cb1..059b880388d 100644 --- a/boards/arm/apollo4p_evb/apollo4p_evb.dts +++ b/boards/arm/apollo4p_evb/apollo4p_evb.dts @@ -49,3 +49,9 @@ clock-frequency = <1000000>; status = "okay"; }; + +&mspi0 { + pinctrl-0 = <&mspi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; From 9d849736ef6da918fc8685d6fa79a66d69d866e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 30 Aug 2023 14:16:46 +0200 Subject: [PATCH 0140/4498] Bluetooth: Mesh: Support for comp data page 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for composition data page 2 & 130. In this implementation the responsibillity for filling the page 2 buffer is left to the application through the new comp page 2 cb API. Only the application can know/decide if the device is NLC compliant, and must thus be given the responsibillity for cheking the NLC profile requirements, defined in the NLC specs, and filling the response buffer for comp data page 2. Signed-off-by: Anders Storrø --- include/zephyr/bluetooth/mesh/access.h | 45 ++++++++++++++++++ subsys/bluetooth/mesh/Kconfig | 5 ++ subsys/bluetooth/mesh/access.c | 66 +++++++++++++++++++++++++- subsys/bluetooth/mesh/access.h | 1 - subsys/bluetooth/mesh/cfg_srv.c | 8 +++- 5 files changed, 121 insertions(+), 4 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index f3b6c373128..5b1653c2487 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -1137,6 +1137,51 @@ struct bt_mesh_comp { struct bt_mesh_elem *elem; /**< List of elements. */ }; +/** Composition data page 2 record. */ +struct bt_mesh_comp2_record { + /** Mesh profile ID. */ + uint16_t id; + /** Mesh Profile Version. */ + struct { + /** Major version. */ + uint8_t x; + /** Minor version. */ + uint8_t y; + /** Z version. */ + uint8_t z; + } version; + /** Element offset count. */ + uint8_t elem_offset_cnt; + /** Element offset list. */ + const uint8_t *elem_offset; + /** Length of additional data. */ + uint16_t data_len; + /** Additional data. */ + const void *data; +}; + +/** Node Composition data page 2 */ +struct bt_mesh_comp2 { + /** The number of Mesh Profile records on a device. */ + size_t record_cnt; + /** List of records. */ + const struct bt_mesh_comp2_record *record; +}; + +/** @brief Register composition data page 2 of the device. + * + * Register Mesh Profiles information (Ref section 3.12 in + * Bluetooth SIG Assigned Numbers) for composition data + * page 2 of the device. + * + * @note There must be at least one record present in @c comp2 + * + * @param comp2 Pointer to composition data page 2. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2); + #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 945b45c12cc..99012e9646a 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1373,6 +1373,11 @@ config BT_MESH_COMP_PAGE_1 help Enable support for Composition Data Page 1. +config BT_MESH_COMP_PAGE_2 + bool "Support for Composition Data Page 2" + help + Enable support for Composition Data Page 2. + config BT_MESH_MODEL_EXTENSION_LIST_SIZE int "Model extensions list size" depends on BT_MESH_COMP_PAGE_1 diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index c022eedbadc..b6dab2d67a7 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -53,6 +53,7 @@ struct comp_foreach_model_arg { }; static const struct bt_mesh_comp *dev_comp; +static const struct bt_mesh_comp2 *dev_comp2; static uint16_t dev_primary_addr; static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); @@ -112,6 +113,9 @@ static const struct { #if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) { "bt/mesh/cmp/1", 1, }, #endif +#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) + { "bt/mesh/cmp/2", 2, }, +#endif }; void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, @@ -609,7 +613,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) return temp_size; } -int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) +static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) { const struct bt_mesh_comp *comp; uint8_t cor_id = 0; @@ -660,6 +664,51 @@ int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) return 0; } +static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf) +{ + if (!dev_comp2) { + LOG_ERR("Composition data P2 not registered"); + return -ENODEV; + } + + for (int i = 0; i < dev_comp2->record_cnt; i++) { + if (net_buf_simple_tailroom(buf) < + (8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len + + BT_MESH_MIC_SHORT)) { + if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { + /* Mesh Profile 1.1 Section 4.4.1.2.2: + * If the complete list of models does not fit in the Data field, + * the element shall not be reported. + */ + LOG_DBG("Record 0x%04x didn't fit in the Data field", + i); + return 0; + } + + LOG_ERR("Too large device composition"); + return -E2BIG; + } + + net_buf_simple_add_le16(buf, dev_comp2->record[i].id); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.x); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.y); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.z); + net_buf_simple_add_u8(buf, dev_comp2->record[i].elem_offset_cnt); + if (dev_comp2->record[i].elem_offset_cnt) { + net_buf_simple_add_mem(buf, dev_comp2->record[i].elem_offset, + dev_comp2->record[i].elem_offset_cnt); + } + + net_buf_simple_add_le16(buf, dev_comp2->record[i].data_len); + if (dev_comp2->record[i].data_len) { + net_buf_simple_add_mem(buf, dev_comp2->record[i].data, + dev_comp2->record[i].data_len); + } + } + + return 0; +} + int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) { int32_t period; @@ -994,6 +1043,17 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) return err; } +int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2) +{ + if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + return -EINVAL; + } + + dev_comp2 = comp2; + + return 0; +} + void bt_mesh_comp_provision(uint16_t addr) { int i; @@ -2151,8 +2211,10 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o { if (page == 0 || page == 128) { return bt_mesh_comp_data_get_page_0(buf, offset); - } else if (page == 1 || page == 129) { + } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { return bt_mesh_comp_data_get_page_1(buf); + } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { + return bt_mesh_comp_data_get_page_2(buf); } return -EINVAL; diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index a7d3ffe5865..4740963dd21 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -27,7 +27,6 @@ size_t bt_mesh_comp_page_0_size(void); int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset); size_t bt_mesh_metadata_page_0_size(void); int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); -int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf); /* Find local element based on unicast address */ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 2fba9360206..eb732a34910 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -61,13 +61,19 @@ static int dev_comp_data_get(struct bt_mesh_model *model, page = net_buf_simple_pull_u8(buf); - if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 130U; + } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { page = 129U; } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { page = 128U; + } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + page = 2U; } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { page = 1U; } else if (page != 0U) { From 0e966cceb2d88375520887c1946aa14db8d65cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 30 Aug 2023 14:16:46 +0200 Subject: [PATCH 0141/4498] tests: Bluetooth: Mesh: Add comp p2 test to bsim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds testing of composition data page 2 and 130 in the mesh_prov_pst_pb_remote_ncrp bsim test. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 1 + .../bsim/bluetooth/mesh/src/test_provision.c | 164 +++++++++++------- 2 files changed, 98 insertions(+), 67 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index e870e190481..8a8b78fe8ea 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -62,6 +62,7 @@ CONFIG_BT_MESH_DFU_SLOT_CNT=3 CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_BT_MESH_COMP_PAGE_1=y +CONFIG_BT_MESH_COMP_PAGE_2=y # Needed for RPR tests due to huge amount of retransmitted messages CONFIG_BT_MESH_MSG_CACHE_SIZE=64 diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 171f8cccbbd..3b9e6578351 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -181,6 +181,31 @@ static const struct bt_mesh_comp rpr_srv_comp_unresponsive = { .elem_count = 1, }; +static const uint8_t elem_offset1[2] = {1, 2}; +static const uint8_t elem_offset2[3] = {4, 5, 6}; +static const uint8_t additional_data[2] = {100, 200}; + +static const struct bt_mesh_comp2_record comp_rec[2] = { + {.id = 1, + .version.x = 2, + .version.y = 3, + .version.z = 4, + .elem_offset_cnt = sizeof(elem_offset1), + .elem_offset = elem_offset1, + .data_len = 0}, + {.id = 10, + .version.x = 20, + .version.y = 30, + .version.z = 40, + .elem_offset_cnt = sizeof(elem_offset2), + .elem_offset = elem_offset2, + .data_len = sizeof(additional_data), + .data = additional_data}, +}; + +static const struct bt_mesh_comp2 comp_p2_1 = {.record_cnt = 1, .record = comp_rec}; +static const struct bt_mesh_comp2 comp_p2_2 = {.record_cnt = 2, .record = comp_rec}; + static const struct bt_mesh_comp rpr_srv_comp_2_elem = { .elem = (struct bt_mesh_elem[]){ @@ -881,14 +906,18 @@ static void device_pb_remote_server_setup(const struct bt_mesh_comp *comp, bool ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); } -static void device_pb_remote_server_setup_unproved(const struct bt_mesh_comp *comp) +static void device_pb_remote_server_setup_unproved(const struct bt_mesh_comp *comp, + const struct bt_mesh_comp2 *comp_p2) { device_pb_remote_server_setup(comp, true); + bt_mesh_comp2_register(comp_p2); } -static void device_pb_remote_server_setup_proved(const struct bt_mesh_comp *comp) +static void device_pb_remote_server_setup_proved(const struct bt_mesh_comp *comp, + const struct bt_mesh_comp2 *comp_p2) { device_pb_remote_server_setup(comp, false); + bt_mesh_comp2_register(comp_p2); } /** @brief Verify that the provisioner can provision a device multiple times after resets using @@ -1182,7 +1211,7 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void) */ static void test_device_pb_remote_server_unproved(void) { - device_pb_remote_server_setup_unproved(&rpr_srv_comp); + device_pb_remote_server_setup_unproved(&rpr_srv_comp, &comp_p2_1); PASS(); } @@ -1193,7 +1222,7 @@ static void test_device_pb_remote_server_unproved(void) */ static void test_device_pb_remote_server_unproved_unresponsive(void) { - device_pb_remote_server_setup_unproved(&rpr_srv_comp_unresponsive); + device_pb_remote_server_setup_unproved(&rpr_srv_comp_unresponsive, NULL); k_sem_init(&pdu_send_sem, 0, 1); ASSERT_OK(k_sem_take(&pdu_send_sem, K_SECONDS(200))); @@ -1206,7 +1235,7 @@ static void test_device_pb_remote_server_unproved_unresponsive(void) */ static void test_device_pb_remote_server_proved(void) { - device_pb_remote_server_setup_proved(&rpr_srv_comp); + device_pb_remote_server_setup_proved(&rpr_srv_comp, &comp_p2_1); PASS(); } @@ -1325,6 +1354,32 @@ static void test_provisioner_pb_remote_client_ncrp_provision(void) PASS(); } +static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_simple *comp) +{ + uint8_t page_rsp; + + net_buf_simple_reset(comp); + ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page, &page_rsp, comp)); + ASSERT_EQUAL(page, page_rsp); +} + +static void comp_data_compare(struct net_buf_simple *comp1, struct net_buf_simple *comp2, + bool expect_equal) +{ + if (expect_equal) { + ASSERT_EQUAL(comp1->len, comp2->len); + if (memcmp(comp1->data, comp2->data, comp1->len)) { + FAIL("Composition data is not equal"); + } + } else { + if (comp1->len == comp2->len) { + if (!memcmp(comp1->data, comp2->data, comp1->len)) { + FAIL("Composition data is equal"); + } + } + } +} + /** @brief Test Node Composition Refresh procedure on Remote Provisioning client: * - initiate Node Composition Refresh procedure on a 3rd device. */ @@ -1332,30 +1387,30 @@ static void test_provisioner_pb_remote_client_ncrp(void) { NET_BUF_SIMPLE_DEFINE(dev_comp_p0, BT_MESH_RX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(dev_comp_p1, BT_MESH_RX_SDU_MAX); + NET_BUF_SIMPLE_DEFINE(dev_comp_p2, BT_MESH_RX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(dev_comp_p128, BT_MESH_RX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(dev_comp_p129, BT_MESH_RX_SDU_MAX); + NET_BUF_SIMPLE_DEFINE(dev_comp_p130, BT_MESH_RX_SDU_MAX); uint16_t pb_remote_server_addr = 0x0003; - uint8_t page; k_sem_init(&prov_sem, 0, 1); k_sem_init(&reprov_sem, 0, 1); bt_mesh_device_setup(&prov, &rpr_cli_comp); - /* Store Composition Data Page 0, 1, 128 and 129. */ - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 0, &page, &dev_comp_p0)); - ASSERT_EQUAL(0, page); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 1, &page, &dev_comp_p1)); - ASSERT_EQUAL(1, page); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 128, &page, - &dev_comp_p128)); - ASSERT_EQUAL(128, page); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 129, &page, - &dev_comp_p129)); - ASSERT_EQUAL(129, page); - ASSERT_TRUE(dev_comp_p0.len != dev_comp_p128.len); - ASSERT_TRUE(dev_comp_p1.len != dev_comp_p129.len); + /* Store Composition Data Page 0, 1, 2, 128, 129 and 130. */ + comp_data_get(pb_remote_server_addr, 0, &dev_comp_p0); + comp_data_get(pb_remote_server_addr, 128, &dev_comp_p128); + comp_data_compare(&dev_comp_p0, &dev_comp_p128, false); + + comp_data_get(pb_remote_server_addr, 1, &dev_comp_p1); + comp_data_get(pb_remote_server_addr, 129, &dev_comp_p129); + comp_data_compare(&dev_comp_p1, &dev_comp_p129, false); + + comp_data_get(pb_remote_server_addr, 2, &dev_comp_p2); + comp_data_get(pb_remote_server_addr, 130, &dev_comp_p130); + comp_data_compare(&dev_comp_p2, &dev_comp_p130, false); LOG_INF("Start Node Composition Refresh procedure...\n"); @@ -1372,59 +1427,34 @@ static void test_provisioner_pb_remote_client_ncrp(void) ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); /* Check that Composition Data Page 128 still exists and is now equal to Page 0. */ - net_buf_simple_reset(&dev_comp_p0); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 0, &page, &dev_comp_p0)); - ASSERT_EQUAL(0, page); - ASSERT_EQUAL(dev_comp_p0.len, dev_comp_p128.len); - if (memcmp(dev_comp_p0.data, dev_comp_p128.data, dev_comp_p0.len)) { - FAIL("Wrong composition data page 0"); - } - - net_buf_simple_reset(&dev_comp_p128); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 128, &page, - &dev_comp_p128)); - ASSERT_EQUAL(128, page); - ASSERT_EQUAL(dev_comp_p0.len, dev_comp_p128.len); - if (memcmp(dev_comp_p0.data, dev_comp_p128.data, dev_comp_p0.len)) { - FAIL("Wrong composition data page 128"); - } + comp_data_get(pb_remote_server_addr, 0, &dev_comp_p0); + comp_data_compare(&dev_comp_p0, &dev_comp_p128, true); + comp_data_get(pb_remote_server_addr, 128, &dev_comp_p128); + comp_data_compare(&dev_comp_p0, &dev_comp_p128, true); /* Check that Composition Data Page 129 still exists and is now equal to Page 1. */ - net_buf_simple_reset(&dev_comp_p1); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 1, &page, &dev_comp_p1)); - ASSERT_EQUAL(1, page); - ASSERT_EQUAL(dev_comp_p1.len, dev_comp_p129.len); - if (memcmp(dev_comp_p1.data, dev_comp_p129.data, dev_comp_p1.len)) { - FAIL("Wrong composition data page 1"); - } + comp_data_get(pb_remote_server_addr, 1, &dev_comp_p1); + comp_data_compare(&dev_comp_p1, &dev_comp_p129, true); + comp_data_get(pb_remote_server_addr, 129, &dev_comp_p129); + comp_data_compare(&dev_comp_p1, &dev_comp_p129, true); - net_buf_simple_reset(&dev_comp_p129); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 129, &page, - &dev_comp_p129)); - ASSERT_EQUAL(129, page); - ASSERT_EQUAL(dev_comp_p1.len, dev_comp_p129.len); - if (memcmp(dev_comp_p1.data, dev_comp_p129.data, dev_comp_p1.len)) { - FAIL("Wrong composition data page 129"); - } + /* Check that Composition Data Page 130 still exists and is now equal to Page 2. */ + comp_data_get(pb_remote_server_addr, 2, &dev_comp_p2); + comp_data_compare(&dev_comp_p2, &dev_comp_p130, true); + comp_data_get(pb_remote_server_addr, 130, &dev_comp_p130); + comp_data_compare(&dev_comp_p2, &dev_comp_p130, true); PASS(); } -static void comp_data_pages_equal_check(uint16_t server_addr, uint8_t page1, uint8_t page2) +static void comp_data_pages_get_and_equal_check(uint16_t server_addr, uint8_t page1, uint8_t page2) { NET_BUF_SIMPLE_DEFINE(comp_1, BT_MESH_RX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(comp_2, BT_MESH_RX_SDU_MAX); - uint8_t page; - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page1, &page, &comp_1)); - ASSERT_EQUAL(page1, page); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page2, &page, - &comp_2)); - ASSERT_EQUAL(page2, page); - ASSERT_TRUE(comp_1.len == comp_2.len); - if (memcmp(comp_1.data, comp_2.data, comp_1.len)) { - FAIL("Composition data page %d is not the same as page %d", page1, page2); - } + comp_data_get(server_addr, page1, &comp_1); + comp_data_get(server_addr, page2, &comp_2); + comp_data_compare(&comp_1, &comp_2, true); } /** @brief Test Node Composition Refresh procedure on Remote Provisioning client: @@ -1440,9 +1470,9 @@ static void test_provisioner_pb_remote_client_ncrp_second_time(void) bt_mesh_device_setup(&prov, &rpr_cli_comp); - comp_data_pages_equal_check(pb_remote_server_addr, 0, 128); - comp_data_pages_equal_check(pb_remote_server_addr, 1, 129); - + comp_data_pages_get_and_equal_check(pb_remote_server_addr, 0, 128); + comp_data_pages_get_and_equal_check(pb_remote_server_addr, 1, 129); + comp_data_pages_get_and_equal_check(pb_remote_server_addr, 2, 130); LOG_INF("Start Node Composition Refresh procedure...\n"); struct bt_mesh_rpr_node srv = { @@ -1467,7 +1497,7 @@ static void test_provisioner_pb_remote_client_ncrp_second_time(void) */ static void test_device_pb_remote_server_ncrp_prepare(void) { - device_pb_remote_server_setup_unproved(&rpr_srv_comp); + device_pb_remote_server_setup_unproved(&rpr_srv_comp, &comp_p2_1); LOG_INF("Preparing for Composition Data change"); bt_mesh_comp_change_prepare(); @@ -1481,7 +1511,7 @@ static void test_device_pb_remote_server_ncrp_prepare(void) */ static void test_device_pb_remote_server_ncrp(void) { - device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem); + device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem, &comp_p2_2); LOG_INF("Waiting for being re-provisioned."); ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); @@ -1497,7 +1527,7 @@ static void test_device_pb_remote_server_ncrp_second_time(void) { int err; - device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem); + device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem, &comp_p2_2); LOG_INF("Wait to verify that node is not re-provisioned..."); err = k_sem_take(&reprov_sem, K_SECONDS(30)); From 6b627771c898ce2086cc69369eaec34302079e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 30 Aug 2023 14:16:46 +0200 Subject: [PATCH 0142/4498] Bluetooth: Mesh: Shell support for comp data page2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds shell support for composition data page 2 and 130 Signed-off-by: Anders Storrø --- include/zephyr/bluetooth/mesh/cfg_cli.h | 34 ++++++++++++++++++++ subsys/bluetooth/mesh/cfg_cli.c | 35 +++++++++++++++++++++ subsys/bluetooth/mesh/shell/cfg.c | 42 +++++++++++++++++++++++-- 3 files changed, 108 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index e6fd31d7c3a..d2221da38da 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -1786,6 +1786,40 @@ struct bt_mesh_comp_p1_model_item *bt_mesh_comp_p1_item_pull( struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item( struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_ext_item *ext_item); +/** Composition data page 2 record parsing structure. */ +struct bt_mesh_comp_p2_record { + /** Mesh profile ID. */ + uint16_t id; + /** Mesh Profile Version. */ + struct { + /** Major version. */ + uint8_t x; + /** Minor version. */ + uint8_t y; + /** Z version. */ + uint8_t z; + } version; + /** Element offset buffer. */ + struct net_buf_simple *elem_buf; + /** Additional data buffer. */ + struct net_buf_simple *data_buf; +}; + +/** @brief Pull a Composition Data Page 2 Record from a composition data page 2 + * instance. + * + * Each call to this function will pull out a new element from the composition + * data page, until all elements have been pulled. + * + * @param buf Composition data page 2 buffer + * @param record Record to fill. + * + * @return A pointer to @c record on success, or NULL if no more elements could + * be pulled. + */ +struct bt_mesh_comp_p2_record *bt_mesh_comp_p2_record_pull(struct net_buf_simple *buf, + struct bt_mesh_comp_p2_record *record); + /** @brief Unpack a list of key index entries from a buffer. * * On success, @c dst_cnt is set to the amount of unpacked key index entries. diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index a5ad80193f3..68af4fae59d 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -2443,3 +2443,38 @@ struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item( } return ext_item; } + +struct bt_mesh_comp_p2_record *bt_mesh_comp_p2_record_pull(struct net_buf_simple *buf, + struct bt_mesh_comp_p2_record *record) +{ + if (buf->len < 8) { + LOG_DBG("No more elements to pull or missing data"); + return NULL; + } + + uint8_t elem_offset_cnt; + uint16_t data_len; + + record->id = net_buf_simple_pull_le16(buf); + record->version.x = net_buf_simple_pull_u8(buf); + record->version.y = net_buf_simple_pull_u8(buf); + record->version.z = net_buf_simple_pull_u8(buf); + elem_offset_cnt = net_buf_simple_pull_u8(buf); + if (buf->len < elem_offset_cnt + 2) { + LOG_WRN("Invalid composition data offset count"); + return NULL; + } + + net_buf_simple_init_with_data(record->elem_buf, + net_buf_simple_pull_mem(buf, elem_offset_cnt), + elem_offset_cnt); + data_len = net_buf_simple_pull_le16(buf); + if (buf->len < data_len) { + LOG_WRN("Invalid composition data additional data length"); + return NULL; + } + + net_buf_simple_init_with_data(record->data_buf, + net_buf_simple_pull_mem(buf, data_len), data_len); + return record; +} diff --git a/subsys/bluetooth/mesh/shell/cfg.c b/subsys/bluetooth/mesh/shell/cfg.c index d47f04bcc00..c4a62a996e3 100644 --- a/subsys/bluetooth/mesh/shell/cfg.c +++ b/subsys/bluetooth/mesh/shell/cfg.c @@ -98,9 +98,10 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[]) return 0; } - if (page != 0 && page != 1 && page != 128 && page != 129) { - shell_print(sh, "Got page %d. No parser available.", - page); + if (page != 0 && page != 128 && + ((page != 1 && page != 129) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) && + ((page != 2 && page != 130) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2))) { + shell_print(sh, "Got page %d. No parser available.", page); return 0; } @@ -254,6 +255,41 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[]) } } + if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { + /* size of 32 is chosen arbitrary, as sufficient for testing purposes */ + NET_BUF_SIMPLE_DEFINE(p2_elem_offset_buf, 32); + NET_BUF_SIMPLE_DEFINE(p2_data_buf, 32); + struct bt_mesh_comp_p2_record p2_elem = { + .elem_buf = &p2_elem_offset_buf, + .data_buf = &p2_data_buf + }; + + if (!buf.len) { + shell_error(sh, "Composition data empty"); + return 0; + } + shell_print(sh, "Got Composition Data for 0x%04x, page: %d:", + bt_mesh_shell_target_ctx.dst, page); + + while (bt_mesh_comp_p2_record_pull(&buf, &p2_elem)) { + + shell_print(sh, "\tMesh Profile id: %04x ", p2_elem.id); + shell_print(sh, "\t\tVersion: %d.%d.%d ", p2_elem.version.x, + p2_elem.version.y, p2_elem.version.z); + shell_print(sh, "\t\tElement offsets:"); + + while (p2_elem.elem_buf->len) { + shell_print(sh, "\t\t\t%d ", + net_buf_simple_pull_u8(p2_elem.elem_buf)); + } + + if (p2_elem.data_buf->len) { + shell_print(sh, "\t\t%d bytes of additional data is available", + p2_elem.data_buf->len); + } + } + } + if (buf.len) { shell_print(sh, "\t\t...truncated data!"); } From 81c6ae8908d7274347b74af49a71c0b7256a2ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 31 Aug 2023 09:12:26 +0200 Subject: [PATCH 0143/4498] doc: Bluetooth: Mesh: Add docs for comp data pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds documentation for all supported composition data pages. Signed-off-by: Anders Storrø --- .../bluetooth/api/mesh/access.rst | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 37d5d6fddef..9bf6e231c21 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -165,6 +165,61 @@ while model data is being stored. It is recommended to use this option and the :c:func:`bt_mesh_model_data_store_schedule` function when large amount of data needs to be stored. +Composition Data +================ + +.. note:: + + Currently the implementation of the Bluetooth Mesh Protocol Specification + version 1.1 is in an experimental state. In that context we must clarify + that for Mesh version 1.0 only composition data page 0 is supported. Users + that are developing for Mesh version 1.0 may therefore disregard all + entries in the following section mentioning the :ref:`bluetooth_mesh_lcd_srv` + model and composition data page 1, 2, 128, 129 and 130. + +The Composition Data provides information about a Mesh device. +A device's composition data holds information about the elements on the +device, the models that it supports, and other features. The Composition +Data is split into different pages, where each page contains specific feature +information about the device. In order to access this information, the user +may use the :ref:`bluetooth_mesh_models_cfg_srv` model or, if supported, +the :ref:`bluetooth_mesh_lcd_srv` model. + +Composition Data Page 0 and 128 +------------------------------- + +Composition Data Page 0 provides the fundemental information about a device, and +is mandatory for all mesh devices. It contains the element and model composition, +the supported features, and manufacturer information. Composition Data Page 128 +mirrors Page 0 and is used to represent the new content of the Composition Data +Page 0 after a device firmware update. + +Composition Data Page 1 and 129 +------------------------------- + +Composition Data Page 1 provides information about the relationships between models, +and is mandatory for all mesh devices. A model may extend and/or correspond to one +or more models. A model can extend another model by calling :c:func:`bt_mesh_model_extend`, +or correspond to another model by calling :c:func:`bt_mesh_model_correspond`. +:kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE` specifies how many models +relations that can be stored in the composition on a device, and this number should +reflect the the number of :c:func:`bt_mesh_model_extend` and +:c:func:`bt_mesh_model_correspond` calls. Composition Data Page 129 mirrors Page 1 +and is used to represent the new content of the Composition Data Page 1 after a +device firmware update. + +Composition Data Page 2 and 130 +------------------------------- + +Composition Data Page 2 provides information for supported Mesh profiles. Mesh profile +specifications define product requirements for devices that want to support a specific +Bluetooth SIG defined profile. Currently supported profiles can be found in section +3.12 in `Bluetooth SIG Assigned Numbers +`_. Composition Data Page 2 is only mandatory for +devices that claim support for or more mesh profile(s). Composition Data Page 130 +mirrors Page 2 and is used to represent the new content of the Composition Data Page 2 +after a device firmware update. + API reference ************* From 1e826bb670b1d047046a6b210631d4216779e04c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 1 Sep 2023 10:59:08 +0200 Subject: [PATCH 0144/4498] Bluetooth: BAP: Shell: Fix issue in cmd add_pa_sync The command was missing a metalen check, and attempted to access array of size 0, which could give a build warning. Signed-off-by: Emil Gydesen --- .../audio/shell/bap_broadcast_assistant.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c index 76902152dd5..5f98a26f8c1 100644 --- a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c @@ -779,7 +779,6 @@ static int cmd_bap_broadcast_assistant_mod_src(const struct shell *sh, static int cmd_bap_broadcast_assistant_add_pa_sync(const struct shell *sh, size_t argc, char **argv) { - struct bt_bap_scan_delegator_subgroup subgroup_params[BT_ISO_MAX_GROUP_ISO_COUNT] = { 0 }; struct bt_bap_broadcast_assistant_add_src_param param = { 0 }; /* TODO: Add support to select which PA sync to BIG sync to */ struct bt_le_per_adv_sync *pa_sync = per_adv_syncs[0]; @@ -855,6 +854,9 @@ static int cmd_bap_broadcast_assistant_add_pa_sync(const struct shell *sh, /* The MIN is used to handle `array-bounds` error on some compilers */ param.num_subgroups = MIN(received_base.subgroup_count, BROADCAST_SNK_SUBGROUP_CNT); +#if BROADCAST_SNK_SUBGROUP_CNT > 0 + struct bt_bap_scan_delegator_subgroup subgroup_params[BROADCAST_SNK_SUBGROUP_CNT] = {0}; + param.subgroups = subgroup_params; for (size_t i = 0; i < param.num_subgroups; i++) { struct bt_bap_scan_delegator_subgroup *subgroup_param = &subgroup_params[i]; @@ -873,12 +875,22 @@ static int cmd_bap_broadcast_assistant_add_pa_sync(const struct shell *sh, #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 metadata_len = subgroup->codec_cfg.meta_len; + if (metadata_len > sizeof(subgroup_param->metadata)) { + shell_error(sh, + "Could not set %zu octets of metadata for subgroup_param of " + "size %zu", + metadata_len, sizeof(subgroup_param->metadata)); + + return -ENOEXEC; + } + memcpy(subgroup_param->metadata, subgroup->codec_cfg.meta, metadata_len); #else metadata_len = 0U; #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ subgroup_param->metadata_len = metadata_len; } +#endif /* BROADCAST_SNK_SUBGROUP_CNT > 0 */ err = bt_bap_broadcast_assistant_add_src(default_conn, ¶m); if (err != 0) { From 7082222ac6606c537c18639ede88286b4a3e575a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 7 Sep 2023 11:01:46 +0200 Subject: [PATCH 0145/4498] Bluetooth: Controller: Nordic LLL: Use HAL to clear RTC event Use the HAL event clear function to clear the RTC EVENT instead of accessing the register directly. This allows using an updated version of the RTC HW models which generate level interrupts (as the real HW) and in which if the EVEN register is not properly cleared, the interrupts are kept high, resulting in the interrupt handler reentering immediately after exiting. Signed-off-by: Alberto Escolar Piedras --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index bc71bbcd5a6..1f8031a7c07 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -8,6 +8,8 @@ #include #include +#include + #include #include @@ -106,7 +108,7 @@ static void rtc0_nrf5_isr(const void *arg) /* On compare0 run ticker worker instance0 */ if (NRF_RTC0->EVENTS_COMPARE[0]) { - NRF_RTC0->EVENTS_COMPARE[0] = 0; + nrf_rtc_event_clear(NRF_RTC0, NRF_RTC_EVENT_COMPARE_0); ticker_trigger(0); } From bb811a1e1d7c7662bbfb9278c8994b32dc61b55b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 7 Sep 2023 11:04:33 +0200 Subject: [PATCH 0146/4498] Bluetooth: Controller: Nordic LLL: Use HAL to clear EVENTs Use the HAL event clear functions to clear EVENTS instead of accessing the registers directly. Signed-off-by: Alberto Escolar Piedras --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 7b72b1a4b93..1875dca7896 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -568,18 +568,18 @@ void radio_status_reset(void) * register value, PPI task will be triggered. Hence, other * EVENT_* registers are not reset to save code and CPU time. */ - NRF_RADIO->EVENTS_READY = 0; - NRF_RADIO->EVENTS_END = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END); #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST) /* Clear it only for SoCs supporting DF extension */ - NRF_RADIO->EVENTS_PHYEND = 0; - NRF_RADIO->EVENTS_CTEPRESENT = 0; - NRF_RADIO->EVENTS_BCMATCH = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT); + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */ - NRF_RADIO->EVENTS_DISABLED = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); #if defined(CONFIG_BT_CTLR_PHY_CODED) #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) - NRF_RADIO->EVENTS_RATEBOOST = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST); #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ #endif /* CONFIG_BT_CTLR_PHY_CODED */ } @@ -1019,7 +1019,7 @@ uint32_t radio_rssi_get(void) void radio_rssi_status_reset(void) { - NRF_RADIO->EVENTS_RSSIEND = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); } uint32_t radio_rssi_is_ready(void) @@ -1051,7 +1051,7 @@ void radio_filter_disable(void) void radio_filter_status_reset(void) { - NRF_RADIO->EVENTS_DEVMATCH = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH); } uint32_t radio_filter_has_match(void) @@ -1072,7 +1072,7 @@ void radio_bc_configure(uint32_t n) void radio_bc_status_reset(void) { - NRF_RADIO->EVENTS_BCMATCH = 0; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); } uint32_t radio_bc_has_match(void) @@ -1356,7 +1356,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) start_us = (now_us << 1) - start_us; /* Setup compare event with min. 1 us offset */ - EVENT_TIMER->EVENTS_COMPARE[0] = 0U; + nrf_timer_event_clear(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0); nrf_timer_cc_set(EVENT_TIMER, 0, start_us + 1U); /* Capture the current time */ @@ -1749,9 +1749,9 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->OUTPTR = (uint32_t)pkt; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = 0; - NRF_CCM->EVENTS_ENDKSGEN = 0; - NRF_CCM->EVENTS_ENDCRYPT = 0; - NRF_CCM->EVENTS_ERROR = 0; + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDCRYPT); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); @@ -1820,9 +1820,9 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM->EVENTS_ENDKSGEN = 0; - NRF_CCM->EVENTS_ENDCRYPT = 0; - NRF_CCM->EVENTS_ERROR = 0; + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDCRYPT); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); @@ -1899,9 +1899,9 @@ void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags) NRF_AAR->ADDRPTR = addrptr; NRF_AAR->SCRATCHPTR = (uint32_t)&_aar_scratch[0]; - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END); + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED); + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED); radio_bc_configure(bcc); radio_bc_status_reset(); @@ -1957,9 +1957,9 @@ uint8_t radio_ar_resolve(const uint8_t *addr) NRF_AAR->ADDRPTR = (uint32_t)addr - 3; - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END); + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED); + nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED); NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR)); From 66bf33f0900854a3df968e8a93a8dba4bd676c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Thu, 7 Sep 2023 17:46:24 +0200 Subject: [PATCH 0147/4498] Bluetooth: Mesh: Fix Solicitation Mesh crypto API use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pointer of the keys should be send to mesh en/decryption APIs. Signed-off-by: Alperen Şener --- subsys/bluetooth/mesh/solicitation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index 1bf9f9a465a..f6543dcb320 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -304,7 +304,7 @@ static int sol_pdu_create(struct bt_mesh_subnet *sub, struct net_buf_simple *pdu /* DST = 0x0000 */ net_buf_simple_add_le16(pdu, 0x0000); - err = bt_mesh_net_encrypt(sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.enc, + err = bt_mesh_net_encrypt(&sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.enc, pdu, 0, BT_MESH_NONCE_SOLICITATION); if (err) { @@ -313,7 +313,7 @@ static int sol_pdu_create(struct bt_mesh_subnet *sub, struct net_buf_simple *pdu } err = bt_mesh_net_obfuscate(pdu->data, 0, - sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.privacy); + &sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.privacy); if (err) { LOG_ERR("Obfuscation failed, err=%d", err); return err; From ffe8815c8c84064c3c2779c3411c539b8e5e2614 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 22 Aug 2023 23:55:03 -0700 Subject: [PATCH 0148/4498] tests: lib: cmsis_dsp: matrix: fix double-promotion warning Double promotion warnings are generated with the flag -Wdouble-promotion Signed-off-by: Ryan McClelland --- tests/lib/cmsis_dsp/matrix/src/unary_f64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib/cmsis_dsp/matrix/src/unary_f64.c b/tests/lib/cmsis_dsp/matrix/src/unary_f64.c index 1835cda30ff..e42a9bd87fc 100644 --- a/tests/lib/cmsis_dsp/matrix/src/unary_f64.c +++ b/tests/lib/cmsis_dsp/matrix/src/unary_f64.c @@ -13,11 +13,11 @@ #include "unary_f64.pat" -#define SNR_ERROR_THRESH ((float32_t)120) +#define SNR_ERROR_THRESH ((float64_t)120) #define REL_ERROR_THRESH (1.0e-6) #define ABS_ERROR_THRESH (1.0e-5) -#define SNR_ERROR_THRESH_CHOL ((float32_t)270) +#define SNR_ERROR_THRESH_CHOL ((float64_t)270) #define REL_ERROR_THRESH_CHOL (1.0e-9) #define ABS_ERROR_THRESH_CHOL (1.0e-9) From 8ea58fc43b77859df713712cc5be2c33a10b0e7e Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Wed, 23 Aug 2023 09:35:59 -0700 Subject: [PATCH 0149/4498] tests: lib: cmsis_dsp: binary: fix double-promotion warning Double promotion warnings are generated with the flag -Wdouble-promotion Signed-off-by: Ryan McClelland --- tests/lib/cmsis_dsp/matrix/src/binary_f64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/cmsis_dsp/matrix/src/binary_f64.c b/tests/lib/cmsis_dsp/matrix/src/binary_f64.c index 4c30dfc8856..2a552750092 100644 --- a/tests/lib/cmsis_dsp/matrix/src/binary_f64.c +++ b/tests/lib/cmsis_dsp/matrix/src/binary_f64.c @@ -13,7 +13,7 @@ #include "binary_f64.pat" -#define SNR_ERROR_THRESH ((float32_t)120) +#define SNR_ERROR_THRESH ((float64_t)120) #define REL_ERROR_THRESH (1.0e-6) #define ABS_ERROR_THRESH (1.0e-5) From 28e6839db60fa8c1f2d2f543d3a9297160018da6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 4 Sep 2023 13:29:53 -0500 Subject: [PATCH 0150/4498] doc/releases: Add picolibc migration notes There aren't any 'required' or 'recommended' changes when switching from the minimal C library to picolibc, but there are a bunch of things which application developers might need to be aware of. Add a separate section to list those. Signed-off-by: Keith Packard --- doc/releases/migration-guide-3.5.rst | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 7ffb16319d1..f3ae1852082 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -42,3 +42,51 @@ Recommended Changes :kconfig:option:`CONFIG_GIC_V3` directly in Kconfig has been deprecated. The GIC version should now be specified by adding the appropriate compatible, for example :dtcompatible:`arm,gic-v2`, to the GIC node in the device tree. + +Picolibc-related Changes +************************ + +The default C library used on most targets has changed from the built-in +minimal C library to Picolibc. While both provide standard C library +interfaces and shouldn't cause any behavioral regressions for applications, +there are a few side effects to be aware of when migrating to Picolibc. + +* Picolibc enables thread local storage + (:kconfig:option:`CONFIG_THREAD_LOCAL_STORAGE`) where supported. This + changes some internal operations within the kernel that improve + performance using some TLS variables. Zephyr places TLS variables in the + memory reserved for the stack, so stack usage for every thread will + increase by 8-16 bytes. + +* Picolibc uses the same malloc implementation as the minimal C library, but + the default heap size depends on which C library is in use. When using the + minimal C library, the default heap is zero bytes, which means that malloc + will always fail. When using Picolibc, the default is 16kB with + :kconfig:option:`CONFIG_MMU` or :kconfig:option:`ARCH_POSIX`, 2kB with + :kconfig:option:`CONFIG_USERSPACE` and + :kconfig:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`. For all + other targets, the default heap uses all remaining memory on the system. + You can change this by adjusting + :kconfig:option:`CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE`. + +* Picolibc can either be built as part of the OS build or pulled from the + toolchain. When building as part of the OS, the build will increase by + approximately 1000 files. + +* When using the standard C++ library with Picolibc, both of those must come + from the toolchain as the standard C++ library depends upon the C library + ABI. + +* Picolibc removes the ``-ffreestanding`` compiler option. This allows + significant compiler optimization improvements, but also means that the + compiler will now warn about declarations of `main` which don't conform to + the Zephyr required type -- ``int main(void)``. + +* Picolibc's default floating point input/output code is larger than the + minimal C library version (this is necessary to conform with the C + language "round trip" requirements for these operations). If you use + :kconfig:option:`CONFIG_CBPRINTF_FP_SUPPORT`, you will see increased + memory usage unless you also disable + :kconfig:option:`CONFIG_PICOLIBC_IO_FLOAT_EXACT`, which switches Picolibc + to a smaller, but inexact conversion algorithm. This requires building + Picolibc as a module. From 7695a4d5e6c5dae9595a58cf1a3d60c48485a8b5 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 8 Sep 2023 13:52:58 -0600 Subject: [PATCH 0151/4498] x86: Remove unused ACPI include The prep_c.c source doesn't depend on the ACPI library. As ACPI support now requires the ACPICA module, the extra header breaks projects using x86 without ACPI support. Signed-off-by: Keith Short --- arch/x86/core/prep_c.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index ffb4d6b019a..ee095efe33d 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include From 51707daaded7e26a80a7ef6b3907a10052e7309f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Fri, 8 Sep 2023 15:00:40 +0200 Subject: [PATCH 0152/4498] doc: Bluetooth: Mesh: Fix comp data doc entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor cleanup of the mesh composition data pages documentation. Signed-off-by: Anders Storrø --- .../bluetooth/api/mesh/access.rst | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 9bf6e231c21..d34b0078d81 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -170,15 +170,15 @@ Composition Data .. note:: - Currently the implementation of the Bluetooth Mesh Protocol Specification - version 1.1 is in an experimental state. In that context we must clarify - that for Mesh version 1.0 only composition data page 0 is supported. Users - that are developing for Mesh version 1.0 may therefore disregard all - entries in the following section mentioning the :ref:`bluetooth_mesh_lcd_srv` - model and composition data page 1, 2, 128, 129 and 130. - -The Composition Data provides information about a Mesh device. -A device's composition data holds information about the elements on the + The implementation of the Bluetooth Mesh Protocol Specification version 1.1 + is currently in an experimental state. For Bluetooth Mesh Profile Specification + version 1.0.1, only Composition Data Page 0 is supported. Users that are developing + for Bluetooth Mesh Profile Specification version 1.0.1 may therefore disregard all + parts of the following section mentioning the :ref:`bluetooth_mesh_lcd_srv` + model and Composition Data Pages 1, 2, 128, 129 and 130. + +The Composition Data provides information about a mesh device. +A device's Composition Data holds information about the elements on the device, the models that it supports, and other features. The Composition Data is split into different pages, where each page contains specific feature information about the device. In order to access this information, the user @@ -201,24 +201,23 @@ Composition Data Page 1 provides information about the relationships between mod and is mandatory for all mesh devices. A model may extend and/or correspond to one or more models. A model can extend another model by calling :c:func:`bt_mesh_model_extend`, or correspond to another model by calling :c:func:`bt_mesh_model_correspond`. -:kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE` specifies how many models -relations that can be stored in the composition on a device, and this number should -reflect the the number of :c:func:`bt_mesh_model_extend` and -:c:func:`bt_mesh_model_correspond` calls. Composition Data Page 129 mirrors Page 1 -and is used to represent the new content of the Composition Data Page 1 after a -device firmware update. +:kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE` specifies how many model +relations can be stored in the composition on a device, and this number should reflect the +number of :c:func:`bt_mesh_model_extend` and :c:func:`bt_mesh_model_correspond` calls. +Composition Data Page 129 mirrors Page 1 and is used to represent the new content of +the Composition Data Page 1 after a device firmware update. Composition Data Page 2 and 130 ------------------------------- -Composition Data Page 2 provides information for supported Mesh profiles. Mesh profile +Composition Data Page 2 provides information for supported mesh profiles. Mesh profile specifications define product requirements for devices that want to support a specific Bluetooth SIG defined profile. Currently supported profiles can be found in section 3.12 in `Bluetooth SIG Assigned Numbers -`_. Composition Data Page 2 is only mandatory for -devices that claim support for or more mesh profile(s). Composition Data Page 130 -mirrors Page 2 and is used to represent the new content of the Composition Data Page 2 -after a device firmware update. +`_. +Composition Data Page 2 is only mandatory for devices that claim support for one or more +mesh profile(s). Composition Data Page 130 mirrors Page 2 and is used to represent the +new content of the Composition Data Page 2 after a device firmware update. API reference ************* From 9a0f914b0f530d7b4b185b3377adfe2cd31f0ad8 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 4 Sep 2023 05:17:26 +0900 Subject: [PATCH 0153/4498] boards: arm: sparkfun_pro_micro_rp2040: documentize supported features Add document about already supported features. Signed-off-by: TOKITA Hiroshi --- boards/arm/sparkfun_pro_micro_rp2040/doc/index.rst | 3 +++ .../sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml | 1 + 2 files changed, 4 insertions(+) diff --git a/boards/arm/sparkfun_pro_micro_rp2040/doc/index.rst b/boards/arm/sparkfun_pro_micro_rp2040/doc/index.rst index e2de7d69aaf..1999d64def7 100644 --- a/boards/arm/sparkfun_pro_micro_rp2040/doc/index.rst +++ b/boards/arm/sparkfun_pro_micro_rp2040/doc/index.rst @@ -79,6 +79,9 @@ hardware features: * - Flash - :kconfig:option:`CONFIG_FLASH` - :dtcompatible:`raspberrypi,pico-flash` + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` Pin Mapping =========== diff --git a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml index c898e1b5d53..d5993798ff4 100644 --- a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml +++ b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml @@ -18,3 +18,4 @@ supported: - watchdog - pwm - flash + - dma From eb12c0c381949d11e21e91411460549058cf9553 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 4 Sep 2023 05:17:30 +0900 Subject: [PATCH 0154/4498] boards: arm: adafruit_kb2040: documentize supported features Add document about already supported features. Signed-off-by: TOKITA Hiroshi --- boards/arm/adafruit_kb2040/adafruit_kb2040.yaml | 2 ++ boards/arm/adafruit_kb2040/doc/index.rst | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/boards/arm/adafruit_kb2040/adafruit_kb2040.yaml b/boards/arm/adafruit_kb2040/adafruit_kb2040.yaml index e7a9e0c9bb7..51dd75d58d9 100644 --- a/boards/arm/adafruit_kb2040/adafruit_kb2040.yaml +++ b/boards/arm/adafruit_kb2040/adafruit_kb2040.yaml @@ -17,3 +17,5 @@ supported: - hwinfo - watchdog - pwm + - flash + - dma diff --git a/boards/arm/adafruit_kb2040/doc/index.rst b/boards/arm/adafruit_kb2040/doc/index.rst index bc891b82fe2..98c2bacf9e3 100644 --- a/boards/arm/adafruit_kb2040/doc/index.rst +++ b/boards/arm/adafruit_kb2040/doc/index.rst @@ -76,6 +76,12 @@ hardware features: * - PWM - :kconfig:option:`CONFIG_PWM` - :dtcompatible:`raspberrypi,pico-pwm` + * - Flash + - :kconfig:option:`CONFIG_FLASH` + - :dtcompatible:`raspberrypi,pico-flash` + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` Pin Mapping =========== From 5aa329cecde6954af379f1f66549d7d07d47165e Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Sat, 2 Sep 2023 15:39:12 +0200 Subject: [PATCH 0155/4498] net: l2: ieee802154: mgmt: fix locking issue Fixes a locking issue in the IEEE 802.15.4 net mgmt implementation. Signed-off-by: Florian Grandel --- subsys/net/l2/ieee802154/ieee802154_mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index e009018c835..d1132d902ce 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -127,6 +127,7 @@ static int ieee802154_scan(uint32_t mgmt_request, struct net_if *iface, pkt = ieee802154_create_mac_cmd_frame( iface, IEEE802154_CFI_BEACON_REQUEST, ¶ms); if (!pkt) { + k_sem_give(&ctx->scan_ctx_lock); NET_DBG("Could not create Beacon Request"); ret = -ENOBUFS; goto out; From c88e5360b12e6e1ca0d12b1a56f8c22309016a5f Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 7 Sep 2023 15:25:49 +0200 Subject: [PATCH 0156/4498] net: l2: ieee802154: fix settings order In the IEEE 802.15.4 area certain settings must be set before net_if_up() may be called (e.g. the channel). Also net_if_up() may not be called if CONFIG_IEEE802154_NET_IF_NO_AUTO_START=y. This fixes the set-up order and handling of CONFIG_IEEE802154_NET_IF_NO_AUTO_START. Signed-off-by: Florian Grandel --- subsys/net/l2/ieee802154/ieee802154.c | 3 ++- subsys/net/lib/config/ieee802154_settings.c | 22 +++++++++++------ subsys/net/lib/config/ieee802154_settings.h | 4 +++- subsys/net/lib/config/init.c | 26 ++++++++++++++++----- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index 543c4a4d43b..43a2d052daa 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -655,7 +655,8 @@ void ieee802154_init(struct net_if *iface) memcpy(ctx->linkaddr.addr, eui64_be, IEEE802154_EXT_ADDR_LENGTH); net_if_set_link_addr(iface, ctx->linkaddr.addr, ctx->linkaddr.len, ctx->linkaddr.type); - if (IS_ENABLED(CONFIG_IEEE802154_NET_IF_NO_AUTO_START)) { + if (IS_ENABLED(CONFIG_IEEE802154_NET_IF_NO_AUTO_START) || + IS_ENABLED(CONFIG_NET_CONFIG_SETTINGS)) { LOG_DBG("Interface auto start disabled."); net_if_flag_set(iface, NET_IF_NO_AUTO_START); } diff --git a/subsys/net/lib/config/ieee802154_settings.c b/subsys/net/lib/config/ieee802154_settings.c index 5217a5cf00e..72fd4a37576 100644 --- a/subsys/net/lib/config/ieee802154_settings.c +++ b/subsys/net/lib/config/ieee802154_settings.c @@ -17,10 +17,12 @@ LOG_MODULE_DECLARE(net_config, CONFIG_NET_CONFIG_LOG_LEVEL); #include #include -int z_net_config_ieee802154_setup(void) +int z_net_config_ieee802154_setup(struct net_if *iface) { uint16_t channel = CONFIG_NET_CONFIG_IEEE802154_CHANNEL; uint16_t pan_id = CONFIG_NET_CONFIG_IEEE802154_PAN_ID; + const struct device *const dev = iface == NULL ? DEVICE_DT_GET(DT_CHOSEN(zephyr_ieee802154)) + : net_if_get_device(iface); int16_t tx_power = CONFIG_NET_CONFIG_IEEE802154_RADIO_TX_POWER; #ifdef CONFIG_NET_L2_IEEE802154_SECURITY @@ -32,16 +34,15 @@ int z_net_config_ieee802154_setup(void) }; #endif /* CONFIG_NET_L2_IEEE802154_SECURITY */ - struct net_if *iface; - const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_ieee802154)); - if (!device_is_ready(dev)) { return -ENODEV; } - iface = net_if_lookup_by_dev(dev); if (!iface) { - return -EINVAL; + iface = net_if_lookup_by_dev(dev); + if (!iface) { + return -ENOENT; + } } if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, @@ -60,7 +61,14 @@ int z_net_config_ieee802154_setup(void) } #endif /* CONFIG_NET_L2_IEEE802154_SECURITY */ - net_if_up(iface); + if (!IS_ENABLED(CONFIG_IEEE802154_NET_IF_NO_AUTO_START)) { + /* The NET_IF_NO_AUTO_START flag was set by the driver, see + * ieee802154_init() to allow for configuration before starting + * up the interface. + */ + net_if_flag_clear(iface, NET_IF_NO_AUTO_START); + net_if_up(iface); + } return 0; } diff --git a/subsys/net/lib/config/ieee802154_settings.h b/subsys/net/lib/config/ieee802154_settings.h index 08164253c05..5f0bb70b249 100644 --- a/subsys/net/lib/config/ieee802154_settings.h +++ b/subsys/net/lib/config/ieee802154_settings.h @@ -7,7 +7,9 @@ */ #if defined(CONFIG_NET_L2_IEEE802154) && defined(CONFIG_NET_CONFIG_SETTINGS) -int z_net_config_ieee802154_setup(void); +struct net_if; + +int z_net_config_ieee802154_setup(struct net_if *iface); #else #define z_net_config_ieee802154_setup(...) 0 #endif diff --git a/subsys/net/lib/config/init.c b/subsys/net/lib/config/init.c index cd2bf711a7d..5e5cf449b22 100644 --- a/subsys/net/lib/config/init.c +++ b/subsys/net/lib/config/init.c @@ -367,6 +367,14 @@ int net_config_init_by_iface(struct net_if *iface, const char *app_info, iface = net_if_get_default(); } + if (!iface) { + return -ENOENT; + } + + if (net_if_flag_is_set(iface, NET_IF_NO_AUTO_START)) { + return -ENETDOWN; + } + if (timeout < 0) { count = -1; } else if (timeout == 0) { @@ -453,7 +461,7 @@ int net_config_init_app(const struct device *dev, const char *app_info) } } - ret = z_net_config_ieee802154_setup(); + ret = z_net_config_ieee802154_setup(iface); if (ret < 0) { NET_ERR("Cannot setup IEEE 802.15.4 interface (%d)", ret); } @@ -466,6 +474,17 @@ int net_config_init_app(const struct device *dev, const char *app_info) } #endif + /* Only try to use a network interface that is auto started */ + if (iface == NULL) { + net_if_foreach(iface_find_cb, &iface); + } + + if (!iface) { + NET_WARN("No auto-started network interface - " + "network-bound app initialization skipped."); + return 0; + } + if (IS_ENABLED(CONFIG_NET_CONFIG_NEED_IPV6)) { flags |= NET_CONFIG_NEED_IPV6; } @@ -478,11 +497,6 @@ int net_config_init_app(const struct device *dev, const char *app_info) flags |= NET_CONFIG_NEED_IPV4; } - /* Only try to use a network interface that is auto started */ - if (iface == NULL) { - net_if_foreach(iface_find_cb, &iface); - } - /* Initialize the application automatically if needed */ ret = net_config_init_by_iface(iface, app_info, flags, CONFIG_NET_CONFIG_INIT_TIMEOUT * MSEC_PER_SEC); From 141293ea231077fa85d954a125612ac265c57434 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 7 Sep 2023 15:35:59 +0200 Subject: [PATCH 0157/4498] net: l2: ieee802154: settings: make ACK configurable Add a network configuration option to configure whether IEEE 802.15.4 packets are expected to be ACKed or not. Signed-off-by: Florian Grandel --- subsys/net/lib/config/Kconfig | 7 +++++++ subsys/net/lib/config/ieee802154_settings.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/subsys/net/lib/config/Kconfig b/subsys/net/lib/config/Kconfig index 0f1e3c50544..7d8ceb88c14 100644 --- a/subsys/net/lib/config/Kconfig +++ b/subsys/net/lib/config/Kconfig @@ -176,6 +176,13 @@ config NET_CONFIG_IEEE802154_SECURITY_LEVEL 6 encryption/authentication with a 8 bytes length tag 7 encryption/authentication with a 16 bytes length tag +config NET_CONFIG_IEEE802154_ACK_REQUIRED + bool "IEEE 802.15.4 acknowledgment" + default y + help + Whether or not to request and require IEEE 802.15.4 acknowledgment + packets. + endif # NET_L2_IEEE802154 || IEEE802154_RAW_MODE config NET_CONFIG_BT_NODE diff --git a/subsys/net/lib/config/ieee802154_settings.c b/subsys/net/lib/config/ieee802154_settings.c index 72fd4a37576..4a142bf75bd 100644 --- a/subsys/net/lib/config/ieee802154_settings.c +++ b/subsys/net/lib/config/ieee802154_settings.c @@ -45,6 +45,12 @@ int z_net_config_ieee802154_setup(struct net_if *iface) } } + if (IS_ENABLED(CONFIG_NET_CONFIG_IEEE802154_ACK_REQUIRED)) { + if (net_mgmt(NET_REQUEST_IEEE802154_SET_ACK, iface, NULL, 0)) { + return -EIO; + } + } + if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface, &pan_id, sizeof(uint16_t)) || net_mgmt(NET_REQUEST_IEEE802154_SET_CHANNEL, From 69e459ffb4ce2e21ed68c484e2ef92ef7856bb88 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Sat, 2 Sep 2023 15:23:22 +0200 Subject: [PATCH 0158/4498] doc: drivers: ieee802154: updated nomenclature Introduces new rules for IEEE 802.15.4 driver nomenclature, see #61227. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154_radio.h | 112 +++++++++++++++++--------- 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index ae175ac8e85..cbe45d97664 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -1,12 +1,13 @@ /* * Copyright (c) 2016 Intel Corporation. + * Copyright (c) 2023 F. Grandel, Zephyr Project * * SPDX-License-Identifier: Apache-2.0 */ /** * @file - * @brief Public IEEE 802.15.4 Radio API + * @brief Public IEEE 802.15.4 Driver API * * All references to the spec refer to IEEE 802.15.4-2020. */ @@ -96,6 +97,14 @@ enum ieee802154_channel { IEEE802154_2_4_GHZ_CHANNEL_MAX = 26, }; +/** + * IEEE 802.15.4 driver capabilities + * + * Any driver properties that can be represented in binary form should be + * modeled as capabilities. These are called "hardware" capabilities for + * historical reasons but may also represent driver firmware capabilities (e.g. + * MAC offloading features). + */ enum ieee802154_hw_caps { /* @@ -231,7 +240,7 @@ struct ieee802154_key { uint8_t key_index; }; -/** IEEE802.15.4 Transmission mode. */ +/** IEEE 802.15.4 Transmission mode. */ enum ieee802154_tx_mode { /** Transmit packet immediately, no CCA. */ IEEE802154_TX_MODE_DIRECT, @@ -267,7 +276,7 @@ enum ieee802154_tx_mode { IEEE802154_TX_MODE_PRIV_START = IEEE802154_TX_MODE_COMMON_COUNT, }; -/** IEEE802.15.4 Frame Pending Bit table address matching mode. */ +/** IEEE 802.15.4 Frame Pending Bit table address matching mode. */ enum ieee802154_fpb_mode { /** The pending bit shall be set only for addresses found in the list. */ @@ -279,10 +288,10 @@ enum ieee802154_fpb_mode { IEEE802154_FPB_ADDR_MATCH_ZIGBEE, }; -/** IEEE802.15.4 driver configuration types. */ +/** IEEE 802.15.4 driver configuration types. */ enum ieee802154_config_type { - /** Indicates how radio driver should set Frame Pending bit in ACK - * responses for Data Requests. If enabled, radio driver should + /** Indicates how the driver should set Frame Pending bit in ACK + * responses for Data Requests. If enabled, the driver should * determine whether to set the bit or not based on the information * provided with ``IEEE802154_CONFIG_ACK_FPB`` config and FPB address * matching mode specified. Otherwise, Frame Pending bit should be set @@ -304,15 +313,19 @@ enum ieee802154_config_type { /** Enable/disable promiscuous mode. */ IEEE802154_CONFIG_PROMISCUOUS, - /** Specifies new radio event handler. Specifying NULL as a handler - * will disable radio events notification. + /** Specifies new IEEE 802.15.4 driver event handler. Specifying NULL as + * a handler will disable events notification. */ IEEE802154_CONFIG_EVENT_HANDLER, - /** Updates MAC keys and key index for radios supporting transmit security. */ + /** Updates MAC keys and key index for drivers supporting transmit + * security offloading. + */ IEEE802154_CONFIG_MAC_KEYS, - /** Sets the current MAC frame counter value for radios supporting transmit security. */ + /** Sets the current MAC frame counter value for drivers supporting + * transmit security offloading. + */ IEEE802154_CONFIG_FRAME_COUNTER, /** Sets the current MAC frame counter value if the provided value is greater than @@ -331,12 +344,12 @@ enum ieee802154_config_type { * * In order to configure a CSL receiver the upper layer should combine several * configuration options in the following way: - * 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the radio driver of the + * 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the driver of the * short and extended addresses of the peer to which it should inject CSL IEs. * 2. Use ``IEEE802154_CONFIG_CSL_RX_TIME`` periodically, before each use of * ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not - * the nearest one) CSL RX window, to allow the radio driver to calculate the proper + * the nearest one) CSL RX window, to allow the driver to calculate the proper * CSL Phase to the nearest CSL window to inject in the CSL IEs for both transmitted * data and ACK frames. * 3. Use ``IEEE802154_CONFIG_CSL_PERIOD`` on each value change to update the current CSL @@ -381,7 +394,7 @@ enum ieee802154_config_type { IEEE802154_CONFIG_PRIV_START = IEEE802154_CONFIG_COMMON_COUNT, }; -/** IEEE802.15.4 driver configuration data. */ +/** IEEE 802.15.4 driver configuration data. */ struct ieee802154_config { /** Configuration data. */ union { @@ -497,7 +510,7 @@ enum ieee802154_attr { }; /** - * @brief IEEE 802.15.4 driver attributes. + * @brief IEEE 802.15.4 driver attribute values. * * @details This structure is reserved to scalar and structured attributes that * originate in the driver implementation and can neither be implemented as @@ -522,15 +535,30 @@ struct ieee802154_attr_value { }; /** - * @brief IEEE 802.15.4 radio interface API. + * @brief IEEE 802.15.4 driver interface API. + * + * @note This structure is called "radio" API for backwards compatibility. A + * better name would be "IEEE 802.15.4 driver API" as typical drivers will not + * only implement L1/radio (PHY) features but also L2 (MAC) features if the + * vendor-specific driver hardware or firmware offers offloading opportunities. * + * While L1-level driver features are exclusively implemented by drivers and MAY + * be mandatory to support certain application requirements, L2 features SHOULD + * be optional by default and only need to be implemented for performance + * optimization or precise timing as deemed necessary by driver maintainers. + * Fallback implementations ("Soft MAC") SHOULD be provided in the + * driver-independent L2 layer for all L2/MAC features especially if these + * features are not implemented in vendor hardware/firmware by a majority of + * existing in-tree drivers. If, however, a driver offers offloading + * opportunities then L2 implementations SHALL delegate performance critical or + * resource intensive tasks to the driver. */ struct ieee802154_radio_api { /** * @brief network interface API * * @note Network devices must extend the network interface API. It is - * therefore mandatory to place it at the top of the radio API struct so + * therefore mandatory to place it at the top of the driver API struct so * that it can be cast to a network interface. */ struct net_if_api iface_api; @@ -538,7 +566,7 @@ struct ieee802154_radio_api { /** * @brief Get the device driver capabilities. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @return Bit field with all supported device driver capabilities. */ @@ -547,7 +575,7 @@ struct ieee802154_radio_api { /** * @brief Clear Channel Assessment - Check channel's activity * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 the channel is available * @retval -EBUSY The channel is busy. @@ -559,7 +587,7 @@ struct ieee802154_radio_api { /** * @brief Set current channel * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param channel the number of the channel to be set in CPU byte order * * @retval 0 channel was successfully set @@ -577,7 +605,7 @@ struct ieee802154_radio_api { * * @note requires IEEE802154_HW_FILTER capability. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param set true to set the filter, false to remove it * @param type the type of entity to be added/removed from the filter * list (a PAN ID or a source/destination address) @@ -598,7 +626,7 @@ struct ieee802154_radio_api { /** * @brief Set TX power level in dbm * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param dbm TX power in dbm * * @retval 0 The TX power was successfully set. @@ -627,7 +655,7 @@ struct ieee802154_radio_api { * in software ("soft MAC") or will be provided by the driver itself * ("hard MAC"). * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param mode the transmission mode, some of which require specific * offloading capabilities. * @param pkt pointer to the network packet to be transmitted. @@ -654,7 +682,7 @@ struct ieee802154_radio_api { /** * @brief Start the device and place it in receive mode. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 The driver was successfully started. * @retval -EIO The driver could not be started. @@ -664,7 +692,7 @@ struct ieee802154_radio_api { /** * @brief Stop the device and switch off the receiver (sleep mode). * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 The driver was successfully stopped. * @retval -EIO The driver could not be stopped. @@ -675,9 +703,9 @@ struct ieee802154_radio_api { * @brief Start continuous carrier wave transmission. * * @details To leave this mode, `start()` or `stop()` should be called, - * putting the radio driver in receive or sleep mode, respectively. + * putting the driver in receive or sleep mode, respectively. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 continuous carrier wave transmission started * @retval -EIO not started @@ -685,9 +713,9 @@ struct ieee802154_radio_api { int (*continuous_carrier)(const struct device *dev); /** - * @brief Set radio driver configuration. + * @brief Set driver configuration. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param type the configuration type to be set * @param config the configuration parameters to be set for the given * configuration type @@ -725,7 +753,7 @@ struct ieee802154_radio_api { * * @note The radio channel must be set prior to calling this function. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * @param duration duration of energy scan in ms * @param done_cb function called when the energy scan has finished * @@ -751,7 +779,7 @@ struct ieee802154_radio_api { * @note requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME * capabilities. * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @return nanoseconds relative to the network subsystem's local clock */ @@ -771,7 +799,7 @@ struct ieee802154_radio_api { * @note Implementations may estimate this value based on current * operating conditions (e.g. temperature). * - * @param dev pointer to radio device + * @param dev pointer to IEEE 802.15.4 driver device * * @return current estimated clock accuracy in PPM */ @@ -799,10 +827,14 @@ struct ieee802154_radio_api { }; /* Make sure that the network interface API is properly setup inside - * IEEE 802154 radio API struct (it is the first one). + * IEEE 802.15.4 driver API struct (it is the first one). */ BUILD_ASSERT(offsetof(struct ieee802154_radio_api, iface_api) == 0); +/** + * IEEE 802.15.4 driver utils + */ + #define IEEE802154_AR_FLAG_SET (0x20) /** @@ -820,13 +852,17 @@ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) } /** - * @brief Radio driver ACK handling callback into L2 that radio - * drivers must call when receiving an ACK package. + * IEEE 802.15.4 driver callbacks + */ + +/** + * @brief IEEE 802.15.4 driver ACK handling callback into L2 that drivers must + * call when receiving an ACK package. * * @details The IEEE 802.15.4 standard prescribes generic procedures for ACK * handling on L2 (MAC) level. L2 stacks therefore have to provides a * fast and re-usable generic implementation of this callback for - * radio drivers to call when receiving an ACK packet. + * drivers to call when receiving an ACK packet. * * Note: This function is part of Zephyr's 802.15.4 stack L1 -> L2 * "inversion-of-control" adaptation API and must be implemented by @@ -845,11 +881,11 @@ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) extern enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt); /** - * @brief Radio driver initialization callback into L2 called by radio drivers + * @brief IEEE 802.15.4 driver initialization callback into L2 called by drivers * to initialize the active L2 stack for a given interface. * - * @details Radio drivers must call this function as part of their own - * initialization routine. + * @details Drivers must call this function as part of their own initialization + * routine. * * Note: This function is part of Zephyr's 802.15.4 stack L1 -> L2 * "inversion-of-control" adaptation API and must be implemented by From ffecd8d0fc38d382c96e9492230360b78532507a Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Wed, 6 Sep 2023 08:21:48 +0200 Subject: [PATCH 0159/4498] scripts: tests: twister: Sanity Check Loader tests Adds explicit testing to the Sanity Check Loader utility. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_scl.py | 249 ++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 scripts/tests/twister/test_scl.py diff --git a/scripts/tests/twister/test_scl.py b/scripts/tests/twister/test_scl.py new file mode 100644 index 00000000000..f070b0977b7 --- /dev/null +++ b/scripts/tests/twister/test_scl.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for scl.py functions +""" + +import logging +import mock +import os +import pytest +import sys + +ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") +sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) + +import scl + +from contextlib import nullcontext +from importlib import reload +from pykwalify.errors import SchemaError +from yaml.scanner import ScannerError + + +TESTDATA_1 = [ + (False), + (True), +] + +@pytest.mark.parametrize( + 'fail_c', + TESTDATA_1, + ids=['C YAML', 'non-C YAML'] +) +def test_yaml_imports(fail_c): + class ImportRaiser: + def find_spec(self, fullname, path, target=None): + if fullname == 'yaml.CLoader' and fail_c: + raise ImportError() + if fullname == 'yaml.CSafeLoader' and fail_c: + raise ImportError() + if fullname == 'yaml.CDumper' and fail_c: + raise ImportError() + + modules_mock = sys.modules.copy() + + if hasattr(modules_mock['yaml'], 'CLoader'): + del modules_mock['yaml'].CLoader + del modules_mock['yaml'].CSafeLoader + del modules_mock['yaml'].CDumper + + cloader_mock = mock.Mock() + loader_mock = mock.Mock() + csafeloader_mock = mock.Mock() + safeloader_mock = mock.Mock() + cdumper_mock = mock.Mock() + dumper_mock = mock.Mock() + + if not fail_c: + modules_mock['yaml'].CLoader = cloader_mock + modules_mock['yaml'].CSafeLoader = csafeloader_mock + modules_mock['yaml'].CDumper = cdumper_mock + + modules_mock['yaml'].Loader = loader_mock + modules_mock['yaml'].SafeLoader = safeloader_mock + modules_mock['yaml'].Dumper = dumper_mock + + meta_path_mock = sys.meta_path[:] + meta_path_mock.insert(0, ImportRaiser()) + + with mock.patch.dict('sys.modules', modules_mock, clear=True), \ + mock.patch('sys.meta_path', meta_path_mock): + reload(scl) + + assert sys.modules['scl'].Loader == loader_mock if fail_c else \ + cloader_mock + + assert sys.modules['scl'].SafeLoader == safeloader_mock if fail_c else \ + csafeloader_mock + + assert sys.modules['scl'].Dumper == dumper_mock if fail_c else \ + cdumper_mock + + import yaml + reload(yaml) + + +TESTDATA_2 = [ + (False, logging.CRITICAL, []), + (True, None, ['can\'t import pykwalify; won\'t validate YAML']), +] + +@pytest.mark.parametrize( + 'fail_pykwalify, log_level, expected_logs', + TESTDATA_2, + ids=['pykwalify OK', 'no pykwalify'] +) +def test_pykwalify_import(caplog, fail_pykwalify, log_level, expected_logs): + class ImportRaiser: + def find_spec(self, fullname, path, target=None): + if fullname == 'pykwalify.core' and fail_pykwalify: + raise ImportError() + + modules_mock = sys.modules.copy() + modules_mock['pykwalify'] = None if fail_pykwalify else \ + modules_mock['pykwalify'] + + meta_path_mock = sys.meta_path[:] + meta_path_mock.insert(0, ImportRaiser()) + + with mock.patch.dict('sys.modules', modules_mock, clear=True), \ + mock.patch('sys.meta_path', meta_path_mock): + reload(scl) + + if log_level: + assert logging.getLogger('pykwalify.core').level == log_level + + assert all([log in caplog.text for log in expected_logs]) + + if fail_pykwalify: + assert scl._yaml_validate(None, None) is None + assert scl._yaml_validate(mock.Mock(), mock.Mock()) is None + + reload(scl) + + +TESTDATA_3 = [ + (False), + (True), +] + +@pytest.mark.parametrize( + 'fail_parsing', + TESTDATA_3, + ids=['ok', 'parsing error'] +) +def test_yaml_load(caplog, fail_parsing): + result_mock = mock.Mock() + + def mock_load(*args, **kwargs): + if fail_parsing: + context_mark = mock.Mock() + problem_mark = mock.Mock() + type(context_mark).args = mock.PropertyMock(return_value=[]) + type(context_mark).name = 'dummy context mark' + type(context_mark).line = 0 + type(context_mark).column = 0 + type(problem_mark).args = mock.PropertyMock(return_value=[]) + type(problem_mark).name = 'dummy problem mark' + type(problem_mark).line = 0 + type(problem_mark).column = 0 + raise ScannerError(context='dummy context', + context_mark=context_mark, problem='dummy problem', + problem_mark=problem_mark, note='Dummy note') + return result_mock + + filename = 'dummy/file.yaml' + + with mock.patch('yaml.load', side_effect=mock_load), \ + mock.patch('builtins.open', mock.mock_open()) as mock_file: + with pytest.raises(ScannerError) if fail_parsing else nullcontext(): + result = scl.yaml_load(filename) + + mock_file.assert_called_with('dummy/file.yaml', 'r') + + if not fail_parsing: + assert result == result_mock + else: + assert 'dummy problem mark:0:0: error: dummy problem' \ + ' (note Dummy note context @dummy context mark:0:0' \ + ' dummy context)' in caplog.text + + + +TESTDATA_4 = [ + (True, False, None), + (False, False, SchemaError), + (False, True, ScannerError), +] + +@pytest.mark.parametrize( + 'validate, fail_load, expected_error', + TESTDATA_4, + ids=['successful validation', 'failed validation', 'failed load'] +) +def test_yaml_load_verify(validate, fail_load, expected_error): + filename = 'dummy/file.yaml' + schema_mock = mock.Mock() + data_mock = mock.Mock() + + def mock_load(file_name, *args, **kwargs): + assert file_name == filename + if fail_load: + raise ScannerError + return data_mock + + def mock_validate(data, schema, *args, **kwargs): + assert data == data_mock + assert schema == schema_mock + if validate: + return True + raise SchemaError(u'Schema validation failed.') + + with mock.patch('scl.yaml_load', side_effect=mock_load), \ + mock.patch('scl._yaml_validate', side_effect=mock_validate), \ + pytest.raises(expected_error) if expected_error else nullcontext(): + res = scl.yaml_load_verify(filename, schema_mock) + + if validate: + assert res == data_mock + + +TESTDATA_5 = [ + (True, True, None), + (True, False, SchemaError), + (False, None, None), +] + +@pytest.mark.parametrize( + 'schema_exists, validate, expected_error', + TESTDATA_5, + ids=['successful validation', 'failed validation', 'no schema'] +) +def test_yaml_validate(schema_exists, validate, expected_error): + data_mock = mock.Mock() + schema_mock = mock.Mock() if schema_exists else None + + def mock_validate(raise_exception, *args, **kwargs): + assert raise_exception + if validate: + return True + raise SchemaError(u'Schema validation failed.') + + def mock_core(source_data, schema_data, *args, **kwargs): + assert source_data == data_mock + assert schema_data == schema_mock + return mock.Mock(validate=mock_validate) + + core_mock = mock.Mock(side_effect=mock_core) + + with mock.patch('pykwalify.core.Core', core_mock), \ + pytest.raises(expected_error) if expected_error else nullcontext(): + scl._yaml_validate(data_mock, schema_mock) + + if schema_exists: + core_mock.assert_called_once() + else: + core_mock.assert_not_called() From e6f55318d78385abbd4e11821ba969d6c21669ea Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 8 Sep 2023 10:47:28 +0200 Subject: [PATCH 0160/4498] modules: hal: ti: fix timer integration issues Updates the TI hal modules to include the following fixes in Zephyr's ClockP API implementation: * The unused stubs.h header was removed. * The ClockP implementation contained some cruft due to an incomplete migration from the ms based to the tick based kernel timer API. * The ClockP implementation assumed timeouts and periods to be given in ms although TI's API always expected ticks. * A fix for a major conversion bug in TI's own usage of the ClockP API throughout the SimpleLink framework is included. Signed-off-by: Florian Grandel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index da27a1bc4d1..85ee1533f95 100644 --- a/west.yml +++ b/west.yml @@ -239,7 +239,7 @@ manifest: groups: - hal - name: hal_ti - revision: ae1db23f32dde779cdfc4afaa9a60ea219310a64 + revision: 9fa5827c44b6a81dced9efafb4095dafabea7421 path: modules/hal/ti groups: - hal From bc695c6df5eb8a1f8f9720b20d7e5dcd1533242b Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Mon, 28 Aug 2023 16:35:17 +0200 Subject: [PATCH 0161/4498] drivers: sam dma xdmac: implemented dma device get_status() the sam xdmac driver does not yet implement the get_status() function. with this commit the function will be implemented. Fixes #62003 Signed-off-by: Sven Ginka --- drivers/dma/dma_sam_xdmac.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/dma/dma_sam_xdmac.c b/drivers/dma/dma_sam_xdmac.c index 954fedddff5..7919c5770d1 100644 --- a/drivers/dma/dma_sam_xdmac.c +++ b/drivers/dma/dma_sam_xdmac.c @@ -375,11 +375,36 @@ static int sam_xdmac_initialize(const struct device *dev) return 0; } +static int sam_xdmac_get_status(const struct device *dev, uint32_t channel, + struct dma_status *status) +{ + const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; + + Xdmac * const xdmac = dev_cfg->regs; + uint32_t chan_cfg = xdmac->XDMAC_CHID[channel].XDMAC_CC; + uint32_t ublen = xdmac->XDMAC_CHID[channel].XDMAC_CUBC; + + /* we need to check some of the XDMAC_CC registers to determine the DMA direction */ + if ((chan_cfg & XDMAC_CC_TYPE_Msk) == 0) { + status->dir = MEMORY_TO_MEMORY; + } else if ((chan_cfg & XDMAC_CC_DSYNC_Msk) == XDMAC_CC_DSYNC_MEM2PER) { + status->dir = MEMORY_TO_PERIPHERAL; + } else { + status->dir = PERIPHERAL_TO_MEMORY; + } + + status->busy = ((chan_cfg & XDMAC_CC_INITD_Msk) != 0) || (ublen > 0); + status->pending_length = ublen; + + return 0; +} + static const struct dma_driver_api sam_xdmac_driver_api = { .config = sam_xdmac_config, .reload = sam_xdmac_transfer_reload, .start = sam_xdmac_transfer_start, .stop = sam_xdmac_transfer_stop, + .get_status = sam_xdmac_get_status, }; /* DMA0 */ From 617c7cb337c1c1ef7d2362c894c55af7179aa0bd Mon Sep 17 00:00:00 2001 From: Keith Short Date: Wed, 19 Jul 2023 12:14:23 -0600 Subject: [PATCH 0162/4498] gpio: nct38xx: Cleanup semaphore usage Cleanup the semaphore usage in the NCT38xx GPIO driver. Signed-off-by: Keith Short --- drivers/gpio/gpio_nct38xx_port.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio_nct38xx_port.c b/drivers/gpio/gpio_nct38xx_port.c index 561e98842c9..07d3838d842 100644 --- a/drivers/gpio/gpio_nct38xx_port.c +++ b/drivers/gpio/gpio_nct38xx_port.c @@ -90,8 +90,7 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg); - k_sem_give(&data->lock); - return ret; + goto done; } /* Select open drain 0:push-pull 1:open-drain */ @@ -220,10 +219,17 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f static int gpio_nct38xx_port_get_raw(const struct device *dev, gpio_port_value_t *value) { + int ret; const struct gpio_nct38xx_port_config *const config = dev->config; + struct gpio_nct38xx_port_data *const data = dev->data; + + k_sem_take(&data->lock, K_FOREVER); + + ret = nct38xx_reg_read_byte(config->nct38xx_dev, + NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), (uint8_t *)value); - return nct38xx_reg_read_byte(config->nct38xx_dev, - NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), (uint8_t *)value); + k_sem_give(&data->lock); + return ret; } static int gpio_nct38xx_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, From ea40f3af24da508d4de2ed8fb23cb9af45e88360 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Wed, 19 Jul 2023 12:02:34 -0600 Subject: [PATCH 0163/4498] mfd: Add NCT38xx multi-function driver The Nuvoton NCT38xx is a multi-function device providing a TCPC controller and a I/O expander (GPIO driver). Add a multi-function driver to manage exclusive access to the device. Tested with "twister -T tests/drivers/build_all/gpio". Signed-off-by: Keith Short --- drivers/gpio/Kconfig.nct38xx | 17 ++- drivers/gpio/gpio_nct38xx.c | 54 +++++-- drivers/gpio/gpio_nct38xx.h | 104 ------------- drivers/gpio/gpio_nct38xx_alert.c | 1 + drivers/gpio/gpio_nct38xx_port.c | 143 +++++++++--------- drivers/mfd/CMakeLists.txt | 1 + drivers/mfd/Kconfig | 1 + drivers/mfd/Kconfig.nct38xx | 10 ++ drivers/mfd/mfd_nct38xx.c | 88 +++++++++++ .../gpio/nuvoton,nct38xx-gpio-alert.yaml | 4 +- dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml | 98 +++++++----- dts/bindings/mfd/nuvoton,nct38xx.yaml | 14 ++ include/zephyr/drivers/mfd/nct38xx.h | 91 +++++++++++ tests/drivers/build_all/gpio/app.overlay | 97 ++++++------ 14 files changed, 442 insertions(+), 281 deletions(-) create mode 100644 drivers/mfd/Kconfig.nct38xx create mode 100644 drivers/mfd/mfd_nct38xx.c create mode 100644 dts/bindings/mfd/nuvoton,nct38xx.yaml create mode 100644 include/zephyr/drivers/mfd/nct38xx.h diff --git a/drivers/gpio/Kconfig.nct38xx b/drivers/gpio/Kconfig.nct38xx index 3c4f396063b..25e91e3cf09 100644 --- a/drivers/gpio/Kconfig.nct38xx +++ b/drivers/gpio/Kconfig.nct38xx @@ -7,7 +7,8 @@ config GPIO_NCT38XX bool "NCT38XX I2C-based GPIO chip" default y depends on DT_HAS_NUVOTON_NCT38XX_GPIO_PORT_ENABLED - depends on I2C + select I2C + select MFD help Enable driver for NCT38XX I2C-based GPIO chip. @@ -15,17 +16,17 @@ if GPIO_NCT38XX config GPIO_NCT38XX_INIT_PRIORITY int "NCT38XX GPIO init priority" - default 51 + default 62 help - Device driver initialization priority. The priority should be lower - than I2C device. + NCT38xx GPIO driver initialization priority. The priority must be lower + than MFD_INIT_PRIORITY. config GPIO_NCT38XX_PORT_INIT_PRIORITY int "NCT38XX GPIO port init priority" - default 52 + default 64 help - Device driver initialization priority. The priority should be lower - than I2C & GPIO_NCT38XX_INIT_PRIORITY device. + NCT38xx GPIO port device driver initialization priority. The priority + must be lower than GPIO_NCT38XX_INIT_PRIORITY device. config GPIO_NCT38XX_ALERT bool "NCT38XX GPIO interrupt" @@ -36,7 +37,7 @@ config GPIO_NCT38XX_ALERT config GPIO_NCT38XX_ALERT_INIT_PRIORITY int "NCT38XX GPIO alert handler init priority" - default 52 + default 64 depends on GPIO_NCT38XX_ALERT help NCT38XX alert handler initialization priority. This initialization diff --git a/drivers/gpio/gpio_nct38xx.c b/drivers/gpio/gpio_nct38xx.c index 82c8663fe15..eb5412fce5c 100644 --- a/drivers/gpio/gpio_nct38xx.c +++ b/drivers/gpio/gpio_nct38xx.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,25 @@ #include LOG_MODULE_REGISTER(gpio_ntc38xx, CONFIG_GPIO_LOG_LEVEL); +/* Driver config */ +struct gpio_nct38xx_config { + /* Multi-function device, parent to the NCT38xx GPIO controller */ + const struct device *mfd; + /* GPIO ports */ + const struct device **sub_gpio_dev; + uint8_t sub_gpio_port_num; + /* Alert handler */ + const struct device *alert_dev; +}; + +/* Driver data */ +struct gpio_nct38xx_data { + /* NCT38XX device */ + const struct device *dev; + /* lock NCT38xx register access */ + struct k_sem *lock; +}; + void nct38xx_gpio_alert_handler(const struct device *dev) { const struct gpio_nct38xx_config *const config = dev->config; @@ -29,11 +49,16 @@ void nct38xx_gpio_alert_handler(const struct device *dev) static int nct38xx_init_interrupt(const struct device *dev) { uint16_t alert, alert_mask = 0; + int ret = 0; + struct gpio_nct38xx_data *data = dev->data; + + k_sem_take(data->lock, K_FOREVER); /* Disable all interrupt */ if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, sizeof(alert_mask))) { - return -EIO; + ret = -EIO; + goto unlock; } /* Enable vendor-defined alert for GPIO. */ @@ -41,34 +66,42 @@ static int nct38xx_init_interrupt(const struct device *dev) /* Clear alert */ if (nct38xx_reg_burst_read(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) { - return -EIO; + ret = -EIO; + goto unlock; } alert &= alert_mask; if (alert) { if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) { - return -EIO; + ret = -EIO; + goto unlock; } } if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, sizeof(alert_mask))) { - return -EIO; + ret = -EIO; + goto unlock; } - return 0; +unlock: + k_sem_give(data->lock); + return ret; } static int nct38xx_gpio_init(const struct device *dev) { const struct gpio_nct38xx_config *const config = dev->config; + struct gpio_nct38xx_data *data = dev->data; - /* Check I2C is ready */ - if (!device_is_ready(config->i2c_dev.bus)) { - LOG_ERR("%s device not ready", config->i2c_dev.bus->name); + /* Verify multi-function parent is ready */ + if (!device_is_ready(config->mfd)) { + LOG_ERR("%s device not ready", config->mfd->name); return -ENODEV; } + data->lock = mfd_nct38xx_get_lock_reference(config->mfd); + if (IS_ENABLED(CONFIG_GPIO_NCT38XX_ALERT)) { nct38xx_init_interrupt(dev); } @@ -81,7 +114,7 @@ static int nct38xx_gpio_init(const struct device *dev) DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, DEVICE_DT_GET, (,)) \ }; \ static const struct gpio_nct38xx_config gpio_nct38xx_cfg_##inst = { \ - .i2c_dev = I2C_DT_SPEC_INST_GET(inst), \ + .mfd = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ .sub_gpio_dev = sub_gpio_dev_##inst, \ .sub_gpio_port_num = ARRAY_SIZE(sub_gpio_dev_##inst), \ }; \ @@ -93,3 +126,6 @@ static int nct38xx_gpio_init(const struct device *dev) CONFIG_GPIO_NCT38XX_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(GPIO_NCT38XX_DEVICE_INSTANCE) + +/* The nct38xx MFD parent must be initialized before this driver */ +BUILD_ASSERT(CONFIG_GPIO_NCT38XX_INIT_PRIORITY > CONFIG_MFD_INIT_PRIORITY); diff --git a/drivers/gpio/gpio_nct38xx.h b/drivers/gpio/gpio_nct38xx.h index 78b7466f6bc..38032664566 100644 --- a/drivers/gpio/gpio_nct38xx.h +++ b/drivers/gpio/gpio_nct38xx.h @@ -31,110 +31,6 @@ #define NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT 15 #define NCT38XX_REG_ALERT_MASK_VENDOR_DEFINDED_ALERT 15 -/* Driver config */ -struct gpio_nct38xx_config { - /* I2C device */ - const struct i2c_dt_spec i2c_dev; - /* GPIO ports */ - const struct device **sub_gpio_dev; - uint8_t sub_gpio_port_num; - /* Alert handler */ - const struct device *alert_dev; -}; - -/* Driver data */ -struct gpio_nct38xx_data { - /* NCT38XX device */ - const struct device *dev; -}; - -/** - * @brief Read a NCT38XX register - * - * @param dev NCT38XX device - * @param reg_addr Register address - * @param val A pointer to a buffer for the data to return - * - * @return 0 if successful, otherwise failed. - */ -static inline int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val) -{ - const struct gpio_nct38xx_config *const config = - (const struct gpio_nct38xx_config *)dev->config; - return i2c_reg_read_byte_dt(&config->i2c_dev, reg_addr, val); -} - -/** - * @brief Read a sequence of NCT38XX registers - * - * @param dev NCT38XX device - * @param start_addr The register start address - * @param buf A pointer to a buffer for the data to return - * @param num_bytes Number of data to read - * - * @return 0 if successful, otherwise failed. - */ -static inline int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf, - uint32_t num_bytes) -{ - const struct gpio_nct38xx_config *const config = - (const struct gpio_nct38xx_config *)dev->config; - return i2c_burst_read_dt(&config->i2c_dev, start_addr, buf, num_bytes); -} - -/** - * @brief Write a NCT38XX register - * - * @param dev NCT38XX device - * @param reg_addr Register address - * @param val Data to write - * - * @return 0 if successful, otherwise failed. - */ -static inline int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val) -{ - const struct gpio_nct38xx_config *const config = - (const struct gpio_nct38xx_config *)dev->config; - return i2c_reg_write_byte_dt(&config->i2c_dev, reg_addr, val); -} - -/** - * @brief Write a sequence of NCT38XX registers - * - * @param dev NCT38XX device - * @param start_addr The register start address - * @param buf A pointer to a buffer for the data to write - * @param num_bytes Number of data to write - * - * @return 0 if successful, otherwise failed. - */ -static inline int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, - uint8_t *buf, uint32_t num_bytes) -{ - const struct gpio_nct38xx_config *const config = - (const struct gpio_nct38xx_config *)dev->config; - return i2c_burst_write_dt(&config->i2c_dev, start_addr, buf, num_bytes); -} - -/** - * @brief Compare data & write a NCT38XX register - * - * @param dev NCT38XX device - * @param reg_addr Register address - * @param reg_val Old register data - * @param new_val New register data - * - * @return 0 if successful, otherwise failed. - */ -static inline int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, - uint8_t new_val) -{ - if (reg_val == new_val) - return 0; - - return nct38xx_reg_write_byte(dev, reg_addr, new_val); -} - /** * @brief Dispatch GPIO port ISR * diff --git a/drivers/gpio/gpio_nct38xx_alert.c b/drivers/gpio/gpio_nct38xx_alert.c index 64ece947bd5..7b5a14b722d 100644 --- a/drivers/gpio/gpio_nct38xx_alert.c +++ b/drivers/gpio/gpio_nct38xx_alert.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpio/gpio_nct38xx_port.c b/drivers/gpio/gpio_nct38xx_port.c index 07d3838d842..d21d66734d6 100644 --- a/drivers/gpio/gpio_nct38xx_port.c +++ b/drivers/gpio/gpio_nct38xx_port.c @@ -8,8 +8,8 @@ #include "gpio_nct38xx.h" #include - #include +#include #include LOG_MODULE_DECLARE(gpio_ntc38xx, CONFIG_GPIO_LOG_LEVEL); @@ -18,7 +18,7 @@ struct gpio_nct38xx_port_config { /* gpio_driver_config needs to be first */ struct gpio_driver_config common; /* NCT38XX controller dev */ - const struct device *nct38xx_dev; + const struct device *mfd; /* GPIO port index */ uint8_t gpio_port; /* GPIO port 0 pinmux mask */ @@ -31,8 +31,8 @@ struct gpio_nct38xx_port_data { struct gpio_driver_data common; /* GPIO callback list */ sys_slist_t cb_list_gpio; - /* lock GPIO register access */ - struct k_sem lock; + /* lock NCT38xx register access */ + struct k_sem *lock; }; /* GPIO api functions */ @@ -59,11 +59,11 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi return -ENOTSUP; } - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); /* Pin multiplexing */ if (config->gpio_port == 0) { - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_MUX_CONTROL, ®); + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®); if (ret < 0) { goto done; } @@ -72,8 +72,7 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi /* NCT3807 bit3 must be set to 0 */ new_reg &= config->pinmux_mask; - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_MUX_CONTROL, reg, - new_reg); + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_MUX_CONTROL, reg, new_reg); if (ret < 0) { goto done; } @@ -81,20 +80,20 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi /* Configure pin as input. */ if (flags & GPIO_INPUT) { - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg); goto done; } /* Select open drain 0:push-pull 1:open-drain */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®); if (ret < 0) { goto done; @@ -104,14 +103,14 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi } else { new_reg = reg & ~mask; } - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), reg, new_reg); if (ret < 0) { goto done; } /* Set level 0:low 1:high */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { @@ -122,7 +121,7 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi } else if (flags & GPIO_OUTPUT_INIT_LOW) { new_reg = reg & ~mask; } - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), reg, new_reg); if (ret < 0) { goto done; @@ -130,18 +129,18 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi /* Configure pin as output, if requested 0:input 1:output */ if (flags & GPIO_OUTPUT) { - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg | mask; - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg); } done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -154,7 +153,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f uint8_t reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); if (config->gpio_port == 0) { if (mask & (~config->common.port_pin_mask)) { @@ -162,7 +161,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f goto done; } - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_MUX_CONTROL, ®); + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®); if (ret < 0) { goto done; } @@ -173,7 +172,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f } } - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); if (ret < 0) { goto done; @@ -184,7 +183,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f *flags = GPIO_OUTPUT; /* 0 - push-pull, 1 - open-drain */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®); if (ret < 0) { goto done; @@ -195,7 +194,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f } /* Output value */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { goto done; @@ -212,7 +211,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f } done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } #endif /* CONFIG_GPIO_GET_CONFIG */ @@ -223,12 +222,12 @@ static int gpio_nct38xx_port_get_raw(const struct device *dev, gpio_port_value_t const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), (uint8_t *)value); - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -240,19 +239,19 @@ static int gpio_nct38xx_port_set_masked_raw(const struct device *dev, gpio_port_ uint8_t reg, new_reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = ((reg & ~mask) | (value & mask)); - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), reg, new_reg); done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -264,19 +263,19 @@ static int gpio_nct38xx_port_set_bits_raw(const struct device *dev, gpio_port_pi uint8_t reg, new_reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg | mask; - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), reg, new_reg); done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -288,19 +287,19 @@ static int gpio_nct38xx_port_clear_bits_raw(const struct device *dev, gpio_port_ uint8_t reg, new_reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), reg, new_reg); done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -312,19 +311,19 @@ static int gpio_nct38xx_port_toggle_bits(const struct device *dev, gpio_port_pin uint8_t reg, new_reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ®); if (ret < 0) { goto done; } new_reg = reg ^ mask; - ret = nct38xx_reg_update(config->nct38xx_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), reg, new_reg); done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -338,16 +337,16 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p int ret; uint32_t mask = BIT(pin); - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); /* Disable irq before configuring them */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg); if (ret < 0) { goto done; @@ -359,12 +358,12 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p } /* set edge register */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), &rise); if (ret < 0) { goto done; } - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), &fall); if (ret < 0) { goto done; @@ -390,13 +389,13 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p new_fall = fall & ~mask; } - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), rise, new_rise); if (ret < 0) { goto done; } - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), fall, new_fall); if (ret < 0) { goto done; @@ -404,7 +403,7 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p if (mode == GPIO_INT_MODE_LEVEL) { /* set active high/low */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), ®); if (ret < 0) { goto done; @@ -419,7 +418,7 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p ret = -EINVAL; goto done; } - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), reg, new_reg); @@ -429,24 +428,24 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p } /* Clear pending bit */ - ret = nct38xx_reg_write_byte(config->nct38xx_dev, + ret = nct38xx_reg_write_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), mask); if (ret < 0) { goto done; } /* Enable it after configuration is completed */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®); if (ret < 0) { goto done; } new_reg = reg | mask; - ret = nct38xx_reg_update(config->nct38xx_dev, + ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg); done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } @@ -468,12 +467,12 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p uint8_t dir_reg; int ret; - k_sem_take(&data->lock, K_FOREVER); + k_sem_take(data->lock, K_FOREVER); if (config->gpio_port == 0) { uint8_t enabled_gpios; /* Remove the disabled GPIOs from the mask */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_MUX_CONTROL, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, &enabled_gpios); mask &= (enabled_gpios & config->common.port_pin_mask); @@ -483,7 +482,7 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p } /* Read direction register, 0 - input, 1 - output */ - ret = nct38xx_reg_read_byte(config->nct38xx_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), &dir_reg); if (ret < 0) { goto done; @@ -498,7 +497,7 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p } done: - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } #endif /* CONFIG_GPIO_GET_DIRECTION */ @@ -511,32 +510,32 @@ int gpio_nct38xx_dispatch_port_isr(const struct device *dev) int ret; do { - k_sem_take(&data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + k_sem_take(data->lock, K_FOREVER); + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), &alert_pins); if (ret < 0) { - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } - ret = nct38xx_reg_read_byte(config->nct38xx_dev, + ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), &mask); if (ret < 0) { - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } alert_pins &= mask; if (alert_pins) { - ret = nct38xx_reg_write_byte(config->nct38xx_dev, + ret = nct38xx_reg_write_byte(config->mfd, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), alert_pins); if (ret < 0) { - k_sem_give(&data->lock); + k_sem_give(data->lock); return ret; } } - k_sem_give(&data->lock); + k_sem_give(data->lock); gpio_fire_callbacks(&data->cb_list_gpio, dev, alert_pins); @@ -572,12 +571,12 @@ static int gpio_nct38xx_port_init(const struct device *dev) const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - if (!device_is_ready(config->nct38xx_dev)) { - LOG_ERR("%s is not ready", config->nct38xx_dev->name); + if (!device_is_ready(config->mfd)) { + LOG_ERR("%s is not ready", config->mfd->name); return -ENODEV; } - k_sem_init(&data->lock, 1, 1); + data->lock = mfd_nct38xx_get_lock_reference(config->mfd); return 0; } @@ -589,7 +588,7 @@ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_PORT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_P static const struct gpio_nct38xx_port_config gpio_nct38xx_port_cfg_##inst = { \ .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst) & \ DT_INST_PROP(inst, pin_mask)}, \ - .nct38xx_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .mfd = DEVICE_DT_GET(DT_INST_GPARENT(inst)), \ .gpio_port = DT_INST_REG_ADDR(inst), \ .pinmux_mask = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pinmux_mask), \ (DT_INST_PROP(inst, pinmux_mask)), (0)), \ diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index 0d27ef2c034..e8e59dd1692 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() +zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c) zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 114b78ad587..be84e348c04 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -19,6 +19,7 @@ config MFD_INIT_PRIORITY Multi-function devices initialization priority. source "drivers/mfd/Kconfig.axp192" +source "drivers/mfd/Kconfig.nct38xx" source "drivers/mfd/Kconfig.npm1300" source "drivers/mfd/Kconfig.npm6001" diff --git a/drivers/mfd/Kconfig.nct38xx b/drivers/mfd/Kconfig.nct38xx new file mode 100644 index 00000000000..aa852d974bb --- /dev/null +++ b/drivers/mfd/Kconfig.nct38xx @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Google, LLC +# SPDX -License-Identifier: Apache-2.0 + +config MFD_NCT38XX + bool "Nuvton NCT38xx multi-function device driver" + default y + depends on DT_HAS_NUVOTON_NCT38XX_ENABLED + select I2C + help + Enable the Nuvoton NCT38xx TCPC multi-function device driver. diff --git a/drivers/mfd/mfd_nct38xx.c b/drivers/mfd/mfd_nct38xx.c new file mode 100644 index 00000000000..ac5885fd46c --- /dev/null +++ b/drivers/mfd/mfd_nct38xx.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023 Google, LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_nct38xx + +#include + +struct mfd_nct38xx_config { + const struct i2c_dt_spec i2c_dev; +}; + +struct mfd_nct38xx_data { + /* lock NC38xx register access */ + struct k_sem lock; +}; + +static int mfd_nct38xx_init(const struct device *dev) +{ + const struct mfd_nct38xx_config *config = dev->config; + struct mfd_nct38xx_data *data = dev->data; + + if (!device_is_ready(config->i2c_dev.bus)) { + return -ENODEV; + } + + k_sem_init(&data->lock, 1, 1); + + return 0; +} + +struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev) +{ + struct mfd_nct38xx_data *data = dev->data; + + return &data->lock; +} + +int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val) +{ + const struct mfd_nct38xx_config *const config = dev->config; + + return i2c_reg_read_byte_dt(&config->i2c_dev, reg_addr, val); +} + +int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf, + uint32_t num_bytes) +{ + const struct mfd_nct38xx_config *const config = dev->config; + + return i2c_burst_read_dt(&config->i2c_dev, start_addr, buf, num_bytes); +} + +int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val) +{ + const struct mfd_nct38xx_config *const config = dev->config; + + return i2c_reg_write_byte_dt(&config->i2c_dev, reg_addr, val); +} + +int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf, + uint32_t num_bytes) +{ + const struct mfd_nct38xx_config *const config = dev->config; + + return i2c_burst_write_dt(&config->i2c_dev, start_addr, buf, num_bytes); +} + +int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, uint8_t new_val) +{ + if (reg_val == new_val) { + return 0; + } + + return nct38xx_reg_write_byte(dev, reg_addr, new_val); +} + +#define MFD_NCT38XX_DEFINE(inst) \ + static struct mfd_nct38xx_data nct38xx_data_##inst; \ + static const struct mfd_nct38xx_config nct38xx_cfg_##inst = { \ + .i2c_dev = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfd_nct38xx_init, NULL, &nct38xx_data_##inst, \ + &nct38xx_cfg_##inst, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_NCT38XX_DEFINE) diff --git a/dts/bindings/gpio/nuvoton,nct38xx-gpio-alert.yaml b/dts/bindings/gpio/nuvoton,nct38xx-gpio-alert.yaml index c6043983b28..4cae0a79eb2 100644 --- a/dts/bindings/gpio/nuvoton,nct38xx-gpio-alert.yaml +++ b/dts/bindings/gpio/nuvoton,nct38xx-gpio-alert.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Nuvoton NCT38XX series I2C-based GPIO expander alert handler + Nuvoton NCT38XX series I2C-based GPIO expander alert handler. Example: nct3807_alert_1 { @@ -25,4 +25,4 @@ properties: type: phandles required: true description: | - NCT38XX devices which alert are handled by this alert handler. + List of NCT38XX multi-function devices managed by this alert handler. diff --git a/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml b/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml index 5f704e768da..5b9afbbc892 100644 --- a/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml +++ b/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml @@ -4,69 +4,83 @@ description: | Nuvoton NCT38XX series I2C-based GPIO expander + This must be a child of the NCT38xx multi-function device. + Example: &i2c0_0 { nct3807@70 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + compatible = "nuvoton,nct38xx"; reg = <0x70>; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xff>; - pinmux_mask = <0xf7>; - }; + nct3807-gpio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; + + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xff>; + pinmux_mask = <0xf7>; + }; - gpio@1 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x1>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xff>; + gpio@1 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xff>; + }; }; }; nct3808_0_P1@71 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + compatible = "nuvoton,nct38xx"; reg = <0x71>; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + nct3808-0-p1-gpio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; + + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xdc>; + pinmux_mask = <0xff>; + }; }; }; nct3808_0_P2@75 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + compatible = "nuvoton,nct38xx"; reg = <0x75>; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + nct3808-0-P2-gpio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; + + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xdc>; + pinmux_mask = <0xff>; + }; }; }; }; compatible: "nuvoton,nct38xx-gpio" -include: [i2c-device.yaml] +include: [base.yaml] diff --git a/dts/bindings/mfd/nuvoton,nct38xx.yaml b/dts/bindings/mfd/nuvoton,nct38xx.yaml new file mode 100644 index 00000000000..ea1e250b4d7 --- /dev/null +++ b/dts/bindings/mfd/nuvoton,nct38xx.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023, Google, LLC +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nuvoton NCT38xx multi-function device + + The NCT38xx provides a TCPC and an I/O Expander capabilities. + + The TCPC and I/O expander drivers are added to the devicetree + as children of the nuvoton,nct38xx device. + +compatible: "nuvoton,nct38xx" + +include: i2c-device.yaml diff --git a/include/zephyr/drivers/mfd/nct38xx.h b/include/zephyr/drivers/mfd/nct38xx.h new file mode 100644 index 00000000000..2ea4513c281 --- /dev/null +++ b/include/zephyr/drivers/mfd/nct38xx.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 Google, LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_NCT38XX_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_NCT38XX_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get the semaphore reference for a NCT38xx instance. Callers + * should pass the return value to k_sem_take/k_sem_give + * + * @param[in] dev Pointer to device struct of the driver instance + * + * @return Address of the semaphore + */ +struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev); + +/** + * @brief Read a NCT38XX register + * + * @param dev NCT38XX multi-function device + * @param reg_addr Register address + * @param val A pointer to a buffer for the data to return + * + * @return 0 if successful, otherwise failed. + */ +int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val); + +/** + * @brief Read a sequence of NCT38XX registers + * + * @param dev NCT38XX multi-function device + * @param start_addr The register start address + * @param buf A pointer to a buffer for the data to return + * @param num_bytes Number of data to read + * + * @return 0 if successful, otherwise failed. + */ +int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf, + uint32_t num_bytes); + +/** + * @brief Write a NCT38XX register + * + * @param dev NCT38XX device + * @param reg_addr Register address + * @param val Data to write + * + * @return 0 if successful, otherwise failed. + */ +int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val); + +/** + * @brief Write a sequence of NCT38XX registers + * + * @param dev NCT38XX device + * @param start_addr The register start address + * @param buf A pointer to a buffer for the data to write + * @param num_bytes Number of data to write + * + * @return 0 if successful, otherwise failed. + */ +int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf, + uint32_t num_bytes); + +/** + * @brief Compare data & write a NCT38XX register + * + * @param dev NCT38XX device + * @param reg_addr Register address + * @param reg_val Old register data + * @param new_val New register data + * + * @return 0 if successful, otherwise failed. + */ +int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, + uint8_t new_val); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_NCT38XX_H_ */ diff --git a/tests/drivers/build_all/gpio/app.overlay b/tests/drivers/build_all/gpio/app.overlay index 2fd3bdc2597..10eea2e04e0 100644 --- a/tests/drivers/build_all/gpio/app.overlay +++ b/tests/drivers/build_all/gpio/app.overlay @@ -103,63 +103,72 @@ gpio-controller; }; - test_i2c_nct3807: nct3807@72 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + mfd-nct38xx@72 { + compatible = "nuvoton,nct38xx"; reg = <0x72>; + test_i2c_nct3807: nct3807 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xff>; - pinmux_mask = <0xf7>; - }; + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xff>; + pinmux_mask = <0xf7>; + }; - gpio@1 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x1>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xff>; + gpio@1 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xff>; + }; }; }; - test_i2c_nct3808_p1: nct3808_0_P1@71 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + test_i2c_nct3808_p1: mfd-nct38xx@71 { + compatible = "nuvoton,nct38xx"; reg = <0x71>; + nct3808_0_P1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xdc>; + pinmux_mask = <0xff>; + }; }; }; - test_i2c_nct3808_p2: nct3808_0_P2@75 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nuvoton,nct38xx-gpio"; + test_i2c_nct3808_p2: mfd-nct38xx@75 { + compatible = "nuvoton,nct38xx"; reg = <0x75>; + nct3808_0_P2 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; - gpio@0 { - compatible = "nuvoton,nct38xx-gpio-port"; - reg = <0x0>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xdc>; + pinmux_mask = <0xff>; + }; }; }; From c9f822df2712e0228e3a7b1ae944e04328a38ccc Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 11 Aug 2023 13:50:26 -0600 Subject: [PATCH 0164/4498] gpio: nct38xx: Remove reg access wrappers Remove the register access wrappers used to read/write the NCT38xx register space. Signed-off-by: Keith Short --- drivers/gpio/gpio_nct38xx.c | 17 +- drivers/gpio/gpio_nct38xx_alert.c | 83 ++++++--- drivers/gpio/gpio_nct38xx_port.c | 242 ++++++++++----------------- drivers/mfd/mfd_nct38xx.c | 38 +---- include/zephyr/drivers/mfd/nct38xx.h | 61 +------ 5 files changed, 161 insertions(+), 280 deletions(-) diff --git a/drivers/gpio/gpio_nct38xx.c b/drivers/gpio/gpio_nct38xx.c index eb5412fce5c..a4949f1f9bb 100644 --- a/drivers/gpio/gpio_nct38xx.c +++ b/drivers/gpio/gpio_nct38xx.c @@ -35,6 +35,8 @@ struct gpio_nct38xx_data { const struct device *dev; /* lock NCT38xx register access */ struct k_sem *lock; + /* I2C device for the MFD parent */ + const struct i2c_dt_spec *i2c_dev; }; void nct38xx_gpio_alert_handler(const struct device *dev) @@ -55,8 +57,8 @@ static int nct38xx_init_interrupt(const struct device *dev) k_sem_take(data->lock, K_FOREVER); /* Disable all interrupt */ - if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, - sizeof(alert_mask))) { + if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, + sizeof(alert_mask))) { ret = -EIO; goto unlock; } @@ -65,21 +67,21 @@ static int nct38xx_init_interrupt(const struct device *dev) alert_mask |= BIT(NCT38XX_REG_ALERT_MASK_VENDOR_DEFINDED_ALERT); /* Clear alert */ - if (nct38xx_reg_burst_read(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) { + if (i2c_burst_read_dt(data->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) { ret = -EIO; goto unlock; } alert &= alert_mask; if (alert) { - if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, - sizeof(alert))) { + if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, + sizeof(alert))) { ret = -EIO; goto unlock; } } - if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, - sizeof(alert_mask))) { + if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask, + sizeof(alert_mask))) { ret = -EIO; goto unlock; } @@ -101,6 +103,7 @@ static int nct38xx_gpio_init(const struct device *dev) } data->lock = mfd_nct38xx_get_lock_reference(config->mfd); + data->i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->mfd); if (IS_ENABLED(CONFIG_GPIO_NCT38XX_ALERT)) { nct38xx_init_interrupt(dev); diff --git a/drivers/gpio/gpio_nct38xx_alert.c b/drivers/gpio/gpio_nct38xx_alert.c index 7b5a14b722d..eb52339364a 100644 --- a/drivers/gpio/gpio_nct38xx_alert.c +++ b/drivers/gpio/gpio_nct38xx_alert.c @@ -18,6 +18,13 @@ #include LOG_MODULE_DECLARE(gpio_ntc38xx, CONFIG_GPIO_LOG_LEVEL); +struct nct38xx_mfd { + /* Lock for NCT38xx register access */ + struct k_sem *lock; + /* I2C device used for register access */ + const struct i2c_dt_spec *i2c_dev; +}; + /* Driver config */ struct nct38xx_alert_config { /* Alert GPIO pin */ @@ -36,6 +43,8 @@ struct nct38xx_alert_data { struct gpio_callback gpio_cb; /* Alert worker */ struct k_work alert_worker; + /* Lock for NCT38xx register access */ + struct nct38xx_mfd *mfd; }; static void nct38xx_alert_callback(const struct device *dev, struct gpio_callback *cb, @@ -47,39 +56,58 @@ static void nct38xx_alert_callback(const struct device *dev, struct gpio_callbac k_work_submit(&data->alert_worker); } +static bool nct38xx_alert_is_active(struct nct38xx_mfd *mfd) +{ + int ret; + uint16_t alert, mask; + + k_sem_take(mfd->lock, K_FOREVER); + + /* Clear alert */ + ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, + sizeof(alert)); + if (ret < 0) { + goto release_lock; + } + ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT_MASK, + (uint8_t *)&mask, sizeof(mask)); + if (ret < 0) { + goto release_lock; + } + + alert &= mask; + if (alert) { + ret = i2c_burst_write_dt(mfd->i2c_dev, NCT38XX_REG_ALERT, + (uint8_t *)&alert, sizeof(alert)); + } + +release_lock: + k_sem_give(mfd->lock); + + if (ret < 0) { + LOG_ERR("i2c access failed"); + return false; + } + + if (alert & BIT(NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT)) { + return true; + } + + return false; +} + static void nct38xx_alert_worker(struct k_work *work) { struct nct38xx_alert_data *const data = CONTAINER_OF(work, struct nct38xx_alert_data, alert_worker); const struct nct38xx_alert_config *const config = data->alert_dev->config; - uint16_t alert, mask; do { /* NCT38XX device handler */ for (int i = 0; i < config->nct38xx_num; i++) { - /* Clear alert */ - if (nct38xx_reg_burst_read(config->nct38xx_dev[i], NCT38XX_REG_ALERT, - (uint8_t *)&alert, sizeof(alert))) { - LOG_ERR("i2c access failed"); - return; - } - if (nct38xx_reg_burst_read(config->nct38xx_dev[i], NCT38XX_REG_ALERT_MASK, - (uint8_t *)&mask, sizeof(mask))) { - LOG_ERR("i2c access failed"); - return; - } + struct nct38xx_mfd *mfd = &data->mfd[i]; - alert &= mask; - if (alert) { - if (nct38xx_reg_burst_write(config->nct38xx_dev[i], - NCT38XX_REG_ALERT, (uint8_t *)&alert, - sizeof(alert))) { - LOG_ERR("i2c access failed"); - return; - } - } - - if (alert & BIT(NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT)) { + if (nct38xx_alert_is_active(mfd)) { nct38xx_gpio_alert_handler(config->nct38xx_dev[i]); } } @@ -99,6 +127,9 @@ static int nct38xx_alert_init(const struct device *dev) LOG_ERR("%s device not ready", config->nct38xx_dev[i]->name); return -ENODEV; } + + data->mfd[i].lock = mfd_nct38xx_get_lock_reference(config->nct38xx_dev[i]); + data->mfd[i].i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->nct38xx_dev[i]); } /* Set the alert pin for handling the interrupt */ @@ -130,8 +161,9 @@ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_ DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), #define NCT38XX_ALERT_DEVICE_INSTANCE(inst) \ - const struct device *nct38xx_dev_##inst[] = { DT_INST_FOREACH_PROP_ELEM( \ - inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA) }; \ + const struct device *nct38xx_dev_##inst[] = { \ + DT_INST_FOREACH_PROP_ELEM(inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA)}; \ + static struct nct38xx_mfd nct38xx_mfd_##inst[DT_INST_PROP_LEN(inst, nct38xx_dev)]; \ static const struct nct38xx_alert_config nct38xx_alert_cfg_##inst = { \ .irq_gpio = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \ .nct38xx_dev = &nct38xx_dev_##inst[0], \ @@ -139,6 +171,7 @@ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_ }; \ static struct nct38xx_alert_data nct38xx_alert_data_##inst = { \ .alert_dev = DEVICE_DT_INST_GET(inst), \ + .mfd = nct38xx_mfd_##inst, \ }; \ DEVICE_DT_INST_DEFINE(inst, nct38xx_alert_init, NULL, &nct38xx_alert_data_##inst, \ &nct38xx_alert_cfg_##inst, POST_KERNEL, \ diff --git a/drivers/gpio/gpio_nct38xx_port.c b/drivers/gpio/gpio_nct38xx_port.c index d21d66734d6..32d70808fcd 100644 --- a/drivers/gpio/gpio_nct38xx_port.c +++ b/drivers/gpio/gpio_nct38xx_port.c @@ -33,6 +33,8 @@ struct gpio_nct38xx_port_data { sys_slist_t cb_list_gpio; /* lock NCT38xx register access */ struct k_sem *lock; + /* I2C device for the MFD parent */ + const struct i2c_dt_spec *i2c_dev; }; /* GPIO api functions */ @@ -40,8 +42,8 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi { const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - uint32_t mask = BIT(pin); - uint8_t reg, new_reg; + uint32_t mask; + uint8_t new_reg; int ret; /* Don't support simultaneous in/out mode */ @@ -63,16 +65,14 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi /* Pin multiplexing */ if (config->gpio_port == 0) { - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®); - if (ret < 0) { - goto done; - } - - new_reg = reg | mask; - /* NCT3807 bit3 must be set to 0 */ - new_reg &= config->pinmux_mask; + /* Set the mux control bit, but ensure the reserved fields + * are cleared. Note that pinmux_mask contains the set + * of non-reserved bits. + */ + new_reg = BIT(pin) & config->pinmux_mask; + mask = BIT(pin) | ~config->pinmux_mask; - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_MUX_CONTROL, reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, mask, new_reg); if (ret < 0) { goto done; } @@ -80,63 +80,45 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi /* Configure pin as input. */ if (flags & GPIO_INPUT) { - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg); + /* Clear the direction bit to set as an input */ + new_reg = 0; + mask = BIT(pin); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), + mask, new_reg); goto done; } /* Select open drain 0:push-pull 1:open-drain */ - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), - ®); - if (ret < 0) { - goto done; - } + mask = BIT(pin); if (flags & GPIO_OPEN_DRAIN) { - new_reg = reg | mask; + new_reg = mask; } else { - new_reg = reg & ~mask; + new_reg = 0; } - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), - reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), + mask, new_reg); if (ret < 0) { goto done; } /* Set level 0:low 1:high */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - ®); - if (ret < 0) { - goto done; - } if (flags & GPIO_OUTPUT_INIT_HIGH) { - new_reg = reg | mask; + new_reg = mask; } else if (flags & GPIO_OUTPUT_INIT_LOW) { - new_reg = reg & ~mask; + new_reg = 0; } - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + mask, new_reg); if (ret < 0) { goto done; } /* Configure pin as output, if requested 0:input 1:output */ if (flags & GPIO_OUTPUT) { - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg | mask; - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg); + new_reg = BIT(pin); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), + mask, new_reg); } done: @@ -161,7 +143,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f goto done; } - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, ®); if (ret < 0) { goto done; } @@ -172,8 +154,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f } } - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), - ®); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), ®); if (ret < 0) { goto done; } @@ -183,8 +164,8 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f *flags = GPIO_OUTPUT; /* 0 - push-pull, 1 - open-drain */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®); + ret = i2c_reg_read_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®); if (ret < 0) { goto done; } @@ -194,8 +175,8 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f } /* Output value */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); + ret = i2c_reg_read_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); if (ret < 0) { goto done; } @@ -224,8 +205,8 @@ static int gpio_nct38xx_port_get_raw(const struct device *dev, gpio_port_value_t k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), (uint8_t *)value); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), + (uint8_t *)value); k_sem_give(data->lock); return ret; @@ -236,21 +217,13 @@ static int gpio_nct38xx_port_set_masked_raw(const struct device *dev, gpio_port_ { const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - uint8_t reg, new_reg; int ret; k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = ((reg & ~mask) | (value & mask)); - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + mask, value); -done: k_sem_give(data->lock); return ret; @@ -260,21 +233,13 @@ static int gpio_nct38xx_port_set_bits_raw(const struct device *dev, gpio_port_pi { const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - uint8_t reg, new_reg; int ret; k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg | mask; - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + mask, mask); -done: k_sem_give(data->lock); return ret; @@ -284,21 +249,13 @@ static int gpio_nct38xx_port_clear_bits_raw(const struct device *dev, gpio_port_ { const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - uint8_t reg, new_reg; int ret; k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - reg, new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + mask, 0); -done: k_sem_give(data->lock); return ret; @@ -313,14 +270,16 @@ static int gpio_nct38xx_port_toggle_bits(const struct device *dev, gpio_port_pin k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - ®); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), + ®); if (ret < 0) { goto done; } new_reg = reg ^ mask; - ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), - reg, new_reg); + if (new_reg != reg) { + ret = i2c_reg_write_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), new_reg); + } done: k_sem_give(data->lock); @@ -333,24 +292,16 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p { const struct gpio_nct38xx_port_config *const config = dev->config; struct gpio_nct38xx_port_data *const data = dev->data; - uint8_t reg, new_reg, rise, new_rise, fall, new_fall; + uint8_t new_reg, new_rise, new_fall; int ret; uint32_t mask = BIT(pin); k_sem_take(data->lock, K_FOREVER); /* Disable irq before configuring them */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg & ~mask; - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg); - if (ret < 0) { - goto done; - } + new_reg = 0; + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), + mask, new_reg); /* Configure and enable interrupt? */ if (mode == GPIO_INT_MODE_DISABLED) { @@ -358,69 +309,52 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p } /* set edge register */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), &rise); - if (ret < 0) { - goto done; - } - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), &fall); - if (ret < 0) { - goto done; - } - if (mode == GPIO_INT_MODE_EDGE) { if (trig == GPIO_INT_TRIG_LOW) { - new_rise = rise & ~mask; - new_fall = fall | mask; + new_rise = 0; + new_fall = mask; } else if (trig == GPIO_INT_TRIG_HIGH) { - new_rise = rise | mask; - new_fall = fall & ~mask; + new_rise = mask; + new_fall = 0; } else if (trig == GPIO_INT_TRIG_BOTH) { - new_rise = rise | mask; - new_fall = fall | mask; + new_rise = mask; + new_fall = mask; } else { LOG_ERR("Invalid interrupt trigger type %d", trig); return -EINVAL; } } else { /* level mode */ - new_rise = rise & ~mask; - new_fall = fall & ~mask; + new_rise = 0; + new_fall = 0; } - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), rise, new_rise); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), + mask, new_rise); if (ret < 0) { goto done; } - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), fall, new_fall); + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), + mask, new_fall); if (ret < 0) { goto done; } if (mode == GPIO_INT_MODE_LEVEL) { /* set active high/low */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - if (trig == GPIO_INT_TRIG_LOW) { - new_reg = reg & ~mask; + new_reg = 0; } else if (trig == GPIO_INT_TRIG_HIGH) { - new_reg = reg | mask; + new_reg = mask; } else { LOG_ERR("Invalid interrupt trigger type %d", trig); ret = -EINVAL; goto done; } - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), reg, - new_reg); + ret = i2c_reg_update_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), mask, + new_reg); if (ret < 0) { goto done; @@ -428,21 +362,16 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p } /* Clear pending bit */ - ret = nct38xx_reg_write_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), mask); + ret = i2c_reg_write_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), + mask); if (ret < 0) { goto done; } /* Enable it after configuration is completed */ - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®); - if (ret < 0) { - goto done; - } - new_reg = reg | mask; - ret = nct38xx_reg_update(config->mfd, - NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg); + new_reg = mask; + ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), + mask, new_reg); done: k_sem_give(data->lock); @@ -472,8 +401,7 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p if (config->gpio_port == 0) { uint8_t enabled_gpios; /* Remove the disabled GPIOs from the mask */ - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, - &enabled_gpios); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, &enabled_gpios); mask &= (enabled_gpios & config->common.port_pin_mask); if (ret < 0) { @@ -482,8 +410,8 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p } /* Read direction register, 0 - input, 1 - output */ - ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port), - &dir_reg); + ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), + &dir_reg); if (ret < 0) { goto done; } @@ -511,25 +439,24 @@ int gpio_nct38xx_dispatch_port_isr(const struct device *dev) do { k_sem_take(data->lock, K_FOREVER); - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), - &alert_pins); + ret = i2c_reg_read_byte_dt( + data->i2c_dev, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), &alert_pins); if (ret < 0) { k_sem_give(data->lock); return ret; } - ret = nct38xx_reg_read_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), &mask); + ret = i2c_reg_read_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), &mask); if (ret < 0) { k_sem_give(data->lock); return ret; } alert_pins &= mask; if (alert_pins) { - ret = nct38xx_reg_write_byte(config->mfd, - NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), - alert_pins); + ret = i2c_reg_write_byte_dt(data->i2c_dev, + NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), + alert_pins); if (ret < 0) { k_sem_give(data->lock); return ret; @@ -577,6 +504,7 @@ static int gpio_nct38xx_port_init(const struct device *dev) } data->lock = mfd_nct38xx_get_lock_reference(config->mfd); + data->i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->mfd); return 0; } diff --git a/drivers/mfd/mfd_nct38xx.c b/drivers/mfd/mfd_nct38xx.c index ac5885fd46c..81b6ece4d1a 100644 --- a/drivers/mfd/mfd_nct38xx.c +++ b/drivers/mfd/mfd_nct38xx.c @@ -37,43 +37,11 @@ struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev) return &data->lock; } -int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val) +const struct i2c_dt_spec *mfd_nct38xx_get_i2c_dt_spec(const struct device *dev) { - const struct mfd_nct38xx_config *const config = dev->config; - - return i2c_reg_read_byte_dt(&config->i2c_dev, reg_addr, val); -} - -int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf, - uint32_t num_bytes) -{ - const struct mfd_nct38xx_config *const config = dev->config; - - return i2c_burst_read_dt(&config->i2c_dev, start_addr, buf, num_bytes); -} - -int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val) -{ - const struct mfd_nct38xx_config *const config = dev->config; - - return i2c_reg_write_byte_dt(&config->i2c_dev, reg_addr, val); -} - -int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf, - uint32_t num_bytes) -{ - const struct mfd_nct38xx_config *const config = dev->config; - - return i2c_burst_write_dt(&config->i2c_dev, start_addr, buf, num_bytes); -} - -int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, uint8_t new_val) -{ - if (reg_val == new_val) { - return 0; - } + const struct mfd_nct38xx_config *config = dev->config; - return nct38xx_reg_write_byte(dev, reg_addr, new_val); + return &config->i2c_dev; } #define MFD_NCT38XX_DEFINE(inst) \ diff --git a/include/zephyr/drivers/mfd/nct38xx.h b/include/zephyr/drivers/mfd/nct38xx.h index 2ea4513c281..40e1a87fc26 100644 --- a/include/zephyr/drivers/mfd/nct38xx.h +++ b/include/zephyr/drivers/mfd/nct38xx.h @@ -7,6 +7,7 @@ #define ZEPHYR_INCLUDE_DRIVERS_MFD_NCT38XX_H_ #include +#include #include #ifdef __cplusplus @@ -24,65 +25,13 @@ extern "C" { struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev); /** - * @brief Read a NCT38XX register + * @brief Get the I2C DT spec reference for a NCT38xx instance. * - * @param dev NCT38XX multi-function device - * @param reg_addr Register address - * @param val A pointer to a buffer for the data to return - * - * @return 0 if successful, otherwise failed. - */ -int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val); - -/** - * @brief Read a sequence of NCT38XX registers - * - * @param dev NCT38XX multi-function device - * @param start_addr The register start address - * @param buf A pointer to a buffer for the data to return - * @param num_bytes Number of data to read - * - * @return 0 if successful, otherwise failed. - */ -int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf, - uint32_t num_bytes); - -/** - * @brief Write a NCT38XX register - * - * @param dev NCT38XX device - * @param reg_addr Register address - * @param val Data to write - * - * @return 0 if successful, otherwise failed. - */ -int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val); - -/** - * @brief Write a sequence of NCT38XX registers - * - * @param dev NCT38XX device - * @param start_addr The register start address - * @param buf A pointer to a buffer for the data to write - * @param num_bytes Number of data to write - * - * @return 0 if successful, otherwise failed. - */ -int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf, - uint32_t num_bytes); - -/** - * @brief Compare data & write a NCT38XX register - * - * @param dev NCT38XX device - * @param reg_addr Register address - * @param reg_val Old register data - * @param new_val New register data + * @param[in] dev Pointer to device struct of the driver instance * - * @return 0 if successful, otherwise failed. + * @return Address of the I2C DT spec */ -int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, - uint8_t new_val); +const struct i2c_dt_spec *mfd_nct38xx_get_i2c_dt_spec(const struct device *dev); #ifdef __cplusplus } From 22db117052a5da813b175878be63d7047badba2f Mon Sep 17 00:00:00 2001 From: Chuang Zhu Date: Mon, 21 Aug 2023 07:12:40 +0800 Subject: [PATCH 0165/4498] boards: msp_exp432p401r_launchxl: Use OpenOCD UniFlash is no longer required for flashing MSP-EXP432P401R, as long as the XDS110 firmware is updated. The updated documentation is based on CC3220SF-LAUNCHXL's. Signed-off-by: Chuang Zhu --- .../arm/msp_exp432p401r_launchxl/board.cmake | 3 + .../msp_exp432p401r_launchxl/doc/index.rst | 76 ++++++++++++++----- .../msp_exp432p401r_launchxl_defconfig | 1 + .../support/MSP432P401R.ccxml | 16 ---- .../support/openocd.cfg | 3 + 5 files changed, 63 insertions(+), 36 deletions(-) create mode 100644 boards/arm/msp_exp432p401r_launchxl/board.cmake delete mode 100644 boards/arm/msp_exp432p401r_launchxl/support/MSP432P401R.ccxml create mode 100644 boards/arm/msp_exp432p401r_launchxl/support/openocd.cfg diff --git a/boards/arm/msp_exp432p401r_launchxl/board.cmake b/boards/arm/msp_exp432p401r_launchxl/board.cmake new file mode 100644 index 00000000000..cbeaea2e456 --- /dev/null +++ b/boards/arm/msp_exp432p401r_launchxl/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/msp_exp432p401r_launchxl/doc/index.rst b/boards/arm/msp_exp432p401r_launchxl/doc/index.rst index 709adee2f08..462aeb04de0 100644 --- a/boards/arm/msp_exp432p401r_launchxl/doc/index.rst +++ b/boards/arm/msp_exp432p401r_launchxl/doc/index.rst @@ -55,47 +55,80 @@ Other hardware features are not currently supported by the Zephyr kernel. Building and Flashing ********************* -Building +Prerequisites: +============== + +#. Ensure the XDS-110 emulation firmware is updated. + + Download and install the latest `XDS-110 emulation package`_. + + Follow these `xds110 firmware update directions + `_ + + Note that the emulation package install may place the xdsdfu utility + in ``/ccs_base/common/uscif/xds110/``. + +#. Install OpenOCD + + You can obtain OpenOCD by following these + :ref:`installing the latest Zephyr SDK instructions `. + + After the installation, add the directory containing the OpenOCD executable + to your environment's PATH variable. For example, use this command in Linux: + + .. code-block:: console + + export PATH=$ZEPHYR_SDK_INSTALL_DIR/sysroots/x86_64-pokysdk-linux/usr/bin/openocd:$PATH + + If you had previously installed TI OpenOCD, you can simply switch to use + the one in the Zephyr SDK. If for some reason you wish to continue to use + your TI OpenOCD installation, you can set the OPENOCD and + OPENOCD_DEFAULT_PATH variables in + :zephyr_file:`boards/arm/msp_exp432p401r_launchxl/board.cmake` to point the build + to the paths of the OpenOCD binary and its scripts, before + including the common openocd.board.cmake file: + + .. code-block:: none + + set(OPENOCD "/usr/local/bin/openocd" CACHE FILEPATH "" FORCE) + set(OPENOCD_DEFAULT_PATH /usr/local/share/openocd/scripts) + include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +Flashing ======== Follow the :ref:`getting_started` instructions for Zephyr application development. -For example, to build the :ref:`hello_world` application for the +For example, to build and flash the :ref:`hello_world` application for the MSP-EXP432P401R LaunchXL: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: msp_exp432p401r_launchxl - :goals: build - -The resulting ``zephyr.elf`` binary in the build directory can be flashed onto -MSP-EXP432P401R LaunchXL using the command line utility mentioned below. - -Flashing -======== + :goals: flash -For Linux: ----------- +This will load the image into flash. -`UniFlash`_ command line utility is used to program the flash memory. Only -elf loading is currently supported. - -The following command will flash the ``zephyr.elf`` binary to the MSP-EXP432P401R LaunchXL board: +To see program output from UART0, connect a separate terminal window: .. code-block:: console - $ ./dslite.sh --config=MSP432P401R.ccxml zephyr.elf + % screen /dev/ttyACM0 115200 8N1 -.. note:: The ccxml configuration file is included in boards/arm/msp_exp432p401r_launchxl/support. +Then press the reset button (S3) on the board to run the program. Debugging ========= -MSP-EXP432P401R LaunchXL board supports debugging primarily using `CCS IDE`_. More information -on debugging using CCS can be found in CCS Debug Handbook. +To debug a previously flashed image, after resetting the board, use the 'debug' +build target: -Launchpad also supports debugging using GDB. See section 3.3 of GCC ARM Toolchain Guide. +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: msp_exp432p401r_launchxl + :maybe-skip-config: + :goals: debug References ********** @@ -114,3 +147,6 @@ TI MSP432 SDK: .. _CCS IDE: http://www.ti.com/tool/ccstudio + +.. _XDS-110 emulation package: + http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS_Emulation_Software_.28emupack.29_Download diff --git a/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl_defconfig b/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl_defconfig index a71dce228eb..01559c8be94 100644 --- a/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl_defconfig +++ b/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl_defconfig @@ -3,6 +3,7 @@ CONFIG_BOARD_MSP_EXP432P401R_LAUNCHXL=y CONFIG_SOC_SERIES_MSP432P4XX=y CONFIG_SOC_MSP432P401R=y +CONFIG_BUILD_OUTPUT_HEX=y # Floating point options CONFIG_FPU=y diff --git a/boards/arm/msp_exp432p401r_launchxl/support/MSP432P401R.ccxml b/boards/arm/msp_exp432p401r_launchxl/support/MSP432P401R.ccxml deleted file mode 100644 index 331f741ae83..00000000000 --- a/boards/arm/msp_exp432p401r_launchxl/support/MSP432P401R.ccxml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/boards/arm/msp_exp432p401r_launchxl/support/openocd.cfg b/boards/arm/msp_exp432p401r_launchxl/support/openocd.cfg new file mode 100644 index 00000000000..d28491faa51 --- /dev/null +++ b/boards/arm/msp_exp432p401r_launchxl/support/openocd.cfg @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +source [find board/ti_msp432_launchpad.cfg] From 24eb2ee80aae4bcaaed445e804aad1c07f8f77f5 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Thu, 24 Aug 2023 06:55:29 +0200 Subject: [PATCH 0166/4498] boards: M5Stack Core2 module suppport This Pull-Request enables support for the M5Stack Core2 hardware. The module features a LCD display, touchscreen, battery, USB-Port, 8MB RAM and 16MB Flash. Basic features are working. Please refere to the board documentation for details. Signed-off-by: Martin Kiepfer gpio: gpio_axp192: fix dependecy between GET_DIRECTION and GET_CONFIG configuration Latest unit gpio get_direction unit test failes, as get_direction api internally requires get_config functionality. This commit fixes this dependecy. Signed-off-by: Martin Kiepfer --- boards/xtensa/m5stack_core2/Kconfig.board | 12 + boards/xtensa/m5stack_core2/Kconfig.defconfig | 51 ++++ boards/xtensa/m5stack_core2/board.cmake | 9 + .../m5stack_core2/doc/img/m5stack_core2.webp | Bin 0 -> 88824 bytes boards/xtensa/m5stack_core2/doc/index.rst | 194 ++++++++++++++ .../m5stack_core2/m5stack_core2-pinctrl.dtsi | 56 ++++ boards/xtensa/m5stack_core2/m5stack_core2.dts | 246 ++++++++++++++++++ .../xtensa/m5stack_core2/m5stack_core2.yaml | 20 ++ .../m5stack_core2/m5stack_core2_defconfig | 19 ++ .../xtensa/m5stack_core2/support/openocd.cfg | 5 + 10 files changed, 612 insertions(+) create mode 100644 boards/xtensa/m5stack_core2/Kconfig.board create mode 100644 boards/xtensa/m5stack_core2/Kconfig.defconfig create mode 100644 boards/xtensa/m5stack_core2/board.cmake create mode 100644 boards/xtensa/m5stack_core2/doc/img/m5stack_core2.webp create mode 100644 boards/xtensa/m5stack_core2/doc/index.rst create mode 100644 boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi create mode 100644 boards/xtensa/m5stack_core2/m5stack_core2.dts create mode 100644 boards/xtensa/m5stack_core2/m5stack_core2.yaml create mode 100644 boards/xtensa/m5stack_core2/m5stack_core2_defconfig create mode 100644 boards/xtensa/m5stack_core2/support/openocd.cfg diff --git a/boards/xtensa/m5stack_core2/Kconfig.board b/boards/xtensa/m5stack_core2/Kconfig.board new file mode 100644 index 00000000000..9b48a15c24d --- /dev/null +++ b/boards/xtensa/m5stack_core2/Kconfig.board @@ -0,0 +1,12 @@ +# M5Stack Core2 board configuration + +# Copyright (c) 2023 Martin Kiepfer +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_M5STACK_CORE2 + bool "M5Stack Core2 Development Board" + depends on SOC_SERIES_ESP32 + +choice SOC_PART_NUMBER + default SOC_ESP32_D0WD_V3 +endchoice diff --git a/boards/xtensa/m5stack_core2/Kconfig.defconfig b/boards/xtensa/m5stack_core2/Kconfig.defconfig new file mode 100644 index 00000000000..278ef95cd88 --- /dev/null +++ b/boards/xtensa/m5stack_core2/Kconfig.defconfig @@ -0,0 +1,51 @@ +# M5Stack Core2 board configuration +# Copyright (c) 2022 AVSystem Sławomir Wolf Sp.j. (AVSystem) +# Copyright (c) 2023 Martin Kiepfer +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_M5STACK_CORE2 + +config BOARD + default "m5stack_core2" + depends on BOARD_M5STACK_CORE2 + +config ENTROPY_GENERATOR + default y + +config HEAP_MEM_POOL_SIZE + default 98304 if WIFI + default 65536 if BT + default 4096 + +config KERNEL_MEM_POOL + default y + +choice BT_HCI_BUS_TYPE + default BT_ESP32 if BT +endchoice + +config MFD_INIT_PRIORITY + default 60 + +config REGULATOR_AXP192_INIT_PRIORITY + default 76 + +config GPIO_AXP192_INIT_PRIORITY + default 80 + +config GPIO_HOGS_INIT_PRIORITY + default 81 + +config INPUT_FT5336_INTERRUPT + default y if INPUT + +config KSCAN + default y if DISPLAY + +config INPUT + default y if KSCAN + +config LV_COLOR_16_SWAP + default y if LVGL + +endif # BOARD_M5STACK_CORE2 diff --git a/boards/xtensa/m5stack_core2/board.cmake b/boards/xtensa/m5stack_core2/board.cmake new file mode 100644 index 00000000000..2f04d1fe886 --- /dev/null +++ b/boards/xtensa/m5stack_core2/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/xtensa/m5stack_core2/doc/img/m5stack_core2.webp b/boards/xtensa/m5stack_core2/doc/img/m5stack_core2.webp new file mode 100644 index 0000000000000000000000000000000000000000..794c8e4c9cbe5944ac90334e7e8b8dab7e93e135 GIT binary patch literal 88824 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 Se|fnkwm+_|+m8`` option during +``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). + +You can also open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! m5stack_core2 + +Debugging +--------- + +M5Stack Core2 debugging is not supported due to pinout limitations. + +Related Documents +***************** + +- `M5StickC PLUS schematic `_ (WEBP) +- `ESP32-PICO-D4 Datasheet `_ (PDF) +- `M5StickC PLUS docs `_ +- `ESP32 Datasheet `_ (PDF) +- `ESP32 Hardware Reference `_ diff --git a/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi new file mode 100644 index 00000000000..658954ad18e --- /dev/null +++ b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 AVSystem Sławomir Wolf Sp.j. (AVSystem) + * Copyright (c) 2023 Martin Kiepfer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_tx_gpio1: uart0_tx_gpio1 { + pinmux = ; + }; + + uart0_rx_gpio3: uart0_rx_gpio3 { + pinmux = ; + bias-pull-up; + }; + + spim3_default: spim3_default { + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + drive-open-drain; + output-high; + }; + }; + +}; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts new file mode 100644 index 00000000000..93cfcf38741 --- /dev/null +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2023 Martin Kiepfer + * + * SPDX-License-Identifier: Apache-2.0 + */ +/dts-v1/; + +#include +#include "m5stack_core2-pinctrl.dtsi" +#include +#include + +/ { + model = "esp32"; + compatible = "espressif,esp32"; + + aliases { + pwr-led = &pwr_led; + uart-0 = &uart0; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + rtc = &pfc8563_rtc; + led0 = &led_pwr; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,display = &ili9342c; + zephyr,keyboard-scan = &kscan_input; + zephyr,code-partition = &slot0_partition; + zephyr,rtc = &pfc8563_rtc; + }; + + leds { + compatible = "gpio-leds"; + led_pwr: led_pwr { + gpios = <&axp192_gpio 1 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; + label = "Power LED"; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&cpu1 { + clock-frequency = ; +}; + +&psram0 { + reg = <0x3f800000 DT_SIZE_M(8)>; + status = "disabled"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_tx_gpio1 &uart0_rx_gpio3>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + sda-gpios = <&gpio0 21 GPIO_OPEN_DRAIN>; + scl-gpios = <&gpio0 22 GPIO_OPEN_DRAIN>; + pinctrl-0 = <&i2c0_default>; + scl-timeout-us = <0>; + pinctrl-names = "default"; + + pfc8563_rtc: pfc8563@51 { + compatible = "nxp,pcf8523"; + reg = <0x51>; + status = "okay"; + battery-switch-over = "disabled"; + }; + + axp192_pmic: axp192@34 { + compatible = "x-powers,axp192"; + reg = <0x34>; + status = "okay"; + + axp192_regulator: axp192_regulator { + compatible = "x-powers,axp192-regulator"; + status = "okay"; + + vdd_mcu: DCDC1 { + regulator-init-microvolt = <3350000>; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3400000>; + regulator-initial-mode = ; + regulator-boot-on; + regulator-always-on; + }; + + lcd_bg: DCDC3 { + regulator-init-microvolt = <2800000>; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + v_peri: LDO2 { + regulator-init-microvolt = <3300000>; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + vib_motor: LDO3 { + regulator-init-microvolt = <2800000>; + }; + }; + + axp192_gpio: axp192_gpio { + compatible = "x-powers,axp192-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + status = "okay"; + + pwr_led: axp192_gpio1 { + gpio-hog; + gpios = <1 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; + output-high; + line-name = "pwr-led"; + }; + + bus_pwr_en: axp192_gpio0 { + gpio-hog; + gpios = <0 0>; + input; + }; + }; + }; + + ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + int-gpios = <&gpio1 7 0>; + + kscan_input: kscan-input { + compatible = "zephyr,kscan-input"; + }; + }; +}; + +&spi3 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim3_default>; + pinctrl-names = "default"; + dma-enabled; + clock-frequency = <20000000>; + cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + + ili9342c: ili9342c@0 { + compatible = "ilitek,ili9342c"; + spi-max-frequency = <30000000>; + reg = <0>; + cmd-data-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + vin-supply = <&lcd_bg>; + reset-gpios = <&axp192_gpio 4 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; + pixel-format = ; + display-inversion; + width = <320>; + height = <240>; + rotation = <0>; + }; +}; + + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&timer3 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&flash0 { + status = "okay"; + reg = <0 DT_SIZE_M(16)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 60kB for the bootloader */ + boot_partition: partition@1000 { + label = "mcuboot"; + reg = <0x00001000 0x0000F000>; + read-only; + }; + + /* Reserve 1024kB for the application in slot 0 */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + /* Reserve 1024kB for the application in slot 1 */ + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + /* Reserve 256kB for the scratch partition */ + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + /* 14MB storage */ + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00db0000>; + }; + }; +}; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.yaml b/boards/xtensa/m5stack_core2/m5stack_core2.yaml new file mode 100644 index 00000000000..1ee36021b39 --- /dev/null +++ b/boards/xtensa/m5stack_core2/m5stack_core2.yaml @@ -0,0 +1,20 @@ +identifier: m5stack_core2 +name: M5Stack Core2 +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - i2c + - spi + - watchdog + - regulator + - uart + - pinmux + - nvs +testing: + default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/xtensa/m5stack_core2/m5stack_core2_defconfig b/boards/xtensa/m5stack_core2/m5stack_core2_defconfig new file mode 100644 index 00000000000..10fde73b477 --- /dev/null +++ b/boards/xtensa/m5stack_core2/m5stack_core2_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOARD_M5STACK_CORE2=y + +CONFIG_SOC_SERIES_ESP32=y + +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_ESP_HEAP_MEM_POOL_REGION_1_SIZE=0 + +CONFIG_GPIO=y + +CONFIG_REGULATOR=y + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + +# for debugging +CONFIG_SHELL=y diff --git a/boards/xtensa/m5stack_core2/support/openocd.cfg b/boards/xtensa/m5stack_core2/support/openocd.cfg new file mode 100644 index 00000000000..338e6e4e6ea --- /dev/null +++ b/boards/xtensa/m5stack_core2/support/openocd.cfg @@ -0,0 +1,5 @@ +set ESP_RTOS none +set ESP32_ONLYCPU 1 + +source [find interface/ftdi/esp32_devkitj_v1.cfg] +source [find target/esp32.cfg] From dbf3768af9a6c14eeca8582ec5ac038b7481f9b4 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Fri, 8 Sep 2023 09:27:56 +0200 Subject: [PATCH 0167/4498] drivers: axp192_gpio: Fix for latest get_direction unit test This commit resolves an internal dependecy between GET_DIRECTION and GET_CONFIG configuration. GET_CONFIG api is internally needed by GET_DIRECTION api. Signed-off-by: Martin Kiepfer --- drivers/gpio/gpio_axp192.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_axp192.c b/drivers/gpio/gpio_axp192.c index 95625d99dfe..cf594c25aba 100644 --- a/drivers/gpio/gpio_axp192.c +++ b/drivers/gpio/gpio_axp192.c @@ -159,7 +159,18 @@ static int gpio_axp192_port_toggle_bits(const struct device *dev, gpio_port_pins return ret; } -#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_axp192_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + +#if defined(CONFIG_GPIO_GET_CONFIG) || defined(CONFIG_GPIO_GET_DIRECTION) static int gpio_axp192_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *out_flags) { const struct gpio_axp192_config *config = dev->config; @@ -265,6 +276,7 @@ static const struct gpio_driver_api gpio_axp192_api = { .port_set_bits_raw = gpio_axp192_port_set_bits_raw, .port_clear_bits_raw = gpio_axp192_port_clear_bits_raw, .port_toggle_bits = gpio_axp192_port_toggle_bits, + .pin_interrupt_configure = gpio_axp192_pin_interrupt_configure, .manage_callback = gpio_axp192_manage_callback, #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_axp192_port_get_direction, From d453c21384b5a44aa972a4b6b97158bd5e9842a4 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Wed, 30 Aug 2023 07:55:02 +0200 Subject: [PATCH 0168/4498] boards: m5stack_core2: Exclude board from device tree test m5stack_core2 enables i2c by default for regulator usage which conflicts with the test and is therefore excluded from the test. Signed-off-by: Martin Kiepfer --- tests/lib/devicetree/devices/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/devicetree/devices/testcase.yaml b/tests/lib/devicetree/devices/testcase.yaml index b57489b9a11..d7695220b8b 100644 --- a/tests/lib/devicetree/devices/testcase.yaml +++ b/tests/lib/devicetree/devices/testcase.yaml @@ -14,4 +14,5 @@ tests: - bt610 - bl5340_dvk_cpuapp - bl5340_dvk_cpuapp_ns + - m5stack_core2 - mimxrt595_evk_cm33 From c45cab369c5c5fd6dd04f1900dbf9b8fe790c535 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Mon, 4 Sep 2023 19:58:14 +0200 Subject: [PATCH 0169/4498] devicetree: Add grove connector definition for m5stack_core2 Basic pinout definition. Signed-off-by: Martin Kiepfer --- .../m5stack_core2/grove_connectors.dtsi | 19 +++++++++++++++++++ .../m5stack_core2/m5stack_core2-pinctrl.dtsi | 17 +++++++++++++++++ boards/xtensa/m5stack_core2/m5stack_core2.dts | 17 +++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 boards/xtensa/m5stack_core2/grove_connectors.dtsi diff --git a/boards/xtensa/m5stack_core2/grove_connectors.dtsi b/boards/xtensa/m5stack_core2/grove_connectors.dtsi new file mode 100644 index 00000000000..3a49570382d --- /dev/null +++ b/boards/xtensa/m5stack_core2/grove_connectors.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Joel Guittet + * Copyright (c) 2023 Martin Kiepfer + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + grove_header: grove_header { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 1 0>, /* D0/SCL/RX */ + <1 0 &gpio1 0 0>; /* D1/SDA/TX */ + }; +}; + +grove_i2c: &i2c1 {}; +grove_uart: &uart1 {}; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi index 658954ad18e..dce82fde545 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi +++ b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi @@ -20,6 +20,14 @@ bias-pull-up; }; + uart1_rx_gpio33: uart1_rx_gpio33 { + pinmux = ; + }; + + uart1_tx_gpio32: uart1_tx_gpio32 { + pinmux = ; + }; + spim3_default: spim3_default { group1 { pinmux = , @@ -53,4 +61,13 @@ }; }; + i2c1_default: i2c1_default { + group1 { + pinmux = , + ; + drive-open-drain; + output-high; + }; + }; + }; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index 93cfcf38741..0f804d5926b 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -7,6 +7,7 @@ #include #include "m5stack_core2-pinctrl.dtsi" +#include "grove_connectors.dtsi" #include #include @@ -63,6 +64,13 @@ pinctrl-names = "default"; }; +&uart1 { + status = "disabled"; + current-speed = <115200>; + pinctrl-0 = <&uart1_rx_gpio33 &uart1_tx_gpio32>; + pinctrl-names = "default"; +}; + &gpio0 { status = "okay"; }; @@ -157,6 +165,15 @@ }; }; +&i2c1 { + status = "disabled"; + clock-frequency = ; + sda-gpios = <&gpio0 32 GPIO_OPEN_DRAIN>; + scl-gpios = <&gpio0 33 GPIO_OPEN_DRAIN>; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; +}; + &spi3 { #address-cells = <1>; #size-cells = <0>; From 830aa5f7da9bce2bac4629757a8e584148780cbc Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 28 Aug 2023 19:48:10 +0200 Subject: [PATCH 0170/4498] tests: Bluetooth: Add initial BAP Broadcast Source unit tests Adds initial BAP Broadcast Source unit tests. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/CMakeLists.txt | 17 ++ .../audio/bap_broadcast_source/prj.conf | 19 ++ .../audio/bap_broadcast_source/src/main.c | 221 ++++++++++++++++++ .../audio/bap_broadcast_source/testcase.yaml | 7 + .../bap_broadcast_source/uut/CMakeLists.txt | 21 ++ tests/bluetooth/audio/mocks/CMakeLists.txt | 1 + .../bluetooth/audio/mocks/include/bluetooth.h | 18 ++ tests/bluetooth/audio/mocks/include/conn.h | 1 + tests/bluetooth/audio/mocks/include/crypto.h | 18 ++ tests/bluetooth/audio/mocks/include/iso.h | 9 +- tests/bluetooth/audio/mocks/src/bap_stream.c | 2 + tests/bluetooth/audio/mocks/src/crypto.c | 10 + tests/bluetooth/audio/mocks/src/iso.c | 88 ++++++- 13 files changed, 420 insertions(+), 12 deletions(-) create mode 100644 tests/bluetooth/audio/bap_broadcast_source/CMakeLists.txt create mode 100644 tests/bluetooth/audio/bap_broadcast_source/prj.conf create mode 100644 tests/bluetooth/audio/bap_broadcast_source/src/main.c create mode 100644 tests/bluetooth/audio/bap_broadcast_source/testcase.yaml create mode 100644 tests/bluetooth/audio/bap_broadcast_source/uut/CMakeLists.txt create mode 100644 tests/bluetooth/audio/mocks/include/bluetooth.h create mode 100644 tests/bluetooth/audio/mocks/include/crypto.h create mode 100644 tests/bluetooth/audio/mocks/src/crypto.c diff --git a/tests/bluetooth/audio/bap_broadcast_source/CMakeLists.txt b/tests/bluetooth/audio/bap_broadcast_source/CMakeLists.txt new file mode 100644 index 00000000000..46976424220 --- /dev/null +++ b/tests/bluetooth/audio/bap_broadcast_source/CMakeLists.txt @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +project(bluetooth_ascs) +find_package(Zephyr COMPONENTS unittest HINTS $ENV{ZEPHYR_BASE}) + +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/audio/bap_broadcast_source/uut uut) + +target_link_libraries(testbinary PRIVATE uut) + +target_include_directories(testbinary PRIVATE include) + +target_sources(testbinary + PRIVATE + src/main.c +) diff --git a/tests/bluetooth/audio/bap_broadcast_source/prj.conf b/tests/bluetooth/audio/bap_broadcast_source/prj.conf new file mode 100644 index 00000000000..b56abbec6c8 --- /dev/null +++ b/tests/bluetooth/audio/bap_broadcast_source/prj.conf @@ -0,0 +1,19 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_BT=y +CONFIG_BT_AUDIO=y + +CONFIG_BT_ISO_MAX_CHAN=2 + +CONFIG_BT_BAP_BROADCAST_SOURCE=y +CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2 +CONFIG_BT_BAP_BROADCAST_SRC_COUNT=1 +CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2 + +CONFIG_LOG=y +CONFIG_BT_BAP_BROADCAST_SOURCE_LOG_LEVEL_DBG=y + +CONFIG_ASSERT=y +CONFIG_ASSERT_LEVEL=2 +CONFIG_ASSERT_VERBOSE=y diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c new file mode 100644 index 00000000000..27a348f4399 --- /dev/null +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -0,0 +1,221 @@ +/* main.c - Application main entry point */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bluetooth.h" +#include "bap_stream_expects.h" + +DEFINE_FFF_GLOBALS; + +static void mock_init_rule_before(const struct ztest_unit_test *test, void *fixture) +{ + mock_bap_stream_init(); +} + +static void mock_destroy_rule_after(const struct ztest_unit_test *test, void *fixture) +{ + mock_bap_stream_cleanup(); +} + +ZTEST_RULE(mock_rule, mock_init_rule_before, mock_destroy_rule_after); + +struct bap_broadcast_source_test_suite_fixture { + struct bt_bap_broadcast_source_create_param *create_param; + size_t stream_cnt; + struct bt_bap_broadcast_source *source; +}; + +static void bap_broadcast_source_test_suite_fixture_init( + struct bap_broadcast_source_test_suite_fixture *fixture) +{ + const size_t streams_per_subgroup = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT / + CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; + const enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + const enum bt_audio_location loc = BT_AUDIO_LOCATION_FRONT_LEFT; + struct bt_bap_broadcast_source_subgroup_param *subgroup_param; + struct bt_bap_broadcast_source_stream_param *stream_params; + struct bt_audio_codec_cfg *codec_cfg; + struct bt_audio_codec_qos *codec_qos; + struct bt_bap_stream *streams; + const uint16_t latency = 10U; /* ms*/ + const uint32_t pd = 40000U; /* us */ + const uint16_t sdu = 40U; /* octets */ + const uint8_t rtn = 2U; + + zassert_true(streams_per_subgroup > 0U); + + /* Allocate memory for everything */ + fixture->create_param = malloc(sizeof(struct bt_bap_broadcast_source_create_param)); + subgroup_param = malloc(sizeof(struct bt_bap_broadcast_source_subgroup_param) * + CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT); + zassert_not_null(subgroup_param); + stream_params = malloc(sizeof(struct bt_bap_broadcast_source_stream_param) * + CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); + zassert_not_null(stream_params); + codec_cfg = malloc(sizeof(struct bt_audio_codec_cfg)); + zassert_not_null(codec_cfg); + codec_qos = malloc(sizeof(struct bt_audio_codec_qos)); + zassert_not_null(codec_qos); + streams = malloc(sizeof(struct bt_bap_stream) * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); + zassert_not_null(streams); + + /* Memset everything to 0 */ + memset(fixture->create_param, 0, sizeof(*fixture->create_param)); + memset(subgroup_param, 0, + sizeof(struct bt_bap_broadcast_source_subgroup_param) * + CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT); + memset(stream_params, 0, + sizeof(struct bt_bap_broadcast_source_stream_param) * + CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); + memset(codec_cfg, 0, sizeof(struct bt_audio_codec_cfg)); + memset(codec_qos, 0, sizeof(struct bt_audio_codec_qos)); + memset(streams, 0, sizeof(struct bt_bap_stream) * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); + + /* Initialize default values*/ + *codec_cfg = BT_AUDIO_CODEC_LC3_CONFIG_16_2(loc, ctx); + *codec_qos = BT_AUDIO_CODEC_LC3_QOS_10_UNFRAMED(sdu, rtn, latency, pd); + + for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; i++) { + subgroup_param[i].params_count = streams_per_subgroup; + subgroup_param[i].params = stream_params + i * streams_per_subgroup; + subgroup_param[i].codec_cfg = codec_cfg; + } + + for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT; i++) { + stream_params[i].stream = &streams[i]; + stream_params[i].data = NULL; + stream_params[i].data_len = 0U; + bt_bap_stream_cb_register(stream_params[i].stream, &mock_bap_stream_ops); + } + + fixture->create_param->params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; + fixture->create_param->params = subgroup_param; + fixture->create_param->qos = codec_qos; + fixture->create_param->encryption = false; + memset(fixture->create_param->broadcast_code, 0, + sizeof(fixture->create_param->broadcast_code)); + fixture->create_param->packing = BT_ISO_PACKING_SEQUENTIAL; + + fixture->stream_cnt = fixture->create_param->params_count * streams_per_subgroup; +} + +static void *bap_broadcast_source_test_suite_setup(void) +{ + struct bap_broadcast_source_test_suite_fixture *fixture; + + fixture = malloc(sizeof(*fixture)); + zassert_not_null(fixture); + + return fixture; +} + +static void bap_broadcast_source_test_suite_before(void *f) +{ + memset(f, 0, sizeof(struct bap_broadcast_source_test_suite_fixture)); + bap_broadcast_source_test_suite_fixture_init(f); +} + +static void bap_broadcast_source_test_suite_after(void *f) +{ + struct bap_broadcast_source_test_suite_fixture *fixture = f; + + if (fixture->source != NULL) { + int err; + + (void)bt_bap_broadcast_source_stop(fixture->source); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; + } + + free(fixture->create_param->params[0].params[0].stream); + free(fixture->create_param->params[0].params); + free(fixture->create_param->params[0].codec_cfg); + free(fixture->create_param->params); + free(fixture->create_param->qos); + free(fixture->create_param); +} + +static void bap_broadcast_source_test_suite_teardown(void *f) +{ + free(f); +} + +ZTEST_SUITE(bap_broadcast_source_test_suite, NULL, bap_broadcast_source_test_suite_setup, + bap_broadcast_source_test_suite_before, bap_broadcast_source_test_suite_after, + bap_broadcast_source_test_suite_teardown); + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) +{ + struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_start_send_stop_delete) +{ + struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_le_ext_adv ext_adv = {0}; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); + zassert_equal(0, err, "Unable to start broadcast source: err %d", err); + + zexpect_call_count("bt_bap_stream_ops.started", fixture->stream_cnt, + mock_bap_stream_started_cb_fake.call_count); + + for (size_t i = 0U; i < create_param->params_count; i++) { + for (size_t j = 0U; j < create_param->params[i].params_count; j++) { + struct bt_bap_stream *bap_stream = create_param->params[i].params[j].stream; + + /* Since BAP doesn't care about the `buf` we can just provide NULL */ + err = bt_bap_stream_send(bap_stream, NULL, 0, BT_ISO_TIMESTAMP_NONE); + zassert_equal(0, err, + "Unable to send on broadcast stream[%zu][%zu]: err %d", i, j, + err); + } + } + + zexpect_call_count("bt_bap_stream_ops.sent", fixture->stream_cnt, + mock_bap_stream_sent_cb_fake.call_count); + + err = bt_bap_broadcast_source_stop(fixture->source); + zassert_equal(0, err, "Unable to stop broadcast source: err %d", err); + + zexpect_call_count("bt_bap_stream_ops.stopped", fixture->stream_cnt, + mock_bap_stream_stopped_cb_fake.call_count); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} diff --git a/tests/bluetooth/audio/bap_broadcast_source/testcase.yaml b/tests/bluetooth/audio/bap_broadcast_source/testcase.yaml new file mode 100644 index 00000000000..7e97c62613a --- /dev/null +++ b/tests/bluetooth/audio/bap_broadcast_source/testcase.yaml @@ -0,0 +1,7 @@ +common: + tags: + - bluetooth + - bluetooth_audio +tests: + bluetooth.audio.bap_broadcast_source.test_default: + type: unit diff --git a/tests/bluetooth/audio/bap_broadcast_source/uut/CMakeLists.txt b/tests/bluetooth/audio/bap_broadcast_source/uut/CMakeLists.txt new file mode 100644 index 00000000000..85f68a6d1a6 --- /dev/null +++ b/tests/bluetooth/audio/bap_broadcast_source/uut/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# CMakeLists.txt file for creating of uut library. +# + +add_library(uut STATIC + ${ZEPHYR_BASE}/subsys/bluetooth/audio/bap_iso.c + ${ZEPHYR_BASE}/subsys/bluetooth/audio/bap_stream.c + ${ZEPHYR_BASE}/subsys/bluetooth/audio/bap_broadcast_source.c + ${ZEPHYR_BASE}/subsys/logging/log_minimal.c + ${ZEPHYR_BASE}/subsys/net/buf_simple.c +) + +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/audio/mocks mocks) + +target_link_libraries(uut PUBLIC test_interface mocks) + +target_compile_options(uut PRIVATE -std=c11 -include ztest.h) diff --git a/tests/bluetooth/audio/mocks/CMakeLists.txt b/tests/bluetooth/audio/mocks/CMakeLists.txt index 10d37d191bf..270a9b75f19 100644 --- a/tests/bluetooth/audio/mocks/CMakeLists.txt +++ b/tests/bluetooth/audio/mocks/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(mocks STATIC src/bap_unicast_client.c src/bap_unicast_server.c src/conn.c + src/crypto.c src/fatal.c src/gatt.c src/iso.c diff --git a/tests/bluetooth/audio/mocks/include/bluetooth.h b/tests/bluetooth/audio/mocks/include/bluetooth.h new file mode 100644 index 00000000000..43baf8b03ee --- /dev/null +++ b/tests/bluetooth/audio/mocks/include/bluetooth.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef MOCKS_BLUETOOTH_H_ +#define MOCKS_BLUETOOTH_H_ + +struct bt_le_ext_adv { + /* ID Address used for advertising */ + uint8_t id; + + /* Advertising handle */ + uint8_t handle; +}; + +#endif /* MOCKS_BLUETOOTH_H_ */ diff --git a/tests/bluetooth/audio/mocks/include/conn.h b/tests/bluetooth/audio/mocks/include/conn.h index eb78a05fe6e..ae6d3dc70d4 100644 --- a/tests/bluetooth/audio/mocks/include/conn.h +++ b/tests/bluetooth/audio/mocks/include/conn.h @@ -12,6 +12,7 @@ struct bt_conn { uint8_t index; struct bt_conn_info info; + struct bt_iso_chan *chan; }; void mock_bt_conn_disconnected(struct bt_conn *conn, uint8_t err); diff --git a/tests/bluetooth/audio/mocks/include/crypto.h b/tests/bluetooth/audio/mocks/include/crypto.h new file mode 100644 index 00000000000..1aa01e5203f --- /dev/null +++ b/tests/bluetooth/audio/mocks/include/crypto.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef MOCKS_CRYPTO_H_ +#define MOCKS_CRYPTO_H_ + +#include +#include + +/* List of fakes used by this unit tester */ +#define CRYPTO_FFF_FAKES_LIST(FAKE) FAKE(bt_rand) + +DECLARE_FAKE_VALUE_FUNC(int, bt_rand, void *, size_t); + +#endif /* MOCKS_CRYPTO_H_ */ diff --git a/tests/bluetooth/audio/mocks/include/iso.h b/tests/bluetooth/audio/mocks/include/iso.h index 40fd0ed94cd..82536c6f0fe 100644 --- a/tests/bluetooth/audio/mocks/include/iso.h +++ b/tests/bluetooth/audio/mocks/include/iso.h @@ -10,14 +10,19 @@ #include #include +#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) +struct bt_iso_big { + struct bt_iso_chan *bis[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; + uint8_t num_bis; +}; +#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */ + void mock_bt_iso_init(void); void mock_bt_iso_cleanup(void); int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id, struct bt_iso_chan **chan); int mock_bt_iso_disconnected(struct bt_iso_chan *chan, uint8_t err); -DECLARE_FAKE_VALUE_FUNC(int, bt_iso_chan_send, struct bt_iso_chan *, struct net_buf *, uint16_t, - uint32_t); DECLARE_FAKE_VALUE_FUNC(int, bt_iso_chan_get_tx_sync, const struct bt_iso_chan *, struct bt_iso_tx_info *); diff --git a/tests/bluetooth/audio/mocks/src/bap_stream.c b/tests/bluetooth/audio/mocks/src/bap_stream.c index c022865dc0a..f55fe226ec7 100644 --- a/tests/bluetooth/audio/mocks/src/bap_stream.c +++ b/tests/bluetooth/audio/mocks/src/bap_stream.c @@ -40,12 +40,14 @@ void mock_bap_stream_init(void) { FFF_FAKES_LIST(RESET_FAKE); +#if defined(CONFIG_BT_BAP_UNICAST) mock_bap_stream_ops.configured = mock_bap_stream_configured_cb; mock_bap_stream_ops.qos_set = mock_bap_stream_qos_set_cb; mock_bap_stream_ops.enabled = mock_bap_stream_enabled_cb; mock_bap_stream_ops.metadata_updated = mock_bap_stream_metadata_updated_cb; mock_bap_stream_ops.disabled = mock_bap_stream_disabled_cb; mock_bap_stream_ops.released = mock_bap_stream_released_cb; +#endif /* CONFIG_BT_BAP_UNICAST */ mock_bap_stream_ops.started = mock_bap_stream_started_cb; mock_bap_stream_ops.stopped = mock_bap_stream_stopped_cb; #if defined(CONFIG_BT_AUDIO_RX) diff --git a/tests/bluetooth/audio/mocks/src/crypto.c b/tests/bluetooth/audio/mocks/src/crypto.c new file mode 100644 index 00000000000..05e23238be2 --- /dev/null +++ b/tests/bluetooth/audio/mocks/src/crypto.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "crypto.h" + +DEFINE_FAKE_VALUE_FUNC(int, bt_rand, void *, size_t); diff --git a/tests/bluetooth/audio/mocks/src/iso.c b/tests/bluetooth/audio/mocks/src/iso.c index 875ba170577..ccf29c07737 100644 --- a/tests/bluetooth/audio/mocks/src/iso.c +++ b/tests/bluetooth/audio/mocks/src/iso.c @@ -11,18 +11,22 @@ #include "iso.h" /* List of fakes used by this unit tester */ -#define FFF_FAKES_LIST(FAKE) \ - FAKE(bt_iso_chan_send) \ - FAKE(bt_iso_chan_get_tx_sync) +#define FFF_FAKES_LIST(FAKE) FAKE(bt_iso_chan_get_tx_sync) static struct bt_iso_server *iso_server; -DEFINE_FAKE_VALUE_FUNC(int, bt_iso_chan_send, struct bt_iso_chan *, struct net_buf *, uint16_t, - uint32_t); - DEFINE_FAKE_VALUE_FUNC(int, bt_iso_chan_get_tx_sync, const struct bt_iso_chan *, struct bt_iso_tx_info *); +int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num, uint32_t ts) +{ + if (chan->ops != NULL && chan->ops->sent != NULL) { + chan->ops->sent(chan); + } + + return 0; +} + int bt_iso_server_register(struct bt_iso_server *server) { zassert_not_null(server, "server is NULL"); @@ -59,6 +63,16 @@ void mock_bt_iso_cleanup(void) } +void mock_bt_iso_connected(struct bt_conn *iso) +{ + struct bt_iso_chan *chan = iso->chan; + + chan->state = BT_ISO_STATE_CONNECTED; + chan->iso = iso; + + chan->ops->connected(chan); +} + int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id, struct bt_iso_chan **chan) { @@ -67,6 +81,7 @@ int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id, .cig_id = cig_id, .cis_id = cis_id, }; + struct bt_conn *iso; int err; zassert_not_null(iso_server, "iso_server is NULL"); @@ -78,11 +93,11 @@ int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id, zassert_not_null(*chan, "chan is NULL"); - (*chan)->state = BT_ISO_STATE_CONNECTED; - (*chan)->iso = malloc(sizeof(struct bt_conn)); - zassert_not_null((*chan)->iso); + iso = malloc(sizeof(struct bt_conn)); + zassert_not_null(iso); - (*chan)->ops->connected(*chan); + iso->chan = (*chan); + mock_bt_iso_connected(iso); return 0; } @@ -96,3 +111,56 @@ int mock_bt_iso_disconnected(struct bt_iso_chan *chan, uint8_t err) return 0; } + +#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) +int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param, + struct bt_iso_big **out_big) +{ + struct bt_iso_big *big; + + zassert_not_null(out_big); + zassert_not_null(param); + zassert_not_equal(param->num_bis, 0); + + big = malloc(sizeof(struct bt_iso_big)); + zassert_not_null(big); + big->num_bis = 0U; + + for (uint8_t i = 0U; i < param->num_bis; i++) { + struct bt_iso_chan *bis = param->bis_channels[i]; + struct bt_conn *iso; + + zassert_not_null(bis); + + iso = malloc(sizeof(struct bt_conn)); + zassert_not_null(iso); + big->bis[i] = bis; + big->num_bis++; + + iso->chan = bis; + mock_bt_iso_connected(iso); + } + + *out_big = big; + + return 0; +} + +int bt_iso_big_terminate(struct bt_iso_big *big) +{ + /* TODO: Call chan->ops->disconnected(*chan); for each BIS */ + zassert_not_equal(big->num_bis, 0); + + for (uint8_t i = 0U; i < big->num_bis; i++) { + struct bt_iso_chan *bis = big->bis[i]; + + zassert_not_null(bis, "big %p", big); + + mock_bt_iso_disconnected(bis, BT_HCI_ERR_LOCALHOST_TERM_CONN); + } + + free(big); + + return 0; +} +#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */ From a6431d1d6a312782a43299ca8376fb001aca084a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:10:42 +0700 Subject: [PATCH 0171/4498] mr_canhubk3: enable L2 ethernet when dummy L2 is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable CONFIG_NET_L2_ETHERNET only when dummy L2 layer is not used. Otherwise having the two of them enabled will cause failures in some net tests that expect only dummy L2 layer to be enabled and configured. Signed-off-by: Manuel Argüelles --- boards/arm/mr_canhubk3/Kconfig.defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/mr_canhubk3/Kconfig.defconfig b/boards/arm/mr_canhubk3/Kconfig.defconfig index c2a2501ebe3..6cf6f085492 100644 --- a/boards/arm/mr_canhubk3/Kconfig.defconfig +++ b/boards/arm/mr_canhubk3/Kconfig.defconfig @@ -23,7 +23,7 @@ endif # CAN if NETWORKING config NET_L2_ETHERNET - default y + default y if !NET_LOOPBACK && !NET_TEST endif # NETWORKING From b86548ca7c83c7a584b722e4f0228a7926a35379 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 13:27:35 +0200 Subject: [PATCH 0172/4498] Bluetooth: Audio: Add check for valid cid and vid for LC3 When using the LC3 codec, the cid and vid fields of the codec shall both be 0x00, as per the BAP and ASCS specs. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_stream.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 2d315ce227e..940b45785de 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -195,6 +195,18 @@ bool bt_audio_valid_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) return false; } + if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->cid != 0U) { + LOG_DBG("codec_cfg->cid (%u) is invalid", codec_cfg->cid); + return false; + } + + if (codec_cfg->vid != 0U) { + LOG_DBG("codec_cfg->vid (%u) is invalid", codec_cfg->vid); + return false; + } + } + #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 if (codec_cfg->data_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) { LOG_DBG("codec_cfg->data_len (%zu) is invalid", codec_cfg->data_len); From c1214f20677ad29c9588375d4a884d3205706142 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 6 Sep 2023 13:16:15 +0200 Subject: [PATCH 0173/4498] Bluetooth: audio: ascs: Make stream->ep valid in bt_bap_stream_ops.released Once the application bt_bap_stream_ops.released callback is called make sure the stream->ep pointer is valid so that application can still access the endpoint details like e.g. endpoint direction. Fixes: ASCS/SR/ACP/BV-{24,25,26,27,28,29,30,31}-C Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/ascs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 9b45754fe90..c7c9e2e43b6 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -117,6 +117,10 @@ static void ase_free(struct bt_ascs_ase *ase) LOG_DBG("conn %p ase %p id 0x%02x", (void *)ase->conn, ase, ase->ep.status.id); + if (ase->ep.iso != NULL) { + bt_bap_iso_unbind_ep(ase->ep.iso, &ase->ep); + } + bt_conn_unref(ase->conn); ase->conn = NULL; } @@ -247,7 +251,10 @@ static void ase_set_state_idle(struct bt_ascs_ase *ase) ase_status_changed(ase, BT_BAP_EP_STATE_IDLE); - bt_bap_stream_reset(stream); + if (stream->conn != NULL) { + bt_conn_unref(stream->conn); + stream->conn = NULL; + } ops = stream->ops; if (ops != NULL && ops->released != NULL) { From ff71508d5f19da2cb035ddd8985bfca745bb5087 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 6 Sep 2023 14:46:24 +0200 Subject: [PATCH 0174/4498] Bluetooth: audio: ascs: Add endpoint by stream lookup function This adds endpoint by stream lookup function used to find the active endpoints that use the stream object provided. The function is used instead of dereferencing stream->ep that may be not valid if application did not memset the stream object. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/ascs.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index c7c9e2e43b6..3ac041e2b7e 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -1480,6 +1480,19 @@ static int ase_config(struct bt_ascs_ase *ase, const struct bt_ascs_config *cfg) return 0; } +static struct bt_bap_ep *ep_lookup_stream(struct bt_conn *conn, struct bt_bap_stream *stream) +{ + for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) { + struct bt_ascs_ase *ase = &ase_pool[i]; + + if (ase->conn == conn && ase->ep.stream == stream) { + return &ase->ep; + } + } + + return NULL; +} + int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_audio_codec_cfg *codec_cfg, const struct bt_audio_codec_qos_pref *qos_pref) @@ -1494,7 +1507,8 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, return -EINVAL; } - if (stream->ep != NULL) { + ep = ep_lookup_stream(conn, stream); + if (ep != NULL) { LOG_DBG("Stream already configured for conn %p", (void *)stream->conn); return -EALREADY; } From fe1c341ae26cd96870ddd0c7eade99fe95e45bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 6 Sep 2023 16:15:34 +0200 Subject: [PATCH 0175/4498] boards: arm: nucleo_f091rc: enable CAN support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This MCU has a classical CAN controller, which was previously not enabled. I2C2 is disabled by default because it uses the same pins as CAN and there are no other free pins that can be used for CAN. Signed-off-by: Martin Jäger --- boards/arm/nucleo_f091rc/doc/index.rst | 5 ++++- boards/arm/nucleo_f091rc/nucleo_f091rc.dts | 11 ++++++++++- boards/arm/nucleo_f091rc/nucleo_f091rc.yaml | 1 + .../i2c/i2c_target_api/boards/nucleo_f091rc.overlay | 7 +++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/boards/arm/nucleo_f091rc/doc/index.rst b/boards/arm/nucleo_f091rc/doc/index.rst index 136b935790f..4e1c8505098 100644 --- a/boards/arm/nucleo_f091rc/doc/index.rst +++ b/boards/arm/nucleo_f091rc/doc/index.rst @@ -98,6 +98,8 @@ The Zephyr nucleo_f091rc board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | SPI | on-chip | SPI controller | +-----------+------------+-------------------------------------+ +| CAN | on-chip | CAN controller | ++-----------+------------+-------------------------------------+ | ADC | on-chip | ADC controller | +-----------+------------+-------------------------------------+ | DAC | on-chip | DAC controller | @@ -132,7 +134,8 @@ Default Zephyr Peripheral Mapping: - UART_1 TX/RX : PB6/PB7 - UART_2 TX/RX : PA2/PA3 (ST-Link Virtual COM Port) - I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) -- I2C2 SCL/SDA : PA11/PA12 +- I2C2 SCL/SDA : PA11/PA12 (disabled by default, uses same pins as CAN) +- CAN RX/TX : PA11/PA12 - SPI1 SCK/MISO/MOSI : PA5/PA6/PA7 (Arduino SPI) - SPI2 SCK/MISO/MOSI : PB13/PB14/PB15 - USER_PB : PC13 diff --git a/boards/arm/nucleo_f091rc/nucleo_f091rc.dts b/boards/arm/nucleo_f091rc/nucleo_f091rc.dts index b496e041c9a..b7a94b29e9e 100644 --- a/boards/arm/nucleo_f091rc/nucleo_f091rc.dts +++ b/boards/arm/nucleo_f091rc/nucleo_f091rc.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,canbus = &can1; }; leds: leds { @@ -105,12 +106,20 @@ }; &i2c2 { + /* Pin conflict with can1. Enable only with can1 disabled. */ pinctrl-0 = <&i2c2_scl_pa11 &i2c2_sda_pa12>; pinctrl-names = "default"; - status = "okay"; + status = "disabled"; clock-frequency = ; }; +&can1 { + pinctrl-0 = <&can_rx_pa11 &can_tx_pa12>; + pinctrl-names = "default"; + bus-speed = <125000>; + status = "okay"; +}; + &spi1 { pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; pinctrl-names = "default"; diff --git a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml index f749400b29c..3bf62e60ee7 100644 --- a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml +++ b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml @@ -22,6 +22,7 @@ supported: - dac - dma - pwm + - can testing: ignore_tags: - net diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_f091rc.overlay b/tests/drivers/i2c/i2c_target_api/boards/nucleo_f091rc.overlay index 6ca9868d734..0e2323a1a0f 100644 --- a/tests/drivers/i2c/i2c_target_api/boards/nucleo_f091rc.overlay +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_f091rc.overlay @@ -20,9 +20,16 @@ &i2c2 { + /* i2c2 is disabled by default because of pin conflict with can1 */ + status = "okay"; eeprom1: eeprom@56 { compatible = "zephyr,i2c-target-eeprom"; reg = <0x56>; size = <1024>; }; }; + +&can1 { + /* can1 shares the pins with i2c2 and must be disabled */ + status = "disabled"; +}; From 5f17a16ef480936ab2c6f66d86fde81cead1087d Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 8 Sep 2023 20:20:13 +0900 Subject: [PATCH 0176/4498] dts: bindings: i2c: Add RasbperryPi Pico I2C Add Raspberry Pi Pico I2C that inheriting both DesignWare I2C device and reset device. Signed-off-by: TOKITA Hiroshi --- dts/arm/rpi_pico/rp2040.dtsi | 6 ++++-- dts/bindings/i2c/raspberrypi,pico-i2c.yaml | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 dts/bindings/i2c/raspberrypi,pico-i2c.yaml diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi index 24c0a3e7bae..131c59a1b1b 100644 --- a/dts/arm/rpi_pico/rp2040.dtsi +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -138,10 +138,11 @@ }; i2c0: i2c@40044000 { - compatible = "snps,designware-i2c"; + compatible = "raspberrypi,pico-i2c", "snps,designware-i2c"; #address-cells = <1>; #size-cells = <0>; reg = <0x40044000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_I2C0>; clocks = <&system_clk>; interrupts = <23 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "i2c0"; @@ -149,10 +150,11 @@ }; i2c1: i2c@40048000 { - compatible = "snps,designware-i2c"; + compatible = "raspberrypi,pico-i2c", "snps,designware-i2c"; #address-cells = <1>; #size-cells = <0>; reg = <0x40048000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_I2C0>; clocks = <&system_clk>; interrupts = <24 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "i2c1"; diff --git a/dts/bindings/i2c/raspberrypi,pico-i2c.yaml b/dts/bindings/i2c/raspberrypi,pico-i2c.yaml new file mode 100644 index 00000000000..ac055dcfd59 --- /dev/null +++ b/dts/bindings/i2c/raspberrypi,pico-i2c.yaml @@ -0,0 +1,5 @@ +description: Raspberry Pi Pico I2C + +compatible: "raspberrypi,pico-i2c" + +include: ["snps,designware-i2c.yaml", "reset-device.yaml"] From e2f47c0c38286ae1bd4d8ec8770607223dff4874 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 8 Sep 2023 20:21:00 +0900 Subject: [PATCH 0177/4498] drivers: i2c: i2c_dw: Add capability for handling reset device Reset the device on initializing if reset-node is available in dts. `snps,desingware-i2c` does not define reset-node itself. Add more of an element that inherits `reset-device.yaml` to the `compatible` section to allow defining the reset-node for using this feature. For example. ``` compatible = "reset-device-inherit-node", "snps,designware-i2c"; ``` Signed-off-by: TOKITA Hiroshi --- drivers/i2c/i2c_dw.c | 21 +++++++++++++++++++++ drivers/i2c/i2c_dw.h | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index 74cf471783b..bb5ecc3779f 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -21,6 +21,9 @@ #if defined(CONFIG_PINCTRL) #include #endif +#if defined(CONFIG_RESET) +#include +#endif #include #include @@ -847,6 +850,15 @@ static int i2c_dw_initialize(const struct device *dev) union ic_con_register ic_con; int ret = 0; +#if defined(CONFIG_RESET) + if (rom->reset.dev) { + ret = reset_line_toggle_dt(&rom->reset); + if (ret) { + return ret; + } + } +#endif + #if defined(CONFIG_PINCTRL) ret = pinctrl_apply_state(rom->pcfg, PINCTRL_STATE_DEFAULT); if (ret) { @@ -922,6 +934,14 @@ static int i2c_dw_initialize(const struct device *dev) #define PINCTRL_DW_CONFIG(n) #endif +#if defined(CONFIG_RESET) +#define RESET_DW_CONFIG(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(0, resets), \ + (.reset = RESET_DT_SPEC_INST_GET(n),)) +#else +#define RESET_DW_CONFIG(n) +#endif + #define I2C_DW_INIT_PCIE0(n) #define I2C_DW_INIT_PCIE1(n) DEVICE_PCIE_INST_INIT(n, pcie), #define I2C_DW_INIT_PCIE(n) \ @@ -985,6 +1005,7 @@ static int i2c_dw_initialize(const struct device *dev) I2C_CONFIG_REG_INIT(n) \ .config_func = i2c_config_##n, \ .bitrate = DT_INST_PROP(n, clock_frequency), \ + RESET_DW_CONFIG(n) \ PINCTRL_DW_CONFIG(n) \ I2C_DW_INIT_PCIE(n) \ }; \ diff --git a/drivers/i2c/i2c_dw.h b/drivers/i2c/i2c_dw.h index c9f7381eb89..1aac3d20340 100644 --- a/drivers/i2c/i2c_dw.h +++ b/drivers/i2c/i2c_dw.h @@ -18,6 +18,10 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "DW I2C in DT needs CONFIG_PCIE"); #include #endif +#if defined(CONFIG_RESET) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -93,6 +97,9 @@ struct i2c_dw_rom_config { #if defined(CONFIG_PINCTRL) const struct pinctrl_dev_config *pcfg; #endif +#if defined(CONFIG_RESET) + const struct reset_dt_spec reset; +#endif #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) struct pcie_dev *pcie; From 15c733a36e5ca287cd31a3821fdbdadc14a90cfc Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 4 Sep 2023 14:36:06 +0200 Subject: [PATCH 0178/4498] samples: net: zperf: add Ethernet twister test add Ethernet twister test for stm32h573i_dk Signed-off-by: Marc Desvaux --- samples/net/zperf/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/zperf/sample.yaml b/samples/net/zperf/sample.yaml index 82b8b519e79..201940c23a9 100644 --- a/samples/net/zperf/sample.yaml +++ b/samples/net/zperf/sample.yaml @@ -26,6 +26,7 @@ tests: - nucleo_h743zi - nucleo_f429zi - nucleo_f746zg + - stm32h573i_dk sample.net.zperf_no_shell: harness: net extra_configs: From 5e63058deb97629066470a5be8d5231a60b10816 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 29 Aug 2023 20:02:00 +0100 Subject: [PATCH 0179/4498] sensor: bq274xx: use K_TIMEOUT_ABS_MS for the startup delay Use K_TIMEOUT_ABS_MS to control the startup delay. Same thing, more compact. Signed-off-by: Fabio Baltieri --- drivers/sensor/bq274xx/bq274xx.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/sensor/bq274xx/bq274xx.c b/drivers/sensor/bq274xx/bq274xx.c index e65db8fd29d..0cf52c79f17 100644 --- a/drivers/sensor/bq274xx/bq274xx.c +++ b/drivers/sensor/bq274xx/bq274xx.c @@ -626,7 +626,6 @@ static int bq274xx_gauge_init(const struct device *dev) struct bq274xx_data *data = dev->data; int ret; uint16_t id; - int32_t delay_remainder_ms; if (!device_is_ready(config->i2c.bus)) { LOG_ERR("I2C bus device not ready"); @@ -640,11 +639,7 @@ static int bq274xx_gauge_init(const struct device *dev) } #endif - delay_remainder_ms = POWER_UP_DELAY_MS - k_uptime_get_32(); - if (delay_remainder_ms > 0) { - LOG_DBG("Power up delay remainder: %dms", delay_remainder_ms); - k_msleep(delay_remainder_ms); - } + k_sleep(K_TIMEOUT_ABS_MS(POWER_UP_DELAY_MS)); ret = bq274xx_get_device_type(dev, &id); if (ret < 0) { From 91dd4fcfdc152279db630284314816cf82b8d923 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Mon, 11 Sep 2023 15:02:17 +0200 Subject: [PATCH 0180/4498] .github: workflows: Black box testing fix This fix pulls West in black box testing. Previously changes in West could break it. Signed-off-by: Lukasz Mrugala --- .github/workflows/blackbox_tests.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/blackbox_tests.yml b/.github/workflows/blackbox_tests.yml index ef84ac12de6..089b0c3e816 100644 --- a/.github/workflows/blackbox_tests.yml +++ b/.github/workflows/blackbox_tests.yml @@ -46,6 +46,15 @@ jobs: - name: Checkout uses: actions/checkout@v3 + - name: Environment Setup + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + west init -l . || true + west config --global update.narrow true + west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/zephyrproject) + west forall -c 'git reset --hard HEAD' + - name: Set Up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: From 9fc414a97f8e8112c6615cd4cf3bc6f503355050 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Mon, 11 Sep 2023 15:16:16 +0200 Subject: [PATCH 0181/4498] scripts: tests: twister_blackbox: Add -i flag to qemu tests An -i flag allows easier debugging for blackbox qemu tests. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister_blackbox/test_qemu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tests/twister_blackbox/test_qemu.py b/scripts/tests/twister_blackbox/test_qemu.py index f8bc54bcc43..a7f7d1c33ef 100644 --- a/scripts/tests/twister_blackbox/test_qemu.py +++ b/scripts/tests/twister_blackbox/test_qemu.py @@ -85,7 +85,7 @@ def teardown_class(cls): ] ) def test_emulation_only(self, capfd, test_path, test_platforms, expected): - args = ['-T', test_path, '--emulation-only'] + \ + args = ['-i', '-T', test_path, '--emulation-only'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms ) for val in pair] From 7e2005b8614e2aada4dcc0139fb384e6e2592530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 18 Jul 2023 16:59:43 +0200 Subject: [PATCH 0182/4498] usb: audio: doc: Cleanup Doxygen documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleaned up various improperly documented elements in the usb_audio.h file. Signed-off-by: Benjamin Cabé --- include/zephyr/usb/class/usb_audio.h | 81 +++++++++++++++++++++------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/include/zephyr/usb/class/usb_audio.h b/include/zephyr/usb/class/usb_audio.h index 26c58c75086..9062af37206 100644 --- a/include/zephyr/usb/class/usb_audio.h +++ b/include/zephyr/usb/class/usb_audio.h @@ -26,7 +26,7 @@ #include #include -/** Audio Interface Subclass Codes +/** Audio Interface Subclass Codes. * Refer to Table A-2 from audio10.pdf */ enum usb_audio_int_subclass_codes { @@ -36,7 +36,7 @@ enum usb_audio_int_subclass_codes { USB_AUDIO_MIDISTREAMING = 0x03 }; -/** Audio Class-Specific AC Interface Descriptor Subtypes +/** Audio Class-Specific AC Interface Descriptor Subtypes. * Refer to Table A-5 from audio10.pdf */ enum usb_audio_cs_ac_int_desc_subtypes { @@ -100,39 +100,81 @@ enum usb_audio_fucs { * Refer to Table 2-1 - Table 2-4 from termt10.pdf */ enum usb_audio_terminal_types { - /* USB Terminal Types */ + /** + * @name USB Terminal Types + * @{ + */ + /** USB undefined */ USB_AUDIO_USB_UNDEFINED = 0x0100, + /** USB streaming */ USB_AUDIO_USB_STREAMING = 0x0101, + /** USB vendor specific */ USB_AUDIO_USB_VENDOR_SPEC = 0x01FF, + /** @} */ - /* Input Terminal Types */ + /** + * @name Input Terminal Types + * @{ + */ + /** Input undefined */ USB_AUDIO_IN_UNDEFINED = 0x0200, + /** Microphone */ USB_AUDIO_IN_MICROPHONE = 0x0201, + /** Desktop microphone */ USB_AUDIO_IN_DESKTOP_MIC = 0x0202, + /** Personal microphone */ USB_AUDIO_IN_PERSONAL_MIC = 0x0203, + /** Omni directional microphone */ USB_AUDIO_IN_OM_DIR_MIC = 0x0204, + /** Microphone array */ USB_AUDIO_IN_MIC_ARRAY = 0x0205, + /** Processing microphone array */ USB_AUDIO_IN_PROC_MIC_ARRAY = 0x0205, + /** @} */ - /* Output Terminal Types */ + /** + * @name Output Terminal Types + * @{ + */ + /** Output undefined */ USB_AUDIO_OUT_UNDEFINED = 0x0300, + /** Speaker */ USB_AUDIO_OUT_SPEAKER = 0x0301, + /** Headphones */ USB_AUDIO_OUT_HEADPHONES = 0x0302, + /** Head mounted display audio */ USB_AUDIO_OUT_HEAD_AUDIO = 0x0303, + /** Desktop speaker */ USB_AUDIO_OUT_DESKTOP_SPEAKER = 0x0304, + /** Room speaker */ USB_AUDIO_OUT_ROOM_SPEAKER = 0x0305, + /** Communication speaker */ USB_AUDIO_OUT_COMM_SPEAKER = 0x0306, + /** Low frequency effects speaker */ USB_AUDIO_OUT_LOW_FREQ_SPEAKER = 0x0307, + /** @} */ - /* Bi-directional Terminal Types */ + /** + * @name Bi-directional Terminal Types + * @{ + */ + /** Bidirectional undefined */ USB_AUDIO_IO_UNDEFINED = 0x0400, + /** Handset */ USB_AUDIO_IO_HANDSET = 0x0401, + /** Headset */ USB_AUDIO_IO_HEADSET = 0x0402, + /** Speakerphone, no echo reduction */ USB_AUDIO_IO_SPEAKERPHONE_ECHO_NONE = 0x0403, + /** Speakerphone, echo reduction */ USB_AUDIO_IO_SPEAKERPHONE_ECHO_SUP = 0x0404, + /** Speakerphone, echo cancellation */ USB_AUDIO_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, }; +/** + * @brief Audio device direction. + */ enum usb_audio_direction { USB_AUDIO_IN = 0x00, USB_AUDIO_OUT = 0x01 @@ -143,20 +185,23 @@ enum usb_audio_direction { * * The event structure is used by feature_update_cb in order to inform the App * whenever the Host has modified one of the device features. - * - * @param dir The device direction that has been changed. Applicable for - * Headset device only. - * @param cs Control selector, feature that has been changed. - * @param channel Device channel that has been changed. If 0xFF, then - * all channels have been changed. - * @param val_len Length of the val field. - * @param val Value of the feature that has been set. */ struct usb_audio_fu_evt { + /** + * The device direction that has been changed. + * Applicable for Headset device only. + */ enum usb_audio_direction dir; + /** Control selector feature that has been changed. */ enum usb_audio_fucs cs; + /** + * Device channel that has been changed. + * If 0xFF, then all channels have been changed. + */ uint8_t channel; + /** Length of the val field. */ uint8_t val_len; + /** Value of the feature that has been set. */ const void *val; }; @@ -214,22 +259,22 @@ typedef void (*usb_audio_feature_updated_cb_t)(const struct device *dev, * to callback documentation above. */ struct usb_audio_ops { - /* Callback called when data could be send */ + /** Callback called when data could be send */ usb_audio_data_request_cb_t data_request_cb; - /* Callback called when data were successfully written with sending + /** Callback called when data were successfully written with sending * capable device. Applicable for headset and microphone. Unused for * headphones. */ usb_audio_data_completion_cb_t data_written_cb; - /* Callback called when data were successfully received by receive + /** Callback called when data were successfully received by receive * capable device. Applicable for headset and headphones. Unused for * microphone. */ usb_audio_data_completion_cb_t data_received_cb; - /* Callback called when features were modified by the Host */ + /** Callback called when features were modified by the Host */ usb_audio_feature_updated_cb_t feature_update_cb; }; From a07b79a8bff26e8042f70c410724c9c06f0388ba Mon Sep 17 00:00:00 2001 From: Rick Talbott Date: Fri, 8 Sep 2023 10:41:02 -0600 Subject: [PATCH 0183/4498] drivers: sensor: tsl2540 Add the tsl2540 sensor to drivers. Signed-off-by: Rick Talbott --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/tsl2540/CMakeLists.txt | 6 + drivers/sensor/tsl2540/Kconfig | 54 +++ drivers/sensor/tsl2540/tsl2540.c | 373 ++++++++++++++++++ drivers/sensor/tsl2540/tsl2540.h | 115 ++++++ drivers/sensor/tsl2540/tsl2540_trigger.c | 200 ++++++++++ dts/bindings/sensor/ams,tsl2540.yaml | 34 ++ include/zephyr/drivers/sensor/tsl2540.h | 52 +++ tests/drivers/build_all/sensor/i2c.dtsi | 6 + .../sensor/sensors_trigger_global.conf | 1 + .../sensor/sensors_trigger_none.conf | 1 + .../build_all/sensor/sensors_trigger_own.conf | 1 + 13 files changed, 845 insertions(+) create mode 100644 drivers/sensor/tsl2540/CMakeLists.txt create mode 100644 drivers/sensor/tsl2540/Kconfig create mode 100644 drivers/sensor/tsl2540/tsl2540.c create mode 100644 drivers/sensor/tsl2540/tsl2540.h create mode 100644 drivers/sensor/tsl2540/tsl2540_trigger.c create mode 100644 dts/bindings/sensor/ams,tsl2540.yaml create mode 100644 include/zephyr/drivers/sensor/tsl2540.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index b3696bde3a2..8247e3b7011 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -137,6 +137,7 @@ add_subdirectory_ifdef(CONFIG_TMP007 tmp007) add_subdirectory_ifdef(CONFIG_TMP108 tmp108) add_subdirectory_ifdef(CONFIG_TMP112 tmp112) add_subdirectory_ifdef(CONFIG_TMP116 tmp116) +add_subdirectory_ifdef(CONFIG_TSL2540 tsl2540) add_subdirectory_ifdef(CONFIG_VCMP_IT8XXX2 ite_vcmp_it8xxx2) add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040) add_subdirectory_ifdef(CONFIG_VEML7700 veml7700) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index cfb9d88b38c..2862e5854b8 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -193,6 +193,7 @@ source "drivers/sensor/tmp007/Kconfig" source "drivers/sensor/tmp108/Kconfig" source "drivers/sensor/tmp112/Kconfig" source "drivers/sensor/tmp116/Kconfig" +source "drivers/sensor/tsl2540/Kconfig" source "drivers/sensor/vcnl4040/Kconfig" source "drivers/sensor/veml7700/Kconfig" source "drivers/sensor/vl53l0x/Kconfig" diff --git a/drivers/sensor/tsl2540/CMakeLists.txt b/drivers/sensor/tsl2540/CMakeLists.txt new file mode 100644 index 00000000000..dbc6ed78927 --- /dev/null +++ b/drivers/sensor/tsl2540/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(tsl2540.c) +zephyr_library_sources_ifdef(CONFIG_TSL2540_TRIGGER tsl2540_trigger.c) diff --git a/drivers/sensor/tsl2540/Kconfig b/drivers/sensor/tsl2540/Kconfig new file mode 100644 index 00000000000..b4d3e1ec510 --- /dev/null +++ b/drivers/sensor/tsl2540/Kconfig @@ -0,0 +1,54 @@ +# TSL2540 Ambient Light Sensor configuration options + +# Copyright (c) 2022 T-Mobile USA, Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig TSL2540 + bool "TSL2540 Ambient Light Sensor" + default y + depends on DT_HAS_AMS_TSL2540_ENABLED + select I2C + help + Enable driver for TSL2540 sensors. + +if TSL2540 + +config TSL2540_TRIGGER + bool + +choice + prompt "Trigger mode" + default TSL2540_TRIGGER_NONE + help + Specify the type of triggering to be used by the driver. + +config TSL2540_TRIGGER_NONE + bool "No trigger" + +config TSL2540_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select TSL2540_TRIGGER + +config TSL2540_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select TSL2540_TRIGGER + +endchoice + +config TSL2540_THREAD_PRIORITY + int "Thread priority" + depends on TSL2540_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config TSL2540_THREAD_STACK_SIZE + int "Thread stack size" + depends on TSL2540_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +endif # TSL2540 diff --git a/drivers/sensor/tsl2540/tsl2540.c b/drivers/sensor/tsl2540/tsl2540.c new file mode 100644 index 00000000000..fb3060d136e --- /dev/null +++ b/drivers/sensor/tsl2540/tsl2540.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2022 T-Mobile USA, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ams_tsl2540 + +#include "tsl2540.h" + +#include + +#include +#include +#include +#include +#include +#include + +#define TSL2540_INTEGRATION_TIME_MS (2.81) +#define TSL2540_DEVICE_FACTOR (53.0) + +#define FIXED_ATTENUATION_TO_DBL(x) (x * 0.00001) + +LOG_MODULE_REGISTER(tsl2540, CONFIG_SENSOR_LOG_LEVEL); + +static int tsl2540_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + int ret = 0; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_LIGHT || + chan == SENSOR_CHAN_IR); + k_sem_take(&data->sem, K_FOREVER); + + if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_LIGHT) { + uint16_t le16_buffer; + + ret = i2c_burst_read_dt(&cfg->i2c_spec, TSL2540_REG_VIS_LOW, + (uint8_t *)&le16_buffer, sizeof(le16_buffer)); + if (ret) { + LOG_ERR("Could not fetch ambient light (visible)"); + k_sem_give(&data->sem); + return -EIO; + } + + data->count_vis = sys_le16_to_cpu(le16_buffer); + } + + if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_IR) { + uint16_t le16_buffer; + + ret = i2c_burst_read_dt(&cfg->i2c_spec, TSL2540_REG_IR_LOW, (uint8_t *)&le16_buffer, + sizeof(le16_buffer)); + if (ret) { + LOG_ERR("Could not fetch ambient light (IR)"); + k_sem_give(&data->sem); + return -EIO; + } + + data->count_ir = sys_le16_to_cpu(le16_buffer); + } + + k_sem_give(&data->sem); + + return ret; +} + +static int tsl2540_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + int ret = 0; + double cpl; + double glass_attenuation = FIXED_ATTENUATION_TO_DBL(cfg->glass_attenuation); + double glass_ir_attenuation = FIXED_ATTENUATION_TO_DBL(cfg->glass_ir_attenuation); + + k_sem_take(&data->sem, K_FOREVER); + + cpl = (data->integration_time + 1) * TSL2540_INTEGRATION_TIME_MS; + cpl *= data->again; + + switch (chan) { + case SENSOR_CHAN_LIGHT: + sensor_value_from_double(val, data->count_vis / cpl * + TSL2540_DEVICE_FACTOR * glass_attenuation); + break; + case SENSOR_CHAN_IR: + sensor_value_from_double(val, data->count_ir / cpl * + TSL2540_DEVICE_FACTOR * glass_ir_attenuation); + break; + default: + ret = -ENOTSUP; + } + + k_sem_give(&data->sem); + + return ret; +} + +static int tsl2540_attr_set_gain(const struct device *dev, enum sensor_gain_tsl2540 gain) +{ + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + uint8_t value = 0; + double again = 0.0; + + switch (gain) { + case TSL2540_SENSOR_GAIN_1_2: + value = TSL2540_CFG1_G1_2; + again = TSL2540_AGAIN_S1_2; + break; + case TSL2540_SENSOR_GAIN_1: + value = TSL2540_CFG1_G1; + again = TSL2540_AGAIN_S1; + break; + case TSL2540_SENSOR_GAIN_4: + value = TSL2540_CFG1_G4; + again = TSL2540_AGAIN_S4; + break; + case TSL2540_SENSOR_GAIN_16: + value = TSL2540_CFG1_G16; + again = TSL2540_AGAIN_S16; + break; + case TSL2540_SENSOR_GAIN_64: + value = TSL2540_CFG1_G64; + again = TSL2540_AGAIN_S64; + break; + case TSL2540_SENSOR_GAIN_128: + value = TSL2540_CFG1_G128; + again = TSL2540_CFG2_G128; + break; + } + + if (i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_REG_CFG_1, value) < 0) { + return -EIO; + } + + if (i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_REG_CFG_2, value) < 0) { + return -EIO; + } + + data->again = again; + + return 0; +} + +static int tsl2540_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + int ret = 0; + uint8_t temp; + double it; + + if ((chan != SENSOR_CHAN_IR) & (chan != SENSOR_CHAN_LIGHT)) { + return -ENOTSUP; + } + + k_sem_take(&data->sem, K_FOREVER); + + i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_ENABLE_ADDR, TSL2540_ENABLE_MASK & + ~TSL2540_ENABLE_CONF); + +#if CONFIG_TSL2540_TRIGGER + if (chan == SENSOR_CHAN_LIGHT) { + if (attr == SENSOR_ATTR_UPPER_THRESH) { + double cpl; + uint16_t thld, le16_buffer; + double glass_attenuation = FIXED_ATTENUATION_TO_DBL(cfg->glass_attenuation); + + cpl = ((data->integration_time + 1) * TSL2540_INTEGRATION_TIME_MS); + cpl *= data->again; + cpl /= (TSL2540_DEVICE_FACTOR * glass_attenuation); + thld = sensor_value_to_double(val) * cpl; + LOG_DBG("attr: %d, cpl: %g, thld: %x\n", attr, cpl, thld); + + le16_buffer = sys_cpu_to_le16(thld); + ret = i2c_burst_write_dt( + &((const struct tsl2540_config *)dev->config)->i2c_spec, + TSL2540_REG_AIHT_LOW, (uint8_t *)&le16_buffer, sizeof(le16_buffer)); + + goto exit; + } + if (attr == SENSOR_ATTR_LOWER_THRESH) { + double cpl; + uint16_t thld, le16_buffer; + double glass_attenuation = FIXED_ATTENUATION_TO_DBL(cfg->glass_attenuation); + + cpl = ((data->integration_time + 1) * TSL2540_INTEGRATION_TIME_MS); + cpl *= data->again; + cpl /= (TSL2540_DEVICE_FACTOR * glass_attenuation); + thld = sensor_value_to_double(val) * cpl; + LOG_DBG("attr: %d, cpl: %g, thld: %x\n", attr, cpl, thld); + + le16_buffer = sys_cpu_to_le16(sys_cpu_to_le16(thld)); + + ret = i2c_burst_write_dt( + &((const struct tsl2540_config *)dev->config)->i2c_spec, + TSL2540_REG_AILT_LOW, (uint8_t *)&le16_buffer, sizeof(le16_buffer)); + + goto exit; + } + + } +#endif /* CONFIG_TSL2540_TRIGGER */ + + switch ((enum sensor_attribute_tsl2540)attr) { + case SENSOR_ATTR_GAIN: + tsl2540_attr_set_gain(dev, (enum sensor_gain_tsl2540)val->val1); + break; + case SENSOR_ATTR_INT_APERS: + temp = (uint8_t)val->val1; + + if (temp > 15) { + ret = -EINVAL; + goto exit; + } + + if (i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_REG_PERS, temp)) { + ret = -EIO; + goto exit; + } + break; + case SENSOR_ATTR_INTEGRATION_TIME: + it = sensor_value_to_double(val); + it /= TSL2540_INTEGRATION_TIME_MS; + if (it < 1 || it > 256) { + ret = -EINVAL; + goto exit; + } + it -= 1; + temp = (uint8_t)it; + if (i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_REG_ATIME, temp)) { + ret = -EIO; + goto exit; + } + + data->integration_time = temp; + ret = 0; + break; + case SENSOR_ATTR_TSL2540_SHUTDOWN_MODE: + data->enable_mode = TSL2540_ENABLE_DISABLE; + ret = i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_CFG3_ADDR, TSL2540_CFG3_MASK, + TSL2540_CFG3_CONF); + break; + case SENSOR_ATTR_TSL2540_CONTINUOUS_MODE: + data->enable_mode = TSL2540_ENABLE_CONF; + ret = i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_CFG3_ADDR, TSL2540_CFG3_MASK, + TSL2540_CFG3_CONF); + break; + case SENSOR_ATTR_TSL2540_CONTINUOUS_NO_WAIT_MODE: + data->enable_mode = TSL2540_ENABLE_AEN_PON; + ret = i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_CFG3_ADDR, TSL2540_CFG3_MASK, + TSL2540_CFG3_DFLT); + break; + } + +exit: + i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_ENABLE_ADDR, TSL2540_ENABLE_MASK, + data->enable_mode); + + k_sem_give(&data->sem); + + return ret; +} + +static int tsl2540_setup(const struct device *dev) +{ + struct sensor_value integration_time; + + /* Set ALS integration time */ + tsl2540_attr_set(dev, (enum sensor_channel)SENSOR_CHAN_LIGHT, + (enum sensor_attribute)SENSOR_ATTR_GAIN, + &(struct sensor_value){.val1 = TSL2540_SENSOR_GAIN_1_2, .val2 = 0}); + + sensor_value_from_double(&integration_time, 500.0); + tsl2540_attr_set(dev, (enum sensor_channel)SENSOR_CHAN_LIGHT, + (enum sensor_attribute)SENSOR_ATTR_INTEGRATION_TIME, &integration_time); + + return 0; +} + +static int tsl2540_init(const struct device *dev) +{ + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + + data->enable_mode = TSL2540_ENABLE_DISABLE; + + k_sem_init(&data->sem, 1, K_SEM_MAX_LIMIT); + + if (!i2c_is_ready_dt(&cfg->i2c_spec)) { + LOG_ERR("I2C dev %s not ready", cfg->i2c_spec.bus->name); + return -ENODEV; + } + + i2c_reg_write_byte_dt(&cfg->i2c_spec, TSL2540_REG_PERS, 1); + i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_CFG3_ADDR, TSL2540_CFG3_MASK, + TSL2540_CFG3_DFLT); + + if (tsl2540_setup(dev)) { + LOG_ERR("Failed to setup ambient light functionality"); + return -EIO; + } + +#if CONFIG_TSL2540_TRIGGER + if (tsl2540_trigger_init(dev)) { + LOG_ERR("Could not initialize interrupts"); + return -EIO; + } +#endif + + LOG_DBG("Init complete"); + + return 0; +} + +static const struct sensor_driver_api tsl2540_driver_api = { + .sample_fetch = tsl2540_sample_fetch, + .channel_get = tsl2540_channel_get, + .attr_set = tsl2540_attr_set, +#ifdef CONFIG_TSL2540_TRIGGER + .trigger_set = tsl2540_trigger_set, +#endif +}; + +#ifdef CONFIG_PM_DEVICE +static int tsl2540_pm_action(const struct device *dev, enum pm_device_action action) +{ + + const struct tsl2540_config *cfg = dev->config; + struct tsl2540_data *data = dev->data; + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_ENABLE_ADDR, + TSL2540_ENABLE_MASK, data->enable_mode); + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = i2c_reg_update_byte_dt(&cfg->i2c_spec, TSL2540_ENABLE_ADDR, + TSL2540_ENABLE_MASK, TSL2540_ENABLE_DISABLE); + break; + default: + return -ENOTSUP; + } + + return ret; +} +#endif + +#define TSL2540_GLASS_ATTEN(inst) \ + .glass_attenuation = DT_INST_PROP(inst, glass_attenuation), \ + .glass_ir_attenuation = DT_INST_PROP(inst, glass_ir_attenuation), \ + +#define TSL2540_DEFINE(inst) \ + static struct tsl2540_data tsl2540_prv_data_##inst; \ + static const struct tsl2540_config tsl2540_config_##inst = { \ + .i2c_spec = I2C_DT_SPEC_INST_GET(inst), \ + IF_ENABLED(CONFIG_TSL2540_TRIGGER, \ + (.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),)) \ + TSL2540_GLASS_ATTEN(inst) \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, tsl2540_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &tsl2540_init, PM_DEVICE_DT_INST_GET(inst), \ + &tsl2540_prv_data_##inst, &tsl2540_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tsl2540_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TSL2540_DEFINE) diff --git a/drivers/sensor/tsl2540/tsl2540.h b/drivers/sensor/tsl2540/tsl2540.h new file mode 100644 index 00000000000..36822f82da2 --- /dev/null +++ b/drivers/sensor/tsl2540/tsl2540.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2022 T-Mobile USA, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_TSL2540_TSL2540_H_ +#define ZEPHYR_DRIVERS_SENSOR_TSL2540_TSL2540_H_ + +#include +#include +#include +#include + +#define TSL2540_REG_ATIME 0x81 +#define TSL2540_REG_WTIME 0x83 +#define TSL2540_REG_AILT_LOW 0x84 +#define TSL2540_REG_AILT_HI 0x85 +#define TSL2540_REG_AIHT_LOW 0x86 +#define TSL2540_REG_AIHT_HI 0x87 +#define TSL2540_REG_PERS 0x8c +#define TSL2540_REG_CFG_0 0x8d +#define TSL2540_REG_CFG_1 0x90 +#define TSL2540_REG_REVID 0x91 +#define TSL2540_REG_ID 0x92 +#define TSL2540_REG_STATUS 0x93 +#define TSL2540_REG_VIS_LOW 0x94 +#define TSL2540_REG_VIS_HI 0x95 +#define TSL2540_REG_IR_LOW 0x96 +#define TSL2540_REG_IR_HI 0x97 +#define TSL2540_REG_REVID2 0x9E +#define TSL2540_REG_CFG_2 0x9f + +#define TSL2540_AGAIN_S1_2 0.5 +#define TSL2540_AGAIN_S1 1 +#define TSL2540_AGAIN_S4 4 +#define TSL2540_AGAIN_S16 16 +#define TSL2540_AGAIN_S64 67 +#define TSL2540_AGAIN_S128 140 + +#define TSL2540_CFG1_G1_2 0x00 +#define TSL2540_CFG1_G1 0x00 +#define TSL2540_CFG1_G4 0x01 +#define TSL2540_CFG1_G16 0x02 +#define TSL2540_CFG1_G64 0x03 +#define TSL2540_CFG1_G128 0x03 + +#define TSL2540_CFG2_G1_2 0x00 +#define TSL2540_CFG2_G1 0x04 +#define TSL2540_CFG2_G4 0x04 +#define TSL2540_CFG2_G16 0x04 +#define TSL2540_CFG2_G64 0x04 +#define TSL2540_CFG2_G128 0x14 + +/* ENABLE(0x80: 0x00): Reserved:7:4 | WEN:3 | Reserved:2 | AEN:1 | PON:0 */ +#define TSL2540_ENABLE_ADDR 0x80 +#define TSL2540_ENABLE_MASK (BIT(3) | BIT(1) | BIT(0)) +#define TSL2540_ENABLE_CONF (BIT(3) | BIT(1) | BIT(0)) +#define TSL2540_ENABLE_AEN_PON (BIT(1) | BIT(0)) +#define TSL2540_ENABLE_DISABLE (0) + +/* CRG3(0xAB: 0x0C): INT_READ_CLEAR:7 | Reserved:6:5 | SAI:4 | Reserved:3:0 */ +#define TSL2540_CFG3_ADDR 0xAB +#define TSL2540_CFG3_MASK (BIT(7) | BIT(4)) +#define TSL2540_CFG3_CONF (BIT(7) | BIT(4)) +#define TSL2540_CFG3_DFLT (0) + +/* INTENAB(0xDD: 0x00): ASIEN:7 | Reserved:6:5 | AIEN:4 | Reserved:3:0 */ +#define TSL2540_INTENAB_ADDR 0xDD +#define TSL2540_INTENAB_MASK (BIT(7) | BIT(4)) +#define TSL2540_INTENAB_CONF (BIT(4)) + +#define TSL2540_INT_EN_AEN 0x90 + +struct tsl2540_config { + const struct i2c_dt_spec i2c_spec; +#ifdef CONFIG_TSL2540_TRIGGER + const struct gpio_dt_spec int_gpio; +#endif + const uint32_t glass_attenuation; + const uint32_t glass_ir_attenuation; +}; + +struct tsl2540_data { + const struct device *i2c; + struct k_sem sem; +#ifdef CONFIG_TSL2540_TRIGGER + const struct device *dev; + struct gpio_callback gpio_cb; + const struct sensor_trigger *als_trigger; + sensor_trigger_handler_t als_handler; +#endif +#ifdef CONFIG_TSL2540_TRIGGER_OWN_THREAD + K_THREAD_STACK_MEMBER(thread_stack, CONFIG_TSL2540_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem trig_sem; +#endif +#ifdef CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD + struct k_work work; +#endif + uint8_t enable_mode; + uint16_t count_vis; + uint16_t count_ir; + uint8_t integration_time; + double again; +}; + +#ifdef CONFIG_TSL2540_TRIGGER +int tsl2540_trigger_init(const struct device *dev); + +int tsl2540_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); +#endif + +#endif diff --git a/drivers/sensor/tsl2540/tsl2540_trigger.c b/drivers/sensor/tsl2540/tsl2540_trigger.c new file mode 100644 index 00000000000..c383186e77c --- /dev/null +++ b/drivers/sensor/tsl2540/tsl2540_trigger.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2022 T-Mobile USA, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tsl2540.h" +#include + +LOG_MODULE_DECLARE(tsl2540, CONFIG_SENSOR_LOG_LEVEL); + +static void tsl2540_setup_int(const struct device *dev, bool enable) +{ + const struct tsl2540_config *config = dev->config; + gpio_flags_t flags = enable + ? GPIO_INT_EDGE_TO_ACTIVE + : GPIO_INT_DISABLE; + + gpio_pin_interrupt_configure_dt(&config->int_gpio, flags); +} + +static void tsl2540_handle_int(const struct device *dev) +{ + struct tsl2540_data *drv_data = dev->data; + + tsl2540_setup_int(dev, false); + +#if defined(CONFIG_TSL2540_TRIGGER_OWN_THREAD) + k_sem_give(&drv_data->trig_sem); +#elif defined(CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD) + k_work_submit(&drv_data->work); +#endif +} + +static void tsl2540_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pin_mask) +{ + struct tsl2540_data *data = CONTAINER_OF(cb, struct tsl2540_data, gpio_cb); + + tsl2540_handle_int(data->dev); +} + +static void tsl2540_process_int(const struct device *dev) +{ + const struct tsl2540_config *config = dev->config; + struct tsl2540_data *data = dev->data; + uint8_t status; + + /* Read the status, cleared automatically in CFG3 */ + int ret = i2c_reg_read_byte_dt(&config->i2c_spec, TSL2540_REG_STATUS, &status); + + if (ret) { + LOG_ERR("Could not read status register (%#x), errno: %d", TSL2540_REG_STATUS, + ret); + return; + } + + if (BIT(7) & status) { /* ASAT */ + LOG_ERR("Interrupt status(%#x): %#x: ASAT", TSL2540_REG_STATUS, status); + } + + if (BIT(3) & status) { /* CINT */ + LOG_DBG("Interrupt status(%#x): %#x: CINT", TSL2540_REG_STATUS, status); + } + + if (BIT(4) & status) { /* AINT */ + LOG_DBG("Interrupt status(%#x): %#x: AINT", TSL2540_REG_STATUS, status); + if (data->als_handler != NULL) { + data->als_handler(dev, data->als_trigger); + } + } + + tsl2540_setup_int(dev, true); + + /* Check for pin that may be asserted while we were busy */ + int pv = gpio_pin_get_dt(&config->int_gpio); + + if (pv > 0) { + tsl2540_handle_int(dev); + } +} + +#ifdef CONFIG_TSL2540_TRIGGER_OWN_THREAD +static void tsl2540_thread_main(struct tsl2540_data *data) +{ + while (true) { + k_sem_take(&data->trig_sem, K_FOREVER); + tsl2540_process_int(data->dev); + } +} +#endif + +#ifdef CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD +static void tsl2540_work_handler(struct k_work *work) +{ + struct tsl2540_data *data = CONTAINER_OF(work, struct tsl2540_data, work); + + tsl2540_process_int(data->dev); +} +#endif + +int tsl2540_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + const struct tsl2540_config *config = dev->config; + struct tsl2540_data *data = dev->data; + int ret; + + if (trig->type != SENSOR_TRIG_THRESHOLD) { + LOG_ERR("Unsupported sensor trigger type: %d", trig->type); + return -ENOTSUP; + } + + if (trig->chan != SENSOR_CHAN_LIGHT) { + LOG_ERR("Unsupported sensor trigger channel: %d", trig->chan); + return -ENOTSUP; + } + + + const struct i2c_dt_spec *i2c_spec = &config->i2c_spec; + + ret = i2c_reg_update_byte_dt(i2c_spec, TSL2540_INTENAB_ADDR, + TSL2540_INTENAB_MASK, TSL2540_INTENAB_CONF); + if (ret) { + LOG_ERR("%#x: I/O error: %d", TSL2540_INTENAB_ADDR, ret); + return -EIO; + } + + ret = i2c_reg_update_byte_dt(i2c_spec, TSL2540_CFG3_ADDR, + TSL2540_CFG3_MASK, TSL2540_CFG3_CONF); + if (ret) { + LOG_ERR("%#x: I/O error: %d", TSL2540_CFG3_ADDR, ret); + return -EIO; + } + + k_sem_take(&data->sem, K_FOREVER); + + data->als_handler = handler; + data->als_trigger = trig; + + if (handler != NULL) { + tsl2540_setup_int(dev, true); + + /* Check whether already asserted */ + int pv = gpio_pin_get_dt(&config->int_gpio); + + if (pv > 0) { + tsl2540_handle_int(dev); + } + } + + k_sem_give(&data->sem); + + return ret; +} + +int tsl2540_trigger_init(const struct device *dev) +{ + const struct tsl2540_config *config = dev->config; + struct tsl2540_data *data = dev->data; + int rc; + + /* Check device is defined */ + if (config->int_gpio.port == NULL) { + LOG_ERR("int-gpios is not defined in the device tree."); + return -EINVAL; + } + + /* Get the GPIO device */ + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("%s: gpio controller %s not ready", dev->name, config->int_gpio.port->name); + return -ENODEV; + } + + rc = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (rc < 0) { + return rc; + } + + gpio_init_callback(&data->gpio_cb, tsl2540_gpio_callback, BIT(config->int_gpio.pin)); + + if (gpio_add_callback(config->int_gpio.port, &data->gpio_cb) < 0) { + LOG_ERR("Failed to set gpio callback!"); + return -EIO; + } + + data->dev = dev; + +#if defined(CONFIG_TSL2540_TRIGGER_OWN_THREAD) + k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); + k_thread_create(&data->thread, data->thread_stack, CONFIG_TSL2540_THREAD_STACK_SIZE, + (k_thread_entry_t)tsl2540_thread_main, data, NULL, NULL, + K_PRIO_COOP(CONFIG_TSL2540_THREAD_PRIORITY), 0, K_NO_WAIT); + k_thread_name_set(&data->thread, "TSL2540 trigger"); +#elif defined(CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD) + data->work.handler = tsl2540_work_handler; +#endif + + return 0; +} diff --git a/dts/bindings/sensor/ams,tsl2540.yaml b/dts/bindings/sensor/ams,tsl2540.yaml new file mode 100644 index 00000000000..e47f8a8e8f0 --- /dev/null +++ b/dts/bindings/sensor/ams,tsl2540.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2022 T-Mobile USA, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + TSL2540 series ambient light sensor. See datasheet at + https://ams.com/documents/20143/36005/TSL2540_DS000564_4-00.pdf/39728ac4-098c-9eca-b5ca-61d9c6f3a588 + +compatible: "ams,tsl2540" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + Identifies the interrupt pin + + glass-attenuation: + type: int + default: 100000 + description: | + Visible light attenuation. + Integer value for a represenation with 5 decimal points. + This default value (1.00000) is chosen for free open space (no glass). + Example: 1.2 would be 120000 + + glass-ir-attenuation: + type: int + default: 100000 + description: | + Infa-red light attenuation. + Integer value for a represenation with 5 decimal points. + This default value (1.00000) is chosen for free open space (no glass). + Example: 1.2 would be 120000 diff --git a/include/zephyr/drivers/sensor/tsl2540.h b/include/zephyr/drivers/sensor/tsl2540.h new file mode 100644 index 00000000000..63a2adfe48b --- /dev/null +++ b/include/zephyr/drivers/sensor/tsl2540.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 T-Mobile USA, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for AMS's TSL2540 ambient light sensor + * + * This exposes attributes for the TSL2540 which can be used for + * setting the on-chip gain and integration time parameters. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_TSL2540_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_TSL2540_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum sensor_attribute_tsl2540 { + /* Sensor Gain */ + SENSOR_ATTR_GAIN = SENSOR_ATTR_PRIV_START + 1, + /* Sensor Integration Time (in ms) */ + SENSOR_ATTR_INTEGRATION_TIME, + /* Sensor ALS interrupt persistence filters */ + SENSOR_ATTR_INT_APERS, + /* Shutdown the sensor */ + SENSOR_ATTR_TSL2540_SHUTDOWN_MODE, + /* Turn on continuous conversion */ + SENSOR_ATTR_TSL2540_CONTINUOUS_MODE, + /* Turn on continuous conversion without wait */ + SENSOR_ATTR_TSL2540_CONTINUOUS_NO_WAIT_MODE, +}; + +enum sensor_gain_tsl2540 { + TSL2540_SENSOR_GAIN_1_2, + TSL2540_SENSOR_GAIN_1, + TSL2540_SENSOR_GAIN_4, + TSL2540_SENSOR_GAIN_16, + TSL2540_SENSOR_GAIN_64, + TSL2540_SENSOR_GAIN_128, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_TSL2540_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 6beea40d494..c0f687ee05d 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -745,3 +745,9 @@ test_i2c_f75303: f75303@70 { compatible = "fintek,f75303"; reg = <0x70>; }; + +test_i2c_tsl2540: tsl2540@71 { + compatible = "ams,tsl2540"; + reg = <0x71>; + int-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index a18d55ab42e..dc8321f1a7d 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -49,6 +49,7 @@ CONFIG_SX9500_TRIGGER_GLOBAL_THREAD=y CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD=y CONFIG_TMD2620_TRIGGER_GLOBAL_THREAD=y CONFIG_TMP007_TRIGGER_GLOBAL_THREAD=y +CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD=y CONFIG_VCNL4040_TRIGGER_GLOBAL_THREAD=y CONFIG_WSEN_HIDS_TRIGGER_GLOBAL_THREAD=y CONFIG_WSEN_TIDS_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index b374ff86525..e53189629ba 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -49,6 +49,7 @@ CONFIG_SX9500_TRIGGER_NONE=y CONFIG_TCN75A_TRIGGER_NONE=y CONFIG_TMD2620_TRIGGER_NONE=y CONFIG_TMP007_TRIGGER_NONE=y +CONFIG_TSL2540_TRIGGER_NONE=y CONFIG_VCNL4040_TRIGGER_NONE=y CONFIG_WSEN_HIDS_TRIGGER_NONE=y CONFIG_WSEN_TIDS_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index 04892cf8ad5..4f7e3bbdbfa 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -46,6 +46,7 @@ CONFIG_STTS751_TRIGGER_OWN_THREAD=y CONFIG_SX9500_TRIGGER_OWN_THREAD=y CONFIG_TCN75A_TRIGGER_OWN_THREAD=y CONFIG_TMP007_TRIGGER_OWN_THREAD=y +CONFIG_TSL2540_TRIGGER_OWN_THREAD=y CONFIG_VCNL4040_TRIGGER_OWN_THREAD=y CONFIG_WSEN_HIDS_TRIGGER_OWN_THREAD=y CONFIG_WSEN_TIDS_TRIGGER_OWN_THREAD=y From 2ffead788b8739dde01b0bc28d6f4631445286be Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Mon, 14 Aug 2023 14:08:26 +0800 Subject: [PATCH 0184/4498] drivers: dac: Add driver for mcux lpdac Create dac_mcxu_lpdac.c file to implement mcux lpdac, add binding for the mcux lpdac, update Kconfig.mcux and CMakeLists.txt file to support mcux lpdac. Signed-off-by: Albort Xue --- drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig.mcux | 7 +++ drivers/dac/dac_mcux_lpdac.c | 107 ++++++++++++++++++++++++++++++++ dts/bindings/dac/nxp,lpdac.yaml | 29 +++++++++ 4 files changed, 144 insertions(+) create mode 100644 drivers/dac/dac_mcux_lpdac.c create mode 100644 dts/bindings/dac/nxp,lpdac.yaml diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index 7cce3c8e7cb..d2164f92d7e 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/dac.h) zephyr_library() +zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_LPDAC dac_mcux_lpdac.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC dac_mcux_dac.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC32 dac_mcux_dac32.c) zephyr_library_sources_ifdef(CONFIG_DAC_STM32 dac_stm32.c) diff --git a/drivers/dac/Kconfig.mcux b/drivers/dac/Kconfig.mcux index e02d498f505..87869775d03 100644 --- a/drivers/dac/Kconfig.mcux +++ b/drivers/dac/Kconfig.mcux @@ -19,6 +19,13 @@ config DAC_MCUX_DAC32 help Enable the driver for the NXP Kinetis MCUX DAC32. +config DAC_MCUX_LPDAC + bool "NXP MCUX LPDAC driver" + default y + depends on DT_HAS_NXP_LPDAC_ENABLED + help + Enable the driver for the NXP MCUX LPDAC. + config DAC_MCUX_DAC32_TESTOUT bool "DAC test output" depends on DAC_MCUX_DAC32 diff --git a/drivers/dac/dac_mcux_lpdac.c b/drivers/dac/dac_mcux_lpdac.c new file mode 100644 index 00000000000..d65624940e7 --- /dev/null +++ b/drivers/dac/dac_mcux_lpdac.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * Copyright (c) 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT nxp_lpdac + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(dac_mcux_lpdac, CONFIG_DAC_LOG_LEVEL); + +struct mcux_lpdac_config { + LPDAC_Type *base; + dac_reference_voltage_source_t ref_voltage; + bool low_power; +}; + +struct mcux_lpdac_data { + bool configured; +}; + +static int mcux_lpdac_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + const struct mcux_lpdac_config *config = dev->config; + struct mcux_lpdac_data *data = dev->data; + dac_config_t dac_config; + + if (channel_cfg->channel_id != 0) { + LOG_ERR("unsupported channel %d", channel_cfg->channel_id); + return -ENOTSUP; + } + + if (channel_cfg->resolution != 12) { + LOG_ERR("unsupported resolution %d", channel_cfg->resolution); + return -ENOTSUP; + } + + DAC_GetDefaultConfig(&dac_config); + dac_config.referenceVoltageSource = config->ref_voltage; +#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL + dac_config.enableLowerLowPowerMode = config->low_power; +#else + dac_config.enableLowPowerMode = config->low_power; +#endif + DAC_Init(config->base, &dac_config); + DAC_Enable(config->base, false); + data->configured = true; + + return 0; +} + +static int mcux_lpdac_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + const struct mcux_lpdac_config *config = dev->config; + struct mcux_lpdac_data *data = dev->data; + + if (!data->configured) { + LOG_ERR("channel not initialized"); + return -EINVAL; + } + + if (channel != 0) { + LOG_ERR("unsupported channel %d", channel); + return -ENOTSUP; + } + + if (value >= 4096) { + LOG_ERR("unsupported value %d", value); + return -EINVAL; + } + + DAC_Enable(config->base, true); + DAC_SetData(config->base, value); + + return 0; +} + +static int mcux_lpdac_init(const struct device *dev) +{ + return 0; +} + +static const struct dac_driver_api mcux_lpdac_driver_api = { + .channel_setup = mcux_lpdac_channel_setup, + .write_value = mcux_lpdac_write_value, +}; + +#define MCUX_LPDAC_INIT(n) \ + static struct mcux_lpdac_data mcux_lpdac_data_##n; \ + \ + static const struct mcux_lpdac_config mcux_lpdac_config_##n = { \ + .base = (LPDAC_Type *)DT_INST_REG_ADDR(n), \ + .ref_voltage = DT_INST_PROP(n, voltage_reference), \ + .low_power = DT_INST_PROP(n, low_power_mode), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, mcux_lpdac_init, NULL, &mcux_lpdac_data_##n, \ + &mcux_lpdac_config_##n, POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \ + &mcux_lpdac_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MCUX_LPDAC_INIT) diff --git a/dts/bindings/dac/nxp,lpdac.yaml b/dts/bindings/dac/nxp,lpdac.yaml new file mode 100644 index 00000000000..2a79af254b7 --- /dev/null +++ b/dts/bindings/dac/nxp,lpdac.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2023, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCUX LPDAC + +compatible: "nxp,lpdac" + +include: dac-controller.yaml + +properties: + reg: + required: true + + voltage-reference: + type: int + required: true + description: | + DAC voltage reference select. The meaning of the value may be + different for different SoCs. + + low-power-mode: + type: boolean + description: Enable low-power mode + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - output From 2073dc9cddffa957fd4f0874b40c827af80a3041 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Thu, 7 Sep 2023 16:38:44 +0800 Subject: [PATCH 0185/4498] boards: arm: lpcxpresso55s36: Added dac support for LPC55S36 Added dac support for the LPC55S36 board, updated lpc55xxx/soc.c to enable clock and power for dac0. Signed-off-by: Albort Xue --- boards/arm/lpcxpresso55s36/doc/index.rst | 2 ++ .../lpcxpresso55s36-pinctrl.dtsi | 10 +++++- .../arm/lpcxpresso55s36/lpcxpresso55s36.dts | 6 ++++ .../arm/lpcxpresso55s36/lpcxpresso55s36.yaml | 1 + dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 27 ++++++++++++++++ soc/arm/nxp_lpc/lpc55xxx/soc.c | 31 +++++++++++++------ 6 files changed, 66 insertions(+), 11 deletions(-) diff --git a/boards/arm/lpcxpresso55s36/doc/index.rst b/boards/arm/lpcxpresso55s36/doc/index.rst index d25bf7776c3..e35e285ff6c 100644 --- a/boards/arm/lpcxpresso55s36/doc/index.rst +++ b/boards/arm/lpcxpresso55s36/doc/index.rst @@ -81,6 +81,8 @@ already supported, which can also be re-used on this lpcxpresso55s36 board: +-----------+------------+-------------------------------------+ | USB FS | on-chip | USB Full Speed device | +-----------+------------+-------------------------------------+ +| DAC | on-chip | dac | ++-----------+------------+-------------------------------------+ Other hardware features are not currently enabled. diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi b/boards/arm/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi index 2d68da1d13f..8ca6f659f2e 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi @@ -2,7 +2,7 @@ * NOTE: File generated by lpc_cfg_utils.py * from LPC55S36.mex * - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -119,4 +119,12 @@ slew-rate = "standard"; }; }; + + pinmux_dac0: pinmux_dac0 { + group0 { + pinmux = ; + slew-rate = "standard"; + nxp,analog-mode; + }; + }; }; diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts index 98713617fdb..df4fbbdc99b 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts @@ -175,3 +175,9 @@ zephyr_udc0: &usbfs { &dma0 { status = "okay"; }; + +&dac0 { + status = "okay"; + pinctrl-0 = <&pinmux_dac0>; + pinctrl-names = "default"; +}; diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml index 823e4d3aeab..499536b1e80 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml @@ -18,3 +18,4 @@ supported: - can - gpio - pwm + - dac diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 51243bcb88e..2d834ff6b80 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -294,6 +294,33 @@ dma-names = "adc0-dma0", "adc0-dma1"; }; + dac0: dac@b2000 { + compatible = "nxp,lpdac"; + reg = < 0xb2000 0x1000>; + interrupts = <74 0>; + status = "disabled"; + voltage-reference = <0>; + #io-channel-cells = <1>; + }; + + dac1: dac@b6000 { + compatible = "nxp,lpdac"; + reg = < 0xb6000 0x1000>; + interrupts = <75 0>; + status = "disabled"; + voltage-reference = <0>; + #io-channel-cells = <1>; + }; + + dac2: dac@b9000 { + compatible = "nxp,lpdac"; + reg = < 0xb9000 0x1000>; + interrupts = <76 0>; + status = "disabled"; + voltage-reference = <0>; + #io-channel-cells = <1>; + }; + can0: can@4009d000 { compatible = "nxp,lpc-mcan"; reg = <0x4009d000 0x1000>; diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index cd3995764c6..8f756b39c3d 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -31,7 +31,8 @@ #include "usb_phy.h" #include "usb.h" #endif -#if defined(CONFIG_SOC_LPC55S36) && defined(CONFIG_ADC_MCUX_LPADC) +#if defined(CONFIG_SOC_LPC55S36) && (defined(CONFIG_ADC_MCUX_LPADC) \ + || defined(CONFIG_DAC_MCUX_LPDAC)) #include #endif @@ -322,8 +323,26 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) #if defined(CONFIG_SOC_LPC55S36) CLOCK_SetClkDiv(kCLOCK_DivAdc0Clk, 2U, true); CLOCK_AttachClk(kFRO_HF_to_ADC0); +#else + CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, + DT_PROP(DT_NODELABEL(adc0), clk_divider), true); + CLOCK_AttachClk(MUX_A(CM_ADCASYNCCLKSEL, DT_PROP(DT_NODELABEL(adc0), clk_source))); -#if defined(CONFIG_ADC_MCUX_LPADC) + /* Power up the ADC */ + POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC); +#endif +#endif +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(dac0), nxp_lpdac, okay) +#if defined(CONFIG_SOC_LPC55S36) + CLOCK_SetClkDiv(kCLOCK_DivDac0Clk, 1U, true); + CLOCK_AttachClk(kMAIN_CLK_to_DAC0); + + /* Disable DAC0 power down */ + POWER_DisablePD(kPDRUNCFG_PD_DAC0); +#endif +#endif +#if defined(CONFIG_SOC_LPC55S36) +#if (defined(CONFIG_ADC_MCUX_LPADC) || defined(CONFIG_DAC_MCUX_LPDAC)) /* Vref is required for LPADC reference */ POWER_DisablePD(kPDRUNCFG_PD_VREF); @@ -335,14 +354,6 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) vrefConfig.enableVrefOut = true; VREF_Init((VREF_Type *)VREF_BASE, &vrefConfig); #endif -#else - CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, - DT_PROP(DT_NODELABEL(adc0), clk_divider), true); - CLOCK_AttachClk(MUX_A(CM_ADCASYNCCLKSEL, DT_PROP(DT_NODELABEL(adc0), clk_source))); - - /* Power up the ADC */ - POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC); -#endif #endif } From f5220bd5d1565fcb2a9ea65dfd93083ee8fb1798 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Thu, 7 Sep 2023 16:40:24 +0800 Subject: [PATCH 0186/4498] samples: drivers: dac: Enable dac example on lpcxpresso55s36 board Added overlay for lpcxpresso55s36, updated README.rst Signed-off-by: Albort Xue --- samples/drivers/dac/README.rst | 13 +++++++++++++ samples/drivers/dac/boards/lpcxpresso55s36.overlay | 13 +++++++++++++ samples/drivers/dac/sample.yaml | 1 + 3 files changed, 27 insertions(+) create mode 100644 samples/drivers/dac/boards/lpcxpresso55s36.overlay diff --git a/samples/drivers/dac/README.rst b/samples/drivers/dac/README.rst index 0075f8f9f67..bfde230a1c6 100644 --- a/samples/drivers/dac/README.rst +++ b/samples/drivers/dac/README.rst @@ -209,6 +209,19 @@ also can run for the :goals: build flash :compact: +Building and Running for NXP LPCXpresso55S36 +============================================ +The sample can be built and executed for the :ref:`lpcxpresso55s36` as +follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/dac + :board: lpcxpresso55s36 + :goals: build flash + :compact: + +DAC output is available on connector J12 pin 4. + Sample output ============= diff --git a/samples/drivers/dac/boards/lpcxpresso55s36.overlay b/samples/drivers/dac/boards/lpcxpresso55s36.overlay new file mode 100644 index 00000000000..a3698266744 --- /dev/null +++ b/samples/drivers/dac/boards/lpcxpresso55s36.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/sample.yaml b/samples/drivers/dac/sample.yaml index 7a2c0d0a4e9..8ac2943ecfc 100644 --- a/samples/drivers/dac/sample.yaml +++ b/samples/drivers/dac/sample.yaml @@ -42,6 +42,7 @@ tests: - stm32f3_disco - stm32l562e_dk - twr_ke18f + - lpcxpresso55s36 depends_on: dac integration_platforms: - nucleo_l152re From 4d9fb55d5e70d7df8c6c367f5e77832426d26be7 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Thu, 7 Sep 2023 16:41:27 +0800 Subject: [PATCH 0187/4498] tests: drivers: dac: Verify dac on lpcxpresso55s36 board Added overlay for lpcxpresso55s36 to verify dac driver. Signed-off-by: Albort Xue --- tests/drivers/dac/dac_api/src/test_dac.c | 3 ++- .../boards/lpcxpresso55s36.overlay | 10 ++++++++++ tests/drivers/dac/dac_loopback/src/test_dac.c | 19 ++++++++++++++++++- tests/drivers/dac/dac_loopback/testcase.yaml | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/dac/dac_loopback/boards/lpcxpresso55s36.overlay diff --git a/tests/drivers/dac/dac_api/src/test_dac.c b/tests/drivers/dac/dac_api/src/test_dac.c index 491fc61a317..71824f4fd9d 100644 --- a/tests/drivers/dac/dac_api/src/test_dac.c +++ b/tests/drivers/dac/dac_api/src/test_dac.c @@ -45,7 +45,8 @@ defined(CONFIG_BOARD_FRDM_K22F) || \ defined(CONFIG_BOARD_SEEEDUINO_XIAO) || \ defined(CONFIG_BOARD_ARDUINO_MKRZERO) || \ - defined(CONFIG_BOARD_ARDUINO_ZERO) + defined(CONFIG_BOARD_ARDUINO_ZERO) || \ + defined(CONFIG_BOARD_LPCXPRESSO55S36) #define DAC_DEVICE_NODE DT_NODELABEL(dac0) #define DAC_RESOLUTION 12 diff --git a/tests/drivers/dac/dac_loopback/boards/lpcxpresso55s36.overlay b/tests/drivers/dac/dac_loopback/boards/lpcxpresso55s36.overlay new file mode 100644 index 00000000000..4c56612e5b6 --- /dev/null +++ b/tests/drivers/dac/dac_loopback/boards/lpcxpresso55s36.overlay @@ -0,0 +1,10 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dac0 { + /* To align reference voltage with ADC. */ + voltage-reference = <1>; +}; diff --git a/tests/drivers/dac/dac_loopback/src/test_dac.c b/tests/drivers/dac/dac_loopback/src/test_dac.c index dff32bbfba2..9b571bf384c 100644 --- a/tests/drivers/dac/dac_loopback/src/test_dac.c +++ b/tests/drivers/dac/dac_loopback/src/test_dac.c @@ -125,6 +125,22 @@ #define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT #define ADC_CHANNEL_ID 23 +#elif defined(CONFIG_BOARD_LPCXPRESSO55S36) + +/* DAC0 output is internally available on ADC0_SE4 */ + +#define DAC_DEVICE_NODE DT_NODELABEL(dac0) +#define DAC_RESOLUTION 12 +#define DAC_CHANNEL_ID 0 + +#define ADC_DEVICE_NODE DT_NODELABEL(adc0) +#define ADC_RESOLUTION 12 +#define ADC_GAIN ADC_GAIN_1 +#define ADC_REFERENCE ADC_REF_EXTERNAL0 +#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT +#define ADC_CHANNEL_ID 0 +#define ADC_1ST_CHANNEL_INPUT 4 + #elif defined(CONFIG_BOARD_BL652_DVK) || \ defined(CONFIG_BOARD_BL653_DVK) || \ defined(CONFIG_BOARD_BL654_DVK) || \ @@ -168,7 +184,8 @@ static const struct adc_channel_cfg adc_ch_cfg = { #if defined(CONFIG_BOARD_BL652_DVK) || \ defined(CONFIG_BOARD_BL653_DVK) || \ defined(CONFIG_BOARD_BL654_DVK) || \ - defined(CONFIG_BOARD_BL5340_DVK_CPUAPP) + defined(CONFIG_BOARD_BL5340_DVK_CPUAPP) || \ + defined(CONFIG_BOARD_LPCXPRESSO55S36) .input_positive = ADC_1ST_CHANNEL_INPUT, #endif }; diff --git a/tests/drivers/dac/dac_loopback/testcase.yaml b/tests/drivers/dac/dac_loopback/testcase.yaml index fe1962e5b2f..f1a682f2f5b 100644 --- a/tests/drivers/dac/dac_loopback/testcase.yaml +++ b/tests/drivers/dac/dac_loopback/testcase.yaml @@ -28,5 +28,6 @@ tests: - nucleo_f746zg - nucleo_g071rb - nucleo_wl55jc + - lpcxpresso55s36 integration_platforms: - nucleo_f207zg From 48a09e5b4f55115da88a0c617d51a53ccf3512d1 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 29 Aug 2023 13:58:17 +0200 Subject: [PATCH 0188/4498] dts: bindings: can: add binding for ti,tcan4x5x Add devicetree binding for the TI TCAN4x5x series of CAN controllers. These CAN controllers are based on the Bosch M_CAN IP and interfaced via a SPI bus. Signed-off-by: Henrik Brix Andersen --- dts/bindings/can/ti,tcan4x5x.yaml | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dts/bindings/can/ti,tcan4x5x.yaml diff --git a/dts/bindings/can/ti,tcan4x5x.yaml b/dts/bindings/can/ti,tcan4x5x.yaml new file mode 100644 index 00000000000..7434da00613 --- /dev/null +++ b/dts/bindings/can/ti,tcan4x5x.yaml @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Vestas Wind Systems A/S +# SPDX-License-Identifier: Apache-2.0 + +description: | + Texas Instruments TCAN4x5x SPI CAN-FD controller. + + Example: + &spi0 { + tcan4x5x: can@0 { + compatible = ti,tcan4x5x"; + reg = <0>; + spi-max-frequency = <18000000>; + clock-frequency = <40000000>; + device-state-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + device-wake-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; + sjw = <1>; + sjw-data = <1>; + sample-point = <875>; + sample-point-data = <875>; + bus-speed = <125000>; + bus-speed-data = <1000000>; + status = "okay"; + + can-transceiver { + max-bitrate = <8000000>; + }; + }; + }; + +compatible: "ti,tcan4x5x" + +include: ["bosch,m_can-base.yaml", "spi-device.yaml"] + +properties: + clock-frequency: + type: int + enum: + - 20000000 + - 40000000 + required: true + description: | + TCAN4x5x oscillator clock frequency in Hz (20MHz or 40MHz). + + device-state-gpios: + type: phandle-array + description: | + GPIO connected to the TCAN4x5x nWKRQ output. This signal is active low. + + device-wake-gpios: + type: phandle-array + description: | + GPIO connected to the TCAN4x5x WAKE input. This signal is high-voltage, active high. + + reset-gpios: + type: phandle-array + description: | + GPIO connected to the TCAN4x5x RST input. This signal is active high. + + int-gpios: + type: phandle-array + required: true + description: | + GPIO connected to the TCAN4x5x nINT interrupt output. This signal is open-drain, active low. From 9bd62f16b6907584fd206aa93a1f13e1692c6c6a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 29 Aug 2023 13:54:03 +0200 Subject: [PATCH 0189/4498] drivers: can: add tcan4x5x CAN controller driver Add driver for the TI TCAN4x5x series of CAN controllers. These CAN controllers are based on the Bosch M_CAN IP and interfaced via an SPI bus. Signed-off-by: Henrik Brix Andersen --- drivers/can/CMakeLists.txt | 1 + drivers/can/Kconfig | 1 + drivers/can/Kconfig.tcan4x5x | 29 ++ drivers/can/can_tcan4x5x.c | 796 +++++++++++++++++++++++++++++++++++ 4 files changed, 827 insertions(+) create mode 100644 drivers/can/Kconfig.tcan4x5x create mode 100644 drivers/can/can_tcan4x5x.c diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 4c97d22265c..df2a013c8aa 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -16,6 +16,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_SAM0 can_sam0.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32_BXCAN can_stm32_bxcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32_FDCAN can_stm32_fdcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32H7_FDCAN can_stm32h7_fdcan.c) +zephyr_library_sources_ifdef(CONFIG_CAN_TCAN4X5X can_tcan4x5x.c) zephyr_library_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) if(CONFIG_CAN_NATIVE_POSIX_LINUX) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index ab8dcf94fe2..352192ba63f 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -99,6 +99,7 @@ source "drivers/can/Kconfig.esp32" source "drivers/can/Kconfig.kvaser" source "drivers/can/Kconfig.fake" source "drivers/can/Kconfig.nxp_s32" +source "drivers/can/Kconfig.tcan4x5x" source "drivers/can/transceiver/Kconfig" diff --git a/drivers/can/Kconfig.tcan4x5x b/drivers/can/Kconfig.tcan4x5x new file mode 100644 index 00000000000..4eeddb35cc0 --- /dev/null +++ b/drivers/can/Kconfig.tcan4x5x @@ -0,0 +1,29 @@ +# TCAN4x5x configuration options + +# Copyright (c) 2023 Vestas Wind Systems A/S +# SPDX-License-Identifier: Apache-2.0 + +config CAN_TCAN4X5X + bool "TI TCAN4x5x" + default y + depends on DT_HAS_TI_TCAN4X5X_ENABLED + select CAN_MCAN + select SPI + help + Enable support for the Texas Instruments TCAN4x5x. + +if CAN_TCAN4X5X + +config CAN_TCAN4X5X_THREAD_STACK_SIZE + int "Stack size for the TCAN4x5x interrupt thread" + default 1024 + help + Size of the stack used for the thread handling interrupts and dispatching callbacks. + +config CAN_TCAN4X5X_THREAD_PRIO + int "Priority for the TCAN4x5x interrupt thread" + default 0 + help + Priority level for the thread handling interrupts and dispatching callbacks. + +endif # CAN_TCAN4X5X diff --git a/drivers/can/can_tcan4x5x.c b/drivers/can/can_tcan4x5x.c new file mode 100644 index 00000000000..e303244b0e5 --- /dev/null +++ b/drivers/can/can_tcan4x5x.c @@ -0,0 +1,796 @@ +/* + * Copyright (c) 2023 Vestas Wind Systems A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(can_tcan4x5x, CONFIG_CAN_LOG_LEVEL); + +#define DT_DRV_COMPAT ti_tcan4x5x + +/* + * The register definitions correspond to those found in the TI TCAN4550-Q1 datasheet, revision D + * June 2022 (SLLSEZ5D). + */ + +/* Device ID1 register */ +#define CAN_TCAN4X5X_DEVICE_ID1 0x0000 + +/* Device ID2 register */ +#define CAN_TCAN4X5X_DEVICE_ID2 0x0004 + +/* Revision register */ +#define CAN_TCAN4X5X_REVISION 0x0008 +#define CAN_TCAN4X5X_REVISION_SPI_2_REVISION GENMASK(31, 24) +#define CAN_TCAN4X5X_REVISION_REV_ID_MAJOR GENMASK(15, 8) +#define CAN_TCAN4X5X_REVISION_REV_ID_MINOR GENMASK(7, 0) + +/* Status register */ +#define CAN_TCAN4X5X_STATUS 0x000c +#define CAN_TCAN4X5X_STATUS_INTERNAL_READ_ERROR BIT(29) +#define CAN_TCAN4X5X_STATUS_INTERNAL_WRITE_ERROR BIT(28) +#define CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_LOG_WRITE BIT(27) +#define CAN_TCAN4X5X_STATUS_READ_FIFO_UNDERFLOW BIT(26) +#define CAN_TCAN4X5X_STATUS_READ_FIFO_EMPTY BIT(25) +#define CAN_TCAN4X5X_STATUS_WRITE_FIFO_OVERFLOW BIT(24) +#define CAN_TCAN4X5X_STATUS_SPI_END_ERROR BIT(21) +#define CAN_TCAN4X5X_STATUS_INVALID_COMMAND BIT(20) +#define CAN_TCAN4X5X_STATUS_WRITE_OVERFLOW BIT(19) +#define CAN_TCAN4X5X_STATUS_WRITE_UNDERFLOW BIT(18) +#define CAN_TCAN4X5X_STATUS_READ_OVERFLOW BIT(17) +#define CAN_TCAN4X5X_STATUS_READ_UNDERFLOW BIT(16) +#define CAN_TCAN4X5X_STATUS_WRITE_FIFO_AVAILABLE BIT(5) +#define CAN_TCAN4X5X_STATUS_READ_FIFO_AVAILABLE BIT(4) +#define CAN_TCAN4X5X_STATUS_INTERNAL_ACCESS_ACTIVE BIT(3) +#define CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_INTERRUPT BIT(2) +#define CAN_TCAN4X5X_STATUS_SPI_ERROR_INTERRUPT BIT(1) +#define CAN_TCAN4X5X_STATUS_INTERRUPT BIT(0) + +/* Mask of clearable status register bits */ +#define CAN_TCAN4X5X_STATUS_CLEAR_ALL \ + (CAN_TCAN4X5X_STATUS_INTERNAL_READ_ERROR | CAN_TCAN4X5X_STATUS_INTERNAL_WRITE_ERROR | \ + CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_LOG_WRITE | CAN_TCAN4X5X_STATUS_READ_FIFO_UNDERFLOW | \ + CAN_TCAN4X5X_STATUS_READ_FIFO_EMPTY | CAN_TCAN4X5X_STATUS_WRITE_FIFO_OVERFLOW | \ + CAN_TCAN4X5X_STATUS_SPI_END_ERROR | CAN_TCAN4X5X_STATUS_INVALID_COMMAND | \ + CAN_TCAN4X5X_STATUS_WRITE_OVERFLOW | CAN_TCAN4X5X_STATUS_WRITE_UNDERFLOW | \ + CAN_TCAN4X5X_STATUS_READ_OVERFLOW | CAN_TCAN4X5X_STATUS_READ_UNDERFLOW) + +/* SPI Error Status Mask register */ +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK 0x0010 +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_READ_ERROR BIT(29) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_WRITE_ERROR BIT(28) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_ERROR_LOG_WRITE BIT(27) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_FIFO_UNDERFLOW BIT(26) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_FIFO_EMPTY BIT(25) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_FIFO_OVERFLOW BIT(24) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_SPI_END_ERROR BIT(21) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INVALID_COMMAND BIT(20) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_OVERFLOW BIT(19) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_UNDERFLOW BIT(18) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_OVERFLOW BIT(17) +#define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_UNDERFLOW BIT(16) + +/* Modes of Operation and Pin Configurations register */ +#define CAN_TCAN4X5X_MODE_CONFIG 0x0800 +#define CAN_TCAN4X5X_MODE_CONFIG_WAKE_CONFIG GENMASK(31, 30) +#define CAN_TCAN4X5X_MODE_CONFIG_WD_TIMER GENMASK(29, 28) +#define CAN_TCAN4X5X_MODE_CONFIG_CLK_REF BIT(27) +#define CAN_TCAN4X5X_MODE_CONFIG_GPO2_CONFIG GENMASK(23, 22) +#define CAN_TCAN4X5X_MODE_CONFIG_TEST_MODE_EN BIT(21) +#define CAN_TCAN4X5X_MODE_CONFIG_NWKRQ_VOLTAGE BIT(19) +#define CAN_TCAN4X5X_MODE_CONFIG_WD_BIT_SET BIT(18) +#define CAN_TCAN4X5X_MODE_CONFIG_WD_ACTION GENMASK(17, 16) +#define CAN_TCAN4X5X_MODE_CONFIG_GPIO1_CONFIG GENMASK(15, 14) +#define CAN_TCAN4X5X_MODE_CONFIG_FAIL_SAFE_EN BIT(13) +#define CAN_TCAN4X5X_MODE_CONFIG_GPIO1_GPO_CONFIG GENMASK(11, 10) +#define CAN_TCAN4X5X_MODE_CONFIG_INH_DIS BIT(9) +#define CAN_TCAN4X5X_MODE_CONFIG_NWKRQ_CONFIG BIT(8) +#define CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL GENMASK(7, 6) +#define CAN_TCAN4X5X_MODE_CONFIG_WD_EN BIT(3) +#define CAN_TCAN4X5X_MODE_CONFIG_DEVICE_RESET BIT(2) +#define CAN_TCAN4X5X_MODE_CONFIG_SWE_DIS BIT(1) +#define CAN_TCAN4X5X_MODE_CONFIG_TEST_MODE_CONFIG BIT(0) + +/* Timestamp Prescaler register */ +#define CAN_TCAN4X5X_TIMESTAMP_PRESCALER 0x0804 +#define CAN_TCAN4X5X_TIMESTAMP_PRESCALER_MASK GENMASK(7, 0) + +/* Test Register and Scratch Pad */ +#define CAN_TCAN4X5X_TEST_SCRATCH_PAD 0x0808 +#define CAN_TCAN4X5X_TEST_SCRATCH_PAD_READ_WRITE GENMASK(31, 16) +#define CAN_TCAN4X5X_TEST_SCRATCH_PAD_SCRATCH_PAD GENMASK(15, 0) + +/* Test register */ +#define CAN_TCAN4X5X_TEST 0x0808 +#define CAN_TCAN4X5X_TEST_ECC_ERR_FORCE_BIT_SEL GENMASK(21, 16) +#define CAN_TCAN4X5X_TEST_ECC_ERR_FORCE BIT(12) +#define CAN_TCAN4X5X_TEST_ECC_ERR_CHECK BIT(11) + +/* Interrupts register */ +#define CAN_TCAN4X5X_IR 0x0820 +#define CAN_TCAN4X5X_IR_CANBUSNOM BIT(31) +#define CAN_TCAN4X5X_IR_SMS BIT(23) +#define CAN_TCAN4X5X_IR_UVSUP BIT(22) +#define CAN_TCAN4X5X_IR_UVIO BIT(21) +#define CAN_TCAN4X5X_IR_PWRON BIT(20) +#define CAN_TCAN4X5X_IR_TSD BIT(19) +#define CAN_TCAN4X5X_IR_WDTO BIT(18) +#define CAN_TCAN4X5X_IR_ECCERR BIT(16) +#define CAN_TCAN4X5X_IR_CANINT BIT(15) +#define CAN_TCAN4X5X_IR_LWU BIT(14) +#define CAN_TCAN4X5X_IR_WKERR BIT(13) +#define CAN_TCAN4X5X_IR_CANSLNT BIT(10) +#define CAN_TCAN4X5X_IR_CANDOM BIT(8) +#define CAN_TCAN4X5X_IR_GLOBALERR BIT(7) +#define CAN_TCAN4X5X_IR_WKRQ BIT(6) +#define CAN_TCAN4X5X_IR_CANERR BIT(5) +#define CAN_TCAN4X5X_IR_SPIERR BIT(3) +#define CAN_TCAN4X5X_IR_M_CAN_INT BIT(1) +#define CAN_TCAN4X5X_IR_VTWD BIT(0) + +/* Mask of clearable interrupts register bits */ +#define CAN_TCAN4X5X_IR_CLEAR_ALL \ + (CAN_TCAN4X5X_IR_SMS | CAN_TCAN4X5X_IR_UVSUP | CAN_TCAN4X5X_IR_UVIO | \ + CAN_TCAN4X5X_IR_PWRON | CAN_TCAN4X5X_IR_TSD | CAN_TCAN4X5X_IR_WDTO | \ + CAN_TCAN4X5X_IR_ECCERR | CAN_TCAN4X5X_IR_CANINT | CAN_TCAN4X5X_IR_LWU | \ + CAN_TCAN4X5X_IR_WKERR | CAN_TCAN4X5X_IR_CANSLNT | CAN_TCAN4X5X_IR_CANDOM) + +/* MCAN Interrupts register */ +#define CAN_TCAN4X5X_MCAN_IR 0x0824 +#define CAN_TCAN4X5X_MCAN_IR_ARA BIT(29) +#define CAN_TCAN4X5X_MCAN_IR_PED BIT(28) +#define CAN_TCAN4X5X_MCAN_IR_PEA BIT(27) +#define CAN_TCAN4X5X_MCAN_IR_WDI BIT(26) +#define CAN_TCAN4X5X_MCAN_IR_BO BIT(25) +#define CAN_TCAN4X5X_MCAN_IR_EW BIT(24) +#define CAN_TCAN4X5X_MCAN_IR_EP BIT(23) +#define CAN_TCAN4X5X_MCAN_IR_ELO BIT(22) +#define CAN_TCAN4X5X_MCAN_IR_BEU BIT(21) +#define CAN_TCAN4X5X_MCAN_IR_BEC BIT(20) +#define CAN_TCAN4X5X_MCAN_IR_DRX BIT(19) +#define CAN_TCAN4X5X_MCAN_IR_TOO BIT(18) +#define CAN_TCAN4X5X_MCAN_IR_MRAF BIT(17) +#define CAN_TCAN4X5X_MCAN_IR_TSW BIT(16) +#define CAN_TCAN4X5X_MCAN_IR_TEFL BIT(15) +#define CAN_TCAN4X5X_MCAN_IR_TEFF BIT(14) +#define CAN_TCAN4X5X_MCAN_IR_TEFW BIT(13) +#define CAN_TCAN4X5X_MCAN_IR_TEFN BIT(12) +#define CAN_TCAN4X5X_MCAN_IR_TFE BIT(11) +#define CAN_TCAN4X5X_MCAN_IR_TCF BIT(10) +#define CAN_TCAN4X5X_MCAN_IR_TC BIT(9) +#define CAN_TCAN4X5X_MCAN_IR_HPM BIT(8) +#define CAN_TCAN4X5X_MCAN_IR_RF1L BIT(7) +#define CAN_TCAN4X5X_MCAN_IR_RF1F BIT(6) +#define CAN_TCAN4X5X_MCAN_IR_RF1W BIT(5) +#define CAN_TCAN4X5X_MCAN_IR_RF1N BIT(4) +#define CAN_TCAN4X5X_MCAN_IR_RF0L BIT(3) +#define CAN_TCAN4X5X_MCAN_IR_RF0F BIT(2) +#define CAN_TCAN4X5X_MCAN_IR_RF0W BIT(1) +#define CAN_TCAN4X5X_MCAN_IR_RF0N BIT(0) + +/* Interrupt Enables register */ +#define CAN_TCAN4X5X_IE 0x0830 +#define CAN_TCAN4X5X_IE_UVSUP BIT(22) +#define CAN_TCAN4X5X_IE_UVIO BIT(21) +#define CAN_TCAN4X5X_IE_TSD BIT(19) +#define CAN_TCAN4X5X_IE_ECCERR BIT(16) +#define CAN_TCAN4X5X_IE_CANINT BIT(15) +#define CAN_TCAN4X5X_IE_LWU BIT(14) +#define CAN_TCAN4X5X_IE_CANSLNT BIT(10) +#define CAN_TCAN4X5X_IE_CANDOM BIT(8) + +/* Bosch M_CAN registers base address */ +#define CAN_TCAN4X5X_MCAN_BASE 0x1000 + +/* Bosch M_CAN Message RAM base address and size */ +#define CAN_TCAN4X5X_MRAM_BASE 0x8000 +#define CAN_TCAN4X5X_MRAM_SIZE 2048 + +/* TCAN4x5x SPI OP codes */ +#define CAN_TCAN4X5X_WRITE_B_FL 0x61 +#define CAN_TCAN4X5X_READ_B_FL 0x41 + +/* TCAN4x5x timing requirements */ +#define CAN_TCAN4X5X_T_MODE_STBY_NOM_US 70 +#define CAN_TCAN4X5X_T_WAKE_US 50 +#define CAN_TCAN4X5X_T_PULSE_WIDTH_US 30 +#define CAN_TCAN4X5X_T_RESET_US 1000 + +/* + * Only compile in support for the optional GPIOs if at least one enabled tcan4x5x device tree node + * has them. Only the INT GPIO is required. + */ +#define TCAN4X5X_RST_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define TCAN4X5X_NWKRQ_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(device_state_gpios) +#define TCAN4X5X_WAKE_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(device_wake_gpios) + +struct tcan4x5x_config { + struct spi_dt_spec spi; +#if TCAN4X5X_RST_GPIO_SUPPORT + struct gpio_dt_spec rst_gpio; +#endif /* TCAN4X5X_RST_GPIO_SUPPORT */ +#if TCAN4X5X_NWKRQ_GPIO_SUPPORT + struct gpio_dt_spec nwkrq_gpio; +#endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */ +#if TCAN4X5X_WAKE_GPIO_SUPPORT + struct gpio_dt_spec wake_gpio; +#endif /* TCAN4X5X_WAKE_GPIO_SUPPORT */ + struct gpio_dt_spec int_gpio; + uint32_t clk_freq; +}; + +struct tcan4x5x_data { + struct gpio_callback int_gpio_cb; + struct k_thread int_thread; + struct k_sem int_sem; + + K_KERNEL_STACK_MEMBER(int_stack, CONFIG_CAN_TCAN4X5X_THREAD_STACK_SIZE); +}; + +static int tcan4x5x_read(const struct device *dev, uint16_t addr, void *dst, size_t len) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + size_t len32 = len / sizeof(uint32_t); + uint32_t *dst32 = (uint32_t *)dst; + uint8_t cmd[4] = {CAN_TCAN4X5X_READ_B_FL, addr >> 8U & 0xFF, addr & 0xFF, + len32 == 256 ? 0U : len32}; + uint8_t global_status; + const struct spi_buf tx_bufs[] = { + {.buf = &cmd, .len = sizeof(cmd)}, + }; + const struct spi_buf rx_bufs[] = { + {.buf = &global_status, .len = sizeof(global_status)}, + {.buf = NULL, .len = 3}, + {.buf = dst, .len = len}, + }; + const struct spi_buf_set tx = { + .buffers = tx_bufs, + .count = ARRAY_SIZE(tx_bufs), + }; + const struct spi_buf_set rx = { + .buffers = rx_bufs, + .count = ARRAY_SIZE(rx_bufs), + }; + int err; + int i; + + if (len == 0) { + return 0; + } + + /* Maximum transfer size is 256 32-bit words */ + __ASSERT_NO_MSG(len % 4 == 0); + __ASSERT_NO_MSG(len32 <= 256); + + err = spi_transceive_dt(&tcan_config->spi, &tx, &rx); + if (err != 0) { + LOG_ERR("failed to read addr %u, len %d (err %d)", addr, len, err); + return err; + } + + __ASSERT_NO_MSG((global_status & CAN_TCAN4X5X_IR_SPIERR) == 0U); + + for (i = 0; i < len32; i++) { + dst32[i] = sys_be32_to_cpu(dst32[i]); + } + + return 0; +} + +static int tcan4x5x_write(const struct device *dev, uint16_t addr, const void *src, size_t len) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + size_t len32 = len / sizeof(uint32_t); + uint32_t src32[len32]; + uint8_t cmd[4] = {CAN_TCAN4X5X_WRITE_B_FL, addr >> 8U & 0xFF, addr & 0xFF, + len32 == 256 ? 0U : len32}; + uint8_t global_status; + const struct spi_buf tx_bufs[] = { + {.buf = &cmd, .len = sizeof(cmd)}, + {.buf = &src32, .len = len}, + }; + const struct spi_buf rx_bufs[] = { + {.buf = &global_status, .len = sizeof(global_status)}, + }; + const struct spi_buf_set tx = { + .buffers = tx_bufs, + .count = ARRAY_SIZE(tx_bufs), + }; + const struct spi_buf_set rx = { + .buffers = rx_bufs, + .count = ARRAY_SIZE(rx_bufs), + }; + int err; + int i; + + if (len == 0) { + return 0; + } + + /* Maximum transfer size is 256 32-bit words */ + __ASSERT_NO_MSG(len % 4 == 0); + __ASSERT_NO_MSG(len32 <= 256); + + for (i = 0; i < len32; i++) { + src32[i] = sys_cpu_to_be32(((uint32_t *)src)[i]); + } + + err = spi_transceive_dt(&tcan_config->spi, &tx, &rx); + if (err != 0) { + LOG_ERR("failed to write addr %u, len %d (err %d)", addr, len, err); + return err; + } + + __ASSERT_NO_MSG((global_status & CAN_TCAN4X5X_IR_SPIERR) == 0U); + + return 0; +} + +static inline int tcan4x5x_read_tcan_reg(const struct device *dev, uint16_t reg, uint32_t *val) +{ + return tcan4x5x_read(dev, reg, val, sizeof(uint32_t)); +} + +static inline int tcan4x5x_write_tcan_reg(const struct device *dev, uint16_t reg, uint32_t val) +{ + return tcan4x5x_write(dev, reg, &val, sizeof(uint32_t)); +} + +static int tcan4x5x_read_mcan_reg(const struct device *dev, uint16_t reg, uint32_t *val) +{ + return tcan4x5x_read(dev, CAN_TCAN4X5X_MCAN_BASE + reg, val, sizeof(uint32_t)); +} + +static int tcan4x5x_write_mcan_reg(const struct device *dev, uint16_t reg, uint32_t val) +{ + return tcan4x5x_write(dev, CAN_TCAN4X5X_MCAN_BASE + reg, &val, sizeof(uint32_t)); +} + +static int tcan4x5x_read_mcan_mram(const struct device *dev, uint16_t offset, void *dst, size_t len) +{ + return tcan4x5x_read(dev, CAN_TCAN4X5X_MRAM_BASE + offset, dst, len); +} + +static int tcan4x5x_write_mcan_mram(const struct device *dev, uint16_t offset, const void *src, + size_t len) +{ + return tcan4x5x_write(dev, CAN_TCAN4X5X_MRAM_BASE + offset, src, len); +} + +static int tcan4x5x_clear_mcan_mram(const struct device *dev, uint16_t offset, size_t len) +{ + static const uint8_t buf[256] = {0}; + size_t pending; + size_t upto; + int err; + + for (upto = 0; upto < len; upto += pending) { + pending = MIN(len - upto, sizeof(buf)); + + err = tcan4x5x_write_mcan_mram(dev, offset, &buf, pending); + if (err != 0) { + LOG_ERR("failed to clear message RAM (err %d)", err); + return err; + } + + offset += pending; + } + + return 0; +} + +static int tcan4x5x_get_core_clock(const struct device *dev, uint32_t *rate) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + + *rate = tcan_config->clk_freq; + + return 0; +} + +static void tcan4x5x_int_gpio_callback_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ + struct tcan4x5x_data *tcan_data = CONTAINER_OF(cb, struct tcan4x5x_data, int_gpio_cb); + + k_sem_give(&tcan_data->int_sem); +} + +static void tcan4x5x_int_thread(const struct device *dev) +{ + struct can_mcan_data *mcan_data = dev->data; + struct tcan4x5x_data *tcan_data = mcan_data->custom; + uint32_t status; + uint32_t ir; + int err; + + while (true) { + k_sem_take(&tcan_data->int_sem, K_FOREVER); + + err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_IR, &ir); + if (err != 0) { + LOG_ERR("failed to read interrupt register (err %d)", err); + continue; + } + + while (ir != 0U) { + err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_IR, + ir & CAN_TCAN4X5X_IR_CLEAR_ALL); + if (err != 0) { + LOG_ERR("failed to write interrupt register (err %d)", err); + break; + } + + if ((ir & CAN_TCAN4X5X_IR_SPIERR) != 0U) { + err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_STATUS, &status); + if (err != 0) { + LOG_ERR("failed to read status register (err %d)", err); + continue; + } + + LOG_ERR("SPIERR, status = 0x%08x", status); + + err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_STATUS, status & + CAN_TCAN4X5X_STATUS_CLEAR_ALL); + if (err != 0) { + LOG_ERR("failed to write status register (err %d)", err); + continue; + } + } + + if ((ir & CAN_TCAN4X5X_IR_M_CAN_INT) != 0U) { + can_mcan_line_0_isr(dev); + can_mcan_line_1_isr(dev); + } + + err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_IR, &ir); + if (err != 0) { + LOG_ERR("failed to read interrupt register (err %d)", err); + break; + } + } + } +} + +static int tcan4x5x_wake(const struct device *dev) +{ +#if TCAN4X5X_WAKE_GPIO_SUPPORT + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + int wake_needed = 1; + int err; + +#if TCAN4X5X_NWKRQ_GPIO_SUPPORT + if (tcan_config->wake_gpio.port != NULL && tcan_config->nwkrq_gpio.port != NULL) { + wake_needed = gpio_pin_get_dt(&tcan_config->nwkrq_gpio); + + if (wake_needed < 0) { + LOG_ERR("failed to get nWKRQ status (err %d)", wake_needed); + return wake_needed; + }; + } +#endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */ + if (tcan_config->wake_gpio.port != NULL && wake_needed != 0) { + err = gpio_pin_set_dt(&tcan_config->wake_gpio, 1); + if (err != 0) { + LOG_ERR("failed to assert WAKE GPIO (err %d)", err); + return err; + } + + k_busy_wait(CAN_TCAN4X5X_T_WAKE_US); + + err = gpio_pin_set_dt(&tcan_config->wake_gpio, 0); + if (err != 0) { + LOG_ERR("failed to deassert WAKE GPIO (err %d)", err); + return err; + } + } +#endif /* TCAN4X5X_WAKE_GPIO_SUPPORT*/ + + return 0; +} + +static int tcan4x5x_reset(const struct device *dev) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + int err; + + err = tcan4x5x_wake(dev); + if (err != 0) { + return err; + } + +#if TCAN4X5X_RST_GPIO_SUPPORT + if (tcan_config->rst_gpio.port != NULL) { + err = gpio_pin_set_dt(&tcan_config->rst_gpio, 1); + if (err != 0) { + LOG_ERR("failed to assert RST GPIO (err %d)", err); + return err; + } + + k_busy_wait(CAN_TCAN4X5X_T_PULSE_WIDTH_US); + + err = gpio_pin_set_dt(&tcan_config->rst_gpio, 0); + if (err != 0) { + LOG_ERR("failed to deassert RST GPIO (err %d)", err); + return err; + } + } else { +#endif /* TCAN4X5X_RST_GPIO_SUPPORT */ + err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG, + CAN_TCAN4X5X_MODE_CONFIG_DEVICE_RESET); + if (err != 0) { + LOG_ERR("failed to initiate SW reset (err %d)", err); + return err; + } +#if TCAN4X5X_RST_GPIO_SUPPORT + } +#endif /* TCAN4X5X_RST_GPIO_SUPPORT */ + + k_busy_wait(CAN_TCAN4X5X_T_RESET_US); + + return 0; +} + +static int tcan4x5x_init(const struct device *dev) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct tcan4x5x_config *tcan_config = mcan_config->custom; + struct can_mcan_data *mcan_data = dev->data; + struct tcan4x5x_data *tcan_data = mcan_data->custom; + k_tid_t tid; + uint32_t reg; + int err; + + /* Initialize int_sem to 1 to ensure any pending IRQ is serviced */ + k_sem_init(&tcan_data->int_sem, 1, 1); + + if (!spi_is_ready_dt(&tcan_config->spi)) { + LOG_ERR("SPI bus not ready"); + return -ENODEV; + } + +#if TCAN4X5X_RST_GPIO_SUPPORT + if (tcan_config->rst_gpio.port != NULL) { + if (!gpio_is_ready_dt(&tcan_config->rst_gpio)) { + LOG_ERR("RST GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&tcan_config->rst_gpio, GPIO_OUTPUT_INACTIVE); + if (err != 0) { + LOG_ERR("failed to configure RST GPIO (err %d)", err); + return -ENODEV; + } + } +#endif /* TCAN4X5X_RST_GPIO_SUPPORT */ + +#if TCAN4X5X_NWKRQ_GPIO_SUPPORT + if (tcan_config->nwkrq_gpio.port != NULL) { + if (!gpio_is_ready_dt(&tcan_config->nwkrq_gpio)) { + LOG_ERR("nWKRQ GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&tcan_config->nwkrq_gpio, GPIO_INPUT); + if (err != 0) { + LOG_ERR("failed to configure nWKRQ GPIO (err %d)", err); + return -ENODEV; + } + } +#endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */ + +#if TCAN4X5X_WAKE_GPIO_SUPPORT + if (tcan_config->wake_gpio.port != NULL) { + if (!gpio_is_ready_dt(&tcan_config->wake_gpio)) { + LOG_ERR("WAKE GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&tcan_config->wake_gpio, GPIO_OUTPUT_INACTIVE); + if (err != 0) { + LOG_ERR("failed to configure WAKE GPIO (err %d)", err); + return -ENODEV; + } + } +#endif /* TCAN4X5X_WAKE_GPIO_SUPPORT */ + + if (!gpio_is_ready_dt(&tcan_config->int_gpio)) { + LOG_ERR("nINT GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&tcan_config->int_gpio, GPIO_INPUT); + if (err != 0) { + LOG_ERR("failed to configure nINT GPIO (err %d)", err); + return -ENODEV; + } + + gpio_init_callback(&tcan_data->int_gpio_cb, tcan4x5x_int_gpio_callback_handler, + BIT(tcan_config->int_gpio.pin)); + + err = gpio_add_callback_dt(&tcan_config->int_gpio, &tcan_data->int_gpio_cb); + if (err != 0) { + LOG_ERR("failed to add nINT GPIO callback (err %d)", err); + return -ENODEV; + } + + /* Initialize nINT GPIO callback and interrupt handler thread to ACK any early SPIERR */ + err = gpio_pin_interrupt_configure_dt(&tcan_config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (err != 0) { + LOG_ERR("failed to configure nINT GPIO interrupt (err %d)", err); + return -ENODEV; + } + + tid = k_thread_create(&tcan_data->int_thread, tcan_data->int_stack, + K_KERNEL_STACK_SIZEOF(tcan_data->int_stack), + (k_thread_entry_t)tcan4x5x_int_thread, (void *)dev, NULL, NULL, + CONFIG_CAN_TCAN4X5X_THREAD_PRIO, 0, K_NO_WAIT); + k_thread_name_set(tid, "tcan4x5x"); + + /* Reset TCAN */ + err = tcan4x5x_reset(dev); + if (err != 0) { + return -ENODEV; + } + +#if CONFIG_CAN_LOG_LEVEL >= LOG_LEVEL_DBG + uint32_t info[3]; + + /* Read DEVICE_ID1, DEVICE_ID2, and REVISION registers */ + err = tcan4x5x_read(dev, CAN_TCAN4X5X_DEVICE_ID1, &info, sizeof(info)); + if (err != 0) { + return -EIO; + } + + LOG_DBG("%c%c%c%c%c%c%c%c, SPI 2 rev. %lu, device rev. ID %lu.%lu", + (char)FIELD_GET(GENMASK(7, 0), info[0]), (char)FIELD_GET(GENMASK(15, 8), info[0]), + (char)FIELD_GET(GENMASK(23, 16), info[0]), + (char)FIELD_GET(GENMASK(31, 24), info[0]), (char)FIELD_GET(GENMASK(7, 0), info[1]), + (char)FIELD_GET(GENMASK(15, 8), info[1]), (char)FIELD_GET(GENMASK(23, 16), info[1]), + (char)FIELD_GET(GENMASK(31, 24), info[1]), FIELD_GET(GENMASK(31, 24), info[2]), + FIELD_GET(GENMASK(15, 8), info[2]), FIELD_GET(GENMASK(7, 0), info[2])); +#endif /* CONFIG_CAN_LOG_LEVEL >= LOG_LEVEL_DBG */ + + /* Set TCAN4x5x mode normal */ + err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG, ®); + if (err != 0) { + LOG_ERR("failed to read configuration register (err %d)", err); + return -ENODEV; + } + + reg &= ~(CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL); + reg |= FIELD_PREP(CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL, 0x02); + reg |= CAN_TCAN4X5X_MODE_CONFIG_WAKE_CONFIG; + + if (tcan_config->clk_freq == MHZ(20)) { + /* 20 MHz frequency reference */ + reg &= ~(CAN_TCAN4X5X_MODE_CONFIG_CLK_REF); + } else { + /* 40 MHz frequency reference */ + reg |= CAN_TCAN4X5X_MODE_CONFIG_CLK_REF; + } + + err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG, reg); + if (err != 0) { + LOG_ERR("failed to write configuration register (err %d)", err); + return -ENODEV; + } + + /* Wait for standby to normal mode switch */ + k_busy_wait(CAN_TCAN4X5X_T_MODE_STBY_NOM_US); + + /* Configure Message RAM */ + err = can_mcan_configure_mram(dev, CAN_TCAN4X5X_MRAM_BASE, CAN_TCAN4X5X_MRAM_BASE); + if (err != 0) { + return -EIO; + } + + /* Initialize M_CAN */ + err = can_mcan_init(dev); + if (err != 0) { + LOG_ERR("failed to initialize mcan (err %d)", err); + return err; + } + + return 0; +} + +static const struct can_driver_api tcan4x5x_driver_api = { + .get_capabilities = can_mcan_get_capabilities, + .start = can_mcan_start, + .stop = can_mcan_stop, + .set_mode = can_mcan_set_mode, + .set_timing = can_mcan_set_timing, + .send = can_mcan_send, + .add_rx_filter = can_mcan_add_rx_filter, + .remove_rx_filter = can_mcan_remove_rx_filter, +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY + .recover = can_mcan_recover, +#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */ + .get_state = can_mcan_get_state, + .set_state_change_callback = can_mcan_set_state_change_callback, + .get_core_clock = tcan4x5x_get_core_clock, + .get_max_filters = can_mcan_get_max_filters, + .get_max_bitrate = can_mcan_get_max_bitrate, + .timing_min = CAN_MCAN_TIMING_MIN_INITIALIZER, + .timing_max = CAN_MCAN_TIMING_MAX_INITIALIZER, +#ifdef CONFIG_CAN_FD_MODE + .set_timing_data = can_mcan_set_timing_data, + .timing_data_min = CAN_MCAN_TIMING_DATA_MIN_INITIALIZER, + .timing_data_max = CAN_MCAN_TIMING_DATA_MAX_INITIALIZER, +#endif /* CONFIG_CAN_FD_MODE */ +}; + +static const struct can_mcan_ops tcan4x5x_ops = { + .read_reg = tcan4x5x_read_mcan_reg, + .write_reg = tcan4x5x_write_mcan_reg, + .read_mram = tcan4x5x_read_mcan_mram, + .write_mram = tcan4x5x_write_mcan_mram, + .clear_mram = tcan4x5x_clear_mcan_mram, +}; + +#if TCAN4X5X_RST_GPIO_SUPPORT +#define TCAN4X5X_RST_GPIO_INIT(inst) \ + .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), +#else /* TCAN4X5X_RST_GPIO_SUPPORT */ +#define TCAN4X5X_RST_GPIO_INIT(inst) +#endif /* !TCAN4X5X_RST_GPIO_SUPPORT */ + +#if TCAN4X5X_NWKRQ_GPIO_SUPPORT +#define TCAN4X5X_NWKRQ_GPIO_INIT(inst) \ + .nwkrq_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, device_state_gpios, {0}), +#else /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */ +#define TCAN4X5X_NWKRQ_GPIO_INIT(inst) +#endif /* !TCAN4X5X_NWKRQ_GPIO_SUPPORT */ + +#if TCAN4X5X_WAKE_GPIO_SUPPORT +#define TCAN4X5X_WAKE_GPIO_INIT(inst) \ + .wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, device_wake_gpios, {0}), +#else /* TCAN4X5X_WAKE_GPIO_SUPPORT */ +#define TCAN4X5X_WAKE_GPIO_INIT(inst) +#endif /* !TCAN4X5X_WAKE_GPIO_SUPPORT */ + +#define TCAN4X5X_INIT(inst) \ + BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_OFFSET(inst) == 0, "MRAM offset must be 0"); \ + BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) <= CAN_TCAN4X5X_MRAM_SIZE, \ + "Insufficient Message RAM size to hold elements"); \ + \ + CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \ + CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, tcan4x5x_cbs_##inst); \ + \ + static const struct tcan4x5x_config tcan4x5x_config_##inst = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ + .int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + .clk_freq = DT_INST_PROP(inst, clock_frequency), \ + TCAN4X5X_RST_GPIO_INIT(inst) \ + TCAN4X5X_NWKRQ_GPIO_INIT(inst) \ + TCAN4X5X_WAKE_GPIO_INIT(inst) \ + }; \ + \ + static const struct can_mcan_config can_mcan_config_##inst = CAN_MCAN_DT_CONFIG_INST_GET( \ + inst, &tcan4x5x_config_##inst, &tcan4x5x_ops, &tcan4x5x_cbs_##inst); \ + \ + static struct tcan4x5x_data tcan4x5x_data_##inst; \ + \ + static struct can_mcan_data can_mcan_data_##inst = \ + CAN_MCAN_DATA_INITIALIZER(&tcan4x5x_data_##inst); \ + \ + DEVICE_DT_INST_DEFINE(inst, &tcan4x5x_init, NULL, &can_mcan_data_##inst, \ + &can_mcan_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &tcan4x5x_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TCAN4X5X_INIT) From 33167d3ad23e57a24485b8b951871d72ee22d2d0 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 29 Aug 2023 13:56:43 +0200 Subject: [PATCH 0190/4498] boards: shields: add TI TCAN4550 evaluation module Add shield definition for the TI TCAN4550EVM, an evaluation module for the TI TCAN4x5x CAN controller series. Signed-off-by: Henrik Brix Andersen --- MAINTAINERS.yml | 1 + boards/shields/tcan4550evm/Kconfig.shield | 5 ++ boards/shields/tcan4550evm/doc/index.rst | 68 ++++++++++++++++++ .../shields/tcan4550evm/doc/tcan4550evm.jpg | Bin 0 -> 67441 bytes .../shields/tcan4550evm/tcan4550evm.overlay | 43 +++++++++++ 5 files changed, 117 insertions(+) create mode 100644 boards/shields/tcan4550evm/Kconfig.shield create mode 100644 boards/shields/tcan4550evm/doc/index.rst create mode 100644 boards/shields/tcan4550evm/doc/tcan4550evm.jpg create mode 100644 boards/shields/tcan4550evm/tcan4550evm.overlay diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 51db64aa7ba..3dd26f34b23 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -713,6 +713,7 @@ Release Notes: - str4t0m files: - boards/shields/mcp2515/ + - boards/shields/tcan4550evm/ - doc/hardware/peripherals/canbus/ - drivers/can/ - drivers/net/canbus.c diff --git a/boards/shields/tcan4550evm/Kconfig.shield b/boards/shields/tcan4550evm/Kconfig.shield new file mode 100644 index 00000000000..f76fffe0bb5 --- /dev/null +++ b/boards/shields/tcan4550evm/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Vestas Wind Systems A/S +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_TCAN4550EVM + def_bool $(shields_list_contains,tcan4550evm) diff --git a/boards/shields/tcan4550evm/doc/index.rst b/boards/shields/tcan4550evm/doc/index.rst new file mode 100644 index 00000000000..73e167dcc49 --- /dev/null +++ b/boards/shields/tcan4550evm/doc/index.rst @@ -0,0 +1,68 @@ +.. _tcan4550evm_shield: + +Texas Instruments TCAN4550EVM +############################# + +Overview +******** + +The Texas Instruments `TCAN4550EVM`_ features a `TI TCAN4550-Q1`_ automotive system basis chip (SBC) +with integrated CAN FD controller & transceiver. + +.. figure:: tcan4550evm.jpg + :align: center + :alt: TCAN4550EVM + + TCAN4550EVM (Credit: Texas Instruments) + +Requirements +************ + +This shield can only be used with a board which provides a configuration for Arduino connectors and +defines node aliases for SPI and GPIO interfaces (see :ref:`shields` for more details). + +.. note:: + + This shield configuration limits the maximum SPI clock frequency to 2MHz although the + TCAN4550-Q1 supports up to 18MHz SPI clock frequency. This is done to accommodate the flywires + usually used for connecting the TCAN4550EVM to the board running Zephyr. + +Pin Assignments +=============== + ++-----------------------+---------------------------------------------+ +| Shield Connector Pin | Function | ++=======================+=============================================+ +| D6 | nWKRQ | ++-----------------------+---------------------------------------------+ +| D7 | WAKE_LV | ++-----------------------+---------------------------------------------+ +| D8 | RESET | ++-----------------------+---------------------------------------------+ +| D9 | nINT | ++-----------------------+---------------------------------------------+ +| D10 | nCS | ++-----------------------+---------------------------------------------+ +| D11 | SDI | ++-----------------------+---------------------------------------------+ +| D12 | SDO | ++-----------------------+---------------------------------------------+ +| D13 | SCLK | ++-----------------------+---------------------------------------------+ + +Programming +*********** + +Set ``-DSHIELD=tcan4550evm`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: tests/drivers/can/api + :board: frdm_k64f + :shield: tcan4550evm + :goals: build + +.. _TCAN4550EVM: + https://www.ti.com/tool/TCAN4550EVM + +.. _TI TCAN4550-Q1: + https://www.ti.com/product/TCAN4550-Q1 diff --git a/boards/shields/tcan4550evm/doc/tcan4550evm.jpg b/boards/shields/tcan4550evm/doc/tcan4550evm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba24e9c5d744d477218db5f78fba9be6f2a56720 GIT binary patch literal 67441 zcmcF~2UJtv^JkFWdv7X5>4FsLDAGi#6sbXa@4X}n(wl&Q6hV6Ly#}O%h;#@ggd)-t zkq{(=&G)ze{qH$@_J7WA_v}vI&ATUg@18qv?#z5|BpVN^FO!U4ghFL@SN|w#mBo3xI>GFPm6au z4B*C%MTqw=`sbp52=5L)0U;4F2`L#l?t(TNz#Tk%{5u5rgoFgRso+K6{s$1y64Koh ze@aAe@P_!l4}-+Jv?3CoXHA2QhO-FX$F{zaq-0FYEUavN{0|-q2ueyx%RG^lQ+=+c zuA!;*;+2uHiRo)Ib31znM<-_&S3m!Nz@Xre(5Uy(F|l#+3F#RhGqbWk<>VHZl$MoO zR900tx3spkcXW1je;pbg866v+n4FtmSX^3OS%t#4cXs!F?*BSCME*YibAh@2RKJ@n`-jOgoODk#` zB;|Q*h+wq!oh4)9m4x#l|6%Q4oc()@MgCuL_MeRXPrlXws<E$M1_wd z0wRKch=`czUqt*LMDi~p{fEf^lWuW?;QezaK0YDtASWRr`Op9U?au86ZgD-lg#sw> z@o6x5 zkN=M{C>>|q0&;*|!K)o82gIL#p_?LwfG_CBda>-~OJeX=R?oM@Hp2x2cXW(wcTX4t z`R5i3Zq&fCg)ES*pQ$VILu?=WnQ!u28|W~=#gd+urtgXN!v1@C`WX}Llo6Fuz4sjR zE}c!i9SNvnAorDBmC<7R7)JAJZR|4Q7Vus{1i?L|2X?EF!WQ2G)}V0~Ywx`Ft6QE| zi@c+=bX@&fB49PV6)M@B^l~FVB*GsfgP}6paZ&REt6mrMF9=IcX-QG4+jm6r3IEm{ zq*Xb6y@hunb>()g2_AHVY~>U-?=Aj}N0M*X=Tse;@CrjUVxx{iBk6xgO1lZ@)nwv# zHJqQJk=MEhg&g=W&=QQRHvn1Sl6}LYHNTra^WqaJ>w^yG=UJ#Bp_q;WNh60Liank1 z0HoUv^H*i219Et3G=xI3kkm}&6tPiy!iS`a1_UG<@~sWMH=I42fQBwN#KM1_8S4CX zLHB|26Y8DkE}3Ds006dE*|`ucA2qZDbDo1Z0N;1WB-I)!YK&x0xY3I_X}c-6YDNT3 zA_^`2Qb!;h;6cY*z*ar5V`f-hISNaUekT@71Q8nI%7e=X%%04_2zsV{a_Sd(US_9x z(&Ph(w!dKMx)kUhQS)pajRRq&Y2T1lht`^D zaro&xQuCkQRBm|(_%H}OcsSA)0ajYeN1M0#NWov!*5)l&T==21QJ`Buq!EUq69Qzz z_?~0=gBxsbIxLVJ&9KKZ5A3z%dl(2l_q&Y`1W5g*gEeU!w}^i9cRRy#&KNjo$~?B& z(_?`XhGu`&I$3+!*3RNn#ypFmt6U?+bl04v|woKKpQQ-X|*qlh*(3iLCC<&YEA>{vBZ<`LFYNLl}ekSoyOv z`g02pDLLW=NqO#8u@Z1Z3S6KKaJI|__h@6o>CtBhF|C`zhJfD+0q|AccIl4js7+PD zi24Wb@*-GKjq`K`2o8x-t$c}K-&{_mrX?tTAUvif1n99P8VS?P$B#`8u#t& z{{zEP&Pr=#XDcJE$-2AU8?`+%<`tt%0DPuQ-}a>SQ@BQzTIuSH_Y?>JDd>JuPxIS3 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 in#F7xApIe~T26dss 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 + +/ { + chosen { + zephyr,canbus = &tcan4x5x_tcan4550evm; + }; +}; + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + + tcan4x5x_tcan4550evm: can@0 { + compatible = "ti,tcan4x5x"; + reg = <0>; + /* reduced spi-max-frequency to accommodate flywire connections */ + spi-max-frequency = <2000000>; + status = "okay"; + clock-frequency = <40000000>; + device-state-gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>; /* D6 */ + device-wake-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; /* D7 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_HIGH>; /* D8 */ + int-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + bosch,mram-cfg = <0x0 15 15 7 7 0 10 10>; + sjw = <1>; + sjw-data = <1>; + sample-point = <875>; + sample-point-data = <875>; + bus-speed = <125000>; + bus-speed-data = <1000000>; + status = "okay"; + + can-transceiver { + max-bitrate = <8000000>; + }; + }; +}; From 37f4cb16f1a08041b9d77680bff7c49cd178fd79 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 29 Aug 2023 13:59:46 +0200 Subject: [PATCH 0191/4498] tests: drivers: build_all: can: add compile test for the tcan4x5x driver Add a compile test for the TI TCAN4x5x series CAN controller driver. Signed-off-by: Henrik Brix Andersen --- tests/drivers/build_all/can/testcase.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/drivers/build_all/can/testcase.yaml b/tests/drivers/build_all/can/testcase.yaml index 4cad66e888f..4894e9cf3f1 100644 --- a/tests/drivers/build_all/can/testcase.yaml +++ b/tests/drivers/build_all/can/testcase.yaml @@ -10,3 +10,9 @@ tests: - arduino_gpio extra_args: SHIELD=dfrobot_can_bus_v2_0 platform_allow: frdm_k64f + drivers.build_all.can.tcan4x5x: + depends_on: + - arduino_spi + - arduino_gpio + extra_args: SHIELD=tcan4550evm + platform_allow: frdm_k64f From 008a82e3bae2afa7089af7a8bcfbabe90e9e943b Mon Sep 17 00:00:00 2001 From: Pirun Lee Date: Mon, 4 Sep 2023 09:14:12 +0800 Subject: [PATCH 0192/4498] Bluetooth: OTS: Fix memory leak while procedure is not finished cur_inst is the copy of ots_client instance to prevent duplicate API call while client is in middle of read/write procedure. But cur_inst can only be cleared while write_obj_tx_done or read rx_done. If ACL is disconnected while read/write is on-going, there is no chance for cur_inst being cleared. This causes ots client will no longer perform select/read/write procedure anymore. API will always return -EBUSY. Let l2cap_disconnect check if cur_inst is NULL and NULL it unconditionally as what it is designed. Make bt_ots_client_unregister public API. Signed-off-by: Pirun Lee --- include/zephyr/bluetooth/services/ots.h | 11 +++++++++++ subsys/bluetooth/services/ots/ots_client.c | 3 +++ 2 files changed, 14 insertions(+) diff --git a/include/zephyr/bluetooth/services/ots.h b/include/zephyr/bluetooth/services/ots.h index 29095642521..224731925db 100644 --- a/include/zephyr/bluetooth/services/ots.h +++ b/include/zephyr/bluetooth/services/ots.h @@ -937,6 +937,17 @@ struct bt_ots_client_cb { */ int bt_ots_client_register(struct bt_ots_client *ots_inst); +/** @brief Unregister an Object Transfer Service Instance. + * + * Unregister an Object Transfer Service instance when disconnect from the peer. + * Call this function when an ACL using OTS instance is disconnected. + * + * @param[in] index Index of OTS instance. + * + * @return int 0 if success, ERRNO on failure. + */ +int bt_ots_client_unregister(uint8_t index); + /** @brief OTS Indicate Handler function. * * Set this function as callback for indicate handler when discovering OTS. diff --git a/subsys/bluetooth/services/ots/ots_client.c b/subsys/bluetooth/services/ots/ots_client.c index 40c6de94b05..e14e83b047a 100644 --- a/subsys/bluetooth/services/ots/ots_client.c +++ b/subsys/bluetooth/services/ots/ots_client.c @@ -230,6 +230,9 @@ static void chan_closed(struct bt_gatt_ots_l2cap *l2cap_ctx, struct bt_conn *conn) { LOG_DBG("L2CAP closed, context: %p, conn: %p", l2cap_ctx, (void *)conn); + if (cur_inst) { + cur_inst = NULL; + } } /* End L2CAP callbacks */ From 4798187801104fc3aa991617bdf1e9d730b00ca3 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 5 Sep 2023 13:37:04 +0300 Subject: [PATCH 0193/4498] test: lwm2m: Fix minor timing issue RD client tests work well on emulated (fast) environments but tend to fail on real HW with real time sleeps. This change refactors wait_for_service() to be a bit more syncronous on background service, instead of relying hardcoded sleeps. Fixes #61824 Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt | 2 +- tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 5f29bdad0dd..81e129c56c1 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -23,7 +23,7 @@ add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH=32) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES=2) add_compile_definitions(CONFIG_LWM2M_COAP_BLOCK_SIZE=256) add_compile_definitions(CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512) -add_compile_definitions(CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=60) +add_compile_definitions(CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=20) add_compile_definitions(CONFIG_LWM2M_SECURITY_INSTANCE_COUNT=1) add_compile_definitions(CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10) add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_UPTIME=10) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index 58f64f4984d..41789e20340 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -117,10 +117,12 @@ uint16_t counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; struct lwm2m_message *pending_message; void *(*pending_message_cb)(); static bool running; +K_SEM_DEFINE(srv_sem, 0, 1); static void service_work_fn(struct k_work *work) { while (running) { + k_sleep(K_MSEC(10)); if (pending_message != NULL && pending_message_cb != NULL) { pending_message_cb(pending_message); pending_message = NULL; @@ -129,8 +131,9 @@ static void service_work_fn(struct k_work *work) if (next && next < k_uptime_get()) { next = 0; service(NULL); + k_sem_give(&srv_sem); } - k_sleep(K_MSEC(10)); + counter--; /* avoid endless loop if rd client is stuck somewhere */ @@ -143,10 +146,8 @@ static void service_work_fn(struct k_work *work) void wait_for_service(uint16_t cycles) { - uint16_t end = counter - cycles; - - while (counter > end) { - k_sleep(K_MSEC(10)); + while (cycles--) { + k_sem_take(&srv_sem, K_MSEC(100)); } } @@ -157,6 +158,7 @@ void test_lwm2m_engine_start_service(void) running = true; counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; k_work_submit(&service_work); + k_sem_reset(&srv_sem); } void test_lwm2m_engine_stop_service(void) From 00d8870a50effde1e631f953bef3930afa59c019 Mon Sep 17 00:00:00 2001 From: Noah Pendleton Date: Sun, 10 Sep 2023 19:33:11 -0400 Subject: [PATCH 0194/4498] debug: Set thread_info.c variables to const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variables are usually placed into an output region located in FLASH memory when linking, but the variables are not marked `const`, so the section ends up with `W` writeable section flag: ```bash ❯ arm-zephyr-eabi-readelf --section-headers build/zephyr/zephyr.elf | \ grep -E '(Section Headers:)|( \[Nr\])|(zephyr_dbg_info)' Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [10] zephyr_dbg_info PROGBITS 60012298 01238c 000040 00 WA 0 0 4 ``` Set them as const to set the output section to read-only: ```bash ❯ arm-zephyr-eabi-readelf --section-headers build/zephyr/zephyr.elf | \ grep -E '(Section Headers:)|( \[Nr\])|(zephyr_dbg_info)' Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [10] zephyr_dbg_info PROGBITS 60012298 01238c 000040 00 A 0 0 4 ``` Signed-off-by: Noah Pendleton --- subsys/debug/thread_info.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/debug/thread_info.c b/subsys/debug/thread_info.c index dde7d1d2a20..742cbd59485 100644 --- a/subsys/debug/thread_info.c +++ b/subsys/debug/thread_info.c @@ -40,7 +40,7 @@ enum { * Only version 1 is backward compatible to version 0. */ __attribute__((used, section(".dbg_thread_info"))) -size_t _kernel_thread_info_offsets[] = { +const size_t _kernel_thread_info_offsets[] = { /* Version 0 starts */ [THREAD_INFO_OFFSET_VERSION] = 1, [THREAD_INFO_OFFSET_K_CURR_THREAD] = offsetof(struct _cpu, current), @@ -146,15 +146,15 @@ size_t _kernel_thread_info_offsets[] = { #endif /* CONFIG_ARC */ }; -extern size_t __attribute__((alias("_kernel_thread_info_offsets"))) +extern const size_t __attribute__((alias("_kernel_thread_info_offsets"))) _kernel_openocd_offsets; __attribute__((used, section(".dbg_thread_info"))) -size_t _kernel_thread_info_num_offsets = ARRAY_SIZE(_kernel_thread_info_offsets); -extern size_t __attribute__((alias("_kernel_thread_info_num_offsets"))) +const size_t _kernel_thread_info_num_offsets = ARRAY_SIZE(_kernel_thread_info_offsets); +extern const size_t __attribute__((alias("_kernel_thread_info_num_offsets"))) _kernel_openocd_num_offsets; __attribute__((used, section(".dbg_thread_info"))) -uint8_t _kernel_thread_info_size_t_size = (uint8_t)sizeof(size_t); -extern uint8_t __attribute__((alias("_kernel_thread_info_size_t_size"))) +const uint8_t _kernel_thread_info_size_t_size = (uint8_t)sizeof(size_t); +extern const uint8_t __attribute__((alias("_kernel_thread_info_size_t_size"))) _kernel_openocd_size_t_size; From 31cd3b1f61e914ca23a620033e22ec8d33402369 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 9 Jun 2023 00:21:09 +0200 Subject: [PATCH 0195/4498] drivers/spi: stm32: fix TX-only mode When doing a TX-only SPI operation, the RX not empty flag will never get set, thus this will just hang forever. Found/tested on STM32L462 trying to drive some WS2812 RGB LEDs. Signed-off-by: David Lamparter --- drivers/spi/spi_ll_stm32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 948b7641eaf..1991bfe6521 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -324,8 +324,10 @@ static void spi_stm32_shift_m(SPI_TypeDef *spi, struct spi_stm32_data *data) spi_context_update_tx(&data->ctx, 2, 1); } - while (!ll_func_rx_is_not_empty(spi)) { - /* NOP */ + if (spi_context_rx_buf_on(&data->ctx)) { + while (!ll_func_rx_is_not_empty(spi)) { + /* NOP */ + } } if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { From 9339882fbb5cff00a4d2669c3ae9daf84d94a4fd Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Sat, 9 Sep 2023 09:20:57 +0200 Subject: [PATCH 0196/4498] samples: lvgl: Extend hello world sample button functionality This commit adds a callback to the button to reset the counter when the button is pressed. The button is automatically created when lvgl pointer or kscan support is enabled. The same reset functionality was already available for possible gpio button. Please make sure to define a zephyr input device in device tree (e.g. "zephyr,lvgl-pointer-input"). Signed-off-by: Martin Kiepfer --- samples/subsys/display/lvgl/src/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/samples/subsys/display/lvgl/src/main.c b/samples/subsys/display/lvgl/src/main.c index 2fd3592dbab..8c86711f172 100644 --- a/samples/subsys/display/lvgl/src/main.c +++ b/samples/subsys/display/lvgl/src/main.c @@ -36,6 +36,13 @@ static void button_isr_callback(const struct device *port, } #endif +static void lv_btn_click_callback(lv_event_t *e) +{ + ARG_UNUSED(e); + + count = 0; +} + int main(void) { char count_str[11] = {0}; @@ -82,6 +89,8 @@ int main(void) hello_world_button = lv_btn_create(lv_scr_act()); lv_obj_align(hello_world_button, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_event_cb(hello_world_button, lv_btn_click_callback, LV_EVENT_CLICKED, + NULL); hello_world_label = lv_label_create(hello_world_button); } else { hello_world_label = lv_label_create(lv_scr_act()); From c61057354e95528f422bf6b03519bd5a74110c8e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 8 Sep 2023 19:24:21 +0200 Subject: [PATCH 0197/4498] modem: Delegate async UART pipe closed event This commit delegates the modem_pipe_notify_closed() call resulting from the UART async API UART_RX_DISABLED event to the workqueue. This is neccesary as the async UART callback may be called from ISR context. modem_pipe_notify_closed() must be called from outside of the ISR context as it takes a mutex. The commit also adds a missing break to the async UART callback, and adds a missing dependency to the Kconfig for the UART backends, RING_BUFFER=y Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/backend/uart.h | 1 + subsys/modem/backends/Kconfig | 1 + subsys/modem/backends/modem_backend_uart_async.c | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/zephyr/modem/backend/uart.h b/include/zephyr/modem/backend/uart.h index 600d5435a1e..1aebe9e2030 100644 --- a/include/zephyr/modem/backend/uart.h +++ b/include/zephyr/modem/backend/uart.h @@ -34,6 +34,7 @@ struct modem_backend_uart_async { struct ring_buf receive_rdb[2]; uint8_t *transmit_buf; uint32_t transmit_buf_size; + struct k_work rx_disabled_work; atomic_t state; }; diff --git a/subsys/modem/backends/Kconfig b/subsys/modem/backends/Kconfig index 1d3e3144a91..417566966a2 100644 --- a/subsys/modem/backends/Kconfig +++ b/subsys/modem/backends/Kconfig @@ -9,6 +9,7 @@ config MODEM_BACKEND_TTY config MODEM_BACKEND_UART bool "Modem UART backend module" select MODEM_PIPE + select RING_BUFFER depends on UART_INTERRUPT_DRIVEN || UART_ASYNC_API if MODEM_BACKEND_UART diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index c5349a0b52c..9c4e904ef9e 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -65,6 +65,8 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, atomic_clear_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT); + break; + case UART_RX_BUF_REQUEST: if (!atomic_test_and_set_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT)) { @@ -120,7 +122,7 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, break; case UART_RX_DISABLED: - modem_pipe_notify_closed(&backend->pipe); + k_work_submit(&backend->async.rx_disabled_work); break; case UART_RX_STOPPED: @@ -244,6 +246,17 @@ bool modem_backend_uart_async_is_supported(struct modem_backend_uart *backend) backend) == 0; } +static void modem_backend_uart_async_notify_closed(struct k_work *item) +{ + struct modem_backend_uart_async *async = + CONTAINER_OF(item, struct modem_backend_uart_async, rx_disabled_work); + + struct modem_backend_uart *backend = + CONTAINER_OF(async, struct modem_backend_uart, async); + + modem_pipe_notify_closed(&backend->pipe); +} + void modem_backend_uart_async_init(struct modem_backend_uart *backend, const struct modem_backend_uart_config *config) { @@ -263,5 +276,6 @@ void modem_backend_uart_async_init(struct modem_backend_uart *backend, backend->async.transmit_buf = config->transmit_buf; backend->async.transmit_buf_size = config->transmit_buf_size; + k_work_init(&backend->async.rx_disabled_work, modem_backend_uart_async_notify_closed); modem_pipe_init(&backend->pipe, backend, &modem_backend_uart_async_api); } From 7c4ff77bf3a99543533e3e389f5a70964a2dd45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 19:35:31 +0200 Subject: [PATCH 0198/4498] doc: zbus: samples: Use new Sphinx extension to document samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new code-sample directive and roles to document the zbus samples so that they show up as "Related samples" when browsing zbus API. Signed-off-by: Benjamin Cabé --- doc/releases/release-notes-3.3.rst | 14 +++++++------- doc/services/zbus/index.rst | 14 +++++++------- samples/subsys/zbus/benchmark/README.rst | 7 ++++--- samples/subsys/zbus/confirmed_channel/README.rst | 7 ++++--- samples/subsys/zbus/dyn_channel/README.rst | 7 ++++--- samples/subsys/zbus/hello_world/README.rst | 7 ++++--- samples/subsys/zbus/remote_mock/README.rst | 7 ++++--- .../zbus/runtime_obs_registration/README.rst | 7 ++++--- samples/subsys/zbus/uart_bridge/README.rst | 7 ++++--- samples/subsys/zbus/work_queue/README.rst | 7 ++++--- samples/subsys/zbus/zbus.rst | 2 +- 11 files changed, 47 insertions(+), 39 deletions(-) diff --git a/doc/releases/release-notes-3.3.rst b/doc/releases/release-notes-3.3.rst index d4b438999e2..93be4649b1e 100644 --- a/doc/releases/release-notes-3.3.rst +++ b/doc/releases/release-notes-3.3.rst @@ -2496,13 +2496,13 @@ Libraries / Subsystems * Uses mutex to control channels access. * Added the following samples: - * :ref:`zbus-hello-world-sample` - * :ref:`zbus-work-queue-sample` - * :ref:`zbus-dyn-channel-sample` - * :ref:`zbus-uart-bridge-sample` - * :ref:`zbus-remote-mock-sample` - * :ref:`zbus-runtime-obs-registration-sample` - * :ref:`zbus-benchmark-sample` + * :zephyr:code-sample:`zbus-hello-world` + * :zephyr:code-sample:`zbus-work-queue` + * :zephyr:code-sample:`zbus-dyn-channel` + * :zephyr:code-sample:`zbus-uart-bridge` + * :zephyr:code-sample:`zbus-remote-mock` + * :zephyr:code-sample:`zbus-runtime-obs-registration` + * :zephyr:code-sample:`zbus-benchmark` * Added zbus channels APIs: diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 29c2d86eb06..441e9f887f4 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -484,13 +484,13 @@ Samples For a complete overview of zbus usage, take a look at the samples. There are the following samples available: -* :ref:`zbus-hello-world-sample` illustrates the code used above in action; -* :ref:`zbus-work-queue-sample` shows how to define and use different kinds of observers. Note there is an example of using a work queue instead of executing the listener as an execution option; -* :ref:`zbus-dyn-channel-sample` demonstrates how to use dynamically allocated exchanging data in zbus; -* :ref:`zbus-uart-bridge-sample` shows an example of sending the operation of the channel to a host via serial; -* :ref:`zbus-remote-mock-sample` illustrates how to implement an external mock (on the host) to send and receive messages to and from the bus. -* :ref:`zbus-runtime-obs-registration-sample` illustrates a way of using the runtime observer registration feature; -* :ref:`zbus-benchmark-sample` implements a benchmark with different combinations of inputs. +* :zephyr:code-sample:`zbus-hello-world` illustrates the code used above in action; +* :zephyr:code-sample:`zbus-work-queue` shows how to define and use different kinds of observers. Note there is an example of using a work queue instead of executing the listener as an execution option; +* :zephyr:code-sample:`zbus-dyn-channel` demonstrates how to use dynamically allocated exchanging data in zbus; +* :zephyr:code-sample:`zbus-uart-bridge` shows an example of sending the operation of the channel to a host via serial; +* :zephyr:code-sample:`zbus-remote-mock` illustrates how to implement an external mock (on the host) to send and receive messages to and from the bus. +* :zephyr:code-sample:`zbus-runtime-obs-registration` illustrates a way of using the runtime observer registration feature; +* :zephyr:code-sample:`zbus-benchmark` implements a benchmark with different combinations of inputs. Suggested Uses ************** diff --git a/samples/subsys/zbus/benchmark/README.rst b/samples/subsys/zbus/benchmark/README.rst index f42bf7ca7e5..4dd14607623 100644 --- a/samples/subsys/zbus/benchmark/README.rst +++ b/samples/subsys/zbus/benchmark/README.rst @@ -1,7 +1,8 @@ -.. _zbus-benchmark-sample: +.. zephyr:code-sample:: zbus-benchmark + :name: Benchmarking + :relevant-api: zbus_apis -Benchmark sample -################ + Measure the time for sending 256KB from a producer to X consumers. This sample implements an application to measure the time for sending 256KB from the producer to the consumers. diff --git a/samples/subsys/zbus/confirmed_channel/README.rst b/samples/subsys/zbus/confirmed_channel/README.rst index 64ff87757aa..c37c0d2546e 100644 --- a/samples/subsys/zbus/confirmed_channel/README.rst +++ b/samples/subsys/zbus/confirmed_channel/README.rst @@ -1,7 +1,8 @@ -.. _zbus-confirmed-channel-sample: +.. zephyr:code-sample:: zbus-confirmed-channel + :name: Confirmed channel + :relevant-api: zbus_apis -Confirmed channel sample -######################## + Use confirmed zbus channels to ensure all subscribers consume a message. Overview ******** diff --git a/samples/subsys/zbus/dyn_channel/README.rst b/samples/subsys/zbus/dyn_channel/README.rst index 190c5422cd7..91577d3dc98 100644 --- a/samples/subsys/zbus/dyn_channel/README.rst +++ b/samples/subsys/zbus/dyn_channel/README.rst @@ -1,7 +1,8 @@ -.. _zbus-dyn-channel-sample: +.. zephyr:code-sample:: zbus-dyn-channel + :name: Dynamic channel + :relevant-api: zbus_apis -Dynamic channel sample -###################### + Use zbus channels with dynamically allocated messages. Overview ******** diff --git a/samples/subsys/zbus/hello_world/README.rst b/samples/subsys/zbus/hello_world/README.rst index 09c897e3241..ba86d669488 100644 --- a/samples/subsys/zbus/hello_world/README.rst +++ b/samples/subsys/zbus/hello_world/README.rst @@ -1,7 +1,8 @@ -.. _zbus-hello-world-sample: +.. zephyr:code-sample:: zbus-hello-world + :name: zbus Hello World + :relevant-api: zbus_apis -Hello world sample -################## + Make three threads talk to each other using zbus. Overview ******** diff --git a/samples/subsys/zbus/remote_mock/README.rst b/samples/subsys/zbus/remote_mock/README.rst index 1afba887987..c1a098839de 100644 --- a/samples/subsys/zbus/remote_mock/README.rst +++ b/samples/subsys/zbus/remote_mock/README.rst @@ -1,7 +1,8 @@ -.. _zbus-remote-mock-sample: +.. zephyr:code-sample:: zbus-remote-mock + :name: Remote mock sample + :relevant-api: zbus_apis -Remote mock sample -################## + Publish to a zbus instance using UART as a bridge. Overview ******** diff --git a/samples/subsys/zbus/runtime_obs_registration/README.rst b/samples/subsys/zbus/runtime_obs_registration/README.rst index 9e59d11dad6..a3376e1a232 100644 --- a/samples/subsys/zbus/runtime_obs_registration/README.rst +++ b/samples/subsys/zbus/runtime_obs_registration/README.rst @@ -1,7 +1,8 @@ -.. _zbus-runtime-obs-registration-sample: +.. zephyr:code-sample:: zbus-runtime-obs-registration + :name: Runtime observer registration + :relevant-api: zbus_apis -Runtime observer registration sample -#################################### + Use zbus' runtime observer registration to filter data generated by a producer. Overview ******** diff --git a/samples/subsys/zbus/uart_bridge/README.rst b/samples/subsys/zbus/uart_bridge/README.rst index 6b8ba15bd8a..c14c0e8d64d 100644 --- a/samples/subsys/zbus/uart_bridge/README.rst +++ b/samples/subsys/zbus/uart_bridge/README.rst @@ -1,7 +1,8 @@ -.. _zbus-uart-bridge-sample: +.. zephyr:code-sample:: zbus-uart-bridge + :name: UART bridge + :relevant-api: zbus_apis -UART bridge sample -################## + Redirect channel events to the host over UART. Overview ******** diff --git a/samples/subsys/zbus/work_queue/README.rst b/samples/subsys/zbus/work_queue/README.rst index 55a94a45999..d88de6d470d 100644 --- a/samples/subsys/zbus/work_queue/README.rst +++ b/samples/subsys/zbus/work_queue/README.rst @@ -1,7 +1,8 @@ -.. _zbus-work-queue-sample: +.. zephyr:code-sample:: zbus-work-queue + :name: Work queue + :relevant-api: zbus_apis -Workqueue sample -################ + Use a work queue to process zbus messages in various ways. Overview ******** diff --git a/samples/subsys/zbus/zbus.rst b/samples/subsys/zbus/zbus.rst index 569802c632f..052589eed94 100644 --- a/samples/subsys/zbus/zbus.rst +++ b/samples/subsys/zbus/zbus.rst @@ -1,6 +1,6 @@ .. _zbus_samples: -Zbus Samples +zbus Samples ############ .. toctree:: From da967225528ab7dee89b9696fd8020d80ef76a9a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 8 Sep 2023 14:57:48 +0100 Subject: [PATCH 0199/4498] bluetooth: Make long workqueue init priority configurable Makes the long workqueue init priority configurable and sets the default to 50, this is to allow for relocating bluetooth libraries to other parts of memory e.g. external flash, and allows for those flash drivers to be initialised prior to calling functions residing in them. Signed-off-by: Jamie McCrae --- subsys/bluetooth/host/Kconfig | 7 +++++++ subsys/bluetooth/host/long_wq.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 19754705200..a4cf2e0959b 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -23,6 +23,13 @@ config BT_LONG_WQ_PRIO int "Long workqueue priority. Should be pre-emptible." default 10 range 0 NUM_PREEMPT_PRIORITIES + +config BT_LONG_WQ_INIT_PRIO + int "Long workqueue init priority" + default 50 + help + Init priority level to setup the long workqueue. + endif # BT_LONG_WQ config BT_HCI_HOST diff --git a/subsys/bluetooth/host/long_wq.c b/subsys/bluetooth/host/long_wq.c index 61f86d0c909..2136739c243 100644 --- a/subsys/bluetooth/host/long_wq.c +++ b/subsys/bluetooth/host/long_wq.c @@ -40,4 +40,4 @@ static int long_wq_init(void) return 0; } -SYS_INIT(long_wq_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(long_wq_init, POST_KERNEL, CONFIG_BT_LONG_WQ_INIT_PRIO); From 62f8fd962b96c2ff33b8e5f8d726a96c6ece46f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 7 Sep 2023 12:20:01 +0700 Subject: [PATCH 0200/4498] tests: code_relocation: update test filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ITCM relocation tests depends on MINIMAL_LIBC and when using Zephyr SDK the default is PICOLIBC for mr_canhubk3 board, so explicitly select it. Also the NXP S32 platforms don't have NXP MPU, so remove it. For frdm_k64f the ITCM relocation test is not executed, so remove the unnecesary filter CONFIG_MINIMAL_LIBC. Signed-off-by: Manuel Argüelles --- tests/application_development/code_relocation/testcase.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/application_development/code_relocation/testcase.yaml b/tests/application_development/code_relocation/testcase.yaml index 12e7595424d..6f3fc3dc537 100644 --- a/tests/application_development/code_relocation/testcase.yaml +++ b/tests/application_development/code_relocation/testcase.yaml @@ -9,16 +9,17 @@ tests: platform_allow: - mimxrt1060_evk application_development.code_relocation_kinetis: - filter: CONFIG_CPU_HAS_NXP_MPU and CONFIG_MINIMAL_LIBC + filter: CONFIG_CPU_HAS_NXP_MPU arch_allow: arm extra_configs: - CONFIG_MPU_ALLOW_FLASH_WRITE=y platform_allow: - frdm_k64f application_development.code_relocation.nxp_s32: - filter: not CONFIG_CPU_HAS_NXP_MPU and CONFIG_MINIMAL_LIBC and dt_chosen_enabled("zephyr,itcm") + filter: dt_chosen_enabled("zephyr,itcm") arch_allow: arm extra_configs: + - CONFIG_MINIMAL_LIBC=y - CONFIG_RELOCATE_TO_ITCM=y - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y platform_allow: From 5b0a08d87690454c8170e9a74ab2160ec94ca741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 8 Sep 2023 14:14:11 +0200 Subject: [PATCH 0201/4498] doc: net: tftp: fix API documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add a missing doxygen group and show the API reference the Sphinx doc. Signed-off-by: Benjamin Cabé --- doc/connectivity/networking/api/protocols.rst | 1 + doc/connectivity/networking/api/tftp.rst | 9 +++++++++ include/zephyr/net/tftp.h | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 doc/connectivity/networking/api/tftp.rst diff --git a/doc/connectivity/networking/api/protocols.rst b/doc/connectivity/networking/api/protocols.rst index 6ed46130fa5..8f2bc2af3d5 100644 --- a/doc/connectivity/networking/api/protocols.rst +++ b/doc/connectivity/networking/api/protocols.rst @@ -13,3 +13,4 @@ Protocols lwm2m mqtt mqtt_sn + tftp diff --git a/doc/connectivity/networking/api/tftp.rst b/doc/connectivity/networking/api/tftp.rst new file mode 100644 index 00000000000..36d9d2cf0bb --- /dev/null +++ b/doc/connectivity/networking/api/tftp.rst @@ -0,0 +1,9 @@ +.. _tftp_interface: + +TFTP +#### + +API Reference +************* + +.. doxygengroup:: tftp_client diff --git a/include/zephyr/net/tftp.h b/include/zephyr/net/tftp.h index 791dcbf6c8e..648212a87cd 100644 --- a/include/zephyr/net/tftp.h +++ b/include/zephyr/net/tftp.h @@ -6,7 +6,10 @@ /** @file tftp.h * - * @brief Zephyr TFTP Implementation + * @defgroup tftp_client TFTP Client library + * @ingroup networking + * @{ + * @brief TFTP Client Implementation */ #ifndef ZEPHYR_INCLUDE_NET_TFTP_H_ @@ -36,13 +39,19 @@ extern "C" { /* Maximum amount of data that can be sent or received */ #define TFTPC_MAX_BUF_SIZE (TFTP_BLOCK_SIZE + TFTP_HEADER_SIZE) -/* TFTP Client Error codes. */ +/** + * @name TFTP client error codes. + * @{ + */ #define TFTPC_SUCCESS 0 #define TFTPC_DUPLICATE_DATA -1 #define TFTPC_BUFFER_OVERFLOW -2 #define TFTPC_UNKNOWN_FAILURE -3 #define TFTPC_REMOTE_ERROR -4 #define TFTPC_RETRIES_EXHAUSTED -5 +/** + * @} + */ /** * @brief TFTP Asynchronous Events notified to the application from the module @@ -166,3 +175,5 @@ int tftp_put(struct tftpc *client, #endif #endif /* ZEPHYR_INCLUDE_NET_TFTP_H_ */ + +/** @} */ From 893a239f854880e30da99f104f97ab4af588b0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 13:06:40 +0200 Subject: [PATCH 0202/4498] tests: Bluetooth: Mesh: Priv beacon pst test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test for persistent storage in private beacon implementation. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/src/mesh_test.c | 9 ++++ .../bluetooth/mesh/src/test_persistence.c | 52 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.c b/tests/bsim/bluetooth/mesh/src/mesh_test.c index 95c9d09598f..13eedd9e2de 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.c +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.c @@ -166,6 +166,11 @@ static struct bt_mesh_model_pub health_pub = { static struct bt_mesh_sar_cfg_cli sar_cfg_cli; #endif +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) +static struct bt_mesh_priv_beacon_cli priv_beacon_cli; +#endif + + static struct bt_mesh_model models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -175,6 +180,10 @@ static struct bt_mesh_model models[] = { BT_MESH_MODEL_SAR_CFG_SRV, BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli), #endif +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + BT_MESH_MODEL_PRIV_BEACON_SRV, + BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), +#endif }; struct bt_mesh_model *test_model = &models[2]; diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 6c510922330..0269b42fb5d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -204,6 +204,11 @@ static const struct stack_cfg { enum bt_mesh_feat_state state; uint8_t transmit; } relay; +#ifdef CONFIG_BT_MESH_PRIV_BEACONS + uint8_t priv_beacon; + uint8_t priv_beacon_int; + uint8_t priv_beacon_gatt; +#endif } stack_cfgs[] = { { .beacon = 1, @@ -212,6 +217,11 @@ static const struct stack_cfg { .friend = 1, .net_transmit = BT_MESH_TRANSMIT(3, 20), .relay = { .state = BT_MESH_FEATURE_ENABLED, .transmit = BT_MESH_TRANSMIT(2, 20) }, +#ifdef CONFIG_BT_MESH_PRIV_BEACONS + .priv_beacon = 1, + .priv_beacon_int = 123, + .priv_beacon_gatt = 0, +#endif }, { .beacon = 0, @@ -220,6 +230,11 @@ static const struct stack_cfg { .friend = 0, .net_transmit = BT_MESH_TRANSMIT(1, 30), .relay = { .state = BT_MESH_FEATURE_ENABLED, .transmit = BT_MESH_TRANSMIT(1, 10) }, +#ifdef CONFIG_BT_MESH_PRIV_BEACONS + .priv_beacon = 1, + .priv_beacon_int = 100, + .priv_beacon_gatt = 1, +#endif }, }; static const struct stack_cfg *current_stack_cfg; @@ -912,6 +927,25 @@ static void test_cfg_save(void) current_stack_cfg->relay.transmit); } +#ifdef CONFIG_BT_MESH_PRIV_BEACONS + struct bt_mesh_priv_beacon priv_beacon_state = { + .enabled = current_stack_cfg->priv_beacon, + .rand_interval = current_stack_cfg->priv_beacon_int, + }; + + err = bt_mesh_priv_beacon_cli_set(test_netkey_idx, TEST_ADDR, &priv_beacon_state); + if (err) { + FAIL("Failed to enable Private Beacon (err %d)", err); + } + + uint8_t priv_beacon_gatt = current_stack_cfg->priv_beacon_gatt; + + err = bt_mesh_priv_beacon_cli_gatt_proxy_set(test_netkey_idx, TEST_ADDR, &priv_beacon_gatt); + if (err) { + FAIL("Failed to enable Private Beacon GATT proxy (err %d)", err); + } +#endif + k_sleep(K_SECONDS(CONFIG_BT_MESH_STORE_TIMEOUT)); PASS(); @@ -963,6 +997,24 @@ static void test_cfg_load(void) FAIL("Relay get failed (err %d, state %u, transmit %x)", err, status, transmit); } +#ifdef CONFIG_BT_MESH_PRIV_BEACONS + struct bt_mesh_priv_beacon priv_beacon_state; + uint8_t priv_beacon_gatt; + + err = bt_mesh_priv_beacon_cli_get(test_netkey_idx, TEST_ADDR, &priv_beacon_state); + if (err || priv_beacon_state.enabled != current_stack_cfg->priv_beacon || + priv_beacon_state.rand_interval != current_stack_cfg->priv_beacon_int) { + FAIL("Private beacon get failed (err %d, enabled %u, interval %x)", err, + priv_beacon_state.enabled, priv_beacon_state.rand_interval); + } + + err = bt_mesh_priv_beacon_cli_gatt_proxy_get(test_netkey_idx, TEST_ADDR, &priv_beacon_gatt); + if (err || priv_beacon_gatt != current_stack_cfg->priv_beacon_gatt) { + FAIL("Private beacon GATT proxy get failed (err %d, enabled %u)", err, + priv_beacon_gatt); + } +#endif + PASS(); } From c80a52a1e31eaf74d83c1d4e2a47f82936ce4bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 13:06:40 +0200 Subject: [PATCH 0203/4498] Bluetooth: Mesh: Store priv beacon in sep entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stores persistent private beacon state in separate settings entry. This is implemented to avoid issues related to backwards compatibility between device firmware updates. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg.c | 27 ++------- subsys/bluetooth/mesh/priv_beacon.h | 7 +++ subsys/bluetooth/mesh/priv_beacon_srv.c | 74 +++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 subsys/bluetooth/mesh/priv_beacon.h diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index 287023afa68..4a59f76bbbd 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -16,6 +16,7 @@ #include "friend.h" #include "adv.h" #include "cfg.h" +#include "priv_beacon.h" #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL #include @@ -30,11 +31,6 @@ struct cfg_val { uint8_t gatt_proxy; uint8_t frnd; uint8_t default_ttl; -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - uint8_t priv_beacon; - uint8_t priv_beacon_int; - uint8_t priv_gatt_proxy; -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) uint8_t on_demand_state; #endif @@ -109,9 +105,9 @@ int bt_mesh_priv_beacon_set(enum bt_mesh_feat_state priv_beacon) /* Beacon timer will stop automatically when all beacons are disabled. */ } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_priv_beacon_srv_store_schedule(); } return 0; @@ -244,9 +240,9 @@ int bt_mesh_priv_gatt_proxy_set(enum bt_mesh_feat_state priv_gatt_proxy) bt_mesh_adv_gatt_update(); } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_priv_beacon_srv_store_schedule(); } return 0; @@ -261,7 +257,6 @@ enum bt_mesh_feat_state bt_mesh_priv_gatt_proxy_get(void) return feature_get(BT_MESH_PRIV_GATT_PROXY); } - int bt_mesh_default_ttl_set(uint8_t default_ttl) { if (default_ttl == 1 || default_ttl > BT_MESH_TTL_MAX) { @@ -454,11 +449,6 @@ static int cfg_set(const char *name, size_t len_rd, bt_mesh_gatt_proxy_set(cfg.gatt_proxy); bt_mesh_friend_set(cfg.frnd); bt_mesh_default_ttl_set(cfg.default_ttl); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - bt_mesh_priv_beacon_set(cfg.priv_beacon); - bt_mesh_priv_beacon_update_interval_set(cfg.priv_beacon_int); - bt_mesh_priv_gatt_proxy_set(cfg.priv_gatt_proxy); -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) bt_mesh_od_priv_proxy_set(cfg.on_demand_state); #endif @@ -476,7 +466,7 @@ static void clear_cfg(void) err = settings_delete("bt/mesh/Cfg"); if (err) { - LOG_ERR("Failed to clear configuration"); + LOG_ERR("Failed to clear configuration (err: %d)", err); } else { LOG_DBG("Cleared configuration"); } @@ -494,11 +484,6 @@ static void store_pending_cfg(void) val.gatt_proxy = bt_mesh_gatt_proxy_get(); val.frnd = bt_mesh_friend_get(); val.default_ttl = bt_mesh_default_ttl_get(); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - val.priv_beacon = bt_mesh_priv_beacon_get(); - val.priv_beacon_int = bt_mesh_priv_beacon_update_interval_get(); - val.priv_gatt_proxy = bt_mesh_priv_gatt_proxy_get(); -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) val.on_demand_state = bt_mesh_od_priv_proxy_get(); #endif diff --git a/subsys/bluetooth/mesh/priv_beacon.h b/subsys/bluetooth/mesh/priv_beacon.h new file mode 100644 index 00000000000..0cbbdafd0b1 --- /dev/null +++ b/subsys/bluetooth/mesh/priv_beacon.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_mesh_priv_beacon_srv_store_schedule(void); diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index a1478efff80..377703e8352 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -11,11 +11,33 @@ #include "foundation.h" #include "beacon.h" #include "cfg.h" +#include "settings.h" #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_priv_beacon_srv); +static struct bt_mesh_model *priv_beacon_srv; + +/* Private Beacon configuration server model states */ +struct { + uint8_t state; + uint8_t interval; + uint8_t proxy_state; +} priv_beacon_state; + +static int priv_beacon_store(bool delete) +{ + if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { + return 0; + } + + const void *data = delete ? NULL : &priv_beacon_state; + size_t len = delete ? 0 : sizeof(priv_beacon_state); + + return bt_mesh_model_data_store(priv_beacon_srv, false, "pb", data, len); +} + static int beacon_status_rsp(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { @@ -179,11 +201,63 @@ static int priv_beacon_srv_init(struct bt_mesh_model *mod) return -EINVAL; } + priv_beacon_srv = mod; mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; return 0; } +static void priv_beacon_srv_reset(struct bt_mesh_model *model) +{ + (void)memset(&priv_beacon_state, 0, sizeof(priv_beacon_state)); + priv_beacon_store(true); +} + +#ifdef CONFIG_BT_SETTINGS +static int priv_beacon_srv_settings_set(struct bt_mesh_model *model, const char *name, + size_t len_rd, settings_read_cb read_cb, void *cb_data) +{ + int err; + + if (len_rd == 0) { + LOG_DBG("Cleared configuration state"); + return 0; + } + + err = bt_mesh_settings_set(read_cb, cb_data, &priv_beacon_state, sizeof(priv_beacon_state)); + if (err) { + LOG_ERR("Failed to set Private Beacon state"); + return err; + } + + bt_mesh_priv_beacon_set(priv_beacon_state.state); + bt_mesh_priv_beacon_update_interval_set(priv_beacon_state.interval); + bt_mesh_priv_gatt_proxy_set(priv_beacon_state.proxy_state); + return 0; +} + +static void priv_beacon_srv_pending_store(struct bt_mesh_model *model) +{ + priv_beacon_state.state = bt_mesh_priv_beacon_get(); + priv_beacon_state.interval = bt_mesh_priv_beacon_update_interval_get(); + priv_beacon_state.proxy_state = bt_mesh_priv_gatt_proxy_get(); + + priv_beacon_store(false); +} +#endif + const struct bt_mesh_model_cb bt_mesh_priv_beacon_srv_cb = { .init = priv_beacon_srv_init, + .reset = priv_beacon_srv_reset, +#ifdef CONFIG_BT_SETTINGS + .settings_set = priv_beacon_srv_settings_set, + .pending_store = priv_beacon_srv_pending_store, +#endif }; + +void bt_mesh_priv_beacon_srv_store_schedule(void) +{ + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_model_data_store_schedule(priv_beacon_srv); + } +} From cf8301d01edb0210b4899fbf98d24dd6ffd3ff7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 13:06:40 +0200 Subject: [PATCH 0204/4498] tests: Bluetooth: Mesh: OD priv proxy pst test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test for persistent storage in On-Demand Private Proxy implementation. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 2 ++ tests/bsim/bluetooth/mesh/src/mesh_test.c | 9 ++++++ .../bluetooth/mesh/src/test_persistence.c | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index 8a8b78fe8ea..69c1055999f 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -61,6 +61,8 @@ CONFIG_BT_MESH_DFD_SRV=y CONFIG_BT_MESH_DFU_SLOT_CNT=3 CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y +CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y +CONFIG_BT_MESH_OD_PRIV_PROXY_CLI=y CONFIG_BT_MESH_COMP_PAGE_1=y CONFIG_BT_MESH_COMP_PAGE_2=y diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.c b/tests/bsim/bluetooth/mesh/src/mesh_test.c index 13eedd9e2de..538af49109e 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.c +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.c @@ -170,6 +170,9 @@ static struct bt_mesh_sar_cfg_cli sar_cfg_cli; static struct bt_mesh_priv_beacon_cli priv_beacon_cli; #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) +static struct bt_mesh_od_priv_proxy_cli priv_proxy_cli; +#endif static struct bt_mesh_model models[] = { BT_MESH_MODEL_CFG_SRV, @@ -184,6 +187,12 @@ static struct bt_mesh_model models[] = { BT_MESH_MODEL_PRIV_BEACON_SRV, BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + BT_MESH_MODEL_OD_PRIV_PROXY_SRV, +#endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) + BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&priv_proxy_cli), +#endif }; struct bt_mesh_model *test_model = &models[2]; diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 0269b42fb5d..24d992e48e8 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -209,6 +209,9 @@ static const struct stack_cfg { uint8_t priv_beacon_int; uint8_t priv_beacon_gatt; #endif +#ifdef CONFIG_BT_MESH_OD_PRIV_PROXY_SRV + uint8_t priv_proxy_val; +#endif } stack_cfgs[] = { { .beacon = 1, @@ -221,6 +224,9 @@ static const struct stack_cfg { .priv_beacon = 1, .priv_beacon_int = 123, .priv_beacon_gatt = 0, +#endif +#ifdef CONFIG_BT_MESH_OD_PRIV_PROXY_SRV + .priv_proxy_val = 10, #endif }, { @@ -234,6 +240,9 @@ static const struct stack_cfg { .priv_beacon = 1, .priv_beacon_int = 100, .priv_beacon_gatt = 1, +#endif +#ifdef CONFIG_BT_MESH_OD_PRIV_PROXY_SRV + .priv_proxy_val = 20, #endif }, }; @@ -946,6 +955,16 @@ static void test_cfg_save(void) } #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) && defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) + uint8_t priv_proxy_val; + + err = bt_mesh_od_priv_proxy_cli_set(test_netkey_idx, TEST_ADDR, + current_stack_cfg->priv_proxy_val, &priv_proxy_val); + if (err || priv_proxy_val != current_stack_cfg->priv_proxy_val) { + FAIL("Failed to set OD Private proxy (err %d, value %d)", err, priv_proxy_val); + } +#endif + k_sleep(K_SECONDS(CONFIG_BT_MESH_STORE_TIMEOUT)); PASS(); @@ -1015,6 +1034,15 @@ static void test_cfg_load(void) } #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) && defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) + uint8_t priv_proxy_val; + + err = bt_mesh_od_priv_proxy_cli_get(test_netkey_idx, TEST_ADDR, &priv_proxy_val); + if (err || priv_proxy_val != current_stack_cfg->priv_proxy_val) { + FAIL("Private proxy get failed (err %d, value %u)", err, priv_proxy_val); + } +#endif + PASS(); } From 6559de3238d3ff6f5da5535811457ad29b6e9677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 13:06:40 +0200 Subject: [PATCH 0205/4498] Bluetooth: Mesh: Store priv proxy in sep entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stores persistent on-demand private GATT proxy state in separate settings entry. This is implemented to avoid issues related to backwards compatibility between device firmware updates. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg.c | 15 ++---- subsys/bluetooth/mesh/od_priv_proxy.h | 7 +++ subsys/bluetooth/mesh/od_priv_proxy_srv.c | 65 +++++++++++++++++++++++ 3 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 subsys/bluetooth/mesh/od_priv_proxy.h diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index 4a59f76bbbd..c7bea0d29b0 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -16,6 +16,7 @@ #include "friend.h" #include "adv.h" #include "cfg.h" +#include "od_priv_proxy.h" #include "priv_beacon.h" #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL @@ -31,9 +32,6 @@ struct cfg_val { uint8_t gatt_proxy; uint8_t frnd; uint8_t default_ttl; -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - uint8_t on_demand_state; -#endif }; void bt_mesh_beacon_set(bool beacon) @@ -157,9 +155,9 @@ int bt_mesh_od_priv_proxy_set(uint8_t on_demand_proxy) bt_mesh.on_demand_state = on_demand_proxy; } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_od_priv_proxy_srv_store_schedule(); } return 0; #endif @@ -449,9 +447,6 @@ static int cfg_set(const char *name, size_t len_rd, bt_mesh_gatt_proxy_set(cfg.gatt_proxy); bt_mesh_friend_set(cfg.frnd); bt_mesh_default_ttl_set(cfg.default_ttl); -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - bt_mesh_od_priv_proxy_set(cfg.on_demand_state); -#endif LOG_DBG("Restored configuration state"); @@ -484,10 +479,6 @@ static void store_pending_cfg(void) val.gatt_proxy = bt_mesh_gatt_proxy_get(); val.frnd = bt_mesh_friend_get(); val.default_ttl = bt_mesh_default_ttl_get(); -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - val.on_demand_state = bt_mesh_od_priv_proxy_get(); -#endif - err = settings_save_one("bt/mesh/Cfg", &val, sizeof(val)); if (err) { diff --git a/subsys/bluetooth/mesh/od_priv_proxy.h b/subsys/bluetooth/mesh/od_priv_proxy.h new file mode 100644 index 00000000000..7baa7f067fc --- /dev/null +++ b/subsys/bluetooth/mesh/od_priv_proxy.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_mesh_od_priv_proxy_srv_store_schedule(void); diff --git a/subsys/bluetooth/mesh/od_priv_proxy_srv.c b/subsys/bluetooth/mesh/od_priv_proxy_srv.c index 32f5ea44179..b18a8ec7530 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_srv.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_srv.c @@ -9,11 +9,28 @@ #include "access.h" #include "cfg.h" #include "foundation.h" +#include "settings.h" #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_od_priv_proxy_srv); + +static struct bt_mesh_model *od_priv_proxy_srv; +static uint8_t on_demand_state; + +static int od_priv_proxy_store(bool delete) +{ + if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { + return 0; + } + + const void *data = delete ? NULL : &on_demand_state; + size_t len = delete ? 0 : sizeof(uint8_t); + + return bt_mesh_model_data_store(od_priv_proxy_srv, false, "pp", data, len); +} + static int proxy_status_rsp(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { @@ -64,6 +81,8 @@ const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_srv_op[] = { static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) { + od_priv_proxy_srv = mod; + struct bt_mesh_model *priv_beacon_srv = bt_mesh_model_find( bt_mesh_model_elem(mod), BT_MESH_MODEL_ID_PRIV_BEACON_SRV); struct bt_mesh_model *sol_pdu_rpl_srv = bt_mesh_model_find( @@ -89,6 +108,52 @@ static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) return 0; } +static void od_priv_proxy_srv_reset(struct bt_mesh_model *model) +{ + on_demand_state = 0; + od_priv_proxy_store(true); +} + +#ifdef CONFIG_BT_SETTINGS +static int od_priv_proxy_srv_settings_set(struct bt_mesh_model *model, const char *name, + size_t len_rd, settings_read_cb read_cb, void *cb_data) +{ + int err; + + if (len_rd == 0) { + LOG_DBG("Cleared configuration state"); + return 0; + } + + err = bt_mesh_settings_set(read_cb, cb_data, &on_demand_state, sizeof(uint8_t)); + if (err) { + LOG_ERR("Failed to set OD private proxy state"); + return err; + } + + bt_mesh_od_priv_proxy_set(on_demand_state); + return 0; +} + +static void od_priv_proxy_srv_pending_store(struct bt_mesh_model *model) +{ + on_demand_state = bt_mesh_od_priv_proxy_get(); + od_priv_proxy_store(false); +} +#endif + const struct bt_mesh_model_cb _bt_mesh_od_priv_proxy_srv_cb = { .init = od_priv_proxy_srv_init, + .reset = od_priv_proxy_srv_reset, +#ifdef CONFIG_BT_SETTINGS + .settings_set = od_priv_proxy_srv_settings_set, + .pending_store = od_priv_proxy_srv_pending_store, +#endif }; + +void bt_mesh_od_priv_proxy_srv_store_schedule(void) +{ + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_model_data_store_schedule(od_priv_proxy_srv); + } +} From 0f8b357d0ae036a113f65f6479bff9fc708527bf Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Mon, 11 Sep 2023 13:31:15 +0200 Subject: [PATCH 0206/4498] tests: Bluetooth: split `id_addr_update` test Split FW into two images, one for central one for peripheral. The SoftDevice controller's connection contexts are not role-agnostic: some are reserved for the peripheral roles some for the central roles. Splitting the test into two images is anyway "The right thing (TM)", it's just that we sometimes take the shortcut of using a single image to go faster. Signed-off-by: Jonathan Rico --- tests/bsim/bluetooth/host/compile.sh | 3 +- .../id_addr_update/central/CMakeLists.txt | 16 ++ .../id_addr_update/{ => central}/prj.conf | 2 +- .../{ => central}/src/central.c | 35 +++ .../bs_bt_utils.c => central/src/utils.c} | 79 ++----- .../id_addr_update/central/src/utils.h | 19 ++ .../{src => common}/bs_bt_utils.h | 5 +- .../{ => peripheral}/CMakeLists.txt | 7 +- .../id_addr_update/peripheral/prj.conf | 25 +++ .../{ => peripheral}/src/peripheral.c | 30 +++ .../id_addr_update/peripheral/src/utils.c | 210 ++++++++++++++++++ .../id_addr_update/peripheral/src/utils.h | 18 ++ .../host/security/id_addr_update/src/main.c | 40 ---- .../id_addr_update/test_scripts/_compile.sh | 6 +- .../id_addr_update/test_scripts/_env.sh | 9 +- .../id_addr_update/test_scripts/run_test.sh | 4 +- 16 files changed, 390 insertions(+), 118 deletions(-) create mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/central/CMakeLists.txt rename tests/bsim/bluetooth/host/security/id_addr_update/{ => central}/prj.conf (95%) rename tests/bsim/bluetooth/host/security/id_addr_update/{ => central}/src/central.c (63%) rename tests/bsim/bluetooth/host/security/id_addr_update/{src/bs_bt_utils.c => central/src/utils.c} (79%) create mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.h rename tests/bsim/bluetooth/host/security/id_addr_update/{src => common}/bs_bt_utils.h (95%) rename tests/bsim/bluetooth/host/security/id_addr_update/{ => peripheral}/CMakeLists.txt (83%) create mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/peripheral/prj.conf rename tests/bsim/bluetooth/host/security/id_addr_update/{ => peripheral}/src/peripheral.c (77%) create mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.c create mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.h delete mode 100644 tests/bsim/bluetooth/host/security/id_addr_update/src/main.c diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 6dcdddc3406..266fa88ab2f 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -69,7 +69,8 @@ app=tests/bsim/bluetooth/host/security/bond_overwrite_denied compile app=tests/bsim/bluetooth/host/security/bond_per_connection compile app=tests/bsim/bluetooth/host/security/ccc_update compile app=tests/bsim/bluetooth/host/security/ccc_update conf_file=prj_2.conf compile -app=tests/bsim/bluetooth/host/security/id_addr_update compile +app=tests/bsim/bluetooth/host/security/id_addr_update/central compile +app=tests/bsim/bluetooth/host/security/id_addr_update/peripheral compile app=tests/bsim/bluetooth/host/security/security_changed_callback compile app=tests/bsim/bluetooth/host/id/settings compile diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/central/CMakeLists.txt b/tests/bsim/bluetooth/host/security/id_addr_update/central/CMakeLists.txt new file mode 100644 index 00000000000..0ca6f4313bd --- /dev/null +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_id_addr_update) + +target_sources(app PRIVATE + src/central.c + src/utils.c) + +zephyr_include_directories( + ../common/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/prj.conf b/tests/bsim/bluetooth/host/security/id_addr_update/central/prj.conf similarity index 95% rename from tests/bsim/bluetooth/host/security/id_addr_update/prj.conf rename to tests/bsim/bluetooth/host/security/id_addr_update/central/prj.conf index 818505da4c5..789cce1f21f 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/prj.conf +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/prj.conf @@ -1,5 +1,4 @@ CONFIG_BT=y -CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_GATT_CLIENT=y @@ -21,6 +20,7 @@ CONFIG_LOG=y CONFIG_BT_ID_MAX=3 CONFIG_BT_MAX_PAIRED=2 + CONFIG_BT_MAX_CONN=2 CONFIG_BT_PRIVACY=y diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/src/central.c b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c similarity index 63% rename from tests/bsim/bluetooth/host/security/id_addr_update/src/central.c rename to tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c index 0739a92ea79..f6e22658e33 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/src/central.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c @@ -5,6 +5,7 @@ */ #include "bs_bt_utils.h" +#include "utils.h" #include "zephyr/bluetooth/addr.h" #include "zephyr/bluetooth/conn.h" @@ -12,6 +13,9 @@ #include +#include +LOG_MODULE_REGISTER(central, LOG_LEVEL_INF); + void central(void) { bs_bt_utils_setup(); @@ -20,33 +24,64 @@ void central(void) struct bt_conn *conn_b; /* Connect to the first identity of the peripheral. */ + LOG_INF("conn first"); scan_connect_to_first_result(); + LOG_INF("wait conn"); wait_connected(&conn_a); /* Subscribe to battery notifications and wait on the first one. */ + LOG_INF("subscribe first"); bas_subscribe(conn_a); wait_bas_notification(); /* Connect to the second identity of the peripheral. */ + LOG_INF("scan 2nd id"); scan_connect_to_first_result(); wait_connected(&conn_b); /* Establish security with the second identity and resolve identity address. */ + LOG_INF("set sec"); set_security(conn_b, BT_SECURITY_L2); wait_pairing_completed(); /* Wait for notification from the first connection after identity address resolution. */ + LOG_INF("wait notif"); wait_bas_notification(); /* Disconnect the first identity of the peripheral. */ + LOG_INF("discon id first"); disconnect(conn_a); wait_disconnected(); clear_conn(conn_a); /* Disconnect the second identity of the peripheral. */ + LOG_INF("discon id second"); disconnect(conn_b); wait_disconnected(); clear_conn(conn_b); PASS("PASS\n"); } + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "central", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = central, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.c similarity index 79% rename from tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.c rename to tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.c index dcf7c4535a0..a1ccc4f6996 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.c @@ -5,15 +5,13 @@ */ #include "bs_bt_utils.h" +#include "utils.h" BUILD_ASSERT(CONFIG_BT_MAX_PAIRED >= 2, "CONFIG_BT_MAX_PAIRED is too small."); BUILD_ASSERT(CONFIG_BT_ID_MAX >= 3, "CONFIG_BT_ID_MAX is too small."); BUILD_ASSERT(CONFIG_BT_MAX_CONN == 2, "CONFIG_BT_MAX_CONN should be equal to two."); BUILD_ASSERT(CONFIG_BT_GATT_CLIENT, "CONFIG_BT_GATT_CLIENT is disabled."); -#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * 1000000) -#define TEST_TIMEOUT_SIMULATED BS_SECONDS(60) - void test_tick(bs_time_t HW_device_time) { bs_trace_debug_time(0, "Simulation ends now.\n"); @@ -177,70 +175,10 @@ void disconnect(struct bt_conn *conn) ASSERT(!err, "Err bt_conn_disconnect %d", err); } -void advertise_connectable(int id) -{ - int err; - struct bt_le_adv_param param = {}; - - param.id = id; - param.interval_min = 0x0020; - param.interval_max = 0x4000; - param.options |= BT_LE_ADV_OPT_ONE_TIME; - param.options |= BT_LE_ADV_OPT_CONNECTABLE; - - err = bt_le_adv_start(¶m, NULL, 0, NULL, 0); - ASSERT(!err, "Advertising failed to start (err %d)\n", err); -} +DEFINE_FLAG(flag_bas_has_notification); -DEFINE_FLAG(flag_bas_ccc_subscribed); static uint8_t bas_level = 50; -static void bas_ccc_cfg_changed(const struct bt_gatt_attr *attr, - uint16_t value) -{ - ARG_UNUSED(attr); - - if (value == BT_GATT_CCC_NOTIFY) { - printk("BAS CCCD: notification enabled\n"); - SET_FLAG(flag_bas_ccc_subscribed); - } -} - -void wait_bas_ccc_subscription(void) -{ - WAIT_FOR_FLAG(flag_bas_ccc_subscribed); - UNSET_FLAG(flag_bas_ccc_subscribed); -} - -static ssize_t bas_read(struct bt_conn *conn, - const struct bt_gatt_attr *attr, void *buf, - uint16_t len, uint16_t offset) -{ - uint8_t lvl8 = bas_level; - - return bt_gatt_attr_read(conn, attr, buf, len, offset, &lvl8, - sizeof(lvl8)); -} - -BT_GATT_SERVICE_DEFINE(bas, - BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS), - BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ, bas_read, NULL, &bas_level), - BT_GATT_CCC(bas_ccc_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), -); - -void bas_notify(struct bt_conn *conn) -{ - int err; - - err = bt_gatt_notify(conn, &bas.attrs[2], &bas_level, sizeof(bas_level)); - ASSERT(!err, "bt_gatt_notify failed (err %d)\n", err); -} - -DEFINE_FLAG(flag_bas_has_notification); - static uint8_t bas_notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length) @@ -261,11 +199,24 @@ void wait_bas_notification(void) UNSET_FLAG(flag_bas_has_notification); } +/* Not actually used, see below why we also have this on the central */ +BT_GATT_SERVICE_DEFINE(bas, + BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS), + BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ, NULL, NULL, &bas_level), + BT_GATT_CCC(NULL, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +); + void bas_subscribe(struct bt_conn *conn) { int err; static struct bt_gatt_subscribe_params subscribe_params = {0}; + /* This is a bit of a shortcut: to skip discovery, we assume the handles + * will be the same on the central & peripheral images. + */ subscribe_params.ccc_handle = bt_gatt_attr_get_handle(&bas.attrs[3]); subscribe_params.value_handle = bt_gatt_attr_get_handle(&bas.attrs[2]); subscribe_params.value = BT_GATT_CCC_NOTIFY; diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.h b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.h new file mode 100644 index 00000000000..af79f165858 --- /dev/null +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/utils.h @@ -0,0 +1,19 @@ +#include +#include + +void test_tick(bs_time_t HW_device_time); +void test_init(void); + +void bs_bt_utils_setup(void); + +void clear_conn(struct bt_conn *conn); +void wait_connected(struct bt_conn **conn); +void wait_disconnected(void); +void disconnect(struct bt_conn *conn); +void scan_connect_to_first_result(void); + +void set_security(struct bt_conn *conn, bt_security_t sec); +void wait_pairing_completed(void); + +void bas_subscribe(struct bt_conn *conn); +void wait_bas_notification(void); diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h similarity index 95% rename from tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.h rename to tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h index bbee0ab7880..13dab52399c 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/src/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h @@ -1,5 +1,5 @@ /** - * Common functions and helpers for BSIM GATT tests + * Common functions and helpers for this test * * Copyright (c) 2023 Nordic Semiconductor ASA * @@ -27,6 +27,9 @@ extern enum bst_result_t bst_result; +#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * 1000000) +#define TEST_TIMEOUT_SIMULATED BS_SECONDS(60) + #define DECLARE_FLAG(flag) extern atomic_t flag #define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false #define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/CMakeLists.txt b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/CMakeLists.txt similarity index 83% rename from tests/bsim/bluetooth/host/security/id_addr_update/CMakeLists.txt rename to tests/bsim/bluetooth/host/security/id_addr_update/peripheral/CMakeLists.txt index 6bb8754c71d..5ea3558fa64 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/CMakeLists.txt +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/CMakeLists.txt @@ -6,13 +6,12 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(bsim_test_id_addr_update) target_sources(app PRIVATE - src/bs_bt_utils.c - src/central.c - src/main.c - src/peripheral.c + src/peripheral.c + src/utils.c ) zephyr_include_directories( + ../common/ ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ ) diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/prj.conf b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/prj.conf new file mode 100644 index 00000000000..86394cab289 --- /dev/null +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/prj.conf @@ -0,0 +1,25 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y + +# Both BT_SMP and BT_SETTINGS options need to be enabled to trigger +# code execution of the bt_gatt_identity_resolved function. +CONFIG_BT_SMP=y +CONFIG_BT_SETTINGS=y + +# Enabled the dependencies of the BT_SETTINGS option. +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_SETTINGS=y + +CONFIG_ASSERT=y +CONFIG_BT_TESTING=y +CONFIG_LOG=y + +CONFIG_BT_ID_MAX=3 +CONFIG_BT_MAX_PAIRED=2 + +CONFIG_BT_MAX_CONN=2 + +CONFIG_BT_PRIVACY=y diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/src/peripheral.c b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c similarity index 77% rename from tests/bsim/bluetooth/host/security/id_addr_update/src/peripheral.c rename to tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c index 530b5287dbf..daac93e5b4e 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c @@ -5,6 +5,7 @@ */ #include "bs_bt_utils.h" +#include "utils.h" #include "zephyr/bluetooth/addr.h" #include "zephyr/bluetooth/bluetooth.h" #include "zephyr/bluetooth/conn.h" @@ -13,6 +14,9 @@ #include #include +#include +LOG_MODULE_REGISTER(peripheral, LOG_LEVEL_INF); + static void verify_equal_address(struct bt_conn *conn_a, struct bt_conn *conn_b) { int err; @@ -47,7 +51,9 @@ void peripheral(void) ASSERT(id_b >= 0, "bt_id_create id_b failed (err %d)\n", id_b); /* Connect with the first identity. */ + LOG_INF("adv"); advertise_connectable(id_a); + LOG_INF("wait conn"); wait_connected(&conn_a); /* Send battery notification on the first connection. */ @@ -55,6 +61,7 @@ void peripheral(void) bas_notify(conn_a); /* Connect with the second identity. */ + LOG_INF("adv id 2"); advertise_connectable(id_b); wait_connected(&conn_b); @@ -77,3 +84,26 @@ void peripheral(void) PASS("PASS\n"); } + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "peripheral", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = peripheral, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.c b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.c new file mode 100644 index 00000000000..1e566fe1d4b --- /dev/null +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_bt_utils.h" +#include "utils.h" + +BUILD_ASSERT(CONFIG_BT_MAX_PAIRED >= 2, "CONFIG_BT_MAX_PAIRED is too small."); +BUILD_ASSERT(CONFIG_BT_ID_MAX >= 3, "CONFIG_BT_ID_MAX is too small."); +BUILD_ASSERT(CONFIG_BT_MAX_CONN == 2, "CONFIG_BT_MAX_CONN should be equal to two."); + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +DEFINE_FLAG(flag_has_new_conn); +struct bt_conn *new_conn; + +DEFINE_FLAG(flag_has_disconnected); + +void clear_conn(struct bt_conn *conn) +{ + if (new_conn == conn) { + new_conn = NULL; + } + + ASSERT(conn, "Test error: No new_conn!\n"); + bt_conn_unref(conn); +} + +void wait_connected(struct bt_conn **conn) +{ + WAIT_FOR_FLAG(flag_has_new_conn); + UNSET_FLAG(flag_has_new_conn); + + ASSERT(new_conn, "connection unpopulated."); + *conn = new_conn; + new_conn = NULL; +} + +void wait_disconnected(void) +{ + WAIT_FOR_FLAG(flag_has_disconnected); + UNSET_FLAG(flag_has_disconnected); +} + +static void print_conn_state_transition(const char *prefix, struct bt_conn *conn) +{ + int err; + struct bt_conn_info info; + char addr_str[BT_ADDR_LE_STR_LEN]; + + err = bt_conn_get_info(conn, &info); + ASSERT(!err, "Unexpected conn info result."); + + bt_addr_le_to_str(info.le.dst, addr_str, sizeof(addr_str)); + printk("%s: %s\n", prefix, addr_str); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + print_conn_state_transition("Disonnected", conn); + SET_FLAG(flag_has_disconnected); +} + +static void connected(struct bt_conn *conn, uint8_t err) +{ + ASSERT((!new_conn || (conn == new_conn)), "Unexpected new connection."); + + if (!new_conn) { + new_conn = bt_conn_ref(conn); + } + + if (err != 0) { + clear_conn(conn); + return; + } + + print_conn_state_transition("Connected", conn); + SET_FLAG(flag_has_new_conn); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +DEFINE_FLAG(flag_pairing_completed); + +static void pairing_complete(struct bt_conn *conn, bool bonded) +{ + print_conn_state_transition("Paired", conn); + SET_FLAG(flag_pairing_completed); +} + +static struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { + .pairing_complete = pairing_complete, +}; + +void set_security(struct bt_conn *conn, bt_security_t sec) +{ + int err; + + err = bt_conn_set_security(conn, sec); + ASSERT(!err, "Err bt_conn_set_security %d", err); +} + +void wait_pairing_completed(void) +{ + WAIT_FOR_FLAG(flag_pairing_completed); + UNSET_FLAG(flag_pairing_completed); +} + +void bs_bt_utils_setup(void) +{ + int err; + + err = bt_enable(NULL); + ASSERT(!err, "bt_enable failed.\n"); + err = bt_conn_auth_info_cb_register(&bt_conn_auth_info_cb); + ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); + + err = settings_load(); + ASSERT(!err, "settings_load failed.\n"); +} + +void disconnect(struct bt_conn *conn) +{ + int err; + + err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + ASSERT(!err, "Err bt_conn_disconnect %d", err); +} + +void advertise_connectable(int id) +{ + int err; + struct bt_le_adv_param param = {}; + + param.id = id; + param.interval_min = 0x0020; + param.interval_max = 0x4000; + param.options |= BT_LE_ADV_OPT_ONE_TIME; + param.options |= BT_LE_ADV_OPT_CONNECTABLE; + + err = bt_le_adv_start(¶m, NULL, 0, NULL, 0); + ASSERT(!err, "Advertising failed to start (err %d)\n", err); +} + +DEFINE_FLAG(flag_bas_ccc_subscribed); +static uint8_t bas_level = 50; + +static void bas_ccc_cfg_changed(const struct bt_gatt_attr *attr, + uint16_t value) +{ + ARG_UNUSED(attr); + + if (value == BT_GATT_CCC_NOTIFY) { + printk("BAS CCCD: notification enabled\n"); + SET_FLAG(flag_bas_ccc_subscribed); + } +} + +void wait_bas_ccc_subscription(void) +{ + WAIT_FOR_FLAG(flag_bas_ccc_subscribed); + UNSET_FLAG(flag_bas_ccc_subscribed); +} + +static ssize_t bas_read(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + uint8_t lvl8 = bas_level; + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &lvl8, + sizeof(lvl8)); +} + +BT_GATT_SERVICE_DEFINE(bas, + BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS), + BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ, bas_read, NULL, &bas_level), + BT_GATT_CCC(bas_ccc_cfg_changed, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +); + +void bas_notify(struct bt_conn *conn) +{ + int err; + + err = bt_gatt_notify(conn, &bas.attrs[2], &bas_level, sizeof(bas_level)); + ASSERT(!err, "bt_gatt_notify failed (err %d)\n", err); +} + +DEFINE_FLAG(flag_bas_has_notification); diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.h b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.h new file mode 100644 index 00000000000..01690b2c82c --- /dev/null +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/utils.h @@ -0,0 +1,18 @@ +#include +#include + +void test_tick(bs_time_t HW_device_time); +void test_init(void); + +void bs_bt_utils_setup(void); + +void clear_conn(struct bt_conn *conn); +void wait_connected(struct bt_conn **conn); +void wait_disconnected(void); +void disconnect(struct bt_conn *conn); +void advertise_connectable(int id); + +void set_security(struct bt_conn *conn, bt_security_t sec); +void wait_pairing_completed(void); + +void bas_notify(struct bt_conn *conn); diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/src/main.c b/tests/bsim/bluetooth/host/security/id_addr_update/src/main.c deleted file mode 100644 index 7553f7b5f83..00000000000 --- a/tests/bsim/bluetooth/host/security/id_addr_update/src/main.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "bs_bt_utils.h" -#include "bstests.h" - -void central(void); -void peripheral(void); - -static const struct bst_test_instance test_to_add[] = { - { - .test_id = "central", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = central, - }, - { - .test_id = "peripheral", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = peripheral, - }, - BSTEST_END_MARKER, -}; - -static struct bst_test_list *install(struct bst_test_list *tests) -{ - return bst_add_tests(tests, test_to_add); -}; - -bst_test_install_t test_installers[] = {install, NULL}; - -int main(void) -{ - bst_main(); - return 0; -} diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_compile.sh index a19e4baf6e4..ca555ea526c 100755 --- a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_compile.sh +++ b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_compile.sh @@ -17,4 +17,8 @@ BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" INCR_BUILD=1 mkdir -p ${WORK_DIR} source ${ZEPHYR_BASE}/tests/bsim/compile.source -app="tests/bsim/bluetooth/host/security/$test_name" compile + +app="tests/bsim/bluetooth/host/security/$test_name/central" compile +app="tests/bsim/bluetooth/host/security/$test_name/peripheral" compile + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_env.sh b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_env.sh index fec28290db9..8ac4b9eaf69 100755 --- a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/_env.sh @@ -9,10 +9,11 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" test_name="id_addr_update" bsim_bin="${BSIM_OUT_PATH}/bin" verbosity_level=2 -BOARD="${BOARD:-nrf52_bsim}" +board="${BOARD:-nrf52_bsim}" simulation_id="$test_name" -central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_security_${test_name}_prj_conf" -peripheral_exe="${central_exe}" +test_path="tests_bsim_bluetooth_host_security_${test_name}" +central_exe="${bsim_bin}/bs_${board}_${test_path}_central_prj_conf" +peripheral_exe="${bsim_bin}/bs_${board}_${test_path}_peripheral_prj_conf" function print_var { # Print a shell-sourceable variable definition. @@ -24,7 +25,7 @@ function print_var { print_var test_name print_var bsim_bin print_var verbosity_level -print_var BOARD +print_var board print_var simulation_id print_var central_exe print_var peripheral_exe diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/run_test.sh index 351f44523cc..b44fa62d61c 100755 --- a/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/security/id_addr_update/test_scripts/run_test.sh @@ -9,7 +9,7 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" source "${bash_source_dir}/_env.sh" source ${ZEPHYR_BASE}/tests/bsim/sh_common.source -EXECUTE_TIMEOUT=30 +EXECUTE_TIMEOUT=10 cd ${BSIM_OUT_PATH}/bin @@ -17,7 +17,7 @@ Execute "$central_exe" \ -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 Execute "$peripheral_exe" \ - -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 -rs=200 Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ -D=2 -sim_length=60e6 $@ From 81cc13d075dbff1100693a593450c50b8c22dcf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 11 Sep 2023 12:14:16 +0200 Subject: [PATCH 0207/4498] logging: Fix increase of code size when CONFIG_LOG=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When logging was disabled there was still a code size increase due to log module structure being kept in the memory even though it was unused. When CONFIG_LOG=n there should be nothing in the memory footprint related to the logging. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/zephyr/logging/log.h b/include/zephyr/logging/log.h index b5ee3b67ab4..7b7dbb56b8a 100644 --- a/include/zephyr/logging/log.h +++ b/include/zephyr/logging/log.h @@ -324,10 +324,11 @@ void z_log_vprintk(const char *fmt, va_list ap); * is enabled, override level is set or module specific level is set (not off). */ #define Z_DO_LOG_MODULE_REGISTER(...) \ - Z_LOG_EVAL(CONFIG_LOG_OVERRIDE_LEVEL, \ + COND_CODE_1(CONFIG_LOG, \ + (Z_LOG_EVAL(CONFIG_LOG_OVERRIDE_LEVEL, \ (1), \ (Z_LOG_EVAL(_LOG_LEVEL_RESOLVE(__VA_ARGS__), (1), (0))) \ - ) + )), (0)) /** * @brief Create module-specific state and register the module with Logger. From 64c46ae56af9d58749a587f06a74383c776b357d Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 10 Sep 2023 16:00:57 +0200 Subject: [PATCH 0208/4498] drivers: display: st7735r: add hold-CS transmit() ST7735S support (separate commits) needs this. Signed-off-by: David Lamparter --- drivers/display/display_st7735r.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/display/display_st7735r.c b/drivers/display/display_st7735r.c index 7d0f4aa6ac9..393d7153d14 100644 --- a/drivers/display/display_st7735r.c +++ b/drivers/display/display_st7735r.c @@ -75,8 +75,8 @@ static void st7735r_set_cmd(const struct device *dev, int is_cmd) gpio_pin_set_dt(&config->cmd_data, is_cmd); } -static int st7735r_transmit(const struct device *dev, uint8_t cmd, - const uint8_t *tx_data, size_t tx_count) +static int st7735r_transmit_hold(const struct device *dev, uint8_t cmd, + const uint8_t *tx_data, size_t tx_count) { const struct st7735r_config *config = dev->config; struct spi_buf tx_buf = { .buf = &cmd, .len = 1 }; @@ -102,6 +102,17 @@ static int st7735r_transmit(const struct device *dev, uint8_t cmd, return 0; } +static int st7735r_transmit(const struct device *dev, uint8_t cmd, + const uint8_t *tx_data, size_t tx_count) +{ + const struct st7735r_config *config = dev->config; + int ret; + + ret = st7735r_transmit_hold(dev, cmd, tx_data, tx_count); + spi_release_dt(&config->bus); + return ret; +} + static int st7735r_exit_sleep(const struct device *dev) { int ret; @@ -539,7 +550,8 @@ static const struct display_driver_api st7735r_api = { #define ST7735R_INIT(inst) \ const static struct st7735r_config st7735r_config_ ## inst = { \ .bus = SPI_DT_SPEC_INST_GET( \ - inst, SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0), \ + inst, SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | \ + SPI_HOLD_ON_CS | SPI_LOCK_ON, 0), \ .cmd_data = GPIO_DT_SPEC_INST_GET(inst, cmd_data_gpios), \ .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}), \ .width = DT_INST_PROP(inst, width), \ From 19113d6e8ca9809aad73e70d34139ad982502b1e Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 10 Sep 2023 16:13:34 +0200 Subject: [PATCH 0209/4498] drivers: display: st7735r: hold CS for pixels Use a continuous transaction with CS kept low for the entire batch of row address, column address and actual pixel data write. This is required by ST7735S and shouldn't hurt elsewhere. Signed-off-by: David Lamparter --- drivers/display/display_st7735r.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/display/display_st7735r.c b/drivers/display/display_st7735r.c index 393d7153d14..7569e906ed8 100644 --- a/drivers/display/display_st7735r.c +++ b/drivers/display/display_st7735r.c @@ -182,18 +182,19 @@ static int st7735r_set_mem_area(const struct device *dev, spi_data[0] = sys_cpu_to_be16(ram_x); spi_data[1] = sys_cpu_to_be16(ram_x + w - 1); - ret = st7735r_transmit(dev, ST7735R_CMD_CASET, (uint8_t *)&spi_data[0], 4); + ret = st7735r_transmit_hold(dev, ST7735R_CMD_CASET, (uint8_t *)&spi_data[0], 4); if (ret < 0) { return ret; } spi_data[0] = sys_cpu_to_be16(ram_y); spi_data[1] = sys_cpu_to_be16(ram_y + h - 1); - ret = st7735r_transmit(dev, ST7735R_CMD_RASET, (uint8_t *)&spi_data[0], 4); + ret = st7735r_transmit_hold(dev, ST7735R_CMD_RASET, (uint8_t *)&spi_data[0], 4); if (ret < 0) { return ret; } + /* NB: CS still held - data transfer coming next */ return 0; } @@ -220,7 +221,7 @@ static int st7735r_write(const struct device *dev, desc->width, desc->height, x, y); ret = st7735r_set_mem_area(dev, x, y, desc->width, desc->height); if (ret < 0) { - return ret; + goto out; } if (desc->pitch > desc->width) { @@ -231,11 +232,11 @@ static int st7735r_write(const struct device *dev, nbr_of_writes = 1U; } - ret = st7735r_transmit(dev, ST7735R_CMD_RAMWR, - (void *) write_data_start, - desc->width * ST7735R_PIXEL_SIZE * write_h); + ret = st7735r_transmit_hold(dev, ST7735R_CMD_RAMWR, + (void *) write_data_start, + desc->width * ST7735R_PIXEL_SIZE * write_h); if (ret < 0) { - return ret; + goto out; } tx_bufs.buffers = &tx_buf; @@ -247,13 +248,16 @@ static int st7735r_write(const struct device *dev, tx_buf.len = desc->width * ST7735R_PIXEL_SIZE * write_h; ret = spi_write_dt(&config->bus, &tx_bufs); if (ret < 0) { - return ret; + goto out; } write_data_start += (desc->pitch * ST7735R_PIXEL_SIZE); } - return 0; + ret = 0; +out: + spi_release_dt(&config->bus); + return ret; } static void *st7735r_get_framebuffer(const struct device *dev) From ea717bba217490ac2f5bd4628b476a95f635e2dc Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 10 Sep 2023 16:15:22 +0200 Subject: [PATCH 0210/4498] drivers: display: st7735r: support ST7735S ST7735S requires the COLMOD command be repeated as part of writing pixels, otherwise it goes back to some kind of default which is likely wrong. ST7735S works correctly after this plus the previous two commits; tested on STM32L462 + KD0096FM. Signed-off-by: David Lamparter --- drivers/display/display_st7735r.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/display/display_st7735r.c b/drivers/display/display_st7735r.c index 7569e906ed8..a20242d9703 100644 --- a/drivers/display/display_st7735r.c +++ b/drivers/display/display_st7735r.c @@ -172,11 +172,18 @@ static int st7735r_set_mem_area(const struct device *dev, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) { + const struct st7735r_config *config = dev->config; struct st7735r_data *data = dev->data; uint16_t spi_data[2]; int ret; + /* ST7735S requires repeating COLMOD for each transfer */ + ret = st7735r_transmit_hold(dev, ST7735R_CMD_COLMOD, &config->colmod, 1); + if (ret < 0) { + return ret; + } + uint16_t ram_x = x + data->x_offset; uint16_t ram_y = y + data->y_offset; From a532dbab510fd45aec318d4f658d07cd9d200cbd Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 10 Sep 2023 16:25:49 +0200 Subject: [PATCH 0211/4498] doc: list ST7735S alongside ST7735R Throw ST7735S into a few places so people can find it. Signed-off-by: David Lamparter --- doc/releases/release-notes-3.5.rst | 2 ++ drivers/display/Kconfig.st7735r | 4 ++-- dts/bindings/display/sitronix,st7735r.yaml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 3612c6d8ae5..9019af80123 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -140,6 +140,8 @@ Drivers and Sensors * Display + * Added support for ST7735S (in ST7735R driver) + * DMA * EEPROM diff --git a/drivers/display/Kconfig.st7735r b/drivers/display/Kconfig.st7735r index 383df0aa0d8..94153eca585 100644 --- a/drivers/display/Kconfig.st7735r +++ b/drivers/display/Kconfig.st7735r @@ -4,9 +4,9 @@ # SPDX-License-Identifier: Apache-2.0 config ST7735R - bool "ST7735R display driver" + bool "ST7735R/ST7735S display driver" default y depends on DT_HAS_SITRONIX_ST7735R_ENABLED select SPI help - Enable driver for ST7735R display driver. + Enable driver for ST7735R/ST7735S display driver. diff --git a/dts/bindings/display/sitronix,st7735r.yaml b/dts/bindings/display/sitronix,st7735r.yaml index 987ff620ec5..90ead2b8731 100644 --- a/dts/bindings/display/sitronix,st7735r.yaml +++ b/dts/bindings/display/sitronix,st7735r.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2020, Kim Bøndergaard # SPDX-License-Identifier: Apache-2.0 -description: ST7735R 160x128 display controller +description: ST7735R/ST7735S 160x128 (max) display controller compatible: "sitronix,st7735r" From 012457580b97e5cb07bf79048de683dad24fbc1d Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Wed, 6 Sep 2023 12:25:22 +0200 Subject: [PATCH 0212/4498] modem: backends: uart: fix backend selection Modem backed configs should be used instead of uart. Signed-off-by: Wojciech Slenska --- subsys/modem/backends/modem_backend_uart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/modem/backends/modem_backend_uart.c b/subsys/modem/backends/modem_backend_uart.c index 91e062b8717..b4b0b81c291 100644 --- a/subsys/modem/backends/modem_backend_uart.c +++ b/subsys/modem/backends/modem_backend_uart.c @@ -36,18 +36,18 @@ struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend, backend->uart = config->uart; k_work_init(&backend->receive_ready_work, modem_backend_uart_receive_ready_handler); -#ifdef CONFIG_UART_ASYNC_API +#ifdef CONFIG_MODEM_BACKEND_UART_ASYNC if (modem_backend_uart_async_is_supported(backend)) { modem_backend_uart_async_init(backend, config); return &backend->pipe; } -#endif /* CONFIG_UART_ASYNC_API */ +#endif /* CONFIG_MODEM_BACKEND_UART_ASYNC */ -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#ifdef CONFIG_MODEM_BACKEND_UART_ISR modem_backend_uart_isr_init(backend, config); return &backend->pipe; -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#endif /* CONFIG_MODEM_BACKEND_UART_ISR */ __ASSERT(0, "No supported UART API"); From 08130f0310e3c8175ccbbdb513e3d0762fffbec3 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Fri, 8 Sep 2023 11:46:15 +0200 Subject: [PATCH 0213/4498] modem: chat: script should be const This change reduce RAM usage of chat scripts. Signed-off-by: Wojciech Slenska --- include/zephyr/modem/chat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index 5f2ff4a9165..f25e1d9893b 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -144,7 +144,7 @@ struct modem_chat_script { }; #define MODEM_CHAT_SCRIPT_DEFINE(_sym, _script_chats, _abort_matches, _callback, _timeout) \ - static struct modem_chat_script _sym = { \ + const static struct modem_chat_script _sym = { \ .name = #_sym, \ .script_chats = _script_chats, \ .script_chats_size = ARRAY_SIZE(_script_chats), \ From a2f92bad9293dbb171d80def00c2987b8e6f6d66 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Tue, 22 Aug 2023 11:16:10 +0200 Subject: [PATCH 0214/4498] bluetooth: tester: MICS Server tests Add support for MICS Server tests Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/src/btp/btp.h | 4 +- tests/bluetooth/tester/src/btp/btp_mics.h | 23 +++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_core.c | 9 +- tests/bluetooth/tester/src/btp_micp.c | 216 +++++++++++++++++++++- 5 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_mics.h diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index f925308fbc1..6736334ceaa 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -26,6 +26,7 @@ #include "btp_has.h" #include "btp_csis.h" #include "btp_micp.h" +#include "btp_mics.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -51,8 +52,9 @@ #define BTP_SERVICE_ID_HAS 15 #define BTP_SERVICE_ID_MICP 16 #define BTP_SERVICE_ID_CSIS 17 +#define BTP_SERVICE_ID_MICS 18 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CSIS +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_MICS #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/tests/bluetooth/tester/src/btp/btp_mics.h b/tests/bluetooth/tester/src/btp/btp_mics.h new file mode 100644 index 00000000000..924abb696c5 --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_mics.h @@ -0,0 +1,23 @@ +/* btp_mics.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* MICS commands */ +#define BTP_MICS_READ_SUPPORTED_COMMANDS 0x01 +struct btp_mics_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MICS_DEV_MUTE_DISABLE 0x02 +#define BTP_MICS_DEV_MUTE_READ 0x03 +#define BTP_MICS_DEV_MUTE 0x04 +#define BTP_MICS_DEV_UNMUTE 0x05 + +#define BTP_MICS_MUTE_STATE_EV 0x80 +struct btp_mics_mute_state_ev { + uint8_t mute; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index e3ba93b0de7..807b890036b 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -95,3 +95,6 @@ uint8_t tester_unregister_csis(void); uint8_t tester_init_micp(void); uint8_t tester_unregister_micp(void); + +uint8_t tester_init_mics(void); +uint8_t tester_unregister_mics(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index e1dafb09351..6f09b1337e4 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -148,10 +148,15 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; - case BTP_SERVICE_ID_MICP: +#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ +#if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) + case BTP_SERVICE_ID_MICP: status = tester_init_micp(); break; -#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ + case BTP_SERVICE_ID_MICS: + status = tester_init_mics(); + break; +#endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: status = tester_init_has(); diff --git a/tests/bluetooth/tester/src/btp_micp.c b/tests/bluetooth/tester/src/btp_micp.c index 52b071469af..8e0d59ee4fb 100644 --- a/tests/bluetooth/tester/src/btp_micp.c +++ b/tests/bluetooth/tester/src/btp_micp.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -30,6 +31,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); static struct bt_micp_mic_ctlr *mic_ctlr; +static struct bt_micp_mic_dev_register_param mic_dev_register_param; #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) static struct bt_micp_included micp_included; @@ -47,6 +49,7 @@ extern struct btp_aics_instance aics_client_instance; extern struct bt_aics_cb aics_client_cb; #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ +/* Microphone Control Profile */ static void btp_send_micp_found_ev(struct bt_conn *conn, const struct chrc_handles *micp_handles) { struct btp_micp_discovered_ev ev; @@ -237,7 +240,7 @@ static const struct btp_handler micp_handlers[] = { .opcode = BTP_MICP_CTLR_MUTE, .expect_len = sizeof(struct btp_micp_mute_cmd), .func = micp_mute, - } + }, }; uint8_t tester_init_micp(void) @@ -262,3 +265,214 @@ uint8_t tester_unregister_micp(void) (void)bt_micp_mic_ctlr_cb_register(NULL); return BTP_STATUS_SUCCESS; } + +/* Microphone Control Service */ +static uint8_t mics_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + struct btp_mics_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_MICS_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_MICS_DEV_MUTE_DISABLE); + tester_set_bit(rp->data, BTP_MICS_DEV_MUTE_READ); + tester_set_bit(rp->data, BTP_MICS_DEV_MUTE); + tester_set_bit(rp->data, BTP_MICS_DEV_UNMUTE); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mics_mute_disable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("MICP Mute disable"); + + err = bt_micp_mic_dev_mute_disable(); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mics_mute_read(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("MICS Mute state read"); + + err = bt_micp_mic_dev_mute_get(); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mics_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("MICS Mute"); + + err = bt_micp_mic_dev_mute(); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mics_unmute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("MICS Mute"); + + err = bt_micp_mic_dev_unmute(); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static void btp_send_mics_mute_state_ev(uint8_t mute) +{ + struct btp_mics_mute_state_ev ev; + + ev.mute = mute; + + tester_event(BTP_SERVICE_ID_MICS, BTP_MICS_MUTE_STATE_EV, &ev, sizeof(ev)); +} + +static void mic_dev_mute_cb(uint8_t mute) +{ + LOG_DBG("Microphone Device Mute cb"); + + btp_send_mics_mute_state_ev(mute); +} + +static struct bt_micp_mic_dev_cb mic_dev_cb = { + .mute = mic_dev_mute_cb, +}; + +#if defined(CONFIG_BT_MICP_MIC_DEV_AICS) +static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, + uint8_t mute, uint8_t mode) +{ + LOG_DBG("AICS state callback (%d)", err); +} + +static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, + int8_t minimum, int8_t maximum) +{ + LOG_DBG("AICS gain setting callback (%d)", err); +} + +static void aics_input_type_cb(struct bt_aics *inst, int err, + uint8_t input_type) +{ + LOG_DBG("AICS input type callback (%d)", err); +} + +static void aics_status_cb(struct bt_aics *inst, int err, bool active) +{ + LOG_DBG("AICS status callback (%d)", err); +} + +static void aics_description_cb(struct bt_aics *inst, int err, + char *description) +{ + LOG_DBG("AICS description callback (%d)", err); +} + +struct bt_aics_cb aics_mic_dev_cb = { + .state = aics_state_cb, + .gain_setting = aics_gain_setting_cb, + .type = aics_input_type_cb, + .status = aics_status_cb, + .description = aics_description_cb, +}; +#endif /* CONFIG_BT_MICP_MIC_DEV_AICS */ + +static const struct btp_handler mics_handlers[] = { + { + .opcode = BTP_MICS_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = mics_supported_commands, + }, + { + .opcode = BTP_MICS_DEV_MUTE_DISABLE, + .expect_len = 0, + .func = mics_mute_disable, + }, + { + .opcode = BTP_MICS_DEV_MUTE_READ, + .expect_len = 0, + .func = mics_mute_read, + }, + { + .opcode = BTP_MICS_DEV_MUTE, + .expect_len = 0, + .func = mics_mute, + }, + { + .opcode = BTP_MICS_DEV_UNMUTE, + .expect_len = 0, + .func = mics_unmute, + }, +}; + +uint8_t tester_init_mics(void) +{ + int err; + + memset(&mic_dev_register_param, 0, sizeof(mic_dev_register_param)); + +#if defined(CONFIG_BT_MICP_MIC_DEV_AICS) + char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16]; + + for (size_t i = 0; i < ARRAY_SIZE(mic_dev_register_param.aics_param); i++) { + mic_dev_register_param.aics_param[i].desc_writable = true; + snprintf(input_desc[i], sizeof(input_desc[i]), + "Input %zu", i + 1); + mic_dev_register_param.aics_param[i].description = input_desc[i]; + mic_dev_register_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL; + mic_dev_register_param.aics_param[i].status = 1; + mic_dev_register_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL; + mic_dev_register_param.aics_param[i].units = 1; + mic_dev_register_param.aics_param[i].min_gain = 0; + mic_dev_register_param.aics_param[i].max_gain = 100; + mic_dev_register_param.aics_param[i].cb = &aics_mic_dev_cb; + } +#endif /* CONFIG_BT_MICP_MIC_DEV_AICS */ + + mic_dev_register_param.cb = &mic_dev_cb; + + err = bt_micp_mic_dev_register(&mic_dev_register_param); + if (err) { + return BTP_STATUS_FAILED; + } + +#if defined(CONFIG_BT_MICP_MIC_DEV_AICS) + err = bt_micp_mic_dev_included_get(&micp_included); + if (err) { + return BTP_STATUS_FAILED; + } +#endif /* CONFIG_BT_MICP_MIC_DEV_AICS */ + + tester_register_command_handlers(BTP_SERVICE_ID_MICS, mics_handlers, + ARRAY_SIZE(mics_handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_mics(void) +{ + return BTP_STATUS_SUCCESS; +} From f2a2d30d06f4d3fbba2ab4e880bb2fc9c6460484 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 8 Sep 2023 18:04:00 +0300 Subject: [PATCH 0215/4498] net: capture: Fix the API documentation The net_capture_send() is only to be called from capture implementation itself, so the API does not need to be public thus hide it from generated documentation. Signed-off-by: Jukka Rissanen --- include/zephyr/net/capture.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/capture.h b/include/zephyr/net/capture.h index b4d9ce323a1..ac8ccdb905d 100644 --- a/include/zephyr/net/capture.h +++ b/include/zephyr/net/capture.h @@ -166,6 +166,8 @@ static inline int net_capture_disable(const struct device *dev) #endif } +/** @cond INTERNAL_HIDDEN */ + /** * @brief Send captured packet. * @@ -192,8 +194,6 @@ static inline int net_capture_send(const struct device *dev, struct net_if *ifac #endif } -/** @cond INTERNAL_HIDDEN */ - /** * @brief Check if the network packet needs to be captured or not. * This is called for every network packet being sent. From 662a14a25e4160d0089af81f518dac0744eb4905 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Fri, 8 Sep 2023 13:31:24 +0800 Subject: [PATCH 0216/4498] tests: net: lib: lwm2m: fix the missing float support The tests `content_json` and `content_plain_test` depend on the float support of libc. After PR##57340, Picolibc would be selected in these two tests and the `PICOLIBC_IO_FLOAT` won't be selected if the platform doesn't select `FPU`. This commit select `CONFIG_PICOLIBC` and `CONFIG_PICOLIBC_IO_FLOAT` for these two tests. Signed-off-by: Huifeng Zhang --- tests/net/lib/lwm2m/content_json/prj.conf | 2 ++ tests/net/lib/lwm2m/content_plain_text/prj.conf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/net/lib/lwm2m/content_json/prj.conf b/tests/net/lib/lwm2m/content_json/prj.conf index 3f2cd3e60f2..7ff07df9897 100644 --- a/tests/net/lib/lwm2m/content_json/prj.conf +++ b/tests/net/lib/lwm2m/content_json/prj.conf @@ -9,3 +9,5 @@ CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 CONFIG_LWM2M_RW_JSON_SUPPORT=y CONFIG_JSON_LIBRARY=y + +CONFIG_PICOLIBC_IO_FLOAT=y diff --git a/tests/net/lib/lwm2m/content_plain_text/prj.conf b/tests/net/lib/lwm2m/content_plain_text/prj.conf index 6041addad83..877c969958f 100644 --- a/tests/net/lib/lwm2m/content_plain_text/prj.conf +++ b/tests/net/lib/lwm2m/content_plain_text/prj.conf @@ -6,3 +6,5 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_LWM2M=y + +CONFIG_PICOLIBC_IO_FLOAT=y From 147109adb0785fddc8d2ea4fcdbd3468e533e65d Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Sat, 9 Sep 2023 08:00:30 +0200 Subject: [PATCH 0217/4498] boards: Add lvgl pointer support on m5stack_core2 Added lvgl-pointer definition in devicetree, to enable touch-support in lvgl applications. Kscan support has been removed from m5stack_core2 as this was just a temporary thing. Has been tested with lvgl hello world sample. Signed-off-by: Martin Kiepfer --- boards/xtensa/m5stack_core2/Kconfig.defconfig | 5 +---- boards/xtensa/m5stack_core2/m5stack_core2.dts | 12 ++++++------ .../subsys/display/lvgl/boards/m5stack_core2.conf | 3 +++ 3 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 samples/subsys/display/lvgl/boards/m5stack_core2.conf diff --git a/boards/xtensa/m5stack_core2/Kconfig.defconfig b/boards/xtensa/m5stack_core2/Kconfig.defconfig index 278ef95cd88..2e68d5614d0 100644 --- a/boards/xtensa/m5stack_core2/Kconfig.defconfig +++ b/boards/xtensa/m5stack_core2/Kconfig.defconfig @@ -39,11 +39,8 @@ config GPIO_HOGS_INIT_PRIORITY config INPUT_FT5336_INTERRUPT default y if INPUT -config KSCAN - default y if DISPLAY - config INPUT - default y if KSCAN + default y config LV_COLOR_16_SWAP default y if LVGL diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index 0f804d5926b..2e70e5b6405 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -30,7 +30,6 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,display = &ili9342c; - zephyr,keyboard-scan = &kscan_input; zephyr,code-partition = &slot0_partition; zephyr,rtc = &pfc8563_rtc; }; @@ -42,6 +41,11 @@ label = "Power LED"; }; }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <&ft5336_touch>; + }; }; &cpu0 { @@ -154,14 +158,10 @@ }; }; - ft5336@38 { + ft5336_touch: ft5336@38 { compatible = "focaltech,ft5336"; reg = <0x38>; int-gpios = <&gpio1 7 0>; - - kscan_input: kscan-input { - compatible = "zephyr,kscan-input"; - }; }; }; diff --git a/samples/subsys/display/lvgl/boards/m5stack_core2.conf b/samples/subsys/display/lvgl/boards/m5stack_core2.conf new file mode 100644 index 00000000000..1ac2b1c55c9 --- /dev/null +++ b/samples/subsys/display/lvgl/boards/m5stack_core2.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=4096 From 555baf719716f97bb8ce881df00a49a4c22546dc Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Mon, 11 Sep 2023 21:09:25 +0200 Subject: [PATCH 0218/4498] boards: m5stack_core2: Increase i2c bitrate on i2c0 All periphals connected on i2c0 support 400kbit. The default speed has been increased to improve responsiveness. Signed-off-by: Martin Kiepfer --- boards/xtensa/m5stack_core2/m5stack_core2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index 2e70e5b6405..f90a19c3981 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -85,7 +85,7 @@ &i2c0 { status = "okay"; - clock-frequency = ; + clock-frequency = ; sda-gpios = <&gpio0 21 GPIO_OPEN_DRAIN>; scl-gpios = <&gpio0 22 GPIO_OPEN_DRAIN>; pinctrl-0 = <&i2c0_default>; From 0711a40cf7846f527fc050a1367374a7182fcfcb Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 11 Sep 2023 11:01:51 +0200 Subject: [PATCH 0219/4498] boards nrf52_bsim: bstests: Use malloc safely Use the wrapped version of the malloc function which checks that malloc succeeded before continuing, so in the unlikely case that we run out of memory we handle it gracefully. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/common/bstests_entry.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boards/posix/nrf52_bsim/common/bstests_entry.c b/boards/posix/nrf52_bsim/common/bstests_entry.c index ee61811ee3d..1f9afda15a6 100644 --- a/boards/posix/nrf52_bsim/common/bstests_entry.c +++ b/boards/posix/nrf52_bsim/common/bstests_entry.c @@ -9,6 +9,7 @@ #include "bs_types.h" #include "bs_tracing.h" #include "bstests.h" +#include "bs_oswrap.h" /* * Result of the testcase execution. @@ -38,7 +39,7 @@ struct bst_test_list *bst_add_tests(struct bst_test_list *tests, } } else { if (test_def[idx].test_id != NULL) { - head = malloc(sizeof(struct bst_test_list)); + head = bs_malloc(sizeof(struct bst_test_list)); head->next = NULL; head->test_instance = (struct bst_test_instance *) &test_def[idx++]; @@ -47,7 +48,7 @@ struct bst_test_list *bst_add_tests(struct bst_test_list *tests, } while (test_def[idx].test_id != NULL) { - tail->next = malloc(sizeof(struct bst_test_list)); + tail->next = bs_malloc(sizeof(struct bst_test_list)); tail = tail->next; tail->test_instance = (struct bst_test_instance *) &test_def[idx++]; From 97c2ef66661614984beb0f9f9316b33b31a576d4 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 7 Sep 2023 10:35:00 -0500 Subject: [PATCH 0220/4498] drivers: clock_control_mcux_syscon: add sctimer Add SCTIMER key to syscon clock control Signed-off-by: Declan Snyder --- drivers/clock_control/clock_control_mcux_syscon.c | 3 +++ include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index a8cf4f240fe..2349be21711 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -145,6 +145,9 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate( break; #endif +#if defined(CONFIG_PWM_MCUX_SCTIMER) + case MCUX_SCTIMER_CLK: +#endif case MCUX_BUS_CLK: *rate = CLOCK_GetFreq(kCLOCK_BusClk); break; diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index f4b1377cadd..581c5b57e08 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -49,4 +49,6 @@ #define MCUX_LCDIF_PIXEL_CLK 33 +#define MCUX_SCTIMER_CLK 34 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ From e3bbdb6a298da64c7e1d9f84a33f1406f5a2008b Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 7 Sep 2023 10:36:09 -0500 Subject: [PATCH 0221/4498] dts: nxp: Add sctimer clock to soc dtsi Add sctimer clock properties to soc dtsi on sctimer node Signed-off-by: Declan Snyder --- dts/arm/nxp/nxp_lpc51u68.dtsi | 1 + dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 1 + dts/arm/nxp/nxp_lpc55S6x_common.dtsi | 1 + dts/arm/nxp/nxp_rt5xx_common.dtsi | 1 + dts/arm/nxp/nxp_rt6xx_common.dtsi | 1 + 5 files changed, 5 insertions(+) diff --git a/dts/arm/nxp/nxp_lpc51u68.dtsi b/dts/arm/nxp/nxp_lpc51u68.dtsi index 751cd17705f..964e863485b 100644 --- a/dts/arm/nxp/nxp_lpc51u68.dtsi +++ b/dts/arm/nxp/nxp_lpc51u68.dtsi @@ -152,6 +152,7 @@ reg = <0x40085000 0x1000>; status = "disabled"; interrupts = <12 0>; + clocks = <&syscon MCUX_SCTIMER_CLK>; prescaler = <1>; #pwm-cells = <3>; }; diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 2d834ff6b80..77e1ed26b0e 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -458,6 +458,7 @@ reg = <0x85000 0x1000>; interrupts = <12 0>; status = "disabled"; + clocks = <&syscon MCUX_SCTIMER_CLK 0 0>; prescaler = <2>; #pwm-cells = <3>; }; diff --git a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi index 1a727654e1a..23db8a86641 100644 --- a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi @@ -407,6 +407,7 @@ reg = <0x85000 0x1000>; interrupts = <12 0>; status = "disabled"; + clocks = <&syscon MCUX_SCTIMER_CLK>; prescaler = <2>; #pwm-cells = <3>; }; diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index d7348758378..9de7dfba991 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -403,6 +403,7 @@ status = "disabled"; prescaler = <8>; #pwm-cells = <3>; + clocks = <&clkctl1 MCUX_SCTIMER_CLK>; }; wwdt0: watchdog@e000 { diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index abef67f81cf..59897efe2a5 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -312,6 +312,7 @@ reg = <0x146000 0x1000>; interrupts = <12 0>; status = "disabled"; + clocks = <&clkctl1 MCUX_SCTIMER_CLK>; prescaler = <8>; #pwm-cells = <3>; }; From e48714949eb21f0ca553a25bd496089b98590328 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 7 Sep 2023 10:36:57 -0500 Subject: [PATCH 0222/4498] drivers: pwm_mcux_sctimer: Use clock control API Use zephyr clock control api instead of hal functions directly in the sctimer driver Signed-off-by: Declan Snyder --- drivers/pwm/Kconfig.mcux_sctimer | 2 +- drivers/pwm/pwm_mcux_sctimer.c | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/pwm/Kconfig.mcux_sctimer b/drivers/pwm/Kconfig.mcux_sctimer index a788208e8ad..0ca23f56847 100644 --- a/drivers/pwm/Kconfig.mcux_sctimer +++ b/drivers/pwm/Kconfig.mcux_sctimer @@ -5,6 +5,6 @@ config PWM_MCUX_SCTIMER bool "MCUX SCTimer PWM driver" default y depends on DT_HAS_NXP_SCTIMER_PWM_ENABLED - select PINCTRL + depends on CLOCK_CONTROL && PINCTRL help Enable sctimer based pwm driver. diff --git a/drivers/pwm/pwm_mcux_sctimer.c b/drivers/pwm/pwm_mcux_sctimer.c index fe5eda5d3d0..91d16092e8f 100644 --- a/drivers/pwm/pwm_mcux_sctimer.c +++ b/drivers/pwm/pwm_mcux_sctimer.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -23,6 +24,8 @@ struct pwm_mcux_sctimer_config { SCT_Type *base; uint32_t prescale; const struct pinctrl_dev_config *pincfg; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; }; struct pwm_mcux_sctimer_data { @@ -79,11 +82,11 @@ static int mcux_sctimer_pwm_set_cycles(const struct device *dev, data->period_cycles[channel] = period_cycles; - /* - * Do not divide by the prescale factor as this is accounted for in - * the SDK function - */ - clock_freq = CLOCK_GetFreq(kCLOCK_BusClk); + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq)) { + return -EINVAL; + } + pwm_freq = (clock_freq / config->prescale) / period_cycles; if (pwm_freq == 0) { @@ -117,8 +120,14 @@ static int mcux_sctimer_pwm_get_cycles_per_sec(const struct device *dev, uint64_t *cycles) { const struct pwm_mcux_sctimer_config *config = dev->config; + uint32_t clock_freq; - *cycles = CLOCK_GetFreq(kCLOCK_BusClk) / config->prescale; + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq)) { + return -EINVAL; + } + + *cycles = clock_freq / config->prescale; return 0; } @@ -138,7 +147,7 @@ static int mcux_sctimer_pwm_init(const struct device *dev) } SCTIMER_GetDefaultConfig(&pwm_config); - /* Divide the SCT clock by 8 */ + pwm_config.prescale_l = config->prescale - 1; status = SCTIMER_Init(config->base, &pwm_config); @@ -170,6 +179,8 @@ static const struct pwm_driver_api pwm_mcux_sctimer_driver_api = { .base = (SCT_Type *)DT_INST_REG_ADDR(n), \ .prescale = DT_INST_PROP(n, prescaler), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ }; \ \ DEVICE_DT_INST_DEFINE(n, \ From 0b92327fc31b031a04e3a48d9cbd2cecccb7ac18 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Tue, 5 Sep 2023 18:29:38 +0530 Subject: [PATCH 0223/4498] net: wifi: Fix crash in wifi_utils_parse_scan_bands wifi_utils_parse_scan_bands could cause a crash if a constant string is passed to it. Fix this by duplicating the input string parameter before parsing it with strtok_r. Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 2 ++ subsys/net/l2/wifi/wifi_utils.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 0bdb5753531..c7a17e930d6 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -41,6 +41,8 @@ extern "C" { #define WIFI_MGMT_SCAN_SSID_FILT_MAX 0 #endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ +#define WIFI_MGMT_BAND_STR_SIZE_MAX 8 + /** Wi-Fi management commands */ enum net_request_wifi_cmd { /** Scan for Wi-Fi networks */ diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index f7e9d9af4dc..6151f480d21 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -215,15 +215,30 @@ static int wifi_utils_validate_chan_str(char *chan_str) int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) { + char parse_str[WIFI_MGMT_BAND_STR_SIZE_MAX + 1]; char *band_str = NULL; char *ctx = NULL; enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN; + int len; if (!scan_bands_str) { return -EINVAL; } - band_str = strtok_r(scan_bands_str, ",", &ctx); + len = strlen(scan_bands_str); + + if (len > WIFI_MGMT_BAND_STR_SIZE_MAX) { + NET_ERR("Band string (%s) size (%d) exceeds maximum allowed value (%d)", + scan_bands_str, + len, + WIFI_MGMT_BAND_STR_SIZE_MAX); + return -EINVAL; + } + + strncpy(parse_str, scan_bands_str, len); + parse_str[len] = '\0'; + + band_str = strtok_r(parse_str, ",", &ctx); while (band_str) { band = wifi_utils_map_band_str_to_idx(band_str); From 85b39b84492605c02daaac4b16227b983dc757f0 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Tue, 5 Sep 2023 18:38:54 +0530 Subject: [PATCH 0224/4498] net: wifi: Fix crash in wifi_utils_parse_scan_ssids wifi_utils_parse_scan_ssids could cause a crash if a constant string is passed to it. Fix this by duplicating the input string parameter before parsing it with strtok_r. Also limit the range of the CONFIG_WIFI_SCAN_SSID_FILT_MAX parameter from 1 to 4 to avoid stack overflow due to users specifying a large value for this parameter. Signed-off-by: Sachin D Kulkarni --- subsys/net/l2/wifi/Kconfig | 1 + subsys/net/l2/wifi/wifi_utils.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index e034a745b5e..6623456d84b 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -76,6 +76,7 @@ config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 + range 1 4 help Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 6151f480d21..ea0e42def47 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -259,15 +259,30 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) int wifi_utils_parse_scan_ssids(char *scan_ssids_str, char ssids[][WIFI_SSID_MAX_LEN + 1]) { + char parse_str[(WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1)) + 1]; char *ssid = NULL; char *ctx = NULL; uint8_t i = 0; + int len; if (!scan_ssids_str) { return -EINVAL; } - ssid = strtok_r(scan_ssids_str, ",", &ctx); + len = strlen(scan_ssids_str); + + if (len > (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))) { + NET_ERR("SSID string (%s) size (%d) exceeds maximum allowed value (%d)", + scan_ssids_str, + len, + (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))); + return -EINVAL; + } + + strncpy(parse_str, scan_ssids_str, len); + parse_str[len] = '\0'; + + ssid = strtok_r(parse_str, ",", &ctx); while (ssid) { if (strlen(ssid) > WIFI_SSID_MAX_LEN) { From ed4cdba828c3c9796496c621ea8e3c7bb0ec1ad6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 5 Sep 2023 09:29:55 +0200 Subject: [PATCH 0225/4498] boards: native: Mention serial drivers capabilities Some users are in doubt about the native serial drivers capabilities. So let's mention them explicitly. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_posix/doc/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index a9306b7451b..630da2c17dc 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -430,6 +430,9 @@ option ``-attach_uart_cmd=<"cmd">``. Where the default command is given by Note that the default command assumes both ``xterm`` and ``screen`` are installed in the system. +This driver only supports poll mode. Interrupt and async mode are not supported. +Neither runtime configuration or line control are supported. + .. _native_tty_uart: TTY UART @@ -466,6 +469,9 @@ Multiple instances of such uart drivers are supported. The :ref:`sample-uart-native-tty` sample app provides a working example of the driver. +This driver only supports poll mode. Interrupt and async mode are not supported. +It has runtime configuration support, but no line control support. + Subsystems backends ******************* From 1c2abbd7f1c743d4cba3c8f3774caa46c31a6983 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 7 Sep 2023 09:48:51 +0200 Subject: [PATCH 0226/4498] doc: bluetooth: mesh: Add missing bt_mesh_dfd group to DFU doc page Add missing bt_mesh_dfd group to the mesh DFU documentation page as it covers all DFU models including Firmware Distribution models (called as `dfd` in the code). Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/dfu.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 685aaf3cbd1..0fee2b867ca 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -219,6 +219,10 @@ API reference This section lists the types common to the Device Firmware Update mesh models. +.. doxygengroup:: bt_mesh_dfd + :project: Zephyr + :members: + .. doxygengroup:: bt_mesh_dfu :project: Zephyr :members: From 313efff191762f57c38a4f53106e167a22cd6496 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 7 Sep 2023 09:52:59 +0200 Subject: [PATCH 0227/4498] Bluetooth: Mesh: Add description for bt_mesh_comp_p1_elem struct Add missing description for bt_mesh_comp_p1_elem struct. Signed-off-by: Pavel Vasilyev --- include/zephyr/bluetooth/mesh/cfg_cli.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index d2221da38da..1a7c8ed7e2c 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -1690,6 +1690,7 @@ uint16_t bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem *elem, int idx); */ struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem *elem, int idx); +/** Composition data page 1 element representation */ struct bt_mesh_comp_p1_elem { /** The number of SIG models in this element */ size_t nsig; From cfa9d151daa39c217e6d36cdcd2764bf8fa8bff5 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 7 Sep 2023 10:35:54 +0200 Subject: [PATCH 0228/4498] Bluetooth: Mesh: Compile bt_mesh_model fields with Doxygen This will enable rendering these fields in the documentation. Signed-off-by: Pavel Vasilyev --- include/zephyr/bluetooth/mesh/access.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 5b1653c2487..2db8a55e986 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -893,7 +893,7 @@ struct bt_mesh_model { uint16_t * const groups; const uint16_t groups_cnt; -#if CONFIG_BT_MESH_LABEL_COUNT > 0 +#if (CONFIG_BT_MESH_LABEL_COUNT > 0) || defined(__DOXYGEN__) /** List of Label UUIDs the model is subscribed to. */ const uint8_t ** const uuids; #endif @@ -909,7 +909,7 @@ struct bt_mesh_model { struct bt_mesh_model *next; #endif -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) || defined(__DOXYGEN__) /* Pointer to the array of model metadata entries. */ struct bt_mesh_models_metadata_entry **metadata; #endif From 028031ec20ba85f450ce01e1e33b41164e84f24d Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 7 Sep 2023 10:39:31 +0200 Subject: [PATCH 0229/4498] doc: bluetooth: mesh: Fix link to Assigned Numbers document The previous file doesn't exist anymore and was redirecting to the new link. Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/provisioning.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connectivity/bluetooth/api/mesh/provisioning.rst b/doc/connectivity/bluetooth/api/mesh/provisioning.rst index 7c564e17f4a..0985234b86c 100644 --- a/doc/connectivity/bluetooth/api/mesh/provisioning.rst +++ b/doc/connectivity/bluetooth/api/mesh/provisioning.rst @@ -53,7 +53,7 @@ The Uniform Resource Identifier shall follow the format specified in the Bluetooth Core Specification Supplement. The URI must start with a URI scheme, encoded as a single utf-8 data point, or the special ``none`` scheme, encoded as ``0x01``. The available schemes are listed on the `Bluetooth website -`_. +`_. Examples of encoded URIs: From 72167f2acfe12acf58040e63888159062e20145e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 8 Sep 2023 14:53:45 +0100 Subject: [PATCH 0230/4498] drivers: flash: nrf_qspi_nor: Add support for XIP at boot Adds support for forcing XIP support at boot time, and reduces the init priority of the driver so that it inits earlier. Signed-off-by: Jamie McCrae --- drivers/flash/Kconfig.nordic_qspi_nor | 14 ++++++++++++-- drivers/flash/nrf_qspi_nor.c | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index 16252e0812c..7b9fa05eb7f 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -14,8 +14,8 @@ menuconfig NORDIC_QSPI_NOR if NORDIC_QSPI_NOR config NORDIC_QSPI_NOR_INIT_PRIORITY - int - default 80 + int "Init priority" + default 41 help Device driver initialization priority. @@ -39,4 +39,14 @@ config NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE if the data is larger than the configured size. Must be a multiple of 4. When set to 0, the feature is disabled. +config NORDIC_QSPI_NOR_XIP + bool "XIP (eXecute in place)" + depends on SOC_NRF5340_CPUAPP + help + Enable setting up the QSPI NOR driver to allow for execution of code + stored in QSPI XIP region. Note that for this functionality to work, + the QSPI NOR init priority must be set so that no XIP code in the + QSPI NOR flash chip is executed until the driver has been setup. + This will also disable power management for the QSPI NOR flash chip. + endif # NORDIC_QSPI_NOR diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index b2455ba3c6f..e2ce6e6a706 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -179,6 +179,8 @@ static bool qspi_initialized; static int qspi_device_init(const struct device *dev); static void qspi_device_uninit(const struct device *dev); +void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); +void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); #define WORD_SIZE 4 @@ -1229,6 +1231,7 @@ static int qspi_nor_configure(const struct device *dev) */ static int qspi_nor_init(const struct device *dev) { + int rc; const struct qspi_nor_config *dev_config = dev->config; int ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); @@ -1238,7 +1241,19 @@ static int qspi_nor_init(const struct device *dev) IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), nrfx_isr, nrfx_qspi_irq_handler, 0); - return qspi_nor_configure(dev); + + rc = qspi_nor_configure(dev); + +#ifdef CONFIG_NORDIC_QSPI_NOR_XIP + if (!rc) { + /* Enable XIP mode for QSPI NOR flash, this will prevent the + * flash from being powered down + */ + z_impl_nrf_qspi_nor_xip_enable(dev, true); + } +#endif + + return rc; } #if defined(CONFIG_FLASH_PAGE_LAYOUT) @@ -1369,6 +1384,10 @@ static int qspi_nor_pm_action(const struct device *dev, } #endif + if (dev_data->xip_enabled) { + return -EBUSY; + } + if (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { return -EBUSY; } From 5b12b6ab554c0ef10f62b822a05e5823d73dd318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ku=C5=BAnia?= Date: Mon, 7 Aug 2023 13:51:53 +0200 Subject: [PATCH 0231/4498] ipc: icmsg: Dedicated workqueue for ICMSG backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ICMSG backend now has a dedicated workqueue to process incoming IPC messages. The system workqueue is no longer utilized for that purpose. Testing shows that in certain scenarios substituting a RPMsg backend with ICMsg results in deadlocks. The deadlocks were a symptom of running a synchronous RPC protocol from the context of the system workqueue and transpired as follows: 1. The RPC protocol sends a request over the ICMsg backend on the system workqueue thread. 2. The RPC protocol puts the thread to sleep until response is received. This puts the system workqueue thread to sleep. 3. The response to the request arrives over ICMsg backend. 4. The backend signals a work item to the system workqueue. 5. The system workqueue is unable to process the response due to being previously pended on the RPC request. The deadlock was initially observed with the nrf-802154 driver in conjuntion with the IPv6 stack. To prevent this condition from occurring, the approach was selected to give ICMsg a dedicated workqueue thread. Added a Kconfig option that enables the dedicated workqueue by default. The config can be disabled, if the user wants to preserve RAM capacity and is certain that the deadlock condition is not encountered. Signed-off-by: Rafał Kuźnia --- subsys/ipc/ipc_service/lib/Kconfig.icmsg | 48 +++++++++++++++++++++--- subsys/ipc/ipc_service/lib/icmsg.c | 34 +++++++++++++++-- 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/subsys/ipc/ipc_service/lib/Kconfig.icmsg b/subsys/ipc/ipc_service/lib/Kconfig.icmsg index 6847844d67a..e8f92a945a3 100644 --- a/subsys/ipc/ipc_service/lib/Kconfig.icmsg +++ b/subsys/ipc/ipc_service/lib/Kconfig.icmsg @@ -27,11 +27,6 @@ config IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS Maximum time to wait, in milliseconds, for access to send data with backends basing on icmsg library. This time should be relatively low. -# The Icmsg library in its simplicity requires the system workqueue to execute -# at a cooperative priority. -config SYSTEM_WORKQUEUE_PRIORITY - range -256 -1 - config IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS int "Bond notification timeout in miliseconds" range 1 100 @@ -39,3 +34,46 @@ config IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS help Time to wait for remote bonding notification before the notification is repeated. + +config IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE + bool "Use dedicated workqueue" + default y + help + Enable dedicated workqueue thread for the ICMsg backend. + Disabling this configuration will cause the ICMsg backend to + process incoming data through the system workqueue context, and + therefore reduces the RAM footprint of the backend. + Disabling this config may result in deadlocks in certain usage + scenarios, such as when synchronous IPC is executed from the system + workqueue context. + The callbacks coming from the backend are executed from the workqueue + context. + When the option is disabled, the user must obey the restrictions + imposed by the system workqueue, such as never performing blocking + operations from within the callback. + +if IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE + +config IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE + int "Size of RX work queue stack" + default 1024 + help + Size of stack used by work queue RX thread. This work queue is + created to prevent notifying service users about received data + from the system work queue. The queue is shared among instances. + +config IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY + int "Priority of RX work queue thread" + default -1 + range -256 -1 + help + Priority of the ICMSG RX work queue thread. + The ICMSG library in its simplicity requires the workqueue to execute + at a cooperative priority. + +endif + +# The Icmsg library in its simplicity requires the system workqueue to execute +# at a cooperative priority. +config SYSTEM_WORKQUEUE_PRIORITY + range -256 -1 if !IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE diff --git a/subsys/ipc/ipc_service/lib/icmsg.c b/subsys/ipc/ipc_service/lib/icmsg.c index b0b9ad11e5b..9d238f19351 100644 --- a/subsys/ipc/ipc_service/lib/icmsg.c +++ b/subsys/ipc/ipc_service/lib/icmsg.c @@ -10,6 +10,7 @@ #include #include #include +#include #define BOND_NOTIFY_REPEAT_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS) #define SHMEM_ACCESS_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS) @@ -28,6 +29,14 @@ enum tx_buffer_state { static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b, 0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34}; +#if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) +static K_THREAD_STACK_DEFINE(icmsg_stack, CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE); +static struct k_work_q icmsg_workq; +static struct k_work_q *const workq = &icmsg_workq; +#else +static struct k_work_q *const workq = &k_sys_work_q; +#endif + static int mbox_deinit(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data) { @@ -62,7 +71,7 @@ static void notify_process(struct k_work *item) if (state != ICMSG_STATE_READY) { int ret; - ret = k_work_reschedule(dwork, BOND_NOTIFY_REPEAT_TO); + ret = k_work_reschedule_for_queue(workq, dwork, BOND_NOTIFY_REPEAT_TO); __ASSERT_NO_MSG(ret >= 0); (void)ret; } @@ -138,7 +147,7 @@ static bool is_rx_data_available(struct icmsg_data_t *dev_data) static void submit_mbox_work(struct icmsg_data_t *dev_data) { - if (k_work_submit(&dev_data->mbox_work) < 0) { + if (k_work_submit_to_queue(workq, &dev_data->mbox_work) < 0) { /* The mbox processing work is never canceled. * The negative error code should never be seen. */ @@ -290,7 +299,7 @@ int icmsg_open(const struct icmsg_config_t *conf, return ret; } - ret = k_work_schedule(&dev_data->notify_work, K_NO_WAIT); + ret = k_work_schedule_for_queue(workq, &dev_data->notify_work, K_NO_WAIT); if (ret < 0) { return ret; } @@ -519,3 +528,22 @@ int icmsg_release_rx_buffer(const struct icmsg_config_t *conf, return 0; } #endif /* CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX */ + +#if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) + +static int work_q_init(void) +{ + struct k_work_queue_config cfg = { + .name = "icmsg_workq", + }; + + k_work_queue_start(&icmsg_workq, + icmsg_stack, + K_KERNEL_STACK_SIZEOF(icmsg_stack), + CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY, &cfg); + return 0; +} + +SYS_INIT(work_q_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + +#endif From fd04f8cc811f2d2843d151453bc03d04bf322eee Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Mon, 12 Jun 2023 20:47:28 -0700 Subject: [PATCH 0232/4498] drivers: spi: Initial version of the Infineon CAT1 SPI driver Initial version of Infineon CAT1 SPI Driver supporting synchronous and asynchronous data transfer API Signed-off-by: Sreeram Tatapudi --- .../cy8cproto_063_ble/cy8cproto_063_ble.yaml | 1 + .../cy8cproto_063_ble_defconfig | 3 + drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 2 + drivers/spi/Kconfig.ifx_cat1 | 12 + drivers/spi/spi_ifx_cat1.c | 360 ++++++++++++++++++ dts/bindings/spi/infineon,cat1-spi.yaml | 20 + .../boards/cy8cproto_062_4343w.overlay | 41 ++ .../boards/cy8cproto_063_ble.overlay | 42 ++ 9 files changed, 482 insertions(+) create mode 100644 drivers/spi/Kconfig.ifx_cat1 create mode 100644 drivers/spi/spi_ifx_cat1.c create mode 100644 dts/bindings/spi/infineon,cat1-spi.yaml create mode 100644 tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay create mode 100644 tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay diff --git a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml index ba6ceaa0f06..c9d851c5ffc 100644 --- a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml +++ b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml @@ -18,3 +18,4 @@ supported: - uart - i2c - watchdog + - spi diff --git a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble_defconfig b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble_defconfig index bc356fad3b4..a3d7e7beab3 100644 --- a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble_defconfig +++ b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble_defconfig @@ -25,6 +25,9 @@ CONFIG_SERIAL=y # Enable pin controller CONFIG_PINCTRL=y +# Enable GPIO +CONFIG_GPIO=y + # Enable clock controller CONFIG_CLOCK_CONTROL=y diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index 0eaea3714b8..269b28549eb 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -48,3 +48,4 @@ zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ mspi_ambiq.c) zephyr_library_sources_ifdef(CONFIG_SPI_RTIO spi_rtio.c) zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c) +zephyr_library_sources_ifdef(CONFIG_SPI_INFINEON_CAT1 spi_ifx_cat1.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index cbc11b374ab..75f7993ef27 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -133,4 +133,6 @@ source "drivers/spi/Kconfig.ambiq" source "drivers/spi/Kconfig.rpi_pico" +source "drivers/spi/Kconfig.ifx_cat1" + endif # SPI diff --git a/drivers/spi/Kconfig.ifx_cat1 b/drivers/spi/Kconfig.ifx_cat1 new file mode 100644 index 00000000000..ab55fb6d67b --- /dev/null +++ b/drivers/spi/Kconfig.ifx_cat1 @@ -0,0 +1,12 @@ +# Infineon CAT1 SPI configuration options + +# Copyright (c) 2022 Cypress Semiconductor Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config SPI_INFINEON_CAT1 + bool "Infineon CAT1 SPI driver" + default y + depends on DT_HAS_INFINEON_CAT1_SPI_ENABLED + select USE_INFINEON_SPI + help + This option enables the SPI driver for Infineon CAT1 family. diff --git a/drivers/spi/spi_ifx_cat1.c b/drivers/spi/spi_ifx_cat1.c new file mode 100644 index 00000000000..ceafe8e6635 --- /dev/null +++ b/drivers/spi/spi_ifx_cat1.c @@ -0,0 +1,360 @@ +/* + * Copyright 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_cat1_spi + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +#include +LOG_MODULE_REGISTER(cat1_spi); + +#include "spi_context.h" + +#include +#include +#include + +#include +#include + +#define IFX_CAT1_SPI_LOCK_TMOUT_MS (30 * 1000) +#define IFX_CAT1_SPI_DEFAULT_OVERSAMPLE (4) +#define IFX_CAT1_SPI_MIN_DATA_WIDTH (8) +#define IFX_CAT1_SPI_MAX_DATA_WIDTH (32) + +/* Device config structure */ +struct ifx_cat1_spi_config { + CySCB_Type *reg_addr; + const struct pinctrl_dev_config *pcfg; + cy_stc_scb_spi_config_t scb_spi_config; + uint8_t irq_priority; +}; + +/* Data structure */ +struct ifx_cat1_spi_data { + struct spi_context ctx; + cyhal_spi_t obj; /* SPI CYHAL object */ + cyhal_resource_inst_t hw_resource; + uint8_t dfs_value; + size_t chunk_len; +}; + +static int32_t get_hw_block_num(CySCB_Type *reg_addr) +{ + uint32_t i; + + for (i = 0u; i < _SCB_ARRAY_SIZE; i++) { + if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) { + return i; + } + } + + return -ENOMEM; +} + +static uint8_t get_dfs_value(struct spi_context *ctx) +{ + switch (SPI_WORD_SIZE_GET(ctx->config->operation)) { + case 8: + return 1; + case 16: + return 2; + case 32: + return 4; + default: + return 1; + } +} + +static void transfer_chunk(const struct device *dev) +{ + struct ifx_cat1_spi_data *const data = dev->data; + struct spi_context *ctx = &data->ctx; + int ret = 0; + size_t chunk_len = spi_context_max_continuous_chunk(ctx); + + if (chunk_len == 0) { + goto exit; + } + + data->chunk_len = chunk_len; + + cy_rslt_t result = cyhal_spi_transfer_async( + &data->obj, ctx->tx_buf, spi_context_tx_buf_on(ctx) ? chunk_len : 0, ctx->rx_buf, + spi_context_rx_buf_on(ctx) ? chunk_len : 0); + if (result == CY_RSLT_SUCCESS) { + return; + } + + ret = -EIO; + +exit: + spi_context_cs_control(ctx, false); + spi_context_complete(ctx, dev, ret); +} + +static void spi_interrupt_callback(void *arg, cyhal_spi_event_t event) +{ + const struct device *dev = (const struct device *)arg; + struct ifx_cat1_spi_data *const data = dev->data; + struct spi_context *ctx = &data->ctx; + + if (event & CYHAL_SPI_IRQ_ERROR) { +#if defined(CONFIG_SPI_ASYNC) + cyhal_spi_abort_async(&data->obj); +#endif + spi_context_cs_control(ctx, false); + spi_context_complete(ctx, dev, -EIO); + } + + if (event & CYHAL_SPI_IRQ_DONE) { + spi_context_update_tx(ctx, data->dfs_value, data->chunk_len); + spi_context_update_rx(ctx, data->dfs_value, data->chunk_len); + + transfer_chunk(dev); + } +} + +int spi_config(const struct device *dev, const struct spi_config *spi_cfg) +{ + cy_rslt_t result; + struct ifx_cat1_spi_data *const data = dev->data; + const struct ifx_cat1_spi_config *const config = dev->config; + cy_stc_scb_spi_config_t scb_spi_config = config->scb_spi_config; + struct spi_context *ctx = &data->ctx; + bool spi_mode_cpol = false; + bool spi_mode_cpha = false; + + /* check if configuration was changed from previous run, if so skip setup again */ + if (spi_context_configured(ctx, spi_cfg)) { + /* Already configured. No need to do it again. */ + return 0; + } + + if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) { + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(spi_cfg->operation) > IFX_CAT1_SPI_MAX_DATA_WIDTH) { + LOG_ERR("Word size %d is greater than %d", SPI_WORD_SIZE_GET(spi_cfg->operation), + IFX_CAT1_SPI_MAX_DATA_WIDTH); + return -EINVAL; + } + + if (SPI_WORD_SIZE_GET(spi_cfg->operation) < IFX_CAT1_SPI_MIN_DATA_WIDTH) { + LOG_ERR("Word size %d is less than %d", SPI_WORD_SIZE_GET(spi_cfg->operation), + IFX_CAT1_SPI_MIN_DATA_WIDTH); + return -EINVAL; + } + + if (SPI_OP_MODE_GET(spi_cfg->operation) == SPI_OP_MODE_SLAVE) { + scb_spi_config.spiMode = CY_SCB_SPI_SLAVE; + scb_spi_config.oversample = 0; + scb_spi_config.enableMisoLateSample = false; + } else { + scb_spi_config.spiMode = CY_SCB_SPI_MASTER; + } + + if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { + spi_mode_cpol = true; + } + + if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) { + spi_mode_cpha = true; + } + + if (SPI_WORD_SIZE_GET(spi_cfg->operation)) { + scb_spi_config.txDataWidth = SPI_WORD_SIZE_GET(spi_cfg->operation); + scb_spi_config.rxDataWidth = SPI_WORD_SIZE_GET(spi_cfg->operation); + } + + if (spi_mode_cpha) { + scb_spi_config.sclkMode = + spi_mode_cpol ? CY_SCB_SPI_CPHA1_CPOL1 : CY_SCB_SPI_CPHA1_CPOL0; + } else { + scb_spi_config.sclkMode = + spi_mode_cpol ? CY_SCB_SPI_CPHA0_CPOL1 : CY_SCB_SPI_CPHA0_CPOL0; + } + + scb_spi_config.enableMsbFirst = (spi_cfg->operation & SPI_TRANSFER_LSB) ? false : true; + + /* Force free resource */ + if (data->obj.base != NULL) { + cyhal_spi_free(&data->obj); + } + + /* Initialize the SPI peripheral */ + cyhal_spi_configurator_t spi_init_cfg = {.resource = &data->hw_resource, + .config = &scb_spi_config, + .gpios = {NC, {NC, NC, NC, NC}, NC, NC}}; + + result = cyhal_spi_init_cfg(&data->obj, &spi_init_cfg); + if (result != CY_RSLT_SUCCESS) { + return -ENOTSUP; + } + + /* Assigns a programmable divider to a selected IP block */ + en_clk_dst_t clk_idx = _cyhal_scb_get_clock_index(spi_init_cfg.resource->block_num); + + result = _cyhal_utils_peri_pclk_assign_divider(clk_idx, &data->obj.clock); + if (result != CY_RSLT_SUCCESS) { + return -ENOTSUP; + } + + /* Configure Slave select polarity */ + if (SPI_OP_MODE_GET(spi_cfg->operation) == SPI_OP_MODE_SLAVE) { + Cy_SCB_SPI_SetActiveSlaveSelectPolarity(data->obj.base, CY_SCB_SPI_SLAVE_SELECT0, + scb_spi_config.ssPolarity); + } + + /* Set the data rate */ + result = cyhal_spi_set_frequency(&data->obj, spi_cfg->frequency); + if (result != CY_RSLT_SUCCESS) { + return -EIO; + } + + /* Write 0 when NULL buffer is provided for Tx/Rx */ + data->obj.write_fill = 0; + + /* Register common SPI callback */ + cyhal_spi_register_callback(&data->obj, spi_interrupt_callback, (void *)dev); + cyhal_spi_enable_event(&data->obj, CYHAL_SPI_IRQ_DONE, config->irq_priority, true); + + /* Store spi config in context */ + ctx->config = spi_cfg; + + data->dfs_value = get_dfs_value(ctx); + + return 0; +} + +static int transceive(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + int result; + struct ifx_cat1_spi_data *const data = dev->data; + struct spi_context *ctx = &data->ctx; + + spi_context_lock(ctx, asynchronous, cb, userdata, spi_cfg); + + result = spi_config(dev, spi_cfg); + if (result) { + LOG_ERR("Error in SPI Configuration (result: 0x%x)", result); + return result; + } + + spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, data->dfs_value); + + spi_context_cs_control(ctx, true); + + transfer_chunk(dev); + + result = spi_context_wait_for_completion(&data->ctx); + + spi_context_release(ctx, result); + + return result; +} + +static int ifx_cat1_spi_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#if defined(CONFIG_SPI_ASYNC) +static int ifx_cat1_spi_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif + +static int ifx_cat1_spi_release(const struct device *dev, const struct spi_config *spi_cfg) +{ + struct ifx_cat1_spi_data *const data = dev->data; + + cyhal_spi_free(&data->obj); + + return 0; +} + +static const struct spi_driver_api ifx_cat1_spi_api = { + .transceive = ifx_cat1_spi_transceive_sync, +#if defined(CONFIG_SPI_ASYNC) + .transceive_async = ifx_cat1_spi_transceive_async, +#endif + .release = ifx_cat1_spi_release, +}; + +static int ifx_cat1_spi_init(const struct device *dev) +{ + struct ifx_cat1_spi_data *const data = dev->data; + const struct ifx_cat1_spi_config *const config = dev->config; + int ret; + + /* Dedicate SCB HW resource */ + data->hw_resource.type = CYHAL_RSC_SCB; + data->hw_resource.block_num = get_hw_block_num(config->reg_addr); + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + /* Configure slave select (master) */ + spi_context_cs_configure_all(&data->ctx); + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#define IFX_CAT1_SPI_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct ifx_cat1_spi_data spi_cat1_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_cat1_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_cat1_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + static struct ifx_cat1_spi_config spi_cat1_config_##n = { \ + .reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .scb_spi_config = \ + {.spiMode = CY_SCB_SPI_MASTER, /* overwrite by cfg */ \ + .sclkMode = CY_SCB_SPI_CPHA0_CPOL0, /* overwrite by cfg */ \ + .rxDataWidth = 8, /* overwrite by cfg */ \ + .txDataWidth = 8, /* overwrite by cfg */ \ + .enableMsbFirst = true, /* overwrite by cfg */ \ + .subMode = DT_INST_PROP_OR(n, sub_mode, CY_SCB_SPI_MOTOROLA), \ + .oversample = \ + DT_INST_PROP_OR(n, oversample, IFX_CAT1_SPI_DEFAULT_OVERSAMPLE), \ + .enableFreeRunSclk = DT_INST_PROP_OR(n, enable_free_run_sclk, false), \ + .enableInputFilter = DT_INST_PROP_OR(n, enable_input_filter, false), \ + .enableMisoLateSample = \ + DT_INST_PROP_OR(n, enable_miso_late_sample, true), \ + .enableTransferSeperation = \ + DT_INST_PROP_OR(n, enable_transfer_seperation, false), \ + .enableWakeFromSleep = DT_INST_PROP_OR(n, enableWakeFromSleep, false), \ + .ssPolarity = DT_INST_PROP_OR(n, ss_polarity, CY_SCB_SPI_ACTIVE_LOW), \ + .rxFifoTriggerLevel = DT_INST_PROP_OR(n, rx_fifo_trigger_level, 0), \ + .rxFifoIntEnableMask = DT_INST_PROP_OR(n, rx_fifo_int_enable_mask, 0), \ + .txFifoTriggerLevel = DT_INST_PROP_OR(n, tx_fifo_trigger_level, 0), \ + .txFifoIntEnableMask = DT_INST_PROP_OR(n, tx_fifo_int_enable_mask, 0), \ + .masterSlaveIntEnableMask = \ + DT_INST_PROP_OR(n, master_slave_int_enable_mask, 0)}, \ + \ + .irq_priority = DT_INST_IRQ(n, priority), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &ifx_cat1_spi_init, NULL, &spi_cat1_data_##n, \ + &spi_cat1_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ifx_cat1_spi_api); + +DT_INST_FOREACH_STATUS_OKAY(IFX_CAT1_SPI_INIT) diff --git a/dts/bindings/spi/infineon,cat1-spi.yaml b/dts/bindings/spi/infineon,cat1-spi.yaml new file mode 100644 index 00000000000..4b1000b3497 --- /dev/null +++ b/dts/bindings/spi/infineon,cat1-spi.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: Infineon CAT1 SPI + +compatible: "infineon,cat1-spi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true diff --git a/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay b/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay new file mode 100644 index 00000000000..893e8416631 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay @@ -0,0 +1,41 @@ +spi1: &scb3 { + compatible = "infineon,cat1-spi"; + status = "okay"; + + pinctrl-0 = <&p6_0_scb3_spi_m_mosi &p6_1_scb3_spi_m_miso &p6_2_scb3_spi_m_clk>; + pinctrl-names = "default"; + cs-gpios = <&gpio_prt6 3 GPIO_ACTIVE_LOW>; + + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <2000000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <3000000>; + }; +}; + +&gpio_prt6 { + status = "okay"; +}; + +&pinctrl { + /* Configure pin control bias mode for SPI pins */ + p6_0_scb3_spi_m_mosi: p6_0_scb3_spi_m_mosi { + pinmux = ; + drive-push-pull; + }; + + p6_1_scb3_spi_m_miso: p6_1_scb3_spi_m_miso { + pinmux = ; + input-enable; + }; + + p6_2_scb3_spi_m_clk: p6_2_scb3_spi_m_clk { + pinmux = ; + drive-push-pull; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay b/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay new file mode 100644 index 00000000000..e6ddcc3ef2e --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay @@ -0,0 +1,42 @@ +&pinctrl { + /* Configure pin control bias mode for SPI pins (MASTER) */ + p10_0_scb1_spi_m_mosi: p10_0_scb1_spi_m_mosi { + pinmux = ; + drive-push-pull; + }; + + p10_1_scb1_spi_m_miso: p10_1_scb1_spi_m_miso { + pinmux = ; + input-enable; + }; + + p10_2_scb1_spi_m_clk: p10_2_scb1_spi_m_clk { + pinmux = ; + drive-push-pull; + }; +}; + +spi: &scb1 { + compatible = "infineon,cat1-spi"; + status = "okay"; + + pinctrl-0 = <&p10_0_scb1_spi_m_mosi &p10_1_scb1_spi_m_miso &p10_2_scb1_spi_m_clk>; + pinctrl-names = "default"; + cs-gpios = <&gpio_prt10 3 GPIO_ACTIVE_LOW>; + + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <200000>; + }; + + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <1500000>; + }; +}; + +&gpio_prt10 { + status = "okay"; +}; From 2749b3beb0b1bf2abad6c4f41aca76ac2bb4136c Mon Sep 17 00:00:00 2001 From: Kong Li Date: Tue, 29 Aug 2023 16:08:42 +0800 Subject: [PATCH 0233/4498] drivers: gpio: Add Intel SEDI gpio driver Add a new GPIO shim driver for Intel Socs. Builds upon the SEDI bare metal gpio driver in hal-intel module. Signed-off-by: Kong Li --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 1 + drivers/gpio/Kconfig.sedi | 14 + drivers/gpio/gpio_sedi.c | 340 +++++++++++++++++++++++++ dts/bindings/gpio/intel,sedi-gpio.yaml | 30 +++ dts/x86/intel/intel_ish5.dtsi | 13 + dts/x86/intel/intel_ish5_8.dtsi | 6 + 7 files changed, 405 insertions(+) create mode 100644 drivers/gpio/Kconfig.sedi create mode 100644 drivers/gpio/gpio_sedi.c create mode 100644 dts/bindings/gpio/intel,sedi-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 5b1229fd00b..60ea5c52fad 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -82,6 +82,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_HOGS gpio_hogs.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7e368a9852e..f0e1a63e364 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -204,5 +204,6 @@ source "drivers/gpio/Kconfig.numaker" source "drivers/gpio/Kconfig.efinix_sapphire" source "drivers/gpio/Kconfig.davinci" +source "drivers/gpio/Kconfig.sedi" endif # GPIO diff --git a/drivers/gpio/Kconfig.sedi b/drivers/gpio/Kconfig.sedi new file mode 100644 index 00000000000..3ad11b5893e --- /dev/null +++ b/drivers/gpio/Kconfig.sedi @@ -0,0 +1,14 @@ +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config GPIO_SEDI + bool "SEDI GPIO driver" + default y + depends on DT_HAS_INTEL_SEDI_GPIO_ENABLED + help + This option enables Intel SEDI GPIO driver. + This driver is simply a shim driver built upon the SEDI + bare metal GPIO driver in hal-intel module. diff --git a/drivers/gpio/gpio_sedi.c b/drivers/gpio/gpio_sedi.c new file mode 100644 index 00000000000..17dfe79f090 --- /dev/null +++ b/drivers/gpio/gpio_sedi.c @@ -0,0 +1,340 @@ +/* Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_sedi_gpio + +#include "sedi_driver_gpio.h" +#include +#include +#include +#include + +struct gpio_sedi_config { + /* gpio_driver_data needs to be first */ + struct gpio_driver_config common; + sedi_gpio_t device; + uint32_t pin_nums; + void (*irq_config)(void); + + DEVICE_MMIO_ROM; +}; + +struct gpio_sedi_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_config common; + sys_slist_t callbacks; + + DEVICE_MMIO_RAM; +}; + +static int gpio_sedi_init(const struct device *dev); + +#ifdef CONFIG_PM_DEVICE +static int gpio_sedi_suspend_device(const struct device *dev) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + int ret; + + if (pm_device_is_busy(dev)) { + return -EBUSY; + } + + ret = sedi_gpio_set_power(gpio_dev, SEDI_POWER_SUSPEND); + + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_sedi_resume_device_from_suspend(const struct device *dev) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + int ret; + + ret = sedi_gpio_set_power(gpio_dev, SEDI_POWER_FULL); + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_sedi_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = gpio_sedi_suspend_device(dev); + break; + case PM_DEVICE_ACTION_RESUME: + ret = gpio_sedi_resume_device_from_suspend(dev); + break; + + default: + ret = -ENOTSUP; + } + + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +static void gpio_sedi_callback(const uint32_t pin_mask, + const sedi_gpio_port_t port, + void *param) +{ + ARG_UNUSED(port); + struct device *dev = (struct device *)param; + struct gpio_sedi_data *data = + (struct gpio_sedi_data *)(dev->data); + + /* call the callbacks */ + gpio_fire_callbacks(&data->callbacks, dev, pin_mask); +} + +static void gpio_sedi_write_raw(const struct device *dev, + uint32_t pins, + bool is_clear) +{ + uint8_t i; + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + sedi_gpio_pin_state_t val; + + if (is_clear) { + val = SEDI_GPIO_STATE_LOW; + } else { + val = SEDI_GPIO_STATE_HIGH; + } + + for (i = 0; i < config->pin_nums; i++) { + if (pins & 0x1) { + sedi_gpio_write_pin(gpio_dev, i, val); + } + pins >>= 1; + if (pins == 0) { + break; + } + } +} + +static int gpio_sedi_configure(const struct device *dev, gpio_pin_t pin, + gpio_flags_t flags) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + sedi_gpio_pin_config_t pin_config = { 0 }; + + if ((flags & GPIO_OUTPUT) && (flags & GPIO_INPUT)) { + /* Pin cannot be configured as input and output */ + return -ENOTSUP; + } else if (!(flags & (GPIO_INPUT | GPIO_OUTPUT))) { + /* Pin has to be configured as input or output */ + return -ENOTSUP; + } + + pin_config.enable_interrupt = false; + /* Map direction */ + if (flags & GPIO_OUTPUT) { + pin_config.direction = SEDI_GPIO_DIR_MODE_OUTPUT; + sedi_gpio_config_pin(gpio_dev, pin, pin_config); + /* Set start state */ + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + sedi_gpio_write_pin(gpio_dev, pin, 1); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + sedi_gpio_write_pin(gpio_dev, pin, 0); + } + } else { + pin_config.direction = SEDI_GPIO_DIR_MODE_INPUT; + sedi_gpio_config_pin(gpio_dev, pin, pin_config); + } + + return 0; +} + +static int gpio_sedi_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + + *value = sedi_gpio_read_pin_32bits(gpio_dev, 0); + + return 0; +} + +static int gpio_sedi_set_masked_raw(const struct device *dev, + uint32_t mask, + uint32_t value) +{ + gpio_sedi_write_raw(dev, (mask & value), false); + + return 0; +} + +static int gpio_sedi_set_bits_raw(const struct device *dev, uint32_t pins) +{ + gpio_sedi_write_raw(dev, pins, false); + + return 0; +} + +static int gpio_sedi_clear_bits_raw(const struct device *dev, uint32_t pins) +{ + gpio_sedi_write_raw(dev, pins, true); + + return 0; +} + +static int gpio_sedi_toggle_bits(const struct device *dev, uint32_t pins) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + uint8_t i; + + for (i = 0; i < config->pin_nums; i++) { + if (pins & 0x1) { + sedi_gpio_toggle_pin(gpio_dev, i); + } + pins >>= 1; + if (pins == 0) { + break; + } + } + + return 0; +} + +static int gpio_sedi_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + sedi_gpio_pin_config_t pin_config = { 0 }; + + /* Not support level trigger */ + if (mode == GPIO_INT_MODE_LEVEL) { + return -EINVAL; + } + /* Only input needs interrupt enabled */ + pin_config.direction = SEDI_GPIO_DIR_MODE_INPUT; + pin_config.enable_wakeup = true; + if (mode == GPIO_INT_MODE_DISABLED) { + pin_config.enable_interrupt = false; + } else { + pin_config.enable_interrupt = true; + switch (trig) { + case GPIO_INT_TRIG_LOW: + pin_config.interrupt_mode = + SEDI_GPIO_INT_MODE_FALLING_EDGE; + break; + case GPIO_INT_TRIG_HIGH: + pin_config.interrupt_mode = + SEDI_GPIO_INT_MODE_RISING_EDGE; + break; + case GPIO_INT_TRIG_BOTH: + pin_config.interrupt_mode = + SEDI_GPIO_INT_MODE_BOTH_EDGE; + break; + } + } + /* Configure interrupt mode */ + sedi_gpio_config_pin(gpio_dev, pin, pin_config); + + return 0; +} + +static int gpio_sedi_manage_callback(const struct device *dev, + struct gpio_callback *callback, + bool set) +{ + struct gpio_sedi_data *data = dev->data; + + gpio_manage_callback(&(data->callbacks), callback, set); + + return 0; +} + +static uint32_t gpio_sedi_get_pending(const struct device *dev) +{ + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + + return sedi_gpio_get_gisr(gpio_dev, 0); +} + +static const struct gpio_driver_api gpio_sedi_driver_api = { + .pin_configure = gpio_sedi_configure, + .port_get_raw = gpio_sedi_get_raw, + .port_set_masked_raw = gpio_sedi_set_masked_raw, + .port_set_bits_raw = gpio_sedi_set_bits_raw, + .port_clear_bits_raw = gpio_sedi_clear_bits_raw, + .port_toggle_bits = gpio_sedi_toggle_bits, + .pin_interrupt_configure = gpio_sedi_interrupt_configure, + .manage_callback = gpio_sedi_manage_callback, + .get_pending_int = gpio_sedi_get_pending +}; + +extern void gpio_isr(IN sedi_gpio_t gpio_device); + +static int gpio_sedi_init(const struct device *dev) +{ + int ret; + const struct gpio_sedi_config *config = dev->config; + sedi_gpio_t gpio_dev = config->device; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + /* Call sedi gpio init */ + ret = sedi_gpio_init(gpio_dev, gpio_sedi_callback, (void *)dev); + + if (ret != 0) { + return ret; + } + sedi_gpio_set_power(gpio_dev, SEDI_POWER_FULL); + + config->irq_config(); + + return 0; +} + +#define GPIO_SEDI_IRQ_FLAGS_SENSE0(n) 0 +#define GPIO_SEDI_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) +#define GPIO_SEDI_IRQ_FLAGS(n) \ + _CONCAT(GPIO_SEDI_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + +#define GPIO_DEVICE_INIT_SEDI(n) \ + static struct gpio_sedi_data gpio##n##_data; \ + static void gpio_sedi_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + gpio_isr, n, \ + GPIO_SEDI_IRQ_FLAGS(n)); \ + irq_enable(DT_INST_IRQN(n)); \ + }; \ + static const struct gpio_sedi_config gpio##n##_config = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + .common = { 0xFFFFFFFF }, \ + .device = DT_INST_PROP(n, peripheral_id), \ + .pin_nums = DT_INST_PROP(n, ngpios), \ + .irq_config = gpio_sedi_irq_config_##n, \ + }; \ + PM_DEVICE_DEFINE(gpio_##n, gpio_sedi_pm_action); \ + DEVICE_DT_INST_DEFINE(n, \ + &gpio_sedi_init, \ + PM_DEVICE_GET(gpio_##n), \ + &gpio##n##_data, \ + &gpio##n##_config, \ + POST_KERNEL, \ + CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_sedi_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_DEVICE_INIT_SEDI) diff --git a/dts/bindings/gpio/intel,sedi-gpio.yaml b/dts/bindings/gpio/intel,sedi-gpio.yaml new file mode 100644 index 00000000000..747546bd56f --- /dev/null +++ b/dts/bindings/gpio/intel,sedi-gpio.yaml @@ -0,0 +1,30 @@ +# +# Copyright (c) 2023 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Intel SEDI GPIO + +compatible: "intel,sedi-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + peripheral-id: + type: int + description: Peripheral Instance ID + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/x86/intel/intel_ish5.dtsi b/dts/x86/intel/intel_ish5.dtsi index 51f15907bef..375b9cc4ea4 100644 --- a/dts/x86/intel/intel_ish5.dtsi +++ b/dts/x86/intel/intel_ish5.dtsi @@ -150,5 +150,18 @@ clock-frequency = ; status = "disabled"; }; + + gpio0: gpio@100000 { + compatible = "intel,sedi-gpio"; + gpio-controller; + #gpio-cells = <2>; + peripheral-id = <0>; + reg = <0x00100000 0x1000>; + interrupt-parent = <&intc>; + ngpios = <32>; + interrupts = <13 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "okay"; + }; }; }; diff --git a/dts/x86/intel/intel_ish5_8.dtsi b/dts/x86/intel/intel_ish5_8.dtsi index 555b8e28e7b..fba74881cf4 100644 --- a/dts/x86/intel/intel_ish5_8.dtsi +++ b/dts/x86/intel/intel_ish5_8.dtsi @@ -35,3 +35,9 @@ status = "disabled"; }; + +&gpio0 { + interrupts = <16 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "okay"; +}; From 2d49ab66234452b3f394f2752ac1728d7c26e7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:36:45 +0700 Subject: [PATCH 0234/4498] tests: mqtt: disable debug log level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid to use debug log level for all modules and keep it only for MQTT and NET related modules. mr_canhubk3 board will fail to initialize the on-board watchdog within the expected window causing a board reset, due to the amount of log messages being printed. Other boards may also be affected. Signed-off-by: Manuel Argüelles --- tests/net/lib/mqtt_sn_client/prj.conf | 1 - tests/net/lib/mqtt_sn_packet/prj.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/net/lib/mqtt_sn_client/prj.conf b/tests/net/lib/mqtt_sn_client/prj.conf index 8ddc1c24880..5c0a5c99f48 100644 --- a/tests/net/lib/mqtt_sn_client/prj.conf +++ b/tests/net/lib/mqtt_sn_client/prj.conf @@ -6,7 +6,6 @@ CONFIG_NET_TEST=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_NET_LOG=y CONFIG_MQTT_SN_LOG_LEVEL_DBG=y diff --git a/tests/net/lib/mqtt_sn_packet/prj.conf b/tests/net/lib/mqtt_sn_packet/prj.conf index 6fa328dcd0e..870f8a813db 100644 --- a/tests/net/lib/mqtt_sn_packet/prj.conf +++ b/tests/net/lib/mqtt_sn_packet/prj.conf @@ -6,7 +6,6 @@ CONFIG_NET_TEST=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_NET_LOG=y CONFIG_MQTT_SN_LOG_LEVEL_DBG=y CONFIG_NET_BUF_LOG_LEVEL_DBG=y From 7ec624c3c47bb1e8ec950104838f5845997a77f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:36:53 +0700 Subject: [PATCH 0235/4498] samples: rtio: disable debug log level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid to build with debug log level enabled and instead register the test log modules with debug level. mr_canhubk3 board will fail to initialize the on-board watchdog within the expected window triggering a reset, due to the amount of log messages being printed. Other boards may face similar issues. Signed-off-by: Manuel Argüelles --- samples/subsys/rtio/sensor_batch_processing/prj.conf | 1 - samples/subsys/rtio/sensor_batch_processing/src/main.c | 2 +- samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/subsys/rtio/sensor_batch_processing/prj.conf b/samples/subsys/rtio/sensor_batch_processing/prj.conf index 68a9ea43ad2..340b3ed9a00 100644 --- a/samples/subsys/rtio/sensor_batch_processing/prj.conf +++ b/samples/subsys/rtio/sensor_batch_processing/prj.conf @@ -1,5 +1,4 @@ CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=y -CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_RTIO=y CONFIG_RTIO_SYS_MEM_BLOCKS=y diff --git a/samples/subsys/rtio/sensor_batch_processing/src/main.c b/samples/subsys/rtio/sensor_batch_processing/src/main.c index c9306c68f01..8fa1a3641ad 100644 --- a/samples/subsys/rtio/sensor_batch_processing/src/main.c +++ b/samples/subsys/rtio/sensor_batch_processing/src/main.c @@ -8,7 +8,7 @@ #include #include -LOG_MODULE_REGISTER(main); +LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); #define N (8) #define M (N/2) diff --git a/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c b/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c index c00dfd9d421..a8662c04998 100644 --- a/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c +++ b/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c @@ -11,7 +11,7 @@ #include #include -LOG_MODULE_REGISTER(vnd_sensor); +LOG_MODULE_REGISTER(vnd_sensor, LOG_LEVEL_DBG); struct vnd_sensor_config { uint32_t sample_period; From a1afaa8b478d96ef303f6dd30b7c159e4b3a009a Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Sep 2023 16:21:34 +0000 Subject: [PATCH 0236/4498] drivers: ioapic: declare the device with DEVICE_DT_INST_DEFINE Use DEVICE_DT_INST_DEFINE instead of DEVICE_DEFINE to declare the device structure. This ensures that the device gets an ordinal and is initialized before any device depending on it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_ioapic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_ioapic.c b/drivers/interrupt_controller/intc_ioapic.c index 424f1d5332c..41a6266a699 100644 --- a/drivers/interrupt_controller/intc_ioapic.c +++ b/drivers/interrupt_controller/intc_ioapic.c @@ -543,7 +543,7 @@ static void IoApicRedUpdateLo(unsigned int irq, ioApicRedSetLo(irq, (ioApicRedGetLo(irq) & ~mask) | (value & mask)); } -PM_DEVICE_DEFINE(ioapic, ioapic_pm_action); +PM_DEVICE_DT_INST_DEFINE(0, ioapic_pm_action); -DEVICE_DEFINE(ioapic, "ioapic", ioapic_init, PM_DEVICE_GET(ioapic), NULL, NULL, - PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); +DEVICE_DT_INST_DEFINE(0, ioapic_init, PM_DEVICE_DT_INST_GET(0), NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From c33492655f5f795cc39804ffee26b7110e4e1f07 Mon Sep 17 00:00:00 2001 From: Markus Fuchs Date: Fri, 8 Sep 2023 17:17:40 +0200 Subject: [PATCH 0237/4498] drivers: bluetooth: slz_hci: Adapt to library BLOBs version 4.2.4 Make HCI driver compatible to the updated versions of the EFR32 Bluetooth library BLOBs consisting of: * libbluetooth_controller * libbgcommon * librail Signed-off-by: Markus Fuchs --- drivers/bluetooth/hci/slz_hci.c | 13 ++++++++----- west.yml | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/bluetooth/hci/slz_hci.c b/drivers/bluetooth/hci/slz_hci.c index 59bd8ba5ff9..d80de8be998 100644 --- a/drivers/bluetooth/hci/slz_hci.c +++ b/drivers/bluetooth/hci/slz_hci.c @@ -16,11 +16,12 @@ #include LOG_MODULE_REGISTER(bt_hci_driver_slz); -#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 -#define SL_BT_CONFIG_MAX_CONNECTIONS 1 -#define SL_BT_CONFIG_USER_ADVERTISERS 1 -#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY -#define SL_BT_SILABS_LL_STACK_SIZE 1024 +#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 +#define SL_BT_CONFIG_MAX_CONNECTIONS 1 +#define SL_BT_CONFIG_USER_ADVERTISERS 1 +#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY +#define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX CONFIG_BT_BUF_ACL_TX_COUNT +#define SL_BT_SILABS_LL_STACK_SIZE 1024 static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE); static struct k_thread slz_ll_thread; @@ -135,6 +136,8 @@ static int slz_bt_open(void) return -ENOMEM; } + sl_btctrl_configure_le_buffer_size(SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX); + ret = sl_btctrl_init_ll(); if (ret) { LOG_ERR("Bluetooth link layer init failed %d", ret); diff --git a/west.yml b/west.yml index 85ee1533f95..3d76e4dc6a3 100644 --- a/west.yml +++ b/west.yml @@ -219,7 +219,7 @@ manifest: groups: - hal - name: hal_silabs - revision: d184c2ccc0ec5a7189d6d5cb7645c7f9bd38c2b5 + revision: 20113e9520ce59ee7fa85ba10102d0880822bb3e path: modules/hal/silabs groups: - hal From ba57c1880c665c51fe913c1a94c9faa4d4728892 Mon Sep 17 00:00:00 2001 From: Markus Fuchs Date: Fri, 8 Sep 2023 17:40:17 +0200 Subject: [PATCH 0238/4498] drivers: bluetooth: slz_hci: Set Number of Completed Packets threshold Configure the Number of Completed Packets event threshold to 1, so the SiLabs Bluetooth controller will always send the Number of Completed Packets HCI event to the host, even for small numbers of transmitted packets. Fixes #62279 Signed-off-by: Markus Fuchs --- drivers/bluetooth/hci/slz_hci.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/bluetooth/hci/slz_hci.c b/drivers/bluetooth/hci/slz_hci.c index d80de8be998..9fe5cb5981c 100644 --- a/drivers/bluetooth/hci/slz_hci.c +++ b/drivers/bluetooth/hci/slz_hci.c @@ -16,12 +16,14 @@ #include LOG_MODULE_REGISTER(bt_hci_driver_slz); -#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 -#define SL_BT_CONFIG_MAX_CONNECTIONS 1 -#define SL_BT_CONFIG_USER_ADVERTISERS 1 -#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY -#define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX CONFIG_BT_BUF_ACL_TX_COUNT -#define SL_BT_SILABS_LL_STACK_SIZE 1024 +#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 +#define SL_BT_CONFIG_MAX_CONNECTIONS 1 +#define SL_BT_CONFIG_USER_ADVERTISERS 1 +#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY +#define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX CONFIG_BT_BUF_ACL_TX_COUNT +#define SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD 1 +#define SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT 3 +#define SL_BT_SILABS_LL_STACK_SIZE 1024 static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE); static struct k_thread slz_ll_thread; @@ -158,6 +160,10 @@ static int slz_bt_open(void) goto deinit; } + sl_btctrl_configure_completed_packets_reporting( + SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD, + SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT); + sl_bthci_init_upper(); sl_btctrl_hci_parser_init_default(); sl_btctrl_hci_parser_init_conn(); From 85d2202e43631e72b3fb3b4e50b7a7174939bf30 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 8 Sep 2023 09:39:36 +0200 Subject: [PATCH 0239/4498] action: manifest: Use the new Git tree checkout feature Use the feature introduced in: https://github.com/zephyrproject-rtos/action-manifest/pull/8 This requires a West workspace to be initialized, since it uses Manifest.from_file(). Signed-off-by: Carles Cufi --- .github/workflows/manifest.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 1ea0031fb56..49f67fb95b7 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -15,12 +15,23 @@ jobs: fetch-depth: 0 persist-credentials: false + - name: west setup + env: + BASE_REF: ${{ github.base_ref }} + working-directory: zephyrproject/zephyr + run: | + pip3 install west + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + west init -l . || true + - name: Manifest - uses: zephyrproject-rtos/action-manifest@a6d0c6e52bbbb7d6df23ceb42842edcb4582b8dc + uses: zephyrproject-rtos/action-manifest@f223dce288b0d8f30bfd57eb2b14b18c230a7d8b with: github-token: ${{ secrets.ZB_GITHUB_TOKEN }} manifest-path: 'west.yml' checkout-path: 'zephyrproject/zephyr' + use-tree-checkout: 'true' label-prefix: 'manifest-' verbosity-level: '1' labels: 'manifest' From 20d2bbdbf00693327f4c6e5d66e6c24a3aa9a8a0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 8 Sep 2023 07:30:30 +0100 Subject: [PATCH 0240/4498] cmake: modules: host tools: Bump minimum version to 0.16 Some tests require the zephyr toolchain version 0.16 or newer to be able to use picolibc functionality. Signed-off-by: Jamie McCrae --- cmake/modules/FindHostTools.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindHostTools.cmake b/cmake/modules/FindHostTools.cmake index c8f28f21285..82225b49e56 100644 --- a/cmake/modules/FindHostTools.cmake +++ b/cmake/modules/FindHostTools.cmake @@ -50,7 +50,7 @@ endif() find_package(Deprecated COMPONENTS XCC_USE_CLANG CROSS_COMPILE) -find_package(Zephyr-sdk 0.15) +find_package(Zephyr-sdk 0.16) # gperf is an optional dependency find_program(GPERF gperf) From 44c723e65d659a222b8744eba97a62335962d197 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Tue, 5 Sep 2023 12:28:45 +0200 Subject: [PATCH 0241/4498] drivers: gpio_nrfx: Allow to disable interrupt support Change introduces a new configuration option that can be used to disable GPIO interrupt support to reduce memory footprint. Signed-off-by: Marek Pieta --- drivers/gpio/Kconfig.nrfx | 11 +++++++++- drivers/gpio/gpio_nrfx.c | 42 +++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/Kconfig.nrfx b/drivers/gpio/Kconfig.nrfx index 6757b6b12e9..356c43cb5fa 100644 --- a/drivers/gpio/Kconfig.nrfx +++ b/drivers/gpio/Kconfig.nrfx @@ -1,10 +1,19 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config GPIO_NRFX +menuconfig GPIO_NRFX bool "nRF GPIO driver" default y depends on DT_HAS_NORDIC_NRF_GPIO_ENABLED select NRFX_GPIOTE help Enable GPIO driver for nRF line of MCUs. + +config GPIO_NRFX_INTERRUPT + bool "Interrupt support" + depends on GPIO_NRFX + default y + help + The option can be used to disable the GPIO interrupt support to + significantly reduce memory footprint in case of application that does + not need GPIO interrupts. diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 1683b8b2cea..0aa282dda37 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -85,17 +85,19 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - nrfx_err_t err; + nrfx_err_t err = NRFX_SUCCESS; uint8_t ch; - bool free_ch; + bool free_ch = false; const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); /* Get the GPIOTE channel associated with this pin, if any. It needs * to be freed when the pin is reconfigured or disconnected. */ - err = nrfx_gpiote_channel_get(abs_pin, &ch); - free_ch = (err == NRFX_SUCCESS); + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { + err = nrfx_gpiote_channel_get(abs_pin, &ch); + free_ch = (err == NRFX_SUCCESS); + } if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { /* Ignore the error code. The pin may not have been used. */ @@ -109,19 +111,21 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, return 0; } - nrfx_gpiote_trigger_config_t trigger_config = { - .trigger = NRFX_GPIOTE_TRIGGER_NONE - }; + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { + nrfx_gpiote_trigger_config_t trigger_config = { + .trigger = NRFX_GPIOTE_TRIGGER_NONE + }; - /* Remove previously configured trigger when pin is reconfigured. */ - err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); - if (err != NRFX_SUCCESS) { - return -EINVAL; - } + /* Remove previously configured trigger when pin is reconfigured. */ + err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); + if (err != NRFX_SUCCESS) { + return -EINVAL; + } - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + if (free_ch) { + err = nrfx_gpiote_channel_free(ch); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + } } if (flags & GPIO_OUTPUT) { @@ -219,6 +223,7 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port, return 0; } +#ifdef CONFIG_GPIO_NRFX_INTERRUPT static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode, enum gpio_int_trig trig) { @@ -285,6 +290,7 @@ static int gpio_nrfx_manage_callback(const struct device *port, return gpio_manage_callback(&get_port_data(port)->callbacks, callback, set); } +#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ #ifdef CONFIG_GPIO_GET_DIRECTION static int gpio_nrfx_port_get_direction(const struct device *port, @@ -322,6 +328,7 @@ static int gpio_nrfx_port_get_direction(const struct device *port, } #endif /* CONFIG_GPIO_GET_DIRECTION */ +#ifdef CONFIG_GPIO_NRFX_INTERRUPT /* Get port device from port id. */ static const struct device *get_dev(uint32_t port_id) { @@ -358,6 +365,7 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, gpio_fire_callbacks(list, port, BIT(pin)); } +#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ #define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote) @@ -374,10 +382,12 @@ static int gpio_nrfx_init(const struct device *port) return -EIO; } +#ifdef CONFIG_GPIO_NRFX_INTERRUPT nrfx_gpiote_global_callback_set(nrfx_gpio_handler, NULL); IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), nrfx_isr, nrfx_gpiote_irq_handler, 0); +#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ return 0; } @@ -389,8 +399,10 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { .port_set_bits_raw = gpio_nrfx_port_set_bits_raw, .port_clear_bits_raw = gpio_nrfx_port_clear_bits_raw, .port_toggle_bits = gpio_nrfx_port_toggle_bits, +#ifdef CONFIG_GPIO_NRFX_INTERRUPT .pin_interrupt_configure = gpio_nrfx_pin_interrupt_configure, .manage_callback = gpio_nrfx_manage_callback, +#endif #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_nrfx_port_get_direction, #endif From 9b56e8ac63943e81a2bd3c5f655069b9a7b6a6c2 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 12 Sep 2023 13:54:09 +0200 Subject: [PATCH 0242/4498] Revert "drivers/spi: stm32: fix TX-only mode" This reverts commit 31cd3b1f61e914ca23a620033e22ec8d33402369. This change is causing regression in SPI loopback tests. Signed-off-by: Erwan Gouriou --- drivers/spi/spi_ll_stm32.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 1991bfe6521..948b7641eaf 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -324,10 +324,8 @@ static void spi_stm32_shift_m(SPI_TypeDef *spi, struct spi_stm32_data *data) spi_context_update_tx(&data->ctx, 2, 1); } - if (spi_context_rx_buf_on(&data->ctx)) { - while (!ll_func_rx_is_not_empty(spi)) { - /* NOP */ - } + while (!ll_func_rx_is_not_empty(spi)) { + /* NOP */ } if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { From 840f2e40b570dcd299bc944c03a183950d635a77 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 11 Sep 2023 16:30:54 +0200 Subject: [PATCH 0243/4498] modem: chat: Add partial match feature to modem_chat This commit adds support for partial matches for the modem_chat module. A match is a combination of an expected response to a request along with delimiters to use and a handler for the parsed response. The usual behavior of the modem_chat script is to continue to the next step when any expected response is received. The partial flag indicates that the script should not proceed to the next step if the response matches the match. This is useful for commands which respond with an unspecified number of lines, followed by an "OK". This flag allows the script to essentially run in a "while" loop until OK is received. Along with this addition, a more scalable macro for initializing the modem_chat match struct, MODEM_CHAT_MATCH_INITIALIZER(). Without this macro, we will need 4 different macros to initialize the 4 variants of a chat_match, and 8 when the next feature is added... Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/chat.h | 16 +++++++++++++++- subsys/modem/modem_chat.c | 5 +++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index f25e1d9893b..17c23c25892 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -44,7 +44,10 @@ struct modem_chat_match { const uint8_t separators_size; /* Set if modem chat instance shall use wildcards when matching */ - const bool wildcards; + const uint8_t wildcards : 1; + + /* Set if script shall not continue to next step in case of match */ + const uint8_t partial : 1; /* Type of modem chat instance */ const modem_chat_match_callback callback; @@ -66,6 +69,17 @@ struct modem_chat_match { .callback = _callback, \ } +#define MODEM_CHAT_MATCH_INITIALIZER(_match, _separators, _callback, _wildcards, _partial) \ + { \ + .match = (uint8_t *)(_match), \ + .match_size = (uint8_t)(sizeof(_match) - 1), \ + .separators = (uint8_t *)(_separators), \ + .separators_size = (uint8_t)(sizeof(_separators) - 1), \ + .wildcards = _wildcards, \ + .partial = _partial, \ + .callback = _callback, \ + } + #define MODEM_CHAT_MATCH_DEFINE(_sym, _match, _separators, _callback) \ const static struct modem_chat_match _sym = MODEM_CHAT_MATCH(_match, _separators, _callback) diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index 27f958dc7b5..bd5824da9a6 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -459,6 +459,11 @@ static void modem_chat_on_command_received_resp(struct modem_chat *chat) chat->parse_match->callback(chat, (char **)chat->argv, chat->argc, chat->user_data); } + /* Validate response command is not partial */ + if (chat->parse_match->partial) { + return; + } + /* Advance script */ modem_chat_script_next(chat, false); } From 4129b10b6900133e41829893c36a01527f293548 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 11 Sep 2023 19:02:47 +0200 Subject: [PATCH 0244/4498] modem: tests: Add test case for partial matches This commit adds a test for the partial matches. Signed-off-by: Bjarki Arge Andreasen --- tests/subsys/modem/modem_chat/src/main.c | 103 +++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/tests/subsys/modem/modem_chat/src/main.c b/tests/subsys/modem/modem_chat/src/main.c index c078119d241..6af24bffaa8 100644 --- a/tests/subsys/modem/modem_chat/src/main.c +++ b/tests/subsys/modem/modem_chat/src/main.c @@ -42,6 +42,8 @@ static struct modem_pipe *mock_pipe; #define MODEM_CHAT_UTEST_ON_APP_RDY_CALLED_BIT (7) #define MODEM_CHAT_UTEST_ON_NORMAL_POWER_DOWN_CALLED_BIT (8) #define MODEM_CHAT_UTEST_ON_SCRIPT_CALLBACK_BIT (9) +#define MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_CALLED_BIT (10) +#define MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_ANY_CALLED_BIT (11) static atomic_t callback_called; @@ -119,6 +121,19 @@ static void on_normal_power_down(struct modem_chat *cmd, char **argv, uint16_t a clone_args(argv, argc); } +static void on_cmgl_partial(struct modem_chat *cmd, char **argv, uint16_t argc, void *user_data) +{ + atomic_set_bit(&callback_called, MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_CALLED_BIT); + clone_args(argv, argc); +} + +static void on_cmgl_any_partial(struct modem_chat *cmd, char **argv, uint16_t argc, + void *user_data) +{ + atomic_set_bit(&callback_called, MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_ANY_CALLED_BIT); + clone_args(argv, argc); +} + /*************************************************************************************************/ /* Script callback */ /*************************************************************************************************/ @@ -161,6 +176,23 @@ MODEM_CHAT_MATCHES_DEFINE(abort_matches, MODEM_CHAT_MATCH("NO CARRIER", "", on_n MODEM_CHAT_SCRIPT_DEFINE(script, script_cmds, abort_matches, on_script_result, 4); +/*************************************************************************************************/ +/* Script implementing partial matches */ +/*************************************************************************************************/ +MODEM_CHAT_MATCHES_DEFINE( + cmgl_matches, + MODEM_CHAT_MATCH_INITIALIZER("+CMGL: ", ",", on_cmgl_partial, false, true), + MODEM_CHAT_MATCH_INITIALIZER("", "", on_cmgl_any_partial, false, true), + MODEM_CHAT_MATCH_INITIALIZER("OK", "", NULL, false, false) +); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE( + script_partial_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CMGL=4", cmgl_matches), +); + +MODEM_CHAT_SCRIPT_DEFINE(script_partial, script_partial_cmds, abort_matches, on_script_result, 4); + /*************************************************************************************************/ /* Script responses */ /*************************************************************************************************/ @@ -174,6 +206,9 @@ static const char qeng_servinc_cell_response[] = "+QENG: \"servingcell\",\"NOCON ",03,E182,AEAD,52,32,2,-68,255,255,0,38,38,1,," ",,,,,,,,\r\n"; +static const char cmgl_response_0[] = "+CMGL: 1,1,,50\r\n"; +static const char cmgl_response_1[] = "07911326060032F064A9542954\r\n"; + /*************************************************************************************************/ /* Test setup */ /*************************************************************************************************/ @@ -416,6 +451,74 @@ ZTEST(modem_chat, test_start_script_then_time_out) "Script result callback user data is incorrect"); } +ZTEST(modem_chat, test_script_with_partial_matches) +{ + bool called; + + zassert_true(modem_chat_script_run(&cmd, &script_partial) == 0, "Failed to start script"); + k_msleep(100); + + /* + * Script sends "AT+CMGL=4\r"; + */ + + modem_backend_mock_get(&mock, buffer, ARRAY_SIZE(buffer)); + zassert_true(memcmp(buffer, "AT+CMGL=4\r", sizeof("AT+CMGL=4\r") - 1) == 0, + "Request not sent as expected"); + + /* + * Modem will return the following sequence 3 times + * "+CMGL: 1,1,,50\r"; + * "07911326060032F064A9542954\r" + */ + + for (uint8_t i = 0; i < 3; i++) { + atomic_set(&callback_called, 0); + modem_backend_mock_put(&mock, cmgl_response_0, sizeof(cmgl_response_0) - 1); + k_msleep(100); + + called = atomic_test_bit(&callback_called, + MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_CALLED_BIT); + zassert_equal(called, true, "Match callback not called"); + zassert_equal(argc_buffers, 5, "Incorrect number of args"); + zassert_equal(strcmp(argv_buffers[0], "+CMGL: "), 0, "Incorrect argv received"); + zassert_equal(strcmp(argv_buffers[1], "1"), 0, "Incorrect argv received"); + zassert_equal(strcmp(argv_buffers[2], "1"), 0, "Incorrect argv received"); + zassert_equal(strcmp(argv_buffers[3], ""), 0, "Incorrect argv received"); + zassert_equal(strcmp(argv_buffers[4], "50"), 0, "Incorrect argv received"); + + atomic_set(&callback_called, 0); + modem_backend_mock_put(&mock, cmgl_response_1, sizeof(cmgl_response_1) - 1); + k_msleep(100); + + called = atomic_test_bit(&callback_called, + MODEM_CHAT_UTEST_ON_CMGL_PARTIAL_ANY_CALLED_BIT); + zassert_equal(called, true, "Match callback not called"); + zassert_equal(argc_buffers, 2, "Incorrect number of args"); + zassert_equal(strcmp(argv_buffers[0], ""), 0, "Incorrect argv received"); + zassert_equal(strcmp(argv_buffers[1], "07911326060032F064A9542954"), 0, + "Incorrect argv received"); + } + + atomic_set(&callback_called, 0); + modem_backend_mock_put(&mock, ok_response, sizeof(ok_response) - 1); + k_msleep(100); + + /* + * Modem returns "OK\r" + * Script terminates + */ + + called = atomic_test_bit(&callback_called, MODEM_CHAT_UTEST_ON_SCRIPT_CALLBACK_BIT); + zassert_true(called == true, "Script callback should have been called"); + zassert_equal(script_result, MODEM_CHAT_SCRIPT_RESULT_SUCCESS, + "Script should have stopped with success"); + + /* Assert no data was sent except the request */ + zassert_equal(modem_backend_mock_get(&mock, buffer, ARRAY_SIZE(buffer)), 0, + "Script sent too many requests"); +} + /*************************************************************************************************/ /* Test suite */ /*************************************************************************************************/ From 89c866ab68e47cd598516b5564ac52773a41c115 Mon Sep 17 00:00:00 2001 From: Aron Lander Date: Thu, 7 Sep 2023 10:08:56 +0200 Subject: [PATCH 0245/4498] modules: Add DFM and move Tracerecorder into percepio module This commit adds the DFM (DevAlert target side code) module and moves the TraceRecorder module into the percepio module, which results in the TraceRecorder module definition being removed from the west manufest and module definition within zephyr. Signed-off-by: Aron Lander --- MAINTAINERS.yml | 19 ++--- .../CMakeLists.txt | 74 ++++++++++++++++++- modules/{TraceRecorder => percepio}/Kconfig | 6 +- subsys/tracing/Kconfig | 2 +- west.yml | 10 +-- 5 files changed, 90 insertions(+), 21 deletions(-) rename modules/{TraceRecorder => percepio}/CMakeLists.txt (63%) rename modules/{TraceRecorder => percepio}/Kconfig (54%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 3dd26f34b23..f934d8df55f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3377,6 +3377,16 @@ West: labels: - "area: OpenThread" +"West project: percepio": + status: maintained + maintainers: + - eriktamlin + - aronlander-pe + files: + - modules/percepio/ + labels: + - "area: Tracing" + "West project: picolibc": status: maintained maintainers: @@ -3441,15 +3451,6 @@ West: labels: - "area: Crypto / RNG" -"West project: TraceRecorderSource": - status: maintained - maintainers: - - eriktamlin - files: - - modules/TraceRecorder/ - labels: - - "area: Tracing" - "West project: trusted-firmware-m": status: maintained maintainers: diff --git a/modules/TraceRecorder/CMakeLists.txt b/modules/percepio/CMakeLists.txt similarity index 63% rename from modules/TraceRecorder/CMakeLists.txt rename to modules/percepio/CMakeLists.txt index a0b4d6ad671..49de379e7f9 100644 --- a/modules/TraceRecorder/CMakeLists.txt +++ b/modules/percepio/CMakeLists.txt @@ -2,11 +2,14 @@ # # SPDX-License-Identifier: Apache-2.0 +if (CONFIG_PERCEPIO_TRACERECORDER OR CONFIG_PERCEPIO_DFM) + zephyr_library() +endif() + if(CONFIG_PERCEPIO_TRACERECORDER) - set(TRACERECORDER_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) + set(TRACERECORDER_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/TraceRecorder) - zephyr_library() zephyr_library_sources_ifdef( CONFIG_PERCEPIO_TRACERECORDER ${TRACERECORDER_DIR}/kernelports/Zephyr/trcKernelPort.c @@ -81,6 +84,7 @@ if(CONFIG_PERCEPIO_TRACERECORDER) ) endif() + zephyr_include_directories( ${TRACERECORDER_DIR}/kernelports/Zephyr/include ${TRACERECORDER_DIR}/kernelports/Zephyr/config @@ -88,8 +92,72 @@ if(CONFIG_PERCEPIO_TRACERECORDER) ${TRACERECORDER_DIR}/include ) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND python3 ${TRACERECORDER_DIR}/kernelports/Zephyr/scripts/tz_parse_syscalls.py ${CMAKE_BINARY_DIR} ${ZEPHYR_BASE} ) endif() + +if(CONFIG_PERCEPIO_DFM) + + set(DFM_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/DFM) + + zephyr_library_sources_ifdef( + CONFIG_PERCEPIO_DFM + ${DFM_DIR}/dfm.c + ${DFM_DIR}/dfmAlert.c + ${DFM_DIR}/dfmCloud.c + ${DFM_DIR}/dfmEntry.c + ${DFM_DIR}/dfmSession.c + ${DFM_DIR}/dfmStorage.c + ${DFM_DIR}/kernelports/Zephyr/dfmKernelPort.c + ) + + if(CONFIG_PERCEPIO_DFM_CFG_STORAGEPORT_NONE) + zephyr_library_sources( + ${DFM_DIR}/storageports/Dummy/dfmStoragePort.c + ) + + zephyr_include_directories( + ${DFM_DIR}/storageports/Dummy/include/ + ) + endif() + + if(CONFIG_PERCEPIO_DFM_CFG_STORAGEPORT_FLASH) + zephyr_library_sources( + ${DFM_DIR}/kernelports/Zephyr/storageports/Flash/dfmStoragePort.c + ) + + zephyr_include_directories( + ${DFM_DIR}/kernelports/Zephyr/storageports/Flash/include/ + ) + endif() + + if(CONFIG_PERCEPIO_DFM_CFG_CLOUDPORT_NONE) + zephyr_library_sources( + ${DFM_DIR}/cloudports/Dummy/dfmCloudPort.c + ) + + zephyr_include_directories( + ${DFM_DIR}/cloudports/Dummy/include/ + ) + endif() + + if(CONFIG_PERCEPIO_DFM_CFG_CLOUDPORT_SERIAL) + zephyr_library_sources( + ${DFM_DIR}/kernelports/Zephyr/cloudports/Serial/dfmCloudPort.c + ) + + zephyr_include_directories( + ${DFM_DIR}/kernelports/Zephyr/cloudports/Serial/config/ + ${DFM_DIR}/kernelports/Zephyr/cloudports/Serial/include/ + ) + endif() + + zephyr_include_directories( + ${DFM_DIR}/kernelports/Zephyr/config + ${DFM_DIR}/kernelports/Zephyr/include + ${DFM_DIR}/include + ) + +endif() diff --git a/modules/TraceRecorder/Kconfig b/modules/percepio/Kconfig similarity index 54% rename from modules/TraceRecorder/Kconfig rename to modules/percepio/Kconfig index 2ab8ebd4e80..7e2546016db 100644 --- a/modules/TraceRecorder/Kconfig +++ b/modules/percepio/Kconfig @@ -1,10 +1,10 @@ -# Zephyr module config for TraceRecorder. +# Zephyr module config for percepio. # The real Kconfig for the module is located in the module repository, -# this file is to ensure ZEPHYR_TRACERECORDER_MODULE is defined also when the +# this file is to ensure ZEPHYR_PERCEPIO_MODULE is defined also when the # module is unavailable. # Copyright (c) 2021 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config ZEPHYR_TRACERECORDER_MODULE +config ZEPHYR_PERCEPIO_MODULE bool diff --git a/subsys/tracing/Kconfig b/subsys/tracing/Kconfig index 31d1637cd60..d7aa7b12e44 100644 --- a/subsys/tracing/Kconfig +++ b/subsys/tracing/Kconfig @@ -37,7 +37,7 @@ config PERCEPIO_TRACERECORDER select THREAD_NAME select INIT_STACKS select THREAD_MONITOR - depends on ZEPHYR_TRACERECORDER_MODULE + depends on ZEPHYR_PERCEPIO_MODULE config SEGGER_SYSTEMVIEW bool "Segger SystemView support" diff --git a/west.yml b/west.yml index 3d76e4dc6a3..1091ef024a7 100644 --- a/west.yml +++ b/west.yml @@ -305,6 +305,11 @@ manifest: - name: openthread revision: f7690fe7e9d638341921808cba6a3e695ec0131e path: modules/lib/openthread + - name: percepio + path: modules/debug/percepio + revision: 831f421994b67856970f131295d1a97ca9d1f086 + groups: + - debug - name: picolibc path: modules/lib/picolibc revision: d07c38ff051386f8e09a143ea0a6c1d6d66dd1d8 @@ -325,11 +330,6 @@ manifest: path: modules/crypto/tinycrypt groups: - crypto - - name: TraceRecorderSource - revision: 1ede7ce8e7ab226e9a84d95266241ba3f38d91d2 - path: modules/debug/TraceRecorder - groups: - - debug - name: trusted-firmware-m revision: b168d92c7ed3c77c94d7ce3362bdde5dbffe8424 path: modules/tee/tf-m/trusted-firmware-m From bf1410bd20fa9778c9c1ebdcc8c07a6e16968045 Mon Sep 17 00:00:00 2001 From: Aron Lander Date: Mon, 11 Sep 2023 09:06:35 +0200 Subject: [PATCH 0246/4498] west.yml: Updated to use the latest version of the percepio module The percepio module change removes unused kernel ports from the zephyr version of the percepio module. Signed-off-by: Aron Lander --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 1091ef024a7..74130cd5aa9 100644 --- a/west.yml +++ b/west.yml @@ -307,7 +307,7 @@ manifest: path: modules/lib/openthread - name: percepio path: modules/debug/percepio - revision: 831f421994b67856970f131295d1a97ca9d1f086 + revision: 7ba53eb1c22d14a49fa51f4b57fc0614a893fdd7 groups: - debug - name: picolibc From 8b6382e68d028f8901adb1bbd0fda51c98696752 Mon Sep 17 00:00:00 2001 From: Brian Juel Folkmann Date: Tue, 12 Sep 2023 08:51:24 +0200 Subject: [PATCH 0247/4498] drivers: flash: stm32 ospi: jedec_id read wrongly Manufacturer id is skipped when reading jedec_id, due to wrong address mode. Before: flash_stm32_ospi: Jedec ID = [60 20 00] After: flash_stm32_ospi: Jedec ID = [ef 60 20] Signed-off-by: Brian Juel Folkmann --- drivers/flash/flash_stm32_ospi.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 6f7cf0cc2a9..7e06f8ee2be 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -345,6 +345,17 @@ static OSPI_RegularCmdTypeDef ospi_prepare_cmd(uint8_t transfer_mode, uint8_t tr return cmd_tmp; } +static uint32_t stm32_ospi_hal_address_size(const struct device *dev) +{ + struct flash_stm32_ospi_data *dev_data = dev->data; + + if (dev_data->address_width == 4U) { + return HAL_OSPI_ADDRESS_32_BITS; + } + + return HAL_OSPI_ADDRESS_24_BITS; +} + #if defined(CONFIG_FLASH_JESD216_API) /* * Read the JEDEC ID data from the octoFlash at init or DTS @@ -367,7 +378,8 @@ static int stm32_ospi_read_jedec_id(const struct device *dev) OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(OSPI_SPI_MODE, OSPI_STR_TRANSFER); cmd.Instruction = JESD216_CMD_READ_ID; - cmd.AddressSize = HAL_OSPI_ADDRESS_NONE; + cmd.AddressSize = stm32_ospi_hal_address_size(dev); + cmd.AddressMode = HAL_OSPI_ADDRESS_NONE; cmd.NbData = JESD216_READ_ID_LEN; /* 3 bytes in the READ ID */ HAL_StatusTypeDef hal_ret; @@ -943,17 +955,6 @@ static int stm32_ospi_mem_reset(const struct device *dev) return 0; } -static uint32_t stm32_ospi_hal_address_size(const struct device *dev) -{ - struct flash_stm32_ospi_data *dev_data = dev->data; - - if (dev_data->address_width == 4U) { - return HAL_OSPI_ADDRESS_32_BITS; - } - - return HAL_OSPI_ADDRESS_24_BITS; -} - /* * Function to erase the flash : chip or sector with possible OSPI/SPI and STR/DTR * to erase the complete chip (using dedicated command) : From 7ae9a0b55de71e9ab6207cec5558b70095f92511 Mon Sep 17 00:00:00 2001 From: Miika Karanki Date: Wed, 6 Sep 2023 21:16:21 +0300 Subject: [PATCH 0248/4498] net: mqtt: change cipher and sec_tag lists to const cipher_list and sec_tag_list are used only with zsock_setsockopt in MQTT. For that use, they can be const (and potentially kept in flash memory). Signed-off-by: Miika Karanki --- include/zephyr/net/mqtt.h | 4 ++-- samples/net/cloud/aws_iot_mqtt/src/main.c | 2 +- samples/net/cloud/mqtt_azure/src/main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index 1980b95bbea..f1071af64f2 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -348,13 +348,13 @@ struct mqtt_sec_config { /** Indicates the list of ciphers to be used for the session. * May be NULL to use the default ciphers. */ - int *cipher_list; + const int *cipher_list; /** Indicates the number of entries in the sec tag list. */ uint32_t sec_tag_count; /** Indicates the list of security tags to be used for the session. */ - sec_tag_t *sec_tag_list; + const sec_tag_t *sec_tag_list; /** Peer hostname for ceritificate verification. * May be NULL to skip hostname verification. diff --git a/samples/net/cloud/aws_iot_mqtt/src/main.c b/samples/net/cloud/aws_iot_mqtt/src/main.c index eddca33de29..2eeec0fd240 100644 --- a/samples/net/cloud/aws_iot_mqtt/src/main.c +++ b/samples/net/cloud/aws_iot_mqtt/src/main.c @@ -58,7 +58,7 @@ static bool do_subscribe; /* Trigger client to subscribe */ #define TLS_TAG_DEVICE_PRIVATE_KEY 1 #define TLS_TAG_AWS_CA_CERTIFICATE 2 -static sec_tag_t sec_tls_tags[] = { +static const sec_tag_t sec_tls_tags[] = { TLS_TAG_DEVICE_CERTIFICATE, TLS_TAG_AWS_CA_CERTIFICATE, }; diff --git a/samples/net/cloud/mqtt_azure/src/main.c b/samples/net/cloud/mqtt_azure/src/main.c index c3cf2a568fa..0d1d0a2da6f 100644 --- a/samples/net/cloud/mqtt_azure/src/main.c +++ b/samples/net/cloud/mqtt_azure/src/main.c @@ -60,7 +60,7 @@ static K_SEM_DEFINE(mqtt_start, 0, 1); #define TLS_SNI_HOSTNAME CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME #define APP_CA_CERT_TAG 1 -static sec_tag_t m_sec_tags[] = { +static const sec_tag_t m_sec_tags[] = { APP_CA_CERT_TAG, }; From ad57c7d621134daf77ef77f5a3eb1732c9584100 Mon Sep 17 00:00:00 2001 From: Mia Koen Date: Wed, 6 Sep 2023 09:02:52 +0200 Subject: [PATCH 0249/4498] doc: bluetooth: mesh: listed models alphabetically Changed placement of a few models so they are in alphabetical order Signed-off-by: Mia Koen --- doc/connectivity/bluetooth/api/mesh/models.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index df3ba7404ef..80209099a72 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -12,18 +12,18 @@ used by network administrators to configure and diagnose mesh nodes. .. toctree:: :maxdepth: 1 - cfg_srv cfg_cli - health_srv + cfg_srv health_cli + health_srv lcd_cli lcd_srv od_cli od_srv op_agg_cli op_agg_srv - priv_beacon_srv priv_beacon_cli + priv_beacon_srv rpr_cli rpr_srv srpl_cli From 0d57935d8025aef5eb2aab49b13b4be2b645d779 Mon Sep 17 00:00:00 2001 From: Mia Koen Date: Mon, 4 Sep 2023 09:05:41 +0200 Subject: [PATCH 0250/4498] doc: bluetooth: mesh: doc for SAR Config models Adding rst files describing SAR Configuration models, SAR Configuration Client and SAR Configuration Server. Signed-off-by: Mia Koen --- doc/connectivity/bluetooth/api/mesh.rst | 1 + .../bluetooth/api/mesh/models.rst | 2 + .../bluetooth/api/mesh/sar_cfg.rst | 278 ++++++++++++++++++ .../bluetooth/api/mesh/sar_cfg_cli.rst | 34 +++ .../bluetooth/api/mesh/sar_cfg_srv.rst | 28 ++ 5 files changed, 343 insertions(+) create mode 100644 doc/connectivity/bluetooth/api/mesh/sar_cfg.rst create mode 100644 doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst create mode 100644 doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 1eb691b96c8..308fb5df953 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -17,6 +17,7 @@ Read more about Bluetooth mesh on the mesh/access.rst mesh/models.rst mesh/msg.rst + mesh/sar_cfg.rst mesh/provisioning.rst mesh/proxy.rst mesh/heartbeat.rst diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index 80209099a72..3f5f94152ce 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -26,6 +26,8 @@ used by network administrators to configure and diagnose mesh nodes. priv_beacon_srv rpr_cli rpr_srv + sar_cfg_cli + sar_cfg_srv srpl_cli srpl_srv diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst new file mode 100644 index 00000000000..1191ec3e2ab --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst @@ -0,0 +1,278 @@ +.. _bluetooth_mesh_sar_cfg: + +Segmentation and reassembly (SAR) +################################# + +Segmentation and reassembly (SAR) provides a way of handling larger upper transport layer messages in a +mesh network, with a purpose of enhancing the Bluetooth mesh throughput. The segmentation and +reassembly mechanism is used by the lower transport layer. + +The lower transport layer defines how the upper transport layer PDUs are segmented and reassembled into multiple Lower Transport PDUs, +and sends them to the lower transport layer on a peer device. +If the Upper Transport PDU fits, it is sent in a single Lower Transport PDU. +For longer packets, which do not fit into a single Lower Transport PDU, the lower transport layer performs segmentation, splitting the Upper Transport +PDU into multiple segments. + +The lower transport layer on the receiving device reassembles the segments into a single Upper Transport PDU before passing it +up the stack. Delivery of a segmented message is acknowledged by the lower transport layer of the receiving node, while an unsegmented message +delivery is not acknowledged. +However, an Upper Transport PDU that fits into one Lower Transport PDU can also be sent as a single-segment segmented message when acknowledgment +by the lower transport layer is required. +Set the ``send rel`` flag (see :c:struct:`bt_mesh_msg_ctx`) to use the reliable message transmission and acknowledge single-segment segmented messages. + +The transport layer is able to transport up to 32 segments with its SAR mechanism, with a maximum message (PDU) size of 384 octets. +To configure message size for the Bluetooth mesh stack, use the following Kconfig options: + +* :kconfig:option:`CONFIG_BT_MESH_RX_SEG_MAX` to set the maximum number of segments in an incoming message. +* :kconfig:option:`CONFIG_BT_MESH_TX_SEG_MAX` to set the maximum number of segments in an outgoing message. + +The Kconfig options :kconfig:option:`CONFIG_BT_MESH_TX_SEG_MSG_COUNT` and :kconfig:option:`CONFIG_BT_MESH_RX_SEG_MSG_COUNT` define how many +outgoing and incoming segmented messages can be processed simultaneously. When more than one segmented message is sent to the same destination, +the messages are queued and sent one at a time. + +Incoming and outgoing segmented messages share the same pool for allocation of their segments. This pool size is configured through the +:kconfig:option:`CONFIG_BT_MESH_SEG_BUFS` Kconfig option. +Both incoming and outgoing messages allocate segments at the start of the transaction. +The outgoing segmented message releases its segments one by one as soon as they are acknowledged by the receiver, while the incoming message releases +the segments first after the message is fully received. +Keep this in mind when defining the size of the buffers. + +SAR does not impose extra overhead on the access layer payload per segment. + +Intervals, timers and retransmission counters +********************************************* + +The current stable stack implementation allows you to configure the following SAR behavior. + +When sending a segmented message to a unicast address, the unacknowledged segments are repeated +the :kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT` number of times before the transmission +is considered as failed. The same option configures a number of retransmissions to a group or virtual +address, but the transmission always succeedes after retransmitting all segments the configured +number of times. + +The timeout between each retransmission to a unicast address is configured by the Kconfig option +:kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST`. The timeout between each retransmission +to a group or a virtual address is configured by the Kconfig option :kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP`. + +The time before sending a Segment Acknowledgment message is controlled by the Kconfig options +:kconfig:option:`CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT`, :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT` +and :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`, and is defined as: + +.. math:: + \begin{aligned} + \max(&\verb|CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT| \\ + &+ \text{TTL} \times \verb|CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT| \\ + &+ \text{number of un-acked segments} \times \verb|CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT| , 400) + \end{aligned} + +Segmentation and reassembly (SAR) Configuration models +====================================================== + +With Bluetooth Mesh Protocol Specification version 1.1, it became possible to configure SAR behavior, such as intervals, +timers and retransmission counters, over a mesh network using SAR Configuration models: + +* :ref:`bluetooth_mesh_sar_cfg_cli` +* :ref:`bluetooth_mesh_sar_cfg_srv` + +The following SAR behavior applies regardless of the presence of a SAR Configuration Server on a node. + +Transmission of segments is separated by a segment transmission interval (see the `SAR Segment Interval Step`_ state). +Other configurable time intervals and delays available for the segmentation and reassembly are: + +* Interval between unicast retransmissions (see the states `SAR Unicast Retransmissions Interval Step`_ and `SAR Unicast Retransmissions Interval Increment`_). +* Interval between multicast retransmissions (see the `SAR Multicast Retransmissions Interval Step`_ state). +* Segment reception interval (see the `SAR Receiver Segment Interval Step`_ state). +* Acknowledgment delay increment (see the `SAR Acknowledgment Delay Increment`_ state). + +When the last segment marked as unacknowledged is transmitted, the lower transport layer starts a retransmissions timer. +The initial value of the SAR Unicast Retransmissions timer depends on the value of the TTL field of the message. +If the TTL field value is greater than ``0``, the initial value for the timer is set according to the following formula: + +.. math:: + + unicast~retransmissions~interval~step + unicast~retransmissions~interval~increment \times (TTL - 1) + + +If the TTL field value is ``0``, the initial value of the timer is set to the unicast retransmissions interval step. + +The initial value of the SAR Multicast Retransmissions timer is set to the multicast retransmissions interval. + +When the lower transport layer receives a message segment, it starts a SAR Discard timer. +The discard timer tells how long the lower transport layer waits before discarding the segmented message the segment belongs to. +The initial value of the SAR Discard timer is the discard timeout value indicated by the `SAR Discard Timeout`_ state. + +SAR Acknowledgment timer holds the time before a Segment Acknowledgment message is sent for a received segment. +The initial value of the SAR Acknowledgment timer is calculated using the following formula: + +.. math:: + + min(SegN + 0.5 , acknowledgment~delay~increment) \times segment~reception~interval + + +The ``SegN`` field value identifies the total number of segments the Upper Transport PDU is segmented into. + +Four counters are related to SAR behavior: + +* Two unicast retransmissions counts (see `SAR Unicast Retransmissions Count`_ state and `SAR Unicast Retransmissions Without Progress Count`_ state) +* Multicast retransmissions count (see `SAR Multicast Retransmissions Count`_ state) +* Acknowledgment retransmissions count (see `SAR Acknowledgment Retransmissions Count`_ state) + +If the number of segments in the transmission is higher than the value of the `SAR Segments Threshold`_ state, Segment Acknowledgment messages are +retransmitted using the value of the `SAR Acknowledgment Retransmissions Count`_ state. + +.. _bt_mesh_sar_cfg_states: + +SAR states +========== + +There are two states defined related to segmentation and reassembly: + +* SAR Transmitter state +* SAR Receiver state + +The SAR Transmitter state is a composite state that controls the number and timing of transmissions of segmented messages. +It includes the following states: + +* SAR Segment Interval Step +* SAR Unicast Retransmissions Count +* SAR Unicast Retransmissions Without Progress Count +* SAR Unicast Retransmissions Interval Step +* SAR Unicast Retransmissions Interval Increment +* SAR Multicast Retransmissions Count +* SAR Multicast Retransmissions Interval Step + +The SAR Receiver state is a composite state that controls the number and timing of Segment Acknowledgment transmissions and the discarding of reassembly of a segmented message. +It includes the following states: + +* SAR Segments Threshold +* SAR Discard Timeout +* SAR Acknowledgment Delay Increment +* SAR Acknowledgment Retransmissions Count +* SAR Receiver Segment Interval Step + +SAR Segment Interval Step +------------------------- + +SAR Segment Interval Step state holds a value that controls the interval between transmissions of segments of a segmented message. +The interval is measured in milliseconds. + +Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP` Kconfig option to set the default value. +Segment transmission interval is then calculated using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP| + 1) \times 10~\text{ms} + + +SAR Unicast Retransmissions Count +--------------------------------- + +SAR Unicast Retransmissions Count holds a value that defines the maximum number of retransmissions of a segmented message to a unicast destination. +Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT` Kconfig option to set the default value for this state. + +SAR Unicast Retransmissions Without Progress Count +-------------------------------------------------- + +This state holds a value that defines the maximum number of retransmissions of a segmented message to a unicast address that will be sent if no acknowledgment +was received during the timeout, or if an acknowledgment with already confirmed segments was received. +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT` to set the maximum number of retransmissions. + +SAR Unicast Retransmissions Interval Step +----------------------------------------- + +The value of this state controls the interval step used for delaying the retransmissions of unacknowledged segments of a segmented message to a unicast address. +The interval step is measured in milliseconds. + +Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP` Kconfig option to set the default value. +This value is then used to calculate the interval step using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP| + 1) \times 25~\text{ms} + + +SAR Unicast Retransmissions Interval Increment +---------------------------------------------- + +SAR Unicast Retransmissions Interval Increment holds a value that controls the interval increment used for delaying the retransmissions of unacknowledged +segments of a segmented message to a unicast address. The increment is measured in milliseconds. + +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC` to set the default value. +The Kconfig option value is used to calculate the increment using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC| + 1) \times 25~\text{ms} + + +SAR Multicast Retransmissions Count +----------------------------------- + +The state holds a value that controls the total number of retransmissions of a segmented message to a multicast address. +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT` to set the total number of retransmissions. + +SAR Multicast Retransmissions Interval Step +------------------------------------------- + +This state holds a value that controls the interval between retransmissions of all segments in a segmented message to a multicast address. +The interval is measured in milliseconds. + +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT` to set the default value that is used to calculate the interval +using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT| + 1) \times 25~\text{ms} + + +SAR Discard Timeout +------------------- + +The value of this state defines the time in seconds that the lower transport layer waits after receiving segments of a segmented message +before discarding that segmented message. Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT` to set the +default value. The discard timeout will be calculated using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT| + 1) \times 5~\text{seconds} + + +SAR Acknowledgment Delay Increment +---------------------------------- + +This state holds a value that controls the delay increment of an interval used for delaying the transmission of an acknowledgment message after receiving a new segment. +The increment is measured in segments. + +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC` to set the default value. The increment value is calculated to be +:math:`\verb|CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC| + 1.5`. + +SAR Segments Threshold +---------------------- + +SAR Segments Threshold state holds a value that defines a threshold in number of segments of a segmented message for acknowledgment retransmissions. +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` to set the threshold. + +When the number of segments of a segmented message is above this threshold, the stack will additionally retransmit every acknowledgment message the +number of times given by the value of :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT`. + +SAR Acknowledgment Retransmissions Count +---------------------------------------- + +The SAR Acknowledgment Retransmissions Count state controls the number of retransmissions of Segment Acknowledgment messages sent by the lower transport layer. +It gives the total number of retranmissions of an acknowledgment message that the stack will additionally send when the size of segments in a +segmented message is above the :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` value. + +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT` to set the default value for this state. +The maximum number of transmissions of a Segment Acknowledgment message is :math:`\verb|CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT| + 1`. + +SAR Receiver Segment Interval Step +---------------------------------- + +The SAR Receiver Segment Interval Step defines the segments reception interval step used for delaying the transmission of an acknowledgment message after receiving a new segment. +The interval is measured in milliseconds. + +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP` to set the default value and calculate the interval using the following formula: + +.. math:: + + (\verb|CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP| + 1) \times 10~\text{ms} diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst new file mode 100644 index 00000000000..cc9dc8947a7 --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst @@ -0,0 +1,34 @@ +.. _bluetooth_mesh_sar_cfg_cli: + +SAR Configuration Client +######################## + +The SAR Configuration Client model is a foundation model defined by the Bluetooth mesh specification. +It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. + +The SAR Configuration Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, +and it supports the configuration of the lower transport layer behavior of a node that supports the :ref:`bluetooth_mesh_sar_cfg_srv` model. + +The model can send messages to query or change the states supported by the SAR Configuration Server (SAR Transmitter and SAR Receiver) using SAR Configuration messages. + +The SAR Transmitter procedure is used to determine and configure the SAR Transmitter state of a SAR Configuration Server. +Function calls :c:func:`bt_mesh_sar_cfg_cli_transmitter_get` and :c:func:`bt_mesh_sar_cfg_cli_transmitter_set` are used to get and set the SAR Transmitter state +of the Target node respectively. + +The SAR Receiver procedure is used to determine and configure the SAR Receiver state of a SAR Configuration Server. +Function calls :c:func:`bt_mesh_sar_cfg_cli_receiver_get` and :c:func:`bt_mesh_sar_cfg_cli_receiver_set` are used to get and set the SAR Receiver state of the +Target node respectively. + +For more information about the two states, see :ref:`bt_mesh_sar_cfg_states`. + +An element can send any SAR Configuration Client message at any time to query or change the states supported by the SAR Configuration Server model of a peer node. +The SAR Configuration Client model only accepts messages encrypted with the device key of the node supporting the SAR Configuration Server model. + +If present, the SAR Configuration Client model must only be instantiated on the primary element. + +API reference +************* + +.. doxygengroup:: bt_mesh_sar_cfg_cli + :project: Zephyr + :members: diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst new file mode 100644 index 00000000000..d1429bac8fd --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst @@ -0,0 +1,28 @@ +.. _bluetooth_mesh_sar_cfg_srv: + +SAR Configuration Server +######################## + +The SAR Configuration Server model is a foundation model defined by the Bluetooth mesh specification. +It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_SRV` configuration option. + +The SAR Configuration Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, +and it supports the configuration of the :ref:`segmentation and reassembly (SAR) ` behavior of a Bluetooth mesh node. +The model defines a set of states and messages for the SAR configuration. + +The SAR Configuration Server model defines two states, SAR Transmitter state and SAR Receiver state. +For more information about the two states, see :ref:`bt_mesh_sar_cfg_states`. + +The model also supports the SAR Transmitter and SAR Receiver get and set messages. + +The SAR Configuration Server model does not have an API of its own, but relies on a :ref:`bluetooth_mesh_sar_cfg_cli` to control it. +The SAR Configuration Server model only accepts messages encrypted with the node’s device key. + +If present, the SAR Configuration Server model must only be instantiated on the primary element. + +API reference +************* + +.. doxygengroup:: bt_mesh_sar_cfg_srv + :project: Zephyr + :members: From 01f144b20191bf9a0241f247a5a859ced86779e0 Mon Sep 17 00:00:00 2001 From: Mia Koen Date: Fri, 8 Sep 2023 14:40:22 +0200 Subject: [PATCH 0251/4498] doc: bluetooth: mesh: fixed spec links Corrected the profile specification v1.0.1 link to point to the spec directly and not to the general specification page. Added link to protocol specification v1.1. Signed-off-by: Mia Koen --- doc/connectivity/bluetooth/api/mesh.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 308fb5df953..6adb9fb6267 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -5,7 +5,10 @@ Bluetooth Mesh Profile The Bluetooth mesh profile adds secure wireless multi-hop communication for Bluetooth Low Energy. This module implements the -`Bluetooth Mesh Profile Specification v1.0.1 `_. +`Bluetooth Mesh Profile Specification v1.0.1 `_. + +Implementation of the draft `Bluetooth Mesh Protocol Specification v1.1 `_ +is in experimental state. Read more about Bluetooth mesh on the `Bluetooth SIG Website `_. From da3c9d267167ee40fddf88cc958e30d54d903426 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Tue, 12 Sep 2023 16:03:39 +0200 Subject: [PATCH 0252/4498] scripts: tests: twister: Testsuite tests update after 20b81a8 A commit breaking tests slipped past CI checks. This commit fixes broken tests in test_testsuite.py. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_testsuite.py | 109 +++++++++++++++++++++--- 1 file changed, 97 insertions(+), 12 deletions(-) diff --git a/scripts/tests/twister/test_testsuite.py b/scripts/tests/twister/test_testsuite.py index 3e12323d723..f72330ef897 100644 --- a/scripts/tests/twister/test_testsuite.py +++ b/scripts/tests/twister/test_testsuite.py @@ -20,6 +20,7 @@ from twisterlib.testsuite import ( _find_src_dir_path, _get_search_area_boundary, + find_c_files_in, scan_file, scan_testsuite_path, ScanPathResult, @@ -426,6 +427,88 @@ def test_get_search_area_boundary( TESTDATA_7 = [ + (True, [os.path.join('', 'home', 'user', 'dummy_path', 'dummy.c'), + os.path.join('', 'home', 'user', 'dummy_path', 'dummy.cpp')]), + (False, []) +] + +@pytest.mark.parametrize( + 'isdir, expected', + TESTDATA_7, + ids=['valid', 'not a directory'] +) +def test_find_c_files_in(isdir, expected): + old_dir = os.path.join('', 'home', 'user', 'dummy_base_dir') + new_path = os.path.join('', 'home', 'user', 'dummy_path') + cur_dir = old_dir + + def mock_chdir(path, *args, **kwargs): + nonlocal cur_dir + cur_dir = path + + # We simulate such a structure: + # + # ┣ dummy.c + # ┣ wrong_dummy.h + # ┗ dummy_dir + # ┣ dummy.cpp + # ┗ wrong_dummy.hpp + # + # ┗ wrong_dummy.c + new_path_base = ['dummy.c', 'wrong_dummy.h'] + new_path_subs = ['dummy.cpp', 'wrong_dummy.hpp'] + old_dir_base = ['wrong_dummy.c'] + + def format_tester(fmt): + formats = [ + {'name': 'subdirs', 'fmt': '**/*.'}, + {'name': 'base', 'fmt': '*.'} + ] + + for format in formats: + if fmt.startswith(format['fmt']): + return format['name'], fmt[len(format['fmt']):] + + raise ValueError('This test wasn\'t designed for those globs.' + ' Please fix the test before PR!') + + def mock_glob(fmt, *args, **kwargs): + from_where, extension = format_tester(fmt) + + if cur_dir == old_dir: + if from_where == 'subdirs': + return [] + elif from_where == 'base': + return list(filter(lambda fn: fn.endswith(extension), + old_dir_base)) + else: + return [] + if cur_dir == new_path: + if from_where == 'subdirs': + return list(filter(lambda fn: fn.endswith(extension), + new_path_subs)) + elif from_where == 'base': + return list(filter(lambda fn: fn.endswith(extension), + new_path_base)) + else: + return [] + + raise ValueError('This test wasn\'t designed for those dirs.' + 'Please fix the test before PR!') + + with mock.patch('os.path.isdir', return_value=isdir), \ + mock.patch('os.getcwd', return_value=cur_dir), \ + mock.patch('glob.glob', mock_glob), \ + mock.patch('os.chdir', side_effect=mock_chdir) as chdir_mock: + filenames = find_c_files_in(new_path) + + assert sorted(filenames) == sorted(expected) + + assert chdir_mock.call_args is None or \ + chdir_mock.call_args == mock.call(old_dir) + + +TESTDATA_8 = [ ( os.path.join('dummy', 'path'), ['testsuite_file_1', 'testsuite_file_2'], @@ -510,7 +593,7 @@ def test_get_search_area_boundary( @pytest.mark.parametrize( 'testsuite_path, testsuite_glob, src_dir_glob, sizes, scanpathresults,' \ ' expected_logs, expected_exception, expected', - TESTDATA_7, + TESTDATA_8, ids=[ 'valid', 'warning in src dir', @@ -528,13 +611,15 @@ def test_scan_testsuite_path( expected_exception, expected ): + src_dir_path = os.path.join(testsuite_path, 'src') + def mock_fsdp(path, *args, **kwargs): - return os.path.join(testsuite_path, 'src') + return src_dir_path - def mock_glob(path, *args, **kwargs): - if path == os.path.join(testsuite_path, 'src', '*.c*'): + def mock_find(path, *args, **kwargs): + if path == src_dir_path: return src_dir_glob - elif path == os.path.join(testsuite_path, '*.c*'): + elif path == testsuite_path: return testsuite_glob else: return [] @@ -552,7 +637,7 @@ def mock_stat(filename, *args, **kwargs): return result with mock.patch('twisterlib.testsuite._find_src_dir_path', mock_fsdp), \ - mock.patch('glob.glob', mock_glob), \ + mock.patch('twisterlib.testsuite.find_c_files_in', mock_find), \ mock.patch('twisterlib.testsuite.scan_file', mock_sf), \ mock.patch('os.stat', mock_stat), \ pytest.raises(type(expected_exception)) if \ @@ -578,7 +663,7 @@ def mock_stat(filename, *args, **kwargs): ) -TESTDATA_8 = [ +TESTDATA_9 = [ ('dummy/path', 'dummy/path/src', 'dummy/path/src'), ('dummy/path', 'dummy/src', 'dummy/src'), ('dummy/path', 'another/path', '') @@ -587,7 +672,7 @@ def mock_stat(filename, *args, **kwargs): @pytest.mark.parametrize( 'test_dir_path, isdir_path, expected', - TESTDATA_8, + TESTDATA_9, ids=['src here', 'src in parent', 'no path'] ) def test_find_src_dir_path(test_dir_path, isdir_path, expected): @@ -609,7 +694,7 @@ def mock_isdir(path, *args, **kwargs): ) -TESTDATA_9 = [ +TESTDATA_10 = [ ( ZEPHYR_BASE, ZEPHYR_BASE, @@ -653,7 +738,7 @@ def mock_isdir(path, *args, **kwargs): @pytest.mark.parametrize( 'testsuite_root, suite_path, name, data,' \ ' parsed_subcases, suite_names, expected', - TESTDATA_9, + TESTDATA_10, ids=['data', 'subcases', 'empty'] ) def test_testsuite_add_subcases( @@ -685,7 +770,7 @@ def test_testsuite_add_subcases( assert False -TESTDATA_10 = [ +TESTDATA_11 = [ # ( # ZEPHYR_BASE, # ZEPHYR_BASE, @@ -723,7 +808,7 @@ def test_testsuite_add_subcases( @pytest.mark.parametrize( 'testsuite_root, suite_path, name, data, expected', - TESTDATA_10, + TESTDATA_11, ids=[ # 'no harness', 'proper harness', From 77998b21711b4f6131d7d78113d7e7acfebfe061 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 11 Jul 2023 23:15:11 +0000 Subject: [PATCH 0253/4498] tests: drivers: adc: support sampling more than 2 channels with test Support sampling more than 2 channels using the ADC API test. This requires updates to the repeated samplings test, which samples using 2 channels even when more channels are defined by the ADC test overlay. Signed-off-by: Daniel DeGrasse --- .../boards/lpcxpresso55s69_cpu0.overlay | 32 ++++++++++++++++--- tests/drivers/adc/adc_api/src/test_adc.c | 4 +-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/lpcxpresso55s69_cpu0.overlay b/tests/drivers/adc/adc_api/boards/lpcxpresso55s69_cpu0.overlay index efddec22a21..386e405b7bb 100644 --- a/tests/drivers/adc/adc_api/boards/lpcxpresso55s69_cpu0.overlay +++ b/tests/drivers/adc/adc_api/boards/lpcxpresso55s69_cpu0.overlay @@ -8,7 +8,7 @@ / { zephyr,user { - io-channels = <&adc0 0>, <&adc0 1>; + io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>; }; }; @@ -16,21 +16,45 @@ #address-cells = <1>; #size-cells = <0>; + /* + * Channel 0 is used in single ended mode, with 12 bit resolution + * CH0A is routed to P19 pin 4 + */ channel@0 { reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <3300>; zephyr,acquisition-time = ; - zephyr,resolution = <12>; - zephyr,input-positive = ; + zephyr,resolution = <13>; + zephyr,input-positive = ; }; + /* + * Channel 1 is used in single ended mode, with 16 bit resolution + * CH4A is routed to P17 pin 19 + */ channel@1 { reg = <1>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = ; + }; + + /* + * Channel 2 is used in single ended mode, with 12 bit resolution + * CH4B is routed to P18 pin 1 + */ + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <3300>; zephyr,acquisition-time = ; zephyr,resolution = <12>; - zephyr,input-positive = ; + zephyr,input-positive = ; }; }; diff --git a/tests/drivers/adc/adc_api/src/test_adc.c b/tests/drivers/adc/adc_api/src/test_adc.c index de21f5c434f..089d9c87a14 100644 --- a/tests/drivers/adc/adc_api/src/test_adc.c +++ b/tests/drivers/adc/adc_api/src/test_adc.c @@ -261,12 +261,12 @@ static enum adc_action repeated_samplings_callback(const struct device *dev, ++m_samplings_done; TC_PRINT("%s: done %d\n", __func__, m_samplings_done); if (m_samplings_done == 1U) { - check_samples(adc_channels_count); + check_samples(MIN(adc_channels_count, 2)); /* After first sampling continue normally. */ return ADC_ACTION_CONTINUE; } else { - check_samples(2 * adc_channels_count); + check_samples(2 * MIN(adc_channels_count, 2)); /* * The second sampling is repeated 9 times (the samples are From 8035ec69fa053d29134701bf2ec5d88e8185d1fa Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Sun, 13 Aug 2023 14:04:33 -0600 Subject: [PATCH 0254/4498] emul: Add syscall support for fuel gauge emulators In order to ease user thread testing with fuel gauges, enable syscalls for the fuel gauge emulator backend API. Signed-off-by: Aaron Massey --- drivers/fuel_gauge/CMakeLists.txt | 5 ++++ .../emul_fuel_gauge_syscall_handlers.c | 25 +++++++++++++++++++ include/zephyr/drivers/emul_fuel_gauge.h | 10 +++++--- .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 2 +- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c diff --git a/drivers/fuel_gauge/CMakeLists.txt b/drivers/fuel_gauge/CMakeLists.txt index bf7d5e4918e..6a95c89ea46 100644 --- a/drivers/fuel_gauge/CMakeLists.txt +++ b/drivers/fuel_gauge/CMakeLists.txt @@ -6,3 +6,8 @@ add_subdirectory_ifdef(CONFIG_SBS_GAUGE_NEW_API sbs_gauge) add_subdirectory_ifdef(CONFIG_MAX17048 max17048) zephyr_library_sources_ifdef(CONFIG_USERSPACE fuel_gauge_syscall_handlers.c) + +if (CONFIG_EMUL AND CONFIG_USERSPACE) + zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/emul_fuel_gauge.h) + zephyr_library_sources(emul_fuel_gauge_syscall_handlers.c) +endif() diff --git a/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c new file mode 100644 index 00000000000..a6b8ce6ee02 --- /dev/null +++ b/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c @@ -0,0 +1,25 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Emulator syscalls just need to exist as stubs as these are only called by tests. */ + +static inline int z_vrfy_emul_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff) +{ + return z_impl_emul_fuel_gauge_is_battery_cutoff(target, cutoff); +} + +#include + +static inline int z_vrfy_emul_fuel_gauge_set_battery_charging(const struct emul *target, + uint32_t uV, int uA) +{ + return z_impl_emul_fuel_gauge_set_battery_charging(target, uV, uA); +} + +#include diff --git a/include/zephyr/drivers/emul_fuel_gauge.h b/include/zephyr/drivers/emul_fuel_gauge.h index 63b85d227c1..5abd7ec4f6f 100644 --- a/include/zephyr/drivers/emul_fuel_gauge.h +++ b/include/zephyr/drivers/emul_fuel_gauge.h @@ -54,8 +54,9 @@ __subsystem struct fuel_gauge_emul_driver_api { * @retval 0 If successful. * @retval -EINVAL if mV or mA are 0. */ -static inline int emul_fuel_gauge_set_battery_charging(const struct emul *target, uint32_t uV, - int uA) +__syscall int emul_fuel_gauge_set_battery_charging(const struct emul *target, uint32_t uV, int uA); +static inline int z_impl_emul_fuel_gauge_set_battery_charging(const struct emul *target, + uint32_t uV, int uA) { const struct fuel_gauge_emul_driver_api *backend_api = (const struct fuel_gauge_emul_driver_api *)target->backend_api; @@ -76,7 +77,8 @@ static inline int emul_fuel_gauge_set_battery_charging(const struct emul *target * @retval 0 If successful. * @retval -ENOTSUP if not supported by emulator. */ -static inline int emul_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff) +__syscall int emul_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff); +static inline int z_impl_emul_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff) { const struct fuel_gauge_emul_driver_api *backend_api = (const struct fuel_gauge_emul_driver_api *)target->backend_api; @@ -91,6 +93,8 @@ static inline int emul_fuel_gauge_is_battery_cutoff(const struct emul *target, b } #endif +#include + /** * @} */ diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 2e5cea19609..9b812e64310 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -344,7 +344,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) zassert_ok(ret); } -ZTEST_F(sbs_gauge_new_api, test_charging_5v_3a) +ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) { /* Validate what props are supported by the driver */ uint32_t expected_uV = 5000 * 1000; From c6fd21c5de6af90add3162747a0a63efa771dff1 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Tue, 22 Aug 2023 13:32:35 -0600 Subject: [PATCH 0255/4498] emul: Remove unused ZTEST_DMEM in sbs emulator The redefinition of ZTEST_DMEM in the SBS emulator is unused. We ought to remove it as it's dead code. Remove the unused #define ZTEST_DMEM. Signed-off-by: Aaron Massey --- drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c index 64668d54307..160552edeff 100644 --- a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c @@ -342,9 +342,6 @@ static void emul_sbs_gauge_reset_rule_after(const struct ztest_unit_test *test, DT_INST_FOREACH_STATUS_OKAY(SBS_GAUGE_EMUL_RESET_RULE_BEFORE) } ZTEST_RULE(emul_sbs_gauge_reset, NULL, emul_sbs_gauge_reset_rule_after); -#else /* !CONFIG_ZTEST */ -/* Stub ZTEST_DMEM in case emulator is not used in a testing environment. */ -#define ZTEST_DMEM #endif /* CONFIG_ZTEST */ /** From 1e7b540aa84a79b202b70b5dc93f01ebda666217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 11 Sep 2023 09:53:06 +0200 Subject: [PATCH 0256/4498] toolchain: Add flag indicating zero length array support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add flag which indicates if a toolchain supports ZLA (Zero Length Arrays). It is a GCCC extension inherited by clang as well. Signed-off-by: Krzysztof Chruściński --- include/zephyr/toolchain.h | 8 ++++++++ include/zephyr/toolchain/gcc.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/include/zephyr/toolchain.h b/include/zephyr/toolchain.h index e46c19689da..27e4a46956c 100644 --- a/include/zephyr/toolchain.h +++ b/include/zephyr/toolchain.h @@ -115,6 +115,14 @@ #define TOOLCHAIN_HAS_C_AUTO_TYPE 0 #endif +/** + * @def TOOLCHAIN_HAS_ZLA + * @brief Indicate if toolchain supports Zero Length Arrays. + */ +#ifndef TOOLCHAIN_HAS_ZLA +#define TOOLCHAIN_HAS_ZLA 0 +#endif + /** * @def TOOLCHAIN_IGNORE_WSHADOW_BEGIN * @brief Begin of block to ignore -Wshadow. diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index 4e30158a341..04c0654888a 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -30,6 +30,8 @@ #define TOOLCHAIN_HAS_C_AUTO_TYPE 1 #endif +#define TOOLCHAIN_HAS_ZLA 1 + /* * Older versions of GCC do not define __BYTE_ORDER__, so it must be manually * detected and defined using arch-specific definitions. From 51914443164da8f9a9fab3be1a0e31f5f6c7fab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 1 Sep 2023 14:37:44 +0200 Subject: [PATCH 0257/4498] logging: Minor improvement in instance logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using instance logging (e.g. LOG_INST_INF) first argument is a pointer to the logging object associated with an instance. It is not used if logging is disabled and that can generate 'unused variable' warning when logging is disabled. Previously logging object was not created when logging was disabled That was done to save memory but because of that object could not be referenced when logging was disabled. Better approach is to create empty array instead of a logging object. It does not increase memory usage but can be referenced and potential compilation warning is suppressed. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_core.h | 6 ++++-- include/zephyr/logging/log_instance.h | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/zephyr/logging/log_core.h b/include/zephyr/logging/log_core.h index 869dcc8643e..94fb92325f7 100644 --- a/include/zephyr/logging/log_core.h +++ b/include/zephyr/logging/log_core.h @@ -251,13 +251,15 @@ static inline char z_log_minimal_level_to_char(int level) #define Z_LOG(_level, ...) \ Z_LOG2(_level, 0, __log_current_const_data, __log_current_dynamic_data, __VA_ARGS__) -#define Z_LOG_INSTANCE(_level, _inst, ...) \ +#define Z_LOG_INSTANCE(_level, _inst, ...) do { \ + (void)_inst; \ Z_LOG2(_level, 1, \ COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, (NULL), (Z_LOG_INST(_inst))), \ (struct log_source_dynamic_data *)COND_CODE_1( \ CONFIG_LOG_RUNTIME_FILTERING, \ (Z_LOG_INST(_inst)), (NULL)), \ - __VA_ARGS__) + __VA_ARGS__); \ +} while (0) /*****************************************************************************/ /****************** Macros for hexdump logging *******************************/ diff --git a/include/zephyr/logging/log_instance.h b/include/zephyr/logging/log_instance.h index 8eca2b46a71..dbaf72f3b06 100644 --- a/include/zephyr/logging/log_instance.h +++ b/include/zephyr/logging/log_instance.h @@ -137,11 +137,16 @@ struct log_source_dynamic_data { /** * @brief Declare a logger instance pointer in the module structure. * + * If logging is disabled then element in the structure is still declared to avoid + * compilation issues. If compiler supports zero length arrays then it is utilized + * to not use any space, else a byte array is created. + * * @param _name Name of a structure element that will have a pointer to logging * instance object. */ #define LOG_INSTANCE_PTR_DECLARE(_name) \ - IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name)) + COND_CODE_1(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name), \ + (int _name[TOOLCHAIN_HAS_ZLA ? 0 : 1])) #define Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name) \ STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \ From 8aa6531aede19a0e4f3871f66ee518b0b5cc76b9 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Tue, 5 Sep 2023 17:23:31 +0200 Subject: [PATCH 0258/4498] drivers: rtc: stm32: add calibration feature This adds the set_calibration and get_calibration API functions to the STM32 RTC driver Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 94 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 7380fb102fa..7ee98a5e053 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 Prevas A/S + * Copyright (c) 2023 Syslinbit * * SPDX-License-Identifier: Apache-2.0 * @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +32,29 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); /* struct tm start: 1st, Jan, 1900 */ #define TM_TO_RTC_OFFSET 100 +/* Convert part per billion calibration value to a number of clock pulses added or removed each + * 2^20 clock cycles so it is suitable for the CALR register fields + * + * nb_pulses = ppb * 2^20 / 10^9 = ppb * 2^11 / 5^9 = ppb * 2048 / 1953125 + */ +#define PPB_TO_NB_PULSES(ppb) DIV_ROUND_CLOSEST((ppb) * 2048, 1953125) + +/* Convert CALR register value (number of clock pulses added or removed each 2^20 clock cycles) + * to part ber billion calibration value + * + * ppb = nb_pulses * 10^9 / 2^20 = nb_pulses * 5^9 / 2^11 = nb_pulses * 1953125 / 2048 + */ +#define NB_PULSES_TO_PPB(pulses) DIV_ROUND_CLOSEST((pulses) * 1953125, 2048) + +/* CALP field can only be 512 or 0 as in reality CALP is a single bit field representing 512 pulses + * added every 2^20 clock cycles + */ +#define MAX_CALP (512) +#define MAX_CALM (511) + +#define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP) +#define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM) + struct rtc_stm32_config { LL_RTC_InitTypeDef ll_rtc_config; const struct stm32_pclken *pclken; @@ -154,11 +179,80 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr return 0; } +#ifdef CONFIG_RTC_CALIBRATION +static int rtc_stm32_set_calibration(const struct device *dev, int32_t calibration) +{ + ARG_UNUSED(dev); + + /* Note : calibration is considered here to be ppb value to apply + * on clock period (not frequency) but with an opposite sign + */ + + if ((calibration > MAX_PPB) || (calibration < MIN_PPB)) { + /* out of supported range */ + return -EINVAL; + } + + int32_t nb_pulses = PPB_TO_NB_PULSES(calibration); + + /* we tested calibration against supported range + * so theoretically nb_pulses is also within range + */ + __ASSERT_NO_MSG(nb_pulses <= MAX_CALP); + __ASSERT_NO_MSG(nb_pulses >= -MAX_CALM); + + uint32_t calp, calm; + + if (nb_pulses > 0) { + calp = LL_RTC_CALIB_INSERTPULSE_SET; + calm = MAX_CALP - nb_pulses; + } else { + calp = LL_RTC_CALIB_INSERTPULSE_NONE; + calm = -nb_pulses; + } + + /* wait for recalibration to be ok if a previous recalibration occurred */ + if (!WAIT_FOR(LL_RTC_IsActiveFlag_RECALP(RTC) == 0, 100000, k_msleep(1))) { + return -EIO; + } + + LL_RTC_DisableWriteProtection(RTC); + + MODIFY_REG(RTC->CALR, RTC_CALR_CALP | RTC_CALR_CALM, calp | calm); + + LL_RTC_EnableWriteProtection(RTC); + + return 0; +} + +static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibration) +{ + ARG_UNUSED(dev); + + uint32_t calp_enabled = LL_RTC_CAL_IsPulseInserted(RTC); + uint32_t calm = LL_RTC_CAL_GetMinus(RTC); + + int32_t nb_pulses = -((int32_t) calm); + + if (calp_enabled) { + nb_pulses += MAX_CALP; + } + + *calibration = NB_PULSES_TO_PPB(nb_pulses); + + return 0; +} +#endif /* CONFIG_RTC_CALIBRATION */ + struct rtc_driver_api rtc_stm32_driver_api = { .set_time = rtc_stm32_set_time, .get_time = rtc_stm32_get_time, /* RTC_ALARM not supported */ /* RTC_UPDATE not supported */ +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rtc_stm32_set_calibration, + .get_calibration = rtc_stm32_get_calibration, +#endif /* CONFIG_RTC_CALIBRATION */ }; #define RTC_STM32_DEV_CFG(n) \ From 29fa7189411566fb39a64c5c8e0c447e5036cd64 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Tue, 5 Sep 2023 18:17:07 +0200 Subject: [PATCH 0259/4498] drivers: rtc: stm32: fix wrong nanosecond value SSR register does not contain direct nanosecond value. This adds the necessary conversion. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 7ee98a5e053..00c54c61b8f 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -156,13 +156,15 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr) { - ARG_UNUSED(dev); + const struct rtc_stm32_config *cfg = dev->config; + uint32_t sync_prescaler = cfg->ll_rtc_config.SynchPrescaler; - uint32_t rtc_date, rtc_time; + uint32_t rtc_date, rtc_time, rtc_subsecond; - /* Read time and date registers */ - rtc_time = LL_RTC_TIME_Get(RTC); - rtc_date = LL_RTC_DATE_Get(RTC); + /* Read subsecond, time and date registers */ + rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); + rtc_time = LL_RTC_TIME_Get(RTC); + rtc_date = LL_RTC_DATE_Get(RTC); timeptr->tm_year = TM_TO_RTC_OFFSET + __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date)); /* tm_mon allowed values are 0-11 */ @@ -174,7 +176,9 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr timeptr->tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time)); timeptr->tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time)); - timeptr->tm_nsec = LL_RTC_TIME_GetSubSecond(RTC); + uint64_t temp = ((uint64_t)(sync_prescaler - rtc_subsecond)) * 1000000000L; + + timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, sync_prescaler + 1); return 0; } From 16de401e79600611bf23629954fed25eba2d6d20 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Fri, 8 Sep 2023 18:14:12 +0200 Subject: [PATCH 0260/4498] drivers: rtc: stm32: fix day of the week conversion The conversion used was working but not consistent with values given by reference manuals. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 00c54c61b8f..d623dc8b776 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -141,7 +141,14 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LL_RTC_DATE_SetMonth(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mon + 1)); LL_RTC_DATE_SetDay(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mday)); - LL_RTC_DATE_SetWeekDay(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_wday) + 1); + if (timeptr->tm_wday == 0) { + /* sunday (tm_wday = 0) is not represented by the same value in hardware */ + LL_RTC_DATE_SetWeekDay(RTC, LL_RTC_WEEKDAY_SUNDAY); + } else { + /* all the other values are consistent with what is expected by hardware */ + LL_RTC_DATE_SetWeekDay(RTC, timeptr->tm_wday); + } + LL_RTC_TIME_SetHour(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_hour)); LL_RTC_TIME_SetMinute(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_min)); @@ -170,7 +177,16 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr /* tm_mon allowed values are 0-11 */ timeptr->tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1; timeptr->tm_mday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_DAY(rtc_date)); - timeptr->tm_wday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_WEEKDAY(rtc_date)) - 1; + + int hw_wday = __LL_RTC_GET_WEEKDAY(rtc_date); + + if (hw_wday == LL_RTC_WEEKDAY_SUNDAY) { + /* LL_RTC_WEEKDAY_SUNDAY = 7 but a 0 is expected in tm_wday for sunday */ + timeptr->tm_wday = 0; + } else { + /* all other values are consistent between hardware and rtc_time structure */ + timeptr->tm_wday = hw_wday; + } timeptr->tm_hour = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(rtc_time)); timeptr->tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time)); From f0b3e4e8501bcb6f9564d5f4071e1eda9dd5cf84 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 12:09:52 +0200 Subject: [PATCH 0261/4498] drivers: rtc: stm32: check if year is supported by RTC RTC does not support year before 2000 while tm/rtc_time structure reference year is 1900 Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index d623dc8b776..f8af22d00c5 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -27,10 +27,12 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); -/* Convert calendar start time */ /* RTC start time: 1st, Jan, 2000 */ -/* struct tm start: 1st, Jan, 1900 */ -#define TM_TO_RTC_OFFSET 100 +#define RTC_YEAR_REF 2000 +/* struct tm start time: 1st, Jan, 1900 */ +#define TM_YEAR_REF 1900 +/* conversion offset between RTC and tm structure */ +#define TM_TO_RTC_OFFSET (RTC_YEAR_REF - TM_YEAR_REF) /* Convert part per billion calibration value to a number of clock pulses added or removed each * 2^20 clock cycles so it is suitable for the CALR register fields @@ -129,6 +131,13 @@ static const struct rtc_stm32_config rtc_config = { static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr) { + uint32_t real_year = timeptr->tm_year + TM_YEAR_REF; + + if (real_year < RTC_YEAR_REF) { + /* RTC does not support years before 2000 */ + return -EINVAL; + } + LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); @@ -137,7 +146,7 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t while (!LL_RTC_IsActiveFlag_INIT(RTC)) { }; - LL_RTC_DATE_SetYear(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_year - TM_TO_RTC_OFFSET)); + LL_RTC_DATE_SetYear(RTC, __LL_RTC_CONVERT_BIN2BCD(real_year - RTC_YEAR_REF)); LL_RTC_DATE_SetMonth(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mon + 1)); LL_RTC_DATE_SetDay(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mday)); From 4eac3db1b97dd3b1665fec6fc6432d983701fd98 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 12:18:57 +0200 Subject: [PATCH 0262/4498] drivers: rtc: stm32: check if tm_wday is set tm/rtc_time structure allow for tm_wday to be set to -1 if unknown but RTC is expecting it Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index f8af22d00c5..c95c331ee97 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -138,6 +138,11 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t return -EINVAL; } + if (timeptr->tm_wday == -1) { + /* day of the week is expected */ + return -EINVAL; + } + LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); From 9e202e57e9d2b4b3e806426353d6e49f9e1a4c3d Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 16:49:11 +0200 Subject: [PATCH 0263/4498] drivers: rtc: stm32: avoid potential erroneous readings As shadow registers bypass is enabled, an erroneous reading may occur at each day or second increment. This commit fixes this issue. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index c95c331ee97..fccbe30f1ce 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -182,10 +182,19 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr uint32_t rtc_date, rtc_time, rtc_subsecond; - /* Read subsecond, time and date registers */ - rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); - rtc_time = LL_RTC_TIME_Get(RTC); - rtc_date = LL_RTC_DATE_Get(RTC); + do { + /* read date, time and subseconds and relaunch if a day increment occurred + * while doing so as it will result in an erroneous result otherwise + */ + rtc_date = LL_RTC_DATE_Get(RTC); + do { + /* read time and subseconds and relaunch if a second increment occurred + * while doing so as it will result in an erroneous result otherwise + */ + rtc_time = LL_RTC_TIME_Get(RTC); + rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); + } while (rtc_time != LL_RTC_TIME_Get(RTC)); + } while (rtc_date != LL_RTC_DATE_Get(RTC)); timeptr->tm_year = TM_TO_RTC_OFFSET + __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date)); /* tm_mon allowed values are 0-11 */ From cdab80eecea25859159e7b94ac972ae0320f8ecc Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 13:45:24 +0200 Subject: [PATCH 0264/4498] drivers: rtc: stm32: avoid reset induced time drift Calling LL_RTC_Init causes the RTC to stop while being configured thus inducing time drift. This commit avoids doing it at each reset if the RTC is already properly configured. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index fccbe30f1ce..feb7ff387a2 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -66,11 +66,35 @@ struct rtc_stm32_data { /* Currently empty */ }; +static int rtc_stm32_configure(const struct device *dev) +{ + const struct rtc_stm32_config *cfg = dev->config; + + uint32_t hour_format = LL_RTC_GetHourFormat(RTC); + uint32_t sync_prescaler = LL_RTC_GetSynchPrescaler(RTC); + uint32_t async_prescaler = LL_RTC_GetAsynchPrescaler(RTC); + + /* configuration process requires to stop the RTC counter so do it + * only if needed to avoid inducing time drift at each reset + */ + if ((hour_format != cfg->ll_rtc_config.HourFormat) || + (sync_prescaler != cfg->ll_rtc_config.SynchPrescaler) || + (async_prescaler != cfg->ll_rtc_config.AsynchPrescaler)) { + if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)&cfg->ll_rtc_config)) != SUCCESS) { + return -EIO; + } + } + + return 0; +} + static int rtc_stm32_init(const struct device *dev) { const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); const struct rtc_stm32_config *cfg = dev->config; + int err = 0; + if (!device_is_ready(clk)) { LOG_ERR("clock control device not ready"); return -ENODEV; @@ -98,8 +122,9 @@ static int rtc_stm32_init(const struct device *dev) z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); - if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)&cfg->ll_rtc_config)) != SUCCESS) { - return -EIO; + err = rtc_stm32_configure(dev); + if (err) { + return err; } #ifdef RTC_CR_BYPSHAD @@ -108,7 +133,7 @@ static int rtc_stm32_init(const struct device *dev) LL_RTC_EnableWriteProtection(RTC); #endif /* RTC_CR_BYPSHAD */ - return 0; + return err; } static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); From a4f5f87e298d65292ec00e7d09d71abf95bc84e9 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 17:23:56 +0200 Subject: [PATCH 0265/4498] drivers: rtc: stm32: avoid infinite blocking loop Use the less CPU intensive and timeout capable WAIT_FOR zephyr provided macro Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index feb7ff387a2..12dc6784e39 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -57,6 +57,9 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); #define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP) #define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM) +/* Timeout in microseconds used to wait for flags */ +#define RTC_TIMEOUT 1000000 + struct rtc_stm32_config { LL_RTC_InitTypeDef ll_rtc_config; const struct stm32_pclken *pclken; @@ -66,6 +69,24 @@ struct rtc_stm32_data { /* Currently empty */ }; +static int rtc_stm32_enter_initialization_mode(void) +{ + LL_RTC_EnableInitMode(RTC); + + bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); + + if (!success) { + return -EIO; + } + + return 0; +} + +static inline void rtc_stm32_leave_initialization_mode(void) +{ + LL_RTC_DisableInitMode(RTC); +} + static int rtc_stm32_configure(const struct device *dev) { const struct rtc_stm32_config *cfg = dev->config; @@ -158,6 +179,8 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t { uint32_t real_year = timeptr->tm_year + TM_YEAR_REF; + int err = 0; + if (real_year < RTC_YEAR_REF) { /* RTC does not support years before 2000 */ return -EINVAL; @@ -171,10 +194,10 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); - LL_RTC_EnableInitMode(RTC); - - while (!LL_RTC_IsActiveFlag_INIT(RTC)) { - }; + err = rtc_stm32_enter_initialization_mode(); + if (err) { + return err; + } LL_RTC_DATE_SetYear(RTC, __LL_RTC_CONVERT_BIN2BCD(real_year - RTC_YEAR_REF)); LL_RTC_DATE_SetMonth(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mon + 1)); @@ -193,11 +216,11 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LL_RTC_TIME_SetMinute(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_min)); LL_RTC_TIME_SetSecond(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_sec)); - LL_RTC_DisableInitMode(RTC); + rtc_stm32_leave_initialization_mode(); LL_RTC_EnableWriteProtection(RTC); - return 0; + return err; } static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr) From e46aff590266ee6d24b946308353eefd1b573146 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 17:47:57 +0200 Subject: [PATCH 0266/4498] drivers: rtc: stm32: avoid using LL_RTC_Init LL_RTC_Init() internally uses LL_RTC_EnterInitMode() wich uses a blocking while loop. This rewrite uses the less CPU time wasteful local rtc_stm32_enter_initialization_mode() instead. As a side effect LL_RTC_InitTypeDef in rtc_stm32_config is not needed anymore. Signed-off-by: Johan Lafon --- drivers/rtc/Kconfig.stm32 | 1 - drivers/rtc/rtc_ll_stm32.c | 59 ++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/rtc/Kconfig.stm32 b/drivers/rtc/Kconfig.stm32 index 1cdbe99ca0b..6842b68a84b 100644 --- a/drivers/rtc/Kconfig.stm32 +++ b/drivers/rtc/Kconfig.stm32 @@ -5,7 +5,6 @@ config RTC_STM32 bool "STM32 RTC driver" default y if !COUNTER depends on DT_HAS_ST_STM32_RTC_ENABLED && !SOC_SERIES_STM32F1X - select USE_STM32_LL_RTC select USE_STM32_LL_PWR select USE_STM32_LL_RCC help diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 12dc6784e39..d8a2559efb9 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -61,7 +61,8 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); #define RTC_TIMEOUT 1000000 struct rtc_stm32_config { - LL_RTC_InitTypeDef ll_rtc_config; + uint32_t async_prescaler; + uint32_t sync_prescaler; const struct stm32_pclken *pclken; }; @@ -91,22 +92,37 @@ static int rtc_stm32_configure(const struct device *dev) { const struct rtc_stm32_config *cfg = dev->config; + int err = 0; + uint32_t hour_format = LL_RTC_GetHourFormat(RTC); uint32_t sync_prescaler = LL_RTC_GetSynchPrescaler(RTC); uint32_t async_prescaler = LL_RTC_GetAsynchPrescaler(RTC); + LL_RTC_DisableWriteProtection(RTC); + /* configuration process requires to stop the RTC counter so do it * only if needed to avoid inducing time drift at each reset */ - if ((hour_format != cfg->ll_rtc_config.HourFormat) || - (sync_prescaler != cfg->ll_rtc_config.SynchPrescaler) || - (async_prescaler != cfg->ll_rtc_config.AsynchPrescaler)) { - if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)&cfg->ll_rtc_config)) != SUCCESS) { - return -EIO; + if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) || + (sync_prescaler != cfg->sync_prescaler) || + (async_prescaler != cfg->async_prescaler)) { + err = rtc_stm32_enter_initialization_mode(); + if (err == 0) { + LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR); + LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler); + LL_RTC_SetAsynchPrescaler(RTC, cfg->async_prescaler); } + + rtc_stm32_leave_initialization_mode(); } - return 0; +#ifdef RTC_CR_BYPSHAD + LL_RTC_EnableShadowRegBypass(RTC); +#endif /* RTC_CR_BYPSHAD */ + + LL_RTC_EnableWriteProtection(RTC); + + return err; } static int rtc_stm32_init(const struct device *dev) @@ -144,15 +160,6 @@ static int rtc_stm32_init(const struct device *dev) z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); err = rtc_stm32_configure(dev); - if (err) { - return err; - } - -#ifdef RTC_CR_BYPSHAD - LL_RTC_DisableWriteProtection(RTC); - LL_RTC_EnableShadowRegBypass(RTC); - LL_RTC_EnableWriteProtection(RTC); -#endif /* RTC_CR_BYPSHAD */ return err; } @@ -160,18 +167,15 @@ static int rtc_stm32_init(const struct device *dev) static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); static const struct rtc_stm32_config rtc_config = { - .ll_rtc_config = { - .HourFormat = LL_RTC_HOURFORMAT_24HOUR, #if DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSI - /* prescaler values for LSI @ 32 KHz */ - .AsynchPrescaler = 0x7F, - .SynchPrescaler = 0x00F9, + /* prescaler values for LSI @ 32 KHz */ + .async_prescaler = 0x7F, + .sync_prescaler = 0x00F9, #else /* DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSE */ - /* prescaler values for LSE @ 32768 Hz */ - .AsynchPrescaler = 0x7F, - .SynchPrescaler = 0x00FF, + /* prescaler values for LSE @ 32768 Hz */ + .async_prescaler = 0x7F, + .sync_prescaler = 0x00FF, #endif - }, .pclken = rtc_clk, }; @@ -226,7 +230,6 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr) { const struct rtc_stm32_config *cfg = dev->config; - uint32_t sync_prescaler = cfg->ll_rtc_config.SynchPrescaler; uint32_t rtc_date, rtc_time, rtc_subsecond; @@ -263,9 +266,9 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr timeptr->tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time)); timeptr->tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time)); - uint64_t temp = ((uint64_t)(sync_prescaler - rtc_subsecond)) * 1000000000L; + uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L; - timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, sync_prescaler + 1); + timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, cfg->sync_prescaler + 1); return 0; } From a8b7076099478b6b8e4db72fa86fb0ad1edbaf72 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 18:50:45 +0200 Subject: [PATCH 0267/4498] drivers: rtc: stm32: ensure thread safe operations This adds mutex a lock in rtc_stm32_set_time and rtc_stm32_get_time to ensure consistent data reading. Also performs register reading in a single operation in rtc_stm32_get_calibration for the same reason. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index d8a2559efb9..65ef2c18e57 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -67,7 +67,7 @@ struct rtc_stm32_config { }; struct rtc_stm32_data { - /* Currently empty */ + struct k_mutex lock; }; static int rtc_stm32_enter_initialization_mode(void) @@ -129,6 +129,7 @@ static int rtc_stm32_init(const struct device *dev) { const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); const struct rtc_stm32_config *cfg = dev->config; + struct rtc_stm32_data *data = dev->data; int err = 0; @@ -143,6 +144,8 @@ static int rtc_stm32_init(const struct device *dev) return -EIO; } + k_mutex_init(&data->lock); + /* Enable Backup access */ z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP) @@ -181,6 +184,8 @@ static const struct rtc_stm32_config rtc_config = { static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr) { + struct rtc_stm32_data *data = dev->data; + uint32_t real_year = timeptr->tm_year + TM_YEAR_REF; int err = 0; @@ -195,11 +200,17 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t return -EINVAL; } + err = k_mutex_lock(&data->lock, K_NO_WAIT); + if (err) { + return err; + } + LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); err = rtc_stm32_enter_initialization_mode(); if (err) { + k_mutex_unlock(&data->lock); return err; } @@ -224,15 +235,24 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LL_RTC_EnableWriteProtection(RTC); + k_mutex_unlock(&data->lock); + return err; } static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr) { const struct rtc_stm32_config *cfg = dev->config; + struct rtc_stm32_data *data = dev->data; uint32_t rtc_date, rtc_time, rtc_subsecond; + int err = k_mutex_lock(&data->lock, K_NO_WAIT); + + if (err) { + return err; + } + do { /* read date, time and subseconds and relaunch if a day increment occurred * while doing so as it will result in an erroneous result otherwise @@ -247,6 +267,8 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr } while (rtc_time != LL_RTC_TIME_Get(RTC)); } while (rtc_date != LL_RTC_DATE_Get(RTC)); + k_mutex_unlock(&data->lock); + timeptr->tm_year = TM_TO_RTC_OFFSET + __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date)); /* tm_mon allowed values are 0-11 */ timeptr->tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1; @@ -323,8 +345,10 @@ static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibrat { ARG_UNUSED(dev); - uint32_t calp_enabled = LL_RTC_CAL_IsPulseInserted(RTC); - uint32_t calm = LL_RTC_CAL_GetMinus(RTC); + uint32_t calr = sys_read32(&RTC->CALR); + + bool calp_enabled = READ_BIT(calr, RTC_CALR_CALP); + uint32_t calm = READ_BIT(calr, RTC_CALR_CALM); int32_t nb_pulses = -((int32_t) calm); From 961c465efb199029299a6ef5d2fe0b1d655eaca1 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 19:52:35 +0200 Subject: [PATCH 0268/4498] drivers: rtc: stm32: use Zephyr BCD<->bin conversion functions This replaces the verbose LL_RTC_CONVERT_BCD2BIN and LL_RTC_CONVERT_BIN2BCD by the bcd2bin and bin2bcd Zephyr provided equivalent Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 65ef2c18e57..ad4dc4b2d75 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -31,8 +31,6 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); #define RTC_YEAR_REF 2000 /* struct tm start time: 1st, Jan, 1900 */ #define TM_YEAR_REF 1900 -/* conversion offset between RTC and tm structure */ -#define TM_TO_RTC_OFFSET (RTC_YEAR_REF - TM_YEAR_REF) /* Convert part per billion calibration value to a number of clock pulses added or removed each * 2^20 clock cycles so it is suitable for the CALR register fields @@ -214,9 +212,9 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t return err; } - LL_RTC_DATE_SetYear(RTC, __LL_RTC_CONVERT_BIN2BCD(real_year - RTC_YEAR_REF)); - LL_RTC_DATE_SetMonth(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mon + 1)); - LL_RTC_DATE_SetDay(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mday)); + LL_RTC_DATE_SetYear(RTC, bin2bcd(real_year - RTC_YEAR_REF)); + LL_RTC_DATE_SetMonth(RTC, bin2bcd(timeptr->tm_mon + 1)); + LL_RTC_DATE_SetDay(RTC, bin2bcd(timeptr->tm_mday)); if (timeptr->tm_wday == 0) { /* sunday (tm_wday = 0) is not represented by the same value in hardware */ @@ -227,9 +225,9 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t } - LL_RTC_TIME_SetHour(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_hour)); - LL_RTC_TIME_SetMinute(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_min)); - LL_RTC_TIME_SetSecond(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_sec)); + LL_RTC_TIME_SetHour(RTC, bin2bcd(timeptr->tm_hour)); + LL_RTC_TIME_SetMinute(RTC, bin2bcd(timeptr->tm_min)); + LL_RTC_TIME_SetSecond(RTC, bin2bcd(timeptr->tm_sec)); rtc_stm32_leave_initialization_mode(); @@ -269,10 +267,10 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr k_mutex_unlock(&data->lock); - timeptr->tm_year = TM_TO_RTC_OFFSET + __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date)); + timeptr->tm_year = bcd2bin(__LL_RTC_GET_YEAR(rtc_date)) + RTC_YEAR_REF - TM_YEAR_REF; /* tm_mon allowed values are 0-11 */ - timeptr->tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1; - timeptr->tm_mday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_DAY(rtc_date)); + timeptr->tm_mon = bcd2bin(__LL_RTC_GET_MONTH(rtc_date)) - 1; + timeptr->tm_mday = bcd2bin(__LL_RTC_GET_DAY(rtc_date)); int hw_wday = __LL_RTC_GET_WEEKDAY(rtc_date); @@ -284,9 +282,9 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr timeptr->tm_wday = hw_wday; } - timeptr->tm_hour = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(rtc_time)); - timeptr->tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time)); - timeptr->tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time)); + timeptr->tm_hour = bcd2bin(__LL_RTC_GET_HOUR(rtc_time)); + timeptr->tm_min = bcd2bin(__LL_RTC_GET_MINUTE(rtc_time)); + timeptr->tm_sec = bcd2bin(__LL_RTC_GET_SECOND(rtc_time)); uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L; From b06a119f2f566ea270bacbb30aeaff388045478f Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 19:57:14 +0200 Subject: [PATCH 0269/4498] drivers: rtc: stm32: fill all rtc_time fields Set tm_yday and tm_isdst to -1 as theses values are unknown. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index ad4dc4b2d75..3b4673da713 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -290,6 +290,10 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, cfg->sync_prescaler + 1); + /* unknown values */ + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + return 0; } From 244b437a0d21ce9e62bb52ef3bebe09c19c63617 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Tue, 12 Sep 2023 11:34:07 +0200 Subject: [PATCH 0270/4498] drivers: rtc: stm32: disable calibration for STM32F2 and some STM32L1 STM32F2 and STM32L1 Cat. 1 only provide the coarse calibration feature which is not supported by the code yet. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 3b4673da713..047fde9188b 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -298,6 +298,8 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr } #ifdef CONFIG_RTC_CALIBRATION +#if !defined(CONFIG_SOC_SERIES_STM32F2X) && \ + !(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT)) static int rtc_stm32_set_calibration(const struct device *dev, int32_t calibration) { ARG_UNUSED(dev); @@ -362,6 +364,7 @@ static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibrat return 0; } +#endif #endif /* CONFIG_RTC_CALIBRATION */ struct rtc_driver_api rtc_stm32_driver_api = { @@ -370,8 +373,13 @@ struct rtc_driver_api rtc_stm32_driver_api = { /* RTC_ALARM not supported */ /* RTC_UPDATE not supported */ #ifdef CONFIG_RTC_CALIBRATION +#if !defined(CONFIG_SOC_SERIES_STM32F2X) && \ + !(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT)) .set_calibration = rtc_stm32_set_calibration, .get_calibration = rtc_stm32_get_calibration, +#else +#error RTC calibration for devices without smooth calibration feature is not supported yet +#endif #endif /* CONFIG_RTC_CALIBRATION */ }; From 1a513a46fd1c7f60c7ec346868ff1e46ca685776 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 12 Sep 2023 09:40:59 -0300 Subject: [PATCH 0271/4498] MAINTAINERS: update esp32 names Keep single maintainer. Added "marekmatej" Remove "glaubermaroto" from the list. Signed-off-by: Sylvio Alves --- MAINTAINERS.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f934d8df55f..b63bc4fff26 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3012,10 +3012,9 @@ West: status: maintained maintainers: - sylvioalves - - glaubermaroto - - uLipe collaborators: - LucasTambor + - marekmatej files: [] labels: - "platform: ESP32" From 1fd3171f7bb9dbc2733088861defb469c82c2110 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 29 Aug 2023 16:57:45 +0000 Subject: [PATCH 0272/4498] arch: remove wait_q.h include This include is not used directly in those files, so remove it. Signed-off-by: Anas Nashif --- arch/arc/core/thread.c | 1 - arch/arm/core/aarch32/cortex_m/thread_abort.c | 1 - arch/arm/core/aarch32/thread.c | 1 - arch/arm64/core/thread.c | 1 - arch/posix/core/thread.c | 1 - lib/posix/_common.c | 1 - 6 files changed, 6 deletions(-) diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index 960889661aa..eeb12d45f6a 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef CONFIG_USERSPACE #include diff --git a/arch/arm/core/aarch32/cortex_m/thread_abort.c b/arch/arm/core/aarch32/cortex_m/thread_abort.c index b28a9bcf6fa..1ea84200cb8 100644 --- a/arch/arm/core/aarch32/cortex_m/thread_abort.c +++ b/arch/arm/core/aarch32/cortex_m/thread_abort.c @@ -21,7 +21,6 @@ #include #include #include -#include #include void z_impl_k_thread_abort(k_tid_t thread) diff --git a/arch/arm/core/aarch32/thread.c b/arch/arm/core/aarch32/thread.c index 275d085e6f6..f09d809e91b 100644 --- a/arch/arm/core/aarch32/thread.c +++ b/arch/arm/core/aarch32/thread.c @@ -14,7 +14,6 @@ #include #include -#include #include #if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index 118bee4397a..e8902d505e7 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -13,7 +13,6 @@ #include #include -#include #include /* diff --git a/arch/posix/core/thread.c b/arch/posix/core/thread.c index a1bcecb766d..e1ebc6fbc80 100644 --- a/arch/posix/core/thread.c +++ b/arch/posix/core/thread.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "posix_core.h" #include diff --git a/lib/posix/_common.c b/lib/posix/_common.c index c22a4c65e23..85a8e7cae66 100644 --- a/lib/posix/_common.c +++ b/lib/posix/_common.c @@ -6,7 +6,6 @@ #include #include -#include #include #ifdef CONFIG_POSIX_CLOCK From 8634c3b444400aa8e6bba4f616007a1a376f4ff1 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 29 Aug 2023 17:03:12 +0000 Subject: [PATCH 0273/4498] kernel: move wait_q.h header to be internal This header does not expose any public APIs, so move it under kernel/include and change files including it. Signed-off-by: Anas Nashif --- kernel/condvar.c | 2 +- kernel/events.c | 5 +++-- kernel/idle.c | 3 ++- {include/zephyr => kernel/include}/wait_q.h | 0 kernel/kheap.c | 5 +++-- kernel/mailbox.c | 5 +++-- kernel/mem_slab.c | 5 +++-- kernel/msg_q.c | 2 +- kernel/mutex.c | 2 +- kernel/pipes.c | 2 +- kernel/poll.c | 2 +- kernel/queue.c | 2 +- kernel/sched.c | 2 +- kernel/sem.c | 2 +- kernel/stack.c | 2 +- kernel/thread.c | 2 +- kernel/timer.c | 4 ++-- kernel/work.c | 2 +- lib/os/p4wq.c | 5 +++-- tests/benchmarks/sched/src/main.c | 2 +- tests/benchmarks/sched_userspace/src/main.c | 4 +++- tests/kernel/events/event_api/CMakeLists.txt | 4 ++++ tests/kernel/events/event_api/src/test_event_apis.c | 2 +- 23 files changed, 39 insertions(+), 27 deletions(-) rename {include/zephyr => kernel/include}/wait_q.h (100%) diff --git a/kernel/condvar.c b/kernel/condvar.c index 87cb36db316..27fb0ec8a02 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include static struct k_spinlock lock; diff --git a/kernel/events.c b/kernel/events.c index 96cae5bc4a8..18ab4656dd1 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -25,13 +25,14 @@ #include #include -#include #include -#include #include #include #include #include +/* private kernel APIs */ +#include +#include #define K_EVENT_WAIT_ANY 0x00 /* Wait for any events */ #define K_EVENT_WAIT_ALL 0x01 /* Wait for all events */ diff --git a/kernel/idle.c b/kernel/idle.c index be3902a5b41..290b45976d9 100644 --- a/kernel/idle.c +++ b/kernel/idle.c @@ -8,12 +8,13 @@ #include #include #include -#include #include #include #include +/* private kernel APIs */ #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/include/zephyr/wait_q.h b/kernel/include/wait_q.h similarity index 100% rename from include/zephyr/wait_q.h rename to kernel/include/wait_q.h diff --git a/kernel/kheap.c b/kernel/kheap.c index fc2d3300e78..71a3da596ad 100644 --- a/kernel/kheap.c +++ b/kernel/kheap.c @@ -5,11 +5,12 @@ */ #include -#include -#include #include #include #include +/* private kernel APIs */ +#include +#include void k_heap_init(struct k_heap *h, void *mem, size_t bytes) { diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 3014af57063..e72023846df 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -14,10 +14,11 @@ #include #include #include -#include -#include #include #include +/* private kernel APIs */ +#include +#include #if (CONFIG_NUM_MBOX_ASYNC_MSGS > 0) diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index b03b731d473..9c326536c38 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -9,12 +9,13 @@ #include #include -#include #include -#include #include #include #include +/* private kernel APIs */ +#include +#include /** * @brief Initialize kernel memory slab subsystem. diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 1179612ce42..82566115a67 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/mutex.c b/kernel/mutex.c index 32c889bb237..44e0d316dab 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/pipes.c b/kernel/pipes.c index 0a899856c02..68cf39d9a27 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/kernel/poll.c b/kernel/poll.c index d3b313f04bd..27d65c147f0 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/queue.c b/kernel/queue.c index 342ee89566e..07435973307 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/kernel/sched.c b/kernel/sched.c index fcd77c69eb7..ea157459dd2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/sem.c b/kernel/sem.c index 368c9377a1a..26e4597911b 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/kernel/stack.c b/kernel/stack.c index 38c2ccb90d4..27038ce133e 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/kernel/thread.c b/kernel/thread.c index fb578eb48d8..4f330b628cd 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/timer.c b/kernel/timer.c index 9de9768c361..0186b42c922 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -7,11 +7,11 @@ #include #include -#include -#include #include #include #include +#include +#include static struct k_spinlock lock; diff --git a/kernel/work.c b/kernel/work.c index 08c9d47176e..402b2f80517 100644 --- a/kernel/work.c +++ b/kernel/work.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/os/p4wq.c b/lib/os/p4wq.c index d5e97476812..22d24da140b 100644 --- a/lib/os/p4wq.c +++ b/lib/os/p4wq.c @@ -5,11 +5,12 @@ */ #include #include -#include #include -#include #include #include +/* private kernel APIs */ +#include +#include LOG_MODULE_REGISTER(p4wq, CONFIG_LOG_DEFAULT_LEVEL); diff --git a/tests/benchmarks/sched/src/main.c b/tests/benchmarks/sched/src/main.c index 43f5ff896e0..79a519ccf2c 100644 --- a/tests/benchmarks/sched/src/main.c +++ b/tests/benchmarks/sched/src/main.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include /* This is a scheduler microbenchmark, designed to measure latencies diff --git a/tests/benchmarks/sched_userspace/src/main.c b/tests/benchmarks/sched_userspace/src/main.c index ff3f66e68cb..5e921d9ee30 100644 --- a/tests/benchmarks/sched_userspace/src/main.c +++ b/tests/benchmarks/sched_userspace/src/main.c @@ -6,7 +6,9 @@ #include #include -#include + +/* private kernel APIs */ +#include #include #include "app_threads.h" diff --git a/tests/kernel/events/event_api/CMakeLists.txt b/tests/kernel/events/event_api/CMakeLists.txt index 1e43c202fc7..9c0c203380f 100644 --- a/tests/kernel/events/event_api/CMakeLists.txt +++ b/tests/kernel/events/event_api/CMakeLists.txt @@ -6,3 +6,7 @@ project(events_api) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/kernel/include + ) diff --git a/tests/kernel/events/event_api/src/test_event_apis.c b/tests/kernel/events/event_api/src/test_event_apis.c index 275040f508d..a6c81272bcd 100644 --- a/tests/kernel/events/event_api/src/test_event_apis.c +++ b/tests/kernel/events/event_api/src/test_event_apis.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define DELAY K_MSEC(50) #define SHORT_TIMEOUT K_MSEC(100) From fcf50ed6e7a9cc22477ff1003233cdc756afef02 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 29 Aug 2023 19:32:46 +0000 Subject: [PATCH 0274/4498] kernel: move timeout_q.h to kernel/include This is a private kernel header with private kernel APIs, it should not be exposed in the public zephyr include directory. Once sample remains to be fixed (metairq_dispatch), which currently uses private APIs from that header, it should not be the case. Signed-off-by: Anas Nashif --- kernel/include/ksched.h | 2 +- {include/zephyr => kernel/include}/timeout_q.h | 0 kernel/include/wait_q.h | 2 +- kernel/timeout.c | 2 +- samples/kernel/metairq_dispatch/CMakeLists.txt | 4 ++++ samples/kernel/metairq_dispatch/src/msgdev.c | 2 +- soc/x86/intel_ish/intel_ish5/pm/power.c | 1 - subsys/pm/pm.c | 1 - 8 files changed, 8 insertions(+), 6 deletions(-) rename {include/zephyr => kernel/include}/timeout_q.h (100%) diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index 0ec1897a2f3..4676a0beca1 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/include/zephyr/timeout_q.h b/kernel/include/timeout_q.h similarity index 100% rename from include/zephyr/timeout_q.h rename to kernel/include/timeout_q.h diff --git a/kernel/include/wait_q.h b/kernel/include/wait_q.h index 3edcb77702a..2c8eeefbf25 100644 --- a/kernel/include/wait_q.h +++ b/kernel/include/wait_q.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/kernel/timeout.c b/kernel/timeout.c index 1d3149b2afe..339bc65a014 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/samples/kernel/metairq_dispatch/CMakeLists.txt b/samples/kernel/metairq_dispatch/CMakeLists.txt index fe39b05df2e..2b16c4b410e 100644 --- a/samples/kernel/metairq_dispatch/CMakeLists.txt +++ b/samples/kernel/metairq_dispatch/CMakeLists.txt @@ -6,3 +6,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(metairq_dispatch) target_sources(app PRIVATE src/main.c src/msgdev.c) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/kernel/include + ) diff --git a/samples/kernel/metairq_dispatch/src/msgdev.c b/samples/kernel/metairq_dispatch/src/msgdev.c index 142f46d043d..d4ba5d5895f 100644 --- a/samples/kernel/metairq_dispatch/src/msgdev.c +++ b/samples/kernel/metairq_dispatch/src/msgdev.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include "msgdev.h" /* This file implements a fake device that creates and enqueues diff --git a/soc/x86/intel_ish/intel_ish5/pm/power.c b/soc/x86/intel_ish/intel_ish5/pm/power.c index a2ea8f65ce5..3ad15eee36b 100644 --- a/soc/x86/intel_ish/intel_ish5/pm/power.c +++ b/soc/x86/intel_ish/intel_ish5/pm/power.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/subsys/pm/pm.c b/subsys/pm/pm.c index ae6e8505d89..cfeadaa4447 100644 --- a/subsys/pm/pm.c +++ b/subsys/pm/pm.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include From a7df4295e2539fdbf0938a4e755adb8f00825170 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 6 Sep 2023 17:27:25 +0000 Subject: [PATCH 0275/4498] manifest: upsate SOF tree This change removes use of internal zephyr API in SOF. Signed-off-by: Anas Nashif --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 74130cd5aa9..cb407d976c0 100644 --- a/west.yml +++ b/west.yml @@ -319,7 +319,7 @@ manifest: groups: - debug - name: sof - revision: e32b825cd6447342b9a308284ccea33b5d249e9f + revision: c0f20b69daa44e3563f970b366e49ccfcfa1b71c path: modules/audio/sof - name: tflite-micro revision: 9156d050927012da87079064db59d07f03b8baf6 From 7b3d94cda20dc7e770d791aab7a3246a432e5848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 12 Sep 2023 14:41:03 +0200 Subject: [PATCH 0276/4498] MAINTAINERS: update GitHub ID for casparfriedrich MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GH User dp7hgh7 is now casparfriedrich. Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b63bc4fff26..bc10f2c9f9d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1394,7 +1394,7 @@ Release Notes: maintainers: - str4t0m collaborators: - - dp7hgh7 + - casparfriedrich files: - doc/hardware/peripherals/w1.rst - drivers/w1/ From 35e38f858a9ef45b366fda0e040a3b29d91934aa Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 12 Sep 2023 17:41:00 +0000 Subject: [PATCH 0277/4498] maintainers: xtensa: Add collaborator Add ceolin as Xtensa collaborator. Signed-off-by: Flavio Ceolin --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index bc10f2c9f9d..5a555645aa8 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3531,6 +3531,7 @@ Xtensa arch: collaborators: - andyross - nashif + - ceolin files: - arch/xtensa/ - include/zephyr/arch/xtensa/ From 3b4c529d7ed05fca35abc52d8c6bbd6dfcf1e36f Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 5 Sep 2023 22:13:03 +0530 Subject: [PATCH 0278/4498] net: Add priority to ping This is handy in testing of setting priority directly rather than deriving from DSCP. Please note ICMP doesn't use net context. This is applicable for both shell and API. Signed-off-by: Chaitanya Tata --- subsys/net/ip/icmpv4.c | 15 +++++++++++++-- subsys/net/ip/icmpv4.h | 3 +++ subsys/net/ip/icmpv6.c | 15 +++++++++++++-- subsys/net/ip/icmpv6.h | 3 +++ subsys/net/ip/net_shell.c | 15 ++++++++++++++- subsys/net/lib/zperf/zperf_shell.c | 2 +- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 5c3d844be8a..7d7514e4d42 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -507,6 +507,7 @@ int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, + int priority, const void *data, size_t data_size) { @@ -537,8 +538,18 @@ int net_icmpv4_send_echo_request(struct net_if *iface, return -ENOMEM; } - net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); - net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); + if (priority >= NET_MAX_PRIORITIES) { + NET_ERR("Priority %d is too large, maximum allowed is %d", + priority, NET_MAX_PRIORITIES - 1); + return -EINVAL; + } + + if (priority < 0) { + net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); + net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); + } else { + net_pkt_set_priority(pkt, priority); + } if (net_ipv4_create(pkt, src, dst) || icmpv4_create(pkt, NET_ICMPV4_ECHO_REQUEST, 0)) { diff --git a/subsys/net/ip/icmpv4.h b/subsys/net/ip/icmpv4.h index bfce2e8d9e6..492fc6e84a0 100644 --- a/subsys/net/ip/icmpv4.h +++ b/subsys/net/ip/icmpv4.h @@ -82,6 +82,7 @@ int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, + int priority, const void *data, size_t data_size); #else @@ -90,6 +91,7 @@ static inline int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, + int priority, const void *data, size_t data_size) { @@ -98,6 +100,7 @@ static inline int net_icmpv4_send_echo_request(struct net_if *iface, ARG_UNUSED(identifier); ARG_UNUSED(sequence); ARG_UNUSED(tos); + ARG_UNUSED(priority); ARG_UNUSED(data); ARG_UNUSED(data_size); diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index 95252a7c156..bc2dd16e5cc 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -341,6 +341,7 @@ int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, + int priority, const void *data, size_t data_size) { @@ -362,8 +363,18 @@ int net_icmpv6_send_echo_request(struct net_if *iface, return -ENOMEM; } - net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); - net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(tc)); + if (priority >= NET_MAX_PRIORITIES) { + NET_ERR("Priority %d is too large, maximum allowed is %d", + priority, NET_MAX_PRIORITIES - 1); + return -EINVAL; + } + + if (priority < 0) { + net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); + net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(tc)); + } else { + net_pkt_set_priority(pkt, priority); + } if (net_ipv6_create(pkt, src, dst) || net_icmpv6_create(pkt, NET_ICMPV6_ECHO_REQUEST, 0)) { diff --git a/subsys/net/ip/icmpv6.h b/subsys/net/ip/icmpv6.h index f0c586a7cf8..d71d9959c14 100644 --- a/subsys/net/ip/icmpv6.h +++ b/subsys/net/ip/icmpv6.h @@ -222,6 +222,7 @@ int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, + int priority, const void *data, size_t data_size); #else @@ -230,6 +231,7 @@ static inline int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, + int priority, const void *data, size_t data_size) { @@ -238,6 +240,7 @@ static inline int net_icmpv6_send_echo_request(struct net_if *iface, ARG_UNUSED(identifier); ARG_UNUSED(sequence); ARG_UNUSED(tc); + ARG_UNUSED(priority); ARG_UNUSED(data); ARG_UNUSED(data_size); diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 286d0eca8a9..c5b07afd6aa 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -4279,6 +4279,7 @@ static struct ping_context { uint32_t sequence; uint16_t payload_size; uint8_t tos; + int priority; } ping_ctx; static void ping_done(struct ping_context *ctx); @@ -4504,6 +4505,7 @@ static void ping_work(struct k_work *work) sys_rand32_get(), ctx->sequence, ctx->tos, + ctx->priority, NULL, ctx->payload_size); } else { @@ -4512,6 +4514,7 @@ static void ping_work(struct k_work *work) sys_rand32_get(), ctx->sequence, ctx->tos, + ctx->priority, NULL, ctx->payload_size); } @@ -4612,6 +4615,7 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) int iface_idx = -1; int tos = 0; int payload_size = 4; + int priority = -1; for (size_t i = 1; i < argc; ++i) { @@ -4647,6 +4651,14 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) } break; + case 'p': + priority = parse_arg(&i, argc, argv); + if (priority < 0 || priority > UINT8_MAX) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + break; + case 'Q': tos = parse_arg(&i, argc, argv); if (tos < 0 || tos > UINT8_MAX) { @@ -4683,6 +4695,7 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) ping_ctx.sh = sh; ping_ctx.count = count; ping_ctx.interval = interval; + ping_ctx.priority = priority; ping_ctx.tos = tos; ping_ctx.payload_size = payload_size; @@ -6584,7 +6597,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ping, SHELL_CMD(--help, NULL, "'net ping [-c count] [-i interval ms] [-I ] " - "[-Q tos] [-s payload size] ' " + "[-Q tos] [-s payload size] [-p priority] ' " "Send ICMPv4 or ICMPv6 Echo-Request to a network host.", cmd_net_ping), SHELL_SUBCMD_SET_END diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index a30caf08074..d3bf11a7b33 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -526,7 +526,7 @@ static int execute_upload(const struct shell *sh, * some time and start the test after that. */ net_icmpv6_send_echo_request(net_if_get_default(), - &ipv6->sin6_addr, 0, 0, 0, NULL, 0); + &ipv6->sin6_addr, 0, 0, 0, -1, NULL, 0); k_sleep(K_SECONDS(1)); } From 7711d28b03bba37ac614dbee54c7180203c0adc9 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 8 Sep 2023 00:37:27 +0530 Subject: [PATCH 0279/4498] net: Add configuration option to allow any priority This adds support to allow any priority from the user instead of limiting to the protocol values (0-7). This is useful in conveying custom priorities from application to the driver/chipset. Signed-off-by: Chaitanya Tata --- subsys/net/ip/Kconfig | 6 ++++++ subsys/net/ip/icmpv4.c | 3 ++- subsys/net/ip/icmpv6.c | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index d7edb988553..d2ca36b845c 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -290,6 +290,12 @@ config NET_RX_DEFAULT_PRIORITY What is the default network RX packet priority if user has not set one. The value 0 means lowest priority and 7 is the highest. +config NET_ALLOW_ANY_PRIORITY + bool "Allow any network packet priority to be used" + help + If this is set, then any user given network packet priority can be used. Otherwise + the network packet priorities are limited to 0-7 range. + config NET_IP_ADDR_CHECK bool "Check IP address validity before sending IP packet" default y diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 7d7514e4d42..3bf7e2ce163 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -538,7 +538,8 @@ int net_icmpv4_send_echo_request(struct net_if *iface, return -ENOMEM; } - if (priority >= NET_MAX_PRIORITIES) { + if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && + priority >= NET_MAX_PRIORITIES) { NET_ERR("Priority %d is too large, maximum allowed is %d", priority, NET_MAX_PRIORITIES - 1); return -EINVAL; diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index bc2dd16e5cc..60865d22017 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -363,7 +363,8 @@ int net_icmpv6_send_echo_request(struct net_if *iface, return -ENOMEM; } - if (priority >= NET_MAX_PRIORITIES) { + if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && + priority >= NET_MAX_PRIORITIES) { NET_ERR("Priority %d is too large, maximum allowed is %d", priority, NET_MAX_PRIORITIES - 1); return -EINVAL; From 79158a777b37b94965e6154906349b44d00d813d Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 8 Sep 2023 00:57:26 +0530 Subject: [PATCH 0280/4498] zperf: Add support to configure context priority This is handy in setting a custom priority for the context either through shell or API. Signed-off-by: Chaitanya Tata --- include/zephyr/net/zperf.h | 1 + subsys/net/lib/zperf/zperf_common.c | 20 +++++++++++- subsys/net/lib/zperf/zperf_internal.h | 2 +- subsys/net/lib/zperf/zperf_shell.c | 39 +++++++++++++++++++++++ subsys/net/lib/zperf/zperf_tcp_uploader.c | 2 +- subsys/net/lib/zperf/zperf_udp_uploader.c | 2 +- 6 files changed, 62 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index 447ffec670c..cd86541721e 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -37,6 +37,7 @@ struct zperf_upload_params { struct { uint8_t tos; int tcp_nodelay; + int priority; } options; }; diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index aa29bc99043..18c296cf508 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -131,7 +131,7 @@ const struct in6_addr *zperf_get_default_if_in6_addr(void) } int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, - int proto) + int priority, int proto) { socklen_t addrlen = peer_addr->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : @@ -192,6 +192,24 @@ int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, return -EINVAL; } + if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY) && priority >= 0) { + uint8_t prio = priority; + + if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && + (prio >= NET_MAX_PRIORITIES)) { + NET_ERR("Priority %d is too large, maximum allowed is %d", + prio, NET_MAX_PRIORITIES - 1); + return -EINVAL; + } + + if (zsock_setsockopt(sock, SOL_SOCKET, SO_PRIORITY, + &prio, + sizeof(prio)) != 0) { + NET_WARN("Failed to set SOL_SOCKET - SO_PRIORITY socket option."); + return -EINVAL; + } + } + ret = zsock_connect(sock, peer_addr, addrlen); if (ret < 0) { NET_ERR("Connect failed (%d)", errno); diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 5bef0331f6f..96dd9ea9123 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -99,7 +99,7 @@ const struct in_addr *zperf_get_default_if_in4_addr(void); const struct in6_addr *zperf_get_default_if_in6_addr(void); int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, - int proto); + int priority, int proto); uint32_t zperf_packet_duration(uint32_t packet_size, uint32_t rate_in_kbps); diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index d3bf11a7b33..3a8a9c61c4b 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -642,6 +642,7 @@ static int shell_cmd_upload(const struct shell *sh, size_t argc, int start = 0; size_t opt_cnt = 0; + param.options.priority = -1; is_udp = proto == IPPROTO_UDP; /* Parse options */ @@ -680,6 +681,19 @@ static int shell_cmd_upload(const struct shell *sh, size_t argc, opt_cnt += 1; break; +#ifdef CONFIG_NET_CONTEXT_PRIORITY + case 'p': + param.options.priority = parse_arg(&i, argc, argv); + if (param.options.priority < 0 || + param.options.priority > UINT8_MAX) { + shell_fprintf(sh, SHELL_WARNING, + "Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + opt_cnt += 2; + break; +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ + default: shell_fprintf(sh, SHELL_WARNING, "Unrecognized argument: %s\n", argv[i]); @@ -853,6 +867,19 @@ static int shell_cmd_upload2(const struct shell *sh, size_t argc, opt_cnt += 1; break; +#ifdef CONFIG_NET_CONTEXT_PRIORITY + case 'p': + param.options.priority = parse_arg(&i, argc, argv); + if (param.options.priority == -1 || + param.options.priority > UINT8_MAX) { + shell_fprintf(sh, SHELL_WARNING, + "Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + opt_cnt += 2; + break; +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ + default: shell_fprintf(sh, SHELL_WARNING, "Unrecognized argument: %s\n", argv[i]); @@ -1146,6 +1173,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" "-n: Disable Nagle's algorithm\n" +#ifdef CONFIG_NET_CONTEXT_PRIORITY + "-p: Specify custom packet priority\n" +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: tcp upload 192.0.2.2 1111 1 1K\n" "Example: tcp upload 2001:db8::2\n", cmd_tcp_upload), @@ -1159,6 +1189,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" +#ifdef CONFIG_NET_CONTEXT_PRIORITY + "-p: Specify custom packet priority\n" +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: tcp upload2 v6 1 1K\n" "Example: tcp upload2 v4\n" "-n: Disable Nagle's algorithm\n" @@ -1198,6 +1231,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" +#ifdef CONFIG_NET_CONTEXT_PRIORITY + "-p: Specify custom packet priority\n" +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: udp upload 192.0.2.2 1111 1 1K 1M\n" "Example: udp upload 2001:db8::2\n", cmd_udp_upload), @@ -1212,6 +1248,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" +#ifdef CONFIG_NET_CONTEXT_PRIORITY + "-p: Specify custom packet priority\n" +#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: udp upload2 v4 1 1K 1M\n" "Example: udp upload2 v6\n" #if defined(CONFIG_NET_IPV6) && defined(MY_IP6ADDR_SET) diff --git a/subsys/net/lib/zperf/zperf_tcp_uploader.c b/subsys/net/lib/zperf/zperf_tcp_uploader.c index 97fd4f57f71..3e72f81e54b 100644 --- a/subsys/net/lib/zperf/zperf_tcp_uploader.c +++ b/subsys/net/lib/zperf/zperf_tcp_uploader.c @@ -117,7 +117,7 @@ int zperf_tcp_upload(const struct zperf_upload_params *param, } sock = zperf_prepare_upload_sock(¶m->peer_addr, param->options.tos, - IPPROTO_TCP); + param->options.priority, IPPROTO_TCP); if (sock < 0) { return sock; } diff --git a/subsys/net/lib/zperf/zperf_udp_uploader.c b/subsys/net/lib/zperf/zperf_udp_uploader.c index 1310063437b..e7e2efb9a08 100644 --- a/subsys/net/lib/zperf/zperf_udp_uploader.c +++ b/subsys/net/lib/zperf/zperf_udp_uploader.c @@ -284,7 +284,7 @@ int zperf_udp_upload(const struct zperf_upload_params *param, } sock = zperf_prepare_upload_sock(¶m->peer_addr, param->options.tos, - IPPROTO_UDP); + param->options.priority, IPPROTO_UDP); if (sock < 0) { return sock; } From 9d0deabba2d3f09520b9b25ad73c4f5f1d97d946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 10:01:21 +0200 Subject: [PATCH 0281/4498] samples: stm32: move board-specific STM32 UART sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The STM32 single-wire UART sample should live with board-specific samples. Signed-off-by: Benjamin Cabé --- .../uart/stm32 => boards/stm32/uart}/single_wire/CMakeLists.txt | 0 .../uart/stm32 => boards/stm32/uart}/single_wire/README.rst | 2 +- .../stm32/uart}/single_wire/boards/stm32f3_disco.overlay | 0 .../uart/stm32 => boards/stm32/uart}/single_wire/prj.conf | 0 .../uart/stm32 => boards/stm32/uart}/single_wire/sample.yaml | 2 +- .../uart/stm32 => boards/stm32/uart}/single_wire/src/main.c | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/CMakeLists.txt (100%) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/README.rst (93%) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/boards/stm32f3_disco.overlay (100%) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/prj.conf (100%) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/sample.yaml (86%) rename samples/{drivers/uart/stm32 => boards/stm32/uart}/single_wire/src/main.c (100%) diff --git a/samples/drivers/uart/stm32/single_wire/CMakeLists.txt b/samples/boards/stm32/uart/single_wire/CMakeLists.txt similarity index 100% rename from samples/drivers/uart/stm32/single_wire/CMakeLists.txt rename to samples/boards/stm32/uart/single_wire/CMakeLists.txt diff --git a/samples/drivers/uart/stm32/single_wire/README.rst b/samples/boards/stm32/uart/single_wire/README.rst similarity index 93% rename from samples/drivers/uart/stm32/single_wire/README.rst rename to samples/boards/stm32/uart/single_wire/README.rst index 8956cca4a31..e16143a663f 100644 --- a/samples/drivers/uart/stm32/single_wire/README.rst +++ b/samples/boards/stm32/uart/single_wire/README.rst @@ -20,7 +20,7 @@ Building and Running Build and flash as follows, replacing ``stm32f3_disco`` with your board: .. zephyr-app-commands:: - :zephyr-app: samples/drivers/uart/stm32/single_wire + :zephyr-app: samples/boards/stm32/uart/single_wire :board: stm32f3_disco :goals: build flash :compact: diff --git a/samples/drivers/uart/stm32/single_wire/boards/stm32f3_disco.overlay b/samples/boards/stm32/uart/single_wire/boards/stm32f3_disco.overlay similarity index 100% rename from samples/drivers/uart/stm32/single_wire/boards/stm32f3_disco.overlay rename to samples/boards/stm32/uart/single_wire/boards/stm32f3_disco.overlay diff --git a/samples/drivers/uart/stm32/single_wire/prj.conf b/samples/boards/stm32/uart/single_wire/prj.conf similarity index 100% rename from samples/drivers/uart/stm32/single_wire/prj.conf rename to samples/boards/stm32/uart/single_wire/prj.conf diff --git a/samples/drivers/uart/stm32/single_wire/sample.yaml b/samples/boards/stm32/uart/single_wire/sample.yaml similarity index 86% rename from samples/drivers/uart/stm32/single_wire/sample.yaml rename to samples/boards/stm32/uart/single_wire/sample.yaml index 006fa8e84f8..6bf267e50a4 100644 --- a/samples/drivers/uart/stm32/single_wire/sample.yaml +++ b/samples/boards/stm32/uart/single_wire/sample.yaml @@ -1,7 +1,7 @@ sample: name: STM32 Single Wire UART sample tests: - sample.drivers.uart.stm32.single_wire: + sample.boards.stm32.uart.single_wire: platform_allow: stm32f3_disco tags: - drivers diff --git a/samples/drivers/uart/stm32/single_wire/src/main.c b/samples/boards/stm32/uart/single_wire/src/main.c similarity index 100% rename from samples/drivers/uart/stm32/single_wire/src/main.c rename to samples/boards/stm32/uart/single_wire/src/main.c From 59e4c5aed0b0b9ae870cc3b1667c6e781c409070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 5 Sep 2023 23:58:56 +0200 Subject: [PATCH 0282/4498] samples: fully migrate basic samples to the new Sphinx extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated basic samples READMEs to use the new zephyr:code-sample:: directive. Dropped "-sample" suffix that's not required anymore now that samples have their own namespace. - Updated all references to the samples to use the :zephyr:code-sample: role. Checked and updated the wording of said references to account for the fact that samples should not have "... sample" in their name anymore. Signed-off-by: Benjamin Cabé --- boards/arc/nsim/doc/index.rst | 2 +- boards/arc/qemu_arc/doc/index.rst | 2 +- boards/arm/adafruit_feather_nrf52840/doc/index.rst | 2 +- boards/arm/adafruit_feather_stm32f405/doc/index.rst | 2 +- boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst | 6 +++--- boards/arm/arduino_giga_r1/doc/index.rst | 2 +- boards/arm/arduino_portenta_h7/doc/index.rst | 2 +- boards/arm/b_g474e_dpow1/doc/index.rst | 2 +- boards/arm/b_u585i_iot02a/doc/index.rst | 2 +- boards/arm/bl652_dvk/doc/bl652_dvk.rst | 4 ++-- boards/arm/bl653_dvk/doc/bl653_dvk.rst | 4 ++-- boards/arm/bl654_dvk/doc/bl654_dvk.rst | 4 ++-- .../arm/bl654_sensor_board/doc/bl654_sensor_board.rst | 4 ++-- boards/arm/bl654_usb/doc/bl654_usb.rst | 4 ++-- boards/arm/black_f407ve/doc/index.rst | 2 +- boards/arm/black_f407zg_pro/doc/index.rst | 2 +- boards/arm/bt510/doc/bt510.rst | 4 ++-- boards/arm/bt610/doc/bt610.rst | 4 ++-- boards/arm/circuitdojo_feather_nrf9160/doc/index.rst | 4 ++-- boards/arm/cy8ckit_062_ble/doc/index.rst | 2 +- boards/arm/cy8cproto_062_4343w/doc/index.rst | 2 +- boards/arm/ebyte_e73_tbb_nrf52832/doc/index.rst | 4 ++-- boards/arm/fvp_baser_aemv8r_aarch32/doc/index.rst | 2 +- boards/arm/holyiot_yj16019/doc/index.rst | 2 +- boards/arm/ip_k66f/doc/index.rst | 4 ++-- boards/arm/lora_e5_dev_board/doc/lora_e5_dev_board.rst | 2 +- boards/arm/nrf51_ble400/doc/index.rst | 8 ++++---- boards/arm/nrf51_vbluno51/doc/index.rst | 8 ++++---- boards/arm/nrf51dongle_nrf51422/doc/index.rst | 2 +- boards/arm/nrf52833dk_nrf52833/doc/index.rst | 4 ++-- boards/arm/nrf52840_blip/doc/index.rst | 4 ++-- boards/arm/nrf52840dongle_nrf52840/doc/index.rst | 6 +++--- boards/arm/nrf52_adafruit_feather/doc/index.rst | 10 +++++----- boards/arm/nrf52_vbluno52/doc/index.rst | 4 ++-- boards/arm/nrf5340dk_nrf5340/doc/index.rst | 4 ++-- boards/arm/nrf9160dk_nrf9160/doc/index.rst | 4 ++-- boards/arm/nrf9161dk_nrf9161/doc/index.rst | 4 ++-- boards/arm/nucleo_c031c6/doc/index.rst | 2 +- boards/arm/nucleo_f030r8/doc/index.rst | 4 ++-- boards/arm/nucleo_f031k6/doc/index.rst | 4 ++-- boards/arm/nucleo_f042k6/doc/index.rst | 4 ++-- boards/arm/nucleo_f070rb/doc/index.rst | 2 +- boards/arm/nucleo_f091rc/doc/index.rst | 2 +- boards/arm/nucleo_f103rb/doc/index.rst | 4 ++-- boards/arm/nucleo_f334r8/doc/index.rst | 4 ++-- boards/arm/nucleo_g031k8/doc/index.rst | 2 +- boards/arm/nucleo_g070rb/doc/index.rst | 2 +- boards/arm/nucleo_g071rb/doc/index.rst | 2 +- boards/arm/nucleo_g0b1re/doc/index.rst | 2 +- boards/arm/nucleo_h563zi/doc/index.rst | 2 +- boards/arm/nucleo_h745zi_q/doc/index.rst | 2 +- boards/arm/nucleo_l011k4/doc/index.rst | 2 +- boards/arm/nucleo_l031k6/doc/index.rst | 2 +- boards/arm/nucleo_l053r8/doc/index.rst | 2 +- boards/arm/nucleo_l073rz/doc/index.rst | 2 +- boards/arm/nucleo_l152re/doc/index.rst | 2 +- boards/arm/nucleo_u575zi_q/doc/index.rst | 2 +- boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst | 2 +- boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst | 2 +- boards/arm/nucleo_wl55jc/doc/nucleo_wl55jc.rst | 2 +- .../doc/olimex_lora_stm32wl_devkit.rst | 2 +- boards/arm/olimex_stm32_h103/doc/index.rst | 2 +- boards/arm/olimexino_stm32/doc/index.rst | 2 +- boards/arm/particle_argon/doc/index.rst | 4 ++-- boards/arm/particle_boron/doc/index.rst | 4 ++-- boards/arm/particle_xenon/doc/index.rst | 4 ++-- boards/arm/qemu_cortex_m0/doc/index.rst | 2 +- boards/arm/qemu_cortex_m3/doc/index.rst | 2 +- boards/arm/qemu_cortex_r5/doc/index.rst | 2 +- boards/arm/reel_board/doc/index.rst | 4 ++-- boards/arm/rpi_pico/doc/index.rst | 6 +++--- boards/arm/ruuvi_ruuvitag/doc/index.rst | 4 ++-- boards/arm/s32z270dc2_r52/doc/index.rst | 2 +- boards/arm/segger_trb_stm32f407/doc/index.rst | 4 ++-- boards/arm/serpente/doc/index.rst | 2 +- boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst | 4 ++-- boards/arm/stm3210c_eval/doc/index.rst | 2 +- boards/arm/stm32373c_eval/doc/index.rst | 4 ++-- boards/arm/stm32_min_dev/doc/index.rst | 2 +- boards/arm/stm32f030_demo/doc/index.rst | 4 ++-- boards/arm/stm32f072_eval/doc/index.rst | 4 ++-- boards/arm/stm32f0_disco/doc/index.rst | 4 ++-- boards/arm/stm32f103_mini/doc/index.rst | 4 ++-- boards/arm/stm32f411e_disco/doc/index.rst | 4 ++-- boards/arm/stm32f4_disco/doc/index.rst | 2 +- boards/arm/stm32g0316_disco/doc/index.rst | 2 +- boards/arm/stm32g071b_disco/doc/index.rst | 2 +- boards/arm/stm32g081b_eval/doc/index.rst | 2 +- boards/arm/stm32h747i_disco/doc/index.rst | 2 +- boards/arm/stm32l1_disco/doc/index.rst | 4 ++-- boards/arm/stm32vl_disco/doc/index.rst | 4 ++-- boards/arm/thingy52_nrf52832/doc/index.rst | 2 +- boards/arm64/fvp_base_revc_2xaemv8a/doc/index.rst | 2 +- boards/arm64/fvp_baser_aemv8r/doc/index.rst | 2 +- boards/arm64/mimx8mm_evk/doc/index.rst | 2 +- boards/arm64/mimx8mn_evk/doc/index.rst | 2 +- boards/arm64/mimx8mp_evk/doc/index.rst | 2 +- boards/arm64/mimx93_evk/doc/index.rst | 2 +- boards/arm64/nxp_ls1046ardb/doc/index.rst | 2 +- boards/arm64/qemu_cortex_a53/doc/index.rst | 2 +- boards/arm64/xenvm/doc/index.rst | 2 +- boards/mips/qemu_malta/doc/index.rst | 4 ++-- boards/nios2/qemu_nios2/doc/index.rst | 2 +- boards/riscv/longan_nano/doc/index.rst | 4 ++-- boards/riscv/qemu_riscv32/doc/index.rst | 2 +- boards/riscv/qemu_riscv32e/doc/index.rst | 2 +- boards/riscv/qemu_riscv64/doc/index.rst | 2 +- boards/sparc/qemu_leon3/doc/index.rst | 2 +- boards/x86/qemu_x86/doc/index.rst | 2 +- boards/xtensa/qemu_xtensa/doc/index.rst | 2 +- doc/build/dts/api-usage.rst | 2 +- doc/build/dts/design.rst | 2 +- doc/build/dts/howtos.rst | 2 +- doc/build/dts/intro-syntax-structure.rst | 2 +- doc/build/kconfig/tips.rst | 2 +- doc/develop/beyond-GSG.rst | 2 +- doc/develop/getting_started/index.rst | 4 ++-- doc/services/tracing/index.rst | 2 +- samples/basic/blinky/README.rst | 4 ++-- samples/basic/blinky_pwm/README.rst | 4 ++-- samples/basic/button/README.rst | 4 ++-- samples/basic/custom_dts_binding/README.rst | 7 ++++--- samples/basic/fade_led/README.rst | 9 +++++---- samples/basic/hash_map/README.rst | 4 ++-- samples/basic/minimal/README.rst | 6 +++--- samples/basic/rgb_led/README.rst | 9 +++++---- samples/basic/servo_motor/README.rst | 9 +++++---- samples/basic/sys_heap/README.rst | 6 +++--- samples/basic/threads/README.rst | 7 ++++--- samples/bluetooth/encrypted_advertising/README.rst | 4 ++-- samples/synchronization/README.rst | 4 ++-- 131 files changed, 214 insertions(+), 209 deletions(-) diff --git a/boards/arc/nsim/doc/index.rst b/boards/arc/nsim/doc/index.rst index a95a2341aea..ee87b4f2aab 100644 --- a/boards/arc/nsim/doc/index.rst +++ b/boards/arc/nsim/doc/index.rst @@ -107,7 +107,7 @@ The supported toolchains are listed in ``toolchain:`` array in ``.yaml`` file, w particular toolchain. Use this configuration to run basic Zephyr applications and kernel tests in -nSIM, for example, with the :ref:`synchronization_sample`: +nSIM, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arc/qemu_arc/doc/index.rst b/boards/arc/qemu_arc/doc/index.rst index e2174fc2c27..5a0857edc41 100644 --- a/boards/arc/qemu_arc/doc/index.rst +++ b/boards/arc/qemu_arc/doc/index.rst @@ -67,7 +67,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample` +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample (note you may use ``qemu_arc_em``, ``qemu_arc_hs``, ``qemu_arc_hs5x`` or ``qemu_arc_hs6x`` depending on target CPU): diff --git a/boards/arm/adafruit_feather_nrf52840/doc/index.rst b/boards/arm/adafruit_feather_nrf52840/doc/index.rst index d198ec9e337..a36bbdd7e3a 100644 --- a/boards/arm/adafruit_feather_nrf52840/doc/index.rst +++ b/boards/arm/adafruit_feather_nrf52840/doc/index.rst @@ -113,7 +113,7 @@ Flashing Flashing Zephyr onto the ``adafruit_feather_nrf52480`` board requires an external programmer. The programmer is attached to the SWD header. -Build the Zephyr kernel and the :ref:`blinky-sample` sample application. +Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/adafruit_feather_stm32f405/doc/index.rst b/boards/arm/adafruit_feather_stm32f405/doc/index.rst index 1e80ba70b49..47d70537e69 100644 --- a/boards/arm/adafruit_feather_stm32f405/doc/index.rst +++ b/boards/arm/adafruit_feather_stm32f405/doc/index.rst @@ -100,7 +100,7 @@ of the built in DFU-Util bootloader is possible by following the Flashing ======== -#. Build the Zephyr kernel and the :ref:`blinky-sample` sample application: +#. Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application: .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst index 699e2151194..26de1d7c3b4 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst +++ b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst @@ -119,8 +119,8 @@ or the :ref:`cdc-acm-console` sample applications to see how this works. Testing LEDs and buttons on the Adafruit ItsyBitsy nRF52840 Express ******************************************************************* -The :ref:`button-sample` sample lets you test the buttons (switches) and the red LED. -The :ref:`blinky-sample` sample lets you test the red LED. +The :zephyr:code-sample:`button` sample lets you test the buttons (switches) and the red LED. +The :zephyr:code-sample:`blinky` sample lets you test the red LED. The DotStar LED has been implemented as a SPI device and can be tested with the :ref:`led_apa102_sample` sample application. @@ -151,7 +151,7 @@ Flashing Flashing is done by dragging and dropping the built Zephyr UF2-file into the :code:`ITSY840BOOT` drive. -#. Build the Zephyr kernel and the :ref:`blinky-sample` +#. Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application: .. zephyr-app-commands:: diff --git a/boards/arm/arduino_giga_r1/doc/index.rst b/boards/arm/arduino_giga_r1/doc/index.rst index f12df182a86..2b9debb4549 100644 --- a/boards/arm/arduino_giga_r1/doc/index.rst +++ b/boards/arm/arduino_giga_r1/doc/index.rst @@ -151,7 +151,7 @@ You should see the following message on the console: Similarly, you can build and flash samples on the M4 target. -Here is an example for the :ref:`blinky-sample` application on M4 core. +Here is an example for the :zephyr:code-sample:`blinky` application on M4 core. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/arduino_portenta_h7/doc/index.rst b/boards/arm/arduino_portenta_h7/doc/index.rst index 305fde248aa..d0ed9df377a 100644 --- a/boards/arm/arduino_portenta_h7/doc/index.rst +++ b/boards/arm/arduino_portenta_h7/doc/index.rst @@ -121,7 +121,7 @@ You should see the following message on the console: Similarly, you can build and flash samples on the M4 target. For this, please take care of the resource sharing (UART port used for console for instance). -Here is an example for the :ref:`blinky-sample` application on M4 core. +Here is an example for the :zephyr:code-sample:`blinky` application on M4 core. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/b_g474e_dpow1/doc/index.rst b/boards/arm/b_g474e_dpow1/doc/index.rst index 30aa1719dd2..1959ab6ad68 100644 --- a/boards/arm/b_g474e_dpow1/doc/index.rst +++ b/boards/arm/b_g474e_dpow1/doc/index.rst @@ -120,7 +120,7 @@ The B-G474E-DPOW1 Discovery board includes an ST-LINK/V3E embedded debug tool in Flashing an application to the B_G474E_DPOW1 -------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/b_u585i_iot02a/doc/index.rst b/boards/arm/b_u585i_iot02a/doc/index.rst index 5d5be82d592..3c794b4de79 100644 --- a/boards/arm/b_u585i_iot02a/doc/index.rst +++ b/boards/arm/b_u585i_iot02a/doc/index.rst @@ -327,7 +327,7 @@ Debugging ========= Default flasher for this board is openocd. It could be used in the usual way. -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/bl652_dvk/doc/bl652_dvk.rst b/boards/arm/bl652_dvk/doc/bl652_dvk.rst index 3fafbf1c34b..9d14b847fb9 100644 --- a/boards/arm/bl652_dvk/doc/bl652_dvk.rst +++ b/boards/arm/bl652_dvk/doc/bl652_dvk.rst @@ -255,8 +255,8 @@ Testing the LEDs and buttons in the BL652 DVK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/bl653_dvk/doc/bl653_dvk.rst b/boards/arm/bl653_dvk/doc/bl653_dvk.rst index 98c6bbf23aa..ee5996e81ae 100644 --- a/boards/arm/bl653_dvk/doc/bl653_dvk.rst +++ b/boards/arm/bl653_dvk/doc/bl653_dvk.rst @@ -162,8 +162,8 @@ Testing the LEDs and buttons on the BL653 DVK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/bl654_dvk/doc/bl654_dvk.rst b/boards/arm/bl654_dvk/doc/bl654_dvk.rst index 4ae9f496d6f..c70afb78729 100644 --- a/boards/arm/bl654_dvk/doc/bl654_dvk.rst +++ b/boards/arm/bl654_dvk/doc/bl654_dvk.rst @@ -168,8 +168,8 @@ Testing the LEDs and buttons on the BL654 DVK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/bl654_sensor_board/doc/bl654_sensor_board.rst b/boards/arm/bl654_sensor_board/doc/bl654_sensor_board.rst index 7a1c79f4804..673eed4eefb 100644 --- a/boards/arm/bl654_sensor_board/doc/bl654_sensor_board.rst +++ b/boards/arm/bl654_sensor_board/doc/bl654_sensor_board.rst @@ -233,8 +233,8 @@ Testing the LED and button on the BL654 Sensor Board There are 2 samples that allow you to test that the button (switch) and LED on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/bl654_usb/doc/bl654_usb.rst b/boards/arm/bl654_usb/doc/bl654_usb.rst index 887a2c82685..5d4fdc774de 100644 --- a/boards/arm/bl654_usb/doc/bl654_usb.rst +++ b/boards/arm/bl654_usb/doc/bl654_usb.rst @@ -130,7 +130,7 @@ before proceeding. These instructions were tested with version 6.1.0. The blue LED should start a fade pattern, signalling the bootloader is running. -#. Compile a Zephyr application; we'll use :ref:`blinky `. +#. Compile a Zephyr application; we'll use :zephyr:code-sample:`blinky`. .. zephyr-app-commands:: :app: zephyr/samples/basic/blinky @@ -171,7 +171,7 @@ Testing the LED on the BL654 USB There is a sample that allows you to test that the LED on the board is working properly with Zephyr: -* :ref:`blinky-sample` +* :zephyr:code-sample:`blinky` You can build and flash the example to make sure Zephyr is running correctly on your board. The LED definitions can be found in diff --git a/boards/arm/black_f407ve/doc/index.rst b/boards/arm/black_f407ve/doc/index.rst index 52a8210df6e..315894d3b36 100644 --- a/boards/arm/black_f407ve/doc/index.rst +++ b/boards/arm/black_f407ve/doc/index.rst @@ -202,7 +202,7 @@ This interface is supported by the openocd version included in Zephyr SDK. Flashing an application to BLACK_F407VE --------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. Run a serial host program to connect with your board: diff --git a/boards/arm/black_f407zg_pro/doc/index.rst b/boards/arm/black_f407zg_pro/doc/index.rst index 18b44f3adf4..4646149a71e 100644 --- a/boards/arm/black_f407zg_pro/doc/index.rst +++ b/boards/arm/black_f407zg_pro/doc/index.rst @@ -184,7 +184,7 @@ This interface is supported by the openocd version included in Zephyr SDK. Flashing an application to BLACK_F407ZG_PRO ------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. Run a serial host program to connect with your board: diff --git a/boards/arm/bt510/doc/bt510.rst b/boards/arm/bt510/doc/bt510.rst index 3514f90b9f0..841c27b85d6 100644 --- a/boards/arm/bt510/doc/bt510.rst +++ b/boards/arm/bt510/doc/bt510.rst @@ -239,8 +239,8 @@ Testing the LEDs and buttons on the BT510 There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button, LED and sensor device definitions can be found in diff --git a/boards/arm/bt610/doc/bt610.rst b/boards/arm/bt610/doc/bt610.rst index e792f91ec57..2fe7d7ad931 100644 --- a/boards/arm/bt610/doc/bt610.rst +++ b/boards/arm/bt610/doc/bt610.rst @@ -593,8 +593,8 @@ Testing the LEDs and buttons on the BT610 There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button, LED and sensor device definitions can be found in diff --git a/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst b/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst index f6fcb2a5225..f089c468e0d 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst +++ b/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst @@ -142,8 +142,8 @@ Testing the LEDs and buttons on the nRF9160 Feather There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/cy8ckit_062_ble/doc/index.rst b/boards/arm/cy8ckit_062_ble/doc/index.rst index af7d2a932f8..7bf45437ca7 100644 --- a/boards/arm/cy8ckit_062_ble/doc/index.rst +++ b/boards/arm/cy8ckit_062_ble/doc/index.rst @@ -190,7 +190,7 @@ Cy_WDT_Disable(). Running on Dual Core ******************** -#. Build the Zephyr kernel and the :ref:`button-sample` sample application: +#. Build the Zephyr kernel and the :zephyr:code-sample:`button` sample application: .. zephyr-app-commands:: :zephyr-app: samples/basic/button diff --git a/boards/arm/cy8cproto_062_4343w/doc/index.rst b/boards/arm/cy8cproto_062_4343w/doc/index.rst index b3d0aeeddbf..2b04a8f3688 100644 --- a/boards/arm/cy8cproto_062_4343w/doc/index.rst +++ b/boards/arm/cy8cproto_062_4343w/doc/index.rst @@ -101,7 +101,7 @@ To fetch Binary Blobs: Build blinking led sample ************************* -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. code-block:: console diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/doc/index.rst b/boards/arm/ebyte_e73_tbb_nrf52832/doc/index.rst index 8fd7dde6967..5b0f88f88a6 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/doc/index.rst +++ b/boards/arm/ebyte_e73_tbb_nrf52832/doc/index.rst @@ -206,8 +206,8 @@ the board are working properly with Zephyr: .. code-block:: console - :ref:`blinky-sample` - :ref:`button-sample` + :zephyr:code-sample:`blinky` + :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/fvp_baser_aemv8r_aarch32/doc/index.rst b/boards/arm/fvp_baser_aemv8r_aarch32/doc/index.rst index c65940d8191..d1911002020 100644 --- a/boards/arm/fvp_baser_aemv8r_aarch32/doc/index.rst +++ b/boards/arm/fvp_baser_aemv8r_aarch32/doc/index.rst @@ -77,7 +77,7 @@ Programming =========== Use this configuration to build basic Zephyr applications and kernel tests in the -Arm FVP emulated environment, for example, with the :ref:`synchronization_sample`: +Arm FVP emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm/holyiot_yj16019/doc/index.rst b/boards/arm/holyiot_yj16019/doc/index.rst index 639b04a5470..57990be93a1 100644 --- a/boards/arm/holyiot_yj16019/doc/index.rst +++ b/boards/arm/holyiot_yj16019/doc/index.rst @@ -109,7 +109,7 @@ found in :ref:`nordic_segger_flashing`. Then build and flash applications as usual (see :ref:`build_an_application` and :ref:`application_run` for more details). -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/ip_k66f/doc/index.rst b/boards/arm/ip_k66f/doc/index.rst index d9b5cf10351..eb8ee3b3e99 100644 --- a/boards/arm/ip_k66f/doc/index.rst +++ b/boards/arm/ip_k66f/doc/index.rst @@ -118,7 +118,7 @@ The default flasher is ``jlink`` using the built-in SEGGER Jlink interface. Flashing ======== -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -130,7 +130,7 @@ Red LED0 should blink at 1 second delay. Debugging ========= -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/lora_e5_dev_board/doc/lora_e5_dev_board.rst b/boards/arm/lora_e5_dev_board/doc/lora_e5_dev_board.rst index a24920002d9..c3c91fc8f74 100644 --- a/boards/arm/lora_e5_dev_board/doc/lora_e5_dev_board.rst +++ b/boards/arm/lora_e5_dev_board/doc/lora_e5_dev_board.rst @@ -263,7 +263,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nrf51_ble400/doc/index.rst b/boards/arm/nrf51_ble400/doc/index.rst index cfe3d8a547d..d746806faa1 100644 --- a/boards/arm/nrf51_ble400/doc/index.rst +++ b/boards/arm/nrf51_ble400/doc/index.rst @@ -199,10 +199,10 @@ Testing the LEDs and buttons in the nRF51 DK There are samples below that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -- :ref:`blinky-sample` -- :ref:`button-sample` -- :ref:`fade-led-sample` -- :ref:`96b_carbon_multi_thread_blinky` +- :zephyr:code-sample:`blinky` +- :zephyr:code-sample:`button` +- :zephyr:code-sample:`fade-led` +- :zephyr:code-sample:`multi-thread-blinky` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf51_vbluno51/doc/index.rst b/boards/arm/nrf51_vbluno51/doc/index.rst index 4aa8a9532c2..e4f6b58a68a 100644 --- a/boards/arm/nrf51_vbluno51/doc/index.rst +++ b/boards/arm/nrf51_vbluno51/doc/index.rst @@ -106,7 +106,7 @@ The VBLUno51 board has on-board DAPLink (CMSIS-DAP) interface for flashing and d You do not need any other programming device. You only need to install pyOCD tool (https://pypi.python.org/pypi/pyOCD) -This tutorial uses the blinky application :ref:`blinky-sample`. +This tutorial uses the blinky application :zephyr:code-sample:`blinky`. See the :ref:`getting_started` for general information on setting up your development environment. Then build and flash the application in @@ -121,7 +121,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -136,8 +136,8 @@ Testing the VBLUno51 with Zephyr: buttons, LEDs, UART, BLE components on the VBLUno51 board: * :ref:`hello_world` - * :ref:`blinky-sample` - * :ref:`button-sample` + * :zephyr:code-sample:`blinky` + * :zephyr:code-sample:`button` * :ref:`bluetooth-beacon-sample` * :ref:`peripheral_hr` diff --git a/boards/arm/nrf51dongle_nrf51422/doc/index.rst b/boards/arm/nrf51dongle_nrf51422/doc/index.rst index ba846747efd..1f73d1f9e08 100644 --- a/boards/arm/nrf51dongle_nrf51422/doc/index.rst +++ b/boards/arm/nrf51dongle_nrf51422/doc/index.rst @@ -132,7 +132,7 @@ Segger IC. Testing the LEDs on the nRF51 Dongle ************************************ -Build and flash the :ref:`blinky-sample` sample to test that the onboard LED +Build and flash the :zephyr:code-sample:`blinky` sample to test that the onboard LED is working properly with Zephyr. References diff --git a/boards/arm/nrf52833dk_nrf52833/doc/index.rst b/boards/arm/nrf52833dk_nrf52833/doc/index.rst index cb6b6fa4a51..126b1266d52 100644 --- a/boards/arm/nrf52833dk_nrf52833/doc/index.rst +++ b/boards/arm/nrf52833dk_nrf52833/doc/index.rst @@ -150,8 +150,8 @@ Testing the LEDs and buttons in the nRF52833 DK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf52840_blip/doc/index.rst b/boards/arm/nrf52840_blip/doc/index.rst index d85fa3cf04c..e9dc8ad939b 100644 --- a/boards/arm/nrf52840_blip/doc/index.rst +++ b/boards/arm/nrf52840_blip/doc/index.rst @@ -175,8 +175,8 @@ Testing the LEDs and buttons in the nRF52840 PDK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst index 6a28927b188..94da6423904 100644 --- a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst +++ b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst @@ -140,7 +140,7 @@ device. Make sure ``nrfutil`` is installed before proceeding. The red LED should start a fade pattern, signalling the bootloader is running. -#. Compile a Zephyr application; we'll use :ref:`blinky `. +#. Compile a Zephyr application; we'll use :zephyr:code-sample:`blinky`. .. zephyr-app-commands:: :app: zephyr/samples/basic/blinky @@ -298,7 +298,7 @@ flashed with an offset. Then build and flash applications as usual (see :ref:`build_an_application` and :ref:`application_run` for more details). -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -321,7 +321,7 @@ Testing the LEDs and buttons on the nRF52840 Dongle There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` +* :zephyr:code-sample:`blinky` You can build and program the examples to make sure Zephyr is running correctly on your board. diff --git a/boards/arm/nrf52_adafruit_feather/doc/index.rst b/boards/arm/nrf52_adafruit_feather/doc/index.rst index 281dbb48d5e..3555803b449 100644 --- a/boards/arm/nrf52_adafruit_feather/doc/index.rst +++ b/boards/arm/nrf52_adafruit_feather/doc/index.rst @@ -166,11 +166,11 @@ Testing the LEDs and buttons on the nRF52 Adafruit Feather There are several samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -- :ref:`blinky-sample` -- :ref:`button-sample` -- :ref:`fade-led-sample` -- :ref:`pwm-blinky-sample` -- :ref:`96b_carbon_multi_thread_blinky` +- :zephyr:code-sample:`blinky` +- :zephyr:code-sample:`button` +- :zephyr:code-sample:`fade-led` +- :zephyr:code-sample:`pwm-blinky` +- :zephyr:code-sample:`multi-thread-blinky` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf52_vbluno52/doc/index.rst b/boards/arm/nrf52_vbluno52/doc/index.rst index 38292648581..5342fdf81c4 100644 --- a/boards/arm/nrf52_vbluno52/doc/index.rst +++ b/boards/arm/nrf52_vbluno52/doc/index.rst @@ -101,7 +101,7 @@ Here are some sample applications that you can use to test different components on the VBLUno52 board: * :ref:`hello_world` -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` * :ref:`bluetooth-beacon-sample` * :ref:`peripheral_hr` diff --git a/boards/arm/nrf5340dk_nrf5340/doc/index.rst b/boards/arm/nrf5340dk_nrf5340/doc/index.rst index 196759af686..984090f3879 100644 --- a/boards/arm/nrf5340dk_nrf5340/doc/index.rst +++ b/boards/arm/nrf5340dk_nrf5340/doc/index.rst @@ -310,8 +310,8 @@ Testing the LEDs and buttons in the nRF5340 DK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf9160dk_nrf9160/doc/index.rst b/boards/arm/nrf9160dk_nrf9160/doc/index.rst index 7a8dbc42788..8deb4848255 100644 --- a/boards/arm/nrf9160dk_nrf9160/doc/index.rst +++ b/boards/arm/nrf9160dk_nrf9160/doc/index.rst @@ -245,8 +245,8 @@ Testing the LEDs and buttons in the nRF9160 DK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nrf9161dk_nrf9161/doc/index.rst b/boards/arm/nrf9161dk_nrf9161/doc/index.rst index 835ba29c1de..559288b06aa 100644 --- a/boards/arm/nrf9161dk_nrf9161/doc/index.rst +++ b/boards/arm/nrf9161dk_nrf9161/doc/index.rst @@ -184,8 +184,8 @@ Testing the LEDs and buttons in the nRF9161 DK There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/nucleo_c031c6/doc/index.rst b/boards/arm/nucleo_c031c6/doc/index.rst index 292f7defcbf..b4f8e484fc1 100644 --- a/boards/arm/nucleo_c031c6/doc/index.rst +++ b/boards/arm/nucleo_c031c6/doc/index.rst @@ -127,7 +127,7 @@ Nucleo C031C6 board includes an ST-LINK/V2-1 embedded debug tool interface. Flashing an application to Nucleo C031C6 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f030r8/doc/index.rst b/boards/arm/nucleo_f030r8/doc/index.rst index c1f6eb023ce..821470b20c0 100644 --- a/boards/arm/nucleo_f030r8/doc/index.rst +++ b/boards/arm/nucleo_f030r8/doc/index.rst @@ -149,7 +149,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F030R8 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -169,7 +169,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f031k6/doc/index.rst b/boards/arm/nucleo_f031k6/doc/index.rst index baff6aadc42..b7adddf6509 100644 --- a/boards/arm/nucleo_f031k6/doc/index.rst +++ b/boards/arm/nucleo_f031k6/doc/index.rst @@ -116,7 +116,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F030R8 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -129,7 +129,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f042k6/doc/index.rst b/boards/arm/nucleo_f042k6/doc/index.rst index bbae06bde44..a9676350eb4 100644 --- a/boards/arm/nucleo_f042k6/doc/index.rst +++ b/boards/arm/nucleo_f042k6/doc/index.rst @@ -116,7 +116,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F042K6 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -129,7 +129,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f070rb/doc/index.rst b/boards/arm/nucleo_f070rb/doc/index.rst index d609c743919..f61a63cd289 100644 --- a/boards/arm/nucleo_f070rb/doc/index.rst +++ b/boards/arm/nucleo_f070rb/doc/index.rst @@ -144,7 +144,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F070RB ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f091rc/doc/index.rst b/boards/arm/nucleo_f091rc/doc/index.rst index 4e1c8505098..5aa41419893 100644 --- a/boards/arm/nucleo_f091rc/doc/index.rst +++ b/boards/arm/nucleo_f091rc/doc/index.rst @@ -161,7 +161,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F091RC ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f103rb/doc/index.rst b/boards/arm/nucleo_f103rb/doc/index.rst index f704a4c0e49..72ed5ce0e8a 100644 --- a/boards/arm/nucleo_f103rb/doc/index.rst +++ b/boards/arm/nucleo_f103rb/doc/index.rst @@ -151,7 +151,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F103RB ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -164,7 +164,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_f334r8/doc/index.rst b/boards/arm/nucleo_f334r8/doc/index.rst index 422f9f86ba1..7d05c42c69a 100644 --- a/boards/arm/nucleo_f334r8/doc/index.rst +++ b/boards/arm/nucleo_f334r8/doc/index.rst @@ -143,7 +143,7 @@ Flashing an application to Nucleo F334R8 Connect the Nucleo F334R8 to your host computer using the USB port, then build and flash an application. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -156,7 +156,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for -the :ref:`blinky-sample` application. +the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_g031k8/doc/index.rst b/boards/arm/nucleo_g031k8/doc/index.rst index 1b32a1fb59e..3e0f72f4811 100644 --- a/boards/arm/nucleo_g031k8/doc/index.rst +++ b/boards/arm/nucleo_g031k8/doc/index.rst @@ -123,7 +123,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo G031K8 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_g070rb/doc/index.rst b/boards/arm/nucleo_g070rb/doc/index.rst index acdbdc53d28..9ceca0731a0 100644 --- a/boards/arm/nucleo_g070rb/doc/index.rst +++ b/boards/arm/nucleo_g070rb/doc/index.rst @@ -155,7 +155,7 @@ Nucleo G070RB board includes an ST-LINK/V2-1 embedded debug tool interface. Flashing an application to Nucleo G070RB ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_g071rb/doc/index.rst b/boards/arm/nucleo_g071rb/doc/index.rst index 81d05439ef8..7cc230fe0e2 100644 --- a/boards/arm/nucleo_g071rb/doc/index.rst +++ b/boards/arm/nucleo_g071rb/doc/index.rst @@ -159,7 +159,7 @@ Nucleo G071RB board includes an ST-LINK/V3 embedded debug tool interface. Flashing an application to Nucleo G071RB ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_g0b1re/doc/index.rst b/boards/arm/nucleo_g0b1re/doc/index.rst index 1e59c160467..22782af46af 100644 --- a/boards/arm/nucleo_g0b1re/doc/index.rst +++ b/boards/arm/nucleo_g0b1re/doc/index.rst @@ -168,7 +168,7 @@ following pyocd command: Flashing an application to Nucleo G0B1RE ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_h563zi/doc/index.rst b/boards/arm/nucleo_h563zi/doc/index.rst index 6ed79d8c7b9..051b7aa3118 100644 --- a/boards/arm/nucleo_h563zi/doc/index.rst +++ b/boards/arm/nucleo_h563zi/doc/index.rst @@ -294,7 +294,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_h745zi_q/doc/index.rst b/boards/arm/nucleo_h745zi_q/doc/index.rst index 99afb70898d..f419c17ccc4 100644 --- a/boards/arm/nucleo_h745zi_q/doc/index.rst +++ b/boards/arm/nucleo_h745zi_q/doc/index.rst @@ -240,7 +240,7 @@ You should see the following message on the console: Similarly, you can build and flash samples on the M4 target. For this, please take care of the resource sharing (UART port used for console for instance). -Here is an example for the :ref:`blinky-sample` application on M4 core. +Here is an example for the :zephyr:code-sample:`blinky` application on M4 core. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_l011k4/doc/index.rst b/boards/arm/nucleo_l011k4/doc/index.rst index 6d5831a37b0..590906ff57c 100644 --- a/boards/arm/nucleo_l011k4/doc/index.rst +++ b/boards/arm/nucleo_l011k4/doc/index.rst @@ -131,7 +131,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo L011K4 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_l031k6/doc/index.rst b/boards/arm/nucleo_l031k6/doc/index.rst index cc9803e7857..229851d829d 100644 --- a/boards/arm/nucleo_l031k6/doc/index.rst +++ b/boards/arm/nucleo_l031k6/doc/index.rst @@ -124,7 +124,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo L031K6 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_l053r8/doc/index.rst b/boards/arm/nucleo_l053r8/doc/index.rst index 5e55da0fbd2..5f66a6d3cdf 100644 --- a/boards/arm/nucleo_l053r8/doc/index.rst +++ b/boards/arm/nucleo_l053r8/doc/index.rst @@ -140,7 +140,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo L053R8 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_l073rz/doc/index.rst b/boards/arm/nucleo_l073rz/doc/index.rst index 0950b903853..e498addbc9a 100644 --- a/boards/arm/nucleo_l073rz/doc/index.rst +++ b/boards/arm/nucleo_l073rz/doc/index.rst @@ -154,7 +154,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo L073RZ ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_l152re/doc/index.rst b/boards/arm/nucleo_l152re/doc/index.rst index 15af9807494..2595144e730 100644 --- a/boards/arm/nucleo_l152re/doc/index.rst +++ b/boards/arm/nucleo_l152re/doc/index.rst @@ -148,7 +148,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo L152RE ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_u575zi_q/doc/index.rst b/boards/arm/nucleo_u575zi_q/doc/index.rst index 9a6df0c6a50..3f297372b82 100644 --- a/boards/arm/nucleo_u575zi_q/doc/index.rst +++ b/boards/arm/nucleo_u575zi_q/doc/index.rst @@ -289,7 +289,7 @@ Debugging ========= Default flasher for this board is openocd. It could be used in the usual way. -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst b/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst index fe03035e9e8..835b99f227f 100644 --- a/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst +++ b/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst @@ -288,7 +288,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst b/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst index 624d1ab1b10..5f13e9fd0b8 100644 --- a/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst +++ b/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst @@ -232,7 +232,7 @@ as flashing tool by default. Flashing an application to Nucleo WBA52CG ----------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/nucleo_wl55jc/doc/nucleo_wl55jc.rst b/boards/arm/nucleo_wl55jc/doc/nucleo_wl55jc.rst index 4b0a2937b05..3d569753f15 100644 --- a/boards/arm/nucleo_wl55jc/doc/nucleo_wl55jc.rst +++ b/boards/arm/nucleo_wl55jc/doc/nucleo_wl55jc.rst @@ -307,7 +307,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst b/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst index 8185d7ef445..be63585fbb1 100644 --- a/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst +++ b/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst @@ -136,7 +136,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/olimex_stm32_h103/doc/index.rst b/boards/arm/olimex_stm32_h103/doc/index.rst index 8ba6e949f8b..3abfb3b8885 100644 --- a/boards/arm/olimex_stm32_h103/doc/index.rst +++ b/boards/arm/olimex_stm32_h103/doc/index.rst @@ -208,7 +208,7 @@ The ``blackmagicprobe`` can also be used to program the device. Flashing ======== -Here is an example for the :ref:`button-sample` application. +Here is an example for the :zephyr:code-sample:`button` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/button diff --git a/boards/arm/olimexino_stm32/doc/index.rst b/boards/arm/olimexino_stm32/doc/index.rst index ce5a2407ac9..af8c880b86a 100644 --- a/boards/arm/olimexino_stm32/doc/index.rst +++ b/boards/arm/olimexino_stm32/doc/index.rst @@ -414,7 +414,7 @@ Flashing an Application to OLIMEXINO-STM32 To upload an application to the OLIMEXINO-STM32 board a TTL(3.3V) serial adapter is required. This tutorial uses the -:ref:`button-sample` sample application. +:zephyr:code-sample:`button` sample application. #. Connect the serial cable to the UEXT lines of the UART interface (pin #3=TX and pin #4=RX). diff --git a/boards/arm/particle_argon/doc/index.rst b/boards/arm/particle_argon/doc/index.rst index 446b0a349dd..2bbb15a546f 100644 --- a/boards/arm/particle_argon/doc/index.rst +++ b/boards/arm/particle_argon/doc/index.rst @@ -160,8 +160,8 @@ Testing the LEDs and buttons There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. diff --git a/boards/arm/particle_boron/doc/index.rst b/boards/arm/particle_boron/doc/index.rst index 1f26fc09b6c..d5b7ce1f5d0 100644 --- a/boards/arm/particle_boron/doc/index.rst +++ b/boards/arm/particle_boron/doc/index.rst @@ -156,8 +156,8 @@ Testing the LEDs and buttons There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. diff --git a/boards/arm/particle_xenon/doc/index.rst b/boards/arm/particle_xenon/doc/index.rst index 5d011b0de0d..cf18340943a 100644 --- a/boards/arm/particle_xenon/doc/index.rst +++ b/boards/arm/particle_xenon/doc/index.rst @@ -161,8 +161,8 @@ Testing the LEDs and buttons There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. diff --git a/boards/arm/qemu_cortex_m0/doc/index.rst b/boards/arm/qemu_cortex_m0/doc/index.rst index f2fe07dd50a..7035f57b07f 100644 --- a/boards/arm/qemu_cortex_m0/doc/index.rst +++ b/boards/arm/qemu_cortex_m0/doc/index.rst @@ -64,7 +64,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm/qemu_cortex_m3/doc/index.rst b/boards/arm/qemu_cortex_m3/doc/index.rst index 9a8d9afd6df..f07f6bf2166 100644 --- a/boards/arm/qemu_cortex_m3/doc/index.rst +++ b/boards/arm/qemu_cortex_m3/doc/index.rst @@ -70,7 +70,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm/qemu_cortex_r5/doc/index.rst b/boards/arm/qemu_cortex_r5/doc/index.rst index bc86cda64c0..9fd59d117ac 100644 --- a/boards/arm/qemu_cortex_r5/doc/index.rst +++ b/boards/arm/qemu_cortex_r5/doc/index.rst @@ -64,7 +64,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the -QEMU emulated environment, for example, with the :ref:`synchronization_sample`: +QEMU emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm/reel_board/doc/index.rst b/boards/arm/reel_board/doc/index.rst index 2dfe60ffeff..dc490249abd 100644 --- a/boards/arm/reel_board/doc/index.rst +++ b/boards/arm/reel_board/doc/index.rst @@ -544,8 +544,8 @@ Testing the LEDs and buttons There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. diff --git a/boards/arm/rpi_pico/doc/index.rst b/boards/arm/rpi_pico/doc/index.rst index 69cb6acd2ce..49d5905e94b 100644 --- a/boards/arm/rpi_pico/doc/index.rst +++ b/boards/arm/rpi_pico/doc/index.rst @@ -152,7 +152,7 @@ Using SEGGER JLink You can Flash the rpi_pico with a SEGGER JLink debug probe as described in :ref:`Building, Flashing and Debugging `. -Here is an example of building and flashing the :ref:`blinky-sample` application. +Here is an example of building and flashing the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -187,7 +187,7 @@ Depending on the interface used (such as JLink), you might need to checkout to a branch that supports this interface, before proceeding. Build and install OpenOCD as described in the README. -Here is an example of building and flashing the :ref:`blinky-sample` application. +Here is an example of building and flashing the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -247,7 +247,7 @@ Using OpenOCD Install OpenOCD as described for flashing the board. -Here is an example for debugging the :ref:`blinky-sample` application. +Here is an example for debugging the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/ruuvi_ruuvitag/doc/index.rst b/boards/arm/ruuvi_ruuvitag/doc/index.rst index 9e827c0941b..5ab0ea9cfc0 100644 --- a/boards/arm/ruuvi_ruuvitag/doc/index.rst +++ b/boards/arm/ruuvi_ruuvitag/doc/index.rst @@ -168,8 +168,8 @@ Testing the LEDs and buttons on the RuuviTag There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in :file:`boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.dts`. diff --git a/boards/arm/s32z270dc2_r52/doc/index.rst b/boards/arm/s32z270dc2_r52/doc/index.rst index 9ae309a33b4..60b465cc940 100644 --- a/boards/arm/s32z270dc2_r52/doc/index.rst +++ b/boards/arm/s32z270dc2_r52/doc/index.rst @@ -99,7 +99,7 @@ using GPIO driver or configuring the pinmuxing for the device drivers. +-------------------+-------------+ This board does not include user LED's or switches, which are needed for some -of the samples such as :ref:`blinky-sample` or :ref:`button-sample`. +of the samples such as :zephyr:code-sample:`blinky` or :zephyr:code-sample:`button`. Follow the steps described in the sample description to enable support for this board. diff --git a/boards/arm/segger_trb_stm32f407/doc/index.rst b/boards/arm/segger_trb_stm32f407/doc/index.rst index 83fb6924e7a..24c8f8df6d8 100644 --- a/boards/arm/segger_trb_stm32f407/doc/index.rst +++ b/boards/arm/segger_trb_stm32f407/doc/index.rst @@ -109,7 +109,7 @@ Flashing an application to the SEGGER-TRB-STM32F407 Connect the J-Trace/J-Link USB dongle to your host computer and to the JTAG port of the SEGGER-TRB-STM32F407 board. Then build and flash an application. -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -121,7 +121,7 @@ After resetting the board, you should see LED0 blink with a 1 second interval. Debugging ========= -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/serpente/doc/index.rst b/boards/arm/serpente/doc/index.rst index e2369d0b95e..c354631047f 100644 --- a/boards/arm/serpente/doc/index.rst +++ b/boards/arm/serpente/doc/index.rst @@ -87,7 +87,7 @@ can be entered by quickly tapping the reset button twice. Flashing ======== -#. Build the Zephyr kernel and the :ref:`blinky-sample` sample application: +#. Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application: .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst index 44366c49a39..72dac6a8900 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst +++ b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst @@ -137,8 +137,8 @@ Testing the LEDs and buttons on the nRF9160 Thing Plus There are 2 samples that allow you to test that the buttons (switches) and LEDs on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/stm3210c_eval/doc/index.rst b/boards/arm/stm3210c_eval/doc/index.rst index 6ec151a1cec..4154d45a878 100644 --- a/boards/arm/stm3210c_eval/doc/index.rst +++ b/boards/arm/stm3210c_eval/doc/index.rst @@ -125,7 +125,7 @@ Flashing an application to STM3210C-EVAL Connect the STM3210C-EVAL to your host computer using the USB port, then build and flash an application in the usual way. -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32373c_eval/doc/index.rst b/boards/arm/stm32373c_eval/doc/index.rst index 2f27c57d0d4..eb9ccf11153 100644 --- a/boards/arm/stm32373c_eval/doc/index.rst +++ b/boards/arm/stm32373c_eval/doc/index.rst @@ -126,7 +126,7 @@ This interface is supported by the openocd version included in Zephyr SDK. Flashing an application to STM32373C-EVAL ----------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -139,7 +139,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32_min_dev/doc/index.rst b/boards/arm/stm32_min_dev/doc/index.rst index 728191c15f0..8f166ea1f92 100644 --- a/boards/arm/stm32_min_dev/doc/index.rst +++ b/boards/arm/stm32_min_dev/doc/index.rst @@ -161,7 +161,7 @@ built and flashed in the usual way (see :ref:`build_an_application` and Flashing ======== -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f030_demo/doc/index.rst b/boards/arm/stm32f030_demo/doc/index.rst index 3c57989be0a..a1f3ecd68e2 100644 --- a/boards/arm/stm32f030_demo/doc/index.rst +++ b/boards/arm/stm32f030_demo/doc/index.rst @@ -87,7 +87,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to STM32F030 DEMO BOARD ----------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -100,7 +100,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f072_eval/doc/index.rst b/boards/arm/stm32f072_eval/doc/index.rst index fad35d0c980..cb623eb0aa5 100644 --- a/boards/arm/stm32f072_eval/doc/index.rst +++ b/boards/arm/stm32f072_eval/doc/index.rst @@ -156,7 +156,7 @@ This interface is supported by the openocd version included in Zephyr SDK. Flashing an application to STM32F072-EVAL ------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -169,7 +169,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f0_disco/doc/index.rst b/boards/arm/stm32f0_disco/doc/index.rst index b528f22adc9..b7b40b1bf09 100644 --- a/boards/arm/stm32f0_disco/doc/index.rst +++ b/boards/arm/stm32f0_disco/doc/index.rst @@ -107,7 +107,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application to Nucleo F030R8 ---------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -120,7 +120,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f103_mini/doc/index.rst b/boards/arm/stm32f103_mini/doc/index.rst index 5ae9621bebc..ab3bbbd9188 100644 --- a/boards/arm/stm32f103_mini/doc/index.rst +++ b/boards/arm/stm32f103_mini/doc/index.rst @@ -133,7 +133,7 @@ pattern, which can be triggered by using the BOOT0 pin. Flashing an application to stm32f103 mini ----------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -146,7 +146,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f411e_disco/doc/index.rst b/boards/arm/stm32f411e_disco/doc/index.rst index 5c8749012f7..7744da987ab 100644 --- a/boards/arm/stm32f411e_disco/doc/index.rst +++ b/boards/arm/stm32f411e_disco/doc/index.rst @@ -141,7 +141,7 @@ Flashing an application to STM32F411E-DISCO Connect the STM32F411E-DISCO Discovery kit to your host computer using the USB port. Then build and flash an application. -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -162,7 +162,7 @@ Debugging ========= You can debug applications in the usual way. Here is an example for -the :ref:`blinky-sample` application. +the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32f4_disco/doc/index.rst b/boards/arm/stm32f4_disco/doc/index.rst index 7cd7c26020d..2a0bd07cd27 100644 --- a/boards/arm/stm32f4_disco/doc/index.rst +++ b/boards/arm/stm32f4_disco/doc/index.rst @@ -169,7 +169,7 @@ This interface is supported by the openocd version included in Zephyr SDK. Flashing an application to STM32F4DISCOVERY ------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. Run a serial host program to connect with your board: diff --git a/boards/arm/stm32g0316_disco/doc/index.rst b/boards/arm/stm32g0316_disco/doc/index.rst index 793e3c98aa8..ed68a7b5dd4 100644 --- a/boards/arm/stm32g0316_disco/doc/index.rst +++ b/boards/arm/stm32g0316_disco/doc/index.rst @@ -100,7 +100,7 @@ the following pyocd command: Flashing an application to the STM32G0316-DISCO ----------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32g071b_disco/doc/index.rst b/boards/arm/stm32g071b_disco/doc/index.rst index 5f9dd31381c..a01020557ea 100644 --- a/boards/arm/stm32g071b_disco/doc/index.rst +++ b/boards/arm/stm32g071b_disco/doc/index.rst @@ -130,7 +130,7 @@ The STM32G071B Discovery board includes an ST-LINK/V2-1 embedded debug tool inte Flashing an application to the STM32G071B_DISCO ----------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32g081b_eval/doc/index.rst b/boards/arm/stm32g081b_eval/doc/index.rst index 84d9e18c61e..6975509a62e 100644 --- a/boards/arm/stm32g081b_eval/doc/index.rst +++ b/boards/arm/stm32g081b_eval/doc/index.rst @@ -168,7 +168,7 @@ The STM32G081B Evaluation board includes an ST-LINK/V2-1 embedded debug tool int Flashing an application to the STM32G081B_EVAL ---------------------------------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32h747i_disco/doc/index.rst b/boards/arm/stm32h747i_disco/doc/index.rst index 2f8d543d446..5610ad0e554 100644 --- a/boards/arm/stm32h747i_disco/doc/index.rst +++ b/boards/arm/stm32h747i_disco/doc/index.rst @@ -258,7 +258,7 @@ You should see the following message on the console: Similarly, you can build and flash samples on the M4 target. For this, please take care of the resource sharing (UART port used for console for instance). -Here is an example for the :ref:`blinky-sample` application on M4 core. +Here is an example for the :zephyr:code-sample:`blinky` application on M4 core. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32l1_disco/doc/index.rst b/boards/arm/stm32l1_disco/doc/index.rst index 87064ada200..65bb4bc028f 100644 --- a/boards/arm/stm32l1_disco/doc/index.rst +++ b/boards/arm/stm32l1_disco/doc/index.rst @@ -143,7 +143,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application ----------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -156,7 +156,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/stm32vl_disco/doc/index.rst b/boards/arm/stm32vl_disco/doc/index.rst index e7a20a3b3e4..006c8854bb4 100644 --- a/boards/arm/stm32vl_disco/doc/index.rst +++ b/boards/arm/stm32vl_disco/doc/index.rst @@ -137,7 +137,7 @@ This interface is supported by the openocd version included in the Zephyr SDK. Flashing an application ----------------------- -Here is an example for the :ref:`blinky-sample` application. +Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -150,7 +150,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm/thingy52_nrf52832/doc/index.rst b/boards/arm/thingy52_nrf52832/doc/index.rst index 96044ee9df4..f90d38a399a 100644 --- a/boards/arm/thingy52_nrf52832/doc/index.rst +++ b/boards/arm/thingy52_nrf52832/doc/index.rst @@ -362,7 +362,7 @@ debugger. A development board with a Debug out connector such as the Testing board features ********************** -The green lightwell LED can be tested with the :ref:`blinky-sample` example. +The green lightwell LED can be tested with the :zephyr:code-sample:`blinky` example. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/arm64/fvp_base_revc_2xaemv8a/doc/index.rst b/boards/arm64/fvp_base_revc_2xaemv8a/doc/index.rst index 224fbd95960..495b7ad11f4 100644 --- a/boards/arm64/fvp_base_revc_2xaemv8a/doc/index.rst +++ b/boards/arm64/fvp_base_revc_2xaemv8a/doc/index.rst @@ -72,7 +72,7 @@ Programming =========== Use this configuration to build basic Zephyr applications and kernel tests in the -ARM FVP emulated environment, for example, with the :ref:`synchronization_sample`: +ARM FVP emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/fvp_baser_aemv8r/doc/index.rst b/boards/arm64/fvp_baser_aemv8r/doc/index.rst index 862e574715b..3c45ce22840 100644 --- a/boards/arm64/fvp_baser_aemv8r/doc/index.rst +++ b/boards/arm64/fvp_baser_aemv8r/doc/index.rst @@ -86,7 +86,7 @@ Programming =========== Use this configuration to build basic Zephyr applications and kernel tests in the -Arm FVP emulated environment, for example, with the :ref:`synchronization_sample`: +Arm FVP emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/mimx8mm_evk/doc/index.rst b/boards/arm64/mimx8mm_evk/doc/index.rst index aa82dbdda83..947abd2ba2a 100644 --- a/boards/arm64/mimx8mm_evk/doc/index.rst +++ b/boards/arm64/mimx8mm_evk/doc/index.rst @@ -92,7 +92,7 @@ Or kick SMP zephyr.bin: Use this configuration to run basic Zephyr applications and kernel tests, -for example, with the :ref:`synchronization_sample`: +for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/mimx8mn_evk/doc/index.rst b/boards/arm64/mimx8mn_evk/doc/index.rst index 4e7497b672e..546df0d5c2d 100644 --- a/boards/arm64/mimx8mn_evk/doc/index.rst +++ b/boards/arm64/mimx8mn_evk/doc/index.rst @@ -92,7 +92,7 @@ Or kick SMP zephyr.bin: Use this configuration to run basic Zephyr applications and kernel tests, -for example, with the :ref:`synchronization_sample`: +for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/mimx8mp_evk/doc/index.rst b/boards/arm64/mimx8mp_evk/doc/index.rst index ab63461f2e8..e59f94189a0 100644 --- a/boards/arm64/mimx8mp_evk/doc/index.rst +++ b/boards/arm64/mimx8mp_evk/doc/index.rst @@ -91,7 +91,7 @@ Or kick SMP zephyr.bin: mw 303d0518 f 1; fatload mmc 1:1 0xc0000000 zephyr.bin; dcache flush; icache flush; dcache off; icache off; cpu 2 release 0xc0000000 Use this configuration to run basic Zephyr applications and kernel tests, -for example, with the :ref:`synchronization_sample`: +for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/mimx93_evk/doc/index.rst b/boards/arm64/mimx93_evk/doc/index.rst index 033739f2d91..7ff38891d22 100644 --- a/boards/arm64/mimx93_evk/doc/index.rst +++ b/boards/arm64/mimx93_evk/doc/index.rst @@ -97,7 +97,7 @@ Or use the following command to kick zephyr.bin to Cortex-A55 Core0: Use this configuration to run basic Zephyr applications and kernel tests, -for example, with the :ref:`synchronization_sample`: +for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/nxp_ls1046ardb/doc/index.rst b/boards/arm64/nxp_ls1046ardb/doc/index.rst index 53f23f89ae2..98e52f941bc 100644 --- a/boards/arm64/nxp_ls1046ardb/doc/index.rst +++ b/boards/arm64/nxp_ls1046ardb/doc/index.rst @@ -84,7 +84,7 @@ Programming and Debugging ************************* Use the following configuration to run basic Zephyr applications and -kernel tests on LS1046A RDB board. For example, with the :ref:`synchronization_sample`: +kernel tests on LS1046A RDB board. For example, with the :zephyr:code-sample:`synchronization` sample: 1. Non-SMP mode diff --git a/boards/arm64/qemu_cortex_a53/doc/index.rst b/boards/arm64/qemu_cortex_a53/doc/index.rst index ad0d2d7cb5d..930671bb927 100644 --- a/boards/arm64/qemu_cortex_a53/doc/index.rst +++ b/boards/arm64/qemu_cortex_a53/doc/index.rst @@ -60,7 +60,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/arm64/xenvm/doc/index.rst b/boards/arm64/xenvm/doc/index.rst index f6ab7d121d1..bfeb319aaae 100644 --- a/boards/arm64/xenvm/doc/index.rst +++ b/boards/arm64/xenvm/doc/index.rst @@ -94,7 +94,7 @@ Building and Running ******************** Use this configuration to run basic Zephyr applications and kernel tests as Xen -guest, for example, with the :ref:`synchronization_sample`: +guest, for example, with the :zephyr:code-sample:`synchronization` sample: - if your hardware is based on GICv2: diff --git a/boards/mips/qemu_malta/doc/index.rst b/boards/mips/qemu_malta/doc/index.rst index 9ce6f383fd2..abca3138061 100644 --- a/boards/mips/qemu_malta/doc/index.rst +++ b/boards/mips/qemu_malta/doc/index.rst @@ -58,7 +58,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization @@ -90,7 +90,7 @@ Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. Big-Endian ========== -Use this configuration to run :ref:`synchronization_sample` in big-endian mode: +Use this configuration to run :zephyr:code-sample:`synchronization` sample in big-endian mode: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/nios2/qemu_nios2/doc/index.rst b/boards/nios2/qemu_nios2/doc/index.rst index cefa66c78fa..9dcef10a451 100644 --- a/boards/nios2/qemu_nios2/doc/index.rst +++ b/boards/nios2/qemu_nios2/doc/index.rst @@ -74,7 +74,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/riscv/longan_nano/doc/index.rst b/boards/riscv/longan_nano/doc/index.rst index dc4a204a9e7..c31abb6ec8f 100644 --- a/boards/riscv/longan_nano/doc/index.rst +++ b/boards/riscv/longan_nano/doc/index.rst @@ -84,7 +84,7 @@ Programming and debugging Building & Flashing =================== -Here is an example for building the :ref:`blinky-sample` application. +Here is an example for building the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky @@ -105,7 +105,7 @@ Debugging ========= You can debug an application in the usual way. Here is an example for the -:ref:`blinky-sample` application. +:zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky diff --git a/boards/riscv/qemu_riscv32/doc/index.rst b/boards/riscv/qemu_riscv32/doc/index.rst index f300f8e6068..cf33745e198 100644 --- a/boards/riscv/qemu_riscv32/doc/index.rst +++ b/boards/riscv/qemu_riscv32/doc/index.rst @@ -20,7 +20,7 @@ Flashing While this board is emulated and you can't "flash" it, you can use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment. For example, with the :ref:`synchronization_sample`: +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/riscv/qemu_riscv32e/doc/index.rst b/boards/riscv/qemu_riscv32e/doc/index.rst index 465b7428f50..15981f00c8e 100644 --- a/boards/riscv/qemu_riscv32e/doc/index.rst +++ b/boards/riscv/qemu_riscv32e/doc/index.rst @@ -20,7 +20,7 @@ Flashing While this board is emulated and you can't "flash" it, you can use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment. For example, with the :ref:`synchronization_sample`: +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/riscv/qemu_riscv64/doc/index.rst b/boards/riscv/qemu_riscv64/doc/index.rst index a0c55fa69a0..e58df91f679 100644 --- a/boards/riscv/qemu_riscv64/doc/index.rst +++ b/boards/riscv/qemu_riscv64/doc/index.rst @@ -29,7 +29,7 @@ Flashing While this board is emulated and you can't "flash" it, you can use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment. For example, with the :ref:`synchronization_sample`: +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/sparc/qemu_leon3/doc/index.rst b/boards/sparc/qemu_leon3/doc/index.rst index 156829d3728..4e0599697fd 100644 --- a/boards/sparc/qemu_leon3/doc/index.rst +++ b/boards/sparc/qemu_leon3/doc/index.rst @@ -20,7 +20,7 @@ Flashing While this board is emulated and you can't "flash" it, you can use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment. For example, with the :ref:`synchronization_sample`: +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/x86/qemu_x86/doc/index.rst b/boards/x86/qemu_x86/doc/index.rst index 3f06125b6eb..8589d73360f 100644 --- a/boards/x86/qemu_x86/doc/index.rst +++ b/boards/x86/qemu_x86/doc/index.rst @@ -79,7 +79,7 @@ Flashing While this board is emulated and you can't "flash" it, you can use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment. For example, with the :ref:`synchronization_sample`: +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/boards/xtensa/qemu_xtensa/doc/index.rst b/boards/xtensa/qemu_xtensa/doc/index.rst index 35f43ac59ae..1bc8b2b2ace 100644 --- a/boards/xtensa/qemu_xtensa/doc/index.rst +++ b/boards/xtensa/qemu_xtensa/doc/index.rst @@ -13,7 +13,7 @@ Programming and Debugging ************************* Use this configuration to run basic Zephyr applications and kernel tests in the QEMU -emulated environment, for example, with the :ref:`synchronization_sample`: +emulated environment, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization diff --git a/doc/build/dts/api-usage.rst b/doc/build/dts/api-usage.rst index 97949d86f67..b31c1e9baf3 100644 --- a/doc/build/dts/api-usage.rst +++ b/doc/build/dts/api-usage.rst @@ -47,7 +47,7 @@ By node label By alias Use :c:func:`DT_ALIAS()` to get a node identifier for a property of the special ``/aliases`` node. This is sometimes done by applications (like - :ref:`blinky `, which uses the ``led0`` alias) that need to + :zephyr:code-sample:`blinky`, which uses the ``led0`` alias) that need to refer to *some* device of a particular type ("the board's user LED") but don't care which one is used. diff --git a/doc/build/dts/design.rst b/doc/build/dts/design.rst index 82cfe652287..34d26cb7441 100644 --- a/doc/build/dts/design.rst +++ b/doc/build/dts/design.rst @@ -22,7 +22,7 @@ Examples - In-tree sample applications shall use :ref:`aliases ` to determine which of multiple possible generic devices of a given type will be - used in the current build. For example, the :ref:`blinky-sample` uses this to + used in the current build. For example, the :zephyr:code-sample:`blinky` sample uses this to determine the LED to blink. - Boot-time pin muxing and pin control for new SoCs shall be accomplished via a diff --git a/doc/build/dts/howtos.rst b/doc/build/dts/howtos.rst index f1a003f2f94..02580ad223d 100644 --- a/doc/build/dts/howtos.rst +++ b/doc/build/dts/howtos.rst @@ -630,6 +630,6 @@ Applications that depend on board-specific devices One way to allow application code to run unmodified on multiple boards is by supporting a devicetree alias to specify the hardware specific portions, as is -done in the :ref:`blinky-sample`. The application can then be configured in +done in the :zephyr:code-sample:`blinky` sample. The application can then be configured in :ref:`BOARD.dts ` files or via :ref:`devicetree overlays `. diff --git a/doc/build/dts/intro-syntax-structure.rst b/doc/build/dts/intro-syntax-structure.rst index 1a92215a1d9..8f5d3aa84d0 100644 --- a/doc/build/dts/intro-syntax-structure.rst +++ b/doc/build/dts/intro-syntax-structure.rst @@ -468,7 +468,7 @@ Using its node label ``uart0``, the same node is set as the value of the chosen Zephyr sample applications sometimes use aliases to allow overriding the particular hardware device used by the application in a generic way. For -example, :ref:`blinky-sample` uses this to abstract the LED to blink via the +example, :zephyr:code-sample:`blinky` uses this to abstract the LED to blink via the ``led0`` alias. The ``/chosen`` node's properties are used to configure system- or diff --git a/doc/build/kconfig/tips.rst b/doc/build/kconfig/tips.rst index 4deab152660..276157cdc08 100644 --- a/doc/build/kconfig/tips.rst +++ b/doc/build/kconfig/tips.rst @@ -83,7 +83,7 @@ An application-specific devicetree :ref:`binding ` to identify board specific properties may be appropriate. See :zephyr_file:`tests/drivers/gpio/gpio_basic_api` for an example. -For applications, see :ref:`blinky-sample` for a devicetree-based alternative. +For applications, see :zephyr:code-sample:`blinky` for a devicetree-based alternative. ``select`` statements ********************* diff --git a/doc/develop/beyond-GSG.rst b/doc/develop/beyond-GSG.rst index 13ea085ada0..41269c12634 100644 --- a/doc/develop/beyond-GSG.rst +++ b/doc/develop/beyond-GSG.rst @@ -184,7 +184,7 @@ Additional information about building applications can be found in the Build Blinky ============ -Let's build the :ref:`blinky-sample` sample application. +Let's build the :zephyr:code-sample:`blinky` sample application. Zephyr applications are built to run on specific hardware, called a "board"\ [#board_misnomer]_. We'll use the Phytec :ref:`reel_board diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 4a1b345ee62..ff97c093420 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -650,14 +650,14 @@ Build the Blinky Sample .. note:: - Blinky is compatible with most, but not all, :ref:`boards`. If your board + :zephyr:code-sample:`blinky` is compatible with most, but not all, :ref:`boards`. If your board does not meet Blinky's :ref:`blinky-sample-requirements`, then :ref:`hello_world` is a good alternative. If you are unsure what name west uses for your board, ``west boards`` can be used to obtain a list of all boards Zephyr supports. -Build the :ref:`blinky-sample` with :ref:`west build `, changing +Build the :zephyr:code-sample:`blinky` with :ref:`west build `, changing ```` appropriately for your board: .. tabs:: diff --git a/doc/services/tracing/index.rst b/doc/services/tracing/index.rst index 9c06c3d3fc8..48124416c8d 100644 --- a/doc/services/tracing/index.rst +++ b/doc/services/tracing/index.rst @@ -107,7 +107,7 @@ supported in Zephyr). To enable tracing support with `SEGGER SystemView`_ add the configuration option :kconfig:option:`CONFIG_SEGGER_SYSTEMVIEW` to your project configuration file and set it to *y*. For example, this can be added to the -:ref:`synchronization_sample` to visualize fast switching between threads. +:zephyr:code-sample:`synchronization` sample to visualize fast switching between threads. SystemView can also be used for post-mortem tracing, which can be enabled with `CONFIG_SEGGER_SYSVIEW_POST_MORTEM_MODE`. In this mode, a debugger can be attached after the system has crashed using ``west attach`` after which the diff --git a/samples/basic/blinky/README.rst b/samples/basic/blinky/README.rst index 22a1c96b9f7..893d00b5103 100644 --- a/samples/basic/blinky/README.rst +++ b/samples/basic/blinky/README.rst @@ -1,4 +1,4 @@ -.. zephyr:code-sample:: blinky-sample +.. zephyr:code-sample:: blinky :name: Blinky :relevant-api: gpio_interface @@ -16,7 +16,7 @@ The source code shows how to: #. Configure the GPIO pin as an output #. Toggle the pin forever -See :zephyr:code-sample:`pwm-blinky-sample` for a similar sample that uses the PWM API instead. +See :zephyr:code-sample:`pwm-blinky` for a similar sample that uses the PWM API instead. .. _blinky-sample-requirements: diff --git a/samples/basic/blinky_pwm/README.rst b/samples/basic/blinky_pwm/README.rst index 638b7597d27..f31c65982fb 100644 --- a/samples/basic/blinky_pwm/README.rst +++ b/samples/basic/blinky_pwm/README.rst @@ -1,4 +1,4 @@ -.. zephyr:code-sample:: pwm-blinky-sample +.. zephyr:code-sample:: pwm-blinky :name: PWM Blinky :relevant-api: pwm_interface @@ -8,7 +8,7 @@ Overview ******** This application blinks an LED using the :ref:`PWM API `. See -:zephyr:code-sample:`blinky-sample` for a GPIO-based sample. +:zephyr:code-sample:`blinky` for a GPIO-based sample. The LED starts blinking at a 1 Hz frequency. The frequency doubles every 4 seconds until it reaches 128 Hz. The frequency will then be halved every 4 diff --git a/samples/basic/button/README.rst b/samples/basic/button/README.rst index 3d487375df9..1989ff74c5d 100644 --- a/samples/basic/button/README.rst +++ b/samples/basic/button/README.rst @@ -1,4 +1,4 @@ -.. zephyr:code-sample:: button-sample +.. zephyr:code-sample:: button :name: Button :relevant-api: gpio_interface @@ -28,7 +28,7 @@ You may see additional build errors if the ``sw0`` alias exists, but is not properly defined. The sample additionally supports an optional ``led0`` devicetree alias. This is -the same alias used by the :zephyr:code-sample:`blinky-sample`. If this is provided, the LED +the same alias used by the :zephyr:code-sample:`blinky` sample. If this is provided, the LED will be turned on when the button is pressed, and turned off off when it is released. diff --git a/samples/basic/custom_dts_binding/README.rst b/samples/basic/custom_dts_binding/README.rst index d3edd890264..1a54cb5ef67 100644 --- a/samples/basic/custom_dts_binding/README.rst +++ b/samples/basic/custom_dts_binding/README.rst @@ -1,7 +1,8 @@ -.. _gpio-custom-dts-binding-sample: +.. zephyr:code-sample:: gpio-custom-dts-binding + :name: GPIO with custom Devicetree binding + :relevant-api: gpio_interface devicetree-generic-id devicetree-generic-exist -GPIO with custom devicetree binding -################################### + Use custom Devicetree binding to control a GPIO. Overview ******** diff --git a/samples/basic/fade_led/README.rst b/samples/basic/fade_led/README.rst index 5ea1a4cf732..4e855548704 100644 --- a/samples/basic/fade_led/README.rst +++ b/samples/basic/fade_led/README.rst @@ -1,7 +1,8 @@ -.. _fade-led-sample: +.. zephyr:code-sample:: fade-led + :name: Fade LED + :relevant-api: pwm_interface -Fade LED -######## + Fade an LED using the PWM API. Overview ******** @@ -18,7 +19,7 @@ Requirements and Wiring *********************** This sample has the same requirements and wiring considerations as the -:zephyr:code-sample:`pwm-blinky-sample`. +:zephyr:code-sample:`pwm-blinky` sample. Building and Running ******************** diff --git a/samples/basic/hash_map/README.rst b/samples/basic/hash_map/README.rst index 977a558e0c0..403ef297923 100644 --- a/samples/basic/hash_map/README.rst +++ b/samples/basic/hash_map/README.rst @@ -1,5 +1,5 @@ .. zephyr:code-sample:: system_hashmap - :name: System Hashmap + :name: System hashmap :relevant-api: hashmap_apis Insert, replace, and remove entries in a hashmap. @@ -7,7 +7,7 @@ Overview ******** -This is a simple example that repeatedly +This is a simple example that repeatedly: * inserts up to ``CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES`` * replaces up to the same number that were previously inserted diff --git a/samples/basic/minimal/README.rst b/samples/basic/minimal/README.rst index 1e4a2d7f70e..6021d80a1d7 100644 --- a/samples/basic/minimal/README.rst +++ b/samples/basic/minimal/README.rst @@ -1,7 +1,7 @@ -.. _minimal_sample: +.. zephyr:code-sample:: minimal + :name: Minimal footprint -Minimal footprint -################# + Measure Zephyr's minimal ROM footprint in different configurations. Overview ******** diff --git a/samples/basic/rgb_led/README.rst b/samples/basic/rgb_led/README.rst index 3f6a6b67862..11cc5d6e646 100644 --- a/samples/basic/rgb_led/README.rst +++ b/samples/basic/rgb_led/README.rst @@ -1,12 +1,13 @@ -.. _rgb-led-sample: +.. zephyr:code-sample:: rgb-led + :name: PWM RGB LED + :relevant-api: pwm_interface -PWM: RGB LED -############ + Drive an RGB LED using the PWM API. Overview ******** -This is a sample app which drives an RGB LED using PWM. +This is a sample app which drives an RGB LED using the :ref:`PWM API `. There are three single-color component LEDs in an RGB LED. Each component LED is driven by a PWM port where the pulse width is changed from zero to the period diff --git a/samples/basic/servo_motor/README.rst b/samples/basic/servo_motor/README.rst index dcfc7afabb8..e4f2e494196 100644 --- a/samples/basic/servo_motor/README.rst +++ b/samples/basic/servo_motor/README.rst @@ -1,12 +1,13 @@ -.. _servo-motor-sample: +.. zephyr:code-sample:: servo-motor + :name: Servomotor + :relevant-api: pwm_interface -Servomotor -########## + Drive a servomotor using the PWM API. Overview ******** -This is a sample app which drives a servomotor using PWM. +This is a sample app which drives a servomotor using the :ref:`PWM API `. The sample rotates a servomotor back and forth in the 180 degree range with a PWM control signal. diff --git a/samples/basic/sys_heap/README.rst b/samples/basic/sys_heap/README.rst index 335084a901f..2b124400cde 100644 --- a/samples/basic/sys_heap/README.rst +++ b/samples/basic/sys_heap/README.rst @@ -1,7 +1,7 @@ -.. _system_heap: +.. zephyr:code-sample:: sys-heap + :name: System heap -System heap -########### + Print system heap usage to the console. Overview ******** diff --git a/samples/basic/threads/README.rst b/samples/basic/threads/README.rst index fd47afad2f0..1ade8e9d360 100644 --- a/samples/basic/threads/README.rst +++ b/samples/basic/threads/README.rst @@ -1,7 +1,8 @@ -.. _96b_carbon_multi_thread_blinky: +.. zephyr:code-sample:: multi-thread-blinky + :name: Basic thread manipulation + :relevant-api: gpio_interface thread_apis -Basic Thread Example -#################### + Spawn multiple threads that blink LEDs and print information to the console. Overview ******** diff --git a/samples/bluetooth/encrypted_advertising/README.rst b/samples/bluetooth/encrypted_advertising/README.rst index 01e38890f32..5c107d8a634 100644 --- a/samples/bluetooth/encrypted_advertising/README.rst +++ b/samples/bluetooth/encrypted_advertising/README.rst @@ -25,8 +25,8 @@ Requirements ************ * Two boards with Bluetooth Low Energy support -* Two boards with a push button connected via a GPIO pin, see :zephyr:code-sample:`button-sample` - for more details +* Two boards with a push button connected via a GPIO pin, see the :zephyr:code-sample:`button` + sample for more details Building and Running ******************** diff --git a/samples/synchronization/README.rst b/samples/synchronization/README.rst index d67d93ec0b0..abb633b69e6 100644 --- a/samples/synchronization/README.rst +++ b/samples/synchronization/README.rst @@ -1,5 +1,5 @@ -.. zephyr:code-sample:: synchronization_sample - :name: Synchronization Sample +.. zephyr:code-sample:: synchronization + :name: Basic Synchronization :relevant-api: thread_apis semaphore_apis Manipulate basic kernel synchronization primitives. From fad29ecb03afe27f33457ec8f86f11b3090e79e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 12:21:21 +0200 Subject: [PATCH 0283/4498] doc: Code samples must be referenced using new dedicated role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop code that would let people reference samples using legacy :ref:`sample_id` syntax, and only support the use of :zephyr:code-sample:`sample_id` role going forward. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 769b1b8a73c..969eca33817 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -94,18 +94,6 @@ def convert_node(self, node): index = parent.index(node) siblings_to_move = parent.children[index + 1 :] - # TODO remove once all :ref:`sample-xyz` have migrated to :zephyr:code-sample:`xyz` - # as this is the recommended way to reference code samples going forward. - self.env.app.env.domaindata["std"]["labels"][node["id"]] = ( - self.env.docname, - node["id"], - node["name"], - ) - self.env.app.env.domaindata["std"]["anonlabels"][node["id"]] = ( - self.env.docname, - node["id"], - ) - # Create a new section new_section = nodes.section(ids=[node["id"]]) new_section += nodes.title(text=node["name"]) From f8398fda0220412d87b0daf1dd9b1f8deb43435d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 12:47:54 +0200 Subject: [PATCH 0284/4498] doc: css: fix text color for toggle buttons in related samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missed this usability issue earlier. This makes the text and icon in collapsible admonition the same color as the admonition title. Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 30d8607f9dc..711edd9936f 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -552,6 +552,7 @@ a.internal:visited code.literal { .rst-content .admonition.toggle button { display: inline-flex; + color: var(--admonition-note-title-color); } .rst-content .admonition.toggle .tb-icon { From dbbdd3c6cfe05ac45c2f1028f07696b23a85c8f6 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Mon, 11 Sep 2023 11:49:52 -0500 Subject: [PATCH 0285/4498] drivers: wdt_mcux_wwdt: Fix warning callback Warning callback by default is configured to happen at the same time as reset, which results in unexpected behavior from the point of view of Zephyr API. Return -ENOTSUP from install_timeout if trying to set up callback with 0 warning time, and add kconfig to configure the warning time. Signed-off-by: Declan Snyder --- drivers/watchdog/Kconfig.mcux | 12 ++++++++++++ drivers/watchdog/wdt_mcux_wwdt.c | 11 +++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/Kconfig.mcux b/drivers/watchdog/Kconfig.mcux index 805aae1cb32..c4b5a4d7fdd 100644 --- a/drivers/watchdog/Kconfig.mcux +++ b/drivers/watchdog/Kconfig.mcux @@ -25,3 +25,15 @@ config WDT_MCUX_WWDT depends on DT_HAS_NXP_LPC_WWDT_ENABLED help Enable the mcux wwdt driver. + +if WDT_MCUX_WWDT + +config WDT_MCUX_WWDT_WARNING_INTERRUPT_CFG + int "WWDT timeout warning interrupt configuration" + range 0 1023 + default 0 + help + WWDT timeout warning interrupt time. The units are + the number of watchdog counter ticks before timeout. + +endif # WDT_MCUX_WWDT diff --git a/drivers/watchdog/wdt_mcux_wwdt.c b/drivers/watchdog/wdt_mcux_wwdt.c index cef55b320a5..0181b3d406f 100644 --- a/drivers/watchdog/wdt_mcux_wwdt.c +++ b/drivers/watchdog/wdt_mcux_wwdt.c @@ -69,7 +69,7 @@ static int mcux_wwdt_disable(const struct device *dev) * This prescaler is different from the clock divider specified in Device Tree. */ #define MSEC_TO_WWDT_TICKS(clock_freq, msec) \ - ((uint32_t)(clock_freq * msec / MSEC_PER_SEC / 4)) + ((uint32_t)((clock_freq / MSEC_PER_SEC) * msec) / 4) static int mcux_wwdt_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) @@ -115,7 +115,14 @@ static int mcux_wwdt_install_timeout(const struct device *dev, LOG_DBG("Enabling SoC reset"); } - data->callback = cfg->callback; + if (cfg->callback && (CONFIG_WDT_MCUX_WWDT_WARNING_INTERRUPT_CFG > 0)) { + data->callback = cfg->callback; + data->wwdt_config.warningValue = CONFIG_WDT_MCUX_WWDT_WARNING_INTERRUPT_CFG; + } else if (cfg->callback) { + return -ENOTSUP; + } + + data->timeout_valid = true; LOG_DBG("Installed timeout (timeoutValue = %d)", data->wwdt_config.timeoutValue); From f03acea3e8c8b57f56b3eb31fe2770d4f0aeef1c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 12:16:52 +0100 Subject: [PATCH 0286/4498] boards: arm: stm32f411e_disco: Add flash partitions Adds flash partitions so that MCUboot can be used with this board Signed-off-by: Jamie McCrae --- .../arm/stm32f411e_disco/stm32f411e_disco.dts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts index bd4d425c5bc..eb5f8058a56 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts @@ -18,6 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds { @@ -160,3 +161,32 @@ zephyr_udc0: &usbotg_fs { pinctrl-names = "default"; status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 DT_SIZE_K(128)>; + }; + + slot1_partition: partition@40000 { + label = "image-1"; + reg = <0x00040000 DT_SIZE_K(128)>; + }; + + scratch_partition: partition@60000 { + label = "image-scratch"; + reg = <0x00060000 DT_SIZE_K(128)>; + }; + }; +}; From f970bf10fafa4e8e0e4717e86e05e1fd7a3361ff Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 12:18:06 +0100 Subject: [PATCH 0287/4498] boards: arm: stm32f411e_disco: Add MCUboot LED/button defines Adds the user button and orange LED for use with MCUboot to enter serial recovery and indicate when in this mode Signed-off-by: Jamie McCrae --- boards/arm/stm32f411e_disco/stm32f411e_disco.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts index eb5f8058a56..9255f496c0d 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts @@ -78,6 +78,8 @@ pwm-led3 = &blue_pwm_led; magn0 = &lsm303agr_magn; accel0 = &lsm303agr_accel; + mcuboot-button0 = &user_button; + mcuboot-led0 = &orange_led_3; }; }; From 0a5e5b68ffc345f464ae2097e5d4aaf169dd675c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 12:18:50 +0100 Subject: [PATCH 0288/4498] boards: arm: stm32f411e_disco: Add MCUmgr UART chosen node Adds a chosen node for MCUmgr UART Signed-off-by: Jamie McCrae --- boards/arm/stm32f411e_disco/stm32f411e_disco.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts index 9255f496c0d..11a65534b4a 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts @@ -16,6 +16,7 @@ chosen { zephyr,console = &usart2; zephyr,shell-uart = &usart2; + zephyr,uart-mcumgr = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; From 07ece0cb1dfa9a1aaf7af3fe94792cc3b7572fa0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 12:24:15 +0100 Subject: [PATCH 0289/4498] boards: arm: stm32f411e_disco: Fix button level Fixes the button to have the correct polarity for when it is pressed. Signed-off-by: Jamie McCrae --- boards/arm/stm32f411e_disco/stm32f411e_disco.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts index 11a65534b4a..197df98212d 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts @@ -62,7 +62,7 @@ compatible = "gpio-keys"; user_button: button { label = "User"; - gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; zephyr,code = ; }; }; From f6a9fc12025264f010eee4200bb4fd34a6a07e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Mon, 11 Sep 2023 15:47:39 +0200 Subject: [PATCH 0290/4498] Bluetooth: Mesh: add optional OOB info to ext scan report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though the OOB information is optional we can add it to extended scan reports in cases there is detected unprovisoned devices. Referring to MshPRT section 4.4.5.3: When the Remote Provisioning Extended Scan procedure completes without receiving an advertisement from the unprovisioned device, the OOBInformation and AdvStructures fields shall be skipped. When the obtained data is empty, the AdvStructures field shall be skipped. The Status field shall be set to Success. and referring to MshPRT section 4.3.4.9: The OOBInformation field contains the OOB Information of either the unprovisioned device or the Remote Provisioning Server. Signed-off-by: Alperen Şener --- subsys/bluetooth/mesh/rpr_srv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index b38bec4cd40..c8639d8b514 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -267,13 +267,15 @@ static void scan_ext_report_send(void) bt_mesh_model_msg_init(&buf, RPR_OP_EXTENDED_SCAN_REPORT); net_buf_simple_add_u8(&buf, BT_MESH_RPR_SUCCESS); net_buf_simple_add_mem(&buf, srv.scan.dev->uuid, 16); - if (!(srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND)) { + + if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND) { + net_buf_simple_add_le16(&buf, srv.scan.dev->oob); + } else { LOG_DBG("not found"); goto send; } if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD) { - net_buf_simple_add_le16(&buf, srv.scan.dev->oob); net_buf_simple_add_mem(&buf, srv.scan.adv_data->data, srv.scan.adv_data->len); LOG_DBG("adv data: %s", From df41deac1cdb46b96c4d1653ef70a44b345e431e Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 4 Jul 2023 14:21:40 +0800 Subject: [PATCH 0291/4498] arch: arm: Remove aarch32 directory It doesn't make sense to keep the aarch32 directory in the 'arch/arm/core' directory as the aarch64 has been moved out. This commit introduces the following major changes. 1. Move all directories and files in 'arch/arm/core/aarch32' to 'arch/arm/core' and remove the 'arch/arm/core/aarch32' directory. 2. Move all directories and files in 'arch/include/aarch32' to 'arch/include' and remove the 'arch/include/aarch32' directory. 3. Remove the nested including in the 'arch/include/kernel_arch_func.h' and 'arch/include/offsets_short_arch.h' header files. 4. Change the path string which is influenced by the changement 1 and 2. Signed-off-by: Huifeng Zhang --- CODEOWNERS | 6 +- arch/arm/CMakeLists.txt | 2 +- arch/arm/Kconfig | 4 +- arch/arm/core/{aarch32 => }/CMakeLists.txt | 2 +- arch/arm/core/{aarch32 => }/Kconfig | 0 arch/arm/core/{aarch32 => }/Kconfig.vfp | 0 arch/arm/core/{aarch32 => }/__aeabi_atexit.c | 0 .../{aarch32 => }/cortex_a_r/CMakeLists.txt | 0 .../arm/core/{aarch32 => }/cortex_a_r/Kconfig | 0 .../cortex_a_r/__aeabi_read_tp.S | 0 .../arm/core/{aarch32 => }/cortex_a_r/cache.c | 0 arch/arm/core/{aarch32 => }/cortex_a_r/exc.S | 0 .../core/{aarch32 => }/cortex_a_r/exc_exit.S | 0 .../arm/core/{aarch32 => }/cortex_a_r/fault.c | 0 .../core/{aarch32 => }/cortex_a_r/irq_init.c | 0 .../core/{aarch32 => }/cortex_a_r/reboot.c | 0 .../arm/core/{aarch32 => }/cortex_a_r/reset.S | 2 +- .../core/{aarch32 => }/cortex_a_r/semihost.c | 0 .../core/{aarch32 => }/cortex_a_r/stacks.c | 2 +- arch/arm/core/{aarch32 => }/cortex_a_r/tcm.c | 0 .../core/{aarch32 => }/cortex_a_r/thread.c | 0 .../{aarch32 => }/cortex_a_r/vector_table.S | 0 .../{aarch32 => }/cortex_a_r/vector_table.h | 0 .../{aarch32 => }/cortex_m/CMakeLists.txt | 0 arch/arm/core/{aarch32 => }/cortex_m/Kconfig | 0 .../{aarch32 => }/cortex_m/__aeabi_read_tp.S | 0 arch/arm/core/{aarch32 => }/cortex_m/cache.c | 0 .../cortex_m/cmse/CMakeLists.txt | 0 .../cortex_m/cmse/arm_core_cmse.c | 2 +- .../core/{aarch32 => }/cortex_m/coredump.c | 0 arch/arm/core/{aarch32 => }/cortex_m/debug.c | 2 +- .../core/{aarch32 => }/cortex_m/exc_exit.S | 0 arch/arm/core/{aarch32 => }/cortex_m/fault.c | 0 .../arm/core/{aarch32 => }/cortex_m/fault_s.S | 0 arch/arm/core/{aarch32 => }/cortex_m/fpu.c | 0 .../core/{aarch32 => }/cortex_m/irq_init.c | 0 .../core/{aarch32 => }/cortex_m/pm_s2ram.S | 0 .../core/{aarch32 => }/cortex_m/pm_s2ram.c | 0 .../cortex_m/relay_vector_table.ld | 0 arch/arm/core/{aarch32 => }/cortex_m/reset.S | 0 arch/arm/core/{aarch32 => }/cortex_m/scb.c | 0 .../core/{aarch32 => }/cortex_m/semihost.c | 0 arch/arm/core/{aarch32 => }/cortex_m/thread.c | 0 .../{aarch32 => }/cortex_m/thread_abort.c | 0 arch/arm/core/{aarch32 => }/cortex_m/timing.c | 2 +- .../{aarch32 => }/cortex_m/tz/CMakeLists.txt | 0 .../core/{aarch32 => }/cortex_m/tz/Kconfig | 0 .../{aarch32 => }/cortex_m/tz/arm_core_tz.c | 4 +- .../cortex_m/tz/secure_entry_functions.ld | 0 .../{aarch32 => }/cortex_m/vector_table.S | 0 .../{aarch32 => }/cortex_m/vector_table.h | 0 .../cortex_m/vector_table_pad.ld | 0 .../cortex_m/vt_pointer_section.ld | 0 arch/arm/core/{aarch32 => }/cpu_idle.S | 0 arch/arm/core/{aarch32 => }/fatal.c | 0 arch/arm/core/{aarch32 => }/header.S | 0 arch/arm/core/{aarch32 => }/irq_manage.c | 2 +- arch/arm/core/{aarch32 => }/irq_offload.c | 0 arch/arm/core/{aarch32 => }/irq_relay.S | 0 arch/arm/core/{aarch32 => }/isr_wrapper.S | 0 .../arm/core/{aarch32 => }/mmu/CMakeLists.txt | 0 arch/arm/core/{aarch32 => }/mmu/Kconfig | 0 arch/arm/core/{aarch32 => }/mmu/arm_mmu.c | 0 .../arm/core/{aarch32 => }/mmu/arm_mmu_priv.h | 0 .../arm/core/{aarch32 => }/mpu/CMakeLists.txt | 0 arch/arm/core/{aarch32 => }/mpu/Kconfig | 0 .../arm/core/{aarch32 => }/mpu/arm_core_mpu.c | 0 .../core/{aarch32 => }/mpu/arm_core_mpu_dev.h | 0 arch/arm/core/{aarch32 => }/mpu/arm_mpu.c | 0 .../{aarch32 => }/mpu/arm_mpu_v7_internal.h | 0 .../{aarch32 => }/mpu/arm_mpu_v8_internal.h | 2 +- .../mpu/cortex_a_r/arm_mpu_internal.h | 0 .../mpu/cortex_m/arm_mpu_internal.h | 0 arch/arm/core/{aarch32 => }/mpu/nxp_mpu.c | 0 arch/arm/core/{aarch32 => }/nmi.c | 0 arch/arm/core/{aarch32 => }/nmi_on_reset.S | 0 arch/arm/core/{aarch32 => }/prep_c.c | 2 +- arch/arm/core/{aarch32 => }/swap.c | 0 arch/arm/core/{aarch32 => }/swap_helper.S | 0 arch/arm/core/{aarch32 => }/thread.c | 0 arch/arm/core/{common => }/tls.c | 0 arch/arm/core/{aarch32 => }/userspace.S | 0 arch/arm/core/{aarch32 => }/vector_table.ld | 0 arch/arm/core/{aarch32 => }/zimage_header.ld | 0 arch/arm/include/aarch32/kernel_arch_func.h | 93 ------------------- arch/arm/include/aarch32/offsets_short_arch.h | 57 ------------ .../include/{aarch32 => }/cortex_a_r/exc.h | 0 .../include/{aarch32 => }/cortex_a_r/stack.h | 0 .../include/{aarch32 => }/cortex_a_r/tcm.h | 0 .../arm/include/{aarch32 => }/cortex_m/cmse.h | 0 arch/arm/include/{aarch32 => }/cortex_m/dwt.h | 0 arch/arm/include/{aarch32 => }/cortex_m/exc.h | 0 .../include/{aarch32 => }/cortex_m/stack.h | 0 arch/arm/include/{aarch32 => }/cortex_m/tz.h | 0 .../include/{aarch32 => }/cortex_m/tz_ns.h | 0 arch/arm/include/kernel_arch_data.h | 8 +- arch/arm/include/kernel_arch_func.h | 82 +++++++++++++++- arch/arm/include/offsets_short_arch.h | 47 +++++++++- doc/hardware/arch/arm_cortex_m.rst | 4 +- doc/hardware/porting/arch.rst | 4 +- include/zephyr/arch/arm/aarch32/irq.h | 2 +- .../zephyr/linker/irq-vector-table-section.ld | 2 +- samples/philosophers/README.rst | 32 +++---- soc/arm/nxp_imx/rt6xx/soc.c | 2 +- soc/arm/nxp_lpc/lpc54xxx/soc.c | 3 +- soc/arm/nxp_lpc/lpc55xxx/soc.c | 2 +- .../arm_irq_vector_table/irq-vector-table.ld | 2 +- tests/arch/arm/arm_tz_wrap_func/src/main.c | 2 +- 108 files changed, 176 insertions(+), 200 deletions(-) rename arch/arm/core/{aarch32 => }/CMakeLists.txt (95%) rename arch/arm/core/{aarch32 => }/Kconfig (100%) rename arch/arm/core/{aarch32 => }/Kconfig.vfp (100%) rename arch/arm/core/{aarch32 => }/__aeabi_atexit.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/Kconfig (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/__aeabi_read_tp.S (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/cache.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/exc.S (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/exc_exit.S (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/fault.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/irq_init.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/reboot.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/reset.S (99%) rename arch/arm/core/{aarch32 => }/cortex_a_r/semihost.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/stacks.c (96%) rename arch/arm/core/{aarch32 => }/cortex_a_r/tcm.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/thread.c (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/vector_table.S (100%) rename arch/arm/core/{aarch32 => }/cortex_a_r/vector_table.h (100%) rename arch/arm/core/{aarch32 => }/cortex_m/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/cortex_m/Kconfig (100%) rename arch/arm/core/{aarch32 => }/cortex_m/__aeabi_read_tp.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/cache.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/cmse/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/cortex_m/cmse/arm_core_cmse.c (99%) rename arch/arm/core/{aarch32 => }/cortex_m/coredump.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/debug.c (99%) rename arch/arm/core/{aarch32 => }/cortex_m/exc_exit.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/fault.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/fault_s.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/fpu.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/irq_init.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/pm_s2ram.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/pm_s2ram.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/relay_vector_table.ld (100%) rename arch/arm/core/{aarch32 => }/cortex_m/reset.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/scb.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/semihost.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/thread.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/thread_abort.c (100%) rename arch/arm/core/{aarch32 => }/cortex_m/timing.c (98%) rename arch/arm/core/{aarch32 => }/cortex_m/tz/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/cortex_m/tz/Kconfig (100%) rename arch/arm/core/{aarch32 => }/cortex_m/tz/arm_core_tz.c (98%) rename arch/arm/core/{aarch32 => }/cortex_m/tz/secure_entry_functions.ld (100%) rename arch/arm/core/{aarch32 => }/cortex_m/vector_table.S (100%) rename arch/arm/core/{aarch32 => }/cortex_m/vector_table.h (100%) rename arch/arm/core/{aarch32 => }/cortex_m/vector_table_pad.ld (100%) rename arch/arm/core/{aarch32 => }/cortex_m/vt_pointer_section.ld (100%) rename arch/arm/core/{aarch32 => }/cpu_idle.S (100%) rename arch/arm/core/{aarch32 => }/fatal.c (100%) rename arch/arm/core/{aarch32 => }/header.S (100%) rename arch/arm/core/{aarch32 => }/irq_manage.c (99%) rename arch/arm/core/{aarch32 => }/irq_offload.c (100%) rename arch/arm/core/{aarch32 => }/irq_relay.S (100%) rename arch/arm/core/{aarch32 => }/isr_wrapper.S (100%) rename arch/arm/core/{aarch32 => }/mmu/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/mmu/Kconfig (100%) rename arch/arm/core/{aarch32 => }/mmu/arm_mmu.c (100%) rename arch/arm/core/{aarch32 => }/mmu/arm_mmu_priv.h (100%) rename arch/arm/core/{aarch32 => }/mpu/CMakeLists.txt (100%) rename arch/arm/core/{aarch32 => }/mpu/Kconfig (100%) rename arch/arm/core/{aarch32 => }/mpu/arm_core_mpu.c (100%) rename arch/arm/core/{aarch32 => }/mpu/arm_core_mpu_dev.h (100%) rename arch/arm/core/{aarch32 => }/mpu/arm_mpu.c (100%) rename arch/arm/core/{aarch32 => }/mpu/arm_mpu_v7_internal.h (100%) rename arch/arm/core/{aarch32 => }/mpu/arm_mpu_v8_internal.h (99%) rename arch/arm/core/{aarch32 => }/mpu/cortex_a_r/arm_mpu_internal.h (100%) rename arch/arm/core/{aarch32 => }/mpu/cortex_m/arm_mpu_internal.h (100%) rename arch/arm/core/{aarch32 => }/mpu/nxp_mpu.c (100%) rename arch/arm/core/{aarch32 => }/nmi.c (100%) rename arch/arm/core/{aarch32 => }/nmi_on_reset.S (100%) rename arch/arm/core/{aarch32 => }/prep_c.c (99%) rename arch/arm/core/{aarch32 => }/swap.c (100%) rename arch/arm/core/{aarch32 => }/swap_helper.S (100%) rename arch/arm/core/{aarch32 => }/thread.c (100%) rename arch/arm/core/{common => }/tls.c (100%) rename arch/arm/core/{aarch32 => }/userspace.S (100%) rename arch/arm/core/{aarch32 => }/vector_table.ld (100%) rename arch/arm/core/{aarch32 => }/zimage_header.ld (100%) delete mode 100644 arch/arm/include/aarch32/kernel_arch_func.h delete mode 100644 arch/arm/include/aarch32/offsets_short_arch.h rename arch/arm/include/{aarch32 => }/cortex_a_r/exc.h (100%) rename arch/arm/include/{aarch32 => }/cortex_a_r/stack.h (100%) rename arch/arm/include/{aarch32 => }/cortex_a_r/tcm.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/cmse.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/dwt.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/exc.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/stack.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/tz.h (100%) rename arch/arm/include/{aarch32 => }/cortex_m/tz_ns.h (100%) diff --git a/CODEOWNERS b/CODEOWNERS index 81ae75325d9..e84d013e9f7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,9 +18,9 @@ /MAINTAINERS.yml @MaureenHelm /arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev /arch/arm/ @MaureenHelm @galak @ioannisg -/arch/arm/core/aarch32/cortex_m/cmse/ @ioannisg -/arch/arm/include/aarch32/cortex_m/cmse.h @ioannisg -/arch/arm/core/aarch32/cortex_a_r/ @MaureenHelm @galak @ioannisg @bbolen @stephanosio +/arch/arm/core/cortex_m/cmse/ @ioannisg +/arch/arm/include/cortex_m/cmse.h @ioannisg +/arch/arm/core/cortex_a_r/ @MaureenHelm @galak @ioannisg @bbolen @stephanosio /arch/arm64/ @carlocaione /arch/arm64/core/cortex_r/ @povergoing /arch/arm64/core/xen/ @lorc @firscity diff --git a/arch/arm/CMakeLists.txt b/arch/arm/CMakeLists.txt index 14c831b9120..5aa25f20396 100644 --- a/arch/arm/CMakeLists.txt +++ b/arch/arm/CMakeLists.txt @@ -2,4 +2,4 @@ set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-littlearm) -add_subdirectory(core/aarch32) +add_subdirectory(core) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e17cf3f9b31..da1878c740c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -69,7 +69,7 @@ config ARM_ON_EXIT_CPU_IDLE observed on some SoCs caused by a memory access following WFI/WFE instructions. -rsource "core/aarch32/Kconfig" -rsource "core/aarch32/Kconfig.vfp" +rsource "core/Kconfig" +rsource "core/Kconfig.vfp" endmenu diff --git a/arch/arm/core/aarch32/CMakeLists.txt b/arch/arm/core/CMakeLists.txt similarity index 95% rename from arch/arm/core/aarch32/CMakeLists.txt rename to arch/arm/core/CMakeLists.txt index 00bc7693cda..e64958471a1 100644 --- a/arch/arm/core/aarch32/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -18,7 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_CPP __aeabi_atexit.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S) -zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE ../common/tls.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_ARM_ZIMAGE_HEADER header.S) diff --git a/arch/arm/core/aarch32/Kconfig b/arch/arm/core/Kconfig similarity index 100% rename from arch/arm/core/aarch32/Kconfig rename to arch/arm/core/Kconfig diff --git a/arch/arm/core/aarch32/Kconfig.vfp b/arch/arm/core/Kconfig.vfp similarity index 100% rename from arch/arm/core/aarch32/Kconfig.vfp rename to arch/arm/core/Kconfig.vfp diff --git a/arch/arm/core/aarch32/__aeabi_atexit.c b/arch/arm/core/__aeabi_atexit.c similarity index 100% rename from arch/arm/core/aarch32/__aeabi_atexit.c rename to arch/arm/core/__aeabi_atexit.c diff --git a/arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt rename to arch/arm/core/cortex_a_r/CMakeLists.txt diff --git a/arch/arm/core/aarch32/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/Kconfig rename to arch/arm/core/cortex_a_r/Kconfig diff --git a/arch/arm/core/aarch32/cortex_a_r/__aeabi_read_tp.S b/arch/arm/core/cortex_a_r/__aeabi_read_tp.S similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/__aeabi_read_tp.S rename to arch/arm/core/cortex_a_r/__aeabi_read_tp.S diff --git a/arch/arm/core/aarch32/cortex_a_r/cache.c b/arch/arm/core/cortex_a_r/cache.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/cache.c rename to arch/arm/core/cortex_a_r/cache.c diff --git a/arch/arm/core/aarch32/cortex_a_r/exc.S b/arch/arm/core/cortex_a_r/exc.S similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/exc.S rename to arch/arm/core/cortex_a_r/exc.S diff --git a/arch/arm/core/aarch32/cortex_a_r/exc_exit.S b/arch/arm/core/cortex_a_r/exc_exit.S similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/exc_exit.S rename to arch/arm/core/cortex_a_r/exc_exit.S diff --git a/arch/arm/core/aarch32/cortex_a_r/fault.c b/arch/arm/core/cortex_a_r/fault.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/fault.c rename to arch/arm/core/cortex_a_r/fault.c diff --git a/arch/arm/core/aarch32/cortex_a_r/irq_init.c b/arch/arm/core/cortex_a_r/irq_init.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/irq_init.c rename to arch/arm/core/cortex_a_r/irq_init.c diff --git a/arch/arm/core/aarch32/cortex_a_r/reboot.c b/arch/arm/core/cortex_a_r/reboot.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/reboot.c rename to arch/arm/core/cortex_a_r/reboot.c diff --git a/arch/arm/core/aarch32/cortex_a_r/reset.S b/arch/arm/core/cortex_a_r/reset.S similarity index 99% rename from arch/arm/core/aarch32/cortex_a_r/reset.S rename to arch/arm/core/cortex_a_r/reset.S index 32d1dc468df..c72f0814c7a 100644 --- a/arch/arm/core/aarch32/cortex_a_r/reset.S +++ b/arch/arm/core/cortex_a_r/reset.S @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "vector_table.h" _ASM_FILE_PROLOGUE diff --git a/arch/arm/core/aarch32/cortex_a_r/semihost.c b/arch/arm/core/cortex_a_r/semihost.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/semihost.c rename to arch/arm/core/cortex_a_r/semihost.c diff --git a/arch/arm/core/aarch32/cortex_a_r/stacks.c b/arch/arm/core/cortex_a_r/stacks.c similarity index 96% rename from arch/arm/core/aarch32/cortex_a_r/stacks.c rename to arch/arm/core/cortex_a_r/stacks.c index 7f98deec9cb..29a5062e299 100644 --- a/arch/arm/core/aarch32/cortex_a_r/stacks.c +++ b/arch/arm/core/cortex_a_r/stacks.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/arch/arm/core/aarch32/cortex_a_r/tcm.c b/arch/arm/core/cortex_a_r/tcm.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/tcm.c rename to arch/arm/core/cortex_a_r/tcm.c diff --git a/arch/arm/core/aarch32/cortex_a_r/thread.c b/arch/arm/core/cortex_a_r/thread.c similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/thread.c rename to arch/arm/core/cortex_a_r/thread.c diff --git a/arch/arm/core/aarch32/cortex_a_r/vector_table.S b/arch/arm/core/cortex_a_r/vector_table.S similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/vector_table.S rename to arch/arm/core/cortex_a_r/vector_table.S diff --git a/arch/arm/core/aarch32/cortex_a_r/vector_table.h b/arch/arm/core/cortex_a_r/vector_table.h similarity index 100% rename from arch/arm/core/aarch32/cortex_a_r/vector_table.h rename to arch/arm/core/cortex_a_r/vector_table.h diff --git a/arch/arm/core/aarch32/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/cortex_m/CMakeLists.txt rename to arch/arm/core/cortex_m/CMakeLists.txt diff --git a/arch/arm/core/aarch32/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig similarity index 100% rename from arch/arm/core/aarch32/cortex_m/Kconfig rename to arch/arm/core/cortex_m/Kconfig diff --git a/arch/arm/core/aarch32/cortex_m/__aeabi_read_tp.S b/arch/arm/core/cortex_m/__aeabi_read_tp.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/__aeabi_read_tp.S rename to arch/arm/core/cortex_m/__aeabi_read_tp.S diff --git a/arch/arm/core/aarch32/cortex_m/cache.c b/arch/arm/core/cortex_m/cache.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/cache.c rename to arch/arm/core/cortex_m/cache.c diff --git a/arch/arm/core/aarch32/cortex_m/cmse/CMakeLists.txt b/arch/arm/core/cortex_m/cmse/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/cortex_m/cmse/CMakeLists.txt rename to arch/arm/core/cortex_m/cmse/CMakeLists.txt diff --git a/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c b/arch/arm/core/cortex_m/cmse/arm_core_cmse.c similarity index 99% rename from arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c rename to arch/arm/core/cortex_m/cmse/arm_core_cmse.c index 7ddab21d547..aac96472ecf 100644 --- a/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c +++ b/arch/arm/core/cortex_m/cmse/arm_core_cmse.c @@ -5,7 +5,7 @@ */ #include -#include +#include int arm_cmse_mpu_region_get(uint32_t addr) { diff --git a/arch/arm/core/aarch32/cortex_m/coredump.c b/arch/arm/core/cortex_m/coredump.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/coredump.c rename to arch/arm/core/cortex_m/coredump.c diff --git a/arch/arm/core/aarch32/cortex_m/debug.c b/arch/arm/core/cortex_m/debug.c similarity index 99% rename from arch/arm/core/aarch32/cortex_m/debug.c rename to arch/arm/core/cortex_m/debug.c index 70394b2d361..8d83cd07f2f 100644 --- a/arch/arm/core/aarch32/cortex_m/debug.c +++ b/arch/arm/core/cortex_m/debug.c @@ -12,7 +12,7 @@ #include #include -#include +#include /** * @brief Assess whether a debug monitor event should be treated as an error diff --git a/arch/arm/core/aarch32/cortex_m/exc_exit.S b/arch/arm/core/cortex_m/exc_exit.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/exc_exit.S rename to arch/arm/core/cortex_m/exc_exit.S diff --git a/arch/arm/core/aarch32/cortex_m/fault.c b/arch/arm/core/cortex_m/fault.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/fault.c rename to arch/arm/core/cortex_m/fault.c diff --git a/arch/arm/core/aarch32/cortex_m/fault_s.S b/arch/arm/core/cortex_m/fault_s.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/fault_s.S rename to arch/arm/core/cortex_m/fault_s.S diff --git a/arch/arm/core/aarch32/cortex_m/fpu.c b/arch/arm/core/cortex_m/fpu.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/fpu.c rename to arch/arm/core/cortex_m/fpu.c diff --git a/arch/arm/core/aarch32/cortex_m/irq_init.c b/arch/arm/core/cortex_m/irq_init.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/irq_init.c rename to arch/arm/core/cortex_m/irq_init.c diff --git a/arch/arm/core/aarch32/cortex_m/pm_s2ram.S b/arch/arm/core/cortex_m/pm_s2ram.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/pm_s2ram.S rename to arch/arm/core/cortex_m/pm_s2ram.S diff --git a/arch/arm/core/aarch32/cortex_m/pm_s2ram.c b/arch/arm/core/cortex_m/pm_s2ram.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/pm_s2ram.c rename to arch/arm/core/cortex_m/pm_s2ram.c diff --git a/arch/arm/core/aarch32/cortex_m/relay_vector_table.ld b/arch/arm/core/cortex_m/relay_vector_table.ld similarity index 100% rename from arch/arm/core/aarch32/cortex_m/relay_vector_table.ld rename to arch/arm/core/cortex_m/relay_vector_table.ld diff --git a/arch/arm/core/aarch32/cortex_m/reset.S b/arch/arm/core/cortex_m/reset.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/reset.S rename to arch/arm/core/cortex_m/reset.S diff --git a/arch/arm/core/aarch32/cortex_m/scb.c b/arch/arm/core/cortex_m/scb.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/scb.c rename to arch/arm/core/cortex_m/scb.c diff --git a/arch/arm/core/aarch32/cortex_m/semihost.c b/arch/arm/core/cortex_m/semihost.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/semihost.c rename to arch/arm/core/cortex_m/semihost.c diff --git a/arch/arm/core/aarch32/cortex_m/thread.c b/arch/arm/core/cortex_m/thread.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/thread.c rename to arch/arm/core/cortex_m/thread.c diff --git a/arch/arm/core/aarch32/cortex_m/thread_abort.c b/arch/arm/core/cortex_m/thread_abort.c similarity index 100% rename from arch/arm/core/aarch32/cortex_m/thread_abort.c rename to arch/arm/core/cortex_m/thread_abort.c diff --git a/arch/arm/core/aarch32/cortex_m/timing.c b/arch/arm/core/cortex_m/timing.c similarity index 98% rename from arch/arm/core/aarch32/cortex_m/timing.c rename to arch/arm/core/cortex_m/timing.c index 2e2912487f8..861f1a9995a 100644 --- a/arch/arm/core/aarch32/cortex_m/timing.c +++ b/arch/arm/core/cortex_m/timing.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/core/aarch32/cortex_m/tz/CMakeLists.txt b/arch/arm/core/cortex_m/tz/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/cortex_m/tz/CMakeLists.txt rename to arch/arm/core/cortex_m/tz/CMakeLists.txt diff --git a/arch/arm/core/aarch32/cortex_m/tz/Kconfig b/arch/arm/core/cortex_m/tz/Kconfig similarity index 100% rename from arch/arm/core/aarch32/cortex_m/tz/Kconfig rename to arch/arm/core/cortex_m/tz/Kconfig diff --git a/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c b/arch/arm/core/cortex_m/tz/arm_core_tz.c similarity index 98% rename from arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c rename to arch/arm/core/cortex_m/tz/arm_core_tz.c index 1a316be7265..8371a08bfef 100644 --- a/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c +++ b/arch/arm/core/cortex_m/tz/arm_core_tz.c @@ -5,8 +5,8 @@ */ #include -#include -#include +#include +#include static void configure_nonsecure_vtor_offset(uint32_t vtor_ns) { diff --git a/arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld b/arch/arm/core/cortex_m/tz/secure_entry_functions.ld similarity index 100% rename from arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld rename to arch/arm/core/cortex_m/tz/secure_entry_functions.ld diff --git a/arch/arm/core/aarch32/cortex_m/vector_table.S b/arch/arm/core/cortex_m/vector_table.S similarity index 100% rename from arch/arm/core/aarch32/cortex_m/vector_table.S rename to arch/arm/core/cortex_m/vector_table.S diff --git a/arch/arm/core/aarch32/cortex_m/vector_table.h b/arch/arm/core/cortex_m/vector_table.h similarity index 100% rename from arch/arm/core/aarch32/cortex_m/vector_table.h rename to arch/arm/core/cortex_m/vector_table.h diff --git a/arch/arm/core/aarch32/cortex_m/vector_table_pad.ld b/arch/arm/core/cortex_m/vector_table_pad.ld similarity index 100% rename from arch/arm/core/aarch32/cortex_m/vector_table_pad.ld rename to arch/arm/core/cortex_m/vector_table_pad.ld diff --git a/arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld b/arch/arm/core/cortex_m/vt_pointer_section.ld similarity index 100% rename from arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld rename to arch/arm/core/cortex_m/vt_pointer_section.ld diff --git a/arch/arm/core/aarch32/cpu_idle.S b/arch/arm/core/cpu_idle.S similarity index 100% rename from arch/arm/core/aarch32/cpu_idle.S rename to arch/arm/core/cpu_idle.S diff --git a/arch/arm/core/aarch32/fatal.c b/arch/arm/core/fatal.c similarity index 100% rename from arch/arm/core/aarch32/fatal.c rename to arch/arm/core/fatal.c diff --git a/arch/arm/core/aarch32/header.S b/arch/arm/core/header.S similarity index 100% rename from arch/arm/core/aarch32/header.S rename to arch/arm/core/header.S diff --git a/arch/arm/core/aarch32/irq_manage.c b/arch/arm/core/irq_manage.c similarity index 99% rename from arch/arm/core/aarch32/irq_manage.c rename to arch/arm/core/irq_manage.c index 6ad5adf7cda..6f6a590b44a 100644 --- a/arch/arm/core/aarch32/irq_manage.c +++ b/arch/arm/core/irq_manage.c @@ -174,7 +174,7 @@ void _arch_isr_direct_pm(void) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* Lock all interrupts. irq_lock() will on this CPU only disable those * lower than BASEPRI, which is not what we want. See comments in - * arch/arm/core/aarch32/isr_wrapper.S + * arch/arm/core/isr_wrapper.S */ __asm__ volatile("cpsid i" : : : "memory"); #else diff --git a/arch/arm/core/aarch32/irq_offload.c b/arch/arm/core/irq_offload.c similarity index 100% rename from arch/arm/core/aarch32/irq_offload.c rename to arch/arm/core/irq_offload.c diff --git a/arch/arm/core/aarch32/irq_relay.S b/arch/arm/core/irq_relay.S similarity index 100% rename from arch/arm/core/aarch32/irq_relay.S rename to arch/arm/core/irq_relay.S diff --git a/arch/arm/core/aarch32/isr_wrapper.S b/arch/arm/core/isr_wrapper.S similarity index 100% rename from arch/arm/core/aarch32/isr_wrapper.S rename to arch/arm/core/isr_wrapper.S diff --git a/arch/arm/core/aarch32/mmu/CMakeLists.txt b/arch/arm/core/mmu/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/mmu/CMakeLists.txt rename to arch/arm/core/mmu/CMakeLists.txt diff --git a/arch/arm/core/aarch32/mmu/Kconfig b/arch/arm/core/mmu/Kconfig similarity index 100% rename from arch/arm/core/aarch32/mmu/Kconfig rename to arch/arm/core/mmu/Kconfig diff --git a/arch/arm/core/aarch32/mmu/arm_mmu.c b/arch/arm/core/mmu/arm_mmu.c similarity index 100% rename from arch/arm/core/aarch32/mmu/arm_mmu.c rename to arch/arm/core/mmu/arm_mmu.c diff --git a/arch/arm/core/aarch32/mmu/arm_mmu_priv.h b/arch/arm/core/mmu/arm_mmu_priv.h similarity index 100% rename from arch/arm/core/aarch32/mmu/arm_mmu_priv.h rename to arch/arm/core/mmu/arm_mmu_priv.h diff --git a/arch/arm/core/aarch32/mpu/CMakeLists.txt b/arch/arm/core/mpu/CMakeLists.txt similarity index 100% rename from arch/arm/core/aarch32/mpu/CMakeLists.txt rename to arch/arm/core/mpu/CMakeLists.txt diff --git a/arch/arm/core/aarch32/mpu/Kconfig b/arch/arm/core/mpu/Kconfig similarity index 100% rename from arch/arm/core/aarch32/mpu/Kconfig rename to arch/arm/core/mpu/Kconfig diff --git a/arch/arm/core/aarch32/mpu/arm_core_mpu.c b/arch/arm/core/mpu/arm_core_mpu.c similarity index 100% rename from arch/arm/core/aarch32/mpu/arm_core_mpu.c rename to arch/arm/core/mpu/arm_core_mpu.c diff --git a/arch/arm/core/aarch32/mpu/arm_core_mpu_dev.h b/arch/arm/core/mpu/arm_core_mpu_dev.h similarity index 100% rename from arch/arm/core/aarch32/mpu/arm_core_mpu_dev.h rename to arch/arm/core/mpu/arm_core_mpu_dev.h diff --git a/arch/arm/core/aarch32/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c similarity index 100% rename from arch/arm/core/aarch32/mpu/arm_mpu.c rename to arch/arm/core/mpu/arm_mpu.c diff --git a/arch/arm/core/aarch32/mpu/arm_mpu_v7_internal.h b/arch/arm/core/mpu/arm_mpu_v7_internal.h similarity index 100% rename from arch/arm/core/aarch32/mpu/arm_mpu_v7_internal.h rename to arch/arm/core/mpu/arm_mpu_v7_internal.h diff --git a/arch/arm/core/aarch32/mpu/arm_mpu_v8_internal.h b/arch/arm/core/mpu/arm_mpu_v8_internal.h similarity index 99% rename from arch/arm/core/aarch32/mpu/arm_mpu_v8_internal.h rename to arch/arm/core/mpu/arm_mpu_v8_internal.h index dd5e7f94bfb..1f7cb04839e 100644 --- a/arch/arm/core/aarch32/mpu/arm_mpu_v8_internal.h +++ b/arch/arm/core/mpu/arm_mpu_v8_internal.h @@ -8,7 +8,7 @@ #ifndef ZEPHYR_ARCH_ARM_CORE_AARCH32_MPU_ARM_MPU_V8_INTERNAL_H_ #define ZEPHYR_ARCH_ARM_CORE_AARCH32_MPU_ARM_MPU_V8_INTERNAL_H_ -#include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include #include diff --git a/arch/arm/core/aarch32/mpu/cortex_a_r/arm_mpu_internal.h b/arch/arm/core/mpu/cortex_a_r/arm_mpu_internal.h similarity index 100% rename from arch/arm/core/aarch32/mpu/cortex_a_r/arm_mpu_internal.h rename to arch/arm/core/mpu/cortex_a_r/arm_mpu_internal.h diff --git a/arch/arm/core/aarch32/mpu/cortex_m/arm_mpu_internal.h b/arch/arm/core/mpu/cortex_m/arm_mpu_internal.h similarity index 100% rename from arch/arm/core/aarch32/mpu/cortex_m/arm_mpu_internal.h rename to arch/arm/core/mpu/cortex_m/arm_mpu_internal.h diff --git a/arch/arm/core/aarch32/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c similarity index 100% rename from arch/arm/core/aarch32/mpu/nxp_mpu.c rename to arch/arm/core/mpu/nxp_mpu.c diff --git a/arch/arm/core/aarch32/nmi.c b/arch/arm/core/nmi.c similarity index 100% rename from arch/arm/core/aarch32/nmi.c rename to arch/arm/core/nmi.c diff --git a/arch/arm/core/aarch32/nmi_on_reset.S b/arch/arm/core/nmi_on_reset.S similarity index 100% rename from arch/arm/core/aarch32/nmi_on_reset.S rename to arch/arm/core/nmi_on_reset.S diff --git a/arch/arm/core/aarch32/prep_c.c b/arch/arm/core/prep_c.c similarity index 99% rename from arch/arm/core/aarch32/prep_c.c rename to arch/arm/core/prep_c.c index 80765dd7f4f..c10acd17b6c 100644 --- a/arch/arm/core/aarch32/prep_c.c +++ b/arch/arm/core/prep_c.c @@ -26,7 +26,7 @@ #endif #if defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A) -#include +#include #endif #if defined(__GNUC__) diff --git a/arch/arm/core/aarch32/swap.c b/arch/arm/core/swap.c similarity index 100% rename from arch/arm/core/aarch32/swap.c rename to arch/arm/core/swap.c diff --git a/arch/arm/core/aarch32/swap_helper.S b/arch/arm/core/swap_helper.S similarity index 100% rename from arch/arm/core/aarch32/swap_helper.S rename to arch/arm/core/swap_helper.S diff --git a/arch/arm/core/aarch32/thread.c b/arch/arm/core/thread.c similarity index 100% rename from arch/arm/core/aarch32/thread.c rename to arch/arm/core/thread.c diff --git a/arch/arm/core/common/tls.c b/arch/arm/core/tls.c similarity index 100% rename from arch/arm/core/common/tls.c rename to arch/arm/core/tls.c diff --git a/arch/arm/core/aarch32/userspace.S b/arch/arm/core/userspace.S similarity index 100% rename from arch/arm/core/aarch32/userspace.S rename to arch/arm/core/userspace.S diff --git a/arch/arm/core/aarch32/vector_table.ld b/arch/arm/core/vector_table.ld similarity index 100% rename from arch/arm/core/aarch32/vector_table.ld rename to arch/arm/core/vector_table.ld diff --git a/arch/arm/core/aarch32/zimage_header.ld b/arch/arm/core/zimage_header.ld similarity index 100% rename from arch/arm/core/aarch32/zimage_header.ld rename to arch/arm/core/zimage_header.ld diff --git a/arch/arm/include/aarch32/kernel_arch_func.h b/arch/arm/include/aarch32/kernel_arch_func.h deleted file mode 100644 index 08f4a6d92b5..00000000000 --- a/arch/arm/include/aarch32/kernel_arch_func.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Private kernel definitions (ARM) - * - * This file contains private kernel function definitions and various - * other definitions for the 32-bit ARM Cortex-A/R/M processor architecture - * family. - * - * This file is also included by assembly language files which must #define - * _ASMLANGUAGE before including this header file. Note that kernel - * assembly source files obtains structure offset values via "absolute symbols" - * in the offsets.o module. - */ - -#ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_KERNEL_ARCH_FUNC_H_ -#define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_KERNEL_ARCH_FUNC_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ASMLANGUAGE -extern void z_arm_fault_init(void); -extern void z_arm_cpu_idle_init(void); -#ifdef CONFIG_ARM_MPU -extern void z_arm_configure_static_mpu_regions(void); -extern void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread); -extern int z_arm_mpu_init(void); -#endif /* CONFIG_ARM_MPU */ -#ifdef CONFIG_ARM_AARCH32_MMU -extern int z_arm_mmu_init(void); -#endif /* CONFIG_ARM_AARCH32_MMU */ - -static ALWAYS_INLINE void arch_kernel_init(void) -{ - z_arm_interrupt_stack_setup(); - z_arm_exc_setup(); - z_arm_fault_init(); - z_arm_cpu_idle_init(); - z_arm_clear_faults(); -#if defined(CONFIG_ARM_MPU) - z_arm_mpu_init(); - /* Configure static memory map. This will program MPU regions, - * to set up access permissions for fixed memory sections, such - * as Application Memory or No-Cacheable SRAM area. - * - * This function is invoked once, upon system initialization. - */ - z_arm_configure_static_mpu_regions(); -#endif /* CONFIG_ARM_MPU */ -#if defined(CONFIG_ARM_AARCH32_MMU) - z_arm_mmu_init(); -#endif /* CONFIG_ARM_AARCH32_MMU */ -} - -static ALWAYS_INLINE void -arch_thread_return_value_set(struct k_thread *thread, unsigned int value) -{ - thread->arch.swap_return_value = value; -} - -#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) -extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( - k_thread_entry_t main_func, - void *p1, void *p2, void *p3); - -#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ - z_arm_switch_to_main_no_multithreading - -#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ - -extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3, - uint32_t stack_end, - uint32_t stack_start); - -extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); - -#endif /* _ASMLANGUAGE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/arm/include/aarch32/offsets_short_arch.h b/arch/arm/include/aarch32/offsets_short_arch.h deleted file mode 100644 index 5f41a7fe195..00000000000 --- a/arch/arm/include/aarch32/offsets_short_arch.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_OFFSETS_SHORT_ARCH_H_ -#define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_OFFSETS_SHORT_ARCH_H_ - -#include - -/* kernel */ - -/* nothing for now */ - -/* end - kernel */ - -/* threads */ - -#define _thread_offset_to_basepri \ - (___thread_t_arch_OFFSET + ___thread_arch_t_basepri_OFFSET) - -#define _thread_offset_to_preempt_float \ - (___thread_t_arch_OFFSET + ___thread_arch_t_preempt_float_OFFSET) - -#if defined(CONFIG_USERSPACE) || defined(CONFIG_FPU_SHARING) -#define _thread_offset_to_mode \ - (___thread_t_arch_OFFSET + ___thread_arch_t_mode_OFFSET) -#endif - -#if defined(CONFIG_ARM_STORE_EXC_RETURN) -#define _thread_offset_to_mode_exc_return \ - (___thread_t_arch_OFFSET + ___thread_arch_t_mode_exc_return_OFFSET) -#endif - -#ifdef CONFIG_USERSPACE -#define _thread_offset_to_priv_stack_start \ - (___thread_t_arch_OFFSET + ___thread_arch_t_priv_stack_start_OFFSET) - -#if defined(CONFIG_CPU_AARCH32_CORTEX_R) -#define _thread_offset_to_priv_stack_end \ - (___thread_t_arch_OFFSET + ___thread_arch_t_priv_stack_end_OFFSET) - -#define _thread_offset_to_sp_usr \ - (___thread_t_arch_OFFSET + ___thread_arch_t_sp_usr_OFFSET) -#endif -#endif - -#if defined(CONFIG_THREAD_STACK_INFO) -#define _thread_offset_to_stack_info_start \ - (___thread_stack_info_t_start_OFFSET + ___thread_t_stack_info_OFFSET) -#endif - - -/* end - threads */ - -#endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_OFFSETS_SHORT_ARCH_H_ */ diff --git a/arch/arm/include/aarch32/cortex_a_r/exc.h b/arch/arm/include/cortex_a_r/exc.h similarity index 100% rename from arch/arm/include/aarch32/cortex_a_r/exc.h rename to arch/arm/include/cortex_a_r/exc.h diff --git a/arch/arm/include/aarch32/cortex_a_r/stack.h b/arch/arm/include/cortex_a_r/stack.h similarity index 100% rename from arch/arm/include/aarch32/cortex_a_r/stack.h rename to arch/arm/include/cortex_a_r/stack.h diff --git a/arch/arm/include/aarch32/cortex_a_r/tcm.h b/arch/arm/include/cortex_a_r/tcm.h similarity index 100% rename from arch/arm/include/aarch32/cortex_a_r/tcm.h rename to arch/arm/include/cortex_a_r/tcm.h diff --git a/arch/arm/include/aarch32/cortex_m/cmse.h b/arch/arm/include/cortex_m/cmse.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/cmse.h rename to arch/arm/include/cortex_m/cmse.h diff --git a/arch/arm/include/aarch32/cortex_m/dwt.h b/arch/arm/include/cortex_m/dwt.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/dwt.h rename to arch/arm/include/cortex_m/dwt.h diff --git a/arch/arm/include/aarch32/cortex_m/exc.h b/arch/arm/include/cortex_m/exc.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/exc.h rename to arch/arm/include/cortex_m/exc.h diff --git a/arch/arm/include/aarch32/cortex_m/stack.h b/arch/arm/include/cortex_m/stack.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/stack.h rename to arch/arm/include/cortex_m/stack.h diff --git a/arch/arm/include/aarch32/cortex_m/tz.h b/arch/arm/include/cortex_m/tz.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/tz.h rename to arch/arm/include/cortex_m/tz.h diff --git a/arch/arm/include/aarch32/cortex_m/tz_ns.h b/arch/arm/include/cortex_m/tz_ns.h similarity index 100% rename from arch/arm/include/aarch32/cortex_m/tz_ns.h rename to arch/arm/include/cortex_m/tz_ns.h diff --git a/arch/arm/include/kernel_arch_data.h b/arch/arm/include/kernel_arch_data.h index 832e4b1042c..6ae5f643341 100644 --- a/arch/arm/include/kernel_arch_data.h +++ b/arch/arm/include/kernel_arch_data.h @@ -25,11 +25,11 @@ #include #if defined(CONFIG_CPU_CORTEX_M) -#include -#include +#include +#include #elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) -#include -#include +#include +#include #endif #ifndef _ASMLANGUAGE diff --git a/arch/arm/include/kernel_arch_func.h b/arch/arm/include/kernel_arch_func.h index b680da356f8..de1a1f83b4a 100644 --- a/arch/arm/include/kernel_arch_func.h +++ b/arch/arm/include/kernel_arch_func.h @@ -3,10 +3,90 @@ * * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Private kernel definitions (ARM) + * + * This file contains private kernel function definitions and various + * other definitions for the 32-bit ARM Cortex-A/R/M processor architecture + * family. + * + * This file is also included by assembly language files which must #define + * _ASMLANGUAGE before including this header file. Note that kernel + * assembly source files obtains structure offset values via "absolute symbols" + * in the offsets.o module. + */ #ifndef ZEPHYR_ARCH_ARM_INCLUDE_KERNEL_ARCH_FUNC_H_ #define ZEPHYR_ARCH_ARM_INCLUDE_KERNEL_ARCH_FUNC_H_ -#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE +extern void z_arm_fault_init(void); +extern void z_arm_cpu_idle_init(void); +#ifdef CONFIG_ARM_MPU +extern void z_arm_configure_static_mpu_regions(void); +extern void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread); +extern int z_arm_mpu_init(void); +#endif /* CONFIG_ARM_MPU */ +#ifdef CONFIG_ARM_AARCH32_MMU +extern int z_arm_mmu_init(void); +#endif /* CONFIG_ARM_AARCH32_MMU */ + +static ALWAYS_INLINE void arch_kernel_init(void) +{ + z_arm_interrupt_stack_setup(); + z_arm_exc_setup(); + z_arm_fault_init(); + z_arm_cpu_idle_init(); + z_arm_clear_faults(); +#if defined(CONFIG_ARM_MPU) + z_arm_mpu_init(); + /* Configure static memory map. This will program MPU regions, + * to set up access permissions for fixed memory sections, such + * as Application Memory or No-Cacheable SRAM area. + * + * This function is invoked once, upon system initialization. + */ + z_arm_configure_static_mpu_regions(); +#endif /* CONFIG_ARM_MPU */ +#if defined(CONFIG_ARM_AARCH32_MMU) + z_arm_mmu_init(); +#endif /* CONFIG_ARM_AARCH32_MMU */ +} + +static ALWAYS_INLINE void +arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +{ + thread->arch.swap_return_value = value; +} + +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) +extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( + k_thread_entry_t main_func, + void *p1, void *p2, void *p3); + +#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ + z_arm_switch_to_main_no_multithreading + +#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ + +extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3, + uint32_t stack_end, + uint32_t stack_start); + +extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); + +#endif /* _ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif #endif /* ZEPHYR_ARCH_ARM_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/arm/include/offsets_short_arch.h b/arch/arm/include/offsets_short_arch.h index f09f24a72f6..78a2607655c 100644 --- a/arch/arm/include/offsets_short_arch.h +++ b/arch/arm/include/offsets_short_arch.h @@ -7,6 +7,51 @@ #ifndef ZEPHYR_ARCH_ARM_INCLUDE_OFFSETS_SHORT_ARCH_H_ #define ZEPHYR_ARCH_ARM_INCLUDE_OFFSETS_SHORT_ARCH_H_ -#include +#include + +/* kernel */ + +/* nothing for now */ + +/* end - kernel */ + +/* threads */ + +#define _thread_offset_to_basepri \ + (___thread_t_arch_OFFSET + ___thread_arch_t_basepri_OFFSET) + +#define _thread_offset_to_preempt_float \ + (___thread_t_arch_OFFSET + ___thread_arch_t_preempt_float_OFFSET) + +#if defined(CONFIG_USERSPACE) || defined(CONFIG_FPU_SHARING) +#define _thread_offset_to_mode \ + (___thread_t_arch_OFFSET + ___thread_arch_t_mode_OFFSET) +#endif + +#if defined(CONFIG_ARM_STORE_EXC_RETURN) +#define _thread_offset_to_mode_exc_return \ + (___thread_t_arch_OFFSET + ___thread_arch_t_mode_exc_return_OFFSET) +#endif + +#ifdef CONFIG_USERSPACE +#define _thread_offset_to_priv_stack_start \ + (___thread_t_arch_OFFSET + ___thread_arch_t_priv_stack_start_OFFSET) + +#if defined(CONFIG_CPU_AARCH32_CORTEX_R) +#define _thread_offset_to_priv_stack_end \ + (___thread_t_arch_OFFSET + ___thread_arch_t_priv_stack_end_OFFSET) + +#define _thread_offset_to_sp_usr \ + (___thread_t_arch_OFFSET + ___thread_arch_t_sp_usr_OFFSET) +#endif +#endif + +#if defined(CONFIG_THREAD_STACK_INFO) +#define _thread_offset_to_stack_info_start \ + (___thread_stack_info_t_start_OFFSET + ___thread_t_stack_info_OFFSET) +#endif + + +/* end - threads */ #endif /* ZEPHYR_ARCH_ARM_INCLUDE_OFFSETS_SHORT_ARCH_H_ */ diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 1e70b10cc8c..4f0454e994e 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -169,7 +169,7 @@ PendSV exception return sequence restores the new thread's caller-saved register return address, as part of unstacking the exception stack frame. The implementation of the context-switch mechanism is present in -:file:`arch/arm/core/aarch32/swap_helper.S`. +:file:`arch/arm/core/swap_helper.S`. Stack limit checking (Arm v8-M) ------------------------------- @@ -337,7 +337,7 @@ CPU Idling The Cortex-M architecture port implements both k_cpu_idle() and k_cpu_atomic_idle(). The implementation is present in -:file:`arch/arm/core/aarch32/cpu_idle.S`. +:file:`arch/arm/core/cpu_idle.S`. In both implementations, the processor will attempt to put the core to low power mode. diff --git a/doc/hardware/porting/arch.rst b/doc/hardware/porting/arch.rst index 8b9e96503b2..a4e1e753cff 100644 --- a/doc/hardware/porting/arch.rst +++ b/doc/hardware/porting/arch.rst @@ -160,7 +160,7 @@ we strongly suggest that handlers at least print some debug information. The information helps figuring out what went wrong when hitting an exception that is a fault, like divide-by-zero or invalid memory access, or an interrupt that is not expected (:dfn:`spurious interrupt`). See the ARM implementation in -:zephyr_file:`arch/arm/core/aarch32/cortex_m/fault.c` for an example. +:zephyr_file:`arch/arm/core/cortex_m/fault.c` for an example. Thread Context Switching ************************ @@ -299,7 +299,7 @@ gracefully exits its entry point function. This means implementing an architecture-specific version of :c:func:`k_thread_abort`, and setting the Kconfig option :kconfig:option:`CONFIG_ARCH_HAS_THREAD_ABORT` as needed for the architecture (e.g. see -:zephyr_file:`arch/arm/core/aarch32/cortex_m/Kconfig`). +:zephyr_file:`arch/arm/core/cortex_m/Kconfig`). Thread Local Storage ******************** diff --git a/include/zephyr/arch/arm/aarch32/irq.h b/include/zephyr/arch/arm/aarch32/irq.h index 5edcd1af4b2..aafc56a19a7 100644 --- a/include/zephyr/arch/arm/aarch32/irq.h +++ b/include/zephyr/arch/arm/aarch32/irq.h @@ -149,7 +149,7 @@ extern void _arch_isr_direct_pm(void); #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap) -/* arch/arm/core/aarch32/exc_exit.S */ +/* arch/arm/core/exc_exit.S */ extern void z_arm_int_exit(void); #ifdef CONFIG_TRACING_ISR diff --git a/include/zephyr/linker/irq-vector-table-section.ld b/include/zephyr/linker/irq-vector-table-section.ld index af4da725706..17c483db98f 100644 --- a/include/zephyr/linker/irq-vector-table-section.ld +++ b/include/zephyr/linker/irq-vector-table-section.ld @@ -6,6 +6,6 @@ KEEP(*(_IRQ_VECTOR_TABLE_SECTION_SYMS)) /* * Some ARM platforms require this symbol to be placed after the IRQ vector * table (like STM32F0). The symbol defined here is overriding the one in - * arch/arm/core/aarch32/vector_table.ld when the IRQ vector table is enbled. + * arch/arm/core/vector_table.ld when the IRQ vector table is enbled. */ _vector_end = .; diff --git a/samples/philosophers/README.rst b/samples/philosophers/README.rst index fbf3ff96f3e..77c07cba670 100644 --- a/samples/philosophers/README.rst +++ b/samples/philosophers/README.rst @@ -86,23 +86,23 @@ OpenOCD Sample Output Thread 1 received signal SIGINT, Interrupt. [Switching to Thread 537003160] - arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107 + arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/cpu_idle.S:107 107 cpsie i (gdb) i threads Id Target Id Frame - * 1 Thread 537003160 (Name: idle 00, prio:40,useropts:1) arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107 + * 1 Thread 537003160 (Name: idle 00, prio:40,useropts:1) arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/cpu_idle.S:107 Info : Getting thread 537002984 reg list - 2 Thread 537002984 (Name: Philosopher 5, prio:-2,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 2 Thread 537002984 (Name: Philosopher 5, prio:-2,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 Info : Getting thread 537002808 reg list - 3 Thread 537002808 (Name: Philosopher 4, prio:-1,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 3 Thread 537002808 (Name: Philosopher 4, prio:-1,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 Info : Getting thread 537002632 reg list - 4 Thread 537002632 (Name: Philosopher 3, prio:0,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 4 Thread 537002632 (Name: Philosopher 3, prio:0,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 Info : Getting thread 537002456 reg list - 5 Thread 537002456 (Name: Philosopher 2, prio:1,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 5 Thread 537002456 (Name: Philosopher 2, prio:1,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 Info : Getting thread 537002280 reg list - 6 Thread 537002280 (Name: Philosopher 1, prio:2,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 6 Thread 537002280 (Name: Philosopher 1, prio:2,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 Info : Getting thread 537002104 reg list - 7 Thread 537002104 (Name: Philosopher 0, prio:3,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95 + 7 Thread 537002104 (Name: Philosopher 0, prio:3,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/asm_inline_gcc.h:95 .. code-block:: console @@ -121,17 +121,17 @@ J-Link Sample Output Thread 2 received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 537920592] - arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107 + arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/cpu_idle.S:107 107 cpsie i (gdb) i threads Id Target Id Frame - * 2 Thread 537920592 (idle 00 UNKNOWN PRIO 40) arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107 - 3 Thread 537919536 (Philosopher 0 PENDING PRIO 3) arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 - 4 Thread 537919712 (Philosopher 1 SUSPENDED PRIO 2) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 - 5 Thread 537919888 (Philosopher 2 SUSPENDED PRIO 1) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 - 6 Thread 537920064 (Philosopher 3 SUSPENDED PRIO 0) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 - 7 Thread 537920240 (Philosopher 4 PENDING PRIO 255) arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 - 8 Thread 537920416 (Philosopher 5 SUSPENDED PRIO 254) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53 + * 2 Thread 537920592 (idle 00 UNKNOWN PRIO 40) arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/cpu_idle.S:107 + 3 Thread 537919536 (Philosopher 0 PENDING PRIO 3) arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 + 4 Thread 537919712 (Philosopher 1 SUSPENDED PRIO 2) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 + 5 Thread 537919888 (Philosopher 2 SUSPENDED PRIO 1) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 + 6 Thread 537920064 (Philosopher 3 SUSPENDED PRIO 0) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 + 7 Thread 537920240 (Philosopher 4 PENDING PRIO 255) arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 + 8 Thread 537920416 (Philosopher 5 SUSPENDED PRIO 254) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/swap.c:53 .. code-block:: console diff --git a/soc/arm/nxp_imx/rt6xx/soc.c b/soc/arm/nxp_imx/rt6xx/soc.c index 8ba2aa9dcec..e04499b289d 100644 --- a/soc/arm/nxp_imx/rt6xx/soc.c +++ b/soc/arm/nxp_imx/rt6xx/soc.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/soc/arm/nxp_lpc/lpc54xxx/soc.c b/soc/arm/nxp_lpc/lpc54xxx/soc.c index df7e5ac1c06..bbc689dbc68 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc54xxx/soc.c @@ -18,7 +18,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 8f756b39c3d..a16b5c959f0 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/arch/arm/arm_irq_vector_table/irq-vector-table.ld b/tests/arch/arm/arm_irq_vector_table/irq-vector-table.ld index 833b94a26b0..5f25268a2c7 100644 --- a/tests/arch/arm/arm_irq_vector_table/irq-vector-table.ld +++ b/tests/arch/arm/arm_irq_vector_table/irq-vector-table.ld @@ -5,6 +5,6 @@ KEEP(*(_IRQ_VECTOR_TABLE_SECTION_SYMS)) /* * Some ARM platforms require this symbol to be placed after the IRQ vector * table (like STM32F0). The symbol defined here is overriding the one in - * arch/arm/core/aarch32/vector_table.ld when the IRQ vector table is enabled. + * arch/arm/core/vector_table.ld when the IRQ vector table is enabled. */ _vector_end = .; diff --git a/tests/arch/arm/arm_tz_wrap_func/src/main.c b/tests/arch/arm/arm_tz_wrap_func/src/main.c index 0323bd50617..407873f906b 100644 --- a/tests/arch/arm/arm_tz_wrap_func/src/main.c +++ b/tests/arch/arm/arm_tz_wrap_func/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include static bool expect_preface; From 2c22e83dfb787bba0e27ee6a7caf99bee3362d82 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 4 Jul 2023 16:01:39 +0800 Subject: [PATCH 0292/4498] include: arch: arm: Remove aarch32 directory This commit follows the parent commit work. This commit introduces the following major changes. 1. Move all directories and files in 'include/zephyr/arch/arm/aarch32' to the 'include/zephyr/arch/arm' directory. 2. Change the path string which is influenced by the changement 1. Signed-off-by: Huifeng Zhang --- CODEOWNERS | 6 ++-- MAINTAINERS.yml | 1 - arch/arm/core/cortex_m/fpu.c | 2 +- arch/arm/core/mmu/arm_mmu.c | 2 +- arch/arm/core/prep_c.c | 2 +- arch/arm/core/swap_helper.S | 2 +- arch/arm/core/userspace.S | 2 +- arch/arm/include/cortex_m/exc.h | 2 +- boards/arm/ip_k66f/linker.ld | 2 +- doc/hardware/arch/arm_cortex_m.rst | 4 +-- doc/kernel/code-relocation.rst | 2 +- doc/kernel/usermode/memory_domain.rst | 2 +- drivers/interrupt_controller/intc_vim.c | 2 +- drivers/watchdog/wdt_cmsdk_apb.c | 2 +- drivers/watchdog/wdt_smartbond.c | 2 +- include/zephyr/arch/arch_inlines.h | 2 +- include/zephyr/arch/arm/{aarch32 => }/arch.h | 34 +++++++++---------- .../arch/arm/{aarch32 => }/arch_inlines.h | 0 .../arch/arm/{aarch32 => }/asm_inline.h | 2 +- .../arch/arm/{aarch32 => }/asm_inline_gcc.h | 4 +-- .../zephyr/arch/arm/{aarch32 => }/barrier.h | 0 .../{aarch32 => }/cortex_a_r/armv8_timer.h | 0 .../arch/arm/{aarch32 => }/cortex_a_r/cmsis.h | 0 .../arch/arm/{aarch32 => }/cortex_a_r/cpu.h | 2 +- .../{aarch32 => }/cortex_a_r/lib_helpers.h | 0 .../arch/arm/{aarch32 => }/cortex_a_r/mpu.h | 0 .../cortex_a_r/scripts/app_data_alignment.ld | 0 .../cortex_a_r/scripts/linker.ld | 0 .../arm/{aarch32 => }/cortex_a_r/sys_io.h | 0 .../arch/arm/{aarch32 => }/cortex_a_r/timer.h | 0 .../{aarch32 => }/cortex_m/arm_mpu_mem_cfg.h | 2 +- .../arch/arm/{aarch32 => }/cortex_m/cmsis.h | 0 .../arch/arm/{aarch32 => }/cortex_m/cpu.h | 0 .../arch/arm/{aarch32 => }/cortex_m/fpu.h | 0 .../arm/{aarch32 => }/cortex_m/memory_map.h | 0 .../arch/arm/{aarch32 => }/cortex_m/nvic.h | 0 .../{aarch32 => }/cortex_m/scripts/linker.ld | 0 .../cortex_r/scripts/app_data_alignment.ld | 0 .../{aarch32 => }/cortex_r/scripts/linker.ld | 2 +- include/zephyr/arch/arm/{aarch32 => }/error.h | 4 +-- include/zephyr/arch/arm/{aarch32 => }/exc.h | 2 +- include/zephyr/arch/arm/{aarch32 => }/irq.h | 0 include/zephyr/arch/arm/{aarch32 => }/misc.h | 0 .../arch/arm/{aarch32 => }/mmu/arm_mmu.h | 0 .../arch/arm/{aarch32 => }/mpu/arm_mpu.h | 4 +-- .../arch/arm/{aarch32 => }/mpu/arm_mpu_v7m.h | 0 .../arch/arm/{aarch32 => }/mpu/arm_mpu_v8.h | 0 .../arch/arm/{aarch32 => }/mpu/nxp_mpu.h | 0 include/zephyr/arch/arm/{aarch32 => }/nmi.h | 0 .../zephyr/arch/arm/{aarch32 => }/syscall.h | 2 +- .../zephyr/arch/arm/{aarch32 => }/thread.h | 0 include/zephyr/arch/cpu.h | 2 +- include/zephyr/arch/syscall.h | 2 +- include/zephyr/sys/barrier.h | 2 +- modules/cmsis/cmsis_core_m.h | 2 +- .../trusted-firmware-m/interface/interface.c | 2 +- .../linker_arm_nocopy.ld | 2 +- samples/subsys/debug/debugmon/src/main.c | 2 +- soc/arm/ambiq/apollo4x/linker.ld | 2 +- soc/arm/arm/beetle/linker.ld | 2 +- soc/arm/arm/designstart/linker.ld | 2 +- .../arm/fvp_aemv8r_aarch32/arm_mpu_regions.c | 2 +- soc/arm/arm/fvp_aemv8r_aarch32/linker.ld | 2 +- soc/arm/arm/mps2/linker.ld | 2 +- soc/arm/arm/mps3/linker.ld | 2 +- soc/arm/arm/musca_b1/linker.ld | 2 +- soc/arm/arm/musca_s1/linker.ld | 2 +- soc/arm/aspeed/ast10x0/linker.ld | 2 +- soc/arm/atmel_sam/sam3x/linker.ld | 2 +- soc/arm/atmel_sam/sam4e/linker.ld | 2 +- soc/arm/atmel_sam/sam4l/linker.ld | 2 +- soc/arm/atmel_sam/sam4s/linker.ld | 2 +- soc/arm/atmel_sam/same70/linker.ld | 2 +- soc/arm/atmel_sam/samv71/linker.ld | 2 +- soc/arm/atmel_sam0/samc20/linker.ld | 2 +- soc/arm/atmel_sam0/samc21/linker.ld | 2 +- soc/arm/atmel_sam0/samd20/linker.ld | 2 +- soc/arm/atmel_sam0/samd21/linker.ld | 2 +- soc/arm/atmel_sam0/samd51/linker.ld | 2 +- soc/arm/atmel_sam0/same51/linker.ld | 2 +- soc/arm/atmel_sam0/same53/linker.ld | 2 +- soc/arm/atmel_sam0/same54/linker.ld | 2 +- soc/arm/atmel_sam0/saml21/linker.ld | 2 +- soc/arm/atmel_sam0/samr21/linker.ld | 2 +- soc/arm/atmel_sam0/samr34/linker.ld | 2 +- soc/arm/atmel_sam0/samr35/linker.ld | 2 +- soc/arm/bcm_vk/valkyrie/linker.ld | 2 +- soc/arm/bcm_vk/viper/linker_m7.ld | 2 +- soc/arm/common/cortex_m/arm_mpu_regions.c | 4 +-- soc/arm/cypress/psoc6/linker.ld | 2 +- soc/arm/gigadevice/gd32a50x/linker.ld | 2 +- soc/arm/gigadevice/gd32e10x/linker.ld | 2 +- soc/arm/gigadevice/gd32e50x/linker.ld | 2 +- soc/arm/gigadevice/gd32f3x0/linker.ld | 2 +- soc/arm/gigadevice/gd32f403/linker.ld | 2 +- soc/arm/gigadevice/gd32f4xx/linker.ld | 2 +- soc/arm/gigadevice/gd32l23x/linker.ld | 2 +- soc/arm/infineon_cat1/psoc6/linker.ld | 2 +- soc/arm/infineon_xmc/4xxx/linker.ld | 2 +- soc/arm/intel_socfpga_std/cyclonev/linker.ld | 2 +- soc/arm/intel_socfpga_std/cyclonev/soc.c | 2 +- soc/arm/microchip_mec/mec1501/linker.ld | 2 +- soc/arm/microchip_mec/mec1501/timing.c | 2 +- soc/arm/microchip_mec/mec172x/linker.ld | 2 +- soc/arm/microchip_mec/mec172x/timing.c | 2 +- soc/arm/nordic_nrf/nrf51/linker.ld | 2 +- soc/arm/nordic_nrf/nrf52/linker.ld | 2 +- soc/arm/nordic_nrf/nrf53/linker.ld | 2 +- soc/arm/nordic_nrf/nrf91/linker.ld | 2 +- soc/arm/nordic_nrf/timing.c | 2 +- soc/arm/nuvoton_npcx/npcx4/linker.ld | 2 +- soc/arm/nuvoton_npcx/npcx7/linker.ld | 2 +- soc/arm/nuvoton_npcx/npcx7/mpu_regions.c | 2 +- soc/arm/nuvoton_npcx/npcx9/linker.ld | 2 +- soc/arm/nuvoton_numaker/m46x/linker.ld | 2 +- soc/arm/nuvoton_numicro/m48x/linker.ld | 2 +- soc/arm/nxp_imx/mcimx6x_m4/linker.ld | 2 +- soc/arm/nxp_imx/mcimx7_m4/linker.ld | 2 +- soc/arm/nxp_imx/mimx8ml8_m7/linker.ld | 2 +- soc/arm/nxp_imx/mimx8ml8_m7/mpu_regions.c | 2 +- soc/arm/nxp_imx/mimx8mm6_m4/linker.ld | 2 +- soc/arm/nxp_imx/mimx8mq6_m4/linker.ld | 2 +- soc/arm/nxp_imx/rt/linker.ld | 2 +- soc/arm/nxp_imx/rt/mpu_regions.c | 2 +- soc/arm/nxp_imx/rt5xx/linker.ld | 2 +- soc/arm/nxp_imx/rt6xx/linker.ld | 2 +- soc/arm/nxp_kinetis/k2x/linker.ld | 2 +- soc/arm/nxp_kinetis/k6x/linker.ld | 2 +- soc/arm/nxp_kinetis/k6x/nxp_mpu_regions.c | 2 +- soc/arm/nxp_kinetis/k8x/linker.ld | 2 +- soc/arm/nxp_kinetis/k8x/nxp_mpu_regions.c | 2 +- soc/arm/nxp_kinetis/ke1xf/linker.ld | 2 +- soc/arm/nxp_kinetis/ke1xf/nxp_mpu_regions.c | 2 +- soc/arm/nxp_kinetis/kl2x/linker.ld | 2 +- soc/arm/nxp_kinetis/kv5x/linker.ld | 2 +- soc/arm/nxp_kinetis/kwx/linker.ld | 2 +- soc/arm/nxp_lpc/lpc11u6x/linker.ld | 2 +- soc/arm/nxp_lpc/lpc51u68/linker.ld | 2 +- soc/arm/nxp_lpc/lpc54xxx/linker.ld | 2 +- soc/arm/nxp_lpc/lpc55xxx/linker.ld | 2 +- soc/arm/nxp_s32/s32k/linker.ld | 2 +- soc/arm/nxp_s32/s32k/mpu_regions.c | 2 +- soc/arm/nxp_s32/s32ze/linker.ld | 2 +- soc/arm/nxp_s32/s32ze/mpu_regions.c | 2 +- soc/arm/quicklogic_eos_s3/linker.ld | 2 +- soc/arm/renesas_rcar/gen3/linker.ld | 2 +- soc/arm/renesas_smartbond/da1469x/linker.ld | 2 +- soc/arm/rpi_pico/rp2/linker.ld | 2 +- soc/arm/silabs_exx32/efm32gg11b/linker.ld | 2 +- soc/arm/silabs_exx32/efm32gg12b/linker.ld | 2 +- soc/arm/silabs_exx32/efm32hg/linker.ld | 2 +- soc/arm/silabs_exx32/efm32jg12b/linker.ld | 2 +- soc/arm/silabs_exx32/efm32pg12b/linker.ld | 2 +- soc/arm/silabs_exx32/efm32pg1b/linker.ld | 2 +- soc/arm/silabs_exx32/efm32wg/linker.ld | 2 +- soc/arm/silabs_exx32/efr32bg13p/linker.ld | 2 +- soc/arm/silabs_exx32/efr32bg22/linker.ld | 2 +- soc/arm/silabs_exx32/efr32bg27/linker.ld | 2 +- soc/arm/silabs_exx32/efr32fg13p/linker.ld | 2 +- soc/arm/silabs_exx32/efr32fg1p/linker.ld | 2 +- soc/arm/silabs_exx32/efr32mg12p/linker.ld | 2 +- soc/arm/silabs_exx32/efr32mg21/linker.ld | 2 +- soc/arm/silabs_exx32/efr32mg24/linker.ld | 2 +- soc/arm/st_stm32/stm32c0/linker.ld | 2 +- soc/arm/st_stm32/stm32f0/linker.ld | 2 +- soc/arm/st_stm32/stm32f1/linker.ld | 2 +- soc/arm/st_stm32/stm32f2/linker.ld | 2 +- soc/arm/st_stm32/stm32f3/linker.ld | 2 +- soc/arm/st_stm32/stm32f4/linker.ld | 2 +- soc/arm/st_stm32/stm32f7/linker.ld | 2 +- soc/arm/st_stm32/stm32g0/linker.ld | 2 +- soc/arm/st_stm32/stm32g4/linker.ld | 2 +- soc/arm/st_stm32/stm32h5/linker.ld | 2 +- soc/arm/st_stm32/stm32h7/linker.ld | 2 +- soc/arm/st_stm32/stm32h7/mpu_regions.c | 2 +- soc/arm/st_stm32/stm32l0/linker.ld | 2 +- soc/arm/st_stm32/stm32l1/linker.ld | 2 +- soc/arm/st_stm32/stm32l4/linker.ld | 2 +- soc/arm/st_stm32/stm32l5/linker.ld | 2 +- soc/arm/st_stm32/stm32mp1/linker.ld | 2 +- soc/arm/st_stm32/stm32u5/linker.ld | 2 +- soc/arm/st_stm32/stm32wb/linker.ld | 2 +- soc/arm/st_stm32/stm32wba/linker.ld | 2 +- soc/arm/st_stm32/stm32wl/linker.ld | 2 +- soc/arm/ti_k3/am62x_m4/linker.ld | 2 +- soc/arm/ti_lm3s6965/linker.ld | 2 +- soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld | 2 +- .../ti_simplelink/cc13x2x7_cc26x2x7/linker.ld | 2 +- soc/arm/ti_simplelink/cc32xx/linker.ld | 2 +- soc/arm/ti_simplelink/msp432p4xx/linker.ld | 2 +- soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld | 2 +- soc/arm/xilinx_zynq7000/xc7zxxx/soc.c | 2 +- soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld | 2 +- soc/arm/xilinx_zynq7000/xc7zxxxs/soc.c | 2 +- soc/arm/xilinx_zynqmp/arm_mpu_regions.c | 2 +- soc/arm/xilinx_zynqmp/linker.ld | 2 +- soc/riscv/openisa_rv32m1/linker.ld | 2 +- tests/arch/arm/arm_mpu_regions/src/main.c | 2 +- .../arm/arm_runtime_nmi/src/arm_runtime_nmi.c | 2 +- 199 files changed, 196 insertions(+), 197 deletions(-) rename include/zephyr/arch/arm/{aarch32 => }/arch.h (91%) rename include/zephyr/arch/arm/{aarch32 => }/arch_inlines.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/asm_inline.h (90%) rename include/zephyr/arch/arm/{aarch32 => }/asm_inline_gcc.h (96%) rename include/zephyr/arch/arm/{aarch32 => }/barrier.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/armv8_timer.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/cmsis.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/cpu.h (98%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/lib_helpers.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/mpu.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/scripts/app_data_alignment.ld (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/scripts/linker.ld (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/sys_io.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_a_r/timer.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/arm_mpu_mem_cfg.h (98%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/cmsis.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/cpu.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/fpu.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/memory_map.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/nvic.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_m/scripts/linker.ld (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_r/scripts/app_data_alignment.ld (100%) rename include/zephyr/arch/arm/{aarch32 => }/cortex_r/scripts/linker.ld (63%) rename include/zephyr/arch/arm/{aarch32 => }/error.h (96%) rename include/zephyr/arch/arm/{aarch32 => }/exc.h (98%) rename include/zephyr/arch/arm/{aarch32 => }/irq.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/misc.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/mmu/arm_mmu.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/mpu/arm_mpu.h (94%) rename include/zephyr/arch/arm/{aarch32 => }/mpu/arm_mpu_v7m.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/mpu/arm_mpu_v8.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/mpu/nxp_mpu.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/nmi.h (100%) rename include/zephyr/arch/arm/{aarch32 => }/syscall.h (99%) rename include/zephyr/arch/arm/{aarch32 => }/thread.h (100%) diff --git a/CODEOWNERS b/CODEOWNERS index e84d013e9f7..45f1c43719c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -655,11 +655,11 @@ /include/zephyr/arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev /include/zephyr/arch/arc/arch.h @abrodkin @ruuddw @evgeniy-paltsev /include/zephyr/arch/arc/v2/irq.h @abrodkin @ruuddw @evgeniy-paltsev -/include/zephyr/arch/arm/aarch32/ @MaureenHelm @galak @ioannisg -/include/zephyr/arch/arm/aarch32/cortex_a_r/ @stephanosio +/include/zephyr/arch/arm @MaureenHelm @galak @ioannisg +/include/zephyr/arch/arm/cortex_a_r/ @stephanosio /include/zephyr/arch/arm64/ @carlocaione /include/zephyr/arch/arm64/cortex_r/ @povergoing -/include/zephyr/arch/arm/aarch32/irq.h @carlocaione +/include/zephyr/arch/arm/irq.h @carlocaione /include/zephyr/arch/mips/ @frantony /include/zephyr/arch/nios2/ @nashif /include/zephyr/arch/nios2/arch.h @nashif diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 5a555645aa8..0e3d96644c0 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -141,7 +141,6 @@ ARM arch: files: - arch/arm/ - arch/arm/core/offsets/ - - include/zephyr/arch/arm/aarch32/ - include/zephyr/arch/arm/ - tests/arch/arm/ - doc/hardware/arch/arm_cortex_m.rst diff --git a/arch/arm/core/cortex_m/fpu.c b/arch/arm/core/cortex_m/fpu.c index 0e6084470e9..a9c964d14d1 100644 --- a/arch/arm/core/cortex_m/fpu.c +++ b/arch/arm/core/cortex_m/fpu.c @@ -7,7 +7,7 @@ #include #include -#include +#include /** * @file @brief Helper functions for saving and restoring the FP context. diff --git a/arch/arm/core/mmu/arm_mmu.c b/arch/arm/core/mmu/arm_mmu.c index 3658b2df639..5281d265cd0 100644 --- a/arch/arm/core/mmu/arm_mmu.c +++ b/arch/arm/core/mmu/arm_mmu.c @@ -31,7 +31,7 @@ #include -#include +#include #include "arm_mmu_priv.h" LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/arch/arm/core/prep_c.c b/arch/arm/core/prep_c.c index c10acd17b6c..eab2d60a94f 100644 --- a/arch/arm/core/prep_c.c +++ b/arch/arm/core/prep_c.c @@ -22,7 +22,7 @@ #include #if !defined(CONFIG_CPU_CORTEX_M) -#include +#include #endif #if defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A) diff --git a/arch/arm/core/swap_helper.S b/arch/arm/core/swap_helper.S index d125e0d740c..1a1097cd154 100644 --- a/arch/arm/core/swap_helper.S +++ b/arch/arm/core/swap_helper.S @@ -22,7 +22,7 @@ #include #if defined(CONFIG_CPU_CORTEX_M) -#include +#include #endif _ASM_FILE_PROLOGUE diff --git a/arch/arm/core/userspace.S b/arch/arm/core/userspace.S index 58553a8c915..bf89c7d663d 100644 --- a/arch/arm/core/userspace.S +++ b/arch/arm/core/userspace.S @@ -12,7 +12,7 @@ #include #include -#include +#include #if defined(CONFIG_CPU_AARCH32_CORTEX_R) #include diff --git a/arch/arm/include/cortex_m/exc.h b/arch/arm/include/cortex_m/exc.h index 13fc08f178d..b46e74341a9 100644 --- a/arch/arm/include/cortex_m/exc.h +++ b/arch/arm/include/cortex_m/exc.h @@ -23,7 +23,7 @@ #else #include -#include +#include #include #ifdef __cplusplus diff --git a/boards/arm/ip_k66f/linker.ld b/boards/arm/ip_k66f/linker.ld index e1005cd32b7..21e9d0e4c1f 100644 --- a/boards/arm/ip_k66f/linker.ld +++ b/boards/arm/ip_k66f/linker.ld @@ -44,4 +44,4 @@ ITERABLE_SECTION_RAM(net_if_dev, 4) \ ITERABLE_SECTION_RAM(net_l2, 4) \ ITERABLE_SECTION_RAM(eth_bridge, 4) -#include +#include diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 4f0454e994e..48e517259ed 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -262,7 +262,7 @@ interrupt. If the ZLI feature is enabled in Mainline Cortex-M builds (see * Regular HW interrupts are assigned priority levels lower than SVC. The priority level configuration in Cortex-M is implemented in -:file:`include/arch/arm/aarch32/exc.h`. +:file:`include/arch/arm/exc.h`. Locking and unlocking IRQs -------------------------- @@ -624,7 +624,7 @@ Linking Cortex-M applications ***************************** Most Cortex-M platforms make use of the default Cortex-M -GCC linker script in :file:`include/arch/arm/aarch32/cortex-m/scripts/linked.ld`, +GCC linker script in :file:`include/arch/arm/cortex-m/scripts/linked.ld`, although it is possible for platforms to use a custom linker script as well. diff --git a/doc/kernel/code-relocation.rst b/doc/kernel/code-relocation.rst index ee534ffe3ef..a9da18e98cd 100644 --- a/doc/kernel/code-relocation.rst +++ b/doc/kernel/code-relocation.rst @@ -135,7 +135,7 @@ A test showcasing this feature is provided at This test shows how the code relocation feature is used. This test will place .text, .data, .bss from 3 files to various parts in the SRAM -using a custom linker file derived from ``include/arch/arm/aarch32/cortex_m/scripts/linker.ld`` +using a custom linker file derived from ``include/zephyr/arch/arm/cortex_m/scripts/linker.ld`` A sample showcasing the NOCOPY flag is provided at ``$ZEPHYR_BASE/samples/application_development/code_relocation_nocopy/`` diff --git a/doc/kernel/usermode/memory_domain.rst b/doc/kernel/usermode/memory_domain.rst index ff5d419ffd8..a1ddcd395e9 100644 --- a/doc/kernel/usermode/memory_domain.rst +++ b/doc/kernel/usermode/memory_domain.rst @@ -419,7 +419,7 @@ dependent. The complete list of available partition attributes for a specific architecture is found in the architecture-specific include file -``include/arch//arch.h``, (for example, ``include/arch/arm/aarch32/arch.h``.) +``include/zephyr/arch//arch.h``, (for example, ``include/zehpyr/arch/arm/arch.h``.) Some examples of partition attributes are: .. code-block:: c diff --git a/drivers/interrupt_controller/intc_vim.c b/drivers/interrupt_controller/intc_vim.c index df4eb4a9605..01d2633413d 100644 --- a/drivers/interrupt_controller/intc_vim.c +++ b/drivers/interrupt_controller/intc_vim.c @@ -8,7 +8,7 @@ #include -#include +#include #include #include #include diff --git a/drivers/watchdog/wdt_cmsdk_apb.c b/drivers/watchdog/wdt_cmsdk_apb.c index 9d4fa1b979d..543a9ecf39e 100644 --- a/drivers/watchdog/wdt_cmsdk_apb.c +++ b/drivers/watchdog/wdt_cmsdk_apb.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/watchdog/wdt_smartbond.c b/drivers/watchdog/wdt_smartbond.c index 4e48aa5c5c4..5ae07671247 100644 --- a/drivers/watchdog/wdt_smartbond.c +++ b/drivers/watchdog/wdt_smartbond.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/include/zephyr/arch/arch_inlines.h b/include/zephyr/arch/arch_inlines.h index a4173d2a95b..4e1cd149dfb 100644 --- a/include/zephyr/arch/arch_inlines.h +++ b/include/zephyr/arch/arch_inlines.h @@ -15,7 +15,7 @@ #if defined(CONFIG_X86) || defined(CONFIG_X86_64) #include #elif defined(CONFIG_ARM) -#include +#include #elif defined(CONFIG_ARM64) #include #elif defined(CONFIG_ARC) diff --git a/include/zephyr/arch/arm/aarch32/arch.h b/include/zephyr/arch/arm/arch.h similarity index 91% rename from include/zephyr/arch/arm/aarch32/arch.h rename to include/zephyr/arch/arm/arch.h index 15426b39e06..a726bba8502 100644 --- a/include/zephyr/arch/arm/aarch32/arch.h +++ b/include/zephyr/arch/arm/arch.h @@ -22,29 +22,29 @@ /* ARM GPRs are often designated by two different names */ #define sys_define_gpr_with_alias(name1, name2) union { uint32_t name1, name2; } -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -#include -#include +#include +#include #include #ifdef CONFIG_CPU_CORTEX_M -#include -#include +#include +#include #include #elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) -#include -#include +#include +#include #if defined(CONFIG_AARCH32_ARMV8_R) -#include -#include +#include +#include #else -#include +#include #endif #endif @@ -265,14 +265,14 @@ enum k_fatal_error_reason_arch { /* Legacy case: retain containing extern "C" with C++ */ #ifdef CONFIG_ARM_MPU #ifdef CONFIG_CPU_HAS_ARM_MPU -#include +#include #endif /* CONFIG_CPU_HAS_ARM_MPU */ #ifdef CONFIG_CPU_HAS_NXP_MPU -#include +#include #endif /* CONFIG_CPU_HAS_NXP_MPU */ #endif /* CONFIG_ARM_MPU */ #ifdef CONFIG_ARM_AARCH32_MMU -#include +#include #endif /* CONFIG_ARM_AARCH32_MMU */ #ifdef __cplusplus diff --git a/include/zephyr/arch/arm/aarch32/arch_inlines.h b/include/zephyr/arch/arm/arch_inlines.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/arch_inlines.h rename to include/zephyr/arch/arm/arch_inlines.h diff --git a/include/zephyr/arch/arm/aarch32/asm_inline.h b/include/zephyr/arch/arm/asm_inline.h similarity index 90% rename from include/zephyr/arch/arm/aarch32/asm_inline.h rename to include/zephyr/arch/arm/asm_inline.h index 0f1aa22310c..c083adcd47a 100644 --- a/include/zephyr/arch/arm/aarch32/asm_inline.h +++ b/include/zephyr/arch/arm/asm_inline.h @@ -15,7 +15,7 @@ */ #if defined(__GNUC__) -#include +#include #else #include #endif diff --git a/include/zephyr/arch/arm/aarch32/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h similarity index 96% rename from include/zephyr/arch/arm/aarch32/asm_inline_gcc.h rename to include/zephyr/arch/arm/asm_inline_gcc.h index 71665eefdfb..7bb58d9897c 100644 --- a/include/zephyr/arch/arm/aarch32/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -19,10 +19,10 @@ #ifndef _ASMLANGUAGE #include -#include +#include #if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) -#include +#include #endif #ifdef __cplusplus diff --git a/include/zephyr/arch/arm/aarch32/barrier.h b/include/zephyr/arch/arm/barrier.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/barrier.h rename to include/zephyr/arch/arm/barrier.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/armv8_timer.h b/include/zephyr/arch/arm/cortex_a_r/armv8_timer.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/armv8_timer.h rename to include/zephyr/arch/arm/cortex_a_r/armv8_timer.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/cmsis.h b/include/zephyr/arch/arm/cortex_a_r/cmsis.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/cmsis.h rename to include/zephyr/arch/arm/cortex_a_r/cmsis.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/cpu.h b/include/zephyr/arch/arm/cortex_a_r/cpu.h similarity index 98% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/cpu.h rename to include/zephyr/arch/arm/cortex_a_r/cpu.h index 4c4901f5cbe..806d28247ac 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_a_r/cpu.h +++ b/include/zephyr/arch/arm/cortex_a_r/cpu.h @@ -8,7 +8,7 @@ #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_A_R_CPU_H_ #if defined(CONFIG_ARM_MPU) -#include +#include #endif /* diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/lib_helpers.h b/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/lib_helpers.h rename to include/zephyr/arch/arm/cortex_a_r/lib_helpers.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/mpu.h b/include/zephyr/arch/arm/cortex_a_r/mpu.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/mpu.h rename to include/zephyr/arch/arm/cortex_a_r/mpu.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/app_data_alignment.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/app_data_alignment.ld similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/app_data_alignment.ld rename to include/zephyr/arch/arm/cortex_a_r/scripts/app_data_alignment.ld diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld rename to include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/sys_io.h b/include/zephyr/arch/arm/cortex_a_r/sys_io.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/sys_io.h rename to include/zephyr/arch/arm/cortex_a_r/sys_io.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/timer.h b/include/zephyr/arch/arm/cortex_a_r/timer.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_a_r/timer.h rename to include/zephyr/arch/arm/cortex_a_r/timer.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/arm_mpu_mem_cfg.h b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h similarity index 98% rename from include/zephyr/arch/arm/aarch32/cortex_m/arm_mpu_mem_cfg.h rename to include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h index c16d1f4d782..4f1132af6b0 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/arm_mpu_mem_cfg.h +++ b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h @@ -6,7 +6,7 @@ #ifndef _ARM_CORTEX_M_MPU_MEM_CFG_H_ #define _ARM_CORTEX_M_MPU_MEM_CFG_H_ -#include +#include #if !defined(CONFIG_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_MAINLINE) diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/cmsis.h b/include/zephyr/arch/arm/cortex_m/cmsis.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/cmsis.h rename to include/zephyr/arch/arm/cortex_m/cmsis.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/cpu.h b/include/zephyr/arch/arm/cortex_m/cpu.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/cpu.h rename to include/zephyr/arch/arm/cortex_m/cpu.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/fpu.h b/include/zephyr/arch/arm/cortex_m/fpu.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/fpu.h rename to include/zephyr/arch/arm/cortex_m/fpu.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/memory_map.h b/include/zephyr/arch/arm/cortex_m/memory_map.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/memory_map.h rename to include/zephyr/arch/arm/cortex_m/memory_map.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/nvic.h b/include/zephyr/arch/arm/cortex_m/nvic.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/nvic.h rename to include/zephyr/arch/arm/cortex_m/nvic.h diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld rename to include/zephyr/arch/arm/cortex_m/scripts/linker.ld diff --git a/include/zephyr/arch/arm/aarch32/cortex_r/scripts/app_data_alignment.ld b/include/zephyr/arch/arm/cortex_r/scripts/app_data_alignment.ld similarity index 100% rename from include/zephyr/arch/arm/aarch32/cortex_r/scripts/app_data_alignment.ld rename to include/zephyr/arch/arm/cortex_r/scripts/app_data_alignment.ld diff --git a/include/zephyr/arch/arm/aarch32/cortex_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_r/scripts/linker.ld similarity index 63% rename from include/zephyr/arch/arm/aarch32/cortex_r/scripts/linker.ld rename to include/zephyr/arch/arm/cortex_r/scripts/linker.ld index 545b371bbd5..28aa5f7c376 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_r/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_r/scripts/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/include/zephyr/arch/arm/aarch32/error.h b/include/zephyr/arch/arm/error.h similarity index 96% rename from include/zephyr/arch/arm/aarch32/error.h rename to include/zephyr/arch/arm/error.h index fdb0f1f1a45..603e1d00088 100644 --- a/include/zephyr/arch/arm/aarch32/error.h +++ b/include/zephyr/arch/arm/error.h @@ -15,8 +15,8 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ERROR_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ERROR_H_ -#include -#include +#include +#include #include #ifdef __cplusplus diff --git a/include/zephyr/arch/arm/aarch32/exc.h b/include/zephyr/arch/arm/exc.h similarity index 98% rename from include/zephyr/arch/arm/aarch32/exc.h rename to include/zephyr/arch/arm/exc.h index b9d61573698..62fd211065a 100644 --- a/include/zephyr/arch/arm/aarch32/exc.h +++ b/include/zephyr/arch/arm/exc.h @@ -18,7 +18,7 @@ #if defined(CONFIG_CPU_CORTEX_M) #include -#include +#include /* for assembler, only works with constants */ #define Z_EXC_PRIO(pri) (((pri) << (8 - NUM_IRQ_PRIO_BITS)) & 0xff) diff --git a/include/zephyr/arch/arm/aarch32/irq.h b/include/zephyr/arch/arm/irq.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/irq.h rename to include/zephyr/arch/arm/irq.h diff --git a/include/zephyr/arch/arm/aarch32/misc.h b/include/zephyr/arch/arm/misc.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/misc.h rename to include/zephyr/arch/arm/misc.h diff --git a/include/zephyr/arch/arm/aarch32/mmu/arm_mmu.h b/include/zephyr/arch/arm/mmu/arm_mmu.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/mmu/arm_mmu.h rename to include/zephyr/arch/arm/mmu/arm_mmu.h diff --git a/include/zephyr/arch/arm/aarch32/mpu/arm_mpu.h b/include/zephyr/arch/arm/mpu/arm_mpu.h similarity index 94% rename from include/zephyr/arch/arm/aarch32/mpu/arm_mpu.h rename to include/zephyr/arch/arm/mpu/arm_mpu.h index 65d9194b7a2..857465a4824 100644 --- a/include/zephyr/arch/arm/aarch32/mpu/arm_mpu.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu.h @@ -11,12 +11,12 @@ defined(CONFIG_CPU_CORTEX_M4) || \ defined(CONFIG_CPU_CORTEX_M7) || \ defined(CONFIG_ARMV7_R) -#include +#include #elif defined(CONFIG_CPU_CORTEX_M23) || \ defined(CONFIG_CPU_CORTEX_M33) || \ defined(CONFIG_CPU_CORTEX_M55) || \ defined(CONFIG_AARCH32_ARMV8_R) -#include +#include #else #error "Unsupported ARM CPU" #endif diff --git a/include/zephyr/arch/arm/aarch32/mpu/arm_mpu_v7m.h b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/mpu/arm_mpu_v7m.h rename to include/zephyr/arch/arm/mpu/arm_mpu_v7m.h diff --git a/include/zephyr/arch/arm/aarch32/mpu/arm_mpu_v8.h b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/mpu/arm_mpu_v8.h rename to include/zephyr/arch/arm/mpu/arm_mpu_v8.h diff --git a/include/zephyr/arch/arm/aarch32/mpu/nxp_mpu.h b/include/zephyr/arch/arm/mpu/nxp_mpu.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/mpu/nxp_mpu.h rename to include/zephyr/arch/arm/mpu/nxp_mpu.h diff --git a/include/zephyr/arch/arm/aarch32/nmi.h b/include/zephyr/arch/arm/nmi.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/nmi.h rename to include/zephyr/arch/arm/nmi.h diff --git a/include/zephyr/arch/arm/aarch32/syscall.h b/include/zephyr/arch/arm/syscall.h similarity index 99% rename from include/zephyr/arch/arm/aarch32/syscall.h rename to include/zephyr/arch/arm/syscall.h index f8561d8c24a..a4e067307ec 100644 --- a/include/zephyr/arch/arm/aarch32/syscall.h +++ b/include/zephyr/arch/arm/syscall.h @@ -26,7 +26,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/arch/arm/aarch32/thread.h b/include/zephyr/arch/arm/thread.h similarity index 100% rename from include/zephyr/arch/arm/aarch32/thread.h rename to include/zephyr/arch/arm/thread.h diff --git a/include/zephyr/arch/cpu.h b/include/zephyr/arch/cpu.h index 5fbe8f8c628..17ec125b395 100644 --- a/include/zephyr/arch/cpu.h +++ b/include/zephyr/arch/cpu.h @@ -16,7 +16,7 @@ #elif defined(CONFIG_ARM64) #include #elif defined(CONFIG_ARM) -#include +#include #elif defined(CONFIG_ARC) #include #elif defined(CONFIG_NIOS2) diff --git a/include/zephyr/arch/syscall.h b/include/zephyr/arch/syscall.h index 3c745921070..b657717e3d4 100644 --- a/include/zephyr/arch/syscall.h +++ b/include/zephyr/arch/syscall.h @@ -18,7 +18,7 @@ #elif defined(CONFIG_ARM64) #include #elif defined(CONFIG_ARM) -#include +#include #elif defined(CONFIG_ARC) #include #elif defined(CONFIG_RISCV) diff --git a/include/zephyr/sys/barrier.h b/include/zephyr/sys/barrier.h index dacc0ba62f5..5390cb38cf0 100644 --- a/include/zephyr/sys/barrier.h +++ b/include/zephyr/sys/barrier.h @@ -11,7 +11,7 @@ #if defined(CONFIG_BARRIER_OPERATIONS_ARCH) # if defined(CONFIG_ARM) -# include +# include # elif defined(CONFIG_ARM64) # include # endif diff --git a/modules/cmsis/cmsis_core_m.h b/modules/cmsis/cmsis_core_m.h index 849c496a9bd..880ff614b5b 100644 --- a/modules/cmsis/cmsis_core_m.h +++ b/modules/cmsis/cmsis_core_m.h @@ -14,7 +14,7 @@ #ifndef ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ #define ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ -#include +#include #include diff --git a/modules/trusted-firmware-m/interface/interface.c b/modules/trusted-firmware-m/interface/interface.c index c89a572a788..ad0ed1abdfe 100644 --- a/modules/trusted-firmware-m/interface/interface.c +++ b/modules/trusted-firmware-m/interface/interface.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include diff --git a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld index e28cfefd675..934f928596c 100644 --- a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld +++ b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld @@ -44,4 +44,4 @@ MEMORY #endif /* CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP */ -#include +#include diff --git a/samples/subsys/debug/debugmon/src/main.c b/samples/subsys/debug/debugmon/src/main.c index a05bb2b4117..9029cc44ae7 100644 --- a/samples/subsys/debug/debugmon/src/main.c +++ b/samples/subsys/debug/debugmon/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); diff --git a/soc/arm/ambiq/apollo4x/linker.ld b/soc/arm/ambiq/apollo4x/linker.ld index 9c1ab8ff301..ab996aa9939 100644 --- a/soc/arm/ambiq/apollo4x/linker.ld +++ b/soc/arm/ambiq/apollo4x/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/beetle/linker.ld b/soc/arm/arm/beetle/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/beetle/linker.ld +++ b/soc/arm/arm/beetle/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/designstart/linker.ld b/soc/arm/arm/designstart/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/designstart/linker.ld +++ b/soc/arm/arm/designstart/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/fvp_aemv8r_aarch32/arm_mpu_regions.c b/soc/arm/arm/fvp_aemv8r_aarch32/arm_mpu_regions.c index e756a81bccc..b1c91d15d9a 100644 --- a/soc/arm/arm/fvp_aemv8r_aarch32/arm_mpu_regions.c +++ b/soc/arm/arm/fvp_aemv8r_aarch32/arm_mpu_regions.c @@ -5,7 +5,7 @@ #include #include -#include +#include #define DEVICE_REGION_START 0x80000000UL #define DEVICE_REGION_END 0xFFFFFFFFUL diff --git a/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld b/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld index 924b5ab62d4..76b6c7a5450 100644 --- a/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld +++ b/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/mps2/linker.ld b/soc/arm/arm/mps2/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/mps2/linker.ld +++ b/soc/arm/arm/mps2/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/mps3/linker.ld b/soc/arm/arm/mps3/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/mps3/linker.ld +++ b/soc/arm/arm/mps3/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/musca_b1/linker.ld b/soc/arm/arm/musca_b1/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/musca_b1/linker.ld +++ b/soc/arm/arm/musca_b1/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/arm/musca_s1/linker.ld b/soc/arm/arm/musca_s1/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/arm/musca_s1/linker.ld +++ b/soc/arm/arm/musca_s1/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/aspeed/ast10x0/linker.ld b/soc/arm/aspeed/ast10x0/linker.ld index ef034e1f70e..fec4d373a82 100644 --- a/soc/arm/aspeed/ast10x0/linker.ld +++ b/soc/arm/aspeed/ast10x0/linker.ld @@ -7,4 +7,4 @@ MEMORY { SRAM_NC (wx) : ORIGIN = CONFIG_SRAM_NC_BASE_ADDRESS, LENGTH = CONFIG_SRAM_NC_SIZE * 1024 } -#include +#include diff --git a/soc/arm/atmel_sam/sam3x/linker.ld b/soc/arm/atmel_sam/sam3x/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/atmel_sam/sam3x/linker.ld +++ b/soc/arm/atmel_sam/sam3x/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam/sam4e/linker.ld b/soc/arm/atmel_sam/sam4e/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/atmel_sam/sam4e/linker.ld +++ b/soc/arm/atmel_sam/sam4e/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam/sam4l/linker.ld b/soc/arm/atmel_sam/sam4l/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/atmel_sam/sam4l/linker.ld +++ b/soc/arm/atmel_sam/sam4l/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam/sam4s/linker.ld b/soc/arm/atmel_sam/sam4s/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/atmel_sam/sam4s/linker.ld +++ b/soc/arm/atmel_sam/sam4s/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam/same70/linker.ld b/soc/arm/atmel_sam/same70/linker.ld index e9411a5f889..cb361723b39 100644 --- a/soc/arm/atmel_sam/same70/linker.ld +++ b/soc/arm/atmel_sam/same70/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam/samv71/linker.ld b/soc/arm/atmel_sam/samv71/linker.ld index e9411a5f889..cb361723b39 100644 --- a/soc/arm/atmel_sam/samv71/linker.ld +++ b/soc/arm/atmel_sam/samv71/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samc20/linker.ld b/soc/arm/atmel_sam0/samc20/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/samc20/linker.ld +++ b/soc/arm/atmel_sam0/samc20/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samc21/linker.ld b/soc/arm/atmel_sam0/samc21/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/samc21/linker.ld +++ b/soc/arm/atmel_sam0/samc21/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samd20/linker.ld b/soc/arm/atmel_sam0/samd20/linker.ld index 5068c8fa74a..75ef287b6d9 100644 --- a/soc/arm/atmel_sam0/samd20/linker.ld +++ b/soc/arm/atmel_sam0/samd20/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samd21/linker.ld b/soc/arm/atmel_sam0/samd21/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/samd21/linker.ld +++ b/soc/arm/atmel_sam0/samd21/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samd51/linker.ld b/soc/arm/atmel_sam0/samd51/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/samd51/linker.ld +++ b/soc/arm/atmel_sam0/samd51/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/same51/linker.ld b/soc/arm/atmel_sam0/same51/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/same51/linker.ld +++ b/soc/arm/atmel_sam0/same51/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/same53/linker.ld b/soc/arm/atmel_sam0/same53/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/same53/linker.ld +++ b/soc/arm/atmel_sam0/same53/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/same54/linker.ld b/soc/arm/atmel_sam0/same54/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/same54/linker.ld +++ b/soc/arm/atmel_sam0/same54/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/saml21/linker.ld b/soc/arm/atmel_sam0/saml21/linker.ld index 799b8baa700..6b4498f0932 100644 --- a/soc/arm/atmel_sam0/saml21/linker.ld +++ b/soc/arm/atmel_sam0/saml21/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samr21/linker.ld b/soc/arm/atmel_sam0/samr21/linker.ld index 3ff98161e11..745c7ad8b2a 100644 --- a/soc/arm/atmel_sam0/samr21/linker.ld +++ b/soc/arm/atmel_sam0/samr21/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samr34/linker.ld b/soc/arm/atmel_sam0/samr34/linker.ld index 799b8baa700..6b4498f0932 100644 --- a/soc/arm/atmel_sam0/samr34/linker.ld +++ b/soc/arm/atmel_sam0/samr34/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/atmel_sam0/samr35/linker.ld b/soc/arm/atmel_sam0/samr35/linker.ld index 799b8baa700..6b4498f0932 100644 --- a/soc/arm/atmel_sam0/samr35/linker.ld +++ b/soc/arm/atmel_sam0/samr35/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/bcm_vk/valkyrie/linker.ld b/soc/arm/bcm_vk/valkyrie/linker.ld index 5a1f7793253..a17ecaeaf32 100644 --- a/soc/arm/bcm_vk/valkyrie/linker.ld +++ b/soc/arm/bcm_vk/valkyrie/linker.ld @@ -4,4 +4,4 @@ */ -#include +#include diff --git a/soc/arm/bcm_vk/viper/linker_m7.ld b/soc/arm/bcm_vk/viper/linker_m7.ld index 3e28ca6c567..670bb23c78b 100644 --- a/soc/arm/bcm_vk/viper/linker_m7.ld +++ b/soc/arm/bcm_vk/viper/linker_m7.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index 557079ef5bc..7eb3eb24f1d 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -5,10 +5,10 @@ */ #include -#include +#include #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/arm/cypress/psoc6/linker.ld b/soc/arm/cypress/psoc6/linker.ld index bd76ded366c..e0657c31ee5 100644 --- a/soc/arm/cypress/psoc6/linker.ld +++ b/soc/arm/cypress/psoc6/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/gigadevice/gd32a50x/linker.ld b/soc/arm/gigadevice/gd32a50x/linker.ld index 32362bbe6e7..34a8f747bdc 100644 --- a/soc/arm/gigadevice/gd32a50x/linker.ld +++ b/soc/arm/gigadevice/gd32a50x/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32e10x/linker.ld b/soc/arm/gigadevice/gd32e10x/linker.ld index 39c3b988037..1223f99d929 100644 --- a/soc/arm/gigadevice/gd32e10x/linker.ld +++ b/soc/arm/gigadevice/gd32e10x/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32e50x/linker.ld b/soc/arm/gigadevice/gd32e50x/linker.ld index 32362bbe6e7..34a8f747bdc 100644 --- a/soc/arm/gigadevice/gd32e50x/linker.ld +++ b/soc/arm/gigadevice/gd32e50x/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32f3x0/linker.ld b/soc/arm/gigadevice/gd32f3x0/linker.ld index d0bc3bd8737..67650d4eb8d 100644 --- a/soc/arm/gigadevice/gd32f3x0/linker.ld +++ b/soc/arm/gigadevice/gd32f3x0/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32f403/linker.ld b/soc/arm/gigadevice/gd32f403/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/gigadevice/gd32f403/linker.ld +++ b/soc/arm/gigadevice/gd32f403/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32f4xx/linker.ld b/soc/arm/gigadevice/gd32f4xx/linker.ld index 32362bbe6e7..34a8f747bdc 100644 --- a/soc/arm/gigadevice/gd32f4xx/linker.ld +++ b/soc/arm/gigadevice/gd32f4xx/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/gigadevice/gd32l23x/linker.ld b/soc/arm/gigadevice/gd32l23x/linker.ld index a5bd1ec82a5..520d4ee69f0 100644 --- a/soc/arm/gigadevice/gd32l23x/linker.ld +++ b/soc/arm/gigadevice/gd32l23x/linker.ld @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/infineon_cat1/psoc6/linker.ld b/soc/arm/infineon_cat1/psoc6/linker.ld index d2e0572cbed..9af77e1c523 100644 --- a/soc/arm/infineon_cat1/psoc6/linker.ld +++ b/soc/arm/infineon_cat1/psoc6/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/infineon_xmc/4xxx/linker.ld b/soc/arm/infineon_xmc/4xxx/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/infineon_xmc/4xxx/linker.ld +++ b/soc/arm/infineon_xmc/4xxx/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/intel_socfpga_std/cyclonev/linker.ld b/soc/arm/intel_socfpga_std/cyclonev/linker.ld index c4812640739..ef4c62338b4 100644 --- a/soc/arm/intel_socfpga_std/cyclonev/linker.ld +++ b/soc/arm/intel_socfpga_std/cyclonev/linker.ld @@ -5,4 +5,4 @@ * Adding support for Cyclone V SoC FPGA, using arm32 linker */ -#include +#include diff --git a/soc/arm/intel_socfpga_std/cyclonev/soc.c b/soc/arm/intel_socfpga_std/cyclonev/soc.c index 70e697dd62b..73f7617d792 100644 --- a/soc/arm/intel_socfpga_std/cyclonev/soc.c +++ b/soc/arm/intel_socfpga_std/cyclonev/soc.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "soc.h" #include diff --git a/soc/arm/microchip_mec/mec1501/linker.ld b/soc/arm/microchip_mec/mec1501/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/microchip_mec/mec1501/linker.ld +++ b/soc/arm/microchip_mec/mec1501/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/microchip_mec/mec1501/timing.c b/soc/arm/microchip_mec/mec1501/timing.c index 016cfa249f4..a67844f60d2 100644 --- a/soc/arm/microchip_mec/mec1501/timing.c +++ b/soc/arm/microchip_mec/mec1501/timing.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include diff --git a/soc/arm/microchip_mec/mec172x/linker.ld b/soc/arm/microchip_mec/mec172x/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/microchip_mec/mec172x/linker.ld +++ b/soc/arm/microchip_mec/mec172x/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/microchip_mec/mec172x/timing.c b/soc/arm/microchip_mec/mec172x/timing.c index c415e3223d5..8dafb73544c 100644 --- a/soc/arm/microchip_mec/mec172x/timing.c +++ b/soc/arm/microchip_mec/mec172x/timing.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include diff --git a/soc/arm/nordic_nrf/nrf51/linker.ld b/soc/arm/nordic_nrf/nrf51/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/nordic_nrf/nrf51/linker.ld +++ b/soc/arm/nordic_nrf/nrf51/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nordic_nrf/nrf52/linker.ld b/soc/arm/nordic_nrf/nrf52/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/nordic_nrf/nrf52/linker.ld +++ b/soc/arm/nordic_nrf/nrf52/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nordic_nrf/nrf53/linker.ld b/soc/arm/nordic_nrf/nrf53/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/nordic_nrf/nrf53/linker.ld +++ b/soc/arm/nordic_nrf/nrf53/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nordic_nrf/nrf91/linker.ld b/soc/arm/nordic_nrf/nrf91/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/nordic_nrf/nrf91/linker.ld +++ b/soc/arm/nordic_nrf/nrf91/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nordic_nrf/timing.c b/soc/arm/nordic_nrf/timing.c index e75be5f9cdb..402e97f2141 100644 --- a/soc/arm/nordic_nrf/timing.c +++ b/soc/arm/nordic_nrf/timing.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include diff --git a/soc/arm/nuvoton_npcx/npcx4/linker.ld b/soc/arm/nuvoton_npcx/npcx4/linker.ld index 7b1a0772918..36859865d02 100644 --- a/soc/arm/nuvoton_npcx/npcx4/linker.ld +++ b/soc/arm/nuvoton_npcx/npcx4/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nuvoton_npcx/npcx7/linker.ld b/soc/arm/nuvoton_npcx/npcx7/linker.ld index 4856bf0a71d..c27b59604dc 100644 --- a/soc/arm/nuvoton_npcx/npcx7/linker.ld +++ b/soc/arm/nuvoton_npcx/npcx7/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nuvoton_npcx/npcx7/mpu_regions.c b/soc/arm/nuvoton_npcx/npcx7/mpu_regions.c index 7592a2e39a2..e9d4c073305 100644 --- a/soc/arm/nuvoton_npcx/npcx7/mpu_regions.c +++ b/soc/arm/nuvoton_npcx/npcx7/mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("FLASH_0_0", diff --git a/soc/arm/nuvoton_npcx/npcx9/linker.ld b/soc/arm/nuvoton_npcx/npcx9/linker.ld index 554ea2c78a7..a07329b6360 100644 --- a/soc/arm/nuvoton_npcx/npcx9/linker.ld +++ b/soc/arm/nuvoton_npcx/npcx9/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nuvoton_numaker/m46x/linker.ld b/soc/arm/nuvoton_numaker/m46x/linker.ld index b9a80770518..37c968fda63 100644 --- a/soc/arm/nuvoton_numaker/m46x/linker.ld +++ b/soc/arm/nuvoton_numaker/m46x/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nuvoton_numicro/m48x/linker.ld b/soc/arm/nuvoton_numicro/m48x/linker.ld index 11d1f0f8f32..737722a1611 100644 --- a/soc/arm/nuvoton_numicro/m48x/linker.ld +++ b/soc/arm/nuvoton_numicro/m48x/linker.ld @@ -4,4 +4,4 @@ * Copyright (c) 2020 Linumiz */ -#include +#include diff --git a/soc/arm/nxp_imx/mcimx6x_m4/linker.ld b/soc/arm/nxp_imx/mcimx6x_m4/linker.ld index aabc45a6059..3cf863608e1 100644 --- a/soc/arm/nxp_imx/mcimx6x_m4/linker.ld +++ b/soc/arm/nxp_imx/mcimx6x_m4/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nxp_imx/mcimx7_m4/linker.ld b/soc/arm/nxp_imx/mcimx7_m4/linker.ld index aabc45a6059..3cf863608e1 100644 --- a/soc/arm/nxp_imx/mcimx7_m4/linker.ld +++ b/soc/arm/nxp_imx/mcimx7_m4/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nxp_imx/mimx8ml8_m7/linker.ld b/soc/arm/nxp_imx/mimx8ml8_m7/linker.ld index 26ae2082fa5..0b4006dd732 100644 --- a/soc/arm/nxp_imx/mimx8ml8_m7/linker.ld +++ b/soc/arm/nxp_imx/mimx8ml8_m7/linker.ld @@ -16,7 +16,7 @@ MEMORY #endif } -#include +#include SECTIONS { diff --git a/soc/arm/nxp_imx/mimx8ml8_m7/mpu_regions.c b/soc/arm/nxp_imx/mimx8ml8_m7/mpu_regions.c index 7964712f646..ed7deb8575a 100644 --- a/soc/arm/nxp_imx/mimx8ml8_m7/mpu_regions.c +++ b/soc/arm/nxp_imx/mimx8ml8_m7/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define REGION_MASK_BASE_ADDRESS 0x00000000U #define REGION_ITCM_BASE_ADDRESS 0x00000000U diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld b/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld index b6698210b52..b1a954f245a 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld +++ b/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include SECTIONS { diff --git a/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld b/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld index ebf224afbaf..895341fda8d 100644 --- a/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld +++ b/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nxp_imx/rt/linker.ld b/soc/arm/nxp_imx/rt/linker.ld index b26f1a38aaf..e4d5ad56db0 100644 --- a/soc/arm/nxp_imx/rt/linker.ld +++ b/soc/arm/nxp_imx/rt/linker.ld @@ -15,4 +15,4 @@ MEMORY #endif } -#include +#include diff --git a/soc/arm/nxp_imx/rt/mpu_regions.c b/soc/arm/nxp_imx/rt/mpu_regions.c index 663e448f5dd..dae25354155 100644 --- a/soc/arm/nxp_imx/rt/mpu_regions.c +++ b/soc/arm/nxp_imx/rt/mpu_regions.c @@ -8,7 +8,7 @@ #include #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/arm/nxp_imx/rt5xx/linker.ld b/soc/arm/nxp_imx/rt5xx/linker.ld index 3b84d02a527..2b6a4d63fba 100644 --- a/soc/arm/nxp_imx/rt5xx/linker.ld +++ b/soc/arm/nxp_imx/rt5xx/linker.ld @@ -21,4 +21,4 @@ FLEXSPI2 (wx) : ORIGIN = DT_REG_ADDR_BY_IDX(DT_NODELABEL(flexspi2), 1), LENGTH = DT_REG_SIZE_BY_IDX(DT_NODELABEL(flexspi2), 1) #endif } -#include +#include diff --git a/soc/arm/nxp_imx/rt6xx/linker.ld b/soc/arm/nxp_imx/rt6xx/linker.ld index d9eaca7598c..cf5cc4c9968 100644 --- a/soc/arm/nxp_imx/rt6xx/linker.ld +++ b/soc/arm/nxp_imx/rt6xx/linker.ld @@ -11,4 +11,4 @@ */ -#include +#include diff --git a/soc/arm/nxp_kinetis/k2x/linker.ld b/soc/arm/nxp_kinetis/k2x/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/k2x/linker.ld +++ b/soc/arm/nxp_kinetis/k2x/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/k6x/linker.ld b/soc/arm/nxp_kinetis/k6x/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/k6x/linker.ld +++ b/soc/arm/nxp_kinetis/k6x/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/k6x/nxp_mpu_regions.c b/soc/arm/nxp_kinetis/k6x/nxp_mpu_regions.c index 8108ca7df88..41d0df3d689 100644 --- a/soc/arm/nxp_kinetis/k6x/nxp_mpu_regions.c +++ b/soc/arm/nxp_kinetis/k6x/nxp_mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include static const struct nxp_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/arm/nxp_kinetis/k8x/linker.ld b/soc/arm/nxp_kinetis/k8x/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/k8x/linker.ld +++ b/soc/arm/nxp_kinetis/k8x/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/k8x/nxp_mpu_regions.c b/soc/arm/nxp_kinetis/k8x/nxp_mpu_regions.c index d7bcce1cd9b..599f1e149ef 100644 --- a/soc/arm/nxp_kinetis/k8x/nxp_mpu_regions.c +++ b/soc/arm/nxp_kinetis/k8x/nxp_mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include static const struct nxp_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/arm/nxp_kinetis/ke1xf/linker.ld b/soc/arm/nxp_kinetis/ke1xf/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/ke1xf/linker.ld +++ b/soc/arm/nxp_kinetis/ke1xf/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/ke1xf/nxp_mpu_regions.c b/soc/arm/nxp_kinetis/ke1xf/nxp_mpu_regions.c index d7bcce1cd9b..599f1e149ef 100644 --- a/soc/arm/nxp_kinetis/ke1xf/nxp_mpu_regions.c +++ b/soc/arm/nxp_kinetis/ke1xf/nxp_mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include static const struct nxp_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/arm/nxp_kinetis/kl2x/linker.ld b/soc/arm/nxp_kinetis/kl2x/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/kl2x/linker.ld +++ b/soc/arm/nxp_kinetis/kl2x/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/kv5x/linker.ld b/soc/arm/nxp_kinetis/kv5x/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/kv5x/linker.ld +++ b/soc/arm/nxp_kinetis/kv5x/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_kinetis/kwx/linker.ld b/soc/arm/nxp_kinetis/kwx/linker.ld index 5d6126629f9..7a1df7beaa5 100644 --- a/soc/arm/nxp_kinetis/kwx/linker.ld +++ b/soc/arm/nxp_kinetis/kwx/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images and XIP images. */ -#include +#include diff --git a/soc/arm/nxp_lpc/lpc11u6x/linker.ld b/soc/arm/nxp_lpc/lpc11u6x/linker.ld index d729ed4c3a7..ad9319b4977 100644 --- a/soc/arm/nxp_lpc/lpc11u6x/linker.ld +++ b/soc/arm/nxp_lpc/lpc11u6x/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/nxp_lpc/lpc51u68/linker.ld b/soc/arm/nxp_lpc/lpc51u68/linker.ld index 1023aa66005..8724d8f68dd 100644 --- a/soc/arm/nxp_lpc/lpc51u68/linker.ld +++ b/soc/arm/nxp_lpc/lpc51u68/linker.ld @@ -9,4 +9,4 @@ */ __Vectors = _vector_table; -#include +#include diff --git a/soc/arm/nxp_lpc/lpc54xxx/linker.ld b/soc/arm/nxp_lpc/lpc54xxx/linker.ld index 817f1d948d0..b6a1fb0bbcc 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/linker.ld +++ b/soc/arm/nxp_lpc/lpc54xxx/linker.ld @@ -16,4 +16,4 @@ */ __Vectors = _vector_table; -#include +#include diff --git a/soc/arm/nxp_lpc/lpc55xxx/linker.ld b/soc/arm/nxp_lpc/lpc55xxx/linker.ld index e7c360409f7..186914f102c 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/linker.ld +++ b/soc/arm/nxp_lpc/lpc55xxx/linker.ld @@ -17,4 +17,4 @@ __Vectors = _vector_table; -#include +#include diff --git a/soc/arm/nxp_s32/s32k/linker.ld b/soc/arm/nxp_s32/s32k/linker.ld index dbbca346ba0..8681f1cd3f3 100644 --- a/soc/arm/nxp_s32/s32k/linker.ld +++ b/soc/arm/nxp_s32/s32k/linker.ld @@ -12,4 +12,4 @@ MEMORY } #endif -#include +#include diff --git a/soc/arm/nxp_s32/s32k/mpu_regions.c b/soc/arm/nxp_s32/s32k/mpu_regions.c index 9c4316d0aa9..48078bde6bf 100644 --- a/soc/arm/nxp_s32/s32k/mpu_regions.c +++ b/soc/arm/nxp_s32/s32k/mpu_regions.c @@ -6,7 +6,7 @@ #include #include -#include +#include #if !defined(CONFIG_XIP) extern char _rom_attr[]; diff --git a/soc/arm/nxp_s32/s32ze/linker.ld b/soc/arm/nxp_s32/s32ze/linker.ld index c8a7570e891..d04a2dc6065 100644 --- a/soc/arm/nxp_s32/s32ze/linker.ld +++ b/soc/arm/nxp_s32/s32ze/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/nxp_s32/s32ze/mpu_regions.c b/soc/arm/nxp_s32/s32ze/mpu_regions.c index aa4109f492f..33c41d362b5 100644 --- a/soc/arm/nxp_s32/s32ze/mpu_regions.c +++ b/soc/arm/nxp_s32/s32ze/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define DEVICE_REGION_START 0x40000000UL #define DEVICE_REGION_END 0x76FFFFFFUL diff --git a/soc/arm/quicklogic_eos_s3/linker.ld b/soc/arm/quicklogic_eos_s3/linker.ld index 448ac908598..5d2ea23f266 100644 --- a/soc/arm/quicklogic_eos_s3/linker.ld +++ b/soc/arm/quicklogic_eos_s3/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/renesas_rcar/gen3/linker.ld b/soc/arm/renesas_rcar/gen3/linker.ld index 257f496c64d..f94542d9256 100644 --- a/soc/arm/renesas_rcar/gen3/linker.ld +++ b/soc/arm/renesas_rcar/gen3/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/renesas_smartbond/da1469x/linker.ld b/soc/arm/renesas_smartbond/da1469x/linker.ld index f3b675269bb..dfa36b95d49 100644 --- a/soc/arm/renesas_smartbond/da1469x/linker.ld +++ b/soc/arm/renesas_smartbond/da1469x/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/rpi_pico/rp2/linker.ld b/soc/arm/rpi_pico/rp2/linker.ld index bf594a89e98..5e1db9a8175 100644 --- a/soc/arm/rpi_pico/rp2/linker.ld +++ b/soc/arm/rpi_pico/rp2/linker.ld @@ -26,4 +26,4 @@ SECTIONS } #endif /* CONFIG_RP2_REQUIRES_SECOND_STAGE_BOOT */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32gg11b/linker.ld b/soc/arm/silabs_exx32/efm32gg11b/linker.ld index 95b76e19ce0..120507fb63f 100644 --- a/soc/arm/silabs_exx32/efm32gg11b/linker.ld +++ b/soc/arm/silabs_exx32/efm32gg11b/linker.ld @@ -13,4 +13,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32gg12b/linker.ld b/soc/arm/silabs_exx32/efm32gg12b/linker.ld index c7955ec596c..f478ff72c40 100644 --- a/soc/arm/silabs_exx32/efm32gg12b/linker.ld +++ b/soc/arm/silabs_exx32/efm32gg12b/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images. */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32hg/linker.ld b/soc/arm/silabs_exx32/efm32hg/linker.ld index ff791e999d2..da96a05932a 100644 --- a/soc/arm/silabs_exx32/efm32hg/linker.ld +++ b/soc/arm/silabs_exx32/efm32hg/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32jg12b/linker.ld b/soc/arm/silabs_exx32/efm32jg12b/linker.ld index e93018c0980..cb2bbd2fdf1 100644 --- a/soc/arm/silabs_exx32/efm32jg12b/linker.ld +++ b/soc/arm/silabs_exx32/efm32jg12b/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32pg12b/linker.ld b/soc/arm/silabs_exx32/efm32pg12b/linker.ld index e93018c0980..cb2bbd2fdf1 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/linker.ld +++ b/soc/arm/silabs_exx32/efm32pg12b/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32pg1b/linker.ld b/soc/arm/silabs_exx32/efm32pg1b/linker.ld index e93018c0980..cb2bbd2fdf1 100644 --- a/soc/arm/silabs_exx32/efm32pg1b/linker.ld +++ b/soc/arm/silabs_exx32/efm32pg1b/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efm32wg/linker.ld b/soc/arm/silabs_exx32/efm32wg/linker.ld index 7c8c33eb937..d877abf5fd4 100644 --- a/soc/arm/silabs_exx32/efm32wg/linker.ld +++ b/soc/arm/silabs_exx32/efm32wg/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32bg13p/linker.ld b/soc/arm/silabs_exx32/efr32bg13p/linker.ld index b0530df09bd..09c3e1cf943 100644 --- a/soc/arm/silabs_exx32/efr32bg13p/linker.ld +++ b/soc/arm/silabs_exx32/efr32bg13p/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32bg22/linker.ld b/soc/arm/silabs_exx32/efr32bg22/linker.ld index 9fcfb60618d..38d9b250c5b 100644 --- a/soc/arm/silabs_exx32/efr32bg22/linker.ld +++ b/soc/arm/silabs_exx32/efr32bg22/linker.ld @@ -11,4 +11,4 @@ * This is the linker script for both standard images. */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32bg27/linker.ld b/soc/arm/silabs_exx32/efr32bg27/linker.ld index 77214fcef49..b65086a5ce1 100644 --- a/soc/arm/silabs_exx32/efr32bg27/linker.ld +++ b/soc/arm/silabs_exx32/efr32bg27/linker.ld @@ -2,4 +2,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32fg13p/linker.ld b/soc/arm/silabs_exx32/efr32fg13p/linker.ld index e93018c0980..cb2bbd2fdf1 100644 --- a/soc/arm/silabs_exx32/efr32fg13p/linker.ld +++ b/soc/arm/silabs_exx32/efr32fg13p/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32fg1p/linker.ld b/soc/arm/silabs_exx32/efr32fg1p/linker.ld index e93018c0980..cb2bbd2fdf1 100644 --- a/soc/arm/silabs_exx32/efr32fg1p/linker.ld +++ b/soc/arm/silabs_exx32/efr32fg1p/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32mg12p/linker.ld b/soc/arm/silabs_exx32/efr32mg12p/linker.ld index b0530df09bd..09c3e1cf943 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/linker.ld +++ b/soc/arm/silabs_exx32/efr32mg12p/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32mg21/linker.ld b/soc/arm/silabs_exx32/efr32mg21/linker.ld index d61039d397a..7295169eae8 100644 --- a/soc/arm/silabs_exx32/efr32mg21/linker.ld +++ b/soc/arm/silabs_exx32/efr32mg21/linker.ld @@ -12,4 +12,4 @@ */ -#include +#include diff --git a/soc/arm/silabs_exx32/efr32mg24/linker.ld b/soc/arm/silabs_exx32/efr32mg24/linker.ld index d83e2a66530..0d44f863613 100644 --- a/soc/arm/silabs_exx32/efr32mg24/linker.ld +++ b/soc/arm/silabs_exx32/efr32mg24/linker.ld @@ -13,4 +13,4 @@ #include -#include +#include diff --git a/soc/arm/st_stm32/stm32c0/linker.ld b/soc/arm/st_stm32/stm32c0/linker.ld index fda50c307af..d5f07ed942a 100644 --- a/soc/arm/st_stm32/stm32c0/linker.ld +++ b/soc/arm/st_stm32/stm32c0/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f0/linker.ld b/soc/arm/st_stm32/stm32f0/linker.ld index 876802cb7ee..c39286d86f5 100644 --- a/soc/arm/st_stm32/stm32f0/linker.ld +++ b/soc/arm/st_stm32/stm32f0/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f1/linker.ld b/soc/arm/st_stm32/stm32f1/linker.ld index 876802cb7ee..c39286d86f5 100644 --- a/soc/arm/st_stm32/stm32f1/linker.ld +++ b/soc/arm/st_stm32/stm32f1/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f2/linker.ld b/soc/arm/st_stm32/stm32f2/linker.ld index 83708c438f6..b5f5c77d59c 100644 --- a/soc/arm/st_stm32/stm32f2/linker.ld +++ b/soc/arm/st_stm32/stm32f2/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f3/linker.ld b/soc/arm/st_stm32/stm32f3/linker.ld index 876802cb7ee..c39286d86f5 100644 --- a/soc/arm/st_stm32/stm32f3/linker.ld +++ b/soc/arm/st_stm32/stm32f3/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f4/linker.ld b/soc/arm/st_stm32/stm32f4/linker.ld index 876802cb7ee..c39286d86f5 100644 --- a/soc/arm/st_stm32/stm32f4/linker.ld +++ b/soc/arm/st_stm32/stm32f4/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32f7/linker.ld b/soc/arm/st_stm32/stm32f7/linker.ld index bf8d6789236..be06b7accb6 100644 --- a/soc/arm/st_stm32/stm32f7/linker.ld +++ b/soc/arm/st_stm32/stm32f7/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32g0/linker.ld b/soc/arm/st_stm32/stm32g0/linker.ld index e5b8916fc1f..a5c6d669295 100644 --- a/soc/arm/st_stm32/stm32g0/linker.ld +++ b/soc/arm/st_stm32/stm32g0/linker.ld @@ -7,4 +7,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32g4/linker.ld b/soc/arm/st_stm32/stm32g4/linker.ld index 954d9eb7587..8053c5cfc11 100644 --- a/soc/arm/st_stm32/stm32g4/linker.ld +++ b/soc/arm/st_stm32/stm32g4/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32h5/linker.ld b/soc/arm/st_stm32/stm32h5/linker.ld index 8bd989bc732..f20e6999579 100644 --- a/soc/arm/st_stm32/stm32h5/linker.ld +++ b/soc/arm/st_stm32/stm32h5/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32h7/linker.ld b/soc/arm/st_stm32/stm32h7/linker.ld index 078ef2a807b..20713e9bfd3 100644 --- a/soc/arm/st_stm32/stm32h7/linker.ld +++ b/soc/arm/st_stm32/stm32h7/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32h7/mpu_regions.c b/soc/arm/st_stm32/stm32h7/mpu_regions.c index f2ba721d2df..01daccdd01d 100644 --- a/soc/arm/st_stm32/stm32h7/mpu_regions.c +++ b/soc/arm/st_stm32/stm32h7/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("FLASH", CONFIG_FLASH_BASE_ADDRESS, diff --git a/soc/arm/st_stm32/stm32l0/linker.ld b/soc/arm/st_stm32/stm32l0/linker.ld index 268542adab1..31b070c6950 100644 --- a/soc/arm/st_stm32/stm32l0/linker.ld +++ b/soc/arm/st_stm32/stm32l0/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32l1/linker.ld b/soc/arm/st_stm32/stm32l1/linker.ld index 48056b39708..0bbb83d949b 100644 --- a/soc/arm/st_stm32/stm32l1/linker.ld +++ b/soc/arm/st_stm32/stm32l1/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32l4/linker.ld b/soc/arm/st_stm32/stm32l4/linker.ld index 876802cb7ee..c39286d86f5 100644 --- a/soc/arm/st_stm32/stm32l4/linker.ld +++ b/soc/arm/st_stm32/stm32l4/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32l5/linker.ld b/soc/arm/st_stm32/stm32l5/linker.ld index 484e77214be..987547b1ee1 100644 --- a/soc/arm/st_stm32/stm32l5/linker.ld +++ b/soc/arm/st_stm32/stm32l5/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32mp1/linker.ld b/soc/arm/st_stm32/stm32mp1/linker.ld index 1ff5da841e5..7f9a84501ef 100644 --- a/soc/arm/st_stm32/stm32mp1/linker.ld +++ b/soc/arm/st_stm32/stm32mp1/linker.ld @@ -7,7 +7,7 @@ */ -#include +#include SECTIONS { diff --git a/soc/arm/st_stm32/stm32u5/linker.ld b/soc/arm/st_stm32/stm32u5/linker.ld index c28ef22f9a0..a5b0e37e825 100644 --- a/soc/arm/st_stm32/stm32u5/linker.ld +++ b/soc/arm/st_stm32/stm32u5/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32wb/linker.ld b/soc/arm/st_stm32/stm32wb/linker.ld index 078ef2a807b..20713e9bfd3 100644 --- a/soc/arm/st_stm32/stm32wb/linker.ld +++ b/soc/arm/st_stm32/stm32wb/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32wba/linker.ld b/soc/arm/st_stm32/stm32wba/linker.ld index 8bd989bc732..f20e6999579 100644 --- a/soc/arm/st_stm32/stm32wba/linker.ld +++ b/soc/arm/st_stm32/stm32wba/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/st_stm32/stm32wl/linker.ld b/soc/arm/st_stm32/stm32wl/linker.ld index 8050cf9b60c..c81df32357e 100644 --- a/soc/arm/st_stm32/stm32wl/linker.ld +++ b/soc/arm/st_stm32/stm32wl/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/ti_k3/am62x_m4/linker.ld b/soc/arm/ti_k3/am62x_m4/linker.ld index 793177b7f72..5e478a0541f 100644 --- a/soc/arm/ti_k3/am62x_m4/linker.ld +++ b/soc/arm/ti_k3/am62x_m4/linker.ld @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include SECTIONS { diff --git a/soc/arm/ti_lm3s6965/linker.ld b/soc/arm/ti_lm3s6965/linker.ld index 96ec397da78..757d858cb69 100644 --- a/soc/arm/ti_lm3s6965/linker.ld +++ b/soc/arm/ti_lm3s6965/linker.ld @@ -6,4 +6,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld b/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld index 42f44928045..643b4899397 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld index f7ba43c42ca..772be96ca3b 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld @@ -5,4 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/ti_simplelink/cc32xx/linker.ld b/soc/arm/ti_simplelink/cc32xx/linker.ld index e8b364e4dcf..812d6f50331 100644 --- a/soc/arm/ti_simplelink/cc32xx/linker.ld +++ b/soc/arm/ti_simplelink/cc32xx/linker.ld @@ -5,4 +5,4 @@ * linker.ld - Linker command/script file */ -#include +#include diff --git a/soc/arm/ti_simplelink/msp432p4xx/linker.ld b/soc/arm/ti_simplelink/msp432p4xx/linker.ld index e8b364e4dcf..812d6f50331 100644 --- a/soc/arm/ti_simplelink/msp432p4xx/linker.ld +++ b/soc/arm/ti_simplelink/msp432p4xx/linker.ld @@ -5,4 +5,4 @@ * linker.ld - Linker command/script file */ -#include +#include diff --git a/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld b/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld index 38f1212398d..00ffe9ceff3 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld +++ b/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/xilinx_zynq7000/xc7zxxx/soc.c b/soc/arm/xilinx_zynq7000/xc7zxxx/soc.c index 5c7317ac3f7..a8d3eab7c73 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxx/soc.c +++ b/soc/arm/xilinx_zynq7000/xc7zxxx/soc.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "soc.h" /* System Level Control Registers (SLCR) */ diff --git a/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld b/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld index 38f1212398d..00ffe9ceff3 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld +++ b/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld @@ -4,4 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include diff --git a/soc/arm/xilinx_zynq7000/xc7zxxxs/soc.c b/soc/arm/xilinx_zynq7000/xc7zxxxs/soc.c index 7f794c5e9f7..66e17b56bc9 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxxs/soc.c +++ b/soc/arm/xilinx_zynq7000/xc7zxxxs/soc.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "soc.h" /* System Level Configuration Registers */ diff --git a/soc/arm/xilinx_zynqmp/arm_mpu_regions.c b/soc/arm/xilinx_zynqmp/arm_mpu_regions.c index f10ba5d94e0..5a6f8dc6c21 100644 --- a/soc/arm/xilinx_zynqmp/arm_mpu_regions.c +++ b/soc/arm/xilinx_zynqmp/arm_mpu_regions.c @@ -4,7 +4,7 @@ */ #include -#include +#include #define MPUTYPE_READ_ONLY \ { \ diff --git a/soc/arm/xilinx_zynqmp/linker.ld b/soc/arm/xilinx_zynqmp/linker.ld index 744cd1c5f36..4f22c8618cf 100644 --- a/soc/arm/xilinx_zynqmp/linker.ld +++ b/soc/arm/xilinx_zynqmp/linker.ld @@ -7,5 +7,5 @@ #if defined(CONFIG_SOC_XILINX_ZYNQMP_RPU) -#include +#include #endif diff --git a/soc/riscv/openisa_rv32m1/linker.ld b/soc/riscv/openisa_rv32m1/linker.ld index 7ade2d4e8dd..784ba791722 100644 --- a/soc/riscv/openisa_rv32m1/linker.ld +++ b/soc/riscv/openisa_rv32m1/linker.ld @@ -5,7 +5,7 @@ * * This file is based on: * - * - include/arch/arm/aarch32/cortex_m/scripts/linker.ld + * - include/arch/arm/cortex_m/scripts/linker.ld * - include/arch/riscv/common/linker.ld * - include/arch/riscv/pulpino/linker.ld * diff --git a/tests/arch/arm/arm_mpu_regions/src/main.c b/tests/arch/arm/arm_mpu_regions/src/main.c index ec784787bb4..72df578f2c0 100644 --- a/tests/arch/arm/arm_mpu_regions/src/main.c +++ b/tests/arch/arm/arm_mpu_regions/src/main.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/arch/arm/arm_runtime_nmi/src/arm_runtime_nmi.c b/tests/arch/arm/arm_runtime_nmi/src/arm_runtime_nmi.c index 870993c59e7..79a4bbedca3 100644 --- a/tests/arch/arm/arm_runtime_nmi/src/arm_runtime_nmi.c +++ b/tests/arch/arm/arm_runtime_nmi/src/arm_runtime_nmi.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include From 1e79cfcd2e72d6159d40acdb659a2f6f178448b4 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 4 Jul 2023 17:19:58 +0800 Subject: [PATCH 0293/4498] arch: arm: cortex-m: Move irq_relay.S to the cortex-m directory 'irq_relay.S' is only used for Arm Cortex-M architecture, so it's better to place it to the 'arch/arm/core/cortex_m' directory. Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 1 - arch/arm/core/cortex_m/CMakeLists.txt | 1 + arch/arm/core/{ => cortex_m}/irq_relay.S | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename arch/arm/core/{ => cortex_m}/irq_relay.S (100%) diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index e64958471a1..4d96198849f 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -17,7 +17,6 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_CPP __aeabi_atexit.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) -zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_ARM_ZIMAGE_HEADER header.S) diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index 8d12299e965..692e2689801 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) zephyr_library_sources_ifdef(CONFIG_PM_S2RAM pm_s2ram.c pm_s2ram.S) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) +zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S) if(CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT) zephyr_library_sources(debug.c) diff --git a/arch/arm/core/irq_relay.S b/arch/arm/core/cortex_m/irq_relay.S similarity index 100% rename from arch/arm/core/irq_relay.S rename to arch/arm/core/cortex_m/irq_relay.S From c86785297c4f7f03b135892cc28074e8c5a9af55 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 4 Jul 2023 19:02:54 +0800 Subject: [PATCH 0294/4498] arch: arm: Separate common swap code There are too many differences between Cortex-A/R and Cortex-M on swap code. For reducing the complexity and easier to maintain, this commit introduces the following major changes 1. Separate swap.c and swap_helper.S into two different parts based on the architecture. 2. Rename 'z_arm_pendsv' to 'z_arm_do_swap' for Cortex-A/R. 3. Removes the part related to the option 'CONFIG_BUILTIN_STACK_GUARD' in 'cortex_a_r/swap_helper.S' because this code is written for the Cortex-M architecture. Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 2 - arch/arm/core/cortex_a_r/CMakeLists.txt | 2 + arch/arm/core/cortex_a_r/exc_exit.S | 8 +- arch/arm/core/cortex_a_r/swap.c | 30 ++ arch/arm/core/cortex_a_r/swap_helper.S | 427 +++++++++++++++++++++ arch/arm/core/cortex_m/CMakeLists.txt | 2 + arch/arm/core/{ => cortex_m}/swap.c | 5 - arch/arm/core/{ => cortex_m}/swap_helper.S | 372 +----------------- 8 files changed, 468 insertions(+), 380 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/swap.c create mode 100644 arch/arm/core/cortex_a_r/swap_helper.S rename arch/arm/core/{ => cortex_m}/swap.c (91%) rename arch/arm/core/{ => cortex_m}/swap_helper.S (62%) diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 4d96198849f..6388a6d9e6f 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -9,8 +9,6 @@ zephyr_library_sources( nmi.c nmi_on_reset.S prep_c.c - swap.c - swap_helper.S thread.c ) diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index c1cdc7e9c67..2a573a84861 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -12,6 +12,8 @@ zephyr_library_sources( stacks.c tcm.c vector_table.S + swap.c + swap_helper.S ) zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) diff --git a/arch/arm/core/cortex_a_r/exc_exit.S b/arch/arm/core/cortex_a_r/exc_exit.S index 5706a390500..67fc5fa6e00 100644 --- a/arch/arm/core/cortex_a_r/exc_exit.S +++ b/arch/arm/core/cortex_a_r/exc_exit.S @@ -23,7 +23,7 @@ _ASM_FILE_PROLOGUE GTEXT(z_arm_exc_exit) GTEXT(z_arm_int_exit) -GTEXT(z_arm_pendsv) +GTEXT(z_arm_do_swap) GDATA(_kernel) .macro userspace_exc_exit @@ -148,7 +148,7 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_int_exit) ldr r1, [r3, #_kernel_offset_to_current] ldr r0, [r3, #_kernel_offset_to_ready_q_cache] cmp r0, r1 - blne z_arm_pendsv + blne z_arm_do_swap __EXIT_INT: #endif /* CONFIG_PREEMPT_ENABLED */ @@ -231,12 +231,12 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_exc_exit) /* * Switch in the next scheduled thread. * - * Note that z_arm_pendsv must be called in the SVC mode because it + * Note that z_arm_do_swap must be called in the SVC mode because it * switches to the SVC mode during context switch and returns to the * caller using lr_svc. */ cps #MODE_SVC - bl z_arm_pendsv + bl z_arm_do_swap /* Decrement exception nesting count */ ldr r3, =_kernel diff --git a/arch/arm/core/cortex_a_r/swap.c b/arch/arm/core/cortex_a_r/swap.c new file mode 100644 index 00000000000..258999be7c7 --- /dev/null +++ b/arch/arm/core/cortex_a_r/swap.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Linaro, Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +extern const int _k_neg_eagain; + +/* The 'key' actually represents the BASEPRI register + * prior to disabling interrupts via the BASEPRI mechanism. + * + * arch_swap() itself does not do much. + */ +int arch_swap(unsigned int key) +{ + /* store off key and return value */ + _current->arch.basepri = key; + _current->arch.swap_return_value = _k_neg_eagain; + + z_arm_cortex_r_svc(); + irq_unlock(key); + + /* Context switch is performed here. Returning implies the + * thread has been context-switched-in again. + */ + return _current->arch.swap_return_value; +} diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S new file mode 100644 index 00000000000..c646e70cc7e --- /dev/null +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright (c) 2017-2019 Nordic Semiconductor ASA. + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Thread context switching for ARM Cortex-A and Cortex-R + * + * This module implements the routines necessary for thread context switching + * on ARM Cortex-A and Cortex-R CPUs. + */ + +#include +#include +#include +#include +#include +#include + +_ASM_FILE_PROLOGUE + +GTEXT(z_arm_svc) +GTEXT(z_arm_do_swap) +GTEXT(z_do_kernel_oops) +#if defined(CONFIG_USERSPACE) +GTEXT(z_arm_do_syscall) +#endif + +GDATA(_kernel) + +/** + * + * @brief Routine to handle context switches + * + * For Cortex-R, this function is directly called either by z_arm_{exc,int}_exit + * in case of preemption, or z_arm_svc in case of cooperative switching. + */ + +SECTION_FUNC(TEXT, z_arm_do_swap) + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + /* Register the context switch */ + push {r0, lr} + bl z_thread_mark_switched_out + pop {r0, lr} +#endif /* CONFIG_INSTRUMENT_THREAD_SWITCHING */ + + /* load _kernel into r1 and current k_thread into r2 */ + ldr r1, =_kernel + ldr r2, [r1, #_kernel_offset_to_current] + +#if defined(CONFIG_ARM_STORE_EXC_RETURN) + /* Store LSB of LR (EXC_RETURN) to the thread's 'mode' word. */ + strb lr, [r2, #_thread_offset_to_mode_exc_return] +#endif + + /* addr of callee-saved regs in thread in r0 */ + ldr r0, =_thread_offset_to_callee_saved + add r0, r2 + + /* Store rest of process context */ + cps #MODE_SYS + stm r0, {r4-r11, sp} + cps #MODE_SVC + +#if defined(CONFIG_FPU_SHARING) + ldrb r0, [r2, #_thread_offset_to_user_options] + tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ + beq out_fp_inactive + + mov ip, #FPEXC_EN + vmsr fpexc, ip + + /* + * If the float context pointer is not null, then the VFP has not been + * used since this thread has used it. Consequently, the caller-saved + * float registers have not been saved away, so write them to the + * exception stack frame. + */ + ldr r0, [r1, #_kernel_offset_to_fp_ctx] + cmp r0, #0 + beq out_store_thread_context + + vstmia r0!, {s0-s15} +#ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 + vstmia r0!, {d16-d31} +#endif + vmrs r3, fpscr + stm r0, {r3, ip} + +out_store_thread_context: + /* Store s16-s31 to thread context */ + add r0, r2, #_thread_offset_to_preempt_float + vstmia r0, {s16-s31} + + mov ip, #0 + vmsr fpexc, ip + +out_fp_inactive: + /* + * The floating context has now been saved to the exception stack + * frame, so zero out the global pointer to note this. + */ + mov r0, #0 + str r0, [r1, #_kernel_offset_to_fp_ctx] +#endif /* CONFIG_FPU_SHARING */ + + /* fetch the thread to run from the ready queue cache */ + ldr r2, [r1, #_kernel_offset_to_ready_q_cache] + + str r2, [r1, #_kernel_offset_to_current] + +#if defined(CONFIG_THREAD_LOCAL_STORAGE) + /* Grab the TLS pointer */ + ldr r4, =_thread_offset_to_tls + adds r4, r2, r4 + ldr r0, [r4] + + /* Store TLS pointer in the "Process ID" register. + * This register is used as a base pointer to all + * thread variables with offsets added by toolchain. + */ + mcr 15, 0, r0, cr13, cr0, 3 +#endif + +#if defined(CONFIG_ARM_STORE_EXC_RETURN) + /* Restore EXC_RETURN value. */ + ldrsb lr, [r2, #_thread_offset_to_mode_exc_return] +#endif + + /* Restore previous interrupt disable state (irq_lock key) + * (We clear the arch.basepri field after restoring state) + */ + ldr r0, [r2, #_thread_offset_to_basepri] + movs r3, #0 + str r3, [r2, #_thread_offset_to_basepri] + +_thread_irq_disabled: + /* load _kernel into r1 and current k_thread into r2 */ + ldr r1, =_kernel + ldr r2, [r1, #_kernel_offset_to_current] + + /* addr of callee-saved regs in thread in r0 */ + ldr r0, =_thread_offset_to_callee_saved + add r0, r2 + + /* restore r4-r11 and sp for incoming thread */ + cps #MODE_SYS + ldm r0, {r4-r11, sp} + cps #MODE_SVC + +#if defined(CONFIG_FPU_SHARING) + ldrb r0, [r2, #_thread_offset_to_user_options] + tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ + beq in_fp_inactive + + mov r3, #FPEXC_EN + vmsr fpexc, r3 + + /* Restore s16-s31 from thread context */ + add r0, r2, #_thread_offset_to_preempt_float + vldmia r0, {s16-s31} + + mov r3, #0 + vmsr fpexc, r3 + +in_fp_inactive: +#endif /* CONFIG_FPU_SHARING */ + +#if defined (CONFIG_ARM_MPU) + /* r2 contains k_thread */ + mov r0, r2 + /* Re-program dynamic memory map */ + push {r2, lr} + bl z_arm_configure_dynamic_mpu_regions + pop {r2, lr} +#endif + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + /* Register the context switch */ + push {r0, lr} + bl z_thread_mark_switched_in + pop {r0, lr} +#endif /* CONFIG_INSTRUMENT_THREAD_SWITCHING */ + + /* + * Cortex-R: return to the caller (z_arm_{exc,int}_exit, or z_arm_svc) + */ + bx lr + +#if defined(CONFIG_FPU_SHARING) +#define FPU_SF_SIZE ___fpu_t_SIZEOF +#else +#define FPU_SF_SIZE 0 +#endif + +/** + * + * @brief Service call handler + * + * The service call (svc) is used in the following occasions: + * - Cooperative context switching + * - IRQ offloading + * - Kernel run-time exceptions + * + */ +SECTION_FUNC(TEXT, z_arm_svc) +#if defined(CONFIG_USERSPACE) + /* Determine if incoming thread was in user context */ + push {r0} + mrs r0, spsr + and r0, #MODE_MASK + cmp r0, #MODE_USR + bne svc_system_thread + + ldr r0, =_kernel + ldr r0, [r0, #_kernel_offset_to_current] + + /* Save away user stack pointer */ + cps #MODE_SYS + str sp, [r0, #_thread_offset_to_sp_usr] /* sp_usr */ + + /* Switch to privileged stack */ + ldr sp, [r0, #_thread_offset_to_priv_stack_end] /* priv stack end */ + cps #MODE_SVC + +svc_system_thread: + pop {r0} +#endif + + /* + * Switch to system mode to store r0-r3 to the process stack pointer. + * Save r12 and the lr as we could be swapping in another process and + * returning to a different location. + */ + srsdb #MODE_SYS! + cps #MODE_SYS + push {r0-r3, r12, lr} + +#if defined(CONFIG_FPU_SHARING) + sub sp, sp, #___fpu_t_SIZEOF + + /* + * Note that this handler was entered with the VFP unit enabled. + * The undefined instruction handler uses this to know that it + * needs to save the current floating context. + */ + vmrs r0, fpexc + str r0, [sp, #___fpu_t_SIZEOF - 4] + tst r0, #FPEXC_EN + beq _vfp_not_enabled + vmrs r0, fpscr + str r0, [sp, #___fpu_t_SIZEOF - 8] + + /* Disable VFP */ + mov r0, #0 + vmsr fpexc, r0 + +_vfp_not_enabled: + /* + * Mark where to store the floating context for the undefined + * instruction handler + */ + ldr r2, =_kernel + ldr r0, [r2, #_kernel_offset_to_fp_ctx] + cmp r0, #0 + streq sp, [r2, #_kernel_offset_to_fp_ctx] +#endif /* CONFIG_FPU_SHARING */ + + mov ip, sp + + cps #MODE_SVC + + /* + * Store lr_svc to the SVC mode stack. This value will be restored prior to + * exiting the SVC call in z_arm_int_exit. + */ + push {lr} + + /* Align stack at double-word boundary */ + and r3, sp, #4 + sub sp, sp, r3 + push {r2, r3} + + /* Increment interrupt nesting count */ + ldr r2, =_kernel + ldr r0, [r2, #_kernel_offset_to_nested] + add r0, r0, #1 + str r0, [r2, #_kernel_offset_to_nested] + + /* Get SVC number */ + mrs r0, spsr + tst r0, #0x20 + + ldreq r1, [lr, #-4] + biceq r1, #0xff000000 + beq demux + + ldr r1, [lr, #-2] + and r1, #0xff + + /* + * grab service call number: + * 0: context switch + * 1: irq_offload (if configured) + * 2: kernel panic or oops (software generated fatal exception) + * 3: system calls for memory protection + */ +demux: + +#if defined(CONFIG_USERSPACE) + cmp r1, #_SVC_CALL_SYSTEM_CALL + beq _do_syscall +#endif + + cmp r1, #_SVC_CALL_CONTEXT_SWITCH + beq _context_switch + + cmp r1, #_SVC_CALL_RUNTIME_EXCEPT + beq _oops + +#if CONFIG_IRQ_OFFLOAD + blx z_irq_do_offload /* call C routine which executes the offload */ + + /* exception return is done in z_arm_int_exit() */ + b z_arm_int_exit +#endif + +_context_switch: + /* handler mode exit, to PendSV */ + bl z_arm_do_swap + + b z_arm_int_exit + +_oops: + /* + * Pass the exception frame to z_do_kernel_oops. r0 contains the + * exception reason. + */ + cps #MODE_SYS + mov r0, sp + cps #MODE_SVC + bl z_do_kernel_oops + b z_arm_int_exit + +#if defined(CONFIG_USERSPACE) + /* + * System call will setup a jump to the _do_arm_syscall function + * running in system mode when returning from the exception. + * + * There is some trickery involved here because we have to preserve + * the original PC value so that we can return back to the caller of + * the SVC. + * + * On SVC exception, the USER/SYSTEM stack looks like the following: + * { possible FPU space } - r0 - r1 - r2 - r3 - r12 - LR - PC - SPSR + * + * Registers look like: + * r0 - arg1 + * r1 - arg2 + * r2 - arg3 + * r3 - arg4 + * r4 - arg5 + * r5 - arg6 + * r6 - call_id + * r8 - saved link register + */ +_do_syscall: + /* grab address of LR from stack frame */ + ldr r8, [ip, #(FPU_SF_SIZE + ___basic_sf_t_pc_OFFSET)] + + /* Make the exception return to system state */ + ldr r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_xpsr_OFFSET)] + + /* If leaving thumb mode, set the return address to thumb mode */ + tst r1, #T_BIT + orrne r8, #1 + + bic r1, #(MODE_MASK | T_BIT) + orr r1, r1, #MODE_SYS + str r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_xpsr_OFFSET)] + + /* + * Store the address of z_arm_do_syscall for the exit so the exception + * return goes there in system state. + */ + ldr r1, =z_arm_do_syscall + str r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_pc_OFFSET)] + + /* validate syscall limit, only set priv mode if valid */ + ldr ip, =K_SYSCALL_LIMIT + cmp r6, ip + blo valid_syscall_id + + /* bad syscall id. Set arg0 to bad id and set call_id to SYSCALL_BAD */ + cps #MODE_SYS + str r6, [sp] + cps #MODE_SVC + ldr r6, =K_SYSCALL_BAD + +valid_syscall_id: + ldr r0, =_kernel + ldr r0, [r0, #_kernel_offset_to_current] + ldr r1, [r0, #_thread_offset_to_mode] + bic r1, #1 + /* Store (privileged) mode in thread's mode state variable */ + str r1, [r0, #_thread_offset_to_mode] + dsb + + /* ISB is not strictly necessary here (stack pointer is not being + * touched), but it's recommended to avoid executing pre-fetched + * instructions with the previous privilege. + */ + isb + + /* Return to _arm_do_syscall in system state. */ + b z_arm_int_exit +#endif + +GTEXT(z_arm_cortex_r_svc) +SECTION_FUNC(TEXT, z_arm_cortex_r_svc) + svc #_SVC_CALL_CONTEXT_SWITCH + bx lr diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index 692e2689801..f1ac9eed64c 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -12,6 +12,8 @@ zephyr_library_sources( scb.c thread_abort.c vector_table.S + swap.c + swap_helper.S ) zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) diff --git a/arch/arm/core/swap.c b/arch/arm/core/cortex_m/swap.c similarity index 91% rename from arch/arm/core/swap.c rename to arch/arm/core/cortex_m/swap.c index 525dc53671e..f41ae2e4e84 100644 --- a/arch/arm/core/swap.c +++ b/arch/arm/core/cortex_m/swap.c @@ -36,16 +36,11 @@ int arch_swap(unsigned int key) _current->arch.basepri = key; _current->arch.swap_return_value = _k_neg_eagain; -#if defined(CONFIG_CPU_CORTEX_M) /* set pending bit to make sure we will take a PendSV exception */ SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; /* clear mask or enable all irqs to take a pendsv */ irq_unlock(0); -#elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) - z_arm_cortex_r_svc(); - irq_unlock(key); -#endif /* Context switch is performed here. Returning implies the * thread has been context-switched-in again. diff --git a/arch/arm/core/swap_helper.S b/arch/arm/core/cortex_m/swap_helper.S similarity index 62% rename from arch/arm/core/swap_helper.S rename to arch/arm/core/cortex_m/swap_helper.S index 1a1097cd154..af1d0d791dd 100644 --- a/arch/arm/core/swap_helper.S +++ b/arch/arm/core/cortex_m/swap_helper.S @@ -8,10 +8,10 @@ /** * @file - * @brief Thread context switching for ARM Cortex-M and Cortex-R + * @brief Thread context switching for ARM Cortex-M * * This module implements the routines necessary for thread context switching - * on ARM Cortex-A, Cortex-M and Cortex-R CPUs. + * on ARM Cortex-M CPUs. */ #include @@ -21,9 +21,7 @@ #include #include -#if defined(CONFIG_CPU_CORTEX_M) #include -#endif _ASM_FILE_PROLOGUE GTEXT(z_arm_svc) @@ -35,7 +33,7 @@ GTEXT(z_arm_do_syscall) GDATA(_kernel) -#if defined(CONFIG_THREAD_LOCAL_STORAGE) && defined(CONFIG_CPU_CORTEX_M) +#if defined(CONFIG_THREAD_LOCAL_STORAGE) GDATA(z_arm_tls_ptr) #endif @@ -52,10 +50,6 @@ GDATA(z_arm_tls_ptr) * have to swap *something*. * * For Cortex-M, z_arm_pendsv() is invoked with no arguments. - * - * For Cortex-R, PendSV exception is not supported by the architecture and this - * function is directly called either by z_arm_{exc,int}_exit in case of - * preemption, or z_arm_svc in case of cooperative switching. */ SECTION_FUNC(TEXT, z_arm_pendsv) @@ -86,9 +80,7 @@ SECTION_FUNC(TEXT, z_arm_pendsv) add r0, r2 /* save callee-saved + psp in thread */ -#if defined(CONFIG_CPU_CORTEX_M) mrs ip, PSP -#endif #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* Store current r4-r7 */ @@ -121,54 +113,6 @@ out_fp_endif: * regardless of whether the thread has an active FP context. */ #endif /* CONFIG_FPU_SHARING */ -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) - /* Store rest of process context */ - cps #MODE_SYS - stm r0, {r4-r11, sp} - cps #MODE_SVC - -#if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] - tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ - beq out_fp_inactive - - mov ip, #FPEXC_EN - vmsr fpexc, ip - - /* - * If the float context pointer is not null, then the VFP has not been - * used since this thread has used it. Consequently, the caller-saved - * float registers have not been saved away, so write them to the - * exception stack frame. - */ - ldr r0, [r1, #_kernel_offset_to_fp_ctx] - cmp r0, #0 - beq out_store_thread_context - - vstmia r0!, {s0-s15} -#ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 - vstmia r0!, {d16-d31} -#endif - vmrs r3, fpscr - stm r0, {r3, ip} - -out_store_thread_context: - /* Store s16-s31 to thread context */ - add r0, r2, #_thread_offset_to_preempt_float - vstmia r0, {s16-s31} - - mov ip, #0 - vmsr fpexc, ip - -out_fp_inactive: - /* - * The floating context has now been saved to the exception stack - * frame, so zero out the global pointer to note this. - */ - mov r0, #0 - str r0, [r1, #_kernel_offset_to_fp_ctx] -#endif /* CONFIG_FPU_SHARING */ #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ @@ -180,12 +124,6 @@ out_fp_inactive: movs.n r0, #_EXC_IRQ_DEFAULT_PRIO msr BASEPRI_MAX, r0 isb /* Make the effect of disabling interrupts be realized immediately */ -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) - /* - * Interrupts are still disabled from arch_swap so empty clause - * here to avoid the preprocessor error below - */ #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ @@ -197,10 +135,8 @@ out_fp_inactive: * to pend PendSV have been taken with the current kernel * state and this is what we're handling currently. */ -#if defined(CONFIG_CPU_CORTEX_M) ldr v4, =_SCS_ICSR ldr v3, =_SCS_ICSR_UNPENDSV -#endif /* _kernel is still in r1 */ @@ -219,9 +155,7 @@ out_fp_inactive: */ /* _SCS_ICSR is still in v4 and _SCS_ICSR_UNPENDSV in v3 */ -#if defined(CONFIG_CPU_CORTEX_M) str v3, [v4, #0] -#endif #if defined(CONFIG_THREAD_LOCAL_STORAGE) /* Grab the TLS pointer */ @@ -229,15 +163,6 @@ out_fp_inactive: adds r4, r2, r4 ldr r0, [r4] -#if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) - /* Store TLS pointer in the "Process ID" register. - * This register is used as a base pointer to all - * thread variables with offsets added by toolchain. - */ - mcr 15, 0, r0, cr13, cr0, 3 -#endif - -#if defined(CONFIG_CPU_CORTEX_M) /* For Cortex-M, store TLS pointer in a global variable, * as it lacks the process ID or thread ID register * to be used by toolchain to access thread data. @@ -246,8 +171,6 @@ out_fp_inactive: str r0, [r4] #endif -#endif - #if defined(CONFIG_ARM_STORE_EXC_RETURN) /* Restore EXC_RETURN value. */ ldrsb lr, [r2, #_thread_offset_to_mode_exc_return] @@ -389,55 +312,11 @@ in_fp_endif: /* load callee-saved + psp from thread */ add r0, r2, #_thread_offset_to_callee_saved ldmia r0, {v1-v8, ip} -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) -_thread_irq_disabled: - /* load _kernel into r1 and current k_thread into r2 */ - ldr r1, =_kernel - ldr r2, [r1, #_kernel_offset_to_current] - - /* addr of callee-saved regs in thread in r0 */ - ldr r0, =_thread_offset_to_callee_saved - add r0, r2 - - /* restore r4-r11 and sp for incoming thread */ - cps #MODE_SYS - ldm r0, {r4-r11, sp} - cps #MODE_SVC - -#if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] - tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ - beq in_fp_inactive - - mov r3, #FPEXC_EN - vmsr fpexc, r3 - - /* Restore s16-s31 from thread context */ - add r0, r2, #_thread_offset_to_preempt_float - vldmia r0, {s16-s31} - - mov r3, #0 - vmsr fpexc, r3 - -in_fp_inactive: -#endif /* CONFIG_FPU_SHARING */ - -#if defined (CONFIG_ARM_MPU) - /* r2 contains k_thread */ - mov r0, r2 - /* Re-program dynamic memory map */ - push {r2, lr} - bl z_arm_configure_dynamic_mpu_regions - pop {r2, lr} -#endif #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#if defined(CONFIG_CPU_CORTEX_M) msr PSP, ip -#endif #ifdef CONFIG_BUILTIN_STACK_GUARD /* r2 contains k_thread */ @@ -461,13 +340,9 @@ in_fp_inactive: /* * Cortex-M: return from PendSV exception - * Cortex-R: return to the caller (z_arm_{exc,int}_exit, or z_arm_svc) */ bx lr -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) || \ - defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - /** * * @brief Service call handler @@ -686,244 +561,3 @@ valid_syscall_id: /* return from SVC to the modified LR - z_arm_do_syscall */ bx lr #endif /* CONFIG_USERSPACE */ - -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) - -#if defined(CONFIG_FPU_SHARING) -#define FPU_SF_SIZE ___fpu_t_SIZEOF -#else -#define FPU_SF_SIZE 0 -#endif - -/** - * - * @brief Service call handler - * - * The service call (svc) is used in the following occasions: - * - Cooperative context switching - * - IRQ offloading - * - Kernel run-time exceptions - * - */ -SECTION_FUNC(TEXT, z_arm_svc) -#if defined(CONFIG_USERSPACE) - /* Determine if incoming thread was in user context */ - push {r0} - mrs r0, spsr - and r0, #MODE_MASK - cmp r0, #MODE_USR - bne svc_system_thread - - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] - - /* Save away user stack pointer */ - cps #MODE_SYS - str sp, [r0, #_thread_offset_to_sp_usr] /* sp_usr */ - - /* Switch to privileged stack */ - ldr sp, [r0, #_thread_offset_to_priv_stack_end] /* priv stack end */ - cps #MODE_SVC - -svc_system_thread: - pop {r0} -#endif - - /* - * Switch to system mode to store r0-r3 to the process stack pointer. - * Save r12 and the lr as we could be swapping in another process and - * returning to a different location. - */ - srsdb #MODE_SYS! - cps #MODE_SYS - push {r0-r3, r12, lr} - -#if defined(CONFIG_FPU_SHARING) - sub sp, sp, #___fpu_t_SIZEOF - - /* - * Note that this handler was entered with the VFP unit enabled. - * The undefined instruction handler uses this to know that it - * needs to save the current floating context. - */ - vmrs r0, fpexc - str r0, [sp, #___fpu_t_SIZEOF - 4] - tst r0, #FPEXC_EN - beq _vfp_not_enabled - vmrs r0, fpscr - str r0, [sp, #___fpu_t_SIZEOF - 8] - - /* Disable VFP */ - mov r0, #0 - vmsr fpexc, r0 - -_vfp_not_enabled: - /* - * Mark where to store the floating context for the undefined - * instruction handler - */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_fp_ctx] - cmp r0, #0 - streq sp, [r2, #_kernel_offset_to_fp_ctx] -#endif /* CONFIG_FPU_SHARING */ - - mov ip, sp - - cps #MODE_SVC - - /* - * Store lr_svc to the SVC mode stack. This value will be restored prior to - * exiting the SVC call in z_arm_int_exit. - */ - push {lr} - - /* Align stack at double-word boundary */ - and r3, sp, #4 - sub sp, sp, r3 - push {r2, r3} - - /* Increment interrupt nesting count */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_nested] - add r0, r0, #1 - str r0, [r2, #_kernel_offset_to_nested] - - /* Get SVC number */ - mrs r0, spsr - tst r0, #0x20 - - ldreq r1, [lr, #-4] - biceq r1, #0xff000000 - beq demux - - ldr r1, [lr, #-2] - and r1, #0xff - - /* - * grab service call number: - * 0: context switch - * 1: irq_offload (if configured) - * 2: kernel panic or oops (software generated fatal exception) - * 3: system calls for memory protection - */ -demux: - -#if defined(CONFIG_USERSPACE) - cmp r1, #_SVC_CALL_SYSTEM_CALL - beq _do_syscall -#endif - - cmp r1, #_SVC_CALL_CONTEXT_SWITCH - beq _context_switch - - cmp r1, #_SVC_CALL_RUNTIME_EXCEPT - beq _oops - -#if CONFIG_IRQ_OFFLOAD - blx z_irq_do_offload /* call C routine which executes the offload */ - - /* exception return is done in z_arm_int_exit() */ - b z_arm_int_exit -#endif - -_context_switch: - /* handler mode exit, to PendSV */ - bl z_arm_pendsv - - b z_arm_int_exit - -_oops: - /* - * Pass the exception frame to z_do_kernel_oops. r0 contains the - * exception reason. - */ - cps #MODE_SYS - mov r0, sp - cps #MODE_SVC - bl z_do_kernel_oops - b z_arm_int_exit - -#if defined(CONFIG_USERSPACE) - /* - * System call will setup a jump to the _do_arm_syscall function - * running in system mode when returning from the exception. - * - * There is some trickery involved here because we have to preserve - * the original PC value so that we can return back to the caller of - * the SVC. - * - * On SVC exception, the USER/SYSTEM stack looks like the following: - * { possible FPU space } - r0 - r1 - r2 - r3 - r12 - LR - PC - SPSR - * - * Registers look like: - * r0 - arg1 - * r1 - arg2 - * r2 - arg3 - * r3 - arg4 - * r4 - arg5 - * r5 - arg6 - * r6 - call_id - * r8 - saved link register - */ -_do_syscall: - /* grab address of LR from stack frame */ - ldr r8, [ip, #(FPU_SF_SIZE + ___basic_sf_t_pc_OFFSET)] - - /* Make the exception return to system state */ - ldr r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_xpsr_OFFSET)] - - /* If leaving thumb mode, set the return address to thumb mode */ - tst r1, #T_BIT - orrne r8, #1 - - bic r1, #(MODE_MASK | T_BIT) - orr r1, r1, #MODE_SYS - str r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_xpsr_OFFSET)] - - /* - * Store the address of z_arm_do_syscall for the exit so the exception - * return goes there in system state. - */ - ldr r1, =z_arm_do_syscall - str r1, [ip, #(FPU_SF_SIZE + ___basic_sf_t_pc_OFFSET)] - - /* validate syscall limit, only set priv mode if valid */ - ldr ip, =K_SYSCALL_LIMIT - cmp r6, ip - blo valid_syscall_id - - /* bad syscall id. Set arg0 to bad id and set call_id to SYSCALL_BAD */ - cps #MODE_SYS - str r6, [sp] - cps #MODE_SVC - ldr r6, =K_SYSCALL_BAD - -valid_syscall_id: - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] - ldr r1, [r0, #_thread_offset_to_mode] - bic r1, #1 - /* Store (privileged) mode in thread's mode state variable */ - str r1, [r0, #_thread_offset_to_mode] - dsb - - /* ISB is not strictly necessary here (stack pointer is not being - * touched), but it's recommended to avoid executing pre-fetched - * instructions with the previous privilege. - */ - isb - - /* Return to _arm_do_syscall in system state. */ - b z_arm_int_exit -#endif - -GTEXT(z_arm_cortex_r_svc) -SECTION_FUNC(TEXT, z_arm_cortex_r_svc) - svc #_SVC_CALL_CONTEXT_SWITCH - bx lr - -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ From 9b739bc0f2f98a6bd6a6578b2c1937b67ce1aea7 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 4 Jul 2023 19:46:20 +0800 Subject: [PATCH 0295/4498] arch: arm: Separate common irq_manage and isr_wrapper code There are too many differences between Cortex-A/R and Cortex-M on irq code, e.g. Cortex-A/R use GIC and Cortex-M uses NVIC. For reducing the complexity and easier to maintain, this commit separates irq_manage.c and isr_wrapper.S into two different parts based on the architecture. This commit also Removes the part related to the option 'CONFIG_ARM_SECURE_FIRMWARE' in 'cortex_a_r/irq_manage.c' because this code is written for the Cortex-M architecture. Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 2 - arch/arm/core/cortex_a_r/CMakeLists.txt | 2 + arch/arm/core/cortex_a_r/irq_manage.c | 148 +++++++++++++++++++ arch/arm/core/{ => cortex_a_r}/isr_wrapper.S | 75 +--------- arch/arm/core/cortex_m/CMakeLists.txt | 2 + arch/arm/core/{ => cortex_m}/irq_manage.c | 65 +------- arch/arm/core/cortex_m/isr_wrapper.S | 136 +++++++++++++++++ 7 files changed, 292 insertions(+), 138 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/irq_manage.c rename arch/arm/core/{ => cortex_a_r}/isr_wrapper.S (70%) rename arch/arm/core/{ => cortex_m}/irq_manage.c (79%) create mode 100644 arch/arm/core/cortex_m/isr_wrapper.S diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 6388a6d9e6f..27c19d73dca 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -5,14 +5,12 @@ zephyr_library() zephyr_library_sources( cpu_idle.S fatal.c - irq_manage.c nmi.c nmi_on_reset.S prep_c.c thread.c ) -zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_CPP __aeabi_atexit.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index 2a573a84861..ccd28b7bd5f 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -14,8 +14,10 @@ zephyr_library_sources( vector_table.S swap.c swap_helper.S + irq_manage.c ) +zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) diff --git a/arch/arm/core/cortex_a_r/irq_manage.c b/arch/arm/core/cortex_a_r/irq_manage.c new file mode 100644 index 00000000000..a381fad2a48 --- /dev/null +++ b/arch/arm/core/cortex_a_r/irq_manage.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM Cortex-A and Cortex-R interrupt management + * + * + * Interrupt management: enabling/disabling and dynamic ISR + * connecting/replacing. SW_ISR_TABLE_DYNAMIC has to be enabled for + * connecting ISRs at runtime. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void z_arm_reserved(void); + +/* + * For Cortex-A and Cortex-R cores, the default interrupt controller is the ARM + * Generic Interrupt Controller (GIC) and therefore the architecture interrupt + * control functions are mapped to the GIC driver interface. + * + * When a custom interrupt controller is used (i.e. + * CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER is enabled), the architecture + * interrupt control functions are mapped to the SoC layer in + * `include/arch/arm/irq.h`. + */ + +#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) +void arch_irq_enable(unsigned int irq) +{ + arm_gic_irq_enable(irq); +} + +void arch_irq_disable(unsigned int irq) +{ + arm_gic_irq_disable(irq); +} + +int arch_irq_is_enabled(unsigned int irq) +{ + return arm_gic_irq_is_enabled(irq); +} + +/** + * @internal + * + * @brief Set an interrupt's priority + * + * The priority is verified if ASSERT_ON is enabled. The maximum number + * of priority levels is a little complex, as there are some hardware + * priority levels which are reserved: three for various types of exceptions, + * and possibly one additional to support zero latency interrupts. + */ +void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) +{ + arm_gic_irq_set_priority(irq, prio, flags); +} +#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + +void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); + +/** + * + * @brief Spurious interrupt handler + * + * Installed in all _sw_isr_table slots at boot time. Throws an error if + * called. + * + */ +void z_irq_spurious(const void *unused) +{ + ARG_UNUSED(unused); + + z_arm_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); +} + +#ifdef CONFIG_PM +void _arch_isr_direct_pm(void) +{ + unsigned int key; + + /* irq_lock() does what we want for this CPU */ + key = irq_lock(); + + if (_kernel.idle) { + _kernel.idle = 0; + z_pm_save_idle_exit(); + } + + irq_unlock(key); +} +#endif + +#ifdef CONFIG_DYNAMIC_INTERRUPTS +#ifdef CONFIG_GEN_ISR_TABLES +int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) +{ + z_isr_install(irq, routine, parameter); + z_arm_irq_priority_set(irq, priority, flags); + return irq; +} +#endif /* CONFIG_GEN_ISR_TABLES */ + +#ifdef CONFIG_DYNAMIC_DIRECT_INTERRUPTS +static inline void z_arm_irq_dynamic_direct_isr_dispatch(void) +{ + uint32_t irq = __get_IPSR() - 16; + + if (irq < IRQ_TABLE_SIZE) { + struct _isr_table_entry *isr_entry = &_sw_isr_table[irq]; + + isr_entry->isr(isr_entry->arg); + } +} + +ISR_DIRECT_DECLARE(z_arm_irq_direct_dynamic_dispatch_reschedule) +{ + z_arm_irq_dynamic_direct_isr_dispatch(); + + return 1; +} + +ISR_DIRECT_DECLARE(z_arm_irq_direct_dynamic_dispatch_no_reschedule) +{ + z_arm_irq_dynamic_direct_isr_dispatch(); + + return 0; +} + +#endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */ + +#endif /* CONFIG_DYNAMIC_INTERRUPTS */ diff --git a/arch/arm/core/isr_wrapper.S b/arch/arm/core/cortex_a_r/isr_wrapper.S similarity index 70% rename from arch/arm/core/isr_wrapper.S rename to arch/arm/core/cortex_a_r/isr_wrapper.S index 205420c5dcc..dc5fa9cac04 100644 --- a/arch/arm/core/isr_wrapper.S +++ b/arch/arm/core/cortex_a_r/isr_wrapper.S @@ -7,7 +7,7 @@ /** * @file - * @brief ARM Cortex-A, Cortex-M and Cortex-R wrapper for ISRs with parameter + * @brief ARM Cortex-A and Cortex-R wrapper for ISRs with parameter * * Wrapper installed in vector table for handling dynamic interrupts that accept * a parameter. @@ -45,10 +45,6 @@ GTEXT(z_arm_int_exit) */ SECTION_FUNC(TEXT, _isr_wrapper) -#if defined(CONFIG_CPU_CORTEX_M) - push {r0,lr} /* r0, lr are now the first items on the stack */ -#elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) - #if defined(CONFIG_USERSPACE) /* See comment below about svc stack usage */ cps #MODE_SVC @@ -147,7 +143,6 @@ _vfp_not_enabled: ldr r0, [r2, #_kernel_offset_to_nested] add r0, r0, #1 str r0, [r2, #_kernel_offset_to_nested] -#endif /* CONFIG_CPU_CORTEX_M */ #ifdef CONFIG_TRACING_ISR bl sys_trace_isr_enter @@ -163,65 +158,21 @@ _vfp_not_enabled: * is called with interrupts disabled. */ -#if defined(CONFIG_CPU_CORTEX_M) - /* - * Disable interrupts to prevent nesting while exiting idle state. This - * is only necessary for the Cortex-M because it is the only ARM - * architecture variant that automatically enables interrupts when - * entering an ISR. - */ - cpsid i /* PRIMASK = 1 */ -#endif - /* is this a wakeup from idle ? */ ldr r2, =_kernel /* requested idle duration, in ticks */ ldr r0, [r2, #_kernel_offset_to_idle] cmp r0, #0 -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - beq _idle_state_cleared - movs.n r1, #0 - /* clear kernel idle state */ - str r1, [r2, #_kernel_offset_to_idle] - bl z_pm_save_idle_exit -_idle_state_cleared: - -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - ittt ne - movne r1, #0 - /* clear kernel idle state */ - strne r1, [r2, #_kernel_offset_to_idle] - blne z_pm_save_idle_exit -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) beq _idle_state_cleared movs r1, #0 /* clear kernel idle state */ str r1, [r2, #_kernel_offset_to_idle] bl z_pm_save_idle_exit _idle_state_cleared: -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - -#if defined(CONFIG_CPU_CORTEX_M) - cpsie i /* re-enable interrupts (PRIMASK = 0) */ -#endif #endif /* CONFIG_PM */ -#if defined(CONFIG_CPU_CORTEX_M) - mrs r0, IPSR /* get exception number */ -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - ldr r1, =16 - subs r0, r1 /* get IRQ number */ - lsls r0, #3 /* table is 8-byte wide */ -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - sub r0, r0, #16 /* get IRQ number */ - lsl r0, r0, #3 /* table is 8-byte wide */ -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) /* Get active IRQ number from the interrupt controller */ #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) bl arm_gic_get_active @@ -230,11 +181,7 @@ _idle_state_cleared: #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ push {r0, r1} lsl r0, r0, #3 /* table is 8-byte wide */ -#else -#error Unknown ARM architecture -#endif /* CONFIG_CPU_CORTEX_M */ -#if !defined(CONFIG_CPU_CORTEX_M) /* * Enable interrupts to allow nesting. * @@ -254,7 +201,6 @@ _idle_state_cleared: lsl r1, r1, #3 cmp r0, r1 bge spurious_continue -#endif /* !CONFIG_CPU_CORTEX_M */ ldr r1, =_sw_isr_table add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay @@ -263,7 +209,6 @@ _idle_state_cleared: ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ blx r3 /* call ISR */ -#if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) spurious_continue: /* Signal end-of-interrupt */ pop {r0, r1} @@ -272,29 +217,11 @@ spurious_continue: #else bl z_soc_irq_eoi #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ -#endif /* CONFIG_CPU_AARCH32_CORTEX_R || CONFIG_CPU_AARCH32_CORTEX_A */ #ifdef CONFIG_TRACING_ISR bl sys_trace_isr_exit #endif -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - pop {r0, r3} - mov lr, r3 -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - pop {r0, lr} -#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) - /* - * r0 and lr_irq were saved on the process stack since a swap could - * happen. exc_exit will handle getting those values back - * from the process stack to return to the correct location - * so there is no need to do anything here. - */ -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - /* Use 'bx' instead of 'b' because 'bx' can jump further, and use * 'bx' instead of 'blx' because exception return is done in * z_arm_int_exit() */ diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index f1ac9eed64c..e4e67870e54 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -14,8 +14,10 @@ zephyr_library_sources( vector_table.S swap.c swap_helper.S + irq_manage.c ) +zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) diff --git a/arch/arm/core/irq_manage.c b/arch/arm/core/cortex_m/irq_manage.c similarity index 79% rename from arch/arm/core/irq_manage.c rename to arch/arm/core/cortex_m/irq_manage.c index 6f6a590b44a..cd0c6f6e5bf 100644 --- a/arch/arm/core/irq_manage.c +++ b/arch/arm/core/cortex_m/irq_manage.c @@ -6,7 +6,7 @@ /** * @file - * @brief ARM Cortex-A, Cortex-M and Cortex-R interrupt management + * @brief ARM Cortex-M interrupt management * * * Interrupt management: enabling/disabling and dynamic ISR @@ -16,12 +16,7 @@ #include #include -#if defined(CONFIG_CPU_CORTEX_M) #include -#elif defined(CONFIG_CPU_AARCH32_CORTEX_A) \ - || defined(CONFIG_CPU_AARCH32_CORTEX_R) -#include -#endif #include #include #include @@ -33,7 +28,6 @@ extern void z_arm_reserved(void); -#if defined(CONFIG_CPU_CORTEX_M) #define NUM_IRQS_PER_REG 32 #define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG) #define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG) @@ -96,53 +90,6 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) NVIC_SetPriority((IRQn_Type)irq, prio); } -#elif defined(CONFIG_CPU_AARCH32_CORTEX_A) \ - || defined(CONFIG_CPU_AARCH32_CORTEX_R) -/* - * For Cortex-A and Cortex-R cores, the default interrupt controller is the ARM - * Generic Interrupt Controller (GIC) and therefore the architecture interrupt - * control functions are mapped to the GIC driver interface. - * - * When a custom interrupt controller is used (i.e. - * CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER is enabled), the architecture - * interrupt control functions are mapped to the SoC layer in - * `include/arch/arm/aarch32/irq.h`. - */ - -#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) -void arch_irq_enable(unsigned int irq) -{ - arm_gic_irq_enable(irq); -} - -void arch_irq_disable(unsigned int irq) -{ - arm_gic_irq_disable(irq); -} - -int arch_irq_is_enabled(unsigned int irq) -{ - return arm_gic_irq_is_enabled(irq); -} - -/** - * @internal - * - * @brief Set an interrupt's priority - * - * The priority is verified if ASSERT_ON is enabled. The maximum number - * of priority levels is a little complex, as there are some hardware - * priority levels which are reserved: three for various types of exceptions, - * and possibly one additional to support zero latency interrupts. - */ -void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) -{ - arm_gic_irq_set_priority(irq, prio, flags); -} -#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ - -#endif /* CONFIG_CPU_CORTEX_M */ - void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); /** @@ -163,10 +110,7 @@ void z_irq_spurious(const void *unused) #ifdef CONFIG_PM void _arch_isr_direct_pm(void) { -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ - || defined(CONFIG_ARMV7_R) \ - || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) unsigned int key; /* irq_lock() does what we want for this CPU */ @@ -186,10 +130,7 @@ void _arch_isr_direct_pm(void) z_pm_save_idle_exit(); } -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ - || defined(CONFIG_ARMV7_R) \ - || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) irq_unlock(key); #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __asm__ volatile("cpsie i" : : : "memory"); diff --git a/arch/arm/core/cortex_m/isr_wrapper.S b/arch/arm/core/cortex_m/isr_wrapper.S new file mode 100644 index 00000000000..78ad6cd1e83 --- /dev/null +++ b/arch/arm/core/cortex_m/isr_wrapper.S @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM Cortex-M wrapper for ISRs with parameter + * + * Wrapper installed in vector table for handling dynamic interrupts that accept + * a parameter. + */ +/* + * Tell armclang that stack alignment are ensured. + */ +.eabi_attribute Tag_ABI_align_preserved, 1 + +#include +#include +#include +#include +#include + + +_ASM_FILE_PROLOGUE + +GDATA(_sw_isr_table) + +GTEXT(_isr_wrapper) +GTEXT(z_arm_int_exit) + +/** + * + * @brief Wrapper around ISRs when inserted in software ISR table + * + * When inserted in the vector table, _isr_wrapper() demuxes the ISR table + * using the running interrupt number as the index, and invokes the registered + * ISR with its corresponding argument. When returning from the ISR, it + * determines if a context switch needs to happen (see documentation for + * z_arm_pendsv()) and pends the PendSV exception if so: the latter will + * perform the context switch itself. + * + */ +SECTION_FUNC(TEXT, _isr_wrapper) + + push {r0,lr} /* r0, lr are now the first items on the stack */ + +#ifdef CONFIG_TRACING_ISR + bl sys_trace_isr_enter +#endif + +#ifdef CONFIG_PM + /* + * All interrupts are disabled when handling idle wakeup. For tickless + * idle, this ensures that the calculation and programming of the + * device for the next timer deadline is not interrupted. For + * non-tickless idle, this ensures that the clearing of the kernel idle + * state is not interrupted. In each case, z_pm_save_idle_exit + * is called with interrupts disabled. + */ + + /* + * Disable interrupts to prevent nesting while exiting idle state. This + * is only necessary for the Cortex-M because it is the only ARM + * architecture variant that automatically enables interrupts when + * entering an ISR. + */ + cpsid i /* PRIMASK = 1 */ + + /* is this a wakeup from idle ? */ + ldr r2, =_kernel + /* requested idle duration, in ticks */ + ldr r0, [r2, #_kernel_offset_to_idle] + cmp r0, #0 + +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + beq _idle_state_cleared + movs.n r1, #0 + /* clear kernel idle state */ + str r1, [r2, #_kernel_offset_to_idle] + bl z_pm_save_idle_exit +_idle_state_cleared: + +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + ittt ne + movne r1, #0 + /* clear kernel idle state */ + strne r1, [r2, #_kernel_offset_to_idle] + blne z_pm_save_idle_exit +#else +#error Unknown ARM architecture +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ + + cpsie i /* re-enable interrupts (PRIMASK = 0) */ + +#endif /* CONFIG_PM */ + + mrs r0, IPSR /* get exception number */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + ldr r1, =16 + subs r0, r1 /* get IRQ number */ + lsls r0, #3 /* table is 8-byte wide */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + sub r0, r0, #16 /* get IRQ number */ + lsl r0, r0, #3 /* table is 8-byte wide */ +#else +#error Unknown ARM architecture +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ + + ldr r1, =_sw_isr_table + add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay + * in thumb mode */ + + ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ + blx r3 /* call ISR */ + +#ifdef CONFIG_TRACING_ISR + bl sys_trace_isr_exit +#endif + +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + pop {r0, r3} + mov lr, r3 +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + pop {r0, lr} +#else +#error Unknown ARM architecture +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ + + /* Use 'bx' instead of 'b' because 'bx' can jump further, and use + * 'bx' instead of 'blx' because exception return is done in + * z_arm_int_exit() */ + ldr r1, =z_arm_int_exit + bx r1 From 38789dbd5ef93b41b423e98030203596990a48b2 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Wed, 12 Jul 2023 18:31:16 +0800 Subject: [PATCH 0296/4498] arch: arm: Separate common exc header file This commit Separate exc.h into two header files, 'cortex_a_r/exc.h' and 'cortex_m/exc.h'. Still, keep 'exc.h' so that we don't need to change other files which include it. Signed-off-by: Huifeng Zhang --- include/zephyr/arch/arm/cortex_a_r/exc.h | 88 ++++++++++++++ include/zephyr/arch/arm/cortex_m/exc.h | 132 ++++++++++++++++++++ include/zephyr/arch/arm/exc.h | 148 +---------------------- 3 files changed, 224 insertions(+), 144 deletions(-) create mode 100644 include/zephyr/arch/arm/cortex_a_r/exc.h create mode 100644 include/zephyr/arch/arm/cortex_m/exc.h diff --git a/include/zephyr/arch/arm/cortex_a_r/exc.h b/include/zephyr/arch/arm/cortex_a_r/exc.h new file mode 100644 index 00000000000..92f074f1b36 --- /dev/null +++ b/include/zephyr/arch/arm/cortex_a_r/exc.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM AArch32 Cortex-A and Cortex-R public exception handling + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_A_R_EXC_H_ +#define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_A_R_EXC_H_ + +#ifdef _ASMLANGUAGE +GTEXT(z_arm_exc_exit); +#else +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + +/* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine calls. + * + * Registers s0-s15 (d0-d7, q0-q3) do not have to be preserved (and can be used + * for passing arguments or returning results in standard procedure-call variants). + * + * Registers d16-d31 (q8-q15), do not have to be preserved. + */ +struct __fpu_sf { + uint32_t s[16]; /* s0~s15 (d0-d7) */ +#ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 + uint64_t d[16]; /* d16~d31 */ +#endif + uint32_t fpscr; + uint32_t undefined; +}; +#endif + +/* Additional register state that is not stacked by hardware on exception + * entry. + * + * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error(). + * When information for a member is unavailable, the field is set to zero. + */ +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) +struct __extra_esf_info { + _callee_saved_t *callee; + uint32_t msp; + uint32_t exc_return; +}; +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ + +struct __esf { +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) + struct __extra_esf_info extra_info; +#endif +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + struct __fpu_sf fpu; +#endif + struct __basic_sf { + sys_define_gpr_with_alias(a1, r0); + sys_define_gpr_with_alias(a2, r1); + sys_define_gpr_with_alias(a3, r2); + sys_define_gpr_with_alias(a4, r3); + sys_define_gpr_with_alias(ip, r12); + sys_define_gpr_with_alias(lr, r14); + sys_define_gpr_with_alias(pc, r15); + uint32_t xpsr; + } basic; +}; + +extern uint32_t z_arm_coredump_fault_sp; + +typedef struct __esf z_arch_esf_t; + +extern void z_arm_exc_exit(bool fatal); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_A_R_EXC_H_ */ diff --git a/include/zephyr/arch/arm/cortex_m/exc.h b/include/zephyr/arch/arm/cortex_m/exc.h new file mode 100644 index 00000000000..8a2cfc8cc3f --- /dev/null +++ b/include/zephyr/arch/arm/cortex_m/exc.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM AArch32 Cortex-M public exception handling + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_M_EXC_H_ +#define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_M_EXC_H_ + +#include + +#include + +/* for assembler, only works with constants */ +#define Z_EXC_PRIO(pri) (((pri) << (8 - NUM_IRQ_PRIO_BITS)) & 0xff) + +/* + * In architecture variants with non-programmable fault exceptions + * (e.g. Cortex-M Baseline variants), hardware ensures processor faults + * are given the highest interrupt priority level. SVCalls are assigned + * the highest configurable priority level (level 0); note, however, that + * this interrupt level may be shared with HW interrupts. + * + * In Cortex variants with programmable fault exception priorities we + * assign the highest interrupt priority level (level 0) to processor faults + * with configurable priority. + * The highest priority level may be shared with either Zero-Latency IRQs (if + * support for the feature is enabled) or with SVCall priority level. + * Regular HW IRQs are always assigned priority levels lower than the priority + * levels for SVCalls, Zero-Latency IRQs and processor faults. + * + * PendSV IRQ (which is used in Cortex-M variants to implement thread + * context-switching) is assigned the lowest IRQ priority level. + */ +#if defined(CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS) +#define _EXCEPTION_RESERVED_PRIO 1 +#else +#define _EXCEPTION_RESERVED_PRIO 0 +#endif + +#define _EXC_FAULT_PRIO 0 +#define _EXC_ZERO_LATENCY_IRQS_PRIO 0 +#define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ + (CONFIG_ZERO_LATENCY_LEVELS), (0)) +#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) +#define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) + +#define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET) + +/* Use lowest possible priority level for PendSV */ +#define _EXC_PENDSV_PRIO 0xff +#define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO) + +#ifdef _ASMLANGUAGE +GTEXT(z_arm_exc_exit); +#else +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + +/* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine calls. + * + * Registers s0-s15 (d0-d7, q0-q3) do not have to be preserved (and can be used + * for passing arguments or returning results in standard procedure-call variants). + * + * Registers d16-d31 (q8-q15), do not have to be preserved. + */ +struct __fpu_sf { + uint32_t s[16]; /* s0~s15 (d0-d7) */ +#ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 + uint64_t d[16]; /* d16~d31 */ +#endif + uint32_t fpscr; + uint32_t undefined; +}; +#endif + +/* Additional register state that is not stacked by hardware on exception + * entry. + * + * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error(). + * When information for a member is unavailable, the field is set to zero. + */ +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) +struct __extra_esf_info { + _callee_saved_t *callee; + uint32_t msp; + uint32_t exc_return; +}; +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ + +struct __esf { + struct __basic_sf { + sys_define_gpr_with_alias(a1, r0); + sys_define_gpr_with_alias(a2, r1); + sys_define_gpr_with_alias(a3, r2); + sys_define_gpr_with_alias(a4, r3); + sys_define_gpr_with_alias(ip, r12); + sys_define_gpr_with_alias(lr, r14); + sys_define_gpr_with_alias(pc, r15); + uint32_t xpsr; + } basic; +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + struct __fpu_sf fpu; +#endif +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) + struct __extra_esf_info extra_info; +#endif +}; + +extern uint32_t z_arm_coredump_fault_sp; + +typedef struct __esf z_arch_esf_t; + +extern void z_arm_exc_exit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_M_EXC_H_ */ diff --git a/include/zephyr/arch/arm/exc.h b/include/zephyr/arch/arm/exc.h index 62fd211065a..9cd664e2c6b 100644 --- a/include/zephyr/arch/arm/exc.h +++ b/include/zephyr/arch/arm/exc.h @@ -16,151 +16,11 @@ #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ #if defined(CONFIG_CPU_CORTEX_M) -#include - -#include - -/* for assembler, only works with constants */ -#define Z_EXC_PRIO(pri) (((pri) << (8 - NUM_IRQ_PRIO_BITS)) & 0xff) - -/* - * In architecture variants with non-programmable fault exceptions - * (e.g. Cortex-M Baseline variants), hardware ensures processor faults - * are given the highest interrupt priority level. SVCalls are assigned - * the highest configurable priority level (level 0); note, however, that - * this interrupt level may be shared with HW interrupts. - * - * In Cortex variants with programmable fault exception priorities we - * assign the highest interrupt priority level (level 0) to processor faults - * with configurable priority. - * The highest priority level may be shared with either Zero-Latency IRQs (if - * support for the feature is enabled) or with SVCall priority level. - * Regular HW IRQs are always assigned priority levels lower than the priority - * levels for SVCalls, Zero-Latency IRQs and processor faults. - * - * PendSV IRQ (which is used in Cortex-M variants to implement thread - * context-switching) is assigned the lowest IRQ priority level. - */ -#if defined(CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS) -#define _EXCEPTION_RESERVED_PRIO 1 +#include +#elif defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R) +#include #else -#define _EXCEPTION_RESERVED_PRIO 0 -#endif - -#define _EXC_FAULT_PRIO 0 -#define _EXC_ZERO_LATENCY_IRQS_PRIO 0 -#define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ - (CONFIG_ZERO_LATENCY_LEVELS), (0)) -#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) -#define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) - -#define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET) - -/* Use lowest possible priority level for PendSV */ -#define _EXC_PENDSV_PRIO 0xff -#define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO) +#error Unknown ARM architecture #endif /* CONFIG_CPU_CORTEX_M */ -#ifdef _ASMLANGUAGE -GTEXT(z_arm_exc_exit); -#else -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - -/* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine calls. - * - * Registers s0-s15 (d0-d7, q0-q3) do not have to be preserved (and can be used - * for passing arguments or returning results in standard procedure-call variants). - * - * Registers d16-d31 (q8-q15), do not have to be preserved. - */ -struct __fpu_sf { - uint32_t s[16]; /* s0~s15 (d0-d7) */ -#ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 - uint64_t d[16]; /* d16~d31 */ -#endif - uint32_t fpscr; - uint32_t undefined; -}; -#endif - -/* Additional register state that is not stacked by hardware on exception - * entry. - * - * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error(). - * When information for a member is unavailable, the field is set to zero. - */ -#if defined(CONFIG_EXTRA_EXCEPTION_INFO) -struct __extra_esf_info { - _callee_saved_t *callee; - uint32_t msp; - uint32_t exc_return; -}; -#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ - -#if defined(CONFIG_CPU_CORTEX_M) - -struct __esf { - struct __basic_sf { - sys_define_gpr_with_alias(a1, r0); - sys_define_gpr_with_alias(a2, r1); - sys_define_gpr_with_alias(a3, r2); - sys_define_gpr_with_alias(a4, r3); - sys_define_gpr_with_alias(ip, r12); - sys_define_gpr_with_alias(lr, r14); - sys_define_gpr_with_alias(pc, r15); - uint32_t xpsr; - } basic; -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - struct __fpu_sf fpu; -#endif -#if defined(CONFIG_EXTRA_EXCEPTION_INFO) - struct __extra_esf_info extra_info; -#endif -}; - -#else - -struct __esf { -#if defined(CONFIG_EXTRA_EXCEPTION_INFO) - struct __extra_esf_info extra_info; -#endif -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - struct __fpu_sf fpu; -#endif - struct __basic_sf { - sys_define_gpr_with_alias(a1, r0); - sys_define_gpr_with_alias(a2, r1); - sys_define_gpr_with_alias(a3, r2); - sys_define_gpr_with_alias(a4, r3); - sys_define_gpr_with_alias(ip, r12); - sys_define_gpr_with_alias(lr, r14); - sys_define_gpr_with_alias(pc, r15); - uint32_t xpsr; - } basic; -}; - -#endif - -extern uint32_t z_arm_coredump_fault_sp; - -typedef struct __esf z_arch_esf_t; - -#ifdef CONFIG_CPU_CORTEX_M -extern void z_arm_exc_exit(void); -#else -extern void z_arm_exc_exit(bool fatal); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _ASMLANGUAGE */ - #endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ */ From 7dbbc49c0707815cb392199e065e74d98c7747ae Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 18 Jul 2023 15:33:29 +0800 Subject: [PATCH 0297/4498] arch: arm: Separate common prep_c code This commit Separate 'prep_c.c' into two file based on the architecture, one is 'cortex_m/prep_c.c', the other is 'cortex_a_r/prep_c.c' Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 1 - arch/arm/core/cortex_a_r/CMakeLists.txt | 1 + arch/arm/core/cortex_a_r/prep_c.c | 155 ++++++++++++++++++++++++ arch/arm/core/cortex_m/CMakeLists.txt | 1 + arch/arm/core/{ => cortex_m}/prep_c.c | 78 ------------ 5 files changed, 157 insertions(+), 79 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/prep_c.c rename arch/arm/core/{ => cortex_m}/prep_c.c (71%) diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 27c19d73dca..a55e8406507 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -7,7 +7,6 @@ zephyr_library_sources( fatal.c nmi.c nmi_on_reset.S - prep_c.c thread.c ) diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index ccd28b7bd5f..6c107bb4065 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources( swap.c swap_helper.S irq_manage.c + prep_c.c ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/cortex_a_r/prep_c.c b/arch/arm/core/cortex_a_r/prep_c.c new file mode 100644 index 00000000000..dc7786af59e --- /dev/null +++ b/arch/arm/core/cortex_a_r/prep_c.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Full C support initialization + * + * + * Initialization of full C support: zero the .bss, copy the .data if XIP, + * call z_cstart(). + * + * Stack is available in this module, but not the global data/bss until their + * initialization is performed. + */ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A) +#include +#endif + +#if defined(__GNUC__) +/* + * GCC can detect if memcpy is passed a NULL argument, however one of + * the cases of relocate_vector_table() it is valid to pass NULL, so we + * suppress the warning for this case. We need to do this before + * string.h is included to get the declaration of memcpy. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnonnull" +#endif + +#include + +#if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) +Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) +void *_vector_table_pointer; +#endif + +#if defined(CONFIG_AARCH32_ARMV8_R) + +#define VECTOR_ADDRESS ((uintptr_t)_vector_start) + +static inline void relocate_vector_table(void) +{ + write_sctlr(read_sctlr() & ~HIVECS); + write_vbar(VECTOR_ADDRESS & VBAR_MASK); + barrier_isync_fence_full(); +} + +#else +#define VECTOR_ADDRESS 0 + +void __weak relocate_vector_table(void) +{ +#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ + !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) + write_sctlr(read_sctlr() & ~HIVECS); + size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; + (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); +#elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) + _vector_table_pointer = _vector_start; +#endif +} + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#endif /* CONFIG_AARCH32_ARMV8_R */ + +#if defined(CONFIG_CPU_HAS_FPU) + +static inline void z_arm_floating_point_init(void) +{ +#if defined(CONFIG_FPU) + uint32_t reg_val = 0; + + /* + * CPACR : Coprocessor Access Control Register -> CP15 1/0/2 + * comp. ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, + * chap. B4.1.40 + * + * Must be accessed in >= PL1! + * [23..22] = CP11 access control bits, + * [21..20] = CP10 access control bits. + * 11b = Full access as defined for the respective CP, + * 10b = UNDEFINED, + * 01b = Access at PL1 only, + * 00b = No access. + */ + reg_val = __get_CPACR(); + /* Enable PL1 access to CP10, CP11 */ + reg_val |= (CPACR_CP10(CPACR_FA) | CPACR_CP11(CPACR_FA)); + __set_CPACR(reg_val); + barrier_isync_fence_full(); + +#if !defined(CONFIG_FPU_SHARING) + /* + * FPEXC: Floating-Point Exception Control register + * comp. ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, + * chap. B6.1.38 + * + * Must be accessed in >= PL1! + * [31] EX bit = determines which registers comprise the current state + * of the FPU. The effects of setting this bit to 1 are + * subarchitecture defined. If EX=0, the following + * registers contain the complete current state + * information of the FPU and must therefore be saved + * during a context switch: + * * D0-D15 + * * D16-D31 if implemented + * * FPSCR + * * FPEXC. + * [30] EN bit = Advanced SIMD/Floating Point Extensions enable bit. + * [29..00] = Subarchitecture defined -> not relevant here. + */ + __set_FPEXC(FPEXC_EN); +#endif +#endif +} + +#endif /* CONFIG_CPU_HAS_FPU */ + +extern FUNC_NORETURN void z_cstart(void); + +/** + * + * @brief Prepare to and run C code + * + * This routine prepares for the execution of and runs C code. + * + */ +void z_arm_prep_c(void) +{ + relocate_vector_table(); +#if defined(CONFIG_CPU_HAS_FPU) + z_arm_floating_point_init(); +#endif + z_bss_zero(); + z_data_copy(); +#if ((defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A)) && defined(CONFIG_INIT_STACKS)) + z_arm_init_stacks(); +#endif + z_arm_interrupt_init(); + z_cstart(); + CODE_UNREACHABLE; +} diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index e4e67870e54..56aa2bb0963 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources( swap.c swap_helper.S irq_manage.c + prep_c.c ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/prep_c.c b/arch/arm/core/cortex_m/prep_c.c similarity index 71% rename from arch/arm/core/prep_c.c rename to arch/arm/core/cortex_m/prep_c.c index eab2d60a94f..ad166775ca4 100644 --- a/arch/arm/core/prep_c.c +++ b/arch/arm/core/cortex_m/prep_c.c @@ -21,14 +21,6 @@ #include #include -#if !defined(CONFIG_CPU_CORTEX_M) -#include -#endif - -#if defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A) -#include -#endif - #if defined(__GNUC__) /* * GCC can detect if memcpy is passed a NULL argument, however one of @@ -58,17 +50,6 @@ static inline void relocate_vector_table(void) barrier_isync_fence_full(); } -#elif defined(CONFIG_AARCH32_ARMV8_R) - -#define VECTOR_ADDRESS ((uintptr_t)_vector_start) - -static inline void relocate_vector_table(void) -{ - write_sctlr(read_sctlr() & ~HIVECS); - write_vbar(VECTOR_ADDRESS & VBAR_MASK); - barrier_isync_fence_full(); -} - #else #define VECTOR_ADDRESS 0 @@ -76,9 +57,6 @@ void __weak relocate_vector_table(void) { #if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) -#if !defined(CONFIG_CPU_CORTEX_M) - write_sctlr(read_sctlr() & ~HIVECS); -#endif size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); #elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) @@ -93,7 +71,6 @@ void __weak relocate_vector_table(void) #endif /* CONFIG_CPU_CORTEX_M_HAS_VTOR */ #if defined(CONFIG_CPU_HAS_FPU) -#if defined(CONFIG_CPU_CORTEX_M) static inline void z_arm_floating_point_init(void) { /* @@ -191,58 +168,6 @@ static inline void z_arm_floating_point_init(void) #endif } -#else - -static inline void z_arm_floating_point_init(void) -{ -#if defined(CONFIG_FPU) - uint32_t reg_val = 0; - - /* - * CPACR : Coprocessor Access Control Register -> CP15 1/0/2 - * comp. ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, - * chap. B4.1.40 - * - * Must be accessed in >= PL1! - * [23..22] = CP11 access control bits, - * [21..20] = CP10 access control bits. - * 11b = Full access as defined for the respective CP, - * 10b = UNDEFINED, - * 01b = Access at PL1 only, - * 00b = No access. - */ - reg_val = __get_CPACR(); - /* Enable PL1 access to CP10, CP11 */ - reg_val |= (CPACR_CP10(CPACR_FA) | CPACR_CP11(CPACR_FA)); - __set_CPACR(reg_val); - barrier_isync_fence_full(); - -#if !defined(CONFIG_FPU_SHARING) - /* - * FPEXC: Floating-Point Exception Control register - * comp. ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, - * chap. B6.1.38 - * - * Must be accessed in >= PL1! - * [31] EX bit = determines which registers comprise the current state - * of the FPU. The effects of setting this bit to 1 are - * subarchitecture defined. If EX=0, the following - * registers contain the complete current state - * information of the FPU and must therefore be saved - * during a context switch: - * * D0-D15 - * * D16-D31 if implemented - * * FPSCR - * * FPEXC. - * [30] EN bit = Advanced SIMD/Floating Point Extensions enable bit. - * [29..00] = Subarchitecture defined -> not relevant here. - */ - __set_FPEXC(FPEXC_EN); -#endif -#endif -} - -#endif /* CONFIG_CPU_CORTEX_M */ #endif /* CONFIG_CPU_HAS_FPU */ extern FUNC_NORETURN void z_cstart(void); @@ -262,9 +187,6 @@ void z_arm_prep_c(void) #endif z_bss_zero(); z_data_copy(); -#if ((defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A)) && defined(CONFIG_INIT_STACKS)) - z_arm_init_stacks(); -#endif z_arm_interrupt_init(); z_cstart(); CODE_UNREACHABLE; From 7e5e08b3abc143a9ad1b80332c44ea720c16694b Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Wed, 19 Jul 2023 15:52:16 +0800 Subject: [PATCH 0298/4498] arch: arm: Separate common thread code This commit separates thread.c into two source files, 'cortex_a_r/thread.c' and 'cortex_m/thread.c, it also introduces some changes. 1. Migrate 'thread.c' and 'cortex_m/thread.c'. 2. Migrate 'thread.c' and 'cortex_a_r/thread.c' 3. Remove the 'z_arm_mpu_stack_guard_and_fpu_adjust' function as this is obviously written for Cortex-M architecture. 4. Remove the 'z_arm_prepare_switch_to_main' function as this is only used by Cortex-M architecture. Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 1 - arch/arm/core/cortex_a_r/CMakeLists.txt | 1 + arch/arm/core/cortex_a_r/thread.c | 384 ++++++++++++++ arch/arm/core/cortex_m/CMakeLists.txt | 2 +- arch/arm/core/cortex_m/thread.c | 632 ++++++++++++++++++++++ arch/arm/core/thread.c | 667 ------------------------ 6 files changed, 1018 insertions(+), 669 deletions(-) delete mode 100644 arch/arm/core/thread.c diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index a55e8406507..3f9d6a7deac 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -7,7 +7,6 @@ zephyr_library_sources( fatal.c nmi.c nmi_on_reset.S - thread.c ) zephyr_library_sources_ifdef(CONFIG_CPP __aeabi_atexit.c) diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index 6c107bb4065..aaaf230679d 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -16,6 +16,7 @@ zephyr_library_sources( swap_helper.S irq_manage.c prep_c.c + thread.c ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/cortex_a_r/thread.c b/arch/arm/core/cortex_a_r/thread.c index 736797f4011..c5dbdc81ba6 100644 --- a/arch/arm/core/cortex_a_r/thread.c +++ b/arch/arm/core/cortex_a_r/thread.c @@ -1,12 +1,235 @@ /* + * Copyright (c) 2013-2014 Wind River Systems, Inc. * Copyright (c) 2021 Lexmark International, Inc. * * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief New thread creation for ARM Cortex-A and Cortex-R + * + * Core thread related primitives for the ARM Cortex-A and + * Cortex-R processor architecture. + */ + +#include +#include +#include #include #include +#if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) +#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - \ + MPU_GUARD_ALIGN_AND_SIZE) +#else +#define FP_GUARD_EXTRA_SIZE 0 +#endif + +#ifndef EXC_RETURN_FTYPE +/* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_FTYPE (0x00000010UL) +#endif + +/* Default last octet of EXC_RETURN, for threads that have not run yet. + * The full EXC_RETURN value will be e.g. 0xFFFFFFBC. + */ +#define DEFAULT_EXC_RETURN 0xFD; + +/* An initial context, to be "restored" by z_arm_pendsv(), is put at the other + * end of the stack, and thus reusable by the stack when not needed anymore. + * + * The initial context is an exception stack frame (ESF) since exiting the + * PendSV exception will want to pop an ESF. Interestingly, even if the lsb of + * an instruction address to jump to must always be set since the CPU always + * runs in thumb mode, the ESF expects the real address of the instruction, + * with the lsb *not* set (instructions are always aligned on 16 bit + * halfwords). Since the compiler automatically sets the lsb of function + * addresses, we have to unset it manually before storing it in the 'pc' field + * of the ESF. + */ +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) +{ + struct __basic_sf *iframe; + +#ifdef CONFIG_MPU_STACK_GUARD +#if defined(CONFIG_USERSPACE) + if (z_stack_is_user_capable(stack)) { + /* Guard area is carved-out of the buffer instead of reserved + * for stacks that can host user threads + */ + thread->stack_info.start += MPU_GUARD_ALIGN_AND_SIZE; + thread->stack_info.size -= MPU_GUARD_ALIGN_AND_SIZE; + } +#endif /* CONFIG_USERSPACE */ +#if FP_GUARD_EXTRA_SIZE > 0 + if ((thread->base.user_options & K_FP_REGS) != 0) { + /* Larger guard needed due to lazy stacking of FP regs may + * overshoot the guard area without writing anything. We + * carve it out of the stack buffer as-needed instead of + * unconditionally reserving it. + */ + thread->stack_info.start += FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= FP_GUARD_EXTRA_SIZE; + } +#endif /* FP_GUARD_EXTRA_SIZE */ +#endif /* CONFIG_MPU_STACK_GUARD */ + + iframe = Z_STACK_PTR_TO_FRAME(struct __basic_sf, stack_ptr); +#if defined(CONFIG_USERSPACE) + if ((thread->base.user_options & K_USER) != 0) { + iframe->pc = (uint32_t)arch_user_mode_enter; + } else { + iframe->pc = (uint32_t)z_thread_entry; + } +#else + iframe->pc = (uint32_t)z_thread_entry; +#endif + + iframe->a1 = (uint32_t)entry; + iframe->a2 = (uint32_t)p1; + iframe->a3 = (uint32_t)p2; + iframe->a4 = (uint32_t)p3; + + iframe->xpsr = A_BIT | MODE_SYS; +#if defined(CONFIG_COMPILER_ISA_THUMB2) + iframe->xpsr |= T_BIT; +#endif /* CONFIG_COMPILER_ISA_THUMB2 */ + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + iframe = (struct __basic_sf *) + ((uintptr_t)iframe - sizeof(struct __fpu_sf)); + memset(iframe, 0, sizeof(struct __fpu_sf)); +#endif + + thread->callee_saved.psp = (uint32_t)iframe; + thread->arch.basepri = 0; + +#if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE) + thread->arch.mode = 0; +#if defined(CONFIG_ARM_STORE_EXC_RETURN) + thread->arch.mode_exc_return = DEFAULT_EXC_RETURN; +#endif +#if FP_GUARD_EXTRA_SIZE > 0 + if ((thread->base.user_options & K_FP_REGS) != 0) { + thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; + } +#endif +#if defined(CONFIG_USERSPACE) + thread->arch.priv_stack_start = 0; +#endif +#endif + /* + * initial values in all other registers/thread entries are + * irrelevant. + */ +} + +#if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) \ + && defined(CONFIG_FPU_SHARING) + +static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, + bool use_large_guard) +{ + if (use_large_guard) { + /* Switch to use a large MPU guard if not already. */ + if ((thread->arch.mode & + Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) == 0) { + /* Default guard size is used. Update required. */ + thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + thread->arch.priv_stack_start += + FP_GUARD_EXTRA_SIZE; + } else +#endif /* CONFIG_USERSPACE */ + { + /* Privileged thread */ + thread->stack_info.start += + FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= + FP_GUARD_EXTRA_SIZE; + } + } + } else { + /* Switch to use the default MPU guard size if not already. */ + if ((thread->arch.mode & + Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + /* Large guard size is used. Update required. */ + thread->arch.mode &= ~Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + thread->arch.priv_stack_start -= + FP_GUARD_EXTRA_SIZE; + } else +#endif /* CONFIG_USERSPACE */ + { + /* Privileged thread */ + thread->stack_info.start -= + FP_GUARD_EXTRA_SIZE; + thread->stack_info.size += + FP_GUARD_EXTRA_SIZE; + } + } + } +} + +#endif + +#ifdef CONFIG_USERSPACE +FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3) +{ + + /* Set up privileged stack before entering user mode */ + _current->arch.priv_stack_start = + (uint32_t)z_priv_stack_find(_current->stack_obj); +#if defined(CONFIG_MPU_STACK_GUARD) +#if defined(CONFIG_THREAD_STACK_INFO) + /* We're dropping to user mode which means the guard area is no + * longer used here, it instead is moved to the privilege stack + * to catch stack overflows there. Un-do the calculations done + * which accounted for memory borrowed from the thread stack. + */ +#if FP_GUARD_EXTRA_SIZE > 0 + if ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; + _current->stack_info.size += FP_GUARD_EXTRA_SIZE; + } +#endif /* FP_GUARD_EXTRA_SIZE */ + _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_THREAD_STACK_INFO */ + + /* Stack guard area reserved at the bottom of the thread's + * privileged stack. Adjust the available (writable) stack + * buffer area accordingly. + */ +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + _current->arch.priv_stack_start += + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; +#else + _current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ +#endif /* CONFIG_MPU_STACK_GUARD */ + +#if defined(CONFIG_CPU_AARCH32_CORTEX_R) + _current->arch.priv_stack_end = + _current->arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE; +#endif + + z_arm_userspace_enter(user_entry, p1, p2, p3, + (uint32_t)_current->stack_info.start, + _current->stack_info.size - + _current->stack_info.delta); + CODE_UNREACHABLE; +} + bool z_arm_thread_is_in_user_mode(void) { uint32_t value; @@ -17,3 +240,164 @@ bool z_arm_thread_is_in_user_mode(void) value = __get_CPSR(); return ((value & CPSR_M_Msk) == CPSR_M_USR); } + +#endif + +#if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) + +#define IS_MPU_GUARD_VIOLATION(guard_start, guard_len, fault_addr, stack_ptr) \ + ((fault_addr != -EINVAL) ? \ + ((fault_addr >= guard_start) && \ + (fault_addr < (guard_start + guard_len)) && \ + (stack_ptr < (guard_start + guard_len))) \ + : \ + (stack_ptr < (guard_start + guard_len))) + +/** + * @brief Assess occurrence of current thread's stack corruption + * + * This function performs an assessment whether a memory fault (on a + * given memory address) is the result of stack memory corruption of + * the current thread. + * + * Thread stack corruption for supervisor threads or user threads in + * privilege mode (when User Space is supported) is reported upon an + * attempt to access the stack guard area (if MPU Stack Guard feature + * is supported). Additionally the current PSP (process stack pointer) + * must be pointing inside or below the guard area. + * + * Thread stack corruption for user threads in user mode is reported, + * if the current PSP is pointing below the start of the current + * thread's stack. + * + * Notes: + * - we assume a fully descending stack, + * - we assume a stacking error has occurred, + * - the function shall be called when handling MemManage and Bus fault, + * and only if a Stacking error has been reported. + * + * If stack corruption is detected, the function returns the lowest + * allowed address where the Stack Pointer can safely point to, to + * prevent from errors when un-stacking the corrupted stack frame + * upon exception return. + * + * @param fault_addr memory address on which memory access violation + * has been reported. It can be invalid (-EINVAL), + * if only Stacking error has been reported. + * @param psp current address the PSP points to + * + * @return The lowest allowed stack frame pointer, if error is a + * thread stack corruption, otherwise return 0. + */ +uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) +{ +#if defined(CONFIG_MULTITHREADING) + const struct k_thread *thread = _current; + + if (thread == NULL) { + return 0; + } +#endif + +#if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && \ + defined(CONFIG_MPU_STACK_GUARD) + uint32_t guard_len = + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; +#else + /* If MPU_STACK_GUARD is not enabled, the guard length is + * effectively zero. Stack overflows may be detected only + * for user threads in nPRIV mode. + */ + uint32_t guard_len = MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + if (z_arm_thread_is_in_user_mode() == false) { + /* User thread in privilege mode */ + if (IS_MPU_GUARD_VIOLATION( + thread->arch.priv_stack_start - guard_len, + guard_len, + fault_addr, psp)) { + /* Thread's privilege stack corruption */ + return thread->arch.priv_stack_start; + } + } else { + if (psp < (uint32_t)thread->stack_obj) { + /* Thread's user stack corruption */ + return (uint32_t)thread->stack_obj; + } + } + } else { + /* Supervisor thread */ + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - + guard_len, + guard_len, + fault_addr, psp)) { + /* Supervisor thread stack corruption */ + return thread->stack_info.start; + } + } +#else /* CONFIG_USERSPACE */ +#if defined(CONFIG_MULTITHREADING) + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, + guard_len, + fault_addr, psp)) { + /* Thread stack corruption */ + return thread->stack_info.start; + } +#else + if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, + guard_len, + fault_addr, psp)) { + /* Thread stack corruption */ + return (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack); + } +#endif +#endif /* CONFIG_USERSPACE */ + + return 0; +} +#endif /* CONFIG_MPU_STACK_GUARD || CONFIG_USERSPACE */ + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) +int arch_float_disable(struct k_thread *thread) +{ + if (thread != _current) { + return -EINVAL; + } + + if (arch_is_in_isr()) { + return -EINVAL; + } + + /* Disable all floating point capabilities for the thread */ + + /* K_FP_REG flag is used in SWAP and stack check fail. Locking + * interrupts here prevents a possible context-switch or MPU + * fault to take an outdated thread user_options flag into + * account. + */ + int key = arch_irq_lock(); + + thread->base.user_options &= ~K_FP_REGS; + + __set_FPEXC(0); + + /* No need to add an ISB barrier after setting the CONTROL + * register; arch_irq_unlock() already adds one. + */ + + arch_irq_unlock(key); + + return 0; +} + +int arch_float_enable(struct k_thread *thread, unsigned int options) +{ + /* This is not supported in Cortex-A and Cortex-R */ + return -ENOTSUP; +} +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index 56aa2bb0963..864a2ccc32a 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -16,10 +16,10 @@ zephyr_library_sources( swap_helper.S irq_manage.c prep_c.c + thread.c ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) -zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) diff --git a/arch/arm/core/cortex_m/thread.c b/arch/arm/core/cortex_m/thread.c index 6ada938f6e1..0ada94e8b27 100644 --- a/arch/arm/core/cortex_m/thread.c +++ b/arch/arm/core/cortex_m/thread.c @@ -1,12 +1,274 @@ /* + * Copyright (c) 2013-2014 Wind River Systems, Inc. * Copyright (c) 2021 Lexmark International, Inc. * * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief New thread creation for ARM Cortex-M + * + * Core thread related primitives for the ARM Cortex-M + * processor architecture. + */ + +#include +#include +#include #include #include +#if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) +#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - \ + MPU_GUARD_ALIGN_AND_SIZE) +#else +#define FP_GUARD_EXTRA_SIZE 0 +#endif + +#ifndef EXC_RETURN_FTYPE +/* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_FTYPE (0x00000010UL) +#endif + +/* Default last octet of EXC_RETURN, for threads that have not run yet. + * The full EXC_RETURN value will be e.g. 0xFFFFFFBC. + */ +#if defined(CONFIG_ARM_NONSECURE_FIRMWARE) +#define DEFAULT_EXC_RETURN 0xBC; +#else +#define DEFAULT_EXC_RETURN 0xFD; +#endif + +#if !defined(CONFIG_MULTITHREADING) +K_THREAD_STACK_DECLARE(z_main_stack, CONFIG_MAIN_STACK_SIZE); +#endif + +/* An initial context, to be "restored" by z_arm_pendsv(), is put at the other + * end of the stack, and thus reusable by the stack when not needed anymore. + * + * The initial context is an exception stack frame (ESF) since exiting the + * PendSV exception will want to pop an ESF. Interestingly, even if the lsb of + * an instruction address to jump to must always be set since the CPU always + * runs in thumb mode, the ESF expects the real address of the instruction, + * with the lsb *not* set (instructions are always aligned on 16 bit + * halfwords). Since the compiler automatically sets the lsb of function + * addresses, we have to unset it manually before storing it in the 'pc' field + * of the ESF. + */ +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) +{ + struct __basic_sf *iframe; + +#ifdef CONFIG_MPU_STACK_GUARD +#if defined(CONFIG_USERSPACE) + if (z_stack_is_user_capable(stack)) { + /* Guard area is carved-out of the buffer instead of reserved + * for stacks that can host user threads + */ + thread->stack_info.start += MPU_GUARD_ALIGN_AND_SIZE; + thread->stack_info.size -= MPU_GUARD_ALIGN_AND_SIZE; + } +#endif /* CONFIG_USERSPACE */ +#if FP_GUARD_EXTRA_SIZE > 0 + if ((thread->base.user_options & K_FP_REGS) != 0) { + /* Larger guard needed due to lazy stacking of FP regs may + * overshoot the guard area without writing anything. We + * carve it out of the stack buffer as-needed instead of + * unconditionally reserving it. + */ + thread->stack_info.start += FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= FP_GUARD_EXTRA_SIZE; + } +#endif /* FP_GUARD_EXTRA_SIZE */ +#endif /* CONFIG_MPU_STACK_GUARD */ + + iframe = Z_STACK_PTR_TO_FRAME(struct __basic_sf, stack_ptr); +#if defined(CONFIG_USERSPACE) + if ((thread->base.user_options & K_USER) != 0) { + iframe->pc = (uint32_t)arch_user_mode_enter; + } else { + iframe->pc = (uint32_t)z_thread_entry; + } +#else + iframe->pc = (uint32_t)z_thread_entry; +#endif + + /* force ARM mode by clearing LSB of address */ + iframe->pc &= 0xfffffffe; + iframe->a1 = (uint32_t)entry; + iframe->a2 = (uint32_t)p1; + iframe->a3 = (uint32_t)p2; + iframe->a4 = (uint32_t)p3; + + iframe->xpsr = + 0x01000000UL; /* clear all, thumb bit is 1, even if RO */ + + thread->callee_saved.psp = (uint32_t)iframe; + thread->arch.basepri = 0; + +#if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE) + thread->arch.mode = 0; +#if defined(CONFIG_ARM_STORE_EXC_RETURN) + thread->arch.mode_exc_return = DEFAULT_EXC_RETURN; +#endif +#if FP_GUARD_EXTRA_SIZE > 0 + if ((thread->base.user_options & K_FP_REGS) != 0) { + thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; + } +#endif +#if defined(CONFIG_USERSPACE) + thread->arch.priv_stack_start = 0; +#endif +#endif + /* + * initial values in all other registers/thread entries are + * irrelevant. + */ +} + +#if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) \ + && defined(CONFIG_FPU_SHARING) + +static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, + bool use_large_guard) +{ + if (use_large_guard) { + /* Switch to use a large MPU guard if not already. */ + if ((thread->arch.mode & + Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) == 0) { + /* Default guard size is used. Update required. */ + thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + thread->arch.priv_stack_start += + FP_GUARD_EXTRA_SIZE; + } else +#endif /* CONFIG_USERSPACE */ + { + /* Privileged thread */ + thread->stack_info.start += + FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= + FP_GUARD_EXTRA_SIZE; + } + } + } else { + /* Switch to use the default MPU guard size if not already. */ + if ((thread->arch.mode & + Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + /* Large guard size is used. Update required. */ + thread->arch.mode &= ~Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + thread->arch.priv_stack_start -= + FP_GUARD_EXTRA_SIZE; + } else +#endif /* CONFIG_USERSPACE */ + { + /* Privileged thread */ + thread->stack_info.start -= + FP_GUARD_EXTRA_SIZE; + thread->stack_info.size += + FP_GUARD_EXTRA_SIZE; + } + } + } +} + +/* + * Adjust the MPU stack guard size together with the FPU + * policy and the stack_info values for the thread that is + * being switched in. + */ +uint32_t z_arm_mpu_stack_guard_and_fpu_adjust(struct k_thread *thread) +{ + if (((thread->base.user_options & K_FP_REGS) != 0) || + ((thread->arch.mode_exc_return & EXC_RETURN_FTYPE) == 0)) { + /* The thread has been pre-tagged (at creation or later) with + * K_FP_REGS, i.e. it is expected to be using the FPU registers + * (if not already). Activate lazy stacking and program a large + * MPU guard to safely detect privilege thread stack overflows. + * + * OR + * The thread is not pre-tagged with K_FP_REGS, but it has + * generated an FP context. Activate lazy stacking and + * program a large MPU guard to detect privilege thread + * stack overflows. + */ + FPU->FPCCR |= FPU_FPCCR_LSPEN_Msk; + + z_arm_thread_stack_info_adjust(thread, true); + + /* Tag the thread with K_FP_REGS */ + thread->base.user_options |= K_FP_REGS; + + return MPU_GUARD_ALIGN_AND_SIZE_FLOAT; + } + + /* Thread is not pre-tagged with K_FP_REGS, and it has + * not been using the FPU. Since there is no active FPU + * context, de-activate lazy stacking and program the + * default MPU guard size. + */ + FPU->FPCCR &= (~FPU_FPCCR_LSPEN_Msk); + + z_arm_thread_stack_info_adjust(thread, false); + + return MPU_GUARD_ALIGN_AND_SIZE; +} +#endif + +#ifdef CONFIG_USERSPACE +FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3) +{ + + /* Set up privileged stack before entering user mode */ + _current->arch.priv_stack_start = + (uint32_t)z_priv_stack_find(_current->stack_obj); +#if defined(CONFIG_MPU_STACK_GUARD) +#if defined(CONFIG_THREAD_STACK_INFO) + /* We're dropping to user mode which means the guard area is no + * longer used here, it instead is moved to the privilege stack + * to catch stack overflows there. Un-do the calculations done + * which accounted for memory borrowed from the thread stack. + */ +#if FP_GUARD_EXTRA_SIZE > 0 + if ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; + _current->stack_info.size += FP_GUARD_EXTRA_SIZE; + } +#endif /* FP_GUARD_EXTRA_SIZE */ + _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_THREAD_STACK_INFO */ + + /* Stack guard area reserved at the bottom of the thread's + * privileged stack. Adjust the available (writable) stack + * buffer area accordingly. + */ +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + _current->arch.priv_stack_start += + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; +#else + _current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ +#endif /* CONFIG_MPU_STACK_GUARD */ + + z_arm_userspace_enter(user_entry, p1, p2, p3, + (uint32_t)_current->stack_info.start, + _current->stack_info.size - + _current->stack_info.delta); + CODE_UNREACHABLE; +} + + bool z_arm_thread_is_in_user_mode(void) { uint32_t value; @@ -15,3 +277,373 @@ bool z_arm_thread_is_in_user_mode(void) value = __get_CONTROL(); return (value & CONTROL_nPRIV_Msk) != 0; } +#endif + +#if defined(CONFIG_BUILTIN_STACK_GUARD) +/* + * @brief Configure ARM built-in stack guard + * + * This function configures per thread stack guards by reprogramming + * the built-in Process Stack Pointer Limit Register (PSPLIM). + * The functionality is meant to be used during context switch. + * + * @param thread thread info data structure. + */ +void configure_builtin_stack_guard(struct k_thread *thread) +{ +#if defined(CONFIG_USERSPACE) + if ((thread->arch.mode & CONTROL_nPRIV_Msk) != 0) { + /* Only configure stack limit for threads in privileged mode + * (i.e supervisor threads or user threads doing system call). + * User threads executing in user mode do not require a stack + * limit protection. + */ + __set_PSPLIM(0); + return; + } + /* Only configure PSPLIM to guard the privileged stack area, if + * the thread is currently using it, otherwise guard the default + * thread stack. Note that the conditional check relies on the + * thread privileged stack being allocated in higher memory area + * than the default thread stack (ensured by design). + */ + uint32_t guard_start = + ((thread->arch.priv_stack_start) && + (__get_PSP() >= thread->arch.priv_stack_start)) ? + (uint32_t)thread->arch.priv_stack_start : + (uint32_t)thread->stack_obj; + + __ASSERT(thread->stack_info.start == ((uint32_t)thread->stack_obj), + "stack_info.start does not point to the start of the" + "thread allocated area."); +#else + uint32_t guard_start = thread->stack_info.start; +#endif +#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) + __set_PSPLIM(guard_start); +#else +#error "Built-in PSP limit checks not supported by HW" +#endif +} +#endif /* CONFIG_BUILTIN_STACK_GUARD */ + +#if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) + +#define IS_MPU_GUARD_VIOLATION(guard_start, guard_len, fault_addr, stack_ptr) \ + ((fault_addr != -EINVAL) ? \ + ((fault_addr >= guard_start) && \ + (fault_addr < (guard_start + guard_len)) && \ + (stack_ptr < (guard_start + guard_len))) \ + : \ + (stack_ptr < (guard_start + guard_len))) + +/** + * @brief Assess occurrence of current thread's stack corruption + * + * This function performs an assessment whether a memory fault (on a + * given memory address) is the result of stack memory corruption of + * the current thread. + * + * Thread stack corruption for supervisor threads or user threads in + * privilege mode (when User Space is supported) is reported upon an + * attempt to access the stack guard area (if MPU Stack Guard feature + * is supported). Additionally the current PSP (process stack pointer) + * must be pointing inside or below the guard area. + * + * Thread stack corruption for user threads in user mode is reported, + * if the current PSP is pointing below the start of the current + * thread's stack. + * + * Notes: + * - we assume a fully descending stack, + * - we assume a stacking error has occurred, + * - the function shall be called when handling MemManage and Bus fault, + * and only if a Stacking error has been reported. + * + * If stack corruption is detected, the function returns the lowest + * allowed address where the Stack Pointer can safely point to, to + * prevent from errors when un-stacking the corrupted stack frame + * upon exception return. + * + * @param fault_addr memory address on which memory access violation + * has been reported. It can be invalid (-EINVAL), + * if only Stacking error has been reported. + * @param psp current address the PSP points to + * + * @return The lowest allowed stack frame pointer, if error is a + * thread stack corruption, otherwise return 0. + */ +uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) +{ +#if defined(CONFIG_MULTITHREADING) + const struct k_thread *thread = _current; + + if (thread == NULL) { + return 0; + } +#endif + +#if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && \ + defined(CONFIG_MPU_STACK_GUARD) + uint32_t guard_len = + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; +#else + /* If MPU_STACK_GUARD is not enabled, the guard length is + * effectively zero. Stack overflows may be detected only + * for user threads in nPRIV mode. + */ + uint32_t guard_len = MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +#if defined(CONFIG_USERSPACE) + if (thread->arch.priv_stack_start) { + /* User thread */ + if (z_arm_thread_is_in_user_mode() == false) { + /* User thread in privilege mode */ + if (IS_MPU_GUARD_VIOLATION( + thread->arch.priv_stack_start - guard_len, + guard_len, + fault_addr, psp)) { + /* Thread's privilege stack corruption */ + return thread->arch.priv_stack_start; + } + } else { + if (psp < (uint32_t)thread->stack_obj) { + /* Thread's user stack corruption */ + return (uint32_t)thread->stack_obj; + } + } + } else { + /* Supervisor thread */ + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - + guard_len, + guard_len, + fault_addr, psp)) { + /* Supervisor thread stack corruption */ + return thread->stack_info.start; + } + } +#else /* CONFIG_USERSPACE */ +#if defined(CONFIG_MULTITHREADING) + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, + guard_len, + fault_addr, psp)) { + /* Thread stack corruption */ + return thread->stack_info.start; + } +#else + if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, + guard_len, + fault_addr, psp)) { + /* Thread stack corruption */ + return (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack); + } +#endif +#endif /* CONFIG_USERSPACE */ + + return 0; +} +#endif /* CONFIG_MPU_STACK_GUARD || CONFIG_USERSPACE */ + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) +int arch_float_disable(struct k_thread *thread) +{ + if (thread != _current) { + return -EINVAL; + } + + if (arch_is_in_isr()) { + return -EINVAL; + } + + /* Disable all floating point capabilities for the thread */ + + /* K_FP_REG flag is used in SWAP and stack check fail. Locking + * interrupts here prevents a possible context-switch or MPU + * fault to take an outdated thread user_options flag into + * account. + */ + int key = arch_irq_lock(); + + thread->base.user_options &= ~K_FP_REGS; + + __set_CONTROL(__get_CONTROL() & (~CONTROL_FPCA_Msk)); + + /* No need to add an ISB barrier after setting the CONTROL + * register; arch_irq_unlock() already adds one. + */ + + arch_irq_unlock(key); + + return 0; +} + +int arch_float_enable(struct k_thread *thread, unsigned int options) +{ + /* This is not supported in Cortex-M */ + return -ENOTSUP; +} +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +/* Internal function for Cortex-M initialization, + * applicable to either case of running Zephyr + * with or without multi-threading support. + */ +static void z_arm_prepare_switch_to_main(void) +{ +#if defined(CONFIG_FPU) + /* Initialize the Floating Point Status and Control Register when in + * Unshared FP Registers mode (In Shared FP Registers mode, FPSCR is + * initialized at thread creation for threads that make use of the FP). + */ +#if defined(CONFIG_ARMV8_1_M_MAINLINE) + /* + * For ARMv8.1-M with FPU, the FPSCR[18:16] LTPSIZE field must be set + * to 0b100 for "Tail predication not applied" as it's reset value + */ + __set_FPSCR(4 << FPU_FPDSCR_LTPSIZE_Pos); +#else + __set_FPSCR(0); +#endif +#if defined(CONFIG_FPU_SHARING) + /* In Sharing mode clearing FPSCR may set the CONTROL.FPCA flag. */ + __set_CONTROL(__get_CONTROL() & (~(CONTROL_FPCA_Msk))); + barrier_isync_fence_full(); +#endif /* CONFIG_FPU_SHARING */ +#endif /* CONFIG_FPU */ +} + +void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, + k_thread_entry_t _main) +{ + z_arm_prepare_switch_to_main(); + + _current = main_thread; + +#if defined(CONFIG_THREAD_LOCAL_STORAGE) + /* On Cortex-M, TLS uses a global variable as pointer to + * the thread local storage area. So this needs to point + * to the main thread's TLS area before switching to any + * thread for the first time, as the pointer is only set + * during context switching. + */ + extern uintptr_t z_arm_tls_ptr; + + z_arm_tls_ptr = main_thread->tls; +#endif + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); +#endif + + /* the ready queue cache already contains the main thread */ + +#if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) + /* + * If stack protection is enabled, make sure to set it + * before jumping to thread entry function + */ + z_arm_configure_dynamic_mpu_regions(main_thread); +#endif + +#if defined(CONFIG_BUILTIN_STACK_GUARD) + /* Set PSPLIM register for built-in stack guarding of main thread. */ +#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) + __set_PSPLIM(main_thread->stack_info.start); +#else +#error "Built-in PSP limit checks not supported by HW" +#endif +#endif /* CONFIG_BUILTIN_STACK_GUARD */ + + /* + * Set PSP to the highest address of the main stack + * before enabling interrupts and jumping to main. + */ + __asm__ volatile ( + "mov r0, %0\n\t" /* Store _main in R0 */ + "msr PSP, %1\n\t" /* __set_PSP(stack_ptr) */ + + "movs r1, #0\n\t" +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + "cpsie i\n\t" /* __enable_irq() */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + "cpsie if\n\t" /* __enable_irq(); __enable_fault_irq() */ + "msr BASEPRI, r1\n\t" /* __set_BASEPRI(0) */ +#else +#error Unknown ARM architecture +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ + "isb\n\t" + "movs r2, #0\n\t" + "movs r3, #0\n\t" + "bl z_thread_entry\n\t" /* z_thread_entry(_main, 0, 0, 0); */ + : + : "r" (_main), "r" (stack_ptr) + : "r0" /* not to be overwritten by msr PSP, %1 */ + ); + + CODE_UNREACHABLE; +} + +#if !defined(CONFIG_MULTITHREADING) + +FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( + k_thread_entry_t main_entry, void *p1, void *p2, void *p3) +{ + z_arm_prepare_switch_to_main(); + + /* Set PSP to the highest address of the main stack. */ + char *psp = Z_THREAD_STACK_BUFFER(z_main_stack) + + K_THREAD_STACK_SIZEOF(z_main_stack); + +#if defined(CONFIG_BUILTIN_STACK_GUARD) + char *psplim = (Z_THREAD_STACK_BUFFER(z_main_stack)); + /* Clear PSPLIM before setting it to guard the main stack area. */ + __set_PSPLIM(0); +#endif + + /* Store all required input in registers, to be accessible + * after stack pointer change. The function is not going + * to return, so callee-saved registers do not need to be + * stacked. + */ + register void *p1_inreg __asm__("r0") = p1; + register void *p2_inreg __asm__("r1") = p2; + register void *p3_inreg __asm__("r2") = p3; + + __asm__ volatile ( +#ifdef CONFIG_BUILTIN_STACK_GUARD + "msr PSPLIM, %[_psplim]\n\t" +#endif + "msr PSP, %[_psp]\n\t" /* __set_PSP(psp) */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + "cpsie i\n\t" /* enable_irq() */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + "cpsie if\n\t" /* __enable_irq(); __enable_fault_irq() */ + "mov r3, #0\n\t" + "msr BASEPRI, r3\n\t" /* __set_BASEPRI(0) */ +#endif + "isb\n\t" + "blx %[_main_entry]\n\t" /* main_entry(p1, p2, p3) */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + "cpsid i\n\t" /* disable_irq() */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + "msr BASEPRI, %[basepri]\n\t"/* __set_BASEPRI(_EXC_IRQ_DEFAULT_PRIO) */ + "isb\n\t" +#endif + "loop: b loop\n\t" /* while (true); */ + : + : "r" (p1_inreg), "r" (p2_inreg), "r" (p3_inreg), + [_psp]"r" (psp), [_main_entry]"r" (main_entry) +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + , [basepri] "r" (_EXC_IRQ_DEFAULT_PRIO) +#endif +#ifdef CONFIG_BUILTIN_STACK_GUARD + , [_psplim]"r" (psplim) +#endif + : + ); + + CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ +} +#endif /* !CONFIG_MULTITHREADING */ diff --git a/arch/arm/core/thread.c b/arch/arm/core/thread.c deleted file mode 100644 index f09d809e91b..00000000000 --- a/arch/arm/core/thread.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright (c) 2013-2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief New thread creation for ARM Cortex-A, Cortex-M and Cortex-R - * - * Core thread related primitives for the ARM Cortex-A, Cortex-M and - * Cortex-R processor architecture. - */ - -#include -#include -#include - -#if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) -#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - \ - MPU_GUARD_ALIGN_AND_SIZE) -#else -#define FP_GUARD_EXTRA_SIZE 0 -#endif - -#ifndef EXC_RETURN_FTYPE -/* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ -#define EXC_RETURN_FTYPE (0x00000010UL) -#endif - -/* Default last octet of EXC_RETURN, for threads that have not run yet. - * The full EXC_RETURN value will be e.g. 0xFFFFFFBC. - */ -#if defined(CONFIG_ARM_NONSECURE_FIRMWARE) -#define DEFAULT_EXC_RETURN 0xBC; -#else -#define DEFAULT_EXC_RETURN 0xFD; -#endif - -#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) -K_THREAD_STACK_DECLARE(z_main_stack, CONFIG_MAIN_STACK_SIZE); -#endif - -/* An initial context, to be "restored" by z_arm_pendsv(), is put at the other - * end of the stack, and thus reusable by the stack when not needed anymore. - * - * The initial context is an exception stack frame (ESF) since exiting the - * PendSV exception will want to pop an ESF. Interestingly, even if the lsb of - * an instruction address to jump to must always be set since the CPU always - * runs in thumb mode, the ESF expects the real address of the instruction, - * with the lsb *not* set (instructions are always aligned on 16 bit - * halfwords). Since the compiler automatically sets the lsb of function - * addresses, we have to unset it manually before storing it in the 'pc' field - * of the ESF. - */ -void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - char *stack_ptr, k_thread_entry_t entry, - void *p1, void *p2, void *p3) -{ - struct __basic_sf *iframe; - -#ifdef CONFIG_MPU_STACK_GUARD -#if defined(CONFIG_USERSPACE) - if (z_stack_is_user_capable(stack)) { - /* Guard area is carved-out of the buffer instead of reserved - * for stacks that can host user threads - */ - thread->stack_info.start += MPU_GUARD_ALIGN_AND_SIZE; - thread->stack_info.size -= MPU_GUARD_ALIGN_AND_SIZE; - } -#endif /* CONFIG_USERSPACE */ -#if FP_GUARD_EXTRA_SIZE > 0 - if ((thread->base.user_options & K_FP_REGS) != 0) { - /* Larger guard needed due to lazy stacking of FP regs may - * overshoot the guard area without writing anything. We - * carve it out of the stack buffer as-needed instead of - * unconditionally reserving it. - */ - thread->stack_info.start += FP_GUARD_EXTRA_SIZE; - thread->stack_info.size -= FP_GUARD_EXTRA_SIZE; - } -#endif /* FP_GUARD_EXTRA_SIZE */ -#endif /* CONFIG_MPU_STACK_GUARD */ - - iframe = Z_STACK_PTR_TO_FRAME(struct __basic_sf, stack_ptr); -#if defined(CONFIG_USERSPACE) - if ((thread->base.user_options & K_USER) != 0) { - iframe->pc = (uint32_t)arch_user_mode_enter; - } else { - iframe->pc = (uint32_t)z_thread_entry; - } -#else - iframe->pc = (uint32_t)z_thread_entry; -#endif - -#if defined(CONFIG_CPU_CORTEX_M) - /* force ARM mode by clearing LSB of address */ - iframe->pc &= 0xfffffffe; -#endif - iframe->a1 = (uint32_t)entry; - iframe->a2 = (uint32_t)p1; - iframe->a3 = (uint32_t)p2; - iframe->a4 = (uint32_t)p3; - -#if defined(CONFIG_CPU_CORTEX_M) - iframe->xpsr = - 0x01000000UL; /* clear all, thumb bit is 1, even if RO */ -#else - iframe->xpsr = A_BIT | MODE_SYS; -#if defined(CONFIG_COMPILER_ISA_THUMB2) - iframe->xpsr |= T_BIT; -#endif /* CONFIG_COMPILER_ISA_THUMB2 */ -#endif /* CONFIG_CPU_CORTEX_M */ - -#if !defined(CONFIG_CPU_CORTEX_M) \ - && defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - iframe = (struct __basic_sf *) - ((uintptr_t)iframe - sizeof(struct __fpu_sf)); - memset(iframe, 0, sizeof(struct __fpu_sf)); -#endif - - thread->callee_saved.psp = (uint32_t)iframe; - thread->arch.basepri = 0; - -#if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE) - thread->arch.mode = 0; -#if defined(CONFIG_ARM_STORE_EXC_RETURN) - thread->arch.mode_exc_return = DEFAULT_EXC_RETURN; -#endif -#if FP_GUARD_EXTRA_SIZE > 0 - if ((thread->base.user_options & K_FP_REGS) != 0) { - thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; - } -#endif -#if defined(CONFIG_USERSPACE) - thread->arch.priv_stack_start = 0; -#endif -#endif - /* - * initial values in all other registers/thread entries are - * irrelevant. - */ -} - -#if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) \ - && defined(CONFIG_FPU_SHARING) - -static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, - bool use_large_guard) -{ - if (use_large_guard) { - /* Switch to use a large MPU guard if not already. */ - if ((thread->arch.mode & - Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) == 0) { - /* Default guard size is used. Update required. */ - thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; -#if defined(CONFIG_USERSPACE) - if (thread->arch.priv_stack_start) { - /* User thread */ - thread->arch.priv_stack_start += - FP_GUARD_EXTRA_SIZE; - } else -#endif /* CONFIG_USERSPACE */ - { - /* Privileged thread */ - thread->stack_info.start += - FP_GUARD_EXTRA_SIZE; - thread->stack_info.size -= - FP_GUARD_EXTRA_SIZE; - } - } - } else { - /* Switch to use the default MPU guard size if not already. */ - if ((thread->arch.mode & - Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { - /* Large guard size is used. Update required. */ - thread->arch.mode &= ~Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; -#if defined(CONFIG_USERSPACE) - if (thread->arch.priv_stack_start) { - /* User thread */ - thread->arch.priv_stack_start -= - FP_GUARD_EXTRA_SIZE; - } else -#endif /* CONFIG_USERSPACE */ - { - /* Privileged thread */ - thread->stack_info.start -= - FP_GUARD_EXTRA_SIZE; - thread->stack_info.size += - FP_GUARD_EXTRA_SIZE; - } - } - } -} - -/* - * Adjust the MPU stack guard size together with the FPU - * policy and the stack_info values for the thread that is - * being switched in. - */ -uint32_t z_arm_mpu_stack_guard_and_fpu_adjust(struct k_thread *thread) -{ - if (((thread->base.user_options & K_FP_REGS) != 0) || - ((thread->arch.mode_exc_return & EXC_RETURN_FTYPE) == 0)) { - /* The thread has been pre-tagged (at creation or later) with - * K_FP_REGS, i.e. it is expected to be using the FPU registers - * (if not already). Activate lazy stacking and program a large - * MPU guard to safely detect privilege thread stack overflows. - * - * OR - * The thread is not pre-tagged with K_FP_REGS, but it has - * generated an FP context. Activate lazy stacking and - * program a large MPU guard to detect privilege thread - * stack overflows. - */ - FPU->FPCCR |= FPU_FPCCR_LSPEN_Msk; - - z_arm_thread_stack_info_adjust(thread, true); - - /* Tag the thread with K_FP_REGS */ - thread->base.user_options |= K_FP_REGS; - - return MPU_GUARD_ALIGN_AND_SIZE_FLOAT; - } - - /* Thread is not pre-tagged with K_FP_REGS, and it has - * not been using the FPU. Since there is no active FPU - * context, de-activate lazy stacking and program the - * default MPU guard size. - */ - FPU->FPCCR &= (~FPU_FPCCR_LSPEN_Msk); - - z_arm_thread_stack_info_adjust(thread, false); - - return MPU_GUARD_ALIGN_AND_SIZE; -} -#endif - -#ifdef CONFIG_USERSPACE -FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3) -{ - - /* Set up privileged stack before entering user mode */ - _current->arch.priv_stack_start = - (uint32_t)z_priv_stack_find(_current->stack_obj); -#if defined(CONFIG_MPU_STACK_GUARD) -#if defined(CONFIG_THREAD_STACK_INFO) - /* We're dropping to user mode which means the guard area is no - * longer used here, it instead is moved to the privilege stack - * to catch stack overflows there. Un-do the calculations done - * which accounted for memory borrowed from the thread stack. - */ -#if FP_GUARD_EXTRA_SIZE > 0 - if ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { - _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; - _current->stack_info.size += FP_GUARD_EXTRA_SIZE; - } -#endif /* FP_GUARD_EXTRA_SIZE */ - _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; - _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; -#endif /* CONFIG_THREAD_STACK_INFO */ - - /* Stack guard area reserved at the bottom of the thread's - * privileged stack. Adjust the available (writable) stack - * buffer area accordingly. - */ -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - _current->arch.priv_stack_start += - ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? - MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; -#else - _current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; -#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ -#endif /* CONFIG_MPU_STACK_GUARD */ - -#if defined(CONFIG_CPU_AARCH32_CORTEX_R) - _current->arch.priv_stack_end = - _current->arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE; -#endif - - z_arm_userspace_enter(user_entry, p1, p2, p3, - (uint32_t)_current->stack_info.start, - _current->stack_info.size - - _current->stack_info.delta); - CODE_UNREACHABLE; -} - -#endif - -#if defined(CONFIG_BUILTIN_STACK_GUARD) -/* - * @brief Configure ARM built-in stack guard - * - * This function configures per thread stack guards by reprogramming - * the built-in Process Stack Pointer Limit Register (PSPLIM). - * The functionality is meant to be used during context switch. - * - * @param thread thread info data structure. - */ -void configure_builtin_stack_guard(struct k_thread *thread) -{ -#if defined(CONFIG_USERSPACE) - if ((thread->arch.mode & CONTROL_nPRIV_Msk) != 0) { - /* Only configure stack limit for threads in privileged mode - * (i.e supervisor threads or user threads doing system call). - * User threads executing in user mode do not require a stack - * limit protection. - */ - __set_PSPLIM(0); - return; - } - /* Only configure PSPLIM to guard the privileged stack area, if - * the thread is currently using it, otherwise guard the default - * thread stack. Note that the conditional check relies on the - * thread privileged stack being allocated in higher memory area - * than the default thread stack (ensured by design). - */ - uint32_t guard_start = - ((thread->arch.priv_stack_start) && - (__get_PSP() >= thread->arch.priv_stack_start)) ? - (uint32_t)thread->arch.priv_stack_start : - (uint32_t)thread->stack_obj; - - __ASSERT(thread->stack_info.start == ((uint32_t)thread->stack_obj), - "stack_info.start does not point to the start of the" - "thread allocated area."); -#else - uint32_t guard_start = thread->stack_info.start; -#endif -#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) - __set_PSPLIM(guard_start); -#else -#error "Built-in PSP limit checks not supported by HW" -#endif -} -#endif /* CONFIG_BUILTIN_STACK_GUARD */ - -#if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) - -#define IS_MPU_GUARD_VIOLATION(guard_start, guard_len, fault_addr, stack_ptr) \ - ((fault_addr != -EINVAL) ? \ - ((fault_addr >= guard_start) && \ - (fault_addr < (guard_start + guard_len)) && \ - (stack_ptr < (guard_start + guard_len))) \ - : \ - (stack_ptr < (guard_start + guard_len))) - -/** - * @brief Assess occurrence of current thread's stack corruption - * - * This function performs an assessment whether a memory fault (on a - * given memory address) is the result of stack memory corruption of - * the current thread. - * - * Thread stack corruption for supervisor threads or user threads in - * privilege mode (when User Space is supported) is reported upon an - * attempt to access the stack guard area (if MPU Stack Guard feature - * is supported). Additionally the current PSP (process stack pointer) - * must be pointing inside or below the guard area. - * - * Thread stack corruption for user threads in user mode is reported, - * if the current PSP is pointing below the start of the current - * thread's stack. - * - * Notes: - * - we assume a fully descending stack, - * - we assume a stacking error has occurred, - * - the function shall be called when handling MemManage and Bus fault, - * and only if a Stacking error has been reported. - * - * If stack corruption is detected, the function returns the lowest - * allowed address where the Stack Pointer can safely point to, to - * prevent from errors when un-stacking the corrupted stack frame - * upon exception return. - * - * @param fault_addr memory address on which memory access violation - * has been reported. It can be invalid (-EINVAL), - * if only Stacking error has been reported. - * @param psp current address the PSP points to - * - * @return The lowest allowed stack frame pointer, if error is a - * thread stack corruption, otherwise return 0. - */ -uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) -{ -#if defined(CONFIG_MULTITHREADING) - const struct k_thread *thread = _current; - - if (thread == NULL) { - return 0; - } -#endif - -#if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && \ - defined(CONFIG_MPU_STACK_GUARD) - uint32_t guard_len = - ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? - MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; -#else - /* If MPU_STACK_GUARD is not enabled, the guard length is - * effectively zero. Stack overflows may be detected only - * for user threads in nPRIV mode. - */ - uint32_t guard_len = MPU_GUARD_ALIGN_AND_SIZE; -#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ - -#if defined(CONFIG_USERSPACE) - if (thread->arch.priv_stack_start) { - /* User thread */ - if (z_arm_thread_is_in_user_mode() == false) { - /* User thread in privilege mode */ - if (IS_MPU_GUARD_VIOLATION( - thread->arch.priv_stack_start - guard_len, - guard_len, - fault_addr, psp)) { - /* Thread's privilege stack corruption */ - return thread->arch.priv_stack_start; - } - } else { - if (psp < (uint32_t)thread->stack_obj) { - /* Thread's user stack corruption */ - return (uint32_t)thread->stack_obj; - } - } - } else { - /* Supervisor thread */ - if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - - guard_len, - guard_len, - fault_addr, psp)) { - /* Supervisor thread stack corruption */ - return thread->stack_info.start; - } - } -#else /* CONFIG_USERSPACE */ -#if defined(CONFIG_MULTITHREADING) - if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, - guard_len, - fault_addr, psp)) { - /* Thread stack corruption */ - return thread->stack_info.start; - } -#else - if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, - guard_len, - fault_addr, psp)) { - /* Thread stack corruption */ - return (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack); - } -#endif -#endif /* CONFIG_USERSPACE */ - - return 0; -} -#endif /* CONFIG_MPU_STACK_GUARD || CONFIG_USERSPACE */ - -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) -int arch_float_disable(struct k_thread *thread) -{ - if (thread != _current) { - return -EINVAL; - } - - if (arch_is_in_isr()) { - return -EINVAL; - } - - /* Disable all floating point capabilities for the thread */ - - /* K_FP_REG flag is used in SWAP and stack check fail. Locking - * interrupts here prevents a possible context-switch or MPU - * fault to take an outdated thread user_options flag into - * account. - */ - int key = arch_irq_lock(); - - thread->base.user_options &= ~K_FP_REGS; - -#if defined(CONFIG_CPU_CORTEX_M) - __set_CONTROL(__get_CONTROL() & (~CONTROL_FPCA_Msk)); -#else - __set_FPEXC(0); -#endif - - /* No need to add an ISB barrier after setting the CONTROL - * register; arch_irq_unlock() already adds one. - */ - - arch_irq_unlock(key); - - return 0; -} - -int arch_float_enable(struct k_thread *thread, unsigned int options) -{ - /* This is not supported in Cortex-M */ - return -ENOTSUP; -} -#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ - -/* Internal function for Cortex-M initialization, - * applicable to either case of running Zephyr - * with or without multi-threading support. - */ -static void z_arm_prepare_switch_to_main(void) -{ -#if defined(CONFIG_FPU) - /* Initialize the Floating Point Status and Control Register when in - * Unshared FP Registers mode (In Shared FP Registers mode, FPSCR is - * initialized at thread creation for threads that make use of the FP). - */ -#if defined(CONFIG_ARMV8_1_M_MAINLINE) - /* - * For ARMv8.1-M with FPU, the FPSCR[18:16] LTPSIZE field must be set - * to 0b100 for "Tail predication not applied" as it's reset value - */ - __set_FPSCR(4 << FPU_FPDSCR_LTPSIZE_Pos); -#else - __set_FPSCR(0); -#endif -#if defined(CONFIG_CPU_CORTEX_M) && defined(CONFIG_FPU_SHARING) - /* In Sharing mode clearing FPSCR may set the CONTROL.FPCA flag. */ - __set_CONTROL(__get_CONTROL() & (~(CONTROL_FPCA_Msk))); - barrier_isync_fence_full(); -#endif /* CONFIG_FPU_SHARING */ -#endif /* CONFIG_FPU */ -} - -void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, - k_thread_entry_t _main) -{ - z_arm_prepare_switch_to_main(); - - _current = main_thread; - -#if defined(CONFIG_THREAD_LOCAL_STORAGE) && defined(CONFIG_CPU_CORTEX_M) - /* On Cortex-M, TLS uses a global variable as pointer to - * the thread local storage area. So this needs to point - * to the main thread's TLS area before switching to any - * thread for the first time, as the pointer is only set - * during context switching. - */ - extern uintptr_t z_arm_tls_ptr; - - z_arm_tls_ptr = main_thread->tls; -#endif - -#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING - z_thread_mark_switched_in(); -#endif - - /* the ready queue cache already contains the main thread */ - -#if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) - /* - * If stack protection is enabled, make sure to set it - * before jumping to thread entry function - */ - z_arm_configure_dynamic_mpu_regions(main_thread); -#endif - -#if defined(CONFIG_BUILTIN_STACK_GUARD) - /* Set PSPLIM register for built-in stack guarding of main thread. */ -#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) - __set_PSPLIM(main_thread->stack_info.start); -#else -#error "Built-in PSP limit checks not supported by HW" -#endif -#endif /* CONFIG_BUILTIN_STACK_GUARD */ - - /* - * Set PSP to the highest address of the main stack - * before enabling interrupts and jumping to main. - */ - __asm__ volatile ( - "mov r0, %0\n\t" /* Store _main in R0 */ -#if defined(CONFIG_CPU_CORTEX_M) - "msr PSP, %1\n\t" /* __set_PSP(stack_ptr) */ -#endif - - "movs r1, #0\n\t" -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ - || defined(CONFIG_ARMV7_R) \ - || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) - "cpsie i\n\t" /* __enable_irq() */ -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - "cpsie if\n\t" /* __enable_irq(); __enable_fault_irq() */ - "msr BASEPRI, r1\n\t" /* __set_BASEPRI(0) */ -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - "isb\n\t" - "movs r2, #0\n\t" - "movs r3, #0\n\t" - "bl z_thread_entry\n\t" /* z_thread_entry(_main, 0, 0, 0); */ - : - : "r" (_main), "r" (stack_ptr) - : "r0" /* not to be overwritten by msr PSP, %1 */ - ); - - CODE_UNREACHABLE; -} - -#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) - -FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( - k_thread_entry_t main_entry, void *p1, void *p2, void *p3) -{ - z_arm_prepare_switch_to_main(); - - /* Set PSP to the highest address of the main stack. */ - char *psp = Z_THREAD_STACK_BUFFER(z_main_stack) + - K_THREAD_STACK_SIZEOF(z_main_stack); - -#if defined(CONFIG_BUILTIN_STACK_GUARD) - char *psplim = (Z_THREAD_STACK_BUFFER(z_main_stack)); - /* Clear PSPLIM before setting it to guard the main stack area. */ - __set_PSPLIM(0); -#endif - - /* Store all required input in registers, to be accessible - * after stack pointer change. The function is not going - * to return, so callee-saved registers do not need to be - * stacked. - */ - register void *p1_inreg __asm__("r0") = p1; - register void *p2_inreg __asm__("r1") = p2; - register void *p3_inreg __asm__("r2") = p3; - - __asm__ volatile ( -#ifdef CONFIG_BUILTIN_STACK_GUARD - "msr PSPLIM, %[_psplim]\n\t" -#endif - "msr PSP, %[_psp]\n\t" /* __set_PSP(psp) */ -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - "cpsie i\n\t" /* enable_irq() */ -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - "cpsie if\n\t" /* __enable_irq(); __enable_fault_irq() */ - "mov r3, #0\n\t" - "msr BASEPRI, r3\n\t" /* __set_BASEPRI(0) */ -#endif - "isb\n\t" - "blx %[_main_entry]\n\t" /* main_entry(p1, p2, p3) */ -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - "cpsid i\n\t" /* disable_irq() */ -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - "msr BASEPRI, %[basepri]\n\t"/* __set_BASEPRI(_EXC_IRQ_DEFAULT_PRIO) */ - "isb\n\t" -#endif - "loop: b loop\n\t" /* while (true); */ - : - : "r" (p1_inreg), "r" (p2_inreg), "r" (p3_inreg), - [_psp]"r" (psp), [_main_entry]"r" (main_entry) -#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - , [basepri] "r" (_EXC_IRQ_DEFAULT_PRIO) -#endif -#ifdef CONFIG_BUILTIN_STACK_GUARD - , [_psplim]"r" (psplim) -#endif - : - ); - - CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ -} -#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ From 9ba3d31310f2d36fc9f48142d7c8861cfc1b0c4f Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 20 Jul 2023 17:00:17 +0800 Subject: [PATCH 0299/4498] arch: arm: Separate common cpu_idle codes This commit separates cpu_idle.S into two asm files, 'cortex_a_r/cpu_idle.S' and 'cortex_m/cpu_idle.S'. Signed-off-by: Huifeng Zhang --- arch/arm/core/CMakeLists.txt | 1 - arch/arm/core/cortex_a_r/CMakeLists.txt | 1 + arch/arm/core/cortex_a_r/cpu_idle.S | 117 ++++++++++++++++++++++++ arch/arm/core/cortex_m/CMakeLists.txt | 1 + arch/arm/core/{ => cortex_m}/cpu_idle.S | 47 ++++------ 5 files changed, 139 insertions(+), 28 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/cpu_idle.S rename arch/arm/core/{ => cortex_m}/cpu_idle.S (93%) diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 3f9d6a7deac..11f22942c11 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -3,7 +3,6 @@ zephyr_library() zephyr_library_sources( - cpu_idle.S fatal.c nmi.c nmi_on_reset.S diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index aaaf230679d..8b0dac374ee 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources( irq_manage.c prep_c.c thread.c + cpu_idle.S ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/cortex_a_r/cpu_idle.S b/arch/arm/core/cortex_a_r/cpu_idle.S new file mode 100644 index 00000000000..b48745c6a81 --- /dev/null +++ b/arch/arm/core/cortex_a_r/cpu_idle.S @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM Cortex-A and Cortex-R power management + * + */ + +#include +#include + +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) +#include +#endif + +_ASM_FILE_PROLOGUE + +GTEXT(z_arm_cpu_idle_init) +GTEXT(arch_cpu_idle) +GTEXT(arch_cpu_atomic_idle) + +.macro _sleep_if_allowed wait_instruction +#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) + push {r0, lr} + bl z_arm_on_enter_cpu_idle + /* Skip the wait instruction if on_enter_cpu_idle() returns false. */ + cmp r0, #0 + beq _skip_\@ +#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */ + + /* + * Wait for all memory transactions to complete before entering low + * power state. + */ + dsb + \wait_instruction + +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) + /* Inline the macro provided by SoC-specific code */ + SOC_ON_EXIT_CPU_IDLE +#endif /* CONFIG_ARM_ON_EXIT_CPU_IDLE */ + +#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) +_skip_\@: + pop {r0, lr} +#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */ +.endm + +/** + * + * @brief Initialization of CPU idle + * + * Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's + * duration. + * + * C function prototype: + * + * void z_arm_cpu_idle_init(void); + */ + +SECTION_FUNC(TEXT, z_arm_cpu_idle_init) + bx lr + +SECTION_FUNC(TEXT, arch_cpu_idle) +#ifdef CONFIG_TRACING + push {r0, lr} + bl sys_trace_idle + pop {r0, lr} +#endif /* CONFIG_TRACING */ + + /* Enter low power state */ + _sleep_if_allowed wfi + + /* + * Clear PRIMASK and flush instruction buffer to immediately service + * the wake-up interrupt. + */ + cpsie i + isb + + bx lr + +SECTION_FUNC(TEXT, arch_cpu_atomic_idle) +#ifdef CONFIG_TRACING + push {r0, lr} + bl sys_trace_idle + pop {r0, lr} +#endif /* CONFIG_TRACING */ + + /* + * Lock PRIMASK while sleeping: wfe will still get interrupted by + * incoming interrupts but the CPU will not service them right away. + */ + cpsid i + + /* + * No need to set SEVONPEND, it's set once in z_arm_cpu_idle_init() + * and never touched again. + */ + + /* r0: interrupt mask from caller */ + + /* No BASEPRI, call wfe directly + * (SEVONPEND is set in z_arm_cpu_idle_init()) + */ + _sleep_if_allowed wfe + + cmp r0, #0 + bne _irq_disabled + cpsie i +_irq_disabled: + + bx lr diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index 864a2ccc32a..7ec2441f12f 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources( irq_manage.c prep_c.c thread.c + cpu_idle.S ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/cpu_idle.S b/arch/arm/core/cortex_m/cpu_idle.S similarity index 93% rename from arch/arm/core/cpu_idle.S rename to arch/arm/core/cortex_m/cpu_idle.S index 8164959ab29..d79ea4f0c16 100644 --- a/arch/arm/core/cpu_idle.S +++ b/arch/arm/core/cortex_m/cpu_idle.S @@ -6,7 +6,7 @@ /** * @file - * @brief ARM Cortex-A, Cortex-M and Cortex-R power management + * @brief ARM Cortex-M power management * */ @@ -23,34 +23,12 @@ GTEXT(z_arm_cpu_idle_init) GTEXT(arch_cpu_idle) GTEXT(arch_cpu_atomic_idle) -#if defined(CONFIG_CPU_CORTEX_M) #define _SCB_SCR 0xE000ED10 #define _SCB_SCR_SEVONPEND (1 << 4) #define _SCB_SCR_SLEEPDEEP (1 << 2) #define _SCB_SCR_SLEEPONEXIT (1 << 1) #define _SCR_INIT_BITS _SCB_SCR_SEVONPEND -#endif - -/** - * - * @brief Initialization of CPU idle - * - * Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's - * duration. - * - * C function prototype: - * - * void z_arm_cpu_idle_init(void); - */ - -SECTION_FUNC(TEXT, z_arm_cpu_idle_init) -#if defined(CONFIG_CPU_CORTEX_M) - ldr r1, =_SCB_SCR - movs.n r2, #_SCR_INIT_BITS - str r2, [r1] -#endif - bx lr .macro _sleep_if_allowed wait_instruction #if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) @@ -84,6 +62,24 @@ _skip_\@: #endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */ .endm +/** + * + * @brief Initialization of CPU idle + * + * Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's + * duration. + * + * C function prototype: + * + * void z_arm_cpu_idle_init(void); + */ + +SECTION_FUNC(TEXT, z_arm_cpu_idle_init) + ldr r1, =_SCB_SCR + movs.n r2, #_SCR_INIT_BITS + str r2, [r1] + bx lr + SECTION_FUNC(TEXT, arch_cpu_idle) #ifdef CONFIG_TRACING push {r0, lr} @@ -162,10 +158,7 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle) /* r0: interrupt mask from caller */ -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ - || defined(CONFIG_ARMV7_R) \ - || defined(CONFIG_AARCH32_ARMV8_R) \ - || defined(CONFIG_ARMV7_A) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* No BASEPRI, call wfe directly * (SEVONPEND is set in z_arm_cpu_idle_init()) */ From 37a6118372c40517f8e84b0d24588d365edff7c6 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Wed, 2 Aug 2023 15:56:38 +0800 Subject: [PATCH 0300/4498] arch: arm: Separate common kernel_arch_func code This commit separates kernel_arch_func.h into two header file, 'cortex_a_r/kernel_arch_func.h' and 'cortex_m/kernel_arch_func.h', it also removes some functions which is empty. Signed-off-by: Huifeng Zhang --- arch/arm/core/cortex_a_r/cpu_idle.S | 22 ----- arch/arm/include/cortex_a_r/exc.h | 20 ----- .../arm/include/cortex_a_r/kernel_arch_func.h | 72 +++++++++++++++ arch/arm/include/cortex_a_r/stack.h | 11 --- arch/arm/include/cortex_m/kernel_arch_func.h | 87 +++++++++++++++++++ arch/arm/include/kernel_arch_func.h | 69 +-------------- 6 files changed, 163 insertions(+), 118 deletions(-) create mode 100644 arch/arm/include/cortex_a_r/kernel_arch_func.h create mode 100644 arch/arm/include/cortex_m/kernel_arch_func.h diff --git a/arch/arm/core/cortex_a_r/cpu_idle.S b/arch/arm/core/cortex_a_r/cpu_idle.S index b48745c6a81..5c6ef3f12ed 100644 --- a/arch/arm/core/cortex_a_r/cpu_idle.S +++ b/arch/arm/core/cortex_a_r/cpu_idle.S @@ -19,7 +19,6 @@ _ASM_FILE_PROLOGUE -GTEXT(z_arm_cpu_idle_init) GTEXT(arch_cpu_idle) GTEXT(arch_cpu_atomic_idle) @@ -50,21 +49,6 @@ _skip_\@: #endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */ .endm -/** - * - * @brief Initialization of CPU idle - * - * Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's - * duration. - * - * C function prototype: - * - * void z_arm_cpu_idle_init(void); - */ - -SECTION_FUNC(TEXT, z_arm_cpu_idle_init) - bx lr - SECTION_FUNC(TEXT, arch_cpu_idle) #ifdef CONFIG_TRACING push {r0, lr} @@ -97,15 +81,9 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle) */ cpsid i - /* - * No need to set SEVONPEND, it's set once in z_arm_cpu_idle_init() - * and never touched again. - */ - /* r0: interrupt mask from caller */ /* No BASEPRI, call wfe directly - * (SEVONPEND is set in z_arm_cpu_idle_init()) */ _sleep_if_allowed wfe diff --git a/arch/arm/include/cortex_a_r/exc.h b/arch/arm/include/cortex_a_r/exc.h index 8f4c7d17c44..b77febbc047 100644 --- a/arch/arm/include/cortex_a_r/exc.h +++ b/arch/arm/include/cortex_a_r/exc.h @@ -54,26 +54,6 @@ static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const z_arch_esf_t } #endif -/** - * @brief Setup system exceptions - * - * Enable fault exceptions. - * - */ -static ALWAYS_INLINE void z_arm_exc_setup(void) -{ -} - -/** - * @brief Clear Fault exceptions - * - * Clear out exceptions for Mem, Bus, Usage and Hard Faults - * - */ -static ALWAYS_INLINE void z_arm_clear_faults(void) -{ -} - extern void z_arm_cortex_r_svc(void); #ifdef __cplusplus diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h new file mode 100644 index 00000000000..5bca1214da1 --- /dev/null +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file + * @brief Private kernel definitions (ARM) + * + * This file contains private kernel function definitions and various + * other definitions for the 32-bit ARM Cortex-A/R processor architecture + * family. + * + * This file is also included by assembly language files which must #define + * _ASMLANGUAGE before including this header file. Note that kernel + * assembly source files obtains structure offset values via "absolute symbols" + * in the offsets.o module. + */ + +#ifndef ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_A_R_KERNEL_ARCH_FUNC_H_ +#define ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_A_R_KERNEL_ARCH_FUNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE +#ifdef CONFIG_ARM_MPU +extern void z_arm_configure_static_mpu_regions(void); +extern int z_arm_mpu_init(void); +#endif /* CONFIG_ARM_MPU */ +#ifdef CONFIG_ARM_AARCH32_MMU +extern int z_arm_mmu_init(void); +#endif /* CONFIG_ARM_AARCH32_MMU */ + +static ALWAYS_INLINE void arch_kernel_init(void) +{ +#if defined(CONFIG_ARM_MPU) + z_arm_mpu_init(); + /* Configure static memory map. This will program MPU regions, + * to set up access permissions for fixed memory sections, such + * as Application Memory or No-Cacheable SRAM area. + * + * This function is invoked once, upon system initialization. + */ + z_arm_configure_static_mpu_regions(); +#endif /* CONFIG_ARM_MPU */ +#if defined(CONFIG_ARM_AARCH32_MMU) + z_arm_mmu_init(); +#endif /* CONFIG_ARM_AARCH32_MMU */ +} + +static ALWAYS_INLINE void +arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +{ + thread->arch.swap_return_value = value; +} + +extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3, + uint32_t stack_end, + uint32_t stack_start); + +extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); + +#endif /* _ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_A_R_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/arm/include/cortex_a_r/stack.h b/arch/arm/include/cortex_a_r/stack.h index e6648f1914e..5638c49ee23 100644 --- a/arch/arm/include/cortex_a_r/stack.h +++ b/arch/arm/include/cortex_a_r/stack.h @@ -26,17 +26,6 @@ extern "C" { extern void z_arm_init_stacks(void); -/** - * - * @brief Setup interrupt stack - * - * On Cortex-A and Cortex-R, the interrupt stack is set up by reset.S - * - */ -static ALWAYS_INLINE void z_arm_interrupt_stack_setup(void) -{ -} - #endif /* _ASMLANGUAGE */ #ifdef __cplusplus diff --git a/arch/arm/include/cortex_m/kernel_arch_func.h b/arch/arm/include/cortex_m/kernel_arch_func.h new file mode 100644 index 00000000000..77619c9d6c4 --- /dev/null +++ b/arch/arm/include/cortex_m/kernel_arch_func.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file + * @brief Private kernel definitions (ARM) + * + * This file contains private kernel function definitions and various + * other definitions for the 32-bit ARM Cortex-M processor architecture + * family. + * + * This file is also included by assembly language files which must #define + * _ASMLANGUAGE before including this header file. Note that kernel + * assembly source files obtains structure offset values via "absolute symbols" + * in the offsets.o module. + */ + +#ifndef ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_KERNEL_ARCH_FUNC_H_ +#define ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_KERNEL_ARCH_FUNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE +extern void z_arm_fault_init(void); +extern void z_arm_cpu_idle_init(void); +#ifdef CONFIG_ARM_MPU +extern void z_arm_configure_static_mpu_regions(void); +extern void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread); +extern int z_arm_mpu_init(void); +#endif /* CONFIG_ARM_MPU */ +#ifdef CONFIG_ARM_AARCH32_MMU +extern int z_arm_mmu_init(void); +#endif /* CONFIG_ARM_AARCH32_MMU */ + +static ALWAYS_INLINE void arch_kernel_init(void) +{ + z_arm_interrupt_stack_setup(); + z_arm_exc_setup(); + z_arm_fault_init(); + z_arm_cpu_idle_init(); + z_arm_clear_faults(); +#if defined(CONFIG_ARM_MPU) + z_arm_mpu_init(); + /* Configure static memory map. This will program MPU regions, + * to set up access permissions for fixed memory sections, such + * as Application Memory or No-Cacheable SRAM area. + * + * This function is invoked once, upon system initialization. + */ + z_arm_configure_static_mpu_regions(); +#endif /* CONFIG_ARM_MPU */ +} + +static ALWAYS_INLINE void +arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +{ + thread->arch.swap_return_value = value; +} + +#if !defined(CONFIG_MULTITHREADING) +extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( + k_thread_entry_t main_func, + void *p1, void *p2, void *p3); + +#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ + z_arm_switch_to_main_no_multithreading + +#endif /* !CONFIG_MULTITHREADING */ + +extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3, + uint32_t stack_end, + uint32_t stack_start); + +extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); + +#endif /* _ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/arm/include/kernel_arch_func.h b/arch/arm/include/kernel_arch_func.h index de1a1f83b4a..b8d67137b52 100644 --- a/arch/arm/include/kernel_arch_func.h +++ b/arch/arm/include/kernel_arch_func.h @@ -22,71 +22,10 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ASMLANGUAGE -extern void z_arm_fault_init(void); -extern void z_arm_cpu_idle_init(void); -#ifdef CONFIG_ARM_MPU -extern void z_arm_configure_static_mpu_regions(void); -extern void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread); -extern int z_arm_mpu_init(void); -#endif /* CONFIG_ARM_MPU */ -#ifdef CONFIG_ARM_AARCH32_MMU -extern int z_arm_mmu_init(void); -#endif /* CONFIG_ARM_AARCH32_MMU */ - -static ALWAYS_INLINE void arch_kernel_init(void) -{ - z_arm_interrupt_stack_setup(); - z_arm_exc_setup(); - z_arm_fault_init(); - z_arm_cpu_idle_init(); - z_arm_clear_faults(); -#if defined(CONFIG_ARM_MPU) - z_arm_mpu_init(); - /* Configure static memory map. This will program MPU regions, - * to set up access permissions for fixed memory sections, such - * as Application Memory or No-Cacheable SRAM area. - * - * This function is invoked once, upon system initialization. - */ - z_arm_configure_static_mpu_regions(); -#endif /* CONFIG_ARM_MPU */ -#if defined(CONFIG_ARM_AARCH32_MMU) - z_arm_mmu_init(); -#endif /* CONFIG_ARM_AARCH32_MMU */ -} - -static ALWAYS_INLINE void -arch_thread_return_value_set(struct k_thread *thread, unsigned int value) -{ - thread->arch.swap_return_value = value; -} - -#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) -extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( - k_thread_entry_t main_func, - void *p1, void *p2, void *p3); - -#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ - z_arm_switch_to_main_no_multithreading - -#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ - -extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3, - uint32_t stack_end, - uint32_t stack_start); - -extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); - -#endif /* _ASMLANGUAGE */ - -#ifdef __cplusplus -} +#if defined(CONFIG_CPU_CORTEX_M) +#include +#else +#include #endif #endif /* ZEPHYR_ARCH_ARM_INCLUDE_KERNEL_ARCH_FUNC_H_ */ From 80e1b37fdb80ce36126dc93eca76f6fc22cf14c6 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 7 Sep 2023 16:38:08 +0800 Subject: [PATCH 0301/4498] doc: release-notes: Add Aarch32 v3.5.0 notes Adds release notes for Aarch32 for Zephyr 3.5.0. Signed-off-by: Huifeng Zhang --- doc/releases/release-notes-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9019af80123..9b6af902848 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -22,6 +22,11 @@ Architectures * ARM + * Architectural support for Arm Cortex-M has been separated from Arm + Cortex-A and Cortex-R. This includes separate source modules to handle + tasks like IRQ management, exception handling, thread handling and swap. + For implementation details see :github:`60031`. + * ARM * ARM64 From 1f51a0e0e1d32415bc27976ae7c05715a75eb666 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 11 Sep 2023 16:31:17 -0700 Subject: [PATCH 0302/4498] scripts/pylib/pytest-twister-harness: Do not fail on Unicode garbage If pylib twister harness reads bytes that can't be decoded to Unicode, it would raise an exception at a separate "serial reader" process, that would fail without any warning. This patch uses "errors='replace'" parameter for Python str.decode() method, so that this doesn't happen. Signed-off-by: Ederson de Souza --- .../src/twister_harness/device/device_adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py index 5fdd7ccc2fa..59be6c52af9 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py @@ -203,7 +203,7 @@ def _handle_device_output(self) -> None: with open(self.handler_log_path, 'a+') as log_file: while self.is_device_running(): if self.is_device_connected(): - output = self._read_device_output().decode().strip() + output = self._read_device_output().decode(errors='replace').strip() if output: self._device_read_queue.put(output) log_file.write(f'{output}\n') From 094342866fd573c021d4b1ccff1c32fd5047412a Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Wed, 23 Aug 2023 10:49:56 +0200 Subject: [PATCH 0303/4498] modules: lvgl: input: add zephyr,lvgl-encoder-input device binding Add a pseudo device which can be used to hook into qdec events and optionally a button and relay the input_event to lvgl. Signed-off-by: Fabian Blatz --- .../input/zephyr,lvgl-encoder-input.yaml | 32 +++++++++ modules/lvgl/CMakeLists.txt | 2 + modules/lvgl/Kconfig.input | 13 ++++ modules/lvgl/include/lvgl_input_device.h | 23 ++++++ modules/lvgl/input/lvgl_common_input.c | 8 +++ modules/lvgl/input/lvgl_encoder_input.c | 71 +++++++++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 dts/bindings/input/zephyr,lvgl-encoder-input.yaml create mode 100644 modules/lvgl/include/lvgl_input_device.h create mode 100644 modules/lvgl/input/lvgl_encoder_input.c diff --git a/dts/bindings/input/zephyr,lvgl-encoder-input.yaml b/dts/bindings/input/zephyr,lvgl-encoder-input.yaml new file mode 100644 index 00000000000..8f16c69a1c7 --- /dev/null +++ b/dts/bindings/input/zephyr,lvgl-encoder-input.yaml @@ -0,0 +1,32 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +description: | + LVGL encoder indev pseudo-device + + Listens for button/encoder input events and routes the + lv_indev_data_t to the underlying encoder lv_indev_t managed by LVGL. + + Example configuration: + + encoder { + compatible = "zephyr,lvgl-encoder-input"; + rotation-input-code = ; + button-input-code = ; + }; + +compatible: "zephyr,lvgl-encoder-input" + +include: zephyr,lvgl-common-input.yaml + +properties: + rotation-input-code: + type: int + required: true + description: | + Input event code associated with rotation (INPUT_REL_*). + + button-input-code: + type: int + description: | + Input event key code for encoder button (INPUT_KEY_* or INPUT_BTN_*). diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt index e6286f8e205..51cfd309ae0 100644 --- a/modules/lvgl/CMakeLists.txt +++ b/modules/lvgl/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library() zephyr_include_directories(${LVGL_DIR}/src/) zephyr_include_directories(.) +zephyr_include_directories(include) zephyr_compile_definitions(LV_CONF_INCLUDE_SIMPLE=1) zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/lv_conf.h) @@ -227,6 +228,7 @@ zephyr_library_sources(input/lvgl_common_input.c) zephyr_library_sources_ifdef(CONFIG_LV_Z_POINTER_KSCAN input/lvgl_pointer_kscan.c) zephyr_library_sources_ifdef(CONFIG_LV_Z_POINTER_INPUT input/lvgl_pointer_input.c) zephyr_library_sources_ifdef(CONFIG_LV_Z_BUTTON_INPUT input/lvgl_button_input.c) +zephyr_library_sources_ifdef(CONFIG_LV_Z_ENCODER_INPUT input/lvgl_encoder_input.c) zephyr_library_link_libraries(LVGL) target_link_libraries(LVGL INTERFACE zephyr_interface) diff --git a/modules/lvgl/Kconfig.input b/modules/lvgl/Kconfig.input index 37b316dc36e..dc1a747fb0d 100644 --- a/modules/lvgl/Kconfig.input +++ b/modules/lvgl/Kconfig.input @@ -68,4 +68,17 @@ config LV_Z_BUTTON_INPUT_MSGQ_COUNT help Size of the button message queue buffering input events. +config LV_Z_ENCODER_INPUT + bool "Input lvgl encoder" + default y + depends on INPUT + depends on DT_HAS_ZEPHYR_LVGL_ENCODER_INPUT_ENABLED + +config LV_Z_ENCODER_INPUT_MSGQ_COUNT + int "Input encoder queue message count" + default 4 + depends on LV_Z_ENCODER_INPUT + help + Size of the encoder message queue buffering input events. + endmenu diff --git a/modules/lvgl/include/lvgl_input_device.h b/modules/lvgl/include/lvgl_input_device.h new file mode 100644 index 00000000000..2e538c92d35 --- /dev/null +++ b/modules/lvgl/include/lvgl_input_device.h @@ -0,0 +1,23 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_INPUT_DEVICE_H_ +#define ZEPHYR_MODULES_LVGL_INPUT_DEVICE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +lv_indev_t *lvgl_input_get_indev(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_INPUT_DEVICE_H_ */ diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c index 23b61a230e6..82814f53fae 100644 --- a/modules/lvgl/input/lvgl_common_input.c +++ b/modules/lvgl/input/lvgl_common_input.c @@ -8,9 +8,17 @@ #include #include #include +#include LOG_MODULE_DECLARE(lvgl); +lv_indev_t *lvgl_input_get_indev(const struct device *dev) +{ + struct lvgl_common_input_data *common_data = dev->data; + + return common_data->indev; +} + static void lvgl_input_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) { const struct device *dev = drv->user_data; diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c new file mode 100644 index 00000000000..e126fb8911a --- /dev/null +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -0,0 +1,71 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_lvgl_encoder_input + +#include "lvgl_common_input.h" + +#include + +LOG_MODULE_DECLARE(lvgl); + +struct lvgl_encoder_input_config { + struct lvgl_common_input_config common_config; /* Needs to be first member */ + int rotation_input_code; + int button_input_code; +}; + +static void lvgl_encoder_process_event(const struct device *dev, struct input_event *evt) +{ + struct lvgl_common_input_data *data = dev->data; + const struct lvgl_encoder_input_config *cfg = dev->config; + + if (evt->code == cfg->rotation_input_code) { + data->pending_event.enc_diff = evt->value; + } else if (evt->code == cfg->button_input_code) { + data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + } else { + LOG_DBG("Ignored input event: %u", evt->code); + return; + } + + if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) { + LOG_WRN("Could not put input data into queue"); + } +} + +static int lvgl_encoder_input_init(const struct device *dev) +{ + return lvgl_input_register_driver(LV_INDEV_TYPE_ENCODER, dev); +} + +#define BUTTON_CODE(inst) DT_INST_PROP_OR(inst, button_input_code, -1) +#define ROTATION_CODE(inst) DT_INST_PROP(inst, rotation_input_code) + +#define ASSERT_PROPERTIES(inst) \ + BUILD_ASSERT(IN_RANGE(ROTATION_CODE(inst), 0, 65536), \ + "Property rotation-input-code needs to be between 0 and 65536."); \ + BUILD_ASSERT(!DT_INST_NODE_HAS_PROP(inst, button_input_code) || \ + IN_RANGE(BUTTON_CODE(inst), 0, 65536), \ + "Property button-input-code needs to be between 0 and 65536."); \ + BUILD_ASSERT(ROTATION_CODE(inst) != BUTTON_CODE(inst), \ + "Property rotation-input-code and button-input-code should not be equal.") + +#define LVGL_ENCODER_INPUT_DEFINE(inst) \ + ASSERT_PROPERTIES(inst); \ + LVGL_INPUT_DEFINE(inst, encoder, CONFIG_LV_Z_ENCODER_INPUT_MSGQ_COUNT, \ + lvgl_encoder_process_event); \ + static const struct lvgl_encoder_input_config lvgl_encoder_input_config_##inst = { \ + .common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, encoder), \ + .rotation_input_code = ROTATION_CODE(inst), \ + .button_input_code = BUTTON_CODE(inst), \ + }; \ + static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, lvgl_encoder_input_init, NULL, &lvgl_common_input_data_##inst, \ + &lvgl_encoder_input_config_##inst, APPLICATION, \ + CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(LVGL_ENCODER_INPUT_DEFINE) From c64724e5db44d3ef0146117b4b879d89d9f7cafd Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Thu, 31 Aug 2023 10:19:45 +0200 Subject: [PATCH 0304/4498] samples: subsys: display: lvgl: Add lvgl-encoder-input device Adds a zephyr,lvgl-encoder-input compatible to the native_posix board overlay and the required code to control an arc widget. Signed-off-by: Fabian Blatz --- .../display/lvgl/boards/native_posix.overlay | 24 +++++++++++++++++-- samples/subsys/display/lvgl/prj.conf | 1 + samples/subsys/display/lvgl/src/main.c | 23 ++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/samples/subsys/display/lvgl/boards/native_posix.overlay b/samples/subsys/display/lvgl/boards/native_posix.overlay index d0cf42da662..43cc9818d5a 100644 --- a/samples/subsys/display/lvgl/boards/native_posix.overlay +++ b/samples/subsys/display/lvgl/boards/native_posix.overlay @@ -11,6 +11,15 @@ sw0 = &button0; }; + qdec { + compatible = "gpio-qdec"; + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>, <&gpio0 5 GPIO_ACTIVE_HIGH>; + steps-per-period = <4>; + zephyr,axis = ; + sample-time-us = <2000>; + idle-timeout-ms = <200>; + }; + keys: keys { compatible = "gpio-keys"; button0: button0 { @@ -23,6 +32,11 @@ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; zephyr,code = ; }; + + encoder_button: encoder_button { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; }; lvgl_button_input { @@ -31,15 +45,21 @@ input-codes = ; coordinates = <160 120>; }; + + lvgl_encoder_input { + compatible = "zephyr,lvgl-encoder-input"; + rotation-input-code = ; + button-input-code = ; + }; }; &gpio0 { - ngpios = <3>; + ngpios = <6>; sdl_gpio { status = "okay"; compatible = "zephyr,gpio-emul-sdl"; /* Skip pin 0 with the unknown code 0 */ - scancodes = <0 21 5>; + scancodes = <0 21 5 30 31 32>; }; }; diff --git a/samples/subsys/display/lvgl/prj.conf b/samples/subsys/display/lvgl/prj.conf index 87a03f57cc0..32ce28965ef 100644 --- a/samples/subsys/display/lvgl/prj.conf +++ b/samples/subsys/display/lvgl/prj.conf @@ -13,6 +13,7 @@ CONFIG_LV_MEM_CUSTOM=y CONFIG_LV_USE_LOG=y CONFIG_LV_USE_LABEL=y CONFIG_LV_USE_BTN=y +CONFIG_LV_USE_ARC=y CONFIG_LV_USE_IMG=y CONFIG_LV_USE_MONKEY=y CONFIG_LV_FONT_MONTSERRAT_14=y diff --git a/samples/subsys/display/lvgl/src/main.c b/samples/subsys/display/lvgl/src/main.c index 8c86711f172..d58be550278 100644 --- a/samples/subsys/display/lvgl/src/main.c +++ b/samples/subsys/display/lvgl/src/main.c @@ -12,6 +12,7 @@ #include #include #include +#include #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL #include @@ -34,7 +35,12 @@ static void button_isr_callback(const struct device *port, count = 0; } -#endif +#endif /* CONFIG_GPIO */ + +#ifdef CONFIG_LV_Z_ENCODER_INPUT +static const struct device *lvgl_encoder = + DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input)); +#endif /* CONFIG_LV_Z_ENCODER_INPUT */ static void lv_btn_click_callback(lv_event_t *e) { @@ -82,7 +88,20 @@ int main(void) return 0; } } -#endif +#endif /* CONFIG_GPIO */ + +#ifdef CONFIG_LV_Z_ENCODER_INPUT + lv_obj_t *arc; + lv_group_t *arc_group; + + arc = lv_arc_create(lv_scr_act()); + lv_obj_align(arc, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(arc, 150, 150); + + arc_group = lv_group_create(); + lv_group_add_obj(arc_group, arc); + lv_indev_set_group(lvgl_input_get_indev(lvgl_encoder), arc_group); +#endif /* CONFIG_LV_Z_ENCODER_INPUT */ if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN) || IS_ENABLED(CONFIG_LV_Z_POINTER_INPUT)) { lv_obj_t *hello_world_button; From ca56084244bc4619720ff652095befd373d1eb77 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Fri, 1 Sep 2023 09:47:45 +0200 Subject: [PATCH 0305/4498] modules: lvgl: move existing includes to folder Moves the includes to the exisiting `include` folder within the module. Signed-off-by: Fabian Blatz --- modules/lvgl/CMakeLists.txt | 3 +-- modules/lvgl/{ => include}/lv_conf.h | 0 modules/lvgl/{ => include}/lvgl_display.h | 0 modules/lvgl/{ => include}/lvgl_fs.h | 0 modules/lvgl/{ => include}/lvgl_mem.h | 0 5 files changed, 1 insertion(+), 2 deletions(-) rename modules/lvgl/{ => include}/lv_conf.h (100%) rename modules/lvgl/{ => include}/lvgl_display.h (100%) rename modules/lvgl/{ => include}/lvgl_fs.h (100%) rename modules/lvgl/{ => include}/lvgl_mem.h (100%) diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt index 51cfd309ae0..51eb2bd11da 100644 --- a/modules/lvgl/CMakeLists.txt +++ b/modules/lvgl/CMakeLists.txt @@ -13,11 +13,10 @@ zephyr_interface_library_named(LVGL) zephyr_library() zephyr_include_directories(${LVGL_DIR}/src/) -zephyr_include_directories(.) zephyr_include_directories(include) zephyr_compile_definitions(LV_CONF_INCLUDE_SIMPLE=1) -zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/lv_conf.h) +zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h) zephyr_library_sources( ${LVGL_DIR}/src/core/lv_disp.c diff --git a/modules/lvgl/lv_conf.h b/modules/lvgl/include/lv_conf.h similarity index 100% rename from modules/lvgl/lv_conf.h rename to modules/lvgl/include/lv_conf.h diff --git a/modules/lvgl/lvgl_display.h b/modules/lvgl/include/lvgl_display.h similarity index 100% rename from modules/lvgl/lvgl_display.h rename to modules/lvgl/include/lvgl_display.h diff --git a/modules/lvgl/lvgl_fs.h b/modules/lvgl/include/lvgl_fs.h similarity index 100% rename from modules/lvgl/lvgl_fs.h rename to modules/lvgl/include/lvgl_fs.h diff --git a/modules/lvgl/lvgl_mem.h b/modules/lvgl/include/lvgl_mem.h similarity index 100% rename from modules/lvgl/lvgl_mem.h rename to modules/lvgl/include/lvgl_mem.h From 4d53ae8a42311de5e8cede8139b7ea1ee09ce951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 31 Aug 2023 09:10:04 +0200 Subject: [PATCH 0306/4498] doc: shell: fix incorrect use of :kbd: role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Key combinations described using the sphinx :kbd: role should not have a white space around + sign i.e. should be :kbd:`Ctrl+d` not :kbd:`Ctrl + d` Signed-off-by: Benjamin Cabé --- doc/services/shell/index.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 6cdb0020bf8..6ce250f563a 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -452,7 +452,7 @@ History Feature This feature enables commands history in the shell. It is activated by: :kconfig:option:`CONFIG_SHELL_HISTORY` set to ``y``. History can be accessed -using keys: :kbd:`↑` :kbd:`↓` or :kbd:`Ctrl + n` and :kbd:`Ctrl + p` +using keys: :kbd:`↑` :kbd:`↓` or :kbd:`Ctrl+n` and :kbd:`Ctrl+p` if meta keys are active. Number of commands that can be stored depends on size of :kconfig:option:`CONFIG_SHELL_HISTORY_BUFFER` parameter. @@ -486,36 +486,36 @@ The shell module supports the following meta keys: * - Meta keys - Action - * - :kbd:`Ctrl + a` + * - :kbd:`Ctrl+a` - Moves the cursor to the beginning of the line. - * - :kbd:`Ctrl + b` + * - :kbd:`Ctrl+b` - Moves the cursor backward one character. - * - :kbd:`Ctrl + c` + * - :kbd:`Ctrl+c` - Preserves the last command on the screen and starts a new command in a new line. - * - :kbd:`Ctrl + d` + * - :kbd:`Ctrl+d` - Deletes the character under the cursor. - * - :kbd:`Ctrl + e` + * - :kbd:`Ctrl+e` - Moves the cursor to the end of the line. - * - :kbd:`Ctrl + f` + * - :kbd:`Ctrl+f` - Moves the cursor forward one character. - * - :kbd:`Ctrl + k` + * - :kbd:`Ctrl+k` - Deletes from the cursor to the end of the line. - * - :kbd:`Ctrl + l` + * - :kbd:`Ctrl+l` - Clears the screen and leaves the currently typed command at the top of the screen. - * - :kbd:`Ctrl + n` + * - :kbd:`Ctrl+n` - Moves in history to next entry. - * - :kbd:`Ctrl + p` + * - :kbd:`Ctrl+p` - Moves in history to previous entry. - * - :kbd:`Ctrl + u` + * - :kbd:`Ctrl+u` - Clears the currently typed command. - * - :kbd:`Ctrl + w` + * - :kbd:`Ctrl+w` - Removes the word or part of the word to the left of the cursor. Words separated by period instead of space are treated as one word. - * - :kbd:`Alt + b` + * - :kbd:`Alt+b` - Moves the cursor backward one word. - * - :kbd:`Alt + f` + * - :kbd:`Alt+f` - Moves the cursor forward one word. This feature is activated by :kconfig:option:`CONFIG_SHELL_METAKEYS` set to ``y``. From 3168623abbf1ce3b3515866aeae879faead96500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 31 Aug 2023 09:29:06 +0200 Subject: [PATCH 0307/4498] tests: drivers: clock_control: nrf_lf_clock_start: Clean up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After 31767a0bc there is no need to disable boot banner because initial clock state is read in POST_KERNEL stage before the boot banner is printed. Signed-off-by: Krzysztof Chruściński --- tests/drivers/clock_control/nrf_lf_clock_start/prj.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf b/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf index f3825418170..9228251051e 100644 --- a/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf +++ b/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf @@ -1,5 +1,2 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y - -# Disable boot banner to reduce time between clock start and test execution -CONFIG_BOOT_BANNER=n From 5670bad5057b1c2af7dd13b275f993866ad5420f Mon Sep 17 00:00:00 2001 From: Max van Kessel Date: Thu, 31 Aug 2023 10:00:27 +0200 Subject: [PATCH 0308/4498] drivers: clock: stm32: overdrive after sysclock According to the reference manual the overdrive should be enabled after setup of the sysclock (HSE or HSI) and enabling the PLL (PLLON). The flash latency should be enabled after the PLL has been turned on, but before switching the system clock to the PLL. Signed-off-by: Max van Kessel --- drivers/clock_control/clock_stm32_ll_common.c | 25 ++++------------ drivers/clock_control/clock_stm32f2_f4_f7.c | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index b596ac08da9..40a2bf28ce3 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -723,20 +723,11 @@ int stm32_clock_control_init(const struct device *dev) /* Some clocks would be activated by default */ config_enable_default_clocks(); -#if defined(STM32_PLL_ENABLED) && defined(CONFIG_SOC_SERIES_STM32F7X) - /* Assuming we stay on Power Scale default value: Power Scale 1 */ - if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC > 180000000) { - /* Set Overdrive if needed before configuring the Flash Latency */ - LL_PWR_EnableOverDriveMode(); - while (LL_PWR_IsActiveFlag_OD() != 1) { - /* Wait for OverDrive mode ready */ - } - LL_PWR_EnableOverDriveSwitching(); - while (LL_PWR_IsActiveFlag_ODSW() != 1) { - /* Wait for OverDrive switch ready */ - } - } -#endif /* STM32_PLL_ENABLED && CONFIG_SOC_SERIES_STM32F7X */ + /* Set up indiviual enabled clocks */ + set_up_fixed_clock_sources(); + + /* Set up PLLs */ + set_up_plls(); #if defined(FLASH_ACR_LATENCY) uint32_t old_flash_freq; @@ -754,12 +745,6 @@ int stm32_clock_control_init(const struct device *dev) } #endif /* FLASH_ACR_LATENCY */ - /* Set up indiviual enabled clocks */ - set_up_fixed_clock_sources(); - - /* Set up PLLs */ - set_up_plls(); - if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) { diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index e7a28445572..6131fcd4c06 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,35 @@ void config_pll_sysclock(void) pllm(STM32_PLL_M_DIVISOR), STM32_PLL_N_MULTIPLIER, pllp(STM32_PLL_P_DIVISOR)); + +#if defined(CONFIG_SOC_SERIES_STM32F7X) + /* Assuming we stay on Power Scale default value: Power Scale 1 */ + if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC > 180000000) { + /* Enable the PLL (PLLON) before setting overdrive. Skipping the PLL + * locking phase since the system will be stalled during the switch + * (ODSW) but the PLL clock system will be running during the locking + * phase. See reference manual (RM0431) §4.1.4 Voltage regulator + * Sub section: Entering Over-drive mode. + */ + LL_RCC_PLL_Enable(); + + /* Set Overdrive if needed before configuring the Flash Latency */ + LL_PWR_EnableOverDriveMode(); + while (LL_PWR_IsActiveFlag_OD() != 1) { + /* Wait for OverDrive mode ready */ + } + LL_PWR_EnableOverDriveSwitching(); + while (LL_PWR_IsActiveFlag_ODSW() != 1) { + /* Wait for OverDrive switch ready */ + } + + /* The PLL could still not be locked when returning to the caller + * function. But the caller doesn't know we've turned on the PLL + * for the overdrive function. The caller will try to turn on the PLL + * And start waiting for the PLL locking phase to complete. + */ + } +#endif /* CONFIG_SOC_SERIES_STM32F7X */ } #endif /* defined(STM32_PLL_ENABLED) */ From 12ba4dff1e1b0097a866b16333fb60bef829592e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 31 Aug 2023 12:47:28 +0200 Subject: [PATCH 0309/4498] doc: include: add missing doxygen comments in math_extras. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the existing named sections were nice and to the point, it is better to also document each function separately. Also mounted this utility header under the "Utilities" doxygen group. Signed-off-by: Benjamin Cabé --- include/zephyr/sys/math_extras.h | 105 +++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/include/zephyr/sys/math_extras.h b/include/zephyr/sys/math_extras.h index aeaf5331088..e66a966f7bd 100644 --- a/include/zephyr/sys/math_extras.h +++ b/include/zephyr/sys/math_extras.h @@ -5,13 +5,15 @@ */ /** - * @file * @brief Extra arithmetic and bit manipulation functions. + * @defgroup math_extras Math extras + * @ingroup utilities * - * @details This header file provides portable wrapper functions for a number of - * arithmetic and bit-counting functions that are often provided by compiler - * builtins. If the compiler does not have an appropriate builtin, a portable C + * Portable wrapper functions for a number of arithmetic and bit-counting functions that are often + * provided by compiler builtins. If the compiler does not have an appropriate builtin, a portable C * implementation is used instead. + * + * @{ */ #ifndef ZEPHYR_INCLUDE_SYS_MATH_EXTRAS_H_ @@ -28,10 +30,44 @@ * true if the operation overflowed. */ /**@{*/ + +/** + * @brief Add two unsigned 16-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool u16_add_overflow(uint16_t a, uint16_t b, uint16_t *result); + +/** + * @brief Add two unsigned 32-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ + static bool u32_add_overflow(uint32_t a, uint32_t b, uint32_t *result); + +/** + * @brief Add two unsigned 64-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool u64_add_overflow(uint64_t a, uint64_t b, uint64_t *result); + +/** + * @brief Add two size_t integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool size_add_overflow(size_t a, size_t b, size_t *result); + /**@}*/ /** @@ -41,10 +77,43 @@ static bool size_add_overflow(size_t a, size_t b, size_t *result); * true if the operation overflowed. */ /**@{*/ + +/** + * @brief Multiply two unsigned 16-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool u16_mul_overflow(uint16_t a, uint16_t b, uint16_t *result); + +/** + * @brief Multiply two unsigned 32-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ + static bool u32_mul_overflow(uint32_t a, uint32_t b, uint32_t *result); +/** + * @brief Multiply two unsigned 64-bit integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool u64_mul_overflow(uint64_t a, uint64_t b, uint64_t *result); + +/** + * @brief Multiply two size_t integers. + * @param a First operand. + * @param b Second operand. + * @param result Pointer to the result. + * @return true if the operation overflowed. + */ static bool size_mul_overflow(size_t a, size_t b, size_t *result); + /**@}*/ /** @@ -54,8 +123,21 @@ static bool size_mul_overflow(size_t a, size_t b, size_t *result); * When `x = 0`, this is the size of `x` in bits. */ /**@{*/ + +/** + * @brief Count the number of leading zero bits in a 32-bit integer. + * @param x Integer to count leading zeros in. + * @return Number of leading zero bits in `x`. + */ static int u32_count_leading_zeros(uint32_t x); + +/** + * @brief Count the number of leading zero bits in a 64-bit integer. + * @param x Integer to count leading zeros in. + * @return Number of leading zero bits in `x`. + */ static int u64_count_leading_zeros(uint64_t x); + /**@}*/ /** @@ -65,8 +147,23 @@ static int u64_count_leading_zeros(uint64_t x); * When `x = 0`, this is the size of `x` in bits. */ /**@{*/ + +/** + * @brief Count the number of trailing zero bits in a 32-bit integer. + * @param x Integer to count trailing zeros in. + * @return Number of trailing zero bits in `x`. + */ static int u32_count_trailing_zeros(uint32_t x); + +/** + * @brief Count the number of trailing zero bits in a 64-bit integer. + * @param x Integer to count trailing zeros in. + * @return Number of trailing zero bits in `x`. + */ static int u64_count_trailing_zeros(uint64_t x); + +/**@}*/ + /**@}*/ #include From a17fe86de2be667d60abc0b904db81e320645bea Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Fri, 1 Sep 2023 15:57:18 +0200 Subject: [PATCH 0310/4498] arch: common: Force linker to fill empty spaces in rom_start with 0x00 LLVM LLD fills empty spaces (created using ALIGN() or moving the location counter) in executable segments with TrapInstr pattern, e.g. for ARM the TrapInstr pattern is 0xd4d4d4d4. GNU LD fills empty spaces with 0x00 pattern. We may want to have some section (e.g. rom_start) filled with 0x00, e.g. because MCU can interpret the pattern as a configuration data. Signed-off-by: Patryk Duda --- arch/common/CMakeLists.txt | 4 ++++ arch/common/fill_with_zeros.ld | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 arch/common/fill_with_zeros.ld diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 80102d70331..f9c6f8a72bb 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -56,6 +56,10 @@ if (DEFINED CONFIG_ARM OR DEFINED CONFIG_X86 OR DEFINED CONFIG_ARM64 # Exclamation mark is printable character with lowest number in ASCII table. # We are sure that this file will be included as a first. zephyr_linker_sources(ROM_START SORT_KEY ! rom_start_address.ld) + # Some linkers fill unspecified region with pattern other than 0x00. Include + # fill_with_zeros.ld file which forces the linker to use 0x00 pattern. Please + # note that the pattern will affect empty spaces created after FILL(0x00). + zephyr_linker_sources(ROM_START SORT_KEY $ fill_with_zeros.ld) zephyr_linker_sources(ROM_START SORT_KEY 0x0 rom_start_offset.ld) # Handled in ld.cmake endif() diff --git a/arch/common/fill_with_zeros.ld b/arch/common/fill_with_zeros.ld new file mode 100644 index 00000000000..b93a5ffead0 --- /dev/null +++ b/arch/common/fill_with_zeros.ld @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Google, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * LLVM LLD fills empty spaces (created using ALIGN() or moving the location + * counter) in executable segments with TrapInstr pattern, e.g. for ARM the + * TrapInstr pattern is 0xd4d4d4d4. GNU LD fills empty spaces with 0x00 + * pattern. + * + * We may want to have some section (e.g. rom_start) filled with 0x00, + * e.g. because MCU can interpret the pattern as a configuration data. + */ +FILL(0x00); From 450dbb15efcaccadf546b42931509e5c4581b5eb Mon Sep 17 00:00:00 2001 From: Vivekananda Uppunda Date: Fri, 1 Sep 2023 15:56:38 +0530 Subject: [PATCH 0311/4498] net: l2: wifi: Add support for W-Fi mode setting and selection This change brings in support for setting various Wi-Fi modes and enables a specific Wi-Fi interface to be also placed into a sniffer operation via monitor mode and promiscuous mode. A raw TX- packet Injection mode is also introduced Signed-off-by: Vivekananda Uppunda --- include/zephyr/net/wifi.h | 33 +++ include/zephyr/net/wifi_mgmt.h | 76 +++++++ subsys/net/l2/wifi/wifi_mgmt.c | 60 +++++ subsys/net/l2/wifi/wifi_shell.c | 388 +++++++++++++++++++++++++++++++- 4 files changed, 556 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index aa3096fc5ac..55bd8d71a3a 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -148,6 +148,7 @@ static inline const char *wifi_band_txt(enum wifi_frequency_bands band) #define WIFI_SAE_PSWD_MAX_LEN 128 #define WIFI_MAC_ADDR_LEN 6 +#define WIFI_CHANNEL_MIN 1 #define WIFI_CHANNEL_MAX 233 #define WIFI_CHANNEL_ANY 255 @@ -355,6 +356,38 @@ static const char * const wifi_ps_mode2str[] = { }; /** @endcond */ +/* Interface index Min and Max values */ +#define WIFI_INTERFACE_INDEX_MIN 1 +#define WIFI_INTERFACE_INDEX_MAX 255 + +/** Wifi operational mode */ +enum wifi_operational_modes { + /** STA mode setting enable */ + WIFI_STA_MODE = BIT(0), + /** Monitor mode setting enable */ + WIFI_MONITOR_MODE = BIT(1), + /** TX injection mode setting enable */ + WIFI_TX_INJECTION_MODE = BIT(2), + /** Promiscuous mode setting enable */ + WIFI_PROMISCUOUS_MODE = BIT(3), + /** AP mode setting enable */ + WIFI_AP_MODE = BIT(4), + /** Softap mode setting enable */ + WIFI_SOFTAP_MODE = BIT(5), +}; + +/** Mode filter settings */ +enum wifi_filter { + /** Support management, data and control packet sniffing */ + WIFI_PACKET_FILTER_ALL = BIT(0), + /** Support only sniffing of management packets */ + WIFI_PACKET_FILTER_MGMT = BIT(1), + /** Support only sniffing of data packets */ + WIFI_PACKET_FILTER_DATA = BIT(2), + /** Support only sniffing of control packets */ + WIFI_PACKET_FILTER_CTRL = BIT(3), +}; + /** Wi-Fi Target Wake Time (TWT) operations. */ enum wifi_twt_operation { /** TWT setup operation */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index c7a17e930d6..ab3225e1408 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -69,6 +69,12 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_REG_DOMAIN, /** Set power save timeout */ NET_REQUEST_WIFI_CMD_PS_TIMEOUT, + /** Set or get Mode of operation */ + NET_REQUEST_WIFI_CMD_MODE, + /** Set or get packet filter setting for current mode */ + NET_REQUEST_WIFI_CMD_PACKET_FILTER, + /** Set or get Wi-Fi channel for Monitor or TX-Injection mode */ + NET_REQUEST_WIFI_CMD_CHANNEL, NET_REQUEST_WIFI_CMD_MAX }; @@ -131,6 +137,21 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT); +#define NET_REQUEST_WIFI_MODE \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_MODE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE); + +#define NET_REQUEST_WIFI_PACKET_FILTER \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PACKET_FILTER) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER); + +#define NET_REQUEST_WIFI_CHANNEL \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_CHANNEL) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL); + /** Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -475,6 +496,37 @@ union wifi_mgmt_events { struct wifi_twt_params twt_params; }; +/** Wi-Fi mode setup */ +struct wifi_mode_info { + /** Mode setting for a specific mode of operation */ + uint8_t mode; + /** Interface index */ + uint8_t if_index; + /** Get or set operation */ + enum wifi_mgmt_op oper; +}; + +/** Wi-Fi filter setting for monitor, prmoiscuous, TX-injection modes */ +struct wifi_filter_info { + /** Filter setting */ + uint8_t filter; + /** Interface index */ + uint8_t if_index; + /** Filter buffer size */ + uint16_t buffer_size; + /** Get or set operation */ + enum wifi_mgmt_op oper; +}; + +/** Wi-Fi channel setting for monitor and TX-injection modes */ +struct wifi_channel_info { + /** Channel value to set */ + uint16_t channel; + /** Interface index */ + uint8_t if_index; + /** Get or set operation */ + enum wifi_mgmt_op oper; +}; #include @@ -596,6 +648,30 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); + /** Set or get packet filter settings for monitor and promiscuous modes + * + * @param dev Pointer to the device structure for the driver instance. + * @param packet filter settings + * + * @return 0 if ok, < 0 if error + */ + int (*filter)(const struct device *dev, struct wifi_filter_info *filter); + /** Set or get mode of operation + * + * @param dev Pointer to the device structure for the driver instance. + * @param mode settings + * + * @return 0 if ok, < 0 if error + */ + int (*mode)(const struct device *dev, struct wifi_mode_info *mode); + /** Set or get current channel of operation + * + * @param dev Pointer to the device structure for the driver instance. + * @param channel settings + * + * @return 0 if ok, < 0 if error + */ + int (*channel)(const struct device *dev, struct wifi_channel_info *channel); }; /** Wi-Fi management offload API */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 22d54b926ab..7f0f30dc8c1 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -446,6 +446,66 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, sizeof(twt_sleep_state)); } +static int wifi_mode(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_mode_info *mode_info = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) { + return -ENOTSUP; + } + + return wifi_mgmt_api->mode(dev, mode_info); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode); + +static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_filter_info *filter_info = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) { + return -ENOTSUP; + } + + return wifi_mgmt_api->filter(dev, filter_info); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter); + +static int wifi_channel(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_channel_info *channel_info = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) { + return -ENOTSUP; + } + + return wifi_mgmt_api->channel(dev, channel_info); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel); + #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_result) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 0b8c6a74983..21b1f551448 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -75,12 +75,20 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi { char *endptr; char *str_tmp = str; - long num = strtol(str_tmp, &endptr, 10); + long num = 0; + + if ((str_tmp[0] == '0') && (str_tmp[1] == 'x')) { + /* Hexadecimal numbers take base 0 in strtol */ + num = strtol(str_tmp, &endptr, 0); + } else { + num = strtol(str_tmp, &endptr, 10); + } if (*endptr != '\0') { print(sh, SHELL_ERROR, "Invalid number: %s", str_tmp); return false; } + if ((num) < (min) || (num) > (max)) { print(sh, SHELL_WARNING, "Value out of range: %s, (%ld-%ld)", str_tmp, min, max); return false; @@ -1255,6 +1263,335 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar return 0; } +void parse_mode_args_to_params(const struct shell *sh, int argc, + char *argv[], struct wifi_mode_info *mode, + bool *do_mode_oper) +{ + int opt; + int option_index = 0; + + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + {"sta", no_argument, 0, 's'}, + {"monitor", no_argument, 0, 'm'}, + {"TX-injection", no_argument, 0, 't'}, + {"promiscuous", no_argument, 0, 'p'}, + {"ap", no_argument, 0, 'a'}, + {"softap", no_argument, 0, 'k'}, + {"get", no_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; + + while ((opt = getopt_long(argc, argv, "i:smtpakgh", long_options, &option_index)) != -1) { + switch (opt) { + case 's': + mode->mode |= WIFI_STA_MODE; + break; + case 'm': + mode->mode |= WIFI_MONITOR_MODE; + break; + case 't': + mode->mode |= WIFI_TX_INJECTION_MODE; + break; + case 'p': + mode->mode |= WIFI_PROMISCUOUS_MODE; + break; + case 'a': + mode->mode |= WIFI_AP_MODE; + break; + case 'k': + mode->mode |= WIFI_SOFTAP_MODE; + break; + case 'g': + mode->oper = true; + break; + case 'i': + mode->if_index = (uint8_t)atoi(optarg); + break; + case 'h': + shell_help(sh); + *do_mode_oper = false; + break; + case '?': + default: + break; + } + } +} + +static int cmd_wifi_mode(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + struct wifi_mode_info mode_info = {0}; + int ret; + bool do_mode_oper = true; + + if (argc > 1) { + mode_info.oper = WIFI_MGMT_SET; + parse_mode_args_to_params(sh, argc, argv, &mode_info, &do_mode_oper); + } else { + shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); + return -EINVAL; + } + + if (do_mode_oper) { + /* Check interface index value. Mode validation must be performed by + * lower layer + */ + if (mode_info.if_index == 0) { + iface = net_if_get_first_wifi(); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find the default wifi interface\n"); + return -ENOEXEC; + } + mode_info.if_index = net_if_get_by_iface(iface); + } else { + iface = net_if_get_by_index(mode_info.if_index); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find interface for if_index %d\n", + mode_info.if_index); + return -ENOEXEC; + } + } + + ret = net_mgmt(NET_REQUEST_WIFI_MODE, iface, &mode_info, sizeof(mode_info)); + + if (ret) { + shell_fprintf(sh, SHELL_ERROR, "mode %s operation failed with reason %d\n", + mode_info.oper == WIFI_MGMT_GET ? "get" : "set", ret); + return -ENOEXEC; + } + + if (mode_info.oper == WIFI_MGMT_GET) { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current mode is %x\n", + mode_info.mode); + } else { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi mode set to %x\n", mode_info.mode); + } + } + return 0; +} + +void parse_channel_args_to_params(const struct shell *sh, int argc, + char *argv[], struct wifi_channel_info *channel, + bool *do_channel_oper) +{ + int opt; + int option_index = 0; + + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + {"channel", required_argument, 0, 'c'}, + {"get", no_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; + + while ((opt = getopt_long(argc, argv, "i:c:gh", long_options, &option_index)) != -1) { + switch (opt) { + case 'c': + channel->channel = (uint16_t)atoi(optarg); + break; + case 'i': + channel->if_index = (uint8_t)atoi(optarg); + break; + case 'g': + channel->oper = WIFI_MGMT_GET; + break; + case 'h': + shell_help(sh); + *do_channel_oper = false; + break; + case '?': + default: + break; + } + } +} + +static int cmd_wifi_channel(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + struct wifi_channel_info channel_info = {0}; + int ret; + bool do_channel_oper = true; + + if (argc > 1) { + channel_info.oper = WIFI_MGMT_SET; + parse_channel_args_to_params(sh, argc, argv, &channel_info, &do_channel_oper); + } else { + shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); + return -EINVAL; + } + + if (do_channel_oper) { + /* + * Validate parameters before sending to lower layer. + * Do it here instead of parse_channel_args_to_params + * as this is right before sending the parameters to + * the lower layer. + */ + + if (channel_info.if_index == 0) { + iface = net_if_get_first_wifi(); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find the default wifi interface\n"); + return -ENOEXEC; + } + channel_info.if_index = net_if_get_by_iface(iface); + } else { + iface = net_if_get_by_index(channel_info.if_index); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find interface for if_index %d\n", + channel_info.if_index); + return -ENOEXEC; + } + } + + if (channel_info.oper == WIFI_MGMT_SET) { + if ((channel_info.channel < WIFI_CHANNEL_MIN) || + (channel_info.channel > WIFI_CHANNEL_MAX)) { + shell_fprintf(sh, SHELL_ERROR, + "Invalid channel number. Range is (1-233)\n"); + return -ENOEXEC; + } + } + + ret = net_mgmt(NET_REQUEST_WIFI_CHANNEL, iface, + &channel_info, sizeof(channel_info)); + + if (ret) { + shell_fprintf(sh, SHELL_ERROR, + "channel %s operation failed with reason %d\n", + channel_info.oper == WIFI_MGMT_GET ? "get" : "set", ret); + return -ENOEXEC; + } + + if (channel_info.oper == WIFI_MGMT_GET) { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current channel is: %d\n", + channel_info.channel); + } else { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi channel set to %d\n", + channel_info.channel); + } + } + return 0; +} + +void parse_filter_args_to_params(const struct shell *sh, int argc, + char *argv[], struct wifi_filter_info *filter, + bool *do_filter_oper) +{ + int opt; + int option_index = 0; + + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + {"capture_len", optional_argument, 0, 'b'}, + {"all", no_argument, 0, 'a'}, + {"mgmt", no_argument, 0, 'm'}, + {"ctrl", no_argument, 0, 'c'}, + {"data", no_argument, 0, 'd'}, + {"get", no_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; + + while ((opt = getopt_long(argc, argv, "i:b:amcdgh", long_options, &option_index)) != -1) { + switch (opt) { + case 'a': + filter->filter |= WIFI_PACKET_FILTER_ALL; + break; + case 'm': + filter->filter |= WIFI_PACKET_FILTER_MGMT; + break; + case 'c': + filter->filter |= WIFI_PACKET_FILTER_DATA; + break; + case 'd': + filter->filter |= WIFI_PACKET_FILTER_CTRL; + break; + case 'i': + filter->if_index = (uint8_t)atoi(optarg); + break; + case 'b': + filter->buffer_size = (uint16_t)atoi(optarg); + break; + case 'h': + shell_help(sh); + *do_filter_oper = false; + break; + case 'g': + filter->oper = WIFI_MGMT_GET; + break; + case '?': + default: + break; + } + } +} + +static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + struct wifi_filter_info packet_filter = {0}; + int ret; + bool do_filter_oper = true; + + if (argc > 1) { + packet_filter.oper = WIFI_MGMT_SET; + parse_filter_args_to_params(sh, argc, argv, &packet_filter, &do_filter_oper); + } else { + shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); + return -EINVAL; + } + + if (do_filter_oper) { + /* + * Validate parameters before sending to lower layer. + * Do it here instead of parse_filter_args_to_params + * as this is right before sending the parameters to + * the lower layer. filter and packet capture length + * value to be verified by the lower layer. + */ + if (packet_filter.if_index == 0) { + iface = net_if_get_first_wifi(); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find the default wifi interface\n"); + return -ENOEXEC; + } + packet_filter.if_index = net_if_get_by_iface(iface); + } else { + iface = net_if_get_by_index(packet_filter.if_index); + if (iface == NULL) { + shell_fprintf(sh, SHELL_ERROR, + "Cannot find interface for if_index %d\n", + packet_filter.if_index); + return -ENOEXEC; + } + } + + ret = net_mgmt(NET_REQUEST_WIFI_PACKET_FILTER, iface, + &packet_filter, sizeof(packet_filter)); + + if (ret) { + shell_fprintf(sh, SHELL_ERROR, + "Wi-Fi packet filter %s operation failed with reason %d\n", + packet_filter.oper == WIFI_MGMT_GET ? "get" : "set", ret); + return -ENOEXEC; + } + + if (packet_filter.oper == WIFI_MGMT_GET) { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current mode packet filter is %d\n", + packet_filter.filter); + } else { + shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi mode packet filter set to %d\n", + packet_filter.filter); + } + } + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, "Disable Access Point mode", @@ -1328,6 +1665,55 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "-f: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), + SHELL_CMD(mode, NULL, "mode operational setting\n" + "This command may be used to set the Wi-Fi device into a specific mode of operation\n" + "parameters:" + "[-i : Interface index - optional argument\n" + "[-s : Station mode.\n" + "[-m : Monitor mode.\n" + "[-p : Promiscuous mode.\n" + "[-t : TX-Injection mode.\n" + "[-a : AP mode.\n" + "[-k : Softap mode.\n" + "[-h : Help.\n" + "[-g : Get current mode for a specific interface index.\n" + "Usage: Get operation example for interface index 1\n" + "wifi mode -g -i1\n" + "Set operation example for interface index 1 - set station+promiscuous\n" + "wifi mode -i1 -sp\n", + cmd_wifi_mode), + SHELL_CMD(packet_filter, NULL, "mode filter setting\n" + "This command is used to set packet filter setting when\n" + "monitor, TX-Injection and promiscuous mode is enabled.\n" + "The different packet filter modes are control, management, data and enable all filters\n" + "parameters:" + "[-i : Interface index - optional argument.\n" + "[-a : Enable all packet filter modes\n" + "[-m : Enable management packets to allowed up the stack.\n" + "[-c : Enable control packets to be allowed up the stack.\n" + "[-d : Enable Data packets to be allowed up the stack.\n" + "[-g : Get current filter settings for a specific interface index.\n" + "<-b : Capture length buffer size for each packet to be captured - optional argument.\n" + "<-h : Help.\n" + "Usage: Get operation example for interface index 1\n" + "wifi packet_filter -g -i1\n" + "Set operation example for interface index 1 - set data+management frame filter\n" + "wifi packet_filter -i1 -md\n", + cmd_wifi_packet_filter), + SHELL_CMD(channel, NULL, "wifi channel setting\n" + "This command is used to set the channel when\n" + "monitor or TX-Injection mode is enabled.\n" + "Currently 20 MHz is only supported and no BW parameter is provided\n" + "parameters:" + "[-i : Interface index - optional argument.\n" + "[-c : Set a specific channel number to the lower layer.\n" + "[-g : Get current set channel number from the lower layer.\n" + "[-h : Help.\n" + "Usage: Get operation example for interface index 1\n" + "wifi channel -g -i1\n" + "Set operation example for interface index 1 (setting channel 5)\n" + "wifi -i1 -c5\n", + cmd_wifi_channel), SHELL_CMD_ARG(ps_timeout, NULL, " - PS inactivity timer(in ms)", From 49ef9be4b96323085ceb00483b8809ca3151585b Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Thu, 24 Aug 2023 10:14:39 +0100 Subject: [PATCH 0312/4498] drivers: regulator: npm1300: Add PFM mode Set regulator mode updated to support forced PFM mode Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_npm1300.c | 25 ++++++++++++++++--- .../zephyr/dt-bindings/regulator/npm1300.h | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index ad52374466d..95c6b8a4d02 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -265,17 +265,34 @@ int regulator_npm1300_get_voltage(const struct device *dev, int32_t *volt_uv) static int set_buck_mode(const struct device *dev, uint8_t chan, regulator_mode_t mode) { const struct regulator_npm1300_config *config = dev->config; + uint8_t pfm_mask = BIT(chan); + uint8_t pfm_data; + uint8_t pwm_reg; + int ret; switch (mode) { case NPM1300_BUCK_MODE_PWM: - return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, - BUCK_OFFSET_PWM_SET + (chan * 2U), 1U); + pfm_data = 0U; + pwm_reg = BUCK_OFFSET_PWM_SET; + break; case NPM1300_BUCK_MODE_AUTO: - return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, - BUCK_OFFSET_PWM_CLR + (chan * 2U), 1U); + pfm_data = 0U; + pwm_reg = BUCK_OFFSET_PWM_CLR; + break; + case NPM1300_BUCK_MODE_PFM: + pfm_data = pfm_mask; + pwm_reg = BUCK_OFFSET_PWM_CLR; + break; default: return -ENOTSUP; } + + ret = mfd_npm1300_reg_update(config->mfd, BUCK_BASE, BUCK_OFFSET_CTRL0, pfm_data, pfm_mask); + if (ret < 0) { + return ret; + } + + return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, pwm_reg + (chan * 2U), 1U); } static int set_ldsw_mode(const struct device *dev, uint8_t chan, regulator_mode_t mode) diff --git a/include/zephyr/dt-bindings/regulator/npm1300.h b/include/zephyr/dt-bindings/regulator/npm1300.h index 3293fe562d4..bf3f8cfa3ee 100644 --- a/include/zephyr/dt-bindings/regulator/npm1300.h +++ b/include/zephyr/dt-bindings/regulator/npm1300.h @@ -20,6 +20,7 @@ /* Buck modes */ #define NPM1300_BUCK_MODE_AUTO 0x00U #define NPM1300_BUCK_MODE_PWM 0x01U +#define NPM1300_BUCK_MODE_PFM 0x04U /* LDSW / LDO modes */ #define NPM1300_LDSW_MODE_LDO 0x02U From dd52908fcf1a6c82599657d027d96b3491f609f7 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Wed, 30 Aug 2023 15:26:02 +0100 Subject: [PATCH 0313/4498] drivers: regulator: npm1300: Set voltage checks existing setting Regulator voltage setting is not applied if the device output is already configured for the requested voltage. This change is needed to ensure correct device behaviour. Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_npm1300.c | 48 +++++++++++++++++---------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index 95c6b8a4d02..84ea5b68263 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -141,10 +141,33 @@ static int retention_set_voltage(const struct device *dev, int32_t retention_uv) idx); } +static int buck_get_voltage_index(const struct device *dev, uint8_t chan, uint8_t *idx) +{ + const struct regulator_npm1300_config *config = dev->config; + uint8_t sel; + int ret; + + ret = mfd_npm1300_reg_read(config->mfd, BUCK_BASE, BUCK_OFFSET_SW_CTRL, &sel); + + if (ret < 0) { + return ret; + } + + if ((sel >> chan) & 1U) { + /* SW control */ + return mfd_npm1300_reg_read(config->mfd, BUCK_BASE, + BUCK_OFFSET_VOUT_NORM + (chan * 2U), idx); + } + + /* VSET pin control */ + return mfd_npm1300_reg_read(config->mfd, BUCK_BASE, BUCK_OFFSET_VOUT_STAT + chan, idx); +} + static int buck_set_voltage(const struct device *dev, uint8_t chan, int32_t min_uv, int32_t max_uv) { const struct regulator_npm1300_config *config = dev->config; uint8_t mask; + uint8_t curr_idx; uint16_t idx; int ret; @@ -154,6 +177,13 @@ static int buck_set_voltage(const struct device *dev, uint8_t chan, int32_t min_ return ret; } + /* Get current setting, and return if current and new index match */ + ret = buck_get_voltage_index(dev, chan, &curr_idx); + + if ((ret < 0) || (idx == curr_idx)) { + return ret; + } + ret = mfd_npm1300_reg_write(config->mfd, BUCK_BASE, BUCK_OFFSET_VOUT_NORM + (chan * 2U), idx); @@ -201,26 +231,10 @@ int regulator_npm1300_set_voltage(const struct device *dev, int32_t min_uv, int3 static int buck_get_voltage(const struct device *dev, uint8_t chan, int32_t *volt_uv) { - const struct regulator_npm1300_config *config = dev->config; - uint8_t sel; uint8_t idx; int ret; - ret = mfd_npm1300_reg_read(config->mfd, BUCK_BASE, BUCK_OFFSET_SW_CTRL, &sel); - - if (ret < 0) { - return ret; - } - - if ((sel >> chan) & 1U) { - /* SW control */ - ret = mfd_npm1300_reg_read(config->mfd, BUCK_BASE, - BUCK_OFFSET_VOUT_NORM + (chan * 2U), &idx); - } else { - /* VSET pin control */ - ret = mfd_npm1300_reg_read(config->mfd, BUCK_BASE, BUCK_OFFSET_VOUT_STAT + chan, - &idx); - } + ret = buck_get_voltage_index(dev, chan, &idx); if (ret < 0) { return ret; From 395395b266c56c9ba52ad61f271ad39c26acbe1b Mon Sep 17 00:00:00 2001 From: Paulo Santos Date: Thu, 31 Aug 2023 11:03:53 -0300 Subject: [PATCH 0314/4498] soc: arm: efr32bg22: add missing GPIO flag Add the missing SOC_GECKO_GPIO selection to the EFR32BG22 SoC Series. Signed-off-by: Paulo Santos --- soc/arm/silabs_exx32/efr32bg22/Kconfig.series | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series index 266d6391725..992e3be97ba 100644 --- a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series @@ -16,6 +16,7 @@ config SOC_SERIES_EFR32BG22 select HAS_SWO select SOC_FAMILY_EXX32 select SOC_GECKO_SERIES2 + select SOC_GECKO_GPIO select SOC_GECKO_CMU select SOC_GECKO_CORE select SOC_GECKO_DEV_INIT From 0829d59925d09b9da8ecd1ff64652b4ea5465e16 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 31 Aug 2023 16:05:44 +0200 Subject: [PATCH 0315/4498] dts: stm32wba: Add missing SoC compatible SoC compatible is now expected in soc .dtsi files Signed-off-by: Erwan Gouriou --- dts/arm/st/wba/stm32wba52Xg.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dts/arm/st/wba/stm32wba52Xg.dtsi b/dts/arm/st/wba/stm32wba52Xg.dtsi index 49724f35e5c..f4ddcbbc9e7 100644 --- a/dts/arm/st/wba/stm32wba52Xg.dtsi +++ b/dts/arm/st/wba/stm32wba52Xg.dtsi @@ -12,6 +12,8 @@ }; soc { + compatible = "st,stm32wba52", "st,stm32wba", "simple-bus"; + flash-controller@40022000 { flash0: flash@8000000 { reg = <0x08000000 DT_SIZE_M(1)>; From 9f52fac1eaed7bd34fb5fd072176ca8f3e1d909c Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 26 Jul 2023 16:10:43 +0200 Subject: [PATCH 0316/4498] driver: entropy: stm32: Enable PM Enable PM on STM32 entropy driver. Only supports PM_DEVICE for now, runtime support will be added later. Signed-off-by: Erwan Gouriou --- drivers/entropy/entropy_stm32.c | 50 ++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 9f2ad136203..cecff05e9e3 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -639,13 +640,60 @@ static int entropy_stm32_rng_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int entropy_stm32_rng_pm_action(const struct device *dev, + enum pm_device_action action) +{ + struct entropy_stm32_rng_dev_data *dev_data = dev->data; + const struct entropy_stm32_rng_dev_cfg *dev_cfg = dev->config; + RNG_TypeDef *rng = dev_data->rng; + int res = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + LL_RNG_Disable(rng); + +#ifdef CONFIG_SOC_SERIES_STM32WBAX + uint32_t wait_cycles, rng_rate; + + if (clock_control_get_rate(dev_data->clock, + (clock_control_subsys_t) &dev_cfg->pclken[0], + &rng_rate) < 0) { + return -EIO; + } + + wait_cycles = SystemCoreClock / rng_rate * 2; + + for (int i = wait_cycles; i >= 0; i--) { + } +#endif /* CONFIG_SOC_SERIES_STM32WBAX */ + + res = clock_control_off(dev_data->clock, + (clock_control_subsys_t)&dev_cfg->pclken[0]); + break; + case PM_DEVICE_ACTION_RESUME: + res = clock_control_on(dev_data->clock, + (clock_control_subsys_t)&dev_cfg->pclken[0]); + LL_RNG_Enable(rng); + break; + default: + return -ENOTSUP; + } + + return res; +} +#endif /* CONFIG_PM_DEVICE */ + static const struct entropy_driver_api entropy_stm32_rng_api = { .get_entropy = entropy_stm32_rng_get_entropy, .get_entropy_isr = entropy_stm32_rng_get_entropy_isr }; +PM_DEVICE_DT_INST_DEFINE(0, entropy_stm32_rng_pm_action); + DEVICE_DT_INST_DEFINE(0, - entropy_stm32_rng_init, NULL, + entropy_stm32_rng_init, + PM_DEVICE_DT_INST_GET(0), &entropy_stm32_rng_data, &entropy_stm32_rng_config, PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, &entropy_stm32_rng_api); From dbc4cfabdb6db0b29d52bff72abce1af3398c566 Mon Sep 17 00:00:00 2001 From: Dong Wang Date: Fri, 8 Sep 2023 10:09:04 +0800 Subject: [PATCH 0317/4498] manifest: intel_hal: update to get more PM patches It contains SEDI PM enhancements and bug fixing. Signed-off-by: Dong Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index cb407d976c0..b3ddef9ca14 100644 --- a/west.yml +++ b/west.yml @@ -173,7 +173,7 @@ manifest: groups: - hal - name: hal_intel - revision: c72eea412d2563463043a2a6cfe41dc46e845d47 + revision: b3b43d4e3da7ba483611bbbea7ef8af92c69df31 path: modules/hal/intel groups: - hal From b328e920b6dfa293ad76102bb73b1b430fb6e983 Mon Sep 17 00:00:00 2001 From: Manimaran A Date: Thu, 31 Aug 2023 16:40:41 +0530 Subject: [PATCH 0318/4498] drivers: spi: Microchip MEC172x SPI fix for Zephyr 3.4 breakage Zephyr version 3.4 changed the SPI context structure and macros which broke the logic in the MEC172x SPI driver configuration API. This was not detected by CI due to no tests for this driver are in the tree. The driver now behaves like most other SPI drivers requiring a different configuration structure pointer to be passed if any item in the configuration changes. Signed-off-by: Manimaran A --- drivers/spi/spi_xec_qmspi_ldma.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi_xec_qmspi_ldma.c b/drivers/spi/spi_xec_qmspi_ldma.c index a5ba08e600b..ab48e49c095 100644 --- a/drivers/spi/spi_xec_qmspi_ldma.c +++ b/drivers/spi/spi_xec_qmspi_ldma.c @@ -346,7 +346,6 @@ static int qmspi_configure(const struct device *dev, { const struct spi_qmspi_config *cfg = dev->config; struct spi_qmspi_data *qdata = dev->data; - const struct spi_config *curr_cfg = qdata->ctx.config; struct qmspi_regs *regs = cfg->regs; uint32_t smode; int ret; @@ -355,13 +354,11 @@ static int qmspi_configure(const struct device *dev, return -EINVAL; } - if (curr_cfg->frequency != config->frequency) { - qmspi_set_frequency(qdata, regs, config->frequency); + if (spi_context_configured(&qdata->ctx, config)) { + return 0; } - if (curr_cfg->operation == config->operation) { - return 0; /* no change required */ - } + qmspi_set_frequency(qdata, regs, config->frequency); /* check new configuration */ ret = spi_feature_support(config); From 5e2498b54fc6dbccbe17ac825b83f1a78d68da4d Mon Sep 17 00:00:00 2001 From: Manimaran A Date: Thu, 31 Aug 2023 16:42:50 +0530 Subject: [PATCH 0319/4498] tests: boards: mec172xevb_assy6906 Add SPI driver test Add a test for the Microchip MEC172x SPI driver using the mec172xevb_assy6906 board with an external SPI dongle. Signed-off-by: Manimaran A --- .../mec172xevb_assy6906/qspi/CMakeLists.txt | 8 + .../mec172xevb_assy6906/qspi/README.txt | 2 + .../qspi/boards/mec172xevb_assy6906.overlay | 18 + .../boards/mec172xevb_assy6906/qspi/prj.conf | 5 + .../mec172xevb_assy6906/qspi/src/main.c | 657 ++++++++++++++++++ .../mec172xevb_assy6906/qspi/testcase.yaml | 7 + 6 files changed, 697 insertions(+) create mode 100644 tests/boards/mec172xevb_assy6906/qspi/CMakeLists.txt create mode 100644 tests/boards/mec172xevb_assy6906/qspi/README.txt create mode 100644 tests/boards/mec172xevb_assy6906/qspi/boards/mec172xevb_assy6906.overlay create mode 100644 tests/boards/mec172xevb_assy6906/qspi/prj.conf create mode 100644 tests/boards/mec172xevb_assy6906/qspi/src/main.c create mode 100644 tests/boards/mec172xevb_assy6906/qspi/testcase.yaml diff --git a/tests/boards/mec172xevb_assy6906/qspi/CMakeLists.txt b/tests/boards/mec172xevb_assy6906/qspi/CMakeLists.txt new file mode 100644 index 00000000000..5c672271901 --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(qspi) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/boards/mec172xevb_assy6906/qspi/README.txt b/tests/boards/mec172xevb_assy6906/qspi/README.txt new file mode 100644 index 00000000000..6cab25952b5 --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/README.txt @@ -0,0 +1,2 @@ +Build test for: + Microchip mec172xevb_assy6906 qspi driver test. diff --git a/tests/boards/mec172xevb_assy6906/qspi/boards/mec172xevb_assy6906.overlay b/tests/boards/mec172xevb_assy6906/qspi/boards/mec172xevb_assy6906.overlay new file mode 100644 index 00000000000..c59d40a485e --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/boards/mec172xevb_assy6906.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi0 { + status = "okay"; + chip-select = <0>; + lines = <4>; + + pinctrl-0 = < &shd_cs0_n_gpio055 + &shd_clk_gpio056 + &shd_io0_gpio223 + &shd_io1_gpio224 + &shd_io2_gpio227 + &shd_io3_gpio016 >; +}; diff --git a/tests/boards/mec172xevb_assy6906/qspi/prj.conf b/tests/boards/mec172xevb_assy6906/qspi/prj.conf new file mode 100644 index 00000000000..0637abd47e2 --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/prj.conf @@ -0,0 +1,5 @@ +CONFIG_SPI=y +CONFIG_SPI_EXTENDED_MODES=y +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_TEST_USERSPACE=y diff --git a/tests/boards/mec172xevb_assy6906/qspi/src/main.c b/tests/boards/mec172xevb_assy6906/qspi/src/main.c new file mode 100644 index 00000000000..feac946c46e --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/src/main.c @@ -0,0 +1,657 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define TEST_FREQ_HZ 24000000U +#define W25Q128_JEDEC_ID 0x001840efU + +#define TEST_BUF_SIZE 4096U +/* #define MAX_SPI_BUF 8 */ + +#define SPI_STATUS1_BUSY 0x01U +#define SPI_STATUS1_WEL 0x02U +#define SPI_STATUS2_QE 0x02U +#define SPI_READ_JEDEC_ID 0x9FU +#define SPI_READ_STATUS1 0x05U +#define SPI_READ_STATUS2 0x35U +#define SPI_WRITE_STATUS2 0x31U +#define SPI_WRITE_ENABLE_VS 0x50U +#define SPI_WRITE_ENABLE 0x06U +#define SPI_SECTOR_ERASE 0x20U +#define SPI_SINGLE_WRITE_DATA 0x02U +#define SPI_QUAD_WRITE_DATA 0x32U + +/* bits[7:0] = spi opcode, + * bits[15:8] = bytes number of clocks with data lines tri-stated + */ +#define SPI_FAST_READ_DATA 0x080BU +#define SPI_DUAL_FAST_READ_DATA 0x083BU +#define SPI_QUAD_FAST_READ_DATA 0x086BU +#define SPI_OCTAL_QUAD_READ_DATA 0xE3U + +#define BUF_SIZE 11 +uint8_t buffer_tx[] = "0123456789\0"; +#define BUF_SIZE_2 7 +uint8_t buffer_tx_2[] = "abcdef\0"; + +#define SPI_TEST_ADDRESS 0x000010U +#define SPI_TEST_ADDRESS_2 0x000020U + +static uint8_t safbuf[TEST_BUF_SIZE] __aligned(4); +static uint8_t safbuf2[TEST_BUF_SIZE] __aligned(4); +static const struct device *const spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi0)); + +/* static struct spi_buf spi_bufs[MAX_SPI_BUF]; */ + +static const struct spi_config spi_cfg_single = { + .frequency = TEST_FREQ_HZ, + .operation = (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) + | SPI_LINES_SINGLE), +}; + +static const struct spi_config spi_cfg_single_hold_cs = { + .frequency = TEST_FREQ_HZ, + .operation = (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) + | SPI_LINES_SINGLE | SPI_HOLD_ON_CS), +}; + +static const struct spi_config spi_cfg_dual = { + .frequency = TEST_FREQ_HZ, + .operation = (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) + | SPI_LINES_DUAL), +}; + +static const struct spi_config spi_cfg_quad = { + .frequency = TEST_FREQ_HZ, + .operation = (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) + | SPI_LINES_QUAD), +}; + +static void spi_single_init(void) +{ + zassert_true(device_is_ready(spi_dev), "SPI controller device is not ready"); +} + +static void clear_buffers(void) +{ + memset(safbuf, 0, sizeof(safbuf)); + memset(safbuf2, 0, sizeof(safbuf2)); +} + +/* Compute the number of bytes required to generate the requested number of + * SPI clocks based on single, dual, or quad mode. + * mode = 1(full-duplex), 2(dual), 4(quad) + * full-duplex: 8 clocks per byte + * dual: 4 clocks per byte + * quad: 2 clocks per byte + */ +static uint32_t spi_clocks_to_bytes(uint32_t spi_clocks, uint8_t mode) +{ + uint32_t nbytes; + + if (mode == 4u) { + nbytes = spi_clocks / 2U; + } else if (mode == 2u) { + nbytes = spi_clocks / 4U; + } else { + nbytes = spi_clocks / 8U; + } + + return nbytes; +} + + +static int spi_flash_address_format(uint8_t *dest, size_t destsz, + uint32_t spi_addr, size_t addrsz) +{ + if (!dest || (addrsz == 0) || (addrsz > 4U) || (addrsz > destsz)) { + return -EINVAL; + } + + for (size_t i = 0; i < addrsz; i++) { + dest[i] = (uint8_t)((spi_addr >> ((addrsz - (i + 1U)) * 8U)) & 0xffU); + } + + return 0; +} + +static int spi_flash_read_status(const struct device *dev, uint8_t opcode, uint8_t *status) +{ + struct spi_buf spi_bufs[2] = { 0 }; + uint32_t txdata = 0; + uint32_t rxdata = 0; + int ret = 0; + + txdata = opcode; + + spi_bufs[0].buf = &txdata; + spi_bufs[0].len = 1U; + spi_bufs[1].buf = &rxdata; + spi_bufs[1].len = 1U; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 2U, + }; + const struct spi_buf_set rxset = { + .buffers = &spi_bufs[0], + .count = 2U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, &rxset); + if (ret) { + return ret; + } + + if (status) { + *status = (uint8_t)(rxdata & 0xffu); + } + + return 0; +} + +static int spi_flash_write_status(const struct device *dev, uint8_t opcode, uint8_t spi_status) +{ + struct spi_buf spi_bufs[1] = { 0 }; + uint32_t txdata = 0; + int ret = 0; + + txdata = spi_status; + txdata <<= 8U; + txdata |= opcode; + + spi_bufs[0].buf = &txdata; + spi_bufs[0].len = 2U; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 1U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, NULL); + if (ret) { + return ret; + } + + return 0; +} + +static int spi_flash_tx_one_byte_cmd(const struct device *dev, uint8_t opcode) +{ + struct spi_buf spi_bufs[1] = { 0 }; + uint32_t txdata = 0; + int ret = 0; + + txdata = opcode; + spi_bufs[0].buf = &txdata; + spi_bufs[0].len = 1U; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 1U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, NULL); + if (ret) { + return ret; + } + + return 0; +} + +/** + * @brief Test spi device + * @details + * - Find spi device + * - Read flash jedec id + */ +ZTEST_USER(spi, test_spi_device) +{ + struct spi_buf spi_bufs[2] = { 0 }; + uint32_t txdata = 0; + uint32_t jedec_id = 0; + int ret = 0; + + /* read jedec id */ + txdata = SPI_READ_JEDEC_ID; + + spi_bufs[0].buf = &txdata; + spi_bufs[0].len = 1U; + spi_bufs[1].buf = &jedec_id; + spi_bufs[1].len = 3U; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 2U, + }; + const struct spi_buf_set rxset = { + .buffers = &spi_bufs[0], + .count = 2U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, &rxset); + zassert_true(ret == 0, "Read JEDEC ID spi_transceive failure: " + "error %d", ret); + zassert_true(jedec_id == W25Q128_JEDEC_ID, + "JEDEC ID doesn't match: expected 0x%08x, read 0x%08x", + W25Q128_JEDEC_ID, jedec_id); +} + +/** + * @brief Test spi sector erase + * @details + * - write enable + * - erase data in flash device + * - read register1 and wait for erase operation completed + */ +ZTEST_USER(spi_sector_erase, test_spi_sector_erase) +{ + struct spi_buf spi_bufs[2] = { 0 }; + int ret = 0; + uint8_t spi_status = 0; + + clear_buffers(); + + /* write enable */ + ret = spi_flash_tx_one_byte_cmd(spi_dev, SPI_WRITE_ENABLE); + zassert_true(ret == 0, "Send write enable spi_transceive failure: error %d", ret); + + /* erase data start from address SPI_TEST_ADDRESS */ + safbuf[0] = SPI_SECTOR_ERASE; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS, 3U); + + spi_bufs[0].buf = &safbuf; + spi_bufs[0].len = 4; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 1U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, NULL); + zassert_true(ret == 0, "Send sector erase data spi_transceive failure: error %d", ret); + + /* read SPI flash status register1 to check whether erase operation completed */ + spi_status = SPI_STATUS1_BUSY; + while (spi_status & SPI_STATUS1_BUSY) { + ret = spi_flash_read_status(spi_dev, SPI_READ_STATUS1, &spi_status); + zassert_true(ret == 0, "Send read register1 spi_transceive " + "failure: error %d", ret); + } +} + +/** + * @brief Write data into flash using spi api + * @details + * - flash write enable + * - write data into flash using spi api + */ +static void test_spi_single_write(void) +{ + struct spi_buf spi_bufs[1] = { 0 }; + int ret = 0; + uint8_t spi_status = 0; + + clear_buffers(); + + ret = spi_flash_tx_one_byte_cmd(spi_dev, SPI_WRITE_ENABLE); + zassert_true(ret == 0, "Send write enable spi_transceive failure: " + "error %d", ret); + + /* write data start from address SPI_TEST_ADDRESS */ + safbuf[0] = SPI_SINGLE_WRITE_DATA; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS, 3U); + + memcpy(&safbuf[4], buffer_tx, BUF_SIZE); + + spi_bufs[0].buf = &safbuf; + spi_bufs[0].len = 4U + BUF_SIZE; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 1U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, NULL); + zassert_true(ret == 0, "Send write data spi_transceive failure: error %d", ret); + + /* read register1 to check whether program operation completed */ + spi_status = SPI_STATUS1_BUSY; + while (spi_status & SPI_STATUS1_BUSY) { + ret = spi_flash_read_status(spi_dev, SPI_READ_STATUS1, &spi_status); + zassert_true(ret == 0, "Read SPI flash STATUS opcode 0x%02x error: %d", + SPI_READ_STATUS1, ret); + } +} + +/** + * @brief Read data from flash using spi single mode + * @details + * - read data using spi single mode + * - check read buffer data whether correct + * @note SPI flash fast instructions require a certain number of SPI clocks + * to be generated with I/O lines tri-stated after the address has been + * transmitted. The purpose is allow SPI flash time to move get data ready + * and enable its output line(s). The MCHP XEC SPI driver can do this by + * specifying a struct spi_buf with buf pointer set to NULL and length set + * to the number of bytes which will generate the required number of clocks. + * For full-duplex one byte is 8 clocks, dual one byte is 4 clocks, and for + * quad one byte is 2 clocks. + */ +ZTEST_USER(spi, test_spi_single_read) +{ + struct spi_buf spi_bufs[3] = { 0 }; + int ret = 0; + uint16_t spi_opcode = 0; + uint8_t cnt = 0; + + clear_buffers(); + + /* bits[7:0] = opcode, + * bits[15:8] = number of SPI clocks with I/O lines tri-stated after + * address transmit before data read phase. + */ + spi_opcode = SPI_FAST_READ_DATA; + + /* read data using spi single mode */ + /* set the spi operation code and address */ + safbuf[0] = spi_opcode & 0xFFU; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS, 3U); + + spi_bufs[cnt].buf = &safbuf; + spi_bufs[cnt].len = 4U; + + /* set the dummy clocks */ + if (spi_opcode & 0xFF00U) { + cnt++; + spi_bufs[cnt].buf = NULL; + spi_bufs[cnt].len = spi_clocks_to_bytes(((spi_opcode >> 8) & 0xffU), 1u); + } + + cnt++; + spi_bufs[cnt].buf = &safbuf2; + spi_bufs[cnt].len = BUF_SIZE; + cnt++; /* total number of buffers */ + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = cnt, + }; + + const struct spi_buf_set rxset = { + .buffers = &spi_bufs[0], + .count = cnt, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single, &txset, &rxset); + zassert_true(ret == 0, "Send fast read data spi_transceive failure: error %d", ret); + + /* check read buffer data whether correct */ + zassert_true(memcmp(buffer_tx, safbuf2, BUF_SIZE) == 0, + "Buffer read data is different to write data"); +} + +static void spi_dual_init(void) +{ + zassert_true(device_is_ready(spi_dev), "SPI controller device is not ready"); +} + +/** + * @brief Read data from flash using spi dual mode + * @details + * - read data using spi dual mode + * - check read buffer data whether correct + */ +ZTEST_USER(spi, test_spi_dual_read) +{ + struct spi_buf spi_bufs[3] = { 0 }; + int ret = 0; + uint16_t spi_opcode = 0; + uint8_t cnt = 0; + + clear_buffers(); + + spi_dual_init(); + + spi_opcode = SPI_DUAL_FAST_READ_DATA; + + /* read data using spi dual mode */ + /* set the spi operation code and address */ + safbuf[0] = spi_opcode & 0xFFU; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS, 3U); + + spi_bufs[cnt].buf = &safbuf; + spi_bufs[cnt].len = 4U; + + /* set the dummy clocks */ + if (spi_opcode & 0xFF00U) { + cnt++; + spi_bufs[cnt].buf = NULL; + spi_bufs[cnt].len = spi_clocks_to_bytes(((spi_opcode >> 8) & 0xffU), 1u); + } + + cnt++; + spi_bufs[cnt].buf = &safbuf2; + spi_bufs[cnt].len = BUF_SIZE; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = cnt, + }; + + const struct spi_buf_set rxset = { + .buffers = &spi_bufs[cnt], + .count = 1U, + }; + + /* send opcode, address, and tri-state clocks using single mode */ + ret = spi_transceive(spi_dev, &spi_cfg_single_hold_cs, &txset, NULL); + zassert_true(ret == 0, "Send fast read data spi_transceive failure: error %d", ret); + + /* get read data using dual mode */ + ret = spi_transceive(spi_dev, &spi_cfg_dual, NULL, &rxset); + zassert_true(ret == 0, "Receive fast read data spi_transceive failure: error %d", ret); + + /* check read buffer data whether correct */ + zassert_true(memcmp(buffer_tx, safbuf2, BUF_SIZE) == 0, + "Buffer read data is different to write data"); + + /* release spi device */ + ret = spi_release(spi_dev, &spi_cfg_single); + zassert_true(ret == 0, "Spi release failure: error %d", ret); +} + +/** + * @brief Write data into flash using spi quad mode + * @details + * - check and make sure spi quad mode is enabled + * - write data using spi quad mode + */ +static void test_spi_quad_write(void) +{ + struct spi_buf spi_bufs[2] = { 0 }; + int ret = 0; + uint8_t spi_status = 0; + uint8_t spi_status2 = 0; + + clear_buffers(); + + /* read register2 to judge whether quad mode is enabled */ + ret = spi_flash_read_status(spi_dev, SPI_READ_STATUS2, &spi_status2); + zassert_true(ret == 0, "SPI read flash STATUS2 failure: error %d", ret); + + /* set register2 QE=1 to enable quad mode. We write the volatile STATUS2 register + * not the normal STATUS2 which retains the value across a power cycle. + */ + if ((spi_status2 & SPI_STATUS2_QE) == 0U) { + ret = spi_flash_tx_one_byte_cmd(spi_dev, SPI_WRITE_ENABLE_VS); + zassert_true(ret == 0, "Send write enable volatile spi_transceive failure: " + "error %d", ret); + + spi_status2 |= SPI_STATUS2_QE; + ret = spi_flash_write_status(spi_dev, SPI_WRITE_STATUS2, spi_status2); + zassert_true(ret == 0, "Write spi status2 QE=1 spi_transceive failure: " + "error %d", ret); + + /* read register2 to confirm quad mode is enabled */ + spi_status2 = 0u; + ret = spi_flash_read_status(spi_dev, SPI_READ_STATUS2, &spi_status2); + zassert_true(ret == 0, "Read register2 status spi_transceive failure: " + "error %d", ret); + + zassert_true((spi_status2 & SPI_STATUS2_QE) == SPI_STATUS2_QE, + "Enable QSPI mode failure"); + } + + /* write enable */ + ret = spi_flash_tx_one_byte_cmd(spi_dev, SPI_WRITE_ENABLE); + zassert_true(ret == 0, "Send write enable spi_transceive failure: error %d", ret); + + /* write data using spi quad mode */ + /* send quad write opcode and address using single mode */ + safbuf[0] = SPI_QUAD_WRITE_DATA; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS_2, 3U); + + spi_bufs[0].buf = &safbuf; + spi_bufs[0].len = 4; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = 1U, + }; + + ret = spi_transceive(spi_dev, &spi_cfg_single_hold_cs, &txset, NULL); + zassert_true(ret == 0, "Send quad write data spi_transceive failure: error %d", ret); + + /* send data using quad mode */ + memcpy(&safbuf[0], buffer_tx_2, BUF_SIZE_2); + + spi_bufs[0].buf = &safbuf; + spi_bufs[0].len = BUF_SIZE_2; + + ret = spi_transceive(spi_dev, &spi_cfg_quad, &txset, NULL); + zassert_true(ret == 0, "Send quad write data spi_transceive failure: error %d", ret); + + /* call SPI release API to clear SPI CS Hold On lock */ + ret = spi_release(spi_dev, &spi_cfg_single); + zassert_true(ret == 0, "Spi release failure: error %d", ret); + + /* poll busy bit in flash status1 register */ + spi_status = SPI_STATUS1_BUSY; + while (spi_status & SPI_STATUS1_BUSY) { + ret = spi_flash_read_status(spi_dev, SPI_READ_STATUS1, &spi_status); + zassert_true(ret == 0, "Read flash STATUS1 register error %d", ret); + } +} + +/** + * @brief Read data from flash using spi quad mode + * @details + * - read data using spi quad mode + * - check read buffer data whether correct + */ +ZTEST_USER(spi_quad, test_spi_quad_read) +{ + struct spi_buf spi_bufs[3] = {0}; + int ret = 0; + uint16_t spi_opcode = 0; + uint8_t cnt = 0; + + clear_buffers(); + + spi_opcode = SPI_QUAD_FAST_READ_DATA; + + /* read data using spi quad mode + * Transmit opcode, address, and tri-state clocks using full-duplex mode + * with driver Hold CS ON flag. + * Next, read data using dual configuration. + * Call driver release API to release lock set by Hold CS ON flag. + */ + + /* set the spi operation code and address */ + safbuf[0] = spi_opcode & 0xFFU; + spi_flash_address_format(&safbuf[1], 4U, SPI_TEST_ADDRESS_2, 3U); + + spi_bufs[cnt].buf = &safbuf; + spi_bufs[cnt].len = 4U; + + /* set the dummy clocks */ + if (spi_opcode & 0xFF00U) { + cnt++; + spi_bufs[cnt].buf = NULL; + spi_bufs[cnt].len = spi_clocks_to_bytes(((spi_opcode >> 8) & 0xffU), 1u); + } + + cnt++; + spi_bufs[cnt].buf = &safbuf2; + spi_bufs[cnt].len = BUF_SIZE_2; + + const struct spi_buf_set txset = { + .buffers = &spi_bufs[0], + .count = cnt, + }; + + const struct spi_buf_set rxset = { + .buffers = &spi_bufs[cnt], + .count = 1U, + }; + + /* send opcode and address using single mode with Hold CS ON flag */ + ret = spi_transceive(spi_dev, &spi_cfg_single_hold_cs, &txset, NULL); + zassert_true(ret == 0, "Send fast read data spi_transceive failure: error %d", ret); + + /* read data using quad mode */ + ret = spi_transceive(spi_dev, &spi_cfg_quad, NULL, &rxset); + zassert_true(ret == 0, "Receive fast read data spi_transceive failure: error %d", ret); + + /* release spi device */ + ret = spi_release(spi_dev, &spi_cfg_single); + zassert_true(ret == 0, "Spi release failure: error %d", ret); + + /* check read buffer data whether correct */ + zassert_true(memcmp(buffer_tx_2, safbuf2, BUF_SIZE_2) == 0, + "Buffer read data is different to write data"); +} + +void *spi_setup(void) +{ + spi_single_init(); + + return NULL; +} + +void *spi_single_setup(void) +{ + spi_single_init(); + + /* The writing test goes + * first berfore testing + * the reading. + */ + test_spi_single_write(); + + return NULL; +} + +void *spi_quad_setup(void) +{ + spi_dual_init(); + + /* The writing test goes + * first berfore testing + * the reading. + */ + test_spi_quad_write(); + + return NULL; +} + +/* Test assumes flash test regions is in erased state */ +ZTEST_SUITE(spi, NULL, spi_single_setup, NULL, NULL, NULL); +ZTEST_SUITE(spi_quad, NULL, spi_quad_setup, NULL, NULL, NULL); +ZTEST_SUITE(spi_sector_erase, NULL, spi_setup, NULL, NULL, NULL); diff --git a/tests/boards/mec172xevb_assy6906/qspi/testcase.yaml b/tests/boards/mec172xevb_assy6906/qspi/testcase.yaml new file mode 100644 index 00000000000..f0302f66cbb --- /dev/null +++ b/tests/boards/mec172xevb_assy6906/qspi/testcase.yaml @@ -0,0 +1,7 @@ +tests: + boards.mec172xevb_assy6906.qspi: + platform_allow: mec172xevb_assy6906 + tags: + - drivers + - spi + - qspi From d40dbdf96f7f6cbc96d4f879080bbc06285e2969 Mon Sep 17 00:00:00 2001 From: Vladimir Graudt Date: Tue, 11 Apr 2023 19:05:34 +0300 Subject: [PATCH 0320/4498] modules: mbedtls: use proper memory alignment on 64-bit platforms This commit instructs mbedtls to use 64-bit alignment in its internal memory allocation routines when targeting 64-bit platforms. By default mbedtls uses 32-bit alignment regardless the platform, what may result in misaligned memory accesses, possibly inducing access time overhead or exceptions Signed-off-by: Vladimir Graudt --- modules/mbedtls/configs/config-coap.h | 1 + modules/mbedtls/configs/config-mini-dtls1_2.h | 1 + modules/mbedtls/configs/config-mini-tls1_2.h | 1 + modules/mbedtls/configs/config-threadnet.h | 1 + modules/mbedtls/configs/config-tls-generic.h | 1 + 5 files changed, 5 insertions(+) diff --git a/modules/mbedtls/configs/config-coap.h b/modules/mbedtls/configs/config-coap.h index 18ed60ef7c7..f610eb20bc6 100644 --- a/modules/mbedtls/configs/config-coap.h +++ b/modules/mbedtls/configs/config-coap.h @@ -35,6 +35,7 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE (sizeof(void *)) #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS #define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY diff --git a/modules/mbedtls/configs/config-mini-dtls1_2.h b/modules/mbedtls/configs/config-mini-dtls1_2.h index 3a13e0d7ca7..ee0d70b5915 100644 --- a/modules/mbedtls/configs/config-mini-dtls1_2.h +++ b/modules/mbedtls/configs/config-mini-dtls1_2.h @@ -16,6 +16,7 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE (sizeof(void *)) #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS #define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY diff --git a/modules/mbedtls/configs/config-mini-tls1_2.h b/modules/mbedtls/configs/config-mini-tls1_2.h index f725801a62e..4045fe70478 100644 --- a/modules/mbedtls/configs/config-mini-tls1_2.h +++ b/modules/mbedtls/configs/config-mini-tls1_2.h @@ -15,6 +15,7 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE (sizeof(void *)) #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS #define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY diff --git a/modules/mbedtls/configs/config-threadnet.h b/modules/mbedtls/configs/config-threadnet.h index 6804c790fbf..c6676f03433 100644 --- a/modules/mbedtls/configs/config-threadnet.h +++ b/modules/mbedtls/configs/config-threadnet.h @@ -38,6 +38,7 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE (sizeof(void *)) #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS #define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index 2268571abe0..9d5dcfdaa47 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -15,6 +15,7 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE (sizeof(void *)) #define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY From 387f3c2092d736b80f913128b2ff09910659f4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Kr=C3=BCger?= Date: Mon, 19 Jun 2023 16:33:13 +0200 Subject: [PATCH 0321/4498] drivers: fuelgauge: Add TI BQ27z746 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add driver for the Texas Instruments BQ27z746 fuel gauge Signed-off-by: Marcel Krüger --- drivers/fuel_gauge/CMakeLists.txt | 1 + drivers/fuel_gauge/Kconfig | 2 +- drivers/fuel_gauge/bq27z746/CMakeLists.txt | 6 + drivers/fuel_gauge/bq27z746/Kconfig | 21 ++ drivers/fuel_gauge/bq27z746/bq27z746.c | 324 ++++++++++++++++ drivers/fuel_gauge/bq27z746/bq27z746.h | 142 +++++++ drivers/fuel_gauge/bq27z746/emul_bq27z746.c | 352 ++++++++++++++++++ dts/bindings/fuel-gauge/ti,bq27z746.yaml | 13 + .../fuel_gauge/bq27z746/CMakeLists.txt | 8 + .../bq27z746/boards/native_posix.conf | 3 + .../bq27z746/boards/native_posix.overlay | 11 + tests/drivers/fuel_gauge/bq27z746/prj.conf | 7 + .../fuel_gauge/bq27z746/src/test_bq27z746.c | 246 ++++++++++++ .../drivers/fuel_gauge/bq27z746/testcase.yaml | 5 + 14 files changed, 1140 insertions(+), 1 deletion(-) create mode 100644 drivers/fuel_gauge/bq27z746/CMakeLists.txt create mode 100644 drivers/fuel_gauge/bq27z746/Kconfig create mode 100644 drivers/fuel_gauge/bq27z746/bq27z746.c create mode 100644 drivers/fuel_gauge/bq27z746/bq27z746.h create mode 100644 drivers/fuel_gauge/bq27z746/emul_bq27z746.c create mode 100644 dts/bindings/fuel-gauge/ti,bq27z746.yaml create mode 100644 tests/drivers/fuel_gauge/bq27z746/CMakeLists.txt create mode 100644 tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf create mode 100644 tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay create mode 100644 tests/drivers/fuel_gauge/bq27z746/prj.conf create mode 100644 tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c create mode 100644 tests/drivers/fuel_gauge/bq27z746/testcase.yaml diff --git a/drivers/fuel_gauge/CMakeLists.txt b/drivers/fuel_gauge/CMakeLists.txt index 6a95c89ea46..c48e2ead003 100644 --- a/drivers/fuel_gauge/CMakeLists.txt +++ b/drivers/fuel_gauge/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/fuel_gauge.h) add_subdirectory_ifdef(CONFIG_SBS_GAUGE_NEW_API sbs_gauge) add_subdirectory_ifdef(CONFIG_MAX17048 max17048) +add_subdirectory_ifdef(CONFIG_BQ27Z746 bq27z746) zephyr_library_sources_ifdef(CONFIG_USERSPACE fuel_gauge_syscall_handlers.c) diff --git a/drivers/fuel_gauge/Kconfig b/drivers/fuel_gauge/Kconfig index 929dd060490..616ab3885d2 100644 --- a/drivers/fuel_gauge/Kconfig +++ b/drivers/fuel_gauge/Kconfig @@ -20,7 +20,7 @@ config FUEL_GAUGE_INIT_PRIORITY Battery fuel gauge initialization priority. source "drivers/fuel_gauge/max17048/Kconfig" - source "drivers/fuel_gauge/sbs_gauge/Kconfig" +source "drivers/fuel_gauge/bq27z746/Kconfig" endif # FUEL_GAUGE diff --git a/drivers/fuel_gauge/bq27z746/CMakeLists.txt b/drivers/fuel_gauge/bq27z746/CMakeLists.txt new file mode 100644 index 00000000000..ff6a6ff0343 --- /dev/null +++ b/drivers/fuel_gauge/bq27z746/CMakeLists.txt @@ -0,0 +1,6 @@ +zephyr_library() + +zephyr_library_sources(bq27z746.c) + +zephyr_include_directories_ifdef(CONFIG_EMUL_BQ27Z746 .) +zephyr_library_sources_ifdef(CONFIG_EMUL_BQ27Z746 ./emul_bq27z746.c) diff --git a/drivers/fuel_gauge/bq27z746/Kconfig b/drivers/fuel_gauge/bq27z746/Kconfig new file mode 100644 index 00000000000..26f3d2612d8 --- /dev/null +++ b/drivers/fuel_gauge/bq27z746/Kconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2023, ithinx GmbH +# Copyright (c) 2023, Tonies GmbH +# +# SPDX-License-Identifier: Apache-2.0 + +config BQ27Z746 + bool "BQ27Z746 Fuel Gauge" + default y + depends on DT_HAS_TI_BQ27Z746_ENABLED + select I2C + help + Enable I2C-based driver for BQ27Z746 Fuel Gauge. + +config EMUL_BQ27Z746 + bool "Emulate an BQ27Z746 fuel gague" + default y + depends on EMUL + depends on BQ27Z746 + help + It provides readings which follow a simple sequence, thus allowing + test code to check that things are working as expected. diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c new file mode 100644 index 00000000000..802de27bad9 --- /dev/null +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2023, ithinx GmbH + * Copyright (c) 2023, Tonies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_bq27z746 + +#include "bq27z746.h" + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(BQ27Z746); + +#define BQ27Z746_MAC_DATA_LEN 32 +#define BQ27Z746_MAC_OVERHEAD_LEN 4 /* 2 cmd bytes, 1 length byte, 1 checksum byte */ +#define BQ27Z746_MAC_COMPLETE_LEN (BQ27Z746_MAC_DATA_LEN + BQ27Z746_MAC_OVERHEAD_LEN) + +static int bq27z746_read16(const struct device *dev, uint8_t reg, uint16_t *value) +{ + uint8_t i2c_data[2]; + const struct bq27z746_config *cfg = dev->config; + const int status = i2c_burst_read_dt(&cfg->i2c, reg, i2c_data, sizeof(i2c_data)); + + if (status < 0) { + LOG_ERR("Unable to read register"); + return status; + } + *value = sys_get_le16(i2c_data); + + return 0; +} + +static int bq27z746_write16(const struct device *dev, uint8_t reg, uint16_t value) +{ + uint8_t buf[3]; + const struct bq27z746_config *cfg = dev->config; + + buf[0] = reg; + sys_put_le16(value, &buf[1]); + + return i2c_write_dt(&cfg->i2c, buf, sizeof(buf)); +} + +static int bq27z746_read_mac(const struct device *dev, uint16_t cmd, uint8_t *data, int len) +{ + if (len > BQ27Z746_MAC_DATA_LEN) { + return -EINVAL; + } + + uint8_t buf[BQ27Z746_MAC_COMPLETE_LEN]; + const struct bq27z746_config *cfg = dev->config; + + /* Instead of MAC, ALTMAC is used as reccommended in the datasheet */ + int ret = bq27z746_write16(dev, BQ27Z746_ALTMANUFACTURERACCESS, cmd); + + if (ret != 0) { + return ret; + } + + /* + * The data read from BQ27Z746_ALTMANUFACTURERACCESS is: + * 0..1: The command (for verification) + * 2..33: The data + * 34: Checksum calculated as (uint8_t)(0xFF - (sum of all command and data bytes)) + * 35: Length including command, checksum and length (e.g. data length + 4) + */ + + ret = i2c_burst_read_dt(&cfg->i2c, BQ27Z746_ALTMANUFACTURERACCESS, buf, + BQ27Z746_MAC_COMPLETE_LEN); + if (ret != 0) { + return ret; + } + + /* The first two bytes read is the command and is used for verification */ + const uint16_t read_cmd = sys_get_le16(buf); + + if (read_cmd != cmd) { + LOG_ERR("Read command 0x%x != written command 0x%x", read_cmd, cmd); + return -EIO; + } + + const uint8_t checksum_actual = buf[34]; + uint8_t sum = 0; /* Intentionally 8 bit wide and overflowing */ + + for (int i = 0; i < BQ27Z746_MAC_COMPLETE_LEN - 2; i++) { + sum += buf[i]; + } + + const uint8_t checksum_expected = 0xFF - sum; + + if (checksum_expected != checksum_actual) { + LOG_ERR("Checksum mismatch"); + return -EIO; + } + + /* First byte of the user buffer is the length */ + data[0] = buf[35] - BQ27Z746_MAC_OVERHEAD_LEN; + + /* Copy only the data to the user buffer (= skipping the first two command bytes) */ + memcpy(&data[1], &buf[2], len); + + return ret; +} + +static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_get_property *prop) +{ + int rc = 0; + uint16_t val = 0; + + /* + * Possibly negative values must be cast from uint16 to int16 first to + * then correctly end up in the wider datatypes of `prop`. + */ + + switch (prop->property_type) { + case FUEL_GAUGE_AVG_CURRENT: + rc = bq27z746_read16(dev, BQ27Z746_AVERAGECURRENT, &val); + prop->value.avg_current = (int16_t)val * 1000; + break; + case FUEL_GAUGE_CYCLE_COUNT: + rc = bq27z746_read16(dev, BQ27Z746_CYCLECOUNT, &val); + prop->value.cycle_count = val * 100; + break; + case FUEL_GAUGE_CURRENT: + rc = bq27z746_read16(dev, BQ27Z746_CURRENT, &val); + prop->value.current = (int16_t)val * 1000; + break; + case FUEL_GAUGE_FULL_CHARGE_CAPACITY: + rc = bq27z746_read16(dev, BQ27Z746_FULLCHARGECAPACITY, &val); + prop->value.full_charge_capacity = val * 1000; + break; + case FUEL_GAUGE_REMAINING_CAPACITY: + rc = bq27z746_read16(dev, BQ27Z746_REMAININGCAPACITY, &val); + prop->value.remaining_capacity = val * 1000; + break; + case FUEL_GAUGE_RUNTIME_TO_EMPTY: + rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOEMPTY, &val); + prop->value.runtime_to_empty = val; + break; + case FUEL_GAUGE_RUNTIME_TO_FULL: + rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOFULL, &val); + prop->value.runtime_to_full = val; + break; + case FUEL_GAUGE_SBS_MFR_ACCESS: + rc = bq27z746_read16(dev, BQ27Z746_MANUFACTURERACCESS, &val); + prop->value.sbs_mfr_access_word = val; + break; + case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: + rc = bq27z746_read16(dev, BQ27Z746_RELATIVESTATEOFCHARGE, &val); + prop->value.relative_state_of_charge = val; + break; + case FUEL_GAUGE_TEMPERATURE: + rc = bq27z746_read16(dev, BQ27Z746_TEMPERATURE, &val); + prop->value.temperature = val; + break; + case FUEL_GAUGE_VOLTAGE: + rc = bq27z746_read16(dev, BQ27Z746_VOLTAGE, &val); + prop->value.voltage = val * 1000; + break; + case FUEL_GAUGE_SBS_ATRATE: + rc = bq27z746_read16(dev, BQ27Z746_ATRATE, &val); + prop->value.sbs_at_rate = (int16_t)val; + break; + case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY: + rc = bq27z746_read16(dev, BQ27Z746_ATRATETIMETOEMPTY, &val); + prop->value.sbs_at_rate_time_to_empty = val; + break; + case FUEL_GAUGE_CHARGE_VOLTAGE: + rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &val); + prop->value.chg_voltage = val; + break; + case FUEL_GAUGE_CHARGE_CURRENT: + rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &val); + prop->value.chg_current = val; + break; + case FUEL_GAUGE_STATUS: + rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &val); + prop->value.fg_status = val; + break; + case FUEL_GAUGE_DESIGN_CAPACITY: + rc = bq27z746_read16(dev, BQ27Z746_DESIGNCAPACITY, &val); + prop->value.design_cap = val; + break; + default: + rc = -ENOTSUP; + } + + prop->status = rc; + + return rc; +} + +static int bq27z746_get_buffer_prop(const struct device *dev, + struct fuel_gauge_get_buffer_property *prop, void *dst, + size_t dst_len) +{ + int rc = 0; + + switch (prop->property_type) { + case FUEL_GAUGE_MANUFACTURER_NAME: + if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) { + rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_MANUFACTURER_NAME, + (uint8_t *)dst, dst_len - 1); + } else { + rc = -EINVAL; + } + break; + case FUEL_GAUGE_DEVICE_NAME: + if (dst_len == sizeof(struct sbs_gauge_device_name)) { + rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_DEVICE_NAME, (uint8_t *)dst, + dst_len - 1); + } else { + rc = -EINVAL; + } + break; + case FUEL_GAUGE_DEVICE_CHEMISTRY: + if (dst_len == sizeof(struct sbs_gauge_device_chemistry)) { + rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_DEVICE_CHEM, (uint8_t *)dst, + dst_len - 1); + } else { + rc = -EINVAL; + } + break; + default: + rc = -ENOTSUP; + } + + prop->status = rc; + return rc; +} + +static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_set_property *prop) +{ + int rc = 0; + uint16_t val = 0; + + switch (prop->property_type) { + case FUEL_GAUGE_SBS_MFR_ACCESS: + rc = bq27z746_write16(dev, BQ27Z746_MANUFACTURERACCESS, + prop->value.sbs_mfr_access_word); + prop->value.sbs_mfr_access_word = val; + break; + case FUEL_GAUGE_SBS_ATRATE: + rc = bq27z746_write16(dev, BQ27Z746_ATRATE, prop->value.sbs_at_rate); + prop->value.sbs_at_rate = val; + break; + default: + rc = -ENOTSUP; + } + + prop->status = rc; + + return rc; +} + +static int bq27z746_get_props(const struct device *dev, struct fuel_gauge_get_property *props, + size_t len) +{ + int err_count = 0; + + for (int i = 0; i < len; i++) { + int ret = bq27z746_get_prop(dev, props + i); + + err_count += ret ? 1 : 0; + } + + err_count = (err_count == len) ? -1 : err_count; + + return err_count; +} + +static int bq27z746_set_props(const struct device *dev, struct fuel_gauge_set_property *props, + size_t len) +{ + int err_count = 0; + + for (int i = 0; i < len; i++) { + int ret = bq27z746_set_prop(dev, props + i); + + err_count += ret ? 1 : 0; + } + + err_count = (err_count == len) ? -1 : err_count; + + return err_count; +} + +static int bq27z746_init(const struct device *dev) +{ + const struct bq27z746_config *cfg; + + cfg = dev->config; + + if (!device_is_ready(cfg->i2c.bus)) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + return 0; +} + +static const struct fuel_gauge_driver_api bq27z746_driver_api = { + .get_property = &bq27z746_get_props, + .set_property = &bq27z746_set_props, + .get_buffer_property = &bq27z746_get_buffer_prop, +}; + +#define BQ27Z746_INIT(index) \ + \ + static const struct bq27z746_config bq27z746_config_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, &bq27z746_init, NULL, NULL, &bq27z746_config_##index, \ + POST_KERNEL, CONFIG_FUEL_GAUGE_INIT_PRIORITY, &bq27z746_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BQ27Z746_INIT) diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.h b/drivers/fuel_gauge/bq27z746/bq27z746.h new file mode 100644 index 00000000000..6d9f821b90d --- /dev/null +++ b/drivers/fuel_gauge/bq27z746/bq27z746.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2023, ithinx GmbH + * Copyright (c) 2023, Tonies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_FUELGAUGE_BQ27Z746_GAUGE_H_ +#define ZEPHYR_DRIVERS_FUELGAUGE_BQ27Z746_GAUGE_H_ + +#include + +/* Registers */ +#define BQ27Z746_MANUFACTURERACCESS 0x00 /* R/W */ +#define BQ27Z746_ATRATE 0x02 /* R/W, Unit: mA, Range: -32768..32767 */ +#define BQ27Z746_ATRATETIMETOEMPTY 0x04 /* R/O, Unit: minutes, Range: 0..65535 */ +#define BQ27Z746_TEMPERATURE 0x06 /* R/O, Unit: 0.1 K, Range: 0..32767 */ +#define BQ27Z746_VOLTAGE 0x08 /* R/O, Unit: mV, Range: 0..32767 */ +#define BQ27Z746_BATTERYSTATUS 0x0A /* R/O, Unit: status bits */ +#define BQ27Z746_CURRENT 0x0C /* R/O, Unit: mA, Range: -32768..32767 */ +#define BQ27Z746_REMAININGCAPACITY 0x10 /* R/O, Unit: mAh, Range: 0..32767 */ +#define BQ27Z746_FULLCHARGECAPACITY 0x12 /* R/O, Unit: mAh, Range: 0..32767 */ +#define BQ27Z746_AVERAGECURRENT 0x14 /* R/O, Unit: mA, Range: -32768..32767 */ +#define BQ27Z746_AVERAGETIMETOEMPTY 0x16 /* R/O, Unit: minutes, Range: 0..65535 */ +#define BQ27Z746_AVERAGETIMETOFULL 0x18 /* R/O, Unit: minutes, Range: 0..65535 */ +#define BQ27Z746_MAXLOADCURRENT 0x1E /* R/O, Unit: mA, Range: 0..65535 */ +#define BQ27Z746_MAXLOADTIMETOEMPTY 0x20 /* R/O, Unit: minutes, Range: 0..65535 */ +#define BQ27Z746_AVERAGEPOWER 0x22 /* R/O, Unit: mW, Range: -32768..32767 */ +#define BQ27Z746_BTPDISCHARGESET 0x24 /* Datasheet unclear */ +#define BQ27Z746_BTPCHARGESET 0x26 /* Datasheet unclear */ +#define BQ27Z746_INTERNALTEMPERATURE 0x28 /* R/O, Unit: 0.1 K, Range: 0..32767 */ +#define BQ27Z746_CYCLECOUNT 0x2A /* R/O, Unit: none, Range: 0..65535 */ +#define BQ27Z746_RELATIVESTATEOFCHARGE 0x2C /* R/O, Unit: percent, Range: 0..100 */ +#define BQ27Z746_STATEOFHEALTH 0x2E /* R/O, Unit: percent, Range: 0..100 */ +#define BQ27Z746_CHARGINGVOLTAGE 0x30 /* R/O, Unit: mV, Range: 0..32767 */ +#define BQ27Z746_CHARGINGCURRENT 0x32 /* R/O, Unit: mA, Range: 0..32767 */ +#define BQ27Z746_TERMINATEVOLTAGE 0x34 /* R/W, Unit: mC, Range: 0..32767 */ +#define BQ27Z746_TIMESTAMPUPPER 0x36 /* R/O, Unit: seconds, Range: 0..65535 */ +#define BQ27Z746_TIMESTAMPLOWER 0x38 /* R/O, Unit: seconds, Range: 0..65535 */ +#define BQ27Z746_QMAXCYCLES 0x3A /* R/O, Unit: none, Range: 0..65535 */ +#define BQ27Z746_DESIGNCAPACITY \ + 0x3C /* R/O (sealed), R/W (unsealed or factory access), Unit: mAh, Range: 0..32767 */ +#define BQ27Z746_ALTMANUFACTURERACCESS 0x3E /* R/W */ +#define BQ27Z746_MACDATA 0x40 /* R/O, MAC data */ +#define BQ27Z746_MACDATASUM 0x60 /* R/O, Checksum over MAC command and data */ +#define BQ27Z746_MACDATALEN 0x61 /* R/O, Length of the MAC data */ +#define BQ27Z746_VOLTHISETTHRESHOLD 0x62 /* R/W, Unit: mV, Range: 0..5000 */ +#define BQ27Z746_VOLTHICLEARTHRESHOLD 0x64 /* R/W, Unit: mV, Range: 0..5000 */ +#define BQ27Z746_VOLTLOSETTHRESHOLD 0x66 /* R/W, Unit: mV, Range: 0..5000 */ +#define BQ27Z746_VOLTLOCLEARTHRESHOLD 0x68 /* R/W, Unit: mV, Range: 0..5000 */ +#define BQ27Z746_TEMPHISETTHRESHOLD 0x6A /* R/W, Unit: degree celsius, Range: -128..127 */ +#define BQ27Z746_TEMPHICLEARTHRESHOLD 0x6B /* R/W, Unit: degree celsius, Range: -128..127 */ +#define BQ27Z746_TEMPLOSETTHRESHOLD 0x6C /* R/W, Unit: degree celsius, Range: -128..127 */ +#define BQ27Z746_TEMPLOCLEARTHRESHOLD 0x6D /* R/W, Unit: degree celsius, Range: -128..127 */ +#define BQ27Z746_INTERRUPTSTATUS 0x6E /* R/O, Unit: status bits */ +#define BQ27Z746_SOCDELTASETTHRESHOLD 0x6F /* R/W, Unit: percent, Range: 0..100 */ + +/* MAC commands */ +#define BQ27Z746_MAC_CMD_DEVICETYPE 0x0001 +#define BQ27Z746_MAC_CMD_FIRMWAREVERSION 0x0002 +#define BQ27Z746_MAC_CMD_HARDWAREVERSION 0x0003 +#define BQ27Z746_MAC_CMD_IFCHECKSUM 0x0004 +#define BQ27Z746_MAC_CMD_STATICDFSIGNATURE 0x0005 +#define BQ27Z746_MAC_CMD_CHEMID 0x0006 +#define BQ27Z746_MAC_CMD_PREV_MACWRITE 0x0007 +#define BQ27Z746_MAC_CMD_STATICCHEMDFSIGNATURE 0x0008 +#define BQ27Z746_MAC_CMD_ALLDFSIGNATURE 0x0009 +#define BQ27Z746_MAC_CMD_SHELFENABLE 0x000B +#define BQ27Z746_MAC_CMD_SHELFDISABLE 0x000C +#define BQ27Z746_MAC_CMD_SHUTDOWNMODE 0x0010 +#define BQ27Z746_MAC_CMD_RESET1 0x0012 +#define BQ27Z746_MAC_CMD_SHIPMODEENABLE 0x0015 +#define BQ27Z746_MAC_CMD_SHIPMODEDISABLE 0x0016 +#define BQ27Z746_MAC_CMD_QMAX_DAY 0x0017 +#define BQ27Z746_MAC_CMD_CHARGEFETTOGGLE 0x001F +#define BQ27Z746_MAC_CMD_DISCHARGEFETTOGGLE 0x0020 +#define BQ27Z746_MAC_CMD_GAUGING_IT_ENABLE 0x0021 +#define BQ27Z746_MAC_CMD_FET_ENABLE 0x0022 +#define BQ27Z746_MAC_CMD_LIFETIMEDATACOLLECTION 0x0023 +#define BQ27Z746_MAC_CMD_LIFETIMEDATARESET 0x0028 +#define BQ27Z746_MAC_CMD_CALIBRATIONMODE 0x002D +#define BQ27Z746_MAC_CMD_LIFETIMEDATAFLUSH 0x002E +#define BQ27Z746_MAC_CMD_LIFETIMEDATASPEEDUPMODE 0x002F +#define BQ27Z746_MAC_CMD_SEALDEVICE 0x0030 +#define BQ27Z746_MAC_CMD_SECURITYKEYS 0x0035 +#define BQ27Z746_MAC_CMD_RESET2 0x0041 +#define BQ27Z746_MAC_CMD_TAMBIENTSYNC 0x0047 +#define BQ27Z746_MAC_CMD_DEVICE_NAME 0x004A +#define BQ27Z746_MAC_CMD_DEVICE_CHEM 0x004B +#define BQ27Z746_MAC_CMD_MANUFACTURER_NAME 0x004C +#define BQ27Z746_MAC_CMD_MANUFACTURE_DATE 0x004D +#define BQ27Z746_MAC_CMD_SERIAL_NUMBER 0x004E +#define BQ27Z746_MAC_CMD_SAFETYALERT 0x0050 +#define BQ27Z746_MAC_CMD_SAFETYSTATUS 0x0051 +#define BQ27Z746_MAC_CMD_OPERATIONSTATUS 0x0054 +#define BQ27Z746_MAC_CMD_CHARGINGSTATUS 0x0055 +#define BQ27Z746_MAC_CMD_GAUGINGSTATUS 0x0056 +#define BQ27Z746_MAC_CMD_MANUFACTURINGSTATUS 0x0057 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK1 0x0060 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK2 0x0061 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK3 0x0062 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK4 0x0063 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK6 0x0065 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK7 0x0065 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK8 0x0067 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK9 0x0068 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK10 0x0069 +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK11 0x006A +#define BQ27Z746_MAC_CMD_LIFETIMEDATABLOCK12 0x006B +#define BQ27Z746_MAC_CMD_MANUFACTURERINFO 0x0070 +#define BQ27Z746_MAC_CMD_DASTATUS1 0x0071 +#define BQ27Z746_MAC_CMD_DASTATUS2 0x0072 +#define BQ27Z746_MAC_CMD_ITSTATUS1 0x0073 +#define BQ27Z746_MAC_CMD_ITSTATUS2 0x0074 +#define BQ27Z746_MAC_CMD_ITSTATUS3 0x0075 +#define BQ27Z746_MAC_CMD_FCC_SOH 0x0077 +#define BQ27Z746_MAC_CMD_FILTERED_CAPACITY 0x0078 +#define BQ27Z746_MAC_CMD_MANUFACTURERINFOB 0x007A +#define BQ27Z746_MAC_CMD_MANUFACTURERINFOC 0x007B +#define BQ27Z746_MAC_CMD_FET_CONTROL_OVERRIDE 0x0097 +#define BQ27Z746_MAC_CMD_SYSTEM_RESET_ENABLE 0x00A3 +#define BQ27Z746_MAC_CMD_SYSTEM_RESET 0x00A4 +#define BQ27Z746_MAC_CMD_BATTSENSEOUTPUT 0x00B1 +#define BQ27Z746_MAC_CMD_RATABLECELL0 0x00E0 +#define BQ27Z746_MAC_CMD_ROMMODE 0x0F00 +#define BQ27Z746_MAC_CMD_DATAFLASHACCESS 0x4000 +#define BQ27Z746_MAC_CMD_SWITCHTOHDQ 0x7C40 +#define BQ27Z746_MAC_CMD_EXITCALIBRATIONOUTPUT 0xF080 +#define BQ27Z746_MAC_CMD_OUTPUTCCANDADCFORCALIBRATIO 0xF081 +#define BQ27Z746_MAC_CMD_OUTPUTTEMPERATURECAL 0xF083 +#define BQ27Z746_MAC_CMD_PROTECTORCALIBRATION 0xF0A0 +#define BQ27Z746_MAC_CMD_PROTECTORIMAGE1 0xF0A1 +#define BQ27Z746_MAC_CMD_PROTECTORIMAGE2 0xF0A2 +#define BQ27Z746_MAC_CMD_PROTECTORIMAGESAVE 0xF0A3 +#define BQ27Z746_MAC_CMD_PROTECTORIMAGELOCK 0xF0A4 +#define BQ27Z746_MAC_CMD_PROTECTORFACTORYCONFIG 0xF0A5 + +struct bq27z746_config { + struct i2c_dt_spec i2c; +}; + +#endif diff --git a/drivers/fuel_gauge/bq27z746/emul_bq27z746.c b/drivers/fuel_gauge/bq27z746/emul_bq27z746.c new file mode 100644 index 00000000000..fe4256cdea5 --- /dev/null +++ b/drivers/fuel_gauge/bq27z746/emul_bq27z746.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2023, ithinx GmbH + * Copyright (c) 2023, Tonies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + * + * Emulator for bq27z746 fuel gauge + */ + +#include +#define DT_DRV_COMPAT ti_bq27z746 + +#include +LOG_MODULE_REGISTER(EMUL_BQ27Z746); + +#include +#include +#include +#include +#include + +#include "bq27z746.h" + +#define BQ27Z746_MAC_DATA_LEN 32 +#define BQ27Z746_MAC_OVERHEAD_LEN 4 /* 2 cmd bytes, 1 length byte, 1 checksum byte */ +#define BQ27Z746_MAC_COMPLETE_LEN (BQ27Z746_MAC_DATA_LEN + BQ27Z746_MAC_OVERHEAD_LEN) + +struct bq27z746_emul_data { + uint16_t mac_cmd; +}; + +/** Static configuration for the emulator */ +struct bq27z746_emul_cfg { + /** I2C address of emulator */ + uint16_t addr; +}; + +static int emul_bq27z746_read_altmac(const struct emul *target, uint8_t *buf, size_t len) +{ + const uint8_t manufacturer_name[] = "Texas Instruments"; + const uint8_t device_name[] = "BQ27Z746"; + const uint8_t device_chemistry[] = "LION"; + const struct bq27z746_emul_data *data = target->data; + + if (len < BQ27Z746_MAC_COMPLETE_LEN) { + LOG_ERR("When reading the ALTMAC, one must read the full %u byte", + BQ27Z746_MAC_COMPLETE_LEN); + return -EIO; + } + + memset(buf, 0, len); + + /* + * The data read from BQ27Z746_ALTMANUFACTURERACCESS is: + * 0..1: The command (for verification) + * 2..33: The data + * 34: Checksum calculated as (uint8_t)(0xFF - (sum of all command and data bytes)) + * 35: Length including command, checksum and length (e.g. data length + 4) + */ + + /* Put the command in the first two byte */ + sys_put_le16(data->mac_cmd, buf); + + /* Based on the command, put some data and the length into the buffer. */ + /* In all of the operations, don't consider the zero-terminator. */ + switch (data->mac_cmd) { + case BQ27Z746_MAC_CMD_MANUFACTURER_NAME: + memcpy(&buf[2], manufacturer_name, sizeof(manufacturer_name) - 1); + buf[35] = sizeof(manufacturer_name) - 1 + BQ27Z746_MAC_OVERHEAD_LEN; + break; + case BQ27Z746_MAC_CMD_DEVICE_NAME: + memcpy(&buf[2], device_name, sizeof(device_name) - 1); + buf[35] = sizeof(device_name) - 1 + BQ27Z746_MAC_OVERHEAD_LEN; + break; + case BQ27Z746_MAC_CMD_DEVICE_CHEM: + memcpy(&buf[2], device_chemistry, sizeof(device_chemistry) - 1); + buf[35] = sizeof(device_chemistry) - 1 + BQ27Z746_MAC_OVERHEAD_LEN; + break; + default: + LOG_ERR("ALTMAC command 0x%x is not supported", data->mac_cmd); + return -EIO; + } + + /* Calculate the checksum */ + uint8_t sum = 0; /* Intentionally 8 bit wide and overflowing */ + + for (int i = 0; i < BQ27Z746_MAC_COMPLETE_LEN - 2; i++) { + sum += buf[i]; + } + buf[34] = 0xFF - sum; + + return 0; +} + +static int emul_bq27z746_write(const struct emul *target, uint8_t *buf, size_t len) +{ + struct bq27z746_emul_data *data = target->data; + const uint8_t reg = buf[0]; + + switch (reg) { + case BQ27Z746_ALTMANUFACTURERACCESS: + data->mac_cmd = sys_get_le16(&buf[1]); + return 0; + default: + LOG_ERR("Writing is only supported to ALTMAC currently"); + return -EIO; + } +} + +static int emul_bq27z746_reg_read(const struct emul *target, int reg, int *val) +{ + switch (reg) { + case BQ27Z746_MANUFACTURERACCESS: + *val = 1; + break; + case BQ27Z746_ATRATE: + *val = -2; + break; + case BQ27Z746_ATRATETIMETOEMPTY: + *val = 1; + break; + case BQ27Z746_TEMPERATURE: + *val = 1; + break; + case BQ27Z746_VOLTAGE: + *val = 1; + break; + case BQ27Z746_BATTERYSTATUS: + *val = 1; + break; + case BQ27Z746_CURRENT: + *val = -2; + break; + case BQ27Z746_REMAININGCAPACITY: + *val = 1; + break; + case BQ27Z746_FULLCHARGECAPACITY: + *val = 1; + break; + case BQ27Z746_AVERAGECURRENT: + *val = -2; + break; + case BQ27Z746_AVERAGETIMETOEMPTY: + *val = 1; + break; + case BQ27Z746_AVERAGETIMETOFULL: + *val = 1; + break; + case BQ27Z746_MAXLOADCURRENT: + *val = 1; + break; + case BQ27Z746_MAXLOADTIMETOEMPTY: + *val = 1; + break; + case BQ27Z746_AVERAGEPOWER: + *val = 1; + break; + case BQ27Z746_BTPDISCHARGESET: + *val = 1; + break; + case BQ27Z746_BTPCHARGESET: + *val = 1; + break; + case BQ27Z746_INTERNALTEMPERATURE: + *val = 1; + break; + case BQ27Z746_CYCLECOUNT: + *val = 1; + break; + case BQ27Z746_RELATIVESTATEOFCHARGE: + *val = 1; + break; + case BQ27Z746_STATEOFHEALTH: + *val = 1; + break; + case BQ27Z746_CHARGINGVOLTAGE: + *val = 1; + break; + case BQ27Z746_CHARGINGCURRENT: + *val = 1; + break; + case BQ27Z746_TERMINATEVOLTAGE: + *val = 1; + break; + case BQ27Z746_TIMESTAMPUPPER: + *val = 1; + break; + case BQ27Z746_TIMESTAMPLOWER: + *val = 1; + break; + case BQ27Z746_QMAXCYCLES: + *val = 1; + break; + case BQ27Z746_DESIGNCAPACITY: + *val = 1; + break; + case BQ27Z746_ALTMANUFACTURERACCESS: + *val = 1; + break; + case BQ27Z746_MACDATA: + *val = 1; + break; + case BQ27Z746_MACDATASUM: + *val = 1; + break; + case BQ27Z746_MACDATALEN: + *val = 1; + break; + case BQ27Z746_VOLTHISETTHRESHOLD: + *val = 1; + break; + case BQ27Z746_VOLTHICLEARTHRESHOLD: + *val = 1; + break; + case BQ27Z746_VOLTLOSETTHRESHOLD: + *val = 1; + break; + case BQ27Z746_VOLTLOCLEARTHRESHOLD: + *val = 1; + break; + case BQ27Z746_TEMPHISETTHRESHOLD: + *val = 1; + break; + case BQ27Z746_TEMPHICLEARTHRESHOLD: + *val = 1; + break; + case BQ27Z746_TEMPLOSETTHRESHOLD: + *val = 1; + break; + case BQ27Z746_TEMPLOCLEARTHRESHOLD: + *val = 1; + break; + case BQ27Z746_INTERRUPTSTATUS: + *val = 1; + break; + case BQ27Z746_SOCDELTASETTHRESHOLD: + *val = 1; + break; + default: + LOG_ERR("Unknown register 0x%x read", reg); + return -EIO; + } + LOG_INF("read 0x%x = 0x%x", reg, *val); + + return 0; +} + +static int emul_bq27z746_read(const struct emul *target, int reg, uint8_t *buf, size_t len) +{ + if (len == 2) { + unsigned int val; + int rc = emul_bq27z746_reg_read(target, reg, &val); + + if (rc) { + return rc; + } + + sys_put_le16(val, buf); + } else { + switch (reg) { + case BQ27Z746_ALTMANUFACTURERACCESS: + LOG_DBG("Reading %u byte from ALTMAC", len); + emul_bq27z746_read_altmac(target, buf, len); + break; + default: + LOG_ERR("Reading is only supported from ALTMAC currently"); + return -EIO; + } + } + + return 0; +} + +static int bq27z746_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, int num_msgs, + int addr) +{ + int reg; + int rc; + + __ASSERT_NO_MSG(msgs && num_msgs); + + i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + switch (num_msgs) { + case 1: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + + return emul_bq27z746_write(target, msgs->buf, msgs->len); + case 2: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len != 1) { + LOG_ERR("Unexpected msg0 length %d", msgs->len); + return -EIO; + } + reg = msgs->buf[0]; + + /* Now process the 'read' part of the message */ + msgs++; + if (msgs->flags & I2C_MSG_READ) { + rc = emul_bq27z746_read(target, reg, msgs->buf, msgs->len); + if (rc) { + return rc; + } + } else { + LOG_ERR("Second message must be an I2C write"); + return -EIO; + } + return rc; + default: + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + + return 0; +} + +static const struct i2c_emul_api bq27z746_emul_api_i2c = { + .transfer = bq27z746_emul_transfer_i2c, +}; + +/** + * Set up a new emulator (I2C) + * + * @param emul Emulation information + * @param parent Device to emulate + * @return 0 indicating success (always) + */ +static int emul_bq27z746_init(const struct emul *target, const struct device *parent) +{ + ARG_UNUSED(target); + ARG_UNUSED(parent); + + return 0; +} + +/* + * Main instantiation macro. + */ +#define BQ27Z746_EMUL(n) \ + static struct bq27z746_emul_data bq27z746_emul_data_##n; \ + static const struct bq27z746_emul_cfg bq27z746_emul_cfg_##n = { \ + .addr = DT_INST_REG_ADDR(n), \ + }; \ + EMUL_DT_INST_DEFINE(n, emul_bq27z746_init, &bq27z746_emul_data_##n, \ + &bq27z746_emul_cfg_##n, &bq27z746_emul_api_i2c, NULL) + +DT_INST_FOREACH_STATUS_OKAY(BQ27Z746_EMUL) diff --git a/dts/bindings/fuel-gauge/ti,bq27z746.yaml b/dts/bindings/fuel-gauge/ti,bq27z746.yaml new file mode 100644 index 00000000000..3de382ca7c3 --- /dev/null +++ b/dts/bindings/fuel-gauge/ti,bq27z746.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023, ithinx GmbH +# Copyright (c) 2023, Tonies GmbH +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Texas Instruments BQ27Z746 fuel gauge. For more info visit + https://www.ti.com/product/BQ27Z746 + + +compatible: "ti,bq27z746" + +include: [i2c-device.yaml, fuel-gauge.yaml] diff --git a/tests/drivers/fuel_gauge/bq27z746/CMakeLists.txt b/tests/drivers/fuel_gauge/bq27z746/CMakeLists.txt new file mode 100644 index 00000000000..24070133dbd --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +FILE(GLOB app_sources src/test_bq27z746.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf b/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf new file mode 100644 index 00000000000..022a71dd0f0 --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y diff --git a/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay b/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay new file mode 100644 index 00000000000..2dc85db341a --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +&i2c0 { + bq27z746: bq27z746@55 { + compatible = "ti,bq27z746"; + reg = <0x55>; + status = "okay"; + }; +}; diff --git a/tests/drivers/fuel_gauge/bq27z746/prj.conf b/tests/drivers/fuel_gauge/bq27z746/prj.conf new file mode 100644 index 00000000000..23ceb0b3cdd --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_I2C=y +CONFIG_TEST_USERSPACE=y +CONFIG_LOG=y + +CONFIG_FUEL_GAUGE=y diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c new file mode 100644 index 00000000000..88d8b59c9f4 --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2023, ithinx GmbH + * Copyright (c) 2023, Tonies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct bq27z746_fixture { + const struct device *dev; + const struct fuel_gauge_driver_api *api; +}; + +static void *bq27z746_setup(void) +{ + static ZTEST_DMEM struct bq27z746_fixture fixture; + + fixture.dev = DEVICE_DT_GET_ANY(ti_bq27z746); + k_object_access_all_grant(fixture.dev); + + zassert_true(device_is_ready(fixture.dev), "Fuel Gauge not found"); + + return &fixture; +} + +ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) +{ + struct fuel_gauge_get_property props[] = { + { + /* Invalid property */ + .property_type = FUEL_GAUGE_PROP_MAX, + }, + }; + + int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", + props[0].property_type); + + zassert_true(ret < 0); +} + +ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) +{ + struct fuel_gauge_get_property props[] = { + { + /* First invalid property */ + .property_type = FUEL_GAUGE_PROP_MAX, + }, + { + /* Second invalid property */ + .property_type = FUEL_GAUGE_PROP_MAX, + }, + { + /* Valid property */ + .property_type = FUEL_GAUGE_VOLTAGE, + }, + + }; + + int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", + props[0].property_type); + + zassert_equal(props[1].status, -ENOTSUP, "Getting bad property %d has a good status.", + props[1].property_type); + + zassert_ok(props[2].status, "Property %d getting %d has a bad status.", 2, + props[2].property_type); + + zassert_equal(ret, 2); +} + +ZTEST_USER_F(bq27z746, test_get_buffer_prop) +{ + struct fuel_gauge_get_buffer_property prop; + int ret; + + { + struct sbs_gauge_manufacturer_name mfg_name; + + prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; + ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name)); + zassert_ok(ret); + zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); +#if CONFIG_EMUL + /* Only test for fixed values in emulation since the real device might be */ + /* reprogrammed and respond with different values */ + zassert_equal(sizeof("Texas Instruments") - 1, mfg_name.manufacturer_name_length); + zassert_mem_equal(mfg_name.manufacturer_name, "Texas Instruments", + mfg_name.manufacturer_name_length, + "mfg_name.manufacturer_name='%s'", mfg_name.manufacturer_name); +#endif + } + { + struct sbs_gauge_device_name dev_name; + + prop.property_type = FUEL_GAUGE_DEVICE_NAME; + ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name)); + zassert_ok(ret); + zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); +#if CONFIG_EMUL + /* Only test for fixed values in emulation since the real device might be */ + /* reprogrammed and respond with different values */ + zassert_equal(sizeof("BQ27Z746") - 1, dev_name.device_name_length); + zassert_mem_equal(dev_name.device_name, "BQ27Z746", dev_name.device_name_length); +#endif + } + { + struct sbs_gauge_device_chemistry device_chemistry; + + prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; + ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &device_chemistry, + sizeof(device_chemistry)); + zassert_ok(ret); + zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); +#if CONFIG_EMUL + /* Only test for fixed values in emulation since the real device might be */ + /* reprogrammed and respond with different values */ + zassert_equal(sizeof("LION") - 1, device_chemistry.device_chemistry_length); + zassert_mem_equal(device_chemistry.device_chemistry, "LION", + device_chemistry.device_chemistry_length); +#endif + } +} + +ZTEST_USER_F(bq27z746, test_get_props__returns_ok) +{ + /* Validate what props are supported by the driver */ + + struct fuel_gauge_get_property props[] = { + { + .property_type = FUEL_GAUGE_AVG_CURRENT, + }, + { + .property_type = FUEL_GAUGE_CYCLE_COUNT, + }, + { + .property_type = FUEL_GAUGE_CURRENT, + }, + { + .property_type = FUEL_GAUGE_FULL_CHARGE_CAPACITY, + }, + { + .property_type = FUEL_GAUGE_REMAINING_CAPACITY, + }, + { + .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, + }, + { + .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, + }, + { + .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, + }, + { + .property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, + }, + { + .property_type = FUEL_GAUGE_TEMPERATURE, + }, + { + .property_type = FUEL_GAUGE_VOLTAGE, + }, + { + .property_type = FUEL_GAUGE_SBS_ATRATE, + }, + { + .property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY, + }, + { + .property_type = FUEL_GAUGE_CHARGE_VOLTAGE, + }, + { + .property_type = FUEL_GAUGE_CHARGE_CURRENT, + }, + { + .property_type = FUEL_GAUGE_STATUS, + }, + { + .property_type = FUEL_GAUGE_DESIGN_CAPACITY, + }, + }; + + int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + /* All props shall have a good status */ + for (int i = 0; i < ARRAY_SIZE(props); i++) { + zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, + props[i].property_type); + } + + /* Check properties for valid ranges */ +#if CONFIG_EMUL + /* When emulating, check for the fixed values coming from the emulator */ + zassert_equal(props[0].value.avg_current, -2000); + zassert_equal(props[1].value.cycle_count, 100); + zassert_equal(props[2].value.current, -2000); + zassert_equal(props[3].value.full_charge_capacity, 1000); + zassert_equal(props[4].value.remaining_capacity, 1000); + zassert_equal(props[5].value.runtime_to_empty, 1); + zassert_equal(props[6].value.runtime_to_full, 1); + zassert_equal(props[7].value.sbs_mfr_access_word, 1); + zassert_equal(props[8].value.relative_state_of_charge, 1); + zassert_equal(props[9].value.temperature, 1); + zassert_equal(props[10].value.voltage, 1000); + zassert_equal(props[11].value.sbs_at_rate, -2); + zassert_equal(props[12].value.sbs_at_rate_time_to_empty, 1); + zassert_equal(props[13].value.chg_voltage, 1); + zassert_equal(props[14].value.chg_current, 1); + zassert_equal(props[15].value.fg_status, 1); + zassert_equal(props[16].value.design_cap, 1); +#else + /* When having a real device, check for the valid ranges */ + zassert_between_inclusive(props[0].value.avg_current, -32768 * 1000, 32767 * 1000); + zassert_between_inclusive(props[1].value.cycle_count, 0, 6553500); + zassert_between_inclusive(props[2].value.current, -32768 * 1000, 32767 * 1000); + zassert_between_inclusive(props[3].value.full_charge_capacity, 0, 32767 * 1000); + zassert_between_inclusive(props[4].value.remaining_capacity, 0, 32767 * 1000); + zassert_between_inclusive(props[5].value.runtime_to_empty, 0, 65535); + zassert_between_inclusive(props[6].value.runtime_to_full, 0, 65535); + /* Not testing props[7]. This is the manufacturer access and has only status bits */ + zassert_between_inclusive(props[8].value.relative_state_of_charge, 0, 100); + zassert_between_inclusive(props[9].value.temperature, 0, 32767); + zassert_between_inclusive(props[10].value.voltage, 0, 32767 * 1000); + zassert_between_inclusive(props[11].value.sbs_at_rate, -32768, 32767); + zassert_between_inclusive(props[12].value.sbs_at_rate_time_to_empty, 0, 65535); + zassert_between_inclusive(props[13].value.chg_voltage, 0, 32767); + zassert_between_inclusive(props[14].value.chg_current, 0, 32767); + /* Not testing props[15]. This property is the status and only has only status bits */ + zassert_between_inclusive(props[16].value.design_cap, 0, 32767); +#endif + + zassert_ok(ret); +} + +ZTEST_SUITE(bq27z746, NULL, bq27z746_setup, NULL, NULL, NULL); diff --git a/tests/drivers/fuel_gauge/bq27z746/testcase.yaml b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml new file mode 100644 index 00000000000..6d9096b3a98 --- /dev/null +++ b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml @@ -0,0 +1,5 @@ +tests: + # section.subsection + drivers.bq27z746: + filter: dt_compat_enabled("ti,bq27z746") + platform_allow: native_posix From 1e06ba2328d94847bb6374afdf39715b5bc2865e Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 3 Jul 2023 19:39:10 +1000 Subject: [PATCH 0322/4498] soc: arm: nordic: handle nRF52832 anomaly 109 Enable workaround for anomaly 109 by default when affected peripherals are enabled. Signed-off-by: Jordan Yates --- modules/hal_nordic/nrfx/nrfx_config.h | 7 +++++++ soc/arm/nordic_nrf/nrf52/CMakeLists.txt | 8 ++++++++ soc/arm/nordic_nrf/nrf52/Kconfig.soc | 11 +++++++++++ 3 files changed, 26 insertions(+) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 4b7cabd7a98..a843e96c3ba 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -487,6 +487,13 @@ #define NRFX_WDT1_ENABLED 1 #endif +#ifdef CONFIG_NRF52_ANOMALY_109_WORKAROUND +#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#endif + #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) #include "nrfx_config_bsim.h" #endif diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index 06fddff5f06..24fdcf6093e 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -14,3 +14,11 @@ zephyr_library_include_directories( if(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 AND CONFIG_SPI_NRFX_SPIM) message(WARNING "Both SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 and an NRF SPIM driver are enabled, therefore PAN 58 will apply if RXD.MAXCNT == 1 and TXD.MAXCNT <= 1") endif() + +if(CONFIG_SOC_NRF52832) + if(NOT CONFIG_NRF52_ANOMALY_109_WORKAROUND) + if (CONFIG_NRFX_SPIS OR CONFIG_NRFX_SPIM OR CONFIG_NRFX_TWIM OR CONFIG_NRFX_PWM) + message(WARNING "NRF52_ANOMALY_109_WORKAROUND disabled with SPIS, SPIM, TWIM or PWM enabled. This will occasionally cause the first byte transmitted to be incorrect") + endif() + endif() +endif() diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index 13a2fef932b..f1a337cbe12 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -129,4 +129,15 @@ config NRF52_ANOMALY_198_WORKAROUND This anomaly applies to IC revisions "Engineering B" up to "3", the most recent one. +config NRF52_ANOMALY_109_WORKAROUND + bool "Anomaly 109 workaround" + default y + depends on SOC_NRF52832 + depends on NRFX_SPIS || NRFX_SPIM || NRFX_TWIM || NRFX_PWM + help + Due to Anomaly 109 the first byte sent out by these peripherals is + sometimes wrong. This occurs when the system enters IDLE and stops the + 64MHz clock at the same time as the peripheral that is using DMA is started. + This anomaly applies to IC revisions up to "3", the most recent one. + endif # SOC_SERIES_NRF52X From 17f2046821f4c8fc6da267acbdbb314b659bc6e0 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Mon, 12 Jun 2023 14:30:00 +1000 Subject: [PATCH 0323/4498] drivers: sensor: current_amp: add driver Add current sense amplifier driver. Implements https://github.com/zephyrproject-rtos/zephyr/issues/60415 Co-authored-by: Marco Argiolas Signed-off-by: Nick Ward --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/current_amp/CMakeLists.txt | 5 + drivers/sensor/current_amp/Kconfig | 13 +++ drivers/sensor/current_amp/current_amp.c | 115 ++++++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 drivers/sensor/current_amp/CMakeLists.txt create mode 100644 drivers/sensor/current_amp/Kconfig create mode 100644 drivers/sensor/current_amp/current_amp.c diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 8247e3b7011..e905bb3ef7f 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory_ifdef(CONFIG_BMM150 bmm150) add_subdirectory_ifdef(CONFIG_BMP388 bmp388) add_subdirectory_ifdef(CONFIG_BQ274XX bq274xx) add_subdirectory_ifdef(CONFIG_CCS811 ccs811) +add_subdirectory_ifdef(CONFIG_CURRENT_AMP current_amp) add_subdirectory_ifdef(CONFIG_DHT dht) add_subdirectory_ifdef(CONFIG_DPS310 dps310) add_subdirectory_ifdef(CONFIG_DS18B20 ds18b20) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 2862e5854b8..fb4080c7823 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -83,6 +83,7 @@ source "drivers/sensor/bmm150/Kconfig" source "drivers/sensor/bmp388/Kconfig" source "drivers/sensor/bq274xx/Kconfig" source "drivers/sensor/ccs811/Kconfig" +source "drivers/sensor/current_amp/Kconfig" source "drivers/sensor/dht/Kconfig" source "drivers/sensor/dps310/Kconfig" source "drivers/sensor/ds18b20/Kconfig" diff --git a/drivers/sensor/current_amp/CMakeLists.txt b/drivers/sensor/current_amp/CMakeLists.txt new file mode 100644 index 00000000000..81410bdcc71 --- /dev/null +++ b/drivers/sensor/current_amp/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(current_amp.c) diff --git a/drivers/sensor/current_amp/Kconfig b/drivers/sensor/current_amp/Kconfig new file mode 100644 index 00000000000..62ea9bc0d12 --- /dev/null +++ b/drivers/sensor/current_amp/Kconfig @@ -0,0 +1,13 @@ +# Current sense amplifier driver +# +# Copyright (c) 2023 FTP Technologies +# +# SPDX-License-Identifier: Apache-2.0 + +config CURRENT_AMP + bool "Current sense amplifier driver" + default y + depends on DT_HAS_CURRENT_SENSE_AMPLIFIER_ENABLED + depends on ADC + help + Enable current sense amplifier driver. diff --git a/drivers/sensor/current_amp/current_amp.c b/drivers/sensor/current_amp/current_amp.c new file mode 100644 index 00000000000..947969c4313 --- /dev/null +++ b/drivers/sensor/current_amp/current_amp.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 FTP Technologies + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT current_sense_amplifier + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(current_amp, CONFIG_SENSOR_LOG_LEVEL); + +struct current_sense_amplifier_data { + struct adc_sequence sequence; + int16_t raw; +}; + +static int fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct current_sense_amplifier_dt_spec *config = dev->config; + struct current_sense_amplifier_data *data = dev->data; + int ret; + + if ((chan != SENSOR_CHAN_CURRENT) && (chan != SENSOR_CHAN_ALL)) { + return -ENOTSUP; + } + + ret = adc_read(config->port.dev, &data->sequence); + if (ret != 0) { + LOG_ERR("adc_read: %d", ret); + } + + return ret; +} + +static int get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) +{ + const struct current_sense_amplifier_dt_spec *config = dev->config; + struct current_sense_amplifier_data *data = dev->data; + int32_t raw_val = data->raw; + int32_t i_ma; + int ret; + + __ASSERT_NO_MSG(val != NULL); + + if (chan != SENSOR_CHAN_CURRENT) { + return -ENOTSUP; + } + + ret = adc_raw_to_millivolts_dt(&config->port, &raw_val); + if (ret != 0) { + LOG_ERR("raw_to_mv: %d", ret); + return ret; + } + + i_ma = raw_val; + current_sense_amplifier_scale_dt(config, &i_ma); + + LOG_DBG("%d/%d, %dmV, current:%duA", data->raw, + (1 << data->sequence.resolution) - 1, raw_val, i_ma); + + val->val1 = i_ma / 1000; + val->val2 = i_ma % 1000; + + return 0; +} + +static const struct sensor_driver_api current_api = { + .sample_fetch = fetch, + .channel_get = get, +}; + +static int current_init(const struct device *dev) +{ + const struct current_sense_amplifier_dt_spec *config = dev->config; + struct current_sense_amplifier_data *data = dev->data; + int ret; + + if (!adc_is_ready_dt(&config->port)) { + LOG_ERR("ADC is not ready"); + return -ENODEV; + } + + ret = adc_channel_setup_dt(&config->port); + if (ret != 0) { + LOG_ERR("setup: %d", ret); + return ret; + } + + ret = adc_sequence_init_dt(&config->port, &data->sequence); + if (ret != 0) { + LOG_ERR("sequence init: %d", ret); + return ret; + } + + data->sequence.buffer = &data->raw; + data->sequence.buffer_size = sizeof(data->raw); + + return 0; +} + +#define CURRENT_SENSE_AMPLIFIER_INIT(inst) \ + static struct current_sense_amplifier_data current_amp_##inst##_data; \ + \ + static const struct current_sense_amplifier_dt_spec current_amp_##inst##_config = \ + CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(DT_DRV_INST(inst)); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, ¤t_init, NULL, ¤t_amp_##inst##_data, \ + ¤t_amp_##inst##_config, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, ¤t_api); + +DT_INST_FOREACH_STATUS_OKAY(CURRENT_SENSE_AMPLIFIER_INIT) From 43be17a5fe56effed3951e109dfed37495ad5a89 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Mon, 12 Jun 2023 14:34:08 +1000 Subject: [PATCH 0324/4498] tests: drivers: build all: sensor: add current_amp Add current sense amplifier driver to tests. Signed-off-by: Nick Ward --- tests/drivers/build_all/sensor/adc.dtsi | 10 ++++++++++ tests/drivers/build_all/sensor/app.overlay | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index 52b41ce0f7c..7eb5b2a0d4b 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -14,6 +14,16 @@ test_adc_mcp9700a: mcp9700a { io-channels = <&test_adc 0>; }; +test_current: current_amp { + status = "okay"; + compatible = "current-sense-amplifier"; + io-channels = <&test_adc 2>; + io-channel-names = "CURRENT_AMP"; + sense-resistor-micro-ohms = <10>; + sense-gain-mult = <1>; + sense-gain-div = <1>; +}; + test_adc_emul: adc { compatible = "zephyr,adc-emul"; nchannels = <2>; diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 36bb97915d7..6348c648e3c 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -32,6 +32,15 @@ zephyr,resolution = <12>; }; + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1_6"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = <0>; + zephyr,resolution = <12>; + }; + #include "adc.dtsi" }; From fdd7e78d3c718d5e1ef0e7ceda68bfcbd0552bcd Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 9 Jun 2023 15:07:33 +0000 Subject: [PATCH 0325/4498] boards: arm: mimxrt1060_evk: added additional PWM outputs Added PWM outputs to arduino header, to make testing PWM support with this EVK simpler. These PWM outputs are enabled by the pwm_api test, although they are not used. The user can enable the PWM shell in order to test these PWM outputs. Signed-off-by: Daniel DeGrasse --- .../mimxrt1060_evk-pinctrl.dtsi | 25 ++++++++++++++++++- boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts | 12 ++++++++- .../pwm/pwm_api/boards/mimxrt1060_evk.overlay | 18 +++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/pwm/pwm_api/boards/mimxrt1060_evk.overlay diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi b/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi index 38eb539577b..7d2ff7a43e4 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi @@ -98,7 +98,7 @@ }; /* flexpwm output for board LED */ - pinmux_flexpwm2: pinmux_flexpwm2 { + pinmux_flexpwm2_3: pinmux_flexpwm2_3 { group0 { pinmux = <&iomuxc_gpio_ad_b0_09_flexpwm2_pwma3>; drive-strength = "r0-4"; @@ -109,6 +109,29 @@ }; }; + /* Conflicts with SD and SPI pins. Requires R281/R356 be populated */ + pinmux_flexpwm1_0: pinmux_flexpwm1_0 { + group0 { + pinmux = <&iomuxc_gpio_sd_b0_01_flexpwm1_pwmb0>; + drive-strength = "r0-4"; + bias-pull-up; + bias-pull-up-value = "47k"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + + pinmux_flexpwm1: pinmux_flexpwm1 { + group0 { + pinmux = <&iomuxc_gpio_ad_b0_10_flexpwm1_pwma3>; + drive-strength = "r0-4"; + bias-pull-up; + bias-pull-up-value = "47k"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + pinmux_flexspi1: pinmux_flexspi1 { group0 { pinmux = <&iomuxc_gpio_sd_b1_05_flexspi_a_dqs>; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index 2b2f352d1c3..998e942e5a2 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -238,7 +238,17 @@ zephyr_udc0: &usb1 { &flexpwm2_pwm3 { status = "okay"; - pinctrl-0 = <&pinmux_flexpwm2>; + pinctrl-0 = <&pinmux_flexpwm2_3>; + pinctrl-names = "default"; +}; + +&flexpwm1_pwm0 { + pinctrl-0 = <&pinmux_flexpwm1_0>; + pinctrl-names = "default"; +}; + +&flexpwm1_pwm3 { + pinctrl-0 = <&pinmux_flexpwm1>; pinctrl-names = "default"; }; diff --git a/tests/drivers/pwm/pwm_api/boards/mimxrt1060_evk.overlay b/tests/drivers/pwm/pwm_api/boards/mimxrt1060_evk.overlay new file mode 100644 index 00000000000..ebd3af9f582 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/mimxrt1060_evk.overlay @@ -0,0 +1,18 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Enable PWM outputs on J24 pin 3 and J22 pin 6. These outputs are not used + * by the test, but can be tested using the PWM shell. + */ + +&flexpwm1_pwm3 { + status = "okay"; +}; + +&flexpwm1_pwm0 { + status = "okay"; +}; From 52ba1ee6212044322cc20784e2f110b72721ecd5 Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Mon, 5 Jun 2023 17:00:00 +0800 Subject: [PATCH 0326/4498] boards: arm: add raytac_mdbt53_db_40_nrf5340 Adds new raytac_mdbt53_db_40_nrf5340 board. Signed-off-by: Stanley Huang --- .../CMakeLists.txt | 7 + .../arm/raytac_mdbt53_db_40_nrf5340/Kconfig | 58 ++++ .../raytac_mdbt53_db_40_nrf5340/Kconfig.board | 18 ++ .../Kconfig.defconfig | 101 +++++++ .../raytac_mdbt53_db_40_nrf5340/board.cmake | 13 + .../doc/img/MDBT53-DB-40.jpg | Bin 0 -> 48728 bytes .../raytac_mdbt53_db_40_nrf5340/doc/index.rst | 274 ++++++++++++++++++ .../pre_dt_board.cmake | 8 + .../raytac_mdbt53_db_40_nrf5340_cpuapp.dts | 27 ++ .../raytac_mdbt53_db_40_nrf5340_cpuapp.yaml | 22 ++ ...3_db_40_nrf5340_cpuapp_common-pinctrl.dtsi | 147 ++++++++++ ...tac_mdbt53_db_40_nrf5340_cpuapp_common.dts | 235 +++++++++++++++ ...ytac_mdbt53_db_40_nrf5340_cpuapp_defconfig | 26 ++ .../raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts | 20 ++ ...raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml | 21 ++ ...c_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig | 29 ++ ...53_db_40_nrf5340_cpuapp_partition_conf.dts | 60 ++++ ...c_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi | 27 ++ .../raytac_mdbt53_db_40_nrf5340_cpunet.dts | 40 +++ .../raytac_mdbt53_db_40_nrf5340_cpunet.yaml | 21 ++ ...tac_mdbt53_db_40_nrf5340_cpunet_common.dts | 60 ++++ ...ytac_mdbt53_db_40_nrf5340_cpunet_defconfig | 23 ++ ...raytac_mdbt53_db_40_nrf5340_cpunet_reset.c | 60 ++++ ...b_40_nrf5340_shared_sram_planning_conf.dts | 30 ++ 24 files changed, 1327 insertions(+) create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/CMakeLists.txt create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.board create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/board.cmake create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/doc/img/MDBT53-DB-40.jpg create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/pre_dt_board.cmake create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_partition_conf.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.yaml create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_common.dts create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_reset.c create mode 100644 boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/CMakeLists.txt b/boards/arm/raytac_mdbt53_db_40_nrf5340/CMakeLists.txt new file mode 100644 index 00000000000..6a13dbb534e --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +if ((CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP OR CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS) + AND CONFIG_BOARD_ENABLE_CPUNET) + zephyr_library() + zephyr_library_sources(raytac_mdbt53_db_40_nrf5340_cpunet_reset.c) +endif() diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig new file mode 100644 index 00000000000..875762de828 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig @@ -0,0 +1,58 @@ +# Ratac MDBT53-DB-40 nRF5340 board configuration + +# Copyright (c) 2019 - 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +config BOARD_ENABLE_DCDC_APP + bool "Application MCU DCDC converter" + select SOC_DCDC_NRF53X_APP + default y + +config BOARD_ENABLE_DCDC_NET + bool "Network MCU DCDC converter" + select SOC_DCDC_NRF53X_NET + default y + +config BOARD_ENABLE_DCDC_HV + bool "High Voltage DCDC converter" + select SOC_DCDC_NRF53X_HV + default y + +config BOARD_ENABLE_CPUNET + bool "NRF53 Network MCU" + select SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 if \ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GPIO_FORWARDER)) + help + This option enables releasing the Network 'force off' signal, which + as a consequence will power up the Network MCU during system boot. + Additionally, the option allocates GPIO pins that will be used by UARTE + of the Network MCU. + Note: GPIO pin allocation can only be configured by the secure Application + MCU firmware, so when this option is used with the non-secure version of + the board, the application needs to take into consideration, that the + secure firmware image must already have configured GPIO allocation for the + Network MCU. + default y if (BT || NRF_802154_SER_HOST) + +config DOMAIN_CPUNET_BOARD + string + default "raytac_mdbt53_db_40_nrf5340_cpunet" + depends on BOARD_ENABLE_CPUNET + help + The board which will be used for CPUNET domain when creating a multi + image application where one or more images should be located on + another board. For example hci_rpmsg on the nRF5340_cpunet for + Bluetooth applications. + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +config DOMAIN_CPUAPP_BOARD + string + default "raytac_mdbt53_db_40_nrf5340_cpuapp" + depends on BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET + help + The board which will be used for CPUAPP domain when creating a multi + image application where one or more images should be located on + another board. diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.board b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.board new file mode 100644 index 00000000000..ff4b1ac6986 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.board @@ -0,0 +1,18 @@ +# Raytac MDBT53-DB-40 NRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF5340_CPUAPP_QKAA + +config BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP + bool "Raytac MDBT53-DB-40 nRF5340 Application MCU" + +config BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + bool "Raytac MDBT53-DB-40 nRF5340 Application MCU non-secure" + +endif # SOC_NRF5340_CPUAPP_QKAA + +config BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET + bool "Raytac MDBT53-DB-40 NRF5340 Network MCU" + depends on SOC_NRF5340_CPUNET_QKAA diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig new file mode 100644 index 00000000000..a0a59dc13ab --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig @@ -0,0 +1,101 @@ +# Raytac MDBT53-DB-40 nRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +config BOARD + default "raytac_mdbt53_db_40_nrf5340_cpuapp" + +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default n if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default n + +endif # BUILD_WITH_TFM + +# Code Partition: +# +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# SRAM Partition: +# +# If the secure firmware is to be combined with a non-secure image +# (TRUSTED_EXECUTION_SECURE=y), the secure FW image SRAM shall always +# be restricted to the secure image SRAM partition (sram-secure-partition). +# Otherwise (if TRUSTED_EXECUTION_SECURE is not set) the whole zephyr,sram +# may be used by the image. +# +# For the non-secure version of the board, the firmware image SRAM is +# always restricted to the allocated non-secure SRAM partition. +# +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition +DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config SRAM_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_SRAM_PARTITION),0,K) + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +config BOARD + default "raytac_mdbt53_dv_40_nrf5340_cpunet" if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET + +config IPM_NRFX + default IPM + +config MBOX_NRFX_IPC + default MBOX + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +choice BT_HCI_BUS_TYPE + default BT_RPMSG if BT +endchoice + +config HEAP_MEM_POOL_SIZE + default 4096 if BT_RPMSG + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS + +if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET + +config BT_CTLR + default y if BT + +endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/board.cmake b/boards/arm/raytac_mdbt53_db_40_nrf5340/board.cmake new file mode 100644 index 00000000000..8657aa50f1c --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/board.cmake @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP OR CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS) + board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") +endif() + +if(CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET) + board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/img/MDBT53-DB-40.jpg b/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/img/MDBT53-DB-40.jpg new file mode 100644 index 0000000000000000000000000000000000000000..32525d94b0ac36809372e12fe050352d2ac7e3b0 GIT binary patch literal 48728 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%0D30y)JiPTf^LWu~{`9U`x!8yN z2_&QT#(oO`8Nfe`)LU}TCLm#{q$CQZwJS;U+ms@ z6i$AT-s#M=1g&QmX{JC`{f-dCqbh4@7Sy51+{vN+Oyu#&%NTwK9qJwUCW9|@N>hzv zE;GNO?$z*(VvbTt;Hz$c>mhG>Xxls;*y-2;ki&8D%shr^@lrjB8;JQS+n{N+?i&l~ zZjSLEfO&b-J{;j=TISW9qlJvx&<}=<)bdi@lbn;BL)R3ORutX_kykp}l&pq1_rxPI zzt7FeVDBJ|0$Kpn+~`Q2rW-=I4%2ai8sUcd(et4}`YV;#Xt@%A`w!rrm}%o}@^S8a zQ13`CtHP~?64+7ME(Urs-OpkPbZk2%Tca3~dp%>a&TDLeMpEpPSjazegQoZ;ahGVR zX6*Z^k=$fPVaIMLIG@5U%Yol<>&5byAdEi%DgUi4+P9dP*Ji7tOY9afSV-3AkltyzQRVGcS znW@f9VUlg2{*7g(4{b*i)0ydK3Z4pOA6x2zm*YCc#Tg#W#dE54spcqC8l#LM)&hMm zCs~V7Bk6H0^i(6BS@=RdK~CbbfTPgF$a^GK!5RDJMWZ3nu7`7|LEFVTCBc<4?=xN( zke6@2@FYL>3#t$P*I8*_Yf2%`l>GQZYf66npJmnc@}`S6hm*MW-_$8G>&0lJZ65mm zDx&}8pFs;IlnH5x7IES4x{(Hc2W{U&Q&iH>g!@UfPKF8&2L%0z z1DFDJX~C_=U#=kKpK|FclW!c~cR`Vj^jsf1y8NAe$DK6VsOc%pSfEn=QCN5?c1gx~ zG}6Iiqx1zH;l7>fEr(K~ZhZ(5GAoX7Df4!oa`N$q(xS3u1LF+#9!g90lktnDeWX$a z=t3)OVkR0U;?k?^G~(pTM0hORWsGH&6?T(k9`ljyy}ORu6hH;f*L3c0vd0rv#G-8DjF%{AEGL;;At4 zVS3g(D^v*n^bf#2-yP#eS^i6i5Y1R>KUH5%iROCm`{&E=sY`DxSf>nHzWhJ;0f1-W zlnGM0{oBI6Yi3dEg;R>j9vfpAKJMd=n^5cMz}wGQd;d%4H$*Npz!+(siYd+{*CP8p zRjgraipZ_* zL6Ps*&snWz=CSF{7JB4p^^P#WgBxhqp+A7lQFLz++N$RxbRWhgYLJr27klTSi?g2B z3DRF~m!eQ_l6@!FDD3iqG>t?MG;!vSpWBW}$iY&#ivMar$G_S|-fytWLo+-4rL;@n zHIq4m8-N>XQM|b*Sfxedu@2L;*dIh z$$%DF40WL`lkBI|omlrA-9T28>aV$CSSF+O8eHWBTMjsjFa7yxB z&pT@C`OIb_o-U}=>h;JYM>&Ly`fxVgK9sTZL*M_XcEas!ZWPoA|IQ(xfTBkc4ZUxP zq;*EUl3M>}h$iS`?UA-r2=@bc*GcUE2QZ94%I2($a0lR}FRJ?Aqd;L0f6|Ojh4$|D zuJxbeHoNtI4)<*LY!{M}#qdNv{Xp{Edf8gi8BXit>OX*~%)@Rg15Da4_QL;VZEt^h z8-A{=1lk4*@0+ls+2b8!z7KfsftBx6ibr7*gVYs%@SM ztZO@O+Ai=ZKic8xq^A+__Hm=U2Hm9B?Q|(E|YY*aQ*jTf)^{D|*o9g(7LUoI7j!{K^3Qe}G%gq&4`WJBjdY zOd~e?x6Uf2wW)Jv>fg)^3~UhTjYKIEslVAoSSgQ*+`}86Z;(k$p7`(XA^%0hv=^kP zZ{Qe-AMpo4Ou8bUy50-;mF1hi?qR_mb2Zz2?rc$rn{GW%WO zP%3j)`gXtiQP)Z4^rBv&Tv7Rn+-S_9hh)35T`9*C8sAjL**7bj@3F*M)hQc+o+f#( z`+or6i5`WLSc{C^o~KUMii`t%?*9km%jL_ZIJ7UUs#~txN7xLb5{9IEy*%xg7zdOz z+FB&9t*a?Kl-sR(a$R~>6il13M1Ot&=|w`|{Q*D<4os`K{&(VGz!RU5 z=mvV^jtaptO>@pE@g3#AF z&?hQ?8{{l~SNwTh`M0MaeE|vfY|=kHJHHEdSJg7B#IFX8|Cc`(Ef@+bU1Su;&SX<$ z-MnzMD@u&qL0>@Bmsjv=TFBNv@m$>MRTYAw1ca0l9HgaUtTHtd$ga0r#fj|f)@u*o z$&*(i9oyH-1IRF?ag73~?bWCVeilZJ3rh(#*8($U-r|i@2(v~I;Cowhe7qk7#C;*Q z9LvZ>ds|bIkDu=K>n5r`DtjDE%-ZZWBwMQ?$Qn;^uIj$SZ8)Tz z=KOAzXGYiGR^(rHelbiD_hRX6?0Dzdw+Mrs;v53l&M#BZQVSEL_}R;?-Da4hY<_4E zk0(%z!DPltdD`|Ida0(_iA^0 zQ!E;;csR;*iId109h<&*5%PR zuem$%FK3W89UnoDwFQ}-?;qaA|D~O@cUWj?exLT*{l8L%M!pKwscf!c{-o0hb zzwGO$z#so5YzTh|oAc%XP2Ty|^z~&ALK(|0`HFUIQ=z~~)b;7)<~nsl5)(U@F;ydp zL(qUb{K@q9!t~9_dD#P=N2fJGKr;g>4jFU@2A1nIMR!)z`V92#s2M4RQwK&Jg!1CA zko~V-zu`anG8?x#NYX^vdqFp(G%Vh%rFJ!&+jHPsJ!^WRb6T2lH5E9rKJ%7cz)@B) zmh$Dh0A~4DjswhRrGpTh1Zf=wQI_u!!UWJ~&VpwL^TGx7xl(__3 zrNIW77?I*a$BVSUm1nNvjv_DEhT|ziFi)Ai9Qh>vWm_3bj;wKDLkvCMj=I(QGtuI? z$bkE|s1&I9{d`|9^yCAy;x7cL<+ha3a>yec?B-MvTG6SZ&ud9{ui!m&GDz9MUn)CC z&u_wxAPm@oTa%_ldVJb-IhZ)NkF~y-j5`%i_T)nCX46>UP+~$$bA%ru7KM3p7AD3j zgM2?{EI(XLZSu7J0ib}hfq)=~EH6w}V;S+mmJ>^`y|-=enzn1kdaK(1o$5W*3>-(0 z_t5yQD$g3vf64EiP9{O$V3#@;ioX8K?nbs0PC!z0ooH)__2_7_6-Q3R<;e$`4{+}c zT0GPkkr^jNZZT%50fGG#eddiO2HImL(2+Zr= zA}2|Y4c@hvH$h)rbXT_PrTNd*%R{9lu64;9uz(&~Fb9rG7Poa^(;hF&Ak-c zp<~`Wk7hFXB%npzR$-PKPz?<334*0ke@1OF!h1l{d*RX_z!2$wz7XYms845y!q88Z zG##ft_RUDMfzmW_%z(_U^41DMii~Ur(}6m>MKzR`m6>%=D_!B}txqxJDmDyhgKht9bBs0(mc{lk-Yfa`eFd z9oT*EB9HVqDp}*&tqqcb{PT6-uWltKHk57s&r?trRsv;PBd9 zIr2S#?-2~=rv9n^16u#q{9jwE=B7USgYQjTSLVPq9wqPu>MmJ>0dK@z+1AZ?o(Pj| z>tDcldV4co1g`xDxc__aKeg8XqvhWYU;ga}28^f8g4{r9ZG&7T&yDG&BBWFIzjql= z|7rC93p%pUBHFs24djY4Ji4EC{(_wU6a2lWP?P}%Ito$4xoT0vJ%+;Ai}A1Z6?2oD ze~U@(-<9aVWkq3}MKs&C+~@sJ1QAAC@aS3K(cN$Uj=)v6chixF7U9t)$X-FRAelTy zBnLJ_m?p!DnfC`P3X9G6l3{|Q=m*6fp1MBvxY?tNLS)YY(j~{eMU%5DVn3ZF9YK?3 z?5OGODyT~H`_!#9U{AM5pHJdyatNBD2UN8hH)-$+z9v!7s_1~zP_B#LE*A2g_|Tpw zpSj%P%61YrjuEdEB4l9lQD@TR5};>)>O$5$(LD-3|6LD=AV7$lj-%qhUN3hM`?S=R zgUx&5)-sq!ZzUm!asKiHbBZ{N$BGzFolmt7i@c>;jhS)vDGQe>{|h{G_ETcJJ%(;V z%Z&VA7gsEbSKY%%38Nq#k`$*}>3>N?q+EX-i*dG8=sq9CSM3Hwja1IDn za1MySSs!5Gpy6O)prD{&ARqxy7|@vH>|$yuSY#CH8Z9vB9A>Vm&1@khL)hY)ZfT_p zl;#$pt=~CC-G>)pB~)>!esM`^nFfa?m;EO(1cC@SF~l1oI%Ol@+3d&L#J(Sm{AxZE z#;$Amo+k{f|CHTI|GEA@4gRO_f8U*!`L`GGzukd-M^fM?u>Ys(c|z-!|a# zzr+2{)BZmTn#TVb{l8;n;N=7RM*n{D|2hAsa3pz54IYk`UyVQJ@5d*p>6eTKUBAq< zd?XJ**Pi(%ChG_Ts@Db}#+FbZO7+PolA#(88k+!Laz$%X9GD(lvG`;?)dCnjhY(|fr8PxF zh|3%w{|S?XP>W>>8JEq$w^<>Hrz*;vu8T#Vg~&3dzVC*aqvdQFt4kU}VTWy)UnYx$ z&f-?gE-Sr029q>6X;lW{h69aHtQ5^aiIy(OxX1#|Xg42R7H6af;0Wty51bcco6CVm z=0IV^NV)LC#u!K!hui0<%GNLLZi&xREdHM2&PLzln&5mB z#{5;m4RbpjDmn9z65?Ie0_tiKx|5vwt0+G_92m%;1oX!lX@y_I5gdMj8VC#?1ri_J4A)clhmK9glPf|IzaHI(nt44YO^ zxD{?O>0SIa*6AAfmlzEyeL3rA@ICg}gszE<{y9Tt)2s=vobN7WvAAMh7FcPH`pJL8 zjUYP6Jxs=3y&qAQuIa(enMU)g-9k&T!ZC&Um2y1*^VIx`q269ib>`fThT%#9AxrYj zwb_c3#gMG>kmlMs69?WNl7Y|=;>!~5M-3xHFCLaG+ZbZP6|{4^5i$cPR|{f#4ZLmu z*BEFSRQpB6wCGbz%qfwUgn75K<)mVTWEV8@D!W>81VkHNQ^qjfDCH-F0N$J!GbMIn z3O&!7ZpTau5n2E5MIZIG^#d3Hv6#=%*%SJfKfC-3*OjUn2@+Q%EG?&!Q5G_@s}%um zCkBaRVjfg5wA&O+H5s6VQmwGcI2`#yF+a<0NUbUDSZxS#umgd3Jhg@Lxwt00(&G4H zm3+EQ_^b}|w3cAy+^Swp0QtRkWkb6S(8U87T5KZ)Q!8H2Mg2|noQs!pk;{+>i8(Xf;X_ynO)n~^TavY$#ho5h}mzVF|raznB13YGX~pZRS<*=g0MXWuI?}r z$kl^u)e44!bEW&)&7I`agzzL=h!s?%zVmb4*#S!wF$LBNV~3A+a*usk!VIxCs0imI z!O2f-e@>H5kiWMsV8^*im8sUMku)3ZC>e4W!inhk%}8Gup;G9}2dMBY>x%6xgfHEQ zgq&FzS0b0Eu4}z$=CU`81xT-1D6jfhP-jM#;GlS(T9Jg3Rq#M6%Uh&Vnp$N_cwF@2 z9dRJncE{ik786uBS=>lGe|F%k{LE% zs&shJ@o~OVK^1c%w`3Xy|3;a({T6iC1ZF=% zjB>o?y?k|ip$=A;n?d`EHg?uj=7?Y|i(G(cGs(|*cTj~1bFP7^(s(Aj7%wk7JRQIy zJNbc#W>{&0Fa^CsRI1TFly)1nwS9B(cRNQ4|2>RSog+N-6@hLVyB&)>ax zR{nKw&>D$6@S&jL?YD-c44aW?5P$kGdK5SS7QCTXUk|cUGnX^!QIT7jEe|Cqos-vs zzB-k>D58#SS7sk#AltL?^KTgM#z#8mHUkr zYgd>?H*nL%GD!}5RO`@Kng*$EI}|2WX2G>pR$2ebrmo(6C=xl89I9u#{E#uzd!VR& zMla&u)A1P)#&D@IEx!r>mg*p+8&NVL(MV=pzINhsil`VAaOB0!YiTYC?9^zq-s3I3 z_g7o~Mf&qgBQYAKx7QdX3fNB|-e6EDGpzrZ-80N5%pct)mh4SeL>tB0?-pGQc7jwp z)B$nwQ6Brse!-xO9i0Z2INMIaax}=@EwQgt`EgeeTj3HHNqbn!a zEhg7jXqaPtlVTO$S1AcZ)Lw_ux4Wc z0mj!Cm5Tej?)dVW9pbEg#-9hu8IXus;b(g#51Js953RbkX+37oDVaqP{VrJrMyAOP z@-}~y<7rq3O1-pwf-hV-!MMj#52}uEIB5~v0&Qw;?ICUx2TX)-Dt^*5IPP8%UA?{x zQ-`LvFz>m5Ha__86!U_o7$KqYHYdK(zb2qMq5gt&jT7JS=h_7c7M{t*6~1=6D9WI@ zqPmc?mIg~?HuT2T!CN%E!2#`iLD+Q`;X6-EV!rOtF|%#9v`0p?Zjd%=Z3 zAu-PnGl6(EgU8D$Ukt>&@&xemn0aEkD+y7VBWtaBk;k`CTM|B+ueLy0Oy|hu#~C6- zx~dmb<0a}vdWd>WOQ@c+bL0BTuGz(?Nr?x2&x1s+UF2Be4HPN^+!I>iu@5s68r@-i z=nxu9Fq*n%pusNM1F9@8MIFcud0mi%Bq>H5@+}|BBU zNp1d_`#p31a2nZSBSWt`Ay$seBsgAL8y7btN2wzL*?cCTO5Gx_Ju%E`$u`h0y4n*cKW+E5XNjyyt;ej0I_I?{nUgM4SHB~2$K80Up> zF-=~kR2Zpg%1s`x*w#|`ux_Z{432q*fzLo%f*0>Z7n1%=+3d1;4f$De_q~BM|61d8 z1uTYv(>+Vw6Ka&x^>zXPg~_7#o|Br>@>h(qVixQ+DudJF#0UG+=8ntj7o6B>m|+3;*~^Dk)IRueqOfQ9@e+^tF-lnkBs|%N zPwUhAH=Ov2uJhCS>zB>h?b$;&IdO1_X#`~l<l$3J<^rRkmW<58!HlFnydW$3jF65hy`P|2hA&CU`O{XI zU6*$ul^DdgJDwOn^bi7_I)7)a3ryCk|!z(Cixy9<-&75dz^1*YiO~epq z1x@+^6Y=(ESRZRcHKMa6)abXWDu-lbQHLysed&i&!__AX>N0283LtwICd*m9ud|&} z3)MNo;q-#v2y(*~Au3(ducOsdP%H&x8fw))^=Gq~iXG6fqJr}h9auEQz5BKjM*+op zHcMlYUm3_V`>X!Nw?fJ{ycHm8By>=!raFpKe8S_D_qVN4L<$$V2^wG?KByMl&kuJK85VgrK)4n{D= z{_k9LB|Cd9M<5cga~#`UKUA|Pucl!}5g?-C=z*&cx_gvKTY)elKssqo=ONW%-3<`B zfzIV<))>TKhwd)6yEBvA>p|+xqf69lfmAj?u|p}W8MDL0QKd0w5vt5_3w1jyfl@qt zw0t_pYu@!XHb)Boq~SSPXJ8{Sz(jkUAthlPT|G#PpC94~RBhfbelCXTOuXvRs@4$V z`ovYe-Ry!oELp=)gU&e_0@YxgpM5-GT13c{*y?0$Mkfx|mJZoaCRLcwJx@@;g zZ37X+a+1)l*!y)5hkgr`~CObIIT=hKcO1q{!AmNyqE3D0~xZ)DY(({W|{5 zl9?Sv`y8faQVG9WU~Qygd<(ZQb?o&Um@SVA#OmhCR?Kx_VQZdaU}kfz!!%vh88EYX zwl^r^(ZPfxe^}Gps)$YFlkw=@EXI$mzF|GKV(-9Imc+ugr?)4jbxV0p$KS8|%i)T< zx$OcW0*q-0ztO3A;zSs)(;OnnYihoyErsG)$ZIZB9Ljr)1;! z+(L!m@1FbvUC6EUwfUhUKiGIXFA?OUfh(yEF8vksgEBQC z3%zEbDuuKTEF-c-jNDMjEaLU(7+E$+vEqI;p54KVDN{L~U2jEZS{VTPBh_9Ew1V9z zh^wc;Tz0=~Lzlb5Tz8vHq;A6RLz^bQa>{~(3C+|5DU-ZJNvX}|L`RgnC{#VSRMTQ^ z!_mEZh3pq1Resj(F=VoupR2Gzlth7(w8a9R-|8R67421j2x?n$2#nd{n~GW z?I|ep!dh$I4||x^Myb}dx9ow}MuwV@*r(80XRKj9`jeSyx14Piw`dFT zfHp5?eiU;o>GUm3KD`?2S2vdHy`x*WKkl`2=u3`Ey>iRz-G-z>NQ&IP9Unm6;P({$ zsnUw!HI)rD*-x#9xCH3odZ9#lNWqpIe$BKpr>DWVbd*ZXDu$&nVJ+tMeVA!!GIm1P ztC(yTF&_MZ^=Y0)Io)Z&c{+eUoX#k*3dVaJtDmjy!Tin3SV(_Wr2olsaN0n)X$=A% zb5^0W2-o=-Irc zJ(gn%2SAjEDpYZ_><{4KLY2VL1)d{O2bH^fqal-RJzpDbjXVFi^XGAMoa z$0!rWda@WyDyW_Rm0I$c5^8wQhNFfX)$%h!ZVlwPn&s`f#bRJa5HK8Rw_ z6Ss(nj>|0Vo8H)K<>##1qJwAXE86rIpb_e@te#k)XSV0_syf{(@(3sSx(62QAAn~( zG)4)mnq7p{OewAx4N9Hx})ae1!3DXn62tGFXTOwS`5UKHRc?6^!9N|<*DYG z);x$b81H6ue3jf(P3#|*Rh1(*6*-Ig#M#DbRq19q<4R_Fd=(J7&cw^dmKyc@eN{4S zTY|9-{QVOeW|$e%94GXQvc8ws8PyN0#dxSYiJ!7VhmAt9qX{Ag8V|&NOvs3kS-aGg zv+Ab0qEYkh_JtgRpxL0o>`!;3^MEv~>G`Eeqvo2kBOSHhcZ}G-BKv@bX^B|C>dw+< zh5E&LC(L9~C0hmNJ%I<&M)YkTA-i+-F118+q<39p*gPkJDJKOe#JM%^XWSp=a9tA^ zSV5Nix%qMZU&J0rpS^i^e>EX1xVtIR2~n9kBRKSNI8{-2e=SoQX@X{$b1Lm}zEL9R zwR%reoT!im)b)yRaqN(b8f*g|B%AzaAup#)nK|?e4J@(B5F5^1dV-PH%P3~zIRv4a zOR;)m(rxd^epcCHENgW=rSz*9jLVhwn>t_V=@Eb&Ai6niE791@cDOH?cteyeCndzf z)kGnmTM;Bs776rbE2rqy(|_J@L|{@gsL?}#eo-?`w8>2`a5KpA=eb5Jg$1_COM^W4 z<1Ne*@dE}cZFR0A4-?QZmT@U-efBkO?qB~=ftwQ^5&GFiBpmCYMg2bMc7Jpa)@V7+ z0LNM%*=2LKU7X4aSaP$h$16>dpbpAw22&BYfKxEN#F`mmxgY@MHn-*wkia%@7v6Ms zOFe+bqB;S>61B(zkPHyNllqO3Fuf$h&XL-V%{JZmc&(3Z4zcP4bcz2D;T!-H&VT3k zB~Sx&P5*3RS*v~6-C?Um!nLY2f$?9PE$->e514pZ{ zV*eOsQz^Zs4sqUZLTKU|l-GK~W=%HNYv}R!8G1~(zPc;kBav?2wd&)flo>`&{g=*m zQX#2wj`n&lr8J!>qX5khY5_^B59+09?4AwBho5+|YxbBL)izt+o9;hnErVaMf+O`U zo5)(pPy-cTfReobnDB$`d@-IrL2Bp{f?+i+J=a$nGkgC?Ge-YN%BAWO#Npk3Sf5}P zZiom?tcA0M2(nJuR(SjyVopUe{!T<7h2EKkdjv896cZEbSm@dp5_+cs9Szj;~|AkMsHl}?wuo?Gou z-T8pO-f|>4*>(2&otV_ zV<7c@(VB-@yY@(1wGS)K2+;MidXq`#YE@DmV?u1tI0&k+M}=5Pb)NQdr#;?Qt|FjW z<|EF&f&4!JtZxF#uT?AiOE)w01ddW$Zkc4E0g_mfJZ^k#H90pmM_)S85PsU(s+-$d z+u>2NJy%#`Pw4^7VbvH>AXc{Q1YN;zQrW|yU^AuHeQo`+mktE#Lb7;&_)*H21-5+1 zVK#r0^Q7}?&XB{=5x-~-C;MKr+|3A-&WP0JZ>bl>)Lm5PWZS456rKvdV%iWHIOHTz z!@^R}Rt!l@TSOh`mqdsaVVKrHiVI1`VrRbO!3x9|oTzSkX>Y#A!9H!T$sg2n#LuiZ zQ>!`f;D_IK78tPn2NA@Uchsv6@Ky{;acospHxxhs0qBV(t2O0_RdZVnwUX)htw1bH zMgh%YkMeI7v`o%ErxdZX_X$6-F7lV~J$5w8UaQKT=zEq;>CgqxNp>mu2+wC+y-QNs zDD$he45@>Wy5v{F`k88KWi=OwfSZzIU5t8w+SFXYS2W!ByYahw9Zk4W67B3)DGuG% z@X~T)?V4G}c4^>G2>x(5&NvODIY$Q3j1u_ ztOKBtF=yS$PWAm{-MUPLoJIlbjr>bnYOf}-p%m~bpT}N z^Kv47Dj!o4_rpW4koQBPIR%@tEMYI#oFEq~2=Z>|d6Sf|*>UanWVO;_o$lLvMvp;+ zvslshE(AD6VE%R(N%z?>Rn1o^YPQOsQ82 zHiz(BEUz<((3Llnm10y2f)G`fB16jahU$jiX$;gI%qZpeU873HS}GHS!a^0f6w=Jm-6&Use6?Me!HYDq!*2937YBi-Jz>?^uK2Z5=cg@rixzQ0WPm>- z!PlyIc4sGWFZLy$0`OAgJEu&63p5S_VRJ5dv=`>do!Yq-yU+trt@x1kJM_mO&-`>dol84q;6|#cE zn<90Nh*F?fdW`{!SasjfD);?Vt~&6I*);9`=O$Seu~XgDZni=y{6mlO7rkwF^rm)7ie

-kjW#D!5=x0>WH?QtL) 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 z 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 P%JaW}Vn+S|{w)0;@D9s; literal 0 HcmV?d00001 diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst b/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst new file mode 100644 index 00000000000..cc2285f1484 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst @@ -0,0 +1,264 @@ +.. _raytac_mdbt53v_db_40_nrf5340: + +Raytac MDBT53V-DB-40 +#################### + +Overview +******** + +Raytac MDBT53V-DB-40 demo board is a development board based on the Raytac MDBT53V-1M module, +using Nordic Semiconductor nRF5340 ARM Cortex-M33 SoC. Its design concept is to connect all +of the module's pins to 2.54mm pin headers. It is convenient for developers to verify whether +the modules are connected to other peripheral devices or sensors as a tool for software development. + +The nRF5340 inside the MDBT53V-1M module is a +dual-core SoC based on the Arm® Cortex®-M33 architecture, with: + +* a full-featured Arm Cortex-M33F core with DSP instructions, FPU, and + Armv8-M Security Extension, running at up to 128 MHz, referred to as + the **application core** +* a secondary Arm Cortex-M33 core, with a reduced feature set, running + at a fixed 64 MHz, referred to as the **network core**. + +The raytac_mdbt53v_db_40_nrf5340_cpuapp build target provides support for the application +core on the nRF5340 SoC. The raytac_mdbt53v_db_40_nrf5340_cpuapp build target provides +support for the network core on the nRF5340 SoC. + +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + +nRF5340 SoC provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/MDBT53V-DB-40.jpg + :width: 442px + :align: center + :alt: MDBT53V-DB-40 + + MDBT53V-DB-40 (Credit: Raytac Corporation) + +More information about the board can be found at the `MDBT53V-DB-40 website`_. +The `MDBT53V-DB-40 Specification`_ contains the demo board's datasheet. +The `MDBT53V-DB-40 Schematic`_ contains the demo board's schematic. + +Hardware +******** +- Module Demo Board build by MDBT53V-1M +- Nordic nRF5340 SoC Solution +- A recommnded 3rd-party module by Nordic Semiconductor. +- Dual-core Arm® Cortex® M33 +- 1MB/256KB Flash Memory; 512kB/ 64kB RAM +- Supports BT5 Long Range Features +- Bluetooth specification v5.2 +- Supports BT5 Long Range Features +- Supports Bluetooth Direction Finding & Mesh +- Supports Bluetooth low energy audio +- Cerifications: FCC, IC, CE, Telec(MIC), KC, SRRC, NCC, RCM, WPC +- RoHs & Reach Compiant. +- 25 GPIO +- Chip Antenna +- Interfaces: SPI, UART, I2C, I2S, PWM, ADC, and NFC +- Highly flexible multiprotocol SoC ideally suited for Bluetooth® Low Energy, ANT+, Zigbee, Thread (802.15.4) ultra low-power wireless applications. +- 1 User LEDs +- 3 User buttons +- 1 Mini USB connector for power supply +- SWD connector for FW programing +- J-Link interface for FW programing + +Supported Features +================== + +The raytac_mdbt53v_db_40_nrf5340_cpuapp board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +The raytac_mdbt53v_db_40_nrf5340_cpunet board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. +See `MDBT53V-DB-40 website`_ and `MDBT53V-DB-40 Specification`_ +for a complete list of Raytac MDBT53V-DB-40 board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.31 + +Push buttons +------------ + +* BUTTON1 = SW1 = P1.13 +* BUTTON2 = SW2 = P0.25 +* BUTTON3 = SW3 = P0.26 + +HSPI +---- +* MOSI = P0.9 +* MISO = P0.10 +* SCK = P0.8 +* CSN = P0.11 +* DCX = P0.12 + +QSPI +---- +* SCK = P0.17 +* CSN = P0.18 +* DATA0 = P0.13 +* DATA1 = P0.14 +* DATA2 = P0.15 +* DATA3 = P0.16 + +Security components +=================== + +- Implementation Defined Attribution Unit (`IDAU`_) on the application core. + The IDAU is implemented with the System Protection Unit and is used to + define secure and non-secure memory maps. By default, all of the memory + space (Flash, SRAM, and peripheral address space) is defined to be secure + accessible only. +- Secure boot. + +Programming and Debugging +************************* + +nRF5340 application core supports the Armv8-M Security Extension. +Applications built for the raytac_mdbt53v_db_40_nrf5340_cpuapp board by +default boot in the Secure state. + +nRF5340 network core does not support the Armv8-M Security Extension. +nRF5340 IDAU may configure bus accesses by the nRF5340 network core +to have Secure attribute set; the latter allows to build and run +Secure only applications on the nRF5340 SoC. + +Applications for the ``raytac_mdbt53v_db_40_nrf5340`` board configuration can be +built, flashed, and debugged in the usual way. See :ref:`build_an_application` and +:ref:`application_run` for more details on building and running. + +.. note:: + Flashing and Debugging Zephyr onto the raytac_mdbt53v_db_40_nrf5340 board + requires an external J-Link programmer. The programmer is attached to the J1 + or J9 SWD connector. + + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +Use a USB to TTL converter to connect the computer and raytac_mdbt53v_db_40_nrf5340 +J13 connector pin 8(RX), 9(TX) and GND. Then run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the USB to TTL converter +can be found. For example, under Linux, :code:`/dev/ttyUSB0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: raytac_mdbt53v_db_40_nrf5340 + :goals: build flash + +Debugging +========= + +The ``raytac_mdbt53v_db_40_nrf5340`` board does not have an on-board-J-Link debug IC, +however, instructions from the :ref:`nordic_segger` page also apply to this board. +Use the Debug out connector of nRF52x DK to connect to the J1 connector, and use SEGGER +J-Link OB IF to debug. + + +References +********** + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _MDBT53V-DB-40 website: + https://www.raytac.com/product/ins.php?index_id=140 +.. _MDBT53V-DB-40 Specification: + https://www.raytac.com/download/index.php?index_id=62 +.. _MDBT53V-DB-40 Schematic: + https://www.raytac.com/upload/catalog_b/f2c33d52dca8cd6546c95938bc0cb295.jpg +.. _J-Link Software and documentation pack: + https://www.segger.com/jlink-software.html diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/pre_dt_board.cmake b/boards/arm/raytac_mdbt53v_db_40_nrf5340/pre_dt_board.cmake new file mode 100644 index 00000000000..fb045e38545 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/pre_dt_board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - flash-controller@39000 & kmu@39000 +# - power@5000 & clock@5000 +# - /reserved-memory/image@20000000 & /reserved-memory/image_s@20000000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.dts new file mode 100644 index 00000000000..6b5890d7472 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts" + +/ { + model = "Raytac MDBT53V-DB-40 NRF5340 Application"; + compatible = "raytac,raytac-mdbt53v-db-40-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_image; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml new file mode 100644 index 00000000000..c9552cb6202 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml @@ -0,0 +1,20 @@ +identifier: raytac_mdbt53v_db_40_nrf5340_cpuapp +name: RAYTAC-MDBT53V-DB-40-NRF5340-application-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 448 +flash: 1024 +supported: + - counter + - gpio + - i2c + - i2s + - pwm + - qspi + - spi + - watchdog + - netif:openthread diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi new file mode 100644 index 00000000000..0839492b156 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c1_default: i2c1_default { + group1 { + psels = , + ; + }; + }; + + i2c1_sleep: i2c1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart0_default: uart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = ; + }; + }; + + pwm0_sleep: pwm0_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; + + qspi_default: qspi_default { + group1 { + psels = , + , + , + , + , + ; + }; + }; + + qspi_sleep: qspi_sleep { + group1 { + psels = , + , + , + , + , + ; + low-power-enable; + }; + }; + + spi4_default: spi4_default { + group1 { + psels = , + , + ; + }; + }; + + spi4_sleep: spi4_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts new file mode 100644 index 00000000000..ca020adaa35 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi" + +/ { + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + }; + button1: button_1 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + }; + button2: button_2 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + }; + }; + + gpio_fwd: nrf-gpio-forwarder { + compatible = "nordic,nrf-gpio-forwarder"; + status = "okay"; + uart { + gpios = <&gpio1 1 0>, <&gpio1 0 0>, <&gpio0 11 0>, <&gpio0 10 0>; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + bootloader-led0 = &led0; + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; + watchdog0 = &wdt0; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c1 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&qspi { + status = "okay"; + pinctrl-0 = <&qspi_default>; + pinctrl-1 = <&qspi_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi4 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 11 0>; + pinctrl-0 = <&spi4_default>; + pinctrl-1 = <&spi4_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@50000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@80000 { + label = "image-1"; + }; + slot1_ns_partition: partition@c0000 { + label = "image-1-nonsecure"; + }; + /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&ieee802154 { + status = "okay"; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_image: image@20000000 { + /* Zephyr image(s) memory */ + }; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_ns: image_ns@20040000 { + /* Non-Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "raytac_mdbt53v_db_40_nrf5340_cpuapp_partition_conf.dts" diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig new file mode 100644 index 00000000000..4824d5987bb --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts new file mode 100644 index 00000000000..0713304bc15 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts" + +/ { + model = "Raytac MDBT53V-DB-40 NRF5340 Application"; + compatible = "raytac,raytac-mdbt53v-db-40-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_ns; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; +}; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml new file mode 100644 index 00000000000..5251dc8737f --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml @@ -0,0 +1,16 @@ +identifier: raytac_mdbt53v_db_40_nrf5340_cpuapp_ns +name: RAYTAC-MDBT53V-DB-40-NRF52840-application-MCU-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 192 +flash: 192 +supported: + - i2c + - pwm + - watchdog + - netif:openthread + - gpio diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig new file mode 100644 index 00000000000..2bae84e660e --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_partition_conf.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_partition_conf.dts new file mode 100644 index 00000000000..207d58f4e75 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_partition_conf.dts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for raytac_mdbt53v_db_40_nrf5340 CPUAPP (Application MCU). + * + * Zephyr build for nRF5340 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot0_ns_partition { + reg = <0x00050000 0x30000>; +}; + +&slot1_partition { + reg = <0x00080000 0x40000>; +}; + +&slot1_ns_partition { + reg = <0x000c0000 0x30000>; +}; + +/* Default SRAM planning when building for nRF5340 with + * ARM TrustZone-M support + * - Lowest 256 kB SRAM allocated to Secure image (sram0_s) + * - Middle 192 kB allocated to Non-Secure image (sram0_ns) + * - Upper 64 kB SRAM allocated as Shared memory (sram0_shared) + * (see raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts) + */ +&sram0_image { + reg = <0x20000000 DT_SIZE_K(448)>; +}; + +&sram0_s { + reg = <0x20000000 0x40000>; +}; + +&sram0_ns { + reg = <0x20040000 0x30000>; +}; + +/* Include shared RAM configuration file */ +#include "raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi new file mode 100644 index 00000000000..15e96ef213e --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts new file mode 100644 index 00000000000..8b36a2aefbb --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi" +#include "raytac_mdbt53v_db_40_nrf5340_cpunet_common.dts" +/ { + model = "Raytac MDBT53V-DB-40 NRF5340 Network"; + compatible = "raytac,raytac-mdbt53v-db-40-nrf5340-cpunet"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,sram = &sram1; + zephyr,flash = &flash1; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + }; + + + /* These aliases are provided for compatibility with samples */ + aliases { + watchdog0 = &wdt0; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml new file mode 100644 index 00000000000..a76a74a6598 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml @@ -0,0 +1,20 @@ +# Raytac MDBT53V_DB_40_NRF5340 board configuration + +# Copyright (c) 2023 Raytac Corporation +# SPDX-License-Identifier: Apache-2.0 +identifier: raytac_mdbt53v_db_40_nrf5340_cpunet +name: RAYTAC MDBT53V-DB-40-NRF5340-network-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - watchdog + - gpio + - i2c + - spi + - uart diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_common.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_common.dts new file mode 100644 index 00000000000..643bebf6e38 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_common.dts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&flash1 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x17000>; + }; + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 0x17000>; + }; + storage_partition: partition@3a000 { + label = "storage"; + reg = <0x0003a000 0x6000>; + }; + }; +}; + +/* Include shared RAM configuration file */ +#include "raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig new file mode 100644 index 00000000000..bff78a85624 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUNET_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_reset.c b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_reset.c new file mode 100644 index 00000000000..fd48ae16fd6 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_reset.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2021 Nordic Semiconductor ASA. + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(raytac_mdbt53v_db_40_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); + +#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) +#include <../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h> +#else +#define DEBUG_SETUP() +#endif + +static void remoteproc_mgr_config(void) +{ +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) + /* Route Bluetooth Controller Debug Pins */ + DEBUG_SETUP(); +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) */ + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Retain nRF5340 Network MCU in Secure domain (bus + * accesses by Network MCU will have Secure attribute set). + */ + NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) */ +} + +static int remoteproc_mgr_boot(const struct device *dev) +{ + + /* Secure domain may configure permissions for the Network MCU. */ + remoteproc_mgr_config(); + +#if !defined(CONFIG_TRUSTED_EXECUTION_SECURE) + /* + * Building Zephyr with CONFIG_TRUSTED_EXECUTION_SECURE=y implies + * building also a Non-Secure image. The Non-Secure image will, in + * this case do the remainder of actions to properly configure and + * boot the Network MCU. + */ + + /* Release the Network MCU, 'Release force off signal' */ + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + + LOG_DBG("Network MCU released."); +#endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ + + return 0; +} + +SYS_INIT(remoteproc_mgr_boot, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts new file mode 100644 index 00000000000..aa162f85a5a --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default shared SRAM planning when building for nRF5340. + * This file is included by both nRF5340 CPUAPP (Application MCU) + * and nRF5340 CPUNET (Network MCU). + * - 64 kB SRAM allocated as Shared memory (sram0_shared) + * - Region defined after the image SRAM of Application MCU + */ + +/ { + chosen { + /* shared memory reserved for the inter-processor communication */ + zephyr,ipc_shm = &sram0_shared; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_shared: memory@20070000 { + /* SRAM allocated to shared memory */ + reg = <0x20070000 0x10000>; + }; + }; +}; diff --git a/samples/net/wpan_serial/sample.yaml b/samples/net/wpan_serial/sample.yaml index 31a458d13fc..c9ff33d9a42 100644 --- a/samples/net/wpan_serial/sample.yaml +++ b/samples/net/wpan_serial/sample.yaml @@ -4,15 +4,13 @@ sample: common: depends_on: usb_device harness: net - tags: - - net - - usb - - ieee802154 + tags: usb ieee802154 platform_exclude: pinnacle_100_dvk tests: sample.net.wpan.serial: filter: dt_chosen_enabled("zephyr,ieee802154") - platform_exclude: thingy53_nrf5340_cpuapp_ns - sample.net.wpan.serial.frdm_cr20a: + platform_exclude: thingy53_nrf5340_cpuapp_ns raytac_mdbt53_db_40_nrf5340_cpuapp_ns + raytac_mdbt53_db_40_nrf5340_cpuapp + sample.net.wpan_serial.frdm_cr20a: extra_args: SHIELD=frdm_cr20a platform_allow: frdm_k64f diff --git a/samples/net/wpanusb/sample.yaml b/samples/net/wpanusb/sample.yaml index 729e8c6ba12..bf16524ea72 100644 --- a/samples/net/wpanusb/sample.yaml +++ b/samples/net/wpanusb/sample.yaml @@ -3,16 +3,14 @@ sample: name: wpanusb common: depends_on: usb_device - tags: - - net - - ieee802154 - - usb + tags: net ieee802154 usb harness: net platform_exclude: pinnacle_100_dvk tests: sample.net.wpanusb: filter: dt_chosen_enabled("zephyr,ieee802154") - platform_exclude: thingy53_nrf5340_cpuapp_ns + platform_exclude: thingy53_nrf5340_cpuapp_ns raytac_mdbt53_db_40_nrf5340_cpuapp_ns + raytac_mdbt53_db_40_nrf5340_cpuapp sample.net.wpanusb_frdm_cr20a: extra_args: SHIELD=frdm_cr20a platform_allow: frdm_k64f From 19ba93c8965b206ef28aea3ed81e1152bb764d6e Mon Sep 17 00:00:00 2001 From: "J.P. Hutchins" Date: Sat, 27 May 2023 14:32:01 -0700 Subject: [PATCH 0328/4498] drivers: flash: implement wp-gpios and hold-gpios Adds the wp-gpios & hold-gpios from jedec,spi-nor compatible to spi_nor.c. Signed-off-by: J.P. Hutchins --- drivers/flash/spi_nor.c | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index c0d67af7250..bb37f0d47f3 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2018 Savoir-Faire Linux. * Copyright (c) 2020 Peter Bigot Consulting, LLC + * Copyright (c) 2023 Intercreate, Inc. * * This driver is heavily inspired from the spi_flash_w25qxxdv.c SPI NOR driver. * @@ -63,6 +64,12 @@ LOG_MODULE_REGISTER(spi_nor, CONFIG_FLASH_LOG_LEVEL); #define T_DPDD_MS 0 #endif /* DPD_WAKEUP_SEQUENCE */ +#define _INST_HAS_WP_OR(inst) DT_INST_NODE_HAS_PROP(inst, wp_gpios) || +#define ANY_INST_HAS_WP_GPIOS DT_INST_FOREACH_STATUS_OKAY(_INST_HAS_WP_OR) 0 + +#define _INST_HAS_HOLD_OR(inst) DT_INST_NODE_HAS_PROP(inst, hold_gpios) || +#define ANY_INST_HAS_HOLD_GPIOS DT_INST_FOREACH_STATUS_OKAY(_INST_HAS_HOLD_OR) 0 + /* Build-time data associated with the device. */ struct spi_nor_config { /* Devicetree SPI configuration */ @@ -107,6 +114,15 @@ struct spi_nor_config { * This information cannot be derived from SFDP. */ uint8_t has_lock; + +#if ANY_INST_HAS_WP_GPIOS + /* The write-protect GPIO (wp-gpios) */ + const struct gpio_dt_spec *wp; +#endif +#if ANY_INST_HAS_HOLD_GPIOS + /* The hold GPIO (hold-gpios) */ + const struct gpio_dt_spec *hold; +#endif }; /** @@ -827,8 +843,17 @@ static int spi_nor_erase(const struct device *dev, off_t addr, size_t size) static int spi_nor_write_protection_set(const struct device *dev, bool write_protect) { +#if ANY_INST_HAS_WP_GPIOS + const struct spi_nor_config *cfg = dev->config; +#endif int ret; +#if ANY_INST_HAS_WP_GPIOS + if (cfg->wp) { + gpio_pin_set_dt(cfg->wp, write_protect); + } +#endif + ret = spi_nor_cmd_write(dev, (write_protect) ? SPI_NOR_CMD_WRDI : SPI_NOR_CMD_WREN); @@ -1320,12 +1345,37 @@ static int spi_nor_pm_control(const struct device *dev, enum pm_device_action ac */ static int spi_nor_init(const struct device *dev) { +#if (ANY_INST_HAS_WP_GPIOS || ANY_INST_HAS_HOLD_GPIOS) + const struct spi_nor_config *cfg = dev->config; +#endif + if (IS_ENABLED(CONFIG_MULTITHREADING)) { struct spi_nor_data *const driver_data = dev->data; k_sem_init(&driver_data->sem, 1, K_SEM_MAX_LIMIT); } +#if ANY_INST_HAS_WP_GPIOS + if (cfg->wp) { + if (!device_is_ready(cfg->wp->port)) { + return -ENODEV; + } + if (gpio_pin_configure_dt(cfg->wp, GPIO_OUTPUT_ACTIVE)) { + return -ENODEV; + } + } +#endif /* ANY_INST_HAS_WP_GPIOS */ +#if ANY_INST_HAS_HOLD_GPIOS + if (cfg->hold) { + if (!device_is_ready(cfg->hold->port)) { + return -ENODEV; + } + if (gpio_pin_configure_dt(cfg->hold, GPIO_OUTPUT_INACTIVE)) { + return -ENODEV; + } + } +#endif /* ANY_INST_HAS_HOLD_GPIOS */ + return spi_nor_configure(dev); } @@ -1422,6 +1472,21 @@ BUILD_ASSERT(DT_INST_PROP(0, has_lock) == (DT_INST_PROP(0, has_lock) & 0xFF), "Need support for lock clear beyond SR1"); #endif +#define INST_HAS_WP_GPIO(idx) DT_INST_NODE_HAS_PROP(idx, wp_gpios) + +#define INST_WP_GPIO_SPEC(idx) \ + IF_ENABLED(INST_HAS_WP_GPIO(idx), (static const struct gpio_dt_spec wp_##idx = \ + GPIO_DT_SPEC_INST_GET(idx, wp_gpios);)) + +#define INST_HAS_HOLD_GPIO(idx) DT_INST_NODE_HAS_PROP(idx, hold_gpios) + +#define INST_HOLD_GPIO_SPEC(idx) \ + IF_ENABLED(INST_HAS_HOLD_GPIO(idx), (static const struct gpio_dt_spec hold_##idx = \ + GPIO_DT_SPEC_INST_GET(idx, hold_gpios);)) + +INST_WP_GPIO_SPEC(0) +INST_HOLD_GPIO_SPEC(0) + static const struct spi_nor_config spi_nor_config_0 = { .spi = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), CONFIG_SPI_NOR_CS_WAIT_DELAY), @@ -1455,6 +1520,14 @@ static const struct spi_nor_config spi_nor_config_0 = { #endif /* CONFIG_SPI_NOR_SFDP_DEVICETREE */ #endif /* CONFIG_SPI_NOR_SFDP_RUNTIME */ + +#if DT_INST_NODE_HAS_PROP(0, wp_gpios) + .wp = &wp_0, +#endif + +#if DT_INST_NODE_HAS_PROP(0, hold_gpios) + .hold = &hold_0, +#endif }; static struct spi_nor_data spi_nor_data_0; From 477ff702300cfe154caf3375b9b26f08dc81f1af Mon Sep 17 00:00:00 2001 From: "J.P. Hutchins" Date: Wed, 31 May 2023 14:04:20 -0700 Subject: [PATCH 0329/4498] test: drivers: flash: build spi_nor.c wp & hold Test spi_nor.c driver builds with or without wp-gpios and hold-gpios. Signed-off-by: J.P. Hutchins --- .../common/boards/nrf52840dk_spi_nor.overlay | 61 ++++++++++++++++++ .../boards/nrf52840dk_spi_nor_wp_hold.overlay | 63 +++++++++++++++++++ tests/drivers/flash/common/testcase.yaml | 10 +++ 3 files changed, 134 insertions(+) create mode 100644 tests/drivers/flash/common/boards/nrf52840dk_spi_nor.overlay create mode 100644 tests/drivers/flash/common/boards/nrf52840dk_spi_nor_wp_hold.overlay diff --git a/tests/drivers/flash/common/boards/nrf52840dk_spi_nor.overlay b/tests/drivers/flash/common/boards/nrf52840dk_spi_nor.overlay new file mode 100644 index 00000000000..1042b429ee3 --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf52840dk_spi_nor.overlay @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Intercreate, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Build test for jedec,spi-nor compatible (drivers/flash/spi_nor.c) + */ + +/ { + aliases { + spi-flash0 = &mx25v1635fzui; + }; +}; + +/delete-node/ &mx25r64; + +&pinctrl { + spi0_default: spi0_default { + group1 { + psels = , + , + ; + }; + }; + + spi0_sleep: spi0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; + +&spi0 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; // mx25v16 + pinctrl-0 = <&spi0_default>; + pinctrl-1 = <&spi0_sleep>; + pinctrl-names = "default", "sleep"; + + mx25v1635fzui: mx25v1635fzui@0 { + compatible = "jedec,spi-nor"; + status = "okay"; + reg = <0>; + spi-max-frequency = <8000000>; // chip supports 80Mhz, SPI0 supports 8MHz + size = <0x1000000>; // bits + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <45000>; + jedec-id = [ C2 23 15 ]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 00 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f1 00 82 ec 04 c2 44 83 48 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + }; +}; diff --git a/tests/drivers/flash/common/boards/nrf52840dk_spi_nor_wp_hold.overlay b/tests/drivers/flash/common/boards/nrf52840dk_spi_nor_wp_hold.overlay new file mode 100644 index 00000000000..f17febff6c3 --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf52840dk_spi_nor_wp_hold.overlay @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Intercreate, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Build test for jedec,spi-nor compatible (drivers/flash/spi_nor.c) wp-gpios and hold-gpios + */ + +/ { + aliases { + spi-flash0 = &mx25v1635fzui; + }; +}; + +/delete-node/ &mx25r64; + +&pinctrl { + spi0_default: spi0_default { + group1 { + psels = , + , + ; + }; + }; + + spi0_sleep: spi0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; + +&spi0 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; // mx25v16 + pinctrl-0 = <&spi0_default>; + pinctrl-1 = <&spi0_sleep>; + pinctrl-names = "default", "sleep"; + + mx25v1635fzui: mx25v1635fzui@0 { + compatible = "jedec,spi-nor"; + status = "okay"; + reg = <0>; + spi-max-frequency = <8000000>; // chip supports 80Mhz, SPI0 supports 8MHz + size = <0x1000000>; // bits + hold-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <45000>; + jedec-id = [ C2 23 15 ]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 00 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f1 00 82 ec 04 c2 44 83 48 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + }; +}; diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index 8e3e3cfbc4c..d0bf791236b 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -79,3 +79,13 @@ tests: platform_allow: mr_canhubk3 extra_configs: - CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME=y + drivers.flash.common.spi_nor: + platform_allow: nrf52840dk_nrf52840 + extra_args: + - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf + - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor.overlay + drivers.flash.common.spi_nor_wp_hold: + platform_allow: nrf52840dk_nrf52840 + extra_args: + - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf + - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor_wp_hold.overlay From a9ac01c457e11615e69c2339a85815f4f5a31677 Mon Sep 17 00:00:00 2001 From: "J.P. Hutchins" Date: Wed, 21 Jun 2023 18:29:02 -0700 Subject: [PATCH 0330/4498] drivers: flash: add LOG_ERR for pin init -ENODEV returned in 4 cases, logs can distinguish Signed-off-by: J.P. Hutchins --- drivers/flash/spi_nor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index bb37f0d47f3..4032e9bd4a1 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -1358,9 +1358,11 @@ static int spi_nor_init(const struct device *dev) #if ANY_INST_HAS_WP_GPIOS if (cfg->wp) { if (!device_is_ready(cfg->wp->port)) { + LOG_ERR("Write-protect pin not ready"); return -ENODEV; } if (gpio_pin_configure_dt(cfg->wp, GPIO_OUTPUT_ACTIVE)) { + LOG_ERR("Write-protect pin failed to set active") return -ENODEV; } } @@ -1368,9 +1370,11 @@ static int spi_nor_init(const struct device *dev) #if ANY_INST_HAS_HOLD_GPIOS if (cfg->hold) { if (!device_is_ready(cfg->hold->port)) { + LOG_ERR("Hold pin not ready"); return -ENODEV; } if (gpio_pin_configure_dt(cfg->hold, GPIO_OUTPUT_INACTIVE)) { + LOG_ERR("Hold pin failed to set inactive") return -ENODEV; } } From b403fdee0098f08eec4b1220768e35ca797467ce Mon Sep 17 00:00:00 2001 From: "J.P. Hutchins" Date: Wed, 21 Jun 2023 18:51:15 -0700 Subject: [PATCH 0331/4498] drivers: flash: cleanup #ifs; fix missing ; Fixes made running tests/drivers/flash Signed-off-by: J.P. Hutchins --- drivers/flash/spi_nor.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 4032e9bd4a1..042bc19a60d 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -70,6 +70,8 @@ LOG_MODULE_REGISTER(spi_nor, CONFIG_FLASH_LOG_LEVEL); #define _INST_HAS_HOLD_OR(inst) DT_INST_NODE_HAS_PROP(inst, hold_gpios) || #define ANY_INST_HAS_HOLD_GPIOS DT_INST_FOREACH_STATUS_OKAY(_INST_HAS_HOLD_OR) 0 +#define DEV_CFG(_dev_) ((const struct spi_nor_config * const) (_dev_)->config) + /* Build-time data associated with the device. */ struct spi_nor_config { /* Devicetree SPI configuration */ @@ -843,14 +845,11 @@ static int spi_nor_erase(const struct device *dev, off_t addr, size_t size) static int spi_nor_write_protection_set(const struct device *dev, bool write_protect) { -#if ANY_INST_HAS_WP_GPIOS - const struct spi_nor_config *cfg = dev->config; -#endif int ret; #if ANY_INST_HAS_WP_GPIOS - if (cfg->wp) { - gpio_pin_set_dt(cfg->wp, write_protect); + if (DEV_CFG(dev)->wp) { + gpio_pin_set_dt(DEV_CFG(dev)->wp, write_protect); } #endif @@ -1345,10 +1344,6 @@ static int spi_nor_pm_control(const struct device *dev, enum pm_device_action ac */ static int spi_nor_init(const struct device *dev) { -#if (ANY_INST_HAS_WP_GPIOS || ANY_INST_HAS_HOLD_GPIOS) - const struct spi_nor_config *cfg = dev->config; -#endif - if (IS_ENABLED(CONFIG_MULTITHREADING)) { struct spi_nor_data *const driver_data = dev->data; @@ -1356,25 +1351,25 @@ static int spi_nor_init(const struct device *dev) } #if ANY_INST_HAS_WP_GPIOS - if (cfg->wp) { - if (!device_is_ready(cfg->wp->port)) { + if (DEV_CFG(dev)->wp) { + if (!device_is_ready(DEV_CFG(dev)->wp->port)) { LOG_ERR("Write-protect pin not ready"); return -ENODEV; } - if (gpio_pin_configure_dt(cfg->wp, GPIO_OUTPUT_ACTIVE)) { - LOG_ERR("Write-protect pin failed to set active") + if (gpio_pin_configure_dt(DEV_CFG(dev)->wp, GPIO_OUTPUT_ACTIVE)) { + LOG_ERR("Write-protect pin failed to set active"); return -ENODEV; } } #endif /* ANY_INST_HAS_WP_GPIOS */ #if ANY_INST_HAS_HOLD_GPIOS - if (cfg->hold) { - if (!device_is_ready(cfg->hold->port)) { + if (DEV_CFG(dev)->hold) { + if (!device_is_ready(DEV_CFG(dev)->hold->port)) { LOG_ERR("Hold pin not ready"); return -ENODEV; } - if (gpio_pin_configure_dt(cfg->hold, GPIO_OUTPUT_INACTIVE)) { - LOG_ERR("Hold pin failed to set inactive") + if (gpio_pin_configure_dt(DEV_CFG(dev)->hold, GPIO_OUTPUT_INACTIVE)) { + LOG_ERR("Hold pin failed to set inactive"); return -ENODEV; } } From d7313388c9e19116b02124a7b27d1e2752b959cc Mon Sep 17 00:00:00 2001 From: "J.P. Hutchins" Date: Mon, 7 Aug 2023 11:40:48 -0700 Subject: [PATCH 0332/4498] drivers: flash: fix hw write protect before sw This change sets write-protect pin disabled BEFORE SW write-protect disable and write-protect pin enabled AFTER SW write-protect enable. Signed-off-by: J.P. Hutchins --- drivers/flash/spi_nor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 042bc19a60d..88d9725168e 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -848,8 +848,8 @@ static int spi_nor_write_protection_set(const struct device *dev, int ret; #if ANY_INST_HAS_WP_GPIOS - if (DEV_CFG(dev)->wp) { - gpio_pin_set_dt(DEV_CFG(dev)->wp, write_protect); + if (DEV_CFG(dev)->wp && write_protect == false) { + gpio_pin_set_dt(DEV_CFG(dev)->wp, 0); } #endif @@ -862,6 +862,12 @@ static int spi_nor_write_protection_set(const struct device *dev, ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_ULBPR); } +#if ANY_INST_HAS_WP_GPIOS + if (DEV_CFG(dev)->wp && write_protect == true) { + gpio_pin_set_dt(DEV_CFG(dev)->wp, 1); + } +#endif + return ret; } From 2779dd9d9bfd85ff9215c331bdada9880261a980 Mon Sep 17 00:00:00 2001 From: Weiwei Guo Date: Wed, 17 May 2023 18:11:30 +0800 Subject: [PATCH 0333/4498] drivers: sensor: bmm150: Add trigger support for bmm150 magnetometer sensor Add bmm150 magetometer sensor data ready trigger support. Signed-off-by: Weiwei Guo --- drivers/sensor/bmm150/CMakeLists.txt | 1 + drivers/sensor/bmm150/Kconfig | 39 ++++ drivers/sensor/bmm150/bmm150.c | 19 ++ drivers/sensor/bmm150/bmm150.h | 33 +++- drivers/sensor/bmm150/bmm150_trigger.c | 175 ++++++++++++++++++ dts/bindings/sensor/bosch,bmm150.yaml | 7 + tests/drivers/build_all/sensor/i2c.dtsi | 1 + .../sensor/sensors_trigger_global.conf | 1 + .../sensor/sensors_trigger_none.conf | 1 + .../build_all/sensor/sensors_trigger_own.conf | 1 + tests/drivers/build_all/sensor/spi.dtsi | 1 + 11 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 drivers/sensor/bmm150/bmm150_trigger.c diff --git a/drivers/sensor/bmm150/CMakeLists.txt b/drivers/sensor/bmm150/CMakeLists.txt index 7b3ad8d04cb..d41b954038c 100644 --- a/drivers/sensor/bmm150/CMakeLists.txt +++ b/drivers/sensor/bmm150/CMakeLists.txt @@ -2,3 +2,4 @@ zephyr_library() zephyr_library_sources(bmm150.c bmm150_i2c.c bmm150_spi.c) +zephyr_library_sources_ifdef(CONFIG_BMM150_TRIGGER bmm150_trigger.c) diff --git a/drivers/sensor/bmm150/Kconfig b/drivers/sensor/bmm150/Kconfig index 54cf97456d3..93f652eb2b3 100644 --- a/drivers/sensor/bmm150/Kconfig +++ b/drivers/sensor/bmm150/Kconfig @@ -33,6 +33,31 @@ config BMM150_PRESET_HIGH_ACCURACY endchoice +choice BMM150_TRIGGER_MODE + prompt "Trigger mode" + default BMM150_TRIGGER_NONE + help + Specify the type of triggering to be used by the driver. + +config BMM150_TRIGGER_NONE + bool "No trigger" + +config BMM150_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + select BMM150_TRIGGER + +config BMM150_TRIGGER_OWN_THREAD + bool "Use own thread" + select BMM150_TRIGGER + +config BMM150_TRIGGER_DIRECT + bool "Use IRQ handler" + select BMM150_TRIGGER +endchoice + +config BMM150_TRIGGER + bool + config BMM150_SAMPLING_RATE_RUNTIME bool "Dynamic sampling rate" help @@ -48,4 +73,18 @@ config BMM150_SAMPLING_REP_Z help Enable alteration of Z oversampling at runtime. +config BMM150_THREAD_PRIORITY + int "Own thread priority" + depends on BMM150_TRIGGER_OWN_THREAD + default 10 + help + Priority of the thread used by the driver to handle interrupts. + +config BMM150_THREAD_STACK_SIZE + int "Own thread stack size" + depends on BMM150_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + endif # BMM150 diff --git a/drivers/sensor/bmm150/bmm150.c b/drivers/sensor/bmm150/bmm150.c index 6c480190a67..62393ca02ae 100644 --- a/drivers/sensor/bmm150/bmm150.c +++ b/drivers/sensor/bmm150/bmm150.c @@ -495,6 +495,10 @@ static const struct sensor_driver_api bmm150_api_funcs = { #endif .sample_fetch = bmm150_sample_fetch, .channel_get = bmm150_channel_get, + +#ifdef CONFIG_BMM150_TRIGGER + .trigger_set = bmm150_trigger_set, +#endif }; static int bmm150_full_por(const struct device *dev) @@ -668,6 +672,13 @@ static int bmm150_init(const struct device *dev) return -EIO; } +#ifdef CONFIG_BMM150_TRIGGER + if (bmm150_trigger_mode_init(dev) < 0) { + LOG_ERR("Cannot set up trigger mode."); + return -EINVAL; + } +#endif + return 0; } @@ -686,6 +697,13 @@ static int bmm150_init(const struct device *dev) (BMM150_CONFIG_I2C(inst)), \ (BMM150_CONFIG_SPI(inst))) +#if defined(CONFIG_BMM150_TRIGGER) +#define BMM150_INT_CFG(inst) \ + .drdy_int = GPIO_DT_SPEC_INST_GET(inst, drdy_gpios), +#else +#define BMM150_INT_CFG(inst) +#endif + /* * Main instantiation macro, which selects the correct bus-specific * instantiation macros for the instance. @@ -694,6 +712,7 @@ static int bmm150_init(const struct device *dev) static struct bmm150_data bmm150_data_##inst; \ static const struct bmm150_config bmm150_config_##inst = { \ BMM150_BUS_CFG(inst) \ + BMM150_INT_CFG(inst) \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \ diff --git a/drivers/sensor/bmm150/bmm150.h b/drivers/sensor/bmm150/bmm150.h index d00497354a4..47fb3f736cd 100644 --- a/drivers/sensor/bmm150/bmm150.h +++ b/drivers/sensor/bmm150/bmm150.h @@ -157,13 +157,38 @@ struct bmm150_trim_regs { struct bmm150_config { union bmm150_bus bus; const struct bmm150_bus_io *bus_io; + +#ifdef CONFIG_BMM150_TRIGGER + struct gpio_dt_spec drdy_int; +#endif }; struct bmm150_data { - struct k_sem sem; struct bmm150_trim_regs tregs; int rep_xy, rep_z, odr, max_odr; int sample_x, sample_y, sample_z; + +#if defined(CONFIG_BMM150_TRIGGER) + struct gpio_callback gpio_cb; +#endif + +#ifdef CONFIG_BMM150_TRIGGER_OWN_THREAD + struct k_sem sem; +#endif + +#ifdef CONFIG_BMM150_TRIGGER_GLOBAL_THREAD + struct k_work work; +#endif + +#if defined(CONFIG_BMM150_TRIGGER_GLOBAL_THREAD) || \ + defined(CONFIG_BMM150_TRIGGER_DIRECT) + const struct device *dev; +#endif + +#ifdef CONFIG_BMM150_TRIGGER + const struct sensor_trigger *drdy_trigger; + sensor_trigger_handler_t drdy_handler; +#endif /* CONFIG_BMM150_TRIGGER */ }; enum bmm150_axis { @@ -198,6 +223,12 @@ enum bmm150_presets { /* Start-Up Time - from suspend to sleep (Max) */ #define BMM150_START_UP_TIME K_MSEC(3) +int bmm150_trigger_mode_init(const struct device *dev); + +int bmm150_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + int bmm150_reg_update_byte(const struct device *dev, uint8_t reg, uint8_t mask, uint8_t value); diff --git a/drivers/sensor/bmm150/bmm150_trigger.c b/drivers/sensor/bmm150/bmm150_trigger.c new file mode 100644 index 00000000000..edfd5d89b68 --- /dev/null +++ b/drivers/sensor/bmm150/bmm150_trigger.c @@ -0,0 +1,175 @@ +/* Bosch BMM150 pressure sensor + * + * Copyright (c) 2020 Facebook, Inc. and its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmm150-ds001.pdf + */ + +#include +#include +#include + +#include "bmm150.h" + +LOG_MODULE_DECLARE(BMM150, CONFIG_SENSOR_LOG_LEVEL); + +static void bmm150_handle_interrupts(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct bmm150_data *data = dev->data; + + if (data->drdy_handler) { + data->drdy_handler(dev, data->drdy_trigger); + } +} + +#ifdef CONFIG_BMM150_TRIGGER_OWN_THREAD +static K_THREAD_STACK_DEFINE(bmm150_thread_stack, + CONFIG_BMM150_THREAD_STACK_SIZE); +static struct k_thread bmm150_thread; + +static void bmm150_thread_main(void *arg1, void *unused1, void *unused2) +{ + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + const struct device *dev = (const struct device *)arg1; + struct bmm150_data *data = dev->data; + + while (1) { + k_sem_take(&data->sem, K_FOREVER); + bmm150_handle_interrupts(dev); + } +} +#endif + +#ifdef CONFIG_BMM150_TRIGGER_GLOBAL_THREAD +static void bmm150_work_handler(struct k_work *work) +{ + struct bmm150_data *data = CONTAINER_OF(work, + struct bmm150_data, + work); + + bmm150_handle_interrupts(data->dev); +} +#endif + +static void bmm150_gpio_callback(const struct device *port, + struct gpio_callback *cb, + uint32_t pin) +{ + struct bmm150_data *data = CONTAINER_OF(cb, + struct bmm150_data, + gpio_cb); + + ARG_UNUSED(port); + ARG_UNUSED(pin); + +#if defined(CONFIG_BMM150_TRIGGER_OWN_THREAD) + k_sem_give(&data->sem); +#elif defined(CONFIG_BMM150_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#elif defined(CONFIG_BMM150_TRIGGER_DIRECT) + bmm150_handle_interrupts(data->dev); +#endif +} + +int bmm150_trigger_set( + const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + uint16_t values[BMM150_AXIS_XYZR_MAX]; + struct bmm150_data *data = dev->data; + const struct bmm150_config *cfg = dev->config; + +#ifdef CONFIG_PM_DEVICE + enum pm_device_state state; + + (void)pm_device_state_get(dev, &state); + if (state != PM_DEVICE_STATE_ACTIVE) { + return -EBUSY; + } +#endif + + if (trig->type != SENSOR_TRIG_DATA_READY) { + return -ENOTSUP; + } + + data->drdy_trigger = trig; + data->drdy_handler = handler; + + if (bmm150_reg_update_byte(dev, + BMM150_REG_INT_DRDY, + BMM150_MASK_DRDY_EN, + (handler != NULL) << BMM150_SHIFT_DRDY_EN) < 0) { + LOG_ERR("Failed to enable DRDY interrupt"); + return -EIO; + } + + /* Clean data registers */ + if (cfg->bus_io->read(&cfg->bus, BMM150_REG_X_L, (uint8_t *)values, sizeof(values)) < 0) { + LOG_ERR("failed to read sample"); + return -EIO; + } + + return 0; +} + +int bmm150_trigger_mode_init(const struct device *dev) +{ + struct bmm150_data *data = dev->data; + const struct bmm150_config *cfg = dev->config; + int ret; + + if (!device_is_ready(cfg->drdy_int.port)) { + LOG_ERR("INT device is not ready"); + return -ENODEV; + } + +#if defined(CONFIG_BMM150_TRIGGER_OWN_THREAD) + k_sem_init(&data->sem, 0, 1); + k_thread_create( + &bmm150_thread, + bmm150_thread_stack, + CONFIG_BMM150_THREAD_STACK_SIZE, + bmm150_thread_main, + (void *)dev, + NULL, + NULL, + K_PRIO_COOP(CONFIG_BMM150_THREAD_PRIORITY), + 0, + K_NO_WAIT); +#elif defined(CONFIG_BMM150_TRIGGER_GLOBAL_THREAD) + k_work_init(&data->work, bmm150_work_handler); +#endif + +#if defined(CONFIG_BMM150_TRIGGER_GLOBAL_THREAD) || \ + defined(CONFIG_BMM150_TRIGGER_DIRECT) + data->dev = dev; +#endif + + ret = gpio_pin_configure_dt(&cfg->drdy_int, GPIO_INPUT); + if (ret < 0) { + return ret; + } + + gpio_init_callback(&data->gpio_cb, + bmm150_gpio_callback, + BIT(cfg->drdy_int.pin)); + + ret = gpio_add_callback(cfg->drdy_int.port, &data->gpio_cb); + if (ret < 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->drdy_int, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + return ret; + } + + return 0; +} diff --git a/dts/bindings/sensor/bosch,bmm150.yaml b/dts/bindings/sensor/bosch,bmm150.yaml index 579999968b5..9b546b81171 100644 --- a/dts/bindings/sensor/bosch,bmm150.yaml +++ b/dts/bindings/sensor/bosch,bmm150.yaml @@ -4,3 +4,10 @@ # Common fields for BMM150 include: sensor-device.yaml + +properties: + drdy-gpios: + type: phandle-array + description: | + This property specifies the connection for data ready pin. + The polarity default is active high when sensor data is ready. diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index c0f687ee05d..d654b93ff15 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -88,6 +88,7 @@ test_i2c_bmg160: bmg160@c { test_i2c_bmm150: bmm150@d { compatible = "bosch,bmm150"; reg = <0xd>; + drdy-gpios = <&test_gpio 0 0>; }; test_i2c_hmc5883l: hmc5883l@e { diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index dc8321f1a7d..cf4fce093e4 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -10,6 +10,7 @@ CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD=y CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD=y CONFIG_BMI160_TRIGGER_GLOBAL_THREAD=y CONFIG_BMI270_TRIGGER_GLOBAL_THREAD=y +CONFIG_BMM150_TRIGGER_GLOBAL_THREAD=y CONFIG_BMP388_TRIGGER_GLOBAL_THREAD=y CONFIG_BQ274XX_TRIGGER_GLOBAL_THREAD=y CONFIG_CCS811_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index e53189629ba..f89a07de1c4 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -10,6 +10,7 @@ CONFIG_BMI08X_ACCEL_TRIGGER_NONE=y CONFIG_BMI08X_GYRO_TRIGGER_NONE=y CONFIG_BMI160_TRIGGER_NONE=y CONFIG_BMI270_TRIGGER_NONE=y +CONFIG_BMM150_TRIGGER_NONE=y CONFIG_BMP388_TRIGGER_NONE=y CONFIG_BQ274XX_TRIGGER_NONE=y CONFIG_CCS811_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index 4f7e3bbdbfa..3447061c16f 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -9,6 +9,7 @@ CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD=y CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD=y CONFIG_BMI160_TRIGGER_OWN_THREAD=y CONFIG_BMI270_TRIGGER_OWN_THREAD=y +CONFIG_BMM150_TRIGGER_OWN_THREAD=y CONFIG_BMP388_TRIGGER_OWN_THREAD=y CONFIG_BQ274XX_TRIGGER_OWN_THREAD=y CONFIG_CCS811_TRIGGER_OWN_THREAD=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index b352cd193fd..246ecd50dd7 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -225,6 +225,7 @@ test_spi_bmm150: bmm150@1d { compatible = "bosch,bmm150"; reg = <0x1d>; spi-max-frequency = <0>; + drdy-gpios = <&test_gpio 0 0>; }; test_spi_hts221: hts221@1e { From c99f7ec019660350f5103773405b1499550aeb26 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 13 Sep 2023 11:01:00 +0000 Subject: [PATCH 0334/4498] drivers: fuel_gauge: fix i2c_dump_msgs_rw argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix another i2c_dump_msgs_rw: /drivers/fuel_gauge/bq27z746/emul_bq27z746.c:282:26: warning: passing argument 1 of ‘i2c_dump_msgs_rw’ from incompatible pointer type Signed-off-by: Fabio Baltieri --- drivers/fuel_gauge/bq27z746/emul_bq27z746.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/fuel_gauge/bq27z746/emul_bq27z746.c b/drivers/fuel_gauge/bq27z746/emul_bq27z746.c index fe4256cdea5..b416babd0d5 100644 --- a/drivers/fuel_gauge/bq27z746/emul_bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/emul_bq27z746.c @@ -279,7 +279,7 @@ static int bq27z746_emul_transfer_i2c(const struct emul *target, struct i2c_msg __ASSERT_NO_MSG(msgs && num_msgs); - i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); switch (num_msgs) { case 1: if (msgs->flags & I2C_MSG_READ) { From 73605f1ee84eb86beddfbe58598197f104ac96eb Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 13 Sep 2023 13:48:37 +0200 Subject: [PATCH 0335/4498] cmake: armlink: update CMake library to arch__arm__core__cortex_m Fixes: #62589 Follow-up: #60031 The PR #60031 moved CMake code to new folder location causing generated library names to change. This change impacted the use of those libraries in the Zephyr armlink CMake code, causing CMake failures at configure time. This PR fixes this failure by updating the armlink CMake code to use the new library names. Signed-off-by: Torsten Rasmussen --- cmake/linker/armlink/target.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/linker/armlink/target.cmake b/cmake/linker/armlink/target.cmake index 8f777c7800d..e8511aea244 100644 --- a/cmake/linker/armlink/target.cmake +++ b/cmake/linker/armlink/target.cmake @@ -65,7 +65,7 @@ function(toolchain_ld_link_elf) ) foreach(lib ${ZEPHYR_LIBS_PROPERTY}) - if(NOT ${lib} STREQUAL arch__arm__core__aarch32__cortex_m) + if(NOT ${lib} STREQUAL arch__arm__core__cortex_m) list(APPEND ZEPHYR_LIBS_OBJECTS $) list(APPEND ZEPHYR_LIBS_OBJECTS $) endif() @@ -76,7 +76,7 @@ function(toolchain_ld_link_elf) ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} --scatter=${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} - $ + $ --map --list=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} ${ZEPHYR_LIBS_OBJECTS} kernel From e79ef005965d8cbab53ab9644a60907095eff10a Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 20:32:55 +0900 Subject: [PATCH 0336/4498] manifest: Update hal_rpi_pico module Update hal_rpi_pico to commit fba7162c to introduce the hardware_timer modification. Signed-off-by: TOKITA Hiroshi --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b3ddef9ca14..c690b2dd31a 100644 --- a/west.yml +++ b/west.yml @@ -215,7 +215,7 @@ manifest: - hal - name: hal_rpi_pico path: modules/hal/rpi_pico - revision: b7801e4db6a62ea2d37bbef7880c3d056530c9bf + revision: fba7162cc7bee06d0149622bbcaac4e41062d368 groups: - hal - name: hal_silabs From 8d98e7064e6e3626b5db0dc196641a6deb6e0291 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 12:26:50 +0900 Subject: [PATCH 0337/4498] modules: hal_rpi_pico: Enable TIMER driver Enable TIME driver. Add the path of the TIME driver header into include paths. Signed-off-by: TOKITA Hiroshi --- modules/hal_rpi_pico/CMakeLists.txt | 5 +++++ modules/hal_rpi_pico/Kconfig | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/modules/hal_rpi_pico/CMakeLists.txt b/modules/hal_rpi_pico/CMakeLists.txt index c085785a093..3ae107449ae 100644 --- a/modules/hal_rpi_pico/CMakeLists.txt +++ b/modules/hal_rpi_pico/CMakeLists.txt @@ -105,6 +105,11 @@ if(CONFIG_HAS_RPI_PICO) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_DMA ${rp2_common_dir}/hardware_dma/include) + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_TIMER + ${rp2_common_dir}/hardware_timer/timer.c) + zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_TIMER + ${rp2_common_dir}/hardware_timer/include) + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_CLAIM ${rp2_common_dir}/hardware_claim/claim.c) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM diff --git a/modules/hal_rpi_pico/Kconfig b/modules/hal_rpi_pico/Kconfig index 4baf11dd406..56f92ea427e 100644 --- a/modules/hal_rpi_pico/Kconfig +++ b/modules/hal_rpi_pico/Kconfig @@ -44,3 +44,8 @@ config PICOSDK_USE_CLAIM bool help Use the "claim" driver from pico-sdk + +config PICOSDK_USE_TIMER + bool + help + Use the TIMER driver from pico-sdk From cf242016b413cc0956d67712c8ce9b8edd98f432 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 12:27:36 +0900 Subject: [PATCH 0338/4498] drivers: counter: Add support for rpi_pico timer Adds support for rpi_pico timer Signed-off-by: TOKITA Hiroshi --- drivers/counter/CMakeLists.txt | 1 + drivers/counter/Kconfig | 2 + drivers/counter/Kconfig.rpi_pico | 8 + drivers/counter/counter_rpi_pico_timer.c | 217 ++++++++++++++++++ dts/arm/rpi_pico/rp2040.dtsi | 16 ++ .../timer/raspberrypi,pico-timer.yaml | 8 + 6 files changed, 252 insertions(+) create mode 100644 drivers/counter/Kconfig.rpi_pico create mode 100644 drivers/counter/counter_rpi_pico_timer.c create mode 100644 dts/bindings/timer/raspberrypi,pico-timer.yaml diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index e250a2851b2..3a59312da24 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -47,3 +47,4 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_NXP_S32_SYS_TIMER counter_nxp_s32_ zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_GD32 counter_gd32_timer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_SNPS_DW counter_dw_timer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_SHELL counter_timer_shell.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_RPI_PICO counter_rpi_pico_timer.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 793c58dd063..956c5d59f64 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -92,4 +92,6 @@ source "drivers/counter/Kconfig.gd32" source "drivers/counter/Kconfig.dw" +source "drivers/counter/Kconfig.rpi_pico" + endif # COUNTER diff --git a/drivers/counter/Kconfig.rpi_pico b/drivers/counter/Kconfig.rpi_pico new file mode 100644 index 00000000000..53fc748e252 --- /dev/null +++ b/drivers/counter/Kconfig.rpi_pico @@ -0,0 +1,8 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_TIMER_RPI_PICO + def_bool y + select PICOSDK_USE_TIMER + select PICOSDK_USE_CLAIM + depends on DT_HAS_RASPBERRYPI_PICO_TIMER_ENABLED diff --git a/drivers/counter/counter_rpi_pico_timer.c b/drivers/counter/counter_rpi_pico_timer.c new file mode 100644 index 00000000000..3e1a1dcbb0b --- /dev/null +++ b/drivers/counter/counter_rpi_pico_timer.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_COUNTER_LOG_LEVEL +#include + +LOG_MODULE_REGISTER(counter_rpi_pico_timer, LOG_LEVEL); + +#define DT_DRV_COMPAT raspberrypi_pico_timer + +struct counter_rpi_pico_timer_ch_data { + counter_alarm_callback_t callback; + void *user_data; +}; + +struct counter_rpi_pico_timer_data { + struct counter_rpi_pico_timer_ch_data *ch_data; + uint32_t guard_period; +}; + +struct counter_rpi_pico_timer_config { + struct counter_config_info info; + timer_hw_t *timer; + void (*irq_config)(); +}; + +static int counter_rpi_pico_timer_start(const struct device *dev) +{ + const struct counter_rpi_pico_timer_config *config = dev->config; + + config->timer->pause = 0; + + return 0; +} + +static int counter_rpi_pico_timer_stop(const struct device *dev) +{ + const struct counter_rpi_pico_timer_config *config = dev->config; + + config->timer->pause = 1u; + config->timer->timelw = 0; + config->timer->timehw = 0; + + return 0; +} + +static uint32_t counter_rpi_pico_timer_get_top_value(const struct device *dev) +{ + const struct counter_rpi_pico_timer_config *config = dev->config; + + return config->info.max_top_value; +} + +static int counter_rpi_pico_timer_get_value(const struct device *dev, uint32_t *ticks) +{ + *ticks = time_us_32(); + return 0; +} + +static int counter_rpi_pico_timer_set_alarm(const struct device *dev, uint8_t id, + const struct counter_alarm_cfg *alarm_cfg) +{ + const struct counter_rpi_pico_timer_config *config = dev->config; + struct counter_rpi_pico_timer_data *data = dev->data; + struct counter_rpi_pico_timer_ch_data *chdata = &data->ch_data[id]; + uint64_t target = (alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) ? 0 : alarm_cfg->ticks; + absolute_time_t alarm_at; + bool missed; + + update_us_since_boot(&alarm_at, config->timer->timerawl + target); + + if (alarm_cfg->ticks > counter_rpi_pico_timer_get_top_value(dev)) { + return -EINVAL; + } + + if (chdata->callback) { + return -EBUSY; + } + + chdata->callback = alarm_cfg->callback; + chdata->user_data = alarm_cfg->user_data; + + missed = hardware_alarm_set_target(id, alarm_at); + + if (missed) { + if (alarm_cfg->flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE) { + hardware_alarm_force_irq(id); + } + chdata->callback = NULL; + chdata->user_data = NULL; + return -ETIME; + } + + return 0; +} + +static int counter_rpi_pico_timer_cancel_alarm(const struct device *dev, uint8_t id) +{ + hardware_alarm_cancel(id); + + return 0; +} + +static int counter_rpi_pico_timer_set_top_value(const struct device *dev, + const struct counter_top_cfg *cfg) +{ + ARG_UNUSED(dev); + ARG_UNUSED(cfg); + + return -ENOTSUP; +} + +static uint32_t counter_rpi_pico_timer_get_pending_int(const struct device *dev) +{ + return 0; +} + +static uint32_t counter_rpi_pico_timer_get_guard_period(const struct device *dev, uint32_t flags) +{ + struct counter_rpi_pico_timer_data *data = dev->data; + + return data->guard_period; +} + +static int counter_rpi_pico_timer_set_guard_period(const struct device *dev, uint32_t guard, + uint32_t flags) +{ + struct counter_rpi_pico_timer_data *data = dev->data; + + __ASSERT_NO_MSG(guard < counter_rpi_pico_timer_get_top_value(dev)); + + data->guard_period = guard; + + return 0; +} + +static void counter_rpi_pico_irq_handle(uint32_t ch, void *arg) +{ + struct device *dev = arg; + struct counter_rpi_pico_timer_data *data = dev->data; + counter_alarm_callback_t cb = data->ch_data[ch].callback; + void *user_data = data->ch_data[ch].user_data; + + if (cb) { + data->ch_data[ch].callback = NULL; + data->ch_data[ch].user_data = NULL; + cb(dev, ch, time_us_32(), user_data); + } +} + +static int counter_rpi_pico_timer_init(const struct device *dev) +{ + const struct counter_rpi_pico_timer_config *config = dev->config; + + config->irq_config(); + + return 0; +} + +static const struct counter_driver_api counter_rpi_pico_driver_api = { + .start = counter_rpi_pico_timer_start, + .stop = counter_rpi_pico_timer_stop, + .get_value = counter_rpi_pico_timer_get_value, + .set_alarm = counter_rpi_pico_timer_set_alarm, + .cancel_alarm = counter_rpi_pico_timer_cancel_alarm, + .set_top_value = counter_rpi_pico_timer_set_top_value, + .get_pending_int = counter_rpi_pico_timer_get_pending_int, + .get_top_value = counter_rpi_pico_timer_get_top_value, + .get_guard_period = counter_rpi_pico_timer_get_guard_period, + .set_guard_period = counter_rpi_pico_timer_set_guard_period, +}; + +#define RPI_PICO_TIMER_IRQ_ENABLE(node_id, name, idx) \ + do { \ + hardware_alarm_set_callback(idx, counter_rpi_pico_irq_handle); \ + IRQ_CONNECT((DT_IRQ_BY_IDX(node_id, idx, irq)), \ + (DT_IRQ_BY_IDX(node_id, idx, priority)), hardware_alarm_irq_handler, \ + (DEVICE_DT_GET(node_id)), 0); \ + irq_enable((DT_IRQ_BY_IDX(node_id, idx, irq))); \ + } while (false); + +#define COUNTER_RPI_PICO_TIMER(inst) \ + static void counter_irq_config##inst(void) \ + { \ + DT_INST_FOREACH_PROP_ELEM(inst, interrupt_names, RPI_PICO_TIMER_IRQ_ENABLE); \ + } \ + static struct counter_rpi_pico_timer_ch_data \ + ch_data##inst[DT_NUM_IRQS(DT_DRV_INST(inst))]; \ + static struct counter_rpi_pico_timer_data counter_##inst##_data = { \ + .ch_data = ch_data##inst, \ + }; \ + static const struct counter_rpi_pico_timer_config counter_##inst##_config = { \ + .timer = (timer_hw_t *)DT_INST_REG_ADDR(inst), \ + .irq_config = counter_irq_config##inst, \ + .info = \ + { \ + .max_top_value = UINT32_MAX, \ + .freq = 1000000, \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = ARRAY_SIZE(ch_data##inst), \ + }, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, counter_rpi_pico_timer_init, NULL, &counter_##inst##_data, \ + &counter_##inst##_config, PRE_KERNEL_1, \ + CONFIG_COUNTER_INIT_PRIORITY, &counter_rpi_pico_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(COUNTER_RPI_PICO_TIMER) diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi index 131c59a1b1b..fd83297fa5a 100644 --- a/dts/arm/rpi_pico/rp2040.dtsi +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -189,6 +189,22 @@ #pwm-cells = <3>; }; + timer: timer@40054000 { + compatible = "raspberrypi,pico-timer"; + reg = <0x40054000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_TIMER>; + clocks = <&xtal_clk>; + interrupts = <0 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <1 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <2 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <3 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "TIMER_IRQ_0", + "TIMER_IRQ_1", + "TIMER_IRQ_2", + "TIMER_IRQ_3"; + status = "disabled"; + }; + dma: dma@50000000 { compatible = "raspberrypi,pico-dma"; reg = <0x50000000 DT_SIZE_K(64)>; diff --git a/dts/bindings/timer/raspberrypi,pico-timer.yaml b/dts/bindings/timer/raspberrypi,pico-timer.yaml new file mode 100644 index 00000000000..98afd1b9659 --- /dev/null +++ b/dts/bindings/timer/raspberrypi,pico-timer.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: RaspberryPi Pico timer + +compatible: "raspberrypi,pico-timer" + +include: [base.yaml, reset-device.yaml] From 66857e70720f9b871b9c95a122421c4f16fd9ca7 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 12:26:17 +0900 Subject: [PATCH 0339/4498] boards: rpi_pico: Add timer support Add timer support for the rpi_pico board Signed-off-by: TOKITA Hiroshi --- boards/arm/rpi_pico/rpi_pico-common.dtsi | 4 ++++ boards/arm/rpi_pico/rpi_pico.yaml | 1 + 2 files changed, 5 insertions(+) diff --git a/boards/arm/rpi_pico/rpi_pico-common.dtsi b/boards/arm/rpi_pico/rpi_pico-common.dtsi index 4cc49ce5181..54f12e53843 100644 --- a/boards/arm/rpi_pico/rpi_pico-common.dtsi +++ b/boards/arm/rpi_pico/rpi_pico-common.dtsi @@ -119,6 +119,10 @@ pinctrl-names = "default"; }; +&timer { + status = "okay"; +}; + &wdt0 { status = "okay"; }; diff --git a/boards/arm/rpi_pico/rpi_pico.yaml b/boards/arm/rpi_pico/rpi_pico.yaml index d3baa1f1822..485cfde0db5 100644 --- a/boards/arm/rpi_pico/rpi_pico.yaml +++ b/boards/arm/rpi_pico/rpi_pico.yaml @@ -19,3 +19,4 @@ supported: - pwm - flash - dma + - counter From 10057d54d9f425b0336369d3688eff36748bbec7 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 12:26:10 +0900 Subject: [PATCH 0340/4498] samples: drivers: counter: alarm: Add support for rpi_pico Add the rpi_pico board to the supported boards for the counter alarm sample Signed-off-by: TOKITA Hiroshi --- samples/drivers/counter/alarm/sample.yaml | 1 + samples/drivers/counter/alarm/src/main.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/samples/drivers/counter/alarm/sample.yaml b/samples/drivers/counter/alarm/sample.yaml index d799d04f5f7..fe81529a45b 100644 --- a/samples/drivers/counter/alarm/sample.yaml +++ b/samples/drivers/counter/alarm/sample.yaml @@ -25,6 +25,7 @@ tests: - gd32f470i_eval - stm32h735g_disco - stm32h573i_dk + - rpi_pico integration_platforms: - nucleo_f746zg harness_config: diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index eb19bbdf098..9eee4d3fba2 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -51,6 +51,8 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_NODELABEL(counter0) #elif defined(CONFIG_COUNTER_SNPS_DW) #define TIMER DT_NODELABEL(timer0) +#elif defined(CONFIG_COUNTER_TIMER_RPI_PICO) +#define TIMER DT_NODELABEL(timer) #endif static void test_counter_interrupt_fn(const struct device *counter_dev, From 5119af04225c1693e3e7e9d01bd0bbc227fcb39b Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 21 Apr 2023 21:07:24 +0900 Subject: [PATCH 0341/4498] tests: counter: counter_basic_api: Add support for rpi_pico boards Add support for rpi_pico board. Signed-off-by: TOKITA Hiroshi --- tests/drivers/counter/counter_basic_api/src/test_counter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/drivers/counter/counter_basic_api/src/test_counter.c b/tests/drivers/counter/counter_basic_api/src/test_counter.c index f2677648b25..462de26d037 100644 --- a/tests/drivers/counter/counter_basic_api/src/test_counter.c +++ b/tests/drivers/counter/counter_basic_api/src/test_counter.c @@ -93,6 +93,9 @@ static const struct device *const devices[] = { #ifdef CONFIG_COUNTER_TIMER_GD32 DEVS_FOR_DT_COMPAT(gd_gd32_timer) #endif +#ifdef CONFIG_COUNTER_TIMER_RPI_PICO + DEVS_FOR_DT_COMPAT(raspberrypi_pico_timer) +#endif }; static const struct device *const period_devs[] = { From dbb786dae184ccd4fc6f463027319b5007e0bce8 Mon Sep 17 00:00:00 2001 From: J M Date: Sun, 11 Jun 2023 13:01:18 -0700 Subject: [PATCH 0342/4498] sys: lists: Add list functions to compute list length This commit adds functions to slist, sflist, and dlist to return the length of provided lists, which will allow future commits to refactor code that implements this manually. The new functions all take a reference to any node in the list and compute the length of the entire list. If the list is empty, they return 0. Signed-off-by: J M --- include/zephyr/sys/dlist.h | 18 ++++++++++++++++++ include/zephyr/sys/list_gen.h | 11 +++++++++++ include/zephyr/sys/sflist.h | 11 +++++++++++ include/zephyr/sys/slist.h | 11 +++++++++++ 4 files changed, 51 insertions(+) diff --git a/include/zephyr/sys/dlist.h b/include/zephyr/sys/dlist.h index 0c269f5da92..4c330c8f04e 100644 --- a/include/zephyr/sys/dlist.h +++ b/include/zephyr/sys/dlist.h @@ -534,6 +534,24 @@ static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list) return node; } +/** + * @brief Compute the size of the given list in O(n) time + * + * @param list A pointer on the list + * + * @return an integer equal to the size of the list, or 0 if empty + */ +static inline size_t sys_dlist_len(sys_dlist_t *list) +{ + size_t len = 0; + sys_dnode_t *node = NULL; + + SYS_DLIST_FOR_EACH_NODE(list, node) { + len++; + } + return len; +} + /** @} */ #ifdef __cplusplus diff --git a/include/zephyr/sys/list_gen.h b/include/zephyr/sys/list_gen.h index 6029e4eceb4..f1aa1b3a510 100644 --- a/include/zephyr/sys/list_gen.h +++ b/include/zephyr/sys/list_gen.h @@ -234,4 +234,15 @@ return false; \ } +#define Z_GENLIST_LEN(__lname, __nname) \ + static inline size_t sys_##__lname##_len(sys_##__lname##_t * list) \ + { \ + size_t len = 0; \ + static sys_##__nname##_t * node; \ + Z_GENLIST_FOR_EACH_NODE(__lname, list, node) { \ + len++; \ + } \ + return len; \ + } + #endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */ diff --git a/include/zephyr/sys/sflist.h b/include/zephyr/sys/sflist.h index 307d3497f4e..97580800831 100644 --- a/include/zephyr/sys/sflist.h +++ b/include/zephyr/sys/sflist.h @@ -489,6 +489,17 @@ static inline bool sys_sflist_find_and_remove(sys_sflist_t *list, Z_GENLIST_FIND_AND_REMOVE(sflist, sfnode) +/** + * @brief Compute the size of the given list in O(n) time + * + * @param list A pointer on the list + * + * @return an integer equal to the size of the list, or 0 if empty + */ +static inline size_t sys_sflist_len(sys_sflist_t *list); + +Z_GENLIST_LEN(sflist, sfnode) + /** @} */ #ifdef __cplusplus diff --git a/include/zephyr/sys/slist.h b/include/zephyr/sys/slist.h index 87ef6719159..095c89ffe02 100644 --- a/include/zephyr/sys/slist.h +++ b/include/zephyr/sys/slist.h @@ -420,6 +420,17 @@ Z_GENLIST_REMOVE(slist, snode) static inline bool sys_slist_find_and_remove(sys_slist_t *list, sys_snode_t *node); +/** + * @brief Compute the size of the given list in O(n) time + * + * @param list A pointer on the list + * + * @return an integer equal to the size of the list, or 0 if empty + */ +static inline size_t sys_slist_len(sys_slist_t *list); + +Z_GENLIST_LEN(slist, snode) + /** @} */ Z_GENLIST_FIND_AND_REMOVE(slist, snode) From 9cf437728ec1e0b1d5a6fc482be37e9a3dff6dfb Mon Sep 17 00:00:00 2001 From: J M Date: Sun, 11 Jun 2023 13:02:00 -0700 Subject: [PATCH 0343/4498] sys: lists: Add tests for newly-added list len functions This commit adds tests for the newly added list len APIs to the corresponding test cases. It is noted that the test functions calculate equivalent values manually using several different internal list functions. This has been left unmodified to ensure that the manual ways using each of the various for_each functions results in the same value as the new list_len() functions. Signed-off-by: J M --- tests/unit/list/dlist.c | 8 ++++++++ tests/unit/list/sflist.c | 8 ++++++++ tests/unit/list/slist.c | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/tests/unit/list/dlist.c b/tests/unit/list/dlist.c index dff44b8bb59..937355c13b5 100644 --- a/tests/unit/list/dlist.c +++ b/tests/unit/list/dlist.c @@ -39,6 +39,10 @@ static inline bool verify_emptyness(sys_dlist_t *list) return false; } + if (sys_dlist_len(list) != 0) { + return false; + } + count = 0; SYS_DLIST_FOR_EACH_NODE(list, node) { count++; @@ -97,6 +101,10 @@ static inline bool verify_content_amount(sys_dlist_t *list, int amount) return false; } + if (sys_dlist_len(list) != amount) { + return false; + } + count = 0; SYS_DLIST_FOR_EACH_NODE(list, node) { count++; diff --git a/tests/unit/list/sflist.c b/tests/unit/list/sflist.c index e7d1ff4a199..c0162d00358 100644 --- a/tests/unit/list/sflist.c +++ b/tests/unit/list/sflist.c @@ -40,6 +40,10 @@ static inline bool verify_emptyness(sys_sflist_t *list) return false; } + if (sys_sflist_len(list) != 0) { + return false; + } + count = 0; SYS_SFLIST_FOR_EACH_NODE(list, node) { count++; @@ -98,6 +102,10 @@ static inline bool verify_content_amount(sys_sflist_t *list, int amount) return false; } + if (sys_sflist_len(list) != amount) { + return false; + } + count = 0; SYS_SFLIST_FOR_EACH_NODE(list, node) { count++; diff --git a/tests/unit/list/slist.c b/tests/unit/list/slist.c index 2df65dac4e2..49c4b8257b2 100644 --- a/tests/unit/list/slist.c +++ b/tests/unit/list/slist.c @@ -40,6 +40,10 @@ static inline bool verify_emptyness(sys_slist_t *list) return false; } + if (sys_slist_len(list) != 0) { + return false; + } + count = 0; SYS_SLIST_FOR_EACH_NODE(list, node) { count++; @@ -98,6 +102,10 @@ static inline bool verify_content_amount(sys_slist_t *list, int amount) return false; } + if (sys_slist_len(list) != amount) { + return false; + } + count = 0; SYS_SLIST_FOR_EACH_NODE(list, node) { count++; From 6bd6f4be657ae90e4b09b55d17367d74eaabc18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 13 Sep 2023 12:22:48 +0200 Subject: [PATCH 0344/4498] samples: code_relocation_nocopy: Use nrf_qspi_nor driver to init XIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the Nordic QSPI NOR flash driver instead of the specific code for the nRF5340 DK to initialize the external flash chip for XIP. Signed-off-by: Andrzej Głąbek --- .../code_relocation_nocopy/CMakeLists.txt | 1 - .../boards/nrf5340dk_nrf5340_cpuapp.conf | 5 +- .../nrf5340dk_nrf5340_cpuapp/ext_mem_init.c | 101 ------------------ 3 files changed, 3 insertions(+), 104 deletions(-) delete mode 100644 samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c diff --git a/samples/application_development/code_relocation_nocopy/CMakeLists.txt b/samples/application_development/code_relocation_nocopy/CMakeLists.txt index 0da6192fa11..426979e7c34 100644 --- a/samples/application_development/code_relocation_nocopy/CMakeLists.txt +++ b/samples/application_development/code_relocation_nocopy/CMakeLists.txt @@ -7,7 +7,6 @@ project(code_relocation_nocopy) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) -target_sources_ifdef(CONFIG_NRFX_QSPI app PRIVATE boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c) # Run ext_code from the external flash (XIP). No need to copy. zephyr_code_relocate(FILES src/ext_code.c LOCATION EXTFLASH_TEXT NOCOPY) diff --git a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf index ec92c11f204..ce54de70c69 100644 --- a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,2 +1,3 @@ -CONFIG_NRFX_QSPI=y -CONFIG_NRF_ENABLE_CACHE=n +CONFIG_FLASH=y +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_XIP=y diff --git a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c deleted file mode 100644 index 36610748a59..00000000000 --- a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2022 Nordic Semiconductor ASA. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#define QSPI_STD_CMD_WRSR 0x01 -#define QSPI_STD_CMD_RSTEN 0x66 -#define QSPI_STD_CMD_RST 0x99 - -#define QSPI_NODE DT_NODELABEL(qspi) - -static int qspi_ext_mem_init(void) -{ - - static const nrfx_qspi_config_t qspi_config = { - .prot_if = { - .readoc = NRF_QSPI_READOC_READ4IO, - .writeoc = NRF_QSPI_WRITEOC_PP4IO, - .addrmode = NRF_QSPI_ADDRMODE_24BIT, - }, - .phy_if = { - /* Frequency = PCLK192M / 2 * (sck_freq + 1) -> 32 MHz. - * 33 MHz is the maximum for WRSR, even in the High - * Performance mode. - */ - .sck_freq = 2, - .sck_delay = 0x05, - .spi_mode = NRF_QSPI_MODE_0, - }, - .skip_gpio_cfg = true, - .skip_psel_cfg = true, - }; - static const nrf_qspi_phy_conf_t qspi_phy_48mhz = { - /* After sending WRSR, use 48 MHz (96 MHz cannot be used, - * as 80 MHz is the maximum for the MX25R6435F chip). - */ - .sck_freq = 1, - .sck_delay = 0x05, - .spi_mode = NRF_QSPI_MODE_0, - }; - nrf_qspi_cinstr_conf_t cinstr_cfg = { - .opcode = QSPI_STD_CMD_RSTEN, - .length = NRF_QSPI_CINSTR_LEN_1B, - .io2_level = true, - .io3_level = true, - .wipwait = true, - }; - static const uint8_t flash_chip_cfg[] = { - /* QE (Quad Enable) bit = 1 */ - BIT(6), - 0x00, - /* L/H Switch bit = 1 -> High Performance mode */ - BIT(1), - }; - nrfx_err_t err; - int ret; - - PINCTRL_DT_DEFINE(QSPI_NODE); - - ret = pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(QSPI_NODE), - PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; - } - - err = nrfx_qspi_init(&qspi_config, NULL, NULL); - if (err != NRFX_SUCCESS) { - return -EIO; - } - - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_1); - - /* Send reset enable */ - nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); - - /* Send reset command */ - cinstr_cfg.opcode = QSPI_STD_CMD_RST; - nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); - - /* Switch to Quad I/O and High Performance mode */ - cinstr_cfg.opcode = QSPI_STD_CMD_WRSR; - cinstr_cfg.wren = true; - cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B; - nrfx_qspi_cinstr_xfer(&cinstr_cfg, &flash_chip_cfg, NULL); - - nrf_qspi_ifconfig1_set(NRF_QSPI, &qspi_phy_48mhz); - - /* Enable XiP */ - nrf_qspi_xip_set(NRF_QSPI, true); - - return 0; -} - -SYS_INIT(qspi_ext_mem_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); From e3ee5c09f2cea3e71c4711001ef6313f8bee1781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 13 Sep 2023 12:39:02 +0200 Subject: [PATCH 0345/4498] samples: code_relocation_nocopy: Make linker script more generic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of depending on the nRF5340 DK, use a path specific to just the nRF5340 SoC and get the size of the external flash in this case from devicetree so that the sample could be easily run on other boards based on the nRF5340 SoC (after just adding proper overlays). On the occasion, correct the attributes of the EXTFLASH memory region. Signed-off-by: Andrzej Głąbek --- .../linker_arm_nocopy.ld | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld index 934f928596c..916b1efe7fa 100644 --- a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld +++ b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld @@ -17,16 +17,14 @@ #include #include -#if CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP +#if defined(CONFIG_NORDIC_QSPI_NOR) && defined(CONFIG_SOC_NRF5340_CPUAPP) -/* - * nRF5340dk is shipping a QSPI external flash mapped at 0x1000_0000 that can - * be used for XIP - */ -MEMORY -{ - EXTFLASH (wx) : ORIGIN = 0x10000000, LENGTH = 0x800000 -} +/* On nRF5340, external flash is mapped in XIP region at 0x1000_0000. */ + +#define EXTFLASH_NODE DT_INST(0, nordic_qspi_nor) +#define EXTFLASH_ADDR 0x10000000 +#define EXTFLASH_SIZE DT_PROP_OR(EXTFLASH_NODE, size_in_bytes, \ + DT_PROP(EXTFLASH_NODE, size) / 8) #else @@ -37,11 +35,11 @@ MEMORY #define EXTFLASH_ADDR 0x5000 #define EXTFLASH_SIZE (CONFIG_FLASH_SIZE * 1K - EXTFLASH_ADDR) +#endif + MEMORY { - EXTFLASH (wx) : ORIGIN = 0x5000, LENGTH = EXTFLASH_SIZE + EXTFLASH (rx) : ORIGIN = EXTFLASH_ADDR, LENGTH = EXTFLASH_SIZE } -#endif /* CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP */ - #include From a85ffa8130e4cd457f7119794c6ea57b608f0f45 Mon Sep 17 00:00:00 2001 From: Mourad Kharrazi Date: Fri, 30 Jun 2023 13:12:21 +0200 Subject: [PATCH 0346/4498] drivers: sdhc: allow bandwidth selection The current implementation uses both, host and card capabilites to derive the maximum bus width to be used. However, in cases where a MMC device is not connected to the host via shdc using the full bus width of 8 lines, device initialization fails. Introducing the `bus-width` property circumvents this by reducing the host bus capabilites and forcing communication with the MMC device using 1, 4 or 8 lines. Signed-off-by: Mourad Kharrazi --- drivers/disk/mmc_subsys.c | 4 ++++ dts/bindings/sd/zephyr,mmc-disk.yaml | 12 ++++++++++++ include/zephyr/sd/sd.h | 1 + subsys/sd/mmc.c | 4 ++-- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/disk/mmc_subsys.c b/drivers/disk/mmc_subsys.c index 8af8a01991e..455d56818d3 100644 --- a/drivers/disk/mmc_subsys.c +++ b/drivers/disk/mmc_subsys.c @@ -21,6 +21,7 @@ enum sd_status { struct mmc_config { const struct device *host_controller; + uint8_t bus_width; }; struct mmc_data { @@ -104,8 +105,10 @@ static struct disk_info mmc_disk = { static int disk_mmc_init(const struct device *dev) { struct mmc_data *data = dev->data; + const struct mmc_config *config = dev->config; data->status = SD_UNINIT; + data->card.bus_width = config->bus_width; mmc_disk.dev = dev; mmc_disk.name = data->name; @@ -115,6 +118,7 @@ static int disk_mmc_init(const struct device *dev) #define DISK_ACCESS_MMC_INIT(n) \ static const struct mmc_config mmc_config_##n = { \ .host_controller = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .bus_width = DT_INST_PROP(n, bus_width), \ }; \ \ static struct mmc_data mmc_data_##n = { \ diff --git a/dts/bindings/sd/zephyr,mmc-disk.yaml b/dts/bindings/sd/zephyr,mmc-disk.yaml index a5167721686..f702b341e1a 100644 --- a/dts/bindings/sd/zephyr,mmc-disk.yaml +++ b/dts/bindings/sd/zephyr,mmc-disk.yaml @@ -7,3 +7,15 @@ description: | compatible: "zephyr,mmc-disk" include: [sd-device.yaml] + +properties: + bus-width: + type: int + default: 8 + description: | + Indicates the way the MMC device is connected to the bus. + Defaults to the maximum possible number of bus lines. + enum: + - 1 + - 4 + - 8 diff --git a/include/zephyr/sd/sd.h b/include/zephyr/sd/sd.h index e73777873c5..a93aec5f012 100644 --- a/include/zephyr/sd/sd.h +++ b/include/zephyr/sd/sd.h @@ -64,6 +64,7 @@ struct sd_card { enum card_status status; /*!< Card status */ enum card_type type; /*!< Card type */ uint16_t flags; /*!< Card flags */ + uint8_t bus_width; /*!< Desired bus width */ uint8_t card_buffer[CONFIG_SD_BUFFER_SIZE] __aligned(CONFIG_SDHC_BUFFER_ALIGNMENT); /* Card internal buffer */ }; diff --git a/subsys/sd/mmc.c b/subsys/sd/mmc.c index eada1ec261f..8ea0b5746d7 100644 --- a/subsys/sd/mmc.c +++ b/subsys/sd/mmc.c @@ -380,10 +380,10 @@ static int mmc_set_bus_width(struct sd_card *card) int ret; struct sdhc_command cmd = {0}; - if (card->host_props.host_caps.bus_8_bit_support) { + if (card->host_props.host_caps.bus_8_bit_support && card->bus_width == 8) { cmd.arg = MMC_SWITCH_8_BIT_BUS_ARG; card->bus_io.bus_width = SDHC_BUS_WIDTH8BIT; - } else if (card->host_props.host_caps.bus_4_bit_support) { + } else if (card->host_props.host_caps.bus_4_bit_support && card->bus_width >= 4) { cmd.arg = MMC_SWITCH_4_BIT_BUS_ARG; card->bus_io.bus_width = SDHC_BUS_WIDTH4BIT; } else { From 25d82ddead48c1acd780e3801a947fc042d0d5e7 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 13 Sep 2023 12:10:38 +0200 Subject: [PATCH 0347/4498] cmake: armclang version detection The armclang version detection introduced in #55133 does not correctly detect a valid ARM Compiler (armclang) installation in all situations. When ARM Compiler for Embedded is installed as part of ARM-DS or Keil, then it may report itself in following output: > Product: Arm Development Studio ... . > Component: ARM Compiler x.y(.z) > Tool: armclang [...] > > Target: ... Correct the version extraction by turning each line into a list of strings which can then be looped to find the ARM compiler component to ensure the correct line is used for retrieving the version information. Signed-off-by: Torsten Rasmussen --- cmake/modules/Findarmclang.cmake | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findarmclang.cmake b/cmake/modules/Findarmclang.cmake index a84a04f163b..e0f9d6e3c1d 100644 --- a/cmake/modules/Findarmclang.cmake +++ b/cmake/modules/Findarmclang.cmake @@ -16,8 +16,16 @@ include(FindPackageHandleStandardArgs) if(CMAKE_C_COMPILER) # Parse the 'clang --version' output to find the installed version. - execute_process(COMMAND ${CMAKE_C_COMPILER} --target=${triple} --version OUTPUT_VARIABLE ARMCLANG_VERSION) - string(REGEX REPLACE "[^0-9]*([0-9.]+) .*" "\\1" ARMCLANG_VERSION ${ARMCLANG_VERSION}) + execute_process(COMMAND ${CMAKE_C_COMPILER} --target=${triple} --version OUTPUT_VARIABLE ARMCLANG_VERSION ERROR_QUIET) + string(REPLACE "\n" ";" armclang_version_list "${ARMCLANG_VERSION}") + set(ARMCLANG_VERSION ARMCLANG_VERSION-NOTFOUND) + foreach(line ${armclang_version_list}) + # Compiler version is either terminated directly, or followed by space and extra build info. + if(line MATCHES ".*[aA]rm [cC]ompiler[^0-9]*([0-9.]+)($| .*$)") + set(ARMCLANG_VERSION "${CMAKE_MATCH_1}") + break() + endif() + endforeach() endif() find_package_handle_standard_args(armclang From 829b91ab2f96e1b2455ddd5cc5e281be0f561b88 Mon Sep 17 00:00:00 2001 From: Rick Talbott Date: Fri, 23 Jun 2023 14:33:08 -0600 Subject: [PATCH 0348/4498] shell: Fix scrolling long commands in history This fixes scrolling long commands in command history in the shell Signed-off-by: Rick Talbott --- subsys/shell/shell_ops.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/subsys/shell/shell_ops.c b/subsys/shell/shell_ops.c index db68c62155b..7b9af71e417 100644 --- a/subsys/shell/shell_ops.c +++ b/subsys/shell/shell_ops.c @@ -367,7 +367,29 @@ static void print_prompt(const struct shell *sh) void z_shell_print_cmd(const struct shell *sh) { - z_shell_raw_fprintf(sh->fprintf_ctx, "%s", sh->ctx->cmd_buff); + int beg_offset = 0; + int end_offset = 0; + int cmd_width = z_shell_strlen(sh->ctx->cmd_buff); + int adjust = sh->ctx->vt100_ctx.cons.name_len; + char ch; + + while (cmd_width > sh->ctx->vt100_ctx.cons.terminal_wid - adjust) { + end_offset += sh->ctx->vt100_ctx.cons.terminal_wid - adjust; + ch = sh->ctx->cmd_buff[end_offset]; + sh->ctx->cmd_buff[end_offset] = '\0'; + + z_shell_raw_fprintf(sh->fprintf_ctx, "%s\n", + &sh->ctx->cmd_buff[beg_offset]); + + sh->ctx->cmd_buff[end_offset] = ch; + cmd_width -= (sh->ctx->vt100_ctx.cons.terminal_wid - adjust); + beg_offset = end_offset; + adjust = 0; + } + if (cmd_width > 0) { + z_shell_raw_fprintf(sh->fprintf_ctx, "%s", + &sh->ctx->cmd_buff[beg_offset]); + } } void z_shell_print_prompt_and_cmd(const struct shell *sh) From cb76aab9d35ed9a9fc000f065402c6f079356c95 Mon Sep 17 00:00:00 2001 From: Andreas Wiesinger Date: Tue, 1 Aug 2023 13:06:59 +0200 Subject: [PATCH 0349/4498] dts: sensor: bosch,bmi270: Move interrupt handling to parent binding Moved the interrupt handling code from a bus-specific binding file to the parent binding file. This modification ensures that interrupt handling, which is inherently independent of the type of BUS used (either i2c or spi), is located in the appropriate location within the code. Previously, this code was found in a bus-specific file, despite its functionality being applicable to all buses. This change ensures a more logical placement and will help to maintain coherence within the codebase. This change aligns with the existing implementation where the interrupt handling code already operates independently of the BUS type. Tested this on a nrf52840 with a bmi270 on spi bus with the sample from zephyr/samples/sensor/bmi270 by adding an interrupt handler in main.c which uses the bmi270_trigger.c implementation and verified this with breakpoints and log output. Added the irq-gpios to tests/drivers/build_all/sensor/i2c.dtsi and tests/drivers/build_all/sensor/spi.dtsi and fixed whitespace formatting. Fixes: #58843 Signed-off-by: Andreas Wiesinger --- dts/bindings/sensor/bosch,bmi270-i2c.yaml | 6 ------ dts/bindings/sensor/bosch,bmi270.yaml | 6 ++++++ tests/drivers/build_all/sensor/i2c.dtsi | 1 + tests/drivers/build_all/sensor/spi.dtsi | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dts/bindings/sensor/bosch,bmi270-i2c.yaml b/dts/bindings/sensor/bosch,bmi270-i2c.yaml index 6a487405585..ca21ba4f3ea 100644 --- a/dts/bindings/sensor/bosch,bmi270-i2c.yaml +++ b/dts/bindings/sensor/bosch,bmi270-i2c.yaml @@ -5,9 +5,3 @@ compatible: "bosch,bmi270" include: [i2c-device.yaml, "bosch,bmi270.yaml"] - -properties: - irq-gpios: - type: phandle-array - description: | - The INT1 and (optional) INT2 signal connections. diff --git a/dts/bindings/sensor/bosch,bmi270.yaml b/dts/bindings/sensor/bosch,bmi270.yaml index 2b50c164e46..8b486f2bcab 100644 --- a/dts/bindings/sensor/bosch,bmi270.yaml +++ b/dts/bindings/sensor/bosch,bmi270.yaml @@ -9,3 +9,9 @@ description: | include: sensor-device.yaml compatible: "bosch,bmi270" + +properties: + irq-gpios: + type: phandle-array + description: | + The INT1 and (optional) INT2 signal connections. diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index d654b93ff15..9b04fc5226f 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -528,6 +528,7 @@ test_i2c_bmi160: bmi160@52 { test_i2c_bmi270: bmi270@53 { compatible = "bosch,bmi270"; reg = <0x53>; + irq-gpios = <&test_gpio 0 0>; }; test_i2c_fdc2x1x: fdc2x1x@54 { diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index 246ecd50dd7..d6764f14d9b 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -162,6 +162,7 @@ test_spi_bmi270: bmi270@15 { compatible = "bosch,bmi270"; reg = <0x15>; spi-max-frequency = <0>; + irq-gpios = <&test_gpio 0 0>; }; test_spi_bmp388: bmp388@16 { From 75bc80d86f3a36284109c8339a8b67495f0ebea0 Mon Sep 17 00:00:00 2001 From: Benjamin Lemouzy Date: Fri, 23 Jun 2023 14:36:47 +0200 Subject: [PATCH 0350/4498] drivers: audio: tas6422dac: add driver Add Texas Instruments TAS6422 DAC driver. Signed-off-by: Benjamin Lemouzy --- drivers/audio/CMakeLists.txt | 1 + drivers/audio/Kconfig | 1 + drivers/audio/Kconfig.tas6422dac | 11 + drivers/audio/tas6422dac.c | 379 ++++++++++++++++++++++++++ drivers/audio/tas6422dac.h | 262 ++++++++++++++++++ dts/bindings/audio/ti,tas6422dac.yaml | 12 + 6 files changed, 666 insertions(+) create mode 100644 drivers/audio/Kconfig.tas6422dac create mode 100644 drivers/audio/tas6422dac.c create mode 100644 drivers/audio/tas6422dac.h create mode 100644 dts/bindings/audio/ti,tas6422dac.yaml diff --git a/drivers/audio/CMakeLists.txt b/drivers/audio/CMakeLists.txt index 73cda8192ac..b1802f9cf26 100644 --- a/drivers/audio/CMakeLists.txt +++ b/drivers/audio/CMakeLists.txt @@ -6,3 +6,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_TLV320DAC tlv320dac310x.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy-i2s.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_NRFX_PDM dmic_nrfx_pdm.c) +zephyr_library_sources_ifdef(CONFIG_AUDIO_TAS6422DAC tas6422dac.c) diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index 2eb98256aac..a45e003f80a 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -29,6 +29,7 @@ module = AUDIO_CODEC module-str = audio codec source "subsys/logging/Kconfig.template.log_config" +source "drivers/audio/Kconfig.tas6422dac" source "drivers/audio/Kconfig.tlv320dac" endif # AUDIO_CODEC diff --git a/drivers/audio/Kconfig.tas6422dac b/drivers/audio/Kconfig.tas6422dac new file mode 100644 index 00000000000..1977e7b6331 --- /dev/null +++ b/drivers/audio/Kconfig.tas6422dac @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Centralp +# SPDX-License-Identifier: Apache-2.0 + +config AUDIO_TAS6422DAC + bool "TAS6422 audio amplifier support" + default y + depends on DT_HAS_TI_TAS6422DAC_ENABLED + select I2C + depends on GPIO + help + Enable TAS6422 support on the selected board diff --git a/drivers/audio/tas6422dac.c b/drivers/audio/tas6422dac.c new file mode 100644 index 00000000000..91c36de2897 --- /dev/null +++ b/drivers/audio/tas6422dac.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2023 Centralp + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tas6422dac + +#include +#include +#include +#include + +#include "tas6422dac.h" + +#define LOG_LEVEL CONFIG_AUDIO_CODEC_LOG_LEVEL +#include +LOG_MODULE_REGISTER(tas6422dac); + +#define TAS6422DAC_MUTE_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(mute_gpios) + +#define CODEC_OUTPUT_VOLUME_MAX (24 * 2) +#define CODEC_OUTPUT_VOLUME_MIN (-100 * 2) + +struct codec_driver_config { + struct i2c_dt_spec bus; +#if TAS6422DAC_MUTE_GPIO_SUPPORT + struct gpio_dt_spec mute_gpio; +#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */ +}; + +struct codec_driver_data { +}; + +enum tas6422dac_channel_t { + TAS6422DAC_CHANNEL_1, + TAS6422DAC_CHANNEL_2, + TAS6422DAC_CHANNEL_ALL, + TAS6422DAC_CHANNEL_UNKNOWN, +}; + +static enum tas6422dac_channel_t audio_to_tas6422dac_channel[] = { + [AUDIO_CHANNEL_FRONT_LEFT] = TAS6422DAC_CHANNEL_1, + [AUDIO_CHANNEL_FRONT_RIGHT] = TAS6422DAC_CHANNEL_2, + [AUDIO_CHANNEL_LFE] = TAS6422DAC_CHANNEL_UNKNOWN, + [AUDIO_CHANNEL_FRONT_CENTER] = TAS6422DAC_CHANNEL_UNKNOWN, + [AUDIO_CHANNEL_REAR_LEFT] = TAS6422DAC_CHANNEL_1, + [AUDIO_CHANNEL_REAR_RIGHT] = TAS6422DAC_CHANNEL_2, + [AUDIO_CHANNEL_REAR_CENTER] = TAS6422DAC_CHANNEL_UNKNOWN, + [AUDIO_CHANNEL_SIDE_LEFT] = TAS6422DAC_CHANNEL_1, + [AUDIO_CHANNEL_SIDE_RIGHT] = TAS6422DAC_CHANNEL_2, + [AUDIO_CHANNEL_ALL] = TAS6422DAC_CHANNEL_ALL, +}; + +static void codec_mute_output(const struct device *dev, enum tas6422dac_channel_t channel); +static void codec_unmute_output(const struct device *dev, enum tas6422dac_channel_t channel); +static void codec_write_reg(const struct device *dev, uint8_t reg, uint8_t val); +static void codec_read_reg(const struct device *dev, uint8_t reg, uint8_t *val); +static void codec_soft_reset(const struct device *dev); +static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg); +static void codec_configure_output(const struct device *dev); +static int codec_set_output_volume(const struct device *dev, enum tas6422dac_channel_t channel, + int vol); + +#if (LOG_LEVEL >= LOG_LEVEL_DEBUG) +static void codec_read_all_regs(const struct device *dev); +#define CODEC_DUMP_REGS(dev) codec_read_all_regs((dev)) +#else +#define CODEC_DUMP_REGS(dev) +#endif + +static int codec_initialize(const struct device *dev) +{ + const struct codec_driver_config *const dev_cfg = dev->config; + + if (!device_is_ready(dev_cfg->bus.bus)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + +#if TAS6422DAC_MUTE_GPIO_SUPPORT + if (!device_is_ready(dev_cfg->mute_gpio.port)) { + LOG_ERR("GPIO device not ready"); + return -ENODEV; + } +#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */ + + return 0; +} + +static int codec_configure(const struct device *dev, struct audio_codec_cfg *cfg) +{ + int ret; + + if (cfg->dai_type != AUDIO_DAI_TYPE_I2S) { + LOG_ERR("dai_type must be AUDIO_DAI_TYPE_I2S"); + return -EINVAL; + } + + codec_soft_reset(dev); + ret = codec_configure_dai(dev, &cfg->dai_cfg); + codec_configure_output(dev); + + return ret; +} + +static void codec_start_output(const struct device *dev) +{ + codec_unmute_output(dev, TAS6422DAC_CHANNEL_ALL); + + CODEC_DUMP_REGS(dev); +} + +static void codec_stop_output(const struct device *dev) +{ + codec_mute_output(dev, TAS6422DAC_CHANNEL_ALL); +} + +static void codec_mute_output(const struct device *dev, enum tas6422dac_channel_t channel) +{ + uint8_t val; + +#if TAS6422DAC_MUTE_GPIO_SUPPORT + const struct codec_driver_config *const dev_cfg = dev->config; + + gpio_pin_configure_dt(&dev_cfg->mute_gpio, GPIO_OUTPUT_ACTIVE); +#endif + + codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val); + switch (channel) { + case TAS6422DAC_CHANNEL_1: + val &= ~CH_STATE_CTRL_CH1_STATE_CTRL_MASK; + val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_MUTE); + break; + case TAS6422DAC_CHANNEL_2: + val &= ~CH_STATE_CTRL_CH2_STATE_CTRL_MASK; + val |= CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_MUTE); + break; + case TAS6422DAC_CHANNEL_ALL: + val &= ~(CH_STATE_CTRL_CH1_STATE_CTRL_MASK | CH_STATE_CTRL_CH2_STATE_CTRL_MASK); + val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_MUTE) | + CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_MUTE); + break; + case TAS6422DAC_CHANNEL_UNKNOWN: + default: + LOG_ERR("Invalid codec channel %u", channel); + return; + } + codec_write_reg(dev, CH_STATE_CTRL_ADDR, val); +} + +static void codec_unmute_output(const struct device *dev, enum tas6422dac_channel_t channel) +{ + uint8_t val; + +#if TAS6422DAC_MUTE_GPIO_SUPPORT + const struct codec_driver_config *const dev_cfg = dev->config; + + gpio_pin_configure_dt(&dev_cfg->mute_gpio, GPIO_OUTPUT_INACTIVE); +#endif + + codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val); + switch (channel) { + case TAS6422DAC_CHANNEL_1: + val &= ~CH_STATE_CTRL_CH1_STATE_CTRL_MASK; + val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_PLAY); + break; + case TAS6422DAC_CHANNEL_2: + val &= ~CH_STATE_CTRL_CH2_STATE_CTRL_MASK; + val |= CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_PLAY); + break; + case TAS6422DAC_CHANNEL_ALL: + val &= ~(CH_STATE_CTRL_CH1_STATE_CTRL_MASK | CH_STATE_CTRL_CH2_STATE_CTRL_MASK); + val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_PLAY) | + CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_PLAY); + break; + case TAS6422DAC_CHANNEL_UNKNOWN: + default: + LOG_ERR("Invalid codec channel %u", channel); + return; + } + codec_write_reg(dev, CH_STATE_CTRL_ADDR, val); +} + +static int codec_set_property(const struct device *dev, audio_property_t property, + audio_channel_t channel, audio_property_value_t val) +{ + enum tas6422dac_channel_t codec_channel = audio_to_tas6422dac_channel[channel]; + + if (codec_channel == TAS6422DAC_CHANNEL_UNKNOWN) { + LOG_ERR("Invalid channel %u", channel); + return -EINVAL; + } + + switch (property) { + case AUDIO_PROPERTY_OUTPUT_VOLUME: + return codec_set_output_volume(dev, codec_channel, val.vol); + + case AUDIO_PROPERTY_OUTPUT_MUTE: + if (val.mute) { + codec_mute_output(dev, codec_channel); + } else { + codec_unmute_output(dev, codec_channel); + } + return 0; + + default: + break; + } + + return -EINVAL; +} + +static int codec_apply_properties(const struct device *dev) +{ + /* nothing to do because there is nothing cached */ + return 0; +} + +static void codec_write_reg(const struct device *dev, uint8_t reg, uint8_t val) +{ + const struct codec_driver_config *const dev_cfg = dev->config; + + i2c_reg_write_byte_dt(&dev_cfg->bus, reg, val); + LOG_DBG("%s WR REG:0x%02x VAL:0x%02x", dev->name, reg, val); +} + +static void codec_read_reg(const struct device *dev, uint8_t reg, uint8_t *val) +{ + const struct codec_driver_config *const dev_cfg = dev->config; + + i2c_reg_read_byte_dt(&dev_cfg->bus, reg, val); + LOG_DBG("%s RD REG:0x%02x VAL:0x%02x", dev->name, reg, *val); +} + +static void codec_soft_reset(const struct device *dev) +{ + uint8_t val; + + codec_read_reg(dev, MODE_CTRL_ADDR, &val); + val |= MODE_CTRL_RESET; + codec_write_reg(dev, MODE_CTRL_ADDR, val); +} + +static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg) +{ + uint8_t val; + + codec_read_reg(dev, SAP_CTRL_ADDR, &val); + + /* I2S mode */ + val &= ~SAP_CTRL_INPUT_FORMAT_MASK; + val |= SAP_CTRL_INPUT_FORMAT(SAP_CTRL_INPUT_FORMAT_I2S); + + /* Input sampling rate */ + val &= ~SAP_CTRL_INPUT_SAMPLING_RATE_MASK; + switch (cfg->i2s.frame_clk_freq) { + case AUDIO_PCM_RATE_44P1K: + val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_44_1_KHZ); + break; + case AUDIO_PCM_RATE_48K: + val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_48_KHZ); + break; + case AUDIO_PCM_RATE_96K: + val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_96_KHZ); + break; + default: + LOG_ERR("Invalid sampling rate %zu", cfg->i2s.frame_clk_freq); + return -EINVAL; + } + + codec_write_reg(dev, SAP_CTRL_ADDR, val); + + return 0; +} + +static void codec_configure_output(const struct device *dev) +{ + uint8_t val; + + /* Overcurrent level = 1 */ + codec_read_reg(dev, MISC_CTRL_1_ADDR, &val); + val &= ~MISC_CTRL_1_OC_CONTROL_MASK; + codec_write_reg(dev, MISC_CTRL_1_ADDR, val); + + /* + * PWM frequency = 10 fs + * Reduce PWM frequency to prevent component overtemperature + */ + codec_read_reg(dev, MISC_CTRL_2_ADDR, &val); + val &= ~MISC_CTRL_2_PWM_FREQUENCY_MASK; + val |= MISC_CTRL_2_PWM_FREQUENCY(MISC_CTRL_2_PWM_FREQUENCY_10_FS); + codec_write_reg(dev, MISC_CTRL_2_ADDR, val); +} + +static int codec_set_output_volume(const struct device *dev, enum tas6422dac_channel_t channel, + int vol) +{ + uint8_t vol_val; + + if ((vol > CODEC_OUTPUT_VOLUME_MAX) || (vol < CODEC_OUTPUT_VOLUME_MIN)) { + LOG_ERR("Invalid volume %d.%d dB", vol >> 1, ((uint32_t)vol & 1) ? 5 : 0); + return -EINVAL; + } + + vol_val = vol + 0xcf; + switch (channel) { + case TAS6422DAC_CHANNEL_1: + codec_write_reg(dev, CH1_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val)); + break; + case TAS6422DAC_CHANNEL_2: + codec_write_reg(dev, CH2_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val)); + break; + case TAS6422DAC_CHANNEL_ALL: + codec_write_reg(dev, CH1_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val)); + codec_write_reg(dev, CH2_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val)); + break; + case TAS6422DAC_CHANNEL_UNKNOWN: + default: + LOG_ERR("Invalid codec channel %u", channel); + return -EINVAL; + } + + return 0; +} + +#if (LOG_LEVEL >= LOG_LEVEL_DEBUG) +static void codec_read_all_regs(const struct device *dev) +{ + uint8_t val; + + codec_read_reg(dev, MODE_CTRL_ADDR, &val); + codec_read_reg(dev, MISC_CTRL_1_ADDR, &val); + codec_read_reg(dev, MISC_CTRL_2_ADDR, &val); + codec_read_reg(dev, SAP_CTRL_ADDR, &val); + codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val); + codec_read_reg(dev, CH1_VOLUME_CTRL_ADDR, &val); + codec_read_reg(dev, CH2_VOLUME_CTRL_ADDR, &val); + codec_read_reg(dev, DC_LDG_CTRL_1_ADDR, &val); + codec_read_reg(dev, DC_LDG_CTRL_2_ADDR, &val); + codec_read_reg(dev, DC_LDG_REPORT_1_ADDR, &val); + codec_read_reg(dev, DC_LDG_REPORT_3_ADDR, &val); + codec_read_reg(dev, CH_FAULTS_ADDR, &val); + codec_read_reg(dev, GLOBAL_FAULTS_1_ADDR, &val); + codec_read_reg(dev, GLOBAL_FAULTS_2_ADDR, &val); + codec_read_reg(dev, WARNINGS_ADDR, &val); + codec_read_reg(dev, PIN_CTRL_ADDR, &val); + codec_read_reg(dev, MISC_CTRL_3_ADDR, &val); + codec_read_reg(dev, ILIMIT_STATUS_ADDR, &val); + codec_read_reg(dev, MISC_CTRL_4_ADDR, &val); + codec_read_reg(dev, MISC_CTRL_5_ADDR, &val); +} +#endif + +static const struct audio_codec_api codec_driver_api = { + .configure = codec_configure, + .start_output = codec_start_output, + .stop_output = codec_stop_output, + .set_property = codec_set_property, + .apply_properties = codec_apply_properties, +}; + +#if TAS6422DAC_MUTE_GPIO_SUPPORT +#define TAS6422DAC_MUTE_GPIO_INIT(n) .mute_gpio = GPIO_DT_SPEC_INST_GET(n, mute_gpios) +#else +#define TAS6422DAC_MUTE_GPIO_INIT(n) +#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */ + +#define TAS6422DAC_INIT(n) \ + static struct codec_driver_data codec_device_data_##n; \ + \ + static struct codec_driver_config codec_device_config_##n = { \ + .bus = I2C_DT_SPEC_INST_GET(n), TAS6422DAC_MUTE_GPIO_INIT(n)}; \ + \ + DEVICE_DT_INST_DEFINE(n, codec_initialize, NULL, &codec_device_data_##n, \ + &codec_device_config_##n, POST_KERNEL, \ + CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TAS6422DAC_INIT) diff --git a/drivers/audio/tas6422dac.h b/drivers/audio/tas6422dac.h new file mode 100644 index 00000000000..84ec0872636 --- /dev/null +++ b/drivers/audio/tas6422dac.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2023 Centralp + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_ +#define ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Mode Control Register */ +#define MODE_CTRL_ADDR 0x00 +#define MODE_CTRL_RESET BIT(7) +#define MODE_CTRL_RESET_MASK BIT(7) +#define MODE_CTRL_PBTL_CH12 BIT(4) +#define MODE_CTRL_PBTL_CH12_MASK BIT(4) +#define MODE_CTRL_CH1_LO_MODE BIT(3) +#define MODE_CTRL_CH1_LO_MODE_MASK BIT(3) +#define MODE_CTRL_CH2_LO_MODE BIT(2) +#define MODE_CTRL_CH2_LO_MODE_MASK BIT(2) + +/* Miscellaneous Control 1 Register */ +#define MISC_CTRL_1_ADDR 0x01 +#define MISC_CTRL_1_HPF_BYPASS BIT(7) +#define MISC_CTRL_1_HPF_BYPASS_MASK BIT(7) +#define MISC_CTRL_1_OTW_CONTROL_MASK (BIT_MASK(2) << 5) +#define MISC_CTRL_1_OTW_CONTROL(val) (((val) << 5) & MISC_CTRL_1_OTW_CONTROL_MASK) +#define MISC_CTRL_1_OTW_CONTROL_140_DEGREE 0 +#define MISC_CTRL_1_OTW_CONTROL_130_DEGREE 1 +#define MISC_CTRL_1_OTW_CONTROL_120_DEGREE 2 +#define MISC_CTRL_1_OTW_CONTROL_110_DEGREE 3 +#define MISC_CTRL_1_OC_CONTROL BIT(4) +#define MISC_CTRL_1_OC_CONTROL_MASK BIT(4) +#define MISC_CTRL_1_VOLUME_RATE_MASK (BIT_MASK(2) << 2) +#define MISC_CTRL_1_VOLUME_RATE(val) (((val) << 2) & MISC_CTRL_1_VOLUME_RATE_MASK) +#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_1_FSYNC 0 +#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_2_FSYNC 1 +#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_4_FSYNC 2 +#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_8_FSYNC 3 +#define MISC_CTRL_1_GAIN_MASK BIT_MASK(2) +#define MISC_CTRL_1_GAIN(val) ((val) & MISC_CTRL_1_GAIN_MASK) +#define MISC_CTRL_1_GAIN_7_5_V_PEAK_OUTPUT 0 +#define MISC_CTRL_1_GAIN_15_V_PEAK_OUTPUT 1 +#define MISC_CTRL_1_GAIN_21_V_PEAK_OUTPUT 2 +#define MISC_CTRL_1_GAIN_29_V_PEAK_OUTPUT 3 + +/* Miscellaneous Control 2 Register */ +#define MISC_CTRL_2_ADDR 0x02 +#define MISC_CTRL_2_PWM_FREQUENCY_MASK (BIT_MASK(3) << 4) +#define MISC_CTRL_2_PWM_FREQUENCY(val) (((val) << 4) & MISC_CTRL_2_PWM_FREQUENCY_MASK) +#define MISC_CTRL_2_PWM_FREQUENCY_8_FS 0 +#define MISC_CTRL_2_PWM_FREQUENCY_10_FS 1 +#define MISC_CTRL_2_PWM_FREQUENCY_38_FS 5 +#define MISC_CTRL_2_PWM_FREQUENCY_44_FS 6 +#define MISC_CTRL_2_PWM_FREQUENCY_48_FS 7 +#define MISC_CTRL_2_SDM_OSR BIT(2) +#define MISC_CTRL_2_SDM_OSR_MASK BIT(2) +#define MISC_CTRL_2_OUTPUT_PHASE_MASK BIT_MASK(2) +#define MISC_CTRL_2_OUTPUT_PHASE(val) ((val) & MISC_CTRL_2_OUTPUT_PHASE_MASK) +#define MISC_CTRL_2_OUTPUT_PHASE_210_DEGREES 1 +#define MISC_CTRL_2_OUTPUT_PHASE_225_DEGREES 2 +#define MISC_CTRL_2_OUTPUT_PHASE_240_DEGREES 3 + +/* Serial Audio-Port Control Register */ +#define SAP_CTRL_ADDR 0x03 +#define SAP_CTRL_INPUT_SAMPLING_RATE_MASK (BIT_MASK(2) << 6) +#define SAP_CTRL_INPUT_SAMPLING_RATE(val) (((val) << 6) & SAP_CTRL_INPUT_SAMPLING_RATE_MASK) +#define SAP_CTRL_INPUT_SAMPLING_RATE_44_1_KHZ 0 +#define SAP_CTRL_INPUT_SAMPLING_RATE_48_KHZ 1 +#define SAP_CTRL_INPUT_SAMPLING_RATE_96_KHZ 2 +#define SAP_CTRL_TDM_SLOT_SELECT BIT(5) +#define SAP_CTRL_TDM_SLOT_SELECT_MASK BIT(5) +#define SAP_CTRL_TDM_SLOT_SIZE BIT(4) +#define SAP_CTRL_TDM_SLOT_SIZE_MASK BIT(4) +#define SAP_CTRL_TDM_SLOT_SELECT_2 BIT(3) +#define SAP_CTRL_TDM_SLOT_SELECT_2_MASK BIT(3) +#define SAP_CTRL_INPUT_FORMAT_MASK BIT_MASK(3) +#define SAP_CTRL_INPUT_FORMAT(val) ((val) & SAP_CTRL_INPUT_FORMAT_MASK) +#define SAP_CTRL_INPUT_FORMAT_24_BITS_RIGHT 0 +#define SAP_CTRL_INPUT_FORMAT_20_BITS_RIGHT 1 +#define SAP_CTRL_INPUT_FORMAT_18_BITS_RIGHT 2 +#define SAP_CTRL_INPUT_FORMAT_16_BITS_RIGHT 3 +#define SAP_CTRL_INPUT_FORMAT_I2S 4 +#define SAP_CTRL_INPUT_FORMAT_LEFT 5 +#define SAP_CTRL_INPUT_FORMAT_DSP 6 + +/* Channel State Control Register */ +#define CH_STATE_CTRL_ADDR 0x04 +#define CH_STATE_CTRL_CH1_STATE_CTRL_MASK (BIT_MASK(2) << 6) +#define CH_STATE_CTRL_CH1_STATE_CTRL(val) (((val) << 6) & CH_STATE_CTRL_CH1_STATE_CTRL_MASK) +#define CH_STATE_CTRL_CH2_STATE_CTRL_MASK (BIT_MASK(2) << 4) +#define CH_STATE_CTRL_CH2_STATE_CTRL(val) (((val) << 4) & CH_STATE_CTRL_CH2_STATE_CTRL_MASK) +#define CH_STATE_CTRL_PLAY 0 +#define CH_STATE_CTRL_HIZ 1 +#define CH_STATE_CTRL_MUTE 2 +#define CH_STATE_CTRL_DC_LOAD 3 + +/* Channel 1 and 2 Volume Control Registers */ +#define CH1_VOLUME_CTRL_ADDR 0x05 +#define CH2_VOLUME_CTRL_ADDR 0x06 +#define CH_VOLUME_CTRL_VOLUME_MASK BIT_MASK(8) +#define CH_VOLUME_CTRL_VOLUME(val) ((val) & CH_VOLUME_CTRL_VOLUME_MASK) + +/* DC Load Diagnostic Control 1 Register */ +#define DC_LDG_CTRL_1_ADDR 0x09 +#define DC_LDG_CTRL_1_ABORT BIT(7) +#define DC_LDG_CTRL_1_ABORT_MASK BIT(7) +#define DC_LDG_CTRL_1_DOUBLE_RAMP BIT(6) +#define DC_LDG_CTRL_1_DOUBLE_RAMP_MASK BIT(6) +#define DC_LDG_CTRL_1_DOUBLE_SETTLE BIT(5) +#define DC_LDG_CTRL_1_DOUBLE_SETTLE_MASK BIT(5) +#define DC_LDG_CTRL_1_LO_ENABLE BIT(1) +#define DC_LDG_CTRL_1_LO_ENABLE_MASK BIT(1) +#define DC_LDG_CTRL_1_BYPASS BIT(0) +#define DC_LDG_CTRL_1_BYPASS_MASK BIT(0) + +/* DC Load Diagnostic Control 2 Register */ +#define DC_LDG_CTRL_2_ADDR 0x0A +#define DC_LDG_CTRL_2_CH1_SL_MASK (BIT_MASK(4) << 4) +#define DC_LDG_CTRL_2_CH1_SL(val) (((val) << 4) & DC_LDG_CTRL_2_CH1_SL_MASK) +#define DC_LDG_CTRL_2_CH2_SL_MASK BIT_MASK(4) +#define DC_LDG_CTRL_2_CH2_SL(val) ((val) & DC_LDG_CTRL_2_CH2_SL_MASK) + +/* DC Load Diagnostics Report 1 */ +#define DC_LDG_REPORT_1_ADDR 0x0C +#define DC_LDG_REPORT_1_CH1_S2G BIT(7) +#define DC_LDG_REPORT_1_CH1_S2G_MASK BIT(7) +#define DC_LDG_REPORT_1_CH1_S2P BIT(6) +#define DC_LDG_REPORT_1_CH1_S2P_MASK BIT(6) +#define DC_LDG_REPORT_1_CH1_OL BIT(5) +#define DC_LDG_REPORT_1_CH1_OL_MASK BIT(5) +#define DC_LDG_REPORT_1_CH1_SL BIT(4) +#define DC_LDG_REPORT_1_CH1_SL_MASK BIT(4) +#define DC_LDG_REPORT_1_CH2_S2G BIT(3) +#define DC_LDG_REPORT_1_CH2_S2G_MASK BIT(3) +#define DC_LDG_REPORT_1_CH2_S2P BIT(2) +#define DC_LDG_REPORT_1_CH2_S2P_MASK BIT(2) +#define DC_LDG_REPORT_1_CH2_OL BIT(1) +#define DC_LDG_REPORT_1_CH2_OL_MASK BIT(1) +#define DC_LDG_REPORT_1_CH2_SL BIT(0) +#define DC_LDG_REPORT_1_CH2_SL_MASK BIT(0) + +/* DC Load Diagnostics Report 3 */ +#define DC_LDG_REPORT_3_ADDR 0x0E +#define DC_LDG_REPORT_3_CH1_LO BIT(3) +#define DC_LDG_REPORT_3_CH1_LO_MASK BIT(3) +#define DC_LDG_REPORT_3_CH2_LO BIT(2) +#define DC_LDG_REPORT_3_CH2_LO_MASK BIT(2) + +/* Channel Faults Register */ +#define CH_FAULTS_ADDR 0x10 +#define CH_FAULTS_CH1_OC BIT(7) +#define CH_FAULTS_CH1_OC_MASK BIT(7) +#define CH_FAULTS_CH2_OC BIT(6) +#define CH_FAULTS_CH2_OC_MASK BIT(6) +#define CH_FAULTS_CH1_DC BIT(3) +#define CH_FAULTS_CH1_DC_MASK BIT(3) +#define CH_FAULTS_CH2_DC BIT(2) +#define CH_FAULTS_CH2_DC_MASK BIT(2) + +/* Global Faults 1 Register */ +#define GLOBAL_FAULTS_1_ADDR 0x11 +#define GLOBAL_FAULTS_1_INVALID_CLOCK BIT(4) +#define GLOBAL_FAULTS_1_INVALID_CLOCK_MASK BIT(4) +#define GLOBAL_FAULTS_1_PVDD_OV BIT(3) +#define GLOBAL_FAULTS_1_PVDD_OV_MASK BIT(3) +#define GLOBAL_FAULTS_1_VBAT_OV BIT(2) +#define GLOBAL_FAULTS_1_VBAT_OV_MASK BIT(2) +#define GLOBAL_FAULTS_1_PVDD_UV BIT(1) +#define GLOBAL_FAULTS_1_PVDD_UV_MASK BIT(1) +#define GLOBAL_FAULTS_1_VBAT_UV BIT(0) +#define GLOBAL_FAULTS_1_VBAT_UV_MASK BIT(0) + +/* Global Faults 2 Register */ +#define GLOBAL_FAULTS_2_ADDR 0x12 +#define GLOBAL_FAULTS_2_OTSD BIT(4) +#define GLOBAL_FAULTS_2_OTSD_MASK BIT(4) +#define GLOBAL_FAULTS_2_CH1_OTSD BIT(3) +#define GLOBAL_FAULTS_2_CH1_OTSD_MASK BIT(3) +#define GLOBAL_FAULTS_2_CH2_OTSD BIT(2) +#define GLOBAL_FAULTS_2_CH2_OTSD_MASK BIT(2) + +/* Warnings Register */ +#define WARNINGS_ADDR 0x13 +#define WARNINGS_VDD_POR BIT(5) +#define WARNINGS_VDD_POR_MASK BIT(5) +#define WARNINGS_OTW BIT(4) +#define WARNINGS_OTW_MASK BIT(4) +#define WARNINGS_OTW_CH1 BIT(3) +#define WARNINGS_OTW_CH1_MASK BIT(3) +#define WARNINGS_OTW_CH2 BIT(2) +#define WARNINGS_OTW_CH2_MASK BIT(2) + +/* Pin Control Register */ +#define PIN_CTRL_ADDR 0x14 +#define PIN_CTRL_MASK_OC BIT(7) +#define PIN_CTRL_MASK_OC_MASK BIT(7) +#define PIN_CTRL_MASK_OTSD BIT(6) +#define PIN_CTRL_MASK_OTSD_MASK BIT(6) +#define PIN_CTRL_MASK_UV BIT(5) +#define PIN_CTRL_MASK_UV_MASK BIT(5) +#define PIN_CTRL_MASK_OV BIT(4) +#define PIN_CTRL_MASK_OV_MASK BIT(4) +#define PIN_CTRL_MASK_DC BIT(3) +#define PIN_CTRL_MASK_DC_MASK BIT(3) +#define PIN_CTRL_MASK_ILIMIT BIT(2) +#define PIN_CTRL_MASK_ILIMIT_MASK BIT(2) +#define PIN_CTRL_MASK_CLIP BIT(1) +#define PIN_CTRL_MASK_CLIP_MASK BIT(1) +#define PIN_CTRL_MASK_OTW BIT(0) +#define PIN_CTRL_MASK_OTW_MASK BIT(0) + +/* Miscellaneous Control 3 Register */ +#define MISC_CTRL_3_ADDR 0x21 +#define MISC_CTRL_3_CLEAR_FAULT BIT(7) +#define MISC_CTRL_3_CLEAR_FAULT_MASK BIT(7) +#define MISC_CTRL_3_PBTL_CH_SEL BIT(6) +#define MISC_CTRL_3_PBTL_CH_SEL_MASK BIT(6) +#define MISC_CTRL_3_MASK_ILIMIT BIT(5) +#define MISC_CTRL_3_MASK_ILIMIT_MASK BIT(5) +#define MISC_CTRL_3_OTSD_AUTO_RECOVERY BIT(3) +#define MISC_CTRL_3_OTSD_AUTO_RECOVERY_MASK BIT(3) + +/* ILIMIT Status Register */ +#define ILIMIT_STATUS_ADDR 0x25 +#define ILIMIT_STATUS_CH2_ILIMIT_WARN BIT(1) +#define ILIMIT_STATUS_CH2_ILIMIT_WARN_MASK BIT(1) +#define ILIMIT_STATUS_CH1_ILIMIT_WARN BIT(0) +#define ILIMIT_STATUS_CH1_ILIMIT_WARN_MASK BIT(0) + +/* Miscellaneous Control 4 Register */ +#define MISC_CTRL_4_ADDR 0x26 +#define MISC_CTRL_4_HPF_CORNER_MASK BIT_MASK(3) +#define MISC_CTRL_4_HPF_CORNER(val) ((val) & MISC_CTRL_4_HPF_CORNER_MASK) +#define MISC_CTRL_4_HPF_CORNER_3_7_HZ 0 +#define MISC_CTRL_4_HPF_CORNER_7_4_HZ 1 +#define MISC_CTRL_4_HPF_CORNER_15_HZ 2 +#define MISC_CTRL_4_HPF_CORNER_30_HZ 3 +#define MISC_CTRL_4_HPF_CORNER_59_HZ 4 +#define MISC_CTRL_4_HPF_CORNER_118_HZ 5 +#define MISC_CTRL_4_HPF_CORNER_235_HZ 6 +#define MISC_CTRL_4_HPF_CORNER_463_HZ 7 + +/* Miscellaneous Control 5 Register */ +#define MISC_CTRL_5_ADDR 0x28 +#define MISC_CTRL_5_SS_BW_SEL BIT(7) +#define MISC_CTRL_5_SS_BW_SEL_MASK BIT(7) +#define MISC_CTRL_5_SS_DIV2 BIT(6) +#define MISC_CTRL_5_SS_DIV2_MASK BIT(6) +#define MISC_CTRL_5_PHASE_SEL_MSB BIT(5) +#define MISC_CTRL_5_PHASE_SEL_MSB_MASK BIT(5) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_ */ diff --git a/dts/bindings/audio/ti,tas6422dac.yaml b/dts/bindings/audio/ti,tas6422dac.yaml new file mode 100644 index 00000000000..5889d76f827 --- /dev/null +++ b/dts/bindings/audio/ti,tas6422dac.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Centralp +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments TAS6422 Audio Amplifier + +compatible: "ti,tas6422dac" + +include: i2c-device.yaml + +properties: + mute-gpios: + type: phandle-array From 696acc78e0c214b53797c0246e1fdd341473f442 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Fri, 4 Aug 2023 15:00:39 -0700 Subject: [PATCH 0351/4498] drivers: i3c: cdns: fix reading error after transfer Due to a bug, after a completed transfer happen. Only the first command response error was read. This fixes the issue so all commands are read for if an error occurred. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index 6ca92581595..0862cd90e87 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -1302,7 +1302,7 @@ static void cdns_i3c_complete_transfer(const struct device *dev) } for (int i = 0; i < data->xfer.num_cmds; i++) { - switch (data->xfer.cmds->error) { + switch (data->xfer.cmds[i].error) { case CMDR_NO_ERROR: break; From 1b63e49b3f75860bcfe8236900b8cecf51f038c6 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Fri, 4 Aug 2023 14:58:03 -0700 Subject: [PATCH 0352/4498] drivers: i3c: cdns: fix transfers while not idle If a transfer happen in rapid sucession. It was possible for the core to not be ready to accept another command. Poll on the idle status bit until the core is ready to accept new data. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 67 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index 0862cd90e87..a756f6003ac 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -371,12 +371,13 @@ #define I3C_CONTROLLER_ADDR 0x08 /* Maximum i3c devices that the IP can be built with */ -#define I3C_MAX_DEVS 11 -#define I3C_MAX_MSGS 10 -#define I3C_SIR_DEFAULT_DA 0x7F -#define I3C_MAX_IDLE_WAIT_RETRIES 50 -#define I3C_PRESCL_REG_SCALE (4) -#define I2C_PRESCL_REG_SCALE (5) +#define I3C_MAX_DEVS 11 +#define I3C_MAX_MSGS 10 +#define I3C_SIR_DEFAULT_DA 0x7F +#define I3C_MAX_IDLE_CANCEL_WAIT_RETRIES 50 +#define I3C_MAX_IDLE_WAIT_RETRIES 5000 +#define I3C_PRESCL_REG_SCALE (4) +#define I2C_PRESCL_REG_SCALE (5) /* Target T_LOW period in open-drain mode. */ #define I3C_BUS_TLOW_OD_MIN_NS 200 @@ -888,7 +889,7 @@ static void cdns_i3c_cancel_transfer(const struct device *dev) * actually take any time since we only get here if a transaction didn't * complete in a long time. */ - retry_count = I3C_MAX_IDLE_WAIT_RETRIES; + retry_count = I3C_MAX_IDLE_CANCEL_WAIT_RETRIES; while (retry_count--) { val = sys_read32(config->base + MST_STATUS0); if (val & MST_STATUS0_IDLE) { @@ -1017,6 +1018,22 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay k_mutex_lock(&data->bus_lock, K_FOREVER); + /** + * Spin waiting for device to go idle. It is unlikely that this will + * actually take any time unless if the last transaction came immediately + * after an error condition. + */ + uint32_t retry_count = I3C_MAX_IDLE_WAIT_RETRIES; + + while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE) && (retry_count > 0)) { + retry_count--; + } + if (retry_count == 0) { + LOG_ERR("%s: Unable to start transfer, device not idle", dev->name); + ret = -EAGAIN; + goto error; + } + dcmd->cmd1 = CMD1_FIFO_CCC(payload->ccc.id); dcmd->cmd0 = CMD0_FIFO_IS_CCC; dcmd->len = 0; @@ -1070,7 +1087,6 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay data->xfer.num_cmds = num_cmds; cdns_i3c_start_transfer(dev); - if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { cdns_i3c_cancel_transfer(dev); } @@ -1080,6 +1096,7 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay } ret = data->xfer.ret; +error: k_mutex_unlock(&data->bus_lock); return ret; @@ -1389,6 +1406,22 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device k_mutex_lock(&data->bus_lock, K_FOREVER); + /** + * Spin waiting for device to go idle. It is unlikely that this will + * actually take any time unless if the last transaction came immediately + * after an error condition. + */ + uint32_t retry_count = I3C_MAX_IDLE_WAIT_RETRIES; + + while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE) && (retry_count > 0)) { + retry_count--; + } + if (retry_count == 0) { + LOG_ERR("%s: Unable to start transfer, device not idle", dev->name); + ret = -EAGAIN; + goto error; + } + for (unsigned int i = 0; i < num_msgs; i++) { struct cdns_i3c_cmd *cmd = &data->xfer.cmds[i]; @@ -1422,6 +1455,7 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device } ret = data->xfer.ret; +error: k_mutex_unlock(&data->bus_lock); return ret; @@ -1664,6 +1698,22 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t k_mutex_lock(&data->bus_lock, K_FOREVER); + /** + * Spin waiting for device to go idle. It is unlikely that this will + * actually take any time unless if the last transaction came immediately + * after an error condition. + */ + uint32_t retry_count = I3C_MAX_IDLE_WAIT_RETRIES; + + while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE) && (retry_count > 0)) { + retry_count--; + } + if (retry_count == 0) { + LOG_ERR("%s: Unable to start transfer, device not idle", dev->name); + ret = -EAGAIN; + goto error; + } + /* * Prepare transfer commands. Currently there is only a single transfer * in-flight but it would be possible to keep a queue of transfers. If so, @@ -1716,6 +1766,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t } ret = data->xfer.ret; +error: k_mutex_unlock(&data->bus_lock); return ret; From a9fbcd2785af07446bad377769774fc8fd7c4515 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Thu, 3 Aug 2023 21:13:52 +0200 Subject: [PATCH 0353/4498] logging: swo: add Kconfig option for SWO reference frequency SWO reference frequency was set based on `swo-ref-frequency` under `itm` nodelabel or `/cpus/cpu@0/clock-frequency` property. Not all platforms configure those. All ST devices configure CPU frequency in `clock-frequency` under `rcc` nodelabel. Configuring the same value for each board in `/cpus/cpu@0/clock-frequency` would be one way to make SWO work out of the box. There is lots of copy-pasting involved in this, which makes this very error-prone. Introduce Kconfig option, which will default to values configured in `itm` or `/cpus/cpu@0`. The main advantage will be for platforms like ST, where CPU clock frequency is already configured in another place. Thsoe could override default value in SoC, board or any other platform specific layer. Signed-off-by: Marcin Niestroj --- subsys/logging/backends/Kconfig.swo | 10 ++++++++++ subsys/logging/backends/log_backend_swo.c | 11 +++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/subsys/logging/backends/Kconfig.swo b/subsys/logging/backends/Kconfig.swo index 8dcbf3f0285..adfc89b274e 100644 --- a/subsys/logging/backends/Kconfig.swo +++ b/subsys/logging/backends/Kconfig.swo @@ -9,6 +9,16 @@ config LOG_BACKEND_SWO When enabled, backend will use SWO for logging. if LOG_BACKEND_SWO + +config LOG_BACKEND_SWO_REF_FREQ_HZ + int "SWO reference clock frequency" + default $(dt_node_int_prop_int,$(dt_nodelabel_path,itm),swo-ref-frequency) if $(dt_nodelabel_enabled,itm) + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if $(dt_node_has_prop,/cpus/cpu@0,clock-frequency) + default 0 + help + Set SWO reference frequency. In most cases it is equal to CPU + frequency. + config LOG_BACKEND_SWO_FREQ_HZ int "Set SWO output frequency" default 0 diff --git a/subsys/logging/backends/log_backend_swo.c b/subsys/logging/backends/log_backend_swo.c index 7c4c89d8b99..2ef29a3e0c6 100644 --- a/subsys/logging/backends/log_backend_swo.c +++ b/subsys/logging/backends/log_backend_swo.c @@ -42,17 +42,12 @@ PINCTRL_DT_DEFINE(DT_NODELABEL(itm)); #define SWO_FREQ_DIV 1 #else -/* Set reference frequency which can be custom or cpu frequency. */ -#if DT_NODE_HAS_PROP(DT_NODELABEL(itm), swo_ref_frequency) -#define SWO_REF_FREQ DT_PROP(DT_NODELABEL(itm), swo_ref_frequency) -#elif DT_NODE_HAS_PROP(DT_PATH(cpus, cpu_0), clock_frequency) -#define SWO_REF_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) -#else -#error "Missing DT 'clock-frequency' property on cpu@0 node" +#if CONFIG_LOG_BACKEND_SWO_REF_FREQ_HZ == 0 +#error "SWO reference frequency is not configured" #endif #define SWO_FREQ_DIV \ - ((SWO_REF_FREQ + (CONFIG_LOG_BACKEND_SWO_FREQ_HZ / 2)) / \ + ((CONFIG_LOG_BACKEND_SWO_REF_FREQ_HZ + (CONFIG_LOG_BACKEND_SWO_FREQ_HZ / 2)) / \ CONFIG_LOG_BACKEND_SWO_FREQ_HZ) #if SWO_FREQ_DIV > 0xFFFF From f15e7c5909d469bf86b1ac5f47aa17e199302528 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Thu, 3 Aug 2023 21:21:52 +0200 Subject: [PATCH 0354/4498] soc: arm: st: set SWO reference frequency based on 'rcc' Configure SWO reference frequency to be the same as CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. This should make all ST boards ready to be used with SWO, without configuring any other devicetree property. Tested with NUCLEO-L476RG and NUCLEO-H563ZI. Signed-off-by: Marcin Niestroj --- soc/arm/st_stm32/common/Kconfig.defconfig.series | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soc/arm/st_stm32/common/Kconfig.defconfig.series b/soc/arm/st_stm32/common/Kconfig.defconfig.series index a632a41ba57..40dda7b6fa0 100644 --- a/soc/arm/st_stm32/common/Kconfig.defconfig.series +++ b/soc/arm/st_stm32/common/Kconfig.defconfig.series @@ -16,6 +16,13 @@ DT_STM32_RCC_CLOCK_FREQ := $(dt_node_int_prop_int,$(DT_STM32_RCC_PATH),clock-fre config SYS_CLOCK_HW_CYCLES_PER_SEC default "$(DT_STM32_RCC_CLOCK_FREQ)" if "$(dt_nodelabel_enabled,rcc)" +if LOG_BACKEND_SWO + +config LOG_BACKEND_SWO_REF_FREQ_HZ + default "$(DT_STM32_RCC_CLOCK_FREQ)" if "$(dt_nodelabel_enabled,rcc)" + +endif # LOG_BACKEND_SWO + # set the tick per sec as a divider of the LPTIM clock source config SYS_CLOCK_TICKS_PER_SEC default 4096 if STM32_LPTIM_TIMER && STM32_LPTIM_CLOCK_LSE From dd97ed130716a058fe9752b021140aeb006884c1 Mon Sep 17 00:00:00 2001 From: Manimaran A Date: Wed, 26 Jul 2023 09:54:20 +0530 Subject: [PATCH 0355/4498] drivers: mchp: kscan: dts update for low power mode pinctrl and dts updated to support low power feature Signed-off-by: Manimaran A --- .../mec1501modular_assy6885.dts | 40 ++--- .../mec15xxevb_assy6853.dts | 40 ++--- .../mec172xevb_assy6906.dts | 38 ++--- .../mec172xmodular_assy6930.dts | 38 ++--- .../microchip/mec152x/mec152xhsz-pinctrl.dtsi | 147 ++++++++++++++++++ .../microchip/mec172x/mec172xnsz-pinctrl.dtsi | 130 ++++++++++++++++ 6 files changed, 337 insertions(+), 96 deletions(-) diff --git a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.dts b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.dts index 852602386a9..d59ff04a62f 100644 --- a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.dts +++ b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.dts @@ -103,31 +103,21 @@ &kscan0 { status = "okay"; - pinctrl-0 = < &kso00_gpio040 - &kso01_gpio045 - &kso02_gpio046 - &kso12_gpio125 - &kso13_gpio126 - &kso03_gpio047 - &kso04_gpio107 - &kso05_gpio112 - &kso06_gpio113 - &kso14_gpio152 - &kso15_gpio151 - &kso07_gpio120 - &kso08_gpio121 - &kso09_gpio122 - &kso10_gpio123 - &kso11_gpio124 - &ksi0_gpio017 - &ksi1_gpio020 - &ksi2_gpio021 - &ksi3_gpio026 - &ksi4_gpio027 - &ksi5_gpio030 - &ksi6_gpio031 - &ksi7_gpio032 >; - pinctrl-names = "default"; + pinctrl-0 = < &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso12_gpio125 + &kso13_gpio126 &kso03_gpio047 &kso04_gpio107 &kso05_gpio112 + &kso06_gpio113 &kso14_gpio152 &kso15_gpio151 &kso07_gpio120 + &kso08_gpio121 &kso09_gpio122 &kso10_gpio123 &kso11_gpio124 + &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026 + &ksi4_gpio027 &ksi5_gpio030 &ksi6_gpio031 &ksi7_gpio032 >; + pinctrl-1 = < &kso00_gpio040_sleep &kso01_gpio045_sleep &kso02_gpio046_sleep + &kso12_gpio125_sleep &kso13_gpio126_sleep &kso03_gpio047_sleep + &kso04_gpio107_sleep &kso05_gpio112_sleep &kso06_gpio113_sleep + &kso14_gpio152_sleep &kso15_gpio151_sleep &kso07_gpio120_sleep + &kso08_gpio121_sleep &kso09_gpio122_sleep &kso10_gpio123_sleep + &kso11_gpio124_sleep &ksi0_gpio017_sleep &ksi1_gpio020_sleep + &ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep + &ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >; + pinctrl-names = "default", "sleep"; }; &peci0 { diff --git a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts index a8bb074a8ff..fa577a53b7e 100644 --- a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts +++ b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts @@ -160,31 +160,21 @@ &kscan0 { status = "okay"; - pinctrl-0 = < &kso00_gpio040 - &kso01_gpio045 - &kso02_gpio046 - &kso12_gpio125 - &kso13_gpio126 - &kso03_gpio047 - &kso04_gpio107 - &kso05_gpio112 - &kso06_gpio113 - &kso14_gpio152 - &kso15_gpio151 - &kso07_gpio120 - &kso08_gpio121 - &kso09_gpio122 - &kso10_gpio123 - &kso11_gpio124 - &ksi0_gpio017 - &ksi1_gpio020 - &ksi2_gpio021 - &ksi3_gpio026 - &ksi4_gpio027 - &ksi5_gpio030 - &ksi6_gpio031 - &ksi7_gpio032 >; - pinctrl-names = "default"; + pinctrl-0 = < &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso12_gpio125 + &kso13_gpio126 &kso03_gpio047 &kso04_gpio107 &kso05_gpio112 + &kso06_gpio113 &kso14_gpio152 &kso15_gpio151 &kso07_gpio120 + &kso08_gpio121 &kso09_gpio122 &kso10_gpio123 &kso11_gpio124 + &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026 + &ksi4_gpio027 &ksi5_gpio030 &ksi6_gpio031 &ksi7_gpio032 >; + pinctrl-1 = < &kso00_gpio040_sleep &kso01_gpio045_sleep &kso02_gpio046_sleep + &kso12_gpio125_sleep &kso13_gpio126_sleep &kso03_gpio047_sleep + &kso04_gpio107_sleep &kso05_gpio112_sleep &kso06_gpio113_sleep + &kso14_gpio152_sleep &kso15_gpio151_sleep &kso07_gpio120_sleep + &kso08_gpio121_sleep &kso09_gpio122_sleep &kso10_gpio123_sleep + &kso11_gpio124_sleep &ksi0_gpio017_sleep &ksi1_gpio020_sleep + &ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep + &ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >; + pinctrl-names = "default", "sleep"; }; &peci0 { diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts index 2ecd3d413f2..35966d882e0 100644 --- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts +++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts @@ -216,29 +216,21 @@ &kscan0 { status = "okay"; - pinctrl-0 = < &ksi0_gpio017 - &ksi1_gpio020 - &ksi2_gpio021 - &ksi3_gpio026 - &ksi4_gpio027 - &ksi5_gpio030 - &ksi6_gpio031 - &ksi7_gpio032 - &kso00_gpio040 - &kso01_gpio045 - &kso02_gpio046 - &kso03_gpio047 - &kso04_gpio107 - &kso05_gpio112 - &kso06_gpio113 - &kso07_gpio120 - &kso08_gpio121 - &kso09_gpio122 - &kso10_gpio123 - &kso11_gpio124 - &kso12_gpio125 - &kso13_gpio126 >; - pinctrl-names = "default"; + pinctrl-0 = < &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026 + &ksi4_gpio027 &ksi5_gpio030 &ksi6_gpio031 &ksi7_gpio032 + &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso03_gpio047 + &kso04_gpio107 &kso05_gpio112 &kso06_gpio113 &kso07_gpio120 + &kso08_gpio121 &kso09_gpio122 &kso10_gpio123 &kso11_gpio124 + &kso12_gpio125 &kso13_gpio126 >; + pinctrl-1 = < &ksi0_gpio017_sleep &ksi1_gpio020_sleep &ksi2_gpio021_sleep + &ksi3_gpio026_sleep &ksi4_gpio027_sleep &ksi5_gpio030_sleep + &ksi6_gpio031_sleep &ksi7_gpio032_sleep &kso00_gpio040_sleep + &kso01_gpio045_sleep &kso02_gpio046_sleep &kso03_gpio047_sleep + &kso04_gpio107_sleep &kso05_gpio112_sleep &kso06_gpio113_sleep + &kso07_gpio120_sleep &kso08_gpio121_sleep &kso09_gpio122_sleep + &kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep + &kso13_gpio126_sleep >; + pinctrl-names = "default", "sleep"; }; &ksi0_gpio017 { diff --git a/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.dts b/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.dts index 631f7ca15b1..d355f19afc3 100644 --- a/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.dts +++ b/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.dts @@ -194,29 +194,21 @@ &kscan0 { status = "okay"; - pinctrl-0 = < &ksi0_gpio017 - &ksi1_gpio020 - &ksi2_gpio021 - &ksi3_gpio026 - &ksi4_gpio027 - &ksi5_gpio030 - &ksi6_gpio031 - &ksi7_gpio032 - &kso00_gpio040 - &kso01_gpio045 - &kso02_gpio046 - &kso03_gpio047 - &kso04_gpio107 - &kso05_gpio112 - &kso06_gpio113 - &kso07_gpio120 - &kso08_gpio121 - &kso09_gpio122 - &kso10_gpio123 - &kso11_gpio124 - &kso12_gpio125 - &kso13_gpio126 >; - pinctrl-names = "default"; + pinctrl-0 = < &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026 + &ksi4_gpio027 &ksi5_gpio030 &ksi6_gpio031 &ksi7_gpio032 + &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso03_gpio047 + &kso04_gpio107 &kso05_gpio112 &kso06_gpio113 &kso07_gpio120 + &kso08_gpio121 &kso09_gpio122 &kso10_gpio123 &kso11_gpio124 + &kso12_gpio125 &kso13_gpio126 >; + pinctrl-1 = < &ksi0_gpio017_sleep &ksi1_gpio020_sleep &ksi2_gpio021_sleep + &ksi3_gpio026_sleep &ksi4_gpio027_sleep &ksi5_gpio030_sleep + &ksi6_gpio031_sleep &ksi7_gpio032_sleep &kso00_gpio040_sleep + &kso01_gpio045_sleep &kso02_gpio046_sleep &kso03_gpio047_sleep + &kso04_gpio107_sleep &kso05_gpio112_sleep &kso06_gpio113_sleep + &kso07_gpio120_sleep &kso08_gpio121_sleep &kso09_gpio122_sleep + &kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep + &kso13_gpio126_sleep >; + pinctrl-names = "default", "sleep"; }; &ksi0_gpio017 { diff --git a/dts/arm/microchip/mec152x/mec152xhsz-pinctrl.dtsi b/dts/arm/microchip/mec152x/mec152xhsz-pinctrl.dtsi index c86a7cc519b..b5614be1969 100644 --- a/dts/arm/microchip/mec152x/mec152xhsz-pinctrl.dtsi +++ b/dts/arm/microchip/mec152x/mec152xhsz-pinctrl.dtsi @@ -1092,65 +1092,212 @@ /* PWM */ pwm0_gpio053_sleep: pwm0_gpio053_sleep { pinmux = < MCHP_XEC_PINMUX(053, MCHP_AF1) >; + low-power-enable; }; pwm0_alt_gpio241_sleep: pwm0_alt_gpio241_sleep { pinmux = < MCHP_XEC_PINMUX(0241, MCHP_AF1) >; + low-power-enable; }; pwm1_gpio054_sleep: pwm1_gpio054_sleep { pinmux = < MCHP_XEC_PINMUX(054, MCHP_AF1) >; + low-power-enable; }; pwm1_alt_gpio254_sleep: pwm1_alt_gpio254_sleep { pinmux = < MCHP_XEC_PINMUX(0254, MCHP_AF1) >; + low-power-enable; }; pwm2_gpio055_sleep: pwm2_gpio055_sleep { pinmux = < MCHP_XEC_PINMUX(055, MCHP_AF1) >; + low-power-enable; }; pwm2_alt_gpio045_sleep: pwm2_alt_gpio045_sleep { pinmux = < MCHP_XEC_PINMUX(045, MCHP_AF2) >; + low-power-enable; }; pwm3_gpio056_sleep: pwm3_gpio056_sleep { pinmux = < MCHP_XEC_PINMUX(056, MCHP_AF1) >; + low-power-enable; }; pwm3_alt_gpio047_sleep: pwm3_alt_gpio047_sleep { pinmux = < MCHP_XEC_PINMUX(047, MCHP_AF2) >; + low-power-enable; }; pwm4_gpio011_sleep: pwm4_gpio011_sleep { pinmux = < MCHP_XEC_PINMUX(011, MCHP_AF2) >; + low-power-enable; }; pwm5_gpio002_sleep: pwm5_gpio002_sleep { pinmux = < MCHP_XEC_PINMUX(02, MCHP_AF1) >; + low-power-enable; }; pwm6_gpio014_sleep: pwm6_gpio014_sleep { pinmux = < MCHP_XEC_PINMUX(014, MCHP_AF1) >; + low-power-enable; }; pwm6_alt_gpio063_sleep: pwm6_alt_gpio063_sleep { pinmux = < MCHP_XEC_PINMUX(063, MCHP_AF2) >; + low-power-enable; }; pwm7_gpio015_sleep: pwm7_gpio015_sleep { pinmux = < MCHP_XEC_PINMUX(015, MCHP_AF1) >; + low-power-enable; }; pwm7_alt_gpio061_sleep: pwm7_alt_gpio061_sleep { pinmux = < MCHP_XEC_PINMUX(061, MCHP_AF2) >; + low-power-enable; }; pwm8_gpio035_sleep: pwm8_gpio035_sleep { pinmux = < MCHP_XEC_PINMUX(035, MCHP_AF1) >; + low-power-enable; }; pwm8_alt_gpio175_sleep: pwm8_alt_gpio175_sleep { pinmux = < MCHP_XEC_PINMUX(0175, MCHP_AF3) >; + low-power-enable; + }; + + /* Keyscan */ + ksi0_gpio017_sleep: ksi0_gpio017_sleep { + pinmux = < MCHP_XEC_PINMUX(017, MCHP_AF1) >; + low-power-enable; + }; + + ksi1_gpio020_sleep: ksi1_gpio020_sleep { + pinmux = < MCHP_XEC_PINMUX(020, MCHP_AF1) >; + low-power-enable; + }; + + ksi2_gpio021_sleep: ksi2_gpio021_sleep { + pinmux = < MCHP_XEC_PINMUX(021, MCHP_AF1) >; + low-power-enable; + }; + + ksi3_gpio026_sleep: ksi3_gpio026_sleep { + pinmux = < MCHP_XEC_PINMUX(026, MCHP_AF1) >; + low-power-enable; + }; + + ksi4_gpio027_sleep: ksi4_gpio027_sleep { + pinmux = < MCHP_XEC_PINMUX(027, MCHP_AF1) >; + low-power-enable; + }; + + ksi5_gpio030_sleep: ksi5_gpio030_sleep { + pinmux = < MCHP_XEC_PINMUX(030, MCHP_AF1) >; + low-power-enable; + }; + + ksi6_gpio031_sleep: ksi6_gpio031_sleep { + pinmux = < MCHP_XEC_PINMUX(031, MCHP_AF1) >; + low-power-enable; + }; + + ksi7_gpio032_sleep: ksi7_gpio032_sleep { + pinmux = < MCHP_XEC_PINMUX(032, MCHP_AF1) >; + low-power-enable; + }; + + kso00_gpio040_sleep: kso00_gpio040_sleep { + pinmux = < MCHP_XEC_PINMUX(040, MCHP_AF2) >; + low-power-enable; + }; + + kso01_gpio045_sleep: kso01_gpio045_sleep { + pinmux = < MCHP_XEC_PINMUX(045, MCHP_AF1) >; + low-power-enable; + }; + + kso02_gpio046_sleep: kso02_gpio046_sleep { + pinmux = < MCHP_XEC_PINMUX(046, MCHP_AF1) >; + low-power-enable; + }; + + kso03_gpio047_sleep: kso03_gpio047_sleep { + pinmux = < MCHP_XEC_PINMUX(047, MCHP_AF1) >; + low-power-enable; + }; + + kso04_gpio107_sleep: kso04_gpio107_sleep { + pinmux = < MCHP_XEC_PINMUX(0107, MCHP_AF2) >; + low-power-enable; + }; + + kso05_gpio112_sleep: kso05_gpio112_sleep { + pinmux = < MCHP_XEC_PINMUX(0112, MCHP_AF1) >; + low-power-enable; + }; + + kso06_gpio113_sleep: kso06_gpio113_sleep { + pinmux = < MCHP_XEC_PINMUX(0113, MCHP_AF1) >; + low-power-enable; + }; + + kso07_gpio120_sleep: kso07_gpio120_sleep { + pinmux = < MCHP_XEC_PINMUX(0120, MCHP_AF1) >; + low-power-enable; + }; + + kso08_gpio121_sleep: kso08_gpio121_sleep { + pinmux = < MCHP_XEC_PINMUX(0121, MCHP_AF2) >; + low-power-enable; + }; + + kso09_gpio122_sleep: kso09_gpio122_sleep { + pinmux = < MCHP_XEC_PINMUX(0122, MCHP_AF2) >; + low-power-enable; + }; + + kso10_gpio123_sleep: kso10_gpio123_sleep { + pinmux = < MCHP_XEC_PINMUX(0123, MCHP_AF2) >; + low-power-enable; + }; + + kso11_gpio124_sleep: kso11_gpio124_sleep { + pinmux = < MCHP_XEC_PINMUX(0124, MCHP_AF2) >; + low-power-enable; + }; + + kso12_gpio125_sleep: kso12_gpio125_sleep { + pinmux = < MCHP_XEC_PINMUX(0125, MCHP_AF2) >; + low-power-enable; + }; + + kso13_gpio126_sleep: kso13_gpio126_sleep { + pinmux = < MCHP_XEC_PINMUX(0126, MCHP_AF2) >; + low-power-enable; + }; + + kso14_gpio152_sleep: kso14_gpio152_sleep { + pinmux = < MCHP_XEC_PINMUX(0152, MCHP_AF1) >; + low-power-enable; + }; + + kso15_gpio151_sleep: kso15_gpio151_sleep { + pinmux = < MCHP_XEC_PINMUX(0151, MCHP_AF2) >; + low-power-enable; + }; + + kso16_gpio132_sleep: kso16_gpio132_sleep { + pinmux = < MCHP_XEC_PINMUX(0132, MCHP_AF2) >; + low-power-enable; + }; + + kso17_gpio140_sleep: kso17_gpio140_sleep { + pinmux = < MCHP_XEC_PINMUX(0140, MCHP_AF3) >; + low-power-enable; }; /* EEPROM */ diff --git a/dts/arm/microchip/mec172x/mec172xnsz-pinctrl.dtsi b/dts/arm/microchip/mec172x/mec172xnsz-pinctrl.dtsi index 9b4d3047a51..fc79cf357fa 100644 --- a/dts/arm/microchip/mec172x/mec172xnsz-pinctrl.dtsi +++ b/dts/arm/microchip/mec172x/mec172xnsz-pinctrl.dtsi @@ -1214,4 +1214,134 @@ low-power-enable; }; + /* Keyscan */ + ksi0_gpio017_sleep: ksi0_gpio017_sleep { + pinmux = < MCHP_XEC_PINMUX(017, MCHP_AF1) >; + low-power-enable; + }; + + ksi1_gpio020_sleep: ksi1_gpio020_sleep { + pinmux = < MCHP_XEC_PINMUX(020, MCHP_AF1) >; + low-power-enable; + }; + + ksi2_gpio021_sleep: ksi2_gpio021_sleep { + pinmux = < MCHP_XEC_PINMUX(021, MCHP_AF1) >; + low-power-enable; + }; + + ksi3_gpio026_sleep: ksi3_gpio026_sleep { + pinmux = < MCHP_XEC_PINMUX(026, MCHP_AF1) >; + low-power-enable; + }; + + ksi4_gpio027_sleep: ksi4_gpio027_sleep { + pinmux = < MCHP_XEC_PINMUX(027, MCHP_AF1) >; + low-power-enable; + }; + + ksi5_gpio030_sleep: ksi5_gpio030_sleep { + pinmux = < MCHP_XEC_PINMUX(030, MCHP_AF1) >; + low-power-enable; + }; + + ksi6_gpio031_sleep: ksi6_gpio031_sleep { + pinmux = < MCHP_XEC_PINMUX(031, MCHP_AF1) >; + low-power-enable; + }; + + ksi7_gpio032_sleep: ksi7_gpio032_sleep { + pinmux = < MCHP_XEC_PINMUX(032, MCHP_AF1) >; + low-power-enable; + }; + + kso00_gpio040_sleep: kso00_gpio040_sleep { + pinmux = < MCHP_XEC_PINMUX(040, MCHP_AF2) >; + low-power-enable; + }; + + kso01_gpio045_sleep: kso01_gpio045_sleep { + pinmux = < MCHP_XEC_PINMUX(045, MCHP_AF1) >; + low-power-enable; + }; + + kso02_gpio046_sleep: kso02_gpio046_sleep { + pinmux = < MCHP_XEC_PINMUX(046, MCHP_AF1) >; + low-power-enable; + }; + + kso03_gpio047_sleep: kso03_gpio047_sleep { + pinmux = < MCHP_XEC_PINMUX(047, MCHP_AF1) >; + low-power-enable; + }; + + kso04_gpio107_sleep: kso04_gpio107_sleep { + pinmux = < MCHP_XEC_PINMUX(0107, MCHP_AF2) >; + low-power-enable; + }; + + kso05_gpio112_sleep: kso05_gpio112_sleep { + pinmux = < MCHP_XEC_PINMUX(0112, MCHP_AF1) >; + low-power-enable; + }; + + kso06_gpio113_sleep: kso06_gpio113_sleep { + pinmux = < MCHP_XEC_PINMUX(0113, MCHP_AF1) >; + low-power-enable; + }; + + kso07_gpio120_sleep: kso07_gpio120_sleep { + pinmux = < MCHP_XEC_PINMUX(0120, MCHP_AF1) >; + low-power-enable; + }; + + kso08_gpio121_sleep: kso08_gpio121_sleep { + pinmux = < MCHP_XEC_PINMUX(0121, MCHP_AF2) >; + low-power-enable; + }; + + kso09_gpio122_sleep: kso09_gpio122_sleep { + pinmux = < MCHP_XEC_PINMUX(0122, MCHP_AF2) >; + low-power-enable; + }; + + kso10_gpio123_sleep: kso10_gpio123_sleep { + pinmux = < MCHP_XEC_PINMUX(0123, MCHP_AF2) >; + low-power-enable; + }; + + kso11_gpio124_sleep: kso11_gpio124_sleep { + pinmux = < MCHP_XEC_PINMUX(0124, MCHP_AF2) >; + low-power-enable; + }; + + kso12_gpio125_sleep: kso12_gpio125_sleep { + pinmux = < MCHP_XEC_PINMUX(0125, MCHP_AF2) >; + low-power-enable; + }; + + kso13_gpio126_sleep: kso13_gpio126_sleep { + pinmux = < MCHP_XEC_PINMUX(0126, MCHP_AF2) >; + low-power-enable; + }; + + kso14_gpio152_sleep: kso14_gpio152_sleep { + pinmux = < MCHP_XEC_PINMUX(0152, MCHP_AF1) >; + low-power-enable; + }; + + kso15_gpio151_sleep: kso15_gpio151_sleep { + pinmux = < MCHP_XEC_PINMUX(0151, MCHP_AF2) >; + low-power-enable; + }; + + kso16_gpio132_sleep: kso16_gpio132_sleep { + pinmux = < MCHP_XEC_PINMUX(0132, MCHP_AF2) >; + low-power-enable; + }; + + kso17_gpio140_sleep: kso17_gpio140_sleep { + pinmux = < MCHP_XEC_PINMUX(0140, MCHP_AF3) >; + low-power-enable; + }; }; From 9b6c93367858dd562b565e55a5cb87ec1b55bdef Mon Sep 17 00:00:00 2001 From: Manimaran A Date: Wed, 26 Jul 2023 10:04:59 +0530 Subject: [PATCH 0356/4498] drivers: mchp: kscan: low power mode enabled KSCAN driver updated to support low power feature Signed-off-by: Manimaran A --- drivers/kscan/kscan_mchp_xec.c | 63 +++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/drivers/kscan/kscan_mchp_xec.c b/drivers/kscan/kscan_mchp_xec.c index d3a39868c28..e0960b1c946 100644 --- a/drivers/kscan/kscan_mchp_xec.c +++ b/drivers/kscan/kscan_mchp_xec.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #define LOG_LEVEL CONFIG_KSCAN_LOG_LEVEL LOG_MODULE_REGISTER(kscan_mchp_xec); @@ -42,13 +44,14 @@ LOG_MODULE_REGISTER(kscan_mchp_xec); struct kscan_xec_config { struct kscan_regs *regs; + const struct pinctrl_dev_config *pcfg; + uint8_t rsvd[3]; uint8_t girq; uint8_t girq_pos; uint8_t irq_pri; uint8_t pcr_idx; uint8_t pcr_pos; - uint8_t rsvd[3]; - const struct pinctrl_dev_config *pcfg; + bool wakeup_source; }; struct kscan_xec_data { @@ -370,7 +373,9 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3) drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_ALL); k_sem_take(&data->poll_lock, K_FOREVER); - +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif uint32_t start_poll_cycles = k_cycle_get_32(); while (atomic_get(&data->enable_scan) == 1U) { @@ -411,6 +416,9 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3) /* Allow other threads to run while we sleep */ k_usleep(wait_period); } +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif } } @@ -449,6 +457,44 @@ static int kscan_xec_enable_interface(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int kscan_xec_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct kscan_xec_config const *cfg = dev->config; + struct kscan_regs *regs = cfg->regs; + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (!(cfg->wakeup_source)) { + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret != 0) { + LOG_ERR("XEC KSCAN pinctrl init failed (%d)", ret); + return ret; + } + regs->KSO_SEL &= ~BIT(MCHP_KSCAN_KSO_EN_POS); + /* Clea Status register */ + regs->KSI_STS = MCHP_KSCAN_KSO_SEL_REG_MASK; + regs->KSI_IEN = MCHP_KSCAN_KSI_IEN_REG_MASK; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + if (!(cfg->wakeup_source)) { + regs->KSO_SEL |= BIT(MCHP_KSCAN_KSO_EN_POS); + regs->KSI_IEN = (~MCHP_KSCAN_KSI_IEN_REG_MASK); + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP); + if (ret == -ENOENT) { /* pinctrl-1 does not exist. */ + ret = 0; + } + } + break; + default: + ret = -ENOTSUP; + } + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + static const struct kscan_driver_api kscan_xec_driver_api = { .config = kscan_xec_configure, .disable_callback = kscan_xec_inhibit_interface, @@ -505,6 +551,12 @@ static struct kscan_xec_data kbd_data; PINCTRL_DT_INST_DEFINE(0); +/* To enable wakeup on the KSCAN, the DTS needs to have entries defined + * in the KSCAN node in the DTS specifying it as a wake source; + * Example as below + * + * wakeup-source; + */ static struct kscan_xec_config kscan_xec_cfg_0 = { .regs = (struct kscan_regs *)(DT_INST_REG_ADDR(0)), .girq = (uint8_t)(DT_INST_PROP_BY_IDX(0, girqs, 0)), @@ -512,9 +564,12 @@ static struct kscan_xec_config kscan_xec_cfg_0 = { .pcr_idx = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 0)), .pcr_pos = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 1)), .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), + .wakeup_source = DT_INST_PROP(0, wakeup_source) }; +PM_DEVICE_DT_INST_DEFINE(0, kscan_xec_pm_action); + DEVICE_DT_INST_DEFINE(0, kscan_xec_init, - NULL, &kbd_data, &kscan_xec_cfg_0, + PM_DEVICE_DT_INST_GET(0), &kbd_data, &kscan_xec_cfg_0, POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, &kscan_xec_driver_api); From 10b85602e60c2db6be7205143c59315ae7bb9963 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 25 Jul 2023 18:04:51 -0700 Subject: [PATCH 0357/4498] drivers: i3c: fix cdns-i3c builds with I3C_USE_IBI=n The Cadence I3C was not building with CONFIG_I3C_USE_IBI, this fixes the build and will give a small code size reduction when enabled. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 65 +++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index a756f6003ac..cad6bab6566 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -613,30 +613,6 @@ static int cdns_i3c_read_rx_fifo(const struct cdns_i3c_config *config, void *buf return 0; } -static int cdns_i3c_read_ibi_fifo(const struct cdns_i3c_config *config, void *buf, uint32_t len) -{ - uint32_t *ptr = buf; - uint32_t remain, val; - - for (remain = len; remain >= 4; remain -= 4) { - if (cdns_i3c_ibi_fifo_empty(config)) { - return -EIO; - } - val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); - *ptr++ = val; - } - - if (remain > 0) { - if (cdns_i3c_ibi_fifo_empty(config)) { - return -EIO; - } - val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); - memcpy(ptr, &val, remain); - } - - return 0; -} - static void cdns_i3c_set_prescalers(const struct device *dev) { struct cdns_i3c_data *data = dev->data; @@ -876,8 +852,9 @@ static void cdns_i3c_cancel_transfer(const struct device *dev) sys_write32(MST_INT_CMDD_EMP, config->base + MST_IDR); /* Ignore if no pending transfer */ - if (data->xfer.num_cmds == 0) + if (data->xfer.num_cmds == 0) { return; + } data->xfer.num_cmds = 0; @@ -1467,8 +1444,9 @@ static int cdns_i3c_master_get_rr_slot(const struct device *dev, uint8_t dyn_add const struct cdns_i3c_config *config = dev->config; if (dyn_addr == 0) { - if (!data->free_rr_slots) + if (!data->free_rr_slots) { return -ENOSPC; + } return find_lsb_set(data->free_rr_slots) - 1; } @@ -1772,6 +1750,31 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t return ret; } +#ifdef CONFIG_I3C_USE_IBI +static int cdns_i3c_read_ibi_fifo(const struct cdns_i3c_config *config, void *buf, uint32_t len) +{ + uint32_t *ptr = buf; + uint32_t remain, val; + + for (remain = len; remain >= 4; remain -= 4) { + if (cdns_i3c_ibi_fifo_empty(config)) { + return -EIO; + } + val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); + *ptr++ = val; + } + + if (remain > 0) { + if (cdns_i3c_ibi_fifo_empty(config)) { + return -EIO; + } + val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); + memcpy(ptr, &val, remain); + } + + return 0; +} + static void cdns_i3c_handle_ibi(const struct device *dev, uint32_t ibir) { const struct cdns_i3c_config *config = dev->config; @@ -1866,6 +1869,7 @@ static void cdns_i3c_target_ibi_hj_complete(const struct device *dev) k_sem_give(&data->ibi_hj_complete); } +#endif static void cdns_i3c_irq_handler(const struct device *dev) { @@ -1904,7 +1908,12 @@ static void cdns_i3c_irq_handler(const struct device *dev) /* In-band interrupt */ if (int_st & MST_INT_IBIR_THR) { sys_write32(MST_INT_IBIR_THR, config->base + MST_ICR); +#ifdef CONFIG_I3C_USE_IBI cnds_i3c_master_demux_ibis(dev); +#else + LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", + dev->name); +#endif } /* In-band interrupt data */ @@ -1999,7 +2008,9 @@ static void cdns_i3c_irq_handler(const struct device *dev) /* HJ could send a DISEC which would trigger the SLV_INT_EVENT_UP bit, * but it's still expected to eventually send a DAA */ +#ifdef CONFIG_I3C_USE_IBI cdns_i3c_target_ibi_hj_complete(dev); +#endif } /* HJ complete and DA has been assigned */ @@ -2457,8 +2468,10 @@ static int cdns_i3c_bus_init(const struct device *dev) if (!ctrl_config->is_secondary) { /* Perform bus initialization */ ret = i3c_bus_init(dev, &config->common.dev_list); +#ifdef CONFIG_I3C_USE_IBI /* Bus Initialization Complete, allow HJ ACKs */ sys_write32(CTRL_HJ_ACK | sys_read32(config->base + CTRL), config->base + CTRL); +#endif } return 0; From 8084ea55b787790e656b78d94bc2433bb47d8deb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 13 Jul 2023 21:59:53 -0700 Subject: [PATCH 0358/4498] boards/arc/qemu_arc: Disable use of branch delay slots I spent several hours debugging a weird stack pointer corruption bug and discovered that QEMU appears to mess up register contents when an interrupt fires during the execution of a branch with a delay slot. Instead of trying to fix qemu, let's just tell the compiler to not generate code that uses the branch instructions with delay slots. Closes: #60071 Signed-off-by: Keith Packard --- boards/arc/qemu_arc/qemu_arc_em_defconfig | 1 + boards/arc/qemu_arc/qemu_arc_hs5x_defconfig | 1 + boards/arc/qemu_arc/qemu_arc_hs6x_defconfig | 1 + boards/arc/qemu_arc/qemu_arc_hs_defconfig | 1 + boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig | 1 + 5 files changed, 5 insertions(+) diff --git a/boards/arc/qemu_arc/qemu_arc_em_defconfig b/boards/arc/qemu_arc/qemu_arc_em_defconfig index 0d6f4052e64..b713b193bc0 100644 --- a/boards/arc/qemu_arc/qemu_arc_em_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_em_defconfig @@ -10,3 +10,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y +CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig b/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig index f8e50bcf3f8..9459d6f70bb 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig @@ -10,3 +10,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 +CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig b/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig index 8ab0d4ae0f0..3d2804c33f7 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig @@ -10,3 +10,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 +CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs_defconfig b/boards/arc/qemu_arc/qemu_arc_hs_defconfig index 911702aab21..5ff910926f8 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs_defconfig @@ -10,3 +10,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y +CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig b/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig index bec83e7c5ae..b072c7692b6 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig @@ -10,3 +10,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y +CONFIG_COMPILER_OPT="-fno-delayed-branch" From 30a2326d0b72cf8ae02fa538651d74d218d44891 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Thu, 13 Jul 2023 14:42:52 +0200 Subject: [PATCH 0359/4498] drivers: sensor: qdec_mcux: update phase bit in register Update single phase bit in register when changing data->qdec_config. Otherwise the changed settings has no effect. Signed-off-by: Jeppe Odgaard --- drivers/sensor/qdec_mcux/qdec_mcux.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sensor/qdec_mcux/qdec_mcux.c b/drivers/sensor/qdec_mcux/qdec_mcux.c index 467fec4bcb7..ac95a4d0a7f 100644 --- a/drivers/sensor/qdec_mcux/qdec_mcux.c +++ b/drivers/sensor/qdec_mcux/qdec_mcux.c @@ -42,6 +42,7 @@ static enc_decoder_work_mode_t int_to_work_mode(int32_t val) static int qdec_mcux_attr_set(const struct device *dev, enum sensor_channel ch, enum sensor_attribute attr, const struct sensor_value *val) { + const struct qdec_mcux_config *config = dev->config; struct qdec_mcux_data *data = dev->data; if (ch != SENSOR_CHAN_ROTATION) { @@ -59,6 +60,8 @@ static int qdec_mcux_attr_set(const struct device *dev, enum sensor_channel ch, case SENSOR_ATTR_QDEC_ENABLE_SINGLE_PHASE: data->qdec_config.decoderWorkMode = int_to_work_mode(val->val1); + + WRITE_BIT(config->base->CTRL, ENC_CTRL_PH1_SHIFT, val->val1); return 0; default: return -ENOTSUP; From 11f6f2f7e8d99f764898598a07ebcf6977cfedc9 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 12 Jul 2023 09:42:32 -0500 Subject: [PATCH 0360/4498] samples: subsys: display: Add RK055HDMIPI4M shield testcase to LVGL Add RK055HDMIPI4M specific testcase to LVGL. This allows LVGL to be verified on the RT1170 and RT595 EVKs from NXP, which support LVGL using this shield. Signed-off-by: Daniel DeGrasse --- samples/subsys/display/lvgl/sample.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/samples/subsys/display/lvgl/sample.yaml b/samples/subsys/display/lvgl/sample.yaml index 5329ba5d90c..d53bc36aaa7 100644 --- a/samples/subsys/display/lvgl/sample.yaml +++ b/samples/subsys/display/lvgl/sample.yaml @@ -20,3 +20,23 @@ tests: - lvgl integration_platforms: - native_posix_64 + sample.display.lvgl.rk055hdmipi4m: + # This sample is intended to test the RT1170 and RT595, which require + # a display shield to work with LVGL + min_flash: 250 + # The minimum RAM needed for this display is actually around 8MB, + # but the RT595 uses external PSRAM for the display buffer + min_ram: 32 + harness: none + tags: + - samples + - display + - gui + modules: + - lvgl + extra_args: SHIELD="rk055hdmipi4m" + platform_allow: + - mimxrt1170_evk_cm7 + - mimxrt595_evk_cm33 + integration_platforms: + - mimxrt1170_evk_cm7 From 3d5e6609034d8e31ade8b33040abdf986180f294 Mon Sep 17 00:00:00 2001 From: Marko Sagadin Date: Tue, 11 Jul 2023 22:33:12 +0200 Subject: [PATCH 0361/4498] drivers: serial: native tty: Split in top and bottom Split the native tty serial driver in a top and bottom to enable using it with embedded libCs. Signed-off-by: Marko Sagadin --- boards/posix/native_sim/doc/index.rst | 2 +- drivers/serial/CMakeLists.txt | 5 + drivers/serial/uart_native_tty.c | 280 +++++------------------- drivers/serial/uart_native_tty_bottom.c | 246 +++++++++++++++++++++ drivers/serial/uart_native_tty_bottom.h | 82 +++++++ 5 files changed, 386 insertions(+), 229 deletions(-) create mode 100644 drivers/serial/uart_native_tty_bottom.c create mode 100644 drivers/serial/uart_native_tty_bottom.h diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 22d3b6b8c31..ea521b0f5e2 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -121,7 +121,7 @@ host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). log backend, native backend, :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`, all rtc, RTC emul, :kconfig:option:`CONFIG_RTC_EMUL`, all serial, uart native posix/PTTY, :kconfig:option:`CONFIG_UART_NATIVE_POSIX`, all - serial, uart native TTY, :kconfig:option:`CONFIG_UART_NATIVE_TTY`, host libC + serial, uart native TTY, :kconfig:option:`CONFIG_UART_NATIVE_TTY`, all spi, SPI emul, :kconfig:option:`CONFIG_SPI_EMUL`, all system tick, native_posix timer, :kconfig:option:`CONFIG_NATIVE_POSIX_TIMER`, all tracing, Posix tracing backend, :kconfig:option:`CONFIG_TRACING_BACKEND_POSIX`, all diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index de3ec08af8b..9150078d66f 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -80,6 +80,11 @@ endif() if(CONFIG_UART_NATIVE_TTY) zephyr_library_compile_definitions(NO_POSIX_CHEATS) zephyr_library_sources(uart_native_tty.c) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(uart_native_tty_bottom.c) + else() + target_sources(native_simulator INTERFACE uart_native_tty_bottom.c) + endif() endif() zephyr_library_sources_ifdef(CONFIG_SERIAL_TEST serial_test.c) diff --git a/drivers/serial/uart_native_tty.c b/drivers/serial/uart_native_tty.c index 2027279d440..22f2b0e539f 100644 --- a/drivers/serial/uart_native_tty.c +++ b/drivers/serial/uart_native_tty.c @@ -5,7 +5,7 @@ * /dev/ttyACM0). Only polling Uart API is implemented. Driver can be configured via devicetree, * command line options or at runtime. * - * To learn more see Native TYY section at: + * To learn more see Native TTY section at: * https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html * or * ${ZEPHYR_BASE}/boards/posix/native_posix/doc/index.rst @@ -18,18 +18,15 @@ #include #include -#include -#include -#include -#include -#include -#include +#include #include "cmdline.h" #include "posix_native_task.h" +#include "uart_native_tty_bottom.h" +#include "nsi_host_trampolines.h" -#define WARN(msg, ...) posix_print_warning(msg, ##__VA_ARGS__) -#define ERROR(msg, ...) posix_print_error_and_exit(msg, ##__VA_ARGS__) +#define WARN(...) nsi_print_warning(__VA_ARGS__) +#define ERROR(...) nsi_print_error_and_exit(__VA_ARGS__) #define DT_DRV_COMPAT zephyr_native_tty_uart @@ -48,170 +45,68 @@ struct native_tty_config { struct uart_config uart_config; }; -struct baudrate_termios_pair { - int baudrate; - speed_t termios_baudrate; -}; - -/** - * @brief Lookup table for mapping the baud rate to the macro understood by termios. - */ -static const struct baudrate_termios_pair baudrate_lut[] = { - {1200, B1200}, {1800, B1800}, {2400, B2400}, {4800, B4800}, - {9600, B9600}, {19200, B19200}, {38400, B38400}, {57600, B57600}, - {115200, B115200}, {230400, B230400}, {460800, B460800}, {500000, B500000}, - {576000, B576000}, {921600, B921600}, {1000000, B1000000}, {1152000, B1152000}, - {1500000, B1500000}, {2000000, B2000000}, {2500000, B2500000}, {3000000, B3000000}, - {3500000, B3500000}, {4000000, B4000000}, -}; - -/** - * @brief Set given termios to defaults appropriate for communicating with serial port devices. - * - * @param ter - */ -static inline void native_tty_termios_defaults_set(struct termios *ter) -{ - /* Set terminal in "serial" mode: - * - Not canonical (no line input) - * - No signal generation from Ctr+{C|Z..} - * - No echoing - */ - ter->c_lflag &= ~(ICANON | ISIG | ECHO); - - /* No special interpretation of output bytes. - * No conversion of newline to carriage return/line feed. - */ - ter->c_oflag &= ~(OPOST | ONLCR); - - /* No software flow control. */ - ter->c_iflag &= ~(IXON | IXOFF | IXANY); - - /* No blocking, return immediately with what is available. */ - ter->c_cc[VMIN] = 0; - ter->c_cc[VTIME] = 0; - - /* No special handling of bytes on receive. */ - ter->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); - - /* - Enable reading data and ignore control lines */ - ter->c_cflag |= CREAD | CLOCAL; -} - /** - * @brief Set the baud rate speed in the termios structure + * @brief Convert from uart_config to native_tty_bottom_cfg eqvivalent struct * - * @param ter - * @param baudrate + * @param bottom_cfg + * @param cfg * - * @retval 0 If successful, - * @retval -ENOTSUP If requested baud rate is not supported. + * @return 0 on success, negative errno otherwise. */ -static inline int native_tty_baud_speed_set(struct termios *ter, int baudrate) +static int native_tty_conv_to_bottom_cfg(struct native_tty_bottom_cfg *bottom_cfg, + const struct uart_config *cfg) { - for (int i = 0; i < ARRAY_SIZE(baudrate_lut); i++) { - if (baudrate_lut[i].baudrate == baudrate) { - cfsetospeed(ter, baudrate_lut[i].termios_baudrate); - cfsetispeed(ter, baudrate_lut[i].termios_baudrate); - return 0; - } - } - return -ENOTSUP; -} + bottom_cfg->baudrate = cfg->baudrate; -/** - * @brief Set parity setting in the termios structure - * - * @param ter - * @param parity - * - * @retval 0 If successful. - * @retval -ENOTSUP If requested parity is not supported. - */ -static inline int native_tty_baud_parity_set(struct termios *ter, enum uart_config_parity parity) -{ - switch (parity) { + switch (cfg->parity) { case UART_CFG_PARITY_NONE: - ter->c_cflag &= ~PARENB; + bottom_cfg->parity = NTB_PARITY_NONE; break; case UART_CFG_PARITY_ODD: - ter->c_cflag |= PARENB; - ter->c_cflag |= PARODD; + bottom_cfg->parity = NTB_PARITY_ODD; break; case UART_CFG_PARITY_EVEN: - ter->c_cflag |= PARENB; - ter->c_cflag &= ~PARODD; + bottom_cfg->parity = NTB_PARITY_EVEN; break; default: - /* Parity options mark and space (UART_CFG_PARITY_MARK and UART_CFG_PARITY_SPACE) - * are not supported on this driver. - */ return -ENOTSUP; } - return 0; -} -/** - * @brief Set the number of stop bits in the termios structure - * - * @param ter - * @param stop_bits - * - * @retval 0 If successful. - * @retval -ENOTSUP If requested number of stop bits is not supported. - */ -static inline int native_tty_stop_bits_set(struct termios *ter, - enum uart_config_stop_bits stop_bits) -{ - switch (stop_bits) { + switch (cfg->data_bits) { case UART_CFG_STOP_BITS_1: - ter->c_cflag &= ~CSTOPB; + bottom_cfg->stop_bits = NTB_STOP_BITS_1; break; case UART_CFG_STOP_BITS_2: - ter->c_cflag |= CSTOPB; + bottom_cfg->stop_bits = NTB_STOP_BITS_2; break; default: - /* Anything else is not supported in termios. */ return -ENOTSUP; } - return 0; -} -/** - * @brief Set the number of data bits in the termios structure - * - * @param ter - * @param stop_bits - * - * @retval 0 If successful. - * @retval -ENOTSUP If requested number of data bits is not supported. - */ -static inline int native_tty_data_bits_set(struct termios *ter, - enum uart_config_data_bits data_bits) -{ - unsigned int data_bits_to_set; - - switch (data_bits) { + switch (cfg->data_bits) { case UART_CFG_DATA_BITS_5: - data_bits_to_set = CS5; + bottom_cfg->data_bits = NTB_DATA_BITS_5; break; case UART_CFG_DATA_BITS_6: - data_bits_to_set = CS6; + bottom_cfg->data_bits = NTB_DATA_BITS_6; break; case UART_CFG_DATA_BITS_7: - data_bits_to_set = CS7; + bottom_cfg->data_bits = NTB_DATA_BITS_7; break; case UART_CFG_DATA_BITS_8: - data_bits_to_set = CS8; + bottom_cfg->data_bits = NTB_DATA_BITS_8; break; default: - /* Anything else is not supported in termios */ return -ENOTSUP; } - /* Clear all bits that set the data size */ - ter->c_cflag &= ~CSIZE; - ter->c_cflag |= data_bits_to_set; + if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { + WARN("Could not set flow control, any kind of hw flow control is not supported.\n"); + return -ENOTSUP; + } + + bottom_cfg->flow_ctrl = NTB_FLOW_CTRL_NONE; + return 0; } @@ -225,10 +120,10 @@ static void native_tty_uart_poll_out(const struct device *dev, unsigned char out { struct native_tty_data *data = dev->data; - int ret = write(data->fd, &out_char, 1); + int ret = nsi_host_write(data->fd, &out_char, 1); if (ret == -1) { - ERROR("Could not write to %s, reason: %s\n", data->serial_port, strerror(errno)); + ERROR("Could not write to %s\n", data->serial_port); } } @@ -245,91 +140,21 @@ static int native_tty_uart_poll_in(const struct device *dev, unsigned char *p_ch { struct native_tty_data *data = dev->data; - return read(data->fd, p_char, 1) > 0 ? 0 : -1; + return nsi_host_read(data->fd, p_char, 1) > 0 ? 0 : -1; } static int native_tty_configure(const struct device *dev, const struct uart_config *cfg) { - int rc, err; int fd = ((struct native_tty_data *)dev->data)->fd; + struct native_tty_bottom_cfg bottom_cfg; - /* Structure used to control properties of a serial port */ - struct termios ter; - - /* Read current terminal driver settings */ - rc = tcgetattr(fd, &ter); - if (rc) { - WARN("Could not read terminal driver settings\n"); - return rc; - } - - native_tty_termios_defaults_set(&ter); - - rc = native_tty_baud_speed_set(&ter, cfg->baudrate); - if (rc) { - WARN("Could not set baudrate, as %d is not supported.\n", cfg->baudrate); - return rc; - } - - rc = native_tty_baud_parity_set(&ter, cfg->parity); - if (rc) { - WARN("Could not set parity.\n"); - return rc; - } - - rc = native_tty_stop_bits_set(&ter, cfg->stop_bits); - if (rc) { - WARN("Could not set number of data bits.\n"); - return rc; - } - - rc = native_tty_data_bits_set(&ter, cfg->data_bits); - if (rc) { - WARN("Could not set number of data bits.\n"); - return rc; - } - - if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { - WARN("Could not set flow control, any kind of hw flow control is not supported.\n"); - return -ENOTSUP; - } - - rc = tcsetattr(fd, TCSANOW, &ter); - if (rc) { - err = errno; - WARN("Could not set serial port settings, reason: %s\n", strerror(err)); - return err; - } - - /* tcsetattr returns success if ANY of the requested changes were successfully carried out, - * not if ALL were. So we need to read back the settings and check if they are equal to the - * requested ones. - */ - struct termios read_ter; - - rc = tcgetattr(fd, &read_ter); + int rc = native_tty_conv_to_bottom_cfg(&bottom_cfg, cfg); if (rc) { - err = errno; - WARN("Could not read serial port settings, reason: %s\n", strerror(err)); - return err; - } - - if (ter.c_cflag != read_ter.c_cflag || ter.c_iflag != read_ter.c_iflag || - ter.c_oflag != read_ter.c_oflag || ter.c_lflag != read_ter.c_lflag || - ter.c_line != read_ter.c_line || ter.c_ispeed != read_ter.c_ispeed || - ter.c_ospeed != read_ter.c_ospeed || 0 != memcmp(ter.c_cc, read_ter.c_cc, NCCS)) { - WARN("Read serial port settings do not match set ones.\n"); - return -EBADE; - } - - /* Flush both input and output */ - rc = tcflush(fd, TCIOFLUSH); - if (rc) { - WARN("Could not flush serial port\n"); + WARN("Could not convert uart config to native tty bottom cfg\n"); return rc; } - return 0; + return native_tty_configure_bottom(fd, &bottom_cfg); } static int native_tty_serial_init(const struct device *dev) @@ -337,22 +162,24 @@ static int native_tty_serial_init(const struct device *dev) struct native_tty_data *data = dev->data; struct uart_config uart_config = ((struct native_tty_config *)dev->config)->uart_config; - /* Default value for cmd_serial_port is NULL, this is due to the set 's' type in command - * line opts. If it is anything else then it was configured via command line. + /* Default value for cmd_serial_port is NULL, this is due to the set 's' type in + * command line opts. If it is anything else then it was configured via command + * line. */ if (data->cmd_serial_port) { data->serial_port = data->cmd_serial_port; } - /* Default value for cmd_baudrate is UINT32_MAX, this is due to the set 'u' type in command - * line opts. If it is anything else then it was configured via command line. + /* Default value for cmd_baudrate is UINT32_MAX, this is due to the set 'u' type in + * command line opts. If it is anything else then it was configured via command + * line. */ if (data->cmd_baudrate != UINT32_MAX) { uart_config.baudrate = data->cmd_baudrate; } - /* Serial port needs to be set either in the devicetree or provided via command line opts, - * if that is not the case, then abort. + /* Serial port needs to be set either in the devicetree or provided via command line + * opts, if that is not the case, then abort. */ if (!data->serial_port) { ERROR("%s: path to the serial port was not set.\n", dev->name); @@ -361,11 +188,8 @@ static int native_tty_serial_init(const struct device *dev) /* Try to open a serial port as with read/write access, also prevent serial port * from becoming the controlling terminal. */ - data->fd = open(data->serial_port, O_RDWR | O_NOCTTY); - if (data->fd < 0) { - ERROR("%s: failed to open serial port %s, reason: %s\n", dev->name, - data->serial_port, strerror(errno)); - } + + data->fd = native_tty_open_tty_bottom(data->serial_port); if (native_tty_configure(dev, &uart_config)) { ERROR("%s: could not configure serial port %s\n", dev->name, data->serial_port); @@ -408,7 +232,6 @@ DT_INST_FOREACH_STATUS_OKAY(NATIVE_TTY_INSTANCE); #define INST_NAME(inst) DEVICE_DT_NAME(DT_DRV_INST(inst)) - #define NATIVE_TTY_COMMAND_LINE_OPTS(inst) \ { \ .option = INST_NAME(inst) "_port", \ @@ -429,7 +252,8 @@ DT_INST_FOREACH_STATUS_OKAY(NATIVE_TTY_INSTANCE); }, /** - * @brief Adds command line options for setting serial port and baud rate for each uart device. + * @brief Adds command line options for setting serial port and baud rate for each uart + * device. */ static void native_tty_add_serial_options(void) { @@ -441,7 +265,7 @@ static void native_tty_add_serial_options(void) #define NATIVE_TTY_CLEANUP(inst) \ if (native_tty_##inst##_data.fd != 0) { \ - close(native_tty_##inst##_data.fd); \ + nsi_host_close(native_tty_##inst##_data.fd); \ } /** diff --git a/drivers/serial/uart_native_tty_bottom.c b/drivers/serial/uart_native_tty_bottom.c new file mode 100644 index 00000000000..21a2f272f10 --- /dev/null +++ b/drivers/serial/uart_native_tty_bottom.c @@ -0,0 +1,246 @@ +/** + * @brief "Bottom" of native tty uart driver + * + * Copyright (c) 2023 Marko Sagadin + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "uart_native_tty_bottom.h" + +#include +#include +#include +#include +#include +#include + +#include + +#define WARN(...) nsi_print_warning(__VA_ARGS__) +#define ERROR(...) nsi_print_error_and_exit(__VA_ARGS__) + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +struct baudrate_termios_pair { + int baudrate; + speed_t termios_baudrate; +}; + +/** + * @brief Lookup table for mapping the baud rate to the macro understood by termios. + */ +static const struct baudrate_termios_pair baudrate_lut[] = { + {1200, B1200}, {1800, B1800}, {2400, B2400}, {4800, B4800}, + {9600, B9600}, {19200, B19200}, {38400, B38400}, {57600, B57600}, + {115200, B115200}, {230400, B230400}, {460800, B460800}, {500000, B500000}, + {576000, B576000}, {921600, B921600}, {1000000, B1000000}, {1152000, B1152000}, + {1500000, B1500000}, {2000000, B2000000}, {2500000, B2500000}, {3000000, B3000000}, + {3500000, B3500000}, {4000000, B4000000}, +}; + +/** + * @brief Set given termios to defaults appropriate for communicating with serial port devices. + * + * @param ter + */ +static inline void native_tty_termios_defaults_set(struct termios *ter) +{ + /* Set terminal in "serial" mode: + * - Not canonical (no line input) + * - No signal generation from Ctr+{C|Z..} + * - No echoing + */ + ter->c_lflag &= ~(ICANON | ISIG | ECHO); + + /* No special interpretation of output bytes. + * No conversion of newline to carriage return/line feed. + */ + ter->c_oflag &= ~(OPOST | ONLCR); + + /* No software flow control. */ + ter->c_iflag &= ~(IXON | IXOFF | IXANY); + + /* No blocking, return immediately with what is available. */ + ter->c_cc[VMIN] = 0; + ter->c_cc[VTIME] = 0; + + /* No special handling of bytes on receive. */ + ter->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); + + /* - Enable reading data and ignore control lines */ + ter->c_cflag |= CREAD | CLOCAL; +} + +/** + * @brief Set the baud rate speed in the termios structure + * + * @param ter + * @param baudrate + */ +static inline void native_tty_baud_speed_set(struct termios *ter, int baudrate) +{ + for (int i = 0; i < ARRAY_SIZE(baudrate_lut); i++) { + if (baudrate_lut[i].baudrate == baudrate) { + cfsetospeed(ter, baudrate_lut[i].termios_baudrate); + cfsetispeed(ter, baudrate_lut[i].termios_baudrate); + return; + } + } + ERROR("Could not set baudrate, as %d is not supported.\n", baudrate); +} + +/** + * @brief Set parity setting in the termios structure + * + * @param ter + * @param parity + */ +static inline void native_tty_baud_parity_set(struct termios *ter, + enum native_tty_bottom_parity parity) +{ + switch (parity) { + case NTB_PARITY_NONE: + ter->c_cflag &= ~PARENB; + break; + case NTB_PARITY_ODD: + ter->c_cflag |= PARENB; + ter->c_cflag |= PARODD; + break; + case NTB_PARITY_EVEN: + ter->c_cflag |= PARENB; + ter->c_cflag &= ~PARODD; + break; + default: + /* Parity options mark and space are not supported on this driver. */ + ERROR("Could not set parity.\n"); + } +} + +/** + * @brief Set the number of stop bits in the termios structure + * + * @param ter + * @param stop_bits + * + */ +static inline void native_tty_stop_bits_set(struct termios *ter, + enum native_tty_bottom_stop_bits stop_bits) +{ + switch (stop_bits) { + case NTB_STOP_BITS_1: + ter->c_cflag &= ~CSTOPB; + break; + case NTB_STOP_BITS_2: + ter->c_cflag |= CSTOPB; + break; + default: + /* Anything else is not supported in termios. */ + ERROR("Could not set number of data bits.\n"); + } +} + +/** + * @brief Set the number of data bits in the termios structure + * + * @param ter + * @param stop_bits + * + */ +static inline void native_tty_data_bits_set(struct termios *ter, + enum native_tty_bottom_data_bits data_bits) +{ + unsigned int data_bits_to_set = CS5; + + switch (data_bits) { + case NTB_DATA_BITS_5: + data_bits_to_set = CS5; + break; + case NTB_DATA_BITS_6: + data_bits_to_set = CS6; + break; + case NTB_DATA_BITS_7: + data_bits_to_set = CS7; + break; + case NTB_DATA_BITS_8: + data_bits_to_set = CS8; + break; + default: + /* Anything else is not supported in termios */ + ERROR("Could not set number of data bits.\n"); + } + + /* Clear all bits that set the data size */ + ter->c_cflag &= ~CSIZE; + ter->c_cflag |= data_bits_to_set; +} + +int native_tty_open_tty_bottom(const char *pathname) +{ + int fd = open(pathname, O_RDWR | O_NOCTTY); + + if (fd < 0) { + ERROR("Failed to open serial port %s, errno: %i\n", pathname, errno); + } + + return fd; +} + +int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg) +{ + int rc, err; + /* Structure used to control properties of a serial port */ + struct termios ter; + + /* Read current terminal driver settings */ + rc = tcgetattr(fd, &ter); + if (rc) { + WARN("Could not read terminal driver settings\n"); + return rc; + } + + native_tty_termios_defaults_set(&ter); + + native_tty_baud_speed_set(&ter, cfg->baudrate); + native_tty_baud_parity_set(&ter, cfg->parity); + native_tty_stop_bits_set(&ter, cfg->stop_bits); + native_tty_data_bits_set(&ter, cfg->data_bits); + + cfg->flow_ctrl = NTB_FLOW_CTRL_NONE; + + rc = tcsetattr(fd, TCSANOW, &ter); + if (rc) { + err = errno; + WARN("Could not set serial port settings, reason: %s\n", strerror(err)); + return err; + } + + /* tcsetattr returns success if ANY of the requested changes were successfully carried out, + * not if ALL were. So we need to read back the settings and check if they are equal to the + * requested ones. + */ + struct termios read_ter; + + rc = tcgetattr(fd, &read_ter); + if (rc) { + err = errno; + WARN("Could not read serial port settings, reason: %s\n", strerror(err)); + return err; + } + + if (ter.c_cflag != read_ter.c_cflag || ter.c_iflag != read_ter.c_iflag || + ter.c_oflag != read_ter.c_oflag || ter.c_lflag != read_ter.c_lflag || + ter.c_line != read_ter.c_line || ter.c_ispeed != read_ter.c_ispeed || + ter.c_ospeed != read_ter.c_ospeed || 0 != memcmp(ter.c_cc, read_ter.c_cc, NCCS)) { + WARN("Read serial port settings do not match set ones.\n"); + return -1; + } + + /* Flush both input and output */ + rc = tcflush(fd, TCIOFLUSH); + if (rc) { + WARN("Could not flush serial port\n"); + return rc; + } + + return 0; +} diff --git a/drivers/serial/uart_native_tty_bottom.h b/drivers/serial/uart_native_tty_bottom.h new file mode 100644 index 00000000000..08ed367e9ec --- /dev/null +++ b/drivers/serial/uart_native_tty_bottom.h @@ -0,0 +1,82 @@ +/** + * @brief "Bottom" of native tty uart driver + * + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + * + * Copyright (c) 2023 Marko Sagadin + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DRIVERS_SERIAL_UART_NATIVE_TTY_BOTTOM_H +#define DRIVERS_SERIAL_UART_NATIVE_TTY_BOTTOM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Below enums are just differently namespaced copies of uart_config_* enums. Options that are not + * supported on the host are not listed. + */ +enum native_tty_bottom_parity { + NTB_PARITY_NONE, + NTB_PARITY_ODD, + NTB_PARITY_EVEN, +}; + +enum native_tty_bottom_stop_bits { + NTB_STOP_BITS_1, + NTB_STOP_BITS_2, +}; + +enum native_tty_bottom_data_bits { + NTB_DATA_BITS_5, + NTB_DATA_BITS_6, + NTB_DATA_BITS_7, + NTB_DATA_BITS_8, +}; + +enum native_tty_bottom_flow_control { + NTB_FLOW_CTRL_NONE, +}; + +struct native_tty_bottom_cfg { + uint32_t baudrate; + enum native_tty_bottom_parity parity; + enum native_tty_bottom_stop_bits stop_bits; + enum native_tty_bottom_data_bits data_bits; + enum native_tty_bottom_flow_control flow_ctrl; +}; + +/* Note: None of these functions are public interfaces. They are internal to the native tty driver. + */ + +/** + * @brief Opens tty port on the given pathname + * + * Returned file descriptor can be then passed to native_tty_configure_bottom to configure it. + * + * @param pathname + * + * @return file descriptor + */ +int native_tty_open_tty_bottom(const char *pathname); + +/** + * @brief Configure tty port + * + * @param fd File descriptor of the tty port. + * @param cfg Configuration struct. + * + * @retval 0 if successful, + * @retval -1 otherwise. + */ +int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_SERIAL_UART_NATIVE_TTY_BOTTOM_H */ From 5f0bb1d2775622b0f4010e53e90f3848f512e483 Mon Sep 17 00:00:00 2001 From: Marko Sagadin Date: Fri, 4 Aug 2023 20:58:57 +0200 Subject: [PATCH 0362/4498] samples: drivers: uart: native tty: Add native_sim overlay Also include it in the twister tests. Signed-off-by: Marko Sagadin --- samples/drivers/uart/native_tty/boards/native_sim.overlay | 1 + samples/drivers/uart/native_tty/sample.yaml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/uart/native_tty/boards/native_sim.overlay diff --git a/samples/drivers/uart/native_tty/boards/native_sim.overlay b/samples/drivers/uart/native_tty/boards/native_sim.overlay new file mode 100644 index 00000000000..2b055bf3de6 --- /dev/null +++ b/samples/drivers/uart/native_tty/boards/native_sim.overlay @@ -0,0 +1 @@ +#include "native_posix.overlay" diff --git a/samples/drivers/uart/native_tty/sample.yaml b/samples/drivers/uart/native_tty/sample.yaml index 92263aa8c42..1e059d9ce3a 100644 --- a/samples/drivers/uart/native_tty/sample.yaml +++ b/samples/drivers/uart/native_tty/sample.yaml @@ -3,7 +3,9 @@ sample: tests: sample.drivers.uart.native_tty: build_only: true - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: - serial - uart From a6756c36e9747dc1c847102d3316de72f523627e Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 13 Sep 2023 08:27:57 -0300 Subject: [PATCH 0363/4498] samples: wifi: esp32s2_saola: reduce RAM usage This modification frees up around ~10kB of RAM and make sample code working again. 1) Reduced net packet size and count. 2) Increase Wi-Fi heap to avoid memory allocation failure. 3) Keep log as minimal. Signed-off-by: Sylvio Alves --- samples/net/wifi/boards/esp32s2_saola.conf | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/samples/net/wifi/boards/esp32s2_saola.conf b/samples/net/wifi/boards/esp32s2_saola.conf index 713c75ad3ca..e9ce202c42c 100644 --- a/samples/net/wifi/boards/esp32s2_saola.conf +++ b/samples/net/wifi/boards/esp32s2_saola.conf @@ -1,11 +1,12 @@ CONFIG_WIFI=y -CONFIG_HEAP_MEM_POOL_SIZE=32768 +CONFIG_HEAP_MEM_POOL_SIZE=34816 + +# decrease packet count and size to save RAM +CONFIG_NET_PKT_RX_COUNT=7 +CONFIG_NET_PKT_TX_COUNT=7 +CONFIG_NET_BUF_RX_COUNT=7 +CONFIG_NET_BUF_TX_COUNT=7 -# when enabling NET_SHELL, the following -# helps to optimize memory footprint -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=8 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_IRAM_OPT=n CONFIG_ESP32_WIFI_RX_IRAM_OPT=n @@ -15,5 +16,7 @@ CONFIG_NET_L2_ETHERNET=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y +CONFIG_LOG_MODE_MINIMAL=y CONFIG_NET_LOG=y From 38c918164217965c92b04f23ca894f926bc11219 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Wed, 13 Sep 2023 14:02:58 +0200 Subject: [PATCH 0364/4498] bluetooth: tester: Service init VCS and AICS service init will be handled in auto-pts Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/src/btp_aics.c | 2 +- tests/bluetooth/tester/src/btp_vcp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_aics.c b/tests/bluetooth/tester/src/btp_aics.c index 185053ab00b..035f88fbbb2 100644 --- a/tests/bluetooth/tester/src/btp_aics.c +++ b/tests/bluetooth/tester/src/btp_aics.c @@ -557,7 +557,7 @@ uint8_t tester_init_aics(void) tester_register_command_handlers(BTP_SERVICE_ID_AICS, aics_handlers, ARRAY_SIZE(aics_handlers)); - return tester_init_vcs(); + return BTP_STATUS_SUCCESS; } uint8_t tester_unregister_aics(void) diff --git a/tests/bluetooth/tester/src/btp_vcp.c b/tests/bluetooth/tester/src/btp_vcp.c index a0000b29c51..ac3f1b92dc7 100644 --- a/tests/bluetooth/tester/src/btp_vcp.c +++ b/tests/bluetooth/tester/src/btp_vcp.c @@ -371,7 +371,7 @@ uint8_t tester_init_vocs(void) tester_register_command_handlers(BTP_SERVICE_ID_VOCS, vocs_handlers, ARRAY_SIZE(vocs_handlers)); - return tester_init_vcs(); + return BTP_STATUS_SUCCESS; } uint8_t tester_unregister_vocs(void) From 45e66de58fdc2974a8a95b72ac23ba5e09ce83e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Sun, 10 Sep 2023 14:24:12 +0200 Subject: [PATCH 0365/4498] west: Add fish shell completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add west completion for fish shell. Update others files to include the support for fish shell. Signed-off-by: Théo Battrel --- scripts/west_commands/completion.py | 8 +- .../completion/west-completion.bash | 2 +- .../completion/west-completion.fish | 371 ++++++++++++++++++ .../completion/west-completion.zsh | 2 +- 4 files changed, 380 insertions(+), 3 deletions(-) create mode 100644 scripts/west_commands/completion/west-completion.fish diff --git a/scripts/west_commands/completion.py b/scripts/west_commands/completion.py index 708d5500243..470d9a8b5f8 100644 --- a/scripts/west_commands/completion.py +++ b/scripts/west_commands/completion.py @@ -31,6 +31,12 @@ # permanent (might require sudo) west completion zsh > "${fpath[1]}/_west" + fish: + # one-time + west completion fish | source + # permanent + west completion fish > $HOME/.config/fish/completions/west.fish + positional arguments: source_dir application source directory cmake_opt extra options to pass to cmake; implies -c @@ -57,7 +63,7 @@ def do_add_parser(self, parser_adder): # Remember to update west-completion.bash if you add or remove # flags - parser.add_argument('shell', nargs=1, choices=['bash', 'zsh'], + parser.add_argument('shell', nargs=1, choices=['bash', 'zsh', 'fish'], help='''Shell that which the completion script is intended for.''') return parser diff --git a/scripts/west_commands/completion/west-completion.bash b/scripts/west_commands/completion/west-completion.bash index 48375cf486a..ca3f5669d05 100644 --- a/scripts/west_commands/completion/west-completion.bash +++ b/scripts/west_commands/completion/west-completion.bash @@ -644,7 +644,7 @@ __comp_west_completion() *) local counter=$( __west_pos_first_nonflag "$(__west_to_extglob "$global_args_opts")" ) if [ "$cword" -eq "$counter" ]; then - __set_comp "bash zsh" + __set_comp "bash zsh fish" fi ;; esac diff --git a/scripts/west_commands/completion/west-completion.fish b/scripts/west_commands/completion/west-completion.fish new file mode 100644 index 00000000000..b8fc9cfa84e --- /dev/null +++ b/scripts/west_commands/completion/west-completion.fish @@ -0,0 +1,371 @@ +# check if we are currently in a west workspace +# this is used to filter which command to show +# +# return 0 if in west workspace +# return 1 else +function __zephyr_west_check_if_in_workspace + west topdir &>/dev/null + if test $status = 0 + return 0 + else + return 1 + end +end + +# exclude the caller if one of the arguments is present in the command line +# +# return 1 if one of the arguments is present in the command line +# return 0 else +function __zephyr_west_exclude + set -l tokens (commandline -opc) + + for t in $tokens + for a in $argv + if test $t = $a + return 1 + end + end + end + + return 0 +end + +# function used to have a maximum number of arguments +# +# argv[1] is the maximum number of arguments +# argv[n] are the arguments to count, if not specified will count all arguments after 'west ' on the command line +# +# return 1 if the command line contain more than $argv[1] element from $argv[n...] +# return 0 else +function __zephyr_west_max_args + set -l tokens (commandline -opc) + set -l argc (count $argv) + set -l max $argv[1] + set -l counter 0 + + if test $argc -eq 1 + if test (math (count $tokens) - 2) -ge $max + return 1 + else + return 0 + end + end + + for idx in (seq 2 $argc) + if contains $argv[idx] $tokens + set counter (math $counter + 1) + end + end + + if $counter -ge $max + return 1 + end + + return 0 +end + +# alias of '__fish_complete_directories' but set the arguments to '' +function __zephyr_west_complete_directories + __fish_complete_directories '' '' +end + +# check if a given token is the last one in the command line +# +# return 0 if one of the given argument is the last token +# return 1 else +function __zephyr_west_is_last_token + set -l tokens (commandline -opc) + + for token in $argv + if string match -qr -- "$token*" "$tokens[-1]" + return 0 + end + end + + return 1 +end + +# function similar to '__fish_use_subcommand' but with special cases +function __zephyr_west_use_subcommand + set -l tokens (commandline -opc) + + for idx in (seq 2 (count $tokens)) + switch $tokens[$idx] + case '-*' + continue + case '*' + if test $idx -ge 3 + set -l prv_idx (math $idx - 1) + switch $tokens[$prv_idx] + # this option can be placed before subcommand and require a folder + # if we don't do that the folder will be catched as a subcommand and + # the subcommands will not be completed + case '-z' '--zephyr-base' + continue + end + end + end + return 1 + end + + return 0 +end + +# function similar to '__fish_seen_subcommand_from' but with special cases +function __zephyr_west_seen_subcommand_from + set -l tokens (commandline -opc) + set -e tokens[1] + + # special case: + # we don't want the command completion when doing `west help ` + if contains -- "help" $tokens + return 1 + end + + for token in $tokens + if contains -- $token $argv + return 0 + end + end + + return 1 +end + +# return the list of projects +function __zephyr_west_complete_projects + set -l tokens (commandline -opc) + set -l zephyr_base "" + set -l projects + + for idx in (seq 1 (count $tokens)) + if test \("$tokens[$idx]" = "-z"\) -o \("$tokens[$idx]" = "--zephyr-base"\) + if set -q $tokens[(math $idx + 1)] + set $zephyr_base $tokens (math $idx + 1) + break + end + end + end + + if test $zephyr_base != "" + set projects (west "-z $zephyr_base" list --format="{name}") + else + set projects (west list --format="{name}") + end + + printf "%s\n" $projects +end + +# return the list of available west commands +function __zephyr_west_complete_help + set -l builtin_cmds "init" "create a west repository" \ + "update" "update projects described in west manifest" \ + "list" "print information about projects" \ + "manifest" "manage the west manifest" \ + "diff" '"git diff" for one or more projects' \ + "statue" '"git status" for one or more projects' \ + "forall" "run a command in one or more local projects" \ + "config" "get or set config file values" \ + "topdir" "print the top level directory of the workspace" \ + "help" "get help for west or a command" + set -l nb_builtin_cmds (count $builtin_cmds) + + set -l ext_cmds "completion" "display shell completion scripts" \ + "boards" "display information about supported boards" \ + "build" "compile a Zephyr application" \ + "sign" "sign a Zephyr binary for bootloader chain-loading" \ + "flash" "flash and run a binary on a board" \ + "debug" "flash and interactively debug a Zephyr application" \ + "debugserver" "connect to board and launch a debug server" \ + "attach" "interactively debug a board" \ + "zephyr-export" "export Zephyr installation as a CMake config package" \ + "spdx" "create SPDX bill of materials" \ + "blobs" "work with binary blobs" + set -l nb_ext_cmds (count $ext_cmds) + + if __zephyr_west_check_if_in_workspace + for idx in (seq 1 2 $nb_ext_cmds) + set -l desc_idx (math $idx + 1) + printf "%s\n" $ext_cmds[$idx]\t"$ext_cmds[$desc_idx]" + end + end + + for idx in (seq 1 2 $nb_builtin_cmds) + set -l desc_idx (math $idx + 1) + printf "%s\n" $builtin_cmds[$idx]\t"$builtin_cmds[$desc_idx]" + end +end + +function __zephyr_west_complete_board + set -l boards (west 2>/dev/null boards --format="{name} {arch}") + for board in $boards + set -l b (string split " " $board) + printf "%s\n" $b[1]\t"$b[2]" + end +end + +# disable file completion, if an option need it, it should use '--force-files' +complete -c west -f + +# global options +complete -c west -n "__zephyr_west_exclude -h --help" -o h -l help -d "show help" +complete -c west -o v -l verbose -d "enable verbosity" +complete -c west -n "__zephyr_west_exclude -V --version" -o V -l version -d "print version" +complete -c west -n "__zephyr_west_exclude -z --zephyr-base; or __zephyr_west_is_last_token -z --zephyr-base" -o z -l zephyr-base -xa "(__zephyr_west_complete_directories)" -d "zephyr base folder" + +# init +complete -c west -n __zephyr_west_use_subcommand -ra init -d "create a west workspace" +complete -c west -n "__zephyr_west_seen_subcommand_from init" -ra "(__zephyr_west_complete_directories)" +complete -c west -n "__zephyr_west_seen_subcommand_from init; and __zephyr_west_exclude -l --local" -l mr -l manifest-rev -r -d "manifest revision" +complete -c west -n "__zephyr_west_seen_subcommand_from init" -l mf -l manifest-file -r -d "manifest file" +complete -c west -n "__zephyr_west_seen_subcommand_from init; and __zephyr_west_exclude -l --local" -o m -l manifest -ra "(__zephyr_west_complete_directories)" -d "manifest URL" +complete -c west -n "__zephyr_west_seen_subcommand_from init; and __zephyr_west_exclude -m --manifest --mr --manifest-rev" -o l -l local -ra "(__zephyr_west_complete_directories)" -d "use local directory as manifest repository" + +# update +complete -c west -n __zephyr_west_use_subcommand -ra update -d "update projects described in west manifest" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -l stats -d "print performance stats" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -l name-cache -ra "(__zephyr_west_complete_directories)" -d "name-based cache" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -l path-cache -ra "(__zephyr_west_complete_directories)" -d "path-based cache" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -o f -l fetch -ra "always smart" -d "fetch strategy" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -o o -l fetch-opt -d "fetch options" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -o n -l narrow -d "narrow fetch" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -o k -l keep-descendants -d "keep manifest-rev descendants checked out" +complete -c west -n "__zephyr_west_seen_subcommand_from update" -o r -l rebase -d "rebase checked out branch onto the new manifest-rev" + +# list +complete -c west -n __zephyr_west_use_subcommand -ra list -d "print information about projects" +complete -c west -n "__zephyr_west_seen_subcommand_from list; and not __fish_seen_subcommand_from blobs" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from list; and not __fish_seen_subcommand_from blobs" -o a -l all -d "include inactive projects" +complete -c west -n "__zephyr_west_seen_subcommand_from list; and not __fish_seen_subcommand_from blobs" -l manifest-path-from-yaml -d "print performance stats" +complete -c west -n "__zephyr_west_seen_subcommand_from list; and not __fish_seen_subcommand_from blobs" -o f -l format -d "format string" + +# manifest +complete -c west -n __zephyr_west_use_subcommand -ra manifest -d "manage the west manifest" +complete -c west -n "__zephyr_west_seen_subcommand_from manifest" -l resolve -d "resolve into single manifest" +complete -c west -n "__zephyr_west_seen_subcommand_from manifest" -l freeze -d "resolve into single manifest, with SHAs" +complete -c west -n "__zephyr_west_seen_subcommand_from manifest" -l validate -d "silently validate manifest" +complete -c west -n "__zephyr_west_seen_subcommand_from manifest" -l path -d "print the path to the top level manifest file" +complete -c west -n "__zephyr_west_seen_subcommand_from manifest" -o o -l output -rF -d "output file" + +# diff +complete -c west -n __zephyr_west_use_subcommand -ra diff -d '"git diff" for one or more projects' +complete -c west -n "__zephyr_west_seen_subcommand_from diff" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from diff" -o a -l all -d "include inactive projects" + +# status +complete -c west -n __zephyr_west_use_subcommand -ra status -d '"git status" for one or more projects' +complete -c west -n "__zephyr_west_seen_subcommand_from status" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from status" -o a -l all -d "include inactive projects" + +# forall +complete -c west -n __zephyr_west_use_subcommand -ra forall -d "run a command in one or more local projects" +complete -c west -n "__zephyr_west_seen_subcommand_from forall" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from forall" -o c -x -d "command to execute" +complete -c west -n "__zephyr_west_seen_subcommand_from forall" -o a -l all -d "include inactive projects" +complete -c west -n "__zephyr_west_seen_subcommand_from forall" -o g -l group -x -d "run command on projects in one of the group" + +# config +complete -c west -n __zephyr_west_use_subcommand -ra config -d "get or set config file values" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -o l -l list -d "list all options and values" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -o d -l delete -d "delete an option in one config file" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -o D -l delete-all -d "delete an option everywhere it's set" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -l system -d "system-wide file" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -l global -d "global user-wide" +complete -c west -n "__zephyr_west_seen_subcommand_from config" -l local -d "this workspace's file" + +# topdir +complete -c west -n __zephyr_west_use_subcommand -a topdir -d "print the top level directory of the workspace" + +# help +complete -c west -n __zephyr_west_use_subcommand -ra help -d "get help for west or a command" +complete -c west -n "__fish_seen_subcommand_from help; and __zephyr_west_max_args 1" -ra "(__zephyr_west_complete_help)" + + + +# completion +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra completion -d "display shell completion scripts" +complete -c west -n "__zephyr_west_seen_subcommand_from completion; and __zephyr_west_max_args 1" -ra "bash zsh fish" + +# boards +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra boards -d "display information about supported boards" +complete -c west -n "__zephyr_west_seen_subcommand_from boards" -o f -l format -d "format string" +complete -c west -n "__zephyr_west_seen_subcommand_from boards" -o n -l name -d "name regex" +complete -c west -n "__zephyr_west_seen_subcommand_from boards" -l arch-root -xa "(__zephyr_west_complete_directories)" -d "add an arch root" +complete -c west -n "__zephyr_west_seen_subcommand_from boards" -l board-root -xa "(__zephyr_west_complete_directories)" -d "add a board root" + +# build +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra build -d "compile a Zephyr application" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -ra "(__zephyr_west_complete_directories)" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o b -l board -xa "(__zephyr_west_complete_board)" -d "board to build for" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o d -l build-dir -xa "(__zephyr_west_complete_directories)" -d "build directory to create or use" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o f -l force -d "ignore errors and continue" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -l sysbuild -d "create multi-domain build system" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -l no-sysbuild -d "do not create multi-domain build system" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o c -l cmake -d "force a cmake run" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -l domain -d "execute build tool (make or ninja) for a given domain" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o t -l target -d "run build system target" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o T -l test-item -d "build based on test data in .yml" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o o -l build-opt -d "options to pass to build tool (make or ninja)" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o n -l just-print -l dry-run -l recon -d "just print build commands, don't run them" +complete -c west -n "__zephyr_west_seen_subcommand_from build" -o p -l pristine -ra "auto always never" -d "pristine build setting" + +# sign +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra sign -d "sign a Zephyr binary for bootloader chain-loading" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o d -l build-dir -ra "(__zephyr_west_complete_directories)" -d "build directory to create or use" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o q -l quiet -d "suppress non-error output" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o f -l force -d "ignore errors and continue" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o t -l tool -ra "imgtool rimage" -d "image signing tool name" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o p -l tool-path -ra "(__zephyr_west_complete_directories)" -d "path to the tool" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o P -l tool-data -ra "(__zephyr_west_complete_directories)" -d "path to tool data" +complete -c west -n "__zephyr_west_seen_subcommand_from sign; and __zephyr_west_exclude --no-bin" -l bin -d "produce a signed bin file" +complete -c west -n "__zephyr_west_seen_subcommand_from sign; and __zephyr_west_exclude --bin" -l no-bin -d "do not produce a signed bin file" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o B -l sbin -rF -d "signed .bin filename" +complete -c west -n "__zephyr_west_seen_subcommand_from sign; and __zephyr_west_exclude --no-hex" -l hex -d "produce a signed hex file" +complete -c west -n "__zephyr_west_seen_subcommand_from sign; and __zephyr_west_exclude --hex" -l no-hex -d "do not produce a signed hex file" +complete -c west -n "__zephyr_west_seen_subcommand_from sign" -o H -l shex -rF -d "signed .hex filename" + +# flash +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra flash -d "flash and run a binary on a board" + +# debug +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra debug -d "flash and interactively debug a Zephyr application" + +# debugserver +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra debugserver -d "connect to board and launch a debug server" + +# attach +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra attach -d "interactively debug a board" + +## flash, debug, debugserver, attach +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -o d -l build-dir -ra "(__zephyr_west_complete_directories)" -d "build directory to create or use" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -o r -l runner -r -d "override default runner from build-dir" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l skip-rebuild -d "do not refresh cmake dependencies first" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l domain -r -d "execute build tool (make or ninja) for a given domain" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -o H -l context -d "print runner-specific options" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l board-dir -ra "(__zephyr_west_complete_directories)" -d "board directory" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -o f -l file -Fr -d "path to binary" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -o t -l file-type -ra "hex bin elf" -d "type of binary" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l elf-file -rka "(__fish_complete_suffix .elf)" -d "path to zephyr.elf" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l hex-file -rka "(__fish_complete_suffix .hex)" -d "path to zephyr.hex" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l bin-file -rka "(__fish_complete_suffix .bin)" -d "path to zephyr.bin" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l gdb -Fr -d "path to GDB" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l openocd -Fr -d "path to openocd" +complete -c west -n "__zephyr_west_seen_subcommand_from flash debug debugserver attach" -l openocd-search -ra "(__zephyr_west_complete_directories)" -d "path to add to openocd search path" + +# zephyr-export +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra zephyr-export -d "export Zephyr installation as a CMake config package" + +# spdx +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra spdx -d "create SPDX bill of materials" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -o i -l init -d "initialize CMake file-based API" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -o d -l build-dir -ra "(__zephyr_west_complete_directories)" -d "build directory to create or use" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -o n -l namespace-prefix -rf -d "namespace prefix" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -o s -l spdx-dir -ra "(__zephyr_west_complete_directories)" -d "SPDX output directory" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -l analyze-includes -d "also analyze included header files" +complete -c west -n "__zephyr_west_seen_subcommand_from spdx" -l include-sdk -d "also generate SPDX document for SDK" + +# blobs +complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra blobs -d "work with binary blobs" +complete -c west -n "__zephyr_west_seen_subcommand_from blobs; and not __fish_seen_subcommand_from list fetch clean" -ra "list\t'list binary blobs' fetch\t'fetch binary blobs' clean\t'clean working tree of binary blobs'" +complete -c west -n "__zephyr_west_seen_subcommand_from blobs; and __fish_seen_subcommand_from list fetch clean" -ra "(__zephyr_west_complete_projects)" +complete -c west -n "__zephyr_west_seen_subcommand_from blobs; and not __fish_seen_subcommand_from fetch clean" -o f -l format -r -d "format string" diff --git a/scripts/west_commands/completion/west-completion.zsh b/scripts/west_commands/completion/west-completion.zsh index 8cca9b5eee0..43c7c0ffc19 100644 --- a/scripts/west_commands/completion/west-completion.zsh +++ b/scripts/west_commands/completion/west-completion.zsh @@ -205,7 +205,7 @@ _west_help() { _west_completion() { - _arguments -S "1:shell:(bash zsh)" + _arguments -S "1:shell:(bash zsh fish)" } _west_boards() { From 87209984f3a3048a1deca9523ed334df044570be Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 16 Jul 2023 22:51:26 +0900 Subject: [PATCH 0366/4498] devicetree: rename and publish DT_COMPAT_ON_BUS_INTERNAL Rename `DT_COMPAT_ON_BUS_INTERNAL` to `DT_HAS_COMPAT_ON_BUS_STATUS_OKAY` to make it a public DT API. It is helpful for code that handles multiple DT_DRV_COMPAT in one file, such as in the following cases. ``` #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(some_sensor, i2c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(another_sensor, i2c) ... #endif #define DT_DRV_COMPAT some_sensor DT_INST_FOREACH_STATUS_OKAY(DEFINE_SOME_SENSOR) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT another_sensor DT_INST_FOREACH_STATUS_OKAY(DEFINE_ANOTHER_SENSOR) ``` Signed-off-by: TOKITA Hiroshi --- include/zephyr/devicetree.h | 38 ++++++++++++++++++++++++++--- tests/lib/devicetree/api/src/main.c | 14 +++++------ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index ff0ecb0a33f..9154d346739 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -3888,6 +3888,39 @@ #define DT_INST_STRING_UNQUOTED_OR(inst, name, default_value) \ DT_STRING_UNQUOTED_OR(DT_DRV_INST(inst), name, default_value) +/* + * @brief Test if any enabled node with the given compatible is on + * the given bus type + * + * This is like DT_ANY_INST_ON_BUS_STATUS_OKAY(), except it can also + * be useful for handling multiple compatibles in single source file. + * + * Example devicetree overlay: + * + * @code{.dts} + * &i2c0 { + * temp: temperature-sensor@76 { + * compatible = "vnd,some-sensor"; + * reg = <0x76>; + * }; + * }; + * @endcode + * + * Example usage, assuming `i2c0` is an I2C bus controller node, and + * therefore `temp` is on an I2C bus: + * + * @code{.c} + * DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_some_sensor, i2c) // 1 + * @endcode + * + * @param compat lowercase-and-underscores compatible, without quotes + * @param bus a binding's bus type as a C token, lowercased and without quotes + * @return 1 if any enabled node with that compatible is on that bus type, + * 0 otherwise + */ +#define DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(compat, bus) \ + IS_ENABLED(UTIL_CAT(DT_CAT(DT_COMPAT_, compat), _BUS_##bus)) + /** * @brief Test if any `DT_DRV_COMPAT` node is on a bus of a given type * and has status okay @@ -3921,7 +3954,7 @@ * 0 otherwise */ #define DT_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ - DT_COMPAT_ON_BUS_INTERNAL(DT_DRV_COMPAT, bus) + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT, bus) /** * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given @@ -4253,9 +4286,6 @@ /** @brief Helper for DT_NODE_HAS_STATUS */ #define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \ IS_ENABLED(DT_CAT3(node_id, _STATUS_, status)) -/** @brief Helper for test cases and DT_ANY_INST_ON_BUS_STATUS_OKAY() */ -#define DT_COMPAT_ON_BUS_INTERNAL(compat, bus) \ - IS_ENABLED(UTIL_CAT(DT_CAT(DT_COMPAT_, compat), _BUS_##bus)) /** @brief Helper macro to OR multiple has property checks in a loop macro */ #define DT_INST_NODE_HAS_PROP_AND_OR(inst, prop) \ diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 906907a0ea1..aec48e6a9c9 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -482,18 +482,18 @@ ZTEST(devicetree_api, test_bus) #undef DT_DRV_COMPAT /* - * Make sure the underlying DT_COMPAT_ON_BUS_INTERNAL used by + * Make sure the underlying DT_HAS_COMPAT_ON_BUS_STATUS_OKAY used by * DT_ANY_INST_ON_BUS works without DT_DRV_COMPAT defined. */ - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_spi_device, spi), 1); - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_spi_device, i2c), 0); + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_spi_device, spi), 1); + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_spi_device, i2c), 0); - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_i2c_device, i2c), 1); - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_i2c_device, spi), 0); + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_i2c_device, i2c), 1); + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_i2c_device, spi), 0); - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_gpio_expander, i2c), 1, + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_gpio_expander, i2c), 1, NULL); - zassert_equal(DT_COMPAT_ON_BUS_INTERNAL(vnd_gpio_expander, spi), 1, + zassert_equal(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_gpio_expander, spi), 1, NULL); } From 237c2aaa792fca288570a02672ccad8d98baa1f3 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 16 Apr 2023 15:26:54 +0900 Subject: [PATCH 0367/4498] drivers: display: ssd1306: add dts properties to ssd1306_config Store properties defined in dts in ssd1306_config's fields. And replace code that uses DT_INST_PROP (0, ...) by config properties. Signed-off-by: TOKITA Hiroshi --- drivers/display/ssd1306.c | 83 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 489f02c597b..de237931984 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -20,25 +20,6 @@ LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); #include "ssd1306_regs.h" -#if DT_INST_PROP(0, segment_remap) == 1 -#define SSD1306_PANEL_SEGMENT_REMAP true -#else -#define SSD1306_PANEL_SEGMENT_REMAP false -#endif - -#if DT_INST_PROP(0, com_invdir) == 1 -#define SSD1306_PANEL_COM_INVDIR true -#else -#define SSD1306_PANEL_COM_INVDIR false -#endif - -#if DT_INST_PROP(0, com_sequential) == 1 -#define SSD1306_COM_PINS_HW_CONFIG SSD1306_SET_PADS_HW_SEQUENTIAL -#else -#define SSD1306_COM_PINS_HW_CONFIG SSD1306_SET_PADS_HW_ALTERNATIVE -#endif - -#define SSD1306_PANEL_NUMOF_PAGES (DT_INST_PROP(0, height) / 8) #define SSD1306_CLOCK_DIV_RATIO 0x0 #define SSD1306_CLOCK_FREQUENCY 0x8 #define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 @@ -56,6 +37,16 @@ struct ssd1306_config { struct gpio_dt_spec data_cmd; #endif struct gpio_dt_spec reset; + uint16_t height; + uint16_t width; + uint8_t segment_offset; + uint8_t page_offset; + uint8_t display_offset; + uint8_t multiplex_ratio; + uint8_t prechargep; + bool segment_remap; + bool com_invdir; + bool com_sequential; int ready_time_ms; }; @@ -122,42 +113,40 @@ static inline int ssd1306_write_bus(const struct device *dev, static inline int ssd1306_set_panel_orientation(const struct device *dev) { - uint8_t cmd_buf[] = { - (SSD1306_PANEL_SEGMENT_REMAP ? - SSD1306_SET_SEGMENT_MAP_REMAPED : - SSD1306_SET_SEGMENT_MAP_NORMAL), - (SSD1306_PANEL_COM_INVDIR ? - SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED : - SSD1306_SET_COM_OUTPUT_SCAN_NORMAL) - }; + const struct ssd1306_config *config = dev->config; + uint8_t cmd_buf[] = {(config->segment_remap ? SSD1306_SET_SEGMENT_MAP_REMAPED + : SSD1306_SET_SEGMENT_MAP_NORMAL), + (config->com_invdir ? SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED + : SSD1306_SET_COM_OUTPUT_SCAN_NORMAL)}; return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } static inline int ssd1306_set_timing_setting(const struct device *dev) { - uint8_t cmd_buf[] = { - SSD1306_SET_CLOCK_DIV_RATIO, - (SSD1306_CLOCK_FREQUENCY << 4) | SSD1306_CLOCK_DIV_RATIO, - SSD1306_SET_CHARGE_PERIOD, - DT_INST_PROP(0, prechargep), - SSD1306_SET_VCOM_DESELECT_LEVEL, - SSD1306_PANEL_VCOM_DESEL_LEVEL - }; + const struct ssd1306_config *config = dev->config; + uint8_t cmd_buf[] = {SSD1306_SET_CLOCK_DIV_RATIO, + (SSD1306_CLOCK_FREQUENCY << 4) | SSD1306_CLOCK_DIV_RATIO, + SSD1306_SET_CHARGE_PERIOD, + config->prechargep, + SSD1306_SET_VCOM_DESELECT_LEVEL, + SSD1306_PANEL_VCOM_DESEL_LEVEL}; return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } static inline int ssd1306_set_hardware_config(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_SET_START_LINE, SSD1306_SET_DISPLAY_OFFSET, - DT_INST_PROP(0, display_offset), + config->display_offset, SSD1306_SET_PADS_HW_CONFIG, - SSD1306_COM_PINS_HW_CONFIG, + (config->com_sequential ? SSD1306_SET_PADS_HW_SEQUENTIAL + : SSD1306_SET_PADS_HW_ALTERNATIVE), SSD1306_SET_MULTIPLEX_RATIO, - DT_INST_PROP(0, multiplex_ratio) + config->multiplex_ratio, }; return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); @@ -248,7 +237,8 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 return ssd1306_write_bus(dev, (uint8_t *)buf, buf_len, false); #elif defined(CONFIG_SSD1306_SH1106_COMPATIBLE) - uint8_t x_offset = x + DT_INST_PROP(0, segment_offset); + const struct ssd1306_config *config = dev->config; + uint8_t x_offset = x + config->segment_offset; uint8_t cmd_buf[] = { SSD1306_SET_LOWER_COL_ADDRESS | (x_offset & SSD1306_SET_LOWER_COL_ADDRESS_MASK), @@ -317,9 +307,10 @@ static int ssd1306_set_contrast(const struct device *dev, const uint8_t contrast static void ssd1306_get_capabilities(const struct device *dev, struct display_capabilities *caps) { + const struct ssd1306_config *config = dev->config; memset(caps, 0, sizeof(struct display_capabilities)); - caps->x_resolution = DT_INST_PROP(0, width); - caps->y_resolution = DT_INST_PROP(0, height); + caps->x_resolution = config->width; + caps->y_resolution = config->height; caps->supported_pixel_formats = PIXEL_FORMAT_MONO10; caps->current_pixel_format = PIXEL_FORMAT_MONO10; caps->screen_info = SCREEN_INFO_MONO_VTILED; @@ -438,6 +429,16 @@ static const struct ssd1306_config ssd1306_config = { .data_cmd = GPIO_DT_SPEC_INST_GET(0, data_cmd_gpios), #endif .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), + .height = DT_INST_PROP(0, height), + .width = DT_INST_PROP(0, width), + .segment_offset = DT_INST_PROP(0, segment_offset), + .page_offset = DT_INST_PROP(0, page_offset), + .display_offset = DT_INST_PROP(0, display_offset), + .multiplex_ratio = DT_INST_PROP(0, multiplex_ratio), + .segment_remap = DT_INST_PROP(0, segment_remap), + .com_invdir = DT_INST_PROP(0, com_invdir), + .com_sequential = DT_INST_PROP(0, com_sequential), + .prechargep = DT_INST_PROP(0, prechargep), .ready_time_ms = DT_INST_PROP(0, ready_time_ms), }; From 91d750ea9482cb5304bc1cb5598adc1ab08ffea5 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 16 Apr 2023 15:16:19 +0900 Subject: [PATCH 0368/4498] drivers: display: ssd1306: replace SSD1306_REVERSE_MODE by property When multiple devices are connected, the SSD1306_REVERSE_MODE setting cannot switch for each device. Add an equivalent setting to the devicetree properties to replace it. Signed-off-by: TOKITA Hiroshi --- drivers/display/Kconfig.ssd1306 | 5 ----- drivers/display/ssd1306.c | 9 ++++----- dts/bindings/display/solomon,ssd1306fb-common.yaml | 4 ++++ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index 443e096ed84..af7992b09b4 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -35,9 +35,4 @@ config SSD1306_SH1106_COMPATIBLE endchoice -config SSD1306_REVERSE_MODE - bool "SSD1306 reverse mode" - help - SSD1306 reverse video mode. - endif # SSD1306 diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index de237931984..f0b9fccd5d4 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -47,6 +47,7 @@ struct ssd1306_config { bool segment_remap; bool com_invdir; bool com_sequential; + bool color_inversion; int ready_time_ms; }; @@ -340,11 +341,8 @@ static int ssd1306_init_device(const struct device *dev) uint8_t cmd_buf[] = { SSD1306_SET_ENTIRE_DISPLAY_OFF, -#ifdef CONFIG_SSD1306_REVERSE_MODE - SSD1306_SET_REVERSE_DISPLAY, -#else - SSD1306_SET_NORMAL_DISPLAY, -#endif + (config->color_inversion ? SSD1306_SET_REVERSE_DISPLAY + : SSD1306_SET_NORMAL_DISPLAY), }; /* Reset if pin connected */ @@ -439,6 +437,7 @@ static const struct ssd1306_config ssd1306_config = { .com_invdir = DT_INST_PROP(0, com_invdir), .com_sequential = DT_INST_PROP(0, com_sequential), .prechargep = DT_INST_PROP(0, prechargep), + .color_inversion = DT_INST_PROP(0, inversion_on), .ready_time_ms = DT_INST_PROP(0, ready_time_ms), }; diff --git a/dts/bindings/display/solomon,ssd1306fb-common.yaml b/dts/bindings/display/solomon,ssd1306fb-common.yaml index bba993a58c8..c4e82d84324 100644 --- a/dts/bindings/display/solomon,ssd1306fb-common.yaml +++ b/dts/bindings/display/solomon,ssd1306fb-common.yaml @@ -49,6 +49,10 @@ properties: If connected directly the MCU pin should be configured as active low. + inversion-on: + type: boolean + description: Turn on display color inverting + ready-time-ms: type: int default: 10 From 2f7e822705386b9569e44d25370b9c940abfb63f Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 16 Apr 2023 15:15:33 +0900 Subject: [PATCH 0369/4498] drivers: display: ssd1306: determin sh1106 by dts compatibility Determine sh1106 from the `compatibility` value instead of the SSD1306_CONTROLLER_TYPE setting. Change the settings in `boards/shields/ssd1306/sh1106_128x64.overlay` to follow this change. Remove the SSD1306_CONTROLLER_TYPE from its Kconfig.defconfig, and set the `compatibility` to `sinowealth,sh1106`. Signed-off-by: TOKITA Hiroshi --- boards/shields/ssd1306/Kconfig.defconfig | 4 - boards/shields/ssd1306/sh1106_128x64.overlay | 2 +- drivers/display/Kconfig.ssd1306 | 18 +--- drivers/display/ssd1306.c | 95 +++++++++++-------- .../display/sinowealth,sh1106-i2c.yaml | 8 ++ .../display/sinowealth,sh1106-spi.yaml | 14 +++ dts/bindings/vendor-prefixes.txt | 1 + 7 files changed, 82 insertions(+), 60 deletions(-) create mode 100644 dts/bindings/display/sinowealth,sh1106-i2c.yaml create mode 100644 dts/bindings/display/sinowealth,sh1106-spi.yaml diff --git a/boards/shields/ssd1306/Kconfig.defconfig b/boards/shields/ssd1306/Kconfig.defconfig index 960247d2f1d..3fc5d5a7c05 100644 --- a/boards/shields/ssd1306/Kconfig.defconfig +++ b/boards/shields/ssd1306/Kconfig.defconfig @@ -5,10 +5,6 @@ if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X64_SPI || SHIELD_SSD1306_128X32 | if DISPLAY -choice SSD1306_CONTROLLER_TYPE - default SSD1306_SH1106_COMPATIBLE if SHIELD_SH1106_128X64 -endchoice - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/shields/ssd1306/sh1106_128x64.overlay b/boards/shields/ssd1306/sh1106_128x64.overlay index 354b818cbd8..a9e4e0768ad 100644 --- a/boards/shields/ssd1306/sh1106_128x64.overlay +++ b/boards/shields/ssd1306/sh1106_128x64.overlay @@ -14,7 +14,7 @@ status = "okay"; sh1106_sh1106_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "sinowealth,sh1106"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index af7992b09b4..32f8b0e1423 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -6,9 +6,11 @@ menuconfig SSD1306 bool "SSD1306 display driver" default y - depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED + depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),spi) help Enable driver for SSD1306 display driver. @@ -21,18 +23,4 @@ config SSD1306_DEFAULT_CONTRAST help SSD1306 default contrast. -choice SSD1306_CONTROLLER_TYPE - prompt "Display controller type" - default SSD1306_DEFAULT - help - Specify the type of the controller. - -config SSD1306_DEFAULT - bool "Default SSD1306 controller" - -config SSD1306_SH1106_COMPATIBLE - bool "SH1106 compatible mode" - -endchoice - endif # SSD1306 diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index f0b9fccd5d4..95457ff7865 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -4,7 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_DT_HAS_SOLOMON_SSD1306FB_ENABLED) #define DT_DRV_COMPAT solomon_ssd1306fb +#elif defined(CONFIG_DT_HAS_SINOWEALTH_SH1106_ENABLED) +#define DT_DRV_COMPAT sinowealth_sh1106 +#endif #include LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); @@ -48,6 +52,7 @@ struct ssd1306_config { bool com_invdir; bool com_sequential; bool color_inversion; + bool sh1106_compatible; int ready_time_ms; }; @@ -155,15 +160,11 @@ static inline int ssd1306_set_hardware_config(const struct device *dev) static inline int ssd1306_set_charge_pump(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { -#if defined(CONFIG_SSD1306_DEFAULT) - SSD1306_SET_CHARGE_PUMP_ON, - SSD1306_SET_CHARGE_PUMP_ON_ENABLED, -#endif -#if defined(CONFIG_SSD1306_SH1106_COMPATIBLE) - SH1106_SET_DCDC_MODE, - SH1106_SET_DCDC_ENABLED, -#endif + (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP_ON), + (config->sh1106_compatible ? SH1106_SET_DCDC_ENABLED + : SSD1306_SET_CHARGE_PUMP_ON_ENABLED), SSD1306_PANEL_PUMP_VOLTAGE, }; @@ -188,37 +189,10 @@ static int ssd1306_suspend(const struct device *dev) return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } -static int ssd1306_write(const struct device *dev, const uint16_t x, const uint16_t y, - const struct display_buffer_descriptor *desc, - const void *buf) +static int ssd1306_write_default(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf, + const size_t buf_len) { - size_t buf_len; - - if (desc->pitch < desc->width) { - LOG_ERR("Pitch is smaller then width"); - return -1; - } - - buf_len = MIN(desc->buf_size, desc->height * desc->width / 8); - if (buf == NULL || buf_len == 0U) { - LOG_ERR("Display buffer is not available"); - return -1; - } - - if (desc->pitch > desc->width) { - LOG_ERR("Unsupported mode"); - return -1; - } - - if ((y & 0x7) != 0U) { - LOG_ERR("Unsupported origin"); - return -1; - } - - LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", - x, y, desc->pitch, desc->width, desc->height, buf_len); - -#if defined(CONFIG_SSD1306_DEFAULT) uint8_t cmd_buf[] = { SSD1306_SET_MEM_ADDRESSING_MODE, SSD1306_ADDRESSING_MODE, @@ -236,8 +210,12 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 } return ssd1306_write_bus(dev, (uint8_t *)buf, buf_len, false); +} -#elif defined(CONFIG_SSD1306_SH1106_COMPATIBLE) +static int ssd1306_write_sh1106(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf, + const size_t buf_len) +{ const struct ssd1306_config *config = dev->config; uint8_t x_offset = x + config->segment_offset; uint8_t cmd_buf[] = { @@ -268,11 +246,47 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 return -1; } } -#endif return 0; } +static int ssd1306_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + const struct ssd1306_config *config = dev->config; + size_t buf_len; + + if (desc->pitch < desc->width) { + LOG_ERR("Pitch is smaller then width"); + return -1; + } + + buf_len = MIN(desc->buf_size, desc->height * desc->width / 8); + if (buf == NULL || buf_len == 0U) { + LOG_ERR("Display buffer is not available"); + return -1; + } + + if (desc->pitch > desc->width) { + LOG_ERR("Unsupported mode"); + return -1; + } + + if ((y & 0x7) != 0U) { + LOG_ERR("Unsupported origin"); + return -1; + } + + LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, + desc->width, desc->height, buf_len); + + if (config->sh1106_compatible) { + return ssd1306_write_sh1106(dev, x, y, desc, buf, buf_len); + } + + return ssd1306_write_default(dev, x, y, desc, buf, buf_len); +} + static int ssd1306_read(const struct device *dev, const uint16_t x, const uint16_t y, const struct display_buffer_descriptor *desc, @@ -438,6 +452,7 @@ static const struct ssd1306_config ssd1306_config = { .com_sequential = DT_INST_PROP(0, com_sequential), .prechargep = DT_INST_PROP(0, prechargep), .color_inversion = DT_INST_PROP(0, inversion_on), + .sh1106_compatible = DT_NODE_HAS_COMPAT(0, sinowealth_sh1106), .ready_time_ms = DT_INST_PROP(0, ready_time_ms), }; diff --git a/dts/bindings/display/sinowealth,sh1106-i2c.yaml b/dts/bindings/display/sinowealth,sh1106-i2c.yaml new file mode 100644 index 00000000000..f476f838bbf --- /dev/null +++ b/dts/bindings/display/sinowealth,sh1106-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: SH1106 128x64 dot-matrix display controller on I2C bus + +compatible: "sinowealth,sh1106" + +include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/sinowealth,sh1106-spi.yaml b/dts/bindings/display/sinowealth,sh1106-spi.yaml new file mode 100644 index 00000000000..5fe3a2cf0f5 --- /dev/null +++ b/dts/bindings/display/sinowealth,sh1106-spi.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: SH1106 128x64 dot-matrix display controller on SPI bus + +compatible: "sinowealth,sh1106" + +include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] + +properties: + data_cmd-gpios: + type: phandle-array + required: true + description: D/C# pin. diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index a2af2b9249a..4b2ab91c73e 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -563,6 +563,7 @@ simcom SIMCom Wireless Solutions Co., LTD simtek Cypress Semiconductor Corporation (Simtek Corporation) sinlinx Sinlinx Electronics Technology Co., LTD sinovoip SinoVoip Co., Ltd +sinowealth Sino Wealth Electronic Ltd sipeed Shenzhen Sipeed Technology Co., Ltd. sirf SiRF Technology, Inc. sis Silicon Integrated Systems Corp. From 9fcfb31c8259818ed150fe940196fae8b24414f5 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 14 Apr 2023 01:27:19 +0900 Subject: [PATCH 0370/4498] drivers: display: ssd1306: Support connecting SPI and I2C at the same Support connecting different display for each SPI and I2C at the same time. In a case like DTS below. ``` &spi1 { ssd1306_spi: ssd1306@0 { compatible = "solomon,ssd1306fb"; ... }; }; &i2c0 { ssd1306_i2c: ssd1306@3c { compatible = "solomon,ssd1306fb"; ... }; }; ``` Signed-off-by: TOKITA Hiroshi --- drivers/display/ssd1306.c | 152 ++++++++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 55 deletions(-) diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 95457ff7865..0f17293a70f 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -4,12 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_DT_HAS_SOLOMON_SSD1306FB_ENABLED) -#define DT_DRV_COMPAT solomon_ssd1306fb -#elif defined(CONFIG_DT_HAS_SINOWEALTH_SH1106_ENABLED) -#define DT_DRV_COMPAT sinowealth_sh1106 -#endif - #include LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); @@ -33,14 +27,23 @@ LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); #define SSD1306_ADDRESSING_MODE (SSD1306_SET_MEM_ADDRESSING_HORIZONTAL) #endif +union ssd1306_bus { + struct i2c_dt_spec i2c; + struct spi_dt_spec spi; +}; + +typedef bool (*ssd1306_bus_ready_fn)(const struct device *dev); +typedef int (*ssd1306_write_bus_fn)(const struct device *dev, uint8_t *buf, size_t len, + bool command); +typedef const char *(*ssd1306_bus_name_fn)(const struct device *dev); + struct ssd1306_config { -#if DT_INST_ON_BUS(0, i2c) - struct i2c_dt_spec bus; -#elif DT_INST_ON_BUS(0, spi) - struct spi_dt_spec bus; + union ssd1306_bus bus; struct gpio_dt_spec data_cmd; -#endif struct gpio_dt_spec reset; + ssd1306_bus_ready_fn bus_ready; + ssd1306_write_bus_fn write_bus; + ssd1306_bus_name_fn bus_name; uint16_t height; uint16_t width; uint8_t segment_offset; @@ -61,29 +64,36 @@ struct ssd1306_data { uint8_t scan_mode; }; -#if DT_INST_ON_BUS(0, i2c) - -static inline bool ssd1306_bus_ready(const struct device *dev) +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, i2c)) +static bool ssd1306_bus_ready_i2c(const struct device *dev) { const struct ssd1306_config *config = dev->config; - return device_is_ready(config->bus.bus); + return i2c_is_ready_dt(&config->bus.i2c); } -static inline int ssd1306_write_bus(const struct device *dev, - uint8_t *buf, size_t len, bool command) +static int ssd1306_write_bus_i2c(const struct device *dev, uint8_t *buf, size_t len, bool command) { const struct ssd1306_config *config = dev->config; - return i2c_burst_write_dt(&config->bus, + return i2c_burst_write_dt(&config->bus.i2c, command ? SSD1306_CONTROL_ALL_BYTES_CMD : SSD1306_CONTROL_ALL_BYTES_DATA, buf, len); } -#elif DT_INST_ON_BUS(0, spi) +static const char *ssd1306_bus_name_i2c(const struct device *dev) +{ + const struct ssd1306_config *config = dev->config; -static inline bool ssd1306_bus_ready(const struct device *dev) + return config->bus.i2c.bus->name; +} +#endif + +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, spi)) +static bool ssd1306_bus_ready_spi(const struct device *dev) { const struct ssd1306_config *config = dev->config; @@ -91,11 +101,10 @@ static inline bool ssd1306_bus_ready(const struct device *dev) return false; } - return spi_is_ready_dt(&config->bus); + return spi_is_ready_dt(&config->bus.spi); } -static inline int ssd1306_write_bus(const struct device *dev, - uint8_t *buf, size_t len, bool command) +static int ssd1306_write_bus_spi(const struct device *dev, uint8_t *buf, size_t len, bool command) { const struct ssd1306_config *config = dev->config; int errno; @@ -111,12 +120,34 @@ static inline int ssd1306_write_bus(const struct device *dev, .count = 1 }; - errno = spi_write_dt(&config->bus, &tx_bufs); + errno = spi_write_dt(&config->bus.spi, &tx_bufs); return errno; } + +static const char *ssd1306_bus_name_spi(const struct device *dev) +{ + const struct ssd1306_config *config = dev->config; + + return config->bus.spi.bus->name; +} #endif +static inline bool ssd1306_bus_ready(const struct device *dev) +{ + const struct ssd1306_config *config = dev->config; + + return config->bus_ready(dev); +} + +static inline int ssd1306_write_bus(const struct device *dev, uint8_t *buf, size_t len, + bool command) +{ + const struct ssd1306_config *config = dev->config; + + return config->write_bus(dev, buf, len, command); +} + static inline int ssd1306_set_panel_orientation(const struct device *dev) { const struct ssd1306_config *config = dev->config; @@ -410,7 +441,7 @@ static int ssd1306_init(const struct device *dev) k_sleep(K_TIMEOUT_ABS_MS(config->ready_time_ms)); if (!ssd1306_bus_ready(dev)) { - LOG_ERR("Bus device %s not ready!", config->bus.bus->name); + LOG_ERR("Bus device %s not ready!", config->bus_name(dev)); return -EINVAL; } @@ -432,32 +463,6 @@ static int ssd1306_init(const struct device *dev) return 0; } -static const struct ssd1306_config ssd1306_config = { -#if DT_INST_ON_BUS(0, i2c) - .bus = I2C_DT_SPEC_INST_GET(0), -#elif DT_INST_ON_BUS(0, spi) - .bus = SPI_DT_SPEC_INST_GET( - 0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0), - .data_cmd = GPIO_DT_SPEC_INST_GET(0, data_cmd_gpios), -#endif - .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), - .height = DT_INST_PROP(0, height), - .width = DT_INST_PROP(0, width), - .segment_offset = DT_INST_PROP(0, segment_offset), - .page_offset = DT_INST_PROP(0, page_offset), - .display_offset = DT_INST_PROP(0, display_offset), - .multiplex_ratio = DT_INST_PROP(0, multiplex_ratio), - .segment_remap = DT_INST_PROP(0, segment_remap), - .com_invdir = DT_INST_PROP(0, com_invdir), - .com_sequential = DT_INST_PROP(0, com_sequential), - .prechargep = DT_INST_PROP(0, prechargep), - .color_inversion = DT_INST_PROP(0, inversion_on), - .sh1106_compatible = DT_NODE_HAS_COMPAT(0, sinowealth_sh1106), - .ready_time_ms = DT_INST_PROP(0, ready_time_ms), -}; - -static struct ssd1306_data ssd1306_driver; - static struct display_driver_api ssd1306_driver_api = { .blanking_on = ssd1306_suspend, .blanking_off = ssd1306_resume, @@ -471,7 +476,44 @@ static struct display_driver_api ssd1306_driver_api = { .set_orientation = ssd1306_set_orientation, }; -DEVICE_DT_INST_DEFINE(0, ssd1306_init, NULL, - &ssd1306_driver, &ssd1306_config, - POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, - &ssd1306_driver_api); +#define SSD1306_CONFIG_SPI(node_id) \ + .bus = {.spi = SPI_DT_SPEC_GET( \ + node_id, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0)}, \ + .bus_ready = ssd1306_bus_ready_spi, \ + .write_bus = ssd1306_write_bus_spi, \ + .bus_name = ssd1306_bus_name_spi, \ + .data_cmd = GPIO_DT_SPEC_GET(node_id, data_cmd_gpios), + +#define SSD1306_CONFIG_I2C(node_id) \ + .bus = {.i2c = I2C_DT_SPEC_GET(node_id)}, \ + .bus_ready = ssd1306_bus_ready_i2c, \ + .write_bus = ssd1306_write_bus_i2c, \ + .bus_name = ssd1306_bus_name_i2c, \ + .data_cmd = {0}, + +#define SSD1306_DEFINE(node_id) \ + static struct ssd1306_data data##node_id; \ + static const struct ssd1306_config config##node_id = { \ + .reset = GPIO_DT_SPEC_GET_OR(node_id, reset_gpios, {0}), \ + .height = DT_PROP(node_id, height), \ + .width = DT_PROP(node_id, width), \ + .segment_offset = DT_PROP(node_id, segment_offset), \ + .page_offset = DT_PROP(node_id, page_offset), \ + .display_offset = DT_PROP(node_id, display_offset), \ + .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ + .segment_remap = DT_PROP(node_id, segment_remap), \ + .com_invdir = DT_PROP(node_id, com_invdir), \ + .com_sequential = DT_PROP(node_id, com_sequential), \ + .prechargep = DT_PROP(node_id, prechargep), \ + .color_inversion = DT_PROP(node_id, inversion_on), \ + .sh1106_compatible = DT_NODE_HAS_COMPAT(node_id, sinowealth_sh1106), \ + .ready_time_ms = DT_PROP(node_id, ready_time_ms), \ + COND_CODE_1(DT_ON_BUS(node_id, spi), (SSD1306_CONFIG_SPI(node_id)), \ + (SSD1306_CONFIG_I2C(node_id))) \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, ssd1306_init, NULL, &data##node_id, &config##node_id, \ + POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1306_driver_api); + +DT_FOREACH_STATUS_OKAY(solomon_ssd1306fb, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(sinowealth_sh1106, SSD1306_DEFINE) From 64708f02001db3936344abd0bec57e1675df4f2e Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 8 Sep 2023 12:07:00 +0200 Subject: [PATCH 0371/4498] devicetree: fix DT_FOREACH_PROP_ELEM_SEP doxygen example Remove a duplicate line from the code sample. Signed-off-by: Pieter De Gendt --- include/zephyr/devicetree.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 9154d346739..00cef4fb8aa 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -2797,7 +2797,6 @@ * * @code{.c} * struct gpio_dt_spec specs[] = { - * struct gpio_dt_spec specs[] = { * GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 0), * GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 1) * }; From 2fd989f16d6414e24b1a1cdcae4be23915631ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 15:47:11 +0200 Subject: [PATCH 0372/4498] ci: bump zephyrproject-rtos/action-first-interaction v1.1.1-zephyr-4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A recent fix in zephyrproject-rtos/action-first-interaction/pull/5 is now making the bot's comments on PR be actual comments, not PR "review comments". Signed-off-by: Benjamin Cabé --- .github/workflows/greet_first_time_contributor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/greet_first_time_contributor.yml b/.github/workflows/greet_first_time_contributor.yml index 8ed7157975a..c4f9b5764e6 100644 --- a/.github/workflows/greet_first_time_contributor.yml +++ b/.github/workflows/greet_first_time_contributor.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: zephyrproject-rtos/action-first-interaction@v1.1.1-zephyr-3 + - uses: zephyrproject-rtos/action-first-interaction@v1.1.1-zephyr-4 with: repo-token: ${{ secrets.GITHUB_TOKEN }} From 8ac4b248c1fa16e8a02b5d1f30de5c5f7c2f0958 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 15 Aug 2023 12:59:29 +0300 Subject: [PATCH 0373/4498] doc: west: Remove empty Footnotes rubric Remove empty rubric. Cross-linking markups are not included in Footnotes. Signed-off-by: Andrei Emeltchenko --- doc/develop/west/build-flash-debug.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/develop/west/build-flash-debug.rst b/doc/develop/west/build-flash-debug.rst index b6809094f85..abe26614aea 100644 --- a/doc/develop/west/build-flash-debug.rst +++ b/doc/develop/west/build-flash-debug.rst @@ -739,8 +739,6 @@ debugging. This can of course also be accomplished using the usual targets provided by Zephyr's build system (in fact, that's how these commands do it). -.. rubric:: Footnotes - .. _cmake(1): https://cmake.org/cmake/help/latest/manual/cmake.1.html From ed61709405650b221b938fc21c5a9332ee3de6e1 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 16 Aug 2023 11:08:44 +0300 Subject: [PATCH 0374/4498] samples: edac: Correct README Correct build and run instructions. Signed-off-by: Andrei Emeltchenko --- samples/subsys/edac/README.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/samples/subsys/edac/README.rst b/samples/subsys/edac/README.rst index c47f93ef804..13647e970a5 100644 --- a/samples/subsys/edac/README.rst +++ b/samples/subsys/edac/README.rst @@ -11,16 +11,21 @@ This sample demonstrates the EDAC driver API in a simple EDAC shell sample. Building and Running ******************** -This project can be built and executed on as following example for the -:ref:`intel_ehl_crb` board: +This sample can be found under :zephyr_file:`samples/subsys/edac` in the +Zephyr tree. +The sample can be built as follows for the :ref:`intel_ehl_crb` board: .. zephyr-app-commands:: :zephyr-app: samples/subsys/edac :host-os: unix :board: intel_ehl_crb - :goals: run + :goals: build :compact: +The Zephyr image that's created can be run on the :ref:`intel_ehl_crb` board +as per the instructions in the board documentation. Check out the +:ref:`intel_ehl_crb` for details. + Sample output ************* From 05afc13f5f74930b567eb73e01245028196b8fcf Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 16 Aug 2023 14:08:58 +0300 Subject: [PATCH 0375/4498] samples: smbus: Update documentation Update README.rst for smbus sample. Signed-off-by: Andrei Emeltchenko --- samples/drivers/smbus/README.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/drivers/smbus/README.rst b/samples/drivers/smbus/README.rst index e1f8fec8db9..9a35ca1bc30 100644 --- a/samples/drivers/smbus/README.rst +++ b/samples/drivers/smbus/README.rst @@ -12,7 +12,9 @@ driver supported exploring the SMBus communication with peripheral devices. Building and Running ******************** -This project can be built and executed on as follows: +This sample can be found under :zephyr_file:`samples/drivers/smbus` in the +Zephyr tree. +The sample can be built and run as follows for the ``qemu_x86_64`` board: .. zephyr-app-commands:: :zephyr-app: zephyr/samples/drivers/smbus @@ -22,7 +24,7 @@ This project can be built and executed on as follows: :compact: Sample Output -============= +************* Output from console when application started:: From 1a983150442aa6db854989fc48afd4b948b675f4 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 1 Sep 2023 13:07:28 +0300 Subject: [PATCH 0376/4498] docs: qemu_x86: Update UEFI boot documentation Update UEFI boot documentation since after commit 75cb6e6498 UEFI boot sample was moved from hello_world app to special uefi boot test. Signed-off-by: Andrei Emeltchenko --- boards/x86/qemu_x86/doc/index.rst | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/boards/x86/qemu_x86/doc/index.rst b/boards/x86/qemu_x86/doc/index.rst index 8589d73360f..2fdba13bc09 100644 --- a/boards/x86/qemu_x86/doc/index.rst +++ b/boards/x86/qemu_x86/doc/index.rst @@ -111,23 +111,36 @@ to run Zephyr applications and kernel tests, but you need to set up some environment configurations as follows: * Please install uefi-run in your system environment according to this - reference link https://github.com/Richard-W/uefi-run. + reference link https://github.com/Richard-W/uefi-run. Note that uefi-run + from snapstore may not work because of strict snap confinements. + The preferred method is installing with cargo. * Please install OVMF in your system environment according to this reference link https://github.com/tianocore/tianocore.github.io/wiki/OVMF. + The easiest way is to install a special ``ovmf`` package found in many distros. + For example, use the following command in Ubuntu: + + .. code-block:: console + + sudo apt install ovmf * Set system environment variable OVMF_FD_PATH, - for example: export OVMF_FD_PATH=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd + for example: -For example, with the test "sample.basic.helloworld.uefi": + .. code-block:: console -.. code-block:: console + export OVMF_FD_PATH=/usr/share/OVMF/OVMF_CODE.fd + +Now you can build application, for example UEFI boot test sample found under +:zephyr_file:`tests/boot/uefi`: - export OVMF_FD_PATH=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd - west build -b qemu_x86_64 -p auto samples/hello_world/ -DCONF_FILE=prj_uefi.conf - west build -t run +.. zephyr-app-commands:: + :zephyr-app: tests/boot/uefi + :host-os: unix + :board: qemu_x86_64 + :goals: run -This will build an image with the hello_world sample app, boot it on +This will build an image with the uefi boot test app, boot it on qemu_x86_64 using UEFI, and display the following console output: .. code-block:: console From c16218e3eb01aaaceb1121bc06f8be59062eacd6 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 8 Sep 2023 16:57:52 +0300 Subject: [PATCH 0377/4498] tests: ibecc: Update IBECC test README Use :menuselection: for BIOS menu selection rendering. Signed-off-by: Andrei Emeltchenko --- tests/subsys/edac/ibecc/README.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/subsys/edac/ibecc/README.rst b/tests/subsys/edac/ibecc/README.rst index 52f4e16cf78..b6f4ff11ead 100644 --- a/tests/subsys/edac/ibecc/README.rst +++ b/tests/subsys/edac/ibecc/README.rst @@ -3,8 +3,7 @@ Testing Error Detection and Correction ###################################### -Tests verify API and use error injection method to inject -errors. +Tests verify API and use error injection method to inject errors. Prerequisites ************* @@ -12,11 +11,11 @@ Prerequisites IBECC should be enabled in BIOS. This is usually enabled in the default BIOS configuration. Verify following is enabled:: - Intel Advanced Menu -> Memory Configuration -> In-Band ECC -> +:menuselection:`Intel Advanced Menu --> Memory Configuration --> In-Band ECC --> Enabled` Verify also operational mode with:: - Intel Advanced Menu -> Memory Configuration -> In-Band ECC Operation Mode -> 2 +:menuselection:`Intel Advanced Menu --> Memory Configuration --> In-Band ECC Operation Mode --> 2` For injection test Error Injection should be enabled. @@ -31,7 +30,7 @@ In order to use Error Injection user need to use BIOS Boot Guard 0 profile. Additionally Error Injection need to be enabled in the following BIOS menu:: - Intel Advanced Menu -> Memory Configuration -> In-Band ECC Error -> +:menuselection:`Intel Advanced Menu --> Memory Configuration --> In-Band ECC Error --> Enabled` .. note:: @@ -43,7 +42,7 @@ Additionally Error Injection need to be enabled in the following BIOS menu:: Building and Running ******************** -This project can be built as follows: +This project can be built as follows for the :ref:`intel_ehl_crb` board: .. zephyr-app-commands:: :zephyr-app: tests/subsys/edac/ibecc From c709b3d97f3b07fd92f7db41cb8bfd9892f41c5e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Sep 2023 15:18:59 +0300 Subject: [PATCH 0378/4498] samples: Using zephyr:code-samples for smbus and edac Using zephyr:code-sample:: for SMBus and EDAC samples docs. Signed-off-by: Andrei Emeltchenko --- samples/drivers/smbus/README.rst | 7 ++++--- samples/subsys/edac/README.rst | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/samples/drivers/smbus/README.rst b/samples/drivers/smbus/README.rst index 9a35ca1bc30..31a753c8542 100644 --- a/samples/drivers/smbus/README.rst +++ b/samples/drivers/smbus/README.rst @@ -1,7 +1,8 @@ -.. _samples_smbus_shell: +.. zephyr:code-sample:: smbus-shell + :name: SMBus shell + :relevant-api: smbus_interface -SMBus Shell Sample -################## + SMBus Shell Sample Overview ******** diff --git a/samples/subsys/edac/README.rst b/samples/subsys/edac/README.rst index 13647e970a5..bcac44df86f 100644 --- a/samples/subsys/edac/README.rst +++ b/samples/subsys/edac/README.rst @@ -1,7 +1,8 @@ -.. _samples_edac: +.. zephyr:code-sample:: edac-sample + :name: EDAC shell + :relevant-api: edac -EDAC Shell Sample -################# + EDAC Shell Sample Overview ******** From 4c04f4488a7908abd2dfe9ba723a4e7b8b8bfda7 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 13 Sep 2023 13:06:56 -0500 Subject: [PATCH 0379/4498] dts: regulator: Fix reoccurring typo in properties Corrects 'propably' to 'probably' in the regulator devicetree bindings. Signed-off-by: Ricardo Rivera-Matos --- dts/bindings/regulator/regulator.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dts/bindings/regulator/regulator.yaml b/dts/bindings/regulator/regulator.yaml index 16a21511ef9..067133aa97e 100644 --- a/dts/bindings/regulator/regulator.yaml +++ b/dts/bindings/regulator/regulator.yaml @@ -147,7 +147,7 @@ properties: type: int description: | Set over current error limit. This is a limit where part of the hardware - propably is malfunctional and damage prevention is requested. Zero can be + probably is malfunctional and damage prevention is requested. Zero can be passed to disable error detection and value '1' indicates that detection should be enabled but limit setting can be omitted. @@ -172,7 +172,7 @@ properties: type: int description: | Set over voltage error limit. This is a limit where part of the hardware - propably is malfunctional and damage prevention is requested Zero can be + probably is malfunctional and damage prevention is requested Zero can be passed to disable error detection and value '1' indicates that detection should be enabled but limit setting can be omitted. Limit is given as microvolt offset from voltage set to regulator. @@ -200,7 +200,7 @@ properties: type: int description: | Set under voltage error limit. This is a limit where part of the hardware - propably is malfunctional and damage prevention is requested Zero can be + probably is malfunctional and damage prevention is requested Zero can be passed to disable error detection and value '1' indicates that detection should be enabled but limit setting can be omitted. Limit is given as microvolt offset from voltage set to regulator. @@ -227,7 +227,7 @@ properties: type: int description: | Set over temperature error limit. This is a limit where part of the - hardware propably is malfunctional and damage prevention is requested Zero + hardware probably is malfunctional and damage prevention is requested Zero can be passed to disable error detection and value '1' indicates that detection should be enabled but limit setting can be omitted. From 23d051537b8d47214fb2e2e5a12bb033c2f31e78 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Tue, 12 Sep 2023 23:51:52 -0600 Subject: [PATCH 0380/4498] rtio: Simplify the mempool handling It's not necessary to cache the block size, instead it can be computed from blk_sz_shift Signed-off-by: Yuval Peress --- include/zephyr/rtio/rtio.h | 99 +++++++++++-------- .../build_all/sensor/src/generic_test.c | 4 +- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index f608d213c37..28481504962 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -211,7 +211,6 @@ struct rtio_cqe; struct rtio_sqe; struct rtio_sqe_pool; struct rtio_cqe_pool; -struct rtio_block_pool; struct rtio_iodev; struct rtio_iodev_sqe; /** @endcond */ @@ -310,13 +309,6 @@ struct rtio_cqe_pool { struct rtio_cqe *pool; }; -struct rtio_block_pool { - /* Memory pool associated with this RTIO context. */ - struct sys_mem_blocks *mempool; - /* The size (in bytes) of a single block in the mempool */ - const uint32_t blk_size; -}; - /** * @brief An RTIO context containing what can be viewed as a pair of queues. * @@ -362,7 +354,7 @@ struct rtio { #ifdef CONFIG_RTIO_SYS_MEM_BLOCKS /* Mem block pool */ - struct rtio_block_pool *block_pool; + struct sys_mem_blocks *block_pool; #endif /* Submission queue */ @@ -375,6 +367,26 @@ struct rtio { /** The memory partition associated with all RTIO context information */ extern struct k_mem_partition rtio_partition; +/** + * @brief Get the mempool block size of the RTIO context + * + * @param[in] r The RTIO context + * @return The size of each block in the context's mempool + * @return 0 if the context doesn't have a mempool + */ +static inline size_t rtio_mempool_block_size(const struct rtio *r) +{ +#ifndef CONFIG_RTIO_SYS_MEM_BLOCKS + ARG_UNUSED(r); + return 0; +#else + if (r == NULL || r->block_pool == NULL) { + return 0; + } + return BIT(r->block_pool->blk_sz_shift); +#endif +} + /** * @brief Compute the mempool block index for a given pointer * @@ -386,8 +398,8 @@ extern struct k_mem_partition rtio_partition; static inline uint16_t __rtio_compute_mempool_block_index(const struct rtio *r, const void *ptr) { uintptr_t addr = (uintptr_t)ptr; - struct sys_mem_blocks *mem_pool = r->block_pool->mempool; - uint32_t block_size = r->block_pool->blk_size; + struct sys_mem_blocks *mem_pool = r->block_pool; + uint32_t block_size = rtio_mempool_block_size(r); uintptr_t buff = (uintptr_t)mem_pool->buffer; uint32_t buff_size = mem_pool->num_blocks * block_size; @@ -648,31 +660,43 @@ static inline void rtio_cqe_pool_free(struct rtio_cqe_pool *pool, struct rtio_cq pool->pool_free++; } -static inline int rtio_block_pool_alloc(struct rtio_block_pool *pool, size_t min_sz, +static inline int rtio_block_pool_alloc(struct rtio *r, size_t min_sz, size_t max_sz, uint8_t **buf, uint32_t *buf_len) { +#ifndef CONFIG_RTIO_SYS_MEM_BLOCKS + ARG_UNUSED(r); + ARG_UNUSED(min_sz); + ARG_UNUSED(max_sz); + ARG_UNUSED(buf); + ARG_UNUSED(buf_len); + return -ENOTSUP; +#else + const uint32_t block_size = rtio_mempool_block_size(r); uint32_t bytes = max_sz; do { - size_t num_blks = DIV_ROUND_UP(bytes, pool->blk_size); - int rc = sys_mem_blocks_alloc_contiguous(pool->mempool, num_blks, (void **)buf); + size_t num_blks = DIV_ROUND_UP(bytes, block_size); + int rc = sys_mem_blocks_alloc_contiguous(r->block_pool, num_blks, (void **)buf); if (rc == 0) { - *buf_len = num_blks * pool->blk_size; + *buf_len = num_blks * block_size; return 0; } - bytes -= pool->blk_size; + bytes -= block_size; } while (bytes >= min_sz); return -ENOMEM; +#endif } -static inline void rtio_block_pool_free(struct rtio_block_pool *pool, void *buf, uint32_t buf_len) +static inline void rtio_block_pool_free(struct rtio *r, void *buf, uint32_t buf_len) { - size_t num_blks = buf_len / pool->blk_size; +#ifdef CONFIG_RTIO_SYS_MEM_BLOCKS + size_t num_blks = buf_len >> r->block_pool->blk_sz_shift; - sys_mem_blocks_free_contiguous(pool->mempool, buf, num_blks); + sys_mem_blocks_free_contiguous(r->block_pool, buf, num_blks); +#endif } /* Do not try and reformat the macros */ @@ -733,16 +757,11 @@ static inline void rtio_block_pool_free(struct rtio_block_pool *pool, void *buf, */ #define RTIO_DMEM COND_CODE_1(CONFIG_USERSPACE, (K_APP_DMEM(rtio_partition) static), (static)) -#define Z_RTIO_BLOCK_POOL_DEFINE(name, blk_sz, blk_cnt, blk_align) \ - RTIO_BMEM uint8_t __aligned(WB_UP(blk_align)) \ - _block_pool_##name[blk_cnt*WB_UP(blk_sz)]; \ - _SYS_MEM_BLOCKS_DEFINE_WITH_EXT_BUF(_sys_blocks_##name, WB_UP(blk_sz), \ - blk_cnt, _block_pool_##name, \ - RTIO_DMEM); \ - static struct rtio_block_pool name = { \ - .mempool = &_sys_blocks_##name, \ - .blk_size = blk_sz, \ - } +#define Z_RTIO_BLOCK_POOL_DEFINE(name, blk_sz, blk_cnt, blk_align) \ + RTIO_BMEM uint8_t __aligned(WB_UP(blk_align)) \ + _block_pool_##name[blk_cnt*WB_UP(blk_sz)]; \ + _SYS_MEM_BLOCKS_DEFINE_WITH_EXT_BUF(name, WB_UP(blk_sz), blk_cnt, _block_pool_##name, \ + RTIO_DMEM) #define Z_RTIO_DEFINE(name, _sqe_pool, _cqe_pool, _block_pool) \ IF_ENABLED(CONFIG_RTIO_SUBMIT_SEM, \ @@ -999,10 +1018,9 @@ static inline uint32_t rtio_cqe_compute_flags(struct rtio_iodev_sqe *iodev_sqe) #ifdef CONFIG_RTIO_SYS_MEM_BLOCKS if (iodev_sqe->sqe.op == RTIO_OP_RX && iodev_sqe->sqe.flags & RTIO_SQE_MEMPOOL_BUFFER) { struct rtio *r = iodev_sqe->r; - struct sys_mem_blocks *mem_pool = r->block_pool->mempool; - uint32_t block_size = r->block_pool->blk_size; - int blk_index = (iodev_sqe->sqe.buf - mem_pool->buffer) / block_size; - int blk_count = iodev_sqe->sqe.buf_len / block_size; + struct sys_mem_blocks *mem_pool = r->block_pool; + int blk_index = (iodev_sqe->sqe.buf - mem_pool->buffer) >> mem_pool->blk_sz_shift; + int blk_count = iodev_sqe->sqe.buf_len >> mem_pool->blk_sz_shift; flags = RTIO_CQE_FLAG_PREP_MEMPOOL(blk_index, blk_count); } @@ -1038,13 +1056,13 @@ static inline int z_impl_rtio_cqe_get_mempool_buffer(const struct rtio *r, struc if (RTIO_CQE_FLAG_GET(cqe->flags) == RTIO_CQE_FLAG_MEMPOOL_BUFFER) { int blk_idx = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_IDX(cqe->flags); int blk_count = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_CNT(cqe->flags); + uint32_t blk_size = rtio_mempool_block_size(r); - *buff = r->block_pool->mempool->buffer + blk_idx * r->block_pool->blk_size; - *buff_len = blk_count * r->block_pool->blk_size; - __ASSERT_NO_MSG(*buff >= r->block_pool->mempool->buffer); + *buff = r->block_pool->buffer + blk_idx * blk_size; + *buff_len = blk_count * blk_size; + __ASSERT_NO_MSG(*buff >= r->block_pool->buffer); __ASSERT_NO_MSG(*buff < - r->block_pool->mempool->buffer + - r->block_pool->blk_size * r->block_pool->mempool->num_blocks); + r->block_pool->buffer + blk_size * r->block_pool->num_blocks); return 0; } return -EINVAL; @@ -1176,8 +1194,7 @@ static inline int rtio_sqe_rx_buf(const struct rtio_iodev_sqe *iodev_sqe, uint32 return 0; } - int rc = rtio_block_pool_alloc(r->block_pool, min_buf_len, max_buf_len, - buf, buf_len); + int rc = rtio_block_pool_alloc(r, min_buf_len, max_buf_len, buf, buf_len); if (rc == 0) { sqe->buf = *buf; sqe->buf_len = *buf_len; @@ -1222,7 +1239,7 @@ static inline void z_impl_rtio_release_buffer(struct rtio *r, void *buff, uint32 return; } - rtio_block_pool_free(r->block_pool, buff, buff_len); + rtio_block_pool_free(r, buff, buff_len); #else ARG_UNUSED(r); ARG_UNUSED(buff); diff --git a/tests/drivers/build_all/sensor/src/generic_test.c b/tests/drivers/build_all/sensor/src/generic_test.c index 0df8b953da9..53c79820c90 100644 --- a/tests/drivers/build_all/sensor/src/generic_test.c +++ b/tests/drivers/build_all/sensor/src/generic_test.c @@ -45,8 +45,8 @@ static void before(void *args) iodev_read_config.sensor = NULL; /* Wipe the mempool by marking every block free */ - zassert_ok(sys_bitarray_clear_region(sensor_read_rtio_ctx_block_pool.mempool->bitmap, - sensor_read_rtio_ctx_block_pool.mempool->num_blocks, + zassert_ok(sys_bitarray_clear_region(sensor_read_rtio_ctx.block_pool->bitmap, + sensor_read_rtio_ctx.block_pool->num_blocks, 0)); /* Flush the SQ and CQ */ From 718a219bf14bd8061cd88f260f6bbd1ce8f72d7c Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 25 Jul 2023 09:23:41 -0700 Subject: [PATCH 0381/4498] cmake: expose TOOLCHAIN_HAS_PICOLIBC to kconfig This mirrors TOOLCHAIN_HAS_NEWLIB to picolibc so the cmake variable TOOLCHAIN_HAS_PICOLIBC can be used in kconfig. Signed-off-by: Daniel Leung --- cmake/modules/kconfig.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 7c4a059b570..632e9a72422 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -122,6 +122,12 @@ else() set(_local_TOOLCHAIN_HAS_NEWLIB n) endif() +if(TOOLCHAIN_HAS_PICOLIBC) + set(_local_TOOLCHAIN_HAS_PICOLIBC y) +else() + set(_local_TOOLCHAIN_HAS_PICOLIBC n) +endif() + set(COMMON_KCONFIG_ENV_SETTINGS PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} srctree=${ZEPHYR_BASE} @@ -140,6 +146,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT} TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} TOOLCHAIN_HAS_NEWLIB=${_local_TOOLCHAIN_HAS_NEWLIB} + TOOLCHAIN_HAS_PICOLIBC=${_local_TOOLCHAIN_HAS_PICOLIBC} EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} From 01dd2f0897f34edf728d3f7e7cb2f9a06e5af997 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 25 Jul 2023 09:27:58 -0700 Subject: [PATCH 0382/4498] libc: picolibc: extend support beyond Zephyr SDK The picolibc kconfigs were tied to ZEPHYR_TOOLCHAIN_VARIANT and it only supported the Zephyr SDK, which is the only toolchain having picolibc built-in at the moment. This commit generalizes that to use TOOLCHAIN_HAS_PICOLIBC cmake variable the same way as newlib: TOOLCHAIN_HAS_NEWLIB. This provides the ability for other toolchains to declare their support for picolibc. Signed-off-by: Daniel Leung --- lib/libc/Kconfig | 4 ++-- lib/libc/picolibc/Kconfig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 522bd4a57b3..7febf1574d4 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -35,8 +35,8 @@ config NEWLIB_LIBC_SUPPORTED config PICOLIBC_SUPPORTED bool depends on !NATIVE_APPLICATION - depends on ("$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr") || (NATIVE_LIBRARY) - depends on !(CPP && "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr") + depends on ("$(TOOLCHAIN_HAS_PICOLIBC)" = "y") || (NATIVE_LIBRARY) + depends on !(CPP && ("$(TOOLCHAIN_HAS_PICOLIBC)" = "y")) default y select FULL_LIBC_SUPPORTED help diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig index 659cbf41db6..8f7dc9e21bf 100644 --- a/lib/libc/picolibc/Kconfig +++ b/lib/libc/picolibc/Kconfig @@ -5,7 +5,7 @@ if PICOLIBC config PICOLIBC_USE_MODULE bool "Picolibc as module" - default y if "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "zephyr" + default y if "$(TOOLCHAIN_HAS_PICOLIBC)" != "y" depends on ZEPHYR_PICOLIBC_MODULE depends on !GLIBCXX_LIBCPP help From b21d35d3577ccc8b6df49a13b7aeaaf95da123cb Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 21 Jul 2023 14:03:38 -0700 Subject: [PATCH 0383/4498] libc: picolibc: disable prompt for PICOLIBC_USE_MODULE... ...when toolchain does not have native picolibc support. Without native support, picolibc needs to be built from the module. Disabling the prompt means this kconfig takes on whatever default value specified, which is to build source from module when there is no native support. Signed-off-by: Daniel Leung --- lib/libc/picolibc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig index 8f7dc9e21bf..b5e1f1bb581 100644 --- a/lib/libc/picolibc/Kconfig +++ b/lib/libc/picolibc/Kconfig @@ -4,7 +4,7 @@ if PICOLIBC config PICOLIBC_USE_MODULE - bool "Picolibc as module" + bool "Picolibc as module" if "$(TOOLCHAIN_HAS_PICOLIBC)" = "y" default y if "$(TOOLCHAIN_HAS_PICOLIBC)" != "y" depends on ZEPHYR_PICOLIBC_MODULE depends on !GLIBCXX_LIBCPP From 26ffa9f59a3936cab6a04964ea178b9499b6859a Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 21 Aug 2023 17:38:00 -0700 Subject: [PATCH 0384/4498] doc: picolibc: a few words about building without native support This adds a few words about using Picolibc without native support from toolchain, and how to enable this behavior for toolchain. Signed-off-by: Daniel Leung --- doc/develop/languages/c/picolibc.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/develop/languages/c/picolibc.rst b/doc/develop/languages/c/picolibc.rst index 32ab8732c7a..33d2e8f3fd6 100644 --- a/doc/develop/languages/c/picolibc.rst +++ b/doc/develop/languages/c/picolibc.rst @@ -62,6 +62,28 @@ For every release of Zephyr, the toolchain-bundled Picolibc and the sync when using the :ref:`recommended version of Zephyr SDK `. +Building Without Toolchain bundled Picolibc +------------------------------------------- + +For toolchain where there is no bundled Picolibc, it is still +possible to use Picolibc by building it from source. Note that +any restrictions mentioned in :ref:`c_library_picolibc_module` +still apply. + +To build without toolchain bundled Picolibc, the toolchain must +enable :kconfig:option:`CONFIG_PICOLIBC_SUPPORTED`. For example, +this needs to be added to the toolchain Kconfig file: + +.. code-block:: none + + config TOOLCHAIN__PICOLIBC_SUPPORTED + def_bool y + select PICOLIBC_SUPPORTED + +By enabling :kconfig:option:`CONFIG_PICOLIBC_SUPPORTED`, the build +system would automatically build Picolibc from source with its module +when there is no toolchain bundled Picolibc. + Formatted Output **************** From db52d27eb56806e4bab316f60b87f61a39d8e064 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Tue, 22 Aug 2023 22:34:27 +0200 Subject: [PATCH 0385/4498] scripts: Update CFB font generator Update CFB font generator so it works with Pillow version 10. They deprecated some methods, with no direct replacements, so the generated fonts might be slightly different. Signed-off-by: Jonathan Rico --- scripts/build/gen_cfb_font_header.py | 15 +++++++++++++-- scripts/requirements-extras.txt | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/build/gen_cfb_font_header.py b/scripts/build/gen_cfb_font_header.py index dacb76c4eef..0bba785bfe7 100755 --- a/scripts/build/gen_cfb_font_header.py +++ b/scripts/build/gen_cfb_font_header.py @@ -76,7 +76,13 @@ def extract_font_glyphs(): fw_max = 0 fh_max = 0 for i in range(args.first, args.last + 1): - fw, fh = font.getsize(chr(i)) + # returns (left, top, right, bottom) bounding box + size = font.getbbox(chr(i)) + + # calculate width + height + fw = size[2] - size[0] # right - left + fh = size[3] - size[1] # bottom - top + if fw > fw_max: fw_max = fw if fh > fh_max: @@ -100,7 +106,12 @@ def extract_font_glyphs(): image = Image.new('1', (width, height), 'white') draw = ImageDraw.Draw(image) - fw, fh = draw.textsize(chr(i), font=font) + # returns (left, top, right, bottom) bounding box + size = draw.textbbox((0, 0), chr(i), font=font) + + # calculate width + height + fw = size[2] - size[0] # right - left + fh = size[3] - size[1] # bottom - top xpos = 0 if args.center_x: diff --git a/scripts/requirements-extras.txt b/scripts/requirements-extras.txt index 969254e7835..f210f069de9 100644 --- a/scripts/requirements-extras.txt +++ b/scripts/requirements-extras.txt @@ -16,7 +16,7 @@ clang-format>=15.0.0 lpc_checksum # used by scripts/build/gen_cfb_font_header.py - helper script for user -Pillow +Pillow>=10.0 # can be used to sign a Zephyr application binary for consumption by a bootloader imgtool>=1.9 From 422cfeeb1a581a7c0b9687d6a75a912c91e85eae Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 12 Sep 2023 10:22:59 +0200 Subject: [PATCH 0386/4498] doc: Bluetooth: Mesh: Align wording for models instantiation req According to https://github.com/zephyrproject-rtos/zephyr/pull/61886#issuecomment-1713302331 we need to use "must only" for models that spec states: `If supported, ... shall be supported by the primary element and shall not be supported by any secondary element`. Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/cfg_cli.rst | 4 ++-- doc/connectivity/bluetooth/api/mesh/cfg_srv.rst | 2 +- doc/connectivity/bluetooth/api/mesh/health_cli.rst | 6 +++--- doc/connectivity/bluetooth/api/mesh/health_srv.rst | 2 ++ doc/connectivity/bluetooth/api/mesh/od_cli.rst | 3 +++ doc/connectivity/bluetooth/api/mesh/od_srv.rst | 2 +- doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst | 8 ++++---- doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst | 3 +-- doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst | 3 +-- doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst | 3 +-- doc/connectivity/bluetooth/api/mesh/rpr_srv.rst | 3 +-- doc/connectivity/bluetooth/api/mesh/srpl_cli.rst | 4 ++-- doc/connectivity/bluetooth/api/mesh/srpl_srv.rst | 4 ++-- 13 files changed, 24 insertions(+), 23 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst index 1e985970690..bf84edc6b86 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst @@ -17,8 +17,8 @@ All configuration functions in the Configuration Client API have ``net_idx`` and ``addr`` as their first parameters. These should be set to the network index and primary unicast address that the target node was provisioned with. -The Configuration Client model is optional, but should be instantiated on the -first element if it is present in the composition data. +The Configuration Client model is optional, and it must only be instantiated on the +primary element if present in the Composition Data. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst index fe265e243f0..0a26eadfc1a 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst @@ -15,7 +15,7 @@ mesh node. It does not have an API of its own, but relies on a controlled through the :ref:`bluetooth_mesh_heartbeat` API. The Configuration Server model is mandatory on all Bluetooth mesh nodes, and -should be instantiated in the first element. +must only be instantiated on the primary element. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/health_cli.rst b/doc/connectivity/bluetooth/api/mesh/health_cli.rst index da8ba1885bf..44f093dd748 100644 --- a/doc/connectivity/bluetooth/api/mesh/health_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/health_cli.rst @@ -12,9 +12,9 @@ used in this function call. The second parameter is the ``ctx`` or message context. Message context contains netkey index, appkey index and unicast address that the target node uses. -The Health Client model is optional, and may be instantiated in any element. -However, if a Health Client model is instantiated in an element other than the -first, an instance must also be present in the first element. +The Health Client model is optional, and may be instantiated on any element. +However, if a Health Client model is instantiated on an element other than the +primary, an instance must also be present on the primary element. See :ref:`bluetooth_mesh_health_faults` for a list of specification defined fault values. diff --git a/doc/connectivity/bluetooth/api/mesh/health_srv.rst b/doc/connectivity/bluetooth/api/mesh/health_srv.rst index 22803680290..84c543b4766 100644 --- a/doc/connectivity/bluetooth/api/mesh/health_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/health_srv.rst @@ -7,6 +7,8 @@ The Health Server model provides attention callbacks and node diagnostics for :ref:`bluetooth_mesh_models_health_cli` models. It is primarily used to report faults in the mesh node and map the mesh nodes to their physical location. +If present, the Health Server model must be instantiated on the primary element. + Faults ****** diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index bf8ef4fc3f4..85d5f0519d9 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -13,6 +13,9 @@ how long a node will advertise Mesh Proxy Service with Private Network Identity The On-Demand Private Proxy Client model communicates with an On-Demand Private Proxy Server model using the device key of the node containing the target On-Demand Private Proxy Server model instance. +If present, the On-Demand Private Proxy Client model must only be instantiated on the primary +element. + Configurations ************** diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 241ce5f155c..4f20340f9e3 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -17,7 +17,7 @@ The On-Demand Private Proxy Server does not have an API of its own, and relies o :ref:`bluetooth_mesh_od_cli` to control it. The On-Demand Private Proxy Server model only accepts messages encrypted with the node's device key. -If present, the On-Demand Private Proxy Server model must be instantiated on the primary +If present, the On-Demand Private Proxy Server model must only be instantiated on the primary element. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst index 23eb608391f..cb2d1e6ab81 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst @@ -13,11 +13,11 @@ a sequence of access layer messages to nodes supporting the :ref:`bluetooth_mesh The Opcodes Aggregator Client model communicates with an Opcodes Aggregator Server model using the device key of the target node or the application keys configured by the Configuration Client. -The Opcodes Aggregator Client model must only be instantiated on the primary -element, and it is implicitly bound to the device key on initialization. +If present, the Opcodes Aggregator Client model must only be instantiated on the primary element. -The Opcodes Aggregator Client model should be bound to the same application keys that the client models, -used to produce the sequence of messages, are bound to. +The Opcodes Aggregator Client model is implicitly bound to the device key on initialization. It +should be bound to the same application keys as the client models that are used to produce the sequence of +messages. To be able to aggregate a message from a client model, it should support an asynchronous API, for example through callbacks. diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst index 5d493cb4590..1f3c6946c79 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst @@ -13,8 +13,7 @@ a sequence of access layer messages. The Opcodes Aggregator Server model accepts messages encrypted with the node's device key or the application keys. -The Opcodes Aggregator Server model can only be instantiated on the -node's primary element. +If present, the Opcodes Aggregator Server model must only be instantiated on the primary element. The targeted server models should be bound to the same application key that is used to encrypt the sequence of access layer messages sent to the Opcodes Aggregator Server. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst index 6a6f44b1387..7f7d5542a7b 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst @@ -25,8 +25,7 @@ All configuration functions in the Private Beacon Client API have ``net_idx`` and ``addr`` as their first parameters. These should be set to the network index and the primary unicast address the target node was provisioned with. -The Private Beacon Client model is optional, and can be instantiated on any -element. +If present, the Private Beacon Client model must only be instantiated on the primary element. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst index d69fe616e38..cedd7166b09 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst @@ -28,8 +28,7 @@ Server model through the :c:struct:`bt_mesh_priv_beacon_srv` instance passed to changes to this configuration in the settings subsystem, the initial values may be overwritten upon loading. -The Private Beacon Server model is optional, and can only be instantiated in the -node's primary element. +If present, the Private Beacon Server model must only be instantiated on the primary element. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst index f958ef31bd9..0dfb0917541 100644 --- a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst @@ -15,8 +15,7 @@ The Remote Provisioning Server does not have an API of its own, but relies on a :ref:`bluetooth_mesh_models_rpr_cli` to control it. The Remote Provisioning Server model only accepts messages encrypted with the node's device key. -If present, the Remote Provisioning Server model must be instantiated on the primary -element. +If present, the Remote Provisioning Server model must be instantiated on the primary element. Note that after refreshing the device key, node address or Composition Data through a Node Provisioning Protocol Interface (NPPI) procedure, the :c:member:`bt_mesh_prov.reprovisioned` callback is triggered. See section diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst index e940158dd2e..ca437edca79 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst @@ -13,8 +13,8 @@ replay protection list (SRPL) of a node that supports the :ref:`bluetooth_mesh_s The Solicitation PDU RPL Configuration Client model communicates with a Solicitation PDU RPL Configuration Server model using the application keys configured by the Configuration Client. -If present, the Solicitation PDU RPL Configuration Client model must be instantiated on the primary -element. +If present, the Solicitation PDU RPL Configuration Client model must only be instantiated on the +primary element. Configurations ************** diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst index a8c5379e305..9ca68517f99 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst @@ -14,8 +14,8 @@ successfully processed by a node, the SSRC field and SSEQ field of the message a The Solicitation PDU RPL Configuration Server does not have an API of its own, and relies on a :ref:`bluetooth_mesh_srpl_cli` to control it. The model only accepts messages encrypted with an application key as configured by the Configuration Client. -If present, the Solicitation PDU RPL Configuration Server model must be instantiated on the primary -element. +If present, the Solicitation PDU RPL Configuration Server model must only be instantiated on the +primary element. Configurations ************** From a4383c2fd1d8c76dfb82d9556f3614d78bc4d5e3 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Thu, 13 Jul 2023 17:57:03 +1200 Subject: [PATCH 0387/4498] canbus: isotp: add CAN-FD support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISO-TP CAN-FD support can be enabled at runtime. Signed-off-by: Grant Ramsay Signed-off-by: Martin Jäger --- include/zephyr/canbus/isotp.h | 29 +++- subsys/canbus/isotp/Kconfig | 6 +- subsys/canbus/isotp/isotp.c | 241 +++++++++++++++++++-------- subsys/canbus/isotp/isotp_internal.h | 38 +---- 4 files changed, 209 insertions(+), 105 deletions(-) diff --git a/include/zephyr/canbus/isotp.h b/include/zephyr/canbus/isotp.h index b975837915f..aed5306b16a 100644 --- a/include/zephyr/canbus/isotp.h +++ b/include/zephyr/canbus/isotp.h @@ -11,8 +11,8 @@ * ISO-TP is a transport protocol for CAN (Controller Area Network) */ -#ifndef ZEPHYR_INCLUDE_ISOTP_H_ -#define ZEPHYR_INCLUDE_ISOTP_H_ +#ifndef ZEPHYR_INCLUDE_CANBUS_ISOTP_H_ +#define ZEPHYR_INCLUDE_CANBUS_ISOTP_H_ /** * @brief CAN ISO-TP Protocol @@ -34,10 +34,16 @@ * DLC Data length code * FC Flow Control * FF First Frame + * SF Single Frame * FS Flow Status * AE Address Extension + * SN Sequence Number + * ST Separation time * SA Source Address * TA Target Address + * RX_DL CAN RX LL data size + * TX_DL CAN TX LL data size + * PCI Process Control Information */ /* @@ -147,6 +153,12 @@ extern "C" { /** Message uses extended (29-bit) CAN ID */ #define ISOTP_MSG_IDE BIT(2) +/** Message uses CAN-FD format (FDF) */ +#define ISOTP_MSG_FDF BIT(3) + +/** Message uses CAN-FD Baud Rate Switch (BRS). Only valid in combination with ``ISOTP_MSG_FDF``. */ +#define ISOTP_MSG_BRS BIT(4) + /** @} */ /** @@ -167,6 +179,17 @@ struct isotp_msg_id { }; /** ISO-TP extended address (if used) */ uint8_t ext_addr; + /** + * ISO-TP frame data length (TX_DL for TX address or RX_DL for RX address). + * + * Valid values are 8 for classical CAN or 8, 12, 16, 20, 24, 32, 48 and 64 for CAN-FD. + * + * 0 will be interpreted as 8 or 64 (if ISOTP_MSG_FDF is set). + * + * The value for incoming transmissions (RX_DL) is determined automatically based on the + * received first frame and does not need to be set during initialization. + */ + uint8_t dl; /** Flags. @see @ref ISOTP_MSG_FLAGS. */ uint8_t flags; }; @@ -459,4 +482,4 @@ struct isotp_recv_ctx { } #endif -#endif /* ZEPHYR_INCLUDE_ISOTP_H_ */ +#endif /* ZEPHYR_INCLUDE_CANBUS_ISOTP_H_ */ diff --git a/subsys/canbus/isotp/Kconfig b/subsys/canbus/isotp/Kconfig index b533bf6d1e8..1f9ae2d8a34 100644 --- a/subsys/canbus/isotp/Kconfig +++ b/subsys/canbus/isotp/Kconfig @@ -5,6 +5,7 @@ menuconfig ISOTP bool "ISO-TP Transport [EXPERIMENTAL]" + depends on CAN select NET_BUF select POLL select EXPERIMENTAL @@ -74,11 +75,12 @@ config ISOTP_RX_BUF_COUNT config ISOTP_RX_BUF_SIZE int "Size of one buffer data block" + default 63 if CAN_FD_MODE default 56 help This value defines the size of a single block in the pool. The number of blocks is given by ISOTP_RX_BUF_COUNT. To be efficient use a multiple of - CAN_DL - 1 (for classic can : 8 - 1 = 7). + CAN_MAX_DLEN - 1 (for classic CAN : 8 - 1 = 7, for CAN-FD : 64 - 1 = 63). config ISOTP_RX_SF_FF_BUF_COUNT int "Number of SF and FF data buffers for receiving data" @@ -87,7 +89,7 @@ config ISOTP_RX_SF_FF_BUF_COUNT This buffer is used for first and single frames. It is extra because the buffer has to be ready for the first reception in isr context and therefor is allocated when binding. - Each buffer will occupy CAN_DL - 1 byte + header (sizeof(struct net_buf)) + Each buffer will occupy CAN_MAX_DLEN - 1 byte + header (sizeof(struct net_buf)) amount of data. config ISOTP_USE_TX_BUF diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 4a55deb76db..104988bec0a 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Alexander Wachter + * Copyright (c) 2023 Enphase Energy * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +27,7 @@ NET_BUF_POOL_DEFINE(isotp_rx_pool, CONFIG_ISOTP_RX_BUF_COUNT, receive_pool_free); NET_BUF_POOL_DEFINE(isotp_rx_sf_ff_pool, CONFIG_ISOTP_RX_SF_FF_BUF_COUNT, - ISOTP_CAN_DL, sizeof(uint32_t), receive_ff_sf_pool_free); + CAN_MAX_DLEN, sizeof(uint32_t), receive_ff_sf_pool_free); static struct isotp_global_ctx global_ctx = { .alloc_list = SYS_SLIST_STATIC_INIT(&global_ctx.alloc_list), @@ -40,6 +41,24 @@ NET_BUF_POOL_VAR_DEFINE(isotp_tx_pool, CONFIG_ISOTP_TX_BUF_COUNT, static void receive_state_machine(struct isotp_recv_ctx *ctx); +static inline void prepare_frame(struct can_frame *frame, struct isotp_msg_id *addr) +{ + frame->id = addr->ext_id; + frame->flags = ((addr->flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0) | + ((addr->flags & ISOTP_MSG_FDF) != 0 ? CAN_FRAME_FDF : 0) | + ((addr->flags & ISOTP_MSG_BRS) != 0 ? CAN_FRAME_BRS : 0); +} + +static inline void prepare_filter(struct can_filter *filter, struct isotp_msg_id *addr, + uint32_t mask) +{ + filter->id = addr->ext_id; + filter->mask = mask; + filter->flags = CAN_FILTER_DATA | + ((addr->flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0) | + ((addr->flags & ISOTP_MSG_FDF) != 0 ? CAN_FILTER_FDF : 0); +} + /* * Wake every context that is waiting for a buffer */ @@ -103,12 +122,12 @@ static inline uint32_t receive_get_ff_length(struct net_buf *buf) return len; } -static inline uint32_t receive_get_sf_length(struct net_buf *buf) +static inline uint32_t receive_get_sf_length(struct net_buf *buf, bool fdf) { uint8_t len = net_buf_pull_u8(buf) & ISOTP_PCI_SF_DL_MASK; - /* Single frames > 16 bytes (CAN-FD only) */ - if (IS_ENABLED(ISOTP_USE_CAN_FD) && !len) { + /* Single frames > 8 bytes (CAN-FD only) */ + if (IS_ENABLED(CONFIG_CAN_FD_MODE) && fdf && !len) { len = net_buf_pull_u8(buf); } @@ -117,16 +136,15 @@ static inline uint32_t receive_get_sf_length(struct net_buf *buf) static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) { - struct can_frame frame = { - .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, - .id = ctx->tx_addr.ext_id - }; + struct can_frame frame; uint8_t *data = frame.data; uint8_t payload_len; int ret; __ASSERT_NO_MSG(!(fs & ISOTP_PCI_TYPE_MASK)); + prepare_frame(&frame, &ctx->tx_addr); + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { *data++ = ctx->tx_addr.ext_addr; } @@ -138,10 +156,11 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) #ifdef CONFIG_ISOTP_ENABLE_TX_PADDING /* AUTOSAR requirement SWS_CanTp_00347 */ - memset(&frame.data[payload_len], 0xCC, ISOTP_CAN_DL - payload_len); - frame.dlc = ISOTP_CAN_DL; + memset(&frame.data[payload_len], ISOTP_PAD_BYTE, + ISOTP_PADDED_FRAME_DL_MIN - payload_len); + frame.dlc = can_bytes_to_dlc(ISOTP_PADDED_FRAME_DL_MIN); #else - frame.dlc = payload_len; + frame.dlc = can_bytes_to_dlc(payload_len); #endif ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), @@ -212,8 +231,10 @@ static int receive_alloc_buffer(struct isotp_recv_ctx *ctx) /* Alloc all buffers because we can't wait during reception */ buf = receive_alloc_buffer_chain(ctx->length); } else { - buf = receive_alloc_buffer_chain(ctx->opts.bs * - (ISOTP_CAN_DL - 1)); + /* Alloc the minimum of the remaining length and bytes of one block */ + uint32_t len = MIN(ctx->length, ctx->opts.bs * (ctx->rx_addr.dl - 1)); + + buf = receive_alloc_buffer_chain(len); } if (!buf) { @@ -257,7 +278,8 @@ static void receive_state_machine(struct isotp_recv_ctx *ctx) switch (ctx->state) { case ISOTP_RX_STATE_PROCESS_SF: - ctx->length = receive_get_sf_length(ctx->buf); + ctx->length = receive_get_sf_length(ctx->buf, + (ctx->rx_addr.flags & ISOTP_MSG_FDF) != 0); ud_rem_len = net_buf_user_data(ctx->buf); *ud_rem_len = 0; LOG_DBG("SM process SF of length %d", ctx->length); @@ -371,8 +393,10 @@ static void receive_work_handler(struct k_work *item) static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) { int index = 0; + uint8_t sf_len; uint8_t payload_len; uint32_t rx_sa; /* ISO-TP fixed source address (if used) */ + uint8_t can_dl = can_dlc_to_bytes(frame->dlc); if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { if (frame->data[index++] != ctx->rx_addr.ext_addr) { @@ -398,13 +422,14 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) switch (frame->data[index] & ISOTP_PCI_TYPE_MASK) { case ISOTP_PCI_TYPE_FF: LOG_DBG("Got FF IRQ"); - if (frame->dlc != ISOTP_CAN_DL) { + if (can_dl < ISOTP_FF_DL_MIN) { LOG_INF("FF DLC invalid. Ignore"); return; } - payload_len = ISOTP_CAN_DL; + payload_len = can_dl; ctx->state = ISOTP_RX_STATE_PROCESS_FF; + ctx->rx_addr.dl = can_dl; ctx->sn_expected = 1; break; @@ -412,16 +437,27 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) LOG_DBG("Got SF IRQ"); #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING /* AUTOSAR requirement SWS_CanTp_00345 */ - if (frame->dlc != ISOTP_CAN_DL) { + if (can_dl < ISOTP_PADDED_FRAME_DL_MIN) { LOG_INF("SF DLC invalid. Ignore"); return; } #endif + sf_len = frame->data[index] & ISOTP_PCI_SF_DL_MASK; + + /* Single frames > 8 bytes (CAN-FD only) */ + if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->rx_addr.flags & ISOTP_MSG_FDF) != 0 && + can_dl > ISOTP_4BIT_SF_MAX_CAN_DL) { + if (sf_len != 0) { + LOG_INF("SF DL invalid. Ignore"); + return; + } + sf_len = frame->data[index + 1]; + payload_len = index + 2 + sf_len; + } else { + payload_len = index + 1 + sf_len; + } - payload_len = index + 1 + (frame->data[index] & - ISOTP_PCI_SF_DL_MASK); - - if (payload_len > frame->dlc) { + if (payload_len > can_dl) { LOG_INF("SF DL does not fit. Ignore"); return; } @@ -464,6 +500,7 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) uint32_t *ud_rem_len = (uint32_t *)net_buf_user_data(ctx->buf); int index = 0; uint32_t data_len; + uint8_t can_dl = can_dlc_to_bytes(frame->dlc); if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { if (frame->data[index++] != ctx->rx_addr.ext_addr) { @@ -490,16 +527,24 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING /* AUTOSAR requirement SWS_CanTp_00346 */ - if (frame->dlc != ISOTP_CAN_DL) { + if (can_dl < ISOTP_PADDED_FRAME_DL_MIN) { LOG_ERR("CF DL invalid"); receive_report_error(ctx, ISOTP_N_ERROR); return; } #endif + /* First frame defines the RX data length, consecutive frames + * must have the same length (except the last frame) + */ + if (can_dl != ctx->rx_addr.dl && ctx->length > can_dl - index) { + LOG_ERR("CF DL invalid"); + receive_report_error(ctx, ISOTP_N_ERROR); + return; + } + LOG_DBG("Got CF irq. Appending data"); - data_len = (ctx->length > frame->dlc - index) ? frame->dlc - index : - ctx->length; + data_len = MIN(ctx->length, can_dl - index); receive_add_mem(ctx, &frame->data[index], data_len); ctx->length -= data_len; LOG_DBG("%d bytes remaining", ctx->length); @@ -555,6 +600,7 @@ static void receive_can_rx(const struct device *dev, struct can_frame *frame, vo static inline int attach_ff_filter(struct isotp_recv_ctx *ctx) { + struct can_filter filter; uint32_t mask; if ((ctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { @@ -563,12 +609,7 @@ static inline int attach_ff_filter(struct isotp_recv_ctx *ctx) mask = CAN_EXT_ID_MASK; } - struct can_filter filter = { - .flags = CAN_FILTER_DATA | - ((ctx->rx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0), - .id = ctx->rx_addr.ext_id, - .mask = mask - }; + prepare_filter(&filter, &ctx->rx_addr, mask); ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx, &filter); @@ -586,6 +627,7 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, const struct isotp_fc_opts *opts, k_timeout_t timeout) { + can_mode_t cap; int ret; __ASSERT(ctx, "ctx is NULL"); @@ -605,6 +647,14 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, ctx->opts = *opts; ctx->state = ISOTP_RX_STATE_WAIT_FF_SF; + if ((rx_addr->flags & ISOTP_MSG_FDF) != 0 || (tx_addr->flags & ISOTP_MSG_FDF) != 0) { + ret = can_get_capabilities(can_dev, &cap); + if (ret != 0 || (cap & CAN_MODE_FD) == 0) { + LOG_ERR("CAN controller does not support FD mode"); + return ISOTP_N_ERROR; + } + } + LOG_DBG("Binding to addr: 0x%x. Responding on 0x%x", ctx->rx_addr.ext_id, ctx->tx_addr.ext_id); @@ -770,7 +820,7 @@ static void send_process_fc(struct isotp_send_ctx *ctx, #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING /* AUTOSAR requirement SWS_CanTp_00349 */ - if (frame->dlc != ISOTP_CAN_DL) { + if (frame->dlc < ISOTP_PADDED_FRAME_DL_MIN) { LOG_ERR("FC DL invalid. Ignore"); send_report_error(ctx, ISOTP_N_ERROR); return; @@ -854,15 +904,14 @@ static void pull_data_ctx(struct isotp_send_ctx *ctx, size_t len) static inline int send_sf(struct isotp_send_ctx *ctx) { - struct can_frame frame = { - .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, - .id = ctx->tx_addr.ext_id - }; + struct can_frame frame; size_t len = get_ctx_data_length(ctx); int index = 0; int ret; const uint8_t *data; + prepare_frame(&frame, &ctx->tx_addr); + data = get_data_ctx(ctx); pull_data_ctx(ctx, len); @@ -870,22 +919,34 @@ static inline int send_sf(struct isotp_send_ctx *ctx) frame.data[index++] = ctx->tx_addr.ext_addr; } - frame.data[index++] = ISOTP_PCI_TYPE_SF | len; + if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + len > ISOTP_4BIT_SF_MAX_CAN_DL - 1 - index) { + frame.data[index++] = ISOTP_PCI_TYPE_SF; + frame.data[index++] = len; + } else { + frame.data[index++] = ISOTP_PCI_TYPE_SF | len; + } - if (len > ISOTP_CAN_DL - index) { + if (len > ctx->tx_addr.dl - index) { LOG_ERR("SF len does not fit DL"); return -ENOSPC; } memcpy(&frame.data[index], data, len); -#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING - /* AUTOSAR requirement SWS_CanTp_00348 */ - memset(&frame.data[index + len], 0xCC, ISOTP_CAN_DL - len - index); - frame.dlc = ISOTP_CAN_DL; -#else - frame.dlc = len + index; -#endif + if (IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) || + (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + len + index > ISOTP_PADDED_FRAME_DL_MIN)) { + /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. + * Mandatory for ISO-TP CAN-FD frames > 8 bytes. + */ + frame.dlc = can_bytes_to_dlc( + MAX(ISOTP_PADDED_FRAME_DL_MIN, len + index)); + memset(&frame.data[index + len], ISOTP_PAD_BYTE, + can_dlc_to_bytes(frame.dlc) - len - index); + } else { + frame.dlc = can_bytes_to_dlc(len + index); + } ctx->state = ISOTP_TX_SEND_SF; ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), @@ -895,16 +956,16 @@ static inline int send_sf(struct isotp_send_ctx *ctx) static inline int send_ff(struct isotp_send_ctx *ctx) { - struct can_frame frame = { - .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, - .id = ctx->tx_addr.ext_id, - .dlc = ISOTP_CAN_DL - }; + struct can_frame frame; int index = 0; size_t len = get_ctx_data_length(ctx); int ret; const uint8_t *data; + prepare_frame(&frame, &ctx->tx_addr); + + frame.dlc = can_bytes_to_dlc(ctx->tx_addr.dl); + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { frame.data[index++] = ctx->tx_addr.ext_addr; } @@ -926,8 +987,8 @@ static inline int send_ff(struct isotp_send_ctx *ctx) */ ctx->sn = 1; data = get_data_ctx(ctx); - pull_data_ctx(ctx, ISOTP_CAN_DL - index); - memcpy(&frame.data[index], data, ISOTP_CAN_DL - index); + pull_data_ctx(ctx, ctx->tx_addr.dl - index); + memcpy(&frame.data[index], data, ctx->tx_addr.dl - index); ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), send_can_tx_cb, ctx); @@ -936,16 +997,15 @@ static inline int send_ff(struct isotp_send_ctx *ctx) static inline int send_cf(struct isotp_send_ctx *ctx) { - struct can_frame frame = { - .flags = (ctx->tx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0, - .id = ctx->tx_addr.ext_id, - }; + struct can_frame frame; int index = 0; int ret; int len; int rem_len; const uint8_t *data; + prepare_frame(&frame, &ctx->tx_addr); + if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { frame.data[index++] = ctx->tx_addr.ext_addr; } @@ -954,18 +1014,24 @@ static inline int send_cf(struct isotp_send_ctx *ctx) frame.data[index++] = ISOTP_PCI_TYPE_CF | ctx->sn; rem_len = get_ctx_data_length(ctx); - len = MIN(rem_len, ISOTP_CAN_DL - index); + len = MIN(rem_len, ctx->tx_addr.dl - index); rem_len -= len; data = get_data_ctx(ctx); memcpy(&frame.data[index], data, len); -#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING - /* AUTOSAR requirement SWS_CanTp_00348 */ - memset(&frame.data[index + len], 0xCC, ISOTP_CAN_DL - len - index); - frame.dlc = ISOTP_CAN_DL; -#else - frame.dlc = len + index; -#endif + if (IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) || + (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + len + index > ISOTP_PADDED_FRAME_DL_MIN)) { + /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. + * Mandatory for ISO-TP CAN-FD frames > 8 bytes. + */ + frame.dlc = can_bytes_to_dlc( + MAX(ISOTP_PADDED_FRAME_DL_MIN, len + index)); + memset(&frame.data[index + len], ISOTP_PAD_BYTE, + can_dlc_to_bytes(frame.dlc) - len - index); + } else { + frame.dlc = can_bytes_to_dlc(len + index); + } ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), send_can_tx_cb, ctx); @@ -1116,12 +1182,9 @@ static void send_work_handler(struct k_work *item) static inline int attach_fc_filter(struct isotp_send_ctx *ctx) { - struct can_filter filter = { - .flags = CAN_FILTER_DATA | - ((ctx->rx_addr.flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0), - .id = ctx->rx_addr.ext_id, - .mask = CAN_EXT_ID_MASK - }; + struct can_filter filter; + + prepare_filter(&filter, &ctx->rx_addr, CAN_EXT_ID_MASK); ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx, &filter); @@ -1138,6 +1201,7 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, const struct isotp_msg_id *rx_addr, isotp_tx_callback_t complete_cb, void *cb_arg) { + can_mode_t cap; size_t len; int ret; @@ -1145,6 +1209,14 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, __ASSERT_NO_MSG(can_dev); __ASSERT_NO_MSG(rx_addr && tx_addr); + if ((rx_addr->flags & ISOTP_MSG_FDF) != 0 || (tx_addr->flags & ISOTP_MSG_FDF) != 0) { + ret = can_get_capabilities(can_dev, &cap); + if (ret != 0 || (cap & CAN_MODE_FD) == 0) { + LOG_ERR("CAN controller does not support FD mode"); + return ISOTP_N_ERROR; + } + } + if (complete_cb) { ctx->fin_cb.cb = complete_cb; ctx->fin_cb.arg = cb_arg; @@ -1163,10 +1235,39 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, k_work_init(&ctx->work, send_work_handler); k_timer_init(&ctx->timer, send_timeout_handler, NULL); + switch (ctx->tx_addr.dl) { + case 0: + if ((ctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { + ctx->tx_addr.dl = 8; + } else { + ctx->tx_addr.dl = 64; + } + __fallthrough; + case 8: + break; + case 12: + case 16: + case 20: + case 24: + case 32: + case 48: + case 64: + if ((ctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { + LOG_ERR("TX_DL > 8 only supported with FD mode"); + return ISOTP_N_ERROR; + } + break; + default: + LOG_ERR("Invalid TX_DL: %u", ctx->tx_addr.dl); + return ISOTP_N_ERROR; + } + len = get_ctx_data_length(ctx); LOG_DBG("Send %zu bytes to addr 0x%x and listen on 0x%x", len, ctx->tx_addr.ext_id, ctx->rx_addr.ext_id); - if (len > ISOTP_CAN_DL - ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0 ? 2 : 1)) { + /* Single frames > 8 bytes use an additional byte for length (CAN-FD only) */ + if (len > ctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - + ((ctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { ret = attach_fc_filter(ctx); if (ret) { LOG_ERR("Can't attach fc filter: %d", ret); diff --git a/subsys/canbus/isotp/isotp_internal.h b/subsys/canbus/isotp/isotp_internal.h index 24db459a2ec..ac7c28f1ba2 100644 --- a/subsys/canbus/isotp/isotp_internal.h +++ b/subsys/canbus/isotp/isotp_internal.h @@ -4,38 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_SUBSYS_NET_CAN_ISOTP_INTERNAL_H_ -#define ZEPHYR_SUBSYS_NET_CAN_ISOTP_INTERNAL_H_ - +#ifndef ZEPHYR_SUBSYS_CANBUS_ISOTP_ISOTP_INTERNAL_H_ +#define ZEPHYR_SUBSYS_CANBUS_ISOTP_ISOTP_INTERNAL_H_ #include #include -/* - * Abbreviations - * BS Block Size - * CAN_DL CAN LL data size - * CF Consecutive Frame - * CTS Continue to send - * DLC Data length code - * FC Flow Control - * FF First Frame - * SF Single Frame - * FS Flow Status - * AE Adders Extension - * SN Sequence Number - * ST Separation time - * PCI Process Control Information - */ - -/* This is for future use when we have CAN-FD */ -#ifdef ISOTP_USE_CAN_FD -/* #define ISOTP_CAN_DL CONFIG_ISOTP_TX_DL* */ -#define ISOTP_CAN_DL 8 -#else -#define ISOTP_CAN_DL 8 -#endif/*ISOTP_USE_CAN_FD*/ - /* Protocol control information*/ #define ISOTP_PCI_SF 0x00 /* Single frame*/ #define ISOTP_PCI_FF 0x01 /* First frame */ @@ -67,7 +41,9 @@ #define ISOTP_PCI_SN_MASK 0x0F -#define ISOTP_FF_DL_MIN (ISOTP_CAN_DL) +#define ISOTP_FF_DL_MIN 8 +#define ISOTP_PADDED_FRAME_DL_MIN 8 +#define ISOTP_PAD_BYTE 0xCC #define ISOTP_STMIN_MAX 0xFA #define ISOTP_STMIN_MS_MAX 0x7F @@ -76,6 +52,8 @@ #define ISOTP_WFT_FIRST 0xFF +#define ISOTP_4BIT_SF_MAX_CAN_DL 8 + #define ISOTP_BS (CONFIG_ISOTP_BS_TIMEOUT) #define ISOTP_A (CONFIG_ISOTP_A_TIMEOUT) #define ISOTP_CR (CONFIG_ISOTP_CR_TIMEOUT) @@ -121,4 +99,4 @@ struct isotp_global_ctx { } #endif -#endif /* ZEPHYR_SUBSYS_NET_CAN_ISOTP_INTERNAL_H_ */ +#endif /* ZEPHYR_SUBSYS_CANBUS_ISOTP_ISOTP_INTERNAL_H_ */ From 09912b74e9df23e0d4032913e91559bbd436c007 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Thu, 13 Jul 2023 17:57:43 +1200 Subject: [PATCH 0388/4498] samples: canbus: isotp: Add support for CAN-FD Enable this sample to be used with CAN-FD Signed-off-by: Grant Ramsay --- samples/subsys/canbus/isotp/Kconfig | 8 +++++ samples/subsys/canbus/isotp/prj.conf | 6 +--- samples/subsys/canbus/isotp/sample.yaml | 16 ++++++++++ samples/subsys/canbus/isotp/src/main.c | 40 ++++++++++++++----------- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/samples/subsys/canbus/isotp/Kconfig b/samples/subsys/canbus/isotp/Kconfig index ba9b4bc25d6..2ee75804b70 100644 --- a/samples/subsys/canbus/isotp/Kconfig +++ b/samples/subsys/canbus/isotp/Kconfig @@ -22,4 +22,12 @@ config SAMPLE_RX_THREAD_PRIORITY help Priority used for the RX threads. +config SAMPLE_CAN_FD_MODE + bool "Use CAN-FD" + select CAN_FD_MODE + +config ISOTP_RX_BUF_COUNT + default 4 if SAMPLE_CAN_FD_MODE + default 2 + source "Kconfig.zephyr" diff --git a/samples/subsys/canbus/isotp/prj.conf b/samples/subsys/canbus/isotp/prj.conf index 73c988ad91b..04c9fc95d13 100644 --- a/samples/subsys/canbus/isotp/prj.conf +++ b/samples/subsys/canbus/isotp/prj.conf @@ -4,9 +4,5 @@ CONFIG_CAN=y CONFIG_CAN_MAX_FILTER=8 CONFIG_ISOTP=y -CONFIG_ISOTP_RX_BUF_COUNT=2 -#A frame has 7 bytes payload, we are using a BS of 8 and need one char for the -#string termination (7 * 8 + 1 = 57) -CONFIG_ISOTP_RX_BUF_SIZE=57 -#We have two receiving contexts that are bound to a single address. +# We have two receiving contexts that are bound to a single address. CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2 diff --git a/samples/subsys/canbus/isotp/sample.yaml b/samples/subsys/canbus/isotp/sample.yaml index dd9fadb0dea..9bb24251656 100644 --- a/samples/subsys/canbus/isotp/sample.yaml +++ b/samples/subsys/canbus/isotp/sample.yaml @@ -14,3 +14,19 @@ tests: type: one_line regex: - "(.*)Got 247 bytes in total" + sample.subsys.canbus.isotp.fd: + tags: + - can + - isotp + depends_on: can + extra_configs: + - CONFIG_SAMPLE_LOOPBACK_MODE=y + - CONFIG_SAMPLE_CAN_FD_MODE=y + platform_allow: + - native_posix + - native_posix_64 + harness: console + harness_config: + type: one_line + regex: + - "(.*)Got 247 bytes in total" diff --git a/samples/subsys/canbus/isotp/src/main.c b/samples/subsys/canbus/isotp/src/main.c index 0a37654fd3d..8005a68c07d 100644 --- a/samples/subsys/canbus/isotp/src/main.c +++ b/samples/subsys/canbus/isotp/src/main.c @@ -12,15 +12,29 @@ const struct isotp_fc_opts fc_opts_0_5 = {.bs = 0, .stmin = 5}; const struct isotp_msg_id rx_addr_8_0 = { .std_id = 0x80, +#ifdef CONFIG_SAMPLE_CAN_FD_MODE + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct isotp_msg_id tx_addr_8_0 = { .std_id = 0x180, +#ifdef CONFIG_SAMPLE_CAN_FD_MODE + .dl = 64, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct isotp_msg_id rx_addr_0_5 = { .std_id = 0x01, +#ifdef CONFIG_SAMPLE_CAN_FD_MODE + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct isotp_msg_id tx_addr_0_5 = { .std_id = 0x101, +#ifdef CONFIG_SAMPLE_CAN_FD_MODE + .dl = 64, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct device *can_dev; @@ -49,8 +63,6 @@ void rx_8_0_thread(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg3); int ret, rem_len, received_len; struct net_buf *buf; - static uint8_t rx_buffer[7]; - ret = isotp_bind(&recv_ctx_8_0, can_dev, &tx_addr_8_0, &rx_addr_8_0, @@ -71,19 +83,11 @@ void rx_8_0_thread(void *arg1, void *arg2, void *arg3) break; } - received_len += buf->len; - if (net_buf_tailroom(buf) >= 1) { - net_buf_add_u8(buf, '\0'); - printk("%s", buf->data); - } else if (buf->len == 6) { - /* First frame does not have tailroom.*/ - memcpy(rx_buffer, buf->data, 6); - rx_buffer[6] = '\0'; - printk("%s", rx_buffer); - } else { - printk("No tailroom for string termination\n"); + while (buf != NULL) { + received_len += buf->len; + printk("%.*s", buf->len, buf->data); + buf = net_buf_frag_del(NULL, buf); } - net_buf_unref(buf); } while (rem_len); printk("Got %d bytes in total\n", received_len); } @@ -142,13 +146,13 @@ int main(void) return 0; } -#ifdef CONFIG_SAMPLE_LOOPBACK_MODE - ret = can_set_mode(can_dev, CAN_MODE_LOOPBACK); + can_mode_t mode = (IS_ENABLED(CONFIG_SAMPLE_LOOPBACK_MODE) ? CAN_MODE_LOOPBACK : 0) | + (IS_ENABLED(CONFIG_SAMPLE_CAN_FD_MODE) ? CAN_MODE_FD : 0); + ret = can_set_mode(can_dev, mode); if (ret != 0) { - printk("CAN: Failed to set loopback mode [%d]", ret); + printk("CAN: Failed to set mode [%d]", ret); return 0; } -#endif /* CONFIG_SAMPLE_LOOPBACK_MODE */ ret = can_start(can_dev); if (ret != 0) { From 9e9cbd8ce43b115b7522a1b29e15cc0ca8caea0c Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Fri, 28 Jul 2023 09:53:25 +1200 Subject: [PATCH 0389/4498] tests: canbus: isotp: conformance: Add tests for CAN-FD support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow existing tests to run with CAN-FD. Add new CAN-FD specific tests. Signed-off-by: Grant Ramsay Signed-off-by: Martin Jäger --- tests/subsys/canbus/isotp/conformance/Kconfig | 14 + .../subsys/canbus/isotp/conformance/prj.conf | 2 + .../canbus/isotp/conformance/src/main.c | 276 +++++++++++++++--- .../canbus/isotp/conformance/testcase.yaml | 47 +++ 4 files changed, 294 insertions(+), 45 deletions(-) create mode 100644 tests/subsys/canbus/isotp/conformance/Kconfig diff --git a/tests/subsys/canbus/isotp/conformance/Kconfig b/tests/subsys/canbus/isotp/conformance/Kconfig new file mode 100644 index 00000000000..8ba8f1c5387 --- /dev/null +++ b/tests/subsys/canbus/isotp/conformance/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +config TEST_USE_CAN_FD_MODE + bool "Use CAN-FD" + select CAN_FD_MODE + +config TEST_ISOTP_TX_DL + int "TX_DL to be used" + default 8 + help + ISO-TP TX_DL value. + Valid values are 8, 12, 16, 20, 24, 32, 48 and 64. + +source "Kconfig.zephyr" diff --git a/tests/subsys/canbus/isotp/conformance/prj.conf b/tests/subsys/canbus/isotp/conformance/prj.conf index 56adfe9dc42..f3e50838304 100644 --- a/tests/subsys/canbus/isotp/conformance/prj.conf +++ b/tests/subsys/canbus/isotp/conformance/prj.conf @@ -7,3 +7,5 @@ CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y CONFIG_ISOTP_RX_BUF_COUNT=6 CONFIG_ISOTP_RX_BUF_SIZE=128 CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2 +# some tests may be skipped if CAN-FD should be used, but is not supported by the controller +CONFIG_ZTEST_VERIFY_RUN_ALL=n diff --git a/tests/subsys/canbus/isotp/conformance/src/main.c b/tests/subsys/canbus/isotp/conformance/src/main.c index ea55fbb7c52..e6510a25f06 100644 --- a/tests/subsys/canbus/isotp/conformance/src/main.c +++ b/tests/subsys/canbus/isotp/conformance/src/main.c @@ -10,18 +10,35 @@ #include #include "random_data.h" -#define PCI_TYPE_POS 4 +#if !defined(CONFIG_TEST_USE_CAN_FD_MODE) || CONFIG_TEST_ISOTP_TX_DL == 8 #define DATA_SIZE_SF 7 #define DATA_SIZE_CF 7 #define DATA_SIZE_SF_EXT 6 #define DATA_SIZE_FF 6 -#define DATA_SIZE_FC 3 -#define CAN_DL 8 +#define TX_DL 8 #define DATA_SEND_LENGTH 272 -#define SF_PCI_TYPE 0 #define SF_PCI_BYTE_1 ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF) #define SF_PCI_BYTE_2_EXT ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF_EXT) #define SF_PCI_BYTE_LEN_8 ((SF_PCI_TYPE << PCI_TYPE_POS) | (DATA_SIZE_SF + 1)) +#else +#define DATA_SIZE_SF (TX_DL - 2) +#define DATA_SIZE_CF (TX_DL - 1) +#define DATA_SIZE_SF_EXT (TX_DL - 3) +#define DATA_SIZE_FF (TX_DL - 2) +#define TX_DL CONFIG_TEST_ISOTP_TX_DL +/* Send length must be larger than FF + (8 * CF). + * But not so big that the remainder cannot fit into the buffers. + */ +#define DATA_SEND_LENGTH (100 + DATA_SIZE_FF + (8 * DATA_SIZE_CF)) +#define SF_PCI_BYTE_1 (SF_PCI_TYPE << PCI_TYPE_POS) +#define SF_PCI_BYTE_2 DATA_SIZE_SF +#define SF_PCI_BYTE_2_EXT (SF_PCI_TYPE << PCI_TYPE_POS) +#define SF_PCI_BYTE_3_EXT DATA_SIZE_SF_EXT +#endif + +#define DATA_SIZE_FC 3 +#define PCI_TYPE_POS 4 +#define SF_PCI_TYPE 0 #define EXT_ADDR 5 #define FF_PCI_TYPE 1 #define FF_PCI_BYTE_1(dl) ((FF_PCI_TYPE << PCI_TYPE_POS) | ((dl) >> 8)) @@ -56,7 +73,7 @@ */ struct frame_desired { - uint8_t data[8]; + uint8_t data[CAN_MAX_DLEN]; uint8_t length; }; @@ -75,39 +92,67 @@ const struct isotp_fc_opts fc_opts_single = { const struct isotp_msg_id rx_addr = { .std_id = 0x10, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct isotp_msg_id tx_addr = { .std_id = 0x11, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif }; const struct isotp_msg_id rx_addr_ext = { .std_id = 0x10, .ext_addr = EXT_ADDR, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_EXT_ADDR | ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#else .flags = ISOTP_MSG_EXT_ADDR, +#endif }; const struct isotp_msg_id tx_addr_ext = { .std_id = 0x11, .ext_addr = EXT_ADDR, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_EXT_ADDR | ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#else .flags = ISOTP_MSG_EXT_ADDR, +#endif }; const struct isotp_msg_id rx_addr_fixed = { .ext_id = 0x18DA0201, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE | ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#else .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE, +#endif }; const struct isotp_msg_id tx_addr_fixed = { .ext_id = 0x18DA0102, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE | ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#else .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE, +#endif }; -const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); -struct isotp_recv_ctx recv_ctx; -struct isotp_send_ctx send_ctx; -uint8_t data_buf[128]; +static const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); +static struct isotp_recv_ctx recv_ctx; +static struct isotp_send_ctx send_ctx; +static uint8_t data_buf[128]; CAN_MSGQ_DEFINE(frame_msgq, 10); -struct k_sem send_compl_sem; +static struct k_sem send_compl_sem; void send_complete_cb(int error_nr, void *arg) { @@ -216,13 +261,15 @@ static void send_frame_series(struct frame_desired *frames, size_t length, { int i, ret; struct can_frame frame = { - .flags = (id > 0x7FF) ? CAN_FRAME_IDE : 0, + .flags = ((id > 0x7FF) ? CAN_FRAME_IDE : 0) | + (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) ? + CAN_FRAME_FDF | CAN_FRAME_BRS : 0), .id = id }; struct frame_desired *desired = frames; for (i = 0; i < length; i++) { - frame.dlc = desired->length; + frame.dlc = can_bytes_to_dlc(desired->length); memcpy(frame.data, desired->data, desired->length); ret = can_send(can_dev, &frame, K_MSEC(500), NULL, NULL); zassert_equal(ret, 0, "Sending msg %d failed.", i); @@ -242,9 +289,9 @@ static void check_frame_series(struct frame_desired *frames, size_t length, zassert_equal(ret, 0, "Timeout waiting for msg nr %d. ret: %d", i, ret); - zassert_equal(frame.dlc, desired->length, + zassert_equal(frame.dlc, can_bytes_to_dlc(desired->length), "DLC of frame nr %d differ. Desired: %d, Got: %d", - i, desired->length, frame.dlc); + i, can_bytes_to_dlc(desired->length), frame.dlc); ret = check_data(frame.data, desired->data, desired->length); zassert_equal(ret, 0, "Data differ"); @@ -259,7 +306,8 @@ static int add_rx_msgq(uint32_t id, uint32_t mask) { int filter_id; struct can_filter filter = { - .flags = CAN_FILTER_DATA | ((id > 0x7FF) ? CAN_FILTER_IDE : 0), + .flags = CAN_FILTER_DATA | ((id > 0x7FF) ? CAN_FILTER_IDE : 0) | + (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) ? CAN_FILTER_FDF : 0), .id = id, .mask = mask }; @@ -280,13 +328,40 @@ static void prepare_fc_frame(struct frame_desired *frame, uint8_t st, frame->data[2] = FC_PCI_BYTE_3(opts->stmin); if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) || (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) { - memset(&frame->data[DATA_SIZE_FC], 0xCC, CAN_DL - DATA_SIZE_FC); - frame->length = CAN_DL; + memset(&frame->data[DATA_SIZE_FC], 0xCC, 8 - DATA_SIZE_FC); + frame->length = 8; } else { frame->length = DATA_SIZE_FC; } } +static void prepare_sf_frame(struct frame_desired *frame, const uint8_t *data) +{ + frame->data[0] = SF_PCI_BYTE_1; +#ifdef SF_PCI_BYTE_2 + frame->data[1] = SF_PCI_BYTE_2; + memcpy(&frame->data[2], data, DATA_SIZE_SF); + frame->length = DATA_SIZE_SF + 2; +#else + memcpy(&frame->data[1], data, DATA_SIZE_SF); + frame->length = DATA_SIZE_SF + 1; +#endif +} + +static void prepare_sf_ext_frame(struct frame_desired *frame, const uint8_t *data) +{ + frame->data[0] = rx_addr_ext.ext_addr; + frame->data[1] = SF_PCI_BYTE_2_EXT; +#ifdef SF_PCI_BYTE_3_EXT + frame->data[2] = SF_PCI_BYTE_3_EXT; + memcpy(&frame->data[3], data, DATA_SIZE_SF_EXT); + frame->length = DATA_SIZE_SF_EXT + 3; +#else + memcpy(&frame->data[2], data, DATA_SIZE_SF_EXT); + frame->length = DATA_SIZE_SF_EXT + 2; +#endif +} + static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, const uint8_t *data, size_t data_len, bool tx) { @@ -296,14 +371,18 @@ static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, for (i = 0; i < frames_cnt && remaining_length; i++) { frames[i].data[0] = CF_PCI_BYTE_1 | ((i+1) & 0x0F); - frames[i].length = CAN_DL; + frames[i].length = TX_DL; memcpy(&des_frames[i].data[1], data_ptr, DATA_SIZE_CF); if (remaining_length < DATA_SIZE_CF) { if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) || (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) { + uint8_t padded_dlc = can_bytes_to_dlc(MAX(8, remaining_length + 1)); + uint8_t padded_len = can_dlc_to_bytes(padded_dlc); + memset(&des_frames[i].data[remaining_length + 1], 0xCC, - CAN_DL - remaining_length - 1); + padded_len - remaining_length - 1); + frames[i].length = padded_len; } else { frames[i].length = remaining_length + 1; } @@ -320,9 +399,7 @@ ZTEST(isotp_conformance, test_send_sf) int filter_id; struct frame_desired des_frame; - des_frame.data[0] = SF_PCI_BYTE_1; - memcpy(&des_frame.data[1], random_data, DATA_SIZE_SF); - des_frame.length = DATA_SIZE_SF + 1; + prepare_sf_frame(&des_frame, random_data); filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", @@ -340,9 +417,7 @@ ZTEST(isotp_conformance, test_receive_sf) int ret; struct frame_desired single_frame; - single_frame.data[0] = SF_PCI_BYTE_1; - memcpy(&single_frame.data[1], random_data, DATA_SIZE_SF); - single_frame.length = DATA_SIZE_SF + 1; + prepare_sf_frame(&single_frame, random_data); ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts_single, K_NO_WAIT); @@ -352,8 +427,14 @@ ZTEST(isotp_conformance, test_receive_sf) get_sf(DATA_SIZE_SF); + /* Frame size too big should be ignored/dropped */ + #ifdef SF_PCI_BYTE_2 + single_frame.data[1]++; + #else single_frame.data[0] = SF_PCI_BYTE_LEN_8; + #endif send_frame_series(&single_frame, 1, rx_addr.std_id); + get_sf_ignore(); #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING single_frame.data[0] = SF_PCI_BYTE_1; @@ -371,10 +452,7 @@ ZTEST(isotp_conformance, test_send_sf_ext) int filter_id, ret; struct frame_desired des_frame; - des_frame.data[0] = rx_addr_ext.ext_addr; - des_frame.data[1] = SF_PCI_BYTE_2_EXT; - memcpy(&des_frame.data[2], random_data, DATA_SIZE_SF_EXT); - des_frame.length = DATA_SIZE_SF_EXT + 2; + prepare_sf_ext_frame(&des_frame, random_data); filter_id = add_rx_msgq(rx_addr_ext.std_id, CAN_STD_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", @@ -395,10 +473,7 @@ ZTEST(isotp_conformance, test_receive_sf_ext) int ret; struct frame_desired single_frame; - single_frame.data[0] = EXT_ADDR; - single_frame.data[1] = SF_PCI_BYTE_2_EXT; - memcpy(&single_frame.data[2], random_data, DATA_SIZE_SF_EXT); - single_frame.length = DATA_SIZE_SF_EXT + 2; + prepare_sf_ext_frame(&single_frame, random_data); ret = isotp_bind(&recv_ctx, can_dev, &rx_addr_ext, &tx_addr, &fc_opts_single, K_NO_WAIT); @@ -408,8 +483,14 @@ ZTEST(isotp_conformance, test_receive_sf_ext) get_sf(DATA_SIZE_SF_EXT); + /* Frame size too big should be ignored/dropped */ + #ifdef SF_PCI_BYTE_2 + single_frame.data[2]++; + #else single_frame.data[1] = SF_PCI_BYTE_1; + #endif send_frame_series(&single_frame, 1, rx_addr.std_id); + get_sf_ignore(); #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING single_frame.data[1] = SF_PCI_BYTE_2_EXT; @@ -427,9 +508,7 @@ ZTEST(isotp_conformance, test_send_sf_fixed) int filter_id, ret; struct frame_desired des_frame; - des_frame.data[0] = SF_PCI_BYTE_1; - memcpy(&des_frame.data[1], random_data, DATA_SIZE_SF); - des_frame.length = DATA_SIZE_SF + 1; + prepare_sf_frame(&des_frame, random_data); /* mask to allow any priority and source address (SA) */ filter_id = add_rx_msgq(rx_addr_fixed.ext_id, 0x03FFFF00); @@ -451,9 +530,7 @@ ZTEST(isotp_conformance, test_receive_sf_fixed) int ret; struct frame_desired single_frame; - single_frame.data[0] = SF_PCI_BYTE_1; - memcpy(&single_frame.data[1], random_data, DATA_SIZE_SF); - single_frame.length = DATA_SIZE_SF + 1; + prepare_sf_frame(&single_frame, random_data); ret = isotp_bind(&recv_ctx, can_dev, &rx_addr_fixed, &tx_addr_fixed, &fc_opts_single, K_NO_WAIT); @@ -488,7 +565,7 @@ ZTEST(isotp_conformance, test_send_data) ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH); ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH); memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF); - ff_frame.length = CAN_DL; + ff_frame.length = TX_DL; data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; @@ -585,7 +662,7 @@ ZTEST(isotp_conformance, test_receive_data) ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH); ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH); memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF); - ff_frame.length = CAN_DL; + ff_frame.length = TX_DL; data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; @@ -940,8 +1017,114 @@ ZTEST(isotp_conformance, test_sender_fc_errors) can_remove_rx_filter(can_dev, filter_id); } +ZTEST(isotp_conformance, test_canfd_mandatory_padding) +{ + /* Mandatory padding of CAN-FD frames (TX_DL > 8). + * Must be padded with 0xCC up to the nearest DLC. + */ +#if TX_DL < 12 + ztest_test_skip(); +#else + /* Input a single frame packet of 10 bytes */ + uint8_t data_size_sf = 10 - 2; + int filter_id, ret; + struct can_frame frame = {}; + const uint8_t expected_padding[] = { 0xCC, 0xCC }; + + filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK); + + ret = isotp_send(&send_ctx, can_dev, random_data, data_size_sf, + &rx_addr, &tx_addr, send_complete_cb, INT_TO_POINTER(ISOTP_N_OK)); + zassert_equal(ret, 0, "Send returned %d", ret); + + ret = k_msgq_get(&frame_msgq, &frame, K_MSEC(500)); + zassert_equal(ret, 0, "Timeout waiting for msg. ret: %d", ret); + + /* The output frame should be 12 bytes, with the last two bytes being 0xCC */ + zassert_equal(can_dlc_to_bytes(frame.dlc), 12, "Incorrect DLC"); + zassert_mem_equal(&frame.data[10], expected_padding, sizeof(expected_padding)); + + can_remove_rx_filter(can_dev, filter_id); +#endif +} + +ZTEST(isotp_conformance, test_canfd_rx_dl_validation) +{ + /* First frame defines the RX data length, consecutive frames + * must have the same length (except the last frame) + */ +#if TX_DL < 16 + ztest_test_skip(); +#else + + uint8_t data_size_ff = 16 - 2; + uint8_t data_size_cf = 12 - 1; + uint8_t data_send_length = data_size_ff + 2 * data_size_cf; + const uint8_t *data_ptr = random_data; + int filter_id, ret; + struct frame_desired fc_frame, ff_frame; + + /* FF uses a TX_DL of 16 */ + ff_frame.data[0] = FF_PCI_BYTE_1(data_send_length); + ff_frame.data[1] = FF_PCI_BYTE_2(data_send_length); + memcpy(&ff_frame.data[2], data_ptr, data_size_ff); + ff_frame.length = data_size_ff + 2; + data_ptr += data_size_ff; + + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, true); + + /* Two CF frames using a TX_DL of 12 */ + des_frames[0].data[0] = CF_PCI_BYTE_1 | (1 & 0x0F); + des_frames[0].length = data_size_cf + 1; + memcpy(&des_frames[0].data[1], data_ptr, data_size_cf); + data_ptr += data_size_cf; + + des_frames[1].data[0] = CF_PCI_BYTE_1 | (2 & 0x0F); + des_frames[1].length = data_size_cf + 1; + memcpy(&des_frames[1].data[1], data_ptr, data_size_cf); + data_ptr += data_size_cf; + + filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK); + + ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, + &fc_opts_single, K_NO_WAIT); + zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret); + + send_frame_series(&ff_frame, 1, rx_addr.std_id); + + check_frame_series(&fc_frame, 1, &frame_msgq); + + send_frame_series(des_frames, 2, rx_addr.std_id); + + /* Assert that the packet was dropped and an error returned */ + ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200)); + zassert_equal(ret, ISOTP_N_ERROR, "recv returned %d", ret); + + can_remove_rx_filter(can_dev, filter_id); + isotp_unbind(&recv_ctx); +#endif +} + +static bool canfd_predicate(const void *state) +{ + ARG_UNUSED(state); + +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + can_mode_t cap; + int err; + + err = can_get_capabilities(can_dev, &cap); + zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err); + + if ((cap & CAN_MODE_FD) == 0) { + return false; + } +#endif -void *isotp_conformance_setup(void) + return true; +} + +static void *isotp_conformance_setup(void) { int ret; @@ -950,8 +1133,11 @@ void *isotp_conformance_setup(void) zassert_true(device_is_ready(can_dev), "CAN device not ready"); - ret = can_set_mode(can_dev, CAN_MODE_LOOPBACK); - zassert_equal(ret, 0, "Failed to set loopback mode [%d]", ret); + (void)can_stop(can_dev); + + ret = can_set_mode(can_dev, CAN_MODE_LOOPBACK | + (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) ? CAN_MODE_FD : 0)); + zassert_equal(ret, 0, "Failed to set mode [%d]", ret); ret = can_start(can_dev); zassert_equal(ret, 0, "Failed to start CAN controller [%d]", ret); @@ -961,4 +1147,4 @@ void *isotp_conformance_setup(void) return NULL; } -ZTEST_SUITE(isotp_conformance, NULL, isotp_conformance_setup, NULL, NULL, NULL); +ZTEST_SUITE(isotp_conformance, canfd_predicate, isotp_conformance_setup, NULL, NULL, NULL); diff --git a/tests/subsys/canbus/isotp/conformance/testcase.yaml b/tests/subsys/canbus/isotp/conformance/testcase.yaml index 04962aa08d8..74ab3331ffa 100644 --- a/tests/subsys/canbus/isotp/conformance/testcase.yaml +++ b/tests/subsys/canbus/isotp/conformance/testcase.yaml @@ -1,7 +1,54 @@ +# +# There are 4 different test cases that have to be considered: +# +# | Case # | Controller type | Selected mode | Example board | +# +--------+------------------------+----------------------+----------------+ +# | 1 | Classical CAN only | CONFIG_CAN_FD_MODE=n | nucleo_f072 | +# | 2 | Classical CAN only | CONFIG_CAN_FD_MODE=y | nucleo_f072 | +# | 3 | Classical CAN + CAN-FD | CONFIG_CAN_FD_MODE=n | native_posix | +# | 4 | Classical CAN + CAN-FD | CONFIG_CAN_FD_MODE=y | native_posix | +# +# The test-specific CONFIG_TEST_USE_CAN_FD_MODE is used to decide if the test should use +# CAN-FD independent of CONFIG_CAN_FD_MODE configuration. +# + tests: + # cases 1, 3 canbus.isotp.conformance: tags: - can - isotp depends_on: can filter: dt_chosen_enabled("zephyr,canbus") and not dt_compat_enabled("kvaser,pcican") + # case 2 + canbus.isotp.conformance.fd.unused: + tags: + - can + - isotp + extra_configs: + - CONFIG_TEST_USE_CAN_FD_MODE=n + - CONFIG_CAN_FD_MODE=y + depends_on: can + filter: dt_chosen_enabled("zephyr,canbus") and not dt_compat_enabled("kvaser,pcican") + # case 4 + canbus.isotp.conformance.fd.txdl_32: + tags: + - can + - isotp + extra_configs: + - CONFIG_TEST_USE_CAN_FD_MODE=y + - CONFIG_TEST_ISOTP_TX_DL=32 + - CONFIG_CAN_FD_MODE=y + depends_on: can + filter: dt_chosen_enabled("zephyr,canbus") and not dt_compat_enabled("kvaser,pcican") + # case 4 + canbus.isotp.conformance.fd.txdl_64: + tags: + - can + - isotp + extra_configs: + - CONFIG_TEST_USE_CAN_FD_MODE=y + - CONFIG_TEST_ISOTP_TX_DL=64 + - CONFIG_CAN_FD_MODE=y + depends_on: can + filter: dt_chosen_enabled("zephyr,canbus") and not dt_compat_enabled("kvaser,pcican") From a816180b166cab184e566055b1534fb339909eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 23 Aug 2023 19:04:13 +0200 Subject: [PATCH 0390/4498] tests: canbus: isotp: conformance: add mode_check test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test to check error codes if attempting to use ISO-TP with CAN FD mode even though the controller supports classical CAN only. Signed-off-by: Martin Jäger --- .../canbus/isotp/conformance/src/mode_check.c | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tests/subsys/canbus/isotp/conformance/src/mode_check.c diff --git a/tests/subsys/canbus/isotp/conformance/src/mode_check.c b/tests/subsys/canbus/isotp/conformance/src/mode_check.c new file mode 100644 index 00000000000..fac5eeffa70 --- /dev/null +++ b/tests/subsys/canbus/isotp/conformance/src/mode_check.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Libre Solar Technologies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This test suite checks that correct errors are returned when trying to use the ISO-TP + * protocol with CAN-FD mode even though the controller does not support CAN-FD. + */ + +#include +#include + +static const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); +static struct isotp_recv_ctx recv_ctx; +static struct isotp_send_ctx send_ctx; +static bool canfd_capable; + +static const struct isotp_fc_opts fc_opts = { + .bs = 0, + .stmin = 0 +}; + +static const struct isotp_msg_id rx_addr = { + .std_id = 0x20, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif +}; + +static const struct isotp_msg_id tx_addr = { + .std_id = 0x21, +#ifdef CONFIG_TEST_USE_CAN_FD_MODE + .dl = CONFIG_TEST_ISOTP_TX_DL, + .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, +#endif +}; + +ZTEST(isotp_conformance_mode_check, test_bind) +{ + int err; + + err = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts, K_NO_WAIT); + if (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) && !canfd_capable) { + zassert_equal(err, ISOTP_N_ERROR); + } else { + zassert_equal(err, ISOTP_N_OK); + } + + isotp_unbind(&recv_ctx); +} + +ZTEST(isotp_conformance_mode_check, test_send) +{ + uint8_t buf[] = { 1, 2, 3 }; + int err; + + err = isotp_send(&send_ctx, can_dev, buf, sizeof(buf), &rx_addr, &tx_addr, NULL, NULL); + if (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) && !canfd_capable) { + zassert_equal(err, ISOTP_N_ERROR); + } else { + zassert_equal(err, ISOTP_N_OK); + } +} + +static void *isotp_conformance_mode_check_setup(void) +{ + can_mode_t cap; + int err; + + zassert_true(device_is_ready(can_dev), "CAN device not ready"); + + err = can_get_capabilities(can_dev, &cap); + zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err); + + canfd_capable = (cap & CAN_MODE_FD) != 0; + + (void)can_stop(can_dev); + + err = can_set_mode(can_dev, CAN_MODE_LOOPBACK | (canfd_capable ? CAN_MODE_FD : 0)); + zassert_equal(err, 0, "Failed to set mode [%d]", err); + + err = can_start(can_dev); + zassert_equal(err, 0, "Failed to start CAN controller [%d]", err); + + return NULL; +} + +ZTEST_SUITE(isotp_conformance_mode_check, NULL, isotp_conformance_mode_check_setup, NULL, NULL, + NULL); From ef77fe3402c95ea40c2ab376554737fe8796f526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Thu, 7 Sep 2023 12:03:16 +0200 Subject: [PATCH 0391/4498] tests: canbus: isotp: conformance: fix global variable usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though it was leading to the same result, the function should use its parameter and not the global variable for desired frames. Signed-off-by: Martin Jäger --- tests/subsys/canbus/isotp/conformance/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/subsys/canbus/isotp/conformance/src/main.c b/tests/subsys/canbus/isotp/conformance/src/main.c index e6510a25f06..64947ae0ed1 100644 --- a/tests/subsys/canbus/isotp/conformance/src/main.c +++ b/tests/subsys/canbus/isotp/conformance/src/main.c @@ -372,7 +372,7 @@ static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, for (i = 0; i < frames_cnt && remaining_length; i++) { frames[i].data[0] = CF_PCI_BYTE_1 | ((i+1) & 0x0F); frames[i].length = TX_DL; - memcpy(&des_frames[i].data[1], data_ptr, DATA_SIZE_CF); + memcpy(&frames[i].data[1], data_ptr, DATA_SIZE_CF); if (remaining_length < DATA_SIZE_CF) { if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) || @@ -380,7 +380,7 @@ static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, uint8_t padded_dlc = can_bytes_to_dlc(MAX(8, remaining_length + 1)); uint8_t padded_len = can_dlc_to_bytes(padded_dlc); - memset(&des_frames[i].data[remaining_length + 1], 0xCC, + memset(&frames[i].data[remaining_length + 1], 0xCC, padded_len - remaining_length - 1); frames[i].length = padded_len; } else { From 017cf89a836216802f6fe69d8c7a77e970c31918 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 11 Aug 2023 11:58:34 +0300 Subject: [PATCH 0392/4498] arch: Add support for static shared interrupts This commit introduces all the necessary changes for enabling the usage of shared interrupts. This works by using a second interrupt table: _shared_sw_isr_table which keeps track of all of the ISR/arg pairs sharing the same interrupt line. Whenever a second ISR/arg pair is registered on the same interrupt line using IRQ_CONNECT(), the entry in _sw_isr_table will be overwriten by a (shared_isr, _shared_sw_isr_table[irq]) pair. In turn, shared_isr() will invoke all of the ISR/arg pairs registered on the same interrupt line. This feature only works statically, meaning you can only make use of shared interrupts using IRQ_CONNECT(). Attempting to dynamically register a ISR/arg pair will overwrite the hijacked _sw_isr_table entry. Signed-off-by: Laurentiu Mihalcea --- arch/Kconfig | 17 +++++ arch/common/CMakeLists.txt | 2 + arch/common/isr_tables.c | 5 ++ arch/common/shared_irq.c | 31 ++++++++ include/zephyr/linker/common-ram.ld | 9 +++ .../common-rom/common-rom-kernel-devices.ld | 9 +++ include/zephyr/linker/section_tags.h | 4 + include/zephyr/linker/sections.h | 5 ++ include/zephyr/sw_isr_table.h | 16 ++++ scripts/build/gen_isr_tables.py | 75 ++++++++++++++++--- 10 files changed, 162 insertions(+), 11 deletions(-) create mode 100644 arch/common/shared_irq.c diff --git a/arch/Kconfig b/arch/Kconfig index 332bb49455f..4560fdfcc51 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -403,6 +403,23 @@ config DYNAMIC_INTERRUPTS interrupt-related data structures to RAM instead of ROM, and on some architectures increase code size. +config SHARED_INTERRUPTS + bool "Set this to enable support for shared interrupts" + depends on GEN_SW_ISR_TABLE + select EXPERIMENTAL + help + Set this to enable support for shared interrupts. Use this with + caution as enabling this will increase the image size by a + non-negligible amount. + +config SHARED_IRQ_MAX_NUM_CLIENTS + int "Maximum number of clients allowed per shared interrupt" + default 2 + depends on SHARED_INTERRUPTS + help + This option controls the maximum number of clients allowed + per shared interrupt. Set this according to your needs. + config GEN_ISR_TABLES bool "Use generated IRQ tables" help diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index f9c6f8a72bb..8056ad5d95d 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -10,6 +10,8 @@ zephyr_library_sources_ifdef( sw_isr_common.c ) +zephyr_library_sources_ifdef(CONFIG_SHARED_INTERRUPTS shared_irq.c) + if(NOT CONFIG_ARCH_HAS_TIMING_FUNCTIONS AND NOT CONFIG_SOC_HAS_TIMING_FUNCTIONS AND NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c index a22776f8edb..0311f81f252 100644 --- a/arch/common/isr_tables.c +++ b/arch/common/isr_tables.c @@ -81,3 +81,8 @@ struct _isr_table_entry __sw_isr_table _sw_isr_table[IRQ_TABLE_SIZE] = { (void *)&z_irq_spurious}, }; #endif + +#ifdef CONFIG_SHARED_INTERRUPTS +struct z_shared_isr_table_entry __shared_sw_isr_table z_shared_sw_isr_table[IRQ_TABLE_SIZE] = { +}; +#endif diff --git a/arch/common/shared_irq.c b/arch/common/shared_irq.c new file mode 100644 index 00000000000..9548ceb7e71 --- /dev/null +++ b/arch/common/shared_irq.c @@ -0,0 +1,31 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* an interrupt line can be considered shared only if there's + * at least 2 clients using it. As such, enforce the fact that + * the maximum number of allowed clients should be at least 2. + */ +BUILD_ASSERT(CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS >= 2, + "maximum number of clients should be at least 2"); + +void z_shared_isr(const void *data) +{ + size_t i; + const struct z_shared_isr_table_entry *entry; + const struct z_shared_isr_client *client; + + entry = data; + + for (i = 0; i < entry->client_num; i++) { + client = &entry->clients[i]; + + if (client->isr) { + client->isr(client->arg); + } + } +} diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index bfaa26ed400..b77e16a6182 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -27,6 +27,15 @@ . = ALIGN(CONFIG_ARCH_SW_ISR_TABLE_ALIGN); *(_SW_ISR_TABLE_SECTION_SYMS) } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#if defined(CONFIG_SHARED_INTERRUPTS) + SECTION_DATA_PROLOGUE(shared_sw_isr_table,,) + { + /* TODO: does this section require alignment? */ + KEEP(*(_SHARED_SW_ISR_TABLE_SECTION_SYMS)) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif + #endif SECTION_DATA_PROLOGUE(device_states,,) diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 6b26691fa59..3d074ac1b38 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -33,6 +33,15 @@ . = ALIGN(CONFIG_ARCH_SW_ISR_TABLE_ALIGN); *(_SW_ISR_TABLE_SECTION_SYMS) } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#if defined(CONFIG_SHARED_INTERRUPTS) + SECTION_PROLOGUE(shared_sw_isr_table,,) + { + /* TODO: does this section require alignment? */ + KEEP(*(_SHARED_SW_ISR_TABLE_SECTION_SYMS)) + } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif + #endif /* verify we don't have rogue .z_init_ initlevel sections */ diff --git a/include/zephyr/linker/section_tags.h b/include/zephyr/linker/section_tags.h index 65df354a7b0..d0ef2ecf126 100644 --- a/include/zephyr/linker/section_tags.h +++ b/include/zephyr/linker/section_tags.h @@ -18,6 +18,10 @@ #define __irq_vector_table Z_GENERIC_SECTION(_IRQ_VECTOR_TABLE_SECTION_NAME) #define __sw_isr_table Z_GENERIC_SECTION(_SW_ISR_TABLE_SECTION_NAME) +#ifdef CONFIG_SHARED_INTERRUPTS +#define __shared_sw_isr_table Z_GENERIC_SECTION(_SHARED_SW_ISR_TABLE_SECTION_NAME) +#endif /* CONFIG_SHARED_INTERRUPTS */ + /* Attribute macros to place code and data into IMR memory */ #define __imr __in_section_unique(imr) #define __imrdata __in_section_unique(imrdata) diff --git a/include/zephyr/linker/sections.h b/include/zephyr/linker/sections.h index ff6dae15dcc..2f1049d09f3 100644 --- a/include/zephyr/linker/sections.h +++ b/include/zephyr/linker/sections.h @@ -39,6 +39,11 @@ #define _SW_ISR_TABLE_SECTION_NAME .gnu.linkonce.sw_isr_table #define _SW_ISR_TABLE_SECTION_SYMS .gnu.linkonce.sw_isr_table* +#ifdef CONFIG_SHARED_INTERRUPTS +#define _SHARED_SW_ISR_TABLE_SECTION_NAME .gnu.linkonce.shared_sw_isr_table +#define _SHARED_SW_ISR_TABLE_SECTION_SYMS .gnu.linkonce.shared_sw_isr_table* +#endif /* CONFIG_SHARED_INTERRUPTS */ + /* Architecture-specific sections */ #if defined(CONFIG_ARM) #define _KINETIS_FLASH_CONFIG_SECTION_NAME kinetis_flash_config diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index 3fd687d2c58..dd700fdfd46 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -61,6 +61,22 @@ struct _isr_list { const void *param; }; +#ifdef CONFIG_SHARED_INTERRUPTS +struct z_shared_isr_client { + void (*isr)(const void *arg); + const void *arg; +}; + +struct z_shared_isr_table_entry { + struct z_shared_isr_client clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS]; + size_t client_num; +}; + +void z_shared_isr(const void *data); + +extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; +#endif /* CONFIG_SHARED_INTERRUPTS */ + /** This interrupt gets put directly in the vector table */ #define ISR_FLAG_DIRECT BIT(0) diff --git a/scripts/build/gen_isr_tables.py b/scripts/build/gen_isr_tables.py index 1b564e17a3c..5c525d67878 100755 --- a/scripts/build/gen_isr_tables.py +++ b/scripts/build/gen_isr_tables.py @@ -177,11 +177,37 @@ def write_address_irq_vector_table(fp, vt, nv): typedef void (* ISR)(const void *); """ -def write_source_file(fp, vt, swt, intlist, syms): +def write_shared_table(fp, shared, nv): + fp.write("struct z_shared_isr_table_entry __shared_sw_isr_table" + " z_shared_sw_isr_table[%d] = {\n" % nv) + + for i in range(nv): + client_num = shared[i][1] + client_list = shared[i][0] + + if not client_num: + fp.write("\t{ },\n") + else: + fp.write(f"\t{{ .client_num = {client_num}, .clients = {{ ") + for j in range(0, client_num): + routine = client_list[j][1] + arg = client_list[j][0] + + fp.write(f"{{ .isr = (ISR){ hex(routine) if isinstance(routine, int) else routine }, " + f".arg = (const void *){hex(arg)} }},") + + fp.write(" },\n},\n") + + fp.write("};\n") + +def write_source_file(fp, vt, swt, intlist, syms, shared): fp.write(source_header) nv = intlist["num_vectors"] + if "CONFIG_SHARED_INTERRUPTS" in syms: + write_shared_table(fp, shared, nv) + if vt: if "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS" in syms: write_address_irq_vector_table(fp, vt, nv) @@ -200,7 +226,11 @@ def write_source_file(fp, vt, swt, intlist, syms): level3_offset = syms.get("CONFIG_3RD_LVL_ISR_TBL_OFFSET") for i in range(nv): - param, func = swt[i] + param = "{0:#x}".format(swt[i][0]) + func = swt[i][1] + + if isinstance (func, str) and "z_shared_isr" in func: + param = "&z_shared_sw_isr_table[{0}]".format(i) if isinstance(func, int): func_as_string = "{0:#x}".format(func) else: @@ -213,7 +243,7 @@ def write_source_file(fp, vt, swt, intlist, syms): fp.write("\t/* Level 3 interrupts start here (offset: {}) */\n". format(level3_offset)) - fp.write("\t{{(const void *){0:#x}, (ISR){1}}},\n".format(param, func_as_string)) + fp.write("\t{{(const void *){0}, (ISR){1}}},\n".format(param, func_as_string)) fp.write("};\n") def get_symbols(obj): @@ -291,6 +321,7 @@ def main(): raise ValueError('nvec is too large, check endianness.') swt_spurious_handler = "((uintptr_t)&z_irq_spurious)" + swt_shared_handler = "((uintptr_t)&z_shared_isr)" vt_spurious_handler = "z_irq_spurious" vt_irq_handler = "_isr_wrapper" @@ -308,6 +339,7 @@ def main(): # Default to spurious interrupt handler. Configured interrupts # will replace these entries. swt = [(0, swt_spurious_handler) for i in range(nvec)] + shared = [([], 0) for i in range(nvec)] else: if args.vector_table: vt = [vt_spurious_handler for i in range(nvec)] @@ -369,16 +401,37 @@ def main(): if not 0 <= table_index < len(swt): error("IRQ %d (offset=%d) exceeds the maximum of %d" % (table_index, offset, len(swt) - 1)) - if swt[table_index] != (0, swt_spurious_handler): - error(f"multiple registrations at table_index {table_index} for irq {irq} (0x{irq:x})" - + f"\nExisting handler 0x{swt[table_index][1]:x}, new handler 0x{func:x}" - + "\nHas IRQ_CONNECT or IRQ_DIRECT_CONNECT accidentally been invoked on the same irq multiple times?" - ) - - swt[table_index] = (param, func) + if "CONFIG_SHARED_INTERRUPTS" in syms: + if swt[table_index] != (0, swt_spurious_handler): + # check client limit + if syms["CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS"] == shared[table_index][1]: + error(f"Reached shared interrupt client limit. Maybe increase" + + f" CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS?") + lst = shared[table_index][0] + delta_size = 1 + if not shared[table_index][1]: + lst.append(swt[table_index]) + # note: the argument will be fixed when writing the ISR table + # to isr_table.c + swt[table_index] = (0, swt_shared_handler) + delta_size += 1 + if (param, func) in lst: + error("Attempting to register the same ISR/arg pair twice.") + lst.append((param, func)) + shared[table_index] = (lst, shared[table_index][1] + delta_size) + else: + swt[table_index] = (param, func) + else: + if swt[table_index] != (0, swt_spurious_handler): + error(f"multiple registrations at table_index {table_index} for irq {irq} (0x{irq:x})" + + f"\nExisting handler 0x{swt[table_index][1]:x}, new handler 0x{func:x}" + + "\nHas IRQ_CONNECT or IRQ_DIRECT_CONNECT accidentally been invoked on the same irq multiple times?" + ) + else: + swt[table_index] = (param, func) with open(args.output_source, "w") as fp: - write_source_file(fp, vt, swt, intlist, syms) + write_source_file(fp, vt, swt, intlist, syms, shared) if __name__ == "__main__": main() From 30d362dbacce004aae78486479c9dcaf2e218cd4 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 30 Aug 2023 15:08:03 +0300 Subject: [PATCH 0393/4498] arch: common: sw_isr_common: Move table index computing logic to function Since the shared IRQ code will also use the same logic to compute the _sw_isr_table index, move the computing logic to a separate function: z_get_sw_isr_table_idx(), which can be used by other modules. Signed-off-by: Laurentiu Mihalcea --- arch/common/sw_isr_common.c | 43 ++++++++++++++++++++--------------- include/zephyr/sw_isr_table.h | 10 ++++++++ 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index 538c03603f2..2aa6202aaee 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -71,40 +71,28 @@ unsigned int get_parent_offset(unsigned int parent_irq, #endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ -void z_isr_install(unsigned int irq, void (*routine)(const void *), - const void *param) +unsigned int z_get_sw_isr_table_idx(unsigned int irq) { unsigned int table_idx; - /* - * Do not assert on the IRQ enable status for ARM GIC since the SGI - * type interrupts are always enabled and attempting to install an ISR - * for them will cause the assertion to fail. - */ -#ifndef CONFIG_GIC - __ASSERT(!irq_is_enabled(irq), "IRQ %d is enabled", irq); -#endif /* !CONFIG_GIC */ - #ifdef CONFIG_MULTI_LEVEL_INTERRUPTS - unsigned int level; - unsigned int parent_irq; - unsigned int parent_offset; + unsigned int level, parent_irq, parent_offset; level = irq_get_level(irq); if (level == 2U) { parent_irq = irq_parent_level_2(irq); parent_offset = get_parent_offset(parent_irq, - lvl2_irq_list, - CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + lvl2_irq_list, + CONFIG_NUM_2ND_LEVEL_AGGREGATORS); table_idx = parent_offset + irq_from_level_2(irq); } #ifdef CONFIG_3RD_LEVEL_INTERRUPTS else if (level == 3U) { parent_irq = irq_parent_level_3(irq); parent_offset = get_parent_offset(parent_irq, - lvl3_irq_list, - CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + lvl3_irq_list, + CONFIG_NUM_3RD_LEVEL_AGGREGATORS); table_idx = parent_offset + irq_from_level_3(irq); } #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ @@ -117,6 +105,25 @@ void z_isr_install(unsigned int irq, void (*routine)(const void *), table_idx = irq - CONFIG_GEN_IRQ_START_VECTOR; #endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ + return table_idx; +} + +void z_isr_install(unsigned int irq, void (*routine)(const void *), + const void *param) +{ + unsigned int table_idx; + + /* + * Do not assert on the IRQ enable status for ARM GIC since the SGI + * type interrupts are always enabled and attempting to install an ISR + * for them will cause the assertion to fail. + */ +#ifndef CONFIG_GIC + __ASSERT(!irq_is_enabled(irq), "IRQ %d is enabled", irq); +#endif /* !CONFIG_GIC */ + + table_idx = z_get_sw_isr_table_idx(irq); + /* If dynamic IRQs are enabled, then the _sw_isr_table is in RAM and * can be modified */ diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index dd700fdfd46..bd301e47592 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -77,6 +77,16 @@ void z_shared_isr(const void *data); extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #endif /* CONFIG_SHARED_INTERRUPTS */ +/** + * @brief Helper function used to compute the index in _sw_isr_table + * based on passed IRQ. + * + * @param irq IRQ number in its zephyr format + * + * @return corresponding index in _sw_isr_table + */ +unsigned int z_get_sw_isr_table_idx(unsigned int irq); + /** This interrupt gets put directly in the vector table */ #define ISR_FLAG_DIRECT BIT(0) From 02f52503bb32fdf4d363305a9e9bfe1a7ee23709 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 11 Aug 2023 12:04:23 +0300 Subject: [PATCH 0394/4498] arch: Add support for dynamic shared interrupts This works by overwriting z_isr_install()'s definition (possible since the symbol is now weak) with our own definiton. Whenever trying to register a new ISR/arg pair, z_isr_install() will check to see if the interrupt line is already in use. If it's not then it will not share the interrupt and will work exactly as the old z_isr_install(), meaning it will just write the new ISR/arg pair to _sw_isr_table. If the interrupt line is already being used by an ISR/arg pair then that line will become shared, meaning we'll overwrite _sw_isr_table with our own (z_shared_isr, z_shared_sw_isr_table[irq]) pair. Signed-off-by: Laurentiu Mihalcea --- arch/common/shared_irq.c | 73 +++++++++++++++++++++++++++++++++++++ arch/common/sw_isr_common.c | 4 +- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/arch/common/shared_irq.c b/arch/common/shared_irq.c index 9548ceb7e71..075a1679850 100644 --- a/arch/common/shared_irq.c +++ b/arch/common/shared_irq.c @@ -5,6 +5,7 @@ */ #include +#include /* an interrupt line can be considered shared only if there's * at least 2 clients using it. As such, enforce the fact that @@ -29,3 +30,75 @@ void z_shared_isr(const void *data) } } } + +#ifdef CONFIG_DYNAMIC_INTERRUPTS + +static struct k_spinlock lock; + +void z_isr_install(unsigned int irq, void (*routine)(const void *), + const void *param) +{ + struct z_shared_isr_table_entry *shared_entry; + struct _isr_table_entry *entry; + struct z_shared_isr_client *client; + unsigned int table_idx; + int i; + k_spinlock_key_t key; + + table_idx = z_get_sw_isr_table_idx(irq); + + /* check for out of bounds table index */ + if (table_idx >= CONFIG_NUM_IRQS) { + return; + } + + shared_entry = &z_shared_sw_isr_table[table_idx]; + entry = &_sw_isr_table[table_idx]; + + key = k_spin_lock(&lock); + + /* have we reached the client limit? */ + __ASSERT(shared_entry->client_num < CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS, + "reached maximum number of clients"); + + if (entry->isr == z_irq_spurious) { + /* this is the first time a ISR/arg pair is registered + * for INTID => no need to share it. + */ + entry->isr = routine; + entry->arg = param; + + k_spin_unlock(&lock, key); + + return; + } else if (entry->isr != z_shared_isr) { + /* INTID is being used by another ISR/arg pair. + * Push back the ISR/arg pair registered in _sw_isr_table + * to the list of clients and hijack the pair stored in + * _sw_isr_table with our own z_shared_isr/shared_entry pair. + */ + shared_entry->clients[shared_entry->client_num].isr = entry->isr; + shared_entry->clients[shared_entry->client_num].arg = entry->arg; + + shared_entry->client_num++; + + entry->isr = z_shared_isr; + entry->arg = shared_entry; + } + + /* don't register the same ISR/arg pair multiple times */ + for (i = 0; i < shared_entry->client_num; i++) { + client = &shared_entry->clients[i]; + + __ASSERT(client->isr != routine && client->arg != param, + "trying to register duplicate ISR/arg pair"); + } + + shared_entry->clients[shared_entry->client_num].isr = routine; + shared_entry->clients[shared_entry->client_num].arg = param; + shared_entry->client_num++; + + k_spin_unlock(&lock, key); +} + +#endif /* CONFIG_DYNAMIC_INTERRUPTS */ diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index 2aa6202aaee..a5262e7fa83 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -108,8 +108,8 @@ unsigned int z_get_sw_isr_table_idx(unsigned int irq) return table_idx; } -void z_isr_install(unsigned int irq, void (*routine)(const void *), - const void *param) +void __weak z_isr_install(unsigned int irq, void (*routine)(const void *), + const void *param) { unsigned int table_idx; From b8d487e54b31666cbfb445062ed51bd997953d3c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 11 Aug 2023 13:09:22 +0300 Subject: [PATCH 0395/4498] arch: Add support for dynamically disconnecting shared interrupts This commit provides the users a way to disconnect dynamic interrupts. This is needed because we don't want to keep piling up ISR/arg pairs until the number of registrable clients is reached. This feature is only relevant for shared and dynamic interrupts. Signed-off-by: Laurentiu Mihalcea --- arch/common/shared_irq.c | 105 ++++++++++++++++++++++++++++ include/zephyr/irq.h | 25 +++++++ include/zephyr/sw_isr_table.h | 5 ++ include/zephyr/sys/arch_interface.h | 18 +++++ 4 files changed, 153 insertions(+) diff --git a/arch/common/shared_irq.c b/arch/common/shared_irq.c index 075a1679850..744aece2fd7 100644 --- a/arch/common/shared_irq.c +++ b/arch/common/shared_irq.c @@ -101,4 +101,109 @@ void z_isr_install(unsigned int irq, void (*routine)(const void *), k_spin_unlock(&lock, key); } +static void swap_client_data(struct z_shared_isr_client *a, + struct z_shared_isr_client *b) +{ + struct z_shared_isr_client tmp; + + tmp.arg = a->arg; + tmp.isr = a->isr; + + a->arg = b->arg; + a->isr = b->isr; + + b->arg = tmp.arg; + b->isr = tmp.isr; +} + +static void shared_irq_remove_client(struct z_shared_isr_table_entry *shared_entry, + int client_idx, unsigned int table_idx) +{ + int i; + + shared_entry->clients[client_idx].isr = NULL; + shared_entry->clients[client_idx].arg = NULL; + + /* push back the removed client to the end of the client list */ + for (i = client_idx; i <= (int)shared_entry->client_num - 2; i++) { + swap_client_data(&shared_entry->clients[i], + &shared_entry->clients[i + 1]); + } + + shared_entry->client_num--; + + /* "unshare" interrupt if there will be a single client left */ + if (shared_entry->client_num == 1) { + _sw_isr_table[table_idx].isr = shared_entry->clients[0].isr; + _sw_isr_table[table_idx].arg = shared_entry->clients[0].arg; + + shared_entry->clients[0].isr = NULL; + shared_entry->clients[0].arg = NULL; + + shared_entry->client_num--; + } +} + +int __weak arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) +{ + ARG_UNUSED(priority); + ARG_UNUSED(flags); + + return z_isr_uninstall(irq, routine, parameter); +} + +int z_isr_uninstall(unsigned int irq, + void (*routine)(const void *), + const void *parameter) +{ + struct z_shared_isr_table_entry *shared_entry; + struct _isr_table_entry *entry; + struct z_shared_isr_client *client; + unsigned int table_idx; + size_t i; + k_spinlock_key_t key; + + table_idx = z_get_sw_isr_table_idx(irq); + + /* check for out of bounds table index */ + if (table_idx >= CONFIG_NUM_IRQS) { + return -EINVAL; + } + + shared_entry = &z_shared_sw_isr_table[table_idx]; + entry = &_sw_isr_table[table_idx]; + + key = k_spin_lock(&lock); + + /* note: it's important that we remove the ISR/arg pair even if + * the IRQ line is not being shared because z_isr_install() will + * not overwrite it unless the _sw_isr_table entry for the given + * IRQ line contains the default pair which is z_irq_spurious/NULL. + */ + if (!shared_entry->client_num) { + if (entry->isr == routine && entry->arg == parameter) { + entry->isr = z_irq_spurious; + entry->arg = NULL; + } + + goto out_unlock; + } + + for (i = 0; i < shared_entry->client_num; i++) { + client = &shared_entry->clients[i]; + + if (client->isr == routine && client->arg == parameter) { + /* note: this is the only match we're going to get */ + shared_irq_remove_client(shared_entry, i, table_idx); + goto out_unlock; + } + } + +out_unlock: + k_spin_unlock(&lock, key); + return 0; +} + #endif /* CONFIG_DYNAMIC_INTERRUPTS */ diff --git a/include/zephyr/irq.h b/include/zephyr/irq.h index d6229f69ea8..1a94a732bbc 100644 --- a/include/zephyr/irq.h +++ b/include/zephyr/irq.h @@ -70,6 +70,31 @@ irq_connect_dynamic(unsigned int irq, unsigned int priority, flags); } +/** + * Disconnect a dynamic interrupt. + * + * Use this in conjunction with shared interrupts to remove a routine/parameter + * pair from the list of clients using the same interrupt line. If the interrupt + * is not being shared then the associated _sw_isr_table entry will be replaced + * by (NULL, z_irq_spurious) (default entry). + * + * @param irq IRQ line number + * @param priority Interrupt priority + * @param routine Interrupt service routine + * @param parameter ISR parameter + * @param flags Arch-specific IRQ configuration flags + * + * @return 0 in case of success, negative value otherwise + */ +static inline int +irq_disconnect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) +{ + return arch_irq_disconnect_dynamic(irq, priority, routine, + parameter, flags); +} + /** * @brief Initialize a 'direct' interrupt handler. * diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index bd301e47592..9508e60e24c 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -107,6 +107,11 @@ unsigned int z_get_sw_isr_table_idx(unsigned int irq); #ifdef CONFIG_DYNAMIC_INTERRUPTS void z_isr_install(unsigned int irq, void (*routine)(const void *), const void *param); + +#ifdef CONFIG_SHARED_INTERRUPTS +int z_isr_uninstall(unsigned int irq, void (*routine)(const void *), + const void *param); +#endif /* CONFIG_SHARED_INTERRUPTS */ #endif #ifdef __cplusplus diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index 0cf8cfb24a4..0e6d43fdf25 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -323,6 +323,24 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, void (*routine)(const void *parameter), const void *parameter, uint32_t flags); +/** + * Arch-specific hook to dynamically uninstall a shared interrupt. + * If the interrupt is not being shared, then the associated + * _sw_isr_table entry will be replaced by (NULL, z_irq_spurious) + * (default entry). + * + * @param irq IRQ line number + * @param priority Interrupt priority + * @param routine Interrupt service routine + * @param parameter ISR parameter + * @param flags Arch-specific IRQ configuration flag + * + * @return 0 in case of success, negative value otherwise + */ +int arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags); + /** * @def ARCH_IRQ_CONNECT(irq, pri, isr, arg, flags) * From 127696383f5f7707bd95fca21ecf347b7fecfd40 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 11 Aug 2023 15:41:51 +0300 Subject: [PATCH 0396/4498] tests: kernel: interrupt: Add testcase for shared interrupts This commit introduces a new testcase for shared interrupts. Signed-off-by: Laurentiu Mihalcea --- tests/kernel/interrupt/CMakeLists.txt | 5 + .../kernel/interrupt/src/dynamic_shared_irq.c | 227 ++++++++++++++++++ .../kernel/interrupt/src/static_shared_irq.c | 96 ++++++++ tests/kernel/interrupt/src/test_shared_irq.h | 69 ++++++ tests/kernel/interrupt/testcase.yaml | 16 ++ 5 files changed, 413 insertions(+) create mode 100644 tests/kernel/interrupt/src/dynamic_shared_irq.c create mode 100644 tests/kernel/interrupt/src/static_shared_irq.c create mode 100644 tests/kernel/interrupt/src/test_shared_irq.h diff --git a/tests/kernel/interrupt/CMakeLists.txt b/tests/kernel/interrupt/CMakeLists.txt index 20851bb5ff4..80f3fbca665 100644 --- a/tests/kernel/interrupt/CMakeLists.txt +++ b/tests/kernel/interrupt/CMakeLists.txt @@ -17,3 +17,8 @@ target_sources(app PRIVATE target_sources_ifdef(CONFIG_DYNAMIC_INTERRUPTS app PRIVATE src/dynamic_isr.c) target_sources_ifdef(CONFIG_X86 app PRIVATE src/regular_isr.c) +target_sources_ifdef(CONFIG_SHARED_INTERRUPTS app PRIVATE src/static_shared_irq.c) + +if (CONFIG_SHARED_INTERRUPTS) +target_sources_ifdef(CONFIG_DYNAMIC_INTERRUPTS app PRIVATE src/dynamic_shared_irq.c) +endif() diff --git a/tests/kernel/interrupt/src/dynamic_shared_irq.c b/tests/kernel/interrupt/src/dynamic_shared_irq.c new file mode 100644 index 00000000000..db7bc1a688c --- /dev/null +++ b/tests/kernel/interrupt/src/dynamic_shared_irq.c @@ -0,0 +1,227 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "test_shared_irq.h" + +struct shared_irq_fixture { + unsigned int irq1; + unsigned int irq2; + unsigned int irq1_table_idx; + unsigned int irq2_table_idx; + unsigned int irq_priority; +}; + +static struct shared_irq_fixture fixture; + +static void reset_test_vector(void) +{ + int i; + + for (i = 0; i < TEST_VECTOR_SIZE; i++) { + test_vector[i] = 0; + } +} + +static void dynamic_shared_irq_suite_after(void *data) +{ + ARG_UNUSED(data); + + /* note: no need to check the state of the SW ISR tables after + * all these disconnect operations. If there's something wrong + * it should be detected by dynamic_shared_irq_suite_before(). + */ + arch_irq_disconnect_dynamic(fixture.irq1, fixture.irq_priority, + test_isr_0, 0, 0); + arch_irq_disconnect_dynamic(fixture.irq1, fixture.irq_priority, + test_isr_1, (void *)1, 0); + arch_irq_disconnect_dynamic(fixture.irq2, fixture.irq_priority, + test_isr_2, (void *)2, 0); +} + +static void dummy_isr(const void *data) +{ + ARG_UNUSED(data); + + test_vector[0] = TEST_DUMMY_ISR_VAL; +} + +static unsigned int get_irq_slot(unsigned int start) +{ + unsigned int i, table_idx; + + for (i = start; i <= CONFIG_GEN_IRQ_START_VECTOR + CONFIG_NUM_IRQS - 1; i++) { + table_idx = i - CONFIG_GEN_IRQ_START_VECTOR; + + if (_sw_isr_table[table_idx].isr == &z_irq_spurious) { + test_vector[0] = 0; + + /* check to see if we can trigger this IRQ */ + arch_irq_connect_dynamic(i, IRQ_PRIORITY, dummy_isr, + NULL, 0); + irq_enable(i); + trigger_irq(i); + + /* wait a bit */ + k_busy_wait(100); + + if (test_vector[0] == TEST_DUMMY_ISR_VAL) { + /* found a valid INTID */ + irq_disable(i); + + arch_irq_disconnect_dynamic(i, IRQ_PRIORITY, + dummy_isr, NULL, 0); + return i; + } + } + } + + return TEST_INVALID_IRQ; +} + +static void *dynamic_shared_irq_suite_setup(void) +{ + fixture.irq1 = get_irq_slot(CONFIG_GEN_IRQ_START_VECTOR); + zassert_true(fixture.irq1 != TEST_INVALID_IRQ, + "no suitable value found for irq1"); + fixture.irq2 = get_irq_slot(fixture.irq1 + 1); + zassert_true(fixture.irq2 != TEST_INVALID_IRQ, + "no suitable value found for irq2"); + fixture.irq_priority = IRQ_PRIORITY; + + fixture.irq1_table_idx = fixture.irq1 - CONFIG_GEN_IRQ_START_VECTOR; + fixture.irq2_table_idx = fixture.irq2 - CONFIG_GEN_IRQ_START_VECTOR; + + return NULL; +} + +static void dynamic_shared_irq_suite_before(void *data) +{ + ARG_UNUSED(data); + + arch_irq_connect_dynamic(fixture.irq1, fixture.irq_priority, + test_isr_0, 0, 0); + + zassert_true(_sw_isr_table[fixture.irq1_table_idx].isr == test_isr_0, + "wrong _sw_isr_table ISR at irq1"); + zassert_true(!_sw_isr_table[fixture.irq1_table_idx].arg, + "wrong _sw_isr_table argument at irq1"); + zassert_true(!z_shared_sw_isr_table[fixture.irq1_table_idx].client_num, + "wrong client number at irq1"); + + arch_irq_connect_dynamic(fixture.irq1, fixture.irq_priority, + test_isr_1, (void *)1, 0); + + zassert_true(_sw_isr_table[fixture.irq1_table_idx].isr == z_shared_isr, + "wrong _sw_isr_table ISR at irq1"); + zassert_true(_sw_isr_table[fixture.irq1_table_idx].arg == + &z_shared_sw_isr_table[fixture.irq1_table_idx], + "wrong _sw_isr_table argument at irq1"); + zassert_true(z_shared_sw_isr_table[fixture.irq1_table_idx].client_num == 2, + "wrong client number at irq1"); + + zassert_true(client_exists_at_index(test_isr_0, 0, fixture.irq1_table_idx, 0), + "unexpected client data for irq1, index 0"); + zassert_true(client_exists_at_index(test_isr_1, (void *)1, fixture.irq1_table_idx, 1), + "unexpected client data for irq1, index 1"); + + arch_irq_connect_dynamic(fixture.irq2, fixture.irq_priority, + test_isr_2, (void *)2, 0); + + zassert_true(_sw_isr_table[fixture.irq2_table_idx].isr == test_isr_2, + "wrong _sw_isr_table ISR at irq2"); + zassert_true(_sw_isr_table[fixture.irq2_table_idx].arg == (void *)2, + "wrong _sw_isr_table argument at irq2"); + zassert_true(!z_shared_sw_isr_table[fixture.irq2_table_idx].client_num, + "wrong client number at irq2"); + + reset_test_vector(); +} + +/** + * @brief Test writing to a vector with a shared interrupt + * + * @ingroup kernel_interrupt_tests + * + * @details This tests if interrupts are dynamically shared successfully + * (i.e: multiple ISR/arg pairs are called whenever the interrupt + * they were registered for is triggered). + */ +ZTEST(shared_irq_feature, test_dynamic_shared_irq_write) +{ + int i; + + irq_enable(fixture.irq1); + irq_enable(fixture.irq2); + + trigger_irq(fixture.irq1); + trigger_irq(fixture.irq2); + + /* wait 5ms before checking the results */ + k_busy_wait(5000); + + for (i = 0; i < TEST_VECTOR_SIZE; i++) { + zassert_true(test_vector[i] == result_vector[i], + "wrong test_vector value at %d: 0x%x vs 0x%x", + i, test_vector[i], result_vector[i]); + } + + irq_disable(fixture.irq1); + irq_disable(fixture.irq2); +} + +/** + * @brief Test writing to a vector after an ISR/arg disconnect. + * + * @ingroup kernel_interrupt_tests + * + * @details This tests if ISR/arg pairs are disconnected successfully + * and the interrupts are "unshared" whenever a single ISR/arg pair is + * left. + */ +ZTEST(shared_irq_feature, test_dynamic_shared_irq_disconnect_write) +{ + int i; + + /* remove test_isr_0/NULL pair. After this statement we expect + * irq1 to be unshared. + */ + arch_irq_disconnect_dynamic(fixture.irq1, fixture.irq_priority, + test_isr_0, 0, 0); + + zassert_true(_sw_isr_table[fixture.irq1_table_idx].isr == test_isr_1, + "wrong _sw_isr_table ISR at irq1"); + zassert_true(_sw_isr_table[fixture.irq1_table_idx].arg == (void *)1, + "wrong _sw_isr_table arg at irq1"); + zassert_true(!z_shared_sw_isr_table[fixture.irq1_table_idx].client_num, + "wrong client number at irq1"); + + irq_enable(fixture.irq1); + trigger_irq(fixture.irq1); + + /* wait 5ms before checking the results */ + k_busy_wait(5000); + + for (i = 0; i < TEST_VECTOR_SIZE; i++) { + if (i == 1) { + zassert_true(test_vector[i] == result_vector[i], + "wrong test_vector at %d: 0x%x vs 0x%x", + i, test_vector[i], result_vector[i]); + continue; + } + + zassert_true(!test_vector[i], + "wrong test_vector value at %d: 0x%x vs 0x%x", + i, test_vector[i], result_vector[i]); + } + + irq_disable(fixture.irq1); +} + +ZTEST_SUITE(shared_irq_feature, NULL, + dynamic_shared_irq_suite_setup, + dynamic_shared_irq_suite_before, + dynamic_shared_irq_suite_after, + NULL); diff --git a/tests/kernel/interrupt/src/static_shared_irq.c b/tests/kernel/interrupt/src/static_shared_irq.c new file mode 100644 index 00000000000..1a7daeb52f1 --- /dev/null +++ b/tests/kernel/interrupt/src/static_shared_irq.c @@ -0,0 +1,96 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "test_shared_irq.h" + +#define GIC_IRQ1 10 +#define GIC_IRQ2 11 + +/** + * @brief Test writing to a vector using static shared interrupts. + * + * @ingroup kernel_interrupt_tests + * + * @details This tests if interrupts are statically shared successfully + * (i.e: multiple ISR/arg pairs are called whenever the interrupt they + * were registered for is triggered). + */ +ZTEST(interrupt_feature, test_static_shared_irq_write) +{ + /* note: this test is very brittle since it requires that + * the chosen interrupt lines be unused for all of the + * testing platforms. Failing to meet this requirement + * leads to build failures due to the number of clients + * exceeding the limit. Still, it's important to test that + * the static shared interrupts work properly. As such, + * this test shall be restricted to a single platform, thus + * decreasing the risk of build errors appearing due to the + * chosen interrupts being used. + */ +#ifndef CONFIG_BOARD_QEMU_CORTEX_A53 + ztest_test_skip(); +#else + int i; + + IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0); + IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0); + IRQ_CONNECT(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0); + + zassert_true(_sw_isr_table[GIC_IRQ1].isr == z_shared_isr, + "wrong _sw_isr_table ISR at GIC_IRQ1"); + zassert_true(_sw_isr_table[GIC_IRQ2].isr == test_isr_2, + "wrong _sw_isr_table ISR at GIC_IRQ1"); + + zassert_true(_sw_isr_table[GIC_IRQ1].arg == + &z_shared_sw_isr_table[GIC_IRQ1], + "wrong _sw_isr_table arg at GIC_IRQ1"); + zassert_true(_sw_isr_table[GIC_IRQ2].arg == (void *)2, + "wrong _sw_isr_table arg at GIC_IRQ2"); + + zassert_true(z_shared_sw_isr_table[GIC_IRQ1].client_num == 2, + "wrong client number for GIC_IRQ1"); + zassert_true(!z_shared_sw_isr_table[GIC_IRQ2].client_num, + "wrong client number for GIC_IRQ2"); + + zassert_true(client_exists_at_index(test_isr_0, 0, GIC_IRQ1, + TEST_INVALID_IDX), + "test_isr_0 not a client for GIC_IRQ1"); + zassert_true(client_exists_at_index(test_isr_1, (void *)1, GIC_IRQ1, + TEST_INVALID_IDX), + "test_isr_1 not a client for GIC_IRQ1"); + + irq_enable(GIC_IRQ1); + irq_enable(GIC_IRQ2); + + trigger_irq(GIC_IRQ1); + trigger_irq(GIC_IRQ2); + + /* wait 5ms before checking the results */ + k_busy_wait(5000); + + for (i = 0; i < TEST_VECTOR_SIZE; i++) { + zassert_true(test_vector[i] == result_vector[i], + "wrong test_vector value at %d: 0x%x vs 0x%x", + i, test_vector[i], result_vector[i]); + } + + irq_disable(GIC_IRQ1); + irq_disable(GIC_IRQ2); + +#ifdef CONFIG_DYNAMIC_INTERRUPTS + /* if dynamic interrupts are enabled this will restore the _sw_isr_table + * entries for GIC_IRQ1 and GIC_IRQ2 to their default values (NULL, + * z_irq_spurious). In turn, this will increase the probability of + * dynamic_shared_irq.c's get_irq_slot() being able to find an available + * slot. + */ + arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0); + arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0); + arch_irq_disconnect_dynamic(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0); +#endif /* CONFIG_DYNAMIC_INTERRUPTS */ + +#endif /* CONFIG_BOARD_QEMU_CORTEX_A53 */ +} diff --git a/tests/kernel/interrupt/src/test_shared_irq.h b/tests/kernel/interrupt/src/test_shared_irq.h new file mode 100644 index 00000000000..fd3c4c4a624 --- /dev/null +++ b/tests/kernel/interrupt/src/test_shared_irq.h @@ -0,0 +1,69 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TEST_SHARED_IRQ_H__ +#define __TEST_SHARED_IRQ_H__ + +#include +#include + +#define IRQ_PRIORITY 1 +#define TEST_VECTOR_SIZE 10 +#define TEST_INVALID_IDX 0xcafebabe +#define TEST_DUMMY_ISR_VAL 0xdeadbeef +#define TEST_INVALID_IRQ 0xcafebabe + +#define ISR_DEFINE(name) \ +static inline void name(const void *data) \ +{ \ + int idx = POINTER_TO_INT(data); \ + test_vector[idx] = result_vector[idx]; \ +} \ + +static uint32_t test_vector[TEST_VECTOR_SIZE] = { +}; + +static uint32_t result_vector[TEST_VECTOR_SIZE] = { + 0xdeadbeef, + 0xcafebabe, + 0x1234cafe, +}; + +ISR_DEFINE(test_isr_0); +ISR_DEFINE(test_isr_1); +ISR_DEFINE(test_isr_2); + +static inline bool client_exists_at_index(void (*routine)(const void *arg), + void *arg, int irq, size_t idx) +{ + size_t i; + struct z_shared_isr_table_entry *shared_entry; + struct z_shared_isr_client *client; + + shared_entry = &z_shared_sw_isr_table[irq]; + + if (idx == TEST_INVALID_IDX) { + for (i = 0; i < shared_entry->client_num; i++) { + client = &shared_entry->clients[i]; + + if (client->isr == routine && client->arg == arg) { + return true; + } + } + } else { + if (shared_entry->client_num <= idx) { + return false; + } + + client = &shared_entry->clients[idx]; + + return client->isr == routine && client->arg == arg; + } + + return false; +} + +#endif /* __TEST_SHARED_IRQ_H__ */ diff --git a/tests/kernel/interrupt/testcase.yaml b/tests/kernel/interrupt/testcase.yaml index bdec3a794ee..cbe58c65e47 100644 --- a/tests/kernel/interrupt/testcase.yaml +++ b/tests/kernel/interrupt/testcase.yaml @@ -36,3 +36,19 @@ tests: extra_configs: - CONFIG_QEMU_ICOUNT=y - CONFIG_MINIMAL_LIBC=y + arch.shared_interrupt: + # excluded because of failures during test_prevent_interruption + platform_exclude: qemu_cortex_m0 + arch_exclude: + # same as above, #22956 + - nios2 + # test needs 2 working interrupt lines + - xtensa + # TODO: make test work on this arch + - mips + tags: + - kernel + - interrupt + extra_configs: + - CONFIG_SHARED_INTERRUPTS=y + filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE From b1111d9de46d1acda859862e6bb8661686ca3c26 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Mon, 11 Sep 2023 17:42:15 +0300 Subject: [PATCH 0397/4498] doc: interrupts: Document support for shared interrupts This commit adds the documentation for shared interrupts. Signed-off-by: Laurentiu Mihalcea --- doc/kernel/services/interrupts.rst | 150 +++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/doc/kernel/services/interrupts.rst b/doc/kernel/services/interrupts.rst index 1496dc7fa7a..b940540e600 100644 --- a/doc/kernel/services/interrupts.rst +++ b/doc/kernel/services/interrupts.rst @@ -215,6 +215,38 @@ priority of the thread handling the offload, it is possible that the currently executing cooperative thread or other higher-priority threads may execute before the thread handling the offload is scheduled. +Sharing interrupt lines +======================= + +In the case of some hardware platforms, the same interrupt lines may be used +by different IPs. For example, interrupt 17 may be used by a DMA controller to +signal that a data transfer has been completed or by a DAI controller to signal +that the transfer FIFO has reached its watermark. To make this work, one would +have to either employ some special logic or find a workaround (for example, using +the shared_irq interrupt controller), which doesn't scale very well. + +To solve this problem, one may use shared interrupts, which can be enabled using +:kconfig:option:`CONFIG_SHARED_INTERRUPTS`. Whenever an attempt to register +a second ISR/argument pair on the same interrupt line is made (using +:c:macro:`IRQ_CONNECT` or :c:func:`irq_connect_dynamic`), the interrupt line will +become shared, meaning the two ISR/argument pairs (previous one and the one that +has just been registered) will be invoked each time the interrupt is triggered. +The entities that make use of an interrupt line in the shared interrupt context +are known as clients. The maximum number of allowed clients for an interrupt is +controlled by :kconfig:option:`SHARED_IRQ_MAX_NUM_CLIENTS`. + +Interrupt sharing is transparent to the user. As such, the user may register +interrupts using :c:macro:`IRQ_CONNECT` and :c:func:`irq_connect_dynamic` as +they normally would. The interrupt sharing is taken care of behind the scenes. + +Enabling the shared interrupt support and dynamic interrupt support will +allow users to dynamically disconnect ISRs using :c:func:`irq_disconnect_dynamic`. +After an ISR is disconnected, whenever the interrupt line for which it was +register gets triggered, the ISR will no longer get invoked. + +Please note that enabling :kconfig:option:`CONFIG_SHARED_INTERRUPTS` will +result in a non-negligible increase in the binary size. Use with caution. + Implementation ************** @@ -326,6 +358,98 @@ architecture-specific basis. (The feature is currently implemented in ARM Cortex-M architecture variant. Dynamic direct interrupts feature is exposed to the user via an ARM-only API.) +Sharing an interrupt line +========================= + +The following code defines two ISRs using the same interrupt number. + +.. code-block:: c + + #define MY_DEV_IRQ 24 /* device uses INTID 24 */ + #define MY_DEV_IRQ_PRIO 2 /* device uses interrupt priority 2 */ + /* this argument may be anything */ + #define MY_FST_ISR_ARG INT_TO_POINTER(1) + /* this argument may be anything */ + #define MY_SND_ISR_ARG INT_TO_POINTER(2) + #define MY_IRQ_FLAGS 0 /* IRQ flags */ + + void my_first_isr(void *arg) + { + ... /* some magic happens here */ + } + + void my_second_isr(void *arg) + { + ... /* even more magic happens here */ + } + + void my_isr_installer(void) + { + ... + IRQ_CONNECT(MY_DEV_IRQ, MY_DEV_IRQ_PRIO, my_first_isr, MY_FST_ISR_ARG, MY_IRQ_FLAGS); + IRQ_CONNECT(MY_DEV_IRQ, MY_DEV_IRQ_PRIO, my_second_isr, MY_SND_ISR_ARG, MY_IRQ_FLAGS); + ... + } + +The same restrictions regarding :c:macro:`IRQ_CONNECT` described in `Defining a regular ISR`_ +are applicable here. If :kconfig:option:`CONFIG_SHARED_INTERRUPTS` is disabled, the above +code will generate a build error. Otherwise, the above code will result in the two ISRs +being invoked each time interrupt 24 is triggered. + +If :kconfig:option:`CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS` is set to a value lower than 2 +(current number of clients), a build error will be generated. + +If dynamic interrupts are enabled, c:func:`irq_connect_dynamic` will allow sharing interrupts +during runtime. Exceeding the configured maximum number of allowed clients will result in +a failed assertion. + +Dynamically disconnecting an ISR +================================ + +The following code defines two ISRs using the same interrupt number. The second +ISR is disconnected during runtime. + +.. code-block:: c + + #define MY_DEV_IRQ 24 /* device uses INTID 24 */ + #define MY_DEV_IRQ_PRIO 2 /* device uses interrupt priority 2 */ + /* this argument may be anything */ + #define MY_FST_ISR_ARG INT_TO_POINTER(1) + /* this argument may be anything */ + #define MY_SND_ISR_ARG INT_TO_POINTER(2) + #define MY_IRQ_FLAGS 0 /* IRQ flags */ + + void my_first_isr(void *arg) + { + ... /* some magic happens here */ + } + + void my_second_isr(void *arg) + { + ... /* even more magic happens here */ + } + + void my_isr_installer(void) + { + ... + IRQ_CONNECT(MY_DEV_IRQ, MY_DEV_IRQ_PRIO, my_first_isr, MY_FST_ISR_ARG, MY_IRQ_FLAGS); + IRQ_CONNECT(MY_DEV_IRQ, MY_DEV_IRQ_PRIO, my_second_isr, MY_SND_ISR_ARG, MY_IRQ_FLAGS); + ... + } + + void my_isr_uninstaller(void) + { + ... + irq_disconnect_dynamic(MY_DEV_IRQ, MY_DEV_IRQ_PRIO, my_first_isr, MY_FST_ISR_ARG, MY_IRQ_FLAGS); + ... + } + +The :c:func:`irq_disconnect_dynamic` call will result in interrupt 24 becoming +unshared, meaning the system will act as if the first :c:macro:`IRQ_CONNECT` +call never happened. This behaviour is only allowed if +:kconfig:option:`CONFIG_DYNAMIC_INTERRUPTS` is enabled, otherwise a linker +error will be generated. + Implementation Details ====================== @@ -417,6 +541,32 @@ This is used by the common software IRQ handler to look up the ISR and its argument and execute it. The active IRQ line is looked up in an interrupt controller register and used to index this table. +Shared SW ISR Table +------------------- + +This is an array of struct z_shared_isr_table_entry: + +.. code-block:: c + + struct z_shared_isr_table_entry { + struct z_shared_isr_client clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS]; + size_t client_num; + }; + +This table keeps track of the registered clients for each of the interrupt +lines. Whenever an interrupt line becomes shared, c:func:`z_shared_isr` will +replace the currently registered ISR in _sw_isr_table. This special ISR will +iterate through the list of registered clients and invoke the ISRs. + +The definition for struct z_shared_isr_client is as follows: + +.. code-block:: c + + struct z_shared_isr_client { + void (*isr)(const void *arg); + const void *arg; + }; + x86 Details ----------- From ff1bb65793574c3d08e8c0b2fb9d17fecb44411a Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Mon, 11 Sep 2023 17:45:36 +0300 Subject: [PATCH 0398/4498] doc: release: 3.5: Add note about shared interrupt support Add a note that shared interrupts are now supported. Signed-off-by: Laurentiu Mihalcea --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9b6af902848..7b090e2c0fd 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -120,6 +120,10 @@ Build system and infrastructure be used to include a snippet when a test is ran (and exclude any boards from running that the snippet cannot be applied to). +* Interrupts + + * Added support for shared interrupts + Drivers and Sensors ******************* From 3fb434a6530897772e40922e780446b2f6ed4a24 Mon Sep 17 00:00:00 2001 From: Hang Fan Date: Sat, 2 Sep 2023 17:00:58 +0800 Subject: [PATCH 0399/4498] Bluetooth: Shell: Fix bt adv-data command Fix wrong adv elements length for bt adv-data command Signed-off-by: Hang Fan --- subsys/bluetooth/shell/bt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index d1d1238baf6..37e817a3aa7 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -67,6 +67,8 @@ static struct bt_conn_auth_info_cb auth_info_cb; #define ADV_DATA_DELIMITER ", " +#define AD_SIZE 9 + /* * Based on the maximum number of parameters for HCI_LE_Generate_DHKey * See BT Core Spec V5.2 Vol. 4, Part E, section 7.8.37 @@ -1902,11 +1904,12 @@ static int cmd_adv_data(const struct shell *sh, size_t argc, char *argv[]) static uint8_t hex_data[1650]; bool appearance = false; struct bt_data *data; - struct bt_data ad[9]; - struct bt_data sd[9]; + struct bt_data ad[AD_SIZE]; + struct bt_data sd[AD_SIZE]; size_t hex_data_len; size_t ad_len = 0; size_t sd_len = 0; + size_t len = 0; bool discoverable = false; size_t *data_len; int err; @@ -1947,8 +1950,6 @@ static int cmd_adv_data(const struct shell *sh, size_t argc, char *argv[]) data = sd; data_len = &sd_len; } else { - size_t len; - len = hex2bin(arg, strlen(arg), &hex_data[hex_data_len], sizeof(hex_data) - hex_data_len); @@ -1970,15 +1971,18 @@ static int cmd_adv_data(const struct shell *sh, size_t argc, char *argv[]) atomic_set_bit_to(adv_set_opt[selected_adv], SHELL_ADV_OPT_APPEARANCE, appearance); - ad_len = ad_init(&ad[*data_len], ARRAY_SIZE(ad) - *data_len, - adv_set_opt[selected_adv]); - if (ad_len < 0) { + len = ad_init(&data[*data_len], AD_SIZE - *data_len, adv_set_opt[selected_adv]); + if (len < 0) { shell_error(sh, "Failed to initialize stack advertising data"); return -ENOEXEC; } - ad_len += *data_len; + if (data == ad) { + ad_len += len; + } else { + sd_len += len; + } err = bt_le_ext_adv_set_data(adv, ad_len > 0 ? ad : NULL, ad_len, sd_len > 0 ? sd : NULL, sd_len); From 7b8b5620fade0c43131a9ad6166b75ea9f3a286e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 14 Sep 2023 07:44:19 +0000 Subject: [PATCH 0400/4498] board: az3166_iotdevkit: update SSD1306_REVERSE_MODE option The SSD1306_REVERSE_MODE is now a devicetree property. Update the board config, fix a: warning: SSD1306_REVERSE_MODE (defined at boards/arm/az3166_iotdevkit/Kconfig.defconfig:15) defined without a type compliance warning. Signed-off-by: Fabio Baltieri --- boards/arm/az3166_iotdevkit/Kconfig.defconfig | 3 --- boards/arm/az3166_iotdevkit/az3166_iotdevkit.dts | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/boards/arm/az3166_iotdevkit/Kconfig.defconfig b/boards/arm/az3166_iotdevkit/Kconfig.defconfig index d7858ac5d9b..af040b8a58d 100644 --- a/boards/arm/az3166_iotdevkit/Kconfig.defconfig +++ b/boards/arm/az3166_iotdevkit/Kconfig.defconfig @@ -12,7 +12,4 @@ choice HTS221_TRIGGER_MODE default HTS221_TRIGGER_NONE endchoice -config SSD1306_REVERSE_MODE - default y - endif # BOARD_AZ3166_DEVKIT diff --git a/boards/arm/az3166_iotdevkit/az3166_iotdevkit.dts b/boards/arm/az3166_iotdevkit/az3166_iotdevkit.dts index 1f1e8f2c7b6..13b641719ee 100644 --- a/boards/arm/az3166_iotdevkit/az3166_iotdevkit.dts +++ b/boards/arm/az3166_iotdevkit/az3166_iotdevkit.dts @@ -172,6 +172,7 @@ segment-remap; com-invdir; prechargep = <0x22>; + inversion-on; reset-gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>; }; From a6540164d44d1f7d2715280cf1dc0bc40a6c423f Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 14 Sep 2023 00:49:52 +0000 Subject: [PATCH 0401/4498] util.h: #include zephyr/toolchain.h, not zephyr/toolchain/common.h Commit 9c5dafed95ee ("util: add type checking to CONTAINER_OF") made `util.h` #include `toolchain/common.h` in order to get `BUILD_ASSERT()` used by CONTAINER_OF_VALIDATE() when compiling C code. However `toolchain/common.h` is not supposed to be included directly but indirectly through `toolchain/.h` and in a very specific order. The direct inclusion caused the following warning when compiling C++: ``` toolchain/gcc.h:87: error: "ZRESTRICT" redefined [-Werror] 87 | #define ZRESTRICT __restrict | In file included from include/zephyr/sys/util.h:18: note: this is the location of the previous definition: include/zephyr/toolchain/common.h:33: 33 | #define ZRESTRICT ``` Fix this issue #62464 by including `zephyr/toolchain.h` instead, as done by 350 other files. Fixes commit 9c5dafed95ee ("util: add type checking to CONTAINER_OF") Signed-off-by: Marc Herbert --- include/zephyr/sys/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index db5d85eeb41..29488e23b91 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -15,7 +15,7 @@ #define ZEPHYR_INCLUDE_SYS_UTIL_H_ #include -#include +#include /* needs to be outside _ASMLANGUAGE so 'true' and 'false' can turn * into '1' and '0' for asm or linker scripts From f6185221440b7fe9f0c1b17702c8231105edc06b Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 8 Sep 2023 17:50:24 +0200 Subject: [PATCH 0402/4498] twister: pytest: Move fixtures to one file Fixtures in pytest-twister-harness plugin are moved to one file to simplify adding new fixtures in the future - no need to add pytest_plugins entry and register asserts. Moved also shell fixture from sample dir, because that fixture can be reused in new tests. Signed-off-by: Grzegorz Chwierut --- .../pytest/shell/pytest/test_shell.py | 12 +--------- .../src/twister_harness/__init__.py | 2 +- .../{fixtures/dut.py => fixtures.py} | 22 +++++++++++++++++++ .../src/twister_harness/fixtures/__init__.py | 8 ------- .../{fixtures => helpers}/mcumgr.py | 16 -------------- .../src/twister_harness/plugin.py | 3 +-- .../tests/fixtures/mcumgr_fixture_test.py | 4 ++-- 7 files changed, 27 insertions(+), 40 deletions(-) rename scripts/pylib/pytest-twister-harness/src/twister_harness/{fixtures/dut.py => fixtures.py} (72%) delete mode 100644 scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py rename scripts/pylib/pytest-twister-harness/src/twister_harness/{fixtures => helpers}/mcumgr.py (88%) diff --git a/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py b/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py index 37efa74795b..84d16ec1e5a 100755 --- a/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py +++ b/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py @@ -4,21 +4,11 @@ import logging -import pytest -from twister_harness import DeviceAdapter, Shell +from twister_harness import Shell logger = logging.getLogger(__name__) -@pytest.fixture(scope='function') -def shell(dut: DeviceAdapter) -> Shell: - """Return ready to use shell interface""" - shell = Shell(dut, timeout=20.0) - logger.info('wait for prompt') - assert shell.wait_for_prompt() - return shell - - def test_shell_print_help(shell: Shell): logger.info('send "help" command') lines = shell.exec_command('help') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py index 251c5deb672..4897e2cf391 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py @@ -5,7 +5,7 @@ # flake8: noqa from twister_harness.device.device_adapter import DeviceAdapter -from twister_harness.fixtures.mcumgr import MCUmgr +from twister_harness.helpers.mcumgr import MCUmgr from twister_harness.helpers.shell import Shell __all__ = ['DeviceAdapter', 'MCUmgr', 'Shell'] diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py similarity index 72% rename from scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py rename to scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py index 0f34c05b252..e2e82674ada 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py @@ -10,6 +10,8 @@ from twister_harness.device.device_adapter import DeviceAdapter from twister_harness.device.factory import DeviceFactory from twister_harness.twister_harness_config import DeviceConfig, TwisterHarnessConfig +from twister_harness.helpers.shell import Shell +from twister_harness.helpers.mcumgr import MCUmgr logger = logging.getLogger(__name__) @@ -44,3 +46,23 @@ def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generat yield device_object finally: # to make sure we close all running processes execution device_object.close() + + +@pytest.fixture(scope='function') +def shell(dut: DeviceAdapter) -> Shell: + """Return ready to use shell interface""" + shell = Shell(dut, timeout=20.0) + logger.info('Wait for prompt') + assert shell.wait_for_prompt() + return shell + + +@pytest.fixture(scope='session') +def is_mcumgr_available() -> None: + if not MCUmgr.is_available(): + pytest.skip('mcumgr not available') + + +@pytest.fixture() +def mcumgr(is_mcumgr_available: None, dut: DeviceAdapter) -> Generator[MCUmgr, None, None]: + yield MCUmgr.create_for_serial(dut.device_config.serial) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py deleted file mode 100644 index ed61bf17b1c..00000000000 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -import pytest - -pytest.register_assert_rewrite('twister_harness.fixtures.dut') -pytest.register_assert_rewrite('twister_harness.fixtures.mcumgr') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py similarity index 88% rename from scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py rename to scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py index e0d85893792..b6cab6475c1 100755 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py @@ -3,19 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations -import pytest import logging import re import shlex -from typing import Generator from subprocess import check_output, getstatusoutput from pathlib import Path from dataclasses import dataclass -from twister_harness.device.device_adapter import DeviceAdapter - - logger = logging.getLogger(__name__) @@ -108,14 +103,3 @@ def image_confirm(self, hash: str | None = None): image_list = self.get_image_list() hash = image_list[0].hash self.run_command(f'image confirm {hash}') - - -@pytest.fixture(scope='session') -def is_mcumgr_available() -> None: - if not MCUmgr.is_available(): - pytest.skip('mcumgr not available') - - -@pytest.fixture() -def mcumgr(is_mcumgr_available: None, dut: DeviceAdapter) -> Generator[MCUmgr, None, None]: - yield MCUmgr.create_for_serial(dut.device_config.serial) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index 59bec12955d..076d36d4cc9 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -14,8 +14,7 @@ logger = logging.getLogger(__name__) pytest_plugins = ( - 'twister_harness.fixtures.dut', - 'twister_harness.fixtures.mcumgr' + 'twister_harness.fixtures' ) diff --git a/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py b/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py index f294adba30a..f336311143a 100644 --- a/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py @@ -6,7 +6,7 @@ import textwrap from unittest import mock -from twister_harness.fixtures.mcumgr import MCUmgr, MCUmgrException +from twister_harness.helpers.mcumgr import MCUmgr, MCUmgrException @pytest.fixture(name='mcumgr') @@ -14,7 +14,7 @@ def fixture_mcumgr() -> MCUmgr: return MCUmgr.create_for_serial('SERIAL_PORT') -@mock.patch('twister_harness.fixtures.mcumgr.MCUmgr.run_command', return_value='') +@mock.patch('twister_harness.helpers.mcumgr.MCUmgr.run_command', return_value='') def test_if_mcumgr_fixture_generate_proper_command( patched_run_command: mock.Mock, mcumgr: MCUmgr ) -> None: From 94cc1bf4551a933200f1f65777a19869264bc5bf Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 13 Sep 2023 08:44:56 -0700 Subject: [PATCH 0403/4498] ipm: remove ipm_cavs_idc driver The ipm_cavs_idc driver was used with the old intel_s1000 board which has been removed. On the audio DSP side, the IDC under CAVS is being handled by SoC layer code. Now the ipm_cavs_idc is not needed anymore for anything. So remove it. Signed-off-by: Daniel Leung --- drivers/ipm/CMakeLists.txt | 1 - drivers/ipm/Kconfig.intel_adsp | 8 - drivers/ipm/ipm_cavs_idc.c | 242 ------------------------- drivers/ipm/ipm_cavs_idc.h | 68 ------- tests/boards/intel_adsp/smoke/prj.conf | 1 - 5 files changed, 320 deletions(-) delete mode 100644 drivers/ipm/ipm_cavs_idc.c delete mode 100644 drivers/ipm/ipm_cavs_idc.h diff --git a/drivers/ipm/CMakeLists.txt b/drivers/ipm/CMakeLists.txt index dbc8affc7c2..a6c41f845e4 100644 --- a/drivers/ipm/CMakeLists.txt +++ b/drivers/ipm/CMakeLists.txt @@ -10,7 +10,6 @@ zephyr_library_sources_ifdef(CONFIG_IPM_IMX_REV2 ipm_imx.c) zephyr_library_sources_ifdef(CONFIG_IPM_MHU ipm_mhu.c) zephyr_library_sources_ifdef(CONFIG_IPM_STM32_IPCC ipm_stm32_ipcc.c) zephyr_library_sources_ifdef(CONFIG_IPM_NRFX ipm_nrfx_ipc.c) -zephyr_library_sources_ifdef(CONFIG_IPM_CAVS_IDC ipm_cavs_idc.c) zephyr_library_sources_ifdef(CONFIG_IPM_STM32_HSEM ipm_stm32_hsem.c) zephyr_library_sources_ifdef(CONFIG_IPM_CAVS_HOST ipm_cavs_host.c) zephyr_library_sources_ifdef(CONFIG_IPM_SEDI ipm_sedi.c) diff --git a/drivers/ipm/Kconfig.intel_adsp b/drivers/ipm/Kconfig.intel_adsp index 9a8880fc0e4..dbf6cdf91f2 100644 --- a/drivers/ipm/Kconfig.intel_adsp +++ b/drivers/ipm/Kconfig.intel_adsp @@ -1,14 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2022, Intel Corporation -config IPM_CAVS_IDC - bool "CAVS DSP Intra-DSP Communication (IDC) driver" - default y if MP_NUM_CPUS > 1 && SMP - depends on CAVS_ICTL && DT_HAS_INTEL_ADSP_IDC_ENABLED - help - Driver for the Intra-DSP Communication (IDC) channel for - cross SoC communications. - config IPM_CALLBACK_ASYNC bool "Deliver callbacks asynchronously" default y if IPM_CAVS_HOST diff --git a/drivers/ipm/ipm_cavs_idc.c b/drivers/ipm/ipm_cavs_idc.c deleted file mode 100644 index 5793d2e4b70..00000000000 --- a/drivers/ipm/ipm_cavs_idc.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include - -#include -#include -#include "ipm_cavs_idc.h" - -#ifdef CONFIG_SCHED_IPI_SUPPORTED -extern void z_sched_ipi(void); -#endif - -struct cavs_idc_data { - ipm_callback_t cb; - void *user_data; -}; - -static struct cavs_idc_data cavs_idc_device_data; - -static void cavs_idc_isr(const struct device *dev) -{ - struct cavs_idc_data *drv_data = dev->data; - - uint32_t i, id; - void *ext; - uint32_t idctfc; - uint32_t curr_cpu_id = arch_curr_cpu()->id; -#ifdef CONFIG_SCHED_IPI_SUPPORTED - bool do_sched_ipi = false; -#endif - - unsigned int num_cpus = arch_num_cpus(); - - for (i = 0; i < num_cpus; i++) { - if (i == curr_cpu_id) { - /* skip current core */ - continue; - } - - idctfc = idc_read(IPC_IDCTFC(i), curr_cpu_id); - - if ((idctfc & IPC_IDCTFC_BUSY) == 0) { - /* No message from this core */ - continue; - } - - /* Extract the message */ - id = idctfc & IPC_IDCTFC_MSG_MASK; - - switch (id) { -#ifdef CONFIG_SCHED_IPI_SUPPORTED - case IPM_CAVS_IDC_MSG_SCHED_IPI_ID: - do_sched_ipi = true; - break; -#endif - default: - if (drv_data->cb != NULL) { - ext = UINT_TO_POINTER( - idc_read(IPC_IDCTEFC(i), curr_cpu_id) & - IPC_IDCTEFC_MSG_MASK); - drv_data->cb(dev, drv_data->user_data, id, ext); - } - break; - } - - /* Reset busy bit by writing to it */ - idctfc |= IPC_IDCTFC_BUSY; - idc_write(IPC_IDCTFC(i), curr_cpu_id, idctfc); - } -#ifdef CONFIG_SCHED_IPI_SUPPORTED - if (do_sched_ipi) { - z_sched_ipi(); - } -#endif -} - -static int cavs_idc_send(const struct device *dev, int wait, uint32_t id, - const void *data, int size) -{ - uint32_t curr_cpu_id = arch_curr_cpu()->id; - uint32_t ext = POINTER_TO_UINT(data); - uint32_t reg; - bool busy; - int i; - - if ((wait != 0) || (size != 0)) { - return -ENOTSUP; - } - - /* Check if any core is still busy */ - busy = false; - unsigned int num_cpus = arch_num_cpus(); - - for (i = 0; i < num_cpus; i++) { - if (i == curr_cpu_id) { - /* skip current core */ - continue; - } - - reg = idc_read(IPC_IDCITC(i), curr_cpu_id); - if ((reg & IPC_IDCITC_BUSY) != 0) { - busy = true; - break; - } - } - - /* Can't send if busy */ - if (busy) { - return -EBUSY; - } - - id &= IPC_IDCITC_MSG_MASK; - ext &= IPC_IDCIETC_MSG_MASK; - ext |= IPC_IDCIETC_DONE; /* always clear DONE bit */ - - for (i = 0; i < num_cpus; i++) { - if (i == curr_cpu_id) { - /* skip current core */ - continue; - } - - idc_write(IPC_IDCIETC(i), curr_cpu_id, ext); - idc_write(IPC_IDCITC(i), curr_cpu_id, id | IPC_IDCITC_BUSY); - } - - return 0; -} - -static int cavs_idc_max_data_size_get(const struct device *dev) -{ - ARG_UNUSED(dev); - - /* IDC can send an ID (of 31 bits, the header) and - * another data of 30 bits (the extension). It cannot - * send a whole message over. Best we can do is send - * a 4-byte aligned pointer. - * - * So return 0 here for max data size. - */ - - return 0; -} - -static uint32_t cavs_idc_max_id_val_get(const struct device *dev) -{ - ARG_UNUSED(dev); - - return IPM_CAVS_IDC_ID_MASK; -} - -static void cavs_idc_register_callback(const struct device *dev, - ipm_callback_t cb, - void *user_data) -{ - struct cavs_idc_data *drv_data = dev->data; - - drv_data->cb = cb; - drv_data->user_data = user_data; -} - -static int cavs_idc_set_enabled(const struct device *dev, int enable) -{ - int i, j; - uint32_t mask; - -#ifdef CONFIG_SCHED_IPI_SUPPORTED - /* With scheduler IPI, IDC must always be enabled. */ - if (enable == 0) { - return -ENOTSUP; - } -#endif - - unsigned int num_cpus = arch_num_cpus(); - - for (i = 0; i < num_cpus; i++) { - mask = 0; - - if (enable) { - for (j = 0; j < num_cpus; j++) { - if (i == j) { - continue; - } - - mask |= IPC_IDCCTL_IDCTBIE(j); - } - } - - idc_write(IPC_IDCCTL, i, mask); - - /* FIXME: when we have API to enable IRQ on specific core. */ - sys_set_bit(DT_REG_ADDR(DT_NODELABEL(cavs_intc0)) + 0x04 + - CAVS_ICTL_INT_CPU_OFFSET(i), - CAVS_IRQ_NUMBER(DT_INST_IRQN(0))); - } - - return 0; -} - -static int cavs_idc_init(const struct device *dev) -{ - IRQ_CONNECT(DT_INST_IRQN(0), - DT_INST_IRQ(0, priority), - cavs_idc_isr, DEVICE_DT_INST_GET(0), 0); - - irq_enable(DT_INST_IRQN(0)); - - return 0; -} - -static const struct ipm_driver_api cavs_idc_driver_api = { - .send = cavs_idc_send, - .register_callback = cavs_idc_register_callback, - .max_data_size_get = cavs_idc_max_data_size_get, - .max_id_val_get = cavs_idc_max_id_val_get, - .set_enabled = cavs_idc_set_enabled, -}; - -DEVICE_DT_INST_DEFINE(0, &cavs_idc_init, NULL, - &cavs_idc_device_data, NULL, - PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &cavs_idc_driver_api); - -#ifdef CONFIG_SCHED_IPI_SUPPORTED -int cavs_idc_smp_init(void) -{ - /* Enable IDC for scheduler IPI */ - cavs_idc_set_enabled(dev, 1); - - return 0; -} - -#ifndef CONFIG_SMP_BOOT_DELAY -SYS_INIT(cavs_idc_smp_init, SMP, 0); -#endif -#endif diff --git a/drivers/ipm/ipm_cavs_idc.h b/drivers/ipm/ipm_cavs_idc.h deleted file mode 100644 index e9ce493d880..00000000000 --- a/drivers/ipm/ipm_cavs_idc.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_IPM_IPM_CAVS_IDC_H_ -#define ZEPHYR_DRIVERS_IPM_IPM_CAVS_IDC_H_ - -#define DT_DRV_COMPAT intel_adsp_idc -#include - -/* Redeclaration of the earlier IDC register API for platforms being - * held back on this driver. - */ -# ifndef IPC_DSP_BASE -# define IPC_DSP_BASE(core) (INTEL_ADSP_IDC_REG_ADDRESS + 0x80 * (core)) -# endif -#define IPC_IDCTFC(x) (x * 0x10) -#define IPC_IDCTFC_BUSY BIT(31) -#define IPC_IDCTFC_MSG_MASK 0x7FFFFFFF -#define IPC_IDCTEFC(x) (0x4 + x * 0x10) -#define IPC_IDCTEFC_MSG_MASK 0x3FFFFFFF -#define IPC_IDCITC(x) (0x8 + x * 0x10) -#define IPC_IDCITC_MSG_MASK 0x7FFFFFFF -#define IPC_IDCITC_BUSY BIT(31) -#define IPC_IDCIETC(x) (0xc + x * 0x10) -#define IPC_IDCIETC_MSG_MASK 0x3FFFFFFF -#define IPC_IDCIETC_DONE BIT(30) -#define IPC_IDCCTL 0x50 -#define IPC_IDCCTL_IDCTBIE(x) BIT(x) - -#define IPM_CAVS_IDC_ID_MASK \ - (CAVS_IDC_TYPE(CAVS_IDC_TYPE_MASK) | \ - CAVS_IDC_HEADER(CAVS_IDC_HEADER_MASK)) - -/* IDC message type. */ -#define CAVS_IDC_TYPE_SHIFT 24U -#define CAVS_IDC_TYPE_MASK 0x7FU -#define CAVS_IDC_TYPE(x) \ - (((x) & CAVS_IDC_TYPE_MASK) << CAVS_IDC_TYPE_SHIFT) - -/* IDC message header. */ -#define CAVS_IDC_HEADER_MASK 0xFFFFFFU -#define CAVS_IDC_HEADER(x) ((x) & CAVS_IDC_HEADER_MASK) - -/* IDC message extension. */ -#define CAVS_IDC_EXTENSION_MASK 0x3FFFFFFFU -#define CAVS_IDC_EXTENSION(x) ((x) & CAVS_IDC_EXTENSION_MASK) - -/* Scheduler IPI message (type 0x7F, header 'IPI' in ascii) */ -#define IPM_CAVS_IDC_MSG_SCHED_IPI_DATA 0 -#define IPM_CAVS_IDC_MSG_SCHED_IPI_ID \ - (CAVS_IDC_TYPE(0x7FU) | CAVS_IDC_HEADER(0x495049U)) - -static inline uint32_t idc_read(uint32_t reg, uint32_t core_id) -{ - return *((volatile uint32_t*)(IPC_DSP_BASE(core_id) + reg)); -} - -static inline void idc_write(uint32_t reg, uint32_t core_id, uint32_t val) -{ - *((volatile uint32_t*)(IPC_DSP_BASE(core_id) + reg)) = val; -} - -int cavs_idc_smp_init(const struct device *dev); - -#endif /* ZEPHYR_DRIVERS_IPM_IPM_CAVS_IDC_H_ */ diff --git a/tests/boards/intel_adsp/smoke/prj.conf b/tests/boards/intel_adsp/smoke/prj.conf index f8f0f741aa4..0ab9b6f7c60 100644 --- a/tests/boards/intel_adsp/smoke/prj.conf +++ b/tests/boards/intel_adsp/smoke/prj.conf @@ -5,4 +5,3 @@ CONFIG_SMP_BOOT_DELAY=y CONFIG_SCHED_CPU_MASK=y CONFIG_IPM=y CONFIG_IPM_CAVS_HOST=y -CONFIG_IPM_CAVS_IDC=n From 691facc20fcaf6b2e283fb53231894984d1d12a6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 11:07:22 +0200 Subject: [PATCH 0404/4498] include: always use <> for Zephyr includes Double quotes "" should only be used for local headers. Signed-off-by: Gerard Marull-Paretas --- arch/posix/core/nsi_compat/nsi_compat.c | 2 +- boards/posix/common/irq/board_irq.h | 2 +- boards/posix/native_posix/cmdline.c | 2 +- boards/posix/native_posix/cmdline_common.c | 2 +- boards/posix/native_posix/hw_models_top.h | 2 +- boards/posix/native_posix/irq_ctrl.c | 2 +- boards/posix/native_posix/native_rtc.h | 2 +- boards/posix/native_posix/timer_model.c | 2 +- boards/posix/nrf52_bsim/board_irq.h | 2 +- boards/posix/nrf52_bsim/time_machine.h | 2 +- drivers/bluetooth/hci/hci_psoc6_bless.c | 2 +- drivers/crypto/crypto_mchp_xec_symcr.c | 2 +- drivers/ethernet/eth_smsc91x.c | 2 +- drivers/i2c/i2c_rtio.c | 2 +- drivers/i2c/i2c_sam_twihs_rtio.c | 2 +- drivers/ipm/ipm_sedi.h | 2 +- drivers/sensor/veml7700/veml7700.c | 2 +- drivers/timer/native_posix_timer.c | 2 +- include/zephyr/acpi/acpi_osal.h | 2 +- include/zephyr/net/net_time.h | 2 +- soc/posix/inf_clock/posix_board_if.h | 2 +- subsys/bluetooth/audio/ascs.c | 2 +- subsys/bluetooth/audio/vocs.c | 2 +- subsys/rtio/rtio_handlers.c | 2 +- tests/arch/arm64/arm64_smc_call/src/main.c | 2 +- tests/bluetooth/bt_crypto/src/test_bt_crypto.c | 2 +- tests/bluetooth/controller/common/src/helper_pdu.c | 4 ++-- tests/bluetooth/controller/common/src/helper_util.c | 4 ++-- tests/bluetooth/controller/mock_ctrl/src/ull_central.c | 2 +- tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c | 2 +- tests/bluetooth/tester/src/btp/btp_ias.h | 2 +- tests/bluetooth/tester/src/btp_csis.c | 2 +- tests/bluetooth/tester/src/btp_has.c | 4 ++-- tests/bluetooth/tester/src/btp_ias.c | 2 +- tests/bluetooth/tester/src/btp_vcp.c | 4 ++-- tests/bsim/bluetooth/audio/src/ias_client_test.c | 2 +- tests/bsim/bluetooth/host/adv/resume/src/bs_bt_utils.h | 2 +- tests/bsim/bluetooth/host/adv/resume/src/dut.c | 8 ++++---- tests/bsim/bluetooth/host/adv/resume/src/tester.c | 4 ++-- tests/bsim/bluetooth/host/gatt/settings/src/settings.c | 2 +- tests/bsim/bluetooth/host/privacy/legacy/src/tester.c | 4 ++-- tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c | 4 ++-- .../security/bond_overwrite_allowed/src/bs_bt_utils.h | 2 +- .../host/security/bond_overwrite_allowed/src/central.c | 4 ++-- .../host/security/bond_overwrite_allowed/src/peripheral.c | 8 ++++---- .../host/security/bond_overwrite_denied/src/bs_bt_utils.h | 2 +- .../host/security/bond_overwrite_denied/src/central.c | 4 ++-- .../host/security/bond_overwrite_denied/src/peripheral.c | 8 ++++---- .../host/security/bond_per_connection/src/bs_bt_utils.h | 2 +- .../host/security/bond_per_connection/src/central.c | 4 ++-- .../host/security/bond_per_connection/src/peripheral.c | 8 ++++---- .../host/security/id_addr_update/central/src/central.c | 4 ++-- .../host/security/id_addr_update/common/bs_bt_utils.h | 2 +- .../security/id_addr_update/peripheral/src/peripheral.c | 8 ++++---- tests/bsim/bluetooth/ll/edtt/common/edtt_driver.h | 2 +- tests/drivers/input/gpio_keys/src/main.c | 2 +- tests/drivers/spi/spi_loopback/src/spi_rtio.c | 2 +- tests/kernel/spinlock/src/spinlock_error_case.c | 2 +- tests/subsys/modem/modem_ppp/src/main.c | 4 ++-- 59 files changed, 86 insertions(+), 86 deletions(-) diff --git a/arch/posix/core/nsi_compat/nsi_compat.c b/arch/posix/core/nsi_compat/nsi_compat.c index eccd2643295..cd338ca1e4f 100644 --- a/arch/posix/core/nsi_compat/nsi_compat.c +++ b/arch/posix/core/nsi_compat/nsi_compat.c @@ -12,7 +12,7 @@ * the migration towards the Native simulator. */ -#include "zephyr/arch/posix/posix_trace.h" +#include void nsi_print_error_and_exit(const char *format, ...) { diff --git a/boards/posix/common/irq/board_irq.h b/boards/posix/common/irq/board_irq.h index abe28b82b94..bad19084dd1 100644 --- a/boards/posix/common/irq/board_irq.h +++ b/boards/posix/common/irq/board_irq.h @@ -9,7 +9,7 @@ #define BOARDS_POSIX_COMMON_BOARD_IRQ_H #include -#include "zephyr/types.h" +#include #ifdef __cplusplus extern "C" { diff --git a/boards/posix/native_posix/cmdline.c b/boards/posix/native_posix/cmdline.c index fd77f8abf94..aa0ef1e6974 100644 --- a/boards/posix/native_posix/cmdline.c +++ b/boards/posix/native_posix/cmdline.c @@ -8,7 +8,7 @@ #include #include #include "cmdline_common.h" -#include "zephyr/types.h" +#include #include "hw_models_top.h" #include "timer_model.h" #include "cmdline.h" diff --git a/boards/posix/native_posix/cmdline_common.c b/boards/posix/native_posix/cmdline_common.c index 40367033e11..8723505658a 100644 --- a/boards/posix/native_posix/cmdline_common.c +++ b/boards/posix/native_posix/cmdline_common.c @@ -12,7 +12,7 @@ #include #include #include "posix_board_if.h" -#include "zephyr/types.h" +#include #include "cmdline_common.h" /** diff --git a/boards/posix/native_posix/hw_models_top.h b/boards/posix/native_posix/hw_models_top.h index fe35f1b0455..47d3333277e 100644 --- a/boards/posix/native_posix/hw_models_top.h +++ b/boards/posix/native_posix/hw_models_top.h @@ -7,7 +7,7 @@ #ifndef _NATIVE_POSIX_HW_MODELS_H #define _NATIVE_POSIX_HW_MODELS_H -#include "zephyr/types.h" +#include #include #ifdef __cplusplus diff --git a/boards/posix/native_posix/irq_ctrl.c b/boards/posix/native_posix/irq_ctrl.c index 245f3f2eece..6524e5123a4 100644 --- a/boards/posix/native_posix/irq_ctrl.c +++ b/boards/posix/native_posix/irq_ctrl.c @@ -14,7 +14,7 @@ #include /* for find_lsb_set() */ #include "board_soc.h" #include "posix_soc.h" -#include "zephyr/types.h" +#include uint64_t irq_ctrl_timer = NEVER; diff --git a/boards/posix/native_posix/native_rtc.h b/boards/posix/native_posix/native_rtc.h index aaff5ae9d92..09fc1663882 100644 --- a/boards/posix/native_posix/native_rtc.h +++ b/boards/posix/native_posix/native_rtc.h @@ -15,7 +15,7 @@ #include "hw_models_top.h" #include -#include "zephyr/types.h" +#include #ifdef __cplusplus extern "C" { diff --git a/boards/posix/native_posix/timer_model.c b/boards/posix/native_posix/timer_model.c index cfa1c10ef06..4927d1028c4 100644 --- a/boards/posix/native_posix/timer_model.c +++ b/boards/posix/native_posix/timer_model.c @@ -25,7 +25,7 @@ #include "hw_models_top.h" #include "irq_ctrl.h" #include "board_soc.h" -#include "zephyr/types.h" +#include #include #include #include "cmdline.h" diff --git a/boards/posix/nrf52_bsim/board_irq.h b/boards/posix/nrf52_bsim/board_irq.h index bc41162c223..e1a385194fb 100644 --- a/boards/posix/nrf52_bsim/board_irq.h +++ b/boards/posix/nrf52_bsim/board_irq.h @@ -7,7 +7,7 @@ #ifndef BOARDS_POSIX_NRF52_BSIM_BOARD_IRQ_H #define BOARDS_POSIX_NRF52_BSIM_BOARD_IRQ_H -#include "zephyr/types.h" +#include #include "../common/irq/board_irq.h" #ifdef __cplusplus diff --git a/boards/posix/nrf52_bsim/time_machine.h b/boards/posix/nrf52_bsim/time_machine.h index de973cf4c8f..2e8a70dfeed 100644 --- a/boards/posix/nrf52_bsim/time_machine.h +++ b/boards/posix/nrf52_bsim/time_machine.h @@ -8,7 +8,7 @@ #include "bs_types.h" #include "time_machine_if.h" -#include "zephyr/toolchain.h" +#include #ifdef __cplusplus extern "C" { diff --git a/drivers/bluetooth/hci/hci_psoc6_bless.c b/drivers/bluetooth/hci/hci_psoc6_bless.c index c001264618b..3a5fddb1000 100644 --- a/drivers/bluetooth/hci/hci_psoc6_bless.c +++ b/drivers/bluetooth/hci/hci_psoc6_bless.c @@ -21,7 +21,7 @@ #include #include #include -#include "zephyr/logging/log.h" +#include #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER) #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL diff --git a/drivers/crypto/crypto_mchp_xec_symcr.c b/drivers/crypto/crypto_mchp_xec_symcr.c index 626d3f88154..8f47e374d36 100644 --- a/drivers/crypto/crypto_mchp_xec_symcr.c +++ b/drivers/crypto/crypto_mchp_xec_symcr.c @@ -12,7 +12,7 @@ #include #include #include -#include "zephyr/sys/util.h" +#include #include LOG_MODULE_REGISTER(xec_symcr, CONFIG_CRYPTO_LOG_LEVEL); diff --git a/drivers/ethernet/eth_smsc91x.c b/drivers/ethernet/eth_smsc91x.c index 02d11a26838..cac41136217 100644 --- a/drivers/ethernet/eth_smsc91x.c +++ b/drivers/ethernet/eth_smsc91x.c @@ -4,7 +4,7 @@ */ #include -#include "zephyr/net/phy.h" +#include #include #include #include diff --git a/drivers/i2c/i2c_rtio.c b/drivers/i2c/i2c_rtio.c index f4a97345e27..7e74329612d 100644 --- a/drivers/i2c/i2c_rtio.c +++ b/drivers/i2c/i2c_rtio.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/rtio/rtio.h" +#include #include #include #include diff --git a/drivers/i2c/i2c_sam_twihs_rtio.c b/drivers/i2c/i2c_sam_twihs_rtio.c index 1111a03c4e1..40abfd0c263 100644 --- a/drivers/i2c/i2c_sam_twihs_rtio.c +++ b/drivers/i2c/i2c_sam_twihs_rtio.c @@ -6,7 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/spinlock.h" +#include #define DT_DRV_COMPAT atmel_sam_i2c_twihs /** @file diff --git a/drivers/ipm/ipm_sedi.h b/drivers/ipm/ipm_sedi.h index bb1e945c2c2..f1524b0beea 100644 --- a/drivers/ipm/ipm_sedi.h +++ b/drivers/ipm/ipm_sedi.h @@ -11,7 +11,7 @@ extern "C" { #endif #include "sedi_driver_common.h" #include "sedi_driver_ipc.h" -#include "zephyr/sys/atomic.h" +#include /* * bit 31 indicates whether message is valid, and could generate interrupt diff --git a/drivers/sensor/veml7700/veml7700.c b/drivers/sensor/veml7700/veml7700.c index 7f00e3fd14c..e008b725167 100644 --- a/drivers/sensor/veml7700/veml7700.c +++ b/drivers/sensor/veml7700/veml7700.c @@ -14,7 +14,7 @@ #include #include -#include "zephyr/drivers/sensor/veml7700.h" +#include LOG_MODULE_REGISTER(VEML7700, CONFIG_SENSOR_LOG_LEVEL); diff --git a/drivers/timer/native_posix_timer.c b/drivers/timer/native_posix_timer.c index efe54e54bf0..31d1fc3bc69 100644 --- a/drivers/timer/native_posix_timer.c +++ b/drivers/timer/native_posix_timer.c @@ -10,7 +10,7 @@ * It also provides a custom k_busy_wait() which can be used with the * POSIX arch and InfClock SOC */ -#include "zephyr/types.h" +#include #include #include #include diff --git a/include/zephyr/acpi/acpi_osal.h b/include/zephyr/acpi/acpi_osal.h index 92e0180bc45..3332bd7ecc3 100644 --- a/include/zephyr/acpi/acpi_osal.h +++ b/include/zephyr/acpi/acpi_osal.h @@ -8,7 +8,7 @@ #define ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ #if defined(CONFIG_X86 || CONFIG_X86_64) -#include "zephyr/acpi/x86_acpi_osal.h" +#include #else #error "Currently only x86 Architecture support ACPI !!" #endif diff --git a/include/zephyr/net/net_time.h b/include/zephyr/net/net_time.h index 6277ea994c8..17795a9df95 100644 --- a/include/zephyr/net/net_time.h +++ b/include/zephyr/net/net_time.h @@ -18,7 +18,7 @@ #define ZEPHYR_INCLUDE_NET_NET_TIME_H_ /* Include required for NSEC_PER_* constants. */ -#include "zephyr/sys_clock.h" +#include #ifdef __cplusplus extern "C" { diff --git a/soc/posix/inf_clock/posix_board_if.h b/soc/posix/inf_clock/posix_board_if.h index 9fec9915443..1d851fb3935 100644 --- a/soc/posix/inf_clock/posix_board_if.h +++ b/soc/posix/inf_clock/posix_board_if.h @@ -6,7 +6,7 @@ #ifndef _POSIX_CORE_BOARD_PROVIDED_IF_H #define _POSIX_CORE_BOARD_PROVIDED_IF_H -#include "zephyr/types.h" +#include /* * This file lists the functions the posix "inf_clock" soc diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 3ac041e2b7e..1b71d27fbf4 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -15,7 +15,7 @@ #include #include #include -#include "zephyr/bluetooth/iso.h" +#include #include #include #include diff --git a/subsys/bluetooth/audio/vocs.c b/subsys/bluetooth/audio/vocs.c index 4b9420d36ee..6a03ceb3b70 100644 --- a/subsys/bluetooth/audio/vocs.c +++ b/subsys/bluetooth/audio/vocs.c @@ -19,7 +19,7 @@ #include "audio_internal.h" #include "vocs_internal.h" -#include "zephyr/bluetooth/audio/audio.h" +#include #define LOG_LEVEL CONFIG_BT_VOCS_LOG_LEVEL #include diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_handlers.c index ec7dc192e38..3be7f2f9f86 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/kernel.h" +#include #include #include #include diff --git a/tests/arch/arm64/arm64_smc_call/src/main.c b/tests/arch/arm64/arm64_smc_call/src/main.c index 01589656e7c..ac397bf6289 100644 --- a/tests/arch/arm64/arm64_smc_call/src/main.c +++ b/tests/arch/arm64/arm64_smc_call/src/main.c @@ -5,7 +5,7 @@ #include -#include "zephyr/arch/arm64/arm-smccc.h" +#include /* SMC function IDs for Standard Service queries */ #define ARM_STD_SMC_CALL_COUNT 0x8400ff00UL diff --git a/tests/bluetooth/bt_crypto/src/test_bt_crypto.c b/tests/bluetooth/bt_crypto/src/test_bt_crypto.c index 8f5aec3e36c..bddce1849c3 100644 --- a/tests/bluetooth/bt_crypto/src/test_bt_crypto.c +++ b/tests/bluetooth/bt_crypto/src/test_bt_crypto.c @@ -2,7 +2,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/ztest_assert.h" +#include #include #include diff --git a/tests/bluetooth/controller/common/src/helper_pdu.c b/tests/bluetooth/controller/common/src/helper_pdu.c index d952ccfb7ff..87454dda432 100644 --- a/tests/bluetooth/controller/common/src/helper_pdu.c +++ b/tests/bluetooth/controller/common/src/helper_pdu.c @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/types.h" -#include "zephyr/ztest.h" +#include +#include #include #include diff --git a/tests/bluetooth/controller/common/src/helper_util.c b/tests/bluetooth/controller/common/src/helper_util.c index 0356fdc1846..d89126c7857 100644 --- a/tests/bluetooth/controller/common/src/helper_util.c +++ b/tests/bluetooth/controller/common/src/helper_util.c @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/types.h" -#include "zephyr/ztest.h" +#include +#include #include #include diff --git a/tests/bluetooth/controller/mock_ctrl/src/ull_central.c b/tests/bluetooth/controller/mock_ctrl/src/ull_central.c index 763a09006eb..8cdf86b5db4 100644 --- a/tests/bluetooth/controller/mock_ctrl/src/ull_central.c +++ b/tests/bluetooth/controller/mock_ctrl/src/ull_central.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/types.h" +#include #include #include "util/util.h" #include "util/mem.h" diff --git a/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c b/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c index 52aa930c8fd..fb7a6f8f1c5 100644 --- a/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c +++ b/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/types.h" +#include #include #include "util/util.h" #include "util/mem.h" diff --git a/tests/bluetooth/tester/src/btp/btp_ias.h b/tests/bluetooth/tester/src/btp/btp_ias.h index 295aea2871a..a2af9d35f59 100644 --- a/tests/bluetooth/tester/src/btp/btp_ias.h +++ b/tests/bluetooth/tester/src/btp/btp_ias.h @@ -6,7 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/bluetooth/services/ias.h" +#include #include /* events */ diff --git a/tests/bluetooth/tester/src/btp_csis.c b/tests/bluetooth/tester/src/btp_csis.c index c7c57dbf035..08e9b05723f 100644 --- a/tests/bluetooth/tester/src/btp_csis.c +++ b/tests/bluetooth/tester/src/btp_csis.c @@ -8,7 +8,7 @@ #include #include "btp/btp.h" -#include "zephyr/sys/byteorder.h" +#include #include #define LOG_MODULE_NAME bttester_csis diff --git a/tests/bluetooth/tester/src/btp_has.c b/tests/bluetooth/tester/src/btp_has.c index 76aa2d85acb..d33d51f54ea 100644 --- a/tests/bluetooth/tester/src/btp_has.c +++ b/tests/bluetooth/tester/src/btp_has.c @@ -8,8 +8,8 @@ #include #include "btp/btp.h" -#include "zephyr/sys/byteorder.h" -#include "zephyr/arch/common/ffs.h" +#include +#include #include #include diff --git a/tests/bluetooth/tester/src/btp_ias.c b/tests/bluetooth/tester/src/btp_ias.c index d8750948858..58d0aa71f64 100644 --- a/tests/bluetooth/tester/src/btp_ias.c +++ b/tests/bluetooth/tester/src/btp_ias.c @@ -8,7 +8,7 @@ #include #include "btp/btp.h" -#include "zephyr/sys/byteorder.h" +#include #include #include diff --git a/tests/bluetooth/tester/src/btp_vcp.c b/tests/bluetooth/tester/src/btp_vcp.c index ac3f1b92dc7..ef8f2b9c97c 100644 --- a/tests/bluetooth/tester/src/btp_vcp.c +++ b/tests/bluetooth/tester/src/btp_vcp.c @@ -12,8 +12,8 @@ #include #include #include -#include "zephyr/bluetooth/audio/vocs.h" -#include "zephyr/sys/util.h" +#include +#include #include <../../subsys/bluetooth/audio/micp_internal.h> #include <../../subsys/bluetooth/audio/aics_internal.h> diff --git a/tests/bsim/bluetooth/audio/src/ias_client_test.c b/tests/bsim/bluetooth/audio/src/ias_client_test.c index 2c5dbd40bd0..6c435fb5cc6 100644 --- a/tests/bsim/bluetooth/audio/src/ias_client_test.c +++ b/tests/bsim/bluetooth/audio/src/ias_client_test.c @@ -7,7 +7,7 @@ #include #ifdef CONFIG_BT_IAS_CLIENT -#include "zephyr/bluetooth/services/ias.h" +#include #include "common.h" extern enum bst_result_t bst_result; diff --git a/tests/bsim/bluetooth/host/adv/resume/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/adv/resume/src/bs_bt_utils.h index 90a77be66e3..a28a046800e 100644 --- a/tests/bsim/bluetooth/host/adv/resume/src/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/adv/resume/src/bs_bt_utils.h @@ -10,7 +10,7 @@ #include "bs_types.h" #include "bstests.h" #include "time_machine.h" -#include "zephyr/sys/__assert.h" +#include #include diff --git a/tests/bsim/bluetooth/host/adv/resume/src/dut.c b/tests/bsim/bluetooth/host/adv/resume/src/dut.c index 4a58e9f5cad..fac6d919e24 100644 --- a/tests/bsim/bluetooth/host/adv/resume/src/dut.c +++ b/tests/bsim/bluetooth/host/adv/resume/src/dut.c @@ -5,10 +5,10 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/bluetooth.h" -#include "zephyr/bluetooth/conn.h" -#include "zephyr/toolchain/gcc.h" +#include +#include +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/adv/resume/src/tester.c b/tests/bsim/bluetooth/host/adv/resume/src/tester.c index 3c6bae7f4a7..9cb5854f260 100644 --- a/tests/bsim/bluetooth/host/adv/resume/src/tester.c +++ b/tests/bsim/bluetooth/host/adv/resume/src/tester.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include diff --git a/tests/bsim/bluetooth/host/gatt/settings/src/settings.c b/tests/bsim/bluetooth/host/gatt/settings/src/settings.c index c87a8470883..2aebd77f05f 100644 --- a/tests/bsim/bluetooth/host/gatt/settings/src/settings.c +++ b/tests/bsim/bluetooth/host/gatt/settings/src/settings.c @@ -11,7 +11,7 @@ #include #include -#include "zephyr/types.h" +#include #include "errno.h" #include "argparse.h" diff --git a/tests/bsim/bluetooth/host/privacy/legacy/src/tester.c b/tests/bsim/bluetooth/host/privacy/legacy/src/tester.c index 1648e030be5..ed425febe3c 100644 --- a/tests/bsim/bluetooth/host/privacy/legacy/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/legacy/src/tester.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c index eae8dc61515..e125f88c615 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/bs_bt_utils.h index 1013fad20fe..b3718eb769d 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/bs_bt_utils.h @@ -10,7 +10,7 @@ #include "bs_types.h" #include "bstests.h" #include "time_machine.h" -#include "zephyr/sys/__assert.h" +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/central.c b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/central.c index 0ea460ab122..164646fe79c 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/central.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/central.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c index 7dca9913dd7..e0e6a81fe93 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c @@ -5,10 +5,10 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/bluetooth.h" -#include "zephyr/bluetooth/conn.h" -#include "zephyr/toolchain/gcc.h" +#include +#include +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/bs_bt_utils.h index 1013fad20fe..b3718eb769d 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/bs_bt_utils.h @@ -10,7 +10,7 @@ #include "bs_types.h" #include "bstests.h" #include "time_machine.h" -#include "zephyr/sys/__assert.h" +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/central.c b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/central.c index e1e8e0efc4d..26f3bee4710 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/central.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/central.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c index fb3527b7ef2..c6baf98c689 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c @@ -5,10 +5,10 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/bluetooth.h" -#include "zephyr/bluetooth/conn.h" -#include "zephyr/toolchain/gcc.h" +#include +#include +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.h index fc440c6bec8..c16d9cb9676 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.h @@ -10,7 +10,7 @@ #include "bs_types.h" #include "bstests.h" #include "time_machine.h" -#include "zephyr/sys/__assert.h" +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/central.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/central.c index f31261b68c0..4e0052310d3 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/central.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/central.c @@ -5,8 +5,8 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c index 5e11d6ac712..8cd01f194ec 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c @@ -5,10 +5,10 @@ */ #include "bs_bt_utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/bluetooth.h" -#include "zephyr/bluetooth/conn.h" -#include "zephyr/toolchain/gcc.h" +#include +#include +#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c index f6e22658e33..15c9fa69cfd 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/central/src/central.c @@ -6,8 +6,8 @@ #include "bs_bt_utils.h" #include "utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/conn.h" +#include +#include #include diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h b/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h index 13dab52399c..2b4b4a48911 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h +++ b/tests/bsim/bluetooth/host/security/id_addr_update/common/bs_bt_utils.h @@ -10,7 +10,7 @@ #include "bs_types.h" #include "bstests.h" #include "time_machine.h" -#include "zephyr/sys/__assert.h" +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c index daac93e5b4e..bbdfc055021 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c @@ -6,10 +6,10 @@ #include "bs_bt_utils.h" #include "utils.h" -#include "zephyr/bluetooth/addr.h" -#include "zephyr/bluetooth/bluetooth.h" -#include "zephyr/bluetooth/conn.h" -#include "zephyr/toolchain/gcc.h" +#include +#include +#include +#include #include #include diff --git a/tests/bsim/bluetooth/ll/edtt/common/edtt_driver.h b/tests/bsim/bluetooth/ll/edtt/common/edtt_driver.h index 04b94c80294..576aa68fa11 100644 --- a/tests/bsim/bluetooth/ll/edtt/common/edtt_driver.h +++ b/tests/bsim/bluetooth/ll/edtt/common/edtt_driver.h @@ -10,7 +10,7 @@ #include #include -#include "zephyr/types.h" +#include #define EDTTT_NONBLOCK 0 #define EDTTT_BLOCK 1 diff --git a/tests/drivers/input/gpio_keys/src/main.c b/tests/drivers/input/gpio_keys/src/main.c index aa86f5f05e3..b5764d7283a 100644 --- a/tests/drivers/input/gpio_keys/src/main.c +++ b/tests/drivers/input/gpio_keys/src/main.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/sys/util.h" +#include #include #include #include diff --git a/tests/drivers/spi/spi_loopback/src/spi_rtio.c b/tests/drivers/spi/spi_loopback/src/spi_rtio.c index 5c1bb4a356d..be52fc8c3ee 100644 --- a/tests/drivers/spi/spi_loopback/src/spi_rtio.c +++ b/tests/drivers/spi/spi_loopback/src/spi_rtio.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/devicetree.h" +#include #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL #include LOG_MODULE_REGISTER(spi_rtio_loopback); diff --git a/tests/kernel/spinlock/src/spinlock_error_case.c b/tests/kernel/spinlock/src/spinlock_error_case.c index 4dd09c7f217..f40bc86f89d 100644 --- a/tests/kernel/spinlock/src/spinlock_error_case.c +++ b/tests/kernel/spinlock/src/spinlock_error_case.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/ztest_test_new.h" +#include #include #include #include diff --git a/tests/subsys/modem/modem_ppp/src/main.c b/tests/subsys/modem/modem_ppp/src/main.c index ee60385163c..27fe6bf64d5 100644 --- a/tests/subsys/modem/modem_ppp/src/main.c +++ b/tests/subsys/modem/modem_ppp/src/main.c @@ -11,8 +11,8 @@ #include #include #include -#include "zephyr/net/net_l2.h" -#include "zephyr/net/ppp.h" +#include +#include #include #include From d8571ef2a9d40b799c4ec8a1517d0d0ebf76ada8 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 31 Aug 2023 15:42:06 +0200 Subject: [PATCH 0405/4498] samples: boards: nrf: system_off: s/printk/printf Use printf instead of printk, samples should prefer standard C APIs. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/src/main.c | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/samples/boards/nrf/system_off/src/main.c b/samples/boards/nrf/system_off/src/main.c index 6a2a3491602..4994dcfbcbe 100644 --- a/samples/boards/nrf/system_off/src/main.c +++ b/samples/boards/nrf/system_off/src/main.c @@ -5,6 +5,7 @@ */ #include + #include #include #include @@ -22,11 +23,11 @@ int main(void) const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); if (!device_is_ready(cons)) { - printk("%s: device not ready.\n", cons->name); + printf("%s: device not ready.\n", cons->name); return 0; } - printk("\n%s system off demo\n", CONFIG_BOARD); + printf("\n%s system off demo\n", CONFIG_BOARD); if (IS_ENABLED(CONFIG_APP_RETENTION)) { bool retained_ok = retained_validate(); @@ -35,12 +36,12 @@ int main(void) retained.boots += 1; retained_update(); - printk("Retained data: %s\n", retained_ok ? "valid" : "INVALID"); - printk("Boot count: %u\n", retained.boots); - printk("Off count: %u\n", retained.off_count); - printk("Active Ticks: %" PRIu64 "\n", retained.uptime_sum); + printf("Retained data: %s\n", retained_ok ? "valid" : "INVALID"); + printf("Boot count: %u\n", retained.boots); + printf("Off count: %u\n", retained.off_count); + printf("Active Ticks: %" PRIu64 "\n", retained.uptime_sum); } else { - printk("Retained data not supported\n"); + printf("Retained data not supported\n"); } /* Configure to generate PORT event (wakeup) on button 1 press. */ @@ -49,23 +50,23 @@ int main(void) nrf_gpio_cfg_sense_set(NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios), NRF_GPIO_PIN_SENSE_LOW); - printk("Busy-wait %u s\n", BUSY_WAIT_S); + printf("Busy-wait %u s\n", BUSY_WAIT_S); k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC); - printk("Busy-wait %u s with UART off\n", BUSY_WAIT_S); + printf("Busy-wait %u s with UART off\n", BUSY_WAIT_S); rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC); rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); - printk("Sleep %u s\n", SLEEP_S); + printf("Sleep %u s\n", SLEEP_S); k_sleep(K_SECONDS(SLEEP_S)); - printk("Sleep %u s with UART off\n", SLEEP_S); + printf("Sleep %u s with UART off\n", SLEEP_S); rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); k_sleep(K_SECONDS(SLEEP_S)); rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); - printk("Entering system off; press BUTTON1 to restart\n"); + printf("Entering system off; press BUTTON1 to restart\n"); if (IS_ENABLED(CONFIG_APP_RETENTION)) { /* Update the retained state */ From 7fb662032df1c7cc67a9d789fd2c9596a0746847 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 31 Aug 2023 15:44:16 +0200 Subject: [PATCH 0406/4498] samples: boards: nrf: system_off: fix includes Include only what is needed, also sort includes properly. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/src/main.c | 10 +++++++--- samples/boards/nrf/system_off/src/retained.c | 6 +++++- samples/boards/nrf/system_off/src/retained.h | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/samples/boards/nrf/system_off/src/main.c b/samples/boards/nrf/system_off/src/main.c index 4994dcfbcbe..b7c73c1390c 100644 --- a/samples/boards/nrf/system_off/src/main.c +++ b/samples/boards/nrf/system_off/src/main.c @@ -4,15 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "retained.h" + +#include #include -#include #include +#include #include #include -#include -#include "retained.h" +#include + #include +#include #define BUSY_WAIT_S 2U #define SLEEP_S 2U diff --git a/samples/boards/nrf/system_off/src/retained.c b/samples/boards/nrf/system_off/src/retained.c index f389b50cc23..e418780f034 100644 --- a/samples/boards/nrf/system_off/src/retained.c +++ b/samples/boards/nrf/system_off/src/retained.c @@ -4,13 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "retained.h" + +#include #include + #include #include #include #include + #include -#include "retained.h" /* nRF52 RAM (really, RAM AHB slaves) are partitioned as: * * Up to 8 blocks of two 4 KiBy byte "small" sections diff --git a/samples/boards/nrf/system_off/src/retained.h b/samples/boards/nrf/system_off/src/retained.h index ebe3b2f2ec2..e79c54ff022 100644 --- a/samples/boards/nrf/system_off/src/retained.h +++ b/samples/boards/nrf/system_off/src/retained.h @@ -7,7 +7,8 @@ #ifndef RETAINED_H_ #define RETAINED_H_ -#include +#include +#include /* Example of validatable retained data. */ struct retained_data { From 6b56c9d8e5bcda0e695d16e86ab5d47d26858743 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 31 Aug 2023 15:50:20 +0200 Subject: [PATCH 0407/4498] samples: boards: nrf: system_off: remove redundant prj.conf comment Not needed, already mentioned in sample.yaml. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/prj.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/boards/nrf/system_off/prj.conf b/samples/boards/nrf/system_off/prj.conf index a57c6919a1e..ffa1571400c 100644 --- a/samples/boards/nrf/system_off/prj.conf +++ b/samples/boards/nrf/system_off/prj.conf @@ -1,7 +1,5 @@ # Required to disable default behavior of deep sleep on timeout CONFIG_PM_DEVICE=y CONFIG_GPIO=y -# Optional select RAM retention (nRF52 only) -#CONFIG_APP_RETENTION=y CONFIG_CRC=y CONFIG_POWEROFF=y From aa1dd873131d6417130f240c73e532e30eb75b01 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 31 Aug 2023 15:51:37 +0200 Subject: [PATCH 0408/4498] samples: boards: nrf: system_off: add missing dependency APP_RETENTION depends on having CRC enabled. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/nrf/system_off/Kconfig b/samples/boards/nrf/system_off/Kconfig index cf7923f59c1..b85b0124de1 100644 --- a/samples/boards/nrf/system_off/Kconfig +++ b/samples/boards/nrf/system_off/Kconfig @@ -5,7 +5,7 @@ mainmenu "Nordic SYSTEM_OFF demo" config APP_RETENTION bool "State retention in system off" - depends on SOC_COMPATIBLE_NRF52X + depends on SOC_COMPATIBLE_NRF52X && CRC help On some Nordic chips this application supports retaining memory while in system off. Select this to enable the From 1f40012c0002b93525b164926d9e119e050ec5e6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 31 Aug 2023 15:57:10 +0200 Subject: [PATCH 0409/4498] samples: boards: nrf: system_off: use standard GPIO API Wake-up from pin is already supported when configuring GPIO interrupt as GPIO_INT_LEVEL_ACTIVE, so there's no need to resort to HAL. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/src/main.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/samples/boards/nrf/system_off/src/main.c b/samples/boards/nrf/system_off/src/main.c index b7c73c1390c..4b8a5342163 100644 --- a/samples/boards/nrf/system_off/src/main.c +++ b/samples/boards/nrf/system_off/src/main.c @@ -10,13 +10,13 @@ #include #include +#include #include #include #include #include -#include -#include +static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); #define BUSY_WAIT_S 2U #define SLEEP_S 2U @@ -48,11 +48,12 @@ int main(void) printf("Retained data not supported\n"); } - /* Configure to generate PORT event (wakeup) on button 1 press. */ - nrf_gpio_cfg_input(NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios), - NRF_GPIO_PIN_PULLUP); - nrf_gpio_cfg_sense_set(NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios), - NRF_GPIO_PIN_SENSE_LOW); + /* configure sw0 as input, interrupt as level active to allow wake-up */ + rc = gpio_pin_configure_dt(&sw0, GPIO_INPUT); + if (rc < 0) { + printf("Could not configure sw0 GPIO (%d)\n", rc); + return 0; + } printf("Busy-wait %u s\n", BUSY_WAIT_S); k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC); @@ -70,7 +71,13 @@ int main(void) k_sleep(K_SECONDS(SLEEP_S)); rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); - printf("Entering system off; press BUTTON1 to restart\n"); + rc = gpio_pin_interrupt_configure_dt(&sw0, GPIO_INT_LEVEL_ACTIVE); + if (rc < 0) { + printf("Could not configure sw0 GPIO interrupt (%d)\n", rc); + return 0; + } + + printf("Entering system off; press sw0 to restart\n"); if (IS_ENABLED(CONFIG_APP_RETENTION)) { /* Update the retained state */ From 2cbc452d1d0dcf9dc6bc9c6081b4bc54f6a04e89 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 11:19:20 +0200 Subject: [PATCH 0410/4498] samples: boards: nrf: system_off: suspend console To achieve minimal power consumption, only the console (ie UART) needs to be suspended. Note that this is a temporary workaround, UART driver should be using device runtime PM so that this is not needed. Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/prj.conf | 1 - samples/boards/nrf/system_off/src/main.c | 25 ++++++------------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/samples/boards/nrf/system_off/prj.conf b/samples/boards/nrf/system_off/prj.conf index ffa1571400c..3849b9c2746 100644 --- a/samples/boards/nrf/system_off/prj.conf +++ b/samples/boards/nrf/system_off/prj.conf @@ -1,4 +1,3 @@ -# Required to disable default behavior of deep sleep on timeout CONFIG_PM_DEVICE=y CONFIG_GPIO=y CONFIG_CRC=y diff --git a/samples/boards/nrf/system_off/src/main.c b/samples/boards/nrf/system_off/src/main.c index 4b8a5342163..83ae6206648 100644 --- a/samples/boards/nrf/system_off/src/main.c +++ b/samples/boards/nrf/system_off/src/main.c @@ -18,9 +18,6 @@ static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); -#define BUSY_WAIT_S 2U -#define SLEEP_S 2U - int main(void) { int rc; @@ -55,22 +52,6 @@ int main(void) return 0; } - printf("Busy-wait %u s\n", BUSY_WAIT_S); - k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC); - - printf("Busy-wait %u s with UART off\n", BUSY_WAIT_S); - rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); - k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC); - rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); - - printf("Sleep %u s\n", SLEEP_S); - k_sleep(K_SECONDS(SLEEP_S)); - - printf("Sleep %u s with UART off\n", SLEEP_S); - rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); - k_sleep(K_SECONDS(SLEEP_S)); - rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); - rc = gpio_pin_interrupt_configure_dt(&sw0, GPIO_INT_LEVEL_ACTIVE); if (rc < 0) { printf("Could not configure sw0 GPIO interrupt (%d)\n", rc); @@ -79,6 +60,12 @@ int main(void) printf("Entering system off; press sw0 to restart\n"); + rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); + if (rc < 0) { + printf("Could not suspend console (%d)\n", rc); + return 0; + } + if (IS_ENABLED(CONFIG_APP_RETENTION)) { /* Update the retained state */ retained.off_count += 1; From 577fd949c2a05781bef61bae1f28b9a3f05a52e5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 13:31:57 +0200 Subject: [PATCH 0411/4498] samples: boards: nrf: system_off: update readme - Remove obsolete information - Remove redundant details, e.g. how to flash - Adjust output Signed-off-by: Gerard Marull-Paretas --- samples/boards/nrf/system_off/README.rst | 43 +++--------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/samples/boards/nrf/system_off/README.rst b/samples/boards/nrf/system_off/README.rst index 77eb93766dc..8d5636be0f9 100644 --- a/samples/boards/nrf/system_off/README.rst +++ b/samples/boards/nrf/system_off/README.rst @@ -7,20 +7,7 @@ Overview ******** This sample can be used for basic power measurement and as an example of -deep sleep on Nordic platforms. The functional behavior is: - -* Busy-wait for 2 seconds -* Sleep for 2 seconds without device power control -* Sleep for 2 seconds after turning UART off, which reduces current draw - by a couple hundred uA -* Turn the system off after enabling wakeup through a button press - -A power monitor will be able to distinguish among these states. - -This sample also demonstrates the use of a :c:func:`SYS_INIT()` call to -disable the deep sleep functionality before the kernel starts, which -prevents the board from powering down during initialization of drivers -that use unbounded delays to wait for startup. +deep sleep on Nordic platforms. RAM Retention ============= @@ -36,27 +23,9 @@ Requirements This application uses nRF51 DK or nRF52 DK board for the demo. -Building, Flashing and Running -****************************** - -.. zephyr-app-commands:: - :zephyr-app: samples/boards/nrf/system_off - :board: nrf52dk_nrf52832 - :goals: build flash - :compact: - -Running: - -1. Open UART terminal. -2. Power Cycle Device. -3. Device will demonstrate two activity levels which can be measured. -4. Device will demonstrate long sleep at minimal non-off power. -5. Device will turn itself off using deep sleep state 1. Press Button 1 - to wake the device and restart the application as if it had been - powered back on. - Sample Output -================= +============= + nRF52 core output ----------------- @@ -65,8 +34,4 @@ nRF52 core output *** Booting Zephyr OS build v2.3.0-rc1-204-g5f2eb85f728d *** nrf52dk_nrf52832 system off demo - Busy-wait 2 s - Busy-wait 2 s with UART off - Sleep 2 s - Sleep 2 s with UART off - Entering system off; press BUTTON1 to restart + Entering system off; press sw0 to restart From f2069530ee9d73d2c5c3a65bd3b146b0631593fb Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 13 Sep 2023 12:37:29 +0530 Subject: [PATCH 0412/4498] Bluetooth: Controller: Fix some compiler instruction re-ordering Fix some compiler instruction re-ordering. Mayfly code with cpu_dmb() help avoid stalled memq_ull_rx processing when rx_demux is to be executed using mayfly. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ticker/ticker.c | 1 + subsys/bluetooth/controller/util/mayfly.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index 679467d148c..ead148e85ba 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -3149,6 +3149,7 @@ void ticker_job(void *param) instance->job_guard = 0U; /* trigger worker if deferred */ + cpu_dmb(); if (instance->worker_trigger || compare_trigger) { instance->sched_cb(TICKER_CALL_ID_JOB, TICKER_CALL_ID_WORKER, 1, instance); diff --git a/subsys/bluetooth/controller/util/mayfly.c b/subsys/bluetooth/controller/util/mayfly.c index e8de3acfd80..d45569c6a35 100644 --- a/subsys/bluetooth/controller/util/mayfly.c +++ b/subsys/bluetooth/controller/util/mayfly.c @@ -6,8 +6,13 @@ */ #include + +#include #include #include + +#include "hal/cpu.h" + #include "memq.h" #include "mayfly.h" @@ -154,10 +159,12 @@ static void dequeue(uint8_t callee_id, uint8_t caller_id, memq_link_t *link, m->_link = link; /* reset mayfly state to idle */ + cpu_dmb(); ack = m->_ack; m->_ack = req; /* re-insert, if re-pended by interrupt */ + cpu_dmb(); if (((m->_req - ack) & 0x03) == 1U) { #if defined(MAYFLY_UT) printk("%s: RACE\n", __func__); From 6ead139b4b171fbe494c4a8422e557ce3fc2d414 Mon Sep 17 00:00:00 2001 From: Yicheng Li Date: Tue, 22 Aug 2023 14:55:36 -0700 Subject: [PATCH 0413/4498] mbox: Add NXP MU as a MBOX device Add a MBOX driver wrapper around the NXP MU, simular to the existing wrapper around the NXP S32 MRU. This allows Zephyr IPC to work based on the MU, on a number of NXP boards. Also update the SHA of NXP HAL to enable the Kconfig for this driver. Signed-off-by: Yicheng Li --- .../arm/mimxrt595_evk/mimxrt595_evk_cm33.dts | 4 + drivers/mbox/CMakeLists.txt | 1 + drivers/mbox/Kconfig | 1 + drivers/mbox/Kconfig.nxp_imx | 9 + drivers/mbox/mbox_nxp_imx_mu.c | 179 ++++++++++++++++++ dts/arm/nxp/nxp_rt5xx_common.dtsi | 9 + dts/bindings/mbox/nxp,mbox-imx-mu.yaml | 29 +++ samples/drivers/mbox/CMakeLists.txt | 2 + .../mbox/boards/mimxrt595_evk_cm33.conf | 1 + samples/drivers/mbox/sample.yaml | 5 +- west.yml | 2 +- 11 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 drivers/mbox/Kconfig.nxp_imx create mode 100644 drivers/mbox/mbox_nxp_imx_mu.c create mode 100644 dts/bindings/mbox/nxp,mbox-imx-mu.yaml create mode 100644 samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts index e65106d87d6..f919ba00ea0 100644 --- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts +++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts @@ -459,6 +459,10 @@ zephyr_udc0: &usbhs { status = "okay"; }; +&mbox { + status = "okay"; +}; + /* Disable this node if not using USB and need another MPU region */ &sram1 { status = "okay"; diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index aa39b235522..b81a3bb679f 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -7,4 +7,5 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE mbox_handlers.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NRFX_IPC mbox_nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_S32_MRU mbox_nxp_s32_mru.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_IMX_MU mbox_nxp_imx_mu.c) zephyr_library_sources_ifdef(CONFIG_MBOX_ANDES_PLIC_SW mbox_andes_plic_sw.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index a88a84472b4..0668c9aab8b 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -13,6 +13,7 @@ if MBOX # overridden (by defining symbols in multiple locations) source "drivers/mbox/Kconfig.nrfx" source "drivers/mbox/Kconfig.nxp_s32" +source "drivers/mbox/Kconfig.nxp_imx" source "drivers/mbox/Kconfig.andes" config MBOX_INIT_PRIORITY diff --git a/drivers/mbox/Kconfig.nxp_imx b/drivers/mbox/Kconfig.nxp_imx new file mode 100644 index 00000000000..6822e5dd87c --- /dev/null +++ b/drivers/mbox/Kconfig.nxp_imx @@ -0,0 +1,9 @@ +# Copyright 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_NXP_IMX_MU + bool "NXP i.MX Message Unit (MU) driver" + default y + depends on DT_HAS_NXP_MBOX_IMX_MU_ENABLED + help + Driver for NXP i.MX Message Unit. diff --git a/drivers/mbox/mbox_nxp_imx_mu.c b/drivers/mbox/mbox_nxp_imx_mu.c new file mode 100644 index 00000000000..3c708b95eca --- /dev/null +++ b/drivers/mbox/mbox_nxp_imx_mu.c @@ -0,0 +1,179 @@ +/* + * Wrapper of the i.MX Message Unit driver into Zephyr's MBOX model. + */ + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_MBOX_LOG_LEVEL +#include +LOG_MODULE_REGISTER(nxp_mbox_imx_mu); + +#define DT_DRV_COMPAT nxp_mbox_imx_mu + +#define MU_MAX_CHANNELS 4 +#define MU_MBOX_SIZE sizeof(uint32_t) + +struct nxp_imx_mu_data { + mbox_callback_t cb[MU_MAX_CHANNELS]; + void *user_data[MU_MAX_CHANNELS]; +}; + +struct nxp_imx_mu_config { + MU_Type *base; +}; + +static int nxp_imx_mu_send(const struct device *dev, uint32_t channel, + const struct mbox_msg *msg) +{ + uint32_t __aligned(4) data32; + const struct nxp_imx_mu_config *cfg = dev->config; + + if (channel >= MU_MAX_CHANNELS) { + return -EINVAL; + } + + /* Signalling mode. */ + if (msg == NULL) { + return MU_TriggerInterrupts( + cfg->base, kMU_GenInt0InterruptTrigger); + } + + /* Data transfer mode. */ + if (msg->size != MU_MBOX_SIZE) { + /* We can only send this many bytes at a time. */ + return -EMSGSIZE; + } + + /* memcpy to avoid issues when msg->data is not word-aligned. */ + memcpy(&data32, msg->data, msg->size); + MU_SendMsg(cfg->base, channel, data32); + return 0; +} + +static int nxp_imx_mu_register_callback(const struct device *dev, uint32_t channel, + mbox_callback_t cb, void *user_data) +{ + struct nxp_imx_mu_data *data = dev->data; + + if (channel >= MU_MAX_CHANNELS) { + return -EINVAL; + } + + data->cb[channel] = cb; + data->user_data[channel] = user_data; + + return 0; +} + +static int nxp_imx_mu_mtu_get(const struct device *dev) +{ + ARG_UNUSED(dev); + return MU_MBOX_SIZE; +} + +static uint32_t nxp_imx_mu_max_channels_get(const struct device *dev) +{ + ARG_UNUSED(dev); + return MU_MAX_CHANNELS; +} + +static int nxp_imx_mu_set_enabled(const struct device *dev, uint32_t channel, + bool enable) +{ + struct nxp_imx_mu_data *data = dev->data; + const struct nxp_imx_mu_config *cfg = dev->config; + + if (channel >= MU_MAX_CHANNELS) { + return -EINVAL; + } + + if (enable) { + if (data->cb[channel] == NULL) { + LOG_WRN("Enabling channel without a registered callback"); + } + MU_EnableInterrupts(cfg->base, + kMU_GenInt0InterruptEnable | kMU_GenInt1InterruptEnable | + kMU_GenInt2InterruptEnable | kMU_GenInt3InterruptEnable | + kMU_Rx0FullInterruptEnable | kMU_Rx1FullInterruptEnable | + kMU_Rx2FullInterruptEnable | kMU_Rx3FullInterruptEnable); + } else { + MU_DisableInterrupts(cfg->base, + kMU_GenInt0InterruptEnable | kMU_GenInt1InterruptEnable | + kMU_GenInt2InterruptEnable | kMU_GenInt3InterruptEnable | + kMU_Rx0FullInterruptEnable | kMU_Rx1FullInterruptEnable | + kMU_Rx2FullInterruptEnable | kMU_Rx3FullInterruptEnable); + } + + return 0; +} + +static const struct mbox_driver_api nxp_imx_mu_driver_api = { + .send = nxp_imx_mu_send, + .register_callback = nxp_imx_mu_register_callback, + .mtu_get = nxp_imx_mu_mtu_get, + .max_channels_get = nxp_imx_mu_max_channels_get, + .set_enabled = nxp_imx_mu_set_enabled, +}; + +#define MU_INSTANCE_DEFINE(idx) \ + static struct nxp_imx_mu_data nxp_imx_mu_##idx##_data; \ + static struct nxp_imx_mu_config nxp_imx_mu_##idx##_config = { \ + .base = (MU_Type *)DT_INST_REG_ADDR(idx), \ + }; \ + \ + void MU_##idx##_IRQHandler(void); \ + static int nxp_imx_mu_##idx##_init(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + MU_Init(nxp_imx_mu_##idx##_config.base); \ + IRQ_CONNECT(DT_INST_IRQN(idx), \ + DT_INST_IRQ(idx, priority), \ + MU_##idx##_IRQHandler, \ + NULL, \ + 0); \ + irq_enable(DT_INST_IRQN(idx)); \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(idx, nxp_imx_mu_##idx##_init, NULL, \ + &nxp_imx_mu_##idx##_data, &nxp_imx_mu_##idx##_config, \ + POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY, \ + &nxp_imx_mu_driver_api) + +#define MU_IRQ_HANDLER(idx) \ + static uint32_t mu_##idx##_received_data; \ + void MU_##idx##_IRQHandler(void) \ + { \ + const struct device *dev = DEVICE_DT_INST_GET(idx); \ + const struct nxp_imx_mu_data *data = dev->data; \ + const struct nxp_imx_mu_config *config = dev->config; \ + int channel = 0; \ + struct mbox_msg msg; \ + struct mbox_msg *callback_msg_ptr = NULL; \ + uint32_t flag = MU_GetStatusFlags(config->base); \ + \ + if ((flag & kMU_Rx0FullFlag) == kMU_Rx0FullFlag) { \ + mu_##idx##_received_data = \ + MU_ReceiveMsgNonBlocking(config->base, 0); \ + msg.data = (const void *)&mu_##idx##_received_data; \ + msg.size = MU_MBOX_SIZE; \ + callback_msg_ptr = &msg; \ + } else if ((flag & kMU_GenInt0Flag) == kMU_GenInt0Flag) { \ + MU_ClearStatusFlags(config->base, kMU_GenInt0Flag); \ + callback_msg_ptr = NULL; \ + } \ + \ + if (data->cb[channel]) { \ + data->cb[channel](dev, channel, \ + data->user_data[channel], \ + callback_msg_ptr); \ + } \ + } + +#define MU_INST(idx) \ + MU_INSTANCE_DEFINE(idx); \ + MU_IRQ_HANDLER(idx); + +DT_INST_FOREACH_STATUS_OKAY(MU_INST) diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 9de7dfba991..5b24777f0c5 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -546,6 +546,15 @@ #address-cells = <3>; #size-cells = <0>; }; + + mbox:mbox@110000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x110000 0x100>; + interrupts = <34 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "disabled"; + }; }; &flexspi { diff --git a/dts/bindings/mbox/nxp,mbox-imx-mu.yaml b/dts/bindings/mbox/nxp,mbox-imx-mu.yaml new file mode 100644 index 00000000000..bc8bb5d6abf --- /dev/null +++ b/dts/bindings/mbox/nxp,mbox-imx-mu.yaml @@ -0,0 +1,29 @@ +description: | + NXP i.MX Message Unit as Zephyr MBOX + +compatible: "nxp,mbox-imx-mu" + +include: [base.yaml, mailbox-controller.yaml] + +properties: + interrupts: + required: true + + rx-channels: + type: int + enum: [1, 2, 3, 4] + description: | + Number of receive channels enabled on this instance. + Setting this value to N, will enable channels 0 to N-1, consecutively. + It should be set by the receiver core coupled with this MU instance. + + For example, if receiver A wants to Rx on channels 0 to 3, then A must + set rx-channels of muA as follows: + + mruA { + rx-channels = <4>; + status = "okay"; + }; + +mbox-cells: + - channel diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index dd7ab115570..d94fdffbfb1 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -12,6 +12,8 @@ if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") elseif("${BOARD}" STREQUAL "adp_xc7k_ae350") set(BOARD_REMOTE "adp_xc7k_ae350") +elseif("${BOARD}" STREQUAL "mimxrt595_evk_cm33") + set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() diff --git a/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf b/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf new file mode 100644 index 00000000000..b01ff58e024 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf @@ -0,0 +1 @@ +CONFIG_MBOX_NXP_IMX_MU=y diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 6d1ee5fd235..eb5e5ac1a5d 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -2,7 +2,10 @@ sample: name: MBOX IPC sample tests: sample.drivers.mbox: - platform_allow: nrf5340dk_nrf5340_cpuapp adp_xc7k_ae350 + platform_allow: + - nrf5340dk_nrf5340_cpuapp + - adp_xc7k_ae350 + - mimxrt595_evk_cm33 integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: mbox diff --git a/west.yml b/west.yml index c690b2dd31a..f0005c12d4d 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 0ef57e8ee40f02f1dce4b4ad666c55885f941703 + revision: 06c956741a81eb0fd3c0c31367c3c177bffaaab8 path: modules/hal/nxp groups: - hal From 4edb915c2cb90c71da23b237ebb45867391ef8ea Mon Sep 17 00:00:00 2001 From: Piotr Zierhoffer Date: Sun, 3 Sep 2023 15:42:47 +0200 Subject: [PATCH 0414/4498] dts/arm/st: add SoC compatible string to stm32wba and stm32mb SoCs While most of the ST family SoCs have the compatible string set, several targets still miss it. Signed-off-by: Piotr Zierhoffer --- dts/arm/st/mp1/stm32mp157.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dts/arm/st/mp1/stm32mp157.dtsi b/dts/arm/st/mp1/stm32mp157.dtsi index aaa653280cc..f70a96b6ead 100644 --- a/dts/arm/st/mp1/stm32mp157.dtsi +++ b/dts/arm/st/mp1/stm32mp157.dtsi @@ -39,6 +39,8 @@ }; soc { + compatible = "st,stm32mp157", "st,stm32mp1", "simple-bus"; + rcc: rcc@50000000 { compatible = "st,stm32mp1-rcc"; reg = <0x50000000 0x1000>; From 9ed51516ed4a4e514db98b7077f7f2ab22a441f7 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 5 Sep 2023 15:12:35 +0200 Subject: [PATCH 0415/4498] dts/bindings/riscv: don't enforce `riscv,isa` values with enum array This commit removes the enum array with allowed values for the `riscv,isa` field. There are many ways in which RISC-V ISA extension string can be represented, and listing them all is futile. In addition, custom extensions can be implemented, meaning every extension would have to be listed in the enum array as well. Signed-off-by: Filip Kokosinski --- dts/bindings/riscv/riscv,cpus.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dts/bindings/riscv/riscv,cpus.yaml b/dts/bindings/riscv/riscv,cpus.yaml index 961b54ca82d..883146d76b2 100644 --- a/dts/bindings/riscv/riscv,cpus.yaml +++ b/dts/bindings/riscv/riscv,cpus.yaml @@ -17,10 +17,3 @@ properties: description: RISC-V instruction set architecture required: true type: string - enum: - - rv32emc - - rv32imac - - rv32imafc - - rv32imafcb - - rv64imac - - rv64imafdc From 806c95163a404d3e3fbae299f8ce7ea8edf94870 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 5 Sep 2023 15:15:25 +0200 Subject: [PATCH 0416/4498] dts/riscv: add missing `riscv,isa` fields and modify existing ones This commit adds/modifies `riscv,isa` strings using the following rules: * the ISA string is lowercase * multi-letter extensions are preceded with the underscore mark * if an extension is implied by another one, it is not specified - e.g. the D extension implies the F extension, so writing `rv32ifd` is redundant Signed-off-by: Filip Kokosinski --- dts/bindings/cpu/espressif,riscv.yaml | 2 +- dts/bindings/cpu/intel,niosv.yaml | 2 +- dts/bindings/cpu/ite,riscv-ite.yaml | 2 +- dts/bindings/cpu/neorv32-cpu.yaml | 2 +- dts/bindings/cpu/nuclei,bumblebee.yaml | 2 +- dts/bindings/cpu/telink,b91.yaml | 2 +- dts/riscv/andes/andes_v5_ae350.dtsi | 16 ++++++++-------- dts/riscv/efinix/sapphire_soc.dtsi | 2 +- dts/riscv/espressif/esp32c3/esp32c3_common.dtsi | 1 + dts/riscv/gigadevice/gd32vf103.dtsi | 1 + dts/riscv/ite/it8xxx2.dtsi | 1 + dts/riscv/lowrisc/opentitan_earlgrey.dtsi | 2 +- dts/riscv/microchip/microchip-miv.dtsi | 2 +- dts/riscv/microchip/mpfs-icicle.dtsi | 10 +++++----- dts/riscv/neorv32.dtsi | 1 + dts/riscv/niosv/niosv-g.dtsi | 1 + dts/riscv/niosv/niosv-m.dtsi | 1 + dts/riscv/openisa/rv32m1.dtsi | 2 ++ dts/riscv/riscv32-litex-vexriscv.dtsi | 2 +- dts/riscv/sifive/riscv32-fe310.dtsi | 2 +- dts/riscv/sifive/riscv64-fu540.dtsi | 2 +- dts/riscv/sifive/riscv64-fu740.dtsi | 10 +++++----- dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi | 4 ++-- dts/riscv/telink/telink_b91.dtsi | 1 + 24 files changed, 41 insertions(+), 32 deletions(-) diff --git a/dts/bindings/cpu/espressif,riscv.yaml b/dts/bindings/cpu/espressif,riscv.yaml index 5894435c061..a93894cd946 100644 --- a/dts/bindings/cpu/espressif,riscv.yaml +++ b/dts/bindings/cpu/espressif,riscv.yaml @@ -5,7 +5,7 @@ description: Espressif RISC-V CPU compatible: "espressif,riscv" -include: cpu.yaml +include: riscv,cpus.yaml properties: clock-source: diff --git a/dts/bindings/cpu/intel,niosv.yaml b/dts/bindings/cpu/intel,niosv.yaml index ca032db1bb4..0eaac730d84 100644 --- a/dts/bindings/cpu/intel,niosv.yaml +++ b/dts/bindings/cpu/intel,niosv.yaml @@ -5,4 +5,4 @@ description: INTEL FPGA NIOSV Softcore Processor compatible: "intel,niosv" -include: cpu.yaml +include: riscv,cpus.yaml diff --git a/dts/bindings/cpu/ite,riscv-ite.yaml b/dts/bindings/cpu/ite,riscv-ite.yaml index 0f0651d059d..f358b0867ac 100644 --- a/dts/bindings/cpu/ite,riscv-ite.yaml +++ b/dts/bindings/cpu/ite,riscv-ite.yaml @@ -5,4 +5,4 @@ description: ITE IT8XXX2 RISC-V CPU compatible: "ite,riscv-ite" -include: cpu.yaml +include: riscv,cpus.yaml diff --git a/dts/bindings/cpu/neorv32-cpu.yaml b/dts/bindings/cpu/neorv32-cpu.yaml index 417ce963cee..b0983771e92 100644 --- a/dts/bindings/cpu/neorv32-cpu.yaml +++ b/dts/bindings/cpu/neorv32-cpu.yaml @@ -5,4 +5,4 @@ description: NEORV32 RISC-V CPU compatible: "neorv32-cpu" -include: cpu.yaml +include: riscv,cpus.yaml diff --git a/dts/bindings/cpu/nuclei,bumblebee.yaml b/dts/bindings/cpu/nuclei,bumblebee.yaml index 3e6c171b90f..8c9dfc7d35d 100644 --- a/dts/bindings/cpu/nuclei,bumblebee.yaml +++ b/dts/bindings/cpu/nuclei,bumblebee.yaml @@ -5,7 +5,7 @@ description: Nuclei Bumblebee RISC-V Core compatible: "nuclei,bumblebee" -include: cpu.yaml +include: riscv,cpus.yaml properties: mcause-exception-mask: diff --git a/dts/bindings/cpu/telink,b91.yaml b/dts/bindings/cpu/telink,b91.yaml index f70640234df..0b39cc85435 100644 --- a/dts/bindings/cpu/telink,b91.yaml +++ b/dts/bindings/cpu/telink,b91.yaml @@ -5,4 +5,4 @@ description: Telink RISC-V CPU compatible: "telink,b91" -include: cpu.yaml +include: riscv,cpus.yaml diff --git a/dts/riscv/andes/andes_v5_ae350.dtsi b/dts/riscv/andes/andes_v5_ae350.dtsi index 4a9456520a1..c102e3b6118 100644 --- a/dts/riscv/andes/andes_v5_ae350.dtsi +++ b/dts/riscv/andes/andes_v5_ae350.dtsi @@ -21,7 +21,7 @@ device_type = "cpu"; reg = <0>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -38,7 +38,7 @@ device_type = "cpu"; reg = <1>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -55,7 +55,7 @@ device_type = "cpu"; reg = <2>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -72,7 +72,7 @@ device_type = "cpu"; reg = <3>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -89,7 +89,7 @@ device_type = "cpu"; reg = <4>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -106,7 +106,7 @@ device_type = "cpu"; reg = <5>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -123,7 +123,7 @@ device_type = "cpu"; reg = <6>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; @@ -140,7 +140,7 @@ device_type = "cpu"; reg = <7>; status = "okay"; - riscv,isa = "rv32imafdcxandes"; + riscv,isa = "rv32gc_xandes"; mmu-type = "riscv,sv32"; clock-frequency = <60000000>; i-cache-line-size = <32>; diff --git a/dts/riscv/efinix/sapphire_soc.dtsi b/dts/riscv/efinix/sapphire_soc.dtsi index c61eec170ed..e6b2a98254b 100644 --- a/dts/riscv/efinix/sapphire_soc.dtsi +++ b/dts/riscv/efinix/sapphire_soc.dtsi @@ -30,7 +30,7 @@ compatible = "riscv"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv32imac"; + riscv,isa = "rv32ima_zicsr_zifencei"; status = "okay"; timebase-frequency = <100000000>; diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 10fc17ac03a..19e621e528f 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -32,6 +32,7 @@ cpu0: cpu@0 { device_type = "cpu"; compatible = "espressif,riscv"; + riscv,isa = "rv32imc_zicsr"; reg = <0>; cpu-power-states = <&light_sleep &deep_sleep>; }; diff --git a/dts/riscv/gigadevice/gd32vf103.dtsi b/dts/riscv/gigadevice/gd32vf103.dtsi index d4b5bb46d8a..c9f37db5180 100644 --- a/dts/riscv/gigadevice/gd32vf103.dtsi +++ b/dts/riscv/gigadevice/gd32vf103.dtsi @@ -25,6 +25,7 @@ clock-frequency = ; mcause-exception-mask = <0x7ff>; compatible = "nuclei,bumblebee"; + riscv,isa = "rv32imac_zicsr_zifencei"; reg = <0>; }; }; diff --git a/dts/riscv/ite/it8xxx2.dtsi b/dts/riscv/ite/it8xxx2.dtsi index c0e5933346d..84f551a5015 100644 --- a/dts/riscv/ite/it8xxx2.dtsi +++ b/dts/riscv/ite/it8xxx2.dtsi @@ -29,6 +29,7 @@ #size-cells = <0>; cpu0: cpu@0 { compatible = "ite,riscv-ite"; + riscv,isa = "rv32imafc_zifencei"; device_type = "cpu"; reg = <0>; cpu-power-states = <&standby>; diff --git a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi index 55171ec2a57..1b86ed2af62 100644 --- a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi +++ b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi @@ -19,7 +19,7 @@ reg = <0x00>; status = "okay"; compatible = "riscv"; - riscv,isa = "rv32imc"; + riscv,isa = "rv32imcb_zicsr_zifencei"; hlic: interrupt-controller { #interrupt-cells = <0x01>; diff --git a/dts/riscv/microchip/microchip-miv.dtsi b/dts/riscv/microchip/microchip-miv.dtsi index 5ef8b3a4931..56060baa8f2 100644 --- a/dts/riscv/microchip/microchip-miv.dtsi +++ b/dts/riscv/microchip/microchip-miv.dtsi @@ -16,7 +16,7 @@ compatible = "microchip,miv", "riscv"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv32imac"; + riscv,isa = "rv32ima_zicsr_zifencei"; hlic: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; diff --git a/dts/riscv/microchip/mpfs-icicle.dtsi b/dts/riscv/microchip/mpfs-icicle.dtsi index 9c1d25161b5..76b0320c55e 100644 --- a/dts/riscv/microchip/mpfs-icicle.dtsi +++ b/dts/riscv/microchip/mpfs-icicle.dtsi @@ -19,7 +19,7 @@ compatible = "riscv"; device_type = "cpu"; reg = < 0x0 >; - riscv,isa = "rv64imac"; + riscv,isa = "rv64imac_zicsr_zfencei"; hlic0: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; @@ -33,7 +33,7 @@ compatible = "riscv"; device_type = "cpu"; reg = < 0x1 >; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; hlic1: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; @@ -47,7 +47,7 @@ compatible = "riscv"; device_type = "cpu"; reg = < 0x2 >; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; hlic2: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; @@ -61,7 +61,7 @@ compatible = "riscv"; device_type = "cpu"; reg = < 0x3 >; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; hlic3: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; @@ -75,7 +75,7 @@ compatible = "riscv"; device_type = "cpu"; reg = < 0x4 >; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; hlic4: interrupt-controller { compatible = "riscv,cpu-intc"; #address-cells = <0>; diff --git a/dts/riscv/neorv32.dtsi b/dts/riscv/neorv32.dtsi index aa5243883bb..429d4372418 100644 --- a/dts/riscv/neorv32.dtsi +++ b/dts/riscv/neorv32.dtsi @@ -20,6 +20,7 @@ cpu0: cpu@0 { compatible = "neorv32-cpu"; + riscv,isa = "rv32imc_zicsr"; reg = <0>; device_type = "cpu"; diff --git a/dts/riscv/niosv/niosv-g.dtsi b/dts/riscv/niosv/niosv-g.dtsi index 587528a8972..2b733f5e803 100644 --- a/dts/riscv/niosv/niosv-g.dtsi +++ b/dts/riscv/niosv/niosv-g.dtsi @@ -18,6 +18,7 @@ cpu0: cpu@0 { device_type = "cpu"; compatible = "intel,niosv"; + riscv,isa = "rv32ima_zicsr_zifencei"; reg = <0>; clock-frequency = <50000000>; diff --git a/dts/riscv/niosv/niosv-m.dtsi b/dts/riscv/niosv/niosv-m.dtsi index 8ffc6f92f7a..aad9cbdeb78 100644 --- a/dts/riscv/niosv/niosv-m.dtsi +++ b/dts/riscv/niosv/niosv-m.dtsi @@ -18,6 +18,7 @@ cpu0: cpu@0 { device_type = "cpu"; compatible = "intel,niosv"; + riscv,isa = "rv32ia_zicsr_zifencei"; reg = <0>; clock-frequency = <50000000>; diff --git a/dts/riscv/openisa/rv32m1.dtsi b/dts/riscv/openisa/rv32m1.dtsi index 94f121658b9..567a6959f1f 100644 --- a/dts/riscv/openisa/rv32m1.dtsi +++ b/dts/riscv/openisa/rv32m1.dtsi @@ -23,12 +23,14 @@ cpu@0 { device_type = "cpu"; compatible = "riscv"; + riscv,isa = "rv32ima_zicsr_zifencei"; reg = <0>; }; cpu@1 { device_type = "cpu"; compatible = "riscv"; + riscv,isa = "rv32ima_zicsr_zifencei"; reg = <1>; }; }; diff --git a/dts/riscv/riscv32-litex-vexriscv.dtsi b/dts/riscv/riscv32-litex-vexriscv.dtsi index e1cff9f488f..3eefacccf6d 100644 --- a/dts/riscv/riscv32-litex-vexriscv.dtsi +++ b/dts/riscv/riscv32-litex-vexriscv.dtsi @@ -23,7 +23,7 @@ compatible = "riscv"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv32imac"; + riscv,isa = "rv32ima_zicsr_zifencei"; status = "okay"; timebase-frequency = <32768>; }; diff --git a/dts/riscv/sifive/riscv32-fe310.dtsi b/dts/riscv/sifive/riscv32-fe310.dtsi index 597a4421121..2a4f9424e81 100644 --- a/dts/riscv/sifive/riscv32-fe310.dtsi +++ b/dts/riscv/sifive/riscv32-fe310.dtsi @@ -30,7 +30,7 @@ compatible = "sifive,e31"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv32imac"; + riscv,isa = "rv32imac_zicsr_zifencei"; status = "okay"; hlic: interrupt-controller { compatible = "riscv,cpu-intc"; diff --git a/dts/riscv/sifive/riscv64-fu540.dtsi b/dts/riscv/sifive/riscv64-fu540.dtsi index 5024743d1c3..a71a68fdb17 100644 --- a/dts/riscv/sifive/riscv64-fu540.dtsi +++ b/dts/riscv/sifive/riscv64-fu540.dtsi @@ -36,7 +36,7 @@ compatible = "sifive,e51"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv64imac"; + riscv,isa = "rv64imac_zicsr_zifencei"; status = "okay"; hlic: interrupt-controller { diff --git a/dts/riscv/sifive/riscv64-fu740.dtsi b/dts/riscv/sifive/riscv64-fu740.dtsi index c8ac2a9d988..9a2c5b62ffd 100644 --- a/dts/riscv/sifive/riscv64-fu740.dtsi +++ b/dts/riscv/sifive/riscv64-fu740.dtsi @@ -35,7 +35,7 @@ compatible = "sifive,s7"; device_type = "cpu"; reg = <0>; - riscv,isa = "rv64imac"; + riscv,isa = "rv64imac_zicsr_zifencei"; status = "okay"; hlic: interrupt-controller { @@ -50,7 +50,7 @@ device_type = "cpu"; mmu-type = "riscv,sv39"; reg = <0x1>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; cpu1_intc: interrupt-controller { compatible = "riscv,cpu-intc"; @@ -63,7 +63,7 @@ device_type = "cpu"; mmu-type = "riscv,sv39"; reg = <0x2>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; cpu2_intc: interrupt-controller { compatible = "riscv,cpu-intc"; @@ -76,7 +76,7 @@ device_type = "cpu"; mmu-type = "riscv,sv39"; reg = <0x3>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; cpu3_intc: interrupt-controller { compatible = "riscv,cpu-intc"; @@ -89,7 +89,7 @@ device_type = "cpu"; mmu-type = "riscv,sv39"; reg = <0x4>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; cpu4_intc: interrupt-controller { compatible = "riscv,cpu-intc"; diff --git a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi index 39382568adf..445a1534c5b 100644 --- a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi +++ b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi @@ -35,7 +35,7 @@ mmu-type = "riscv,sv39"; next-level-cache = <&cachectrl>; reg = <0>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; starfive,itim = <&itim0>; status = "okay"; tlb-split; @@ -64,7 +64,7 @@ mmu-type = "riscv,sv39"; next-level-cache = <&cachectrl>; reg = <1>; - riscv,isa = "rv64imafdc"; + riscv,isa = "rv64gc"; starfive,itim = <&itim1>; status = "okay"; tlb-split; diff --git a/dts/riscv/telink/telink_b91.dtsi b/dts/riscv/telink/telink_b91.dtsi index 23ebf5bb4c4..85ffbf6f57f 100644 --- a/dts/riscv/telink/telink_b91.dtsi +++ b/dts/riscv/telink/telink_b91.dtsi @@ -23,6 +23,7 @@ reg = <0>; clock-frequency = <24000000>; compatible ="telink,b91", "riscv"; + riscv,isa = "rv32imac_zicsr_zifencei"; }; }; From 1c7a6e2679cfd50072d7f1f97024588df55f3144 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 13 Sep 2023 13:01:35 +0200 Subject: [PATCH 0417/4498] board nrf52_bsim: Fix build warning with clang Fix a build warning with clang due to an implicit cast. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/common/phy_sync_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/posix/nrf52_bsim/common/phy_sync_ctrl.c b/boards/posix/nrf52_bsim/common/phy_sync_ctrl.c index 8a03fd797ae..fc4a7992837 100644 --- a/boards/posix/nrf52_bsim/common/phy_sync_ctrl.c +++ b/boards/posix/nrf52_bsim/common/phy_sync_ctrl.c @@ -23,7 +23,7 @@ static struct { double start_offset; - double max_resync_offset; + bs_time_t max_resync_offset; bool delay_init; bool sync_preinit; bool sync_preboot; From 24a2b6b004aca4f818d28afe1763179c6471dbf7 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Wed, 13 Sep 2023 20:04:46 +0200 Subject: [PATCH 0418/4498] drivers: rtc: stm32: fix build warning Use a mem_addr_t cast to avoid build warning. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 047fde9188b..66c277aa43f 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -349,7 +349,7 @@ static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibrat { ARG_UNUSED(dev); - uint32_t calr = sys_read32(&RTC->CALR); + uint32_t calr = sys_read32((mem_addr_t) &RTC->CALR); bool calp_enabled = READ_BIT(calr, RTC_CALR_CALP); uint32_t calm = READ_BIT(calr, RTC_CALR_CALM); From 9ae9ee7ec43418e70ce111e5ad5a9415c8d507ae Mon Sep 17 00:00:00 2001 From: Andrew Sonzogni Date: Thu, 14 Sep 2023 10:14:57 +0200 Subject: [PATCH 0419/4498] drivers: flash: stm32: change undefined variable causing build error Replace an undefined variable. Signed-off-by: Andrew Sonzogni --- drivers/flash/flash_stm32g0x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/flash_stm32g0x.c b/drivers/flash/flash_stm32g0x.c index 07eea9ce32b..41a0e1da3bf 100644 --- a/drivers/flash/flash_stm32g0x.c +++ b/drivers/flash/flash_stm32g0x.c @@ -231,7 +231,7 @@ int flash_stm32_check_configuration(void) { #if defined(STM32G0_DBANK_SUPPORT) && (CONFIG_FLASH_SIZE == 256) /* Single bank mode not supported on dual bank SoCs with 256kiB flash */ - if ((regs->OPTR & FLASH_OPTR_DUAL_BANK) == 0) { + if ((FLASH->OPTR & FLASH_OPTR_DUAL_BANK) == 0) { LOG_ERR("Single bank configuration not supported by the driver"); return -ENOTSUP; } From 3f585f527b8b613ed6302412f9b0751015411e4c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 14 Sep 2023 10:22:43 +0200 Subject: [PATCH 0420/4498] Bluetooth: Host: Add additional logging for bt_conn_exists_le The bt_conn_exists_le is commonly hit by users attempting to connect (either as central or peripheral) to a device they are already connected to in some way. The current log statement does not provide particularly much information, so added more. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/conn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 5e69c8006c9..93cd6a47d95 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -28,6 +28,7 @@ #include #include "common/assert.h" +#include "common/bt_str.h" #include "addr_internal.h" #include "hci_core.h" @@ -2367,7 +2368,8 @@ bool bt_conn_exists_le(uint8_t id, const bt_addr_le_t *peer) * still has valid references. The last reference of the stack * is released after the disconnected callback. */ - LOG_WRN("Found valid connection in %s state", state2str(conn->state)); + LOG_WRN("Found valid connection (%p) with address %s in %s state ", conn, + bt_addr_le_str(peer), state2str(conn->state)); bt_conn_unref(conn); return true; } From 815891643edc44944b3cc9e5834a4180ad914c6b Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Tue, 18 Jul 2023 16:44:24 +0100 Subject: [PATCH 0421/4498] Bluetooth: Host: Pass pointer to server in L2CAP accept() callback Add a pointer to the associated server structure in the L2CAP accept() callback. This allows the callee to know which server an incoming L2CAP connection is associated with. Signed-off-by: Donatien Garnier --- include/zephyr/bluetooth/l2cap.h | 4 +++- subsys/bluetooth/host/att.c | 3 ++- subsys/bluetooth/host/avdtp.c | 3 ++- subsys/bluetooth/host/l2cap.c | 2 +- subsys/bluetooth/host/l2cap_br.c | 2 +- subsys/bluetooth/host/rfcomm.c | 3 ++- subsys/bluetooth/host/sdp.c | 3 ++- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/zephyr/bluetooth/l2cap.h b/include/zephyr/bluetooth/l2cap.h index 5c23a05ec7d..34d1f2dc2ab 100644 --- a/include/zephyr/bluetooth/l2cap.h +++ b/include/zephyr/bluetooth/l2cap.h @@ -453,6 +453,7 @@ struct bt_l2cap_server { * authorization. * * @param conn The connection that is requesting authorization + * @param server Pointer to the server structure this callback relates to * @param chan Pointer to received the allocated channel * * @return 0 in case of success or negative value in case of error. @@ -460,7 +461,8 @@ struct bt_l2cap_server { * @return -EACCES if application did not authorize the connection. * @return -EPERM if encryption key size is too short. */ - int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); + int (*accept)(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan); sys_snode_t node; }; diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index d2c41eaa928..bea0fffaa8d 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -3723,7 +3723,8 @@ int bt_eatt_reconfigure(struct bt_conn *conn, uint16_t mtu) #endif /* CONFIG_BT_TESTING */ #endif /* CONFIG_BT_EATT */ -static int bt_eatt_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int bt_eatt_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_att_chan *att_chan = att_get_fixed_chan(conn); struct bt_att *att = att_chan->att; diff --git a/subsys/bluetooth/host/avdtp.c b/subsys/bluetooth/host/avdtp.c index ce4854507be..62409937514 100644 --- a/subsys/bluetooth/host/avdtp.c +++ b/subsys/bluetooth/host/avdtp.c @@ -220,7 +220,8 @@ int bt_avdtp_disconnect(struct bt_avdtp *session) return bt_l2cap_chan_disconnect(&session->br_chan.chan); } -int bt_avdtp_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +int bt_avdtp_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_avdtp *session = NULL; int result; diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 2af255a622e..e6fbe2144f8 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -1048,7 +1048,7 @@ static uint16_t l2cap_chan_accept(struct bt_conn *conn, /* Request server to accept the new connection and allocate the * channel. */ - err = server->accept(conn, chan); + err = server->accept(conn, server, chan); if (err < 0) { return le_err_to_result(err); } diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index 676fbf0a344..e9a10ff8d72 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -747,7 +747,7 @@ static void l2cap_br_conn_req(struct bt_l2cap_br *l2cap, uint8_t ident, * channel. If no free channels available for PSM server reply with * proper result and quit since chan pointer is uninitialized then. */ - if (server->accept(conn, &chan) < 0) { + if (server->accept(conn, server, &chan) < 0) { result = BT_L2CAP_BR_ERR_NO_RESOURCES; goto no_chan; } diff --git a/subsys/bluetooth/host/rfcomm.c b/subsys/bluetooth/host/rfcomm.c index 8682db1c254..21b0e45e13a 100644 --- a/subsys/bluetooth/host/rfcomm.c +++ b/subsys/bluetooth/host/rfcomm.c @@ -1704,7 +1704,8 @@ int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc) return rfcomm_dlc_close(dlc); } -static int rfcomm_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int rfcomm_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_rfcomm_session *session; diff --git a/subsys/bluetooth/host/sdp.c b/subsys/bluetooth/host/sdp.c index ae20b5dfa79..bd36187d43c 100644 --- a/subsys/bluetooth/host/sdp.c +++ b/subsys/bluetooth/host/sdp.c @@ -1389,7 +1389,8 @@ static int bt_sdp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) * * @return 0 for success, or relevant error code */ -static int bt_sdp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int bt_sdp_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { static const struct bt_l2cap_chan_ops ops = { .connected = bt_sdp_connected, From 185a6117c084ff49fece33611ab82363ab1f8780 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Tue, 18 Jul 2023 17:37:56 +0000 Subject: [PATCH 0422/4498] Bluetooth: Host: Amend existing L2CAP accept callbacks This patch amends the existing L2CAP accept callbacks to use the new accept signature that includes a pointer to the L2CAP server structure. Signed-off-by: Donatien Garnier --- subsys/bluetooth/services/ots/ots_l2cap.c | 3 ++- subsys/bluetooth/shell/bredr.c | 3 ++- subsys/bluetooth/shell/l2cap.c | 3 ++- subsys/net/l2/bluetooth/bluetooth.c | 3 ++- tests/bluetooth/l2cap/src/main.c | 3 ++- tests/bluetooth/tester/src/btp_l2cap.c | 3 ++- tests/bsim/bluetooth/host/l2cap/credits/src/main.c | 3 ++- tests/bsim/bluetooth/host/l2cap/credits_seg_recv/src/main.c | 3 ++- tests/bsim/bluetooth/host/l2cap/general/src/main_l2cap_ecred.c | 3 ++- .../l2cap/send_on_connect/src/main_l2cap_send_on_connect.c | 3 ++- tests/bsim/bluetooth/host/l2cap/split/dut/src/main.c | 3 ++- tests/bsim/bluetooth/host/l2cap/stress/src/main.c | 3 ++- .../bluetooth/host/l2cap/userdata/src/main_l2cap_userdata.c | 3 ++- 13 files changed, 26 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/services/ots/ots_l2cap.c b/subsys/bluetooth/services/ots/ots_l2cap.c index 137829b7d03..923f2c8a593 100644 --- a/subsys/bluetooth/services/ots/ots_l2cap.c +++ b/subsys/bluetooth/services/ots/ots_l2cap.c @@ -187,7 +187,8 @@ static struct bt_gatt_ots_l2cap *find_free_l2cap_ctx(void) return NULL; } -static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_gatt_ots_l2cap *l2cap_ctx; diff --git a/subsys/bluetooth/shell/bredr.c b/subsys/bluetooth/shell/bredr.c index 3e96676a7fe..167aaf91a47 100644 --- a/subsys/bluetooth/shell/bredr.c +++ b/subsys/bluetooth/shell/bredr.c @@ -243,7 +243,8 @@ static struct bt_l2cap_br_chan l2cap_chan = { .rx.mtu = 48, }; -static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { shell_print(ctx_shell, "Incoming BR/EDR conn %p", conn); diff --git a/subsys/bluetooth/shell/l2cap.c b/subsys/bluetooth/shell/l2cap.c index 31bf94ffed2..fe594fb0127 100644 --- a/subsys/bluetooth/shell/l2cap.c +++ b/subsys/bluetooth/shell/l2cap.c @@ -212,7 +212,8 @@ static int l2cap_accept_policy(struct bt_conn *conn) return 0; } -static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { int err; diff --git a/subsys/net/l2/bluetooth/bluetooth.c b/subsys/net/l2/bluetooth/bluetooth.c index 8879c085425..8e7685c550f 100644 --- a/subsys/net/l2/bluetooth/bluetooth.c +++ b/subsys/net/l2/bluetooth/bluetooth.c @@ -315,7 +315,8 @@ static struct net_if_api bt_if_api = { .init = bt_iface_init, }; -static int ipsp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int ipsp_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_if_conn *if_conn = NULL; int i; diff --git a/tests/bluetooth/l2cap/src/main.c b/tests/bluetooth/l2cap/src/main.c index 029b5f90287..165c5cc7fa7 100644 --- a/tests/bluetooth/l2cap/src/main.c +++ b/tests/bluetooth/l2cap/src/main.c @@ -14,7 +14,8 @@ #include #include -static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { return -ENOSYS; } diff --git a/tests/bluetooth/tester/src/btp_l2cap.c b/tests/bluetooth/tester/src/btp_l2cap.c index 0ed01cf5087..ff78fa9ad55 100644 --- a/tests/bluetooth/tester/src/btp_l2cap.c +++ b/tests/bluetooth/tester/src/btp_l2cap.c @@ -433,7 +433,8 @@ static bool is_free_psm(uint16_t psm) return true; } -static int accept(struct bt_conn *conn, struct bt_l2cap_chan **l2cap_chan) +static int accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **l2cap_chan) { struct channel *chan; diff --git a/tests/bsim/bluetooth/host/l2cap/credits/src/main.c b/tests/bsim/bluetooth/host/l2cap/credits/src/main.c index ea44dbccd67..570693ae98b 100644 --- a/tests/bsim/bluetooth/host/l2cap/credits/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/credits/src/main.c @@ -135,7 +135,8 @@ static struct bt_l2cap_chan_ops ops = { .sent = sent_cb, }; -int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_chan **chan) +int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_l2cap_le_chan *le_chan = &test_ctx.le_chan; diff --git a/tests/bsim/bluetooth/host/l2cap/credits_seg_recv/src/main.c b/tests/bsim/bluetooth/host/l2cap/credits_seg_recv/src/main.c index 3f941851a21..deead1a8b10 100644 --- a/tests/bsim/bluetooth/host/l2cap/credits_seg_recv/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/credits_seg_recv/src/main.c @@ -141,7 +141,8 @@ static struct bt_l2cap_chan_ops ops = { .sent = sent_cb, }; -int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_chan **chan) +int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_l2cap_le_chan *le_chan = &test_ctx.le_chan; diff --git a/tests/bsim/bluetooth/host/l2cap/general/src/main_l2cap_ecred.c b/tests/bsim/bluetooth/host/l2cap/general/src/main_l2cap_ecred.c index e7f6589bef6..d89e71d327f 100644 --- a/tests/bsim/bluetooth/host/l2cap/general/src/main_l2cap_ecred.c +++ b/tests/bsim/bluetooth/host/l2cap/general/src/main_l2cap_ecred.c @@ -261,7 +261,8 @@ static void disconnect_all_channels(void) } } -static int accept(struct bt_conn *conn, struct bt_l2cap_chan **l2cap_chan) +static int accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **l2cap_chan) { struct channel *chan; diff --git a/tests/bsim/bluetooth/host/l2cap/send_on_connect/src/main_l2cap_send_on_connect.c b/tests/bsim/bluetooth/host/l2cap/send_on_connect/src/main_l2cap_send_on_connect.c index b214928d036..485c97c11dc 100644 --- a/tests/bsim/bluetooth/host/l2cap/send_on_connect/src/main_l2cap_send_on_connect.c +++ b/tests/bsim/bluetooth/host/l2cap/send_on_connect/src/main_l2cap_send_on_connect.c @@ -75,7 +75,8 @@ static const struct bt_l2cap_chan_ops l2cap_ops = { static struct bt_l2cap_le_chan channel; -static int accept(struct bt_conn *conn, struct bt_l2cap_chan **l2cap_chan) +static int accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **l2cap_chan) { channel.chan.ops = &l2cap_ops; *l2cap_chan = &channel.chan; diff --git a/tests/bsim/bluetooth/host/l2cap/split/dut/src/main.c b/tests/bsim/bluetooth/host/l2cap/split/dut/src/main.c index db7a45dfa48..72818bee5c2 100644 --- a/tests/bsim/bluetooth/host/l2cap/split/dut/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/split/dut/src/main.c @@ -89,7 +89,8 @@ static struct bt_l2cap_chan_ops ops = { .sent = sent_cb, }; -int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_chan **chan) +int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct bt_l2cap_le_chan *le_chan = &test_chan; diff --git a/tests/bsim/bluetooth/host/l2cap/stress/src/main.c b/tests/bsim/bluetooth/host/l2cap/stress/src/main.c index 0af76643a34..244d69b7fa2 100644 --- a/tests/bsim/bluetooth/host/l2cap/stress/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/stress/src/main.c @@ -206,7 +206,8 @@ struct test_ctx *alloc_test_context(void) return NULL; } -int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_chan **chan) +int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **chan) { struct test_ctx *ctx = NULL; diff --git a/tests/bsim/bluetooth/host/l2cap/userdata/src/main_l2cap_userdata.c b/tests/bsim/bluetooth/host/l2cap/userdata/src/main_l2cap_userdata.c index 9230089dd95..46d1389dee9 100644 --- a/tests/bsim/bluetooth/host/l2cap/userdata/src/main_l2cap_userdata.c +++ b/tests/bsim/bluetooth/host/l2cap/userdata/src/main_l2cap_userdata.c @@ -48,7 +48,8 @@ static const struct bt_l2cap_chan_ops l2cap_ops = { static struct bt_l2cap_le_chan channel; -static int accept(struct bt_conn *conn, struct bt_l2cap_chan **l2cap_chan) +static int accept(struct bt_conn *conn, struct bt_l2cap_server *server, + struct bt_l2cap_chan **l2cap_chan) { channel.chan.ops = &l2cap_ops; *l2cap_chan = &channel.chan; From 30cd9a22cfda64690fc4aa6974e16c20288e3bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 19:51:25 +0200 Subject: [PATCH 0423/4498] doc: fs: samples: Use new Sphinx extension to document samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new code-sample directive and roles to document the filesystem samples so that they show up as "Related samples" when browsing the API documentation. Signed-off-by: Benjamin Cabé --- samples/subsys/fs/format/README.rst | 7 ++++--- samples/subsys/fs/fs_sample/README.rst | 7 ++++--- samples/subsys/fs/littlefs/README.rst | 7 ++++--- samples/subsys/shell/fs/README.rst | 2 +- samples/subsys/usb/mass/README.rst | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/samples/subsys/fs/format/README.rst b/samples/subsys/fs/format/README.rst index f42209fc2f2..20bcad1931a 100644 --- a/samples/subsys/fs/format/README.rst +++ b/samples/subsys/fs/format/README.rst @@ -1,7 +1,8 @@ -.. _fs_format_sample: +.. zephyr:code-sample:: fs-format + :name: Formatting + :relevant-api: file_system_api -FS Format Sample -################ + Format different storage devices for different file systems. Overview *********** diff --git a/samples/subsys/fs/fs_sample/README.rst b/samples/subsys/fs/fs_sample/README.rst index 6a441e201cd..e23cc1db7f9 100644 --- a/samples/subsys/fs/fs_sample/README.rst +++ b/samples/subsys/fs/fs_sample/README.rst @@ -1,7 +1,8 @@ -.. _fs_sample: +.. zephyr:code-sample:: fs + :name: Filesystem manipulation + :relevant-api: file_system_api disk_access_interface -Filesystems Sample Application -################################### + Use filesystem API with various filesystems and storage devices. Overview ******** diff --git a/samples/subsys/fs/littlefs/README.rst b/samples/subsys/fs/littlefs/README.rst index 948da3f635b..40911001dda 100644 --- a/samples/subsys/fs/littlefs/README.rst +++ b/samples/subsys/fs/littlefs/README.rst @@ -1,7 +1,8 @@ -.. _littlefs-sample: +.. zephyr:code-sample:: littlefs + :name: LittleFS filesystem + :relevant-api: file_system_api flash_area_api -littlefs File System Sample Application -####################################### + Use file system API over LittleFS. Overview ******** diff --git a/samples/subsys/shell/fs/README.rst b/samples/subsys/shell/fs/README.rst index 5482b2e050d..ec9d95364a7 100644 --- a/samples/subsys/shell/fs/README.rst +++ b/samples/subsys/shell/fs/README.rst @@ -48,7 +48,7 @@ Particle Xenon ============== This target is customized to support the same SPI NOR partition table as -the :ref:`littlefs-sample`. +the :zephyr:code-sample:`littlefs` sample. .. zephyr-app-commands:: :zephyr-app: samples/subsys/shell/fs diff --git a/samples/subsys/usb/mass/README.rst b/samples/subsys/usb/mass/README.rst index 82a252061c8..75d6f2f388a 100644 --- a/samples/subsys/usb/mass/README.rst +++ b/samples/subsys/usb/mass/README.rst @@ -157,7 +157,7 @@ LittleFS Example This board configures to use the external 64 MiBi QSPI flash chip with a 128 KiBy `littlefs`_ partition compatible with the one produced by the -:ref:`littlefs-sample`. +:zephyr:code-sample:`littlefs` sample. .. zephyr-app-commands:: :zephyr-app: samples/subsys/usb/mass From c3bb1b3c6d7ca679b754650ec27fca6498c08408 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 12 Jul 2023 13:39:00 +0200 Subject: [PATCH 0424/4498] dts: bindings: adc: add MAX11102-MAX11117 Add bindings for the following ADCs: - MAX11102 - MAX11103 - MAX11105 - MAX11106 - MAX11110 - MAX11111 - MAX11115 - MAX11116 - MAX11117 Signed-off-by: Benedikt Schmidt --- dts/bindings/adc/maxim,max11102-17-base.yaml | 11 +++++++++++ dts/bindings/adc/maxim,max11102.yaml | 13 +++++++++++++ dts/bindings/adc/maxim,max11103.yaml | 13 +++++++++++++ dts/bindings/adc/maxim,max11105.yaml | 8 ++++++++ dts/bindings/adc/maxim,max11106.yaml | 13 +++++++++++++ dts/bindings/adc/maxim,max11110.yaml | 8 ++++++++ dts/bindings/adc/maxim,max11111.yaml | 13 +++++++++++++ dts/bindings/adc/maxim,max11115.yaml | 8 ++++++++ dts/bindings/adc/maxim,max11116.yaml | 8 ++++++++ dts/bindings/adc/maxim,max11117.yaml | 8 ++++++++ 10 files changed, 103 insertions(+) create mode 100644 dts/bindings/adc/maxim,max11102-17-base.yaml create mode 100644 dts/bindings/adc/maxim,max11102.yaml create mode 100644 dts/bindings/adc/maxim,max11103.yaml create mode 100644 dts/bindings/adc/maxim,max11105.yaml create mode 100644 dts/bindings/adc/maxim,max11106.yaml create mode 100644 dts/bindings/adc/maxim,max11110.yaml create mode 100644 dts/bindings/adc/maxim,max11111.yaml create mode 100644 dts/bindings/adc/maxim,max11115.yaml create mode 100644 dts/bindings/adc/maxim,max11116.yaml create mode 100644 dts/bindings/adc/maxim,max11117.yaml diff --git a/dts/bindings/adc/maxim,max11102-17-base.yaml b/dts/bindings/adc/maxim,max11102-17-base.yaml new file mode 100644 index 00000000000..1a129d7f8cc --- /dev/null +++ b/dts/bindings/adc/maxim,max11102-17-base.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +include: [adc-controller.yaml, spi-device.yaml] + +properties: + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/bindings/adc/maxim,max11102.yaml b/dts/bindings/adc/maxim,max11102.yaml new file mode 100644 index 00000000000..78016a6e9fb --- /dev/null +++ b/dts/bindings/adc/maxim,max11102.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 2 channels 12 bit 2 Msps SPI ADC + +compatible: "maxim,max11102" + +include: maxim,max11102-17-base.yaml + +properties: + chsel-gpios: + type: phandle-array + description: "GPIO for channel selection" diff --git a/dts/bindings/adc/maxim,max11103.yaml b/dts/bindings/adc/maxim,max11103.yaml new file mode 100644 index 00000000000..3438cede85e --- /dev/null +++ b/dts/bindings/adc/maxim,max11103.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 2 channels 12 bit 3 Msps SPI ADC + +compatible: "maxim,max11103" + +include: maxim,max11102-17-base.yaml + +properties: + chsel-gpios: + type: phandle-array + description: "GPIO for channel selection" diff --git a/dts/bindings/adc/maxim,max11105.yaml b/dts/bindings/adc/maxim,max11105.yaml new file mode 100644 index 00000000000..467886b5071 --- /dev/null +++ b/dts/bindings/adc/maxim,max11105.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 1 channel 12 bit 2 Msps SPI ADC + +compatible: "maxim,max11105" + +include: maxim,max11102-17-base.yaml diff --git a/dts/bindings/adc/maxim,max11106.yaml b/dts/bindings/adc/maxim,max11106.yaml new file mode 100644 index 00000000000..75ca22f661e --- /dev/null +++ b/dts/bindings/adc/maxim,max11106.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 2 channels 10 bit 3 Msps SPI ADC + +compatible: "maxim,max11106" + +include: maxim,max11102-17-base.yaml + +properties: + chsel-gpios: + type: phandle-array + description: "GPIO for channel selection" diff --git a/dts/bindings/adc/maxim,max11110.yaml b/dts/bindings/adc/maxim,max11110.yaml new file mode 100644 index 00000000000..ec07b358b53 --- /dev/null +++ b/dts/bindings/adc/maxim,max11110.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 1 channel 10 bit 2 Msps SPI ADC + +compatible: "maxim,max11110" + +include: maxim,max11102-17-base.yaml diff --git a/dts/bindings/adc/maxim,max11111.yaml b/dts/bindings/adc/maxim,max11111.yaml new file mode 100644 index 00000000000..e00a075ba51 --- /dev/null +++ b/dts/bindings/adc/maxim,max11111.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 2 channels 8 bit 3 Msps SPI ADC + +compatible: "maxim,max11111" + +include: maxim,max11102-17-base.yaml + +properties: + chsel-gpios: + type: phandle-array + description: "GPIO for channel selection" diff --git a/dts/bindings/adc/maxim,max11115.yaml b/dts/bindings/adc/maxim,max11115.yaml new file mode 100644 index 00000000000..a968931b748 --- /dev/null +++ b/dts/bindings/adc/maxim,max11115.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 1 channel 8 bit 2 Msps SPI ADC + +compatible: "maxim,max11115" + +include: maxim,max11102-17-base.yaml diff --git a/dts/bindings/adc/maxim,max11116.yaml b/dts/bindings/adc/maxim,max11116.yaml new file mode 100644 index 00000000000..c601f25d99e --- /dev/null +++ b/dts/bindings/adc/maxim,max11116.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 1 channel 8 bit 3 Msps SPI ADC + +compatible: "maxim,max11116" + +include: maxim,max11102-17-base.yaml diff --git a/dts/bindings/adc/maxim,max11117.yaml b/dts/bindings/adc/maxim,max11117.yaml new file mode 100644 index 00000000000..078ec527aa1 --- /dev/null +++ b/dts/bindings/adc/maxim,max11117.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim Integrated 1 channel 10 bit 3 Msps SPI ADC + +compatible: "maxim,max11117" + +include: maxim,max11102-17-base.yaml From 666520b8b6680b5ca7e22198dabb72feecd4477f Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 2 Aug 2023 16:54:26 +0200 Subject: [PATCH 0425/4498] drivers: adc: add driver for MAX11102-MAX11117 Add a driver for the following ADCs: - MAX11102 - MAX11103 - MAX11105 - MAX11106 - MAX11110 - MAX11111 - MAX11115 - MAX11116 - MAX11117 Signed-off-by: Benedikt Schmidt --- drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig | 2 + drivers/adc/Kconfig.max11102_17 | 32 +++ drivers/adc/adc_max11102_17.c | 475 ++++++++++++++++++++++++++++++++ 4 files changed, 510 insertions(+) create mode 100644 drivers/adc/Kconfig.max11102_17 create mode 100644 drivers/adc/adc_max11102_17.c diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index ee426090d3f..a22af9a5336 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -45,3 +45,4 @@ zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_SDADC adc_smartbond_sdadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_TLA2021 adc_tla2021.c) zephyr_library_sources_ifdef(CONFIG_ADC_NXP_S32_ADC_SAR adc_nxp_s32_adc_sar.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX1125X adc_max1125x.c) +zephyr_library_sources_ifdef(CONFIG_ADC_MAX11102_17 adc_max11102_17.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index eb9e03041a9..32cf7601e8d 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -114,4 +114,6 @@ source "drivers/adc/Kconfig.nxp_s32" source "drivers/adc/Kconfig.max1125x" +source "drivers/adc/Kconfig.max11102_17" + endif # ADC diff --git a/drivers/adc/Kconfig.max11102_17 b/drivers/adc/Kconfig.max11102_17 new file mode 100644 index 00000000000..6fcd8add11e --- /dev/null +++ b/drivers/adc/Kconfig.max11102_17 @@ -0,0 +1,32 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ADC_MAX11102_17 + bool "Maxim Integrated MAX11102-MAX11117" + default y + depends on DT_HAS_MAXIM_MAX11102_ENABLED \ + || DT_HAS_MAXIM_MAX11103_ENABLED \ + || DT_HAS_MAXIM_MAX11105_ENABLED \ + || DT_HAS_MAXIM_MAX11106_ENABLED \ + || DT_HAS_MAXIM_MAX11110_ENABLED \ + || DT_HAS_MAXIM_MAX11111_ENABLED \ + || DT_HAS_MAXIM_MAX11115_ENABLED \ + || DT_HAS_MAXIM_MAX11116_ENABLED \ + || DT_HAS_MAXIM_MAX11117_ENABLED + select SPI + help + Enable the driver implementation for the MAX11102-MAX11117 family + +config ADC_MAX11102_17_ACQUISITION_THREAD_INIT_PRIO + int "ADC data acquisition thread priority" + default 0 + depends on ADC_MAX11102_17 && ADC_ASYNC + +config ADC_MAX11102_17_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the ADC data acquisition thread" + default 400 + depends on ADC_MAX11102_17 && ADC_ASYNC + help + Size of the stack used for the internal data acquisition + thread. diff --git a/drivers/adc/adc_max11102_17.c b/drivers/adc/adc_max11102_17.c new file mode 100644 index 00000000000..fa87ce7c55e --- /dev/null +++ b/drivers/adc/adc_max11102_17.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER 1 +#include "adc_context.h" + +LOG_MODULE_REGISTER(max11102_17, CONFIG_ADC_LOG_LEVEL); + +struct max11102_17_config { + struct spi_dt_spec bus; + const struct gpio_dt_spec gpio_chsel; + uint8_t resolution; + uint8_t channel_count; +}; + +struct max11102_17_data { + struct adc_context ctx; + struct k_sem acquire_signal; + int16_t *buffer; + int16_t *buffer_ptr; + uint8_t current_channel_id; + uint8_t sequence_channel_id; +#if CONFIG_ADC_ASYNC + struct k_thread thread; + + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_STACK_SIZE); +#endif /* CONFIG_ADC_ASYNC */ +}; + +static int max11102_17_switch_channel(const struct device *dev) +{ + const struct max11102_17_config *config = dev->config; + struct max11102_17_data *data = dev->data; + int result; + uint8_t buffer_rx[1]; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + struct spi_dt_spec bus; + + memcpy(&bus, &config->bus, sizeof(bus)); + bus.config.operation |= SPI_HOLD_ON_CS; + + result = spi_read_dt(&bus, &rx); + if (result != 0) { + LOG_ERR("read failed with error %i", result); + return result; + } + + gpio_pin_set_dt(&config->gpio_chsel, data->current_channel_id); + + result = spi_read_dt(&config->bus, &rx); + if (result != 0) { + LOG_ERR("read failed with error %i", result); + return result; + } + + return 0; +} + +static int max11102_17_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + const struct max11102_17_config *config = dev->config; + + LOG_DBG("read from ADC channel %i", channel_cfg->channel_id); + + if (channel_cfg->reference != ADC_REF_EXTERNAL0) { + LOG_ERR("invalid reference %i", channel_cfg->reference); + return -EINVAL; + } + + if (channel_cfg->gain != ADC_GAIN_1) { + LOG_ERR("invalid gain %i", channel_cfg->gain); + return -EINVAL; + } + + if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { + LOG_ERR("invalid acquisition time %i", channel_cfg->acquisition_time); + return -EINVAL; + } + + if (channel_cfg->differential != 0) { + LOG_ERR("differential inputs are not supported"); + return -EINVAL; + } + + if (channel_cfg->channel_id > config->channel_count) { + LOG_ERR("invalid channel selection %i", channel_cfg->channel_id); + return -EINVAL; + } + + return 0; +} + +static int max11102_17_validate_buffer_size(const struct adc_sequence *sequence) +{ + size_t necessary = sizeof(int16_t); + + if (sequence->options) { + necessary *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < necessary) { + return -ENOMEM; + } + + return 0; +} + +static int max11102_17_validate_sequence(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct max11102_17_config *config = dev->config; + struct max11102_17_data *data = dev->data; + size_t sequence_channel_count = 0; + const size_t channel_maximum = 8*sizeof(sequence->channels); + + if (sequence->resolution != config->resolution) { + LOG_ERR("invalid resolution"); + return -EINVAL; + } + + for (size_t i = 0; i < channel_maximum; ++i) { + if ((BIT(i) & sequence->channels) == 0) { + continue; + } + + if (i > config->channel_count) { + LOG_ERR("invalid channel selection"); + return -EINVAL; + } + + sequence_channel_count++; + data->sequence_channel_id = i; + } + + if (sequence_channel_count == 0) { + LOG_ERR("no channel selected"); + return -EINVAL; + } + + if (sequence_channel_count > 1) { + LOG_ERR("multiple channels selected"); + return -EINVAL; + } + + if (sequence->oversampling) { + LOG_ERR("oversampling is not supported"); + return -EINVAL; + } + + return max11102_17_validate_buffer_size(sequence); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct max11102_17_data *data = CONTAINER_OF(ctx, struct max11102_17_data, ctx); + + if (repeat_sampling) { + data->buffer = data->buffer_ptr; + } +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct max11102_17_data *data = CONTAINER_OF(ctx, struct max11102_17_data, ctx); + + data->buffer_ptr = data->buffer; + k_sem_give(&data->acquire_signal); +} + +static int max11102_17_adc_start_read(const struct device *dev, const struct adc_sequence *sequence, + bool wait) +{ + int result; + struct max11102_17_data *data = dev->data; + + result = max11102_17_validate_sequence(dev, sequence); + + if (result != 0) { + LOG_ERR("sequence validation failed"); + return result; + } + + data->buffer = sequence->buffer; + + adc_context_start_read(&data->ctx, sequence); + + if (wait) { + result = adc_context_wait_for_completion(&data->ctx); + } + + return result; +} + +static int max11102_17_read_sample(const struct device *dev, int16_t *sample) +{ + const struct max11102_17_config *config = dev->config; + int result; + size_t trailing_bits = 15 - config->resolution; + uint8_t buffer_rx[2]; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + result = spi_read_dt(&config->bus, &rx); + + if (result != 0) { + LOG_ERR("read failed with error %i", result); + return result; + } + + *sample = sys_get_be16(buffer_rx); + LOG_DBG("raw sample: 0x%04X", *sample); + + *sample = *sample >> trailing_bits; + *sample = *sample & GENMASK(config->resolution, 0); + LOG_DBG("sample: 0x%04X", *sample); + + return 0; +} + +static int max11102_17_adc_perform_read(const struct device *dev) +{ + int result; + struct max11102_17_data *data = dev->data; + + k_sem_take(&data->acquire_signal, K_FOREVER); + + if (data->sequence_channel_id != data->current_channel_id) { + LOG_DBG("switch channel selection"); + data->current_channel_id = data->sequence_channel_id; + max11102_17_switch_channel(dev); + } + + result = max11102_17_read_sample(dev, data->buffer); + if (result != 0) { + LOG_ERR("reading sample failed"); + adc_context_complete(&data->ctx, result); + return result; + } + + data->buffer++; + + adc_context_on_sampling_done(&data->ctx, dev); + + return result; +} + +#if CONFIG_ADC_ASYNC +static int max11102_17_adc_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + int result; + struct max11102_17_data *data = dev->data; + + adc_context_lock(&data->ctx, true, async); + result = max11102_17_adc_start_read(dev, sequence, true); + adc_context_release(&data->ctx, result); + + return result; +} + +static int max11102_17_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int result; + struct max11102_17_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + result = max11102_17_adc_start_read(dev, sequence, true); + adc_context_release(&data->ctx, result); + + return result; +} + +#else +static int max11102_17_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int result; + struct max11102_17_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + result = max11102_17_adc_start_read(dev, sequence, false); + + while (result == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) { + result = max11102_17_adc_perform_read(dev); + } + + adc_context_release(&data->ctx, result); + return result; +} +#endif + +#if CONFIG_ADC_ASYNC +static void max11102_17_acquisition_thread(const struct device *dev) +{ + while (true) { + max11102_17_adc_perform_read(dev); + } +} +#endif + +static int max11102_17_init(const struct device *dev) +{ + int result; + const struct max11102_17_config *config = dev->config; + struct max11102_17_data *data = dev->data; + int16_t sample; + + adc_context_init(&data->ctx); + + k_sem_init(&data->acquire_signal, 0, 1); + + if (!spi_is_ready_dt(&config->bus)) { + LOG_ERR("SPI device is not ready"); + return -ENODEV; + } + + switch (config->channel_count) { + case 1: + if (config->gpio_chsel.port != NULL) { + LOG_ERR("GPIO for chsel set with only one channel"); + return -EINVAL; + } + break; + case 2: + if (config->gpio_chsel.port == NULL) { + LOG_ERR("no GPIO for chsel set with two channels"); + return -EINVAL; + } + + result = gpio_pin_configure_dt(&config->gpio_chsel, GPIO_OUTPUT_INACTIVE); + if (result != 0) { + LOG_ERR("failed to initialize GPIO for chsel"); + return result; + } + break; + default: + LOG_ERR("invalid number of channels (%i)", config->channel_count); + return -EINVAL; + } + + data->current_channel_id = 0; + +#if CONFIG_ADC_ASYNC + const k_tid_t tid = k_thread_create( + &data->thread, data->stack, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_STACK_SIZE, + (k_thread_entry_t)max11102_17_acquisition_thread, (void *)dev, NULL, NULL, + CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_INIT_PRIO, 0, K_NO_WAIT); + k_thread_name_set(tid, "adc_max11102_17"); +#endif + + /* power up time is one conversion cycle */ + result = max11102_17_read_sample(dev, &sample); + if (result != 0) { + LOG_ERR("unable to read dummy sample for power up timing"); + return result; + } + + adc_context_unlock_unconditionally(&data->ctx); + + return result; +} + +static const struct adc_driver_api api = { + .channel_setup = max11102_17_channel_setup, + .read = max11102_17_read, + .ref_internal = 0, +#ifdef CONFIG_ADC_ASYNC + .read_async = max11102_17_adc_read_async, +#endif +}; + +BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, + "CONFIG_ADC_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY"); + +#define ADC_MAX11102_17_INST_DEFINE(index, name, res, channels) \ + static const struct max11102_17_config config_##name##_##index = { \ + .bus = SPI_DT_SPEC_INST_GET( \ + index, \ + SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ + .gpio_chsel = GPIO_DT_SPEC_INST_GET_OR(index, chsel_gpios, {0}), \ + .resolution = res, \ + .channel_count = channels, \ + }; \ + static struct max11102_17_data data_##name##_##index; \ + DEVICE_DT_INST_DEFINE(index, max11102_17_init, NULL, &data_##name##_##index, \ + &config_##name##_##index, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + &api); + +#define DT_DRV_COMPAT maxim_max11102 +#define ADC_MAX11102_RESOLUTION 12 +#define ADC_MAX11102_CHANNELS 2 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11102_RESOLUTION, ADC_MAX11102_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11103 +#define ADC_MAX11103_RESOLUTION 12 +#define ADC_MAX11103_CHANNELS 2 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11103_RESOLUTION, ADC_MAX11103_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11105 +#define ADC_MAX11105_RESOLUTION 12 +#define ADC_MAX11105_CHANNELS 1 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11105_RESOLUTION, ADC_MAX11105_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11106 +#define ADC_MAX11106_RESOLUTION 10 +#define ADC_MAX11106_CHANNELS 2 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11106_RESOLUTION, ADC_MAX11106_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11110 +#define ADC_MAX11110_RESOLUTION 10 +#define ADC_MAX11110_CHANNELS 1 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11110_RESOLUTION, ADC_MAX11110_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11111 +#define ADC_MAX11111_RESOLUTION 8 +#define ADC_MAX11111_CHANNELS 2 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11111_RESOLUTION, ADC_MAX11111_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11115 +#define ADC_MAX11115_RESOLUTION 8 +#define ADC_MAX11115_CHANNELS 1 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11115_RESOLUTION, ADC_MAX11115_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11116 +#define ADC_MAX11116_RESOLUTION 8 +#define ADC_MAX11116_CHANNELS 1 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11116_RESOLUTION, ADC_MAX11116_CHANNELS) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT maxim_max11117 +#define ADC_MAX11117_RESOLUTION 10 +#define ADC_MAX11117_CHANNELS 1 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_MAX11102_17_INST_DEFINE, DT_DRV_COMPAT, + ADC_MAX11117_RESOLUTION, ADC_MAX11117_CHANNELS) +#undef DT_DRV_COMPAT From 413267ea4f0da7720a53f2ef6d6fc3789214486e Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Mon, 24 Jul 2023 16:57:55 +0200 Subject: [PATCH 0426/4498] drivers: adc: add MAX11102-MAX11117 to ADC shell Add all available instances of the ADC series MAX11102-MAX11117 to the ADC shell. Signed-off-by: Benedikt Schmidt --- drivers/adc/adc_shell.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index c7677b8d45f..4aa9209ae5f 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -91,6 +91,15 @@ static struct adc_hdl { DT_FOREACH_STATUS_OKAY(raspberrypi_pico_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(zephyr_adc_emul, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_s32_adc_sar, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11102, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11103, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11105, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11106, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11110, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11111, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11115, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11116, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(maxim_max11117, ADC_HDL_LIST_ENTRY) }; static struct adc_hdl *get_adc(const char *device_label) From 02dabecbd1653507a815d89b7f8411ebe1ec82e4 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 13 Jul 2023 10:10:40 +0200 Subject: [PATCH 0427/4498] tests: drivers: adc: add MAX11102-MAX11117 Add instances of the ADC family MAX11102-MAX11117 to the build all tests. Signed-off-by: Benedikt Schmidt --- .../build_all/adc/boards/native_posix.overlay | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/drivers/build_all/adc/boards/native_posix.overlay b/tests/drivers/build_all/adc/boards/native_posix.overlay index 8cba0de309a..7f6f64243c8 100644 --- a/tests/drivers/build_all/adc/boards/native_posix.overlay +++ b/tests/drivers/build_all/adc/boards/native_posix.overlay @@ -99,6 +99,15 @@ /* one entry for every devices at spi.dtsi */ cs-gpios = <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, @@ -229,6 +238,73 @@ drdy-gpios = <&test_gpio 0 0>; start-sync-gpios = <&test_gpio 0 0>; }; + + test_spi_max11102: max11102@a { + compatible = "maxim,max11102"; + reg = <0xa>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + chsel-gpios = <&test_gpio 0 0>; + }; + + test_spi_max11103: max11103@b { + compatible = "maxim,max11103"; + reg = <0xb>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + chsel-gpios = <&test_gpio 0 0>; + }; + + test_spi_max11105: max11105@c { + compatible = "maxim,max11105"; + reg = <0xc>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + }; + + test_spi_max11106: max11106@d { + compatible = "maxim,max11106"; + reg = <0xd>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + chsel-gpios = <&test_gpio 0 0>; + }; + + test_spi_max11110: max11110@e { + compatible = "maxim,max11110"; + reg = <0xe>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + }; + + test_spi_max11111: max11111@f { + compatible = "maxim,max11111"; + reg = <0xf>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + chsel-gpios = <&test_gpio 0 0>; + }; + + test_spi_max11115: max11115@10 { + compatible = "maxim,max11115"; + reg = <0x10>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + }; + + test_spi_max11116: max11116@11 { + compatible = "maxim,max11116"; + reg = <0x11>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + }; + + test_spi_max11117: max11117@12 { + compatible = "maxim,max11117"; + reg = <0x12>; + spi-max-frequency = <0>; + #io-channel-cells = <1>; + }; }; }; }; From 6bc67ba541b751adfa3fc1d6232c63de387db3f1 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Tue, 25 Jul 2023 09:35:14 +0200 Subject: [PATCH 0428/4498] tests: drivers: adc: increase RODATA region size Increase the rodata section for build_all/adc to successfully build on the platform atsame54_xpro. Signed-off-by: Benedikt Schmidt --- tests/drivers/build_all/adc/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/build_all/adc/prj.conf b/tests/drivers/build_all/adc/prj.conf index afb4cf20d79..c5d1cb3b04f 100644 --- a/tests/drivers/build_all/adc/prj.conf +++ b/tests/drivers/build_all/adc/prj.conf @@ -3,3 +3,4 @@ CONFIG_TEST_USERSPACE=y CONFIG_ADC=y CONFIG_MAX_THREAD_BYTES=4 CONFIG_ADC_INIT_PRIORITY=80 +CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES=256 From 24ad40a7f2d45a87e9419436195f7f5de47d8cfa Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 3 Aug 2023 12:10:49 +0200 Subject: [PATCH 0429/4498] CODEOWNERS: add codeowner of MAX11102-17 Add myself as codeowner of the previously committed ADC driver for the MAX11102-17 series. Signed-off-by: Benedikt Schmidt --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 45f1c43719c..52ce1669342 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -243,6 +243,7 @@ /drivers/adc/adc_stm32.c @cybertale /drivers/adc/adc_rpi_pico.c @soburi /drivers/adc/*ads114s0x* @benediktibk +/drivers/adc/*max11102_17* @benediktibk /drivers/audio/*nrfx* @anangl /drivers/auxdisplay/*pt6314* @xingrz /drivers/auxdisplay/* @thedjnK @@ -576,6 +577,7 @@ /dts/bindings/i2c/zephyr*i2c-emul*.yaml @sjg20 /dts/bindings/adc/st*stm32-adc.yaml @cybertale /dts/bindings/adc/*ads114s08.yaml @benediktibk +/dts/bindings/adc/*max111* @benediktibk /dts/bindings/modem/*hl7800.yaml @rerickson1 /dts/bindings/serial/ns16550.yaml @dcpleung @nashif /dts/bindings/counter/snps,dw-timers.yaml @pbalsundar From 6f0bf76086b52e55e205ba64819d2471f36ae95c Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Thu, 14 Sep 2023 12:35:59 +0200 Subject: [PATCH 0430/4498] modules: fatfs: fix build warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a missing include to avoid these warnings : - zephyr/modules/fatfs/zfs_ffsystem.c:19:16: warning: implicit declaration of function 'k_malloc'; did you mean 'ff_memalloc'? [-Wimplicit-function-declaration] - zephyr/modules/fatfs/zfs_ffsystem.c:19:16: warning: returning 'int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion] - zephyr/modules/fatfs/zfs_ffsystem.c:25:9: warning: implicit declaration of function 'k_free' [-Wimplicit-function-declaration] Signed-off-by: Johan Lafon --- modules/fatfs/zfs_ffsystem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/fatfs/zfs_ffsystem.c b/modules/fatfs/zfs_ffsystem.c index 6f4d134f798..f4f2c900372 100644 --- a/modules/fatfs/zfs_ffsystem.c +++ b/modules/fatfs/zfs_ffsystem.c @@ -10,6 +10,8 @@ * https://github.com/zephyrproject-rtos/fatfs/blob/master/option/ffsystem.c */ +#include + #include #if FF_USE_LFN == 3 /* Dynamic memory allocation */ From 183b84d0e22d95541b6c6950a0b6b595fed2e3c4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 15 Aug 2023 11:30:01 +0000 Subject: [PATCH 0431/4498] scripts: compliance: add a check for missing west area maintainer enties Add a check to ensure that every module has a corresponding maintainers file entry, ensure modules are not added with no recorded point of contact. Signed-off-by: Fabio Baltieri --- .gitignore | 1 + scripts/ci/check_compliance.py | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/.gitignore b/.gitignore index 16e54c46628..fae5aabbf30 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,7 @@ Kconfig.txt KconfigBasic.txt KconfigBasicNoModules.txt MaintainersFormat.txt +ModulesMaintainers.txt Nits.txt Pylint.txt YAMLLint.txt diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 8a70ffabeeb..c63007580e3 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -22,6 +22,9 @@ from junitparser import TestCase, TestSuite, JUnitXml, Skipped, Error, Failure import magic +from west.manifest import Manifest +from west.manifest import ManifestProject + sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from get_maintainer import Maintainers, MaintainersError @@ -1084,6 +1087,40 @@ def run(self): except MaintainersError as ex: self.failure(f"Error parsing {file}: {ex}") +class ModulesMaintainers(ComplianceTest): + """ + Check that all modules have a MAINTAINERS entry. + """ + name = "ModulesMaintainers" + doc = "Check that all modules have a MAINTAINERS entry." + path_hint = "" + + def run(self): + MAINTAINERS_FILES = ["MAINTAINERS.yml", "MAINTAINERS.yaml"] + + manifest = Manifest.from_file() + + maintainers_file = None + for file in MAINTAINERS_FILES: + if os.path.exists(file): + maintainers_file = file + break + if not maintainers_file: + return + + maintainers = Maintainers(maintainers_file) + + for project in manifest.get_projects([]): + if not manifest.is_active(project): + continue + + if isinstance(project, ManifestProject): + continue + + area = f"West project: {project.name}" + if area not in maintainers.areas: + self.failure(f"Missing {maintainers_file} entry for: \"{area}\"") + class YAMLLint(ComplianceTest): """ From c8dcdd9957c617d6199b93f490d36ba48e076322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sat, 19 Aug 2023 09:45:30 +0100 Subject: [PATCH 0432/4498] atsamd2x_xpro/ev11l78a: update RST table format. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This follows the same template as the atsamc21n_xpro and other boards by using the list-table extension, and the same device descriptions where applicable. Signed-off-by: Diego Elio Pettenò --- boards/arm/atsamd20_xpro/doc/index.rst | 54 +++++++++++++--------- boards/arm/atsamd21_xpro/doc/index.rst | 64 ++++++++++++++++---------- boards/arm/ev11l78a/doc/index.rst | 55 +++++++++++++--------- 3 files changed, 106 insertions(+), 67 deletions(-) diff --git a/boards/arm/atsamd20_xpro/doc/index.rst b/boards/arm/atsamd20_xpro/doc/index.rst index fb4c3f90acc..b5b6d96eb03 100644 --- a/boards/arm/atsamd20_xpro/doc/index.rst +++ b/boards/arm/atsamd20_xpro/doc/index.rst @@ -36,27 +36,39 @@ Supported Features The atsamd20_xpro board configuration supports the following hardware features: -+-----------+------------+------------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+==========================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+------------------------------------------+ -| Flash | on-chip | Can be used with LittleFS to store files | -+-----------+------------+------------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+------------------------------------------+ -| WDT | on-chip | Watchdog | -+-----------+------------+------------------------------------------+ -| ADC | on-chip | Analog to Digital Converter | -+-----------+------------+------------------------------------------+ -| GPIO | on-chip | I/O ports | -+-----------+------------+------------------------------------------+ -| USART | on-chip | Serial ports | -+-----------+------------+------------------------------------------+ -| I2C | on-chip | I2C ports | -+-----------+------------+------------------------------------------+ -| SPI | on-chip | Serial Peripheral Interface ports | -+-----------+------------+------------------------------------------+ +.. list-table:: + :header-rows: 1 + + * - Interface + - Controller + - Driver / Component + * - NVIC + - on-chip + - nested vector interrupt controller + * - Flash + - on-chip + - Can be used with LittleFS to store files + * - SYSTICK + - on-chip + - systick + * - WDT + - on-chip + - Watchdog + * - ADC + - on-chip + - Analog to Digital Converter + * - GPIO + - on-chip + - I/O ports + * - USART + - on-chip + - Serial ports + * - I2C + - on-chip + - I2C ports + * - SPI + - on-chip + - Serial Peripheral Interface ports Other hardware features are not currently supported by Zephyr. diff --git a/boards/arm/atsamd21_xpro/doc/index.rst b/boards/arm/atsamd21_xpro/doc/index.rst index 97d9f037696..9732c84d6fb 100644 --- a/boards/arm/atsamd21_xpro/doc/index.rst +++ b/boards/arm/atsamd21_xpro/doc/index.rst @@ -36,31 +36,45 @@ Supported Features The atsamd21_xpro board configuration supports the following hardware features: -+-----------+------------+------------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+==========================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+------------------------------------------+ -| Flash | on-chip | Can be used with LittleFS to store files | -+-----------+------------+------------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+------------------------------------------+ -| WDT | on-chip | Watchdog | -+-----------+------------+------------------------------------------+ -| ADC | on-chip | Analog to Digital Converter | -+-----------+------------+------------------------------------------+ -| GPIO | on-chip | I/O ports | -+-----------+------------+------------------------------------------+ -| PWM | on-chip | Pulse Width Modulation | -+-----------+------------+------------------------------------------+ -| USART | on-chip | Serial ports | -+-----------+------------+------------------------------------------+ -| I2C | on-chip | I2C ports | -+-----------+------------+------------------------------------------+ -| SPI | on-chip | Serial Peripheral Interface ports | -+-----------+------------+------------------------------------------+ -| USB | on-chip | Universal Serial Bus device ports | -+-----------+------------+------------------------------------------+ +.. list-table:: + :header-rows: 1 + + * - Interface + - Controller + - Driver / Component + * - NVIC + - on-chip + - nested vector interrupt controller + * - Flash + - on-chip + - Can be used with LittleFS to store files + * - SYSTICK + - on-chip + - systick + * - WDT + - on-chip + - Watchdog + * - ADC + - on-chip + - Analog to Digital Converter + * - GPIO + - on-chip + - I/O ports + * - PWM + - on-chip + - Pulse Width Modulation + * - USART + - on-chip + - Serial ports + * - I2C + - on-chip + - I2C ports + * - SPI + - on-chip + - Serial Peripheral Interface ports + * - USB + - on-chip + - Universal Serial Bus device ports Other hardware features are not currently supported by Zephyr. diff --git a/boards/arm/ev11l78a/doc/index.rst b/boards/arm/ev11l78a/doc/index.rst index 894cda97197..cfa4f075eee 100644 --- a/boards/arm/ev11l78a/doc/index.rst +++ b/boards/arm/ev11l78a/doc/index.rst @@ -33,27 +33,40 @@ Supported Features The ev11l78a board configuration supports the following hardware features: -+-----------+------------+------------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+==========================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+------------------------------------------+ -| Flash | on-chip | Can be used with LittleFS to store files | -+-----------+------------+------------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+------------------------------------------+ -| WDT | on-chip | Watchdog | -+-----------+------------+------------------------------------------+ -| GPIO | on-chip | I/O ports | -+-----------+------------+------------------------------------------+ -| USART | on-chip | Serial ports | -+-----------+------------+------------------------------------------+ -| SPI | on-chip | Serial Peripheral Interface ports | -+-----------+------------+------------------------------------------+ -| I2C | on-chip | I²C ports | -+-----------+------------+------------------------------------------+ -| ADC | on-chip | Analog-to-Digital Converter | -+-----------+------------+------------------------------------------+ + +.. list-table:: + :header-rows: 1 + + * - Interface + - Controller + - Driver / Component + * - NVIC + - on-chip + - nested vector interrupt controller + * - Flash + - on-chip + - Can be used with LittleFS to store files + * - SYSTICK + - on-chip + - systick + * - WDT + - on-chip + - Watchdog + * - ADC + - on-chip + - Analog to Digital Converter + * - GPIO + - on-chip + - I/O ports + * - USART + - on-chip + - Serial ports + * - I2C + - on-chip + - I2C ports + * - SPI + - on-chip + - Serial Peripheral Interface ports Other hardware features are not currently supported by Zephyr. From 3e3f9d155f1d087b28c6cb2c44a0d2b20f1a4e3d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 14 Sep 2023 09:52:57 -0700 Subject: [PATCH 0433/4498] xtensa: dc233c: enlarge ROM space The zdsp.basicmath needs a bit more ROM space to run. So enlarge the indicated ROM size to accommodate that. Signed-off-by: Daniel Leung --- dts/xtensa/dc233c.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/xtensa/dc233c.dtsi b/dts/xtensa/dc233c.dtsi index 8a0eed405c3..81f5042c586 100644 --- a/dts/xtensa/dc233c.dtsi +++ b/dts/xtensa/dc233c.dtsi @@ -29,13 +29,13 @@ }; /* - * Although ROM is of size 32MB (0x02000000), limit this to 8KB so + * Although ROM is of size 32MB (0x02000000), limit this to 16KB so * fewer L2 page table entries are needed when MMU is enabled. */ rom0: memory@fe000000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0xfe000000 0x00002000>; + reg = <0xfe000000 0x00004000>; }; soc { From 8cb9d7655352369a483545c313a09cd5ad633f15 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 14 Sep 2023 09:55:05 -0700 Subject: [PATCH 0434/4498] xtensa: dc233c: Add TLS support Add TLS support for this target. Signed-off-by: Flavio Ceolin Signed-off-by: Daniel Leung --- soc/xtensa/dc233c/Kconfig.soc | 1 + soc/xtensa/dc233c/include/xtensa-dc233c.ld | 2 ++ 2 files changed, 3 insertions(+) diff --git a/soc/xtensa/dc233c/Kconfig.soc b/soc/xtensa/dc233c/Kconfig.soc index fee0730da95..cf846b82839 100644 --- a/soc/xtensa/dc233c/Kconfig.soc +++ b/soc/xtensa/dc233c/Kconfig.soc @@ -6,6 +6,7 @@ config SOC_XTENSA_DC233C bool "Xtensa dc233c core" select XTENSA select XTENSA_HAL + select ARCH_HAS_THREAD_LOCAL_STORAGE select CPU_HAS_MMU imply XTENSA_MMU select ARCH_HAS_RESERVED_PAGE_FRAMES if XTENSA_MMU diff --git a/soc/xtensa/dc233c/include/xtensa-dc233c.ld b/soc/xtensa/dc233c/include/xtensa-dc233c.ld index 07d40aef49e..d6c57e36499 100644 --- a/soc/xtensa/dc233c/include/xtensa-dc233c.ld +++ b/soc/xtensa/dc233c/include/xtensa-dc233c.ld @@ -397,6 +397,8 @@ SECTIONS #include +#include + #include #include From 40b9f51ee52a9b0a4e1ced48f9861fefc56088fc Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 13 Sep 2023 20:03:27 +0200 Subject: [PATCH 0435/4498] modem: pipe: Reinvoke receive ready on attach This PR makes the modem_pipe instances track if they have data ready to receive, and invoke the RECEIVE_READY event every time they are attached if the backend implementing the pipe has notified that receive is ready. This mechanism ensures that modules attaching to a pipe get the async RECEIVE_READY event immediately after attaching to a pipe if there is data ready, instead of having to poll the pipe, or worse, wait until newer data becomes available. The addition revealed a timing issue in the cmux test suite. Specifically the CMUX instance now immediately receives the response to a command which the CMUX instance has not sent yet, causing it to drop the response. The CMUX test suite now uses the transaction mechanism of the mock_pipe to wait for the command before sending the response. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/pipe.h | 1 + subsys/modem/modem_pipe.c | 10 ++++++++++ tests/subsys/modem/modem_cmux/src/main.c | 24 +++++++++--------------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/zephyr/modem/pipe.h b/include/zephyr/modem/pipe.h index 4fdd98155da..945cace6bb8 100644 --- a/include/zephyr/modem/pipe.h +++ b/include/zephyr/modem/pipe.h @@ -53,6 +53,7 @@ struct modem_pipe { enum modem_pipe_state state; struct k_mutex lock; struct k_condvar condvar; + bool receive_ready_pending; }; /** diff --git a/subsys/modem/modem_pipe.c b/subsys/modem/modem_pipe.c index ca2a26020be..5240c5ebc27 100644 --- a/subsys/modem/modem_pipe.c +++ b/subsys/modem/modem_pipe.c @@ -20,6 +20,7 @@ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api pipe->callback = NULL; pipe->user_data = NULL; pipe->state = MODEM_PIPE_STATE_CLOSED; + pipe->receive_ready_pending = false; k_mutex_init(&pipe->lock); k_condvar_init(&pipe->condvar); @@ -63,6 +64,11 @@ void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback k_mutex_lock(&pipe->lock, K_FOREVER); pipe->callback = callback; pipe->user_data = user_data; + + if (pipe->receive_ready_pending && (pipe->callback != NULL)) { + pipe->callback(pipe, MODEM_PIPE_EVENT_RECEIVE_READY, pipe->user_data); + } + k_mutex_unlock(&pipe->lock); } @@ -94,6 +100,7 @@ int modem_pipe_receive(struct modem_pipe *pipe, uint8_t *buf, size_t size) } ret = pipe->api->receive(pipe->data, buf, size); + pipe->receive_ready_pending = false; k_mutex_unlock(&pipe->lock); return ret; } @@ -155,6 +162,7 @@ void modem_pipe_notify_closed(struct modem_pipe *pipe) { k_mutex_lock(&pipe->lock, K_FOREVER); pipe->state = MODEM_PIPE_STATE_CLOSED; + pipe->receive_ready_pending = false; if (pipe->callback != NULL) { pipe->callback(pipe, MODEM_PIPE_EVENT_CLOSED, pipe->user_data); @@ -168,6 +176,8 @@ void modem_pipe_notify_receive_ready(struct modem_pipe *pipe) { k_mutex_lock(&pipe->lock, K_FOREVER); + pipe->receive_ready_pending = true; + if (pipe->callback != NULL) { pipe->callback(pipe, MODEM_PIPE_EVENT_RECEIVE_READY, pipe->user_data); } diff --git a/tests/subsys/modem/modem_cmux/src/main.c b/tests/subsys/modem/modem_cmux/src/main.c index 13422641b9c..115b3bd89b9 100644 --- a/tests/subsys/modem/modem_cmux/src/main.c +++ b/tests/subsys/modem/modem_cmux/src/main.c @@ -265,32 +265,26 @@ static void *test_modem_cmux_setup(void) }; bus_mock_pipe = modem_backend_mock_init(&bus_mock, &bus_mock_config); - __ASSERT_NO_MSG(modem_pipe_open_async(bus_mock_pipe) == 0); + __ASSERT_NO_MSG(modem_pipe_open(bus_mock_pipe) == 0); /* Connect CMUX */ __ASSERT_NO_MSG(modem_cmux_attach(&cmux, bus_mock_pipe) == 0); + modem_backend_mock_prime(&bus_mock, &transaction_control_sabm); __ASSERT_NO_MSG(modem_cmux_connect_async(&cmux) == 0); - modem_backend_mock_put(&bus_mock, cmux_frame_control_sabm_ack, - sizeof(cmux_frame_control_sabm_ack)); - events = k_event_wait(&cmux_event, EVENT_CMUX_CONNECTED, false, K_MSEC(100)); __ASSERT_NO_MSG(events == EVENT_CMUX_CONNECTED); /* Open DLCI channels */ modem_pipe_attach(dlci1_pipe, test_modem_dlci1_pipe_callback, NULL); - modem_pipe_attach(dlci2_pipe, test_modem_dlci2_pipe_callback, NULL); + modem_backend_mock_prime(&bus_mock, &transaction_dlci1_sabm); __ASSERT_NO_MSG(modem_pipe_open_async(dlci1_pipe) == 0); - __ASSERT_NO_MSG(modem_pipe_open_async(dlci2_pipe) == 0); - modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_sabm_ack, - sizeof(cmux_frame_dlci1_sabm_ack)); - - modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_sabm_ack, - sizeof(cmux_frame_dlci2_sabm_ack)); - - events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI1_OPEN | EVENT_CMUX_DLCI2_OPEN), - false, K_MSEC(100)); - + events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI1_OPEN, false, K_MSEC(100)); __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI1_OPEN)); + + modem_pipe_attach(dlci2_pipe, test_modem_dlci2_pipe_callback, NULL); + modem_backend_mock_prime(&bus_mock, &transaction_dlci2_sabm); + __ASSERT_NO_MSG(modem_pipe_open_async(dlci2_pipe) == 0); + events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_OPEN, false, K_MSEC(100)); __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI2_OPEN)); return NULL; From a6db78e2b3e4619951d23d07e989eb3b4ff04ce0 Mon Sep 17 00:00:00 2001 From: Vincent van Beveren Date: Wed, 24 May 2023 13:49:27 +0200 Subject: [PATCH 0436/4498] driver: sdhc: added atmel SAM4E hsmci driver This commit adds support for the ATMEL HSMCI peripheral for the SAM4E MCU series, enabling native SD card support. Signed-off-by: Vincent van Beveren --- drivers/sdhc/CMakeLists.txt | 2 + drivers/sdhc/Kconfig | 1 + drivers/sdhc/Kconfig.sam_hsmci | 38 ++ drivers/sdhc/sam_hsmci.c | 683 +++++++++++++++++++++++++ dts/arm/atmel/sam4e.dtsi | 7 + dts/bindings/sdhc/atmel,sam-hsmci.yaml | 24 + 6 files changed, 755 insertions(+) create mode 100644 drivers/sdhc/Kconfig.sam_hsmci create mode 100644 drivers/sdhc/sam_hsmci.c create mode 100644 dts/bindings/sdhc/atmel,sam-hsmci.yaml diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index a29829de24a..b6563382a82 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -6,4 +6,6 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_IMX_USDHC imx_usdhc.c) zephyr_library_sources_ifdef(CONFIG_SPI_SDHC sdhc_spi.c) zephyr_library_sources_ifdef(CONFIG_MCUX_SDIF mcux_sdif.c) +zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) + endif() diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index 0969c6fa73c..5a1c7d6c95f 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -11,6 +11,7 @@ if SDHC source "drivers/sdhc/Kconfig.imx" source "drivers/sdhc/Kconfig.spi" source "drivers/sdhc/Kconfig.mcux_sdif" +source "drivers/sdhc/Kconfig.sam_hsmci" config SDHC_INIT_PRIORITY int "SDHC driver init priority" diff --git a/drivers/sdhc/Kconfig.sam_hsmci b/drivers/sdhc/Kconfig.sam_hsmci new file mode 100644 index 00000000000..68265dcabed --- /dev/null +++ b/drivers/sdhc/Kconfig.sam_hsmci @@ -0,0 +1,38 @@ +# Copyright 2023 Nikhef +# SPDX -License-Identifier: Apache-2.0 + +config SAM_HSMCI + bool "ATMEL SAM HSMCI driver" + default y + depends on DT_HAS_ATMEL_SAM_HSMCI_ENABLED + select SDHC_SUPPORTS_NATIVE_MODE + help + Enable the ATMEL SAM HSMCI MMC/SD card driver. + +if SAM_HSMCI + +config SAM_HSMCI_PDCMODE + bool "Use PDC if available" + default y if SOC_SERIES_SAM4E + help + Use peripheral DMA controller, if supported + +config SAM_HSMCI_PWRSAVE + bool "Power save during card inactive" + default y + help + Power-save mode reduces the clock-speed during SD card + inactivity. + +if SAM_HSMCI_PWRSAVE + +config SAM_HSMCI_PWRSAVE_DIV + int "Divisor value of clock when in power-save mode" + default 7 + help + SD clock freqeuncy is divided by 2**(N+1) where N + is the divisor value. Valid values are 0 to 7. + +endif # SAM_HSMCI_PWRSAVE + +endif # SAM_HSMCI diff --git a/drivers/sdhc/sam_hsmci.c b/drivers/sdhc/sam_hsmci.c new file mode 100644 index 00000000000..b7c3d3b8783 --- /dev/null +++ b/drivers/sdhc/sam_hsmci.c @@ -0,0 +1,683 @@ +/* + * Copyright 2023 Nikhef + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT atmel_sam_hsmci + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(hsmci, CONFIG_SDHC_LOG_LEVEL); + +#ifdef HSMCI_MR_PDCMODE +#ifdef CONFIG_SAM_HSMCI_PDCMODE +#define _HSMCI_PDCMODE +#endif +#endif + +#ifdef CONFIG_SAM_HSMCI_PWRSAVE +#if (CONFIG_SAM_HSMCI_PWRSAVE_DIV < 0) || (CONFIG_SAM_HSMCI_PWRSAVE_DIV > 7) +#error "CONFIG_SAM_HSMCI_PWRSAVE_DIV must be 0 to 7" +#endif +#endif + +#define _HSMCI_DEFAULT_TIMEOUT 5000 +#define _HSMCI_MAX_FREQ (SOC_ATMEL_SAM_MCK_FREQ_HZ >> 1) +#define _HSMCI_MIN_FREQ (_HSMCI_MAX_FREQ / 0x200) +#define _MSMCI_MAX_DIVISOR 0x1FF +#define _HSMCI_SR_ERR (HSMCI_SR_RINDE \ + | HSMCI_SR_RDIRE \ + | HSMCI_SR_RCRCE \ + | HSMCI_SR_RENDE \ + | HSMCI_SR_RTOE \ + | HSMCI_SR_DCRCE \ + | HSMCI_SR_DTOE \ + | HSMCI_SR_CSTOE \ + | HSMCI_SR_OVRE \ + | HSMCI_SR_UNRE) + +static const uint8_t _resp2size[] = { + [SD_RSP_TYPE_NONE] = HSMCI_CMDR_RSPTYP_NORESP, + [SD_RSP_TYPE_R1] = HSMCI_CMDR_RSPTYP_48_BIT, + [SD_RSP_TYPE_R1b] = HSMCI_CMDR_RSPTYP_R1B, + [SD_RSP_TYPE_R2] = HSMCI_CMDR_RSPTYP_136_BIT, + [SD_RSP_TYPE_R3] = HSMCI_CMDR_RSPTYP_48_BIT, + [SD_RSP_TYPE_R4] = HSMCI_CMDR_RSPTYP_48_BIT, + [SD_RSP_TYPE_R5] = 0 /* SDIO not supported */, + [SD_RSP_TYPE_R5b] = 0 /* SDIO not supported */, + [SD_RSP_TYPE_R6] = HSMCI_CMDR_RSPTYP_48_BIT, + [SD_RSP_TYPE_R7] = HSMCI_CMDR_RSPTYP_48_BIT, +}; + +/* timeout multiplier shift (actual value is 1 << _mul_shift[*]) */ +static const uint8_t _mul_shift[] = {0, 4, 7, 8, 10, 12, 16, 20}; +static const uint8_t _mul_shift_size = 8; + +struct sam_hsmci_config { + Hsmci *base; + const struct atmel_sam_pmc_config clock_cfg; + const struct pinctrl_dev_config *pincfg; + struct gpio_dt_spec carrier_detect; +}; + +struct sam_hsmci_data { + bool open_drain; + uint8_t cmd_in_progress; + struct k_mutex mtx; +}; + +static int sam_hsmci_reset(const struct device *dev) +{ + const struct sam_hsmci_config *config = dev->config; + Hsmci *hsmci = config->base; + + uint32_t mr = hsmci->HSMCI_MR; + uint32_t dtor = hsmci->HSMCI_DTOR; + uint32_t sdcr = hsmci->HSMCI_SDCR; + uint32_t cstor = hsmci->HSMCI_CSTOR; + uint32_t cfg = hsmci->HSMCI_CFG; + + hsmci->HSMCI_CR = HSMCI_CR_SWRST; + hsmci->HSMCI_MR = mr; + hsmci->HSMCI_DTOR = dtor; + hsmci->HSMCI_SDCR = sdcr; + hsmci->HSMCI_CSTOR = cstor; + hsmci->HSMCI_CFG = cfg; + + hsmci->HSMCI_CR = HSMCI_CR_PWSEN | HSMCI_CR_MCIEN; + return 0; +} + +static int sam_hsmci_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + memset(props, 0, sizeof(*props)); + + props->f_max = _HSMCI_MAX_FREQ; + props->f_min = _HSMCI_MIN_FREQ; + /* high-speed not working yet due to limitations of the SDHC sm */ + props->host_caps.high_spd_support = false; + props->power_delay = 500; + props->is_spi = false; + props->max_current_330 = 4; + + return 0; +} + +static int sam_hsmci_set_io(const struct device *dev, struct sdhc_io *ios) +{ + const struct sam_hsmci_config *config = dev->config; + struct sam_hsmci_data *data = dev->data; + Hsmci *hsmci = config->base; + uint32_t frequency; + uint32_t div_val; + int ret; + + LOG_DBG("%s(clock=%d, bus_width=%d, timing=%d, mode=%d)", __func__, ios->clock, + ios->bus_width, ios->timing, ios->bus_mode); + + if (ios->clock > 0) { + if (ios->clock > _HSMCI_MAX_FREQ) { + return -ENOTSUP; + } + + ret = clock_control_get_rate(SAM_DT_PMC_CONTROLLER, + (clock_control_subsys_t)&config->clock_cfg, + &frequency); + + if (ret < 0) { + LOG_ERR("Failed to get clock rate, err=%d", ret); + return ret; + } + + div_val = frequency / ios->clock - 2; + + if (div_val < 0) { + div_val = 0; + } + + if (div_val > _MSMCI_MAX_DIVISOR) { + div_val = _MSMCI_MAX_DIVISOR; + } + + LOG_DBG("divider: %d (freq=%d)", div_val, frequency / (div_val + 2)); + + hsmci->HSMCI_MR &= ~HSMCI_MR_CLKDIV_Msk; + hsmci->HSMCI_MR |= + ((div_val & 1) ? HSMCI_MR_CLKODD : 0) | HSMCI_MR_CLKDIV(div_val >> 1); + } + + if (ios->bus_width) { + hsmci->HSMCI_SDCR &= ~HSMCI_SDCR_SDCBUS_Msk; + + switch (ios->bus_width) { + case SDHC_BUS_WIDTH1BIT: + hsmci->HSMCI_SDCR = HSMCI_SDCR_SDCBUS_1; + break; + case SDHC_BUS_WIDTH4BIT: + hsmci->HSMCI_SDCR = HSMCI_SDCR_SDCBUS_4; + break; + default: + return -ENOTSUP; + } + } + + data->open_drain = (ios->bus_mode == SDHC_BUSMODE_OPENDRAIN); + + if (ios->timing) { + switch (ios->timing) { + case SDHC_TIMING_LEGACY: + hsmci->HSMCI_CFG &= ~HSMCI_CFG_HSMODE; + break; + case SDHC_TIMING_HS: + hsmci->HSMCI_CFG |= HSMCI_CFG_HSMODE; + break; + default: + return -ENOTSUP; + } + } + + return 0; +} + +static int sam_hsmci_init(const struct device *dev) +{ + const struct sam_hsmci_config *config = dev->config; + int ret; + + /* Connect pins to the peripheral */ + ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("pinctrl_apply_state() => %d", ret); + return ret; + } + /* Enable module's clock */ + (void)clock_control_on(SAM_DT_PMC_CONTROLLER, (clock_control_subsys_t)&config->clock_cfg); + + /* init carrier detect (if set) */ + if (config->carrier_detect.port != NULL) { + if (!gpio_is_ready_dt(&config->carrier_detect)) { + LOG_ERR("GPIO port for carrier-detect pin is not ready"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->carrier_detect, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Couldn't configure carrier-detect pin; (%d)", ret); + return ret; + } + } + + Hsmci *hsmci = config->base; + + /* reset the device */ + hsmci->HSMCI_CR = HSMCI_CR_SWRST; + hsmci->HSMCI_CR = HSMCI_CR_PWSDIS; + hsmci->HSMCI_CR = HSMCI_CR_MCIEN; +#ifdef CONFIG_SAM_HSMCI_PWRSAVE + hsmci->HSMCI_MR = + HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_PWSDIV(CONFIG_SAM_HSMCI_PWRSAVE_DIV); + hsmci->HSMCI_CR = HSMCI_CR_PWSEN; +#else + hsmci->HSMCI_MR = HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF; +#endif + + return 0; +} + +static int sam_hsmci_get_card_present(const struct device *dev) +{ + const struct sam_hsmci_config *config = dev->config; + + if (config->carrier_detect.port == NULL) { + return 1; + } + + return gpio_pin_get_dt(&config->carrier_detect); +} + +static int sam_hsmci_card_busy(const struct device *dev) +{ + const struct sam_hsmci_config *config = dev->config; + Hsmci *hsmci = config->base; + + return (hsmci->HSMCI_SR & HSMCI_SR_NOTBUSY) == 0; +} + +static void sam_hsmci_send_clocks(Hsmci *hsmci) +{ + hsmci->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE); + hsmci->HSMCI_ARGR = 0; + hsmci->HSMCI_CMDR = + HSMCI_CMDR_RSPTYP_NORESP | HSMCI_CMDR_SPCMD_INIT | HSMCI_CMDR_OPDCMD_OPENDRAIN; + while (!(hsmci->HSMCI_SR & HSMCI_SR_CMDRDY)) { + ; + } + hsmci->HSMCI_MR |= HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF; +} + +static int sam_hsmci_send_cmd(Hsmci *hsmci, struct sdhc_command *cmd, uint32_t cmdr, + struct sam_hsmci_data *data) +{ + uint32_t sr; + + hsmci->HSMCI_ARGR = cmd->arg; + + cmdr |= HSMCI_CMDR_CMDNB(cmd->opcode) | HSMCI_CMDR_MAXLAT_64; + if (data->open_drain) { + cmdr |= HSMCI_CMDR_OPDCMD_OPENDRAIN; + } + + uint8_t nrt = cmd->response_type & SDHC_NATIVE_RESPONSE_MASK; + + if (nrt > SD_RSP_TYPE_R7) { + return -ENOTSUP; + } + + cmdr |= _resp2size[nrt]; + hsmci->HSMCI_CMDR = cmdr; + do { + sr = hsmci->HSMCI_SR; + + /* special case ,ignore CRC status if response is R3 to clear it */ + if (nrt == SD_RSP_TYPE_R3 || nrt == SD_RSP_TYPE_NONE) { + sr &= ~HSMCI_SR_RCRCE; + } + + if ((sr & _HSMCI_SR_ERR) != 0) { + LOG_DBG("Status register error bits: %08x", sr & _HSMCI_SR_ERR); + return -EIO; + } + } while (!(sr & HSMCI_SR_CMDRDY)); + + if (nrt == SD_RSP_TYPE_R1b) { + do { + sr = hsmci->HSMCI_SR; + } while (!((sr & HSMCI_SR_NOTBUSY) && ((sr & HSMCI_SR_DTIP) == 0))); + } + + /* RSPR is just a FIFO, index is of no consequence */ + cmd->response[3] = hsmci->HSMCI_RSPR[0]; + cmd->response[2] = hsmci->HSMCI_RSPR[0]; + cmd->response[1] = hsmci->HSMCI_RSPR[0]; + cmd->response[0] = hsmci->HSMCI_RSPR[0]; + return 0; +} + +static int sam_hsmci_wait_write_end(Hsmci *hsmci) +{ + uint32_t sr = 0; + +#ifdef _HSMCI_PDCMODE + /* Timeout is included in HSMCI, see DTOE bit, not required explicitly. */ + do { + sr = hsmci->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + LOG_DBG("PDC sr 0x%08x error", sr); + return -EIO; + } + } while (!(sr & HSMCI_SR_TXBUFE)); +#endif + + do { + sr = hsmci->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + LOG_DBG("PDC sr 0x%08x last transfer error", sr); + return -EIO; + } + } while (!(sr & HSMCI_SR_NOTBUSY)); + + if (!(hsmci->HSMCI_SR & HSMCI_SR_FIFOEMPTY)) { + return -EIO; + } + return 0; +} + +static int sam_hsmci_wait_read_end(Hsmci *hsmci) +{ + uint32_t sr; + +#ifdef _HSMCI_PDCMODE + do { + sr = hsmci->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + LOG_DBG("PDC sr 0x%08x error", sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)); + return -EIO; + } + } while (!(sr & HSMCI_SR_RXBUFF)); +#endif + + do { + sr = hsmci->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + return -EIO; + } + } while (!(sr & HSMCI_SR_XFRDONE)); + return 0; +} + +static int sam_hsmci_write_timeout(Hsmci *hsmci, int timeout_ms) +{ + /* convert to clocks (coarsely) */ + int clocks = ATMEL_SAM_DT_CPU_CLK_FREQ_HZ / 1000 * timeout_ms; + int mul, max_clock; + + for (int i = 0; i < _mul_shift_size; i++) { + mul = 1 << _mul_shift[i]; + max_clock = 15 * mul; + if (max_clock > clocks) { + hsmci->HSMCI_DTOR = ((i << HSMCI_DTOR_DTOMUL_Pos) & HSMCI_DTOR_DTOMUL_Msk) | + HSMCI_DTOR_DTOCYC((clocks + mul - 1) / mul); + return 0; + } + } + /* + * So, if it is > maximum timeout... we'll just put it on the maximum the driver supports + * its not nice.. but it should work.. what else is there to do? + */ + hsmci->HSMCI_DTOR = HSMCI_DTOR_DTOMUL_Msk | HSMCI_DTOR_DTOCYC_Msk; + return 0; +} + +static inline int wait_write_transfer_done(Hsmci *hsmci) +{ + int sr; + + do { + sr = hsmci->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + return -EIO; + } + } while (!(sr & HSMCI_SR_TXRDY)); + return 0; +} + +static inline int wait_read_transfer_done(Hsmci *hsmci) +{ + int sr; + + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + return -EIO; + } + } while (!(sr & HSMCI_SR_RXRDY)); + return 0; +} + +#ifndef _HSMCI_PDCMODE + +static int hsmci_do_manual_transfer(Hsmci *hsmci, bool byte_mode, bool is_write, void *data, + int transfer_count) +{ + int ret; + + if (is_write) { + if (byte_mode) { + const uint8_t *ptr = data; + + while (transfer_count-- > 0) { + ret = wait_write_transfer_done(hsmci); + if (ret != 0) { + return ret; + } + hsmci->HSMCI_TDR = *ptr; + ptr++; + } + } else { + const uint32_t *ptr = data; + + while (transfer_count-- > 0) { + ret = wait_write_transfer_done(hsmci); + if (ret != 0) { + return ret; + } + hsmci->HSMCI_TDR = *ptr; + ptr++; + } + } + ret = sam_hsmci_wait_write_end(hsmci); + } else { + if (byte_mode) { + uint8_t *ptr = data; + + while (transfer_count-- > 0) { + ret = wait_read_transfer_done(hsmci); + if (ret != 0) { + return ret; + } + *ptr = hsmci->HSMCI_RDR; + ptr++; + } + } else { + uint32_t *ptr = data; + + while (transfer_count-- > 0) { + ret = wait_read_transfer_done(hsmci); + if (ret != 0) { + return ret; + } + *ptr = hsmci->HSMCI_RDR; + ptr++; + } + } + ret = sam_hsmci_wait_read_end(hsmci); + } + return ret; +} + +#endif /* !_HSMCI_PDCMODE */ + +static int sam_hsmci_request_inner(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *sd_data) +{ + const struct sam_hsmci_config *config = dev->config; + struct sam_hsmci_data *data = dev->data; + Hsmci *hsmci = config->base; + uint32_t sr; + uint32_t size; + uint32_t transfer_count; + uint32_t cmdr = 0; + int ret; + bool is_write, byte_mode; + + LOG_DBG("%s(opcode=%d, arg=%08x, data=%08x, rsptype=%d)", __func__, cmd->opcode, cmd->arg, + (uint32_t)sd_data, cmd->response_type & SDHC_NATIVE_RESPONSE_MASK); + + if (cmd->opcode == SD_GO_IDLE_STATE) { + /* send 74 clocks, as required by SD spec */ + sam_hsmci_send_clocks(hsmci); + } + + if (sd_data) { + cmdr |= HSMCI_CMDR_TRCMD_START_DATA; + + ret = sam_hsmci_write_timeout(hsmci, cmd->timeout_ms); + if (ret != 0) { + return ret; + } + + switch (cmd->opcode) { + case SD_WRITE_SINGLE_BLOCK: + cmdr |= HSMCI_CMDR_TRTYP_SINGLE; + cmdr |= HSMCI_CMDR_TRDIR_WRITE; + is_write = true; + break; + case SD_WRITE_MULTIPLE_BLOCK: + is_write = true; + cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE; + cmdr |= HSMCI_CMDR_TRDIR_WRITE; + break; + case SD_APP_SEND_SCR: + case SD_SWITCH: + case SD_READ_SINGLE_BLOCK: + is_write = false; + cmdr |= HSMCI_CMDR_TRTYP_SINGLE; + cmdr |= HSMCI_CMDR_TRDIR_READ; + break; + case SD_READ_MULTIPLE_BLOCK: + is_write = false; + cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE; + cmdr |= HSMCI_CMDR_TRDIR_READ; + break; + case SD_APP_SEND_NUM_WRITTEN_BLK: + is_write = false; + break; + default: + return -ENOTSUP; + } + + if ((sd_data->block_size & 0x3) == 0 && (((uint32_t)sd_data->data) & 0x3) == 0) { + size = (sd_data->block_size + 3) >> 2; + hsmci->HSMCI_MR &= ~HSMCI_MR_FBYTE; + byte_mode = true; + } else { + size = sd_data->block_size; + hsmci->HSMCI_MR |= HSMCI_MR_FBYTE; + byte_mode = false; + } + + hsmci->HSMCI_BLKR = + HSMCI_BLKR_BLKLEN(sd_data->block_size) | HSMCI_BLKR_BCNT(sd_data->blocks); + + transfer_count = size * sd_data->blocks; + +#ifdef _HSMCI_PDCMODE + hsmci->HSMCI_MR |= HSMCI_MR_PDCMODE; + + hsmci->HSMCI_RNCR = 0; + + if (is_write) { + hsmci->HSMCI_TCR = transfer_count; + hsmci->HSMCI_TPR = (uint32_t)sd_data->data; + } else { + hsmci->HSMCI_RCR = transfer_count; + hsmci->HSMCI_RPR = (uint32_t)sd_data->data; + hsmci->HSMCI_PTCR = HSMCI_PTCR_RXTEN; + } + + } else { + hsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE; +#endif /* _HSMCI_PDCMODE */ + } + + ret = sam_hsmci_send_cmd(hsmci, cmd, cmdr, data); + + if (sd_data) { +#ifdef _HSMCI_PDCMODE + if (ret == 0) { + if (is_write) { + hsmci->HSMCI_PTCR = HSMCI_PTCR_TXTEN; + ret = sam_hsmci_wait_write_end(hsmci); + } else { + ret = sam_hsmci_wait_read_end(hsmci); + } + } + hsmci->HSMCI_PTCR = HSMCI_PTCR_TXTDIS | HSMCI_PTCR_RXTDIS; + hsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE; +#else /* !_HSMCI_PDCMODE */ + if (ret == 0) { + ret = hsmci_do_manual_transfer(hsmci, byte_mode, is_write, sd_data->data, + transfer_count); + } +#endif /* _HSMCI_PDCMODE */ + } + + sr = hsmci->HSMCI_SR; + + LOG_DBG("RSP0=%08x, RPS1=%08x, RPS2=%08x,RSP3=%08x, SR=%08x", cmd->response[0], + cmd->response[1], cmd->response[2], cmd->response[3], sr); + + return ret; +} + +static void sam_hsmci_abort(const struct device *dev) +{ +#ifdef _HSMCI_PDCMODE + const struct sam_hsmci_config *config = dev->config; + Hsmci *hsmci = config->base; + + hsmci->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS; +#endif /* _HSMCI_PDCMODE */ + + struct sdhc_command cmd = { + .opcode = SD_STOP_TRANSMISSION, .arg = 0, .response_type = SD_RSP_TYPE_NONE}; + sam_hsmci_request_inner(dev, &cmd, NULL); +} + +static int sam_hsmci_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *sd_data) +{ + struct sam_hsmci_data *dev_data = dev->data; + int busy_timeout = _HSMCI_DEFAULT_TIMEOUT; + int ret; + + ret = k_mutex_lock(&dev_data->mtx, K_MSEC(cmd->timeout_ms)); + if (ret) { + LOG_ERR("Could not access card"); + return -EBUSY; + } + +#ifdef CONFIG_SAM_HSMCI_PWRSAVE + const struct sam_hsmci_config *config = dev->config; + Hsmci *hsmci = config->base; + + hsmci->HSMCI_CR = HSMCI_CR_PWSDIS; +#endif /* CONFIG_SAM_HSMCI_PWRSAVE */ + + do { + ret = sam_hsmci_request_inner(dev, cmd, sd_data); + if (sd_data && (ret || sd_data->blocks > 1)) { + sam_hsmci_abort(dev); + while (busy_timeout > 0) { + if (!sam_hsmci_card_busy(dev)) { + break; + } + k_busy_wait(125); + busy_timeout -= 125; + } + if (busy_timeout <= 0) { + LOG_ERR("Card did not idle after CMD12"); + ret = -ETIMEDOUT; + } + } + } while (ret != 0 && (cmd->retries-- > 0)); + +#ifdef CONFIG_SAM_HSMCI_PWRSAVE + hsmci->HSMCI_CR = HSMCI_CR_PWSEN; +#endif /* CONFIG_SAM_HSMCI_PWRSAVE */ + + k_mutex_unlock(&dev_data->mtx); + + return ret; +} + +static const struct sdhc_driver_api hsmci_api = { + .reset = sam_hsmci_reset, + .get_host_props = sam_hsmci_get_host_props, + .set_io = sam_hsmci_set_io, + .get_card_present = sam_hsmci_get_card_present, + .request = sam_hsmci_request, + .card_busy = sam_hsmci_card_busy, +}; + +#define SAM_HSMCI_INIT(N) \ + PINCTRL_DT_INST_DEFINE(N); \ + static const struct sam_hsmci_config hsmci_##N##_config = { \ + .base = (Hsmci *)DT_INST_REG_ADDR(N), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(N), \ + .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(N), \ + .carrier_detect = GPIO_DT_SPEC_INST_GET_OR(N, cd_gpios, {0})}; \ + static struct sam_hsmci_data hsmci_##N##_data = {}; \ + DEVICE_DT_INST_DEFINE(N, &sam_hsmci_init, NULL, &hsmci_##N##_data, &hsmci_##N##_config, \ + POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, &hsmci_api); + +DT_INST_FOREACH_STATUS_OKAY(SAM_HSMCI_INIT) diff --git a/dts/arm/atmel/sam4e.dtsi b/dts/arm/atmel/sam4e.dtsi index 6aaf079e821..6393de005f9 100644 --- a/dts/arm/atmel/sam4e.dtsi +++ b/dts/arm/atmel/sam4e.dtsi @@ -294,6 +294,13 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 8>; status = "disabled"; }; + + hsmci: hsmci@40080000 { + compatible = "atmel,sam-hsmci"; + reg = <0x40080000 0x1000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 16>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/sdhc/atmel,sam-hsmci.yaml b/dts/bindings/sdhc/atmel,sam-hsmci.yaml new file mode 100644 index 00000000000..171f8774246 --- /dev/null +++ b/dts/bindings/sdhc/atmel,sam-hsmci.yaml @@ -0,0 +1,24 @@ +# Copyright 2023, Nikhef +# SPDX-License-Identifier: Apache-2.0 + +description: ATMEL (Microchip) SAM HSMCI SD host controller + +compatible: "atmel,sam-hsmci" + +include: [sdhc.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + clocks: + required: true + + cd-gpios: + type: phandle-array From 96beb5c87099da05b186493328329ee696e24b67 Mon Sep 17 00:00:00 2001 From: Vincent van Beveren Date: Wed, 24 May 2023 13:53:58 +0200 Subject: [PATCH 0437/4498] boards: sam4_xpro: add HSMCI support Adds support for the HSMCI peripheral enabling SD card access on the SAM4E eXplained pro board Signed-off-by: Vincent van Beveren --- boards/arm/sam4e_xpro/sam4e_xpro-pinctrl.dtsi | 12 ++++++++++++ boards/arm/sam4e_xpro/sam4e_xpro.dts | 12 ++++++++++++ boards/arm/sam4e_xpro/sam4e_xpro.yaml | 1 + 3 files changed, 25 insertions(+) diff --git a/boards/arm/sam4e_xpro/sam4e_xpro-pinctrl.dtsi b/boards/arm/sam4e_xpro/sam4e_xpro-pinctrl.dtsi index e83b9eeffe8..fb19be497ca 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro-pinctrl.dtsi +++ b/boards/arm/sam4e_xpro/sam4e_xpro-pinctrl.dtsi @@ -94,4 +94,16 @@ ; }; }; + + hsmci_default: hsmci_default { + group1 { + pinmux = , + , + , + , + , + ; + }; + }; + }; diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.dts b/boards/arm/sam4e_xpro/sam4e_xpro.dts index 254a4a21100..eb4ff5fcecc 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.dts +++ b/boards/arm/sam4e_xpro/sam4e_xpro.dts @@ -21,6 +21,7 @@ sw0 = &user_button; wdog = &wdt; watchdog0 = &wdt; + sdhc0 = &hsmci; }; chosen { @@ -211,6 +212,17 @@ pinctrl-names = "default"; }; +&hsmci { + status = "okay"; + + pinctrl-0 = <&hsmci_default>; + pinctrl-names = "default"; + mmc { + compatible = "zephyr,sdmmc-disk"; + status = "okay"; + }; +}; + &wdt { status = "okay"; }; diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.yaml b/boards/arm/sam4e_xpro/sam4e_xpro.yaml index b9392fc5089..79c357b5df5 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.yaml +++ b/boards/arm/sam4e_xpro/sam4e_xpro.yaml @@ -10,6 +10,7 @@ supported: - netif:eth - gpio - spi + - sdhc - watchdog - xpro_gpio - xpro_i2c From 6d67a56d5b5ddb3f744eb844e6b4f7d033be7a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Thu, 14 Sep 2023 11:00:22 +0200 Subject: [PATCH 0438/4498] drivers: serial: uart_nrfx_uart: fix NRFX_WAIT_FOR result type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro expects a bool variable to store the result. Signed-off-by: Martin Jäger --- drivers/serial/uart_nrfx_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/uart_nrfx_uart.c b/drivers/serial/uart_nrfx_uart.c index 4eb4e231474..25dab17ea74 100644 --- a/drivers/serial/uart_nrfx_uart.c +++ b/drivers/serial/uart_nrfx_uart.c @@ -285,7 +285,7 @@ static void uart_nrfx_poll_out(const struct device *dev, unsigned char c) nrf_uart_txd_set(uart0_addr, (uint8_t)c); /* Wait until the transmitter is ready, i.e. the character is sent. */ - int res; + bool res; NRFX_WAIT_FOR(event_txdrdy_check(), 1000, 1, res); From 79d0bf39b8402f2b59fbcad2860e2a25c270545e Mon Sep 17 00:00:00 2001 From: Florian La Roche Date: Tue, 22 Aug 2023 20:06:51 +0200 Subject: [PATCH 0439/4498] modules/acpica: CMakeLists.txt: move conditional to beginning of file Move the conditional compile of CONFIG_ACPI to the beginning of the file as we currently add compiler include paths to all projects even if CONFIG_ACPI is not set. Signed-off-by: Florian La Roche --- modules/acpica/CMakeLists.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/acpica/CMakeLists.txt b/modules/acpica/CMakeLists.txt index 17aed310448..2c77a6c1633 100644 --- a/modules/acpica/CMakeLists.txt +++ b/modules/acpica/CMakeLists.txt @@ -1,25 +1,25 @@ # Copyright (c) 2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(ACPI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/) -set(INC_DIR ${ACPI_DIR}/source/include/) -set(SRC_DIR ${ACPI_DIR}/source) -set(COMP_DIR ${ACPI_DIR}/source/components) -set(PARENT_SRC_DIR ${ACPI_DIR}../../zephyr) -set(ACPI_PARENT_DIR ${ACPI_DIR}/../) +if (CONFIG_ACPI) + set(ACPI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/) + set(INC_DIR ${ACPI_DIR}/source/include/) + set(SRC_DIR ${ACPI_DIR}/source) + set(COMP_DIR ${ACPI_DIR}/source/components) + set(PARENT_SRC_DIR ${ACPI_DIR}../../zephyr) + set(ACPI_PARENT_DIR ${ACPI_DIR}/../) -zephyr_include_directories( - ${PARENT_SRC_DIR}/include/ - ${ACPI_PARENT_DIR}/ - ${INC_DIR}/ - ${INC_DIR}/platform/ - ${SRC_DIR}/compiler/ - ${ZEPHYR_CURRENT_MODULE_DIR}/generate/zephyr/ - ${SRC_DIR}/tools/acpiexec/ - ${SRC_DIR}/tools/acpidump/ -) + zephyr_include_directories( + ${PARENT_SRC_DIR}/include/ + ${ACPI_PARENT_DIR}/ + ${INC_DIR}/ + ${INC_DIR}/platform/ + ${SRC_DIR}/compiler/ + ${ZEPHYR_CURRENT_MODULE_DIR}/generate/zephyr/ + ${SRC_DIR}/tools/acpiexec/ + ${SRC_DIR}/tools/acpidump/ + ) -if (CONFIG_ACPI) zephyr_library() add_compile_definitions(__ZEPHYR__) From 4bebb654913f320f9e94d42d9b7112988a7ae315 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 12 Sep 2023 13:54:05 -0700 Subject: [PATCH 0440/4498] tests: mem_protect/mem_protect: fix number of kobjects to test In test_kobject_perm_error, there are 13 kobjects to test but the loop only do 12. So amend the code to test all 13 kobjects. Also remove the parameter of tid to child thread as the child thread is not using it. Signed-off-by: Daniel Leung --- tests/kernel/mem_protect/mem_protect/src/kobject.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 2cb37c72eba..5314e81af28 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -1333,8 +1333,7 @@ struct k_condvar condvar; static void entry_error_perm(void *p1, void *p2, void *p3) { set_fault_valid(true); - k_object_access_grant(p2, k_current_get()); - + k_object_access_grant(p1, k_current_get()); } /** @@ -1350,7 +1349,9 @@ static void entry_error_perm(void *p1, void *p2, void *p3) */ ZTEST(mem_protect_kobj, test_kobject_perm_error) { - void *kobj[16]; +#define NUM_KOBJS 13 + + void *kobj[NUM_KOBJS]; kobj[0] = &ms; kobj[1] = &mq; @@ -1366,16 +1367,18 @@ ZTEST(mem_protect_kobj, test_kobject_perm_error) kobj[11] = &f; kobj[12] = &condvar; - for (int i = 0; i < 12 ; i++) { + for (int i = 0; i < NUM_KOBJS; i++) { k_tid_t tid = k_thread_create(&child_thread, child_stack, K_THREAD_STACK_SIZEOF(child_stack), (k_thread_entry_t)entry_error_perm, - (void *)&tid, kobj[i], NULL, + kobj[i], NULL, NULL, 1, K_USER, K_NO_WAIT); k_thread_join(tid, K_FOREVER); } + +#undef NUM_KOBJS } extern const char *otype_to_str(enum k_objects otype); From 3441c70117d8559b29a6604d0ec229c524d11252 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 12 Sep 2023 13:56:46 -0700 Subject: [PATCH 0441/4498] tests: mem_protect/mem_protect: reuse child thread and stack This reuses the child_thread variable and child_stack acorss test suites. Signed-off-by: Daniel Leung --- tests/kernel/mem_protect/mem_protect/src/kobject.c | 4 ++-- tests/kernel/mem_protect/mem_protect/src/mem_domain.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 5314e81af28..122184160d4 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -9,14 +9,14 @@ /* Kernel objects */ -K_THREAD_STACK_DEFINE(child_stack, KOBJECT_STACK_SIZE); +K_THREAD_STACK_DECLARE(child_stack, KOBJECT_STACK_SIZE); K_THREAD_STACK_DEFINE(extra_stack, KOBJECT_STACK_SIZE); K_SEM_DEFINE(kobject_sem, SEMAPHORE_INIT_COUNT, SEMAPHORE_MAX_COUNT); K_SEM_DEFINE(kobject_public_sem, SEMAPHORE_INIT_COUNT, SEMAPHORE_MAX_COUNT); K_MUTEX_DEFINE(kobject_mutex); -struct k_thread child_thread; +extern struct k_thread child_thread; struct k_thread extra_thread; struct k_sem *random_sem_type; diff --git a/tests/kernel/mem_protect/mem_protect/src/mem_domain.c b/tests/kernel/mem_protect/mem_protect/src/mem_domain.c index 5c4c6c1ce81..4ea5ad7ed1b 100644 --- a/tests/kernel/mem_protect/mem_protect/src/mem_domain.c +++ b/tests/kernel/mem_protect/mem_protect/src/mem_domain.c @@ -8,8 +8,8 @@ #include /* For z_main_thread */ #include /* for z_libc_partition */ -static struct k_thread child_thread; -static K_THREAD_STACK_DEFINE(child_stack, 512 + CONFIG_TEST_EXTRA_STACK_SIZE); +struct k_thread child_thread; +K_THREAD_STACK_DEFINE(child_stack, KOBJECT_STACK_SIZE); /* Special memory domain for test case purposes */ static struct k_mem_domain test_domain; From c5d224abb66378b931e2000a5581dae698f7f2c9 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Tue, 30 May 2023 04:04:29 +0000 Subject: [PATCH 0442/4498] dts: arm64: intel: Change compat string for Intel Agilex SiP SMC driver. Change compat string from intel,agilex-socfpga-sip-smc to intel,socfpga-agilex-sip-smc for Intel AGILEX SOC FPGA sip smc driver. Signed-off-by: Mahesh Rao --- drivers/sip_svc/Kconfig.sip_smc_agilex | 2 +- drivers/sip_svc/sip_smc_intel_socfpga.c | 4 ++-- dts/arm64/intel/intel_socfpga_agilex.dtsi | 2 +- dts/bindings/sip_svc/intel,agilex-socfpga-sip-smc.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/sip_svc/Kconfig.sip_smc_agilex b/drivers/sip_svc/Kconfig.sip_smc_agilex index 5b982e7c721..50e1247325c 100644 --- a/drivers/sip_svc/Kconfig.sip_smc_agilex +++ b/drivers/sip_svc/Kconfig.sip_smc_agilex @@ -4,7 +4,7 @@ config ARM_SIP_SVC_HAS_INTEL_SDM_MAILBOX_FIFO bool default y - depends on DT_HAS_INTEL_AGILEX_SOCFPGA_SIP_SMC_ENABLED + depends on DT_HAS_INTEL_SOCFPGA_AGILEX_SIP_SMC_ENABLED imply ARM_SIP_SVC_HAS_DRIVER help Support for SDM mailbox fifo in Intel SoC FPGA Agilex via SMC calls. diff --git a/drivers/sip_svc/sip_smc_intel_socfpga.c b/drivers/sip_svc/sip_smc_intel_socfpga.c index af6ffe95c71..c7cc599fef3 100644 --- a/drivers/sip_svc/sip_smc_intel_socfpga.c +++ b/drivers/sip_svc/sip_smc_intel_socfpga.c @@ -15,9 +15,9 @@ #include -LOG_MODULE_REGISTER(intel_agilex_socfpga_sip_smc, CONFIG_ARM_SIP_SVC_DRIVER_LOG_LEVEL); +LOG_MODULE_REGISTER(intel_socfpga_agilex_sip_smc, CONFIG_ARM_SIP_SVC_DRIVER_LOG_LEVEL); -#define DT_DRV_COMPAT intel_agilex_socfpga_sip_smc +#define DT_DRV_COMPAT intel_socfpga_agilex_sip_smc #define DT_SIP_SMC DT_COMPAT_GET_ANY_STATUS_OKAY(DT_DRV_COMPAT) diff --git a/dts/arm64/intel/intel_socfpga_agilex.dtsi b/dts/arm64/intel/intel_socfpga_agilex.dtsi index 63ef2c9629f..19957a19988 100644 --- a/dts/arm64/intel/intel_socfpga_agilex.dtsi +++ b/dts/arm64/intel/intel_socfpga_agilex.dtsi @@ -112,7 +112,7 @@ }; sip_smc: smc{ - compatible = "intel,agilex-socfpga-sip-smc"; + compatible = "intel,socfpga-agilex-sip-smc"; method = "smc"; status = "disabled"; zephyr,num-clients = <2>; diff --git a/dts/bindings/sip_svc/intel,agilex-socfpga-sip-smc.yaml b/dts/bindings/sip_svc/intel,agilex-socfpga-sip-smc.yaml index f7cb3af2b88..82a6f53dbf0 100644 --- a/dts/bindings/sip_svc/intel,agilex-socfpga-sip-smc.yaml +++ b/dts/bindings/sip_svc/intel,agilex-socfpga-sip-smc.yaml @@ -4,7 +4,7 @@ description: SiP SVC driver instance on Intel Agilex SOC FPGA for SMC call -compatible: "intel,agilex-socfpga-sip-smc" +compatible: "intel,socfpga-agilex-sip-smc" include: base.yaml From 17cfcaea13d9054548f8cf018f6e12ad506e2048 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Wed, 24 May 2023 05:19:08 +0000 Subject: [PATCH 0443/4498] driver: sip_svc: Add RSU_UPDATE_ADDR function id Add RSU UPDATE function id in sip_svc to set the RSU UPDATE ADDRESS in sip_svc_v2 for Intel Agilex SOCFPGA platform. Signed-off-by: Mahesh Rao --- drivers/sip_svc/sip_smc_intel_socfpga.c | 1 + include/zephyr/drivers/sip_svc/sip_svc_agilex_smc.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/sip_svc/sip_smc_intel_socfpga.c b/drivers/sip_svc/sip_smc_intel_socfpga.c index c7cc599fef3..583708414a5 100644 --- a/drivers/sip_svc/sip_smc_intel_socfpga.c +++ b/drivers/sip_svc/sip_smc_intel_socfpga.c @@ -39,6 +39,7 @@ static bool intel_sip_smc_plat_func_id_valid(const struct device *dev, uint32_t case SMC_FUNC_ID_REG_WRITE: case SMC_FUNC_ID_REG_UPDATE: case SMC_FUNC_ID_SET_HPS_BRIDGES: + case SMC_FUNC_ID_RSU_UPDATE_ADDR: valid = true; break; default: diff --git a/include/zephyr/drivers/sip_svc/sip_svc_agilex_smc.h b/include/zephyr/drivers/sip_svc/sip_svc_agilex_smc.h index 88c9002af17..4e430e72bf9 100644 --- a/include/zephyr/drivers/sip_svc/sip_svc_agilex_smc.h +++ b/include/zephyr/drivers/sip_svc/sip_svc_agilex_smc.h @@ -55,6 +55,7 @@ #define SMC_FUNC_ID_REG_WRITE 0xC2000402 #define SMC_FUNC_ID_REG_UPDATE 0xC2000403 #define SMC_FUNC_ID_SET_HPS_BRIDGES 0xC2000404 +#define SMC_FUNC_ID_RSU_UPDATE_ADDR 0xC2000405 /* @brief ASYNC SMC Function IDs */ From 629a6bf10698724c8c0fe0a8c4d198e90f763457 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Tue, 30 May 2023 07:21:20 +0000 Subject: [PATCH 0444/4498] drivers: sip_svc: sip_smc_intel_socfpga: Fix type error Fix typo error in code. Signed-off-by: Mahesh Rao --- drivers/sip_svc/sip_smc_intel_socfpga.c | 2 +- include/zephyr/drivers/sip_svc/sip_svc_proto.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/sip_svc/sip_smc_intel_socfpga.c b/drivers/sip_svc/sip_smc_intel_socfpga.c index 583708414a5..096bf0beb70 100644 --- a/drivers/sip_svc/sip_smc_intel_socfpga.c +++ b/drivers/sip_svc/sip_smc_intel_socfpga.c @@ -67,7 +67,7 @@ static uint32_t intel_sip_smc_plat_format_trans_id(const struct device *dev, uin { ARG_UNUSED(dev); - /*combine the transaction id and client id to get the job id*/ + /* Combine the transaction id and client id to get the job id*/ return (((client_idx & 0xF) << 4) | (trans_idx & 0xF)); } diff --git a/include/zephyr/drivers/sip_svc/sip_svc_proto.h b/include/zephyr/drivers/sip_svc/sip_svc_proto.h index 63eebec2cd3..08d2510e061 100644 --- a/include/zephyr/drivers/sip_svc/sip_svc_proto.h +++ b/include/zephyr/drivers/sip_svc/sip_svc_proto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Intel Corporation. + * Copyright (c) 2023, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ From f816f787e2f99c3083c0db052a62e0b596c3bf6d Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Thu, 22 Jun 2023 05:50:42 +0000 Subject: [PATCH 0445/4498] drivers: sip_svc: sip_smc_intel_socfpga: Log execution time Log execution time for each svc call. Signed-off-by: Mahesh Rao --- drivers/sip_svc/sip_smc_intel_socfpga.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/sip_svc/sip_smc_intel_socfpga.c b/drivers/sip_svc/sip_smc_intel_socfpga.c index 096bf0beb70..b4db6d48a86 100644 --- a/drivers/sip_svc/sip_smc_intel_socfpga.c +++ b/drivers/sip_svc/sip_smc_intel_socfpga.c @@ -172,8 +172,9 @@ static void intel_sip_secure_monitor_call(const struct device *dev, unsigned lon { __ASSERT_NO_MSG(dev != NULL); __ASSERT_NO_MSG(res != NULL); + uint64_t start, end; - LOG_INF("Before %s call", DT_PROP(DT_SIP_SMC, method)); + LOG_DBG("Before %s call", DT_PROP(DT_SIP_SMC, method)); LOG_DBG("\tfunction_id %08lx", function_id); LOG_DBG("\targ0 %08lx", arg0); LOG_DBG("\targ1 %08lx", arg1); @@ -183,9 +184,14 @@ static void intel_sip_secure_monitor_call(const struct device *dev, unsigned lon LOG_DBG("\targ5 %08lx", arg5); LOG_DBG("\targ6 %08lx", arg6); + start = k_cycle_get_64(); arm_smccc_smc(function_id, arg0, arg1, arg2, arg3, arg4, arg5, arg6, res); + end = k_cycle_get_64(); - LOG_INF("After %s call", DT_PROP(DT_SIP_SMC, method)); + LOG_INF("Time taken for %08lx is %08lld ns", function_id, + k_cyc_to_ns_ceil64(end - start)); + + LOG_DBG("After %s call", DT_PROP(DT_SIP_SMC, method)); LOG_DBG("\tres->a0 %08lx", res->a0); LOG_DBG("\tres->a1 %08lx", res->a1); LOG_DBG("\tres->a2 %08lx", res->a2); From 0993bce77d74453ad5daf2f536477243ad99b7e4 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Fri, 19 May 2023 12:50:33 +0000 Subject: [PATCH 0446/4498] subsystem: sip_svc: Increase stack size for sip_svc thread Increase sip_svc thread stack size to 4096. Signed-off-by: Mahesh Rao --- subsys/sip_svc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/sip_svc/Kconfig b/subsys/sip_svc/Kconfig index 1d1702f4905..298fe0b670f 100644 --- a/subsys/sip_svc/Kconfig +++ b/subsys/sip_svc/Kconfig @@ -22,7 +22,7 @@ config ARM_SIP_SVC_SUBSYS_INIT_PRIORITY config ARM_SIP_SVC_SUBSYS_THREAD_STACK_SIZE int "ARM SiP service thread stack size" - default 1856 + default 4096 help Stack size of the ARM SiP service. The thread calls the callbacks of the requestor From 7b2e82ecc7f06a47585817313688f66e645bea95 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Thu, 22 Jun 2023 05:51:58 +0000 Subject: [PATCH 0447/4498] subsystem: sip_svc: Check the number of clients as part of build Check number of clients as part of build. Signed-off-by: Mahesh Rao --- include/zephyr/sip_svc/sip_svc_controller.h | 4 ++++ subsys/sip_svc/sip_svc_subsys.c | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/zephyr/sip_svc/sip_svc_controller.h b/include/zephyr/sip_svc/sip_svc_controller.h index e74033670ff..614ba7aed52 100644 --- a/include/zephyr/sip_svc/sip_svc_controller.h +++ b/include/zephyr/sip_svc/sip_svc_controller.h @@ -93,6 +93,10 @@ struct sip_svc_controller { */ #define SIP_SVC_CONTROLLER_DEFINE(inst, conduit_name, sip_dev, sip_num_clients, \ sip_max_transactions, sip_resp_size) \ + BUILD_ASSERT( \ + ((sip_num_clients <= CONFIG_ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT) && \ + (sip_num_clients > 0)), \ + "Number of client should be within 1 and ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT"); \ static STRUCT_SECTION_ITERABLE(sip_svc_controller, sip_svc_##inst) = { \ .method = conduit_name, \ .dev = sip_dev, \ diff --git a/subsys/sip_svc/sip_svc_subsys.c b/subsys/sip_svc/sip_svc_subsys.c index 7bf5d52e133..56655d4be2f 100644 --- a/subsys/sip_svc/sip_svc_subsys.c +++ b/subsys/sip_svc/sip_svc_subsys.c @@ -839,12 +839,6 @@ static int sip_svc_subsys_init(void) } dev = (struct device *)(ctrl->dev); - if (ctrl->num_clients > CONFIG_ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT) { - LOG_ERR("number of clients cannot be greater than the " - "CONFIG_ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT"); - return -EPROTO; - } - LOG_INF("Got registered conduit %.*s", (int)sizeof(ctrl->method), ctrl->method); ctrl->async_resp_data = k_malloc(ctrl->resp_size); From 817f44f7144fdb5a0fb7f9d357217c9cb25c3637 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Thu, 22 Jun 2023 05:54:05 +0000 Subject: [PATCH 0448/4498] subsystem: sip_svc: Change polling delay to micro seconds Change polling delay to use microseconds. Signed-off-by: Mahesh Rao --- subsys/sip_svc/Kconfig | 4 ++-- subsys/sip_svc/sip_svc_subsys.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/sip_svc/Kconfig b/subsys/sip_svc/Kconfig index 298fe0b670f..c7cf1b36bc5 100644 --- a/subsys/sip_svc/Kconfig +++ b/subsys/sip_svc/Kconfig @@ -55,8 +55,8 @@ config ARM_SIP_SVC_SUBSYS_MAX_TRANSACTION_ID_COUNT Maximum number of transaction_id per client. config ARM_SIP_SVC_SUBSYS_ASYNC_POLLING_DELAY - int "Delay used for polling asynchronous jobs in milliseconds" - default 10 + int "Delay used for polling asynchronous jobs in micro-seconds" + default 100 help Delay for sip_svc thread to sleep during each polling call for ASYNC response. diff --git a/subsys/sip_svc/sip_svc_subsys.c b/subsys/sip_svc/sip_svc_subsys.c index 56655d4be2f..48e82f3ff4f 100644 --- a/subsys/sip_svc/sip_svc_subsys.c +++ b/subsys/sip_svc/sip_svc_subsys.c @@ -284,7 +284,7 @@ int sip_svc_open(void *ct, uint32_t c_token, k_timeout_t k_timeout) * transactions are complete. */ for (bool first_iteration = false; get_timer_status(&first_iteration, &timer, k_timeout); - k_msleep(CONFIG_ARM_SIP_SVC_SUBSYS_ASYNC_POLLING_DELAY)) { + k_usleep(CONFIG_ARM_SIP_SVC_SUBSYS_ASYNC_POLLING_DELAY)) { ret = k_mutex_lock(&ctrl->data_mutex, K_NO_WAIT); if (ret != 0) { @@ -331,7 +331,7 @@ int sip_svc_open(void *ct, uint32_t c_token, k_timeout_t k_timeout) /* Make the client state to be open and stop timer*/ ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_OPEN; - LOG_INF("%x successfully opened a connection with sip_svc", c_token); + LOG_INF("0x%x successfully opened a connection with sip_svc", c_token); k_mutex_unlock(&ctrl->data_mutex); k_timer_stop(&timer); return 0; @@ -661,7 +661,7 @@ static void sip_svc_thread(void *ctrl_ptr, void *arg2, void *arg3) /* sleep only when waiting for ASYNC responses*/ if (ret_msgq == 0 && ret_resp != 0) { - k_msleep(CONFIG_ARM_SIP_SVC_SUBSYS_ASYNC_POLLING_DELAY); + k_usleep(CONFIG_ARM_SIP_SVC_SUBSYS_ASYNC_POLLING_DELAY); } } LOG_INF("Suspend thread, all transactions are completed"); From 97f9d3c60b25b7576d12844c97ead26f3c2d5915 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Thu, 22 Jun 2023 05:54:56 +0000 Subject: [PATCH 0449/4498] subsystem: sip_svc: Initialize clients structure after allocation Initialize client structure after memory allocation. Signed-off-by: Mahesh Rao --- subsys/sip_svc/sip_svc_subsys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/sip_svc/sip_svc_subsys.c b/subsys/sip_svc/sip_svc_subsys.c index 48e82f3ff4f..e08c91df16e 100644 --- a/subsys/sip_svc/sip_svc_subsys.c +++ b/subsys/sip_svc/sip_svc_subsys.c @@ -878,6 +878,8 @@ static int sip_svc_subsys_init(void) return -ENOMEM; } + memset(ctrl->clients, 0, ctrl->num_clients * sizeof(struct sip_svc_client)); + /* Initialize request msgq */ k_msgq_init(&ctrl->req_msgq, msgq_buf, sizeof(struct sip_svc_request), CONFIG_ARM_SIP_SVC_SUBSYS_MSGQ_DEPTH); From c13466974eeb7fe2fe529849c696459bfaf66943 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Sun, 30 Jul 2023 12:47:34 +0000 Subject: [PATCH 0450/4498] subsystem: sip_svc: Use atomic variable for locking in singly open system Use atomic variable for singly open system. Add k_timer_stop() for sip_svc open timer(). Signed-off-by: Mahesh Rao --- include/zephyr/sip_svc/sip_svc_controller.h | 16 +++++++++++--- subsys/sip_svc/sip_svc_subsys.c | 23 +++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/include/zephyr/sip_svc/sip_svc_controller.h b/include/zephyr/sip_svc/sip_svc_controller.h index 614ba7aed52..2ce9394230b 100644 --- a/include/zephyr/sip_svc/sip_svc_controller.h +++ b/include/zephyr/sip_svc/sip_svc_controller.h @@ -13,11 +13,21 @@ #ifdef CONFIG_ARM_SIP_SVC_SUBSYS +#include + /** * @brief Length of SVC conduit name in sip svc subsystem. * */ -#define SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH (4) +#define SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH (4U) + +/** + * @brief Open lock states in sip_svc atomic variable + */ +enum open_state { + SIP_SVC_OPEN_UNLOCKED = 0, + SIP_SVC_OPEN_LOCKED +}; /** * @brief Arm SiP Service client data. @@ -73,8 +83,8 @@ struct sip_svc_controller { k_tid_t tid; #if CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN - /* Mutex to restrict one client access */ - struct k_mutex open_mutex; + /* Atomic variable to restrict one client access */ + atomic_t open_lock; #endif /* Mutex for protecting database access */ struct k_mutex data_mutex; diff --git a/subsys/sip_svc/sip_svc_subsys.c b/subsys/sip_svc/sip_svc_subsys.c index e08c91df16e..d4984abdf57 100644 --- a/subsys/sip_svc/sip_svc_subsys.c +++ b/subsys/sip_svc/sip_svc_subsys.c @@ -129,8 +129,7 @@ static inline bool is_sip_svc_controller(void *ct) return false; } - STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) - { + STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) { if ((void *)ctrl == ct) { return true; } @@ -320,10 +319,8 @@ int sip_svc_open(void *ct, uint32_t c_token, k_timeout_t k_timeout) * Acquire open lock, when only one client can transact at * a time. */ - ret = k_mutex_lock(&ctrl->open_mutex, K_NO_WAIT); - if (ret != 0) { - LOG_DBG("0x%x didn't get open lock, wait for it to be released, %d", - c_token, ret); + if (!atomic_cas(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED, SIP_SVC_OPEN_LOCKED)) { + LOG_DBG("0x%x didn't get open lock, wait for it to be released", c_token); k_mutex_unlock(&ctrl->data_mutex); continue; } @@ -337,6 +334,7 @@ int sip_svc_open(void *ct, uint32_t c_token, k_timeout_t k_timeout) return 0; } + k_timer_stop(&timer); LOG_ERR("Timedout at %s for 0x%x", __func__, c_token); return -ETIMEDOUT; } @@ -386,7 +384,7 @@ int sip_svc_close(void *ct, uint32_t c_token, struct sip_svc_request *pre_close_ } #if CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN - k_mutex_unlock(&ctrl->open_mutex); + (void)atomic_set(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED); #endif k_mutex_unlock(&ctrl->data_mutex); @@ -802,8 +800,7 @@ void *sip_svc_get_controller(char *method) /** * For more info on below code check @ref SIP_SVC_CONTROLLER_DEFINE() */ - STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) - { + STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) { if (!strncmp(ctrl->method, method, SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH)) { return (void *)ctrl; } @@ -831,8 +828,7 @@ static int sip_svc_subsys_init(void) * SIP_SVC_CONTROLLER_DEFINE(),see @ref SIP_SVC_CONTROLLER_DEFINE() for more * info. */ - STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) - { + STRUCT_SECTION_FOREACH(sip_svc_controller, ctrl) { if (!device_is_ready(ctrl->dev)) { LOG_ERR("device not ready"); return -ENODEV; @@ -926,10 +922,11 @@ static int sip_svc_subsys_init(void) ctrl->active_job_cnt = 0; ctrl->active_async_job_cnt = 0; - /* Initialize mutex */ + /* Initialize atomic variable */ #if CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN - k_mutex_init(&ctrl->open_mutex); + (void)atomic_set(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED); #endif + /* Initialize mutex */ k_mutex_init(&ctrl->data_mutex); ctrl->init = true; From a57a90feb439034c8c0379512c51f289bbe55b20 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Sun, 30 Jul 2023 12:52:55 +0000 Subject: [PATCH 0451/4498] subsystem: sip_svc: Reduce the max timeout to 1 second. Reduce the max timeout for shell to 1 second. Change the sip_svc open shell function to take millisecond as timeout argument. Signed-off-by: Mahesh Rao --- subsys/sip_svc/sip_svc_agilex_mailbox_shell.c | 26 +++++++++---------- subsys/sip_svc/sip_svc_shell.c | 19 +++++++------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/subsys/sip_svc/sip_svc_agilex_mailbox_shell.c b/subsys/sip_svc/sip_svc_agilex_mailbox_shell.c index ea6e237e777..7657b3b8d09 100644 --- a/subsys/sip_svc/sip_svc_agilex_mailbox_shell.c +++ b/subsys/sip_svc/sip_svc_agilex_mailbox_shell.c @@ -15,7 +15,7 @@ #include #include -#define MAX_TIMEOUT_SECS (10 * 60UL) +#define MAX_TIMEOUT_MSECS (1 * 1000UL) struct private_data { struct k_sem semaphore; @@ -76,10 +76,10 @@ static int cmd_unreg(const struct shell *sh, size_t argc, char **argv) static int cmd_open(const struct shell *sh, size_t argc, char **argv) { - unsigned long seconds = 0; + unsigned long mseconds = 0; int err; char *endptr; - k_timeout_t timeout = K_FOREVER; + k_timeout_t timeout = K_MSEC(MAX_TIMEOUT_MSECS); if (!mb_smc_ctrl) { shell_print(sh, "Mailbox client is not registered"); @@ -88,18 +88,18 @@ static int cmd_open(const struct shell *sh, size_t argc, char **argv) if (argc > 1) { errno = 0; - seconds = strtoul(argv[1], &endptr, 10); + mseconds = strtoul(argv[1], &endptr, 10); if (errno == ERANGE) { shell_error(sh, "out of range value"); return -ERANGE; } else if (errno || endptr == argv[1] || *endptr) { return -errno; - } else if (seconds <= MAX_TIMEOUT_SECS) { - timeout = K_SECONDS(seconds); + } else if (mseconds <= MAX_TIMEOUT_MSECS) { + timeout = K_MSEC(mseconds); } else { - timeout = K_SECONDS(MAX_TIMEOUT_SECS); - shell_error(sh, "Setting timeout value to %lu seconds", - MAX_TIMEOUT_SECS); + timeout = K_MSEC(MAX_TIMEOUT_MSECS); + shell_error(sh, "Setting timeout value to %lu milliseconds", + MAX_TIMEOUT_MSECS); } } @@ -281,11 +281,11 @@ static int cmd_send(const struct shell *sh, size_t argc, char **argv) } else if (errno || endptr == argv[2] || *endptr) { shell_error(sh, "Invalid argument"); return -EINVAL; - } else if (msecond <= (MSEC_PER_SEC * MAX_TIMEOUT_SECS)) { + } else if (msecond <= (MSEC_PER_SEC * MAX_TIMEOUT_MSECS)) { timeout = K_MSEC(msecond); } else { - timeout = K_SECONDS(MAX_TIMEOUT_SECS); - shell_error(sh, "Setting timeout value to %lu seconds", MAX_TIMEOUT_SECS); + timeout = K_SECONDS(MAX_TIMEOUT_MSECS); + shell_error(sh, "Setting timeout value to %lu seconds", MAX_TIMEOUT_MSECS); } } @@ -337,7 +337,7 @@ static int cmd_send(const struct shell *sh, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_mailbox, SHELL_CMD_ARG(reg, NULL, "", cmd_reg, 2, 0), SHELL_CMD_ARG(unreg, NULL, NULL, cmd_unreg, 1, 0), - SHELL_CMD_ARG(open, NULL, "[]", cmd_open, 1, 1), + SHELL_CMD_ARG(open, NULL, "[]", cmd_open, 1, 1), SHELL_CMD_ARG(close, NULL, NULL, cmd_close, 1, 0), SHELL_CMD_ARG(send, NULL, " []", diff --git a/subsys/sip_svc/sip_svc_shell.c b/subsys/sip_svc/sip_svc_shell.c index a291ad54558..c0d64495206 100644 --- a/subsys/sip_svc/sip_svc_shell.c +++ b/subsys/sip_svc/sip_svc_shell.c @@ -12,7 +12,7 @@ #include #include -#define MAX_TIMEOUT_SECS (10 * 60UL) +#define MAX_TIMEOUT_MSECS (1 * 1000UL) struct private_data { struct k_sem semaphore; @@ -98,10 +98,10 @@ static int cmd_open(const struct shell *sh, size_t argc, char **argv) { struct sip_svc_controller *ctrl; uint32_t c_token; - unsigned long seconds = 0; + unsigned long mseconds = 0; int err; char *endptr; - k_timeout_t timeout = K_FOREVER; + k_timeout_t timeout = K_MSEC(MAX_TIMEOUT_MSECS); err = parse_common_args(sh, argv, (void **)&ctrl); if (err < 0) { @@ -120,18 +120,19 @@ static int cmd_open(const struct shell *sh, size_t argc, char **argv) if (argc > 3) { errno = 0; - seconds = strtoul(argv[3], &endptr, 10); + mseconds = strtoul(argv[3], &endptr, 10); if (errno == ERANGE) { shell_error(sh, "Out of range value"); return -ERANGE; } else if (errno || endptr == argv[3] || *endptr) { shell_error(sh, "Invalid Argument"); return -EINVAL; - } else if (seconds <= MAX_TIMEOUT_SECS) { - timeout = K_SECONDS(seconds); + } else if (mseconds <= MAX_TIMEOUT_MSECS) { + timeout = K_MSEC(mseconds); } else { - timeout = K_SECONDS(MAX_TIMEOUT_SECS); - shell_error(sh, "Setting timeout value to %lu", MAX_TIMEOUT_SECS); + timeout = K_MSEC(MAX_TIMEOUT_MSECS); + shell_error(sh, "Setting timeout value to %lu milliseconds", + MAX_TIMEOUT_MSECS); } } @@ -376,7 +377,7 @@ static int cmd_info(const struct shell *sh, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_sip_svc, SHELL_CMD_ARG(reg, NULL, "", cmd_reg, 2, 0), SHELL_CMD_ARG(unreg, NULL, " ", cmd_unreg, 3, 0), - SHELL_CMD_ARG(open, NULL, " <[timeout_sec]>", cmd_open, 3, 1), + SHELL_CMD_ARG(open, NULL, " <[timeout_msec]>", cmd_open, 3, 1), SHELL_CMD_ARG(close, NULL, " ", cmd_close, 3, 0), SHELL_CMD_ARG(send, NULL, " [ ... ]", cmd_send, 4, 7), SHELL_CMD_ARG(info, NULL, "", cmd_info, 2, 0), SHELL_SUBCMD_SET_END); From 1a4e5dff5d32960076b1a3c6b37bee0354821197 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Fri, 12 May 2023 16:21:25 +0000 Subject: [PATCH 0452/4498] dts: arm64: intel: Add support for sip_svc for agilex5 Add support for SiP SVC driver for intel_socfpga_agilex5_socdk. Signed-off-by: Mahesh Rao --- dts/arm64/intel/intel_socfpga_agilex5.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/arm64/intel/intel_socfpga_agilex5.dtsi b/dts/arm64/intel/intel_socfpga_agilex5.dtsi index 7ecdac4fc9e..6a98aa34df9 100644 --- a/dts/arm64/intel/intel_socfpga_agilex5.dtsi +++ b/dts/arm64/intel/intel_socfpga_agilex5.dtsi @@ -160,4 +160,11 @@ resets = <&reset RSTMGR_L4SYSTIMER1_RSTLINE>; status = "disabled"; }; + + sip_smc: smc{ + compatible = "intel,socfpga-agilex-sip-smc"; + method = "smc"; + status = "disabled"; + zephyr,num-clients = <2>; + }; }; From 80a863f9470d44ee6760f0b3e059d7b4a648865e Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Thu, 22 Jun 2023 06:00:14 +0000 Subject: [PATCH 0453/4498] tests: sip_svc: Add a stress test for sip_svc subsystem Add a stress test for sip_svc subsystem using INTEL SOCFPGA AGILEX platform. Signed-off-by: Mahesh Rao --- tests/subsys/sip_svc/CMakeLists.txt | 9 + tests/subsys/sip_svc/Kconfig | 20 ++ .../intel_socfpga_agilex5_socdk.overlay | 11 + .../boards/intel_socfpga_agilex_socdk.overlay | 11 + tests/subsys/sip_svc/prj.conf | 14 + tests/subsys/sip_svc/src/main.c | 260 ++++++++++++++++++ tests/subsys/sip_svc/testcase.yaml | 11 + 7 files changed, 336 insertions(+) create mode 100644 tests/subsys/sip_svc/CMakeLists.txt create mode 100644 tests/subsys/sip_svc/Kconfig create mode 100644 tests/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay create mode 100644 tests/subsys/sip_svc/boards/intel_socfpga_agilex_socdk.overlay create mode 100644 tests/subsys/sip_svc/prj.conf create mode 100644 tests/subsys/sip_svc/src/main.c create mode 100644 tests/subsys/sip_svc/testcase.yaml diff --git a/tests/subsys/sip_svc/CMakeLists.txt b/tests/subsys/sip_svc/CMakeLists.txt new file mode 100644 index 00000000000..a24518d44a8 --- /dev/null +++ b/tests/subsys/sip_svc/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(integration) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/sip_svc/Kconfig b/tests/subsys/sip_svc/Kconfig new file mode 100644 index 00000000000..bb6e047a801 --- /dev/null +++ b/tests/subsys/sip_svc/Kconfig @@ -0,0 +1,20 @@ +# Private config options for sip svc stress test app + +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Intel Agilex SiP SVC stress test" + +config PACKETS_PER_ITERATION + int + default 3 + help + Number of SYNC and ASYNC packets to be sent per iteration + +config ITERATIONS + int + default 7 + help + Number of iterations to be performed. + +source "Kconfig.zephyr" diff --git a/tests/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay b/tests/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay new file mode 100644 index 00000000000..0598c9b1de4 --- /dev/null +++ b/tests/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2023, Intel Corporation + * + */ + +&sip_smc { + status = "okay"; + zephyr,num-clients = <16>; +}; diff --git a/tests/subsys/sip_svc/boards/intel_socfpga_agilex_socdk.overlay b/tests/subsys/sip_svc/boards/intel_socfpga_agilex_socdk.overlay new file mode 100644 index 00000000000..0598c9b1de4 --- /dev/null +++ b/tests/subsys/sip_svc/boards/intel_socfpga_agilex_socdk.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2023, Intel Corporation + * + */ + +&sip_smc { + status = "okay"; + zephyr,num-clients = <16>; +}; diff --git a/tests/subsys/sip_svc/prj.conf b/tests/subsys/sip_svc/prj.conf new file mode 100644 index 00000000000..61be5b51966 --- /dev/null +++ b/tests/subsys/sip_svc/prj.conf @@ -0,0 +1,14 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTRESS=y +CONFIG_ZTRESS_MAX_THREADS=16 +CONFIG_NUM_PREEMPT_PRIORITIES=18 +CONFIG_ZTRESS_REPORT_PROGRESS_MS=0 + +# SiP SVC Service +CONFIG_ARM_SIP_SVC_DRIVER=y +CONFIG_ARM_SIP_SVC_SUBSYS=y +CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN=y + +# Misc +CONFIG_HEAP_MEM_POOL_SIZE=16384 diff --git a/tests/subsys/sip_svc/src/main.c b/tests/subsys/sip_svc/src/main.c new file mode 100644 index 00000000000..49efc28028e --- /dev/null +++ b/tests/subsys/sip_svc/src/main.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2023, Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +ZTEST_SUITE(sip_svc_tests, NULL, NULL, NULL, NULL, NULL); + +#define SVC_METHOD "smc" +#define ECHO_CMD (0x01U) +#define TEST_VAL (0xDEADBEEFU) + +#define SIP_SVC_CLIENT_INSTANCES CONFIG_ZTRESS_MAX_THREADS + +struct private_data { + uint64_t time_start; + uint64_t time_end; + struct k_sem semaphore; +}; + +struct total_time { + uint64_t sync_time; + uint64_t async_time; +}; + +static void get_sync_callback(uint32_t c_token, struct sip_svc_response *response) +{ + if (response == NULL) { + return; + } + + struct private_data *priv = (struct private_data *)response->priv_data; + + priv->time_end = k_cycle_get_64(); + printk("sip_svc version in TFA is %2ld.%02ld\n", response->a2, response->a3); + + k_sem_give(&(priv->semaphore)); +} + +/** + * @brief send SYNC request + * + * @param token sip_svc token + */ +static void sip_svc_send_sync_request(uint32_t token) +{ + int err, trans_id; + void *ctrl; + uint64_t t = 0; + struct total_time *tot_time; + struct private_data priv; + struct sip_svc_request req = {0}; + + ctrl = sip_svc_get_controller(SVC_METHOD); + __ASSERT(ctrl != NULL, "couldn't get the controller"); + + tot_time = (struct total_time *)sip_svc_get_priv_data(ctrl, token); + __ASSERT(tot_time != NULL, "tot_time should not be NULL"); + + err = sip_svc_open(ctrl, token, K_FOREVER); + __ASSERT(err == 0, "couldn't open channel"); + + k_sem_init(&(priv.semaphore), 0, 1); + + req.header = SIP_SVC_PROTO_HEADER(SIP_SVC_PROTO_CMD_SYNC, 0); + req.a0 = SMC_FUNC_ID_GET_SVC_VERSION; + req.priv_data = (void *)&priv; + + priv.time_start = k_cycle_get_64(); + trans_id = sip_svc_send(ctrl, token, &req, get_sync_callback); + __ASSERT(trans_id >= 0, "error in sending request"); + + err = k_sem_take(&(priv.semaphore), K_FOREVER); + __ASSERT(err == 0, "Error in taking semaphore"); + + t = k_cyc_to_us_ceil64(priv.time_end - priv.time_start); + tot_time->sync_time += t; + + printk("In %s got SYNC response for id 0x%02x and time taken is %lldus\n", + k_thread_name_get(k_current_get()), trans_id, t); + + err = sip_svc_close(ctrl, token, NULL); + __ASSERT(err == 0, "error in closing channel"); +} + +static void get_async_callback(uint32_t c_token, struct sip_svc_response *response) +{ + if (response == NULL) { + return; + } + + struct private_data *priv = (struct private_data *)response->priv_data; + + priv->time_end = k_cycle_get_64(); + uint32_t *resp_data = (uint32_t *)response->resp_data_addr; + uint32_t resp_len = response->resp_data_size / sizeof(uint32_t); + + if (resp_data && resp_len) { + __ASSERT((resp_data[1] == TEST_VAL), "SDM response is not matching"); + } + + k_sem_give(&(priv->semaphore)); + k_free(resp_data); +} + +/** + * @brief send ASYNC request + * + * @param token sip_svc token + */ +static void sip_svc_send_async_request(uint32_t token) +{ + int err, trans_id; + /* size of mailbox command buffer, here we require 2 words */ + uint32_t cmd_size = (2 * sizeof(uint32_t)); + /* size of mailbox response buffer, here we require 2 words */ + uint32_t resp_size = (2 * sizeof(uint32_t)); + uint64_t t = 0; + uint32_t *cmd_addr, *resp_addr; + void *ctrl; + struct total_time *tot_time; + struct private_data priv; + struct sip_svc_request req = {0}; + + ctrl = sip_svc_get_controller(SVC_METHOD); + __ASSERT(ctrl != NULL, "couldn't get the controller"); + + err = sip_svc_open(ctrl, token, K_FOREVER); + __ASSERT(err == 0, "couldn't open channel"); + + tot_time = (struct total_time *)sip_svc_get_priv_data(ctrl, token); + __ASSERT(tot_time != NULL, "tot_time should not be NULL"); + + resp_addr = (uint32_t *)k_malloc(resp_size); + __ASSERT(resp_addr != NULL, "couldn' get memory"); + + k_sem_init(&(priv.semaphore), 0, 1); + + cmd_addr = (uint32_t *)k_malloc(cmd_size); + __ASSERT(cmd_addr != NULL, "couldn't get memory"); + + cmd_addr[0] = (1 << 12) | ECHO_CMD; + cmd_addr[1] = 0xDEADBEEF; + + req.header = SIP_SVC_PROTO_HEADER(SIP_SVC_PROTO_CMD_ASYNC, 0); + req.a0 = SMC_FUNC_ID_MAILBOX_SEND_COMMAND; + req.a2 = (uint64_t)cmd_addr; + req.a3 = (uint64_t)cmd_size; + req.resp_data_addr = (uint64_t)resp_addr; + req.resp_data_size = (uint64_t)resp_size; + req.priv_data = (void *)&priv; + + priv.time_start = k_cycle_get_64(); + trans_id = sip_svc_send(ctrl, token, &req, get_async_callback); + __ASSERT(trans_id >= 0, "error in sending request"); + + err = k_sem_take(&(priv.semaphore), K_FOREVER); + __ASSERT(err == 0, "Error in taking semaphore"); + + t = k_cyc_to_us_ceil64(priv.time_end - priv.time_start); + tot_time->async_time += t; + + printk("In %s got ASYNC response for id 0x%02x and time taken is %lldus\n", + k_thread_name_get(k_current_get()), trans_id, t); + + err = sip_svc_close(ctrl, token, NULL); + __ASSERT(err == 0, "error in closing channel"); +} + +static bool sip_svc_register_and_send(void *user_data, uint32_t cnt, bool last, int prio) +{ + int err, token; + void *ctrl; + + printk("\nIn %s and count is %d\n", k_thread_name_get(k_current_get()), cnt); + + ctrl = sip_svc_get_controller(SVC_METHOD); + if (ctrl == NULL) { + return false; + } + + token = sip_svc_register(ctrl, user_data); + if (token == SIP_SVC_ID_INVALID) { + return false; + } + + for (uint32_t i = 0; i < CONFIG_PACKETS_PER_ITERATION; i++) { + sip_svc_send_sync_request(token); + sip_svc_send_async_request(token); + } + + err = sip_svc_unregister(ctrl, token); + if (err < 0) { + return false; + } + + return true; +} + +ZTEST(sip_svc_tests, test_sip_stress) +{ + struct total_time t[SIP_SVC_CLIENT_INSTANCES] = {0}; + struct total_time average = {0}; + + ZTRESS_EXECUTE(ZTRESS_THREAD(sip_svc_register_and_send, &t[0], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[1], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[2], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[3], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[4], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[5], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[6], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[7], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[8], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[9], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[10], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[11], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[12], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[13], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[14], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10)), + ZTRESS_THREAD(sip_svc_register_and_send, &t[15], CONFIG_ITERATIONS, 0, + Z_TIMEOUT_TICKS(10))); + + for (uint32_t i = 0; i < SIP_SVC_CLIENT_INSTANCES; i++) { + average.sync_time += t[i].sync_time; + average.async_time += t[i].async_time; + } + + average.sync_time = average.sync_time / (CONFIG_ITERATIONS * CONFIG_PACKETS_PER_ITERATION * + SIP_SVC_CLIENT_INSTANCES); + average.async_time = + average.async_time / + (CONFIG_ITERATIONS * CONFIG_PACKETS_PER_ITERATION * SIP_SVC_CLIENT_INSTANCES); + + printk("\n***************************************\n"); + printk("Average SYNC transaction time is %lldus\n", average.sync_time); + printk("Average ASYNC transaction time is %lldus\n", average.async_time); + printk("\n***************************************\n"); +} diff --git a/tests/subsys/sip_svc/testcase.yaml b/tests/subsys/sip_svc/testcase.yaml new file mode 100644 index 00000000000..3cd6a496b29 --- /dev/null +++ b/tests/subsys/sip_svc/testcase.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2022-2023, Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +tests: + sip_svc.stress_test.ztest: + build_only: true + platform_allow: intel_socfpga_agilex_socdk intel_socfpga_agilex5_socdk + integration_platforms: + - intel_socfpga_agilex_socdk + - intel_socfpga_agilex5_socdk + tags: sip_svc From 5a7552bce889542ac8978de5c15b644f35ee9c24 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Fri, 12 May 2023 16:30:40 +0000 Subject: [PATCH 0454/4498] samples: sip_svc: Add support for intel_socfpga_agilex5_socdk Add support for intel_socfpga_agilex5_socdk for sip_svc sample application. Signed-off-by: Mahesh Rao --- .../boards/intel_socfpga_agilex5_socdk.overlay | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 samples/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay diff --git a/samples/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay b/samples/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay new file mode 100644 index 00000000000..4a6c02a6b1e --- /dev/null +++ b/samples/subsys/sip_svc/boards/intel_socfpga_agilex5_socdk.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2023, Intel Corporation + * + */ + +&sip_smc { + status = "okay"; + zephyr,num-clients = <1>; +}; From dec80da4c0cd8a987d00725ddf5d022ffdfd29a0 Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Wed, 13 Sep 2023 11:13:19 +0000 Subject: [PATCH 0455/4498] samples: subsys: shell_module: Add support for intel_socfpga_agilex series Add sip_svc shell support to intel_socfpga_agilex_socdk and intel_socfpga_agilex5_socdk boards. Signed-off-by: Mahesh Rao --- .../boards/intel_socfpga_agilex5_socdk.conf | 8 +++++++ .../intel_socfpga_agilex5_socdk.overlay | 5 ++++ .../boards/intel_socfpga_agilex_socdk.conf | 23 +++++++++++++++++++ .../boards/intel_socfpga_agilex_socdk.overlay | 15 ++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.conf create mode 100644 samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.overlay diff --git a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.conf b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.conf index ad18b0509ce..489e3f9fe16 100644 --- a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.conf +++ b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.conf @@ -19,3 +19,11 @@ CONFIG_COUNTER=y # Enable Timer shell commands CONFIG_COUNTER_SHELL=y + +#SiP SVC Service +CONFIG_ARM_SIP_SVC_DRIVER=y +CONFIG_ARM_SIP_SVC_SUBSYS=y +CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN=y + +#SiP SVC Service Shell +CONFIG_ARM_SIP_SVC_SUBSYS_SHELL=y diff --git a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.overlay b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.overlay index 86a4fdb4843..a35c307aeca 100644 --- a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.overlay +++ b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex5_socdk.overlay @@ -26,3 +26,8 @@ &timer3 { status = "okay"; }; + +&sip_smc { + status = "okay"; + zephyr,num-clients = <2>; +}; diff --git a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.conf b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.conf new file mode 100644 index 00000000000..22a3788b1b8 --- /dev/null +++ b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.conf @@ -0,0 +1,23 @@ +# Copyright (c) 2023, Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# Misc +CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_SHELL_STACK_SIZE=8192 + +# Setting the Shell prompt +CONFIG_SHELL_PROMPT_UART="agilex$ " + +# Setting the max argc +CONFIG_SHELL_ARGC_MAX=12 + +# Enable the Zephyr boot banner +CONFIG_BOOT_BANNER=y + +#SiP SVC Service +CONFIG_ARM_SIP_SVC_DRIVER=y +CONFIG_ARM_SIP_SVC_SUBSYS=y +CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN=y + +#SiP SVC Service Shell +CONFIG_ARM_SIP_SVC_SUBSYS_SHELL=y diff --git a/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.overlay b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.overlay new file mode 100644 index 00000000000..7b96b8e2b28 --- /dev/null +++ b/samples/subsys/shell/shell_module/boards/intel_socfpga_agilex_socdk.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The overlay file should be used to enable any + * dts nodes required by this shell application for this + * board. + */ + +&sip_smc { + status = "okay"; + zephyr,num-clients = <2>; +}; From 4dc648642f733c99ba917e3b908f44bdab909907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Thu, 14 Sep 2023 06:17:05 +0200 Subject: [PATCH 0456/4498] west: Fix a typo in the fish completion script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the `help` command, 'status' was written 'statue'. Signed-off-by: Théo Battrel --- scripts/west_commands/completion/west-completion.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/completion/west-completion.fish b/scripts/west_commands/completion/west-completion.fish index b8fc9cfa84e..92dbc65c800 100644 --- a/scripts/west_commands/completion/west-completion.fish +++ b/scripts/west_commands/completion/west-completion.fish @@ -162,7 +162,7 @@ function __zephyr_west_complete_help "list" "print information about projects" \ "manifest" "manage the west manifest" \ "diff" '"git diff" for one or more projects' \ - "statue" '"git status" for one or more projects' \ + "status" '"git status" for one or more projects' \ "forall" "run a command in one or more local projects" \ "config" "get or set config file values" \ "topdir" "print the top level directory of the workspace" \ From e5de0b68249fbf93399adcd410058984e6874987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Thu, 14 Sep 2023 06:25:29 +0200 Subject: [PATCH 0457/4498] west: fix wrong zsh completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The subcommand 'spdx' was suggesting '-d' for SPDX output directory instead of '-s'. Signed-off-by: Théo Battrel --- scripts/west_commands/completion/west-completion.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/completion/west-completion.zsh b/scripts/west_commands/completion/west-completion.zsh index 43c7c0ffc19..b3a881288c0 100644 --- a/scripts/west_commands/completion/west-completion.zsh +++ b/scripts/west_commands/completion/west-completion.zsh @@ -300,7 +300,7 @@ _west_spdx() { '(-i --init)'{-i,--init}'[initialize CMake file-based API]' '(-d --build-dir)'{-d,--build-dir}'[build directory to create or use]:build dir:_directories' '(-n --namespace-prefix)'{-n,--namespace-prefix}'[namespace prefix]:namespace prefix:' - '(-s --spdx-dir)'{-d,--spdx-dir}'[SPDX output directory]:spdx output dir:_directories' + '(-s --spdx-dir)'{-s,--spdx-dir}'[SPDX output directory]:spdx output dir:_directories' '--analyze-includes[also analyze included header files]' '--include-sdk[also generate SPDX document for SDK]' ) From aaeb0a672ecf31e2e776fc141bf1e26b7835c3a3 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 11:47:58 +0200 Subject: [PATCH 0458/4498] toolchain: only include It is wrong to use toolchain-specific header files. Signed-off-by: Gerard Marull-Paretas --- drivers/adc/adc_stm32.c | 2 +- soc/arm/aspeed/aspeed_util.h | 2 +- soc/riscv/espressif_esp32/esp32c3/soc.c | 2 +- soc/riscv/espressif_esp32/esp32c3/soc_irq.c | 2 +- soc/xtensa/espressif_esp32/esp32/soc.c | 2 +- soc/xtensa/espressif_esp32/esp32_net/soc.c | 2 +- soc/xtensa/espressif_esp32/esp32s2/soc.c | 2 +- soc/xtensa/espressif_esp32/esp32s3/soc.c | 2 +- subsys/usb/device_next/usbd_class.c | 2 +- subsys/usb/device_next/usbd_core.c | 2 +- tests/bsim/bluetooth/host/adv/resume/src/dut.c | 2 +- tests/bsim/bluetooth/host/gatt/settings/src/client.c | 2 +- tests/bsim/bluetooth/host/gatt/settings/src/server.c | 2 +- tests/bsim/bluetooth/host/privacy/central/src/tester.c | 2 +- tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c | 2 +- .../host/security/bond_overwrite_allowed/src/peripheral.c | 2 +- .../host/security/bond_overwrite_denied/src/peripheral.c | 2 +- .../host/security/bond_per_connection/src/peripheral.c | 2 +- .../host/security/id_addr_update/peripheral/src/peripheral.c | 2 +- west.yml | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 4bff19ce57c..ad8fcdcb1fd 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -27,7 +27,7 @@ #ifdef CONFIG_ADC_STM32_DMA #include #include -#include +#include #include #endif diff --git a/soc/arm/aspeed/aspeed_util.h b/soc/arm/aspeed/aspeed_util.h index 27a4a504e78..c1b656aeaee 100644 --- a/soc/arm/aspeed/aspeed_util.h +++ b/soc/arm/aspeed/aspeed_util.h @@ -7,7 +7,7 @@ #define ZEPHYR_SOC_ARM_ASPEED_UTIL_H_ #include #include -#include +#include /* gcc.h doesn't define __section but checkpatch.pl will complain for this. so * temporarily add a macro here. diff --git a/soc/riscv/espressif_esp32/esp32c3/soc.c b/soc/riscv/espressif_esp32/esp32c3/soc.c index be94280a96a..8bb32a5febd 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc.c +++ b/soc/riscv/espressif_esp32/esp32c3/soc.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_MCUBOOT diff --git a/soc/riscv/espressif_esp32/esp32c3/soc_irq.c b/soc/riscv/espressif_esp32/esp32c3/soc_irq.c index e1be1d23019..44c8161950c 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc_irq.c +++ b/soc/riscv/espressif_esp32/esp32c3/soc_irq.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/soc/xtensa/espressif_esp32/esp32/soc.c b/soc/xtensa/espressif_esp32/esp32/soc.c index 953c4797ce9..2abd0f6a88a 100644 --- a/soc/xtensa/espressif_esp32/esp32/soc.c +++ b/soc/xtensa/espressif_esp32/esp32/soc.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/soc/xtensa/espressif_esp32/esp32_net/soc.c b/soc/xtensa/espressif_esp32/esp32_net/soc.c index bec52472e3e..ac53ccb7e74 100644 --- a/soc/xtensa/espressif_esp32/esp32_net/soc.c +++ b/soc/xtensa/espressif_esp32/esp32_net/soc.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/soc/xtensa/espressif_esp32/esp32s2/soc.c b/soc/xtensa/espressif_esp32/esp32s2/soc.c index 9fc9701db52..45edde47178 100644 --- a/soc/xtensa/espressif_esp32/esp32s2/soc.c +++ b/soc/xtensa/espressif_esp32/esp32s2/soc.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include "esp_private/system_internal.h" diff --git a/soc/xtensa/espressif_esp32/esp32s3/soc.c b/soc/xtensa/espressif_esp32/esp32s3/soc.c index 4d44fe2f004..617ee05aabb 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/soc.c +++ b/soc/xtensa/espressif_esp32/esp32s3/soc.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/subsys/usb/device_next/usbd_class.c b/subsys/usb/device_next/usbd_class.c index 407e9145258..64610fa3d53 100644 --- a/subsys/usb/device_next/usbd_class.c +++ b/subsys/usb/device_next/usbd_class.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/subsys/usb/device_next/usbd_core.c b/subsys/usb/device_next/usbd_core.c index 5e68ccfcafa..e025397cc85 100644 --- a/subsys/usb/device_next/usbd_core.c +++ b/subsys/usb/device_next/usbd_core.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/bsim/bluetooth/host/adv/resume/src/dut.c b/tests/bsim/bluetooth/host/adv/resume/src/dut.c index fac6d919e24..40e4612b04d 100644 --- a/tests/bsim/bluetooth/host/adv/resume/src/dut.c +++ b/tests/bsim/bluetooth/host/adv/resume/src/dut.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/gatt/settings/src/client.c b/tests/bsim/bluetooth/host/gatt/settings/src/client.c index 8720fdea219..fc33f17bd4b 100644 --- a/tests/bsim/bluetooth/host/gatt/settings/src/client.c +++ b/tests/bsim/bluetooth/host/gatt/settings/src/client.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/gatt/settings/src/server.c b/tests/bsim/bluetooth/host/gatt/settings/src/server.c index 9457febc5d4..7fff0f72c15 100644 --- a/tests/bsim/bluetooth/host/gatt/settings/src/server.c +++ b/tests/bsim/bluetooth/host/gatt/settings/src/server.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/privacy/central/src/tester.c b/tests/bsim/bluetooth/host/privacy/central/src/tester.c index d511202c450..1c29b53e0c4 100644 --- a/tests/bsim/bluetooth/host/privacy/central/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/central/src/tester.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include DEFINE_FLAG(flag_new_address); diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c index 6446545d72a..3000a3e0f9e 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "common/bt_str.h" diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c index e0e6a81fe93..633768879d3 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_allowed/src/peripheral.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c index c6baf98c689..319779c94f1 100644 --- a/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_overwrite_denied/src/peripheral.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c index 8cd01f194ec..9b368cce26e 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c index bbdfc055021..5420fdf0dd4 100644 --- a/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/id_addr_update/peripheral/src/peripheral.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/west.yml b/west.yml index f0005c12d4d..5a39a5d2e0f 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 06c956741a81eb0fd3c0c31367c3c177bffaaab8 + revision: 5331fe2ff1310b033bf01cd3a232f1e587726e3b path: modules/hal/nxp groups: - hal From 6ee650a91783114368640cd83fd780f877b2f8d6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 11:51:56 +0200 Subject: [PATCH 0459/4498] toolchain: do not allow including toolchain-specific headers Toolchain utilities need to be used through the parent header, where the right header is chosen. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/toolchain/armclang.h | 3 +++ include/zephyr/toolchain/common.h | 5 +++++ include/zephyr/toolchain/gcc.h | 4 ++++ include/zephyr/toolchain/llvm.h | 3 +++ include/zephyr/toolchain/mwdt.h | 4 ++++ include/zephyr/toolchain/xcc.h | 4 ++++ 6 files changed, 23 insertions(+) diff --git a/include/zephyr/toolchain/armclang.h b/include/zephyr/toolchain/armclang.h index 89081227be0..d8dfa235a16 100644 --- a/include/zephyr/toolchain/armclang.h +++ b/include/zephyr/toolchain/armclang.h @@ -7,6 +7,9 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_ARMCLANG_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_ARMCLANG_H_ +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif #include diff --git a/include/zephyr/toolchain/common.h b/include/zephyr/toolchain/common.h index ea6c0db5f4e..c84328365fd 100644 --- a/include/zephyr/toolchain/common.h +++ b/include/zephyr/toolchain/common.h @@ -6,6 +6,11 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif + /** * @file * @brief Common toolchain abstraction diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index 04c0654888a..a0e325cfa28 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -7,6 +7,10 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif + /** * @file * @brief GCC toolchain abstraction diff --git a/include/zephyr/toolchain/llvm.h b/include/zephyr/toolchain/llvm.h index 990cbe6ada4..8a78d4e8404 100644 --- a/include/zephyr/toolchain/llvm.h +++ b/include/zephyr/toolchain/llvm.h @@ -7,6 +7,9 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_LLVM_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_LLVM_H_ +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif #define __no_optimization __attribute__((optnone)) diff --git a/include/zephyr/toolchain/mwdt.h b/include/zephyr/toolchain/mwdt.h index 60bcc1c4919..0da5e7bbee5 100644 --- a/include/zephyr/toolchain/mwdt.h +++ b/include/zephyr/toolchain/mwdt.h @@ -8,6 +8,10 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_MWDT_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_MWDT_H_ +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif + #ifndef _LINKER #if defined(_ASMLANGUAGE) diff --git a/include/zephyr/toolchain/xcc.h b/include/zephyr/toolchain/xcc.h index 65ddc7ea35e..ae4bb811ec0 100644 --- a/include/zephyr/toolchain/xcc.h +++ b/include/zephyr/toolchain/xcc.h @@ -7,6 +7,10 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_XCC_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_XCC_H_ +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif + /* toolchain/gcc.h errors out if __BYTE_ORDER__ cannot be determined * there. However, __BYTE_ORDER__ is actually being defined later in * this file. So define __BYTE_ORDER__ to skip the check in gcc.h From afd48e03d064568a536e89038d1a31a50cd76349 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 16 Jun 2023 18:36:10 +0530 Subject: [PATCH 0460/4498] Bluetooth: Controller: Minor clean up of redundant initialization Minor clean up of redundant initialization. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 10 +--------- subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 4 ---- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 49ab4909e3e..71b8d742a76 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -690,15 +690,6 @@ void ll_cis_create(uint16_t cis_handle, uint16_t acl_handle) /* Initialize stream states */ cis->established = 0; cis->teardown = 0; - cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; - cis->lll.sn = 0; - cis->lll.nesn = 0; - cis->lll.cie = 0; - cis->lll.flush = LLL_CIS_FLUSH_NONE; - cis->lll.active = 0; - cis->lll.datapath_ready_rx = 0; - cis->lll.tx.bn_curr = 1U; - cis->lll.rx.bn_curr = 1U; (void)memset(&cis->hdr, 0U, sizeof(cis->hdr)); @@ -875,6 +866,7 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ cis->central.instant = instant; + cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; cis->lll.nesn = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index 5bbac2528d0..d45d89aa009 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -259,15 +259,11 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->lll.rx.bn = req->c_bn; cis->lll.rx.ft = req->c_ft; cis->lll.rx.max_pdu = sys_le16_to_cpu(req->c_max_pdu); - cis->lll.rx.payload_count = 0; - cis->lll.rx.bn_curr = 1U; cis->lll.tx.phy = req->p_phy; cis->lll.tx.bn = req->p_bn; cis->lll.tx.ft = req->p_ft; cis->lll.tx.max_pdu = sys_le16_to_cpu(req->p_max_pdu); - cis->lll.tx.payload_count = 0; - cis->lll.tx.bn_curr = 1U; if (!cis->lll.link_tx_free) { cis->lll.link_tx_free = &cis->lll.link_tx; From 1291e4b6868d81518167a99dd48108ed48e1abd4 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Sep 2023 15:33:26 +0530 Subject: [PATCH 0461/4498] Bluetooth: Controller: Fix initialization of lazy_active Fix initialization of CIS lazy_active event count used when first CIS event is active. Now initialization for first and any subsequent CISes made active. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 8b79100d942..cc76c5219cb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -851,6 +851,10 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, */ if (cig->state == CIG_STATE_ACTIVE) { #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + /* Initialize CIS event lazy at CIS create */ + cis->lll.lazy_active = 0U; + + /* Deferred fill CIS event lazy value at CIS create */ cis_lazy_fill(cis); #else /* CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Set CIS active in already active CIG */ @@ -996,6 +1000,9 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, } ticks_slot = cig->ull.ticks_slot + ticks_slot_overhead; + + /* Initialize CIS event lazy at CIS create */ + cis->lll.lazy_active = 0U; #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Start CIS peripheral CIG ticker */ @@ -1014,11 +1021,6 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, /* Set CIG and the first CIS state as active */ cig->state = CIG_STATE_ACTIVE; cis->lll.active = 1U; - -#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) - /* CIS event lazy at CIS create */ - cis->lll.lazy_active = 0U; -#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ } #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) From d42d14e392e70a846abe5baaceb849ef21a50584 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Sep 2023 15:35:53 +0530 Subject: [PATCH 0462/4498] Bluetooth: Controller: Fix missing lazy calculation for Central ISO Fix missing lazy calculation when using ticker interface required for Central CIS create. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/Kconfig.ll_sw_split | 2 +- subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 84db5fddb10..910c3819f0c 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -53,7 +53,7 @@ config BT_LLL_VENDOR_NORDIC (BT_OBSERVER && BT_CTLR_ADV_EXT) select BT_TICKER_REMAINDER if BT_CTLR_CENTRAL_ISO select BT_TICKER_REMAINDER_GET if BT_BROADCASTER && BT_CTLR_ADV_EXT - select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC + select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CENTRAL_ISO default y help diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index cc76c5219cb..2ee5905b23b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -1042,8 +1042,8 @@ static void mfy_cis_lazy_fill(void *param) uint32_t ticks_to_expire; uint32_t ticks_current; uint32_t remainder; + uint16_t lazy = 0U; uint8_t ticker_id; - uint16_t lazy; uint8_t retry; uint8_t id; From ef041c6b985f0d1b1fe4bcd9477695c4f69b4e27 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 15 Sep 2023 10:45:47 +0200 Subject: [PATCH 0463/4498] modules: acpica: Fix header inclusion issue After 79d0bf39b8402f2b59fbcad2860e2a25c270545e was merged, the inclusion of with CONFIG_ACPI=n caused a build failure because could no longer be included due to the inlcude path not being injected anymore. Fix this by guarding the header inclusion when CONFIG_ACPI is not set. Fixes #62679. Signed-off-by: Carles Cufi --- arch/x86/core/intel64/cpu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index db8b69b0d1e..6afcec2a017 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -11,7 +11,9 @@ #include #include #include +#ifdef CONFIG_ACPI #include +#endif BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 4, "Only supports max 4 CPUs"); @@ -142,14 +144,14 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, uint8_t vector = ((unsigned long) x86_ap_start) >> 12; uint8_t apic_id; - if (IS_ENABLED(CONFIG_ACPI)) { - struct acpi_madt_local_apic *lapic = acpi_local_apic_get(cpu_num); +#ifdef CONFIG_ACPI + struct acpi_madt_local_apic *lapic = acpi_local_apic_get(cpu_num); - if (lapic != NULL) { - /* We update the apic_id, __start will need it. */ - x86_cpu_loapics[cpu_num] = lapic->Id; - } + if (lapic != NULL) { + /* We update the apic_id, __start will need it. */ + x86_cpu_loapics[cpu_num] = lapic->Id; } +#endif apic_id = x86_cpu_loapics[cpu_num]; From 62fd5ab3e1fcc62553f3a61ffc220984fc657f73 Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Wed, 5 Apr 2023 14:02:25 +0300 Subject: [PATCH 0464/4498] drivers: xen: gnttab: do Xen node mapping inside driver Move memory mapping of Xen node to Grant Table driver system init function. After moving mapping we don't need anymore records of xen-xen node into 'mmu_regions' array, so they were deleted from all SoCs: Rcar Gen3/Gen4 and XenVM. We need at least 16M of virtual address space to map memory of Xen node, so the virtual memory sized has been increased to 32 MB, it should be enough for basic use-cases and mapping of 16M mem region of Xen node. Unfortunately, after moving we also need to increase number of XLAT tables. The previous code was more efficient if we talking about usage of XLAT tables, because it mapped grant tables using a higher- order table that allows mapping blocks of 2MB. And after the changes is maps every 4KB page, so we need more XLAT tables. Increase number of grant frames, it is needed to sync stage 1 and stage 2 memory mappings, previously we map only one page on stage 2 and further usage of unmap regions can cause MMU translation errors. Perform mapping stage 1 before mapping for stage 2 (add to physmap), because right after stage 1 we can try to access memory and if it is unmap in stage 2, error will be received during translation. Note: Xen Grant Table driver doesn't use Zephyr Device Model. Authored-by: Mykola Kvach Co-authored-by: Oleksii Moisieiev Signed-off-by: Mykola Kvach --- boards/arm64/xenvm/xenvm_defconfig | 2 +- boards/arm64/xenvm/xenvm_gicv3_defconfig | 2 +- drivers/xen/gnttab.c | 17 ++++++++++++----- soc/arm64/xenvm/Kconfig.defconfig | 5 +++++ soc/arm64/xenvm/mmu_regions.c | 5 ----- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/boards/arm64/xenvm/xenvm_defconfig b/boards/arm64/xenvm/xenvm_defconfig index 8905b74a0c9..ff8597199e7 100644 --- a/boards/arm64/xenvm/xenvm_defconfig +++ b/boards/arm64/xenvm/xenvm_defconfig @@ -4,7 +4,7 @@ CONFIG_BOARD_XENVM=y # Enable UART driver CONFIG_SERIAL=y -CONFIG_MAX_XLAT_TABLES=10 +CONFIG_MAX_XLAT_TABLES=24 CONFIG_HEAP_MEM_POOL_SIZE=16384 # Enable console diff --git a/boards/arm64/xenvm/xenvm_gicv3_defconfig b/boards/arm64/xenvm/xenvm_gicv3_defconfig index 9bff11a2edb..59a0c306cb7 100644 --- a/boards/arm64/xenvm/xenvm_gicv3_defconfig +++ b/boards/arm64/xenvm/xenvm_gicv3_defconfig @@ -4,7 +4,7 @@ CONFIG_BOARD_XENVM=y # Enable UART driver CONFIG_SERIAL=y -CONFIG_MAX_XLAT_TABLES=10 +CONFIG_MAX_XLAT_TABLES=24 # Enable console CONFIG_CONSOLE=y diff --git a/drivers/xen/gnttab.c b/drivers/xen/gnttab.c index d871eb62d27..8ceb97e2db1 100644 --- a/drivers/xen/gnttab.c +++ b/drivers/xen/gnttab.c @@ -28,17 +28,24 @@ #include #include #include +#include LOG_MODULE_REGISTER(xen_gnttab); /* Timeout for grant table ops retrying */ #define GOP_RETRY_DELAY 200 +#define GNTTAB_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, xen_xen), 0) +BUILD_ASSERT(!(GNTTAB_SIZE % XEN_PAGE_SIZE), "Size of gnttab have to be aligned on XEN_PAGE_SIZE"); + /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ -#define NR_GRANT_FRAMES 1 +#define NR_GRANT_FRAMES (GNTTAB_SIZE / XEN_PAGE_SIZE) #define NR_GRANT_ENTRIES \ (NR_GRANT_FRAMES * XEN_PAGE_SIZE / sizeof(grant_entry_v1_t)) +BUILD_ASSERT(GNTTAB_SIZE <= CONFIG_KERNEL_VM_SIZE); +DEVICE_MMIO_TOPLEVEL_STATIC(grant_tables, DT_INST(0, xen_xen)); + static struct gnttab { struct k_sem sem; grant_entry_v1_t *table; @@ -307,15 +314,12 @@ static int gnttab_init(void) put_free_entry(gref); } - gnttab.table = (grant_entry_v1_t *) - DT_REG_ADDR_BY_IDX(DT_INST(0, xen_xen), 0); - for (i = 0; i < NR_GRANT_FRAMES; i++) { xatp.domid = DOMID_SELF; xatp.size = 0; xatp.space = XENMAPSPACE_grant_table; xatp.idx = i; - xatp.gpfn = xen_virt_to_gfn(gnttab.table) + i; + xatp.gpfn = xen_virt_to_gfn(Z_TOPLEVEL_ROM_NAME(grant_tables).phys_addr) + i; rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); __ASSERT(!rc, "add_to_physmap failed; status = %d\n", rc); } @@ -327,6 +331,9 @@ static int gnttab_init(void) __ASSERT((!rc) && (!setup.status), "Table setup failed; status = %s\n", gnttabop_error(setup.status)); + DEVICE_MMIO_TOPLEVEL_MAP(grant_tables, K_MEM_CACHE_WB | K_MEM_PERM_RW); + gnttab.table = (grant_entry_v1_t *)DEVICE_MMIO_TOPLEVEL_GET(grant_tables); + LOG_DBG("%s: grant table mapped\n", __func__); return 0; diff --git a/soc/arm64/xenvm/Kconfig.defconfig b/soc/arm64/xenvm/Kconfig.defconfig index 9d8d6847e20..4a88b6bed93 100644 --- a/soc/arm64/xenvm/Kconfig.defconfig +++ b/soc/arm64/xenvm/Kconfig.defconfig @@ -14,4 +14,9 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC int default 8320000 +# We need at least 16M of virtual address space to map memory of Xen node +# 32M should be enough for basic use-cases +config KERNEL_VM_SIZE + default 0x2000000 + endif diff --git a/soc/arm64/xenvm/mmu_regions.c b/soc/arm64/xenvm/mmu_regions.c index 43e3ada82e9..070bb01474f 100644 --- a/soc/arm64/xenvm/mmu_regions.c +++ b/soc/arm64/xenvm/mmu_regions.c @@ -18,11 +18,6 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), - - MMU_REGION_FLAT_ENTRY("HYPERVISOR", - DT_REG_ADDR_BY_IDX(DT_INST(0, xen_xen), 0), - DT_REG_SIZE_BY_IDX(DT_INST(0, xen_xen), 0), - MT_NORMAL | MT_P_RW_U_NA | MT_NS), }; const struct arm_mmu_config mmu_config = { From 40fe36669c15079963e908cb7661ccb6e1230bfe Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Fri, 16 Jun 2023 12:14:27 +0300 Subject: [PATCH 0465/4498] tests: kernel: exclude xenvm from device tests Zephyr device and device.pm tests uses device tree fragments applied to main board device trees. For xenvm they have conflicting address/size cells definition with board DT. It leads to CI and test issues during build (xenvm has 0x2 cells, tests have 0x1). Signed-off-by: Dmytro Firsov --- tests/kernel/device/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/kernel/device/testcase.yaml b/tests/kernel/device/testcase.yaml index 8634e2746ed..40aee98fa57 100644 --- a/tests/kernel/device/testcase.yaml +++ b/tests/kernel/device/testcase.yaml @@ -9,6 +9,7 @@ tests: tags: - kernel - device + platform_exclude: xenvm kernel.device.minimallibc: filter: CONFIG_MINIMAL_LIBC_SUPPORTED tags: @@ -17,10 +18,11 @@ tests: - libc extra_configs: - CONFIG_MINIMAL_LIBC=y + platform_exclude: xenvm kernel.device.pm: tags: - kernel - device - platform_exclude: mec15xxevb_assy6853 + platform_exclude: mec15xxevb_assy6853 xenvm extra_configs: - CONFIG_PM_DEVICE=y From 66dfe7b99ab35136cc762b925a78aa109a3bd60d Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Wed, 15 Mar 2023 13:33:30 +0200 Subject: [PATCH 0466/4498] dts: bindings: xen: add xen,xen.yaml file Add yaml file for 'xen,xen', because without it an appropriate 'CONFIG_DT_HAS_XEN_XEN_ENABLED' isn't generated. It will be used for checking Xen support on current setup, instead of checking if it is BOARD/SOC "xenvm" (which is not correct for Domain-0 configurations). Remove xen,xen-4.15.yaml at all, because it isn't necessary to have yaml for some specific Xen version. Signed-off-by: Mykola Kvach Signed-off-by: Dmytro Firsov --- boards/arm64/xenvm/xenvm.dts | 6 +++--- dts/bindings/xen/{xen,xen-4.15.yaml => xen,xen.yaml} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename dts/bindings/xen/{xen,xen-4.15.yaml => xen,xen.yaml} (83%) diff --git a/boards/arm64/xenvm/xenvm.dts b/boards/arm64/xenvm/xenvm.dts index fb6daa3656a..bbba268d9a3 100644 --- a/boards/arm64/xenvm/xenvm.dts +++ b/boards/arm64/xenvm/xenvm.dts @@ -18,8 +18,8 @@ #include / { - model = "XENVM-4.15"; - compatible = "xen,xenvm-4.15", "xen,xenvm"; + model = "XENVM"; + compatible = "xen,xenvm"; interrupt-parent = <&gic>; #address-cells = <0x02>; #size-cells = <0x02>; @@ -68,7 +68,7 @@ }; hypervisor: hypervisor@38000000 { - compatible = "xen,xen-4.15", "xen,xen"; + compatible = "xen,xen"; reg = <0x00 0x38000000 0x00 0x1000000>; interrupts = ; interrupt-parent = <&gic>; diff --git a/dts/bindings/xen/xen,xen-4.15.yaml b/dts/bindings/xen/xen,xen.yaml similarity index 83% rename from dts/bindings/xen/xen,xen-4.15.yaml rename to dts/bindings/xen/xen,xen.yaml index 7456450d3ad..1627f6d9340 100644 --- a/dts/bindings/xen/xen,xen-4.15.yaml +++ b/dts/bindings/xen/xen,xen.yaml @@ -1,6 +1,6 @@ description: Xen Platform Control Registers -compatible: "xen,xen-4.15" +compatible: "xen,xen" include: base.yaml From c9d2fb7d406b0558ff0ae69a88f29c0e37ae387e Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Tue, 13 Jun 2023 13:19:18 +0300 Subject: [PATCH 0467/4498] xen: refactor Xen hypervisor Kconfig options Xen-related Kconfig options were highly dependand on BOARD/SOC xenvm. It is not correct because Xen support may be used on any board and SoC. So, Kconfig structure was refactored, now CONFIG_XEN is located in arch/ directory (same as in Linux kernel) and can be selected for any Cortex-A arm64 setup (no other platforms are currently supported). Also remove confusion in Domain 0 naming: Domain-0, initial domain, Dom0, privileged domain etc. Now all options related to Xen Domain 0 will be controlled by CONFIG_XEN_DOM0. Signed-off-by: Dmytro Firsov --- arch/arm64/core/CMakeLists.txt | 2 +- arch/arm64/core/Kconfig | 2 ++ arch/arm64/core/xen/Kconfig | 20 ++++++++++++++++++++ drivers/CMakeLists.txt | 2 +- drivers/serial/Kconfig.xen | 8 +++----- drivers/xen/Kconfig | 6 +++--- soc/arm64/xenvm/Kconfig.soc | 6 ------ 7 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 arch/arm64/core/xen/Kconfig diff --git a/arch/arm64/core/CMakeLists.txt b/arch/arm64/core/CMakeLists.txt index 56d6413034e..1804556c1a7 100644 --- a/arch/arm64/core/CMakeLists.txt +++ b/arch/arm64/core/CMakeLists.txt @@ -54,4 +54,4 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU") zephyr_cc_option(-moverride=tune=no_ldp_stp_qregs) endif() -add_subdirectory_ifdef(CONFIG_SOC_XENVM xen) +add_subdirectory_ifdef(CONFIG_XEN xen) diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index cd34eb02568..e0963211238 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -197,6 +197,8 @@ config ARMV8_A so that it can support some features included in the AArch64 state. It supports the T32 and A32 instruction sets. +rsource "xen/Kconfig" + endif # CPU_CORTEX_A if CPU_AARCH64_CORTEX_R diff --git a/arch/arm64/core/xen/Kconfig b/arch/arm64/core/xen/Kconfig new file mode 100644 index 00000000000..ea9489d4422 --- /dev/null +++ b/arch/arm64/core/xen/Kconfig @@ -0,0 +1,20 @@ +# Xen hypervisor configuration options + +# Copyright (c) 2023 EPAM Systems +# SPDX-License-Identifier: Apache-2.0 + +config XEN + bool + default y + depends on ARMV8_A + depends on DT_HAS_XEN_XEN_ENABLED + help + Enables support of Xen hypervisor on arm64 platform. Get enabled + when board device tree contains "hypervisor" node with "xen,xen" + compatible enabled. + +config XEN_DOM0 + bool "Zephyr as Xen Domain 0" + depends on XEN + help + Built binary will be used as Xen privileged domain (Domain 0). diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index b255b2b638e..891041f2ded 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -15,7 +15,7 @@ add_subdirectory(usb_c) add_subdirectory_ifdef(CONFIG_ADC adc) add_subdirectory_ifdef(CONFIG_AUDIO audio) add_subdirectory_ifdef(CONFIG_BBRAM bbram) -add_subdirectory_ifdef(CONFIG_BOARD_XENVM xen) +add_subdirectory_ifdef(CONFIG_XEN xen) add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth) add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache) add_subdirectory_ifdef(CONFIG_CAN can) diff --git a/drivers/serial/Kconfig.xen b/drivers/serial/Kconfig.xen index 010541f77d1..89fe3f54194 100644 --- a/drivers/serial/Kconfig.xen +++ b/drivers/serial/Kconfig.xen @@ -1,6 +1,6 @@ # Xen hypervisor console via UART setup # -# Copyright (c) 2021 EPAM Systems +# Copyright (c) 2021-2023 EPAM Systems # SPDX-License-Identifier: Apache-2.0 # @@ -10,7 +10,7 @@ config UART_XEN_HVC depends on DT_HAS_XEN_HVC_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - depends on !XEN_INITIAL_DOMAIN + depends on XEN && !XEN_DOM0 help Enable Xen ring buffer based hypervisor console driver. Used for Zephyr as unprivileged domain. @@ -18,8 +18,7 @@ config UART_XEN_HVC config UART_XEN_HVC_CONSOLEIO bool "Xen hypervisor Dom0 console UART driver" select SERIAL_HAS_DRIVER - depends on BOARD_XENVM - depends on XEN_INITIAL_DOMAIN + depends on XEN_DOM0 default y help Enable Xen hypervisor console driver. Used for Zephyr as @@ -35,7 +34,6 @@ config XEN_HVC_INIT_PRIORITY config XEN_EARLY_CONSOLEIO bool "Early printk/stdout through console_io Xen interface" - depends on BOARD_XENVM depends on UART_XEN_HVC help Enable setting of console_io symbol hook for stdout and printk. diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 547b3a7f9e7..361c71a3538 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2022 EPAM Systems +# Copyright (c) 2022-2023 EPAM Systems -if SOC_XENVM +if XEN menu "Xen drivers" @@ -22,4 +22,4 @@ config XEN_GRANT_TABLE_INIT_PRIORITY endmenu -endif # SOC_XENVM +endif # XEN diff --git a/soc/arm64/xenvm/Kconfig.soc b/soc/arm64/xenvm/Kconfig.soc index 89f90ed5c7c..00f1bf0ca31 100644 --- a/soc/arm64/xenvm/Kconfig.soc +++ b/soc/arm64/xenvm/Kconfig.soc @@ -6,9 +6,3 @@ config SOC_XENVM select ARM64 select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS select CPU_CORTEX_A72 - -config XEN_INITIAL_DOMAIN - bool "Zephyr as Xen Domain 0" - depends on SOC_XENVM - help - Built binary will be used as Xen privileged domain. From 5852dd2b1a1bcb58e9611e9b74a69db8dcad27d0 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Tue, 14 Feb 2023 14:40:38 +0200 Subject: [PATCH 0468/4498] xen: events: add event channel allocation for domain-0 This commit adds interface for evtchn allocation that can be used by privilaged domain. Domain 0 can specify both dom and remote_dom parameters for hypercall, where in others domains dom should be always DOMID_SELF. It is needed for creating pre-defined channels during domain setup in Zephyr Dom0. Signed-off-by: Dmytro Firsov --- drivers/xen/events.c | 18 ++++++++++++++++++ include/zephyr/xen/events.h | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index e077b0f6cfa..a16cce8b5c5 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -47,6 +47,24 @@ int alloc_unbound_event_channel(domid_t remote_dom) return rc; } +#ifdef CONFIG_XEN_DOM0 +int alloc_unbound_event_channel_dom0(domid_t dom, domid_t remote_dom) +{ + int rc; + struct evtchn_alloc_unbound alloc = { + .dom = dom, + .remote_dom = remote_dom, + }; + + rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &alloc); + if (rc == 0) { + rc = alloc.port; + } + + return rc; +} +#endif /* CONFIG_XEN_DOM0 */ + int bind_interdomain_event_channel(domid_t remote_dom, evtchn_port_t remote_port, evtchn_cb_t cb, void *data) { diff --git a/include/zephyr/xen/events.h b/include/zephyr/xen/events.h index d2a936a59ed..cbad8162cbb 100644 --- a/include/zephyr/xen/events.h +++ b/include/zephyr/xen/events.h @@ -36,6 +36,17 @@ void notify_evtchn(evtchn_port_t port); */ int alloc_unbound_event_channel(domid_t remote_dom); +#ifdef CONFIG_XEN_DOM0 +/* + * Allocate event-channel between remote domains. Can be used only from Dom0. + * + * @param dom - first remote domain domid (may be DOMID_SELF) + * @param remote_dom - second remote domain domid + * @return - local event channel port on success, negative on error + */ +int alloc_unbound_event_channel_dom0(domid_t dom, domid_t remote_dom); +#endif /* CONFIG_XEN_DOM0 */ + /* * Allocate local event channel, binded to remote port and attach specified callback * to it From 0c69913eae5e0308ba2e90f30f14c0e9bd1802c1 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 2 Feb 2023 14:25:45 +0200 Subject: [PATCH 0469/4498] xen: dom0: update Xen public headers for running Zephyr as Dom0 Xen public headers are added to Zephyr kernel partially, so we need to update them for new features implementation. Further implementation of Xen domains configuration and memory management requires dedicated Xen public headers inside Zephyr kernel. It will be used for add Zephyr OS Xen Domain-0 funtionalities. Update existent and add new required public headers from Xen 4.17.0 release. Signed-off-by: Dmytro Firsov --- include/zephyr/xen/public/arch-arm.h | 254 ++++++++++++- include/zephyr/xen/public/domctl.h | 517 +++++++++++++++++++++++++++ include/zephyr/xen/public/memory.h | 34 ++ include/zephyr/xen/public/xen.h | 21 ++ 4 files changed, 823 insertions(+), 3 deletions(-) create mode 100644 include/zephyr/xen/public/domctl.h diff --git a/include/zephyr/xen/public/arch-arm.h b/include/zephyr/xen/public/arch-arm.h index f2812dc3b9b..c3a8afe9a92 100644 --- a/include/zephyr/xen/public/arch-arm.h +++ b/include/zephyr/xen/public/arch-arm.h @@ -205,15 +205,138 @@ typedef uint64_t xen_pfn_t; #define PRI_xen_pfn PRIx64 #define PRIu_xen_pfn PRIu64 -typedef uint64_t xen_ulong_t; -#define PRI_xen_ulong PRIx64 - /* * Maximum number of virtual CPUs in legacy multi-processor guests. * Only one. All other VCPUS must use VCPUOP_register_vcpu_info. */ #define XEN_LEGACY_MAX_VCPUS 1 +typedef uint64_t xen_ulong_t; +#define PRI_xen_ulong PRIx64 + +#ifdef CONFIG_XEN_DOM0 +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */ +# define __DECL_REG(n64, n32) union { \ + uint64_t n64; \ + uint32_t n32; \ +} +#else +/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */ +#define __DECL_REG(n64, n32) uint64_t n64 +#endif + +struct vcpu_guest_core_regs { + /* Aarch64 Aarch32 */ + __DECL_REG(x0, r0_usr); + __DECL_REG(x1, r1_usr); + __DECL_REG(x2, r2_usr); + __DECL_REG(x3, r3_usr); + __DECL_REG(x4, r4_usr); + __DECL_REG(x5, r5_usr); + __DECL_REG(x6, r6_usr); + __DECL_REG(x7, r7_usr); + __DECL_REG(x8, r8_usr); + __DECL_REG(x9, r9_usr); + __DECL_REG(x10, r10_usr); + __DECL_REG(x11, r11_usr); + __DECL_REG(x12, r12_usr); + + __DECL_REG(x13, sp_usr); + __DECL_REG(x14, lr_usr); + + __DECL_REG(x15, __unused_sp_hyp); + + __DECL_REG(x16, lr_irq); + __DECL_REG(x17, sp_irq); + + __DECL_REG(x18, lr_svc); + __DECL_REG(x19, sp_svc); + + __DECL_REG(x20, lr_abt); + __DECL_REG(x21, sp_abt); + + __DECL_REG(x22, lr_und); + __DECL_REG(x23, sp_und); + + __DECL_REG(x24, r8_fiq); + __DECL_REG(x25, r9_fiq); + __DECL_REG(x26, r10_fiq); + __DECL_REG(x27, r11_fiq); + __DECL_REG(x28, r12_fiq); + + __DECL_REG(x29, sp_fiq); + __DECL_REG(x30, lr_fiq); + + /* Return address and mode */ + __DECL_REG(pc64, pc32); /* ELR_EL2 */ + uint32_t cpsr; /* SPSR_EL2 */ + + union { + uint32_t spsr_el1; /* AArch64 */ + uint32_t spsr_svc; /* AArch32 */ + }; + + /* AArch32 guests only */ + uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt; + + /* AArch64 guests only */ + uint64_t sp_el0; + uint64_t sp_el1, elr_el1; +}; +typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t); + +#undef __DECL_REG + +struct vcpu_guest_context { +#define _VGCF_online 0 +#define VGCF_online (1 << _VGCF_online) + uint32_t flags; /* VGCF_* */ + + struct vcpu_guest_core_regs user_regs; /* Core CPU registers */ + + uint64_t sctlr; + uint64_t ttbcr, ttbr0, ttbr1; +}; +typedef struct vcpu_guest_context vcpu_guest_context_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); + +/* + * struct xen_arch_domainconfig's ABI is covered by + * XEN_DOMCTL_INTERFACE_VERSION. + */ +#define XEN_DOMCTL_CONFIG_GIC_NATIVE 0 +#define XEN_DOMCTL_CONFIG_GIC_V2 1 +#define XEN_DOMCTL_CONFIG_GIC_V3 2 + +#define XEN_DOMCTL_CONFIG_TEE_NONE 0 +#define XEN_DOMCTL_CONFIG_TEE_OPTEE 1 + +struct xen_arch_domainconfig { + /* IN/OUT */ + uint8_t gic_version; + /* IN */ + uint16_t tee_type; + /* IN */ + uint32_t nr_spis; + /* + * OUT + * Based on the property clock-frequency in the DT timer node. + * The property may be present when the bootloader/firmware doesn't + * set correctly CNTFRQ which hold the timer frequency. + * + * As it's not possible to trap this register, we have to replicate + * the value in the guest DT. + * + * = 0 => property not present + * > 0 => Value of the property + * + */ + uint32_t clock_frequency; +}; +#endif /* CONFIG_XEN_DOM0 */ + struct arch_vcpu_info { }; typedef struct arch_vcpu_info arch_vcpu_info_t; @@ -225,4 +348,129 @@ typedef uint64_t xen_callback_t; #endif /* __ASSEMBLY__ */ +#ifdef CONFIG_XEN_DOM0 + +/* PSR bits (CPSR, SPSR) */ +#define PSR_THUMB (1 << 5) /* Thumb Mode enable */ +#define PSR_FIQ_MASK (1 << 6) /* Fast Interrupt mask */ +#define PSR_IRQ_MASK (1 << 7) /* Interrupt mask */ +#define PSR_ABT_MASK (1 << 8) /* Asynchronous Abort mask */ +#define PSR_BIG_ENDIAN (1 << 9) /* arm32: Big Endian Mode */ +#define PSR_DBG_MASK (1 << 9) /* arm64: Debug Exception mask */ +#define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */ +#define PSR_JAZELLE (1<<24) /* Jazelle Mode */ + +/* 32 bit modes */ +#define PSR_MODE_USR 0x10 +#define PSR_MODE_FIQ 0x11 +#define PSR_MODE_IRQ 0x12 +#define PSR_MODE_SVC 0x13 +#define PSR_MODE_MON 0x16 +#define PSR_MODE_ABT 0x17 +#define PSR_MODE_HYP 0x1a +#define PSR_MODE_UND 0x1b +#define PSR_MODE_SYS 0x1f + +/* 64 bit modes */ +#define PSR_MODE_BIT 0x10 /* Set iff AArch32 */ +#define PSR_MODE_EL3h 0x0d +#define PSR_MODE_EL3t 0x0c +#define PSR_MODE_EL2h 0x09 +#define PSR_MODE_EL2t 0x08 +#define PSR_MODE_EL1h 0x05 +#define PSR_MODE_EL1t 0x04 +#define PSR_MODE_EL0t 0x00 + +#define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC) +#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h) + +#define SCTLR_GUEST_INIT xen_mk_ullong(0x00c50078) + +/* + * Virtual machine platform (memory layout, interrupts) + * + * These are defined for consistency between the tools and the + * hypervisor. Guests must not rely on these hardcoded values but + * should instead use the FDT. + */ + +/* Physical Address Space */ + +/* + * vGIC mappings: Only one set of mapping is used by the guest. + * Therefore they can overlap. + */ + +/* vGIC v2 mappings */ +#define GUEST_GICD_BASE xen_mk_ullong(0x03001000) +#define GUEST_GICD_SIZE xen_mk_ullong(0x00001000) +#define GUEST_GICC_BASE xen_mk_ullong(0x03002000) +#define GUEST_GICC_SIZE xen_mk_ullong(0x00002000) + +/* vGIC v3 mappings */ +#define GUEST_GICV3_GICD_BASE xen_mk_ullong(0x03001000) +#define GUEST_GICV3_GICD_SIZE xen_mk_ullong(0x00010000) + +#define GUEST_GICV3_RDIST_REGIONS 1 + +#define GUEST_GICV3_GICR0_BASE xen_mk_ullong(0x03020000) /* vCPU0..127 */ +#define GUEST_GICV3_GICR0_SIZE xen_mk_ullong(0x01000000) + +/* ACPI tables physical address */ +#define GUEST_ACPI_BASE xen_mk_ullong(0x20000000) +#define GUEST_ACPI_SIZE xen_mk_ullong(0x02000000) + +/* PL011 mappings */ +#define GUEST_PL011_BASE xen_mk_ullong(0x22000000) +#define GUEST_PL011_SIZE xen_mk_ullong(0x00001000) + +/* + * 16MB == 4096 pages reserved for guest to use as a region to map its + * grant table in. + */ +#define GUEST_GNTTAB_BASE xen_mk_ullong(0x38000000) +#define GUEST_GNTTAB_SIZE xen_mk_ullong(0x01000000) + +#define GUEST_MAGIC_BASE xen_mk_ullong(0x39000000) +#define GUEST_MAGIC_SIZE xen_mk_ullong(0x01000000) + +#define GUEST_RAM_BANKS 2 + +#define GUEST_RAM0_BASE xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */ +#define GUEST_RAM0_SIZE xen_mk_ullong(0xc0000000) + +#define GUEST_RAM1_BASE xen_mk_ullong(0x0200000000) /* 1016GB of RAM @ 8GB */ +#define GUEST_RAM1_SIZE xen_mk_ullong(0xfe00000000) + +#define GUEST_RAM_BASE GUEST_RAM0_BASE /* Lowest RAM address */ +/* Largest amount of actual RAM, not including holes */ +#define GUEST_RAM_MAX (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE) +/* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */ +#define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE } +#define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE } + +/* Current supported guest VCPUs */ +#define GUEST_MAX_VCPUS 128 + +/* Interrupts */ +#define GUEST_TIMER_VIRT_PPI 27 +#define GUEST_TIMER_PHYS_S_PPI 29 +#define GUEST_TIMER_PHYS_NS_PPI 30 +#define GUEST_EVTCHN_PPI 31 + +#define GUEST_VPL011_SPI 32 + +/* PSCI functions */ +#define PSCI_cpu_suspend 0 +#define PSCI_cpu_off 1 +#define PSCI_cpu_on 2 +#define PSCI_migrate 3 + +#endif /* CONFIG_XEN_DOM0 */ + +#ifndef __ASSEMBLY__ +/* Stub definition of PMU structure */ +typedef struct xen_pmu_arch { uint8_t dummy; } xen_pmu_arch_t; +#endif /* __ASSEMBLY__ */ + #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */ diff --git a/include/zephyr/xen/public/domctl.h b/include/zephyr/xen/public/domctl.h new file mode 100644 index 00000000000..b33cf7966fa --- /dev/null +++ b/include/zephyr/xen/public/domctl.h @@ -0,0 +1,517 @@ +/* SPDX-License-Identifier: MIT */ +/****************************************************************************** + * domctl.h + * + * Domain management operations. For use by node control stack. + * + * Copyright (c) 2002-2003, B Dragovic + * Copyright (c) 2002-2006, K Fraser + */ + +#ifndef __XEN_PUBLIC_DOMCTL_H__ +#define __XEN_PUBLIC_DOMCTL_H__ + +#ifndef CONFIG_XEN_DOM0 +#error "domctl operations are intended for use by node control tools only" +#endif + +#include "xen.h" +#include "event_channel.h" +#include "grant_table.h" +#include "memory.h" + +#define XEN_DOMCTL_INTERFACE_VERSION 0x00000015 + +/* + * NB. xen_domctl.domain is an IN/OUT parameter for this operation. + * If it is specified as an invalid value (0 or >= DOMID_FIRST_RESERVED), + * an id is auto-allocated and returned. + */ +/* XEN_DOMCTL_createdomain */ +struct xen_domctl_createdomain { + /* IN parameters */ + uint32_t ssidref; + xen_domain_handle_t handle; +/* Is this an HVM guest (as opposed to a PV guest)? */ +#define _XEN_DOMCTL_CDF_hvm 0 +#define XEN_DOMCTL_CDF_hvm (1U << _XEN_DOMCTL_CDF_hvm) +/* Use hardware-assisted paging if available? */ +#define _XEN_DOMCTL_CDF_hap 1 +#define XEN_DOMCTL_CDF_hap (1U << _XEN_DOMCTL_CDF_hap) +/* Should domain memory integrity be verifed by tboot during Sx? */ +#define _XEN_DOMCTL_CDF_s3_integrity 2 +#define XEN_DOMCTL_CDF_s3_integrity (1U << _XEN_DOMCTL_CDF_s3_integrity) +/* Disable out-of-sync shadow page tables? */ +#define _XEN_DOMCTL_CDF_oos_off 3 +#define XEN_DOMCTL_CDF_oos_off (1U << _XEN_DOMCTL_CDF_oos_off) +/* Is this a xenstore domain? */ +#define _XEN_DOMCTL_CDF_xs_domain 4 +#define XEN_DOMCTL_CDF_xs_domain (1U << _XEN_DOMCTL_CDF_xs_domain) +/* Should this domain be permitted to use the IOMMU? */ +#define _XEN_DOMCTL_CDF_iommu 5 +#define XEN_DOMCTL_CDF_iommu (1U << _XEN_DOMCTL_CDF_iommu) +#define _XEN_DOMCTL_CDF_nested_virt 6 +#define XEN_DOMCTL_CDF_nested_virt (1U << _XEN_DOMCTL_CDF_nested_virt) +/* Should we expose the vPMU to the guest? */ +#define XEN_DOMCTL_CDF_vpmu (1U << 7) + +/* Max XEN_DOMCTL_CDF_* constant. Used for ABI checking. */ +#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_vpmu + + uint32_t flags; + +#define _XEN_DOMCTL_IOMMU_no_sharept 0 +#define XEN_DOMCTL_IOMMU_no_sharep (1U << _XEN_DOMCTL_IOMMU_no_sharept) + +/* Max XEN_DOMCTL_IOMMU_* constant. Used for ABI checking. */ +#define XEN_DOMCTL_IOMMU_MAX XEN_DOMCTL_IOMMU_no_sharept + + uint32_t iommu_opts; + + /* + * Various domain limits, which impact the quantity of resources + * (global mapping space, xenheap, etc) a guest may consume. For + * max_grant_frames and max_maptrack_frames, < 0 means "use the + * default maximum value in the hypervisor". + */ + uint32_t max_vcpus; + uint32_t max_evtchn_port; + int32_t max_grant_frames; + int32_t max_maptrack_frames; + +/* Grant version, use low 4 bits. */ +#define XEN_DOMCTL_GRANT_version_mask 0xf +#define XEN_DOMCTL_GRANT_version(v) ((v) & XEN_DOMCTL_GRANT_version_mask) + + uint32_t grant_opts; + + /* Per-vCPU buffer size in bytes. 0 to disable. */ + uint32_t vmtrace_size; + + /* CPU pool to use; specify 0 or a specific existing pool */ + uint32_t cpupool_id; + + struct xen_arch_domainconfig arch; +}; + +/* XEN_DOMCTL_getdomaininfo */ +struct xen_domctl_getdomaininfo { + /* OUT variables. */ + domid_t domain; /* Also echoed in domctl.domain */ + uint16_t pad1; +/* Domain is scheduled to die. */ +#define _XEN_DOMINF_dying 0 +#define XEN_DOMINF_dying (1U << _XEN_DOMINF_dying) +/* Domain is an HVM guest (as opposed to a PV guest). */ +#define _XEN_DOMINF_hvm_guest 1 +#define XEN_DOMINF_hvm_guest (1U << _XEN_DOMINF_hvm_guest) +/* The guest OS has shut down. */ +#define _XEN_DOMINF_shutdown 2 +#define XEN_DOMINF_shutdown (1U << _XEN_DOMINF_shutdown) +/* Currently paused by control software. */ +#define _XEN_DOMINF_paused 3 +#define XEN_DOMINF_paused (1U << _XEN_DOMINF_paused) +/* Currently blocked pending an event. */ +#define _XEN_DOMINF_blocked 4 +#define XEN_DOMINF_blocked (1U << _XEN_DOMINF_blocked) +/* Domain is currently running. */ +#define _XEN_DOMINF_running 5 +#define XEN_DOMINF_running (1U << _XEN_DOMINF_running) +/* Being debugged. */ +#define _XEN_DOMINF_debugged 6 +#define XEN_DOMINF_debugged (1U << _XEN_DOMINF_debugged) +/* domain is a xenstore domain */ +#define _XEN_DOMINF_xs_domain 7 +#define XEN_DOMINF_xs_domain (1U << _XEN_DOMINF_xs_domain) +/* domain has hardware assisted paging */ +#define _XEN_DOMINF_hap 8 +#define XEN_DOMINF_hap (1U << _XEN_DOMINF_hap) +/* XEN_DOMINF_shutdown guest-supplied code. */ +#define XEN_DOMINF_shutdownmask 255 +#define XEN_DOMINF_shutdownshift 16 + uint32_t flags; /* XEN_DOMINF_* */ + uint64_aligned_t tot_pages; + uint64_aligned_t max_pages; + uint64_aligned_t outstanding_pages; + uint64_aligned_t shr_pages; + uint64_aligned_t paged_pages; + uint64_aligned_t shared_info_frame; /* GMFN of shared_info struct */ + uint64_aligned_t cpu_time; + uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */ +#define XEN_INVALID_MAX_VCPU_ID (~0U) /* Domain has no vcpus? */ + uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */ + uint32_t ssidref; + xen_domain_handle_t handle; + uint32_t cpupool; + uint8_t gpaddr_bits; /* Guest physical address space size. */ + uint8_t pad2[7]; + struct xen_arch_domainconfig arch_config; +}; +typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t); + +/* + * Control shadow pagetables operation + */ +/* XEN_DOMCTL_shadow_op */ + +/* Memory allocation accessors. */ +#define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION 30 +#define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION 31 + +struct xen_domctl_shadow_op_stats { + uint32_t fault_count; + uint32_t dirty_count; +}; + +struct xen_domctl_shadow_op { + /* IN variables. */ + uint32_t op; /* XEN_DOMCTL_SHADOW_OP_* */ + + /* OP_ENABLE: XEN_DOMCTL_SHADOW_ENABLE_* */ + /* OP_PEAK / OP_CLEAN: XEN_DOMCTL_SHADOW_LOGDIRTY_* */ + uint32_t mode; + + /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */ + uint32_t mb; /* Shadow memory allocation in MB */ + + /* OP_PEEK / OP_CLEAN */ + XEN_GUEST_HANDLE_64(uint8_t) dirty_bitmap; + uint64_aligned_t pages; /* Size of buffer. Updated with actual size. */ + struct xen_domctl_shadow_op_stats stats; +}; + +/* XEN_DOMCTL_max_mem */ +struct xen_domctl_max_mem { + /* IN variables. */ + uint64_aligned_t max_memkb; +}; + +/* XEN_DOMCTL_setvcpucontext */ +/* XEN_DOMCTL_getvcpucontext */ +struct xen_domctl_vcpucontext { + uint32_t vcpu; /* IN */ + + XEN_GUEST_HANDLE_64(vcpu_guest_context_t) ctxt; /* IN/OUT */ +}; + +/* + * XEN_DOMCTL_max_vcpus: + * + * The parameter passed to XEN_DOMCTL_max_vcpus must match the value passed to + * XEN_DOMCTL_createdomain. This hypercall is in the process of being removed + * (once the failure paths in domain_create() have been improved), but is + * still required in the short term to allocate the vcpus themselves. + */ +struct xen_domctl_max_vcpus { + uint32_t max; /* maximum number of vcpus */ +}; + +/* XEN_DOMCTL_scheduler_op */ +/* Scheduler types. */ +/* #define XEN_SCHEDULER_SEDF 4 (Removed) */ +#define XEN_SCHEDULER_CREDIT 5 +#define XEN_SCHEDULER_CREDIT2 6 +#define XEN_SCHEDULER_ARINC653 7 +#define XEN_SCHEDULER_RTDS 8 +#define XEN_SCHEDULER_NULL 9 + +struct xen_domctl_sched_credit { + uint16_t weight; + uint16_t cap; +}; + +struct xen_domctl_sched_credit2 { + uint16_t weight; + uint16_t cap; +}; + +struct xen_domctl_sched_rtds { + uint32_t period; + uint32_t budget; +/* Can this vCPU execute beyond its reserved amount of time? */ +#define _XEN_DOMCTL_SCHEDRT_extra 0 +#define XEN_DOMCTL_SCHEDRT_extra (1U<<_XEN_DOMCTL_SCHEDRT_extra) + uint32_t flags; +}; + +typedef struct xen_domctl_schedparam_vcpu { + union { + struct xen_domctl_sched_credit credit; + struct xen_domctl_sched_credit2 credit2; + struct xen_domctl_sched_rtds rtds; + } u; + uint32_t vcpuid; +} xen_domctl_schedparam_vcpu_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_schedparam_vcpu_t); + +/* + * Set or get info? + * For schedulers supporting per-vcpu settings (e.g., RTDS): + * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus; + * XEN_DOMCTL_SCHEDOP_getinfo gets default params; + * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo sets (gets) params of vcpus; + * + * For schedulers not supporting per-vcpu settings: + * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus; + * XEN_DOMCTL_SCHEDOP_getinfo gets domain-wise params; + * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo returns error; + */ +#define XEN_DOMCTL_SCHEDOP_putinfo 0 +#define XEN_DOMCTL_SCHEDOP_getinfo 1 +#define XEN_DOMCTL_SCHEDOP_putvcpuinfo 2 +#define XEN_DOMCTL_SCHEDOP_getvcpuinfo 3 +struct xen_domctl_scheduler_op { + uint32_t sched_id; /* XEN_SCHEDULER_* */ + uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */ + /* IN/OUT */ + union { + struct xen_domctl_sched_credit credit; + struct xen_domctl_sched_credit2 credit2; + struct xen_domctl_sched_rtds rtds; + struct { + XEN_GUEST_HANDLE_64(xen_domctl_schedparam_vcpu_t) vcpus; + /* + * IN: Number of elements in vcpus array. + * OUT: Number of processed elements of vcpus array. + */ + uint32_t nr_vcpus; + uint32_t padding; + } v; + } u; +}; + +/* XEN_DOMCTL_iomem_permission */ +struct xen_domctl_iomem_permission { + uint64_aligned_t first_mfn;/* first page (physical page number) in range */ + uint64_aligned_t nr_mfns; /* number of pages in range (>0) */ + uint8_t allow_access; /* allow (!0) or deny (0) access to range? */ +}; + +/* XEN_DOMCTL_set_address_size */ +/* XEN_DOMCTL_get_address_size */ +struct xen_domctl_address_size { + uint32_t size; +}; + +/* Assign a device to a guest. Sets up IOMMU structures. */ +/* XEN_DOMCTL_assign_device */ +/* + * XEN_DOMCTL_test_assign_device: Pass DOMID_INVALID to find out whether the + * given device is assigned to any DomU at all. Pass a specific domain ID to + * find out whether the given device can be assigned to that domain. + */ +/* + * XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs + * between the different type of device: + * - PCI device (XEN_DOMCTL_DEV_PCI) will be reassigned to DOM0 + * - DT device (XEN_DOMCTL_DEV_DT) will left unassigned. DOM0 + * will have to call XEN_DOMCTL_assign_device in order to use the + * device. + */ +#define XEN_DOMCTL_DEV_PCI 0 +#define XEN_DOMCTL_DEV_DT 1 +struct xen_domctl_assign_device { + /* IN */ + uint32_t dev; /* XEN_DOMCTL_DEV_* */ + uint32_t flags; +#define XEN_DOMCTL_DEV_RDM_RELAXED 1 /* assign only */ + union { + struct { + uint32_t machine_sbdf; /* machine PCI ID of assigned device */ + } pci; + struct { + uint32_t size; /* Length of the path */ + + XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */ + } dt; + } u; +}; + +/* Pass-through interrupts: bind real irq -> hvm devfn. */ +/* XEN_DOMCTL_bind_pt_irq */ +/* XEN_DOMCTL_unbind_pt_irq */ +enum pt_irq_type { + PT_IRQ_TYPE_PCI, + PT_IRQ_TYPE_ISA, + PT_IRQ_TYPE_MSI, + PT_IRQ_TYPE_MSI_TRANSLATE, + PT_IRQ_TYPE_SPI, /* ARM: valid range 32-1019 */ +}; +struct xen_domctl_bind_pt_irq { + uint32_t machine_irq; + uint32_t irq_type; /* enum pt_irq_type */ + + union { + struct { + uint8_t isa_irq; + } isa; + struct { + uint8_t bus; + uint8_t device; + uint8_t intx; + } pci; + struct { + uint8_t gvec; + uint32_t gflags; +#define XEN_DOMCTL_VMSI_X86_DEST_ID_MASK 0x0000ff +#define XEN_DOMCTL_VMSI_X86_RH_MASK 0x000100 +#define XEN_DOMCTL_VMSI_X86_DM_MASK 0x000200 +#define XEN_DOMCTL_VMSI_X86_DELIV_MASK 0x007000 +#define XEN_DOMCTL_VMSI_X86_TRIG_MASK 0x008000 +#define XEN_DOMCTL_VMSI_X86_UNMASKED 0x010000 + + uint64_aligned_t gtable; + } msi; + struct { + uint16_t spi; + } spi; + } u; +}; + + +/* Bind machine I/O address range -> HVM address range. */ +/* XEN_DOMCTL_memory_mapping */ +/* Returns + * - zero success, everything done + * - -E2BIG passed in nr_mfns value too large for the implementation + * - positive partial success for the first page frames (with + * less than nr_mfns), requiring re-invocation by the + * caller after updating inputs + * - negative error; other than -E2BIG + */ +#define DPCI_ADD_MAPPING 1 +#define DPCI_REMOVE_MAPPING 0 +struct xen_domctl_memory_mapping { + uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */ + uint64_aligned_t first_mfn; /* first page (machine page) in range */ + uint64_aligned_t nr_mfns; /* number of pages in range (>0) */ + uint32_t add_mapping; /* add or remove mapping */ + uint32_t padding; /* padding for 64-bit aligned structure */ +}; + +/* + * ARM: Clean and invalidate caches associated with given region of + * guest memory. + */ +struct xen_domctl_cacheflush { + /* IN: page range to flush. */ + xen_pfn_t start_pfn, nr_pfns; +}; + +/* + * XEN_DOMCTL_get_paging_mempool_size / XEN_DOMCTL_set_paging_mempool_size. + * + * Get or set the paging memory pool size. The size is in bytes. + * + * This is a dedicated pool of memory for Xen to use while managing the guest, + * typically containing pagetables. As such, there is an implementation + * specific minimum granularity. + * + * The set operation can fail mid-way through the request (e.g. Xen running + * out of memory, no free memory to reclaim from the pool, etc.). + */ +struct xen_domctl_paging_mempool { + uint64_aligned_t size; /* Size in bytes. */ +}; + +struct xen_domctl { + uint32_t cmd; +#define XEN_DOMCTL_createdomain 1 +#define XEN_DOMCTL_destroydomain 2 +#define XEN_DOMCTL_pausedomain 3 +#define XEN_DOMCTL_unpausedomain 4 +#define XEN_DOMCTL_getdomaininfo 5 +#define XEN_DOMCTL_setvcpuaffinity 9 +#define XEN_DOMCTL_shadow_op 10 +#define XEN_DOMCTL_max_mem 11 +#define XEN_DOMCTL_setvcpucontext 12 +#define XEN_DOMCTL_getvcpucontext 13 +#define XEN_DOMCTL_getvcpuinfo 14 +#define XEN_DOMCTL_max_vcpus 15 +#define XEN_DOMCTL_scheduler_op 16 +#define XEN_DOMCTL_setdomainhandle 17 +#define XEN_DOMCTL_setdebugging 18 +#define XEN_DOMCTL_irq_permission 19 +#define XEN_DOMCTL_iomem_permission 20 +#define XEN_DOMCTL_ioport_permission 21 +#define XEN_DOMCTL_hypercall_init 22 +#define XEN_DOMCTL_settimeoffset 24 +#define XEN_DOMCTL_getvcpuaffinity 25 +#define XEN_DOMCTL_real_mode_area 26 /* Obsolete PPC only */ +#define XEN_DOMCTL_resumedomain 27 +#define XEN_DOMCTL_sendtrigger 28 +#define XEN_DOMCTL_subscribe 29 +#define XEN_DOMCTL_gethvmcontext 33 +#define XEN_DOMCTL_sethvmcontext 34 +#define XEN_DOMCTL_set_address_size 35 +#define XEN_DOMCTL_get_address_size 36 +#define XEN_DOMCTL_assign_device 37 +#define XEN_DOMCTL_bind_pt_irq 38 +#define XEN_DOMCTL_memory_mapping 39 +#define XEN_DOMCTL_ioport_mapping 40 +#define XEN_DOMCTL_set_ext_vcpucontext 42 +#define XEN_DOMCTL_get_ext_vcpucontext 43 +#define XEN_DOMCTL_set_opt_feature 44 /* Obsolete IA64 only */ +#define XEN_DOMCTL_test_assign_device 45 +#define XEN_DOMCTL_set_target 46 +#define XEN_DOMCTL_deassign_device 47 +#define XEN_DOMCTL_unbind_pt_irq 48 +#define XEN_DOMCTL_get_device_group 50 +#define XEN_DOMCTL_debug_op 54 +#define XEN_DOMCTL_gethvmcontext_partial 55 +#define XEN_DOMCTL_vm_event_op 56 +#define XEN_DOMCTL_mem_sharing_op 57 +#define XEN_DOMCTL_gettscinfo 59 +#define XEN_DOMCTL_settscinfo 60 +#define XEN_DOMCTL_getpageframeinfo3 61 +#define XEN_DOMCTL_setvcpuextstate 62 +#define XEN_DOMCTL_getvcpuextstate 63 +#define XEN_DOMCTL_set_access_required 64 +#define XEN_DOMCTL_audit_p2m 65 +#define XEN_DOMCTL_set_virq_handler 66 +#define XEN_DOMCTL_set_broken_page_p2m 67 +#define XEN_DOMCTL_setnodeaffinity 68 +#define XEN_DOMCTL_getnodeaffinity 69 +#define XEN_DOMCTL_cacheflush 71 +#define XEN_DOMCTL_get_vcpu_msrs 72 +#define XEN_DOMCTL_set_vcpu_msrs 73 +#define XEN_DOMCTL_setvnumainfo 74 +#define XEN_DOMCTL_psr_cmt_op 75 +#define XEN_DOMCTL_monitor_op 77 +#define XEN_DOMCTL_psr_alloc 78 +#define XEN_DOMCTL_soft_reset 79 +#define XEN_DOMCTL_vuart_op 81 +#define XEN_DOMCTL_get_cpu_policy 82 +#define XEN_DOMCTL_set_cpu_policy 83 +#define XEN_DOMCTL_vmtrace_op 84 +#define XEN_DOMCTL_get_paging_mempool_size 85 +#define XEN_DOMCTL_set_paging_mempool_size 86 +#define XEN_DOMCTL_gdbsx_guestmemio 1000 +#define XEN_DOMCTL_gdbsx_pausevcpu 1001 +#define XEN_DOMCTL_gdbsx_unpausevcpu 1002 +#define XEN_DOMCTL_gdbsx_domstatus 1003 + uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ + domid_t domain; + uint16_t _pad[3]; + union { + struct xen_domctl_createdomain createdomain; + struct xen_domctl_getdomaininfo getdomaininfo; + struct xen_domctl_max_mem max_mem; + struct xen_domctl_vcpucontext vcpucontext; + struct xen_domctl_max_vcpus max_vcpus; + struct xen_domctl_scheduler_op scheduler_op; + struct xen_domctl_iomem_permission iomem_permission; + struct xen_domctl_address_size address_size; + struct xen_domctl_assign_device assign_device; + struct xen_domctl_bind_pt_irq bind_pt_irq; + struct xen_domctl_memory_mapping memory_mapping; + struct xen_domctl_cacheflush cacheflush; + struct xen_domctl_paging_mempool paging_mempool; + uint8_t pad[128]; + } u; +}; +typedef struct xen_domctl xen_domctl_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_t); + +#endif /* __XEN_PUBLIC_DOMCTL_H__ */ diff --git a/include/zephyr/xen/public/memory.h b/include/zephyr/xen/public/memory.h index 9496b5f5271..513b32735de 100644 --- a/include/zephyr/xen/public/memory.h +++ b/include/zephyr/xen/public/memory.h @@ -69,6 +69,40 @@ struct xen_memory_reservation { typedef struct xen_memory_reservation xen_memory_reservation_t; DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); +/* A batched version of add_to_physmap. */ +#define XENMEM_add_to_physmap_batch 23 +struct xen_add_to_physmap_batch { + /* IN */ + /* Which domain to change the mapping for. */ + domid_t domid; + uint16_t space; /* => enum phys_map_space */ + + /* Number of pages to go through */ + uint16_t size; + +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */ +#else + union xen_add_to_physmap_batch_extra { + domid_t foreign_domid; /* gmfn_foreign */ + uint16_t res0; /* All the other spaces. Should be 0 */ + } u; +#endif + + /* Indexes into space being mapped. */ + XEN_GUEST_HANDLE(xen_ulong_t) idxs; + + /* GPFN in domid where the source mapping page should appear. */ + XEN_GUEST_HANDLE(xen_pfn_t) gpfns; + + /* OUT */ + /* Per index error code. */ + XEN_GUEST_HANDLE(int) errs; +}; +typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t); + + #define XENMAPSPACE_shared_info 0 /* shared info page */ #define XENMAPSPACE_grant_table 1 /* grant table page */ #define XENMAPSPACE_gmfn 2 /* GMFN */ diff --git a/include/zephyr/xen/public/xen.h b/include/zephyr/xen/public/xen.h index 8b7c478656b..f8a5b6eba05 100644 --- a/include/zephyr/xen/public/xen.h +++ b/include/zephyr/xen/public/xen.h @@ -47,6 +47,7 @@ __DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long); #endif DEFINE_XEN_GUEST_HANDLE(void); +DEFINE_XEN_GUEST_HANDLE(uint8_t); DEFINE_XEN_GUEST_HANDLE(uint64_t); DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); @@ -371,6 +372,26 @@ struct shared_info { typedef struct shared_info shared_info_t; #endif +typedef uint8_t xen_domain_handle_t[16]; + +#ifndef int64_aligned_t +#define int64_aligned_t int64_t +#endif +#ifndef uint64_aligned_t +#define uint64_aligned_t uint64_t +#endif +#ifndef XEN_GUEST_HANDLE_64 +#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) +#endif + +#ifndef __ASSEMBLY__ +struct xenctl_bitmap { + XEN_GUEST_HANDLE_64(uint8_t) bitmap; + uint32_t nr_bits; +}; +typedef struct xenctl_bitmap xenctl_bitmap_t; +#endif + #endif /* !__ASSEMBLY__ */ #endif /* __XEN_PUBLIC_XEN_H__ */ From 3581527b53967a22fc005328d278bb1b5ea5a7c6 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Wed, 26 Apr 2023 13:39:28 +0300 Subject: [PATCH 0470/4498] xen: implement Xen domain control interface Add Xen domctl API implementation for Zephyr as control domain. Previously Zephyr OS was used as unprivileged Xen domain (Domain-U), but it also can be used as lightweight Xen control domain (Domain-0). To implement such fuctionality additional Xen interfaces are needed. One of them is Xen domain controls (domctls) - it allows to create, configure and manage Xen domains. Also, used it as a possibility to update files copyright and licenses identifiers in touched files. Signed-off-by: Dmytro Firsov --- arch/arm64/core/xen/hypercall.S | 9 +- drivers/xen/CMakeLists.txt | 4 +- drivers/xen/dom0/CMakeLists.txt | 4 + drivers/xen/dom0/domctl.c | 305 ++++++++++++++++++++++++++ include/zephyr/arch/arm64/hypercall.h | 9 +- include/zephyr/xen/dom0/domctl.h | 37 ++++ 6 files changed, 361 insertions(+), 7 deletions(-) create mode 100644 drivers/xen/dom0/CMakeLists.txt create mode 100644 drivers/xen/dom0/domctl.c create mode 100644 include/zephyr/xen/dom0/domctl.h diff --git a/arch/arm64/core/xen/hypercall.S b/arch/arm64/core/xen/hypercall.S index 429b0a42286..063538bae90 100644 --- a/arch/arm64/core/xen/hypercall.S +++ b/arch/arm64/core/xen/hypercall.S @@ -1,7 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 */ /* - * Copyright (c) 2021 EPAM Systems - * - * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2021-2023 EPAM Systems */ #include @@ -24,3 +23,7 @@ HYPERCALL(sched_op); HYPERCALL(event_channel_op); HYPERCALL(hvm_op); HYPERCALL(memory_op); + +#ifdef CONFIG_XEN_DOM0 +HYPERCALL(domctl); +#endif diff --git a/drivers/xen/CMakeLists.txt b/drivers/xen/CMakeLists.txt index fe5a679fd9b..350c6d577bb 100644 --- a/drivers/xen/CMakeLists.txt +++ b/drivers/xen/CMakeLists.txt @@ -1,6 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021-2022 EPAM Systems +# Copyright (c) 2021-2023 EPAM Systems zephyr_sources(hvm.c) zephyr_sources(events.c) zephyr_sources_ifdef(CONFIG_XEN_GRANT_TABLE gnttab.c) + +add_subdirectory_ifdef(CONFIG_XEN_DOM0 dom0) diff --git a/drivers/xen/dom0/CMakeLists.txt b/drivers/xen/dom0/CMakeLists.txt new file mode 100644 index 00000000000..c722beb6119 --- /dev/null +++ b/drivers/xen/dom0/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 EPAM Systems + +zephyr_sources(domctl.c) diff --git a/drivers/xen/dom0/domctl.c b/drivers/xen/dom0/domctl.c new file mode 100644 index 00000000000..2b1e3a6ca5b --- /dev/null +++ b/drivers/xen/dom0/domctl.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static int do_domctl(xen_domctl_t *domctl) +{ + domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION; + return HYPERVISOR_domctl(domctl); +} + +int xen_domctl_scheduler_op(int domid, struct xen_domctl_scheduler_op *sched_op) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_scheduler_op, + .domain = domid, + .u.scheduler_op = *sched_op, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_pausedomain(int domid) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_pausedomain, + .domain = domid, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_unpausedomain(int domid) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_unpausedomain, + .domain = domid, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_resumedomain(int domid) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_resumedomain, + .domain = domid, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_getvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_getvcpucontext, + .domain = domid, + .u.vcpucontext.vcpu = 0, + }; + + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); + + return do_domctl(&domctl); +} + +int xen_domctl_setvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_setvcpucontext, + .domain = domid, + .u.vcpucontext.vcpu = 0, + }; + + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); + + return do_domctl(&domctl); +} + +int xen_domctl_getdomaininfo(int domid, xen_domctl_getdomaininfo_t *dom_info) +{ + int rc; + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_getdomaininfo, + .domain = domid, + }; + + rc = do_domctl(&domctl); + if (rc) { + return rc; + } + + memcpy(dom_info, &domctl.u.getdomaininfo, sizeof(*dom_info)); + + return 0; +} + +int xen_domctl_get_paging_mempool_size(int domid, uint64_t *size_mb) +{ + int rc; + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_get_paging_mempool_size, + .domain = domid, + }; + + rc = do_domctl(&domctl); + if (rc) + return rc; + + *size_mb = domctl.u.paging_mempool.size; + + return 0; +} + +int xen_domctl_set_paging_mempool_size(int domid, uint64_t size_mb) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_set_paging_mempool_size, + .domain = domid, + .u.paging_mempool.size = size_mb, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_max_mem(int domid, uint64_t max_memkb) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_max_mem, + .domain = domid, + .u.max_mem.max_memkb = max_memkb, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_set_address_size(int domid, int addr_size) +{ + xen_domctl_t domctl = { + .domain = domid, + .cmd = XEN_DOMCTL_set_address_size, + .u.address_size.size = addr_size, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_iomem_permission(int domid, uint64_t first_mfn, + uint64_t nr_mfns, uint8_t allow_access) +{ + xen_domctl_t domctl = { + .domain = domid, + .cmd = XEN_DOMCTL_iomem_permission, + .u.iomem_permission.first_mfn = first_mfn, + .u.iomem_permission.nr_mfns = nr_mfns, + .u.iomem_permission.allow_access = allow_access, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_memory_mapping(int domid, uint64_t first_gfn, uint64_t first_mfn, + uint64_t nr_mfns, uint32_t add_mapping) +{ + int ret; + uint64_t curr, nr_max, done; + xen_domctl_t domctl = { + .domain = domid, + .cmd = XEN_DOMCTL_memory_mapping, + .u.memory_mapping.add_mapping = add_mapping, + }; + + if (!nr_mfns) { + return 0; + } + + /* nr_mfns can be big and we need to handle this here */ + done = 0; + nr_max = nr_mfns; + do { + domctl.u.memory_mapping.first_gfn = first_gfn + done; + domctl.u.memory_mapping.first_mfn = first_mfn + done; + + curr = MIN(nr_mfns - done, nr_max); + domctl.u.memory_mapping.nr_mfns = curr; + + ret = do_domctl(&domctl); + if (ret < 0) { + if (ret == -E2BIG) { + /* Check if we not reach min amount */ + if (nr_max <= 1) { + break; + } + + /* Decrease amount twice and try again */ + nr_max = nr_max >> 1; + continue; + } else { + break; + } + } + + done += curr; + } while (done < nr_mfns); + + /* We may come here when get E2BIG and reach 1 at nr_max */ + if (!done) { + ret = -1; + } + + return ret; +} + +int xen_domctl_assign_dt_device(int domid, char *dtdev_path) +{ + xen_domctl_t domctl = { + .domain = domid, + .cmd = XEN_DOMCTL_assign_device, + .u.assign_device.flags = 0, + .u.assign_device.dev = XEN_DOMCTL_DEV_DT, + .u.assign_device.u.dt.size = strlen(dtdev_path), + }; + + set_xen_guest_handle(domctl.u.assign_device.u.dt.path, dtdev_path); + + return do_domctl(&domctl); + +} + +int xen_domctl_bind_pt_irq(int domid, uint32_t machine_irq, uint8_t irq_type, + uint8_t bus, uint8_t device, uint8_t intx, uint8_t isa_irq, + uint16_t spi) +{ + xen_domctl_t domctl = { + .domain = domid, + .cmd = XEN_DOMCTL_bind_pt_irq, + }; + struct xen_domctl_bind_pt_irq *bind = &(domctl.u.bind_pt_irq); + + switch (irq_type) { + case PT_IRQ_TYPE_SPI: + bind->irq_type = irq_type; + bind->machine_irq = machine_irq; + bind->u.spi.spi = spi; + break; + default: + /* TODO: implement other types */ + return -ENOTSUP; + } + + return do_domctl(&domctl); +} + +int xen_domctl_max_vcpus(int domid, int max_vcpus) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_max_vcpus, + .domain = domid, + .u.max_vcpus.max = max_vcpus, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_createdomain(int domid, struct xen_domctl_createdomain *config) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_createdomain, + .domain = domid, + .u.createdomain = *config, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_destroydomain(int domid) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_destroydomain, + .domain = domid, + }; + + return do_domctl(&domctl); +} + +int xen_domctl_cacheflush(int domid, struct xen_domctl_cacheflush *cacheflush) +{ + xen_domctl_t domctl = { + .cmd = XEN_DOMCTL_cacheflush, + .domain = domid, + .u.cacheflush = *cacheflush, + }; + + return do_domctl(&domctl); +} diff --git a/include/zephyr/arch/arm64/hypercall.h b/include/zephyr/arch/arm64/hypercall.h index 7a0b7aecf2b..023ea10803d 100644 --- a/include/zephyr/arch/arm64/hypercall.h +++ b/include/zephyr/arch/arm64/hypercall.h @@ -1,7 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 */ /* - * Copyright (c) 2021-2022 EPAM Systems - * - * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2021-2023 EPAM Systems */ #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_HYPERCALL_H_ @@ -15,4 +14,8 @@ int HYPERVISOR_hvm_op(int op, void *param); int HYPERVISOR_memory_op(int op, void *param); int HYPERVISOR_grant_table_op(int op, void *uop, unsigned int count); +#ifdef CONFIG_XEN_DOM0 +int HYPERVISOR_domctl(void *param); +#endif + #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_HYPERCALL_H_ */ diff --git a/include/zephyr/xen/dom0/domctl.h b/include/zephyr/xen/dom0/domctl.h new file mode 100644 index 00000000000..6dfe9053887 --- /dev/null +++ b/include/zephyr/xen/dom0/domctl.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + * + */ +#ifndef __XEN_DOM0_DOMCTL_H__ +#define __XEN_DOM0_DOMCTL_H__ + +#include +#include +#include + +#include + +int xen_domctl_scheduler_op(int domid, struct xen_domctl_scheduler_op *sched_op); +int xen_domctl_pausedomain(int domid); +int xen_domctl_unpausedomain(int domid); +int xen_domctl_resumedomain(int domid); +int xen_domctl_getvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt); +int xen_domctl_setvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt); +int xen_domctl_getdomaininfo(int domid, xen_domctl_getdomaininfo_t *dom_info); +int xen_domctl_set_paging_mempool_size(int domid, uint64_t size_mb); +int xen_domctl_max_mem(int domid, uint64_t max_memkb); +int xen_domctl_set_address_size(int domid, int addr_size); +int xen_domctl_iomem_permission(int domid, uint64_t first_mfn, + uint64_t nr_mfns, uint8_t allow_access); +int xen_domctl_memory_mapping(int domid, uint64_t first_gfn, uint64_t first_mfn, + uint64_t nr_mfns, uint32_t add_mapping); +int xen_domctl_assign_dt_device(int domid, char *dtdev_path); +int xen_domctl_bind_pt_irq(int domid, uint32_t machine_irq, uint8_t irq_type, uint8_t bus, + uint8_t device, uint8_t intx, uint8_t isa_irq, uint16_t spi); +int xen_domctl_max_vcpus(int domid, int max_vcpus); +int xen_domctl_createdomain(int domid, struct xen_domctl_createdomain *config); +int xen_domctl_cacheflush(int domid, struct xen_domctl_cacheflush *cacheflush); +int xen_domctl_destroydomain(int domid); + +#endif /* __XEN_DOM0_DOMCTL_H__ */ From 74b271bc2a69d0ea9ce02a44f94cf68b50b39ba8 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 2 Feb 2023 14:38:23 +0200 Subject: [PATCH 0471/4498] xen: change HVM functions signature to run it for other domains This commit adds possibility to call hypervisor HVM parameter functions for specified domain (instead of only DOMID_SELF). It is needed for configuring domains, that were created from Zephyr control domain. Signed-off-by: Dmytro Firsov --- drivers/serial/uart_hvc_xen.c | 4 ++-- drivers/xen/hvm.c | 8 ++++---- include/zephyr/xen/hvm.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/serial/uart_hvc_xen.c b/drivers/serial/uart_hvc_xen.c index 3911fbfae44..fc26e79f13a 100644 --- a/drivers/serial/uart_hvc_xen.c +++ b/drivers/serial/uart_hvc_xen.c @@ -233,14 +233,14 @@ int xen_console_init(const struct device *dev) data->dev = dev; - ret = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &data->evtchn); + ret = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, DOMID_SELF, &data->evtchn); if (ret) { LOG_ERR("%s: failed to get Xen console evtchn, ret = %d\n", __func__, ret); return ret; } - ret = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &console_pfn); + ret = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, DOMID_SELF, &console_pfn); if (ret) { LOG_ERR("%s: failed to get Xen console PFN, ret = %d\n", __func__, ret); diff --git a/drivers/xen/hvm.c b/drivers/xen/hvm.c index 67c254a8bbc..5244d34d433 100644 --- a/drivers/xen/hvm.c +++ b/drivers/xen/hvm.c @@ -11,23 +11,23 @@ #include -int hvm_set_parameter(int idx, uint64_t value) +int hvm_set_parameter(int idx, int domid, uint64_t value) { struct xen_hvm_param xhv; - xhv.domid = DOMID_SELF; + xhv.domid = domid; xhv.index = idx; xhv.value = value; return HYPERVISOR_hvm_op(HVMOP_set_param, &xhv); } -int hvm_get_parameter(int idx, uint64_t *value) +int hvm_get_parameter(int idx, int domid, uint64_t *value) { int ret = 0; struct xen_hvm_param xhv; - xhv.domid = DOMID_SELF; + xhv.domid = domid; xhv.index = idx; ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); diff --git a/include/zephyr/xen/hvm.h b/include/zephyr/xen/hvm.h index 968abf01c1a..1848705975a 100644 --- a/include/zephyr/xen/hvm.h +++ b/include/zephyr/xen/hvm.h @@ -11,7 +11,7 @@ #include -int hvm_set_parameter(int idx, uint64_t value); -int hvm_get_parameter(int idx, uint64_t *value); +int hvm_set_parameter(int idx, int domid, uint64_t value); +int hvm_get_parameter(int idx, int domid, uint64_t *value); #endif /* __XEN_HVM_H__ */ From 3942e3ccff0f270c39f90f113cc632c4cc21a3bc Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 27 Apr 2023 12:35:25 +0300 Subject: [PATCH 0472/4498] xen: add helper functions for Xen domain memory management Add wrapper functions for Xen memory managment hypercall. They can be used for unprivilaged Zephyr guest initialization and for domain management, when Zephyr is used as Xen Domain 0. Signed-off-by: Dmytro Firsov --- drivers/xen/CMakeLists.txt | 1 + drivers/xen/memory.c | 68 +++++++++++++++++++++++++++++++++++++ include/zephyr/xen/memory.h | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/xen/memory.c create mode 100644 include/zephyr/xen/memory.h diff --git a/drivers/xen/CMakeLists.txt b/drivers/xen/CMakeLists.txt index 350c6d577bb..412be7d318d 100644 --- a/drivers/xen/CMakeLists.txt +++ b/drivers/xen/CMakeLists.txt @@ -4,5 +4,6 @@ zephyr_sources(hvm.c) zephyr_sources(events.c) zephyr_sources_ifdef(CONFIG_XEN_GRANT_TABLE gnttab.c) +zephyr_sources(memory.c) add_subdirectory_ifdef(CONFIG_XEN_DOM0 dom0) diff --git a/drivers/xen/memory.c b/drivers/xen/memory.c new file mode 100644 index 00000000000..6472ad74af2 --- /dev/null +++ b/drivers/xen/memory.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + */ + +#include +#include +#include +#include + +#include + +int xendom_add_to_physmap(int domid, unsigned long idx, + unsigned int space, xen_pfn_t gpfn) +{ + struct xen_add_to_physmap xatp = { + .domid = domid, + .idx = idx, + .space = space, + .gpfn = gpfn, + }; + + return HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); +} + +int xendom_add_to_physmap_batch(int domid, int foreign_domid, + unsigned int space, unsigned int size, + xen_ulong_t *idxs, xen_pfn_t *gpfns, int *errs) +{ + struct xen_add_to_physmap_batch xatpb = { + .domid = domid, + .u.foreign_domid = foreign_domid, + .space = space, + .size = size, + }; + + set_xen_guest_handle(xatpb.gpfns, gpfns); + set_xen_guest_handle(xatpb.idxs, idxs); + set_xen_guest_handle(xatpb.errs, errs); + + return HYPERVISOR_memory_op(XENMEM_add_to_physmap_batch, &xatpb); +} + +int xendom_remove_from_physmap(int domid, xen_pfn_t gpfn) +{ + struct xen_remove_from_physmap xrfp = { + .domid = domid, + .gpfn = gpfn, + }; + + return HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrfp); +} + +int xendom_populate_physmap(int domid, unsigned int extent_order, + unsigned int nr_extents, unsigned int mem_flags, + xen_pfn_t *extent_start) +{ + struct xen_memory_reservation reservation = { + .domid = domid, + .extent_order = extent_order, + .nr_extents = nr_extents, + .mem_flags = mem_flags, + }; + + set_xen_guest_handle(reservation.extent_start, extent_start); + + return HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); +} diff --git a/include/zephyr/xen/memory.h b/include/zephyr/xen/memory.h new file mode 100644 index 00000000000..636f0998856 --- /dev/null +++ b/include/zephyr/xen/memory.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + */ + +#include +#include +#include + +/** + * Add mapping for specified page frame in Xen domain physmap. + * + * @param domid domain id, where mapping will be added. For unprivileged should + * be DOMID_SELF. + * @param idx index into space being mapped. + * @param space XENMAPSPACE_* mapping space identifier. + * @param gpfn page frame where the source mapping page should appear. + * @return zero on success, negative errno on error. + */ +int xendom_add_to_physmap(int domid, unsigned long idx, unsigned int space, + xen_pfn_t gpfn); + +/** + * Add mapping for specified set of page frames to Xen domain physmap. + * + * @param domid domain id, where mapping will be added. For unprivileged + * should be DOMID_SELF. + * @param foreign_domid for gmfn_foreign - domain id, whose pages being mapped, + * 0 for other. + * @param space XENMAPSPACE_* mapping space identifier. + * @param size number of page frames being mapped. + * @param idxs array of indexes into space being mapped. + * @param gpfns array of page frames where the mapping should appear. + * @param errs array of per-index error codes. + * @return zero on success, negative errno on error. + */ +int xendom_add_to_physmap_batch(int domid, int foreign_domid, + unsigned int space, unsigned int size, + xen_ulong_t *idxs, xen_pfn_t *gpfns, int *errs); + +/** + * Removes page frame from Xen domain physmap. + * + * @param domid domain id, whose page is going to be removed. For unprivileged + * should be DOMID_SELF. + * @param gpfn page frame number, that needs to be removed + * @return zero on success, negative errno on error. + */ +int xendom_remove_from_physmap(int domid, xen_pfn_t gpfn); + +/** + * Populate specified Xen domain page frames with memory. + * + * @param domid domain id, where mapping will be added. For unprivileged + * should be DOMID_SELF. + * @param extent_order size/alignment of each extent (size is 2^extent_order), + * e.g. 0 for 4K extents, 9 for 2M etc. + * @param nr_extents number of page frames being populated. + * @param mem_flags N/A, should be 0 for Arm. + * @param extent_start page frame bases of extents to populate with memory. + * @return number of populated frames success, negative errno on + * error. + */ +int xendom_populate_physmap(int domid, unsigned int extent_order, + unsigned int nr_extents, unsigned int mem_flags, + xen_pfn_t *extent_start); From 5207c6f3f9c8faa209790289ff6ccc8735823a89 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 11 May 2023 12:30:59 +0300 Subject: [PATCH 0473/4498] snippets: add virtual Xen dom0 snippet support Zephyr snippets allow to apply pre-defined build configuration and extentions to your build0. It is made by applying generic snippet conf/device-tree changes and may be extended with platform-specific files. It looks like great approach for convertion Zephyr OS build to Xen control domain on different boards, as it requires Kconfig changes and board device tree changes (configuration for memory node, hypervisor console, grant table region etc). Please note, that Xen hypervisor passes all selected parameters via domain device-tree, but Zephyr does not use it in runtime. So, user should keep values in board overlays in sync with real Xen values. Add example and docs for converting qemu_cortex_a53 board to Xen Domain-0 guest. This approach might be used for other boards, where Zephyr Dom0 is needed. Signed-off-by: Mykola Kvach Signed-off-by: Dmytro Firsov --- snippets/xen_dom0/README.rst | 51 +++++++++++++++++++ .../xen_dom0/boards/qemu_cortex_a53.overlay | 47 +++++++++++++++++ snippets/xen_dom0/snippet.yml | 9 ++++ snippets/xen_dom0/xen_dom0.conf | 1 + snippets/xen_dom0/xen_dom0.overlay | 25 +++++++++ 5 files changed, 133 insertions(+) create mode 100644 snippets/xen_dom0/README.rst create mode 100644 snippets/xen_dom0/boards/qemu_cortex_a53.overlay create mode 100644 snippets/xen_dom0/snippet.yml create mode 100644 snippets/xen_dom0/xen_dom0.conf create mode 100644 snippets/xen_dom0/xen_dom0.overlay diff --git a/snippets/xen_dom0/README.rst b/snippets/xen_dom0/README.rst new file mode 100644 index 00000000000..a871d9f4f51 --- /dev/null +++ b/snippets/xen_dom0/README.rst @@ -0,0 +1,51 @@ +.. _xen_dom0: + +Xen Dom0: universal snippet for XEN control domain +################################################## + +Overview +******** + +This snippet allows user to build Zephyr as a Xen initial domain (Dom0). The feature +is implemented as configuration snippet to allow support for any compatible platform. + +How to add support of a new board +********************************* + +* add board dts overlay to this snippet which deletes/adds memory and deletes UART nodes; +* add correct memory and hypervisor nodes, based on regions Xen picked for Domain-0 on your setup. + +Programming +*********** + +Correct snippet designation for Xen must +be entered when you invoke ``west build``. +For example: + +.. code-block:: console + + west build -b qemu_cortex_a53 -S xen_dom0 samples/synchronization + +QEMU example with Xen +*********************** + +Overlay for qemu_cortex_a53 board, that is present in `board/` directory of this snippet is QEMU +Xen control domain example. To run such setup, you need to: + +* fetch and build Xen (e.g. RELEASE-4.17.0) for arm64 platform +* take and compile sample device tree from `example/` directory +* build your Zephyr sample/application with `xen_dom0` snippet and start it as Xen control domain + +For starting you can use QEMU from Zephyr SDK by following command: + +.. code-block:: console + + /sysroots/x86_64-pokysdk-linux/usr/bin/qemu-system-aarch64 -cpu cortex-a53 \ + -m 6G -nographic -machine virt,gic-version=3,virtualization=true -chardev stdio,id=con,mux=on \ + -serial chardev:con -mon chardev=con,mode=readline -pidfile qemu.pid \ + -device loader,file=/zephyr.bin,addr=0x40600000 \ + -dtb /xen.dtb -kernel /xen + +This will start you a Xen hypervisor with your application as Xen control domain. To make it usable, +you can add `zephyr-xenlib` by Xen-troops library to your project. It'll provide basic domain +management functionalities - domain creation and configuration. diff --git a/snippets/xen_dom0/boards/qemu_cortex_a53.overlay b/snippets/xen_dom0/boards/qemu_cortex_a53.overlay new file mode 100644 index 00000000000..8d841a2be6d --- /dev/null +++ b/snippets/xen_dom0/boards/qemu_cortex_a53.overlay @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 EPAM Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &sram0; + +&uart0 { + /* Xen consoleio will be used */ + status = "disabled"; +}; + +/ { + /* + * This node may differs on different setups, please check + * following line in Xen boot log to set it right: + * (XEN) Grant table range: 0x00000040200000-0x00000040240000 + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + hypervisor: hypervisor@40200000 { + compatible = "xen,xen"; + reg = <0x0 0x40200000 0x0 0x40000>; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + /* + * This node may differs on different setups, because Xen picks + * region for Domain-0 for every specific configuration. You can + * start Xen for your platform and check following log: + * (XEN) Allocating 1:1 mappings for dom0: + * (XEN) BANK[0] 0x00000058000000-0x00000060000000 (128MB) + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + soc { + sram0: memory@58000000 { + device_type = "mmio-sram"; + reg = <0x00 0x58000000 0x00 DT_SIZE_M(128)>; + }; + }; +}; diff --git a/snippets/xen_dom0/snippet.yml b/snippets/xen_dom0/snippet.yml new file mode 100644 index 00000000000..d3af96f9527 --- /dev/null +++ b/snippets/xen_dom0/snippet.yml @@ -0,0 +1,9 @@ +name: xen_dom0 +append: + EXTRA_DTC_OVERLAY_FILE: xen_dom0.overlay + EXTRA_CONF_FILE: xen_dom0.conf + +boards: + qemu_cortex_a53: + append: + EXTRA_DTC_OVERLAY_FILE: boards/qemu_cortex_a53.overlay diff --git a/snippets/xen_dom0/xen_dom0.conf b/snippets/xen_dom0/xen_dom0.conf new file mode 100644 index 00000000000..c5cb5d24aa3 --- /dev/null +++ b/snippets/xen_dom0/xen_dom0.conf @@ -0,0 +1 @@ +CONFIG_XEN_DOM0=y diff --git a/snippets/xen_dom0/xen_dom0.overlay b/snippets/xen_dom0/xen_dom0.overlay new file mode 100644 index 00000000000..98fe1e39d67 --- /dev/null +++ b/snippets/xen_dom0/xen_dom0.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 EPAM Systems. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { + zephyr,console = &xen_consoleio_hvc; + zephyr,shell-uart = &xen_consoleio_hvc; + }; + + psci { + method = "hvc"; + }; + + xen_consoleio_hvc: hvc { + compatible = "xen,uart_hvc"; + status = "okay"; + }; +}; From 7f04c352c14c0253110305df4f62162fe06ba646 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Tue, 8 Aug 2023 12:47:50 +0300 Subject: [PATCH 0474/4498] snippets: xen_dom0: add support for Renesas R-Car Gen3 boards Renesas rcar_h3ulcb_ca57 and rcar_salvator_xs_m3 boards support recently was added to Zephyr mainline. Add Xen control domain guest support for them via xen_dom0 snippet extention. Note: please pay attetion to overlay nodes and comments in case of any issues on your setup. Signed-off-by: Dmytro Firsov --- .../xen_dom0/boards/rcar_h3ulcb_ca57.overlay | 41 +++++++++++++++++++ .../boards/rcar_salvator_xs_m3.overlay | 41 +++++++++++++++++++ snippets/xen_dom0/snippet.yml | 6 +++ 3 files changed, 88 insertions(+) create mode 100644 snippets/xen_dom0/boards/rcar_h3ulcb_ca57.overlay create mode 100644 snippets/xen_dom0/boards/rcar_salvator_xs_m3.overlay diff --git a/snippets/xen_dom0/boards/rcar_h3ulcb_ca57.overlay b/snippets/xen_dom0/boards/rcar_h3ulcb_ca57.overlay new file mode 100644 index 00000000000..9af28690c2c --- /dev/null +++ b/snippets/xen_dom0/boards/rcar_h3ulcb_ca57.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 EPAM Systems. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &ram; +/delete-node/ &scif2; + +/ { + /* + * This node may differs on different setups, please check + * following line in Xen boot log to set it right: + * (XEN) Grant table range: 0x00000088080000-0x000000880c0000 + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + hypervisor: hypervisor@88080000 { + compatible = "xen,xen"; + reg = <0x0 0x88080000 0x0 0x40000>; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + /* + * This node may differs on different setups, because Xen picks + * region for Domain-0 for every specific configuration. You can + * start Xen for your platform and check following log: + * (XEN) Allocating 1:1 mappings for dom0: + * (XEN) BANK[0] 0x00000060000000-0x00000070000000 (256MB) + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + ram: memory@60000000 { + device_type = "mmio-sram"; + reg = <0x00 0x60000000 0x00 DT_SIZE_M(256)>; + }; +}; diff --git a/snippets/xen_dom0/boards/rcar_salvator_xs_m3.overlay b/snippets/xen_dom0/boards/rcar_salvator_xs_m3.overlay new file mode 100644 index 00000000000..9af28690c2c --- /dev/null +++ b/snippets/xen_dom0/boards/rcar_salvator_xs_m3.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 EPAM Systems. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &ram; +/delete-node/ &scif2; + +/ { + /* + * This node may differs on different setups, please check + * following line in Xen boot log to set it right: + * (XEN) Grant table range: 0x00000088080000-0x000000880c0000 + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + hypervisor: hypervisor@88080000 { + compatible = "xen,xen"; + reg = <0x0 0x88080000 0x0 0x40000>; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + /* + * This node may differs on different setups, because Xen picks + * region for Domain-0 for every specific configuration. You can + * start Xen for your platform and check following log: + * (XEN) Allocating 1:1 mappings for dom0: + * (XEN) BANK[0] 0x00000060000000-0x00000070000000 (256MB) + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + ram: memory@60000000 { + device_type = "mmio-sram"; + reg = <0x00 0x60000000 0x00 DT_SIZE_M(256)>; + }; +}; diff --git a/snippets/xen_dom0/snippet.yml b/snippets/xen_dom0/snippet.yml index d3af96f9527..cb6fddeaccd 100644 --- a/snippets/xen_dom0/snippet.yml +++ b/snippets/xen_dom0/snippet.yml @@ -7,3 +7,9 @@ boards: qemu_cortex_a53: append: EXTRA_DTC_OVERLAY_FILE: boards/qemu_cortex_a53.overlay + rcar_h3ulcb_ca57: + append: + EXTRA_DTC_OVERLAY_FILE: boards/rcar_h3ulcb_ca57.overlay + rcar_salvator_xs_m3: + append: + EXTRA_DTC_OVERLAY_FILE: boards/rcar_salvator_xs_m3.overlay From e4a125b6a42d4f7e0a7a179c169b92aad6fd665c Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 16 Aug 2023 12:48:26 +0200 Subject: [PATCH 0475/4498] dt: Make zephyr,memory-attr a capabilities bitmask This is the final step in making the `zephyr,memory-attr` property actually useful. The problem with the current implementation is that `zephyr,memory-attr` is an enum type, this is making very difficult to use that to actually describe the memory capabilities. The solution proposed in this PR is to use the `zephyr,memory-attr` property as an OR-ed bitmask of memory attributes. With the change proposed in this PR it is possible in the DeviceTree to mark the memory regions with a bitmask of attributes by using the `zephyr,memory-attr` property. This property and the related memory region can then be retrieved at run-time by leveraging a provided helper library or the usual DT helpers. The set of general attributes that can be specified in the property are defined and explained in `include/zephyr/dt-bindings/memory-attr/memory-attr.h` (the list can be extended when needed). For example, to mark a memory region in the DeviceTree as volatile, non-cacheable, out-of-order: mem: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; zephyr,memory-attr = <( DT_MEM_VOLATILE | DT_MEM_NON_CACHEABLE | DT_MEM_OOO )>; }; The `zephyr,memory-attr` property can also be used to set architecture-specific custom attributes that can be interpreted at run time. This is leveraged, among other things, to create MPU regions out of DeviceTree defined memory regions on ARM, for example: mem: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; zephyr,memory-region = "NOCACHE_REGION"; zephyr,memory-attr = <( DT_ARM_MPU(ATTR_MPU_RAM_NOCACHE) )>; }; See `include/zephyr/dt-bindings/memory-attr/memory-attr-mpu.h` to see how an architecture can define its own special memory attributes (in this case ARM MPU). The property can also be used to set custom software-specific attributes. For example we can think of marking a memory region as available to be used for memory allocation (not yet implemented): mem: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; zephyr,memory-attr = <( DT_MEM_NON_CACHEABLE | DT_MEM_SW_ALLOCATABLE )>; }; Or maybe we can leverage the property to specify some alignment requirements for the region: mem: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_SW_ALIGN(32) )>; }; The conventional and recommended way to deal and manage with memory regions marked with attributes is by using the provided `mem-attr` helper library by enabling `CONFIG_MEM_ATTR` (or by using the usual DT helpers). When this option is enabled the list of memory regions and their attributes are compiled in a user-accessible array and a set of functions is made available that can be used to query, probe and act on regions and attributes, see `include/zephyr/mem_mgmt/mem_attr.h` Note that the `zephyr,memory-attr` property is only a descriptive property of the capabilities of the associated memory region, but it does not result in any actual setting for the memory to be set. The user, code or subsystem willing to use this information to do some work (for example creating an MPU region out of the property) must use either the provided `mem-attr` library or the usual DeviceTree helpers to perform the required work / setting. Signed-off-by: Carlo Caione --- arch/arm/core/mpu/arm_mpu.c | 87 ++++++++++ arch/arm/core/mpu/nxp_mpu.c | 68 ++++++++ arch/arm64/core/cortex_r/arm_mpu.c | 73 ++++++++ .../arduino_giga_r1/arduino_giga_r1_m7.dts | 3 +- .../arm/stm32f746g_disco/stm32f746g_disco.dts | 4 +- boards/arm/stm32f7508_dk/stm32f7508_dk.dts | 3 +- .../arm/stm32f769i_disco/stm32f769i_disco.dts | 3 +- .../stm32h747i_disco/stm32h747i_disco_m7.dts | 3 +- boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts | 3 +- .../fvp_baser_aemv8r/fvp_baser_aemv8r.dts | 3 +- doc/build/dts/api/api.rst | 9 - doc/hardware/arch/arm_cortex_m.rst | 12 +- doc/releases/migration-guide-3.5.rst | 13 ++ doc/releases/release-notes-3.5.rst | 10 -- doc/services/index.rst | 1 + doc/services/mem_mgmt/index.rst | 90 ++++++++++ drivers/adc/adc_stm32.c | 25 +-- drivers/dma/dma_stm32_bdma.c | 3 +- drivers/spi/spi_ll_stm32.c | 3 +- dts/arm/nxp/nxp_lpc55S1x_common.dtsi | 3 +- dts/arm/nxp/nxp_lpc55S2x_common.dtsi | 3 +- dts/arm/nxp/nxp_lpc55S6x_common.dtsi | 3 +- dts/arm/nxp/nxp_rt5xx_common.dtsi | 3 +- dts/arm/nxp/nxp_rt6xx_common.dtsi | 3 +- dts/arm/st/f7/stm32f7.dtsi | 4 +- dts/arm/st/h7/stm32h7.dtsi | 4 +- dts/bindings/base/zephyr,memory-attr.yaml | 20 ++- .../arch/arm/cortex_m/arm_mpu_mem_cfg.h | 42 ----- include/zephyr/arch/arm/mpu/arm_mpu_v7m.h | 6 + include/zephyr/arch/arm/mpu/arm_mpu_v8.h | 13 ++ include/zephyr/arch/arm64/cortex_r/arm_mpu.h | 8 - include/zephyr/devicetree.h | 1 - include/zephyr/devicetree/memory-attr.h | 163 ------------------ .../dt-bindings/memory-attr/memory-attr-arm.h | 39 +++++ .../memory-attr/memory-attr-riscv.h | 37 ++++ .../memory-attr/memory-attr-xtensa.h | 31 ++++ .../dt-bindings/memory-attr/memory-attr.h | 48 ++++++ include/zephyr/mem_mgmt/mem_attr.h | 114 ++++++++++++ include/zephyr/multi_heap/shared_multi_heap.h | 2 +- .../openamp/boards/mimxrt1160_evk_cm7.overlay | 4 +- .../openamp/boards/mimxrt1170_evk_cm7.overlay | 4 +- .../boards/mimxrt1170_evkb_cm7.overlay | 4 +- .../remote/boards/mimxrt1160_evk_cm4.overlay | 2 +- .../remote/boards/mimxrt1170_evk_cm4.overlay | 2 +- .../remote/boards/mimxrt1170_evkb_cm4.overlay | 2 +- soc/arm/common/cortex_m/arm_mpu_regions.c | 4 - soc/arm/nxp_imx/rt/mpu_regions.c | 4 - soc/arm/nxp_s32/s32k/mpu_regions.c | 3 - soc/arm/st_stm32/stm32h7/mpu_regions.c | 3 - soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c | 4 - subsys/CMakeLists.txt | 1 + subsys/Kconfig | 1 + subsys/mem_mgmt/CMakeLists.txt | 3 + subsys/mem_mgmt/Kconfig | 12 ++ subsys/mem_mgmt/mem_attr.c | 61 +++++++ tests/arch/arm/arm_mpu_regions/CMakeLists.txt | 8 - .../arm_mpu_regions/boards/mps2_an385.overlay | 41 ----- tests/arch/arm/arm_mpu_regions/src/main.c | 53 ------ tests/arch/arm/arm_mpu_regions/testcase.yaml | 6 - .../adc/adc_dma/boards/nucleo_h743zi.overlay | 5 +- .../boards/nucleo_h743zi.overlay | 4 +- .../boards/nucleo_h743zi.overlay | 2 +- .../boards/mps2_an521.overlay | 9 +- .../boards/qemu_cortex_a53.overlay | 9 +- .../mem_heap/shared_multi_heap/src/main.c | 27 +-- tests/lib/devicetree/api/app.overlay | 12 -- tests/lib/devicetree/api/src/main.c | 64 ------- tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt | 8 + tests/subsys/mem_mgmt/mem_attr/app.overlay | 28 +++ .../mem_mgmt/mem_attr}/prj.conf | 1 + tests/subsys/mem_mgmt/mem_attr/src/main.c | 87 ++++++++++ tests/subsys/mem_mgmt/mem_attr/testcase.yaml | 8 + 72 files changed, 934 insertions(+), 515 deletions(-) create mode 100644 doc/services/mem_mgmt/index.rst delete mode 100644 include/zephyr/devicetree/memory-attr.h create mode 100644 include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h create mode 100644 include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h create mode 100644 include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h create mode 100644 include/zephyr/dt-bindings/memory-attr/memory-attr.h create mode 100644 include/zephyr/mem_mgmt/mem_attr.h create mode 100644 subsys/mem_mgmt/CMakeLists.txt create mode 100644 subsys/mem_mgmt/Kconfig create mode 100644 subsys/mem_mgmt/mem_attr.c delete mode 100644 tests/arch/arm/arm_mpu_regions/CMakeLists.txt delete mode 100644 tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay delete mode 100644 tests/arch/arm/arm_mpu_regions/src/main.c delete mode 100644 tests/arch/arm/arm_mpu_regions/testcase.yaml create mode 100644 tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt create mode 100644 tests/subsys/mem_mgmt/mem_attr/app.overlay rename tests/{arch/arm/arm_mpu_regions => subsys/mem_mgmt/mem_attr}/prj.conf (67%) create mode 100644 tests/subsys/mem_mgmt/mem_attr/src/main.c create mode 100644 tests/subsys/mem_mgmt/mem_attr/testcase.yaml diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index ac28ab6b609..6c95fe044b2 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -11,6 +11,8 @@ #include "arm_core_mpu_dev.h" #include #include +#include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include @@ -32,6 +34,13 @@ LOG_MODULE_DECLARE(mpu); #define NUM_MPU_REGIONS DT_PROP(MPU_NODEID, arm_num_mpu_regions) #endif +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + /* * Global status variable holding the number of HW MPU region indices, which * have been reserved by the MPU driver to program the static (fixed) memory @@ -74,6 +83,79 @@ static int region_allocate_and_init(const uint8_t index, return index; } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct arm_mpu_region) ARM_MPU_REGION_INIT((reg).dt_name, \ + (reg).dt_addr, \ + (reg).dt_size, \ + _ATTR) + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct arm_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_RAM_NOCACHE_ATTR + case DT_MEM_ARM_MPU_RAM_NOCACHE: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_NOCACHE_ATTR); + __ASSERT(!(region[idx].dt_attr & DT_MEM_CACHEABLE), + "RAM_NOCACHE with DT_MEM_CACHEABLE attribute\n"); + break; +#endif +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_PPB_ATTR + case DT_MEM_ARM_MPU_PPB: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_PPB_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif +#ifdef REGION_EXTMEM_ATTR + case DT_MEM_ARM_MPU_EXTMEM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_EXTMEM_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } +#if defined(CONFIG_ARMV7_R) + region_conf.size = size_to_mpu_rasr_size(region[idx].dt_size); +#endif + + if (region_allocate_and_init((*reg_index), + (const struct arm_mpu_region *) ®ion_conf) < 0) { + return -EINVAL; + } + + (*reg_index)++; + } + + return 0; +} + /* This internal function programs an MPU region * of a given configuration at a given MPU index. */ @@ -375,6 +457,11 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return -EINVAL; + } arm_core_mpu_enable(); diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index eeed6383d83..71b55ae7c11 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -13,11 +13,20 @@ #include #include #include +#include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include LOG_MODULE_DECLARE(mpu); +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + /* * Global status variable holding the number of HW MPU region indices, which * have been reserved by the MPU driver to program the static (fixed) memory @@ -134,6 +143,60 @@ static int region_allocate_and_init(const uint8_t index, return index; } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct nxp_mpu_region) { .name = (reg).dt_name, \ + .base = (reg).dt_addr, \ + .end = (reg).dt_addr + (reg).dt_size, \ + .attr = _ATTR, \ + } + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct nxp_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } + + if (region_allocate_and_init((*reg_index), + (const struct nxp_mpu_region *) ®ion_conf) < 0) { + return -EINVAL; + } + + (*reg_index)++; + } + + return 0; +} + /** * This internal function is utilized by the MPU driver to combine a given * region attribute configuration and size and fill-in a driver-specific @@ -636,6 +699,11 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return -EINVAL; + } arm_core_mpu_enable(); diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 2ecdb525715..7ee56c52ea4 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -15,9 +15,18 @@ #include #include #include +#include +#include LOG_MODULE_REGISTER(mpu, CONFIG_MPU_LOG_LEVEL); +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + #define MPU_DYNAMIC_REGION_AREAS_NUM 1 #ifdef CONFIG_USERSPACE @@ -167,6 +176,64 @@ static ALWAYS_INLINE void region_init(const uint32_t index, mpu_set_region(index, rbar, rlar); } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct arm_mpu_region) { .name = (reg).dt_name, \ + .base = (reg).dt_addr, \ + .limit = (reg).dt_addr + (reg).dt_size, \ + .attr = _ATTR, \ + } + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct arm_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_RAM_NOCACHE_ATTR + case DT_MEM_ARM_MPU_RAM_NOCACHE: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_NOCACHE_ATTR); + __ASSERT(!(region[idx].dt_attr & DT_MEM_CACHEABLE), + "RAM_NOCACHE with DT_MEM_CACHEABLE attribute\n"); + break; +#endif +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } + + region_init((*reg_index), (const struct arm_mpu_region *) ®ion_conf); + + (*reg_index)++; + } + + return 0; +} + /* * @brief MPU default configuration * @@ -222,6 +289,12 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return; + } + arm_core_mpu_enable(); if (!is_primary_core) { diff --git a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts index 24e26e68fbe..ef3544ef958 100644 --- a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts +++ b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_giga_r1.dtsi" / { @@ -29,7 +30,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(8)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts index f28c5857cbe..e81172d381b 100644 --- a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts @@ -9,6 +9,8 @@ #include #include "arduino_r3_connector.dtsi" #include +#include +#include / { model = "STMicroelectronics STM32F746G DISCOVERY board"; @@ -51,7 +53,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f7508_dk/stm32f7508_dk.dts b/boards/arm/stm32f7508_dk/stm32f7508_dk.dts index 3969add4e28..8102e002863 100644 --- a/boards/arm/stm32f7508_dk/stm32f7508_dk.dts +++ b/boards/arm/stm32f7508_dk/stm32f7508_dk.dts @@ -8,6 +8,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -52,7 +53,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts index fcd2197aa9d..0548cf06bd8 100644 --- a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts +++ b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -28,7 +29,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; leds { diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts index 918c61b9978..8f6f519186d 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "stm32h747i_disco.dtsi" / { @@ -27,7 +28,7 @@ device_type = "memory"; reg = <0xd0000000 DT_SIZE_M(32)>; zephyr,memory-region = "SDRAM2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; leds { diff --git a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts index 4183c4912bd..e9acb61b820 100644 --- a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -54,7 +55,7 @@ device_type = "memory"; reg = <0xd0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; transceiver0: can-phy0 { diff --git a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts index eb49a3e3856..727e7b5d7a2 100644 --- a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts +++ b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "FVP BaseR AEMv8R"; @@ -41,7 +42,7 @@ compatible = "zephyr,memory-region", "mmio-dram"; reg = <0x9a000000 0x66000000>; zephyr,memory-region = "DEVICE_REGION"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; }; diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index f3a8c2bcb0d..7d802838041 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -294,15 +294,6 @@ and properties related to them. .. doxygengroup:: devicetree-mbox -.. _devicetree-memory-attr-api: - -Memory attributes -================= - -These conveniences may be used for nodes with a memory attribute property. - -.. doxygengroup:: devicetree-memory-attr - .. _devicetree-pinctrl-api: Pinctrl (pin control) diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 48e517259ed..b037896776f 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -457,10 +457,6 @@ region will be allocated and programmed during system boot. When used with the :dtcompatible:`zephyr,memory-region` devicetree compatible, it will result in a linker section being generated associated to that MPU region. -The property ``zephyr,memory-attr`` is a string carrying the attributes -for the MPU region. It is converted to a C token for use defining the attributes -of the MPU region. - For example, to define a new non-cacheable memory region in devicetree: .. code-block:: devicetree @@ -469,13 +465,11 @@ For example, to define a new non-cacheable memory region in devicetree: compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x20300000 0x100000>; zephyr,memory-region = "SRAM_NO_CACHE"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; -This will automatically create a new MPU entry in -:zephyr_file:`soc/arm/common/cortex_m/arm_mpu_regions.c` with the correct name, base, -size and attributes gathered directly from the devicetree. See -:zephyr_file:`include/zephyr/linker/devicetree_regions.h` for more details. +This will automatically create a new MPU entry in with the correct name, base, +size and attributes gathered directly from the devicetree. Static MPU regions ------------------ diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index f3ae1852082..767c5378be1 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -34,6 +34,19 @@ Required changes SMP version 2 error code defines for in-tree modules have been updated to replace the ``*_RET_RC_*`` parts with ``*_ERR_*``. +* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` and its type + moved from 'enum' to 'int'. To have a seamless conversion this is the + required change in the DT: + + .. code-block:: none + + - "RAM" -> <( DT_MEM_ARM(ATTR_MPU_RAM) )> + - "RAM_NOCACHE" -> <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )> + - "FLASH" -> <( DT_MEM_ARM(ATTR_MPU_FLASH) )> + - "PPB" -> <( DT_MEM_ARM(ATTR_MPU_PPB) )> + - "IO" -> <( DT_MEM_ARM(ATTR_MPU_IO) )> + - "EXTMEM" -> <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )> + Recommended Changes ******************* diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7b090e2c0fd..00e23f6d30b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -284,16 +284,6 @@ USB Devicetree ********** -* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` - -* The following macros were added: - :c:macro:`DT_FOREACH_NODE_VARGS`, - :c:macro:`DT_FOREACH_STATUS_OKAY_NODE_VARGS` - :c:macro:`DT_MEMORY_ATTR_FOREACH_NODE` - :c:macro:`DT_MEMORY_ATTR_APPLY` - :c:macro:`DT_MEM_FROM_FIXED_PARTITION` - :c:macro:`DT_FIXED_PARTITION_ADDR` - Libraries / Subsystems ********************** diff --git a/doc/services/index.rst b/doc/services/index.rst index 6ba8af68a67..990f0cfea49 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -18,6 +18,7 @@ OS Services logging/index.rst tracing/index.rst resource_management/index.rst + mem_mgmt/index.rst modbus/index.rst notify.rst pm/index.rst diff --git a/doc/services/mem_mgmt/index.rst b/doc/services/mem_mgmt/index.rst new file mode 100644 index 00000000000..eb689c409d1 --- /dev/null +++ b/doc/services/mem_mgmt/index.rst @@ -0,0 +1,90 @@ +.. _mem_mgmt_api: + +Memory Attributes +################# + +It is possible in the devicetree to mark the memory regions with attributes by +using the ``zephyr,memory-attr`` property. This property and the related memory +region can then be retrieved at run-time by leveraging a provided helper +library. + +The set of general attributes that can be specified in the property are defined +and explained in :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr.h`. + +For example, to mark a memory region in the devicetree as non-volatile, cacheable, +out-of-order: + +.. code-block:: devicetree + + mem: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x10000000 0x1000>; + zephyr,memory-attr = <( DT_MEM_NON_VOLATILE | DT_MEM_CACHEABLE | DT_MEM_OOO )>; + }; + +.. note:: + + The ``zephyr,memory-attr`` usage does not result in any memory region + actually created. When it is needed to create an actual section out of the + devicetree defined memory region, it is possible to use the compatible + :dtcompatible:`zephyr,memory-region` that will result (only when supported + by the architecture) in a new linker section and region. + +The ``zephyr,memory-attr`` property can also be used to set +architecture-specific and software-specific custom attributes that can be +interpreted at run time. This is leveraged, among other things, to create MPU +regions out of devicetree defined memory regions, for example: + +.. code-block:: devicetree + + mem: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x10000000 0x1000>; + zephyr,memory-region = "NOCACHE_REGION"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + }; + +See :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` and +:ref:`arm_cortex_m_developer_guide` for more details about MPU usage. + +The conventional and recommended way to deal and manage with memory regions +marked with attributes is by using the provided ``mem-attr`` helper library by +enabling :kconfig:option:`CONFIG_MEM_ATTR`. When this option is enabled the +list of memory regions and their attributes are compiled in a user-accessible +array and a set of functions is made available that can be used to query, probe +and act on regions and attributes (see next section for more details). + +.. note:: + + The ``zephyr,memory-attr`` property is only a descriptive property of the + capabilities of the associated memory region, but it does not result in any + actual setting for the memory to be set. The user, code or subsystem willing + to use this information to do some work (for example creating an MPU region + out of the property) must use either the provided ``mem-attr`` library or + the usual devicetree helpers to perform the required work / setting. + +A test for the ``mem-attr`` library and its usage is provided in +``tests/subsys/mem_mgmt/mem_attr/``. + +Migration guide from `zephyr,memory-region-mpu` +*********************************************** + +When the ``zephyr,memory-attr`` property was introduced, the +``zephyr,memory-region-mpu`` property was removed and deprecated. + +The developers that are still using the deprecated property can move to the new +one by renaming the property and changing its value according to the following list: + +.. code-block:: none + + "RAM" -> <( DT_ARM_MPU(ATTR_MPU_RAM) )> + "RAM_NOCACHE" -> <( DT_ARM_MPU(ATTR_MPU_RAM_NOCACHE) )> + "FLASH" -> <( DT_ARM_MPU(ATTR_MPU_FLASH) )> + "PPB" -> <( DT_ARM_MPU(ATTR_MPU_PPB) )> + "IO" -> <( DT_ARM_MPU(ATTR_MPU_IO) )> + "EXTMEM" -> <( DT_ARM_MPU(ATTR_MPU_EXTMEM) )> + +API Reference +************* + +.. doxygengroup:: memory_attr_interface diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index ad8fcdcb1fd..28a1df08ba6 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -42,6 +42,8 @@ LOG_MODULE_REGISTER(adc_stm32); #include #include #include +#include +#include #if defined(CONFIG_SOC_SERIES_STM32F3X) #if defined(ADC1_V2_5) @@ -253,27 +255,16 @@ static int adc_stm32_dma_start(const struct device *dev, * The entire buffer must be in a single region. * An example of how the SRAM region can be defined in the DTS: * &sram4 { - * zephyr,memory-attr = "RAM_NOCACHE"; + * zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) | ... )>; * }; */ static bool address_in_non_cacheable_sram(const uint16_t *buffer, const uint16_t size) { - /* Default if no valid SRAM region found or buffer+size not located in a single region */ - bool cachable = false; -#define IS_NON_CACHEABLE_REGION_FN(node_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_attr), ({ \ - const uint32_t region_start = DT_REG_ADDR(node_id); \ - const uint32_t region_end = region_start + DT_REG_SIZE(node_id); \ - if (((uint32_t)buffer >= region_start) && \ - (((uint32_t)buffer + size) < region_end)) { \ - cachable = strcmp(DT_PROP(node_id, zephyr_memory_attr), \ - "RAM_NOCACHE") == 0; \ - } \ - }), \ - (EMPTY)) - DT_FOREACH_STATUS_OKAY(mmio_sram, IS_NON_CACHEABLE_REGION_FN); - - return cachable; + if (mem_attr_check_buf((void *) buffer, (size_t) size, DT_MEM_ARM_MPU_RAM_NOCACHE) == 0) { + return true; + } + + return false; } #endif /* defined(CONFIG_ADC_STM32_DMA) && defined(CONFIG_SOC_SERIES_STM32H7X) */ diff --git a/drivers/dma/dma_stm32_bdma.c b/drivers/dma/dma_stm32_bdma.c index 797ed9ed794..1df5746facb 100644 --- a/drivers/dma/dma_stm32_bdma.c +++ b/drivers/dma/dma_stm32_bdma.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -813,7 +814,7 @@ static int bdma_stm32_init(const struct device *dev) * }; */ #if DT_NODE_HAS_PROP(DT_NODELABEL(sram4), zephyr_memory_attr) - if (strcmp(DT_PROP(DT_NODELABEL(sram4), zephyr_memory_attr), "RAM_NOCACHE") != 0) { + if ((DT_PROP(DT_NODELABEL(sram4), zephyr_memory_attr) & DT_MEM_ARM_MPU_RAM_NOCACHE) == 0) { LOG_ERR("SRAM4 is not set as non-cachable."); return -EIO; } diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 948b7641eaf..d4ad84fae77 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #include #include #include +#include #ifdef CONFIG_NOCACHE_MEMORY #include @@ -81,7 +82,7 @@ struct mem_region { }; static const struct mem_region nocache_mem_regions[] = { - DT_MEMORY_ATTR_FOREACH_NODE(GET_MEM_REGION_IF_NOCACHE) + DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(GET_MEM_REGION_IF_NOCACHE) }; #endif /* CONFIG_SOC_SERIES_STM32H7X */ diff --git a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi index bbd71e2afa1..c6b21b7495f 100644 --- a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -61,7 +62,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x20010000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi index 1e9222f5d07..c429a4bd4ef 100644 --- a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include / { @@ -75,7 +76,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40100000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi index 23db8a86641..c7c7d238dc7 100644 --- a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -95,7 +96,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x100000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; syscon: syscon@0 { diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 5b24777f0c5..fa7936db9c2 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include / { chosen { @@ -78,7 +79,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40140000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index 59897efe2a5..5b8748c566f 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { chosen { @@ -62,7 +63,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40140000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index a92e5138ce1..addab096c9c 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include / { @@ -47,7 +49,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x90000000 DT_SIZE_M(256)>; zephyr,memory-region = "QSPI"; - zephyr,memory-attr = "EXTMEM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; }; clocks { diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index c9f72afb784..ac0aefdb6f3 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include / { @@ -48,7 +50,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x90000000 DT_SIZE_M(256)>; zephyr,memory-region = "QSPI"; - zephyr,memory-attr = "EXTMEM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; }; clocks { diff --git a/dts/bindings/base/zephyr,memory-attr.yaml b/dts/bindings/base/zephyr,memory-attr.yaml index e3c19b9b288..1a5611b5258 100644 --- a/dts/bindings/base/zephyr,memory-attr.yaml +++ b/dts/bindings/base/zephyr,memory-attr.yaml @@ -4,17 +4,19 @@ include: [base.yaml] properties: - zephyr,memory-attr: + zephyr,memory-region-mpu: type: string - enum: - - "RAM" - - "RAM_NOCACHE" - - "FLASH" - - "PPB" - - "IO" - - "EXTMEM" + deprecated: true + description: | + Signify that this node should result in a dedicated MPU region. + Deprecated in favor of 'zephyr,memory-attr'. + + zephyr,memory-attr: + type: int description: | - Attribute for the memory region. + Attribute or set of attributes (bitmask) for the memory region. See + 'include/zephyr/dt-bindings/memory-attr/memory-attr.h' for a + comprehensive list with description of possible values. reg: required: true diff --git a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h index 4f1132af6b0..7f0d3e3ef66 100644 --- a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h +++ b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h @@ -72,48 +72,6 @@ #error "Unsupported sram size configuration" #endif -#define MPU_REGION_SIZE_32 REGION_32B -#define MPU_REGION_SIZE_64 REGION_64B -#define MPU_REGION_SIZE_128 REGION_128B -#define MPU_REGION_SIZE_256 REGION_256B -#define MPU_REGION_SIZE_512 REGION_512B -#define MPU_REGION_SIZE_1024 REGION_1K -#define MPU_REGION_SIZE_2048 REGION_2K -#define MPU_REGION_SIZE_4096 REGION_4K -#define MPU_REGION_SIZE_8192 REGION_8K -#define MPU_REGION_SIZE_16384 REGION_16K -#define MPU_REGION_SIZE_32768 REGION_32K -#define MPU_REGION_SIZE_65536 REGION_64K -#define MPU_REGION_SIZE_131072 REGION_128K -#define MPU_REGION_SIZE_262144 REGION_256K -#define MPU_REGION_SIZE_524288 REGION_512K -#define MPU_REGION_SIZE_1048576 REGION_1M -#define MPU_REGION_SIZE_2097152 REGION_2M -#define MPU_REGION_SIZE_4194304 REGION_4M -#define MPU_REGION_SIZE_8388608 REGION_8M -#define MPU_REGION_SIZE_16777216 REGION_16M -#define MPU_REGION_SIZE_33554432 REGION_32M -#define MPU_REGION_SIZE_67108864 REGION_64M -#define MPU_REGION_SIZE_134217728 REGION_128M -#define MPU_REGION_SIZE_268435456 REGION_256M -#define MPU_REGION_SIZE_536870912 REGION_512M - -#define MPU_REGION_SIZE(x) MPU_REGION_SIZE_ ## x - -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(MPU_REGION_SIZE(p_size)), \ - } - -#else - -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(p_base, p_size), \ - } - #endif /* !ARMV8_M_BASELINE && !ARMV8_M_MAINLINE */ #endif /* _ARM_CORTEX_M_MPU_MEM_CFG_H_ */ diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h index a3b61844368..1ed8636ec50 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h @@ -109,6 +109,12 @@ #define REGION_2G REGION_SIZE(2GB) #define REGION_4G REGION_SIZE(4GB) +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(size_to_mpu_rasr_size(p_size)), \ + } + /* Some helper defines for common regions */ /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h index ee8f2e8ac07..cf60cca99da 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h @@ -188,6 +188,13 @@ * that they do not overlap with other MPU regions). */ #if defined(CONFIG_AARCH32_ARMV8_R) + +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base + p_size), \ + } + #define REGION_RAM_ATTR(limit) \ { \ .rbar = NOT_EXEC | \ @@ -246,6 +253,12 @@ } #else +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base, p_size), \ + } + /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep * the SRAM region XN bit clear or the application code will not be executable. diff --git a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h index d208f2566a1..74426005fb7 100644 --- a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h +++ b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h @@ -227,14 +227,6 @@ struct arm_mpu_config { .attr = _attr, \ } -#define MPU_REGION_ENTRY_FROM_DTS(_name, _base, _size, _attr) \ - { \ - .name = _name, \ - .base = _base, \ - .limit = _base + _size, \ - .attr = _attr, \ - } - #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 00cef4fb8aa..c249ad371e2 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -4315,6 +4315,5 @@ #include #include #include -#include #endif /* DEVICETREE_H */ diff --git a/include/zephyr/devicetree/memory-attr.h b/include/zephyr/devicetree/memory-attr.h deleted file mode 100644 index 65fcfe0ca50..00000000000 --- a/include/zephyr/devicetree/memory-attr.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2023 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_MEMORY_ATTR_H_ -#define ZEPHYR_INCLUDE_MEMORY_ATTR_H_ - -#include -#include -#include - -/** - * @file - * @brief Memory-attr helpers - */ - -/** - * @defgroup devicetree-memory-attr Memory attributes - * @ingroup devicetree - * @{ - */ - -/** @cond INTERNAL_HIDDEN */ - -#define _DT_MEM_ATTR zephyr_memory_attr -#define _DT_ATTR(token) UTIL_CAT(UTIL_CAT(REGION_, token), _ATTR) - -#define _UNPACK(node_id, fn) \ - fn(COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_region), \ - (LINKER_DT_NODE_REGION_NAME(node_id)), \ - (DT_NODE_FULL_NAME(node_id))), \ - DT_REG_ADDR(node_id), \ - DT_REG_SIZE(node_id), \ - _DT_ATTR(DT_STRING_TOKEN(node_id, _DT_MEM_ATTR))), - -#define _APPLY(node_id, fn) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, _DT_MEM_ATTR), \ - (_UNPACK(node_id, fn)), \ - ()) - - -#define _FILTER(node_id, fn) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, _DT_MEM_ATTR), \ - (fn(node_id)), \ - ()) - -/** @endcond */ - -/** - * @brief Invokes @p fn for every node in the tree with property - * `zephyr,memory-attr` - * - * The macro @p fn must take one parameter, which will be a node identifier - * with the `zephyr,memory-attr` property. The macro is expanded once for each - * node in the tree. The order that nodes are visited in is not specified. - * - * @param fn macro to invoke - */ -#define DT_MEMORY_ATTR_FOREACH_NODE(fn) \ - DT_FOREACH_STATUS_OKAY_NODE_VARGS(_FILTER, fn) - -/** - * @brief Invokes @p fn for MPU/MMU regions generation from the device tree - * nodes with `zephyr,memory-attr` property. - * - * Helper macro to invoke a @p fn macro on all the memory regions declared - * using the `zephyr,memory-attr` property - * - * The macro @p fn must take the form: - * - * @code{.c} - * #define MPU_FN(name, base, size, attr) ... - * @endcode - * - * The @p name, @p base and @p size parameters are retrieved from the DT node. - * When the `zephyr,memory-region` property is present in the node, the @p name - * parameter is retrived from there, otherwise the full node name is used. - * - * The `zephyr,memory-attr` enum property is passed as an extended token - * to the @p fn macro using the @p attr parameter in the form of a macro - * REGION_{attr}_ATTR. - * - * The following enums are supported for the `zephyr,memory-attr` property (see - * `zephyr,memory-attr.yaml` for a complete list): - * - * - RAM - * - RAM_NOCACHE - * - FLASH - * - PPB - * - IO - * - EXTMEM - * - * This means that usually the user code would provide some macros or defines - * with the same name of the extended property, that is: - * - * - REGION_RAM_ATTR - * - REGION_RAM_NOCACHE_ATTR - * - REGION_FLASH_ATTR - * - REGION_PPB_ATTR - * - REGION_IO_ATTR - * - REGION_EXTMEM_ATTR - * - * Example devicetree fragment: - * - * @code{.dts} - * / { - * soc { - * res0: memory@20000000 { - * reg = <0x20000000 0x4000>; - * zephyr,memory-region = "MY_NAME"; - * zephyr,memory-attr = "RAM_NOCACHE"; - * }; - * - * res1: memory@30000000 { - * reg = <0x30000000 0x2000>; - * zephyr,memory-attr = "RAM"; - * }; - - * }; - * }; - * @endcode - * - * Example usage: - * - * @code{.c} - * #define REGION_RAM_NOCACHE_ATTR 0xAAAA - * #define REGION_RAM_ATTR 0xBBBB - * #define REGION_FLASH_ATTR 0xCCCC - * - * #define MPU_FN(p_name, p_base, p_size, p_attr) \ - * { \ - * .name = p_name, \ - * .base = p_base, \ - * .size = p_size, \ - * .attr = p_attr, \ - * } - * - * static const struct arm_mpu_region mpu_regions[] = { - * DT_MEMORY_ATTR_APPLY(MPU_FN) - * }; - * @endcode - * - * This expands to: - * - * @code{.c} - * static const struct arm_mpu_region mpu_regions[] = { - * { "MY_NAME", 0x20000000, 0x4000, 0xAAAA }, - * { "memory@30000000", 0x30000000, 0x2000, 0xBBBB }, - * }; - * @endcode - * - * @param fn macro to invoke - */ -#define DT_MEMORY_ATTR_APPLY(fn) \ - DT_FOREACH_STATUS_OKAY_NODE_VARGS(_APPLY, fn) - -/** - * @} - */ - -#endif /* ZEPHYR_INCLUDE_MEMORY_ATTR_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h new file mode 100644 index 00000000000..5ffe1f3a3a8 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ + +#include +#include + +/* + * Architecture specific ARM MPU related attributes. + * + * This list is to seamlessy support the MPU regions configuration using DT and + * the `zephyr,memory-attr` property. + * + * This is legacy and it should NOT be extended further. If new MPU region + * types must be added, these must rely on the generic memory attributes. + */ +#define DT_MEM_ARM_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_ARM(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_MPU_RAM BIT(0) +#define ATTR_MPU_RAM_NOCACHE BIT(1) +#define ATTR_MPU_FLASH BIT(2) +#define ATTR_MPU_PPB BIT(3) +#define ATTR_MPU_IO BIT(4) +#define ATTR_MPU_EXTMEM BIT(5) + +#define DT_MEM_ARM_MPU_RAM DT_MEM_ARM(ATTR_MPU_RAM) +#define DT_MEM_ARM_MPU_RAM_NOCACHE DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) +#define DT_MEM_ARM_MPU_FLASH DT_MEM_ARM(ATTR_MPU_FLASH) +#define DT_MEM_ARM_MPU_PPB DT_MEM_ARM(ATTR_MPU_PPB) +#define DT_MEM_ARM_MPU_IO DT_MEM_ARM(ATTR_MPU_IO) +#define DT_MEM_ARM_MPU_EXTMEM DT_MEM_ARM(ATTR_MPU_EXTMEM) +#define DT_MEM_ARM_MPU_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h new file mode 100644 index 00000000000..c51cd010ef1 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ + +#include +#include + +/* + * Architecture specific RISCV related attributes. + */ +#define DT_MEM_RISCV_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_RISCV(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_RISCV_TYPE_MAIN BIT(0) +#define ATTR_RISCV_TYPE_IO BIT(1) +#define ATTR_RISCV_TYPE_EMPTY BIT(2) +#define ATTR_RISCV_AMO_SWAP BIT(3) +#define ATTR_RISCV_AMO_LOGICAL BIT(4) +#define ATTR_RISCV_AMO_ARITHMETIC BIT(5) +#define ATTR_RISCV_IO_IDEMPOTENT_READ BIT(6) +#define ATTR_RISCV_IO_IDEMPOTENT_WRITE BIT(7) + +#define DT_MEM_RISCV_TYPE_MAIN DT_MEM_RISCV(ATTR_RISCV_TYPE_MAIN) +#define DT_MEM_RISCV_TYPE_IO DT_MEM_RISCV(ATTR_RISCV_TYPE_IO) +#define DT_MEM_RISCV_TYPE_EMPTY DT_MEM_RISCV(ATTR_RISCV_TYPE_EMPTY) +#define DT_MEM_RISCV_AMO_SWAP DT_MEM_RISCV(ATTR_RISCV_AMO_SWAP) +#define DT_MEM_RISCV_AMO_LOGICAL DT_MEM_RISCV(ATTR_RISCV_AMO_LOGICAL) +#define DT_MEM_RISCV_AMO_ARITHMETIC DT_MEM_RISCV(ATTR_RISCV_AMO_ARITHMETIC) +#define DT_MEM_RISCV_IO_IDEMPOTENT_READ DT_MEM_RISCV(ATTR_RISCV_IO_IDEMPOTENT_READ) +#define DT_MEM_RISCV_IO_IDEMPOTENT_WRITE DT_MEM_RISCV(ATTR_RISCV_IO_IDEMPOTENT_WRITE) +#define DT_MEM_RISCV_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h new file mode 100644 index 00000000000..c845b071a6b --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ + +#include +#include + +/* + * Architecture specific Xtensa related attributes. + */ +#define DT_MEM_XTENSA_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_XTENSA(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_XTENSA_INSTR_ROM BIT(0) +#define ATTR_XTENSA_INSTR_RAM BIT(1) +#define ATTR_XTENSA_DATA_ROM BIT(2) +#define ATTR_XTENSA_DATA_RAM BIT(3) +#define ATTR_XTENSA_XLMI BIT(4) + +#define DT_MEM_XTENSA_INSTR_ROM DT_MEM_XTENSA(ATTR_XTENSA_INSTR_ROM) +#define DT_MEM_XTENSA_INSTR_RAM DT_MEM_XTENSA(ATTR_XTENSA_INSTR_RAM) +#define DT_MEM_XTENSA_DATA_ROM DT_MEM_XTENSA(ATTR_XTENSA_DATA_ROM) +#define DT_MEM_XTENSA_DATA_RAM DT_MEM_XTENSA(ATTR_XTENSA_DATA_RAM) +#define DT_MEM_XTENSA_XLMI DT_MEM_XTENSA(ATTR_XTENSA_XLMI) +#define DT_MEM_XTENSA_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr.h b/include/zephyr/dt-bindings/memory-attr/memory-attr.h new file mode 100644 index 00000000000..ea4ac04cafe --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ + +#include + +/* + * Generic memory attributes. + * + * Generic memory attributes that should be common to all architectures. + */ +#define DT_MEM_ATTR_MASK GENMASK(15, 0) +#define DT_MEM_ATTR_SHIFT (0) + +#define DT_MEM_CACHEABLE BIT(0) /* cacheable */ +#define DT_MEM_NON_VOLATILE BIT(1) /* non-volatile */ +#define DT_MEM_OOO BIT(2) /* out-of-order */ +#define DT_MEM_DMA BIT(3) /* DMA-able */ +#define DT_MEM_UNKNOWN BIT(15) /* must be last */ +/* to be continued */ + +/* + * Software specific memory attributes. + * + * Software can define their own memory attributes if needed using the + * provided mask. + */ +#define DT_MEM_SW_ATTR_MASK GENMASK(19, 16) +#define DT_MEM_SW_ATTR_SHIFT (16) +#define DT_MEM_SW_ATTR_UNKNOWN BIT(19) + +/* + * Architecture specific memory attributes. + * + * Architectures can define their own memory attributes if needed using the + * provided mask. + * + * See for example `include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` + */ +#define DT_MEM_ARCH_ATTR_MASK GENMASK(31, 20) +#define DT_MEM_ARCH_ATTR_SHIFT (20) +#define DT_MEM_ARCH_ATTR_UNKNOWN BIT(31) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ */ diff --git a/include/zephyr/mem_mgmt/mem_attr.h b/include/zephyr/mem_mgmt/mem_attr.h new file mode 100644 index 00000000000..a8da629c3e3 --- /dev/null +++ b/include/zephyr/mem_mgmt/mem_attr.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_MEM_ATTR_H_ +#define ZEPHYR_INCLUDE_MEM_ATTR_H_ + +/** + * @brief Memory-Attr Interface + * @defgroup memory_attr_interface Memory-Attr Interface + * @ingroup mem_mgmt + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +#define __MEM_ATTR zephyr_memory_attr + +#define _FILTER(node_id, fn) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, __MEM_ATTR), \ + (fn(node_id)), \ + ()) + +/** @endcond */ + +/** + * @brief Invokes @p fn for every status `okay` node in the tree with property + * `zephyr,memory-attr` + * + * The macro @p fn must take one parameter, which will be a node identifier + * with the `zephyr,memory-attr` property. The macro is expanded once for each + * node in the tree with status `okay`. The order that nodes are visited in is + * not specified. + * + * @param fn macro to invoke + */ +#define DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(fn) \ + DT_FOREACH_STATUS_OKAY_NODE_VARGS(_FILTER, fn) + +/** + * @brief memory-attr region structure. + * + * This structure represents the data gathered from DT about a memory-region + * marked with memory attributes. + */ +struct mem_attr_region_t { + /** Memory node full name */ + const char *dt_name; + /** Memory region physical address */ + uintptr_t dt_addr; + /** Memory region size */ + size_t dt_size; + /** Memory region attributes */ + uint32_t dt_attr; +}; + +/** + * @brief Get the list of memory regions. + * + * Get the list of enabled memory regions with their memory-attribute as + * gathered by DT. + * + * @param region Pointer to pointer to the list of memory regions. + * + * @retval Number of memory regions returned in the parameter. + */ +size_t mem_attr_get_regions(const struct mem_attr_region_t **region); + +/** + * @brief Check if a buffer has correct size and attributes. + * + * This function is used to check if a given buffer with a given set of + * attributes fully match a memory region in terms of size and attributes. + * + * This is usually used to verify that a buffer has the expected attributes + * (for example the buffer is cacheable / non-cacheable or belongs to RAM / + * FLASH, etc...) and it has been correctly allocated. + * + * The expected set of attributes for the buffer is and-matched against the + * full set of attributes for the memory region it belongs to (bitmask). So the + * buffer is considered matching when at least that set of attributes are valid + * for the memory region (but the region can be marked also with other + * attributes besides the one passed as parameter). + * + * @param addr Virtual address of the user buffer. + * @param size Size of the user buffer. + * @param attr Expected / desired attribute for the buffer. + * + * @retval 0 if the buffer has the correct size and attribute. + * @retval -ENOSYS if the operation is not supported (for example if the MMU is enabled). + * @retval -ENOTSUP if the wrong parameters were passed. + * @retval -EINVAL if the buffer has the wrong set of attributes. + * @retval -ENOSPC if the buffer is too big for the region it belongs to. + * @retval -ENOBUFS if the buffer is entirely allocated outside a memory region. + */ +int mem_attr_check_buf(void *addr, size_t size, uint32_t attr); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_MEM_ATTR_H_ */ diff --git a/include/zephyr/multi_heap/shared_multi_heap.h b/include/zephyr/multi_heap/shared_multi_heap.h index 0d5e66bf293..a9cdf120fae 100644 --- a/include/zephyr/multi_heap/shared_multi_heap.h +++ b/include/zephyr/multi_heap/shared_multi_heap.h @@ -88,7 +88,7 @@ enum shared_multi_heap_attr { */ struct shared_multi_heap_region { /** Memory heap attribute */ - unsigned int attr; + uint32_t attr; /** Memory heap starting virtual address */ uintptr_t addr; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay index 52c68fd5339..7facea692cb 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay index 52c68fd5339..7facea692cb 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay index a5d921810bb..584538a14f7 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay index fa4d29c3cd1..32d5003bb19 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay index fa4d29c3cd1..32d5003bb19 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay index f4ee15de7ed..72510d26166 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index 7eb3eb24f1d..6af62f84078 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -6,7 +6,6 @@ #include #include -#include #include @@ -29,9 +28,6 @@ static const struct arm_mpu_region mpu_regions[] = { #else REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/nxp_imx/rt/mpu_regions.c b/soc/arm/nxp_imx/rt/mpu_regions.c index dae25354155..51ce490eff1 100644 --- a/soc/arm/nxp_imx/rt/mpu_regions.c +++ b/soc/arm/nxp_imx/rt/mpu_regions.c @@ -7,7 +7,6 @@ #define SDRAM_BASE_ADDR 0x80000000 #include -#include #include static const struct arm_mpu_region mpu_regions[] = { @@ -28,9 +27,6 @@ static const struct arm_mpu_region mpu_regions[] = { */ MPU_REGION_ENTRY("SDRAM0", SDRAM_BASE_ADDR, REGION_IO_ATTR(REGION_512M)), #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/nxp_s32/s32k/mpu_regions.c b/soc/arm/nxp_s32/s32k/mpu_regions.c index 48078bde6bf..acd3ee9d916 100644 --- a/soc/arm/nxp_s32/s32k/mpu_regions.c +++ b/soc/arm/nxp_s32/s32k/mpu_regions.c @@ -35,9 +35,6 @@ static struct arm_mpu_region mpu_regions[] = { .attr = {(uint32_t)_rom_attr}, }, #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/st_stm32/stm32h7/mpu_regions.c b/soc/arm/st_stm32/stm32h7/mpu_regions.c index 01daccdd01d..29825ad226a 100644 --- a/soc/arm/st_stm32/stm32h7/mpu_regions.c +++ b/soc/arm/st_stm32/stm32h7/mpu_regions.c @@ -38,9 +38,6 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_PPB_ATTR(REGION_256B)), #endif #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c b/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c index 65400c67269..a36f53d4193 100644 --- a/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c +++ b/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c @@ -7,7 +7,6 @@ #include #include -#include #include static const struct arm_mpu_region mpu_regions[] = { @@ -39,9 +38,6 @@ static const struct arm_mpu_region mpu_regions[] = { #endif (uintptr_t)__kernel_ram_end, REGION_RAM_ATTR), - - /* Extra regions defined in device tree */ - DT_MEMORY_ATTR_APPLY(MPU_REGION_ENTRY_FROM_DTS) }; const struct arm_mpu_config mpu_config = { diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index e4f155ef0e2..f72add5d914 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(fb) add_subdirectory(fs) add_subdirectory(ipc) add_subdirectory(logging) +add_subdirectory(mem_mgmt) add_subdirectory(mgmt) add_subdirectory(modbus) add_subdirectory(pm) diff --git a/subsys/Kconfig b/subsys/Kconfig index 322ce245729..7121dc586fe 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -22,6 +22,7 @@ source "subsys/ipc/Kconfig" source "subsys/jwt/Kconfig" source "subsys/logging/Kconfig" source "subsys/lorawan/Kconfig" +source "subsys/mem_mgmt/Kconfig" source "subsys/mgmt/Kconfig" source "subsys/modbus/Kconfig" source "subsys/modem/Kconfig" diff --git a/subsys/mem_mgmt/CMakeLists.txt b/subsys/mem_mgmt/CMakeLists.txt new file mode 100644 index 00000000000..62e61fb4d1f --- /dev/null +++ b/subsys/mem_mgmt/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_MEM_ATTR mem_attr.c) diff --git a/subsys/mem_mgmt/Kconfig b/subsys/mem_mgmt/Kconfig new file mode 100644 index 00000000000..dda1a404167 --- /dev/null +++ b/subsys/mem_mgmt/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +config MEM_ATTR + bool "Memory Attributes management library" + default y if ARM_MPU + help + Enable a small library to manage the memory regions defined in the DT + with a `zephyr,memory-attr` property. This library builds at build + time an array of the memory regions defined in the DT that can be + probed at run-time using several helper functions. Set to `N` if + unsure to save RODATA space. diff --git a/subsys/mem_mgmt/mem_attr.c b/subsys/mem_mgmt/mem_attr.c new file mode 100644 index 00000000000..c70a515dd81 --- /dev/null +++ b/subsys/mem_mgmt/mem_attr.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Carlo Caione, + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define _BUILD_MEM_ATTR_REGION(node_id) \ + { \ + .dt_name = DT_NODE_FULL_NAME(node_id), \ + .dt_addr = DT_REG_ADDR(node_id), \ + .dt_size = DT_REG_SIZE(node_id), \ + .dt_attr = DT_PROP(node_id, zephyr_memory_attr), \ + }, + +static const struct mem_attr_region_t mem_attr_region[] = { + DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(_BUILD_MEM_ATTR_REGION) +}; + +size_t mem_attr_get_regions(const struct mem_attr_region_t **region) +{ + *region = mem_attr_region; + + return ARRAY_SIZE(mem_attr_region); +} + +int mem_attr_check_buf(void *v_addr, size_t size, uint32_t attr) +{ + uintptr_t addr = (uintptr_t) v_addr; + + /* + * If MMU is enabled the address of the buffer is a virtual address + * while the addresses in the DT are physical addresses. Given that we + * have no way of knowing whether a mapping exists, we simply bail out. + */ + if (IS_ENABLED(CONFIG_MMU)) { + return -ENOSYS; + } + + if (size == 0) { + return -ENOTSUP; + } + + for (size_t idx = 0; idx < ARRAY_SIZE(mem_attr_region); idx++) { + const struct mem_attr_region_t *region = &mem_attr_region[idx]; + size_t region_end = region->dt_addr + region->dt_size; + + /* Check if the buffer is in the region */ + if ((addr >= region->dt_addr) && (addr < region_end)) { + /* Check if the buffer is entirely contained in the region */ + if ((addr + size) <= region_end) { + /* check if the attribute is correct */ + return (region->dt_attr & attr) == attr ? 0 : -EINVAL; + } + return -ENOSPC; + } + } + return -ENOBUFS; +} diff --git a/tests/arch/arm/arm_mpu_regions/CMakeLists.txt b/tests/arch/arm/arm_mpu_regions/CMakeLists.txt deleted file mode 100644 index b847ef0b65d..00000000000 --- a/tests/arch/arm/arm_mpu_regions/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(arm_mpu_regions) - -target_sources(app PRIVATE src/main.c) diff --git a/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay b/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay deleted file mode 100644 index 4c9f1a5d5a8..00000000000 --- a/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - /delete-node/ memory@20000000; - - sram0: memory@20000000 { - compatible = "mmio-sram"; - reg = <0x20000000 0x200000>; - }; - - sram_cache: memory@20200000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x20200000 0x100000>; - zephyr,memory-region = "SRAM_CACHE"; - zephyr,memory-attr = "RAM"; - }; - - sram_no_cache: memory@20300000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x20300000 0x100000>; - zephyr,memory-region = "SRAM_NO_CACHE"; - zephyr,memory-attr = "RAM_NOCACHE"; - }; - - sram_dtcm_fake: memory@abcdabcd { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0xabcdabcd 0x100000>; - zephyr,memory-region = "SRAM_DTCM_FAKE"; - zephyr,memory-attr = "RAM"; - }; - - sram_no_mpu: memory@deaddead { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0xdeaddead 0x100000>; - zephyr,memory-region = "SRAM_NO_MPU"; - }; -}; diff --git a/tests/arch/arm/arm_mpu_regions/src/main.c b/tests/arch/arm/arm_mpu_regions/src/main.c deleted file mode 100644 index 72df578f2c0..00000000000 --- a/tests/arch/arm/arm_mpu_regions/src/main.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -extern const struct arm_mpu_config mpu_config; - -static arm_mpu_region_attr_t cacheable = REGION_RAM_ATTR(REGION_1M); -static arm_mpu_region_attr_t noncacheable = REGION_RAM_NOCACHE_ATTR(REGION_1M); - -ZTEST(test_c_arm_mpu_regions, test_regions) -{ - int cnt = 0; - - for (size_t i = 0; i < mpu_config.num_regions; i++) { - const struct arm_mpu_region *r = &mpu_config.mpu_regions[i]; - - if (!strcmp(r->name, "SRAM_CACHE")) { - zassert_equal(r->base, 0x20200000, "Wrong base"); - zassert_equal(r->attr.rasr, cacheable.rasr, - "Wrong attr for SRAM_CACHE"); - cnt++; - } else if (!strcmp(r->name, "SRAM_NO_CACHE")) { - zassert_equal(r->base, 0x20300000, "Wrong base"); - zassert_equal(r->attr.rasr, noncacheable.rasr, - "Wrong attr for SRAM_NO_CACHE"); - cnt++; - } else if (!strcmp(r->name, "SRAM_DTCM_FAKE")) { - zassert_equal(r->base, 0xabcdabcd, "Wrong base"); - zassert_equal(r->attr.rasr, cacheable.rasr, - "Wrong attr for SRAM_DTCM_FAKE"); - cnt++; - } - } - - if (cnt != 3) { - /* - * SRAM0 and SRAM_NO_MPU should not create any MPU region. - * Check that. - */ - ztest_test_fail(); - } -} - -ZTEST_SUITE(test_c_arm_mpu_regions, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/arm/arm_mpu_regions/testcase.yaml b/tests/arch/arm/arm_mpu_regions/testcase.yaml deleted file mode 100644 index b04c2689137..00000000000 --- a/tests/arch/arm/arm_mpu_regions/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -tests: - arch.mpu_regions.arm: - platform_allow: mps2_an385 - tags: - - sram - - mpu diff --git a/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay b/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay index 22590af7af4..fdedd2a4635 100644 --- a/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay +++ b/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include + &adc1 { dmas = < &dmamux1 0 9 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_MEM_INC | STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS) >; @@ -22,7 +25,7 @@ /* ADC driver expects a buffer in a non-cachable memory region */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &dma1 { diff --git a/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay b/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay index 20c8062f325..35e5f3935d3 100644 --- a/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay +++ b/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay @@ -2,6 +2,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + &dma1 { status = "okay"; }; @@ -18,7 +20,7 @@ test_dma0: &dmamux1 { * to be non-cachable. */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &bdma1 { diff --git a/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay b/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay index 20c8062f325..eb94644f3f3 100644 --- a/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay +++ b/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay @@ -18,7 +18,7 @@ test_dma0: &dmamux1 { * to be non-cachable. */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &bdma1 { diff --git a/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay b/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay index c52183dfe81..fca88ad07fd 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay +++ b/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + / { /delete-node/ memory@38000000; @@ -17,20 +20,20 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38100000 0x1000>; zephyr,memory-region = "RES0"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; res1: memory@38200000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38200000 0x2000>; zephyr,memory-region = "RES1"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; res2: memory@38300000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38300000 0x3000>; zephyr,memory-region = "RES2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay b/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay index a4ec256ad17..e00b217a8eb 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay +++ b/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay @@ -4,20 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + / { soc { res0: memory@42000000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x42000000 0x0 0x1000>; zephyr,memory-region = "RES0"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; res1: memory@43000000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x43000000 0x0 0x2000>; zephyr,memory-region = "RES1"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; res_no_mpu: memory@45000000 { @@ -30,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x44000000 0x0 0x3000>; zephyr,memory-region = "RES2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; }; diff --git a/tests/kernel/mem_heap/shared_multi_heap/src/main.c b/tests/kernel/mem_heap/shared_multi_heap/src/main.c index d2169f9164a..ae324d10b22 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/src/main.c +++ b/tests/kernel/mem_heap/shared_multi_heap/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -22,14 +23,14 @@ struct region_map { uintptr_t p_addr; }; -#define FOREACH_REG(n) \ - { \ - .region = { \ - .addr = (uintptr_t) DT_INST_REG_ADDR(n), \ - .size = DT_INST_REG_SIZE(n), \ - .attr = DT_INST_ENUM_IDX_OR(n, zephyr_memory_attr, \ - SMH_REG_ATTR_NUM), \ - }, \ +#define FOREACH_REG(n) \ + { \ + .region = { \ + .addr = (uintptr_t) DT_INST_REG_ADDR(n), \ + .size = DT_INST_REG_SIZE(n), \ + .attr = DT_INST_PROP_OR(n, zephyr_memory_attr, \ + DT_MEM_ARM_MPU_UNKNOWN), \ + }, \ }, struct region_map map[] = { @@ -66,7 +67,7 @@ static struct region_map *get_region_map(void *v_addr) return NULL; } -static inline enum shared_multi_heap_attr mpu_to_reg_attr(int mpu_attr) +static inline enum shared_multi_heap_attr mpu_to_reg_attr(uint32_t dt_attr) { /* * All the memory regions defined in the DT with the MPU property `RAM` @@ -82,10 +83,10 @@ static inline enum shared_multi_heap_attr mpu_to_reg_attr(int mpu_attr) * RAM -> SMH_REG_ATTR_CACHEABLE * RAM_NOCACHE -> SMH_REG_ATTR_NON_CACHEABLE */ - switch (mpu_attr) { - case 0: /* RAM */ + switch (DT_MEM_ARM_MASK(dt_attr)) { + case DT_MEM_ARM_MPU_RAM: return SMH_REG_ATTR_CACHEABLE; - case 1: /* RAM_NOCACHE */ + case DT_MEM_ARM_MPU_RAM_NOCACHE: return SMH_REG_ATTR_NON_CACHEABLE; default: /* How ? */ @@ -104,7 +105,7 @@ static void fill_multi_heap(void) reg_map = &map[idx]; /* zephyr,memory-attr property not found. Skip it. */ - if (reg_map->region.attr == SMH_REG_ATTR_NUM) { + if (reg_map->region.attr == DT_MEM_ARM_MPU_UNKNOWN) { continue; } diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 508d84b39b4..2a5f4bd5135 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -645,18 +645,6 @@ val = "XA XPLUS XB", "XC XPLUS XD", "XA XMINUS XB", "XC XMINUS XD"; }; - test_mem_ram: memory@aabbccdd { - compatible = "vnd,memory-attr"; - reg = < 0xaabbccdd 0x4000 >; - zephyr,memory-attr = "RAM"; - }; - - test_mem_ram_nocache: memory@44332211 { - compatible = "vnd,memory-attr"; - reg = < 0x44332211 0x2000 >; - zephyr,memory-attr = "RAM_NOCACHE"; - }; - test-mtd@ffeeddcc { reg = < 0x0 0x1000 >; #address-cells = < 1 >; diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index aec48e6a9c9..255357e85e8 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -2717,70 +2717,6 @@ ZTEST(devicetree_api, test_mbox) DT_NODELABEL(test_mbox_zero_cell)), ""); } -ZTEST(devicetree_api, test_memory_attr) -{ - #define REGION_RAM_ATTR (0xDEDE) - #define REGION_RAM_NOCACHE_ATTR (0xCACA) - - #define TEST_FUNC(p_name, p_base, p_size, p_attr) \ - { .name = (p_name), \ - .base = (p_base), \ - .size = (p_size), \ - .attr = (p_attr), \ - } - - struct vnd_memory_binding { - char *name; - uintptr_t base; - size_t size; - unsigned int attr; - }; - - struct vnd_memory_binding val_apply[] = { - DT_MEMORY_ATTR_APPLY(TEST_FUNC) - }; - - zassert_true(!strcmp(val_apply[0].name, "memory@aabbccdd"), ""); - zassert_equal(val_apply[0].base, 0xaabbccdd, ""); - zassert_equal(val_apply[0].size, 0x4000, ""); - zassert_equal(val_apply[0].attr, 0xDEDE, ""); - - zassert_true(!strcmp(val_apply[1].name, "memory@44332211"), ""); - zassert_equal(val_apply[1].base, 0x44332211, ""); - zassert_equal(val_apply[1].size, 0x2000, ""); - zassert_equal(val_apply[1].attr, 0xCACA, ""); - - #undef TEST_FUNC - #undef REGION_RAM_ATTR - #undef REGION_RAM_NOCACHE_ATTR - - #define TEST_FUNC(node_id) DT_NODE_FULL_NAME(node_id), - - static const char * const val_func[] = { - DT_MEMORY_ATTR_FOREACH_NODE(TEST_FUNC) - }; - - zassert_true(!strcmp(val_func[0], "memory@aabbccdd"), ""); - zassert_true(!strcmp(val_func[1], "memory@44332211"), ""); - - #undef TEST_FUNC - - #define TEST_FUNC(node_id) \ - COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, \ - zephyr_memory_attr, \ - RAM_NOCACHE), \ - (DT_REG_ADDR(node_id)), \ - ()) - - uintptr_t val_filt[] = { - DT_MEMORY_ATTR_FOREACH_NODE(TEST_FUNC) - }; - - zassert_equal(val_filt[0], 0x44332211, ""); - - #undef TEST_FUNC -} - ZTEST(devicetree_api, test_fixed_partitions) { /* Test finding fixed partitions by the 'label' property. */ diff --git a/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt b/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt new file mode 100644 index 00000000000..7b1f9a77f89 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt @@ -0,0 +1,8 @@ +#SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_mem_attr) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/mem_mgmt/mem_attr/app.overlay b/tests/subsys/mem_mgmt/mem_attr/app.overlay new file mode 100644 index 00000000000..26773fe2345 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/app.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Carlo Caione + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + mem_ram: memory@10000000 { + compatible = "vnd,memory-attr"; + reg = <0x10000000 0x1000>; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_FLASH) | DT_MEM_NON_VOLATILE )>; + }; + + mem_ram_nocache: memory@20000000 { + compatible = "vnd,memory-attr"; + reg = <0x20000000 0x2000>; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + }; + + mem_ram_disabled: memory@30000000 { + compatible = "vnd,memory-attr"; + reg = <0x30000000 0x3000>; + zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_OOO )>; + status = "disabled"; + }; +}; diff --git a/tests/arch/arm/arm_mpu_regions/prj.conf b/tests/subsys/mem_mgmt/mem_attr/prj.conf similarity index 67% rename from tests/arch/arm/arm_mpu_regions/prj.conf rename to tests/subsys/mem_mgmt/mem_attr/prj.conf index 9228251051e..2fcddad0bc8 100644 --- a/tests/arch/arm/arm_mpu_regions/prj.conf +++ b/tests/subsys/mem_mgmt/mem_attr/prj.conf @@ -1,2 +1,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y +CONFIG_MEM_ATTR=y diff --git a/tests/subsys/mem_mgmt/mem_attr/src/main.c b/tests/subsys/mem_mgmt/mem_attr/src/main.c new file mode 100644 index 00000000000..a05ea6dab20 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/src/main.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +ZTEST(mem_attr, test_mem_attr) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + zassert_equal(num_regions, 2, "No regions returned"); + + /* + * Check the data in the regions + */ + for (size_t idx = 0; idx < num_regions; idx++) { + if (region[idx].dt_size == 0x1000) { + zassert_equal(region[idx].dt_addr, 0x10000000, "Wrong region address"); + zassert_equal(region[idx].dt_size, 0x1000, "Wrong region size"); + zassert_equal(region[idx].dt_attr, DT_MEM_ARM_MPU_FLASH | + DT_MEM_NON_VOLATILE, + "Wrong region address"); + zassert_true((strcmp(region[idx].dt_name, "memory@10000000") == 0), + "Wrong name"); + } else { + zassert_equal(region[idx].dt_addr, 0x20000000, "Wrong region address"); + zassert_equal(region[idx].dt_size, 0x2000, "Wrong region size"); + zassert_equal(region[idx].dt_attr, DT_MEM_ARM_MPU_RAM_NOCACHE, + "Wrong region address"); + zassert_true((strcmp(region[idx].dt_name, "memory@20000000") == 0), + "Wrong name"); + } + } + + /* + * Check the input sanitization + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000000, 0x0, DT_MEM_NON_VOLATILE), + -ENOTSUP, "Unexpected return value"); + + /* + * Check a buffer with the correct properties + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000100, 0x100, + DT_MEM_ARM_MPU_FLASH | DT_MEM_NON_VOLATILE), + 0, "Unexpected return value"); + zassert_equal(mem_attr_check_buf((void *) 0x20000000, 0x2000, DT_MEM_ARM_MPU_RAM_NOCACHE), + 0, "Unexpected return value"); + + /* + * Check partial attributes + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000100, 0x100, DT_MEM_NON_VOLATILE), + 0, "Unexpected return value"); + + /* + * Check a buffer with the wrong attribute + */ + zassert_equal(mem_attr_check_buf((void *) 0x20000000, 0x2000, DT_MEM_OOO), + -EINVAL, "Unexpected return value"); + + /* + * Check a buffer outsize the regions + */ + zassert_equal(mem_attr_check_buf((void *) 0x40000000, 0x1000, DT_MEM_NON_VOLATILE), + -ENOBUFS, "Unexpected return value"); + + /* + * Check a buffer too big for the region + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000000, 0x2000, DT_MEM_NON_VOLATILE), + -ENOSPC, "Unexpected return value"); + + /* + * Check a buffer in a disabled region + */ + zassert_equal(mem_attr_check_buf((void *) 0x30000000, 0x1000, DT_MEM_OOO), + -ENOBUFS, "Unexpected return value"); +} + +ZTEST_SUITE(mem_attr, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/mem_mgmt/mem_attr/testcase.yaml b/tests/subsys/mem_mgmt/mem_attr/testcase.yaml new file mode 100644 index 00000000000..ecb445a077e --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/testcase.yaml @@ -0,0 +1,8 @@ +common: + platform_allow: + - native_posix + - native_posix_64 + integration_platforms: + - native_posix +tests: + mem_mgmt.mem_attr.default: {} From 07a898bbdfc74452be497d19abb564b302454333 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 14 Sep 2023 21:11:54 +0200 Subject: [PATCH 0476/4498] MAINTAINERS: nanopb: Update status to maintained Change my collaborator role to maintainer and add test files entry. Signed-off-by: Pieter De Gendt --- MAINTAINERS.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 0e3d96644c0..a075530316c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3323,12 +3323,13 @@ West: - "area: Tracing" "West project: nanopb": - status: odd fixes - collaborators: + status: maintained + maintainers: - pdgendt files: - modules/nanopb/ - samples/modules/nanopb/ + - tests/modules/nanopb/ labels: - "area: Serialization" From 0357b4d4f54ea836c4dd74cf9215e171c87e47dd Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 14 Sep 2023 20:02:53 +0200 Subject: [PATCH 0477/4498] modules: nanopb: Add helper function to generate sources Introduce a helper function zephyr_nanopb_sources to generate source files and add these to a target. Signed-off-by: Pieter De Gendt --- modules/nanopb/CMakeLists.txt | 14 ++---------- modules/nanopb/nanopb.cmake | 33 +++++++++++++++++++++++++++ samples/modules/nanopb/CMakeLists.txt | 15 ++++-------- 3 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 modules/nanopb/nanopb.cmake diff --git a/modules/nanopb/CMakeLists.txt b/modules/nanopb/CMakeLists.txt index 7696ae9e118..2520595cf94 100644 --- a/modules/nanopb/CMakeLists.txt +++ b/modules/nanopb/CMakeLists.txt @@ -6,25 +6,15 @@ if(CONFIG_NANOPB) set(NANOPB_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) - find_program(PROTOC protoc) - if(NOT PROTOC) - message(FATAL_ERROR "'protoc' not found, please ensure protoc is installed\ - and in path. See https://docs.zephyrproject.org/latest/samples/modules/nanopb/README.html") - endif() - - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_DIR}/extra) - find_package(Nanopb REQUIRED) - zephyr_library() - - zephyr_include_directories(${NANOPB_DIR}) - zephyr_library_sources( ${NANOPB_DIR}/pb_common.c ${NANOPB_DIR}/pb_encode.c ${NANOPB_DIR}/pb_decode.c ) + zephyr_include_directories(${NANOPB_DIR}) + zephyr_compile_definitions( PB_MAX_REQUIRED_FIELDS=${CONFIG_NANOPB_MAX_REQUIRED_FIELDS}) diff --git a/modules/nanopb/nanopb.cmake b/modules/nanopb/nanopb.cmake new file mode 100644 index 00000000000..ddcdb5f61d1 --- /dev/null +++ b/modules/nanopb/nanopb.cmake @@ -0,0 +1,33 @@ +# Copyright (c) 2023, Basalte bv +# +# SPDX-License-Identifier: Apache-2.0 + +include_guard(GLOBAL) + +list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_NANOPB_MODULE_DIR}/extra) + +find_program(PROTOC protoc) +if(NOT PROTOC) + message(FATAL_ERROR "'protoc' not found, please ensure protoc is installed\ +and in path. See https://docs.zephyrproject.org/latest/samples/modules/nanopb/README.html") +endif() + +find_package(Nanopb REQUIRED) + +# Usage: +# list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb) +# include(nanopb) +# +# zephyr_nanopb_sources( ) +# +# Generate source and header files from provided .proto files and +# add these as sources to the specified target. +function(zephyr_nanopb_sources target) + # Turn off the default nanopb behavior + set(NANOPB_GENERATE_CPP_STANDALONE OFF) + + nanopb_generate_cpp(proto_srcs proto_hdrs RELPATH ${CMAKE_CURRENT_SOURCE_DIR} ${ARGN}) + + target_include_directories(${target} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + target_sources(${target} PRIVATE ${proto_srcs} ${proto_hdrs}) +endfunction() diff --git a/samples/modules/nanopb/CMakeLists.txt b/samples/modules/nanopb/CMakeLists.txt index 67caa89ac80..a3180075d8e 100644 --- a/samples/modules/nanopb/CMakeLists.txt +++ b/samples/modules/nanopb/CMakeLists.txt @@ -5,15 +5,10 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(nanopb_sample) -# Note that here, we're adding CMAKE_SOURCE_DIR to the include path for nanopb. -# This is needed because the below call to nanopb_generate_cpp() is using -# 'RELPATH .' -set(NANOPB_OPTIONS "-I${CMAKE_SOURCE_DIR}") -nanopb_generate_cpp(proto_sources proto_headers RELPATH . - src/simple.proto -) -# we need to be able to include generated header files -zephyr_library_include_directories(${CMAKE_CURRENT_BINARY_DIR}) +list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb) +include(nanopb) + +zephyr_nanopb_sources(app src/simple.proto) FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${proto_sources} ${app_sources}) +target_sources(app PRIVATE ${app_sources}) From b255182a13e610b42f2aebaf1d40ab906e4f1244 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 14 Sep 2023 21:06:55 +0200 Subject: [PATCH 0478/4498] tests: modules: Add nanopb tests Add test cases for nanopb for simple and nested complex messages. Signed-off-by: Pieter De Gendt --- tests/modules/nanopb/CMakeLists.txt | 19 +++++ tests/modules/nanopb/prj.conf | 4 ++ tests/modules/nanopb/proto/complex.proto | 13 ++++ tests/modules/nanopb/proto/simple.options | 1 + tests/modules/nanopb/proto/simple.proto | 11 +++ tests/modules/nanopb/proto/sub/nested.options | 1 + tests/modules/nanopb/proto/sub/nested.proto | 12 ++++ tests/modules/nanopb/src/main.c | 71 +++++++++++++++++++ tests/modules/nanopb/testcase.yaml | 9 +++ 9 files changed, 141 insertions(+) create mode 100644 tests/modules/nanopb/CMakeLists.txt create mode 100644 tests/modules/nanopb/prj.conf create mode 100644 tests/modules/nanopb/proto/complex.proto create mode 100644 tests/modules/nanopb/proto/simple.options create mode 100644 tests/modules/nanopb/proto/simple.proto create mode 100644 tests/modules/nanopb/proto/sub/nested.options create mode 100644 tests/modules/nanopb/proto/sub/nested.proto create mode 100644 tests/modules/nanopb/src/main.c create mode 100644 tests/modules/nanopb/testcase.yaml diff --git a/tests/modules/nanopb/CMakeLists.txt b/tests/modules/nanopb/CMakeLists.txt new file mode 100644 index 00000000000..bbe95de0bf2 --- /dev/null +++ b/tests/modules/nanopb/CMakeLists.txt @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(nanopb_tests) + +list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb) +include(nanopb) + +zephyr_nanopb_sources(app proto/simple.proto) + +zephyr_nanopb_sources(app + proto/complex.proto + proto/sub/nested.proto +) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/modules/nanopb/prj.conf b/tests/modules/nanopb/prj.conf new file mode 100644 index 00000000000..6d5e46c1ddd --- /dev/null +++ b/tests/modules/nanopb/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_NANOPB=y diff --git a/tests/modules/nanopb/proto/complex.proto b/tests/modules/nanopb/proto/complex.proto new file mode 100644 index 00000000000..fde97aeeeab --- /dev/null +++ b/tests/modules/nanopb/proto/complex.proto @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +syntax = "proto3"; + +import "sub/nested.proto"; + +message ComplexMessage { + NestedMessage nested = 1; +}; diff --git a/tests/modules/nanopb/proto/simple.options b/tests/modules/nanopb/proto/simple.options new file mode 100644 index 00000000000..47c1f05de08 --- /dev/null +++ b/tests/modules/nanopb/proto/simple.options @@ -0,0 +1 @@ +SimpleMessage.buffer max_size:8 fixed_length:true diff --git a/tests/modules/nanopb/proto/simple.proto b/tests/modules/nanopb/proto/simple.proto new file mode 100644 index 00000000000..ff192f8f87a --- /dev/null +++ b/tests/modules/nanopb/proto/simple.proto @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +syntax = "proto3"; + +message SimpleMessage { + bytes buffer = 1; +}; diff --git a/tests/modules/nanopb/proto/sub/nested.options b/tests/modules/nanopb/proto/sub/nested.options new file mode 100644 index 00000000000..967f27485fe --- /dev/null +++ b/tests/modules/nanopb/proto/sub/nested.options @@ -0,0 +1 @@ +NestedMessage.name max_size:32 diff --git a/tests/modules/nanopb/proto/sub/nested.proto b/tests/modules/nanopb/proto/sub/nested.proto new file mode 100644 index 00000000000..01790b55fa0 --- /dev/null +++ b/tests/modules/nanopb/proto/sub/nested.proto @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +syntax = "proto3"; + +message NestedMessage { + uint32 id = 1; + string name = 2; +}; diff --git a/tests/modules/nanopb/src/main.c b/tests/modules/nanopb/src/main.c new file mode 100644 index 00000000000..cd68298960e --- /dev/null +++ b/tests/modules/nanopb/src/main.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +#include +#include + +ZTEST(nanopb_tests, test_nanopb_simple) +{ + uint8_t buffer[SimpleMessage_size]; + SimpleMessage msg = SimpleMessage_init_zero; + + for (size_t i = 0; i < sizeof(msg.buffer); ++i) { + msg.buffer[i] = i; + } + + pb_ostream_t ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + zassert_true(pb_encode(&ostream, SimpleMessage_fields, &msg), + "Encoding failed: %s", PB_GET_ERROR(&ostream)); + + /* Sanity check, clear data */ + memset(&msg, 0, sizeof(SimpleMessage)); + + pb_istream_t istream = pb_istream_from_buffer(buffer, ostream.bytes_written); + + zassert_true(pb_decode(&istream, SimpleMessage_fields, &msg), + "Decoding failed: %s", PB_GET_ERROR(&ostream)); + + for (size_t i = 0; i < sizeof(msg.buffer); ++i) { + zassert_equal(msg.buffer[i], i); + } +} + +ZTEST(nanopb_tests, test_nanopb_nested) +{ + uint8_t buffer[ComplexMessage_size]; + ComplexMessage msg = ComplexMessage_init_zero; + + msg.has_nested = true; + msg.nested.id = 42; + strcpy(msg.nested.name, "Test name"); + + pb_ostream_t ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + zassert_true(pb_encode(&ostream, ComplexMessage_fields, &msg), + "Encoding failed: %s", PB_GET_ERROR(&ostream)); + + /* Sanity check, clear data */ + memset(&msg, 0, sizeof(ComplexMessage)); + + pb_istream_t istream = pb_istream_from_buffer(buffer, ostream.bytes_written); + + zassert_true(pb_decode(&istream, ComplexMessage_fields, &msg), + "Decoding failed: %s", PB_GET_ERROR(&istream)); + + zassert_equal(42, msg.nested.id); + zassert_true(msg.has_nested); + zassert_equal(0, strcmp(msg.nested.name, "Test name")); +} + +ZTEST_SUITE(nanopb_tests, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/modules/nanopb/testcase.yaml b/tests/modules/nanopb/testcase.yaml new file mode 100644 index 00000000000..23956de2091 --- /dev/null +++ b/tests/modules/nanopb/testcase.yaml @@ -0,0 +1,9 @@ +tests: + libraries.nanopb: + modules: + - nanopb + tags: + - nanopb + integration_platforms: + - native_posix + - native_posix_64 From 5029922384a8a2e11ca32d1cd2b01d62a4b6297c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 14:01:06 +0200 Subject: [PATCH 0479/4498] mbedtls module: Fix for other POSIX arch boards Instead of detecting that we are in a native/POSIX arch based board by checking for each board specifically, let checks for the architecture. In that way other boards (like the upcoming nrf53_bsim ones) will also work. Signed-off-by: Alberto Escolar Piedras --- modules/mbedtls/configs/config-tls-generic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index 9d5dcfdaa47..7cf85731c85 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -463,7 +463,7 @@ #define MBEDTLS_PSA_CRYPTO_C #define MBEDTLS_USE_PSA_CRYPTO -#if defined(CONFIG_BOARD_NRF52_BSIM) || defined(CONFIG_BOARD_NATIVE_POSIX) +#if defined(CONFIG_ARCH_POSIX) #define MBEDTLS_PSA_KEY_SLOT_COUNT 64 #define MBEDTLS_PSA_CRYPTO_STORAGE_C #define MBEDTLS_PSA_ITS_FILE_C From 6be960ae715236b62f79bc1d131dfca7761aa021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 15 Sep 2023 12:36:25 +0200 Subject: [PATCH 0480/4498] drivers: rtc: drop printk statement from RTC Shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove a printk forgotten in rtc get command. Signed-off-by: Benjamin Cabé --- drivers/rtc/rtc_shell.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/rtc/rtc_shell.c b/drivers/rtc/rtc_shell.c index c6de3f0a632..8dcaf46f875 100644 --- a/drivers/rtc/rtc_shell.c +++ b/drivers/rtc/rtc_shell.c @@ -197,8 +197,6 @@ static int cmd_get(const struct shell *sh, size_t argc, char **argv) { const struct device *dev = device_get_binding(argv[1]); - printk("in RTC Shell Get\n"); - if (!device_is_ready(dev)) { shell_error(sh, "device %s not ready", argv[1]); return -ENODEV; From ae8c72444e31c6b535f4f297ec24d414789ae063 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 13 Sep 2023 16:22:42 +0200 Subject: [PATCH 0481/4498] scripts: build: file2hex: Add optional offset and length parameters Add optional offset and length parameters to generate partial hex files. Signed-off-by: Pieter De Gendt --- scripts/build/file2hex.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/build/file2hex.py b/scripts/build/file2hex.py index 34857d4159b..2bb967cf29d 100755 --- a/scripts/build/file2hex.py +++ b/scripts/build/file2hex.py @@ -26,6 +26,11 @@ def parse_args(): formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) parser.add_argument("-f", "--file", required=True, help="Input file") + parser.add_argument("-o", "--offset", type=lambda x: int(x, 0), default=0, + help="Byte offset in the input file") + parser.add_argument("-l", "--length", type=lambda x: int(x, 0), default=-1, + help="""Length in bytes to read from the input file. + Defaults to reading till the end of the input file.""") parser.add_argument("-g", "--gzip", action="store_true", help="Compress the file using gzip before output") parser.add_argument("-t", "--gzip-mtime", type=int, default=0, @@ -53,18 +58,26 @@ def main(): if args.gzip: with io.BytesIO() as content: with open(args.file, 'rb') as fg: + fg.seek(args.offset) with gzip.GzipFile(fileobj=content, mode='w', mtime=args.gzip_mtime, compresslevel=9) as gz_obj: - gz_obj.write(fg.read()) + gz_obj.write(fg.read(args.length)) content.seek(0) for chunk in iter(lambda: content.read(8), b''): make_hex(chunk) else: with open(args.file, "rb") as fp: - for chunk in iter(lambda: fp.read(8), b''): - make_hex(chunk) + fp.seek(args.offset) + if args.length < 0: + for chunk in iter(lambda: fp.read(8), b''): + make_hex(chunk) + else: + remainder = args.length + for chunk in iter(lambda: fp.read(min(8, remainder)), b''): + make_hex(chunk) + remainder = remainder - len(chunk) if __name__ == "__main__": From a6d81591a2ca270f01ab6c4d6c1fce186c49fd8d Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 14 Sep 2023 08:30:21 +0200 Subject: [PATCH 0482/4498] tests: gen_inc_file: Add tests for optional offset/length Add tests to validate the optional offset/length arguments for the file2hex python script. Signed-off-by: Pieter De Gendt --- .../gen_inc_file/CMakeLists.txt | 4 ++ .../gen_inc_file/src/main.c | 52 +++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/tests/application_development/gen_inc_file/CMakeLists.txt b/tests/application_development/gen_inc_file/CMakeLists.txt index aebb2257572..45401b981c6 100644 --- a/tests/application_development/gen_inc_file/CMakeLists.txt +++ b/tests/application_development/gen_inc_file/CMakeLists.txt @@ -13,6 +13,10 @@ set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/) set(source_file src/file.bin) generate_inc_file_for_target(app ${source_file} ${gen_dir}/file.bin.inc) +generate_inc_file_for_target(app ${source_file} ${gen_dir}/file.bin.partial.inc + --offset=100 --length=42) generate_inc_file_for_target(app ${source_file} ${gen_dir}/file.bin.gz.inc --gzip) generate_inc_file_for_target(app ${source_file} ${gen_dir}/file.bin.mtime.gz.inc --gzip --gzip-mtime=42) +generate_inc_file_for_target(app ${source_file} ${gen_dir}/file.bin.partial.gz.inc + --gzip --offset=100 --length=42) diff --git a/tests/application_development/gen_inc_file/src/main.c b/tests/application_development/gen_inc_file/src/main.c index a7eaf7d50b3..2fbb57c2ac3 100644 --- a/tests/application_development/gen_inc_file/src/main.c +++ b/tests/application_development/gen_inc_file/src/main.c @@ -13,11 +13,16 @@ * @cond INTERNAL_HIDDEN */ -/* The file.inc contains characters from 0 to 255 */ +/* The file.bin.inc contains characters from 0 to 255 */ static const unsigned char inc_file[] = { #include }; +/* The file.bin.partial.inc contains characters from 100 to 141 */ +static const unsigned char partial_inc_file[] = { +#include +}; + static const unsigned char no_mtime_gz_inc_file[] = { #include }; @@ -26,6 +31,10 @@ static const unsigned char mtime_gz_inc_file[] = { #include }; +static const unsigned char partial_gz_inc_file[] = { +#include +}; + /** * @endcond */ @@ -74,6 +83,17 @@ static const unsigned char compressed_inc_file[] = { 0x8c, 0x05, 0x29, 0x00, 0x01, 0x00, 0x00, }; +static const unsigned char compressed_partial_inc_file[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xff, 0x4b, 0x49, 0x4d, 0x4b, 0xcf, 0xc8, + 0xcc, 0xca, 0xce, 0xc9, 0xcd, 0xcb, 0x2f, 0x28, + 0x2c, 0x2a, 0x2e, 0x29, 0x2d, 0x2b, 0xaf, 0xa8, + 0xac, 0xaa, 0xae, 0xa9, 0xad, 0xab, 0x6f, 0x68, + 0x6c, 0x6a, 0x6e, 0x69, 0x6d, 0x6b, 0xef, 0xe8, + 0xec, 0xea, 0xee, 0xe9, 0x05, 0x00, 0xe7, 0xa1, + 0xc1, 0x22, 0x2a, 0x00, 0x00, 0x00, +}; + ZTEST(gen_inc_file, test_gen_inc_file) { int i; @@ -85,13 +105,24 @@ ZTEST(gen_inc_file, test_gen_inc_file) } } +ZTEST(gen_inc_file, test_gen_partial_inc_file) +{ + int i; + + zassert_equal(sizeof(partial_inc_file), 42, "Invalid partial size file"); + + for (i = 0; i < sizeof(partial_inc_file); i++) { + zassert_equal(partial_inc_file[i], i + 100, "Invalid value in partial inc file"); + } +} static void do_test_gen_gz_inc_file(const unsigned char gz_inc_file[], + const unsigned char ref_file[], int ref_size, const unsigned char mtime[4]) { int i; - for (i = 0; i < sizeof(inc_file); i++) { + for (i = 0; i < ref_size; i++) { if (4 <= i && i < 8) { /* Modification time field (4 bytes) in * the gzip header. @@ -104,7 +135,7 @@ static void do_test_gen_gz_inc_file(const unsigned char gz_inc_file[], continue; } - zassert_equal(gz_inc_file[i], compressed_inc_file[i], + zassert_equal(gz_inc_file[i], ref_file[i], "Invalid value in inc file"); } } @@ -114,7 +145,8 @@ ZTEST(gen_inc_file, test_gen_gz_inc_file_no_mtime) zassert_equal(sizeof(no_mtime_gz_inc_file), sizeof(compressed_inc_file), "Invalid compressed file size"); - do_test_gen_gz_inc_file(no_mtime_gz_inc_file, mtime_zero); + do_test_gen_gz_inc_file(no_mtime_gz_inc_file, compressed_inc_file, + sizeof(compressed_inc_file), mtime_zero); } ZTEST(gen_inc_file, test_gen_gz_inc_file_mtime_arg) @@ -122,7 +154,17 @@ ZTEST(gen_inc_file, test_gen_gz_inc_file_mtime_arg) zassert_equal(sizeof(mtime_gz_inc_file), sizeof(compressed_inc_file), "Invalid compressed file size"); - do_test_gen_gz_inc_file(mtime_gz_inc_file, mtime_test_val); + do_test_gen_gz_inc_file(mtime_gz_inc_file, compressed_inc_file, + sizeof(compressed_inc_file), mtime_test_val); +} + +ZTEST(gen_inc_file, test_gen_gz_inc_partial_file) +{ + zassert_equal(sizeof(partial_gz_inc_file), sizeof(compressed_partial_inc_file), + "Invalid partial compressed file size"); + + do_test_gen_gz_inc_file(partial_gz_inc_file, compressed_partial_inc_file, + sizeof(compressed_partial_inc_file), NULL); } From 21a36f60631f96cf9eefefedb9a18cfa470b471d Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 14 Sep 2023 13:34:45 +0000 Subject: [PATCH 0483/4498] manifest: update hal_ti Update hal_ti to include a build error fix. Signed-off-by: Fabio Baltieri --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 5a39a5d2e0f..a02a5026175 100644 --- a/west.yml +++ b/west.yml @@ -239,7 +239,7 @@ manifest: groups: - hal - name: hal_ti - revision: 9fa5827c44b6a81dced9efafb4095dafabea7421 + revision: b85f86e51fc4d47c4c383d320d64d52d4d371ae4 path: modules/hal/ti groups: - hal From b9d3909589c3ac305b9cdba634849e46a5fbe9b5 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 14:21:44 +0800 Subject: [PATCH 0484/4498] boards: riscv: Introduce esp32c3_luatos_core board ESP32C3 LuatOS core is a dev board with esp32-c3. It has similar functions to esp32c3 devkitm, but smaller in size. Signed-off-by: YuLong Yao --- .../riscv/esp32c3_luatos_core/Kconfig.board | 14 + .../esp32c3_luatos_core/Kconfig.defconfig | 17 ++ .../esp32c3_luatos_core/Kconfig.sysbuild | 10 + boards/riscv/esp32c3_luatos_core/board.cmake | 10 + .../doc/img/esp32c3_luatos_core.jpg | Bin 0 -> 58004 bytes .../doc/img/esp32c3_luatos_core_pinfunc.jpg | Bin 0 -> 93618 bytes .../doc/img/esp32c3_luatos_core_usb.jpg | Bin 0 -> 54920 bytes .../riscv/esp32c3_luatos_core/doc/index.rst | 259 ++++++++++++++++++ .../esp32c3_luatos_core-pinctrl.dtsi | 51 ++++ .../esp32c3_luatos_core.dts | 18 ++ .../esp32c3_luatos_core.dtsi | 137 +++++++++ .../esp32c3_luatos_core.yaml | 21 ++ .../esp32c3_luatos_core_defconfig | 11 + .../esp32c3_luatos_core_usb.dts | 26 ++ .../esp32c3_luatos_core_usb.yaml | 21 ++ .../esp32c3_luatos_core_usb_defconfig | 11 + .../esp32c3_luatos_core/support/openocd.cfg | 12 + 17 files changed, 618 insertions(+) create mode 100644 boards/riscv/esp32c3_luatos_core/Kconfig.board create mode 100644 boards/riscv/esp32c3_luatos_core/Kconfig.defconfig create mode 100644 boards/riscv/esp32c3_luatos_core/Kconfig.sysbuild create mode 100644 boards/riscv/esp32c3_luatos_core/board.cmake create mode 100644 boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core.jpg create mode 100644 boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core_pinfunc.jpg create mode 100644 boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core_usb.jpg create mode 100644 boards/riscv/esp32c3_luatos_core/doc/index.rst create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dts create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dtsi create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_defconfig create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.dts create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml create mode 100644 boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb_defconfig create mode 100644 boards/riscv/esp32c3_luatos_core/support/openocd.cfg diff --git a/boards/riscv/esp32c3_luatos_core/Kconfig.board b/boards/riscv/esp32c3_luatos_core/Kconfig.board new file mode 100644 index 00000000000..ac7b48a7a36 --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/Kconfig.board @@ -0,0 +1,14 @@ +# Copyright (c) 2023 YuLong Yao +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32C3_LUATOS_CORE + bool "luatos ESP32C3-CORE Board" + depends on SOC_SERIES_ESP32C3 + +config BOARD_ESP32C3_LUATOS_CORE_USB + bool "luatos ESP32C3-CORE Board without UART chip" + depends on SOC_SERIES_ESP32C3 + +choice SOC_PART_NUMBER + default SOC_ESP32C3_MINI_N4 +endchoice diff --git a/boards/riscv/esp32c3_luatos_core/Kconfig.defconfig b/boards/riscv/esp32c3_luatos_core/Kconfig.defconfig new file mode 100644 index 00000000000..1a1ee456a3d --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/Kconfig.defconfig @@ -0,0 +1,17 @@ +# ESP32C3 core board configuration + +# Copyright (c) 2023 YuLong Yao +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "esp32c3_luatos_core" + depends on BOARD_ESP32C3_LUATOS_CORE || BOARD_ESP32C3_LUATOS_CORE_USB + +config HEAP_MEM_POOL_SIZE + default 98304 if WIFI + default 40960 if BT + default 4096 + +choice BT_HCI_BUS_TYPE + default BT_ESP32 if BT +endchoice diff --git a/boards/riscv/esp32c3_luatos_core/Kconfig.sysbuild b/boards/riscv/esp32c3_luatos_core/Kconfig.sysbuild new file mode 100644 index 00000000000..3a2d17ac5cf --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/riscv/esp32c3_luatos_core/board.cmake b/boards/riscv/esp32c3_luatos_core/board.cmake new file mode 100644 index 00000000000..d8eee88156c --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2023 YuLong Yao +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core.jpg b/boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df25a96c292b1c1df110a12450fbdb91583d95c3 GIT binary patch literal 58004 zcmb5UbyOVN69zbFfv~yw`31mLl2eoeARr(D=wA=O%PK$`fP{$n@A=x0 zUr&^`C@9FtDClqApuWXK$Hc@y$H2hCeus;NjfahaflGvohfhFANQj9;OhQCJ@{WLz z;NMOVkY2w*MnOYCK_kGzz#{nn-ClYDcyAG85#*5&@BoN-2uOGcFZ}=t0003Q2?6kb zH&g&J${Pekq_?kc$q@jENC*i3&(|o3NXQ7NZ(ddan6IB9;v(U`_HYIG@F@fl`7Q4M z=LN$&Q}b(lZo3`{X4-bZVn+{lQi|{Gr(fPY*PWQo4%5E(CPl}ueMo*mvyNs|6Wg)& zWeZ=g@g@~YTJn}{C%=6PK`qpU%Hma#VTK>@WA#uB zdmJ06;SukAnSpYQ(1smlJz$Lc*Ypy3_2Xe)1$l)v9eaETp;+uV*l-uY@eWFYkejc{ z5Bh&Cd5o$(bA7c7mJ|(mK#5(THZ`pLmjQ~;8IK!kUINvhWq&!M8KE-#rpdBGyEFp< z1ol?5&s8YyQO!*!lRF*5HhDuLE4+zipYAP)(EWO~j>uFiecdbFe!iOd9{_cO&&?ip zJCD+I!(Y00^PCE|u}7PEdrYopSlWV4Oi^cpQh9BtsPfAsmNeLsKgv535_UR8Yn}X) zrhLmkIrhH*_#we!@DfkUBP%RMl2qfbgG$43aYp~HBQD(B$h|Zk*VwOlSnN|8e(LmN zrEBrun=-h^I5-91*T3oO$X@_Lhsw;YUBD&4jRoSetn<1XTYb8(x+d@P$94%3yD?eJ zMd*9emKZR8Ta&cW+vAleAgpUn;P-zktR|C#Y^~L>~?%m#e1{;ob_x2hREl!0;`yd9W}jCCv^7$+yXTvaef1F z{1x31l4Sm=xqqhy0mnps54TR{t81l&c%9foozTp2y1RD!!91wVU^DFefb#qhivxCf z7GIt_nD0z@x`r?g4tbCes`EP{x}Zz&nkxQ&2>j}r%@N3SDIQHcbN^F}Pj#m?jko&~ zv(x`XXq^q{ITtaX*MAuK6r=MqsI*eMgc!NK&IV}A* zXKD~bf)Pi5a0L9eHI*e}WW~TJw9HKnl|cQQ)@j#jkjr%QUPv6_4&UHt=6aRhF=CUa zIf~I)hs=H;trtA`()g=z+b@1>PLK?@$)O9{5tVYj;R8-Wz35ouuH&(4!~e`qHDdY# z@IizBJq!>$$o=+Yl7GOVH$vL4=5@*D@7{hk@?hszjbs+uIQ*dHO0#U-V_@Hp)QBm4 zjcT8{ctSjMf4g&($wBg4?Os%EyesWbP|0s!kKf`7DHNkK(9ZL-|AnuT%sO;Ss1Rhk z+K;YnbYy1XGA=zSC%?DCwNtZbcPM0nq-Th9XyiVAt8<#fYkcc4UnW#yqBKiE)}O8XYyWM7hMgj}{hny|ivpi?)0m)O<*?4vBKa(h(_2Ld85sgJ&E;GN&HgzpvpHIiv z8I`T=v_ zt8?1bo8V#k<2AI(NBsX&f$&L;41#D}HkG=#40FCLE7Iw8;~Vf;Z3uU)%M*CO9~a)J ziun91>*6`IKx~klRno*8psfS)`_6k=Ce%~_CbD1oWHa3=lwj?>`^C0PL{=WJ8qAw~ zRbAU2|Kl}?kcIJ;ajE@P$z!D+DK(}nSvT9_(95!5m2HkOR5kPZkrYFvg!c6&hLoaa z)3eU>o0KG69GR@Yjzf0_v%0A z&`$i-+>GHDYMt3MqGLsRB)Ul2|D=81*@kF3s5YMe_0s9O_><90P)OFGuP*Fp7!ibg z+1y>OX#G?B7MVp4b9?5Z!t20-EjH|0^y+OpuTjgJe4A;4`b6B%Pi7cUU3fq&Y4y-V!q{GIe$f{QZFK@bHRgYxPXWqF-<9I~v=pSnz9E(hc zjPX)i&VLLZ*w%hMi@2FVs+7EwD~WJBY>0|0$T@6Dp{tin{2C} zc;4QvxE5wvi4_~{1q*X_3vQK(V6?xN5I)|dic#zPfS3K_VNbzdT|~@@jN9OCb9p5( zw_ua$>C;y600VaN;3iOTvhSR#dIUp6bCToRs}dyW$@R2gu_r_eiUnCIxY$Fr5`X1H z%HJ@WYX?6sV@0plDIe|QwdrP|fy#s38*~q2djlgWjz30szL6v}>{`4}XzQaOs z`oCJh8~b1!`|nDf_#*~>70Oiq6JQRP;@?fULL1?73?v2BF1Q~k6P|ep_pVj%$;G7M zt7Tm+t{x_Rn)xv%l5IGQVAaH*gVIUkuT*YRk7becb>Eq!4q;Zsywru1^Gdkpp9LMZ z=12k?@wmL+qc@*k^Cu<>IQ{49x6S$cUVAHQ)#sqAktMlpV@;-t5~ucLZL6!YJc~DD zw8x2X?TF=eHxuI?6~_^U)9Po@ZqYuw_{*td2)OME&t(9sK;7|k4WG&R){RJOL~5Xt zc(d(wbl(4IYqjzD)4zrr70e?Z*~ireTYHY|DCBgDXGO+lX^ngxAsw332H)3}Sve`{ zGD*=d`MxC`>0s2#U`E=!=WgpkGFoXe!mUWZJ9B81D7jn;4qwprn0l}fiICkN3h)xv=bWRmArk62GWj06H%pc#7>Ns&Zxx8FJt!6)^ z1`pAE=fbnXo9uI_oA-IlVGMsm%mf0tvKNy$&|i$XQI~ICEK@iVPtY=-{a+~mUgHCeExFu!@&-FC69*j zPU8Mo%7zB{gPL7h71JVRj6o7gzJt!x)COB+saN##YGZaW)S8>JZjDR=9P--T-nia(>7`V&ORXH&iKyIJe2 zwT01xM^ahXgXXs=UUf0%QGnQ>aH>jCq2eVbr3V#CE>Tv%%mP|H$1lUDE`o(;5r} z;sC9>|J_+)qG)uRrp7*W3)^G|luQZu$@;At@4Ax2w$2BabnGxeq_XX(&yBx9#2|(> z!#W?A&r#kG85ljzTFK9QMh>8&bWiPp_>uRkWM#GDWsz8<^PWV%Q~)=f4RxmeNwv+wow+>IeGv7(Eq`!c4xMYjzI45C zWjbC{)ytJ`fs8-F#3Uw`I0lb5?1@z;A4MqT5-w7%mr0S>nrd=MH&mrBlMm{QxmzIgl-{J zX3_iS@6HsmA7y5I*JRC}?O5c?K;S>9Pj|YeL2X0FdQdv7ycpMKwIOko5TD9Oz1p{> zYI$o>D8d_K_iZA%^;L+~2k&Fk@BYfe4{E>u4dyr;ejsq4p~8NBUcmu*oXfaKQSH_8 z;L-^=dl|!j>SNK9ek{clhOG4z=!0EiwYNpp&EARO+)gv`=gY~18DX0r*1cV3(F{xa z!rX~%pqYS?ktL%$6vUAP;tbs#}|4z!oS<5COrIeKTj}khQ~{GylF8dC#gBz z;hKj*f$TO;WCF<;OK9aG$7`gb8&zx9DRGB`%mAF_WaK{{0jw3;`0_efGQbPK_Z=B( znGj{vgfml4kYZCip$-2pV3~vib^N7T=+8rSx{%NrCJK`d_ zlwFH#ja$lS4}@3to{jH|{Hr zMnphFK}3B;`v0P7GbxvVQlU7V7_L}r^Y9im;@v`wCuR!$pZl|o5EmE%Q_uxS-d47|%<{BRL zGdc0)!Sl+7+sLESUCLI)waNbA)BY3nKkzV4{APE?pj`=@<{&nmzg->$R35npLIZ~G zyOW3UR);xNxknEgbx$!tyynlrsI{!iLqTi-ao%2Tc}uX=$cC8lh!+50>_PRp&mE__ z{waU{4)VPD)#ozzjzeT$W}CTSp>5LPXd)$u*Wx*dds5rdr&@M$##}BcI`_b;wY~+f ze68WRKG_o{Wmgp}+ z_eXZScSfgvwaF?l7dtiVLWYLk4#%NNS;fnZH8#l=jZVs7RhgP>D0-=gJ^A@}YVplc z!NPfw8tI8iNU~5I1Cz3V5vpL76|)g&j5LcNd_<(9-{(+&5Ngex??e*$*@oO|A0@F& z?y>OiFw%TDW|bjHguo7GHJh|AaXVQ9-WVUJ$2f_I8^bz;zH&mk48C0w!xI#jfSVd$*U&Whi0_zSgS{+!?wy9Uzct8Q#lm> z)2F)TcecS?WqjT)?+lbPx@_8f%*AxZN4bva2_LRl9$I*8q{&=2?SDB37x2+Dji!Au z-Dd$=s8XK<)Fq}GE*^d1D16Sd4M2sfKH^>o06-w7OSKlQlF5x-`3bkN1_urtvfl;v!F1_U|%}(FncIE@liT zPhZ9-E0yNd_iblHBG_%aMUu2qMb?Twv~aQOCT#@axv(}r0T*H6#xKCoh!a_yHdMAcUA6oN&{H~=A&yL@m7>4ojl zKx*B&1zp;bgd*?|vBdCyj-Dwcn`u|KF{H(Z8!kF3MMFivSSf+>epLmBH(HCK_(@LW zBz||rVw1m<_R0nwJ&)W(S9XTHFnJ-Tg7j746}7+`i-wS=BXJ@Fl~a8V6^dREu#PAd zC1|BKFgpOj777{7b$d2+3yc2c-2ICLJ=XA5M?d%;wLEla)g;Fjv7pseYow% zKR8;vDI7HBd#VZ!8h7#@++W2oBPA@>Q^an=YT}PN&v=7nB1FtLv*$VUzL`=V?6670 zZKFMTI(2v=kii!xKO9TJ(~$(8kLw6~SVi=NR1kY+)T6VBsG4_nQymrn1`|KgC@KNf z-)Y)pRe+w?&INtr-1lo)*}N{;BAB!!Li8b)1lIC~?1r_07tq>jrc6IN`|a5s&Pw^_ z577WK*RS=eh3lm_U}U*wW|T{TFMWXVxEZ18>S$3%Pw3kZZmO$aG$xV-o>TQJBS*u< zw3@4kmrqRMVvMu5hvR&DAf<)u#uLtM4MPM3qSg@8cu$I)62r{Oi48*!AR z`^OyW@9ByL05|)Ysw^M2pHVBSZzyC)=;mK?4V397RR1IX_nX%0$jzXUBAL z)y-VH>24;!h*tCJ8ds94T`NV;Q!qqxxLF^*3XC&xsg<$poO=>9{)T}RRHnTLSzI>! zaD{?9;bKfvJ1@@b+Ia=e2ujnd)$Lx4vILZN3?#ooT;c&Ub$X#le7!id8aE2oH;a~n z=0_zp__}n{kt^6N`VXt-_J54(3q%L@x{hMLRH@QhBE*)qL^Q&iv2kPILd12hO;+5e%r_g0RBo%~8>9Ayf1)ALVC9XZ=IiUaYyPgIg5Y9wVK51H zf~;2af$Yw~k9ml4pAAyov0pjFE~(0Ql@g3D)X@B!D1TPN8G0pAVt zdCqtQ!@I}HRXPvwg4vX#Z=RV%ETJCU4TUh*R!}QL)B@V!O!##vIyK)bGQIS^&@^7B zgQ-Sz*I_JhRqaPw1RhkKjzA|yYskqfF7C7a5|Q(a@+69W($O_n*I?2GM3k~RHeo#b zuXJC#=BJ4S%P&y0PFcW1?HEeo2Jwl^U=LYBHS(AUh94aT>?h5sBcZYh9_W~KK!f|| zJ&FEEIH{f}bt5xtx*HCPL;hQ4+tH<8WcJT9Wc~lD-i}B*%4$NUdp%8y4e>3&W@~uc zOSSzT*?yp=k)cwn=50I5W}&Pf#5+#kyZ!Cf(nQDMpBR1qN;>JI)UToD0oFG{vX=Aw zhCx)_^($0LBwITS*s>*&1XlIG zUvp{;`MrZ9!*WbMnTU}6fzt()V09noJ&!6&9jVMmZ_hWn5vE8lfQGpR{1*UC0?B~0 zSIYh(R5_SLq(=&;G9zaBj-2b(vdIs2r1>EqHY`(b?wUV8mI<@wDES^$bEPw{=qybe)bFlT zSr)gi55&Zg!uyK7qitvB-f|n_8M)arWfb+sWza`04I?b z5@N};qy8kZ);WHzRh|DLFE+T`1@A20fUJa4?|Ua!zH-a5w zta-9~AcUHho;SVAN+T?2Dsla&Mp#!~=L^S@4>3VvRT+-IQwz;qg-3^eL%K_uti;SB zDs*xe99DfehP3HXg2mM0ZRlbwRlY8%+>$r;;rabY!?g9JZe~!&8f;)QxeqMwGyOg4 zqkBYKT|PwEq9s>c&dOf+E}5C980!*}%I4h@>Q&DV`v`gT&!YU_Xt|B*64=1gqO9NBLv-D~d^g3} z446iT@0{#W&n$JB;nXKC(X?b0B3c&hcVnb}mAN2Hy>eo+U%{KZdsY3f^S4B&&}-x$ z6G4gXZL#x{L<-F!j9bhza@vkIpkCv3OVj!Wzn!D&_tZ_zGjE_*#?lU?i0YTivBrggu z>{q^S^pjV$&Yj~|h@;m>Ah6)~}iMB=ZiH#o=c*+eES*9p&Uy-~Bdb zUKku&E32@V1jNnY5L#!iNSYzPi)O*nLk?CHpRQpYLDHcieZO@V^>-!Ljz0W^z>!9X z?3ywX%6~MsK}k{)8B%q@y`gz)Dua1-^vrj*a3JS$wB8#p$eQ;8FvIzGJ9R${ozv(M zi)BdMDs0O3IjdI9UI!Z<&@`_#;%yqjL7wf@?%9i>_cJ8M~9zOLj5Rt-JrnYqcozSbA&is<()g<=NCYqeW|jFk&=q4 z(Gm>mM{z#l^2WMnnXxDLkAq<=OK?gJ)`0>4w;8Ly(c`M5QE9@K(&_&tr42x~f$ZD- zfGDLHLmezT+|Ch36X|nbm7__xjTcu8Y0M;0NM`c;RA2d8i{hWwE7<`H-omU^Ydj=M z((7a*r3m4jDr>_)*1Ti~l^_9~s47{Fm3#8Rpxh_H4Q}GKRt>f+?OM^R*2|gVp?QG_ zozYN1a~%rI(-DXF91=!xcN2k8iE{$Yzo)ln29K|p+*?sGqGFOoD6S`)Uytf7Vqu^# zkYa9#k2iEMkhjL8wKbVT?yvb{UUECd^+AnCjYpkuW0lZkfL~*s@FLzlMnl^xPb7i| zKtMu5L_$S+`&!ZQFH!Vwi3Kv=J8Eux8c7sf0xlj+EwjQ8w7gPoAw7Q@q=D0fAI+2K zG|vBHj9!Z|BoJPS`*tZinxSyV4zT=S80d%n-uC{jF^7q#Jqy}3C!s*UPIS&T>wucK zJ0b72`#JAlS)aD>ELyNco0bkJ#kuAAIjM_ zrg4cP-M`Bq3yyO;xLc%h`S+4RRlE%Zf$S!MN0s4iobPp>w~U3Wo_gCkpoQ0n0nN|hw4I9&*LwEc9&q=nDlS>t8SL-Z`7+B<7p%KQz?Ng_@ZWK`bTnOMK28INK3V-!7$1kEL-BoaYi05BVCAc8rcO3_#1{hqo&RrLsHhJ16=RRzPyvPk8&fop3X zTkAL5)-N0%mWfe+1LeE{71TeN%-o1>&`#|j>Es_3)}z0lkbbklq4*lpWI~PQA#lNB zKfo743`>D#qhzmxz=hpWmFGVL=+TG2)SG+OF!Ue=RmHA{{~i_-1Mb;QyXhv_&a^@M ze|LD1A}r;1gMpyMrnjD&H)Gt7gYa*)R*D0~T|bHzlFSLg4EXN`sMLedni_?mNG9{* z$=)rRm0qGtapHyI`G%fvTg`$hV@0AO(Hdg!*K3;8wi3xUYUkfBb8U-t-AZ6VwJ>++ zuAN>0ZVez!c?v9c@*)6nOQQawGydVW&%gv|&av#B7%cTZXbXZ=8wu**+l|?J0Z9D$ zo^;`tXuFj%|LLcZd(EIPC%@((hr31-{~lTvEmHP$-QQ)Qp6*n;i~D6|wUvBRc85S9 z)8P{LfGbVxdfZvo1y?+YoNs4p_^JFuD~+@N3DasCrsK7ER0IpSk|H2BUr2jm>P zi?J+Tv)H>rsLF|95_~dm6l6o>m_68b^SjK^vBBJKEGZkYq^wVyg)Klt#cr`B5kH%X zn>qC){4BwXHg^njqC1CRgkt-Ww6l9Oua%+>=7VIVsEk~{#|$kW0EAsgvFS&~g%Uew z-(?>6$kj|D^eHDCc&;R`a|XNQL%{?S

9^j#&h57vW{xaZ8`)?&1W|`kIb)-s$GM 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%0DCr>K*u}cNq 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

Nq~ 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 literal 0 HcmV?d00001 diff --git a/boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core_usb.jpg b/boards/riscv/esp32c3_luatos_core/doc/img/esp32c3_luatos_core_usb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10ccc8d0cf1b66a518a29d07d1ebaad40e86e871 GIT binary patch literal 54920 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 E*$iG4SpWb4 literal 0 HcmV?d00001 diff --git a/boards/riscv/esp32c3_luatos_core/doc/index.rst b/boards/riscv/esp32c3_luatos_core/doc/index.rst new file mode 100644 index 00000000000..75f1f3c5e6a --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/doc/index.rst @@ -0,0 +1,259 @@ +.. _esp32c3_luatos_core: + +ESP32C3_LUATOS_CORE +################### + +Overview +******** + +ESP32-C3 is a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, +based on the open-source RISC-V architecture. It strikes the right balance of power, +I/O capabilities and security, thus offering the optimal cost-effective +solution for connected devices. +The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, +but it also facilitates a variety of use-cases based on dual connectivity. [1]_ + +The features include the following: + +- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz +- 400 KB of internal RAM +- 802.11b/g/n/e/i +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth mesh +- Various peripherals: + + - 12-bit ADC with up to 6 channels + - TWAI compatible with CAN bus 2.0 + - Temperature sensor + - 3x SPI + - 1x I2S + - 1x I2C + - 2x UART + - LED PWM with up to 6 channels + +- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) + +There are two version hardware of this board. The difference between them is the ch343 chip. + +1. USB-C connect to UART over CH343 chip(esp32c3_luatos_core) + +.. image:: img/esp32c3_luatos_core.jpg + :align: center + :alt: esp32c3_luatos_core + +2. USB-C connect to esp32 chip directly(esp32c3_luatos_core_usb) + +.. image:: img/esp32c3_luatos_core_usb.jpg + :align: center + :alt: esp32c3_luatos_core_usb + +Supported Features +================== + +Current Zephyr's ESP32C3_LUATOS_CORE board supports the following features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ ++------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++------------+------------+-------------------------------------+ +| USB-JTAG | on-chip | hardware interface | ++------------+------------+-------------------------------------+ +| SPI Master | on-chip | spi | ++------------+------------+-------------------------------------+ +| Timers | on-chip | counter | ++------------+------------+-------------------------------------+ +| Watchdog | on-chip | watchdog | ++------------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++------------+------------+-------------------------------------+ +| LEDC | on-chip | pwm | ++------------+------------+-------------------------------------+ +| SPI DMA | on-chip | spi | ++------------+------------+-------------------------------------+ +| TWAI | on-chip | can | ++------------+------------+-------------------------------------+ +| USB-CDC | on-chip | serial | ++------------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++------------+------------+-------------------------------------+ +| Wi-Fi | on-chip | | ++------------+------------+-------------------------------------+ +| Bluetooth | on-chip | | ++------------+------------+-------------------------------------+ + +.. image:: img/esp32c3_luatos_core_pinfunc.jpg + :align: center + :alt: esp32c3_luatos_core_pinfunc + +System requirements +******************* + +Prerequisites +============= + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +ESP-IDF bootloader +================== + +The board is using the ESP-IDF bootloader as the default 2nd stage bootloader. +It is build as a subproject at each application build. No further attention +is expected from the user. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be build (and flash) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + ``` + CONFIG_BOOTLOADER_MCUBOOT=y + ``` + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the EPS32 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :app: samples/hello_world + :board: esp32c3_luatos_core + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │   └── zephyr + │   ├── zephyr.elf + │   └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be build one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_luatos_core + :goals: build + +The usual ``flash`` target will work with the ``esp32c3_luatos_core`` board +configuration. Here is an example for the :ref:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_luatos_core + :goals: flash + +Open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! esp32c3_luatos_core + +Debugging +********* + +As with much custom hardware, the ESP32-C3 modules require patches to +OpenOCD that are not upstreamed yet. Espressif maintains their own fork of +the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_ + +The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the +``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` +parameter when building. + +Here is an example for building the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_luatos_core + :goals: build flash + :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= + +You can debug an application in the usual way. Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_luatos_core + :goals: debug + +.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases + +References +********** + +.. [1] https://www.espressif.com/en/products/socs/esp32-c3 +.. _ESP32C3 Core Website: https://wiki.luatos.com/chips/esp32c3/board.html +.. _ESP32C3 Technical Reference Manual: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf +.. _ESP32C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi new file mode 100644 index 00000000000..c775009d8d5 --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + twai_default: twai_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dts b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dts new file mode 100644 index 00000000000..5a74be9984e --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "esp32c3_luatos_core.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + }; +}; diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dtsi b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dtsi new file mode 100644 index 00000000000..2a1a74996c5 --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.dtsi @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp32c3_luatos_core-pinctrl.dtsi" +#include + +/ { + model = "esp32c3_luatos_core"; + compatible = "espressif,esp32c3"; + + aliases { + sw0 = &user_button1; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + led0 = &led_d4; + led1 = &led_d5; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button1: button_1 { + label = "User SW1"; + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_d4: led_1 { + label = "D4"; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + led_d5: led_2 { + label = "D5"; + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&trng0 { + status = "okay"; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&timer0 { + status = "disabled"; +}; + +&timer1 { + status = "disabled"; +}; + +&twai { + /* requires external CAN transceiver or jumper on RX and TX pins for loopback testing */ + status = "disabled"; + pinctrl-0 = <&twai_default>; + pinctrl-names = "default"; + bus-speed = <125000>; +}; + +&flash0 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 60kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000F000>; + read-only; + }; + + /* Reserve 1024kB for the application in slot 0 */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + /* Reserve 1024kB for the application in slot 1 */ + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + /* Reserve 256kB for the scratch partition */ + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml new file mode 100644 index 00000000000..da27504e274 --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml @@ -0,0 +1,21 @@ +identifier: esp32c3_luatos_core +name: ESP32C3 LuatOS Core +type: mcu +arch: riscv32 +toolchain: + - zephyr +supported: + - adc + - gpio + - i2c + - watchdog + - uart + - dma + - pwm + - spi + - counter + - entropy +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_defconfig b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_defconfig new file mode 100644 index 00000000000..d3f8458a2ef --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOARD_ESP32C3_LUATOS_CORE=y +CONFIG_SOC_SERIES_ESP32C3=y + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.dts b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.dts new file mode 100644 index 00000000000..f7e99f9b776 --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "esp32c3_luatos_core.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + }; +}; + +&uart0 { + status = "disabled"; +}; + +&usb_serial { + status = "okay"; +}; diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml new file mode 100644 index 00000000000..5e5b13c76cf --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml @@ -0,0 +1,21 @@ +identifier: esp32c3_luatos_core_usb +name: ESP32C3 LuatOS Core USB +type: mcu +arch: riscv32 +toolchain: + - zephyr +supported: + - adc + - gpio + - i2c + - watchdog + - uart + - dma + - pwm + - spi + - counter + - entropy +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb_defconfig b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb_defconfig new file mode 100644 index 00000000000..0a441dde0bb --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb_defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOARD_ESP32C3_LUATOS_CORE_USB=y +CONFIG_SOC_SERIES_ESP32C3=y + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/riscv/esp32c3_luatos_core/support/openocd.cfg b/boards/riscv/esp32c3_luatos_core/support/openocd.cfg new file mode 100644 index 00000000000..b93b20ba46e --- /dev/null +++ b/boards/riscv/esp32c3_luatos_core/support/openocd.cfg @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 +set ESP_RTOS none + +# ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). +# Uncomment the line below to enable USB debugging. +source [find interface/esp_usb_jtag.cfg] + +# Otherwise, use external JTAG programmer as ESP-Prog +# source [find interface/ftdi/esp32_devkitj_v1.cfg] + +source [find target/esp32c3.cfg] +adapter_khz 5000 From 8704419126061d30eaa09ad30811eb6d256154c0 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 14:21:44 +0800 Subject: [PATCH 0485/4498] Samples: net: wifi: add esp32c3_luatos_core board add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- samples/net/wifi/boards/esp32c3_luatos_core.conf | 12 ++++++++++++ samples/net/wifi/boards/esp32c3_luatos_core.overlay | 9 +++++++++ samples/net/wifi/boards/esp32c3_luatos_core_usb.conf | 12 ++++++++++++ .../net/wifi/boards/esp32c3_luatos_core_usb.overlay | 9 +++++++++ 4 files changed, 42 insertions(+) create mode 100644 samples/net/wifi/boards/esp32c3_luatos_core.conf create mode 100644 samples/net/wifi/boards/esp32c3_luatos_core.overlay create mode 100644 samples/net/wifi/boards/esp32c3_luatos_core_usb.conf create mode 100644 samples/net/wifi/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/net/wifi/boards/esp32c3_luatos_core.conf b/samples/net/wifi/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..5c37cfc402d --- /dev/null +++ b/samples/net/wifi/boards/esp32c3_luatos_core.conf @@ -0,0 +1,12 @@ +CONFIG_WIFI=y +CONFIG_HEAP_MEM_POOL_SIZE=98304 + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y + +CONFIG_NET_LOG=y diff --git a/samples/net/wifi/boards/esp32c3_luatos_core.overlay b/samples/net/wifi/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..ea9865cf5f8 --- /dev/null +++ b/samples/net/wifi/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; diff --git a/samples/net/wifi/boards/esp32c3_luatos_core_usb.conf b/samples/net/wifi/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..5c37cfc402d --- /dev/null +++ b/samples/net/wifi/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,12 @@ +CONFIG_WIFI=y +CONFIG_HEAP_MEM_POOL_SIZE=98304 + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y + +CONFIG_NET_LOG=y diff --git a/samples/net/wifi/boards/esp32c3_luatos_core_usb.overlay b/samples/net/wifi/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..ea9865cf5f8 --- /dev/null +++ b/samples/net/wifi/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; From 10d66c4f6353d7f14ac96225016a67bc9a14d025 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 06:36:49 +0800 Subject: [PATCH 0486/4498] samples: subsys: nvs: add esp32s3_luatos_core add conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- samples/subsys/nvs/boards/esp32c3_luatos_core.conf | 1 + samples/subsys/nvs/boards/esp32c3_luatos_core_usb.conf | 1 + 2 files changed, 2 insertions(+) create mode 100644 samples/subsys/nvs/boards/esp32c3_luatos_core.conf create mode 100644 samples/subsys/nvs/boards/esp32c3_luatos_core_usb.conf diff --git a/samples/subsys/nvs/boards/esp32c3_luatos_core.conf b/samples/subsys/nvs/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..26d52701286 --- /dev/null +++ b/samples/subsys/nvs/boards/esp32c3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 diff --git a/samples/subsys/nvs/boards/esp32c3_luatos_core_usb.conf b/samples/subsys/nvs/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..26d52701286 --- /dev/null +++ b/samples/subsys/nvs/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 From 8a29fb5fa5f68b24feff202cddbcdf4bafbbe5b2 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 06:45:09 +0800 Subject: [PATCH 0487/4498] samples: subsys: settings: add esp32s3_luatos_core add conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- samples/subsys/settings/boards/esp32c3_luatos_core.conf | 4 ++++ samples/subsys/settings/boards/esp32c3_luatos_core_usb.conf | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 samples/subsys/settings/boards/esp32c3_luatos_core.conf create mode 100644 samples/subsys/settings/boards/esp32c3_luatos_core_usb.conf diff --git a/samples/subsys/settings/boards/esp32c3_luatos_core.conf b/samples/subsys/settings/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..498fb072287 --- /dev/null +++ b/samples/subsys/settings/boards/esp32c3_luatos_core.conf @@ -0,0 +1,4 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/samples/subsys/settings/boards/esp32c3_luatos_core_usb.conf b/samples/subsys/settings/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..498fb072287 --- /dev/null +++ b/samples/subsys/settings/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,4 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y From ff264dc03e3f60bd932f8c5bef2aef791b1edf46 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 06:48:01 +0800 Subject: [PATCH 0488/4498] samples: boards: deepsleep: add esp32s3_luatos_core add overlay and conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.conf | 1 + .../boards/esp32c3_luatos_core.overlay | 21 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 1 + .../boards/esp32c3_luatos_core_usb.overlay | 21 +++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.conf create mode 100644 samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.overlay create mode 100644 samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.conf create mode 100644 samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.conf b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..2ce9f6b8f5c --- /dev/null +++ b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_EXAMPLE_GPIO_WAKEUP=y diff --git a/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.overlay b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..6235a933aec --- /dev/null +++ b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* On ESP32-C3, only GPIO0~5 can be used + * as wake-up sources + */ + wakeup-button = &sample_button; + }; + + gpio_keys { + compatible = "gpio-keys"; + sample_button: sample_button { + gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + }; + }; +}; diff --git a/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.conf b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..2ce9f6b8f5c --- /dev/null +++ b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_EXAMPLE_GPIO_WAKEUP=y diff --git a/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.overlay b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..6235a933aec --- /dev/null +++ b/samples/boards/esp32/deep_sleep/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* On ESP32-C3, only GPIO0~5 can be used + * as wake-up sources + */ + wakeup-button = &sample_button; + }; + + gpio_keys { + compatible = "gpio-keys"; + sample_button: sample_button { + gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + }; + }; +}; From 8876e9d7333caa8e157737988f3724bdc1b0191a Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 06:50:30 +0800 Subject: [PATCH 0489/4498] samples: drivers: counter: add esp32s3_luatos_core add overlay and conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../drivers/counter/alarm/boards/esp32c3_luatos_core.overlay | 3 +++ .../counter/alarm/boards/esp32c3_luatos_core_usb.overlay | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 samples/drivers/counter/alarm/boards/esp32c3_luatos_core.overlay create mode 100644 samples/drivers/counter/alarm/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/drivers/counter/alarm/boards/esp32c3_luatos_core.overlay b/samples/drivers/counter/alarm/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/esp32c3_luatos_core_usb.overlay b/samples/drivers/counter/alarm/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; From 75778574da6afe3729a9414852c709005771aa60 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 07:01:36 +0800 Subject: [PATCH 0490/4498] samples: drivers: adc: add esp32s3_luatos_core add overlay and conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../adc/boards/esp32c3_luatos_core.overlay | 41 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.overlay | 41 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 samples/drivers/adc/boards/esp32c3_luatos_core.overlay create mode 100644 samples/drivers/adc/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/drivers/adc/boards/esp32c3_luatos_core.overlay b/samples/drivers/adc/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..d43209179f7 --- /dev/null +++ b/samples/drivers/adc/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = + <&adc0 0>, + <&adc1 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/boards/esp32c3_luatos_core_usb.overlay b/samples/drivers/adc/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..d43209179f7 --- /dev/null +++ b/samples/drivers/adc/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = + <&adc0 0>, + <&adc1 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 8092b8d96b0385e0e7bb050e8498c71f4cb58126 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 07:03:19 +0800 Subject: [PATCH 0491/4498] samples: sensor: die temp: add esp32s3_luatos_core add overlay and conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../die_temp_polling/boards/esp32c3_luatos_core.conf | 1 + .../boards/esp32c3_luatos_core.overlay | 11 +++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 1 + .../boards/esp32c3_luatos_core_usb.overlay | 11 +++++++++++ 4 files changed, 24 insertions(+) create mode 100644 samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf create mode 100644 samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.overlay create mode 100644 samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf create mode 100644 samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..13ed95d4291 --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_NEWLIB_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.overlay b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..55c2a4c86ae --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023, Hiroki Tada + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for creating temperature sensor device instance + */ + +&coretemp { + status = "okay"; +}; diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..13ed95d4291 --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_NEWLIB_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.overlay b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..55c2a4c86ae --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023, Hiroki Tada + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for creating temperature sensor device instance + */ + +&coretemp { + status = "okay"; +}; From 49e5394e1c7180d22713616db09c562fb3516b6d Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 26 Aug 2023 07:04:21 +0800 Subject: [PATCH 0492/4498] samples: basic: blinkypwm: add esp32s3_luatos_core add overlay and conf file for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.overlay | 45 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.overlay | 45 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 samples/basic/blinky_pwm/boards/esp32c3_luatos_core.overlay create mode 100644 samples/basic/blinky_pwm/boards/esp32c3_luatos_core_usb.overlay diff --git a/samples/basic/blinky_pwm/boards/esp32c3_luatos_core.overlay b/samples/basic/blinky_pwm/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..a438cc5246b --- /dev/null +++ b/samples/basic/blinky_pwm/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2021 Andrei-Edward Popa + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + pwm-led0 = &pwm_led_blue; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led_blue: pwm_led_gpio0_2 { + label = "PWM LED0"; + pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/samples/basic/blinky_pwm/boards/esp32c3_luatos_core_usb.overlay b/samples/basic/blinky_pwm/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..a438cc5246b --- /dev/null +++ b/samples/basic/blinky_pwm/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2021 Andrei-Edward Popa + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + pwm-led0 = &pwm_led_blue; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led_blue: pwm_led_gpio0_2 { + label = "PWM LED0"; + pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; From 7caaafd5f46e36e9e4d04fbed59d8ef47961d2b7 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:34:52 +0800 Subject: [PATCH 0493/4498] tests: drivers: adc: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../adc_api/boards/esp32c3_luatos_core.conf | 1 + .../boards/esp32c3_luatos_core.overlay | 35 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 1 + .../boards/esp32c3_luatos_core_usb.overlay | 35 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.conf create mode 100644 tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.conf b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..b6c5c80f924 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_ADC_ASYNC=n diff --git a/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.overlay b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..c288312aa3a --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Wolter HV + * Copyright (c) 2023 Benjamin Björnsson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..b6c5c80f924 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_ADC_ASYNC=n diff --git a/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..c288312aa3a --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Wolter HV + * Copyright (c) 2023 Benjamin Björnsson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 4337bbab82b626e7d4ab12fda1834132bb77ed26 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:35:15 +0800 Subject: [PATCH 0494/4498] tests: drivers: counter: add esp32c3_luatos_core add overlay for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../counter_basic_api/boards/esp32c3_luatos_core.overlay | 3 +++ .../counter_basic_api/boards/esp32c3_luatos_core_usb.overlay | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core.overlay b/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; diff --git a/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; From 8283e639a1157ee6d8c012595700b0c67194d173 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:35:32 +0800 Subject: [PATCH 0495/4498] tests: drivers: dma: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.conf | 3 +++ .../boards/esp32c3_luatos_core.overlay | 11 +++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 3 +++ .../boards/esp32c3_luatos_core_usb.overlay | 11 +++++++++++ 4 files changed, 28 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.conf b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..56bf25e718b --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.conf @@ -0,0 +1,3 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=5 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=0 +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.overlay b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..9098b0dd5b9 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..56bf25e718b --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,3 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=5 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=0 +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..9098b0dd5b9 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; From bd7db23a0aa1ebdd30a650d0bd1332ad83889481 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:35:48 +0800 Subject: [PATCH 0496/4498] tests: drivers: dma: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../dma/loop_transfer/boards/esp32c3_luatos_core.conf | 2 ++ .../loop_transfer/boards/esp32c3_luatos_core.overlay | 11 +++++++++++ .../loop_transfer/boards/esp32c3_luatos_core_usb.conf | 2 ++ .../boards/esp32c3_luatos_core_usb.overlay | 11 +++++++++++ 4 files changed, 26 insertions(+) create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.conf b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..311bfc8f535 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR=0 +CONFIG_DMA_LOOP_TRANSFER_SIZE=4094 diff --git a/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.overlay b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..9098b0dd5b9 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; diff --git a/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..311bfc8f535 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR=0 +CONFIG_DMA_LOOP_TRANSFER_SIZE=4094 diff --git a/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..9098b0dd5b9 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; From b83a0580aafbb0584930006530420132d88ca002 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:36:07 +0800 Subject: [PATCH 0497/4498] tests: drivers: flash: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- tests/drivers/flash/common/boards/esp32c3_luatos_core.conf | 1 + tests/drivers/flash/common/boards/esp32c3_luatos_core_usb.conf | 1 + 2 files changed, 2 insertions(+) create mode 100644 tests/drivers/flash/common/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/flash/common/boards/esp32c3_luatos_core_usb.conf diff --git a/tests/drivers/flash/common/boards/esp32c3_luatos_core.conf b/tests/drivers/flash/common/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..2bcf636958b --- /dev/null +++ b/tests/drivers/flash/common/boards/esp32c3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=16384 diff --git a/tests/drivers/flash/common/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/flash/common/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..2bcf636958b --- /dev/null +++ b/tests/drivers/flash/common/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=16384 From 0c867d310cc886aba302fbd69e101549d31e846c Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:36:27 +0800 Subject: [PATCH 0498/4498] tests: drivers: gpio: add esp32c3_luatos_core add overlay for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.overlay | 13 +++++++++++++ .../boards/esp32c3_luatos_core_usb.overlay | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core.overlay b/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..6c4f3e2e226 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio0 4 0>; + in-gpios = <&gpio0 5 0>; + }; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..6c4f3e2e226 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio0 4 0>; + in-gpios = <&gpio0 5 0>; + }; +}; From ca6168c723f33921185e70084aa489c5001fc70a Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:36:45 +0800 Subject: [PATCH 0499/4498] tests: drivers: pwm: add esp32c3_luatos_core add overlay for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.overlay | 35 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.overlay | 35 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core.overlay b/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..5c0a5285e6e --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..5c0a5285e6e --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; From 27df7aa0ce303e9ba34e6832c7f7fe8d1b965e6d Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:36:59 +0800 Subject: [PATCH 0500/4498] tests: drivers: spi: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.conf | 2 + .../boards/esp32c3_luatos_core.overlay | 40 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 2 + .../boards/esp32c3_luatos_core_usb.overlay | 40 +++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.conf b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..3438f794f66 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_ESP32_INTERRUPT=y +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.overlay b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..8e5037e7691 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Kumar Gala + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spim2_loopback: spim2_loopback { + group1 { + pinmux = ; + output-enable; /* Enable internal loopback */ + }; + group2 { + pinmux = ; + input-enable; /* Enable internal loopback */ + }; + group3 { + pinmux = , + ; + }; + }; +}; + +&spi2 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&spi2 { + dma-enabled; + pinctrl-0 = <&spim2_loopback>; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..3438f794f66 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_ESP32_INTERRUPT=y +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..8e5037e7691 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Kumar Gala + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spim2_loopback: spim2_loopback { + group1 { + pinmux = ; + output-enable; /* Enable internal loopback */ + }; + group2 { + pinmux = ; + input-enable; /* Enable internal loopback */ + }; + group3 { + pinmux = , + ; + }; + }; +}; + +&spi2 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&spi2 { + dma-enabled; + pinctrl-0 = <&spim2_loopback>; +}; From 641a70f3b80f0c60fbc81fd213bc85e3771eba8e Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 14:05:07 +0800 Subject: [PATCH 0501/4498] tests: drivers: uart: add esp32c3_luatos_core add overlay and conf for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.conf | 2 ++ .../boards/esp32c3_luatos_core.overlay | 31 ++++++++++++++++ .../boards/esp32c3_luatos_core_usb.conf | 2 ++ .../boards/esp32c3_luatos_core_usb.overlay | 36 +++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.conf create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.overlay create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.conf create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.conf b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.conf new file mode 100644 index 00000000000..76f7644d896 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.conf @@ -0,0 +1,2 @@ +CONFIG_HEAP_MEM_POOL_SIZE=32768 +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.overlay b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..3582e7dcf94 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + dmas = <&dma 0>, <&dma 1>; + dma-names = "rx", "tx"; +}; + +&dma { + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.conf b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.conf new file mode 100644 index 00000000000..76f7644d896 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.conf @@ -0,0 +1,2 @@ +CONFIG_HEAP_MEM_POOL_SIZE=32768 +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.overlay b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..c23a4f9a0b4 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + dmas = <&dma 0>, <&dma 1>; + dma-names = "rx", "tx"; +}; + +&dma { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; From 6c3e5be8f74d9fd46954cb067115b442adc9acea Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:37:29 +0800 Subject: [PATCH 0502/4498] tests: drivers: debug: add esp32c3_luatos_core add overlay for esp32c3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32c3_luatos_core.overlay | 25 +++++++++++++++++++ .../boards/esp32c3_luatos_core_usb.overlay | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core.overlay create mode 100644 tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core_usb.overlay diff --git a/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core.overlay b/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core.overlay new file mode 100644 index 00000000000..eb707ee7221 --- /dev/null +++ b/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + partitions { + /* + * Reduce storage_partition to make space for + * coredump_partition + */ + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00005000>; + }; + + coredump_partition: partition@255000 { + label = "coredump-partition"; + reg = <0x255000 DT_SIZE_K(4)>; + }; + + }; +}; diff --git a/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core_usb.overlay b/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core_usb.overlay new file mode 100644 index 00000000000..eb707ee7221 --- /dev/null +++ b/tests/subsys/debug/coredump_backends/boards/esp32c3_luatos_core_usb.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + partitions { + /* + * Reduce storage_partition to make space for + * coredump_partition + */ + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00005000>; + }; + + coredump_partition: partition@255000 { + label = "coredump-partition"; + reg = <0x255000 DT_SIZE_K(4)>; + }; + + }; +}; From 71dbeeb08446cf85f3a7513aab3894bf7446208e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 11:50:51 +0000 Subject: [PATCH 0503/4498] sys: util: fix parameter documentation Second one should have been "b". Signed-off-by: Fabio Baltieri --- include/zephyr/sys/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index 29488e23b91..b3cbb917b46 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -206,7 +206,7 @@ extern "C" { * @brief Validate if two entities have a compatible type * * @param a the first entity to be compared - * @param a the second entity to be compared + * @param b the second entity to be compared * @return 1 if the two elements are compatible, 0 if they are not */ #define SAME_TYPE(a, b) __builtin_types_compatible_p(__typeof__(a), __typeof__(b)) From 8bd49da316fcf949a24ae4f70ab7bbda00a63e5f Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 11:55:35 +0000 Subject: [PATCH 0504/4498] doc: doxygen: define XEN_GUEST_HANDLE_64 as no-op Doxygen gets confused by the macro expansion in include/zephyr/xen/public/domctl.h as that is only defined if CONFIG_ARM64=y, add a no-op expansion of that macro when building the documention so it has something to work on. Signed-off-by: Fabio Baltieri --- doc/zephyr.doxyfile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index a66110b6d05..6d5ad2793bc 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -2391,6 +2391,7 @@ PREDEFINED = __DOXYGEN__ \ NET_MGMT_DEFINE_REQUEST_HANDLER(x)= \ DEVICE_DEFINE()= \ BUILD_ASSERT()= \ + XEN_GUEST_HANDLE_64(x)= \ _LINKER \ __deprecated= \ __packed= \ From 764c440613255950bed999860cddbf8ac1bed8c0 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 10:24:50 +0200 Subject: [PATCH 0505/4498] nrf_bsim: Include peripheral kconfig for all simulated nrf bords Include the nrf peripheral kconfig definitions for all simulated nrf boards, not just for the nrf52_bsim. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/posix/nrf52_bsim/Kconfig b/boards/posix/nrf52_bsim/Kconfig index ea1b49bea0a..4660e965275 100644 --- a/boards/posix/nrf52_bsim/Kconfig +++ b/boards/posix/nrf52_bsim/Kconfig @@ -1,14 +1,14 @@ # SPDX-License-Identifier: Apache-2.0 -if BOARD_NRF52_BSIM +if SOC_SERIES_BSIM_NRFXX # The following file is normally parsed only for the ARM architecture, which is # used by Nordic SoCs, so to make the symbols defined in this file available for -# the simulated nrf52_bsim board, which uses the POSIX architecture, the file +# the simulated nrf5x_bsim boards, which use the POSIX architecture, the file # must be read also from here. source "soc/arm/nordic_nrf/Kconfig.peripherals" -endif # BOARD_NRF52_BSIM +endif # SOC_SERIES_BSIM_NRFXX # This would eventually be shared by a possible family of simulated NRF boards From 1f71ad568660c21e40c91754f27dc9da6a870033 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 14:44:12 +0200 Subject: [PATCH 0506/4498] boards nrf_bsim: Include nrf52833 header only for nrf52_bsim Include the nrf52833.h header only for nrf52_bsim Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/common/cmsis/cmsis.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis.h b/boards/posix/nrf52_bsim/common/cmsis/cmsis.h index f40ae49a9b7..ff9030ca547 100644 --- a/boards/posix/nrf52_bsim/common/cmsis/cmsis.h +++ b/boards/posix/nrf52_bsim/common/cmsis/cmsis.h @@ -14,7 +14,9 @@ #include #include "cmsis_instr.h" +#if defined(CONFIG_SOC_COMPATIBLE_NRF52833) #include "nrf52833.h" +#endif #ifdef __cplusplus extern "C" { From b5a50e9ae12ff89044de21fb8917362d3c9373f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 8 Sep 2023 10:40:10 +0200 Subject: [PATCH 0507/4498] doc: Revert "doc: Add more known-warnings" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3127d7b54c22449fcc85dd1c59ca294885d5f997 which was forgotten when switching back to breathe from docleaf and causing unecessary "here's a warning about something that's not actually a warning" :) Signed-off-by: Benjamin Cabé --- doc/known-warnings.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/known-warnings.txt b/doc/known-warnings.txt index abe8e7eca13..35a0ed60b03 100644 --- a/doc/known-warnings.txt +++ b/doc/known-warnings.txt @@ -22,8 +22,3 @@ .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct in_addr.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct in6_addr.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct net_if.*'.* - -# Clash with field of nested anonymous struct -.*Duplicate C declaration.*\n.*'\.\. c:member:: enum *bt_mesh_dfd_upload_phase bt_mesh_dfd_srv.phase'.* -.*Duplicate C declaration.*\n.*'\.\. c:member:: struct *bt_mesh_blob_xfer bt_mesh_dfu_cli.blob'.* -.*Duplicate C declaration.*\n.*'\.\. c:member:: struct *net_if *\* net_if_mcast_monitor.iface'. From 4856fd4cb6ce13d7218d7993cce658463ef702c0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 13 Sep 2023 16:16:55 +0000 Subject: [PATCH 0508/4498] can: rework the table lookup code in can_dlc_to_bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework the can_dlc_to_bytes table lookup code in a way that allow the compiler to guess the resulting output and somehow fix the build warning: zephyr/drivers/can/can_nxp_s32_canxl.c:757:9: warning: '__builtin___memcpy_chk' forming offset [16, 71] is out of the bounds [0, 16] of object 'frame' with type 'struct can_frame' [-Warray-bounds] 757 | memcpy(frame->data, msg_data.data, can_dlc_to_bytes(frame->dlc)); where the compiler detects that frame->data is 8 bytes long but can_dlc_to_bytes could return more than that. Can be reproduced with: west build -p -b s32z270dc2_rtu1_r52 \ -T samples/net/sockets/can/sample.net.sockets.can.one_socket Suggested-by: Martin Jäger Signed-off-by: Fabio Baltieri --- include/zephyr/drivers/can.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 44f4b360689..15387afd2c4 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -1360,7 +1360,7 @@ static inline uint8_t can_dlc_to_bytes(uint8_t dlc) static const uint8_t dlc_table[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}; - return dlc > 0x0F ? 64 : dlc_table[dlc]; + return dlc_table[MIN(dlc, ARRAY_SIZE(dlc_table) - 1)]; } /** From 349306bda73cb262f95e1321cf68a0a6029e9b3f Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 14:40:08 +0200 Subject: [PATCH 0509/4498] bluetooth: audio: use SYS_INIT The device model was not used for anything useful, only to call some init code. Change to SYS_INIT instead. Signed-off-by: Gerard Marull-Paretas --- subsys/bluetooth/audio/bap_scan_delegator.c | 7 ++----- subsys/bluetooth/audio/tbs.c | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index c8ddbdcd704..251bd722ec4 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -1030,7 +1029,7 @@ BT_GATT_SERVICE_DEFINE(bass_svc, #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */ ); -static int bt_bap_scan_delegator_init(const struct device *unused) +static int bt_bap_scan_delegator_init(void) { /* Store the pointer to the first characteristic in each receive state */ scan_delegator.recv_states[0].attr = &bass_svc.attrs[3]; @@ -1049,9 +1048,7 @@ static int bt_bap_scan_delegator_init(const struct device *unused) return 0; } -DEVICE_DEFINE(bt_bap_scan_delegator, "bt_bap_scan_delegator", - &bt_bap_scan_delegator_init, NULL, NULL, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); +SYS_INIT(bt_bap_scan_delegator_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); /****************************** PUBLIC API ******************************/ void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb) diff --git a/subsys/bluetooth/audio/tbs.c b/subsys/bluetooth/audio/tbs.c index d8ef918fcd0..9159d2b2324 100644 --- a/subsys/bluetooth/audio/tbs.c +++ b/subsys/bluetooth/audio/tbs.c @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -1753,7 +1752,7 @@ static void signal_interval_timeout(struct k_work *work) } } -static int bt_tbs_init(const struct device *unused) +static int bt_tbs_init(void) { for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) { int err; @@ -1798,8 +1797,7 @@ static int bt_tbs_init(const struct device *unused) return 0; } -DEVICE_DEFINE(bt_tbs, "bt_tbs", &bt_tbs_init, NULL, NULL, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); +SYS_INIT(bt_tbs_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); /***************************** Profile API *****************************/ int bt_tbs_accept(uint8_t call_index) From 4f80e50b55d325999f6749354a6c8519b1d54096 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 16:11:40 +0200 Subject: [PATCH 0510/4498] bluetooth: controller: coex: convert to DT device Convert the driver to a dt-based device. Also update Kconfig so that it depends on the right compatible being enabled, initialize in POST_KERNEL (APPLICATION should not be used for devices) and remove one redundant include. Signed-off-by: Gerard Marull-Paretas --- samples/bluetooth/beacon/prj-coex.conf | 1 - subsys/bluetooth/controller/coex/Kconfig | 4 ++-- subsys/bluetooth/controller/coex/coex_ticker.c | 18 ++++++------------ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/samples/bluetooth/beacon/prj-coex.conf b/samples/bluetooth/beacon/prj-coex.conf index b16487f3999..eb9cd4bb16e 100644 --- a/samples/bluetooth/beacon/prj-coex.conf +++ b/samples/bluetooth/beacon/prj-coex.conf @@ -3,5 +3,4 @@ CONFIG_LOG=y CONFIG_BT_DEVICE_NAME="Test beacon" CONFIG_BT_LL_SW_SPLIT=y -CONFIG_BT_CTLR_COEX_DRIVERS=y CONFIG_BT_CTLR_COEX_TICKER=y diff --git a/subsys/bluetooth/controller/coex/Kconfig b/subsys/bluetooth/controller/coex/Kconfig index 31754fbf52c..b7bc7d30681 100644 --- a/subsys/bluetooth/controller/coex/Kconfig +++ b/subsys/bluetooth/controller/coex/Kconfig @@ -5,8 +5,8 @@ menuconfig BT_CTLR_COEX_DRIVERS bool "Bluetooth Co-existence Drivers" - default n - depends on BT_CTLR + default y + depends on BT_CTLR && DT_HAS_GPIO_RADIO_COEX_ENABLED if BT_CTLR_COEX_DRIVERS diff --git a/subsys/bluetooth/controller/coex/coex_ticker.c b/subsys/bluetooth/controller/coex/coex_ticker.c index 229e2f9e125..be349622ecd 100644 --- a/subsys/bluetooth/controller/coex/coex_ticker.c +++ b/subsys/bluetooth/controller/coex/coex_ticker.c @@ -4,12 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT gpio_radio_coex + #include #include #include #include -#include #include #include #include @@ -195,18 +196,11 @@ static int coex_ticker_init(const struct device *dev) return 0; } -#define RADIO_NODE DT_NODELABEL(radio) -#define COEX_NODE DT_PROP(RADIO_NODE, coex) - -#if DT_NODE_EXISTS(COEX_NODE) static struct coex_ticker_config config = { - .grant_spec = GPIO_DT_SPEC_GET(COEX_NODE, grant_gpios), - .grant_delay_us = DT_PROP(COEX_NODE, grant_delay_us) + .grant_spec = GPIO_DT_SPEC_INST_GET(0, grant_gpios), + .grant_delay_us = DT_INST_PROP(0, grant_delay_us) }; static struct coex_ticker_data data; -DEVICE_DEFINE(coex_ticker, "COEX_TICKER", &coex_ticker_init, NULL, - &data, &config, - APPLICATION, 90, - NULL); -#endif +DEVICE_DT_INST_DEFINE(0, &coex_ticker_init, NULL, &data, &config, + POST_KERNEL, 90, NULL); From 222409fa493b3a4b37a339ca876aa1317899ac82 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:06:55 +0200 Subject: [PATCH 0511/4498] drivers: display: move to POST_KERNEL There's no need to use APPLICATION level here. Signed-off-by: Gerard Marull-Paretas --- drivers/display/display_dummy.c | 2 +- drivers/display/display_sdl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/display/display_dummy.c b/drivers/display/display_dummy.c index dd49573f790..630ed57a045 100644 --- a/drivers/display/display_dummy.c +++ b/drivers/display/display_dummy.c @@ -142,7 +142,7 @@ static const struct display_driver_api dummy_display_api = { DEVICE_DT_INST_DEFINE(n, &dummy_display_init, NULL, \ &dd_data_##n, \ &dd_config_##n, \ - APPLICATION, \ + POST_KERNEL, \ CONFIG_DISPLAY_INIT_PRIORITY, \ &dummy_display_api); \ diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index f7ada84fbea..2a457249ede 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -374,7 +374,7 @@ static const struct display_driver_api sdl_display_api = { DEVICE_DT_INST_DEFINE(n, &sdl_display_init, NULL, \ &sdl_data_##n, \ &sdl_config_##n, \ - APPLICATION, \ + POST_KERNEL, \ CONFIG_DISPLAY_INIT_PRIORITY, \ &sdl_display_api); \ \ From fe2bca3020e204fb91229b72aaa7f29f08786b9b Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 14:45:07 +0200 Subject: [PATCH 0512/4498] drivers: fpga: move to POST_KERNEL Devices should be initialized either in pre-Kernel or post-Kernel stages. Signed-off-by: Gerard Marull-Paretas --- drivers/fpga/fpga_eos_s3.c | 2 +- drivers/fpga/fpga_zynqmp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/fpga/fpga_eos_s3.c b/drivers/fpga/fpga_eos_s3.c index a0e21226530..30841dd43bf 100644 --- a/drivers/fpga/fpga_eos_s3.c +++ b/drivers/fpga/fpga_eos_s3.c @@ -148,5 +148,5 @@ static const struct fpga_driver_api eos_s3_api = { .get_info = eos_s3_fpga_get_info }; -DEVICE_DT_DEFINE(DT_NODELABEL(fpga0), &eos_s3_fpga_init, NULL, &fpga_data, NULL, APPLICATION, +DEVICE_DT_DEFINE(DT_NODELABEL(fpga0), &eos_s3_fpga_init, NULL, &fpga_data, NULL, POST_KERNEL, CONFIG_FPGA_INIT_PRIORITY, &eos_s3_api); diff --git a/drivers/fpga/fpga_zynqmp.c b/drivers/fpga/fpga_zynqmp.c index 1be08d59b7d..8da54462fae 100644 --- a/drivers/fpga/fpga_zynqmp.c +++ b/drivers/fpga/fpga_zynqmp.c @@ -323,4 +323,4 @@ static const struct fpga_driver_api zynqmp_api = { }; DEVICE_DT_INST_DEFINE(0, &zynqmp_fpga_init, NULL, &fpga_data, NULL, - APPLICATION, CONFIG_FPGA_INIT_PRIORITY, &zynqmp_api); + POST_KERNEL, CONFIG_FPGA_INIT_PRIORITY, &zynqmp_api); From 4cf5d5cf8b84221310677706441b9324d04521d7 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:07:18 +0200 Subject: [PATCH 0513/4498] drivers: misc: ft8xx: move to POST_KERNEL level There's no need to use APPLICATION level. Also create a custom init level that runs late in the process (depends e.g. on SPI which runs at high priority level, 70). Signed-off-by: Gerard Marull-Paretas --- drivers/misc/ft8xx/Kconfig | 7 +++++++ drivers/misc/ft8xx/ft8xx.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/misc/ft8xx/Kconfig b/drivers/misc/ft8xx/Kconfig index 6cc3773e662..1123c188c12 100644 --- a/drivers/misc/ft8xx/Kconfig +++ b/drivers/misc/ft8xx/Kconfig @@ -10,3 +10,10 @@ config FT800 select SPI help Enable driver for FT800 controller. + +config FT800_INIT_PRIORITY + int "FT800 init priority" + default 90 + depends on FT800 + help + FT800 driver initialization priority in POST_KERNEL. diff --git a/drivers/misc/ft8xx/ft8xx.c b/drivers/misc/ft8xx/ft8xx.c index 9b71dd3c92a..1dcbe581b13 100644 --- a/drivers/misc/ft8xx/ft8xx.c +++ b/drivers/misc/ft8xx/ft8xx.c @@ -168,7 +168,7 @@ static int ft8xx_init(const struct device *dev) } DEVICE_DT_INST_DEFINE(0, ft8xx_init, NULL, &ft8xx_data, &ft8xx_config, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + POST_KERNEL, CONFIG_FT800_INIT_PRIORITY, NULL); int ft8xx_get_touch_tag(void) { From c7292efbda9902579966657ae5bc514bcda7033b Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:15:12 +0200 Subject: [PATCH 0514/4498] modules: lvgl: input: move to POST_KERNEL level devices need to be initialized in pre/post-Kernel. Signed-off-by: Gerard Marull-Paretas --- modules/lvgl/input/lvgl_button_input.c | 2 +- modules/lvgl/input/lvgl_encoder_input.c | 2 +- modules/lvgl/input/lvgl_pointer_input.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/lvgl/input/lvgl_button_input.c b/modules/lvgl/input/lvgl_button_input.c index d340721b556..5d6f64c82b6 100644 --- a/modules/lvgl/input/lvgl_button_input.c +++ b/modules/lvgl/input/lvgl_button_input.c @@ -80,7 +80,7 @@ static int lvgl_button_input_init(const struct device *dev) }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, lvgl_button_input_init, NULL, &lvgl_common_input_data_##inst, \ - &lvgl_button_input_config_##inst, APPLICATION, \ + &lvgl_button_input_config_##inst, POST_KERNEL, \ CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_BUTTON_INPUT_DEFINE) diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c index e126fb8911a..655275c7264 100644 --- a/modules/lvgl/input/lvgl_encoder_input.c +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -65,7 +65,7 @@ static int lvgl_encoder_input_init(const struct device *dev) }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, lvgl_encoder_input_init, NULL, &lvgl_common_input_data_##inst, \ - &lvgl_encoder_input_config_##inst, APPLICATION, \ + &lvgl_encoder_input_config_##inst, POST_KERNEL, \ CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_ENCODER_INPUT_DEFINE) diff --git a/modules/lvgl/input/lvgl_pointer_input.c b/modules/lvgl/input/lvgl_pointer_input.c index 483c36a456b..ed01a1d1515 100644 --- a/modules/lvgl/input/lvgl_pointer_input.c +++ b/modules/lvgl/input/lvgl_pointer_input.c @@ -124,7 +124,7 @@ static int lvgl_pointer_input_init(const struct device *dev) }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, lvgl_pointer_input_init, NULL, &lvgl_common_input_data_##inst, \ - &lvgl_pointer_input_config_##inst, APPLICATION, \ + &lvgl_pointer_input_config_##inst, POST_KERNEL, \ CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_POINTER_INPUT_DEFINE) From 4dd7bc997ffa6480afea93bb47236df04d36f7c4 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:12:21 +0200 Subject: [PATCH 0515/4498] samples: pm: move to POST_KERNEL There's no need to use APPLICATION level. Signed-off-by: Gerard Marull-Paretas --- samples/subsys/pm/device_pm/src/dummy_driver.c | 2 +- samples/subsys/pm/latency/src/test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/subsys/pm/device_pm/src/dummy_driver.c b/samples/subsys/pm/device_pm/src/dummy_driver.c index c0d0f3873be..9164da50bbe 100644 --- a/samples/subsys/pm/device_pm/src/dummy_driver.c +++ b/samples/subsys/pm/device_pm/src/dummy_driver.c @@ -115,5 +115,5 @@ int dummy_init(const struct device *dev) PM_DEVICE_DEFINE(dummy_driver, dummy_device_pm_action); DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init, - PM_DEVICE_GET(dummy_driver), NULL, NULL, APPLICATION, + PM_DEVICE_GET(dummy_driver), NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs); diff --git a/samples/subsys/pm/latency/src/test.c b/samples/subsys/pm/latency/src/test.c index b9d31f4415c..bf94c9c1bf8 100644 --- a/samples/subsys/pm/latency/src/test.c +++ b/samples/subsys/pm/latency/src/test.c @@ -60,4 +60,4 @@ int dev_test_init(const struct device *dev) static struct dev_test_data data; DEVICE_DEFINE(dev_test, "dev_test", &dev_test_init, NULL, &data, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dev_test_api); + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dev_test_api); From ee0f8d838153121844d3f98fdd92bb1e2f6322a5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:03:33 +0200 Subject: [PATCH 0516/4498] tests: benchmarks: footprints: use POST_KERNEL level Because APPLICATION is going to be removed for devices. Signed-off-by: Gerard Marull-Paretas --- tests/benchmarks/footprints/src/pm_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/footprints/src/pm_device.c b/tests/benchmarks/footprints/src/pm_device.c index 6b2e6f32e50..028eff1e3f9 100644 --- a/tests/benchmarks/footprints/src/pm_device.c +++ b/tests/benchmarks/footprints/src/pm_device.c @@ -26,11 +26,11 @@ static int dummy_device_pm_action(const struct device *dev, PM_DEVICE_DEFINE(dummy_pm_driver, dummy_device_pm_action); DEVICE_DEFINE(dummy_pm_driver, DUMMY_PM_DRIVER_NAME, NULL, - PM_DEVICE_GET(dummy_pm_driver), NULL, NULL, APPLICATION, + PM_DEVICE_GET(dummy_pm_driver), NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, NULL, NULL, NULL, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); void run_pm_device(void) { From c0e6e1167b91c0a30621dfeb20a5bd7fdfda161c Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:02:11 +0200 Subject: [PATCH 0517/4498] tests: drivers: use POST_KERNEL level There's no need to use APPLICATION level. In case of the IPM console test, priorities have been adjusted to make sure sender/receiver are initialized in the correct order. Signed-off-by: Gerard Marull-Paretas --- tests/drivers/ipm/src/main.c | 7 ++++--- tests/drivers/sensor/generic/src/dummy_sensor.c | 4 ++-- tests/drivers/smbus/smbus_emul/src/smbus.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/drivers/ipm/src/main.c b/tests/drivers/ipm/src/main.c index 95b97b2ce92..bbb97e46580 100644 --- a/tests/drivers/ipm/src/main.c +++ b/tests/drivers/ipm/src/main.c @@ -24,7 +24,8 @@ #define DEST IPM_CONSOLE_STDOUT #endif -#define INIT_PRIO_IPM_SEND 50 +#define INIT_PRIO_IPM_SEND 40 +#define INIT_PRIO_IPM_RECV 50 extern struct ipm_driver_api ipm_dummy_api; @@ -44,7 +45,7 @@ static struct ipm_console_sender_config_info sender_config = { }; DEVICE_DEFINE(ipm_console_send0, "ipm_send0", ipm_console_sender_init, NULL, NULL, &sender_config, - APPLICATION, INIT_PRIO_IPM_SEND, NULL); + POST_KERNEL, INIT_PRIO_IPM_SEND, NULL); /* Receiving side of the console IPM driver. These numbers are * more or less arbitrary @@ -70,7 +71,7 @@ static struct ipm_console_receiver_config_info receiver_config = { struct ipm_console_receiver_runtime_data receiver_data; DEVICE_DEFINE(ipm_console_recv0, "ipm_recv0", ipm_console_receiver_init, NULL, &receiver_data, &receiver_config, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + POST_KERNEL, INIT_PRIO_IPM_RECV, NULL); static const char thestr[] = "everything is awesome\n"; diff --git a/tests/drivers/sensor/generic/src/dummy_sensor.c b/tests/drivers/sensor/generic/src/dummy_sensor.c index b825cea14ac..556ad33c5de 100644 --- a/tests/drivers/sensor/generic/src/dummy_sensor.c +++ b/tests/drivers/sensor/generic/src/dummy_sensor.c @@ -178,9 +178,9 @@ static const struct sensor_driver_api dummy_sensor_no_trig_api = { }; DEVICE_DEFINE(dummy_sensor, DUMMY_SENSOR_NAME, &dummy_sensor_init, - NULL, &dummy_data, &dummy_config, APPLICATION, + NULL, &dummy_data, &dummy_config, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dummy_sensor_api); DEVICE_DEFINE(dummy_sensor_no_trig, DUMMY_SENSOR_NAME_NO_TRIG, &dummy_sensor_init, - NULL, &dummy_data, &dummy_config, APPLICATION, + NULL, &dummy_data, &dummy_config, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dummy_sensor_no_trig_api); diff --git a/tests/drivers/smbus/smbus_emul/src/smbus.c b/tests/drivers/smbus/smbus_emul/src/smbus.c index 8157fa1aef4..a41a4894662 100644 --- a/tests/drivers/smbus/smbus_emul/src/smbus.c +++ b/tests/drivers/smbus/smbus_emul/src/smbus.c @@ -101,7 +101,7 @@ static struct pch_config pch_config_data = { }; DEVICE_DEFINE(dummy_driver, SMBUS_EMUL, &pch_smbus_init, - NULL, &smbus_data, &pch_config_data, APPLICATION, + NULL, &smbus_data, &pch_config_data, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs); ZTEST(test_smbus_emul, test_byte) From 724274247a0c04d7ef6882b00a4bf94b67e99977 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 14:49:14 +0200 Subject: [PATCH 0518/4498] tests: pm: move all devices to POST_KERNEL There's no need to use APPLICATION level. Signed-off-by: Gerard Marull-Paretas --- tests/subsys/pm/device_runtime_api/src/main.c | 2 +- tests/subsys/pm/power_domain/src/main.c | 3 +-- tests/subsys/pm/power_mgmt/src/dummy_driver.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/subsys/pm/device_runtime_api/src/main.c b/tests/subsys/pm/device_runtime_api/src/main.c index acda0aa822f..57fd7d8bcc8 100644 --- a/tests/subsys/pm/device_runtime_api/src/main.c +++ b/tests/subsys/pm/device_runtime_api/src/main.c @@ -218,7 +218,7 @@ ZTEST(device_runtime_api, test_api) } DEVICE_DEFINE(pm_unsupported_device, "PM Unsupported", NULL, NULL, NULL, NULL, - APPLICATION, 0, NULL); + POST_KERNEL, 0, NULL); ZTEST(device_runtime_api, test_unsupported) { diff --git a/tests/subsys/pm/power_domain/src/main.c b/tests/subsys/pm/power_domain/src/main.c index 0f9f44e5837..aab61a57f1c 100644 --- a/tests/subsys/pm/power_domain/src/main.c +++ b/tests/subsys/pm/power_domain/src/main.c @@ -105,8 +105,7 @@ DEVICE_DT_DEFINE(TEST_DEVB, NULL, PM_DEVICE_DT_GET(TEST_DEVB), PM_DEVICE_DEFINE(devc, deva_pm_action); DEVICE_DEFINE(devc, "devc", NULL, PM_DEVICE_GET(devc), - NULL, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + NULL, NULL, POST_KERNEL, 40, NULL); /** * @brief Test the power domain behavior diff --git a/tests/subsys/pm/power_mgmt/src/dummy_driver.c b/tests/subsys/pm/power_mgmt/src/dummy_driver.c index f33722c30a1..81a053ce1d3 100644 --- a/tests/subsys/pm/power_mgmt/src/dummy_driver.c +++ b/tests/subsys/pm/power_mgmt/src/dummy_driver.c @@ -39,5 +39,5 @@ int dummy_init(const struct device *dev) PM_DEVICE_DEFINE(dummy_driver, dummy_device_pm_action); DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init, - PM_DEVICE_GET(dummy_driver), NULL, NULL, APPLICATION, + PM_DEVICE_GET(dummy_driver), NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs); From 1ffacb6c3ad8b20b4232e27f1f5c84d9d7c38438 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:03:06 +0200 Subject: [PATCH 0519/4498] input: longpress: use POST_KERNEL level Because APPLICATION is going to be deleted. Signed-off-by: Gerard Marull-Paretas --- subsys/input/input_longpress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/input/input_longpress.c b/subsys/input/input_longpress.c index b8510c66a5c..c9acbbf14fe 100644 --- a/subsys/input/input_longpress.c +++ b/subsys/input/input_longpress.c @@ -137,6 +137,6 @@ static int longpress_init(const struct device *dev) }; \ DEVICE_DT_INST_DEFINE(inst, longpress_init, NULL, \ &longpress_data_##inst, &longpress_config_##inst, \ - APPLICATION, CONFIG_INPUT_INIT_PRIORITY, NULL); + POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(INPUT_LONGPRESS_DEFINE) From 87c4b7e04399b9571ea400d094e053b0b15ddba1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:04:38 +0200 Subject: [PATCH 0520/4498] sensing: use POST_KERNEL level In a first place, hardcoding priorities like this is a bad idea, but this patch just moves the device to late POST_KERNEL stage, as APPLICATION level should be avoided for device drivers. Signed-off-by: Gerard Marull-Paretas --- include/zephyr/sensing/sensing_sensor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sensing/sensing_sensor.h b/include/zephyr/sensing/sensing_sensor.h index 39d94d71fb3..8c9e0c83811 100644 --- a/include/zephyr/sensing/sensing_sensor.h +++ b/include/zephyr/sensing/sensing_sensor.h @@ -114,7 +114,7 @@ static inline int sensing_sensor_dev_init( }; \ DEVICE_DT_DEFINE(node_id, sensing_sensor_dev_init, NULL, \ &_CONCAT(__sensing_sensor_ctx_, Z_DEVICE_DT_DEV_ID(node_id)), \ - NULL, APPLICATION, 10, api_ptr) + NULL, POST_KERNEL, 99, api_ptr) /** * @brief Get registered context data pointer for a sensor instance. From d4ffef507ca53103aaaab90ed805e7c1b1209768 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:13:41 +0200 Subject: [PATCH 0521/4498] testsuite: busy_sim: use POST_KERNEL Devices should be initialized in pre/post-Kernel. Signed-off-by: Gerard Marull-Paretas --- subsys/testsuite/busy_sim/busy_sim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/testsuite/busy_sim/busy_sim.c b/subsys/testsuite/busy_sim/busy_sim.c index a7e59b97472..9ca5534851a 100644 --- a/subsys/testsuite/busy_sim/busy_sim.c +++ b/subsys/testsuite/busy_sim/busy_sim.c @@ -204,5 +204,5 @@ static int busy_sim_init(const struct device *dev) DEVICE_DT_DEFINE(DT_BUSY_SIM, busy_sim_init, NULL, &sim_data, &sim_config, - APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, + POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY, NULL); From e6bef2d3f3adaae757c8ad7e89cf35b84e59c344 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:12:47 +0200 Subject: [PATCH 0522/4498] usb: device: class: audio: move to POST_KERNEL Devices should be initialized in pre/post-Kernel levels. Signed-off-by: Gerard Marull-Paretas --- subsys/usb/device/class/audio/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/usb/device/class/audio/audio.c b/subsys/usb/device/class/audio/audio.c index dc7e15f08d8..646f006ab51 100644 --- a/subsys/usb/device/class/audio/audio.c +++ b/subsys/usb/device/class/audio/audio.c @@ -931,7 +931,7 @@ void usb_audio_register(const struct device *dev, &usb_audio_device_init, \ NULL, \ &dev##_audio_dev_data_##i, \ - &dev##_audio_config_##i, APPLICATION, \ + &dev##_audio_config_##i, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ DUMMY_API) From 011321f0cfd3d67d3402c6fd1196297873d474eb Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 15:02:35 +0200 Subject: [PATCH 0523/4498] usb: usb_c: use POST_KERNEL level Usage of application level for device drivers needs to be avoided. Also introduced a new init level, with default to 90 as other dependencies of USB-C run at priority 80. Signed-off-by: Gerard Marull-Paretas --- subsys/usb/usb_c/Kconfig | 6 ++++++ subsys/usb/usb_c/usbc_stack.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/subsys/usb/usb_c/Kconfig b/subsys/usb/usb_c/Kconfig index 57be78f6819..a7bd7a08f74 100644 --- a/subsys/usb/usb_c/Kconfig +++ b/subsys/usb/usb_c/Kconfig @@ -14,6 +14,12 @@ menuconfig USBC_STACK if USBC_STACK +config USBC_INIT_PRIORITY + int "USB-C initialization priority" + default 90 + help + Initialization priority of the USB-C connector driver in POST_KERNEL. + config USBC_THREAD_PRIORITY int "USB-C thread priority" default 0 diff --git a/subsys/usb/usb_c/usbc_stack.c b/subsys/usb/usb_c/usbc_stack.c index 48d4fb3d00d..c1a636ab6c3 100644 --- a/subsys/usb/usb_c/usbc_stack.c +++ b/subsys/usb/usb_c/usbc_stack.c @@ -82,8 +82,8 @@ static ALWAYS_INLINE void usbc_handler(void *port_dev) }; \ \ DEVICE_DT_INST_DEFINE(inst, &usbc_subsys_init, NULL, &usbc_port_data_##inst, \ - &usbc_port_config_##inst, APPLICATION, \ - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + &usbc_port_config_##inst, POST_KERNEL, \ + CONFIG_USBC_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(USBC_SUBSYS_INIT) From 1213ed4e8fdaf75a3d8eb3e9f9dc7b4d69d83722 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 14:25:18 +0200 Subject: [PATCH 0524/4498] dts: bindings: arm: nordic,nrf-uicr add nfct-pins-as-gpios Allow configuring NFCT pins as GPIOs from devicetree. This setting is part of the UICR. Signed-off-by: Gerard Marull-Paretas --- dts/bindings/arm/nordic,nrf-uicr.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dts/bindings/arm/nordic,nrf-uicr.yaml b/dts/bindings/arm/nordic,nrf-uicr.yaml index 82ac8fc2089..dbbb34e1265 100644 --- a/dts/bindings/arm/nordic,nrf-uicr.yaml +++ b/dts/bindings/arm/nordic,nrf-uicr.yaml @@ -7,3 +7,15 @@ include: base.yaml properties: reg: required: true + + nfct-pins-as-gpios: + type: boolean + description: | + When enabled this property will configure pins dedicated to NFCT + peripheral as regular GPIOs. + + NFC pins in nRF52 series: P0.09 and P0.10 + NFC pins in nRF5340: P0.02 and P0.03 + + This setting, once applied, can only be unset by erasing the UICR + registers. Refer to the reference manual for more details. From e43c2f3eb58cb98b0fcdbde3dba810a501747200 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 14:32:51 +0200 Subject: [PATCH 0525/4498] modules: hal_nordic: inject CONFIG_NFCT_PINS_AS_GPIOS If the users configures this option in devicetree, ie, ``` &uicr { nfct-pins-as-gpios; }; ``` CMake will inject the HAL-specific CONFIG_NFCT_PINS_AS_GPIOS definition, so that the necessary operations are performed during system init. Signed-off-by: Gerard Marull-Paretas --- modules/hal_nordic/nrfx/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 5842ae45ad5..98ba1961396 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -109,3 +109,16 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_WDT ${SRC_DIR}/nrfx_wdt.c) if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) zephyr_library_sources(${SRC_DIR}/nrfx_twi_twim.c) endif() + +# Inject HAL "CONFIG_NFCT_PINS_AS_GPIOS" definition if user requests to +# configure the NFCT pins as GPIOS. This way, the HAL will take care of doing +# the proper configuration sequence during system init + +dt_nodelabel(uicr_path NODELABEL "uicr") +if(${uicr_path}) + dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") + + if(${nfct_pins_as_gpios}) + zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) + endif() +endif() From dd568d01b89eb9e021027df140ae148144830663 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 14:39:01 +0200 Subject: [PATCH 0526/4498] boards: arm: nrf: use UICR nfc-pins-as-gpios devicetree property Instead of CONFIG_NFCT_PINS_AS_GPIOS (about to be deprecated). Signed-off-by: Gerard Marull-Paretas --- boards/arm/bt610/bt610.dts | 4 ++++ boards/arm/bt610/bt610_defconfig | 1 - .../arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts | 4 ++++ .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig | 1 - .../arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts | 4 ++++ .../nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig | 1 - .../nrf5340_audio_dk_nrf5340_cpuapp.dts | 4 ++++ .../nrf5340_audio_dk_nrf5340_cpuapp_defconfig | 1 - boards/arm/pinetime_devkit0/pinetime_devkit0.dts | 4 ++++ boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig | 3 --- 10 files changed, 20 insertions(+), 7 deletions(-) diff --git a/boards/arm/bt610/bt610.dts b/boards/arm/bt610/bt610.dts index 3c047a50fcd..6bbe8d57fe3 100644 --- a/boards/arm/bt610/bt610.dts +++ b/boards/arm/bt610/bt610.dts @@ -143,6 +143,10 @@ status = "okay"; }; +&uicr { + nfct-pins-as-gpios; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/bt610/bt610_defconfig b/boards/arm/bt610/bt610_defconfig index 64f0fcb85ed..1c77ed9e37b 100644 --- a/boards/arm/bt610/bt610_defconfig +++ b/boards/arm/bt610/bt610_defconfig @@ -9,7 +9,6 @@ CONFIG_ARM_MPU=y # Enable GPIO CONFIG_GPIO=y -CONFIG_NFCT_PINS_AS_GPIOS=y # Enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts index 616af71443c..8e835597c78 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts @@ -87,6 +87,10 @@ status = "okay"; }; +&uicr { + nfct-pins-as-gpios; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index 92ec1dc7885..90850c10e0a 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -15,6 +15,5 @@ CONFIG_GPIO=y # additional board options CONFIG_GPIO_AS_PINRESET=y -CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts index f17ecb8e18a..93b59baa920 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts @@ -99,6 +99,10 @@ status = "okay"; }; +&uicr { + nfct-pins-as-gpios; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index f38880961d5..32a9d03b44e 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -15,7 +15,6 @@ CONFIG_GPIO=y # additional board options CONFIG_GPIO_AS_PINRESET=y -CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_PINCTRL=y diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts index 8fe46bdd7a3..be871800332 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts @@ -20,3 +20,7 @@ zephyr,sram-non-secure-partition = &sram0_ns; }; }; + +&uicr { + nfct-pins-as-gpios; +}; diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig index 0f5f1991b6d..d1b5f551c9b 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig @@ -12,7 +12,6 @@ CONFIG_HW_STACK_PROTECTION=y CONFIG_ARM_TRUSTZONE_M=y CONFIG_GPIO=y -CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_SERIAL=y diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts index baad177740c..fb377fd89e1 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts @@ -87,6 +87,10 @@ status = "okay"; }; +&uicr { + nfct-pins-as-gpios; +}; + &gpio0 { status = "okay"; diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig index 4e48c259730..ad7442afe0d 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -13,9 +13,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# use P0.09 and P0.10 as GPIOs -CONFIG_NFCT_PINS_AS_GPIOS=y - # use P0.21 as RST CONFIG_GPIO_AS_PINRESET=y From 0762008586976290d7a2f23b39489227b088e1fa Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 14:40:59 +0200 Subject: [PATCH 0527/4498] soc: arm: nordic_nrf: deprecate CONFIG_NFCT_PINS_AS_GPIOS In favor of the new UICR nfct-pins-as-gpios devicetree property. Signed-off-by: Gerard Marull-Paretas --- soc/arm/nordic_nrf/Kconfig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 2c386f99a53..c2129db64b3 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -47,8 +47,9 @@ config NRF_ACL_FLASH_REGION_SIZE FLASH region size for the NRF_ACL peripheral. config NFCT_PINS_AS_GPIOS - bool "NFCT pins as GPIOs" + bool "[DEPRECATED] NFCT pins as GPIOs" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_NFCT)) + select DEPRECATED help Two pins are usually reserved for NFC in SoCs that implement the NFCT peripheral. This option switches them to normal GPIO mode. @@ -60,6 +61,13 @@ config NFCT_PINS_AS_GPIOS NFC pins in nRF52 series: P0.09 and P0.10 NFC pins in nRF5340: P0.02 and P0.03 + This option is deprecated, please use devicetree to configure NFCT + pins as GPIOS like this: + + &uicr { + nfct-pins-as-gpios; + }; + choice NRF_APPROTECT_HANDLING bool "APPROTECT handling" depends on SOC_SERIES_NRF52X || SOC_NRF5340_CPUNET || \ From c0bf310ac87e5339978e7d4072e2b93652830c7a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 14 Sep 2023 14:45:33 +0200 Subject: [PATCH 0528/4498] doc: migration-guide: add notes on CONFIG_NFCT_PINS_AS_GPIOS changes So that users know how to migrate to the new option. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 767c5378be1..c7135c0e21b 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -56,6 +56,17 @@ Recommended Changes The GIC version should now be specified by adding the appropriate compatible, for example :dtcompatible:`arm,gic-v2`, to the GIC node in the device tree. +* Nordic nRF based boards using :kconfig:option:`CONFIG_NFCT_PINS_AS_GPIOS` + to configure NFCT pins as GPIOs, should instead set the new UICR + ``nfct-pins-as-gpios`` property in devicetree. It can be set like this in the + board devicetree files: + + .. code-block:: devicetree + + &uicr { + nfct-pins-as-gpios; + }; + Picolibc-related Changes ************************ From 61ab3a844c26fbe44011440505b40358825b99c8 Mon Sep 17 00:00:00 2001 From: Leifu Zhao Date: Tue, 22 Aug 2023 16:42:51 +0800 Subject: [PATCH 0529/4498] pm: policy: add check for device busy in policy Add check for device busy when CONFIG_PM_NEED_ALL_DEVICES_IDLE is set to y because one or more devices may still in busy and causes problem when system go into low power in Intel ISH platform. Signed-off-by: Leifu Zhao --- soc/x86/intel_ish/intel_ish5/pm/Kconfig.pm | 3 +++ subsys/pm/Kconfig | 7 +++++++ subsys/pm/policy.c | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/soc/x86/intel_ish/intel_ish5/pm/Kconfig.pm b/soc/x86/intel_ish/intel_ish5/pm/Kconfig.pm index d4decc82f7d..d50e435c13e 100644 --- a/soc/x86/intel_ish/intel_ish5/pm/Kconfig.pm +++ b/soc/x86/intel_ish/intel_ish5/pm/Kconfig.pm @@ -18,4 +18,7 @@ config GDT_RESERVED_NUM_ENTRIES config REBOOT default y +config PM_NEED_ALL_DEVICES_IDLE + default y + endif diff --git a/subsys/pm/Kconfig b/subsys/pm/Kconfig index 36535e383a1..aeffe8c60ec 100644 --- a/subsys/pm/Kconfig +++ b/subsys/pm/Kconfig @@ -37,6 +37,13 @@ config PM_S2RAM help This option enables suspend-to-RAM (S2RAM). +config PM_NEED_ALL_DEVICES_IDLE + bool "System Low Power Mode Needs All Devices Idle" + depends on PM_DEVICE && !SMP + help + When this option is enabled, check that no devices are busy before + entering into system low power mode. + choice PM_POLICY prompt "Idle State Power Management Policy" default PM_POLICY_DEFAULT diff --git a/subsys/pm/policy.c b/subsys/pm/policy.c index 4c3012db2cc..fa44a7069f7 100644 --- a/subsys/pm/policy.c +++ b/subsys/pm/policy.c @@ -14,6 +14,7 @@ #include #include #include +#include #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state) @@ -136,6 +137,12 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) uint8_t num_cpu_states; const struct pm_state_info *cpu_states; +#ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE + if (pm_device_is_any_busy()) { + return NULL; + } +#endif + if (ticks != K_TICKS_FOREVER) { cyc = k_ticks_to_cyc_ceil32(ticks); } From 23264c4b3a6b9f079a81d4d96f2e40e2c89e3314 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 16 Aug 2023 18:16:49 -0500 Subject: [PATCH 0530/4498] soc: arm: nxp_imx: introduce ROM ramloader feature The iMX RT bootrom allows the user to load images into RAM regions from flash by providing a correctly configured boot header. In particular, if the boot header contains a load address within RAM, the bootroom will automatically copy the image to the load address before executing it Introduce CONFIG_NXP_IMX_RT_ROM_RAMLOADER to enable this feature. This Kconfig will shift the LMA of a image built to run in a RAM region to reside in the default FlexSPI boot region, which allows the image to be loaded to the FlexSPI region using west. This is intended to simplify development of applications executing from RAM on iMX RT based systems. Signed-off-by: Daniel DeGrasse --- soc/arm/nxp_imx/rt/Kconfig.soc | 17 +++++++++++++++++ soc/arm/nxp_imx/rt5xx/Kconfig.soc | 19 +++++++++++++++++++ soc/arm/nxp_imx/rt6xx/Kconfig.soc | 17 +++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index 23fb53ca344..253e316548e 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -795,6 +795,23 @@ config NXP_IMX_EXTERNAL_SDRAM an MPU region will be defined to disable cached access to the SDRAM memory space. +config NXP_IMX_RT_ROM_RAMLOADER + depends on !FLASH_MCUX_FLEXSPI_XIP && NXP_IMX_RT_BOOT_HEADER + # Required so that debugger will load image to correct offset + select BUILD_OUTPUT_HEX + bool "Create output image that IMX RT ROM can load from FlexSPI to ram" + help + Builds an output image that the IMX RT BootROM can load from the + FlexSPI boot device into RAM region. The image will be loaded + from FLEXSPI into the region specified by `zephyr,flash` node. + +# Setup LMA adjustment if using the RAMLOADER feature of ROM +FLASH_CHOSEN := zephyr,flash +FLASH_BASE := $(dt_chosen_reg_addr_hex,$(FLASH_CHOSEN)) +FLEXSPI_BASE := $(dt_node_reg_addr_hex,/soc/spi@402a8000,1) +config BUILD_OUTPUT_ADJUST_LMA + default "$(FLEXSPI_BASE) - $(FLASH_BASE)" if NXP_IMX_RT_ROM_RAMLOADER + config SECOND_CORE_MCUX bool "Dual core operation on the RT11xx series" depends on SOC_SERIES_IMX_RT11XX diff --git a/soc/arm/nxp_imx/rt5xx/Kconfig.soc b/soc/arm/nxp_imx/rt5xx/Kconfig.soc index f41c63d104b..2c82c533de9 100644 --- a/soc/arm/nxp_imx/rt5xx/Kconfig.soc +++ b/soc/arm/nxp_imx/rt5xx/Kconfig.soc @@ -101,8 +101,27 @@ config IMAGE_VECTOR_TABLE_OFFSET the application entry point and device configuration data. The boot ROM requires a fixed IVT offset for each type of boot device. +config NXP_IMX_RT_ROM_RAMLOADER + depends on !FLASH_MCUX_FLEXSPI_XIP + # Required so that debugger will load image to correct offset + select BUILD_OUTPUT_HEX + bool "Create output image that IMX RT ROM can load from FlexSPI to ram" + help + Builds an output image that the IMX RT BootROM can load from the + FlexSPI boot device into RAM region. The image will be loaded + from FLEXSPI0 into the region specified by `zephyr,flash` node. + +# Setup LMA adjustment if using the RAMLOADER feature of ROM +FLASH_CHOSEN := zephyr,flash +FLASH_BASE := $(dt_chosen_reg_addr_hex,$(FLASH_CHOSEN)) +FLEXSPI_BASE := $(dt_node_reg_addr_hex,/soc/spi@134000,1) +config BUILD_OUTPUT_ADJUST_LMA + default "$(FLEXSPI_BASE) - $(FLASH_BASE)" if NXP_IMX_RT_ROM_RAMLOADER + endif # NXP_IMX_RT5XX_BOOT_HEADER + + config IMXRT5XX_CODE_CACHE bool "Code cache" default y diff --git a/soc/arm/nxp_imx/rt6xx/Kconfig.soc b/soc/arm/nxp_imx/rt6xx/Kconfig.soc index b94e98b7384..e2222ab3214 100644 --- a/soc/arm/nxp_imx/rt6xx/Kconfig.soc +++ b/soc/arm/nxp_imx/rt6xx/Kconfig.soc @@ -107,6 +107,23 @@ config IMAGE_VECTOR_TABLE_OFFSET the application entry point and device configuration data. The boot ROM requires a fixed IVT offset for each type of boot device. +config NXP_IMX_RT_ROM_RAMLOADER + depends on !FLASH_MCUX_FLEXSPI_XIP + # Required so that debugger will load image to correct offset + select BUILD_OUTPUT_HEX + bool "Create output image that IMX RT ROM can load from FlexSPI to ram" + help + Builds an output image that the IMX RT BootROM can load from the + FlexSPI boot device into RAM region. The image will be loaded + from FLEXSPI into the region specified by `zephyr,flash` node. + +# Setup LMA adjustment if using the RAMLOADER feature of ROM +FLASH_CHOSEN := zephyr,flash +FLASH_BASE := $(dt_chosen_reg_addr_hex,$(FLASH_CHOSEN)) +FLEXSPI_BASE := $(dt_node_reg_addr_hex,/soc/spi@134000,1) +config BUILD_OUTPUT_ADJUST_LMA + default "$(FLEXSPI_BASE) - $(FLASH_BASE)" if NXP_IMX_RT_ROM_RAMLOADER + endif # NXP_IMX_RT6XX_BOOT_HEADER config IMXRT6XX_CODE_CACHE From d0f6321e293059f517d7414b379bee9aaf82c917 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 16 Aug 2023 18:20:38 -0500 Subject: [PATCH 0531/4498] dts: arm: nxp: rt5xx: add SRAM code region Add SRAM code region definition to RT5xx series SOC. The RT5xx shares SRAM partitions between the code and data bus, but a default allocation is chosen by the SOC level devicetree. The user can modify this allocation by changing the base address and size of the sram_code and sram0 regions in their board devicetree. Signed-off-by: Daniel DeGrasse --- dts/arm/nxp/nxp_rt5xx.dtsi | 5 +++-- dts/arm/nxp/nxp_rt5xx_common.dtsi | 14 ++++++++++++++ dts/arm/nxp/nxp_rt5xx_ns.dtsi | 5 +++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/dts/arm/nxp/nxp_rt5xx.dtsi b/dts/arm/nxp/nxp_rt5xx.dtsi index 3391ed2f33f..931f5afb422 100644 --- a/dts/arm/nxp/nxp_rt5xx.dtsi +++ b/dts/arm/nxp/nxp_rt5xx.dtsi @@ -8,8 +8,9 @@ / { soc { - sram: sram@30018000 { - ranges = <0x20180000 0x30180000 0x300000>; + sram: sram@30000000 { + ranges = <0x0 0x10000000 0x500000 + 0x20000000 0x30000000 0x500000>; }; peripheral: peripheral@50000000 { diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index fa7936db9c2..54469d3a56f 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -70,6 +70,20 @@ #address-cells = <1>; #size-cells = <1>; + /* RT5XX SRAM partitions are shared + * between code and data. Boards can + * override the reg properties of either sram0 or sram_code nodes to + * change the balance of SRAM allocation. + * + * Note that the sram code region starts at an offset of 0x1B000, + * as the boot ROM will not load code before 0x1C000. The first + * 0x1000 of the image will contain the boot header. + */ + sram_code: memory@1b000 { + compatible = "mmio-sram"; + reg = <0x1b000 DT_SIZE_K(1428)>; + }; + sram0: memory@20180000 { compatible = "mmio-sram"; reg = <0x20180000 DT_SIZE_K(3072)>; diff --git a/dts/arm/nxp/nxp_rt5xx_ns.dtsi b/dts/arm/nxp/nxp_rt5xx_ns.dtsi index b5751704fbd..10e36fa7a24 100644 --- a/dts/arm/nxp/nxp_rt5xx_ns.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_ns.dtsi @@ -8,8 +8,9 @@ / { soc { - sram: sram@20180000 { - ranges = <0x20180000 0x20180000 0x300000>; + sram: sram@20000000 { + ranges = <0x0 0x0 0x500000 + 0x20000000 0x20000000 0x500000>; }; peripheral: peripheral@40000000 { From b0b32c5701d9984613bd58e4b0ea72ef357c04b6 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 17 Aug 2023 10:54:55 -0500 Subject: [PATCH 0532/4498] dts: arm: nxp: rt6xx: add SRAM code region Add SRAM code region definition to RT6xx series SOC. The RT6xx shares SRAM partitions between the code and data bus, but a default allocation is chosen by the SOC level devicetree. The user can modify this allocation by changing the base address and size of the sram_code and sram0 regions in their board devicetree. Signed-off-by: Daniel DeGrasse --- dts/arm/nxp/nxp_rt6xx.dtsi | 5 +++-- dts/arm/nxp/nxp_rt6xx_common.dtsi | 14 ++++++++++++++ dts/arm/nxp/nxp_rt6xx_ns.dtsi | 5 +++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/dts/arm/nxp/nxp_rt6xx.dtsi b/dts/arm/nxp/nxp_rt6xx.dtsi index fd6c53b10dd..3744184cc9c 100644 --- a/dts/arm/nxp/nxp_rt6xx.dtsi +++ b/dts/arm/nxp/nxp_rt6xx.dtsi @@ -8,8 +8,9 @@ / { soc { - sram: sram@30018000 { - ranges = <0x20180000 0x30180000 0x300000>; + sram: sram@30000000 { + ranges = <0x0 0x10000000 0x500000 + 0x20000000 0x30000000 0x500000>; }; peripheral: peripheral@50000000 { diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index 5b8748c566f..843c1739cd2 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -54,6 +54,20 @@ #address-cells = <1>; #size-cells = <1>; + /* RT6XX SRAM partitions are shared + * between code and data. Boards can + * override the reg properties of either sram0 or sram_code nodes to + * change the balance of SRAM allocation. + * + * Note that the sram code region starts at an offset of 0x1B000, + * as the boot ROM will not load code before 0x1C000. The first + * 0x1000 of the image will contain the boot header. + */ + sram_code: memory@1b000 { + compatible = "mmio-sram"; + reg = <0x1b000 DT_SIZE_K(1428)>; + }; + sram0: memory@20180000 { compatible = "mmio-sram"; reg = <0x20180000 DT_SIZE_K(3072)>; diff --git a/dts/arm/nxp/nxp_rt6xx_ns.dtsi b/dts/arm/nxp/nxp_rt6xx_ns.dtsi index fafe3e9ffc4..04ce50e84b1 100644 --- a/dts/arm/nxp/nxp_rt6xx_ns.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_ns.dtsi @@ -8,8 +8,9 @@ / { soc { - sram: sram@20180000 { - ranges = <0x20180000 0x20180000 0x300000>; + sram: sram@20000000 { + ranges = <0x0 0x0 0x500000 + 0x20000000 0x20000000 0x500000>; }; peripheral: peripheral@40000000 { From 4431c4755c1402c77753999a1be812b9457abad5 Mon Sep 17 00:00:00 2001 From: Mathias Storck Date: Thu, 14 Sep 2023 13:15:19 +0200 Subject: [PATCH 0533/4498] drivers: sensor: lis2dh: add tap interrupt add interrupt for single tap on ST LIS2DH shared interrupt with any motion Signed-off-by: Mathias Storck --- drivers/sensor/lis2dh/lis2dh.h | 50 +++--- drivers/sensor/lis2dh/lis2dh_trigger.c | 207 ++++++++++++++++++------- 2 files changed, 182 insertions(+), 75 deletions(-) diff --git a/drivers/sensor/lis2dh/lis2dh.h b/drivers/sensor/lis2dh/lis2dh.h index 72cc710ed9e..142b1330d78 100644 --- a/drivers/sensor/lis2dh/lis2dh.h +++ b/drivers/sensor/lis2dh/lis2dh.h @@ -29,11 +29,9 @@ #define LIS2DH_AUTOINCREMENT_ADDR BIT(7) #define LIS2DH_REG_CTRL0 0x1e -#define LIS2DH_SDO_PU_DISC_SHIFT 7 -#define LIS2DH_SDO_PU_DISC_MASK BIT(LIS2DH_SDO_PU_DISC_SHIFT) +#define LIS2DH_SDO_PU_DISC_MASK BIT(7) #define LIS2DH_REG_CTRL1 0x20 -#define LIS2DH_ACCEL_XYZ_SHIFT 0 #define LIS2DH_ACCEL_X_EN_BIT BIT(0) #define LIS2DH_ACCEL_Y_EN_BIT BIT(1) #define LIS2DH_ACCEL_Z_EN_BIT BIT(2) @@ -91,14 +89,15 @@ #define LIS2DH_HPIS2_EN_BIT BIT(1) #define LIS2DH_FDS_EN_BIT BIT(3) -#define LIS2DH_HPIS_EN_SHIFT 0 -#define LIS2DH_HPIS_EN_MASK BIT_MASK(2) << LIS2DH_HPIS_EN_SHIFT +#define LIS2DH_HPIS_EN_MASK BIT_MASK(2) #define LIS2DH_REG_CTRL3 0x22 -#define LIS2DH_EN_DRDY1_INT1_SHIFT 4 -#define LIS2DH_EN_DRDY1_INT1 BIT(LIS2DH_EN_DRDY1_INT1_SHIFT) +#define LIS2DH_EN_CLICK_INT1 BIT(7) +#define LIS2DH_EN_IA_INT1 BIT(6) +#define LIS2DH_EN_DRDY1_INT1 BIT(4) #define LIS2DH_REG_CTRL4 0x23 +#define LIS2DH_CTRL4_BDU_BIT BIT(7) #define LIS2DH_FS_SHIFT 4 #define LIS2DH_FS_MASK (BIT_MASK(2) << LIS2DH_FS_SHIFT) @@ -122,16 +121,12 @@ #endif #define LIS2DH_REG_CTRL5 0x24 -#define LIS2DH_LIR_INT2_SHIFT 1 -#define LIS2DH_LIR_INT1_SHIFT 3 -#define LIS2DH_EN_LIR_INT2 BIT(LIS2DH_LIR_INT2_SHIFT) -#define LIS2DH_EN_LIR_INT1 BIT(LIS2DH_LIR_INT1_SHIFT) +#define LIS2DH_EN_LIR_INT2 BIT(1) +#define LIS2DH_EN_LIR_INT1 BIT(3) #define LIS2DH_REG_CTRL6 0x25 -#define LIS2DH_EN_INT2_INT2_SHIFT 5 -#define LIS2DH_EN_INT2_INT2 BIT(LIS2DH_EN_INT2_INT2_SHIFT) -#define LIS2DH_EN_INT1_INT1_SHIFT 6 -#define LIS2DH_EN_INT1_INT1 BIT(LIS2DH_EN_INT1_INT1_SHIFT) +#define LIS2DH_EN_CLICK_INT2 BIT(7) +#define LIS2DH_EN_IA_INT2 BIT(5) #define LIS2DH_REG_REFERENCE 0x26 @@ -164,8 +159,8 @@ #define LIS2DH_REG_INT2_DUR 0x37 #define LIS2DH_INT_CFG_MODE_SHIFT 6 -#define LIS2DH_INT_CFG_AOI_CFG BIT(LIS2DH_INT_CFG_MODE_SHIFT + 1) -#define LIS2DH_INT_CFG_6D_CFG BIT(LIS2DH_INT_CFG_MODE_SHIFT) +#define LIS2DH_INT_CFG_AOI_CFG BIT(7) +#define LIS2DH_INT_CFG_6D_CFG BIT(6) #define LIS2DH_INT_CFG_ZHIE_ZUPE BIT(5) #define LIS2DH_INT_CFG_ZLIE_ZDOWNE BIT(4) #define LIS2DH_INT_CFG_YHIE_YUPE BIT(3) @@ -173,11 +168,26 @@ #define LIS2DH_INT_CFG_XHIE_XUPE BIT(1) #define LIS2DH_INT_CFG_XLIE_XDOWNE BIT(0) +#define LIS2DH_REG_CFG_CLICK 0x38 +#define LIS2DH_EN_CLICK_ZD BIT(5) +#define LIS2DH_EN_CLICK_ZS BIT(4) +#define LIS2DH_EN_CLICK_YD BIT(3) +#define LIS2DH_EN_CLICK_YS BIT(2) +#define LIS2DH_EN_CLICK_XD BIT(1) +#define LIS2DH_EN_CLICK_XS BIT(0) + +#define LIS2DH_REG_CLICK_SRC 0x39 +#define LIS2DH_CLICK_SRC_DCLICK BIT(5) +#define LIS2DH_CLICK_SRC_SCLICK BIT(4) + +#define LIS2DH_REG_CFG_CLICK_THS 0x3A +#define LIS2DH_CLICK_LIR BIT(7) + +#define LIS2DH_REG_TIME_LIMIT 0x3B + /* sample buffer size includes status register */ #define LIS2DH_BUF_SZ 7 -#define LIS2DH_CTRL4_BDU_BIT BIT(7) - union lis2dh_sample { uint8_t raw[LIS2DH_BUF_SZ]; struct { @@ -260,6 +270,8 @@ struct lis2dh_data { const struct sensor_trigger *trig_drdy; sensor_trigger_handler_t handler_anymotion; const struct sensor_trigger *trig_anymotion; + sensor_trigger_handler_t handler_tap; + const struct sensor_trigger *trig_tap; atomic_t trig_flags; enum sensor_channel chan_drdy; diff --git a/drivers/sensor/lis2dh/lis2dh_trigger.c b/drivers/sensor/lis2dh/lis2dh_trigger.c index 5b017ff0013..2b773b2aef8 100644 --- a/drivers/sensor/lis2dh/lis2dh_trigger.c +++ b/drivers/sensor/lis2dh/lis2dh_trigger.c @@ -127,9 +127,10 @@ static inline void setup_int2(const struct device *dev, : GPIO_INT_DISABLE); } -static int lis2dh_trigger_anym_set(const struct device *dev, - sensor_trigger_handler_t handler, - const struct sensor_trigger *trig) +/* common handler for any motion and tap triggers */ +static int lis2dh_trigger_anym_tap_set(const struct device *dev, + sensor_trigger_handler_t handler, + const struct sensor_trigger *trig) { const struct lis2dh_config *cfg = dev->config; struct lis2dh_data *lis2dh = dev->data; @@ -152,19 +153,34 @@ static int lis2dh_trigger_anym_set(const struct device *dev, } /* disable any movement interrupt events */ - status = lis2dh->hw_tf->write_reg( - dev, - cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_CFG : LIS2DH_REG_INT2_CFG, - 0); + status = lis2dh->hw_tf->write_reg(dev, + cfg->hw.anym_on_int1 ? + LIS2DH_REG_INT1_CFG : + LIS2DH_REG_INT2_CFG, + 0); + /* disable any click interrupt events */ + status = lis2dh->hw_tf->write_reg(dev, + LIS2DH_REG_CFG_CLICK, + 0); /* make sure any pending interrupt is cleared */ - status = lis2dh->hw_tf->read_reg( - dev, - cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_SRC : LIS2DH_REG_INT2_SRC, - ®_val); + status = lis2dh->hw_tf->read_reg(dev, + cfg->hw.anym_on_int1 ? + LIS2DH_REG_INT1_SRC : + LIS2DH_REG_INT2_SRC, + ®_val); + status = lis2dh->hw_tf->read_reg(dev, + LIS2DH_REG_CLICK_SRC, + ®_val); + + if (trig->type == SENSOR_TRIG_DELTA) { + lis2dh->handler_anymotion = handler; + lis2dh->trig_anymotion = trig; + } else if (trig->type == SENSOR_TRIG_TAP) { + lis2dh->handler_tap = handler; + lis2dh->trig_tap = trig; + } - lis2dh->handler_anymotion = handler; - lis2dh->trig_anymotion = trig; if ((handler == NULL) || (status < 0)) { return status; } @@ -181,17 +197,71 @@ static int lis2dh_trigger_anym_set(const struct device *dev, return 0; } +static int lis2dh_trigger_anym_set(const struct device *dev, + sensor_trigger_handler_t handler, + const struct sensor_trigger *trig) +{ + return lis2dh_trigger_anym_tap_set(dev, handler, trig); +} + +static int lis2dh_trigger_tap_set(const struct device *dev, + sensor_trigger_handler_t handler, + const struct sensor_trigger *trig) +{ + return lis2dh_trigger_anym_tap_set(dev, handler, trig); +} + static int lis2dh_start_trigger_int2(const struct device *dev) { struct lis2dh_data *lis2dh = dev->data; const struct lis2dh_config *cfg = dev->config; + int status = 0; + uint8_t reg = 0, mask = 0, val = 0; setup_int2(dev, true); - return lis2dh->hw_tf->write_reg( - dev, - cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_CFG : LIS2DH_REG_INT2_CFG, - (cfg->hw.anym_mode << LIS2DH_INT_CFG_MODE_SHIFT) | LIS2DH_ANYM_CFG); + bool has_anyt = (lis2dh->handler_tap != NULL); + bool has_anym = (lis2dh->handler_anymotion != NULL); + + /* configure any motion interrupt */ + reg = cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_CFG : LIS2DH_REG_INT2_CFG; + val = (cfg->hw.anym_mode << LIS2DH_INT_CFG_MODE_SHIFT) | LIS2DH_ANYM_CFG; + status = lis2dh->hw_tf->write_reg(dev, reg, val); + if (status < 0) { + LOG_ERR("Failed to configure any motion interrupt"); + return status; + } + + /* enable any motion detection on int line */ + reg = cfg->hw.anym_on_int1 ? LIS2DH_REG_CTRL3 : LIS2DH_REG_CTRL6; + mask = cfg->hw.anym_on_int1 ? LIS2DH_EN_IA_INT1 : LIS2DH_EN_IA_INT2; + val = has_anym ? mask : 0; + status = lis2dh->hw_tf->update_reg(dev, reg, mask, val); + if (status < 0) { + LOG_ERR("Failed to enable any motion detection on int line"); + return status; + } + + /* configure tap interrupt on all axes */ + reg = LIS2DH_REG_CFG_CLICK; + mask = LIS2DH_EN_CLICK_XS | LIS2DH_EN_CLICK_YS | LIS2DH_EN_CLICK_ZS; + val = has_anyt ? mask : 0; + status = lis2dh->hw_tf->update_reg(dev, reg, mask, val); + if (status < 0) { + LOG_ERR("Failed to configure tap interrupt"); + return status; + } + + /* set click detection on int line */ + reg = cfg->hw.anym_on_int1 ? LIS2DH_REG_CTRL3 : LIS2DH_REG_CTRL6; + mask = cfg->hw.anym_on_int1 ? LIS2DH_EN_CLICK_INT1 : LIS2DH_EN_CLICK_INT2; + val = has_anyt ? mask : 0; + status = lis2dh->hw_tf->update_reg(dev, reg, mask, val); + if (status < 0) { + LOG_ERR("Failed to enable click detection on int line"); + return status; + } + return 0; } int lis2dh_trigger_set(const struct device *dev, @@ -203,6 +273,8 @@ int lis2dh_trigger_set(const struct device *dev, return lis2dh_trigger_drdy_set(dev, trig->chan, handler, trig); } else if (trig->type == SENSOR_TRIG_DELTA) { return lis2dh_trigger_anym_set(dev, handler, trig); + } else if (trig->type == SENSOR_TRIG_TAP) { + return lis2dh_trigger_tap_set(dev, handler, trig); } return -ENOTSUP; @@ -243,11 +315,17 @@ int lis2dh_acc_slope_config(const struct device *dev, LOG_INF("int2_ths=0x%x range_g=%d ums2=%u", reg_val, range_g, slope_th_ums2 - 1); + /* Configure threshold for the any motion recognition */ status = lis2dh->hw_tf->write_reg(dev, cfg->hw.anym_on_int1 ? - LIS2DH_REG_INT1_THS : - LIS2DH_REG_INT2_THS, + LIS2DH_REG_INT1_THS : + LIS2DH_REG_INT2_THS, reg_val); + + /* Configure threshold for the Click recognition */ + status = lis2dh->hw_tf->write_reg(dev, + LIS2DH_REG_CFG_CLICK_THS, + LIS2DH_CLICK_LIR | reg_val); } else { /* SENSOR_ATTR_SLOPE_DUR */ /* * slope duration is measured in number of samples: @@ -259,10 +337,16 @@ int lis2dh_acc_slope_config(const struct device *dev, LOG_INF("int2_dur=0x%x", val->val1); + /* Configure time limit for the any motion recognition */ status = lis2dh->hw_tf->write_reg(dev, cfg->hw.anym_on_int1 ? - LIS2DH_REG_INT1_DUR : - LIS2DH_REG_INT2_DUR, + LIS2DH_REG_INT1_DUR : + LIS2DH_REG_INT2_DUR, + val->val1); + + /* Configure time limit for the Click recognition */ + status = lis2dh->hw_tf->write_reg(dev, + LIS2DH_REG_TIME_LIMIT, val->val1); } @@ -358,7 +442,6 @@ static void lis2dh_thread_cb(const struct device *dev) TRIGGED_INT1)) { if (likely(lis2dh->handler_drdy != NULL)) { lis2dh->handler_drdy(dev, lis2dh->trig_drdy); - } /* Reactivate level triggered interrupt if handler did not @@ -374,7 +457,7 @@ static void lis2dh_thread_cb(const struct device *dev) if (cfg->gpio_int.port && atomic_test_and_clear_bit(&lis2dh->trig_flags, TRIGGED_INT2)) { - uint8_t reg_val; + uint8_t reg_val = 0; if (cfg->hw.anym_latch) { /* clear interrupt to de-assert int line */ @@ -387,18 +470,34 @@ static void lis2dh_thread_cb(const struct device *dev) LOG_ERR("clearing interrupt 2 failed: %d", status); return; } + } + + if (likely(lis2dh->handler_anymotion != NULL) && + (reg_val >> LIS2DH_INT_CFG_MODE_SHIFT)) { + lis2dh->handler_anymotion(dev, lis2dh->trig_anymotion); LOG_DBG("@tick=%u int2_src=0x%x", k_cycle_get_32(), reg_val); } - if (likely(lis2dh->handler_anymotion != NULL)) { - lis2dh->handler_anymotion(dev, lis2dh->trig_anymotion); + /* read click interrupt */ + status = lis2dh->hw_tf->read_reg(dev, LIS2DH_REG_CLICK_SRC, + ®_val); + if (status < 0) { + LOG_ERR("clearing interrupt 2 failed: %d", status); + return; + } + + if (likely(lis2dh->handler_tap != NULL) && + (reg_val & LIS2DH_CLICK_SRC_SCLICK)) { + lis2dh->handler_tap(dev, lis2dh->trig_tap); + + LOG_DBG("@tick=%u click_src=0x%x", k_cycle_get_32(), reg_val); } /* Reactivate level triggered interrupt if handler did not * disable itself */ - if (lis2dh->handler_anymotion != NULL) { + if (lis2dh->handler_anymotion || lis2dh->handler_tap) { setup_int2(dev, true); } @@ -522,49 +621,45 @@ int lis2dh_init_interrupt(const struct device *dev) } LOG_INF("%s: int2 on %s.%02u", dev->name, - cfg->gpio_int.port->name, - cfg->gpio_int.pin); + cfg->gpio_int.port->name, + cfg->gpio_int.pin); /* disable interrupt in case of warm (re)boot */ - status = lis2dh->hw_tf->write_reg( - dev, - cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_CFG : LIS2DH_REG_INT2_CFG, - 0); + status = lis2dh->hw_tf->write_reg(dev, + cfg->hw.anym_on_int1 ? + LIS2DH_REG_INT1_CFG : + LIS2DH_REG_INT2_CFG, + 0); + if (status < 0) { + LOG_ERR("Interrupt disable reg write failed (%d)", status); + return status; + } + status = lis2dh->hw_tf->write_reg(dev, + LIS2DH_REG_CFG_CLICK, + 0); if (status < 0) { LOG_ERR("Interrupt disable reg write failed (%d)", status); return status; } (void)memset(raw, 0, sizeof(raw)); - status = lis2dh->hw_tf->write_data( - dev, - cfg->hw.anym_on_int1 ? LIS2DH_REG_INT1_THS : LIS2DH_REG_INT2_THS, - raw, sizeof(raw)); + status = lis2dh->hw_tf->write_data(dev, + cfg->hw.anym_on_int1 ? + LIS2DH_REG_INT1_THS : + LIS2DH_REG_INT2_THS, + raw, sizeof(raw)); if (status < 0) { LOG_ERR("Burst write to THS failed (%d)", status); return status; } - if (cfg->hw.anym_on_int1) { - /* enable interrupt 1 on int1 line */ - status = lis2dh->hw_tf->update_reg(dev, LIS2DH_REG_CTRL3, - LIS2DH_EN_INT1_INT1, - LIS2DH_EN_INT1_INT1); - if (cfg->hw.anym_latch) { - /* latch int1 line interrupt */ - status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL5, - LIS2DH_EN_LIR_INT1); - } - } else { - /* enable interrupt 2 on int2 line */ - status = lis2dh->hw_tf->update_reg(dev, LIS2DH_REG_CTRL6, - LIS2DH_EN_INT2_INT2, - LIS2DH_EN_INT2_INT2); - if (cfg->hw.anym_latch) { - /* latch int2 line interrupt */ - status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL5, - LIS2DH_EN_LIR_INT2); - } + if (cfg->hw.anym_latch) { + /* latch line interrupt */ + status = lis2dh->hw_tf->write_reg(dev, + LIS2DH_REG_CTRL5, + cfg->hw.anym_on_int1 ? + LIS2DH_EN_LIR_INT1 : + LIS2DH_EN_LIR_INT2); } if (status < 0) { From 6f3bbe19a776720f5a33d2cf62e175acb06cf06a Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Thu, 14 Sep 2023 14:35:30 +0200 Subject: [PATCH 0534/4498] net: ip: stats: changed dependency for PPP stats NET_STATISTICS_PPP are dependend on NET_L2_PPP, not on NET_PPP. This allows to use statistics also in modem subsys. Signed-off-by: Wojciech Slenska --- subsys/net/ip/Kconfig.stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/Kconfig.stats b/subsys/net/ip/Kconfig.stats index 147b002d603..53105e0d70c 100644 --- a/subsys/net/ip/Kconfig.stats +++ b/subsys/net/ip/Kconfig.stats @@ -95,7 +95,7 @@ config NET_STATISTICS_IGMP config NET_STATISTICS_PPP bool "Point-to-point (PPP) statistics" - depends on NET_PPP + depends on NET_L2_PPP default y help Keep track of PPP related statistics From 798b863f3639481f95ec10d3ff923b93eadc60d5 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Fri, 15 Sep 2023 10:36:46 +0200 Subject: [PATCH 0535/4498] modem: modem_ppp: added net stats Added ppp net stats to modem subsys. Signed-off-by: Wojciech Slenska --- include/zephyr/modem/ppp.h | 4 ++++ subsys/modem/modem_ppp.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/zephyr/modem/ppp.h b/include/zephyr/modem/ppp.h index dc592fb90f9..5d6d485e308 100644 --- a/include/zephyr/modem/ppp.h +++ b/include/zephyr/modem/ppp.h @@ -97,6 +97,10 @@ struct modem_ppp { /* Work */ struct k_work send_work; struct k_work process_work; + +#if defined(CONFIG_NET_STATISTICS_PPP) + struct net_stats_ppp stats; +#endif }; /** diff --git a/subsys/modem/modem_ppp.c b/subsys/modem/modem_ppp.c index 48a550d4d1f..476926f4db3 100644 --- a/subsys/modem/modem_ppp.c +++ b/subsys/modem/modem_ppp.c @@ -285,6 +285,9 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) net_pkt_unref(ppp->rx_pkt); ppp->rx_pkt = NULL; ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; +#if defined(CONFIG_NET_STATISTICS_PPP) + ppp->stats.drop++; +#endif } break; @@ -295,6 +298,9 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) net_pkt_unref(ppp->rx_pkt); ppp->rx_pkt = NULL; ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; +#if defined(CONFIG_NET_STATISTICS_PPP) + ppp->stats.drop++; +#endif break; } @@ -433,11 +439,23 @@ static int modem_ppp_ppp_api_send(const struct device *dev, struct net_pkt *pkt) return 0; } +#if defined(CONFIG_NET_STATISTICS_PPP) +static struct net_stats_ppp *modem_ppp_ppp_get_stats(const struct device *dev) +{ + struct modem_ppp *ppp = (struct modem_ppp *)dev->data; + + return &ppp->stats; +} +#endif + const struct ppp_api modem_ppp_ppp_api = { .iface_api.init = modem_ppp_ppp_api_init, .start = modem_ppp_ppp_api_start, .stop = modem_ppp_ppp_api_stop, .send = modem_ppp_ppp_api_send, +#if defined(CONFIG_NET_STATISTICS_PPP) + .get_stats = modem_ppp_ppp_get_stats, +#endif }; int modem_ppp_attach(struct modem_ppp *ppp, struct modem_pipe *pipe) From c7255cf3749a122c30f82a7077f06ac87431b4bf Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 15 Sep 2023 11:05:12 -0400 Subject: [PATCH 0536/4498] kernel: Remove references to _EXPIRED The _EXPIRED macro is no longer necessary. It is a relic of an older timeout processing algorithm from several years ago. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 3 -- kernel/include/ksched.h | 9 ------ kernel/poll.c | 4 --- tests/kernel/poll/src/test_poll.c | 49 ------------------------------- 4 files changed, 65 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index e847ee272be..611f9f2be08 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -676,9 +676,6 @@ static inline k_ticks_t z_impl_k_thread_timeout_remaining_ticks( * @cond INTERNAL_HIDDEN */ -/* timeout has timed out and is not on _timeout_q anymore */ -#define _EXPIRED (-2) - struct _static_thread_data { struct k_thread *init_thread; k_thread_stack_t *init_stack; diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index 4676a0beca1..9d0ef300376 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -268,15 +268,6 @@ static ALWAYS_INLINE void z_sched_unlock_no_reschedule(void) ++_current->base.sched_locked; } -static ALWAYS_INLINE bool z_is_thread_timeout_expired(struct k_thread *thread) -{ -#ifdef CONFIG_SYS_CLOCK_EXISTS - return thread->base.timeout.dticks == _EXPIRED; -#else - return 0; -#endif -} - /* * APIs for working with the Zephyr kernel scheduler. Intended for use in * management of IPC objects, either in the core kernel or other IPC diff --git a/kernel/poll.c b/kernel/poll.c index 27d65c147f0..9903c9c1fab 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -271,10 +271,6 @@ static int signal_poller(struct k_poll_event *event, uint32_t state) return 0; } - if (z_is_thread_timeout_expired(thread)) { - return -EAGAIN; - } - z_unpend_thread(thread); arch_thread_return_value_set(thread, state == K_POLL_STATE_CANCELLED ? -EINTR : 0); diff --git a/tests/kernel/poll/src/test_poll.c b/tests/kernel/poll/src/test_poll.c index 3faa591826a..8af64040a0c 100644 --- a/tests/kernel/poll/src/test_poll.c +++ b/tests/kernel/poll/src/test_poll.c @@ -787,52 +787,3 @@ ZTEST(poll_api_1cpu, test_poll_zero_events) zassert_equal(k_poll(&event, 0, K_MSEC(50)), -EAGAIN); } - -/* subthread entry */ -void polling_event(void *p1, void *p2, void *p3) -{ - k_poll(p1, 1, K_FOREVER); -} - -/** - * @brief Detect is_polling is false in signal_poll_event() - * - * @details - * Define and initialize a signal event, and spawn a thread to - * poll event, and set dticks as invalid, check if the value - * of is_polling in function signal_poll_event(). - * - * @ingroup kernel_poll_tests - */ -ZTEST(poll_api_1cpu, test_detect_is_polling) -{ - k_poll_signal_init(&test_signal); - - struct k_thread *p = &test_thread; - struct k_poll_event events[1] = { - K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &test_signal), - }; - - k_tid_t tid = k_thread_create(&test_thread, test_stack, - K_THREAD_STACK_SIZEOF(test_stack), polling_event, - events, NULL, NULL, K_PRIO_PREEMPT(0), - K_INHERIT_PERMS, K_NO_WAIT); - - /* Set up the thread timeout value to check if - * what happened if dticks is invalid. - */ - p->base.timeout.dticks = _EXPIRED; - /* Wait for register event successfully */ - k_sleep(K_MSEC(50)); - - /* Raise a signal */ - int ret = k_poll_signal_raise(&test_signal, 0x1337); - - zassert_true(ret == -EAGAIN, "thread expired failed\n"); - zassert_true(events[0].poller->is_polling == false, - "the value of is_polling is invalid\n"); - - k_thread_abort(tid); -} From ad8f3e5b4e2854cf58b6384219199b82a0d4c534 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Thu, 14 Sep 2023 18:44:04 +0200 Subject: [PATCH 0537/4498] manifest: hal_nordic: fix wrong include in nrfx_pwm New nrfx revision fixes issue in the PWM driver causing build errors due to invalid include when workaround for anomaly 109 is enabled. Signed-off-by: Nikodem Kastelik --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a02a5026175..3ce53625f87 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 9ae7c765985ebdea3d9b98c0d3b154794f0b47cf + revision: 03807f75485c97bd7b9094e0c20e40f8044da9f5 path: modules/hal/nordic groups: - hal From 1731010869c479e19dd87307b8defa25276418cb Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 15 Sep 2023 21:12:25 -0400 Subject: [PATCH 0538/4498] posix: pthread: do not assert in pthread_exit() on k_thread If `pthread_exit()` is called from a `k_thread`, then we would previously trigger an assertion. The problem with that, is that is POSIX is acting as a compatibility layer. Given that it is a reasonable expectation to have the calling thread exit or abort when calling `pthread_exit()`, lets do just that. Signed-off-by: Christopher Friedt --- lib/posix/pthread.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 0b5ca186530..01734ab615f 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -601,7 +601,6 @@ void pthread_exit(void *retval) self = to_posix_thread(pthread_self()); if (self == NULL) { /* not a valid posix_thread */ - __ASSERT_NO_MSG(self != NULL); k_thread_abort(k_current_get()); } From ceb42a688ea15c81ff8da5fd0fc68ae350b6f979 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 14 Sep 2023 11:27:10 +0000 Subject: [PATCH 0539/4498] kernel: remove reference to non existing z_thread_heap_assign we have no z_thread_heap_assign, was suppoosed to reference k_thread_heap_assign. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 2 +- tests/kernel/mem_protect/mem_protect/src/inherit.c | 2 +- tests/kernel/queue/src/test_queue_contexts.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 611f9f2be08..8f203e5ab59 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -440,7 +440,7 @@ __syscall int k_thread_stack_space_get(const struct k_thread *thread, /** * @brief Assign the system heap as a thread's resource pool * - * Similar to z_thread_heap_assign(), but the thread will use + * Similar to k_thread_heap_assign(), but the thread will use * the kernel heap to draw memory. * * Use with caution, as a malicious thread could perform DoS attacks on the diff --git a/tests/kernel/mem_protect/mem_protect/src/inherit.c b/tests/kernel/mem_protect/mem_protect/src/inherit.c index 7f22d308af6..fc3cb736abe 100644 --- a/tests/kernel/mem_protect/mem_protect/src/inherit.c +++ b/tests/kernel/mem_protect/mem_protect/src/inherit.c @@ -169,7 +169,7 @@ void parent_handler(void *p1, void *p2, void *p3) * * @ingroup kernel_memprotect_tests * - * @see z_thread_heap_assign() + * @see k_thread_heap_assign() */ ZTEST(mem_protect, test_inherit_resource_pool) { diff --git a/tests/kernel/queue/src/test_queue_contexts.c b/tests/kernel/queue/src/test_queue_contexts.c index a96a2300fc8..33832b5b419 100644 --- a/tests/kernel/queue/src/test_queue_contexts.c +++ b/tests/kernel/queue/src/test_queue_contexts.c @@ -294,7 +294,7 @@ static void tqueue_alloc(struct k_queue *pqueue) * @brief Test queue alloc append and prepend * @ingroup kernel_queue_tests * @see k_queue_alloc_append(), k_queue_alloc_prepend(), - * z_thread_heap_assign(), k_queue_is_empty(), + * k_thread_heap_assign(), k_queue_is_empty(), * k_queue_get(), k_queue_remove() */ ZTEST(queue_api, test_queue_alloc) From c64ab308595e0319f1baacd413bb51cbe548b2af Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 14 Sep 2023 13:29:44 +0000 Subject: [PATCH 0540/4498] kernel: kernel_includes.h: double guard header This header should not be included directly, only via kernel.h. Signed-off-by: Anas Nashif --- include/zephyr/kernel_includes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/kernel_includes.h b/include/zephyr/kernel_includes.h index 4e19fa1bd96..f128fcc2c5c 100644 --- a/include/zephyr/kernel_includes.h +++ b/include/zephyr/kernel_includes.h @@ -13,6 +13,10 @@ #ifndef ZEPHYR_INCLUDE_KERNEL_INCLUDES_H_ #define ZEPHYR_INCLUDE_KERNEL_INCLUDES_H_ +#ifndef ZEPHYR_INCLUDE_KERNEL_H_ +#error Please do not include kernel-specific headers directly, use instead +#endif + #include #include #include From cc4ab45a4500dd6b9b6ac44a9baf18adf58bad5b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 14 Sep 2023 13:36:32 +0000 Subject: [PATCH 0541/4498] kernel: header: k_queue struct should not be hidden This is not a private struct, it should not be hidden in the docs. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 8f203e5ab59..c06eec0f381 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1819,10 +1819,6 @@ static inline uint64_t k_cycle_get_64(void) * @} */ -/** - * @cond INTERNAL_HIDDEN - */ - struct k_queue { sys_sflist_t data_q; struct k_spinlock lock; @@ -1833,6 +1829,10 @@ struct k_queue { SYS_PORT_TRACING_TRACKING_FIELD(k_queue) }; +/** + * @cond INTERNAL_HIDDEN + */ + #define Z_QUEUE_INITIALIZER(obj) \ { \ .data_q = SYS_SFLIST_STATIC_INIT(&obj.data_q), \ From 8dc2746c0eba4886e7513ab443e566f3ab91a6bf Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 14 Sep 2023 14:08:07 +0000 Subject: [PATCH 0542/4498] kernel: z_handle_obj_poll_events is internal not kernel.h material This internal kernel API is misplaced in a public kernel header. Just make it available to the code using it in the kernel. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 5 ----- kernel/include/kernel_internal.h | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index c06eec0f381..0cbecc802d3 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5767,11 +5767,6 @@ __syscall void k_poll_signal_check(struct k_poll_signal *sig, __syscall int k_poll_signal_raise(struct k_poll_signal *sig, int result); -/** - * @internal - */ -extern void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state); - /** @} */ /** diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index aaee3095d9e..576996cc9f6 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -227,6 +227,9 @@ void z_mem_manage_init(void); */ void z_mem_manage_boot_finish(void); + +void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state); + #ifdef CONFIG_PM /* When the kernel is about to go idle, it calls this function to notify the From c4e190f414c262c461f0e8034d326689e2463180 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 15 Sep 2023 07:57:28 +0000 Subject: [PATCH 0543/4498] kernel: header: remove unused z_queue_node_peek from kernel.h This function is private to the kernel and should not be exposed in a public header. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 0cbecc802d3..84233df9de2 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1841,8 +1841,6 @@ struct k_queue { _POLL_EVENT_OBJ_INIT(obj) \ } -extern void *z_queue_node_peek(sys_sfnode_t *node, bool needs_free); - /** * INTERNAL_HIDDEN @endcond */ From a4de2eb3d1756c445d2e2ecb72e6d562674c118b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 15 Sep 2023 08:04:48 +0000 Subject: [PATCH 0544/4498] kernel: doc: mark sections as internal in kernel.h Add doxygen conditionals around internal segments of the header. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 84233df9de2..efaad0ce8ec 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5814,6 +5814,7 @@ static inline void k_cpu_atomic_idle(unsigned int key) */ /** + * @cond INTERNAL_HIDDEN * @internal */ #ifdef ARCH_EXCEPT @@ -5840,6 +5841,9 @@ static inline void k_cpu_atomic_idle(unsigned int key) } while (false) #endif /* _ARCH__EXCEPT */ +/** + * INTERNAL_HIDDEN @endcond + */ /** * @brief Fatally terminate a thread @@ -5864,6 +5868,10 @@ static inline void k_cpu_atomic_idle(unsigned int key) */ #define k_panic() z_except_reason(K_ERR_KERNEL_PANIC) +/** + * @cond INTERNAL_HIDDEN + */ + /* * private APIs that are utilized by one or more public APIs */ @@ -5901,6 +5909,9 @@ void z_smp_thread_swap(void); * @internal */ extern void z_timer_expiration_handler(struct _timeout *t); +/** + * INTERNAL_HIDDEN @endcond + */ #ifdef CONFIG_PRINTK /** From d8cdd86132483eb3715044e13eb34b1ee7069cc0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 14 Sep 2023 15:53:02 +0000 Subject: [PATCH 0545/4498] MAINTAINERS: include the ethos driver in the ethos module The driver is bound to the module, there's no separate platform, so let's just add the driver path to the module area so that changes for it gets tagged and assigned. Signed-off-by: Fabio Baltieri --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a075530316c..3ed671854b2 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3023,6 +3023,7 @@ West: maintainers: - kristofer-jonsson-arm files: + - drivers/misc/ethos_u/ - modules/hal_ethos_u/ labels: - manifest-hal_ethos_u From 36883d2e6811b32a29158e842018deeef6290d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Fri, 15 Sep 2023 14:30:09 +0100 Subject: [PATCH 0546/4498] samx2x: separate RAM/Flash sizes by model. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This creates separate dtsi files for the various memory density codes of SAM X2xfamilies (they are the same where the specific size exists.) All of the boards with the exclusion of EV11L78A use the same density model of 18 (32KiB RAM and 256KiB flash) which is what the samd2x.dtsi include specified for all of them previously. The density code has been confirmed being the same across the D20/D21, C20/C21, L21, and R21 families. This does not carry over to some other series such as the E5x. Signed-off-by: Diego Elio Pettenò --- .../adafruit_feather_m0_basic_proto.dts | 1 + .../adafruit_feather_m0_lora.dts | 1 + .../adafruit_trinket_m0.dts | 1 + .../arm/arduino_mkrzero/arduino_mkrzero.dts | 1 + .../arduino_nano_33_iot.dts | 1 + boards/arm/arduino_zero/arduino_zero.dts | 1 + boards/arm/atsamc21n_xpro/atsamc21n_xpro.dts | 3 ++- boards/arm/atsamd20_xpro/atsamd20_xpro.dts | 1 + boards/arm/atsamd21_xpro/atsamd21_xpro.dts | 1 + boards/arm/atsamr21_xpro/atsamr21_xpro.dts | 1 + boards/arm/ev11l78a/ev11l78a.dts | 6 +++-- boards/arm/seeeduino_xiao/seeeduino_xiao.dts | 1 + boards/arm/serpente/serpente.dts | 1 + dts/arm/atmel/samc20x15.dtsi | 22 ------------------- dts/arm/atmel/samc20x16.dtsi | 22 ------------------- dts/arm/atmel/samc20x17.dtsi | 22 ------------------- dts/arm/atmel/samc20x18.dtsi | 22 ------------------- dts/arm/atmel/samc21x15.dtsi | 22 ------------------- dts/arm/atmel/samc21x16.dtsi | 22 ------------------- dts/arm/atmel/samc21x17.dtsi | 22 ------------------- dts/arm/atmel/samc21x18.dtsi | 22 ------------------- dts/arm/atmel/samd2x.dtsi | 2 -- dts/arm/atmel/samx2xx14.dtsi | 15 +++++++++++++ dts/arm/atmel/samx2xx15.dtsi | 15 +++++++++++++ dts/arm/atmel/samx2xx16.dtsi | 15 +++++++++++++ dts/arm/atmel/samx2xx17.dtsi | 15 +++++++++++++ dts/arm/atmel/samx2xx18.dtsi | 15 +++++++++++++ 27 files changed, 92 insertions(+), 181 deletions(-) delete mode 100644 dts/arm/atmel/samc20x15.dtsi delete mode 100644 dts/arm/atmel/samc20x16.dtsi delete mode 100644 dts/arm/atmel/samc20x17.dtsi delete mode 100644 dts/arm/atmel/samc20x18.dtsi delete mode 100644 dts/arm/atmel/samc21x15.dtsi delete mode 100644 dts/arm/atmel/samc21x16.dtsi delete mode 100644 dts/arm/atmel/samc21x17.dtsi delete mode 100644 dts/arm/atmel/samc21x18.dtsi create mode 100644 dts/arm/atmel/samx2xx14.dtsi create mode 100644 dts/arm/atmel/samx2xx15.dtsi create mode 100644 dts/arm/atmel/samx2xx16.dtsi create mode 100644 dts/arm/atmel/samx2xx17.dtsi create mode 100644 dts/arm/atmel/samx2xx18.dtsi diff --git a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts index df83c6d6ddd..8d98095e703 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts +++ b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "adafruit_feather_m0_basic_proto-pinctrl.dtsi" #include "feather_connector.dtsi" diff --git a/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.dts b/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.dts index ac62ebca4f4..c69f547622c 100644 --- a/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.dts +++ b/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "adafruit_feather_m0_lora-pinctrl.dtsi" #include "feather_connector.dtsi" diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts index ce128b6807b..dd227354dc0 100644 --- a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts +++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "adafruit_trinket_m0-pinctrl.dtsi" / { diff --git a/boards/arm/arduino_mkrzero/arduino_mkrzero.dts b/boards/arm/arduino_mkrzero/arduino_mkrzero.dts index 657aca978a1..b682e84aec8 100644 --- a/boards/arm/arduino_mkrzero/arduino_mkrzero.dts +++ b/boards/arm/arduino_mkrzero/arduino_mkrzero.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "arduino_mkrzero-pinctrl.dtsi" #include "arduino_mkr_connector.dtsi" diff --git a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts index 732084dab3e..6cce683f0a9 100644 --- a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts +++ b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "arduino_nano_33_iot-pinctrl.dtsi" #include "arduino_nano_r3_connector.dtsi" diff --git a/boards/arm/arduino_zero/arduino_zero.dts b/boards/arm/arduino_zero/arduino_zero.dts index 4eff1db0e85..841e7ab7620 100644 --- a/boards/arm/arduino_zero/arduino_zero.dts +++ b/boards/arm/arduino_zero/arduino_zero.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "arduino_zero-pinctrl.dtsi" / { diff --git a/boards/arm/atsamc21n_xpro/atsamc21n_xpro.dts b/boards/arm/atsamc21n_xpro/atsamc21n_xpro.dts index e1d64e9124d..da657b5788b 100644 --- a/boards/arm/atsamc21n_xpro/atsamc21n_xpro.dts +++ b/boards/arm/atsamc21n_xpro/atsamc21n_xpro.dts @@ -6,7 +6,8 @@ /dts-v1/; -#include +#include +#include #include "atsamc21n_xpro-pinctrl.dtsi" #include diff --git a/boards/arm/atsamd20_xpro/atsamd20_xpro.dts b/boards/arm/atsamd20_xpro/atsamd20_xpro.dts index ade715cd77c..778d76b6017 100644 --- a/boards/arm/atsamd20_xpro/atsamd20_xpro.dts +++ b/boards/arm/atsamd20_xpro/atsamd20_xpro.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "atsamd20_xpro-pinctrl.dtsi" #include diff --git a/boards/arm/atsamd21_xpro/atsamd21_xpro.dts b/boards/arm/atsamd21_xpro/atsamd21_xpro.dts index b51712589e4..e48e5afd467 100644 --- a/boards/arm/atsamd21_xpro/atsamd21_xpro.dts +++ b/boards/arm/atsamd21_xpro/atsamd21_xpro.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "atsamd21_xpro-pinctrl.dtsi" #include diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts index a94621730eb..9dd7f6f91d6 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "atsamr21_xpro-pinctrl.dtsi" #include diff --git a/boards/arm/ev11l78a/ev11l78a.dts b/boards/arm/ev11l78a/ev11l78a.dts index 0096fe9651d..02fa9f35915 100644 --- a/boards/arm/ev11l78a/ev11l78a.dts +++ b/boards/arm/ev11l78a/ev11l78a.dts @@ -6,7 +6,9 @@ /dts-v1/; #include +#include #include +#include #include "ev11l78a-pinctrl.dtsi" / { @@ -94,9 +96,9 @@ * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@3c000 { + storage_partition: partition@c000 { label = "storage"; - reg = <0x0003c000 0x00004000>; + reg = ; }; }; }; diff --git a/boards/arm/seeeduino_xiao/seeeduino_xiao.dts b/boards/arm/seeeduino_xiao/seeeduino_xiao.dts index a0bc69a4814..0859e87e635 100644 --- a/boards/arm/seeeduino_xiao/seeeduino_xiao.dts +++ b/boards/arm/seeeduino_xiao/seeeduino_xiao.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "seeeduino_xiao-pinctrl.dtsi" #include "seeed_xiao_connector.dtsi" diff --git a/boards/arm/serpente/serpente.dts b/boards/arm/serpente/serpente.dts index 3237920aa5e..d042cb4a363 100644 --- a/boards/arm/serpente/serpente.dts +++ b/boards/arm/serpente/serpente.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "serpente-pinctrl.dtsi" / { diff --git a/dts/arm/atmel/samc20x15.dtsi b/dts/arm/atmel/samc20x15.dtsi deleted file mode 100644 index fc1b141dab2..00000000000 --- a/dts/arm/atmel/samc20x15.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(4)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(32)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc20x16.dtsi b/dts/arm/atmel/samc20x16.dtsi deleted file mode 100644 index 8bffaf72078..00000000000 --- a/dts/arm/atmel/samc20x16.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(8)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(64)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc20x17.dtsi b/dts/arm/atmel/samc20x17.dtsi deleted file mode 100644 index 2149e2b5898..00000000000 --- a/dts/arm/atmel/samc20x17.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(16)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(128)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc20x18.dtsi b/dts/arm/atmel/samc20x18.dtsi deleted file mode 100644 index d819ae2492e..00000000000 --- a/dts/arm/atmel/samc20x18.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(32)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(256)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc21x15.dtsi b/dts/arm/atmel/samc21x15.dtsi deleted file mode 100644 index 0e4ef466428..00000000000 --- a/dts/arm/atmel/samc21x15.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(4)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(32)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc21x16.dtsi b/dts/arm/atmel/samc21x16.dtsi deleted file mode 100644 index 7f66c19dbb3..00000000000 --- a/dts/arm/atmel/samc21x16.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(8)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(64)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc21x17.dtsi b/dts/arm/atmel/samc21x17.dtsi deleted file mode 100644 index b09568beb1b..00000000000 --- a/dts/arm/atmel/samc21x17.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(16)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(128)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samc21x18.dtsi b/dts/arm/atmel/samc21x18.dtsi deleted file mode 100644 index 353c2d23253..00000000000 --- a/dts/arm/atmel/samc21x18.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/ { - sram0: memory@20000000 { - reg = <0x20000000 DT_SIZE_K(32)>; - }; - - soc { - nvmctrl: nvmctrl@41004000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(256)>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/samd2x.dtsi b/dts/arm/atmel/samd2x.dtsi index feae5b3ccb9..c247daffc1a 100644 --- a/dts/arm/atmel/samd2x.dtsi +++ b/dts/arm/atmel/samd2x.dtsi @@ -33,7 +33,6 @@ sram0: memory@20000000 { compatible = "mmio-sram"; - reg = <0x20000000 0x8000>; }; id: device_id@80a00c { @@ -71,7 +70,6 @@ flash0: flash@0 { compatible = "soc-nv-flash"; - reg = <0 0x40000>; write-block-size = <4>; }; }; diff --git a/dts/arm/atmel/samx2xx14.dtsi b/dts/arm/atmel/samx2xx14.dtsi new file mode 100644 index 00000000000..8e345dda9a5 --- /dev/null +++ b/dts/arm/atmel/samx2xx14.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_K(2)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(16)>; +}; diff --git a/dts/arm/atmel/samx2xx15.dtsi b/dts/arm/atmel/samx2xx15.dtsi new file mode 100644 index 00000000000..88bfa454b14 --- /dev/null +++ b/dts/arm/atmel/samx2xx15.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_K(4)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(32)>; +}; diff --git a/dts/arm/atmel/samx2xx16.dtsi b/dts/arm/atmel/samx2xx16.dtsi new file mode 100644 index 00000000000..484c06315ce --- /dev/null +++ b/dts/arm/atmel/samx2xx16.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_K(8)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(64)>; +}; diff --git a/dts/arm/atmel/samx2xx17.dtsi b/dts/arm/atmel/samx2xx17.dtsi new file mode 100644 index 00000000000..19b8b2607cf --- /dev/null +++ b/dts/arm/atmel/samx2xx17.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_K(16)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(128)>; +}; diff --git a/dts/arm/atmel/samx2xx18.dtsi b/dts/arm/atmel/samx2xx18.dtsi new file mode 100644 index 00000000000..2abbffa6ee7 --- /dev/null +++ b/dts/arm/atmel/samx2xx18.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_K(32)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(256)>; +}; From ea9dd594606ab7b181bb799258bfbcaf7dc378f9 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 1 Sep 2023 14:22:31 +0200 Subject: [PATCH 0547/4498] yamllint: bindings: add ipll clock index Adding new property to intel,adsp-shim-clkctl with ACE integrated PLL clock index. Signed-off-by: Tomasz Leman --- dts/bindings/clock/intel,adsp-shim-clkctl.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dts/bindings/clock/intel,adsp-shim-clkctl.yaml b/dts/bindings/clock/intel,adsp-shim-clkctl.yaml index c0c73856ed2..99e8ec83c84 100644 --- a/dts/bindings/clock/intel,adsp-shim-clkctl.yaml +++ b/dts/bindings/clock/intel,adsp-shim-clkctl.yaml @@ -19,6 +19,10 @@ properties: type: int description: Index of HPRO clock encoding in the encoding array. + adsp-clkctl-clk-ipll: + type: int + description: Index of ACE integrated PLL clock encoding in the encoding array. + adsp-clkctl-freq-enc: type: array required: true From 2f2689e3d3103b8e6fa8d677e71634518630532b Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Thu, 7 Sep 2023 13:27:46 +0200 Subject: [PATCH 0548/4498] intel_adsp: ace15: shim: update wovrco request bit Updating value of WOVRCO request bit in CLKCTL register according to the documentation. Previus value was mask used for clock enabling. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_shim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_shim.h b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_shim.h index a6faa63c3d2..56997ee84d1 100644 --- a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_shim.h +++ b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_shim.h @@ -140,7 +140,7 @@ struct ace_dfpmccu { #endif /* _ASMLANGUAGE */ -#define ACE_CLKCTL_WOVCRO BIT(4) /* Request WOVCRO clock */ +#define ACE_CLKCTL_WOVCRO BIT(21) /* Request WOVCRO clock */ #define SHIM_LDOCTL_HPSRAM_LDO_ON (3 << 0) #define SHIM_LDOCTL_HPSRAM_LDO_BYPASS BIT(0) From dcecda859c5784488cd034d2c8b515333d5a7064 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 8 Sep 2023 13:39:43 +0200 Subject: [PATCH 0549/4498] dts: adsp: ace15: replace hp with ipll clock The ACE family platforms do not have LP/HP RING OSC clocks. They were replaced by the ACE IP integrated PLL clock. Selecting LP or HP in CLKCTL will result in enabling IPLL. Clock can supply frequencies for both replaced clocks, default frequency equals to 393.2 MHz. Signed-off-by: Tomasz Leman --- dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi index f68c745f45d..6f8fd52163c 100644 --- a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi @@ -82,7 +82,7 @@ compatible = "intel,adsp-shim-clkctl"; adsp-clkctl-clk-wovcro = <0>; adsp-clkctl-clk-lpro = <1>; - adsp-clkctl-clk-hpro = <2>; + adsp-clkctl-clk-ipll = <2>; adsp-clkctl-freq-enc = <0xc 0x0 0x4>; adsp-clkctl-freq-mask = <0x0 0x0 0x0>; adsp-clkctl-freq-default = <2>; From 2d835e1b297346a6e7a5b62f2fc2cd2f77b6c5a3 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 8 Sep 2023 14:24:44 +0200 Subject: [PATCH 0550/4498] dts: adsp: ace20: replace hp with ipll clock The ACE family platforms do not have LP/HP RING OSC clocks. They were replaced by the ACE IP integrated PLL clock. Selecting LP or HP in CLKCTL will result in enabling IPLL. Clock can supply frequencies for both replaced clocks, default frequency equals to 393.2 MHz. Signed-off-by: Tomasz Leman --- dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi index f47c94ddf1b..ad1259ea452 100644 --- a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi @@ -96,7 +96,7 @@ compatible = "intel,adsp-shim-clkctl"; adsp-clkctl-clk-wovcro = <0>; adsp-clkctl-clk-lpro = <1>; - adsp-clkctl-clk-hpro = <2>; + adsp-clkctl-clk-ipll = <2>; adsp-clkctl-freq-enc = <0xc 0x0 0x4>; adsp-clkctl-freq-mask = <0x0 0x0 0x0>; adsp-clkctl-freq-default = <2>; From cf6d5f95b6dc17d60b2f6382508ebd6b84c6bcf4 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 8 Sep 2023 14:39:53 +0200 Subject: [PATCH 0551/4498] adsp: clk: ace: select ipll if wovrco is unavailable Selecting Low Power clock has the same result as selecting High Performance clock (now IPLL). Therefore, the LP clock will be removed from the list of available clocks on ACE family platforms. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/common/clk.c | 2 +- soc/xtensa/intel_adsp/common/include/adsp_clk.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/common/clk.c b/soc/xtensa/intel_adsp/common/clk.c index fada03528bf..99421914407 100644 --- a/soc/xtensa/intel_adsp/common/clk.c +++ b/soc/xtensa/intel_adsp/common/clk.c @@ -84,7 +84,7 @@ void adsp_clock_init(void) if (ACE_DfPMCCU.dfclkctl & ACE_CLKCTL_WOVCRO) { ACE_DfPMCCU.dfclkctl = ACE_DfPMCCU.dfclkctl & ~ACE_CLKCTL_WOVCRO; } else { - platform_lowest_freq_idx = ADSP_CPU_CLOCK_FREQ_LPRO; + platform_lowest_freq_idx = ADSP_CPU_CLOCK_FREQ_IPLL; } #else CAVS_SHIM.clkctl |= CAVS_CLKCTL_WOVCRO; diff --git a/soc/xtensa/intel_adsp/common/include/adsp_clk.h b/soc/xtensa/intel_adsp/common/include/adsp_clk.h index 94d2cb07c00..34d7c21822d 100644 --- a/soc/xtensa/intel_adsp/common/include/adsp_clk.h +++ b/soc/xtensa/intel_adsp/common/include/adsp_clk.h @@ -59,6 +59,8 @@ struct adsp_cpu_clock_info *adsp_cpu_clocks_get(void); #define ADSP_CPU_CLOCK_FREQ_WOVCRO ADSP_CPU_CLOCK_FREQ(wovcro) #endif +#define ADSP_CPU_CLOCK_FREQ_IPLL ADSP_CPU_CLOCK_FREQ(ipll) + /* Clock sources used by dai */ #define ADSP_CLOCK_SOURCE_XTAL_OSC 0 From 50f0e223e87bfe03ae33ef9cbcb8f92002eaabb6 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 8 Sep 2023 15:38:45 +0200 Subject: [PATCH 0552/4498] dts: adsp: ace15: remove lp clock LP/HP RING OSC clocks were replaced by the ACE IPLL clock. If needed IPLL can be configured to work as low power clock. But right now ACE uses only WOVCRO and IPLL (configured to work as HP RING OSC clock). Signed-off-by: Tomasz Leman --- dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi index 6f8fd52163c..564ee3fe26d 100644 --- a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi @@ -81,11 +81,10 @@ clkctl: clkctl { compatible = "intel,adsp-shim-clkctl"; adsp-clkctl-clk-wovcro = <0>; - adsp-clkctl-clk-lpro = <1>; - adsp-clkctl-clk-ipll = <2>; - adsp-clkctl-freq-enc = <0xc 0x0 0x4>; - adsp-clkctl-freq-mask = <0x0 0x0 0x0>; - adsp-clkctl-freq-default = <2>; + adsp-clkctl-clk-ipll = <1>; + adsp-clkctl-freq-enc = <0xc 0x4>; + adsp-clkctl-freq-mask = <0x0 0x0>; + adsp-clkctl-freq-default = <1>; adsp-clkctl-freq-lowest = <0>; wovcro-supported; }; From 9656056b191cee544c60436dfa2745c4825f150d Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 8 Sep 2023 15:47:10 +0200 Subject: [PATCH 0553/4498] dts: adsp: ace20: remove lp clock LP/HP RING OSC clocks were replaced by the ACE IPLL clock. If needed IPLL can be configured to work as low power clock. But right now ACE uses only WOVCRO and IPLL (configured to work as HP RING OSC clock). Signed-off-by: Tomasz Leman --- dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi index ad1259ea452..726e94bc271 100644 --- a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi @@ -95,11 +95,10 @@ clkctl: clkctl { compatible = "intel,adsp-shim-clkctl"; adsp-clkctl-clk-wovcro = <0>; - adsp-clkctl-clk-lpro = <1>; - adsp-clkctl-clk-ipll = <2>; - adsp-clkctl-freq-enc = <0xc 0x0 0x4>; - adsp-clkctl-freq-mask = <0x0 0x0 0x0>; - adsp-clkctl-freq-default = <2>; + adsp-clkctl-clk-ipll = <1>; + adsp-clkctl-freq-enc = <0xc 0x4>; + adsp-clkctl-freq-mask = <0x0 0x0>; + adsp-clkctl-freq-default = <1>; adsp-clkctl-freq-lowest = <0>; wovcro-supported; }; From a5d1fd98578ce1d1df0947607f4adc1efebe0684 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Thu, 7 Sep 2023 15:14:04 +0200 Subject: [PATCH 0554/4498] soc: adsp: clk: update clock switch flow This patch corrects clock selection flow for ACE platforms. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/common/clk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/soc/xtensa/intel_adsp/common/clk.c b/soc/xtensa/intel_adsp/common/clk.c index 99421914407..0f3f3d32b80 100644 --- a/soc/xtensa/intel_adsp/common/clk.c +++ b/soc/xtensa/intel_adsp/common/clk.c @@ -25,6 +25,15 @@ int adsp_clock_freq_mask[] = ADSP_CPU_CLOCK_FREQ_MASK; static void select_cpu_clock_hw(uint32_t freq_idx) { uint32_t enc = adsp_clock_freq_enc[freq_idx]; + +#ifdef CONFIG_SOC_SERIES_INTEL_ACE + uint32_t clk_ctl = ADSP_CLKCTL; + + clk_ctl &= ~ADSP_CLKCTL_OSC_SOURCE_MASK; + clk_ctl |= (enc & ADSP_CLKCTL_OSC_SOURCE_MASK); + + ADSP_CLKCTL = clk_ctl; +#else uint32_t status_mask = adsp_clock_freq_mask[freq_idx]; /* Request clock */ @@ -42,6 +51,7 @@ static void select_cpu_clock_hw(uint32_t freq_idx) /* Release other clocks */ ADSP_CLKCTL &= ~ADSP_CLKCTL_OSC_REQUEST_MASK | enc; +#endif } int adsp_clock_set_cpu_freq(uint32_t freq_idx) From 738b12428153c6498a8581bce74a7f50ae50d181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 17:05:28 +0700 Subject: [PATCH 0555/4498] tests: kernel: usage: skip for mr_canhubk3 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mr_canhubk3 board enables by default an off-chip watchdog that must be serviced to avoid triggering a reset and cannot be disabled on a per-test basis. test_all_stats_usage assumes the CPU was never idle before the test starts but this is not the case for mr_canhubk3 because the off-chip watchdog driver has a thread kicked off during device init that will conflict with the expected usage stats on this test. So skip this test for this board. Signed-off-by: Manuel Argüelles --- tests/kernel/usage/thread_runtime_stats/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/kernel/usage/thread_runtime_stats/testcase.yaml b/tests/kernel/usage/thread_runtime_stats/testcase.yaml index 30d67c3741c..05fabf3ba57 100644 --- a/tests/kernel/usage/thread_runtime_stats/testcase.yaml +++ b/tests/kernel/usage/thread_runtime_stats/testcase.yaml @@ -16,3 +16,5 @@ tests: integration_platforms: - qemu_x86 - mps2_an385 + platform_exclude: + - mr_canhubk3 From c9cc03b6ef929409569d69aa31608b11f12378e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:22:41 +0700 Subject: [PATCH 0556/4498] samples: tracing: exclude mr_canhubk3 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mr_canhubk3 board enables by default an off-chip watchdog that must be serviced to avoid triggering a reset and cannot be disabled on a per-test basis. The amount of data printed on this test prevents to initialize the on-board watchdog within the expected window, causing a board reset. Hence do not run the test on mr_canhubk3 board. Signed-off-by: Manuel Argüelles --- samples/subsys/tracing/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index f206a4e9ca4..75868ade861 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -13,6 +13,8 @@ tests: extra_args: CONF_FILE="prj_user.conf" integration_platforms: - qemu_x86 + platform_exclude: + - mr_canhubk3 harness_config: type: multi_line regex: From 775ec5ac190d2737cf31e164ef7eff66c7375fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 13 Sep 2023 12:04:09 +0700 Subject: [PATCH 0557/4498] tests: watchdog: wdt_basic_api: make mr_canhubk3 build only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests cannot be executed in the board because ECC initialization will clear SRAM contents that are used by this test to persist data across resets. Signed-off-by: Manuel Argüelles --- tests/drivers/watchdog/wdt_basic_api/testcase.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 4ea568ca15e..f42734011c8 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -112,11 +112,12 @@ tests: - longan_nano integration_platforms: - gd32e103v_eval - drivers.watchdog.s32z270dc2_r52: + drivers.watchdog.nxp_s32: build_only: true platform_allow: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - mr_canhubk3 drivers.watchdog.mimxrt1050_evk_ti_tps382x: filter: dt_compat_enabled("ti,tps382x") platform_allow: mimxrt1050_evk From da56b98f8b1b7ab8a4ac2272d9e4686bcf672afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 13 Sep 2023 12:23:09 +0700 Subject: [PATCH 0558/4498] tests: arch: arm_irq_vector_table: exclude mr_canhubk3 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mr_canhubk3 board enables by default an off-chip watchdog that must be serviced to avoid triggering a reset and cannot be disabled on a per-test basis. To add the needed ISR for this test involve doing modifications to the LPSPI MCUX driver that does not worth the trouble for this test only, so exclude this board. Signed-off-by: Manuel Argüelles --- tests/arch/arm/arm_irq_vector_table/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/arch/arm/arm_irq_vector_table/testcase.yaml b/tests/arch/arm/arm_irq_vector_table/testcase.yaml index c570d1a0488..b1bacbca309 100644 --- a/tests/arch/arm/arm_irq_vector_table/testcase.yaml +++ b/tests/arch/arm/arm_irq_vector_table/testcase.yaml @@ -8,3 +8,5 @@ common: tests: arch.arm.irq_vector_table: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE + platform_exclude: + - mr_canhubk3 From 78cc40f4e525b23ad1b42745c63a5bd5204541ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 13 Sep 2023 12:15:51 +0700 Subject: [PATCH 0559/4498] tests: code_relocation: exclude mr_canhubk3 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mr_canhubk3 board enables by default an off-chip watchdog that must be serviced to avoid triggering a reset and cannot be disabled on a per-test basis. The watchdog driver make uses of a semaphore during device init and on this test the relocation of the kernel sources produces a fault. So skip this test for this board. Signed-off-by: Manuel Argüelles --- .../code_relocation/testcase.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/application_development/code_relocation/testcase.yaml b/tests/application_development/code_relocation/testcase.yaml index 6f3fc3dc537..e67885390d8 100644 --- a/tests/application_development/code_relocation/testcase.yaml +++ b/tests/application_development/code_relocation/testcase.yaml @@ -15,15 +15,6 @@ tests: - CONFIG_MPU_ALLOW_FLASH_WRITE=y platform_allow: - frdm_k64f - application_development.code_relocation.nxp_s32: - filter: dt_chosen_enabled("zephyr,itcm") - arch_allow: arm - extra_configs: - - CONFIG_MINIMAL_LIBC=y - - CONFIG_RELOCATE_TO_ITCM=y - - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y - platform_allow: - - mr_canhubk3 application_development.code_relocation.no_itcm: filter: not CONFIG_CPU_HAS_NXP_MPU and not dt_chosen_enabled("zephyr,itcm") arch_allow: arm From f5fa4b3bcdd8af30ac2a8d95b32be9776cd6b953 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 13 Sep 2023 07:24:52 -0300 Subject: [PATCH 0560/4498] soc: espressif: provide VMA to rodata and text by default Flash segments require VMA to proper work. Executing from LMA is not possible. Current implementation did not take into account runtime iterable rom sections that any application could implement. In the above cenario and as reported in the issue below, ESP32 won't run when those ROM sections are created in application level. This change make sure all flash segments are properly mapped accordingly. Fixes #61834 Signed-off-by: Sylvio Alves --- soc/riscv/espressif_esp32/esp32c3/default.ld | 11 +++++------ soc/xtensa/espressif_esp32/esp32/default.ld | 11 +++++------ soc/xtensa/espressif_esp32/esp32_net/linker.ld | 11 +++++------ soc/xtensa/espressif_esp32/esp32s2/default.ld | 11 +++++------ soc/xtensa/espressif_esp32/esp32s3/default.ld | 11 +++++------ 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/soc/riscv/espressif_esp32/esp32c3/default.ld b/soc/riscv/espressif_esp32/esp32c3/default.ld index 01aeb903af2..9fb9f0c1ab0 100644 --- a/soc/riscv/espressif_esp32/esp32c3/default.ld +++ b/soc/riscv/espressif_esp32/esp32c3/default.ld @@ -49,6 +49,11 @@ #define IROM_SEG_ALIGN 0x10000 #endif +/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + /* Global symbols required for espressif hal build */ MEMORY { @@ -185,11 +190,6 @@ SECTIONS . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion #include #include #include @@ -197,7 +197,6 @@ SECTIONS #include #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ diff --git a/soc/xtensa/espressif_esp32/esp32/default.ld b/soc/xtensa/espressif_esp32/esp32/default.ld index b04399a24ac..ddc95c4527f 100644 --- a/soc/xtensa/espressif_esp32/esp32/default.ld +++ b/soc/xtensa/espressif_esp32/esp32/default.ld @@ -46,6 +46,11 @@ #endif #define IRAM_SEG_LEN 0x20000 +/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + MEMORY { mcuboot_hdr (RX): org = 0x0, len = 0x20 @@ -209,11 +214,6 @@ SECTIONS . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion #include #include #include @@ -221,7 +221,6 @@ SECTIONS #include #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ diff --git a/soc/xtensa/espressif_esp32/esp32_net/linker.ld b/soc/xtensa/espressif_esp32/esp32_net/linker.ld index 6c1b69872b1..2b815957e84 100644 --- a/soc/xtensa/espressif_esp32/esp32_net/linker.ld +++ b/soc/xtensa/espressif_esp32/esp32_net/linker.ld @@ -26,6 +26,11 @@ #define ROMABLE_DATA_REGION dram0_1_seg #define dram0_0_seg dram0_1_seg +/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + MEMORY { iram0_0_seg(RX): org = 0x40080000 + 0x08000, len = 0x18000 @@ -200,11 +205,6 @@ SECTIONS . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_DATA_REGION) - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion #include #include #include @@ -212,7 +212,6 @@ SECTIONS #include #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ diff --git a/soc/xtensa/espressif_esp32/esp32s2/default.ld b/soc/xtensa/espressif_esp32/esp32s2/default.ld index c6681215e5d..35e2889db56 100644 --- a/soc/xtensa/espressif_esp32/esp32s2/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s2/default.ld @@ -53,6 +53,11 @@ #define IROM_SEG_ALIGN 0x10000 #endif +/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + MEMORY { mcuboot_hdr (RX): org = 0x0, len = 0x20 @@ -181,18 +186,12 @@ SECTIONS . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion #include #include #include #include #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index b3cbd62c89b..fc6a4e47d0e 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -59,6 +59,11 @@ #define IROM_SEG_ALIGN 0x10000 +/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + MEMORY { mcuboot_hdr (RX): org = 0x0, len = 0x20 @@ -207,11 +212,6 @@ SECTIONS . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion #include #include #include @@ -219,7 +219,6 @@ SECTIONS #include #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ From eae44a55d87b9a351ffc3acdb6403a7800c442fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Thu, 14 Sep 2023 10:51:32 +0200 Subject: [PATCH 0561/4498] net: lib: sockets: sockets_tls: prefix mbedtls error with 0x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The errors are printed in hex, but no prefix was used. This could be confused with usual errno return values. The 0x prefix makes clear that it's a hex value. Also a missing minus sign is added to one log message. Signed-off-by: Martin Jäger --- subsys/net/lib/sockets/sockets_tls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 20fdc3617af..a6950243392 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -602,7 +602,7 @@ static int tls_session_save(const struct sockaddr *peer_addr, ret = mbedtls_ssl_session_save(session, entry->session, session_len, &session_len); if (ret < 0) { - NET_ERR("Failed to serialize session, err: 0x%x.", -ret); + NET_ERR("Failed to serialize session, err: -0x%x.", -ret); mbedtls_free(entry->session); entry->session = NULL; return -ENOMEM; @@ -1231,7 +1231,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, /* MbedTLS API documentation requires session to * be reset in other error cases */ - NET_ERR("TLS handshake error: -%x", -ret); + NET_ERR("TLS handshake error: -0x%x", -ret); ret = tls_mbedtls_reset(context); if (ret == 0) { ret = -ECONNABORTED; @@ -1240,7 +1240,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, } /* Avoid constant loop if tls_mbedtls_reset fails */ - NET_ERR("TLS reset error: -%x", -ret); + NET_ERR("TLS reset error: -0x%x", -ret); ret = -ECONNABORTED; break; } From a7b25d599b87b7aa8ee5755454448045b2e1ba99 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Wed, 13 Sep 2023 12:16:52 -0600 Subject: [PATCH 0562/4498] fuel_gauge: Join get/set prop structs The fuel gauge API uses separate get/set property structs to indicate what properties are readable or writable. This lead to duplication in property names and potential confusion for new users of the API. See issue #61818. In addition to above, drivers already determine at runtime if a property is supported for read or write actions. Join the get/set fuel gauge property structs as a single struct. Signed-off-by: Aaron Massey --- doc/hardware/peripherals/fuel_gauge.rst | 2 +- drivers/fuel_gauge/bq27z746/bq27z746.c | 10 ++-- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 24 ++++---- drivers/fuel_gauge/max17048/max17048.c | 4 +- drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 10 ++-- include/zephyr/drivers/fuel_gauge.h | 59 +++++-------------- samples/fuel_gauge/max17048/src/main.c | 2 +- .../fuel_gauge/bq27z746/src/test_bq27z746.c | 8 +-- .../fuel_gauge/max17048/src/test_max17048.c | 8 +-- .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 20 +++---- 10 files changed, 60 insertions(+), 87 deletions(-) diff --git a/doc/hardware/peripherals/fuel_gauge.rst b/doc/hardware/peripherals/fuel_gauge.rst index bef7b122796..ee6ba3ddbad 100644 --- a/doc/hardware/peripherals/fuel_gauge.rst +++ b/doc/hardware/peripherals/fuel_gauge.rst @@ -20,7 +20,7 @@ Fundamentally, a property is a quantity that a fuel gauge device can measure. Fuel gauges typically support multiple properties, such as temperature readings of the battery-pack or present-time current/voltage. -Properties are fetched using a client allocated array of :c:struct:`fuel_gauge_get_property`. This +Properties are fetched using a client allocated array of :c:struct:`fuel_gauge_property`. This array is then populated by values as according to its `property_type` field. Battery Cutoff diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index 802de27bad9..41086fb8699 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -109,7 +109,7 @@ static int bq27z746_read_mac(const struct device *dev, uint16_t cmd, uint8_t *da return ret; } -static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_get_property *prop) +static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_property *prop) { int rc = 0; uint16_t val = 0; @@ -198,7 +198,7 @@ static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_get_pro } static int bq27z746_get_buffer_prop(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, void *dst, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len) { int rc = 0; @@ -236,7 +236,7 @@ static int bq27z746_get_buffer_prop(const struct device *dev, return rc; } -static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_set_property *prop) +static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_property *prop) { int rc = 0; uint16_t val = 0; @@ -260,7 +260,7 @@ static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_set_pro return rc; } -static int bq27z746_get_props(const struct device *dev, struct fuel_gauge_get_property *props, +static int bq27z746_get_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { int err_count = 0; @@ -276,7 +276,7 @@ static int bq27z746_get_props(const struct device *dev, struct fuel_gauge_get_pr return err_count; } -static int bq27z746_set_props(const struct device *dev, struct fuel_gauge_set_property *props, +static int bq27z746_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { int err_count = 0; diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 4c664b0f551..2db583bfdb5 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -9,19 +9,19 @@ #include static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_get_property *props, + struct fuel_gauge_property *props, size_t props_len) { - struct fuel_gauge_get_property k_props[props_len]; + struct fuel_gauge_property k_props[props_len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); Z_OOPS(z_user_from_copy(k_props, props, - props_len * sizeof(struct fuel_gauge_get_property))); + props_len * sizeof(struct fuel_gauge_property))); int ret = z_impl_fuel_gauge_get_prop(dev, k_props, props_len); - Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_get_property))); + Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); return ret; } @@ -29,19 +29,19 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, #include static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_set_property *props, + struct fuel_gauge_property *props, size_t props_len) { - struct fuel_gauge_set_property k_props[props_len]; + struct fuel_gauge_property k_props[props_len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); Z_OOPS(z_user_from_copy(k_props, props, - props_len * sizeof(struct fuel_gauge_set_property))); + props_len * sizeof(struct fuel_gauge_property))); int ret = z_impl_fuel_gauge_set_prop(dev, k_props, props_len); - Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_set_property))); + Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); return ret; } @@ -49,22 +49,22 @@ static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, #include static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len) { - struct fuel_gauge_get_buffer_property k_prop; + struct fuel_gauge_buffer_property k_prop; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); Z_OOPS(z_user_from_copy(&k_prop, prop, - sizeof(struct fuel_gauge_get_buffer_property))); + sizeof(struct fuel_gauge_buffer_property))); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, dst_len)); int ret = z_impl_fuel_gauge_get_buffer_prop(dev, &k_prop, dst, dst_len); Z_OOPS(z_user_to_copy(prop, &k_prop, - sizeof(struct fuel_gauge_get_buffer_property))); + sizeof(struct fuel_gauge_buffer_property))); return ret; } diff --git a/drivers/fuel_gauge/max17048/max17048.c b/drivers/fuel_gauge/max17048/max17048.c index 3da147e3c29..76f14e67d91 100644 --- a/drivers/fuel_gauge/max17048/max17048.c +++ b/drivers/fuel_gauge/max17048/max17048.c @@ -175,7 +175,7 @@ static int max17048_init(const struct device *dev) /** * Get a single property from the fuel gauge */ -static int max17048_get_prop(const struct device *dev, struct fuel_gauge_get_property *prop) +static int max17048_get_prop(const struct device *dev, struct fuel_gauge_property *prop) { struct max17048_data *data = dev->data; int rc = 0; @@ -205,7 +205,7 @@ static int max17048_get_prop(const struct device *dev, struct fuel_gauge_get_pro /** * Get all possible properties from the fuel gague */ -static int max17048_get_props(const struct device *dev, struct fuel_gauge_get_property *props, +static int max17048_get_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { int err_count = 0; diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index e136900187d..1cb855fd03d 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -66,7 +66,7 @@ static int sbs_cmd_buffer_read(const struct device *dev, uint8_t reg_addr, char return 0; } -static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_get_property *prop) +static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop) { int rc = 0; uint16_t val = 0; @@ -196,7 +196,7 @@ static int sbs_gauge_do_battery_cutoff(const struct device *dev) return rc; } -static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_property *prop) +static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop) { int rc = 0; uint16_t val = 0; @@ -236,7 +236,7 @@ static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_pr } static int sbs_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, void *dst, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len) { int rc = 0; @@ -274,7 +274,7 @@ static int sbs_gauge_get_buffer_prop(const struct device *dev, return rc; } -static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_get_property *props, +static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { int err_count = 0; @@ -290,7 +290,7 @@ static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_get_p return err_count; } -static int sbs_gauge_set_props(const struct device *dev, struct fuel_gauge_set_property *props, +static int sbs_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { int err_count = 0; diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 5be69baa8ab..9b878c0ae0c 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -28,7 +28,7 @@ extern "C" { /* Keep these alphabetized wrt property name */ -enum fuel_gauge_property { +enum fuel_gauge_prop_type { /** Runtime Dynamic Battery Parameters */ /** * Provide a 1 minute average of the current on the battery. @@ -115,7 +115,7 @@ enum fuel_gauge_property { typedef uint16_t fuel_gauge_prop_t; -struct fuel_gauge_get_property { +struct fuel_gauge_property { /** Battery fuel gauge property to get */ fuel_gauge_prop_t property_type; @@ -184,35 +184,8 @@ struct fuel_gauge_get_property { } value; }; -struct fuel_gauge_set_property { - /** Battery fuel gauge property to set */ - fuel_gauge_prop_t property_type; - - /** Negative error status set by callee e.g. -ENOTSUP for an unsupported property */ - int status; - - /** Property field for setting */ - union { - /* Fields have the format: */ - /* FUEL_GAUGE_PROPERTY_FIELD */ - /* type property_field; */ - - /* Writable Dynamic Battery Info */ - /** FUEL_GAUGE_SBS_MFR_ACCESS */ - uint16_t sbs_mfr_access_word; - /** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */ - uint16_t sbs_remaining_capacity_alarm; - /** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */ - uint16_t sbs_remaining_time_alarm; - /** FUEL_GAUGE_SBS_MODE */ - uint16_t sbs_mode; - /** FUEL_GAUGE_SBS_ATRATE */ - int16_t sbs_at_rate; - } value; -}; - /** Buffer properties are separated due to size */ -struct fuel_gauge_get_buffer_property { +struct fuel_gauge_buffer_property { /** Battery fuel gauge property to get */ fuel_gauge_prop_t property_type; @@ -249,7 +222,7 @@ struct sbs_gauge_device_chemistry { * See fuel_gauge_get_property() for argument description */ typedef int (*fuel_gauge_get_property_t)(const struct device *dev, - struct fuel_gauge_get_property *props, size_t props_len); + struct fuel_gauge_property *props, size_t props_len); /** * @typedef fuel_gauge_set_property_t @@ -258,7 +231,7 @@ typedef int (*fuel_gauge_get_property_t)(const struct device *dev, * See fuel_gauge_set_property() for argument description */ typedef int (*fuel_gauge_set_property_t)(const struct device *dev, - struct fuel_gauge_set_property *props, size_t props_len); + struct fuel_gauge_property *props, size_t props_len); /** * @typedef fuel_gauge_get_buffer_property_t @@ -267,7 +240,7 @@ typedef int (*fuel_gauge_set_property_t)(const struct device *dev, * See fuel_gauge_get_buffer_property() for argument description */ typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len); /** @@ -291,20 +264,20 @@ __subsystem struct fuel_gauge_driver_api { * @brief Fetch a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param props pointer to array of fuel_gauge_get_property struct where the property struct + * @param props pointer to array of fuel_gauge_property struct where the property struct * field is set by the caller to determine what property is read from the - * fuel gauge device into the fuel_gauge_get_property struct's value field. The props array + * fuel gauge device into the fuel_gauge_property struct's value field. The props array * maintains the same order of properties as it was given. * @param props_len number of properties in props array * * @return return=0 if successful, return < 0 if getting all properties failed, return > 0 if some * properties failed where return=number of failing properties. */ -__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_get_property *props, +__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *props, size_t props_len); static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_get_property *props, + struct fuel_gauge_property *props, size_t props_len) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; @@ -320,19 +293,19 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, * @brief Set a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param props pointer to array of fuel_gauge_set_property struct where the property struct + * @param props pointer to array of fuel_gauge_property struct where the property struct * field is set by the caller to determine what property is written to the fuel gauge device from - * the fuel_gauge_get_property struct's value field. + * the fuel_gauge_property struct's value field. * @param props_len number of properties in props array * * @return return=0 if successful, return < 0 if setting all properties failed, return > 0 if some * properties failed where return=number of failing properties. */ -__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_property *props, +__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *props, size_t props_len); static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_set_property *props, + struct fuel_gauge_property *props, size_t props_len) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; @@ -357,11 +330,11 @@ static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, * @return return=0 if successful, return < 0 if getting property failed, return 0 on success */ __syscall int fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, void *dst, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len); static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_get_buffer_property *prop, + struct fuel_gauge_buffer_property *prop, void *dst, size_t dst_len) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; diff --git a/samples/fuel_gauge/max17048/src/main.c b/samples/fuel_gauge/max17048/src/main.c index 01428f10aba..62121f6da82 100644 --- a/samples/fuel_gauge/max17048/src/main.c +++ b/samples/fuel_gauge/max17048/src/main.c @@ -38,7 +38,7 @@ int main(void) while (1) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, }, diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c index 88d8b59c9f4..ec6cbcb1488 100644 --- a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -33,7 +33,7 @@ static void *bq27z746_setup(void) ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* Invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -50,7 +50,7 @@ ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* First invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -82,7 +82,7 @@ ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) ZTEST_USER_F(bq27z746, test_get_buffer_prop) { - struct fuel_gauge_get_buffer_property prop; + struct fuel_gauge_buffer_property prop; int ret; { @@ -137,7 +137,7 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_AVG_CURRENT, }, diff --git a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c index 8507b36049e..fbb495d5ebf 100644 --- a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c +++ b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c @@ -34,7 +34,7 @@ static void *max17048_setup(void) ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* Invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -51,7 +51,7 @@ ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) ZTEST_USER_F(max17048, test_get_some_props_failed_returns_failed_prop_count) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* First invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -86,7 +86,7 @@ ZTEST_USER_F(max17048, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, }, @@ -115,7 +115,7 @@ ZTEST_USER_F(max17048, test_current_rate_zero) { /* Test when crate is 0, which is a special case */ - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, }, diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 9b812e64310..6eee40c19ca 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -34,7 +34,7 @@ static void *sbs_gauge_new_api_setup(void) ZTEST_USER_F(sbs_gauge_new_api, test_get_all_props_failed_returns_negative) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* Invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -51,7 +51,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_all_props_failed_returns_negative) ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_count) { - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { /* First invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -83,7 +83,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_c ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative) { - struct fuel_gauge_set_property props[] = { + struct fuel_gauge_property props[] = { { /* Invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -100,7 +100,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative) ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_count) { - struct fuel_gauge_set_property props[] = { + struct fuel_gauge_property props[] = { { /* First invalid property */ .property_type = FUEL_GAUGE_PROP_MAX, @@ -135,7 +135,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_c ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) { uint16_t word = BIT(15) | BIT(0); - struct fuel_gauge_set_property set_props[] = { + struct fuel_gauge_property set_props[] = { { /* Valid property */ .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, @@ -160,7 +160,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) }, }; - struct fuel_gauge_get_property get_props[] = { + struct fuel_gauge_property get_props[] = { { .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, }, @@ -201,7 +201,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_VOLTAGE, }, @@ -290,7 +290,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_set_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, }, @@ -322,7 +322,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) { /* Validate what properties are supported by the driver */ - struct fuel_gauge_get_buffer_property prop; + struct fuel_gauge_buffer_property prop; struct sbs_gauge_manufacturer_name mfg_name; struct sbs_gauge_device_name dev_name; struct sbs_gauge_device_chemistry chem; @@ -350,7 +350,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) uint32_t expected_uV = 5000 * 1000; uint32_t expected_uA = 3000 * 1000; - struct fuel_gauge_get_property props[] = { + struct fuel_gauge_property props[] = { { .property_type = FUEL_GAUGE_VOLTAGE, }, From 131105811de373c6324fddca1024ecd5f75ac8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 15 Sep 2023 13:12:42 +0200 Subject: [PATCH 0563/4498] boards: esp32: M5Stack Core2 has PCF8563 RTC, not PCF8523 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RTC chip on i2c0 is a PCF8563, not a PCF8523. RTC _almost_ works when using the latter, but not quite, hence why it probably was missed before. Fix tested as working using RTC Shell commands. Signed-off-by: Benjamin Cabé --- boards/xtensa/m5stack_core2/m5stack_core2.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index f90a19c3981..35ed29ae32f 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -93,10 +93,9 @@ pinctrl-names = "default"; pfc8563_rtc: pfc8563@51 { - compatible = "nxp,pcf8523"; + compatible = "nxp,pcf8563"; reg = <0x51>; status = "okay"; - battery-switch-over = "disabled"; }; axp192_pmic: axp192@34 { From 3e369ec8ed0c55016d0fb63391617d37ba1d7adc Mon Sep 17 00:00:00 2001 From: Hein Wessels Date: Fri, 15 Sep 2023 14:25:39 +0200 Subject: [PATCH 0564/4498] drivers: spi: stm32: LOG_INF should be LOG_DBG to not clutter console Drivers should only log extra information during initialization if debug logging is enabled. Otherwise it always clutters the console when not required. Signed-off-by: Hein Wessels --- drivers/spi/spi_ll_stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index d4ad84fae77..dc640613882 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -1038,7 +1038,7 @@ static int spi_stm32_init(const struct device *dev) return -ENODEV; } - LOG_INF(" SPI with DMA transfer"); + LOG_DBG("SPI with DMA transfer"); #endif /* CONFIG_SPI_STM32_DMA */ From 5dfc93b73ce931e591c8eeb36163999e49f3a22d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 15 Sep 2023 16:10:37 +0200 Subject: [PATCH 0565/4498] tests interrupt_offload: Set a proper interrupt for POSIX arch targets The test assumed that interrupt line 5 was up for grabs, but it is not in general. (For ex., on an nrf53_bsim this is the clock interrupt, which cannot be hijacked). Instead, for boards that define it, let's use the int line used for offloading SW interrupts (which is defined for all posix arch boards in tree) And if this is not defined, let's skip the test. Signed-off-by: Alberto Escolar Piedras --- tests/kernel/interrupt/src/interrupt_offload.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/kernel/interrupt/src/interrupt_offload.c b/tests/kernel/interrupt/src/interrupt_offload.c index f025cbc4261..f0aa0f54c7c 100644 --- a/tests/kernel/interrupt/src/interrupt_offload.c +++ b/tests/kernel/interrupt/src/interrupt_offload.c @@ -7,6 +7,9 @@ #include #include #include +#if defined(CONFIG_ARCH_POSIX) +#include +#endif #define STACK_SIZE 1024 #define NUM_WORK 4 @@ -89,7 +92,11 @@ void isr_handler(const void *param) #define TEST_IRQ_DYN_LINE 26 #elif defined(CONFIG_ARCH_POSIX) -#define TEST_IRQ_DYN_LINE 5 +#if defined(OFFLOAD_SW_IRQ) +#define TEST_IRQ_DYN_LINE OFFLOAD_SW_IRQ +#else +#define TEST_IRQ_DYN_LINE 0 +#endif #else #define TEST_IRQ_DYN_LINE 0 From e3aa649ee09cc076c9f8bbe281ff0a2fc53fb110 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 4 Sep 2023 15:20:35 +0200 Subject: [PATCH 0566/4498] native simulator: Get latest from upstream Align with native_simulator's upstream main 64b8be6311a61df2c63987813e8058560c8dc49c Which includes: * 64b8be6 Make: Give option to add extra localization parameters * 05bc3ce Generalize code for N CPUs/MCUs * 489069b Makefile: Generalize for N embedded images * a4c817e runner->embedded trampolines: Improve definitions * 8d8dd29 nsi_utils: Provide debracket macro * 6b4956e Add optional embedded test hook definition Signed-off-by: Alberto Escolar Piedras --- scripts/native_simulator/Makefile | 28 ++++--- .../common/src/include/nsi_cpu_ctrl.h | 46 ++++++++++++ .../common/src/include/nsi_cpu_if.h | 42 +++++------ .../common/src/include/nsi_cpu_if_internal.h | 74 +++++++++++++++++++ .../common/src/{ => include}/nsi_utils.h | 2 + scripts/native_simulator/common/src/main.c | 24 ++++-- .../native_simulator/common/src/nsi_config.h | 14 ++++ .../common/src/nsi_cpu_ctrl.c | 52 +++++++++++++ .../native_simulator/common/src/nsi_cpun_if.c | 42 +---------- .../native_simulator/common/src/nsi_cpun_if.h | 1 + .../common/src/nsi_weak_stubs.c | 46 +++++------- 11 files changed, 261 insertions(+), 110 deletions(-) create mode 100644 scripts/native_simulator/common/src/include/nsi_cpu_ctrl.h create mode 100644 scripts/native_simulator/common/src/include/nsi_cpu_if_internal.h rename scripts/native_simulator/common/src/{ => include}/nsi_utils.h (87%) create mode 100644 scripts/native_simulator/common/src/nsi_config.h create mode 100644 scripts/native_simulator/common/src/nsi_cpu_ctrl.c diff --git a/scripts/native_simulator/Makefile b/scripts/native_simulator/Makefile index 9dbdb66f31a..e74b1c7bc69 100644 --- a/scripts/native_simulator/Makefile +++ b/scripts/native_simulator/Makefile @@ -27,12 +27,15 @@ NSI_BUILD_PATH?=$(abspath _build/) EXE_NAME?=native_simulator.exe # Final executable path/file_name which will be produced NSI_EXE?=${NSI_BUILD_PATH}/${EXE_NAME} -# Path to the embedded SW which will be linked with the final executable +# Number of embedded CPUs/MCUs +NSI_N_CPUS?=1 +# Path to all CPUs embedded SW which will be linked with the final executable NSI_EMBEDDED_CPU_SW?= # Host architecture configuration switch NSI_ARCH?=-m32 # Coverage switch (GCOV coverage is enabled by default) NSI_COVERAGE?=--coverage +NSI_LOCALIZE_OPTIONS?= NSI_BUILD_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE} NSI_LINK_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE} # Extra source files to be built in the runner context @@ -61,7 +64,7 @@ NSI_CPPFLAGS?=-D_POSIX_C_SOURCE=200809 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTEN NO_PIE_CO:=-fno-pie -fno-pic DEPENDFLAGS:=-MMD -MP -CFLAGS:=${NSI_DEBUG} ${NSI_WARNINGS} ${NSI_OPT} ${NO_PIE_CO} \ +CFLAGS:=${NSI_DEBUG} ${NSI_WARNINGS} ${NSI_OPT} ${NO_PIE_CO} -DNSI_N_CPUS=${NSI_N_CPUS} \ -ffunction-sections -fdata-sections ${DEPENDFLAGS} -std=c11 ${NSI_BUILD_OPTIONS} FINALLINK_FLAGS:=${NO_PIE_CO} -no-pie ${NSI_WARNINGS} \ -Wl,--gc-sections -ldl -pthread \ @@ -93,6 +96,8 @@ DEPENDFILES:=$(addsuffix .d,$(basename ${OBJS})) -include ${DEPENDFILES} +LOCALIZED_EMBSW:=$(abspath $(addprefix $(NSI_BUILD_PATH)/,$(addsuffix .loc_cpusw.o,${NSI_EMBEDDED_CPU_SW}))) + ${NSI_BUILD_PATH}: @if [ ! -d ${NSI_BUILD_PATH} ]; then mkdir -p ${NSI_BUILD_PATH}; fi @@ -112,16 +117,19 @@ ${NSI_BUILD_PATH}/${RUNNER_LIB}: ${OBJS} if [ -f $@ ]; then rm $@ ; fi ${NSI_AR} -cr $@ ${OBJS} -${NSI_EXE}: ${NSI_BUILD_PATH}/${RUNNER_LIB} ${NSI_EMBEDDED_CPU_SW} ${NSI_EXTRA_LIBS} \ - ${NSI_BUILD_PATH}/linker_script.ld - @if [ -z ${NSI_EMBEDDED_CPU_SW} ] || [ ! -f ${NSI_EMBEDDED_CPU_SW} ]; then \ - echo "Error: Input embedded CPU SW not found (NSI_EMBEDDED_CPU_SW=${NSI_EMBEDDED_CPU_SW} )"; \ +${NSI_BUILD_PATH}/%.loc_cpusw.o: /% ${NSI_CONFIG_FILE} + @if [ -z $< ] || [ ! -f $< ]; then \ + echo "Error: Input embedded CPU SW ($<) not found \ +(NSI_EMBEDDED_CPU_SW=${NSI_EMBEDDED_CPU_SW} )"; \ false; \ fi - ${NSI_OBJCOPY} --localize-hidden ${NSI_EMBEDDED_CPU_SW} ${NSI_BUILD_PATH}/cpu_0.sw.o \ - -w --localize-symbol=_* - ${NSI_CC} -Wl,--whole-archive ${NSI_BUILD_PATH}/cpu_0.sw.o ${NSI_BUILD_PATH}/${RUNNER_LIB} \ - ${NSI_EXTRA_LIBS} -Wl,--no-whole-archive \ + @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi + ${NSI_OBJCOPY} --localize-hidden $< $@ -w --localize-symbol=_* ${NSI_LOCALIZE_OPTIONS} + +${NSI_EXE}: ${NSI_BUILD_PATH}/${RUNNER_LIB} ${LOCALIZED_EMBSW} ${NSI_EXTRA_LIBS} \ + ${NSI_BUILD_PATH}/linker_script.ld + ${NSI_CC} -Wl,--whole-archive ${LOCALIZED_EMBSW} ${NSI_BUILD_PATH}/${RUNNER_LIB} \ + ${NSI_EXTRA_LIBS} -Wl,--no-whole-archive \ -o $@ ${FINALLINK_FLAGS} -T ${NSI_BUILD_PATH}/linker_script.ld Makefile: ; diff --git a/scripts/native_simulator/common/src/include/nsi_cpu_ctrl.h b/scripts/native_simulator/common/src/include/nsi_cpu_ctrl.h new file mode 100644 index 00000000000..4ea3ba37ddc --- /dev/null +++ b/scripts/native_simulator/common/src/include/nsi_cpu_ctrl.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NSI_COMMON_SRC_INCL_NSI_CPU_CTRL_H +#define NSI_COMMON_SRC_INCL_NSI_CPU_CTRL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Define if a CPU should automatically start at boot or not + * + * @param[in] cpu_n: Which CPU + * @param[in] auto_start: If true, it will autostart on its own, + * if 0, it won't + */ +void nsi_cpu_set_auto_start(int cpu_n, bool auto_start); + +bool nsi_cpu_get_auto_start(int cpu_n); + +/** + * @brief Boot CPU + * + * Note: This API may only be called if that CPU was not stared before + * + * @param[in] cpu_n: Which CPU + */ +void nsi_cpu_boot(int cpu_n); + +/* + * Internal native simulator runner API. + * Boot all CPUs which are configured to boot automatically + */ +void nsi_cpu_auto_boot(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NSI_COMMON_SRC_INCL_NSI_CPU_CTRL_H */ diff --git a/scripts/native_simulator/common/src/include/nsi_cpu_if.h b/scripts/native_simulator/common/src/include/nsi_cpu_if.h index 47afcf029e7..991b0b29917 100644 --- a/scripts/native_simulator/common/src/include/nsi_cpu_if.h +++ b/scripts/native_simulator/common/src/include/nsi_cpu_if.h @@ -11,6 +11,8 @@ extern "C" { #endif +#include "nsi_cpu_if_internal.h" + /* * Any symbol annotated by this macro will be visible outside of the * embedded SW library, both by the native simulator runner, @@ -93,31 +95,21 @@ NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised(void); */ NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised_from_sw(void); -#define NSI_CPU_IF_N(i) \ -NATIVE_SIMULATOR_IF void nsif_cpu##i##_pre_cmdline_hooks(void); \ -NATIVE_SIMULATOR_IF void nsif_cpu##i##_pre_hw_init_hooks(void); \ -NATIVE_SIMULATOR_IF void nsif_cpu##i##_boot(void); \ -NATIVE_SIMULATOR_IF int nsif_cpu##i##_cleanup(void); \ -NATIVE_SIMULATOR_IF void nsif_cpu##i##_irq_raised(void); \ -NATIVE_SIMULATOR_IF void nsif_cpu##i##_irq_raised_from_sw(void); - -NSI_CPU_IF_N(1) -NSI_CPU_IF_N(2) -NSI_CPU_IF_N(3) -NSI_CPU_IF_N(4) -NSI_CPU_IF_N(5) -NSI_CPU_IF_N(6) -NSI_CPU_IF_N(7) -NSI_CPU_IF_N(8) -NSI_CPU_IF_N(9) -NSI_CPU_IF_N(10) -NSI_CPU_IF_N(11) -NSI_CPU_IF_N(12) -NSI_CPU_IF_N(13) -NSI_CPU_IF_N(14) -NSI_CPU_IF_N(15) - -#undef NSI_CPU_IF_N +/* + * Optional hook which may be used for test functionality. + * When the runner HW models use them and for what is up to those + * specific models. + */ +NATIVE_SIMULATOR_IF int nsif_cpu0_test_hook(void *p); + +/* Provide prototypes for all n instances of these hooks */ +F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _pre_cmdline_hooks(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _pre_hw_init_hooks(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _boot(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF int nsif_cpu, _cleanup(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _irq_raised(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _irq_raised_from_sw(void)) +F_TRAMP_LIST(NATIVE_SIMULATOR_IF int nsif_cpu, _test_hook(void *p)) #ifdef __cplusplus } diff --git a/scripts/native_simulator/common/src/include/nsi_cpu_if_internal.h b/scripts/native_simulator/common/src/include/nsi_cpu_if_internal.h new file mode 100644 index 00000000000..d75f64065e2 --- /dev/null +++ b/scripts/native_simulator/common/src/include/nsi_cpu_if_internal.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NSI_COMMON_SRC_INCL_NSI_CPU_IF_INTERNAL_H +#define NSI_COMMON_SRC_INCL_NSI_CPU_IF_INTERNAL_H + +#include "nsi_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FUNCT(i, pre, post) \ + pre##i##post + +#define FUNCT_LIST(pre, post, sep) \ + FUNCT(0, pre, post) NSI_DEBRACKET sep \ + FUNCT(1, pre, post) NSI_DEBRACKET sep \ + FUNCT(2, pre, post) NSI_DEBRACKET sep \ + FUNCT(3, pre, post) NSI_DEBRACKET sep \ + FUNCT(4, pre, post) NSI_DEBRACKET sep \ + FUNCT(5, pre, post) NSI_DEBRACKET sep \ + FUNCT(6, pre, post) NSI_DEBRACKET sep \ + FUNCT(7, pre, post) NSI_DEBRACKET sep \ + FUNCT(8, pre, post) NSI_DEBRACKET sep \ + FUNCT(9, pre, post) NSI_DEBRACKET sep \ + FUNCT(10, pre, post) NSI_DEBRACKET sep \ + FUNCT(11, pre, post) NSI_DEBRACKET sep \ + FUNCT(12, pre, post) NSI_DEBRACKET sep \ + FUNCT(13, pre, post) NSI_DEBRACKET sep \ + FUNCT(14, pre, post) NSI_DEBRACKET sep \ + FUNCT(15, pre, post) NSI_DEBRACKET sep \ + +#define F_TRAMP_TABLE(pre, post) FUNCT_LIST(pre, post, (,)) + +#define F_TRAMP_LIST(pre, post) FUNCT_LIST(pre, post, (;)) + +#define F_TRAMP_BODY_LIST(pre, post) FUNCT_LIST(pre, post, ()) + +#define TRAMPOLINES(pre, post) \ + void pre ## n ## post(int n) \ + { \ + void(*fptrs[])(void) = { \ + F_TRAMP_TABLE(pre, post) \ + }; \ + fptrs[n](); \ + } + +#define TRAMPOLINES_i_vp(pre, post) \ + int pre ## n ## post(int n, void *p) \ + { \ + int(*fptrs[])(void *p) = { \ + F_TRAMP_TABLE(pre, post) \ + }; \ + return fptrs[n](p); \ + } + +#define TRAMPOLINES_i_(pre, post) \ + int pre ## n ## post(int n) \ + { \ + int(*fptrs[])(void) = { \ + F_TRAMP_TABLE(pre, post) \ + }; \ + return fptrs[n](); \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* NSI_COMMON_SRC_INCL_NSI_CPU_IF_INTERNAL_H */ diff --git a/scripts/native_simulator/common/src/nsi_utils.h b/scripts/native_simulator/common/src/include/nsi_utils.h similarity index 87% rename from scripts/native_simulator/common/src/nsi_utils.h rename to scripts/native_simulator/common/src/include/nsi_utils.h index 83f2f22943b..f41fdf9ddc8 100644 --- a/scripts/native_simulator/common/src/nsi_utils.h +++ b/scripts/native_simulator/common/src/include/nsi_utils.h @@ -8,6 +8,8 @@ #ifndef NSI_COMMON_SRC_INCL_NSI_UTILS_H #define NSI_COMMON_SRC_INCL_NSI_UTILS_H +/* Remove brackets from around a single argument: */ +#define NSI_DEBRACKET(...) __VA_ARGS__ #define _NSI_STRINGIFY(x) #x #define NSI_STRINGIFY(s) _NSI_STRINGIFY(s) diff --git a/scripts/native_simulator/common/src/main.c b/scripts/native_simulator/common/src/main.c index b97904a43d3..ffe1d3b93d1 100644 --- a/scripts/native_simulator/common/src/main.c +++ b/scripts/native_simulator/common/src/main.c @@ -14,25 +14,29 @@ #include #include #include -#include "nsi_cpu_if.h" +#include "nsi_cpun_if.h" #include "nsi_tasks.h" #include "nsi_cmdline_main_if.h" #include "nsi_utils.h" #include "nsi_hw_scheduler.h" +#include "nsi_config.h" +#include "nsi_cpu_ctrl.h" int nsi_exit_inner(int exit_code) { static int max_exit_code; + int cpu_ret; max_exit_code = NSI_MAX(exit_code, max_exit_code); /* - * nsif_cpu0_cleanup may not return if this is called from a SW thread, + * nsif_cpun_cleanup may not return if this is called from a SW thread, * but instead it would get nsi_exit() recalled again * ASAP from the HW thread */ - int cpu_0_ret = nsif_cpu0_cleanup(); - - max_exit_code = NSI_MAX(cpu_0_ret, max_exit_code); + for (int i = 0; i < NSI_N_CPUS; i++) { + cpu_ret = nsif_cpun_cleanup(i); + max_exit_code = NSI_MAX(cpu_ret, max_exit_code); + } nsi_run_tasks(NSITASK_ON_EXIT_PRE_LEVEL); nsi_hws_cleanup(); @@ -62,19 +66,23 @@ static void nsi_init(int argc, char *argv[]) setvbuf(stderr, NULL, _IOLBF, 512); nsi_run_tasks(NSITASK_PRE_BOOT_1_LEVEL); - nsif_cpu0_pre_cmdline_hooks(); + for (int i = 0; i < NSI_N_CPUS; i++) { + nsif_cpun_pre_cmdline_hooks(i); + } nsi_handle_cmd_line(argc, argv); nsi_run_tasks(NSITASK_PRE_BOOT_2_LEVEL); - nsif_cpu0_pre_hw_init_hooks(); + for (int i = 0; i < NSI_N_CPUS; i++) { + nsif_cpun_pre_hw_init_hooks(i); + } nsi_run_tasks(NSITASK_HW_INIT_LEVEL); nsi_hws_init(); nsi_run_tasks(NSITASK_PRE_BOOT_3_LEVEL); - nsif_cpu0_boot(); + nsi_cpu_auto_boot(); nsi_run_tasks(NSITASK_FIRST_SLEEP_LEVEL); } diff --git a/scripts/native_simulator/common/src/nsi_config.h b/scripts/native_simulator/common/src/nsi_config.h new file mode 100644 index 00000000000..1ca67ddc8b1 --- /dev/null +++ b/scripts/native_simulator/common/src/nsi_config.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NSI_COMMON_SRC_NSI_CONFIG_H +#define NSI_COMMON_SRC_NSI_CONFIG_H + +#ifndef NSI_N_CPUS +#define NSI_N_CPUS 1 +#endif + +#endif /* NSI_COMMON_SRC_NSI_CONFIG_H */ diff --git a/scripts/native_simulator/common/src/nsi_cpu_ctrl.c b/scripts/native_simulator/common/src/nsi_cpu_ctrl.c new file mode 100644 index 00000000000..4b7e5cd1b65 --- /dev/null +++ b/scripts/native_simulator/common/src/nsi_cpu_ctrl.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "nsi_config.h" +#include "nsi_cpun_if.h" +#include "nsi_tracing.h" + +static bool cpu_auto_start[NSI_N_CPUS] = {true}; /* Only the first core starts on its own */ +static bool cpu_booted[NSI_N_CPUS]; + +#define CPU_N_RANGE_CHECK(cpu_n) \ + if (cpu_n >= NSI_N_CPUS) { \ + nsi_print_error_and_exit("%s called with cpu_n(%i) >= NSI_N_CPUS (%i)\n", \ + cpu_n, NSI_N_CPUS); \ + } + +void nsi_cpu_set_auto_start(int cpu_n, bool auto_start) +{ + CPU_N_RANGE_CHECK(cpu_n); + + cpu_auto_start[cpu_n] = auto_start; +} + +bool nsi_cpu_get_auto_start(int cpu_n) +{ + return cpu_auto_start[cpu_n]; +} + +void nsi_cpu_auto_boot(void) +{ + for (int i = 0; i < NSI_N_CPUS; i++) { + if (cpu_auto_start[i] == true) { + cpu_booted[i] = true; + nsif_cpun_boot(i); + } + } +} + +void nsi_cpu_boot(int cpu_n) +{ + CPU_N_RANGE_CHECK(cpu_n); + if (cpu_booted[cpu_n]) { + nsi_print_warning("%s called with cpu_n(%i) which was already booted\n", + cpu_n); + } + cpu_booted[cpu_n] = true; + nsif_cpun_boot(cpu_n); +} diff --git a/scripts/native_simulator/common/src/nsi_cpun_if.c b/scripts/native_simulator/common/src/nsi_cpun_if.c index 174c770a7a4..c30bfd5a587 100644 --- a/scripts/native_simulator/common/src/nsi_cpun_if.c +++ b/scripts/native_simulator/common/src/nsi_cpun_if.c @@ -11,48 +11,10 @@ * for ex., nsif_cpun_boot(4) -> nsif_cpu4_boot() */ -#define FUNCT(i, pre, post) \ - pre##i##post - -#define F_TABLE(pre, post) \ - FUNCT(0, pre, post), \ - FUNCT(1, pre, post), \ - FUNCT(2, pre, post), \ - FUNCT(3, pre, post), \ - FUNCT(4, pre, post), \ - FUNCT(5, pre, post), \ - FUNCT(6, pre, post), \ - FUNCT(7, pre, post), \ - FUNCT(8, pre, post), \ - FUNCT(9, pre, post), \ - FUNCT(10, pre, post), \ - FUNCT(11, pre, post), \ - FUNCT(12, pre, post), \ - FUNCT(13, pre, post), \ - FUNCT(14, pre, post), \ - FUNCT(15, pre, post) - -#define TRAMPOLINES(pre, post) \ - void pre ## n ## post(int n) \ - { \ - void(*fptrs[])(void) = { \ - F_TABLE(pre, post) \ - }; \ - fptrs[n](); \ - } - -#define TRAMPOLINES_i(pre, post) \ - int pre ## n ## post(int n) \ - { \ - int(*fptrs[])(void) = { \ - F_TABLE(pre, post) \ - }; \ - return fptrs[n](); \ - } - TRAMPOLINES(nsif_cpu, _pre_cmdline_hooks) TRAMPOLINES(nsif_cpu, _pre_hw_init_hooks) TRAMPOLINES(nsif_cpu, _boot) -TRAMPOLINES_i(nsif_cpu, _cleanup) +TRAMPOLINES_i_(nsif_cpu, _cleanup) TRAMPOLINES(nsif_cpu, _irq_raised) TRAMPOLINES(nsif_cpu, _irq_raised_from_sw) +TRAMPOLINES_i_vp(nsif_cpu, _test_hook) diff --git a/scripts/native_simulator/common/src/nsi_cpun_if.h b/scripts/native_simulator/common/src/nsi_cpun_if.h index c072e5938ea..d0d546378cc 100644 --- a/scripts/native_simulator/common/src/nsi_cpun_if.h +++ b/scripts/native_simulator/common/src/nsi_cpun_if.h @@ -21,6 +21,7 @@ void nsif_cpun_boot(int n); int nsif_cpun_cleanup(int n); void nsif_cpun_irq_raised(int n); void nsif_cpun_irq_raised_from_sw(int n); +void nsif_cpun_test_hook(int n, void *p); #ifdef __cplusplus } diff --git a/scripts/native_simulator/common/src/nsi_weak_stubs.c b/scripts/native_simulator/common/src/nsi_weak_stubs.c index b2e7e2d2ebd..3c4f096684c 100644 --- a/scripts/native_simulator/common/src/nsi_weak_stubs.c +++ b/scripts/native_simulator/common/src/nsi_weak_stubs.c @@ -12,33 +12,25 @@ * The CPU does not boot, and interrupts are just ignored * These are all defined as weak, so if an actual image is present for that CPU, * that will be linked against. + * + * This exists in case the total device image is assembled lacking some of the embedded CPU images */ -#define NSI_CPU_STUBBED_IMAGE(i) \ -__attribute__((weak)) void nsif_cpu##i##_pre_cmdline_hooks(void) { } \ -__attribute__((weak)) void nsif_cpu##i##_pre_hw_init_hooks(void) { } \ -__attribute__((weak)) void nsif_cpu##i##_boot(void) \ - { \ - nsi_print_trace("Attempted boot of CPU %i without image. "\ - "CPU %i shut down permanently\n", i, i); \ - } \ -__attribute__((weak)) int nsif_cpu##i##_cleanup(void) { return 0; } \ -__attribute__((weak)) void nsif_cpu##i##_irq_raised(void) { } \ -__attribute__((weak)) void nsif_cpu##i##_irq_raised_from_sw(void) { } +static void nsi_boot_warning(const char *func) +{ + nsi_print_trace("%s: Attempted boot of CPU without image. " + "CPU shut down permanently\n", func); +} -NSI_CPU_STUBBED_IMAGE(0) -NSI_CPU_STUBBED_IMAGE(1) -NSI_CPU_STUBBED_IMAGE(2) -NSI_CPU_STUBBED_IMAGE(3) -NSI_CPU_STUBBED_IMAGE(4) -NSI_CPU_STUBBED_IMAGE(5) -NSI_CPU_STUBBED_IMAGE(6) -NSI_CPU_STUBBED_IMAGE(7) -NSI_CPU_STUBBED_IMAGE(8) -NSI_CPU_STUBBED_IMAGE(9) -NSI_CPU_STUBBED_IMAGE(10) -NSI_CPU_STUBBED_IMAGE(11) -NSI_CPU_STUBBED_IMAGE(12) -NSI_CPU_STUBBED_IMAGE(13) -NSI_CPU_STUBBED_IMAGE(14) -NSI_CPU_STUBBED_IMAGE(15) +/* + * These will define N functions like + * int nsif_cpu_cleanup(void) { return 0; } + */ +F_TRAMP_BODY_LIST(__attribute__((weak)) void nsif_cpu, _pre_cmdline_hooks(void) { }) +F_TRAMP_BODY_LIST(__attribute__((weak)) void nsif_cpu, _pre_hw_init_hooks(void) { }) +F_TRAMP_BODY_LIST(__attribute__((weak)) void nsif_cpu, + _boot(void) { nsi_boot_warning(__func__); }) +F_TRAMP_BODY_LIST(__attribute__((weak)) int nsif_cpu, _cleanup(void) { return 0; }) +F_TRAMP_BODY_LIST(__attribute__((weak)) void nsif_cpu, _irq_raised(void) { }) +F_TRAMP_BODY_LIST(__attribute__((weak)) void nsif_cpu, _irq_raised_from_sw(void) { }) +F_TRAMP_BODY_LIST(__attribute__((weak)) int nsif_cpu, _test_hook(void *p) { return 0; }) From ff14d64086f18ba09578599afc15ddebe9462c90 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 15 Sep 2023 16:56:41 +0200 Subject: [PATCH 0567/4498] samples zbus benchmark: Fix twister filter For the posix arch, this sample only works for native_posix, all others will get a build error: https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/subsys/zbus/benchmark/src/benchmark.c#L20 So let's filter them. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/zbus/benchmark/sample.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/subsys/zbus/benchmark/sample.yaml b/samples/subsys/zbus/benchmark/sample.yaml index cf05106947b..b090cc9d467 100644 --- a/samples/subsys/zbus/benchmark/sample.yaml +++ b/samples/subsys/zbus/benchmark/sample.yaml @@ -4,7 +4,7 @@ tests: sample.zbus.benchmark_async: tags: zbus min_ram: 16 - filter: CONFIG_SYS_CLOCK_EXISTS + filter: CONFIG_SYS_CLOCK_EXISTS and not (CONFIG_ARCH_POSIX and not CONFIG_BOARD_NATIVE_POSIX) harness: console harness_config: type: multi_line @@ -21,13 +21,12 @@ tests: - CONFIG_BM_ASYNC=y - arch:nios2:CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 - CONFIG_IDLE_STACK_SIZE=1024 - platform_exclude: nrf52_bsim integration_platforms: - qemu_x86 sample.zbus.benchmark_sync: tags: zbus min_ram: 16 - filter: CONFIG_SYS_CLOCK_EXISTS + filter: CONFIG_SYS_CLOCK_EXISTS and not (CONFIG_ARCH_POSIX and not CONFIG_BOARD_NATIVE_POSIX) harness: console harness_config: type: multi_line @@ -44,6 +43,5 @@ tests: - CONFIG_BM_ASYNC=n - arch:nios2:CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 - CONFIG_IDLE_STACK_SIZE=1024 - platform_exclude: nrf52_bsim integration_platforms: - qemu_x86 From ac0f731b2e49b3bbefd5d6ba8eff041ce13338ce Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Fri, 15 Sep 2023 21:13:31 +0300 Subject: [PATCH 0568/4498] xen: add Kconfig option for Zephyr on Dom0less setups Dom0less is Xen mode without privileged domain. All guests are created according to hypervisor device tree configuration on boot. Thus, there is no Dom0 with console daemon, that usually manages console output from domains. Zephyr OS contains 2 serial drivers related to Xen hypervisor: regular with console shared page and consoleio-based. The first one is for setups with console daemon and usually was used for Zephyr DomU guests. The second one previously was used only for Zephyr Dom0 and had corresponding Kconfig options. But consoleio is also used as interface for DomU output on Dom0less setups and should be configurable without XEN_DOM0 option. Add corresponding XEN_DOM0LESS config to Xen Kconfig files and proper dependencies in serial drivers. Signed-off-by: Dmytro Firsov Co-authored-by: Oleksandr Tyshchenko --- arch/arm64/core/xen/Kconfig | 7 +++++++ drivers/serial/Kconfig.xen | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/arm64/core/xen/Kconfig b/arch/arm64/core/xen/Kconfig index ea9489d4422..a4bb0be77e9 100644 --- a/arch/arm64/core/xen/Kconfig +++ b/arch/arm64/core/xen/Kconfig @@ -18,3 +18,10 @@ config XEN_DOM0 depends on XEN help Built binary will be used as Xen privileged domain (Domain 0). + +config XEN_DOM0LESS + bool "Zephyr for Xen Dom0less setup" + depends on XEN && !XEN_DOM0 + help + Configures Zephyr as DomU, that can be started on Dom0less + setup. diff --git a/drivers/serial/Kconfig.xen b/drivers/serial/Kconfig.xen index 89fe3f54194..471e5eb7269 100644 --- a/drivers/serial/Kconfig.xen +++ b/drivers/serial/Kconfig.xen @@ -10,19 +10,22 @@ config UART_XEN_HVC depends on DT_HAS_XEN_HVC_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - depends on XEN && !XEN_DOM0 + depends on XEN && !XEN_DOM0 && !XEN_DOM0LESS help Enable Xen ring buffer based hypervisor console driver. Used for Zephyr as unprivileged domain. config UART_XEN_HVC_CONSOLEIO - bool "Xen hypervisor Dom0 console UART driver" + bool "Xen hypervisor consoleio UART driver" select SERIAL_HAS_DRIVER - depends on XEN_DOM0 + depends on XEN_DOM0 || XEN_DOM0LESS default y help Enable Xen hypervisor console driver. Used for Zephyr as - privileged domain (Dom0). + privileged domain (Dom0) or for Zephyr DomU in Dom0less + configuration. Dom0less configuration does not have + privileged domain. Thus, there is no console daemon and Xen + manages all domain outputs through the consoleio interface. config XEN_HVC_INIT_PRIORITY int "Xen hypervisor console init priority" From efea1ad3983220f99ffe8356af190a99556b2774 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 15 Sep 2023 23:50:19 -0700 Subject: [PATCH 0569/4498] samples: userspace: Remove unnecessary build options This sample is selecting many things that are not needed, just remove them. Signed-off-by: Flavio Ceolin --- samples/userspace/hello_world_user/prj.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/userspace/hello_world_user/prj.conf b/samples/userspace/hello_world_user/prj.conf index 746de64bb6a..7de714c1418 100644 --- a/samples/userspace/hello_world_user/prj.conf +++ b/samples/userspace/hello_world_user/prj.conf @@ -1,6 +1,2 @@ CONFIG_USERSPACE=y -CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_ASSERT=y -CONFIG_LOG=y -CONFIG_LOG_MODE_MINIMAL=y -CONFIG_MAIN_STACK_SIZE=2560 From 0e8e7a01897837794553555e94abf93d74cccebb Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Sat, 16 Sep 2023 15:20:11 -0400 Subject: [PATCH 0570/4498] drivers: rtc: stm32: fix cell index of source clock The DT_INST_CLOCKS_CELL macro takes as the first argument the device instance and not the cell index. This change correctly gets the second index of the first device as intended. Signed-off-by: Brett Witherspoon --- drivers/rtc/rtc_ll_stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 66c277aa43f..cb7c85ad3a1 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -168,11 +168,11 @@ static int rtc_stm32_init(const struct device *dev) static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); static const struct rtc_stm32_config rtc_config = { -#if DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSI +#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI /* prescaler values for LSI @ 32 KHz */ .async_prescaler = 0x7F, .sync_prescaler = 0x00F9, -#else /* DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSE */ +#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ /* prescaler values for LSE @ 32768 Hz */ .async_prescaler = 0x7F, .sync_prescaler = 0x00FF, From 462a7262be4bb5d325c428a2ae4453b00cc8a87c Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Sat, 16 Sep 2023 15:44:43 -0400 Subject: [PATCH 0571/4498] drivers: rtc: stm32: add build assertion for source clock Assert the source clock is defined in the device tree to ensure the reference is valid. Signed-off-by: Brett Witherspoon --- drivers/rtc/rtc_ll_stm32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index cb7c85ad3a1..722a1552558 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -167,6 +167,8 @@ static int rtc_stm32_init(const struct device *dev) static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); +BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree"); + static const struct rtc_stm32_config rtc_config = { #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI /* prescaler values for LSI @ 32 KHz */ From e363c5e26d2b8e86d75c2e13bf633ca6ec26b731 Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Sat, 16 Sep 2023 16:01:07 -0400 Subject: [PATCH 0572/4498] drivers: rtc: stm32: use single instance driver This driver only supports a single instance. This commit cleans up the device definition and indicates this. Signed-off-by: Brett Witherspoon --- drivers/rtc/rtc_ll_stm32.c | 43 ++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 722a1552558..93fd146df5c 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -165,23 +165,6 @@ static int rtc_stm32_init(const struct device *dev) return err; } -static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); - -BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree"); - -static const struct rtc_stm32_config rtc_config = { -#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI - /* prescaler values for LSI @ 32 KHz */ - .async_prescaler = 0x7F, - .sync_prescaler = 0x00F9, -#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ - /* prescaler values for LSE @ 32768 Hz */ - .async_prescaler = 0x7F, - .sync_prescaler = 0x00FF, -#endif - .pclken = rtc_clk, -}; - static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr) { struct rtc_stm32_data *data = dev->data; @@ -385,10 +368,24 @@ struct rtc_driver_api rtc_stm32_driver_api = { #endif /* CONFIG_RTC_CALIBRATION */ }; -#define RTC_STM32_DEV_CFG(n) \ - static struct rtc_stm32_data rtc_data_##n = {}; \ - \ - DEVICE_DT_INST_DEFINE(n, &rtc_stm32_init, NULL, &rtc_data_##n, &rtc_config, POST_KERNEL, \ - CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api); +static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); + +BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree"); + +static const struct rtc_stm32_config rtc_config = { +#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI + /* prescaler values for LSI @ 32 KHz */ + .async_prescaler = 0x7F, + .sync_prescaler = 0x00F9, +#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ + /* prescaler values for LSE @ 32768 Hz */ + .async_prescaler = 0x7F, + .sync_prescaler = 0x00FF, +#endif + .pclken = rtc_clk, +}; + +static struct rtc_stm32_data rtc_data; -DT_INST_FOREACH_STATUS_OKAY(RTC_STM32_DEV_CFG); +DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, POST_KERNEL, + CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api); From dd090f06b7ed45bdc88335082a10bbe0db2ce439 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 16 Sep 2023 15:41:39 +1000 Subject: [PATCH 0573/4498] net: wifi_mgmt: change type of `wifi_scan_params->chan` All WiFi channel numbers fit within a 8 bit number, as the maximum allocated channel is 233. This halves the memory requirement. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_mgmt.h | 2 +- include/zephyr/net/wifi_utils.h | 2 +- subsys/net/l2/wifi/wifi_utils.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ab3225e1408..ee94ca58559 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -252,7 +252,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - uint16_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; + uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index 86b39ff4660..b005d075847 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -100,7 +100,7 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint16_t chan[][WIFI_CHANNEL_MAX]); + uint8_t chan[][WIFI_CHANNEL_MAX]); /** * @} diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index ea0e42def47..a77e225bfbf 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -103,13 +103,13 @@ static bool wifi_utils_validate_chan(uint8_t band, } -static int wifi_utils_get_all_chans_in_range(uint16_t chan_start, - uint16_t chan_end, - uint16_t chan[][WIFI_CHANNEL_MAX], +static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, + uint8_t chan_end, + uint8_t chan[][WIFI_CHANNEL_MAX], uint8_t band_idx, uint8_t *chan_idx) { - uint16_t i; + uint8_t i; bool start = false; bool end = false; uint8_t idx; @@ -310,7 +310,7 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint16_t chan[][WIFI_CHANNEL_MAX]) + uint8_t chan[][WIFI_CHANNEL_MAX]) { char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; @@ -318,8 +318,8 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, uint16_t band_str_start_idx = 0; uint16_t chan_str_start_idx = 0; uint8_t chan_idx = 0; - uint16_t chan_start = 0; - uint16_t chan_val = 0; + uint8_t chan_start = 0; + uint8_t chan_val = 0; uint16_t i = 0; bool valid_band = false; bool valid_chan = false; From b990a74f8b41b91634061ee366c1005541f319eb Mon Sep 17 00:00:00 2001 From: Ludvig Samuelsen Jordet Date: Wed, 9 Aug 2023 09:30:29 +0200 Subject: [PATCH 0574/4498] Bluetooth: Mesh: Add support for Upload OOB Start This adds support for the Upload OOB Start message to the DFD server, by providing callbacks that the application can use to hook any OOB scheme into the model behavior. There are also extensive changes to the dfu_slot module, to accomodate the new needs that appeared with the support for OOB transfer (mainly, fwid, size and metadata are no longer available when the slot is allocated, they appear later in the handling). Signed-off-by: Ludvig Samuelsen Jordet --- doc/connectivity/bluetooth/api/mesh/shell.rst | 5 +- include/zephyr/bluetooth/mesh/dfd_srv.h | 163 +++++++++- include/zephyr/bluetooth/mesh/dfu.h | 13 +- subsys/bluetooth/mesh/Kconfig | 8 + subsys/bluetooth/mesh/dfd_srv.c | 270 +++++++++++++--- subsys/bluetooth/mesh/dfu_slot.c | 294 ++++++++++-------- subsys/bluetooth/mesh/dfu_slot.h | 87 ++++-- subsys/bluetooth/mesh/shell/dfd.c | 9 +- subsys/bluetooth/mesh/shell/dfu.c | 53 ++-- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 3 +- tests/bsim/bluetooth/mesh/src/test_dfu.c | 185 +++++++---- .../tests_scripts/dfu/dfu_slot_idempotency.sh | 14 + .../tests_scripts/dfu/dfu_slot_reservation.sh | 14 + 13 files changed, 792 insertions(+), 326 deletions(-) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index f9acf24d277..e6609f40e5c 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1034,15 +1034,14 @@ Firmware Update Client model The Firmware Update Client model can be added to the mesh shell by enabling configuration options :kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` and :kconfig:option:`CONFIG_BT_MESH_DFU_CLI`. The Firmware Update Client demonstrates the firmware update Distributor role by transferring a dummy firmware update to a set of Target nodes. -``mesh models dfu slot add [ [ []]]`` +``mesh models dfu slot add []`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add a virtual DFU image slot that can be transferred as a DFU image. The image slot will be assigned an image slot index, which is printed as a response, and can be used to reference the slot in other commands. To update the image slot, remove it using the ``mesh models dfu slot del`` shell command and then add it again. * ``Size``: DFU image slot size in bytes. - * ``FwID``: Optional firmware ID, formatted as a hexstring. + * ``FwID``: Firmware ID, formatted as a hexstring. * ``Metadata``: Optional firmware metadata, formatted as a hexstring. - * ``URI``: Optional URI for the firmware. ``mesh models dfu slot del `` diff --git a/include/zephyr/bluetooth/mesh/dfd_srv.h b/include/zephyr/bluetooth/mesh/dfd_srv.h index 0e281b29186..da339c57ec6 100644 --- a/include/zephyr/bluetooth/mesh/dfd_srv.h +++ b/include/zephyr/bluetooth/mesh/dfd_srv.h @@ -29,11 +29,47 @@ extern "C" { #define CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 0 #endif +#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE +#define CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 0 +#endif + +#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE +#define CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 0 +#endif + struct bt_mesh_dfd_srv; +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD +/** + * + * @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB + * upload support. + * + * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. + * @param[in] _oob_schemes Array of OOB schemes supported by the server, + * each scheme being a code point from the + * Bluetooth SIG Assigned Numbers document. + * @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes. + */ +#define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \ + { \ + .cb = _cb, \ + .dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \ + .upload = { \ + .blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \ + }, \ + .oob_schemes = { \ + .schemes = _oob_schemes, \ + .count = _oob_schemes_count, \ + }, \ + } +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ + /** * * @brief Initialization parameters for the @ref bt_mesh_dfd_srv. + * + * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. */ #define BT_MESH_DFD_SRV_INIT(_cb) \ { \ @@ -75,6 +111,64 @@ struct bt_mesh_dfd_srv_cb { const struct bt_mesh_dfu_slot *slot, const struct bt_mesh_blob_io **io); +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + /** @brief Firmware upload OOB start callback. + * + * Called at the start of an OOB firmware upload. The application must + * start a firmware check using an OOB mechanism, and then call + * @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return + * value of this function, the application must then start storing the + * firmware image using an OOB mechanism, and call + * @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory + * to support OOB uploads. + * + * @param srv Firmware Distribution Server model instance. + * @param slot Slot to be used for the upload. + * @param uri Pointer to buffer containing the URI used to + * check for new firmware. + * @param uri_len Length of the URI buffer. + * @param fwid Pointer to buffer containing the current + * firmware ID to be used when checking for + * availability of new firmware. + * @param fwid_len Length of the current firmware ID. Must be set + * to the length of the new firmware ID if it is + * available, or to 0 if new firmware is not + * available. + * + * @return BT_MESH_DFD_SUCCESS on success, or error code otherwise. + */ + int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, + const char *uri, uint8_t uri_len, + const uint8_t *fwid, uint16_t fwid_len); + + /** @brief Cancel store OOB callback + * + * Called when an OOB store is cancelled. The application must stop + * any ongoing OOB image transfer. This callback is mandatory to + * support OOB uploads. + * + * @param srv Firmware Distribution Server model instance. + * @param slot DFU image slot to cancel + */ + void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot); + + /** @brief Get the progress of an ongoing OOB store + * + * Called by the Firmware Distribution Server model when it needs to + * get the current progress of an ongoing OOB store from the + * application. This callback is mandatory to support OOB uploads. + * + * @param srv Firmware Distribution Server model instance. + * @param slot DFU image slot to get progress for. + * + * @return The current progress of the ongoing OOB store, in percent. + */ + uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot); +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ + /** @brief Slot delete callback. * * Called when the Firmware Distribution Server is about to delete a DFU image slot. @@ -129,12 +223,79 @@ struct bt_mesh_dfd_srv { struct { enum bt_mesh_dfd_upload_phase phase; - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; const struct flash_area *area; struct bt_mesh_blob_srv blob; +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + bool is_oob; + struct { + uint8_t uri_len; + uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; + uint16_t current_fwid_len; + uint8_t current_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; + struct bt_mesh_msg_ctx ctx; + } oob; +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ } upload; + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + struct { + const uint8_t *schemes; + const uint8_t count; + } oob_schemes; +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ }; +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD +/** @brief Call when an OOB check has completed or failed + * + * This should be called by the application after an OOB check started by the @c start_oob_upload + * callback has completed or failed. The @p status param should be set to one of the following + * values: + * + * * @c BT_MESH_DFD_SUCCESS if the check was succesfull and a new firmware ID was found. + * * @c BT_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly. + * * @c BT_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node. + * * @c BT_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached. + * * @c BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new + * firmware is available. + * + * If this function returns 0, the application should then download the firmware to the + * slot. If an error code is returned, the application should abort the OOB upload. + * + * @param srv Firmware Distribution Server model instance. + * @param slot The slot used in the OOB upload. + * @param status The result of the firmware check. + * @param fwid If the check was successful and new firmware found, this should point to a + * buffer containing the new firmware ID to store. + * @param fwid_len The length of the firmware ID pointed to by @p fwid. + * + * @return 0 on success, (negative) error code otherwise. + */ +int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, int status, + uint8_t *fwid, size_t fwid_len); + +/** @brief Call when an OOB store has completed or failed + * + * This should be called by the application after an OOB store started after a succesfull call to + * @c bt_mesh_dfd_srv_oob_check_complete has completed successfully or failed. + * + * @param srv Firmware Distribution Server model instance. + * @param slot The slot used when storing the firmware image. + * @param success @c true if the OOB store completed successfully, @c false otherwise. + * @param size The size of the stored firmware image, in bytes. + * @param metadata Pointer to the metadata received OOB, or @c NULL if no metadata was + * received. + * @param metadata_len Size of the metadata pointed to by @p metadata. + * + * @return 0 on success, (negative) error code otherwise. + */ +int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, bool success, + size_t size, const uint8_t *metadata, size_t metadata_len); +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ + /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[]; extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb; diff --git a/include/zephyr/bluetooth/mesh/dfu.h b/include/zephyr/bluetooth/mesh/dfu.h index 91f36cdbaeb..4745355f039 100644 --- a/include/zephyr/bluetooth/mesh/dfu.h +++ b/include/zephyr/bluetooth/mesh/dfu.h @@ -34,6 +34,10 @@ extern "C" { #define CONFIG_BT_MESH_DFU_URI_MAXLEN 0 #endif +#ifndef CONFIG_BT_MESH_DFU_SLOT_CNT +#define CONFIG_BT_MESH_DFU_SLOT_CNT 0 +#endif + /** DFU transfer phase. */ enum bt_mesh_dfu_phase { /** Ready to start a Receive Firmware procedure. */ @@ -140,10 +144,7 @@ struct bt_mesh_dfu_img { /** Length of the firmware ID. */ size_t fwid_len; - /** Update URI, or NULL. - * - * Must use one of the http: or https: schemes. - */ + /** Update URI, or NULL. */ const char *uri; }; @@ -155,14 +156,10 @@ struct bt_mesh_dfu_slot { size_t fwid_len; /** Length of the metadata. */ size_t metadata_len; - /** Length of the image URI. */ - size_t uri_len; /** Firmware ID. */ uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; /** Metadata. */ uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; - /** Image URI. */ - char uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; }; /** @} */ diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 99012e9646a..6bc4c8b5673 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1235,6 +1235,14 @@ config BT_MESH_DFD_SRV_TARGETS_MAX This value defines the maximum number of Target nodes the Firmware Distribution Server can target simultaneously. +config BT_MESH_DFD_SRV_OOB_UPLOAD + bool "Support for DFU image OOB upload" + help + This enables support for OOB upload of firmware images for + distribution. This makes several callbacks and use of the init + macro BT_MESH_DFD_SRV_INIT_OOB mandatory. See the API documentation + for bt_mesh_dfd_srv_cb for details about the mandatory callbacks. + endif config BT_MESH_RPR_SRV diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 2898ca39a39..54de343c94a 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -224,7 +224,20 @@ static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg size = MIN(size, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE); net_buf_simple_add_le32(&rsp, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE - size); - net_buf_simple_add_u8(&rsp, 0U); /* OOB retrieval not supported */ + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + struct bt_mesh_dfd_srv *srv = mod->user_data; + + if (srv->oob_schemes.count > 0) { + net_buf_simple_add_u8(&rsp, 1); + net_buf_simple_add_mem(&rsp, srv->oob_schemes.schemes, + srv->oob_schemes.count); + } else +#else + { + net_buf_simple_add_u8(&rsp, 0); + } +#endif bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL); @@ -346,10 +359,19 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, return; } - net_buf_simple_add_u8(&rsp, - bt_mesh_blob_srv_progress(&srv->upload.blob)); - net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, - srv->upload.slot->fwid_len); +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + if (srv->upload.is_oob) { + net_buf_simple_add_u8(&rsp, + srv->cb->oob_progress_get(srv, srv->upload.slot) | BIT(7)); + net_buf_simple_add_mem(&rsp, srv->upload.oob.current_fwid, + srv->upload.oob.current_fwid_len); + } else +#endif + { + net_buf_simple_add_u8(&rsp, bt_mesh_blob_srv_progress(&srv->upload.blob)); + net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, + srv->upload.slot->fwid_len); + } bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } @@ -364,16 +386,42 @@ static int handle_upload_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } +static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_msg_ctx *ctx, + const uint8_t *fwid, size_t fwid_len) +{ + int err = bt_mesh_dfu_slot_fwid_set(srv->upload.slot, fwid, fwid_len); + + switch (err) { + case -EFBIG: /* Fwid too long */ + case -EALREADY: /* Other server is in progress with this fwid */ + bt_mesh_dfu_slot_release(srv->upload.slot); + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); + break; + case -EEXIST: /* Img with this fwid already is in list */ + srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; + bt_mesh_dfu_slot_release(srv->upload.slot); + upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); + break; + case 0: + srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; + break; + case -EINVAL: /* Slot in wrong state. */ + default: + break; + } + + return err; +} + static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; - const struct bt_mesh_dfu_slot *old_slot = srv->upload.slot; size_t meta_len, fwid_len, size; const uint8_t *meta, *fwid; uint16_t timeout_base; uint64_t blob_id; - int err, idx; + int err; uint8_t ttl; ttl = net_buf_simple_pull_u8(buf); @@ -392,9 +440,7 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx LOG_DBG("Upload Start: size: %d, fwid: %s, metadata: %s", size, bt_hex(fwid, fwid_len), bt_hex(meta, meta_len)); - if (size > CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE || - fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN || - meta_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN) { + if (size > CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE) { upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES); return 0; @@ -413,7 +459,11 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx !memcmp(srv->upload.slot->metadata, meta, meta_len) && srv->upload.blob.state.xfer.id == blob_id && srv->upload.blob.state.ttl == ttl && - srv->upload.blob.state.timeout_base == timeout_base) { + srv->upload.blob.state.timeout_base == timeout_base +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + && !srv->upload.is_oob +#endif + ) { LOG_DBG("Duplicate upload start"); upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); return 0; @@ -424,23 +474,16 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } - idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &srv->upload.slot); - if (idx >= 0 && bt_mesh_dfu_slot_is_valid(srv->upload.slot)) { - LOG_DBG("Already received image"); - srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; - upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); - return 0; - } + /* This will be a no-op if the slot state isn't RESERVED, which is + * what we want. + */ + bt_mesh_dfu_slot_release(srv->upload.slot); - if (old_slot && !bt_mesh_dfu_slot_is_valid(old_slot)) { - LOG_DBG("Deleting old invalid slot"); - slot_del(srv, old_slot); - } +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + srv->upload.is_oob = false; +#endif + srv->upload.slot = bt_mesh_dfu_slot_reserve(); - /* TODO Store transfer state before slot is added. */ - - srv->upload.slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, meta, - meta_len, NULL, 0); if (!srv->upload.slot) { LOG_WRN("No space for slot"); upload_status_rsp(srv, ctx, @@ -448,11 +491,27 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } + err = set_upload_fwid(srv, ctx, fwid, fwid_len); + if (err) { + return err; + } + + err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, meta, meta_len); + switch (err) { + case -EFBIG: + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); + break; + case 0: + break; + default: + return err; + } + srv->io = NULL; err = srv->cb->recv(srv, srv->upload.slot, &srv->io); if (err || !srv->io) { LOG_ERR("App rejected upload. err: %d io: %p", err, srv->io); - slot_del(srv, srv->upload.slot); + bt_mesh_dfu_slot_release(srv->upload.slot); upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); return 0; } @@ -461,7 +520,7 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx timeout_base); if (err) { LOG_ERR("BLOB Server rejected upload (err: %d)", err); - slot_del(srv, srv->upload.slot); + bt_mesh_dfu_slot_release(srv->upload.slot); upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); return 0; } @@ -478,10 +537,71 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; + uint8_t uri_len; + uint8_t *uri; + uint16_t fwid_len; + uint8_t *fwid; - LOG_DBG(""); + uri_len = net_buf_simple_pull_u8(buf); + + if (uri_len > buf->len) { + return -EINVAL; + } + + uri = net_buf_simple_pull_mem(buf, uri_len); + fwid_len = buf->len; + fwid = net_buf_simple_pull_mem(buf, fwid_len); + if (upload_is_busy(srv)) { +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + if (srv->upload.is_oob && + uri_len == srv->upload.oob.uri_len && + fwid_len == srv->upload.oob.current_fwid_len && + !memcmp(uri, srv->upload.oob.uri, uri_len) && + !memcmp(fwid, srv->upload.oob.current_fwid, fwid_len)) { + /* Same image, return SUCCESS for idempotency */ + upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); + return 0; + } +#endif + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD); + return 0; + } + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + if (uri_len > CONFIG_BT_MESH_DFU_URI_MAXLEN || + fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN) { + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); + return 0; + } + + struct bt_mesh_dfu_slot *slot = bt_mesh_dfu_slot_reserve(); + + if (slot == NULL) { + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES); + return 0; + } + + srv->upload.is_oob = true; + srv->upload.slot = slot; + memcpy(srv->upload.oob.uri, uri, uri_len); + srv->upload.oob.uri_len = uri_len; + memcpy(srv->upload.oob.current_fwid, fwid, fwid_len); + srv->upload.oob.current_fwid_len = fwid_len; + memcpy(&srv->upload.oob.ctx, ctx, sizeof(struct bt_mesh_msg_ctx)); + + int status = srv->cb->start_oob_upload(srv, srv->upload.slot, srv->upload.oob.uri, + srv->upload.oob.uri_len, + srv->upload.oob.current_fwid, + srv->upload.oob.current_fwid_len); + + if (status != BT_MESH_DFD_SUCCESS) { + upload_status_rsp(srv, ctx, status); + bt_mesh_dfu_slot_release(srv->upload.slot); + } +#else upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_URI_NOT_SUPPORTED); +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ return 0; } @@ -492,7 +612,14 @@ static int handle_upload_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ct struct bt_mesh_dfd_srv *srv = mod->user_data; srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; - (void)bt_mesh_blob_srv_cancel(&srv->upload.blob); +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + if (srv->upload.is_oob) { + srv->cb->cancel_oob_upload(srv, srv->upload.slot); + } else +#endif + { + (void)bt_mesh_blob_srv_cancel(&srv->upload.blob); + } upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); return 0; @@ -508,7 +635,7 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv, bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_FW_STATUS); net_buf_simple_add_u8(&rsp, status); - net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_foreach(NULL, NULL)); + net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_count()); net_buf_simple_add_le16(&rsp, idx); if (fwid) { @@ -522,7 +649,7 @@ static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; const uint8_t *fwid; size_t fwid_len; int idx; @@ -531,7 +658,7 @@ static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, fwid = net_buf_simple_pull_mem(buf, fwid_len); idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); - if (idx >= 0 && bt_mesh_dfu_slot_is_valid(slot)) { + if (idx >= 0) { fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, fwid, fwid_len); } else { @@ -552,7 +679,7 @@ static int handle_fw_get_by_index(struct bt_mesh_model *mod, struct bt_mesh_msg_ idx = net_buf_simple_pull_le16(buf); slot = bt_mesh_dfu_slot_at(idx); - if (slot && bt_mesh_dfu_slot_is_valid(slot)) { + if (slot) { fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, slot->fwid, slot->fwid_len); } else { @@ -729,8 +856,7 @@ static void upload_end(struct bt_mesh_blob_srv *b, uint64_t id, bool success) LOG_DBG("%u", success); - if (success) { - bt_mesh_dfu_slot_valid_set(srv->upload.slot, true); + if (success && (bt_mesh_dfu_slot_commit(srv->upload.slot) == 0)) { srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; return; } @@ -850,7 +976,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv, xfer.mode = params->xfer_mode; xfer.slot = bt_mesh_dfu_slot_at(params->slot_idx); - if (!xfer.slot || !bt_mesh_dfu_slot_is_valid(xfer.slot)) { + if (!xfer.slot) { return BT_MESH_DFD_ERR_FW_NOT_FOUND; } @@ -1013,7 +1139,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_apply(struct bt_mesh_dfd_srv *srv) enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, size_t *fwid_len, const uint8_t **fwid) { - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; int idx, err; if (srv->phase != BT_MESH_DFD_PHASE_IDLE) { @@ -1023,7 +1149,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, s } idx = bt_mesh_dfu_slot_get(*fwid, *fwid_len, &slot); - if (idx < 0 || !bt_mesh_dfu_slot_is_valid(slot)) { + if (idx < 0) { return BT_MESH_DFD_SUCCESS; } @@ -1049,3 +1175,69 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete_all(struct bt_mesh_dfd_srv *sr return BT_MESH_DFD_SUCCESS; } + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD +int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, int status, + uint8_t *fwid, size_t fwid_len) +{ + int err; + + if (slot != srv->upload.slot || !srv->upload.is_oob || + srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) { + /* This should not happen, unless the application calls the function with a + * "wrong" pointer or at a wrong time. + */ + return -EINVAL; + } + + if (status != BT_MESH_DFD_SUCCESS) { + bt_mesh_dfu_slot_release(srv->upload.slot); + upload_status_rsp(srv, &srv->upload.oob.ctx, status); + return -ECANCELED; + } + + err = set_upload_fwid(srv, &srv->upload.oob.ctx, fwid, fwid_len); + + if (err) { + return err; + } + + upload_status_rsp(srv, &srv->upload.oob.ctx, BT_MESH_DFD_SUCCESS); + return 0; +} + +int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, bool success, + size_t size, const uint8_t *metadata, size_t metadata_len) +{ + int err = 0; + + if (srv->upload.phase != BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE || + srv->upload.slot != slot || !srv->upload.is_oob) { + return -EINVAL; + } + + if (!success) { + goto error; + } + + err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, metadata, metadata_len); + if (err) { + goto error; + } + + err = bt_mesh_dfu_slot_commit(srv->upload.slot); + if (err) { + goto error; + } + + srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; + return 0; + +error: + srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR; + bt_mesh_dfu_slot_release(srv->upload.slot); + return err; +} +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ diff --git a/subsys/bluetooth/mesh/dfu_slot.c b/subsys/bluetooth/mesh/dfu_slot.c index 16628793457..097d5abcc82 100644 --- a/subsys/bluetooth/mesh/dfu_slot.c +++ b/subsys/bluetooth/mesh/dfu_slot.c @@ -20,23 +20,22 @@ LOG_MODULE_REGISTER(bt_mesh_dfu_slot); #define DFU_SLOT_SETTINGS_PATH "bt/mesh-dfu/slot" -#define HEADER_SIZE offsetof(struct bt_mesh_dfu_slot, fwid) +#define HEADER_SIZE offsetof(struct slot, slot.fwid) #define PROP_HEADER "h" #define PROP_FWID "id" #define PROP_METADATA "m" -#define PROP_URI "u" -#define VALID_SLOTS_TAG "v" -#define SLOT_IN_ARRAY(_slot) PART_OF_ARRAY(slots, CONTAINER_OF(_slot, struct slot, slot)) - -static ATOMIC_DEFINE(valid_slots, CONFIG_BT_MESH_DFU_SLOT_CNT); static sys_slist_t list; + static struct slot { - sys_snode_t n; + uint32_t idx; struct bt_mesh_dfu_slot slot; + sys_snode_t n; } slots[CONFIG_BT_MESH_DFU_SLOT_CNT]; +static uint32_t slot_index; + static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN], const char *property) { @@ -46,32 +45,29 @@ static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN], return buf; } -static inline bool slot_in_use(const struct bt_mesh_dfu_slot *slot) +static bool slot_eq(const struct bt_mesh_dfu_slot *slot, + const uint8_t *fwid, size_t fwid_len) { - return slot->size > 0U; + return (slot->fwid_len == fwid_len) && + !memcmp(fwid, slot->fwid, fwid_len); } -static inline uint16_t slot_idx(const struct bt_mesh_dfu_slot *slot) +static bool is_slot_committed(struct slot *slot_to_check) { - return CONTAINER_OF(slot, struct slot, slot) - &slots[0]; -} + struct slot *s; -static inline void slot_invalidate(struct slot *slot_to_invalidate) -{ - slot_to_invalidate->slot.size = 0U; - atomic_clear_bit(valid_slots, slot_to_invalidate - &slots[0]); -} + SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { + if (s == slot_to_check) { + return true; + } + } -static bool slot_eq(const struct bt_mesh_dfu_slot *slot, - const uint8_t *fwid, size_t fwid_len) -{ - return (slot->fwid_len == fwid_len) && - !memcmp(fwid, slot->fwid, fwid_len); + return false; } static int slot_store(const struct slot *slot_to_store) { - uint16_t idx = slot_to_store - &slots[0]; + uint16_t idx = ARRAY_INDEX(slots, slot_to_store); char buf[SLOT_ENTRY_BUFLEN]; int err; @@ -90,55 +86,51 @@ static int slot_store(const struct slot *slot_to_store) err = settings_save_one(slot_entry_encode(idx, buf, PROP_METADATA), slot_to_store->slot.metadata, slot_to_store->slot.metadata_len); - if (err) { - return err; - } - return settings_save_one(slot_entry_encode(idx, buf, PROP_URI), - slot_to_store->slot.uri, slot_to_store->slot.uri_len); + return err; } static void slot_erase(struct slot *slot_to_erase) { - uint16_t idx = slot_to_erase - &slots[0]; + uint16_t idx = ARRAY_INDEX(slots, slot_to_erase); char buf[SLOT_ENTRY_BUFLEN]; settings_delete(slot_entry_encode(idx, buf, PROP_HEADER)); settings_delete(slot_entry_encode(idx, buf, PROP_FWID)); settings_delete(slot_entry_encode(idx, buf, PROP_METADATA)); - settings_delete(slot_entry_encode(idx, buf, PROP_URI)); } -static int valid_slots_store(void) +static void slot_index_defrag(void) { - return settings_save_one(DFU_SLOT_SETTINGS_PATH "/" VALID_SLOTS_TAG, - valid_slots, sizeof(valid_slots)); + slot_index = 0; + struct slot *s; + + SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { + s->idx = ++slot_index; + slot_store(s); + } } -const struct bt_mesh_dfu_slot * -bt_mesh_dfu_slot_add(size_t size, const uint8_t *fwid, - size_t fwid_len, const uint8_t *metadata, - size_t metadata_len, const char *uri, size_t uri_len) +int bt_mesh_dfu_slot_count(void) { - struct slot *slot = NULL; - int err, i; + int cnt = 0; + sys_snode_t *n; - if (size == 0 || fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN || - metadata_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN || - uri_len > CONFIG_BT_MESH_DFU_URI_MAXLEN) { - LOG_WRN("Param too large: (size: %d, fwid: %d, metadata: %d, uri: %d)", - size, fwid_len, metadata_len, uri_len); - return NULL; + SYS_SLIST_FOR_EACH_NODE(&list, n) { + cnt++; } - for (i = 0; i < ARRAY_SIZE(slots); ++i) { - if (!slot_in_use(&slots[i].slot)) { - slot = &slots[i]; - continue; - } + return cnt; +} - if (slot_eq(&slots[i].slot, fwid, fwid_len)) { - return &slots[i].slot; +struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void) +{ + struct slot *slot = NULL; + + for (int i = 0; i < ARRAY_SIZE(slots); ++i) { + if (slots[i].idx == 0) { + slot = &slots[i]; + break; } } @@ -147,110 +139,136 @@ bt_mesh_dfu_slot_add(size_t size, const uint8_t *fwid, return NULL; } - slot->slot.fwid_len = fwid_len; - slot->slot.metadata_len = metadata_len; - slot->slot.uri_len = uri_len; - memcpy(slot->slot.fwid, fwid, fwid_len); - memcpy(slot->slot.metadata, metadata, metadata_len); - memcpy(slot->slot.uri, uri, uri_len); - slot->slot.size = size; - - err = slot_store(slot); - if (err) { - slot_invalidate(slot); - LOG_WRN("Store failed (err: %d)", err); - return NULL; + if (slot_index == UINT32_MAX) { + slot_index_defrag(); } - sys_slist_append(&list, &slot->n); + slot->slot.fwid_len = 0; + slot->slot.metadata_len = 0; + slot->slot.size = 0; + slot->idx = ++slot_index; + + LOG_DBG("Reserved slot #%u", slot - &slots[0]); - LOG_DBG("Added slot #%u: %s", slot - &slots[0], - bt_hex(slot->slot.fwid, slot->slot.fwid_len)); return &slot->slot; } -int bt_mesh_dfu_slot_valid_set(const struct bt_mesh_dfu_slot *slot, bool valid) +int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size, + const uint8_t *metadata, size_t metadata_len) { - uint16_t idx; - bool prev; - int err; + struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); + + if (metadata_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN) { + return -EFBIG; + } - if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { - return -ENOENT; + if (slot->idx == 0 || is_slot_committed(slot)) { + return -EINVAL; } - idx = slot_idx(slot); + slot->slot.size = size; + slot->slot.metadata_len = metadata_len; + memcpy(slot->slot.metadata, metadata, metadata_len); + return 0; +} + +int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot, + const uint8_t *fwid, size_t fwid_len) +{ + struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); - LOG_DBG("%u: %u", idx, valid); + if (fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN) { + return -EFBIG; + } - if (valid) { - prev = atomic_test_and_set_bit(valid_slots, idx); - } else { - prev = atomic_test_and_clear_bit(valid_slots, idx); + if (slot->idx == 0 || is_slot_committed(slot)) { + return -EINVAL; } - if (valid == prev) { - return 0; + for (int i = 0; i < ARRAY_SIZE(slots); i++) { + if (slots[i].idx != 0 && + slot_eq(&slots[i].slot, fwid, fwid_len)) { + return is_slot_committed(&slots[i]) ? + -EEXIST : -EALREADY; + } + } + + slot->slot.fwid_len = fwid_len; + memcpy(slot->slot.fwid, fwid, fwid_len); + return 0; +} + +int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot) +{ + int err; + struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); + + if (slot->idx == 0 || + slot->slot.fwid_len == 0 || + slot->slot.size == 0 || + is_slot_committed(slot)) { + return -EINVAL; } - err = valid_slots_store(); + err = slot_store(slot); if (err) { - LOG_WRN("Storage failed. err: %d", err); - atomic_set_bit_to(valid_slots, idx, prev); + LOG_WRN("Store failed (err: %d)", err); + return err; } - return err; + sys_slist_append(&list, &slot->n); + + LOG_DBG("Stored slot #%u: %s", ARRAY_INDEX(slots, slot), + bt_hex(slot->slot.fwid, slot->slot.fwid_len)); + return 0; } -bool bt_mesh_dfu_slot_is_valid(const struct bt_mesh_dfu_slot *slot) +void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot) { - uint16_t idx; + struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); - if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { - return false; + if (is_slot_committed(slot)) { + return; } - idx = slot_idx(slot); - return atomic_test_bit(valid_slots, idx); + slot->idx = 0; } -int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *slot) +int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *dfu_slot) { - struct slot *s = CONTAINER_OF(slot, struct slot, slot); + struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); - if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { - return -ENOENT; + if (!sys_slist_find_and_remove(&list, &slot->n)) { + return -EINVAL; } - LOG_DBG("%u", s - &slots[0]); + int idx = ARRAY_INDEX(slots, slot); - slot_erase(s); - slot_invalidate(s); - sys_slist_find_and_remove(&list, &s->n); + LOG_DBG("%u", idx); + + slot_erase(slot); + slot->idx = 0; return 0; } -int bt_mesh_dfu_slot_del_all(void) +void bt_mesh_dfu_slot_del_all(void) { struct slot *s; - SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { slot_erase(s); - slot_invalidate(s); + s->idx = 0; } sys_slist_init(&list); - - return 0; } -const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx) +const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx) { struct slot *s; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (!idx--) { + if (!img_idx--) { return &s->slot; } } @@ -258,34 +276,33 @@ const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx) return NULL; } -int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, - const struct bt_mesh_dfu_slot **slot) +int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot) { struct slot *s; int idx = 0; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { if (slot_eq(&s->slot, fwid, fwid_len)) { - *slot = &s->slot; + if (slot) { + *slot = &s->slot; + } return idx; } - idx++; } return -ENOENT; } -int bt_mesh_dfu_slot_idx_get(const struct bt_mesh_dfu_slot *slot) +int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *dfu_slot) { struct slot *s; int idx = 0; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (&s->slot == slot) { + if (&s->slot == dfu_slot) { return idx; } - idx++; } @@ -295,11 +312,12 @@ int bt_mesh_dfu_slot_idx_get(const struct bt_mesh_dfu_slot *slot) size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data) { enum bt_mesh_dfu_iter iter; - struct slot *s; size_t cnt = 0; + struct slot *s; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { cnt++; + if (!cb) { continue; } @@ -320,15 +338,6 @@ static int slot_data_load(const char *key, size_t len_rd, size_t len; uint16_t idx; - if (!strncmp(key, VALID_SLOTS_TAG, 1)) { - if (read_cb(cb_arg, valid_slots, - MIN(sizeof(valid_slots), len_rd)) < 0) { - return -EINVAL; - } - - return 0; - } - idx = strtol(key, NULL, 16); if (idx >= ARRAY_SIZE(slots)) { @@ -339,16 +348,34 @@ static int slot_data_load(const char *key, size_t len_rd, if (!strncmp(prop, PROP_HEADER, len)) { if (read_cb(cb_arg, &slots[idx], HEADER_SIZE) > 0) { - sys_slist_append(&list, &slots[idx].n); - } + struct slot *s, *prev = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { + if (s->idx > slots[idx].idx) { + break; + } + + prev = s; + } + if (prev == NULL) { + sys_slist_prepend(&list, &slots[idx].n); + } else { + sys_slist_insert(&list, &prev->n, &slots[idx].n); + } + + if (slots[idx].idx >= slot_index) { + slot_index = slots[idx].idx + 1; + } + } return 0; } if (!strncmp(prop, PROP_FWID, len)) { if (read_cb(cb_arg, &slots[idx].slot.fwid, sizeof(slots[idx].slot.fwid)) < 0) { - slot_invalidate(&slots[idx]); + slots[idx].idx = 0; + sys_slist_find_and_remove(&list, &slots[idx].n); return 0; } @@ -359,7 +386,8 @@ static int slot_data_load(const char *key, size_t len_rd, if (!strncmp(prop, PROP_METADATA, len)) { if (read_cb(cb_arg, &slots[idx].slot.metadata, sizeof(slots[idx].slot.metadata)) < 0) { - slot_invalidate(&slots[idx]); + slots[idx].idx = 0; + sys_slist_find_and_remove(&list, &slots[idx].n); return 0; } @@ -367,16 +395,6 @@ static int slot_data_load(const char *key, size_t len_rd, return 0; } - if (!strncmp(prop, PROP_URI, len)) { - if (read_cb(cb_arg, &slots[idx].slot.uri, - sizeof(slots[idx].slot.uri)) < 0) { - slot_invalidate(&slots[idx]); - return 0; - } - - slots[idx].slot.uri_len = len_rd; - } - return 0; } diff --git a/subsys/bluetooth/mesh/dfu_slot.h b/subsys/bluetooth/mesh/dfu_slot.h index 1bc58f64de9..969c6d3d25b 100644 --- a/subsys/bluetooth/mesh/dfu_slot.h +++ b/subsys/bluetooth/mesh/dfu_slot.h @@ -16,50 +16,69 @@ typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_slot_cb_t)( const struct bt_mesh_dfu_slot *slot, void *user_data); -/** @brief Register a new DFU image slot for a distributable image. +/** @brief Get the number of slots committed to the firmware list. + * + * @return Number of committed slots. + */ +int bt_mesh_dfu_slot_count(void); + +/** @brief Reserve a new DFU image slot for a distributable image. * * A DFU image slot represents a single distributable DFU image with all its - * metadata. + * metadata. The slot data must be set using @ref bt_mesh_dfu_slot_info_set and + * @ref bt_mesh_dfu_slot_fwid_set, and the slot committed using + * @ref bt_mesh_dfu_slot_commit for the slot to be considered part of the slot + * list. * - * @note The slot is allocated as invalid. Call - * @ref bt_mesh_dfu_slot_valid_set to make it valid. + * @return A pointer to the reserved slot, or NULL if allocation failed. + */ +struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void); + +/** @brief Set the size and metadata for a reserved slot. * - * @param size Size of the image in bytes. - * @param fwid Firmware ID. - * @param fwid_len Length of the firmware ID, at most @c - * CONFIG_BT_MESH_DFU_FWID_MAXLEN. + * @param dfu_slot Pointer to the reserved slot for which to set the + * metadata. + * @param size The size of the image. * @param metadata Metadata or NULL. * @param metadata_len Length of the metadata, at most @c * CONFIG_BT_MESH_DFU_METADATA_MAXLEN. - * @param uri Image URI or NULL. - * @param uri_len Length of the image URI, at most @c - * CONFIG_BT_MESH_DFU_URI_MAXLEN. * - * @return A pointer to the allocated slot, or NULL if allocation failed. + * @return 0 on success, (negative) error code otherwise. */ -const struct bt_mesh_dfu_slot * -bt_mesh_dfu_slot_add(size_t size, const uint8_t *fwid, size_t fwid_len, - const uint8_t *metadata, size_t metadata_len, - const char *uri, size_t uri_len); +int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size, + const uint8_t *metadata, size_t metadata_len); -/** @brief Set whether the given slot is valid. +/** @brief Set the new fwid for the incoming image for a reserved slot. * - * @param slot Allocated DFU image slot. - * @param valid New valid state of the slot. + * @param dfu_slot Pointer to the reserved slot for which to set the fwid. + * @param fwid Fwid to set. + * @param fwid_len Length of the fwid, at most @c + * CONFIG_BT_MESH_DFU_FWID_MAXLEN. * - * @return 0 on success, or (negative) error code on failure. + * @return 0 on success, (negative) error code otherwise. */ -int bt_mesh_dfu_slot_valid_set(const struct bt_mesh_dfu_slot *slot, bool valid); +int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot, + const uint8_t *fwid, size_t fwid_len); -/** @brief Check whether a slot is valid. +/** @brief Commit the reserved slot to the list of slots, and store it + * persistently. + * + * If the commit fails for any reason, the slot will still be in the reserved + * state after this call. + * + * @param dfu_slot Pointer to the reserved slot. * - * @param slot Slot to check. + * @return 0 on success, (negative) error code otherwise. + */ +int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot); + +/** @brief Release a reserved slot so that it can be reserved again. * - * @return true if the slot is valid, false otherwise. + * @param dfu_slot Pointer to the reserved slot. */ -bool bt_mesh_dfu_slot_is_valid(const struct bt_mesh_dfu_slot *slot); +void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot); -/** @brief Delete an allocated DFU image slot. +/** @brief Delete a committed DFU image slot. * * @param slot Slot to delete. Must be a valid pointer acquired from this * module. @@ -72,18 +91,19 @@ int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *slot); * * @return 0 on success, or (negative) error code on failure. */ -int bt_mesh_dfu_slot_del_all(void); +void bt_mesh_dfu_slot_del_all(void); -/** @brief Get the DFU image slot at the given index. +/** @brief Get the DFU image slot at the given firmware image list index. * * @param idx DFU image slot index. * * @return The DFU image slot at the given index, or NULL if no slot exists with the * given index. */ -const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx); +const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx); -/** @brief Get the DFU image slot for the image with the given firmware ID. +/** @brief Get the committed DFU image slot for the image with the given + * firmware ID. * * @param fwid Firmware ID. * @param fwid_len Firmware ID length. @@ -91,16 +111,15 @@ const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx); * * @return Slot index on success, or negative error code on failure. */ -int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, - const struct bt_mesh_dfu_slot **slot); +int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot); -/** @brief Get the DFU image slot index of the given slot. +/** @brief Get the index in the firmware image list for the given slot. * * @param slot Slot to find. * * @return Slot index on success, or negative error code on failure. */ -int bt_mesh_dfu_slot_idx_get(const struct bt_mesh_dfu_slot *slot); +int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *slot); /** @brief Iterate through all DFU image slots. * diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index 94d656f3689..b7daf42af1c 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -43,7 +43,7 @@ static void print_fw_status(const struct shell *sh, enum bt_mesh_dfd_status stat uint16_t idx, const uint8_t *fwid, size_t fwid_len) { shell_fprintf(sh, SHELL_NORMAL, "{ \"status\": %d, \"slot_cnt\": %d, \"idx\": %d", - status, bt_mesh_dfu_slot_foreach(NULL, NULL), idx); + status, bt_mesh_dfu_slot_count(), idx); if (fwid) { shell_fprintf(sh, SHELL_NORMAL, ", \"fwid\": \""); for (size_t i = 0; i < fwid_len; i++) { @@ -325,10 +325,9 @@ static int cmd_dfd_fw_get(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - const struct bt_mesh_dfu_slot *slot; - int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); + int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, NULL); - if (idx >= 0 && bt_mesh_dfu_slot_is_valid(slot)) { + if (idx >= 0) { print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, fwid, fwid_len); } else { print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, 0xffff, fwid, fwid_len); @@ -349,7 +348,7 @@ static int cmd_dfd_fw_get_by_idx(const struct shell *sh, size_t argc, char *argv return err; } - if (slot && bt_mesh_dfu_slot_is_valid(slot)) { + if (slot) { print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, slot->fwid, slot->fwid_len); } else { print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, idx, NULL, 0); diff --git a/subsys/bluetooth/mesh/shell/dfu.c b/subsys/bluetooth/mesh/shell/dfu.c index 71d27b158e4..8d7fc96e014 100644 --- a/subsys/bluetooth/mesh/shell/dfu.c +++ b/subsys/bluetooth/mesh/shell/dfu.c @@ -375,13 +375,12 @@ static int cmd_dfu_metadata_encode(const struct shell *sh, size_t argc, char *ar static int cmd_dfu_slot_add(const struct shell *sh, size_t argc, char *argv[]) { - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; size_t size; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; size_t fwid_len = 0; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; size_t metadata_len = 0; - const char *uri = ""; int err = 0; size = shell_strtoul(argv[1], 0, &err); @@ -390,32 +389,33 @@ static int cmd_dfu_slot_add(const struct shell *sh, size_t argc, char *argv[]) return err; } - if (argc > 2) { - fwid_len = hex2bin(argv[2], strlen(argv[2]), fwid, - sizeof(fwid)); + shell_print(sh, "Adding slot (size: %u)", size); + slot = bt_mesh_dfu_slot_reserve(); + + if (!slot) { + shell_print(sh, "Failed to reserve slot."); + return 0; } + fwid_len = hex2bin(argv[2], strlen(argv[2]), fwid, + sizeof(fwid)); + bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len); + if (argc > 3) { metadata_len = hex2bin(argv[3], strlen(argv[3]), metadata, sizeof(metadata)); } - if (argc > 4) { - uri = argv[4]; - } + bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len); - shell_print(sh, "Adding slot (size: %u)", size); - - slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, - metadata_len, uri, strlen(uri)); - if (!slot) { - shell_print(sh, "Failed."); - return 0; + err = bt_mesh_dfu_slot_commit(slot); + if (err) { + shell_print(sh, "Failed to commit slot: %d", err); + bt_mesh_dfu_slot_release(slot); + return err; } - bt_mesh_dfu_slot_valid_set(slot, true); - - shell_print(sh, "Slot added. ID: %u", bt_mesh_dfu_slot_idx_get(slot)); + shell_print(sh, "Slot added. Index: %u", bt_mesh_dfu_slot_img_idx_get(slot)); return 0; } @@ -451,14 +451,7 @@ static int cmd_dfu_slot_del(const struct shell *sh, size_t argc, char *argv[]) static int cmd_dfu_slot_del_all(const struct shell *sh, size_t argc, char *argv[]) { - int err; - - err = bt_mesh_dfu_slot_del_all(); - if (err) { - shell_print(sh, "Failed deleting all slots (err: %d)", err); - return 0; - } - + bt_mesh_dfu_slot_del_all(); shell_print(sh, "All slots deleted."); return 0; } @@ -468,7 +461,6 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo { char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1]; char metadata[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1]; - char uri[CONFIG_BT_MESH_DFU_URI_MAXLEN + 1]; size_t len; len = bin2hex(slot->fwid, slot->fwid_len, fwid, sizeof(fwid)); @@ -476,8 +468,6 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo len = bin2hex(slot->metadata, slot->metadata_len, metadata, sizeof(metadata)); metadata[len] = '\0'; - memcpy(uri, slot->uri, slot->uri_len); - uri[slot->uri_len] = '\0'; if (idx != NULL) { shell_print(sh, "Slot %u:", *idx); @@ -487,7 +477,6 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo shell_print(sh, "\tSize: %u bytes", slot->size); shell_print(sh, "\tFWID: %s", fwid); shell_print(sh, "\tMetadata: %s", metadata); - shell_print(sh, "\tURI: %s", uri); } static int cmd_dfu_slot_get(const struct shell *sh, size_t argc, char *argv[]) @@ -970,8 +959,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_STATIC_SUBCMD_SET_CREATE( dfu_slot_cmds, SHELL_CMD_ARG(add, NULL, - " [ [ []]]", - cmd_dfu_slot_add, 2, 3), + " []", + cmd_dfu_slot_add, 3, 1), SHELL_CMD_ARG(del, NULL, "", cmd_dfu_slot_del, 2, 0), SHELL_CMD_ARG(del-all, NULL, NULL, cmd_dfu_slot_del_all, 1, 0), SHELL_CMD_ARG(get, NULL, "", cmd_dfu_slot_get, 2, 0), diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index 69c1055999f..15df7b8a5d3 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -58,7 +58,8 @@ CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y CONFIG_BT_MESH_DFU_SRV=y CONFIG_BT_MESH_DFU_CLI=y CONFIG_BT_MESH_DFD_SRV=y -CONFIG_BT_MESH_DFU_SLOT_CNT=3 +CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD=y +CONFIG_BT_MESH_DFU_SLOT_CNT=4 CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index f7c4ca6f4f0..a235e86eeec 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -434,25 +434,50 @@ static void target_prov_and_conf_default(void) target_prov_and_conf(addr, bind_params, ARRAY_SIZE(bind_params)); } +static struct bt_mesh_dfu_slot *slot_reserve_and_set(size_t size, uint8_t *fwid, size_t fwid_len, + uint8_t *metadata, size_t metadata_len) +{ + struct bt_mesh_dfu_slot *new_slot = bt_mesh_dfu_slot_reserve(); + + if (!new_slot) { + LOG_WRN("Reserving slot failed"); + return NULL; + } + + int err = bt_mesh_dfu_slot_fwid_set(new_slot, fwid, fwid_len); + + if (err) { + return NULL; + } + + err = bt_mesh_dfu_slot_info_set(new_slot, size, metadata, metadata_len); + + if (err) { + return NULL; + } + + return new_slot; +} + static bool slot_add(const struct bt_mesh_dfu_slot **slot) { - const struct bt_mesh_dfu_slot *new_slot; + struct bt_mesh_dfu_slot *new_slot; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; size_t metadata_len = 4; - const char *uri = ""; ASSERT_EQUAL(sizeof(target_fw_ver_new), fwid_len); - new_slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len, uri, - strlen(uri)); + new_slot = slot_reserve_and_set(size, fwid, fwid_len, metadata, metadata_len); if (!new_slot) { return false; } - bt_mesh_dfu_slot_valid_set(new_slot, true); + if (bt_mesh_dfu_slot_commit(new_slot) != 0) { + return false; + } if (slot) { *slot = new_slot; @@ -568,13 +593,12 @@ static void test_dist_dfu_self_update(void) static void test_dist_dfu_slot_create(void) { - const struct bt_mesh_dfu_slot *slot[3]; + struct bt_mesh_dfu_slot *slot[CONFIG_BT_MESH_DFU_SLOT_CNT]; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; - const char *uri = "test"; int err, i; ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, @@ -584,36 +608,26 @@ static void test_dist_dfu_slot_create(void) bt_mesh_device_setup(&prov, &dist_comp); dist_prov_and_conf(DIST_ADDR); - for (i = CONFIG_BT_MESH_DFU_SLOT_CNT - 1; i >= 0; i--) { + for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { fwid[0] = i; metadata[0] = i; - slot[i] = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len, uri, - strlen(uri)); + slot[i] = slot_reserve_and_set(size, fwid, fwid_len, metadata, metadata_len); ASSERT_FALSE(slot[i] == NULL, "Failed to add slot"); - } - - /* First slot is set as valid */ - err = bt_mesh_dfu_slot_valid_set(slot[0], true); - if (err) { - FAIL("Setting slot to valid state failed (err %d)", err); - return; - } - ASSERT_TRUE(bt_mesh_dfu_slot_is_valid(slot[0])); - /* Second slot is set as invalid */ - err = bt_mesh_dfu_slot_valid_set(slot[1], false); - if (err) { - FAIL("Setting slot to invalid state failed (err %d)", err); - return; + if (i > 0) { + /* All but first slot are committed */ + err = bt_mesh_dfu_slot_commit(slot[i]); + if (err) { + FAIL("Committing slot failed (err %d)", err); + } + } } - ASSERT_TRUE(!bt_mesh_dfu_slot_is_valid(slot[1])); - /* Last slot is deleted */ - err = bt_mesh_dfu_slot_del(slot[CONFIG_BT_MESH_DFU_SLOT_CNT - 1]); + /* Second slot is deleted */ + err = bt_mesh_dfu_slot_del(slot[1]); if (err) { FAIL("Slot delete failed (err %d)", err); - return; } PASS(); @@ -626,20 +640,17 @@ enum bt_mesh_dfu_iter check_slot(const struct bt_mesh_dfu_slot *slot, void *data size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; - const char *uri = "test"; - int idx = bt_mesh_dfu_slot_idx_get(slot); - - ASSERT_TRUE(idx >= 0, "Failed to retrieve slot index"); + int idx = bt_mesh_dfu_slot_img_idx_get(slot); + int *i = data; + ASSERT_EQUAL(idx, (*i)++); ASSERT_EQUAL(size, slot->size); - ASSERT_TRUE(strcmp(uri, slot->uri) == 0); - - fwid[0] = idx; + fwid[0] = idx + 2; ASSERT_EQUAL(fwid_len, slot->fwid_len); ASSERT_TRUE(memcmp(fwid, slot->fwid, fwid_len) == 0); - metadata[0] = idx; + metadata[0] = idx + 2; ASSERT_EQUAL(metadata_len, slot->metadata_len); ASSERT_TRUE(memcmp(metadata, slot->metadata, metadata_len) == 0); @@ -649,13 +660,12 @@ enum bt_mesh_dfu_iter check_slot(const struct bt_mesh_dfu_slot *slot, void *data static void test_dist_dfu_slot_create_recover(void) { size_t slot_count; - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; - const char *uri = "test"; int i, idx; ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, @@ -664,26 +674,17 @@ static void test_dist_dfu_slot_create_recover(void) bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); - slot_count = bt_mesh_dfu_slot_foreach(check_slot, NULL); - ASSERT_EQUAL(CONFIG_BT_MESH_DFU_SLOT_CNT - 1, slot_count); - - slot = bt_mesh_dfu_slot_at(0); - ASSERT_EQUAL(true, bt_mesh_dfu_slot_is_valid(slot)); + i = 0; + slot_count = bt_mesh_dfu_slot_foreach(check_slot, &i); + ASSERT_EQUAL(CONFIG_BT_MESH_DFU_SLOT_CNT - 2, slot_count); - slot = bt_mesh_dfu_slot_at(1); - ASSERT_TRUE(slot != NULL); - ASSERT_EQUAL(false, bt_mesh_dfu_slot_is_valid(slot)); - - for (i = 0; i < (CONFIG_BT_MESH_DFU_SLOT_CNT - 1); i++) { + for (i = 2; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { fwid[0] = i; idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); - ASSERT_TRUE(idx >= 0); - ASSERT_EQUAL(idx, bt_mesh_dfu_slot_idx_get(slot)); - + ASSERT_EQUAL(idx, i - 2); ASSERT_EQUAL(size, slot->size); - ASSERT_TRUE(strcmp(uri, slot->uri) == 0); - metadata[0] = idx; + metadata[0] = i; ASSERT_EQUAL(metadata_len, slot->metadata_len); ASSERT_TRUE(memcmp(metadata, slot->metadata, metadata_len) == 0); } @@ -693,7 +694,7 @@ static void test_dist_dfu_slot_create_recover(void) static void check_delete_all(void) { - int i, idx, err; + int i; const struct bt_mesh_dfu_slot *slot; size_t slot_count; @@ -706,14 +707,6 @@ static void check_delete_all(void) for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT - 1; i++) { slot = bt_mesh_dfu_slot_at(i); ASSERT_TRUE(slot == NULL); - - idx = bt_mesh_dfu_slot_idx_get(slot); - ASSERT_TRUE(idx < 0); - - err = bt_mesh_dfu_slot_valid_set(slot, true); - ASSERT_EQUAL(err, -ENOENT); - - ASSERT_TRUE(!bt_mesh_dfu_slot_is_valid(slot)); } } @@ -726,7 +719,6 @@ static void test_dist_dfu_slot_delete_all(void) bt_mesh_device_setup(&prov, &dist_comp); bt_mesh_dfu_slot_del_all(); - check_delete_all(); PASS(); @@ -742,6 +734,63 @@ static void test_dist_dfu_slot_check_delete_all(void) PASS(); } +static void test_dist_dfu_slot_reservation(void) +{ + int i; + struct bt_mesh_dfu_slot *slots[CONFIG_BT_MESH_DFU_SLOT_CNT]; + + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_device_setup(&prov, &dist_comp); + + for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { + slots[i] = bt_mesh_dfu_slot_reserve(); + ASSERT_TRUE(slots[i] != NULL); + } + + ASSERT_EQUAL(NULL, bt_mesh_dfu_slot_reserve()); + bt_mesh_dfu_slot_release(slots[0]); + /* Release twice to check idempotency with empty pool */ + bt_mesh_dfu_slot_release(slots[0]); + ASSERT_TRUE(bt_mesh_dfu_slot_reserve() != NULL); + ASSERT_EQUAL(NULL, bt_mesh_dfu_slot_reserve()); + + PASS(); +} + +static void test_dist_dfu_slot_idempotency(void) +{ + uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; + size_t fwid_len = 4; + struct bt_mesh_dfu_slot *slot; + + ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 1, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 1"); + + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_device_setup(&prov, &dist_comp); + dist_prov_and_conf(DIST_ADDR); + + slot = bt_mesh_dfu_slot_reserve(); + ASSERT_TRUE(slot != NULL); + + bt_mesh_dfu_slot_release(slot); + bt_mesh_dfu_slot_release(slot); + + slot = bt_mesh_dfu_slot_reserve(); + ASSERT_TRUE(slot != NULL); + + ASSERT_EQUAL(0, bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len)); + ASSERT_EQUAL(0, bt_mesh_dfu_slot_info_set(slot, 100, NULL, 0)); + + ASSERT_EQUAL(0, bt_mesh_dfu_slot_commit(slot)); + ASSERT_EQUAL(-EINVAL, bt_mesh_dfu_slot_commit(slot)); + + ASSERT_EQUAL(0, bt_mesh_dfu_slot_del(slot)); + ASSERT_EQUAL(-EINVAL, bt_mesh_dfu_slot_del(slot)); + + PASS(); +} + static void target_test_effect(enum bt_mesh_dfu_effect effect) { dfu_target_effect = effect; @@ -921,12 +970,14 @@ static void cli_common_fail_on_init(void) static void cli_common_init_recover(void) { - const struct bt_mesh_dfu_slot *slot; + struct bt_mesh_dfu_slot *slot; + uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; + size_t fwid_len = 4; bt_mesh_test_cfg_set(NULL, 300); bt_mesh_device_setup(&prov, &cli_comp); - ASSERT_TRUE(slot_add(&slot)); + ASSERT_TRUE(bt_mesh_dfu_slot_get(fwid, fwid_len, &slot) >= 0); dfu_cli_inputs_prepare(0); dfu_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; @@ -1595,6 +1646,10 @@ static const struct bst_test_instance test_dfu[] = { TEST_CASE(dist, dfu_slot_delete_all, "Distributor deletes all image slots"), TEST_CASE(dist, dfu_slot_check_delete_all, "Distributor checks if all slots are removed from persistent storage"), + TEST_CASE(dist, dfu_slot_reservation, + "Distributor checks that the correct number of slots can be reserved"), + TEST_CASE(dist, dfu_slot_idempotency, + "Distributor checks that the the DFU slot APIs are idempotent"), TEST_CASE(cli, stop, "DFU Client stops at configured point of Firmware Distribution"), TEST_CASE(cli, fail_on_persistency, "DFU Client doesn't give up DFU Transfer"), TEST_CASE(cli, all_targets_lost_on_metadata, diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh new file mode 100755 index 00000000000..3f18f1a2651 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test DFU Slot API. This test tests that the APIs are idempotent. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest dfu_slot_idempotency dfu_dist_dfu_slot_idempotency + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest dfu_slot_idempotency_psa dfu_dist_dfu_slot_idempotency diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh new file mode 100755 index 00000000000..ddd7d0123f5 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test DFU Slot API. This test tests slot reservation APIs. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest dfu_slot_reservation dfu_dist_dfu_slot_reservation + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest dfu_slot_reservation_psa dfu_dist_dfu_slot_reservation From 5bb306794232d4e391987448bbf73724e21d5a08 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 14 Sep 2023 15:34:07 +0200 Subject: [PATCH 0575/4498] twister: pytest: Allow list of pytest testpaths Allow to specify a list of pytest directories, files or subtests with pytest_root keyword in test yaml. Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/harness.py | 5 +- scripts/schemas/twister/testsuite-schema.yaml | 8 ++- .../pytest_integration/test_harness_pytest.py | 61 +++++++++++++++++++ 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 96b4a2e3461..6ae2622c810 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -245,19 +245,20 @@ def pytest_run(self, timeout): def generate_command(self): config = self.instance.testsuite.harness_config - pytest_root = config.get('pytest_root', 'pytest') if config else 'pytest' + pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] pytest_args = config.get('pytest_args', []) if config else [] command = [ 'pytest', '--twister-harness', '-s', '-v', - os.path.join(self.source_dir, pytest_root), f'--build-dir={self.running_dir}', f'--junit-xml={self.report_file}', '--log-file-level=DEBUG', '--log-file-format=%(asctime)s.%(msecs)d:%(levelname)s:%(name)s: %(message)s', f'--log-file={self.pytest_log_file_path}' ] + command.extend([os.path.normpath(os.path.join( + self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) command.extend(pytest_args) handler: Handler = self.instance.handler diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 116c1a43379..96a121767a5 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -95,8 +95,10 @@ mapping: type: int required: false "pytest_root": - type: str + type: seq required: false + sequence: + - type: str "pytest_args": type: seq required: false @@ -293,8 +295,10 @@ mapping: type: int required: false "pytest_root": - type: str + type: seq required: false + sequence: + - type: str "pytest_args": type: seq required: false diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index db7bf389fbd..e1b27a0cf02 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -48,6 +48,67 @@ def test_pytest_command(testinstance: TestInstance, device_type): assert c in command +@pytest.mark.parametrize( + ('pytest_root', 'expected'), + [ + ( + ['pytest/test_shell_help.py'], + ['samples/hello/pytest/test_shell_help.py'] + ), + ( + ['pytest/test_shell_help.py', 'pytest/test_shell_version.py', 'test_dir'], + ['samples/hello/pytest/test_shell_help.py', + 'samples/hello/pytest/test_shell_version.py', + 'samples/hello/test_dir'] + ), + ( + ['../shell/pytest/test_shell.py'], + ['samples/shell/pytest/test_shell.py'] + ), + ( + ['/tmp/test_temp.py'], + ['/tmp/test_temp.py'] + ), + ( + ['~/tmp/test_temp.py'], + ['/home/joe/tmp/test_temp.py'] + ), + ( + ['$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest'], + ['/zephyr_base/samples/subsys/testsuite/pytest/shell/pytest'] + ), + ( + ['pytest/test_shell_help.py::test_A', 'pytest/test_shell_help.py::test_B'], + ['samples/hello/pytest/test_shell_help.py::test_A', + 'samples/hello/pytest/test_shell_help.py::test_B'] + ), + ( + ['pytest/test_shell_help.py::test_A[param_a]'], + ['samples/hello/pytest/test_shell_help.py::test_A[param_a]'] + ) + ], + ids=[ + 'one_file', + 'more_files', + 'relative_path', + 'absollute_path', + 'user_dir', + 'with_env_var', + 'subtests', + 'subtest_with_param' + ] +) +def test_pytest_handle_source_list(testinstance: TestInstance, monkeypatch, pytest_root, expected): + monkeypatch.setenv('ZEPHYR_BASE', '/zephyr_base') + monkeypatch.setenv('HOME', '/home/joe') + testinstance.testsuite.harness_config['pytest_root'] = pytest_root + pytest_harness = Pytest() + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + for pytest_src in expected: + assert pytest_src in command + + def test_if_report_is_parsed(pytester, testinstance: TestInstance): test_file_content = textwrap.dedent(""" def test_1(): From 033afe1c0c3c047b36c86ca9a1d225129e3e5315 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 14 Sep 2023 15:38:34 +0200 Subject: [PATCH 0576/4498] twister: doc: Update pytest and twister docs Document how to use pytest_root keyword. Update docs with changes in pytest-twister-harness plugin. Signed-off-by: Grzegorz Chwierut --- doc/develop/test/pytest.rst | 55 +++++++++++++++++++++++------------- doc/develop/test/twister.rst | 26 +++++++++++------ 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 97737ce0ae2..d0fad4d6be6 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -49,28 +49,47 @@ How to create a pytest test An example of a pytest test is given at :zephyr_file:`samples/subsys/testsuite/pytest/shell/pytest/test_shell.py`. Twister calls pytest for each configuration from the .yaml file which uses ``harness: pytest``. By default, it points to ``pytest`` directory, located next to a directory with binary sources. -A keyword ``pytest_root`` placed under ``harness_config`` section can be used to point to another -location. +A keyword ``pytest_root`` placed under ``harness_config`` section can be used to point to other +files, directories or subtests. -Pytest scans the given folder looking for tests, following its default +Pytest scans the given locations looking for tests, following its default `discovery rules `_ One can also pass some extra arguments to the pytest from yaml file using ``pytest_args`` keyword under ``harness_config``, e.g.: ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. -Following import is required to include in .py sources: +Helpers & fixtures +================== + +dut +--- + +Give access to a DeviceAdapter type object, that represents Device Under Test. +This fixture is the core of pytest harness plugin. It is required to launch +DUT (initialize logging, flash device, connect serial etc). +This fixture yields a device prepared according to the requested type +(native posix, qemu, hardware, etc.). All types of devices share the same API. +This allows for writing tests which are device-type-agnostic. .. code-block:: python - from twister_harness import Device + from twister_harness import DeviceAdapter -It is important for type checking and enabling IDE hints for ``dut`` s (objects representing -Devices Under Test). The ``dut`` fixture is the core of pytest harness plugin. When used as an -argument of a test function it gives access to a DeviceAbstract type object. The fixture yields a -device prepared according to the requested type (native posix, qemu, hardware, etc.). All types of -devices share the same API. This allows for writing tests which are device-type-agnostic. + def test_sample(dut: DeviceAdapter): + dut.readlines_until('Hello world') -Helpers & fixtures -================== +shell +----- + +Provide an object with methods used to interact with shell application. +It calls `wait_for_promt` method, to not start scenario until DUT is ready. +Note that it uses `dut` fixture, so `dut` can be skipped when `shell` is used. + +.. code-block:: python + + from twister_harness import Shell + + def test_shell(shell: Shell): + shell.exec_command('help') mcumgr ------ @@ -82,16 +101,15 @@ More information about MCUmgr can be found here :ref:`mcu_mgr`. This fixture requires the ``mcumgr`` available in the system PATH Only selected functionality of MCUmgr is wrapped by this fixture. - For example, here is a test with a fixture ``mcumgr`` .. code-block:: python - from twister_harness import Device, McuMgr + from twister_harness import DeviceAdapter, Shell, McuMgr - def test_upgrade(dut: Device, mcumgr: McuMgr): - # wait for dut is up - time.sleep(2) + def test_upgrade(dut: DeviceAdapter, shell: Shell, mcumgr: McuMgr): + # free the serial port for mcumgr + dut.disconnect() # upload the signed image mcumgr.image_upload('path/to/zephyr.signed.bin') # obtain the hash of uploaded image from the device @@ -105,7 +123,4 @@ For example, here is a test with a fixture ``mcumgr`` Limitations *********** -* Device adapters in pytest plugin provide `iter_stdout` method to read from devices. In some - cases, it is not the most convenient way, and it will be considered how to improve this - (for example replace it with a simple read function with a given byte size and timeout arguments). * Not every platform type is supported in the plugin (yet). diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 48c86ca899d..5f61e6ec810 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -492,10 +492,11 @@ harness_config: Only one fixture can be defined per testcase and the fixture name has to be unique across all tests in the test suite. - pytest_root: (default pytest) - Specify a pytest directory which need to execute when test case begin to running, - default pytest directory name is pytest, after pytest finished, twister will - check if this case pass or fail according the pytest report. + pytest_root: (default pytest) + Specify a list of pytest directories, files or subtests that need to be executed + when test case begin to running, default pytest directory is pytest. + After pytest finished, twister will check if this case pass or fail according + to the pytest report. pytest_args: (default empty) Specify a list of additional arguments to pass to ``pytest``. @@ -526,15 +527,24 @@ harness_config: The following is an example yaml file with pytest harness_config options, default pytest_root name "pytest" will be used if pytest_root not specified. - please refer the example in samples/subsys/testsuite/pytest/. + please refer the examples in samples/subsys/testsuite/pytest/. :: + common: + harness: pytest tests: - pytest.example: - harness: pytest + pytest.example.directories: + harness_config: + pytest_root: + - pytest_dir1 + - $ENV_VAR/samples/test/pytest_dir2 + pytest.example.files_and_subtests: harness_config: - pytest_root: [pytest directory name] + pytest_root: + - pytest/test_file_1.py + - test_file_2.py::test_A + - test_file_2.py::test_B[param_a] The following is an example yaml file with robot harness_config options. From 8219c7ccdad00f160371bd068d919c840be828f2 Mon Sep 17 00:00:00 2001 From: Hein Wessels Date: Tue, 15 Aug 2023 09:06:37 +0200 Subject: [PATCH 0577/4498] doc: release process: link to milestone dates on wiki This adds a link for convenience. Many times before I struggled to find the date for the next feature freeze. This is to help others, and myself, to find it easier in the future. Signed-off-by: Hein Wessels --- doc/project/release_process.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/project/release_process.rst b/doc/project/release_process.rst index 5ffb189dbf1..e1e07c417c8 100644 --- a/doc/project/release_process.rst +++ b/doc/project/release_process.rst @@ -45,6 +45,12 @@ The Zephyr release model was loosely based on the Linux kernel model: Release Cycle +.. note:: + + The milestones for the current major version can be found on the + `Official GitHub Wiki `_. + Information on previous releases can be found :ref:`here `. + Development Phase ***************** From 8f370034015073aa91c4b33a98fb216c160ecd25 Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Fri, 15 Sep 2023 07:52:50 -0700 Subject: [PATCH 0578/4498] twister: platform filtering when test-only Add the functionality to use -p and -P to filter out platforms when using test-only Signed-off-by: Pavlo Havrylyuk --- scripts/pylib/twister/twisterlib/testplan.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 1d9c625b28a..0199c6e1ef5 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -216,11 +216,16 @@ def load(self): # in cases where no platform was specified when running the tests. # If the platform does not exist in the hardware map, just skip it. connected_list = [] - if not self.options.platform: + if self.options.platform: + connected_list = self.options.platform + else: for connected in self.hwm.duts: if connected['connected']: connected_list.append(connected['platform']) - + if self.options.exclude_platform: + for excluded in self.options.exclude_platform: + if excluded in connected_list: + connected_list.remove(excluded) self.load_from_file(last_run, filter_platform=connected_list) self.selected_platforms = set(p.platform.name for p in self.instances.values()) else: From acf3755d1cdf3393e91a15094992e718cc885348 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 15 Sep 2023 23:51:00 +0800 Subject: [PATCH 0579/4498] ztest_new: add CONFIG_ZTEST_NO_YIELD to ztest_new Rather than yielding to idle thread, keep the part awake. So debugger can still access it, since some SOCs cannot be debugged in low power states. Signed-off-by: Hake Huang --- subsys/testsuite/ztest/src/ztest_new.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index 0772383bc0a..61453f25339 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -1079,7 +1079,18 @@ int main(void) z_init_mock(); test_main(); end_report(); +#ifdef CONFIG_ZTEST_NO_YIELD + /* + * Rather than yielding to idle thread, keep the part awake so debugger can + * still access it, since some SOCs cannot be debugged in low power states. + */ + uint32_t key = irq_lock(); + while (1) { + ; /* Spin */ + } + irq_unlock(key); +#endif return test_status; } #else @@ -1124,6 +1135,18 @@ int main(void) state.boots = 0; } } +#ifdef CONFIG_ZTEST_NO_YIELD + /* + * Rather than yielding to idle thread, keep the part awake so debugger can + * still access it, since some SOCs cannot be debugged in low power states. + */ + uint32_t key = irq_lock(); + + while (1) { + ; /* Spin */ + } + irq_unlock(key); +#endif return 0; } #endif From 3a3f02c990642cc8b001020e2f6ca7dd34a9903a Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 3 Aug 2023 12:47:47 +0300 Subject: [PATCH 0580/4498] west: hal_silabs: Add support for librail for 1x devices Update hal_silabs to support the use of librail for efr32xg1x devices. Signed-off-by: Yonatan Schachter --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3ce53625f87..85e92e965f0 100644 --- a/west.yml +++ b/west.yml @@ -219,7 +219,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 20113e9520ce59ee7fa85ba10102d0880822bb3e + revision: 267cd0bb17cf3cd431633a40b6d37a981e78dcb7 path: modules/hal/silabs groups: - hal From fb140de04ad428305b37e5032ff9c02d057df252 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sun, 6 Aug 2023 13:55:40 +0300 Subject: [PATCH 0581/4498] soc: silabs_exx32: Select SOC_GECKO_SERIES1 for 1x devices Select SOC_GECKO_SERIES1 for all Silabs devices of the series 1x. Signed-off-by: Yonatan Schachter --- boards/arm/efr32_radio/Kconfig.defconfig | 1 + soc/arm/silabs_exx32/efm32gg11b/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32gg12b/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg1p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg12p/Kconfig.series | 1 + 7 files changed, 7 insertions(+) diff --git a/boards/arm/efr32_radio/Kconfig.defconfig b/boards/arm/efr32_radio/Kconfig.defconfig index 2ed602da2eb..39c4b9ff695 100644 --- a/boards/arm/efr32_radio/Kconfig.defconfig +++ b/boards/arm/efr32_radio/Kconfig.defconfig @@ -33,6 +33,7 @@ config LOG_BACKEND_SWO_FREQ_HZ if SOC_GECKO_USE_RAIL config FPU + default n if SOC_GECKO_SERIES1 default y endif # SOC_GECKO_USE_RAIL diff --git a/soc/arm/silabs_exx32/efm32gg11b/Kconfig.series b/soc/arm/silabs_exx32/efm32gg11b/Kconfig.series index 50d8a7eb0aa..34fa472c23d 100644 --- a/soc/arm/silabs_exx32/efm32gg11b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32gg11b/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFM32GG11B select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_TRNG + select SOC_GECKO_SERIES1 help Enable support for EFM32 GiantGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32gg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32gg12b/Kconfig.series index 0f2c18cfbb4..e8dcf52cf17 100644 --- a/soc/arm/silabs_exx32/efm32gg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32gg12b/Kconfig.series @@ -17,5 +17,6 @@ config SOC_SERIES_EFM32GG12B select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_TRNG + select SOC_GECKO_SERIES1 help Enable support for EFM32 GiantGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series index e7f524a026f..aae28d74a45 100644 --- a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFR32BG13P select SOC_GECKO_EMU select SOC_GECKO_GPIO select HAS_PM + select SOC_GECKO_SERIES1 help Enable support for EFR32BG13P Blue Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series index 6f557377579..6feb9f9cc22 100644 --- a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFR32FG13P select SOC_GECKO_GPIO select SOC_GECKO_HAS_ERRATA_RTCC_E201 select HAS_PM + select SOC_GECKO_SERIES1 help Enable support for EFR32 FlexGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series index f8e509faa6d..8e57722a566 100644 --- a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFR32FG1P select SOC_GECKO_GPIO select SOC_GECKO_HAS_ERRATA_RTCC_E201 select HAS_PM + select SOC_GECKO_SERIES1 help Enable support for EFR32 FlexGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series index 7c636daec86..00bdfc643b5 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series @@ -20,5 +20,6 @@ config SOC_SERIES_EFR32MG12P select SOC_GECKO_GPIO select SOC_GECKO_TRNG select HAS_PM + select SOC_GECKO_SERIES1 help Enable support for EFR32 Mighty Gecko MCU series From cb297ae3bf72da8cd482d8be19e651674a572b84 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sun, 6 Aug 2023 14:35:46 +0300 Subject: [PATCH 0582/4498] pinctrl: silabs: Added default pinctrl for efr32xg13p Added a default pinctrl for the efr32xg13p device. Signed-off-by: Yonatan Schachter --- .../arm/efr32_radio/efr32_radio_brd4255a.dts | 8 +++++++ dts/arm/silabs/efr32xg13p-pinctrl.dtsi | 23 +++++++++++++++++++ dts/arm/silabs/efr32xg13p.dtsi | 8 +++++++ 3 files changed, 39 insertions(+) create mode 100644 dts/arm/silabs/efr32xg13p-pinctrl.dtsi diff --git a/boards/arm/efr32_radio/efr32_radio_brd4255a.dts b/boards/arm/efr32_radio/efr32_radio_brd4255a.dts index de019e6d1e8..cf146428322 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4255a.dts +++ b/boards/arm/efr32_radio/efr32_radio_brd4255a.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include #include "efr32_radio.dtsi" / { @@ -57,3 +58,10 @@ }; }; + +&usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/dts/arm/silabs/efr32xg13p-pinctrl.dtsi b/dts/arm/silabs/efr32xg13p-pinctrl.dtsi new file mode 100644 index 00000000000..e500e3b18bd --- /dev/null +++ b/dts/arm/silabs/efr32xg13p-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for uart0 device, default state */ + usart0_default: usart0_default { + group1 { + /* configure PA.1 as UART_RX */ + psels = , + ; + }; + group2 { + /* configure PA.0 as UART_TX */ + psels = , + ; + }; + }; +}; diff --git a/dts/arm/silabs/efr32xg13p.dtsi b/dts/arm/silabs/efr32xg13p.dtsi index 3db40b5b5d4..96d9c6493d1 100644 --- a/dts/arm/silabs/efr32xg13p.dtsi +++ b/dts/arm/silabs/efr32xg13p.dtsi @@ -180,6 +180,14 @@ status = "disabled"; }; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; &nvic { From b0f0cd04e273407af314919750617e6916f9e208 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 10 Aug 2023 20:25:40 +0300 Subject: [PATCH 0583/4498] pinctrl: silabs: Added default pinctrl for efr32xg1p Added a default pinctrl for the efr32xg1p device. Signed-off-by: Yonatan Schachter --- .../arm/efr32_radio/efr32_radio_brd4250b.dts | 8 +++++++ dts/arm/silabs/efr32fg1p.dtsi | 8 +++++++ dts/arm/silabs/efr32xg1p-pinctrl.dtsi | 23 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 dts/arm/silabs/efr32xg1p-pinctrl.dtsi diff --git a/boards/arm/efr32_radio/efr32_radio_brd4250b.dts b/boards/arm/efr32_radio/efr32_radio_brd4250b.dts index 531f3bf1094..2167b1b69b7 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4250b.dts +++ b/boards/arm/efr32_radio/efr32_radio_brd4250b.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "efr32_radio.dtsi" / { @@ -79,3 +80,10 @@ }; }; + +&usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/dts/arm/silabs/efr32fg1p.dtsi b/dts/arm/silabs/efr32fg1p.dtsi index 586bbcd36fd..a451d44cb2c 100644 --- a/dts/arm/silabs/efr32fg1p.dtsi +++ b/dts/arm/silabs/efr32fg1p.dtsi @@ -172,6 +172,14 @@ }; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; &nvic { diff --git a/dts/arm/silabs/efr32xg1p-pinctrl.dtsi b/dts/arm/silabs/efr32xg1p-pinctrl.dtsi new file mode 100644 index 00000000000..e500e3b18bd --- /dev/null +++ b/dts/arm/silabs/efr32xg1p-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for uart0 device, default state */ + usart0_default: usart0_default { + group1 { + /* configure PA.1 as UART_RX */ + psels = , + ; + }; + group2 { + /* configure PA.0 as UART_TX */ + psels = , + ; + }; + }; +}; From 8b4c75d2330ced1bddfe758db707b63dad868146 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 10 Aug 2023 23:17:26 +0300 Subject: [PATCH 0584/4498] pinctrl: silabs: Added default pinctrl for efr32xg12p Added a default pinctrl for the efr32xg12p device. Signed-off-by: Yonatan Schachter --- .../arm/efr32mg_sltb004a/efr32mg_sltb004a.dts | 5 ++-- dts/arm/silabs/efr32mg.dtsi | 8 +++++++ dts/arm/silabs/efr32xg12p-pinctrl.dtsi | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 dts/arm/silabs/efr32xg12p-pinctrl.dtsi diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts index 1a746d53e61..6bdc5be574f 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include / { @@ -74,8 +75,8 @@ &usart0 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/dts/arm/silabs/efr32mg.dtsi b/dts/arm/silabs/efr32mg.dtsi index 65611091edf..cfbbde48af9 100644 --- a/dts/arm/silabs/efr32mg.dtsi +++ b/dts/arm/silabs/efr32mg.dtsi @@ -233,6 +233,14 @@ status = "disabled"; }; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; &nvic { diff --git a/dts/arm/silabs/efr32xg12p-pinctrl.dtsi b/dts/arm/silabs/efr32xg12p-pinctrl.dtsi new file mode 100644 index 00000000000..e500e3b18bd --- /dev/null +++ b/dts/arm/silabs/efr32xg12p-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for uart0 device, default state */ + usart0_default: usart0_default { + group1 { + /* configure PA.1 as UART_RX */ + psels = , + ; + }; + group2 { + /* configure PA.0 as UART_TX */ + psels = , + ; + }; + }; +}; From 55ec77cac7a8fc0e6b859c260812ef81b7d4d911 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 10:59:27 +0200 Subject: [PATCH 0585/4498] dts: bindings: arm: nordic,nrf-uicr: add gpio-as-nreset So that the reset GPIO can be configured as nRESET from devicetree. Signed-off-by: Gerard Marull-Paretas --- dts/bindings/arm/nordic,nrf-uicr.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dts/bindings/arm/nordic,nrf-uicr.yaml b/dts/bindings/arm/nordic,nrf-uicr.yaml index dbbb34e1265..b39a6ed6855 100644 --- a/dts/bindings/arm/nordic,nrf-uicr.yaml +++ b/dts/bindings/arm/nordic,nrf-uicr.yaml @@ -19,3 +19,14 @@ properties: This setting, once applied, can only be unset by erasing the UICR registers. Refer to the reference manual for more details. + + gpio-as-nreset: + type: boolean + description: | + When enabled, this property will configure the reset GPIO as nRESET. + + nRESET pin in nRF52805/52810/52811/52832 series: P0.21 + nRESET pin in nRF52820/52833/52840 series: P0.18 + + This setting, once applied, can only be unset by erasing the UICR + registers. Refer to the reference manual for more details. From 4d7d5ce226951d7bd54af38d7613e07b30641f09 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:06:23 +0200 Subject: [PATCH 0586/4498] modules: hal_nordic: nrfx: add support for 'gpio-as-nreset' So that the HAL's system init function configures the reset GPIO as nRESET if requested by the user. Signed-off-by: Gerard Marull-Paretas --- modules/hal_nordic/nrfx/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 98ba1961396..e98db561906 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -111,14 +111,19 @@ if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) endif() # Inject HAL "CONFIG_NFCT_PINS_AS_GPIOS" definition if user requests to -# configure the NFCT pins as GPIOS. This way, the HAL will take care of doing -# the proper configuration sequence during system init +# configure the NFCT pins as GPIOS. Do the same with "CONFIG_GPIO_AS_PINRESET" +# to configure the reset GPIO as nRESET. This way, the HAL will take care of +# doing the proper configuration sequence during system init dt_nodelabel(uicr_path NODELABEL "uicr") if(${uicr_path}) dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") - if(${nfct_pins_as_gpios}) zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) endif() + + dt_prop(gpio_as_nreset PATH ${uicr_path} PROPERTY "gpio-as-nreset") + if(${gpio_as_nreset}) + zephyr_library_compile_definitions(CONFIG_GPIO_AS_PINRESET) + endif() endif() From 012fa5c5ef2b314c92bf4f31634d71560d81d081 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:34:15 +0200 Subject: [PATCH 0587/4498] boards: arm: nrf-based: move all boards to gpio-as-nreset dt property Instead of using the about to be deprecated CONFIG_GPIO_AS_PINRESET option. Signed-off-by: Gerard Marull-Paretas --- boards/arm/96b_nitrogen/96b_nitrogen.dts | 4 ++++ boards/arm/96b_nitrogen/96b_nitrogen_defconfig | 3 --- boards/arm/acn52832/acn52832.dts | 4 ++++ boards/arm/acn52832/acn52832_defconfig | 3 --- .../adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts | 4 ++++ .../adafruit_feather_nrf52840_defconfig | 3 --- .../adafruit_itsybitsy_nrf52840.dts | 4 ++++ .../adafruit_itsybitsy_nrf52840_defconfig | 2 -- .../arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi | 4 ++++ boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig | 3 --- .../arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig | 3 --- boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts | 4 ++++ .../arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig | 3 --- boards/arm/bl652_dvk/bl652_dvk.dts | 4 ++++ boards/arm/bl652_dvk/bl652_dvk_defconfig | 3 --- boards/arm/bl653_dvk/bl653_dvk.dts | 4 ++++ boards/arm/bl653_dvk/bl653_dvk_defconfig | 3 --- boards/arm/bl654_dvk/bl654_dvk.dts | 4 ++++ boards/arm/bl654_dvk/bl654_dvk_defconfig | 3 --- boards/arm/bl654_sensor_board/bl654_sensor_board.dts | 4 ++++ boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig | 3 --- boards/arm/bl654_usb/bl654_usb.dts | 4 ++++ boards/arm/bl654_usb/bl654_usb_defconfig | 3 --- .../blueclover_plt_demo_v2_nrf52832.dts | 4 ++++ .../blueclover_plt_demo_v2_nrf52832_defconfig | 3 --- boards/arm/bt510/bt510.dts | 4 ++++ boards/arm/bt510/bt510_defconfig | 3 --- boards/arm/bt610/bt610.dts | 1 + boards/arm/bt610/bt610_defconfig | 3 --- .../contextualelectronics_abc/contextualelectronics_abc.dts | 4 ++++ .../contextualelectronics_abc_defconfig | 3 --- boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts | 4 ++++ .../arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig | 3 --- boards/arm/degu_evk/degu_evk.dts | 4 ++++ boards/arm/degu_evk/degu_evk_defconfig | 1 - boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts | 4 ++++ .../ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig | 3 --- boards/arm/mg100/mg100.dts | 4 ++++ boards/arm/mg100/mg100_defconfig | 3 --- boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts | 4 ++++ boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig | 3 --- boards/arm/nrf52832_mdk/nrf52832_mdk.dts | 4 ++++ boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig | 3 --- boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts | 4 ++++ boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig | 3 --- boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts | 4 ++++ boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig | 3 --- boards/arm/nrf52840_blip/nrf52840_blip.dts | 4 ++++ boards/arm/nrf52840_blip/nrf52840_blip_defconfig | 3 --- boards/arm/nrf52840_mdk/nrf52840_mdk.dts | 4 ++++ boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig | 3 --- .../arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts | 1 + .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig | 3 --- boards/arm/nrf52840_papyr/nrf52840_papyr.dts | 4 ++++ boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig | 3 --- boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts | 4 ++++ boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig | 3 --- boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts | 4 ++++ boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig | 3 --- .../arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts | 1 + .../nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig | 3 --- boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts | 4 ++++ .../nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig | 3 --- boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts | 4 ++++ boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig | 3 --- boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts | 4 ++++ boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig | 3 --- boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts | 4 ++++ boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig | 3 --- boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts | 4 ++++ boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig | 3 --- boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts | 4 ++++ boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig | 3 --- boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts | 4 ++++ boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig | 3 --- boards/arm/pan1770_evb/pan1770_evb.dts | 4 ++++ boards/arm/pan1770_evb/pan1770_evb_defconfig | 3 --- boards/arm/pan1780_evb/pan1780_evb.dts | 4 ++++ boards/arm/pan1780_evb/pan1780_evb_defconfig | 3 --- boards/arm/pan1781_evb/pan1781_evb.dts | 4 ++++ boards/arm/pan1781_evb/pan1781_evb_defconfig | 3 --- boards/arm/pan1782_evb/pan1782_evb.dts | 4 ++++ boards/arm/pan1782_evb/pan1782_evb_defconfig | 3 --- boards/arm/particle_argon/particle_argon.dts | 4 ++++ boards/arm/particle_argon/particle_argon_defconfig | 3 --- boards/arm/particle_boron/particle_boron.dts | 4 ++++ boards/arm/particle_boron/particle_boron_defconfig | 3 --- boards/arm/particle_xenon/particle_xenon.dts | 4 ++++ boards/arm/particle_xenon/particle_xenon_defconfig | 3 --- boards/arm/pinetime_devkit0/pinetime_devkit0.dts | 4 ++++ boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig | 3 --- boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts | 4 ++++ boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig | 3 --- boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts | 4 ++++ boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig | 3 --- .../raytac_mdbt50q_db_33_nrf52833.dts | 4 ++++ .../raytac_mdbt50q_db_33_nrf52833_defconfig | 3 --- .../raytac_mdbt50q_db_40_nrf52840.dts | 4 ++++ .../raytac_mdbt50q_db_40_nrf52840_defconfig | 3 --- boards/arm/reel_board/dts/reel_board.dtsi | 4 ++++ boards/arm/reel_board/reel_board_defconfig | 3 --- boards/arm/reel_board/reel_board_v2_defconfig | 3 --- .../arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts | 4 ++++ .../ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig | 3 --- .../arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts | 4 ++++ .../ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig | 3 --- .../arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts | 4 ++++ .../ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig | 3 --- .../arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts | 4 ++++ .../ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig | 3 --- .../arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts | 4 ++++ .../ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig | 3 --- .../arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts | 4 ++++ .../ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig | 3 --- boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts | 4 ++++ .../ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig | 3 --- boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts | 4 ++++ .../ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig | 3 --- boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts | 4 ++++ .../ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig | 3 --- boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts | 4 ++++ .../ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig | 3 --- boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts | 4 ++++ .../we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig | 3 --- boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts | 4 ++++ .../we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig | 3 --- boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts | 4 ++++ .../we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig | 3 --- boards/arm/xiao_ble/xiao_ble_common.dtsi | 4 ++++ boards/arm/xiao_ble/xiao_ble_defconfig | 3 --- boards/arm/xiao_ble/xiao_ble_sense_defconfig | 3 --- 131 files changed, 247 insertions(+), 198 deletions(-) diff --git a/boards/arm/96b_nitrogen/96b_nitrogen.dts b/boards/arm/96b_nitrogen/96b_nitrogen.dts index d5bac1cd6d3..69148a032d7 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen.dts +++ b/boards/arm/96b_nitrogen/96b_nitrogen.dts @@ -58,6 +58,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig index 500c469813b..e804b43da5c 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig +++ b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig @@ -16,7 +16,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/acn52832/acn52832.dts b/boards/arm/acn52832/acn52832.dts index 1e01221f652..ca9f5046fba 100644 --- a/boards/arm/acn52832/acn52832.dts +++ b/boards/arm/acn52832/acn52832.dts @@ -45,6 +45,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/acn52832/acn52832_defconfig b/boards/arm/acn52832/acn52832_defconfig index 6b1ae1a7ba7..2bb13882f8c 100644 --- a/boards/arm/acn52832/acn52832_defconfig +++ b/boards/arm/acn52832/acn52832_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Enable P0_21 as RST -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts index 5024f43fd81..284a4d24542 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts @@ -61,6 +61,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig index 8d892db30f2..1f42d1a0aa4 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts index 6e827388aef..103e18d8328 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts @@ -55,6 +55,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig index bc27efcdd29..e5a88c27fb3 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig @@ -17,8 +17,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y CONFIG_PINCTRL=y # Flashing diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi index 60c0d63920c..200db7f94c7 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi @@ -177,6 +177,10 @@ arduino_spi: &spi2 { pinctrl-names = "default", "sleep"; }; +&uicr { + gpio-as-nreset; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig index 2d91725aaf9..dcdc0c8a836 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig @@ -20,7 +20,4 @@ CONFIG_UART_CONSOLE=y CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig index 8ef8ece861c..4604c6bf386 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig @@ -20,7 +20,4 @@ CONFIG_UART_CONSOLE=y CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts index ada4c76441c..2329853a1a3 100644 --- a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts +++ b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts @@ -45,6 +45,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig index 396d37d36e0..c2f2b95cc72 100644 --- a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig +++ b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig @@ -18,8 +18,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # enable pin controller CONFIG_PINCTRL=y diff --git a/boards/arm/bl652_dvk/bl652_dvk.dts b/boards/arm/bl652_dvk/bl652_dvk.dts index 5569f1323c0..f2cffbd819b 100644 --- a/boards/arm/bl652_dvk/bl652_dvk.dts +++ b/boards/arm/bl652_dvk/bl652_dvk.dts @@ -68,6 +68,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/bl652_dvk/bl652_dvk_defconfig b/boards/arm/bl652_dvk/bl652_dvk_defconfig index 1ca971e2546..5302fa8d53f 100644 --- a/boards/arm/bl652_dvk/bl652_dvk_defconfig +++ b/boards/arm/bl652_dvk/bl652_dvk_defconfig @@ -21,9 +21,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl653_dvk/bl653_dvk.dts b/boards/arm/bl653_dvk/bl653_dvk.dts index ceb91aeb96f..ba8fa3658d2 100644 --- a/boards/arm/bl653_dvk/bl653_dvk.dts +++ b/boards/arm/bl653_dvk/bl653_dvk.dts @@ -91,6 +91,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/bl653_dvk/bl653_dvk_defconfig b/boards/arm/bl653_dvk/bl653_dvk_defconfig index 4933055c93c..83b73ef4435 100644 --- a/boards/arm/bl653_dvk/bl653_dvk_defconfig +++ b/boards/arm/bl653_dvk/bl653_dvk_defconfig @@ -20,9 +20,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl654_dvk/bl654_dvk.dts b/boards/arm/bl654_dvk/bl654_dvk.dts index b99435696d1..7ede69427de 100644 --- a/boards/arm/bl654_dvk/bl654_dvk.dts +++ b/boards/arm/bl654_dvk/bl654_dvk.dts @@ -91,6 +91,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/bl654_dvk/bl654_dvk_defconfig b/boards/arm/bl654_dvk/bl654_dvk_defconfig index aa2238cda87..976495f7e88 100644 --- a/boards/arm/bl654_dvk/bl654_dvk_defconfig +++ b/boards/arm/bl654_dvk/bl654_dvk_defconfig @@ -21,9 +21,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board.dts b/boards/arm/bl654_sensor_board/bl654_sensor_board.dts index 1c2949ee2e8..c43354f2705 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board.dts +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board.dts @@ -56,6 +56,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig index 259fac9d309..e92c2c4005f 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig @@ -17,9 +17,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/bl654_usb/bl654_usb.dts b/boards/arm/bl654_usb/bl654_usb.dts index 2cc6850a468..80600290dbf 100644 --- a/boards/arm/bl654_usb/bl654_usb.dts +++ b/boards/arm/bl654_usb/bl654_usb.dts @@ -47,6 +47,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/bl654_usb/bl654_usb_defconfig b/boards/arm/bl654_usb/bl654_usb_defconfig index 59c26ddb4d7..983150c35d9 100644 --- a/boards/arm/bl654_usb/bl654_usb_defconfig +++ b/boards/arm/bl654_usb/bl654_usb_defconfig @@ -19,9 +19,6 @@ CONFIG_GPIO=y # Enable USB CONFIG_USB_DEVICE_STACK=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts index cf7dd7a52de..4c49979bb0a 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts @@ -48,6 +48,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status ="okay"; }; diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig index 52f089ba0d6..301a23af362 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig @@ -24,7 +24,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/bt510/bt510.dts b/boards/arm/bt510/bt510.dts index 74818be0d7c..984b098e5d5 100644 --- a/boards/arm/bt510/bt510.dts +++ b/boards/arm/bt510/bt510.dts @@ -72,6 +72,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/bt510/bt510_defconfig b/boards/arm/bt510/bt510_defconfig index fd86ea3f0f2..eb769cc9465 100644 --- a/boards/arm/bt510/bt510_defconfig +++ b/boards/arm/bt510/bt510_defconfig @@ -17,9 +17,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/bt610/bt610.dts b/boards/arm/bt610/bt610.dts index 6bbe8d57fe3..489401a5fb3 100644 --- a/boards/arm/bt610/bt610.dts +++ b/boards/arm/bt610/bt610.dts @@ -145,6 +145,7 @@ &uicr { nfct-pins-as-gpios; + gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/bt610/bt610_defconfig b/boards/arm/bt610/bt610_defconfig index 1c77ed9e37b..d1d7226fade 100644 --- a/boards/arm/bt610/bt610_defconfig +++ b/boards/arm/bt610/bt610_defconfig @@ -17,9 +17,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts index ebc866afeff..6f60b1ddfed 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts @@ -25,6 +25,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig index bb841469339..7a3055b9c82 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig @@ -20,7 +20,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts index 75510faf4a6..a1c415fc299 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts @@ -84,6 +84,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig index 89d31bfd45b..4cb6022e7ae 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig @@ -21,7 +21,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/degu_evk/degu_evk.dts b/boards/arm/degu_evk/degu_evk.dts index caa134752e0..eb3329726e9 100644 --- a/boards/arm/degu_evk/degu_evk.dts +++ b/boards/arm/degu_evk/degu_evk.dts @@ -92,6 +92,10 @@ status ="okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status ="okay"; }; diff --git a/boards/arm/degu_evk/degu_evk_defconfig b/boards/arm/degu_evk/degu_evk_defconfig index 7b9d7737481..e003438c3dc 100644 --- a/boards/arm/degu_evk/degu_evk_defconfig +++ b/boards/arm/degu_evk/degu_evk_defconfig @@ -17,7 +17,6 @@ CONFIG_USB_DEVICE_STACK=y # additional board options CONFIG_GPIO=y -CONFIG_GPIO_AS_PINRESET=y # required to enable 3V3 power rail and Vin1 monitor CONFIG_REGULATOR=y diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts index 9fa240cb5ae..31eb0cc7524 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts +++ b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts @@ -75,6 +75,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig index 3e1778de525..05acf2ca945 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig +++ b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/mg100/mg100.dts b/boards/arm/mg100/mg100.dts index 512ca901010..0d33fd32151 100644 --- a/boards/arm/mg100/mg100.dts +++ b/boards/arm/mg100/mg100.dts @@ -65,6 +65,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/mg100/mg100_defconfig b/boards/arm/mg100/mg100_defconfig index 93f55f3d0a4..bb7d09dabf2 100644 --- a/boards/arm/mg100/mg100_defconfig +++ b/boards/arm/mg100/mg100_defconfig @@ -18,9 +18,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts index 077eb4a1657..af0ea59794c 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts @@ -150,6 +150,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig index 56d8497b43a..af230adb18a 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts index 348a5b79745..c51002c6497 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts @@ -86,6 +86,10 @@ }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig index 2c283bda97e..8993b59f938 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts index f70d6649aa8..4942dd6daa0 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts @@ -99,6 +99,10 @@ clock-prescaler = <8>; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig index 9bbc4da98cb..9ef66860ab3 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts index 0d1725d5bbb..b488b5d1ff3 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts @@ -127,6 +127,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig index 7fe9f4e480c..9cbee72b2e7 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_blip/nrf52840_blip.dts b/boards/arm/nrf52840_blip/nrf52840_blip.dts index 112d22799bc..e641c60bd1f 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip.dts +++ b/boards/arm/nrf52840_blip/nrf52840_blip.dts @@ -66,6 +66,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig index 82c0146ecf1..811a88de939 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig +++ b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts index 0ed4addb069..2439b0c2aca 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts @@ -90,6 +90,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig index f0ed2a2fbad..e4c79a2bf88 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts index 8e835597c78..4e13783d656 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts @@ -89,6 +89,7 @@ &uicr { nfct-pins-as-gpios; + gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index 90850c10e0a..8701863e99a 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -13,7 +13,4 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts index acbb09d2df2..0a9d8ff4724 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts @@ -85,6 +85,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig index 0ad48d7f940..4a5e737cd14 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts index eb99beca22f..a53a174be15 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts @@ -97,6 +97,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig index 36553a757eb..2c6b7f2fc82 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig @@ -22,9 +22,6 @@ CONFIG_UART_CONSOLE=y # enable GPIO CONFIG_GPIO=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # Bluetooth not enabled by default on nRF52811 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index ba5d94738a6..96006ec4722 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -139,6 +139,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig index 100d91ed320..9f1232a8f0a 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts index 93b59baa920..dcf9fb690d1 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts @@ -101,6 +101,7 @@ &uicr { nfct-pins-as-gpios; + gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index 32a9d03b44e..c367a90d5ef 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -13,9 +13,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y # Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts index 4412d3c492d..c29ca8000dc 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts @@ -70,6 +70,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig index 42948633b2f..19aaa3825d1 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts index 618bd670ad1..60de01f0bb0 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts @@ -50,6 +50,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig index 944fc20b9c8..2a21dc07192 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Enable P0_21 as RST -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts b/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts index 8b276c5fed7..b622a1a23ea 100644 --- a/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts +++ b/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts @@ -49,6 +49,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig index 97f4efbc236..fac5419e6f6 100644 --- a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig +++ b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts index 29257e7a0b2..e0eaa911a06 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts @@ -89,6 +89,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig index 31571f10fb4..6e275e63f35 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig @@ -20,9 +20,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # Bluetooth not enabled by default on nRF52805 due to RAM limitations when # running the default set of kernel tests. diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts index 823a3db7f7e..4d4600f1222 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts @@ -91,6 +91,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig index 5873f1d2e9a..93706e89d0a 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig @@ -20,9 +20,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # Bluetooth not enabled by default on nRF52810 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts index 3002a1841c9..687bba9254a 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts @@ -138,6 +138,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig index 547ff67c348..23e1f4c249a 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts index c8cc706750c..07dc648b853 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts @@ -141,6 +141,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig index c15e39669ea..073409dbba1 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/pan1770_evb/pan1770_evb.dts b/boards/arm/pan1770_evb/pan1770_evb.dts index d8fbe8fe9df..2b2a9d561a7 100644 --- a/boards/arm/pan1770_evb/pan1770_evb.dts +++ b/boards/arm/pan1770_evb/pan1770_evb.dts @@ -137,6 +137,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1770_evb/pan1770_evb_defconfig b/boards/arm/pan1770_evb/pan1770_evb_defconfig index 1192aca064e..1d90cb82c25 100644 --- a/boards/arm/pan1770_evb/pan1770_evb_defconfig +++ b/boards/arm/pan1770_evb/pan1770_evb_defconfig @@ -26,8 +26,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1780_evb/pan1780_evb.dts b/boards/arm/pan1780_evb/pan1780_evb.dts index 4f4dbca98ac..da9a7e7fdb8 100644 --- a/boards/arm/pan1780_evb/pan1780_evb.dts +++ b/boards/arm/pan1780_evb/pan1780_evb.dts @@ -137,6 +137,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1780_evb/pan1780_evb_defconfig b/boards/arm/pan1780_evb/pan1780_evb_defconfig index 0c459f39aac..ca1a58c3b74 100644 --- a/boards/arm/pan1780_evb/pan1780_evb_defconfig +++ b/boards/arm/pan1780_evb/pan1780_evb_defconfig @@ -26,8 +26,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1781_evb/pan1781_evb.dts b/boards/arm/pan1781_evb/pan1781_evb.dts index 7d9b7028e35..8ab6af51ea9 100644 --- a/boards/arm/pan1781_evb/pan1781_evb.dts +++ b/boards/arm/pan1781_evb/pan1781_evb.dts @@ -98,6 +98,10 @@ clock-prescaler = <8>; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1781_evb/pan1781_evb_defconfig b/boards/arm/pan1781_evb/pan1781_evb_defconfig index 76436dd2ccd..dacffd42175 100644 --- a/boards/arm/pan1781_evb/pan1781_evb_defconfig +++ b/boards/arm/pan1781_evb/pan1781_evb_defconfig @@ -26,8 +26,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1782_evb/pan1782_evb.dts b/boards/arm/pan1782_evb/pan1782_evb.dts index cf169e41d87..fdc86f792ec 100644 --- a/boards/arm/pan1782_evb/pan1782_evb.dts +++ b/boards/arm/pan1782_evb/pan1782_evb.dts @@ -98,6 +98,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1782_evb/pan1782_evb_defconfig b/boards/arm/pan1782_evb/pan1782_evb_defconfig index 0bdeb9d9127..e6a6cc1d4a5 100644 --- a/boards/arm/pan1782_evb/pan1782_evb_defconfig +++ b/boards/arm/pan1782_evb/pan1782_evb_defconfig @@ -26,9 +26,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/particle_argon/particle_argon.dts b/boards/arm/particle_argon/particle_argon.dts index fa2314b6fb2..a88199fe40b 100644 --- a/boards/arm/particle_argon/particle_argon.dts +++ b/boards/arm/particle_argon/particle_argon.dts @@ -32,6 +32,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &uart1 { /* ESP32 */ compatible = "nordic,nrf-uarte"; current-speed = <921600>; diff --git a/boards/arm/particle_argon/particle_argon_defconfig b/boards/arm/particle_argon/particle_argon_defconfig index 784364e9edc..c29f62babd4 100644 --- a/boards/arm/particle_argon/particle_argon_defconfig +++ b/boards/arm/particle_argon/particle_argon_defconfig @@ -21,7 +21,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/particle_boron/particle_boron.dts b/boards/arm/particle_boron/particle_boron.dts index 3e20eddb94f..06e75a5a52e 100644 --- a/boards/arm/particle_boron/particle_boron.dts +++ b/boards/arm/particle_boron/particle_boron.dts @@ -36,6 +36,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &i2c1 { /* power monitoring */ compatible = "nordic,nrf-twi"; status = "okay"; diff --git a/boards/arm/particle_boron/particle_boron_defconfig b/boards/arm/particle_boron/particle_boron_defconfig index 6963e9d9393..622a3169073 100644 --- a/boards/arm/particle_boron/particle_boron_defconfig +++ b/boards/arm/particle_boron/particle_boron_defconfig @@ -20,9 +20,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y # Fix the priority to enable the modem line's serial buffer diff --git a/boards/arm/particle_xenon/particle_xenon.dts b/boards/arm/particle_xenon/particle_xenon.dts index 22252c077f3..2d64ba119b2 100644 --- a/boards/arm/particle_xenon/particle_xenon.dts +++ b/boards/arm/particle_xenon/particle_xenon.dts @@ -33,6 +33,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &uart1 { /* feather UART2 */ compatible = "nordic,nrf-uarte"; current-speed = <115200>; diff --git a/boards/arm/particle_xenon/particle_xenon_defconfig b/boards/arm/particle_xenon/particle_xenon_defconfig index 5f90beabba0..2495d886b41 100644 --- a/boards/arm/particle_xenon/particle_xenon_defconfig +++ b/boards/arm/particle_xenon/particle_xenon_defconfig @@ -20,7 +20,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts index fb377fd89e1..207c8934880 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts @@ -83,6 +83,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig index ad7442afe0d..fc8f45eceaa 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -13,7 +13,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# use P0.21 as RST -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts index 62664e67b5e..19f9e6ff41e 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts @@ -88,6 +88,10 @@ status ="okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status ="okay"; }; diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig index 7f11757ab5d..010c72e8c07 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig @@ -22,9 +22,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts index 43b2dd0de28..454c4bb84b1 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts @@ -48,6 +48,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig index 80da4e05041..4cc2863efab 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig @@ -22,7 +22,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts index 6a530e687f6..a3ada26e811 100644 --- a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts +++ b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts @@ -93,6 +93,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig index 7ed9a1ffe8b..1212ba8928f 100644 --- a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig +++ b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts index 2414b8ea517..bd1a2f06855 100644 --- a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts +++ b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts @@ -93,6 +93,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig index 973b83c9d62..438343c6d9b 100644 --- a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig +++ b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/dts/reel_board.dtsi b/boards/arm/reel_board/dts/reel_board.dtsi index 6289cf0ec6d..028a5d86a78 100644 --- a/boards/arm/reel_board/dts/reel_board.dtsi +++ b/boards/arm/reel_board/dts/reel_board.dtsi @@ -94,6 +94,10 @@ }; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/reel_board/reel_board_defconfig b/boards/arm/reel_board/reel_board_defconfig index 7ec7b36871b..850506692ba 100644 --- a/boards/arm/reel_board/reel_board_defconfig +++ b/boards/arm/reel_board/reel_board_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/reel_board_v2_defconfig b/boards/arm/reel_board/reel_board_v2_defconfig index a7f80f970e8..2ac0610f78c 100644 --- a/boards/arm/reel_board/reel_board_v2_defconfig +++ b/boards/arm/reel_board/reel_board_v2_defconfig @@ -17,7 +17,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts index a248d8f650e..9594b760488 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts @@ -137,6 +137,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig index 769e28f5846..801393790fe 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig @@ -23,7 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts index 5afd4960694..c65221eb38c 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts @@ -137,6 +137,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig index 6fd69454784..4f8a5c5a8da 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts index f7fbee05909..070730c69d2 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts @@ -136,6 +136,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig index 4a1d3a6075c..37271c2ce81 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts index 2db4e005b04..68b3755123b 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts @@ -152,6 +152,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig index 6a6d80f1b2b..4a35f6e612f 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts index 842c882ac7f..5b8679cc065 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts @@ -137,6 +137,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig index b2996dba82d..7a63bc69bf2 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts index 1c4623b52fe..d7a21c98b44 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts @@ -97,6 +97,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig index d0a583edbe8..c20dc6fe9f3 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig @@ -27,7 +27,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts index b183b17bc41..2c0f051d25f 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts @@ -133,6 +133,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig index 4a289cc2597..93127beefef 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts index 691705b3a91..849c96c5e6f 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts @@ -133,6 +133,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig index b7064633b25..b44e54e3d18 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts index 19b4e25a5af..5e15c5cc232 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts @@ -129,6 +129,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig index ca03d00a8e7..f9cabe94b4a 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts index 783d69b4788..521f9f6aa9e 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts @@ -134,6 +134,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig index 96d99738526..c06ad795868 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig @@ -26,7 +26,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts index b9b9bfcedb2..4d7c3d8cc0b 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts @@ -61,6 +61,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpio0 { status = "okay"; }; diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig index d1a44910ced..88c4ddb2023 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig @@ -21,9 +21,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Additional board options -CONFIG_GPIO_AS_PINRESET=y - # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts index 4cd193c4162..ef7eede1f75 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts @@ -56,6 +56,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig index ab2356cf412..249c4a8e394 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig @@ -24,9 +24,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts index 4c64bcaa4d0..62cecf7066e 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts @@ -57,6 +57,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig index b232a355e40..cca27094e6a 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig @@ -24,9 +24,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/xiao_ble/xiao_ble_common.dtsi b/boards/arm/xiao_ble/xiao_ble_common.dtsi index 588f381868a..d031ce4b5b3 100644 --- a/boards/arm/xiao_ble/xiao_ble_common.dtsi +++ b/boards/arm/xiao_ble/xiao_ble_common.dtsi @@ -62,6 +62,10 @@ status = "okay"; }; +&uicr { + gpio-as-nreset; +}; + &gpiote { status = "okay"; }; diff --git a/boards/arm/xiao_ble/xiao_ble_defconfig b/boards/arm/xiao_ble/xiao_ble_defconfig index faef5befa1f..6b6aa3168ec 100644 --- a/boards/arm/xiao_ble/xiao_ble_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_defconfig @@ -29,7 +29,4 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y diff --git a/boards/arm/xiao_ble/xiao_ble_sense_defconfig b/boards/arm/xiao_ble/xiao_ble_sense_defconfig index f549e4173dc..269f6f7915b 100644 --- a/boards/arm/xiao_ble/xiao_ble_sense_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_sense_defconfig @@ -29,9 +29,6 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y -# additional board options -CONFIG_GPIO_AS_PINRESET=y - CONFIG_PINCTRL=y # required to enable LSM6DS3TR-C power From 5d6d6f5b65ca5696dd27d1c266d6eb4f257d7a45 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:37:32 +0200 Subject: [PATCH 0588/4498] boards: arm: nrf9160dk_nrf52840: use UICR gpio-as-nreset property Instead of the about to be deprecated GPIO_AS_PINRESET. Signed-off-by: Gerard Marull-Paretas --- boards/arm/nrf9160dk_nrf52840/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/nrf9160dk_nrf52840/board.c b/boards/arm/nrf9160dk_nrf52840/board.c index e01b8eb64e7..cdf00f8f3dd 100644 --- a/boards/arm/nrf9160dk_nrf52840/board.c +++ b/boards/arm/nrf9160dk_nrf52840/board.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_NRF9160DK_LOG_LEVEL); * exposes the nRESET function (P0.18 in nRF52840), there is no need to * provide any additional GPIO configuration for it. */ -#define RESET_INPUT_IS_PINRESET (IS_ENABLED(CONFIG_GPIO_AS_PINRESET) && \ +#define RESET_INPUT_IS_PINRESET (DT_PROP(DT_NODELABEL(uicr), gpio_as_nreset) && \ GET_PORT(reset_input, gpios, 0) == 0 && \ GET_PIN(reset_input, gpios, 0) == 18) #define USE_RESET_GPIO \ From efb8408ba2e9a2cb1de638441ec60de495ee0f0d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:02:25 +0200 Subject: [PATCH 0589/4498] soc: arm: nordic_nrf: nrf52: deprecate GPIO_AS_PINRESET In favor of devicetree property in the UICR node. Signed-off-by: Gerard Marull-Paretas --- soc/arm/nordic_nrf/nrf52/Kconfig.soc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index f1a337cbe12..517b4ce2baa 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -94,8 +94,15 @@ config SOC_DCDC_NRF52X_HV Enable nRF52 series System on Chip High Voltage DC/DC converter. config GPIO_AS_PINRESET - bool "GPIO as pin reset (reset button)" - default y + bool "[DEPRECATED] GPIO as pin reset (reset button)" + select DEPRECATED + help + This option is deprecated, use devicetree instead. Example + configuration: + + &uicr { + gpio-as-nreset; + }; config NRF_ENABLE_ICACHE bool "The instruction cache (I-Cache)" From c572228aa0fc157197207841250ca5e71696b05a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:38:09 +0200 Subject: [PATCH 0590/4498] boards: arm: nrf-based: remove redundant GPIO_AS_PINRESET=n Because the option is disabled by default now that it is deprecated. Signed-off-by: Gerard Marull-Paretas --- boards/arm/holyiot_yj16019/Kconfig.defconfig | 3 --- boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig | 4 ---- 2 files changed, 7 deletions(-) diff --git a/boards/arm/holyiot_yj16019/Kconfig.defconfig b/boards/arm/holyiot_yj16019/Kconfig.defconfig index 99373ad286a..de2d63ad7c8 100644 --- a/boards/arm/holyiot_yj16019/Kconfig.defconfig +++ b/boards/arm/holyiot_yj16019/Kconfig.defconfig @@ -8,9 +8,6 @@ if BOARD_HOLYIOT_YJ16019 config BOARD default "holyiot_yj16019" -config GPIO_AS_PINRESET - default n - config BT_CTLR default BT diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig index bd247788458..7e28dde8423 100644 --- a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig @@ -14,8 +14,4 @@ CONFIG_USE_SEGGER_RTT=y # Enable GPIO CONFIG_GPIO=y -# additional board options -# set y to disable R button -CONFIG_GPIO_AS_PINRESET=n - CONFIG_PINCTRL=y From 9019e468392a22e274282517a037c079ab1592c0 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 11:41:42 +0200 Subject: [PATCH 0591/4498] doc: migration-guide: inform about GPIO_AS_PINRESET deprecation In favor of the new devicetree 'gpio-as-nreset' property. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index c7135c0e21b..3106ed9c4ce 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -67,6 +67,17 @@ Recommended Changes nfct-pins-as-gpios; }; +* Nordic nRF based boards using :kconfig:option:`CONFIG_GPIO_AS_PINRESET` + to configure reset GPIO as nRESET, should instead set the new UICR + ``gpio-as-nreset`` property in devicetree. It can be set like this in the + board devicetree files: + + .. code-block:: devicetree + + &uicr { + gpio-as-nreset; + }; + Picolibc-related Changes ************************ From b961be53a0d76c781ddea532348bf3def31281d4 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Mon, 12 Jun 2023 10:25:41 +0200 Subject: [PATCH 0592/4498] scripts: tests: Handler Expansion of the tests related to handlers.py Achieves over 85% coverage. Implemented most of golowanow's suggestions. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_handlers.py | 1272 ++++++++++++++++++++++++ 1 file changed, 1272 insertions(+) create mode 100644 scripts/tests/twister/test_handlers.py diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py new file mode 100644 index 00000000000..24abf4912b5 --- /dev/null +++ b/scripts/tests/twister/test_handlers.py @@ -0,0 +1,1272 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for handlers.py classes' methods +""" + +import itertools +import mock +import os +import pytest +import signal +import subprocess + +from serial import SerialException + +import twisterlib.harness + +from twisterlib.error import TwisterException +from twisterlib.handlers import ( + Handler, + BinaryHandler, + DeviceHandler, + QEMUHandler +) + + +@pytest.fixture +def mocked_instance(tmp_path): + instance = mock.Mock() + + testsuite = mock.Mock() + type(testsuite).source_dir = mock.PropertyMock(return_value='') + instance.testsuite = testsuite + + build_dir = tmp_path / 'build_dir' + os.makedirs(build_dir) + type(instance).build_dir = mock.PropertyMock(return_value=str(build_dir)) + + platform = mock.Mock() + type(platform).binaries = mock.PropertyMock(return_value=[]) + instance.platform = platform + + type(instance.testsuite).timeout = mock.PropertyMock(return_value=60) + type(instance.platform).timeout_multiplier = mock.PropertyMock( + return_value=2 + ) + + instance.status = None + instance.reason = 'Unknown' + + return instance + + +@pytest.fixture +def faux_timer(): + class Counter: + def __init__(self): + self.t = 0 + + def time(self): + self.t += 1 + return self.t + + return Counter() + + +def test_handler_final_handle_actions(mocked_instance): + instance = mocked_instance + instance.testcases = [mock.Mock()] + + handler = Handler(mocked_instance) + handler.suite_name_check = True + + harness = twisterlib.harness.Test() + harness.state = mock.Mock() + harness.detected_suite_names = mock.Mock() + harness.matched_run_id = False + harness.run_id_exists = True + + handler_time = mock.Mock() + + handler._final_handle_actions(harness, handler_time) + + assert handler.instance.status == 'failed' + assert handler.instance.execution_time == handler_time + assert handler.instance.reason == 'RunID mismatch' + assert all(testcase.status == 'failed' for \ + testcase in handler.instance.testcases) + + handler.instance.reason = 'This reason shan\'t be changed.' + handler._final_handle_actions(harness, handler_time) + + assert handler.instance.reason == 'This reason shan\'t be changed.' + + +TESTDATA_1 = [ + (['dummy_testsuite_name'], False), + ([], True), + (['another_dummy_name', 'yet_another_dummy_name'], True), +] + + +@pytest.mark.parametrize( + 'detected_suite_names, should_be_called', + TESTDATA_1, + ids=['detected one expected', 'detected none', 'detected two unexpected'] +) +def test_handler_verify_ztest_suite_name( + mocked_instance, + detected_suite_names, + should_be_called +): + instance = mocked_instance + type(instance.testsuite).ztest_suite_names = ['dummy_testsuite_name'] + + harness_state = 'passed' + + handler_time = mock.Mock() + + with mock.patch.object(Handler, '_missing_suite_name') as _missing_mocked: + handler = Handler(instance) + handler._verify_ztest_suite_name( + harness_state, + detected_suite_names, + handler_time + ) + + if should_be_called: + _missing_mocked.assert_called_once() + else: + _missing_mocked.assert_not_called() + + +def test_handler_missing_suite_name(mocked_instance): + instance = mocked_instance + instance.testcases = [mock.Mock()] + + handler = Handler(mocked_instance) + handler.suite_name_check = True + + expected_suite_names = ['dummy_testsuite_name'] + + handler_time = mock.Mock() + + handler._missing_suite_name(expected_suite_names, handler_time) + + assert handler.instance.status == 'failed' + assert handler.instance.execution_time == handler_time + assert handler.instance.reason == 'Testsuite mismatch' + assert all( + testcase.status == 'failed' for testcase in handler.instance.testcases + ) + + +def test_handler_record(mocked_instance): + instance = mocked_instance + instance.testcases = [mock.Mock()] + + handler = Handler(instance) + handler.suite_name_check = True + + harness = twisterlib.harness.Test() + harness.recording = ['dummy recording'] + type(harness).fieldnames = mock.PropertyMock(return_value=[]) + + mock_writerow = mock.Mock() + mock_writer = mock.Mock(writerow=mock_writerow) + + with mock.patch( + 'builtins.open', + mock.mock_open(read_data='') + ) as mock_file, \ + mock.patch( + 'csv.writer', + mock.Mock(return_value=mock_writer) + ) as mock_writer_constructor: + handler.record(harness) + + mock_file.assert_called_with( + os.path.join(instance.build_dir, 'recording.csv'), + 'at' + ) + + mock_writer_constructor.assert_called_with( + mock_file(), + harness.fieldnames, + lineterminator=os.linesep + ) + + mock_writerow.assert_has_calls( + [mock.call(harness.fieldnames)] + \ + [mock.call(recording) for recording in harness.recording] + ) + + +def test_handler_terminate(mocked_instance): + def mock_kill_function(pid, sig): + if pid < 0: + raise ProcessLookupError + + instance = mocked_instance + + handler = Handler(instance) + + mock_process = mock.Mock() + mock_child1 = mock.Mock(pid=1) + mock_child2 = mock.Mock(pid=2) + mock_process.children = mock.Mock(return_value=[mock_child1, mock_child2]) + + mock_proc = mock.Mock(pid=0) + mock_proc.terminate = mock.Mock(return_value=None) + mock_proc.kill = mock.Mock(return_value=None) + + with mock.patch('psutil.Process', mock.Mock(return_value=mock_process)), \ + mock.patch( + 'os.kill', + mock.Mock(side_effect=mock_kill_function) + ) as mock_kill: + handler.terminate(mock_proc) + + assert handler.terminated + mock_proc.terminate.assert_called_once() + mock_proc.kill.assert_called_once() + mock_kill.assert_has_calls( + [mock.call(1, signal.SIGTERM), mock.call(2, signal.SIGTERM)] + ) + + mock_child_neg1 = mock.Mock(pid=-1) + mock_process.children = mock.Mock( + return_value=[mock_child_neg1, mock_child2] + ) + handler.terminated = False + mock_kill.reset_mock() + + handler.terminate(mock_proc) + + mock_kill.assert_has_calls( + [mock.call(-1, signal.SIGTERM), mock.call(2, signal.SIGTERM)] + ) + + +def test_binaryhandler_try_kill_process_by_pid(mocked_instance): + def mock_kill_function(pid, sig): + if pid < 0: + raise ProcessLookupError + + instance = mocked_instance + + handler = BinaryHandler(instance, 'build') + handler.pid_fn = os.path.join('dummy', 'path', 'to', 'pid.pid') + + with mock.patch( + 'os.kill', + mock.Mock(side_effect=mock_kill_function) + ) as mock_kill, \ + mock.patch('os.unlink', mock.Mock()) as mock_unlink: + with mock.patch('builtins.open', mock.mock_open(read_data='1')): + handler.try_kill_process_by_pid() + + mock_unlink.assert_called_once_with( + os.path.join('dummy', 'path', 'to', 'pid.pid') + ) + mock_kill.assert_called_once_with(1, signal.SIGKILL) + + mock_unlink.reset_mock() + mock_kill.reset_mock() + handler.pid_fn = os.path.join('dummy', 'path', 'to', 'pid.pid') + + with mock.patch('builtins.open', mock.mock_open(read_data='-1')): + handler.try_kill_process_by_pid() + + mock_unlink.assert_called_once_with( + os.path.join('dummy', 'path', 'to', 'pid.pid') + ) + mock_kill.assert_called_once_with(-1, signal.SIGKILL) + + +TESTDATA_2 = [ + ( + [b'This\\r\\n', b'is\r', b'a short', b'file.'], + mock.Mock(state=False, capture_coverage=False), + [ + mock.call('This\\r\\n'), + mock.call('is\r'), + mock.call('a short'), + mock.call('file.') + ], + [ + mock.call('This'), + mock.call('is'), + mock.call('a short'), + mock.call('file.') + ], + None + ), + ( + [b'Too much.'] * 120, # Should be more than the timeout + mock.Mock(state=False, capture_coverage=False), + None, + None, + True + ), + ( + [b'Too much.'] * 120, # Should be more than the timeout + mock.Mock(state=True, capture_coverage=False), + None, + None, + True + ), + ( + [b'Too much.'] * 120, # Should be more than the timeout + mock.Mock(state=True, capture_coverage=True), + None, + None, + False + ), +] + + +@pytest.mark.parametrize( + 'proc_stdout, harness, expected_handler_calls,' + ' expected_harness_calls, should_be_less', + TESTDATA_2, + ids=[ + 'no timeout', + 'timeout', + 'timeout with harness state', + 'timeout with capture_coverage' + ] +) +def test_binaryhandler_output_handler( + mocked_instance, + faux_timer, + proc_stdout, + harness, + expected_handler_calls, + expected_harness_calls, + should_be_less +): + class MockStdout(mock.Mock): + def __init__(self, text): + super().__init__(text) + self.text = text + self.line_index = 0 + + def readline(self): + if self.line_index == len(self.text): + self.line_index = 0 + return b'' + else: + line = self.text[self.line_index] + self.line_index += 1 + return line + + class MockProc(mock.Mock): + def __init__(self, pid, stdout): + super().__init__(pid, stdout) + self.pid = mock.PropertyMock(return_value=pid) + self.stdout = MockStdout(stdout) + + handler = BinaryHandler(mocked_instance, 'build') + + proc = MockProc(1, proc_stdout) + proc.wait = mock.Mock(return_value = None) + + with mock.patch( + 'builtins.open', + mock.mock_open(read_data='') + ) as mock_file, \ + mock.patch('time.time', mock.Mock(side_effect=faux_timer.time)): + handler._output_handler(proc, harness) + + mock_file.assert_called_with(handler.log, 'wt') + + if expected_handler_calls: + mock_file.return_value.write.assert_has_calls(expected_handler_calls) + if expected_harness_calls: + harness.handle.assert_has_calls(expected_harness_calls) + if should_be_less is not None: + if should_be_less: + assert mock_file.return_value.write.call_count < len(proc_stdout) + else: + assert mock_file.return_value.write.call_count == len(proc_stdout) + + +TESTDATA_3 = [ + ( + { + 'call_make_run': False, + 'call_west_flash': False, + 'options': mock.Mock( + enable_valgrind=True, + enable_asan=True, + enable_lsan=True, + enable_ubsan=True, + coverage=True + ), + }, + mock.Mock(is_robot_test=True), + False, + 1, + 'success', + ['generator_cmd', 'run_renode_test', 'valgrind'] + ), + ( + { + 'call_make_run': True, + 'call_west_flash': False, + 'seed': 0, + 'options': mock.Mock( + enable_valgrind=True, + enable_asan=True, + enable_lsan=False, + enable_ubsan=True, + coverage=False + ), + }, + mock.Mock(is_robot_test=False), + False, + 2, + 'success', + ['generator_cmd', 'run', '--seed=0'] + ), + ( + { + 'call_make_run': False, + 'call_west_flash': True, + 'extra_test_args': ['extra_arg'], + 'options': mock.Mock( + enable_valgrind=True, + enable_asan=False, + enable_lsan=False, + enable_ubsan=False, + coverage=True + ), + }, + mock.Mock(is_robot_test=False), + False, + 1, + 'failed', + ['west', 'flash', 'extra_arg'] + ), + ( + { + 'call_make_run': False, + 'call_west_flash': False, + 'extra_test_args': None, + 'options': mock.Mock( + enable_valgrind=False, + enable_asan=False, + enable_lsan=False, + enable_ubsan=True, + coverage=False + ), + }, + mock.Mock(is_robot_test=False), + True, + 0, + 'failed', + ['binary'] + ), + ( + { + 'call_make_run': False, + 'call_west_flash': False, + 'extra_test_args': None, + 'options': mock.Mock( + enable_valgrind=False, + enable_asan=False, + enable_lsan=False, + enable_ubsan=True, + coverage=False + ), + }, + mock.Mock(is_robot_test=False), + True, + 0, + 'passed', + ['binary'] + ), + ( + { + 'call_make_run': False, + 'call_west_flash': False, + 'extra_test_args': None, + 'options': mock.Mock( + enable_valgrind=False, + enable_asan=False, + enable_lsan=False, + enable_ubsan=True, + coverage=False + ), + }, + mock.Mock(is_robot_test=False), + True, + 0, + None, + ['binary'] + ) +] + +@pytest.mark.parametrize( + 'handler_attrs, harness, isatty, return_code, harness_state, expected', + TESTDATA_3, + ids=[ + 'robot_test, valgrind, asan, lsan, ubsan, coverage,' \ + ' harness_state=success, return_code=1', + 'make_run, valgrind, asan, ubsan, seed,' \ + ' harness_state=success, return_code=2', + 'west_flash, valgrind, coverage, extra_args,' \ + ' harness_state=failed, return_code=1', + 'binary, ubsan, isatty, harness_state=failed', + 'binary, ubsan, isatty, harness_state=passed', + 'binary, ubsan, isatty, harness_state=None' + ] +) +def test_binaryhandler_handle( + mocked_instance, + handler_attrs, + harness, + isatty, + return_code, + harness_state, + expected +): + def assert_run_robot_test(command, handler): + assert all(w in command for w in expected) + + def assert_popen(command, *args, **kwargs,): + assert all(w in command for w in expected) + return mock.Mock( + __enter__=mock.Mock( + return_value=mock.Mock(pid=0, returncode=return_code) + ), + __exit__=mock.Mock(return_value=None) + ) + + def mock_isatty(): + return isatty + + def assert_calls(command, *args, **kwargs): + if handler_attrs['options'].coverage and 'gcov' in command: + return + elif mock_isatty() and 'stty' in command: + return + assert False + + def mock_thread(target=None, args=None, daemon=None): + harness.state = harness_state + return mock.Mock() + + handler = BinaryHandler(mocked_instance, 'build') + handler.generator_cmd = 'generator_cmd' + handler.binary = 'binary' + handler.extra_test_args = handler_attrs.get( + 'extra_test_args', + handler.extra_test_args + ) + handler.seed = handler_attrs.get('seed', handler.seed) + handler.call_make_run = handler_attrs.get( + 'call_make_run', + handler.call_make_run + ) + handler.call_west_flash = handler_attrs.get( + 'call_west_flash', + handler.call_west_flash + ) + handler.options = handler_attrs.get('options', handler.options) + + mock_popen = mock.Mock(side_effect=assert_popen) + mock_call = mock.Mock(side_effect=assert_calls) + + with mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)), \ + mock.patch.object( + BinaryHandler, + '_final_handle_actions', + lambda s, h, ht: None + ), \ + mock.patch.object(BinaryHandler, 'terminate', lambda s, p: None), \ + mock.patch.object( + twisterlib.harness.Robot, + 'run_robot_test', + assert_run_robot_test + ), \ + mock.patch('subprocess.Popen', mock_popen), \ + mock.patch('subprocess.call', mock_call), \ + mock.patch('sys.stdout.isatty', mock.Mock(side_effect=mock_isatty)): + handler.handle(harness) + + if handler.returncode == 0 and harness.state and harness.state != 'failed': + assert handler.instance.status != 'failed' + else: + assert handler.instance.status == 'failed' + + assert harness.run_robot_test.called or mock_popen.called + +TESTDATA_4 = [ + (3, 2, 0, 0, 3, -1, True, False, False, 1), + (4, 1, 0, 0, -1, -1, False, True, False, 0), + (5, 0, 1, 2, -1, 4, False, False, True, 3) +] + +@pytest.mark.parametrize( + 'success_count, in_waiting_count, oserror_count, readline_error_count,' + ' haltless_count, stateless_count, end_by_halt, end_by_close,' + ' end_by_state, expected_line_count', + TESTDATA_4, + ids=[ + 'halt event', + 'serial closes', + 'harness state with errors' + ] +) +def test_devicehandler_monitor_serial( + mocked_instance, + success_count, + in_waiting_count, + oserror_count, + readline_error_count, + haltless_count, + stateless_count, + end_by_halt, + end_by_close, + end_by_state, + expected_line_count +): + is_open_iter = iter(lambda: True, False) + line_iter = [ + TypeError('dummy TypeError') if x % 2 else \ + SerialException('dummy SerialException') for x in range( + readline_error_count + ) + ] + [ + f'line no {idx}'.encode('utf-8') for idx in range(success_count) + ] + in_waiting_iter = [False] * in_waiting_count + [ + TypeError('dummy TypeError') + ] if end_by_close else ( + [OSError('dummy OSError')] * oserror_count + [False] * in_waiting_count + ) + [True] * (success_count + readline_error_count) + + is_set_iter = [False] * haltless_count + [True] \ + if end_by_halt else iter(lambda: False, True) + + state_iter = [False] * stateless_count + [True] \ + if end_by_state else iter(lambda: False, True) + + halt_event = mock.Mock(is_set=mock.Mock(side_effect=is_set_iter)) + ser = mock.Mock( + isOpen=mock.Mock(side_effect=is_open_iter), + readline=mock.Mock(side_effect=line_iter) + ) + type(ser).in_waiting = mock.PropertyMock( + side_effect=in_waiting_iter, + return_value=False + ) + harness = mock.Mock(capture_coverage=False) + type(harness).state=mock.PropertyMock(side_effect=state_iter) + + handler = DeviceHandler(mocked_instance, 'build') + handler.options = mock.Mock(coverage=not end_by_state) + + with mock.patch('builtins.open', mock.mock_open(read_data='')): + handler.monitor_serial(ser, halt_event, harness) + + if not end_by_close: + ser.close.assert_called_once() + + harness.handle.assert_has_calls( + [mock.call(f'line no {idx}') for idx in range(expected_line_count)] + ) + + +TESTDATA_5 = [ + ( + 'dummy_platform', + 'dummy fixture', + [ + mock.Mock( + fixtures=[], + platform='dummy_platform', + available=1, + counter=0 + ), + mock.Mock( + fixtures=['dummy fixture'], + platform='another_platform', + available=1, + counter=0 + ), + mock.Mock( + fixtures=['dummy fixture'], + platform='dummy_platform', + serial_pty=None, + serial=None, + available=1, + counter=0 + ), + mock.Mock( + fixtures=['dummy fixture'], + platform='dummy_platform', + serial_pty=mock.Mock(), + available=1, + counter=0 + ) + ], + 3 + ), + ( + 'dummy_platform', + 'dummy fixture', + [], + TwisterException + ), + ( + 'dummy_platform', + 'dummy fixture', + [ + mock.Mock( + fixtures=['dummy fixture'], + platform='dummy_platform', + serial_pty=mock.Mock(), + available=0 + ), + mock.Mock( + fixtures=['another fixture'], + platform='dummy_platform', + serial_pty=mock.Mock(), + available=0 + ), + mock.Mock( + fixtures=['dummy fixture'], + platform='dummy_platform', + serial=mock.Mock(), + available=0 + ), + mock.Mock( + fixtures=['another fixture'], + platform='dummy_platform', + serial=mock.Mock(), + available=0 + ) + ], + None + ) +] + + +@pytest.mark.parametrize( + 'platform_name, fixture, duts, expected', + TESTDATA_5, + ids=['one good dut', 'exception - no duts', 'no available duts'] +) +def test_devicehandler_device_is_available( + mocked_instance, + platform_name, + fixture, + duts, + expected +): + mocked_instance.platform.name = platform_name + mocked_instance.testsuite.harness_config = {'fixture': fixture} + + handler = DeviceHandler(mocked_instance, 'build') + handler.duts = duts + + if isinstance(expected, int): + device = handler.device_is_available(mocked_instance) + + assert device == duts[expected] + assert device.available == 0 + assert device.counter == 1 + elif expected is None: + device = handler.device_is_available(mocked_instance) + + assert device is None + elif isinstance(expected, type): + with pytest.raises(expected): + device = handler.device_is_available(mocked_instance) + else: + assert False + + +def test_devicehandler_make_device_available(mocked_instance): + serial = mock.Mock(name='dummy_serial') + duts = [ + mock.Mock(available=0, serial=serial, serial_pty=None), + mock.Mock(available=0, serial=None, serial_pty=serial), + mock.Mock( + available=0, + serial=mock.Mock('another_serial'), + serial_pty=None + ) + ] + + handler = DeviceHandler(mocked_instance, 'build') + handler.duts = duts + + handler.make_device_available(serial) + + assert len([None for d in handler.duts if d.available == 1]) == 2 + assert handler.duts[2].available == 0 + + +TESTDATA_6 = [ + (mock.Mock(pid=0, returncode=0), False), + (mock.Mock(pid=0, returncode=1), False), + (mock.Mock(pid=0, returncode=1), True) +] + + +@pytest.mark.parametrize( + 'mock_process, raise_timeout', + TESTDATA_6, + ids=['proper script', 'error', 'timeout'] +) +def test_devicehandler_run_custom_script(caplog, mock_process, raise_timeout): + def raise_timeout_fn(timeout=-1): + if raise_timeout and timeout != -1: + raise subprocess.TimeoutExpired(None, timeout) + else: + return mock.Mock(), mock.Mock() + + def assert_popen(command, *args, **kwargs): + return mock.Mock( + __enter__=mock.Mock(return_value=mock_process), + __exit__=mock.Mock(return_value=None) + ) + + mock_process.communicate = mock.Mock(side_effect=raise_timeout_fn) + + script = [os.path.join('test','script', 'path'), 'arg'] + timeout = 60 + + with mock.patch('subprocess.Popen', mock.Mock(side_effect=assert_popen)): + DeviceHandler.run_custom_script(script, timeout) + + if raise_timeout: + assert all( + t in caplog.text.lower() for t in [str(script), 'timed out'] + ) + mock_process.assert_has_calls( + [ + mock.call.communicate(timeout=timeout), + mock.call.kill(), + mock.call.communicate() + ] + ) + elif mock_process.returncode == 0: + assert not any([r.levelname == 'ERROR' for r in caplog.records]) + else: + assert 'timed out' not in caplog.text.lower() + assert 'custom script failure' in caplog.text.lower() + + +TESTDATA_7 = [ + (0, False), + (4, False), + (0, True) +] + + +@pytest.mark.parametrize( + 'num_of_failures, raise_exception', + TESTDATA_7, + ids=['no failures', 'with failures', 'exception'] +) +def test_devicehandler_get_hardware( + mocked_instance, + caplog, + num_of_failures, + raise_exception +): + expected_hardware = mock.Mock() + + def mock_availability(handler, instance, no=num_of_failures): + if raise_exception: + raise TwisterException(f'dummy message') + if handler.no: + handler.no -= 1 + return None + return expected_hardware + + handler = DeviceHandler(mocked_instance, 'build') + handler.no = num_of_failures + + with mock.patch.object( + DeviceHandler, + 'device_is_available', + mock_availability + ): + hardware = handler.get_hardware() + + if raise_exception: + assert 'dummy message' in caplog.text.lower() + assert mocked_instance.status == 'failed' + assert mocked_instance.reason == 'dummy message' + else: + assert hardware == expected_hardware + + +TESTDATA_8 = [ + ('', '', None, None, False, ['generator_cmd']), + ( + 'pyocd', + 'product', + '--dummy-option-1,-do2', + [], + False, + [ + '--dummy-option-1', + '-do2', + '--runner', + 'pyocd', + '--dev-id', + 'board_id' + ] + ), + ( + 'openocd', + 'STM32 STLink', + [], + ['--dummy-option3'], + False, + [ + '--dummy-option3', + '--runner', + 'openocd', + '--cmd-pre-init', + 'hla_serial board_id' + ] + ), + ( + 'openocd', + 'STLINK-V3', + [], + [], + True, + ['--runner', 'openocd', '--cmd-pre-init', 'hla_serial board_id'] + ), + ( + 'openocd', + 'EDBG CMSIS-DAP', + [], + [], + False, + ['--runner', 'openocd', '--cmd-pre-init', 'cmsis_dap_serial board_id'] + ), + ( + 'jlink', + 'product', + [], + [], + False, + ['--runner', 'jlink', '--tool-opt=-SelectEmuBySN board_id'] + ), + ( + 'stm32cubeprogrammer', + 'product', + [], + [], + False, + ['--runner', 'stm32cubeprogrammer', '--tool-opt=sn=board_id'] + ), +] + + +@pytest.mark.parametrize( + 'runner, product, west_flash_options,' + ' runner_options, serial_not_pty, expected', + TESTDATA_8, + ids=[ + 'generator_cmd', + 'pyocd', + 'openocd, stm32 stlink', + 'openocd, stlink-v3', + 'openocd, edbg cmsis-dap', + 'jlink', + 'stm32cubeprogrammer' + ] +) +def test_devicehandler_handle( + mocked_instance, + runner, + product, + west_flash_options, + runner_options, + serial_not_pty, + expected +): + mock_process = mock.Mock(pid=0, returncode=0) + mock_process.communicate = mock.Mock( + return_value=(mock.Mock(), mock.Mock()) + ) + + def mock_popen(command, stdout=None, stdin=None, stderr=None): + if 'flash' in command: + assert all([c in command for c in expected]) + + return mock.Mock( + __enter__=mock.Mock(return_value=mock_process), + __exit__=mock.Mock(return_value=None), + communicate=mock.Mock(return_value=(mock.Mock(), mock.Mock())) + ) + + def mock_thread(target=None, daemon=None, args=None): + return mock.Mock() + + hardware_runner = runner + hardware_product = product + hardware_serial_pty = 'cmd1,| cmd2' if not serial_not_pty else None + hardware_serial = mock.Mock() + hardware_runner_params = runner_options + hardware_flash_timeout = 1 + hardware = mock.Mock( + product=hardware_product, + runner=hardware_runner, + serial=hardware_serial, + serial_pty=hardware_serial_pty, + runner_params=hardware_runner_params, + flash_timeout=hardware_flash_timeout, + probe_id='board_id' + ) + harness = mock.Mock() + handler_options_west_flash = west_flash_options + + handler = DeviceHandler(mocked_instance, 'build') + handler.options = mock.Mock( + west_flash=handler_options_west_flash, + west_runner=None + ) + handler.run_custom_script = mock.Mock(return_value=None) + handler.make_device_available = mock.Mock(return_value=None) + handler._final_handle_actions = mock.Mock(return_value=None) + handler.generator_cmd = 'generator_cmd' + + with mock.patch.object( + DeviceHandler, + 'get_hardware', + mock.Mock(return_value=hardware) + ), \ + mock.patch( + 'pty.openpty', + mock.Mock(return_value=(mock.Mock(), mock.Mock())) + ), \ + mock.patch('subprocess.Popen', mock.Mock(side_effect=mock_popen)), \ + mock.patch('os.ttyname', mock.Mock(return_value=mock.Mock())), \ + mock.patch('serial.Serial', mock.Mock(return_value=mock.Mock())), \ + mock.patch('builtins.open', mock.mock_open(read_data='')), \ + mock.patch('threading.Event', mock.Mock(return_value=mock.Mock())), \ + mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)): + handler.handle(harness) + + assert True + + +def test_qemuhandler_get_cpu_time(): + def mock_process(pid): + return mock.Mock( + cpu_times=mock.Mock( + return_value=mock.Mock( + user=20.0, + system=64.0 + ) + ) + ) + + with mock.patch('psutil.Process', mock_process): + res = QEMUHandler._get_cpu_time(0) + + assert res == pytest.approx(84.0) + + +TESTDATA_9 = [ + ( + ('1\n' * 60).encode('utf-8'), + 60, + 1, + [None] * 60 + ['success'] * 6, + 1000, + 'failed', + 'Timeout' + ), + ( + ('1\n' * 60).encode('utf-8'), + 60, + -1, + [None] * 60 + ['success'] * 30, + 100, + 'failed', + 'Failed' + ), + ( + b'', + 60, + 1, + ['success'] * 3, + 100, + 'failed', + 'unexpected eof' + ), + ( + b'\x81', + 60, + 1, + ['success'] * 3, + 100, + 'failed', + 'unexpected byte' + ), + ( + '1\n2\n3\n4\n5\n'.encode('utf-8'), + 600, + 1, + [None] * 3 + ['success'] * 7, + 100, + 'success', + 'Unknown' + ), +] + + +@pytest.mark.parametrize( + 'content, timeout, pid, harness_states, cputime,' + ' expected_instance_status, expected_instance_reason', + TESTDATA_9, + ids=[ + 'timeout', + 'harness failed', + 'unexpected eof', + 'unexpected byte', + 'harness success' + ] +) +def test_qemuhandler_thread( + mocked_instance, + faux_timer, + content, + timeout, + pid, + harness_states, + cputime, + expected_instance_status, + expected_instance_reason +): + def mock_cputime(pid): + if pid > 0: + return cputime + else: + raise ProcessLookupError() + + handler = QEMUHandler(mocked_instance, 'build') + handler.ignore_unexpected_eof=False + handler.results = {} + handler.pid_fn = 'pid_fn' + handler.fifo_fn = 'fifo_fn' + type(mocked_instance.testsuite).timeout = mock.PropertyMock( + return_value=timeout + ) + + def mocked_open(filename, *args, **kwargs): + if filename == handler.pid_fn: + contents = str(pid).encode('utf-8') + elif filename == handler.fifo_fn + '.out': + contents = content + else: + contents = b'' + + file_object = mock.mock_open(read_data=contents).return_value + file_object.__iter__.return_value = contents.splitlines(True) + return file_object + + harness = mock.Mock(capture_coverage=False) + type(harness).state = mock.PropertyMock(side_effect=harness_states) + + p = mock.Mock() + p.poll = mock.Mock( + side_effect=itertools.cycle([True, True, True, True, False]) + ) + + with mock.patch('time.time', mock.Mock(side_effect=faux_timer.time)), \ + mock.patch('builtins.open', new=mocked_open), \ + mock.patch('select.poll', mock.Mock(return_value=p)), \ + mock.patch('os.path.exists', mock.Mock(return_value=True)), \ + mock.patch('os.unlink', mock.Mock()), \ + mock.patch('os.mkfifo', mock.Mock()), \ + mock.patch('os.kill', mock.Mock()), \ + mock.patch.object(QEMUHandler, '_get_cpu_time', mock_cputime): + + QEMUHandler._thread( + handler, + handler.timeout, + handler.build_dir, + handler.log, + handler.fifo_fn, + handler.pid_fn, + handler.results, + harness, + handler.ignore_unexpected_eof + ) + + assert handler.instance.status == expected_instance_status + assert handler.instance.reason == expected_instance_reason + + +def test_qemuhandler_handle(mocked_instance, caplog, tmp_path): + mock_process = mock.Mock(pid=0, returncode=0) + mock_process.communicate = mock.Mock( + return_value=(mock.Mock(), mock.Mock()) + ) + + def mock_popen(command, stdout=None, stdin=None, stderr=None, cwd=None): + return mock.Mock( + __enter__=mock.Mock(return_value=mock_process), + __exit__=mock.Mock(return_value=None), + communicate=mock.Mock(return_value=(mock.Mock(), mock.Mock())) + ) + + def mock_thread(name=None, target=None, daemon=None, args=None): + return mock.Mock() + + mocked_domain = mock.Mock() + mocked_domain.get_default_domain = mock.Mock(return_value=mock.Mock()) + type(mocked_domain.get_default_domain()).build_dir = os.path.join( + tmp_path, + 'domain_build_dir' + ) + + hardware_flash_timeout = 1 + hardware = mock.Mock( + flash_timeout=hardware_flash_timeout, + probe_id='board_id' + ) + harness = mock.Mock() + handler_options_west_flash = [] + + handler = QEMUHandler(mocked_instance, 'build') + handler.options = mock.Mock( + west_flash=handler_options_west_flash, + west_runner=None + ) + handler.run_custom_script = mock.Mock(return_value=None) + handler.make_device_available = mock.Mock(return_value=None) + handler._final_handle_actions = mock.Mock(return_value=None) + handler.generator_cmd = 'generator_cmd' + + with mock.patch.object( + DeviceHandler, + 'get_hardware', + mock.Mock(return_value=hardware) + ), \ + mock.patch( + 'pty.openpty', + mock.Mock(return_value=(mock.Mock(), mock.Mock())) + ), \ + mock.patch('subprocess.Popen', mock.Mock(side_effect=mock_popen)), \ + mock.patch('os.ttyname', mock.Mock(return_value=mock.Mock())), \ + mock.patch('serial.Serial', mock.Mock(return_value=mock.Mock())), \ + mock.patch('builtins.open', mock.mock_open(read_data='')), \ + mock.patch('threading.Event', mock.Mock(return_value=mock.Mock())), \ + mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)), \ + mock.patch( + 'domains.Domains.from_file', + mock.Mock(return_value=mocked_domain) + ): + handler.handle(harness) + + assert caplog.records[-1].message == 'return code from QEMU (None):' \ + f' {mock_process.returncode}' + assert caplog.records[-1].levelname == 'DEBUG' From 2d3d22d66654985088710b49293dd1969498da7f Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Fri, 25 Aug 2023 09:07:13 +0200 Subject: [PATCH 0593/4498] scripts: pylib: twister: twisterlib: Handlers refactor Simple refactoring aiming to reduce the average method length. Minor corrections of the handlers module, removing wholly unused variables, etc. Signed-off-by: Lukasz Mrugala --- scripts/pylib/twister/twisterlib/handlers.py | 394 ++++++++++++------- 1 file changed, 242 insertions(+), 152 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index d9f1943e1c3..b5ba721a2fb 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -5,19 +5,20 @@ # Copyright 2022 NXP # SPDX-License-Identifier: Apache-2.0 -import math -import os -import sys import csv -import time -import signal import logging +import math +import os +import psutil +import re +import select import shlex +import signal import subprocess +import sys import threading -import select -import re -import psutil +import time + from twisterlib.environment import ZEPHYR_BASE from twisterlib.error import TwisterException sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/build_helpers")) @@ -223,10 +224,7 @@ def _output_handler(self, proc, harness): except subprocess.TimeoutExpired: self.terminate(proc) - def handle(self, harness): - - robot_test = getattr(harness, "is_robot_test", False) - + def _create_command(self, robot_test): if robot_test: command = [self.generator_cmd, "run_renode_test"] elif self.call_make_run: @@ -236,7 +234,6 @@ def handle(self, harness): else: command = [self.binary] - run_valgrind = False if self.options.enable_valgrind: command = ["valgrind", "--error-exitcode=2", "--leak-check=full", @@ -244,7 +241,6 @@ def handle(self, harness): "--log-file=" + self.build_dir + "/valgrind.log", "--track-origins=yes", ] + command - run_valgrind = True # Only valid for native_posix if self.seed is not None: @@ -252,12 +248,9 @@ def handle(self, harness): if self.extra_test_args is not None: command.extend(self.extra_test_args) - logger.debug("Spawning process: " + - " ".join(shlex.quote(word) for word in command) + os.linesep + - "in directory: " + self.build_dir) - - start_time = time.time() + return command + def _create_env(self): env = os.environ.copy() if self.options.enable_asan: env["ASAN_OPTIONS"] = "log_path=stdout:" + \ @@ -269,6 +262,40 @@ def handle(self, harness): env["UBSAN_OPTIONS"] = "log_path=stdout:halt_on_error=1:" + \ env.get("UBSAN_OPTIONS", "") + return env + + def _update_instance_info(self, harness_state, handler_time): + self.instance.execution_time = handler_time + if not self.terminated and self.returncode != 0: + self.instance.status = "failed" + if self.options.enable_valgrind and self.returncode == 2: + self.instance.reason = "Valgrind error" + else: + # When a process is killed, the default handler returns 128 + SIGTERM + # so in that case the return code itself is not meaningful + self.instance.reason = "Failed" + elif harness_state: + self.instance.status = harness_state + if harness_state == "failed": + self.instance.reason = "Failed" + else: + self.instance.status = "failed" + self.instance.reason = "Timeout" + self.instance.add_missing_case_status("blocked", "Timeout") + + def handle(self, harness): + robot_test = getattr(harness, "is_robot_test", False) + + command = self._create_command(robot_test) + + logger.debug("Spawning process: " + + " ".join(shlex.quote(word) for word in command) + os.linesep + + "in directory: " + self.build_dir) + + start_time = time.time() + + env = self._create_env() + if robot_test: harness.run_robot_test(command, self) return @@ -297,23 +324,7 @@ def handle(self, harness): if sys.stdout.isatty(): subprocess.call(["stty", "sane"], stdin=sys.stdout) - self.instance.execution_time = handler_time - if not self.terminated and self.returncode != 0: - self.instance.status = "failed" - if run_valgrind and self.returncode == 2: - self.instance.reason = "Valgrind error" - else: - # When a process is killed, the default handler returns 128 + SIGTERM - # so in that case the return code itself is not meaningful - self.instance.reason = "Failed" - elif harness.state: - self.instance.status = harness.state - if harness.state == "failed": - self.instance.reason = "Failed" - else: - self.instance.status = "failed" - self.instance.reason = "Timeout" - self.instance.add_missing_case_status("blocked", "Timeout") + self._update_instance_info(harness.state, handler_time) self._final_handle_actions(harness, handler_time) @@ -333,6 +344,7 @@ def __init__(self, instance, type_str): self.binary = os.path.join(instance.build_dir, "zephyr", "zephyr.exe") self.ready = True + class DeviceHandler(Handler): def __init__(self, instance, type_str): @@ -451,45 +463,7 @@ def run_custom_script(script, timeout): proc.communicate() logger.error("{} timed out".format(script)) - def get_hardware(self): - hardware = None - try: - hardware = self.device_is_available(self.instance) - while not hardware: - time.sleep(1) - hardware = self.device_is_available(self.instance) - except TwisterException as error: - self.instance.status = "failed" - self.instance.reason = str(error) - logger.error(self.instance.reason) - return hardware - - def handle(self, harness): - runner = None - hardware = self.get_hardware() - if hardware: - self.instance.dut = hardware.id - if not hardware: - return - - runner = hardware.runner or self.options.west_runner - serial_pty = hardware.serial_pty - - ser_pty_process = None - if serial_pty: - master, slave = pty.openpty() - try: - ser_pty_process = subprocess.Popen(re.split(',| ', serial_pty), stdout=master, stdin=master, stderr=master) - except subprocess.CalledProcessError as error: - logger.error("Failed to run subprocess {}, error {}".format(serial_pty, error.output)) - return - - serial_device = os.ttyname(slave) - else: - serial_device = hardware.serial - - logger.debug(f"Using serial device {serial_device} @ {hardware.baud} baud") - + def _create_command(self, runner, hardware): if (self.options.west_flash is not None) or runner: command = ["west", "flash", "--skip-rebuild", "-d", self.build_dir] command_extra_args = [] @@ -516,44 +490,50 @@ def handle(self, harness): command_extra_args.append(board_id) elif runner == "openocd" and product == "STM32 STLink": command_extra_args.append("--cmd-pre-init") - command_extra_args.append("hla_serial %s" % (board_id)) + command_extra_args.append("hla_serial %s" % board_id) elif runner == "openocd" and product == "STLINK-V3": command_extra_args.append("--cmd-pre-init") - command_extra_args.append("hla_serial %s" % (board_id)) + command_extra_args.append("hla_serial %s" % board_id) elif runner == "openocd" and product == "EDBG CMSIS-DAP": command_extra_args.append("--cmd-pre-init") - command_extra_args.append("cmsis_dap_serial %s" % (board_id)) + command_extra_args.append("cmsis_dap_serial %s" % board_id) elif runner == "jlink": - command.append("--tool-opt=-SelectEmuBySN %s" % (board_id)) + command.append("--tool-opt=-SelectEmuBySN %s" % board_id) elif runner == "stm32cubeprogrammer": - command.append("--tool-opt=sn=%s" % (board_id)) + command.append("--tool-opt=sn=%s" % board_id) # Receive parameters from runner_params field. if hardware.runner_params: for param in hardware.runner_params: command.append(param) - if command_extra_args != []: + if command_extra_args: command.append('--') command.extend(command_extra_args) else: command = [self.generator_cmd, "-C", self.build_dir, "flash"] - pre_script = hardware.pre_script - post_flash_script = hardware.post_flash_script - post_script = hardware.post_script + return command - if pre_script: - self.run_custom_script(pre_script, 30) + def _update_instance_info(self, harness_state, handler_time, flash_error): + self.instance.execution_time = handler_time + if harness_state: + self.instance.status = harness_state + if harness_state == "failed": + self.instance.reason = "Failed" + elif not flash_error: + self.instance.status = "failed" + self.instance.reason = "Timeout" - flash_timeout = hardware.flash_timeout - if hardware.flash_with_test: - flash_timeout += self.timeout + if self.instance.status in ["error", "failed"]: + self.instance.add_missing_case_status("blocked", self.instance.reason) + def _create_serial_connection(self, serial_device, hardware_baud, + flash_timeout, serial_pty, ser_pty_process): try: ser = serial.Serial( serial_device, - baudrate=hardware.baud, + baudrate=hardware_baud, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, @@ -574,6 +554,86 @@ def handle(self, harness): self.make_device_available(serial_pty) else: self.make_device_available(serial_device) + raise + + return ser + + def get_hardware(self): + hardware = None + try: + hardware = self.device_is_available(self.instance) + while not hardware: + time.sleep(1) + hardware = self.device_is_available(self.instance) + except TwisterException as error: + self.instance.status = "failed" + self.instance.reason = str(error) + logger.error(self.instance.reason) + return hardware + + def _get_serial_device(self, serial_pty, hardware_serial): + ser_pty_process = None + if serial_pty: + master, slave = pty.openpty() + try: + ser_pty_process = subprocess.Popen( + re.split('[, ]', serial_pty), + stdout=master, + stdin=master, + stderr=master + ) + except subprocess.CalledProcessError as error: + logger.error( + "Failed to run subprocess {}, error {}".format( + serial_pty, + error.output + ) + ) + return + + serial_device = os.ttyname(slave) + else: + serial_device = hardware_serial + + return serial_device, ser_pty_process + + def handle(self, harness): + runner = None + hardware = self.get_hardware() + if hardware: + self.instance.dut = hardware.id + if not hardware: + return + + runner = hardware.runner or self.options.west_runner + serial_pty = hardware.serial_pty + + serial_device, ser_pty_process = self._get_serial_device(serial_pty, hardware.serial) + + logger.debug(f"Using serial device {serial_device} @ {hardware.baud} baud") + + command = self._create_command(runner, hardware) + + pre_script = hardware.pre_script + post_flash_script = hardware.post_flash_script + post_script = hardware.post_script + + if pre_script: + self.run_custom_script(pre_script, 30) + + flash_timeout = hardware.flash_timeout + if hardware.flash_with_test: + flash_timeout += self.timeout + + try: + ser = self._create_serial_connection( + serial_device, + hardware.baud, + flash_timeout, + serial_pty, + ser_pty_process + ) + except serial.SerialException: return halt_monitor_evt = threading.Event() @@ -592,7 +652,7 @@ def handle(self, harness): try: (stdout, stderr) = proc.communicate(timeout=flash_timeout) # ignore unencodable unicode chars - logger.debug(stdout.decode(errors = "ignore")) + logger.debug(stdout.decode(errors="ignore")) if proc.returncode != 0: self.instance.status = "error" @@ -645,17 +705,7 @@ def handle(self, harness): handler_time = time.time() - start_time - self.instance.execution_time = handler_time - if harness.state: - self.instance.status = harness.state - if harness.state == "failed": - self.instance.reason = "Failed" - elif not flash_error: - self.instance.status = "failed" - self.instance.reason = "Timeout" - - if self.instance.status in ["error", "failed"]: - self.instance.add_missing_case_status("blocked", self.instance.reason) + self._update_instance_info(harness.state, handler_time, flash_error) self._final_handle_actions(harness, handler_time) @@ -667,6 +717,7 @@ def handle(self, harness): else: self.make_device_available(serial_device) + class QEMUHandler(Handler): """Spawns a thread to monitor QEMU output from pipes @@ -707,11 +758,14 @@ def _get_cpu_time(pid): return cpu_time.user + cpu_time.system @staticmethod - def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, harness, - ignore_unexpected_eof=False): + def _thread_get_fifo_names(fifo_fn): fifo_in = fifo_fn + ".in" fifo_out = fifo_fn + ".out" + return fifo_in, fifo_out + + @staticmethod + def _thread_open_files(fifo_in, fifo_out, logfile): # These in/out nodes are named from QEMU's perspective, not ours if os.path.exists(fifo_in): os.unlink(fifo_in) @@ -728,6 +782,51 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, harness in_fp = open(fifo_out, "rb", buffering=0) log_out_fp = open(logfile, "wt") + return out_fp, in_fp, log_out_fp + + @staticmethod + def _thread_close_files(fifo_in, fifo_out, pid, out_fp, in_fp, log_out_fp): + log_out_fp.close() + out_fp.close() + in_fp.close() + if pid: + try: + if pid: + os.kill(pid, signal.SIGTERM) + except ProcessLookupError: + # Oh well, as long as it's dead! User probably sent Ctrl-C + pass + + os.unlink(fifo_in) + os.unlink(fifo_out) + + @staticmethod + def _thread_update_instance_info(handler, handler_time, out_state): + handler.instance.execution_time = handler_time + if out_state == "timeout": + handler.instance.status = "failed" + handler.instance.reason = "Timeout" + elif out_state == "failed": + handler.instance.status = "failed" + handler.instance.reason = "Failed" + elif out_state in ['unexpected eof', 'unexpected byte']: + handler.instance.status = "failed" + handler.instance.reason = out_state + else: + handler.instance.status = out_state + handler.instance.reason = "Unknown" + + @staticmethod + def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, + harness, ignore_unexpected_eof=False): + fifo_in, fifo_out = QEMUHandler._thread_get_fifo_names(fifo_fn) + + out_fp, in_fp, log_out_fp = QEMUHandler._thread_open_files( + fifo_in, + fifo_out, + logfile + ) + start_time = time.time() timeout_time = start_time + timeout p = select.poll() @@ -746,9 +845,9 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, harness if this_timeout < 0 or not p.poll(this_timeout): try: if pid and this_timeout > 0: - #there's possibility we polled nothing because - #of not enough CPU time scheduled by host for - #QEMU process during p.poll(this_timeout) + # there's possibility we polled nothing because + # of not enough CPU time scheduled by host for + # QEMU process during p.poll(this_timeout) cpu_time = QEMUHandler._get_cpu_time(pid) if cpu_time < timeout and not out_state: timeout_time = time.time() + (timeout - cpu_time) @@ -810,62 +909,62 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, harness handler_time = time.time() - start_time logger.debug(f"QEMU ({pid}) complete ({out_state}) after {handler_time} seconds") - handler.instance.execution_time = handler_time - if out_state == "timeout": - handler.instance.status = "failed" - handler.instance.reason = "Timeout" - elif out_state == "failed": - handler.instance.status = "failed" - handler.instance.reason = "Failed" - elif out_state in ['unexpected eof', 'unexpected byte']: - handler.instance.status = "failed" - handler.instance.reason = out_state - else: - handler.instance.status = out_state - handler.instance.reason = "Unknown" - - log_out_fp.close() - out_fp.close() - in_fp.close() - if pid: - try: - if pid: - os.kill(pid, signal.SIGTERM) - except ProcessLookupError: - # Oh well, as long as it's dead! User probably sent Ctrl-C - pass - - os.unlink(fifo_in) - os.unlink(fifo_out) + QEMUHandler._thread_update_instance_info(handler, handler_time, out_state) - def handle(self, harness): - self.results = {} - self.run = True - - # We pass this to QEMU which looks for fifos with .in and .out - # suffixes. + QEMUHandler._thread_close_files(fifo_in, fifo_out, pid, out_fp, in_fp, log_out_fp) + def _get_sysbuild_build_dir(self): if self.instance.testsuite.sysbuild: # Load domain yaml to get default domain build directory # Note: for targets using QEMU, we assume that the target will # have added any additional images to the run target manually domain_path = os.path.join(self.build_dir, "domains.yaml") domains = Domains.from_file(domain_path) - logger.debug("Loaded sysbuild domain data from %s" % (domain_path)) + logger.debug("Loaded sysbuild domain data from %s" % domain_path) build_dir = domains.get_default_domain().build_dir else: build_dir = self.build_dir + return build_dir + + def _set_qemu_filenames(self, sysbuild_build_dir): + # We pass this to QEMU which looks for fifos with .in and .out suffixes. # QEMU fifo will use main build dir self.fifo_fn = os.path.join(self.instance.build_dir, "qemu-fifo") # PID file will be created in the main sysbuild app's build dir - self.pid_fn = os.path.join(build_dir, "qemu.pid") + self.pid_fn = os.path.join(sysbuild_build_dir, "qemu.pid") if os.path.exists(self.pid_fn): os.unlink(self.pid_fn) self.log_fn = self.log + def _create_command(self, sysbuild_build_dir): + command = [self.generator_cmd] + command += ["-C", sysbuild_build_dir, "run"] + + return command + + def _update_instance_info(self, harness_state, is_timeout): + if (self.returncode != 0 and not self.ignore_qemu_crash) or not harness_state: + self.instance.status = "failed" + if is_timeout: + self.instance.reason = "Timeout" + else: + if not self.instance.reason: + self.instance.reason = "Exited with {}".format(self.returncode) + self.instance.add_missing_case_status("blocked") + + def handle(self, harness): + self.results = {} + self.run = True + + sysbuild_build_dir = self._get_sysbuild_build_dir() + + command = self._create_command(sysbuild_build_dir) + + self._set_qemu_filenames(sysbuild_build_dir) + self.thread = threading.Thread(name=self.name, target=QEMUHandler._thread, args=(self, self.timeout, self.build_dir, self.log_fn, self.fifo_fn, @@ -879,8 +978,6 @@ def handle(self, harness): subprocess.call(["stty", "sane"], stdin=sys.stdout) logger.debug("Running %s (%s)" % (self.name, self.type_str)) - command = [self.generator_cmd] - command += ["-C", build_dir, "run"] is_timeout = False qemu_pid = None @@ -919,14 +1016,7 @@ def handle(self, harness): logger.debug(f"return code from QEMU ({qemu_pid}): {self.returncode}") - if (self.returncode != 0 and not self.ignore_qemu_crash) or not harness.state: - self.instance.status = "failed" - if is_timeout: - self.instance.reason = "Timeout" - else: - if not self.instance.reason: - self.instance.reason = "Exited with {}".format(self.returncode) - self.instance.add_missing_case_status("blocked") + self._update_instance_info(harness.state, is_timeout) self._final_handle_actions(harness, 0) From a0642b8538707f3084369d900c50afbad7b805b1 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Wed, 30 Aug 2023 13:16:25 +0200 Subject: [PATCH 0594/4498] scripts: tests: twister: Handlers test update post refactor After the handler.py module has been split up more, we can update the relevant tests. 100% coverage achieved. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_handlers.py | 1602 ++++++++++++++++++------ 1 file changed, 1200 insertions(+), 402 deletions(-) diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py index 24abf4912b5..ad08f56f112 100644 --- a/scripts/tests/twister/test_handlers.py +++ b/scripts/tests/twister/test_handlers.py @@ -12,17 +12,23 @@ import pytest import signal import subprocess +import sys +from contextlib import nullcontext +from importlib import reload from serial import SerialException +from subprocess import CalledProcessError, TimeoutExpired import twisterlib.harness +from conftest import ZEPHYR_BASE from twisterlib.error import TwisterException from twisterlib.handlers import ( Handler, BinaryHandler, DeviceHandler, - QEMUHandler + QEMUHandler, + SimulationHandler ) @@ -66,6 +72,51 @@ def time(self): return Counter() +TESTDATA_1 = [ + (True, False, 'posix', ['Install pyserial python module with pip to use' \ + ' --device-testing option.'], None), + (False, True, 'nt', [], None), + (True, True, 'posix', ['Install pyserial python module with pip to use' \ + ' --device-testing option.'], ImportError), +] + +@pytest.mark.parametrize( + 'fail_serial, fail_pty, os_name, expected_outs, expected_error', + TESTDATA_1, + ids=['import serial', 'import pty nt', 'import serial+pty posix'] +) +def test_imports( + capfd, + fail_serial, + fail_pty, + os_name, + expected_outs, + expected_error +): + class ImportRaiser: + def find_spec(self, fullname, path, target=None): + if fullname == 'serial' and fail_serial: + raise ImportError() + if fullname == 'pty' and fail_pty: + raise ImportError() + + modules_mock = sys.modules.copy() + modules_mock['serial'] = None if fail_serial else modules_mock['serial'] + modules_mock['pty'] = None if fail_pty else modules_mock['pty'] + + meta_path_mock = sys.meta_path[:] + meta_path_mock.insert(0, ImportRaiser()) + + with mock.patch('os.name', os_name), \ + mock.patch.dict('sys.modules', modules_mock, clear=True), \ + mock.patch('sys.meta_path', meta_path_mock), \ + pytest.raises(expected_error) if expected_error else nullcontext(): + reload(twisterlib.handlers) + + out, _ = capfd.readouterr() + assert all([expected_out in out for expected_out in expected_outs]) + + def test_handler_final_handle_actions(mocked_instance): instance = mocked_instance instance.testcases = [mock.Mock()] @@ -95,16 +146,15 @@ def test_handler_final_handle_actions(mocked_instance): assert handler.instance.reason == 'This reason shan\'t be changed.' -TESTDATA_1 = [ +TESTDATA_2 = [ (['dummy_testsuite_name'], False), ([], True), (['another_dummy_name', 'yet_another_dummy_name'], True), ] - @pytest.mark.parametrize( 'detected_suite_names, should_be_called', - TESTDATA_1, + TESTDATA_2, ids=['detected one expected', 'detected none', 'detected two unexpected'] ) def test_handler_verify_ztest_suite_name( @@ -213,7 +263,7 @@ def mock_kill_function(pid, sig): mock_proc.terminate = mock.Mock(return_value=None) mock_proc.kill = mock.Mock(return_value=None) - with mock.patch('psutil.Process', mock.Mock(return_value=mock_process)), \ + with mock.patch('psutil.Process', return_value=mock_process), \ mock.patch( 'os.kill', mock.Mock(side_effect=mock_kill_function) @@ -277,7 +327,7 @@ def mock_kill_function(pid, sig): mock_kill.assert_called_once_with(-1, signal.SIGKILL) -TESTDATA_2 = [ +TESTDATA_3 = [ ( [b'This\\r\\n', b'is\r', b'a short', b'file.'], mock.Mock(state=False, capture_coverage=False), @@ -293,41 +343,44 @@ def mock_kill_function(pid, sig): mock.call('a short'), mock.call('file.') ], - None + None, + False ), ( [b'Too much.'] * 120, # Should be more than the timeout mock.Mock(state=False, capture_coverage=False), None, None, - True + True, + False ), ( [b'Too much.'] * 120, # Should be more than the timeout mock.Mock(state=True, capture_coverage=False), None, None, - True + True, + False ), ( [b'Too much.'] * 120, # Should be more than the timeout mock.Mock(state=True, capture_coverage=True), None, None, - False + False, + True ), ] - @pytest.mark.parametrize( 'proc_stdout, harness, expected_handler_calls,' - ' expected_harness_calls, should_be_less', - TESTDATA_2, + ' expected_harness_calls, should_be_less, timeout_wait', + TESTDATA_3, ids=[ 'no timeout', 'timeout', 'timeout with harness state', - 'timeout with capture_coverage' + 'timeout with capture_coverage, wait timeout' ] ) def test_binaryhandler_output_handler( @@ -337,7 +390,8 @@ def test_binaryhandler_output_handler( harness, expected_handler_calls, expected_harness_calls, - should_be_less + should_be_less, + timeout_wait ): class MockStdout(mock.Mock): def __init__(self, text): @@ -360,16 +414,20 @@ def __init__(self, pid, stdout): self.pid = mock.PropertyMock(return_value=pid) self.stdout = MockStdout(stdout) + def wait(self, *args, **kwargs): + if timeout_wait: + raise TimeoutExpired('dummy cmd', 'dummyamount') + handler = BinaryHandler(mocked_instance, 'build') + handler.terminate = mock.Mock() proc = MockProc(1, proc_stdout) - proc.wait = mock.Mock(return_value = None) with mock.patch( 'builtins.open', mock.mock_open(read_data='') ) as mock_file, \ - mock.patch('time.time', mock.Mock(side_effect=faux_timer.time)): + mock.patch('time.time', side_effect=faux_timer.time): handler._output_handler(proc, harness) mock_file.assert_called_with(handler.log, 'wt') @@ -383,220 +441,253 @@ def __init__(self, pid, stdout): assert mock_file.return_value.write.call_count < len(proc_stdout) else: assert mock_file.return_value.write.call_count == len(proc_stdout) + if timeout_wait: + handler.terminate.assert_called_once_with(proc) -TESTDATA_3 = [ - ( - { - 'call_make_run': False, - 'call_west_flash': False, - 'options': mock.Mock( - enable_valgrind=True, - enable_asan=True, - enable_lsan=True, - enable_ubsan=True, - coverage=True - ), - }, - mock.Mock(is_robot_test=True), - False, - 1, - 'success', - ['generator_cmd', 'run_renode_test', 'valgrind'] - ), - ( - { - 'call_make_run': True, - 'call_west_flash': False, - 'seed': 0, - 'options': mock.Mock( - enable_valgrind=True, - enable_asan=True, - enable_lsan=False, - enable_ubsan=True, - coverage=False - ), - }, - mock.Mock(is_robot_test=False), - False, - 2, - 'success', - ['generator_cmd', 'run', '--seed=0'] - ), - ( - { - 'call_make_run': False, - 'call_west_flash': True, - 'extra_test_args': ['extra_arg'], - 'options': mock.Mock( - enable_valgrind=True, - enable_asan=False, - enable_lsan=False, - enable_ubsan=False, - coverage=True - ), - }, - mock.Mock(is_robot_test=False), - False, - 1, - 'failed', - ['west', 'flash', 'extra_arg'] - ), - ( - { - 'call_make_run': False, - 'call_west_flash': False, - 'extra_test_args': None, - 'options': mock.Mock( - enable_valgrind=False, - enable_asan=False, - enable_lsan=False, - enable_ubsan=True, - coverage=False - ), - }, - mock.Mock(is_robot_test=False), - True, - 0, - 'failed', - ['binary'] - ), - ( - { - 'call_make_run': False, - 'call_west_flash': False, - 'extra_test_args': None, - 'options': mock.Mock( - enable_valgrind=False, - enable_asan=False, - enable_lsan=False, - enable_ubsan=True, - coverage=False - ), - }, - mock.Mock(is_robot_test=False), - True, - 0, - 'passed', - ['binary'] - ), - ( - { - 'call_make_run': False, - 'call_west_flash': False, - 'extra_test_args': None, - 'options': mock.Mock( - enable_valgrind=False, - enable_asan=False, - enable_lsan=False, - enable_ubsan=True, - coverage=False - ), - }, - mock.Mock(is_robot_test=False), - True, - 0, - None, - ['binary'] +TESTDATA_4 = [ + (True, False, False, True, None, None, + ['valgrind', '--error-exitcode=2', '--leak-check=full', + f'--suppressions={ZEPHYR_BASE}/scripts/valgrind.supp', + '--log-file=build_dir/valgrind.log', '--track-origins=yes', + 'generator', 'run_renode_test']), + (False, True, False, False, 123, None, ['generator', 'run', '--seed=123']), + (False, False, True, False, None, None, + ['west', 'flash', '--skip-rebuild', '-d', 'build_dir']), + (False, False, False, False, None, ['ex1', 'ex2'], ['bin', 'ex1', 'ex2']), +] + +@pytest.mark.parametrize( + 'robot_test, call_make_run, call_west_flash, enable_valgrind, seed,' \ + ' extra_args, expected', + TESTDATA_4, + ids=['robot, valgrind', 'make run, seed', 'west flash', 'binary, extra'] +) +def test_binaryhandler_create_command( + mocked_instance, + robot_test, + call_make_run, + call_west_flash, + enable_valgrind, + seed, + extra_args, + expected +): + handler = BinaryHandler(mocked_instance, 'build') + handler.generator_cmd = 'generator' + handler.binary = 'bin' + handler.call_make_run = call_make_run + handler.call_west_flash = call_west_flash + handler.options = mock.Mock(enable_valgrind=enable_valgrind) + handler.seed = seed + handler.extra_test_args = extra_args + handler.build_dir = 'build_dir' + + command = handler._create_command(robot_test) + + assert command == expected + + +TESTDATA_5 = [ + (False, False, False), + (True, False, False), + (True, True, False), + (False, False, True), +] + +@pytest.mark.parametrize( + 'enable_asan, enable_lsan, enable_ubsan', + TESTDATA_5, + ids=['none', 'asan', 'asan, lsan', 'ubsan'] +) +def test_binaryhandler_create_env( + mocked_instance, + enable_asan, + enable_lsan, + enable_ubsan +): + handler = BinaryHandler(mocked_instance, 'build') + handler.options = mock.Mock( + enable_asan=enable_asan, + enable_lsan=enable_lsan, + enable_ubsan=enable_ubsan ) + + env = { + 'example_env_var': True, + 'ASAN_OPTIONS': 'dummy=dummy:', + 'UBSAN_OPTIONS': 'dummy=dummy:' + } + + with mock.patch('os.environ', env): + res = handler._create_env() + + assert env['example_env_var'] == res['example_env_var'] + + if enable_ubsan: + assert env['UBSAN_OPTIONS'] in res['UBSAN_OPTIONS'] + assert 'log_path=stdout:' in res['UBSAN_OPTIONS'] + assert 'halt_on_error=1:' in res['UBSAN_OPTIONS'] + + if enable_asan: + assert env['ASAN_OPTIONS'] in res['ASAN_OPTIONS'] + assert 'log_path=stdout:' in res['ASAN_OPTIONS'] + + if not enable_lsan: + assert 'detect_leaks=0' in res['ASAN_OPTIONS'] + + +TESTDATA_6 = [ + (None, False, 2, True, 'failed', 'Valgrind error', False), + (None, False, 1, False, 'failed', 'Failed', False), + ('failed', False, 0, False, 'failed', 'Failed', False), + ('success', False, 0, False, 'success', 'Unknown', False), + (None, True, 1, True, 'failed', 'Timeout', True), ] @pytest.mark.parametrize( - 'handler_attrs, harness, isatty, return_code, harness_state, expected', - TESTDATA_3, - ids=[ - 'robot_test, valgrind, asan, lsan, ubsan, coverage,' \ - ' harness_state=success, return_code=1', - 'make_run, valgrind, asan, ubsan, seed,' \ - ' harness_state=success, return_code=2', - 'west_flash, valgrind, coverage, extra_args,' \ - ' harness_state=failed, return_code=1', - 'binary, ubsan, isatty, harness_state=failed', - 'binary, ubsan, isatty, harness_state=passed', - 'binary, ubsan, isatty, harness_state=None' - ] + 'harness_state, terminated, returncode, enable_valgrind,' \ + ' expected_status, expected_reason, do_add_missing', + TESTDATA_6, + ids=['valgrind error', 'failed', 'harness failed', 'success', 'no state'] ) -def test_binaryhandler_handle( +def test_binaryhandler_update_instance_info( mocked_instance, - handler_attrs, - harness, - isatty, - return_code, harness_state, - expected + terminated, + returncode, + enable_valgrind, + expected_status, + expected_reason, + do_add_missing +): + handler = BinaryHandler(mocked_instance, 'build') + handler_time = 59 + handler.terminated = terminated + handler.returncode = returncode + handler.options = mock.Mock(enable_valgrind=enable_valgrind) + missing_mock = mock.Mock() + handler.instance.add_missing_case_status = missing_mock + + handler._update_instance_info(harness_state, handler_time) + + assert handler.instance.execution_time == handler_time + + assert handler.instance.status == expected_status + assert handler.instance.reason == expected_reason + + if do_add_missing: + missing_mock.assert_called_once_with('blocked', expected_reason) + + +TESTDATA_7 = [ + (True, False, False), + (False, True, False), + (False, False, True), +] + +@pytest.mark.parametrize( + 'is_robot_test, coverage, isatty', + TESTDATA_7, + ids=['robot test', 'coverage', 'isatty'] +) +def test_binaryhandler_handle( + mocked_instance, + caplog, + is_robot_test, + coverage, + isatty ): - def assert_run_robot_test(command, handler): - assert all(w in command for w in expected) + thread_mock_obj = mock.Mock() - def assert_popen(command, *args, **kwargs,): - assert all(w in command for w in expected) + def mock_popen(command, *args, **kwargs,): return mock.Mock( - __enter__=mock.Mock( - return_value=mock.Mock(pid=0, returncode=return_code) - ), + __enter__=mock.Mock(return_value=mock.Mock(pid=0, returncode=0)), __exit__=mock.Mock(return_value=None) ) - def mock_isatty(): - return isatty - - def assert_calls(command, *args, **kwargs): - if handler_attrs['options'].coverage and 'gcov' in command: - return - elif mock_isatty() and 'stty' in command: - return - assert False - - def mock_thread(target=None, args=None, daemon=None): - harness.state = harness_state - return mock.Mock() + def mock_thread(target, *args, **kwargs): + return thread_mock_obj handler = BinaryHandler(mocked_instance, 'build') - handler.generator_cmd = 'generator_cmd' - handler.binary = 'binary' - handler.extra_test_args = handler_attrs.get( - 'extra_test_args', - handler.extra_test_args - ) - handler.seed = handler_attrs.get('seed', handler.seed) - handler.call_make_run = handler_attrs.get( - 'call_make_run', - handler.call_make_run - ) - handler.call_west_flash = handler_attrs.get( - 'call_west_flash', - handler.call_west_flash - ) - handler.options = handler_attrs.get('options', handler.options) - - mock_popen = mock.Mock(side_effect=assert_popen) - mock_call = mock.Mock(side_effect=assert_calls) - - with mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)), \ - mock.patch.object( - BinaryHandler, - '_final_handle_actions', - lambda s, h, ht: None - ), \ - mock.patch.object(BinaryHandler, 'terminate', lambda s, p: None), \ - mock.patch.object( - twisterlib.harness.Robot, - 'run_robot_test', - assert_run_robot_test - ), \ - mock.patch('subprocess.Popen', mock_popen), \ - mock.patch('subprocess.call', mock_call), \ - mock.patch('sys.stdout.isatty', mock.Mock(side_effect=mock_isatty)): + handler.sourcedir = 'source_dir' + handler.build_dir = 'build_dir' + handler.name= 'Dummy Name' + handler._create_command = mock.Mock(return_value=['dummy' , 'command']) + handler._create_env = mock.Mock(return_value=[]) + handler._update_instance_info = mock.Mock() + handler._final_handle_actions = mock.Mock() + handler.terminate = mock.Mock() + handler.try_kill_process_by_pid = mock.Mock() + handler.options = mock.Mock(coverage=coverage) + + robot_mock = mock.Mock() + harness = mock.Mock(is_robot_test=is_robot_test, run_robot_test=robot_mock) + + popen_mock = mock.Mock(side_effect=mock_popen) + thread_mock = mock.Mock(side_effect=mock_thread) + call_mock = mock.Mock() + + with mock.patch('subprocess.call', call_mock), \ + mock.patch('subprocess.Popen', popen_mock), \ + mock.patch('threading.Thread', thread_mock), \ + mock.patch('sys.stdout.isatty', return_value=isatty): handler.handle(harness) - if handler.returncode == 0 and harness.state and harness.state != 'failed': - assert handler.instance.status != 'failed' - else: - assert handler.instance.status == 'failed' + if is_robot_test: + robot_mock.assert_called_once_with(['dummy', 'command'], mock.ANY) + return - assert harness.run_robot_test.called or mock_popen.called + assert 'Spawning BinaryHandler Thread for Dummy Name' in caplog.text -TESTDATA_4 = [ + thread_mock_obj.join.assert_called() + handler._update_instance_info.assert_called_once() + handler._final_handle_actions.assert_called_once() + + if coverage: + call_mock.assert_any_call( + ['GCOV_PREFIX=build_dir', 'gcov', 'source_dir', + '-b', '-s', 'build_dir'], + shell=True + ) + + if isatty: + call_mock.assert_any_call(['stty', 'sane'], stdin=mock.ANY) + + +TESTDATA_8 = [ + ('renode', True, True, False, False), + ('native', False, False, False, True), + ('build', False, True, False, False), +] + +@pytest.mark.parametrize( + 'type_str, is_pid_fn, expected_call_make_run, is_binary, expected_ready', + TESTDATA_8, + ids=[t[0] for t in TESTDATA_8] +) +def test_simulationhandler_init( + mocked_instance, + type_str, + is_pid_fn, + expected_call_make_run, + is_binary, + expected_ready +): + handler = SimulationHandler(mocked_instance, type_str) + + assert handler.call_make_run == expected_call_make_run + assert handler.ready == expected_ready + + if is_pid_fn: + assert handler.pid_fn == os.path.join(mocked_instance.build_dir, + 'renode.pid') + if is_binary: + assert handler.pid_fn == os.path.join(mocked_instance.build_dir, + 'zephyr', 'zephyr.exe') + + +TESTDATA_9 = [ (3, 2, 0, 0, 3, -1, True, False, False, 1), (4, 1, 0, 0, -1, -1, False, True, False, 0), (5, 0, 1, 2, -1, 4, False, False, True, 3) @@ -606,7 +697,7 @@ def mock_thread(target=None, args=None, daemon=None): 'success_count, in_waiting_count, oserror_count, readline_error_count,' ' haltless_count, stateless_count, end_by_halt, end_by_close,' ' end_by_state, expected_line_count', - TESTDATA_4, + TESTDATA_9, ids=[ 'halt event', 'serial closes', @@ -673,7 +764,7 @@ def test_devicehandler_monitor_serial( ) -TESTDATA_5 = [ +TESTDATA_10 = [ ( 'dummy_platform', 'dummy fixture', @@ -747,10 +838,9 @@ def test_devicehandler_monitor_serial( ) ] - @pytest.mark.parametrize( 'platform_name, fixture, duts, expected', - TESTDATA_5, + TESTDATA_10, ids=['one good dut', 'exception - no duts', 'no available duts'] ) def test_devicehandler_device_is_available( @@ -804,16 +894,15 @@ def test_devicehandler_make_device_available(mocked_instance): assert handler.duts[2].available == 0 -TESTDATA_6 = [ +TESTDATA_11 = [ (mock.Mock(pid=0, returncode=0), False), (mock.Mock(pid=0, returncode=1), False), (mock.Mock(pid=0, returncode=1), True) ] - @pytest.mark.parametrize( 'mock_process, raise_timeout', - TESTDATA_6, + TESTDATA_11, ids=['proper script', 'error', 'timeout'] ) def test_devicehandler_run_custom_script(caplog, mock_process, raise_timeout): @@ -834,7 +923,7 @@ def assert_popen(command, *args, **kwargs): script = [os.path.join('test','script', 'path'), 'arg'] timeout = 60 - with mock.patch('subprocess.Popen', mock.Mock(side_effect=assert_popen)): + with mock.patch('subprocess.Popen', side_effect=assert_popen): DeviceHandler.run_custom_script(script, timeout) if raise_timeout: @@ -855,16 +944,15 @@ def assert_popen(command, *args, **kwargs): assert 'custom script failure' in caplog.text.lower() -TESTDATA_7 = [ +TESTDATA_12 = [ (0, False), (4, False), (0, True) ] - @pytest.mark.parametrize( 'num_of_failures, raise_exception', - TESTDATA_7, + TESTDATA_12, ids=['no failures', 'with failures', 'exception'] ) def test_devicehandler_get_hardware( @@ -901,159 +989,469 @@ def mock_availability(handler, instance, no=num_of_failures): assert hardware == expected_hardware -TESTDATA_8 = [ - ('', '', None, None, False, ['generator_cmd']), +TESTDATA_13 = [ + ( + None, + None, + None, + ['generator_cmd', '-C', '$build_dir', 'flash'] + ), + ( + [], + None, + None, + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir'] + ), + ( + '--dummy', + None, + None, + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--', '--dummy'] + ), + ( + '--dummy1,--dummy2', + None, + None, + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--', '--dummy1', '--dummy2'] + ), + + ( + None, + 'runner', + 'product', + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'runner', 'param1', 'param2'] + ), + ( + None, 'pyocd', 'product', - '--dummy-option-1,-do2', - [], - False, - [ - '--dummy-option-1', - '-do2', - '--runner', - 'pyocd', - '--dev-id', - 'board_id' - ] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'pyocd', 'param1', 'param2', '--', '--dev-id', 12345] + ), + ( + None, + 'nrfjprog', + 'product', + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'nrfjprog', 'param1', 'param2', '--', '--dev-id', 12345] ), ( + None, 'openocd', 'STM32 STLink', - [], - ['--dummy-option3'], - False, - [ - '--dummy-option3', - '--runner', - 'openocd', - '--cmd-pre-init', - 'hla_serial board_id' - ] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'openocd', 'param1', 'param2', + '--', '--cmd-pre-init', 'hla_serial 12345'] ), ( + None, 'openocd', 'STLINK-V3', - [], - [], - True, - ['--runner', 'openocd', '--cmd-pre-init', 'hla_serial board_id'] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'openocd', 'param1', 'param2', + '--', '--cmd-pre-init', 'hla_serial 12345'] ), ( + None, 'openocd', 'EDBG CMSIS-DAP', - [], - [], - False, - ['--runner', 'openocd', '--cmd-pre-init', 'cmsis_dap_serial board_id'] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'openocd', 'param1', 'param2', + '--', '--cmd-pre-init', 'cmsis_dap_serial 12345'] ), ( + None, 'jlink', 'product', - [], - [], - False, - ['--runner', 'jlink', '--tool-opt=-SelectEmuBySN board_id'] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'jlink', '--tool-opt=-SelectEmuBySN 12345', # 2x space + 'param1', 'param2'] ), ( + None, 'stm32cubeprogrammer', 'product', - [], - [], - False, - ['--runner', 'stm32cubeprogrammer', '--tool-opt=sn=board_id'] + ['west', 'flash', '--skip-rebuild', '-d', '$build_dir', + '--runner', 'stm32cubeprogrammer', '--tool-opt=sn=12345', + 'param1', 'param2'] ), + ] +TESTDATA_13_2 = [(True), (False)] @pytest.mark.parametrize( - 'runner, product, west_flash_options,' - ' runner_options, serial_not_pty, expected', - TESTDATA_8, - ids=[ - 'generator_cmd', - 'pyocd', - 'openocd, stm32 stlink', - 'openocd, stlink-v3', - 'openocd, edbg cmsis-dap', - 'jlink', - 'stm32cubeprogrammer' - ] + 'self_west_flash, runner,' \ + ' hardware_product_name, expected', + TESTDATA_13, + ids=['generator', '--west-flash', 'one west flash value', + 'multiple west flash values', 'generic runner', 'pyocd', + 'nrfjprog', 'openocd, STM32 STLink', 'openocd, STLINK-v3', + 'openocd, EDBG CMSIS-DAP', 'jlink', 'stm32cubeprogrammer'] ) -def test_devicehandler_handle( +@pytest.mark.parametrize('hardware_probe', TESTDATA_13_2, ids=['probe', 'id']) +def test_devicehandler_create_command( mocked_instance, + self_west_flash, runner, - product, - west_flash_options, - runner_options, - serial_not_pty, + hardware_probe, + hardware_product_name, expected ): - mock_process = mock.Mock(pid=0, returncode=0) - mock_process.communicate = mock.Mock( - return_value=(mock.Mock(), mock.Mock()) - ) - - def mock_popen(command, stdout=None, stdin=None, stderr=None): - if 'flash' in command: - assert all([c in command for c in expected]) - - return mock.Mock( - __enter__=mock.Mock(return_value=mock_process), - __exit__=mock.Mock(return_value=None), - communicate=mock.Mock(return_value=(mock.Mock(), mock.Mock())) - ) + handler = DeviceHandler(mocked_instance, 'build') + handler.options = mock.Mock(west_flash=self_west_flash) + handler.generator_cmd = 'generator_cmd' - def mock_thread(target=None, daemon=None, args=None): - return mock.Mock() + expected = [handler.build_dir if val == '$build_dir' else \ + val for val in expected] - hardware_runner = runner - hardware_product = product - hardware_serial_pty = 'cmd1,| cmd2' if not serial_not_pty else None - hardware_serial = mock.Mock() - hardware_runner_params = runner_options - hardware_flash_timeout = 1 hardware = mock.Mock( - product=hardware_product, - runner=hardware_runner, - serial=hardware_serial, - serial_pty=hardware_serial_pty, - runner_params=hardware_runner_params, - flash_timeout=hardware_flash_timeout, - probe_id='board_id' + product=hardware_product_name, + probe_id=12345 if hardware_probe else None, + id=12345 if not hardware_probe else None, + runner_params=['param1', 'param2'] ) - harness = mock.Mock() - handler_options_west_flash = west_flash_options - handler = DeviceHandler(mocked_instance, 'build') - handler.options = mock.Mock( - west_flash=handler_options_west_flash, - west_runner=None - ) - handler.run_custom_script = mock.Mock(return_value=None) - handler.make_device_available = mock.Mock(return_value=None) - handler._final_handle_actions = mock.Mock(return_value=None) - handler.generator_cmd = 'generator_cmd' + command = handler._create_command(runner, hardware) - with mock.patch.object( - DeviceHandler, - 'get_hardware', - mock.Mock(return_value=hardware) - ), \ - mock.patch( - 'pty.openpty', - mock.Mock(return_value=(mock.Mock(), mock.Mock())) - ), \ - mock.patch('subprocess.Popen', mock.Mock(side_effect=mock_popen)), \ - mock.patch('os.ttyname', mock.Mock(return_value=mock.Mock())), \ - mock.patch('serial.Serial', mock.Mock(return_value=mock.Mock())), \ - mock.patch('builtins.open', mock.mock_open(read_data='')), \ - mock.patch('threading.Event', mock.Mock(return_value=mock.Mock())), \ - mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)): - handler.handle(harness) + assert command == expected - assert True + +TESTDATA_14 = [ + ('success', False, 'success', 'Unknown', False), + ('failed', False, 'failed', 'Failed', True), + ('error', False, 'error', 'Unknown', True), + (None, True, None, 'Unknown', False), + (None, False, 'failed', 'Timeout', True), +] + +@pytest.mark.parametrize( + 'harness_state, flash_error,' \ + ' expected_status, expected_reason, do_add_missing', + TESTDATA_14, + ids=['success', 'failed', 'error', 'flash error', 'no status'] +) +def test_devicehandler_update_instance_info( + mocked_instance, + harness_state, + flash_error, + expected_status, + expected_reason, + do_add_missing +): + handler = DeviceHandler(mocked_instance, 'build') + handler_time = 59 + missing_mock = mock.Mock() + handler.instance.add_missing_case_status = missing_mock + + handler._update_instance_info(harness_state, handler_time, flash_error) + + assert handler.instance.execution_time == handler_time + + assert handler.instance.status == expected_status + assert handler.instance.reason == expected_reason + + if do_add_missing: + missing_mock.assert_called_once_with('blocked', expected_reason) + + +TESTDATA_15 = [ + ('dummy device', 'dummy pty', None, None, True, False, False), + ( + 'dummy device', + 'dummy pty', + mock.Mock(communicate=mock.Mock(return_value=('', ''))), + SerialException, + False, + True, + 'dummy pty' + ), + ( + 'dummy device', + None, + None, + SerialException, + False, + False, + 'dummy device' + ) +] + +@pytest.mark.parametrize( + 'serial_device, serial_pty, ser_pty_process, expected_exception,' \ + ' expected_result, terminate_ser_pty_process, make_available', + TESTDATA_15, + ids=['valid', 'serial pty process', 'no serial pty'] +) +def test_devicehandler_create_serial_connection( + mocked_instance, + serial_device, + serial_pty, + ser_pty_process, + expected_exception, + expected_result, + terminate_ser_pty_process, + make_available +): + def mock_serial(*args, **kwargs): + if expected_exception: + raise expected_exception('') + return expected_result + + handler = DeviceHandler(mocked_instance, 'build') + handler.make_device_available = mock.Mock() + missing_mock = mock.Mock() + handler.instance.add_missing_case_status = missing_mock + available_mock = mock.Mock() + handler.make_device_available = available_mock + + hardware_baud = 14400 + flash_timeout = 60 + serial_mock = mock.Mock(side_effect=mock_serial) + + with mock.patch('serial.Serial', serial_mock), \ + pytest.raises(expected_exception) if expected_exception else \ + nullcontext(): + result = handler._create_serial_connection(serial_device, hardware_baud, + flash_timeout, serial_pty, + ser_pty_process) + + if expected_result: + assert result is not None + + if expected_exception: + assert handler.instance.status == 'failed' + assert handler.instance.reason == 'Serial Device Error' + + missing_mock.assert_called_once_with('blocked', 'Serial Device Error') + + if terminate_ser_pty_process: + ser_pty_process.terminate.assert_called_once() + ser_pty_process.communicate.assert_called_once() + + if make_available: + available_mock.assert_called_once_with(make_available) + + +TESTDATA_16 = [ + ('dummy1 dummy2', None, 'slave name'), + ('dummy1,dummy2', CalledProcessError, None), + (None, None, 'dummy hardware serial'), +] + +@pytest.mark.parametrize( + 'serial_pty, popen_exception, expected_device', + TESTDATA_16, + ids=['pty', 'pty process error', 'no pty'] +) +def test_devicehandler_get_serial_device( + mocked_instance, + serial_pty, + popen_exception, + expected_device +): + def mock_popen(command, *args, **kwargs): + assert command == ['dummy1', 'dummy2'] + if popen_exception: + raise popen_exception(command, 'Dummy error') + return mock.Mock() + + handler = DeviceHandler(mocked_instance, 'build') + hardware_serial = 'dummy hardware serial' + + popen_mock = mock.Mock(side_effect=mock_popen) + openpty_mock = mock.Mock(return_value=('master', 'slave')) + ttyname_mock = mock.Mock(side_effect=lambda x: x + ' name') + + with mock.patch('subprocess.Popen', popen_mock), \ + mock.patch('pty.openpty', openpty_mock), \ + mock.patch('os.ttyname', ttyname_mock): + result = handler._get_serial_device(serial_pty, hardware_serial) + + if popen_exception: + assert result is None + else: + assert result[0] == expected_device + +TESTDATA_17 = [ + (False, False, False, False, None, False, False, + None, None, []), + (True, True, False, False, None, False, False, + None, None, []), + (True, False, True, False, None, False, False, + 'error', 'Device issue (Flash error)', []), + (True, False, False, True, None, False, False, + 'error', 'Device issue (Timeout)', ['Flash operation timed out.']), + (True, False, False, False, 1, False, False, + 'error', 'Device issue (Flash error?)', []), + (True, False, False, False, 0, True, False, + None, None, ['Timed out while monitoring serial output on IPName']), + (True, False, False, False, 0, False, True, + None, None, ['Process Serial PTY terminated outs: errs ']), +] + +@pytest.mark.parametrize( + 'has_hardware, raise_create_serial, raise_popen, raise_timeout,' \ + ' returncode, do_timeout_thread, use_pty,' \ + ' expected_status, expected_reason, expected_logs', + TESTDATA_17, + ids=['no hardware', 'create serial failure', 'popen called process error', + 'communicate timeout', 'nonzero returncode', 'valid pty', 'valid dev'] +) +def test_devicehandler_handle( + mocked_instance, + caplog, + has_hardware, + raise_create_serial, + raise_popen, + raise_timeout, + returncode, + do_timeout_thread, + use_pty, + expected_status, + expected_reason, + expected_logs +): + def mock_get_serial(serial_pty, hardware_serial): + if serial_pty: + serial_pty_process = mock.Mock( + name='dummy serial PTY process', + communicate=mock.Mock( + return_value=('', '') + ) + ) + return 'dummy serial PTY device', serial_pty_process + return 'dummy serial device', None + + def mock_create_serial(*args, **kwargs): + if raise_create_serial: + raise SerialException('dummy cmd', 'dummy msg') + return mock.Mock(name='dummy serial') + + def mock_thread(*args, **kwargs): + is_alive_mock = mock.Mock(return_value=bool(do_timeout_thread)) + + return mock.Mock(is_alive=is_alive_mock) + + def mock_terminate(proc, *args, **kwargs): + proc.communicate = mock.Mock(return_value=(mock.Mock(), mock.Mock())) + + def mock_communicate(*args, **kwargs): + if raise_timeout: + raise TimeoutExpired('dummy cmd', 'dummyamount') + return mock.Mock(), mock.Mock() + + def mock_popen(command, *args, **kwargs): + if raise_popen: + raise CalledProcessError('dummy proc', 'dummy msg') + + mock_process = mock.Mock( + pid=1, + returncode=returncode, + communicate=mock.Mock(side_effect=mock_communicate) + ) + + return mock.Mock( + __enter__=mock.Mock(return_value=mock_process), + __exit__=mock.Mock(return_value=None) + ) + + hardware = None if not has_hardware else mock.Mock( + baud=14400, + runner='dummy runner', + serial_pty='Serial PTY' if use_pty else None, + serial='dummy serial', + pre_script='dummy pre script', + post_script='dummy post script', + post_flash_script='dummy post flash script', + flash_timeout=60, + flash_with_test=True + ) + + handler = DeviceHandler(mocked_instance, 'build') + handler.get_hardware = mock.Mock(return_value=hardware) + handler.options = mock.Mock( + west_flash=None, + west_runner=None + ) + handler._get_serial_device = mock.Mock(side_effect=mock_get_serial) + handler._create_command = mock.Mock(return_value=['dummy', 'command']) + handler.run_custom_script = mock.Mock() + handler._create_serial_connection = mock.Mock( + side_effect=mock_create_serial + ) + handler.monitor_serial = mock.Mock() + handler.terminate = mock.Mock(side_effect=mock_terminate) + handler._update_instance_info = mock.Mock() + handler._final_handle_actions = mock.Mock() + handler.make_device_available = mock.Mock() + handler.instance.platform.name = 'IPName' + + harness = mock.Mock() + + with mock.patch('builtins.open', mock.mock_open(read_data='')), \ + mock.patch('subprocess.Popen', side_effect=mock_popen), \ + mock.patch('threading.Event', mock.Mock()), \ + mock.patch('threading.Thread', side_effect=mock_thread): + handler.handle(harness) + + handler.get_hardware.assert_called_once() + + messages = [record.msg for record in caplog.records] + assert all([msg in messages for msg in expected_logs]) + + if not has_hardware: + return + + handler.run_custom_script.assert_has_calls([ + mock.call('dummy pre script', mock.ANY) + ]) + + if raise_create_serial: + return + + handler.run_custom_script.assert_has_calls([ + mock.call('dummy pre script', mock.ANY), + mock.call('dummy post flash script', mock.ANY), + mock.call('dummy post script', mock.ANY) + ]) + + if expected_reason: + assert handler.instance.reason == expected_reason + if expected_status: + assert handler.instance.status == expected_status + + handler.make_device_available.assert_called_once_with( + 'Serial PTY' if use_pty else 'dummy serial device' + ) + + +TESTDATA_18 = [ + (True, True, True), + (False, False, False), +] + +@pytest.mark.parametrize( + 'ignore_qemu_crash, expected_ignore_crash, expected_ignore_unexpected_eof', + TESTDATA_18, + ids=['ignore crash', 'qemu crash'] +) +def test_qemuhandler_init( + mocked_instance, + ignore_qemu_crash, + expected_ignore_crash, + expected_ignore_unexpected_eof +): + mocked_instance.testsuite.ignore_qemu_crash = ignore_qemu_crash + + handler = QEMUHandler(mocked_instance, 'build') + + assert handler.ignore_qemu_crash == expected_ignore_crash + assert handler.ignore_unexpected_eof == expected_ignore_unexpected_eof def test_qemuhandler_get_cpu_time(): @@ -1073,15 +1471,340 @@ def mock_process(pid): assert res == pytest.approx(84.0) -TESTDATA_9 = [ +TESTDATA_19 = [ + ( + True, + os.path.join('self', 'dummy_dir', '1'), + mock.PropertyMock(return_value=os.path.join('dummy_dir', '1')), + os.path.join('dummy_dir', '1') + ), + ( + False, + os.path.join('self', 'dummy_dir', '2'), + mock.PropertyMock(return_value=os.path.join('dummy_dir', '2')), + os.path.join('self', 'dummy_dir', '2') + ), +] + +@pytest.mark.parametrize( + 'self_sysbuild, self_build_dir, build_dir, expected', + TESTDATA_19, + ids=['domains build dir', 'self build dir'] +) +def test_qemuhandler_get_sysbuild_build_dir( + mocked_instance, + self_sysbuild, + self_build_dir, + build_dir, + expected +): + get_default_domain_mock = mock.Mock() + type(get_default_domain_mock()).build_dir = build_dir + domains_mock = mock.Mock(get_default_domain=get_default_domain_mock) + from_file_mock = mock.Mock(return_value=domains_mock) + + handler = QEMUHandler(mocked_instance, 'build') + handler.instance.testsuite.sysbuild = self_sysbuild + handler.build_dir = self_build_dir + + with mock.patch('domains.Domains.from_file', from_file_mock): + result = handler._get_sysbuild_build_dir() + + assert result == expected + + +TESTDATA_20 = [ + ( + os.path.join('self', 'dummy_dir', 'log1'), + os.path.join('self', 'dummy_dir', 'pid1'), + os.path.join('sysbuild', 'dummy_dir', 'bd1'), + True + ), + ( + os.path.join('self', 'dummy_dir', 'log2'), + os.path.join('self', 'dummy_dir', 'pid2'), + os.path.join('sysbuild', 'dummy_dir', 'bd2'), + False + ), +] + +@pytest.mark.parametrize( + 'self_log, self_pid_fn, sysbuild_build_dir, exists_pid_fn', + TESTDATA_20, + ids=['pid exists', 'pid missing'] +) +def test_qemuhandler_set_qemu_filenames( + mocked_instance, + self_log, + self_pid_fn, + sysbuild_build_dir, + exists_pid_fn +): + unlink_mock = mock.Mock() + exists_mock = mock.Mock(return_value=exists_pid_fn) + + handler = QEMUHandler(mocked_instance, 'build') + handler.log = self_log + handler.pid_fn = self_pid_fn + + with mock.patch('os.unlink', unlink_mock), \ + mock.patch('os.path.exists', exists_mock): + handler._set_qemu_filenames(sysbuild_build_dir) + + assert handler.fifo_fn == mocked_instance.build_dir + \ + os.path.sep + 'qemu-fifo' + + assert handler.pid_fn == sysbuild_build_dir + os.path.sep + 'qemu.pid' + + assert handler.log_fn == self_log + + if exists_pid_fn: + unlink_mock.assert_called_once_with(sysbuild_build_dir + \ + os.path.sep + 'qemu.pid') + + +def test_qemuhandler_create_command(mocked_instance): + sysbuild_build_dir = os.path.join('sysbuild', 'dummy_dir') + + handler = QEMUHandler(mocked_instance, 'build') + handler.generator_cmd = 'dummy_cmd' + + result = handler._create_command(sysbuild_build_dir) + + assert result == ['dummy_cmd', '-C', 'sysbuild' + os.path.sep + 'dummy_dir', + 'run'] + + +TESTDATA_21 = [ + ( + 0, + False, + None, + 'good dummy state', + False, + None, + None, + False + ), + ( + 1, + True, + None, + 'good dummy state', + False, + None, + None, + False + ), + ( + 0, + False, + None, + None, + True, + 'failed', + 'Timeout', + True + ), + ( + 1, + False, + None, + None, + False, + 'failed', + 'Exited with 1', + True + ), + ( + 1, + False, + 'preexisting reason', + 'good dummy state', + False, + 'failed', + 'preexisting reason', + True + ), +] + +@pytest.mark.parametrize( + 'self_returncode, self_ignore_qemu_crash,' \ + ' self_instance_reason, harness_state, is_timeout,' \ + ' expected_status, expected_reason, expected_called_missing_case', + TESTDATA_21, + ids=['not failed', 'qemu ignore', 'timeout', 'bad returncode', 'other fail'] +) +def test_qemuhandler_update_instance_info( + mocked_instance, + self_returncode, + self_ignore_qemu_crash, + self_instance_reason, + harness_state, + is_timeout, + expected_status, + expected_reason, + expected_called_missing_case +): + mocked_instance.add_missing_case_status = mock.Mock() + mocked_instance.reason = self_instance_reason + + handler = QEMUHandler(mocked_instance, 'build') + handler.returncode = self_returncode + handler.ignore_qemu_crash = self_ignore_qemu_crash + + handler._update_instance_info(harness_state, is_timeout) + + assert handler.instance.status == expected_status + assert handler.instance.reason == expected_reason + + if expected_called_missing_case: + mocked_instance.add_missing_case_status.assert_called_once_with( + 'blocked' + ) + + +def test_qemuhandler_thread_get_fifo_names(): + fifo_fn = 'dummy' + + fifo_in, fifo_out = QEMUHandler._thread_get_fifo_names(fifo_fn) + + assert fifo_in == 'dummy.in' + assert fifo_out == 'dummy.out' + +TESTDATA_22 = [ + (False, False), + (False, True), + (True, False), + (True, True), +] + +@pytest.mark.parametrize( + 'fifo_in_exists, fifo_out_exists', + TESTDATA_22, + ids=['both missing', 'out exists', 'in exists', 'both exist'] +) +def test_qemuhandler_thread_open_files(fifo_in_exists, fifo_out_exists): + def mock_exists(path): + if path == 'fifo.in': + return fifo_in_exists + elif path == 'fifo.out': + return fifo_out_exists + else: + raise ValueError('Unexpected path in mock of os.path.exists') + + unlink_mock = mock.Mock() + exists_mock = mock.Mock(side_effect=mock_exists) + mkfifo_mock = mock.Mock() + + fifo_in = 'fifo.in' + fifo_out = 'fifo.out' + logfile = 'log.file' + + with mock.patch('os.unlink', unlink_mock), \ + mock.patch('os.mkfifo', mkfifo_mock), \ + mock.patch('os.path.exists', exists_mock), \ + mock.patch('builtins.open', mock.mock_open()) as open_mock: + _, _, _ = QEMUHandler._thread_open_files(fifo_in, fifo_out, logfile) + + open_mock.assert_has_calls([ + mock.call('fifo.in', 'wb'), + mock.call('fifo.out', 'rb', buffering=0), + mock.call('log.file', 'wt'), + ]) + + if fifo_in_exists: + unlink_mock.assert_any_call('fifo.in') + + if fifo_out_exists: + unlink_mock.assert_any_call('fifo.out') + + +TESTDATA_23 = [ + (False, False), + (True, True), + (True, False) +] + +@pytest.mark.parametrize( + 'is_pid, is_lookup_error', + TESTDATA_23, + ids=['pid missing', 'pid lookup error', 'pid ok'] +) +def test_qemuhandler_thread_close_files(is_pid, is_lookup_error): + is_process_killed = {} + + def mock_kill(pid, sig): + if is_lookup_error: + raise ProcessLookupError(f'Couldn\'t find pid: {pid}.') + elif sig == signal.SIGTERM: + is_process_killed[pid] = True + + unlink_mock = mock.Mock() + kill_mock = mock.Mock(side_effect=mock_kill) + + fifo_in = 'fifo.in' + fifo_out = 'fifo.out' + pid = 12345 if is_pid else None + out_fp = mock.Mock() + in_fp = mock.Mock() + log_out_fp = mock.Mock() + + with mock.patch('os.unlink', unlink_mock), \ + mock.patch('os.kill', kill_mock): + QEMUHandler._thread_close_files(fifo_in, fifo_out, pid, out_fp, + in_fp, log_out_fp) + + out_fp.close.assert_called_once() + in_fp.close.assert_called_once() + log_out_fp.close.assert_called_once() + + unlink_mock.assert_has_calls([mock.call('fifo.in'), mock.call('fifo.out')]) + + if is_pid and not is_lookup_error: + assert is_process_killed[pid] + + +TESTDATA_24 = [ + ('timeout', 'failed', 'Timeout'), + ('failed', 'failed', 'Failed'), + ('unexpected eof', 'failed', 'unexpected eof'), + ('unexpected byte', 'failed', 'unexpected byte'), + (None, None, 'Unknown'), +] + +@pytest.mark.parametrize( + 'out_state, expected_status, expected_reason', + TESTDATA_24, + ids=['timeout', 'failed', 'unexpected eof', 'unexpected byte', 'unknown'] +) +def test_qemuhandler_thread_update_instance_info( + mocked_instance, + out_state, + expected_status, + expected_reason +): + handler = QEMUHandler(mocked_instance, 'build') + handler_time = 59 + + QEMUHandler._thread_update_instance_info(handler, handler_time, out_state) + + assert handler.instance.execution_time == handler_time + + assert handler.instance.status == expected_status + assert handler.instance.reason == expected_reason + + +TESTDATA_25 = [ ( ('1\n' * 60).encode('utf-8'), 60, 1, [None] * 60 + ['success'] * 6, 1000, - 'failed', - 'Timeout' + False, + 'timeout', + [mock.call('1\n'), mock.call('1\n')] ), ( ('1\n' * 60).encode('utf-8'), @@ -1089,8 +1812,9 @@ def mock_process(pid): -1, [None] * 60 + ['success'] * 30, 100, + False, 'failed', - 'Failed' + [mock.call('1\n'), mock.call('1\n')] ), ( b'', @@ -1098,8 +1822,9 @@ def mock_process(pid): 1, ['success'] * 3, 100, - 'failed', - 'unexpected eof' + False, + 'unexpected eof', + [] ), ( b'\x81', @@ -1107,8 +1832,9 @@ def mock_process(pid): 1, ['success'] * 3, 100, - 'failed', - 'unexpected byte' + False, + 'unexpected byte', + [] ), ( '1\n2\n3\n4\n5\n'.encode('utf-8'), @@ -1116,22 +1842,44 @@ def mock_process(pid): 1, [None] * 3 + ['success'] * 7, 100, + False, 'success', - 'Unknown' + [mock.call('1\n'), mock.call('2\n'), mock.call('3\n'), mock.call('4\n')] + ), + ( + '1\n2\n3\n4\n5\n'.encode('utf-8'), + 600, + 0, + [None] * 3 + ['success'] * 7, + 100, + False, + 'timeout', + [mock.call('1\n'), mock.call('2\n')] + ), + ( + '1\n2\n3\n4\n5\n'.encode('utf-8'), + 6, + 1, + [None] * 3 + ['success'] * 7, + (n for n in [100, 100, 10000]), + True, + 'success', + [mock.call('1\n'), mock.call('2\n'), mock.call('3\n'), mock.call('4\n')] ), ] - @pytest.mark.parametrize( - 'content, timeout, pid, harness_states, cputime,' - ' expected_instance_status, expected_instance_reason', - TESTDATA_9, + 'content, timeout, pid, harness_states, cputime, capture_coverage,' \ + ' expected_out_state, expected_log_calls', + TESTDATA_25, ids=[ 'timeout', 'harness failed', 'unexpected eof', 'unexpected byte', - 'harness success' + 'harness success', + 'timeout by pid=0', + 'capture_coverage' ] ) def test_qemuhandler_thread( @@ -1142,18 +1890,19 @@ def test_qemuhandler_thread( pid, harness_states, cputime, - expected_instance_status, - expected_instance_reason + capture_coverage, + expected_out_state, + expected_log_calls ): def mock_cputime(pid): if pid > 0: - return cputime + return cputime if isinstance(cputime, int) else next(cputime) else: raise ProcessLookupError() handler = QEMUHandler(mocked_instance, 'build') - handler.ignore_unexpected_eof=False handler.results = {} + handler.ignore_unexpected_eof = False handler.pid_fn = 'pid_fn' handler.fifo_fn = 'fifo_fn' type(mocked_instance.testsuite).timeout = mock.PropertyMock( @@ -1172,7 +1921,7 @@ def mocked_open(filename, *args, **kwargs): file_object.__iter__.return_value = contents.splitlines(True) return file_object - harness = mock.Mock(capture_coverage=False) + harness = mock.Mock(capture_coverage=capture_coverage, handle=print) type(harness).state = mock.PropertyMock(side_effect=harness_states) p = mock.Mock() @@ -1180,15 +1929,33 @@ def mocked_open(filename, *args, **kwargs): side_effect=itertools.cycle([True, True, True, True, False]) ) - with mock.patch('time.time', mock.Mock(side_effect=faux_timer.time)), \ - mock.patch('builtins.open', new=mocked_open), \ - mock.patch('select.poll', mock.Mock(return_value=p)), \ - mock.patch('os.path.exists', mock.Mock(return_value=True)), \ - mock.patch('os.unlink', mock.Mock()), \ - mock.patch('os.mkfifo', mock.Mock()), \ - mock.patch('os.kill', mock.Mock()), \ - mock.patch.object(QEMUHandler, '_get_cpu_time', mock_cputime): + mock_thread_get_fifo_names = mock.Mock( + return_value=('fifo_fn.in', 'fifo_fn.out') + ) + log_fp_mock = mock.Mock() + in_fp_mock = mocked_open('fifo_fn.out') + out_fp_mock = mock.Mock() + mock_thread_open_files = mock.Mock( + return_value=(out_fp_mock, in_fp_mock, log_fp_mock) + ) + mock_thread_close_files = mock.Mock() + mock_thread_update_instance_info = mock.Mock() + with mock.patch('time.time', side_effect=faux_timer.time), \ + mock.patch('builtins.open', new=mocked_open), \ + mock.patch('select.poll', return_value=p), \ + mock.patch('os.path.exists', return_value=True), \ + mock.patch('twisterlib.handlers.QEMUHandler._get_cpu_time', + mock_cputime), \ + mock.patch('twisterlib.handlers.QEMUHandler._thread_get_fifo_names', + mock_thread_get_fifo_names), \ + mock.patch('twisterlib.handlers.QEMUHandler._thread_open_files', + mock_thread_open_files), \ + mock.patch('twisterlib.handlers.QEMUHandler._thread_close_files', + mock_thread_close_files), \ + mock.patch('twisterlib.handlers.QEMUHandler.' \ + '_thread_update_instance_info', + mock_thread_update_instance_info): QEMUHandler._thread( handler, handler.timeout, @@ -1201,15 +1968,52 @@ def mocked_open(filename, *args, **kwargs): handler.ignore_unexpected_eof ) - assert handler.instance.status == expected_instance_status - assert handler.instance.reason == expected_instance_reason + mock_thread_update_instance_info.assert_called_once_with( + handler, + mock.ANY, + expected_out_state + ) + + log_fp_mock.write.assert_has_calls(expected_log_calls) + + +TESTDATA_26 = [ + (True, False, None, True, + ['No timeout, return code from QEMU (1): 1', + 'return code from QEMU (1): 1']), + (False, True, 'passed', True, ['return code from QEMU (1): 0']), + (False, True, 'failed', False, ['return code from QEMU (None): 1']), +] +@pytest.mark.parametrize( + 'isatty, do_timeout, harness_state, exists_pid_fn, expected_logs', + TESTDATA_26, + ids=['no timeout, isatty', 'timeout passed', 'timeout, no pid_fn'] +) +def test_qemuhandler_handle( + mocked_instance, + caplog, + tmp_path, + isatty, + do_timeout, + harness_state, + exists_pid_fn, + expected_logs +): + def mock_wait(*args, **kwargs): + if do_timeout: + raise TimeoutExpired('dummy cmd', 'dummyamount') -def test_qemuhandler_handle(mocked_instance, caplog, tmp_path): - mock_process = mock.Mock(pid=0, returncode=0) + mock_process = mock.Mock(pid=0, returncode=1) mock_process.communicate = mock.Mock( return_value=(mock.Mock(), mock.Mock()) ) + mock_process.wait = mock.Mock(side_effect=mock_wait) + + handler = QEMUHandler(mocked_instance, 'build') + + def mock_path_exists(name, *args, **kwargs): + return exists_pid_fn def mock_popen(command, stdout=None, stdin=None, stderr=None, cwd=None): return mock.Mock( @@ -1221,22 +2025,17 @@ def mock_popen(command, stdout=None, stdin=None, stderr=None, cwd=None): def mock_thread(name=None, target=None, daemon=None, args=None): return mock.Mock() - mocked_domain = mock.Mock() - mocked_domain.get_default_domain = mock.Mock(return_value=mock.Mock()) - type(mocked_domain.get_default_domain()).build_dir = os.path.join( - tmp_path, - 'domain_build_dir' - ) + def mock_filenames(sysbuild_build_dir): + handler.fifo_fn = os.path.join('dummy', 'qemu-fifo') + handler.pid_fn = os.path.join(sysbuild_build_dir, 'qemu.pid') + handler.log_fn = os.path.join('dummy', 'log') - hardware_flash_timeout = 1 - hardware = mock.Mock( - flash_timeout=hardware_flash_timeout, - probe_id='board_id' - ) - harness = mock.Mock() + harness = mock.Mock(state=harness_state) handler_options_west_flash = [] - handler = QEMUHandler(mocked_instance, 'build') + sysbuild_build_dir = os.path.join('sysbuild', 'dummydir') + command = ['generator_cmd', '-C', os.path.join('cmd', 'path'), 'run'] + handler.options = mock.Mock( west_flash=handler_options_west_flash, west_runner=None @@ -1244,29 +2043,28 @@ def mock_thread(name=None, target=None, daemon=None, args=None): handler.run_custom_script = mock.Mock(return_value=None) handler.make_device_available = mock.Mock(return_value=None) handler._final_handle_actions = mock.Mock(return_value=None) - handler.generator_cmd = 'generator_cmd' - - with mock.patch.object( - DeviceHandler, - 'get_hardware', - mock.Mock(return_value=hardware) - ), \ - mock.patch( - 'pty.openpty', - mock.Mock(return_value=(mock.Mock(), mock.Mock())) - ), \ - mock.patch('subprocess.Popen', mock.Mock(side_effect=mock_popen)), \ - mock.patch('os.ttyname', mock.Mock(return_value=mock.Mock())), \ - mock.patch('serial.Serial', mock.Mock(return_value=mock.Mock())), \ - mock.patch('builtins.open', mock.mock_open(read_data='')), \ - mock.patch('threading.Event', mock.Mock(return_value=mock.Mock())), \ - mock.patch('threading.Thread', mock.Mock(side_effect=mock_thread)), \ - mock.patch( - 'domains.Domains.from_file', - mock.Mock(return_value=mocked_domain) - ): + handler._create_command = mock.Mock(return_value=command) + handler._set_qemu_filenames = mock.Mock(side_effect=mock_filenames) + handler._get_sysbuild_build_dir = mock.Mock(return_value=sysbuild_build_dir) + handler.terminate = mock.Mock() + + unlink_mock = mock.Mock() + + with mock.patch('subprocess.Popen', side_effect=mock_popen), \ + mock.patch('builtins.open', mock.mock_open(read_data='1')), \ + mock.patch('threading.Thread', side_effect=mock_thread), \ + mock.patch('os.path.exists', side_effect=mock_path_exists), \ + mock.patch('os.unlink', unlink_mock), \ + mock.patch('sys.stdout.isatty', return_value=isatty): handler.handle(harness) - assert caplog.records[-1].message == 'return code from QEMU (None):' \ - f' {mock_process.returncode}' - assert caplog.records[-1].levelname == 'DEBUG' + assert all([expected_log in caplog.text for expected_log in expected_logs]) + + +def test_qemuhandler_get_fifo(mocked_instance): + handler = QEMUHandler(mocked_instance, 'build') + handler.fifo_fn = 'fifo_fn' + + result = handler.get_fifo() + + assert result == 'fifo_fn' From c986104485914a0adbcfb5cf96dcb152e82fa87d Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 30 Jun 2023 07:07:38 +0530 Subject: [PATCH 0595/4498] Bluetooth: Controller: Revert EVENT_OVERHEAD_END_US to original value Revert back the EVENT_OVERHEAD_END_US value to original value in initial commit 5c3709c13fd8 ("bluetooth: controller: Add def's re. update to slot reservation calc"). 40 us is a sufficient margin considering ~30 us being the worst case Rx chain delay for S8 Coded PHY on nRF5x SoCs. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h index 5ee063e4d53..7df39f65c8a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h @@ -42,7 +42,7 @@ /* Worst-case time margin needed after event end-time in the air * (done/preempt race margin + power-down/chain delay) */ -#define EVENT_OVERHEAD_END_US 100 +#define EVENT_OVERHEAD_END_US 40 /* Sleep Clock Accuracy */ #define EVENT_JITTER_US 16 From 01314b2e434e5759327bcf78c38089e6750c54c4 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 30 Jun 2023 08:18:53 +0530 Subject: [PATCH 0596/4498] Bluetooth: Controller: Make openisa and test hal ticker.h consistent Make openisa and unit test hal ticker.h consistent with nrf hal ticker.h. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 3 +- .../ll_sw/openisa/hal/RV32M1/ticker.h | 36 ++++++++++---- .../mock_ctrl/include/hal/ticker_vendor_hal.h | 49 +++++++++++++------ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 5845d15145a..315601ce203 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -26,7 +26,8 @@ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & HAL_TICKER_CNTR_MASK \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index 642ca1e608f..e4d162eb9d2 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -6,37 +6,53 @@ */ #define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL +/* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 2 +/* Macro defining the max. counter update latency in ticks */ #define HAL_TICKER_CNTR_SET_LATENCY 1 + +/* Macro defines the h/w supported most significant bit */ +#define HAL_TICKER_CNTR_MSBIT 31 + +/* Macro defining the HW supported counter bits */ +#define HAL_TICKER_CNTR_MASK 0xFFFFFFFF + /* * When the LPTMR is enabled, the first increment will take an additional * one or two prescaler clock cycles due to synchronization logic. */ +/* Macro to translate microseconds to tick units. + * NOTE: This returns the floor value. + */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / 30517578125UL)) \ - & HAL_TICKER_CNTR_MASK \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ + ) + +/* Macro to translate tick units to microseconds. */ +#define HAL_TICKER_TICKS_TO_US(x) \ + ( \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ + 1000000000UL)) \ ) +/* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ ((uint64_t) (x) * 1000000000UL) \ - - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * 30517578125UL) \ + - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ + HAL_TICKER_CNTR_CLK_UNIT_FS) \ ) \ / 1000UL \ ) -#define HAL_TICKER_TICKS_TO_US(x) \ - ((uint32_t)(((uint64_t)(x) * 30517578125UL) / 1000000000UL)) - -#define HAL_TICKER_CNTR_MSBIT 31 - -#define HAL_TICKER_CNTR_MASK 0xFFFFFFFF - /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index bbd4b3e462c..7c3792d848c 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -3,7 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -11,30 +13,47 @@ /* Macro defining the max. counter update latency in ticks */ #define HAL_TICKER_CNTR_SET_LATENCY 0 +/* Macro defines the h/w supported most significant bit */ +#define HAL_TICKER_CNTR_MSBIT 23 + +/* Macro defining the HW supported counter bits */ +#define HAL_TICKER_CNTR_MASK 0x00FFFFFF + /* Macro to translate microseconds to tick units. * NOTE: This returns the floor value. */ -#define HAL_TICKER_US_TO_TICKS(x) \ - (((uint32_t)(((uint64_t)(x) * 1000000000UL) / 30517578125UL)) & HAL_TICKER_CNTR_MASK) +#define HAL_TICKER_US_TO_TICKS(x) \ + ( \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ + ) -/* Macro returning remainder in nanoseconds */ -#define HAL_TICKER_REMAINDER(x) \ - ((((uint64_t)(x) * 1000000000UL) - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * 30517578125UL)) /\ - 1000UL) /* Macro to translate tick units to microseconds. */ -#define HAL_TICKER_TICKS_TO_US(x) ((uint32_t)(((uint64_t)(x) * 30517578125UL) / 1000000000UL)) - -/* Macro defines the h/w supported most significant bit */ -#define HAL_TICKER_CNTR_MSBIT 23 - -/* Macro defining the HW supported counter bits */ -#define HAL_TICKER_CNTR_MASK 0x00FFFFFF +#define HAL_TICKER_TICKS_TO_US(x) \ + ( \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ + 1000000000UL)) \ + ) + +/* Macro returning remainder in picoseconds (to fit in 32-bits) */ +#define HAL_TICKER_REMAINDER(x) \ + ( \ + ( \ + ((uint64_t) (x) * 1000000000UL) \ + - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ + HAL_TICKER_CNTR_CLK_UNIT_FS) \ + ) \ + / 1000UL \ + ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ -#define HAL_TICKER_REMAINDER_RANGE HAL_TICKER_TICKS_TO_US(1000000) +#define HAL_TICKER_REMAINDER_RANGE \ + HAL_TICKER_TICKS_TO_US(1000000) /* Macro defining the margin for positioning re-scheduled nodes */ -#define HAL_TICKER_RESCHEDULE_MARGIN HAL_TICKER_US_TO_TICKS(150) +#define HAL_TICKER_RESCHEDULE_MARGIN \ + HAL_TICKER_US_TO_TICKS(150) From 333ff94e6bd19f7b2bc7c9c3ddb1f84fb84bff80 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 13 Jun 2023 09:07:19 +0530 Subject: [PATCH 0597/4498] Bluetooth: Controller: Use HAL_TICKER_US_TO_TICKS_CEIL for ticks_slot Use HAL_TICKER_US_TO_TICKS_CEIL for ticks_slot calculations. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 11 +++++++++++ .../controller/ll_sw/openisa/hal/RV32M1/ticker.h | 11 +++++++++++ subsys/bluetooth/controller/ll_sw/ull_adv.c | 4 ++-- subsys/bluetooth/controller/ll_sw/ull_adv_aux.c | 6 +++--- subsys/bluetooth/controller/ll_sw/ull_adv_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_sync.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_central.c | 11 ++++------- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_conn.c | 10 ++++------ subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_peripheral.c | 11 ++++------- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 10 ++++------ subsys/bluetooth/controller/ll_sw/ull_sched.c | 10 ++++++---- subsys/bluetooth/controller/ll_sw/ull_sync.c | 10 ++++------ subsys/bluetooth/controller/ll_sw/ull_sync_iso.c | 10 +++++----- .../mock_ctrl/include/hal/ticker_vendor_hal.h | 10 ++++++++++ 16 files changed, 72 insertions(+), 50 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 315601ce203..f179dbd0035 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -30,6 +30,17 @@ HAL_TICKER_CNTR_MASK \ ) +/* Macro to translate microseconds to tick units. + * NOTE: This returns the ceil value. + */ +#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ + ( \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ + ) + /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index e4d162eb9d2..1f491739185 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -35,6 +35,17 @@ HAL_TICKER_CNTR_MASK \ ) +/* Macro to translate microseconds to tick units. + * NOTE: This returns the ceil value. + */ +#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ + ( \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ + ) + /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index 3797acdc541..d7d5b23f63e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -1251,7 +1251,7 @@ uint8_t ll_adv_enable(uint8_t enable) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); adv->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - adv->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + adv->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); ticks_slot_offset = MAX(adv->ull.ticks_active_to_start, adv->ull.ticks_prepare_to_start); @@ -2145,7 +2145,7 @@ uint8_t ull_adv_time_update(struct ll_adv_set *adv, struct pdu_adv *pdu, chan_map = lll->chan_map; chan_cnt = util_ones_count_get(&chan_map, sizeof(chan_map)); time_us = adv_time_get(pdu, pdu_scan, chan_cnt, phy, phy_flags); - time_ticks = HAL_TICKER_US_TO_TICKS(time_us); + time_ticks = HAL_TICKER_US_TO_TICKS_CEIL(time_us); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) uint32_t volatile ret_cb; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 907a69b05c7..5349b21dd9f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -2454,7 +2454,7 @@ uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); aux->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, @@ -2471,7 +2471,7 @@ uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux, #if defined(CONFIG_BT_CTLR_ADV_RESERVE_MAX) time_us = ull_adv_aux_time_get(aux, PDU_AC_PAYLOAD_SIZE_MAX, PDU_AC_PAYLOAD_SIZE_MAX); - ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); #else ticks_slot = aux->ull.ticks_slot; #endif @@ -2997,7 +2997,7 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu, uint32_t time_us; time_us = aux_time_min_get(aux); - time_ticks = HAL_TICKER_US_TO_TICKS(time_us); + time_ticks = HAL_TICKER_US_TO_TICKS_CEIL(time_us); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) uint32_t volatile ret_cb; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 765e911b208..89e66ff99e5 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -977,7 +977,7 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); adv_iso->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - adv_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); + adv_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); ticks_slot_offset = MAX(adv_iso->ull.ticks_active_to_start, adv_iso->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c index 178116a54ec..bbb1b351848 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c @@ -1136,7 +1136,7 @@ uint32_t ull_adv_sync_evt_init(struct ll_adv_set *adv, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); ticks_slot_offset = MAX(sync->ull.ticks_active_to_start, sync->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 5effe2ae676..de14395f840 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -360,13 +360,10 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, #endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - conn->ull.ticks_slot = - HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + - EVENT_OVERHEAD_END_US + - ready_delay_us + - max_tx_time + - EVENT_IFS_US + - max_rx_time); + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay_us + max_tx_time + EVENT_IFS_US + max_rx_time + + (EVENT_CLOCK_JITTER_US << 1)); #if defined(CONFIG_BT_CTLR_PRIVACY) ull_filter_scan_update(filter_policy); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 71b8d742a76..2a19e03bde5 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -559,7 +559,7 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); cig->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); + cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Reset params cache */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 0b54a5dee79..a8d3178e020 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1257,12 +1257,10 @@ void ull_conn_done(struct node_rx_event_done *done) tx_time = PDU_DC_MAX_US(lll->dle.eff.max_tx_octets, 0); rx_time = PDU_DC_MAX_US(lll->dle.eff.max_rx_octets, 0); #endif /* CONFIG_BT_CTLR_PHY */ - ticks_slot = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + - ready_delay + - EVENT_IFS_US + - rx_time + - tx_time + - 4); + ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay + EVENT_IFS_US + rx_time + tx_time + + (EVENT_CLOCK_JITTER_US << 1)); if (ticks_slot > conn->ull.ticks_slot) { ticks_slot_plus = ticks_slot - conn->ull.ticks_slot; } else { diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 2ee5905b23b..46c00c305fe 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -987,7 +987,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); cig->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); + cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); } ticks_slot_offset = MAX(cig->ull.ticks_active_to_start, diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index f1716c06573..8b813fda9fd 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -371,13 +371,10 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); conn->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - conn->ull.ticks_slot = - HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + - EVENT_OVERHEAD_END_US + - ready_delay_us + - max_rx_time + - EVENT_IFS_US + - max_tx_time); + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay_us + max_rx_time + EVENT_IFS_US + max_tx_time + + (EVENT_CLOCK_JITTER_US << 1)); ticks_slot_offset = MAX(conn->ull.ticks_active_to_start, conn->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 26fc6d4806b..316cec7fec7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -666,12 +666,10 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); aux->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - aux->ull.ticks_slot = - HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + - ready_delay_us + - PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, - lll_aux->phy) + - EVENT_OVERHEAD_END_US); + aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + ready_delay_us + + PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll_aux->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(aux->ull.ticks_active_to_start, aux->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index a445d986248..e7ca8a0358b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -656,7 +656,7 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) time_us = ull_adv_aux_time_get(aux, PDU_AC_PAYLOAD_SIZE_MAX, PDU_AC_PAYLOAD_SIZE_MAX); - *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); } else { *ticks_slot = aux->ull.ticks_slot; @@ -686,7 +686,7 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) uint32_t time_us; time_us = ull_adv_sync_time_get(sync, PDU_AC_PAYLOAD_SIZE_MAX); - *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); } else { *ticks_slot = sync->ull.ticks_slot; } @@ -745,9 +745,11 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) #endif /* !CONFIG_BT_CTLR_PHY_CODED */ time_us = EVENT_OVERHEAD_START_US + + EVENT_OVERHEAD_END_US + ready_delay_us + max_rx_time + - EVENT_IFS_US + max_tx_time; - *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); + EVENT_IFS_US + max_tx_time + + (EVENT_CLOCK_JITTER_US << 1); + *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); } else { *ticks_slot = conn->ull.ticks_slot; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 6c674885810..265475196fd 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -826,12 +826,10 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync->ull.ticks_slot = - HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + - ready_delay_us + - PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, - lll->phy) + - EVENT_OVERHEAD_END_US); + sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + ready_delay_us + + PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(sync->ull.ticks_active_to_start, sync->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index fbacb56f8b4..ff3327ce393 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -509,11 +509,11 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync_iso->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS( - EVENT_OVERHEAD_START_US + ready_delay_us + - PDU_BIS_MAX_US(PDU_AC_EXT_PAYLOAD_SIZE_MAX, lll->enc, - lll->phy) + - EVENT_OVERHEAD_END_US); + sync_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + ready_delay_us + + PDU_BIS_MAX_US(PDU_AC_EXT_PAYLOAD_SIZE_MAX, lll->enc, + lll->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(sync_iso->ull.ticks_active_to_start, sync_iso->ull.ticks_prepare_to_start); diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index 7c3792d848c..67a46515033 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -29,6 +29,16 @@ HAL_TICKER_CNTR_MASK \ ) +/* Macro to translate microseconds to tick units. + * NOTE: This returns the ceil value. + */ +#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ + ( \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + HAL_TICKER_CNTR_MASK \ + ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ From 3a690f62dda966ab55322b5c5d92f096a92b1bbb Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 13 Sep 2023 17:27:12 +0530 Subject: [PATCH 0598/4498] tests: bsim: Bluetooth: mesh: Adjust test sleep durations Adjust test sleep durations to compensate towards timing changes in Zephyr Controller radio scheduling. With the change in the radio scheduling, there is overlap of advertising PDU from multiple nodes that relay the PDU, hence increase test timeout so that next advertising interval that uses random delay will get received by nodes without collisions on air. Signed-off-by: Vinayak Kariappa Chettimada --- tests/bsim/bluetooth/mesh/src/test_provision.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 3b9e6578351..9f31cb77faf 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -579,26 +579,26 @@ static void node_configure_and_reset(void) &status)); ASSERT_EQUAL(0, status); - k_sleep(K_SECONDS(1)); + k_sleep(K_SECONDS(2)); ASSERT_OK(bt_mesh_cfg_cli_mod_app_bind(0, current_dev_addr, current_dev_addr, 0x0, BT_MESH_MODEL_ID_HEALTH_SRV, &status)); ASSERT_EQUAL(0, status); - k_sleep(K_SECONDS(1)); + k_sleep(K_SECONDS(2)); ASSERT_OK(bt_mesh_cfg_cli_mod_sub_add(0, current_dev_addr, current_dev_addr, 0xc000, BT_MESH_MODEL_ID_HEALTH_SRV, &status)); ASSERT_EQUAL(0, status); - k_sleep(K_SECONDS(1)); + k_sleep(K_SECONDS(2)); ASSERT_OK(bt_mesh_cfg_cli_mod_pub_set(0, current_dev_addr, current_dev_addr, BT_MESH_MODEL_ID_HEALTH_SRV, &healthpub, &status)); ASSERT_EQUAL(0, status); - k_sleep(K_SECONDS(1)); + k_sleep(K_SECONDS(2)); ASSERT_OK(bt_mesh_cfg_cli_node_reset(0, current_dev_addr, (bool *)&status)); From 34100cb7ea9d398a10281eb76fc97218569f94f1 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Sep 2023 18:47:25 +0530 Subject: [PATCH 0599/4498] Bluetooth: Controller: Use defines for femto and pico seconds Use defines for femto and pico seconds in HAL ticker calculations. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 41 ++++++++++--------- .../ll_sw/openisa/hal/RV32M1/ticker.h | 29 +++++++------ .../mock_ctrl/include/hal/ticker_vendor_hal.h | 29 +++++++------ 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index f179dbd0035..cbb8ae6a8ce 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -5,8 +5,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL +#define HAL_TICKER_FSEC_PER_USEC 1000000000UL +#define HAL_TICKER_PSEC_PER_USEC 1000000UL +#define HAL_TICKER_FSEC_PER_PSEC 1000UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -25,8 +28,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -35,35 +38,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ - 1000000000UL)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ + HAL_TICKER_FSEC_PER_USEC)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * 1000000000UL) \ + ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FS) \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ ) \ - / 1000UL \ + / HAL_TICKER_FSEC_PER_PSEC \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(1000000) + HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ @@ -74,24 +77,24 @@ static inline void hal_ticker_remove_jitter(uint32_t *ticks, uint32_t *remainder) { /* Is remainder less than 1 us */ - if ((*remainder & BIT(31)) || !(*remainder / 1000000UL)) { + if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { *ticks -= 1U; - *remainder += HAL_TICKER_CNTR_CLK_UNIT_FS / 1000UL; + *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; } /* pico seconds to micro seconds unit */ - *remainder /= 1000000UL; + *remainder /= HAL_TICKER_PSEC_PER_USEC; } /* Add ticks and return positive remainder value in microseconds */ static inline void hal_ticker_add_jitter(uint32_t *ticks, uint32_t *remainder) { /* Is remainder less than 1 us */ - if ((*remainder & BIT(31)) || !(*remainder / 1000000UL)) { + if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { *ticks += 1U; - *remainder += HAL_TICKER_CNTR_CLK_UNIT_FS / 1000UL; + *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; } /* pico seconds to micro seconds unit */ - *remainder /= 1000000UL; + *remainder /= HAL_TICKER_PSEC_PER_USEC; } diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index 1f491739185..78aa6362595 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -5,8 +5,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL +#define HAL_TICKER_FSEC_PER_USEC 1000000000UL +#define HAL_TICKER_PSEC_PER_USEC 1000000UL +#define HAL_TICKER_FSEC_PER_PSEC 1000UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 2 @@ -30,8 +33,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -40,35 +43,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ - 1000000000UL)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ + HAL_TICKER_FSEC_PER_USEC)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * 1000000000UL) \ + ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FS) \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ ) \ - / 1000UL \ + / HAL_TICKER_FSEC_PER_PSEC \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(1000000) + HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index 67a46515033..c2b20050caa 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -4,8 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL +#define HAL_TICKER_FSEC_PER_USEC 1000000000UL +#define HAL_TICKER_PSEC_PER_USEC 1000000UL +#define HAL_TICKER_FSEC_PER_PSEC 1000UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -24,8 +27,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -34,35 +37,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ - 1000000000UL)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ + HAL_TICKER_FSEC_PER_USEC)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * 1000000000UL) \ + ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FS) \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ ) \ - / 1000UL \ + / HAL_TICKER_FSEC_PER_PSEC \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(1000000) + HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ From 5daa864b5e7b21d840b3fdb51c238a009a24c8f1 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Sep 2023 19:04:22 +0530 Subject: [PATCH 0600/4498] Bluetooth: Controller: Use DIV_ROUND_UP macro in HAL ticker Use DIV_ROUND_UP macro in HAL ticker. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h | 5 ++--- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h | 5 ++--- .../controller/mock_ctrl/include/hal/ticker_vendor_hal.h | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index cbb8ae6a8ce..10d780a559c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -38,9 +38,8 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ HAL_TICKER_CNTR_MASK \ ) diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index 78aa6362595..ab9b14207c1 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -43,9 +43,8 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ HAL_TICKER_CNTR_MASK \ ) diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index c2b20050caa..8cb4e791a30 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -37,9 +37,8 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ HAL_TICKER_CNTR_MASK \ ) From e318a3032b0d09ef9439b2a9b1c792a3cae203d6 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Fri, 30 Jun 2023 09:17:36 +0200 Subject: [PATCH 0601/4498] Bluetooth: controller: Use consecutive event for framed TX and RX bugfix Changes: -- Disregards target event after segmenting the first TX SDU and instead decide event based on the next payload and feasibility to fragment for that event (time-offset > 0) -- Corrected error SDU release logic when an error occurs while expecting the start of a new SDU, to avoid releasing an SDU which could be received in the next payload or event -- Included additional debug logging Signed-off-by: Nirosharn Amarasinghe --- subsys/bluetooth/controller/ll_sw/isoal.c | 408 +++++++++++++++------- subsys/bluetooth/controller/ll_sw/isoal.h | 4 +- 2 files changed, 292 insertions(+), 120 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 0a500cfd05e..110a7aa901e 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -50,6 +50,11 @@ LOG_MODULE_REGISTER(bt_ctlr_isoal, LOG_LEVEL_INF); (s == ISOAL_CONTINUE ? "CONTINUE" : \ (s == ISOAL_ERR_SPOOL ? "ERR SPOOL" : "???"))) +#define STATE_TO_STR(s) (s == BT_ISO_SINGLE ? "SINGLE" : \ + (s == BT_ISO_START ? "START" : \ + (s == BT_ISO_CONT ? "CONT" : \ + (s == BT_ISO_END ? "END" : "???")))) + #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) /* Given the minimum payload, this defines the minimum number of bytes that * should be remaining in a TX PDU such that it would make inserting a new @@ -186,7 +191,7 @@ static bool isoal_get_time_diff(uint32_t time_before, uint32_t time_after, uint3 #define SET_RX_SDU_TIMESTAMP(_sink, _timestamp, _value) \ _timestamp = _value; \ - ISOAL_LOG_DBGV("[%p] %s updated (%ld)", _sink, #_timestamp, _value); + ISOAL_LOG_DBGV("[%p] %s updated (%lu)", _sink, #_timestamp, _value); static void isoal_rx_framed_update_sdu_release(struct isoal_sink *sink); @@ -415,7 +420,7 @@ static isoal_status_t isoal_rx_allocate_sdu(struct isoal_sink *sink, ); if (err == ISOAL_STATUS_OK) { - sp->sdu_allocated = true; + sp->sdu_allocated = 1U; } /* Nothing has been written into buffer yet */ @@ -599,7 +604,7 @@ static isoal_status_t isoal_rx_try_emit_sdu(struct isoal_sink *sink, bool end_of sdu->status = sp->sdu_status; err = isoal_rx_buffered_emit_sdu(sink, end_of_sdu); - sp->sdu_allocated = false; + sp->sdu_allocated = 0U; if (end_of_sdu) { isoal_rx_framed_update_sdu_release(sink); @@ -729,9 +734,9 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, next_state = ISOAL_START; /* If status is not ISOAL_PDU_STATUS_VALID, length and LLID cannot be trusted */ - llid = pdu_meta->pdu->ll_id; + llid = pdu->ll_id; pdu_err = (pdu_meta->meta->status != ISOAL_PDU_STATUS_VALID); - length = pdu_meta->pdu->len; + length = pdu->len; /* A zero length PDU with LLID 0b01 (PDU_BIS_LLID_START_CONTINUE) would be a padding PDU. * However if there are errors in the PDU, it could be an incorrectly receive non-padding * PDU. Therefore only consider a PDU with errors as padding if received after the end @@ -937,7 +942,7 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, sp->prev_pdu_is_end = !pdu_err && llid == PDU_BIS_LLID_COMPLETE_END; sp->prev_pdu_is_padding = !pdu_err && pdu_padding; - sp->initialized = true; + sp->initialized = 1U; return err; } @@ -1293,6 +1298,8 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } if (pdu_err || seq_err || seg_err) { + bool error_sdu_pending = false; + /* When one or more ISO Data PDUs are not received, the receiving device may * discard all SDUs affected by the missing PDUs. Any partially received SDU * may also be discarded. @@ -1321,14 +1328,28 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, switch (sp->fsm) { case ISOAL_START: - /* First release lost SDUs and then release a new SDU - * with errors. Since we have an SDU to release - * following any lost SDUs, lost SDUs handling should be - * similar to when a valid timestamp exists. + /* If errors occur while waiting for the start of an SDU + * then an SDU should should only be released if there + * is confirmation that a reception occurred + * unsuccessfully. In the case of STATUS_LOST_DATA which + * could result from a flush, an SDU should not be + * released as the flush does not necessarily mean that + * part of an SDU has been lost. In this case Lost SDU + * release defaults to the lost SDU detection based on + * the SDU interval. If we have a SDU to release + * following any lost SDUs, lost SDU handling should be + * similar to when a valid timestamp for the next SDU + * exists. */ - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, true, timestamp); - sp->sdu_status = next_sdu_status; - err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); + error_sdu_pending = seg_err || + (pdu_err && meta->status == ISOAL_SDU_STATUS_ERRORS); + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, + error_sdu_pending, timestamp); + + if (error_sdu_pending) { + sp->sdu_status = next_sdu_status; + err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); + } break; case ISOAL_CONTINUE: @@ -1339,11 +1360,13 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, */ sp->sdu_status = next_sdu_status; err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, false, timestamp); + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, + error_sdu_pending, timestamp); break; case ISOAL_ERR_SPOOL: - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, false, timestamp); + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, + error_sdu_pending, timestamp); break; } @@ -1353,7 +1376,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } sp->prev_pdu_id = meta->payload_number; - sp->initialized = true; + sp->initialized = 1U; return err; } @@ -1610,6 +1633,10 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, /* Attempt to enqueue the node towards the LL */ status = source_ctx->session.pdu_emit(node_tx, handle); + ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", + source_ctx, node_tx->payload_count, status, + produced_pdu->contents.pdu->len, sdu_fragments); + if (status != ISOAL_STATUS_OK) { /* If it fails, the node will be released and no further attempt * will be possible @@ -1666,6 +1693,7 @@ static isoal_status_t isoal_tx_allocate_pdu(struct isoal_source *source, /* Nothing has been written into buffer yet */ pp->pdu_written = 0; pp->pdu_available = available_len; + pp->pdu_allocated = 1U; LL_ASSERT(available_len > 0); pp->pdu_cnt++; @@ -1708,6 +1736,7 @@ static isoal_status_t isoal_tx_try_emit_pdu(struct isoal_source *source, pp->pdu_written); pp->payload_number++; pp->sdu_fragments = 0; + pp->pdu_allocated = 0U; } return err; @@ -1751,7 +1780,7 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ time_diff = 0; /* Adjust payload number */ - if (IS_ENABLED(CONFIG_BT_CTLR_ISOAL_SN_STRICT) && session->sn) { + if (IS_ENABLED(CONFIG_BT_CTLR_ISOAL_SN_STRICT) && pp->initialized) { /* Not the first SDU in this session, so reference * information should be valid. At this point, the * current payload number should be at the first PDU of @@ -1806,15 +1835,26 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ return sdus_skipped; } -/* NOTE: Use of target_event and grp_ref_point as input from upper layer. +/** + * @brief Fragment received SDU and produce unframed PDUs + * @details Destination source may have an already partially built PDU * - * For unframed: + * @param source_hdl[in] Destination source handle + * @param tx_sdu[in] SDU with packet boundary information + * + * @return Status + * + * @note + * PSN in SDUs for unframed TX: + * + * @par * Before the modification to use the PSN to decide the position of an SDU in a * stream of SDU, the target event was what was used in deciding the event for * each SDU. This meant that there would possibly have been skews on the - * receiver for each SDU and we had trouble with LL/CIS/PER/BV-39-C which + * receiver for each SDU and there were problems with LL/CIS/PER/BV-39-C which * expects clustering within an event. * + * @par * After the change, the PSN is used to decide the position of an SDU in the * stream anchored at the first PSN received. However for the first SDU * (assume that PSN=0), it will be the target event that decides which event @@ -1823,6 +1863,7 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * impacts the event chosen for the first SDU and all subsequent SDUs will be * decided relative to the first. * + * @par * The target event and related group reference point is still used to provide * the ISO-AL with a notion of time, for example when storing information * required for the TX Sync command. For example if for PSN 4, target event is @@ -1832,26 +1873,17 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * for event 7. It is also expected that this value is the latest reference and * is drift compensated. * - * The PSN alone is not sufficient for this because as far as I am aware, host - * and controller have no common reference time for when CIG/BIG event 0 starts. - * Therefore I would expect it is possible to receive PSN 0 in event 2 for - * example. If the target event provided is event 3, then PSN 0 will be - * fragmented into payloads for event 3 and that will serve as the anchor for - * the stream and subsequent SDUs. If for example target event provided was - * event 2 instead, then it could very well be that PSN 0 might not be - * transmitted as is was received midway through event 2 and the payloads - * expired. If this happens then subsequent SDUs might also all be late for - * their transmission slots as they are positioned relative to PSN 0. - */ - -/** - * @brief Fragment received SDU and produce unframed PDUs - * @details Destination source may have an already partially built PDU - * - * @param source_hdl[in] Destination source handle - * @param tx_sdu[in] SDU with packet boundary information - * - * @return Status + * @par + * The PSN alone is not sufficient for this because host and controller have no + * common reference time for when CIG / BIG event 0 starts. Therefore it is + * expected that it is possible to receive PSN 0 in event 2 for example. If the + * target event provided is event 3, then PSN 0 will be fragmented into payloads + * for event 3 and that will serve as the anchor for the stream and subsequent + * SDUs. If for example target event provided was event 2 instead, then it could + * very well be that PSN 0 might not be transmitted as is was received midway + * through event 2 and the payloads expired. If this happens then subsequent + * SDUs might also all be late for their transmission slots as they are + * positioned relative to PSN 0. */ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl, const struct isoal_sdu_tx *tx_sdu) @@ -1881,7 +1913,6 @@ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { - /* Initialize to info provided in SDU */ uint32_t actual_grp_ref_point; uint64_t next_payload_number; uint16_t sdus_skipped; @@ -2062,6 +2093,8 @@ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl zero_length_sdu = false; } + pp->initialized = 1U; + return err; } @@ -2126,6 +2159,9 @@ static isoal_status_t isoal_insert_seg_header_timeoffset(struct isoal_source *so pp->pdu_written += write_size; pp->pdu_available -= write_size; + ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u TO=%u len=%u", + source, write_size, sc, cmplt, time_offset, seg_hdr.len); + return err; } @@ -2163,6 +2199,155 @@ static isoal_status_t isoal_update_seg_header_cmplt_length(struct isoal_source * pp->last_seg_hdr_loc, (uint8_t *) &seg_hdr, PDU_ISO_SEG_HDR_SIZE); + + ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u len=%u", + source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); +} + +/** + * Find the earliest feasible event for transmission capacity is not wasted and + * return information based on that event. + * @param[in] source_hdl Destination source handle + * @param[in] tx_sdu SDU with meta data information + * @param[out] payload_number Updated payload number for the selected event + * @param[out] grp_ref_point Group reference point for the selected event + * @param[out] time_offset Segmentation Time offset to selected event + * @return The number SDUs skipped from the last + */ +static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t source_hdl, + const struct isoal_sdu_tx *tx_sdu, + uint64_t *payload_number, + uint32_t *grp_ref_point, + uint32_t *time_offset) +{ + struct isoal_source_session *session; + struct isoal_pdu_production *pp; + uint32_t actual_grp_ref_point; + uint64_t next_payload_number; + struct isoal_source *source; + uint16_t sdus_skipped; + uint64_t actual_event; + bool time_diff_valid; + uint32_t time_diff; + + source = &isoal_global.source_state[source_hdl]; + session = &source->session; + pp = &source->pdu_production; + + sdus_skipped = 0; + + /* Continue with the current payload unless there is need to change */ + next_payload_number = pp->payload_number; + actual_event = pp->payload_number / session->burst_number; + + ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source, next_payload_number, actual_event); + + /* Get the drift updated group reference point for this event based on + * the actual event being set. This might introduce some errors as the + * group refernce point for future events could drift. However as the + * time offset calculation requires an absolute value, this seems to be + * the best candidate. + */ + if (actual_event != tx_sdu->target_event) { + actual_grp_ref_point = isoal_get_wrapped_time_us(tx_sdu->grp_ref_point, + ((actual_event - tx_sdu->target_event) * session->iso_interval * + ISO_INT_UNIT_US)); + } else { + actual_grp_ref_point = tx_sdu->grp_ref_point; + } + + ISOAL_LOG_DBGV("[%p] Current PL=%llu Evt=%llu Ref=%lu", + source, next_payload_number, actual_event, actual_grp_ref_point); + + if (tx_sdu->sdu_state == BT_ISO_START || + tx_sdu->sdu_state == BT_ISO_SINGLE) { + /* Start of a new SDU */ + + /* Adjust payload number */ + if (pp->initialized) { + /* Not the first SDU in this session, so reference + * information should be valid. . + */ + time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, + tx_sdu->time_stamp, + &time_diff); + + /* Priority is given to the sequence number */ + if (tx_sdu->packet_sn > session->last_input_sn + 1) { + ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source); + sdus_skipped = (tx_sdu->packet_sn - session->last_input_sn) - 1; + + } else if (tx_sdu->packet_sn == session->last_input_sn && + time_diff_valid && time_diff > session->sdu_interval) { + ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", source); + /* Round at mid-point */ + sdus_skipped = ((time_diff + (session->sdu_interval / 2)) / + session->sdu_interval) - 1; + } else { + /* SDU is next in sequence */ + } + + } else { + /* First SDU, align with target event */ + actual_event = tx_sdu->target_event; + actual_grp_ref_point = tx_sdu->grp_ref_point; + + ISOAL_LOG_DBGV("[%p] Use target_event", source); + } + + /* Selecting the event for transmission is done solely based on + * the time stamp and the ability to calculate a valid time + * offset. + */ + + /* Check if time stamp on packet is later than the group + * reference point and find next feasible event for transmission. + * + * BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: + * 3.1 Time_Offset in framed PDUs : + * The Time_Offset shall be a positive value. + */ + while (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || + time_diff == 0) { + /* Advance target to next event */ + actual_event++; + actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, + session->iso_interval * ISO_INT_UNIT_US); + } + + ISOAL_LOG_DBGV("[%p] Chosen PL=%llu Evt=%llu Ref=%lu", + source, (actual_event * session->burst_number), actual_event, + actual_grp_ref_point); + + /* If the event selected is the last event segmented for, then + * it is possible that that some payloads have already been + * released for this event. Segmentation should continue from + * that payload. + */ + next_payload_number = MAX(pp->payload_number, + (actual_event * session->burst_number)); + } + + ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", + source, actual_event, (actual_event * session->burst_number), + actual_grp_ref_point, next_payload_number); + + /* Calculate the time offset */ + time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, + actual_grp_ref_point, &time_diff); + + LL_ASSERT(time_diff_valid); + LL_ASSERT(time_diff > 0); + /* Time difference must be less than the maximum possible + * time-offset of 24-bits. + */ + LL_ASSERT(time_diff <= 0x00FFFFFF); + + *payload_number = next_payload_number; + *grp_ref_point = actual_grp_ref_point; + *time_offset = time_diff; + + return sdus_skipped; } /** @@ -2186,7 +2371,6 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, bool zero_length_sdu; isoal_status_t err; bool padding_pdu; - uint8_t ll_id; source = &isoal_global.source_state[source_hdl]; session = &source->session; @@ -2202,15 +2386,53 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, zero_length_sdu = (packet_available == 0 && tx_sdu->sdu_state == BT_ISO_SINGLE); + ISOAL_LOG_DBGV("[%p] SDU %u len=%u TS=%lu Ref=%lu Evt=%llu Frag=%u", + source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, + tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); + if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { + uint32_t actual_grp_ref_point; + uint64_t next_payload_number; + uint16_t sdus_skipped; + /* Start of a new SDU */ - /* Initialize to info provided in SDU */ - uint32_t actual_grp_ref_point = tx_sdu->grp_ref_point; - uint64_t actual_event = tx_sdu->target_event; - bool time_diff_valid = false; - uint32_t time_diff = 0; + /* Find the best transmission event */ + sdus_skipped = isoal_tx_framed_find_correct_tx_event(source_hdl, tx_sdu, + &next_payload_number, + &actual_grp_ref_point, + &time_offset); + + ISOAL_LOG_DBGV("[%p] %u SDUs skipped.", source, sdus_skipped); + ISOAL_LOG_DBGV("[%p] Starting SDU %u PL=(%llu->%llu) Grp Ref=%lu TO=%lu", + source, tx_sdu->packet_sn, pp->payload_number, next_payload_number, + actual_grp_ref_point, time_offset); + + + if (next_payload_number > pp->payload_number) { + /* Moving to a new payload */ + if (pp->pdu_allocated) { + /* Current PDU in production should be released before + * moving to new event. + */ + ISOAL_LOG_DBGV("[%p] Pending PDU released.\n"); + err |= isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); + } + + while (err == ISOAL_STATUS_OK && next_payload_number > pp->payload_number && + (pp->payload_number % session->burst_number)) { + /* Release padding PDUs for this event */ + err |= isoal_tx_allocate_pdu(source, tx_sdu); + err |= isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); + } + } + + /* Reset PDU production state */ + pp->pdu_state = BT_ISO_START; + + /* Update to new payload number */ + pp->payload_number = next_payload_number; /* Update sequence number for received SDU * @@ -2224,67 +2446,8 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, * with the sequence number in the ISOAL once the Datapath is * configured and the link is established. */ - session->sn++; - - /* Reset PDU production state */ - pp->pdu_state = BT_ISO_START; - - /* Update payload counter in case time has passed since the last - * SDU. This should mean that event count * burst number should - * be greater than the current payload number. In the event of - * an SDU interval smaller than the ISO interval, multiple SDUs - * will be sent in the same event. As such the current payload - * number should be retained. Payload numbers are indexed at 0 - * and valid until the PDU is emitted. - */ - pp->payload_number = MAX(pp->payload_number, - (tx_sdu->target_event * session->burst_number)); - - /* Get actual event for this payload number */ - actual_event = pp->payload_number / session->burst_number; - - /* Get group reference point for this PDU based on the actual - * event being set. This might introduce some errors as the - * group refernce point for future events could drift. However - * as the time offset calculation requires an absolute value, - * this seems to be the best candidate. - */ - if (actual_event > tx_sdu->target_event) { - actual_grp_ref_point = isoal_get_wrapped_time_us(tx_sdu->grp_ref_point, - ((actual_event - tx_sdu->target_event) * session->iso_interval * - ISO_INT_UNIT_US)); - } - - /* Check if time stamp on packet is later than the group - * reference point and adjust targets. This could happen if the - * SDU has been time-stampped at the controller when received - * via HCI. - * - * BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: - * 3.1 Time_Offset in framed PDUs : - * The Time_Offset shall be a positive value. - */ - if (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || - time_diff == 0) { - /* Advance target to next event */ - actual_event++; - actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, - session->iso_interval * ISO_INT_UNIT_US); - - /* Set payload number */ - pp->payload_number = actual_event * session->burst_number; - } - /* Calculate the time offset */ - time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, - actual_grp_ref_point, &time_diff); - LL_ASSERT(time_diff_valid); - LL_ASSERT(time_diff > 0); - /* Time difference must be less than the maximum possible - * time-offset of 24-bits. - */ - LL_ASSERT(time_diff <= 0x00FFFFFF); - time_offset = time_diff; + session->sn += sdus_skipped + 1; /* Store timing info for TX Sync command */ session->tx_time_stamp = actual_grp_ref_point; @@ -2292,6 +2455,10 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Reset PDU fragmentation count for this SDU */ pp->pdu_cnt = 0; + + /* Update input packet number and time stamp */ + session->last_input_sn = tx_sdu->packet_sn; + session->last_input_time_stamp = tx_sdu->time_stamp; } /* PDUs should be created until the SDU fragment has been fragmented or if @@ -2305,6 +2472,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, err |= err_alloc; + ISOAL_LOG_DBGV("[%p] State %s", source, STATE_TO_STR(pp->pdu_state)); if (pp->pdu_state == BT_ISO_START) { /* Start of a new SDU. Segmentation header and time-offset * should be inserted. @@ -2366,15 +2534,13 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Update complete flag in last segmentation header */ err |= isoal_update_seg_header_cmplt_length(source, end_of_sdu, consume_len); - /* LLID is fixed for framed PDUs */ - ll_id = PDU_BIS_LLID_FRAMED; - /* If there isn't sufficient usable space then release the * PDU when the end of the SDU is reached, instead of waiting * for the next SDU. */ bool release_pdu = end_of_sdu && (pp->pdu_available <= ISOAL_TX_SEGMENT_MIN_SIZE); - const isoal_status_t err_emit = isoal_tx_try_emit_pdu(source, release_pdu, ll_id); + const isoal_status_t err_emit = isoal_tx_try_emit_pdu(source, release_pdu, + PDU_BIS_LLID_FRAMED); err |= err_emit; @@ -2392,6 +2558,8 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, zero_length_sdu = false; } + pp->initialized = 1U; + return err; } @@ -2424,9 +2592,9 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t first_event_payload = (session->burst_number * event_count); last_event_payload = (session->burst_number * (event_count + 1ULL)) - 1ULL; - if (pp->pdu_available > 0 && - pp->payload_number <= last_event_payload) { + if (pp->pdu_allocated && pp->payload_number <= last_event_payload) { /* Pending PDU that should be released for framed TX */ + ISOAL_LOG_DBGV("[%p] Prepare PDU released.", source); err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); } @@ -2462,6 +2630,7 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t if (release_padding) { while (!err && !err_alloc && (pp->payload_number < last_event_payload + 1ULL)) { + ISOAL_LOG_DBGV("[%p] Prepare padding PDU release.", source); err_alloc = isoal_tx_allocate_pdu(source, NULL); err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); @@ -2473,6 +2642,7 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t if (pp->payload_number < last_event_payload + 1ULL) { pp->payload_number = last_event_payload + 1ULL; + ISOAL_LOG_DBGV("[%p] Prepare PL updated to %lu.", source, pp->payload_number); } return err; @@ -2500,7 +2670,7 @@ isoal_status_t isoal_tx_sdu_fragment(isoal_source_handle_t source_hdl, /* Set source context active to mutually exclude ISO Event prepare * kick. */ - source->context_active = true; + source->context_active = 1U; if (source->pdu_production.mode != ISOAL_PRODUCTION_MODE_DISABLED) { /* BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: @@ -2520,11 +2690,12 @@ isoal_status_t isoal_tx_sdu_fragment(isoal_source_handle_t source_hdl, } } - source->context_active = false; + source->context_active = 0U; if (source->timeout_trigger) { - source->timeout_trigger = false; + source->timeout_trigger = 0U; if (session->framed) { + ISOAL_LOG_DBGV("[%p] Prepare cb flag trigger", source); isoal_tx_framed_event_prepare_handle(source_hdl, source->timeout_event_count); } @@ -2599,13 +2770,14 @@ void isoal_tx_event_prepare(isoal_source_handle_t source_hdl, * is active. */ source->timeout_event_count = event_count; - source->timeout_trigger = true; + source->timeout_trigger = 1U; if (source->context_active) { return; } - source->timeout_trigger = false; + source->timeout_trigger = 0U; if (session->framed) { + ISOAL_LOG_DBGV("[%p] Prepare call back", source); isoal_tx_framed_event_prepare_handle(source_hdl, event_count); } } diff --git a/subsys/bluetooth/controller/ll_sw/isoal.h b/subsys/bluetooth/controller/ll_sw/isoal.h index 44f3504f1a6..cc69e4a5d53 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.h +++ b/subsys/bluetooth/controller/ll_sw/isoal.h @@ -376,8 +376,6 @@ struct isoal_source_session { uint8_t burst_number; uint8_t pdus_per_sdu; uint8_t max_pdu_size; - int32_t latency_unframed; - int32_t latency_framed; }; struct isoal_pdu_production { @@ -392,6 +390,8 @@ struct isoal_pdu_production { uint64_t seg_hdr_sc:1; uint64_t seg_hdr_length:8; uint64_t sdu_fragments:8; + uint64_t initialized:1; + uint64_t pdu_allocated:1; isoal_pdu_len_t pdu_written; isoal_pdu_len_t pdu_available; /* Location (byte index) of last segmentation header */ From ec2093862784369892b2a386c9399a0c98267858 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Wed, 5 Jul 2023 16:13:20 +0200 Subject: [PATCH 0602/4498] tests: bluetooth: controller: Test for framed TX in consecutive events Changes: -- Included a test to check TX in concesecutive events irrespective of the input target event -- Updated expected output of current tests for change in framed RX error handling which waiting for the start of an event Signed-off-by: Nirosharn Amarasinghe --- .../ctrl_isoal/src/sub_sets/isoal_test_rx.c | 109 +-- .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 754 ++++++++++++++---- 2 files changed, 682 insertions(+), 181 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c index 2ce8862e1d4..5a3c60e0854 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c @@ -8332,27 +8332,30 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err1) */ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) { + const uint8_t test_data_size = 33; + const uint8_t max_sdu_burst = 2; + + struct rx_sdu_frag_buffer rx_sdu_frag_buf[max_sdu_burst]; + struct isoal_sdu_buffer sdu_buffer[max_sdu_burst]; + isoal_sdu_status_t collated_status[max_sdu_burst]; struct rx_pdu_meta_buffer rx_pdu_meta_buf; - struct rx_sdu_frag_buffer rx_sdu_frag_buf; - struct isoal_sdu_buffer sdu_buffer; - isoal_sdu_status_t collated_status; + isoal_sdu_len_t sdu_size[max_sdu_burst]; + uint16_t total_sdu_size[max_sdu_burst]; + uint32_t sdu_timestamp[max_sdu_burst]; + uint8_t testdata[test_data_size]; isoal_sink_handle_t sink_hdl; uint32_t stream_sync_delay; uint32_t group_sync_delay; - isoal_sdu_len_t sdu_size; uint8_t iso_interval_int; uint16_t pdu_data_loc[5]; uint32_t iso_interval_us; uint64_t payload_number; - uint16_t total_sdu_size; uint32_t sdu_timeoffset; uint32_t pdu_timestamp; - uint32_t sdu_timestamp; uint16_t testdata_indx; uint16_t testdata_size; uint32_t sdu_interval; isoal_sdu_cnt_t seqn; - uint8_t testdata[33]; isoal_status_t err; uint32_t latency; uint8_t role; @@ -8371,12 +8374,14 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) /* PDU 1 -------------------------------------------------------------*/ isoal_test_init_rx_pdu_buffer(&rx_pdu_meta_buf); - isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf); - init_test_data_buffer(testdata, 33); + isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf[0]); + init_test_data_buffer(testdata, test_data_size); memset(pdu_data_loc, 0, sizeof(pdu_data_loc)); - sdu_buffer.dbuf = &rx_sdu_frag_buf; - sdu_buffer.size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; + sdu_buffer[0].dbuf = &rx_sdu_frag_buf[0]; + sdu_buffer[0].size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; + sdu_buffer[1].dbuf = &rx_sdu_frag_buf[1]; + sdu_buffer[1].size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; payload_number = 1000 * BN; pdu_timestamp = 9249; latency = calc_rx_latency_by_role(role, @@ -8388,13 +8393,13 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) group_sync_delay); sdu_timeoffset = group_sync_delay - 50; /* PDU will have errors. Time stamp is only an approximation */ - sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency - iso_interval_us); + sdu_timestamp[0] = (uint32_t)((int64_t)pdu_timestamp + latency - iso_interval_us); seqn = 0; testdata_indx = 0; testdata_size = 23; - sdu_size = 0; - total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); - collated_status = + sdu_size[0] = 0; + total_sdu_size[0] = COLLATED_RX_SDU_INFO(sdu_size[0], sdu_size[0]); + collated_status[0] = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); sink_hdl = basic_rx_test_setup(0xADAD, /* Handle */ @@ -8418,7 +8423,7 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) &rx_pdu_meta_buf.pdu_meta); /* Set callback function return values */ - push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer); + push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer[0]); sink_sdu_alloc_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_write_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_emit_test_fake.return_val = ISOAL_STATUS_OK; @@ -8428,25 +8433,14 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); /* Test recombine (Black Box) */ - /* A new SDU should be allocated */ - ZASSERT_ISOAL_SDU_ALLOC_TEST(val, - &isoal_global.sink_state[sink_hdl], /* Sink */ - &rx_pdu_meta_buf.pdu_meta); /* PDU */ + /* A new SDU should not be allocated */ + ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(0); /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); - /* SDU should be emitted */ - ZASSERT_ISOAL_SDU_EMIT_TEST(val, - &isoal_global.sink_state[sink_hdl], /* Sink */ - BT_ISO_SINGLE, /* Frag state */ - sdu_size, /* Frag size */ - ISOAL_SDU_STATUS_LOST_DATA, /* Frag status */ - sdu_timestamp, /* Timestamp */ - seqn, /* Seq. number */ - sdu_buffer.dbuf, /* Buffer */ - sdu_buffer.size, /* Buffer size */ - total_sdu_size, /* Total size */ - collated_status); /* SDU status */ + /* SDU should not be emitted */ + ZASSERT_ISOAL_SDU_EMIT_TEST_CALL_COUNT(0); /* Test recombine (White Box) */ zassert_equal(isoal_global.sink_state[sink_hdl].sdu_production.fsm, @@ -8457,18 +8451,17 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) /* PDU 2 -------------------------------------------------------------*/ isoal_test_init_rx_pdu_buffer(&rx_pdu_meta_buf); - isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf); + isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf[1]); payload_number++; sdu_timeoffset = get_next_time_offset(sdu_timeoffset, iso_interval_us, sdu_interval, false); - sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency - sdu_timeoffset); - seqn++; + sdu_timestamp[1] = (uint32_t)((int64_t)pdu_timestamp + latency - sdu_timeoffset); testdata_indx = testdata_size; testdata_size += 10; - sdu_size = 10; - total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); - collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_VALID, ISOAL_SDU_STATUS_VALID); + sdu_size[1] = 10; + total_sdu_size[1] = COLLATED_RX_SDU_INFO(sdu_size[1], sdu_size[1]); + collated_status[1] = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_VALID, ISOAL_SDU_STATUS_VALID); isoal_test_create_framed_pdu_base(payload_number, pdu_timestamp, @@ -8480,7 +8473,7 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) &rx_pdu_meta_buf.pdu_meta); /* Set callback function return values */ - push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer); + push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer[1]); sink_sdu_alloc_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_write_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_emit_test_fake.return_val = ISOAL_STATUS_OK; @@ -8490,14 +8483,38 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); /* Test recombine (Black Box) */ + /* SDU 0 -------------------------------------------------------------*/ + /* A new SDU should be allocated */ + ZASSERT_ISOAL_SDU_ALLOC_TEST(history[0], + &isoal_global.sink_state[sink_hdl], /* Sink */ + &rx_pdu_meta_buf.pdu_meta); /* PDU */ + + /* SDU payload should not be written */ + + /* SDU should be emitted */ + ZASSERT_ISOAL_SDU_EMIT_TEST(history[0], + &isoal_global.sink_state[sink_hdl], /* Sink */ + BT_ISO_SINGLE, /* Frag state */ + sdu_size[0], /* Frag size */ + ISOAL_SDU_STATUS_LOST_DATA, /* Frag status */ + sdu_timestamp[0], /* Timestamp */ + seqn, /* Seq. number */ + sdu_buffer[0].dbuf, /* Buffer */ + sdu_buffer[0].size, /* Buffer size */ + total_sdu_size[0], /* Total size */ + collated_status[0]); /* SDU status */ + + /* SDU 1 -------------------------------------------------------------*/ + seqn++; /* A new SDU should be allocated */ ZASSERT_ISOAL_SDU_ALLOC_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ + &rx_sdu_frag_buf[1], /* SDU buffer */ &rx_pdu_meta_buf.pdu[3 + pdu_data_loc[1]], /* PDU payload */ (testdata_size - testdata_indx)); /* Size */ @@ -8506,14 +8523,14 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ BT_ISO_SINGLE, /* Frag state */ - sdu_size, /* Frag size */ + sdu_size[1], /* Frag size */ ISOAL_SDU_STATUS_VALID, /* Frag status */ - sdu_timestamp, /* Timestamp */ + sdu_timestamp[1], /* Timestamp */ seqn, /* Seq. number */ - sdu_buffer.dbuf, /* Buffer */ - sdu_buffer.size, /* Buffer size */ - total_sdu_size, /* Total size */ - collated_status); /* SDU status */ + sdu_buffer[1].dbuf, /* Buffer */ + sdu_buffer[1].size, /* Buffer size */ + total_sdu_size[1], /* Total size */ + collated_status[1]); /* SDU status */ /* Test recombine (White Box) */ zassert_equal(isoal_global.sink_state[sink_hdl].sdu_production.fsm, diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index fe375b7accd..dc21c9b5d61 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -111,7 +111,8 @@ static void push_custom_source_pdu_write_test_sdu_payload(const uint8_t *data, c } static void check_next_custom_source_pdu_write_test_sdu_payload(const uint8_t *data, - const size_t length) + const size_t length, + const uint32_t line) { size_t pos = custom_source_pdu_write_test_sdu_payloads.pos; size_t buffer_size = custom_source_pdu_write_test_sdu_payloads.buffer_size; @@ -125,7 +126,8 @@ static void check_next_custom_source_pdu_write_test_sdu_payload(const uint8_t *d for (size_t i = 0; i < custom_source_pdu_write_test_sdu_payloads.out_size[pos]; i++) { zassert_equal(custom_source_pdu_write_test_sdu_payloads.out[pos][i], data[i], - "deviation at index %u, expected %u, got %u", + "[Line %lu] deviation at index %u, expected %u, got %u", + line, i, data[i], custom_source_pdu_write_test_sdu_payloads.out[pos][i]); @@ -193,7 +195,7 @@ static isoal_status_t custom_source_pdu_write_test(struct isoal_pdu_buffer *pdu_ _consume_len, \ source_pdu_write_test_fake.arg3_##_typ); \ check_next_custom_source_pdu_write_test_sdu_payload((const uint8_t *)_sdu_payload, \ - _consume_len); + _consume_len, __LINE__); #define ZASSERT_PDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ @@ -422,7 +424,7 @@ static isoal_source_handle_t basic_tx_test_setup(uint16_t handle, burst_number, flush_timeout, max_octets, - (iso_interval_int * CONN_INT_UNIT_US), + (iso_interval_int * ISO_INT_UNIT_US), sdu_interval, stream_sync_delay, group_sync_delay); @@ -536,8 +538,8 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_destroy) max_octets = 40; sdu_interval_int = 1; iso_interval_int = 1; - iso_interval = iso_interval_int * CONN_INT_UNIT_US; - sdu_interval = sdu_interval_int * CONN_INT_UNIT_US; + iso_interval = iso_interval_int * ISO_INT_UNIT_US; + sdu_interval = sdu_interval_int * ISO_INT_UNIT_US; stream_sync_delay = iso_interval - 200; group_sync_delay = iso_interval - 50; @@ -606,8 +608,8 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_destroy) max_octets += max_octets / 2; sdu_interval_int++; iso_interval_int = iso_interval_int * sdu_interval_int; - sdu_interval = (sdu_interval_int * CONN_INT_UNIT_US) - (framed ? 100 : 0); - iso_interval = iso_interval_int * CONN_INT_UNIT_US; + sdu_interval = (sdu_interval_int * ISO_INT_UNIT_US) - (framed ? 100 : 0); + iso_interval = iso_interval_int * ISO_INT_UNIT_US; stream_sync_delay = iso_interval - (200 * i); group_sync_delay = iso_interval - 50; } @@ -654,9 +656,9 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_err) flush_timeout = 1; framed = false; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; - stream_sync_delay = CONN_INT_UNIT_US - 200; - group_sync_delay = CONN_INT_UNIT_US - 50; + sdu_interval = ISO_INT_UNIT_US; + stream_sync_delay = ISO_INT_UNIT_US - 200; + group_sync_delay = ISO_INT_UNIT_US - 50; res = isoal_init(); zassert_equal(res, ISOAL_STATUS_OK, "res = 0x%02x", res); @@ -747,12 +749,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -764,7 +766,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -875,12 +877,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -892,7 +894,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX; @@ -993,12 +995,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1010,7 +1012,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = 100; testdata_indx = 0; testdata_size = 100; @@ -1152,12 +1154,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1169,7 +1171,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX / 3; @@ -1357,12 +1359,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -1378,7 +1380,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -1689,12 +1691,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1821,7 +1823,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Check TX Sync info */ tx_sync_seq_expected = 2; - tx_sync_timestamp_expected = (iso_interval_int * CONN_INT_UNIT_US) - 1; + tx_sync_timestamp_expected = (iso_interval_int * ISO_INT_UNIT_US) - 1; tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -1870,12 +1872,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 4; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -1891,7 +1893,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -2264,12 +2266,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 8; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -2289,7 +2291,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -2739,12 +2741,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -2764,7 +2766,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = 0; testdata_indx = 0; testdata_size = 0; @@ -2907,12 +2909,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -2924,7 +2926,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -3024,12 +3026,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3041,7 +3043,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -3153,12 +3155,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US / 2; + sdu_interval = ISO_INT_UNIT_US / 2; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ /* Sets initial fragmentation status */ @@ -3171,7 +3173,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) event_number = 2000; sdu_packet_number = (event_number * BN); sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = 23; testdata_indx = 0; testdata_size = 23; @@ -3253,9 +3255,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); sdu_packet_number += 29; - sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) - sdu_interval; + sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) - sdu_interval; event_number += 15; - ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3303,7 +3305,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 29; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3319,9 +3321,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); /* Same SDU packet sequence number for testing */ /* Time stamp just before the exact multiple of the SDU interval */ - sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) - 1; + sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) - 1; event_number += 15; - ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3369,7 +3371,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 30; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3388,9 +3390,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) * +1 (reset to exact multiple of SDU interval from the last SDU) * +1 (push the time stamp 1us beyond the multiple mark) */ - sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) + 1 + 1; + sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) + 1 + 1; event_number += 15; - ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3438,7 +3440,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 30; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3490,12 +3492,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3510,7 +3512,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -3645,12 +3647,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3665,7 +3667,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -3791,12 +3793,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3810,7 +3812,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = 100 - ((3 * PDU_ISO_SEG_HDR_SIZE) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; testdata_size = 100 - ((3 * PDU_ISO_SEG_HDR_SIZE) + PDU_ISO_SEG_TIMEOFFSET_SIZE); @@ -4022,12 +4024,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -4042,7 +4044,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4281,12 +4283,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -4305,7 +4307,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4583,12 +4585,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 4; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -4607,7 +4609,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4851,7 +4853,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_packet_number++; event_number = 2000; sdu_timestamp = 9249 + sdu_interval; - ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -5115,12 +5117,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 6; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -5137,7 +5139,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = testdata_size_max; testdata_indx = 0; testdata_size = testdata_size_max / number_of_sdu_frags; @@ -5374,7 +5376,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number++; event_number = 2000; sdu_timestamp = 9249 + sdu_interval; - ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = testdata_size_max; testdata_indx = 0; testdata_size = testdata_size_max / number_of_sdu_frags; @@ -5661,12 +5663,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -5682,7 +5684,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -5800,7 +5802,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) /* PDU 2 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * CONN_INT_UNIT_US; + ref_point += iso_interval_int * ISO_INT_UNIT_US; payload_number++; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -5890,12 +5892,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -5955,7 +5957,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) /* PDU 1 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * CONN_INT_UNIT_US; + ref_point += iso_interval_int * ISO_INT_UNIT_US; payload_number = event_number * BN; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -6046,12 +6048,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6185,7 +6187,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) /* PDU 2 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * CONN_INT_UNIT_US; + ref_point += iso_interval_int * ISO_INT_UNIT_US; payload_number++; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -6270,12 +6272,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6288,7 +6290,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6413,12 +6415,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -6439,7 +6441,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6598,12 +6600,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6618,7 +6620,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6726,12 +6728,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = CONN_INT_UNIT_US + 50; + sdu_interval = ISO_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6746,7 +6748,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6879,8 +6881,8 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6893,7 +6895,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_packet_number = 0; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -7056,7 +7058,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) event_number++; sdu_packet_number++; sdu_timestamp = sdu_timestamp + sdu_interval; - ref_point = ref_point + (iso_interval_int * CONN_INT_UNIT_US); + ref_point = ref_point + (iso_interval_int * ISO_INT_UNIT_US); sdu_total_size = 20; testdata_indx = testdata_size; testdata_size += 20; @@ -7129,6 +7131,488 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) isoal_global.source_state[source_hdl].session.handle); } +/** + * Test Suite : TX framed SDU segmentation + * + * Tests that consecutive events are used irrespective of the target event info + * as long as they are feasible. + */ +ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) +{ + const uint8_t number_of_pdus = 3; + const uint8_t sdu_fragment_data_size = 25; + const uint8_t testdata_size_max = sdu_fragment_data_size * 4; + /* Two SDUs and one that would overflow into a new PDU */ + const uint8_t number_of_seg_hdr_buf = 3; + + struct tx_pdu_meta_buffer tx_pdu_meta_buf[number_of_pdus]; + struct pdu_iso_sdu_sh seg_hdr[number_of_seg_hdr_buf]; + struct isoal_pdu_buffer pdu_buffer[number_of_pdus]; + struct tx_sdu_frag_buffer tx_sdu_frag_buf; + uint8_t testdata[testdata_size_max]; + isoal_source_handle_t source_hdl; + isoal_sdu_len_t sdu_total_size; + isoal_pdu_len_t pdu_write_end; + uint32_t stream_sync_delay; + uint64_t sdu_packet_number; + uint32_t group_sync_delay; + uint64_t pdu_event_number; + uint8_t iso_interval_int; + uint32_t iso_interval_us; + uint64_t payload_number; + uint32_t pdu_ref_point; + uint32_t sdu_timestamp; + uint16_t testdata_indx; + uint16_t testdata_size; + uint16_t pdu_write_loc; + uint16_t sdu_read_loc; + uint64_t event_number; + uint32_t sdu_interval; + uint8_t sdu_fragments; + uint16_t pdu_hdr_loc; + uint32_t ref_point; + isoal_status_t err; + uint8_t max_octets; + uint8_t role; + uint8_t BN; + uint8_t FT; + + /* Settings */ + role = BT_CONN_ROLE_PERIPHERAL; + iso_interval_int = 1; + iso_interval_us = iso_interval_int * ISO_INT_UNIT_US; + sdu_interval = ISO_INT_UNIT_US - 50; /* Less than an ISO interval */ + max_octets = TEST_TX_PDU_PAYLOAD_MAX; + BN = 2; + FT = 1; + stream_sync_delay = iso_interval_us - 200; + group_sync_delay = iso_interval_us - 50; + + /* SDU 0 -------------------------------------------------------------*/ + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[1]); + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[2]); + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + init_test_data_buffer(testdata, testdata_size_max); + (void)memset(&seg_hdr, 0, sizeof(seg_hdr)); + pdu_buffer[0].handle = (void *)&tx_pdu_meta_buf[0].node_tx; + pdu_buffer[0].pdu = (struct pdu_iso *)tx_pdu_meta_buf[0].node_tx.pdu; + pdu_buffer[0].size = TEST_TX_PDU_PAYLOAD_MAX; + pdu_buffer[1].handle = (void *)&tx_pdu_meta_buf[1].node_tx; + pdu_buffer[1].pdu = (struct pdu_iso *)tx_pdu_meta_buf[1].node_tx.pdu; + pdu_buffer[1].size = TEST_TX_PDU_PAYLOAD_MAX; + pdu_buffer[2].handle = (void *)&tx_pdu_meta_buf[2].node_tx; + pdu_buffer[2].pdu = (struct pdu_iso *)tx_pdu_meta_buf[2].node_tx.pdu; + pdu_buffer[2].size = TEST_TX_PDU_PAYLOAD_MAX; + sdu_packet_number = 0; + event_number = 5; + pdu_event_number = event_number; + sdu_timestamp = 9249; + ref_point = sdu_timestamp + iso_interval_us; + pdu_ref_point = ref_point; + sdu_total_size = sdu_fragment_data_size; + testdata_indx = 0; + testdata_size = sdu_fragment_data_size; + sdu_fragments = 0; + + source_hdl = basic_tx_test_setup(0xADAD, /* Handle */ + role, /* Role */ + true, /* Framed */ + BN, /* BN */ + FT, /* FT */ + max_octets, /* max_octets */ + sdu_interval, /* SDU Interval */ + iso_interval_int, /* ISO Interval */ + stream_sync_delay, /* Stream Sync Delay */ + group_sync_delay); /* Group Sync Delay */ + + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + sdu_total_size, + sdu_packet_number, + sdu_timestamp, + ref_point, + event_number, + &tx_sdu_frag_buf.sdu_tx); + + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[1]); + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[1]); + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[2]); + SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); + PDU_ALLOC_TEST_RETURNS(ISOAL_STATUS_OK); + PDU_WRITE_TEST_RETURNS(ISOAL_STATUS_OK); + PDU_EMIT_TEST_RETURNS(ISOAL_STATUS_OK); + PDU_RELEASE_TEST_RETURNS(ISOAL_STATUS_OK); + + err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); + + zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); + + /* Test segmentation (Black Box) */ + /* Valid PDUs */ + /* PDU 0 */ + payload_number = event_number * BN; + seg_hdr[0].sc = 0; + seg_hdr[0].cmplt = 0; + seg_hdr[0].timeoffset = pdu_ref_point - sdu_timestamp; + seg_hdr[0].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; + pdu_hdr_loc = 0; + pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; + sdu_read_loc = 0; + pdu_write_end = sdu_fragment_data_size + pdu_write_loc; + sdu_fragments++; + + ZASSERT_PDU_WRITE_TEST(history[0], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[0], + (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); + + ZASSERT_PDU_WRITE_TEST(history[1], + pdu_buffer[0], + pdu_write_loc, + &testdata[sdu_read_loc], + (pdu_write_end - pdu_write_loc)); + + seg_hdr[0].cmplt = 1; + seg_hdr[0].len += (pdu_write_end - pdu_write_loc); + + ZASSERT_PDU_WRITE_TEST(history[2], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[0], + PDU_ISO_SEG_HDR_SIZE); + + /* PDU should not be emitted */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(0); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* SDU 1 -------------------------------------------------------------*/ + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + sdu_packet_number++; + event_number += 2; + ref_point += iso_interval_us * 2; + sdu_timestamp += sdu_interval; + testdata_indx = testdata_size; + testdata_size += sdu_fragment_data_size; + + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + sdu_total_size, + sdu_packet_number, + sdu_timestamp, + ref_point, + event_number, + &tx_sdu_frag_buf.sdu_tx); + + err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); + + zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); + + /* Test segmentation (Black Box) */ + /* Valid PDUs */ + /* PDU 10 */ + pdu_hdr_loc = pdu_write_end; + seg_hdr[1].sc = 0; + seg_hdr[1].cmplt = 0; + seg_hdr[1].timeoffset = pdu_ref_point - sdu_timestamp; + seg_hdr[1].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; + pdu_write_loc = pdu_write_end + (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); + pdu_write_end = TEST_TX_PDU_PAYLOAD_MAX; + sdu_read_loc = testdata_indx; + + ZASSERT_PDU_WRITE_TEST(history[3], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[1], + (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); + + ZASSERT_PDU_WRITE_TEST(history[4], + pdu_buffer[0], + pdu_write_loc, + &testdata[sdu_read_loc], + (pdu_write_end - pdu_write_loc)); + + /* PDU should not be allocated */ + + seg_hdr[1].len += (pdu_write_end - pdu_write_loc); + + ZASSERT_PDU_WRITE_TEST(history[5], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[1], + PDU_ISO_SEG_HDR_SIZE); + + ZASSERT_PDU_EMIT_TEST(history[0], + &tx_pdu_meta_buf[0].node_tx, + payload_number, + sdu_fragments, + PDU_BIS_LLID_FRAMED, + pdu_write_end, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* PDU 11 */ + payload_number++; + seg_hdr[2].sc = 1; + seg_hdr[2].cmplt = 0; + seg_hdr[2].timeoffset = 0; + seg_hdr[2].len = 0; + sdu_read_loc += (pdu_write_end - pdu_write_loc); + pdu_hdr_loc = 0; + pdu_write_end = testdata_size - testdata_indx - (pdu_write_end - pdu_write_loc) + + PDU_ISO_SEG_HDR_SIZE; + pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; + sdu_fragments = 1; + + ZASSERT_PDU_WRITE_TEST(history[6], + pdu_buffer[1], + pdu_hdr_loc, + &seg_hdr[2], + PDU_ISO_SEG_HDR_SIZE); + + ZASSERT_PDU_WRITE_TEST(history[7], + pdu_buffer[1], + pdu_write_loc, + &testdata[sdu_read_loc], + (pdu_write_end - pdu_write_loc)); + + seg_hdr[2].cmplt = 1; + seg_hdr[2].len += (pdu_write_end - pdu_write_loc); + + ZASSERT_PDU_WRITE_TEST(history[8], + pdu_buffer[1], + pdu_hdr_loc, + &seg_hdr[2], + PDU_ISO_SEG_HDR_SIZE); + + /* PDU should not be emitted */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(1); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* SDU 2 -------------------------------------------------------------*/ + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + sdu_packet_number++; + event_number += 2; + ref_point += iso_interval_us * 2; + sdu_timestamp += sdu_interval; + testdata_indx = testdata_size; + testdata_size += sdu_fragment_data_size; + + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + sdu_total_size, + sdu_packet_number, + sdu_timestamp, + ref_point, + event_number, + &tx_sdu_frag_buf.sdu_tx); + + err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); + + zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); + + /* Test segmentation (Black Box) */ + /* Valid PDUs */ + /* PDU 11 */ + + ZASSERT_PDU_EMIT_TEST(history[1], + &tx_pdu_meta_buf[1].node_tx, + payload_number, + sdu_fragments, + PDU_BIS_LLID_FRAMED, + pdu_write_end, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* PDU 12 */ + payload_number++; + pdu_event_number++; + pdu_ref_point += iso_interval_us; + seg_hdr[0].sc = 0; + seg_hdr[0].cmplt = 0; + seg_hdr[0].timeoffset = pdu_ref_point - sdu_timestamp; + seg_hdr[0].len = 3; + sdu_read_loc = testdata_indx; + pdu_hdr_loc = 0; + pdu_write_end = testdata_size - testdata_indx + PDU_ISO_SEG_HDR_SIZE + + PDU_ISO_SEG_TIMEOFFSET_SIZE; + pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; + sdu_fragments = 1; + + ZASSERT_PDU_WRITE_TEST(history[9], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[0], + (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); + + ZASSERT_PDU_WRITE_TEST(history[10], + pdu_buffer[0], + pdu_write_loc, + &testdata[sdu_read_loc], + (pdu_write_end - pdu_write_loc)); + + seg_hdr[0].cmplt = 1; + seg_hdr[0].len += (pdu_write_end - pdu_write_loc); + + ZASSERT_PDU_WRITE_TEST(history[11], + pdu_buffer[0], + pdu_hdr_loc, + &seg_hdr[0], + PDU_ISO_SEG_HDR_SIZE); + + /* PDU should not be emitted */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(2); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* Send Event Timeout ----------------------------------------------- */ + isoal_tx_event_prepare(source_hdl, pdu_event_number - 1); + + /* PDU should not be emitted */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(2); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* SDU 3 -------------------------------------------------------------*/ + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[1]); + isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[2]); + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + sdu_packet_number++; + event_number += 2; + ref_point += iso_interval_us * 2; + sdu_timestamp += sdu_interval; + sdu_total_size = sdu_fragment_data_size; + testdata_indx = testdata_size; + testdata_size += sdu_fragment_data_size; + + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + sdu_total_size, + sdu_packet_number, + sdu_timestamp, + ref_point, + event_number, + &tx_sdu_frag_buf.sdu_tx); + + err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); + + zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); + + /* Test segmentation (Black Box) */ + /* Valid PDUs */ + /* PDU 12 */ + ZASSERT_PDU_EMIT_TEST(history[2], + &tx_pdu_meta_buf[0].node_tx, + payload_number, + sdu_fragments, + PDU_BIS_LLID_FRAMED, + pdu_write_end, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU 13 */ + payload_number++; + + /* Padding PDU */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(4); + ZASSERT_PDU_EMIT_TEST(history[3], + &tx_pdu_meta_buf[1].node_tx, + payload_number, + 0, + PDU_BIS_LLID_FRAMED, + 0, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* PDU 14 */ + payload_number++; + pdu_event_number++; + pdu_ref_point += iso_interval_us; + seg_hdr[1].sc = 0; + seg_hdr[1].cmplt = 0; + seg_hdr[1].timeoffset = pdu_ref_point - sdu_timestamp; + seg_hdr[1].len = 3; + sdu_read_loc = testdata_indx; + pdu_hdr_loc = 0; + pdu_write_end = testdata_size - testdata_indx + PDU_ISO_SEG_HDR_SIZE + + PDU_ISO_SEG_TIMEOFFSET_SIZE; + pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; + sdu_fragments = 1; + + ZASSERT_PDU_WRITE_TEST(history[12], + pdu_buffer[2], + pdu_hdr_loc, + &seg_hdr[1], + PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); + + ZASSERT_PDU_WRITE_TEST(history[13], + pdu_buffer[2], + pdu_write_loc, + &testdata[sdu_read_loc], + (pdu_write_end - pdu_write_loc)); + + seg_hdr[1].cmplt = 1; + seg_hdr[1].len += (pdu_write_end - pdu_write_loc); + + ZASSERT_PDU_WRITE_TEST(history[14], + pdu_buffer[2], + pdu_hdr_loc, + &seg_hdr[1], + PDU_ISO_SEG_HDR_SIZE); + + /* PDU should not be emitted */ + ZASSERT_PDU_EMIT_TEST_CALL_COUNT(4); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); + + /* Send Event Timeout ----------------------------------------------- */ + isoal_tx_event_prepare(source_hdl, pdu_event_number); + + + ZASSERT_PDU_EMIT_TEST(history[4], + &tx_pdu_meta_buf[2].node_tx, + payload_number, + sdu_fragments, + PDU_BIS_LLID_FRAMED, + pdu_write_end, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU 5 */ + payload_number++; + + /* Padding PDU */ + ZASSERT_PDU_EMIT_TEST(history[5], + &tx_pdu_meta_buf[0].node_tx, + payload_number, + 0, + PDU_BIS_LLID_FRAMED, + 0, + isoal_global.source_state[source_hdl].session.handle); + + /* PDU release not expected (No Error) */ + ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); +} + /** * Test Suite : TX framed EBQ test IAL-CIS-FRA-PER-BV07C * @@ -7173,8 +7657,8 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -7187,7 +7671,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_packet_number = 0; event_number = 0; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; sdu_total_size = 10; testdata_indx = 0; testdata_size = 10; @@ -7350,7 +7834,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) event_number++; sdu_packet_number++; sdu_timestamp = sdu_timestamp + sdu_interval; - ref_point = ref_point + (iso_interval_int * CONN_INT_UNIT_US); + ref_point = ref_point + (iso_interval_int * ISO_INT_UNIT_US); sdu_total_size = 20; testdata_indx = testdata_size; testdata_size += 20; From 31df0ef80b50cad0cd28cac82888b49eaf80ee2b Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Fri, 14 Jul 2023 16:57:37 +0200 Subject: [PATCH 0603/4498] Bluetooth: controller: corrected time-offset for endianness Changes: -- Corrected reading and writing time offset in framed segment header to account for endianness -- Corrected bit positioning of time offset bit field in the segment header structure definition -- Fixed upstream Zephyr BSIM test build failure due to debug logging 39-bit variable Signed-off-by: Nirosharn Amarasinghe --- subsys/bluetooth/controller/ll_sw/isoal.c | 12 +++++++----- subsys/bluetooth/controller/ll_sw/pdu.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 110a7aa901e..00bc40504f7 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -16,6 +16,8 @@ #include #include +#include + #include "util/memq.h" #include "hal/ccm.h" @@ -1158,7 +1160,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, case ISOAL_START: if (!sc) { /* Start segment, included time-offset */ - timeoffset = seg_hdr->timeoffset; + timeoffset = sys_le24_to_cpu(seg_hdr->timeoffset); anchorpoint = meta->timestamp; latency = session->sdu_sync_const; timestamp = isoal_get_wrapped_time_us(anchorpoint, @@ -1215,7 +1217,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, if (!sc) { /* Start segment, included time-offset */ - timeoffset = seg_hdr->timeoffset; + timeoffset = sys_le24_to_cpu(seg_hdr->timeoffset); anchorpoint = meta->timestamp; latency = session->sdu_sync_const; timestamp = isoal_get_wrapped_time_us(anchorpoint, @@ -1634,7 +1636,7 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, status = source_ctx->session.pdu_emit(node_tx, handle); ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", - source_ctx, node_tx->payload_count, status, + source_ctx, payload_number, status, produced_pdu->contents.pdu->len, sdu_fragments); if (status != ISOAL_STATUS_OK) { @@ -2479,7 +2481,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, */ err |= isoal_insert_seg_header_timeoffset(source, false, false, - time_offset); + sys_cpu_to_le24(time_offset)); pp->pdu_state = BT_ISO_CONT; } else if (!padding_pdu && pp->pdu_state == BT_ISO_CONT && pp->pdu_written == 0) { /* Continuing an SDU in a new PDU. Segmentation header @@ -2487,7 +2489,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, */ err |= isoal_insert_seg_header_timeoffset(source, true, false, - 0); + sys_cpu_to_le24(0)); } /* diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index ceeb9ca12e7..93e50e1ebcc 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -1018,8 +1018,8 @@ struct pdu_iso_sdu_sh { uint8_t len; /* Note, timeoffset only available in first segment of sdu */ - uint32_t payload:8; uint32_t timeoffset:24; + uint32_t payload:8; #endif /* CONFIG_LITTLE_ENDIAN */ } __packed; From 05ce650c856ec98ccbdaff7a72ccfe6ab33ad405 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Mon, 17 Jul 2023 16:19:46 +0200 Subject: [PATCH 0604/4498] test: bluetooth: controller: Updated ISO-AL tests to cover endianness Changes: -- Changed RX tests and one TX test to cover endianness of the framed segment header fields -- Updated RX debug PDU print to include framed segment details Signed-off-by: Nirosharn Amarasinghe --- .../ctrl_isoal/src/isoal_test_common.c | 12 ++--- .../ctrl_isoal/src/isoal_test_debug.c | 44 ++++++++++++++++++- tests/bluetooth/ctrl_isoal/src/main.c | 2 + .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 36 ++++++++------- 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c index a20ba5fd084..35947656336 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c @@ -23,6 +23,7 @@ #include #include +#include #include "util/memq.h" @@ -109,7 +110,7 @@ void isoal_test_create_unframed_pdu(uint8_t llid, uint16_t isoal_test_insert_segment(bool sc, bool cmplt, uint32_t time_offset, uint8_t *dataptr, uint8_t length, struct isoal_pdu_rx *pdu_meta) { - struct pdu_iso_sdu_sh seg_hdr; + uint8_t seg_hdr[PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE]; uint16_t pdu_payload_size; uint8_t hdr_write_size; uint16_t pdu_data_loc; @@ -122,12 +123,13 @@ uint16_t isoal_test_insert_segment(bool sc, bool cmplt, uint32_t time_offset, ui zassert_true(pdu_payload_size <= TEST_RX_PDU_PAYLOAD_MAX, "pdu_payload_size (%d)", pdu_payload_size); - seg_hdr.sc = sc; - seg_hdr.cmplt = cmplt; - seg_hdr.len = length + (sc ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); + /* Write header independent of endian dependent structures */ + WRITE_BIT(seg_hdr[0], 0, sc); /* sc */ + WRITE_BIT(seg_hdr[0], 1, cmplt); /* cmplt */ + seg_hdr[1] = length + (sc ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); if (!sc) { - seg_hdr.timeoffset = time_offset; + sys_put_le24(time_offset, &seg_hdr[PDU_ISO_SEG_HDR_SIZE]); } memcpy(&pdu_meta->pdu->payload[pdu_meta->pdu->len], &seg_hdr, hdr_write_size); diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c index 464d2586598..734af1ad7c0 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c @@ -52,6 +52,12 @@ void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta) { zassert_not_null(pdu_meta, ""); + struct pdu_iso *pdu; + uint8_t seg_length; + + pdu = pdu_meta->pdu; + seg_length = 0; + PRINT("\n"); PRINT("PDU %04u (%10u) | %12s [%10s] %03u: ", (uint32_t) pdu_meta->meta->payload_number, @@ -60,8 +66,42 @@ void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta) DU_ERR_TO_STR(pdu_meta->meta->status), pdu_meta->pdu->len); - for (int i = 0; i < pdu_meta->pdu->len; i++) { - PRINT("%02x ", pdu_meta->pdu->payload[i]); + for (uint8_t i = 0U; i < pdu->len; i++) { + if (seg_length == 0U && pdu->ll_id == PDU_BIS_LLID_FRAMED) { + seg_length = pdu->payload[i + 1U]; + PRINT("[%s %s %03u]", + pdu->payload[i] & BIT(0) ? "C" : "S", + pdu->payload[i] & BIT(1) ? "C" : "-", + pdu->payload[i + 1U]); + if ((pdu->payload[i] & BIT(0)) == 0U) { + PRINT("(%8uus)", + ((uint32_t)pdu->payload[i + 2U] + + ((uint32_t)pdu->payload[i + 3U] << 8) + + ((uint32_t)pdu->payload[i + 4U] << 16))); + } + + PRINT(" / "); + PRINT("[%02x %02x]", + pdu->payload[i], + pdu->payload[i + 1U]); + if ((pdu->payload[i] & BIT(0)) == 0U) { + PRINT("(%02x %02x %02x)", + (uint32_t)pdu->payload[i + 4U], + (uint32_t)pdu->payload[i + 3U], + (uint32_t)pdu->payload[i + 2U]); + } + + PRINT(" : "); + seg_length -= pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE; + i += PDU_ISO_SEG_HDR_SIZE + + (pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); + } + + PRINT("%02x ", pdu->payload[i]); + seg_length--; + if (seg_length == 0 && pdu->ll_id == PDU_BIS_LLID_FRAMED) { + PRINT("\n%44s", ""); + } } PRINT("\n"); PRINT("\n"); diff --git a/tests/bluetooth/ctrl_isoal/src/main.c b/tests/bluetooth/ctrl_isoal/src/main.c index 92ca21ff199..08175eab153 100644 --- a/tests/bluetooth/ctrl_isoal/src/main.c +++ b/tests/bluetooth/ctrl_isoal/src/main.c @@ -18,6 +18,8 @@ #include #include +#include + #include DEFINE_FFF_GLOBALS; diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index dc21c9b5d61..3f57d8bccbc 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -3757,7 +3757,8 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) * Test Suite : TX framed SDU segmentation * * Tests segmentation of a single SDU contained in a single fragment - * into three PDUs where Max PDU is less than the PDU buffer size + * into three PDUs where Max PDU is less than the PDU buffer size. Also tests + * endianness of the segment header. */ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) { @@ -3854,10 +3855,11 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* Test segmentation (Black Box) */ /* Valid PDUs */ /* PDU 1 */ - seg_hdr[0].sc = 0; - seg_hdr[0].cmplt = 0; - seg_hdr[0].timeoffset = ref_point - sdu_timestamp; - seg_hdr[0].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; + /* Test endianness */ + WRITE_BIT(((uint8_t *)&seg_hdr[0])[0], 0, 0); /* sc */ + WRITE_BIT(((uint8_t *)&seg_hdr[0])[0], 1, 0); /* cmplt */ + sys_put_le24(ref_point - sdu_timestamp, (uint8_t *)(&seg_hdr[0]) + PDU_ISO_SEG_HDR_SIZE); + ((uint8_t *)(&seg_hdr[0]))[1] = PDU_ISO_SEG_TIMEOFFSET_SIZE; /* len */ pdu_hdr_loc = 0; pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; sdu_read_loc = 0; @@ -3877,7 +3879,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[1] = seg_hdr[0]; - seg_hdr[1].len += (pdu_write_size - pdu_write_loc); + ((uint8_t *)(&seg_hdr[1]))[1] += (pdu_write_size - pdu_write_loc); ZASSERT_PDU_WRITE_TEST(history[2], pdu_buffer, @@ -3895,10 +3897,10 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* PDU 2 */ payload_number++; - seg_hdr[2].sc = 1; - seg_hdr[2].cmplt = 0; - seg_hdr[2].timeoffset = 0; - seg_hdr[2].len = 0; + WRITE_BIT(((uint8_t *)&seg_hdr[2])[0], 0, 1); /* sc */ + WRITE_BIT(((uint8_t *)&seg_hdr[2])[0], 1, 0); /* cmplt */ + sys_put_le24(0, (uint8_t *)(&seg_hdr[2]) + PDU_ISO_SEG_HDR_SIZE); + ((uint8_t *)(&seg_hdr[2]))[1] = 0; /* len */ pdu_hdr_loc = 0; sdu_read_loc += (pdu_write_size - pdu_write_loc); pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; @@ -3918,7 +3920,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[3] = seg_hdr[2]; - seg_hdr[3].len += (pdu_write_size - pdu_write_loc); + ((uint8_t *)(&seg_hdr[3]))[1] += (pdu_write_size - pdu_write_loc); /* len */ ZASSERT_PDU_WRITE_TEST(history[5], pdu_buffer, @@ -3936,10 +3938,10 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* PDU 3 */ payload_number++; - seg_hdr[4].sc = 1; - seg_hdr[4].cmplt = 0; - seg_hdr[4].timeoffset = 0; - seg_hdr[4].len = 0; + WRITE_BIT(((uint8_t *)&seg_hdr[4])[0], 0, 1); /* sc */ + WRITE_BIT(((uint8_t *)&seg_hdr[4])[0], 1, 0); /* cmplt */ + sys_put_le24(0, (uint8_t *)(&seg_hdr[4]) + PDU_ISO_SEG_HDR_SIZE); + ((uint8_t *)(&seg_hdr[4]))[1] = 0; /* len */ pdu_hdr_loc = 0; sdu_read_loc += (pdu_write_size - pdu_write_loc); pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; @@ -3962,8 +3964,8 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[5] = seg_hdr[4]; - seg_hdr[5].cmplt = 1; - seg_hdr[5].len += (pdu_write_size - pdu_write_loc); + WRITE_BIT(((uint8_t *)&seg_hdr[5])[0], 1, 1); /* cmplt */ + ((uint8_t *)(&seg_hdr[5]))[1] += (pdu_write_size - pdu_write_loc); /* len */ ZASSERT_PDU_WRITE_TEST(history[8], pdu_buffer, From d414cab87a87c63a70266a83256a77ae6abaa052 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Tue, 18 Jul 2023 16:32:29 +0200 Subject: [PATCH 0605/4498] Bluetooth: Controller: ISO-AL validation and selection of TX time stamps Intent is to pass Ellisys ISOAL quality tests for framed TX scenarios where the TX SDU includes a time stamp that is not based on the controller's clock. Changes: -- Include controller's reception time as a separate field in the TX SDU information -- Include decision on whether SDU time stamp is valid and based on the controller's clock -- Arbitrate and select / compute time stamp for the SDU Signed-off-by: Nirosharn Amarasinghe --- subsys/bluetooth/controller/hci/hci.c | 14 +- subsys/bluetooth/controller/ll_sw/isoal.c | 212 +++++++++++++++----- subsys/bluetooth/controller/ll_sw/isoal.h | 2 + subsys/bluetooth/controller/ll_sw/ull_iso.c | 3 +- 4 files changed, 176 insertions(+), 55 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 9ca905c44e0..30fb363fc9c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5700,17 +5700,21 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * -- A captured time stamp of the SDU * -- A time stamp provided by the higher layer * -- A computed time stamp based on a sequence counter provided by the - * higher layer (Not implemented) - * -- Any other method of determining Time_Offset (Not implemented) + * higher layer + * -- Any other method of determining Time_Offset + * (Uses a timestamp computed from the difference in provided + * timestamps, if the timestamp is deemed not based on the + * controller's clock) */ + sdu_frag_tx.cntr_time_stamp = HAL_TICKER_TICKS_TO_US(ticker_ticks_now_get()); if (ts_flag) { - /* Overwrite time stamp with HCI provided time stamp */ + /* Use HCI provided time stamp */ time_stamp = net_buf_pull_mem(buf, sizeof(*time_stamp)); len -= sizeof(*time_stamp); sdu_frag_tx.time_stamp = sys_le32_to_cpu(*time_stamp); } else { - sdu_frag_tx.time_stamp = - HAL_TICKER_TICKS_TO_US(ticker_ticks_now_get()); + /* Use controller's capture time */ + sdu_frag_tx.time_stamp = sdu_frag_tx.cntr_time_stamp; } /* Extract ISO data header if included (PB_Flag 0b00 or 0b10) */ diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 00bc40504f7..d4cc61cea6c 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -1282,7 +1282,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } /* Update next state */ - ISOAL_LOG_DBGV("[%p] Decoding: Next State %s", sink, FSM_TO_STR(next_state)); + ISOAL_LOG_DBGV("[%p] FSM Next State %s", sink, FSM_TO_STR(next_state)); sp->fsm = next_state; /* Find next segment header, set to null if past end of PDU */ @@ -1350,7 +1350,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, if (error_sdu_pending) { sp->sdu_status = next_sdu_status; - err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); + err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0U, 0U, true, false); } break; @@ -1373,8 +1373,8 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } /* Update next state */ - ISOAL_LOG_DBGV("[%p] Error: Next State %s", sink, FSM_TO_STR(next_state)); - sink->sdu_production.fsm = next_state; + ISOAL_LOG_DBGV("[%p] FSM Error Next State %s", sink, FSM_TO_STR(next_state)); + sp->fsm = next_state; } sp->prev_pdu_id = meta->payload_number; @@ -1591,6 +1591,46 @@ void isoal_source_destroy(isoal_source_handle_t hdl) isoal_source_deallocate(hdl); } +static bool isoal_is_time_stamp_valid(const struct isoal_source *source_ctx, + const uint32_t cntr_time, + const uint32_t time_stamp) +{ + const struct isoal_source_session *session; + uint32_t time_diff; + + session = &source_ctx->session; + + /* This is an arbitrarily defined range. The purpose is to + * decide if the time stamp provided by the host is sensible + * within the controller's clock domain. An SDU interval plus ISO + * interval is expected to provide a good balance between situations + * where either could be significantly larger than the other. + * + * BT Core V5.4 : Vol 6 Low Energy Controller : Part G IS0-AL: + * 3.3 Time Stamp for SDU : + * When an HCI ISO Data packet sent by the Host does not contain + * a Time Stamp or the Time_Stamp value is not based on the + * Controller's clock, the Controller should determine the CIS + * or BIS event to be used to transmit the SDU contained in that + * packet based on the time of arrival of that packet. + */ + const uint32_t sdu_interval_us = session->sdu_interval; + const uint32_t iso_interval_us = session->iso_interval * ISO_INT_UNIT_US; + /* ISO Interval 0x0000_0004 ~ 0x0000_0C80 x 1250 + + * SDU Interval 0x0000_00FF ~ 0x000F_FFFF <= 004D_08FF + */ + const int32_t time_stamp_valid_half_range = sdu_interval_us + iso_interval_us; + const uint32_t time_stamp_valid_min = isoal_get_wrapped_time_us(cntr_time, + (-time_stamp_valid_half_range)); + const uint32_t time_stamp_valid_range = 2 * time_stamp_valid_half_range; + const bool time_stamp_is_valid = isoal_get_time_diff(time_stamp_valid_min, + time_stamp, + &time_diff) && + time_diff <= time_stamp_valid_range; + + return time_stamp_is_valid; +} + /** * Queue the PDU in production in the relevant LL transmit queue. If the * attmept to release the PDU fails, the buffer linked to the PDU will be released @@ -1636,8 +1676,8 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, status = source_ctx->session.pdu_emit(node_tx, handle); ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", - source_ctx, payload_number, status, - produced_pdu->contents.pdu->len, sdu_fragments); + source_ctx, payload_number, status, + produced_pdu->contents.pdu->len, sdu_fragments); if (status != ISOAL_STATUS_OK) { /* If it fails, the node will be released and no further attempt @@ -1841,8 +1881,8 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * @brief Fragment received SDU and produce unframed PDUs * @details Destination source may have an already partially built PDU * - * @param source_hdl[in] Destination source handle - * @param tx_sdu[in] SDU with packet boundary information + * @param[in] source_hdl Destination source handle + * @param[in] tx_sdu SDU with packet boundary information * * @return Status * @@ -2162,7 +2202,7 @@ static isoal_status_t isoal_insert_seg_header_timeoffset(struct isoal_source *so pp->pdu_available -= write_size; ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u TO=%u len=%u", - source, write_size, sc, cmplt, time_offset, seg_hdr.len); + source, write_size, sc, cmplt, time_offset, seg_hdr.len); return err; } @@ -2203,46 +2243,48 @@ static isoal_status_t isoal_update_seg_header_cmplt_length(struct isoal_source * PDU_ISO_SEG_HDR_SIZE); ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u len=%u", - source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); + source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); } /** * Find the earliest feasible event for transmission capacity is not wasted and * return information based on that event. - * @param[in] source_hdl Destination source handle + * + * @param[in] *source_ctx Destination source context * @param[in] tx_sdu SDU with meta data information * @param[out] payload_number Updated payload number for the selected event * @param[out] grp_ref_point Group reference point for the selected event * @param[out] time_offset Segmentation Time offset to selected event * @return The number SDUs skipped from the last */ -static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t source_hdl, +static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source *source_ctx, const struct isoal_sdu_tx *tx_sdu, uint64_t *payload_number, uint32_t *grp_ref_point, uint32_t *time_offset) { - struct isoal_source_session *session; - struct isoal_pdu_production *pp; + const struct isoal_source_session *session; + const struct isoal_pdu_production *pp; uint32_t actual_grp_ref_point; uint64_t next_payload_number; - struct isoal_source *source; uint16_t sdus_skipped; uint64_t actual_event; bool time_diff_valid; uint32_t time_diff; + uint32_t time_stamp_selected; - source = &isoal_global.source_state[source_hdl]; - session = &source->session; - pp = &source->pdu_production; + session = &source_ctx->session; + pp = &source_ctx->pdu_production; - sdus_skipped = 0; + sdus_skipped = 0U; + time_diff = 0U; /* Continue with the current payload unless there is need to change */ next_payload_number = pp->payload_number; actual_event = pp->payload_number / session->burst_number; - ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source, next_payload_number, actual_event); + ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source_ctx, next_payload_number, + actual_event); /* Get the drift updated group reference point for this event based on * the actual event being set. This might introduce some errors as the @@ -2259,29 +2301,35 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t sour } ISOAL_LOG_DBGV("[%p] Current PL=%llu Evt=%llu Ref=%lu", - source, next_payload_number, actual_event, actual_grp_ref_point); + source_ctx, next_payload_number, actual_event, actual_grp_ref_point); if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { /* Start of a new SDU */ + const bool time_stamp_is_valid = isoal_is_time_stamp_valid(source_ctx, + tx_sdu->cntr_time_stamp, + tx_sdu->time_stamp); + /* Adjust payload number */ if (pp->initialized) { /* Not the first SDU in this session, so reference * information should be valid. . */ + time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, tx_sdu->time_stamp, &time_diff); /* Priority is given to the sequence number */ if (tx_sdu->packet_sn > session->last_input_sn + 1) { - ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source); + ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source_ctx); sdus_skipped = (tx_sdu->packet_sn - session->last_input_sn) - 1; } else if (tx_sdu->packet_sn == session->last_input_sn && - time_diff_valid && time_diff > session->sdu_interval) { - ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", source); + time_diff_valid && time_diff > session->sdu_interval) { + ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", + source_ctx); /* Round at mid-point */ sdus_skipped = ((time_diff + (session->sdu_interval / 2)) / session->sdu_interval) - 1; @@ -2289,12 +2337,58 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t sour /* SDU is next in sequence */ } + if (time_stamp_is_valid) { + /* Use provided time stamp for time offset + * calcutation + */ + time_stamp_selected = tx_sdu->time_stamp; + ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from SDU", + source_ctx, time_stamp_selected); + } else if (time_diff_valid) { + /* Project a time stamp based on the last time + * stamp and the difference in input time stamps + */ + time_stamp_selected = isoal_get_wrapped_time_us( + session->tx_time_stamp, + time_diff - session->tx_time_offset); + ISOAL_LOG_DBGV("[%p] Projecting Time Stamp (%lu) from SDU delta", + source_ctx, time_stamp_selected); + } else { + /* Project a time stamp based on the last time + * stamp and the number of skipped SDUs + */ + time_stamp_selected = isoal_get_wrapped_time_us( + session->tx_time_stamp, + ((sdus_skipped + 1) * session->sdu_interval) + - session->tx_time_offset); + ISOAL_LOG_DBGV("[%p] Projecting Time Stamp (%lu) from skipped SDUs", + source_ctx, time_stamp_selected); + } + } else { /* First SDU, align with target event */ - actual_event = tx_sdu->target_event; - actual_grp_ref_point = tx_sdu->grp_ref_point; + if (actual_event < tx_sdu->target_event) { + actual_event = tx_sdu->target_event; + actual_grp_ref_point = tx_sdu->grp_ref_point; + } - ISOAL_LOG_DBGV("[%p] Use target_event", source); + ISOAL_LOG_DBGV("[%p] Use target_event", source_ctx); + + if (time_stamp_is_valid) { + /* Time stamp is within valid range - + * use provided time stamp + */ + time_stamp_selected = tx_sdu->time_stamp; + ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from SDU", + source_ctx, time_stamp_selected); + } else { + /* Time stamp is out of range - + * use controller's capture time + */ + time_stamp_selected = tx_sdu->cntr_time_stamp; + ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from controller", + source_ctx, time_stamp_selected); + } } /* Selecting the event for transmission is done solely based on @@ -2309,8 +2403,8 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t sour * 3.1 Time_Offset in framed PDUs : * The Time_Offset shall be a positive value. */ - while (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || - time_diff == 0) { + while (!isoal_get_time_diff(time_stamp_selected, actual_grp_ref_point, &time_diff) + || time_diff == 0) { /* Advance target to next event */ actual_event++; actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, @@ -2318,8 +2412,8 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t sour } ISOAL_LOG_DBGV("[%p] Chosen PL=%llu Evt=%llu Ref=%lu", - source, (actual_event * session->burst_number), actual_event, - actual_grp_ref_point); + source_ctx, (actual_event * session->burst_number), actual_event, + actual_grp_ref_point); /* If the event selected is the last event segmented for, then * it is possible that that some payloads have already been @@ -2327,23 +2421,23 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t sour * that payload. */ next_payload_number = MAX(pp->payload_number, - (actual_event * session->burst_number)); - } + (actual_event * session->burst_number)); - ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", - source, actual_event, (actual_event * session->burst_number), - actual_grp_ref_point, next_payload_number); + ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", + source, actual_event, (actual_event * session->burst_number), + actual_grp_ref_point, next_payload_number); - /* Calculate the time offset */ - time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, - actual_grp_ref_point, &time_diff); + /* Calculate the time offset */ + time_diff_valid = isoal_get_time_diff(time_stamp_selected, + actual_grp_ref_point, &time_diff); - LL_ASSERT(time_diff_valid); - LL_ASSERT(time_diff > 0); - /* Time difference must be less than the maximum possible - * time-offset of 24-bits. - */ - LL_ASSERT(time_diff <= 0x00FFFFFF); + LL_ASSERT(time_diff_valid); + LL_ASSERT(time_diff > 0); + /* Time difference must be less than the maximum possible + * time-offset of 24-bits. + */ + LL_ASSERT(time_diff <= 0x00FFFFFF); + } *payload_number = next_payload_number; *grp_ref_point = actual_grp_ref_point; @@ -2389,19 +2483,24 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, tx_sdu->sdu_state == BT_ISO_SINGLE); ISOAL_LOG_DBGV("[%p] SDU %u len=%u TS=%lu Ref=%lu Evt=%llu Frag=%u", - source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, - tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); + source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, + tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { uint32_t actual_grp_ref_point; uint64_t next_payload_number; uint16_t sdus_skipped; + bool time_diff_valid; + uint32_t time_diff; /* Start of a new SDU */ + time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, + tx_sdu->time_stamp, + &time_diff); /* Find the best transmission event */ - sdus_skipped = isoal_tx_framed_find_correct_tx_event(source_hdl, tx_sdu, + sdus_skipped = isoal_tx_framed_find_correct_tx_event(source, tx_sdu, &next_payload_number, &actual_grp_ref_point, &time_offset); @@ -2460,7 +2559,22 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Update input packet number and time stamp */ session->last_input_sn = tx_sdu->packet_sn; - session->last_input_time_stamp = tx_sdu->time_stamp; + + if (pp->initialized && tx_sdu->time_stamp == tx_sdu->cntr_time_stamp && + (!time_diff_valid || time_diff < session->sdu_interval)) { + /* If the time-stamp is invalid or the difference is + * less than an SDU interval, then set the reference + * time stamp to what should have been received. This is + * done to avoid incorrectly detecting a gap in time + * stamp inputs should there be a burst of SDUs + * clustered together. + */ + session->last_input_time_stamp = isoal_get_wrapped_time_us( + session->last_input_time_stamp, + session->sdu_interval); + } else { + session->last_input_time_stamp = tx_sdu->time_stamp; + } } /* PDUs should be created until the SDU fragment has been fragmented or if diff --git a/subsys/bluetooth/controller/ll_sw/isoal.h b/subsys/bluetooth/controller/ll_sw/isoal.h index cc69e4a5d53..61d3773c43d 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.h +++ b/subsys/bluetooth/controller/ll_sw/isoal.h @@ -189,6 +189,8 @@ struct isoal_sdu_tx { uint16_t iso_sdu_length; /** Time stamp from HCI or vendor specific path (us) */ uint32_t time_stamp; + /** Capture time stamp from controller (us) */ + uint32_t cntr_time_stamp; /** CIG Reference of target event (us, compensated for drift) */ uint32_t grp_ref_point; /** Target Event of SDU */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index 1520bd76963..70d018e7e0c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -1058,7 +1058,8 @@ void ll_iso_transmit_test_send_sdu(uint16_t handle, uint32_t ticks_at_expire) /* Send all SDU fragments */ do { - sdu.time_stamp = HAL_TICKER_TICKS_TO_US(ticks_at_expire); + sdu.cntr_time_stamp = HAL_TICKER_TICKS_TO_US(ticks_at_expire); + sdu.time_stamp = sdu.cntr_time_stamp; sdu.size = MIN(remaining_tx, ISO_TEST_TX_BUFFER_SIZE); memset(tx_buffer, 0, sdu.size); From 2260b651b65be683fc1e82aafeef166d97dde64a Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Wed, 19 Jul 2023 12:20:42 +0200 Subject: [PATCH 0606/4498] tests: bluetooth: controller: ISO-AL selection of TX time stamps Unit tests for TX time stamp related decisions. Signed-off-by: Nirosharn Amarasinghe --- .../ctrl_isoal/src/isoal_test_debug.c | 1 + tests/bluetooth/ctrl_isoal/src/main.c | 2 +- .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 540 +++++++++++++++++- 3 files changed, 540 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c index 734af1ad7c0..084677cf462 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c @@ -233,6 +233,7 @@ void isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx *tx_sdu) PRINT("%02x ", buf[i]); } PRINT("\n"); + PRINT("Cntr TS. <%10u>\n", tx_sdu->cntr_time_stamp); PRINT(" Ref. <%10u>\n", tx_sdu->grp_ref_point); PRINT(" Event <%10u>\n", (uint32_t)tx_sdu->target_event); PRINT("\n"); diff --git a/tests/bluetooth/ctrl_isoal/src/main.c b/tests/bluetooth/ctrl_isoal/src/main.c index 08175eab153..8cbd36c509a 100644 --- a/tests/bluetooth/ctrl_isoal/src/main.c +++ b/tests/bluetooth/ctrl_isoal/src/main.c @@ -37,7 +37,7 @@ DEFINE_FFF_GLOBALS; ZTEST_SUITE(test_rx_basics, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); ZTEST_SUITE(test_rx_unframed, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); -ZTEST_SUITE(test_rx_framed, NULL, NULL, NULL, isoal_test_rx_common_before, NULL); +ZTEST_SUITE(test_rx_framed, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); ZTEST_SUITE(test_tx_basics, NULL, NULL, isoal_test_tx_common_before, NULL, NULL); ZTEST_SUITE(test_tx_unframed, NULL, NULL, isoal_test_tx_common_before, NULL, NULL); diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index 3f57d8bccbc..c9a6fe67637 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -195,14 +195,14 @@ static isoal_status_t custom_source_pdu_write_test(struct isoal_pdu_buffer *pdu_ _consume_len, \ source_pdu_write_test_fake.arg3_##_typ); \ check_next_custom_source_pdu_write_test_sdu_payload((const uint8_t *)_sdu_payload, \ - _consume_len, __LINE__); + _consume_len, __LINE__) #define ZASSERT_PDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ source_pdu_write_test_fake.call_count, \ "Expected %u, got %u", \ _expected, \ - source_pdu_write_test_fake.call_count); + source_pdu_write_test_fake.call_count) /*------------------ PDU Emit Callback --------------------------------------*/ /** @@ -480,6 +480,7 @@ static void isoal_test_create_sdu_fagment(uint8_t sdu_state, uint16_t sdu_total_length, uint16_t packet_number, uint32_t timestamp, + uint32_t cntr_timestamp, uint32_t ref_point, uint64_t target_event, struct isoal_sdu_tx *sdu_tx) @@ -488,6 +489,7 @@ static void isoal_test_create_sdu_fagment(uint8_t sdu_state, sdu_tx->packet_sn = packet_number; sdu_tx->iso_sdu_length = sdu_total_length; sdu_tx->time_stamp = timestamp; + sdu_tx->cntr_time_stamp = cntr_timestamp; sdu_tx->grp_ref_point = ref_point; sdu_tx->target_event = target_event; memcpy(sdu_tx->dbuf, dataptr, length); @@ -792,6 +794,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -920,6 +923,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1035,6 +1039,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1195,6 +1200,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1241,6 +1247,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1284,6 +1291,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1403,6 +1411,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1451,6 +1460,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1517,6 +1527,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1734,6 +1745,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1787,6 +1799,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1916,6 +1929,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1968,6 +1982,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2030,6 +2045,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2085,6 +2101,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2128,6 +2145,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2190,6 +2208,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2314,6 +2333,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2370,6 +2390,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2432,6 +2453,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2527,6 +2549,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2569,6 +2592,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2631,6 +2655,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2792,6 +2817,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2952,6 +2978,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3069,6 +3096,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3199,6 +3227,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3269,6 +3298,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3335,6 +3365,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3404,6 +3435,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3451,6 +3483,470 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) zassert_equal(tx_sync_offset, tx_sync_offset_expected, "%u != %u", tx_sync_seq, 0); } +/** + * Test Suite : TX framed SDU segmentation + * + * Tests framed event selection + */ +#define RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT() \ + out_sdus_skipped = isoal_tx_framed_find_correct_tx_event(source, \ + &tx_sdu_frag_buf.sdu_tx, \ + &out_payload_number, \ + &out_ref_point, \ + &out_time_offset); \ + \ + zassert_equal(out_payload_number, expect_payload_number, "%llu != %llu", \ + out_payload_number, expect_payload_number); \ + zassert_equal(out_ref_point, expect_ref_point, "%u != %u", \ + out_ref_point, expect_ref_point); \ + zassert_equal(out_time_offset, expect_time_offset, "%u != %u", \ + out_time_offset, expect_time_offset); \ + zassert_equal(out_sdus_skipped, expect_sdus_skipped, "%u .!= %u", \ + out_sdus_skipped, expect_sdus_skipped) + +ZTEST(test_tx_framed, test_tx_framed_find_correct_tx_event) +{ + const uint8_t number_of_pdus = 1; + const uint8_t testdata_size_max = MAX_FRAMED_PDU_PAYLOAD(number_of_pdus); + + struct tx_sdu_frag_buffer tx_sdu_frag_buf; + struct isoal_source_session *session; + uint8_t testdata[testdata_size_max]; + isoal_sdu_len_t in_sdu_total_size; + isoal_source_handle_t source_hdl; + struct isoal_pdu_production *pp; + uint64_t expect_payload_number; + struct isoal_source *source; + uint64_t out_payload_number; + uint32_t expect_time_offset; + uint8_t expect_sdus_skipped; + uint32_t expected_timestamp; + uint32_t stream_sync_delay; + uint32_t in_cntr_timestamp; + uint32_t group_sync_delay; + uint64_t in_sdu_packet_sn; + uint32_t in_sdu_timestamp; + uint32_t expect_ref_point; + uint64_t in_target_event; + uint32_t iso_interval_us; + uint8_t iso_interval_int; + uint32_t out_time_offset; + uint8_t out_sdus_skipped; + uint16_t testdata_indx; + uint16_t testdata_size; + uint32_t out_ref_point; + uint32_t sdu_interval; + uint32_t in_ref_point; + uint8_t max_octets; + uint8_t role; + uint8_t BN; + uint8_t FT; + + /* Settings */ + role = BT_CONN_ROLE_PERIPHERAL; + iso_interval_int = 1; + iso_interval_us = iso_interval_int * ISO_INT_UNIT_US; + sdu_interval = iso_interval_us + 50; + max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; + BN = 2; + FT = 1; + stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + + init_test_data_buffer(testdata, testdata_size_max); + + /* Create source */ + source_hdl = basic_tx_test_setup(0xADAD, /* Handle */ + role, /* Role */ + true, /* Framed */ + BN, /* BN */ + FT, /* FT */ + max_octets, /* max_octets */ + sdu_interval, /* SDU Interval */ + iso_interval_int, /* ISO Interval */ + stream_sync_delay, /* Stream Sync Delay */ + group_sync_delay); /* Group Sync Delay */ + + source = &isoal_global.source_state[source_hdl]; + session = &source->session; + pp = &source->pdu_production; + + in_sdu_total_size = testdata_size_max; + testdata_indx = 0; + testdata_size = testdata_size_max; + + /* Test : Selection of event for first SDU where + * -- Last SDU packet number is uninitialized + * -- Last SDU time stamp is uninitialized + * -- Payload number is uninitialized + * -- Target event and reference point are one event ahead + * -- Time stamp is valid + * -- Time stamp indicates that target event is feasible + * Expected: + * -- Target event is used for transmission and calculations are based + * on that + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2000; + in_sdu_timestamp = 9249; + in_cntr_timestamp = in_sdu_timestamp + 200; + in_ref_point = in_sdu_timestamp + iso_interval_us - 50; + + pp->initialized = 0U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = 0; + session->last_input_time_stamp = 0; + pp->payload_number = 0; + + expect_sdus_skipped = 0; + expect_payload_number = in_target_event * BN; + expect_ref_point = in_ref_point; + expected_timestamp = in_sdu_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for first SDU where + * -- Last SDU packet number is uninitialized + * -- Last SDU time stamp is uninitialized + * -- Payload number ahead of target event + * -- Target event and reference point are one event behind + * current payload + * -- Time stamp is valid + * -- Time stamp indicates that target event is feasible + * Expected: + * -- Target event + 1 is selected based on the payload being ahead and + * calculations are based on that reference + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2000; + in_sdu_timestamp = 9249; + in_cntr_timestamp = in_sdu_timestamp + 200; + in_ref_point = in_sdu_timestamp + iso_interval_us - 50; + + pp->initialized = 0U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = 0; + session->last_input_time_stamp = 0; + pp->payload_number = (in_target_event + 1) * BN; + + expect_sdus_skipped = 0; + expect_payload_number = (in_target_event + 1) * BN; + expect_ref_point = in_ref_point + iso_interval_us; + expected_timestamp = in_sdu_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for first SDU where + * -- Last SDU packet number is uninitialized + * -- Last SDU time stamp is uninitialized + * -- Payload number ahead of target event + * -- Target event and reference point are one event behind + * current payload + * -- Time stamp is invalid + * -- Controller time stamp indicates that target event is + * feasible + * Expected: + * -- Target event + 1 is selected based on the payload being ahead and + * calculations are based on that reference + * -- Time offset is based on the controller's capture time + */ + in_sdu_packet_sn = 2000; + in_target_event = 2000; + in_sdu_timestamp = 0; + in_cntr_timestamp = 9249 + 200; + in_ref_point = in_cntr_timestamp + iso_interval_us - 50; + + pp->initialized = 0U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = 0; + session->last_input_time_stamp = 0; + pp->payload_number = (in_target_event + 1) * BN; + + expect_sdus_skipped = 0; + expect_payload_number = (in_target_event + 1) * BN; + expect_ref_point = in_ref_point + iso_interval_us; + expected_timestamp = in_cntr_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for a subsequent SDU where + * -- Last SDU packet number is in sequence + * -- Last SDU time stamp is in sequence + * -- Payload number is in sequence + * -- Target event and reference point are one event ahead of + * current payload + * -- Time stamp is valid + * -- Time stamp indicates that target event is feasible + * Expected: + * -- Target event is selected based on the time stamp and calculations + * are based on that reference + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2000; + in_sdu_timestamp = 9249; + in_cntr_timestamp = 9249 + 200; + in_ref_point = in_sdu_timestamp + iso_interval_us - 50; + + pp->initialized = 1U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = in_sdu_packet_sn - 1; + session->last_input_time_stamp = in_sdu_timestamp - sdu_interval; + pp->payload_number = (in_target_event - 1) * BN; + + expect_sdus_skipped = 0; + expect_payload_number = in_target_event * BN; + expect_ref_point = in_ref_point; + expected_timestamp = in_sdu_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for a subsequent SDU where + * -- Last SDU packet number is not in sequence + * -- Last SDU time stamp is not in sequence + * -- Payload number is not in sequence + * -- Target event and reference point are two events ahead + * -- Time stamp is valid but at the border of the range + * -- Time stamp indicates that target event - 1 is feasible + * Expected: + * -- Target event - 1 is selected based on the time stamp and + * calculations are based on that reference + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2001; + in_sdu_timestamp = 9249; + in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us; + in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; + + pp->initialized = 1U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = in_sdu_packet_sn - 3; + session->last_input_time_stamp = in_sdu_timestamp - (sdu_interval * 2); + pp->payload_number = (in_target_event - 2) * BN; + + expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; + expect_payload_number = (in_target_event - 1) * BN; + expect_ref_point = in_ref_point - iso_interval_us; + expected_timestamp = in_sdu_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for a subsequent SDU where + * -- Last SDU packet number is not in sequence + * -- Last SDU time stamp is not in sequence + * -- Payload number is not in sequence + * -- Target event and reference point are two events ahead + * -- Time stamp is invalid + * Expected: + * -- Target event is selected based on the time stamp calculated + * from the difference between time stamps and calculations are based + * on that reference + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2001; + in_sdu_timestamp = 9249; + in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us + 1; + in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; + + pp->initialized = 1U; + session->tx_time_stamp = in_ref_point - iso_interval_us; + session->tx_time_offset = session->tx_time_stamp - + (in_sdu_timestamp - sdu_interval); + session->last_input_sn = in_sdu_packet_sn - 3; + session->last_input_time_stamp = in_sdu_timestamp - (sdu_interval * 2); + pp->payload_number = (in_target_event - 2) * BN; + + expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; + expect_payload_number = in_target_event * BN; + expect_ref_point = in_ref_point; + expected_timestamp = session->tx_time_stamp - session->tx_time_offset + + (in_sdu_timestamp - session->last_input_time_stamp); + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for a subsequent SDU where + * -- Last SDU packet number is not in sequence + * -- Last SDU time stamp has been projected as part of a + * burst + * -- Payload number is not in sequence + * -- Target event and reference point are two events ahead + * -- Time stamp is invalid + * -- Time stamp delta is invalid + * Expected: + * -- Target event + 1 is selected based on the time stamp calculated + * from the difference in packet sn and calculations are based + * on that reference + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2001; + in_sdu_timestamp = 9249; + in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us + 1; + in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; + + pp->initialized = 1U; + session->tx_time_stamp = in_ref_point - iso_interval_us; + session->tx_time_offset = session->tx_time_stamp - + (in_sdu_timestamp + sdu_interval); + session->last_input_sn = in_sdu_packet_sn - 1; + session->last_input_time_stamp = in_sdu_timestamp + (sdu_interval * 2); + pp->payload_number = (in_target_event - 2) * BN; + + expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; + expect_payload_number = (in_target_event + 1) * BN; + expect_ref_point = in_ref_point + iso_interval_us; + expected_timestamp = session->tx_time_stamp - session->tx_time_offset + sdu_interval; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); + + /* Test : Selection of event for a subsequent SDU where + * -- Last SDU packet number is in sequence + * -- Last SDU time stamp has been projected as part of a + * burst + * -- Payload number is ahead of selected event + * -- Target event and reference point are two events ahead + * -- Time stamp is valid + * -- Time stamp indicates that target event - 1 is feasible + * Expected: + * -- Target event -1 is selected based on the time stamp and + * calculations are based on that reference + * -- Payload number continues from last + * -- Time offset is based on the SDUs time stamp + */ + in_sdu_packet_sn = 2000; + in_target_event = 2001; + in_sdu_timestamp = 9249; + in_cntr_timestamp = 9249; + in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; + + pp->initialized = 1U; + session->tx_time_stamp = 0; + session->tx_time_offset = 0; + session->last_input_sn = in_sdu_packet_sn - 1; + session->last_input_time_stamp = in_sdu_timestamp - sdu_interval; + pp->payload_number = ((in_target_event - 1) * BN) + 1; + + expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; + expect_payload_number = pp->payload_number; + expect_ref_point = in_ref_point - iso_interval_us; + expected_timestamp = in_sdu_timestamp; + expect_time_offset = expect_ref_point - expected_timestamp; + + isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); + isoal_test_create_sdu_fagment(BT_ISO_SINGLE, + &testdata[testdata_indx], + (testdata_size - testdata_indx), + in_sdu_total_size, + in_sdu_packet_sn, + in_sdu_timestamp, + in_cntr_timestamp, + in_ref_point, + in_target_event, + &tx_sdu_frag_buf.sdu_tx); + + RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); +} + /** * Test Suite : TX framed SDU segmentation * @@ -3537,6 +4033,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3692,6 +4189,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3836,6 +4334,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4073,6 +4572,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4144,6 +4644,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4198,6 +4699,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4335,6 +4837,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4408,6 +4911,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4500,6 +5004,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4637,6 +5142,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4712,6 +5218,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4804,6 +5311,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4870,6 +5378,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4936,6 +5445,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5027,6 +5537,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5164,6 +5675,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5236,6 +5748,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5327,6 +5840,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5390,6 +5904,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5451,6 +5966,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5541,6 +6057,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5711,6 +6228,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5791,6 +6309,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5940,6 +6459,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6096,6 +6616,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6176,6 +6697,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6316,6 +6838,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6467,6 +6990,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6647,6 +7171,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6775,6 +7300,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6921,6 +7447,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6997,6 +7524,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7071,6 +7599,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7234,6 +7763,7 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7309,6 +7839,7 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7418,6 +7949,7 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7510,6 +8042,7 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7696,6 +8229,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7767,6 +8301,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7847,6 +8382,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, + sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); From 365a56ce87fa91eb3a059f0353a450c4408d0bf4 Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Thu, 10 Aug 2023 14:44:59 +0200 Subject: [PATCH 0607/4498] Bluetooth: controller: disregard length field on pdu error In case of unframed iso rx, length field cannot be trusted in case of PDU error. Signed-off-by: Erik Brockhoff --- subsys/bluetooth/controller/ll_sw/isoal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index d4cc61cea6c..6c1dedd7b9d 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -738,7 +738,7 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, /* If status is not ISOAL_PDU_STATUS_VALID, length and LLID cannot be trusted */ llid = pdu->ll_id; pdu_err = (pdu_meta->meta->status != ISOAL_PDU_STATUS_VALID); - length = pdu->len; + length = pdu_err ? 0U : pdu->len; /* A zero length PDU with LLID 0b01 (PDU_BIS_LLID_START_CONTINUE) would be a padding PDU. * However if there are errors in the PDU, it could be an incorrectly receive non-padding * PDU. Therefore only consider a PDU with errors as padding if received after the end From 770f435e6881ea667466744c22d2ee9ca6f715ec Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Mon, 14 Aug 2023 12:36:14 +0200 Subject: [PATCH 0608/4498] tests: bluetooth: controller: Updated ISO-AL tests for length of err PDU Updated unit tests to match changes in ISO-AL that disregard the length of a received PDU with errors. Signed-off-by: Nirosharn Amarasinghe --- .../ctrl_isoal/src/sub_sets/isoal_test_rx.c | 115 ++++++++---------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c index 5a3c60e0854..fdb86af1f5c 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c @@ -60,19 +60,19 @@ static isoal_status_t custom_sink_sdu_alloc_test(const struct isoal_sink *sink_c #define ZASSERT_ISOAL_SDU_ALLOC_TEST(_typ, _sink, _pdu) \ zassert_equal_ptr(_sink, \ sink_sdu_alloc_test_fake.arg0_##_typ, \ - "\t\t%p != %p", \ + "\t\tExpected alloc sink at %p, got %p.", \ _sink, \ sink_sdu_alloc_test_fake.arg0_##_typ); \ zassert_equal_ptr(_pdu, \ sink_sdu_alloc_test_fake.arg1_##_typ, \ - "\t\t%p != %p", \ + "\t\tExpected alloc PDU buffer at %p, got %p.", \ _pdu, \ sink_sdu_alloc_test_fake.arg1_##_typ) #define ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_alloc_test_fake.call_count, \ - "Expected %u got %u", \ + "Expected alloc called %u times, actual %u.", \ _expected, \ sink_sdu_alloc_test_fake.call_count) @@ -125,59 +125,59 @@ static isoal_status_t custom_sink_sdu_emit_test(const struct isoal_sink *sink_ct _sdu_status) \ zassert_equal_ptr(_sink, \ sink_sdu_emit_test_fake.arg0_##_typ, \ - "\t\t%p != %p", \ + "\t\tExpected sink at %p, got %p.", \ _sink, \ sink_sdu_emit_test_fake.arg0_##_typ); \ zassert_equal(_state, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state, \ - "\t\t%d != %d", \ - _state, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state); \ + "\t\tExpected SDU state '%s', got '%s'.", \ + STATE_TO_STR(_state), \ + STATE_TO_STR(sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state)); \ zassert_equal(_frag_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_frag_size, \ - "\t\t%d != %d", \ + "\t\tExpected SDU frag of size %u, got %u.", \ _frag_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_frag_size); \ zassert_equal(_frag_status, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status, \ - "\t\t%d != %d", \ - _frag_status, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status); \ + "\t\tExpected SDU with status '%s', got '%s'.", \ + DU_ERR_TO_STR(_frag_status), \ + DU_ERR_TO_STR(sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status)); \ zassert_equal(_timestamp, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.timestamp, \ - "\t\t%d != %d", \ + "\t\tExpected SDU with timestamp %u, got %u.", \ _timestamp, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.timestamp); \ zassert_equal(_sn, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.sn, \ - "\t\t%d != %d", \ + "\t\tExpected SDU with sequence number %u, got %u.", \ _sn, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.sn); \ - zassert_equal(_dbuf, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf, \ - "\t\t%p != %p", \ - _dbuf, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf); \ + zassert_equal_ptr(_dbuf, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf, \ + "\t\tExpected SDU data buffer at %p, got %p.", \ + _dbuf, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf); \ zassert_equal(_dbuf_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.size, \ - "\t\t%d != %d", \ + "\t\tExpected SDU data buffer of size %u, got %u.", \ _dbuf_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.size); \ zassert_equal(_total_sz, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.total_sdu_size, \ - "\t\t%d != %d", \ + "\t\tExpected total size of SDU %u,got %u.", \ _total_sz, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.total_sdu_size); \ zassert_equal(_sdu_status, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status, \ - "\t\t%d != %d", \ - _sdu_status, \ - sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status) + "\t\tExpected SDU with status '%s', got '%s'.", \ + DU_ERR_TO_STR(_sdu_status), \ + DU_ERR_TO_STR(sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status)) #define ZASSERT_ISOAL_SDU_EMIT_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_emit_test_fake.call_count, \ - "Expected %u got %u", \ + "Expected emit called %u times, actual %u.", \ _expected, \ sink_sdu_emit_test_fake.call_count) @@ -212,24 +212,24 @@ custom_sink_sdu_write_test(void *dbuf, const uint8_t *pdu_payload, const size_t #define ZASSERT_ISOAL_SDU_WRITE_TEST(_typ, _frag_buf, _payload_buf, _length) \ zassert_equal_ptr(_frag_buf, \ sink_sdu_write_test_fake.arg0_##_typ, \ - "\t\t%p != %p", \ + "\t\tExpected write buffer at %p, got %p.", \ _frag_buf, \ sink_sdu_write_test_fake.arg0_##_typ); \ zassert_equal_ptr(_payload_buf, \ sink_sdu_write_test_fake.arg1_##_typ, \ - "\t\t%p != %p", \ + "\t\tExpected write source at %p, got %p.", \ _payload_buf, \ sink_sdu_write_test_fake.arg1_##_typ); \ zassert_equal(_length, \ sink_sdu_write_test_fake.arg2_##_typ, \ - "\t\t%d != %d", \ + "\t\tExpected write length of %u, got %u.", \ _length, \ sink_sdu_write_test_fake.arg2_##_typ) #define ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_write_test_fake.call_count, \ - "Expected %u got %u", \ + "Expected write called %u times, actual %u.", \ _expected, \ sink_sdu_write_test_fake.call_count) @@ -2767,7 +2767,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) seqn = 0; testdata_indx = 0; testdata_size = 13; - sdu_size = 13; + sdu_size = 0; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -2804,11 +2804,9 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); + /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -2838,7 +2836,6 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency); testdata_indx = testdata_size; testdata_size += 10; - sdu_size = 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -2866,11 +2863,9 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); + /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -3239,7 +3234,6 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err1) payload_number++; testdata_indx = testdata_size; testdata_size += 10; - sdu_size += 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -3263,12 +3257,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err1) /* Test recombine (Black Box) */ /* A new SDU should not be allocated */ + ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(1); + + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -3535,7 +3528,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err2) payload_number++; testdata_indx = testdata_size; testdata_size += 10; - sdu_size = 10; + sdu_size = 0; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, 50); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -3565,11 +3558,9 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err2) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); + /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -4569,7 +4560,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_padding_error1) seqn = 0; testdata_indx = 0; testdata_size = 13; - sdu_size = 13; + sdu_size = 0; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -4607,11 +4598,9 @@ ZTEST(test_rx_unframed, test_rx_unframed_padding_error1) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); + /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -5935,7 +5924,6 @@ ZTEST(test_rx_unframed, test_rx_unframed_dbl_pdu_invalid_llid2_pdu_err) payload_number++; testdata_indx = testdata_size; testdata_size += 10; - sdu_size += 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -5958,12 +5946,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_dbl_pdu_invalid_llid2_pdu_err) /* Test recombine (Black Box) */ /* A new SDU should not be allocated */ + ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(1); + + /* SDU payload should not be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); - /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf, /* SDU buffer */ - &rx_pdu_meta_buf.pdu[3], /* PDU payload */ - (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ From b96436296fc593329325a03689896d73193a1589 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Fri, 8 Sep 2023 16:37:40 +0200 Subject: [PATCH 0609/4498] Bluetooth: controller: Included kconfigs for ISO-AL logging Included kconfigs to set the ISO-AL logging level and control debug logging verbosity. Signed-off-by: Nirosharn Amarasinghe --- subsys/bluetooth/Kconfig.logging | 17 +++++++++++++++++ subsys/bluetooth/controller/Kconfig | 7 +++++++ subsys/bluetooth/controller/ll_sw/isoal.c | 6 +++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/Kconfig.logging b/subsys/bluetooth/Kconfig.logging index 67a18afa919..addf8eb65fe 100644 --- a/subsys/bluetooth/Kconfig.logging +++ b/subsys/bluetooth/Kconfig.logging @@ -398,6 +398,16 @@ config BT_DEBUG_SERVICE This option enables debug support for the Bluetooth Services. +# CONTROLLER (subsys/bluetooth/controller/Kconfig) + +config BT_CTLR_DEBUG_ISOAL + bool "[DEPRECATED] Bluetooth ISO-AL debug" + select DEPRECATED + depends on BT_CTLR_ISO + help + This option enables debug support for the Bluetooth ISO-AL. + + endmenu # [DEPRECATED] Others menu "[DEPRECATED] BR/EDR" @@ -900,6 +910,13 @@ legacy-debug-sym = BT_DEBUG_SERVICE module-str = "Bluetooth Services" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" +# CONTROLLER (subsys/bluetooth/controller/Kconfig) + +module = BT_CTLR_ISOAL +legacy-debug-sym = BT_CTLR_DEBUG_ISOAL +module-str = "Bluetooth Controller ISO-AL" +source "subsys/bluetooth/common/Kconfig.template.log_config_bt" + endmenu # Others menu "BR/EDR" diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index cfa265f595b..9a3b2bdf437 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -206,6 +206,13 @@ config BT_CTLR_ISO_TX_BUFFER_SIZE Size of the Isochronous Tx buffers and the value returned in HCI LE Read Buffer Size V2 command response. +config BT_CTLR_ISOAL_LOG_DBG_VERBOSE + bool "ISO-AL verbose debug logging" + depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 + default n + help + Use this option to enable ISO-AL verbose debug logging. + config BT_CTLR_ISOAL_SOURCES int "Number of Isochronous Adaptation Layer sources" depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 6c1dedd7b9d..d43233f0289 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -36,15 +36,15 @@ #include -LOG_MODULE_REGISTER(bt_ctlr_isoal, LOG_LEVEL_INF); +LOG_MODULE_REGISTER(bt_ctlr_isoal, CONFIG_BT_CTLR_ISOAL_LOG_LEVEL); #define ISOAL_LOG_DBG(...) LOG_DBG(__VA_ARGS__) -#if defined(ISOAL_DEBUG_VERBOSE) +#if defined(CONFIG_BT_CTLR_ISOAL_LOG_DBG_VERBOSE) #define ISOAL_LOG_DBGV(...) LOG_DBG(__VA_ARGS__) #else #define ISOAL_LOG_DBGV(...) (void) 0 -#endif /* ISOAL_DEBUG_VERBOSE */ +#endif /* CONFIG_BT_CTLR_ISOAL_LOG_DBG_VERBOSE */ #include "hal/debug.h" From 467ec2e6b7b4f4a235cc0c401e378a50f735dfe1 Mon Sep 17 00:00:00 2001 From: Nirosharn Amarasinghe Date: Fri, 8 Sep 2023 17:03:06 +0200 Subject: [PATCH 0610/4498] tests: bluetooth: controller: Included kconfigs for ISO-AL logging Included kconfigs to set the ISO-AL logging level and control debug logging verbosity in ISO-AL unit tests. Signed-off-by: Nirosharn Amarasinghe --- tests/bluetooth/ctrl_isoal/Kconfig | 19 +++++++++++++++++++ tests/bluetooth/ctrl_isoal/prj.conf | 2 ++ 2 files changed, 21 insertions(+) diff --git a/tests/bluetooth/ctrl_isoal/Kconfig b/tests/bluetooth/ctrl_isoal/Kconfig index b7c10723b93..30049d53a5e 100644 --- a/tests/bluetooth/ctrl_isoal/Kconfig +++ b/tests/bluetooth/ctrl_isoal/Kconfig @@ -12,6 +12,25 @@ config BT_CTLR_CONN_ISO_GROUPS range 1 240 default 1 +config BT_CTLR_DEBUG_ISOAL + bool "[DEPRECATED] Bluetooth ISO-AL debug" + select DEPRECATED + depends on BT_CTLR_ISO + help + This option enables debug support for the Bluetooth ISO-AL. + +module = BT_CTLR_ISOAL +legacy-debug-sym = BT_CTLR_DEBUG_ISOAL +module-str = "Bluetooth Controller ISO-AL" +source "subsys/bluetooth/common/Kconfig.template.log_config_bt" + +config BT_CTLR_ISOAL_LOG_DBG_VERBOSE + bool "ISO-AL verbose debug logging" + depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 + default n + help + Use this option to enable ISO-AL verbose debug logging. + config BT_CTLR_ISOAL_SINKS int "Number of Isochronous Adaptation Layer sinks (for unit tests)" diff --git a/tests/bluetooth/ctrl_isoal/prj.conf b/tests/bluetooth/ctrl_isoal/prj.conf index 5009e2785f8..2f429dd8c47 100644 --- a/tests/bluetooth/ctrl_isoal/prj.conf +++ b/tests/bluetooth/ctrl_isoal/prj.conf @@ -9,3 +9,5 @@ CONFIG_BT_CTLR_CONN_ISO=y CONFIG_BT_CTLR_ISOAL_SINKS=4 CONFIG_BT_CTLR_ISOAL_SOURCES=4 CONFIG_BT_CTLR_ISO_RX_SDU_BUFFERS=4 + +CONFIG_BT_CTLR_ISOAL_LOG_LEVEL_INF=y From c9bc07a4f3dd28120fb481c803190b12172defa4 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 15 Sep 2023 13:45:56 +0200 Subject: [PATCH 0611/4498] modem: chat: Add synchronous functions for script exec This commit adds one new feature, modem_chat_run_script(), which synchronously runs a script. The existing function modem_chat_script_run() is async, and doesn't follow the naming convention created for the other modem modules, specifically, all functions are sync, unless appended with _async. To preserve backwards compatibility, the existing function modem_chat_script_run() will remain until deprecated. It simply calls modem_chat_run_script_async(). Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/chat.h | 34 ++++++++++++++++++++++++++++++-- subsys/modem/modem_chat.c | 39 ++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index 17c23c25892..d9cbe9fc80c 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -227,6 +227,8 @@ struct modem_chat { struct k_work script_abort_work; uint16_t script_chat_it; atomic_t script_state; + enum modem_chat_script_result script_result; + struct k_sem script_stopped_sem; /* Script sending */ uint16_t script_send_request_pos; @@ -293,6 +295,18 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con */ int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe); +/** + * @brief Run script asynchronously + * @param chat Chat instance + * @param script Script to run + * @returns 0 if script successfully started + * @returns -EBUSY if a script is currently running + * @returns -EPERM if modem pipe is not attached + * @returns -EINVAL if arguments or script is invalid + * @note Script runs asynchronously until complete or aborted. + */ +int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat_script *script); + /** * @brief Run script * @param chat Chat instance @@ -301,9 +315,25 @@ int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe); * @returns -EBUSY if a script is currently running * @returns -EPERM if modem pipe is not attached * @returns -EINVAL if arguments or script is invalid - * @note Script runs asynchronously until complete or aborted. + * @note Script runs until complete or aborted. */ -int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_script *script); +int modem_chat_run_script(struct modem_chat *chat, const struct modem_chat_script *script); + +/** + * @brief Run script asynchronously + * @note Function exists for backwards compatibility and should be deprecated + * @param chat Chat instance + * @param script Script to run + * @returns 0 if script successfully started + * @returns -EBUSY if a script is currently running + * @returns -EPERM if modem pipe is not attached + * @returns -EINVAL if arguments or script is invalid + */ +static inline int modem_chat_script_run(struct modem_chat *chat, + const struct modem_chat_script *script) +{ + return modem_chat_run_script_async(chat, script); +} /** * @brief Abort script diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index bd5824da9a6..f6d88624026 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -69,9 +69,6 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri LOG_WRN("%s: timed out", chat->script->name); } - /* Clear script running state */ - atomic_clear_bit(&chat->script_state, MODEM_CHAT_SCRIPT_STATE_RUNNING_BIT); - /* Call back with result */ if (chat->script->callback != NULL) { chat->script->callback(chat, result, chat->user_data); @@ -88,6 +85,15 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri /* Cancel timeout work */ k_work_cancel_delayable(&chat->script_timeout_work); + + /* Clear script running state */ + atomic_clear_bit(&chat->script_state, MODEM_CHAT_SCRIPT_STATE_RUNNING_BIT); + + /* Store result of script for script stoppted indication */ + chat->script_result = result; + + /* Indicate script stopped */ + k_sem_give(&chat->script_stopped_sem); } static void modem_chat_script_send(struct modem_chat *chat) @@ -680,9 +686,6 @@ static void modem_chat_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_ev } } -/********************************************************* - * GLOBAL FUNCTIONS - *********************************************************/ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *config) { __ASSERT_NO_MSG(chat != NULL); @@ -711,6 +714,7 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con chat->matches_size[MODEM_CHAT_MATCHES_INDEX_UNSOL] = config->unsol_matches_size; chat->process_timeout = config->process_timeout; atomic_set(&chat->script_state, 0); + k_sem_init(&chat->script_stopped_sem, 0, 1); k_work_init_delayable(&chat->process_work, modem_chat_process_handler); k_work_init(&chat->script_run_work, modem_chat_script_run_handler); k_work_init_delayable(&chat->script_timeout_work, modem_chat_script_timeout_handler); @@ -730,7 +734,7 @@ int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe) return 0; } -int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_script *script) +int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat_script *script) { bool script_is_running; @@ -764,6 +768,25 @@ int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_scrip return 0; } +int modem_chat_run_script(struct modem_chat *chat, const struct modem_chat_script *script) +{ + int ret; + + k_sem_reset(&chat->script_stopped_sem); + + ret = modem_chat_run_script_async(chat, script); + if (ret < 0) { + return ret; + } + + ret = k_sem_take(&chat->script_stopped_sem, K_FOREVER); + if (ret < 0) { + return ret; + } + + return chat->script_result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS ? 0 : -EAGAIN; +} + void modem_chat_script_abort(struct modem_chat *chat) { k_work_submit(&chat->script_abort_work); @@ -789,6 +812,8 @@ void modem_chat_release(struct modem_chat *chat) chat->script = NULL; chat->script_chat_it = 0; atomic_set(&chat->script_state, 0); + chat->script_result = MODEM_CHAT_SCRIPT_RESULT_ABORT; + k_sem_reset(&chat->script_stopped_sem); chat->script_send_request_pos = 0; chat->script_send_delimiter_pos = 0; chat->parse_match = NULL; From add09f389bd365c89f74d42dc5e0cda328e842b8 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 15 Sep 2023 14:31:11 +0200 Subject: [PATCH 0612/4498] tests: modem: Add tests for sync script run functions This commit adds tests to validate the behavior of the new script run functions. Signed-off-by: Bjarki Arge Andreasen --- tests/subsys/modem/modem_chat/src/main.c | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/subsys/modem/modem_chat/src/main.c b/tests/subsys/modem/modem_chat/src/main.c index 6af24bffaa8..ccd6e785bd9 100644 --- a/tests/subsys/modem/modem_chat/src/main.c +++ b/tests/subsys/modem/modem_chat/src/main.c @@ -193,6 +193,34 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE( MODEM_CHAT_SCRIPT_DEFINE(script_partial, script_partial_cmds, abort_matches, on_script_result, 4); +/*************************************************************************************************/ +/* Small echo script and mock transactions */ +/*************************************************************************************************/ +static const uint8_t at_echo_data[] = {'A', 'T', '\r', '\n'}; +static const struct modem_backend_mock_transaction at_echo_transaction = { + .get = at_echo_data, + .get_size = sizeof(at_echo_data), + .put = at_echo_data, + .put_size = sizeof(at_echo_data), +}; + +static const uint8_t at_echo_error_data[] = {'E', 'R', 'R', 'O', 'R', ' ', '1', '\r', '\n'}; +static const struct modem_backend_mock_transaction at_echo_error_transaction = { + .get = at_echo_data, + .get_size = sizeof(at_echo_data), + .put = at_echo_error_data, + .put_size = sizeof(at_echo_error_data), +}; + +MODEM_CHAT_MATCH_DEFINE(at_match, "AT", "", NULL); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE( + script_echo_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT", at_match), +); + +MODEM_CHAT_SCRIPT_DEFINE(script_echo, script_echo_cmds, abort_matches, on_script_result, 4); + /*************************************************************************************************/ /* Script responses */ /*************************************************************************************************/ @@ -519,6 +547,25 @@ ZTEST(modem_chat, test_script_with_partial_matches) "Script sent too many requests"); } +ZTEST(modem_chat, test_script_run_sync_complete) +{ + modem_backend_mock_prime(&mock, &at_echo_transaction); + zassert_ok(modem_chat_run_script(&cmd, &script_echo), "Failed to run echo script"); +} + +ZTEST(modem_chat, test_script_run_sync_timeout) +{ + zassert_equal(modem_chat_run_script(&cmd, &script_echo), -EAGAIN, + "Failed to run echo script"); +} + +ZTEST(modem_chat, test_script_run_sync_abort) +{ + modem_backend_mock_prime(&mock, &at_echo_error_transaction); + zassert_equal(modem_chat_run_script(&cmd, &script_echo), -EAGAIN, + "Echo script should time out and return -EAGAIN"); +} + /*************************************************************************************************/ /* Test suite */ /*************************************************************************************************/ From 328b588ceb0a4d1aef5a7d204de393aca24ecdfb Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 15 Sep 2023 17:42:27 +0200 Subject: [PATCH 0613/4498] drivers: modem: modem_cellular: Update script run function This commit updates the modem_cellular driver to use the new naming scheme for the modem_chat functions. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/modem_cellular.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 9cad08332a7..9d13b65dedc 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -591,7 +591,7 @@ static void modem_cellular_run_init_script_event_handler(struct modem_cellular_d switch (evt) { case MODEM_CELLULAR_EVENT_BUS_OPENED: modem_chat_attach(&data->chat, data->uart_pipe); - modem_chat_script_run(&data->chat, config->init_chat_script); + modem_chat_run_script_async(&data->chat, config->init_chat_script); break; case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: @@ -740,7 +740,7 @@ static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_d switch (evt) { case MODEM_CELLULAR_EVENT_TIMEOUT: modem_chat_attach(&data->chat, data->dlci1_pipe); - modem_chat_script_run(&data->chat, config->dial_chat_script); + modem_chat_run_script_async(&data->chat, config->dial_chat_script); break; case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: From 586504bed8439f236c2ebb655eb2251ab52c0d41 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 16 Sep 2023 10:52:22 +0200 Subject: [PATCH 0614/4498] modem: chat: Track size of script_chat request to avoid strlen() This commit optimizes the performance of the script chats by storing the size of requests with the chat script chat, negating the need to use strlen() within the modem_chat module every time a chat script chat request is sent. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/chat.h | 43 ++++++++++++++++++++++--------------- subsys/modem/modem_chat.c | 13 ++++++----- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index d9cbe9fc80c..188c04657b3 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -35,21 +35,19 @@ typedef void (*modem_chat_match_callback)(struct modem_chat *chat, char **argv, * @brief Modem chat match */ struct modem_chat_match { - /* Match array */ + /** Match array */ const uint8_t *match; + /** Size of match */ const uint8_t match_size; - - /* Separators array */ + /** Separators array */ const uint8_t *separators; + /** Size of separators array */ const uint8_t separators_size; - - /* Set if modem chat instance shall use wildcards when matching */ + /** Set if modem chat instance shall use wildcards when matching */ const uint8_t wildcards : 1; - - /* Set if script shall not continue to next step in case of match */ + /** Set if script shall not continue to next step in case of match */ const uint8_t partial : 1; - - /* Type of modem chat instance */ + /** Type of modem chat instance */ const modem_chat_match_callback callback; }; @@ -90,9 +88,11 @@ struct modem_chat_match { * @brief Modem chat script chat */ struct modem_chat_script_chat { - /** Request to send to modem formatted as char string */ - const char *request; - /** Expected responses to request */ + /** Request to send to modem */ + const uint8_t *request; + /** Size of request */ + uint8_t request_size; + /** Array of expected responses to request */ const struct modem_chat_match *const response_matches; /** Number of elements in expected responses */ const uint16_t response_matches_size; @@ -102,19 +102,28 @@ struct modem_chat_script_chat { #define MODEM_CHAT_SCRIPT_CMD_RESP(_request, _response_match) \ { \ - .request = _request, .response_matches = &_response_match, \ - .response_matches_size = 1, .timeout = 0, \ + .request = (uint8_t *)(_request), \ + .request_size = (uint8_t)(sizeof(_request) - 1), \ + .response_matches = &_response_match, \ + .response_matches_size = 1, \ + .timeout = 0, \ } #define MODEM_CHAT_SCRIPT_CMD_RESP_MULT(_request, _response_matches) \ { \ - .request = _request, .response_matches = _response_matches, \ - .response_matches_size = ARRAY_SIZE(_response_matches), .timeout = 0, \ + .request = (uint8_t *)(_request), \ + .request_size = (uint8_t)(sizeof(_request) - 1), \ + .response_matches = _response_matches, \ + .response_matches_size = ARRAY_SIZE(_response_matches), \ + .timeout = 0, \ } #define MODEM_CHAT_SCRIPT_CMD_RESP_NONE(_request, _timeout) \ { \ - .request = _request, .response_matches = NULL, .response_matches_size = 0, \ + .request = (uint8_t *)(_request), \ + .request_size = (uint8_t)(sizeof(_request) - 1), \ + .response_matches = NULL, \ + .response_matches_size = 0, \ .timeout = _timeout, \ } diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index f6d88624026..fb934f7732c 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -135,8 +135,8 @@ static void modem_chat_script_next(struct modem_chat *chat, bool initial) chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = script_chat->response_matches_size; /* Check if work must be sent */ - if (strlen(script_chat->request) > 0) { - LOG_DBG("sending: %s", script_chat->request); + if (script_chat->request_size > 0) { + LOG_DBG("sending: %.*s", script_chat->request_size, script_chat->request); modem_chat_script_send(chat); } } @@ -196,18 +196,17 @@ static bool modem_chat_script_send_request(struct modem_chat *chat) const struct modem_chat_script_chat *script_chat = &chat->script->script_chats[chat->script_chat_it]; - uint16_t script_chat_request_size = strlen(script_chat->request); uint8_t *script_chat_request_start; uint16_t script_chat_request_remaining; int ret; /* Validate data to send */ - if (script_chat_request_size == chat->script_send_request_pos) { + if (script_chat->request_size == chat->script_send_request_pos) { return true; } script_chat_request_start = (uint8_t *)&script_chat->request[chat->script_send_request_pos]; - script_chat_request_remaining = script_chat_request_size - chat->script_send_request_pos; + script_chat_request_remaining = script_chat->request_size - chat->script_send_request_pos; /* Send data through pipe */ ret = modem_pipe_transmit(chat->pipe, script_chat_request_start, @@ -222,7 +221,7 @@ static bool modem_chat_script_send_request(struct modem_chat *chat) chat->script_send_request_pos += (uint16_t)ret; /* Check if data remains */ - if (chat->script_send_request_pos < script_chat_request_size) { + if (chat->script_send_request_pos < script_chat->request_size) { return false; } @@ -750,7 +749,7 @@ int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat /* Validate script commands */ for (uint16_t i = 0; i < script->script_chats_size; i++) { - if ((strlen(script->script_chats[i].request) == 0) && + if ((script->script_chats[i].request_size == 0) && (script->script_chats[i].response_matches_size == 0)) { return -EINVAL; } From 7310adaa49dca0100f5895cc17d0225e2a01e2d1 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 15 Sep 2023 17:57:57 +0200 Subject: [PATCH 0615/4498] modem: chat: Optimize const usage This commit removes const declarations for members inside structures used for chat scripts to allow for modifying them at runtime. Macros like MODEM_CHAT_SCRIPT_DEFINE() cover the whole struct when declaring them const, ensuring they remain placed in ROM. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/chat.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index 188c04657b3..746e122135e 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -38,17 +38,17 @@ struct modem_chat_match { /** Match array */ const uint8_t *match; /** Size of match */ - const uint8_t match_size; + uint8_t match_size; /** Separators array */ const uint8_t *separators; /** Size of separators array */ - const uint8_t separators_size; + uint8_t separators_size; /** Set if modem chat instance shall use wildcards when matching */ - const uint8_t wildcards : 1; + uint8_t wildcards : 1; /** Set if script shall not continue to next step in case of match */ - const uint8_t partial : 1; + uint8_t partial : 1; /** Type of modem chat instance */ - const modem_chat_match_callback callback; + modem_chat_match_callback callback; }; #define MODEM_CHAT_MATCH(_match, _separators, _callback) \ @@ -92,10 +92,10 @@ struct modem_chat_script_chat { const uint8_t *request; /** Size of request */ uint8_t request_size; - /** Array of expected responses to request */ - const struct modem_chat_match *const response_matches; + /** Expected responses to request */ + const struct modem_chat_match *response_matches; /** Number of elements in expected responses */ - const uint16_t response_matches_size; + uint16_t response_matches_size; /** Timeout before chat script may continue to next step in milliseconds */ uint16_t timeout; }; @@ -128,7 +128,7 @@ struct modem_chat_script_chat { } #define MODEM_CHAT_SCRIPT_CMDS_DEFINE(_sym, ...) \ - const static struct modem_chat_script_chat _sym[] = {__VA_ARGS__} + const struct modem_chat_script_chat _sym[] = {__VA_ARGS__} enum modem_chat_script_result { MODEM_CHAT_SCRIPT_RESULT_SUCCESS, @@ -155,15 +155,15 @@ struct modem_chat_script { /** Array of script chats */ const struct modem_chat_script_chat *script_chats; /** Elements in array of script chats */ - const uint16_t script_chats_size; + uint16_t script_chats_size; /** Array of abort matches */ - const struct modem_chat_match *const abort_matches; + const struct modem_chat_match *abort_matches; /** Number of elements in array of abort matches */ - const uint16_t abort_matches_size; + uint16_t abort_matches_size; /** Callback called when script execution terminates */ modem_chat_script_callback callback; /** Timeout in seconds within which the script execution must terminate */ - const uint32_t timeout; + uint32_t timeout; }; #define MODEM_CHAT_SCRIPT_DEFINE(_sym, _script_chats, _abort_matches, _callback, _timeout) \ From f007f21b3ce2b85f941e8b5d1fc6386ee7fc45d3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 15 Sep 2023 20:45:31 +0200 Subject: [PATCH 0616/4498] modem: chat: Add test for runtime chat scripts This commit adds a test to ensure chat scripts can be created and modified at runtime. Signed-off-by: Bjarki Arge Andreasen --- tests/subsys/modem/modem_chat/src/main.c | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/subsys/modem/modem_chat/src/main.c b/tests/subsys/modem/modem_chat/src/main.c index ccd6e785bd9..3f1ef57754d 100644 --- a/tests/subsys/modem/modem_chat/src/main.c +++ b/tests/subsys/modem/modem_chat/src/main.c @@ -566,6 +566,51 @@ ZTEST(modem_chat, test_script_run_sync_abort) "Echo script should time out and return -EAGAIN"); } +ZTEST(modem_chat, test_script_run_dynamic_script_sync) +{ + char match[] = "AT"; + char separators[] = ","; + char request[] = "AT"; + char name[] = "Dynamic"; + + struct modem_chat_match stack_response_match = { + .match = NULL, + .match_size = 0, + .separators = NULL, + .separators_size = 0, + .wildcards = false, + .partial = false, + .callback = NULL, + }; + + struct modem_chat_script_chat stack_script_chat = { + .request = NULL, + .response_matches = &stack_response_match, + .response_matches_size = 1, + .timeout = 0, + }; + + struct modem_chat_script stack_script = { + .name = name, + .script_chats = &stack_script_chat, + .script_chats_size = 1, + .abort_matches = NULL, + .abort_matches_size = 0, + .callback = NULL, + .timeout = 1, + }; + + stack_response_match.match = match; + stack_response_match.match_size = strlen(match); + stack_response_match.separators = separators; + stack_response_match.separators_size = strlen(match); + stack_script_chat.request = request; + stack_script_chat.request_size = strlen(request); + + modem_backend_mock_prime(&mock, &at_echo_transaction); + zassert_ok(modem_chat_run_script(&cmd, &stack_script), "Failed to run script"); +} + /*************************************************************************************************/ /* Test suite */ /*************************************************************************************************/ From f53a0e9ce5a3ba23444580155a72ba768ba9cc74 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 15 Sep 2023 15:21:06 +0200 Subject: [PATCH 0617/4498] twister: Allow an empty quarantine file Added an exception to scl.py module, to not process an empty yaml file, because of error from pykwalify. New exception is handled when processing quarantine files, to allow an empty file. Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/scl.py | 7 +++++++ scripts/pylib/twister/twisterlib/testplan.py | 9 ++++++--- scripts/tests/twister/test_scl.py | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/scl.py b/scripts/pylib/twister/scl.py index 2518e4b4138..bbd9f6d19d0 100644 --- a/scripts/pylib/twister/scl.py +++ b/scripts/pylib/twister/scl.py @@ -21,6 +21,11 @@ log = logging.getLogger("scl") + +class EmptyYamlFileException(Exception): + pass + + # # def yaml_load(filename): @@ -78,5 +83,7 @@ def yaml_load_verify(filename, schema): """ # 'document.yaml' contains a single YAML document. y = yaml_load(filename) + if not y: + raise EmptyYamlFileException('No data in YAML file: %s' % filename) _yaml_validate(y, schema) return y diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 0199c6e1ef5..7c837000672 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -194,8 +194,11 @@ def discover(self): raise TwisterRuntimeError("No quarantine list given to be verified") if ql: for quarantine_file in ql: - # validate quarantine yaml file against the provided schema - scl.yaml_load_verify(quarantine_file, self.quarantine_schema) + try: + # validate quarantine yaml file against the provided schema + scl.yaml_load_verify(quarantine_file, self.quarantine_schema) + except scl.EmptyYamlFileException: + logger.debug(f'Quarantine file {quarantine_file} is empty') self.quarantine = Quarantine(ql) def load(self): @@ -454,7 +457,7 @@ def add_configurations(self): # if there is already an existed _.yaml, then use it to # load platform directly, otherwise, iterate the directory to # get all valid board revision based on each _.conf. - if not "@" in platform.name: + if '@' not in platform.name: tmp_dir = os.listdir(os.path.dirname(file)) for item in tmp_dir: # Need to make sure the revision matches diff --git a/scripts/tests/twister/test_scl.py b/scripts/tests/twister/test_scl.py index f070b0977b7..e334df17e2b 100644 --- a/scripts/tests/twister/test_scl.py +++ b/scripts/tests/twister/test_scl.py @@ -247,3 +247,10 @@ def mock_core(source_data, schema_data, *args, **kwargs): core_mock.assert_called_once() else: core_mock.assert_not_called() + + +def test_yaml_load_empty_file(tmp_path): + quarantine_file = tmp_path / 'empty_quarantine.yml' + quarantine_file.write_text("# yaml file without data") + with pytest.raises(scl.EmptyYamlFileException): + scl.yaml_load_verify(quarantine_file, None) From a9aed0bb51fd25d49e3fd03f879f5611343a5277 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 18 Sep 2023 10:42:41 +0000 Subject: [PATCH 0618/4498] boards: raytec_mdbt53: add input codes Add input codes to the gpio-keys devices, this makes the board build correctly with the input samples, that are currently failing to build in CI. Signed-off-by: Fabio Baltieri --- .../raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts | 5 +++++ .../raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts index 5c67687a002..21cc368f959 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi" +#include / { @@ -50,18 +51,22 @@ button0: button_0 { gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 1 (SW1)"; + zephyr,code = ; }; button1: button_1 { gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 2 (SW2)"; + zephyr,code = ; }; button2: button_2 { gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 3 (SW3)"; + zephyr,code = ; }; button3: button_3 { gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 4 (SW4)"; + zephyr,code = ; }; }; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts index ca020adaa35..79887dba909 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi" +#include / { @@ -38,14 +39,17 @@ button0: button_0 { gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 1"; + zephyr,code = ; }; button1: button_1 { gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 2"; + zephyr,code = ; }; button2: button_2 { gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button 3"; + zephyr,code = ; }; }; From 0b24aaad2c9a10c2b8a3d8d035bd914a5e946e96 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 7 Sep 2023 16:45:16 +0300 Subject: [PATCH 0619/4498] net: socket: Use network interface name length for IFNAMSIZ If the network interface naming is enabled, then use the interface name length (CONFIG_NET_INTERFACE_NAME_LEN) for IFNAMSIZ instead of device name length. Signed-off-by: Jukka Rissanen --- include/zephyr/net/socket.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index ff7b2cc2281..684c74a7037 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -995,7 +995,11 @@ static inline char *inet_ntop(sa_family_t family, const void *src, char *dst, #define EAI_FAMILY DNS_EAI_FAMILY #endif /* defined(CONFIG_NET_SOCKETS_POSIX_NAMES) */ +#if defined(CONFIG_NET_INTERFACE_NAME) +#define IFNAMSIZ CONFIG_NET_INTERFACE_NAME_LEN +#else #define IFNAMSIZ Z_DEVICE_MAX_NAME_LEN +#endif /** Interface description structure */ struct ifreq { From f67dd39bb290fc28a03a1ab86265090e0ed0512a Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 7 Jul 2023 00:30:04 +0200 Subject: [PATCH 0620/4498] drivers: ramdisk: use devicetree to instantiate RAM disk Rework RAM disk driver to be configured using devicetree and support multiple instances. This patch also removes a copy of the RAM disk driver, tests/subsys/fs/fat_fs_dual_drive/src/disk_access_test_drv.c, that was there for testing multiple disk drivers support. Bonus: one SYS_INIT() less and a memory region can be exported to the host. Signed-off-by: Johann Fischer --- doc/connectivity/usb/device/usb_device.rst | 9 +- drivers/disk/Kconfig.ram | 13 +- drivers/disk/ramdisk.c | 115 ++++++++++++++---- dts/bindings/disk/zephyr,ram-disk.yaml | 35 ++++++ samples/subsys/fs/format/prj_ram.conf | 2 - samples/subsys/fs/format/ramdisk.overlay | 14 +++ samples/subsys/fs/format/sample.yaml | 4 +- .../cdc_acm/overlay-composite-cdc-msc.conf | 3 - samples/subsys/usb/cdc_acm/ramdisk.overlay | 14 +++ samples/subsys/usb/cdc_acm/sample.yaml | 4 +- samples/subsys/usb/mass/Kconfig | 5 - samples/subsys/usb/mass/ramdisk.overlay | 14 +++ samples/subsys/usb/mass/sample.yaml | 12 +- .../disk_access/boards/qemu_x86_64.overlay | 7 ++ tests/drivers/disk/disk_access/src/main.c | 2 +- tests/drivers/disk/disk_access/testcase.yaml | 2 - .../drivers/disk/disk_performance/src/main.c | 2 - tests/posix/fs/app.overlay | 14 +++ tests/posix/fs/prj.conf | 2 - tests/subsys/fs/ext2/prj.conf | 1 - tests/subsys/fs/ext2/prj_big.conf | 1 - tests/subsys/fs/ext2/ramdisk_big.overlay | 14 +++ tests/subsys/fs/ext2/ramdisk_small.overlay | 14 +++ tests/subsys/fs/ext2/testcase.yaml | 6 +- .../fs/fat_fs_api/prj_native_posix_ram.conf | 1 - tests/subsys/fs/fat_fs_api/ramdisk.overlay | 14 +++ tests/subsys/fs/fat_fs_api/src/test_fat.h | 2 +- tests/subsys/fs/fat_fs_api/testcase.yaml | 4 +- tests/subsys/fs/fat_fs_dual_drive/app.overlay | 21 ++++ tests/subsys/fs/fat_fs_dual_drive/prj.conf | 1 - .../src/disk_access_test_drv.c | 97 --------------- tests/subsys/fs/multi-fs/prj.conf | 2 - tests/subsys/fs/multi-fs/prj_fs_shell.conf | 2 - tests/subsys/fs/multi-fs/ramdisk.overlay | 14 +++ tests/subsys/fs/multi-fs/testcase.yaml | 6 +- 35 files changed, 299 insertions(+), 174 deletions(-) create mode 100644 dts/bindings/disk/zephyr,ram-disk.yaml create mode 100644 samples/subsys/fs/format/ramdisk.overlay create mode 100644 samples/subsys/usb/cdc_acm/ramdisk.overlay create mode 100644 samples/subsys/usb/mass/ramdisk.overlay create mode 100644 tests/posix/fs/app.overlay create mode 100644 tests/subsys/fs/ext2/ramdisk_big.overlay create mode 100644 tests/subsys/fs/ext2/ramdisk_small.overlay create mode 100644 tests/subsys/fs/fat_fs_api/ramdisk.overlay create mode 100644 tests/subsys/fs/fat_fs_dual_drive/app.overlay delete mode 100644 tests/subsys/fs/fat_fs_dual_drive/src/disk_access_test_drv.c create mode 100644 tests/subsys/fs/multi-fs/ramdisk.overlay diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index 6b17e2ec2ca..752d6392077 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -286,10 +286,11 @@ access and expose a RAM disk, emulated block device on a flash partition, or SD Card to the host. Only one disk instance can be exported at a time. The disc to be used by the implementation is set by the -:kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME` and should be equal to one -of the options used by the disc access driver that the application wants to expose to -the host, :kconfig:option:`CONFIG_DISK_RAM_VOLUME_NAME`, -:kconfig:option:`CONFIG_MMC_VOLUME_NAME`, or :kconfig:option:`CONFIG_SDMMC_VOLUME_NAME`. +:kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME` and should be the same as the name +used by the disc access driver that the application wants to expose to the host. +SD card disk drivers use options :kconfig:option:`CONFIG_MMC_VOLUME_NAME` or +:kconfig:option:`CONFIG_SDMMC_VOLUME_NAME`, and flash and RAM disk drivers use +node property ``disk-name`` to set the disk name. For the emulated block device on a flash partition, the flash partition and flash disk to be used must be described in the devicetree. If a storage partition diff --git a/drivers/disk/Kconfig.ram b/drivers/disk/Kconfig.ram index b662c41fa3a..f09bd3af45f 100644 --- a/drivers/disk/Kconfig.ram +++ b/drivers/disk/Kconfig.ram @@ -3,6 +3,7 @@ config DISK_DRIVER_RAM bool "RAM Disk" + default y if DT_HAS_ZEPHYR_RAM_DISK_ENABLED help RAM buffer used to emulate storage disk. This option can be used to test the file @@ -10,18 +11,6 @@ config DISK_DRIVER_RAM if DISK_DRIVER_RAM -config DISK_RAM_VOLUME_SIZE - int "RAM Disk size in kilobytes" - default 96 - help - Size of the RAM Disk. - -config DISK_RAM_VOLUME_NAME - string "RAM Disk mount point or drive name" - default "RAM" - help - Disk name as per file system naming guidelines. - module = RAMDISK module-str = ramdisk source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/disk/ramdisk.c b/drivers/disk/ramdisk.c index 7c9c8789c85..1d1fcc46a0d 100644 --- a/drivers/disk/ramdisk.c +++ b/drivers/disk/ramdisk.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016 Intel Corporation. - * Copyright (c) 2021, Nordic Semiconductor ASA + * Copyright (c) 2021,2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,15 +15,25 @@ LOG_MODULE_REGISTER(ramdisk, CONFIG_RAMDISK_LOG_LEVEL); -#define RAMDISK_SECTOR_SIZE 512 -#define RAMDISK_VOLUME_SIZE (CONFIG_DISK_RAM_VOLUME_SIZE * 1024) -#define RAMDISK_SECTOR_COUNT (RAMDISK_VOLUME_SIZE / RAMDISK_SECTOR_SIZE) +struct ram_disk_data { + struct disk_info info; + const size_t sector_size; + const size_t sector_count; + uint8_t *const buf; +}; -static uint8_t ramdisk_buf[RAMDISK_VOLUME_SIZE]; +struct ram_disk_config { + const size_t sector_size; + const size_t sector_count; + const size_t size; + uint8_t *const buf; +}; -static void *lba_to_address(uint32_t lba) +static void *lba_to_address(const struct device *dev, uint32_t lba) { - return &ramdisk_buf[lba * RAMDISK_SECTOR_SIZE]; + const struct ram_disk_config *config = dev->config; + + return &config->buf[lba * config->sector_size]; } static int disk_ram_access_status(struct disk_info *disk) @@ -39,15 +49,17 @@ static int disk_ram_access_init(struct disk_info *disk) static int disk_ram_access_read(struct disk_info *disk, uint8_t *buff, uint32_t sector, uint32_t count) { + const struct device *dev = disk->dev; + const struct ram_disk_config *config = dev->config; uint32_t last_sector = sector + count; - if (last_sector < sector || last_sector > RAMDISK_SECTOR_COUNT) { - LOG_ERR("Sector %" PRIu32 " is outside the range %u", - last_sector, RAMDISK_SECTOR_COUNT); + if (last_sector < sector || last_sector > config->sector_count) { + LOG_ERR("Sector %" PRIu32 " is outside the range %zu", + last_sector, config->sector_count); return -EIO; } - memcpy(buff, lba_to_address(sector), count * RAMDISK_SECTOR_SIZE); + memcpy(buff, lba_to_address(dev, sector), count * config->sector_size); return 0; } @@ -55,29 +67,33 @@ static int disk_ram_access_read(struct disk_info *disk, uint8_t *buff, static int disk_ram_access_write(struct disk_info *disk, const uint8_t *buff, uint32_t sector, uint32_t count) { + const struct device *dev = disk->dev; + const struct ram_disk_config *config = dev->config; uint32_t last_sector = sector + count; - if (last_sector < sector || last_sector > RAMDISK_SECTOR_COUNT) { - LOG_ERR("Sector %" PRIu32 " is outside the range %u", - last_sector, RAMDISK_SECTOR_COUNT); + if (last_sector < sector || last_sector > config->sector_count) { + LOG_ERR("Sector %" PRIu32 " is outside the range %zu", + last_sector, config->sector_count); return -EIO; } - memcpy(lba_to_address(sector), buff, count * RAMDISK_SECTOR_SIZE); + memcpy(lba_to_address(dev, sector), buff, count * config->sector_size); return 0; } static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) { + const struct ram_disk_config *config = disk->dev->config; + switch (cmd) { case DISK_IOCTL_CTRL_SYNC: break; case DISK_IOCTL_GET_SECTOR_COUNT: - *(uint32_t *)buff = RAMDISK_SECTOR_COUNT; + *(uint32_t *)buff = config->sector_count; break; case DISK_IOCTL_GET_SECTOR_SIZE: - *(uint32_t *)buff = RAMDISK_SECTOR_SIZE; + *(uint32_t *)buff = config->sector_size; break; case DISK_IOCTL_GET_ERASE_BLOCK_SZ: *(uint32_t *)buff = 1U; @@ -89,6 +105,15 @@ static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff return 0; } +static int disk_ram_init(const struct device *dev) +{ + struct disk_info *info = dev->data; + + info->dev = dev; + + return disk_access_register(info); +} + static const struct disk_operations ram_disk_ops = { .init = disk_ram_access_init, .status = disk_ram_access_status, @@ -97,15 +122,51 @@ static const struct disk_operations ram_disk_ops = { .ioctl = disk_ram_access_ioctl, }; -static struct disk_info ram_disk = { - .name = CONFIG_DISK_RAM_VOLUME_NAME, - .ops = &ram_disk_ops, -}; - -static int disk_ram_init(void) -{ +#define DT_DRV_COMPAT zephyr_ram_disk + +#define RAMDISK_DEVICE_SIZE(n) \ + (DT_INST_PROP(n, sector_size) * DT_INST_PROP(n, sector_count)) + +#define RAMDISK_DEVICE_CONFIG_DEFINE_MEMREG(n) \ + BUILD_ASSERT(RAMDISK_DEVICE_SIZE(n) <= \ + DT_REG_SIZE(DT_INST_PHANDLE(n, ram_region)), \ + "Disk size is smaller than memory region"); \ + \ + static struct ram_disk_config disk_config_##n = { \ + .sector_size = DT_INST_PROP(n, sector_size), \ + .sector_count = DT_INST_PROP(n, sector_count), \ + .size = RAMDISK_DEVICE_SIZE(n), \ + .buf = UINT_TO_POINTER(DT_REG_ADDR(DT_INST_PHANDLE(n, ram_region))), \ + } - return disk_access_register(&ram_disk); -} +#define RAMDISK_DEVICE_CONFIG_DEFINE_LOCAL(n) \ + static uint8_t disk_buf_##n[DT_INST_PROP(n, sector_size) * \ + DT_INST_PROP(n, sector_count)]; \ + \ + static struct ram_disk_config disk_config_##n = { \ + .sector_size = DT_INST_PROP(n, sector_size), \ + .sector_count = DT_INST_PROP(n, sector_count), \ + .size = RAMDISK_DEVICE_SIZE(n), \ + .buf = disk_buf_##n, \ + } -SYS_INIT(disk_ram_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#define RAMDISK_DEVICE_CONFIG_DEFINE(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, ram_region), \ + (RAMDISK_DEVICE_CONFIG_DEFINE_MEMREG(n)), \ + (RAMDISK_DEVICE_CONFIG_DEFINE_LOCAL(n))) + +#define RAMDISK_DEVICE_DEFINE(n) \ + \ + static struct disk_info disk_info_##n = { \ + .name = DT_INST_PROP(n, disk_name), \ + .ops = &ram_disk_ops, \ + }; \ + \ + RAMDISK_DEVICE_CONFIG_DEFINE(n); \ + \ + DEVICE_DT_INST_DEFINE(n, disk_ram_init, NULL, \ + &disk_info_##n, &disk_config_##n, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &ram_disk_ops); + +DT_INST_FOREACH_STATUS_OKAY(RAMDISK_DEVICE_DEFINE) diff --git a/dts/bindings/disk/zephyr,ram-disk.yaml b/dts/bindings/disk/zephyr,ram-disk.yaml new file mode 100644 index 00000000000..68b9709cede --- /dev/null +++ b/dts/bindings/disk/zephyr,ram-disk.yaml @@ -0,0 +1,35 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: RAM disk + +compatible: "zephyr,ram-disk" + +include: ["base.yaml", "memory-region.yaml"] + +properties: + disk-name: + type: string + required: true + description: | + Disk name. + + sector-size: + type: int + required: true + enum: [512, 1024, 2048, 4096, 8192, 16384, 32768, 65536] + description: | + Disk sector size in bytes. + + sector-count: + type: int + required: true + description: | + Number of sectors. + + ram-region: + type: phandle + description: | + Optional phandle to the memory region to be used as a RAM disk, + if not used a local buffer is defined for each disk instance. + Use it with caution as it makes memory contents easily accessible. diff --git a/samples/subsys/fs/format/prj_ram.conf b/samples/subsys/fs/format/prj_ram.conf index 3604ca153db..feecc2eefd4 100644 --- a/samples/subsys/fs/format/prj_ram.conf +++ b/samples/subsys/fs/format/prj_ram.conf @@ -1,7 +1,5 @@ CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVERS=y -CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=64 CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=y diff --git a/samples/subsys/fs/format/ramdisk.overlay b/samples/subsys/fs/format/ramdisk.overlay new file mode 100644 index 00000000000..b76a5ef6161 --- /dev/null +++ b/samples/subsys/fs/format/ramdisk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <128>; + }; +}; diff --git a/samples/subsys/fs/format/sample.yaml b/samples/subsys/fs/format/sample.yaml index 0c41105fc63..ca93e00f075 100644 --- a/samples/subsys/fs/format/sample.yaml +++ b/samples/subsys/fs/format/sample.yaml @@ -12,5 +12,7 @@ tests: - native_posix - mimxrt1064_evk build_only: true - extra_args: CONF_FILE="prj_ram.conf" + extra_args: + - CONF_FILE="prj_ram.conf" + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" tags: filesystem diff --git a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf index a272869511e..6618209fa63 100644 --- a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf +++ b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf @@ -3,6 +3,3 @@ CONFIG_USB_MASS_STORAGE=y CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y - -#RAM DISK -CONFIG_DISK_DRIVER_RAM=y diff --git a/samples/subsys/usb/cdc_acm/ramdisk.overlay b/samples/subsys/usb/cdc_acm/ramdisk.overlay new file mode 100644 index 00000000000..b76a5ef6161 --- /dev/null +++ b/samples/subsys/usb/cdc_acm/ramdisk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <128>; + }; +}; diff --git a/samples/subsys/usb/cdc_acm/sample.yaml b/samples/subsys/usb/cdc_acm/sample.yaml index 60d6ab46fff..19e645174f7 100644 --- a/samples/subsys/usb/cdc_acm/sample.yaml +++ b/samples/subsys/usb/cdc_acm/sample.yaml @@ -27,7 +27,9 @@ tests: depends_on: usb_device tags: usb arch_exclude: posix - extra_args: OVERLAY_CONFIG=overlay-composite-cdc-msc.conf + extra_args: + - OVERLAY_CONFIG=overlay-composite-cdc-msc.conf + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" harness: console harness_config: type: one_line diff --git a/samples/subsys/usb/mass/Kconfig b/samples/subsys/usb/mass/Kconfig index eb47261d1c4..e031a4545db 100644 --- a/samples/subsys/usb/mass/Kconfig +++ b/samples/subsys/usb/mass/Kconfig @@ -14,11 +14,9 @@ choice config APP_MSC_STORAGE_NONE bool "Use RAM disk as block device" - imply DISK_DRIVER_RAM config APP_MSC_STORAGE_RAM bool "Use RAM disk and FAT file system" - imply DISK_DRIVER_RAM imply FILE_SYSTEM imply FAT_FILESYSTEM_ELM @@ -42,9 +40,6 @@ config APP_MSC_STORAGE_SDCARD endchoice -config DISK_RAM_VOLUME_SIZE - default 32 if APP_MSC_STORAGE_NONE - config MASS_STORAGE_DISK_NAME default "NAND" if DISK_DRIVER_FLASH default "RAM" if DISK_DRIVER_RAM diff --git a/samples/subsys/usb/mass/ramdisk.overlay b/samples/subsys/usb/mass/ramdisk.overlay new file mode 100644 index 00000000000..ff09a0f8ca7 --- /dev/null +++ b/samples/subsys/usb/mass/ramdisk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <192>; + }; +}; diff --git a/samples/subsys/usb/mass/sample.yaml b/samples/subsys/usb/mass/sample.yaml index 2e7570a5ae3..9149012a212 100644 --- a/samples/subsys/usb/mass/sample.yaml +++ b/samples/subsys/usb/mass/sample.yaml @@ -2,9 +2,11 @@ sample: name: Mass Storage tests: sample.usb.mass_ram_none: - min_ram: 64 + min_ram: 128 depends_on: usb_device arch_exclude: posix + extra_args: + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" extra_configs: - CONFIG_LOG_DEFAULT_LEVEL=3 tags: @@ -18,12 +20,14 @@ tests: - "No file system selected" - "The device is put in USB mass storage mode." sample.usb_device_next.mass_ram_none: - min_ram: 64 + min_ram: 128 depends_on: usb_device platform_allow: - nrf52840dk_nrf52840 - frdm_k64f - extra_args: CONF_FILE="usbd_next_prj.conf" + extra_args: + - CONF_FILE="usbd_next_prj.conf" + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" extra_configs: - CONFIG_LOG_DEFAULT_LEVEL=3 tags: @@ -40,6 +44,8 @@ tests: min_ram: 128 depends_on: usb_device arch_exclude: posix + extra_args: + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" extra_configs: - CONFIG_LOG_DEFAULT_LEVEL=3 - CONFIG_APP_MSC_STORAGE_RAM=y diff --git a/tests/drivers/disk/disk_access/boards/qemu_x86_64.overlay b/tests/drivers/disk/disk_access/boards/qemu_x86_64.overlay index 1485f30e4d5..65f66de9273 100644 --- a/tests/drivers/disk/disk_access/boards/qemu_x86_64.overlay +++ b/tests/drivers/disk/disk_access/boards/qemu_x86_64.overlay @@ -18,4 +18,11 @@ status = "okay"; }; }; + + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <192>; + }; }; diff --git a/tests/drivers/disk/disk_access/src/main.c b/tests/drivers/disk/disk_access/src/main.c index 3677556ef0c..7dd58359f95 100644 --- a/tests/drivers/disk/disk_access/src/main.c +++ b/tests/drivers/disk/disk_access/src/main.c @@ -19,7 +19,7 @@ #elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME CONFIG_MMC_VOLUME_NAME #elif IS_ENABLED(CONFIG_DISK_DRIVER_RAM) -#define DISK_NAME CONFIG_DISK_RAM_VOLUME_NAME +#define DISK_NAME "RAM" #elif IS_ENABLED(CONFIG_NVME) #define DISK_NAME "nvme0n0" #else diff --git a/tests/drivers/disk/disk_access/testcase.yaml b/tests/drivers/disk/disk_access/testcase.yaml index 2dc6cac00af..86c7a365a5f 100644 --- a/tests/drivers/disk/disk_access/testcase.yaml +++ b/tests/drivers/disk/disk_access/testcase.yaml @@ -14,8 +14,6 @@ tests: - mimxrt1050_evk - mimxrt1064_evk drivers.disk.ram: - extra_configs: - - CONFIG_DISK_DRIVER_RAM=y platform_allow: qemu_x86_64 drivers.disk.nvme: extra_configs: diff --git a/tests/drivers/disk/disk_performance/src/main.c b/tests/drivers/disk/disk_performance/src/main.c index 5def5931319..84402429082 100644 --- a/tests/drivers/disk/disk_performance/src/main.c +++ b/tests/drivers/disk/disk_performance/src/main.c @@ -16,8 +16,6 @@ #define DISK_NAME CONFIG_SDMMC_VOLUME_NAME #elif IS_ENABLED(CONFIG_DISK_DRIVER_MMC) #define DISK_NAME CONFIG_MMC_VOLUME_NAME -#elif IS_ENABLED(CONFIG_DISK_DRIVER_RAM) -#define DISK_NAME CONFIG_DISK_RAM_VOLUME_NAME #elif IS_ENABLED(CONFIG_NVME) #define DISK_NAME "nvme0n0" #else diff --git a/tests/posix/fs/app.overlay b/tests/posix/fs/app.overlay new file mode 100644 index 00000000000..87ae21b1e64 --- /dev/null +++ b/tests/posix/fs/app.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <160>; + }; +}; diff --git a/tests/posix/fs/prj.conf b/tests/posix/fs/prj.conf index 27758bc609e..24b214aa6ce 100644 --- a/tests/posix/fs/prj.conf +++ b/tests/posix/fs/prj.conf @@ -1,8 +1,6 @@ CONFIG_FILE_SYSTEM=y CONFIG_LOG=y CONFIG_FAT_FILESYSTEM_ELM=y -CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=80 CONFIG_POSIX_API=y CONFIG_POSIX_FS=y CONFIG_ZTEST=y diff --git a/tests/subsys/fs/ext2/prj.conf b/tests/subsys/fs/ext2/prj.conf index 8661fc9969e..86f11ba1086 100644 --- a/tests/subsys/fs/ext2/prj.conf +++ b/tests/subsys/fs/ext2/prj.conf @@ -4,7 +4,6 @@ CONFIG_FILE_SYSTEM_MKFS=y CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=200 CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/subsys/fs/ext2/prj_big.conf b/tests/subsys/fs/ext2/prj_big.conf index 1a108557b47..4590cd4cd57 100644 --- a/tests/subsys/fs/ext2/prj_big.conf +++ b/tests/subsys/fs/ext2/prj_big.conf @@ -4,7 +4,6 @@ CONFIG_FILE_SYSTEM_MKFS=y CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=9000 CONFIG_EXT2_MAX_BLOCK_COUNT=20 diff --git a/tests/subsys/fs/ext2/ramdisk_big.overlay b/tests/subsys/fs/ext2/ramdisk_big.overlay new file mode 100644 index 00000000000..0f0422c8fa4 --- /dev/null +++ b/tests/subsys/fs/ext2/ramdisk_big.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <18000>; + }; +}; diff --git a/tests/subsys/fs/ext2/ramdisk_small.overlay b/tests/subsys/fs/ext2/ramdisk_small.overlay new file mode 100644 index 00000000000..8a4d7708a80 --- /dev/null +++ b/tests/subsys/fs/ext2/ramdisk_small.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <400>; + }; +}; diff --git a/tests/subsys/fs/ext2/testcase.yaml b/tests/subsys/fs/ext2/testcase.yaml index 14654c83d0a..21615994ba6 100644 --- a/tests/subsys/fs/ext2/testcase.yaml +++ b/tests/subsys/fs/ext2/testcase.yaml @@ -3,10 +3,14 @@ common: tests: filesystem.ext2.default: platform_allow: native_posix native_posix_64 hifive_unmatched bl5340_dvk_cpuapp + extra_args: + - EXTRA_DTC_OVERLAY_FILE="ramdisk_small.overlay" filesystem.ext2.big: platform_allow: native_posix native_posix_64 - extra_args: CONF_FILE=prj_big.conf + extra_args: + - CONF_FILE=prj_big.conf + - EXTRA_DTC_OVERLAY_FILE="ramdisk_big.overlay" filesystem.ext2.sdcard: platform_allow: hifive_unmatched bl5340_dvk_cpuapp diff --git a/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf b/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf index 231fb7cf364..bff7a3e070d 100644 --- a/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf +++ b/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf @@ -2,7 +2,6 @@ CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_MKFS=y CONFIG_LOG=y CONFIG_FAT_FILESYSTEM_ELM=y -CONFIG_DISK_DRIVER_RAM=y CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y diff --git a/tests/subsys/fs/fat_fs_api/ramdisk.overlay b/tests/subsys/fs/fat_fs_api/ramdisk.overlay new file mode 100644 index 00000000000..b76a5ef6161 --- /dev/null +++ b/tests/subsys/fs/fat_fs_api/ramdisk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <128>; + }; +}; diff --git a/tests/subsys/fs/fat_fs_api/src/test_fat.h b/tests/subsys/fs/fat_fs_api/src/test_fat.h index 9c168b4bccf..8048ef084cf 100644 --- a/tests/subsys/fs/fat_fs_api/src/test_fat.h +++ b/tests/subsys/fs/fat_fs_api/src/test_fat.h @@ -12,7 +12,7 @@ #include #ifdef CONFIG_DISK_DRIVER_RAM -#define DISK_NAME CONFIG_DISK_RAM_VOLUME_NAME +#define DISK_NAME "RAM" #elif defined(CONFIG_DISK_DRIVER_FLASH) #define DISK_NAME DT_PROP(DT_NODELABEL(test_disk), disk_name) #elif defined(CONFIG_DISK_DRIVER_SDMMC) diff --git a/tests/subsys/fs/fat_fs_api/testcase.yaml b/tests/subsys/fs/fat_fs_api/testcase.yaml index c6557e6f230..bc3927def92 100644 --- a/tests/subsys/fs/fat_fs_api/testcase.yaml +++ b/tests/subsys/fs/fat_fs_api/testcase.yaml @@ -15,7 +15,9 @@ tests: filter: dt_compat_enabled("zephyr,mmc-disk") filesystem.fat.ram.api: platform_allow: native_posix - extra_args: CONF_FILE="prj_native_posix_ram.conf" + extra_args: + - CONF_FILE="prj_native_posix_ram.conf" + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" filesystem.fat.api.reentrant: platform_allow: native_posix extra_configs: diff --git a/tests/subsys/fs/fat_fs_dual_drive/app.overlay b/tests/subsys/fs/fat_fs_dual_drive/app.overlay new file mode 100644 index 00000000000..59e564f8829 --- /dev/null +++ b/tests/subsys/fs/fat_fs_dual_drive/app.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <160>; + }; + + ramdisk1 { + compatible = "zephyr,ram-disk"; + disk-name = "CF"; + sector-size = <512>; + sector-count = <160>; + }; +}; diff --git a/tests/subsys/fs/fat_fs_dual_drive/prj.conf b/tests/subsys/fs/fat_fs_dual_drive/prj.conf index 7ac2ebe96cc..bfdefcdfdc4 100644 --- a/tests/subsys/fs/fat_fs_dual_drive/prj.conf +++ b/tests/subsys/fs/fat_fs_dual_drive/prj.conf @@ -3,7 +3,6 @@ CONFIG_LOG=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_FS_FATFS_NUM_FILES=8 CONFIG_FS_FATFS_NUM_DIRS=8 -CONFIG_DISK_DRIVER_RAM=y CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/subsys/fs/fat_fs_dual_drive/src/disk_access_test_drv.c b/tests/subsys/fs/fat_fs_dual_drive/src/disk_access_test_drv.c deleted file mode 100644 index 8af0f07a3ed..00000000000 --- a/tests/subsys/fs/fat_fs_dual_drive/src/disk_access_test_drv.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -#define RAMDISK_SECTOR_SIZE 512 - -/* A 96KB RAM Disk, which meets ELM FAT fs's minimum block requirement. Fit for - * qemu testing (as it may exceed target's RAM limits). - */ -#define RAMDISK_VOLUME_SIZE (192 * RAMDISK_SECTOR_SIZE) -static uint8_t ramdisk_buf[RAMDISK_VOLUME_SIZE]; - -static void *lba_to_address(uint32_t lba) -{ - __ASSERT(((lba * RAMDISK_SECTOR_SIZE) < RAMDISK_VOLUME_SIZE), - "FS bound error"); - - return &ramdisk_buf[(lba * RAMDISK_SECTOR_SIZE)]; -} - -static int disk_ram_access_status(struct disk_info *disk) -{ - return DISK_STATUS_OK; -} - -static int disk_ram_access_init(struct disk_info *disk) -{ - return 0; -} - -static int disk_ram_access_read(struct disk_info *disk, uint8_t *buff, - uint32_t sector, uint32_t count) -{ - memcpy(buff, lba_to_address(sector), count * RAMDISK_SECTOR_SIZE); - - return 0; -} - -static int disk_ram_access_write(struct disk_info *disk, const uint8_t *buff, - uint32_t sector, uint32_t count) -{ - memcpy(lba_to_address(sector), buff, count * RAMDISK_SECTOR_SIZE); - - return 0; -} - -static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) -{ - switch (cmd) { - case DISK_IOCTL_CTRL_SYNC: - break; - case DISK_IOCTL_GET_SECTOR_COUNT: - *(uint32_t *)buff = RAMDISK_VOLUME_SIZE / RAMDISK_SECTOR_SIZE; - break; - case DISK_IOCTL_GET_SECTOR_SIZE: - *(uint32_t *)buff = RAMDISK_SECTOR_SIZE; - break; - case DISK_IOCTL_GET_ERASE_BLOCK_SZ: - *(uint32_t *)buff = 1U; - break; - default: - return -EINVAL; - } - - return 0; -} - -static struct disk_operations ram_disk_ops = { - .init = disk_ram_access_init, - .status = disk_ram_access_status, - .read = disk_ram_access_read, - .write = disk_ram_access_write, - .ioctl = disk_ram_access_ioctl, -}; - -static struct disk_info ram_disk = { - .name = "CF", - .ops = &ram_disk_ops, -}; - -static int disk_ram_test_init(void) -{ - - return disk_access_register(&ram_disk); -} - -SYS_INIT(disk_ram_test_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/tests/subsys/fs/multi-fs/prj.conf b/tests/subsys/fs/multi-fs/prj.conf index 179e66c9378..7a2b28cffed 100644 --- a/tests/subsys/fs/multi-fs/prj.conf +++ b/tests/subsys/fs/multi-fs/prj.conf @@ -6,8 +6,6 @@ CONFIG_FILE_SYSTEM_LITTLEFS=y CONFIG_LOG=y CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=16384 CONFIG_FAT_FILESYSTEM_ELM=y -CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=80 CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/fs/multi-fs/prj_fs_shell.conf b/tests/subsys/fs/multi-fs/prj_fs_shell.conf index 8a0e59b1ffc..aa2c4cfd79c 100644 --- a/tests/subsys/fs/multi-fs/prj_fs_shell.conf +++ b/tests/subsys/fs/multi-fs/prj_fs_shell.conf @@ -10,8 +10,6 @@ CONFIG_SHELL_BACKEND_DUMMY=y CONFIG_SHELL_CMD_BUFF_SIZE=90 CONFIG_FILE_SYSTEM_SHELL=y CONFIG_FAT_FILESYSTEM_ELM=y -CONFIG_DISK_DRIVER_RAM=y -CONFIG_DISK_RAM_VOLUME_SIZE=80 CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_MAIN_STACK_SIZE=1024 CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/fs/multi-fs/ramdisk.overlay b/tests/subsys/fs/multi-fs/ramdisk.overlay new file mode 100644 index 00000000000..87ae21b1e64 --- /dev/null +++ b/tests/subsys/fs/multi-fs/ramdisk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <160>; + }; +}; diff --git a/tests/subsys/fs/multi-fs/testcase.yaml b/tests/subsys/fs/multi-fs/testcase.yaml index 07f543d64a4..b4c1e49d195 100644 --- a/tests/subsys/fs/multi-fs/testcase.yaml +++ b/tests/subsys/fs/multi-fs/testcase.yaml @@ -8,13 +8,17 @@ common: - littlefs tests: filesystem.multifs: + extra_args: + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" platform_allow: - native_posix - qemu_x86 integration_platforms: - native_posix filesystem.fs_shell: - extra_args: CONF_FILE="prj_fs_shell.conf" + extra_args: + - CONF_FILE="prj_fs_shell.conf" + - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" platform_allow: - native_posix - qemu_x86 From 9fe56ed709dfd166616b81e7fda41d81d343d980 Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Fri, 18 Aug 2023 18:55:03 +0200 Subject: [PATCH 0621/4498] dts: bindings: adiltc2990: add dts bindings for analog devices ltc2990 This commit adds adi,adltc2990.yaml to dts/bindings/sensor. Signed-off-by: Jilay Pandya --- dts/bindings/sensor/adi,adltc2990.yaml | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 dts/bindings/sensor/adi,adltc2990.yaml diff --git a/dts/bindings/sensor/adi,adltc2990.yaml b/dts/bindings/sensor/adi,adltc2990.yaml new file mode 100644 index 00000000000..443221aa66d --- /dev/null +++ b/dts/bindings/sensor/adi,adltc2990.yaml @@ -0,0 +1,86 @@ +# Copyright (c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + + +description: ADLTC2990 Quad I2C Voltage, Current and Temperature Monitor + +compatible: "adi,adltc2990" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + temperature-format: + type: int + description: | + Define the temperature format. As per the datasheet, + b7 Temperature Format Temperature Reported In; Celsius = 0 (Default), Kelvin = 1 + default: 0 + enum: + - 0 + - 1 + + acquistion-format: + type: int + description: | + Define the acquisition format. As per the datasheet, + b6 Repeat/Single Repeated Acquisition = 0 (Default), Single Acquisition = 1 + default: 0 + enum: + - 0 + - 1 + + measurement-mode: + type: array + description: | + An array of two integers for configuring the chip measurement mode. + + The first integer defines the bits 2..0 in the control register. In all + cases the internal temperature and supply voltage are measured. In + addition the following input measurements are enabled per mode: + As per the datasheet, + ------------------------------------------- + b[2:0] | Mode [2:0] | Mode Description + 0 | 0 0 0 | V1, V2, TR2 (Default) + 1 | 0 0 1 | V1 – V2, TR2 + 2 | 0 1 0 | V1 – V2, V3, V4 + 3 | 0 1 1 | TR1, V3, V4 + 4 | 1 0 0 | TR1, V3 – V4 + 5 | 1 0 1 | TR1, TR2 + 6 | 1 1 0 | V1 – V2, V3 – V4 + 7 | 1 1 1 | V1, V2, V3, V4 + ------------------------------------------- + The second integer defines the bits 4..3 in the control register. This + allows a subset of the measurements to be enabled: + As Per the Datasheet, + ------------------------------------------------------------ + b[4:3] | Mode [4:3] | Mode Description + 0 | 0 0 | Internal Temperature Only (Default) + 1 | 0 1 | TR1, V1 or V1 – V2 Only per Mode [2:0] + 2 | 1 0 | TR2, V3 or V3 – V4 Only per Mode [2:0] + 3 | 1 1 | All Measurements per Mode [2:0] + ------------------------------------------------------------ + default: [0, 0] + + pins-v1-v2-current-resistor: + type: int + description: Define the resistor to be used for measuring current in microohms + + pin-v1-voltage-divider-resistors: + type: array + description: Define the resistor to be used for measuring Vout in milliohms + + pin-v2-voltage-divider-resistors: + type: array + description: Define the resistor to be used for measuring Vout in milliohms + + pins-v3-v4-current-resistor: + type: int + description: Define the resistor to be used for measuring current in microohms + + pin-v3-voltage-divider-resistors: + type: array + description: Define the resistor to be used for measuring Vout in milliohms + + pin-v4-voltage-divider-resistors: + type: array + description: Define the resistor to be used for measuring Vout in milliohms From 3384ebb00feb0de26b1f843eab01908a69db6332 Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Fri, 18 Aug 2023 18:56:46 +0200 Subject: [PATCH 0622/4498] driver: sensor: adds basic support for analog devices ltc2990 This commit adds Kconfig variables to configure ADLTC2990. This commit adds basic driver code for analog devices ltc2990 sensor. Signed-off-by: Jilay Pandya --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/adltc2990/CMakeLists.txt | 6 + drivers/sensor/adltc2990/Kconfig | 13 + drivers/sensor/adltc2990/adltc2990.c | 470 +++++++++++++++++++++++ drivers/sensor/adltc2990/adltc2990.h | 63 +++ drivers/sensor/adltc2990/adltc2990_reg.h | 54 +++ tests/drivers/build_all/sensor/i2c.dtsi | 12 + 8 files changed, 620 insertions(+) create mode 100644 drivers/sensor/adltc2990/CMakeLists.txt create mode 100644 drivers/sensor/adltc2990/Kconfig create mode 100644 drivers/sensor/adltc2990/adltc2990.c create mode 100644 drivers/sensor/adltc2990/adltc2990.h create mode 100644 drivers/sensor/adltc2990/adltc2990_reg.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index e905bb3ef7f..e2d46e88fd6 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory_ifdef(CONFIG_A01NYUB a01nyub) add_subdirectory_ifdef(CONFIG_ADC_CMP_NPCX nuvoton_adc_cmp_npcx) +add_subdirectory_ifdef(CONFIG_ADLTC2990 adltc2990) add_subdirectory_ifdef(CONFIG_ADT7310 adt7310) add_subdirectory_ifdef(CONFIG_ADT7420 adt7420) add_subdirectory_ifdef(CONFIG_ADXL345 adxl345) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index fb4080c7823..cd4faef46e4 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -58,6 +58,7 @@ config SENSOR_INFO comment "Device Drivers" source "drivers/sensor/a01nyub/Kconfig" +source "drivers/sensor/adltc2990/Kconfig" source "drivers/sensor/adt7310/Kconfig" source "drivers/sensor/adt7420/Kconfig" source "drivers/sensor/adxl345/Kconfig" diff --git a/drivers/sensor/adltc2990/CMakeLists.txt b/drivers/sensor/adltc2990/CMakeLists.txt new file mode 100644 index 00000000000..45ca5eb803b --- /dev/null +++ b/drivers/sensor/adltc2990/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright(c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(adltc2990.c) diff --git a/drivers/sensor/adltc2990/Kconfig b/drivers/sensor/adltc2990/Kconfig new file mode 100644 index 00000000000..260ae6af66b --- /dev/null +++ b/drivers/sensor/adltc2990/Kconfig @@ -0,0 +1,13 @@ +# ADLTC2990 Quad I2C Voltage, Current and Temperature sensor configuration options + +# Copyright(c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +config ADLTC2990 + bool "ADLTC2990 Quad I2C Voltage, Current and Temperature Monitor" + default y + depends on DT_HAS_ADI_ADLTC2990_ENABLED + select I2C + help + Enable the driver for Analog Devices LTC2990 + Quad I2C Voltage, Current and Temperature Monitor. diff --git a/drivers/sensor/adltc2990/adltc2990.c b/drivers/sensor/adltc2990/adltc2990.c new file mode 100644 index 00000000000..2e410505136 --- /dev/null +++ b/drivers/sensor/adltc2990/adltc2990.c @@ -0,0 +1,470 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adltc2990 + +#include +#include + +#include "adltc2990_reg.h" +#include "adltc2990.h" + +#include +LOG_MODULE_REGISTER(adltc2990, CONFIG_SENSOR_LOG_LEVEL); + +static enum adltc2990_monitoring_type adltc2990_get_v1_v2_measurement_modes(uint8_t mode_4_3, + uint8_t mode_2_0) +{ + if (mode_2_0 > ADLTC2990_MODE_2_0_MAX_VALUE || mode_4_3 > ADLTC2990_MODE_4_3_MAX_VALUE) { + LOG_ERR("Invalid Measurement Mode"); + return -EINVAL; + } + if (mode_4_3 == ADLTC2990_MEASURE_INTERNAL_TEMPERATURE_ONLY || + mode_4_3 == ADLTC2990_MEASURE_PINS_V3_V4_ONLY) { + return NOTHING; + } + + enum adltc2990_monitoring_type type = NOTHING; + + switch (mode_2_0) { + case ADLTC2990_MODE_V1_V2_TR2: + case ADLTC2990_MODE_V1_V2_V3_V4: { + type = VOLTAGE_SINGLEENDED; + break; + } + case ADLTC2990_MODE_V1_MINUS_V2_TR2: + case ADLTC2990_MODE_V1_MINUS_V2_V3_V4: + case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: { + type = VOLTAGE_DIFFERENTIAL; + break; + } + case ADLTC2990_MODE_TR1_V3_V4: + case ADLTC2990_MODE_TR1_V3_MINUS_V4: { + case ADLTC2990_MODE_TR1_TR2: + type = TEMPERATURE; + break; + } + default: { + break; + } + } + return type; +} + +static enum adltc2990_monitoring_type adltc2990_get_v3_v4_measurement_modes(uint8_t mode_4_3, + uint8_t mode_2_0) +{ + if (mode_2_0 > ADLTC2990_MODE_2_0_MAX_VALUE || mode_4_3 > ADLTC2990_MODE_4_3_MAX_VALUE) { + LOG_ERR("Invalid Measurement Mode"); + return -EINVAL; + } + if (mode_4_3 == ADLTC2990_MEASURE_INTERNAL_TEMPERATURE_ONLY || + mode_4_3 == ADLTC2990_MEASURE_PINS_V1_V2_ONLY) { + return NOTHING; + } + + enum adltc2990_monitoring_type type = NOTHING; + + switch (mode_2_0) { + case ADLTC2990_MODE_V1_V2_TR2: + case ADLTC2990_MODE_V1_MINUS_V2_TR2: + case ADLTC2990_MODE_TR1_TR2: { + type = TEMPERATURE; + break; + } + + case ADLTC2990_MODE_V1_MINUS_V2_V3_V4: + case ADLTC2990_MODE_TR1_V3_V4: + case ADLTC2990_MODE_V1_V2_V3_V4: { + type = VOLTAGE_SINGLEENDED; + break; + } + case ADLTC2990_MODE_TR1_V3_MINUS_V4: + case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: { + type = VOLTAGE_DIFFERENTIAL; + break; + } + default: { + break; + } + } + return type; +} + +static bool adltc2990_is_busy(const struct device *dev) +{ + const struct adltc2990_config *cfg = dev->config; + uint8_t status_reg = 0; + + i2c_reg_read_byte_dt(&cfg->bus, ADLTC2990_REG_STATUS, &status_reg); + return status_reg & BIT(0); +} + +static void adltc2990_get_v1_v2_val(const struct device *dev, struct sensor_value *val, + uint8_t num_values, uint8_t *const offset_index) +{ + struct adltc2990_data *data = dev->data; + + for (uint8_t index = 0; index < num_values; index++) { + val[index].val1 = data->pins_v1_v2_values[index] / 1000000; + val[index].val2 = data->pins_v1_v2_values[index] % 1000000; + *offset_index = index + 1; + } +} + +static void adltc2990_get_v3_v4_val(const struct device *dev, struct sensor_value *val, + uint8_t num_values, uint8_t const *const offset) +{ + struct adltc2990_data *data = dev->data; + + uint8_t offset_index = *offset; + + for (uint8_t index = 0; index < num_values; index++) { + val[index + offset_index].val1 = data->pins_v3_v4_values[index] / 1000000; + val[index + offset_index].val2 = data->pins_v3_v4_values[index] % 1000000; + } +} + +static int adltc2990_trigger_measurement(const struct device *dev) +{ + const struct adltc2990_config *cfg = dev->config; + + return i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_TRIGGER, 0x1); +} + +static int32_t adltc2990_get_property_value(const struct device *dev, + enum adltc2990_monitoring_type type, + enum adltc2990_monitor_pins pin) +{ + const struct adltc2990_config *cfg = dev->config; + + uint8_t msb_value = 0, lsb_value = 0; + uint8_t msb_address, lsb_address; + + switch (pin) { + case V1: { + msb_address = ADLTC2990_REG_V1_MSB; + lsb_address = ADLTC2990_REG_V1_LSB; + break; + } + case V2: { + msb_address = ADLTC2990_REG_V2_MSB; + lsb_address = ADLTC2990_REG_V2_LSB; + break; + } + case V3: { + msb_address = ADLTC2990_REG_V3_MSB; + lsb_address = ADLTC2990_REG_V3_LSB; + break; + } + case V4: { + msb_address = ADLTC2990_REG_V4_MSB; + lsb_address = ADLTC2990_REG_V4_LSB; + break; + } + case INTERNAL_TEMPERATURE: { + msb_address = ADLTC2990_REG_INTERNAL_TEMP_MSB; + lsb_address = ADLTC2990_REG_INTERNAL_TEMP_LSB; + break; + } + case SUPPLY_VOLTAGE: { + msb_address = ADLTC2990_REG_VCC_MSB; + lsb_address = ADLTC2990_REG_VCC_LSB; + break; + } + default: { + LOG_ERR("Trying to access illegal register"); + return -EINVAL; + } + } + + i2c_reg_read_byte_dt(&cfg->bus, msb_address, &msb_value); + i2c_reg_read_byte_dt(&cfg->bus, lsb_address, &lsb_value); + uint16_t conversion_factor; + uint8_t negative_bit_index; + + if (type == VOLTAGE_SINGLEENDED) { + conversion_factor = ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR; + negative_bit_index = 14; + } else if (type == VOLTAGE_DIFFERENTIAL) { + conversion_factor = ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR; + negative_bit_index = 14; + } else if (type == TEMPERATURE) { + conversion_factor = ADLTC2990_TEMPERATURE_CONVERSION_FACTOR; + negative_bit_index = 12; + } else { + LOG_ERR("unknown type"); + return -EINVAL; + } + + int16_t value = (msb_value<<8)+lsb_value; + + int32_t voltage_value = (value << (31-negative_bit_index))>>(31-negative_bit_index); + + return (voltage_value * conversion_factor) / 100; +} + +static int adltc2990_init(const struct device *dev) +{ + const struct adltc2990_config *cfg = dev->config; + + if (!i2c_is_ready_dt(&cfg->bus)) { + LOG_ERR("I2C bus %s not ready", cfg->bus.bus->name); + return -ENODEV; + } + + const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | cfg->acq_format << 6 | 0 << 5 | + cfg->measurement_mode[1] << 3 | cfg->measurement_mode[0]; + + LOG_DBG("Setting Control Register to: 0x%x", ctrl_reg_setting); + int err = i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting); + + if (err < 0) { + LOG_ERR("configuring for single bus failed: %d", err); + return err; + } + LOG_INF("Initializing ADLTC2990 with name %s", dev->name); + return 0; +} + +static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct adltc2990_data *data = dev->data; + const struct adltc2990_config *cfg = dev->config; + enum adltc2990_monitoring_type mode_v1_v2 = adltc2990_get_v1_v2_measurement_modes( + cfg->measurement_mode[1], cfg->measurement_mode[0]); + enum adltc2990_monitoring_type mode_v3_v4 = adltc2990_get_v3_v4_measurement_modes( + cfg->measurement_mode[1], cfg->measurement_mode[0]); + + float voltage_divider_ratio; + + switch (chan) { + case SENSOR_CHAN_DIE_TEMP: { + data->internal_temperature = + adltc2990_get_property_value(dev, TEMPERATURE, INTERNAL_TEMPERATURE); + break; + } + case SENSOR_CHAN_CURRENT: { + if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) { + LOG_ERR("Sensor is not configured to measure Current"); + return -EINVAL; + } + if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { + data->pins_v1_v2_values[0] = + (adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V1) * + ADLTC2990_MICROOHM_CONVERSION_FACTOR) / + cfg->pins_v1_v2.pins_current_resistor; + } + if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { + data->pins_v3_v4_values[0] = + (adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V3) * + ADLTC2990_MICROOHM_CONVERSION_FACTOR) / + cfg->pins_v3_v4.pins_current_resistor; + } + break; + } + case SENSOR_CHAN_VOLTAGE: { + data->supply_voltage = + adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, SUPPLY_VOLTAGE) + + 2500000; + + if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { + data->pins_v1_v2_values[0] = + adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V1); + } else if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { + uint32_t v1_r1 = + cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; + uint32_t v1_r2 = + cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; + voltage_divider_ratio = DIV_ROUND_CLOSEST(v1_r1 + v1_r2, v1_r2); + data->pins_v1_v2_values[0] = + adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V1) * + voltage_divider_ratio; + + uint32_t v2_r1 = + cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; + uint32_t v2_r2 = + cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; + voltage_divider_ratio = DIV_ROUND_CLOSEST(v2_r1 + v2_r2, v2_r2); + data->pins_v1_v2_values[1] = + adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V2) * + voltage_divider_ratio; + } + + if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { + data->pins_v3_v4_values[0] = + adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V3); + } else if (mode_v3_v4 == VOLTAGE_SINGLEENDED) { + uint32_t v3_r1 = + cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; + uint32_t v3_r2 = + cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; + voltage_divider_ratio = DIV_ROUND_CLOSEST(v3_r1 + v3_r2, v3_r2); + data->pins_v3_v4_values[0] = + adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V3) * + voltage_divider_ratio; + + uint32_t v4_r1 = + cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; + uint32_t v4_r2 = + cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; + voltage_divider_ratio = DIV_ROUND_CLOSEST((v4_r1 + v4_r2), v4_r2); + data->pins_v3_v4_values[1] = + adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V4) * + voltage_divider_ratio; + } + break; + } + case SENSOR_CHAN_AMBIENT_TEMP: { + if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) { + LOG_ERR("Sensor is not configured to measure Ambient Temperature"); + return -EINVAL; + } + if (mode_v1_v2 == TEMPERATURE) { + data->pins_v1_v2_values[0] = + adltc2990_get_property_value(dev, TEMPERATURE, V1); + } + if (mode_v3_v4 == TEMPERATURE) { + data->pins_v3_v4_values[1] = + adltc2990_get_property_value(dev, TEMPERATURE, V3); + } + break; + } + case SENSOR_CHAN_ALL: { + if (adltc2990_is_busy(dev)) { + LOG_INF("ADLTC2990 conversion ongoing"); + return -EBUSY; + } + adltc2990_trigger_measurement(dev); + break; + } + default: { + LOG_ERR("does not measure channel: %d", chan); + return -ENOTSUP; + } + } + + return 0; +} + +static int adltc2990_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + if (val == NULL) { + LOG_ERR("Argument of type sensor_value* cannot be null "); + return -EINVAL; + } + struct adltc2990_data *data = dev->data; + const struct adltc2990_config *cfg = dev->config; + enum adltc2990_monitoring_type mode_v1_v2 = adltc2990_get_v1_v2_measurement_modes( + cfg->measurement_mode[1], cfg->measurement_mode[0]); + enum adltc2990_monitoring_type mode_v3_v4 = adltc2990_get_v3_v4_measurement_modes( + cfg->measurement_mode[1], cfg->measurement_mode[0]); + + uint8_t offset_index = 0, num_values_v1_v2 = 0, num_values_v3_v4 = 0; + + switch (chan) { + case SENSOR_CHAN_DIE_TEMP: { + val->val1 = data->internal_temperature / 10000; + val->val2 = data->internal_temperature % 10000; + LOG_DBG("Internal Temperature Value is:%d.%d", val->val1, val->val2); + break; + } + case SENSOR_CHAN_VOLTAGE: { + if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { + LOG_DBG("Getting V1,V2"); + num_values_v1_v2 = ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES; + } else if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Getting V3-V4"); + num_values_v1_v2 = ADLTC2990_VOLTAGE_DIFF_VALUES; + } + if (mode_v3_v4 == VOLTAGE_SINGLEENDED) { + LOG_DBG("Getting V3,V4"); + num_values_v3_v4 = ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES; + } else if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Getting V3-V4"); + num_values_v3_v4 = ADLTC2990_VOLTAGE_DIFF_VALUES; + } + val[num_values_v1_v2 + num_values_v3_v4].val1 = data->supply_voltage / 1000000; + val[num_values_v1_v2 + num_values_v3_v4].val2 = data->supply_voltage % 1000000; + break; + } + case SENSOR_CHAN_CURRENT: { + if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) { + LOG_ERR("Sensor is not configured to measure Current"); + return -EINVAL; + } + if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL && mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Getting I12 and I34"); + num_values_v1_v2 = ADLTC2990_CURRENT_VALUES; + num_values_v3_v4 = ADLTC2990_CURRENT_VALUES; + } else if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Getting I12"); + num_values_v1_v2 = ADLTC2990_CURRENT_VALUES; + } else if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Getting I34"); + num_values_v3_v4 = ADLTC2990_CURRENT_VALUES; + } + break; + } + case SENSOR_CHAN_AMBIENT_TEMP: { + if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) { + LOG_ERR("Sensor is not configured to measure Ambient Temperature"); + return -EINVAL; + } + if (mode_v1_v2 == TEMPERATURE && mode_v3_v4 == TEMPERATURE) { + LOG_DBG("Getting T12 and T34"); + num_values_v1_v2 = ADLTC2990_TEMP_VALUES; + num_values_v3_v4 = ADLTC2990_TEMP_VALUES; + } else if (mode_v1_v2 == TEMPERATURE) { + LOG_DBG("Getting T12"); + num_values_v1_v2 = ADLTC2990_TEMP_VALUES; + } else if (mode_v3_v4 == TEMPERATURE) { + LOG_DBG("Getting T34"); + num_values_v3_v4 = ADLTC2990_TEMP_VALUES; + } + break; + } + default: { + return -ENOTSUP; + } + } + + adltc2990_get_v1_v2_val(dev, val, num_values_v1_v2, &offset_index); + adltc2990_get_v3_v4_val(dev, val, num_values_v3_v4, &offset_index); + return 0; +} + +static const struct sensor_driver_api adltc2990_driver_api = { + .sample_fetch = adltc2990_sample_fetch, + .channel_get = adltc2990_channel_get, +}; + +#define ADLTC2990_DEFINE(inst) \ + static struct adltc2990_data adltc2990_data_##inst; \ + static const struct adltc2990_config adltc2990_config_##inst = { \ + .bus = I2C_DT_SPEC_INST_GET(inst), \ + .temp_format = DT_INST_PROP(inst, temperature_format), \ + .acq_format = DT_INST_PROP(inst, acquistion_format), \ + .measurement_mode = DT_INST_PROP(inst, measurement_mode), \ + .pins_v1_v2.pins_current_resistor = \ + DT_INST_PROP_OR(inst, pins_v1_v2_current_resistor, 1), \ + .pins_v1_v2.voltage_divider_resistors.v1_r1_r2 = \ + DT_INST_PROP_OR(inst, pin_v1_voltage_divider_resistors, NULL), \ + .pins_v1_v2.voltage_divider_resistors.v2_r1_r2 = \ + DT_INST_PROP_OR(inst, pin_v2_voltage_divider_resistors, NULL), \ + .pins_v3_v4.pins_current_resistor = \ + DT_INST_PROP_OR(inst, pins_v3_v4_current_resistor, 1), \ + .pins_v3_v4.voltage_divider_resistors.v3_r1_r2 = \ + DT_INST_PROP_OR(inst, pin_v3_voltage_divider_resistors, NULL), \ + .pins_v3_v4.voltage_divider_resistors.v4_r1_r2 = \ + DT_INST_PROP_OR(inst, pin_v4_voltage_divider_resistors, NULL)}; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, adltc2990_init, NULL, &adltc2990_data_##inst, \ + &adltc2990_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &adltc2990_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(ADLTC2990_DEFINE) diff --git a/drivers/sensor/adltc2990/adltc2990.h b/drivers/sensor/adltc2990/adltc2990.h new file mode 100644 index 00000000000..f1c20d33b23 --- /dev/null +++ b/drivers/sensor/adltc2990/adltc2990.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H +#define ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H + +#include +#include +#include +#include + +enum adltc2990_monitor_pins { + V1, + V2, + V3, + V4, + INTERNAL_TEMPERATURE, + SUPPLY_VOLTAGE +} adltc2990_monitor_pins; + +enum adltc2990_monitoring_type { + NOTHING, + VOLTAGE_DIFFERENTIAL, + VOLTAGE_SINGLEENDED, + TEMPERATURE +} adltc2990_monitoring_type; + +union voltage_divider_resistors { + struct { + uint32_t v1_r1_r2[2]; + uint32_t v2_r1_r2[2]; + }; + struct { + uint32_t v3_r1_r2[2]; + uint32_t v4_r1_r2[2]; + }; +}; + +struct pins_configuration { + uint32_t pins_current_resistor; + union voltage_divider_resistors voltage_divider_resistors; +}; + +struct adltc2990_data { + int32_t internal_temperature; + int32_t supply_voltage; + int32_t pins_v1_v2_values[2]; + int32_t pins_v3_v4_values[2]; +}; + +struct adltc2990_config { + struct i2c_dt_spec bus; + uint8_t temp_format; + uint8_t acq_format; + uint8_t measurement_mode[2]; + struct pins_configuration pins_v1_v2; + struct pins_configuration pins_v3_v4; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H */ diff --git a/drivers/sensor/adltc2990/adltc2990_reg.h b/drivers/sensor/adltc2990/adltc2990_reg.h new file mode 100644 index 00000000000..3b23b8b066f --- /dev/null +++ b/drivers/sensor/adltc2990/adltc2990_reg.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ADLTC2990_REG_H +#define ZEPHYR_DRIVERS_SENSOR_ADLTC2990_REG_H + +#define ADLTC2990_REG_STATUS 0x00U +#define ADLTC2990_REG_CONTROL 0x01U +#define ADLTC2990_REG_TRIGGER 0x02U +#define ADLTC2990_REG_UNUSED 0x03U +#define ADLTC2990_REG_INTERNAL_TEMP_MSB 0x04U +#define ADLTC2990_REG_INTERNAL_TEMP_LSB 0x05U +#define ADLTC2990_REG_V1_MSB 0x06U +#define ADLTC2990_REG_V1_LSB 0x07U +#define ADLTC2990_REG_V2_MSB 0x08U +#define ADLTC2990_REG_V2_LSB 0x09U +#define ADLTC2990_REG_V3_MSB 0x0AU +#define ADLTC2990_REG_V3_LSB 0x0BU +#define ADLTC2990_REG_V4_MSB 0x0CU +#define ADLTC2990_REG_V4_LSB 0x0DU +#define ADLTC2990_REG_VCC_MSB 0x0EU +#define ADLTC2990_REG_VCC_LSB 0x0FU + +#define ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES 2U +#define ADLTC2990_VOLTAGE_DIFF_VALUES 1U +#define ADLTC2990_TEMP_VALUES 1U +#define ADLTC2990_CURRENT_VALUES 1U +#define ADLTC2990_MICROOHM_CONVERSION_FACTOR 1000000U + +#define ADLTC2990_MODE_V1_V2_TR2 0U +#define ADLTC2990_MODE_V1_MINUS_V2_TR2 1U +#define ADLTC2990_MODE_V1_MINUS_V2_V3_V4 2U +#define ADLTC2990_MODE_TR1_V3_V4 3U +#define ADLTC2990_MODE_TR1_V3_MINUS_V4 4U +#define ADLTC2990_MODE_TR1_TR2 5U +#define ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4 6U +#define ADLTC2990_MODE_V1_V2_V3_V4 7U + +#define ADLTC2990_MEASURE_INTERNAL_TEMPERATURE_ONLY 0U +#define ADLTC2990_MEASURE_PINS_V1_V2_ONLY 1U +#define ADLTC2990_MEASURE_PINS_V3_V4_ONLY 2U +#define ADLTC2990_MEASURE_ALL_PINS_PER_MODE_2_0 3U + +#define ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR 30518 +#define ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR 1942 +#define ADLTC2990_TEMPERATURE_CONVERSION_FACTOR 62500 + +#define ADLTC2990_MODE_2_0_MAX_VALUE 7U +#define ADLTC2990_MODE_4_3_MAX_VALUE 3U + +#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_REG_H */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 9b04fc5226f..1409b74ea68 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -753,3 +753,15 @@ test_i2c_tsl2540: tsl2540@71 { reg = <0x71>; int-gpios = <&test_gpio 0 0>; }; + +test_i2c_adltc2990@72 { + compatible = "adi,adltc2990"; + reg = <0x72>; + status = "okay"; + measurement-mode = <7 3>; + pins-v1-v2-current-resistor = <1>; + pin-v1-voltage-divider-resistors = <100 10>; + pin-v2-voltage-divider-resistors = <100 10>; + pin-v3-voltage-divider-resistors = <100 100>; + pin-v4-voltage-divider-resistors = <0 1>; +}; From 7c870e149c9937fa791be8698aa71dc349cbc11c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 18 Sep 2023 15:29:18 +0000 Subject: [PATCH 0623/4498] dts: efm32gg12b: add pin-controller binding The gecko UART driver needs pinctrl support for SOC_GECKO_SERIES1 devices, this has been added to jg and pg 12b series in 40fa96506b but is missing in others, causing some build failurse. Add the device nodes for the gg11b and gg12b files since they contain gecko-uart references and seems to be under the SERIES1 define. Signed-off-by: Fabio Baltieri --- dts/arm/silabs/efm32gg11b.dtsi | 8 ++++++++ dts/arm/silabs/efm32gg12b.dtsi | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/dts/arm/silabs/efm32gg11b.dtsi b/dts/arm/silabs/efm32gg11b.dtsi index 732490ffd9a..a8435797a80 100644 --- a/dts/arm/silabs/efm32gg11b.dtsi +++ b/dts/arm/silabs/efm32gg11b.dtsi @@ -287,6 +287,14 @@ interrupts = <64 0>; status = "disabled"; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; diff --git a/dts/arm/silabs/efm32gg12b.dtsi b/dts/arm/silabs/efm32gg12b.dtsi index 3e7d105e6b3..d1c3e5aa70d 100644 --- a/dts/arm/silabs/efm32gg12b.dtsi +++ b/dts/arm/silabs/efm32gg12b.dtsi @@ -240,6 +240,14 @@ interrupts = <55 0>; status = "disabled"; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; From 5b9f82668b4680072a94ede9d3aa632d89615086 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 12 Sep 2023 16:33:05 +0800 Subject: [PATCH 0624/4498] riscv: telink_b91: fix compilation Fix compilation failure due to multilevel interrupt. Signed-off-by: Yong Cong Sin --- drivers/gpio/gpio_b91.c | 2 +- dts/riscv/telink/telink_b91.dtsi | 8 ++++++++ .../riscv-privileged/telink_b91/Kconfig.defconfig.series | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_b91.c b/drivers/gpio/gpio_b91.c index 45a82f71620..bc73f9db9f5 100644 --- a/drivers/gpio/gpio_b91.c +++ b/drivers/gpio/gpio_b91.c @@ -78,7 +78,7 @@ struct gpio_b91_t { struct gpio_b91_config { struct gpio_driver_config common; uint32_t gpio_base; - uint8_t irq_num; + uint32_t irq_num; uint8_t irq_priority; void (*pirq_connect)(void); }; diff --git a/dts/riscv/telink/telink_b91.dtsi b/dts/riscv/telink/telink_b91.dtsi index 85ffbf6f57f..2a6acfd5fd2 100644 --- a/dts/riscv/telink/telink_b91.dtsi +++ b/dts/riscv/telink/telink_b91.dtsi @@ -24,6 +24,12 @@ clock-frequency = <24000000>; compatible ="telink,b91", "riscv"; riscv,isa = "rv32imac_zicsr_zifencei"; + hlic: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; }; }; @@ -124,6 +130,8 @@ #address-cells = <0>; #interrupt-cells = <2>; interrupt-controller; + interrupts-extended = <&hlic 11>; + interrupt-parent = <&cpu0>; reg = < 0xe4000000 0x00001000 0xe4002000 0x00000800 0xe4200000 0x00010000 >; diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series b/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series index 43eb3a03927..986b6240750 100644 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series +++ b/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series @@ -50,6 +50,9 @@ config TEST_EXTRA_STACK_SIZE int default 1024 +config 2ND_LVL_INTR_00_OFFSET + default 11 + config HAS_FLASH_LOAD_OFFSET default y if BOOTLOADER_MCUBOOT From 40ee8791f21e47cadf2552386b9f16b18f3fb060 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 14 Sep 2023 23:34:45 +0530 Subject: [PATCH 0625/4498] net: socketpair: Fix use after free In low memory conditions, its possible for socketpair memory allocation to fail and then the socketpair is freed but after that the remote semaphore is released causing a crash. Fix this by freeing the socketpair after releasing the semaphore. Add a test case to induce low memory conditions (low HEAP and high socketpair buffer size), with the fix issue is not seen. Signed-off-by: Chaitanya Tata --- subsys/net/lib/sockets/socketpair.c | 8 ++++---- tests/net/socket/socketpair/testcase.yaml | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index f3bbb46f6c8..9207f4b659e 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -191,6 +191,10 @@ static void spair_delete(struct spair *spair) res = k_poll_signal_raise(&spair->writeable, SPAIR_SIG_CANCEL); __ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res); + if (remote != NULL && have_remote_sem) { + k_sem_give(&remote->sem); + } + /* ensure no private information is released to the memory pool */ memset(spair, 0, sizeof(*spair)); #ifdef CONFIG_NET_SOCKETPAIR_STATIC @@ -200,10 +204,6 @@ static void spair_delete(struct spair *spair) #else k_free(spair); #endif - - if (remote != NULL && have_remote_sem) { - k_sem_give(&remote->sem); - } } /** diff --git a/tests/net/socket/socketpair/testcase.yaml b/tests/net/socket/socketpair/testcase.yaml index e771e7c61d4..d2b4462ce2d 100644 --- a/tests/net/socket/socketpair/testcase.yaml +++ b/tests/net/socket/socketpair/testcase.yaml @@ -18,3 +18,11 @@ tests: extra_configs: - CONFIG_PICOLIBC=y platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 + net.socket.socketpair.high_mem: + min_ram: 64 + extra_configs: + # Low buffer sizes (e.g., 8192) will verify the crash fix, but tests will still + # fail due to insufficient memory. So, use high buffer sizes. + - CONFIG_NET_SOCKETPAIR_BUFFER_SIZE=4096 + - CONFIG_HEAP_MEM_POOL_SIZE=32768 + platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 From 47396e18e12ae859b9858cb439e531a5611255b8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 13 Sep 2023 15:13:48 +0000 Subject: [PATCH 0626/4498] net: Fix usage of strncpy in net_if_get_name and net_if_set_name Replaced with memcpy. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_if.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index e6e3512e4b2..828e48ecf78 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4747,7 +4747,8 @@ int net_if_get_name(struct net_if *iface, char *buf, int len) return -ERANGE; } - strncpy(buf, net_if_get_config(iface)->name, name_len); + /* Copy string and null terminator */ + memcpy(buf, net_if_get_config(iface)->name, name_len + 1); return name_len; #else @@ -4769,7 +4770,8 @@ int net_if_set_name(struct net_if *iface, const char *buf) return -ENAMETOOLONG; } - strncpy(net_if_get_config(iface)->name, buf, name_len); + /* Copy string and null terminator */ + memcpy(net_if_get_config(iface)->name, buf, name_len + 1); return 0; #else From fa0bbaf66cd66843f60a4ea9205e14fc17a6ea78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85lg=C3=A5rd?= Date: Mon, 18 Sep 2023 10:07:12 +0200 Subject: [PATCH 0627/4498] net: promiscuous: Fix crash in promiscuous mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a packet can't be cloned we crash as we try to initialize the cursor on a nullptr. We should check if we have a valid pointer, and if we don't we drop the packet along with a warning. Signed-off-by: Andreas Ålgård --- subsys/net/ip/net_if.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 828e48ecf78..d431cbf1334 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4145,12 +4145,15 @@ enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt) /* L2 has modified the buffer starting point, it is easier * to re-initialize the cursor rather than updating it. */ - net_pkt_cursor_init(new_pkt); + if (new_pkt) { + net_pkt_cursor_init(new_pkt); - if (net_promisc_mode_input(new_pkt) == NET_DROP) { - net_pkt_unref(new_pkt); + if (net_promisc_mode_input(new_pkt) == NET_DROP) { + net_pkt_unref(new_pkt); + } + } else { + NET_WARN("promiscuous packet dropped, unable to clone packet"); } - net_pkt_unref(pkt); return verdict; From 7afbcdc619965a4687ee3243ecc5e349cba75756 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 12 Sep 2023 21:24:41 +0800 Subject: [PATCH 0628/4498] drivers: intc: plic: fix the calculation of trig register trig register should be independent of the `riscv,max-priority` property. Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/intc_plic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 67a5313287c..fe061b89b0a 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -29,7 +29,7 @@ #define PLIC_IRQS (CONFIG_NUM_IRQS - CONFIG_2ND_LVL_ISR_TBL_OFFSET) #define PLIC_EN_SIZE ((PLIC_IRQS >> 5) + 1) -#define PLIC_EDGE_TRIG_TYPE (PLIC_MAX_PRIO + DT_INST_PROP(0, riscv_trigger_reg_offset)) +#define PLIC_EDGE_TRIG_TYPE (DT_INST_REG_ADDR(0) + DT_INST_PROP(0, riscv_trigger_reg_offset)) #define PLIC_EDGE_TRIG_SHIFT 5 struct plic_regs_t { From 9b7c2cba3a6d3b03a520e48dd2c62561eb7de7a1 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 13 Sep 2023 11:21:41 +0800 Subject: [PATCH 0629/4498] tests: add intc_plic build_all test Add an interrupt_controller build_all test for intc_plic. Signed-off-by: Yong Cong Sin --- .../interrupt_controller/CMakeLists.txt | 8 ++++++++ .../boards/qemu_riscv32_trig.overlay | 9 +++++++++ .../boards/qemu_riscv64_trig.overlay | 3 +++ .../build_all/interrupt_controller/prj.conf | 3 +++ .../build_all/interrupt_controller/src/main.c | 20 +++++++++++++++++++ .../interrupt_controller/testcase.yaml | 20 +++++++++++++++++++ 6 files changed, 63 insertions(+) create mode 100644 tests/drivers/build_all/interrupt_controller/CMakeLists.txt create mode 100644 tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay create mode 100644 tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay create mode 100644 tests/drivers/build_all/interrupt_controller/prj.conf create mode 100644 tests/drivers/build_all/interrupt_controller/src/main.c create mode 100644 tests/drivers/build_all/interrupt_controller/testcase.yaml diff --git a/tests/drivers/build_all/interrupt_controller/CMakeLists.txt b/tests/drivers/build_all/interrupt_controller/CMakeLists.txt new file mode 100644 index 00000000000..518596a02f7 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(build_all) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay b/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay new file mode 100644 index 00000000000..72b36e70091 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 + + /{ + soc { + plic: interrupt-controller@c000000 { + riscv,trigger-reg-offset = < 0x00001080 >; + }; + }; +}; diff --git a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay b/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay new file mode 100644 index 00000000000..5fe1ca0cf60 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include "qemu_riscv32_trig.overlay" diff --git a/tests/drivers/build_all/interrupt_controller/prj.conf b/tests/drivers/build_all/interrupt_controller/prj.conf new file mode 100644 index 00000000000..4fac64b8a33 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/prj.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_TEST=y diff --git a/tests/drivers/build_all/interrupt_controller/src/main.c b/tests/drivers/build_all/interrupt_controller/src/main.c new file mode 100644 index 00000000000..82860397c3f --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/src/main.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifdef CONFIG_PLIC_SUPPORTS_EDGE_IRQ +BUILD_ASSERT(DT_PROP(DT_NODELABEL(plic), riscv_trigger_reg_offset) == 0x00001080, + "the offset should be the value defined in the board dt overlay"); +#else +BUILD_ASSERT(DT_PROP(DT_NODELABEL(plic), riscv_trigger_reg_offset) == 4224, + "the offset should be the binding default value"); +#endif /* CONFIG_PLIC_SUPPORTS_EDGE_IRQ */ + +int main(void) +{ + return 0; +} diff --git a/tests/drivers/build_all/interrupt_controller/testcase.yaml b/tests/drivers/build_all/interrupt_controller/testcase.yaml new file mode 100644 index 00000000000..1ce419177c2 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/testcase.yaml @@ -0,0 +1,20 @@ +common: + build_only: true + tags: + - drivers + - interrupt +tests: + drivers.interrupt_controller.intc_plic.build: + platform_allow: + - qemu_riscv32 + - qemu_riscv64 + tags: plic + drivers.interrupt_controller.intc_plic.edge.build: + platform_allow: + - qemu_riscv32 + - qemu_riscv64 + extra_args: + DTC_OVERLAY_FILE="./boards/qemu_riscv32_trig.overlay;./boards/qemu_riscv64_trig.overlay" + extra_configs: + - CONFIG_PLIC_SUPPORTS_EDGE_IRQ=y + tags: plic From 1896130bd8d806c3ffdbb1a64f5151595f9e1a84 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Mon, 18 Sep 2023 07:05:22 +0200 Subject: [PATCH 0630/4498] modules: lvgl: fix initialization order depedencies Removes the pseudo device prerequisite that the LVGL setup routine has been executed before initialization. The pseudo devices are now registered at the end of the LVGL setup routine, the driver is not concerned with configuring the devices anymore. This also removes the need for enforcing certain priorities within the same init level. This resolves issue #62753. Signed-off-by: Fabian Blatz --- modules/lvgl/Kconfig.input | 4 --- modules/lvgl/include/lvgl_button_input.h | 22 ++++++++++++++ .../{input => include}/lvgl_common_input.h | 1 + modules/lvgl/include/lvgl_encoder_input.h | 22 ++++++++++++++ modules/lvgl/include/lvgl_pointer_input.h | 22 ++++++++++++++ modules/lvgl/input/lvgl_button_input.c | 7 +++-- modules/lvgl/input/lvgl_common_input.c | 30 +++++++++++++++++++ modules/lvgl/input/lvgl_encoder_input.c | 7 +++-- modules/lvgl/input/lvgl_pointer_input.c | 7 +++-- modules/lvgl/input/lvgl_pointer_kscan.c | 2 +- modules/lvgl/lvgl.c | 12 ++++---- 11 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 modules/lvgl/include/lvgl_button_input.h rename modules/lvgl/{input => include}/lvgl_common_input.h (97%) create mode 100644 modules/lvgl/include/lvgl_encoder_input.h create mode 100644 modules/lvgl/include/lvgl_pointer_input.h diff --git a/modules/lvgl/Kconfig.input b/modules/lvgl/Kconfig.input index dc1a747fb0d..b6cbdad0c28 100644 --- a/modules/lvgl/Kconfig.input +++ b/modules/lvgl/Kconfig.input @@ -4,10 +4,6 @@ menu "Input device settings" -config LV_Z_INPUT_INIT_PRIORITY - int - default 91 - config LV_Z_POINTER_KSCAN bool "Keyboard scan pointer input" depends on KSCAN diff --git a/modules/lvgl/include/lvgl_button_input.h b/modules/lvgl/include/lvgl_button_input.h new file mode 100644 index 00000000000..dd97b5e7c7f --- /dev/null +++ b/modules/lvgl/include/lvgl_button_input.h @@ -0,0 +1,22 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_LVGL_BUTTON_INPUT_H_ +#define ZEPHYR_MODULES_LVGL_LVGL_BUTTON_INPUT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int lvgl_button_input_init(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_LVGL_BUTTON_INPUT_H_ */ diff --git a/modules/lvgl/input/lvgl_common_input.h b/modules/lvgl/include/lvgl_common_input.h similarity index 97% rename from modules/lvgl/input/lvgl_common_input.h rename to modules/lvgl/include/lvgl_common_input.h index e9d0ef34f84..a218ed29647 100644 --- a/modules/lvgl/input/lvgl_common_input.h +++ b/modules/lvgl/include/lvgl_common_input.h @@ -26,6 +26,7 @@ struct lvgl_common_input_data { }; int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device *dev); +int lvgl_init_input_devices(void); #define LVGL_INPUT_EVENT_MSGQ(inst, type) lvgl_input_msgq_##type##_##inst #define LVGL_INPUT_DEVICE(inst) DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, input)) diff --git a/modules/lvgl/include/lvgl_encoder_input.h b/modules/lvgl/include/lvgl_encoder_input.h new file mode 100644 index 00000000000..1fe9a23c2c4 --- /dev/null +++ b/modules/lvgl/include/lvgl_encoder_input.h @@ -0,0 +1,22 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_LVGL_ENCODER_INPUT_H_ +#define ZEPHYR_MODULES_LVGL_LVGL_ENCODER_INPUT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int lvgl_encoder_input_init(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_LVGL_ENCODER_INPUT_H_ */ diff --git a/modules/lvgl/include/lvgl_pointer_input.h b/modules/lvgl/include/lvgl_pointer_input.h new file mode 100644 index 00000000000..f168477b982 --- /dev/null +++ b/modules/lvgl/include/lvgl_pointer_input.h @@ -0,0 +1,22 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_LVGL_POINTER_INPUT_H_ +#define ZEPHYR_MODULES_LVGL_LVGL_POINTER_INPUT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int lvgl_pointer_input_init(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_LVGL_POINTER_INPUT_H_ */ diff --git a/modules/lvgl/input/lvgl_button_input.c b/modules/lvgl/input/lvgl_button_input.c index 5d6f64c82b6..f9c9d59f4d5 100644 --- a/modules/lvgl/input/lvgl_button_input.c +++ b/modules/lvgl/input/lvgl_button_input.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT zephyr_lvgl_button_input #include "lvgl_common_input.h" +#include "lvgl_button_input.h" #include @@ -44,7 +45,7 @@ static void lvgl_button_process_event(const struct device *dev, struct input_eve } } -static int lvgl_button_input_init(const struct device *dev) +int lvgl_button_input_init(const struct device *dev) { struct lvgl_common_input_data *data = dev->data; const struct lvgl_button_input_config *cfg = dev->config; @@ -79,8 +80,8 @@ static int lvgl_button_input_init(const struct device *dev) .coordinates = lvgl_button_coordinates_##inst, \ }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ - DEVICE_DT_INST_DEFINE(inst, lvgl_button_input_init, NULL, &lvgl_common_input_data_##inst, \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_common_input_data_##inst, \ &lvgl_button_input_config_##inst, POST_KERNEL, \ - CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); + CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_BUTTON_INPUT_DEFINE) diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c index 82814f53fae..5e7e1474368 100644 --- a/modules/lvgl/input/lvgl_common_input.c +++ b/modules/lvgl/input/lvgl_common_input.c @@ -9,6 +9,9 @@ #include #include #include +#include "lvgl_pointer_input.h" +#include "lvgl_button_input.h" +#include "lvgl_encoder_input.h" LOG_MODULE_DECLARE(lvgl); @@ -52,3 +55,30 @@ int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device * return 0; } + +#define LV_DEV_INIT(node_id, init_fn) \ + do { \ + int ret = init_fn(DEVICE_DT_GET(node_id)); \ + if (ret) { \ + return ret; \ + } \ + } while (0) + +int lvgl_init_input_devices(void) +{ +#ifdef CONFIG_LV_Z_POINTER_INPUT + DT_FOREACH_STATUS_OKAY_VARGS(zephyr_lvgl_pointer_input, LV_DEV_INIT, + lvgl_pointer_input_init); +#endif /* CONFIG_LV_Z_POINTER_INPUT */ + +#ifdef CONFIG_LV_Z_BUTTON_INPUT + DT_FOREACH_STATUS_OKAY_VARGS(zephyr_lvgl_button_input, LV_DEV_INIT, lvgl_button_input_init); +#endif /* CONFIG_LV_Z_BUTTON_INPUT */ + +#ifdef CONFIG_LV_Z_ENCODER_INPUT + DT_FOREACH_STATUS_OKAY_VARGS(zephyr_lvgl_encoder_input, LV_DEV_INIT, + lvgl_encoder_input_init); +#endif /* CONFIG_LV_Z_ENCODER_INPUT */ + + return 0; +} diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c index 655275c7264..a49f1eeca29 100644 --- a/modules/lvgl/input/lvgl_encoder_input.c +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT zephyr_lvgl_encoder_input #include "lvgl_common_input.h" +#include "lvgl_encoder_input.h" #include @@ -37,7 +38,7 @@ static void lvgl_encoder_process_event(const struct device *dev, struct input_ev } } -static int lvgl_encoder_input_init(const struct device *dev) +int lvgl_encoder_input_init(const struct device *dev) { return lvgl_input_register_driver(LV_INDEV_TYPE_ENCODER, dev); } @@ -64,8 +65,8 @@ static int lvgl_encoder_input_init(const struct device *dev) .button_input_code = BUTTON_CODE(inst), \ }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ - DEVICE_DT_INST_DEFINE(inst, lvgl_encoder_input_init, NULL, &lvgl_common_input_data_##inst, \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_common_input_data_##inst, \ &lvgl_encoder_input_config_##inst, POST_KERNEL, \ - CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); + CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_ENCODER_INPUT_DEFINE) diff --git a/modules/lvgl/input/lvgl_pointer_input.c b/modules/lvgl/input/lvgl_pointer_input.c index ed01a1d1515..19c71eb1972 100644 --- a/modules/lvgl/input/lvgl_pointer_input.c +++ b/modules/lvgl/input/lvgl_pointer_input.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT zephyr_lvgl_pointer_input #include "lvgl_common_input.h" +#include "lvgl_pointer_input.h" #include #include @@ -108,7 +109,7 @@ static void lvgl_pointer_process_event(const struct device *dev, struct input_ev } } -static int lvgl_pointer_input_init(const struct device *dev) +int lvgl_pointer_input_init(const struct device *dev) { return lvgl_input_register_driver(LV_INDEV_TYPE_POINTER, dev); } @@ -123,8 +124,8 @@ static int lvgl_pointer_input_init(const struct device *dev) .invert_y = DT_INST_PROP(inst, invert_y), \ }; \ static struct lvgl_common_input_data lvgl_common_input_data_##inst; \ - DEVICE_DT_INST_DEFINE(inst, lvgl_pointer_input_init, NULL, &lvgl_common_input_data_##inst, \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_common_input_data_##inst, \ &lvgl_pointer_input_config_##inst, POST_KERNEL, \ - CONFIG_LV_Z_INPUT_INIT_PRIORITY, NULL); + CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(LVGL_POINTER_INPUT_DEFINE) diff --git a/modules/lvgl/input/lvgl_pointer_kscan.c b/modules/lvgl/input/lvgl_pointer_kscan.c index f3115ffa029..197106e4f2c 100644 --- a/modules/lvgl/input/lvgl_pointer_kscan.c +++ b/modules/lvgl/input/lvgl_pointer_kscan.c @@ -146,4 +146,4 @@ static int lvgl_kscan_pointer_init(void) return 0; } -SYS_INIT(lvgl_kscan_pointer_init, APPLICATION, CONFIG_LV_Z_INPUT_INIT_PRIORITY); +SYS_INIT(lvgl_kscan_pointer_init, APPLICATION, CONFIG_INPUT_INIT_PRIORITY); diff --git a/modules/lvgl/lvgl.c b/modules/lvgl/lvgl.c index ec242924e0a..0f4c24e9a34 100644 --- a/modules/lvgl/lvgl.c +++ b/modules/lvgl/lvgl.c @@ -8,6 +8,7 @@ #include #include #include "lvgl_display.h" +#include "lvgl_common_input.h" #ifdef CONFIG_LV_Z_USE_FILESYSTEM #include "lvgl_fs.h" #endif @@ -241,12 +242,13 @@ static int lvgl_init(void) return -EPERM; } + err = lvgl_init_input_devices(); + if (err < 0) { + LOG_ERR("Failed to initialize input devices."); + return err; + } + return 0; } -BUILD_ASSERT(CONFIG_APPLICATION_INIT_PRIORITY < CONFIG_LV_Z_INPUT_INIT_PRIORITY); -#ifdef CONFIG_INPUT -BUILD_ASSERT(CONFIG_INPUT_INIT_PRIORITY < CONFIG_LV_Z_INPUT_INIT_PRIORITY); -#endif /* CONFIG_INPUT */ - SYS_INIT(lvgl_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); From 995eeda266fe450a93ef876c9a135450caadf890 Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Mon, 11 Sep 2023 15:54:51 +0100 Subject: [PATCH 0631/4498] kernel: poll: Lock all calls to signal_poll_event The signal_poll_event function was previously called without the poll lock held. This created a race condition between a thread calling k_poll to wait for an event and another thread signalling for this same event. This resulted in the waiting thread to stay pending and the handle to it getting removed from the notifyq, meaning it couldn't get woken up again. Signed-off-by: Ambroise Vincent --- kernel/poll.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/poll.c b/kernel/poll.c index 9903c9c1fab..67e1e7f76a2 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Wind River Systems, Inc. + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -466,11 +467,14 @@ static int signal_poll_event(struct k_poll_event *event, uint32_t state) void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state) { struct k_poll_event *poll_event; + k_spinlock_key_t key = k_spin_lock(&lock); poll_event = (struct k_poll_event *)sys_dlist_get(events); if (poll_event != NULL) { (void) signal_poll_event(poll_event, state); } + + k_spin_unlock(&lock, key); } void z_impl_k_poll_signal_init(struct k_poll_signal *sig) From bb450eb26ff87aa366f213f13d40ad92e9b1c7b0 Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Tue, 12 Sep 2023 16:43:28 +0100 Subject: [PATCH 0632/4498] net: sockets: Keep lock when notifying condvar Releasing the lock before notifying condvar led to a race condition between a thread calling k_condvar_wait to wait for a condition variable and another thread signalling for this same condition variable. This resulted in the waiting thread to stay pending and the handle to it getting removed from the notifyq, meaning it couldn't get woken up again. Signed-off-by: Ambroise Vincent --- subsys/net/lib/sockets/sockets.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 801ed99fe60..facc509acaf 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017 Linaro Limited * Copyright (c) 2021 Nordic Semiconductor + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -423,12 +424,12 @@ static void zsock_received_cb(struct net_context *ctx, k_fifo_put(&ctx->recv_q, pkt); unlock: + /* Wake reader if it was sleeping */ + (void)k_condvar_signal(&ctx->cond.recv); + if (ctx->cond.lock) { (void)k_mutex_unlock(ctx->cond.lock); } - - /* Wake reader if it was sleeping */ - (void)k_condvar_signal(&ctx->cond.recv); } int zsock_shutdown_ctx(struct net_context *ctx, int how) From 4ba97c22555ed088d770eaf5ca212573de80f5d9 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 18 Sep 2023 15:45:44 +0200 Subject: [PATCH 0633/4498] maintainers: remove gmarull as a PM subsystem collaborator I disagree on the way the subsystem is maintained. For more context refer to https://github.com/zephyrproject-rtos/zephyr/pull/61726 or https://discord.com/channels/720317445772017664/997527108844798012/ 1153288380231208960 Signed-off-by: Gerard Marull-Paretas --- MAINTAINERS.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 3ed671854b2..ac8b22c424b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2085,7 +2085,6 @@ Power management: - ceolin collaborators: - nashif - - gmarull - teburd - tmleman - JordanYates From a04a1d8991e312ece8530f0ab35b444010113fb9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 09:00:51 -0400 Subject: [PATCH 0634/4498] tracing: remove references to deprecated k_pipe_block_put k_pipe_block_put was deprecated some time ago. Signed-off-by: Anas Nashif --- include/zephyr/tracing/tracing.h | 14 -------------- subsys/tracing/ctf/tracing_ctf.h | 2 -- subsys/tracing/sysview/SYSVIEW_Zephyr.txt | 1 - subsys/tracing/sysview/tracing_sysview.h | 2 -- subsys/tracing/test/tracing_test.h | 8 -------- subsys/tracing/user/tracing_user.h | 2 -- .../kernel/pipe/pipe_api/src/test_pipe_contexts.c | 1 - 7 files changed, 30 deletions(-) diff --git a/include/zephyr/tracing/tracing.h b/include/zephyr/tracing/tracing.h index a8500e6eda9..baf9632a30d 100644 --- a/include/zephyr/tracing/tracing.h +++ b/include/zephyr/tracing/tracing.h @@ -1633,20 +1633,6 @@ */ #define sys_port_trace_k_pipe_get_exit(pipe, timeout, ret) -/** - * @brief Trace Pipe block put enter - * @param pipe Pipe object - * @param sem Semaphore object - */ -#define sys_port_trace_k_pipe_block_put_enter(pipe, sem) - -/** - * @brief Trace Pipe block put exit - * @param pipe Pipe object - * @param sem Semaphore object - */ -#define sys_port_trace_k_pipe_block_put_exit(pipe, sem) - /** @} */ /* end of subsys_tracing_apis_pipe */ /** diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index b278c9dc050..6b1b03e97d0 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -295,8 +295,6 @@ extern "C" { #define sys_port_trace_k_pipe_get_enter(pipe, timeout) #define sys_port_trace_k_pipe_get_blocking(pipe, timeout) #define sys_port_trace_k_pipe_get_exit(pipe, timeout, ret) -#define sys_port_trace_k_pipe_block_put_enter(pipe, sem) -#define sys_port_trace_k_pipe_block_put_exit(pipe, sem) #define sys_port_trace_k_heap_init(heap) #define sys_port_trace_k_heap_aligned_alloc_enter(heap, timeout) diff --git a/subsys/tracing/sysview/SYSVIEW_Zephyr.txt b/subsys/tracing/sysview/SYSVIEW_Zephyr.txt index b6dcd8073a2..dfad10e404a 100644 --- a/subsys/tracing/sysview/SYSVIEW_Zephyr.txt +++ b/subsys/tracing/sysview/SYSVIEW_Zephyr.txt @@ -79,7 +79,6 @@ TaskState 0xBF 1=dummy, 2=Waiting, 4=New, 8=Terminated, 16=Suspended, 32=Termina 72 k_pipe_cleanup pipe=%I | Returns %ErrCodePosix 73 k_pipe_put pipe=%I, data=%p, bytes_to_write=%u, bytes_written=%u, min_xfer=%u, Timeout=%TimeOut | Returns %ErrCodePosix 74 k_pipe_get pipe=%I, data=%p, bytes_to_read=%u, bytes_read=%u, min_xfer=%u, Timeout=%TimeOut | Returns %ErrCodePosix -75 k_pipe_block_put pipe=%I, block=%p, bytes_to_write=%u, sem=%I | Returns (void)(%ErrCodePosix) 76 k_heap_init heap=%I, mem=%p, bytes=%u 77 k_heap_alloc heap=%I, bytes=%u, Timeout=%TimeOut | Returns %p diff --git a/subsys/tracing/sysview/tracing_sysview.h b/subsys/tracing/sysview/tracing_sysview.h index 7578d6a750c..105cfb1a3ee 100644 --- a/subsys/tracing/sysview/tracing_sysview.h +++ b/subsys/tracing/sysview/tracing_sysview.h @@ -530,8 +530,6 @@ void sys_trace_thread_info(struct k_thread *thread); #define sys_port_trace_k_pipe_get_enter(pipe, timeout) #define sys_port_trace_k_pipe_get_blocking(pipe, timeout) #define sys_port_trace_k_pipe_get_exit(pipe, timeout, ret) -#define sys_port_trace_k_pipe_block_put_enter(pipe, sem) -#define sys_port_trace_k_pipe_block_put_exit(pipe, sem) #define sys_port_trace_k_event_init(event) #define sys_port_trace_k_event_post_enter(event, events, events_mask) diff --git a/subsys/tracing/test/tracing_test.h b/subsys/tracing/test/tracing_test.h index 06ca3e56cd5..6cf3ee6e583 100644 --- a/subsys/tracing/test/tracing_test.h +++ b/subsys/tracing/test/tracing_test.h @@ -366,10 +366,6 @@ sys_trace_k_pipe_get_blocking(pipe, data, bytes_to_read, bytes_read, min_xfer, timeout) #define sys_port_trace_k_pipe_get_exit(pipe, timeout, ret) \ sys_trace_k_pipe_get_exit(pipe, data, bytes_to_read, bytes_read, min_xfer, timeout, ret) -#define sys_port_trace_k_pipe_block_put_enter(pipe, sem) \ - sys_trace_k_pipe_block_put_enter(pipe, block, bytes_to_write, sem) -#define sys_port_trace_k_pipe_block_put_exit(pipe, sem) \ - sys_trace_k_pipe_block_put_exit(pipe, block, bytes_to_write, sem) #define sys_port_trace_k_heap_init(h) sys_trace_k_heap_init(h, mem, bytes) #define sys_port_trace_k_heap_aligned_alloc_enter(h, timeout) \ @@ -634,10 +630,6 @@ void sys_trace_k_pipe_get_blocking(struct k_pipe *pipe, void *data, size_t bytes size_t *bytes_read, size_t min_xfer, k_timeout_t timeout); void sys_trace_k_pipe_get_exit(struct k_pipe *pipe, void *data, size_t bytes_to_read, size_t *bytes_read, size_t min_xfer, k_timeout_t timeout, int ret); -void sys_trace_k_pipe_block_put_enter(struct k_pipe *pipe, struct k_mem_block *block, size_t size, - struct k_sem *sem); -void sys_trace_k_pipe_block_put_exit(struct k_pipe *pipe, struct k_mem_block *block, size_t size, - struct k_sem *sem); void sys_trace_k_msgq_init(struct k_msgq *msgq); void sys_trace_k_msgq_alloc_init_enter(struct k_msgq *msgq, size_t msg_size, uint32_t max_msgs); diff --git a/subsys/tracing/user/tracing_user.h b/subsys/tracing/user/tracing_user.h index 747fe875f2b..ddc6668d68a 100644 --- a/subsys/tracing/user/tracing_user.h +++ b/subsys/tracing/user/tracing_user.h @@ -280,8 +280,6 @@ void sys_trace_idle(void); #define sys_port_trace_k_pipe_get_enter(pipe, timeout) #define sys_port_trace_k_pipe_get_blocking(pipe, timeout) #define sys_port_trace_k_pipe_get_exit(pipe, timeout, ret) -#define sys_port_trace_k_pipe_block_put_enter(pipe, sem) -#define sys_port_trace_k_pipe_block_put_exit(pipe, sem) #define sys_port_trace_k_heap_init(heap) #define sys_port_trace_k_heap_aligned_alloc_enter(heap, timeout) diff --git a/tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c b/tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c index 2d14dfad1a3..3c7a119bf41 100644 --- a/tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c +++ b/tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c @@ -437,7 +437,6 @@ ZTEST(pipe_api, test_pipe_get_large) */ ZTEST(pipe_api, test_pipe_reader_wait) { - /**TESTPOINT: test k_pipe_block_put with semaphore*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_handler, &kpipe1, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); From 9cff600e25ca78af2d5d732dd5e61bdf9565c82e Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 17 Sep 2023 19:57:46 -0400 Subject: [PATCH 0635/4498] posix: add logging to pooled resource templates Support logging for all POSIX pooled resource types such as pthread_t, pthread_mutex_t, and pthread_cond_t. Signed-off-by: Christopher Friedt --- lib/posix/Kconfig.template.pooled_ipc_type | 1 + lib/posix/Kconfig.template.pooled_type | 1 + lib/posix/Kconfig.template.with_logging | 7 +++++++ 3 files changed, 9 insertions(+) create mode 100644 lib/posix/Kconfig.template.with_logging diff --git a/lib/posix/Kconfig.template.pooled_ipc_type b/lib/posix/Kconfig.template.pooled_ipc_type index ad0bf5bc9b0..557a98f8849 100644 --- a/lib/posix/Kconfig.template.pooled_ipc_type +++ b/lib/posix/Kconfig.template.pooled_ipc_type @@ -3,6 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 source "lib/posix/Kconfig.template.with_url" +source "lib/posix/Kconfig.template.with_logging" # Not user configurable (i.e. private for now) config $(TYPE) diff --git a/lib/posix/Kconfig.template.pooled_type b/lib/posix/Kconfig.template.pooled_type index d2699e2f17c..a30686043a1 100644 --- a/lib/posix/Kconfig.template.pooled_type +++ b/lib/posix/Kconfig.template.pooled_type @@ -3,6 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 source "lib/posix/Kconfig.template.with_url" +source "lib/posix/Kconfig.template.with_logging" # This is mainly for TIMER currently. config $(TYPE) diff --git a/lib/posix/Kconfig.template.with_logging b/lib/posix/Kconfig.template.with_logging new file mode 100644 index 00000000000..f1fc5141e7c --- /dev/null +++ b/lib/posix/Kconfig.template.with_logging @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Meta +# +# SPDX-License-Identifier: Apache-2.0 + +module = $(TYPE) +module-str = $(TYPE) logging +source "subsys/logging/Kconfig.template.log_config" From d2845abcb3abd9b380be374b8fc46aca44bcc378 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 17 Sep 2023 20:00:01 -0400 Subject: [PATCH 0636/4498] posix: pthread: add logging for POSIX threads Add logging to POSIX threads. Signed-off-by: Christopher Friedt --- lib/posix/pthread.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 01734ab615f..761d29cb4dc 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -12,10 +12,13 @@ #include #include +#include #include #include #include +LOG_MODULE_DECLARE(pthread, CONFIG_PTHREAD_LOG_LEVEL); + #ifdef CONFIG_DYNAMIC_THREAD_STACK_SIZE #define DYNAMIC_STACK_SIZE CONFIG_DYNAMIC_THREAD_STACK_SIZE #else @@ -91,10 +94,12 @@ struct posix_thread *to_posix_thread(pthread_t pthread) /* if the provided thread does not claim to be initialized, its invalid */ if (!is_pthread_obj_initialized(pthread)) { + LOG_ERR("pthread is not initialized (%x)", pthread); return NULL; } if (bit >= CONFIG_MAX_PTHREAD_COUNT) { + LOG_ERR("Invalid pthread (%x)", pthread); return NULL; } @@ -112,7 +117,7 @@ struct posix_thread *to_posix_thread(pthread_t pthread) k_spin_unlock(&pthread_pool_lock, key); if (!actually_initialized) { - /* The thread claims to be initialized but is actually not */ + LOG_ERR("Pthread claims to be initialized (%x)", pthread); return NULL; } @@ -137,6 +142,8 @@ static bool is_posix_policy_prio_valid(uint32_t priority, int policy) return true; } + LOG_ERR("Invalid piority %d and / or policy %d", priority, policy); + return false; } @@ -185,6 +192,7 @@ int pthread_attr_setschedparam(pthread_attr_t *_attr, const struct sched_param * if ((attr == NULL) || (attr->initialized == 0U) || (is_posix_policy_prio_valid(priority, attr->schedpolicy) == false)) { + LOG_ERR("Invalid pthread_attr_t or sched_param"); return EINVAL; } @@ -202,6 +210,7 @@ int pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, size_t stacksi struct pthread_attr *attr = (struct pthread_attr *)_attr; if (stackaddr == NULL) { + LOG_ERR("NULL stack address"); return EACCES; } @@ -219,22 +228,26 @@ static bool pthread_attr_is_valid(const struct pthread_attr *attr) /* caller-provided thread stack */ if (attr->initialized == 0U || attr->stack == NULL || attr->stacksize == 0) { + LOG_ERR("pthread_attr_t is not initialized, has a NULL stack, or is of size 0"); return false; } /* require a valid scheduler policy */ if (!valid_posix_policy(attr->schedpolicy)) { + LOG_ERR("Invalid scheduler policy %d", attr->schedpolicy); return false; } /* require a valid detachstate */ if (!(attr->detachstate == PTHREAD_CREATE_JOINABLE || attr->detachstate == PTHREAD_CREATE_DETACHED)) { + LOG_ERR("Invalid detachstate %d", attr->detachstate); return false; } /* we cannot create an essential thread (i.e. one that may not abort) */ if ((attr->flags & K_ESSENTIAL) != 0) { + LOG_ERR("Cannot create an essential thread"); return false; } @@ -323,9 +336,12 @@ static void posix_thread_recycle(void) return; } + LOG_DBG("Recycling %zu threads", sys_dlist_len(&recyclables)); + if (IS_ENABLED(CONFIG_DYNAMIC_THREAD)) { SYS_DLIST_FOR_EACH_CONTAINER(&recyclables, t, q_node) { if (t->dynamic_stack != NULL) { + LOG_DBG("Freeing thread stack %p", t->dynamic_stack); (void)k_thread_stack_free(t->dynamic_stack); t->dynamic_stack = NULL; } @@ -367,8 +383,10 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou attr->stack = k_thread_stack_alloc(attr->stacksize, k_is_user_context() ? K_USER : 0); if (attr->stack == NULL) { + LOG_ERR("Unable to allocate stack of size %u", attr->stacksize); return EAGAIN; } + LOG_DBG("Allocated thread stack %p", attr->stack); } else { __ASSERT_NO_MSG(attr != &attr_storage); } @@ -395,6 +413,7 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou if (t == NULL) { /* no threads are ready */ + LOG_ERR("No threads are ready"); return EAGAIN; } @@ -402,6 +421,7 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou err = pthread_barrier_init(&barrier, NULL, 2); if (err != 0) { if (t->dynamic_stack != NULL) { + LOG_DBG("freeing thread stack at %p", attr->stack); (void)k_thread_stack_free(attr->stack); } @@ -434,6 +454,8 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou /* finally provide the initialized thread to the caller */ *th = mark_pthread_obj_initialized(posix_thread_to_offset(t)); + LOG_DBG("Created pthread %p", &t->thread); + return 0; } @@ -449,6 +471,7 @@ int pthread_setcancelstate(int state, int *oldstate) struct posix_thread *t; if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE) { + LOG_ERR("Invalid pthread state %d", state); return EINVAL; } @@ -513,6 +536,7 @@ int pthread_setschedparam(pthread_t pthread, int policy, const struct sched_para } if (!valid_posix_policy(policy)) { + LOG_ERR("Invalid scheduler policy %d", policy); return EINVAL; } @@ -535,6 +559,7 @@ int pthread_attr_init(pthread_attr_t *attr) { if (attr == NULL) { + LOG_ERR("Invalid attr pointer"); return ENOMEM; } @@ -601,6 +626,7 @@ void pthread_exit(void *retval) self = to_posix_thread(pthread_self()); if (self == NULL) { /* not a valid posix_thread */ + LOG_DBG("Aborting non-pthread %p", k_current_get()); k_thread_abort(k_current_get()); } @@ -625,6 +651,7 @@ int pthread_join(pthread_t pthread, void **status) struct posix_thread *t; if (pthread == pthread_self()) { + LOG_ERR("Pthread attempted to join itself (%x)", pthread); return EDEADLK; } @@ -633,18 +660,22 @@ int pthread_join(pthread_t pthread, void **status) return ESRCH; } + LOG_DBG("Pthread %p joining..", &t->thread); + ret = 0; K_SPINLOCK(&pthread_pool_lock) { if (t->detachstate != PTHREAD_CREATE_JOINABLE) { ret = EINVAL; K_SPINLOCK_BREAK; + LOG_ERR("Pthread %p is not a joinable", &t->thread); } if (t->qid == POSIX_THREAD_READY_Q) { /* in case thread has moved to ready_q between to_posix_thread() and here */ ret = ESRCH; K_SPINLOCK_BREAK; + LOG_ERR("Pthread %p has already been joined", &t->thread); } /* @@ -662,7 +693,10 @@ int pthread_join(pthread_t pthread, void **status) /* other possibilities? */ __ASSERT_NO_MSG(err == 0); + LOG_DBG("Joined pthread %p", &t->thread); + if (status != NULL) { + LOG_DBG("Writing status to %p", status); *status = t->retval; } @@ -691,6 +725,7 @@ int pthread_detach(pthread_t pthread) key = k_spin_lock(&pthread_pool_lock); qid = t->qid; if (qid == POSIX_THREAD_READY_Q || t->detachstate != PTHREAD_CREATE_JOINABLE) { + LOG_ERR("Pthread %p cannot be detached", &t->thread); ret = EINVAL; } else { ret = 0; @@ -698,6 +733,10 @@ int pthread_detach(pthread_t pthread) } k_spin_unlock(&pthread_pool_lock, key); + if (ret == 0) { + LOG_DBG("Pthread %p detached", &t->thread); + } + return ret; } From 0958c46e238421c6ac2fe23c2297dc008df9eeeb Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 17 Sep 2023 20:00:42 -0400 Subject: [PATCH 0637/4498] posix: mutex: add logging for POSIX mutexes Add logging for POSIX mutex operations. Signed-off-by: Christopher Friedt --- lib/posix/mutex.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/posix/mutex.c b/lib/posix/mutex.c index 7d27cdae53c..5ed3fe09249 100644 --- a/lib/posix/mutex.c +++ b/lib/posix/mutex.c @@ -9,9 +9,12 @@ #include #include +#include #include #include +LOG_MODULE_DECLARE(pthread_mutex, CONFIG_PTHREAD_MUTEX_LOG_LEVEL); + static struct k_spinlock pthread_mutex_spinlock; int64_t timespec_to_timeoutms(const struct timespec *abstime); @@ -54,16 +57,19 @@ static struct k_mutex *get_posix_mutex(pthread_mutex_t mu) /* if the provided mutex does not claim to be initialized, its invalid */ if (!is_pthread_obj_initialized(mu)) { + LOG_ERR("Mutex is uninitialized (%x)", mu); return NULL; } /* Mask off the MSB to get the actual bit index */ if (sys_bitarray_test_bit(&posix_mutex_bitarray, bit, &actually_initialized) < 0) { + LOG_ERR("Mutex is invalid (%x)", mu); return NULL; } if (actually_initialized == 0) { /* The mutex claims to be initialized but is actually not */ + LOG_ERR("Mutex claims to be initialized (%x)", mu); return NULL; } @@ -82,7 +88,7 @@ struct k_mutex *to_posix_mutex(pthread_mutex_t *mu) /* Try and automatically associate a posix_mutex */ if (sys_bitarray_alloc(&posix_mutex_bitarray, 1, &bit) < 0) { - /* No mutexes left to allocate */ + LOG_ERR("Unable to allocate pthread_mutex_t"); return NULL; } @@ -111,6 +117,8 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) return EINVAL; } + LOG_DBG("Locking mutex %p with timeout %llx", m, timeout.ticks); + bit = posix_mutex_to_offset(m); type = posix_mutex_type[bit]; @@ -119,11 +127,13 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) switch (type) { case PTHREAD_MUTEX_NORMAL: if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { - ret = EBUSY; - break; + k_spin_unlock(&pthread_mutex_spinlock, key); + LOG_ERR("Timeout locking mutex %p", m); + return EBUSY; } /* On most POSIX systems, this usually results in an infinite loop */ k_spin_unlock(&pthread_mutex_spinlock, key); + LOG_ERR("Attempt to relock non-recursive mutex %p", m); do { (void)k_sleep(K_FOREVER); } while (true); @@ -131,10 +141,12 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) break; case PTHREAD_MUTEX_RECURSIVE: if (m->lock_count >= MUTEX_MAX_REC_LOCK) { + LOG_ERR("Mutex %p locked recursively too many times", m); ret = EAGAIN; } break; case PTHREAD_MUTEX_ERRORCHECK: + LOG_ERR("Attempt to recursively lock non-recursive mutex %p", m); ret = EDEADLK; break; default: @@ -148,18 +160,24 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) if (ret == 0) { ret = k_mutex_lock(m, timeout); if (ret == -EAGAIN) { + LOG_ERR("Timeout locking mutex %p", m); /* * special quirk - k_mutex_lock() returns EAGAIN if a timeout occurs, but * for pthreads, that means something different */ - ret = -ETIMEDOUT; + ret = ETIMEDOUT; } } if (ret < 0) { + LOG_ERR("k_mutex_unlock() failed: %d", ret); ret = -ret; } + if (ret == 0) { + LOG_DBG("Locked mutex %p", m); + } + return ret; } @@ -211,6 +229,8 @@ int pthread_mutex_init(pthread_mutex_t *mu, const pthread_mutexattr_t *_attr) posix_mutex_type[bit] = attr->type; } + LOG_DBG("Initialized mutex %p", m); + return 0; } @@ -242,10 +262,12 @@ int pthread_mutex_unlock(pthread_mutex_t *mu) ret = k_mutex_unlock(m); if (ret < 0) { + LOG_ERR("k_mutex_unlock() failed: %d", ret); return -ret; } __ASSERT_NO_MSG(ret == 0); + LOG_DBG("Unlocked mutex %p", m); return 0; } @@ -270,6 +292,8 @@ int pthread_mutex_destroy(pthread_mutex_t *mu) err = sys_bitarray_free(&posix_mutex_bitarray, 1, bit); __ASSERT_NO_MSG(err == 0); + LOG_DBG("Destroyed mutex %p", m); + return 0; } From d9841ca9fb5412091c8dcd8be5f4a2cb083312f5 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 17 Sep 2023 20:01:20 -0400 Subject: [PATCH 0638/4498] posix: cond: add logging for condition variables Add logging for POSIX condition variable operations. Signed-off-by: Christopher Friedt --- lib/posix/cond.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/posix/cond.c b/lib/posix/cond.c index b40105d1ae7..8e2407f3297 100644 --- a/lib/posix/cond.c +++ b/lib/posix/cond.c @@ -9,9 +9,12 @@ #include #include +#include #include #include +LOG_MODULE_DECLARE(pthread_cond, CONFIG_PTHREAD_COND_LOG_LEVEL); + int64_t timespec_to_timeoutms(const struct timespec *abstime); static struct k_condvar posix_cond_pool[CONFIG_MAX_PTHREAD_COND_COUNT]; @@ -42,16 +45,19 @@ static struct k_condvar *get_posix_cond(pthread_cond_t cond) /* if the provided cond does not claim to be initialized, its invalid */ if (!is_pthread_obj_initialized(cond)) { + LOG_ERR("Cond is uninitialized (%x)", cond); return NULL; } /* Mask off the MSB to get the actual bit index */ if (sys_bitarray_test_bit(&posix_cond_bitarray, bit, &actually_initialized) < 0) { + LOG_ERR("Cond is invalid (%x)", cond); return NULL; } if (actually_initialized == 0) { /* The cond claims to be initialized but is actually not */ + LOG_ERR("Cond claims to be initialized (%x)", cond); return NULL; } @@ -70,6 +76,7 @@ static struct k_condvar *to_posix_cond(pthread_cond_t *cvar) /* Try and automatically associate a posix_cond */ if (sys_bitarray_alloc(&posix_cond_bitarray, 1, &bit) < 0) { /* No conds left to allocate */ + LOG_ERR("Unable to allocate pthread_cond_t"); return NULL; } @@ -92,13 +99,17 @@ static int cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu, k_timeout_t time return EINVAL; } + LOG_DBG("Waiting on cond %p with timeout %llx", cv, timeout.ticks); ret = k_condvar_wait(cv, m, timeout); if (ret == -EAGAIN) { + LOG_ERR("Timeout waiting on cond %p", cv); ret = ETIMEDOUT; } else if (ret < 0) { + LOG_ERR("k_condvar_wait() failed: %d", ret); ret = -ret; } else { __ASSERT_NO_MSG(ret == 0); + LOG_DBG("Cond %p received signal", cv); } return ret; @@ -114,8 +125,10 @@ int pthread_cond_signal(pthread_cond_t *cvar) return EINVAL; } + LOG_DBG("Signaling cond %p", cv); ret = k_condvar_signal(cv); if (ret < 0) { + LOG_ERR("k_condvar_signal() failed: %d", ret); return -ret; } @@ -134,8 +147,10 @@ int pthread_cond_broadcast(pthread_cond_t *cvar) return EINVAL; } + LOG_DBG("Broadcasting on cond %p", cv); ret = k_condvar_broadcast(cv); if (ret < 0) { + LOG_ERR("k_condvar_broadcast() failed: %d", ret); return -ret; } @@ -167,6 +182,8 @@ int pthread_cond_init(pthread_cond_t *cvar, const pthread_condattr_t *att) return ENOMEM; } + LOG_DBG("Initialized cond %p", cv); + return 0; } @@ -187,6 +204,8 @@ int pthread_cond_destroy(pthread_cond_t *cvar) *cvar = -1; + LOG_DBG("Destroyed cond %p", cv); + return 0; } From 8131a67d6f0c63faab083b004c65a908c33479fb Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 19 Sep 2023 13:10:44 +0200 Subject: [PATCH 0639/4498] soc/arm/silabs_exx32: select missing `CONFIG_SOC_GECKO_SERIESx` This commit: * adds the `CONFIG_SOC_GECKO_SERIES0` Kconfig option for Gecko Series 0 SoCs * selects the proper `CONFIG_SOC_GECKO_SERIESx` option where it's currently missing Fixes #62806. Signed-off-by: Filip Kokosinski --- soc/arm/silabs_exx32/Kconfig | 13 ++++++++++--- soc/arm/silabs_exx32/efm32hg/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32pg1b/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32wg/Kconfig.series | 1 + west.yml | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index a99c060c68f..cdd96703850 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -21,11 +21,11 @@ config SOC_PART_NUMBER that you should not set directly. The part number selection choice defines the default value for this string. -config SOC_GECKO_SERIES2 +config SOC_GECKO_SERIES0 bool help - Set if we're building for Gecko Series 2 SoC. - This is equivalent of _SILICON_LABS_32B_SERIES_2 definition in HAL + Set if we're building for Gecko Series 0 SoC. + This is equivalent of _SILICON_LABS_32B_SERIES_0 definition in HAL code. config SOC_GECKO_SERIES1 @@ -35,6 +35,13 @@ config SOC_GECKO_SERIES1 This is equivalent of _SILICON_LABS_32B_SERIES_1 definition in HAL code. +config SOC_GECKO_SERIES2 + bool + help + Set if we're building for Gecko Series 2 SoC. + This is equivalent of _SILICON_LABS_32B_SERIES_2 definition in HAL + code. + config SOC_GECKO_BURTC bool help diff --git a/soc/arm/silabs_exx32/efm32hg/Kconfig.series b/soc/arm/silabs_exx32/efm32hg/Kconfig.series index 4acdfa793cc..33793b5386d 100644 --- a/soc/arm/silabs_exx32/efm32hg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32hg/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_EFM32HG select SOC_GECKO_CMU select SOC_GECKO_GPIO select HAS_PM + select SOC_GECKO_SERIES0 help Enable support for EFM32 Happy Gecko MCU series diff --git a/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series b/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series index caeae082a3b..5a22fa29908 100644 --- a/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFM32PG1B select SOC_GECKO_EMU select SOC_GECKO_GPIO select HAS_PM + select SOC_GECKO_SERIES1 help Enable support for EFM32 PearlGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32wg/Kconfig.series b/soc/arm/silabs_exx32/efm32wg/Kconfig.series index f339c755e05..99dfba375d1 100644 --- a/soc/arm/silabs_exx32/efm32wg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32wg/Kconfig.series @@ -15,5 +15,6 @@ config SOC_SERIES_EFM32WG select SOC_GECKO_CMU select SOC_GECKO_GPIO select HAS_PM + select SOC_GECKO_SERIES0 help Enable support for EFM32 WonderGecko MCU series diff --git a/west.yml b/west.yml index 85e92e965f0..01fc12724d1 100644 --- a/west.yml +++ b/west.yml @@ -219,7 +219,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 267cd0bb17cf3cd431633a40b6d37a981e78dcb7 + revision: 32f35f1b3763b4d31021c656ff7cd4e7b192a97c path: modules/hal/silabs groups: - hal From be6dd12f3a7cacbe54fdf22a3dcb307c00e95e1a Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 18 Sep 2023 13:55:43 -0500 Subject: [PATCH 0640/4498] i2c: Fix documentation ifdefry The docs should be viewable if doxygen is being run, and that requires checking for the __DOXYGEN__ define. This should fix the missing I2C callback, k_poll_signal, and rtio API sections not being shown in the built documentation. Signed-off-by: Tom Burdick --- include/zephyr/drivers/i2c.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/zephyr/drivers/i2c.h b/include/zephyr/drivers/i2c.h index c3ea9bb43eb..f0268322ecb 100644 --- a/include/zephyr/drivers/i2c.h +++ b/include/zephyr/drivers/i2c.h @@ -227,7 +227,7 @@ typedef int (*i2c_api_transfer_cb_t)(const struct device *dev, i2c_callback_t cb, void *userdata); #endif /* CONFIG_I2C_CALLBACK */ -#if defined(CONFIG_I2C_RTIO) || defined(DOXYGEN) +#if defined(CONFIG_I2C_RTIO) || defined(__DOXYGEN__) /** * @typedef i2c_api_iodev_submit @@ -778,7 +778,7 @@ static inline int z_impl_i2c_transfer(const struct device *dev, return res; } -#ifdef CONFIG_I2C_CALLBACK +#if defined(CONFIG_I2C_CALLBACK) || defined(__DOXYGEN__) /** * @brief Perform data transfer to another I2C device in controller mode. @@ -787,7 +787,7 @@ static inline int z_impl_i2c_transfer(const struct device *dev, * to another I2C device asynchronously with a callback completion. * * @see i2c_transfer() - * @funcprop \isr_ok + * @funcprops \isr_ok * * @param dev Pointer to the device structure for an I2C controller * driver configured in controller mode. @@ -915,7 +915,7 @@ static inline int i2c_write_read_cb_dt(const struct i2c_dt_spec *spec, struct i2 read_buf, num_read, cb, userdata); } -#ifdef CONFIG_POLL +#if defined(CONFIG_POLL) || defined(__DOXYGEN__) /** @cond INTERNAL_HIDDEN */ void z_i2c_transfer_signal_cb(const struct device *dev, int result, void *userdata); @@ -928,14 +928,14 @@ void z_i2c_transfer_signal_cb(const struct device *dev, int result, void *userda * to another I2C device asynchronously with a k_poll_signal completion. * * @see i2c_transfer_cb() - * @funcprop \isr_ok + * @funcprops \isr_ok * * @param dev Pointer to the device structure for an I2C controller * driver configured in controller mode. * @param msgs Array of messages to transfer, must live until callback completes. * @param num_msgs Number of messages to transfer. * @param addr Address of the I2C target device. - * @param signal Signal to notify of transfer completion. + * @param sig Signal to notify of transfer completion. * * @retval 0 If successful. * @retval -EIO General input / output error. @@ -962,7 +962,7 @@ static inline int i2c_transfer_signal(const struct device *dev, #endif /* CONFIG_I2C_CALLBACK */ -#if defined(CONFIG_I2C_RTIO) || defined(DOXYGEN) +#if defined(CONFIG_I2C_RTIO) || defined(__DOXYGEN__) /** * @brief Submit request(s) to an I2C device with RTIO @@ -987,7 +987,8 @@ extern const struct rtio_iodev_api i2c_iodev_api; * These do not need to be shared globally but doing so * will save a small amount of memory. * - * @param node DT_NODE + * @param name Symbolic name of the iodev to define + * @param node_id Devicetree node identifier */ #define I2C_DT_IODEV_DEFINE(name, node_id) \ const struct i2c_dt_spec _i2c_dt_spec_##name = \ From cbc6af0d098f41590af821d672a4c9d23300328d Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 18 Sep 2023 16:15:07 -0500 Subject: [PATCH 0641/4498] spi: Cleanup and fix SPI docs build Use the defined(__DOXYGEN__) more specifically in the header to better match i2c.h and make things more explicit. Removes the define being setup in zephyr.doxyfile.in. Fixes some of the deprecation notes and what to look for instead. Fixes some typos. The async, signal, and rtio APIs for SPI are now shown in the built docs as would be expected. Signed-off-by: Tom Burdick --- doc/zephyr.doxyfile.in | 1 - include/zephyr/drivers/spi.h | 45 ++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 6d5ad2793bc..7565a7401ec 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -2377,7 +2377,6 @@ PREDEFINED = __DOXYGEN__ \ CONFIG_SCHED_DEADLINE \ CONFIG_SETTINGS_RUNTIME \ CONFIG_SMP \ - CONFIG_SPI_ASYNC \ CONFIG_SYS_CLOCK_EXISTS \ CONFIG_THREAD_CUSTOM_DATA \ CONFIG_THREAD_MONITOR \ diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 3e121a1da0e..671040de6a3 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -775,7 +775,7 @@ static inline int spi_transceive_dt(const struct spi_dt_spec *spec, * * @note This function is synchronous. * - * @note This function is an helper function calling spi_transceive. + * @note This function is a helper function calling spi_transceive. * * @param dev Pointer to the device structure for the driver instance * @param config Pointer to a valid spi_config structure instance. @@ -816,7 +816,7 @@ static inline int spi_read_dt(const struct spi_dt_spec *spec, * * @note This function is synchronous. * - * @note This function is an helper function calling spi_transceive. + * @note This function is a helper function calling spi_transceive. * * @param dev Pointer to the device structure for the driver instance * @param config Pointer to a valid spi_config structure instance. @@ -852,8 +852,7 @@ static inline int spi_write_dt(const struct spi_dt_spec *spec, return spi_write(spec->bus, &spec->config, tx_bufs); } -/* Doxygen defines this so documentation is generated. */ -#ifdef CONFIG_SPI_ASYNC +#if defined(CONFIG_SPI_ASYNC) || defined(__DOXYGEN__) /** * @brief Read/write the specified amount of data from the SPI driver. @@ -894,7 +893,7 @@ static inline int spi_transceive_cb(const struct device *dev, return api->transceive_async(dev, config, tx_bufs, rx_bufs, callback, userdata); } -#ifdef CONFIG_POLL +#if defined(CONFIG_POLL) || defined(__DOXYGEN__) /** @cond INTERNAL_HIDDEN */ void z_spi_transfer_signal_cb(const struct device *dev, int result, void *userdata); @@ -941,8 +940,7 @@ static inline int spi_transceive_signal(const struct device *dev, /** * @brief Alias for spi_transceive_signal for backwards compatibility * - * @deprecated - * @see spi_transceive_signal + * @deprecated Use @ref spi_transceive_signal instead. */ __deprecated static inline int spi_transceive_async(const struct device *dev, const struct spi_config *config, @@ -958,7 +956,7 @@ __deprecated static inline int spi_transceive_async(const struct device *dev, * * @note This function is asynchronous. * - * @note This function is an helper function calling spi_transceive_signal. + * @note This function is a helper function calling spi_transceive_signal. * * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} * and @kconfig{CONFIG_POLL} are selected. @@ -987,8 +985,7 @@ static inline int spi_read_signal(const struct device *dev, /** * @brief Alias for spi_read_signal for backwards compatibility * - * @deprecated - * @see spi_read_signal + * @deprecated Use @ref spi_read_signal instead. */ __deprecated static inline int spi_read_async(const struct device *dev, const struct spi_config *config, @@ -1003,7 +1000,7 @@ __deprecated static inline int spi_read_async(const struct device *dev, * * @note This function is asynchronous. * - * @note This function is an helper function calling spi_transceive_async. + * @note This function is a helper function calling spi_transceive_async. * * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} * and @kconfig{CONFIG_POLL} are selected. @@ -1030,10 +1027,9 @@ static inline int spi_write_signal(const struct device *dev, } /** - * @brief Alias for spi_read_signal for backwards compatibility + * @brief Alias for spi_write_signal for backwards compatibility * - * @deprecated - * @see spi_read_signal + * @deprecated Use @ref spi_write_signal instead. */ __deprecated static inline int spi_write_async(const struct device *dev, const struct spi_config *config, @@ -1048,18 +1044,14 @@ __deprecated static inline int spi_write_async(const struct device *dev, #endif /* CONFIG_SPI_ASYNC */ -#if defined(CONFIG_SPI_RTIO) || defined(DOXYGEN) +#if defined(CONFIG_SPI_RTIO) || defined(__DOXYGEN__) /** * @brief Submit a SPI device with a request * - * @param dev SPI device * @param iodev_sqe Prepared submissions queue entry connected to an iodev * defined by SPI_IODEV_DEFINE. * Must live as long as the request is in flight. - * - * @retval 0 If successful. - * @retval -errno Negative errno code on failure. */ static inline void spi_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) { @@ -1078,7 +1070,10 @@ extern const struct rtio_iodev_api spi_iodev_api; * These do not need to be shared globally but doing so * will save a small amount of memory. * - * @param node DT_NODE + * @param name Symbolic name to use for defining the iodev + * @param node_id Devicetree node identifier + * @param operation_ SPI operational mode + * @param delay_ Chip select delay in microseconds */ #define SPI_DT_IODEV_DEFINE(name, node_id, operation_, delay_) \ const struct spi_dt_spec _spi_dt_spec_##name = \ @@ -1103,11 +1098,11 @@ static inline bool spi_is_ready_iodev(const struct rtio_iodev *spi_iodev) /** * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests * - * @param r rtio context - * @param iodev iodev to transceive with - * @param tx_bufs transmit buffer set - * @param rx_bufs receive buffer set - * @param sqe[out] Last sqe submitted, NULL if not enough memory + * @param[in] r rtio context + * @param[in] iodev iodev to transceive with + * @param[in] tx_bufs transmit buffer set + * @param[in] rx_bufs receive buffer set + * @param[out] last_sqe last sqe submitted, NULL if not enough memory * * @retval Number of submission queue entries * @retval -ENOMEM out of memory From 839258a9544a4781d07453d44eac328399559690 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 01:09:55 +0000 Subject: [PATCH 0642/4498] boards: rcar_salvator_xs_m3: not a default test platform This is not an emulation platform, so it should not be set as a default. Signed-off-by: Anas Nashif --- boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml b/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml index 413e33258bf..80903847d59 100644 --- a/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml +++ b/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml @@ -10,7 +10,6 @@ supported: - clock_control - uart testing: - default: true ignore_tags: - net - bluetooth From 6c0a14822ed2fd8f70760bf85a42b2ed756c9520 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 17 Aug 2023 18:00:32 +0300 Subject: [PATCH 0643/4498] boards: doc: Include only index document to toctree Use correct glob pattern to exclude common rst helpers from toctree. Signed-off-by: Andrei Emeltchenko --- boards/x86/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/x86/index.rst b/boards/x86/index.rst index 07afe762193..d51c2551c4f 100644 --- a/boards/x86/index.rst +++ b/boards/x86/index.rst @@ -7,4 +7,4 @@ x86 Boards :maxdepth: 1 :glob: - **/* + **/index From 1dd3c6f9c2ac77e906b6e16a805a27a3fadcb934 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 18 Aug 2023 11:01:39 +0300 Subject: [PATCH 0644/4498] boards: x86: doc: Orphan included RST helpers Mark documents, which are included in other documents as :orphan: following existing samples in Zephyr tree. Signed-off-by: Andrei Emeltchenko --- boards/x86/common/efi_boot.rst | 2 ++ boards/x86/common/net_boot.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/boards/x86/common/efi_boot.rst b/boards/x86/common/efi_boot.rst index 140de965bf5..bfd88d276f5 100644 --- a/boards/x86/common/efi_boot.rst +++ b/boards/x86/common/efi_boot.rst @@ -1,3 +1,5 @@ +:orphan: + Preparing the Boot Device ------------------------- diff --git a/boards/x86/common/net_boot.rst b/boards/x86/common/net_boot.rst index 98543b00037..20e2de0f45b 100644 --- a/boards/x86/common/net_boot.rst +++ b/boards/x86/common/net_boot.rst @@ -1,3 +1,5 @@ +:orphan: + Prepare Linux host ------------------ From fe5c915a562c6924394759e386a75e5b0c95f377 Mon Sep 17 00:00:00 2001 From: TaiJu Wu Date: Mon, 18 Sep 2023 20:34:53 +0000 Subject: [PATCH 0645/4498] test: fix ITRERATION_COUNT typo ITERATION_COUNT was written as ITRERATION_COUNT. Signed-off-by: TaiJu Wu --- .../kernel/sched/schedule_api/src/test_priority_scheduling.c | 4 ++-- tests/kernel/sched/schedule_api/src/test_slice_scheduling.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/kernel/sched/schedule_api/src/test_priority_scheduling.c b/tests/kernel/sched/schedule_api/src/test_priority_scheduling.c index dfd7ba57460..7d72b54c0d6 100644 --- a/tests/kernel/sched/schedule_api/src/test_priority_scheduling.c +++ b/tests/kernel/sched/schedule_api/src/test_priority_scheduling.c @@ -16,7 +16,7 @@ #else #define NUM_THREAD 10 #endif -#define ITRERATION_COUNT 5 +#define ITERATION_COUNT 5 #define BASE_PRIORITY 1 BUILD_ASSERT(NUM_THREAD <= MAX_NUM_THREAD); @@ -83,7 +83,7 @@ ZTEST(threads_scheduling, test_priority_scheduling) K_NO_WAIT); } - while (count < ITRERATION_COUNT) { + while (count < ITERATION_COUNT) { /* Wait for each thread to complete */ for (int i = 0; i < NUM_THREAD; i++) { diff --git a/tests/kernel/sched/schedule_api/src/test_slice_scheduling.c b/tests/kernel/sched/schedule_api/src/test_slice_scheduling.c index af2d1ff9884..a65e7dcb3c7 100644 --- a/tests/kernel/sched/schedule_api/src/test_slice_scheduling.c +++ b/tests/kernel/sched/schedule_api/src/test_slice_scheduling.c @@ -19,7 +19,7 @@ #define NUM_THREAD 10 #endif #define BASE_PRIORITY 0 -#define ITRERATION_COUNT 5 +#define ITERATION_COUNT 5 BUILD_ASSERT(NUM_THREAD <= MAX_NUM_THREAD); /* slice size in millisecond */ @@ -113,7 +113,7 @@ ZTEST(threads_scheduling, test_slice_scheduling) /* enable time slice */ k_sched_time_slice_set(SLICE_SIZE, K_PRIO_PREEMPT(BASE_PRIORITY)); - while (count < ITRERATION_COUNT) { + while (count < ITERATION_COUNT) { k_uptime_delta(&elapsed_slice); /* Keep the current thread busy for more than one slice, From 6d64fe67ee7810833e88737c8e5e6e70a635b046 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Mon, 18 Sep 2023 16:26:27 +0200 Subject: [PATCH 0646/4498] twister: Change category of skip due to emulation_platforms The value of emulation_platforms is a bool corresponding to --emulation-only CLI option. Therefore, it should be registered as Filters.CMD_LINE. Without it, twister raises errors when an integration platform is descoped due to this option. Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/testplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 7c837000672..9f55d240ca2 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -936,7 +936,7 @@ def apply_filters(self, **kwargs): elif emulation_platforms: self.add_instances(instance_list) for instance in list(filter(lambda inst: not inst.platform.simulation != 'na', instance_list)): - instance.add_filter("Not an emulated platform", Filters.PLATFORM) + instance.add_filter("Not an emulated platform", Filters.CMD_LINE) else: self.add_instances(instance_list) From 42aa8fd72c716aa1042e946afa03d94294994f07 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 15 Sep 2023 15:22:15 +0200 Subject: [PATCH 0647/4498] twister: Always change skip to error on integration platforms Before only with --integration such skips were changed to errors. This hinders issues when twister is call with --all flag in CI and new skips on integration platforms are not caught. Then those skips cause errors in other PRs when --integration was used. Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/testplan.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 9f55d240ca2..f7242943df6 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -1024,8 +1024,8 @@ def _create_build_dir_link(self, links_dir_path, instance): def change_skip_to_error_if_integration(options, instance): - ''' If integration mode is on all skips on integration_platforms are treated as errors.''' - if options.integration and instance.platform.name in instance.testsuite.integration_platforms \ + ''' All skips on integration_platforms are treated as errors.''' + if instance.platform.name in instance.testsuite.integration_platforms \ and "quarantine" not in instance.reason.lower(): # Do not treat this as error if filter type is command line filters = {t['type'] for t in instance.filters} From dee8bb5ed0b7db7009c6cace616b2bb3cb1e8e93 Mon Sep 17 00:00:00 2001 From: Manoel Brunnen Date: Mon, 18 Sep 2023 11:00:48 +0200 Subject: [PATCH 0648/4498] twister: fix test plan to skip unconnected platforms Remove dead and erroneous (DUT is not a dict) if branch. Simply use the self.options.platform list. Which is filled by either the hardware map or the '--platform' option. This change addresses issue #62723 and #62560. Signed-off-by: Manoel Brunnen --- scripts/pylib/twister/twisterlib/testplan.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index f7242943df6..2e0eb9880f7 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -215,16 +215,10 @@ def load(self): self.load_from_file(self.options.load_tests) self.selected_platforms = set(p.platform.name for p in self.instances.values()) elif self.options.test_only: - # Get list of connected hardware and filter tests to only be run on connected hardware - # in cases where no platform was specified when running the tests. - # If the platform does not exist in the hardware map, just skip it. - connected_list = [] - if self.options.platform: - connected_list = self.options.platform - else: - for connected in self.hwm.duts: - if connected['connected']: - connected_list.append(connected['platform']) + # Get list of connected hardware and filter tests to only be run on connected hardware. + # If the platform does not exist in the hardware map or was not specified by --platform, + # just skip it. + connected_list = self.options.platform if self.options.exclude_platform: for excluded in self.options.exclude_platform: if excluded in connected_list: From 196b1d6289e34836404681400a4a6d91044d324b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 14 Sep 2023 14:07:02 +0000 Subject: [PATCH 0649/4498] modem: hl7800: replace an snprintk with a strncpy GCC format-truncation kicks in on this printk whenever the logging configuration transforms the LOG_WRN below into a noop, and the snprintk return argument become unused. Fix that by switching to strncpy, fixes: zephyrproject/zephyr/drivers/modem/hl7800.c:1786:74: warning: '%s' directive output may be truncated writing up to 53 bytes into a region of size 21 [-Wformat-truncation=] reproduced with: west build -p -b mg100 -T samples/net/telnet/sample.net.telnet Signed-off-by: Fabio Baltieri --- drivers/modem/hl7800.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c index 9e59cf5e33b..291856a01ff 100644 --- a/drivers/modem/hl7800.c +++ b/drivers/modem/hl7800.c @@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_MODEM_LOG_LEVEL); #include #include +#include #include #include @@ -1762,9 +1763,9 @@ static bool on_cmd_atcmdinfo_imei(struct net_buf **buf, uint16_t len) */ static bool on_cmd_atcmdinfo_iccid(struct net_buf **buf, uint16_t len) { - int ret; char value[MDM_CCID_RESP_MAX_SIZE]; char *delim; + int iccid_len; size_t out_len; out_len = net_buf_linearize(value, sizeof(value), *buf, 0, len); @@ -1783,9 +1784,13 @@ static bool on_cmd_atcmdinfo_iccid(struct net_buf **buf, uint16_t len) LOG_INF("EID: %s", delim + 1); } - ret = snprintk(iface_ctx.mdm_iccid, sizeof(iface_ctx.mdm_iccid), "%s", value); - if (ret > MDM_HL7800_ICCID_MAX_STRLEN) { - LOG_WRN("ICCID too long: %d", ret); + iccid_len = strlen(value); + strncpy(iface_ctx.mdm_iccid, value, sizeof(iface_ctx.mdm_iccid)); + len = MIN(iccid_len, sizeof(iface_ctx.mdm_iccid) - 1); + iface_ctx.mdm_iccid[len] = '\0'; + + if (iccid_len > len) { + LOG_WRN("ICCID too long: %d (max %d)", iccid_len, len); } LOG_INF("ICCID: %s", iface_ctx.mdm_iccid); From 04bb819d20107ab924ccc94872e442b73d2a6503 Mon Sep 17 00:00:00 2001 From: Weiwei Guo Date: Mon, 24 Jul 2023 16:20:30 +0800 Subject: [PATCH 0650/4498] net: mqtt-sn: Improve thread safety of publish/topic allocators Current MQTT-SN topic and publish allocators are not thread safe. Fix this, by using k_mem_slab instead of arrays. Signed-off-by: Weiwei Guo --- subsys/net/lib/mqtt_sn/mqtt_sn.c | 53 +++++++++----------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn.c b/subsys/net/lib/mqtt_sn/mqtt_sn.c index 95b79d490d6..4335a663557 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn.c @@ -24,7 +24,6 @@ struct mqtt_sn_confirmable { int64_t last_attempt; uint16_t msg_id; uint8_t retries; - bool in_use; }; struct mqtt_sn_publish { @@ -37,8 +36,6 @@ struct mqtt_sn_publish { bool retain; }; -static struct mqtt_sn_publish mqtt_sn_pubs[CONFIG_MQTT_SN_LIB_MAX_PUBLISH]; - enum mqtt_sn_topic_state { MQTT_SN_TOPIC_STATE_REGISTERING, MQTT_SN_TOPIC_STATE_REGISTERED, @@ -58,7 +55,9 @@ struct mqtt_sn_topic { enum mqtt_sn_topic_state state; }; -static struct mqtt_sn_topic topics[CONFIG_MQTT_SN_LIB_MAX_TOPICS]; +K_MEM_SLAB_DEFINE_STATIC(publishes, sizeof(struct mqtt_sn_publish), + CONFIG_MQTT_SN_LIB_MAX_PUBLISH, 4); +K_MEM_SLAB_DEFINE_STATIC(topics, sizeof(struct mqtt_sn_topic), CONFIG_MQTT_SN_LIB_MAX_TOPICS, 4); enum mqtt_sn_client_state { MQTT_SN_CLIENT_DISCONNECTED, @@ -126,13 +125,12 @@ static void mqtt_sn_con_init(struct mqtt_sn_confirmable *con) con->last_attempt = 0; con->retries = N_RETRY; con->msg_id = next_msg_id(); - con->in_use = true; } static void mqtt_sn_publish_destroy(struct mqtt_sn_client *client, struct mqtt_sn_publish *pub) { sys_slist_find_and_remove(&client->publish, &pub->next); - memset(pub, 0, sizeof(*pub)); + k_mem_slab_free(&publishes, (void *)pub); } static void mqtt_sn_publish_destroy_all(struct mqtt_sn_client *client) @@ -142,32 +140,21 @@ static void mqtt_sn_publish_destroy_all(struct mqtt_sn_client *client) while ((next = sys_slist_get(&client->publish)) != NULL) { pub = SYS_SLIST_CONTAINER(next, pub, next); - memset(pub, 0, sizeof(*pub)); - } -} - -static struct mqtt_sn_publish *mqtt_sn_publish_find_empty(void) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(mqtt_sn_pubs); i++) { - if (!mqtt_sn_pubs[i].con.in_use) { - return &mqtt_sn_pubs[i]; - } + k_mem_slab_free(&publishes, (void *)pub); } - - return NULL; } static struct mqtt_sn_publish *mqtt_sn_publish_create(struct mqtt_sn_data *data) { - struct mqtt_sn_publish *pub = mqtt_sn_publish_find_empty(); + struct mqtt_sn_publish *pub; - if (!pub) { + if (k_mem_slab_alloc(&publishes, (void **)&pub, K_NO_WAIT)) { LOG_ERR("Can't create PUB: no free slot"); return NULL; } + memset(pub, 0, sizeof(*pub)); + if (data && data->data && data->size) { if (data->size > sizeof(pub->pubdata)) { LOG_ERR("Can't create PUB: Too much data (%" PRIu16 ")", data->size); @@ -211,28 +198,17 @@ static struct mqtt_sn_publish *mqtt_sn_publish_find_topic(struct mqtt_sn_client return NULL; } -static struct mqtt_sn_topic *mqtt_sn_topic_find_empty(void) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(topics); i++) { - if (!topics[i].con.in_use) { - return &topics[i]; - } - } - - return NULL; -} - static struct mqtt_sn_topic *mqtt_sn_topic_create(struct mqtt_sn_data *name) { - struct mqtt_sn_topic *topic = mqtt_sn_topic_find_empty(); + struct mqtt_sn_topic *topic; - if (!topic) { + if (k_mem_slab_alloc(&topics, (void **)&topic, K_NO_WAIT)) { LOG_ERR("Can't create topic: no free slot"); return NULL; } + memset(topic, 0, sizeof(*topic)); + if (!name || !name->data || !name->size) { LOG_ERR("Can't create topic with empty name"); return NULL; @@ -291,7 +267,6 @@ static void mqtt_sn_topic_destroy(struct mqtt_sn_client *client, struct mqtt_sn_ } sys_slist_find_and_remove(&client->topic, &topic->next); - memset(topic, 0, sizeof(*topic)); } static void mqtt_sn_topic_destroy_all(struct mqtt_sn_client *client) @@ -308,7 +283,7 @@ static void mqtt_sn_topic_destroy_all(struct mqtt_sn_client *client) mqtt_sn_publish_destroy(client, pub); } - memset(topic, 0, sizeof(*topic)); + k_mem_slab_free(&topics, (void *)topic); } } From 326d8c79fe49857b99913ec07cb132e1d1dca860 Mon Sep 17 00:00:00 2001 From: Weiwei Guo Date: Tue, 5 Sep 2023 14:47:31 +0800 Subject: [PATCH 0651/4498] net: mqtt-sn: Active mqtt-sn process work when buffer run out When publish buffer run out, no thread active process work. Fix this, by reschedule process work. Signed-off-by: Weiwei Guo --- subsys/net/lib/mqtt_sn/mqtt_sn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn.c b/subsys/net/lib/mqtt_sn/mqtt_sn.c index 4335a663557..213ca55753f 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn.c @@ -867,6 +867,7 @@ int mqtt_sn_publish(struct mqtt_sn_client *client, enum mqtt_sn_qos qos, pub = mqtt_sn_publish_create(data); if (!pub) { + k_work_reschedule(&client->process_work, K_NO_WAIT); return -ENOMEM; } From 2d02cae964f2c88dffdb9893725b4efcb86cc7e5 Mon Sep 17 00:00:00 2001 From: Kuno Heltborg Date: Mon, 7 Aug 2023 11:00:15 +0200 Subject: [PATCH 0652/4498] MGMT: Add user data to mgmt_handler RFC: #60616 Signed-off-by: Kuno Heltborg --- doc/releases/release-notes-3.5.rst | 3 +++ include/zephyr/mgmt/mcumgr/mgmt/mgmt.h | 3 +++ subsys/mgmt/mcumgr/mgmt/Kconfig | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 00e23f6d30b..0fd4fb94a95 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -328,6 +328,9 @@ Libraries / Subsystems * Added :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING` that allows to erase slots pending for next boot, that are not revert slots. + * Added ``user_data`` as an optional field to :c:struct:`mgmt_handler` when + :kconfig:option:`CONFIG_MCUMGR_MGMT_HANDLER_USER_DATA` is enabled. + * File systems * Added support for ext2 file system. diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h index e681ea2b939..ec09bb03467 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h @@ -71,6 +71,9 @@ typedef int (*mgmt_handler_fn)(struct smp_streamer *ctxt); struct mgmt_handler { mgmt_handler_fn mh_read; mgmt_handler_fn mh_write; +#if IS_ENABLED(CONFIG_MCUMGR_MGMT_HANDLER_USER_DATA) + void *user_data; +#endif }; /** diff --git a/subsys/mgmt/mcumgr/mgmt/Kconfig b/subsys/mgmt/mcumgr/mgmt/Kconfig index d1701627860..a0c889f0c5e 100644 --- a/subsys/mgmt/mcumgr/mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/mgmt/Kconfig @@ -25,3 +25,9 @@ config MCUMGR_MGMT_NOTIFICATION_HOOKS or decline the current operation, by returning false this will signal to the calling function that the request should be denied, for informal-only notifications or acceptable, true must be returned by all the registered notification handlers. + +config MCUMGR_MGMT_HANDLER_USER_DATA + bool "MCUmgr mgmt handler user data support" + help + This will add an extra field to the struct mgmt_handler that will allow a user + to pass user_data when the defined handler is called. From 0c6a3faeb4ae0973aaa31980f8e8fbef8f5b28b3 Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Tue, 19 Sep 2023 13:53:10 +0300 Subject: [PATCH 0653/4498] mgmt: mcumgr: Image management client fix Fix broken MCUmgr image group client. Signed-off-by: Juha Heiskanen --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h | 4 ++-- .../mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt | 1 + .../mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h index 6ee12fb5a61..8cede40d64e 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h @@ -40,7 +40,7 @@ struct mcumgr_image_data { /** Image number */ uint32_t img_num; /** Image SHA256 checksum */ - char hash[IMG_MGMT_HASH_LEN]; + char hash[IMG_MGMT_DATA_SHA_LEN]; /** Image Version */ char version[IMG_MGMT_VER_MAX_STR_LEN + 1]; /** Image Flags */ @@ -76,7 +76,7 @@ struct mcumgr_image_upload { */ struct img_gr_upload { /** Image 256-bit hash */ - char sha256[IMG_MGMT_HASH_LEN]; + char sha256[IMG_MGMT_DATA_SHA_LEN]; /** True when Hash is configured, false when not */ bool hash_initialized; /** Image size */ diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt index 693891896d8..cae17e865ff 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt @@ -13,3 +13,4 @@ zephyr_library_sources( ) zephyr_library_include_directories(include) +zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c index b0e38640e8c..9ab8ee02dcd 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c @@ -126,7 +126,7 @@ static int image_state_res_fn(struct net_buf *nb, void *user_data) goto out; } /* Check that mandatory parameters have decoded */ - if (hash.len != IMG_MGMT_HASH_LEN || !version.len || + if (hash.len != IMG_MGMT_DATA_SHA_LEN || !version.len || !zcbor_map_decode_bulk_key_found(list_res_decode, ARRAY_SIZE(list_res_decode), "slot")) { LOG_ERR("Missing mandatory parametrs"); @@ -138,7 +138,7 @@ static int image_state_res_fn(struct net_buf *nb, void *user_data) image_info->image_list[image_info->image_list_length].img_num = img_num; image_info->image_list[image_info->image_list_length].slot_num = slot_num; memcpy(image_info->image_list[image_info->image_list_length].hash, - hash.value, IMG_MGMT_HASH_LEN); + hash.value, IMG_MGMT_DATA_SHA_LEN); if (version.len > IMG_MGMT_VER_MAX_STR_LEN) { LOG_WRN("Version truncated len %d -> %d", version.len, IMG_MGMT_VER_MAX_STR_LEN); @@ -277,7 +277,7 @@ static size_t upload_message_header_size(struct img_gr_upload *upload_state) /* Write hash when it defined and offset is 0 */ if (ok && upload_state->hash_initialized) { ok = zcbor_tstr_put_lit(zse, "sha") && - zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_HASH_LEN); + zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_DATA_SHA_LEN); } if (ok) { @@ -311,7 +311,7 @@ int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_siz client->upload.offset = 0; client->upload.image_num = image_num; if (image_hash) { - memcpy(client->upload.sha256, image_hash, IMG_MGMT_HASH_LEN); + memcpy(client->upload.sha256, image_hash, IMG_MGMT_DATA_SHA_LEN); client->upload.hash_initialized = true; } else { client->upload.hash_initialized = false; @@ -395,7 +395,7 @@ int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, if (ok && active_client->upload.hash_initialized) { ok = zcbor_tstr_put_lit(zse, "sha") && zcbor_bstr_encode_ptr(zse, active_client->upload.sha256, - IMG_MGMT_HASH_LEN); + IMG_MGMT_DATA_SHA_LEN); } } @@ -485,7 +485,7 @@ int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool /* Write hash data */ if (ok && hash) { ok = zcbor_tstr_put_lit(zse, "hash") && - zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_HASH_LEN); + zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_DATA_SHA_LEN); } /* Close map */ if (ok) { From 3e0ed42427046d988601b2222f63e16669657c2d Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Tue, 19 Sep 2023 13:57:25 +0300 Subject: [PATCH 0654/4498] tests: mcumgr: Updated MCUmg & smp client tests Fixed broken MCUmgr client unit test. Added test_ -prefix to tests. Added testcase.yaml to test trigger test run. Signed-off-by: Juha Heiskanen --- .../subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt | 2 +- tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf | 7 +++++-- .../mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c | 10 ++++++++-- tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c | 12 ++++++------ tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml | 11 +++++++++++ tests/subsys/mgmt/mcumgr/smp_client/src/main.c | 6 +++--- tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml | 11 +++++++++++ 7 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt index a0f76554629..20a96480514 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt @@ -14,4 +14,4 @@ FILE(GLOB app_sources target_sources(app PRIVATE ${app_sources}) -add_compile_definitions(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1) +zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf index 46835a49dc7..461a0ec9477 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf @@ -12,14 +12,17 @@ CONFIG_NET_BUF=y CONFIG_BASE64=y CONFIG_ZCBOR=y CONFIG_CRC=y -# Enable mcumgr +# Enable MCUboot util library +CONFIG_MCUBOOT_BOOTUTIL_LIB=y +# Enable mcumgr client CONFIG_MCUMGR=y CONFIG_SMP_CLIENT=y -CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1 CONFIG_MCUMGR_GRP_OS_CLIENT=y CONFIG_MCUMGR_GRP_IMG_CLIENT=y CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO=y CONFIG_MCUMGR_GRP_OS_CLIENT_RESET=y +# disable default image group build +CONFIG_IMG_MANAGER=n # Extend System Workqueue stack size CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c index 5bd784a3954..aea03935fe6 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c @@ -24,6 +24,12 @@ static struct mcumgr_image_data image_dummy_info[2]; static size_t test_offset; static uint8_t *image_hash_ptr; +#ifdef CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER +#define IMG_UPDATABLE_IMAGE_COUNT CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER +#else +#define IMG_UPDATABLE_IMAGE_COUNT 1 +#endif + #define ZCBOR_ENCODE_FLAG(zse, label, value) \ (zcbor_tstr_put_lit(zse, label) && zcbor_bool_put(zse, value)) @@ -117,7 +123,7 @@ void img_read_response(int count) zcbor_tstr_put_term(zse, image_dummy_info[i].version) && zcbor_tstr_put_term(zse, "hash") && - zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_HASH_LEN) && + zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_DATA_SHA_LEN) && ZCBOR_ENCODE_FLAG(zse, "bootable", image_dummy_info[i].flags.bootable) && ZCBOR_ENCODE_FLAG(zse, "pending", image_dummy_info[i].flags.pending) && ZCBOR_ENCODE_FLAG(zse, "confirmed", image_dummy_info[i].flags.confirmed) && @@ -126,7 +132,7 @@ void img_read_response(int count) zcbor_map_end_encode(zse, 15); } - ok = ok && zcbor_list_end_encode(zse, 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER); + ok = ok && zcbor_list_end_encode(zse, 2 * IMG_UPDATABLE_IMAGE_COUNT); ok = ok && zcbor_map_end_encode(zse, 15); diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c index a15e82f17a6..bf70f178fe7 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c @@ -27,7 +27,7 @@ static struct smp_client_object smp_client; static struct img_mgmt_client img_client; static struct os_mgmt_client os_client; -ZTEST(mcumgr_client, img_upload) +ZTEST(mcumgr_client, test_img_upload) { int rc; struct mcumgr_image_upload response; @@ -108,7 +108,7 @@ ZTEST(mcumgr_client, img_upload) response.image_upload_offset); } -ZTEST(mcumgr_client, img_erase) +ZTEST(mcumgr_client, test_img_erase) { int rc; @@ -130,7 +130,7 @@ ZTEST(mcumgr_client, img_erase) zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); } -ZTEST(mcumgr_client, image_state_read) +ZTEST(mcumgr_client, test_image_state_read) { int rc; struct mcumgr_image_state res_buf; @@ -153,7 +153,7 @@ ZTEST(mcumgr_client, image_state_read) res_buf.image_list_length); } -ZTEST(mcumgr_client, image_state_set) +ZTEST(mcumgr_client, test_image_state_set) { int rc; char hash[32]; @@ -199,7 +199,7 @@ ZTEST(mcumgr_client, image_state_set) true, image_info[0].flags.confirmed); } -ZTEST(mcumgr_client, os_reset) +ZTEST(mcumgr_client, test_os_reset) { int rc; @@ -217,7 +217,7 @@ ZTEST(mcumgr_client, os_reset) zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); } -ZTEST(mcumgr_client, os_echo) +ZTEST(mcumgr_client, test_os_echo) { int rc; diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml b/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml new file mode 100644 index 00000000000..99b9fac34ad --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +tests: + mgmt.mcumgr.mcumgr.client: + platform_allow: native_posix + tags: + - mcumgr + - mcumgr_client diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c index be1a3968274..7b6ad8eafa8 100644 --- a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c @@ -32,7 +32,7 @@ int smp_client_res_cb(struct net_buf *nb, void *user_data) return 0; } -ZTEST(smp_client, buf_alloc) +ZTEST(smp_client, test_buf_alloc) { struct smp_client_object smp_client; @@ -56,7 +56,7 @@ ZTEST(smp_client, buf_alloc) } } -ZTEST(smp_client, msg_send_timeout) +ZTEST(smp_client, test_msg_send_timeout) { struct net_buf *nb; @@ -72,7 +72,7 @@ ZTEST(smp_client, msg_send_timeout) zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); } -ZTEST(smp_client, msg_response_handler) +ZTEST(smp_client, test_msg_response_handler) { struct smp_hdr dst_hdr; int rc; diff --git a/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml b/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml new file mode 100644 index 00000000000..49971116251 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +tests: + mgmt.mcumgr.smp.client: + platform_allow: native_posix + tags: + - mcumgr + - smp_client From e2005b6e48d3b578f83fdfaaff547d1f8082ce35 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 11 Aug 2023 16:50:28 +0200 Subject: [PATCH 0655/4498] modules: openthread: radio: OT now uses standard TX timestamp Synchronizes with the new upstream RX/TX timestamp definition in OpenThread based on the standard's SFD. This change is synchronized with the upstream OpenThread implementation via west.yml. Signed-off-by: Florian Grandel --- modules/openthread/CMakeLists.txt | 12 ++++++++++++ modules/openthread/Kconfig.features | 13 +++++++++++++ modules/openthread/platform/radio.c | 4 +--- tests/subsys/openthread/radio_test.c | 10 ++++------ west.yml | 2 +- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 67acbe00dec..826d9b31590 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -154,6 +154,12 @@ else() set(OT_DATASET_UPDATER OFF CACHE BOOL "Enable Dataset updater" FORCE) endif() +if(CONFIG_OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT) + set(OT_DEVICE_PROP_LEADER_WEIGHT ON CACHE BOOL "Enable device props for leader weight" FORCE) +else() + set(OT_DEVICE_PROP_LEADER_WEIGHT OFF CACHE BOOL "Enable device props for leader weight" FORCE) +endif() + if(CONFIG_OPENTHREAD_DHCP6_CLIENT) set(OT_DHCP6_CLIENT ON CACHE BOOL "Enable DHCPv6 Client" FORCE) else() @@ -274,6 +280,12 @@ else() set(OT_LINK_METRICS_INITIATOR OFF CACHE BOOL "Enable Link Metrics initiator for Thread 1.2" FORCE) endif() +if(CONFIG_OPENTHREAD_LINK_METRICS_MANAGER) + set(OT_LINK_METRICS_MANAGER ON CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) +else() + set(OT_LINK_METRICS_MANAGER OFF CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) +endif() + if(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT) set(OT_LINK_METRICS_SUBJECT ON CACHE BOOL "Enable Link Metrics subject for Thread 1.2" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 61b0efc921b..87c220944a4 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -92,6 +92,16 @@ config OPENTHREAD_CSL_RECEIVER help Enable CSL Receiver support for Thread 1.2 +config OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT + bool "Device props for leader weight" + default n if (OPENTHREAD_THREAD_VERSION_1_1 || \ + OPENTHREAD_THREAD_VERSION_1_2 || \ + OPENTHREAD_THREAD_VERSION_1_3) + default y + help + Enable the device properties which are then used to determine and set + the Leader Weight. + config OPENTHREAD_DATASET_UPDATER bool "Dataset updater" @@ -165,6 +175,9 @@ config OPENTHREAD_LEGACY config OPENTHREAD_LINK_METRICS_INITIATOR bool "Link Metrics initiator" +config OPENTHREAD_LINK_METRICS_MANAGER + bool "Link Metrics manager" + config OPENTHREAD_LINK_METRICS_SUBJECT bool "Link Metrics subject" diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 94b79ddfed6..9d50e445714 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -58,8 +58,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #define CHANNEL_COUNT OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN + 1 -#define PHY_SHR_DURATION 160 /* duration of SHR in us */ - enum pending_events { PENDING_EVENT_FRAME_TO_SEND, /* There is a tx frame to send */ PENDING_EVENT_FRAME_RECEIVED, /* Radio has received new frame */ @@ -397,7 +395,7 @@ void transmit_message(struct k_work *tx_job) (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) { #if defined(CONFIG_NET_PKT_TXTIME) uint32_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + - sTransmitFrame.mInfo.mTxInfo.mTxDelay + PHY_SHR_DURATION; + sTransmitFrame.mInfo.mTxInfo.mTxDelay; struct net_ptp_time timestamp = ns_to_net_ptp_time(convert_32bit_us_wrapped_to_64bit_ns(tx_at)); net_pkt_set_timestamp(tx_pkt, ×tamp); diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index fb6c8755039..87a7013a0d5 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -30,8 +30,6 @@ DEFINE_FFF_GLOBALS; #define FRAME_TYPE_MASK 0x07 #define FRAME_TYPE_ACK 0x02 -#define PHY_SHR_DURATION 160 - K_SEM_DEFINE(ot_sem, 0, 1); /** @@ -295,10 +293,10 @@ ZTEST(openthread_radio, test_tx_test) get_time_mock_fake.return_val = (int64_t)UINT32_MAX * NSEC_PER_USEC + 1000; frm->mInfo.mTxInfo.mTxDelayBaseTime = 3U; frm->mInfo.mTxInfo.mTxDelay = 5U; - expected_target_time = get_time_mock_fake.return_val + - (frm->mInfo.mTxInfo.mTxDelayBaseTime + - frm->mInfo.mTxInfo.mTxDelay + PHY_SHR_DURATION) * - NSEC_PER_USEC; + expected_target_time = + get_time_mock_fake.return_val + + (frm->mInfo.mTxInfo.mTxDelayBaseTime + frm->mInfo.mTxInfo.mTxDelay) * + NSEC_PER_USEC; } /* ACKed frame */ diff --git a/west.yml b/west.yml index 01fc12724d1..9b2f1dff851 100644 --- a/west.yml +++ b/west.yml @@ -303,7 +303,7 @@ manifest: revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 path: modules/lib/open-amp - name: openthread - revision: f7690fe7e9d638341921808cba6a3e695ec0131e + revision: d62167ee34b091e7025c9ec2820aae71e17a3944 path: modules/lib/openthread - name: percepio path: modules/debug/percepio From 88fa4904ab3c45c094eeb596014bdc8fe4970690 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 28 Aug 2023 14:38:15 +0200 Subject: [PATCH 0656/4498] samples: Bluetooth: TMAP peripheral context fixes The sample did not properly include the source context in the advertising data. It also set different contexts for PACS and the advertising data Signed-off-by: Emil Gydesen --- .../tmap_peripheral/src/bap_unicast_sr.c | 9 ++++----- samples/bluetooth/tmap_peripheral/src/main.c | 13 ++++--------- .../tmap_peripheral/src/tmap_peripheral.h | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index 16556251c97..a62b2b774a9 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -20,15 +20,14 @@ #include #include -#define AVAILABLE_SINK_CONTEXT CONFIG_BT_PACS_SNK_CONTEXT -#define AVAILABLE_SOURCE_CONTEXT CONFIG_BT_PACS_SRC_CONTEXT +#include "tmap_peripheral.h" static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3(BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_32KHZ | BT_AUDIO_CODEC_LC3_FREQ_48KHZ, BT_AUDIO_CODEC_LC3_DURATION_7_5 | BT_AUDIO_CODEC_LC3_DURATION_10, BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(2), 30, 155u, 1u, - (CONFIG_BT_PACS_SNK_CONTEXT | CONFIG_BT_PACS_SRC_CONTEXT)); + (AVAILABLE_SINK_CONTEXT | AVAILABLE_SOURCE_CONTEXT)); static struct bt_conn *default_conn; static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; @@ -331,7 +330,7 @@ int bap_unicast_sr_init(void) { bt_bap_unicast_server_register_cb(&unicast_server_cb); - if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) { + if (IS_ENABLED(CONFIG_BT_PAC_SNK)) { /* Register CT required capabilities */ bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); @@ -347,7 +346,7 @@ int bap_unicast_sr_init(void) AVAILABLE_SINK_CONTEXT); } - if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) { + if (IS_ENABLED(CONFIG_BT_PAC_SRC)) { /* Register CT required capabilities */ bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap); diff --git a/samples/bluetooth/tmap_peripheral/src/main.c b/samples/bluetooth/tmap_peripheral/src/main.c index 2fb2dd54c68..3b7c891be64 100644 --- a/samples/bluetooth/tmap_peripheral/src/main.c +++ b/samples/bluetooth/tmap_peripheral/src/main.c @@ -24,20 +24,15 @@ #include "tmap_peripheral.h" -#define AVAILABLE_SINK_CONTEXT (BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | \ - BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | \ - BT_AUDIO_CONTEXT_TYPE_MEDIA | \ - BT_AUDIO_CONTEXT_TYPE_GAME | \ - BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL) - static struct bt_conn *default_conn; static struct k_work_delayable call_terminate_set_work; static struct k_work_delayable media_pause_set_work; static uint8_t unicast_server_addata[] = { - BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */ + BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */ BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */ BT_BYTES_LIST_LE16(AVAILABLE_SINK_CONTEXT), + BT_BYTES_LIST_LE16(AVAILABLE_SOURCE_CONTEXT), 0x00, /* Metadata length */ }; @@ -47,8 +42,8 @@ static const uint8_t cap_addata[] = { }; static uint8_t tmap_addata[] = { - BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL), /* TMAS UUID */ - (BT_TMAP_ROLE_UMR | BT_TMAP_ROLE_CT), 0x00, /* TMAP Role */ + BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL), /* TMAS UUID */ + BT_BYTES_LIST_LE16(BT_TMAP_ROLE_UMR | BT_TMAP_ROLE_CT), /* TMAP Role */ }; static uint8_t csis_rsi_addata[BT_CSIP_RSI_SIZE]; diff --git a/samples/bluetooth/tmap_peripheral/src/tmap_peripheral.h b/samples/bluetooth/tmap_peripheral/src/tmap_peripheral.h index b23a8adb23b..b01f5c8b0c8 100644 --- a/samples/bluetooth/tmap_peripheral/src/tmap_peripheral.h +++ b/samples/bluetooth/tmap_peripheral/src/tmap_peripheral.h @@ -6,6 +6,23 @@ #include +#if defined(CONFIG_BT_ASCS_ASE_SNK) +#define AVAILABLE_SINK_CONTEXT \ + (BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | \ + BT_AUDIO_CONTEXT_TYPE_MEDIA | BT_AUDIO_CONTEXT_TYPE_GAME | \ + BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL) +#else +#define AVAILABLE_SINK_CONTEXT 0x0000 +#endif /* CONFIG_BT_ASCS_ASE_SNK */ + +#if defined(CONFIG_BT_ASCS_ASE_SRC) +#define AVAILABLE_SOURCE_CONTEXT \ + (BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | \ + BT_AUDIO_CONTEXT_TYPE_MEDIA | BT_AUDIO_CONTEXT_TYPE_GAME | \ + BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL) +#else +#define AVAILABLE_SOURCE_CONTEXT 0x0000 +#endif /* CONFIG_BT_ASCS_ASE_SRC */ /** * @brief Initialize the VCP Volume Renderer role * From 3cb0d7ad6f1001a399352cf405679a5d8049da8c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 28 Aug 2023 15:09:01 +0200 Subject: [PATCH 0657/4498] samples: Bluetooth: TMAP Peripheral fix appearance Use the defind value, BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD, instead of the hard coded "magic numbers". Signed-off-by: Emil Gydesen --- samples/bluetooth/tmap_peripheral/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/bluetooth/tmap_peripheral/src/main.c b/samples/bluetooth/tmap_peripheral/src/main.c index 3b7c891be64..59aa8c70ef0 100644 --- a/samples/bluetooth/tmap_peripheral/src/main.c +++ b/samples/bluetooth/tmap_peripheral/src/main.c @@ -52,7 +52,8 @@ static bool peer_is_ums; static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, 0x09, 0x41), /* Appearance - Earbud */ + BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, + BT_BYTES_LIST_LE16(BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD)), BT_DATA_BYTES(BT_DATA_UUID16_SOME, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), BT_UUID_16_ENCODE(BT_UUID_CAS_VAL), BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL)), #if defined(CONFIG_BT_CSIP_SET_MEMBER) From d2495b14f25a49b7247d1d325bd97ecb5530851c Mon Sep 17 00:00:00 2001 From: Maciej Baczmanski Date: Tue, 5 Sep 2023 07:32:03 +0200 Subject: [PATCH 0658/4498] modules: openthread: fix unused variable during `otPlatCryptoInit` If asserts are disabled, there is a warning in 'otPlatCryptoInit' regarding unused variable `err`. This commit fixes that. Signed-off-by: Maciej Baczmanski --- modules/openthread/platform/crypto_psa.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index e61177ef4c4..e5b234ce030 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -137,9 +137,8 @@ void otPlatCryptoInit(void) * PSA with emulated TFM, Settings have to be initialized at the end of otPlatCryptoInit(), * to be available before storing Network Key. */ - int err = settings_subsys_init(); - - __ASSERT(!err, "Failed to initialize settings"); + __ASSERT_EVAL((void) settings_subsys_init(), int err = settings_subsys_init(), + !err, "Failed to initialize settings"); #endif } From ccc2a7a90d91d59097793e7bae11ca38b2552ded Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 5 Sep 2023 10:32:49 +0300 Subject: [PATCH 0659/4498] doc: release: Migration guide for CONFIG_NET_INTERFACE_NAME option Clarified the impact of CONFIG_NET_INTERFACE_NAME Kconfig option as it can change how SO_BINDTODEVICE BSD socket option behaves. Signed-off-by: Jukka Rissanen --- doc/releases/migration-guide-3.5.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 3106ed9c4ce..7330c64132e 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -47,6 +47,16 @@ Required changes - "IO" -> <( DT_MEM_ARM(ATTR_MPU_IO) )> - "EXTMEM" -> <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )> +* A new networking Kconfig option :kconfig:option:`CONFIG_NET_INTERFACE_NAME` + defaults to ``y``. The option allows user to set a name to a network interface. + During system startup a default name is assigned to the network interface like + ``eth0`` to the first Ethernet network interface. The option affects the behavior + of ``SO_BINDTODEVICE`` BSD socket option. If the Kconfig option is set to ``n``, + which is how the system worked earlier, then the name of the device assigned + to the network interface is used by the ``SO_BINDTODEVICE`` socket option. + If the Kconfig option is set to ``y`` (current default), then the network + interface name is used by the ``SO_BINDTODEVICE`` socket option. + Recommended Changes ******************* From b0f92e13b92e5a3d54f2d3694f623aef7cf71f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 19:42:38 +0200 Subject: [PATCH 0660/4498] doc: video: samples: Use new Sphinx extension to document samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new code-sample directive and roles to document the video capture samples so that they show up as "Related samples" when browsing the API documentation. Signed-off-by: Benjamin Cabé --- samples/subsys/video/capture/README.rst | 9 +++++---- samples/subsys/video/tcpserversink/README.rst | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/samples/subsys/video/capture/README.rst b/samples/subsys/video/capture/README.rst index 4609da6a7de..29dedf2bdf4 100644 --- a/samples/subsys/video/capture/README.rst +++ b/samples/subsys/video/capture/README.rst @@ -1,12 +1,13 @@ -.. _video_capture-sample: +.. zephyr:code-sample:: video-capture + :name: Video capture + :relevant-api: video_interface -Video Capture -############# + Use the video API to retrieve video frames from a capture device. Description *********** -This sample application uses the Video API to retrieve video frames from the +This sample application uses the :ref:`Video API ` to retrieve video frames from the video capture device, writes a frame count message to the console, and then discards the video frame data. diff --git a/samples/subsys/video/tcpserversink/README.rst b/samples/subsys/video/tcpserversink/README.rst index df856011091..6c7fc89afde 100644 --- a/samples/subsys/video/tcpserversink/README.rst +++ b/samples/subsys/video/tcpserversink/README.rst @@ -1,12 +1,13 @@ -.. _video_tcpserversink-sample: +.. zephyr:code-sample:: video-tcpserversink + :name: Video TCP server sink + :relevant-api: video_interface bsd_sockets -VIDEO TCP SERVER SINK -##################### + Capture video frames and send them over the network to a TCP client. Description *********** -This sample application gets frames from video capture device and sends +This sample application gets frames from a video capture device and sends them over the network to the connected TCP client. Requirements From 9f4cd4a72764627f48fcc64c962f3de31bad2a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 8 Sep 2023 10:31:55 +0200 Subject: [PATCH 0661/4498] net: openthread: doc: Fix doxygen group for openthread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the name/brief of the openthread doxygen group Signed-off-by: Benjamin Cabé --- include/zephyr/net/openthread.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/openthread.h b/include/zephyr/net/openthread.h index 34aa78df824..d928f9cb056 100644 --- a/include/zephyr/net/openthread.h +++ b/include/zephyr/net/openthread.h @@ -12,8 +12,8 @@ #define ZEPHYR_INCLUDE_NET_OPENTHREAD_H_ /** - * @brief OpenThread l2 stack api - * @defgroup OpenThread l2 layer + * @brief OpenThread Layer 2 abstraction layer + * @defgroup openthread OpenThread L2 abstraction layer * @ingroup networking * @{ */ From 994558ef8e0ddacf0df913f84b0bef9e0177b70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 8 Sep 2023 10:34:42 +0200 Subject: [PATCH 0662/4498] samples: net: doc: Use new Sphinx extension to document networking samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new code-sample directive and roles to document the networking samples so that they show up as "Related samples" when browsing the various relevant networking APIs. Signed-off-by: Benjamin Cabé --- boards/arm/atsamr21_xpro/doc/index.rst | 6 +++--- boards/arm/cc3220sf_launchxl/doc/index.rst | 4 ++-- boards/arm/cc3235sf_launchxl/doc/index.rst | 4 ++-- boards/posix/native_posix/doc/index.rst | 2 +- boards/shields/atmel_rf2xx/doc/index.rst | 4 ++-- boards/shields/inventek_eswifi/doc/index.rst | 2 +- doc/connectivity/networking/api/capture.rst | 2 +- doc/connectivity/networking/api/coap.rst | 4 ++-- doc/connectivity/networking/api/dhcpv4.rst | 2 +- doc/connectivity/networking/api/dns_resolve.rst | 2 +- doc/connectivity/networking/api/gptp.rst | 2 +- doc/connectivity/networking/api/gsm_modem.rst | 2 +- doc/connectivity/networking/api/http.rst | 2 +- doc/connectivity/networking/api/lwm2m.rst | 4 ++-- doc/connectivity/networking/api/mqtt.rst | 4 ++-- doc/connectivity/networking/api/mqtt_sn.rst | 2 +- doc/connectivity/networking/api/promiscuous.rst | 2 +- doc/connectivity/networking/api/sockets.rst | 4 ++-- doc/connectivity/networking/api/socks5.rst | 4 ++-- doc/connectivity/networking/api/thread.rst | 4 ++-- doc/connectivity/networking/api/vlan.rst | 2 +- doc/connectivity/networking/api/zperf.rst | 2 +- .../networking/armfvp_user_networking_setup.rst | 2 +- .../networking/native_posix_setup.rst | 2 +- .../networking/network_monitoring.rst | 2 +- .../networking/networking-api-usage.rst | 4 ++-- .../networking_with_multiple_instances.rst | 4 ++-- doc/connectivity/networking/overview.rst | 6 +++--- doc/connectivity/networking/qemu_eth_setup.rst | 4 ++-- doc/connectivity/networking/qemu_setup.rst | 2 +- doc/connectivity/networking/usbnet_setup.rst | 2 +- doc/connectivity/usb/device/usb_device.rst | 6 +++--- doc/connectivity/usb/device_next/usb_device.rst | 2 +- doc/hardware/peripherals/canbus/controller.rst | 4 ++-- doc/releases/release-notes-1.14.rst | 2 +- doc/releases/release-notes-3.4.rst | 2 +- doc/services/device_mgmt/ota.rst | 2 +- samples/net/capture/README.rst | 11 +++++++---- samples/net/cellular_modem/README.rst | 6 +++--- samples/net/cloud/aws_iot_mqtt/README.rst | 7 ++++--- samples/net/cloud/mqtt_azure/README.rst | 7 ++++--- samples/net/cloud/tagoio_http_post/README.rst | 7 ++++--- samples/net/dhcpv4_client/README.rst | 7 ++++--- samples/net/dns_resolve/README.rst | 7 ++++--- samples/net/dsa/README.rst | 7 ++++--- samples/net/eth_native_posix/README.rst | 7 ++++--- samples/net/gptp/README.rst | 7 ++++--- samples/net/gsm_modem/README.rst | 6 +++--- samples/net/ipv4_autoconf/README.rst | 7 ++++--- samples/net/lldp/README.rst | 7 ++++--- samples/net/lwm2m_client/README.rst | 7 ++++--- samples/net/mdns_responder/README.rst | 7 ++++--- samples/net/mqtt_publisher/README.rst | 7 ++++--- samples/net/mqtt_sn_publisher/README.rst | 13 +++++++------ samples/net/openthread/coprocessor/README.rst | 7 ++++--- samples/net/promiscuous_mode/README.rst | 7 ++++--- samples/net/sockets/big_http_download/README.rst | 9 +++++---- samples/net/sockets/can/README.rst | 7 ++++--- samples/net/sockets/coap_client/README.rst | 7 ++++--- samples/net/sockets/coap_server/README.rst | 7 ++++--- samples/net/sockets/dumb_http_server/README.rst | 7 ++++--- .../net/sockets/dumb_http_server_mt/README.rst | 9 +++++---- samples/net/sockets/echo/README.rst | 7 ++++--- samples/net/sockets/echo_async/README.rst | 11 ++++++----- samples/net/sockets/echo_async_select/README.rst | 11 ++++++----- samples/net/sockets/echo_client/README.rst | 11 ++++++----- samples/net/sockets/echo_server/README.rst | 11 ++++++----- samples/net/sockets/http_client/README.rst | 7 ++++--- samples/net/sockets/http_get/README.rst | 7 ++++--- samples/net/sockets/net_mgmt/README.rst | 7 ++++--- samples/net/sockets/packet/README.rst | 7 ++++--- samples/net/sockets/sntp_client/README.rst | 7 ++++--- samples/net/sockets/socketpair/README.rst | 7 ++++--- samples/net/sockets/tcp/README.rst | 7 ++++--- samples/net/sockets/txtime/README.rst | 15 ++++++++------- samples/net/sockets/websocket_client/README.rst | 7 ++++--- samples/net/stats/README.rst | 7 ++++--- samples/net/syslog_net/README.rst | 7 ++++--- samples/net/telnet/README.rst | 7 ++++--- samples/net/tftp_client/README.rst | 7 ++++--- samples/net/virtual/README.rst | 10 +++++++--- samples/net/vlan/README.rst | 7 ++++--- samples/net/wifi/README.rst | 7 ++++--- samples/net/wpan_serial/README.rst | 7 ++++--- samples/net/wpanusb/README.rst | 7 ++++--- samples/net/zperf/README.rst | 7 ++++--- samples/subsys/mgmt/updatehub/README.rst | 4 ++-- 87 files changed, 275 insertions(+), 223 deletions(-) diff --git a/boards/arm/atsamr21_xpro/doc/index.rst b/boards/arm/atsamr21_xpro/doc/index.rst index b362648d652..139b6ea6bcb 100644 --- a/boards/arm/atsamr21_xpro/doc/index.rst +++ b/boards/arm/atsamr21_xpro/doc/index.rst @@ -159,10 +159,10 @@ externally connected SPI devices. +-------------+------------------------------------------------------------------------------------------+ Zephyr provide several samples that can use this technology. You can check -:ref:`wpanusb-sample` and :ref:`wpan_serial-sample` examples as starting +:zephyr:code-sample:`wpanusb` and :zephyr:code-sample:`wpan-serial` examples as starting points. Another good test can be done with IPv6 by using the server/client -echo demo. More information at :ref:`sockets-echo-server-sample` and -:ref:`sockets-echo-client-sample`. +echo demo. More information at :zephyr:code-sample:`sockets-echo-server` and +:zephyr:code-sample:`sockets-echo-client`. Programming and Debugging ************************* diff --git a/boards/arm/cc3220sf_launchxl/doc/index.rst b/boards/arm/cc3220sf_launchxl/doc/index.rst index 00dad2e5a96..8b88133ccbd 100644 --- a/boards/arm/cc3220sf_launchxl/doc/index.rst +++ b/boards/arm/cc3220sf_launchxl/doc/index.rst @@ -261,7 +261,7 @@ re-specify the SSID and password. To connect to an AP, first run the Zephyr Wi-Fi shell sample application, and connect to a known AP with SSID and password. -See :ref:`wifi_sample` +See :zephyr:code-sample:`wifi-shell` Once the connection succeeds, the network co-processor keeps the AP identity in its persistent memory. Newly loaded Wi-Fi applications then need not explicitly @@ -284,7 +284,7 @@ and enabled by: keys to the secure flash filesystem, and enabling the TI Trusted Root-Certificate Catalog. -See :ref:`sockets-http-get` and +See :zephyr:code-sample:`sockets-http-get` and :zephyr_file:`samples/net/sockets/http_get/boards/cc3220sf_launchxl.conf` for an example. diff --git a/boards/arm/cc3235sf_launchxl/doc/index.rst b/boards/arm/cc3235sf_launchxl/doc/index.rst index cb0c5f7858f..71d8a44a8fb 100644 --- a/boards/arm/cc3235sf_launchxl/doc/index.rst +++ b/boards/arm/cc3235sf_launchxl/doc/index.rst @@ -261,7 +261,7 @@ re-specify the SSID and password. To connect to an AP, first run the Zephyr Wi-Fi shell sample application, and connect to a known AP with SSID and password. -See :ref:`wifi_sample` +See :zephyr:code-sample:`wifi-shell` Once the connection succeeds, the network co-processor keeps the AP identity in its persistent memory. Newly loaded Wi-Fi applications then need not explicitly @@ -284,7 +284,7 @@ and enabled by: keys to the secure flash filesystem, and enabling the TI Trusted Root-Certificate Catalog. -See :ref:`sockets-http-get` and +See :zephyr:code-sample:`sockets-http-get` and :zephyr_file:`samples/net/sockets/http_get/boards/cc3235sf_launchxl.conf` for an example. diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 630da2c17dc..185c80c583b 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -329,7 +329,7 @@ The following peripherals are currently provided with this board: be created if needed. The IP address configuration can be specified for each network interface instance. See :kconfig:option:`CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT` option for more details. - The :ref:`eth-native-posix-sample` sample app provides + The :zephyr:code-sample:`eth-native-posix` sample app provides some use examples and more information about this driver configuration. Note that this device can only be used with Linux hosts, and that the user diff --git a/boards/shields/atmel_rf2xx/doc/index.rst b/boards/shields/atmel_rf2xx/doc/index.rst index 31abe4c03f8..dbcdccbd3e8 100644 --- a/boards/shields/atmel_rf2xx/doc/index.rst +++ b/boards/shields/atmel_rf2xx/doc/index.rst @@ -283,8 +283,8 @@ and Echo client samples, which provide out-of-the-box configuration for both IEEE 802.15.4 and OpenThread. To enable IEEE 802.15.4 support in the samples, build them with ``overlay-802154.conf`` overlay config file. Same way, to enable OpenThread support, build them with ``overlay-ot.conf`` overlay -config file. See :ref:`sockets-echo-server-sample` and -:ref:`sockets-echo-client-sample` for details. +config file. See :zephyr:code-sample:`sockets-echo-server` and +:zephyr:code-sample:`sockets-echo-client` samples for details. Build and Programming ********************* diff --git a/boards/shields/inventek_eswifi/doc/index.rst b/boards/shields/inventek_eswifi/doc/index.rst index 699fd540190..e19713acd3f 100644 --- a/boards/shields/inventek_eswifi/doc/index.rst +++ b/boards/shields/inventek_eswifi/doc/index.rst @@ -140,7 +140,7 @@ Tested Boards Sample usage ************ -The reference sample for WIFI is :ref:`wifi_sample`. It allows you use WIFI +The reference sample for WIFI is :zephyr:code-sample:`wifi-shell`. It allows you to use WIFI shell to scan local Wireless networks. With the password you can pick, connect and send ping. diff --git a/doc/connectivity/networking/api/capture.rst b/doc/connectivity/networking/api/capture.rst index ba6e347170d..ee7605624c4 100644 --- a/doc/connectivity/networking/api/capture.rst +++ b/doc/connectivity/networking/api/capture.rst @@ -18,7 +18,7 @@ using ``net-shell`` or automatically by using the ``net_capture`` API. Sample usage ************ -See :ref:`Network capture sample application ` and +See :zephyr:code-sample:`net-capture` sample application and :ref:`network_monitoring` for details. diff --git a/doc/connectivity/networking/api/coap.rst b/doc/connectivity/networking/api/coap.rst index 8e5690b3387..a7d54f02235 100644 --- a/doc/connectivity/networking/api/coap.rst +++ b/doc/connectivity/networking/api/coap.rst @@ -142,7 +142,7 @@ in Zephyr. See the `net-tools `_ project for more details -The :ref:`coap-server-sample` sample can be built and executed on QEMU as described +The :zephyr:code-sample:`coap-server` sample can be built and executed on QEMU as described in :ref:`networking_with_qemu`. Use this command on the host to run the libcoap implementation of @@ -181,7 +181,7 @@ Follow the instruction to setup CoAP test suite from here: - https://github.com/eclipse/titan.misc - https://github.com/eclipse/titan.misc/tree/master/CoAP_Conf -After the build is complete, the :ref:`coap-server-sample` sample can be built +After the build is complete, the :zephyr:code-sample:`coap-server` sample can be built and executed on QEMU as described in :ref:`networking_with_qemu`. Change the client (test suite) and server (Zephyr coap-server sample) addresses diff --git a/doc/connectivity/networking/api/dhcpv4.rst b/doc/connectivity/networking/api/dhcpv4.rst index f9588e9dda4..e06bcd9182a 100644 --- a/doc/connectivity/networking/api/dhcpv4.rst +++ b/doc/connectivity/networking/api/dhcpv4.rst @@ -23,7 +23,7 @@ Note that Zephyr only supports DHCP client functionality. Sample usage ************ -See :ref:`dhcpv4-client-sample` for details. +See :zephyr:code-sample:`dhcpv4-client` sample application for details. API Reference ************* diff --git a/doc/connectivity/networking/api/dns_resolve.rst b/doc/connectivity/networking/api/dns_resolve.rst index fc4f0d8613c..d119fc74190 100644 --- a/doc/connectivity/networking/api/dns_resolve.rst +++ b/doc/connectivity/networking/api/dns_resolve.rst @@ -35,7 +35,7 @@ For more information about DNS configuration variables, see: Sample usage ************ -See :ref:`DNS resolve sample application ` for details. +See :zephyr:code-sample:`dns-resolve` sample application for details. API Reference ************* diff --git a/doc/connectivity/networking/api/gptp.rst b/doc/connectivity/networking/api/gptp.rst index e3bba55f50d..12dedeaab0b 100644 --- a/doc/connectivity/networking/api/gptp.rst +++ b/doc/connectivity/networking/api/gptp.rst @@ -66,7 +66,7 @@ Testing The stack has been informally tested using the `OpenAVnu gPTP `_ and `Linux ptp4l `_ daemons. -The :ref:`gPTP sample application ` from the Zephyr +The :zephyr:code-sample:`gPTP sample application ` from the Zephyr source distribution can be used for testing. .. _IEEE 802.1AS-2011 standard: diff --git a/doc/connectivity/networking/api/gsm_modem.rst b/doc/connectivity/networking/api/gsm_modem.rst index d44f68b38f1..cf15e429796 100644 --- a/doc/connectivity/networking/api/gsm_modem.rst +++ b/doc/connectivity/networking/api/gsm_modem.rst @@ -12,7 +12,7 @@ The Zephyr uses :ref:`PPP (Point-to-Point Protocol) ` to connect to the GSM modem using UART. Note that some cellular modems have proprietary offloading support using AT commands, but usually those modems also support 3GPP standards and provide PPP connection to them. -See :ref:`GSM modem sample application ` how to setup Zephyr +See :zephyr:code-sample:`GSM modem sample application ` how to setup Zephyr to use the GSM modem. The GSM muxing, that is defined in diff --git a/doc/connectivity/networking/api/http.rst b/doc/connectivity/networking/api/http.rst index a8b81b86357..060a41643d9 100644 --- a/doc/connectivity/networking/api/http.rst +++ b/doc/connectivity/networking/api/http.rst @@ -68,7 +68,7 @@ The following is an example of a very simple response handling function: LOG_INF("Response status %s", rsp->http_status); } -See :ref:`HTTP client sample application ` for +See :zephyr:code-sample:`HTTP client sample application ` for more information about the library usage. API Reference diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 6d26205511e..6ddc66a1836 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -227,7 +227,7 @@ The full list of registered objects and resource IDs can be found in the Zephyr's LwM2M library lives in the :zephyr_file:`subsys/net/lib/lwm2m`, with a client sample in :zephyr_file:`samples/net/lwm2m_client`. For more information -about the provided sample see: :ref:`lwm2m-client-sample` The sample can be +about the provided sample see: :zephyr:code-sample:`lwm2m-client`. The sample can be configured to use normal unsecure network sockets or sockets secured via DTLS. The Zephyr LwM2M library implements the following items: @@ -444,7 +444,7 @@ value of 1 is ok here). client.tls_tag = 1; /* <---- */ lwm2m_rd_client_start(&client, "endpoint-name", 0, rd_client_event); -For a more detailed LwM2M client sample see: :ref:`lwm2m-client-sample`. +For a more detailed LwM2M client sample see: :zephyr:code-sample:`lwm2m-client`. Multi-thread usage ****************** diff --git a/doc/connectivity/networking/api/mqtt.rst b/doc/connectivity/networking/api/mqtt.rst index b1090c8d394..973b61860e3 100644 --- a/doc/connectivity/networking/api/mqtt.rst +++ b/doc/connectivity/networking/api/mqtt.rst @@ -129,7 +129,7 @@ be called and an appropriate event notified. The connection can be closed by calling the ``mqtt_disconnect`` function. Zephyr provides sample code utilizing the MQTT client API. See -:ref:`mqtt-publisher-sample` for more information. +:zephyr:code-sample:`mqtt-publisher` for more information. Using MQTT with TLS ******************* @@ -162,7 +162,7 @@ registered in the system first. For more information on how to do that, refer to :ref:`secure sockets documentation `. An example of how to use TLS with MQTT is also present in -:ref:`mqtt-publisher-sample`. +:zephyr:code-sample:`mqtt-publisher` sample application. .. _mqtt_api_reference: diff --git a/doc/connectivity/networking/api/mqtt_sn.rst b/doc/connectivity/networking/api/mqtt_sn.rst index 40a1b9d8df8..13860346946 100644 --- a/doc/connectivity/networking/api/mqtt_sn.rst +++ b/doc/connectivity/networking/api/mqtt_sn.rst @@ -124,7 +124,7 @@ has no effect on the transport, however. If you want to close the transport (e.g the socket), call ``mqtt_sn_client_deinit``, which will deinit the transport as well. Zephyr provides sample code utilizing the MQTT-SN client API. See -:ref:`mqtt-sn-publisher-sample` for more information. +:zephyr:code-sample:`mqtt-sn-publisher-sample` for more information. Deviations from the standard **************************** diff --git a/doc/connectivity/networking/api/promiscuous.rst b/doc/connectivity/networking/api/promiscuous.rst index c5e18f58fb0..9b60770c00e 100644 --- a/doc/connectivity/networking/api/promiscuous.rst +++ b/doc/connectivity/networking/api/promiscuous.rst @@ -70,7 +70,7 @@ Finally the promiscuous mode can be turned OFF by the application like this: } -See :ref:`net-promiscuous-mode-sample` for a more comprehensive example. +See :zephyr:code-sample:`net-promiscuous-mode` for a more comprehensive example. API Reference diff --git a/doc/connectivity/networking/api/sockets.rst b/doc/connectivity/networking/api/sockets.rst index f7a77f68f67..3f632e3bea9 100644 --- a/doc/connectivity/networking/api/sockets.rst +++ b/doc/connectivity/networking/api/sockets.rst @@ -133,8 +133,8 @@ CA certificate and hostname can be set: Once configured, socket can be used just like a regular TCP socket. Several samples in Zephyr use secure sockets for communication. For a sample use -see e.g. :ref:`echo-server sample application ` or -:ref:`HTTP GET sample application `. +see e.g. :zephyr:code-sample:`echo-server sample application ` or +:zephyr:code-sample:`HTTP GET sample application `. Secure Sockets options ====================== diff --git a/doc/connectivity/networking/api/socks5.rst b/doc/connectivity/networking/api/socks5.rst index a935fd9e439..ab72270394a 100644 --- a/doc/connectivity/networking/api/socks5.rst +++ b/doc/connectivity/networking/api/socks5.rst @@ -47,5 +47,5 @@ SOCKS5 Proxy Usage in MQTT ************************** For MQTT client, there is :c:func:`mqtt_client_set_proxy()` API that the -application can call to setup SOCKS5 proxy. See :ref:`mqtt-publisher-sample` -for usage example. +application can call to setup SOCKS5 proxy. See :zephyr:code-sample:`mqtt-publisher` +sample application for usage example. diff --git a/doc/connectivity/networking/api/thread.rst b/doc/connectivity/networking/api/thread.rst index 6dae56d5c12..280758078fa 100644 --- a/doc/connectivity/networking/api/thread.rst +++ b/doc/connectivity/networking/api/thread.rst @@ -38,5 +38,5 @@ Sample usage You can try using OpenThread with the Zephyr Echo server and Echo client samples, which provide out-of-the-box configuration for OpenThread. To enable OpenThread support in these samples, build them with ``overlay-ot.conf`` overlay config file. -See :ref:`sockets-echo-server-sample` and :ref:`sockets-echo-client-sample` for -details. +See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` +samples for details. diff --git a/doc/connectivity/networking/api/vlan.rst b/doc/connectivity/networking/api/vlan.rst index b0fe35b79a4..efa6d60b8b0 100644 --- a/doc/connectivity/networking/api/vlan.rst +++ b/doc/connectivity/networking/api/vlan.rst @@ -37,7 +37,7 @@ function. The VLAN tagging for a given network interface can be disabled by a :c:func:`net_eth_vlan_disable` function. The application needs to configure the VLAN network interface itself, such as setting the IP address, etc. -See also the :ref:`VLAN sample application ` for API usage +See also the :zephyr:code-sample:`VLAN sample application ` for API usage example. The source code for that sample application can be found at :zephyr_file:`samples/net/vlan`. diff --git a/doc/connectivity/networking/api/zperf.rst b/doc/connectivity/networking/api/zperf.rst index 4f6674679d2..fe09823c057 100644 --- a/doc/connectivity/networking/api/zperf.rst +++ b/doc/connectivity/networking/api/zperf.rst @@ -22,7 +22,7 @@ are missing. LAST PACKET NOT RECEIVED!!! zperf can be enabled in any application, a dedicated sample is also present -in Zephyr. See :ref:`zperf sample application ` for details. +in Zephyr. See :zephyr:code-sample:`zperf sample application ` for details. Sample Usage ************ diff --git a/doc/connectivity/networking/armfvp_user_networking_setup.rst b/doc/connectivity/networking/armfvp_user_networking_setup.rst index c0aeb3a0693..618a33a8242 100644 --- a/doc/connectivity/networking/armfvp_user_networking_setup.rst +++ b/doc/connectivity/networking/armfvp_user_networking_setup.rst @@ -33,7 +33,7 @@ Using Arm FVP User Mode Networking with Zephyr Arm FVP user mode networking can be enabled in any applications and it doesn't need any configurations on the host system. This feature has been enabled in DHCPv4 client sample. -See :ref:`Sample DHCPv4 client application ` +See :zephyr:code-sample:`dhcpv4-client` sample application. Limitations ************* diff --git a/doc/connectivity/networking/native_posix_setup.rst b/doc/connectivity/networking/native_posix_setup.rst index 249cef7f07a..cc94c9f790b 100644 --- a/doc/connectivity/networking/native_posix_setup.rst +++ b/doc/connectivity/networking/native_posix_setup.rst @@ -10,7 +10,7 @@ Networking with native_posix board This page describes how to set up a virtual network between a (Linux) host and a Zephyr application running in a native_posix board. -In this example, the :ref:`sockets-echo-server-sample` sample application from +In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from the Zephyr source distribution is run in native_posix board. The Zephyr native_posix board instance is connected to a Linux host using a tuntap device which is modeled in Linux as an Ethernet network interface. diff --git a/doc/connectivity/networking/network_monitoring.rst b/doc/connectivity/networking/network_monitoring.rst index 0dbe00fa4fa..b0a20b287d0 100644 --- a/doc/connectivity/networking/network_monitoring.rst +++ b/doc/connectivity/networking/network_monitoring.rst @@ -13,7 +13,7 @@ Zephyr. This page describes how to set up a way to capture network traffic so that user is able to use Wireshark or similar tool in remote host to see the network packets sent or received by a Zephyr device. -See also the :ref:`net-capture-sample` sample application from the Zephyr +See also the :zephyr:code-sample:`net-capture` sample application from the Zephyr source distribution for configuration options that need to be enabled. Host Configuration diff --git a/doc/connectivity/networking/networking-api-usage.rst b/doc/connectivity/networking/networking-api-usage.rst index d1249d01e6d..0145482fec9 100644 --- a/doc/connectivity/networking/networking-api-usage.rst +++ b/doc/connectivity/networking/networking-api-usage.rst @@ -8,8 +8,8 @@ Applications should use the BSD socket API defined in and close a connection. The same API can be used when working with UDP or TCP data. See :ref:`BSD socket API ` for more details. -See :ref:`sockets-echo-server-sample` and :ref:`sockets-echo-client-sample` -applications how to create a simple server or client BSD socket based +See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` +sample applications to learn how to create a simple server or client BSD socket based application. The legacy connectivity API in :zephyr_file:`include/zephyr/net/net_context.h` should not be diff --git a/doc/connectivity/networking/networking_with_multiple_instances.rst b/doc/connectivity/networking/networking_with_multiple_instances.rst index 6bd4531c829..c83f7e04ed6 100644 --- a/doc/connectivity/networking/networking_with_multiple_instances.rst +++ b/doc/connectivity/networking/networking_with_multiple_instances.rst @@ -122,8 +122,8 @@ In terminal #3, type: Step 4 - Start Zephyr instances =============================== -In this example we start :ref:`sockets-echo-server-sample` and -:ref:`sockets-echo-client-sample` applications. You can use other applications +In this example we start :zephyr:code-sample:`sockets-echo-server` and +:zephyr:code-sample:`sockets-echo-client` sample applications. You can use other applications too as needed. In terminal #4, if you are using QEMU, type this: diff --git a/doc/connectivity/networking/overview.rst b/doc/connectivity/networking/overview.rst index c339632fdf1..f271bcd8a8c 100644 --- a/doc/connectivity/networking/overview.rst +++ b/doc/connectivity/networking/overview.rst @@ -69,12 +69,12 @@ can be disabled if not needed. are provided by mbedTLS library. * **MQTT** Message Queue Telemetry Transport (ISO/IEC PRF 20922) is supported. - A sample :ref:`mqtt-publisher-sample` client application for MQTT v3.1.1 is + A sample :zephyr:code-sample:`mqtt-publisher` client application for MQTT v3.1.1 is implemented. * **CoAP** Constrained Application Protocol (`RFC 7252 `_) is supported. - Both :ref:`coap-client-sample` and :ref:`coap-server-sample` sample + Both :zephyr:code-sample:`coap-client` and :zephyr:code-sample:`coap-server` sample applications are implemented. * **LWM2M** OMA Lightweight Machine-to-Machine Protocol @@ -83,7 +83,7 @@ can be disabled if not needed. Reporting" interfaces. The required core LwM2M objects are implemented as well as several IPSO Smart Objects. (`LwM2M specification 1.1.1`_) is supported in similar manner when enabled with a Kconfig option. - :ref:`lwm2m-client-sample` implements the library as an example. + :zephyr:code-sample:`lwm2m-client` sample implements the library as an example. * **DNS** Domain Name Service (`RFC 1035 `_) client functionality diff --git a/doc/connectivity/networking/qemu_eth_setup.rst b/doc/connectivity/networking/qemu_eth_setup.rst index 5d6aab68962..a0219e6126c 100644 --- a/doc/connectivity/networking/qemu_eth_setup.rst +++ b/doc/connectivity/networking/qemu_eth_setup.rst @@ -10,7 +10,7 @@ Networking with QEMU Ethernet This page describes how to set up a virtual network between a (Linux) host and a Zephyr application running in QEMU. -In this example, the :ref:`sockets-echo-server-sample` sample application from +In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from the Zephyr source distribution is run in QEMU. The Zephyr instance is connected to a Linux host using a tuntap device which is modeled in Linux as an Ethernet network interface. @@ -71,7 +71,7 @@ by running ``net-setup.sh`` like this: Step 2 - Start app in QEMU board ================================ -Build and start the :ref:`sockets-echo-server-sample` sample application. +Build and start the :zephyr:code-sample:`sockets-echo-server` sample application. In this example, the qemu_x86 board is used. In terminal #2, type: diff --git a/doc/connectivity/networking/qemu_setup.rst b/doc/connectivity/networking/qemu_setup.rst index 5740145cd74..f2b979867a8 100644 --- a/doc/connectivity/networking/qemu_setup.rst +++ b/doc/connectivity/networking/qemu_setup.rst @@ -13,7 +13,7 @@ targets such as qemu_x86 and qemu_cortex_m3). Some virtual ARM boards (such as qemu_cortex_a53) only support a single UART, in this case QEMU Ethernet is preferred, see :ref:`networking_with_eth_qemu` for details. -In this example, the :ref:`sockets-echo-server-sample` sample application from +In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from the Zephyr source distribution is run in QEMU. The QEMU instance is connected to a Linux host using a serial port, and SLIP is used to transfer data between the Zephyr application and Linux (over a chain of diff --git a/doc/connectivity/networking/usbnet_setup.rst b/doc/connectivity/networking/usbnet_setup.rst index 5f193770504..a71a48c6771 100644 --- a/doc/connectivity/networking/usbnet_setup.rst +++ b/doc/connectivity/networking/usbnet_setup.rst @@ -12,7 +12,7 @@ and a Zephyr application running on USB supported devices. The board is connected to Linux host using USB cable and provides an Ethernet interface to the host. -The :ref:`sockets-echo-server-sample` application from the Zephyr source +The :zephyr:code-sample:`sockets-echo-server` application from the Zephyr source distribution is run on supported board. The board is connected to a Linux host using a USB cable providing an Ethernet interface to the host. diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index 752d6392077..19fd5e61577 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -166,7 +166,7 @@ CDC ACM UART as backend for a subsystem or application: * ``zephyr,bt-c2h-uart`` used in Bluetooth, for example see :ref:`bluetooth-hci-uart-sample` * ``zephyr,ot-uart`` used in OpenThread, - for example see :ref:`coprocessor-sample` + for example see :zephyr:code-sample:`coprocessor` * ``zephyr,shell-uart`` used by shell for serial backend, for example see :zephyr_file:`samples/subsys/shell/shell_module` * ``zephyr,uart-mcumgr`` used by :ref:`smp_svr_sample` @@ -339,7 +339,7 @@ Ethernet connection between the remote (USB host) and Zephyr network support. * CDC EEM class, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_EEM` * RNDIS support, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_RNDIS` -See :ref:`zperf-sample` or :ref:`sockets-dumb-http-server-sample` for reference. +See :zephyr:code-sample:`zperf` or :zephyr:code-sample:`socket-dumb-http-server` for reference. Typically, users will need to add a configuration file overlay to the build, such as :zephyr_file:`samples/net/zperf/overlay-netusb.conf`. @@ -500,7 +500,7 @@ The following Product IDs are currently used: +-------------------------------------+--------+ | :ref:`bluetooth-hci-usb-h4-sample` | 0x000C | +-------------------------------------+--------+ -| :ref:`wpanusb-sample` | 0x000D | +| :zephyr:code-sample:`wpan-usb` | 0x000D | +-------------------------------------+--------+ The USB device descriptor field ``bcdDevice`` (Device Release Number) represents diff --git a/doc/connectivity/usb/device_next/usb_device.rst b/doc/connectivity/usb/device_next/usb_device.rst index c7755329538..1ef6f7ef933 100644 --- a/doc/connectivity/usb/device_next/usb_device.rst +++ b/doc/connectivity/usb/device_next/usb_device.rst @@ -51,7 +51,7 @@ At the moment only CDC ECM class is implemented and has support for multiple ins It provides a virtual Ethernet connection between the remote (USB host) and Zephyr network support. -See :ref:`zperf-sample` for reference. +See :zephyr:code-sample:`zperf` for reference. To build the sample for the new device support, set the configuration overlay file ``-DDEXTRA_CONF_FILE=overlay-usbd_next_ecm.conf`` and devicetree overlay file ``-DDTC_OVERLAY_FILE="usbd_next_ecm.overlay`` either directly or via ``west``. diff --git a/doc/hardware/peripherals/canbus/controller.rst b/doc/hardware/peripherals/canbus/controller.rst index 85dee4b0f67..82e004a6df1 100644 --- a/doc/hardware/peripherals/canbus/controller.rst +++ b/doc/hardware/peripherals/canbus/controller.rst @@ -331,9 +331,9 @@ which adds some computation and memory overhead. Samples ******* -We have two ready-to-build samples demonstrating use of the Zephyr CAN API +We have two ready-to-build samples demonstrating use of the Zephyr CAN API: :ref:`Zephyr CAN counter sample ` and -:ref:`SocketCAN sample `. +:zephyr:code-sample:`SocketCAN sample `. CAN Controller API Reference diff --git a/doc/releases/release-notes-1.14.rst b/doc/releases/release-notes-1.14.rst index 32393436194..45ed7625890 100644 --- a/doc/releases/release-notes-1.14.rst +++ b/doc/releases/release-notes-1.14.rst @@ -862,7 +862,7 @@ Networking * :ref:`Network interface ` numbering starts now from 1 for POSIX compatibility. * :ref:`OpenThread ` enhancements. -* :ref:`zperf ` sample application fixes. +* :zephyr:code-sample:`zperf ` sample application fixes. * :ref:`LLDP ` (Link Layer Discovery Protocol) enhancements. * ARP cache update fix. * gPTP link delay calculation fixes. diff --git a/doc/releases/release-notes-3.4.rst b/doc/releases/release-notes-3.4.rst index 0fb4efbe40f..092fa251c6f 100644 --- a/doc/releases/release-notes-3.4.rst +++ b/doc/releases/release-notes-3.4.rst @@ -1143,7 +1143,7 @@ Networking which allow to disable ND/MLD respectively on an interface. * Reworked network interface mutex protection, to use individual mutex for each interface, instead of a global one. - * Added new :ref:`aws-iot-mqtt-sample`. + * Added new :zephyr:code-sample:`aws-iot-mqtt`. * Added a few missing NULL pointer checks in network interface functions. * OpenThread: diff --git a/doc/services/device_mgmt/ota.rst b/doc/services/device_mgmt/ota.rst index 737b957c082..8f400582740 100644 --- a/doc/services/device_mgmt/ota.rst +++ b/doc/services/device_mgmt/ota.rst @@ -74,7 +74,7 @@ Lightweight M2M (LWM2M) The :ref:`lwm2m_interface` protocol includes support for firmware update via :kconfig:option:`CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT`. Devices securely -connect to an LwM2M server using DTLS. An :ref:`lwm2m-client-sample` sample is +connect to an LwM2M server using DTLS. A :zephyr:code-sample:`lwm2m-client` sample is available but it does not demonstrate the firmware update feature. .. _MCUboot bootloader: https://mcuboot.com/ diff --git a/samples/net/capture/README.rst b/samples/net/capture/README.rst index 87259408582..c6846e5d552 100644 --- a/samples/net/capture/README.rst +++ b/samples/net/capture/README.rst @@ -1,13 +1,16 @@ -.. _net-capture-sample: +.. zephyr:code-sample:: net-capture + :name: Network packet capture + :relevant-api: net_capture -Network Packet Capture -###################### + Capture network packets and send them to a remote host via IPIP tunnel. Overview ******** This application will setup the device so that net-shell can be used -to enable network packet capture. The captured packets are sent to +to enable network packet capture. + +The captured packets are sent to remote host via IPIP tunnel. The tunnel can be configured to be in the same connection as what we are capturing packets or it can be a separate bearer. For example if you are capturing network traffic for interface 1, diff --git a/samples/net/cellular_modem/README.rst b/samples/net/cellular_modem/README.rst index 7c30a850705..384d8b3bef5 100644 --- a/samples/net/cellular_modem/README.rst +++ b/samples/net/cellular_modem/README.rst @@ -1,7 +1,7 @@ -.. _cellular_modem_sample: +.. zephyr:code-sample:: cellular-modem + :name: Cellular modem -Cellular Modem Sample -######################## + Use a cellular modem to communicate with a UDP server. Overview ******** diff --git a/samples/net/cloud/aws_iot_mqtt/README.rst b/samples/net/cloud/aws_iot_mqtt/README.rst index 0f0d08234d2..8ad0d1f9738 100644 --- a/samples/net/cloud/aws_iot_mqtt/README.rst +++ b/samples/net/cloud/aws_iot_mqtt/README.rst @@ -1,7 +1,8 @@ -.. _aws-iot-mqtt-sample: +.. zephyr:code-sample:: aws-iot-mqtt + :name: AWS IoT Core MQTT + :relevant-api: bsd_sockets mqtt_socket dns_resolve tls_credentials json sntp random_api -AWS IoT Core MQTT Sample -######################## + Connect to AWS IoT Core and publish messages using MQTT. Overview ******** diff --git a/samples/net/cloud/mqtt_azure/README.rst b/samples/net/cloud/mqtt_azure/README.rst index a1414b8df43..1369b83d0e5 100644 --- a/samples/net/cloud/mqtt_azure/README.rst +++ b/samples/net/cloud/mqtt_azure/README.rst @@ -1,7 +1,8 @@ -.. _mqtt-azure-sample: +.. zephyr:code-sample:: mqtt-azure + :name: Microsoft Azure IoT Hub MQTT + :relevant-api: bsd_sockets mqtt_socket tls_credentials random_api -MQTT Azure Sample -################# + Connect to Azure IoT Hub and publish messages using MQTT. Overview ******** diff --git a/samples/net/cloud/tagoio_http_post/README.rst b/samples/net/cloud/tagoio_http_post/README.rst index 235a35265e4..dc0f2b9da6c 100644 --- a/samples/net/cloud/tagoio_http_post/README.rst +++ b/samples/net/cloud/tagoio_http_post/README.rst @@ -1,7 +1,8 @@ -.. _cloud-tagoio-http-post-sample: +.. zephyr:code-sample:: tagoio-http-post + :name: TagoIO HTTP Post + :relevant-api: bsd_sockets http_client dns_resolve tls_credentials -TagoIO IoT Cloud HTTP Sample -############################ + Send random temperature values to TagoIO IoT Cloud Platform using HTTP. Overview ******** diff --git a/samples/net/dhcpv4_client/README.rst b/samples/net/dhcpv4_client/README.rst index 60e985eb0a9..e8c232a7e94 100644 --- a/samples/net/dhcpv4_client/README.rst +++ b/samples/net/dhcpv4_client/README.rst @@ -1,7 +1,8 @@ -.. _dhcpv4-client-sample: +.. zephyr:code-sample:: dhcpv4-client + :name: DHCPv4 client + :relevant-api: dhcpv4 net_mgmt -Sample DHCPv4 client application -################################ + Start a DHCPv4 client to obtain an IPv4 address from a DHCPv4 server. Overview ******** diff --git a/samples/net/dns_resolve/README.rst b/samples/net/dns_resolve/README.rst index 28cfabdf013..ac2ea0f391b 100644 --- a/samples/net/dns_resolve/README.rst +++ b/samples/net/dns_resolve/README.rst @@ -1,7 +1,8 @@ -.. _dns-resolve-sample: +.. zephyr:code-sample:: dns-resolve + :name: DNS resolve + :relevant-api: dns_resolve net_mgmt -DNS Resolve Application -####################### + Resolve an IP address for a given hostname. Overview ******** diff --git a/samples/net/dsa/README.rst b/samples/net/dsa/README.rst index 588adf28db1..729aac7785e 100644 --- a/samples/net/dsa/README.rst +++ b/samples/net/dsa/README.rst @@ -1,7 +1,8 @@ -.. _dsa-sample: +.. zephyr:code-sample:: dsa + :name: DSA (Distributed Switch Architecture) + :relevant-api: DSA -DSA Sample Application -###################### + Test and debug Distributed Switch Architecture Overview ******** diff --git a/samples/net/eth_native_posix/README.rst b/samples/net/eth_native_posix/README.rst index 2ec9c55c52d..7d7232acd5c 100644 --- a/samples/net/eth_native_posix/README.rst +++ b/samples/net/eth_native_posix/README.rst @@ -1,7 +1,8 @@ -.. _eth-native-posix-sample: +.. zephyr:code-sample:: eth-native-posix + :name: Native POSIX Ethernet + :relevant-api: net_core ethernet -Native Posix Ethernet -##################### + Create a network interface to the host system. Overview ******** diff --git a/samples/net/gptp/README.rst b/samples/net/gptp/README.rst index 4b7f6a100fc..a2c8696d95a 100644 --- a/samples/net/gptp/README.rst +++ b/samples/net/gptp/README.rst @@ -1,7 +1,8 @@ -.. _gptp-sample: +.. zephyr:code-sample:: gptp + :name: gPTP + :relevant-api: gptp ptp_time -gPTP Sample Application -####################### + Enable gPTP support and monitor functionality using net-shell. Overview ******** diff --git a/samples/net/gsm_modem/README.rst b/samples/net/gsm_modem/README.rst index aebfc2ab3a5..2021b0e0554 100644 --- a/samples/net/gsm_modem/README.rst +++ b/samples/net/gsm_modem/README.rst @@ -1,7 +1,7 @@ -.. _gsm-modem-sample: +.. zephyr:code-sample:: gsm-modem + :name: Generic GSM modem -Generic GSM Modem Sample -######################## + Use a GSM modem to connect to a GPRS network. Overview ******** diff --git a/samples/net/ipv4_autoconf/README.rst b/samples/net/ipv4_autoconf/README.rst index 1ee783cbe41..614f2c64047 100644 --- a/samples/net/ipv4_autoconf/README.rst +++ b/samples/net/ipv4_autoconf/README.rst @@ -1,7 +1,8 @@ -.. _ipv4-autoconf-sample: +.. zephyr:code-sample:: ipv4-autoconf + :name: IPv4 autoconf client + :relevant-api: networking net_if net_context net_mgmt -IPv4 autoconf client application -################################ + Perform IPv4 autoconfiguration and self-assign a random IPv4 address Overview ******** diff --git a/samples/net/lldp/README.rst b/samples/net/lldp/README.rst index 856c4342910..ba392d8be94 100644 --- a/samples/net/lldp/README.rst +++ b/samples/net/lldp/README.rst @@ -1,7 +1,8 @@ -.. _lldp-sample: +.. zephyr:code-sample:: lldp + :name: Link Layer Discovery Protocol (LLDP) + :relevant-api: lldp net_l2 -LLDP Sample Application -####################### + Enable LLDP support and setup VLANs. Overview ******** diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index c05a1149d31..4e231ba0051 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -1,7 +1,8 @@ -.. _lwm2m-client-sample: +.. zephyr:code-sample:: lwm2m-client + :name: LwM2M client + :relevant-api: lwm2m_api -LwM2M client -############ + Implement a LwM2M client that connects to a LwM2M server. Overview ******** diff --git a/samples/net/mdns_responder/README.rst b/samples/net/mdns_responder/README.rst index 8b9d93299a4..015f6c8b444 100644 --- a/samples/net/mdns_responder/README.rst +++ b/samples/net/mdns_responder/README.rst @@ -1,7 +1,8 @@ -.. _mdns-responder-sample: +.. zephyr:code-sample:: mdns-responder + :name: mDNS responder + :relevant-api: net_core dns_sd bsd_sockets -mDNS Responder Application -########################## + Listen and respond to mDNS queries. Overview ******** diff --git a/samples/net/mqtt_publisher/README.rst b/samples/net/mqtt_publisher/README.rst index 04ff4c47bfd..2c22394036b 100644 --- a/samples/net/mqtt_publisher/README.rst +++ b/samples/net/mqtt_publisher/README.rst @@ -1,7 +1,8 @@ -.. _mqtt-publisher-sample: +.. zephyr:code-sample:: mqtt-publisher + :name: MQTT publisher + :relevant-api: mqtt_socket -MQTT Publisher -############## + Send MQTT PUBLISH messages to an MQTT server. Overview ******** diff --git a/samples/net/mqtt_sn_publisher/README.rst b/samples/net/mqtt_sn_publisher/README.rst index 57e82f30594..e7831487650 100644 --- a/samples/net/mqtt_sn_publisher/README.rst +++ b/samples/net/mqtt_sn_publisher/README.rst @@ -1,7 +1,8 @@ -.. _mqtt-sn-publisher-sample: +.. zephyr:code-sample:: mqtt-sn-publisher + :name: MQTT-SN publisher + :relevant-api: mqtt_sn_socket -MQTT-SN Publisher -################# + Send MQTT-SN PUBLISH messages to an MQTT-SN gateway. Overview ******** @@ -16,8 +17,8 @@ requires a reliable TCP/IP transport, MQTT-SN is designed to be usable on any datagram-based transport like UDP, ZigBee or even a plain UART (with an additional framing protocol). -The Zephyr MQTT-SN Publisher sample application is a MQTT-SN v1.2 -client that sends MQTT-SN PUBLISH messages to a MQTT-SN gateway. +The Zephyr MQTT-SN Publisher sample application is an MQTT-SN v1.2 +client that sends MQTT-SN PUBLISH messages to an MQTT-SN gateway. It also SUBSCRIBEs to a topic. See the `MQTT-SN v1.2 spec`_ for more information. @@ -43,7 +44,7 @@ Currently, this sample application only supports static IP addresses. Open the :file:`prj.conf` file and set the IP addresses according to the LAN environment. -You will also need to start a MQTT-SN gateway. With paho, you can either +You will also need to start an MQTT-SN gateway. With Paho, you can either build it from source - see `PAHO MQTT-SN Gateway`_ - or run an unofficial docker image, like `kyberpunk/paho`_. diff --git a/samples/net/openthread/coprocessor/README.rst b/samples/net/openthread/coprocessor/README.rst index ee76942c3fc..9ba9fc62f0d 100644 --- a/samples/net/openthread/coprocessor/README.rst +++ b/samples/net/openthread/coprocessor/README.rst @@ -1,7 +1,8 @@ -.. _coprocessor-sample: +.. zephyr:code-sample:: coprocessor + :name: OpenThread co-processor + :relevant-api: openthread -OpenThread Co-Processor -####################### + Build a Thread border-router using OpenThread's co-processor designs. Overview ******** diff --git a/samples/net/promiscuous_mode/README.rst b/samples/net/promiscuous_mode/README.rst index 44e5bdd27c0..3587deb8d9c 100644 --- a/samples/net/promiscuous_mode/README.rst +++ b/samples/net/promiscuous_mode/README.rst @@ -1,7 +1,8 @@ -.. _net-promiscuous-mode-sample: +.. zephyr:code-sample:: net-promiscuous-mode + :name: Promiscuous mode + :relevant-api: promiscuous -Promiscuous Mode Sample Application -################################### + Enable promiscuous mode on all interfaces and print information about incoming packets. Overview ******** diff --git a/samples/net/sockets/big_http_download/README.rst b/samples/net/sockets/big_http_download/README.rst index 0cefa732063..222af88d573 100644 --- a/samples/net/sockets/big_http_download/README.rst +++ b/samples/net/sockets/big_http_download/README.rst @@ -1,14 +1,15 @@ -.. _sockets-big-http-download: +.. zephyr:code-sample:: sockets-big-http-download + :name: Large HTTP download + :relevant-api: bsd_sockets tls_credentials -Socket Big HTTP Download Example -################################ + Download a large file from a web server using BSD sockets. Overview ******** The sockets/big_http_download sample application for Zephyr implements a simple HTTP GET client using a BSD Sockets compatible API. Unlike -the :ref:`sockets-http-get` sample application, it downloads a file of +the :zephyr:code-sample:`sockets-http-get` sample application, it downloads a file of several megabytes in size, and verifies its integrity using hashing. It also performs download repeatedly, tracking the total number of bytes transferred. Thus, it can serve as a "load testing" application for diff --git a/samples/net/sockets/can/README.rst b/samples/net/sockets/can/README.rst index 5239985c260..800665a8523 100644 --- a/samples/net/sockets/can/README.rst +++ b/samples/net/sockets/can/README.rst @@ -1,7 +1,8 @@ -.. _socket-can-sample: +.. zephyr:code-sample:: socket-can + :name: SocketCAN + :relevant-api: bsd_sockets socket_can -Socket CAN -########## + Send and receive raw CAN frames using BSD sockets API. Overview ******** diff --git a/samples/net/sockets/coap_client/README.rst b/samples/net/sockets/coap_client/README.rst index fedea647b3c..a26d632772b 100644 --- a/samples/net/sockets/coap_client/README.rst +++ b/samples/net/sockets/coap_client/README.rst @@ -1,7 +1,8 @@ -.. _coap-client-sample: +.. zephyr:code-sample:: coap-client + :name: CoAP client + :relevant-api: coap udp -CoAP client -########### + Use the CoAP library to implement a client that fetches a resource. Overview ******** diff --git a/samples/net/sockets/coap_server/README.rst b/samples/net/sockets/coap_server/README.rst index 5159c66b989..57e4a818809 100644 --- a/samples/net/sockets/coap_server/README.rst +++ b/samples/net/sockets/coap_server/README.rst @@ -1,7 +1,8 @@ -.. _coap-server-sample: +.. zephyr:code-sample:: coap-server + :name: CoAP server + :relevant-api: coap udp -CoAP Server -########### + Use the CoAP library to implement a server that exposes CoAP resources. Overview ******** diff --git a/samples/net/sockets/dumb_http_server/README.rst b/samples/net/sockets/dumb_http_server/README.rst index f578d877bd1..56e6ac281e4 100644 --- a/samples/net/sockets/dumb_http_server/README.rst +++ b/samples/net/sockets/dumb_http_server/README.rst @@ -1,7 +1,8 @@ -.. _sockets-dumb-http-server-sample: +.. zephyr:code-sample:: socket-dumb-http-server + :name: Dumb HTTP server + :relevant-api: bsd_sockets net_pkt -Socket Dumb HTTP Server -####################### + Implement a simple, portable, HTTP server using BSD sockets. Overview ******** diff --git a/samples/net/sockets/dumb_http_server_mt/README.rst b/samples/net/sockets/dumb_http_server_mt/README.rst index e999f8229cf..76e55cbbc0f 100644 --- a/samples/net/sockets/dumb_http_server_mt/README.rst +++ b/samples/net/sockets/dumb_http_server_mt/README.rst @@ -1,14 +1,15 @@ -.. _sockets-dumb-http-server-mt-sample: +.. zephyr:code-sample:: socket-dumb-http-server-mt + :name: Dumb HTTP server (multi-threaded) + :relevant-api: bsd_sockets net_pkt thread_apis tls_credentials -Socket Multithreaded Dumb HTTP Server -##################################### + Implement a simple HTTP server supporting simultaneous connections using BSD sockets. Overview ******** The ``sockets/dumb_http_server_mt`` sample application for Zephyr implements a skeleton HTTP server using a BSD Sockets compatible API. -This sample has similar functionality as :ref:`sockets-dumb-http-server-sample` +This sample has similar functionality as :zephyr:code-sample:`socket-dumb-http-server` except it has support for multiple simultaneous connections, TLS and IPv6. Also this sample application has no compatibility with POSIX. This HTTP server example is very minimal and does not really parse an incoming diff --git a/samples/net/sockets/echo/README.rst b/samples/net/sockets/echo/README.rst index 0d91e0ac3e7..68edc84c46f 100644 --- a/samples/net/sockets/echo/README.rst +++ b/samples/net/sockets/echo/README.rst @@ -1,7 +1,8 @@ -.. _sockets-echo-sample: +.. zephyr:code-sample:: socket-echo + :name: Echo server (simple) + :relevant-api: bsd_sockets -Socket Echo Server -################## + Implements a simple IPv4 TCP echo server using BSD sockets. Overview ******** diff --git a/samples/net/sockets/echo_async/README.rst b/samples/net/sockets/echo_async/README.rst index e17953b506c..0499973fc2e 100644 --- a/samples/net/sockets/echo_async/README.rst +++ b/samples/net/sockets/echo_async/README.rst @@ -1,7 +1,8 @@ -.. _async-sockets-echo-sample: +.. zephyr:code-sample:: async-sockets-echo + :name: Asynchronous echo server using poll() + :relevant-api: bsd_sockets -Asynchronous Socket Echo Server -############################### + Implement an asynchronous IPv4/IPv6 TCP echo server using BSD sockets and poll() Overview ******** @@ -9,7 +10,7 @@ Overview The sockets/echo-async sample application for Zephyr implements an asynchronous IPv4/IPv6 TCP echo server using a BSD Sockets compatible API with non-blocking sockets and a ``poll()`` call. This is an extension of -the :ref:`sockets-echo-sample` sample. It's a more involved application, +the :zephyr:code-sample:`sockets-echo` sample. It's a more involved application, supporting both IPv4 and IPv6 with concurrent connections, limiting maximum number of simultaneous connections, and basic error handling. @@ -42,7 +43,7 @@ After the sample starts, it expects connections at 192.0.2.1 (IPv4), or $ telnet 2001:db8::1 4242 # or this for IPv6 After a connection is made, the application will echo back any line sent to -it. Unlike the above-mentioned :ref:`sockets-echo-sample`, this application +it. Unlike the above-mentioned :zephyr:code-sample:`sockets-echo` sample, this application supports multiple concurrent client connections. You can open another terminal window and run the same telnet command as above. The sample supports up to three connected clients, but this can be adjusted diff --git a/samples/net/sockets/echo_async_select/README.rst b/samples/net/sockets/echo_async_select/README.rst index af30527727d..cc2b48735d8 100644 --- a/samples/net/sockets/echo_async_select/README.rst +++ b/samples/net/sockets/echo_async_select/README.rst @@ -1,7 +1,8 @@ -.. _async-sockets-echo-select-sample: +.. zephyr:code-sample:: async-sockets-echo-select + :name: Asynchronous echo server using select() + :relevant-api: bsd_sockets -Asynchronous Socket Echo Server Using select() -############################################## + Implement an asynchronous IPv4/IPv6 TCP echo server using BSD sockets and select() Overview ******** @@ -9,7 +10,7 @@ Overview The sockets/echo_async_select sample application for Zephyr implements an asynchronous IPv4/IPv6 TCP echo server using a BSD Sockets compatible API with non-blocking sockets and a ``select()`` call. This is a variant of -the :ref:`async-sockets-echo-sample` sample. +the :zephyr:code-sample:`async-sockets-echo` sample. The source code for this sample application can be found at: :zephyr_file:`samples/net/sockets/echo_async_select`. @@ -40,7 +41,7 @@ After the sample starts, it expects connections at 192.0.2.1 (IPv4), or $ telnet 2001:db8::1 4242 # or this for IPv6 After a connection is made, the application will echo back any line sent to -it. Unlike the :ref:`sockets-echo-sample`, this application +it. Unlike the :zephyr:code-sample:`sockets-echo` sample, this application supports multiple concurrent client connections. You can open another terminal window and run the same telnet command as above. The sample supports up to three connected clients, but this can be adjusted diff --git a/samples/net/sockets/echo_client/README.rst b/samples/net/sockets/echo_client/README.rst index 31d03d18202..ce9ccf2532b 100644 --- a/samples/net/sockets/echo_client/README.rst +++ b/samples/net/sockets/echo_client/README.rst @@ -1,7 +1,8 @@ -.. _sockets-echo-client-sample: +.. zephyr:code-sample:: sockets-echo-client + :name: Echo client (advanced) + :relevant-api: bsd_sockets tls_credentials -Socket Echo Client -################## + Implement a client that sends IP packets, waits for data to be sent back, and verifies it. Overview ******** @@ -105,7 +106,7 @@ running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's ``src`` directory. The default certificates used by Socket Echo Client and -:ref:`sockets-echo-server-sample` enable establishing a secure connection +:zephyr:code-sample:`sockets-echo-server` enable establishing a secure connection between the samples. SOCKS5 proxy support @@ -178,6 +179,6 @@ You can verify TLS communication with a Linux host as well. See https://github.com/zephyrproject-rtos/net-tools documentation for information on how to test TLS with Linux host samples. -See the :ref:`sockets-echo-server-sample` documentation for an alternate +See the :zephyr:code-sample:`sockets-echo-server` documentation for an alternate way of running, with the echo-client on the Linux host and the echo-server in QEMU. diff --git a/samples/net/sockets/echo_server/README.rst b/samples/net/sockets/echo_server/README.rst index fed7ef00a41..20ce37e7991 100644 --- a/samples/net/sockets/echo_server/README.rst +++ b/samples/net/sockets/echo_server/README.rst @@ -1,7 +1,8 @@ -.. _sockets-echo-server-sample: +.. zephyr:code-sample:: sockets-echo-server + :name: Echo server (advanced) + :relevant-api: bsd_sockets tls_credentials -Socket Echo Server -################## + Implement a UDP/TCP server that sends received packets back to the sender. Overview ******** @@ -107,7 +108,7 @@ running ``west build`` or ``cmake``. The certificate used by the sample can be found in the sample's ``src`` directory. The default certificates used by Socket Echo Server and -:ref:`sockets-echo-client-sample` enable establishing a secure connection +:zephyr:code-sample:`sockets-echo-client` enable establishing a secure connection between the samples. Running echo-client in Linux Host @@ -140,6 +141,6 @@ You can verify TLS communication with a Linux host as well. See https://github.com/zephyrproject-rtos/net-tools documentation for information on how to test TLS with Linux host samples. -See the :ref:`sockets-echo-client-sample` documentation for an alternate +See the :zephyr:code-sample:`sockets-echo-client` sample documentation for an alternate way of running, with the echo-server on the Linux host and the echo-client in QEMU. diff --git a/samples/net/sockets/http_client/README.rst b/samples/net/sockets/http_client/README.rst index 1d37121ad56..855c36d068a 100644 --- a/samples/net/sockets/http_client/README.rst +++ b/samples/net/sockets/http_client/README.rst @@ -1,7 +1,8 @@ -.. _sockets-http-client-sample: +.. zephyr:code-sample:: sockets-http-client + :name: HTTP client + :relevant-api: bsd_sockets http_client tls_credentials secure_sockets_options -Socket HTTP Client -################## + Implement an HTTP(S) client that issues a variety of HTTP requests. Overview ******** diff --git a/samples/net/sockets/http_get/README.rst b/samples/net/sockets/http_get/README.rst index bd4a6824d7f..790b9756f31 100644 --- a/samples/net/sockets/http_get/README.rst +++ b/samples/net/sockets/http_get/README.rst @@ -1,7 +1,8 @@ -.. _sockets-http-get: +.. zephyr:code-sample:: sockets-http-get + :name: HTTP GET using plain sockets + :relevant-api: bsd_sockets tls_credentials secure_sockets_options -Socket HTTP GET Example -####################### + Implement an HTTP(S) client using plain BSD sockets. Overview ******** diff --git a/samples/net/sockets/net_mgmt/README.rst b/samples/net/sockets/net_mgmt/README.rst index 4fade75c725..92d6d8524c7 100644 --- a/samples/net/sockets/net_mgmt/README.rst +++ b/samples/net/sockets/net_mgmt/README.rst @@ -1,7 +1,8 @@ -.. _sockets-net-mgmt-sample: +.. zephyr:code-sample:: sockets-net-mgmt + :name: Network management socket + :relevant-api: bsd_sockets net_if -Network Management Socket -######################### + Listen to network management events using a network management socket. Overview ******** diff --git a/samples/net/sockets/packet/README.rst b/samples/net/sockets/packet/README.rst index fe6ce34c7cd..ea096be0a23 100644 --- a/samples/net/sockets/packet/README.rst +++ b/samples/net/sockets/packet/README.rst @@ -1,7 +1,8 @@ -.. _packet-socket-sample: +.. zephyr:code-sample:: packet-socket + :name: Packet socket + :relevant-api: bsd_sockets ethernet -Packet socket sample -#################### + Use raw packet sockets over Ethernet. Overview ******** diff --git a/samples/net/sockets/sntp_client/README.rst b/samples/net/sockets/sntp_client/README.rst index 9515ca3158c..1e061c36a70 100644 --- a/samples/net/sockets/sntp_client/README.rst +++ b/samples/net/sockets/sntp_client/README.rst @@ -1,7 +1,8 @@ -.. _sntp-client-sample: +.. zephyr:code-sample:: sntp-client + :name: SNTP client + :relevant-api: bsd_sockets sntp -SNTP client sample -################## + Use SNTP to get the current time from the host. Overview ******** diff --git a/samples/net/sockets/socketpair/README.rst b/samples/net/sockets/socketpair/README.rst index 7372d1293f0..3dce3caea7e 100644 --- a/samples/net/sockets/socketpair/README.rst +++ b/samples/net/sockets/socketpair/README.rst @@ -1,7 +1,8 @@ -.. _sockets-socketpair-sample: +.. zephyr:code-sample:: sockets-socketpair + :name: Socketpair + :relevant-api: bsd_sockets -Socketpair Example -################## + Implement communication between threads using socket pairs. Overview ******** diff --git a/samples/net/sockets/tcp/README.rst b/samples/net/sockets/tcp/README.rst index 5f43d02d41f..c0540cca147 100644 --- a/samples/net/sockets/tcp/README.rst +++ b/samples/net/sockets/tcp/README.rst @@ -1,7 +1,8 @@ -.. _sockets-tcp-sample: +.. zephyr:code-sample:: sockets-tcp-sample + :name: TCP sample for TTCN-3 based sanity check + :relevant-api: bsd_sockets -TCP Sample for TTCN-3 based Sanity Check -######################################## + Use TTCN-3 to validate the functionality of the TCP stack. Overview ******** diff --git a/samples/net/sockets/txtime/README.rst b/samples/net/sockets/txtime/README.rst index 67909d609c8..46979ce68bb 100644 --- a/samples/net/sockets/txtime/README.rst +++ b/samples/net/sockets/txtime/README.rst @@ -1,7 +1,8 @@ -.. _so_txtime-sample: +.. zephyr:code-sample:: so_txtime + :name: UDP sender using SO_TXTIME + :relevant-api: bsd_sockets ethernet -SO_TXTIME sample -################ + Control the transmission time of a packet using SO_TXTIME socket option. Overview ******** @@ -14,9 +15,9 @@ provided for qemu_x86 board. Also frdm_k64f and sam_e70_xplained boards are supported. Other mcux or gmac Ethernet driver based boards should work too. User can control how long the application should wait between packets sent by -setting CONFIG_NET_SAMPLE_PACKET_INTERVAL option. +setting :kconfig:option:`CONFIG_NET_SAMPLE_PACKET_INTERVAL` option. Also the TXTIME value can be specified in the config file by setting the -CONFIG_NET_SAMPLE_PACKET_TXTIME option. In this case the value is +:kconfig:option:`CONFIG_NET_SAMPLE_PACKET_TXTIME` option. In this case the value is used as an offset from the current time. Building and Running @@ -25,8 +26,8 @@ Building and Running When the application is run, it starts to send UDP packets. You can start ``echo-server`` application from `net-tools`_ project to catch these and send the data back to this application. Optionally you can set -CONFIG_NET_SAMPLE_PACKET_SOCKET option, which makes the application -to create an AF_PACKET type socket. In this case, the ``echo-server`` +:kconfig:option:`CONFIG_NET_SAMPLE_PACKET_SOCKET` option, which makes the application +to create an ``AF_PACKET`` type socket. In this case, the ``echo-server`` application cannot be used as a peer. This sample can be built and executed on qemu_x86 board as diff --git a/samples/net/sockets/websocket_client/README.rst b/samples/net/sockets/websocket_client/README.rst index d6ae83b568f..b8cf079683f 100644 --- a/samples/net/sockets/websocket_client/README.rst +++ b/samples/net/sockets/websocket_client/README.rst @@ -1,7 +1,8 @@ -.. _sockets-websocket-client-sample: +.. zephyr:code-sample:: sockets-websocket-client + :name: WebSocket Client + :relevant-api: bsd_sockets websocket -Socket Websocket Client -####################### + Implement a Websocket client that connects to a Websocket server. Overview ******** diff --git a/samples/net/stats/README.rst b/samples/net/stats/README.rst index e7d4ac6d911..84204d46131 100644 --- a/samples/net/stats/README.rst +++ b/samples/net/stats/README.rst @@ -1,7 +1,8 @@ -.. _net_stats-sample: +.. zephyr:code-sample:: net-stats + :name: Network statistics + :relevant-api: net_stats -Network Statistics Sample Application -##################################### + Query and display network statistics from a user application. Overview ******** diff --git a/samples/net/syslog_net/README.rst b/samples/net/syslog_net/README.rst index 04440b34f77..6e4247a5828 100644 --- a/samples/net/syslog_net/README.rst +++ b/samples/net/syslog_net/README.rst @@ -1,7 +1,8 @@ -.. _syslog-net-sample: +.. zephyr:code-sample:: syslog-net + :name: Remote syslog + :relevant-api: log_backend log_ctrl -Syslog net Application -###################### + Enable a remote syslog service that sends syslog messages to a remote server Overview ******** diff --git a/samples/net/telnet/README.rst b/samples/net/telnet/README.rst index ee77c9b1402..1c648e2e970 100644 --- a/samples/net/telnet/README.rst +++ b/samples/net/telnet/README.rst @@ -1,7 +1,8 @@ -.. _telnet-console-sample: +.. zephyr:code-sample:: telnet-console + :name: Telnet console + :relevant-api: shell_api net_core net_if net_mgmt -Sample TELNET console application -################################# + Access Zephyr shell over telnet. Overview ******** diff --git a/samples/net/tftp_client/README.rst b/samples/net/tftp_client/README.rst index ac7181f4605..40da21adcf6 100644 --- a/samples/net/tftp_client/README.rst +++ b/samples/net/tftp_client/README.rst @@ -1,7 +1,8 @@ -.. _tftp-client-sample: +.. zephyr:code-sample:: tftp-client + :name: TFTP client + :relevant-api: tftp_client -TFTP client -############ + Use the TFTP client library to get/put files from/to a TFTP server. Overview ******** diff --git a/samples/net/virtual/README.rst b/samples/net/virtual/README.rst index 6869d21e1a4..8b83fc9e0e7 100644 --- a/samples/net/virtual/README.rst +++ b/samples/net/virtual/README.rst @@ -1,7 +1,8 @@ -.. _virtual_network_interface-sample: +.. zephyr:code-sample:: virtual-network-interface + :name: Virtual network interface + :relevant-api: virtual virtual_mgmt -Virtual Network Interface Application -##################################### + Create a sample virtual network interface. Overview ******** @@ -9,11 +10,14 @@ Overview This sample application creates a sample virtual network interface for demonstrative purposes, it does not do anything useful here. There are total 4 network interfaces. + Ethernet network interface is providing the real network interface and all the virtual interfaces are running on top of it. + On top of Ethernet interface there are two virtual network interfaces, one provides only IPv6 tunnel, and the other only IPv4. These two tunnels are provided by IPIP tunnel. + The sample provides tunnel interface which runs on top of the IPv6 tunnel. The source code for this sample application can be found at: diff --git a/samples/net/vlan/README.rst b/samples/net/vlan/README.rst index 3cd2c812bff..346dc07a6c3 100644 --- a/samples/net/vlan/README.rst +++ b/samples/net/vlan/README.rst @@ -1,7 +1,8 @@ -.. _vlan-sample: +.. zephyr:code-sample:: vlan + :name: Virtual LAN + :relevant-api: vlan_api net_l2 net_if -Virtual LAN Sample Application -############################## + Setup two virtual LAN networks and use net-shell to view the networks' settings. Overview ******** diff --git a/samples/net/wifi/README.rst b/samples/net/wifi/README.rst index 8638e48103e..81aaa61a729 100644 --- a/samples/net/wifi/README.rst +++ b/samples/net/wifi/README.rst @@ -1,7 +1,8 @@ -.. _wifi_sample: +.. zephyr:code-sample:: wifi-shell + :name: Wi-Fi shell + :relevant-api: net_stats -Wi-Fi sample -############ + Test Wi-Fi functionality using the Wi-Fi shell module. Overview ******** diff --git a/samples/net/wpan_serial/README.rst b/samples/net/wpan_serial/README.rst index 669c574117d..3bcf5dbb4d4 100644 --- a/samples/net/wpan_serial/README.rst +++ b/samples/net/wpan_serial/README.rst @@ -1,7 +1,8 @@ -.. _wpan_serial-sample: +.. zephyr:code-sample:: wpan-serial + :name: 802.15.4 "serial-radio" + :relevant-api: ieee802154 uart_interface -802.15.4 "serial-radio" sample -############################## + Implement a slip-radio device for Contiki-based border routers. Overview ******** diff --git a/samples/net/wpanusb/README.rst b/samples/net/wpanusb/README.rst index e6e87502a66..aa4b6e38e14 100644 --- a/samples/net/wpanusb/README.rst +++ b/samples/net/wpanusb/README.rst @@ -1,7 +1,8 @@ -.. _wpanusb-sample: +.. zephyr:code-sample:: _wpanusb + :name: 802.15.4 USB + :relevant-api: ieee802154 _usb_device_core_api -wpanusb sample -############## + Implement a device that exposes an IEEE 802.15.4 radio over USB. Overview ******** diff --git a/samples/net/zperf/README.rst b/samples/net/zperf/README.rst index ded271b9a43..949acba5e76 100644 --- a/samples/net/zperf/README.rst +++ b/samples/net/zperf/README.rst @@ -1,7 +1,8 @@ -.. _zperf-sample: +.. zephyr:code-sample:: zperf + :name: zperf: Network Traffic Generator + :relevant-api: net_config -zperf: Network Traffic Generator -################################ + Use the zperf shell utility to evaluate network bandwidth. Description *********** diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index 0324ab97025..aea33944193 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -203,7 +203,7 @@ Step 4.3: Build for Modem Modem needs add ``overlay-modem.conf``. Now, a DTC overlay file is used to configure the glue between the modem and an arduino headers. The modem config -uses PPP over GSM modem, see :ref:`gsm-modem-sample`. +uses PPP over GSM modem, see :zephyr:code-sample:`gsm-modem-sample` sample application. .. zephyr-app-commands:: :zephyr-app: zephyr/samples/subsys/mgmt/updatehub @@ -220,7 +220,7 @@ Step 4.4: Build for IEEE 802.15.4 [experimental] For IEEE 802.15.4 needs add ``overlay-802154.conf``. This requires two nodes: one will be the host and the second one will be the device under test. The validation needs a Linux kernel >= 4.9 with all 6loWPAN support. The start -point is try reproduce the Zephyr :ref:`wpanusb-sample`. It is out of scope +point is try reproduce the Zephyr :zephyr:code-sample:`wpan-usb`. It is out of scope at this moment provide support since it is experimental. The gateway was tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. From 9d62bef3ac4510c7a2ed4f65104b3de6e737d940 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 11:29:44 +0200 Subject: [PATCH 0663/4498] Bluetooth: BAP: Broadcast source state checks for ID and BASE Add state checks for the get_id and get_base functions, as the ID and base are not valid when the state of the broadcast source is BT_BAP_EP_STATE_IDLE. Since the broadcast_source_get_state uses the slist functions, the broadcast source object for bt_bap_broadcast_source_get_id can no longer be `const`. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/bap.h | 2 +- subsys/bluetooth/audio/bap_broadcast_source.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 269e37d5aba..3068a86ed24 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1536,7 +1536,7 @@ int bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source *source); * * @return Zero on success or (negative) error code otherwise. */ -int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, +int bt_bap_broadcast_source_get_id(struct bt_bap_broadcast_source *source, uint32_t *const broadcast_id); /** diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 4fa436e8e32..8354fcae18b 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -956,9 +956,11 @@ int bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source *source) return 0; } -int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, +int bt_bap_broadcast_source_get_id(struct bt_bap_broadcast_source *source, uint32_t *const broadcast_id) { + enum bt_bap_ep_state broadcast_state; + CHECKIF(source == NULL) { LOG_DBG("source is NULL"); return -EINVAL; @@ -969,6 +971,12 @@ int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, return -EINVAL; } + broadcast_state = broadcast_source_get_state(source); + if (broadcast_state == BT_BAP_EP_STATE_IDLE) { + LOG_DBG("Broadcast source invalid state: %u", broadcast_state); + return -EBADMSG; + } + *broadcast_id = source->broadcast_id; return 0; @@ -977,6 +985,8 @@ int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *base_buf) { + enum bt_bap_ep_state broadcast_state; + CHECKIF(source == NULL) { LOG_DBG("source is NULL"); return -EINVAL; @@ -987,6 +997,12 @@ int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source, return -EINVAL; } + broadcast_state = broadcast_source_get_state(source); + if (broadcast_state == BT_BAP_EP_STATE_IDLE) { + LOG_DBG("Broadcast source invalid state: %u", broadcast_state); + return -EBADMSG; + } + if (!encode_base(source, base_buf)) { LOG_DBG("base_buf %p with size %u not large enough", base_buf, base_buf->size); From f49309cf52eb97b2f6556ad044c725c595aed2e5 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 11 Sep 2023 15:23:53 +0300 Subject: [PATCH 0664/4498] net: lwm2m: Add timeouts to state machine Allow certain RD-client states to timeout. As stated in LwM2M specification: The bootstrap procedure failed when the LwM2M Client did not receive the "Bootstrap-Finish" operation after the EXCHANGE_LIFETIME time period expired. The EXCHANGE_LIFETIME parameter is defined in RFC 7252 We must handle the case where Bootstrap server is not sending information towards us. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index 0f4405bfc92..fca3f7d560f 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -70,6 +70,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_QUEUE_LEN sizeof("Q") #define DELAY_BEFORE_CLOSING (1 * MSEC_PER_SEC) #define DELAY_FOR_ACK 100U +#define EXCHANGE_LIFETIME 247U static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -120,6 +121,7 @@ struct lwm2m_rd_client_info { int64_t last_update; int64_t last_tx; int64_t next_event; + int64_t last_state_change; char ep_name[CLIENT_EP_LEN]; char server_ep[CLIENT_EP_LEN]; @@ -172,6 +174,7 @@ void engine_update_tx_time(void) static void next_event_at(int64_t timestamp) { + client.next_event = timestamp; (void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp); } @@ -236,6 +239,7 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) lwm2m_close_socket(client.ctx); } } + client.last_state_change = k_uptime_get(); next_event_at(k_uptime_get() + delay_ms); k_mutex_unlock(&client.mutex); } @@ -1288,8 +1292,11 @@ static void lwm2m_rd_client_service(struct k_work *work) { k_mutex_lock(&client.mutex, K_FOREVER); + int64_t timeout = 0; + if (client.ctx) { LOG_DBG("State: %d", get_sm_state()); + client.next_event = INT64_MAX; switch (get_sm_state()) { case ENGINE_IDLE: if (client.ctx->sock_fd > -1) { @@ -1312,10 +1319,12 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_BOOTSTRAP_REG_SENT: /* wait for bootstrap registration done */ + timeout = EXCHANGE_LIFETIME; break; case ENGINE_BOOTSTRAP_REG_DONE: /* wait for transfer done */ + timeout = EXCHANGE_LIFETIME; break; case ENGINE_BOOTSTRAP_TRANS_DONE: @@ -1333,6 +1342,7 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_REGISTRATION_SENT: /* wait registration to be done or timeout */ + timeout = EXCHANGE_LIFETIME; break; case ENGINE_REGISTRATION_DONE: @@ -1346,6 +1356,7 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_UPDATE_SENT: /* wait update to be done or abort */ + timeout = EXCHANGE_LIFETIME; break; case ENGINE_DEREGISTER: @@ -1354,6 +1365,7 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_DEREGISTER_SENT: /* wait for deregister to be done or reset */ + timeout = EXCHANGE_LIFETIME; break; case ENGINE_DEREGISTERED: @@ -1369,6 +1381,17 @@ static void lwm2m_rd_client_service(struct k_work *work) LOG_ERR("Unhandled state: %d", get_sm_state()); } + + if (timeout) { + int64_t end = client.last_state_change + timeout * MSEC_PER_SEC; + + if (end < k_uptime_get()) { + LOG_DBG("State machine have timed out"); + sm_handle_timeout_state(NULL, ENGINE_INIT); + } else if (client.next_event > end) { + next_event_at(end); + } + } } k_mutex_unlock(&client.mutex); From da1463756ebe524b3fcaa40b2a3c3fde32bd2592 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 12 Sep 2023 11:39:37 +0300 Subject: [PATCH 0665/4498] net: lwm2m: Allow Bootstrap server to close DTLS connection Allow Bootstrap server to close the DTLS connection immediately after receiving Ack to Bootstrap-Finish command. This is not an error as either parties are allowed to tear down the connection. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index fca3f7d560f..feebcaeea17 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -89,12 +89,10 @@ static void set_sm_state(uint8_t sm_state); enum sm_engine_state { ENGINE_IDLE, ENGINE_INIT, -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) ENGINE_DO_BOOTSTRAP_REG, ENGINE_BOOTSTRAP_REG_SENT, ENGINE_BOOTSTRAP_REG_DONE, ENGINE_BOOTSTRAP_TRANS_DONE, -#endif ENGINE_DO_REGISTRATION, ENGINE_SEND_REGISTRATION, ENGINE_REGISTRATION_SENT, @@ -355,14 +353,20 @@ static void sm_handle_failure_state(enum sm_engine_state sm_state) static void socket_fault_cb(int error) { LOG_ERR("RD Client socket error: %d", error); + lwm2m_socket_close(client.ctx); - if (sm_is_bootstrap()) { + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) && sm_is_bootstrap()) { client.ctx->sec_obj_inst = -1; /* force full registration */ client.last_update = 0; - } - lwm2m_socket_close(client.ctx); + if (get_sm_state() == ENGINE_BOOTSTRAP_TRANS_DONE) { + /* Ignore the error, some servers close the connection immediately + * after receiving Ack to Bootstrap-Finish command. + */ + return; + } + } /* Network error state causes engine to re-register, * so only trigger that state if we are not stopping the From 3975b4596fd9866cc0f8e94eef3f87bd638afbeb Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 12 Sep 2023 10:57:49 +0200 Subject: [PATCH 0666/4498] dts: riscv: niosv: Fix status string Change malformed status string "disable" -> "disabled". Signed-off-by: Franciszek Zdobylak --- dts/riscv/niosv/niosv-g.dtsi | 2 +- dts/riscv/niosv/niosv-m.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/riscv/niosv/niosv-g.dtsi b/dts/riscv/niosv/niosv-g.dtsi index 2b733f5e803..90869676f2b 100644 --- a/dts/riscv/niosv/niosv-g.dtsi +++ b/dts/riscv/niosv/niosv-g.dtsi @@ -52,7 +52,7 @@ uart0: serial@90078 { compatible = "altr,jtag-uart"; interrupts = <16>; - status = "disable"; + status = "disabled"; }; }; }; diff --git a/dts/riscv/niosv/niosv-m.dtsi b/dts/riscv/niosv/niosv-m.dtsi index aad9cbdeb78..88f8042383c 100644 --- a/dts/riscv/niosv/niosv-m.dtsi +++ b/dts/riscv/niosv/niosv-m.dtsi @@ -52,7 +52,7 @@ uart0: serial@90078 { compatible = "altr,jtag-uart"; interrupts = <16>; - status = "disable"; + status = "disabled"; }; }; }; From fa5636632e40355d74bebf0c380e1bad5175219d Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Tue, 12 Sep 2023 09:38:52 -0700 Subject: [PATCH 0667/4498] twister: fix utf-8 encoding for device handler Fixed bug for when yaml contains utf-8 special character Changed handler.log to be utf-8 Signed-off-by: Pavlo Havrylyuk --- scripts/pylib/twister/scl.py | 2 +- scripts/pylib/twister/twisterlib/handlers.py | 4 ++-- scripts/tests/twister/test_scl.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/pylib/twister/scl.py b/scripts/pylib/twister/scl.py index bbd9f6d19d0..25a3210b141 100644 --- a/scripts/pylib/twister/scl.py +++ b/scripts/pylib/twister/scl.py @@ -41,7 +41,7 @@ def yaml_load(filename): :return: dictionary representing the YAML document """ try: - with open(filename, 'r') as f: + with open(filename, 'r', encoding='utf-8') as f: return yaml.load(f, Loader=SafeLoader) except yaml.scanner.ScannerError as e: # For errors parsing schema.yaml mark = e.problem_mark diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index b5ba721a2fb..372a8b019dc 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -355,7 +355,7 @@ def __init__(self, instance, type_str): super().__init__(instance, type_str) def monitor_serial(self, ser, halt_event, harness): - log_out_fp = open(self.log, "wt") + log_out_fp = open(self.log, "wb") if self.options.coverage: # Set capture_coverage to True to indicate that right after @@ -407,7 +407,7 @@ def monitor_serial(self, ser, halt_event, harness): sl = serial_line.decode('utf-8', 'ignore').lstrip() logger.debug("DEVICE: {0}".format(sl.rstrip())) - log_out_fp.write(sl) + log_out_fp.write(sl.encode('utf-8')) log_out_fp.flush() harness.handle(sl.rstrip()) diff --git a/scripts/tests/twister/test_scl.py b/scripts/tests/twister/test_scl.py index e334df17e2b..14a0c447192 100644 --- a/scripts/tests/twister/test_scl.py +++ b/scripts/tests/twister/test_scl.py @@ -162,7 +162,7 @@ def mock_load(*args, **kwargs): with pytest.raises(ScannerError) if fail_parsing else nullcontext(): result = scl.yaml_load(filename) - mock_file.assert_called_with('dummy/file.yaml', 'r') + mock_file.assert_called_with('dummy/file.yaml', 'r', encoding='utf-8') if not fail_parsing: assert result == result_mock From dfd3d6e6cb0222f2f9f22ed6d1aebb01ec69d59e Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Mon, 11 Sep 2023 20:20:33 -0700 Subject: [PATCH 0668/4498] samples: sensor: die_temp_polling: add @ symbol to regex Added @ symbol for when address of dietemp sensor is printed Signed-off-by: Pavlo Havrylyuk --- samples/sensor/die_temp_polling/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sensor/die_temp_polling/sample.yaml b/samples/sensor/die_temp_polling/sample.yaml index f27b40e34f3..f64b321c2bd 100644 --- a/samples/sensor/die_temp_polling/sample.yaml +++ b/samples/sensor/die_temp_polling/sample.yaml @@ -12,4 +12,4 @@ tests: harness_config: type: one_line regex: - - "CPU Die temperature\\[[A-Za-z0-9_]+\\]: [1-9][0-9].[0-9] °C" + - "CPU Die temperature\\[[A-Za-z0-9_@]+\\]: [1-9][0-9].[0-9] °C" From b3a3a8b3a2d81a22339dd6f5a75a8769aa800739 Mon Sep 17 00:00:00 2001 From: Konrad Derda Date: Tue, 12 Sep 2023 21:33:38 +0200 Subject: [PATCH 0669/4498] net: ip: use default interface while matching LL src address While matching source address for a given Link-Local destination the functions iterate over interfaces and return a first result with a valid LL-address. However, they should first try to fetch address of the default interface as it not always the first one on the list. Signed-off-by: Konrad Derda --- subsys/net/ip/net_if.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index d431cbf1334..f526cac02d1 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -2890,9 +2890,15 @@ const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *dst_iface, if (dst_iface) { src = net_if_ipv6_get_ll(dst_iface, NET_ADDR_PREFERRED); } else { - STRUCT_SECTION_FOREACH(net_if, iface) { - struct in6_addr *addr; + struct in6_addr *addr; + + addr = net_if_ipv6_get_ll(net_if_get_default(), NET_ADDR_PREFERRED); + if (addr) { + src = addr; + goto out; + } + STRUCT_SECTION_FOREACH(net_if, iface) { addr = net_if_ipv6_get_ll(iface, NET_ADDR_PREFERRED); if (addr) { @@ -2905,7 +2911,6 @@ const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *dst_iface, if (!src) { src = net_ipv6_unspecified_address(); - goto out; } out: @@ -3427,9 +3432,15 @@ const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *dst_iface, if (dst_iface) { src = net_if_ipv4_get_ll(dst_iface, NET_ADDR_PREFERRED); } else { - STRUCT_SECTION_FOREACH(net_if, iface) { - struct in_addr *addr; + struct in_addr *addr; + + addr = net_if_ipv4_get_ll(net_if_get_default(), NET_ADDR_PREFERRED); + if (addr) { + src = addr; + goto out; + } + STRUCT_SECTION_FOREACH(net_if, iface) { addr = net_if_ipv4_get_ll(iface, NET_ADDR_PREFERRED); if (addr) { @@ -3454,8 +3465,6 @@ const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *dst_iface, if (!src) { src = net_ipv4_unspecified_address(); } - - goto out; } out: From 2baac8e7699fda977b4359893198bb17c82feed1 Mon Sep 17 00:00:00 2001 From: Jonas Otto Date: Sat, 9 Sep 2023 20:55:01 +0200 Subject: [PATCH 0670/4498] soc: Add support for STM32F072X8 Adds support for the STM32F072X8 SOC, which is a variant of the existing STM32F072XB with less flash. Signed-off-by: Jonas Otto --- dts/arm/st/f0/stm32f072X8.dtsi | 21 +++++++++++++++++++ ...32f072xb => Kconfig.defconfig.stm32f072xx} | 4 ++-- soc/arm/st_stm32/stm32f0/Kconfig.soc | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 dts/arm/st/f0/stm32f072X8.dtsi rename soc/arm/st_stm32/stm32f0/{Kconfig.defconfig.stm32f072xb => Kconfig.defconfig.stm32f072xx} (68%) diff --git a/dts/arm/st/f0/stm32f072X8.dtsi b/dts/arm/st/f0/stm32f072X8.dtsi new file mode 100644 index 00000000000..66669041b91 --- /dev/null +++ b/dts/arm/st/f0/stm32f072X8.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Jonas Otto + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(16)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xb b/soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xx similarity index 68% rename from soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xb rename to soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xx index dcb67a92390..8bfed8c7b10 100644 --- a/soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xb +++ b/soc/arm/st_stm32/stm32f0/Kconfig.defconfig.stm32f072xx @@ -3,7 +3,7 @@ # Copyright (c) 2017 BayLibre, SAS # SPDX-License-Identifier: Apache-2.0 -if SOC_STM32F072XB +if SOC_STM32F072X8 || SOC_STM32F072XB config SOC default "stm32f072xb" @@ -11,4 +11,4 @@ config SOC config NUM_IRQS default 32 -endif # SOC_STM32F072XB +endif # SOC_STM32F072X8 || SOC_STM32F072XB diff --git a/soc/arm/st_stm32/stm32f0/Kconfig.soc b/soc/arm/st_stm32/stm32f0/Kconfig.soc index 728ea4a10c3..eb82615bb09 100644 --- a/soc/arm/st_stm32/stm32f0/Kconfig.soc +++ b/soc/arm/st_stm32/stm32f0/Kconfig.soc @@ -31,6 +31,9 @@ config SOC_STM32F051X8 config SOC_STM32F070XB bool "STM32F070XB" +config SOC_STM32F072X8 + bool "STM32F072X8" + config SOC_STM32F072XB bool "STM32F072XB" From f4e05e3e5426b492b34073dd2acde0b164736f97 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 17 Sep 2023 21:35:58 +0200 Subject: [PATCH 0671/4498] Bluetooth: Controller: Fix ticker to prefer ticker node started Fix ticker implementation to prefer to keep ticker node started in case of race condition to start and stop. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 17 +++++ subsys/bluetooth/controller/ticker/ticker.c | 12 +++- tests/bluetooth/init/prj_ctlr_ticker.conf | 65 +++++++++++++++++++ tests/bluetooth/init/testcase.yaml | 9 +++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/bluetooth/init/prj_ctlr_ticker.conf diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 910c3819f0c..5fb2c54d085 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -55,6 +55,8 @@ config BT_LLL_VENDOR_NORDIC select BT_TICKER_REMAINDER_GET if BT_BROADCASTER && BT_CTLR_ADV_EXT select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CENTRAL_ISO + select BT_TICKER_PREFER_START_BEFORE_STOP if BT_TICKER_SLOT_AGNOSTIC + default y help Use Nordic Lower Link Layer implementation. @@ -1036,6 +1038,21 @@ config BT_TICKER_SLOT_AGNOSTIC reservations and collision handling, and operates as a simple multi-instance programmable timer. +config BT_TICKER_PREFER_START_BEFORE_STOP + bool "Ticker prefer start before stop request" + help + Under race conditions wherein for a given ticker node if a number of + start and stop operations are enqueued towards ticker_job by a said + user execution context, then start operations is preferred to be + processed before stop operations. + + Without this option, the default behavior is to defer all start + requests after all stop requests enqueued by all user context having + been processed. The rationale for default behavior being that under + race conditions, start followed by stop requests, or start before stop + requests, the said ticker node is always scheduled and at timeout the + execution context can take decision based on its execution state. + config BT_CTLR_JIT_SCHEDULING bool "Just-in-Time Scheduling" select BT_TICKER_SLOT_AGNOSTIC diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index ead148e85ba..e5c89dca905 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -55,9 +55,11 @@ struct ticker_node { uint8_t force:1; /* If non-zero, node timeout should * be forced at next expiration */ +#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) uint8_t start_pending:1; /* If non-zero, start is pending for * bottom half of ticker_job. */ +#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ uint32_t ticks_periodic; /* If non-zero, interval * between expirations */ @@ -1907,12 +1909,15 @@ static inline uint8_t ticker_job_list_manage(struct ticker_instance *instance, /* if op is start, then skip update and stop ops */ if (user_op->op < TICKER_USER_OP_TYPE_UPDATE) { +#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) if (user_op->op == TICKER_USER_OP_TYPE_START) { /* Set start pending to validate a * successive, inline stop operation. */ ticker->start_pending = 1U; } +#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ + continue; } @@ -1923,7 +1928,10 @@ static inline uint8_t ticker_job_list_manage(struct ticker_instance *instance, * set status and continue. */ if ((user_op->op > TICKER_USER_OP_TYPE_STOP_ABS) || - (((state == 0U) && !ticker->start_pending) && + ((state == 0U) && +#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) + !ticker->start_pending && +#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ (user_op->op != TICKER_USER_OP_TYPE_YIELD_ABS)) || ((user_op->op == TICKER_USER_OP_TYPE_UPDATE) && (user_op->params.update.ticks_drift_plus == 0U) && @@ -2731,7 +2739,9 @@ static inline void ticker_job_list_insert(struct ticker_instance *instance, continue; } +#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) ticker->start_pending = 0U; +#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ if (((ticker->req - ticker->ack) & 0xff) != 0U) { diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf new file mode 100644 index 00000000000..d77f519406b --- /dev/null +++ b/tests/bluetooth/init/prj_ctlr_ticker.conf @@ -0,0 +1,65 @@ +CONFIG_BT=y +CONFIG_BT_CTLR=y +CONFIG_BT_LL_SW_SPLIT=y +CONFIG_BT_CTLR_DUP_FILTER_LEN=16 +CONFIG_BT_CTLR_CONN_PARAM_REQ=y +CONFIG_BT_CTLR_LE_PING=y +CONFIG_BT_CTLR_PRIVACY=n +CONFIG_BT_CTLR_EXT_SCAN_FP=n +CONFIG_BT_DATA_LEN_UPDATE=n +CONFIG_BT_PHY_UPDATE=y +CONFIG_BT_CTLR_CHAN_SEL_2=y +CONFIG_BT_CTLR_MIN_USED_CHAN=y +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_DTM_HCI=y +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_PHY_2M=y +CONFIG_BT_CTLR_PHY_2M_NRF=y +CONFIG_BT_CTLR_PHY_CODED=y +CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y +CONFIG_BT_CTLR_LLL_PRIO=0 +CONFIG_BT_CTLR_ULL_HIGH_PRIO=1 +CONFIG_BT_CTLR_XTAL_ADVANCED=n +CONFIG_BT_CTLR_SCHED_ADVANCED=n +CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y +CONFIG_BT_CTLR_TIFS_HW=n +CONFIG_BT_CTLR_FAST_ENC=y +CONFIG_BT_CTLR_TX_RETRY_DISABLE=y +CONFIG_BT_CTLR_CONN_RSSI=y +CONFIG_BT_CTLR_ADV_INDICATION=y +CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y +CONFIG_BT_CTLR_SCAN_REQ_RSSI=y +CONFIG_BT_CTLR_SCAN_INDICATION=y +CONFIG_BT_CTLR_PROFILE_ISR=y +CONFIG_BT_CTLR_DEBUG_PINS=y +CONFIG_BT_CTLR_TEST=y +CONFIG_BT_TICKER_EXT=n +CONFIG_BT_TICKER_SLOT_AGNOSTIC=y +CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP=y +CONFIG_BT_HCI_VS_EXT=y +CONFIG_BT_HCI_MESH_EXT=n +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_SMP=y +CONFIG_BT_SIGNING=y +CONFIG_BT_SMP_SC_ONLY=y +CONFIG_BT_TINYCRYPT_ECC=y +CONFIG_BT_USE_DEBUG_KEYS=y +CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_DEBUG_MONITOR_UART=y +CONFIG_BT_HCI_CORE_LOG_LEVEL_DBG=y +CONFIG_BT_CONN_LOG_LEVEL_DBG=y +CONFIG_BT_KEYS_LOG_LEVEL_DBG=y +CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y +CONFIG_BT_SMP_LOG_LEVEL_DBG=y +CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=y +CONFIG_BT_SMP_SELFTEST=y +CONFIG_BT_ATT_LOG_LEVEL_DBG=y +CONFIG_BT_GATT_LOG_LEVEL_DBG=y +CONFIG_BT_BREDR=n +CONFIG_DEBUG=y +CONFIG_FLASH=y +CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index 4c252115178..fa30920dc1e 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,6 +122,15 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 + bluetooth.init.test_ctlr_ticker: + extra_args: + - CONF_FILE=prj_ctlr_ticker.conf + platform_allow: + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 + integration_platforms: + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 bluetooth.init.test_ctlr_broadcaster: extra_args: CONF_FILE=prj_ctlr_broadcaster.conf platform_allow: From 4cefcb6fc7917a44c51cb4c16e06daefcd8d9ca2 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 18 Sep 2023 09:00:14 +0200 Subject: [PATCH 0672/4498] Bluetooth: Controller: Fix order of preempt timeout requested flag Fix the order of setting the flag that indicates that preempt timeout has been successfully requested versus the request is waiting to be scheduled. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 1f8031a7c07..fe0a031d402 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -835,11 +835,17 @@ static void ticker_start_op_cb(uint32_t status, void *param) ARG_UNUSED(param); LL_ASSERT(status == TICKER_STATUS_SUCCESS); - LL_ASSERT(preempt_start_req != preempt_start_ack); - preempt_start_ack++; - + /* Increase preempt requested count before acknowledging that the + * ticker start operation for the preempt timeout has been handled. + */ LL_ASSERT(preempt_req == preempt_ack); preempt_req++; + + /* Increase preempt start ack count, to acknowledge that the ticker + * start operation has been handled. + */ + LL_ASSERT(preempt_start_req != preempt_start_ack); + preempt_start_ack++; } static uint32_t preempt_ticker_start(struct lll_event *first, @@ -854,7 +860,11 @@ static uint32_t preempt_ticker_start(struct lll_event *first, uint32_t preempt_to; uint32_t ret; - /* Do not request to start preempt timeout if already requested */ + /* Do not request to start preempt timeout if already requested. + * + * Check if there is pending preempt timeout start requested or if + * preempt timeout ticker has already been scheduled. + */ if ((preempt_start_req != preempt_start_ack) || (preempt_req != preempt_ack)) { uint32_t diff; From aaed347d60a08bc48c72b9f4db00f007efb06377 Mon Sep 17 00:00:00 2001 From: Ryan Erickson Date: Mon, 18 Sep 2023 08:17:50 -0500 Subject: [PATCH 0673/4498] drivers: modem: gsm: Mark as deprecated The MODEM_GSM_PPP driver is now deprecated in favor of using MODEM_CELLULAR. Signed-off-by: Ryan Erickson --- drivers/modem/Kconfig.gsm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/modem/Kconfig.gsm b/drivers/modem/Kconfig.gsm index 24e608e590e..4d5666b6f76 100644 --- a/drivers/modem/Kconfig.gsm +++ b/drivers/modem/Kconfig.gsm @@ -2,14 +2,15 @@ # SPDX-License-Identifier: Apache-2.0 config MODEM_GSM_PPP - bool "Support GSM modems" + bool "[DEPRECATED] Support GSM modems" select MODEM_CONTEXT select MODEM_CMD_HANDLER select MODEM_IFACE_UART select NET_MGMT select NET_MGMT_EVENT + select DEPRECATED help - Enable GSM modems that support standard AT commands and PPP. + This driver is deprecated, use the MODEM_CELLULAR driver instead. if MODEM_GSM_PPP From ea1cf4d2e186d576c88200d1c724feb454e9b184 Mon Sep 17 00:00:00 2001 From: Ryan Erickson Date: Mon, 18 Sep 2023 12:57:18 -0500 Subject: [PATCH 0674/4498] drivers: console: deprecate uart_mux and gsm_mux GSM_MUX and UART_MUX are being marked as deprecated. The new modem subsystem MODEM_CMUX and MODEM_PPP should be used instead. Signed-off-by: Ryan Erickson --- drivers/console/Kconfig | 3 ++- drivers/console/Kconfig.gsm_mux | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index b0dbdf7df7b..606ce1fe6d6 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -256,10 +256,11 @@ source "subsys/logging/Kconfig.template.log_config" source "drivers/console/Kconfig.gsm_mux" config UART_MUX - bool "UART muxing (GSM 07.10) support [EXPERIMENTAL]" + bool "[DEPRECATED] UART muxing (GSM 07.10) support [EXPERIMENTAL]" depends on SERIAL_SUPPORT_INTERRUPT && GSM_MUX select UART_INTERRUPT_DRIVEN select EXPERIMENTAL + select DEPRECATED help Enable this option to create UART muxer that run over a physical UART. The GSM 07.10 muxing protocol is used to separate the data diff --git a/drivers/console/Kconfig.gsm_mux b/drivers/console/Kconfig.gsm_mux index 14ef6b66da6..100b5d54303 100644 --- a/drivers/console/Kconfig.gsm_mux +++ b/drivers/console/Kconfig.gsm_mux @@ -2,8 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 config GSM_MUX - bool "GSM 07.10 muxing protocol" + bool "[DEPRECATED] GSM 07.10 muxing protocol" select CRC + select DEPRECATED help Enable GSM 07.10 muxing protocol defined in https://www.etsi.org/deliver/etsi_ts/101300_101399/101369/07.01.00_60/ts_101369v070100p.pdf From 452fadcd0edf173cdcd8e12d9b06b91e4cec1e7d Mon Sep 17 00:00:00 2001 From: Ryan Erickson Date: Mon, 18 Sep 2023 13:01:48 -0500 Subject: [PATCH 0675/4498] doc: migration-guide: inform about MODEM_GSM_PPP deprecation MODEM_GSM_PPP is deprecated in favor of using the new MODEM_CELLULAR driver. Directly related to this are UART_MUX and GSM_MUX. These are also being deprecated. Signed-off-by: Ryan Erickson --- doc/releases/migration-guide-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 7330c64132e..9e5c3b37d93 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -88,6 +88,12 @@ Recommended Changes gpio-as-nreset; }; +* The :kconfig:option:`CONFIG_MODEM_GSM_PPP` modem driver is obsolete. + Instead the new :kconfig:option:`CONFIG_MODEM_CELLULAR` driver should be used. + As part of this :kconfig:option:`CONFIG_GSM_MUX` and :kconfig:option:`CONFIG_UART_MUX` are being + marked as deprecated as well. The new modem subsystem :kconfig:option:`CONFIG_MODEM_CMUX` + and :kconfig:option:`CONFIG_MODEM_PPP`` should be used instead. + Picolibc-related Changes ************************ From 879c611f58c2af8ed26af4cbb54a96ca42f52ad9 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 19 Sep 2023 14:16:41 +0200 Subject: [PATCH 0676/4498] Bluetooth: Controller: Fix LE Set Ext Adv Param Cmd invalid status Fix HCI LE Set Extended Advertising Parameter Command invalid status reason. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_adv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index d7d5b23f63e..b5595e5e9c2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -690,7 +690,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, lll_adv_data_reset(&adv->lll.scan_rsp); err = lll_adv_aux_data_init(&adv->lll.scan_rsp); if (err) { - return err; + return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; } pdu = lll_adv_scan_rsp_peek(&adv->lll); @@ -710,7 +710,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, lll_adv_data_reset(&adv->lll.scan_rsp); err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return err; + return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; } pdu = lll_adv_scan_rsp_peek(&adv->lll); @@ -926,7 +926,7 @@ uint8_t ll_adv_enable(uint8_t enable) err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return err; + return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; } pdu_scan = lll_adv_scan_rsp_peek(lll); @@ -1873,7 +1873,7 @@ uint8_t ull_scan_rsp_set(struct ll_adv_set *adv, uint8_t len, err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return err; + return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; } prev = lll_adv_scan_rsp_peek(&adv->lll); From 97e15f29236f2e5780cd3e48ba97b9835b814338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Mon, 18 Sep 2023 09:39:33 +0000 Subject: [PATCH 0677/4498] drivers: sensor: ntc-thermistor: Fix flipped condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the flipped condition inside this if statement. Signed-off-by: Paweł Anikiel --- drivers/sensor/ntc_thermistor/ntc_thermistor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index 18c3b291645..8a73f391807 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -39,7 +39,7 @@ static int ntc_thermistor_sample_fetch(const struct device *dev, enum sensor_cha adc_sequence_init_dt(&cfg->adc_channel, &sequence); res = adc_read(cfg->adc_channel.dev, &sequence); - if (res) { + if (!res) { val_mv = data->raw; res = adc_raw_to_millivolts_dt(&cfg->adc_channel, &val_mv); data->sample_val = val_mv; From 883a0c46a8301f3d6f74bec515006a0e15f281a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:07 +0000 Subject: [PATCH 0678/4498] drivers: sensor: ntc-thermistor: Fix voltage & resistance calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pullup resistance was assumed to be the maximum ADC value. This is incorrect when the reference ADC voltage and the thermistor pullup voltage differ. Use the pullup_uv property from DT instead. The equations for the thermistor resistance are also wrong. The correct equations are (see https://en.wikipedia.org/wiki/Voltage_divider): R1 = R2 * (Vin / Vout - 1) for the positive-connected resistor, and R2 = R1 * (Vin / Vout - 1)^-1 for the negative-connected resistor. These were transformed so that they can be computed using integer math. Signed-off-by: Paweł Anikiel --- .../sensor/ntc_thermistor/ntc_thermistor.c | 5 ++--- .../sensor/ntc_thermistor/ntc_thermistor.h | 7 +++---- .../ntc_thermistor/ntc_thermistor_calc.c | 19 ++++++++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index 8a73f391807..0f003e4a278 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -55,13 +55,12 @@ static int ntc_thermistor_channel_get(const struct device *dev, enum sensor_chan { struct ntc_thermistor_data *data = dev->data; const struct ntc_thermistor_config *cfg = dev->config; - uint32_t ohm, max_adc; + uint32_t ohm; int32_t temp; switch (chan) { case SENSOR_CHAN_AMBIENT_TEMP: - max_adc = (1 << (cfg->adc_channel.resolution - 1)) - 1; - ohm = ntc_get_ohm_of_thermistor(&cfg->ntc_cfg, max_adc, data->raw); + ohm = ntc_get_ohm_of_thermistor(&cfg->ntc_cfg, data->sample_val); temp = ntc_get_temp_mc(&cfg->ntc_cfg.type, ohm); val->val1 = temp / 1000; val->val2 = (temp % 1000) * 1000; diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.h b/drivers/sensor/ntc_thermistor/ntc_thermistor.h index c8b0642bfb4..a84df840719 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.h +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.h @@ -56,11 +56,10 @@ int32_t ntc_get_temp_mc(const struct ntc_type *type, unsigned int ohm); * @brief Calculate the resistance read from NTC Thermistor * * @param cfg: NTC Thermistor configuration - * @param max_adc: Max ADC value - * @param raw_adc: Raw ADC value read + * @sample_mv: Measured voltage in mV * - * @return resistance from raw ADC value + * @return Thermistor resistance */ -uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, uint32_t max_adc, int16_t raw_adc); +uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, int sample_mv); #endif /* NTC_THERMISTOR_H */ diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c b/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c index 347156fb335..2f449544bed 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include "ntc_thermistor.h" @@ -97,17 +98,25 @@ static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int * * ntc_get_ohm_of_thermistor() - Calculate the resistance read from NTC Thermistor * * @cfg: NTC Thermistor configuration - * @max_adc: Max ADC value - * @raw_adc: Raw ADC value read + * @sample_mv: Measured voltage in mV */ -uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, uint32_t max_adc, int16_t raw_adc) +uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, int sample_mv) { + int pullup_mv = cfg->pullup_uv / 1000; uint32_t ohm; + if (sample_mv <= 0) { + return cfg->connected_positive ? INT_MAX : 0; + } + + if (sample_mv >= pullup_mv) { + return cfg->connected_positive ? 0 : INT_MAX; + } + if (cfg->connected_positive) { - ohm = cfg->pulldown_ohm * max_adc / (raw_adc - 1); + ohm = cfg->pulldown_ohm * (pullup_mv - sample_mv) / sample_mv; } else { - ohm = cfg->pullup_ohm * (raw_adc - 1) / max_adc; + ohm = cfg->pullup_ohm * sample_mv / (pullup_mv - sample_mv); } return ohm; From 694b7fe8227a8bb261c570f207b6c6eb3e75f26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:18 +0000 Subject: [PATCH 0679/4498] drivers: sensor: ntc-thermistor: Fix wrong n_comp value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The value of n_comp is wrong for ntc-thermistor-generic. Introduce a helper macro to compute n_comp correctly for both thermistor types. Signed-off-by: Paweł Anikiel --- drivers/sensor/ntc_thermistor/ntc_thermistor.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index 0f003e4a278..fcaa6a5723e 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -95,9 +95,7 @@ static int ntc_thermistor_init(const struct device *dev) return 0; } -#define NTC_THERMISTOR_DEFINE(inst, id, comp_table) \ - BUILD_ASSERT(ARRAY_SIZE(comp_table) % 2 == 0, "Compensation table needs to be even size"); \ - \ +#define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \ static int compare_ohm_##id##inst(const void *key, const void *element); \ \ static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \ @@ -112,8 +110,8 @@ static int ntc_thermistor_init(const struct device *dev) .pulldown_ohm = DT_INST_PROP(inst, pulldown_ohm), \ .connected_positive = DT_INST_PROP(inst, connected_positive), \ .type = { \ - .comp = (const struct ntc_compensation *)comp_table, \ - .n_comp = ARRAY_SIZE(comp_table), \ + .comp = _comp, \ + .n_comp = _n_comp, \ .ohm_cmp = compare_ohm_##id##inst, \ }, \ }, \ @@ -130,12 +128,16 @@ static int ntc_thermistor_init(const struct device *dev) &ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ &ntc_thermistor_driver_api); +#define NTC_THERMISTOR_DEFINE(inst, id, comp) \ + NTC_THERMISTOR_DEFINE0(inst, id, comp, ARRAY_SIZE(comp)) + /* ntc-thermistor-generic */ #define DT_DRV_COMPAT ntc_thermistor_generic #define NTC_THERMISTOR_GENERIC_DEFINE(inst) \ static const uint32_t comp_##inst[] = DT_INST_PROP(inst, zephyr_compensation_table); \ - NTC_THERMISTOR_DEFINE(inst, DT_DRV_COMPAT, comp_##inst) + NTC_THERMISTOR_DEFINE0(inst, DT_DRV_COMPAT, (struct ntc_compensation *)comp_##inst, \ + ARRAY_SIZE(comp_##inst) / 2) DT_INST_FOREACH_STATUS_OKAY(NTC_THERMISTOR_GENERIC_DEFINE) From 83be5fb596c24106dd69962c2d07fe1249226ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:23 +0000 Subject: [PATCH 0680/4498] drivers: sensor: ntc-thermistor: Simplify comp lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bsearch() tries to find the exact match for the key, otherwise it returns NULL. However, here we want to find two elements our key lies in-between. This requires some rather complicated logic that pretends it found the exact match even if it didn't. Replace this with a simple implementation of binary search. Signed-off-by: Paweł Anikiel --- .../sensor/ntc_thermistor/ntc_thermistor.c | 9 --- .../sensor/ntc_thermistor/ntc_thermistor.h | 14 ---- .../ntc_thermistor/ntc_thermistor_calc.c | 70 +++++-------------- 3 files changed, 19 insertions(+), 74 deletions(-) diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index fcaa6a5723e..9ca8b659f02 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -96,8 +96,6 @@ static int ntc_thermistor_init(const struct device *dev) } #define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \ - static int compare_ohm_##id##inst(const void *key, const void *element); \ - \ static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \ \ static const struct ntc_thermistor_config ntc_thermistor_cfg_##id##inst = { \ @@ -112,17 +110,10 @@ static int ntc_thermistor_init(const struct device *dev) .type = { \ .comp = _comp, \ .n_comp = _n_comp, \ - .ohm_cmp = compare_ohm_##id##inst, \ }, \ }, \ }; \ \ - static int compare_ohm_##id##inst(const void *key, const void *element) \ - { \ - return ntc_compensation_compare_ohm( \ - &ntc_thermistor_cfg_##id##inst.ntc_cfg.type, key, element); \ - } \ - \ SENSOR_DEVICE_DT_INST_DEFINE( \ inst, ntc_thermistor_init, NULL, &ntc_thermistor_driver_##id##inst, \ &ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.h b/drivers/sensor/ntc_thermistor/ntc_thermistor.h index a84df840719..77143d451ef 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.h +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.h @@ -17,7 +17,6 @@ struct ntc_compensation { struct ntc_type { const struct ntc_compensation *comp; int n_comp; - int (*ohm_cmp)(const void *key, const void *element); }; struct ntc_config { @@ -29,19 +28,6 @@ struct ntc_config { struct ntc_type type; }; -/** - * @brief Helper comparison function for bsearch for specific - * ntc_type - * - * Ohms are sorted in descending order, perform comparison to find - * interval indexes where key falls between - * - * @param type: Pointer to ntc_type table info - * @param key: Key value bsearch is looking for - * @param element: Array element bsearch is searching - */ -int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element); - /** * @brief Converts ohm to temperature in milli centigrade * diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c b/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c index 2f449544bed..51e1537a058 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor_calc.c @@ -30,47 +30,6 @@ static int ntc_fixp_linear_interpolate(int x0, int y0, int x1, int y1, int x) return y0 + ((y1 - y0) * (x - x0) / (x1 - x0)); } -/** - * ntc_compensation_compare_ohm() - Helper comparison function for bsearch - * - * Ohms are sorted in descending order, perform comparison to find - * interval indexes where key falls between - * - * @type: Pointer to ntc_type table info - * @key: Key value bsearch is looking for - * @element: Array element bsearch is searching - */ -int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element) -{ - int sgn = 0; - const struct ntc_compensation *ntc_key = key; - const struct ntc_compensation *element_val = element; - int element_idx = element_val - type->comp; - - if (ntc_key->ohm > element_val->ohm) { - if (element_idx == 0) { - sgn = 0; - } else { - sgn = -1; - } - } else if (ntc_key->ohm == element_val->ohm) { - sgn = 0; - } else if (ntc_key->ohm < element_val->ohm) { - if (element_idx == (type->n_comp / 2) - 1) { - sgn = 0; - } else { - if (element_idx != (type->n_comp / 2) - 1 && - ntc_key->ohm > type->comp[element_idx + 1].ohm) { - sgn = 0; - } else { - sgn = 1; - } - } - } - - return sgn; -} - /** * ntc_lookup_comp() - Finds indicies where ohm falls between * @@ -80,18 +39,27 @@ int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, c */ static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int *i_low, int *i_high) { - const struct ntc_compensation *ptr; - struct ntc_compensation search_ohm_key = {.ohm = ohm}; + int low = 0; + int high = type->n_comp - 1; - ptr = bsearch(&search_ohm_key, type->comp, type->n_comp, sizeof(type->comp[0]), - type->ohm_cmp); - if (ptr) { - *i_low = ptr - type->comp; - *i_high = *i_low + 1; - } else { - *i_low = 0; - *i_high = 0; + if (ohm > type->comp[low].ohm) { + high = low; + } else if (ohm < type->comp[high].ohm) { + low = high; + } + + while (high - low > 1) { + int mid = (low + high) / 2; + + if (ohm > type->comp[mid].ohm) { + high = mid; + } else { + low = mid; + } } + + *i_low = low; + *i_high = high; } /** From 4b33f4fe197a1fbc8cd3d06af666e508e8dffcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:35 +0000 Subject: [PATCH 0681/4498] scripts: Update ntc-thermistor table generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the script to work with the current version of the ntc-thermistor driver. Signed-off-by: Paweł Anikiel --- scripts/utils/ntc_thermistor_table.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/scripts/utils/ntc_thermistor_table.py b/scripts/utils/ntc_thermistor_table.py index 06c282a3c0f..f57d3ca662b 100755 --- a/scripts/utils/ntc_thermistor_table.py +++ b/scripts/utils/ntc_thermistor_table.py @@ -7,8 +7,8 @@ Zephyr's NTC Thermistor DTS Table generator ########################################### -This script can be used to generate a "zephyr,ntc-thermistor-rt-table" compatible -Device Tree node for NTC thermistors. This uses the Beta Parameter Equation +This script can be used to generate an NTC thermistor DTS node with a +"zephyr,compensation-table" property. This uses the Beta Parameter Equation https://devxplained.eu/en/blog/temperature-measurement-with-ntcs#beta-parameter-equation @@ -47,22 +47,17 @@ def main( temps_range = range(temp_init, temp_final + interval - 1, interval) print(f"/* NTC Thermistor Table Generated with {os.path.basename(__file__)} */\n") - print(f"/ {{") print( - f"\tthermistor_R25_{int(r25)}_B_{int(beta)}: thermistor-R25-{int(r25)}-B-{int(beta)} {{" + f"thermistor_R25_{int(r25)}_B_{int(beta)}: thermistor-R25-{int(r25)}-B-{int(beta)} {{" ) - print(f'\t\tstatus = "disabled";') - print(f'\t\tcompatible = "zephyr,ntc-thermistor-rt-table";\n') table = [] for temp in temps_range: resistance = beta_equation_calc_resistance(r25, beta, temp) table.append(f"<({int(temp)}) {int(resistance)}>") - tbl_string = ',\n\t\t\t'.join(table) - print(f"\t\t/* TR Table Format */") - print(f"\t\ttr-table = {tbl_string};") - print(f"\t}};") + tbl_string = ',\n\t\t'.join(table) + print(f"\tzephyr,compensation-table = {tbl_string};") print(f"}};") From 5db05878ab6ef2592281e068b5372d1dd6c62571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:40 +0000 Subject: [PATCH 0682/4498] drivers: sensor: ntc-thermistor: Remove r25-ohm property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the r25-ohm property. It is not used by the driver, and it is not present in linux. Signed-off-by: Paweł Anikiel --- boards/arm/tdk_robokit1/tdk_robokit1-common.dtsi | 1 - drivers/sensor/ntc_thermistor/ntc_thermistor.c | 1 - drivers/sensor/ntc_thermistor/ntc_thermistor.h | 1 - dts/bindings/sensor/ntc-thermistor.yaml | 5 ----- tests/drivers/build_all/sensor/adc.dtsi | 2 -- 5 files changed, 10 deletions(-) diff --git a/boards/arm/tdk_robokit1/tdk_robokit1-common.dtsi b/boards/arm/tdk_robokit1/tdk_robokit1-common.dtsi index 4d7003fadd9..5fc1bf4cb9f 100644 --- a/boards/arm/tdk_robokit1/tdk_robokit1-common.dtsi +++ b/boards/arm/tdk_robokit1/tdk_robokit1-common.dtsi @@ -46,7 +46,6 @@ temp_sensor: ambient_temp_sensor { compatible = "epcos,b57861s0103a039"; io-channels = <&spi_adc 0>; - r25-ohm = <10000>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index 9ca8b659f02..c07742f3b3f 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -102,7 +102,6 @@ static int ntc_thermistor_init(const struct device *dev) .adc_channel = ADC_DT_SPEC_INST_GET(inst), \ .ntc_cfg = \ { \ - .r25_ohm = DT_INST_PROP(inst, r25_ohm), \ .pullup_uv = DT_INST_PROP(inst, pullup_uv), \ .pullup_ohm = DT_INST_PROP(inst, pullup_ohm), \ .pulldown_ohm = DT_INST_PROP(inst, pulldown_ohm), \ diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.h b/drivers/sensor/ntc_thermistor/ntc_thermistor.h index 77143d451ef..3a202d3bcb3 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.h +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.h @@ -21,7 +21,6 @@ struct ntc_type { struct ntc_config { bool connected_positive; - uint32_t r25_ohm; uint32_t pullup_uv; uint32_t pullup_ohm; uint32_t pulldown_ohm; diff --git a/dts/bindings/sensor/ntc-thermistor.yaml b/dts/bindings/sensor/ntc-thermistor.yaml index 35fd96bec29..5c7fe3a4654 100644 --- a/dts/bindings/sensor/ntc-thermistor.yaml +++ b/dts/bindings/sensor/ntc-thermistor.yaml @@ -11,11 +11,6 @@ properties: description: | ADC IO channel connected to this NTC thermistor. - r25-ohm: - type: int - description: | - The resistance value of the thermistor at 25 C. - pullup-uv: type: int description: | diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index 7eb5b2a0d4b..c5a1223576e 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -36,7 +36,6 @@ test_adc_emul: adc { test_ntc_thermistor_generic: ntc-thermistor-generic { compatible = "ntc-thermistor-generic"; io-channels = <&adc0 0>; - r25-ohm = <10000>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; @@ -47,7 +46,6 @@ test_ntc_thermistor_generic: ntc-thermistor-generic { test_epcos_b57861s0103a039: epcos-b57861s0103a039 { compatible = "epcos,b57861s0103a039"; io-channels = <&adc0 0>; - r25-ohm = <10000>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; From ebdfb6b5e24202b2d7e54318f1fc2742ba42c9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Fri, 4 Aug 2023 10:36:54 +0000 Subject: [PATCH 0683/4498] drivers: sensor: ntc-thermistor: Add Murata NCP15WB473 thermistor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add murata,ncp15wb473 property together with a compensation table. The table can be found on the vendor's website (Resistance VS. Temperature tab): https://www.murata.com/en-us/products/productdetail?partno=NCP15WB473F03RC Signed-off-by: Paweł Anikiel --- drivers/sensor/ntc_thermistor/Kconfig | 3 ++- .../sensor/ntc_thermistor/ntc_thermistor.c | 26 +++++++++++++++++++ dts/bindings/sensor/murata,ncp15wb473.yaml | 8 ++++++ tests/drivers/build_all/sensor/adc.dtsi | 9 +++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/sensor/murata,ncp15wb473.yaml diff --git a/drivers/sensor/ntc_thermistor/Kconfig b/drivers/sensor/ntc_thermistor/Kconfig index 3b73aebd205..8ab04aaf184 100644 --- a/drivers/sensor/ntc_thermistor/Kconfig +++ b/drivers/sensor/ntc_thermistor/Kconfig @@ -6,7 +6,8 @@ config NTC_THERMISTOR bool "NTC Thermistor" default y depends on DT_HAS_NTC_THERMISTOR_GENERIC_ENABLED || \ - DT_HAS_EPCOS_B57861S0103A039_ENABLED + DT_HAS_EPCOS_B57861S0103A039_ENABLED || \ + DT_HAS_MURATA_NCP15WB473_ENABLED select ADC help Enable driver for Zephyr NTC Thermistor. diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index c07742f3b3f..00757a49f0c 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -156,3 +156,29 @@ static __unused const struct ntc_compensation comp_epcos_b57861s0103a039[] = { DT_INST_FOREACH_STATUS_OKAY_VARGS(NTC_THERMISTOR_DEFINE, DT_DRV_COMPAT, comp_epcos_b57861s0103a039) + +/* murata,ncp15wb473 */ +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT murata_ncp15wb473 + +static __unused const struct ntc_compensation comp_murata_ncp15wb473[] = { + { -25, 655802 }, + { -15, 360850 }, + { -5, 206463 }, + { 5, 122259 }, + { 15, 74730 }, + { 25, 47000 }, + { 35, 30334 }, + { 45, 20048 }, + { 55, 13539 }, + { 65, 9328 }, + { 75, 6544 }, + { 85, 4674 }, + { 95, 3388 }, + { 105, 2494 }, + { 115, 1860 }, + { 125, 1406 }, +}; + +DT_INST_FOREACH_STATUS_OKAY_VARGS(NTC_THERMISTOR_DEFINE, DT_DRV_COMPAT, + comp_murata_ncp15wb473) diff --git a/dts/bindings/sensor/murata,ncp15wb473.yaml b/dts/bindings/sensor/murata,ncp15wb473.yaml new file mode 100644 index 00000000000..2ea851719dd --- /dev/null +++ b/dts/bindings/sensor/murata,ncp15wb473.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: MURATA NCP15WB473 thermistor + +compatible: "murata,ncp15wb473" + +include: ntc-thermistor.yaml diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index c5a1223576e..fb004abaf37 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -51,3 +51,12 @@ test_epcos_b57861s0103a039: epcos-b57861s0103a039 { pulldown-ohm = <10000>; connected-positive; }; + +test_murata_ncp15wb473: murata-ncp15wb473 { + compatible = "murata,ncp15wb473"; + io-channels = <&adc0 0>; + pullup-uv = <3300000>; + pullup-ohm = <0>; + pulldown-ohm = <10000>; + connected-positive; +}; From cd67428fecaa065538ae367b82814da460e3e358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Tue, 8 Aug 2023 14:49:02 +0000 Subject: [PATCH 0684/4498] drivers: sensor: ntc-thermistor: Add PM support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for runtime power management. Signed-off-by: Paweł Anikiel --- .../sensor/ntc_thermistor/ntc_thermistor.c | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/ntc_thermistor/ntc_thermistor.c b/drivers/sensor/ntc_thermistor/ntc_thermistor.c index 00757a49f0c..4f76ddc30f8 100644 --- a/drivers/sensor/ntc_thermistor/ntc_thermistor.c +++ b/drivers/sensor/ntc_thermistor/ntc_thermistor.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include "ntc_thermistor.h" @@ -26,6 +28,7 @@ static int ntc_thermistor_sample_fetch(const struct device *dev, enum sensor_cha { struct ntc_thermistor_data *data = dev->data; const struct ntc_thermistor_config *cfg = dev->config; + enum pm_device_state pm_state; int32_t val_mv; int res; struct adc_sequence sequence = { @@ -35,6 +38,11 @@ static int ntc_thermistor_sample_fetch(const struct device *dev, enum sensor_cha .calibrate = false, }; + (void)pm_device_state_get(dev, &pm_state); + if (pm_state != PM_DEVICE_STATE_ACTIVE) { + return -EIO; + } + k_mutex_lock(&data->mutex, K_FOREVER); adc_sequence_init_dt(&cfg->adc_channel, &sequence); @@ -92,9 +100,34 @@ static int ntc_thermistor_init(const struct device *dev) return err; } +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_init_suspended(dev); + + err = pm_device_runtime_enable(dev); + if (err) { + LOG_ERR("Failed to enable runtime power management"); + return err; + } +#endif + return 0; } +#ifdef CONFIG_PM_DEVICE +static int ntc_thermistor_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_RESUME: + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_SUSPEND: + return 0; + default: + return -ENOTSUP; + } +} +#endif + #define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \ static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \ \ @@ -113,10 +146,12 @@ static int ntc_thermistor_init(const struct device *dev) }, \ }; \ \ + PM_DEVICE_DT_INST_DEFINE(inst, ntc_thermistor_pm_action); \ + \ SENSOR_DEVICE_DT_INST_DEFINE( \ - inst, ntc_thermistor_init, NULL, &ntc_thermistor_driver_##id##inst, \ - &ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &ntc_thermistor_driver_api); + inst, ntc_thermistor_init, PM_DEVICE_DT_INST_GET(inst), \ + &ntc_thermistor_driver_##id##inst, &ntc_thermistor_cfg_##id##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &ntc_thermistor_driver_api); #define NTC_THERMISTOR_DEFINE(inst, id, comp) \ NTC_THERMISTOR_DEFINE0(inst, id, comp, ARRAY_SIZE(comp)) From b142e9dd5ecced30d58dc5846a72fcb35174d263 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Tue, 19 Sep 2023 10:29:16 -0400 Subject: [PATCH 0685/4498] posix: logging: use log module register instead of declare Log modules should be registered with LOG_MODULE_REGISTER rather than LOG_MODULE_DECLARE. It seems the latter works on most platforms (at least with in minimal mode as configured with ZTest). Signed-off-by: Christopher Friedt --- lib/posix/cond.c | 2 +- lib/posix/mutex.c | 2 +- lib/posix/pthread.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/posix/cond.c b/lib/posix/cond.c index 8e2407f3297..f4128054e3f 100644 --- a/lib/posix/cond.c +++ b/lib/posix/cond.c @@ -13,7 +13,7 @@ #include #include -LOG_MODULE_DECLARE(pthread_cond, CONFIG_PTHREAD_COND_LOG_LEVEL); +LOG_MODULE_REGISTER(pthread_cond, CONFIG_PTHREAD_COND_LOG_LEVEL); int64_t timespec_to_timeoutms(const struct timespec *abstime); diff --git a/lib/posix/mutex.c b/lib/posix/mutex.c index 5ed3fe09249..3c8dde8d52d 100644 --- a/lib/posix/mutex.c +++ b/lib/posix/mutex.c @@ -13,7 +13,7 @@ #include #include -LOG_MODULE_DECLARE(pthread_mutex, CONFIG_PTHREAD_MUTEX_LOG_LEVEL); +LOG_MODULE_REGISTER(pthread_mutex, CONFIG_PTHREAD_MUTEX_LOG_LEVEL); static struct k_spinlock pthread_mutex_spinlock; diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 761d29cb4dc..f3ca678ac4d 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -17,7 +17,7 @@ #include #include -LOG_MODULE_DECLARE(pthread, CONFIG_PTHREAD_LOG_LEVEL); +LOG_MODULE_REGISTER(pthread, CONFIG_PTHREAD_LOG_LEVEL); #ifdef CONFIG_DYNAMIC_THREAD_STACK_SIZE #define DYNAMIC_STACK_SIZE CONFIG_DYNAMIC_THREAD_STACK_SIZE From 2ea2d37d60ada33bdf051eb9d699f4db9123c3ff Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Mon, 18 Sep 2023 06:20:40 +0200 Subject: [PATCH 0686/4498] modules: lvgl: retain last event for button/pointer device Adds saving of the last lv_indev_data_t for button and pointer type devices. This is needed because there is currently no way to tell LVGL in the read callback that no event is pending. Preservation of the last state is expected to happen in the port layer for the input devices. This resolves issue #62512. Signed-off-by: Fabian Blatz --- modules/lvgl/include/lvgl_common_input.h | 1 + modules/lvgl/input/lvgl_common_input.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/lvgl/include/lvgl_common_input.h b/modules/lvgl/include/lvgl_common_input.h index a218ed29647..c34dabe1a8a 100644 --- a/modules/lvgl/include/lvgl_common_input.h +++ b/modules/lvgl/include/lvgl_common_input.h @@ -23,6 +23,7 @@ struct lvgl_common_input_data { lv_indev_drv_t indev_drv; lv_indev_t *indev; lv_indev_data_t pending_event; + lv_indev_data_t previous_event; }; int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device *dev); diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c index 5e7e1474368..f91b01bacd3 100644 --- a/modules/lvgl/input/lvgl_common_input.c +++ b/modules/lvgl/input/lvgl_common_input.c @@ -26,8 +26,18 @@ static void lvgl_input_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) { const struct device *dev = drv->user_data; const struct lvgl_common_input_config *cfg = dev->config; + struct lvgl_common_input_data *common_data = dev->data; + + if (k_msgq_get(cfg->event_msgq, data, K_NO_WAIT) != 0) { + memcpy(data, &common_data->previous_event, sizeof(lv_indev_data_t)); + if (drv->type == LV_INDEV_TYPE_ENCODER) { + data->enc_diff = 0; /* For encoders, clear last movement */ + } + data->continue_reading = false; + return; + } - k_msgq_get(cfg->event_msgq, data, K_NO_WAIT); + memcpy(&common_data->previous_event, data, sizeof(lv_indev_data_t)); data->continue_reading = k_msgq_num_used_get(cfg->event_msgq) > 0; } From 24f2dd059e29fab87c942182624fd0aae3d9591a Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Mon, 11 Sep 2023 17:14:48 -0500 Subject: [PATCH 0687/4498] drivers: eth_mcux: Avoid using deprecated SDK function The SDK function ENET_SetCallback is deprecated and has been removed in the latest SDK. Update the driver to set the callback during Init by using the callback config param. Signed-off-by: Mahesh Mahadevan --- drivers/ethernet/eth_mcux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_mcux.c b/drivers/ethernet/eth_mcux.c index a03922ccd78..b4e244ae304 100644 --- a/drivers/ethernet/eth_mcux.c +++ b/drivers/ethernet/eth_mcux.c @@ -1042,6 +1042,8 @@ static void eth_mcux_init(const struct device *dev) enet_config.interrupt |= kENET_MiiInterrupt; #endif enet_config.miiMode = kENET_RmiiMode; + enet_config.callback = eth_callback; + enet_config.userData = context; if (IS_ENABLED(CONFIG_ETH_MCUX_PROMISCUOUS_MODE)) { enet_config.macSpecialConfig |= kENET_ControlPromiscuousEnable; @@ -1098,7 +1100,6 @@ static void eth_mcux_init(const struct device *dev) /* Enable reclaim of tx descriptors that will have the tx timestamp */ ENET_SetTxReclaim(&context->enet_handle, true, 0); #endif - ENET_SetCallback(&context->enet_handle, eth_callback, context); eth_mcux_phy_start(context); } From 73bc59fad8bcc76b95787eab7d7636da55d390b0 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 12 Sep 2023 09:34:52 -0500 Subject: [PATCH 0688/4498] boards: mimxrt595_evk: Update PM code Some SDK power macros are no longer available in the header file. Add local defines in Zephyr. Signed-off-by: Mahesh Mahadevan --- boards/arm/mimxrt595_evk/board.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/boards/arm/mimxrt595_evk/board.c b/boards/arm/mimxrt595_evk/board.c index 99aed3a7642..fce50f4c23d 100644 --- a/boards/arm/mimxrt595_evk/board.c +++ b/boards/arm/mimxrt595_evk/board.c @@ -19,6 +19,22 @@ static const struct device *sw2 = DEVICE_DT_GET(NODE_SW2); static const struct device *ldo1 = DEVICE_DT_GET(NODE_LDO1); static const struct device *ldo2 = DEVICE_DT_GET(NODE_LDO2); +#define MEGA (1000000U) + +/* Core frequency levels number. */ +#define POWER_FREQ_LEVELS_NUM (5U) + +/* Invalid voltage level. */ +#define POWER_INVALID_VOLT_LEVEL (0xFFFFFFFFU) + +static const uint32_t power_freq_level[POWER_FREQ_LEVELS_NUM] = { + 275U * MEGA, + 230U * MEGA, + 192U * MEGA, + 100U * MEGA, + 60U * MEGA +}; + /* System clock frequency. */ extern uint32_t SystemCoreClock; @@ -30,7 +46,7 @@ static int32_t board_calc_volt_level(void) uint32_t volt; for (i = 0U; i < POWER_FREQ_LEVELS_NUM; i++) { - if (SystemCoreClock > powerFreqLevel[i]) { + if (SystemCoreClock > power_freq_level[i]) { break; } } From ded77bccb3e2a09094ff7cd7e57aba3cf7454a87 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 12 Sep 2023 09:52:56 -0500 Subject: [PATCH 0689/4498] drivers: pwm: Use the SDK macro to check if wait field is available Wait enable is available only for certain SoC's Signed-off-by: Mahesh Mahadevan --- drivers/pwm/pwm_mcux.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pwm/pwm_mcux.c b/drivers/pwm/pwm_mcux.c index 23bbd3d0326..d753682f46e 100644 --- a/drivers/pwm/pwm_mcux.c +++ b/drivers/pwm/pwm_mcux.c @@ -199,7 +199,9 @@ static int pwm_mcux_init(const struct device *dev) pwm_config.reloadLogic = config->reload; pwm_config.clockSource = kPWM_BusClock; pwm_config.enableDebugMode = config->run_debug; +#if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN) pwm_config.enableWait = config->run_wait; +#endif status = PWM_Init(config->base, config->index, &pwm_config); if (status != kStatus_Success) { From 2ea61305354575058ee27d90423456dada4648bf Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Thu, 14 Sep 2023 15:02:50 +0100 Subject: [PATCH 0690/4498] drivers: dma_pxp: Update to the PXP DMA per SDK 2.14 changes Some macros have been redefined in SDK 2.14 Signed-off-by: Mahesh Mahadevan --- drivers/dma/dma_mcux_pxp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/dma_mcux_pxp.c b/drivers/dma/dma_mcux_pxp.c index 69ce6a2eeba..ef6f9f90f28 100644 --- a/drivers/dma/dma_mcux_pxp.c +++ b/drivers/dma/dma_mcux_pxp.c @@ -89,7 +89,13 @@ static int dma_mcux_pxp_configure(const struct device *dev, uint32_t channel, bytes_per_pixel = 2; break; case DMA_MCUX_PXP_FMT_RGB888: +#if (!(defined(FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT) && \ + FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT)) && \ + (!(defined(FSL_FEATURE_PXP_V3) && FSL_FEATURE_PXP_V3)) + ps_buffer_cfg.pixelFormat = kPXP_PsPixelFormatARGB8888; +#else ps_buffer_cfg.pixelFormat = kPXP_PsPixelFormatRGB888; +#endif output_buffer_cfg.pixelFormat = kPXP_OutputPixelFormatRGB888; bytes_per_pixel = 3; break; From bf6ccbb9de32b10af6e48ca9f73207752c7b50ec Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Thu, 14 Sep 2023 17:25:23 +0100 Subject: [PATCH 0691/4498] drivers: dma_pxp: Select PXP driver when CONFIG_DISPLAY is enabled The PXP DMA driver is only used by Display drivers. Signed-off-by: Mahesh Mahadevan --- drivers/dma/Kconfig.mcux_pxp | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/Kconfig.mcux_pxp b/drivers/dma/Kconfig.mcux_pxp index 054dde52451..b00148304cf 100644 --- a/drivers/dma/Kconfig.mcux_pxp +++ b/drivers/dma/Kconfig.mcux_pxp @@ -5,5 +5,6 @@ config MCUX_PXP bool "MCUX PXP DMA driver" default y depends on DT_HAS_NXP_PXP_ENABLED + depends on DISPLAY help PXP DMA driver for NXP SOCs From 492517b918d267f553688cd6b9d59b92ffc10f91 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Wed, 6 Sep 2023 12:06:47 -0500 Subject: [PATCH 0692/4498] west.yml: Update NXP HAL SDK to 2.14 Update NXP HAL SDK to 2.14 Signed-off-by: Mahesh Mahadevan --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9b2f1dff851..bac275806b5 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 5331fe2ff1310b033bf01cd3a232f1e587726e3b + revision: a87e6a8ba3af330fc43f9ed93ce3748416e1009d path: modules/hal/nxp groups: - hal From 5eb2e5eb2b6e91992bb8d8092954892ee8432f04 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 19 Sep 2023 16:37:15 +0000 Subject: [PATCH 0693/4498] dts: efm32_pg_1b: add pin-controller binding This platform (SOC_SERIES_EFM32PG1B) is also using SOC_GECKO_SERIES1 and needs a pinctrl device defined to build the gecko-uart driver successfully. Signed-off-by: Fabio Baltieri --- dts/arm/silabs/efm32_pg_1b.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/arm/silabs/efm32_pg_1b.dtsi b/dts/arm/silabs/efm32_pg_1b.dtsi index f88fc07def7..30d242256dd 100644 --- a/dts/arm/silabs/efm32_pg_1b.dtsi +++ b/dts/arm/silabs/efm32_pg_1b.dtsi @@ -139,6 +139,13 @@ #gpio-cells = <2>; status = "disabled"; }; + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; wdog0: wdog@40052000 { From 4a8d6201279e83c792ecc0bd48fa7dfab65f2e62 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 17:42:02 +0000 Subject: [PATCH 0694/4498] twister: platform key filtering should not be flagged as error If coverage is provided by a different platform not in the integration list, it should not be reported as error. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/testplan.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 2e0eb9880f7..d8873eade0a 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -50,6 +50,8 @@ import scl class Filters: + # platform keys + PLATFORM_KEY = 'platform key filter' # filters provided on command line by the user/tester CMD_LINE = 'command line filter' # filters in the testsuite yaml definition @@ -884,7 +886,7 @@ def apply_filters(self, **kwargs): keyed_test = keyed_tests.get(test_key) if keyed_test is not None: plat_key = {key_field: getattr(keyed_test['plat'], key_field) for key_field in key_fields} - instance.add_filter(f"Excluded test already covered for key {tuple(key)} by platform {keyed_test['plat'].name} having key {plat_key}", Filters.TESTSUITE) + instance.add_filter(f"Excluded test already covered for key {tuple(key)} by platform {keyed_test['plat'].name} having key {plat_key}", Filters.PLATFORM_KEY) else: keyed_tests[test_key] = {'plat': plat, 'ts': ts} else: @@ -1023,7 +1025,8 @@ def change_skip_to_error_if_integration(options, instance): and "quarantine" not in instance.reason.lower(): # Do not treat this as error if filter type is command line filters = {t['type'] for t in instance.filters} - if Filters.CMD_LINE in filters or Filters.SKIP in filters: + ignore_filters ={Filters.CMD_LINE, Filters.SKIP, Filters.PLATFORM_KEY} + if filters.intersection(ignore_filters): return instance.status = "error" instance.reason += " but is one of the integration platforms" From 7f04014c0a4a420b071bcaaf6e348d44684e6a63 Mon Sep 17 00:00:00 2001 From: Ryan Erickson Date: Tue, 19 Sep 2023 09:58:16 -0500 Subject: [PATCH 0695/4498] boards: mg100: add SD card regulator enable Add regulator to enable SD card communication. Signed-off-by: Ryan Erickson --- boards/arm/mg100/Kconfig.defconfig | 3 +++ boards/arm/mg100/mg100.dts | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/boards/arm/mg100/Kconfig.defconfig b/boards/arm/mg100/Kconfig.defconfig index 74160f93bf5..46091ee3b47 100644 --- a/boards/arm/mg100/Kconfig.defconfig +++ b/boards/arm/mg100/Kconfig.defconfig @@ -18,6 +18,9 @@ config NORDIC_QSPI_NOR config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE default 4096 if NORDIC_QSPI_NOR +config REGULATOR + default DISK_DRIVER_SDMMC + config BT_CTLR default BT diff --git a/boards/arm/mg100/mg100.dts b/boards/arm/mg100/mg100.dts index 0d33fd32151..1bbaa146dd6 100644 --- a/boards/arm/mg100/mg100.dts +++ b/boards/arm/mg100/mg100.dts @@ -49,6 +49,13 @@ }; }; + en-sd-switch { + compatible = "regulator-fixed"; + regulator-name = "en_sd_switch"; + enable-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; + /* These aliases are provided for compatibility with samples */ aliases { led0 = &led1; From 70bdccac7f6c30dc9fc87b700315d8d0903646ea Mon Sep 17 00:00:00 2001 From: Henrik Eriksen Date: Fri, 18 Aug 2023 09:23:22 +0200 Subject: [PATCH 0696/4498] bluetooth: tester: ccp: Added support for testing Call Control client. - Discover GTBS. - Accept call. - Terminate call. - Originate call. - Get call states. Signed-off-by: Henrik Eriksen --- tests/bluetooth/tester/CMakeLists.txt | 4 + tests/bluetooth/tester/overlay-le-audio.conf | 5 + tests/bluetooth/tester/src/btp/btp.h | 6 +- tests/bluetooth/tester/src/btp/btp_ccp.h | 63 ++++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_ccp.c | 343 +++++++++++++++++++ tests/bluetooth/tester/src/btp_core.c | 13 + 7 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_ccp.h create mode 100644 tests/bluetooth/tester/src/btp_ccp.c diff --git a/tests/bluetooth/tester/CMakeLists.txt b/tests/bluetooth/tester/CMakeLists.txt index 71dbe85c2b3..d773e6b0da2 100644 --- a/tests/bluetooth/tester/CMakeLists.txt +++ b/tests/bluetooth/tester/CMakeLists.txt @@ -51,3 +51,7 @@ endif() if(CONFIG_BT_AICS) target_sources(app PRIVATE src/btp_aics.c) endif() + +if (CONFIG_BT_TBS_CLIENT) + target_sources(app PRIVATE src/btp_ccp.c) +endif() diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 3a94bf77d7a..d925d805826 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -66,3 +66,8 @@ CONFIG_BT_HAS_PRESET_NAME_DYNAMIC=y # CSIS CONFIG_BT_CSIP_SET_MEMBER=y + +# CCP +CONFIG_BT_L2CAP_TX_BUF_COUNT=12 +CONFIG_BT_TBS_CLIENT_GTBS=y +CONFIG_BT_TBS_CLIENT_TBS=n diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index 6736334ceaa..bc4092c7926 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -27,6 +27,7 @@ #include "btp_csis.h" #include "btp_micp.h" #include "btp_mics.h" +#include "btp_ccp.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -53,14 +54,17 @@ #define BTP_SERVICE_ID_MICP 16 #define BTP_SERVICE_ID_CSIS 17 #define BTP_SERVICE_ID_MICS 18 +#define BTP_SERVICE_ID_CCP 19 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_MICS +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CCP #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 #define BTP_STATUS_UNKNOWN_CMD 0x02 #define BTP_STATUS_NOT_READY 0x03 +#define BTP_STATUS_VAL(err) (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS + /* TODO indicate delay response, should be removed when all commands are * converted to cmd+status+ev pattern */ diff --git a/tests/bluetooth/tester/src/btp/btp_ccp.h b/tests/bluetooth/tester/src/btp/btp_ccp.h new file mode 100644 index 00000000000..1792637de2e --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_ccp.h @@ -0,0 +1,63 @@ +/* btp_ccp.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Oticon + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/* CCP commands */ +#define BTP_CCP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_ccp_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_CCP_DISCOVER_TBS 0x02 +struct btp_ccp_discover_tbs_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_CCP_ACCEPT_CALL 0x03 +struct btp_ccp_accept_call_cmd { + bt_addr_le_t address; + uint8_t inst_index; + uint8_t call_id; +} __packed; + +#define BTP_CCP_TERMINATE_CALL 0x04 +struct btp_ccp_terminate_call_cmd { + bt_addr_le_t address; + uint8_t inst_index; + uint8_t call_id; +} __packed; + +#define BTP_CCP_ORIGINATE_CALL 0x05 +struct btp_ccp_originate_call_cmd { + bt_addr_le_t address; + uint8_t inst_index; + uint8_t uri_len; + char uri[0]; +} __packed; + +#define BTP_CCP_READ_CALL_STATE 0x06 +struct btp_ccp_read_call_state_cmd { + bt_addr_le_t address; + uint8_t inst_index; +} __packed; + +/* CCP events */ +#define BTP_CCP_EV_DISCOVERED 0x80 +struct btp_ccp_discovered_ev { + int status; + uint8_t tbs_count; + bool gtbs_found; +} __packed; + +#define BTP_CCP_EV_CALL_STATES 0x81 +struct btp_ccp_call_states_ev { + int status; + uint8_t inst_index; + uint8_t call_count; + struct bt_tbs_client_call_state call_states[0]; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 807b890036b..63d70c825b7 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -98,3 +98,6 @@ uint8_t tester_unregister_micp(void); uint8_t tester_init_mics(void); uint8_t tester_unregister_mics(void); + +uint8_t tester_init_ccp(void); +uint8_t tester_unregister_ccp(void); diff --git a/tests/bluetooth/tester/src/btp_ccp.c b/tests/bluetooth/tester/src/btp_ccp.c new file mode 100644 index 00000000000..6c0d18258c3 --- /dev/null +++ b/tests/bluetooth/tester/src/btp_ccp.c @@ -0,0 +1,343 @@ +/* btp_ccp.c - Bluetooth CCP Tester */ + +/* + * Copyright (c) 2023 Oticon + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "btp/btp.h" +#include "zephyr/sys/byteorder.h" +#include + +#include +#define LOG_MODULE_NAME bttester_ccp +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); + +static uint8_t ccp_supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_ccp_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_CCP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_CCP_DISCOVER_TBS); + tester_set_bit(rp->data, BTP_CCP_ACCEPT_CALL); + tester_set_bit(rp->data, BTP_CCP_TERMINATE_CALL); + tester_set_bit(rp->data, BTP_CCP_ORIGINATE_CALL); + tester_set_bit(rp->data, BTP_CCP_READ_CALL_STATE); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static void tbs_client_discovered_ev(int err, uint8_t tbs_count, bool gtbs_found) +{ + struct btp_ccp_discovered_ev ev; + + ev.status = sys_cpu_to_le32(err); + ev.tbs_count = tbs_count; + ev.gtbs_found = gtbs_found; + + tester_event(BTP_SERVICE_ID_CCP, BTP_CCP_EV_DISCOVERED, &ev, sizeof(ev)); +} + +/** + * @brief Callback function for ccp_discover. + * + * @param conn The connection that was used to discover CCP for a + * device. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param tbs_count Number of TBS instances on peer device. + * @param gtbs_found Whether or not the server has a Generic TBS instance. + */ +static void tbs_client_discover_cb(struct bt_conn *conn, + int err, + uint8_t tbs_count, + bool gtbs_found) +{ + LOG_DBG("Discovered TBS - err (%u) GTBS (%u)", err, gtbs_found); + + tbs_client_discovered_ev(err, tbs_count, gtbs_found); +} + +/** + * @brief Callback function for the CCP call control functions. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_index The call index. For #bt_tbs_client_originate_call this will + * always be 0, and does not reflect the actual call index. + */ +static void tbs_client_originate_call_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_index) +{ + LOG_DBG("Originate call - err (%u) Call Index (%u)", err, call_index); +} + +/** + * @brief Callback function for the CCP call control functions. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_index The call index. For #bt_tbs_client_originate_call this will + * always be 0, and does not reflect the actual call index. + */ +static void tbs_client_terminate_call_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_index) +{ + LOG_DBG("Terminate call - err (%u) Call Index (%u)", err, call_index); +} + +/** + * @brief Callback function for the CCP call control functions. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_index The call index. For #bt_tbs_client_originate_call this will + * always be 0, and does not reflect the actual call index. + */ +static void tbs_client_accept_call_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_index) +{ + LOG_DBG("Accept call - err (%u) Call Index (%u)", err, call_index); +} + +/** + * @brief Callback function for the CCP call control functions. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_index The call index. For #bt_tbs_client_originate_call this will + * always be 0, and does not reflect the actual call index. + */ +static void tbs_client_retrieve_call_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_index) +{ + LOG_DBG("Retrieve call - err (%u) Call Index (%u)", err, call_index); +} + +typedef struct bt_tbs_client_call_state bt_tbs_client_call_state_t; + +#define CALL_STATES_EV_SIZE sizeof(struct btp_ccp_call_states_ev) + \ + sizeof(bt_tbs_client_call_state_t) * \ + CONFIG_BT_TBS_CLIENT_MAX_CALLS + +static void tbs_client_call_states_ev(int err, + uint8_t inst_index, + uint8_t call_count, + const bt_tbs_client_call_state_t *call_states) +{ + struct net_buf_simple *buf = NET_BUF_SIMPLE(CALL_STATES_EV_SIZE); + struct btp_ccp_call_states_ev ev = { + sys_cpu_to_le32(err), inst_index, call_count + }; + + net_buf_simple_init(buf, 0); + net_buf_simple_add_mem(buf, &ev, sizeof(ev)); + + for (uint8_t n = 0; n < call_count; n++, call_states++) { + net_buf_simple_add_mem(buf, call_states, sizeof(bt_tbs_client_call_state_t)); + } + + tester_event(BTP_SERVICE_ID_CCP, BTP_CCP_EV_CALL_STATES, buf->data, buf->len); +} + +/** + * @brief Callback function for ccp_read_call_state. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_count Number of call states read. + * @param call_states Array of call states. The array is not kept by + * the client, so must be copied to be saved. + */ +static void tbs_client_call_states_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_count, + const bt_tbs_client_call_state_t *call_states) +{ + LOG_DBG("Call states - err (%u) Call Count (%u)", err, call_count); + + tbs_client_call_states_ev(err, inst_index, call_count, call_states); +} + +/** + * @brief Callback function for ccp_read_termination_reason. + * + * @param conn The connection used in the function. + * @param err Error value. BT_TBS_CLIENT_RESULT_CODE_*, + * GATT error or errno value. + * @param inst_index The index of the TBS instance that was updated. + * @param call_index The call index. + * @param reason The termination reason. + */ +static void tbs_client_termination_reason_cb(struct bt_conn *conn, + int err, + uint8_t inst_index, + uint8_t call_index, + uint8_t reason) +{ + LOG_DBG("Termination reason - err (%u) Call Index (%u) Reason (%u)", + err, call_index, reason); +} + +static const struct bt_tbs_client_cb tbs_client_callbacks = { + .discover = tbs_client_discover_cb, + .originate_call = tbs_client_originate_call_cb, + .terminate_call = tbs_client_terminate_call_cb, + .accept_call = tbs_client_accept_call_cb, + .retrieve_call = tbs_client_retrieve_call_cb, + .call_state = tbs_client_call_states_cb, + .termination_reason = tbs_client_termination_reason_cb +}; + +static uint8_t ccp_discover_tbs(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_ccp_discover_tbs_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + err = (conn) ? bt_tbs_client_discover(conn) : -ENOTCONN; + if (conn) { + bt_conn_unref(conn); + } + + return BTP_STATUS_VAL(err); +} + +static uint8_t ccp_accept_call(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_ccp_accept_call_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + err = (conn) ? bt_tbs_client_accept_call(conn, cp->inst_index, cp->call_id) : -ENOTCONN; + if (conn) { + bt_conn_unref(conn); + } + + return BTP_STATUS_VAL(err); +} + +static uint8_t ccp_terminate_call(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_ccp_terminate_call_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + err = (conn) ? bt_tbs_client_terminate_call(conn, cp->inst_index, cp->call_id) : + -ENOTCONN; + if (conn) { + bt_conn_unref(conn); + } + + return BTP_STATUS_VAL(err); +} + +static uint8_t ccp_originate_call(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_ccp_originate_call_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + err = (conn) ? bt_tbs_client_originate_call(conn, cp->inst_index, cp->uri) : -ENOTCONN; + if (conn) { + bt_conn_unref(conn); + } + + return BTP_STATUS_VAL(err); +} + +static uint8_t ccp_read_call_state(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_ccp_read_call_state_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + err = (conn) ? bt_tbs_client_read_call_state(conn, cp->inst_index) : -ENOTCONN; + if (conn) { + bt_conn_unref(conn); + } + + return BTP_STATUS_VAL(err); +} + +static const struct btp_handler ccp_handlers[] = { + { + .opcode = BTP_CCP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = ccp_supported_commands + }, + { + .opcode = BTP_CCP_DISCOVER_TBS, + .expect_len = sizeof(struct btp_ccp_discover_tbs_cmd), + .func = ccp_discover_tbs + }, + { + .opcode = BTP_CCP_ACCEPT_CALL, + .expect_len = sizeof(struct btp_ccp_accept_call_cmd), + .func = ccp_accept_call + }, + { + .opcode = BTP_CCP_TERMINATE_CALL, + .expect_len = sizeof(struct btp_ccp_terminate_call_cmd), + .func = ccp_terminate_call + }, + { + .opcode = BTP_CCP_ORIGINATE_CALL, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = ccp_originate_call + }, + { + .opcode = BTP_CCP_READ_CALL_STATE, + .expect_len = sizeof(struct btp_ccp_read_call_state_cmd), + .func = ccp_read_call_state + } +}; + +uint8_t tester_init_ccp(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_CCP, ccp_handlers, + ARRAY_SIZE(ccp_handlers)); + + bt_tbs_client_register_cb(&tbs_client_callbacks); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_ccp(void) +{ + return BTP_STATUS_SUCCESS; +} diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 6f09b1337e4..c8c541e9dac 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -83,6 +83,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) tester_set_bit(rp->data, BTP_SERVICE_ID_MICP); #endif /* CONFIG_BT_MICP_MIC_DEV */ +#if defined(CONFIG_BT_TBS_CLIENT) + tester_set_bit(rp->data, BTP_SERVICE_ID_CCP); +#endif /* CONFIG_BT_TBS_CLIENT */ *rsp_len = sizeof(*rp) + 2; @@ -167,6 +170,11 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_csis(); break; #endif /* CONFIG_BT_CSIP_SET_MEMBER */ +#if defined(CONFIG_BT_TBS_CLIENT) + case BTP_SERVICE_ID_CCP: + status = tester_init_ccp(); + break; +#endif /* CONFIG_BT_TBS_CLIENT */ default: LOG_WRN("unknown id: 0x%02x", cp->id); status = BTP_STATUS_FAILED; @@ -253,6 +261,11 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_csis(); break; #endif /* CONFIG_BT_CSIP_SET_MEMBER */ +#if defined(CONFIG_BT_TBS_CLIENT) + case BTP_SERVICE_ID_CCP: + status = tester_unregister_ccp(); + break; +#endif /* CONFIG_BT_TBS_CLIENT */ default: LOG_WRN("unknown id: 0x%x", cp->id); status = BTP_STATUS_FAILED; From 3d3a221b1e86bb37518b7c9668863d81a7673eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Fri, 1 Sep 2023 10:45:04 +0200 Subject: [PATCH 0697/4498] net: sockets: add support for SO_REUSEADDR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for the SO_REUSEADDR option to be enabled for a socket using setsockopt(). With this option, it is possible to bind multiple sockets to the same local IP address / port combination, when one of the IP address is unspecified (ANY_ADDR). The implementation strictly follows the BSD implementation and tries to follow the Linux implementation as close as possible. However, there is one limitation: for client sockets, the Linux implementation of SO_REUSEADDR behaves exactly like the one for SO_REUSEPORT and enables multiple sockets to have exactly the same specific IP address / port combination. This behavior is not possible with this implementation, as there is no trivial way to identify a socket to be a client socket during the bind() call. For this behavior, one has to use the SO_REUSEPORT option in Zephyr. There is also a new Kconfig to control this feature similar to other socket options: CONFIG_NET_CONTEXT_REUSEADDR. This option is enabled by default if TCP or UDP are enabled. However, it can still be disabled explicitly. Signed-off-by: Tobias Frauenschläger --- include/zephyr/net/net_context.h | 4 + include/zephyr/net/socket.h | 4 +- subsys/net/ip/Kconfig | 7 ++ subsys/net/ip/net_context.c | 193 ++++++++++++++++++++++++++++--- subsys/net/ip/net_private.h | 6 + subsys/net/ip/tcp.c | 20 ++++ subsys/net/lib/sockets/sockets.c | 31 ++++- 7 files changed, 242 insertions(+), 23 deletions(-) diff --git a/include/zephyr/net/net_context.h b/include/zephyr/net/net_context.h index 7ab30dd0cb1..362d350ba8b 100644 --- a/include/zephyr/net/net_context.h +++ b/include/zephyr/net/net_context.h @@ -322,6 +322,9 @@ __net_socket struct net_context { #endif #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) uint8_t dscp_ecn; +#endif +#if defined(CONFIG_NET_CONTEXT_REUSEADDR) + bool reuseaddr; #endif } options; @@ -1073,6 +1076,7 @@ enum net_context_option { NET_OPT_RCVBUF = 6, NET_OPT_SNDBUF = 7, NET_OPT_DSCP_ECN = 8, + NET_OPT_REUSEADDR = 9, }; /** diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 684c74a7037..a7bfcbb8347 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -1013,7 +1013,7 @@ struct ifreq { /** sockopt: Recording debugging information (ignored, for compatibility) */ #define SO_DEBUG 1 -/** sockopt: address reuse (ignored, for compatibility) */ +/** sockopt: address reuse */ #define SO_REUSEADDR 2 /** sockopt: Type of the socket */ #define SO_TYPE 3 @@ -1024,7 +1024,7 @@ struct ifreq { /** sockopt: Transmission of broadcast messages is supported (ignored, for compatibility) */ #define SO_BROADCAST 6 -/** sockopt: Size of socket socket send buffer (ignored, for compatibility) */ +/** sockopt: Size of socket send buffer */ #define SO_SNDBUF 7 /** sockopt: Size of socket recv buffer */ #define SO_RCVBUF 8 diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index d2ca36b845c..be519e1f34c 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -689,6 +689,13 @@ config NET_CONTEXT_DSCP_ECN Notification values on net_context. Those values are then used in IPv4/IPv6 header when sending packets over net_context. +config NET_CONTEXT_REUSEADDR + bool "Add REUSEADDR support to net_context" + default y if NET_TCP || NET_UDP + help + Allow to set the SO_REUSEADDR flag on a socket. This enables multiple + sockets to bind to the same local IP address. + config NET_TEST bool "Network Testing" help diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 1372398185a..ff7a1420108 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -60,10 +60,51 @@ static struct net_context contexts[NET_MAX_CONTEXT]; */ static struct k_sem contexts_lock; +bool net_context_is_reuseaddr_set(struct net_context *context) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEADDR) + return context->options.reuseaddr; +#else + return false; +#endif +} + #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) +static inline bool is_in_tcp_listen_state(struct net_context *context) +{ +#if defined(CONFIG_NET_TCP) + if (net_context_get_type(context) == SOCK_STREAM && + net_context_get_state(context) == NET_CONTEXT_LISTENING) { + return true; + } + + return false; +#else + return false; +#endif +} + +static inline bool is_in_tcp_time_wait_state(struct net_context *context) +{ +#if defined(CONFIG_NET_TCP) + if (net_context_get_type(context) == SOCK_STREAM) { + const struct tcp *tcp_conn = context->tcp; + + if (net_tcp_get_state(tcp_conn) == TCP_TIME_WAIT) { + return true; + } + } + + return false; +#else + return false; +#endif +} + static int check_used_port(enum net_ip_protocol proto, uint16_t local_port, - const struct sockaddr *local_addr) + const struct sockaddr *local_addr, + bool reuseaddr_set) { int i; @@ -85,12 +126,41 @@ static int check_used_port(enum net_ip_protocol proto, continue; } + if ((net_ipv6_is_addr_unspecified( + net_sin6_ptr(&contexts[i].local)->sin6_addr) || + net_ipv6_is_addr_unspecified( + &net_sin6(local_addr)->sin6_addr))) { + if (reuseaddr_set && + !is_in_tcp_listen_state(&contexts[i]) && + !(net_ipv6_is_addr_unspecified( + net_sin6_ptr(&contexts[i].local)->sin6_addr) && + net_ipv6_is_addr_unspecified( + &net_sin6(local_addr)->sin6_addr))) { + /* In case of REUSEADDR, only one context may be + * bound to the unspecified address, but not both. + * Furthermore, in case the existing context is in + * TCP LISTEN state, we ignore the REUSEADDR option + * (Linux behavior). + */ + continue; + } else { + return -EEXIST; + } + } + if (net_ipv6_addr_cmp( net_sin6_ptr(&contexts[i].local)-> sin6_addr, &((struct sockaddr_in6 *) local_addr)->sin6_addr)) { - return -EEXIST; + if (reuseaddr_set && is_in_tcp_time_wait_state(&contexts[i])) { + /* With REUSEADDR, the existing context must be + * in the TCP TIME_WAIT state. + */ + continue; + } else { + return -EEXIST; + } } } else if (IS_ENABLED(CONFIG_NET_IPV4) && local_addr->sa_family == AF_INET) { @@ -98,12 +168,41 @@ static int check_used_port(enum net_ip_protocol proto, continue; } + if ((net_ipv4_is_addr_unspecified( + net_sin_ptr(&contexts[i].local)->sin_addr) || + net_ipv4_is_addr_unspecified( + &net_sin(local_addr)->sin_addr))) { + if (reuseaddr_set && + !is_in_tcp_listen_state(&contexts[i]) && + !(net_ipv4_is_addr_unspecified( + net_sin_ptr(&contexts[i].local)->sin_addr) && + net_ipv4_is_addr_unspecified( + &net_sin(local_addr)->sin_addr))) { + /* In case of REUSEADDR, only one context may be + * bound to the unspecified address, but not both. + * Furthermore, in case the existing context is in + * TCP LISTEN state, we ignore the REUSEADDR option + * (Linux behavior). + */ + continue; + } else { + return -EEXIST; + } + } + if (net_ipv4_addr_cmp( net_sin_ptr(&contexts[i].local)-> sin_addr, &((struct sockaddr_in *) local_addr)->sin_addr)) { - return -EEXIST; + if (reuseaddr_set && is_in_tcp_time_wait_state(&contexts[i])) { + /* With REUSEADDR, the existing context must be + * in the TCP TIME_WAIT state. + */ + continue; + } else { + return -EEXIST; + } } } } @@ -119,7 +218,7 @@ static uint16_t find_available_port(struct net_context *context, do { local_port = sys_rand32_get() | 0x8000; } while (check_used_port(net_context_get_proto(context), - htons(local_port), addr) == -EEXIST); + htons(local_port), addr, false) == -EEXIST); return htons(local_port); } @@ -132,7 +231,7 @@ bool net_context_port_in_use(enum net_ip_protocol proto, uint16_t local_port, const struct sockaddr *local_addr) { - return check_used_port(proto, htons(local_port), local_addr) != 0; + return check_used_port(proto, htons(local_port), local_addr, false) != 0; } #if defined(CONFIG_NET_CONTEXT_CHECK) @@ -591,15 +690,18 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, net_sin6_ptr(&context->local)->sin6_family = AF_INET6; net_sin6_ptr(&context->local)->sin6_addr = ptr; if (addr6->sin6_port) { - ret = check_used_port(AF_INET6, addr6->sin6_port, - addr); - if (!ret) { - net_sin6_ptr(&context->local)->sin6_port = - addr6->sin6_port; - } else { + ret = check_used_port(context->proto, + addr6->sin6_port, + addr, + net_context_is_reuseaddr_set(context)); + if (ret != 0) { NET_ERR("Port %d is in use!", ntohs(addr6->sin6_port)); + ret = -EADDRINUSE; goto unlock_ipv6; + } else { + net_sin6_ptr(&context->local)->sin6_port = + addr6->sin6_port; } } else { addr6->sin6_port = @@ -689,15 +791,18 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, net_sin_ptr(&context->local)->sin_family = AF_INET; net_sin_ptr(&context->local)->sin_addr = ptr; if (addr4->sin_port) { - ret = check_used_port(AF_INET, addr4->sin_port, - addr); - if (!ret) { - net_sin_ptr(&context->local)->sin_port = - addr4->sin_port; - } else { + ret = check_used_port(context->proto, + addr4->sin_port, + addr, + net_context_is_reuseaddr_set(context)); + if (ret != 0) { NET_ERR("Port %d is in use!", ntohs(addr4->sin_port)); + ret = -EADDRINUSE; goto unlock_ipv4; + } else { + net_sin_ptr(&context->local)->sin_port = + addr4->sin_port; } } else { addr4->sin_port = @@ -1309,6 +1414,32 @@ static int get_context_dscp_ecn(struct net_context *context, #endif } +static int get_context_reuseaddr(struct net_context *context, + void *value, size_t *len) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEADDR) + if (!value || !len) { + return -EINVAL; + } + + if (*len != sizeof(int)) { + return -EINVAL; + } + + if (context->options.reuseaddr == true) { + *((int *)value) = (int) true; + } else { + *((int *)value) = (int) false; + } + + *len = sizeof(int); + + return 0; +#else + return -ENOTSUP; +#endif +} + /* If buf is not NULL, then use it. Otherwise read the data to be written * to net_pkt from msghdr. */ @@ -2363,6 +2494,28 @@ static int set_context_dscp_ecn(struct net_context *context, #endif } +static int set_context_reuseaddr(struct net_context *context, + const void *value, size_t len) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEADDR) + bool reuseaddr = false; + + if (len != sizeof(int)) { + return -EINVAL; + } + + if (*((int *) value) != 0) { + reuseaddr = true; + } + + context->options.reuseaddr = reuseaddr; + + return 0; +#else + return -ENOTSUP; +#endif +} + int net_context_set_option(struct net_context *context, enum net_context_option option, const void *value, size_t len) @@ -2402,6 +2555,9 @@ int net_context_set_option(struct net_context *context, case NET_OPT_DSCP_ECN: ret = set_context_dscp_ecn(context, value, len); break; + case NET_OPT_REUSEADDR: + ret = set_context_reuseaddr(context, value, len); + break; } k_mutex_unlock(&context->lock); @@ -2448,6 +2604,9 @@ int net_context_get_option(struct net_context *context, case NET_OPT_DSCP_ECN: ret = get_context_dscp_ecn(context, value, len); break; + case NET_OPT_REUSEADDR: + ret = get_context_reuseaddr(context, value, len); + break; } k_mutex_unlock(&context->lock); diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index be0466fc98b..305dd66a98a 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -58,6 +58,7 @@ extern void net_process_tx_packet(struct net_pkt *pkt); #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD) extern void net_context_init(void); extern const char *net_context_state(struct net_context *context); +extern bool net_context_is_reuseaddr_set(struct net_context *context); extern void net_pkt_init(void); extern void net_tc_tx_init(void); extern void net_tc_rx_init(void); @@ -71,6 +72,11 @@ static inline const char *net_context_state(struct net_context *context) ARG_UNUSED(context); return NULL; } +static inline bool net_context_is_reuseaddr_set(struct net_context *context) +{ + ARG_UNUSED(context); + return false; +} #endif #if defined(CONFIG_NET_NATIVE) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index ad9cd1e4c98..4f59ad40758 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1923,6 +1923,26 @@ static struct tcp *tcp_conn_new(struct net_pkt *pkt) goto err; } + /* The newly created context object for the new TCP client connection needs + * all four parameters of the tuple (local address, local port, remote + * address, remote port) to be properly identified. Remote address and port + * are already copied above from conn->dst. The call to net_context_bind + * with the prepared local_addr further copies the local address. However, + * this call wont copy the local port, as the bind would then fail due to + * an address/port reuse without the REUSEPORT option enables for both + * connections. Therefore, we copy the port after the bind call. + * It is safe to bind to this address/port combination, as the new TCP + * client connection is separated from the local listening connection + * by the specified remote address and remote port. + */ + if (IS_ENABLED(CONFIG_NET_IPV6) && + net_context_get_family(context) == AF_INET6) { + net_sin6_ptr(&context->local)->sin6_port = conn->src.sin6.sin6_port; + } else if (IS_ENABLED(CONFIG_NET_IPV4) && + net_context_get_family(context) == AF_INET) { + net_sin_ptr(&context->local)->sin_port = conn->src.sin.sin_port; + } + if (!(IS_ENABLED(CONFIG_NET_TEST_PROTOCOL) || IS_ENABLED(CONFIG_NET_TEST))) { conn->seq = tcp_init_isn(&local_addr, &context->remote); diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index facc509acaf..d2df178464b 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2013,6 +2013,20 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname, return 0; } break; + + case SO_REUSEADDR: + if (IS_ENABLED(CONFIG_NET_CONTEXT_REUSEADDR)) { + ret = net_context_get_option(ctx, + NET_OPT_REUSEADDR, + optval, optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + break; } break; @@ -2149,10 +2163,19 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, break; case SO_REUSEADDR: - /* Ignore for now. Provided to let port - * existing apps. - */ - return 0; + if (IS_ENABLED(CONFIG_NET_CONTEXT_REUSEADDR)) { + ret = net_context_set_option(ctx, + NET_OPT_REUSEADDR, + optval, optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + + break; case SO_PRIORITY: if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { From 795c96494ab56c5e2d79641bd8f5ed590f7139c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Fri, 1 Sep 2023 10:50:57 +0200 Subject: [PATCH 0698/4498] tests: net: sockets: add tests for SO_REUSEADDR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds unit tests for the SO_REUSEADDR socket option to test the different possible scenarios for the option to work correctly. There is also a fix for the TCP testsuite to make a now failing test pass again due to a TIME_WAIT socket. Signed-off-by: Tobias Frauenschläger --- tests/net/socket/reuseaddr/CMakeLists.txt | 8 + tests/net/socket/reuseaddr/prj.conf | 55 +++ tests/net/socket/reuseaddr/src/main.c | 473 ++++++++++++++++++++++ tests/net/socket/reuseaddr/testcase.yaml | 20 + tests/net/socket/tcp/src/main.c | 8 +- 5 files changed, 561 insertions(+), 3 deletions(-) create mode 100644 tests/net/socket/reuseaddr/CMakeLists.txt create mode 100644 tests/net/socket/reuseaddr/prj.conf create mode 100644 tests/net/socket/reuseaddr/src/main.c create mode 100644 tests/net/socket/reuseaddr/testcase.yaml diff --git a/tests/net/socket/reuseaddr/CMakeLists.txt b/tests/net/socket/reuseaddr/CMakeLists.txt new file mode 100644 index 00000000000..eaa76e6a460 --- /dev/null +++ b/tests/net/socket/reuseaddr/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(socket-reuseaddr_reuseport) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/socket/reuseaddr/prj.conf b/tests/net/socket/reuseaddr/prj.conf new file mode 100644 index 00000000000..c820fefa199 --- /dev/null +++ b/tests/net/socket/reuseaddr/prj.conf @@ -0,0 +1,55 @@ +# General config +CONFIG_NEWLIB_LIBC=y + +# Networking config +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_NET_DRIVERS=y +CONFIG_NET_LOOPBACK=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=y +CONFIG_NET_UDP=y +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETS_POSIX_NAMES=y +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_IPV6_ND=n +CONFIG_NET_ARP=n + +CONFIG_NET_PKT_RX_COUNT=16 +CONFIG_NET_PKT_TX_COUNT=16 +CONFIG_NET_BUF_RX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=64 + +CONFIG_NET_CONTEXT_REUSEADDR=y + +CONFIG_NET_HOSTNAME_ENABLE=y +CONFIG_NET_HOSTNAME="ztest_hostname" + +CONFIG_POSIX_MAX_FDS=8 +CONFIG_NET_MAX_CONN=10 +CONFIG_NET_MAX_CONTEXTS=10 + +# Network driver config +CONFIG_TEST_RANDOM_GENERATOR=y + +# Reduce the retry count, so the close always finishes within a second +CONFIG_NET_TCP_RETRY_COUNT=3 +CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT=120 + +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=4096 + +# User mode requirements +CONFIG_TEST_USERSPACE=y +CONFIG_HEAP_MEM_POOL_SIZE=8192 + +# If you want to debug the tests, you can get logging using these statements +# CONFIG_LOG=y +# CONFIG_LOG_MODE_DEFERRED=y +# CONFIG_NET_LOG=y +# CONFIG_NET_TCP_LOG_LEVEL_DBG=y diff --git a/tests/net/socket/reuseaddr/src/main.c b/tests/net/socket/reuseaddr/src/main.c new file mode 100644 index 00000000000..1dc41fb72d1 --- /dev/null +++ b/tests/net/socket/reuseaddr/src/main.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2019 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include +#include +#include +#include + +#include +#include + +#include "../../socket_helpers.h" + +#define TEST_IPV4_ANY_ADDR "0.0.0.0" +#define TEST_MY_IPV4_ADDR "192.0.2.1" +#define TEST_MY_IPV4_ADDR2 "192.0.2.2" + +#define TEST_IPV6_ANY_ADDR "::" +#define TEST_MY_IPV6_ADDR "2001:db8::1" +#define TEST_MY_IPV6_ADDR2 "2001:db8::2" + +#define LOCAL_PORT 4242 + +#define TCP_TEARDOWN_TIMEOUT K_SECONDS(3) + +#define SHOULD_SUCCEED true +#define SHOULD_FAIL false + +static inline void prepare_sock_tcp(sa_family_t family, const char *addr, uint16_t port, + int *sock, struct sockaddr *sockaddr) +{ + if (family == AF_INET) { + prepare_sock_tcp_v4(addr, + port, + sock, + (struct sockaddr_in *) sockaddr); + } else if (family == AF_INET6) { + prepare_sock_tcp_v6(addr, + port, + sock, + (struct sockaddr_in6 *) sockaddr); + } +} + +static void test_getsocketopt_reuseaddr(int sock, void *optval, socklen_t *optlen) +{ + zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), + 0, + "getsocketopt() failed with error %d", errno); +} + +static void test_setsocketopt_reuseaddr(int sock, void *optval, socklen_t optlen) +{ + zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), + 0, + "setsocketopt() failed with error %d", errno); +} + +static void test_enable_reuseaddr(int sock) +{ + int value = 1; + + test_setsocketopt_reuseaddr(sock, &value, sizeof(value)); +} + +static void test_add_local_ip_address(sa_family_t family, const char *ip) +{ + if (family == AF_INET) { + struct sockaddr_in addr; + + zsock_inet_pton(AF_INET, ip, &addr.sin_addr); + + zassert_not_null(net_if_ipv4_addr_add(net_if_get_default(), + &addr.sin_addr, + NET_ADDR_MANUAL, + 0), + "Cannot add IPv4 address %s", ip); + } else if (family == AF_INET6) { + struct sockaddr_in6 addr; + + zsock_inet_pton(AF_INET6, ip, &addr.sin6_addr); + + zassert_not_null(net_if_ipv6_addr_add(net_if_get_default(), + &addr.sin6_addr, + NET_ADDR_MANUAL, + 0), + "Cannot add IPv6 address %s", ip); + } +} + +static void test_bind_success(int sock, const struct sockaddr * addr, socklen_t addrlen) +{ + zassert_equal(bind(sock, addr, addrlen), + 0, + "bind() failed with error %d", errno); +} + +static void test_bind_fail(int sock, const struct sockaddr * addr, socklen_t addrlen) +{ + zassert_equal(bind(sock, addr, addrlen), + -1, + "bind() succeeded incorrectly"); + + zassert_equal(errno, EADDRINUSE, "bind() returned unexpected errno (%d)", errno); +} + +static void test_listen(int sock) +{ + zassert_equal(listen(sock, 0), + 0, + "listen() failed with error %d", errno); +} + +static void test_connect(int sock, const struct sockaddr * addr, socklen_t addrlen) +{ + zassert_equal(connect(sock, addr, addrlen), + 0, + "connect() failed with error %d", errno); + + if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) { + /* Let the connection proceed */ + k_msleep(50); + } +} + +static int test_accept(int sock, struct sockaddr * addr, socklen_t * addrlen) +{ + int new_sock = accept(sock, addr, addrlen); + + zassert_not_equal(new_sock, -1, "accept() failed with error %d", errno); + + return new_sock; +} + +static void calc_net_context(struct net_context *context, void *user_data) +{ + int *count = user_data; + + (*count)++; +} + +/* Wait until the number of TCP contexts reaches a certain level + * exp_num_contexts : The number of contexts to wait for + * timeout : The time to wait for + */ +int wait_for_n_tcp_contexts(int exp_num_contexts, k_timeout_t timeout) +{ + uint32_t start_time = k_uptime_get_32(); + uint32_t time_diff; + int context_count = 0; + + /* After the client socket closing, the context count should be 1 less */ + net_context_foreach(calc_net_context, &context_count); + + time_diff = k_uptime_get_32() - start_time; + + /* Eventually the client socket should be cleaned up */ + while (context_count != exp_num_contexts) { + context_count = 0; + net_context_foreach(calc_net_context, &context_count); + k_sleep(K_MSEC(50)); + time_diff = k_uptime_get_32() - start_time; + + if (K_MSEC(time_diff).ticks > timeout.ticks) { + return -ETIMEDOUT; + } + } + + return 0; +} + +static void test_context_cleanup(void) +{ + zassert_equal(wait_for_n_tcp_contexts(0, TCP_TEARDOWN_TIMEOUT), + 0, + "Not all TCP contexts properly cleaned up"); +} + + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_enable_disable) +{ + int server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(server_sock >= 0, "socket open failed"); + + int value = -1; + size_t value_size = sizeof(int); + + /* Read initial value */ + test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); + zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()"); + zassert_equal(value, (int) false, "SO_REUSEADDR incorrectly set (expected false)"); + + /* Enable option */ + value = 1; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 2; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 0x100; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = -1; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + close(server_sock); + + test_context_cleanup(); +} + + +static void test_reuseaddr_unspecified_specified_common(sa_family_t family, + char const *first_ip, + char const *second_ip, + bool should_succeed) +{ + int server_sock1 = -1; + int server_sock2 = -1; + + struct sockaddr bind_addr1; + struct sockaddr bind_addr2; + + /* Create the sockets */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); + + /* Bind the first socket */ + test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); + + /* Try to bind the second socket, should fail */ + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + + /* Enable SO_REUSEADDR option for the second socket */ + test_enable_reuseaddr(server_sock2); + + /* Try to bind the second socket again */ + if (should_succeed) { + test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } else { + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } + + close(server_sock1); + close(server_sock2); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_first_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_first_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_second_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_second_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_both_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_both_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_FAIL); +} + + +static void test_reuseaddr_tcp_listening_common(sa_family_t family, + char const *first_ip, + char const *second_ip) +{ + int server_sock1 = -1; + int server_sock2 = -1; + + struct sockaddr bind_addr1; + struct sockaddr bind_addr2; + + /* Create the sockets */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); + + /* Bind the first socket */ + test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); + + /* Set the first socket to LISTEN state */ + test_listen(server_sock1); + + /* Enable SO_REUSEADDR option for the second socket */ + test_enable_reuseaddr(server_sock2); + + /* Try to bind the second socket, should fail */ + test_bind_fail(server_sock2, (struct sockaddr *) &bind_addr2, sizeof(bind_addr2)); + + close(server_sock1); + close(server_sock2); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_unspecified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_unspecified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_specified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_specified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR); +} + + +static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family, + char const *first_ip, + char const *second_ip) +{ + int server_sock = -1; + int client_sock = -1; + int accept_sock = -1; + + struct sockaddr bind_addr; + struct sockaddr conn_addr; + + struct sockaddr accept_addr; + socklen_t accept_addrlen = sizeof(accept_addr); + + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &client_sock, &conn_addr); + + /* Bind the server socket */ + test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + /* Start listening on the server socket */ + test_listen(server_sock); + + /* Connect the client */ + test_connect(client_sock, &conn_addr, sizeof(conn_addr)); + + /* Accept the client */ + accept_sock = test_accept(server_sock, &accept_addr, &accept_addrlen); + + /* Close the server socket */ + close(server_sock); + + /* Close the accepted socket */ + close(accept_sock); + + /* Wait a short time for the accept socket to enter TIME_WAIT state*/ + k_msleep(50); + + /* Recreate the server socket */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); + + /* Bind the server socket, should fail */ + test_bind_fail(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + /* Enable SO_REUSEADDR option for the new server socket */ + test_enable_reuseaddr(server_sock); + + /* Try to bind the new server socket again, should work now */ + test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + close(client_sock); + close(server_sock); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_time_wait_unspecified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_time_wait_unspecified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_time_wait_specified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_time_wait_specified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_MY_IPV6_ADDR); +} + + +static void *setup(void) +{ + /* Make sure that both the specified IPv4 and IPv6 addresses are + * added to the network interface. + */ + test_add_local_ip_address(AF_INET, TEST_MY_IPV4_ADDR); + test_add_local_ip_address(AF_INET6, TEST_MY_IPV6_ADDR); + + return NULL; +} + + +ZTEST_SUITE(socket_reuseaddr_reuseport_test_suite, NULL, setup, NULL, NULL, NULL); diff --git a/tests/net/socket/reuseaddr/testcase.yaml b/tests/net/socket/reuseaddr/testcase.yaml new file mode 100644 index 00000000000..b2d864d934c --- /dev/null +++ b/tests/net/socket/reuseaddr/testcase.yaml @@ -0,0 +1,20 @@ +common: + depends_on: netif + filter: TOOLCHAIN_HAS_NEWLIB == 1 + min_ram: 31 + tags: + - net + - socket + # FIXME: This test fails very frequently on mps2_an385 due to the system + # timer stability issues, so keep it disabled until the root cause + # is fixed (GitHub issue zephyrproject-rtos/zephyr#48608). + platform_exclude: mps2_an385 +tests: + net.socket.reuseaddr_reuseport: + extra_configs: + - CONFIG_TEST_USERSPACE=n + net.socket.reuseaddr_reuseport.userspace: + extra_configs: + - CONFIG_TEST_USERSPACE=y + # FIXME: This test fails with an unknown error on qemu_x86 + platform_exclude: qemu_x86 diff --git a/tests/net/socket/tcp/src/main.c b/tests/net/socket/tcp/src/main.c index 38ba5ae81ad..5095e6512a7 100644 --- a/tests/net/socket/tcp/src/main.c +++ b/tests/net/socket/tcp/src/main.c @@ -31,21 +31,21 @@ static void test_bind(int sock, struct sockaddr *addr, socklen_t addrlen) { zassert_equal(bind(sock, addr, addrlen), 0, - "bind failed"); + "bind failed with error %d", errno); } static void test_listen(int sock) { zassert_equal(listen(sock, MAX_CONNS), 0, - "listen failed"); + "listen failed with error %d", errno); } static void test_connect(int sock, struct sockaddr *addr, socklen_t addrlen) { zassert_equal(connect(sock, addr, addrlen), 0, - "connect failed"); + "connect failed with error %d", errno); if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) { /* Let the connection proceed */ @@ -554,6 +554,8 @@ ZTEST(net_socket_tcp, test_v4_broken_link) test_close(s_sock); restore_packet_loss_ratio(); + + k_sleep(TCP_TEARDOWN_TIMEOUT); } ZTEST_USER(net_socket_tcp, test_v4_sendto_recvfrom) From dcc63120cf2cd8ee138e9f51750b0349e89c4130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Fri, 1 Sep 2023 11:22:13 +0200 Subject: [PATCH 0699/4498] net: sockets: add support for SO_REUSEPORT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commits adds support for the SO_REUSEPORT socket option. The implementation follows the behavior of BSD and tries to also follow the specific additional features of linux with the following limitations: * SO_REUSEADDR and SO_REUSEPORT are not "the same" for client sockets, as we do not have a trivial way so identify a socket as "client" during binding. To get the Linux behavior, one has to use SO_REUSEPORT with Zephyr * No prevention of "port hijacking" * No support for the load balancing stuff for incoming packets/connections There is also a new Kconfig option to control this feature, which is enabled by default if TCP or UDP is enabled. Signed-off-by: Tobias Frauenschläger --- include/zephyr/net/net_context.h | 4 + include/zephyr/net/socket.h | 2 +- subsys/net/ip/Kconfig | 7 ++ subsys/net/ip/connection.c | 83 +++++++++++---------- subsys/net/ip/net_context.c | 122 +++++++++++++++++++++++++++---- subsys/net/ip/net_private.h | 6 ++ subsys/net/lib/sockets/sockets.c | 29 ++++++++ 7 files changed, 195 insertions(+), 58 deletions(-) diff --git a/include/zephyr/net/net_context.h b/include/zephyr/net/net_context.h index 362d350ba8b..78a88aec0fe 100644 --- a/include/zephyr/net/net_context.h +++ b/include/zephyr/net/net_context.h @@ -325,6 +325,9 @@ __net_socket struct net_context { #endif #if defined(CONFIG_NET_CONTEXT_REUSEADDR) bool reuseaddr; +#endif +#if defined(CONFIG_NET_CONTEXT_REUSEPORT) + bool reuseport; #endif } options; @@ -1077,6 +1080,7 @@ enum net_context_option { NET_OPT_SNDBUF = 7, NET_OPT_DSCP_ECN = 8, NET_OPT_REUSEADDR = 9, + NET_OPT_REUSEPORT = 10, }; /** diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index a7bfcbb8347..f12622e5df5 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -1035,7 +1035,7 @@ struct ifreq { #define SO_OOBINLINE 10 /** sockopt: Socket lingers on close (ignored, for compatibility) */ #define SO_LINGER 13 -/** sockopt: Allow multiple sockets to reuse a single port (ignored, for compatibility) */ +/** sockopt: Allow multiple sockets to reuse a single port */ #define SO_REUSEPORT 15 /** sockopt: Receive low watermark (ignored, for compatibility) */ diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index be519e1f34c..74f53293983 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -696,6 +696,13 @@ config NET_CONTEXT_REUSEADDR Allow to set the SO_REUSEADDR flag on a socket. This enables multiple sockets to bind to the same local IP address. +config NET_CONTEXT_REUSEPORT + bool "Add REUSEPORT support to net_context" + default y if NET_TCP || NET_UDP + help + Allow to set the SO_REUSEPORT flag on a socket. This enables multiple + sockets to bind to the same local IP address and port combination. + config NET_TEST bool "Network Testing" help diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 225a3fdbaad..be1366b32ca 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -158,7 +158,8 @@ static struct net_conn *conn_find_handler(uint16_t proto, uint8_t family, const struct sockaddr *remote_addr, const struct sockaddr *local_addr, uint16_t remote_port, - uint16_t local_port) + uint16_t local_port, + bool reuseport_set) { struct net_conn *conn; struct net_conn *tmp; @@ -174,67 +175,75 @@ static struct net_conn *conn_find_handler(uint16_t proto, uint8_t family, continue; } - if (remote_addr) { - if (!(conn->flags & NET_CONN_REMOTE_ADDR_SET)) { + if (local_addr) { + if (!(conn->flags & NET_CONN_LOCAL_ADDR_SET)) { continue; } if (IS_ENABLED(CONFIG_NET_IPV6) && - remote_addr->sa_family == AF_INET6 && - remote_addr->sa_family == - conn->remote_addr.sa_family) { + local_addr->sa_family == AF_INET6 && + local_addr->sa_family == + conn->local_addr.sa_family) { if (!net_ipv6_addr_cmp( - &net_sin6(remote_addr)->sin6_addr, - &net_sin6(&conn->remote_addr)-> + &net_sin6(local_addr)->sin6_addr, + &net_sin6(&conn->local_addr)-> sin6_addr)) { continue; } } else if (IS_ENABLED(CONFIG_NET_IPV4) && - remote_addr->sa_family == AF_INET && - remote_addr->sa_family == - conn->remote_addr.sa_family) { + local_addr->sa_family == AF_INET && + local_addr->sa_family == + conn->local_addr.sa_family) { if (!net_ipv4_addr_cmp( - &net_sin(remote_addr)->sin_addr, - &net_sin(&conn->remote_addr)-> + &net_sin(local_addr)->sin_addr, + &net_sin(&conn->local_addr)-> sin_addr)) { continue; } } else { continue; } - } else if (conn->flags & NET_CONN_REMOTE_ADDR_SET) { + } else if (conn->flags & NET_CONN_LOCAL_ADDR_SET) { continue; } - if (local_addr) { - if (!(conn->flags & NET_CONN_LOCAL_ADDR_SET)) { + if (net_sin(&conn->local_addr)->sin_port != + htons(local_port)) { + continue; + } + + if (remote_addr) { + if (!(conn->flags & NET_CONN_REMOTE_ADDR_SET)) { continue; } if (IS_ENABLED(CONFIG_NET_IPV6) && - local_addr->sa_family == AF_INET6 && - local_addr->sa_family == - conn->local_addr.sa_family) { + remote_addr->sa_family == AF_INET6 && + remote_addr->sa_family == + conn->remote_addr.sa_family) { if (!net_ipv6_addr_cmp( - &net_sin6(local_addr)->sin6_addr, - &net_sin6(&conn->local_addr)-> + &net_sin6(remote_addr)->sin6_addr, + &net_sin6(&conn->remote_addr)-> sin6_addr)) { continue; } } else if (IS_ENABLED(CONFIG_NET_IPV4) && - local_addr->sa_family == AF_INET && - local_addr->sa_family == - conn->local_addr.sa_family) { + remote_addr->sa_family == AF_INET && + remote_addr->sa_family == + conn->remote_addr.sa_family) { if (!net_ipv4_addr_cmp( - &net_sin(local_addr)->sin_addr, - &net_sin(&conn->local_addr)-> + &net_sin(remote_addr)->sin_addr, + &net_sin(&conn->remote_addr)-> sin_addr)) { continue; } } else { continue; } - } else if (conn->flags & NET_CONN_LOCAL_ADDR_SET) { + } else if (conn->flags & NET_CONN_REMOTE_ADDR_SET) { + continue; + } else if (reuseport_set && conn->context != NULL && + net_context_is_reuseport_set(conn->context)) { continue; } @@ -243,11 +252,6 @@ static struct net_conn *conn_find_handler(uint16_t proto, uint8_t family, continue; } - if (net_sin(&conn->local_addr)->sin_port != - htons(local_port)) { - continue; - } - k_mutex_unlock(&conn_lock); return conn; } @@ -270,10 +274,13 @@ int net_conn_register(uint16_t proto, uint8_t family, uint8_t flags = 0U; conn = conn_find_handler(proto, family, remote_addr, local_addr, - remote_port, local_port); + remote_port, local_port, + context != NULL ? + net_context_is_reuseport_set(context) : + false); if (conn) { NET_ERR("Identical connection handler %p already found.", conn); - return -EALREADY; + return -EADDRINUSE; } conn = conn_get_unused(); @@ -736,14 +743,6 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, continue; /* wrong local address */ } - /* If we have an existing best_match, and that one - * specifies a remote port, then we've matched to a - * LISTENING connection that we should not override. - */ - if (best_match != NULL && best_match->flags & NET_CONN_REMOTE_PORT_SPEC) { - continue; /* do not override listening connection */ - } - if (best_rank < NET_CONN_RANK(conn->flags)) { struct net_pkt *mcast_pkt; diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index ff7a1420108..5bd4122efc6 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -69,6 +69,15 @@ bool net_context_is_reuseaddr_set(struct net_context *context) #endif } +bool net_context_is_reuseport_set(struct net_context *context) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEPORT) + return context->options.reuseport; +#else + return false; +#endif +} + #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) static inline bool is_in_tcp_listen_state(struct net_context *context) { @@ -104,7 +113,8 @@ static inline bool is_in_tcp_time_wait_state(struct net_context *context) static int check_used_port(enum net_ip_protocol proto, uint16_t local_port, const struct sockaddr *local_addr, - bool reuseaddr_set) + bool reuseaddr_set, + bool reuseport_set) { int i; @@ -130,11 +140,17 @@ static int check_used_port(enum net_ip_protocol proto, net_sin6_ptr(&contexts[i].local)->sin6_addr) || net_ipv6_is_addr_unspecified( &net_sin6(local_addr)->sin6_addr))) { - if (reuseaddr_set && - !is_in_tcp_listen_state(&contexts[i]) && - !(net_ipv6_is_addr_unspecified( + if (reuseport_set && + net_context_is_reuseport_set(&contexts[i])) { + /* When both context have the REUSEPORT set, both + * may be unspecified. + */ + continue; + } else if (reuseaddr_set && + !is_in_tcp_listen_state(&contexts[i]) && + !(net_ipv6_is_addr_unspecified( net_sin6_ptr(&contexts[i].local)->sin6_addr) && - net_ipv6_is_addr_unspecified( + net_ipv6_is_addr_unspecified( &net_sin6(local_addr)->sin6_addr))) { /* In case of REUSEADDR, only one context may be * bound to the unspecified address, but not both. @@ -153,7 +169,14 @@ static int check_used_port(enum net_ip_protocol proto, sin6_addr, &((struct sockaddr_in6 *) local_addr)->sin6_addr)) { - if (reuseaddr_set && is_in_tcp_time_wait_state(&contexts[i])) { + if (reuseport_set && + net_context_is_reuseport_set(&contexts[i])) { + /* When both context have the REUSEPORT set, both + * may be bound to exactly the same address. + */ + continue; + } else if (reuseaddr_set && + is_in_tcp_time_wait_state(&contexts[i])) { /* With REUSEADDR, the existing context must be * in the TCP TIME_WAIT state. */ @@ -172,11 +195,17 @@ static int check_used_port(enum net_ip_protocol proto, net_sin_ptr(&contexts[i].local)->sin_addr) || net_ipv4_is_addr_unspecified( &net_sin(local_addr)->sin_addr))) { - if (reuseaddr_set && - !is_in_tcp_listen_state(&contexts[i]) && - !(net_ipv4_is_addr_unspecified( + if (reuseport_set && + net_context_is_reuseport_set(&contexts[i])) { + /* When both context have the REUSEPORT set, both + * may be unspecified. + */ + continue; + } else if (reuseaddr_set && + !is_in_tcp_listen_state(&contexts[i]) && + !(net_ipv4_is_addr_unspecified( net_sin_ptr(&contexts[i].local)->sin_addr) && - net_ipv4_is_addr_unspecified( + net_ipv4_is_addr_unspecified( &net_sin(local_addr)->sin_addr))) { /* In case of REUSEADDR, only one context may be * bound to the unspecified address, but not both. @@ -195,7 +224,14 @@ static int check_used_port(enum net_ip_protocol proto, sin_addr, &((struct sockaddr_in *) local_addr)->sin_addr)) { - if (reuseaddr_set && is_in_tcp_time_wait_state(&contexts[i])) { + if (reuseport_set && + net_context_is_reuseport_set(&contexts[i])) { + /* When both context have the REUSEPORT set, both + * may be bound to exactly the same address. + */ + continue; + } else if (reuseaddr_set && + is_in_tcp_time_wait_state(&contexts[i])) { /* With REUSEADDR, the existing context must be * in the TCP TIME_WAIT state. */ @@ -218,7 +254,7 @@ static uint16_t find_available_port(struct net_context *context, do { local_port = sys_rand32_get() | 0x8000; } while (check_used_port(net_context_get_proto(context), - htons(local_port), addr, false) == -EEXIST); + htons(local_port), addr, false, false) == -EEXIST); return htons(local_port); } @@ -231,7 +267,7 @@ bool net_context_port_in_use(enum net_ip_protocol proto, uint16_t local_port, const struct sockaddr *local_addr) { - return check_used_port(proto, htons(local_port), local_addr, false) != 0; + return check_used_port(proto, htons(local_port), local_addr, false, false) != 0; } #if defined(CONFIG_NET_CONTEXT_CHECK) @@ -693,7 +729,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, ret = check_used_port(context->proto, addr6->sin6_port, addr, - net_context_is_reuseaddr_set(context)); + net_context_is_reuseaddr_set(context), + net_context_is_reuseport_set(context)); if (ret != 0) { NET_ERR("Port %d is in use!", ntohs(addr6->sin6_port)); @@ -794,7 +831,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, ret = check_used_port(context->proto, addr4->sin_port, addr, - net_context_is_reuseaddr_set(context)); + net_context_is_reuseaddr_set(context), + net_context_is_reuseport_set(context)); if (ret != 0) { NET_ERR("Port %d is in use!", ntohs(addr4->sin_port)); @@ -1440,6 +1478,32 @@ static int get_context_reuseaddr(struct net_context *context, #endif } +static int get_context_reuseport(struct net_context *context, + void *value, size_t *len) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEPORT) + if (!value || !len) { + return -EINVAL; + } + + if (*len != sizeof(int)) { + return -EINVAL; + } + + if (context->options.reuseport == true) { + *((int *)value) = (int) true; + } else { + *((int *)value) = (int) false; + } + + *len = sizeof(int); + + return 0; +#else + return -ENOTSUP; +#endif +} + /* If buf is not NULL, then use it. Otherwise read the data to be written * to net_pkt from msghdr. */ @@ -2516,6 +2580,28 @@ static int set_context_reuseaddr(struct net_context *context, #endif } +static int set_context_reuseport(struct net_context *context, + const void *value, size_t len) +{ +#if defined(CONFIG_NET_CONTEXT_REUSEPORT) + bool reuseport = false; + + if (len != sizeof(int)) { + return -EINVAL; + } + + if (*((int *) value) != 0) { + reuseport = true; + } + + context->options.reuseport = reuseport; + + return 0; +#else + return -ENOTSUP; +#endif +} + int net_context_set_option(struct net_context *context, enum net_context_option option, const void *value, size_t len) @@ -2558,6 +2644,9 @@ int net_context_set_option(struct net_context *context, case NET_OPT_REUSEADDR: ret = set_context_reuseaddr(context, value, len); break; + case NET_OPT_REUSEPORT: + ret = set_context_reuseport(context, value, len); + break; } k_mutex_unlock(&context->lock); @@ -2607,6 +2696,9 @@ int net_context_get_option(struct net_context *context, case NET_OPT_REUSEADDR: ret = get_context_reuseaddr(context, value, len); break; + case NET_OPT_REUSEPORT: + ret = get_context_reuseport(context, value, len); + break; } k_mutex_unlock(&context->lock); diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 305dd66a98a..0f573ca1257 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -59,6 +59,7 @@ extern void net_process_tx_packet(struct net_pkt *pkt); extern void net_context_init(void); extern const char *net_context_state(struct net_context *context); extern bool net_context_is_reuseaddr_set(struct net_context *context); +extern bool net_context_is_reuseport_set(struct net_context *context); extern void net_pkt_init(void); extern void net_tc_tx_init(void); extern void net_tc_rx_init(void); @@ -77,6 +78,11 @@ static inline bool net_context_is_reuseaddr_set(struct net_context *context) ARG_UNUSED(context); return false; } +static inline bool net_context_is_reuseport_set(struct net_context *context) +{ + ARG_UNUSED(context); + return false; +} #endif #if defined(CONFIG_NET_NATIVE) diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index d2df178464b..91cf6044c02 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2027,6 +2027,20 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname, return 0; } break; + + case SO_REUSEPORT: + if (IS_ENABLED(CONFIG_NET_CONTEXT_REUSEPORT)) { + ret = net_context_get_option(ctx, + NET_OPT_REUSEPORT, + optval, optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + break; } break; @@ -2177,6 +2191,21 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, break; + case SO_REUSEPORT: + if (IS_ENABLED(CONFIG_NET_CONTEXT_REUSEPORT)) { + ret = net_context_set_option(ctx, + NET_OPT_REUSEPORT, + optval, optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + + break; + case SO_PRIORITY: if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { ret = net_context_set_option(ctx, From 1de4e73e6d62bd90d2533f6333483f7643982119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Fri, 1 Sep 2023 11:24:51 +0200 Subject: [PATCH 0700/4498] tests: net: sockets: add tests for SO_REUSEPORT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds unit tests for the SO_REUSEPORT sockets option. It also fixes some bugs in other tests triggered by the new features. Signed-off-by: Tobias Frauenschläger --- tests/net/socket/misc/src/main.c | 4 +- tests/net/socket/reuseaddr/src/main.c | 473 -------- .../CMakeLists.txt | 0 .../prj.conf | 1 + .../net/socket/reuseaddr_reuseport/src/main.c | 1011 +++++++++++++++++ .../testcase.yaml | 0 6 files changed, 1015 insertions(+), 474 deletions(-) delete mode 100644 tests/net/socket/reuseaddr/src/main.c rename tests/net/socket/{reuseaddr => reuseaddr_reuseport}/CMakeLists.txt (100%) rename tests/net/socket/{reuseaddr => reuseaddr_reuseport}/prj.conf (97%) create mode 100644 tests/net/socket/reuseaddr_reuseport/src/main.c rename tests/net/socket/{reuseaddr => reuseaddr_reuseport}/testcase.yaml (100%) diff --git a/tests/net/socket/misc/src/main.c b/tests/net/socket/misc/src/main.c index c8f31435fd8..384eafe6126 100644 --- a/tests/net/socket/misc/src/main.c +++ b/tests/net/socket/misc/src/main.c @@ -286,6 +286,8 @@ void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr, zassert_equal(ret, 0, "close failed, %d", errno); ret = close(sock_s); zassert_equal(ret, 0, "close failed, %d", errno); + + k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY)); } void test_ipv4_so_bindtodevice(void) @@ -423,7 +425,7 @@ void test_getpeername(int family) ret = close(sock_s); zassert_equal(ret, 0, "close failed, %d", errno); - k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY)); + k_sleep(K_MSEC(2 * CONFIG_NET_TCP_TIME_WAIT_DELAY)); } diff --git a/tests/net/socket/reuseaddr/src/main.c b/tests/net/socket/reuseaddr/src/main.c deleted file mode 100644 index 1dc41fb72d1..00000000000 --- a/tests/net/socket/reuseaddr/src/main.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (c) 2019 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); - -#include -#include -#include -#include - -#include -#include - -#include "../../socket_helpers.h" - -#define TEST_IPV4_ANY_ADDR "0.0.0.0" -#define TEST_MY_IPV4_ADDR "192.0.2.1" -#define TEST_MY_IPV4_ADDR2 "192.0.2.2" - -#define TEST_IPV6_ANY_ADDR "::" -#define TEST_MY_IPV6_ADDR "2001:db8::1" -#define TEST_MY_IPV6_ADDR2 "2001:db8::2" - -#define LOCAL_PORT 4242 - -#define TCP_TEARDOWN_TIMEOUT K_SECONDS(3) - -#define SHOULD_SUCCEED true -#define SHOULD_FAIL false - -static inline void prepare_sock_tcp(sa_family_t family, const char *addr, uint16_t port, - int *sock, struct sockaddr *sockaddr) -{ - if (family == AF_INET) { - prepare_sock_tcp_v4(addr, - port, - sock, - (struct sockaddr_in *) sockaddr); - } else if (family == AF_INET6) { - prepare_sock_tcp_v6(addr, - port, - sock, - (struct sockaddr_in6 *) sockaddr); - } -} - -static void test_getsocketopt_reuseaddr(int sock, void *optval, socklen_t *optlen) -{ - zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), - 0, - "getsocketopt() failed with error %d", errno); -} - -static void test_setsocketopt_reuseaddr(int sock, void *optval, socklen_t optlen) -{ - zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), - 0, - "setsocketopt() failed with error %d", errno); -} - -static void test_enable_reuseaddr(int sock) -{ - int value = 1; - - test_setsocketopt_reuseaddr(sock, &value, sizeof(value)); -} - -static void test_add_local_ip_address(sa_family_t family, const char *ip) -{ - if (family == AF_INET) { - struct sockaddr_in addr; - - zsock_inet_pton(AF_INET, ip, &addr.sin_addr); - - zassert_not_null(net_if_ipv4_addr_add(net_if_get_default(), - &addr.sin_addr, - NET_ADDR_MANUAL, - 0), - "Cannot add IPv4 address %s", ip); - } else if (family == AF_INET6) { - struct sockaddr_in6 addr; - - zsock_inet_pton(AF_INET6, ip, &addr.sin6_addr); - - zassert_not_null(net_if_ipv6_addr_add(net_if_get_default(), - &addr.sin6_addr, - NET_ADDR_MANUAL, - 0), - "Cannot add IPv6 address %s", ip); - } -} - -static void test_bind_success(int sock, const struct sockaddr * addr, socklen_t addrlen) -{ - zassert_equal(bind(sock, addr, addrlen), - 0, - "bind() failed with error %d", errno); -} - -static void test_bind_fail(int sock, const struct sockaddr * addr, socklen_t addrlen) -{ - zassert_equal(bind(sock, addr, addrlen), - -1, - "bind() succeeded incorrectly"); - - zassert_equal(errno, EADDRINUSE, "bind() returned unexpected errno (%d)", errno); -} - -static void test_listen(int sock) -{ - zassert_equal(listen(sock, 0), - 0, - "listen() failed with error %d", errno); -} - -static void test_connect(int sock, const struct sockaddr * addr, socklen_t addrlen) -{ - zassert_equal(connect(sock, addr, addrlen), - 0, - "connect() failed with error %d", errno); - - if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) { - /* Let the connection proceed */ - k_msleep(50); - } -} - -static int test_accept(int sock, struct sockaddr * addr, socklen_t * addrlen) -{ - int new_sock = accept(sock, addr, addrlen); - - zassert_not_equal(new_sock, -1, "accept() failed with error %d", errno); - - return new_sock; -} - -static void calc_net_context(struct net_context *context, void *user_data) -{ - int *count = user_data; - - (*count)++; -} - -/* Wait until the number of TCP contexts reaches a certain level - * exp_num_contexts : The number of contexts to wait for - * timeout : The time to wait for - */ -int wait_for_n_tcp_contexts(int exp_num_contexts, k_timeout_t timeout) -{ - uint32_t start_time = k_uptime_get_32(); - uint32_t time_diff; - int context_count = 0; - - /* After the client socket closing, the context count should be 1 less */ - net_context_foreach(calc_net_context, &context_count); - - time_diff = k_uptime_get_32() - start_time; - - /* Eventually the client socket should be cleaned up */ - while (context_count != exp_num_contexts) { - context_count = 0; - net_context_foreach(calc_net_context, &context_count); - k_sleep(K_MSEC(50)); - time_diff = k_uptime_get_32() - start_time; - - if (K_MSEC(time_diff).ticks > timeout.ticks) { - return -ETIMEDOUT; - } - } - - return 0; -} - -static void test_context_cleanup(void) -{ - zassert_equal(wait_for_n_tcp_contexts(0, TCP_TEARDOWN_TIMEOUT), - 0, - "Not all TCP contexts properly cleaned up"); -} - - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_enable_disable) -{ - int server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - zassert_true(server_sock >= 0, "socket open failed"); - - int value = -1; - size_t value_size = sizeof(int); - - /* Read initial value */ - test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); - zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()"); - zassert_equal(value, (int) false, "SO_REUSEADDR incorrectly set (expected false)"); - - /* Enable option */ - value = 1; - test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); - test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); - zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); - - /* Enable option (with other value as linux takes any int here) */ - value = 2; - test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); - test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); - zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); - - /* Enable option (with other value as linux takes any int here) */ - value = 0x100; - test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); - test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); - zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); - - /* Enable option (with other value as linux takes any int here) */ - value = -1; - test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); - test_getsocketopt_reuseaddr(server_sock, (void *)&value, (socklen_t *)&value_size); - zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); - - close(server_sock); - - test_context_cleanup(); -} - - -static void test_reuseaddr_unspecified_specified_common(sa_family_t family, - char const *first_ip, - char const *second_ip, - bool should_succeed) -{ - int server_sock1 = -1; - int server_sock2 = -1; - - struct sockaddr bind_addr1; - struct sockaddr bind_addr2; - - /* Create the sockets */ - prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); - prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); - - /* Bind the first socket */ - test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); - - /* Try to bind the second socket, should fail */ - test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); - - /* Enable SO_REUSEADDR option for the second socket */ - test_enable_reuseaddr(server_sock2); - - /* Try to bind the second socket again */ - if (should_succeed) { - test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2)); - } else { - test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); - } - - close(server_sock1); - close(server_sock2); - - test_context_cleanup(); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_first_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET, - TEST_IPV4_ANY_ADDR, - TEST_MY_IPV4_ADDR, - SHOULD_SUCCEED); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_first_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET6, - TEST_IPV6_ANY_ADDR, - TEST_MY_IPV6_ADDR, - SHOULD_SUCCEED); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_second_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET, - TEST_MY_IPV4_ADDR, - TEST_IPV4_ANY_ADDR, - SHOULD_SUCCEED); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_second_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET6, - TEST_MY_IPV6_ADDR, - TEST_IPV6_ANY_ADDR, - SHOULD_SUCCEED); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_both_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET, - TEST_IPV4_ANY_ADDR, - TEST_IPV4_ANY_ADDR, - SHOULD_FAIL); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_both_unspecified) -{ - test_reuseaddr_unspecified_specified_common(AF_INET6, - TEST_IPV6_ANY_ADDR, - TEST_IPV6_ANY_ADDR, - SHOULD_FAIL); -} - - -static void test_reuseaddr_tcp_listening_common(sa_family_t family, - char const *first_ip, - char const *second_ip) -{ - int server_sock1 = -1; - int server_sock2 = -1; - - struct sockaddr bind_addr1; - struct sockaddr bind_addr2; - - /* Create the sockets */ - prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); - prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); - - /* Bind the first socket */ - test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); - - /* Set the first socket to LISTEN state */ - test_listen(server_sock1); - - /* Enable SO_REUSEADDR option for the second socket */ - test_enable_reuseaddr(server_sock2); - - /* Try to bind the second socket, should fail */ - test_bind_fail(server_sock2, (struct sockaddr *) &bind_addr2, sizeof(bind_addr2)); - - close(server_sock1); - close(server_sock2); - - test_context_cleanup(); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_unspecified_listening) -{ - test_reuseaddr_tcp_listening_common(AF_INET, - TEST_IPV4_ANY_ADDR, - TEST_MY_IPV4_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_unspecified_listening) -{ - test_reuseaddr_tcp_listening_common(AF_INET6, - TEST_IPV6_ANY_ADDR, - TEST_MY_IPV6_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_specified_listening) -{ - test_reuseaddr_tcp_listening_common(AF_INET, - TEST_MY_IPV4_ADDR, - TEST_IPV4_ANY_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_specified_listening) -{ - test_reuseaddr_tcp_listening_common(AF_INET6, - TEST_MY_IPV6_ADDR, - TEST_IPV6_ANY_ADDR); -} - - -static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family, - char const *first_ip, - char const *second_ip) -{ - int server_sock = -1; - int client_sock = -1; - int accept_sock = -1; - - struct sockaddr bind_addr; - struct sockaddr conn_addr; - - struct sockaddr accept_addr; - socklen_t accept_addrlen = sizeof(accept_addr); - - prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); - prepare_sock_tcp(family, second_ip, LOCAL_PORT, &client_sock, &conn_addr); - - /* Bind the server socket */ - test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); - - /* Start listening on the server socket */ - test_listen(server_sock); - - /* Connect the client */ - test_connect(client_sock, &conn_addr, sizeof(conn_addr)); - - /* Accept the client */ - accept_sock = test_accept(server_sock, &accept_addr, &accept_addrlen); - - /* Close the server socket */ - close(server_sock); - - /* Close the accepted socket */ - close(accept_sock); - - /* Wait a short time for the accept socket to enter TIME_WAIT state*/ - k_msleep(50); - - /* Recreate the server socket */ - prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); - - /* Bind the server socket, should fail */ - test_bind_fail(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); - - /* Enable SO_REUSEADDR option for the new server socket */ - test_enable_reuseaddr(server_sock); - - /* Try to bind the new server socket again, should work now */ - test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); - - close(client_sock); - close(server_sock); - - test_context_cleanup(); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_time_wait_unspecified) -{ - test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, - TEST_IPV4_ANY_ADDR, - TEST_MY_IPV4_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_time_wait_unspecified) -{ - test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, - TEST_IPV6_ANY_ADDR, - TEST_MY_IPV6_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv4_tcp_time_wait_specified) -{ - test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, - TEST_MY_IPV4_ADDR, - TEST_MY_IPV4_ADDR); -} - -ZTEST_USER(socket_reuseaddr_reuseport_test_suite, test_reuseaddr_ipv6_tcp_time_wait_specified) -{ - test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, - TEST_MY_IPV6_ADDR, - TEST_MY_IPV6_ADDR); -} - - -static void *setup(void) -{ - /* Make sure that both the specified IPv4 and IPv6 addresses are - * added to the network interface. - */ - test_add_local_ip_address(AF_INET, TEST_MY_IPV4_ADDR); - test_add_local_ip_address(AF_INET6, TEST_MY_IPV6_ADDR); - - return NULL; -} - - -ZTEST_SUITE(socket_reuseaddr_reuseport_test_suite, NULL, setup, NULL, NULL, NULL); diff --git a/tests/net/socket/reuseaddr/CMakeLists.txt b/tests/net/socket/reuseaddr_reuseport/CMakeLists.txt similarity index 100% rename from tests/net/socket/reuseaddr/CMakeLists.txt rename to tests/net/socket/reuseaddr_reuseport/CMakeLists.txt diff --git a/tests/net/socket/reuseaddr/prj.conf b/tests/net/socket/reuseaddr_reuseport/prj.conf similarity index 97% rename from tests/net/socket/reuseaddr/prj.conf rename to tests/net/socket/reuseaddr_reuseport/prj.conf index c820fefa199..7ff751c8785 100644 --- a/tests/net/socket/reuseaddr/prj.conf +++ b/tests/net/socket/reuseaddr_reuseport/prj.conf @@ -24,6 +24,7 @@ CONFIG_NET_BUF_RX_COUNT=64 CONFIG_NET_BUF_TX_COUNT=64 CONFIG_NET_CONTEXT_REUSEADDR=y +CONFIG_NET_CONTEXT_REUSEPORT=y CONFIG_NET_HOSTNAME_ENABLE=y CONFIG_NET_HOSTNAME="ztest_hostname" diff --git a/tests/net/socket/reuseaddr_reuseport/src/main.c b/tests/net/socket/reuseaddr_reuseport/src/main.c new file mode 100644 index 00000000000..db047ac9cf4 --- /dev/null +++ b/tests/net/socket/reuseaddr_reuseport/src/main.c @@ -0,0 +1,1011 @@ +/* + * Copyright (c) 2019 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include +#include +#include +#include + +#include +#include + +#include "../../socket_helpers.h" + +#define TEST_IPV4_ANY_ADDR "0.0.0.0" +#define TEST_MY_IPV4_ADDR "192.0.2.1" +#define TEST_MY_IPV4_ADDR2 "192.0.2.2" + +#define TEST_IPV6_ANY_ADDR "::" +#define TEST_MY_IPV6_ADDR "2001:db8::1" +#define TEST_MY_IPV6_ADDR2 "2001:db8::2" + +#define LOCAL_PORT 4242 + +#define TCP_TEARDOWN_TIMEOUT K_SECONDS(3) + +#define SHOULD_SUCCEED true +#define SHOULD_FAIL false + +static void test_add_local_ip_address(sa_family_t family, const char *ip) +{ + if (family == AF_INET) { + struct sockaddr_in addr; + + zsock_inet_pton(AF_INET, ip, &addr.sin_addr); + + zassert_not_null(net_if_ipv4_addr_add(net_if_get_default(), + &addr.sin_addr, + NET_ADDR_MANUAL, + 0), + "Cannot add IPv4 address %s", ip); + } else if (family == AF_INET6) { + struct sockaddr_in6 addr; + + zsock_inet_pton(AF_INET6, ip, &addr.sin6_addr); + + zassert_not_null(net_if_ipv6_addr_add(net_if_get_default(), + &addr.sin6_addr, + NET_ADDR_MANUAL, + 0), + "Cannot add IPv6 address %s", ip); + } +} + +static void *setup(void) +{ + /* Make sure that both the specified IPv4 and IPv6 addresses are + * added to the network interface. + */ + test_add_local_ip_address(AF_INET, TEST_MY_IPV4_ADDR); + test_add_local_ip_address(AF_INET6, TEST_MY_IPV6_ADDR); + + return NULL; +} + +static inline void prepare_sock_tcp(sa_family_t family, const char *ip, uint16_t port, + int *sock, struct sockaddr *addr) +{ + if (family == AF_INET) { + prepare_sock_tcp_v4(ip, + port, + sock, + (struct sockaddr_in *) addr); + } else if (family == AF_INET6) { + prepare_sock_tcp_v6(ip, + port, + sock, + (struct sockaddr_in6 *) addr); + } +} + +static inline void prepare_sock_udp(sa_family_t family, const char *ip, uint16_t port, + int *sock, struct sockaddr *addr) +{ + if (family == AF_INET) { + prepare_sock_udp_v4(ip, + port, + sock, + (struct sockaddr_in *) addr); + } else if (family == AF_INET6) { + prepare_sock_udp_v6(ip, + port, + sock, + (struct sockaddr_in6 *) addr); + } +} + +static void test_getsocketopt_reuseaddr(int sock, void *optval, socklen_t *optlen) +{ + zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), + 0, + "getsocketopt() failed with error %d", errno); +} + +static void test_setsocketopt_reuseaddr(int sock, void *optval, socklen_t optlen) +{ + zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen), + 0, + "setsocketopt() failed with error %d", errno); +} + +static void test_enable_reuseaddr(int sock) +{ + int value = 1; + + test_setsocketopt_reuseaddr(sock, &value, sizeof(value)); +} + +static void test_getsocketopt_reuseport(int sock, void *optval, socklen_t *optlen) +{ + zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen), + 0, + "getsocketopt() failed with error %d", errno); +} + +static void test_setsocketopt_reuseport(int sock, void *optval, socklen_t optlen) +{ + zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen), + 0, + "setsocketopt() failed with error %d", errno); +} + +static void test_enable_reuseport(int sock) +{ + int value = 1; + + test_setsocketopt_reuseport(sock, &value, sizeof(value)); +} + +static void test_bind_success(int sock, const struct sockaddr *addr, socklen_t addrlen) +{ + zassert_equal(bind(sock, addr, addrlen), + 0, + "bind() failed with error %d", errno); +} + +static void test_bind_fail(int sock, const struct sockaddr *addr, socklen_t addrlen) +{ + zassert_equal(bind(sock, addr, addrlen), + -1, + "bind() succeeded incorrectly"); + + zassert_equal(errno, EADDRINUSE, "bind() returned unexpected errno (%d)", errno); +} + +static void test_listen(int sock) +{ + zassert_equal(listen(sock, 0), + 0, + "listen() failed with error %d", errno); +} + +static void test_connect_success(int sock, const struct sockaddr *addr, socklen_t addrlen) +{ + zassert_equal(connect(sock, addr, addrlen), + 0, + "connect() failed with error %d", errno); + + if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) { + /* Let the connection proceed */ + k_msleep(50); + } +} + +static void test_connect_fail(int sock, const struct sockaddr *addr, socklen_t addrlen) +{ + zassert_equal(connect(sock, addr, addrlen), + -1, + "connect() succeeded incorrectly"); + + zassert_equal(errno, EADDRINUSE, "connect() returned unexpected errno (%d)", errno); +} + +static int test_accept(int sock, struct sockaddr *addr, socklen_t *addrlen) +{ + int new_sock = accept(sock, addr, addrlen); + + zassert_not_equal(new_sock, -1, "accept() failed with error %d", errno); + + return new_sock; +} + +static void test_sendto(int sock, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + zassert_equal(sendto(sock, buf, len, flags, dest_addr, addrlen), + len, + "sendto failed with error %d", errno); +} + +static void test_recvfrom_success(int sock, void *buf, size_t max_len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + zassert_equal(recvfrom(sock, buf, max_len, flags, src_addr, addrlen), + max_len, + "recvfrom failed with error %d", errno); +} + +static void test_recvfrom_fail(int sock, void *buf, size_t max_len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + zassert_equal(recvfrom(sock, buf, max_len, flags, src_addr, addrlen), + -1, + "recvfrom succeeded incorrectly"); + + zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno); +} + +static void test_recv_success(int sock, void *buf, size_t max_len, int flags) +{ + zassert_equal(recv(sock, buf, max_len, flags), + max_len, + "recv failed with error %d", errno); +} + +static void test_recv_fail(int sock, void *buf, size_t max_len, int flags) +{ + zassert_equal(recv(sock, buf, max_len, flags), + -1, + "recvfrom succeeded incorrectly"); + + zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno); +} + +static void calc_net_context(struct net_context *context, void *user_data) +{ + int *count = user_data; + + (*count)++; +} + +/* Wait until the number of TCP contexts reaches a certain level + * exp_num_contexts : The number of contexts to wait for + * timeout : The time to wait for + */ +int wait_for_n_tcp_contexts(int exp_num_contexts, k_timeout_t timeout) +{ + uint32_t start_time = k_uptime_get_32(); + uint32_t time_diff; + int context_count = 0; + + /* After the client socket closing, the context count should be 1 less */ + net_context_foreach(calc_net_context, &context_count); + + time_diff = k_uptime_get_32() - start_time; + + /* Eventually the client socket should be cleaned up */ + while (context_count != exp_num_contexts) { + context_count = 0; + net_context_foreach(calc_net_context, &context_count); + k_sleep(K_MSEC(50)); + time_diff = k_uptime_get_32() - start_time; + + if (K_MSEC(time_diff).ticks > timeout.ticks) { + return -ETIMEDOUT; + } + } + + return 0; +} + +static void test_context_cleanup(void) +{ + zassert_equal(wait_for_n_tcp_contexts(0, TCP_TEARDOWN_TIMEOUT), + 0, + "Not all TCP contexts properly cleaned up"); +} + + +ZTEST_USER(socket_reuseaddr_test_suite, test_enable_disable) +{ + int server_sock = -1; + int value = -1; + socklen_t value_size = sizeof(int); + + server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(server_sock >= 0, "socket open failed"); + + /* Read initial value */ + test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size); + zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()"); + zassert_equal(value, (int) false, "SO_REUSEADDR incorrectly set (expected false)"); + + /* Enable option */ + value = 1; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 2; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 0x100; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = -1; + test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); + + close(server_sock); + + test_context_cleanup(); +} + + +static void test_reuseaddr_unspecified_specified_common(sa_family_t family, + char const *first_ip, + char const *second_ip, + bool should_succeed) +{ + int server_sock1 = -1; + int server_sock2 = -1; + + struct sockaddr bind_addr1; + struct sockaddr bind_addr2; + + /* Create the sockets */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); + + /* Bind the first socket */ + test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); + + /* Try to bind the second socket, should fail */ + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + + /* Enable SO_REUSEADDR option for the second socket */ + test_enable_reuseaddr(server_sock2); + + /* Try to bind the second socket again */ + if (should_succeed) { + test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } else { + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } + + close(server_sock1); + close(server_sock2); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_first_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_first_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_second_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_second_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_both_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_both_unspecified) +{ + test_reuseaddr_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_FAIL); +} + + +static void test_reuseaddr_tcp_listening_common(sa_family_t family, + char const *first_ip, + char const *second_ip) +{ + int server_sock1 = -1; + int server_sock2 = -1; + + struct sockaddr bind_addr1; + struct sockaddr bind_addr2; + + /* Create the sockets */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); + + /* Bind the first socket */ + test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); + + /* Set the first socket to LISTEN state */ + test_listen(server_sock1); + + /* Enable SO_REUSEADDR option for the second socket */ + test_enable_reuseaddr(server_sock2); + + /* Try to bind the second socket, should fail */ + test_bind_fail(server_sock2, (struct sockaddr *) &bind_addr2, sizeof(bind_addr2)); + + close(server_sock1); + close(server_sock2); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_unspecified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_unspecified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_specified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_specified_listening) +{ + test_reuseaddr_tcp_listening_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR); +} + + +static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family, + char const *first_ip, + char const *second_ip) +{ + int server_sock = -1; + int client_sock = -1; + int accept_sock = -1; + + struct sockaddr bind_addr; + struct sockaddr conn_addr; + + struct sockaddr accept_addr; + socklen_t accept_addrlen = sizeof(accept_addr); + + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &client_sock, &conn_addr); + + /* Bind the server socket */ + test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + /* Start listening on the server socket */ + test_listen(server_sock); + + /* Connect the client */ + test_connect_success(client_sock, &conn_addr, sizeof(conn_addr)); + + /* Accept the client */ + accept_sock = test_accept(server_sock, &accept_addr, &accept_addrlen); + + /* Close the server socket */ + close(server_sock); + + /* Close the accepted socket */ + close(accept_sock); + + /* Wait a short time for the accept socket to enter TIME_WAIT state*/ + k_msleep(50); + + /* Recreate the server socket */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr); + + /* Bind the server socket, should fail */ + test_bind_fail(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + /* Enable SO_REUSEADDR option for the new server socket */ + test_enable_reuseaddr(server_sock); + + /* Try to bind the new server socket again, should work now */ + test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr)); + + close(client_sock); + close(server_sock); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_unspecified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_unspecified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_specified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_MY_IPV4_ADDR); +} + +ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_specified) +{ + test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_MY_IPV6_ADDR); +} + + +ZTEST_SUITE(socket_reuseaddr_test_suite, NULL, setup, NULL, NULL, NULL); + + +ZTEST_USER(socket_reuseport_test_suite, test_enable_disable) +{ + int server_sock = -1; + + int value = -1; + socklen_t value_size = sizeof(int); + + server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(server_sock >= 0, "socket open failed"); + + /* Read initial value */ + test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size); + zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()"); + zassert_equal(value, (int) false, "SO_REUSEPORT incorrectly set (expected false)"); + + /* Enable option */ + value = 1; + test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 2; + test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = 0x100; + test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value); + + /* Enable option (with other value as linux takes any int here) */ + value = -1; + test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value)); + test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size); + zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value); + + close(server_sock); + + test_context_cleanup(); +} + + +static void test_reuseport_unspecified_specified_common(sa_family_t family, + char const *first_ip, + char const *second_ip, + bool should_succeed) +{ + int server_sock1 = -1; + int server_sock2 = -1; + + struct sockaddr bind_addr1; + struct sockaddr bind_addr2; + + /* Create the sockets */ + prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1); + prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2); + + /* Depending on the expected result, we enable SO_REUSEPORT for the first socket */ + if (should_succeed) { + test_enable_reuseport(server_sock1); + } + + /* Bind the first socket */ + test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1)); + + /* Try to bind the second socket, should fail */ + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + + /* Enable SO_REUSEPORT option for the second socket */ + test_enable_reuseport(server_sock2); + + /* Try to bind the second socket again */ + if (should_succeed) { + test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } else { + test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2)); + } + + close(server_sock1); + close(server_sock2); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_bad) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_FAIL); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET, + TEST_MY_IPV4_ADDR, + TEST_IPV4_ANY_ADDR, + SHOULD_SUCCEED); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_good) +{ + test_reuseport_unspecified_specified_common(AF_INET6, + TEST_MY_IPV6_ADDR, + TEST_IPV6_ANY_ADDR, + SHOULD_SUCCEED); +} + + +enum sockets_reuseport_enabled { + NONE_SET = 0, + FIRST_SET, + SECOND_SET, + BOTH_SET +}; + +static void test_reuseport_udp_server_client_common(sa_family_t family, + char const *ip, + enum sockets_reuseport_enabled setup) +{ + int server_sock = -1; + int client_sock = -1; + int accept_sock = 1; + + struct sockaddr server_addr; + struct sockaddr client_addr; + + struct sockaddr accept_addr; + socklen_t accept_addr_len = sizeof(accept_addr); + + char tx_buf = 0x55; + char rx_buf; + + /* Create sockets */ + prepare_sock_udp(family, ip, LOCAL_PORT, &server_sock, &server_addr); + prepare_sock_udp(family, ip, 0, &client_sock, &client_addr); + + /* Make sure we can bind to the address:port */ + if (setup == FIRST_SET || setup == BOTH_SET) { + test_enable_reuseport(server_sock); + } + + /* Bind server socket */ + test_bind_success(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)); + + /* Bind client socket (on a random port) */ + test_bind_success(client_sock, (struct sockaddr *) &client_addr, sizeof(client_addr)); + + /* Send message from client to server */ + test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr)); + + /* Give the packet a chance to go through the net stack */ + k_msleep(50); + + /* Receive data from the client */ + rx_buf = 0; + test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT, + &accept_addr, &accept_addr_len); + zassert_equal(rx_buf, tx_buf, "wrong data"); + + /* Create a more specific socket to have a direct connection to the new client */ + accept_sock = socket(family, SOCK_DGRAM, IPPROTO_UDP); + zassert_true(accept_sock >= 0, "socket open failed"); + + /* Make sure we can bind to the address:port */ + if (setup == SECOND_SET || setup == BOTH_SET) { + test_enable_reuseport(accept_sock); + } + + /* Try to bind new client socket */ + if (setup == BOTH_SET) { + /* Should succeed */ + test_bind_success(accept_sock, (struct sockaddr *) &server_addr, + sizeof(server_addr)); + } else { + /* Should fail */ + test_bind_fail(accept_sock, (struct sockaddr *) &server_addr, + sizeof(server_addr)); + } + + /* Connect the client to set remote address and remote port */ + test_connect_success(accept_sock, &accept_addr, sizeof(accept_addr)); + + /* Send another message from client to server */ + test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr)); + + /* Give the packet a chance to go through the net stack */ + k_msleep(50); + + /* Receive the data */ + if (setup == BOTH_SET) { + /* We should receive data on the new specific socket, not on the general one */ + rx_buf = 0; + test_recvfrom_fail(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT, + &accept_addr, &accept_addr_len); + + rx_buf = 0; + test_recv_success(accept_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT); + } else { + /* We should receive data on the general server socket */ + rx_buf = 0; + test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT, + &accept_addr, &accept_addr_len); + + rx_buf = 0; + test_recv_fail(accept_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT); + } + + close(accept_sock); + close(client_sock); + close(server_sock); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_both_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET, + TEST_MY_IPV4_ADDR, + NONE_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_both_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET6, + TEST_MY_IPV6_ADDR, + NONE_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_first_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET, + TEST_MY_IPV4_ADDR, + SECOND_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_first_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET6, + TEST_MY_IPV6_ADDR, + SECOND_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_second_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET, + TEST_MY_IPV4_ADDR, + FIRST_SET); +} + + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_second_not_set) +{ + test_reuseport_udp_server_client_common(AF_INET6, + TEST_MY_IPV6_ADDR, + FIRST_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_good) +{ + test_reuseport_udp_server_client_common(AF_INET, + TEST_MY_IPV4_ADDR, + BOTH_SET); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_good) +{ + test_reuseport_udp_server_client_common(AF_INET6, + TEST_MY_IPV6_ADDR, + BOTH_SET); +} + + +static void test_reuseport_tcp_identical_clients_common(sa_family_t family, + char const *server_ip, + char const *client_ip) +{ + int server_sock = -1; + int client_sock1 = -1; + int client_sock2 = -1; + int accept_sock = 1; + + struct sockaddr server_addr; + struct sockaddr client_addr; + struct sockaddr connect_addr; + + struct sockaddr accept_addr; + socklen_t accept_addr_len = sizeof(accept_addr); + + /* Create sockets */ + prepare_sock_tcp(family, server_ip, LOCAL_PORT, &server_sock, &server_addr); + prepare_sock_tcp(family, client_ip, LOCAL_PORT + 1, &client_sock1, &client_addr); + prepare_sock_tcp(family, client_ip, LOCAL_PORT, &client_sock2, &connect_addr); + + /* Enable SO_REUSEPORT option for the two sockets */ + test_enable_reuseport(client_sock1); + test_enable_reuseport(client_sock2); + + /* Bind server socket */ + test_bind_success(server_sock, &server_addr, sizeof(server_addr)); + + /* Start listening on the server socket */ + test_listen(server_sock); + + /* Bind the client sockets */ + test_bind_success(client_sock1, &client_addr, sizeof(client_addr)); + test_bind_success(client_sock2, &client_addr, sizeof(client_addr)); + + /* Connect the first client */ + test_connect_success(client_sock1, &connect_addr, sizeof(connect_addr)); + + /* Accept the first client */ + accept_sock = test_accept(server_sock, &accept_addr, &accept_addr_len); + + /* Connect the second client, should fail */ + test_connect_fail(client_sock2, (struct sockaddr *)&connect_addr, sizeof(connect_addr)); + + close(accept_sock); + close(client_sock1); + close(client_sock2); + close(server_sock); + + test_context_cleanup(); +} + +ZTEST_USER(socket_reuseport_test_suite, test_ipv4_tcp_identical_clients) +{ + test_reuseport_tcp_identical_clients_common(AF_INET, + TEST_IPV4_ANY_ADDR, + TEST_MY_IPV4_ADDR); +} + + +ZTEST_USER(socket_reuseport_test_suite, test_ipv6_tcp_identical_clients) +{ + test_reuseport_tcp_identical_clients_common(AF_INET6, + TEST_IPV6_ANY_ADDR, + TEST_MY_IPV6_ADDR); +} + +ZTEST_SUITE(socket_reuseport_test_suite, NULL, setup, NULL, NULL, NULL); diff --git a/tests/net/socket/reuseaddr/testcase.yaml b/tests/net/socket/reuseaddr_reuseport/testcase.yaml similarity index 100% rename from tests/net/socket/reuseaddr/testcase.yaml rename to tests/net/socket/reuseaddr_reuseport/testcase.yaml From 0e8f97df49a497de4a71d681bc34f429b239862c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 09:43:08 +0200 Subject: [PATCH 0701/4498] nrf5x_bsim: Add helper kconfig symbols for simulated nrf5340 Just like for the nrf52_bsim let's add helper kconfig symbols which can be used to identify we are running in a target that is compatible with the real HW but is not the real HW. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/Kconfig | 6 ++++++ soc/Kconfig | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/boards/posix/nrf52_bsim/Kconfig b/boards/posix/nrf52_bsim/Kconfig index 4660e965275..20620317521 100644 --- a/boards/posix/nrf52_bsim/Kconfig +++ b/boards/posix/nrf52_bsim/Kconfig @@ -26,3 +26,9 @@ config SOC_SERIES_BSIM_NRF52X depends on SOC_SERIES_BSIM_NRFXX help Any NRF52 simulated SOC with BabbleSim, based on the POSIX arch + +config SOC_SERIES_BSIM_NRF53X + bool + depends on SOC_SERIES_BSIM_NRFXX + help + Any NRF53 simulated SOC with BabbleSim, based on the POSIX arch diff --git a/soc/Kconfig b/soc/Kconfig index 20734c0f51f..33c2d0c29a4 100644 --- a/soc/Kconfig +++ b/soc/Kconfig @@ -24,8 +24,7 @@ source "subsys/logging/Kconfig.template.log_config" endmenu # The helper symbols below are put here due to an unusual setup: The simulated -# nrf52_bsim board uses the POSIX arch, but is compatible with Nordic ARM -# boards +# nrf5x_bsim boards use the POSIX arch, but are compatible with Nordic ARM boards config SOC_COMPATIBLE_NRF bool @@ -33,9 +32,18 @@ config SOC_COMPATIBLE_NRF config SOC_COMPATIBLE_NRF52X bool +config SOC_COMPATIBLE_NRF53X + bool + config SOC_COMPATIBLE_NRF52833 bool +config SOC_COMPATIBLE_NRF5340_CPUNET + bool + +config SOC_COMPATIBLE_NRF5340_CPUAPP + bool + # # SOC_*_LD: SoC specific Linker script additions # From 6afe7cf2168aa649276d3b734980a40dc686e2e2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 14:04:15 +0200 Subject: [PATCH 0702/4498] hal nordic: cmake: Add support for nrf53_bsim boards Also set the HAL variant appropriately when building for the new nrf53_bsim boards. Signed-off-by: Alberto Escolar Piedras --- modules/hal_nordic/nrfx/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index e98db561906..3edab6336c3 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -28,7 +28,9 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF52833 NRF52833_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF52833 NRF52833_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF52840 NRF52840_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUAPP NRF5340_XXAA_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP NRF5340_XXAA_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUNET NRF5340_XXAA_NETWORK) +zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET NRF5340_XXAA_NETWORK) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9120 NRF9120_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9160 NRF9160_XXAA) From 4e467a9bee5179842e3d7af92a6d99c023c5b60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Mon, 18 Sep 2023 12:52:38 +0200 Subject: [PATCH 0703/4498] Bluetooth: Test: Remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unused code in `host/gatt/settings` test. The conditional block could never be reached because the type of the discovery parameter is `BT_GATT_DISCOVER_CHARACTERISTIC`. Signed-off-by: Théo Battrel --- .../host/gatt/settings/src/gatt_utils.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/tests/bsim/bluetooth/host/gatt/settings/src/gatt_utils.c b/tests/bsim/bluetooth/host/gatt/settings/src/gatt_utils.c index fae0531a0b3..abfcbcfafc8 100644 --- a/tests/bsim/bluetooth/host/gatt/settings/src/gatt_utils.c +++ b/tests/bsim/bluetooth/host/gatt/settings/src/gatt_utils.c @@ -125,8 +125,6 @@ DEFINE_FLAG(flag_discovered); static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, struct bt_gatt_discover_params *params) { - int err; - if (attr == NULL) { for (int i = 0; i < ARRAY_SIZE(gatt_handles); i++) { printk("handle[%d] = 0x%x\n", i, gatt_handles[i]); @@ -143,20 +141,7 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at return BT_GATT_ITER_STOP; } - if (params->type == BT_GATT_DISCOVER_PRIMARY && - bt_uuid_cmp(params->uuid, &test_svc_uuid.uuid) == 0) { - printk("Found test service\n"); - params->uuid = NULL; - params->start_handle = attr->handle + 1; - params->type = BT_GATT_DISCOVER_CHARACTERISTIC; - - err = bt_gatt_discover(conn, params); - if (err != 0) { - FAIL("Discover failed (err %d)\n", err); - } - - return BT_GATT_ITER_STOP; - } else if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) { + if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) { const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_CLIENT_FEATURES) == 0) { From 0660719346d4c275a9dc935fc7ebe25a2189fbc0 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 19 Sep 2023 14:02:22 +0200 Subject: [PATCH 0704/4498] drivers: nrf: select PINCTRL Drivers for nRF SoCs using pinctrl did not select PINCTRL. This means boards are forced to enable PINCTRL. Signed-off-by: Gerard Marull-Paretas --- drivers/audio/Kconfig.dmic_pdm_nrfx | 1 + drivers/flash/Kconfig.nordic_qspi_nor | 1 + drivers/i2c/Kconfig.nrfx | 1 + drivers/i2s/Kconfig.nrfx | 1 + drivers/pwm/Kconfig.nrfx | 1 + drivers/sensor/qdec_nrfx/Kconfig | 1 + drivers/serial/Kconfig.nrfx | 1 + drivers/spi/Kconfig.nrfx | 1 + 8 files changed, 8 insertions(+) diff --git a/drivers/audio/Kconfig.dmic_pdm_nrfx b/drivers/audio/Kconfig.dmic_pdm_nrfx index 729c1cfa92e..9f45144effa 100644 --- a/drivers/audio/Kconfig.dmic_pdm_nrfx +++ b/drivers/audio/Kconfig.dmic_pdm_nrfx @@ -6,5 +6,6 @@ config AUDIO_DMIC_NRFX_PDM default y depends on DT_HAS_NORDIC_NRF_PDM_ENABLED select NRFX_PDM + select PINCTRL help Enable support for nrfx PDM driver for nRF MCU series. diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index 7b9fa05eb7f..aac9830835a 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -8,6 +8,7 @@ menuconfig NORDIC_QSPI_NOR select FLASH_HAS_DRIVER_ENABLED select NRFX_QSPI select FLASH_JESD216 + select PINCTRL help Enable support for nrfx QSPI driver with EasyDMA. diff --git a/drivers/i2c/Kconfig.nrfx b/drivers/i2c/Kconfig.nrfx index 1be1ba5aa1a..bfde27721a8 100644 --- a/drivers/i2c/Kconfig.nrfx +++ b/drivers/i2c/Kconfig.nrfx @@ -8,6 +8,7 @@ menuconfig I2C_NRFX default y depends on SOC_FAMILY_NRF depends on MULTITHREADING + select PINCTRL help Enable support for nrfx TWI drivers for nRF MCU series. diff --git a/drivers/i2s/Kconfig.nrfx b/drivers/i2s/Kconfig.nrfx index 404f78a15bf..1cb023a2b2e 100644 --- a/drivers/i2s/Kconfig.nrfx +++ b/drivers/i2s/Kconfig.nrfx @@ -6,6 +6,7 @@ menuconfig I2S_NRFX default y depends on DT_HAS_NORDIC_NRF_I2S_ENABLED select NRFX_I2S0 if HAS_HW_NRF_I2S0 + select PINCTRL help Enable support for nrfx I2S driver for nRF MCU series. diff --git a/drivers/pwm/Kconfig.nrfx b/drivers/pwm/Kconfig.nrfx index 712021a7780..9a84c5fd21b 100644 --- a/drivers/pwm/Kconfig.nrfx +++ b/drivers/pwm/Kconfig.nrfx @@ -9,5 +9,6 @@ config PWM_NRFX select NRFX_PWM1 if HAS_HW_NRF_PWM1 select NRFX_PWM2 if HAS_HW_NRF_PWM2 select NRFX_PWM3 if HAS_HW_NRF_PWM3 + select PINCTRL help Enable support for nrfx Hardware PWM driver for nRF52 MCU series. diff --git a/drivers/sensor/qdec_nrfx/Kconfig b/drivers/sensor/qdec_nrfx/Kconfig index 245d56ef126..64d91d6ba6f 100644 --- a/drivers/sensor/qdec_nrfx/Kconfig +++ b/drivers/sensor/qdec_nrfx/Kconfig @@ -7,5 +7,6 @@ config QDEC_NRFX depends on DT_HAS_NORDIC_NRF_QDEC_ENABLED select NRFX_QDEC0 if HAS_HW_NRF_QDEC0 select NRFX_QDEC1 if HAS_HW_NRF_QDEC1 + select PINCTRL help Enable support for nrfx QDEC driver for nRF MCU series. diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index c9c9d687a00..1775b598c35 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -9,6 +9,7 @@ menuconfig UART_NRFX select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select SERIAL_SUPPORT_ASYNC + select PINCTRL depends on DT_HAS_NORDIC_NRF_UART_ENABLED || DT_HAS_NORDIC_NRF_UARTE_ENABLED help Enable support for nrfx UART drivers for nRF MCU series. diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index 5b642a32b68..a1a2182c265 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -6,6 +6,7 @@ menuconfig SPI_NRFX default y depends on SOC_FAMILY_NRF depends on MULTITHREADING + select PINCTRL help Enable support for nrfx SPI drivers for nRF MCU series. From e61f52b0f42346e1d6c66ba42c84419122b37dcb Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 19 Sep 2023 14:14:44 +0200 Subject: [PATCH 0705/4498] boards: nrf-based: remove redundant CONFIG_PINCTRL=y This setting is no longer needed, relevant drivers select PINCTRL instead. Signed-off-by: Gerard Marull-Paretas --- boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig | 2 -- boards/arm/96b_nitrogen/96b_nitrogen_defconfig | 2 -- boards/arm/acn52832/acn52832_defconfig | 2 -- boards/arm/actinius_icarus/actinius_icarus_defconfig | 2 -- boards/arm/actinius_icarus/actinius_icarus_ns_defconfig | 2 -- boards/arm/actinius_icarus_bee/actinius_icarus_bee_defconfig | 2 -- .../arm/actinius_icarus_bee/actinius_icarus_bee_ns_defconfig | 2 -- boards/arm/actinius_icarus_som/actinius_icarus_som_defconfig | 2 -- .../arm/actinius_icarus_som/actinius_icarus_som_ns_defconfig | 2 -- .../actinius_icarus_som_dk/actinius_icarus_som_dk_defconfig | 2 -- .../actinius_icarus_som_dk/actinius_icarus_som_dk_ns_defconfig | 2 -- .../adafruit_feather_nrf52840_defconfig | 2 -- .../adafruit_itsybitsy_nrf52840_defconfig | 2 -- boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig | 2 -- .../arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig | 2 -- boards/arm/bbc_microbit/bbc_microbit_defconfig | 2 -- boards/arm/bbc_microbit_v2/bbc_microbit_v2_defconfig | 2 -- boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_defconfig | 2 -- boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns_defconfig | 2 -- boards/arm/bl5340_dvk/bl5340_dvk_cpunet_defconfig | 2 -- boards/arm/bl652_dvk/bl652_dvk_defconfig | 2 -- boards/arm/bl653_dvk/bl653_dvk_defconfig | 2 -- boards/arm/bl654_dvk/bl654_dvk_defconfig | 2 -- boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig | 2 -- boards/arm/bl654_usb/bl654_usb_defconfig | 2 -- .../blueclover_plt_demo_v2_nrf52832_defconfig | 2 -- boards/arm/bt510/bt510_defconfig | 2 -- boards/arm/bt610/bt610_defconfig | 2 -- .../circuitdojo_feather_nrf9160_defconfig | 2 -- .../circuitdojo_feather_nrf9160_ns_defconfig | 2 -- .../contextualelectronics_abc_defconfig | 2 -- boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig | 2 -- boards/arm/degu_evk/degu_evk_defconfig | 2 -- .../ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig | 2 -- boards/arm/holyiot_yj16019/holyiot_yj16019_defconfig | 2 -- boards/arm/mg100/mg100_defconfig | 2 -- boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig | 2 -- boards/arm/nrf51_ble400/nrf51_ble400_defconfig | 2 -- boards/arm/nrf51_blenano/nrf51_blenano_defconfig | 2 -- boards/arm/nrf51_vbluno51/nrf51_vbluno51_defconfig | 2 -- boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422_defconfig | 2 -- boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422_defconfig | 2 -- boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig | 2 -- boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig | 2 -- boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig | 2 -- boards/arm/nrf52840_blip/nrf52840_blip_defconfig | 2 -- boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig | 2 -- .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig | 2 -- boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig | 2 -- boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig | 2 -- boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig | 2 -- .../nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig | 2 -- .../nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig | 2 -- boards/arm/nrf52_blenano2/nrf52_blenano2_defconfig | 2 -- boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig | 2 -- boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig | 2 -- boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig | 2 -- boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig | 2 -- boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig | 2 -- .../nrf5340_audio_dk_nrf5340_cpuapp_defconfig | 2 -- .../nrf5340_audio_dk_nrf5340_cpuapp_ns_defconfig | 2 -- .../nrf5340_audio_dk_nrf5340_cpunet_defconfig | 3 --- .../arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig | 2 -- .../nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns_defconfig | 2 -- .../arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig | 2 -- boards/arm/nrf9160_innblue21/nrf9160_innblue21_defconfig | 2 -- boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns_defconfig | 2 -- boards/arm/nrf9160_innblue22/nrf9160_innblue22_defconfig | 2 -- boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns_defconfig | 2 -- boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig | 2 -- boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig | 2 -- boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns_defconfig | 2 -- boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_defconfig | 2 -- boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_defconfig | 2 -- boards/arm/pan1770_evb/pan1770_evb_defconfig | 3 --- boards/arm/pan1780_evb/pan1780_evb_defconfig | 3 --- boards/arm/pan1781_evb/pan1781_evb_defconfig | 3 --- boards/arm/pan1782_evb/pan1782_evb_defconfig | 3 --- boards/arm/particle_argon/particle_argon_defconfig | 2 -- boards/arm/particle_boron/particle_boron_defconfig | 2 -- boards/arm/particle_xenon/particle_xenon_defconfig | 2 -- boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig | 2 -- boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig | 2 -- boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig | 2 -- boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig | 2 -- boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig | 2 -- .../raytac_mdbt50q_db_33_nrf52833_defconfig | 2 -- .../raytac_mdbt50q_db_40_nrf52840_defconfig | 2 -- .../raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig | 2 -- .../raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig | 2 -- .../raytac_mdbt53_db_40_nrf5340_cpunet_defconfig | 2 -- .../raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig | 2 -- .../raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig | 2 -- .../raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig | 2 -- boards/arm/reel_board/reel_board_defconfig | 2 -- boards/arm/reel_board/reel_board_v2_defconfig | 2 -- .../sparkfun_thing_plus_nrf9160_defconfig | 2 -- .../sparkfun_thing_plus_nrf9160_ns_defconfig | 2 -- boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig | 2 -- boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_defconfig | 2 -- .../arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns_defconfig | 2 -- boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet_defconfig | 2 -- .../ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig | 2 -- .../ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig | 2 -- .../ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig | 2 -- .../ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig | 2 -- .../ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig | 2 -- .../ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig | 2 -- .../ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig | 2 -- .../ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig | 2 -- .../ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig | 2 -- .../ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig | 2 -- .../we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig | 2 -- .../we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig | 2 -- .../we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig | 2 -- boards/arm/xiao_ble/xiao_ble_defconfig | 2 -- boards/arm/xiao_ble/xiao_ble_sense_defconfig | 2 -- 117 files changed, 239 deletions(-) diff --git a/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig b/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig index 91a90e7986a..e53e9565e4a 100644 --- a/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig +++ b/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig @@ -12,5 +12,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig index e804b43da5c..b8565973eb1 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig +++ b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig @@ -15,5 +15,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/acn52832/acn52832_defconfig b/boards/arm/acn52832/acn52832_defconfig index 2bb13882f8c..d35096cdd6e 100644 --- a/boards/arm/acn52832/acn52832_defconfig +++ b/boards/arm/acn52832/acn52832_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus/actinius_icarus_defconfig b/boards/arm/actinius_icarus/actinius_icarus_defconfig index 6e00f057830..58d15739a95 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_defconfig +++ b/boards/arm/actinius_icarus/actinius_icarus_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig b/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig index 2eafce1cfb6..e2e6e11584b 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig +++ b/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_defconfig b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_defconfig index 504bbcadae5..64de49c899b 100644 --- a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_defconfig +++ b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns_defconfig b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns_defconfig index 73e3c4a84ce..7e0d1c6e2df 100644 --- a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns_defconfig +++ b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_som/actinius_icarus_som_defconfig b/boards/arm/actinius_icarus_som/actinius_icarus_som_defconfig index e51d63709b9..b2bbfdba52d 100644 --- a/boards/arm/actinius_icarus_som/actinius_icarus_som_defconfig +++ b/boards/arm/actinius_icarus_som/actinius_icarus_som_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_som/actinius_icarus_som_ns_defconfig b/boards/arm/actinius_icarus_som/actinius_icarus_som_ns_defconfig index 6ebb20a5994..81712f3aa1f 100644 --- a/boards/arm/actinius_icarus_som/actinius_icarus_som_ns_defconfig +++ b/boards/arm/actinius_icarus_som/actinius_icarus_som_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_defconfig b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_defconfig index b62a72cf708..2542dbb901e 100644 --- a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_defconfig +++ b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns_defconfig b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns_defconfig index 77d7eac9e7e..212dd785cd2 100644 --- a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns_defconfig +++ b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig index 1f42d1a0aa4..74b11931eb8 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig index e5a88c27fb3..a88657578f3 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig @@ -17,8 +17,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - # Flashing CONFIG_USE_DT_CODE_PARTITION=y CONFIG_BUILD_OUTPUT_UF2=y diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig index dcdc0c8a836..49b2009f744 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig @@ -19,5 +19,3 @@ CONFIG_UART_CONSOLE=y # enable sam-ba bootloader on legacy mode CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig index 4604c6bf386..024c659ad37 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig @@ -19,5 +19,3 @@ CONFIG_UART_CONSOLE=y # enable sam-ba bootloader on legacy mode CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bbc_microbit/bbc_microbit_defconfig b/boards/arm/bbc_microbit/bbc_microbit_defconfig index ba34da254e7..8396a17b16f 100644 --- a/boards/arm/bbc_microbit/bbc_microbit_defconfig +++ b/boards/arm/bbc_microbit/bbc_microbit_defconfig @@ -17,5 +17,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bbc_microbit_v2/bbc_microbit_v2_defconfig b/boards/arm/bbc_microbit_v2/bbc_microbit_v2_defconfig index 970aabdd1fb..f4d34eb3599 100644 --- a/boards/arm/bbc_microbit_v2/bbc_microbit_v2_defconfig +++ b/boards/arm/bbc_microbit_v2/bbc_microbit_v2_defconfig @@ -17,5 +17,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_defconfig b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_defconfig index 23bb9d57b10..6c21af3695a 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_defconfig +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_defconfig @@ -28,5 +28,3 @@ CONFIG_CLOCK_CONTROL_NRF_K32SRC_250PPM=y CONFIG_SOC_LFXO_CAP_INT_7PF=y CONFIG_SOC_HFXO_CAP_INTERNAL=y CONFIG_SOC_HFXO_CAP_INT_VALUE_X2=27 - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns_defconfig b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns_defconfig index 47fcea1c3a4..27af7678a34 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns_defconfig +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_defconfig b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_defconfig index 83098b18827..c68fdfc9312 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_defconfig +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl652_dvk/bl652_dvk_defconfig b/boards/arm/bl652_dvk/bl652_dvk_defconfig index 5302fa8d53f..def931d42fc 100644 --- a/boards/arm/bl652_dvk/bl652_dvk_defconfig +++ b/boards/arm/bl652_dvk/bl652_dvk_defconfig @@ -24,5 +24,3 @@ CONFIG_RTT_CONSOLE=y # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl653_dvk/bl653_dvk_defconfig b/boards/arm/bl653_dvk/bl653_dvk_defconfig index 83b73ef4435..b1abe06089c 100644 --- a/boards/arm/bl653_dvk/bl653_dvk_defconfig +++ b/boards/arm/bl653_dvk/bl653_dvk_defconfig @@ -23,5 +23,3 @@ CONFIG_UART_CONSOLE=y # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl654_dvk/bl654_dvk_defconfig b/boards/arm/bl654_dvk/bl654_dvk_defconfig index 976495f7e88..7d5b17577b2 100644 --- a/boards/arm/bl654_dvk/bl654_dvk_defconfig +++ b/boards/arm/bl654_dvk/bl654_dvk_defconfig @@ -24,5 +24,3 @@ CONFIG_RTT_CONSOLE=y # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig index e92c2c4005f..f8352265d3f 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig @@ -20,5 +20,3 @@ CONFIG_UART_CONSOLE=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bl654_usb/bl654_usb_defconfig b/boards/arm/bl654_usb/bl654_usb_defconfig index 983150c35d9..b51d0c1d99e 100644 --- a/boards/arm/bl654_usb/bl654_usb_defconfig +++ b/boards/arm/bl654_usb/bl654_usb_defconfig @@ -22,5 +22,3 @@ CONFIG_USB_DEVICE_STACK=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig index 301a23af362..d9999ba9516 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig @@ -23,5 +23,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bt510/bt510_defconfig b/boards/arm/bt510/bt510_defconfig index eb769cc9465..cd897918fe1 100644 --- a/boards/arm/bt510/bt510_defconfig +++ b/boards/arm/bt510/bt510_defconfig @@ -20,5 +20,3 @@ CONFIG_UART_CONSOLE=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/bt610/bt610_defconfig b/boards/arm/bt610/bt610_defconfig index d1d7226fade..531ba015b1e 100644 --- a/boards/arm/bt610/bt610_defconfig +++ b/boards/arm/bt610/bt610_defconfig @@ -23,5 +23,3 @@ CONFIG_HW_STACK_PROTECTION=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig index 8d077a6c0ff..f3dc6d6155c 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig @@ -25,5 +25,3 @@ CONFIG_UART_CONSOLE=y # required to enable 3V3 power rail CONFIG_REGULATOR=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns_defconfig b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns_defconfig index d38a8dc66ad..9f25a5dda67 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns_defconfig +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns_defconfig @@ -28,5 +28,3 @@ CONFIG_UART_CONSOLE=y # required to enable 3V3 power rail CONFIG_REGULATOR=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig index 7a3055b9c82..fce13936984 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig index 4cb6022e7ae..b77b8937a77 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig @@ -20,5 +20,3 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/degu_evk/degu_evk_defconfig b/boards/arm/degu_evk/degu_evk_defconfig index e003438c3dc..6123f6c756e 100644 --- a/boards/arm/degu_evk/degu_evk_defconfig +++ b/boards/arm/degu_evk/degu_evk_defconfig @@ -20,5 +20,3 @@ CONFIG_GPIO=y # required to enable 3V3 power rail and Vin1 monitor CONFIG_REGULATOR=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig index 05acf2ca945..8b9a09a8e8d 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig +++ b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/holyiot_yj16019/holyiot_yj16019_defconfig b/boards/arm/holyiot_yj16019/holyiot_yj16019_defconfig index 8cd91b6b694..7a5c82fbdc8 100644 --- a/boards/arm/holyiot_yj16019/holyiot_yj16019_defconfig +++ b/boards/arm/holyiot_yj16019/holyiot_yj16019_defconfig @@ -13,5 +13,3 @@ CONFIG_USE_SEGGER_RTT=y # Enable GPIO CONFIG_GPIO=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/mg100/mg100_defconfig b/boards/arm/mg100/mg100_defconfig index bb7d09dabf2..e2af3973938 100644 --- a/boards/arm/mg100/mg100_defconfig +++ b/boards/arm/mg100/mg100_defconfig @@ -21,5 +21,3 @@ CONFIG_UART_CONSOLE=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig index af230adb18a..fecb5052471 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf51_ble400/nrf51_ble400_defconfig b/boards/arm/nrf51_ble400/nrf51_ble400_defconfig index 57332970318..34fd08c47d5 100644 --- a/boards/arm/nrf51_ble400/nrf51_ble400_defconfig +++ b/boards/arm/nrf51_ble400/nrf51_ble400_defconfig @@ -13,5 +13,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf51_blenano/nrf51_blenano_defconfig b/boards/arm/nrf51_blenano/nrf51_blenano_defconfig index e4a5441877a..7bd3f7c6736 100644 --- a/boards/arm/nrf51_blenano/nrf51_blenano_defconfig +++ b/boards/arm/nrf51_blenano/nrf51_blenano_defconfig @@ -13,5 +13,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf51_vbluno51/nrf51_vbluno51_defconfig b/boards/arm/nrf51_vbluno51/nrf51_vbluno51_defconfig index 9cdf638b99c..09836ecc779 100644 --- a/boards/arm/nrf51_vbluno51/nrf51_vbluno51_defconfig +++ b/boards/arm/nrf51_vbluno51/nrf51_vbluno51_defconfig @@ -13,5 +13,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422_defconfig b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422_defconfig index 0aba32cb596..7cd29568889 100644 --- a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422_defconfig +++ b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422_defconfig @@ -13,5 +13,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422_defconfig b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422_defconfig index dbe03eef66d..c937ab159c8 100644 --- a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422_defconfig +++ b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422_defconfig @@ -13,5 +13,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig index 8993b59f938..732b02a3610 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig index 9ef66860ab3..f953cca65f1 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig index 9cbee72b2e7..d4d96e6e395 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig index 811a88de939..526283ef3d4 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig +++ b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig index e4c79a2bf88..76c73a15a04 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index 8701863e99a..c76e57e17a9 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -12,5 +12,3 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig index 4a5e737cd14..9d0226eed01 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig index 2c6b7f2fc82..97eaa9232e5 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig @@ -25,5 +25,3 @@ CONFIG_GPIO=y # Bluetooth not enabled by default on nRF52811 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig index 9f1232a8f0a..107f9e00d59 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index c367a90d5ef..36998fc79a1 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -13,8 +13,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y -CONFIG_PINCTRL=y - # Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote # wakeup by default. It needs to be disabled here, because the USB nrfx # driver always overwrites option from Kconfig mentioned above with the diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig index 19aaa3825d1..b434b22401d 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_blenano2/nrf52_blenano2_defconfig b/boards/arm/nrf52_blenano2/nrf52_blenano2_defconfig index 5c51849c0d9..318b8de6922 100644 --- a/boards/arm/nrf52_blenano2/nrf52_blenano2_defconfig +++ b/boards/arm/nrf52_blenano2/nrf52_blenano2_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig index 2a21dc07192..3c893c08bc7 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig index fac5419e6f6..074355f29a1 100644 --- a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig +++ b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig index 6e275e63f35..d1c9da8186c 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig @@ -22,5 +22,3 @@ CONFIG_UART_CONSOLE=y # Bluetooth not enabled by default on nRF52805 due to RAM limitations when # running the default set of kernel tests. - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig index 93706e89d0a..a90ea346ba0 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig @@ -23,5 +23,3 @@ CONFIG_UART_CONSOLE=y # Bluetooth not enabled by default on nRF52810 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig index 23e1f4c249a..1f1eccdbec2 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig index d1b5f551c9b..2e7ac0ea3cc 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig @@ -18,6 +18,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - CONFIG_REGULATOR=y diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns_defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns_defconfig index f0d723ad450..425ae718426 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns_defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns_defconfig @@ -19,6 +19,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - CONFIG_REGULATOR=y diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet_defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet_defconfig index 0450bb97797..d0844088568 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet_defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet_defconfig @@ -10,9 +10,6 @@ CONFIG_ARM_MPU=y # Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y -# Enable PINCTRL -CONFIG_PINCTRL=y - # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig index 419a8001670..22e8f52ff31 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns_defconfig index 95172e7b2bf..0fe351e2780 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig index 2edb56e45ab..47f7b157d06 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_defconfig b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_defconfig index 450db1d4d21..7c0e84c1abd 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_defconfig +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_defconfig @@ -21,5 +21,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns_defconfig b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns_defconfig index ff57f4b7cdb..4f5410848bc 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns_defconfig +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns_defconfig @@ -24,5 +24,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_defconfig b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_defconfig index 73d88346580..ae9e2e2413e 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_defconfig +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_defconfig @@ -21,5 +21,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns_defconfig b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns_defconfig index f75f894b1dd..e956d4d8b75 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns_defconfig +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns_defconfig @@ -24,5 +24,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig index 073409dbba1..58f290ba271 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig index 7eadd01a2ab..aa61cc4ca35 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns_defconfig b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns_defconfig index 67f4522c30e..93343cc0264 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns_defconfig +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_defconfig b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_defconfig index d4db57f62b4..1e04a544d95 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_defconfig +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_defconfig b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_defconfig index f2d7f04470c..97649b3d4d8 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_defconfig +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/pan1770_evb/pan1770_evb_defconfig b/boards/arm/pan1770_evb/pan1770_evb_defconfig index 1d90cb82c25..7fbc9b87408 100644 --- a/boards/arm/pan1770_evb/pan1770_evb_defconfig +++ b/boards/arm/pan1770_evb/pan1770_evb_defconfig @@ -25,6 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -# using pinctrl -CONFIG_PINCTRL=y diff --git a/boards/arm/pan1780_evb/pan1780_evb_defconfig b/boards/arm/pan1780_evb/pan1780_evb_defconfig index ca1a58c3b74..1bb9d720f52 100644 --- a/boards/arm/pan1780_evb/pan1780_evb_defconfig +++ b/boards/arm/pan1780_evb/pan1780_evb_defconfig @@ -25,6 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -# using pinctrl -CONFIG_PINCTRL=y diff --git a/boards/arm/pan1781_evb/pan1781_evb_defconfig b/boards/arm/pan1781_evb/pan1781_evb_defconfig index dacffd42175..90e88bd4e1c 100644 --- a/boards/arm/pan1781_evb/pan1781_evb_defconfig +++ b/boards/arm/pan1781_evb/pan1781_evb_defconfig @@ -25,6 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -# using pinctrl -CONFIG_PINCTRL=y diff --git a/boards/arm/pan1782_evb/pan1782_evb_defconfig b/boards/arm/pan1782_evb/pan1782_evb_defconfig index e6a6cc1d4a5..98904968416 100644 --- a/boards/arm/pan1782_evb/pan1782_evb_defconfig +++ b/boards/arm/pan1782_evb/pan1782_evb_defconfig @@ -26,8 +26,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# using pinctrl -CONFIG_PINCTRL=y - # using rc for slow clock CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/particle_argon/particle_argon_defconfig b/boards/arm/particle_argon/particle_argon_defconfig index c29f62babd4..5f3f7a7e2b5 100644 --- a/boards/arm/particle_argon/particle_argon_defconfig +++ b/boards/arm/particle_argon/particle_argon_defconfig @@ -20,5 +20,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/particle_boron/particle_boron_defconfig b/boards/arm/particle_boron/particle_boron_defconfig index 622a3169073..453981d2a64 100644 --- a/boards/arm/particle_boron/particle_boron_defconfig +++ b/boards/arm/particle_boron/particle_boron_defconfig @@ -20,8 +20,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - # Fix the priority to enable the modem line's serial buffer # before the modem driver starts (gsm_ppp or ublox-sara-r4). CONFIG_REGULATOR=y diff --git a/boards/arm/particle_xenon/particle_xenon_defconfig b/boards/arm/particle_xenon/particle_xenon_defconfig index 2495d886b41..8c7246fad1c 100644 --- a/boards/arm/particle_xenon/particle_xenon_defconfig +++ b/boards/arm/particle_xenon/particle_xenon_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig index fc8f45eceaa..ce594faf969 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -12,5 +12,3 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig index 010c72e8c07..0e6c950ae36 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig @@ -25,5 +25,3 @@ CONFIG_UART_CONSOLE=y # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig b/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig index a1b24f00c47..a169a86f8de 100644 --- a/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig +++ b/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig @@ -18,7 +18,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - # icount is kinda broken when the NRF timer emulation is used CONFIG_QEMU_ICOUNT=n diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig index 4cc2863efab..bfdc1718875 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig @@ -21,5 +21,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig b/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig index b908cb5debd..b7e873c3f03 100644 --- a/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig +++ b/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig @@ -21,5 +21,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig index 1212ba8928f..1176302a56d 100644 --- a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig +++ b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig index 438343c6d9b..3651902f740 100644 --- a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig +++ b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig index 86ab484940a..cf048d3d213 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig index 26f206727c9..e0759063b9a 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig index ed5249f0a0d..92b16601314 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig index 4824d5987bb..6966d7d728c 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig index 2bae84e660e..44e16cd65ac 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig index bff78a85624..94f21fb4c98 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig @@ -19,5 +19,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/reel_board_defconfig b/boards/arm/reel_board/reel_board_defconfig index 850506692ba..8e88a3b3231 100644 --- a/boards/arm/reel_board/reel_board_defconfig +++ b/boards/arm/reel_board/reel_board_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/reel_board_v2_defconfig b/boards/arm/reel_board/reel_board_v2_defconfig index 2ac0610f78c..fcec54b6d0c 100644 --- a/boards/arm/reel_board/reel_board_v2_defconfig +++ b/boards/arm/reel_board/reel_board_v2_defconfig @@ -16,5 +16,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_defconfig b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_defconfig index e53eb77c651..8748d5dd83c 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_defconfig +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_defconfig @@ -20,6 +20,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - CONFIG_REGULATOR=y diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns_defconfig b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns_defconfig index f2e6c1026c7..92818ef157b 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns_defconfig +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns_defconfig @@ -23,6 +23,4 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_PINCTRL=y - CONFIG_REGULATOR=y diff --git a/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig b/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig index 6cdebdd6ff1..2bdadf855de 100644 --- a/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig +++ b/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig @@ -30,5 +30,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_defconfig b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_defconfig index 6ca9f643a56..5f3fd735660 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_defconfig +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_defconfig @@ -23,8 +23,6 @@ CONFIG_UART_CONSOLE=y # Enable uart driver CONFIG_SERIAL=y -CONFIG_PINCTRL=y - # Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote # wakeup by default. It needs to be disabled here, because the USB nrfx # driver always overwrites option from Kconfig mentioned above with the diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns_defconfig b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns_defconfig index b6608ff6a25..23d7e5ff6e0 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns_defconfig +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns_defconfig @@ -26,8 +26,6 @@ CONFIG_UART_CONSOLE=y # Enable uart driver CONFIG_SERIAL=y -CONFIG_PINCTRL=y - # Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote # wakeup by default. It needs to be disabled here, because the USB nrfx # driver always overwrites option from Kconfig mentioned above with the diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet_defconfig b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet_defconfig index 50a0e59d652..33dc6fbdedd 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet_defconfig +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet_defconfig @@ -12,5 +12,3 @@ CONFIG_HW_STACK_PROTECTION=y # Enable GPIO CONFIG_GPIO=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig index 801393790fe..0ac55829154 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig @@ -22,5 +22,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig index 4f8a5c5a8da..edfe56e0a15 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig index 37271c2ce81..f1fd8825b8c 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig index 4a35f6e612f..97872745a6d 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig index 7a63bc69bf2..6cc16653c74 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig index c20dc6fe9f3..79826cc9974 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig @@ -26,5 +26,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig index 93127beefef..95f9f59739f 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig index b44e54e3d18..c23f9eb7833 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig index f9cabe94b4a..9ccc843efb0 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig index c06ad795868..80995445718 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig @@ -25,5 +25,3 @@ CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig index 88c4ddb2023..b81a1a35e4e 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig @@ -23,5 +23,3 @@ CONFIG_UART_CONSOLE=y # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig index 249c4a8e394..0b4e298d05a 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig @@ -26,5 +26,3 @@ CONFIG_UART_CONSOLE=y # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig index cca27094e6a..a7687b6b541 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig @@ -26,5 +26,3 @@ CONFIG_UART_CONSOLE=y # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/xiao_ble/xiao_ble_defconfig b/boards/arm/xiao_ble/xiao_ble_defconfig index 6b6aa3168ec..59471d3d22a 100644 --- a/boards/arm/xiao_ble/xiao_ble_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_defconfig @@ -28,5 +28,3 @@ CONFIG_USB_DEVICE_STACK=y # Build UF2 by default, supported by the Adafruit nRF52 Bootloader CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/xiao_ble/xiao_ble_sense_defconfig b/boards/arm/xiao_ble/xiao_ble_sense_defconfig index 269f6f7915b..73878352edd 100644 --- a/boards/arm/xiao_ble/xiao_ble_sense_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_sense_defconfig @@ -29,7 +29,5 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y -CONFIG_PINCTRL=y - # required to enable LSM6DS3TR-C power CONFIG_REGULATOR=y From a59666754eccb4e47001021943b583ad5b66c578 Mon Sep 17 00:00:00 2001 From: Lucas Dietrich Date: Tue, 19 Sep 2023 14:43:24 +0200 Subject: [PATCH 0706/4498] lorawan: Add LORAWAN_PUBLIC_NETWORK configuration choice Provides a toggle between public and private network selections. Signed-off-by: Lucas Dietrich --- subsys/lorawan/Kconfig | 7 +++++++ subsys/lorawan/lorawan.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/subsys/lorawan/Kconfig b/subsys/lorawan/Kconfig index 691b3a19eb2..229e075b5c5 100644 --- a/subsys/lorawan/Kconfig +++ b/subsys/lorawan/Kconfig @@ -27,6 +27,13 @@ config LORAWAN_SYSTEM_MAX_RX_ERROR System Max Rx timing error value in ms to be used by LoRaWAN stack for calculating the RX1/RX2 window timing. +config LORAWAN_PUBLIC_NETWORK + bool "LoRaWAN Public Network" + default y + help + Enable this option to use a public LoRaWAN network. + Disable for private LoRaWAN networks. + config LORAMAC_REGION_AS923 bool "Asia 923MHz Frequency band" diff --git a/subsys/lorawan/lorawan.c b/subsys/lorawan/lorawan.c index 70bcc67a4d3..d73691cfde8 100644 --- a/subsys/lorawan/lorawan.c +++ b/subsys/lorawan/lorawan.c @@ -369,7 +369,7 @@ int lorawan_join(const struct lorawan_join_config *join_cfg) /* MIB_PUBLIC_NETWORK powers on the radio and does not turn it off */ mib_req.Type = MIB_PUBLIC_NETWORK; - mib_req.Param.EnablePublicNetwork = true; + mib_req.Param.EnablePublicNetwork = IS_ENABLED(CONFIG_LORAWAN_PUBLIC_NETWORK); LoRaMacMibSetRequestConfirm(&mib_req); if (join_cfg->mode == LORAWAN_ACT_OTAA) { From 4a250c26b16dc439e5c63e23ce7c35cd0465b514 Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Mon, 18 Sep 2023 19:22:49 -0400 Subject: [PATCH 0707/4498] drivers: counter: fix index of stm32 RTC source clock The DT_INST_CLOCKS_CELL macro takes as the first argument the device instance and not the cell index. This change correctly gets the second index of the first device as intended. Signed-off-by: Brett Witherspoon --- drivers/counter/counter_ll_stm32_rtc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index a7265c635f2..8ad9bd0d619 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -484,23 +484,23 @@ static const struct rtc_stm32_config rtc_config = { .ll_rtc_config = { #if !defined(CONFIG_SOC_SERIES_STM32F1X) .HourFormat = LL_RTC_HOURFORMAT_24HOUR, -#if DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSI +#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI /* prescaler values for LSI @ 32 KHz */ .AsynchPrescaler = 0x7F, .SynchPrescaler = 0x00F9, -#else /* DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSE */ +#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ /* prescaler values for LSE @ 32768 Hz */ .AsynchPrescaler = 0x7F, .SynchPrescaler = 0x00FF, #endif #else /* CONFIG_SOC_SERIES_STM32F1X */ -#if DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSI +#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI /* prescaler values for LSI @ 40 KHz */ .AsynchPrescaler = 0x9C3F, -#else /* DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSE */ +#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ /* prescaler values for LSE @ 32768 Hz */ .AsynchPrescaler = 0x7FFF, -#endif /* DT_INST_CLOCKS_CELL(1, bus) == STM32_SRC_LSE */ +#endif .OutPutSource = LL_RTC_CALIB_OUTPUT_NONE, #endif /* CONFIG_SOC_SERIES_STM32F1X */ }, From 9608c8f667f7be30db2da4e964772c583d956695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Tue, 19 Sep 2023 18:49:39 +0200 Subject: [PATCH 0708/4498] usbc: fix conflicting Kconfigs for USB-C related init priority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a new Kconfig for USB-C init priority that is conflicting with currently used Kconfig for init of VBUS and TCPC. This commit changes the names to more specific related to the subsystem they belong to. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/Kconfig | 4 ++-- drivers/usb_c/tcpc/ucpd_stm32.c | 2 +- drivers/usb_c/vbus/Kconfig | 6 ++++++ drivers/usb_c/vbus/usbc_vbus_adc.c | 2 +- subsys/usb/usb_c/Kconfig | 6 ++++-- subsys/usb/usb_c/usbc_stack.c | 2 +- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/usb_c/tcpc/Kconfig b/drivers/usb_c/tcpc/Kconfig index 1e30c3cef1e..51b9a79c394 100644 --- a/drivers/usb_c/tcpc/Kconfig +++ b/drivers/usb_c/tcpc/Kconfig @@ -10,8 +10,8 @@ menuconfig USBC_TCPC_DRIVER if USBC_TCPC_DRIVER -config USBC_INIT_PRIORITY - int "USBC driver init priority" +config USBC_TCPC_INIT_PRIORITY + int "USB-C TCPC driver init priority" default 80 help USB-C device driver initialization priority. diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index 812ddfaa7a1..7082342dd1e 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -1500,7 +1500,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0, &drv_data_##inst, \ &drv_config_##inst, \ POST_KERNEL, \ - CONFIG_USBC_INIT_PRIORITY, \ + CONFIG_USBC_TCPC_INIT_PRIORITY, \ &driver_api); DT_INST_FOREACH_STATUS_OKAY(TCPC_DRIVER_INIT) diff --git a/drivers/usb_c/vbus/Kconfig b/drivers/usb_c/vbus/Kconfig index 36e20e3c382..5b368a944ae 100644 --- a/drivers/usb_c/vbus/Kconfig +++ b/drivers/usb_c/vbus/Kconfig @@ -10,6 +10,12 @@ menuconfig USBC_VBUS_DRIVER if USBC_VBUS_DRIVER +config USBC_VBUS_INIT_PRIORITY + int "USB-C VBUS driver init priority" + default 85 + help + Initialization priority of the USB-C VBUS measurement drivers in POST_KERNEL. + source "drivers/usb_c/vbus/Kconfig.usbc_vbus_adc" endif # USBC_VBUS_DRIVER diff --git a/drivers/usb_c/vbus/usbc_vbus_adc.c b/drivers/usb_c/vbus/usbc_vbus_adc.c index 6ed645795d2..a1fbe6f3421 100644 --- a/drivers/usb_c/vbus/usbc_vbus_adc.c +++ b/drivers/usb_c/vbus/usbc_vbus_adc.c @@ -218,7 +218,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0, &drv_data_##inst, \ &drv_config_##inst, \ POST_KERNEL, \ - CONFIG_USBC_INIT_PRIORITY, \ + CONFIG_USBC_VBUS_INIT_PRIORITY, \ &driver_api); DT_INST_FOREACH_STATUS_OKAY(DRIVER_INIT) diff --git a/subsys/usb/usb_c/Kconfig b/subsys/usb/usb_c/Kconfig index a7bd7a08f74..6cd85c79d56 100644 --- a/subsys/usb/usb_c/Kconfig +++ b/subsys/usb/usb_c/Kconfig @@ -14,11 +14,13 @@ menuconfig USBC_STACK if USBC_STACK -config USBC_INIT_PRIORITY - int "USB-C initialization priority" +config USBC_STACK_INIT_PRIORITY + int "USB-C stack init priority" default 90 help Initialization priority of the USB-C connector driver in POST_KERNEL. + This driver must be initialized after devices referenced by USB-C connectors + like VBUS and TCPC. config USBC_THREAD_PRIORITY int "USB-C thread priority" diff --git a/subsys/usb/usb_c/usbc_stack.c b/subsys/usb/usb_c/usbc_stack.c index c1a636ab6c3..7620a3c8cc8 100644 --- a/subsys/usb/usb_c/usbc_stack.c +++ b/subsys/usb/usb_c/usbc_stack.c @@ -83,7 +83,7 @@ static ALWAYS_INLINE void usbc_handler(void *port_dev) \ DEVICE_DT_INST_DEFINE(inst, &usbc_subsys_init, NULL, &usbc_port_data_##inst, \ &usbc_port_config_##inst, POST_KERNEL, \ - CONFIG_USBC_INIT_PRIORITY, NULL); + CONFIG_USBC_STACK_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(USBC_SUBSYS_INIT) From 66069b3b397dbd68fe47ab54579501b9fc365425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Wed, 20 Sep 2023 10:16:50 +0200 Subject: [PATCH 0709/4498] drivers: serial: uart_nrfx_uarte: coexisting async and interrupt API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes an issue with the nrfx uarte driver to allow the async and interrupt driven UART APIs to coexist on different uart instances. As both APIs cannot be used simultaneously for a given instance, there is no need to handle CONFIG_UART_EXCLUSIVE_API_CALLBACKS in this driver. Signed-off-by: Eivind Jølsgard --- drivers/serial/uart_nrfx_uarte.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index bdafe6c7d4c..017efa6a2e5 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -937,11 +937,6 @@ static int uarte_nrfx_callback_set(const struct device *dev, data->async->user_callback = callback; data->async->user_data = user_data; -#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(UARTE_INTERRUPT_DRIVEN) - data->int_driven->cb = NULL; - data->int_driven->cb_data = NULL; -#endif - return 0; } @@ -1680,11 +1675,6 @@ static void uarte_nrfx_irq_callback_set(const struct device *dev, data->int_driven->cb = cb; data->int_driven->cb_data = cb_data; - -#if defined(UARTE_ANY_ASYNC) && defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) - data->async->user_callback = NULL; - data->async->user_data = NULL; -#endif } #endif /* UARTE_INTERRUPT_DRIVEN */ From 8e6b401ca476f17f3a640c51b05031e42ffa26f1 Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Fri, 15 Sep 2023 19:01:08 +0100 Subject: [PATCH 0710/4498] drivers: spi: stm32h7 Check nocache memory correctly The way of setting a nocache region in devicetree has changed. Adapt the H7 SPI driver to this new circumstance. Signed-off-by: Daniel Gaston Ochoa --- drivers/spi/spi_ll_stm32.c | 45 ++++++-------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index dc640613882..0911cb96f58 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -27,6 +27,10 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #include #include +#ifdef CONFIG_SOC_SERIES_STM32H7X +#include +#endif + #ifdef CONFIG_NOCACHE_MEMORY #include #endif /* CONFIG_NOCACHE_MEMORY */ @@ -57,35 +61,6 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #ifdef CONFIG_SPI_STM32_DMA -#ifdef CONFIG_SOC_SERIES_STM32H7X - -#define IS_NOCACHE_MEM_REGION(node_id) \ - COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, zephyr_memory_attr, RAM_NOCACHE), \ - (1), \ - (0)) - -#define GET_MEM_REGION(node_id) \ - { \ - .start = DT_REG_ADDR(node_id), \ - .end = (DT_REG_ADDR(node_id) + DT_REG_SIZE(node_id)) - 1, \ - }, - -#define GET_MEM_REGION_IF_NOCACHE(node_id) \ - COND_CODE_1(IS_NOCACHE_MEM_REGION(node_id), \ - ( \ - GET_MEM_REGION(node_id) \ - ), ()) - -struct mem_region { - uintptr_t start; - uintptr_t end; -}; - -static const struct mem_region nocache_mem_regions[] = { - DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(GET_MEM_REGION_IF_NOCACHE) -}; -#endif /* CONFIG_SOC_SERIES_STM32H7X */ - /* dummy value used for transferring NOP when tx buf is null * and use as dummy sink for when rx buf is null */ @@ -771,16 +746,10 @@ static bool buf_in_nocache(uintptr_t buf, size_t len_bytes) } #endif /* CONFIG_NOCACHE_MEMORY */ - for (size_t i = 0; i < ARRAY_SIZE(nocache_mem_regions); i++) { - const struct mem_region *mem_reg = &nocache_mem_regions[i]; + buf_within_nocache = mem_attr_check_buf( + (void *)buf, len_bytes, DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE)) == 0; - buf_within_nocache = - (buf >= mem_reg->start) && ((buf + len_bytes - 1) <= mem_reg->end); - if (buf_within_nocache) { - return true; - } - } - return false; + return buf_within_nocache; } static bool is_dummy_buffer(const struct spi_buf *buf) From 0e72d63a0177744a49b6a0be71e1c9c012fa121c Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Tue, 12 Sep 2023 10:38:45 +0100 Subject: [PATCH 0711/4498] drivers: spi: stm32h7 Fix SPI DMA 16 bits frames Modify STM32H7 SPI driver so that it updates the rx/tx pointers correctly (depending on the frame size) when DMA is enabled. Also, make the dummy rx/tx buffer cache-coherent. Signed-off-by: Daniel Gaston Ochoa --- drivers/spi/Kconfig.stm32 | 1 + drivers/spi/spi_ll_stm32.c | 49 ++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/spi/Kconfig.stm32 b/drivers/spi/Kconfig.stm32 index 0096d800df2..8baa5880192 100644 --- a/drivers/spi/Kconfig.stm32 +++ b/drivers/spi/Kconfig.stm32 @@ -21,6 +21,7 @@ config SPI_STM32_INTERRUPT config SPI_STM32_DMA bool "STM32 MCU SPI DMA Support" select DMA + select CACHE_MANAGEMENT if CPU_HAS_DCACHE help Enable the SPI DMA mode for SPI instances that enable dma channels in their device tree node. diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 0911cb96f58..e62a763a3f9 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -33,10 +33,24 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #ifdef CONFIG_NOCACHE_MEMORY #include +#elif defined(CONFIG_CACHE_MANAGEMENT) +#include #endif /* CONFIG_NOCACHE_MEMORY */ #include "spi_ll_stm32.h" +/* + * Check defined(CONFIG_DCACHE) because some platforms disable it in the tests + * e.g. nucleo_f746zg + */ +#if defined(CONFIG_CPU_HAS_DCACHE) && \ + defined(CONFIG_DCACHE) && \ + !defined(CONFIG_NOCACHE_MEMORY) +#define SPI_STM32_MANUAL_CACHE_COHERENCY_REQUIRED 1 +#else +#define SPI_STM32_MANUAL_CACHE_COHERENCY_REQUIRED 0 +#endif /* defined(CONFIG_CPU_HAS_DCACHE) && !defined(CONFIG_NOCACHE_MEMORY) */ + #define WAIT_1US 1U /* @@ -60,11 +74,30 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #endif /* CONFIG_SOC_SERIES_STM32MP1X */ #ifdef CONFIG_SPI_STM32_DMA +static uint32_t bits2bytes(uint32_t bits) +{ + return bits / 8; +} /* dummy value used for transferring NOP when tx buf is null - * and use as dummy sink for when rx buf is null + * and use as dummy sink for when rx buf is null. + */ +#ifdef CONFIG_NOCACHE_MEMORY +/* + * If a nocache area is available, place it there to avoid potential DMA + * cache-coherency problems. */ -uint32_t dummy_rx_tx_buffer; +static __aligned(32) uint32_t dummy_rx_tx_buffer + __attribute__((__section__(".nocache"))); + +#else /* CONFIG_NOCACHE_MEMORY */ + +/* + * If nocache areas are not available, cache coherency might need to be kept + * manually. See SPI_STM32_MANUAL_CACHE_COHERENCY_REQUIRED. + */ +static __aligned(32) uint32_t dummy_rx_tx_buffer; +#endif /* CONFIG_NOCACHE_MEMORY */ /* This function is executed in the interrupt context */ static void dma_callback(const struct device *dev, void *arg, @@ -113,8 +146,11 @@ static int spi_stm32_dma_tx_load(const struct device *dev, const uint8_t *buf, /* tx direction has memory as source and periph as dest. */ if (buf == NULL) { - dummy_rx_tx_buffer = 0; /* if tx buff is null, then sends NOP on the line. */ + dummy_rx_tx_buffer = 0; +#if SPI_STM32_MANUAL_CACHE_COHERENCY_REQUIRED + arch_dcache_flush_range((void *)&dummy_rx_tx_buffer, sizeof(uint32_t)); +#endif /* CONFIG_CPU_HAS_DCACHE && !defined(CONFIG_NOCACHE_MEMORY) */ blk_cfg->source_address = (uint32_t)&dummy_rx_tx_buffer; blk_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; } else { @@ -876,8 +912,11 @@ static int transceive_dma(const struct device *dev, LL_SPI_DisableDMAReq_RX(spi); #endif /* ! st_stm32h7_spi */ - spi_context_update_tx(&data->ctx, 1, dma_len); - spi_context_update_rx(&data->ctx, 1, dma_len); + uint8_t frame_size_bytes = bits2bytes( + SPI_WORD_SIZE_GET(config->operation)); + + spi_context_update_tx(&data->ctx, frame_size_bytes, dma_len); + spi_context_update_rx(&data->ctx, frame_size_bytes, dma_len); } /* spi complete relies on SPI Status Reg which cannot be disabled */ From 382eaf7baaa8258f659ee78665a1e80daf837477 Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Tue, 12 Sep 2023 10:42:49 +0100 Subject: [PATCH 0712/4498] tests: drivers: spi: stm32h7: Run 16-bit frames tests for DMA Run 16-bit frames tests also when DMA is enabled. In addition, remove the extra code required for the mentioned tests in favor of config. files, and add test cases for nocache regions defined in devicetree. Signed-off-by: Daniel Gaston Ochoa --- tests/drivers/spi/spi_loopback/Kconfig | 17 +++ .../spi_loopback/boards/nucleo_h743zi.overlay | 6 + .../spi_loopback/boards/nucleo_h753zi.overlay | 6 + ...erlay-stm32-spi-16bits-dma-no-nocache.conf | 14 +++ .../overlay-stm32-spi-16bits-dma.conf | 11 ++ .../overlay-stm32-spi-16bits.conf | 6 + .../overlay-stm32-spi-16bits.overlay | 37 ++++++ .../overlay-stm32-spi-dma-no-nocache.conf | 7 ++ tests/drivers/spi/spi_loopback/src/spi.c | 106 +++++++----------- tests/drivers/spi/spi_loopback/testcase.yaml | 30 +++++ 10 files changed, 172 insertions(+), 68 deletions(-) create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma-no-nocache.conf create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma.conf create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.conf create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.overlay create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-dma-no-nocache.conf diff --git a/tests/drivers/spi/spi_loopback/Kconfig b/tests/drivers/spi/spi_loopback/Kconfig index 5f1033ea470..8c26b723092 100644 --- a/tests/drivers/spi/spi_loopback/Kconfig +++ b/tests/drivers/spi/spi_loopback/Kconfig @@ -6,3 +6,20 @@ source "Kconfig.zephyr" config SPI_LOOPBACK_MODE_LOOP bool "Configure the SPI in LOOP mode, so that no extra wiring is needed" + +if SOC_SERIES_STM32H7X + +config SPI_LOOPBACK_16BITS_FRAMES + bool "Use 16 bits frames for tests" + +config DT_DEFINED_NOCACHE + bool "Enable this if nocache regions are defined in devicetree" + +if DT_DEFINED_NOCACHE + +config DT_DEFINED_NOCACHE_NAME + string "Name of the nocache region defined in devicetree (capitals)" + +endif # DT_DEFINED_NOCACHE + +endif # SOC_SERIES_STM32H7X diff --git a/tests/drivers/spi/spi_loopback/boards/nucleo_h743zi.overlay b/tests/drivers/spi/spi_loopback/boards/nucleo_h743zi.overlay index 7e3b9a2d6c2..0b6e78046f5 100644 --- a/tests/drivers/spi/spi_loopback/boards/nucleo_h743zi.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nucleo_h743zi.overlay @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + +&sram2 { + zephyr,memory-attr = < DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) >; +}; + &spi1 { dmas = <&dmamux1 0 38 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH) &dmamux1 1 37 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH)>; diff --git a/tests/drivers/spi/spi_loopback/boards/nucleo_h753zi.overlay b/tests/drivers/spi/spi_loopback/boards/nucleo_h753zi.overlay index 5fc1ba71d53..e9aa1127ab7 100644 --- a/tests/drivers/spi/spi_loopback/boards/nucleo_h753zi.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nucleo_h753zi.overlay @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + +&sram2 { + zephyr,memory-attr = < DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) >; +}; + &spi1 { dmas = <&dmamux1 0 38 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH) &dmamux1 1 37 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH)>; diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma-no-nocache.conf b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma-no-nocache.conf new file mode 100644 index 00000000000..4bb96e35f58 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma-no-nocache.conf @@ -0,0 +1,14 @@ +# +# Copyright (c) 2023 Graphcore Ltd, All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# enable DMA mode for SPI loopback test +CONFIG_SPI_STM32_DMA=y +CONFIG_SPI_STM32_INTERRUPT=n +CONFIG_SPI_ASYNC=n +CONFIG_NOCACHE_MEMORY=n +CONFIG_DT_DEFINED_NOCACHE=y +CONFIG_DT_DEFINED_NOCACHE_NAME="SRAM2" +CONFIG_SPI_LOOPBACK_16BITS_FRAMES=y diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma.conf b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma.conf new file mode 100644 index 00000000000..c49efea868a --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits-dma.conf @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Graphcore Ltd, All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# enable DMA mode for SPI loopback test +CONFIG_SPI_STM32_DMA=y +CONFIG_SPI_STM32_INTERRUPT=n +CONFIG_SPI_ASYNC=n +CONFIG_SPI_LOOPBACK_16BITS_FRAMES=y diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.conf b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.conf new file mode 100644 index 00000000000..00ca04782b4 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.conf @@ -0,0 +1,6 @@ +# +# Copyright (c) 2023 Graphcore Ltd, All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_SPI_LOOPBACK_16BITS_FRAMES=y diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.overlay b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.overlay new file mode 100644 index 00000000000..ee0ad036da6 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-16bits.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Graphcore Ltd, All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sram2 { + zephyr,memory-attr = < DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) >; +}; + +&spi1 { + dmas = <&dmamux1 0 38 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH | STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS) + &dmamux1 1 37 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH | STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS)>; + dma-names = "tx", "rx"; + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&dma1 { + status = "okay"; +}; + +&dma2 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-dma-no-nocache.conf b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-dma-no-nocache.conf new file mode 100644 index 00000000000..12eeb52c3b2 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-dma-no-nocache.conf @@ -0,0 +1,7 @@ +# enable DMA mode for SPI loopback test +CONFIG_SPI_STM32_DMA=y +CONFIG_SPI_STM32_INTERRUPT=n +CONFIG_SPI_ASYNC=n +CONFIG_NOCACHE_MEMORY=n +CONFIG_DT_DEFINED_NOCACHE=y +CONFIG_DT_DEFINED_NOCACHE_NAME="SRAM2" diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index a1904395847..2d7eeef6663 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -25,17 +25,32 @@ LOG_MODULE_REGISTER(spi_loopback); #define MODE_LOOP 0 #endif -#define SPI_OP(frame_size) SPI_OP_MODE_MASTER | SPI_MODE_CPOL | MODE_LOOP | \ - SPI_MODE_CPHA | SPI_WORD_SET(frame_size) | SPI_LINES_SINGLE +#ifdef CONFIG_SPI_LOOPBACK_16BITS_FRAMES +#define FRAME_SIZE (16) +#define FRAME_SIZE_STR ", frame size = 16" +#else +#define FRAME_SIZE (8) +#define FRAME_SIZE_STR ", frame size = 8" +#endif /* CONFIG_SPI_LOOPBACK_16BITS_FRAMES */ +#ifdef CONFIG_DMA + +#ifdef CONFIG_NOCACHE_MEMORY +#define DMA_ENABLED_STR ", DMA enabled" +#else /* CONFIG_NOCACHE_MEMORY */ +#define DMA_ENABLED_STR ", DMA enabled (without CONFIG_NOCACHE_MEMORY)" +#endif -static struct spi_dt_spec spi_fast = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP(8), 0); -static struct spi_dt_spec spi_slow = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP(8), 0); +#else /* CONFIG_DMA */ + +#define DMA_ENABLED_STR +#endif /* CONFIG_DMA */ + +#define SPI_OP(frame_size) SPI_OP_MODE_MASTER | SPI_MODE_CPOL | MODE_LOOP | \ + SPI_MODE_CPHA | SPI_WORD_SET(frame_size) | SPI_LINES_SINGLE -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) -static __used struct spi_dt_spec spi_fast_16 = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP(16), 0); -static __used struct spi_dt_spec spi_slow_16 = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP(16), 0); -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ +static struct spi_dt_spec spi_fast = SPI_DT_SPEC_GET(SPI_FAST_DEV, SPI_OP(FRAME_SIZE), 0); +static struct spi_dt_spec spi_slow = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI_OP(FRAME_SIZE), 0); /* to run this test, connect MOSI pin to the MISO of the SPI */ @@ -44,20 +59,19 @@ static __used struct spi_dt_spec spi_slow_16 = SPI_DT_SPEC_GET(SPI_SLOW_DEV, SPI #define BUF2_SIZE 36 #if CONFIG_NOCACHE_MEMORY +#define __NOCACHE __attribute__((__section__(".nocache"))) +#elif defined(CONFIG_DT_DEFINED_NOCACHE) +#define __NOCACHE __attribute__((__section__(CONFIG_DT_DEFINED_NOCACHE_NAME))) +#else /* CONFIG_NOCACHE_MEMORY */ +#define __NOCACHE +#endif /* CONFIG_NOCACHE_MEMORY */ + static const char tx_data[BUF_SIZE] = "0123456789abcdef-\0"; -static __aligned(32) char buffer_tx[BUF_SIZE] __used __attribute__((__section__(".nocache"))); -static __aligned(32) char buffer_rx[BUF_SIZE] __used __attribute__((__section__(".nocache"))); +static __aligned(32) char buffer_tx[BUF_SIZE] __used __NOCACHE; +static __aligned(32) char buffer_rx[BUF_SIZE] __used __NOCACHE; static const char tx2_data[BUF2_SIZE] = "Thequickbrownfoxjumpsoverthelazydog\0"; -static __aligned(32) char buffer2_tx[BUF2_SIZE] __used __attribute__((__section__(".nocache"))); -static __aligned(32) char buffer2_rx[BUF2_SIZE] __used __attribute__((__section__(".nocache"))); -#else -/* this src memory shall be in RAM to support using as a DMA source pointer.*/ -static uint8_t buffer_tx[] = "0123456789abcdef-\0"; -static uint8_t buffer_rx[BUF_SIZE] = {}; - -static uint8_t buffer2_tx[] = "Thequickbrownfoxjumpsoverthelazydog\0"; -static uint8_t buffer2_rx[BUF2_SIZE] = {}; -#endif +static __aligned(32) char buffer2_tx[BUF2_SIZE] __used __NOCACHE; +static __aligned(32) char buffer2_rx[BUF2_SIZE] __used __NOCACHE; /* * We need 5x(buffer size) + 1 to print a comma-separated list of each @@ -539,7 +553,10 @@ ZTEST(spi_loopback, test_spi_loopback) struct k_thread async_thread; k_tid_t async_thread_id; #endif - LOG_INF("SPI test on buffers TX/RX %p/%p", buffer_tx, buffer_rx); + + LOG_INF("SPI test on buffers TX/RX %p/%p" FRAME_SIZE_STR DMA_ENABLED_STR, + buffer_tx, + buffer_rx); #if (CONFIG_SPI_ASYNC) async_thread_id = k_thread_create(&async_thread, @@ -582,51 +599,6 @@ ZTEST(spi_loopback, test_spi_loopback) goto end; } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) - -/* 16 bits DMA test require to change dmamux config. by adding: - * STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS - */ -#ifndef CONFIG_SPI_STM32_DMA - - zassert_true(spi_is_ready_dt(&spi_slow_16), - "Slow spi lookback (16 bits) device is not ready"); - - LOG_INF("SPI test slow config (16 bits)"); - - if (spi_complete_multiple(&spi_slow_16) || - spi_complete_loop(&spi_slow_16) || - spi_null_tx_buf(&spi_slow_16) || - spi_rx_half_start(&spi_slow_16) || - spi_rx_half_end(&spi_slow_16) || - spi_rx_every_4(&spi_slow_16) -#if (CONFIG_SPI_ASYNC) - || spi_async_call(&spi_slow_16) -#endif /* (CONFIG_SPI_ASYNC) */ - ) { - goto end; - } - - zassert_true(spi_is_ready_dt(&spi_fast_16), - "Fast spi lookback (16 bits) device is not ready"); - - LOG_INF("SPI test fast config (16 bits)"); - - if (spi_complete_multiple(&spi_fast_16) || - spi_complete_loop(&spi_fast_16) || - spi_null_tx_buf(&spi_fast_16) || - spi_rx_half_start(&spi_fast_16) || - spi_rx_half_end(&spi_fast_16) || - spi_rx_every_4(&spi_fast_16) -#if (CONFIG_SPI_ASYNC) - || spi_async_call(&spi_fast_16) -#endif /* (CONFIG_SPI_ASYNC) */ - ) { - goto end; - } -#endif /* CONFIG_SPI_STM32_DMA */ -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ - if (spi_resource_lock_test(&spi_slow, &spi_fast)) { goto end; } @@ -642,12 +614,10 @@ ZTEST(spi_loopback, test_spi_loopback) static void *spi_loopback_setup(void) { -#if CONFIG_NOCACHE_MEMORY memset(buffer_tx, 0, sizeof(buffer_tx)); memcpy(buffer_tx, tx_data, sizeof(tx_data)); memset(buffer2_tx, 0, sizeof(buffer2_tx)); memcpy(buffer2_tx, tx2_data, sizeof(tx2_data)); -#endif return NULL; } diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index a71f2d9b885..e1d36d593fb 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -32,6 +32,13 @@ tests: - tdk_robokit1 integration_platforms: - sam_e70_xplained + drivers.spi.stm32_spi_16bits_frames.loopback: + extra_args: + - OVERLAY_CONFIG="overlay-stm32-spi-16bits.conf" + - DTC_OVERLAY_FILE="overlay-stm32-spi-16bits.overlay" + platform_allow: + - nucleo_h743zi + - nucleo_h753zi drivers.spi.stm32_spi_dma.loopback: extra_args: OVERLAY_CONFIG="overlay-stm32-spi-dma.conf" filter: CONFIG_SOC_FAMILY_STM32 @@ -48,6 +55,29 @@ tests: - stm32h573i_dk integration_platforms: - nucleo_g474re + drivers.spi.stm32_spi_dma_no_nocache.loopback: + extra_args: + - OVERLAY_CONFIG="overlay-stm32-spi-dma-no-nocache.conf" + filter: CONFIG_SOC_FAMILY_STM32 + platform_allow: + - nucleo_h743zi + - nucleo_h753zi + drivers.spi.stm32_spi_16bits_frames_dma.loopback: + extra_args: + - OVERLAY_CONFIG="overlay-stm32-spi-16bits-dma.conf" + - DTC_OVERLAY_FILE="overlay-stm32-spi-16bits.overlay" + filter: CONFIG_SOC_FAMILY_STM32 + platform_allow: + - nucleo_h743zi + - nucleo_h753zi + drivers.spi.stm32_spi_16bits_frames_dma_no_nocache.loopback: + extra_args: + - OVERLAY_CONFIG="overlay-stm32-spi-16bits-dma-no-nocache.conf" + - DTC_OVERLAY_FILE="overlay-stm32-spi-16bits.overlay" + filter: CONFIG_SOC_FAMILY_STM32 + platform_allow: + - nucleo_h743zi + - nucleo_h753zi drivers.spi.gd32_spi_interrupt.loopback: extra_args: OVERLAY_CONFIG="overlay-gd32-spi-interrupt.conf" platform_allow: From a63bb6317cbfc3a99a84221beb2740e601c1bb09 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Wed, 13 Sep 2023 19:55:08 +0200 Subject: [PATCH 0713/4498] drivers: rtc: stm32: allow new RTC driver to work with BBRAM STM32 BBRAM depends on RTC to work. This changes STM32 RTC init stage to PRE_KERNEL_1 to allow RTC driver to initialize before BBRAM driver. Some adjustments are made so that kernel API is not used during the init procedure. Signed-off-by: Johan Lafon --- drivers/bbram/Kconfig.stm32 | 2 +- drivers/rtc/Kconfig.stm32 | 1 + drivers/rtc/rtc_ll_stm32.c | 28 ++++++++++++++++++++-------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/bbram/Kconfig.stm32 b/drivers/bbram/Kconfig.stm32 index e3cbd3bbd40..ec372cb3ecb 100644 --- a/drivers/bbram/Kconfig.stm32 +++ b/drivers/bbram/Kconfig.stm32 @@ -5,7 +5,7 @@ config BBRAM_STM32 bool "ST STM32 Battery-backed RAM drivers" default y depends on DT_HAS_ST_STM32_BBRAM_ENABLED - depends on COUNTER + depends on COUNTER_RTC_STM32 || RTC_STM32 help This option enables the BBRAM driver for STM32 family of processors. diff --git a/drivers/rtc/Kconfig.stm32 b/drivers/rtc/Kconfig.stm32 index 6842b68a84b..1cdbe99ca0b 100644 --- a/drivers/rtc/Kconfig.stm32 +++ b/drivers/rtc/Kconfig.stm32 @@ -5,6 +5,7 @@ config RTC_STM32 bool "STM32 RTC driver" default y if !COUNTER depends on DT_HAS_ST_STM32_RTC_ENABLED && !SOC_SERIES_STM32F1X + select USE_STM32_LL_RTC select USE_STM32_LL_PWR select USE_STM32_LL_RCC help diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 93fd146df5c..51e3fd12ad4 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -25,6 +25,8 @@ #include +#include + LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); /* RTC start time: 1st, Jan, 2000 */ @@ -68,14 +70,24 @@ struct rtc_stm32_data { struct k_mutex lock; }; -static int rtc_stm32_enter_initialization_mode(void) +static int rtc_stm32_enter_initialization_mode(bool kernel_available) { - LL_RTC_EnableInitMode(RTC); + if (kernel_available) { + LL_RTC_EnableInitMode(RTC); + bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); - bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); + if (!success) { + return -EIO; + } + } else { + /* kernel is not available so use the blocking but otherwise equivalent function + * provided by LL + */ + ErrorStatus status = LL_RTC_EnterInitMode(RTC); - if (!success) { - return -EIO; + if (status != SUCCESS) { + return -EIO; + } } return 0; @@ -104,7 +116,7 @@ static int rtc_stm32_configure(const struct device *dev) if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) || (sync_prescaler != cfg->sync_prescaler) || (async_prescaler != cfg->async_prescaler)) { - err = rtc_stm32_enter_initialization_mode(); + err = rtc_stm32_enter_initialization_mode(false); if (err == 0) { LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR); LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler); @@ -191,7 +203,7 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); - err = rtc_stm32_enter_initialization_mode(); + err = rtc_stm32_enter_initialization_mode(true); if (err) { k_mutex_unlock(&data->lock); return err; @@ -387,5 +399,5 @@ static const struct rtc_stm32_config rtc_config = { static struct rtc_stm32_data rtc_data; -DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, POST_KERNEL, +DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1, CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api); From 469ba4e36768399767dd0f9e1fa5144b183cb660 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 18 Sep 2023 15:34:11 +0200 Subject: [PATCH 0714/4498] driver: rtc: stm23: fix build for STM32L1 Cat.1 The Cat.1 STM32L1 MCUs do not provide the subsecond feature. This disable subsecond related code for these MCUs. Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index 51e3fd12ad4..8714439ef47 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -29,6 +29,13 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); +#if defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SUBSECOND_SUPPORT) +/* subsecond counting is not supported by some STM32L1x MCUs */ +#define HW_SUBSECOND_SUPPORT (0) +#else +#define HW_SUBSECOND_SUPPORT (1) +#endif + /* RTC start time: 1st, Jan, 2000 */ #define RTC_YEAR_REF 2000 /* struct tm start time: 1st, Jan, 1900 */ @@ -237,10 +244,14 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr) { - const struct rtc_stm32_config *cfg = dev->config; struct rtc_stm32_data *data = dev->data; - uint32_t rtc_date, rtc_time, rtc_subsecond; + uint32_t rtc_date, rtc_time; + +#if HW_SUBSECOND_SUPPORT + const struct rtc_stm32_config *cfg = dev->config; + uint32_t rtc_subsecond; +#endif int err = k_mutex_lock(&data->lock, K_NO_WAIT); @@ -258,7 +269,9 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr * while doing so as it will result in an erroneous result otherwise */ rtc_time = LL_RTC_TIME_Get(RTC); +#if HW_SUBSECOND_SUPPORT rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); +#endif } while (rtc_time != LL_RTC_TIME_Get(RTC)); } while (rtc_date != LL_RTC_DATE_Get(RTC)); @@ -283,9 +296,13 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr timeptr->tm_min = bcd2bin(__LL_RTC_GET_MINUTE(rtc_time)); timeptr->tm_sec = bcd2bin(__LL_RTC_GET_SECOND(rtc_time)); +#if HW_SUBSECOND_SUPPORT uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L; timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, cfg->sync_prescaler + 1); +#else + timeptr->tm_nsec = 0; +#endif /* unknown values */ timeptr->tm_yday = -1; From a4e610a4eeabad71a74fcec7fd2252bcb8ebc242 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 18 Sep 2023 12:08:15 +0200 Subject: [PATCH 0715/4498] tests: drivers: bbram: add a second stm32 test entry BBRAM can now depend on the new RTC driver implementation instead of the old counter based one. This adds the corresponding test scenario. Signed-off-by: Johan Lafon --- tests/drivers/bbram/stm32_rtc.conf | 1 + tests/drivers/bbram/testcase.yaml | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 tests/drivers/bbram/stm32_rtc.conf diff --git a/tests/drivers/bbram/stm32_rtc.conf b/tests/drivers/bbram/stm32_rtc.conf new file mode 100644 index 00000000000..3a87a9c6c6e --- /dev/null +++ b/tests/drivers/bbram/stm32_rtc.conf @@ -0,0 +1 @@ +CONFIG_RTC=y diff --git a/tests/drivers/bbram/testcase.yaml b/tests/drivers/bbram/testcase.yaml index 00dd965870a..00f0eb9bcc9 100644 --- a/tests/drivers/bbram/testcase.yaml +++ b/tests/drivers/bbram/testcase.yaml @@ -22,3 +22,8 @@ tests: filter: dt_compat_enabled("st,stm32-bbram") integration_platforms: - stm32f746g_disco + driver.bbram.stm32_rtc: + extra_args: OVERLAY_CONFIG="stm32_rtc.conf" + filter: dt_compat_enabled("st,stm32-bbram") + integration_platforms: + - stm32f746g_disco From da11b5fc09069f102dfbed90a3eafa723b661430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Mon, 18 Sep 2023 13:00:56 +0200 Subject: [PATCH 0716/4498] Documentation: Update `bt_gatt_discover_params` & `bt_gatt_discover_params` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documentation for `bt_gatt_subscribe_params` and `bt_gatt_discover_params` is not complete. `CONFIG_BT_GATT_AUTO_DISCOVER_CCC` need to be selected so Doxygen add see `end_handle`, `disc_params` and `sub_params`. Signed-off-by: Théo Battrel --- include/zephyr/bluetooth/gatt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index e4aae4e4d41..4826e93e6fd 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -1463,10 +1463,10 @@ struct bt_gatt_discover_params { uint16_t end_handle; /** Discover type */ uint8_t type; -#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) +#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) || defined(__DOXYGEN__) /** Only for stack-internal use, used for automatic discovery. */ struct bt_gatt_subscribe_params *sub_params; -#endif /* defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) */ +#endif /* defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) || defined(__DOXYGEN__) */ #if defined(CONFIG_BT_EATT) enum bt_att_chan_opt chan_opt; #endif /* CONFIG_BT_EATT */ @@ -1831,12 +1831,12 @@ struct bt_gatt_subscribe_params { uint16_t value_handle; /** Subscribe CCC handle */ uint16_t ccc_handle; -#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) +#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) || defined(__DOXYGEN__) /** Subscribe End handle (for automatic discovery) */ uint16_t end_handle; /** Discover parameters used when ccc_handle = 0 */ struct bt_gatt_discover_params *disc_params; -#endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */ +#endif /* defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) || defined(__DOXYGEN__) */ /** Subscribe value */ uint16_t value; #if defined(CONFIG_BT_SMP) From a24460a7db45eacc9a82b97c9861c432c484a846 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Fri, 15 Sep 2023 16:45:27 -0700 Subject: [PATCH 0717/4498] drivers: sensor: tmp116: Added ability to read configuration register Added ability to read contents of TMP116 configuration register by adding an attribute get function that supports the SENSOR_ATTR_CONFIGURATION option. Followed the same approach as the TMP108 driver. Interpretation of the returned value is left up to the caller. Tested using Nucleo-F401RE and Temp-Log 2 (TMP116) click board and confirmed a read of the configuration register returned the expected value. Signed-off-by: Ian Morris --- drivers/sensor/tmp116/tmp116.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/sensor/tmp116/tmp116.c b/drivers/sensor/tmp116/tmp116.c index a327f522f05..4972ac443a2 100644 --- a/drivers/sensor/tmp116/tmp116.c +++ b/drivers/sensor/tmp116/tmp116.c @@ -257,8 +257,36 @@ static int tmp116_attr_set(const struct device *dev, } } +static int tmp116_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + uint16_t data; + int rc; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_CONFIGURATION: + rc = tmp116_reg_read(dev, TMP116_REG_CFGR, &data); + if (rc < 0) { + return rc; + } + break; + default: + return -ENOTSUP; + } + + val->val1 = data; + val->val2 = 0; + + return 0; +} + static const struct sensor_driver_api tmp116_driver_api = { .attr_set = tmp116_attr_set, + .attr_get = tmp116_attr_get, .sample_fetch = tmp116_sample_fetch, .channel_get = tmp116_channel_get }; From 2e0981b65866c149e3321d6978ffe283cb1e5994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rait=20R=C3=A4=C3=A4k?= Date: Wed, 20 Sep 2023 11:24:44 +1000 Subject: [PATCH 0718/4498] bluetooth: ead: Add C++ include support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bluetooth EAD header is missing C++ include support (extern C). Add support for including from C++. Signed-off-by: Rait Rääk --- include/zephyr/bluetooth/ead.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/zephyr/bluetooth/ead.h b/include/zephyr/bluetooth/ead.h index ba4de42ce40..8aaee2e4136 100644 --- a/include/zephyr/bluetooth/ead.h +++ b/include/zephyr/bluetooth/ead.h @@ -11,6 +11,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Encrypted Advertising Data (EAD) * @defgroup bt_ead Encrypted Advertising Data (EAD) @@ -104,4 +108,8 @@ int bt_ead_decrypt(const uint8_t session_key[BT_EAD_KEY_SIZE], const uint8_t iv[ * @} */ +#ifdef __cplusplus +} +#endif + #endif /* ZEPHYR_INCLUDE_BLUETOOTH_EAD_H_ */ From a4cabee9d877a349963635eef4d1f9f063d7508b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 11:50:55 +0200 Subject: [PATCH 0719/4498] samples: net: doc: fix bad code-sample id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Echo server simple sample is referred to as sockets-echo, not socket-echo. Signed-off-by: Benjamin Cabé --- samples/net/sockets/echo/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/sockets/echo/README.rst b/samples/net/sockets/echo/README.rst index 68edc84c46f..005036ca538 100644 --- a/samples/net/sockets/echo/README.rst +++ b/samples/net/sockets/echo/README.rst @@ -1,4 +1,4 @@ -.. zephyr:code-sample:: socket-echo +.. zephyr:code-sample:: sockets-echo :name: Echo server (simple) :relevant-api: bsd_sockets From d65d3046a577cd079943ad1fda57e2ca95db911d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 11:51:51 +0200 Subject: [PATCH 0720/4498] samples: usb: wpanusb: fix bad code-sample id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WPAN USB sample is referred to as wpan-usb, not _wpansub. Signed-off-by: Benjamin Cabé --- boards/arm/atsamr21_xpro/doc/index.rst | 2 +- samples/net/wpanusb/README.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/arm/atsamr21_xpro/doc/index.rst b/boards/arm/atsamr21_xpro/doc/index.rst index 139b6ea6bcb..da9cb14a437 100644 --- a/boards/arm/atsamr21_xpro/doc/index.rst +++ b/boards/arm/atsamr21_xpro/doc/index.rst @@ -159,7 +159,7 @@ externally connected SPI devices. +-------------+------------------------------------------------------------------------------------------+ Zephyr provide several samples that can use this technology. You can check -:zephyr:code-sample:`wpanusb` and :zephyr:code-sample:`wpan-serial` examples as starting +:zephyr:code-sample:`wpan-usb` and :zephyr:code-sample:`wpan-serial` examples as starting points. Another good test can be done with IPv6 by using the server/client echo demo. More information at :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client`. diff --git a/samples/net/wpanusb/README.rst b/samples/net/wpanusb/README.rst index aa4b6e38e14..27c6c2bae72 100644 --- a/samples/net/wpanusb/README.rst +++ b/samples/net/wpanusb/README.rst @@ -1,4 +1,4 @@ -.. zephyr:code-sample:: _wpanusb +.. zephyr:code-sample:: wpan-usb :name: 802.15.4 USB :relevant-api: ieee802154 _usb_device_core_api From 430e009a5f2e3ecc58de5e7afd7b1a94ea94e3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 11:58:09 +0200 Subject: [PATCH 0721/4498] samples: net: mqtt-sn: fix bad code-sample id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MQTT-SN publisher sample is referred to as mqtt-sn-publisher, not mqtt-sn-publisher-sample. Signed-off-by: Benjamin Cabé --- doc/connectivity/networking/api/mqtt_sn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connectivity/networking/api/mqtt_sn.rst b/doc/connectivity/networking/api/mqtt_sn.rst index 13860346946..3da4d903725 100644 --- a/doc/connectivity/networking/api/mqtt_sn.rst +++ b/doc/connectivity/networking/api/mqtt_sn.rst @@ -124,7 +124,7 @@ has no effect on the transport, however. If you want to close the transport (e.g the socket), call ``mqtt_sn_client_deinit``, which will deinit the transport as well. Zephyr provides sample code utilizing the MQTT-SN client API. See -:zephyr:code-sample:`mqtt-sn-publisher-sample` for more information. +:zephyr:code-sample:`mqtt-sn-publisher` for more information. Deviations from the standard **************************** From 944f0d48759058c46e952bed44bbfab7335a99bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 11:59:06 +0200 Subject: [PATCH 0722/4498] samples: net: fix bad gsm-modem code-sample id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GSM Modem sample is referred to as gsm-modem, not gsm-modem-sample. Signed-off-by: Benjamin Cabé --- samples/subsys/mgmt/updatehub/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index aea33944193..3f19982f838 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -203,7 +203,7 @@ Step 4.3: Build for Modem Modem needs add ``overlay-modem.conf``. Now, a DTC overlay file is used to configure the glue between the modem and an arduino headers. The modem config -uses PPP over GSM modem, see :zephyr:code-sample:`gsm-modem-sample` sample application. +uses PPP over GSM modem, see :zephyr:code-sample:`gsm-modem` sample application. .. zephyr-app-commands:: :zephyr-app: zephyr/samples/subsys/mgmt/updatehub From c82d0232485aa75525298985cf805c569620e6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 11:54:23 +0200 Subject: [PATCH 0723/4498] doc: Issue warning for dangling code-sample references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sphinx will now issue a warning when a code-sample role points to a sample that does not exist. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 969eca33817..d9ba85114fd 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -214,7 +214,7 @@ class ZephyrDomain(Domain): label = "Zephyr Project" roles = { - "code-sample": XRefRole(innernodeclass=nodes.inline), + "code-sample": XRefRole(innernodeclass=nodes.inline, warn_dangling=True), } directives = {"code-sample": CodeSampleDirective} From 813e40f818613b1f2649e4113b1821473e42a585 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Wed, 20 Sep 2023 13:21:34 +0200 Subject: [PATCH 0724/4498] twister: Ignore skips due to toolchain incompatibility. Skips are turned to errors on integration platforms. However, if a user (or a CI) selects toolchain other than zephyr, unexpected errors due to skips can appear. With this commit skips due to toolchain incompatibilities are not treated as errors. Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/testplan.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index d8873eade0a..1a524a67019 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -62,6 +62,8 @@ class Filters: QUARENTINE = 'Quarantine filter' # in case a test suite is skipped intentionally . SKIP = 'Skip filter' + # in case of incompatibility between selected and allowed toolchains. + TOOLCHAIN = 'Toolchain filter' class TestLevel: @@ -779,7 +781,7 @@ def apply_filters(self, **kwargs): instance.add_filter("In test case platform exclude", Filters.TESTSUITE) if ts.toolchain_exclude and toolchain in ts.toolchain_exclude: - instance.add_filter("In test case toolchain exclude", Filters.TESTSUITE) + instance.add_filter("In test case toolchain exclude", Filters.TOOLCHAIN) if platform_filter and plat.name not in platform_filter: instance.add_filter("Command line platform filter", Filters.CMD_LINE) @@ -793,7 +795,7 @@ def apply_filters(self, **kwargs): instance.add_filter("Not in testsuite platform type list", Filters.TESTSUITE) if ts.toolchain_allow and toolchain not in ts.toolchain_allow: - instance.add_filter("Not in testsuite toolchain allow list", Filters.TESTSUITE) + instance.add_filter("Not in testsuite toolchain allow list", Filters.TOOLCHAIN) if not plat.env_satisfied: instance.add_filter("Environment ({}) not satisfied".format(", ".join(plat.env)), Filters.PLATFORM) @@ -1025,7 +1027,8 @@ def change_skip_to_error_if_integration(options, instance): and "quarantine" not in instance.reason.lower(): # Do not treat this as error if filter type is command line filters = {t['type'] for t in instance.filters} - ignore_filters ={Filters.CMD_LINE, Filters.SKIP, Filters.PLATFORM_KEY} + ignore_filters ={Filters.CMD_LINE, Filters.SKIP, Filters.PLATFORM_KEY, + Filters.TOOLCHAIN} if filters.intersection(ignore_filters): return instance.status = "error" From 49df14c08a69839d8a7bfcae742547ba818ce640 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 20 Sep 2023 11:33:37 +0200 Subject: [PATCH 0725/4498] dts: arm: nordic: fix cryptocell description The ARM Cryptocell 310/312 IP is wrapped by Nordic specific registers. It is organized as follows: - Base address: Nordic wrapper - Base address + 0x1000: ARM Cryptocell IP registers Following more standard devicetree conventions, use a single node for what is exposed as a single peripheral. The node contains 2 register entries, one for the wrapper and a second one for the 3rd party IP. Compatibles are used from more specific (nordic,cryptocell) to more generic (arm,cryptocell-3xx). Other minor fixes: peripheral is disabled by default (as it should be in SoC dts files). Signed-off-by: Gerard Marull-Paretas --- dts/arm/nordic/nrf52840.dtsi | 15 +++++---------- dts/arm/nordic/nrf5340_cpuapp.dtsi | 15 +++++---------- dts/arm/nordic/nrf91.dtsi | 15 +++++---------- dts/bindings/crypto/nordic,nrf-cc310.yaml | 12 ------------ dts/bindings/crypto/nordic,nrf-cc312.yaml | 12 ------------ soc/arm/nordic_nrf/Kconfig.peripherals | 4 ++-- 6 files changed, 17 insertions(+), 56 deletions(-) delete mode 100644 dts/bindings/crypto/nordic,nrf-cc310.yaml delete mode 100644 dts/bindings/crypto/nordic,nrf-cc312.yaml diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 8c89968c108..f35778a9d48 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -537,16 +537,11 @@ }; cryptocell: crypto@5002a000 { - compatible = "nordic,nrf-cc310"; - reg = <0x5002A000 0x1000>; - status = "okay"; - #address-cells = <1>; - #size-cells = <1>; - cryptocell310: crypto@5002b000 { - compatible = "arm,cryptocell-310"; - reg = <0x5002B000 0x1000>; - interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; - }; + compatible = "nordic,cryptocell", "arm,cryptocell-310"; + reg = <0x5002a000 0x1000>, <0x5002b000 0x1000>; + reg-names = "wrapper", "core"; + interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; }; }; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 7a32c5398db..77762990e13 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -87,16 +87,11 @@ }; cryptocell: crypto@50844000 { - compatible = "nordic,nrf-cc312"; - reg = <0x50844000 0x1000>; - status = "okay"; - #address-cells = <1>; - #size-cells = <1>; - cryptocell312: crypto@50845000 { - compatible = "arm,cryptocell-312"; - reg = <0x50845000 0x1000>; - interrupts = <68 NRF_DEFAULT_IRQ_PRIORITY>; - }; + compatible = "nordic,cryptocell", "arm,cryptocell-312"; + reg = <0x50844000 0x1000>, <0x50845000 0x1000>; + reg-names = "wrapper", "core"; + interrupts = <68 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; }; }; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index d872680fb20..46024011166 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -47,16 +47,11 @@ /* Additional Secure peripherals */ cryptocell: crypto@50840000 { - compatible = "nordic,nrf-cc310"; - reg = <0x50840000 0x1000>; - status = "okay"; - #address-cells = <1>; - #size-cells = <1>; - cryptocell310: crypto@50841000 { - compatible = "arm,cryptocell-310"; - reg = <0x50841000 0x1000>; - interrupts = <64 NRF_DEFAULT_IRQ_PRIORITY>; - }; + compatible = "nordic,cryptocell", "arm,cryptocell-310"; + reg = <0x50840000 0x1000>, <0x50841000 0x1000>; + reg-names = "wrapper", "core"; + interrupts = <64 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; }; ctrlap: ctrlap@50006000 { diff --git a/dts/bindings/crypto/nordic,nrf-cc310.yaml b/dts/bindings/crypto/nordic,nrf-cc310.yaml deleted file mode 100644 index 8ab48636848..00000000000 --- a/dts/bindings/crypto/nordic,nrf-cc310.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2018, Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Nordic Control Interface for ARM TrustZone CryptoCell 310 - -compatible: "nordic,nrf-cc310" - -include: base.yaml - -properties: - reg: - required: true diff --git a/dts/bindings/crypto/nordic,nrf-cc312.yaml b/dts/bindings/crypto/nordic,nrf-cc312.yaml deleted file mode 100644 index bc0b227e7e5..00000000000 --- a/dts/bindings/crypto/nordic,nrf-cc312.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2018, 2020 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Nordic Control Interface for ARM TrustZone CryptoCell 312 - -compatible: "nordic,nrf-cc312" - -include: base.yaml - -properties: - reg: - required: true diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index c7bfb552409..9a4152a6d84 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -13,10 +13,10 @@ config HAS_HW_NRF_BPROT def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_BPROT)) config HAS_HW_NRF_CC310 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC310)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_310)) config HAS_HW_NRF_CC312 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC312)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_312)) config HAS_HW_NRF_CCM def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CCM)) From 759e07bebe208f4cc1036a7525a80551e16a465c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 20 Sep 2023 01:32:18 +0000 Subject: [PATCH 0726/4498] intel_adsp: move memory window setup to PRE_KERNEL_1 PRE_KERNEL_1 is more suited for dealing with devices, so move out of EARLY. Verified on hardware and things seem to behave the same. Something was changed since this was first introduced as this was not possible for some reason. Fixes #62627 Signed-off-by: Anas Nashif --- drivers/console/winstream_console.c | 2 +- soc/xtensa/intel_adsp/common/mem_window.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/console/winstream_console.c b/drivers/console/winstream_console.c index 8d574bbe3a2..abc5344593a 100644 --- a/drivers/console/winstream_console.c +++ b/drivers/console/winstream_console.c @@ -62,4 +62,4 @@ static int winstream_console_init(void) return 0; } -SYS_INIT(winstream_console_init, EARLY, CONFIG_CONSOLE_INIT_PRIORITY); +SYS_INIT(winstream_console_init, PRE_KERNEL_1, CONFIG_CONSOLE_INIT_PRIORITY); diff --git a/soc/xtensa/intel_adsp/common/mem_window.c b/soc/xtensa/intel_adsp/common/mem_window.c index e101d03ec16..8ca591deb36 100644 --- a/soc/xtensa/intel_adsp/common/mem_window.c +++ b/soc/xtensa/intel_adsp/common/mem_window.c @@ -54,8 +54,9 @@ void mem_window_idle_exit(void) .mem_base = DT_REG_ADDR(DT_PHANDLE(MEM_WINDOW_NODE(n), memory)) + WIN_OFFSET(n), \ .initialize = DT_PROP(MEM_WINDOW_NODE(n), initialize), \ }; \ - DEVICE_DT_DEFINE(MEM_WINDOW_NODE(n), mem_win_init, NULL, NULL, &mem_win_config_##n, EARLY, \ - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + DEVICE_DT_DEFINE(MEM_WINDOW_NODE(n), mem_win_init, NULL, NULL, \ + &mem_win_config_##n, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); #if DT_NODE_HAS_STATUS(MEM_WINDOW_NODE(0), okay) MEM_WINDOW_DEFINE(0) From 78eda66eb59678ddb7d640e21247bdfd46fc7b23 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 20 Sep 2023 13:26:34 +0000 Subject: [PATCH 0727/4498] samples: synchronization: build this sample on all platforms Try to catch issues related to platforms and HAL changes using this basic sample. We have the same flag for a kernel test, but this is skipped if no kernel changes are present in the PR, so we were missing some coverage of platform related changes. Signed-off-by: Anas Nashif --- samples/synchronization/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/synchronization/sample.yaml b/samples/synchronization/sample.yaml index 173bfe22ea7..aa6b442c3fa 100644 --- a/samples/synchronization/sample.yaml +++ b/samples/synchronization/sample.yaml @@ -5,6 +5,7 @@ sample: tests: sample.kernel.synchronization: tags: synchronization + build_on_all: true harness: console harness_config: type: multi_line From 7a4627bf382c99ac48c138b8b48e95cb995fae16 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 20 Sep 2023 13:56:32 +0000 Subject: [PATCH 0728/4498] manifest: update hal_nxp Update hal_nxp to include a build warning fix for redefinition of MPIDR_AFFLVL_MASK. Signed-off-by: Fabio Baltieri --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index bac275806b5..900b16401c8 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: a87e6a8ba3af330fc43f9ed93ce3748416e1009d + revision: 8cc344e9091fdaf2aea821714ee806b04cfb950e path: modules/hal/nxp groups: - hal From 0e765a9ef8d6976e862ebe4a676a265e1a401d54 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 20 Sep 2023 14:44:58 +0000 Subject: [PATCH 0729/4498] clock_control: mcux_ccm: include zephyr/arch/cpu.h Add an explicit include of zephyr/arch/cpu.h before fsl_clock.h so that the Zephyr cpu definitions are parsed before the hal ones. Signed-off-by: Fabio Baltieri --- drivers/clock_control/clock_control_mcux_ccm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clock_control/clock_control_mcux_ccm.c b/drivers/clock_control/clock_control_mcux_ccm.c index d836bb2c260..93a495b9dae 100644 --- a/drivers/clock_control/clock_control_mcux_ccm.c +++ b/drivers/clock_control/clock_control_mcux_ccm.c @@ -6,6 +6,7 @@ #define DT_DRV_COMPAT nxp_imx_ccm #include +#include #include #include #include From 7fca0aa8a6932bfd599552cd17be7b0d1d16b407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 15 Sep 2023 13:40:02 +0700 Subject: [PATCH 0730/4498] nxp_s32: enable clock control for S32ZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable clock control driver for NXP S32ZE SoCs and add clock sources definitions for devicetree. Signed-off-by: Manuel Argüelles --- dts/arm/nxp/nxp_s32z27x_r52.dtsi | 21 +- .../dt-bindings/clock/nxp_s32z2_clock.h | 297 ++++++++++++++++++ soc/arm/nxp_s32/s32ze/Kconfig.series | 1 + soc/arm/nxp_s32/s32ze/Kconfig.soc | 8 - soc/arm/nxp_s32/s32ze/soc.c | 10 - 5 files changed, 318 insertions(+), 19 deletions(-) create mode 100644 include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 3d083083b91..5f5c69948cb 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -80,6 +80,25 @@ soc { interrupt-parent = <&gic>; + clock: clock-controller@40030000 { + compatible = "nxp,s32-clock"; + reg = <0x40030000 0x10000>, + <0x40200000 0x10000>, + <0x40210000 0x10000>, + <0x40220000 0x10000>, + <0x40260000 0x10000>, + <0x40270000 0x10000>, + <0x40830000 0x10000>, + <0x41030000 0x10000>, + <0x41830000 0x10000>, + <0x42030000 0x10000>, + <0x42830000 0x10000>, + <0x44030000 0x10000>, + <0x440a0000 0x10000>; + #clock-cells = <1>; + status = "okay"; + }; + gic: interrupt-controller@47800000 { compatible = "arm,gic-v3", "arm,gic"; reg = <0x47800000 0x10000>, diff --git a/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h b/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h new file mode 100644 index 00000000000..47eb060c545 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h @@ -0,0 +1,297 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32Z2_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32Z2_CLOCK_H_ + +#define NXP_S32_FIRC_CLK 1U +#define NXP_S32_FXOSC_CLK 2U +#define NXP_S32_SIRC_CLK 3U +#define NXP_S32_COREPLL_CLK 4U +#define NXP_S32_PERIPHPLL_CLK 5U +#define NXP_S32_DDRPLL_CLK 6U +#define NXP_S32_LFAST0_PLL_CLK 7U +#define NXP_S32_LFAST1_PLL_CLK 8U +#define NXP_S32_COREPLL_PHI0_CLK 9U +#define NXP_S32_COREPLL_DFS0_CLK 10U +#define NXP_S32_COREPLL_DFS1_CLK 11U +#define NXP_S32_COREPLL_DFS2_CLK 12U +#define NXP_S32_COREPLL_DFS3_CLK 13U +#define NXP_S32_COREPLL_DFS4_CLK 14U +#define NXP_S32_COREPLL_DFS5_CLK 15U +#define NXP_S32_PERIPHPLL_PHI0_CLK 16U +#define NXP_S32_PERIPHPLL_PHI1_CLK 17U +#define NXP_S32_PERIPHPLL_PHI2_CLK 18U +#define NXP_S32_PERIPHPLL_PHI3_CLK 19U +#define NXP_S32_PERIPHPLL_PHI4_CLK 20U +#define NXP_S32_PERIPHPLL_PHI5_CLK 21U +#define NXP_S32_PERIPHPLL_PHI6_CLK 22U +#define NXP_S32_PERIPHPLL_DFS0_CLK 23U +#define NXP_S32_PERIPHPLL_DFS1_CLK 24U +#define NXP_S32_PERIPHPLL_DFS2_CLK 25U +#define NXP_S32_PERIPHPLL_DFS3_CLK 26U +#define NXP_S32_PERIPHPLL_DFS4_CLK 27U +#define NXP_S32_PERIPHPLL_DFS5_CLK 28U +#define NXP_S32_DDRPLL_PHI0_CLK 29U +#define NXP_S32_LFAST0_PLL_PH0_CLK 30U +#define NXP_S32_LFAST1_PLL_PH0_CLK 31U +#define NXP_S32_ETH_RGMII_REF_CLK 32U +#define NXP_S32_ETH_EXT_TS_CLK 33U +#define NXP_S32_ETH0_EXT_RX_CLK 34U +#define NXP_S32_ETH0_EXT_TX_CLK 35U +#define NXP_S32_ETH1_EXT_RX_CLK 36U +#define NXP_S32_ETH1_EXT_TX_CLK 37U +#define NXP_S32_LFAST0_EXT_REF_CLK 38U +#define NXP_S32_LFAST1_EXT_REF_CLK 39U +#define NXP_S32_DDR_CLK 40U +#define NXP_S32_P0_SYS_CLK 41U +#define NXP_S32_P1_SYS_CLK 42U +#define NXP_S32_P1_SYS_DIV2_CLK 43U +#define NXP_S32_P1_SYS_DIV4_CLK 44U +#define NXP_S32_P2_SYS_CLK 45U +#define NXP_S32_CORE_M33_CLK 46U +#define NXP_S32_P2_SYS_DIV2_CLK 47U +#define NXP_S32_P2_SYS_DIV4_CLK 48U +#define NXP_S32_P3_SYS_CLK 49U +#define NXP_S32_CE_SYS_DIV2_CLK 50U +#define NXP_S32_CE_SYS_DIV4_CLK 51U +#define NXP_S32_P3_SYS_DIV2_NOC_CLK 52U +#define NXP_S32_P3_SYS_DIV4_CLK 53U +#define NXP_S32_P4_SYS_CLK 54U +#define NXP_S32_P4_SYS_DIV2_CLK 55U +#define NXP_S32_HSE_SYS_DIV2_CLK 56U +#define NXP_S32_P5_SYS_CLK 57U +#define NXP_S32_P5_SYS_DIV2_CLK 58U +#define NXP_S32_P5_SYS_DIV4_CLK 59U +#define NXP_S32_P2_MATH_CLK 60U +#define NXP_S32_P2_MATH_DIV3_CLK 61U +#define NXP_S32_GLB_LBIST_CLK 62U +#define NXP_S32_RTU0_CORE_CLK 63U +#define NXP_S32_RTU0_CORE_DIV2_CLK 64U +#define NXP_S32_RTU1_CORE_CLK 65U +#define NXP_S32_RTU1_CORE_DIV2_CLK 66U +#define NXP_S32_P0_PSI5_S_UTIL_CLK 67U +#define NXP_S32_P4_PSI5_S_UTIL_CLK 68U +#define NXP_S32_ADC0_CLK 70U +#define NXP_S32_ADC1_CLK 71U +#define NXP_S32_CE_EDMA_CLK 72U +#define NXP_S32_CE_PIT0_CLK 73U +#define NXP_S32_CE_PIT1_CLK 74U +#define NXP_S32_CE_PIT2_CLK 75U +#define NXP_S32_CE_PIT3_CLK 76U +#define NXP_S32_CE_PIT4_CLK 77U +#define NXP_S32_CE_PIT5_CLK 78U +#define NXP_S32_CLKOUT0_CLK 79U +#define NXP_S32_CLKOUT1_CLK 80U +#define NXP_S32_CLKOUT2_CLK 81U +#define NXP_S32_CLKOUT3_CLK 82U +#define NXP_S32_CLKOUT4_CLK 83U +#define NXP_S32_CTU_CLK 84U +#define NXP_S32_DMACRC0_CLK 85U +#define NXP_S32_DMACRC1_CLK 86U +#define NXP_S32_DMACRC4_CLK 87U +#define NXP_S32_DMACRC5_CLK 88U +#define NXP_S32_DMAMUX0_CLK 89U +#define NXP_S32_DMAMUX1_CLK 90U +#define NXP_S32_DMAMUX4_CLK 91U +#define NXP_S32_DMAMUX5_CLK 92U +#define NXP_S32_EDMA0_CLK 93U +#define NXP_S32_EDMA1_CLK 94U +#define NXP_S32_EDMA3_CLK 95U +#define NXP_S32_EDMA4_CLK 96U +#define NXP_S32_EDMA5_CLK 97U +#define NXP_S32_ETH0_TX_MII_CLK 98U +#define NXP_S32_ENET0_CLK 99U +#define NXP_S32_P3_CAN_PE_CLK 100U +#define NXP_S32_FLEXCAN0_CLK 101U +#define NXP_S32_FLEXCAN1_CLK 102U +#define NXP_S32_FLEXCAN2_CLK 103U +#define NXP_S32_FLEXCAN3_CLK 104U +#define NXP_S32_FLEXCAN4_CLK 105U +#define NXP_S32_FLEXCAN5_CLK 106U +#define NXP_S32_FLEXCAN6_CLK 107U +#define NXP_S32_FLEXCAN7_CLK 108U +#define NXP_S32_FLEXCAN8_CLK 109U +#define NXP_S32_FLEXCAN9_CLK 110U +#define NXP_S32_FLEXCAN10_CLK 111U +#define NXP_S32_FLEXCAN11_CLK 112U +#define NXP_S32_FLEXCAN12_CLK 113U +#define NXP_S32_FLEXCAN13_CLK 114U +#define NXP_S32_FLEXCAN14_CLK 115U +#define NXP_S32_FLEXCAN15_CLK 116U +#define NXP_S32_FLEXCAN16_CLK 117U +#define NXP_S32_FLEXCAN17_CLK 118U +#define NXP_S32_FLEXCAN18_CLK 119U +#define NXP_S32_FLEXCAN19_CLK 120U +#define NXP_S32_FLEXCAN20_CLK 121U +#define NXP_S32_FLEXCAN21_CLK 122U +#define NXP_S32_FLEXCAN22_CLK 123U +#define NXP_S32_FLEXCAN23_CLK 124U +#define NXP_S32_P0_FR_PE_CLK 125U +#define NXP_S32_FRAY0_CLK 126U +#define NXP_S32_FRAY1_CLK 127U +#define NXP_S32_GTM_CLK 128U +#define NXP_S32_IIIC0_CLK 129U +#define NXP_S32_IIIC1_CLK 130U +#define NXP_S32_IIIC2_CLK 131U +#define NXP_S32_P0_LIN_BAUD_CLK 132U +#define NXP_S32_LIN0_CLK 133U +#define NXP_S32_LIN1_CLK 134U +#define NXP_S32_LIN2_CLK 135U +#define NXP_S32_P1_LIN_BAUD_CLK 136U +#define NXP_S32_LIN3_CLK 137U +#define NXP_S32_LIN4_CLK 138U +#define NXP_S32_LIN5_CLK 139U +#define NXP_S32_P4_LIN_BAUD_CLK 140U +#define NXP_S32_LIN6_CLK 141U +#define NXP_S32_LIN7_CLK 142U +#define NXP_S32_LIN8_CLK 143U +#define NXP_S32_P5_LIN_BAUD_CLK 144U +#define NXP_S32_LIN9_CLK 145U +#define NXP_S32_LIN10_CLK 146U +#define NXP_S32_LIN11_CLK 147U +#define NXP_S32_MSCDSPI_CLK 148U +#define NXP_S32_MSCLIN_CLK 149U +#define NXP_S32_NANO_CLK 150U +#define NXP_S32_P0_CLKOUT_SRC_CLK 151U +#define NXP_S32_P0_CTU_PER_CLK 152U +#define NXP_S32_P0_DSPI_MSC_CLK 153U +#define NXP_S32_P0_EMIOS_LCU_CLK 154U +#define NXP_S32_P0_GTM_CLK 155U +#define NXP_S32_P0_GTM_NOC_CLK 156U +#define NXP_S32_P0_GTM_TS_CLK 157U +#define NXP_S32_P0_LIN_CLK 158U +#define NXP_S32_P0_NANO_CLK 159U +#define NXP_S32_P0_PSI5_125K_CLK 160U +#define NXP_S32_P0_PSI5_189K_CLK 161U +#define NXP_S32_P0_PSI5_S_BAUD_CLK 162U +#define NXP_S32_P0_PSI5_S_CORE_CLK 163U +#define NXP_S32_P0_PSI5_S_TRIG0_CLK 164U +#define NXP_S32_P0_PSI5_S_TRIG1_CLK 165U +#define NXP_S32_P0_PSI5_S_TRIG2_CLK 166U +#define NXP_S32_P0_PSI5_S_TRIG3_CLK 167U +#define NXP_S32_P0_PSI5_S_UART_CLK 168U +#define NXP_S32_P0_PSI5_S_WDOG0_CLK 169U +#define NXP_S32_P0_PSI5_S_WDOG1_CLK 170U +#define NXP_S32_P0_PSI5_S_WDOG2_CLK 171U +#define NXP_S32_P0_PSI5_S_WDOG3_CLK 172U +#define NXP_S32_P0_REG_INTF_2X_CLK 173U +#define NXP_S32_P0_REG_INTF_CLK 174U +#define NXP_S32_P1_CLKOUT_SRC_CLK 175U +#define NXP_S32_P1_DSPI60_CLK 176U +#define NXP_S32_ETH_TS_CLK 177U +#define NXP_S32_ETH_TS_DIV4_CLK 178U +#define NXP_S32_ETH0_REF_RMII_CLK 179U +#define NXP_S32_ETH0_RX_MII_CLK 180U +#define NXP_S32_ETH0_RX_RGMII_CLK 181U +#define NXP_S32_ETH0_TX_RGMII_CLK 182U +#define NXP_S32_ETH0_TX_RGMII_LPBK_CLK 183U +#define NXP_S32_ETH1_REF_RMII_CLK 184U +#define NXP_S32_ETH1_RX_MII_CLK 185U +#define NXP_S32_ETH1_RX_RGMII_CLK 186U +#define NXP_S32_ETH1_TX_MII_CLK 187U +#define NXP_S32_ETH1_TX_RGMII_CLK 188U +#define NXP_S32_ETH1_TX_RGMII_LPBK_CLK 189U +#define NXP_S32_P1_LFAST0_REF_CLK 190U +#define NXP_S32_P1_LFAST1_REF_CLK 191U +#define NXP_S32_P1_LFAST_DFT_CLK 192U +#define NXP_S32_P1_NETC_AXI_CLK 193U +#define NXP_S32_P1_LIN_CLK 194U +#define NXP_S32_P1_REG_INTF_CLK 195U +#define NXP_S32_P2_DBG_ATB_CLK 196U +#define NXP_S32_P2_REG_INTF_CLK 197U +#define NXP_S32_P3_AES_CLK 198U +#define NXP_S32_P3_CLKOUT_SRC_CLK 199U +#define NXP_S32_P3_DBG_TS_CLK 200U +#define NXP_S32_P3_REG_INTF_CLK 201U +#define NXP_S32_P3_SYS_MON1_CLK 202U +#define NXP_S32_P3_SYS_MON2_CLK 203U +#define NXP_S32_P3_SYS_MON3_CLK 204U +#define NXP_S32_P4_CLKOUT_SRC_CLK 205U +#define NXP_S32_P4_DSPI60_CLK 206U +#define NXP_S32_P4_EMIOS_LCU_CLK 207U +#define NXP_S32_P4_LIN_CLK 208U +#define NXP_S32_P4_PSI5_125K_CLK 209U +#define NXP_S32_P4_PSI5_189K_CLK 210U +#define NXP_S32_P4_PSI5_S_BAUD_CLK 211U +#define NXP_S32_P4_PSI5_S_CORE_CLK 212U +#define NXP_S32_P4_PSI5_S_TRIG0_CLK 213U +#define NXP_S32_P4_PSI5_S_TRIG1_CLK 214U +#define NXP_S32_P4_PSI5_S_TRIG2_CLK 215U +#define NXP_S32_P4_PSI5_S_TRIG3_CLK 216U +#define NXP_S32_P4_PSI5_S_UART_CLK 217U +#define NXP_S32_P4_PSI5_S_WDOG0_CLK 218U +#define NXP_S32_P4_PSI5_S_WDOG1_CLK 219U +#define NXP_S32_P4_PSI5_S_WDOG2_CLK 220U +#define NXP_S32_P4_PSI5_S_WDOG3_CLK 221U +#define NXP_S32_P4_QSPI0_2X_CLK 222U +#define NXP_S32_P4_QSPI0_1X_CLK 223U +#define NXP_S32_P4_QSPI1_2X_CLK 224U +#define NXP_S32_P4_QSPI1_1X_CLK 225U +#define NXP_S32_P4_REG_INTF_2X_CLK 226U +#define NXP_S32_P4_REG_INTF_CLK 227U +#define NXP_S32_P4_SDHC_IP_CLK 228U +#define NXP_S32_P4_SDHC_IP_DIV2_CLK 229U +#define NXP_S32_P5_DIPORT_CLK 230U +#define NXP_S32_P5_AE_CLK 231U +#define NXP_S32_P5_CANXL_PE_CLK 232U +#define NXP_S32_P5_CANXL_CHI_CLK 233U +#define NXP_S32_P5_CLKOUT_SRC_CLK 234U +#define NXP_S32_P5_LIN_CLK 235U +#define NXP_S32_P5_REG_INTF_CLK 236U +#define NXP_S32_P6_REG_INTF_CLK 237U +#define NXP_S32_PIT0_CLK 238U +#define NXP_S32_PIT1_CLK 239U +#define NXP_S32_PIT4_CLK 240U +#define NXP_S32_PIT5_CLK 241U +#define NXP_S32_P0_PSI5_1US_CLK 242U +#define NXP_S32_PSI5_0_CLK 243U +#define NXP_S32_P4_PSI5_1US_CLK 244U +#define NXP_S32_PSI5_1_CLK 245U +#define NXP_S32_PSI5S_0_CLK 246U +#define NXP_S32_PSI5S_1_CLK 247U +#define NXP_S32_QSPI0_CLK 248U +#define NXP_S32_QSPI1_CLK 249U +#define NXP_S32_RTU0_CORE_MON1_CLK 250U +#define NXP_S32_RTU0_CORE_MON2_CLK 251U +#define NXP_S32_RTU0_CORE_DIV2_MON1_CLK 252U +#define NXP_S32_RTU0_CORE_DIV2_MON2_CLK 253U +#define NXP_S32_RTU0_CORE_DIV2_MON3_CLK 254U +#define NXP_S32_RTU0_REG_INTF_CLK 255U +#define NXP_S32_RTU1_CORE_MON1_CLK 256U +#define NXP_S32_RTU1_CORE_MON2_CLK 257U +#define NXP_S32_RTU1_CORE_DIV2_MON1_CLK 258U +#define NXP_S32_RTU1_CORE_DIV2_MON2_CLK 259U +#define NXP_S32_RTU1_CORE_DIV2_MON3_CLK 260U +#define NXP_S32_RTU1_REG_INTF_CLK 261U +#define NXP_S32_P4_SDHC_CLK 262U +#define NXP_S32_RXLUT_CLK 263U +#define NXP_S32_SDHC0_CLK 264U +#define NXP_S32_SINC_CLK 265U +#define NXP_S32_SIPI0_CLK 266U +#define NXP_S32_SIPI1_CLK 267U +#define NXP_S32_SIUL2_0_CLK 268U +#define NXP_S32_SIUL2_1_CLK 269U +#define NXP_S32_SIUL2_4_CLK 270U +#define NXP_S32_SIUL2_5_CLK 271U +#define NXP_S32_P0_DSPI_CLK 272U +#define NXP_S32_SPI0_CLK 273U +#define NXP_S32_SPI1_CLK 274U +#define NXP_S32_P1_DSPI_CLK 275U +#define NXP_S32_SPI2_CLK 276U +#define NXP_S32_SPI3_CLK 277U +#define NXP_S32_SPI4_CLK 278U +#define NXP_S32_P4_DSPI_CLK 279U +#define NXP_S32_SPI5_CLK 280U +#define NXP_S32_SPI6_CLK 281U +#define NXP_S32_SPI7_CLK 282U +#define NXP_S32_P5_DSPI_CLK 283U +#define NXP_S32_SPI8_CLK 284U +#define NXP_S32_SPI9_CLK 285U +#define NXP_S32_SRX0_CLK 286U +#define NXP_S32_SRX1_CLK 287U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32Z2_CLOCK_H_ */ diff --git a/soc/arm/nxp_s32/s32ze/Kconfig.series b/soc/arm/nxp_s32/s32ze/Kconfig.series index 5414de3546f..ebeca180a1e 100644 --- a/soc/arm/nxp_s32/s32ze/Kconfig.series +++ b/soc/arm/nxp_s32/s32ze/Kconfig.series @@ -14,5 +14,6 @@ config SOC_SERIES_S32ZE_R52 select VFP_DP_D16 select PLATFORM_SPECIFIC_INIT select SOC_FAMILY_NXP_S32 + select CLOCK_CONTROL help Enable support for NXP S32Z/E MCUs family on Cortex-R52 cores. diff --git a/soc/arm/nxp_s32/s32ze/Kconfig.soc b/soc/arm/nxp_s32/s32ze/Kconfig.soc index c8a1322f531..757b4096634 100644 --- a/soc/arm/nxp_s32/s32ze/Kconfig.soc +++ b/soc/arm/nxp_s32/s32ze/Kconfig.soc @@ -26,14 +26,6 @@ config SOC_PART_NUMBER_S32ZE_R52 that you should not set directly. The part number selection choice defines the default value for this string. -config INIT_CLOCK_AT_BOOT_TIME - bool "Initialize clocks at boot time" - default y - help - Initialize clocks at boot time with the configuration generated through the - driver's configurator, instead of using the default SoC clock configuration - at reset. - config NXP_S32_RTU_INDEX int range 0 1 diff --git a/soc/arm/nxp_s32/s32ze/soc.c b/soc/arm/nxp_s32/s32ze/soc.c index 4a1837f9dca..36acfbf9dc8 100644 --- a/soc/arm/nxp_s32/s32ze/soc.c +++ b/soc/arm/nxp_s32/s32ze/soc.c @@ -12,11 +12,6 @@ #include -#ifdef CONFIG_INIT_CLOCK_AT_BOOT_TIME -#include -#include -#endif - void z_arm_platform_init(void) { /* enable peripheral port access at EL1 and EL0 */ @@ -47,11 +42,6 @@ static int soc_init(void) { OsIf_Init(NULL); -#ifdef CONFIG_INIT_CLOCK_AT_BOOT_TIME - /* Initialize clocks with tool generated code */ - Clock_Ip_Init(Clock_Ip_aClockConfig); -#endif - return 0; } From d327b1625c6bd2b3d16dfe1e025abb539f880b28 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 17 Aug 2023 13:15:12 +0200 Subject: [PATCH 0731/4498] Bluetooth: BAP: Broadcast source reconfig with subgroups Modify the bt_bap_broadcast_source_reconfig to use the same parameter struct as bt_bap_broadcast_source_create so that the two are more similar, since they both set the same values. This allow for full control of which subgroups and stream are updated. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/bap.h | 18 ++- .../broadcast_audio_source/src/main.c | 2 +- subsys/bluetooth/audio/bap_broadcast_source.c | 132 ++++++++++++++---- subsys/bluetooth/audio/cap_initiator.c | 4 +- subsys/bluetooth/audio/shell/bap.c | 2 +- subsys/bluetooth/audio/shell/cap_initiator.c | 2 +- 6 files changed, 125 insertions(+), 35 deletions(-) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 3068a86ed24..52a9c0d477d 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1400,7 +1400,7 @@ struct bt_bap_broadcast_source_subgroup_param { }; /** Broadcast Source create parameters */ -struct bt_bap_broadcast_source_create_param { +struct bt_bap_broadcast_source_param { /** The number of parameters in @p subgroup_params */ size_t params_count; @@ -1451,7 +1451,7 @@ struct bt_bap_broadcast_source_create_param { * * @return Zero on success or (negative) error code otherwise. */ -int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param *param, +int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param, struct bt_bap_broadcast_source **source); /** @@ -1460,15 +1460,21 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * * Reconfigure an audio broadcast source with a new codec and codec quality of * service parameters. This can only be done when the source is stopped. * + * Since this may modify the Broadcast Audio Source Endpoint (BASE), + * bt_bap_broadcast_source_get_base() should be called after this to get the new BASE information. + * + * If the @p param.params_count is smaller than the number of subgroups that have been created in + * the Broadcast Source, only the first @p param.params_count subgroups are updated. If a stream + * exist in a subgroup not part of @p param, then that stream is left as is (i.e. it is not removed; + * the only way to remove a stream from a Broadcast Source is to recreate the Broadcast Source). + * * @param source Pointer to the broadcast source - * @param codec_cfg Codec configuration. - * @param qos Quality of Service configuration + * @param param Pointer to parameters used to reconfigure the broadcast source. * * @return Zero on success or (negative) error code otherwise. */ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, - struct bt_audio_codec_cfg *codec_cfg, - struct bt_audio_codec_qos *qos); + struct bt_bap_broadcast_source_param *param); /** * @brief Modify the metadata of an audio broadcast source. diff --git a/samples/bluetooth/broadcast_audio_source/src/main.c b/samples/bluetooth/broadcast_audio_source/src/main.c index 111bba09bc6..f1ab4034987 100644 --- a/samples/bluetooth/broadcast_audio_source/src/main.c +++ b/samples/bluetooth/broadcast_audio_source/src/main.c @@ -93,7 +93,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; struct bt_bap_broadcast_source_subgroup_param subgroup_param[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; const size_t streams_per_subgroup = ARRAY_SIZE(stream_params) / ARRAY_SIZE(subgroup_param); int err; diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 8354fcae18b..a6aaf43a60b 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -476,7 +476,8 @@ static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source) (void)memset(source, 0, sizeof(*source)); } -static bool valid_create_param(const struct bt_bap_broadcast_source_create_param *param) +static bool valid_broadcast_source_param(const struct bt_bap_broadcast_source_param *param, + const struct bt_bap_broadcast_source *source) { const struct bt_audio_codec_qos *qos; @@ -555,7 +556,8 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param return false; } - CHECKIF(stream_param->stream->group != NULL) { + CHECKIF(stream_param->stream->group != NULL && + stream_param->stream->group != source) { LOG_DBG("subgroup_params[%zu].stream_params[%zu]->stream is " "already part of group %p", i, j, stream_param->stream->group); @@ -618,7 +620,7 @@ static enum bt_bap_ep_state broadcast_source_get_state(struct bt_bap_broadcast_s return stream->ep->status.state; } -int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param *param, +int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param, struct bt_bap_broadcast_source **out_source) { struct bt_bap_broadcast_source *source; @@ -635,7 +637,7 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * /* Set out_source to NULL until the source has actually been created */ *out_source = NULL; - if (!valid_create_param(param)) { + if (!valid_broadcast_source_param(param, NULL)) { LOG_DBG("Invalid parameters"); return -EINVAL; } @@ -738,35 +740,20 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * } int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, - struct bt_audio_codec_cfg *codec_cfg, - struct bt_audio_codec_qos *qos) + struct bt_bap_broadcast_source_param *param) { struct bt_bap_broadcast_subgroup *subgroup; enum bt_bap_ep_state broadcast_state; - struct bt_bap_stream *stream; + struct bt_audio_codec_qos *qos; + size_t subgroup_cnt; CHECKIF(source == NULL) { LOG_DBG("source is NULL"); return -EINVAL; } - CHECKIF(!bt_audio_valid_codec_cfg(codec_cfg)) { - LOG_DBG("codec_cfg is invalid"); - return -EINVAL; - } - - CHECKIF(qos == NULL) { - LOG_DBG("qos is NULL"); - return -EINVAL; - } - - CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) { - LOG_DBG("qos is invalid"); - return -EINVAL; - } - - CHECKIF(qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { - LOG_DBG("qos->rtn %u invalid", qos->rtn); + if (!valid_broadcast_source_param(param, source)) { + LOG_DBG("Invalid parameters"); return -EINVAL; } @@ -776,9 +763,97 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, return -EBADMSG; } + /* Verify that the parameter counts do not exceed existing number of subgroups and streams*/ + subgroup_cnt = 0U; SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) { + const struct bt_bap_broadcast_source_subgroup_param *subgroup_param = + ¶m->params[subgroup_cnt]; + const size_t subgroup_stream_param_cnt = subgroup_param->params_count; + struct bt_bap_stream *stream; + size_t stream_cnt = 0U; + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) { + stream_cnt++; + } + + /* Verify that the param stream is in the subgroup */ + for (size_t i = 0U; i < subgroup_param->params_count; i++) { + struct bt_bap_stream *subgroup_stream; + struct bt_bap_stream *param_stream; + bool stream_in_subgroup; + + param_stream = subgroup_param->params[i].stream; + + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, subgroup_stream, _node) { + if (subgroup_stream == param_stream) { + stream_in_subgroup = true; + break; + } + } + + if (!stream_in_subgroup) { + LOG_DBG("Invalid param->params[%zu]->param[%zu].stream " + "not in subgroup", + subgroup_cnt, i); + return -EINVAL; + } + } + + if (subgroup_stream_param_cnt < stream_cnt) { + LOG_DBG("Invalid param->params[%zu]->params_count: %zu " + "(only %zu streams in subgroup)", + subgroup_cnt, subgroup_stream_param_cnt, stream_cnt); + return -EINVAL; + } + + subgroup_cnt++; + } + + if (subgroup_cnt < param->params_count) { + LOG_DBG("Invalid param->params_count: %zu (only %zu subgroups in source)", + param->params_count, subgroup_cnt); + return -EINVAL; + } + + qos = param->qos; + + /* We update up to the first param->params_count subgroups */ + for (size_t i = 0U; i < param->params_count; i++) { + const struct bt_bap_broadcast_source_subgroup_param *subgroup_param; + struct bt_audio_codec_cfg *codec_cfg; + + if (i == 0) { + subgroup = + SYS_SLIST_PEEK_HEAD_CONTAINER(&source->subgroups, subgroup, _node); + } else { + subgroup = SYS_SLIST_PEEK_NEXT_CONTAINER(subgroup, _node); + } + + subgroup_param = ¶m->params[i]; + codec_cfg = subgroup_param->codec_cfg; + subgroup->codec_cfg = codec_cfg; + + for (size_t j = 0U; j < subgroup_param->params_count; j++) { + const struct bt_bap_broadcast_source_stream_param *stream_param; + struct bt_audio_broadcast_stream_data *stream_data; + struct bt_bap_stream *subgroup_stream; struct bt_iso_chan_io_qos *iso_qos; + struct bt_bap_stream *stream; + bool stream_in_subgroup; + size_t stream_idx; + + stream_param = &subgroup_param->params[j]; + stream = stream_param->stream; + + stream_idx = 0U; + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, subgroup_stream, _node) { + if (subgroup_stream == stream) { + stream_in_subgroup = true; + break; + } + + stream_idx++; + } iso_qos = stream->ep->iso->chan.qos->tx; @@ -787,6 +862,15 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, bt_audio_codec_qos_to_iso_qos(iso_qos, qos); bt_audio_codec_cfg_to_iso_path(iso_qos->path, codec_cfg); stream->qos = qos; + + /* Store the BIS specific codec configuration data in the broadcast source. + * It is stored in the broadcast* source, instead of the stream object, + * as this is only relevant for the broadcast source, and not used + * for unicast or broadcast sink. + */ + stream_data = &source->stream_data[stream_idx]; + (void)memcpy(stream_data->data, stream_param->data, stream_param->data_len); + stream_data->data_len = stream_param->data_len; } } diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index b8ceb017057..4c7e5c767bb 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -114,7 +114,7 @@ static bool cap_initiator_broadcast_audio_start_valid_param( static void cap_initiator_broadcast_to_bap_broadcast_param( const struct bt_cap_initiator_broadcast_create_param *cap_param, - struct bt_bap_broadcast_source_create_param *bap_param, + struct bt_bap_broadcast_source_param *bap_param, struct bt_bap_broadcast_source_subgroup_param bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT], struct bt_bap_broadcast_source_stream_param @@ -170,7 +170,7 @@ int bt_cap_initiator_broadcast_audio_create( bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; struct bt_bap_broadcast_source_stream_param bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; - struct bt_bap_broadcast_source_create_param bap_create_param; + struct bt_bap_broadcast_source_param bap_create_param; CHECKIF(param == NULL) { LOG_DBG("param is NULL"); diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 3e34fe12ec4..3d6408276a7 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -2052,7 +2052,7 @@ static int cmd_create_broadcast(const struct shell *sh, size_t argc, struct bt_bap_broadcast_source_stream_param stream_params[ARRAY_SIZE(broadcast_source_streams)]; struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_create_param create_param = {0}; + struct bt_bap_broadcast_source_param create_param = {0}; const struct named_lc3_preset *named_preset; int err; diff --git a/subsys/bluetooth/audio/shell/cap_initiator.c b/subsys/bluetooth/audio/shell/cap_initiator.c index 44c91b7d521..a57050a5607 100644 --- a/subsys/bluetooth/audio/shell/cap_initiator.c +++ b/subsys/bluetooth/audio/shell/cap_initiator.c @@ -1043,7 +1043,7 @@ static int cap_ac_broadcast(const struct shell *sh, size_t argc, char **argv, uint8_t left_data[] = {BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, BT_AUDIO_LOCATION_FRONT_LEFT)}; struct bt_bap_broadcast_source_subgroup_param subgroup_param = {0}; - struct bt_bap_broadcast_source_create_param create_param = {0}; + struct bt_bap_broadcast_source_param create_param = {0}; const struct named_lc3_preset *named_preset; struct bt_le_ext_adv *adv; int err; From 6dd90c1ab00e0b979f5418340550259cd0a9b246 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 17 Aug 2023 13:18:48 +0200 Subject: [PATCH 0732/4498] tests: Bluetooth: BAP: Update test for bt_bap_broadcast_source_reconfig Added additional testing for bt_bap_broadcast_source_reconfig after the API changed. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 430 ++++++++++++++---- 1 file changed, 342 insertions(+), 88 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 8f741279b60..1b81d0f714b 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -100,14 +100,14 @@ static struct bt_bap_stream_ops stream_ops = { static uint8_t valid_bis_codec_data[] = {BT_AUDIO_CODEC_DATA( BT_AUDIO_CODEC_CONFIG_LC3_FREQ, BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ))}; -static void broadcast_source_create_inval_reset_param( - struct bt_bap_broadcast_source_create_param *param, - struct bt_bap_broadcast_source_subgroup_param *subgroup_param, - struct bt_bap_broadcast_source_stream_param *stream_param) +static void +broadcast_source_inval_reset_param(struct bt_bap_broadcast_source_param *param, + struct bt_bap_broadcast_source_subgroup_param *subgroup_param, + struct bt_bap_broadcast_source_stream_param *stream_param) { struct bt_bap_broadcast_source_stream_param valid_stream_param; struct bt_bap_broadcast_source_subgroup_param valid_subgroup_param; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; valid_stream_param.stream = &broadcast_source_streams[0]; valid_stream_param.data_len = ARRAY_SIZE(valid_bis_codec_data); @@ -133,12 +133,12 @@ static void broadcast_source_create_inval_reset_param( static void broadcast_source_create_inval_stream_param(void) { struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; struct bt_bap_broadcast_source_stream_param stream_param; struct bt_bap_broadcast_source *broadcast_source; int err; - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Set data NULL while count is 1 */ stream_param.data = NULL; @@ -151,7 +151,7 @@ static void broadcast_source_create_inval_stream_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Initialize codec configuration data that is too large */ stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; @@ -166,7 +166,7 @@ static void broadcast_source_create_inval_stream_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Set stream to NULL */ stream_param.stream = NULL; @@ -179,7 +179,7 @@ static void broadcast_source_create_inval_stream_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { uint8_t bis_codec_data[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1] = {0}; @@ -205,13 +205,13 @@ static void broadcast_source_create_inval_stream_param(void) static void broadcast_source_create_inval_subgroup_codec_param(void) { struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; struct bt_bap_broadcast_source_stream_param stream_param; struct bt_bap_broadcast_source *broadcast_source; struct bt_audio_codec_cfg codec_cfg; int err; - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); @@ -225,7 +225,7 @@ static void broadcast_source_create_inval_subgroup_codec_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); @@ -240,8 +240,7 @@ static void broadcast_source_create_inval_subgroup_codec_param(void) } if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, - &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); @@ -260,8 +259,7 @@ static void broadcast_source_create_inval_subgroup_codec_param(void) } if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE < 255) { - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, - &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); @@ -283,12 +281,12 @@ static void broadcast_source_create_inval_subgroup_codec_param(void) static void broadcast_source_create_inval_subgroup_param(void) { struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; struct bt_bap_broadcast_source_stream_param stream_param; struct bt_bap_broadcast_source *broadcast_source; int err; - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Set count to 0 */ subgroup_param.params_count = 0; @@ -309,7 +307,7 @@ static void broadcast_source_create_inval_subgroup_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Set params to NULL */ subgroup_param.params = NULL; @@ -320,7 +318,7 @@ static void broadcast_source_create_inval_subgroup_param(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); /* Set codec to NULL */ subgroup_param.codec_cfg = NULL; @@ -339,7 +337,7 @@ static void broadcast_source_create_inval(void) { struct bt_bap_broadcast_source_stream_param stream_param; struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; struct bt_bap_broadcast_source *broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT + 1U]; struct bt_audio_codec_qos qos; int err; @@ -367,7 +365,7 @@ static void broadcast_source_create_inval(void) broadcast_source_create_inval_subgroup_param(); /* Invalid create_param values */ - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); create_param.params_count = 0; printk("Test bt_bap_broadcast_source_create with 0 params_count\n"); @@ -377,7 +375,7 @@ static void broadcast_source_create_inval(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); create_param.params = NULL; printk("Test bt_bap_broadcast_source_create with NULL params\n"); @@ -387,7 +385,7 @@ static void broadcast_source_create_inval(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); create_param.packing = 0x35; printk("Test bt_bap_broadcast_source_create with packing 0x%02X\n", create_param.packing); @@ -397,7 +395,7 @@ static void broadcast_source_create_inval(void) return; } - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); create_param.qos = NULL; printk("Test bt_bap_broadcast_source_create with NULL qos\n"); @@ -408,7 +406,7 @@ static void broadcast_source_create_inval(void) } /* Invalid QoS values */ - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); create_param.qos = memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); qos.phy = BT_AUDIO_CODEC_QOS_CODED + 1; @@ -497,7 +495,7 @@ static void broadcast_source_create_inval(void) } /* Exceeding memory limits */ - broadcast_source_create_inval_reset_param(&create_param, &subgroup_param, &stream_param); + broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); printk("Test bt_bap_broadcast_source_create with %zu broadcast sources\n", ARRAY_SIZE(broadcast_sources)); @@ -540,13 +538,15 @@ static void broadcast_source_create_inval(void) static int setup_broadcast_source(struct bt_bap_broadcast_source **source) { - uint8_t bis_codec_data[] = {3, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, - BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ)}; + uint8_t bis_codec_data[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_FREQ, + BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ)), + }; struct bt_bap_broadcast_source_stream_param stream_params[ARRAY_SIZE(broadcast_source_streams)]; struct bt_bap_broadcast_source_subgroup_param subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; int err; (void)memset(broadcast_source_streams, 0, @@ -570,7 +570,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) create_param.params_count = ARRAY_SIZE(subgroup_params); create_param.params = subgroup_params; - create_param.qos = &preset_16_2_2.qos; + create_param.qos = &preset_16_2_1.qos; create_param.packing = BT_ISO_PACKING_SEQUENTIAL; create_param.encryption = false; @@ -739,111 +739,328 @@ static int setup_extended_adv(struct bt_bap_broadcast_source *source, struct bt_ static void test_broadcast_source_reconfig_inval_state(struct bt_bap_broadcast_source *source) { + uint8_t bis_codec_data[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_FREQ, + BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ)), + }; + struct bt_bap_broadcast_source_stream_param + stream_params[ARRAY_SIZE(broadcast_source_streams)]; + struct bt_bap_broadcast_source_subgroup_param + subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; + struct bt_bap_broadcast_source_param reconfig_param; int err; + for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) { + stream_params[i].stream = &broadcast_source_streams[i]; + bt_bap_stream_cb_register(stream_params[i].stream, &stream_ops); + stream_params[i].data_len = sizeof(bis_codec_data); + stream_params[i].data = bis_codec_data; + } + + for (size_t i = 0U; i < ARRAY_SIZE(subgroup_params); i++) { + subgroup_params[i].params_count = 1U; + subgroup_params[i].params = &stream_params[i]; + subgroup_params[i].codec_cfg = &preset_16_2_2.codec_cfg; + } + + reconfig_param.params_count = ARRAY_SIZE(subgroup_params); + reconfig_param.params = subgroup_params; + reconfig_param.qos = &preset_16_2_2.qos; + reconfig_param.packing = BT_ISO_PACKING_SEQUENTIAL; + reconfig_param.encryption = false; + printk("Test bt_bap_broadcast_source_reconfig in stopped state\n"); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, - &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig in stopped state did not fail\n"); return; } } -static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source *source) +static void +test_broadcast_source_reconfig_inval_stream_param(struct bt_bap_broadcast_source *broadcast_source) { - struct bt_audio_codec_qos qos; - struct bt_audio_codec_cfg codec_cfg; + struct bt_bap_broadcast_source_subgroup_param subgroup_param; + struct bt_bap_broadcast_source_param reconfig_param; + struct bt_bap_broadcast_source_stream_param stream_param; int err; - /* Test NULL values */ - printk("Test bt_bap_broadcast_source_reconfig with NULL source\n"); - err = bt_bap_broadcast_source_reconfig(NULL, &preset_16_2_1.codec_cfg, &preset_16_2_1.qos); + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Set data NULL while count is 1 */ + stream_param.data = NULL; + + printk("Test bt_bap_broadcast_source_reconfig with NULL stream_param\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL broadcast source did not fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param data did not " + "fail\n"); return; } - printk("Test bt_bap_broadcast_source_reconfig with NULL codec\n"); - err = bt_bap_broadcast_source_reconfig(source, NULL, &preset_16_2_1.qos); + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Initialize codec configuration data that is too large */ + stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + + printk("Test bt_bap_broadcast_source_reconfig with stream_param.data_len %zu\n", + stream_param.data_len); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL codec did not fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with stream_param data count %u " + "did not fail\n", + stream_param.data_len); return; } - printk("Test bt_bap_broadcast_source_reconfig with NULL QoS\n"); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, NULL); + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Set stream to NULL */ + stream_param.stream = NULL; + + printk("Test bt_bap_broadcast_source_reconfig with NULL stream_param.stream\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL QoS did not fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param stream " + "did not fail\n"); return; } - /* Test invalid codec values */ - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { + uint8_t bis_codec_data[sizeof(sizeof(valid_bis_codec_data))]; + + memcpy(bis_codec_data, valid_bis_codec_data, sizeof(valid_bis_codec_data)); + + /* Set LTV data to invalid size */ + stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + stream_param.data = bis_codec_data; + + printk("Test bt_bap_broadcast_source_reconfig with CC LTV size %zu\n", + sizeof(bis_codec_data)); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with CC LTV size %zu in " + "stream_param did not fail\n", + sizeof(bis_codec_data)); + return; + } + } +} + +static void test_broadcast_source_reconfig_inval_subgroup_codec_param( + struct bt_bap_broadcast_source *broadcast_source) +{ + struct bt_bap_broadcast_source_subgroup_param subgroup_param; + struct bt_bap_broadcast_source_param reconfig_param; + struct bt_bap_broadcast_source_stream_param stream_param; + struct bt_audio_codec_cfg codec_cfg; + int err; + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + subgroup_param.codec_cfg = + memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; printk("Test bt_bap_broadcast_source_reconfig with codec.data_len %zu\n", codec_cfg.data_len); - err = bt_bap_broadcast_source_reconfig(source, &codec_cfg, &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high codec data len did not " - "fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with too high codec data len %zu did not " + "fail\n", codec_cfg.data_len); return; } - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + subgroup_param.codec_cfg = + memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; printk("Test bt_bap_broadcast_source_reconfig with codec.meta_len %zu\n", codec_cfg.meta_len); - err = bt_bap_broadcast_source_reconfig(source, &codec_cfg, &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high codec meta len did not " - "fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with too high codec meta len %u did not " + "fail\n", codec_cfg.meta_len); return; } - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, + sizeof(preset_16_2_1.codec_cfg)); + /* Set LTV data to invalid size */ codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - printk("Test bt_bap_broadcast_source_reconfig with CC LTV size %u\n", + printk("Test bt_bap_broadcast_source_reconfig with CC LTV len %u\n", codec_cfg.data_len); - err = bt_bap_broadcast_source_reconfig(source, &codec_cfg, &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too large CC LTV did not " - "fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with CC LTV len %zu in " + "subgroup_param did not fail\n", + codec_cfg.data_len); return; } - - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); } if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE < 255) { + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, + sizeof(preset_16_2_1.codec_cfg)); + /* Set LTV data to invalid size */ codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; printk("Test bt_bap_broadcast_source_reconfig with meta LTV size %u\n", codec_cfg.meta_len); - err = bt_bap_broadcast_source_reconfig(source, &codec_cfg, &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too large meta LTV did not " - "fail\n"); + FAIL("bt_bap_broadcast_source_reconfig with meta LTV size %zu in " + "subgroup_param did not fail\n", + codec_cfg.meta_len); return; } + } +} - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); +static void test_broadcast_source_reconfig_inval_subgroup_param( + struct bt_bap_broadcast_source *broadcast_source) +{ + struct bt_bap_broadcast_source_subgroup_param subgroup_param; + struct bt_bap_broadcast_source_param reconfig_param; + struct bt_bap_broadcast_source_stream_param stream_param; + int err; + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Set count to 0 */ + subgroup_param.params_count = 0; + + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with 0 stream_param count did not fail\n"); + return; } - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); + /* Set count higher than max */ + subgroup_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT + 1; + + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with too high stream_param count did not " + "fail\n"); + return; + } + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Set params to NULL */ + subgroup_param.params = NULL; + + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param did not fail\n"); + return; + } + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + + /* Set codec to NULL */ + subgroup_param.codec_cfg = NULL; + + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL codec did not fail\n"); + return; + } + + /* Invalid codec values */ + test_broadcast_source_reconfig_inval_subgroup_codec_param(broadcast_source); +} + +static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source *broadcast_source) +{ + struct bt_bap_broadcast_source_stream_param stream_param; + struct bt_bap_broadcast_source_subgroup_param subgroup_param; + struct bt_bap_broadcast_source_param reconfig_param; + struct bt_audio_codec_qos qos; + int err; + + /* Test NULL parameters */ + + printk("Test bt_bap_broadcast_source_reconfig with NULL broadcast source\n"); + err = bt_bap_broadcast_source_reconfig(NULL, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL broadcast source did not fail\n"); + return; + } + + printk("Test bt_bap_broadcast_source_reconfig with NULL param\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, NULL); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL param did not fail\n"); + return; + } + + /* Test stream_param values */ + test_broadcast_source_reconfig_inval_stream_param(broadcast_source); + + /* Test invalid subgroup_param values*/ + test_broadcast_source_reconfig_inval_subgroup_param(broadcast_source); + + /* Invalid reconfig_param values */ + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + reconfig_param.params_count = 0; + + printk("Test bt_bap_broadcast_source_reconfig with 0 params_count\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with 0 params_count did not fail\n"); + return; + } + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + reconfig_param.params = NULL; + + printk("Test bt_bap_broadcast_source_reconfig with NULL params\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL params did not fail\n"); + return; + } + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + reconfig_param.packing = 0x35; + + printk("Test bt_bap_broadcast_source_reconfig with packing 0x%02X\n", + reconfig_param.packing); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with invalid packing did not fail\n"); + return; + } + + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + reconfig_param.qos = NULL; + + printk("Test bt_bap_broadcast_source_reconfig with NULL qos\n"); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with NULL qos did not fail\n"); + return; + } + + /* Invalid QoS values */ + broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); + reconfig_param.qos = memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); qos.phy = BT_AUDIO_CODEC_QOS_CODED + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.phy %u\n", qos.phy); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.phy 0x%02X\n", qos.phy); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with invalid PHY did not fail\n"); return; @@ -853,8 +1070,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.framing = BT_AUDIO_CODEC_QOS_FRAMING_FRAMED + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.framing %u\n", qos.framing); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.framing 0x%02X\n", qos.framing); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with invalid framing did not fail\n"); return; @@ -864,8 +1081,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.rtn = BT_ISO_BROADCAST_RTN_MAX + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.rtn %u\n", qos.rtn); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.rtn 0x%02X\n", qos.rtn); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with invalid RTN did not fail\n"); return; @@ -875,8 +1092,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.sdu = BT_ISO_MAX_SDU + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.sdu %u\n", qos.sdu); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.sdu 0x%02X\n", qos.sdu); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with invalid SDU size did not fail\n"); return; @@ -886,8 +1103,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.latency = BT_ISO_LATENCY_MIN - 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.latency %u\n", qos.latency); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.latency 0x%02X\n", qos.latency); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with too low latency did not fail\n"); return; @@ -897,8 +1114,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.latency = BT_ISO_LATENCY_MAX + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.latency %u\n", qos.latency); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.latency 0x%02X\n", qos.latency); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with too high latency did not fail\n"); return; @@ -908,8 +1125,8 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.interval = BT_ISO_SDU_INTERVAL_MIN - 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.interval %u\n", qos.interval); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.interval 0x%02X\n", qos.interval); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with too low interval did not fail\n"); return; @@ -919,21 +1136,58 @@ static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source qos.interval = BT_ISO_SDU_INTERVAL_MAX + 1; - printk("Test bt_bap_broadcast_source_reconfig with qos.interval %u\n", qos.interval); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, &qos); + printk("Test bt_bap_broadcast_source_reconfig with qos.interval 0x%02X\n", qos.interval); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); if (err == 0) { FAIL("bt_bap_broadcast_source_reconfig with too high interval did not fail\n"); return; } + + reconfig_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT + 1; + + printk("Test bt_bap_broadcast_source_reconfig with %zu subgroups\n", + reconfig_param.params_count); + err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); + if (err == 0) { + FAIL("bt_bap_broadcast_source_reconfig with %zu subgroups did not fail\n", + reconfig_param.params_count); + return; + } } static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *source) { + uint8_t bis_codec_data[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_FREQ, + BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ)), + }; + struct bt_bap_broadcast_source_stream_param + stream_params[ARRAY_SIZE(broadcast_source_streams)]; + struct bt_bap_broadcast_source_subgroup_param + subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; + struct bt_bap_broadcast_source_param reconfig_param; int err; + for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) { + stream_params[i].stream = &broadcast_source_streams[i]; + stream_params[i].data_len = ARRAY_SIZE(bis_codec_data); + stream_params[i].data = bis_codec_data; + } + + for (size_t i = 0U; i < ARRAY_SIZE(subgroup_params); i++) { + subgroup_params[i].params_count = 1U; + subgroup_params[i].params = &stream_params[i]; + subgroup_params[i].codec_cfg = &preset_16_2_2.codec_cfg; + } + + reconfig_param.params_count = ARRAY_SIZE(subgroup_params); + reconfig_param.params = subgroup_params; + reconfig_param.qos = &preset_16_2_2.qos; + reconfig_param.packing = BT_ISO_PACKING_SEQUENTIAL; + reconfig_param.encryption = false; + printk("Reconfiguring broadcast source\n"); - err = bt_bap_broadcast_source_reconfig(source, &preset_16_2_1.codec_cfg, - &preset_16_2_1.qos); + err = bt_bap_broadcast_source_reconfig(source, &reconfig_param); if (err != 0) { FAIL("Unable to reconfigure broadcast source: %d\n", err); return; @@ -1150,7 +1404,7 @@ static void test_main(void) err = bt_bap_broadcast_source_update_metadata(source, new_metadata, ARRAY_SIZE(new_metadata)); if (err != 0) { - FAIL("Failed to update metadata broadcast source: %d", err); + FAIL("Failed to update metadata broadcast source: %d\n", err); return; } From 0d877e785572f5af93dd4383ffdf059fcd0446ec Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 25 Aug 2023 11:15:25 +0200 Subject: [PATCH 0733/4498] drivers: counter: Fix Smartbond counter get_rate When timer calibration for SmartBond(tm) was added, opaque type clock_control_subsystem_t that used to have device tree ordinal number was changed to enum to allow values that are not in device tree (like no clock selection). During this process counter driver for SmartBond(tm) was not updated accordingly, resulting in wrong frequency being reported to counter driver. Failure could be seen when samples/drivers/counter/alarm was execute on da1469x_dk_pro board. With this fix counter driver uses correct type when clock_control_get_rate is called and counter test works again. Signed-off-by: Jerzy Kasenberg --- drivers/counter/counter_smartbond_timer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/counter/counter_smartbond_timer.c b/drivers/counter/counter_smartbond_timer.c index 5d1468648fd..0173373f107 100644 --- a/drivers/counter/counter_smartbond_timer.c +++ b/drivers/counter/counter_smartbond_timer.c @@ -7,7 +7,7 @@ #define DT_DRV_COMPAT renesas_smartbond_timer #include -#include +#include #include #include @@ -225,7 +225,7 @@ static int counter_smartbond_init_timer(const struct device *dev) TIMER_Type *timer0 = ((TIMER_Type *)cfg->timer) == TIMER ? TIMER : NULL; const struct device *osc_dev; uint32_t osc_freq; - uint32_t osc; + enum smartbond_clock osc; if (cfg->clock_src_divn) { /* Timer clock source is DIVn 32MHz */ @@ -238,17 +238,17 @@ static int counter_smartbond_init_timer(const struct device *dev) switch ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >> CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) { case LP_CLK_OSC_RC32K: - osc = DT_DEP_ORD(DT_NODELABEL(rc32k)); + osc = SMARTBOND_CLK_RC32K; break; case LP_CLK_OSC_RCX: - osc = DT_DEP_ORD(DT_NODELABEL(rcx)); + osc = SMARTBOND_CLK_RCX; break; default: case LP_CLK_OSC_XTAL32K: - osc = DT_DEP_ORD(DT_NODELABEL(xtal32k)); + osc = SMARTBOND_CLK_XTAL32K; break; } - clock_control_get_rate(osc_dev, (clock_control_subsys_t *)&osc, &osc_freq); + clock_control_get_rate(osc_dev, (clock_control_subsys_t)osc, &osc_freq); data->freq = osc_freq / (cfg->prescaler + 1); } timer->TIMER2_PRESCALER_REG = cfg->prescaler; From ddf4504bce5b79b590f6a10b3efbbb3b4095a7ec Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 13:58:42 +0200 Subject: [PATCH 0734/4498] tests: Bluetooth: Add inval test of bt_bap_broadcast_source_start Add tests to test invalid parameters to bt_bap_broadcast_source_start. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index 27a348f4399..3c5562f4049 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -219,3 +219,53 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_start_send zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); fixture->source = NULL; } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_source_null) +{ + struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_le_ext_adv ext_adv = {0}; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(NULL, &ext_adv); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_ext_adv_null) +{ + struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, NULL); + zassert_not_equal(0, err, "Did not fail with null ext_adv"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_double_start) +{ + struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_le_ext_adv ext_adv = {0}; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); + zassert_equal(0, err, "Unable to start broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); + zassert_not_equal(0, err, "Did not fail with starting already started source"); +} From b92422afb83bc94e5186d268fb50b09f686d794a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 14:00:45 +0200 Subject: [PATCH 0735/4498] tests: bsim: Bluetooth: Remove broadcast_source_start_inval Removed the tests for invalid bt_bap_broadcast_source_start parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 1b81d0f714b..b43bd6f3a5e 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -1194,39 +1194,6 @@ static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *sourc } } -static void test_broadcast_source_start_inval_state(struct bt_bap_broadcast_source *source, - struct bt_le_ext_adv *adv) -{ - int err; - - printk("Test bt_bap_broadcast_source_start in streaming state\n"); - err = bt_bap_broadcast_source_start(source, adv); - if (err == 0) { - FAIL("bt_bap_broadcast_source_start in streaming state did not fail\n"); - return; - } -} - -static void test_broadcast_source_start_inval(struct bt_bap_broadcast_source *source, - struct bt_le_ext_adv *adv) -{ - int err; - - printk("Test bt_bap_broadcast_source_start with NULL source\n"); - err = bt_bap_broadcast_source_start(NULL, adv); - if (err == 0) { - FAIL("bt_bap_broadcast_source_start with NULL source did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_start with NULL adv\n"); - err = bt_bap_broadcast_source_start(source, NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_start with NULL adv did not fail\n"); - return; - } -} - static void test_broadcast_source_start(struct bt_bap_broadcast_source *source, struct bt_le_ext_adv *adv) { @@ -1384,10 +1351,8 @@ static void test_main(void) test_broadcast_source_reconfig_inval(source); test_broadcast_source_reconfig(source); - test_broadcast_source_start_inval(source, adv); test_broadcast_source_start(source, adv); test_broadcast_source_reconfig_inval_state(source); - test_broadcast_source_start_inval_state(source, adv); /* Initialize sending */ for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { From 0341c6cbcf680124d1b27d47ccdb2ef0afc3f6e0 Mon Sep 17 00:00:00 2001 From: Steve Boylan Date: Wed, 6 Sep 2023 14:27:04 -0400 Subject: [PATCH 0736/4498] samples: sensor: bme280: Demonstrate RP2040 PIO Demonstrate use of the Raspberry Pi Pico PIO SPI driver. Added rpi_pico test cases to sample.yaml Signed-off-by: Steve Boylan --- boards/arm/rpi_pico/doc/index.rst | 10 ++++++ boards/arm/rpi_pico/rpi_pico_w.yaml | 1 + samples/sensor/bme280/README.rst | 28 +++++++++++++++ samples/sensor/bme280/boards/rpi_pico.overlay | 10 ++++++ .../sensor/bme280/rpi_pico_spi_pio.overlay | 36 +++++++++++++++++++ samples/sensor/bme280/sample.yaml | 16 ++++++++- 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 samples/sensor/bme280/boards/rpi_pico.overlay create mode 100644 samples/sensor/bme280/rpi_pico_spi_pio.overlay diff --git a/boards/arm/rpi_pico/doc/index.rst b/boards/arm/rpi_pico/doc/index.rst index 49d5905e94b..2fb41387864 100644 --- a/boards/arm/rpi_pico/doc/index.rst +++ b/boards/arm/rpi_pico/doc/index.rst @@ -140,6 +140,16 @@ Zephyr does not (currently) assemble PIO programs. Rather, they should be manually assembled and embedded in source code. An example of how this is done can be found at `drivers/serial/uart_rpi_pico_pio.c`. +Sample: SPI vio PIO +==================== + +The :zephyr_file:`samples/sensor/bme280/README.rst` sample includes a +demonstration of using the PIO SPI driver to communicate with an +environmental sensor. The PIO SPI driver supports using any +combination of GPIO pins for an SPI bus, as well as allowing up to +four independent SPI buses on a single board (using the two SPI +devices as well as both PIO devices). + Programming and Debugging ************************* diff --git a/boards/arm/rpi_pico/rpi_pico_w.yaml b/boards/arm/rpi_pico/rpi_pico_w.yaml index adc102da731..32bf9ef078f 100644 --- a/boards/arm/rpi_pico/rpi_pico_w.yaml +++ b/boards/arm/rpi_pico/rpi_pico_w.yaml @@ -19,3 +19,4 @@ supported: - pwm - flash - dma + - pio diff --git a/samples/sensor/bme280/README.rst b/samples/sensor/bme280/README.rst index f47512fe341..f6372779154 100644 --- a/samples/sensor/bme280/README.rst +++ b/samples/sensor/bme280/README.rst @@ -73,6 +73,34 @@ The devicetree overlay :zephyr_file:`samples/sensor/bme280/arduino_i2c.overlay` works on any board with a properly configured Arduino pin-compatible I2C peripheral. +BME280 via Raspberry Pi Pico +============================ + +The default assignment of the built-in spi0 device on the :ref:`rpi_pico` is +to GPIO16 through GPIO19. With the sensor wired to those lines, build and +flash with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/bme280 + :goals: build flash + :board: rpi_pico + +An alternative is to use PIO serving as an SPI device. The devicetree +overlay :zephyr_file:`samples/sensor/bme280/rpi_pico_spi_pio.overlay` +demonstrates using PIO SPI with the sensor wired to arbitrary GPIO pins. +Build and flash with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/bme280 + :goals: build flash + :board: rpi_pico + :gen-args: -DDTC_OVERLAY_FILE=rpi_pico_spi_pio.overlay + +Note that miso-gpios, mosi-gpios, and clk-gpios need to be assigned to the +selected PIO device in pinctrl, while cs-gpios should not; chip select is +controlled by the SPI context and must operate as a conventional GPIO pin, +not under control of PIO. + Board-specific overlays ======================= diff --git a/samples/sensor/bme280/boards/rpi_pico.overlay b/samples/sensor/bme280/boards/rpi_pico.overlay new file mode 100644 index 00000000000..61cf67aff5b --- /dev/null +++ b/samples/sensor/bme280/boards/rpi_pico.overlay @@ -0,0 +1,10 @@ +&spi0 { + status = "okay"; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi0_default>; + bme280@0 { + compatible = "bosch,bme280"; + reg = <0>; + spi-max-frequency = <1000000>; /* conservatively set to 1MHz */ + }; +}; diff --git a/samples/sensor/bme280/rpi_pico_spi_pio.overlay b/samples/sensor/bme280/rpi_pico_spi_pio.overlay new file mode 100644 index 00000000000..473cfae2a0b --- /dev/null +++ b/samples/sensor/bme280/rpi_pico_spi_pio.overlay @@ -0,0 +1,36 @@ +&pinctrl { + pio0_spi0_default: pio0_spi0_default { + /* gpio 13 is used for chip select, not assigned to the PIO */ + group1 { + pinmux = , ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; +}; + +&pio0 { + status = "okay"; + + pio0_spi0: pio0_spi0 { + pinctrl-0 = <&pio0_spi0_default>; + pinctrl-names = "default"; + + compatible = "raspberrypi,pico-spi-pio"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + clocks = < &system_clk >; + miso-gpios = <&gpio0 12 0>; + cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + clk-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + bme280@0 { + compatible = "bosch,bme280"; + reg = <0>; + spi-max-frequency = <1000000>; /* conservatively set to 1MHz */ + }; + }; +}; diff --git a/samples/sensor/bme280/sample.yaml b/samples/sensor/bme280/sample.yaml index eaa0d13e5bb..2e84cd1af03 100644 --- a/samples/sensor/bme280/sample.yaml +++ b/samples/sensor/bme280/sample.yaml @@ -4,7 +4,9 @@ tests: sample.sensor.bme280: harness: console tags: sensors - platform_allow: adafruit_feather_m0_basic_proto + platform_allow: + - adafruit_feather_m0_basic_proto + - rpi_pico integration_platforms: - adafruit_feather_m0_basic_proto harness_config: @@ -24,3 +26,15 @@ tests: regex: - "temp: (.*); press: (.*); humidity: (.*)" fixture: fixture_spi_bme280 + sample.sensor.bme280.rpi_pico.pio: + harness: console + tags: sensors + platform_allow: rpi_pico + integration_platforms: + - rpi_pico + extra_args: "DTC_OVERLAY_FILE=rpi_pico_spi_pio.overlay" + harness_config: + type: one_line + regex: + - "temp: (.*); press: (.*); humidity: (.*)" + fixture: fixture_rpi_pico_pio_spi_bme280 From 7c1ec029334b8e15e22795e386f4f7dcf798fa2c Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Fri, 25 Aug 2023 18:41:59 +0100 Subject: [PATCH 0737/4498] drivers: spi: stm32h7: Add interrupt tests for H7 Add interrupt loopback tests for SPI STM32H7. Signed-off-by: Daniel Gaston Ochoa --- .../spi/spi_loopback/overlay-stm32-spi-interrupt.conf | 7 +++++++ tests/drivers/spi/spi_loopback/testcase.yaml | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/overlay-stm32-spi-interrupt.conf diff --git a/tests/drivers/spi/spi_loopback/overlay-stm32-spi-interrupt.conf b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-interrupt.conf new file mode 100644 index 00000000000..f678c776824 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/overlay-stm32-spi-interrupt.conf @@ -0,0 +1,7 @@ +# +# Copyright (c) 2023 Graphcore Ltd, All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SPI_STM32_INTERRUPT=y diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index e1d36d593fb..4abf97911ce 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -78,6 +78,12 @@ tests: platform_allow: - nucleo_h743zi - nucleo_h753zi + drivers.spi.stm32_spi_interrupt.loopback: + extra_args: OVERLAY_CONFIG="overlay-stm32-spi-interrupt.conf" + filter: CONFIG_SOC_FAMILY_STM32 + platform_allow: + - nucleo_h743zi + - nucleo_h753zi drivers.spi.gd32_spi_interrupt.loopback: extra_args: OVERLAY_CONFIG="overlay-gd32-spi-interrupt.conf" platform_allow: From 956a202ab8bd4258e80076b10bece4dbd1fb6e03 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 12 Sep 2023 10:30:02 +0200 Subject: [PATCH 0738/4498] Bluetooth: BAP: Add cc len check for BT_HCI_CODING_FORMAT_TRANSPARENT When using BT_HCI_CODING_FORMAT_TRANSPARENT as the codec_id, the codec configuration (cc) len sent to the controller shall be 0. Since this goes for all devices, we ensure that we don't send invalid codec ID and cc data over air. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_stream.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 940b45785de..091ee87f49e 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -208,6 +208,14 @@ bool bt_audio_valid_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) } #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 + /* Verify that codec configuration length is 0 when using + * BT_HCI_CODING_FORMAT_TRANSPARENT as per the core spec, 5.4, Vol 4, Part E, 7.8.109 + */ + if (codec_cfg->id == BT_HCI_CODING_FORMAT_TRANSPARENT && codec_cfg->data_len != 0) { + LOG_DBG("Invalid data_len %zu for codec_id %u", codec_cfg->data_len, codec_cfg->id); + return false; + } + if (codec_cfg->data_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) { LOG_DBG("codec_cfg->data_len (%zu) is invalid", codec_cfg->data_len); return false; From f93caa39030f9f29d0a9287e5f4e03f0f750c5d0 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 12 Sep 2023 10:38:43 +0200 Subject: [PATCH 0739/4498] Bluetooth: Audio: BT_AUDIO_CODEC_LC3_ID -> BT_HCI_CODING_FORMAT_LC3 Replace the BT_AUDIO_CODEC_LC3_ID macro with the BT_HCI_CODING_FORMAT_LC3 as there is no reason to define and use the LC3 ID different than the other allowed codec IDs. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/lc3.h | 10 +++------- include/zephyr/bluetooth/hci_types.h | 2 ++ samples/bluetooth/hap_ha/src/bap_unicast_sr.c | 2 +- samples/bluetooth/tmap_central/src/cap_initiator.c | 2 +- samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c | 2 +- samples/bluetooth/unicast_audio_client/src/main.c | 2 +- samples/bluetooth/unicast_audio_server/src/main.c | 2 +- subsys/bluetooth/audio/bap_stream.c | 2 +- subsys/bluetooth/audio/bap_unicast_client.c | 2 +- subsys/bluetooth/audio/shell/audio.h | 4 ++-- subsys/bluetooth/audio/shell/bap.c | 2 +- tests/bluetooth/tester/src/btp_bap.c | 4 ++-- tests/bsim/bluetooth/audio/src/bap_unicast_common.c | 4 ++-- .../bsim/bluetooth/audio/src/bap_unicast_server_test.c | 2 +- 14 files changed, 20 insertions(+), 22 deletions(-) diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index cec566e5983..65c978261e2 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -20,16 +20,12 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif -/** - * @brief LC3 codec ID - */ -#define BT_AUDIO_CODEC_LC3_ID 0x06 - /** * @brief Codec capability type id's * @@ -292,7 +288,7 @@ enum bt_audio_codec_config_type { */ #define BT_AUDIO_CODEC_CAP_LC3(_freq, _duration, _chan_count, _len_min, _len_max, \ _max_frames_per_sdu, _prefer_context) \ - BT_AUDIO_CODEC_CAP(BT_AUDIO_CODEC_LC3_ID, 0x0000, 0x0000, \ + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, \ BT_AUDIO_CODEC_CAP_LC3_DATA(_freq, _duration, _chan_count, _len_min, \ _len_max, _max_frames_per_sdu), \ BT_AUDIO_CODEC_CAP_LC3_META(_prefer_context)) @@ -341,7 +337,7 @@ enum bt_audio_codec_config_type { */ #define BT_AUDIO_CODEC_LC3_CONFIG(_freq, _duration, _loc, _len, _frames_per_sdu, _stream_context) \ BT_AUDIO_CODEC_CFG( \ - BT_AUDIO_CODEC_LC3_ID, 0x0000, 0x0000, \ + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, \ BT_AUDIO_CODEC_CFG_LC3_DATA(_freq, _duration, _loc, _len, _frames_per_sdu), \ BT_AUDIO_CODEC_CFG_LC3_META(_stream_context)) diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index d9dff357d35..4d637bbe4e2 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -749,6 +749,8 @@ struct bt_hci_rp_read_bd_addr { #define BT_HCI_CODING_FORMAT_TRANSPARENT 0x03 #define BT_HCI_CODING_FORMAT_LINEAR_PCM 0x04 #define BT_HCI_CODING_FORMAT_MSBC 0x05 +#define BT_HCI_CODING_FORMAT_LC3 0x06 +#define BT_HCI_CODING_FORMAT_G729A 0x07 #define BT_HCI_CODING_FORMAT_VS 0xFF diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 8db83b2ef2d..90724b68cc2 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -74,7 +74,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk("codec_cfg 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { /* LC3 uses the generic LTV format - other codecs might do as well */ enum bt_audio_location chan_allocation; diff --git a/samples/bluetooth/tmap_central/src/cap_initiator.c b/samples/bluetooth/tmap_central/src/cap_initiator.c index 2ddeada8037..1b45741e14b 100644 --- a/samples/bluetooth/tmap_central/src/cap_initiator.c +++ b/samples/bluetooth/tmap_central/src/cap_initiator.c @@ -196,7 +196,7 @@ static void print_remote_codec(const struct bt_audio_codec_cap *codec_cap, enum printk("codec id 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, codec_cap->vid, codec_cap->data_len); - if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { bt_audio_data_parse(codec_cap->data, codec_cap->data_len, print_cb, "data"); } else { /* If not LC3, we cannot assume it's LTV */ printk("data: "); diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index a62b2b774a9..bfb0588b497 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -63,7 +63,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk("codec_cfg 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { /* LC3 uses the generic LTV format - other codecs might do as well */ enum bt_audio_location chan_allocation; diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index ff3c1311c36..be17e887e08 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -369,7 +369,7 @@ static void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) printk("codec id 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, codec_cap->vid, codec_cap->data_len); - if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { bt_audio_data_parse(codec_cap->data, codec_cap->data_len, print_cb, "data"); } else { /* If not LC3, we cannot assume it's LTV */ printk("data: "); diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index 05669c5d7e7..d1e9dfb2737 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -134,7 +134,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk("codec_cfg 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { /* LC3 uses the generic LTV format - other codecs might do as well */ enum bt_audio_location chan_allocation; diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 091ee87f49e..0a6a26014ef 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -195,7 +195,7 @@ bool bt_audio_valid_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) return false; } - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { if (codec_cfg->cid != 0U) { LOG_DBG("codec_cfg->cid (%u) is invalid", codec_cfg->cid); return false; diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 4ab7b95232f..1ff81daeb60 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -1212,7 +1212,7 @@ static int unicast_client_set_codec_cap(uint8_t id, uint16_t cid, uint16_t vid, /* If codec is LC3, then it shall be LTV encoded - We verify this before storing the * data For any non-LC3 codecs, we cannot verify anything */ - if (id == BT_AUDIO_CODEC_LC3_ID) { + if (id == BT_HCI_CODING_FORMAT_LC3) { bt_data_parse(&buf, valid_ltv_cb, NULL); /* Check if all entries could be parsed */ diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index 7ba7fe52883..7f19d9105d8 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -185,7 +185,7 @@ static inline void print_codec_cap(const struct shell *sh, codec_cap->cid, codec_cap->vid, codec_cap->data_len); #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 - if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { print_ltv_array(sh, "data", codec_cap->data, codec_cap->data_len); } else { /* If not LC3, we cannot assume it's LTV */ shell_hexdump(sh, codec_cap->data, codec_cap->data_len); @@ -204,7 +204,7 @@ static inline void print_codec_cfg(const struct shell *sh, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { print_ltv_array(sh, "data", codec_cfg->data, codec_cfg->data_len); } else { /* If not LC3, we cannot assume it's LTV */ shell_hexdump(sh, codec_cfg->data, codec_cfg->data_len); diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 3d6408276a7..c238a882e13 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -1726,7 +1726,7 @@ static void base_recv(struct bt_bap_broadcast_sink *sink, const struct bt_bap_ba shell_print(ctx_shell, "%4sBIS[%d] index 0x%02x", "", i, bis_data->index); bis_indexes[index_count++] = bis_data->index; - if (subgroup->codec_cfg.id == BT_AUDIO_CODEC_LC3_ID) { + if (subgroup->codec_cfg.id == BT_HCI_CODING_FORMAT_LC3) { const int err = bt_audio_data_parse(bis_data->data, bis_data->data_len, print_data_func_cb, NULL); diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 096950df83f..fd084c2aa4b 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -110,7 +110,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) LOG_DBG("codec_cfg 0x%02x cid 0x%04x vid 0x%04x count %u", codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { /* LC3 uses the generic LTV format - other codecs might do as well */ enum bt_audio_location chan_allocation; @@ -140,7 +140,7 @@ static void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) LOG_DBG("codec_cap 0x%02x cid 0x%04x vid 0x%04x count %zu", codec_cap->id, codec_cap->cid, codec_cap->vid, codec_cap->data_len); - if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { bt_audio_data_parse(codec_cap->data, codec_cap->data_len, print_cb, "data"); } else { LOG_HEXDUMP_DBG(codec_cap->data, codec_cap->data_len, "data"); diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_common.c b/tests/bsim/bluetooth/audio/src/bap_unicast_common.c index 36023339bbf..4a828e2d6a2 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_common.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_common.c @@ -48,7 +48,7 @@ void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) printk("codec_cap ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, codec_cap->vid, codec_cap->data_len); - if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { print_ltv_array("data", codec_cap->data, codec_cap->data_len); } else { /* If not LC3, we cannot assume it's LTV */ printk("data: "); @@ -64,7 +64,7 @@ void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk("codec_cfg ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); - if (codec_cfg->id == BT_AUDIO_CODEC_LC3_ID) { + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { print_ltv_array("data", codec_cfg->data, codec_cfg->data_len); } else { /* If not LC3, we cannot assume it's LTV */ printk("data: "); diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index c302ec320ab..5062ac61ad3 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -21,7 +21,7 @@ extern enum bst_result_t bst_result; static const struct bt_audio_codec_cap lc3_codec_cap = { .path_id = BT_ISO_DATA_PATH_HCI, - .id = BT_AUDIO_CODEC_LC3_ID, + .id = BT_HCI_CODING_FORMAT_LC3, .cid = 0x0000U, .vid = 0x0000U, .data_len = (3 + 1) + (2 + 1) + (2 + 1) + (5 + 1) + (2 + 1), From 3c34dd3724918ce8f4865629374d3fdef7a55d3e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 12 Sep 2023 11:49:21 +0200 Subject: [PATCH 0740/4498] Bluetooth: Audio: Remove struct BT_AUDIO_CODEC_LC3_frame_len Remove this unused and malnamed struct. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/lc3.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 65c978261e2..caac8aebc33 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -145,11 +145,6 @@ enum bt_audio_codec_capability_type { #define BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(...) \ ((uint8_t)((FOR_EACH(BIT, (|), __VA_ARGS__)) >> 1)) -struct BT_AUDIO_CODEC_LC3_frame_len { - uint16_t min; - uint16_t max; -}; - /** * @brief Codec configuration type IDs * From b9a193a0a39376368a9dfd2b231fe5ca5cda4600 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 14:20:49 +0100 Subject: [PATCH 0741/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 736234caa5ee0b3090cf02e5af0c2dc798aa4beb Brings following Zephyr relevant fixes: - c7aa2c0 boot_serial: Fix issues with single slot mode/encrypted images - 6ba46c0 boot_serial: Fix issue with queued commands - 274547c bootutil: PSA Crypto ECDSA enablement - 8f8fbf9 zephyr: Fall back to minimal C library - 5c5222f boot_serial: Fix include - b847a33 espressif: use minimal libc as default for ESP32 boards - 480b97f boot_serial: Fix missing point if using snprintf - 3790f5f boot: zephyr: use indication LED also in timeout based recovery - 0035c33 zephyr: Provide third image cases for direct image upload Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 900b16401c8..788eb9dfe3d 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 9bf7ce8c5fe8152836a6e00bd4444153bd950342 + revision: 736234caa5ee0b3090cf02e5af0c2dc798aa4beb path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From 9064170cf85c8ac71961ff01c018cadc03d742d7 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 12 Sep 2023 23:28:34 +0200 Subject: [PATCH 0742/4498] tests: Bluetooth: Audio: Modify bsim tests to use bt_le_scan_cb_register Update the tests to use bt_le_scan_cb_register and the "new" scan callback, as that is better suited to handle extended advertising. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_assistant_test.c | 3 ++- .../audio/src/bap_unicast_client_test.c | 17 ++++++++++++++++- tests/bsim/bluetooth/audio/src/common.c | 19 +++++++++++-------- tests/bsim/bluetooth/audio/src/common.h | 3 +-- .../bluetooth/audio/src/has_client_test.c | 4 +++- .../bluetooth/audio/src/ias_client_test.c | 4 +++- tests/bsim/bluetooth/audio/src/mcc_test.c | 4 +++- .../audio/src/media_controller_test.c | 4 +++- .../bluetooth/audio/src/micp_mic_ctlr_test.c | 4 +++- .../audio/src/pacs_notify_client_test.c | 6 ++++-- tests/bsim/bluetooth/audio/src/tbs_test.c | 3 ++- .../bluetooth/audio/src/vcp_vol_ctlr_test.c | 3 ++- 12 files changed, 53 insertions(+), 21 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c index 381810d68db..9964bd29c0a 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c @@ -490,9 +490,10 @@ static int common_init(void) bt_gatt_cb_register(&gatt_callbacks); bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cbs); bt_le_per_adv_sync_cb_register(&sync_callbacks); + bt_le_scan_cb_register(&common_scan_cb); printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return err; diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index e31c092684a..72aa1cfcd96 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -320,6 +320,7 @@ static void init(void) g_streams[i].ops = &stream_ops; } + bt_le_scan_cb_register(&common_scan_cb); bt_gatt_cb_register(&gatt_callbacks); err = bt_bap_unicast_client_register_cb(&unicast_client_cbs); @@ -333,7 +334,7 @@ static void scan_and_connect(void) { int err; - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; @@ -343,6 +344,19 @@ static void scan_and_connect(void) WAIT_FOR_FLAG(flag_connected); } +static void disconnect_acl(void) +{ + int err; + + err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err != 0) { + FAIL("Failed to disconnect (err %d)\n", err); + return; + } + + WAIT_FOR_UNSET_FLAG(flag_connected); +} + static void exchange_mtu(void) { WAIT_FOR_FLAG(flag_mtu_exchanged); @@ -748,6 +762,7 @@ static void test_main(void) unicast_group = NULL; } + disconnect_acl(); PASS("Unicast client passed\n"); } diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 30758e01732..90a8cb98efa 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -16,8 +16,7 @@ const struct bt_data ad[AD_SIZE] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) }; -void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, - struct net_buf_simple *ad) +static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) { char addr_str[BT_ADDR_LE_STR_LEN]; int err; @@ -27,15 +26,15 @@ void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, } /* We're only interested in connectable events */ - if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) { + if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0) { return; } - bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); - printk("Device found: %s (RSSI %d)\n", addr_str, rssi); + bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (info->rssi < -70) { FAIL("RSSI too low"); return; } @@ -46,13 +45,17 @@ void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, return; } - err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, - BT_LE_CONN_PARAM_DEFAULT, &default_conn); + err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, + &default_conn); if (err) { FAIL("Could not connect to peer: %d", err); } } +struct bt_le_scan_cb common_scan_cb = { + .recv = device_found, +}; + static void connected(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 917a024b724..14d6dbbc092 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -65,13 +65,12 @@ #define SYNC_RETRY_COUNT 6 /* similar to retries for connections */ #define PA_SYNC_SKIP 5 +extern struct bt_le_scan_cb common_scan_cb; extern const struct bt_data ad[AD_SIZE]; extern struct bt_conn *default_conn; extern atomic_t flag_connected; extern atomic_t flag_conn_updated; -void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, - struct net_buf_simple *ad); void disconnected(struct bt_conn *conn, uint8_t reason); void test_tick(bs_time_t HW_device_time); void test_init(void); diff --git a/tests/bsim/bluetooth/audio/src/has_client_test.c b/tests/bsim/bluetooth/audio/src/has_client_test.c index 9d63463e0ce..6690c6b032e 100644 --- a/tests/bsim/bluetooth/audio/src/has_client_test.c +++ b/tests/bsim/bluetooth/audio/src/has_client_test.c @@ -157,7 +157,9 @@ static void test_main(void) return; } - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + bt_le_scan_cb_register(&common_scan_cb); + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err < 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/ias_client_test.c b/tests/bsim/bluetooth/audio/src/ias_client_test.c index 6c435fb5cc6..0966d899306 100644 --- a/tests/bsim/bluetooth/audio/src/ias_client_test.c +++ b/tests/bsim/bluetooth/audio/src/ias_client_test.c @@ -83,7 +83,9 @@ static void test_main(void) return; } - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + bt_le_scan_cb_register(&common_scan_cb); + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err < 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/mcc_test.c b/tests/bsim/bluetooth/audio/src/mcc_test.c index 8a32e33bf16..9e8cd95806b 100644 --- a/tests/bsim/bluetooth/audio/src/mcc_test.c +++ b/tests/bsim/bluetooth/audio/src/mcc_test.c @@ -2396,6 +2396,8 @@ void test_main(void) printk("Bluetooth initialized\n"); + bt_le_scan_cb_register(&common_scan_cb); + /* Initialize MCC ********************************************/ err = do_mcc_init(); if (err != 0) { @@ -2414,7 +2416,7 @@ void test_main(void) printk("\n########### Running iteration #%u\n\n", i); UNSET_FLAG(flag_connected); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Failed to start scanning (err %d\n)", err); } else { diff --git a/tests/bsim/bluetooth/audio/src/media_controller_test.c b/tests/bsim/bluetooth/audio/src/media_controller_test.c index 9c1df656fd1..ad91cffb939 100644 --- a/tests/bsim/bluetooth/audio/src/media_controller_test.c +++ b/tests/bsim/bluetooth/audio/src/media_controller_test.c @@ -1585,6 +1585,8 @@ void initialize_bluetooth(void) WAIT_FOR_FLAG(ble_is_initialized); printk("Bluetooth initialized\n"); + + bt_le_scan_cb_register(&common_scan_cb); } void scan_and_connect(void) @@ -1592,7 +1594,7 @@ void scan_and_connect(void) char addr[BT_ADDR_LE_STR_LEN]; int err; - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err) { FAIL("Failed to start scanning (err %d\n)", err); return; diff --git a/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c b/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c index 1074c8c2cef..5cefd31d099 100644 --- a/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c +++ b/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c @@ -357,11 +357,13 @@ static void test_main(void) return; } + bt_le_scan_cb_register(&common_scan_cb); + bt_micp_mic_ctlr_cb_register(&micp_mic_ctlr_cbs); WAIT_FOR_COND(g_bt_init); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c b/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c index 7cbe5feaa22..9910f6f2c8c 100644 --- a/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c +++ b/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c @@ -490,8 +490,10 @@ static void test_main(void) return; } + bt_le_scan_cb_register(&common_scan_cb); + printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Could not start scanning (err %d)\n", err); return; @@ -536,7 +538,7 @@ static void test_main(void) WAIT_FOR_UNSET_FLAG(flag_connected); printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Could not start scanning (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/tbs_test.c b/tests/bsim/bluetooth/audio/src/tbs_test.c index b20dca26608..a1bf1e035c0 100644 --- a/tests/bsim/bluetooth/audio/src/tbs_test.c +++ b/tests/bsim/bluetooth/audio/src/tbs_test.c @@ -331,9 +331,10 @@ static void test_main(void) printk("Audio Client: Bluetooth initialized\n"); bt_conn_cb_register(&conn_callbacks); + bt_le_scan_cb_register(&common_scan_cb); bt_tbs_register_cb(&tbs_cbs); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c b/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c index 52ba2f072ab..77feaa4bfb5 100644 --- a/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c +++ b/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c @@ -1153,9 +1153,10 @@ static void test_main(void) return; } + bt_le_scan_cb_register(&common_scan_cb); test_cb_register(); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; From 01f7d108f3d1982549535f6fe4c7096b188cb3ed Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 13 Sep 2023 16:58:54 +0200 Subject: [PATCH 0743/4498] tests: bsim: Bluetooth: Add BAP unicast disconnect test The purpose of this test is to verify that the stack has the correct behavior if the ACL disconnects while one or more streams are in the streaming state. The main point it validates is that unicast server device can restart advertising using a simple k_work in the disconnected callback. The number of connections supported by the test suite has also been reduced to 3, to avoid some seen issues with scheduling when CONFIG_BT_MAX_CONN=5. A part of implementing the test for this purpose, the unicast client and unicast server have been extended to also advertise and scan for proper ASCS advertising data. Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/audio/prj.conf | 5 +- .../audio/src/bap_unicast_client_test.c | 149 ++++++++++++- .../audio/src/bap_unicast_server_test.c | 201 +++++++++++++----- .../bap_unicast_audio_acl_disconnect.sh | 27 +++ 4 files changed, 328 insertions(+), 54 deletions(-) create mode 100755 tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index 2077143452b..8f2d6a585a9 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -9,8 +9,9 @@ CONFIG_BT_DEVICE_NAME="bsim_test_audio" # TBS Client may require up to 12 buffers CONFIG_BT_L2CAP_TX_BUF_COUNT=12 CONFIG_BT_ATT_PREPARE_COUNT=5 -CONFIG_BT_MAX_CONN=5 -CONFIG_BT_MAX_PAIRED=5 +CONFIG_BT_MAX_CONN=3 +CONFIG_BT_MAX_PAIRED=3 +CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_SMP=y CONFIG_BT_L2CAP_TX_MTU=100 diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index 72aa1cfcd96..3fbd70458b9 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -306,6 +306,92 @@ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = att_mtu_updated, }; +static bool parse_ascs_ad_data(struct bt_data *data, void *user_data) +{ + const struct bt_le_scan_recv_info *info = user_data; + uint16_t available_source_context; + uint16_t available_sink_context; + struct net_buf_simple net_buf; + struct bt_uuid_16 adv_uuid; + uint8_t announcement_type; + void *uuid; + int err; + + const size_t min_data_len = BT_UUID_SIZE_16 + sizeof(announcement_type) + + sizeof(available_sink_context) + + sizeof(available_source_context); + + if (data->type != BT_DATA_SVC_DATA16) { + return true; + } + + if (data->data_len < min_data_len) { + + return true; + } + + net_buf_simple_init_with_data(&net_buf, (void *)data->data, data->data_len); + + uuid = net_buf_simple_pull_mem(&net_buf, BT_UUID_SIZE_16); + if (!bt_uuid_create(&adv_uuid.uuid, uuid, BT_UUID_SIZE_16)) { + return true; + } + + if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_ASCS)) { + return true; + } + + announcement_type = net_buf_simple_pull_u8(&net_buf); + available_sink_context = net_buf_simple_pull_le16(&net_buf); + available_source_context = net_buf_simple_pull_le16(&net_buf); + + printk("Found ASCS with announcement type 0x%02X, sink ctx 0x%04X, source ctx 0x%04X\n", + announcement_type, available_sink_context, available_source_context); + + printk("Stopping scan\n"); + if (bt_le_scan_stop()) { + FAIL("Could not stop scan"); + return false; + } + + err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, + &default_conn); + if (err) { + FAIL("Could not connect to peer: %d", err); + return false; + } + + /* Stop parsing */ + return false; +} + +static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + + if (default_conn) { + return; + } + + /* We're only interested in connectable events */ + if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0) { + return; + } + /* connect only to devices in close proximity */ + if (info->rssi < -70) { + return; + } + + bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi); + + bt_data_parse(ad, parse_ascs_ad_data, (void *)info); +} + +static struct bt_le_scan_cb bap_scan_cb = { + .recv = broadcast_scan_recv, +}; + static void init(void) { int err; @@ -320,7 +406,7 @@ static void init(void) g_streams[i].ops = &stream_ops; } - bt_le_scan_cb_register(&common_scan_cb); + bt_le_scan_cb_register(&bap_scan_cb); bt_gatt_cb_register(&gatt_callbacks); err = bt_bap_unicast_client_register_cb(&unicast_client_cbs); @@ -767,14 +853,71 @@ static void test_main(void) PASS("Unicast client passed\n"); } +static void test_main_acl_disconnect(void) +{ + struct bt_bap_unicast_group *unicast_group; + size_t stream_cnt; + + init(); + + scan_and_connect(); + + exchange_mtu(); + + discover_sinks(); + + discover_sources(); + + /* Run the stream setup multiple time to ensure states are properly + * set and reset + */ + + printk("Creating unicast group\n"); + stream_cnt = create_unicast_group(&unicast_group); + + printk("Codec configuring streams\n"); + codec_configure_streams(stream_cnt); + + printk("QoS configuring streams\n"); + qos_configure_streams(unicast_group, stream_cnt); + + printk("Enabling streams\n"); + enable_streams(stream_cnt); + + printk("Metadata update streams\n"); + metadata_update_streams(stream_cnt); + + printk("Starting streams\n"); + start_streams(); + + disconnect_acl(); + + printk("Deleting unicast group\n"); + delete_unicast_group(unicast_group); + unicast_group = NULL; + + /* Reconnect */ + scan_and_connect(); + + disconnect_acl(); + + PASS("Unicast client ACL disconnect passed\n"); +} + static const struct bst_test_instance test_unicast_client[] = { { .test_id = "unicast_client", .test_post_init_f = test_init, .test_tick_f = test_tick, - .test_main_f = test_main + .test_main_f = test_main, + }, + { + .test_id = "unicast_client_acl_disconnect", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main_acl_disconnect, }, - BSTEST_END_MARKER + BSTEST_END_MARKER, }; struct bst_test_list *test_unicast_client_install(struct bst_test_list *tests) diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index 5062ac61ad3..9dcf878de9b 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -48,11 +48,20 @@ static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASC static const struct bt_audio_codec_qos_pref qos_pref = BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000); -/* TODO: Expand with BAP data */ +static uint8_t unicast_server_addata[] = { + BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */ + BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */ + BT_BYTES_LIST_LE16(PREF_CONTEXT), + BT_BYTES_LIST_LE16(PREF_CONTEXT), + 0x00, /* Metadata length */ +}; + static const struct bt_data unicast_server_ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL)), + BT_DATA(BT_DATA_SVC_DATA16, unicast_server_addata, ARRAY_SIZE(unicast_server_addata)), }; +static struct bt_le_ext_adv *ext_adv; CREATE_FLAG(flag_stream_configured); @@ -230,47 +239,6 @@ static struct bt_bap_stream_ops stream_ops = { .recv = stream_recv }; -static void init(void) -{ - static struct bt_pacs_cap cap = { - .codec_cap = &lc3_codec_cap, - }; - int err; - - err = bt_enable(NULL); - if (err != 0) { - FAIL("Bluetooth enable failed (err %d)\n", err); - return; - } - - printk("Bluetooth initialized\n"); - - bt_bap_unicast_server_register_cb(&unicast_server_cb); - - err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); - if (err != 0) { - FAIL("Failed to register capabilities: %d", err); - return; - } - - err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap); - if (err != 0) { - FAIL("Failed to register capabilities: %d", err); - return; - } - - for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { - bt_bap_stream_cb_register(&streams[i], &stream_ops); - } - - err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, unicast_server_ad, ARRAY_SIZE(unicast_server_ad), - NULL, 0); - if (err != 0) { - FAIL("Advertising failed to start (err %d)\n", err); - return; - } -} - static void set_location(void) { int err; @@ -332,25 +300,160 @@ static void set_available_contexts(void) printk("Available contexts successfully set\n"); } -static void test_main(void) +static void init(void) { - init(); + static struct bt_pacs_cap cap = { + .codec_cap = &lc3_codec_cap, + }; + int err; + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth enable failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + bt_bap_unicast_server_register_cb(&unicast_server_cb); + + err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); + if (err != 0) { + FAIL("Failed to register capabilities: %d", err); + return; + } + + err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap); + if (err != 0) { + FAIL("Failed to register capabilities: %d", err); + return; + } set_location(); set_available_contexts(); + for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { + bt_bap_stream_cb_register(&streams[i], &stream_ops); + } + + /* Create a non-connectable non-scannable advertising set */ + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN_NAME, NULL, &ext_adv); + if (err != 0) { + FAIL("Failed to create advertising set (err %d)\n", err); + return; + } + + err = bt_le_ext_adv_set_data(ext_adv, unicast_server_ad, ARRAY_SIZE(unicast_server_ad), + NULL, 0); + if (err != 0) { + FAIL("Failed to set advertising data (err %d)\n", err); + return; + } + + err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + FAIL("Failed to start advertising set (err %d)\n", err); + return; + } + printk("Advertising started\n"); +} + +static void test_main(void) +{ + init(); + /* TODO: When babblesim supports ISO, wait for audio stream to pass */ WAIT_FOR_FLAG(flag_connected); WAIT_FOR_FLAG(flag_stream_configured); + + WAIT_FOR_UNSET_FLAG(flag_connected); + PASS("Unicast server passed\n"); } -static const struct bst_test_instance test_unicast_server[] = {{.test_id = "unicast_server", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = test_main}, - BSTEST_END_MARKER}; +static void restart_adv_cb(struct k_work *work) +{ + int err; + + printk("Restarting ext_adv after disconnect\n"); + + err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + FAIL("Failed to start advertising set (err %d)\n", err); + return; + } +} + +static K_WORK_DEFINE(restart_adv_work, restart_adv_cb); + +static void acl_disconnected(struct bt_conn *conn, uint8_t reason) +{ + if (conn != default_conn) { + return; + } + + k_work_submit(&restart_adv_work); +} + +static void test_main_acl_disconnect(void) +{ + struct bt_le_ext_adv *dummy_ext_adv[CONFIG_BT_MAX_CONN - 1]; + static struct bt_conn_cb conn_callbacks = { + .disconnected = acl_disconnected, + }; + + init(); + + /* Create CONFIG_BT_MAX_CONN - 1 dummy advertising sets, to ensure that we only have 1 free + * connection when attempting to restart advertising, which should ensure that the + * bt_conn object is properly unref'ed by the stack + */ + for (size_t i = 0U; i < ARRAY_SIZE(dummy_ext_adv); i++) { + const struct bt_le_adv_param param = BT_LE_ADV_PARAM_INIT( + (BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CONNECTABLE), + BT_GAP_ADV_SLOW_INT_MAX, BT_GAP_ADV_SLOW_INT_MAX, NULL); + int err; + + err = bt_le_ext_adv_create(¶m, NULL, &dummy_ext_adv[i]); + if (err != 0) { + FAIL("Failed to create advertising set[%zu] (err %d)\n", i, err); + return; + } + + err = bt_le_ext_adv_start(dummy_ext_adv[i], BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + FAIL("Failed to start advertising set[%zu] (err %d)\n", i, err); + return; + } + } + + bt_conn_cb_register(&conn_callbacks); + + WAIT_FOR_FLAG(flag_connected); + WAIT_FOR_FLAG(flag_stream_configured); + + /* The client will reconnect */ + WAIT_FOR_UNSET_FLAG(flag_connected); + WAIT_FOR_FLAG(flag_connected); + PASS("Unicast server ACL disconnect passed\n"); +} + +static const struct bst_test_instance test_unicast_server[] = { + { + .test_id = "unicast_server", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main, + }, + { + .test_id = "unicast_server_acl_disconnect", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main_acl_disconnect, + }, + BSTEST_END_MARKER, +}; struct bst_test_list *test_unicast_server_install(struct bst_test_list *tests) { diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh new file mode 100755 index 00000000000..875a2b752dc --- /dev/null +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +SIMULATION_ID="unicast_audio_acl_disconnect" +VERBOSITY_LEVEL=2 +EXECUTE_TIMEOUT=20 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n======== Unicast Audio ACL Disconnect test =========\n\n" + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client_acl_disconnect -rs=23 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server_acl_disconnect -rs=28 + +# Simulation time should be larger than the WAIT_TIME in common.h +Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs From c3c83c7049337f2ab1b6889ad83cb922457a3185 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 13 Sep 2023 17:02:45 +0200 Subject: [PATCH 0744/4498] Bluetooth: ASCS: Modify the ACL disconnect behavior Instead of calling ase_release for each ASE in the ACL disconnected callback, we now call the state_transition_work_handler directly. This is to ensure that when the disconnected callback returns, the bt_conn object has been properly unref'ed in a timely manner. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/ascs.c | 14 +++++++++++++- tests/bluetooth/audio/ascs/src/main.c | 4 ---- tests/bluetooth/audio/mocks/src/kernel.c | 7 +++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 1b71d27fbf4..b74cc5ce284 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -123,6 +123,8 @@ static void ase_free(struct bt_ascs_ase *ase) bt_conn_unref(ase->conn); ase->conn = NULL; + + (void)k_work_cancel(&ase->state_transition_work); } static void ase_status_changed(struct bt_ascs_ase *ase, uint8_t state) @@ -1101,7 +1103,17 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) } if (ase->ep.status.state != BT_BAP_EP_STATE_IDLE) { - ase_release(ase, reason, BT_BAP_ASCS_RSP_NULL); + /* We must set the state to idle when the ACL is disconnected immediately, + * as when the ACL disconnect callbacks have been called, the application + * should expect there to be only a single reference to the bt_conn pointer + * from the stack. + * We trigger the work handler directly rather than e.g. calling + * ase_set_state_idle to trigger "regular" state change behavior (such) as + * calling stream->stopped when leaving the streaming state. + */ + ase->ep.reason = reason; + ase->state_pending = BT_BAP_EP_STATE_IDLE; + state_transition_work_handler(&ase->state_transition_work); /* At this point, `ase` object have been free'd */ } } diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index b0bc7f88150..126c82d63bb 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -250,7 +250,6 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_client_terminates mock_bt_iso_disconnected(chan, BT_HCI_ERR_REMOTE_USER_TERM_CONN); /* Expected to notify the upper layers */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); expect_bt_bap_stream_ops_released_called_once(stream); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); @@ -288,7 +287,6 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_server_terminates k_sleep(K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY)); /* Expected to notify the upper layers */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); expect_bt_bap_stream_ops_released_called_once(stream); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); @@ -351,7 +349,6 @@ ZTEST_F(ascs_test_suite, test_release_stream_pair_on_acl_disconnection_client_te const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream }; expect_bt_bap_stream_ops_released_called_twice(streams); - expect_bt_bap_unicast_server_cb_release_called_twice(streams); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); } @@ -413,7 +410,6 @@ ZTEST_F(ascs_test_suite, test_release_stream_pair_on_acl_disconnection_server_te const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream }; expect_bt_bap_stream_ops_released_called_twice(streams); - expect_bt_bap_unicast_server_cb_release_called_twice(streams); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); } diff --git a/tests/bluetooth/audio/mocks/src/kernel.c b/tests/bluetooth/audio/mocks/src/kernel.c index ce9dcab5d3a..03dc2cf582d 100644 --- a/tests/bluetooth/audio/mocks/src/kernel.c +++ b/tests/bluetooth/audio/mocks/src/kernel.c @@ -56,6 +56,13 @@ int k_work_cancel_delayable(struct k_work_delayable *dwork) return 0; } +int k_work_cancel(struct k_work *work) +{ + (void)sys_slist_find_and_remove(&work_pending, &work->node); + + return 0; +} + void k_work_init(struct k_work *work, k_work_handler_t handler) { work->handler = handler; From 3a34840957a186fe5956c5714eda4072b469a707 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Fri, 15 Sep 2023 10:50:13 +0200 Subject: [PATCH 0745/4498] boards: arm: nrf9161dk: update SPI flash This patch updates the SPI flash to the one currently used in the latest board version. Since these are still 0.X.X board versions, old configurations are not explicitly supported. Signed-off-by: Maximilian Deubel --- .../nrf9161dk_nrf9161_common.dtsi | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi index 1dee5b1b1a3..a6aeccf34b9 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi @@ -128,7 +128,7 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &gd25lb256; + spi-flash0 = &gd25wb256; }; }; @@ -195,22 +195,22 @@ arduino_spi: &spi3 { pinctrl-1 = <&spi3_sleep>; pinctrl-names = "default", "sleep"; - gd25lb256: gd25lb256e3ir@1 { + gd25wb256: gd25wb256e3ir@1 { compatible = "jedec,spi-nor"; status = "disabled"; reg = <1>; - spi-max-frequency = <60000000>; - jedec-id = [c8 67 19]; - sfdp-bfp = [ - e5 20 ea ff ff ff ff 0f 44 eb 08 6b 00 3b 00 bb - fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 - 10 d8 00 ff d5 31 b1 fe 82 e4 14 4c ec 60 06 33 - 7a 75 7a 75 04 bd d5 5c 29 06 74 00 08 50 00 01 - ]; + spi-max-frequency = <8000000>; size = <268435456>; has-dpd; t-enter-dpd = <3000>; - t-exit-dpd = <30000>; + t-exit-dpd = <40000>; + sfdp-bfp = [ + e5 20 f3 ff ff ff ff 0f 44 eb 08 6b 08 3b 42 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 44 7a c9 fe 83 67 26 62 ec 82 18 44 + 7a 75 7a 75 04 c4 d5 5c 00 06 74 00 08 50 00 01 + ]; + jedec-id = [c8 65 19]; }; }; From 8eecca2419b10c1318e3978c4f21447614e6cfad Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 15 Sep 2023 14:01:28 +0200 Subject: [PATCH 0746/4498] Bluetooth: BAP: Broadcast sink call stopped after BIG cleanup Modify the order of operation in broadcast_sink_iso_disconnected so that when the application gets the last stopped callback, the BIG has already been cleaned up, and the broadcast sink is in a reusable state. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 25 ++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 9866dfd1c57..296989244af 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -360,25 +360,24 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, broadcast_sink_set_ep_state(ep, BT_BAP_EP_STATE_IDLE); - if (ops != NULL && ops->stopped != NULL) { - ops->stopped(stream, reason); - } else { - LOG_WRN("No callback for stopped set"); - } - sink = broadcast_sink_lookup_iso_chan(chan); if (sink == NULL) { LOG_ERR("Could not lookup sink by iso %p", chan); - return; - } + } else { + if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) { + LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink); + } - if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) { - LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink); + /* Clear sink->big if not already cleared */ + if (sys_slist_is_empty(&sink->streams) && sink->big) { + broadcast_sink_clear_big(sink, reason); + } } - /* Clear sink->big if not already cleared */ - if (sys_slist_is_empty(&sink->streams) && sink->big) { - broadcast_sink_clear_big(sink, reason); + if (ops != NULL && ops->stopped != NULL) { + ops->stopped(stream, reason); + } else { + LOG_WRN("No callback for stopped set"); } } From 9693ae3021fd29281c256db94b1e64c7082a72a6 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 15 Sep 2023 15:21:49 +0200 Subject: [PATCH 0747/4498] Bluetooth: Audio: Add parsers for getting metadata values Add parsers to retrieve metadata values from codec capabilities and codec configuration structs. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 192 ++++++++++++++- subsys/bluetooth/audio/codec.c | 318 ++++++++++++++++++++++++- 2 files changed, 499 insertions(+), 11 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 58506030686..ab40e7f372d 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -659,11 +659,8 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default); -/** @brief Lookup a specific value based on type - * - * Depending on context bt_audio_codec_cfg will be either codec capabilities, codec configuration - * or meta data. - * +/** @brief Lookup a specific codec configuration value based on type + * * * Typically types used are: * @ref bt_audio_codec_capability_type * @ref bt_audio_codec_config_type @@ -679,6 +676,191 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u /** @} */ /* End of bt_audio_codec_cfg */ +/** + * @brief Audio codec Config APIs + * @defgroup bt_audio_codec_meta Metadata parsing APIs + * + * Functions to parse LTV formatted metadata. + * + * @{ + */ + +/** @brief Lookup a specific metadata value based on type + * + * This works for metadata from both @ref bt_audio_codec_cfg meta and @ref bt_audio_codec_cap meta. + * * + * @param[in] meta The metadata to search in. + * @param[in] meta_len The length of @p meta. + * @param[in] type The type id to look for + * @param[out] data Pointer to the data-pointer to update when item is found + * + * @retval Length of found @p data (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, + const uint8_t **data); + +/** @brief Extract preferred contexts + * + * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval The preferred context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len); + +/** @brief Extract stream contexts + * + * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval The stream context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len); + +/** @brief Extract program info + * + * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. + * + * @param[in] meta The metadata to get the data from in. + * @param[in] meta_len The length of @p meta. + * @param[out] program_info Pointer to the UTF-8 formatted program info. + * + * @retval The length of the @p program_info (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info); + +/** @brief Extract stream language + * + * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval The stream language if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len); + +/** @brief Extract CCID list + * + * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. + * + * @param[in] meta The metadata to get the data from in. + * @param[in] meta_len The length of @p meta. + * @param[out] ccid_list Pointer to the array containing 8-bit CCIDs. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, + const uint8_t **ccid_list); + +/** @brief Extract parental rating + * + * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval The parental rating if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len); + +/** @brief Extract program info URI + * + * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. + * + * @param[in] meta The metadata to get the data from in. + * @param[in] meta_len The length of @p meta. + * @param[out] program_info_uri Pointer to the UTF-8 formatted program info URI. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info_uri); + +/** @brief Extract audio active state + * + * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval The preferred context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len); + +/** @brief Extract broadcast audio immediate rendering flag + * + * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. + * + * @param meta The metadata to get the data from in. + * @param meta_len The length of @p meta. + * + * @retval 0 if the flag was found + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not the flag was not found + */ +int bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag(const uint8_t meta[], + size_t meta_len); + +/** @brief Extract extended metadata + * + * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. + * + * @param[in] meta The metadata to get the data from in. + * @param[in] meta_len The length of @p meta. + * @param[out] extended_meta Pointer to the extended metadata. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, + const uint8_t **extended_meta); + +/** @brief Extract vendor specific metadata + * + * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. + * + * @param[in] meta The metadata to get the data from in. + * @param[in] meta_len The length of @p meta. + * @param[out] vendor_meta Pointer to the vendor specific metadata. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, + const uint8_t **vendor_meta); + +/** @} */ /* End of bt_audio_codec_meta */ #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 1b4c9c659c7..9ce5bf228dc 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -18,9 +18,8 @@ LOG_MODULE_REGISTER(bt_audio_codec, CONFIG_BT_AUDIO_CODEC_LOG_LEVEL); -#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 - struct search_type_param { + bool found; uint8_t type; uint8_t data_len; const uint8_t **data; @@ -31,6 +30,7 @@ static bool parse_cb(struct bt_data *data, void *user_data) struct search_type_param *param = (struct search_type_param *)user_data; if (param->type == data->type) { + param->found = true; param->data_len = data->data_len; *param->data = data->data; @@ -40,10 +40,13 @@ static bool parse_cb(struct bt_data *data, void *user_data) return true; } +#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 + uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data) { struct search_type_param param = { + .found = false, .type = type, .data_len = 0, .data = data, @@ -168,8 +171,8 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, - &data); + data_len = + bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, &data); if (data == NULL) { return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } @@ -193,8 +196,8 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, - &data); + data_len = + bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, &data); if (data == NULL) { return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } @@ -234,3 +237,306 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg return data[0]; } #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ + +#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ + CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 + +int bt_audio_codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, + const uint8_t **data) +{ + struct search_type_param param = { + .type = type, + .data_len = 0, + .data = data, + }; + int err; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(data == NULL) { + LOG_DBG("data is NULL"); + return -EINVAL; + } + + *data = NULL; + + err = bt_audio_data_parse(meta, meta_len, parse_cb, ¶m); + if (err != 0 && err != -ECANCELED) { + LOG_DBG("Could not parse the meta data: %d", err); + return err; + } + + if (!param.found) { + LOG_DBG("Could not find the type %u", type); + return -ENODATA; + } + + return param.data_len; +} + +int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + &data); + if (data == NULL) { + return -ENODATA; + } + + if (ret != sizeof(uint16_t)) { + return -EBADMSG; + } + + return sys_get_le16(data); +} + +int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + &data); + if (data == NULL) { + return -ENODATA; + } + + if (ret != sizeof(uint16_t)) { + return -EBADMSG; + } + + return sys_get_le16(data); +} + +int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info == NULL) { + LOG_DBG("program_info is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + &data); + if (data == NULL) { + return -ENODATA; + } + + *program_info = data; + + return ret; +} + +int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_LANG, + &data); + if (data == NULL) { + return -ENODATA; + } + + if (ret != 3) { /* Stream language is 3 octets */ + return -EBADMSG; + } + + return sys_get_le24(data); +} + +int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, + const uint8_t **ccid_list) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(ccid_list == NULL) { + LOG_DBG("ccid_list is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_CCID_LIST, &data); + if (data == NULL) { + return -ENODATA; + } + + *ccid_list = data; + + return ret; +} + +int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + &data); + if (data == NULL) { + return -ENODATA; + } + + if (ret != sizeof(uint8_t)) { + return -EBADMSG; + } + + return data[0]; +} + +int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info_uri) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info_uri == NULL) { + LOG_DBG("program_info_uri is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, + &data); + if (data == NULL) { + return -ENODATA; + } + + *program_info_uri = data; + + return ret; +} + +int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + &data); + if (data == NULL) { + return -ENODATA; + } + + if (ret != sizeof(uint8_t)) { + return -EBADMSG; + } + + return data[0]; +} + +int bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag(const uint8_t meta[], + size_t meta_len) +{ + const uint8_t *data; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + return bt_audio_codec_meta_get_val(meta, meta_len, + BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, &data); +} + +int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, + const uint8_t **extended_meta) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(extended_meta == NULL) { + LOG_DBG("extended_meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_EXTENDED, &data); + if (data == NULL) { + return -ENODATA; + } + + *extended_meta = data; + + return ret; +} + +int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, + const uint8_t **vendor_meta) +{ + const uint8_t *data; + int ret; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(vendor_meta == NULL) { + LOG_DBG("vendor_meta is NULL"); + return -EINVAL; + } + + ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_VENDOR, &data); + if (data == NULL) { + return -ENODATA; + } + + *vendor_meta = data; + + return ret; +} +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ + * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ + */ From 64720549763bc38aff17c1285d03376f14e73b1b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 18 Sep 2023 11:22:23 +0200 Subject: [PATCH 0748/4498] tests: Bluetooth: Audio: Codec meta_get unit tests Add unit tests for the bt_audio_codec_meta_get_* functions. Signed-off-by: Emil Gydesen --- tests/bluetooth/audio/codec/src/main.c | 147 +++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 982082328a1..e4727dfec78 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -9,6 +9,7 @@ #include #include #include +#include DEFINE_FFF_GLOBALS; @@ -71,3 +72,149 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_blocks_per_sdu) ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&preset.codec_cfg, true); zassert_equal(ret, 1u, "unexpected return value %d", ret); } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_pref_context) +{ + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | + BT_AUDIO_CONTEXT_TYPE_MEDIA)), + }; + int ret; + + ret = bt_audio_codec_meta_get_pref_context(metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, 0x0005, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_stream_context) +{ + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | + BT_AUDIO_CONTEXT_TYPE_MEDIA)), + }; + int ret; + + ret = bt_audio_codec_meta_get_stream_context(metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', + 'I', 'n', 'f', 'o'}; + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + 'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'I', 'n', 'f', 'o'), + }; + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_meta_get_program_info(metadata, ARRAY_SIZE(metadata), &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g'), + }; + int ret; + + ret = bt_audio_codec_meta_get_stream_lang(metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15), + }; + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_meta_get_ccid_list(metadata, ARRAY_SIZE(metadata), &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_parental_rating) +{ + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE), + }; + int ret; + + ret = bt_audio_codec_meta_get_parental_rating(metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'), + }; + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_meta_get_program_info_uri(metadata, ARRAY_SIZE(metadata), + &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_audio_active_state) +{ + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED), + }; + int ret; + + ret = bt_audio_codec_meta_get_audio_active_state(metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag) +{ + const uint8_t metadata[] = {0x01, BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE}; + int ret; + + ret = bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag( + metadata, ARRAY_SIZE(metadata)); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03), + }; + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_meta_get_extended(metadata, ARRAY_SIZE(metadata), &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t metadata[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03), + }; + const uint8_t *vendor_meta; + int ret; + + ret = bt_audio_codec_meta_get_vendor(metadata, ARRAY_SIZE(metadata), &vendor_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); +} From 5452665beb98acba74dbf8ecf07e1deb97b2a7e0 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 17 Sep 2023 21:16:00 +1000 Subject: [PATCH 0749/4498] net: l2: wifi_mgmt: remove scan kconfig defaults Remove the wifi_mgmt interface overriding default values with values from kconfig. The defaults were only applied when a `params` struct was provided by the application. This is the case when the application is explicitly setting the options it wants, why is the mgmt API changing these. When `params` is NULL and thus modem defaults are requested, these defaults aren't applied. This is the opposite behaviour from what seems reasonable. In addition, these options are: * Undocumented * Using non-trivial string parsing functions (strtok) * Adding complexity to the API implementation by forcing support for ROM versions of command line arguments. Signed-off-by: Jordan Yates --- subsys/net/l2/wifi/Kconfig | 67 ---------------------------------- subsys/net/l2/wifi/wifi_mgmt.c | 55 ---------------------------- 2 files changed, 122 deletions(-) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 6623456d84b..ccf5ce31ca6 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -39,40 +39,6 @@ config WIFI_MGMT_TWT_CHECK_IP even when it is awake intervals. Rejecting TWT setup till Wi-Fi interface has a valid IP address might be desirable in most scenarios. -config WIFI_MGMT_FORCED_PASSIVE_SCAN - bool "Force Passive scan" - help - Force passive scan (typically used to reduce power consumption), - the scan type is always sent as passive. - This doesn't guarantee that passive scan will be used, it depends - on the underlying chip implementation to support and honour scan type. - -config WIFI_MGMT_SCAN_BANDS - string "Frequency bands to scan" - default "" - help - Specifies the frequency bands to scan, as follows: - 2 - 2.4 GHz - 5 - 5 GHz - 6 - 6 GHz - "" - All bands allowed by the regulatory domain. - Multiple bands can be specified as comma separated band values. - Only regulatory domain permitted values are allowed. - -config WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE - int "Active scan dwell time" - default 50 - range 5 1000 - help - Active scan dwell time (in ms) per channel. - -config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE - int "Passive scan dwell time" - default 130 - range 10 1000 - help - Passive scan dwell time (in ms) per channel. - config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 @@ -81,39 +47,6 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. -config WIFI_MGMT_SCAN_SSID_FILT - string "Scan for specific SSIDs" - default "" - help - String of comma separated SSID values to scan for. The number of SSID’s - that can be specified depends on WIFI_MGMT_SCAN_MAX_SSIDS. - Use "" to disable SSID filtering. - -config WIFI_MGMT_SCAN_MAX_BSS_CNT - int "Maximum number of scan results to return." - default 0 - range 0 65535 - help - Maximum number of scan results to return. 0 represents unlimited number of BSSes. - -config WIFI_MGMT_SCAN_CHAN - string "Scan on specific channels" - default "" - help - Formatted string which specifies channels to be scanned. The channel string has to be formatted - using the colon (:), comma(,), hyphen (-) and space ( ) delimiters as follows: - - A colon identifies the value preceding it as a band. A band value - (2: 2.4 GHz, 5: 5 GHz 6: 6 GHz) has to precede the channels in that band (e.g. 2: etc) - - Hyphens are used to identify channel ranges (e.g. 2-7, 32-48 etc) - - Commas are used to separate channel values within a band. Channels can be specified - as individual values (2,6,48 etc) or channel ranges using hyphens (1-14, 32-48 etc) - - Spaces are used to specify multiple band-channel sets (e.g. 2:1,2 5:36,40 etc) - - No spaces should be used anywhere else, i.e. before/after commas, - before/after hyphens. - An example channel specification specifying channels in the 2.4 GHz and 5 GHz bands is - as below: - 2:1,5,7,9-11_5:36-48,100,163-167 - config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 7f0f30dc8c1..e9355f4f703 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -13,7 +13,6 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include -#include #ifdef CONFIG_WIFI_NM #include #endif /* CONFIG_WIFI_NM */ @@ -104,65 +103,11 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct wifi_scan_params *params = data; const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); - bool chan_specified = false; - uint8_t i = 0; if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) { return -ENOTSUP; } - if (data && (len == sizeof(*params))) { -#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN - params->scan_type = WIFI_SCAN_TYPE_PASSIVE; -#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */ - - if (!params->bands) { - if (wifi_utils_parse_scan_bands(CONFIG_WIFI_MGMT_SCAN_BANDS, - ¶ms->bands)) { - NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_BANDS: %s", - CONFIG_WIFI_MGMT_SCAN_BANDS); - return -EINVAL; - } - } - - if (!params->dwell_time_active) { - params->dwell_time_active = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE; - } - - if (!params->dwell_time_passive) { - params->dwell_time_passive = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE; - } - - if (!strlen(params->ssids[0])) { - if (wifi_utils_parse_scan_ssids(CONFIG_WIFI_MGMT_SCAN_SSID_FILT, - params->ssids)) { - NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_SSID_FILT: %s", - CONFIG_WIFI_MGMT_SCAN_SSID_FILT); - return -EINVAL; - } - } - - if (!params->max_bss_cnt) { - params->max_bss_cnt = CONFIG_WIFI_MGMT_SCAN_MAX_BSS_CNT; - } - - for (i = 0; i <= WIFI_FREQ_BAND_MAX; i++) { - if (params->chan[i][0]) { - chan_specified = true; - break; - } - } - - if ((!chan_specified) && strlen(CONFIG_WIFI_MGMT_SCAN_CHAN)) { - if (wifi_utils_parse_scan_chan(CONFIG_WIFI_MGMT_SCAN_CHAN, - params->chan)) { - NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_CHAN: %s", - CONFIG_WIFI_MGMT_SCAN_CHAN); - return -EINVAL; - } - } - } - return wifi_mgmt_api->scan(dev, params, scan_result_cb); } From d1f058e65e4bf128877497c1443afe5506e25647 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 18 Sep 2023 09:38:49 +0300 Subject: [PATCH 0750/4498] scripts: pytest: Add option to filter the captured shell output Sometimes you might need exec_command() to return an value from running device. If the output contains shell prompts or logger output, it is harder to capture the value. Filter away the lines we thing belongs to the shell prompt or normal logging output. Signed-off-by: Seppo Takalo --- .../src/twister_harness/helpers/shell.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index fc8009d12fe..b785724b1ad 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -66,3 +66,15 @@ def exec_command(self, command: str, timeout: float | None = None, print_output: # wait for device command execution lines.extend(self._device.readlines_until(regex=regex_prompt, timeout=timeout, print_output=print_output)) return lines + + def get_filtered_output(self, command_lines: list[str]) -> list[str]: + regex_filter = re.compile( + '|'.join([ + re.escape(self.prompt), + '', + '', + '', + '' + ]) + ) + return list(filter(lambda l: not regex_filter.search(l), command_lines)) From 5cc14b6c50b2612aacebed548cb686e8b47eaa29 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 15 Sep 2023 15:57:37 +0200 Subject: [PATCH 0751/4498] Bluetooth: Audio: Replace BT_AUDIO_CODEC_PARSE_ERR_ with errno Replace the BT_AUDIO_CODEC_PARSE_ERR_ values with errno values. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 50 +++++++++++--------------- subsys/bluetooth/audio/codec.c | 45 ++++++++++++----------- 2 files changed, 46 insertions(+), 49 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index ab40e7f372d..943681189bc 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -566,30 +566,14 @@ struct bt_audio_codec_qos_pref { * @{ */ -/** - * @brief Codec parser error codes for @ref bt_audio_codec_cfg. - */ -enum bt_audio_codec_cfg_parse_err { - - /** @brief The requested type is not present in the data set. */ - BT_AUDIO_CODEC_PARSE_ERR_SUCCESS = 0, - - /** @brief The requested type is not present in the data set. */ - BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND = -1, - - /** @brief The value found is invalid. */ - BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND = -2, - - /** @brief The parameters specified to the function call are not valid. */ - BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM = -3, -}; - /**@brief Extract the frequency from a codec configuration. * * @param codec_cfg The codec configuration to extract data from. * - * @return The frequency in Hz if found else a negative value of type - * @ref bt_audio_codec_cfg_parse_err. + * @retval The frequency in Hz + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg); @@ -597,8 +581,10 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg); * * @param codec_cfg The codec configuration to extract data from. * - * @return Frame duration in microseconds if value is found else a negative value - * of type @ref bt_audio_codec_cfg_parse_err. + * @retval Frame duration in microseconds + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg); @@ -613,8 +599,10 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co * @param codec_cfg The codec configuration to extract data from. * @param chan_allocation Pointer to the variable to store the extracted value in. * - * @return BT_AUDIO_CODEC_PARSE_SUCCESS if value is found and stored in the pointer provided - * else a negative value of type @ref bt_audio_codec_cfg_parse_err. + * @retval 0 if value is found and stored in the pointer provided + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_location *chan_allocation); @@ -632,8 +620,10 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * * * @param codec_cfg The codec configuration to extract data from. * - * @return Frame length in octets if value is found else a negative value - * of type @ref bt_audio_codec_cfg_parse_err. + * @retval Frame length in octets + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg); @@ -652,9 +642,11 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod * if the type is not found. In this case the function will only fail if a NULL * pointer is provided. * - * @return The count of codec frames in each SDU if value is found else a negative value - * of type @ref bt_audio_codec_cfg_parse_err - unless when \p fallback_to_default is true - * then the value 1 is returned if frames per sdu is not found. + * @retval The count of codec frames in each SDU if value is found else of @p fallback_to_default + * is true then the value 1 is returned if frames per sdu is not found. + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default); diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 9ce5bf228dc..adf5ad2884f 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -53,13 +53,18 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u }; int err; - *data = NULL; - CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); return 0; } + CHECKIF(data == NULL) { + LOG_DBG("data is NULL"); + return 0; + } + + *data = NULL; + err = bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, parse_cb, ¶m); if (err != 0 && err != -ECANCELED) { LOG_DBG("Could not parse the data: %d", err); @@ -81,16 +86,16 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &data); if (data == NULL) { - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return -ENODATA; } if (data_len != sizeof(uint8_t)) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } switch (data[0]) { @@ -121,7 +126,7 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ: return 384000; default: - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } } @@ -132,16 +137,16 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, &data); if (data == NULL) { - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return -ENODATA; } if (data_len != sizeof(uint8_t)) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } switch (data[0]) { @@ -150,7 +155,7 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: return 10000; default: - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } } @@ -164,21 +169,21 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } CHECKIF(chan_allocation == NULL) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, &data); if (data == NULL) { - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return -ENODATA; } if (data_len != sizeof(uint32_t)) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } *chan_allocation = sys_get_le32(data); @@ -193,17 +198,17 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, &data); if (data == NULL) { - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return -ENODATA; } if (data_len != sizeof(uint16_t)) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } return sys_get_le16(data); @@ -217,7 +222,7 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; + return -EINVAL; } data_len = bt_audio_codec_cfg_get_val(codec_cfg, @@ -227,11 +232,11 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg return 1; } - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return -ENODATA; } if (data_len != sizeof(uint8_t)) { - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + return -EBADMSG; } return data[0]; From 215b248cc6a1b8fd47f64aacbd37860042b12615 Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Tue, 19 Sep 2023 11:21:02 -0700 Subject: [PATCH 0752/4498] boards: cy8cproto_063_ble: Add pyocd support Allow support for flashing board with pyocd Signed-off-by: Pavlo Havrylyuk --- boards/arm/cy8cproto_063_ble/board.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm/cy8cproto_063_ble/board.cmake b/boards/arm/cy8cproto_063_ble/board.cmake index 79511e34a42..9600fd724ce 100644 --- a/boards/arm/cy8cproto_063_ble/board.cmake +++ b/boards/arm/cy8cproto_063_ble/board.cmake @@ -5,3 +5,6 @@ #*************************************************************************** include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +board_runner_args(pyocd "--target=cy8c6xx7_nosmif") +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) From 166d89c69e2211bfb043922193d9e23be165ad45 Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Tue, 19 Sep 2023 11:49:52 -0700 Subject: [PATCH 0753/4498] tests: drivers: Added overlays to tests for 063_ble Fixed pinout in adc overlays to align with board Allowed adc driver sample Added overlay for gpio_basic_api test support Added overlay for i2c_api test support Signed-off-by: Pavlo Havrylyuk --- .../adc/boards/cy8cproto_063_ble.overlay | 8 ++--- samples/drivers/adc/sample.yaml | 1 + .../adc_api/boards/cy8cproto_063_ble.overlay | 4 +-- .../boards/cy8cproto_063_ble.overlay | 18 +++++++++++ .../i2c_api/boards/cy8cproto_063_ble.overlay | 32 +++++++++++++++++++ 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay create mode 100644 tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay diff --git a/samples/drivers/adc/boards/cy8cproto_063_ble.overlay b/samples/drivers/adc/boards/cy8cproto_063_ble.overlay index 48b2befb803..c2f70eff7e8 100644 --- a/samples/drivers/adc/boards/cy8cproto_063_ble.overlay +++ b/samples/drivers/adc/boards/cy8cproto_063_ble.overlay @@ -24,7 +24,7 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <0>; /* P10.0 */ + zephyr,input-positive = <2>; /* P10.2 */ }; channel@1 { @@ -33,7 +33,7 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <1>; /* P10.1 */ + zephyr,input-positive = <3>; /* P10.3 */ }; channel@2 { @@ -42,7 +42,7 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <2>; /* P10.2 */ + zephyr,input-positive = <4>; /* P10.4 */ }; channel@3 { @@ -51,6 +51,6 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <3>; /* P10.3 */ + zephyr,input-positive = <5>; /* P10.5 */ }; }; diff --git a/samples/drivers/adc/sample.yaml b/samples/drivers/adc/sample.yaml index fd3807fad99..46b88fa6040 100644 --- a/samples/drivers/adc/sample.yaml +++ b/samples/drivers/adc/sample.yaml @@ -9,6 +9,7 @@ tests: - disco_l475_iot1 - cc3220sf_launchxl - cc3235sf_launchxl + - cy8cproto_063_ble - stm32l496g_disco - stm32h735g_disco - nrf51dk_nrf51422 diff --git a/tests/drivers/adc/adc_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/adc/adc_api/boards/cy8cproto_063_ble.overlay index 4863af8b2c8..b8f7b78001e 100644 --- a/tests/drivers/adc/adc_api/boards/cy8cproto_063_ble.overlay +++ b/tests/drivers/adc/adc_api/boards/cy8cproto_063_ble.overlay @@ -24,7 +24,7 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <0>; /* P10.0 */ + zephyr,input-positive = <2>; /* P10.2 */ }; channel@1 { @@ -33,6 +33,6 @@ zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; - zephyr,input-positive = <1>; /* P10.1 */ + zephyr,input-positive = <3>; /* P10.3 */ }; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay new file mode 100644 index 00000000000..a01e0d692c5 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio_prt9 4 0>; + in-gpios = <&gpio_prt9 2 0>; + }; +}; + +&gpio_prt9 { + status = "okay"; +}; diff --git a/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay new file mode 100644 index 00000000000..17df1697469 --- /dev/null +++ b/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + */ + +/ { + aliases { + gy271 = &i2c1; + i2c-0 =&i2c1; + }; +}; + +i2c1: &scb1 { + compatible = "infineon,cat1-i2c"; + + status = "okay"; + pinctrl-0 = <&p10_0_scb1_i2c_scl &p10_1_scb1_i2c_sda>; + pinctrl-names = "default"; +}; + +/* Configure pin control bias mode for i2c pins */ +&p10_0_scb1_i2c_scl { + drive-open-drain; + input-enable; +}; + +&p10_1_scb1_i2c_sda { + drive-open-drain; + input-enable; +}; From 6c86af0331f2cd0f2e410b88c6ee290ea7648f83 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 19 Sep 2023 15:07:21 +0200 Subject: [PATCH 0754/4498] twister: pytest: Fix problems with no prompt in tests with shell Only impacts on twister-pytest scenarios. Exec command is waiting for the prompt message, but in some cases, e.g. after reseting the DUT, prompt can be followed by another strings. Solution is to clear internal serial buffer and to not request the prompt string before executing a command. Signed-off-by: Grzegorz Chwierut --- .../src/twister_harness/device/hardware_adapter.py | 1 + .../pytest-twister-harness/src/twister_harness/helpers/shell.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 3a3f242fa85..403978eed9a 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -250,6 +250,7 @@ def _clear_internal_resources(self) -> None: super()._clear_internal_resources() self._serial_connection = None self._serial_pty_proc = None + self._serial_buffer.clear() @staticmethod def _run_custom_script(script_path: str | Path, timeout: float) -> None: diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index b785724b1ad..047d6029a6e 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -57,7 +57,7 @@ def exec_command(self, command: str, timeout: float | None = None, print_output: timeout = timeout or self.base_timeout command_ext = f'{command}\n\n' regex_prompt = re.escape(self.prompt) - regex_command = f'{regex_prompt}.*{command}' + regex_command = f'.*{command}' self._device.clear_buffer() self._device.write(command_ext.encode()) lines: list[str] = [] From 108893304a493216f7c377f8c52557cf92bc4f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 20 Sep 2023 13:00:38 +0200 Subject: [PATCH 0755/4498] doc: code-sample: Fix "text" attribute for code sample links. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A link to a code-sample should have its "text" attribute set to the text description of the sample, not the description _node_. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index d9ba85114fd..46451e1f682 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -267,7 +267,7 @@ def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): code_sample_info["docname"], code_sample_info["id"], contnode, - code_sample_info["description"], + code_sample_info["description"].astext(), ) def add_code_sample(self, code_sample): From 59153afe0900eeb316d10f78976c153a7293eee7 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Wed, 20 Sep 2023 15:04:12 +0200 Subject: [PATCH 0756/4498] tests: drivers: uart: uart_basic_api: basic_api.wide issue The test drivers.uart.basic_api.wide can't work without keyboard add harness: keyboard for this test Signed-off-by: Marc Desvaux --- tests/drivers/uart/uart_basic_api/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/uart/uart_basic_api/testcase.yaml b/tests/drivers/uart/uart_basic_api/testcase.yaml index 17f0b5a7986..ee4fd934660 100644 --- a/tests/drivers/uart/uart_basic_api/testcase.yaml +++ b/tests/drivers/uart/uart_basic_api/testcase.yaml @@ -12,6 +12,7 @@ tests: - CONFIG_UART_WIDE_DATA=y tags: drivers uart filter: CONFIG_UART_CONSOLE + harness: keyboard arch_allow: arm platform_allow: nucleo_h743zi integration_platforms: From 68751b89907627e2273a47f0c5c6ea04940d21ae Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 4 Jul 2023 16:33:17 +0200 Subject: [PATCH 0757/4498] tests: Bluetooth: Audio: Add testing of source stream Expand the CAP tests to also discover and setup a source stream, so that the CAP procedures are run on multiple streams. Signed-off-by: Emil Gydesen --- .../audio/src/cap_initiator_unicast_test.c | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c index 4df05cdb8c1..0f40413d712 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c @@ -54,7 +54,9 @@ extern enum bst_result_t bst_result; static struct bt_bap_lc3_preset unicast_preset_16_2_1 = BT_BAP_LC3_UNICAST_PRESET_16_2_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); -static struct bt_cap_stream unicast_client_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; +static struct bt_cap_stream unicast_client_sink_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; +static struct bt_cap_stream + unicast_client_source_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT]; static struct bt_bap_ep *unicast_sink_eps[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; static struct bt_bap_ep @@ -351,8 +353,12 @@ static void init(void) return; } - for (size_t i = 0; i < ARRAY_SIZE(unicast_client_streams); i++) { - bt_cap_stream_ops_register(&unicast_client_streams[i], &unicast_stream_ops); + for (size_t i = 0; i < ARRAY_SIZE(unicast_client_sink_streams); i++) { + bt_cap_stream_ops_register(&unicast_client_sink_streams[i], &unicast_stream_ops); + } + + for (size_t i = 0; i < ARRAY_SIZE(unicast_client_source_streams); i++) { + bt_cap_stream_ops_register(&unicast_client_source_streams[i], &unicast_stream_ops); } } @@ -506,15 +512,18 @@ static void discover_cas(struct bt_conn *conn) static void unicast_group_create(struct bt_bap_unicast_group **out_unicast_group) { - struct bt_bap_unicast_group_stream_param group_stream_params; + struct bt_bap_unicast_group_stream_param group_source_stream_params; + struct bt_bap_unicast_group_stream_param group_sink_stream_params; struct bt_bap_unicast_group_stream_pair_param pair_params; struct bt_bap_unicast_group_param group_param; int err; - group_stream_params.qos = &unicast_preset_16_2_1.qos; - group_stream_params.stream = &unicast_client_streams[0].bap_stream; - pair_params.tx_param = &group_stream_params; - pair_params.rx_param = NULL; + group_sink_stream_params.qos = &unicast_preset_16_2_1.qos; + group_sink_stream_params.stream = &unicast_client_sink_streams[0].bap_stream; + group_source_stream_params.qos = &unicast_preset_16_2_1.qos; + group_source_stream_params.stream = &unicast_client_source_streams[0].bap_stream; + pair_params.tx_param = &group_sink_stream_params; + pair_params.rx_param = &group_source_stream_params; group_param.packing = BT_ISO_PACKING_SEQUENTIAL; group_param.params_count = 1; @@ -542,7 +551,7 @@ static void unicast_audio_start_inval(struct bt_bap_unicast_group *unicast_group valid_start_param.stream_params = &valid_stream_param; valid_stream_param.member.member = default_conn; - valid_stream_param.stream = &unicast_client_streams[0]; + valid_stream_param.stream = &unicast_client_sink_streams[0]; valid_stream_param.ep = unicast_sink_eps[bt_conn_index(default_conn)][0]; valid_stream_param.codec_cfg = &unicast_preset_16_2_1.codec_cfg; @@ -639,18 +648,24 @@ static void unicast_audio_start_inval(struct bt_bap_unicast_group *unicast_group static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group, bool wait) { - struct bt_cap_unicast_audio_start_stream_param stream_param[1]; + struct bt_cap_unicast_audio_start_stream_param stream_param[2]; struct bt_cap_unicast_audio_start_param param; int err; param.type = BT_CAP_SET_TYPE_AD_HOC; - param.count = 1u; + param.count = ARRAY_SIZE(stream_param); param.stream_params = stream_param; stream_param[0].member.member = default_conn; - stream_param[0].stream = &unicast_client_streams[0]; + stream_param[0].stream = &unicast_client_sink_streams[0]; stream_param[0].ep = unicast_sink_eps[bt_conn_index(default_conn)][0]; stream_param[0].codec_cfg = &unicast_preset_16_2_1.codec_cfg; + stream_param[1].member.member = default_conn; + stream_param[1].stream = &unicast_client_source_streams[0]; + stream_param[1].ep = unicast_source_eps[bt_conn_index(default_conn)][0]; + stream_param[1].codec_cfg = &unicast_preset_16_2_1.codec_cfg; + stream_param[1].qos = &unicast_preset_16_2_1.qos; + UNSET_FLAG(flag_started); err = bt_cap_initiator_unicast_audio_start(¶m, unicast_group); @@ -671,7 +686,7 @@ static void unicast_audio_update_inval(void) struct bt_cap_unicast_audio_update_param param; int err; - param.stream = &unicast_client_streams[0]; + param.stream = &unicast_client_sink_streams[0]; param.meta = unicast_preset_16_2_1.codec_cfg.meta; param.meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; @@ -701,16 +716,20 @@ static void unicast_audio_update_inval(void) static void unicast_audio_update(void) { - struct bt_cap_unicast_audio_update_param param; + struct bt_cap_unicast_audio_update_param param[2]; int err; - param.stream = &unicast_client_streams[0]; - param.meta = unicast_preset_16_2_1.codec_cfg.meta; - param.meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; + param[0].stream = &unicast_client_sink_streams[0]; + param[0].meta = unicast_preset_16_2_1.codec_cfg.meta; + param[0].meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; + + param[1].stream = &unicast_client_source_streams[0]; + param[1].meta = unicast_preset_16_2_1.codec_cfg.meta; + param[1].meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; UNSET_FLAG(flag_updated); - err = bt_cap_initiator_unicast_audio_update(¶m, 1); + err = bt_cap_initiator_unicast_audio_update(param, ARRAY_SIZE(param)); if (err != 0) { FAIL("Failed to update unicast audio: %d\n", err); return; @@ -808,6 +827,7 @@ static void test_main_cap_initiator_unicast(void) discover_cas(default_conn); discover_sink(default_conn); + discover_source(default_conn); for (size_t i = 0U; i < iterations; i++) { unicast_group_create(&unicast_group); @@ -841,6 +861,7 @@ static void test_main_cap_initiator_unicast_inval(void) discover_cas(default_conn); discover_sink(default_conn); + discover_source(default_conn); unicast_group_create(&unicast_group); @@ -875,6 +896,7 @@ static void test_cap_initiator_unicast_timeout(void) discover_cas(default_conn); discover_sink(default_conn); + discover_source(default_conn); unicast_group_create(&unicast_group); @@ -1009,10 +1031,14 @@ static int set_chan_alloc(enum bt_audio_location loc, struct bt_audio_codec_cfg return 0; } + + /* Since we are incrementing i by the value_len, we don't need to increment it + * further in the `for` statement + */ i += value_len; } - return -ENODATA; + return -ENOENT; } static int cap_initiator_ac_cap_unicast_start(const struct cap_initiator_ac_param *param, From f0cc8d4cb1f434ad0c7c33d187dc78f481867842 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 6 Jul 2023 13:40:10 +0200 Subject: [PATCH 0758/4498] Bluetooth: CAP: Add support for long read/write Add support for reading and writing long values (> MTU) when using the CAP API. This change does make it slightly slower to execute the CAP procedures as it is now done on a one-by-one basis, which affect multi-ACL setups, but that also means that the buffer requirements for CAP will generally be lower. There is still room for improvement as we can perform the BAP operations in parallel on each ACl, which should return this to its former performance. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/cap_initiator.c | 489 +++++++++++------- .../audio/src/cap_initiator_unicast_test.c | 17 +- 2 files changed, 311 insertions(+), 195 deletions(-) diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index 4c7e5c767bb..7362ea94341 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -314,6 +314,23 @@ enum cap_unicast_subproc_type { CAP_UNICAST_SUBPROC_TYPE_RELEASE, }; +struct cap_unicast_proc_param { + struct bt_cap_stream *stream; + union { + struct { + struct bt_conn *conn; + struct bt_bap_ep *ep; + struct bt_audio_codec_cfg codec_cfg; + } start; + struct { + /** Codec Specific Capabilities Metadata count */ + size_t meta_len; + /** Codec Specific Capabilities Metadata */ + uint8_t meta[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE]; + } meta_update; + }; +}; + struct cap_unicast_proc { ATOMIC_DEFINE(proc_state_flags, CAP_UNICAST_PROC_STATE_FLAG_NUM); /* Total number of streams in the procedure*/ @@ -326,7 +343,7 @@ struct cap_unicast_proc { enum cap_unicast_subproc_type subproc_type; int err; struct bt_conn *failed_conn; - struct bt_cap_stream *streams[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT]; + struct cap_unicast_proc_param proc_param[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT]; struct bt_bap_unicast_group *unicast_group; }; @@ -388,7 +405,7 @@ static bool cap_conn_in_active_proc(const struct bt_conn *conn) } for (size_t i = 0U; i < active_proc.stream_initiated_cnt; i++) { - if (active_proc.streams[i]->bap_stream.conn == conn) { + if (active_proc.proc_param[i].stream->bap_stream.conn == conn) { return true; } } @@ -619,7 +636,7 @@ static bool cap_stream_in_active_proc(const struct bt_cap_stream *cap_stream) } for (size_t i = 0U; i < active_proc.stream_cnt; i++) { - if (active_proc.streams[i] == cap_stream) { + if (active_proc.proc_param[i].stream == cap_stream) { return true; } } @@ -749,71 +766,6 @@ static bool valid_unicast_audio_start_param(const struct bt_cap_unicast_audio_st return true; } -static int cap_initiator_unicast_audio_configure( - const struct bt_cap_unicast_audio_start_param *param) -{ - /** TODO: If this is a CSIP set, then the order of the procedures may - * not match the order in the parameters, and the CSIP ordered access - * procedure should be used. - */ - - /* Store the information about the active procedure so that we can - * continue the procedure after each step - */ - atomic_set_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ACTIVE); - active_proc.stream_cnt = param->count; - - cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_CODEC_CONFIG); - - for (size_t i = 0U; i < param->count; i++) { - struct bt_cap_unicast_audio_start_stream_param *stream_param = - ¶m->stream_params[i]; - union bt_cap_set_member *member = &stream_param->member; - struct bt_cap_stream *cap_stream = stream_param->stream; - struct bt_bap_stream *bap_stream = &cap_stream->bap_stream; - struct bt_bap_ep *ep = stream_param->ep; - struct bt_audio_codec_cfg *codec_cfg = stream_param->codec_cfg; - struct bt_conn *conn; - int err; - - if (param->type == BT_CAP_SET_TYPE_AD_HOC) { - conn = member->member; - } else { - struct cap_unicast_client *client; - - /* We have verified that `client` wont be NULL in - * `valid_unicast_audio_start_param`. - */ - client = lookup_unicast_client_by_csis(member->csip); - __ASSERT(client != NULL, "client is NULL"); - conn = client->conn; - } - - /* Ensure that ops are registered before any procedures are started */ - bt_cap_stream_ops_register_bap(cap_stream); - - active_proc.streams[i] = cap_stream; - - err = bt_bap_stream_config(conn, bap_stream, ep, codec_cfg); - if (err != 0) { - LOG_DBG("bt_bap_stream_config failed for param->stream_params[%zu]: %d", - i, err); - - if (i > 0U) { - cap_abort_proc(bap_stream->conn, err); - } else { - (void)memset(&active_proc, 0, sizeof(active_proc)); - } - - return err; - } - - active_proc.stream_initiated_cnt++; - } - - return 0; -} - static void cap_initiator_unicast_audio_proc_complete(void) { struct bt_bap_unicast_group *unicast_group; @@ -853,6 +805,82 @@ static void cap_initiator_unicast_audio_proc_complete(void) } } +static int cap_initiator_unicast_audio_configure( + const struct bt_cap_unicast_audio_start_param *param) +{ + struct cap_unicast_proc_param *proc_param; + struct bt_audio_codec_cfg *codec_cfg; + struct bt_bap_stream *bap_stream; + struct bt_bap_ep *ep; + struct bt_conn *conn; + int err; + /** TODO: If this is a CSIP set, then the order of the procedures may + * not match the order in the parameters, and the CSIP ordered access + * procedure should be used. + */ + + for (size_t i = 0U; i < param->count; i++) { + struct bt_cap_unicast_audio_start_stream_param *stream_param = + ¶m->stream_params[i]; + union bt_cap_set_member *member = &stream_param->member; + struct bt_cap_stream *cap_stream = stream_param->stream; + + if (param->type == BT_CAP_SET_TYPE_AD_HOC) { + conn = member->member; + } else { + struct cap_unicast_client *client; + + /* We have verified that `client` wont be NULL in + * `valid_unicast_audio_start_param`. + */ + client = lookup_unicast_client_by_csis(member->csip); + __ASSERT(client != NULL, "client is NULL"); + conn = client->conn; + } + + /* Ensure that ops are registered before any procedures are started */ + bt_cap_stream_ops_register_bap(cap_stream); + + /* Store the necessary parameters as we cannot assume that the supplied parameters + * are kept valid + */ + active_proc.proc_param[i].stream = cap_stream; + active_proc.proc_param[i].start.ep = stream_param->ep; + active_proc.proc_param[i].start.conn = conn; + memcpy(&active_proc.proc_param[i].start.codec_cfg, stream_param->codec_cfg, + sizeof(*stream_param->codec_cfg)); + } + + /* Store the information about the active procedure so that we can + * continue the procedure after each step + */ + atomic_set_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ACTIVE); + active_proc.stream_cnt = param->count; + + cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_CODEC_CONFIG); + + proc_param = &active_proc.proc_param[0]; + bap_stream = &proc_param->stream->bap_stream; + codec_cfg = &proc_param->start.codec_cfg; + conn = proc_param->start.conn; + ep = proc_param->start.ep; + + /* Since BAP operations may require a write long or a read long on the notification, + * we cannot assume that we can do multiple streams at once, thus do it one at a time. + * TODO: We should always be able to do one per ACL, so there is room for optimization. + */ + err = bt_bap_stream_config(conn, bap_stream, ep, codec_cfg); + if (err != 0) { + LOG_DBG("Failed to config stream %p: %d", proc_param->stream, err); + + (void)memset(&active_proc, 0, sizeof(active_proc)); + } else { + active_proc.stream_initiated_cnt++; + } + + return err; +} + int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start_param *param, struct bt_bap_unicast_group *unicast_group) { @@ -879,8 +907,9 @@ int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream) { - struct bt_conn *conns[MIN(CONFIG_BT_MAX_CONN, - CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT)]; + struct bt_conn + *conns[MIN(CONFIG_BT_MAX_CONN, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT)]; + struct cap_unicast_proc_param *proc_param; struct bt_bap_unicast_group *unicast_group; if (!cap_stream_in_active_proc(cap_stream)) { @@ -900,14 +929,8 @@ void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream) } else { active_proc.stream_done_cnt++; - LOG_DBG("Stream %p configured (%zu/%zu streams done)", - cap_stream, active_proc.stream_done_cnt, - active_proc.stream_cnt); - - if (!cap_proc_is_done()) { - /* Not yet finished, wait for all */ - return; - } + LOG_DBG("Stream %p configured (%zu/%zu streams done)", cap_stream, + active_proc.stream_done_cnt, active_proc.stream_cnt); } if (cap_proc_is_aborted()) { @@ -918,13 +941,43 @@ void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream) return; } + if (!cap_proc_is_done()) { + struct bt_cap_stream *next_cap_stream = + active_proc.proc_param[active_proc.stream_done_cnt].stream; + struct bt_conn *conn = + active_proc.proc_param[active_proc.stream_done_cnt].start.conn; + struct bt_bap_ep *ep = active_proc.proc_param[active_proc.stream_done_cnt].start.ep; + struct bt_audio_codec_cfg *codec_cfg = + &active_proc.proc_param[active_proc.stream_done_cnt].start.codec_cfg; + struct bt_bap_stream *bap_stream = &next_cap_stream->bap_stream; + int err; + + /* Since BAP operations may require a write long or a read long on the notification, + * we cannot assume that we can do multiple streams at once, thus do it one at a + * time. + * TODO: We should always be able to do one per ACL, so there is room for + * optimization. + */ + err = bt_bap_stream_config(conn, bap_stream, ep, codec_cfg); + if (err != 0) { + LOG_DBG("Failed to config stream %p: %d", next_cap_stream, err); + + cap_abort_proc(conn, err); + cap_initiator_unicast_audio_proc_complete(); + } else { + active_proc.stream_initiated_cnt++; + } + + return; + } + /* The QoS Configure procedure works on a set of connections and a * unicast group, so we generate a list of unique connection pointers * for the procedure */ (void)memset(conns, 0, sizeof(conns)); for (size_t i = 0U; i < active_proc.stream_cnt; i++) { - struct bt_conn *stream_conn = active_proc.streams[i]->bap_stream.conn; + struct bt_conn *stream_conn = active_proc.proc_param[i].stream->bap_stream.conn; struct bt_conn **free_conn = NULL; bool already_added = false; @@ -951,7 +1004,8 @@ void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream) /* All streams in the procedure share the same unicast group, so we just * use the reference from the first stream */ - unicast_group = (struct bt_bap_unicast_group *)active_proc.streams[0]->bap_stream.group; + proc_param = &active_proc.proc_param[0]; + unicast_group = (struct bt_bap_unicast_group *)proc_param->stream->bap_stream.group; cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_QOS_CONFIG); for (size_t i = 0U; i < ARRAY_SIZE(conns); i++) { @@ -985,6 +1039,11 @@ void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream) void bt_cap_initiator_qos_configured(struct bt_cap_stream *cap_stream) { + struct cap_unicast_proc_param *proc_param; + struct bt_cap_stream *next_cap_stream; + struct bt_bap_stream *bap_stream; + int err; + if (!cap_stream_in_active_proc(cap_stream)) { /* State change happened outside of a procedure; ignore */ return; @@ -996,14 +1055,8 @@ void bt_cap_initiator_qos_configured(struct bt_cap_stream *cap_stream) } else { active_proc.stream_done_cnt++; - LOG_DBG("Stream %p QoS configured (%zu/%zu streams done)", - cap_stream, active_proc.stream_done_cnt, - active_proc.stream_cnt); - - if (!cap_proc_is_done()) { - /* Not yet finished, wait for all */ - return; - } + LOG_DBG("Stream %p QoS configured (%zu/%zu streams done)", cap_stream, + active_proc.stream_done_cnt, active_proc.stream_cnt); } if (cap_proc_is_aborted()) { @@ -1014,36 +1067,35 @@ void bt_cap_initiator_qos_configured(struct bt_cap_stream *cap_stream) return; } - cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_ENABLE); - - for (size_t i = 0U; i < active_proc.stream_cnt; i++) { - struct bt_cap_stream *cap_stream_active = active_proc.streams[i]; - struct bt_bap_stream *bap_stream = &cap_stream_active->bap_stream; - int err; + if (!cap_proc_is_done()) { + /* Not yet finished, wait for all */ + return; + } - /* TODO: Add metadata */ - err = bt_bap_stream_enable(bap_stream, bap_stream->codec_cfg->meta, - bap_stream->codec_cfg->meta_len); - if (err != 0) { - LOG_DBG("Failed to enable stream %p: %d", - cap_stream_active, err); + cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_ENABLE); + proc_param = &active_proc.proc_param[0]; + next_cap_stream = proc_param->stream; + bap_stream = &next_cap_stream->bap_stream; - /* End or mark procedure as aborted. - * If we have sent any requests over air, we will abort - * once all sent requests has completed - */ - cap_abort_proc(bap_stream->conn, err); - if (i == 0U) { - cap_initiator_unicast_audio_proc_complete(); - } + /* Since BAP operations may require a write long or a read long on the notification, we + * cannot assume that we can do multiple streams at once, thus do it one at a time. + * TODO: We should always be able to do one per ACL, so there is room for optimization. + */ + err = bt_bap_stream_enable(bap_stream, bap_stream->codec_cfg->meta, + bap_stream->codec_cfg->meta_len); + if (err != 0) { + LOG_DBG("Failed to enable stream %p: %d", next_cap_stream, err); - return; - } + cap_abort_proc(bap_stream->conn, err); + cap_initiator_unicast_audio_proc_complete(); + } else { + active_proc.stream_initiated_cnt++; } } void bt_cap_initiator_enabled(struct bt_cap_stream *cap_stream) { + struct cap_unicast_proc_param *proc_param; struct bt_bap_stream *bap_stream; int err; @@ -1058,14 +1110,8 @@ void bt_cap_initiator_enabled(struct bt_cap_stream *cap_stream) } else { active_proc.stream_done_cnt++; - LOG_DBG("Stream %p enabled (%zu/%zu streams done)", - cap_stream, active_proc.stream_done_cnt, - active_proc.stream_cnt); - - if (!cap_proc_is_done()) { - /* Not yet finished, wait for all */ - return; - } + LOG_DBG("Stream %p enabled (%zu/%zu streams done)", cap_stream, + active_proc.stream_done_cnt, active_proc.stream_cnt); } if (cap_proc_is_aborted()) { @@ -1076,17 +1122,42 @@ void bt_cap_initiator_enabled(struct bt_cap_stream *cap_stream) return; } - cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_START); + if (!cap_proc_is_done()) { + struct bt_cap_stream *next_cap_stream = + active_proc.proc_param[active_proc.stream_done_cnt].stream; + struct bt_bap_stream *next_bap_stream = &next_cap_stream->bap_stream; + + /* Since BAP operations may require a write long or a read long on the notification, + * we cannot assume that we can do multiple streams at once, thus do it one at a + * time. + * TODO: We should always be able to do one per ACL, so there is room for + * optimization. + */ + err = bt_bap_stream_enable(next_bap_stream, next_bap_stream->codec_cfg->meta, + next_bap_stream->codec_cfg->meta_len); + if (err != 0) { + LOG_DBG("Failed to enable stream %p: %d", next_cap_stream, err); - bap_stream = &active_proc.streams[0]->bap_stream; + cap_abort_proc(next_bap_stream->conn, err); + cap_initiator_unicast_audio_proc_complete(); + } else { + active_proc.stream_initiated_cnt++; + } - /* Since bt_bap_stream_start connects the ISO, we can, at this point, - * only do this one by one due to a restriction in the ISO layer - * (maximum 1 outstanding ISO connection request at any one time). + return; + } + + cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_START); + proc_param = &active_proc.proc_param[0]; + bap_stream = &proc_param->stream->bap_stream; + + /* Since BAP operations may require a write long or a read long on the notification, we + * cannot assume that we can do multiple streams at once, thus do it one at a time. + * TODO: We should always be able to do one per ACL, so there is room for optimization. */ err = bt_bap_stream_start(bap_stream); if (err != 0) { - LOG_DBG("Failed to start stream %p: %d", active_proc.streams[0], err); + LOG_DBG("Failed to start stream %p: %d", proc_param->stream, err); /* End and mark procedure as aborted. * If we have sent any requests over air, we will abort @@ -1122,14 +1193,15 @@ void bt_cap_initiator_started(struct bt_cap_stream *cap_stream) * (maximum 1 outstanding ISO connection request at any one time). */ if (!cap_proc_is_done()) { - struct bt_cap_stream *next = active_proc.streams[active_proc.stream_done_cnt]; - struct bt_bap_stream *bap_stream = &next->bap_stream; + struct bt_cap_stream *next_cap_stream = + active_proc.proc_param[active_proc.stream_done_cnt].stream; + struct bt_bap_stream *bap_stream = &next_cap_stream->bap_stream; int err; /* Not yet finished, start next */ err = bt_bap_stream_start(bap_stream); if (err != 0) { - LOG_DBG("Failed to start stream %p: %d", next, err); + LOG_DBG("Failed to start stream %p: %d", next_cap_stream, err); /* End and mark procedure as aborted. * If we have sent any requests over air, we will abort @@ -1166,6 +1238,12 @@ static bool can_update_metadata(const struct bt_bap_stream *bap_stream) int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param params[], size_t count) { + struct cap_unicast_proc_param *proc_param; + struct bt_bap_stream *bap_stream; + const uint8_t *meta; + size_t meta_len; + int err; + CHECKIF(params == NULL) { LOG_DBG("params is NULL"); @@ -1185,13 +1263,15 @@ int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_upda } for (size_t i = 0U; i < count; i++) { - CHECKIF(params[i].stream == NULL) { + struct bt_cap_stream *cap_stream = params[i].stream; + + CHECKIF(cap_stream == NULL) { LOG_DBG("params[%zu].stream is NULL", i); return -EINVAL; } - CHECKIF(params[i].stream->bap_stream.conn == NULL) { + CHECKIF(cap_stream->bap_stream.conn == NULL) { LOG_DBG("params[%zu].stream->bap_stream.conn is NULL", i); return -EINVAL; @@ -1205,56 +1285,46 @@ int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_upda } for (size_t j = 0U; j < i; j++) { - if (params[j].stream == params[i].stream) { + if (params[j].stream == cap_stream) { LOG_DBG("param.streams[%zu] is duplicated by param.streams[%zu]", j, i); return -EINVAL; } } - if (!can_update_metadata(¶ms[i].stream->bap_stream)) { + if (!can_update_metadata(&cap_stream->bap_stream)) { LOG_DBG("params[%zu].stream is not in right state to be updated", i); return -EINVAL; } + + active_proc.proc_param[i].stream = cap_stream; + active_proc.proc_param[i].meta_update.meta_len = params[i].meta_len; + memcpy(&active_proc.proc_param[i].meta_update.meta, params[i].meta, + params[i].meta_len); } - atomic_set_bit(active_proc.proc_state_flags, - CAP_UNICAST_PROC_STATE_ACTIVE); + atomic_set_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ACTIVE); active_proc.stream_cnt = count; - active_proc.proc_type = CAP_UNICAST_PROC_TYPE_UPDATE; + active_proc.proc_type = CAP_UNICAST_PROC_TYPE_UPDATE; cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_META_UPDATE); - /** TODO: If this is a CSIP set, then the order of the procedures may - * not match the order in the parameters, and the CSIP ordered access - * procedure should be used. - */ - for (size_t i = 0U; i < count; i++) { - int err; - - active_proc.streams[i] = params[i].stream; + proc_param = &active_proc.proc_param[0]; + bap_stream = &proc_param->stream->bap_stream; + meta_len = proc_param->meta_update.meta_len; + meta = proc_param->meta_update.meta; - err = bt_bap_stream_metadata(¶ms[i].stream->bap_stream, params[i].meta, - params[i].meta_len); - if (err != 0) { - LOG_DBG("Failed to update metadata for stream %p: %d", - params[i].stream, err); - - if (i > 0U) { - cap_abort_proc(params[i].stream->bap_stream.conn, err); - } else { - (void)memset(&active_proc, 0, - sizeof(active_proc)); - } - - return err; - } + err = bt_bap_stream_metadata(bap_stream, meta, meta_len); + if (err != 0) { + LOG_DBG("Failed to update metadata for stream %p: %d", proc_param->stream, err); + (void)memset(&active_proc, 0, sizeof(active_proc)); + } else { active_proc.stream_initiated_cnt++; } - return 0; + return err; } int bt_cap_initiator_unicast_audio_cancel(void) @@ -1289,10 +1359,7 @@ void bt_cap_initiator_metadata_updated(struct bt_cap_stream *cap_stream) active_proc.stream_cnt); } - if (!cap_proc_is_done()) { - /* Not yet finished, wait for all */ - return; - } else if (cap_proc_is_aborted()) { + if (cap_proc_is_aborted()) { if (cap_proc_all_streams_handled()) { cap_initiator_unicast_audio_proc_complete(); } @@ -1300,6 +1367,37 @@ void bt_cap_initiator_metadata_updated(struct bt_cap_stream *cap_stream) return; } + if (!cap_proc_is_done()) { + const size_t meta_len = + active_proc.proc_param[active_proc.stream_done_cnt].meta_update.meta_len; + const uint8_t *meta = + active_proc.proc_param[active_proc.stream_done_cnt].meta_update.meta; + struct bt_cap_stream *next_cap_stream = + active_proc.proc_param[active_proc.stream_done_cnt].stream; + struct bt_bap_stream *bap_stream = &next_cap_stream->bap_stream; + int err; + + /* Since BAP operations may require a write long or a read long on the notification, + * we cannot assume that we can do multiple streams at once, thus do it one at a + * time. + * TODO: We should always be able to do one per ACL, so there is room for + * optimization. + */ + + err = bt_bap_stream_metadata(bap_stream, meta, meta_len); + if (err != 0) { + LOG_DBG("Failed to update metadata for stream %p: %d", next_cap_stream, + err); + + cap_abort_proc(bap_stream->conn, err); + cap_initiator_unicast_audio_proc_complete(); + } else { + active_proc.stream_initiated_cnt++; + } + + return; + } + cap_initiator_unicast_audio_proc_complete(); } @@ -1324,8 +1422,10 @@ static bool can_release(const struct bt_bap_stream *bap_stream) int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_group) { + struct cap_unicast_proc_param *proc_param; struct bt_bap_stream *bap_stream; size_t stream_cnt; + int err; if (cap_proc_is_active()) { LOG_DBG("A CAP procedure is already in progress"); @@ -1341,6 +1441,9 @@ int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_gro stream_cnt = 0U; SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, bap_stream, _node) { if (can_release(bap_stream)) { + struct bt_cap_stream *cap_stream = + CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream); + active_proc.proc_param[stream_cnt].stream = cap_stream; stream_cnt++; } } @@ -1363,35 +1466,19 @@ int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_gro * not match the order in the parameters, and the CSIP ordered access * procedure should be used. */ - SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, bap_stream, _node) { - struct bt_cap_stream *cap_stream = - CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream); - int err; + proc_param = &active_proc.proc_param[0]; + bap_stream = &proc_param->stream->bap_stream; - if (!can_release(bap_stream)) { - continue; - } - - active_proc.streams[active_proc.stream_initiated_cnt] = cap_stream; - - err = bt_bap_stream_release(bap_stream); - if (err != 0) { - LOG_DBG("Failed to stop bap_stream %p: %d", bap_stream, err); - - if (active_proc.stream_initiated_cnt > 0U) { - cap_abort_proc(bap_stream->conn, err); - } else { - (void)memset(&active_proc, 0, - sizeof(active_proc)); - } - - return err; - } + err = bt_bap_stream_release(bap_stream); + if (err != 0) { + LOG_DBG("Failed to stop bap_stream %p: %d", proc_param->stream, err); + (void)memset(&active_proc, 0, sizeof(active_proc)); + } else { active_proc.stream_initiated_cnt++; } - return 0; + return err; } void bt_cap_initiator_released(struct bt_cap_stream *cap_stream) @@ -1412,10 +1499,7 @@ void bt_cap_initiator_released(struct bt_cap_stream *cap_stream) active_proc.stream_cnt); } - if (!cap_proc_is_done()) { - /* Not yet finished, wait for all */ - return; - } else if (cap_proc_is_aborted()) { + if (cap_proc_is_aborted()) { if (cap_proc_all_streams_handled()) { cap_initiator_unicast_audio_proc_complete(); } @@ -1423,7 +1507,30 @@ void bt_cap_initiator_released(struct bt_cap_stream *cap_stream) return; } - cap_initiator_unicast_audio_proc_complete(); + if (!cap_proc_is_done()) { + struct bt_cap_stream *next_cap_stream = + active_proc.proc_param[active_proc.stream_done_cnt].stream; + struct bt_bap_stream *bap_stream = &next_cap_stream->bap_stream; + int err; + + /* Since BAP operations may require a write long or a read long on the notification, + * we cannot assume that we can do multiple streams at once, thus do it one at a + * time. + * TODO: We should always be able to do one per ACL, so there is room for + * optimization. + */ + err = bt_bap_stream_release(bap_stream); + if (err != 0) { + LOG_DBG("Failed to release stream %p: %d", next_cap_stream, err); + + cap_abort_proc(bap_stream->conn, err); + cap_initiator_unicast_audio_proc_complete(); + } else { + active_proc.stream_initiated_cnt++; + } + } else { + cap_initiator_unicast_audio_proc_complete(); + } } #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */ diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c index 0f40413d712..97c8d876b47 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c @@ -717,15 +717,23 @@ static void unicast_audio_update_inval(void) static void unicast_audio_update(void) { struct bt_cap_unicast_audio_update_param param[2]; + uint8_t new_meta[] = { + 3, + BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED), + LONG_META_LEN, + BT_AUDIO_METADATA_TYPE_VENDOR, + LONG_META, + }; int err; param[0].stream = &unicast_client_sink_streams[0]; - param[0].meta = unicast_preset_16_2_1.codec_cfg.meta; - param[0].meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; + param[0].meta = new_meta; + param[0].meta_len = ARRAY_SIZE(new_meta); param[1].stream = &unicast_client_source_streams[0]; - param[1].meta = unicast_preset_16_2_1.codec_cfg.meta; - param[1].meta_len = unicast_preset_16_2_1.codec_cfg.meta_len; + param[1].meta = new_meta; + param[1].meta_len = ARRAY_SIZE(new_meta); UNSET_FLAG(flag_updated); @@ -736,6 +744,7 @@ static void unicast_audio_update(void) } WAIT_FOR_FLAG(flag_updated); + printk("READ LONG META\n"); } static void unicast_audio_stop_inval(void) From 5212a4c61960026ba297ff7df05c7d0ce7c5ef99 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Sep 2023 18:10:13 +0000 Subject: [PATCH 0759/4498] scripts: check_init_priorities: use the Zephyr executable file Rework check_init_priorities to use the main executable file instead of the individual object files for discovering the devices. This should make the script more robust in case of stale files in the build directory, and also makes it work with LTO object files. Additionally, keep track of the detected init calls, and add a handy "-i" option to produce a human readable print of the initcalls in the call sequence, which can be useful for debugging initialization problems due to odd SYS_INIT and DEVICE interactions. Signed-off-by: Fabio Baltieri --- CMakeLists.txt | 3 +- Kconfig.zephyr | 1 + scripts/build/check_init_priorities.py | 257 ++++++++------ scripts/build/check_init_priorities_test.py | 335 ++++++++++-------- .../misc/check_init_priorities/CMakeLists.txt | 13 +- .../validate_check_init_priorities_output.py | 14 +- 6 files changed, 353 insertions(+), 270 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d761a97d8b..ac9cf9ca0fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1811,8 +1811,7 @@ if(CONFIG_CHECK_INIT_PRIORITIES) list(APPEND post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py - --build-dir ${PROJECT_BINARY_DIR}/.. - --edt-pickle ${EDT_PICKLE} + --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${fail_on_warning} ) endif() diff --git a/Kconfig.zephyr b/Kconfig.zephyr index d01cc55eea7..3523bb50617 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -747,6 +747,7 @@ config BUILD_OUTPUT_STRIP_PATHS config CHECK_INIT_PRIORITIES bool "Build time initialization priorities check" default y + depends on !NATIVE_LIBRARY help Check the build for initialization priority issues by comparing the initialization priority in the build with the device dependency diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 8e743fa5323..582d7dd0e88 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -6,14 +6,16 @@ """ Checks the initialization priorities -This script parses the object files in the specified build directory, creates a -list of known devices and their effective initialization priorities and -compares that with the device dependencies inferred from the devicetree -hierarchy. +This script parses a Zephyr executable file, creates a list of known devices +and their effective initialization priorities and compares that with the device +dependencies inferred from the devicetree hierarchy. This can be used to detect devices that are initialized in the incorrect order, but also devices that are initialized at the same priority but depends on each other, which can potentially break if the linking order is changed. + +Optionally, it can also produce a human readable list of the initialization +calls for the various init levels. """ import argparse @@ -24,7 +26,6 @@ import sys from elftools.elf.elffile import ELFFile -from elftools.elf.relocation import RelocationSection from elftools.elf.sections import SymbolTableSection # This is needed to load edt.pickle files. @@ -32,24 +33,14 @@ "dts", "python-devicetree", "src")) from devicetree import edtlib # pylint: disable=unused-import -# Prefix used for relocation sections containing initialization data, as in -# sequence of "struct init_entry". -_INIT_SECTION_PREFIX = (".rel.z_init_", ".rela.z_init_") - # Prefix used for "struct device" reference initialized based on devicetree # entries with a known ordinal. _DEVICE_ORD_PREFIX = "__device_dts_ord_" -# File name suffix for object files to be scanned. -_OBJ_FILE_SUFFIX = ".c.obj" - # Defined init level in order of priority. _DEVICE_INIT_LEVELS = ["EARLY", "PRE_KERNEL_1", "PRE_KERNEL_2", "POST_KERNEL", "APPLICATION", "SMP"] -# File name to check for detecting and skiping nested build directories. -_BUILD_DIR_DETECT_FILE = "CMakeCache.txt" - # List of compatibles for node where the initialization priority should be the # opposite of the device tree inferred dependency. _INVERTED_PRIORITY_COMPATIBLES = frozenset() @@ -65,34 +56,28 @@ class Priority: """Parses and holds a device initialization priority. - Parses an ELF section name for the corresponding initialization level and - priority, for example ".rel.z_init_PRE_KERNEL_155_" for "PRE_KERNEL_1 55". - The object can be used for comparing levels with one another. Attributes: name: the section name """ - def __init__(self, name): - for idx, level in enumerate(_DEVICE_INIT_LEVELS): - if level in name: - _, priority_str = name.strip("_").split(level) - priority, sub_priority = priority_str.split("_") + def __init__(self, level, priority): + for idx, level_name in enumerate(_DEVICE_INIT_LEVELS): + if level_name == level: self._level = idx - self._priority = int(priority) - self._sub_priority = int(sub_priority) + self._priority = priority # Tuples compare elementwise in order - self._level_priority = (self._level, self._priority, self._sub_priority) + self._level_priority = (self._level, self._priority) return - raise ValueError("Unknown level in %s" % name) + raise ValueError("Unknown level in %s" % level) def __repr__(self): - return "<%s %s %d %d>" % (self.__class__.__name__, - _DEVICE_INIT_LEVELS[self._level], self._priority, self._sub_priority) + return "<%s %s %d>" % (self.__class__.__name__, + _DEVICE_INIT_LEVELS[self._level], self._priority) def __str__(self): - return "%s %d %d" % (_DEVICE_INIT_LEVELS[self._level], self._priority, self._sub_priority) + return "%s %d" % (_DEVICE_INIT_LEVELS[self._level], self._priority) def __lt__(self, other): return self._level_priority < other._level_priority @@ -104,15 +89,15 @@ def __hash__(self): return self._level_priority -class ZephyrObjectFile: - """Load an object file and finds the device defined within it. +class ZephyrInitLevels: + """Load an executable file and find the initialization calls and devices. - Load an object file and scans the relocation sections looking for the known - ones containing initialization callbacks. Then finds what device ordinals - are being initialized at which priority and stores the list internally. + Load a Zephyr executable file and scan for the list of initialization calls + and defined devices. - A dictionary of {ordinal: Priority} is available in the defined_devices - class variable. + The list of devices is available in the "devices" class variable in the + {ordinal: Priority} format, the list of initilevels is in the "initlevels" + class variables in the {"level name": ["call", ...]} format. Attributes: file_path: path of the file to be loaded. @@ -120,26 +105,49 @@ class variable. def __init__(self, file_path): self.file_path = file_path self._elf = ELFFile(open(file_path, "rb")) - self._load_symbols() - self._find_defined_devices() + self._load_objects() + self._load_level_addr() + self._process_initlevels() - def _load_symbols(self): - """Initialize the symbols table.""" - self._symbols = {} + def _load_objects(self): + """Initialize the object table.""" + self._objects = {} for section in self._elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue - for num, sym in enumerate(section.iter_symbols()): - if sym.name: - self._symbols[num] = sym.name + for sym in section.iter_symbols(): + if (sym.name and + sym.entry.st_size > 0 and + sym.entry.st_info.type in ["STT_OBJECT", "STT_FUNC"]): + self._objects[sym.entry.st_value] = ( + sym.name, sym.entry.st_size, sym.entry.st_shndx) - def _device_ord_from_rel(self, rel): - """Find a device ordinal from a device symbol name.""" - sym_id = rel["r_info_sym"] - sym_name = self._symbols.get(sym_id, None) + def _load_level_addr(self): + """Find the address associated with known init levels.""" + self._init_level_addr = {} + for section in self._elf.iter_sections(): + if not isinstance(section, SymbolTableSection): + continue + + for sym in section.iter_symbols(): + for level in _DEVICE_INIT_LEVELS: + name = f"__init_{level}_start" + if sym.name == name: + self._init_level_addr[level] = sym.entry.st_value + elif sym.name == "__init_end": + self._init_level_end = sym.entry.st_value + + if len(self._init_level_addr) != len(_DEVICE_INIT_LEVELS): + raise ValueError(f"Missing init symbols, found: {self._init_level_addr}") + + if not self._init_level_end: + raise ValueError(f"Missing init section end symbol") + + def _device_ord_from_name(self, sym_name): + """Find a device ordinal from a symbol name.""" if not sym_name: return None @@ -149,35 +157,67 @@ def _device_ord_from_rel(self, rel): _, device_ord = sym_name.split(_DEVICE_ORD_PREFIX) return int(device_ord) - def _find_defined_devices(self): - """Find the device structures defined in the object file.""" - self.defined_devices = {} + def _object_name(self, addr): + if not addr: + return "NULL" + elif addr in self._objects: + return self._objects[addr][0] + else: + return "unknown" + + def _initlevel_pointer(self, addr, idx, shidx): + elfclass = self._elf.elfclass + if elfclass == 32: + ptrsize = 4 + elif elfclass == 64: + ptrsize = 8 + else: + ValueError(f"Unknown pointer size for ELF class f{elfclass}") - for section in self._elf.iter_sections(): - if not isinstance(section, RelocationSection): - continue + section = self._elf.get_section(shidx) + start = section.header.sh_addr + data = section.data() - if not section.name.startswith(_INIT_SECTION_PREFIX): - continue + offset = addr - start - prio = Priority(section.name) + start = offset + ptrsize * idx + stop = offset + ptrsize * (idx + 1) - for rel in section.iter_relocations(): - device_ord = self._device_ord_from_rel(rel) - if not device_ord: - continue + return int.from_bytes(data[start:stop], byteorder="little") - if device_ord in self.defined_devices: - raise ValueError( - f"Device {device_ord} already defined, stale " - "object files in the build directory? " - "Try running a clean build.") + def _process_initlevels(self): + """Process the init level and find the init functions and devices.""" + self.devices = {} + self.initlevels = {} - self.defined_devices[device_ord] = prio + for i, level in enumerate(_DEVICE_INIT_LEVELS): + start = self._init_level_addr[level] + if i + 1 == len(_DEVICE_INIT_LEVELS): + stop = self._init_level_end + else: + stop = self._init_level_addr[_DEVICE_INIT_LEVELS[i + 1]] - def __repr__(self): - return (f"<{self.__class__.__name__} {self.file_path} " - f"defined_devices: {self.defined_devices}>") + self.initlevels[level] = [] + + priority = 0 + addr = start + while addr < stop: + if addr not in self._objects: + raise ValueError(f"no symbol at addr {addr:08x}") + obj, size, shidx = self._objects[addr] + + arg0_name = self._object_name(self._initlevel_pointer(addr, 0, shidx)) + arg1_name = self._object_name(self._initlevel_pointer(addr, 1, shidx)) + + self.initlevels[level].append(f"{obj}: {arg0_name}({arg1_name})") + + ordinal = self._device_ord_from_name(arg1_name) + if ordinal: + prio = Priority(level, priority) + self.devices[ordinal] = prio + + addr += size + priority += 1 class Validator(): """Validates the initialization priorities. @@ -187,52 +227,26 @@ class Validator(): dependency list and log any found priority issue. Attributes: - build_dir: the build directory to scan - edt_pickle_path: path of the EDT pickle file + elf_file_path: path of the ELF file + edt_pickle: name of the EDT pickle file log: a logging.Logger object """ - def __init__(self, build_dir, edt_pickle_path, log): + def __init__(self, elf_file_path, edt_pickle, log): self.log = log - edtser = pathlib.Path(build_dir, edt_pickle_path) - with open(edtser, "rb") as f: + edt_pickle_path = pathlib.Path( + pathlib.Path(elf_file_path).parent, + edt_pickle) + with open(edt_pickle_path, "rb") as f: edt = pickle.load(f) self._ord2node = edt.dep_ord2node - self._objs = [] - for file in self._find_build_objfiles(build_dir, is_root=True): - obj = ZephyrObjectFile(file) - if obj.defined_devices: - self._objs.append(obj) - for dev, prio in obj.defined_devices.items(): - dev_path = self._ord2node[dev].path - self.log.debug(f"{file}: {dev_path} {prio}") - - self._dev_priorities = {} - for obj in self._objs: - for dev, prio in obj.defined_devices.items(): - if dev in self._dev_priorities: - dev_path = self._ord2node[dev].path - raise ValueError( - f"ERROR: device {dev} ({dev_path}) already defined") - self._dev_priorities[dev] = prio + self._obj = ZephyrInitLevels(elf_file_path) self.warnings = 0 self.errors = 0 - def _find_build_objfiles(self, build_dir, is_root=False): - """Find all project object files, skip sub-build directories.""" - if not is_root and pathlib.Path(build_dir, _BUILD_DIR_DETECT_FILE).exists(): - return - - for file in pathlib.Path(build_dir).iterdir(): - if file.is_file() and file.name.endswith(_OBJ_FILE_SUFFIX): - yield file - if file.is_dir(): - for file in self._find_build_objfiles(file.resolve()): - yield file - def _check_dep(self, dev_ord, dep_ord): """Validate the priority between two devices.""" if dev_ord == dep_ord: @@ -254,8 +268,8 @@ def _check_dep(self, dev_ord, dep_ord): self.log.info(f"Swapped priority: {dev_compat}, {dep_compat}") dev_ord, dep_ord = dep_ord, dev_ord - dev_prio = self._dev_priorities.get(dev_ord, None) - dep_prio = self._dev_priorities.get(dep_ord, None) + dev_prio = self._obj.devices.get(dev_ord, None) + dep_prio = self._obj.devices.get(dep_ord, None) if not dev_prio or not dep_prio: return @@ -286,10 +300,16 @@ def _check_edt_r(self, dev_ord, dev): def check_edt(self): """Scan through all known devices and validate the init priorities.""" - for dev_ord in self._dev_priorities: + for dev_ord in self._obj.devices: dev = self._ord2node[dev_ord] self._check_edt_r(dev_ord, dev) + def print_initlevels(self): + for level, calls in self._obj.initlevels.items(): + print(level) + for call in calls: + print(f" {call}") + def _parse_args(argv): """Parse the command line arguments.""" parser = argparse.ArgumentParser( @@ -297,8 +317,8 @@ def _parse_args(argv): formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) - parser.add_argument("-d", "--build-dir", default="build", - help="build directory to use") + parser.add_argument("-f", "--elf-file", default=pathlib.Path("build", "zephyr", "zephyr.elf"), + help="ELF file to use") parser.add_argument("-v", "--verbose", action="count", help=("enable verbose output, can be used multiple times " "to increase verbosity level")) @@ -308,8 +328,10 @@ def _parse_args(argv): help="always exit with a return code of 0, used for testing") parser.add_argument("-o", "--output", help="write the output to a file in addition to stdout") - parser.add_argument("--edt-pickle", default=pathlib.Path("zephyr", "edt.pickle"), - help="path to read the pickled edtlib.EDT object from", + parser.add_argument("-i", "--initlevels", action="store_true", + help="print the initlevel functions instead of checking the device dependencies") + parser.add_argument("--edt-pickle", default=pathlib.Path("edt.pickle"), + help="name of the the pickled edtlib.EDT file", type=pathlib.Path) return parser.parse_args(argv) @@ -323,7 +345,7 @@ def _init_log(verbose, output): log.addHandler(console) if output: - file = logging.FileHandler(output) + file = logging.FileHandler(output, mode="w") file.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) log.addHandler(file) @@ -341,10 +363,13 @@ def main(argv=None): log = _init_log(args.verbose, args.output) - log.info(f"check_init_priorities build_dir: {args.build_dir}") + log.info(f"check_init_priorities: {args.elf_file}") - validator = Validator(args.build_dir, args.edt_pickle, log) - validator.check_edt() + validator = Validator(args.elf_file, args.edt_pickle, log) + if args.initlevels: + validator.print_initlevels() + else: + validator.check_edt() if args.always_succeed: return 0 diff --git a/scripts/build/check_init_priorities_test.py b/scripts/build/check_init_priorities_test.py index 85185ebc258..6e404221194 100755 --- a/scripts/build/check_init_priorities_test.py +++ b/scripts/build/check_init_priorities_test.py @@ -10,7 +10,7 @@ import pathlib import unittest -from elftools.elf.relocation import RelocationSection +from elftools.elf.relocation import Section from elftools.elf.sections import SymbolTableSection import check_init_priorities @@ -19,191 +19,245 @@ class TestPriority(unittest.TestCase): """Tests for the Priority class.""" def test_priority_parsing(self): - prio1 = check_init_priorities.Priority(".rel.z_init_POST_KERNEL12_0_") - self.assertEqual(prio1._level_priority, (3, 12, 0)) + prio1 = check_init_priorities.Priority("POST_KERNEL", 12) + self.assertEqual(prio1._level_priority, (3, 12)) - prio2 = check_init_priorities.Priority("noisenoise_POST_KERNEL99_00023_") - self.assertEqual(prio2._level_priority, (3, 99, 23)) - - prio3 = check_init_priorities.Priority("_PRE_KERNEL_10_99999_") - self.assertEqual(prio3._level_priority, (1, 0, 99999)) - - prio4 = check_init_priorities.Priority("_PRE_KERNEL_110_00001_") - self.assertEqual(prio4._level_priority, (1, 10, 1)) + prio1 = check_init_priorities.Priority("APPLICATION", 9999) + self.assertEqual(prio1._level_priority, (4, 9999)) with self.assertRaises(ValueError): - check_init_priorities.Priority("i-am-not-a-priority") - check_init_priorities.Priority("_DOESNOTEXIST0_") - check_init_priorities.Priority(".rel.z_init_POST_KERNEL12_blah") - check_init_priorities.Priority(".rel.z_init_2_") - check_init_priorities.Priority(".rel.z_init_POST_KERNEL1_") + check_init_priorities.Priority("i-am-not-a-priority", 0) + check_init_priorities.Priority("_DOESNOTEXIST0_", 0) def test_priority_levels(self): prios = [ - check_init_priorities.Priority(".rel.z_init_EARLY0_0_"), - check_init_priorities.Priority(".rel.z_init_EARLY1_0_"), - check_init_priorities.Priority(".rel.z_init_EARLY11_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_10_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_11_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_111_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_111_1_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_111_00002_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_111_00010_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_20_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_21_0_"), - check_init_priorities.Priority(".rel.z_init_PRE_KERNEL_211_0_"), - check_init_priorities.Priority(".rel.z_init_POST_KERNEL0_0_"), - check_init_priorities.Priority(".rel.z_init_POST_KERNEL1_0_"), - check_init_priorities.Priority(".rel.z_init_POST_KERNEL11_0_"), - check_init_priorities.Priority(".rel.z_init_APPLICATION0_0_"), - check_init_priorities.Priority(".rel.z_init_APPLICATION1_0_"), - check_init_priorities.Priority(".rel.z_init_APPLICATION11_0_"), - check_init_priorities.Priority(".rel.z_init_SMP0_0_"), - check_init_priorities.Priority(".rel.z_init_SMP1_0_"), - check_init_priorities.Priority(".rel.z_init_SMP11_0_"), + check_init_priorities.Priority("EARLY", 0), + check_init_priorities.Priority("EARLY", 1), + check_init_priorities.Priority("PRE_KERNEL_1", 0), + check_init_priorities.Priority("PRE_KERNEL_1", 1), + check_init_priorities.Priority("PRE_KERNEL_2", 0), + check_init_priorities.Priority("PRE_KERNEL_2", 1), + check_init_priorities.Priority("POST_KERNEL", 0), + check_init_priorities.Priority("POST_KERNEL", 1), + check_init_priorities.Priority("APPLICATION", 0), + check_init_priorities.Priority("APPLICATION", 1), + check_init_priorities.Priority("SMP", 0), + check_init_priorities.Priority("SMP", 1), ] self.assertListEqual(prios, sorted(prios)) def test_priority_strings(self): - prio = check_init_priorities.Priority(".rel.z_init_POST_KERNEL12_00023_") - self.assertEqual(str(prio), "POST_KERNEL 12 23") - self.assertEqual(repr(prio), "") + prio = check_init_priorities.Priority("POST_KERNEL", 12) + self.assertEqual(str(prio), "POST_KERNEL 12") + self.assertEqual(repr(prio), "") -class testZephyrObjectFile(unittest.TestCase): - """Tests for the ZephyrObjectFile class.""" +class testZephyrInitLevels(unittest.TestCase): + """Tests for the ZephyrInitLevels class.""" - @mock.patch("check_init_priorities.ZephyrObjectFile.__init__", return_value=None) - def test_load_symbols(self, mock_zofinit): + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_load_objects(self, mock_zilinit): mock_elf = mock.Mock() sts = mock.Mock(spec=SymbolTableSection) - rel = mock.Mock(spec=RelocationSection) + rel = mock.Mock(spec=Section) mock_elf.iter_sections.return_value = [sts, rel] s0 = mock.Mock() s0.name = "a" + s0.entry.st_info.type = "STT_OBJECT" + s0.entry.st_size = 4 + s0.entry.st_value = 0xaa + s0.entry.st_shndx = 1 + s1 = mock.Mock() s1.name = None + s2 = mock.Mock() s2.name = "b" + s2.entry.st_info.type = "STT_FUNC" + s2.entry.st_size = 8 + s2.entry.st_value = 0xbb + s2.entry.st_shndx = 2 + sts.iter_symbols.return_value = [s0, s1, s2] - obj = check_init_priorities.ZephyrObjectFile("") + obj = check_init_priorities.ZephyrInitLevels("") obj._elf = mock_elf - obj._load_symbols() + obj._load_objects() - self.assertDictEqual(obj._symbols, {0: "a", 2: "b"}) + self.assertDictEqual(obj._objects, {0xaa: ("a", 4, 1), 0xbb: ("b", 8, 2)}) - @mock.patch("check_init_priorities.Priority") - @mock.patch("check_init_priorities.ZephyrObjectFile._device_ord_from_rel") - @mock.patch("check_init_priorities.ZephyrObjectFile.__init__", return_value=None) - def test_find_defined_devices(self, mock_zofinit, mock_dofr, mock_prio): + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_load_level_addr(self, mock_zilinit): mock_elf = mock.Mock() sts = mock.Mock(spec=SymbolTableSection) - rel1 = mock.Mock(spec=RelocationSection) - rel1.name = ".rel.z_init_SOMETHING" - rel2 = mock.Mock(spec=RelocationSection) - rel2.name = ".rel.something_else" - mock_elf.iter_sections.return_value = [sts, rel1, rel2] + rel = mock.Mock(spec=Section) + mock_elf.iter_sections.return_value = [sts, rel] - r0 = mock.Mock() - rel1.iter_relocations.return_value = [r0] + s0 = mock.Mock() + s0.name = "__init_EARLY_start" + s0.entry.st_value = 0x00 - mock_dofr.return_value = 123 + s1 = mock.Mock() + s1.name = "__init_PRE_KERNEL_1_start" + s1.entry.st_value = 0x11 - r0_prio = mock.Mock() - mock_prio.return_value = r0_prio + s2 = mock.Mock() + s2.name = "__init_PRE_KERNEL_2_start" + s2.entry.st_value = 0x22 - obj = check_init_priorities.ZephyrObjectFile("") - obj._elf = mock_elf - obj._find_defined_devices() + s3 = mock.Mock() + s3.name = "__init_POST_KERNEL_start" + s3.entry.st_value = 0x33 - self.assertDictEqual(obj.defined_devices, {123: r0_prio}) - mock_dofr.assert_called_once_with(r0) - mock_prio.assert_called_once_with(rel1.name) + s4 = mock.Mock() + s4.name = "__init_APPLICATION_start" + s4.entry.st_value = 0x44 - @mock.patch("check_init_priorities.ZephyrObjectFile.__init__", return_value=None) - def test_device_ord_from_rel(self, mock_zofinit): - obj = check_init_priorities.ZephyrObjectFile("") + s5 = mock.Mock() + s5.name = "__init_SMP_start" + s5.entry.st_value = 0x55 - obj._symbols = { - 1: "blah", - 2: "__device_dts_ord_123", + s6 = mock.Mock() + s6.name = "__init_end" + s6.entry.st_value = 0x66 + + sts.iter_symbols.return_value = [s0, s1, s2, s3, s4, s5, s6] + + obj = check_init_priorities.ZephyrInitLevels("") + obj._elf = mock_elf + obj._load_level_addr() + + self.assertDictEqual(obj._init_level_addr, { + "EARLY": 0x00, + "PRE_KERNEL_1": 0x11, + "PRE_KERNEL_2": 0x22, + "POST_KERNEL": 0x33, + "APPLICATION": 0x44, + "SMP": 0x55, + }) + self.assertEqual(obj._init_level_end, 0x66) + + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_device_ord_from_name(self, mock_zilinit): + obj = check_init_priorities.ZephyrInitLevels("") + + self.assertEqual(obj._device_ord_from_name(None), None) + self.assertEqual(obj._device_ord_from_name("hey, hi!"), None) + self.assertEqual(obj._device_ord_from_name("__device_dts_ord_123"), 123) + + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_object_name(self, mock_zilinit): + obj = check_init_priorities.ZephyrInitLevels("") + obj._objects = {0x123: ("name", 4)} + + self.assertEqual(obj._object_name(0), "NULL") + self.assertEqual(obj._object_name(73), "unknown") + self.assertEqual(obj._object_name(0x123), "name") + + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_initlevel_pointer_32(self, mock_zilinit): + obj = check_init_priorities.ZephyrInitLevels("") + obj._elf = mock.Mock() + obj._elf.elfclass = 32 + mock_section = mock.Mock() + obj._elf.get_section.return_value = mock_section + mock_section.header.sh_addr = 0x100 + mock_section.data.return_value = (b"\x01\x00\x00\x00" + b"\x02\x00\x00\x00" + b"\x03\x00\x00\x00") + + self.assertEqual(obj._initlevel_pointer(0x100, 0, 0), 1) + self.assertEqual(obj._initlevel_pointer(0x100, 1, 0), 2) + self.assertEqual(obj._initlevel_pointer(0x104, 0, 0), 2) + self.assertEqual(obj._initlevel_pointer(0x104, 1, 0), 3) + + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_initlevel_pointer_64(self, mock_zilinit): + obj = check_init_priorities.ZephyrInitLevels("") + obj._elf = mock.Mock() + obj._elf.elfclass = 64 + mock_section = mock.Mock() + obj._elf.get_section.return_value = mock_section + mock_section.header.sh_addr = 0x100 + mock_section.data.return_value = (b"\x01\x00\x00\x00\x00\x00\x00\x00" + b"\x02\x00\x00\x00\x00\x00\x00\x00" + b"\x03\x00\x00\x00\x00\x00\x00\x00") + + self.assertEqual(obj._initlevel_pointer(0x100, 0, 0), 1) + self.assertEqual(obj._initlevel_pointer(0x100, 1, 0), 2) + self.assertEqual(obj._initlevel_pointer(0x108, 0, 0), 2) + self.assertEqual(obj._initlevel_pointer(0x108, 1, 0), 3) + + @mock.patch("check_init_priorities.ZephyrInitLevels._object_name") + @mock.patch("check_init_priorities.ZephyrInitLevels._initlevel_pointer") + @mock.patch("check_init_priorities.ZephyrInitLevels.__init__", return_value=None) + def test_process_initlevels(self, mock_zilinit, mock_ip, mock_on): + obj = check_init_priorities.ZephyrInitLevels("") + obj._init_level_addr = { + "EARLY": 0x00, + "PRE_KERNEL_1": 0x00, + "PRE_KERNEL_2": 0x00, + "POST_KERNEL": 0x08, + "APPLICATION": 0x0c, + "SMP": 0x0c, + } + obj._init_level_end = 0x0c + obj._objects = { + 0x00: ("a", 4, 0), + 0x04: ("b", 4, 0), + 0x08: ("c", 4, 0), } - self.assertEqual(obj._device_ord_from_rel({"r_info_sym": 0}), None) - self.assertEqual(obj._device_ord_from_rel({"r_info_sym": 1}), None) - self.assertEqual(obj._device_ord_from_rel({"r_info_sym": 2}), 123) + mock_ip.side_effect = lambda *args: args + + def mock_obj_name(*args): + if args[0] == (0, 0, 0): + return "i0" + elif args[0] == (0, 1, 0): + return "__device_dts_ord_11" + elif args[0] == (4, 0, 0): + return "i1" + elif args[0] == (4, 1, 0): + return "__device_dts_ord_22" + return f"name_{args[0][0]}_{args[0][1]}" + mock_on.side_effect = mock_obj_name + + obj._process_initlevels() + + self.assertDictEqual(obj.initlevels, { + "EARLY": [], + "PRE_KERNEL_1": [], + "PRE_KERNEL_2": ["a: i0(__device_dts_ord_11)", "b: i1(__device_dts_ord_22)"], + "POST_KERNEL": ["c: name_8_0(name_8_1)"], + "APPLICATION": [], + "SMP": [], + }) + self.assertDictEqual(obj.devices, { + 11: check_init_priorities.Priority("PRE_KERNEL_2", 0), + 22: check_init_priorities.Priority("PRE_KERNEL_2", 1), + }) class testValidator(unittest.TestCase): """Tests for the Validator class.""" - @mock.patch("check_init_priorities.ZephyrObjectFile") - @mock.patch("check_init_priorities.Validator._find_build_objfiles") + @mock.patch("check_init_priorities.ZephyrInitLevels") @mock.patch("pickle.load") - def test_initialize(self, mock_pl, mock_fbo, mock_zof): - mock_fbo.return_value = ["filepath"] - + def test_initialize(self, mock_pl, mock_zil): mock_log = mock.Mock() mock_prio = mock.Mock() mock_obj = mock.Mock() mock_obj.defined_devices = {123: mock_prio} - mock_zof.return_value = mock_obj + mock_zil.return_value = mock_obj with mock.patch("builtins.open", mock.mock_open()) as mock_open: validator = check_init_priorities.Validator("path", "pickle", mock_log) - self.assertListEqual(validator._objs, [mock_obj]) - self.assertDictEqual(validator._dev_priorities, {123: mock_prio}) - mock_fbo.assert_called_once_with("path", is_root=True) - mock_zof.assert_called_once_with("filepath") - mock_open.assert_called_once_with(pathlib.Path("path/pickle"), "rb") - - @mock.patch("pathlib.Path") - @mock.patch("check_init_priorities.Validator.__init__", return_value=None) - def test_find_build_objfiles(self, mock_vinit, mock_path): - mock_log = mock.Mock() - - validator = check_init_priorities.Validator("", "", mock_log) - - mock_file = mock.Mock() - mock_file.is_file.return_value = True - mock_file.is_dir.return_value = False - mock_file.file.name = "filename.c.obj" - - mock_dir = mock.Mock() - mock_dir.is_file.return_value = False - mock_dir.is_dir.return_value = True - mock_dir.resolve.return_value = "subdir" - mock_dir.iterdir.return_value = [] - - mock_nosettingsfile = mock.Mock() - mock_nosettingsfile.exists.return_value = False - - mock_path_root = mock.Mock() - mock_path_root.iterdir.return_value = [mock_file, mock_dir] - - def mock_path_stubs(*args): - if args == ("root",): - return mock_path_root - elif args == ("subdir",): - return mock_dir - elif args == ("subdir", "CMakeCache.txt"): - return mock_nosettingsfile - raise ValueError - mock_path.side_effect = mock_path_stubs - - ret = list(validator._find_build_objfiles("root", is_root=True)) - self.assertListEqual(ret, [mock_file]) - - mock_nosettingsfile.exists.assert_called_once_with() - self.assertListEqual(mock_path.call_args_list, [ - mock.call("root"), - mock.call("subdir", "CMakeCache.txt"), - mock.call("subdir") - ]) + self.assertEqual(validator._obj, mock_obj) + mock_zil.assert_called_once_with("path") + mock_open.assert_called_once_with(pathlib.Path("pickle"), "rb") @mock.patch("check_init_priorities.Validator.__init__", return_value=None) def test_check_dep_same_node(self, mock_vinit): @@ -220,15 +274,16 @@ def test_check_dep_same_node(self, mock_vinit): def test_check_dep_no_prio(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() + validator._obj = mock.Mock() validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} validator._ord2node[1]._binding = None validator._ord2node[2]._binding = None - validator._dev_priorities = {1: 10} + validator._obj.devices = {1: 10} validator._check_dep(1, 2) - validator._dev_priorities = {2: 20} + validator._obj.devices = {2: 20} validator._check_dep(1, 2) self.assertFalse(validator.log.info.called) @@ -239,6 +294,7 @@ def test_check_dep_no_prio(self, mock_vinit): def test_check(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() + validator._obj = mock.Mock() validator.warnings = 0 validator.errors = 0 @@ -250,7 +306,7 @@ def test_check(self, mock_vinit): validator._ord2node[3]._binding = None validator._ord2node[3].path = "/3" - validator._dev_priorities = {1: 10, 2: 10, 3: 20} + validator._obj.devices = {1: 10, 2: 10, 3: 20} validator._check_dep(3, 1) validator._check_dep(2, 1) @@ -266,6 +322,7 @@ def test_check(self, mock_vinit): def test_check_swapped(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() + validator._obj = mock.Mock() validator.warnings = 0 validator.errors = 0 @@ -279,7 +336,7 @@ def test_check_swapped(self, mock_vinit): validator._ord2node[3]._binding.compatible = "compat-3" validator._ord2node[3].path = "/3" - validator._dev_priorities = {1: 20, 3: 10} + validator._obj.devices = {1: 20, 3: 10} validator._check_dep(3, 1) @@ -296,6 +353,7 @@ def test_check_swapped(self, mock_vinit): def test_check_ignored(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() + validator._obj = mock.Mock() validator.warnings = 0 validator.errors = 0 @@ -309,7 +367,7 @@ def test_check_ignored(self, mock_vinit): validator._ord2node[3]._binding.compatible = "compat-3" validator._ord2node[3].path = "/3" - validator._dev_priorities = {1: 20, 3: 10} + validator._obj.devices = {1: 20, 3: 10} validator._check_dep(3, 1) @@ -360,7 +418,8 @@ def test_check_edt_r(self, mock_vinit, mock_cd): def test_check_edt(self, mock_vinit, mock_cer): validator = check_init_priorities.Validator("", "", None) validator._ord2node = {1: mock.Mock(), 2: mock.Mock(), 3: mock.Mock()} - validator._dev_priorities = {1: 10, 2: 10, 3: 20} + validator._obj = mock.Mock() + validator._obj.devices = {1: 10, 2: 10, 3: 20} validator.check_edt() diff --git a/tests/misc/check_init_priorities/CMakeLists.txt b/tests/misc/check_init_priorities/CMakeLists.txt index c5e9fec4071..8803b2fa651 100644 --- a/tests/misc/check_init_priorities/CMakeLists.txt +++ b/tests/misc/check_init_priorities/CMakeLists.txt @@ -5,21 +5,20 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) set(output_file ${PROJECT_BINARY_DIR}/check_init_priorities_output.txt) -add_custom_target( - check_init_priorities_output +add_custom_command( COMMENT "Running check_init_priorities.py" + OUTPUT ${output_file} + DEPENDS ${BYPRODUCT_KERNEL_ELF_NAME} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py --verbose - --build-dir ${PROJECT_BINARY_DIR}/.. + --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} --output ${output_file} --always-succeed COMMAND ${PYTHON_EXECUTABLE} ${APPLICATION_SOURCE_DIR}/validate_check_init_priorities_output.py ${output_file} - DEPENDS zephyr_pre0 ) -if (TARGET zephyr_pre1) - add_dependencies(zephyr_pre1 check_init_priorities_output) -endif() + +add_custom_target(check_init_priorities_output ALL DEPENDS ${output_file}) project(check_init_priorities) diff --git a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py index 96d98954469..84d5335372f 100755 --- a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py +++ b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py @@ -8,12 +8,12 @@ import sys REFERENCE_OUTPUT = [ - "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 49 31 < /gpio@ffff PRE_KERNEL_1 50 29", - "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 49 31 < /i2c@11112222 PRE_KERNEL_1 50 30", - "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 50 32 > /gpio@ffff PRE_KERNEL_1 50 29", - "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 50 32 > /i2c@11112222 PRE_KERNEL_1 50 30", - "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 51 33 > /gpio@ffff PRE_KERNEL_1 50 29", - "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 51 33 > /i2c@11112222 PRE_KERNEL_1 50 30" + "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /gpio@ffff PRE_KERNEL_1 1", + "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /i2c@11112222 PRE_KERNEL_1 2", + "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /gpio@ffff PRE_KERNEL_1 1", + "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /i2c@11112222 PRE_KERNEL_1 2", + "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 4 > /gpio@ffff PRE_KERNEL_1 1", + "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 4 > /i2c@11112222 PRE_KERNEL_1 2", ] if len(sys.argv) != 2: @@ -23,7 +23,7 @@ output = [] with open(sys.argv[1], "r") as file: for line in file: - if line.startswith("INFO: check_init_priorities build_dir:"): + if line.startswith("INFO: check_init_priorities"): continue output.append(line.strip()) From 79ed6da8fd175b4cbbb53bc169c67ab19c4414be Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 11 Sep 2023 15:09:14 +0000 Subject: [PATCH 0760/4498] cmake: add a new "initlevels" target to print the init sequence Add a new "initlevels" target that can be used to print a human readable version of the init sequence by running: west build -t initlevels. Signed-off-by: Fabio Baltieri --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac9cf9ca0fd..d0b25d16c8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1816,6 +1816,15 @@ if(CONFIG_CHECK_INIT_PRIORITIES) ) endif() +add_custom_target( + initlevels + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py + --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} + --initlevels + DEPENDS ${logical_target_for_zephyr_elf} + USES_TERMINAL +) + # Generate and use MCUboot related artifacts as needed. if(CONFIG_BOOTLOADER_MCUBOOT) get_target_property(signing_script zephyr_property_target SIGNING_SCRIPT) From 4a556a925c79fa2518315546fd38a7210e1e8d77 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 18 Sep 2023 11:35:35 +0000 Subject: [PATCH 0761/4498] cmake: skip build time priority checking with armclang The script does not play well with armclang binariest at the moment. Disable the automatic invocation when running with armclang, at least until this is investigated and fixed. Signed-off-by: Fabio Baltieri --- CMakeLists.txt | 18 ++++++++++-------- Kconfig.zephyr | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0b25d16c8c..6d5c643f3e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1816,14 +1816,16 @@ if(CONFIG_CHECK_INIT_PRIORITIES) ) endif() -add_custom_target( - initlevels - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py - --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} - --initlevels - DEPENDS ${logical_target_for_zephyr_elf} - USES_TERMINAL -) +if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") + add_custom_target( + initlevels + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py + --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} + --initlevels + DEPENDS ${logical_target_for_zephyr_elf} + USES_TERMINAL + ) +endif() # Generate and use MCUboot related artifacts as needed. if(CONFIG_BOOTLOADER_MCUBOOT) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 3523bb50617..4b6976a503f 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -748,6 +748,7 @@ config CHECK_INIT_PRIORITIES bool "Build time initialization priorities check" default y depends on !NATIVE_LIBRARY + depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "armclang" help Check the build for initialization priority issues by comparing the initialization priority in the build with the device dependency From b1d2a8a9b6f4c793daa7e3282f8a0ebcb491add2 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 28 Mar 2023 15:34:12 -0500 Subject: [PATCH 0762/4498] drivers: regulator: Add NXP VREF driver Add binding, include header, and driver for NXP VREF IP block. NXP VREF is an internal voltage reference generator on some SOCs that fits well with the regulator API in zephyr. Signed-off-by: Declan Snyder --- drivers/regulator/CMakeLists.txt | 1 + drivers/regulator/Kconfig | 1 + drivers/regulator/Kconfig.nxp_vref | 14 ++ drivers/regulator/regulator_nxp_vref.c | 221 ++++++++++++++++++ dts/bindings/regulator/nxp,vref.yaml | 41 ++++ .../zephyr/dt-bindings/regulator/nxp_vref.h | 29 +++ 6 files changed, 307 insertions(+) create mode 100644 drivers/regulator/Kconfig.nxp_vref create mode 100644 drivers/regulator/regulator_nxp_vref.c create mode 100644 dts/bindings/regulator/nxp,vref.yaml create mode 100644 include/zephyr/dt-bindings/regulator/nxp_vref.h diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 972618db12d..27bf32076cf 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -15,3 +15,4 @@ zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_RPI_PICO regulator_rpi_pico.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_NXP_VREF regulator_nxp_vref.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 94998fb6191..5ecaf1181ea 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -37,5 +37,6 @@ source "drivers/regulator/Kconfig.npm1300" source "drivers/regulator/Kconfig.npm6001" source "drivers/regulator/Kconfig.pca9420" source "drivers/regulator/Kconfig.rpi_pico" +source "drivers/regulator/Kconfig.nxp_vref" endif # REGULATOR diff --git a/drivers/regulator/Kconfig.nxp_vref b/drivers/regulator/Kconfig.nxp_vref new file mode 100644 index 00000000000..4c9bc54fd13 --- /dev/null +++ b/drivers/regulator/Kconfig.nxp_vref @@ -0,0 +1,14 @@ +# Copyright 2023 NXP +# SPDX -License-Identifier: Apache-2.0 + +config REGULATOR_NXP_VREF + bool "NXP VREF peripheral driver" + default y if DT_HAS_NXP_VREF_ENABLED + help + Enable the NXP VREF driver + +config REGULATOR_NXP_VREF_INIT_PRIORITY + int "NXP VREF peripheral driver init priority" + default 45 + help + Init priority for the NXP VREF peripheral. diff --git a/drivers/regulator/regulator_nxp_vref.c b/drivers/regulator/regulator_nxp_vref.c new file mode 100644 index 00000000000..3d2ba23010e --- /dev/null +++ b/drivers/regulator/regulator_nxp_vref.c @@ -0,0 +1,221 @@ +/* + * Copyright 2023 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_vref + +#include + +#include +#include +#include +#include +#include + +#include + +static const struct linear_range utrim_range = LINEAR_RANGE_INIT(1000000, 100000U, 0x0U, 0xBU); + +struct regulator_nxp_vref_data { + struct regulator_common_data common; +}; + +struct regulator_nxp_vref_config { + struct regulator_common_config common; + VREF_Type *base; + uint8_t gnd_sel; + uint16_t buf_start_delay; + uint16_t bg_start_time; +}; + +static int regulator_nxp_vref_enable(const struct device *dev) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + + volatile uint32_t *const csr = &base->CSR; + + *csr |= VREF_CSR_LPBGEN_MASK | VREF_CSR_LPBG_BUF_EN_MASK; + /* Wait for bandgap startup */ + k_busy_wait(config->bg_start_time); + + /* Enable high accuracy bandgap */ + *csr |= VREF_CSR_HCBGEN_MASK; + + /* Monitor until stable */ + while (!(*csr & VREF_CSR_VREFST_MASK)) + ; + + /* Enable output buffer */ + *csr |= VREF_CSR_BUF21EN_MASK; + + return 0; +} + +static int regulator_nxp_vref_disable(const struct device *dev) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + + /* + * Disable HC Bandgap, LP Bandgap, and Buf21 + * to achieve "Off" mode of VREF + */ + base->CSR &= ~(VREF_CSR_BUF21EN_MASK | VREF_CSR_HCBGEN_MASK | VREF_CSR_LPBGEN_MASK); + + return 0; +} + +static int regulator_nxp_vref_set_mode(const struct device *dev, regulator_mode_t mode) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + uint32_t csr = base->CSR; + + if (mode == NXP_VREF_MODE_STANDBY) { + csr &= ~VREF_CSR_REGEN_MASK & + ~VREF_CSR_CHOPEN_MASK & + ~VREF_CSR_HI_PWR_LV_MASK & + ~VREF_CSR_BUF21EN_MASK; + } else if (mode == NXP_VREF_MODE_LOW_POWER) { + csr &= ~VREF_CSR_REGEN_MASK & + ~VREF_CSR_CHOPEN_MASK & + ~VREF_CSR_HI_PWR_LV_MASK; + csr |= VREF_CSR_BUF21EN_MASK; + } else if (mode == NXP_VREF_MODE_HIGH_POWER) { + csr &= ~VREF_CSR_REGEN_MASK & + ~VREF_CSR_CHOPEN_MASK; + csr |= VREF_CSR_HI_PWR_LV_MASK & + VREF_CSR_BUF21EN_MASK; + } else if (mode == NXP_VREF_MODE_INTERNAL_REGULATOR) { + csr |= VREF_CSR_REGEN_MASK & + VREF_CSR_CHOPEN_MASK & + VREF_CSR_HI_PWR_LV_MASK & + VREF_CSR_BUF21EN_MASK; + } else { + return -EINVAL; + } + + base->CSR = csr; + + k_busy_wait(config->buf_start_delay); + + return 0; +} + +static int regulator_nxp_vref_get_mode(const struct device *dev, regulator_mode_t *mode) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + uint32_t csr = base->CSR; + + /* Check bits to determine mode */ + if (csr & VREF_CSR_REGEN_MASK) { + *mode = NXP_VREF_MODE_INTERNAL_REGULATOR; + } else if (csr & VREF_CSR_HI_PWR_LV_MASK) { + *mode = NXP_VREF_MODE_HIGH_POWER; + } else if (csr & VREF_CSR_BUF21EN_MASK) { + *mode = NXP_VREF_MODE_LOW_POWER; + } else { + *mode = NXP_VREF_MODE_STANDBY; + } + + return 0; +} + +static inline unsigned int regulator_nxp_vref_count_voltages(const struct device *dev) +{ + return linear_range_values_count(&utrim_range); +} + +static int regulator_nxp_vref_list_voltage(const struct device *dev, + unsigned int idx, int32_t *volt_uv) +{ + return linear_range_get_value(&utrim_range, idx, volt_uv); +} + +static int regulator_nxp_vref_set_voltage(const struct device *dev, + int32_t min_uv, int32_t max_uv) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + uint16_t idx; + int ret; + + ret = linear_range_get_win_index(&utrim_range, min_uv, max_uv, &idx); + if (ret < 0) { + return ret; + } + + base->UTRIM &= ~VREF_UTRIM_TRIM2V1_MASK; + base->UTRIM |= VREF_UTRIM_TRIM2V1_MASK & idx; + + return 0; +} + +static int regulator_nxp_vref_get_voltage(const struct device *dev, + int32_t *volt_uv) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *const base = config->base; + uint16_t idx; + int ret; + + /* Linear range index is the register value */ + idx = (base->UTRIM & VREF_UTRIM_TRIM2V1_MASK) >> VREF_UTRIM_TRIM2V1_SHIFT; + + ret = linear_range_get_value(&utrim_range, base->UTRIM, volt_uv); + + return ret; +} + +static const struct regulator_driver_api api = { + .enable = regulator_nxp_vref_enable, + .disable = regulator_nxp_vref_disable, + .set_mode = regulator_nxp_vref_set_mode, + .get_mode = regulator_nxp_vref_get_mode, + .set_voltage = regulator_nxp_vref_set_voltage, + .get_voltage = regulator_nxp_vref_get_voltage, + .list_voltage = regulator_nxp_vref_list_voltage, + .count_voltages = regulator_nxp_vref_count_voltages, +}; + +static int regulator_nxp_vref_init(const struct device *dev) +{ + const struct regulator_nxp_vref_config *config = dev->config; + VREF_Type *base = config->base; + int ret; + + regulator_common_data_init(dev); + + /* Select ground */ + base->CSR &= ~VREF_CSR_REFL_GRD_SEL_MASK; + base->CSR |= config->gnd_sel; + + ret = regulator_nxp_vref_disable(dev); + if (ret < 0) { + return ret; + } + + return regulator_common_init(dev, false); +} + +#define REGULATOR_NXP_VREF_DEFINE(inst) \ + static struct regulator_nxp_vref_data data_##inst; \ + \ + static const struct regulator_nxp_vref_config config_##inst = { \ + .common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst), \ + .base = (VREF_Type *) DT_INST_REG_ADDR(inst), \ + .gnd_sel = DT_INST_ENUM_IDX_OR(inst, nxp_ground_select, 0), \ + .buf_start_delay = DT_INST_PROP(inst, \ + nxp_buffer_startup_delay_us), \ + .bg_start_time = DT_INST_PROP(inst, \ + nxp_bandgap_startup_time_us), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, regulator_nxp_vref_init, NULL, &data_##inst,\ + &config_##inst, POST_KERNEL, \ + CONFIG_REGULATOR_NXP_VREF_INIT_PRIORITY, &api); \ + +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NXP_VREF_DEFINE) diff --git a/dts/bindings/regulator/nxp,vref.yaml b/dts/bindings/regulator/nxp,vref.yaml new file mode 100644 index 00000000000..e3466ad29d5 --- /dev/null +++ b/dts/bindings/regulator/nxp,vref.yaml @@ -0,0 +1,41 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP VREF SOC peripheral + +compatible: "nxp,vref" + +include: + - name: base.yaml + - name: regulator.yaml + property-allowlist: + - regulator-name + - regulator-init-microvolt + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-initial-mode + - regulator-allowed-modes + +properties: + reg: + required: true + + nxp,ground-select: + type: string + enum: + - "VREFL3V" # 0 + - "VSSA" # 1 + + nxp,buffer-startup-delay-us: + type: int + required: true + description: | + Buffer startup delay as specified in the + appropriate device data sheet, in microseconds. + + nxp,bandgap-startup-time-us: + type: int + required: true + description: | + Maximum bandgap startup time as specified in the + appropriate device data sheet, in microseconds. diff --git a/include/zephyr/dt-bindings/regulator/nxp_vref.h b/include/zephyr/dt-bindings/regulator/nxp_vref.h new file mode 100644 index 00000000000..37c3856496a --- /dev/null +++ b/include/zephyr/dt-bindings/regulator/nxp_vref.h @@ -0,0 +1,29 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NXP_VREF_H +#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NXP_VREF_H + +/** + * @defgroup regulator_nxp_vref Devicetree helpers + * @ingroup regulator_interface + * @{ + */ + +/** + * @name NXP VREF Regulator API Modes + * @{ + */ +#define NXP_VREF_MODE_STANDBY 0 +#define NXP_VREF_MODE_LOW_POWER 1 +#define NXP_VREF_MODE_HIGH_POWER 2 +#define NXP_VREF_MODE_INTERNAL_REGULATOR 3 + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NXP_VREF_H */ From 15bc6a2389c6fe0d7dc371fbcd6b604a9be0d3f9 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 12 Apr 2023 15:19:44 +0000 Subject: [PATCH 0763/4498] soc: lpc55s3x: Enable VREF Add node for VREF0 peripheral to LPC55S3X SOC DT Clock VREF peripheral if status = okay in DT Enable VREF on lpcxpresso55s36 Signed-off-by: Declan Snyder --- .../arm/lpcxpresso55s36/lpcxpresso55s36.dts | 4 +++ dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 9 ++++++ soc/arm/nxp_lpc/lpc55xxx/soc.c | 32 +++++++------------ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts index df4fbbdc99b..3b51a1602f2 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts @@ -176,6 +176,10 @@ zephyr_udc0: &usbfs { status = "okay"; }; +&vref0 { + status = "okay"; +}; + &dac0 { status = "okay"; pinctrl-0 = <&pinmux_dac0>; diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 77e1ed26b0e..99b105fbf81 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -462,6 +462,15 @@ prescaler = <2>; #pwm-cells = <3>; }; + + vref0: vref@b5000 { + compatible = "nxp,vref"; + regulator-name = "lpc55s36-vref"; + reg = <0xb5000 0x30>; + status = "disabled"; + nxp,buffer-startup-delay-us = <400>; + nxp,bandgap-startup-time-us = <20>; + }; }; &nvic { diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index a16b5c959f0..8084be53384 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -1,5 +1,4 @@ -/* - * Copyright 2017, 2019-2023 NXP +/* Copyright 2017, 2019-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -323,15 +322,21 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) #if defined(CONFIG_SOC_LPC55S36) CLOCK_SetClkDiv(kCLOCK_DivAdc0Clk, 2U, true); CLOCK_AttachClk(kFRO_HF_to_ADC0); -#else +#else /* not LPC55s36 */ CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, DT_PROP(DT_NODELABEL(adc0), clk_divider), true); CLOCK_AttachClk(MUX_A(CM_ADCASYNCCLKSEL, DT_PROP(DT_NODELABEL(adc0), clk_source))); /* Power up the ADC */ POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC); -#endif -#endif +#endif /* SOC platform */ +#endif /* ADC */ + +#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(vref0), nxp_vref, okay)) + CLOCK_EnableClock(kCLOCK_Vref); + POWER_DisablePD(kPDRUNCFG_PD_VREF); +#endif /* vref0 */ + #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(dac0), nxp_lpdac, okay) #if defined(CONFIG_SOC_LPC55S36) CLOCK_SetClkDiv(kCLOCK_DivDac0Clk, 1U, true); @@ -339,22 +344,9 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) /* Disable DAC0 power down */ POWER_DisablePD(kPDRUNCFG_PD_DAC0); -#endif -#endif -#if defined(CONFIG_SOC_LPC55S36) -#if (defined(CONFIG_ADC_MCUX_LPADC) || defined(CONFIG_DAC_MCUX_LPDAC)) - /* Vref is required for LPADC reference */ - POWER_DisablePD(kPDRUNCFG_PD_VREF); +#endif /* SOC platform */ +#endif /* DAC */ - vref_config_t vrefConfig; - - VREF_GetDefaultConfig(&vrefConfig); - vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer; - vrefConfig.enableInternalVoltageRegulator = true; - vrefConfig.enableVrefOut = true; - VREF_Init((VREF_Type *)VREF_BASE, &vrefConfig); -#endif -#endif } /** From fe8b112efd34c4feae67e7d42385827ecec4a8ed Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 12 Apr 2023 20:21:10 +0000 Subject: [PATCH 0764/4498] dts: bindings: lpadc: Add regulator phandle prop Add phandle prop to reference any regulator that must be enabled in order for the LPADC to function as intended. Change LPADC driver to use this property if present. LPADC on LPC55S36 depends on VREF peripheral, enable for this platform. Signed-off-by: Declan Snyder --- drivers/adc/Kconfig.mcux | 1 + drivers/adc/adc_mcux_lpadc.c | 25 ++++++++++++++++++++++++- dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 1 + dts/bindings/adc/nxp,lpc-lpadc.yaml | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/adc/Kconfig.mcux b/drivers/adc/Kconfig.mcux index c53ffeee468..725ec32c2c8 100644 --- a/drivers/adc/Kconfig.mcux +++ b/drivers/adc/Kconfig.mcux @@ -30,6 +30,7 @@ config ADC_MCUX_LPADC bool "MCUX LPADC driver" default y select ADC_CONFIGURABLE_INPUTS + select REGULATOR depends on DT_HAS_NXP_LPC_LPADC_ENABLED help Enable the MCUX LPADC driver. diff --git a/drivers/adc/adc_mcux_lpadc.c b/drivers/adc/adc_mcux_lpadc.c index c9ea7197c2b..b15790ccb9d 100644 --- a/drivers/adc/adc_mcux_lpadc.c +++ b/drivers/adc/adc_mcux_lpadc.c @@ -13,7 +13,9 @@ #include #include +#include #include +#include #include @@ -43,6 +45,7 @@ struct mcux_lpadc_config { uint32_t offset_b; void (*irq_config_func)(const struct device *dev); const struct pinctrl_dev_config *pincfg; + const struct device **ref_supplies; }; struct mcux_lpadc_data { @@ -392,6 +395,16 @@ static int mcux_lpadc_init(const struct device *dev) return err; } + /* Enable necessary regulators */ + const struct device **regulator = config->ref_supplies; + + while (*regulator != NULL) { + err = regulator_enable(*(regulator++)); + if (err) { + return err; + } + } + LPADC_GetDefaultConfig(&adc_config); adc_config.enableAnalogPreliminary = true; @@ -455,8 +468,18 @@ static const struct adc_driver_api mcux_lpadc_driver_api = { #endif }; +#define LPADC_REGULATOR_DEPENDENCY(node_id, prop, idx) \ + DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), + +#define LPADC_REGULATORS_DEFINE(inst) \ + static const struct device *mcux_lpadc_ref_supplies_##inst[] = { \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, nxp_reference_supply), \ + (DT_INST_FOREACH_PROP_ELEM(inst, nxp_reference_supply, \ + LPADC_REGULATOR_DEPENDENCY)), ()) NULL}; #define LPADC_MCUX_INIT(n) \ + LPADC_REGULATORS_DEFINE(n) \ + \ static void mcux_lpadc_config_func_##n(const struct device *dev); \ \ PINCTRL_DT_INST_DEFINE(n); \ @@ -469,8 +492,8 @@ static const struct adc_driver_api mcux_lpadc_driver_api = { .offset_b = DT_INST_PROP(n, offset_value_b), \ .irq_config_func = mcux_lpadc_config_func_##n, \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .ref_supplies = mcux_lpadc_ref_supplies_##n, \ }; \ - \ static struct mcux_lpadc_data mcux_lpadc_data_##n = { \ ADC_CONTEXT_INIT_TIMER(mcux_lpadc_data_##n, ctx), \ ADC_CONTEXT_INIT_LOCK(mcux_lpadc_data_##n, ctx), \ diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 99b105fbf81..24b326f2ce8 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -292,6 +292,7 @@ #io-channel-cells = <1>; dmas = <&dma0 21>, <&dma0 22>; dma-names = "adc0-dma0", "adc0-dma1"; + nxp,reference-supply = <&vref0>; }; dac0: dac@b2000 { diff --git a/dts/bindings/adc/nxp,lpc-lpadc.yaml b/dts/bindings/adc/nxp,lpc-lpadc.yaml index 0a8c2c74783..75b9c7fa357 100644 --- a/dts/bindings/adc/nxp,lpc-lpadc.yaml +++ b/dts/bindings/adc/nxp,lpc-lpadc.yaml @@ -71,6 +71,10 @@ properties: required: true description: Offset value B to use if CONFIG_LPADC_DO_OFFSET_CALIBRATION is false + nxp,reference-supply: + type: phandles + description: References to required regulators which must be enabled for LPADC to function + "#io-channel-cells": const: 1 From a9750d4fea056c14bd71d76c0c342264204910b3 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 6 Jul 2023 11:14:20 -0500 Subject: [PATCH 0765/4498] tests: regulator voltage: Support LPC55S36 board Support lpcxpresso55s36 on regulator voltage test using VREF Signed-off-by: Declan Snyder --- .../regulator/voltage/lpcxpresso55s36.overlay | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/drivers/regulator/voltage/lpcxpresso55s36.overlay diff --git a/tests/drivers/regulator/voltage/lpcxpresso55s36.overlay b/tests/drivers/regulator/voltage/lpcxpresso55s36.overlay new file mode 100644 index 00000000000..a6414a494ca --- /dev/null +++ b/tests/drivers/regulator/voltage/lpcxpresso55s36.overlay @@ -0,0 +1,39 @@ +/* + * Copyright 2023 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* To do this test, connect AN (J7-1) to VREF_OUT (J12-16) */ + +/ { + resources: resources { + compatible = "test-regulator-voltage"; + regulators = <&vref0>; + tolerance-microvolt = <1000000>; + set-read-delay-ms = <10>; + adc-avg-count = <10>; + io-channels = <&adc0 0>; + }; +}; + +&vref0 { + regulator-initial-mode = ; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <1800>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + zephyr,input-positive = ; + }; +}; From 91781306e95c28ca9b96fff242e342acb86edf11 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 1 Sep 2023 05:11:50 +0200 Subject: [PATCH 0766/4498] Revert "Bluetooth: Controller: Fix ull_prepare_dequeue for skipped events" These change are reverted as part of fixing regression failure in LL/DDI/SCN/BV-21-C and LL/DDI/SCN/BV-25-C. This reverts commit 0d54ca876168b7d5d28219af3f3f1a247da49209. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll.c | 6 +-- subsys/bluetooth/controller/ll_sw/ull.c | 48 +++++++------------ 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index fe0a031d402..cde3eaaa6ee 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -930,8 +930,8 @@ static uint32_t preempt_ticker_start(struct lll_event *first, TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, TICKER_NULL_SLOT, - preempt_ticker_cb, first->prepare_param.param, - ticker_start_op_cb, NULL); + preempt_ticker_cb, first, + ticker_start_op_cb, first); return ret; } @@ -1007,7 +1007,7 @@ static void preempt(void *param) } /* Preemptor not in pipeline */ - if (next->prepare_param.param != param) { + if (next != param) { uint32_t ret; /* Start the preempt timeout */ diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 2f325f1a86b..3f60290dba3 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2063,8 +2063,6 @@ void *ull_prepare_dequeue_iter(uint8_t *idx) void ull_prepare_dequeue(uint8_t caller_id) { - void *param_normal_head = NULL; - void *param_normal_next = NULL; void *param_resume_head = NULL; void *param_resume_next = NULL; struct lll_event *next; @@ -2105,41 +2103,31 @@ void ull_prepare_dequeue(uint8_t caller_id) /* The prepare element was not a resume event, it would * use the radio or was enqueued back into prepare * pipeline with a preempt timeout being set. - * - * Remember the first encountered and the next element - * in the prepare pipeline so that we do not infinitely - * loop through the resume events in prepare pipeline. */ if (!is_resume) { - if (!param_normal_head) { - param_normal_head = param; - } else if (!param_normal_next) { - param_normal_next = param; - } - } else { - if (!param_resume_head) { - param_resume_head = param; - } else if (!param_resume_next) { - param_resume_next = param; - } + break; + } + + /* Remember the first encountered resume and the next + * resume element in the prepare pipeline so that we do + * not infinitely loop through the resume events in + * prepare pipeline. + */ + if (!param_resume_head) { + param_resume_head = param; + } else if (!param_resume_next) { + param_resume_next = param; } /* Stop traversing the prepare pipeline when we reach - * back to the first or next event where we + * back to the first or next resume event where we * initially started processing the prepare pipeline. */ - if (!next->is_aborted && - ((!next->is_resume && - ((next->prepare_param.param == - param_normal_head) || - (next->prepare_param.param == - param_normal_next))) || - (next->is_resume && - !param_normal_next && - ((next->prepare_param.param == - param_resume_head) || - (next->prepare_param.param == - param_resume_next))))) { + if (next->is_resume && + ((next->prepare_param.param == + param_resume_head) || + (next->prepare_param.param == + param_resume_next))) { break; } } From dacadf2f1a987339cb4ec08e29fd88b77f8e5ae6 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 1 Sep 2023 05:18:47 +0200 Subject: [PATCH 0767/4498] Bluetooth: Controller: Use the state/role param in prepare pipeline Use the state/role context parameter in prepare pipeline to identify the preempt timeout that was setup. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index cde3eaaa6ee..fe0a031d402 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -930,8 +930,8 @@ static uint32_t preempt_ticker_start(struct lll_event *first, TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, TICKER_NULL_SLOT, - preempt_ticker_cb, first, - ticker_start_op_cb, first); + preempt_ticker_cb, first->prepare_param.param, + ticker_start_op_cb, NULL); return ret; } @@ -1007,7 +1007,7 @@ static void preempt(void *param) } /* Preemptor not in pipeline */ - if (next != param) { + if (next->prepare_param.param != param) { uint32_t ret; /* Start the preempt timeout */ From 67a2fc429320f4422faa35adbfc2fff14ee198de Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 2 Sep 2023 09:18:23 +0530 Subject: [PATCH 0768/4498] Bluetooth: Controller: Use ticker_ticks_diff_get to check short prepare Use ticker_ticks_diff_get consistently when calculating difference between ticker ticks when determining short prepare requests. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index fe0a031d402..b127e60a9f4 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -869,6 +869,13 @@ static uint32_t preempt_ticker_start(struct lll_event *first, (preempt_req != preempt_ack)) { uint32_t diff; + /* preempt timeout already started but no role/state in the head + * of prepare pipeline. + */ + if (!prev || prev->is_aborted) { + return TICKER_STATUS_SUCCESS; + } + /* Calc the preempt timeout */ p = &next->prepare_param; ull = HDR_LLL2ULL(p->param); @@ -881,9 +888,9 @@ static uint32_t preempt_ticker_start(struct lll_event *first, ticks_at_preempt_new &= HAL_TICKER_CNTR_MASK; /* Check for short preempt timeouts */ - diff = ticks_at_preempt_new - ticks_at_preempt; - if (!prev || prev->is_aborted || - ((diff & BIT(HAL_TICKER_CNTR_MSBIT)) == 0U)) { + diff = ticker_ticks_diff_get(ticks_at_preempt_new, + ticks_at_preempt); + if ((diff & BIT(HAL_TICKER_CNTR_MSBIT)) == 0U) { return TICKER_STATUS_SUCCESS; } From 377e2a1f48720a53e8b727eba32d40442c1ad46b Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 1 Sep 2023 05:35:19 +0200 Subject: [PATCH 0769/4498] Bluetooth: Controller: Fix ticks_slot_window use in Observer Fix ticks_slot_window use in Observer, do not use for unreserved continuous scanning, and do not use when scanning on both 1M and Coded PHY simultaneously. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_scan.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan.c b/subsys/bluetooth/controller/ll_sw/ull_scan.c index 1ee99565a13..21d6cc9c401 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan.c @@ -500,6 +500,10 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan) * enabled. */ } + +#if defined(CONFIG_BT_TICKER_EXT) + ll_scan_ticker_ext[handle].ticks_slot_window = 0U; +#endif /* CONFIG_BT_TICKER_EXT */ } /* 1M scan window starts without any offset */ @@ -559,6 +563,10 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan) } else { ticks_offset = 0U; } + +#if defined(CONFIG_BT_TICKER_EXT) + ll_scan_ticker_ext[handle].ticks_slot_window = 0U; +#endif /* CONFIG_BT_TICKER_EXT */ } else { ticks_offset = 0U; } From 7f388bb70a3dadb5b3d4a2b4d2a63d1837108492 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 18 Jan 2022 17:52:06 +0530 Subject: [PATCH 0770/4498] Bluetooth: Controller: Fix short prepare when many enqueued in pipeline Fix short prepare handling when more than one event is enqueued in the pipeline and the short prepare is placed at the end of the prepare pipeline. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll.c | 69 ++++++++++++------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index b127e60a9f4..9ccc36e49e5 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -899,15 +899,6 @@ static uint32_t preempt_ticker_start(struct lll_event *first, LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); - /* Set early as we get called again through the call to - * abort_cb(). - */ - ticks_at_preempt = ticks_at_preempt_new; - - /* Abort previous prepare that set the preempt timeout */ - prev->is_aborted = 1U; - prev->abort_cb(&prev->prepare_param, prev->prepare_param.param); - /* Schedule short preempt timeout */ first = next; } else { @@ -996,17 +987,11 @@ static void preempt(void *param) return; } - /* Check if any prepare in pipeline */ - idx = UINT8_MAX; - next = ull_prepare_dequeue_iter(&idx); - if (!next) { - return; - } - /* Find a prepare that is ready and not a resume */ - while (next && (next->is_aborted || next->is_resume)) { + idx = UINT8_MAX; + do { next = ull_prepare_dequeue_iter(&idx); - } + } while (next && (next->is_aborted || next->is_resume)); /* No ready prepare */ if (!next) { @@ -1015,14 +1000,52 @@ static void preempt(void *param) /* Preemptor not in pipeline */ if (next->prepare_param.param != param) { + struct lll_event *next_next = NULL; + struct lll_event *e; uint32_t ret; - /* Start the preempt timeout */ - ret = preempt_ticker_start(next, NULL, next); - LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || - (ret == TICKER_STATUS_BUSY)); + /* Find if a short prepare request in the pipeline */ + do { + e = ull_prepare_dequeue_iter(&idx); + if (!next_next && e && !e->is_aborted && + !e->is_resume) { + next_next = e; + } + } while (e && (e->is_aborted || e->is_resume || + (e->prepare_param.param != param))); - return; + /* No short prepare request in pipeline */ + if (!e) { + /* Start the preempt timeout for next event */ + ret = preempt_ticker_start(next, NULL, next); + LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || + (ret == TICKER_STATUS_BUSY)); + + return; + } + + /* FIXME: Abort all events in pipeline before the short + * prepare event. For now, lets assert when many + * enqueued prepares need aborting. + */ + LL_ASSERT(next_next == e); + + /* Abort the prepare that is present before the short prepare */ + next->is_aborted = 1; + next->abort_cb(&next->prepare_param, next->prepare_param.param); + + /* As the prepare queue has been refreshed due to the call of + * abort_cb which invokes the lll_done, find the latest prepare + */ + idx = UINT8_MAX; + do { + next = ull_prepare_dequeue_iter(&idx); + } while (next && (next->is_aborted || next->is_resume)); + + /* No ready prepare */ + if (!next) { + return; + } } /* Check if current event want to continue */ From c1042dff408cb37947e069e963c4424a249db525 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 20 Sep 2023 09:54:23 +0200 Subject: [PATCH 0771/4498] Bluetooth: Controller: Refactor prepare dequeue iteration code Refactor/rename prepare dequeue iteration code and reuse it. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll.c | 165 +++++++++--------- 1 file changed, 82 insertions(+), 83 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 9ccc36e49e5..db8f25a374c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -65,7 +65,9 @@ static int init_reset(void); #if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) static inline void done_inc(void); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ -static struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb); +static inline bool is_done_sync(void); +static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx); +static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb); static void isr_race(void *param); #if !defined(CONFIG_BT_CTLR_LOW_LAT) @@ -643,52 +645,27 @@ void lll_isr_early_abort(void *param) lll_done(NULL); } -static int init_reset(void) -{ - return 0; -} - -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) -static inline void done_inc(void) -{ - event.done.lll_count++; - LL_ASSERT(event.done.lll_count != event.done.ull_count); -} -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ - -static inline bool is_done_sync(void) -{ -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) - return event.done.lll_count == event.done.ull_count; -#else /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ - return true; -#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ -} - int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, lll_prepare_cb_t prepare_cb, struct lll_prepare_param *prepare_param, uint8_t is_resume, uint8_t is_dequeue) { - struct lll_event *p; + struct lll_event *ready; + struct lll_event *next; uint8_t idx; int err; /* Find the ready prepare in the pipeline */ idx = UINT8_MAX; - p = ull_prepare_dequeue_iter(&idx); - while (p && (p->is_aborted || p->is_resume)) { - p = ull_prepare_dequeue_iter(&idx); - } + ready = prepare_dequeue_iter_ready_get(&idx); /* Current event active or another prepare is ready in the pipeline */ if ((!is_dequeue && !is_done_sync()) || event.curr.abort_cb || - (p && is_resume)) { + (ready && is_resume)) { #if defined(CONFIG_BT_CTLR_LOW_LAT) lll_prepare_cb_t resume_cb; #endif /* CONFIG_BT_CTLR_LOW_LAT */ - struct lll_event *next; if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) && event.curr.param) { /* early abort */ @@ -706,29 +683,28 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, } /* Always start preempt timeout for first prepare in pipeline */ - struct lll_event *first = p ? p : next; + struct lll_event *first = ready ? ready : next; uint32_t ret; /* Start the preempt timeout */ - ret = preempt_ticker_start(first, p, next); + ret = preempt_ticker_start(first, ready, next); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); #else /* CONFIG_BT_CTLR_LOW_LAT */ next = NULL; - while (p) { - if (!p->is_aborted) { - if (event.curr.param == - p->prepare_param.param) { - p->is_aborted = 1; - p->abort_cb(&p->prepare_param, - p->prepare_param.param); + while (ready) { + if (!ready->is_aborted) { + if (event.curr.param == ready->prepare_param.param) { + ready->is_aborted = 1; + ready->abort_cb(&ready->prepare_param, + ready->prepare_param.param); } else { - next = p; + next = ready; } } - p = ull_prepare_dequeue_iter(&idx); + ready = ull_prepare_dequeue_iter(&idx); } if (next) { @@ -749,7 +725,7 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, return -EINPROGRESS; } - LL_ASSERT(!p || &p->prepare_param == prepare_param); + LL_ASSERT(!ready || &ready->prepare_param == prepare_param); event.curr.param = prepare_param->param; event.curr.is_abort_cb = is_abort_cb; @@ -774,15 +750,13 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, */ /* Find next prepare needing preempt timeout to be setup */ - do { - p = ull_prepare_dequeue_iter(&idx); - if (!p) { - return err; - } - } while (p->is_aborted || p->is_resume); + next = prepare_dequeue_iter_ready_get(&idx); + if (!next) { + return err; + } /* Start the preempt timeout */ - ret = preempt_ticker_start(p, NULL, p); + ret = preempt_ticker_start(next, NULL, next); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); #endif /* !CONFIG_BT_CTLR_LOW_LAT */ @@ -790,7 +764,40 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, return err; } -static struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb) +static int init_reset(void) +{ + return 0; +} + +#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) +static inline void done_inc(void) +{ + event.done.lll_count++; + LL_ASSERT(event.done.lll_count != event.done.ull_count); +} +#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ + +static inline bool is_done_sync(void) +{ +#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) + return event.done.lll_count == event.done.ull_count; +#else /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ + return true; +#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ +} + +static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx) +{ + struct lll_event *ready; + + do { + ready = ull_prepare_dequeue_iter(idx); + } while (ready && (ready->is_aborted || ready->is_resume)); + + return ready; +} + +static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb) { struct lll_prepare_param prepare_param = {0}; @@ -978,7 +985,7 @@ static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, static void preempt(void *param) { lll_prepare_cb_t resume_cb; - struct lll_event *next; + struct lll_event *ready; uint8_t idx; int err; @@ -989,35 +996,32 @@ static void preempt(void *param) /* Find a prepare that is ready and not a resume */ idx = UINT8_MAX; - do { - next = ull_prepare_dequeue_iter(&idx); - } while (next && (next->is_aborted || next->is_resume)); - - /* No ready prepare */ - if (!next) { + ready = prepare_dequeue_iter_ready_get(&idx); + if (!ready) { + /* No ready prepare */ return; } /* Preemptor not in pipeline */ - if (next->prepare_param.param != param) { - struct lll_event *next_next = NULL; - struct lll_event *e; + if (ready->prepare_param.param != param) { + struct lll_event *ready_next = NULL; + struct lll_event *preemptor; uint32_t ret; /* Find if a short prepare request in the pipeline */ do { - e = ull_prepare_dequeue_iter(&idx); - if (!next_next && e && !e->is_aborted && - !e->is_resume) { - next_next = e; + preemptor = ull_prepare_dequeue_iter(&idx); + if (!ready_next && preemptor && !preemptor->is_aborted && + !preemptor->is_resume) { + ready_next = preemptor; } - } while (e && (e->is_aborted || e->is_resume || - (e->prepare_param.param != param))); + } while (preemptor && (preemptor->is_aborted || preemptor->is_resume || + (preemptor->prepare_param.param != param))); /* No short prepare request in pipeline */ - if (!e) { - /* Start the preempt timeout for next event */ - ret = preempt_ticker_start(next, NULL, next); + if (!preemptor) { + /* Start the preempt timeout for ready event */ + ret = preempt_ticker_start(ready, NULL, ready); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); @@ -1028,34 +1032,29 @@ static void preempt(void *param) * prepare event. For now, lets assert when many * enqueued prepares need aborting. */ - LL_ASSERT(next_next == e); + LL_ASSERT(preemptor == ready_next); /* Abort the prepare that is present before the short prepare */ - next->is_aborted = 1; - next->abort_cb(&next->prepare_param, next->prepare_param.param); + ready->is_aborted = 1; + ready->abort_cb(&ready->prepare_param, ready->prepare_param.param); /* As the prepare queue has been refreshed due to the call of * abort_cb which invokes the lll_done, find the latest prepare */ idx = UINT8_MAX; - do { - next = ull_prepare_dequeue_iter(&idx); - } while (next && (next->is_aborted || next->is_resume)); - - /* No ready prepare */ - if (!next) { + ready = prepare_dequeue_iter_ready_get(&idx); + if (!ready) { + /* No ready prepare */ return; } } /* Check if current event want to continue */ - err = event.curr.is_abort_cb(next->prepare_param.param, - event.curr.param, - &resume_cb); + err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); if (!err) { /* Let preemptor LLL know about the cancelled prepare */ - next->is_aborted = 1; - next->abort_cb(&next->prepare_param, next->prepare_param.param); + ready->is_aborted = 1; + ready->abort_cb(&ready->prepare_param, ready->prepare_param.param); return; } From 02b1c768206291a8f4d105a34ab357b973240195 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 26 Mar 2023 21:38:42 +0530 Subject: [PATCH 0772/4498] Bluetooth: Controller: Reduce successive ticker_job() on Extended Scan Reduce number of successive calls to ticker_job() by disabling mayflies in the ULL_HIGH priority, enqueue ticker_yield_abs() and ticker_start() before re-enabling so that single ticker_job() handles both yield and start. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 316cec7fec7..ecdfdd60d07 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -682,6 +682,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) ticks_aux_offset = HAL_TICKER_US_TO_TICKS(aux_offset_us); +#if (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) + /* disable ticker job, in order to chain yield and start to reduce + * CPU use by reducing successive calls to ticker_job(). + */ + mayfly_enable(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 0); +#endif + /* Yield the primary scan window or auxiliary or periodic sync event * in ticker. */ @@ -714,6 +721,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) ((ticker_status == TICKER_STATUS_FAILURE) && IS_ENABLED(CONFIG_BT_TICKER_LOW_LAT))); +#if (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) + /* enable ticker job, queued ticker operation will be handled + * thereafter. + */ + mayfly_enable(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1); +#endif + return; ull_scan_aux_rx_flush: From d8f0006de5182d233ab1a438fe8594c2faa4372e Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 4 Sep 2023 15:26:18 +0530 Subject: [PATCH 0773/4498] Bluetooth: Controller: Revert EVENT_OVERHEAD_START_US for Coded PHY Revert EVENT_OVERHEAD_START_US value for Coded PHY support, needed to pass LL/DDI/SCN/BV-21-C and LL/DDI/SCN/BV-25-C. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h index 7df39f65c8a..db5f8e3f1d8 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h @@ -21,22 +21,22 @@ /* Active connection in peripheral role with extended scanning on 1M and Coded * PHY, scheduling and receiving auxiliary PDUs. */ -#define EVENT_OVERHEAD_START_US 458 +#define EVENT_OVERHEAD_START_US 733 /* 24 RTC ticks */ #else /* !CONFIG_BT_CTLR_PHY_CODED */ /* Active connection in peripheral role with extended scanning on 1M only, * scheduling and receiving auxiliary PDUs. */ -#define EVENT_OVERHEAD_START_US 428 +#define EVENT_OVERHEAD_START_US 428 /* 14 RTC ticks */ #endif /* !CONFIG_BT_CTLR_PHY_CODED */ #else /* !CONFIG_BT_OBSERVER */ /* Active connection in peripheral role with legacy scanning on 1M. */ -#define EVENT_OVERHEAD_START_US 275 +#define EVENT_OVERHEAD_START_US 275 /* 9 RTC ticks */ #endif /* !CONFIG_BT_OBSERVER */ #else /* !CONFIG_BT_CTLR_ADV_EXT */ /* Active connection in peripheral role with additional advertising state. */ -#define EVENT_OVERHEAD_START_US 275 +#define EVENT_OVERHEAD_START_US 275 /* 9 RTC ticks */ #endif /* !CONFIG_BT_CTLR_ADV_EXT */ /* Worst-case time margin needed after event end-time in the air From e8fe144f3a0209569ea661520b65dee20e767c12 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 5 Sep 2023 12:44:50 +0530 Subject: [PATCH 0774/4498] Bluetooth: Controller: Fix missing PHY_CODED cond compile Fix missing Coded PHY implementation conditional compile causing compile error when disabling Coded PHY support in SoCs that have radio that support Coded PHY. Signed-off-by: Vinayak Kariappa Chettimada --- samples/bluetooth/hci_rpmsg/sample.yaml | 10 ++++++++++ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/samples/bluetooth/hci_rpmsg/sample.yaml b/samples/bluetooth/hci_rpmsg/sample.yaml index 3330002a59d..7cecb12be67 100644 --- a/samples/bluetooth/hci_rpmsg/sample.yaml +++ b/samples/bluetooth/hci_rpmsg/sample.yaml @@ -82,6 +82,16 @@ tests: platform_allow: nrf5340dk_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet + sample.bluetooth.hci_rpmsg.df.no_phy_coded.bt_ll_sw_split: + harness: bluetooth + tags: bluetooth + extra_args: + - CONF_FILE="nrf5340_cpunet_df-bt_ll_sw_split.conf" + - DTC_OVERLAY_FILE="nrf5340_cpunet_df-bt_ll_sw_split.overlay" + - CONFIG_BT_CTLR_PHY_CODED=n + platform_allow: nrf5340dk_nrf5340_cpunet + integration_platforms: + - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.mesh.bt_ll_sw_split: harness: bluetooth tags: bluetooth diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 085b881d47e..71e5ffa0e6f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -582,6 +582,7 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI)); } +#if defined(CONFIG_BT_CTLR_PHY_CODED) && defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) { @@ -594,6 +595,7 @@ static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT( SW_SWITCH_TIMER_S2_EVTS_COMP(group_index)) = 0; } +#endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) From 4f1cd0e42858b8b7f02512bfca603332bc90edee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 6 Sep 2023 10:25:28 +0200 Subject: [PATCH 0775/4498] doc: Migrate subsys/ code samples to new Sphinx extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This migrates the subsys code samples to the new Sphinx code-sample extension, making it easier to find relevant samples when browsing API reference. Signed-off-by: Benjamin Cabé --- .../doc/index.rst | 2 +- .../adafruit_feather_m0_lora/doc/index.rst | 2 +- .../doc/index.rst | 2 +- .../adafruit_itsybitsy_nrf52840/doc/index.rst | 4 +- boards/arm/adafruit_trinket_m0/doc/index.rst | 2 +- boards/arm/arduino_mkrzero/doc/index.rst | 2 +- boards/arm/arduino_nano_33_iot/doc/index.rst | 2 +- boards/arm/arduino_zero/doc/index.rst | 2 +- .../arm/nrf52840dongle_nrf52840/doc/index.rst | 2 +- boards/arm/seeeduino_xiao/doc/index.rst | 2 +- boards/arm/serpente/doc/index.rst | 2 +- boards/arm/wio_terminal/doc/index.rst | 2 +- .../heltec_wifi_lora32_v2/doc/index.rst | 2 +- doc/connectivity/usb/device/usb_device.rst | 75 ++++++++++--------- .../usb/device_next/usb_device.rst | 6 +- doc/develop/west/sign.rst | 2 +- doc/services/device_mgmt/mcumgr.rst | 2 +- doc/services/device_mgmt/ota.rst | 6 +- .../backends/ipc_service_icmsg.rst | 2 +- doc/services/logging/index.rst | 3 +- doc/services/modbus/index.rst | 13 ++-- doc/services/settings/index.rst | 3 +- samples/subsys/canbus/isotp/README.rst | 13 ++-- samples/subsys/console/getchar/README.rst | 8 +- samples/subsys/console/getline/README.rst | 8 +- samples/subsys/debug/gdbstub/README.rst | 6 +- samples/subsys/display/cfb/README.rst | 7 +- .../subsys/display/cfb_custom_font/README.rst | 7 +- samples/subsys/display/cfb_shell/README.rst | 7 +- samples/subsys/display/lvgl/README.rst | 7 +- samples/subsys/edac/README.rst | 6 +- samples/subsys/fs/format/README.rst | 2 +- samples/subsys/fs/fs_sample/README.rst | 4 +- samples/subsys/input/input_dump/README.rst | 7 +- .../subsys/ipc/ipc_service/icmsg/README.rst | 7 +- .../ipc/ipc_service/static_vrings/README.rst | 7 +- samples/subsys/ipc/openamp/README.rst | 7 +- .../subsys/ipc/openamp_rsc_table/README.rst | 7 +- samples/subsys/ipc/rpmsg_service/README.rst | 7 +- samples/subsys/logging/ble_backend/README.rst | 7 +- samples/subsys/logging/dictionary/README.rst | 12 ++- samples/subsys/logging/logger/README.rst | 7 +- samples/subsys/lorawan/class_a/README.rst | 9 ++- samples/subsys/mgmt/hawkbit/README.rst | 9 ++- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 6 +- samples/subsys/mgmt/updatehub/README.rst | 7 +- samples/subsys/modbus/rtu_client/README.rst | 10 +-- samples/subsys/modbus/rtu_server/README.rst | 7 +- samples/subsys/modbus/tcp_gateway/README.rst | 11 +-- samples/subsys/modbus/tcp_server/README.rst | 7 +- samples/subsys/nvs/README.rst | 7 +- .../cmsis_rtos_v1/philosophers/README.rst | 6 +- .../timer_synchronization/README.rst | 6 +- .../cmsis_rtos_v2/philosophers/README.rst | 6 +- .../timer_synchronization/README.rst | 6 +- samples/subsys/sensing/simple/README.rst | 7 +- samples/subsys/settings/README.rst | 7 +- samples/subsys/shell/fs/README.rst | 7 +- samples/subsys/task_wdt/README.rst | 9 ++- samples/subsys/tracing/README.rst | 9 +-- .../audio/headphones_microphone/README.rst | 7 +- samples/subsys/usb/audio/headset/README.rst | 7 +- samples/subsys/usb/cdc_acm/README.rst | 7 +- .../subsys/usb/cdc_acm_composite/README.rst | 7 +- samples/subsys/usb/console/README.rst | 7 +- samples/subsys/usb/dfu/README.rst | 7 +- samples/subsys/usb/hid-cdc/README.rst | 7 +- samples/subsys/usb/hid-mouse/README.rst | 7 +- samples/subsys/usb/hid/README.rst | 7 +- samples/subsys/usb/mass/README.rst | 7 +- samples/subsys/usb/shell/README.rst | 9 ++- samples/subsys/usb/testusb/README.rst | 9 ++- samples/subsys/usb/webusb/README.rst | 11 +-- samples/subsys/usb_c/sink/README.rst | 7 +- samples/subsys/usb_c/source/README.rst | 7 +- 75 files changed, 286 insertions(+), 246 deletions(-) diff --git a/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst b/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst index 0e1943db6ff..4b1af3d8d49 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst +++ b/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst @@ -97,7 +97,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. Programming and Debugging diff --git a/boards/arm/adafruit_feather_m0_lora/doc/index.rst b/boards/arm/adafruit_feather_m0_lora/doc/index.rst index 5aa85132689..154feb14539 100644 --- a/boards/arm/adafruit_feather_m0_lora/doc/index.rst +++ b/boards/arm/adafruit_feather_m0_lora/doc/index.rst @@ -100,7 +100,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. LoRa Radio diff --git a/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst index 54cfa87d90a..aca89603ff5 100644 --- a/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst +++ b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst @@ -107,7 +107,7 @@ USB Device Port The SAMD51 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. Programming and Debugging diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst index 26de1d7c3b4..9096e8037c2 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst +++ b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst @@ -114,8 +114,8 @@ Push buttons Logging ------- -Logging is done using the USB-CDC port. See the :ref:`logger_sample` -or the :ref:`cdc-acm-console` sample applications to see how this works. +Logging is done using the USB-CDC port. See the :zephyr:code-sample:`logging` sample +or the :zephyr:code-sample:`usb-cdc-acm-console` sample applications to see how this works. Testing LEDs and buttons on the Adafruit ItsyBitsy nRF52840 Express ******************************************************************* diff --git a/boards/arm/adafruit_trinket_m0/doc/index.rst b/boards/arm/adafruit_trinket_m0/doc/index.rst index 5934589f93d..2512df3fd56 100644 --- a/boards/arm/adafruit_trinket_m0/doc/index.rst +++ b/boards/arm/adafruit_trinket_m0/doc/index.rst @@ -99,7 +99,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. Programming and Debugging diff --git a/boards/arm/arduino_mkrzero/doc/index.rst b/boards/arm/arduino_mkrzero/doc/index.rst index 3df9ea49d19..a64a9248bd0 100644 --- a/boards/arm/arduino_mkrzero/doc/index.rst +++ b/boards/arm/arduino_mkrzero/doc/index.rst @@ -112,7 +112,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. DAC diff --git a/boards/arm/arduino_nano_33_iot/doc/index.rst b/boards/arm/arduino_nano_33_iot/doc/index.rst index 64e89e717f5..dfcf2a6bbcb 100644 --- a/boards/arm/arduino_nano_33_iot/doc/index.rst +++ b/boards/arm/arduino_nano_33_iot/doc/index.rst @@ -103,7 +103,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. Programming and Debugging diff --git a/boards/arm/arduino_zero/doc/index.rst b/boards/arm/arduino_zero/doc/index.rst index f466a173e5f..4c686daff5e 100644 --- a/boards/arm/arduino_zero/doc/index.rst +++ b/boards/arm/arduino_zero/doc/index.rst @@ -99,7 +99,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. DAC diff --git a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst index 94da6423904..6cfe7329d2c 100644 --- a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst +++ b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst @@ -210,7 +210,7 @@ to the zephyr repository on your computer. nrfutil dfu usb-serial -pkg mcuboot.zip -p /dev/ttyACM0 You can now flash a Zephyr application to the board using MCUboot's serial -recovery mode. We'll use the :ref:`smp_svr_sample` since it's ready to be +recovery mode. We'll use the :zephyr:code-sample:`smp-svr` sample since it's ready to be compiled for chain-loading by MCUboot (and itself supports firmware updates over Bluetooth). diff --git a/boards/arm/seeeduino_xiao/doc/index.rst b/boards/arm/seeeduino_xiao/doc/index.rst index fb4ff4420a0..22693fed2ab 100644 --- a/boards/arm/seeeduino_xiao/doc/index.rst +++ b/boards/arm/seeeduino_xiao/doc/index.rst @@ -99,7 +99,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. DAC diff --git a/boards/arm/serpente/doc/index.rst b/boards/arm/serpente/doc/index.rst index c354631047f..c446103c712 100644 --- a/boards/arm/serpente/doc/index.rst +++ b/boards/arm/serpente/doc/index.rst @@ -75,7 +75,7 @@ USB Device Port The SAMD21 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for -more, such as the :ref:`usb_cdc-acm` sample which prints "Hello World!" +more, such as the :zephyr:code-sample:`usb-cdc-acm` sample which prints "Hello World!" to the host PC. Programming and Debugging diff --git a/boards/arm/wio_terminal/doc/index.rst b/boards/arm/wio_terminal/doc/index.rst index 5ccd90061c2..56a13748ac6 100644 --- a/boards/arm/wio_terminal/doc/index.rst +++ b/boards/arm/wio_terminal/doc/index.rst @@ -122,7 +122,7 @@ USB Device Port The SAMD51 MCU has a USB device port that can be used to communicate with a host PC. See the :ref:`usb-samples` sample applications for more, such as the -:ref:`usb_cdc-acm` sample which sets up a virtual serial port that echos +:zephyr:code-sample:`usb-cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. Programming and Debugging diff --git a/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst b/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst index 658c6083182..69ad019e52e 100644 --- a/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst +++ b/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst @@ -188,7 +188,7 @@ Onboard OLED display The onboard OLED display is of type ``ssd1306``, has 128*64 pixels and is connected via I2C. It can therefore be used by enabling the -:ref:`ssd1306_128_shield` as shown in the following for the :ref:`lvgl-sample`: +:ref:`ssd1306_128_shield` as shown in the following for the :zephyr:code-sample:`lvgl` sample: .. zephyr-app-commands:: :zephyr-app: samples/subsys/display/lvgl diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index 19fd5e61577..5e394a20457 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -39,7 +39,8 @@ Audio There is an experimental implementation of the Audio class. It follows specification version 1.00 (``bcdADC 0x0100``) and supports synchronous synchronisation type only. -See :ref:`usb_audio_headphones_microphone` and :ref:`usb_audio_headset` for reference. +See :zephyr:code-sample:`usb-audio-headphones-microphone` and +:zephyr:code-sample:`usb-audio-headset` samples for reference. Bluetooth HCI USB transport layer ================================= @@ -106,7 +107,7 @@ and looks like this: }; }; -Samples :ref:`usb_cdc-acm` and :ref:`usb_hid-cdc` have similar overlay files. +Samples :zephyr:code-sample:`usb-cdc-acm` and :zephyr:code-sample:`usb-hid-cdc` have similar overlay files. And since no special properties are present, it may seem overkill to use devicetree to describe CDC ACM UART. The motivation behind using devicetree is the easy interchangeability of a real UART controller and CDC ACM UART @@ -117,7 +118,7 @@ Console over CDC ACM UART With the CDC ACM UART node from above and ``zephyr,console`` property of the chosen node, we can describe that CDC ACM UART is to be used with the console. -A similar overlay file is used by :ref:`cdc-acm-console`. +A similar overlay file is used by the :zephyr:code-sample:`usb-cdc-acm-console` sample. .. code-block:: devicetree @@ -169,7 +170,7 @@ CDC ACM UART as backend for a subsystem or application: for example see :zephyr:code-sample:`coprocessor` * ``zephyr,shell-uart`` used by shell for serial backend, for example see :zephyr_file:`samples/subsys/shell/shell_module` -* ``zephyr,uart-mcumgr`` used by :ref:`smp_svr_sample` +* ``zephyr,uart-mcumgr`` used by :zephyr:code-sample:`smp-svr` sample DFU === @@ -177,7 +178,7 @@ DFU USB DFU class implementation is tightly coupled to :ref:`dfu` and :ref:`mcuboot_api`. This means that the target platform must support the :ref:`flash_img_api` API. -See :ref:`usb_dfu` for reference. +See :zephyr:code-sample:`usb-dfu` sample for reference. USB Human Interface Devices (HID) support ========================================= @@ -276,7 +277,7 @@ The disadvantage of this is that Kconfig options such as :kconfig:option:`CONFIG_HID_INTERRUPT_EP_MPS` apply to all instances. This design issue will be fixed in the HID class implementation for the new USB support. -See :ref:`usb_hid` or :ref:`usb_hid-mouse` for reference. +See :zephyr:code-sample:`usb-hid` or :zephyr:code-sample:`usb-hid-mouse` sample for reference. Mass Storage Class ================== @@ -327,7 +328,7 @@ should be the same as ``disk-name`` property. The ``disk-property`` "NAND" may be confusing, but it is simply how some file systems identifies the disc. Therefore, if the application also accesses the file system on the exposed disc, default names should be used, see -:ref:`usb_mass` for reference. +:zephyr:code-sample:`usb-mass` sample for reference. Networking ========== @@ -355,7 +356,7 @@ The application should register descriptors such as Capability Descriptor using :c:func:`usb_bos_register_cap`. Registered descriptors are added to the root BOS descriptor and handled by the stack. -See :ref:`webusb-sample` for reference. +See :zephyr:code-sample:`webusb` sample for reference. Implementing a non-standard USB class ************************************* @@ -473,35 +474,35 @@ and documented requests. The following Product IDs are currently used: -+-------------------------------------+--------+ -| Sample | PID | -+=====================================+========+ -| :ref:`usb_cdc-acm` | 0x0001 | -+-------------------------------------+--------+ -| :ref:`usb_cdc-acm_composite` | 0x0002 | -+-------------------------------------+--------+ -| :ref:`usb_hid-cdc` | 0x0003 | -+-------------------------------------+--------+ -| :ref:`cdc-acm-console` | 0x0004 | -+-------------------------------------+--------+ -| :ref:`usb_dfu` | 0x0005 | -+-------------------------------------+--------+ -| :ref:`usb_hid` | 0x0006 | -+-------------------------------------+--------+ -| :ref:`usb_hid-mouse` | 0x0007 | -+-------------------------------------+--------+ -| :ref:`usb_mass` | 0x0008 | -+-------------------------------------+--------+ -| :ref:`testusb-app` | 0x0009 | -+-------------------------------------+--------+ -| :ref:`webusb-sample` | 0x000A | -+-------------------------------------+--------+ -| :ref:`bluetooth-hci-usb-sample` | 0x000B | -+-------------------------------------+--------+ -| :ref:`bluetooth-hci-usb-h4-sample` | 0x000C | -+-------------------------------------+--------+ -| :zephyr:code-sample:`wpan-usb` | 0x000D | -+-------------------------------------+--------+ ++----------------------------------------------------+--------+ +| Sample | PID | ++====================================================+========+ +| :zephyr:code-sample:`usb-cdc-acm` | 0x0001 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-cdc-acm-composite` | 0x0002 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-hid-cdc` | 0x0003 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-cdc-acm-console` | 0x0004 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-dfu` | 0x0005 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-hid` | 0x0006 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-hid-mouse` | 0x0007 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`usb-mass` | 0x0008 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`testusb-app` | 0x0009 | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`webusb` | 0x000A | ++----------------------------------------------------+--------+ +| :ref:`bluetooth-hci-usb-sample` | 0x000B | ++----------------------------------------------------+--------+ +| :ref:`bluetooth-hci-usb-h4-sample` | 0x000C | ++----------------------------------------------------+--------+ +| :zephyr:code-sample:`wpan-usb` | 0x000D | ++----------------------------------------------------+--------+ The USB device descriptor field ``bcdDevice`` (Device Release Number) represents the Zephyr kernel major and minor versions as a binary coded decimal value. diff --git a/doc/connectivity/usb/device_next/usb_device.rst b/doc/connectivity/usb/device_next/usb_device.rst index 1ef6f7ef933..a9009d54e2b 100644 --- a/doc/connectivity/usb/device_next/usb_device.rst +++ b/doc/connectivity/usb/device_next/usb_device.rst @@ -14,7 +14,7 @@ class API that should be used to implement the functions (classes). It will replace :ref:`usb_device_stack`. If you would like to play around with the new device support, or the new USB -support in general, please try :ref:`usb_shell-app`. The sample is mainly to help +support in general, please try :zephyr:code-sample:`usb-shell` sample. The sample is mainly to help test the capabilities of the stack and correct implementation of the USB controller drivers. @@ -33,14 +33,14 @@ CDC ACM CDC ACM implementation has support for multiple instances. Description from :ref:`usb_device_cdc_acm` also applies to the new implementation. -See :ref:`usb_cdc-acm` sample for reference. +See :zephyr:code-sample:`usb-cdc-acm` sample for reference. To build the sample for the new device support, set the configuration ``-DCONF_FILE=usbd_next_prj.conf`` either directly or via ``west``. Mass Storage Class ================== -See :ref:`usb_mass` sample for reference. +See :zephyr:code-sample:`usb-mass` sample for reference. To build the sample for the new device support, set the configuration ``-DCONF_FILE=usbd_next_prj.conf`` either directly or via ``west``. diff --git a/doc/develop/west/sign.rst b/doc/develop/west/sign.rst index 0606da34dc3..44193d4611f 100644 --- a/doc/develop/west/sign.rst +++ b/doc/develop/west/sign.rst @@ -42,7 +42,7 @@ Notes on the above commands: - The ``CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`` value is the insecure default provided and used by by MCUboot for development and testing - You can change the ``hello_world`` application directory to any other - application that can be loaded by MCUboot, such as the :ref:`smp_svr_sample` + application that can be loaded by MCUboot, such as the :zephyr:code-sample:`smp-svr` sample. For more information on these and other related configuration options, see: diff --git a/doc/services/device_mgmt/mcumgr.rst b/doc/services/device_mgmt/mcumgr.rst index 568525ba5d1..f868aaceb17 100644 --- a/doc/services/device_mgmt/mcumgr.rst +++ b/doc/services/device_mgmt/mcumgr.rst @@ -30,7 +30,7 @@ systems. The management subsystem is located in :zephyr_file:`subsys/mgmt/` inside of the Zephyr tree. -Additionally, there is a :ref:`sample ` that provides +Additionally, there is a :zephyr:code-sample:`sample ` sample that provides management functionality over BLE and serial. .. _mcumgr_cli: diff --git a/doc/services/device_mgmt/ota.rst b/doc/services/device_mgmt/ota.rst index 8f400582740..30a6a5b7cbc 100644 --- a/doc/services/device_mgmt/ota.rst +++ b/doc/services/device_mgmt/ota.rst @@ -44,7 +44,7 @@ REST api to detect firmware updates. When a new update is detected, the binary is downloaded and installed. MCUboot can be used to verify the signature before upgrading the firmware. -There is a :ref:`hawkbit-api-sample` included in the +There is a :zephyr:code-sample:`hawkbit-api` sample included in the Zephyr :ref:`mgmt-samples` section. UpdateHub @@ -55,7 +55,7 @@ be manually triggered or monitored via polling. When a new update is detected, the binary is downloaded and installed. MCUboot can be used to verify the signature before upgrading the firmware. -There is an :ref:`updatehub_fota_sample` included in the Zephyr +There is an :zephyr:code-sample:`updatehub-fota` sample included in the Zephyr :ref:`mgmt-samples` section. SMP Server @@ -66,7 +66,7 @@ Bluetooth Low Energy (BLE) or UDP. :ref:`mcu_mgr` is used to send a signed firmware binary to the remote device where it is verified by MCUboot before the upgrade occurs. -There is an :ref:`smp_svr_sample` included in the Zephyr :ref:`mgmt-samples` +There is an :zephyr:code-sample:`smp-svr` sample included in the Zephyr :ref:`mgmt-samples` section. Lightweight M2M (LWM2M) diff --git a/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst b/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst index 32fb2cbf6aa..2fd67bff195 100644 --- a/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst +++ b/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst @@ -83,4 +83,4 @@ and the backend informs the application by calling Samples ======= - - :ref:`ipc_icmsg_sample` + - :zephyr:code-sample:`ipc-icmsg` diff --git a/doc/services/logging/index.rst b/doc/services/logging/index.rst index c1ee1bf6d9a..8201e728b9a 100644 --- a/doc/services/logging/index.rst +++ b/doc/services/logging/index.rst @@ -734,7 +734,8 @@ hexadecimal characters (e.g. when ``CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX=y``). This tells the parser to convert the hexadecimal characters to binary before parsing. -Please refer to :ref:`logging_dictionary_sample` on how to use the log parser. +Please refer to the :zephyr:code-sample:`logging-dictionary` sample to learn more on how to use +the log parser. Recommendations diff --git a/doc/services/modbus/index.rst b/doc/services/modbus/index.rst index 51b3780d6b1..a263e1eeb7f 100644 --- a/doc/services/modbus/index.rst +++ b/doc/services/modbus/index.rst @@ -25,14 +25,11 @@ More information about Modbus and Modbus RTU can be found on the website Samples ******* -:ref:`modbus-rtu-server-sample` and :ref:`modbus-rtu-client-sample` give -the possibility to try out RTU server and RTU client implementation with -an evaluation board. - -:ref:`modbus-tcp-server-sample` is a simple Modbus TCP server. - -:ref:`modbus-gateway-sample` is an example how to build a TCP to serial line -gateway with Zephyr OS. +* :zephyr:code-sample:`modbus-rtu-server` and :zephyr:code-sample:`modbus-rtu-client` samples give + the possibility to try out RTU server and RTU client implementation with an evaluation board. +* :zephyr:code-sample:`modbus-tcp-server` sample is a simple Modbus TCP server. +* :zephyr:code-sample:`modbus-gateway` sample shows how to build a TCP to serial line + gateway with Zephyr OS. API Reference ************* diff --git a/doc/services/settings/index.rst b/doc/services/settings/index.rst index 61f0a2b82a7..fa6d7360052 100644 --- a/doc/services/settings/index.rst +++ b/doc/services/settings/index.rst @@ -19,8 +19,7 @@ element for the package ``id``. Convenience routines are provided for converting a key value to and from a string type. -For an example of the settings subsystem refer to -:ref:`the sample `. +For an example of the settings subsystem refer to :zephyr:code-sample:`settings` sample. .. note:: diff --git a/samples/subsys/canbus/isotp/README.rst b/samples/subsys/canbus/isotp/README.rst index 378ecd03e4e..4a9d2019bc5 100644 --- a/samples/subsys/canbus/isotp/README.rst +++ b/samples/subsys/canbus/isotp/README.rst @@ -1,14 +1,17 @@ -.. _isotp-sample: +.. zephyr:code-sample:: isotp + :name: ISO-TP library + :relevant-api: can_isotp -ISO-TP library -############## + Use ISO-TP library to exchange messages between two boards. Overview ******** -This sample demonstrates how to use the ISO-TP library. +This sample demonstrates how to use the :ref:`ISO-TP library `. + Messages are exchanged between two boards. A long message, that is sent with -a block-size (BS) of eight frames, and a short one that has an minimal +a block-size (BS) of eight frames, and a short one that has a minimal separation-time (STmin) of five milliseconds. + The send function call for the short message is non-blocking, and the send function call for the long message is blocking. diff --git a/samples/subsys/console/getchar/README.rst b/samples/subsys/console/getchar/README.rst index eddfb83671f..54dc7e8fc48 100644 --- a/samples/subsys/console/getchar/README.rst +++ b/samples/subsys/console/getchar/README.rst @@ -1,7 +1,7 @@ -.. _console_getchar_sample: +.. zephyr:code-sample:: console_getchar + :name: console_getchar() -console_getchar() Sample Application -#################################### + Use console_getchar() to read an input character from the console. Overview ******** @@ -15,7 +15,7 @@ process console input character by character. The sample also allows to see key/character codes as returned by the function. If you are interested in line by line console input, see -:ref:`console_getline_sample`. +:zephyr:code-sample:`console_getline`. Requirements diff --git a/samples/subsys/console/getline/README.rst b/samples/subsys/console/getline/README.rst index f10cbf791c1..6c7e05f4f8d 100644 --- a/samples/subsys/console/getline/README.rst +++ b/samples/subsys/console/getline/README.rst @@ -1,7 +1,7 @@ -.. _console_getline_sample: +.. zephyr:code-sample:: console_getline + :name: console_getline() -console_getline() Sample Application -#################################### + Use console_getline() to read an input line from the console. Overview ******** @@ -15,7 +15,7 @@ console input line by line. The sample also allows to see details of how a line is returned by the function. If you are interested in character by character console input, see -:ref:`console_getchar_sample`. +:zephyr:code-sample:`console_getchar`. Requirements diff --git a/samples/subsys/debug/gdbstub/README.rst b/samples/subsys/debug/gdbstub/README.rst index b2f6af74b96..dc8430cd339 100644 --- a/samples/subsys/debug/gdbstub/README.rst +++ b/samples/subsys/debug/gdbstub/README.rst @@ -1,7 +1,7 @@ -.. _gdb_debug_sample: +.. zephyr:code-sample:: gdb-debug + :name: GDB debug -GDB Debug Sample -################ + Use GDB Remote Serial Protocol to debug a Zephyr application running on QEMU. Overview ******** diff --git a/samples/subsys/display/cfb/README.rst b/samples/subsys/display/cfb/README.rst index 8e9a71de3a4..093fed8f11c 100644 --- a/samples/subsys/display/cfb/README.rst +++ b/samples/subsys/display/cfb/README.rst @@ -1,7 +1,8 @@ -.. _character_frame_buffer_sample: +.. zephyr:code-sample:: character-frame-buffer + :name: Character frame buffer + :relevant-api: monochrome_character_framebuffer -Character frame buffer -###################### + Display character strings using the Character Frame Buffer (CFB). Overview ******** diff --git a/samples/subsys/display/cfb_custom_font/README.rst b/samples/subsys/display/cfb_custom_font/README.rst index 369f22236b1..1e5dea47535 100644 --- a/samples/subsys/display/cfb_custom_font/README.rst +++ b/samples/subsys/display/cfb_custom_font/README.rst @@ -1,7 +1,8 @@ -.. _cfb_custom_fonts: +.. zephyr:code-sample:: cfb-custom-fonts + :name: Custom fonts + :relevant-api: monochrome_character_framebuffer -Custom Fonts -############ + Generate and use a custom font. Overview ******** diff --git a/samples/subsys/display/cfb_shell/README.rst b/samples/subsys/display/cfb_shell/README.rst index e17422015ab..3e118aba9a4 100644 --- a/samples/subsys/display/cfb_shell/README.rst +++ b/samples/subsys/display/cfb_shell/README.rst @@ -1,7 +1,8 @@ -.. _cfb_shell_sample: +.. zephyr:code-sample:: cfb-shell-sample + :name: Character Framebuffer shell module + :relevant-api: monochrome_character_framebuffer -Character Framebuffer Shell Module Sample -######################################### + Use the CFB shell module to interact with a monochrome display. Overview ******** diff --git a/samples/subsys/display/lvgl/README.rst b/samples/subsys/display/lvgl/README.rst index fde1d2780ec..e7312a2791b 100644 --- a/samples/subsys/display/lvgl/README.rst +++ b/samples/subsys/display/lvgl/README.rst @@ -1,7 +1,8 @@ -.. _lvgl-sample: +.. zephyr:code-sample:: lvgl + :name: LVGL basic sample + :relevant-api: display_interface -LVGL Basic Sample -################# + Display "Hello World" and a dynamic counter using LVGL. Overview ******** diff --git a/samples/subsys/edac/README.rst b/samples/subsys/edac/README.rst index bcac44df86f..2548284928a 100644 --- a/samples/subsys/edac/README.rst +++ b/samples/subsys/edac/README.rst @@ -1,13 +1,13 @@ -.. zephyr:code-sample:: edac-sample +.. zephyr:code-sample:: edac :name: EDAC shell :relevant-api: edac - EDAC Shell Sample + Test error detection and correction (EDAC) using shell commands. Overview ******** -This sample demonstrates the EDAC driver API in a simple EDAC shell sample. +This sample demonstrates the :ref:`EDAC driver API ` in a simple EDAC shell sample. Building and Running ******************** diff --git a/samples/subsys/fs/format/README.rst b/samples/subsys/fs/format/README.rst index 20bcad1931a..1801af34306 100644 --- a/samples/subsys/fs/format/README.rst +++ b/samples/subsys/fs/format/README.rst @@ -1,5 +1,5 @@ .. zephyr:code-sample:: fs-format - :name: Formatting + :name: Format filesystem :relevant-api: file_system_api Format different storage devices for different file systems. diff --git a/samples/subsys/fs/fs_sample/README.rst b/samples/subsys/fs/fs_sample/README.rst index e23cc1db7f9..e53068b92c7 100644 --- a/samples/subsys/fs/fs_sample/README.rst +++ b/samples/subsys/fs/fs_sample/README.rst @@ -1,8 +1,8 @@ .. zephyr:code-sample:: fs - :name: Filesystem manipulation + :name: File system manipulation :relevant-api: file_system_api disk_access_interface - Use filesystem API with various filesystems and storage devices. + Use file system API with various filesystems and storage devices. Overview ******** diff --git a/samples/subsys/input/input_dump/README.rst b/samples/subsys/input/input_dump/README.rst index 8a02f104ec8..0492f02b831 100644 --- a/samples/subsys/input/input_dump/README.rst +++ b/samples/subsys/input/input_dump/README.rst @@ -1,7 +1,8 @@ -.. _input-dump-sample: +.. zephyr:code-sample:: input-dump + :name: Input dump + :relevant-api: input_events -Input Dump -########## + Print all input events. Overview ******** diff --git a/samples/subsys/ipc/ipc_service/icmsg/README.rst b/samples/subsys/ipc/ipc_service/icmsg/README.rst index ce052214986..81426ee9353 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/README.rst +++ b/samples/subsys/ipc/ipc_service/icmsg/README.rst @@ -1,7 +1,8 @@ -.. _ipc_icmsg_sample: +.. zephyr:code-sample:: ipc-icmsg + :name: IPC service: icmsg backend + :relevant-api: ipc -IPC Service - icmsg - Sample Application -######################################## + Send messages between two cores using the IPC service and icmsg backend. Overview ******** diff --git a/samples/subsys/ipc/ipc_service/static_vrings/README.rst b/samples/subsys/ipc/ipc_service/static_vrings/README.rst index 59df32c833e..e9633ad63d6 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/README.rst +++ b/samples/subsys/ipc/ipc_service/static_vrings/README.rst @@ -1,7 +1,8 @@ -.. _static_vrings_sample: +.. zephyr:code-sample:: ipc-static-vrings + :name: IPC service: static vrings backend + :relevant-api: ipc -IPC Service - static vrings - Sample Application -################################################ + Send messages between two cores using the IPC service and static vrings backend. Overview ******** diff --git a/samples/subsys/ipc/openamp/README.rst b/samples/subsys/ipc/openamp/README.rst index fb54261f14f..1ad79dff354 100644 --- a/samples/subsys/ipc/openamp/README.rst +++ b/samples/subsys/ipc/openamp/README.rst @@ -1,7 +1,8 @@ -.. _openAMP_sample: +.. zephyr:code-sample:: openamp + :name: OpenAMP + :relevant-api: ipm_interface -OpenAMP Sample Application -########################## + Send messages between two cores using OpenAMP. Overview ******** diff --git a/samples/subsys/ipc/openamp_rsc_table/README.rst b/samples/subsys/ipc/openamp_rsc_table/README.rst index 313ebb18888..95eaabfae60 100644 --- a/samples/subsys/ipc/openamp_rsc_table/README.rst +++ b/samples/subsys/ipc/openamp_rsc_table/README.rst @@ -1,7 +1,8 @@ -.. _openAMP_rsc_table_sample: +.. zephyr:code-sample:: openamp-rsc-table + :name: OpenAMP using resource table + :relevant-api: ipm_interface -OpenAMP Sample Application using resource table -############################################### + Send messages between two cores using OpenAMP and a resource table. Overview ******** diff --git a/samples/subsys/ipc/rpmsg_service/README.rst b/samples/subsys/ipc/rpmsg_service/README.rst index bcc35d70e43..ce32b16b61e 100644 --- a/samples/subsys/ipc/rpmsg_service/README.rst +++ b/samples/subsys/ipc/rpmsg_service/README.rst @@ -1,7 +1,8 @@ -.. _RPMsg_Service_sample: +.. zephyr:code-sample:: rpmsg-service + :name: RPMsg service + :relevant-api: rpmsg_service_api -RPMsg Service sample Application -################################ + Send messages between cores using RPMsg service. Overview ******** diff --git a/samples/subsys/logging/ble_backend/README.rst b/samples/subsys/logging/ble_backend/README.rst index 2c3726dc0bf..8324bbbd99f 100644 --- a/samples/subsys/logging/ble_backend/README.rst +++ b/samples/subsys/logging/ble_backend/README.rst @@ -1,7 +1,8 @@ -.. _logger_ble_backend: +.. zephyr:code-sample:: logging-ble-backend + :name: BLE logging backend + :relevant-api: log_api log_backend bt_gatt -Logging: BLE Backend -######################## + Send log messages over BLE using the BLE logging backend. Overview ******** diff --git a/samples/subsys/logging/dictionary/README.rst b/samples/subsys/logging/dictionary/README.rst index be7176b9af4..2253ff18320 100644 --- a/samples/subsys/logging/dictionary/README.rst +++ b/samples/subsys/logging/dictionary/README.rst @@ -1,9 +1,13 @@ -.. _logging_dictionary_sample: +.. zephyr:code-sample:: logging-dictionary + :name: Dictionary-based logging + :relevant-api: log_api -Dictionary-based Logging Sample -############################### + Output binary log data using the dictionary-based logging API. -This is a sample app which utilizes dictionary based logging and +Overview +******** + +This is a sample app which utilizes :ref:`dictionary-based logging ` and the UART backend. This is configured to output binary log data in hexadecimal so it could be run in terminal. diff --git a/samples/subsys/logging/logger/README.rst b/samples/subsys/logging/logger/README.rst index e3ed5e04e64..e82247efe94 100644 --- a/samples/subsys/logging/logger/README.rst +++ b/samples/subsys/logging/logger/README.rst @@ -1,7 +1,8 @@ -.. _logger_sample: +.. zephyr:code-sample:: logging + :name: Logging + :relevant-api: log_api log_ctrl -Logging -########### + Output log messages to the console using the logging subsystem. Overview ******** diff --git a/samples/subsys/lorawan/class_a/README.rst b/samples/subsys/lorawan/class_a/README.rst index ba72fe1d4da..3a7a7944997 100644 --- a/samples/subsys/lorawan/class_a/README.rst +++ b/samples/subsys/lorawan/class_a/README.rst @@ -1,12 +1,13 @@ -.. _lorawan_class_a_sample: +.. zephyr:code-sample:: lorawan-class-a + :name: LoRaWAN class A device + :relevant-api: lorawan_api -LoRaWAN Class A Sample -###################### + Join a LoRaWAN network and send a message periodically. Overview ******** -A simple application to demonstrate the LoRaWAN subsystem of Zephyr. +A simple application to demonstrate the :ref:`LoRaWAN subsystem ` of Zephyr. Building and Running ******************** diff --git a/samples/subsys/mgmt/hawkbit/README.rst b/samples/subsys/mgmt/hawkbit/README.rst index 1a0e095529b..db96c518213 100644 --- a/samples/subsys/mgmt/hawkbit/README.rst +++ b/samples/subsys/mgmt/hawkbit/README.rst @@ -1,12 +1,13 @@ -.. _hawkbit-api-sample: +.. zephyr:code-sample:: hawkbit-api + :name: Eclipse hawkBit Direct Device Integration API + :relevant-api: hawkbit -Hawkbit Direct Device Integration API sample -############################################ + Update a device using Eclipse hawkBit DDI API. Overview ******** -The hawkbit update server provides REST resources which are consumed by the +The Eclipse hawkBit update server provides REST resources which are consumed by the device to retrieve software update tasks. This API is based on HTTP standards and a polling mechanism. diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index c988e414564..c24103815af 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -1,7 +1,7 @@ -.. _smp_svr_sample: +.. zephyr:code-sample:: smp-svr + :name: SMP server -SMP Server Sample -################# + Implement a Simple Management Protocol (SMP) server. Overview ******** diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index 3f19982f838..ad29354146e 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -1,7 +1,8 @@ -.. _updatehub_fota_sample: +.. zephyr:code-sample:: updatehub-fota + :name: UpdateHub embedded Firmware Over-The-Air (FOTA) update + :relevant-api: updatehub -UpdateHub embedded Firmware Over-The-Air (FOTA) sample -###################################################### + Perform Firmware Over-The-Air (FOTA) updates using UpdateHub. Overview ******** diff --git a/samples/subsys/modbus/rtu_client/README.rst b/samples/subsys/modbus/rtu_client/README.rst index 1159cfa771f..a432a07b83e 100644 --- a/samples/subsys/modbus/rtu_client/README.rst +++ b/samples/subsys/modbus/rtu_client/README.rst @@ -1,7 +1,8 @@ -.. _modbus-rtu-client-sample: +.. zephyr:code-sample:: modbus-rtu-client + :name: Modbus RTU client + :relevant-api: modbus -Modbus RTU Client Sample -######################## + Communicate with a Modbus RTU server. Overview ******** @@ -16,8 +17,7 @@ This sample has been tested with the nRF52840-DK and FRDM-K64F boards, but it should work with any board that has a free UART interface. RTU client example is running on an evaluation board and communicates -with another board that has been prepared according to the description -`modbus-rtu-server-sample`. +with another board running the :zephyr:code-sample:`modbus-rtu-server` sample. In addition to the evaluation board a RS-485 shield may be used. The shield converts UART TX, RX signals to RS-485. diff --git a/samples/subsys/modbus/rtu_server/README.rst b/samples/subsys/modbus/rtu_server/README.rst index 973339e1cb7..289aa73ea7b 100644 --- a/samples/subsys/modbus/rtu_server/README.rst +++ b/samples/subsys/modbus/rtu_server/README.rst @@ -1,7 +1,8 @@ -.. _modbus-rtu-server-sample: +.. zephyr:code-sample:: modbus-rtu-server + :name: Modbus RTU server + :relevant-api: modbus -Modbus RTU Server Sample -######################## + Implement a Modbus RTU server exposing Modbus commands to control LEDs. Overview ******** diff --git a/samples/subsys/modbus/tcp_gateway/README.rst b/samples/subsys/modbus/tcp_gateway/README.rst index eeb13c0c5d9..5fbc02b41ef 100644 --- a/samples/subsys/modbus/tcp_gateway/README.rst +++ b/samples/subsys/modbus/tcp_gateway/README.rst @@ -1,7 +1,8 @@ -.. _modbus-gateway-sample: +.. zephyr:code-sample:: modbus-gateway + :name: Modbus TCP-to-serial gateway + :relevant-api: modbus bsd_sockets -Modbus TCP to serial line gateway sample -######################################## + Implement a gateway between an Ethernet TCP-IP network and a Modbus serial line. Overview ******** @@ -16,8 +17,8 @@ This sample has been tested with FRDM-K64F board, but it should work with any board or shield that has a network interface. Gateway example is running on an evaluation board and communicates -with another board that has been prepared according to the description -`modbus-rtu-server-sample`. Client is running on a PC or laptop. +with another board that has been prepared according to the instructions in +:zephyr:code-sample:`modbus-rtu-server` sample. Client is running on a PC or laptop. The description of this sample uses `PyModbus`_ (Pymodbus REPL). The user can of course try out other client implementations with this sample. diff --git a/samples/subsys/modbus/tcp_server/README.rst b/samples/subsys/modbus/tcp_server/README.rst index d994d1044c8..1b3f777db45 100644 --- a/samples/subsys/modbus/tcp_server/README.rst +++ b/samples/subsys/modbus/tcp_server/README.rst @@ -1,7 +1,8 @@ -.. _modbus-tcp-server-sample: +.. zephyr:code-sample:: modbus-tcp-server + :name: Modbus TCP server + :relevant-api: modbus bsd_sockets -Modbus TCP Server Sample -######################## + Implement a Modbus TCP server exposing Modbus commands to control LEDs. Overview ******** diff --git a/samples/subsys/nvs/README.rst b/samples/subsys/nvs/README.rst index b9a59b0fa75..ac1df6f9cf7 100644 --- a/samples/subsys/nvs/README.rst +++ b/samples/subsys/nvs/README.rst @@ -1,7 +1,8 @@ -.. _nvs-sample: +.. zephyr:code-sample:: nvs + :name: Non-Volatile Storage (NVS) + :relevant-api: nvs_high_level_api -NVS: Non-Volatile Storage -######################### + Store and retrieve data from flash using the NVS API. Overview ******** diff --git a/samples/subsys/portability/cmsis_rtos_v1/philosophers/README.rst b/samples/subsys/portability/cmsis_rtos_v1/philosophers/README.rst index 5e8d70f1a60..6817cae7883 100644 --- a/samples/subsys/portability/cmsis_rtos_v1/philosophers/README.rst +++ b/samples/subsys/portability/cmsis_rtos_v1/philosophers/README.rst @@ -1,7 +1,7 @@ -.. _cmsis_rtos_v1-sample: +.. zephyr:code-sample:: cmsis-rtos-v1 + :name: Dining Philosophers (CMSIS RTOS V1 APIs) -Dining Philosophers (CMSIS RTOS V1 APIs) -######################################## + Implement a solution to the Dining Philosophers problem using CMSIS RTOS V1. Overview ******** diff --git a/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/README.rst b/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/README.rst index 68db8860a75..53b76b3f182 100644 --- a/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/README.rst +++ b/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/README.rst @@ -1,7 +1,7 @@ -.. _cmsis_rtos_v1-sync_sample: +.. zephyr:code-sample:: cmsis-rtos-v1-sync + :name: Synchronization using CMSIS RTOS V1 APIs -Synchronization using CMSIS RTOS V1 APIs -######################################## + Use timers and message queues from CMSIS RTOS v1 API to synchronize threads. Overview ******** diff --git a/samples/subsys/portability/cmsis_rtos_v2/philosophers/README.rst b/samples/subsys/portability/cmsis_rtos_v2/philosophers/README.rst index a87af61973c..e5889223ceb 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/philosophers/README.rst +++ b/samples/subsys/portability/cmsis_rtos_v2/philosophers/README.rst @@ -1,7 +1,7 @@ -.. _cmsis_rtos_v2-sample: +.. zephyr:code-sample:: cmsis-rtos-v2 + :name: Dining Philosophers (CMSIS RTOS V2 APIs) -Dining Philosophers (CMSIS RTOS V2 APIs) -######################################## + Implement a solution to the Dining Philosophers problem using CMSIS RTOS V2. Overview ******** diff --git a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/README.rst b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/README.rst index 0acee5e1883..e5c2d1f8ff4 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/README.rst +++ b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/README.rst @@ -1,7 +1,7 @@ -.. _cmsis_rtos_v2-sync_sample: +.. zephyr:code-sample:: cmsis-rtos-v2-sync + :name: Synchronization using CMSIS RTOS V2 APIs -Synchronization using CMSIS RTOS V2 APIs -######################################## + Use timers and message queues from CMSIS RTOS v2 API to synchronize threads. Overview ******** diff --git a/samples/subsys/sensing/simple/README.rst b/samples/subsys/sensing/simple/README.rst index 11a72341fcb..b24d4868585 100644 --- a/samples/subsys/sensing/simple/README.rst +++ b/samples/subsys/sensing/simple/README.rst @@ -1,7 +1,8 @@ -.. _sensing subsytem-sample: +.. zephyr:code-sample:: sensing + :name: Sensing subsystem + :relevant-api: sensing_api -Sensing subsystem sample -######################## + Get high-level sensor data in defined intervals. Overview ******** diff --git a/samples/subsys/settings/README.rst b/samples/subsys/settings/README.rst index 9a986735bf2..82f8b797e86 100644 --- a/samples/subsys/settings/README.rst +++ b/samples/subsys/settings/README.rst @@ -1,7 +1,8 @@ -.. _settings_subsys_sample: +.. zephyr:code-sample:: settings + :name: Settings API + :relevant-api: settings settings_rt settings_name_proc -Settings sample -############### + Load and save configuration values using the settings API. Overview ******** diff --git a/samples/subsys/shell/fs/README.rst b/samples/subsys/shell/fs/README.rst index ec9d95364a7..d8bdecae6cd 100644 --- a/samples/subsys/shell/fs/README.rst +++ b/samples/subsys/shell/fs/README.rst @@ -1,7 +1,8 @@ -.. _shell-fs-sample: +.. zephyr:code-sample:: shell-fs + :name: File system shell + :relevant-api: file_system_api -File system shell example -######################### + Access a LittleFS file system partition in flash using the file system shell. Overview ******** diff --git a/samples/subsys/task_wdt/README.rst b/samples/subsys/task_wdt/README.rst index 03cfd7e90c3..21372f87d2d 100644 --- a/samples/subsys/task_wdt/README.rst +++ b/samples/subsys/task_wdt/README.rst @@ -1,12 +1,13 @@ -.. _task_wdt_sample: +.. zephyr:code-sample:: task-wdt + :name: Task watchdog + :relevant-api: task_wdt_api -Task Watchdog Sample -#################### + Monitor a thread using a task watchdog. Overview ******** -This sample allows to test the task watchdog subsystem. +This sample allows to test the :ref:`task watchdog ` subsystem. Building and Running ******************** diff --git a/samples/subsys/tracing/README.rst b/samples/subsys/tracing/README.rst index df736046ced..5214e35ce48 100644 --- a/samples/subsys/tracing/README.rst +++ b/samples/subsys/tracing/README.rst @@ -1,10 +1,7 @@ -.. _tracing_sample: +.. zephyr:code-sample:: tracing + :name: Tracing -Send Tracing Formatted Packet To The Host With Supported Backends -################################################################# - -Overview -******** + Send tracing formatted packet to the host with supported backends. This application can be used to demonstrate the tracing feature. The tracing formatted packet will be sent to the host with the currently supported tracing diff --git a/samples/subsys/usb/audio/headphones_microphone/README.rst b/samples/subsys/usb/audio/headphones_microphone/README.rst index c7bb238894a..eedd3891eec 100644 --- a/samples/subsys/usb/audio/headphones_microphone/README.rst +++ b/samples/subsys/usb/audio/headphones_microphone/README.rst @@ -1,7 +1,8 @@ -.. _usb_audio_headphones_microphone: +.. zephyr:code-sample:: usb-audio-headphones-microphone + :name: USB Audio microphone & headphones + :relevant-api: _usb_device_core_api -USB Audio Sample Application -############################ + Implement a USB Audio microphone + headphones device with audio IN/OUT loopback. Overview ******** diff --git a/samples/subsys/usb/audio/headset/README.rst b/samples/subsys/usb/audio/headset/README.rst index 4a804a1f388..8ab11bbd586 100644 --- a/samples/subsys/usb/audio/headset/README.rst +++ b/samples/subsys/usb/audio/headset/README.rst @@ -1,7 +1,8 @@ -.. _usb_audio_headset: +.. zephyr:code-sample:: usb-audio-headset + :name: USB Audio headset + :relevant-api: _usb_device_core_api -USB Audio Sample Application -############################ + Implement a USB Audio headset device with audio IN/OUT loopback. Overview ******** diff --git a/samples/subsys/usb/cdc_acm/README.rst b/samples/subsys/usb/cdc_acm/README.rst index 50a0e1531e1..15dcb7d574c 100644 --- a/samples/subsys/usb/cdc_acm/README.rst +++ b/samples/subsys/usb/cdc_acm/README.rst @@ -1,7 +1,8 @@ -.. _usb_cdc-acm: +.. zephyr:code-sample:: usb-cdc-acm + :name: USB CDC-ACM + :relevant-api: usbd_api _usb_device_core_api -USB CDC ACM Sample Application -#################################### + Use USB CDC-ACM driver to implement a serial port echo. Overview ******** diff --git a/samples/subsys/usb/cdc_acm_composite/README.rst b/samples/subsys/usb/cdc_acm_composite/README.rst index 97c3333baa5..a138efffb42 100644 --- a/samples/subsys/usb/cdc_acm_composite/README.rst +++ b/samples/subsys/usb/cdc_acm_composite/README.rst @@ -1,7 +1,8 @@ -.. _usb_cdc-acm_composite: +.. zephyr:code-sample:: usb-cdc-acm-composite + :name: USB CDC-ACM composite + :relevant-api: usbd_api -USB CDC ACM Sample Composite Application -######################################## + Implement a composite USB device exposing two serial ports using USB CDC-ACM driver. Overview ******** diff --git a/samples/subsys/usb/console/README.rst b/samples/subsys/usb/console/README.rst index 08f05aca7d2..ac341a9285b 100644 --- a/samples/subsys/usb/console/README.rst +++ b/samples/subsys/usb/console/README.rst @@ -1,7 +1,8 @@ -.. _cdc-acm-console: +.. zephyr:code-sample:: usb-cdc-acm-console + :name: Console over USB CDC ACM + :relevant-api: _usb_device_core_api usbd_api uart_interface -Console over CDC ACM UART Sample -################################ + Output "Hello World!" to the console over USB CDC ACM. Overview ******** diff --git a/samples/subsys/usb/dfu/README.rst b/samples/subsys/usb/dfu/README.rst index 1803287754d..0ca87d7a8cf 100644 --- a/samples/subsys/usb/dfu/README.rst +++ b/samples/subsys/usb/dfu/README.rst @@ -1,7 +1,8 @@ -.. _usb_dfu: +.. zephyr:code-sample:: usb-dfu + :name: USB DFU (Device Firmware Upgrade) + :relevant-api: usbd_api _usb_device_core_api -USB DFU Sample Application -########################## + Implement device firmware upgrade using the USB DFU class driver. Overview ******** diff --git a/samples/subsys/usb/hid-cdc/README.rst b/samples/subsys/usb/hid-cdc/README.rst index 9a55e7d76a3..403785ef25e 100644 --- a/samples/subsys/usb/hid-cdc/README.rst +++ b/samples/subsys/usb/hid-cdc/README.rst @@ -1,7 +1,8 @@ -.. _usb_hid-cdc: +.. zephyr:code-sample:: usb-hid-cdc + :name: USB HID and CDC ACM + :relevant-api: _usb_device_core_api usb_hid_class input_interface -USB HID CDC ACM Application -########################### + Expose multiple USB HID and CDC ACM instances. Overview ******** diff --git a/samples/subsys/usb/hid-mouse/README.rst b/samples/subsys/usb/hid-mouse/README.rst index a7ff90bc2fe..c532141e71e 100644 --- a/samples/subsys/usb/hid-mouse/README.rst +++ b/samples/subsys/usb/hid-mouse/README.rst @@ -1,7 +1,8 @@ -.. _usb_hid-mouse: +.. zephyr:code-sample:: usb-hid-mouse + :name: USB HID mouse + :relevant-api: _usb_device_core_api usb_hid_class input_interface -USB HID mouse Sample Application -################################ + Implement a basic HID mouse device. Overview ******** diff --git a/samples/subsys/usb/hid/README.rst b/samples/subsys/usb/hid/README.rst index 0d95738f751..c29809cdf00 100644 --- a/samples/subsys/usb/hid/README.rst +++ b/samples/subsys/usb/hid/README.rst @@ -1,7 +1,8 @@ -.. _usb_hid: +.. zephyr:code-sample:: usb-hid + :name: USB HID (Human Interface Device) + :relevant-api: usbd_api usb_hid_device_api -USB HID Sample Application -########################## + Use USB HID driver to enumerate as a raw HID device. Overview ******** diff --git a/samples/subsys/usb/mass/README.rst b/samples/subsys/usb/mass/README.rst index 75d6f2f388a..4d400e942c9 100644 --- a/samples/subsys/usb/mass/README.rst +++ b/samples/subsys/usb/mass/README.rst @@ -1,7 +1,8 @@ -.. _usb_mass: +.. zephyr:code-sample:: usb-mass + :name: USB Mass Storage + :relevant-api: usbd_api _usb_device_core_api file_system_api -USB Mass Storage Sample Application -################################### + Expose board's RAM or FLASH as a USB disk using USB Mass Storage driver. Overview ******** diff --git a/samples/subsys/usb/shell/README.rst b/samples/subsys/usb/shell/README.rst index 12f7c0ae193..0e368187c79 100644 --- a/samples/subsys/usb/shell/README.rst +++ b/samples/subsys/usb/shell/README.rst @@ -1,13 +1,14 @@ -.. _usb_shell-app: +.. zephyr:code-sample:: usb-shell + :name: USB shell + :relevant-api: usbd_api -USB support shell sample -######################## + Use shell commands to interact with USB device stack. Overview ******** The sample enables new experimental USB device support and the shell function. -It is primarily intended to aid in the development and testing of USB constoller +It is primarily intended to aid in the development and testing of USB controller drivers and new USB support. Building and flashing diff --git a/samples/subsys/usb/testusb/README.rst b/samples/subsys/usb/testusb/README.rst index 74a6585ab48..03e6f6c104a 100644 --- a/samples/subsys/usb/testusb/README.rst +++ b/samples/subsys/usb/testusb/README.rst @@ -1,9 +1,10 @@ -.. _testusb-app: +.. zephyr:code-sample:: testusb-app + :name: USB testing application + :relevant-api: _usb_device_core_api -Testusb application sample -########################## + Test USB device drivers using a loopback function. -The testusb sample implements a loopback function. This function can be used +This sample implements a loopback function that can be used to test USB device drivers and the device stack connected to a Linux host and has a similar interface to "Gadget Zero" of the Linux kernel. The userspace tool ``testusb`` is needed to start the tests. diff --git a/samples/subsys/usb/webusb/README.rst b/samples/subsys/usb/webusb/README.rst index f5d5c17e1d7..ac8ca57b698 100644 --- a/samples/subsys/usb/webusb/README.rst +++ b/samples/subsys/usb/webusb/README.rst @@ -1,7 +1,8 @@ -.. _webusb-sample: +.. zephyr:code-sample:: webusb + :name: WebUSB + :relevant-api: usbd_api -WebUSB sample application -######################### + Receive and echo data from a web page using WebUSB API. For a deeper dive into the WebUSB, refer to https://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web @@ -9,8 +10,8 @@ https://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web WebUSB API Specification: https://wicg.github.io/webusb/ -Sample Overview -*************** +Overview +******** This simple echo application demonstrates the WebUSB sample application. This application receives the data and echoed back to the WebUSB diff --git a/samples/subsys/usb_c/sink/README.rst b/samples/subsys/usb_c/sink/README.rst index 8b8a4657c81..954147965b7 100644 --- a/samples/subsys/usb_c/sink/README.rst +++ b/samples/subsys/usb_c/sink/README.rst @@ -1,7 +1,8 @@ -.. _usb-c-sink-sample: +.. zephyr:code-sample:: usb-c-sink + :name: Basic USB-C Sink + :relevant-api: _usbc_device_api -Basic USB-C SINK -################ + Implement a USB-C Power Delivery application in the form of a USB-C Sink. Overview ******** diff --git a/samples/subsys/usb_c/source/README.rst b/samples/subsys/usb_c/source/README.rst index 06cb38eab37..1e9b861cc85 100644 --- a/samples/subsys/usb_c/source/README.rst +++ b/samples/subsys/usb_c/source/README.rst @@ -1,7 +1,8 @@ -.. _usb-c-source-sample: +.. zephyr:code-sample:: usb-c-source + :name: Basic USB-C Source + :relevant-api: _usbc_device_api -Basic USB-C SOURCE -################## + Implement a USB-C Power Delivery application in the form of a USB-C Source. Overview ******** From 4b9f5cc455c1c018c506a94f8b4a5b2fa617e51e Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Wed, 20 Sep 2023 17:57:04 +0530 Subject: [PATCH 0776/4498] net: l2: wifi: Change arrays to functions The header file contains mixture of functions and static arrays. Replacing static arrays to functions. Initialize functions in C file. Signed-off-by: Kapil Bhatt --- include/zephyr/net/wifi.h | 187 +++-------------------- subsys/net/l2/wifi/wifi_shell.c | 258 +++++++++++++++++++++++++++++--- 2 files changed, 256 insertions(+), 189 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 55bd8d71a3a..294fdc53c5d 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -52,30 +52,7 @@ enum wifi_security_type { }; /** Helper function to get user-friendly security type name. */ -static inline const char *wifi_security_txt(enum wifi_security_type security) -{ - switch (security) { - case WIFI_SECURITY_TYPE_NONE: - return "OPEN"; - case WIFI_SECURITY_TYPE_WEP: - return "WEP"; - case WIFI_SECURITY_TYPE_WPA_PSK: - return "WPA-PSK"; - case WIFI_SECURITY_TYPE_PSK: - return "WPA2-PSK"; - case WIFI_SECURITY_TYPE_PSK_SHA256: - return "WPA2-PSK-SHA256"; - case WIFI_SECURITY_TYPE_SAE: - return "WPA3-SAE"; - case WIFI_SECURITY_TYPE_WAPI: - return "WAPI"; - case WIFI_SECURITY_TYPE_EAP: - return "EAP"; - case WIFI_SECURITY_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_security_txt(enum wifi_security_type security); /** IEEE 802.11w - Management frame protection. */ enum wifi_mfp_options { @@ -92,20 +69,7 @@ enum wifi_mfp_options { }; /** Helper function to get user-friendly MFP name.*/ -static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp) -{ - switch (mfp) { - case WIFI_MFP_DISABLE: - return "Disable"; - case WIFI_MFP_OPTIONAL: - return "Optional"; - case WIFI_MFP_REQUIRED: - return "Required"; - case WIFI_MFP_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_mfp_txt(enum wifi_mfp_options mfp); /** * @brief IEEE 802.11 operational frequency bands (not exhaustive). @@ -127,20 +91,7 @@ enum wifi_frequency_bands { }; /** Helper function to get user-friendly frequency band name. */ -static inline const char *wifi_band_txt(enum wifi_frequency_bands band) -{ - switch (band) { - case WIFI_FREQ_BAND_2_4_GHZ: - return "2.4GHz"; - case WIFI_FREQ_BAND_5_GHZ: - return "5GHz"; - case WIFI_FREQ_BAND_6_GHZ: - return "6GHz"; - case WIFI_FREQ_BAND_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_band_txt(enum wifi_frequency_bands band); #define WIFI_SSID_MAX_LEN 32 #define WIFI_PSK_MIN_LEN 8 @@ -184,34 +135,7 @@ enum wifi_iface_state { }; /** Helper function to get user-friendly interface state name. */ -static inline const char *wifi_state_txt(enum wifi_iface_state state) -{ - switch (state) { - case WIFI_STATE_DISCONNECTED: - return "DISCONNECTED"; - case WIFI_STATE_INACTIVE: - return "INACTIVE"; - case WIFI_STATE_INTERFACE_DISABLED: - return "INTERFACE_DISABLED"; - case WIFI_STATE_SCANNING: - return "SCANNING"; - case WIFI_STATE_AUTHENTICATING: - return "AUTHENTICATING"; - case WIFI_STATE_ASSOCIATING: - return "ASSOCIATING"; - case WIFI_STATE_ASSOCIATED: - return "ASSOCIATED"; - case WIFI_STATE_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case WIFI_STATE_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case WIFI_STATE_COMPLETED: - return "COMPLETED"; - case WIFI_STATE_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_state_txt(enum wifi_iface_state state); /** Wi-Fi interface modes. * @@ -237,26 +161,7 @@ enum wifi_iface_mode { }; /** Helper function to get user-friendly interface mode name. */ -static inline const char *wifi_mode_txt(enum wifi_iface_mode mode) -{ - switch (mode) { - case WIFI_MODE_INFRA: - return "STATION"; - case WIFI_MODE_IBSS: - return "ADHOC"; - case WIFI_MODE_AP: - return "ACCESS POINT"; - case WIFI_MODE_P2P_GO: - return "P2P GROUP OWNER"; - case WIFI_MODE_P2P_GROUP_FORMATION: - return "P2P GROUP FORMATION"; - case WIFI_MODE_MESH: - return "MESH"; - case WIFI_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_mode_txt(enum wifi_iface_mode mode); /** Wi-Fi link operating modes * @@ -288,32 +193,7 @@ enum wifi_link_mode { }; /** Helper function to get user-friendly link mode name. */ -static inline const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) -{ - switch (link_mode) { - case WIFI_0: - return "WIFI 0 (802.11)"; - case WIFI_1: - return "WIFI 1 (802.11b)"; - case WIFI_2: - return "WIFI 2 (802.11a)"; - case WIFI_3: - return "WIFI 3 (802.11g)"; - case WIFI_4: - return "WIFI 4 (802.11n/HT)"; - case WIFI_5: - return "WIFI 5 (802.11ac/VHT)"; - case WIFI_6: - return "WIFI 6 (802.11ax/HE)"; - case WIFI_6E: - return "WIFI 6E (802.11ax 6GHz/HE)"; - case WIFI_7: - return "WIFI 7 (802.11be/EHT)"; - case WIFI_LINK_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} +const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode); /** Wi-Fi scanning types. */ enum wifi_scan_type { @@ -331,12 +211,8 @@ enum wifi_ps { WIFI_PS_ENABLED, }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_ps2str[] = { - [WIFI_PS_DISABLED] = "Power save disabled", - [WIFI_PS_ENABLED] = "Power save enabled", -}; -/** @endcond */ +/** Helper function to get user-friendly ps name. */ +const char * const wifi_ps_txt(enum wifi_ps ps_name); /** Wi-Fi power save modes. */ enum wifi_ps_mode { @@ -349,12 +225,8 @@ enum wifi_ps_mode { WIFI_PS_MODE_WMM, }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_ps_mode2str[] = { - [WIFI_PS_MODE_LEGACY] = "Legacy power save", - [WIFI_PS_MODE_WMM] = "WMM power save", -}; -/** @endcond */ +/** Helper function to get user-friendly ps mode name. */ +const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode); /* Interface index Min and Max values */ #define WIFI_INTERFACE_INDEX_MIN 1 @@ -396,12 +268,8 @@ enum wifi_twt_operation { WIFI_TWT_TEARDOWN, }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_twt_operation2str[] = { - [WIFI_TWT_SETUP] = "TWT setup", - [WIFI_TWT_TEARDOWN] = "TWT teardown", -}; -/** @endcond */ +/** Helper function to get user-friendly twt operation name. */ +const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation); /** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { @@ -413,13 +281,8 @@ enum wifi_twt_negotiation_type { WIFI_TWT_WAKE_TBTT }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_twt_negotiation_type2str[] = { - [WIFI_TWT_INDIVIDUAL] = "TWT individual negotiation", - [WIFI_TWT_BROADCAST] = "TWT broadcast negotiation", - [WIFI_TWT_WAKE_TBTT] = "TWT wake TBTT negotiation", -}; -/** @endcond */ +/** Helper function to get user-friendly twt negotiation type name. */ +const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation); /** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { @@ -441,18 +304,8 @@ enum wifi_twt_setup_cmd { WIFI_TWT_SETUP_CMD_REJECT, }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_twt_setup_cmd2str[] = { - [WIFI_TWT_SETUP_CMD_REQUEST] = "TWT request", - [WIFI_TWT_SETUP_CMD_SUGGEST] = "TWT suggest", - [WIFI_TWT_SETUP_CMD_DEMAND] = "TWT demand", - [WIFI_TWT_SETUP_CMD_GROUPING] = "TWT grouping", - [WIFI_TWT_SETUP_CMD_ACCEPT] = "TWT accept", - [WIFI_TWT_SETUP_CMD_ALTERNATE] = "TWT alternate", - [WIFI_TWT_SETUP_CMD_DICTATE] = "TWT dictate", - [WIFI_TWT_SETUP_CMD_REJECT] = "TWT reject", -}; -/** @endcond */ +/** Helper function to get user-friendly twt setup cmd name. */ +const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup); /** Wi-Fi Target Wake Time (TWT) negotiation status. */ enum wifi_twt_setup_resp_status { @@ -543,12 +396,8 @@ enum wifi_ps_wakeup_mode { WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, }; -/** @cond INTERNAL_HIDDEN */ -static const char * const wifi_ps_wakeup_mode2str[] = { - [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", - [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", -}; -/** @endcond */ +/** Helper function to get user-friendly ps wakeup mode name. */ +const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode); /** Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 21b1f551448..74284e56e98 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -97,6 +97,224 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi return true; } +const char * const wifi_security_txt(enum wifi_security_type security) +{ + switch (security) { + case WIFI_SECURITY_TYPE_NONE: + return "OPEN"; + case WIFI_SECURITY_TYPE_WEP: + return "WEP"; + case WIFI_SECURITY_TYPE_WPA_PSK: + return "WPA-PSK"; + case WIFI_SECURITY_TYPE_PSK: + return "WPA2-PSK"; + case WIFI_SECURITY_TYPE_PSK_SHA256: + return "WPA2-PSK-SHA256"; + case WIFI_SECURITY_TYPE_SAE: + return "WPA3-SAE"; + case WIFI_SECURITY_TYPE_WAPI: + return "WAPI"; + case WIFI_SECURITY_TYPE_EAP: + return "EAP"; + case WIFI_SECURITY_TYPE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) +{ + switch (mfp) { + case WIFI_MFP_DISABLE: + return "Disable"; + case WIFI_MFP_OPTIONAL: + return "Optional"; + case WIFI_MFP_REQUIRED: + return "Required"; + case WIFI_MFP_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_band_txt(enum wifi_frequency_bands band) +{ + switch (band) { + case WIFI_FREQ_BAND_2_4_GHZ: + return "2.4GHz"; + case WIFI_FREQ_BAND_5_GHZ: + return "5GHz"; + case WIFI_FREQ_BAND_6_GHZ: + return "6GHz"; + case WIFI_FREQ_BAND_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_state_txt(enum wifi_iface_state state) +{ + switch (state) { + case WIFI_STATE_DISCONNECTED: + return "DISCONNECTED"; + case WIFI_STATE_INACTIVE: + return "INACTIVE"; + case WIFI_STATE_INTERFACE_DISABLED: + return "INTERFACE_DISABLED"; + case WIFI_STATE_SCANNING: + return "SCANNING"; + case WIFI_STATE_AUTHENTICATING: + return "AUTHENTICATING"; + case WIFI_STATE_ASSOCIATING: + return "ASSOCIATING"; + case WIFI_STATE_ASSOCIATED: + return "ASSOCIATED"; + case WIFI_STATE_4WAY_HANDSHAKE: + return "4WAY_HANDSHAKE"; + case WIFI_STATE_GROUP_HANDSHAKE: + return "GROUP_HANDSHAKE"; + case WIFI_STATE_COMPLETED: + return "COMPLETED"; + case WIFI_STATE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mode_txt(enum wifi_iface_mode mode) +{ + switch (mode) { + case WIFI_MODE_INFRA: + return "STATION"; + case WIFI_MODE_IBSS: + return "ADHOC"; + case WIFI_MODE_AP: + return "ACCESS POINT"; + case WIFI_MODE_P2P_GO: + return "P2P GROUP OWNER"; + case WIFI_MODE_P2P_GROUP_FORMATION: + return "P2P GROUP FORMATION"; + case WIFI_MODE_MESH: + return "MESH"; + case WIFI_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) +{ + switch (link_mode) { + case WIFI_0: + return "WIFI 0 (802.11)"; + case WIFI_1: + return "WIFI 1 (802.11b)"; + case WIFI_2: + return "WIFI 2 (802.11a)"; + case WIFI_3: + return "WIFI 3 (802.11g)"; + case WIFI_4: + return "WIFI 4 (802.11n/HT)"; + case WIFI_5: + return "WIFI 5 (802.11ac/VHT)"; + case WIFI_6: + return "WIFI 6 (802.11ax/HE)"; + case WIFI_6E: + return "WIFI 6E (802.11ax 6GHz/HE)"; + case WIFI_7: + return "WIFI 7 (802.11be/EHT)"; + case WIFI_LINK_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_txt(enum wifi_ps ps_name) +{ + switch (ps_name) { + case WIFI_PS_DISABLED: + return "Power save disabled"; + case WIFI_PS_ENABLED: + return "Power save enabled"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) +{ + switch (ps_mode) { + case WIFI_PS_MODE_LEGACY: + return "Legacy power save"; + case WIFI_PS_MODE_WMM: + return "WMM power save"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) +{ + switch (twt_operation) { + case WIFI_TWT_SETUP: + return "TWT setup"; + case WIFI_TWT_TEARDOWN: + return "TWT teardown"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) +{ + switch (twt_negotiation) { + case WIFI_TWT_INDIVIDUAL: + return "TWT individual negotiation"; + case WIFI_TWT_BROADCAST: + return "TWT broadcast negotiation"; + case WIFI_TWT_WAKE_TBTT: + return "TWT wake TBTT negotiation"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) +{ + switch (twt_setup) { + case WIFI_TWT_SETUP_CMD_REQUEST: + return "TWT request"; + case WIFI_TWT_SETUP_CMD_SUGGEST: + return "TWT suggest"; + case WIFI_TWT_SETUP_CMD_DEMAND: + return "TWT demand"; + case WIFI_TWT_SETUP_CMD_GROUPING: + return "TWT grouping"; + case WIFI_TWT_SETUP_CMD_ACCEPT: + return "TWT accept"; + case WIFI_TWT_SETUP_CMD_ALTERNATE: + return "TWT alternate"; + case WIFI_TWT_SETUP_CMD_DICTATE: + return "TWT dictate"; + case WIFI_TWT_SETUP_CMD_REJECT: + return "TWT reject"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) +{ + switch (ps_wakeup_mode) { + case WIFI_PS_WAKEUP_MODE_DTIM: + return "PS wakeup mode DTIM"; + case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: + return "PS wakeup mode listen interval"; + default: + return "UNKNOWN"; + } +} + static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) { const struct wifi_scan_result *entry = @@ -257,7 +475,7 @@ static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, print(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", flow_id); print(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", - wifi_twt_negotiation_type2str[negotiation_type]); + wifi_twt_negotiation_type_txt(negotiation_type)); print(context.sh, SHELL_NORMAL, "TWT responder: %s\n", responder ? "true" : "false"); print(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", @@ -286,7 +504,7 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", - wifi_twt_setup_cmd2str[resp->setup_cmd]); + wifi_twt_setup_cmd_txt(resp->setup_cmd)); print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, @@ -736,10 +954,10 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) } shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", - wifi_ps2str[config.ps_params.enabled]); + wifi_ps_txt(config.ps_params.enabled)); if (config.ps_params.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", - wifi_ps_mode2str[config.ps_params.mode]); + wifi_ps_mode_txt(config.ps_params.mode)); } shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", @@ -794,7 +1012,7 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps2str[params.enabled]); + shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_txt(params.enabled)); return 0; } @@ -819,12 +1037,12 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s failed Reason : %s\n", - wifi_ps_mode2str[params.mode], + wifi_ps_mode_txt(params.mode), wifi_ps_get_config_err_code_str(params.fail_reason)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_mode2str[params.mode]); + shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_mode_txt(params.mode)); return 0; } @@ -903,15 +1121,15 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], + wifi_twt_operation_txt(params.operation), + wifi_twt_negotiation_type_txt(params.negotiation_type), wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", - wifi_twt_operation2str[params.operation], + wifi_twt_operation_txt(params.operation), params.dialog_token, params.flow_id); return 0; @@ -990,15 +1208,15 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed. reason : %s\n", - wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], + wifi_twt_operation_txt(params.operation), + wifi_twt_negotiation_type_txt(params.negotiation_type), wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", - wifi_twt_operation2str[params.operation], + wifi_twt_operation_txt(params.operation), params.dialog_token, params.flow_id); return 0; @@ -1046,15 +1264,15 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], + wifi_twt_operation_txt(params.operation), + wifi_twt_negotiation_type_txt(params.negotiation_type), wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d success\n", - wifi_twt_operation2str[params.operation], + wifi_twt_operation_txt(params.operation), params.dialog_token, params.flow_id); return 0; @@ -1073,15 +1291,15 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], + wifi_twt_operation_txt(params.operation), + wifi_twt_negotiation_type_txt(params.negotiation_type), wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows success\n", - wifi_twt_operation2str[params.operation]); + wifi_twt_operation_txt(params.operation)); return 0; } @@ -1258,7 +1476,7 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar } shell_fprintf(sh, SHELL_NORMAL, "%s\n", - wifi_ps_wakeup_mode2str[params.wakeup_mode]); + wifi_ps_wakeup_mode_txt(params.wakeup_mode)); return 0; } From fa4086875def4b4b78b0f6a485a962f6e4c1cd4b Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 20 Sep 2023 07:35:48 +0200 Subject: [PATCH 0777/4498] mgmt: ec_host_cmd: fix checking number of backends If autoinit is not enebled, it is allowed to build a few backends and initialize a proper one in runtime. Check number of backends only if autoinit is enabled. Signed-off-by: Dawid Niedzwiecki --- subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c index 23a90a64094..e322b5b8412 100644 --- a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c +++ b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(host_cmd_handler, CONFIG_EC_HC_LOG_LEVEL); +#ifdef CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT #define EC_HOST_CMD_CHOSEN_BACKEND_LIST \ zephyr_host_cmd_espi_backend, zephyr_host_cmd_shi_backend, zephyr_host_cmd_uart_backend, \ zephyr_host_cmd_spi_backend @@ -26,6 +27,7 @@ LOG_MODULE_REGISTER(host_cmd_handler, CONFIG_EC_HC_LOG_LEVEL); +0 BUILD_ASSERT(NUMBER_OF_CHOSEN_BACKENDS < 2, "Number of chosen backends > 1"); +#endif #define RX_HEADER_SIZE (sizeof(struct ec_host_cmd_request_header)) #define TX_HEADER_SIZE (sizeof(struct ec_host_cmd_response_header)) From 340ffe1c485e1bd391f5ac306fd880d704746b24 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 20 Sep 2023 12:51:53 +0200 Subject: [PATCH 0778/4498] mgmt: ec_host_cmd: fix struct init order Order structure members according to the structure definition. Signed-off-by: Dawid Niedzwiecki --- include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h | 4 ++-- .../mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h b/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h index 5b03ae7c5f3..018aa60e980 100644 --- a/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h +++ b/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h @@ -170,8 +170,8 @@ struct ec_host_cmd_handler { */ #define EC_HOST_CMD_HANDLER(_id, _function, _version_mask, _request_type, _response_type) \ const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = { \ - .id = _id, \ .handler = _function, \ + .id = _id, \ .version_mask = _version_mask, \ .min_rqt_size = sizeof(_request_type), \ .min_rsp_size = sizeof(_response_type), \ @@ -190,8 +190,8 @@ struct ec_host_cmd_handler { */ #define EC_HOST_CMD_HANDLER_UNBOUND(_id, _function, _version_mask) \ const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = { \ - .id = _id, \ .handler = _function, \ + .id = _id, \ .version_mask = _version_mask, \ .min_rqt_size = 0, \ .min_rsp_size = 0, \ diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c index c022150aa3b..c4e045ac800 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c @@ -136,8 +136,8 @@ struct dma_stream { struct ec_host_cmd_spi_cfg { SPI_TypeDef *spi; const struct pinctrl_dev_config *pcfg; - size_t pclk_len; const struct stm32_pclken *pclken; + size_t pclk_len; }; struct ec_host_cmd_spi_ctx { @@ -189,9 +189,9 @@ static int prepare_rx(struct ec_host_cmd_spi_ctx *hc_spi); \ static struct ec_host_cmd_spi_cfg ec_host_cmd_spi_cfg = { \ .spi = (SPI_TypeDef *)DT_REG_ADDR(id), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(id), \ .pclken = pclken, \ .pclk_len = DT_NUM_CLOCKS(id), \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(id), \ }; \ \ static struct dma_stream dma_rx = {SPI_DMA_CHANNEL_INIT(id, rx, RX, PERIPHERAL, MEMORY)}; \ From d8d81a8075679cb04b8706de873ecfa1ae9ce438 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 20 Sep 2023 10:08:50 +0300 Subject: [PATCH 0779/4498] net: lwm2m: Fix build warning on access-control object With bootstrap one function is unused. Fix by changing ifdef to if (IS_ENABLED()) so linker can drop it. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_obj_access_control.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c b/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c index 1a83ef5ad29..383dbe9b539 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c @@ -432,10 +432,10 @@ static int ac_control_init(void) ac_obj.create_cb = ac_create; lwm2m_register_obj(&ac_obj); -#if !IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - /* add the objects/object instances that were created before the ac control object */ - add_existing_objects(); -#endif /* CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP */ + if (!IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + /* add the objects/object instances that were created before the ac control */ + add_existing_objects(); + } return 0; } From b0303f5bd37bb1af8152a6910f70fbd569724ebb Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 20 Sep 2023 13:26:41 +0300 Subject: [PATCH 0780/4498] net: lwm2m: Don't allow operations on security object In spec: The LwM2M Client MUST reject any LwM2M Server operation on the Security Object (ID: 0) with an "4.01 Unauthorized" response code. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 952a3d9c130..1a7d023ceb2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2330,6 +2330,11 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) goto error; } #endif + if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { + r = -EACCES; + goto error; + } + switch (msg->operation) { case LWM2M_OP_READ: From 8e7c7c62b15cbc09633e48f95eec6aa9150a4791 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 20 Sep 2023 19:45:22 +0000 Subject: [PATCH 0781/4498] .gitlint: de-duplicate defaults with zephyr_commit_rules.py We don't need to have two different sets of Zephyr-specific default values overriding one another, it's confusing. Note this commit makes NO functional change, the effective defaults stay the same. It does however make it easier to change defaults in the future. Signed-off-by: Marc Herbert --- .gitlint | 9 +++++---- scripts/gitlint/zephyr_commit_rules.py | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.gitlint b/.gitlint index b8d25ce49b9..de5285527ce 100644 --- a/.gitlint +++ b/.gitlint @@ -1,4 +1,5 @@ # All these sections are optional, edit this file as you like. +# Zephyr-specific defaults are located in scripts/gitlint/zephyr_commit_rules.py [general] ignore=title-trailing-punctuation, T3, title-max-length, T1, body-hard-tab, B3, B1 # verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this @@ -16,13 +17,13 @@ debug = false extra-path=scripts/gitlint [title-max-length-no-revert] -line-length=75 +# line-length=75 [body-min-line-count] -min-line-count=1 +# min-line-count=1 [body-max-line-count] -max-line-count=200 +# max-line-count=200 [title-starts-with-subsystem] regex = ^(?!subsys:)(([^:]+):)(\s([^:]+):)*\s(.+)$ @@ -42,7 +43,7 @@ words=wip [max-line-length-with-exceptions] # B1 = body-max-line-length -line-length=75 +# line-length=75 [body-min-length] min-length=3 diff --git a/scripts/gitlint/zephyr_commit_rules.py b/scripts/gitlint/zephyr_commit_rules.py index 8f9cce21b1d..8979292bbb6 100644 --- a/scripts/gitlint/zephyr_commit_rules.py +++ b/scripts/gitlint/zephyr_commit_rules.py @@ -24,8 +24,8 @@ class BodyMinLineCount(CommitRule): # A rule MUST have an *unique* id, we recommend starting with UC (for User-defined Commit-rule). id = "UC6" - # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [IntOption('min-line-count', 2, "Minimum body line count excluding Signed-off-by")] + # A rule MAY have an options_spec if its behavior should be configurable. + options_spec = [IntOption('min-line-count', 1, "Minimum body line count excluding Signed-off-by")] def validate(self, commit): filtered = [x for x in commit.message.body if not x.lower().startswith("signed-off-by") and x != ''] @@ -42,8 +42,8 @@ class BodyMaxLineCount(CommitRule): # A rule MUST have an *unique* id, we recommend starting with UC (for User-defined Commit-rule). id = "UC1" - # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [IntOption('max-line-count', 3, "Maximum body line count")] + # A rule MAY have an options_spec if its behavior should be configurable. + options_spec = [IntOption('max-line-count', 200, "Maximum body line count")] def validate(self, commit): line_count = len(commit.message.body) @@ -78,7 +78,7 @@ class TitleMaxLengthRevert(LineRule): name = "title-max-length-no-revert" id = "UC5" target = CommitMessageTitle - options_spec = [IntOption('line-length', 72, "Max line length")] + options_spec = [IntOption('line-length', 75, "Max line length")] violation_message = "Commit title exceeds max length ({0}>{1})" def validate(self, line, _commit): @@ -103,7 +103,7 @@ class MaxLineLengthExceptions(LineRule): name = "max-line-length-with-exceptions" id = "UC4" target = CommitMessageBody - options_spec = [IntOption('line-length', 80, "Max line length")] + options_spec = [IntOption('line-length', 75, "Max line length")] violation_message = "Commit message body line exceeds max length ({0}>{1})" def validate(self, line, _commit): From 0a982c3617dbc7e98bfa51357c8644fe3e44ae4f Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 19 Sep 2023 10:27:22 +0300 Subject: [PATCH 0782/4498] net: lwm2m: Add shell command to create object instances Some testcases might need to be able to create object instances, so add shell command for it. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_shell.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index f8374eb34f2..2a86aa88d69 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -40,6 +40,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "-sX\tWrite value as intX_t\n" \ "-f \tWrite value as float\n" \ "-t \tWrite value as time_t\n" +#define LWM2M_HELP_CREATE "Create object instance\ncreate PATH\n" #define LWM2M_HELP_START "Start the LwM2M RD (Registration / Discovery) Client\n" \ "start EP_NAME [BOOTSTRAP FLAG]\n" \ "-b \tSet the bootstrap flag (default 0)\n" @@ -372,6 +373,40 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) return 0; } +static int cmd_create(const struct shell *sh, size_t argc, char **argv) +{ + struct lwm2m_obj_path path; + struct lwm2m_engine_obj_inst *obj_inst; + int ret; + + if (argc < 2) { + shell_error(sh, "No object ID given\n"); + shell_help(sh); + return -EINVAL; + } + + ret = lwm2m_string_to_path(argv[1], &path, '/'); + if (ret < 0) { + shell_error(sh, "failed to read path (%d)\n", ret); + return -ENOEXEC; + } + + if (path.level != LWM2M_PATH_LEVEL_OBJECT_INST) { + shell_error(sh, "path is not an object instance\n"); + shell_help(sh); + return -EINVAL; + } + + ret = lwm2m_create_obj_inst(path.obj_id, path.obj_inst_id, &obj_inst); + if (ret < 0) { + shell_error(sh, "Failed to create object instance %d/%d, ret=%d", path.obj_id, + path.obj_inst_id, ret); + return -ENOEXEC; + } + + return 0; +} + static int cmd_start(const struct shell *sh, size_t argc, char **argv) { struct lwm2m_ctx *ctx = lwm2m_rd_client_ctx(); @@ -561,6 +596,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(exec, NULL, LWM2M_HELP_EXEC, cmd_exec, 2, 1), SHELL_CMD_ARG(read, NULL, LWM2M_HELP_READ, cmd_read, 2, 1), SHELL_CMD_ARG(write, NULL, LWM2M_HELP_WRITE, cmd_write, 3, 1), + SHELL_CMD_ARG(create, NULL, LWM2M_HELP_CREATE, cmd_create, 2, 0), SHELL_CMD_ARG(start, NULL, LWM2M_HELP_START, cmd_start, 2, 2), SHELL_CMD_ARG(stop, NULL, LWM2M_HELP_STOP, cmd_stop, 1, 1), SHELL_CMD_ARG(update, NULL, LWM2M_HELP_UPDATE, cmd_update, 1, 0), From 7d65c55a50a451d126af671b5a5f136ce9fc865e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Sep 2023 10:55:25 +0200 Subject: [PATCH 0783/4498] tests: Bluetooth: BAP broadcast source param name fix The test fixture used an invalid struct for the param due to a renaming of the struct in another commit. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index 3c5562f4049..fbf32ed146a 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -34,7 +34,7 @@ static void mock_destroy_rule_after(const struct ztest_unit_test *test, void *fi ZTEST_RULE(mock_rule, mock_init_rule_before, mock_destroy_rule_after); struct bap_broadcast_source_test_suite_fixture { - struct bt_bap_broadcast_source_create_param *create_param; + struct bt_bap_broadcast_source_param *param; size_t stream_cnt; struct bt_bap_broadcast_source *source; }; @@ -59,7 +59,7 @@ static void bap_broadcast_source_test_suite_fixture_init( zassert_true(streams_per_subgroup > 0U); /* Allocate memory for everything */ - fixture->create_param = malloc(sizeof(struct bt_bap_broadcast_source_create_param)); + fixture->param = malloc(sizeof(struct bt_bap_broadcast_source_param)); subgroup_param = malloc(sizeof(struct bt_bap_broadcast_source_subgroup_param) * CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT); zassert_not_null(subgroup_param); @@ -74,7 +74,7 @@ static void bap_broadcast_source_test_suite_fixture_init( zassert_not_null(streams); /* Memset everything to 0 */ - memset(fixture->create_param, 0, sizeof(*fixture->create_param)); + memset(fixture->param, 0, sizeof(*fixture->param)); memset(subgroup_param, 0, sizeof(struct bt_bap_broadcast_source_subgroup_param) * CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT); @@ -102,15 +102,14 @@ static void bap_broadcast_source_test_suite_fixture_init( bt_bap_stream_cb_register(stream_params[i].stream, &mock_bap_stream_ops); } - fixture->create_param->params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; - fixture->create_param->params = subgroup_param; - fixture->create_param->qos = codec_qos; - fixture->create_param->encryption = false; - memset(fixture->create_param->broadcast_code, 0, - sizeof(fixture->create_param->broadcast_code)); - fixture->create_param->packing = BT_ISO_PACKING_SEQUENTIAL; + fixture->param->params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; + fixture->param->params = subgroup_param; + fixture->param->qos = codec_qos; + fixture->param->encryption = false; + memset(fixture->param->broadcast_code, 0, sizeof(fixture->param->broadcast_code)); + fixture->param->packing = BT_ISO_PACKING_SEQUENTIAL; - fixture->stream_cnt = fixture->create_param->params_count * streams_per_subgroup; + fixture->stream_cnt = fixture->param->params_count * streams_per_subgroup; } static void *bap_broadcast_source_test_suite_setup(void) @@ -143,12 +142,12 @@ static void bap_broadcast_source_test_suite_after(void *f) fixture->source = NULL; } - free(fixture->create_param->params[0].params[0].stream); - free(fixture->create_param->params[0].params); - free(fixture->create_param->params[0].codec_cfg); - free(fixture->create_param->params); - free(fixture->create_param->qos); - free(fixture->create_param); + free(fixture->param->params[0].params[0].stream); + free(fixture->param->params[0].params); + free(fixture->param->params[0].codec_cfg); + free(fixture->param->params); + free(fixture->param->qos); + free(fixture->param); } static void bap_broadcast_source_test_suite_teardown(void *f) @@ -162,7 +161,7 @@ ZTEST_SUITE(bap_broadcast_source_test_suite, NULL, bap_broadcast_source_test_sui ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) { - struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_bap_broadcast_source_param *create_param = fixture->param; int err; printk("Creating broadcast source with %zu subgroups with %zu streams\n", @@ -178,7 +177,7 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_start_send_stop_delete) { - struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_bap_broadcast_source_param *create_param = fixture->param; struct bt_le_ext_adv ext_adv = {0}; int err; @@ -222,7 +221,7 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_start_send ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_source_null) { - struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_bap_broadcast_source_param *create_param = fixture->param; struct bt_le_ext_adv ext_adv = {0}; int err; @@ -238,7 +237,7 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_sourc ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_ext_adv_null) { - struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_bap_broadcast_source_param *create_param = fixture->param; int err; printk("Creating broadcast source with %zu subgroups with %zu streams\n", @@ -253,7 +252,7 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_ext_a ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_double_start) { - struct bt_bap_broadcast_source_create_param *create_param = fixture->create_param; + struct bt_bap_broadcast_source_param *create_param = fixture->param; struct bt_le_ext_adv ext_adv = {0}; int err; From fa7ab41c1b60d656e2674a8d432eefffb53a849e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 20 Sep 2023 12:35:15 +0200 Subject: [PATCH 0784/4498] native_simulator: Be sure the symbol_to_keep section is kept The native simulator final link can garbage collect unused symbols. So let's ensure the symbol to keep ones are indeed kept even if not used. Signed-off-by: Alberto Escolar Piedras --- boards/posix/common/natsim_config.cmake | 3 +++ boards/posix/common/natsim_linker_script.ld | 22 +++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 boards/posix/common/natsim_linker_script.ld diff --git a/boards/posix/common/natsim_config.cmake b/boards/posix/common/natsim_config.cmake index 54f26aef3ef..30da901f535 100644 --- a/boards/posix/common/natsim_config.cmake +++ b/boards/posix/common/natsim_config.cmake @@ -4,6 +4,9 @@ set(zephyr_build_path ${CMAKE_BINARY_DIR}/zephyr) get_property(CCACHE GLOBAL PROPERTY RULE_LAUNCH_COMPILE) +target_link_options(native_simulator INTERFACE + "-T ${ZEPHYR_BASE}/boards/posix/common/natsim_linker_script.ld") + set(nsi_config_content ${nsi_config_content} "NSI_BUILD_OPTIONS:=$,\ >" diff --git a/boards/posix/common/natsim_linker_script.ld b/boards/posix/common/natsim_linker_script.ld new file mode 100644 index 00000000000..add80b86c75 --- /dev/null +++ b/boards/posix/common/natsim_linker_script.ld @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extra linker command/script file for the native simulator runner + */ + +SECTIONS + { + symbol_to_keep : + { + KEEP(*(symbol_to_keep*)); + } + } INSERT AFTER .data; + +/* + * Note this script augments the default native simulator linker script + */ From 5fdc43270f4ebf5aee7efedc0804ed940e7d4c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 6 Sep 2023 07:29:02 +0200 Subject: [PATCH 0785/4498] canbus: isotp: improve internal function naming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use prefixes to make naming more clear and improve code readability. Signed-off-by: Martin Jäger --- subsys/canbus/isotp/isotp.c | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 104988bec0a..8eadfb02508 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -598,7 +598,7 @@ static void receive_can_rx(const struct device *dev, struct can_frame *frame, vo k_work_submit(&ctx->work); } -static inline int attach_ff_filter(struct isotp_recv_ctx *ctx) +static inline int add_ff_sf_filter(struct isotp_recv_ctx *ctx) { struct can_filter filter; uint32_t mask; @@ -614,7 +614,7 @@ static inline int attach_ff_filter(struct isotp_recv_ctx *ctx) ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx, &filter); if (ctx->filter_id < 0) { - LOG_ERR("Error attaching FF filter [%d]", ctx->filter_id); + LOG_ERR("Error adding FF filter [%d]", ctx->filter_id); return ISOTP_NO_FREE_FILTER; } @@ -664,9 +664,9 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, return ISOTP_NO_NET_BUF_LEFT; } - ret = attach_ff_filter(ctx); + ret = add_ff_sf_filter(ctx); if (ret) { - LOG_ERR("Can't attach filter for binding"); + LOG_ERR("Can't add filter for binding"); net_buf_unref(ctx->buf); ctx->buf = NULL; return ret; @@ -878,12 +878,12 @@ static void send_can_rx_cb(const struct device *dev, struct can_frame *frame, vo k_work_submit(&ctx->work); } -static size_t get_ctx_data_length(struct isotp_send_ctx *ctx) +static size_t get_send_ctx_data_len(struct isotp_send_ctx *ctx) { return ctx->is_net_buf ? net_buf_frags_len(ctx->buf) : ctx->len; } -static const uint8_t *get_data_ctx(struct isotp_send_ctx *ctx) +static const uint8_t *get_send_ctx_data(struct isotp_send_ctx *ctx) { if (ctx->is_net_buf) { return ctx->buf->data; @@ -892,7 +892,7 @@ static const uint8_t *get_data_ctx(struct isotp_send_ctx *ctx) } } -static void pull_data_ctx(struct isotp_send_ctx *ctx, size_t len) +static void pull_send_ctx_data(struct isotp_send_ctx *ctx, size_t len) { if (ctx->is_net_buf) { net_buf_pull_mem(ctx->buf, len); @@ -958,7 +958,7 @@ static inline int send_ff(struct isotp_send_ctx *ctx) { struct can_frame frame; int index = 0; - size_t len = get_ctx_data_length(ctx); + size_t len = get_send_ctx_data_len(ctx); int ret; const uint8_t *data; @@ -986,8 +986,8 @@ static inline int send_ff(struct isotp_send_ctx *ctx) * although it's not part of the FF frame */ ctx->sn = 1; - data = get_data_ctx(ctx); - pull_data_ctx(ctx, ctx->tx_addr.dl - index); + data = get_send_ctx_data(ctx); + pull_send_ctx_data(ctx, ctx->tx_addr.dl - index); memcpy(&frame.data[index], data, ctx->tx_addr.dl - index); ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), @@ -1013,10 +1013,10 @@ static inline int send_cf(struct isotp_send_ctx *ctx) /*sn wraps around at 0xF automatically because it has a 4 bit size*/ frame.data[index++] = ISOTP_PCI_TYPE_CF | ctx->sn; - rem_len = get_ctx_data_length(ctx); + rem_len = get_send_ctx_data_len(ctx); len = MIN(rem_len, ctx->tx_addr.dl - index); rem_len -= len; - data = get_data_ctx(ctx); + data = get_send_ctx_data(ctx); memcpy(&frame.data[index], data, len); if (IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) || @@ -1037,7 +1037,7 @@ static inline int send_cf(struct isotp_send_ctx *ctx) send_can_tx_cb, ctx); if (ret == 0) { ctx->sn++; - pull_data_ctx(ctx, len); + pull_send_ctx_data(ctx, len); ctx->bs--; ctx->tx_backlog++; } @@ -1059,7 +1059,7 @@ static inline void free_send_ctx(struct isotp_send_ctx **ctx) } } -static int alloc_ctx(struct isotp_send_ctx **ctx, k_timeout_t timeout) +static int alloc_send_ctx(struct isotp_send_ctx **ctx, k_timeout_t timeout) { int ret; @@ -1180,7 +1180,7 @@ static void send_work_handler(struct k_work *item) send_state_machine(ctx); } -static inline int attach_fc_filter(struct isotp_send_ctx *ctx) +static inline int add_fc_filter(struct isotp_send_ctx *ctx) { struct can_filter filter; @@ -1189,7 +1189,7 @@ static inline int attach_fc_filter(struct isotp_send_ctx *ctx) ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx, &filter); if (ctx->filter_id < 0) { - LOG_ERR("Error attaching FC filter [%d]", ctx->filter_id); + LOG_ERR("Error adding FC filter [%d]", ctx->filter_id); return ISOTP_NO_FREE_FILTER; } @@ -1262,15 +1262,15 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, return ISOTP_N_ERROR; } - len = get_ctx_data_length(ctx); + len = get_send_ctx_data_len(ctx); LOG_DBG("Send %zu bytes to addr 0x%x and listen on 0x%x", len, ctx->tx_addr.ext_id, ctx->rx_addr.ext_id); /* Single frames > 8 bytes use an additional byte for length (CAN-FD only) */ if (len > ctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - ((ctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { - ret = attach_fc_filter(ctx); + ret = add_fc_filter(ctx); if (ret) { - LOG_ERR("Can't attach fc filter: %d", ret); + LOG_ERR("Can't add fc filter: %d", ret); free_send_ctx(&ctx); return ret; } @@ -1327,7 +1327,7 @@ int isotp_send_ctx_buf(const struct device *can_dev, __ASSERT_NO_MSG(data); - ret = alloc_ctx(&ctx, timeout); + ret = alloc_send_ctx(&ctx, timeout); if (ret) { return ret; } @@ -1351,7 +1351,7 @@ int isotp_send_net_ctx_buf(const struct device *can_dev, __ASSERT_NO_MSG(data); - ret = alloc_ctx(&ctx, timeout); + ret = alloc_send_ctx(&ctx, timeout); if (ret) { return ret; } @@ -1376,7 +1376,7 @@ int isotp_send_buf(const struct device *can_dev, __ASSERT_NO_MSG(data); - ret = alloc_ctx(&ctx, timeout); + ret = alloc_send_ctx(&ctx, timeout); if (ret) { return ret; } From b82a4478ad0ad6defaeea89aa043d7dee1af1382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 6 Sep 2023 09:04:03 +0200 Subject: [PATCH 0786/4498] canbus: isotp: add _TIMEOUT_MS suffix to defines for timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The defines like ISOTP_A were obfuscating that this is actually a timeout value. Signed-off-by: Martin Jäger --- subsys/canbus/isotp/isotp.c | 26 +++++++++++--------------- subsys/canbus/isotp/isotp_internal.h | 8 ++++---- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 8eadfb02508..0ef6fce1e8c 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -163,8 +163,7 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) frame.dlc = can_bytes_to_dlc(payload_len); #endif - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), - receive_can_tx, ctx); + ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), receive_can_tx, ctx); if (ret) { LOG_ERR("Can't send FC, (%d)", ret); receive_report_error(ctx, ISOTP_N_TIMEOUT_A); @@ -238,7 +237,7 @@ static int receive_alloc_buffer(struct isotp_recv_ctx *ctx) } if (!buf) { - k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); if (ctx->wft == ISOTP_WFT_FIRST) { LOG_DBG("Allocation failed. Append to alloc list"); @@ -328,7 +327,7 @@ static void receive_state_machine(struct isotp_recv_ctx *ctx) case ISOTP_RX_STATE_SEND_FC: LOG_DBG("SM send CTS FC frame"); receive_send_fc(ctx, ISOTP_PCI_FS_CTS); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); ctx->state = ISOTP_RX_STATE_WAIT_CF; break; @@ -336,7 +335,7 @@ static void receive_state_machine(struct isotp_recv_ctx *ctx) if (++ctx->wft < CONFIG_ISOTP_WFTMAX) { LOG_DBG("Send wait frame number %d", ctx->wft); receive_send_fc(ctx, ISOTP_PCI_FS_WAIT); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); ctx->state = ISOTP_RX_STATE_TRY_ALLOC; break; } @@ -516,7 +515,7 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) return; } - k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); if ((frame->data[index++] & ISOTP_PCI_SN_MASK) != ctx->sn_expected++) { LOG_ERR("Sequence number mismatch"); @@ -842,7 +841,7 @@ static void send_process_fc(struct isotp_send_ctx *ctx, case ISOTP_PCI_FS_WAIT: LOG_DBG("Got WAIT frame"); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); if (ctx->wft >= CONFIG_ISOTP_WFTMAX) { LOG_INF("Got to many wait frames"); send_report_error(ctx, ISOTP_N_WFT_OVRN); @@ -949,8 +948,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx) } ctx->state = ISOTP_TX_SEND_SF; - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), - send_can_tx_cb, ctx); + ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); return ret; } @@ -990,8 +988,7 @@ static inline int send_ff(struct isotp_send_ctx *ctx) pull_send_ctx_data(ctx, ctx->tx_addr.dl - index); memcpy(&frame.data[index], data, ctx->tx_addr.dl - index); - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), - send_can_tx_cb, ctx); + ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); return ret; } @@ -1033,8 +1030,7 @@ static inline int send_cf(struct isotp_send_ctx *ctx) frame.dlc = can_bytes_to_dlc(len + index); } - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A), - send_can_tx_cb, ctx); + ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); if (ret == 0) { ctx->sn++; pull_send_ctx_data(ctx, len); @@ -1099,7 +1095,7 @@ static void send_state_machine(struct isotp_send_ctx *ctx) case ISOTP_TX_SEND_FF: send_ff(ctx); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); ctx->state = ISOTP_TX_WAIT_FC; LOG_DBG("SM send FF"); break; @@ -1123,7 +1119,7 @@ static void send_state_machine(struct isotp_send_ctx *ctx) } if (ctx->opts.bs && !ctx->bs) { - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS), K_NO_WAIT); + k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); ctx->state = ISOTP_TX_WAIT_FC; LOG_DBG("BS reached. Wait for FC again"); break; diff --git a/subsys/canbus/isotp/isotp_internal.h b/subsys/canbus/isotp/isotp_internal.h index ac7c28f1ba2..c5b7dec58e7 100644 --- a/subsys/canbus/isotp/isotp_internal.h +++ b/subsys/canbus/isotp/isotp_internal.h @@ -54,12 +54,12 @@ #define ISOTP_4BIT_SF_MAX_CAN_DL 8 -#define ISOTP_BS (CONFIG_ISOTP_BS_TIMEOUT) -#define ISOTP_A (CONFIG_ISOTP_A_TIMEOUT) -#define ISOTP_CR (CONFIG_ISOTP_CR_TIMEOUT) +#define ISOTP_BS_TIMEOUT_MS (CONFIG_ISOTP_BS_TIMEOUT) +#define ISOTP_A_TIMEOUT_MS (CONFIG_ISOTP_A_TIMEOUT) +#define ISOTP_CR_TIMEOUT_MS (CONFIG_ISOTP_CR_TIMEOUT) /* Just before the sender would time out*/ -#define ISOTP_ALLOC_TIMEOUT (CONFIG_ISOTP_A_TIMEOUT - 100) +#define ISOTP_ALLOC_TIMEOUT_MS (CONFIG_ISOTP_A_TIMEOUT - 100) #ifdef __cplusplus extern "C" { From 6b0135b15129bf2a039712d3ede130d4c908121d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 6 Sep 2023 09:27:12 +0200 Subject: [PATCH 0787/4498] canbus: isotp: rename ctx function parameters to rctx/sctx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes clear if the context is a recv_ctx or a send_ctx and improves code readability. Signed-off-by: Martin Jäger --- include/zephyr/canbus/isotp.h | 22 +- subsys/canbus/isotp/isotp.c | 808 +++++++++++++++++----------------- 2 files changed, 405 insertions(+), 425 deletions(-) diff --git a/include/zephyr/canbus/isotp.h b/include/zephyr/canbus/isotp.h index aed5306b16a..d162b8dc531 100644 --- a/include/zephyr/canbus/isotp.h +++ b/include/zephyr/canbus/isotp.h @@ -234,7 +234,7 @@ struct isotp_recv_ctx; * When calling this routine, a filter is applied in the CAN device, and the * context is initialized. The context must be valid until calling unbind. * - * @param ctx Context to store the internal states. + * @param rctx Context to store the internal states. * @param can_dev The CAN device to be used for sending and receiving. * @param rx_addr Identifier for incoming data. * @param tx_addr Identifier for FC frames. @@ -244,7 +244,7 @@ struct isotp_recv_ctx; * @retval ISOTP_N_OK on success * @retval ISOTP_NO_FREE_FILTER if CAN device has no filters left. */ -int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, +int isotp_bind(struct isotp_recv_ctx *rctx, const struct device *can_dev, const struct isotp_msg_id *rx_addr, const struct isotp_msg_id *tx_addr, const struct isotp_fc_opts *opts, @@ -258,9 +258,9 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, * buffers are freed. * The context can be discarded safely after calling this function. * - * @param ctx Context that should be unbound. + * @param rctx Context that should be unbound. */ -void isotp_unbind(struct isotp_recv_ctx *ctx); +void isotp_unbind(struct isotp_recv_ctx *rctx); /** * @brief Read out received data from fifo. @@ -270,7 +270,7 @@ void isotp_unbind(struct isotp_recv_ctx *ctx); * If an error occurs, the function returns a negative number and leaves the * data buffer unchanged. * - * @param ctx Context that is already bound. + * @param rctx Context that is already bound. * @param data Pointer to a buffer where the data is copied to. * @param len Size of the buffer. * @param timeout Timeout for incoming data. @@ -279,8 +279,7 @@ void isotp_unbind(struct isotp_recv_ctx *ctx); * @retval ISOTP_RECV_TIMEOUT when "timeout" timed out * @retval ISOTP_N_* on error */ -int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, - k_timeout_t timeout); +int isotp_recv(struct isotp_recv_ctx *rctx, uint8_t *data, size_t len, k_timeout_t timeout); /** * @brief Get the net buffer on data reception @@ -292,7 +291,7 @@ int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, * The net-buffers are referenced and must be freed with net_buf_unref after the * data is processed. * - * @param ctx Context that is already bound. + * @param rctx Context that is already bound. * @param buffer Pointer where the net_buf pointer is written to. * @param timeout Timeout for incoming data. * @@ -300,8 +299,7 @@ int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, * @retval ISOTP_RECV_TIMEOUT when "timeout" timed out * @retval ISOTP_N_* on error */ -int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer, - k_timeout_t timeout); +int isotp_recv_net(struct isotp_recv_ctx *rctx, struct net_buf **buffer, k_timeout_t timeout); /** * @brief Send data @@ -312,7 +310,7 @@ int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer, * If a complete_cb is given, this function is non-blocking, and the callback * is called on completion with the return value as a parameter. * - * @param ctx Context to store the internal states. + * @param sctx Context to store the internal states. * @param can_dev The CAN device to be used for sending and receiving. * @param data Data to be sent. * @param len Length of the data to be sent. @@ -324,7 +322,7 @@ int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer, * @retval ISOTP_N_OK on success * @retval ISOTP_N_* on error */ -int isotp_send(struct isotp_send_ctx *ctx, const struct device *can_dev, +int isotp_send(struct isotp_send_ctx *sctx, const struct device *can_dev, const uint8_t *data, size_t len, const struct isotp_msg_id *tx_addr, const struct isotp_msg_id *rx_addr, diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 0ef6fce1e8c..710487950c6 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -39,7 +39,7 @@ NET_BUF_POOL_VAR_DEFINE(isotp_tx_pool, CONFIG_ISOTP_TX_BUF_COUNT, CONFIG_ISOTP_BUF_TX_DATA_POOL_SIZE, 0, NULL); #endif -static void receive_state_machine(struct isotp_recv_ctx *ctx); +static void receive_state_machine(struct isotp_recv_ctx *rctx); static inline void prepare_frame(struct can_frame *frame, struct isotp_msg_id *addr) { @@ -64,46 +64,46 @@ static inline void prepare_filter(struct can_filter *filter, struct isotp_msg_id */ static void receive_pool_free(struct net_buf *buf) { - struct isotp_recv_ctx *ctx; - sys_snode_t *ctx_node; + struct isotp_recv_ctx *rctx; + sys_snode_t *rctx_node; net_buf_destroy(buf); - SYS_SLIST_FOR_EACH_NODE(&global_ctx.alloc_list, ctx_node) { - ctx = CONTAINER_OF(ctx_node, struct isotp_recv_ctx, alloc_node); - k_work_submit(&ctx->work); + SYS_SLIST_FOR_EACH_NODE(&global_ctx.alloc_list, rctx_node) { + rctx = CONTAINER_OF(rctx_node, struct isotp_recv_ctx, alloc_node); + k_work_submit(&rctx->work); } } static void receive_ff_sf_pool_free(struct net_buf *buf) { - struct isotp_recv_ctx *ctx; - sys_snode_t *ctx_node; + struct isotp_recv_ctx *rctx; + sys_snode_t *rctx_node; net_buf_destroy(buf); - SYS_SLIST_FOR_EACH_NODE(&global_ctx.ff_sf_alloc_list, ctx_node) { - ctx = CONTAINER_OF(ctx_node, struct isotp_recv_ctx, alloc_node); - k_work_submit(&ctx->work); + SYS_SLIST_FOR_EACH_NODE(&global_ctx.ff_sf_alloc_list, rctx_node) { + rctx = CONTAINER_OF(rctx_node, struct isotp_recv_ctx, alloc_node); + k_work_submit(&rctx->work); } } -static inline void receive_report_error(struct isotp_recv_ctx *ctx, int err) +static inline void receive_report_error(struct isotp_recv_ctx *rctx, int err) { - ctx->state = ISOTP_RX_STATE_ERR; - ctx->error_nr = err; + rctx->state = ISOTP_RX_STATE_ERR; + rctx->error_nr = err; } static void receive_can_tx(const struct device *dev, int error, void *arg) { - struct isotp_recv_ctx *ctx = (struct isotp_recv_ctx *)arg; + struct isotp_recv_ctx *rctx = (struct isotp_recv_ctx *)arg; ARG_UNUSED(dev); if (error != 0) { LOG_ERR("Error sending FC frame (%d)", error); - receive_report_error(ctx, ISOTP_N_ERROR); - k_work_submit(&ctx->work); + receive_report_error(rctx, ISOTP_N_ERROR); + k_work_submit(&rctx->work); } } @@ -134,7 +134,7 @@ static inline uint32_t receive_get_sf_length(struct net_buf *buf, bool fdf) return len; } -static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) +static void receive_send_fc(struct isotp_recv_ctx *rctx, uint8_t fs) { struct can_frame frame; uint8_t *data = frame.data; @@ -143,15 +143,15 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) __ASSERT_NO_MSG(!(fs & ISOTP_PCI_TYPE_MASK)); - prepare_frame(&frame, &ctx->tx_addr); + prepare_frame(&frame, &rctx->tx_addr); - if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - *data++ = ctx->tx_addr.ext_addr; + if ((rctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + *data++ = rctx->tx_addr.ext_addr; } *data++ = ISOTP_PCI_TYPE_FC | fs; - *data++ = ctx->opts.bs; - *data++ = ctx->opts.stmin; + *data++ = rctx->opts.bs; + *data++ = rctx->opts.stmin; payload_len = data - frame.data; #ifdef CONFIG_ISOTP_ENABLE_TX_PADDING @@ -163,11 +163,11 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) frame.dlc = can_bytes_to_dlc(payload_len); #endif - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), receive_can_tx, ctx); + ret = can_send(rctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), receive_can_tx, rctx); if (ret) { LOG_ERR("Can't send FC, (%d)", ret); - receive_report_error(ctx, ISOTP_N_TIMEOUT_A); - receive_state_machine(ctx); + receive_report_error(rctx, ISOTP_N_TIMEOUT_A); + receive_state_machine(rctx); } } @@ -206,172 +206,163 @@ static inline struct net_buf *receive_alloc_buffer_chain(uint32_t len) static void receive_timeout_handler(struct k_timer *timer) { - struct isotp_recv_ctx *ctx = CONTAINER_OF(timer, struct isotp_recv_ctx, timer); + struct isotp_recv_ctx *rctx = CONTAINER_OF(timer, struct isotp_recv_ctx, timer); - switch (ctx->state) { + switch (rctx->state) { case ISOTP_RX_STATE_WAIT_CF: LOG_ERR("Timeout while waiting for CF"); - receive_report_error(ctx, ISOTP_N_TIMEOUT_CR); + receive_report_error(rctx, ISOTP_N_TIMEOUT_CR); break; case ISOTP_RX_STATE_TRY_ALLOC: - ctx->state = ISOTP_RX_STATE_SEND_WAIT; + rctx->state = ISOTP_RX_STATE_SEND_WAIT; break; } - k_work_submit(&ctx->work); + k_work_submit(&rctx->work); } -static int receive_alloc_buffer(struct isotp_recv_ctx *ctx) +static int receive_alloc_buffer(struct isotp_recv_ctx *rctx) { struct net_buf *buf = NULL; - if (ctx->opts.bs == 0) { + if (rctx->opts.bs == 0) { /* Alloc all buffers because we can't wait during reception */ - buf = receive_alloc_buffer_chain(ctx->length); + buf = receive_alloc_buffer_chain(rctx->length); } else { /* Alloc the minimum of the remaining length and bytes of one block */ - uint32_t len = MIN(ctx->length, ctx->opts.bs * (ctx->rx_addr.dl - 1)); + uint32_t len = MIN(rctx->length, rctx->opts.bs * (rctx->rx_addr.dl - 1)); buf = receive_alloc_buffer_chain(len); } if (!buf) { - k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); + k_timer_start(&rctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); - if (ctx->wft == ISOTP_WFT_FIRST) { + if (rctx->wft == ISOTP_WFT_FIRST) { LOG_DBG("Allocation failed. Append to alloc list"); - ctx->wft = 0; - sys_slist_append(&global_ctx.alloc_list, - &ctx->alloc_node); + rctx->wft = 0; + sys_slist_append(&global_ctx.alloc_list, &rctx->alloc_node); } else { LOG_DBG("Allocation failed. Send WAIT frame"); - ctx->state = ISOTP_RX_STATE_SEND_WAIT; - receive_state_machine(ctx); + rctx->state = ISOTP_RX_STATE_SEND_WAIT; + receive_state_machine(rctx); } return -1; } - if (ctx->state == ISOTP_RX_STATE_TRY_ALLOC) { - k_timer_stop(&ctx->timer); - ctx->wft = ISOTP_WFT_FIRST; - sys_slist_find_and_remove(&global_ctx.alloc_list, - &ctx->alloc_node); + if (rctx->state == ISOTP_RX_STATE_TRY_ALLOC) { + k_timer_stop(&rctx->timer); + rctx->wft = ISOTP_WFT_FIRST; + sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); } - if (ctx->opts.bs != 0) { - ctx->buf = buf; + if (rctx->opts.bs != 0) { + rctx->buf = buf; } else { - net_buf_frag_insert(ctx->buf, buf); + net_buf_frag_insert(rctx->buf, buf); } - ctx->act_frag = buf; + rctx->act_frag = buf; return 0; } -static void receive_state_machine(struct isotp_recv_ctx *ctx) +static void receive_state_machine(struct isotp_recv_ctx *rctx) { int ret; uint32_t *ud_rem_len; - switch (ctx->state) { + switch (rctx->state) { case ISOTP_RX_STATE_PROCESS_SF: - ctx->length = receive_get_sf_length(ctx->buf, - (ctx->rx_addr.flags & ISOTP_MSG_FDF) != 0); - ud_rem_len = net_buf_user_data(ctx->buf); + rctx->length = receive_get_sf_length(rctx->buf, + (rctx->rx_addr.flags & ISOTP_MSG_FDF) != 0); + ud_rem_len = net_buf_user_data(rctx->buf); *ud_rem_len = 0; - LOG_DBG("SM process SF of length %d", ctx->length); - net_buf_put(&ctx->fifo, ctx->buf); - ctx->state = ISOTP_RX_STATE_RECYCLE; - receive_state_machine(ctx); + LOG_DBG("SM process SF of length %d", rctx->length); + net_buf_put(&rctx->fifo, rctx->buf); + rctx->state = ISOTP_RX_STATE_RECYCLE; + receive_state_machine(rctx); break; case ISOTP_RX_STATE_PROCESS_FF: - ctx->length = receive_get_ff_length(ctx->buf); - LOG_DBG("SM process FF. Length: %d", ctx->length); - ctx->length -= ctx->buf->len; - if (ctx->opts.bs == 0 && - ctx->length > CONFIG_ISOTP_RX_BUF_COUNT * - CONFIG_ISOTP_RX_BUF_SIZE) { - LOG_ERR("Pkt length is %d but buffer has only %d bytes", - ctx->length, - CONFIG_ISOTP_RX_BUF_COUNT * - CONFIG_ISOTP_RX_BUF_SIZE); - receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW); - receive_state_machine(ctx); + rctx->length = receive_get_ff_length(rctx->buf); + LOG_DBG("SM process FF. Length: %d", rctx->length); + rctx->length -= rctx->buf->len; + if (rctx->opts.bs == 0 && + rctx->length > CONFIG_ISOTP_RX_BUF_COUNT * CONFIG_ISOTP_RX_BUF_SIZE) { + LOG_ERR("Pkt length is %d but buffer has only %d bytes", rctx->length, + CONFIG_ISOTP_RX_BUF_COUNT * CONFIG_ISOTP_RX_BUF_SIZE); + receive_report_error(rctx, ISOTP_N_BUFFER_OVERFLW); + receive_state_machine(rctx); break; } - if (ctx->opts.bs) { - ctx->bs = ctx->opts.bs; - ud_rem_len = net_buf_user_data(ctx->buf); - *ud_rem_len = ctx->length; - net_buf_put(&ctx->fifo, ctx->buf); + if (rctx->opts.bs) { + rctx->bs = rctx->opts.bs; + ud_rem_len = net_buf_user_data(rctx->buf); + *ud_rem_len = rctx->length; + net_buf_put(&rctx->fifo, rctx->buf); } - ctx->wft = ISOTP_WFT_FIRST; - ctx->state = ISOTP_RX_STATE_TRY_ALLOC; + rctx->wft = ISOTP_WFT_FIRST; + rctx->state = ISOTP_RX_STATE_TRY_ALLOC; __fallthrough; case ISOTP_RX_STATE_TRY_ALLOC: LOG_DBG("SM try to allocate"); - k_timer_stop(&ctx->timer); - ret = receive_alloc_buffer(ctx); + k_timer_stop(&rctx->timer); + ret = receive_alloc_buffer(rctx); if (ret) { LOG_DBG("SM allocation failed. Wait for free buffer"); break; } - ctx->state = ISOTP_RX_STATE_SEND_FC; + rctx->state = ISOTP_RX_STATE_SEND_FC; __fallthrough; case ISOTP_RX_STATE_SEND_FC: LOG_DBG("SM send CTS FC frame"); - receive_send_fc(ctx, ISOTP_PCI_FS_CTS); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); - ctx->state = ISOTP_RX_STATE_WAIT_CF; + receive_send_fc(rctx, ISOTP_PCI_FS_CTS); + k_timer_start(&rctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); + rctx->state = ISOTP_RX_STATE_WAIT_CF; break; case ISOTP_RX_STATE_SEND_WAIT: - if (++ctx->wft < CONFIG_ISOTP_WFTMAX) { - LOG_DBG("Send wait frame number %d", ctx->wft); - receive_send_fc(ctx, ISOTP_PCI_FS_WAIT); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); - ctx->state = ISOTP_RX_STATE_TRY_ALLOC; + if (++rctx->wft < CONFIG_ISOTP_WFTMAX) { + LOG_DBG("Send wait frame number %d", rctx->wft); + receive_send_fc(rctx, ISOTP_PCI_FS_WAIT); + k_timer_start(&rctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); + rctx->state = ISOTP_RX_STATE_TRY_ALLOC; break; } - sys_slist_find_and_remove(&global_ctx.alloc_list, - &ctx->alloc_node); - LOG_ERR("Sent %d wait frames. Giving up to alloc now", - ctx->wft); - receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW); + sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); + LOG_ERR("Sent %d wait frames. Giving up to alloc now", rctx->wft); + receive_report_error(rctx, ISOTP_N_BUFFER_OVERFLW); __fallthrough; case ISOTP_RX_STATE_ERR: - LOG_DBG("SM ERR state. err nr: %d", ctx->error_nr); - k_timer_stop(&ctx->timer); + LOG_DBG("SM ERR state. err nr: %d", rctx->error_nr); + k_timer_stop(&rctx->timer); - if (ctx->error_nr == ISOTP_N_BUFFER_OVERFLW) { - receive_send_fc(ctx, ISOTP_PCI_FS_OVFLW); + if (rctx->error_nr == ISOTP_N_BUFFER_OVERFLW) { + receive_send_fc(rctx, ISOTP_PCI_FS_OVFLW); } - k_fifo_cancel_wait(&ctx->fifo); - net_buf_unref(ctx->buf); - ctx->buf = NULL; - ctx->state = ISOTP_RX_STATE_RECYCLE; + k_fifo_cancel_wait(&rctx->fifo); + net_buf_unref(rctx->buf); + rctx->buf = NULL; + rctx->state = ISOTP_RX_STATE_RECYCLE; __fallthrough; case ISOTP_RX_STATE_RECYCLE: LOG_DBG("SM recycle context for next message"); - ctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, K_NO_WAIT); - if (!ctx->buf) { + rctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, K_NO_WAIT); + if (!rctx->buf) { LOG_DBG("No free context. Append to waiters list"); - sys_slist_append(&global_ctx.ff_sf_alloc_list, - &ctx->alloc_node); + sys_slist_append(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); break; } - sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, - &ctx->alloc_node); - ctx->state = ISOTP_RX_STATE_WAIT_FF_SF; + sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); + rctx->state = ISOTP_RX_STATE_WAIT_FF_SF; __fallthrough; case ISOTP_RX_STATE_UNBOUND: break; @@ -383,13 +374,12 @@ static void receive_state_machine(struct isotp_recv_ctx *ctx) static void receive_work_handler(struct k_work *item) { - struct isotp_recv_ctx *ctx = CONTAINER_OF(item, struct isotp_recv_ctx, - work); + struct isotp_recv_ctx *rctx = CONTAINER_OF(item, struct isotp_recv_ctx, work); - receive_state_machine(ctx); + receive_state_machine(rctx); } -static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) +static void process_ff_sf(struct isotp_recv_ctx *rctx, struct can_frame *frame) { int index = 0; uint8_t sf_len; @@ -397,24 +387,24 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) uint32_t rx_sa; /* ISO-TP fixed source address (if used) */ uint8_t can_dl = can_dlc_to_bytes(frame->dlc); - if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - if (frame->data[index++] != ctx->rx_addr.ext_addr) { + if ((rctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + if (frame->data[index++] != rctx->rx_addr.ext_addr) { return; } } - if ((ctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { + if ((rctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { /* store actual CAN ID used by the sender */ - ctx->rx_addr.ext_id = frame->id; + rctx->rx_addr.ext_id = frame->id; /* replace TX target address with RX source address */ rx_sa = (frame->id & ISOTP_FIXED_ADDR_SA_MASK) >> ISOTP_FIXED_ADDR_SA_POS; - ctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_TA_MASK); - ctx->tx_addr.ext_id |= rx_sa << ISOTP_FIXED_ADDR_TA_POS; + rctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_TA_MASK); + rctx->tx_addr.ext_id |= rx_sa << ISOTP_FIXED_ADDR_TA_POS; /* use same priority for TX as in received message */ if (ISOTP_FIXED_ADDR_PRIO_MASK) { - ctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_PRIO_MASK); - ctx->tx_addr.ext_id |= frame->id & ISOTP_FIXED_ADDR_PRIO_MASK; + rctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_PRIO_MASK); + rctx->tx_addr.ext_id |= frame->id & ISOTP_FIXED_ADDR_PRIO_MASK; } } @@ -427,9 +417,9 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) } payload_len = can_dl; - ctx->state = ISOTP_RX_STATE_PROCESS_FF; - ctx->rx_addr.dl = can_dl; - ctx->sn_expected = 1; + rctx->state = ISOTP_RX_STATE_PROCESS_FF; + rctx->rx_addr.dl = can_dl; + rctx->sn_expected = 1; break; case ISOTP_PCI_TYPE_SF: @@ -444,7 +434,7 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) sf_len = frame->data[index] & ISOTP_PCI_SF_DL_MASK; /* Single frames > 8 bytes (CAN-FD only) */ - if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->rx_addr.flags & ISOTP_MSG_FDF) != 0 && + if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (rctx->rx_addr.flags & ISOTP_MSG_FDF) != 0 && can_dl > ISOTP_4BIT_SF_MAX_CAN_DL) { if (sf_len != 0) { LOG_INF("SF DL invalid. Ignore"); @@ -461,7 +451,7 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) return; } - ctx->state = ISOTP_RX_STATE_PROCESS_SF; + rctx->state = ISOTP_RX_STATE_PROCESS_SF; break; default: @@ -469,40 +459,39 @@ static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame) return; } - net_buf_add_mem(ctx->buf, &frame->data[index], payload_len - index); + net_buf_add_mem(rctx->buf, &frame->data[index], payload_len - index); } -static inline void receive_add_mem(struct isotp_recv_ctx *ctx, uint8_t *data, - size_t len) +static inline void receive_add_mem(struct isotp_recv_ctx *rctx, uint8_t *data, size_t len) { - size_t tailroom = net_buf_tailroom(ctx->act_frag); + size_t tailroom = net_buf_tailroom(rctx->act_frag); if (tailroom >= len) { - net_buf_add_mem(ctx->act_frag, data, len); + net_buf_add_mem(rctx->act_frag, data, len); return; } /* Use next fragment that is already allocated*/ - net_buf_add_mem(ctx->act_frag, data, tailroom); - ctx->act_frag = ctx->act_frag->frags; - if (!ctx->act_frag) { + net_buf_add_mem(rctx->act_frag, data, tailroom); + rctx->act_frag = rctx->act_frag->frags; + if (!rctx->act_frag) { LOG_ERR("No fragment left to append data"); - receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW); + receive_report_error(rctx, ISOTP_N_BUFFER_OVERFLW); return; } - net_buf_add_mem(ctx->act_frag, data + tailroom, len - tailroom); + net_buf_add_mem(rctx->act_frag, data + tailroom, len - tailroom); } -static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) +static void process_cf(struct isotp_recv_ctx *rctx, struct can_frame *frame) { - uint32_t *ud_rem_len = (uint32_t *)net_buf_user_data(ctx->buf); + uint32_t *ud_rem_len = (uint32_t *)net_buf_user_data(rctx->buf); int index = 0; uint32_t data_len; uint8_t can_dl = can_dlc_to_bytes(frame->dlc); - if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - if (frame->data[index++] != ctx->rx_addr.ext_addr) { + if ((rctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + if (frame->data[index++] != rctx->rx_addr.ext_addr) { return; } } @@ -510,17 +499,17 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) if ((frame->data[index] & ISOTP_PCI_TYPE_MASK) != ISOTP_PCI_TYPE_CF) { LOG_DBG("Waiting for CF but got something else (%d)", frame->data[index] >> ISOTP_PCI_TYPE_POS); - receive_report_error(ctx, ISOTP_N_UNEXP_PDU); - k_work_submit(&ctx->work); + receive_report_error(rctx, ISOTP_N_UNEXP_PDU); + k_work_submit(&rctx->work); return; } - k_timer_start(&ctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); + k_timer_start(&rctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); - if ((frame->data[index++] & ISOTP_PCI_SN_MASK) != ctx->sn_expected++) { + if ((frame->data[index++] & ISOTP_PCI_SN_MASK) != rctx->sn_expected++) { LOG_ERR("Sequence number mismatch"); - receive_report_error(ctx, ISOTP_N_WRONG_SN); - k_work_submit(&ctx->work); + receive_report_error(rctx, ISOTP_N_WRONG_SN); + k_work_submit(&rctx->work); return; } @@ -528,7 +517,7 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) /* AUTOSAR requirement SWS_CanTp_00346 */ if (can_dl < ISOTP_PADDED_FRAME_DL_MIN) { LOG_ERR("CF DL invalid"); - receive_report_error(ctx, ISOTP_N_ERROR); + receive_report_error(rctx, ISOTP_N_ERROR); return; } #endif @@ -536,50 +525,50 @@ static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame) /* First frame defines the RX data length, consecutive frames * must have the same length (except the last frame) */ - if (can_dl != ctx->rx_addr.dl && ctx->length > can_dl - index) { + if (can_dl != rctx->rx_addr.dl && rctx->length > can_dl - index) { LOG_ERR("CF DL invalid"); - receive_report_error(ctx, ISOTP_N_ERROR); + receive_report_error(rctx, ISOTP_N_ERROR); return; } LOG_DBG("Got CF irq. Appending data"); - data_len = MIN(ctx->length, can_dl - index); - receive_add_mem(ctx, &frame->data[index], data_len); - ctx->length -= data_len; - LOG_DBG("%d bytes remaining", ctx->length); + data_len = MIN(rctx->length, can_dl - index); + receive_add_mem(rctx, &frame->data[index], data_len); + rctx->length -= data_len; + LOG_DBG("%d bytes remaining", rctx->length); - if (ctx->length == 0) { - ctx->state = ISOTP_RX_STATE_RECYCLE; + if (rctx->length == 0) { + rctx->state = ISOTP_RX_STATE_RECYCLE; *ud_rem_len = 0; - net_buf_put(&ctx->fifo, ctx->buf); + net_buf_put(&rctx->fifo, rctx->buf); return; } - if (ctx->opts.bs && !--ctx->bs) { + if (rctx->opts.bs && !--rctx->bs) { LOG_DBG("Block is complete. Allocate new buffer"); - ctx->bs = ctx->opts.bs; - *ud_rem_len = ctx->length; - net_buf_put(&ctx->fifo, ctx->buf); - ctx->state = ISOTP_RX_STATE_TRY_ALLOC; + rctx->bs = rctx->opts.bs; + *ud_rem_len = rctx->length; + net_buf_put(&rctx->fifo, rctx->buf); + rctx->state = ISOTP_RX_STATE_TRY_ALLOC; } } static void receive_can_rx(const struct device *dev, struct can_frame *frame, void *arg) { - struct isotp_recv_ctx *ctx = (struct isotp_recv_ctx *)arg; + struct isotp_recv_ctx *rctx = (struct isotp_recv_ctx *)arg; ARG_UNUSED(dev); - switch (ctx->state) { + switch (rctx->state) { case ISOTP_RX_STATE_WAIT_FF_SF: - __ASSERT_NO_MSG(ctx->buf); - process_ff_sf(ctx, frame); + __ASSERT_NO_MSG(rctx->buf); + process_ff_sf(rctx, frame); break; case ISOTP_RX_STATE_WAIT_CF: - process_cf(ctx, frame); + process_cf(rctx, frame); /* still waiting for more CF */ - if (ctx->state == ISOTP_RX_STATE_WAIT_CF) { + if (rctx->state == ISOTP_RX_STATE_WAIT_CF) { return; } @@ -587,40 +576,39 @@ static void receive_can_rx(const struct device *dev, struct can_frame *frame, vo case ISOTP_RX_STATE_RECYCLE: LOG_ERR("Got a frame but was not yet ready for a new one"); - receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW); + receive_report_error(rctx, ISOTP_N_BUFFER_OVERFLW); break; default: LOG_INF("Got a frame in a state where it is unexpected."); } - k_work_submit(&ctx->work); + k_work_submit(&rctx->work); } -static inline int add_ff_sf_filter(struct isotp_recv_ctx *ctx) +static inline int add_ff_sf_filter(struct isotp_recv_ctx *rctx) { struct can_filter filter; uint32_t mask; - if ((ctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { + if ((rctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { mask = ISOTP_FIXED_ADDR_RX_MASK; } else { mask = CAN_EXT_ID_MASK; } - prepare_filter(&filter, &ctx->rx_addr, mask); + prepare_filter(&filter, &rctx->rx_addr, mask); - ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx, - &filter); - if (ctx->filter_id < 0) { - LOG_ERR("Error adding FF filter [%d]", ctx->filter_id); + rctx->filter_id = can_add_rx_filter(rctx->can_dev, receive_can_rx, rctx, &filter); + if (rctx->filter_id < 0) { + LOG_ERR("Error adding FF filter [%d]", rctx->filter_id); return ISOTP_NO_FREE_FILTER; } return 0; } -int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, +int isotp_bind(struct isotp_recv_ctx *rctx, const struct device *can_dev, const struct isotp_msg_id *rx_addr, const struct isotp_msg_id *tx_addr, const struct isotp_fc_opts *opts, @@ -629,22 +617,22 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, can_mode_t cap; int ret; - __ASSERT(ctx, "ctx is NULL"); + __ASSERT(rctx, "rctx is NULL"); __ASSERT(can_dev, "CAN device is NULL"); __ASSERT(rx_addr && tx_addr, "RX or TX addr is NULL"); __ASSERT(opts, "OPTS is NULL"); - ctx->can_dev = can_dev; - ctx->rx_addr = *rx_addr; - ctx->tx_addr = *tx_addr; - k_fifo_init(&ctx->fifo); + rctx->can_dev = can_dev; + rctx->rx_addr = *rx_addr; + rctx->tx_addr = *tx_addr; + k_fifo_init(&rctx->fifo); __ASSERT(opts->stmin < ISOTP_STMIN_MAX, "STmin limit"); __ASSERT(opts->stmin <= ISOTP_STMIN_MS_MAX || opts->stmin >= ISOTP_STMIN_US_BEGIN, "STmin reserved"); - ctx->opts = *opts; - ctx->state = ISOTP_RX_STATE_WAIT_FF_SF; + rctx->opts = *opts; + rctx->state = ISOTP_RX_STATE_WAIT_FF_SF; if ((rx_addr->flags & ISOTP_MSG_FDF) != 0 || (tx_addr->flags & ISOTP_MSG_FDF) != 0) { ret = can_get_capabilities(can_dev, &cap); @@ -655,68 +643,65 @@ int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev, } LOG_DBG("Binding to addr: 0x%x. Responding on 0x%x", - ctx->rx_addr.ext_id, ctx->tx_addr.ext_id); + rctx->rx_addr.ext_id, rctx->tx_addr.ext_id); - ctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, timeout); - if (!ctx->buf) { + rctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, timeout); + if (!rctx->buf) { LOG_ERR("No buffer for FF left"); return ISOTP_NO_NET_BUF_LEFT; } - ret = add_ff_sf_filter(ctx); + ret = add_ff_sf_filter(rctx); if (ret) { LOG_ERR("Can't add filter for binding"); - net_buf_unref(ctx->buf); - ctx->buf = NULL; + net_buf_unref(rctx->buf); + rctx->buf = NULL; return ret; } - k_work_init(&ctx->work, receive_work_handler); - k_timer_init(&ctx->timer, receive_timeout_handler, NULL); + k_work_init(&rctx->work, receive_work_handler); + k_timer_init(&rctx->timer, receive_timeout_handler, NULL); return ISOTP_N_OK; } -void isotp_unbind(struct isotp_recv_ctx *ctx) +void isotp_unbind(struct isotp_recv_ctx *rctx) { struct net_buf *buf; - if (ctx->filter_id >= 0 && ctx->can_dev) { - can_remove_rx_filter(ctx->can_dev, ctx->filter_id); + if (rctx->filter_id >= 0 && rctx->can_dev) { + can_remove_rx_filter(rctx->can_dev, rctx->filter_id); } - k_timer_stop(&ctx->timer); + k_timer_stop(&rctx->timer); - sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, - &ctx->alloc_node); - sys_slist_find_and_remove(&global_ctx.alloc_list, - &ctx->alloc_node); + sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); + sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); - ctx->state = ISOTP_RX_STATE_UNBOUND; + rctx->state = ISOTP_RX_STATE_UNBOUND; - while ((buf = net_buf_get(&ctx->fifo, K_NO_WAIT))) { + while ((buf = net_buf_get(&rctx->fifo, K_NO_WAIT))) { net_buf_unref(buf); } - k_fifo_cancel_wait(&ctx->fifo); + k_fifo_cancel_wait(&rctx->fifo); - if (ctx->buf) { - net_buf_unref(ctx->buf); + if (rctx->buf) { + net_buf_unref(rctx->buf); } LOG_DBG("Unbound"); } -int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer, - k_timeout_t timeout) +int isotp_recv_net(struct isotp_recv_ctx *rctx, struct net_buf **buffer, k_timeout_t timeout) { struct net_buf *buf; int ret; - buf = net_buf_get(&ctx->fifo, timeout); + buf = net_buf_get(&rctx->fifo, timeout); if (!buf) { - ret = ctx->error_nr ? ctx->error_nr : ISOTP_RECV_TIMEOUT; - ctx->error_nr = 0; + ret = rctx->error_nr ? rctx->error_nr : ISOTP_RECV_TIMEOUT; + rctx->error_nr = 0; return ret; } @@ -726,17 +711,16 @@ int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer, return *(uint32_t *)net_buf_user_data(buf); } -int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, - k_timeout_t timeout) +int isotp_recv(struct isotp_recv_ctx *rctx, uint8_t *data, size_t len, k_timeout_t timeout) { size_t copied, to_copy; int err; - if (!ctx->recv_buf) { - ctx->recv_buf = net_buf_get(&ctx->fifo, timeout); - if (!ctx->recv_buf) { - err = ctx->error_nr ? ctx->error_nr : ISOTP_RECV_TIMEOUT; - ctx->error_nr = 0; + if (!rctx->recv_buf) { + rctx->recv_buf = net_buf_get(&rctx->fifo, timeout); + if (!rctx->recv_buf) { + err = rctx->error_nr ? rctx->error_nr : ISOTP_RECV_TIMEOUT; + rctx->error_nr = 0; return err; } @@ -744,16 +728,16 @@ int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, /* traverse fragments and delete them after copying the data */ copied = 0; - while (ctx->recv_buf && copied < len) { - to_copy = MIN(len - copied, ctx->recv_buf->len); - memcpy((uint8_t *)data + copied, ctx->recv_buf->data, to_copy); + while (rctx->recv_buf && copied < len) { + to_copy = MIN(len - copied, rctx->recv_buf->len); + memcpy((uint8_t *)data + copied, rctx->recv_buf->data, to_copy); - if (ctx->recv_buf->len == to_copy) { + if (rctx->recv_buf->len == to_copy) { /* point recv_buf to next frag */ - ctx->recv_buf = net_buf_frag_del(NULL, ctx->recv_buf); + rctx->recv_buf = net_buf_frag_del(NULL, rctx->recv_buf); } else { /* pull received data from remaining frag(s) */ - net_buf_pull(ctx->recv_buf, to_copy); + net_buf_pull(rctx->recv_buf, to_copy); } copied += to_copy; @@ -762,58 +746,57 @@ int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len, return copied; } -static inline void send_report_error(struct isotp_send_ctx *ctx, uint32_t err) +static inline void send_report_error(struct isotp_send_ctx *sctx, uint32_t err) { - ctx->state = ISOTP_TX_ERR; - ctx->error_nr = err; + sctx->state = ISOTP_TX_ERR; + sctx->error_nr = err; } static void send_can_tx_cb(const struct device *dev, int error, void *arg) { - struct isotp_send_ctx *ctx = (struct isotp_send_ctx *)arg; + struct isotp_send_ctx *sctx = (struct isotp_send_ctx *)arg; ARG_UNUSED(dev); - ctx->tx_backlog--; - k_sem_give(&ctx->tx_sem); + sctx->tx_backlog--; + k_sem_give(&sctx->tx_sem); - if (ctx->state == ISOTP_TX_WAIT_BACKLOG) { - if (ctx->tx_backlog > 0) { + if (sctx->state == ISOTP_TX_WAIT_BACKLOG) { + if (sctx->tx_backlog > 0) { return; } - ctx->state = ISOTP_TX_WAIT_FIN; + sctx->state = ISOTP_TX_WAIT_FIN; } - k_work_submit(&ctx->work); + k_work_submit(&sctx->work); } static void send_timeout_handler(struct k_timer *timer) { - struct isotp_send_ctx *ctx = CONTAINER_OF(timer, struct isotp_send_ctx, timer); + struct isotp_send_ctx *sctx = CONTAINER_OF(timer, struct isotp_send_ctx, timer); - if (ctx->state != ISOTP_TX_SEND_CF) { - send_report_error(ctx, ISOTP_N_TIMEOUT_BS); + if (sctx->state != ISOTP_TX_SEND_CF) { + send_report_error(sctx, ISOTP_N_TIMEOUT_BS); LOG_ERR("Reception of next FC has timed out"); } - k_work_submit(&ctx->work); + k_work_submit(&sctx->work); } -static void send_process_fc(struct isotp_send_ctx *ctx, - struct can_frame *frame) +static void send_process_fc(struct isotp_send_ctx *sctx, struct can_frame *frame) { uint8_t *data = frame->data; - if ((ctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - if (ctx->rx_addr.ext_addr != *data++) { + if ((sctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + if (sctx->rx_addr.ext_addr != *data++) { return; } } if ((*data & ISOTP_PCI_TYPE_MASK) != ISOTP_PCI_TYPE_FC) { LOG_ERR("Got unexpected PDU expected FC"); - send_report_error(ctx, ISOTP_N_UNEXP_PDU); + send_report_error(sctx, ISOTP_N_UNEXP_PDU); return; } @@ -821,104 +804,104 @@ static void send_process_fc(struct isotp_send_ctx *ctx, /* AUTOSAR requirement SWS_CanTp_00349 */ if (frame->dlc < ISOTP_PADDED_FRAME_DL_MIN) { LOG_ERR("FC DL invalid. Ignore"); - send_report_error(ctx, ISOTP_N_ERROR); + send_report_error(sctx, ISOTP_N_ERROR); return; } #endif switch (*data++ & ISOTP_PCI_FS_MASK) { case ISOTP_PCI_FS_CTS: - ctx->state = ISOTP_TX_SEND_CF; - ctx->wft = 0; - ctx->tx_backlog = 0; - k_sem_reset(&ctx->tx_sem); - ctx->opts.bs = *data++; - ctx->opts.stmin = *data++; - ctx->bs = ctx->opts.bs; - LOG_DBG("Got CTS. BS: %d, STmin: %d", ctx->opts.bs, - ctx->opts.stmin); + sctx->state = ISOTP_TX_SEND_CF; + sctx->wft = 0; + sctx->tx_backlog = 0; + k_sem_reset(&sctx->tx_sem); + sctx->opts.bs = *data++; + sctx->opts.stmin = *data++; + sctx->bs = sctx->opts.bs; + LOG_DBG("Got CTS. BS: %d, STmin: %d", sctx->opts.bs, + sctx->opts.stmin); break; case ISOTP_PCI_FS_WAIT: LOG_DBG("Got WAIT frame"); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); - if (ctx->wft >= CONFIG_ISOTP_WFTMAX) { + k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); + if (sctx->wft >= CONFIG_ISOTP_WFTMAX) { LOG_INF("Got to many wait frames"); - send_report_error(ctx, ISOTP_N_WFT_OVRN); + send_report_error(sctx, ISOTP_N_WFT_OVRN); } - ctx->wft++; + sctx->wft++; break; case ISOTP_PCI_FS_OVFLW: LOG_ERR("Got overflow FC frame"); - send_report_error(ctx, ISOTP_N_BUFFER_OVERFLW); + send_report_error(sctx, ISOTP_N_BUFFER_OVERFLW); break; default: - send_report_error(ctx, ISOTP_N_INVALID_FS); + send_report_error(sctx, ISOTP_N_INVALID_FS); } } static void send_can_rx_cb(const struct device *dev, struct can_frame *frame, void *arg) { - struct isotp_send_ctx *ctx = (struct isotp_send_ctx *)arg; + struct isotp_send_ctx *sctx = (struct isotp_send_ctx *)arg; ARG_UNUSED(dev); - if (ctx->state == ISOTP_TX_WAIT_FC) { - k_timer_stop(&ctx->timer); - send_process_fc(ctx, frame); + if (sctx->state == ISOTP_TX_WAIT_FC) { + k_timer_stop(&sctx->timer); + send_process_fc(sctx, frame); } else { LOG_ERR("Got unexpected PDU"); - send_report_error(ctx, ISOTP_N_UNEXP_PDU); + send_report_error(sctx, ISOTP_N_UNEXP_PDU); } - k_work_submit(&ctx->work); + k_work_submit(&sctx->work); } -static size_t get_send_ctx_data_len(struct isotp_send_ctx *ctx) +static size_t get_send_ctx_data_len(struct isotp_send_ctx *sctx) { - return ctx->is_net_buf ? net_buf_frags_len(ctx->buf) : ctx->len; + return sctx->is_net_buf ? net_buf_frags_len(sctx->buf) : sctx->len; } -static const uint8_t *get_send_ctx_data(struct isotp_send_ctx *ctx) +static const uint8_t *get_send_ctx_data(struct isotp_send_ctx *sctx) { - if (ctx->is_net_buf) { - return ctx->buf->data; + if (sctx->is_net_buf) { + return sctx->buf->data; } else { - return ctx->data; + return sctx->data; } } -static void pull_send_ctx_data(struct isotp_send_ctx *ctx, size_t len) +static void pull_send_ctx_data(struct isotp_send_ctx *sctx, size_t len) { - if (ctx->is_net_buf) { - net_buf_pull_mem(ctx->buf, len); + if (sctx->is_net_buf) { + net_buf_pull_mem(sctx->buf, len); } else { - ctx->data += len; - ctx->len -= len; + sctx->data += len; + sctx->len -= len; } } -static inline int send_sf(struct isotp_send_ctx *ctx) +static inline int send_sf(struct isotp_send_ctx *sctx) { struct can_frame frame; - size_t len = get_ctx_data_length(ctx); + size_t len = get_send_ctx_data_len(sctx); int index = 0; int ret; const uint8_t *data; - prepare_frame(&frame, &ctx->tx_addr); + prepare_frame(&frame, &sctx->tx_addr); - data = get_data_ctx(ctx); - pull_data_ctx(ctx, len); + data = get_send_ctx_data(sctx); + pull_send_ctx_data(sctx, len); - if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - frame.data[index++] = ctx->tx_addr.ext_addr; + if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + frame.data[index++] = sctx->tx_addr.ext_addr; } - if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && len > ISOTP_4BIT_SF_MAX_CAN_DL - 1 - index) { frame.data[index++] = ISOTP_PCI_TYPE_SF; frame.data[index++] = len; @@ -926,7 +909,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx) frame.data[index++] = ISOTP_PCI_TYPE_SF | len; } - if (len > ctx->tx_addr.dl - index) { + if (len > sctx->tx_addr.dl - index) { LOG_ERR("SF len does not fit DL"); return -ENOSPC; } @@ -934,7 +917,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx) memcpy(&frame.data[index], data, len); if (IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) || - (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && len + index > ISOTP_PADDED_FRAME_DL_MIN)) { /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. * Mandatory for ISO-TP CAN-FD frames > 8 bytes. @@ -947,25 +930,25 @@ static inline int send_sf(struct isotp_send_ctx *ctx) frame.dlc = can_bytes_to_dlc(len + index); } - ctx->state = ISOTP_TX_SEND_SF; - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); + sctx->state = ISOTP_TX_SEND_SF; + ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); return ret; } -static inline int send_ff(struct isotp_send_ctx *ctx) +static inline int send_ff(struct isotp_send_ctx *sctx) { struct can_frame frame; int index = 0; - size_t len = get_send_ctx_data_len(ctx); + size_t len = get_send_ctx_data_len(sctx); int ret; const uint8_t *data; - prepare_frame(&frame, &ctx->tx_addr); + prepare_frame(&frame, &sctx->tx_addr); - frame.dlc = can_bytes_to_dlc(ctx->tx_addr.dl); + frame.dlc = can_bytes_to_dlc(sctx->tx_addr.dl); - if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - frame.data[index++] = ctx->tx_addr.ext_addr; + if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + frame.data[index++] = sctx->tx_addr.ext_addr; } if (len > 0xFFF) { @@ -983,16 +966,16 @@ static inline int send_ff(struct isotp_send_ctx *ctx) /* According to ISO FF has sn 0 and is incremented to one * although it's not part of the FF frame */ - ctx->sn = 1; - data = get_send_ctx_data(ctx); - pull_send_ctx_data(ctx, ctx->tx_addr.dl - index); - memcpy(&frame.data[index], data, ctx->tx_addr.dl - index); + sctx->sn = 1; + data = get_send_ctx_data(sctx); + pull_send_ctx_data(sctx, sctx->tx_addr.dl - index); + memcpy(&frame.data[index], data, sctx->tx_addr.dl - index); - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); + ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); return ret; } -static inline int send_cf(struct isotp_send_ctx *ctx) +static inline int send_cf(struct isotp_send_ctx *sctx) { struct can_frame frame; int index = 0; @@ -1001,23 +984,23 @@ static inline int send_cf(struct isotp_send_ctx *ctx) int rem_len; const uint8_t *data; - prepare_frame(&frame, &ctx->tx_addr); + prepare_frame(&frame, &sctx->tx_addr); - if ((ctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { - frame.data[index++] = ctx->tx_addr.ext_addr; + if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { + frame.data[index++] = sctx->tx_addr.ext_addr; } /*sn wraps around at 0xF automatically because it has a 4 bit size*/ - frame.data[index++] = ISOTP_PCI_TYPE_CF | ctx->sn; + frame.data[index++] = ISOTP_PCI_TYPE_CF | sctx->sn; - rem_len = get_send_ctx_data_len(ctx); - len = MIN(rem_len, ctx->tx_addr.dl - index); + rem_len = get_send_ctx_data_len(sctx); + len = MIN(rem_len, sctx->tx_addr.dl - index); rem_len -= len; - data = get_send_ctx_data(ctx); + data = get_send_ctx_data(sctx); memcpy(&frame.data[index], data, len); if (IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) || - (IS_ENABLED(CONFIG_CAN_FD_MODE) && (ctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && + (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && len + index > ISOTP_PADDED_FRAME_DL_MIN)) { /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. * Mandatory for ISO-TP CAN-FD frames > 8 bytes. @@ -1030,12 +1013,12 @@ static inline int send_cf(struct isotp_send_ctx *ctx) frame.dlc = can_bytes_to_dlc(len + index); } - ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, ctx); + ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); if (ret == 0) { - ctx->sn++; - pull_send_ctx_data(ctx, len); - ctx->bs--; - ctx->tx_backlog++; + sctx->sn++; + pull_send_ctx_data(sctx, len); + sctx->bs--; + sctx->tx_backlog++; } ret = ret ? ret : rem_len; @@ -1043,28 +1026,28 @@ static inline int send_cf(struct isotp_send_ctx *ctx) } #ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS -static inline void free_send_ctx(struct isotp_send_ctx **ctx) +static inline void free_send_ctx(struct isotp_send_ctx **sctx) { - if ((*ctx)->is_net_buf) { - net_buf_unref((*ctx)->buf); - (*ctx)->buf = NULL; + if ((*sctx)->is_net_buf) { + net_buf_unref((*sctx)->buf); + (*sctx)->buf = NULL; } - if ((*ctx)->is_ctx_slab) { - k_mem_slab_free(&ctx_slab, (void *)*ctx); + if ((*sctx)->is_ctx_slab) { + k_mem_slab_free(&ctx_slab, (void *)*sctx); } } -static int alloc_send_ctx(struct isotp_send_ctx **ctx, k_timeout_t timeout) +static int alloc_send_ctx(struct isotp_send_ctx **sctx, k_timeout_t timeout) { int ret; - ret = k_mem_slab_alloc(&ctx_slab, (void **)ctx, timeout); + ret = k_mem_slab_alloc(&ctx_slab, (void **)sctx, timeout); if (ret) { return ISOTP_NO_CTX_LEFT; } - (*ctx)->is_ctx_slab = 1; + (*sctx)->is_ctx_slab = 1; return 0; } @@ -1087,56 +1070,56 @@ static k_timeout_t stmin_to_timeout(uint8_t stmin) return K_MSEC(stmin); } -static void send_state_machine(struct isotp_send_ctx *ctx) +static void send_state_machine(struct isotp_send_ctx *sctx) { int ret; - switch (ctx->state) { + switch (sctx->state) { case ISOTP_TX_SEND_FF: - send_ff(ctx); - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); - ctx->state = ISOTP_TX_WAIT_FC; + send_ff(sctx); + k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); + sctx->state = ISOTP_TX_WAIT_FC; LOG_DBG("SM send FF"); break; case ISOTP_TX_SEND_CF: LOG_DBG("SM send CF"); - k_timer_stop(&ctx->timer); + k_timer_stop(&sctx->timer); do { - ret = send_cf(ctx); + ret = send_cf(sctx); if (!ret) { - ctx->state = ISOTP_TX_WAIT_BACKLOG; + sctx->state = ISOTP_TX_WAIT_BACKLOG; break; } if (ret < 0) { LOG_ERR("Failed to send CF"); - send_report_error(ctx, ret == -EAGAIN ? + send_report_error(sctx, ret == -EAGAIN ? ISOTP_N_TIMEOUT_A : ISOTP_N_ERROR); break; } - if (ctx->opts.bs && !ctx->bs) { - k_timer_start(&ctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); - ctx->state = ISOTP_TX_WAIT_FC; + if (sctx->opts.bs && !sctx->bs) { + k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); + sctx->state = ISOTP_TX_WAIT_FC; LOG_DBG("BS reached. Wait for FC again"); break; - } else if (ctx->opts.stmin) { - ctx->state = ISOTP_TX_WAIT_ST; + } else if (sctx->opts.stmin) { + sctx->state = ISOTP_TX_WAIT_ST; break; } /* Ensure FIFO style transmission of CF */ - k_sem_take(&ctx->tx_sem, K_FOREVER); + k_sem_take(&sctx->tx_sem, K_FOREVER); } while (ret > 0); break; case ISOTP_TX_WAIT_ST: - k_timer_start(&ctx->timer, stmin_to_timeout(ctx->opts.stmin), K_NO_WAIT); - ctx->state = ISOTP_TX_SEND_CF; + k_timer_start(&sctx->timer, stmin_to_timeout(sctx->opts.stmin), K_NO_WAIT); + sctx->state = ISOTP_TX_SEND_CF; LOG_DBG("SM wait ST"); break; @@ -1146,21 +1129,21 @@ static void send_state_machine(struct isotp_send_ctx *ctx) case ISOTP_TX_SEND_SF: __fallthrough; case ISOTP_TX_WAIT_FIN: - if (ctx->filter_id >= 0) { - can_remove_rx_filter(ctx->can_dev, ctx->filter_id); + if (sctx->filter_id >= 0) { + can_remove_rx_filter(sctx->can_dev, sctx->filter_id); } LOG_DBG("SM finish"); - k_timer_stop(&ctx->timer); + k_timer_stop(&sctx->timer); - if (ctx->has_callback) { - ctx->fin_cb.cb(ctx->error_nr, ctx->fin_cb.arg); - free_send_ctx(&ctx); + if (sctx->has_callback) { + sctx->fin_cb.cb(sctx->error_nr, sctx->fin_cb.arg); + free_send_ctx(&sctx); } else { - k_sem_give(&ctx->fin_sem); + k_sem_give(&sctx->fin_sem); } - ctx->state = ISOTP_TX_STATE_RESET; + sctx->state = ISOTP_TX_STATE_RESET; break; default: @@ -1170,29 +1153,28 @@ static void send_state_machine(struct isotp_send_ctx *ctx) static void send_work_handler(struct k_work *item) { - struct isotp_send_ctx *ctx = CONTAINER_OF(item, struct isotp_send_ctx, - work); + struct isotp_send_ctx *sctx = CONTAINER_OF(item, struct isotp_send_ctx, work); - send_state_machine(ctx); + send_state_machine(sctx); } -static inline int add_fc_filter(struct isotp_send_ctx *ctx) +static inline int add_fc_filter(struct isotp_send_ctx *sctx) { struct can_filter filter; - prepare_filter(&filter, &ctx->rx_addr, CAN_EXT_ID_MASK); + prepare_filter(&filter, &sctx->rx_addr, CAN_EXT_ID_MASK); - ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx, + sctx->filter_id = can_add_rx_filter(sctx->can_dev, send_can_rx_cb, sctx, &filter); - if (ctx->filter_id < 0) { - LOG_ERR("Error adding FC filter [%d]", ctx->filter_id); + if (sctx->filter_id < 0) { + LOG_ERR("Error adding FC filter [%d]", sctx->filter_id); return ISOTP_NO_FREE_FILTER; } return 0; } -static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, +static int send(struct isotp_send_ctx *sctx, const struct device *can_dev, const struct isotp_msg_id *tx_addr, const struct isotp_msg_id *rx_addr, isotp_tx_callback_t complete_cb, void *cb_arg) @@ -1201,7 +1183,7 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, size_t len; int ret; - __ASSERT_NO_MSG(ctx); + __ASSERT_NO_MSG(sctx); __ASSERT_NO_MSG(can_dev); __ASSERT_NO_MSG(rx_addr && tx_addr); @@ -1214,29 +1196,29 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, } if (complete_cb) { - ctx->fin_cb.cb = complete_cb; - ctx->fin_cb.arg = cb_arg; - ctx->has_callback = 1; + sctx->fin_cb.cb = complete_cb; + sctx->fin_cb.arg = cb_arg; + sctx->has_callback = 1; } else { - k_sem_init(&ctx->fin_sem, 0, 1); - ctx->has_callback = 0; + k_sem_init(&sctx->fin_sem, 0, 1); + sctx->has_callback = 0; } - k_sem_init(&ctx->tx_sem, 0, 1); - ctx->can_dev = can_dev; - ctx->tx_addr = *tx_addr; - ctx->rx_addr = *rx_addr; - ctx->error_nr = ISOTP_N_OK; - ctx->wft = 0; - k_work_init(&ctx->work, send_work_handler); - k_timer_init(&ctx->timer, send_timeout_handler, NULL); + k_sem_init(&sctx->tx_sem, 0, 1); + sctx->can_dev = can_dev; + sctx->tx_addr = *tx_addr; + sctx->rx_addr = *rx_addr; + sctx->error_nr = ISOTP_N_OK; + sctx->wft = 0; + k_work_init(&sctx->work, send_work_handler); + k_timer_init(&sctx->timer, send_timeout_handler, NULL); - switch (ctx->tx_addr.dl) { + switch (sctx->tx_addr.dl) { case 0: - if ((ctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { - ctx->tx_addr.dl = 8; + if ((sctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { + sctx->tx_addr.dl = 8; } else { - ctx->tx_addr.dl = 64; + sctx->tx_addr.dl = 64; } __fallthrough; case 8: @@ -1248,65 +1230,65 @@ static int send(struct isotp_send_ctx *ctx, const struct device *can_dev, case 32: case 48: case 64: - if ((ctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { + if ((sctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { LOG_ERR("TX_DL > 8 only supported with FD mode"); return ISOTP_N_ERROR; } break; default: - LOG_ERR("Invalid TX_DL: %u", ctx->tx_addr.dl); + LOG_ERR("Invalid TX_DL: %u", sctx->tx_addr.dl); return ISOTP_N_ERROR; } - len = get_send_ctx_data_len(ctx); + len = get_send_ctx_data_len(sctx); LOG_DBG("Send %zu bytes to addr 0x%x and listen on 0x%x", len, - ctx->tx_addr.ext_id, ctx->rx_addr.ext_id); + sctx->tx_addr.ext_id, sctx->rx_addr.ext_id); /* Single frames > 8 bytes use an additional byte for length (CAN-FD only) */ - if (len > ctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - - ((ctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { - ret = add_fc_filter(ctx); + if (len > sctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - + ((sctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { + ret = add_fc_filter(sctx); if (ret) { LOG_ERR("Can't add fc filter: %d", ret); - free_send_ctx(&ctx); + free_send_ctx(&sctx); return ret; } LOG_DBG("Starting work to send FF"); - ctx->state = ISOTP_TX_SEND_FF; - k_work_submit(&ctx->work); + sctx->state = ISOTP_TX_SEND_FF; + k_work_submit(&sctx->work); } else { LOG_DBG("Sending single frame"); - ctx->filter_id = -1; - ret = send_sf(ctx); + sctx->filter_id = -1; + ret = send_sf(sctx); if (ret) { - free_send_ctx(&ctx); + free_send_ctx(&sctx); return ret == -EAGAIN ? ISOTP_N_TIMEOUT_A : ISOTP_N_ERROR; } } if (!complete_cb) { - k_sem_take(&ctx->fin_sem, K_FOREVER); - ret = ctx->error_nr; - free_send_ctx(&ctx); + k_sem_take(&sctx->fin_sem, K_FOREVER); + ret = sctx->error_nr; + free_send_ctx(&sctx); return ret; } return ISOTP_N_OK; } -int isotp_send(struct isotp_send_ctx *ctx, const struct device *can_dev, +int isotp_send(struct isotp_send_ctx *sctx, const struct device *can_dev, const uint8_t *data, size_t len, const struct isotp_msg_id *tx_addr, const struct isotp_msg_id *rx_addr, isotp_tx_callback_t complete_cb, void *cb_arg) { - ctx->data = data; - ctx->len = len; - ctx->is_ctx_slab = 0; - ctx->is_net_buf = 0; + sctx->data = data; + sctx->len = len; + sctx->is_ctx_slab = 0; + sctx->is_net_buf = 0; - return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); + return send(sctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); } #ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS @@ -1318,21 +1300,21 @@ int isotp_send_ctx_buf(const struct device *can_dev, isotp_tx_callback_t complete_cb, void *cb_arg, k_timeout_t timeout) { - struct isotp_send_ctx *ctx; + struct isotp_send_ctx *sctx; int ret; __ASSERT_NO_MSG(data); - ret = alloc_send_ctx(&ctx, timeout); + ret = alloc_send_ctx(&sctx, timeout); if (ret) { return ret; } - ctx->data = data; - ctx->len = len; - ctx->is_net_buf = 0; + sctx->data = data; + sctx->len = len; + sctx->is_net_buf = 0; - return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); + return send(sctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); } int isotp_send_net_ctx_buf(const struct device *can_dev, @@ -1342,20 +1324,20 @@ int isotp_send_net_ctx_buf(const struct device *can_dev, isotp_tx_callback_t complete_cb, void *cb_arg, k_timeout_t timeout) { - struct isotp_send_ctx *ctx; + struct isotp_send_ctx *sctx; int ret; __ASSERT_NO_MSG(data); - ret = alloc_send_ctx(&ctx, timeout); + ret = alloc_send_ctx(&sctx, timeout); if (ret) { return ret; } - ctx->is_net_buf = 1; - ctx->buf = data; + sctx->is_net_buf = 1; + sctx->buf = data; - return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); + return send(sctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); } #ifdef CONFIG_ISOTP_USE_TX_BUF @@ -1366,29 +1348,29 @@ int isotp_send_buf(const struct device *can_dev, isotp_tx_callback_t complete_cb, void *cb_arg, k_timeout_t timeout) { - struct isotp_send_ctx *ctx; + struct isotp_send_ctx *sctx; struct net_buf *buf; int ret; __ASSERT_NO_MSG(data); - ret = alloc_send_ctx(&ctx, timeout); + ret = alloc_send_ctx(&sctx, timeout); if (ret) { return ret; } buf = net_buf_alloc_len(&isotp_tx_pool, len, timeout); if (!buf) { - k_mem_slab_free(&ctx_slab, (void *)ctx); + k_mem_slab_free(&ctx_slab, (void *)sctx); return ISOTP_NO_BUF_DATA_LEFT; } net_buf_add_mem(buf, data, len); - ctx->is_net_buf = 1; - ctx->buf = buf; + sctx->is_net_buf = 1; + sctx->buf = buf; - return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); + return send(sctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg); } #endif /*CONFIG_ISOTP_USE_TX_BUF*/ #endif /*CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS*/ From 0d5c508fc78b002ffae3d4445acb6c5cf4fa8cff Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 12 Sep 2023 11:46:57 +0100 Subject: [PATCH 0788/4498] mgmt: mcumgr: grp: fs_mgmt: Update file upload errors Updates possible return errors for fs mgmt file upload, to clarify when a provided path is on a read-only filesystem or if the mount point does not exist. Signed-off-by: Jamie McCrae --- include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h | 6 ++++++ subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h index 5f07c2ed2d8..b48ea8edc8e 100644 --- a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h @@ -73,6 +73,12 @@ enum fs_mgmt_err_code_t { /** The requested checksum or hash type was not found or is not supported by this build. */ FS_MGMT_ERR_CHECKSUM_HASH_NOT_FOUND, + + /** The specified mount point was not found or is not mounted. */ + FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND, + + /** The specified mount point is that of a read-only filesystem. */ + FS_MGMT_ERR_READ_ONLY_FILESYSTEM, }; #ifdef __cplusplus diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c index 571d4c01515..2d0402fc451 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c @@ -425,7 +425,9 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc == -EINVAL) { rc = FS_MGMT_ERR_FILE_INVALID_NAME; } else if (rc == -ENOENT) { - rc = FS_MGMT_ERR_FILE_NOT_FOUND; + rc = FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND; + } else if (rc == -EROFS) { + rc = FS_MGMT_ERR_READ_ONLY_FILESYSTEM; } else { rc = FS_MGMT_ERR_UNKNOWN; } @@ -909,7 +911,18 @@ static int fs_mgmt_translate_error_code(uint16_t err) int rc; switch (err) { + case FS_MGMT_ERR_FILE_INVALID_NAME: + case FS_MGMT_ERR_CHECKSUM_HASH_NOT_FOUND: + rc = MGMT_ERR_EINVAL; + break; + + case FS_MGMT_ERR_FILE_NOT_FOUND: + case FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND: + rc = MGMT_ERR_ENOENT; + break; + case FS_MGMT_ERR_UNKNOWN: + case FS_MGMT_ERR_FILE_IS_DIRECTORY: case FS_MGMT_ERR_FILE_OPEN_FAILED: case FS_MGMT_ERR_FILE_SEEK_FAILED: case FS_MGMT_ERR_FILE_READ_FAILED: @@ -918,6 +931,7 @@ static int fs_mgmt_translate_error_code(uint16_t err) case FS_MGMT_ERR_FILE_WRITE_FAILED: case FS_MGMT_ERR_FILE_OFFSET_NOT_VALID: case FS_MGMT_ERR_FILE_OFFSET_LARGER_THAN_FILE: + case FS_MGMT_ERR_READ_ONLY_FILESYSTEM: default: rc = MGMT_ERR_EUNKNOWN; } From 6e78b435beb69a0fce73485f093682849fb2085f Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 20 Sep 2023 20:36:36 +0000 Subject: [PATCH 0789/4498] Bluetooth: BAP: drop unused variable stream_in_subgroup is set but never used here. Signed-off-by: Fabio Baltieri --- subsys/bluetooth/audio/bap_broadcast_source.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index a6aaf43a60b..c52c31c005a 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -839,7 +839,6 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, struct bt_bap_stream *subgroup_stream; struct bt_iso_chan_io_qos *iso_qos; struct bt_bap_stream *stream; - bool stream_in_subgroup; size_t stream_idx; stream_param = &subgroup_param->params[j]; @@ -848,7 +847,6 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, stream_idx = 0U; SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, subgroup_stream, _node) { if (subgroup_stream == stream) { - stream_in_subgroup = true; break; } From 09f02edfa429cfe4c225217affc9ded22cb42c32 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 20 Sep 2023 20:48:05 +0000 Subject: [PATCH 0790/4498] Bluetooth: CAP: drop non existing qos qos got dropped from bt_cap_unicast_audio_start_stream_param in 71b1591337. Signed-off-by: Fabio Baltieri --- tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c index 97c8d876b47..abc1098cd9d 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c @@ -664,7 +664,6 @@ static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group, bool stream_param[1].stream = &unicast_client_source_streams[0]; stream_param[1].ep = unicast_source_eps[bt_conn_index(default_conn)][0]; stream_param[1].codec_cfg = &unicast_preset_16_2_1.codec_cfg; - stream_param[1].qos = &unicast_preset_16_2_1.qos; UNSET_FLAG(flag_started); From 5b4eb9bc76b68c50d1babdef988efcce2491ce4a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 6 Jul 2023 06:05:42 +0530 Subject: [PATCH 0791/4498] Bluetooth: Controller: Minor rename ull_adv_sync_iso_created() Minor rename to ull_adv_sync_iso_created(). Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_adv_internal.h | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_sync.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h index 00bf3c126df..f4d059e0cd3 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h @@ -205,7 +205,7 @@ ull_adv_aux_hdr_len_fill(struct pdu_adv_com_ext_adv *com_hdr, uint8_t len) void ull_adv_sync_started_stopped(struct ll_adv_aux_set *aux); /* notify adv_sync_set that an iso instance has been created for it */ -void ull_adv_iso_created(struct ll_adv_sync_set *sync); +void ull_adv_sync_iso_created(struct ll_adv_sync_set *sync); #endif /* CONFIG_BT_CTLR_ADV_EXT */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 89e66ff99e5..cb53f913b01 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -487,7 +487,7 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) /* Notify the sync instance */ - ull_adv_iso_created(HDR_LLL2ULL(lll_adv_sync)); + ull_adv_sync_iso_created(HDR_LLL2ULL(lll_adv_sync)); #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ /* Commit the BIGInfo in the ACAD field of Periodic Advertising */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c index bbb1b351848..f1f521ca235 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c @@ -222,7 +222,7 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags) } #if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) -void ull_adv_iso_created(struct ll_adv_sync_set *sync) +void ull_adv_sync_iso_created(struct ll_adv_sync_set *sync) { if (sync->lll.iso && sync->is_started) { uint8_t iso_handle = sync->lll.iso->handle; From 87138e7ee34a54e609f45f3fb1acb5475e745cea Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 5 Jul 2023 05:29:24 +0530 Subject: [PATCH 0792/4498] Bluetooth: Controller: Calculate Broadcast ISO event overheads Calculate Broadcast ISO event overheads due to extended and periodic advertising events. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/ll_sw/ull_adv_iso.c | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index cb53f913b01..4551fac228d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -97,13 +97,19 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, struct ll_adv_iso_set *adv_iso; struct pdu_adv *pdu_prev, *pdu; struct pdu_big_info *big_info; + uint32_t ticks_slot_overhead; + struct ll_adv_sync_set *sync; + struct ll_adv_aux_set *aux; uint32_t event_spacing_max; uint8_t pdu_big_info_size; uint32_t iso_interval_us; uint32_t latency_packing; + uint32_t ticks_slot_sync; + uint32_t ticks_slot_aux; memq_link_t *link_cmplt; memq_link_t *link_term; struct ll_adv_set *adv; + uint32_t slot_overhead; uint32_t event_spacing; uint16_t ctrl_spacing; uint8_t sdu_per_event; @@ -275,14 +281,48 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, lll_adv_iso->num_bis; event_spacing = latency_packing + ctrl_spacing + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - /* FIXME: calculate overheads due to extended and periodic advertising. + + /* Calculate overheads due to extended advertising. */ + aux = HDR_LLL2ULL(adv->lll.aux); + ticks_slot_aux = aux->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, + aux->ull.ticks_prepare_to_start); + } else { + ticks_slot_overhead = 0U; + } + ticks_slot_aux += ticks_slot_overhead; + + /* Calculate overheads due to periodic advertising. */ + sync = HDR_LLL2ULL(lll_adv_sync); + ticks_slot_sync = sync->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, + sync->ull.ticks_prepare_to_start); + } else { + ticks_slot_overhead = 0U; + } + ticks_slot_sync += ticks_slot_overhead; + + /* Calculate total overheads due to extended and periodic advertising */ + if (CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET > 0U) { + ticks_slot_overhead = MAX(ticks_slot_aux, ticks_slot_sync); + } else { + ticks_slot_overhead = ticks_slot_aux + ticks_slot_sync; + } + + /* Calculate max available ISO event spacing */ + slot_overhead = HAL_TICKER_TICKS_TO_US(ticks_slot_overhead); + if (slot_overhead < iso_interval_us) { + event_spacing_max = iso_interval_us - slot_overhead; + } else { + event_spacing_max = 0U; + } + + /* Check if ISO interval too small to fit the calculated BIG event + * timing required for the supplied BIG create parameters. */ - event_spacing_max = iso_interval_us - 2000U; if (event_spacing > event_spacing_max) { - /* ISO interval too small to fit the calculated BIG event - * timing required for the supplied BIG create parameters. - */ - /* Release allocated link buffers */ ll_rx_link_release(link_cmplt); ll_rx_link_release(link_term); From 0f2980db15f3448533c8a978e71daffbde2cdbf2 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 31 Jan 2023 12:30:49 +0530 Subject: [PATCH 0793/4498] Bluetooth: Controller: Maximize BIG event length and preempt PTO & CTRL Maximize BIG event length to extend upto ISO interval, and allow PTO and Control subevents to be pre-emptible. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 12 +++++ .../bluetooth/controller/ll_sw/ull_adv_iso.c | 51 +++++++++++++------ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 5fb2c54d085..1fa9031d47f 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -386,6 +386,18 @@ config BT_CTLR_ADV_RESERVE_MAX corresponding to the Advertising Data present at the time of the start/enable of Advertising is used. +config BT_CTLR_ADV_ISO_RESERVE_MAX + bool "Use maximum Broadcast ISO event time reservation" + depends on BT_CTLR_ADV_ISO + default y + help + Use maximum Broadcast ISO event time reservation. If disabled, then + time reservation does not include the pre-transmissions of the last + BIS and any Control subevents. This will allow extended or periodic + advertising events to preempt the BIG events but allow higher radio + utilizations by allowing larger BIG events when not overlapping with + extended or periodic advertising. + config BT_CTLR_ADV_AUX_SYNC_OFFSET int "Pre-defined offset between AUX_ADV_IND and AUX_SYNC_IND" depends on BT_CTLR_ADV_PERIODIC diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 4551fac228d..de78352baa2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -282,27 +282,41 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, event_spacing = latency_packing + ctrl_spacing + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + /* Check if aux context allocated before we are creating ISO */ + if (adv->lll.aux) { + aux = HDR_LLL2ULL(adv->lll.aux); + } else { + aux = NULL; + } + /* Calculate overheads due to extended advertising. */ - aux = HDR_LLL2ULL(adv->lll.aux); - ticks_slot_aux = aux->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, - aux->ull.ticks_prepare_to_start); + if (aux && aux->is_started) { + ticks_slot_aux = aux->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, + aux->ull.ticks_prepare_to_start); + } else { + ticks_slot_overhead = 0U; + } + ticks_slot_aux += ticks_slot_overhead; } else { - ticks_slot_overhead = 0U; + ticks_slot_aux = 0U; } - ticks_slot_aux += ticks_slot_overhead; /* Calculate overheads due to periodic advertising. */ sync = HDR_LLL2ULL(lll_adv_sync); - ticks_slot_sync = sync->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, - sync->ull.ticks_prepare_to_start); + if (sync->is_started) { + ticks_slot_sync = sync->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, + sync->ull.ticks_prepare_to_start); + } else { + ticks_slot_overhead = 0U; + } + ticks_slot_sync += ticks_slot_overhead; } else { - ticks_slot_overhead = 0U; + ticks_slot_sync = 0U; } - ticks_slot_sync += ticks_slot_overhead; /* Calculate total overheads due to extended and periodic advertising */ if (CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET > 0U) { @@ -1008,8 +1022,15 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, EVENT_MSS_US; ctrl_spacing = PDU_BIS_US(sizeof(struct pdu_big_ctrl), lll_iso->enc, lll_iso->phy, lll_iso->phy_flags); - slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + - ctrl_spacing; + + if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX)) { + slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + + ctrl_spacing; + } else { + slot_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - + lll_iso->ptc); + } + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; adv_iso->ull.ticks_active_to_start = 0U; From 3fba1a18e70dbf6d2993ce9fb9d5424601ddce16 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 6 Jul 2023 06:03:43 +0530 Subject: [PATCH 0794/4498] Bluetooth: Controller: Use max time when scheduling Broadcast ISO Use maximum event time length when scheduling Broadcast ISO events. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/ull_adv_internal.h | 3 + .../bluetooth/controller/ll_sw/ull_adv_iso.c | 63 +++++++++++++------ subsys/bluetooth/controller/ll_sw/ull_sched.c | 5 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h index f4d059e0cd3..a2a0db7391f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h @@ -322,6 +322,9 @@ struct lll_adv_iso_stream *ull_adv_iso_stream_get(uint16_t handle); /* helper function to release stream instances */ void ull_adv_iso_stream_release(struct ll_adv_iso_set *adv_iso); +/* helper function to return time reservation for Broadcast ISO event */ +uint32_t ull_adv_iso_max_time_get(const struct ll_adv_iso_set *adv_iso); + #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX) /* helper function to release unused DF configuration memory */ void ull_df_adv_cfg_release(struct lll_df_adv_cfg *df_adv_cfg); diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index de78352baa2..6191f811311 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -57,6 +57,7 @@ static struct stream *adv_iso_stream_acquire(void); static uint16_t adv_iso_stream_handle_get(struct lll_adv_iso_stream *stream); static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing, uint32_t event_spacing_max); +static uint32_t adv_iso_time_get(const struct ll_adv_iso_set *adv_iso, bool max); static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, uint32_t iso_interval_us); static uint8_t adv_iso_chm_update(uint8_t big_handle); @@ -945,6 +946,11 @@ void ull_adv_iso_stream_release(struct ll_adv_iso_set *adv_iso) lll->adv = NULL; } +uint32_t ull_adv_iso_max_time_get(const struct ll_adv_iso_set *adv_iso) +{ + return adv_iso_time_get(adv_iso, true); +} + static int init_reset(void) { /* Add initializations common to power up initialization and HCI reset @@ -998,22 +1004,12 @@ static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing, return 0U; } -static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, - uint32_t iso_interval_us) +static uint32_t adv_iso_time_get(const struct ll_adv_iso_set *adv_iso, bool max) { - uint32_t ticks_slot_overhead; - struct lll_adv_iso *lll_iso; - uint32_t ticks_slot_offset; - uint32_t volatile ret_cb; - uint32_t ticks_anchor; + const struct lll_adv_iso *lll_iso; uint32_t ctrl_spacing; uint32_t pdu_spacing; - uint32_t ticks_slot; - uint32_t slot_us; - uint32_t ret; - int err; - - ull_hdr_init(&adv_iso->ull); + uint32_t time_us; lll_iso = &adv_iso->lll; @@ -1023,15 +1019,46 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, ctrl_spacing = PDU_BIS_US(sizeof(struct pdu_big_ctrl), lll_iso->enc, lll_iso->phy, lll_iso->phy_flags); - if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX)) { - slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + + /* 1. Maximum PDU transmission time in 1M/2M/S8 PHY is 17040 us, or + * represented in 15-bits. + * 2. NSE in the range 1 to 31 is represented in 5-bits + * 3. num_bis in the range 1 to 31 is represented in 5-bits + * + * Hence, worst case event time can be represented in 25-bits plus + * one each bit for added ctrl_spacing and radio event overheads. I.e. + * 27-bits required and sufficiently covered by using 32-bit data type + * for time_us. + */ + + if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX) || max) { + time_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + ctrl_spacing; } else { - slot_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - + time_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - lll_iso->ptc); } - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + /* Add implementation defined radio event overheads */ + time_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + + return time_us; +} + +static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, + uint32_t iso_interval_us) +{ + uint32_t ticks_slot_overhead; + uint32_t ticks_slot_offset; + volatile uint32_t ret_cb; + uint32_t ticks_anchor; + uint32_t ticks_slot; + uint32_t slot_us; + uint32_t ret; + int err; + + ull_hdr_init(&adv_iso->ull); + + slot_us = adv_iso_time_get(adv_iso, false); adv_iso->ull.ticks_active_to_start = 0U; adv_iso->ull.ticks_prepare_to_start = @@ -1066,7 +1093,7 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, ret_cb = TICKER_STATUS_BUSY; ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD, - (TICKER_ID_ADV_ISO_BASE + lll_iso->handle), + (TICKER_ID_ADV_ISO_BASE + adv_iso->lll.handle), ticks_anchor, 0U, HAL_TICKER_US_TO_TICKS(iso_interval_us), HAL_TICKER_REMAINDER(iso_interval_us), diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index e7ca8a0358b..38589a2e644 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -701,7 +701,10 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) adv_iso = ull_adv_iso_get(ticker_id - TICKER_ID_ADV_ISO_BASE); if (adv_iso) { - *ticks_slot = adv_iso->ull.ticks_slot; + uint32_t time_us; + + time_us = ull_adv_iso_max_time_get(adv_iso); + *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); return &adv_iso->ull; } From f4993df9378a94769e723f78fd2ad363f51baef1 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 8 Aug 2023 23:08:52 -0700 Subject: [PATCH 0795/4498] drivers: misc: ethos_u: fix irq connect The Ethos-U driver was using IRQ_DIRECT_CONNECT. This is not what the driver needs as this will not detect a context switch when coming out of the isr, and this is needed as the isr will release a semaphore. Signed-off-by: Ryan McClelland --- drivers/misc/ethos_u/init.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/misc/ethos_u/init.c b/drivers/misc/ethos_u/init.c index b50e3facc47..bae2b50c27a 100644 --- a/drivers/misc/ethos_u/init.c +++ b/drivers/misc/ethos_u/init.c @@ -102,6 +102,14 @@ struct ethosu_data { struct ethosu_driver drv; }; +void ethosu_zephyr_irq_handler(const struct device *dev) +{ + struct ethosu_data *data = dev->data; + struct ethosu_driver *drv = &data->drv; + + ethosu_irq_handler(drv); +} + static int ethosu_zephyr_init(const struct device *dev) { const struct ethosu_dts_info *config = dev->config; @@ -131,17 +139,12 @@ static int ethosu_zephyr_init(const struct device *dev) #define ETHOSU_DEVICE_INIT(n) \ static struct ethosu_data ethosu_data_##n; \ \ - static void ethosu_zephyr_irq_handler_##n(void) \ - { \ - struct ethosu_driver *drv = ðosu_data_##n.drv; \ - ethosu_irq_handler(drv); \ - } \ - \ static void ethosu_zephyr_irq_config_##n(void) \ { \ - IRQ_DIRECT_CONNECT(DT_INST_IRQN(n), \ + IRQ_CONNECT(DT_INST_IRQN(n), \ DT_INST_IRQ(n, priority), \ - ethosu_zephyr_irq_handler_##n, 0); \ + ethosu_zephyr_irq_handler, \ + DEVICE_DT_INST_GET(n), 0); \ irq_enable(DT_INST_IRQN(n)); \ } \ \ From 646ef0b3b136c5a39a60ddf1c37a8b0b3c971a40 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 8 Aug 2023 23:12:22 -0700 Subject: [PATCH 0796/4498] drivers: misc: ethos_u: rename init.c to ethos_u.c A file just named `init.c` is not that descriptive inside of a project that has a lot of files of already. Rename to `ethos_u.c`. Signed-off-by: Ryan McClelland --- drivers/misc/ethos_u/CMakeLists.txt | 2 +- drivers/misc/ethos_u/{init.c => ethos_u.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/misc/ethos_u/{init.c => ethos_u.c} (100%) diff --git a/drivers/misc/ethos_u/CMakeLists.txt b/drivers/misc/ethos_u/CMakeLists.txt index 1bb2d158045..c251488eb3c 100644 --- a/drivers/misc/ethos_u/CMakeLists.txt +++ b/drivers/misc/ethos_u/CMakeLists.txt @@ -3,4 +3,4 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() -zephyr_library_sources(init.c) +zephyr_library_sources(ethos_u.c) diff --git a/drivers/misc/ethos_u/init.c b/drivers/misc/ethos_u/ethos_u.c similarity index 100% rename from drivers/misc/ethos_u/init.c rename to drivers/misc/ethos_u/ethos_u.c From 6a536f9f8ce972a1153b88658e722231568fca74 Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Thu, 21 Sep 2023 10:05:46 +0200 Subject: [PATCH 0797/4498] net: Deprecated and unused flags cleanup. In net_pkt structure couple of flags are no longer used. Flag pkt_queued can be removed permanently togeter with setter and getter functions. Second flag sent_or_eof has been renamed because it is still used partially only for indicating EOF. Additionally unused setter and getter for 'sent_' part of this flag are removed. Signed-off-by: Marcin Gasiorek --- include/zephyr/net/net_pkt.h | 35 +++-------------------------------- subsys/net/ip/ipv4_fragment.c | 9 --------- subsys/net/ip/ipv6_nbr.c | 10 ---------- subsys/net/ip/net_if.c | 5 ----- 4 files changed, 3 insertions(+), 56 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index d4011d1f582..7ea9d520b73 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -151,16 +151,7 @@ struct net_pkt { #endif uint8_t overwrite : 1; /* Is packet content being overwritten? */ - uint8_t sent_or_eof : 1; /* For outgoing packet: is this sent or not - * For incoming packet of a socket: last - * packet before EOF - * Used only if defined(CONFIG_NET_TCP) - */ - uint8_t pkt_queued : 1; /* For outgoing packet: is this packet - * queued to be sent but has not reached - * the driver yet. - * Used only if defined(CONFIG_NET_TCP) - */ + uint8_t eof : 1; /* Last packet before EOF */ uint8_t ptp_pkt : 1; /* For outgoing packet: is this packet * a L2 PTP packet. * Used only if defined (CONFIG_NET_L2_PTP) @@ -455,26 +446,6 @@ static inline void net_pkt_set_ip_ecn(struct net_pkt *pkt, uint8_t ecn) #endif } -static inline uint8_t net_pkt_sent(struct net_pkt *pkt) -{ - return pkt->sent_or_eof; -} - -static inline void net_pkt_set_sent(struct net_pkt *pkt, bool sent) -{ - pkt->sent_or_eof = sent; -} - -static inline uint8_t net_pkt_queued(struct net_pkt *pkt) -{ - return pkt->pkt_queued; -} - -static inline void net_pkt_set_queued(struct net_pkt *pkt, bool send) -{ - pkt->pkt_queued = send; -} - static inline uint8_t net_pkt_tcp_1st_msg(struct net_pkt *pkt) { #if defined(CONFIG_NET_TCP) @@ -497,12 +468,12 @@ static inline void net_pkt_set_tcp_1st_msg(struct net_pkt *pkt, bool is_1st) #if defined(CONFIG_NET_SOCKETS) static inline uint8_t net_pkt_eof(struct net_pkt *pkt) { - return pkt->sent_or_eof; + return pkt->eof; } static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof) { - pkt->sent_or_eof = eof; + pkt->eof = eof; } #endif diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index 99297ae5e20..04df53304a8 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -613,15 +613,6 @@ enum net_verdict net_ipv4_prepare_for_send(struct net_pkt *pkt) } } - /* We "fake" the sending of the packet here so that - * tcp.c:tcp_retry_expired() will increase the ref count when re-sending - * the packet. This is crucial to do here and will cause free memory - * access if not done. - */ - if (IS_ENABLED(CONFIG_NET_TCP)) { - net_pkt_set_sent(pkt, true); - } - /* We need to unref here because we simulate the packet being sent. */ net_pkt_unref(pkt); diff --git a/subsys/net/ip/ipv6_nbr.c b/subsys/net/ip/ipv6_nbr.c index cba36f41d50..e220980a199 100644 --- a/subsys/net/ip/ipv6_nbr.c +++ b/subsys/net/ip/ipv6_nbr.c @@ -807,16 +807,6 @@ enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt) } } - /* We "fake" the sending of the packet here so that - * tcp.c:tcp_retry_expired() will increase the ref - * count when re-sending the packet. This is crucial - * thing to do here and will cause free memory access - * if not done. - */ - if (IS_ENABLED(CONFIG_NET_TCP)) { - net_pkt_set_sent(pkt, true); - } - /* We need to unref here because we simulate the packet * sending. */ diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index f526cac02d1..4aaccecd2be 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -249,11 +249,6 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) context = net_pkt_context(pkt); if (net_if_flag_is_set(iface, NET_IF_LOWER_UP)) { - if (IS_ENABLED(CONFIG_NET_TCP) && - net_pkt_family(pkt) != AF_UNSPEC) { - net_pkt_set_queued(pkt, false); - } - if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) { pkt_priority = net_pkt_priority(pkt); From a3cde71fbbdb52c4eb906c9a7eb40dd55d4783f4 Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Thu, 21 Sep 2023 10:10:54 +0200 Subject: [PATCH 0798/4498] net: Remove '#ifdef CONFIG_NET_ROUTE' around forwarding getter and setter. Because `forwarding` flag is available unconditionally the compilation guard has no make sense. Additionally this flag and related getter and setter can be used for e.g. IPv4 packets forwarding in future, which would be impossible looking at `NET_ROUTE` dependencies. Signed-off-by: Marcin Gasiorek --- include/zephyr/net/net_pkt.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 7ea9d520b73..6c8ac419594 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -477,7 +477,6 @@ static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof) } #endif -#if defined(CONFIG_NET_ROUTE) static inline bool net_pkt_forwarding(struct net_pkt *pkt) { return pkt->forwarding; @@ -487,12 +486,6 @@ static inline void net_pkt_set_forwarding(struct net_pkt *pkt, bool forward) { pkt->forwarding = forward; } -#else -static inline bool net_pkt_forwarding(struct net_pkt *pkt) -{ - return false; -} -#endif #if defined(CONFIG_NET_IPV4) static inline uint8_t net_pkt_ipv4_ttl(struct net_pkt *pkt) From c668fbc4d25ad7196e63bbd657f20920ef4b5e04 Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Thu, 21 Sep 2023 10:30:55 +0200 Subject: [PATCH 0799/4498] net: ip: Add cloning of missing attributes A few attributes isn't cloned togerder with pkt. This commit add missing part. Additionally, because the `eof` flag in net_pkt structure is avilable unconditionally hence `#if defined(CONFIG_NET_SOCKETS)` guard has been removed form setter and getter functions for this flag. Signed-off-by: Marcin Gasiorek --- include/zephyr/net/net_pkt.h | 2 -- subsys/net/ip/net_pkt.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 6c8ac419594..71cde17b67f 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -465,7 +465,6 @@ static inline void net_pkt_set_tcp_1st_msg(struct net_pkt *pkt, bool is_1st) #endif } -#if defined(CONFIG_NET_SOCKETS) static inline uint8_t net_pkt_eof(struct net_pkt *pkt) { return pkt->eof; @@ -475,7 +474,6 @@ static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof) { pkt->eof = eof; } -#endif static inline bool net_pkt_forwarding(struct net_pkt *pkt) { diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index 57ba0f3bb0d..944ea8499f1 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1809,6 +1809,9 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt) net_pkt_set_priority(clone_pkt, net_pkt_priority(pkt)); net_pkt_set_orig_iface(clone_pkt, net_pkt_orig_iface(pkt)); net_pkt_set_captured(clone_pkt, net_pkt_is_captured(pkt)); + net_pkt_set_eof(clone_pkt, net_pkt_eof(pkt)); + net_pkt_set_ptp(clone_pkt, net_pkt_is_ptp(pkt)); + net_pkt_set_forwarding(clone_pkt, net_pkt_forwarding(pkt)); net_pkt_set_l2_bridged(clone_pkt, net_pkt_is_l2_bridged(pkt)); net_pkt_set_l2_processed(clone_pkt, net_pkt_is_l2_processed(pkt)); From 0564345715f196a3d4fc8be372fbbe0dbad151cc Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Fri, 15 Sep 2023 08:37:16 +0200 Subject: [PATCH 0800/4498] net: Follow coding style when converting int to bool Added double exclamation mark where missing in order to keep code in one convention. Signed-off-by: Marcin Gasiorek --- include/zephyr/net/net_pkt.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 71cde17b67f..219293dd647 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -477,7 +477,7 @@ static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof) static inline bool net_pkt_forwarding(struct net_pkt *pkt) { - return pkt->forwarding; + return !!(pkt->forwarding); } static inline void net_pkt_set_forwarding(struct net_pkt *pkt, bool forward) @@ -1117,7 +1117,7 @@ static inline void net_pkt_set_ll_proto_type(struct net_pkt *pkt, uint16_t type) #if defined(CONFIG_NET_IPV4_AUTO) static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt) { - return pkt->ipv4_auto_arp_msg; + return !!(pkt->ipv4_auto_arp_msg); } static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt, @@ -1144,7 +1144,7 @@ static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt, #if defined(CONFIG_NET_LLDP) static inline bool net_pkt_is_lldp(struct net_pkt *pkt) { - return pkt->lldp_pkt; + return !!(pkt->lldp_pkt); } static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp) @@ -1169,7 +1169,7 @@ static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp) #if defined(CONFIG_NET_L2_PPP) static inline bool net_pkt_is_ppp(struct net_pkt *pkt) { - return pkt->ppp_msg; + return !!(pkt->ppp_msg); } static inline void net_pkt_set_ppp(struct net_pkt *pkt, @@ -1224,7 +1224,7 @@ static inline void net_pkt_set_overwrite(struct net_pkt *pkt, bool overwrite) static inline bool net_pkt_is_being_overwritten(struct net_pkt *pkt) { - return pkt->overwrite; + return !!(pkt->overwrite); } #ifdef CONFIG_NET_PKT_FILTER From 4ebf6e5facac61588d5cc9785ceaf312c9a33a79 Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Fri, 15 Sep 2023 09:12:20 +0200 Subject: [PATCH 0801/4498] tests: net: Add missing tests to net_pkt_clone Add tests for flag cloning and couple extra. Signed-off-by: Marcin Gasiorek --- tests/net/net_pkt/prj.conf | 1 + tests/net/net_pkt/src/main.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/net/net_pkt/prj.conf b/tests/net/net_pkt/prj.conf index 15d778a4ef7..9f2702d15e4 100644 --- a/tests/net/net_pkt/prj.conf +++ b/tests/net/net_pkt/prj.conf @@ -12,3 +12,4 @@ CONFIG_NET_LOG=y CONFIG_NET_BUF_POOL_USAGE=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NET_ETHERNET_BRIDGE=y diff --git a/tests/net/net_pkt/src/main.c b/tests/net/net_pkt/src/main.c index f9bc52e3638..1cf3516f785 100644 --- a/tests/net/net_pkt/src/main.c +++ b/tests/net/net_pkt/src/main.c @@ -814,6 +814,16 @@ ZTEST(net_pkt_test_suite, test_net_pkt_clone) net_pkt_lladdr_dst(pkt)->type = NET_LINK_ETHERNET; zassert_mem_equal(net_pkt_lladdr_dst(pkt)->addr, &buf[6], NET_LINK_ADDR_MAX_LENGTH); + net_pkt_set_family(pkt, AF_INET6); + net_pkt_set_captured(pkt, true); + net_pkt_set_eof(pkt, true); + net_pkt_set_ptp(pkt, true); + net_pkt_set_forwarding(pkt, true); + + net_pkt_set_l2_bridged(pkt, true); + net_pkt_set_l2_processed(pkt, true); + net_pkt_set_ll_proto_type(pkt, ETH_P_IEEE802154); + net_pkt_set_overwrite(pkt, false); cloned_pkt = net_pkt_clone(pkt, K_NO_WAIT); zassert_true(cloned_pkt != NULL, "Pkt not cloned"); @@ -833,6 +843,27 @@ ZTEST(net_pkt_test_suite, test_net_pkt_clone) zassert_false(net_pkt_is_being_overwritten(pkt), "Pkt overwrite flag not restored"); + zassert_equal(net_pkt_family(cloned_pkt), AF_INET6, + "Address family value mismatch"); + + zassert_true(net_pkt_is_captured(cloned_pkt), + "Cloned pkt captured flag mismatch"); + + zassert_true(net_pkt_eof(cloned_pkt), + "Cloned pkt eof flag mismatch"); + + zassert_true(net_pkt_is_ptp(cloned_pkt), + "Cloned pkt ptp_pkt flag mismatch"); + + zassert_true(net_pkt_forwarding(cloned_pkt), + "Cloned pkt forwarding flag mismatch"); + + zassert_true(net_pkt_is_l2_bridged(cloned_pkt), + "Cloned pkt l2_bridged flag mismatch"); + + zassert_true(net_pkt_is_l2_processed(cloned_pkt), + "Cloned pkt l2_processed flag mismatch"); + zassert_mem_equal(net_pkt_lladdr_src(cloned_pkt)->addr, buf, NET_LINK_ADDR_MAX_LENGTH); zassert_true(net_pkt_lladdr_src(cloned_pkt)->addr == cloned_pkt->buffer->data, "Cloned pkt ll src addr mismatch"); @@ -841,6 +872,9 @@ ZTEST(net_pkt_test_suite, test_net_pkt_clone) zassert_true(net_pkt_lladdr_dst(cloned_pkt)->addr == net_pkt_cursor_get_pos(cloned_pkt), "Cloned pkt ll dst addr mismatch"); + zassert_equal(net_pkt_ll_proto_type(cloned_pkt), ETH_P_IEEE802154, + "Address ll_proto_type value mismatch"); + net_pkt_unref(pkt); net_pkt_unref(cloned_pkt); } From 663826a9f93d7675e8a2205abd923e0f7753fc3a Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Mon, 18 Sep 2023 13:42:16 +1200 Subject: [PATCH 0802/4498] drivers: can: mcan: Add CAN statistics Add CAN stats for MCAN drivers. Update MCAN drivers to use CAN_DEVICE_DT_INST_DEFINE which initialises and registers CAN stats if enabled. Signed-off-by: Grant Ramsay --- drivers/can/can_mcan.c | 83 +++++++++++++++++++++++++-- drivers/can/can_mcux_mcan.c | 12 ++-- drivers/can/can_sam.c | 12 ++-- drivers/can/can_sam0.c | 10 ++-- drivers/can/can_stm32_fdcan.c | 10 ++-- drivers/can/can_stm32h7_fdcan.c | 10 ++-- drivers/can/can_tcan4x5x.c | 6 +- include/zephyr/drivers/can/can_mcan.h | 11 ++++ 8 files changed, 120 insertions(+), 34 deletions(-) diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index 0655d3d9e5a..103c80400d8 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -317,6 +317,9 @@ int can_mcan_start(const struct device *dev) } } + /* Reset statistics */ + CAN_STATS_RESET(dev); + err = can_mcan_leave_init_mode(dev, K_MSEC(CAN_INIT_TIMEOUT_MS)); if (err != 0) { LOG_ERR("failed to leave init mode"); @@ -524,11 +527,67 @@ static void can_mcan_tx_event_handler(const struct device *dev) } } +#ifdef CONFIG_CAN_STATS +static void can_mcan_lec_update_stats(const struct device *dev, enum can_mcan_psr_lec lec) +{ + switch (lec) { + case CAN_MCAN_PSR_LEC_STUFF_ERROR: + CAN_STATS_STUFF_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_FORM_ERROR: + CAN_STATS_FORM_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_ACK_ERROR: + CAN_STATS_ACK_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_BIT1_ERROR: + CAN_STATS_BIT1_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_BIT0_ERROR: + CAN_STATS_BIT0_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_CRC_ERROR: + CAN_STATS_CRC_ERROR_INC(dev); + break; + case CAN_MCAN_PSR_LEC_NO_ERROR: + case CAN_MCAN_PSR_LEC_NO_CHANGE: + default: + break; + } +} +#endif /* CONFIG_CAN_STATS */ + +static int can_mcan_read_psr(const struct device *dev, uint32_t *val) +{ + /* Reading the lower byte of the PSR register clears the protocol last + * error codes (LEC). To avoid missing errors, this function should be + * used whenever the PSR register is read. + */ + int err = can_mcan_read_reg(dev, CAN_MCAN_PSR, val); + + if (err != 0) { + return err; + } + +#ifdef CONFIG_CAN_STATS + enum can_mcan_psr_lec lec; + + lec = FIELD_GET(CAN_MCAN_PSR_LEC, *val); + can_mcan_lec_update_stats(dev, lec); +#ifdef CONFIG_CAN_FD_MODE + lec = FIELD_GET(CAN_MCAN_PSR_DLEC, *val); + can_mcan_lec_update_stats(dev, lec); +#endif +#endif /* CONFIG_CAN_STATS */ + + return 0; +} + void can_mcan_line_0_isr(const struct device *dev) { const uint32_t events = CAN_MCAN_IR_BO | CAN_MCAN_IR_EP | CAN_MCAN_IR_EW | CAN_MCAN_IR_TEFN | CAN_MCAN_IR_TEFL | CAN_MCAN_IR_ARA | - CAN_MCAN_IR_MRAF; + CAN_MCAN_IR_MRAF | CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED; struct can_mcan_data *data = dev->data; uint32_t ir; int err; @@ -562,10 +621,18 @@ void can_mcan_line_0_isr(const struct device *dev) LOG_ERR("Access to reserved address"); } - if (ir & CAN_MCAN_IR_MRAF) { + if ((ir & CAN_MCAN_IR_MRAF) != 0U) { LOG_ERR("Message RAM access failure"); } +#ifdef CONFIG_CAN_STATS + if ((ir & (CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED)) != 0U) { + uint32_t reg; + /* This function automatically updates protocol error stats */ + can_mcan_read_psr(dev, ®); + } +#endif + err = can_mcan_read_reg(dev, CAN_MCAN_IR, &ir); if (err != 0) { return; @@ -739,10 +806,12 @@ void can_mcan_line_1_isr(const struct device *dev) if ((ir & CAN_MCAN_IR_RF0L) != 0U) { LOG_ERR("Message lost on FIFO0"); + CAN_STATS_RX_OVERRUN_INC(dev); } if ((ir & CAN_MCAN_IR_RF1L) != 0U) { LOG_ERR("Message lost on FIFO1"); + CAN_STATS_RX_OVERRUN_INC(dev); } err = can_mcan_read_reg(dev, CAN_MCAN_IR, &ir); @@ -760,7 +829,7 @@ int can_mcan_get_state(const struct device *dev, enum can_state *state, int err; if (state != NULL) { - err = can_mcan_read_reg(dev, CAN_MCAN_PSR, ®); + err = can_mcan_read_psr(dev, ®); if (err != 0) { return err; } @@ -877,7 +946,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim return -ENETDOWN; } - err = can_mcan_read_reg(dev, CAN_MCAN_PSR, ®); + err = can_mcan_read_psr(dev, ®); if (err != 0) { return err; } @@ -1456,6 +1525,12 @@ int can_mcan_init(const struct device *dev) reg = CAN_MCAN_IE_BOE | CAN_MCAN_IE_EWE | CAN_MCAN_IE_EPE | CAN_MCAN_IE_MRAFE | CAN_MCAN_IE_TEFLE | CAN_MCAN_IE_TEFNE | CAN_MCAN_IE_RF0NE | CAN_MCAN_IE_RF1NE | CAN_MCAN_IE_RF0LE | CAN_MCAN_IE_RF1LE; +#ifdef CONFIG_CAN_STATS + /* These ISRs are only enabled/used for statistics, they are otherwise + * disabled as they may produce a significant amount of frequent ISRs. + */ + reg |= CAN_MCAN_IE_PEAE | CAN_MCAN_IE_PEDE; +#endif err = can_mcan_write_reg(dev, CAN_MCAN_IE, reg); if (err != 0) { diff --git a/drivers/can/can_mcux_mcan.c b/drivers/can/can_mcux_mcan.c index 73caabb9d9c..eb382c95292 100644 --- a/drivers/can/can_mcux_mcan.c +++ b/drivers/can/can_mcux_mcan.c @@ -208,12 +208,12 @@ static const struct can_mcan_ops mcux_mcan_ops = { static struct can_mcan_data can_mcan_data_##n = \ CAN_MCAN_DATA_INITIALIZER(NULL); \ \ - DEVICE_DT_INST_DEFINE(n, &mcux_mcan_init, NULL, \ - &can_mcan_data_##n, \ - &can_mcan_config_##n, \ - POST_KERNEL, \ - CONFIG_CAN_INIT_PRIORITY, \ - &mcux_mcan_driver_api); \ + CAN_DEVICE_DT_INST_DEFINE(n, mcux_mcan_init, NULL, \ + &can_mcan_data_##n, \ + &can_mcan_config_##n, \ + POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, \ + &mcux_mcan_driver_api); \ \ static void mcux_mcan_irq_config_##n(const struct device *dev) \ { \ diff --git a/drivers/can/can_sam.c b/drivers/can/can_sam.c index 10ff7bc503f..e081e57c794 100644 --- a/drivers/can/can_sam.c +++ b/drivers/can/can_sam.c @@ -186,12 +186,12 @@ static void config_can_##inst##_irq(void) static struct can_mcan_data can_mcan_data_##inst = \ CAN_MCAN_DATA_INITIALIZER(NULL); -#define CAN_SAM_DEVICE_INST(inst) \ - DEVICE_DT_INST_DEFINE(inst, &can_sam_init, NULL, \ - &can_mcan_data_##inst, \ - &can_mcan_cfg_##inst, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_sam_driver_api); +#define CAN_SAM_DEVICE_INST(inst) \ + CAN_DEVICE_DT_INST_DEFINE(inst, can_sam_init, NULL, \ + &can_mcan_data_##inst, \ + &can_mcan_cfg_##inst, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_sam_driver_api); #define CAN_SAM_INST(inst) \ CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \ diff --git a/drivers/can/can_sam0.c b/drivers/can/can_sam0.c index 786d2cb9a72..ac322fe936e 100644 --- a/drivers/can/can_sam0.c +++ b/drivers/can/can_sam0.c @@ -214,11 +214,11 @@ static void config_can_##inst##_irq(void) \ CAN_MCAN_DATA_INITIALIZER(NULL); #define CAN_SAM0_DEVICE_INST(inst) \ - DEVICE_DT_INST_DEFINE(inst, &can_sam0_init, NULL, \ - &can_mcan_data_##inst, \ - &can_mcan_cfg_##inst, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_sam0_driver_api); + CAN_DEVICE_DT_INST_DEFINE(inst, can_sam0_init, NULL, \ + &can_mcan_data_##inst, \ + &can_mcan_cfg_##inst, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_sam0_driver_api); #define CAN_SAM0_INST(inst) \ CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \ diff --git a/drivers/can/can_stm32_fdcan.c b/drivers/can/can_stm32_fdcan.c index 94bc1802c3a..e17fce0e1b9 100644 --- a/drivers/can/can_stm32_fdcan.c +++ b/drivers/can/can_stm32_fdcan.c @@ -673,11 +673,11 @@ static void config_can_##inst##_irq(void) \ static struct can_mcan_data can_mcan_data_##inst = \ CAN_MCAN_DATA_INITIALIZER(NULL); -#define CAN_STM32FD_DEVICE_INST(inst) \ - DEVICE_DT_INST_DEFINE(inst, &can_stm32fd_init, NULL, \ - &can_mcan_data_##inst, &can_mcan_cfg_##inst, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_stm32fd_driver_api); +#define CAN_STM32FD_DEVICE_INST(inst) \ + CAN_DEVICE_DT_INST_DEFINE(inst, can_stm32fd_init, NULL, \ + &can_mcan_data_##inst, &can_mcan_cfg_##inst, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_stm32fd_driver_api); #define CAN_STM32FD_INST(inst) \ CAN_STM32FD_BUILD_ASSERT_MRAM_CFG(inst) \ diff --git a/drivers/can/can_stm32h7_fdcan.c b/drivers/can/can_stm32h7_fdcan.c index ecffd4ce1cb..291bcfe8091 100644 --- a/drivers/can/can_stm32h7_fdcan.c +++ b/drivers/can/can_stm32h7_fdcan.c @@ -224,11 +224,11 @@ static const struct can_mcan_ops can_stm32h7_ops = { static struct can_mcan_data can_mcan_data_##n = \ CAN_MCAN_DATA_INITIALIZER(NULL); \ \ - DEVICE_DT_INST_DEFINE(n, &can_stm32h7_init, NULL, \ - &can_mcan_data_##n, \ - &can_mcan_cfg_##n, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_stm32h7_driver_api); \ + CAN_DEVICE_DT_INST_DEFINE(n, can_stm32h7_init, NULL, \ + &can_mcan_data_##n, \ + &can_mcan_cfg_##n, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_stm32h7_driver_api); \ \ static void stm32h7_mcan_irq_config_##n(void) \ { \ diff --git a/drivers/can/can_tcan4x5x.c b/drivers/can/can_tcan4x5x.c index e303244b0e5..2d77ce746c3 100644 --- a/drivers/can/can_tcan4x5x.c +++ b/drivers/can/can_tcan4x5x.c @@ -789,8 +789,8 @@ static const struct can_mcan_ops tcan4x5x_ops = { static struct can_mcan_data can_mcan_data_##inst = \ CAN_MCAN_DATA_INITIALIZER(&tcan4x5x_data_##inst); \ \ - DEVICE_DT_INST_DEFINE(inst, &tcan4x5x_init, NULL, &can_mcan_data_##inst, \ - &can_mcan_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &tcan4x5x_driver_api); + CAN_DEVICE_DT_INST_DEFINE(inst, tcan4x5x_init, NULL, &can_mcan_data_##inst, \ + &can_mcan_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &tcan4x5x_driver_api); DT_INST_FOREACH_STATUS_OKAY(TCAN4X5X_INIT) diff --git a/include/zephyr/drivers/can/can_mcan.h b/include/zephyr/drivers/can/can_mcan.h index c1a1fb9f85d..6cc632fb13e 100644 --- a/include/zephyr/drivers/can/can_mcan.h +++ b/include/zephyr/drivers/can/can_mcan.h @@ -127,6 +127,17 @@ #define CAN_MCAN_PSR_ACT GENMASK(4, 3) #define CAN_MCAN_PSR_LEC GENMASK(2, 0) +enum can_mcan_psr_lec { + CAN_MCAN_PSR_LEC_NO_ERROR = 0, + CAN_MCAN_PSR_LEC_STUFF_ERROR = 1, + CAN_MCAN_PSR_LEC_FORM_ERROR = 2, + CAN_MCAN_PSR_LEC_ACK_ERROR = 3, + CAN_MCAN_PSR_LEC_BIT1_ERROR = 4, + CAN_MCAN_PSR_LEC_BIT0_ERROR = 5, + CAN_MCAN_PSR_LEC_CRC_ERROR = 6, + CAN_MCAN_PSR_LEC_NO_CHANGE = 7 +}; + /* Transmitter Delay Compensation register */ #define CAN_MCAN_TDCR 0x048 #define CAN_MCAN_TDCR_TDCO GENMASK(14, 8) From 89935550ce681b394146285f27f56a6aeb84ed9d Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 19 Sep 2023 14:23:17 +0200 Subject: [PATCH 0803/4498] dts: bindings: can: deprecate advanced CAN timing properties Deprecate the advanced CAN timing devicetree properties in favor of setting advanced timing parameters from application code. The advanced timing properties are giving in number of time quanta (Tq) and requires reverse-calculation to find a suitable CAN clock divider. The resulting bitrate error is compared against a threshold in the driver initialization code, but the application is not able to retrieve it. Forcing applications to use the CAN timing APIs directly instead makes it up to the application to determine if the bitrate error is acceptable or not. The deprecated properties are: - prop-seg - phase-seg1 - phase-seg2 - prop-seg-data - phase-seg1-data - phase-seg2-data Signed-off-by: Henrik Brix Andersen --- dts/bindings/can/can-controller.yaml | 15 ++++++++++++--- dts/bindings/can/can-fd-controller.yaml | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/dts/bindings/can/can-controller.yaml b/dts/bindings/can/can-controller.yaml index d558a7ffc09..0a6309ecd68 100644 --- a/dts/bindings/can/can-controller.yaml +++ b/dts/bindings/can/can-controller.yaml @@ -13,13 +13,22 @@ properties: description: Resynchronization jump width (ISO 11898-1) prop-seg: type: int - description: Time quantums of propagation segment (ISO 11898-1) + deprecated: true + description: | + Time quantums of propagation segment (ISO 11898-1). Deprecated in favor of setting advanced + timing parameters from the application. phase-seg1: type: int - description: Time quantums of phase buffer 1 segment (ISO 11898-1) + deprecated: true + description: | + Time quantums of phase buffer 1 segment (ISO 11898-1). Deprecated in favor of setting advanced + timing parameters from the application. phase-seg2: type: int - description: Time quantums of phase buffer 2 segment (ISO 11898-1) + deprecated: true + description: | + Time quantums of phase buffer 2 segment (ISO 11898-1). Deprecated in favor of setting advanced + timing parameters from the application. sample-point: type: int description: > diff --git a/dts/bindings/can/can-fd-controller.yaml b/dts/bindings/can/can-fd-controller.yaml index 4fdfff2b25b..176013f775f 100644 --- a/dts/bindings/can/can-fd-controller.yaml +++ b/dts/bindings/can/can-fd-controller.yaml @@ -13,13 +13,22 @@ properties: description: Resynchronization jump width for the data phase. (ISO11898-1:2015) prop-seg-data: type: int - description: Time quantums of propagation segment for the data phase. (ISO11898-1:2015) + deprecated: true + description: | + Time quantums of propagation segment for the data phase (ISO11898-1:2015). Deprecated in favor + of setting advanced timing parameters from the application. phase-seg1-data: type: int - description: Time quantums of phase buffer 1 segment for the data phase. (ISO11898-1:2015) + deprecated: true + description: | + Time quantums of phase buffer 1 segment for the data phase (ISO11898-1:2015). Deprecated in + favor of setting advanced timing parameters from the application. phase-seg2-data: type: int - description: Time quantums of phase buffer 2 segment for the data phase. (ISO11898-1:2015) + deprecated: true + description: | + Time quantums of phase buffer 2 segment for the data phase (ISO11898-1:2015). Deprecated in + favor of setting advanced timing parameters from the application. sample-point-data: type: int description: > From af7d972f4c484d83c47b4fcbe2affa4bc79b6206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 18 Sep 2023 12:30:49 +0700 Subject: [PATCH 0804/4498] can: nxp_s32_canxl: use clock control APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use clock control API to retrieve the module's frequency and update the boards using it to provide the source clocks. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 2 -- .../s32z270dc2_r52/s32z270dc2_rtu0_r52.dts | 1 + .../s32z270dc2_r52/s32z270dc2_rtu1_r52.dts | 1 + drivers/can/Kconfig.nxp_s32 | 3 ++- drivers/can/can_nxp_s32_canxl.c | 25 ++++++++++++++----- dts/arm/nxp/nxp_s32z27x_r52.dtsi | 2 ++ dts/bindings/can/nxp,s32-canxl.yaml | 6 ++--- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index eed395cce8c..59c46f7896b 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -109,7 +109,6 @@ &can0 { pinctrl-0 = <&can0_default>; pinctrl-names = "default"; - clock-frequency = <80000000>; bus-speed = <125000>; sample-point = <875>; sjw = <1>; @@ -122,7 +121,6 @@ &can1 { pinctrl-0 = <&can1_default>; pinctrl-names = "default"; - clock-frequency = <80000000>; bus-speed = <125000>; sample-point = <875>; sjw = <1>; diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts index a8650758089..ebaf1658f3b 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts @@ -5,6 +5,7 @@ */ /dts-v1/; +#include #include #include "s32z270dc2_r52.dtsi" diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts index 1f74fe4a3a9..06cf6b25844 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts @@ -5,6 +5,7 @@ */ /dts-v1/; +#include #include #include "s32z270dc2_r52.dtsi" diff --git a/drivers/can/Kconfig.nxp_s32 b/drivers/can/Kconfig.nxp_s32 index a8102d8e958..53c1ffc2b8b 100644 --- a/drivers/can/Kconfig.nxp_s32 +++ b/drivers/can/Kconfig.nxp_s32 @@ -1,10 +1,11 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 config CAN_NXP_S32_CANXL bool "NXP S32 CANXL driver" default y depends on DT_HAS_NXP_S32_CANXL_ENABLED + select CLOCK_CONTROL help Enable support for NXP S32 CANXL driver. diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index b5dd7305c51..a601399e82e 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,8 @@ struct can_nxp_s32_config { CANXL_GRP_CONTROL_Type *base_grp_ctrl; CANXL_DSC_CONTROL_Type *base_dsc_ctrl; uint8 instance; - uint32_t clock_can; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; uint32_t bitrate; uint32_t sample_point; uint32_t sjw; @@ -286,9 +288,7 @@ static int can_nxp_s32_get_core_clock(const struct device *dev, uint32_t *rate) __ASSERT_NO_MSG(rate != NULL); - *rate = config->clock_can; - - return 0; + return clock_control_get_rate(config->clock_dev, config->clock_subsys, rate); } static int can_nxp_s32_get_max_filters(const struct device *dev, bool ide) @@ -829,6 +829,17 @@ static int can_nxp_s32_init(const struct device *dev) } } + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock control device not ready"); + return -ENODEV; + } + + err = clock_control_on(config->clock_dev, config->clock_subsys); + if (err) { + LOG_ERR("Failed to enable clock"); + return err; + } + k_mutex_init(&data->rx_mutex); k_mutex_init(&data->tx_mutex); k_sem_init(&data->tx_allocs_sem, CONFIG_CAN_NXP_S32_MAX_TX, CONFIG_CAN_NXP_S32_MAX_TX); @@ -1060,7 +1071,9 @@ static const struct can_driver_api can_nxp_s32_driver_api = { .base_dsc_ctrl = (CANXL_DSC_CONTROL_Type *) \ DT_REG_ADDR_BY_NAME(CAN_NXP_S32_NODE(n), dsc_ctrl), \ .instance = n, \ - .clock_can = DT_PROP(CAN_NXP_S32_NODE(n), clock_frequency), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(CAN_NXP_S32_NODE(n))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_CLOCKS_CELL(CAN_NXP_S32_NODE(n), name), \ .bitrate = DT_PROP(CAN_NXP_S32_NODE(n), bus_speed), \ .sjw = DT_PROP(CAN_NXP_S32_NODE(n), sjw), \ .prop_seg = DT_PROP_OR(CAN_NXP_S32_NODE(n), prop_seg, 0), \ diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 5f5c69948cb..5728e3e3ff9 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -688,6 +688,7 @@ interrupts = , ; interrupt-names = "RX_TX_DATA_IRQ", "INT_ERROR_IRQ"; + clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; can1: can@4751b000 { @@ -700,6 +701,7 @@ interrupts = , ; interrupt-names = "RX_TX_DATA_IRQ", "INT_ERROR_IRQ"; + clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; }; }; diff --git a/dts/bindings/can/nxp,s32-canxl.yaml b/dts/bindings/can/nxp,s32-canxl.yaml index 8d498e47007..2a0f9408b65 100644 --- a/dts/bindings/can/nxp,s32-canxl.yaml +++ b/dts/bindings/can/nxp,s32-canxl.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -15,10 +15,8 @@ properties: interrupts: required: true - clock-frequency: - type: int + clocks: required: true - description: Module clock frequency in Hz. pinctrl-0: required: true From 42d8f7ff1726f49902752eb8298eafb819319ee0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 20 Sep 2023 01:57:42 +0000 Subject: [PATCH 0805/4498] samples: pm: fix init priority after init level change Moving from APPLICATION level to POST_KERNEL and keeping both parent and child on the same level is causing problems, so fix this by putting them on different priorities in POST_KERNEL. Also, this sample runs fine in qemu, so make it the integration platform. Fixes #62772 Signed-off-by: Anas Nashif --- samples/subsys/pm/device_pm/sample.yaml | 4 +++- samples/subsys/pm/device_pm/src/dummy_driver.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/subsys/pm/device_pm/sample.yaml b/samples/subsys/pm/device_pm/sample.yaml index ab22dee2ed2..13a57cd4b2a 100644 --- a/samples/subsys/pm/device_pm/sample.yaml +++ b/samples/subsys/pm/device_pm/sample.yaml @@ -5,8 +5,10 @@ tests: platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 + - qemu_x86 + - mps2_an385 integration_platforms: - - nrf52840dk_nrf52840 + - qemu_x86 tags: power harness: console harness_config: diff --git a/samples/subsys/pm/device_pm/src/dummy_driver.c b/samples/subsys/pm/device_pm/src/dummy_driver.c index 9164da50bbe..ffc4decb1eb 100644 --- a/samples/subsys/pm/device_pm/src/dummy_driver.c +++ b/samples/subsys/pm/device_pm/src/dummy_driver.c @@ -116,4 +116,4 @@ PM_DEVICE_DEFINE(dummy_driver, dummy_device_pm_action); DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init, PM_DEVICE_GET(dummy_driver), NULL, NULL, POST_KERNEL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs); + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &funcs); From 634416bc49d7ce8b498a93467c82ff6f5d784114 Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Wed, 6 Sep 2023 14:36:59 +0200 Subject: [PATCH 0806/4498] drivers: hwinfo: add driver for TI SimpleLink CC13xx/CC26xx series Introduce hwinfo driver for Texas Instruments SimpleLink CC13xx/CC26xx SOC series, with support for retrieving device's ID and cause of reset. By default, the pre-programmed, 8-bytes length IEEE MAC address is used for device's ID, with option ('HWINFO_CC13XX_CC26XX_USE_BLE_MAC') for use 6-bytes length BLE MAC instead. By default, read-only values stored in FCFG (Factory Configuration) are used but additional Kconfig option ('HWINFO_CC13XX_CC26XX_ALWAYS_USE_FACTORY_DEFAULT') is also provided, which allows to use values from writable CCFG (Customer Configuration) area. In all cases, device ID value is provided in big-endian which matches what TI's UniFlash tool returns. For reset cause, 'SysCtrlResetSourceGet()' function from TI's driver library is used and its value is mapped to Zephyr's implementation. Importantly, only root cause of reset is available on CC13xx/CC26xx platform as described in MCU Technical Reference Manual ('RESET_SRC' field in 'RESETCTL' register): "Shows the root cause of the last system reset. More than the reported reset source can have been active during the last system reset but only the root cause is reported." Signed-off-by: Piotr Dymacz --- drivers/hwinfo/CMakeLists.txt | 1 + drivers/hwinfo/Kconfig | 36 ++++++++++ drivers/hwinfo/hwinfo_cc13xx_cc26xx.c | 98 +++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/hwinfo/hwinfo_cc13xx_cc26xx.c diff --git a/drivers/hwinfo/CMakeLists.txt b/drivers/hwinfo/CMakeLists.txt index 6ff5d1929f6..437fbf969cf 100644 --- a/drivers/hwinfo/CMakeLists.txt +++ b/drivers/hwinfo/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE hwinfo_handlers.c) zephyr_library_sources_ifdef(CONFIG_HWINFO hwinfo_weak_impl.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SHELL hwinfo_shell.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_CC13XX_CC26XX hwinfo_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_ESP32 hwinfo_esp32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_GECKO hwinfo_gecko.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_IMXRT hwinfo_imxrt.c) diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 879f2b3e9d7..6971315b6b8 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -21,6 +21,42 @@ config HWINFO_SHELL help Enable hwinfo Shell for testing. +menuconfig HWINFO_CC13XX_CC26XX + bool "TI SimpleLink CC13xx/CC26xx hwinfo driver" + default y + depends on SOC_SERIES_CC13X2_CC26X2 || SOC_SERIES_CC13X2X7_CC26X2X7 + help + Enable TI SimpleLink CC13xx/CC26xx hwinfo driver. + +if HWINFO_CC13XX_CC26XX + +config HWINFO_CC13XX_CC26XX_ALWAYS_USE_FACTORY_DEFAULT + bool "Ignore CCFG and always use factory value" + default y + help + Always return factory pre-programmed values, stored in FCFG and ignore + values provided in CCFG (Customer Configuration). + +choice + prompt "Select MAC address type for device ID" + default HWINFO_CC13XX_CC26XX_USE_IEEE_MAC + help + Specify the MAC address type to be used as device ID by the driver. + +config HWINFO_CC13XX_CC26XX_USE_IEEE_MAC + bool "Use IEEE 802.15.4 extended address" + help + Use 8-bytes length IEEE 802.15.4 extended address as device ID value. + +config HWINFO_CC13XX_CC26XX_USE_BLE_MAC + bool "Use BLE MAC address" + help + Use 6-bytes length BLE MAC address as device ID value. + +endchoice + +endif + config HWINFO_STM32 bool "STM32 hwinfo" default y diff --git a/drivers/hwinfo/hwinfo_cc13xx_cc26xx.c b/drivers/hwinfo/hwinfo_cc13xx_cc26xx.c new file mode 100644 index 00000000000..536ff15a192 --- /dev/null +++ b/drivers/hwinfo/hwinfo_cc13xx_cc26xx.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 Piotr Dymacz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_HWINFO_CC13XX_CC26XX_USE_BLE_MAC +#define CC13XX_CC26XX_DEVID_SIZE 6 +#else +#define CC13XX_CC26XX_DEVID_SIZE 8 +#endif + +ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) +{ + uint8_t *mac; + + if (IS_ENABLED(CONFIG_HWINFO_CC13XX_CC26XX_USE_BLE_MAC)) { + if (IS_ENABLED(CONFIG_HWINFO_CC13XX_CC26XX_ALWAYS_USE_FACTORY_DEFAULT) || + sys_read32(CCFG_BASE + CCFG_O_IEEE_BLE_0) == 0xFFFFFFFF || + sys_read32(CCFG_BASE + CCFG_O_IEEE_BLE_1) == 0xFFFFFFFF) { + mac = (uint8_t *)(FCFG1_BASE + FCFG1_O_MAC_BLE_0); + } else { + mac = (uint8_t *)(CCFG_BASE + CCFG_O_IEEE_BLE_0); + } + } else if (IS_ENABLED(CONFIG_HWINFO_CC13XX_CC26XX_USE_IEEE_MAC)) { + if (IS_ENABLED(CONFIG_HWINFO_CC13XX_CC26XX_ALWAYS_USE_FACTORY_DEFAULT) || + sys_read32(CCFG_BASE + CCFG_O_IEEE_MAC_0) == 0xFFFFFFFF || + sys_read32(CCFG_BASE + CCFG_O_IEEE_MAC_1) == 0xFFFFFFFF) { + mac = (uint8_t *)(FCFG1_BASE + FCFG1_O_MAC_15_4_0); + } else { + mac = (uint8_t *)(CCFG_BASE + CCFG_O_IEEE_MAC_0); + } + } + + if (length > CC13XX_CC26XX_DEVID_SIZE) { + length = CC13XX_CC26XX_DEVID_SIZE; + } + + /* Provide device ID (MAC) in big endian */ + sys_memcpy_swap(buffer, mac, length); + + return length; +} + +int z_impl_hwinfo_get_reset_cause(uint32_t *cause) +{ + uint32_t reset_src; + + reset_src = SysCtrlResetSourceGet(); + + switch (reset_src) { + case RSTSRC_PWR_ON: + *cause = RESET_POR; + break; + case RSTSRC_PIN_RESET: + *cause = RESET_PIN; + break; + case RSTSRC_VDDS_LOSS: + __fallthrough; + case RSTSRC_VDDR_LOSS: + *cause = RESET_BROWNOUT; + break; + case RSTSRC_CLK_LOSS: + *cause = RESET_CLOCK; + break; + case RSTSRC_SYSRESET: + *cause = RESET_SOFTWARE; + break; + } + + return 0; +} + +int z_impl_hwinfo_clear_reset_cause(void) +{ + return -ENOSYS; +} + +int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) +{ + *supported = (RESET_PIN + | RESET_SOFTWARE + | RESET_BROWNOUT + | RESET_POR + | RESET_CLOCK); + + return 0; +} From beec8b05a8f11de474c88cdec15cdf89dbd3a86b Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 14:05:58 +0200 Subject: [PATCH 0807/4498] device: only allow PRE_KERNEL_1/2 and POST_KERNEL levels Because devices share the same underlying infrastructure with SYS_INIT, the same levels have always been available. However, not all of them are needed, and some are not even usable. For example, `EARLY` can't be used because when initialized `z_device_state_init` has not been called yet. `SMP` has never been used by device drivers, and it is now in question, likely to be moved to SMP specific hooks. Finally, `APPLICATION` does not make much sense in the context of Kernel devices. Note that of the 3 levels just mentioned, only one was actively tested (`APPLICATION`) by Kernel tests, meaning others were likely never considered in the context of devices. This patch leaves `PRE_KERNEL_1`, `PRE_KERNEL_2` and `POST_KERNEL` available to devices. Others have been deprecated, and will generate a compiler warning if used. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 7 +++++++ include/zephyr/device.h | 28 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 9e5c3b37d93..387aacaf282 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -94,6 +94,13 @@ Recommended Changes marked as deprecated as well. The new modem subsystem :kconfig:option:`CONFIG_MODEM_CMUX` and :kconfig:option:`CONFIG_MODEM_PPP`` should be used instead. +* Device drivers should now be restricted to ``PRE_KERNEL_1``, ``PRE_KERNEL_2`` + and ``POST_KERNEL`` initialization levels. Other device initialization levels, + including ``EARLY``, ``APPLICATION``, and ``SMP``, have been deprecated and + will be removed in future releases. Note that these changes do not apply to + initialization levels used in the context of the ``init.h`` API, + e.g. :c:macro:`SYS_INIT`. + Picolibc-related Changes ************************ diff --git a/include/zephyr/device.h b/include/zephyr/device.h index ce9b6c1312e..ca595795000 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -118,8 +118,8 @@ typedef int16_t device_handle_t; * stored in @ref device.data. * @param config Pointer to the device's private constant data, which will be * stored in @ref device.config. - * @param level The device's initialization level. See @ref sys_init for - * details. + * @param level The device's initialization level (PRE_KERNEL_1, PRE_KERNEL_2 or + * POST_KERNEL). * @param prio The device's priority within its initialization level. See * SYS_INIT() for details. * @param api Pointer to the device's API structure. Can be `NULL`. @@ -169,7 +169,8 @@ typedef int16_t device_handle_t; * stored in @ref device.data. * @param config Pointer to the device's private constant data, which will be * stored in @ref device.config field. - * @param level The device's initialization level. See SYS_INIT() for details. + * @param level The device's initialization level (PRE_KERNEL_1, PRE_KERNEL_2 or + * POST_KERNEL). * @param prio The device's priority within its initialization level. See * SYS_INIT() for details. * @param api Pointer to the device's API structure. Can be `NULL`. @@ -931,6 +932,25 @@ static inline bool z_impl_device_is_ready(const struct device *dev) DEVICE_NAME_GET(dev_id)) = \ Z_DEVICE_INIT(name, pm, data, config, api, state, deps) +/* deprecated device initialization levels */ +#define Z_DEVICE_LEVEL_DEPRECATED_EARLY \ + __WARN("EARLY device driver level is deprecated") +#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_1 +#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_2 +#define Z_DEVICE_LEVEL_DEPRECATED_POST_KERNEL +#define Z_DEVICE_LEVEL_DEPRECATED_APPLICATION \ + __WARN("APPLICATION device driver level is deprecated") +#define Z_DEVICE_LEVEL_DEPRECATED_SMP \ + __WARN("SMP device driver level is deprecated") + +/** + * @brief Issue a warning if the given init level is deprecated. + * + * @param level Init level + */ +#define Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \ + Z_DEVICE_LEVEL_DEPRECATED_##level + /** * @brief Define the init entry for a device. * @@ -942,6 +962,8 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * @param prio Initialization priority. */ #define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \ + Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \ + \ static const Z_DECL_ALIGN(struct init_entry) __used __noasan \ Z_INIT_ENTRY_SECTION(level, prio, \ Z_DEVICE_INIT_SUB_PRIO(node_id)) \ From 3ff5222a6fded4334ca8033e6d962be4995adb92 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 13 Sep 2023 14:54:25 +0200 Subject: [PATCH 0808/4498] tests: kernel: device: drop APPLICATION level Level is about to be removed, so stop testing it. Signed-off-by: Gerard Marull-Paretas --- tests/kernel/device/src/main.c | 4 ++-- tests/kernel/device/src/test_driver_init.c | 22 ++++------------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/tests/kernel/device/src/main.c b/tests/kernel/device/src/main.c index a3e9430c15a..4c02a52ce94 100644 --- a/tests/kernel/device/src/main.c +++ b/tests/kernel/device/src/main.c @@ -284,9 +284,9 @@ ZTEST(device, test_device_init_level) bool seq_correct = true; /* we check if the stored executing sequence for different level is - * correct, and it should be 1, 2, 3, 4 + * correct, and it should be 1, 2, 3 */ - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 3; i++) { if (init_level_sequence[i] != (i + 1)) { seq_correct = false; } diff --git a/tests/kernel/device/src/test_driver_init.c b/tests/kernel/device/src/test_driver_init.c index e89d6acc7ff..aaca820942f 100644 --- a/tests/kernel/device/src/test_driver_init.c +++ b/tests/kernel/device/src/test_driver_init.c @@ -19,7 +19,6 @@ #define MY_DRIVER_LV_1 "my_driver_level_1" #define MY_DRIVER_LV_2 "my_driver_level_2" #define MY_DRIVER_LV_3 "my_driver_level_3" -#define MY_DRIVER_LV_4 "my_driver_level_4" #define MY_DRIVER_PRI_1 "my_driver_priority_1" #define MY_DRIVER_PRI_2 "my_driver_priority_2" #define MY_DRIVER_PRI_3 "my_driver_priority_3" @@ -28,7 +27,6 @@ #define LEVEL_PRE_KERNEL_1 1 #define LEVEL_PRE_KERNEL_2 2 #define LEVEL_POST_KERNEL 3 -#define LEVEL_APPLICATION 4 #define PRIORITY_1 1 #define PRIORITY_2 2 @@ -37,7 +35,7 @@ /* this is for storing sequence during initialization */ -__pinned_bss int init_level_sequence[4] = {0}; +__pinned_bss int init_level_sequence[3] = {0}; __pinned_bss int init_priority_sequence[4] = {0}; __pinned_bss int init_sub_priority_sequence[3] = {0}; __pinned_bss unsigned int seq_level_cnt; @@ -87,14 +85,6 @@ static int my_driver_lv_3_init(const struct device *dev) return 0; } -static int my_driver_lv_4_init(const struct device *dev) -{ - init_level_sequence[seq_level_cnt] = LEVEL_APPLICATION; - seq_level_cnt++; - - return 0; -} - /* driver init function of testing priority */ static int my_driver_pri_1_init(const struct device *dev) { @@ -173,10 +163,6 @@ DEVICE_DEFINE(my_driver_level_3, MY_DRIVER_LV_3, &my_driver_lv_3_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs_my_drivers); -DEVICE_DEFINE(my_driver_level_4, MY_DRIVER_LV_4, &my_driver_lv_4_init, - NULL, NULL, NULL, APPLICATION, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs_my_drivers); - /* We use priority value of 20 to create a possible sorting conflict with * priority value of 2. So if the linker sorting isn't working correctly * we'll find out. @@ -201,8 +187,8 @@ DEVICE_DEFINE(my_driver_priority_3, MY_DRIVER_PRI_3, * other in devicetree so that we can validate linker sorting. */ DEVICE_DT_DEFINE(DT_NODELABEL(fakedomain_0), my_driver_sub_pri_0_init, - NULL, NULL, NULL, APPLICATION, 33, NULL); + NULL, NULL, NULL, POST_KERNEL, 33, NULL); DEVICE_DT_DEFINE(DT_NODELABEL(fakedomain_1), my_driver_sub_pri_1_init, - NULL, NULL, NULL, APPLICATION, 33, NULL); + NULL, NULL, NULL, POST_KERNEL, 33, NULL); DEVICE_DT_DEFINE(DT_NODELABEL(fakedomain_2), my_driver_sub_pri_2_init, - NULL, NULL, NULL, APPLICATION, 33, NULL); + NULL, NULL, NULL, POST_KERNEL, 33, NULL); From 235319cfaad9eeef7b667d056c068cfcb82ee408 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 31 Aug 2023 11:25:51 +0200 Subject: [PATCH 0809/4498] samples: boards: stm32: power_mgmt: Disable exclusive device PM Disable exclusive PM run time handling as PM_DEVICE_RUNTIME is not supported in all drivers. Signed-off-by: Erwan Gouriou --- samples/boards/stm32/power_mgmt/blinky/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/boards/stm32/power_mgmt/blinky/prj.conf b/samples/boards/stm32/power_mgmt/blinky/prj.conf index 4921dcc3392..9ac206bd0f3 100644 --- a/samples/boards/stm32/power_mgmt/blinky/prj.conf +++ b/samples/boards/stm32/power_mgmt/blinky/prj.conf @@ -1,3 +1,4 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y +CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n From 16487c7047b6fb13b20b9adeff7db9491006df62 Mon Sep 17 00:00:00 2001 From: Saw Xu Date: Tue, 15 Aug 2023 11:12:09 +0800 Subject: [PATCH 0810/4498] dts: bindings: usb_audio: Add volume properties Add volume feature specific fields. So remove this outdated description. Signed-off-by: Saw Xu --- .../usb/usb-audio-feature-volume.yaml | 37 +++++++++++++++++++ dts/bindings/usb/usb-audio-hp.yaml | 2 +- dts/bindings/usb/usb-audio-hs.yaml | 3 +- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 dts/bindings/usb/usb-audio-feature-volume.yaml diff --git a/dts/bindings/usb/usb-audio-feature-volume.yaml b/dts/bindings/usb/usb-audio-feature-volume.yaml new file mode 100644 index 00000000000..7a4356f4ed5 --- /dev/null +++ b/dts/bindings/usb/usb-audio-feature-volume.yaml @@ -0,0 +1,37 @@ +# Copyright (c) 2023, LISTENAI +# SPDX-License-Identifier: Apache-2.0 +# +# Specific fields for USB volume control. + +description: USB volume control specific fields. + +compatible: "usb-audio-feature-volume" + +include: base.yaml + +properties: + volume-max: + type: int + default: 0x0A00 + description: | + attention: this attribute is a signed value. + This attribute represents the maximum volume level. + The range from +127.9961 dB (0x7FFF) down to -127.9961 dB (0x8001). + Valid range: 0 - 0xFFFF + volume-min: + type: int + default: 0xBA00 + description: | + attention: this attribute is a signed value. + This attribute represents the minimum volume level. + The range from +127.9961 dB (0x7FFF) down to -127.9961 dB (0x8001). + Valid range: 0 - 0xFFFF + volume-res: + type: int + default: 0x100 + description: | + attention: this attribute can only take positive values. + This attribute represents the volume resolution(step). + 1 = 1/256 dB or 0.00390625 dB. + 0x100(256) = 1dB. + Valid range: 1 - 0x7FFF diff --git a/dts/bindings/usb/usb-audio-hp.yaml b/dts/bindings/usb/usb-audio-hp.yaml index 051c57c07d3..91968126c1e 100644 --- a/dts/bindings/usb/usb-audio-hp.yaml +++ b/dts/bindings/usb/usb-audio-hp.yaml @@ -7,7 +7,7 @@ description: USB Audio headphones specific fields. compatible: "usb-audio-hp" -include: usb-audio.yaml +include: [usb-audio.yaml, usb-audio-feature-volume.yaml] properties: resolution: diff --git a/dts/bindings/usb/usb-audio-hs.yaml b/dts/bindings/usb/usb-audio-hs.yaml index 3c4a39842a5..ce0245cc136 100644 --- a/dts/bindings/usb/usb-audio-hs.yaml +++ b/dts/bindings/usb/usb-audio-hs.yaml @@ -7,7 +7,7 @@ description: USB Audio headset specific fields. compatible: "usb-audio-hs" -include: usb-audio.yaml +include: [usb-audio.yaml, usb-audio-feature-volume.yaml] properties: mic-resolution: @@ -167,7 +167,6 @@ properties: type: boolean description: | Enable Volume feature. - Currently not supported. hp-feature-tone-control: type: boolean description: | From 459f8e3251b0f1b4b02dc7d2653d0993772d79ce Mon Sep 17 00:00:00 2001 From: Saw Xu Date: Tue, 15 Aug 2023 11:12:09 +0800 Subject: [PATCH 0811/4498] usb: device: audio: Support volume control Makes USB device audio class support volume control feature. Signed-off-by: Saw Xu --- subsys/usb/device/class/audio/audio.c | 92 +++++++++++++++++-- .../device/class/audio/usb_audio_internal.h | 5 + 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/subsys/usb/device/class/audio/audio.c b/subsys/usb/device/class/audio/audio.c index 646f006ab51..338163940e3 100644 --- a/subsys/usb/device/class/audio/audio.c +++ b/subsys/usb/device/class/audio/audio.c @@ -24,6 +24,12 @@ #include LOG_MODULE_REGISTER(usb_audio, CONFIG_USB_AUDIO_LOG_LEVEL); +struct feature_volume { + int16_t volume_max; + int16_t volume_min; + int16_t volume_res; +}; + /* Device data structure */ struct usb_audio_dev_data { const struct usb_audio_ops *ops; @@ -41,6 +47,9 @@ struct usb_audio_dev_data { /* Not applicable for Headphones, left with 0 */ uint16_t in_frame_size; + /* Not applicable for not support volume feature device */ + struct feature_volume volumes; + bool rx_enable; bool tx_enable; }; @@ -146,11 +155,14 @@ static struct usb_ep_cfg_data dev##_usb_audio_ep_data_##i[] = { \ #define DEFINE_AUDIO_DEV_DATA(dev, i, __out_pool, __in_pool_size) \ static uint8_t dev##_controls_##i[FEATURES_SIZE(dev, i)] = {0};\ - static struct usb_audio_dev_data dev##_audio_dev_data_##i = \ - { .pool = __out_pool, \ - .in_frame_size = __in_pool_size, \ - .controls = {dev##_controls_##i, NULL}, \ - .ch_cnt = {(CH_CNT(dev, i) + 1), 0} \ + static struct usb_audio_dev_data dev##_audio_dev_data_##i = \ + { .pool = __out_pool, \ + .in_frame_size = __in_pool_size, \ + .controls = {dev##_controls_##i, NULL}, \ + .ch_cnt = {(CH_CNT(dev, i) + 1), 0}, \ + .volumes.volume_max = GET_VOLUME(dev, i, volume_max), \ + .volumes.volume_min = GET_VOLUME(dev, i, volume_min), \ + .volumes.volume_res = GET_VOLUME(dev, i, volume_res), \ } #define DEFINE_AUDIO_DEV_DATA_BIDIR(dev, i, __out_pool, __in_pool_size) \ @@ -161,7 +173,10 @@ static struct usb_ep_cfg_data dev##_usb_audio_ep_data_##i[] = { \ .in_frame_size = __in_pool_size, \ .controls = {dev##_controls0_##i, dev##_controls1_##i}, \ .ch_cnt = {(CH_CNT(dev##_MIC, i) + 1), \ - (CH_CNT(dev##_HP, i) + 1)} \ + (CH_CNT(dev##_HP, i) + 1)}, \ + .volumes.volume_max = GET_VOLUME(dev, i, volume_max), \ + .volumes.volume_min = GET_VOLUME(dev, i, volume_min), \ + .volumes.volume_res = GET_VOLUME(dev, i, volume_res), \ } /** @@ -541,6 +556,67 @@ static int handle_fu_mute_req(struct usb_audio_dev_data *audio_dev_data, return -EINVAL; } + +static int handle_fu_volume_req(struct usb_audio_dev_data *audio_dev_data, + struct usb_setup_packet *setup, int32_t *len, uint8_t **data, + struct usb_audio_fu_evt *evt, uint8_t device) +{ + uint8_t ch = (setup->wValue) & 0xFF; + uint8_t ch_cnt = audio_dev_data->ch_cnt[device]; + uint8_t *controls = audio_dev_data->controls[device]; + uint8_t *control_val = &controls[POS(VOLUME, ch, ch_cnt)]; + int16_t target_vol = 0; + int16_t temp_vol = 0; + + if (usb_reqtype_is_to_device(setup)) { + /* Check if *len has valid value */ + if (*len != LEN(1, VOLUME)) { + LOG_ERR("*len: %d, LEN(1, VOLUME): %d", *len, LEN(1, VOLUME)); + return -EINVAL; + } + if (setup->bRequest == USB_AUDIO_SET_CUR) { + target_vol = *((int16_t *)*data); + if (!IN_RANGE(target_vol, audio_dev_data->volumes.volume_min, + audio_dev_data->volumes.volume_max)) { + LOG_ERR("Volume out of range: %d", target_vol); + return -EINVAL; + } + if (target_vol % audio_dev_data->volumes.volume_res != 0) { + target_vol = ROUND_UP(target_vol, + audio_dev_data->volumes.volume_res); + } + evt->val = control_val; + evt->val_len = *len; + *((int16_t *)evt->val) = sys_le16_to_cpu(target_vol); + return 0; + } + } else { + if (setup->bRequest == USB_AUDIO_GET_CUR) { + *len = LEN(ch_cnt, VOLUME); + temp_vol = sys_cpu_to_le16(*(int16_t *)control_val); + memcpy(*data, &temp_vol, *len); + return 0; + } else if (setup->bRequest == USB_AUDIO_GET_MIN) { + *len = sizeof(audio_dev_data->volumes.volume_min); + temp_vol = sys_cpu_to_le16(audio_dev_data->volumes.volume_min); + memcpy(*data, &temp_vol, *len); + return 0; + } else if (setup->bRequest == USB_AUDIO_GET_MAX) { + *len = sizeof(audio_dev_data->volumes.volume_max); + temp_vol = sys_cpu_to_le16(audio_dev_data->volumes.volume_max); + memcpy(*data, &temp_vol, *len); + return 0; + } else if (setup->bRequest == USB_AUDIO_GET_RES) { + *len = sizeof(audio_dev_data->volumes.volume_res); + temp_vol = sys_cpu_to_le16(audio_dev_data->volumes.volume_res); + memcpy(*data, &temp_vol, *len); + return 0; + } + } + + return -EINVAL; +} + /** * @brief Handler for feature unit requests. * @@ -590,6 +666,10 @@ static int handle_feature_unit_req(struct usb_audio_dev_data *audio_dev_data, ret = handle_fu_mute_req(audio_dev_data, pSetup, len, data, &evt, device); break; + case USB_AUDIO_FU_VOLUME_CONTROL: + ret = handle_fu_volume_req(audio_dev_data, pSetup, + len, data, &evt, device); + break; default: return -ENOTSUP; } diff --git a/subsys/usb/device/class/audio/usb_audio_internal.h b/subsys/usb/device/class/audio/usb_audio_internal.h index c0d5383577d..7a70ae94178 100644 --- a/subsys/usb/device/class/audio/usb_audio_internal.h +++ b/subsys/usb/device/class/audio/usb_audio_internal.h @@ -160,6 +160,11 @@ #define GET_RES_HS_MIC(i) DT_PROP(DT_INST(i, COMPAT_HS), mic_resolution) #define GET_RES(dev, i) GET_RES_##dev(i) +#define GET_VOLUME_HS(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_HS), prop, 0) +#define GET_VOLUME_HP(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_HP), prop, 0) +#define GET_VOLUME_MIC(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_MIC), prop, 0) +#define GET_VOLUME(dev, i, prop) GET_VOLUME_##dev(i, prop) + #define SYNC_TYPE_HP(i) 3 #define SYNC_TYPE_MIC(i) DT_ENUM_IDX(DT_INST(i, COMPAT_MIC), sync_type) #define SYNC_TYPE_HS_HP(i) 3 From 8951bab7e741f3750532d4af68497b9af06a453c Mon Sep 17 00:00:00 2001 From: Saw Xu Date: Tue, 15 Aug 2023 11:12:09 +0800 Subject: [PATCH 0812/4498] samples: subsys: usb: audio: Add volume control case Add sample code for getting volume to headset sample and headphone_microphone sample Signed-off-by: Saw Xu --- samples/subsys/usb/audio/headphones_microphone/app.overlay | 5 +++++ samples/subsys/usb/audio/headphones_microphone/src/main.c | 7 +++++++ samples/subsys/usb/audio/headset/app.overlay | 5 +++++ samples/subsys/usb/audio/headset/src/main.c | 7 +++++++ 4 files changed, 24 insertions(+) diff --git a/samples/subsys/usb/audio/headphones_microphone/app.overlay b/samples/subsys/usb/audio/headphones_microphone/app.overlay index 0e68f9a89d2..1c9633b3ec0 100644 --- a/samples/subsys/usb/audio/headphones_microphone/app.overlay +++ b/samples/subsys/usb/audio/headphones_microphone/app.overlay @@ -10,6 +10,11 @@ feature-mute; channel-l; channel-r; + + feature-volume; + volume-max = <0x0500>; + volume-min = <0xBA00>; + volume-res = <0x100>; }; mic_0 { compatible = "usb-audio-mic"; diff --git a/samples/subsys/usb/audio/headphones_microphone/src/main.c b/samples/subsys/usb/audio/headphones_microphone/src/main.c index 57a5bcd62d8..0c680702ed3 100644 --- a/samples/subsys/usb/audio/headphones_microphone/src/main.c +++ b/samples/subsys/usb/audio/headphones_microphone/src/main.c @@ -45,10 +45,17 @@ static void data_received(const struct device *dev, static void feature_update(const struct device *dev, const struct usb_audio_fu_evt *evt) { + int16_t volume = 0; + LOG_DBG("Control selector %d for channel %d updated", evt->cs, evt->channel); switch (evt->cs) { case USB_AUDIO_FU_MUTE_CONTROL: + break; + case USB_AUDIO_FU_VOLUME_CONTROL: + volume = *((int16_t *)(evt->val)); + LOG_INF("set volume: %d", volume); + break; default: break; } diff --git a/samples/subsys/usb/audio/headset/app.overlay b/samples/subsys/usb/audio/headset/app.overlay index cdb2aa0aa88..91c153cd13b 100644 --- a/samples/subsys/usb/audio/headset/app.overlay +++ b/samples/subsys/usb/audio/headset/app.overlay @@ -14,5 +14,10 @@ hp-feature-mute; hp-channel-l; hp-channel-r; + + hp-feature-volume; + volume-max = <0x0500>; + volume-min = <0xBA00>; + volume-res = <0x100>; }; }; diff --git a/samples/subsys/usb/audio/headset/src/main.c b/samples/subsys/usb/audio/headset/src/main.c index ddf39735bc5..447ebf03308 100644 --- a/samples/subsys/usb/audio/headset/src/main.c +++ b/samples/subsys/usb/audio/headset/src/main.c @@ -43,10 +43,17 @@ static void data_received(const struct device *dev, static void feature_update(const struct device *dev, const struct usb_audio_fu_evt *evt) { + int16_t volume = 0; + LOG_DBG("Control selector %d for channel %d updated", evt->cs, evt->channel); switch (evt->cs) { case USB_AUDIO_FU_MUTE_CONTROL: + break; + case USB_AUDIO_FU_VOLUME_CONTROL: + volume = *((int16_t *)(evt->val)); + LOG_INF("set volume: %d", volume); + break; default: break; } From a1adc17b31d260eb961beb073f9ab8d07004a189 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 6 Sep 2023 15:06:04 +0200 Subject: [PATCH 0813/4498] drivers: adc: stm32: move internal path setting to sensor drivers On some STM32 families (such as F4), temperature and Vbat sensor share the same ADC channel, which can lead to conflict when reading them, and wrong measurement can follow. To alleviate this problem, this commit moves the setting of the common path internal channel to the sensor drivers themselves instead of doing it in the ADC driver. The teardown is still done in the ADC driver, systematically, instead of channel by channel (which has the same result). By moving this logic in the sensor drivers, the properties temp-channel, vbat-channel and vref-channel becomes useless and are thus removed. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 101 ++----------------------- drivers/sensor/stm32_temp/stm32_temp.c | 7 ++ drivers/sensor/stm32_vbat/stm32_vbat.c | 6 ++ drivers/sensor/stm32_vref/stm32_vref.c | 9 +++ 4 files changed, 27 insertions(+), 96 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 28a1df08ba6..875e9f2ba94 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -167,9 +167,6 @@ struct adc_stm32_cfg { const struct pinctrl_dev_config *pcfg; const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME]; int8_t num_sampling_time_common_channels; - int8_t temp_channel; - int8_t vref_channel; - int8_t vbat_channel; int8_t res_table_size; const uint32_t res_table[]; }; @@ -610,93 +607,6 @@ static int adc_stm32_enable(ADC_TypeDef *adc) return 0; } -/* - * Enable internal channel source - */ -static void adc_stm32_set_common_path(const struct device *dev, uint32_t PathInternal) -{ - const struct adc_stm32_cfg *config = - (const struct adc_stm32_cfg *)dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; - - ARG_UNUSED(adc); /* Avoid 'unused variable' warning for some families */ - - /* Do not remove existing paths */ - PathInternal |= LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc)); - LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal); -} - -static void adc_stm32_setup_channel(const struct device *dev, uint8_t channel_id) -{ - const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; - - if (config->temp_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR); - k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US); - } - - if (config->vref_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT); -#ifdef LL_ADC_DELAY_VREFINT_STAB_US - k_usleep(LL_ADC_DELAY_VREFINT_STAB_US); -#endif - } - -#if defined(LL_ADC_CHANNEL_VBAT) - /* Enable the bridge divider only when needed for ADC conversion. */ - if (config->vbat_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT); - } -#endif /* LL_ADC_CHANNEL_VBAT */ -} - -static void adc_stm32_unset_common_path(const struct device *dev, uint32_t PathInternal) -{ - const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; - const uint32_t currentPath = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc)); - - ARG_UNUSED(adc); /* Avoid 'unused variable' warning for some families */ - - PathInternal = ~PathInternal & currentPath; - LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal); -} - -static void adc_stm32_teardown_channels(const struct device *dev) -{ - const struct adc_stm32_cfg *config = dev->config; - struct adc_stm32_data *data = dev->data; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; - uint8_t channel_id; - - for (uint32_t channels = data->channels; channels; channels &= ~BIT(channel_id)) { - channel_id = find_lsb_set(channels) - 1; - if (config->temp_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR); - } - - if (config->vref_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT); - } - -#if defined(LL_ADC_CHANNEL_VBAT) - /* Enable the bridge divider only when needed for ADC conversion. */ - if (config->vbat_channel == channel_id) { - adc_stm32_disable(adc); - adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT); - } -#endif /* LL_ADC_CHANNEL_VBAT */ - } - - adc_stm32_enable(adc); -} - #ifdef CONFIG_ADC_STM32_DMA static void dma_callback(const struct device *dev, void *user_data, uint32_t channel, int status) @@ -873,8 +783,6 @@ static int start_read(const struct device *dev, uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(channel_id); - adc_stm32_setup_channel(dev, channel_id); - #if defined(CONFIG_SOC_SERIES_STM32H7X) /* * Each channel in the sequence must be previously enabled in PCSEL. @@ -1047,10 +955,14 @@ static void adc_context_on_complete(struct adc_context *ctx, int status) { struct adc_stm32_data *data = CONTAINER_OF(ctx, struct adc_stm32_data, ctx); + const struct adc_stm32_cfg *config = data->dev->config; + ADC_TypeDef *adc = (ADC_TypeDef *)config->base; ARG_UNUSED(status); - adc_stm32_teardown_channels(data->dev); + adc_stm32_disable(adc); + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), + LL_ADC_PATH_INTERNAL_NONE); } static int adc_stm32_read(const struct device *dev, @@ -1538,9 +1450,6 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \ .pclk_len = DT_INST_NUM_CLOCKS(index), \ .clk_prescaler = ADC_STM32_DT_PRESC(index), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ - .temp_channel = DT_INST_PROP_OR(index, temp_channel, 0xFF), \ - .vref_channel = DT_INST_PROP_OR(index, vref_channel, 0xFF), \ - .vbat_channel = DT_INST_PROP_OR(index, vbat_channel, 0xFF), \ .sampling_time_table = DT_INST_PROP(index, sampling_times), \ .num_sampling_time_common_channels = \ DT_INST_PROP_OR(index, num_sampling_time_common_channels, 0),\ diff --git a/drivers/sensor/stm32_temp/stm32_temp.c b/drivers/sensor/stm32_temp/stm32_temp.c index e432461fee5..7ad72490e91 100644 --- a/drivers/sensor/stm32_temp/stm32_temp.c +++ b/drivers/sensor/stm32_temp/stm32_temp.c @@ -10,6 +10,7 @@ #include #include #include +#include #if defined(CONFIG_SOC_SERIES_STM32H5X) #include #endif /* CONFIG_SOC_SERIES_STM32H5X */ @@ -35,6 +36,7 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); struct stm32_temp_data { const struct device *adc; const struct adc_channel_cfg adc_cfg; + ADC_TypeDef *adc_base; struct adc_sequence adc_seq; struct k_mutex mutex; int16_t sample_buffer; @@ -78,6 +80,10 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel goto unlock; } + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base), + LL_ADC_PATH_INTERNAL_TEMPSENSOR); + k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US); + rc = adc_read(data->adc, sp); if (rc == 0) { data->raw = data->sample_buffer; @@ -168,6 +174,7 @@ static int stm32_temp_init(const struct device *dev) static struct stm32_temp_data stm32_temp_dev_data = { .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(0)), + .adc_base = (ADC_TypeDef *)DT_REG_ADDR(DT_INST_IO_CHANNELS_CTLR(0)), .adc_cfg = { .gain = ADC_GAIN_1, .reference = ADC_REF_INTERNAL, diff --git a/drivers/sensor/stm32_vbat/stm32_vbat.c b/drivers/sensor/stm32_vbat/stm32_vbat.c index 489d4c0ae35..10c035baacf 100644 --- a/drivers/sensor/stm32_vbat/stm32_vbat.c +++ b/drivers/sensor/stm32_vbat/stm32_vbat.c @@ -9,6 +9,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(stm32_vbat, CONFIG_SENSOR_LOG_LEVEL); @@ -21,6 +22,7 @@ LOG_MODULE_REGISTER(stm32_vbat, CONFIG_SENSOR_LOG_LEVEL); struct stm32_vbat_data { const struct device *adc; const struct adc_channel_cfg adc_cfg; + ADC_TypeDef *adc_base; struct adc_sequence adc_seq; struct k_mutex mutex; int16_t sample_buffer; @@ -50,6 +52,9 @@ static int stm32_vbat_sample_fetch(const struct device *dev, enum sensor_channel goto unlock; } + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base), + LL_ADC_PATH_INTERNAL_VBAT); + rc = adc_read(data->adc, sp); if (rc == 0) { data->raw = data->sample_buffer; @@ -110,6 +115,7 @@ static int stm32_vbat_init(const struct device *dev) #define STM32_VBAT_DEFINE(inst) \ static struct stm32_vbat_data stm32_vbat_dev_data_##inst = { \ .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \ + .adc_base = (ADC_TypeDef *)DT_REG_ADDR(DT_INST_IO_CHANNELS_CTLR(0)), \ .adc_cfg = { \ .gain = ADC_GAIN_1, \ .reference = ADC_REF_INTERNAL, \ diff --git a/drivers/sensor/stm32_vref/stm32_vref.c b/drivers/sensor/stm32_vref/stm32_vref.c index 4e49e17e9e8..4dcb8324076 100644 --- a/drivers/sensor/stm32_vref/stm32_vref.c +++ b/drivers/sensor/stm32_vref/stm32_vref.c @@ -11,6 +11,7 @@ #include #include #include +#include #if defined(CONFIG_SOC_SERIES_STM32H5X) #include #endif /* CONFIG_SOC_SERIES_STM32H5X */ @@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(stm32_vref, CONFIG_SENSOR_LOG_LEVEL); struct stm32_vref_data { const struct device *adc; const struct adc_channel_cfg adc_cfg; + ADC_TypeDef *adc_base; struct adc_sequence adc_seq; struct k_mutex mutex; int16_t sample_buffer; @@ -49,6 +51,12 @@ static int stm32_vref_sample_fetch(const struct device *dev, enum sensor_channel goto unlock; } + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base), + LL_ADC_PATH_INTERNAL_VREFINT); +#ifdef LL_ADC_DELAY_VREFINT_STAB_US + k_usleep(LL_ADC_DELAY_VREFINT_STAB_US); +#endif + rc = adc_read(data->adc, sp); if (rc == 0) { data->raw = data->sample_buffer; @@ -135,6 +143,7 @@ static int stm32_vref_init(const struct device *dev) static struct stm32_vref_data stm32_vref_dev_data = { .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(0)), + .adc_base = (ADC_TypeDef *)DT_REG_ADDR(DT_INST_IO_CHANNELS_CTLR(0)), .adc_cfg = {.gain = ADC_GAIN_1, .reference = ADC_REF_INTERNAL, .acquisition_time = ADC_ACQ_TIME_MAX, From fa1f33316d2d8750bfd174b531df43fd26c7b85a Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 6 Sep 2023 15:08:31 +0200 Subject: [PATCH 0814/4498] dts: arm: st: remove sensor channels from stm32 adc nodes Remove temp-, vref- and vbat-channel from STM32 ADC nodes as it is not used in the driver anymore. Signed-off-by: Guillaume Gautier --- dts/arm/st/c0/stm32c0.dtsi | 2 -- dts/arm/st/f0/stm32f0.dtsi | 2 -- dts/arm/st/f0/stm32f031.dtsi | 5 ----- dts/arm/st/f1/stm32f1.dtsi | 2 -- dts/arm/st/f2/stm32f2.dtsi | 2 -- dts/arm/st/f3/stm32f302.dtsi | 3 --- dts/arm/st/f3/stm32f303.dtsi | 4 ---- dts/arm/st/f3/stm32f334.dtsi | 3 --- dts/arm/st/f3/stm32f373.dtsi | 3 --- dts/arm/st/f4/stm32f4.dtsi | 4 ---- dts/arm/st/f7/stm32f7.dtsi | 4 ---- dts/arm/st/g0/stm32g0.dtsi | 3 --- dts/arm/st/g4/stm32g4.dtsi | 3 --- dts/arm/st/g4/stm32g473.dtsi | 1 - dts/arm/st/g4/stm32g491.dtsi | 1 - dts/arm/st/h5/stm32h5.dtsi | 3 --- dts/arm/st/h7/stm32h723.dtsi | 3 --- dts/arm/st/h7/stm32h743.dtsi | 6 ------ dts/arm/st/h7/stm32h745.dtsi | 6 ------ dts/arm/st/h7/stm32h750.dtsi | 6 ------ dts/arm/st/h7/stm32h7a3.dtsi | 6 ------ dts/arm/st/l0/stm32l0.dtsi | 2 -- dts/arm/st/l0/stm32l011X4.dtsi | 4 ---- dts/arm/st/l0/stm32l031.dtsi | 4 ---- dts/arm/st/l0/stm32l051.dtsi | 4 ---- dts/arm/st/l0/stm32l071.dtsi | 4 ---- dts/arm/st/l1/stm32l1.dtsi | 2 -- dts/arm/st/l4/stm32l4.dtsi | 3 --- dts/arm/st/l4/stm32l471.dtsi | 1 - dts/arm/st/l5/stm32l5.dtsi | 3 --- dts/arm/st/u5/stm32u5.dtsi | 6 ------ dts/arm/st/wb/stm32wb.dtsi | 3 --- dts/arm/st/wb/stm32wb55.dtsi | 4 ---- dts/arm/st/wba/stm32wba.dtsi | 3 --- dts/arm/st/wl/stm32wl.dtsi | 3 --- dts/bindings/adc/st,stm32-adc.yaml | 12 ------------ 36 files changed, 130 deletions(-) diff --git a/dts/arm/st/c0/stm32c0.dtsi b/dts/arm/st/c0/stm32c0.dtsi index 7133e2b026d..0ee56ff36dd 100644 --- a/dts/arm/st/c0/stm32c0.dtsi +++ b/dts/arm/st/c0/stm32c0.dtsi @@ -293,8 +293,6 @@ interrupts = <12 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <9>; - vref-channel = <10>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vref-channel = <17>; resolutions = ; -}; diff --git a/dts/arm/st/f1/stm32f1.dtsi b/dts/arm/st/f1/stm32f1.dtsi index 5b0d9f002c4..8676b402de1 100644 --- a/dts/arm/st/f1/stm32f1.dtsi +++ b/dts/arm/st/f1/stm32f1.dtsi @@ -339,8 +339,6 @@ interrupts = <18 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vref-channel = <17>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; }; diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index 778c30dd75d..7fa86bf6dc5 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -366,8 +366,6 @@ interrupts = <18 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vref-channel = <17>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vbat-channel = <17>; - vref-channel = <18>; resolutions = ; #io-channel-cells = <1>; - temp-channel = <16>; - vbat-channel = <17>; - vref-channel = <18>; resolutions = ; #io-channel-cells = <1>; - vref-channel = <18>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vbat-channel = <17>; - vref-channel = <18>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vref-channel = <17>; - vbat-channel = <18>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; }; diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index 11a2593964d..9b07a6d6d67 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -513,10 +513,6 @@ interrupts = <18 0>; status = "disabled"; #io-channel-cells = <1>; - /* Temperature and VBAT sensor share channel 18 */ - temp-channel = <18>; - vbat-channel = <18>; - vref-channel = <17>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - /* Temperature and VBAT sensor share channel 18 */ - temp-channel = <18>; - vbat-channel = <18>; - vref-channel = <17>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <12>; - vref-channel = <13>; - vbat-channel = <14>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vbat-channel = <17>; - vref-channel = <18>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <4>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - vref-channel = <18>; resolutions = ; #io-channel-cells = <1>; - vbat-channel = <2>; - temp-channel = <16>; - vref-channel = <17>; resolutions = ; - temp-channel = <17>; - vref-channel = <18>; resolutions = ; - temp-channel = <18>; - vref-channel = <19>; - }; - dmamux1: dmamux@40020800 { dma-requests= <107>; }; diff --git a/dts/arm/st/h7/stm32h745.dtsi b/dts/arm/st/h7/stm32h745.dtsi index d0483adf653..5cfa418cc60 100644 --- a/dts/arm/st/h7/stm32h745.dtsi +++ b/dts/arm/st/h7/stm32h745.dtsi @@ -28,12 +28,6 @@ }; }; - adc3: adc@58026000 { - vbat-channel = <17>; - temp-channel = <18>; - vref-channel = <19>; - }; - dmamux1: dmamux@40020800 { dma-requests= <107>; }; diff --git a/dts/arm/st/h7/stm32h750.dtsi b/dts/arm/st/h7/stm32h750.dtsi index 73167a4e1b2..50d20175b55 100644 --- a/dts/arm/st/h7/stm32h750.dtsi +++ b/dts/arm/st/h7/stm32h750.dtsi @@ -21,12 +21,6 @@ }; }; - adc3: adc@58026000 { - vbat-channel = <17>; - temp-channel = <18>; - vref-channel = <19>; - }; - dmamux1: dmamux@40020800 { dma-requests= <107>; }; diff --git a/dts/arm/st/h7/stm32h7a3.dtsi b/dts/arm/st/h7/stm32h7a3.dtsi index cfcf5862991..7f85387ca06 100644 --- a/dts/arm/st/h7/stm32h7a3.dtsi +++ b/dts/arm/st/h7/stm32h7a3.dtsi @@ -24,12 +24,6 @@ }; }; - adc2: adc@40022100 { - vbat-channel = <14>; - temp-channel = <18>; - vref-channel = <19>; - }; - dmamux1: dmamux@40020800 { dma-requests= <107>; }; diff --git a/dts/arm/st/l0/stm32l0.dtsi b/dts/arm/st/l0/stm32l0.dtsi index 2a77be4c636..2448656c98d 100644 --- a/dts/arm/st/l0/stm32l0.dtsi +++ b/dts/arm/st/l0/stm32l0.dtsi @@ -309,8 +309,6 @@ interrupts = <12 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <18>; - vref-channel = <17>; resolutions = ; }; }; - - adc1: adc@40012400 { - temp-channel = <18>; - }; }; }; diff --git a/dts/arm/st/l0/stm32l031.dtsi b/dts/arm/st/l0/stm32l031.dtsi index 7cf9fdb8698..18cb9e5160c 100644 --- a/dts/arm/st/l0/stm32l031.dtsi +++ b/dts/arm/st/l0/stm32l031.dtsi @@ -30,9 +30,5 @@ eeprom: eeprom@8080000{ reg = <0x08080000 DT_SIZE_K(1)>; }; - - adc1: adc@40012400 { - temp-channel = <18>; - }; }; }; diff --git a/dts/arm/st/l0/stm32l051.dtsi b/dts/arm/st/l0/stm32l051.dtsi index 93266f7e02b..e6209dc531b 100644 --- a/dts/arm/st/l0/stm32l051.dtsi +++ b/dts/arm/st/l0/stm32l051.dtsi @@ -72,9 +72,5 @@ eeprom: eeprom@8080000{ reg = <0x08080000 DT_SIZE_K(2)>; }; - - adc1: adc@40012400 { - temp-channel = <18>; - }; }; }; diff --git a/dts/arm/st/l0/stm32l071.dtsi b/dts/arm/st/l0/stm32l071.dtsi index a01ea5800bf..56d88c5bd51 100644 --- a/dts/arm/st/l0/stm32l071.dtsi +++ b/dts/arm/st/l0/stm32l071.dtsi @@ -160,9 +160,5 @@ eeprom: eeprom@8080000{ reg = <0x08080000 DT_SIZE_K(6)>; }; - - adc1: adc@40012400 { - temp-channel = <18>; - }; }; }; diff --git a/dts/arm/st/l1/stm32l1.dtsi b/dts/arm/st/l1/stm32l1.dtsi index 2f7cc7deb03..e43859d598a 100644 --- a/dts/arm/st/l1/stm32l1.dtsi +++ b/dts/arm/st/l1/stm32l1.dtsi @@ -216,8 +216,6 @@ interrupts = <18 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <16>; - vref-channel = <17>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <17>; - vbat-channel = <18>; - vref-channel = <0>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <17>; }; rtc@40002800 { diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index e5b9f1b7a62..8455fa09f45 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -659,9 +659,6 @@ interrupts = <37 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <17>; - vbat-channel = <18>; - vref-channel = <0>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <19>; - vref-channel = <0>; - vbat-channel = <18>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <13>; - vref-channel = <0>; - vbat-channel = <14>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <17>; - vbat-channel = <18>; - vref-channel = <0>; resolutions = ; - }; }; }; diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index d489143ec71..42ecc4efd8f 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -388,9 +388,6 @@ interrupts = <65 0>; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <19>; - vref-channel = <0>; - vbat-channel = <18>; resolutions = ; status = "disabled"; #io-channel-cells = <1>; - temp-channel = <12>; - vref-channel = <13>; - vbat-channel = <14>; resolutions = Date: Wed, 13 Sep 2023 08:54:52 +0200 Subject: [PATCH 0815/4498] doc: releases: update migration guide Update migration guide Signed-off-by: Guillaume Gautier --- doc/releases/migration-guide-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 387aacaf282..8c53ae0bf97 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -57,6 +57,12 @@ Required changes If the Kconfig option is set to ``y`` (current default), then the network interface name is used by the ``SO_BINDTODEVICE`` socket option. +* On all STM32 ADC, it is no longer possible to read sensor channels (Vref, + Vbat or temperature) using the ADC driver. The dedicated sensor driver should + be used instead. This change is due to a limitation on STM32F4 where the + channels for temperature and Vbat are identical, and the impossibility of + determining what we want to measure using solely the ADC API. + Recommended Changes ******************* From 336941a1e52c042a97381ed8650c651be32c7538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 14 Sep 2023 14:24:52 +0200 Subject: [PATCH 0816/4498] samples: drivers: cleanup led_xec README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The README file for led_xec sample had several formatting issues causing it to render very poorly. Signed-off-by: Benjamin Cabé --- samples/drivers/led_xec/README.rst | 94 +++++++++++++++++------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/samples/drivers/led_xec/README.rst b/samples/drivers/led_xec/README.rst index 883126640d3..072ef1abb80 100644 --- a/samples/drivers/led_xec/README.rst +++ b/samples/drivers/led_xec/README.rst @@ -9,12 +9,16 @@ Overview This sample allows to test the Microchip led-xec driver which uses the breathing-blinking LED (BBLED) controllers. The SoC design is fixed allowing each BBLED control over one specific GPIO. + MEC15xx and MEC172x: -BBLED controller 0 uses GPIO 0156. -BBLED controller 1 uses GPIO 0157. -BBLED controller 2 uses GPIO 0153. -MEC172x has a fourth instance of BBLED. -BBLED controller 3 uses GPIO 0035 + +- BBLED controller 0 uses GPIO 0156. +- BBLED controller 1 uses GPIO 0157. +- BBLED controller 2 uses GPIO 0153. + +MEC172x has a fourth instance of BBLED: + +- BBLED controller 3 uses GPIO 0035 Test pattern ============ @@ -27,44 +31,50 @@ For each LEDs (one after the other): - Blinking on: 1 sec, off: 1 sec Board Jumpers -******************** +************* + +mec172xevb_assy6906 evaluation board +==================================== + +- BBLED0: GPIO 0156. + - Connect GPIO 0156 to board LED4 by placing a wire from JP71-11 to J47-3. + - Make sure there are no jumpers on JP54 1-2 and JP21 4-5 + +- BBLED1: GPIO 0157. + - Connect GPIO 0156 to board LED5 by placing a wire from JP71-12 to J48-3. + - Make sure there are no jumpers on JP54 3-4 and JP21 16-17 + +- BBLED2: GPIO 0153. + - Connect GPIO 0153 to board LED7 by placing a wire from JP71-5 to JP146-5. + + JP146-5 is connected to MEC172x VCI_OUT1 without a jumper. Force VCI_OUT1 + high by forcing VCI_IN1 high: install jumper on J55 3-4 which pulls VCI_IN1 + to the VBAT rail via a 100K pull-up. Requires VBAT power rail is connected + to VTR or some other power source. + +- BBLED3: GPIO 0035. + - Connect GPIO 0035 to board LED7 by placing a wire from JP67-19 to JP146-1. + - Make sure there is no jumper on JP79 17-18. + + JP146-1 is connected to MEC172x VCI_OUT2 without a jumper. Force VCI_OUT2 + high by forcing VCI_IN2 high: install a jumper on J55 5-6 which pulls VCI_IN2 + to the VBAT rail via a 100K pull-up. Requires VBAT power rail is connected + to VTR or some other power source. + +mec15xxevb_assy6853 evaluation board +==================================== + +- BBLED0: GPIO 0156. + - Add jumper on JP41 1-2 to connect GPIO 0156 to board LED2 + - Remove jumper on JP31 13-14 + +- BBLED1: GPIO 0157. + - Add jumper on JP41 3-4 to connect GPIO 0157 to board LED3 + - Remove jumper on JP31 15-16 -EVB: mec172xevb_assy6906 -BBLED0 GPIO 0156. -Connect GPIO 0156 to board LED4 by placing a wire from JP71-11 to J47-3. -Make sure there are no jumpers on JP54 1-2 and JP21 4-5 - -BBLED1 GPIO 0157. -Connect GPIO 0156 to board LED5 by placing a wire from JP71-12 to J48-3. -Make sure there are no jumpers on JP54 3-4 and JP21 16-17 - -BBLED2 GPIO 0153. -Connect GPIO 0153 to board LED7 by placing a wire from JP71-5 to JP146-5. -JP146-5 is connected to MEC172x VCI_OUT1 without a jumper. Force VCI_OUT1 -high by forcing VCI_IN1 high: install jumper on J55 3-4 which pulls VCI_IN1 -to the VBAT rail via a 100K pull-up. Requires VBAT power rail is connected -to VTR or some other power source. - -BBLED3 GPIO 0035. -Connect GPIO 0035 to board LED7 by placing a wire from JP67-19 to JP146-1. -Make sure there is no jumper on JP79 17-18. -JP146-1 is connected to MEC172x VCI_OUT2 without a jumper. Force VCI_OUT2 -high by forcing VCI_IN2 high: install a jumper on J55 5-6 which pulls VCI_IN2 -to the VBAT rail via a 100K pull-up. Requires VBAT power rail is connected -to VTR or some other power source. - -EVB: mec15xxevb_assy6853 -BBLED0 GPIO 0156. -Add jumper on JP41 1-2 to connect GPIO 0156 to board LED2 -Remove jumper on JP31 13-14 - -BBLED1 GPIO 0157. -Add jumper on JP41 3-4 to connect GPIO 0157 to board LED3 -Remove jumper on JP31 15-16 - -BBLED2 GPIO 0153. -Add jumper on JP41 3-4 to connect GPIO 0153 to board LED4 -Remove jumper on JP31 17-18 +- BBLED2: GPIO 0153. + - Add jumper on JP41 3-4 to connect GPIO 0153 to board LED4 + - Remove jumper on JP31 17-18 Building and Running ******************** From f6a4217a882ebfa389894863666e6ae46968aa13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 10:04:01 +0200 Subject: [PATCH 0817/4498] doc: driver: samples: Update driver samples to use new Sphinx extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrated existing driver samples to use the new code-sample directive and role. Signed-off-by: Benjamin Cabé --- .../adafruit_itsybitsy_nrf52840/doc/index.rst | 2 +- .../doc/index.rst | 2 +- boards/posix/native_posix/doc/index.rst | 2 +- boards/shields/ftdi_vm800c/doc/index.rst | 2 +- boards/shields/x_nucleo_eeprma2/doc/index.rst | 2 +- boards/xtensa/yd_esp32/doc/index.rst | 2 +- .../peripherals/canbus/controller.rst | 2 +- doc/services/virtualization/ivshmem.rst | 2 +- .../boards/stm32/uart/single_wire/README.rst | 7 +++--- samples/drivers/adc/README.rst | 9 ++++---- samples/drivers/audio/dmic/README.rst | 11 +++++----- samples/drivers/auxdisplay/README.rst | 11 +++++----- samples/drivers/can/babbling/README.rst | 7 +++--- samples/drivers/can/counter/README.rst | 7 +++--- .../drivers/clock_control_litex/README.rst | 7 +++--- samples/drivers/counter/alarm/README.rst | 9 ++++---- .../drivers/counter/maxim_ds3231/README.rst | 7 +++--- samples/drivers/crypto/README.rst | 9 ++++---- samples/drivers/dac/README.rst | 9 ++++---- samples/drivers/display/README.rst | 7 +++--- samples/drivers/eeprom/README.rst | 9 ++++---- samples/drivers/espi/README.rst | 11 +++++----- .../drivers/ethernet/eth_ivshmem/README.rst | 7 +++--- samples/drivers/flash_shell/README.rst | 8 ++++--- .../drivers/fpga/fpga_controller/README.rst | 6 ++--- samples/drivers/ht16k33/README.rst | 9 ++++---- samples/drivers/i2s/echo/README.rst | 7 +++--- samples/drivers/ipm/ipm_esp32/README.rst | 9 ++++---- samples/drivers/ipm/ipm_imx/README.rst | 7 +++--- samples/drivers/ipm/ipm_ivshmem/README.rst | 7 ++++-- samples/drivers/ipm/ipm_mcux/README.rst | 7 +++--- .../drivers/ipm/ipm_mhu_dual_core/README.rst | 7 +++--- samples/drivers/jesd216/README.rst | 7 +++--- samples/drivers/kscan/README.rst | 7 +++--- samples/drivers/kscan_touch/README.rst | 7 +++--- samples/drivers/lcd_hd44780/README.rst | 7 +++--- samples/drivers/led_apa102/README.rst | 7 +++--- samples/drivers/led_is31fl3216a/README.rst | 10 +++++---- samples/drivers/led_is31fl3733/README.rst | 22 ++++++++++--------- samples/drivers/led_lp3943/README.rst | 7 +++--- samples/drivers/led_lp50xx/README.rst | 11 +++++----- samples/drivers/led_lp5562/README.rst | 7 +++--- samples/drivers/led_lp5569/README.rst | 7 +++--- samples/drivers/led_lpd8806/README.rst | 7 +++--- samples/drivers/led_pca9633/README.rst | 7 +++--- samples/drivers/led_pwm/README.rst | 7 +++--- .../drivers/led_sx1509b_intensity/README.rst | 7 +++--- samples/drivers/led_ws2812/README.rst | 10 ++++++--- samples/drivers/led_xec/README.rst | 7 +++--- samples/drivers/mbox/README.rst | 7 +++--- samples/drivers/memc/README.rst | 6 ++--- samples/drivers/misc/ft800/README.rst | 7 +++--- samples/drivers/misc/grove_display/README.rst | 7 +++--- samples/drivers/peci/README.rst | 7 +++--- samples/drivers/ps2/README.rst | 7 +++--- samples/drivers/smbus/README.rst | 4 ++-- samples/drivers/soc_flash_nrf/README.rst | 17 +++++++------- samples/drivers/spi_bitbang/README.rst | 7 +++--- samples/drivers/spi_flash/README.rst | 9 ++++---- samples/drivers/spi_flash_at45/README.rst | 9 ++++---- samples/drivers/uart/echo_bot/README.rst | 7 +++--- samples/drivers/uart/native_tty/README.rst | 7 +++--- .../ivshmem/doorbell/README.rst | 10 ++++++--- samples/drivers/w1/scanner/README.rst | 7 +++--- samples/drivers/watchdog/README.rst | 7 +++--- 65 files changed, 272 insertions(+), 207 deletions(-) diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst index 9096e8037c2..aa28cb501c3 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst +++ b/boards/arm/adafruit_itsybitsy_nrf52840/doc/index.rst @@ -123,7 +123,7 @@ The :zephyr:code-sample:`button` sample lets you test the buttons (switches) and The :zephyr:code-sample:`blinky` sample lets you test the red LED. The DotStar LED has been implemented as a SPI device and can be tested -with the :ref:`led_apa102_sample` sample application. +with the :zephyr:code-sample:`led-apa102` sample application. You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/doc/index.rst b/boards/arm/blueclover_plt_demo_v2_nrf52832/doc/index.rst index 517572c3d96..7a41d95e647 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/doc/index.rst +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/doc/index.rst @@ -122,7 +122,7 @@ Flashing Flashing Zephyr onto the ``blueclover_plt_demo_v2_nrf52832`` board requires an external programmer. The programmer is attached to the SWD header. -Build the Zephyr kernel and the :ref:`led_apa102_sample` sample application. +Build the Zephyr kernel and the :zephyr:code-sample:`led-apa102` sample application. .. zephyr-app-commands:: :zephyr-app: samples/drivers/led_apa102 diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 185c80c583b..73e3eb4110d 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -466,7 +466,7 @@ Interaction with serial ports can be configured in several different ways: Multiple instances of such uart drivers are supported. -The :ref:`sample-uart-native-tty` sample app provides a working example of the +The :zephyr:code-sample:`uart-native-tty` sample app provides a working example of the driver. This driver only supports poll mode. Interrupt and async mode are not supported. diff --git a/boards/shields/ftdi_vm800c/doc/index.rst b/boards/shields/ftdi_vm800c/doc/index.rst index 720ffee5aa1..df72ff21111 100644 --- a/boards/shields/ftdi_vm800c/doc/index.rst +++ b/boards/shields/ftdi_vm800c/doc/index.rst @@ -70,7 +70,7 @@ Sample usage You can try use FT800 with the Zephyr FT800 sample, which provides out-of-the-box configuration for FT800 Embedded Video engine. -See :ref:`display-ft800-sample` for details. +See :zephyr:code-sample:`ft800` sample for details. Build and Programming ********************* diff --git a/boards/shields/x_nucleo_eeprma2/doc/index.rst b/boards/shields/x_nucleo_eeprma2/doc/index.rst index ea5a330b514..248260b3657 100644 --- a/boards/shields/x_nucleo_eeprma2/doc/index.rst +++ b/boards/shields/x_nucleo_eeprma2/doc/index.rst @@ -50,7 +50,7 @@ and the X-NUCLEO-EEPRMA2 in particular, see these ST Microelectronics documents: Samples ******* -The :ref:`samples_eeprom` can be used to demonstrate the expansion boards +The :zephyr:code-sample:`eeprom` sample can be used to demonstrate the expansion boards functionality. Per default the shield sets an ``eeprom-0`` alias for the M24C02-FMC6TG EEPROM, which can be overwritten to use the other EEPROM devices instead. diff --git a/boards/xtensa/yd_esp32/doc/index.rst b/boards/xtensa/yd_esp32/doc/index.rst index 2696c2664b8..9ffd9f89c66 100644 --- a/boards/xtensa/yd_esp32/doc/index.rst +++ b/boards/xtensa/yd_esp32/doc/index.rst @@ -233,7 +233,7 @@ RGB LED ======= The board contains an addressable RGB LED (`XL-5050RGBC-WS2812B`_), driven by GPIO16. -Here is an example of how to test it using the :ref:`led_ws2812_sample` application. +Here is an example of how to test it using the :zephyr:code-sample:`led-ws2812` application. .. zephyr-app-commands:: :zephyr-app: samples/drivers/led_ws2812 diff --git a/doc/hardware/peripherals/canbus/controller.rst b/doc/hardware/peripherals/canbus/controller.rst index 82e004a6df1..182141c6045 100644 --- a/doc/hardware/peripherals/canbus/controller.rst +++ b/doc/hardware/peripherals/canbus/controller.rst @@ -332,7 +332,7 @@ Samples ******* We have two ready-to-build samples demonstrating use of the Zephyr CAN API: -:ref:`Zephyr CAN counter sample ` and +:zephyr:code-sample:`Zephyr CAN counter sample ` and :zephyr:code-sample:`SocketCAN sample `. diff --git a/doc/services/virtualization/ivshmem.rst b/doc/services/virtualization/ivshmem.rst index 673b083794c..4325c261fc0 100644 --- a/doc/services/virtualization/ivshmem.rst +++ b/doc/services/virtualization/ivshmem.rst @@ -46,7 +46,7 @@ Zephyr also supports ivshmem-v2: https://github.com/siemens/jailhouse/blob/master/Documentation/ivshmem-v2-specification.md This is primarily used for IPC in the Jailhouse hypervisor -(e.g. :ref:`eth_ivshmem_sample`). It is also possible to use ivshmem-v2 without +(e.g. :zephyr:code-sample:`eth-ivshmem`). It is also possible to use ivshmem-v2 without Jailhouse by building the Siemens fork of QEMU, and modifying the QEMU launch flags: https://github.com/siemens/qemu/tree/wip/ivshmem2 diff --git a/samples/boards/stm32/uart/single_wire/README.rst b/samples/boards/stm32/uart/single_wire/README.rst index e16143a663f..d5f0e1b592f 100644 --- a/samples/boards/stm32/uart/single_wire/README.rst +++ b/samples/boards/stm32/uart/single_wire/README.rst @@ -1,7 +1,8 @@ -.. _sample_uart_stm32_single_wire: +.. zephyr:code-sample:: uart-stm32-single-wire + :name: STM32 single-wire UART + :relevant-api: uart_interface -STM32 Single Wire UART -###################### + Use single-wire/half-duplex UART functionality of STM32 devices. Overview ******** diff --git a/samples/drivers/adc/README.rst b/samples/drivers/adc/README.rst index 4b701cc1711..b91867e2ff0 100644 --- a/samples/drivers/adc/README.rst +++ b/samples/drivers/adc/README.rst @@ -1,12 +1,13 @@ -.. _adc-sample: +.. zephyr:code-sample:: adc + :name: Analog-to-Digital Converter (ADC) + :relevant-api: adc_interface -Analog-to-Digital Converter (ADC) -################################# + Read analog inputs from ADC channels. Overview ******** -This sample demonstrates how to use the ADC driver API. +This sample demonstrates how to use the :ref:`ADC driver API `. Depending on the target board, it reads ADC samples from one or more channels and prints the readings on the console. If voltage of the used reference can diff --git a/samples/drivers/audio/dmic/README.rst b/samples/drivers/audio/dmic/README.rst index 70e2b5b8ba1..3e1463795c0 100644 --- a/samples/drivers/audio/dmic/README.rst +++ b/samples/drivers/audio/dmic/README.rst @@ -1,13 +1,14 @@ -.. _dmic_sample: +.. zephyr:code-sample:: dmic + :name: Digital Microphone (DMIC) + :relevant-api: audio_dmic_interface -DMIC Sample -########### + Perform PDM transfers using different configurations. Overview ******** -This is a very simple application intended to show how to use the Audio DMIC -API and also to be an aid in developing drivers to implement this API. +This is a very simple application intended to show how to use the :ref:`Audio DMIC +API ` and also to be an aid in developing drivers to implement this API. It performs two PDM transfers with different configurations (using one channel and two channels) but does not in any way process the received audio data. diff --git a/samples/drivers/auxdisplay/README.rst b/samples/drivers/auxdisplay/README.rst index 1bbe5750d6a..67bfb0e5677 100644 --- a/samples/drivers/auxdisplay/README.rst +++ b/samples/drivers/auxdisplay/README.rst @@ -1,13 +1,14 @@ -.. _auxdisplay-sample: +.. zephyr:code-sample:: auxdisplay + :name: Auxiliary display + :relevant-api: auxdisplay_interface -Auxiliary display sample -######################## + Output "Hello World" to an auxiliary display. Overview ******** -This sample shows how to use the auxiliary display drivers by outputting a -sample "Hello World" text to one. +This sample shows how to use the :ref:`auxiliary display driver ` +by outputting a sample "Hello World" text to one. Building and Running ******************** diff --git a/samples/drivers/can/babbling/README.rst b/samples/drivers/can/babbling/README.rst index 1f5e7128cc1..e80e03c8449 100644 --- a/samples/drivers/can/babbling/README.rst +++ b/samples/drivers/can/babbling/README.rst @@ -1,7 +1,8 @@ -.. _can-babbling-sample: +.. zephyr:code-sample:: can-babbling + :name: Controller Area Network (CAN) babbling node + :relevant-api: can_interface -Controller Area Network (CAN) Babbling Node -########################################### + Simulate a babbling CAN node. Overview ******** diff --git a/samples/drivers/can/counter/README.rst b/samples/drivers/can/counter/README.rst index 10a35ac480e..6addd47b714 100644 --- a/samples/drivers/can/counter/README.rst +++ b/samples/drivers/can/counter/README.rst @@ -1,7 +1,8 @@ -.. _can-counter-sample: +.. zephyr:code-sample:: can-counter + :name: Controller Area Network (CAN) counter + :relevant-api: can_interface -Controller Area Network (CAN) Counter -##################################### + Send and receive CAN messages. Overview ******** diff --git a/samples/drivers/clock_control_litex/README.rst b/samples/drivers/clock_control_litex/README.rst index a77002a0e2e..c2fa951bd38 100644 --- a/samples/drivers/clock_control_litex/README.rst +++ b/samples/drivers/clock_control_litex/README.rst @@ -1,7 +1,8 @@ -.. _clock_control_litex_sample: +.. zephyr:code-sample:: clock-control-litex + :name: LiteX clock control driver + :relevant-api: clock_control_interface -LiteX Clock Control Driver Sample -################################# + Use LiteX clock control driver to generate multiple clock signals. Introduction ************ diff --git a/samples/drivers/counter/alarm/README.rst b/samples/drivers/counter/alarm/README.rst index 9efffc81ae7..50ddfed2b13 100644 --- a/samples/drivers/counter/alarm/README.rst +++ b/samples/drivers/counter/alarm/README.rst @@ -1,11 +1,12 @@ -.. _alarm_sample: +.. zephyr:code-sample:: alarm + :name: Counter Alarm + :relevant-api: counter_interface -Counter Alarm Sample -##################### + Implement an alarm application using the counter API. Overview ******** -This sample provides an example of alarm application using counter API. +This sample provides an example of alarm application using :ref:`counter API `. It sets an alarm with an initial delay of 2 seconds. At each alarm expiry, a new alarm is configured with a delay multiplied by 2. diff --git a/samples/drivers/counter/maxim_ds3231/README.rst b/samples/drivers/counter/maxim_ds3231/README.rst index f8ad28a3f82..dbea079ef21 100644 --- a/samples/drivers/counter/maxim_ds3231/README.rst +++ b/samples/drivers/counter/maxim_ds3231/README.rst @@ -1,7 +1,8 @@ -.. _maxim-ds3231-sample: +.. zephyr:code-sample:: ds3231 + :name: DS3231 TCXO RTC + :relevant-api: counter_interface -Maxim DS3231 TCXO RTC Sample Application -######################################## + Interact with a DS3231 real-time clock using the counter API and dedicated driver API. Overview ******** diff --git a/samples/drivers/crypto/README.rst b/samples/drivers/crypto/README.rst index ee53a917182..02d86b35cec 100644 --- a/samples/drivers/crypto/README.rst +++ b/samples/drivers/crypto/README.rst @@ -1,11 +1,12 @@ -.. _crypto_sample: +.. zephyr:code-sample:: crypto + :name: Crypto + :relevant-api: crypto -Crypto -###### + Use the crypto APIs to perform various encryption/decryption operations. Overview ******** -An example to illustrate the usage of crypto APIs. +An example to illustrate the usage of :ref:`crypto APIs `. Building and Running ******************** diff --git a/samples/drivers/dac/README.rst b/samples/drivers/dac/README.rst index bfde230a1c6..16cbd170ce0 100644 --- a/samples/drivers/dac/README.rst +++ b/samples/drivers/dac/README.rst @@ -1,12 +1,13 @@ -.. _dac-sample: +.. zephyr:code-sample:: dac + :name: Digital-to-Analog Converter (DAC) + :relevant-api: dac_interface -Digital-to-Analog Converter (DAC) -################################# + Generate an analog sawtooth signal using the DAC driver API. Overview ******** -This sample demonstrates how to use the DAC driver API. +This sample demonstrates how to use the `DAC driver API `. Building and Running ******************** diff --git a/samples/drivers/display/README.rst b/samples/drivers/display/README.rst index de774646789..02ec21f3eda 100644 --- a/samples/drivers/display/README.rst +++ b/samples/drivers/display/README.rst @@ -1,7 +1,8 @@ -.. _display-sample: +.. zephyr:code-sample:: display + :name: Display + :relevant-api: display_interface -Display Sample -############## + Draw basic rectangles on a display device. Overview ******** diff --git a/samples/drivers/eeprom/README.rst b/samples/drivers/eeprom/README.rst index 98007767a5e..7202456e3f3 100644 --- a/samples/drivers/eeprom/README.rst +++ b/samples/drivers/eeprom/README.rst @@ -1,12 +1,13 @@ -.. _samples_eeprom: +.. zephyr:code-sample:: eeprom + :name: EEPROM + :relevant-api: eeprom_interface -EEPROM Sample -############# + Store a boot count value in EEPROM. Overview ******** -This sample demonstrates the EEPROM driver API in a simple boot counter +This sample demonstrates the `EEPROM driver API ` in a simple boot counter application. Building and Running diff --git a/samples/drivers/espi/README.rst b/samples/drivers/espi/README.rst index eef65b6741b..cbb6bb752b6 100644 --- a/samples/drivers/espi/README.rst +++ b/samples/drivers/espi/README.rst @@ -1,13 +1,14 @@ -.. _espi-sample: +.. zephyr:code-sample:: espi + :name: Enhanced Serial Peripheral Interface (eSPI) + :relevant-api: espi_interface spi_interface -Enhanced Serial Peripheral Interface -#################################### + Use eSPI to connect to a slave device and exchange virtual wire packets. Overview ******** -This sample demonstrates how to use the Enhanced Serial Peripheral Interface -(eSPI) API. +This sample demonstrates how to use the :ref:`Enhanced Serial Peripheral Interface +(eSPI) API `. It shows how to configure and select eSPI controller capabilities as part of a simple eSPI handshake that includes exchanging virtual wire packets. diff --git a/samples/drivers/ethernet/eth_ivshmem/README.rst b/samples/drivers/ethernet/eth_ivshmem/README.rst index 5757bbd6c83..03de6cd0e39 100644 --- a/samples/drivers/ethernet/eth_ivshmem/README.rst +++ b/samples/drivers/ethernet/eth_ivshmem/README.rst @@ -1,7 +1,8 @@ -.. _eth_ivshmem_sample: +.. zephyr:code-sample:: eth-ivshmem + :name: Inter-VM Shared Memory (ivshmem) Ethernet + :relevant-api: ivshmem ethernet -Inter-VM Shared Memory (ivshmem) Ethernet Sample Application -############################################################ + Communicate with another "cell" in the Jailhouse hypervisor using IVSHMEM Ethernet. Overview ******** diff --git a/samples/drivers/flash_shell/README.rst b/samples/drivers/flash_shell/README.rst index 60623450a36..1c8513bf2c0 100644 --- a/samples/drivers/flash_shell/README.rst +++ b/samples/drivers/flash_shell/README.rst @@ -1,10 +1,12 @@ -.. _samples_flash_shell: +.. zephyr:code-sample:: flash-shell + :name: Flash shell + :relevant-api: flash_interface -Flash Shell Sample -################## + Explore a flash device using shell commands. Overview ******** + This is a simple shell module that allows arbitrary boards with flash driver support to explore the flash device. diff --git a/samples/drivers/fpga/fpga_controller/README.rst b/samples/drivers/fpga/fpga_controller/README.rst index 82b4e68abcc..d971c138541 100644 --- a/samples/drivers/fpga/fpga_controller/README.rst +++ b/samples/drivers/fpga/fpga_controller/README.rst @@ -1,7 +1,7 @@ -.. _samples_fpga_controller: +.. zephyr:code-sample:: fpga-controller + :name: FPGA Controller -Zephyr FPGA controller -###################### + Load a bitstream into an FPGA and perform basic operations on it. Overview ******** diff --git a/samples/drivers/ht16k33/README.rst b/samples/drivers/ht16k33/README.rst index 01b899d5ff5..06fcc50a697 100644 --- a/samples/drivers/ht16k33/README.rst +++ b/samples/drivers/ht16k33/README.rst @@ -1,7 +1,8 @@ -.. _ht16k33: +.. zephyr:code-sample:: ht16k33 + :name: HT16K33 LED driver with keyscan + :relevant-api: led_interface kscan_interface -HT16K33 LED driver with keyscan -############################### + Control up to 128 LEDs connected to an HT16K33 LED driver and log keyscan events. Overview ******** @@ -23,7 +24,7 @@ Building and Running ******************** Build the application for the :ref:`nrf52840dk_nrf52840` board, and -connect a HT16K33 LED driver at address 0x70 on the I2C-0 bus. +connect an HT16K33 LED driver at address 0x70 on the I2C-0 bus. .. zephyr-app-commands:: :zephyr-app: samples/drivers/ht16k33 diff --git a/samples/drivers/i2s/echo/README.rst b/samples/drivers/i2s/echo/README.rst index 40dfecca1c4..8f7838d6298 100644 --- a/samples/drivers/i2s/echo/README.rst +++ b/samples/drivers/i2s/echo/README.rst @@ -1,7 +1,8 @@ -.. _i2s_echo_sample: +.. zephyr:code-sample:: i2s-echo + :name: I2S echo + :relevant-api: i2s_interface -I2S Echo Sample -############### + Process an audio stream to add an echo effect. Overview ******** diff --git a/samples/drivers/ipm/ipm_esp32/README.rst b/samples/drivers/ipm/ipm_esp32/README.rst index f3501e15910..3219ee7b307 100644 --- a/samples/drivers/ipm/ipm_esp32/README.rst +++ b/samples/drivers/ipm/ipm_esp32/README.rst @@ -1,7 +1,8 @@ -.. _ipm_esp32: +.. zephyr:code-sample:: ipm-esp32 + :name: IPM on ESP32 + :relevant-api: ipm_interface -ESP32 Soft-IPM example -###################### + Implement inter-processor mailbox (IPM) between ESP32 APP and PRO CPUs. Overview ******** @@ -16,7 +17,7 @@ ESP32 intercore messaging has up two four channels, the 0 and 1 are reserved for BT and WIFI messages, and channels 2 and 3 is free to any application, each channel supports up to 64 bytes of data per message, so high level protocol is responsible to fragment larger -messages in chunks of 64bytes. +messages in chunks of 64 bytes. Building and Running the Zephyr Code ************************************ diff --git a/samples/drivers/ipm/ipm_imx/README.rst b/samples/drivers/ipm/ipm_imx/README.rst index 3a356112d31..570f7115362 100644 --- a/samples/drivers/ipm/ipm_imx/README.rst +++ b/samples/drivers/ipm/ipm_imx/README.rst @@ -1,7 +1,8 @@ -.. _ipm_imx: +.. zephyr:code-sample:: ipm-imx + :name: IPM on NXP i.MX + :relevant-api: ipm_interface -i.MX IPM example -################ + Implement inter-processor mailbox (IPM) on i.MX SoCs containing a Messaging Unit peripheral. Overview ******** diff --git a/samples/drivers/ipm/ipm_ivshmem/README.rst b/samples/drivers/ipm/ipm_ivshmem/README.rst index 174fce788e7..80fe914d5da 100644 --- a/samples/drivers/ipm/ipm_ivshmem/README.rst +++ b/samples/drivers/ipm/ipm_ivshmem/README.rst @@ -1,5 +1,8 @@ -IPM over IVSHMEM Driver sample -################################ +.. zephyr:code-sample:: ipm-ivshmem + :name: IPM over IVSHMEM + :relevant-api: ipm_interface + + Implement inter-processor mailbox (IPM) over IVSHMEM (Inter-VM shared memory) Prerequisites ************* diff --git a/samples/drivers/ipm/ipm_mcux/README.rst b/samples/drivers/ipm/ipm_mcux/README.rst index d8dfcc65aea..1fcd1e9818e 100644 --- a/samples/drivers/ipm/ipm_mcux/README.rst +++ b/samples/drivers/ipm/ipm_mcux/README.rst @@ -1,7 +1,8 @@ -.. _ipm-mcux-sample: +.. zephyr:code-sample:: ipm-mcux + :name: IPM on NXP LPC + :relevant-api: ipm_interface -Sample mailbox application -########################## + Implement inter-processor mailbox (IPM) on NXP LPC family. Overview ******** diff --git a/samples/drivers/ipm/ipm_mhu_dual_core/README.rst b/samples/drivers/ipm/ipm_mhu_dual_core/README.rst index b6e212efd25..fc6414d83ff 100644 --- a/samples/drivers/ipm/ipm_mhu_dual_core/README.rst +++ b/samples/drivers/ipm/ipm_mhu_dual_core/README.rst @@ -1,7 +1,8 @@ -.. _ipm_mhu_dual_core: +.. zephyr:code-sample:: ipm-mhu-dual-core + :name: IPM with ARM MHU + :relevant-api: ipm_interface -MHU Dual Core -############# + Implement inter-processor mailbox (IPM) using an MHU (Message Handling Unit) Overview ******** diff --git a/samples/drivers/jesd216/README.rst b/samples/drivers/jesd216/README.rst index 8aaa07a8283..71887480a58 100644 --- a/samples/drivers/jesd216/README.rst +++ b/samples/drivers/jesd216/README.rst @@ -1,7 +1,8 @@ -.. _jesd216-sample: +.. zephyr:code-sample:: jesd216 + :name: JESD216 flash + :relevant-api: flash_interface -JESD216 Sample -############## + Use the JESD216 flash API to extract information from a compatible serial memory device. Overview ******** diff --git a/samples/drivers/kscan/README.rst b/samples/drivers/kscan/README.rst index 2bbf5b04ad5..e2d2d129b6b 100644 --- a/samples/drivers/kscan/README.rst +++ b/samples/drivers/kscan/README.rst @@ -1,7 +1,8 @@ -.. _kscan-sample: +.. zephyr:code-sample:: kscan + :name: KSCAN + :relevant-api: kscan_interface timer_apis -KSCAN Interface -#################################### + Use the KSCAN API to read key presses and releases on a keyboard matrix. Overview ******** diff --git a/samples/drivers/kscan_touch/README.rst b/samples/drivers/kscan_touch/README.rst index 80fb2f273cd..52ad2aa7095 100644 --- a/samples/drivers/kscan_touch/README.rst +++ b/samples/drivers/kscan_touch/README.rst @@ -1,7 +1,8 @@ -.. _kscan-touch-sample: +.. zephyr:code-sample:: kscan-touch + :name: KSCAN touch panel + :relevant-api: kscan_interface -KSCAN touch panel example -#################################### + Use the KSCAN API to interface with a touch panel. Overview ******** diff --git a/samples/drivers/lcd_hd44780/README.rst b/samples/drivers/lcd_hd44780/README.rst index 44b27251e9c..c4d729ca6df 100644 --- a/samples/drivers/lcd_hd44780/README.rst +++ b/samples/drivers/lcd_hd44780/README.rst @@ -1,7 +1,8 @@ -.. _samples_lcd_hd44780: +.. zephyr:code-sample:: lcd-hd44780 + :name: HD44780 LCD controller + :relevant-api: gpio_interface -LCD HD44780 driver sample -######################### + Control an HD44780-based LCD display using GPIO pins. Overview ******** diff --git a/samples/drivers/led_apa102/README.rst b/samples/drivers/led_apa102/README.rst index 9def8376dcc..2ea03328238 100644 --- a/samples/drivers/led_apa102/README.rst +++ b/samples/drivers/led_apa102/README.rst @@ -1,7 +1,8 @@ -.. _led_apa102_sample: +.. zephyr:code-sample:: led-apa102 + :name: APA102 LED strip + :relevant-api: led_strip_interface -APA102 Sample Application -######################### + Control an LED strip using an APA102, Adafruit DotStar, or compatible driver chip. Overview ******** diff --git a/samples/drivers/led_is31fl3216a/README.rst b/samples/drivers/led_is31fl3216a/README.rst index fb3c2353dd5..fa527d09579 100644 --- a/samples/drivers/led_is31fl3216a/README.rst +++ b/samples/drivers/led_is31fl3216a/README.rst @@ -1,7 +1,8 @@ -.. _is31fl3216a: +.. zephyr:code-sample:: is31fl3216a + :name: IS31FL3216A LED + :relevant-api: led_interface -is31fl3216a: 16 channels PWD LEDs controller -############################################ + Control up to 16 PWM LEDs connected to an IS31FL3216A driver chip. Overview ******** @@ -12,12 +13,13 @@ Each LED is gradually pulsed until it reach 100% of luminosity and gradually turned off again. Once each LED was pulsed, multiple LEDs are pulse simultaneously using the -``write_channels`` LED API. +:c:func:`led_write_channels` API. Test pattern ============ For each LED: + - Increase the luminosity until 100% is reached - Decrease the luminosity until completely turned off diff --git a/samples/drivers/led_is31fl3733/README.rst b/samples/drivers/led_is31fl3733/README.rst index 0894c7ef9e8..8f0f30e61cf 100644 --- a/samples/drivers/led_is31fl3733/README.rst +++ b/samples/drivers/led_is31fl3733/README.rst @@ -1,7 +1,8 @@ -.. _is31fl3733: +.. zephyr:code-sample:: is31fl3733 + :name: IS31FL3733 LED Matrix + :relevant-api: led_interface -IS31FL3733 LED Matrix Driver Demo Application -############################################# + Control a matrix of up to 192 LEDs connected to an IS31FL3733 driver chip. Overview ******** @@ -9,19 +10,20 @@ Overview This sample controls a matrix of up to 192 LEDs. The sample performs the following test steps in an infinite loop: -- Set all LEDs to full brightness with `led_write_channels` API -- Disable upper quadrant of LED array with `led_write_channels` API -- Dim each LED in sequence using `led_set_brightness` API -- Toggle each LED in sequency using `led_on` and `led_off` APIs -- Toggle between low or high current limit using `is31fl3733_current_limit` +- Set all LEDs to full brightness with :c:func:`led_write_channels` API +- Disable upper quadrant of LED array with :c:func:`led_write_channels` API +- Dim each LED in sequence using :c:func:`led_set_brightness` API +- Toggle each LED in sequency using :c:func:`led_on` and :c:func:`led_of` APIs +- Toggle between low or high current limit using :c:func:`is31fl3733_current_limit` API, and repeat the above tests Sample Configuration ==================== The number of LEDs can be limited using the following sample specific Kconfigs: -- `CONFIG_LED_ROW_COUNT` -- `CONFIG_LED_COLUMN_COUNT` + +- :kconfig:option:`CONFIG_LED_ROW_COUNT` +- :kconfig:option:`CONFIG_LED_COLUMN_COUNT` Building and Running ******************** diff --git a/samples/drivers/led_lp3943/README.rst b/samples/drivers/led_lp3943/README.rst index c092a9dfdf0..cb1905d2c14 100644 --- a/samples/drivers/led_lp3943/README.rst +++ b/samples/drivers/led_lp3943/README.rst @@ -1,7 +1,8 @@ -.. _lp3943: +.. zephyr:code-sample:: lp3943 + :name: LP3943 RGBW LED + :relevant-api: led_interface -LP3943: 16-Channel RGB, White-LED Driver -######################################## + Control up to 16 RGBW LEDs connected to an LP3943 driver chip. Overview ******** diff --git a/samples/drivers/led_lp50xx/README.rst b/samples/drivers/led_lp50xx/README.rst index afad1ee0ea5..23d4fcaa3ff 100644 --- a/samples/drivers/led_lp50xx/README.rst +++ b/samples/drivers/led_lp50xx/README.rst @@ -1,7 +1,8 @@ -.. _lp50xx: +.. zephyr:code-sample:: lp50xx + :name: LP50XX RGB LED + :relevant-api: led_interface -LP50XX: up to 12 RGB channels -############################### + Control up to 12 RGB LEDs connected to an LP50xx driver chip. Overview ******** @@ -11,8 +12,8 @@ This sample controls up to 12 LEDs connected to a LP50xx driver. First, for each LED information is retrieved using the led_get_info syscall and printed in the log messages. Next, from an infinite loop, a test pattern (described below) is applied to all the LEDs simultaneously (using the -led_write_channels syscall) and then to each LED one by one (using the -led_set_{brightness,color} syscalls). +:c:func:`led_write_channels` syscall) and then to each LED one by one (using the +:c:func:`led_set_brightness` and :c:func:`led_set_color` syscalls). Test pattern ============ diff --git a/samples/drivers/led_lp5562/README.rst b/samples/drivers/led_lp5562/README.rst index 9f141507612..4848455ab32 100644 --- a/samples/drivers/led_lp5562/README.rst +++ b/samples/drivers/led_lp5562/README.rst @@ -1,7 +1,8 @@ -.. _lp5562: +.. zephyr:code-sample:: lp5562 + :name: LP5562 RGB LED + :relevant-api: led_interface -LP5562: 4-Channel RGB -###################### + Control 4 RGB LEDs connected to an LP5562 driver chip. Overview ******** diff --git a/samples/drivers/led_lp5569/README.rst b/samples/drivers/led_lp5569/README.rst index c7679972f1d..f9d0f5febd9 100644 --- a/samples/drivers/led_lp5569/README.rst +++ b/samples/drivers/led_lp5569/README.rst @@ -1,7 +1,8 @@ -.. _lp5569: +.. zephyr:code-sample:: lp5569 + :name: LP5569 9-channel LED controller + :relevant-api: led_interface -LP5569: 9-Channel LED Controller -################################ + Control 9 LEDs connected to an LP5569 driver chip. Overview ******** diff --git a/samples/drivers/led_lpd8806/README.rst b/samples/drivers/led_lpd8806/README.rst index 095638c74ad..570f6498fc7 100644 --- a/samples/drivers/led_lpd8806/README.rst +++ b/samples/drivers/led_lpd8806/README.rst @@ -1,7 +1,8 @@ -.. _led_lpd8806_sample: +.. zephyr:code-sample:: led-lpd8806 + :name: LPD880x LED strip + :relevant-api: led_strip_interface -LPD880x Sample Application -########################## + Control an LED strip using an LPD880x-compatible driver chip. Overview ******** diff --git a/samples/drivers/led_pca9633/README.rst b/samples/drivers/led_pca9633/README.rst index 32e5ed14db9..ac461961e03 100644 --- a/samples/drivers/led_pca9633/README.rst +++ b/samples/drivers/led_pca9633/README.rst @@ -1,7 +1,8 @@ -.. _pca9633: +.. zephyr:code-sample:: pca9633 + :name: PCA9633 LED + :relevant-api: led_interface -PCA9633: 4-Channel RGB -###################### + Control 4 LEDs connected to a PCA9633 driver chip. Overview ******** diff --git a/samples/drivers/led_pwm/README.rst b/samples/drivers/led_pwm/README.rst index 54ae34f4d64..62e830fcae1 100644 --- a/samples/drivers/led_pwm/README.rst +++ b/samples/drivers/led_pwm/README.rst @@ -1,7 +1,8 @@ -.. _led_pwm: +.. zephyr:code-sample:: led-pwm + :name: LED PWM + :relevant-api: led_interface -LED PWM sample application -########################## + Control PWM LEDs using the LED API. Overview ******** diff --git a/samples/drivers/led_sx1509b_intensity/README.rst b/samples/drivers/led_sx1509b_intensity/README.rst index ce715fab878..2fdeee737ac 100644 --- a/samples/drivers/led_sx1509b_intensity/README.rst +++ b/samples/drivers/led_sx1509b_intensity/README.rst @@ -1,7 +1,8 @@ -.. _sx1509b_intensity: +.. zephyr:code-sample:: sx1509b + :name: SX1509B RGB LED + :relevant-api: led_interface -SX1509B LED Intensity -###################### + Control an RGB LED connected to an SX1509B driver chip. Overview ******** diff --git a/samples/drivers/led_ws2812/README.rst b/samples/drivers/led_ws2812/README.rst index 4d07c825bf3..6c1c26bd843 100644 --- a/samples/drivers/led_ws2812/README.rst +++ b/samples/drivers/led_ws2812/README.rst @@ -1,7 +1,8 @@ -.. _led_ws2812_sample: +.. zephyr:code-sample:: led-ws2812 + :name: WS2812 LED strip + :relevant-api: led_strip_interface -WS2812 Sample Application -######################### + Control an LED strip using a WS2812 (or compatible) driver chip. Overview ******** @@ -96,9 +97,11 @@ Supported drivers This sample uses different drivers depending on the selected board: I2S driver: + - thingy52_nrf52832 SPI driver: + - mimxrt1050_evk - mimxrt1050_evk_qspi - nrf52dk_nrf52832 @@ -108,6 +111,7 @@ SPI driver: - nucleo_l476rg GPIO driver (cortex-M0 only): + - bbc_microbit - nrf51dk_nrf51422 diff --git a/samples/drivers/led_xec/README.rst b/samples/drivers/led_xec/README.rst index 072ef1abb80..12c951c7ad3 100644 --- a/samples/drivers/led_xec/README.rst +++ b/samples/drivers/led_xec/README.rst @@ -1,7 +1,8 @@ -.. _led: +.. zephyr:code-sample:: led-xec + :name: Breathing-blinking LED (BBLED) + :relevant-api: led_interface -LED sample application -########################## + Control a BBLED (Breathing-Blinking LED) using Microchip XEC driver. Overview ******** diff --git a/samples/drivers/mbox/README.rst b/samples/drivers/mbox/README.rst index a05aa24aa00..35c421335f9 100644 --- a/samples/drivers/mbox/README.rst +++ b/samples/drivers/mbox/README.rst @@ -1,7 +1,8 @@ -.. _mbox-sample: +.. zephyr:code-sample:: mbox + :name: MBOX + :relevant-api: mbox_interface -MBOX Interface -############## + Perform inter-processor mailbox communication using the MBOX API. Overview ******** diff --git a/samples/drivers/memc/README.rst b/samples/drivers/memc/README.rst index 05da1c094d5..814b7e949fc 100644 --- a/samples/drivers/memc/README.rst +++ b/samples/drivers/memc/README.rst @@ -1,7 +1,7 @@ -.. _memc: +.. zephyr:code-sample:: memc + :name: Memory controller (MEMC) driver -MEMC Driver Sample -################## + Access memory-mapped external RAM Overview ******** diff --git a/samples/drivers/misc/ft800/README.rst b/samples/drivers/misc/ft800/README.rst index 81c4a3ad764..5c72c3641e6 100644 --- a/samples/drivers/misc/ft800/README.rst +++ b/samples/drivers/misc/ft800/README.rst @@ -1,7 +1,8 @@ -.. _display-ft800-sample: +.. zephyr:code-sample:: ft800 + :name: FT800 + :relevant-api: ft8xx_interface -FT800 -##### + Display various shapes and text using FT800 Embedded Video Engine. Overview ******** diff --git a/samples/drivers/misc/grove_display/README.rst b/samples/drivers/misc/grove_display/README.rst index a1838d0ec5c..cd288b5b76f 100644 --- a/samples/drivers/misc/grove_display/README.rst +++ b/samples/drivers/misc/grove_display/README.rst @@ -1,7 +1,8 @@ -.. _grove-lcd-sample: +.. zephyr:code-sample:: grove-lcd + :name: Grove LCD + :relevant-api: grove_display -Grove LCD -######### + Display an incrementing counter and change the backlight color. Overview ******** diff --git a/samples/drivers/peci/README.rst b/samples/drivers/peci/README.rst index aa361dc7611..98c11d43a25 100644 --- a/samples/drivers/peci/README.rst +++ b/samples/drivers/peci/README.rst @@ -1,7 +1,8 @@ -.. _peci-sample: +.. zephyr:code-sample:: peci + :name: PECI interface + :relevant-api: peci_interface -PECI Interface -#################################### + Monitor CPU temperature using PECI. Overview ******** diff --git a/samples/drivers/ps2/README.rst b/samples/drivers/ps2/README.rst index f18e1a5e6f9..d37fbde392e 100644 --- a/samples/drivers/ps2/README.rst +++ b/samples/drivers/ps2/README.rst @@ -1,7 +1,8 @@ -.. _ps2-sample: +.. zephyr:code-sample:: ps2 + :name: PS/2 interface + :relevant-api: ps2_interface -PS/2 Interface -#################################### + Communicate with a PS/2 mouse. Overview ******** diff --git a/samples/drivers/smbus/README.rst b/samples/drivers/smbus/README.rst index 31a753c8542..cd2e7ed90d1 100644 --- a/samples/drivers/smbus/README.rst +++ b/samples/drivers/smbus/README.rst @@ -2,7 +2,7 @@ :name: SMBus shell :relevant-api: smbus_interface - SMBus Shell Sample + Interact with SMBus peripherals using shell commands. Overview ******** @@ -33,7 +33,7 @@ Output from console when application started:: Start SMBUS shell sample qemu_x86_64 uart:~$ -List avaibalbe SMBus shell commands with:: +List available SMBus shell commands with:: uart:~$ smbus smbus - smbus commands diff --git a/samples/drivers/soc_flash_nrf/README.rst b/samples/drivers/soc_flash_nrf/README.rst index df97e4b65cc..496688e8b65 100644 --- a/samples/drivers/soc_flash_nrf/README.rst +++ b/samples/drivers/soc_flash_nrf/README.rst @@ -1,18 +1,19 @@ -.. _soc-flash-nrf-sample: +.. zephyr:code-sample:: soc-flash-nrf + :name: nRF SoC flash + :relevant-api: flash_interface flash_area_api -nRF SoC flash sample -#################### + Use the flash API to interact with the SoC flash. Overview ******** -This sample demonstrates using the flash API on a SoC internal flash. -The sample uses :ref:`flash_map_api` to obtain device for flash, using -DTS node label, and then directly uses :ref:`flash_api` to perform +This sample demonstrates using the :ref:`Flash API ` on an SoC internal flash. +The sample uses :ref:`Flash map API ` to obtain device for flash, using +DTS node label, and then directly uses :ref:`Flash API ` to perform flash operations. -Within the sample user may observe how read/write/erase operations -are performed on a device and how to first check whether device is +Within the sample, user may observe how read/write/erase operations +are performed on a device, and how to first check whether device is ready for operation. Building and Running diff --git a/samples/drivers/spi_bitbang/README.rst b/samples/drivers/spi_bitbang/README.rst index 6b629c99118..a8ff597f002 100644 --- a/samples/drivers/spi_bitbang/README.rst +++ b/samples/drivers/spi_bitbang/README.rst @@ -1,7 +1,8 @@ -.. _spi-bitbang-sample: +.. zephyr:code-sample:: spi-bitbang + :name: SPI bitbang + :relevant-api: spi_interface -SPI-Bitbang Sample -#################### + Use the bitbang SPI driver for communicating with a slave. Overview ******** diff --git a/samples/drivers/spi_flash/README.rst b/samples/drivers/spi_flash/README.rst index e459559a418..f7bbb0d792b 100644 --- a/samples/drivers/spi_flash/README.rst +++ b/samples/drivers/spi_flash/README.rst @@ -1,12 +1,13 @@ -.. _spi-nor-sample: +.. zephyr:code-sample:: spi-nor + :name: JEDEC SPI-NOR flash + :relevant-api: flash_interface -JEDEC SPI-NOR Sample -#################### + Use the flash API to interact with an SPI NOR serial flash memory device. Overview ******** -This sample demonstrates using the flash API on a SPI NOR serial flash +This sample demonstrates using the `flash API ` on a SPI NOR serial flash memory device. While trivial it is an example of direct access and allows confirmation that the flash is working and that automatic power savings is correctly implemented. diff --git a/samples/drivers/spi_flash_at45/README.rst b/samples/drivers/spi_flash_at45/README.rst index c8d5b60c91e..467edb2a4d2 100644 --- a/samples/drivers/spi_flash_at45/README.rst +++ b/samples/drivers/spi_flash_at45/README.rst @@ -1,7 +1,8 @@ -.. _spi_flash_at45_sample: +.. zephyr:code-sample:: spi-flash-at45 + :name: AT45 DataFlash driver + :relevant-api: flash_interface -AT45 DataFlash driver sample -############################# + Use the AT45 family DataFlash driver to interact with the flash memory over SPI. Overview ******** @@ -23,7 +24,7 @@ enables the flash page layout API which allow show the flash information. In the default configuration, the AT45 flash driver is configured to use the Read-Modify-Write functionality of DataFlash chips and does not perform page erasing, as it is not needed in this case. This can be modified by -simply disabling the SPI_FLASH_AT45_USE_READ_MODIFY_WRITE option. +simply disabling the :kconfig:option:`CONFIG_SPI_FLASH_AT45_USE_READ_MODIFY_WRITE` option. Requirements ************ diff --git a/samples/drivers/uart/echo_bot/README.rst b/samples/drivers/uart/echo_bot/README.rst index f46f39b99ba..8f08af803d4 100644 --- a/samples/drivers/uart/echo_bot/README.rst +++ b/samples/drivers/uart/echo_bot/README.rst @@ -1,7 +1,8 @@ -.. _uart_sample: +.. zephyr:code-sample:: uart + :name: UART echo + :relevant-api: uart_interface -UART Driver Sample -################## + Read data from the console and echo it back. Overview ******** diff --git a/samples/drivers/uart/native_tty/README.rst b/samples/drivers/uart/native_tty/README.rst index deacfde80d3..8571ad1c538 100644 --- a/samples/drivers/uart/native_tty/README.rst +++ b/samples/drivers/uart/native_tty/README.rst @@ -1,7 +1,8 @@ -.. _sample-uart-native-tty: +.. zephyr:code-sample:: uart-native-tty + :name: Native TTY UART + :relevant-api: uart_interface -Native TTY UART -############### + Use native TTY driver to send and receive data between two UART-to-USB bridge dongles. Overview ******** diff --git a/samples/drivers/virtualization/ivshmem/doorbell/README.rst b/samples/drivers/virtualization/ivshmem/doorbell/README.rst index 001bdf3e545..d5091323b2c 100644 --- a/samples/drivers/virtualization/ivshmem/doorbell/README.rst +++ b/samples/drivers/virtualization/ivshmem/doorbell/README.rst @@ -1,5 +1,9 @@ -IVSHMEM Doorbell Sample Application -################################### +.. zephyr:code-sample:: ivshmem-doorbell + :name: IVSHMEM doorbell + :relevant-api: ivshmem + + Use Inter-VM Shared Memory to exchange messages between two processes running on different + operating systems. Overview ******** @@ -62,7 +66,7 @@ How to .. note:: The ivshmem shared memory can be manipulated to crash QEMU and bring down - Zephyr. Check `ivshmem_doorbell_sample_security`_ for details. + Zephyr. Check :ref:`ivshmem_doorbell_sample_security` section for more details. .. note:: diff --git a/samples/drivers/w1/scanner/README.rst b/samples/drivers/w1/scanner/README.rst index fa8e8563dfa..325b02f528c 100644 --- a/samples/drivers/w1/scanner/README.rst +++ b/samples/drivers/w1/scanner/README.rst @@ -1,7 +1,8 @@ -.. _w1_scanner_sample: +.. zephyr:code-sample:: w1-scanner + :name: 1-Wire scanner + :relevant-api: w1_interface -1-Wire Scanner Sample -##################### + Scan for 1-Wire devices and print their family ID and serial number. Overview ******** diff --git a/samples/drivers/watchdog/README.rst b/samples/drivers/watchdog/README.rst index 54f95cb032b..619ddf78952 100644 --- a/samples/drivers/watchdog/README.rst +++ b/samples/drivers/watchdog/README.rst @@ -1,7 +1,8 @@ -.. _watchdog-sample: +.. zephyr:code-sample:: watchdog + :name: Watchdog + :relevant-api: watchdog_interface -Watchdog Sample -############### + Use the watchdog driver API to reset the board when it gets stuck in an infinite loop. Overview ******** From 2147eefa1576c4771749dbb05738f9dacae8c9d4 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 11 Sep 2023 17:10:16 +0200 Subject: [PATCH 0818/4498] Bluetooth: PACS: Remove CONFIG_BT_PACS_{SNK,SRC}_CONTEXT The Kconfig option was never used by the stack and should thus be removed. Signed-off-by: Emil Gydesen --- samples/bluetooth/hap_ha/prj.conf | 5 ---- samples/bluetooth/hap_ha/src/main.c | 7 ++--- samples/bluetooth/tmap_peripheral/prj.conf | 5 ---- subsys/bluetooth/audio/Kconfig.pacs | 35 ---------------------- 4 files changed, 2 insertions(+), 50 deletions(-) diff --git a/samples/bluetooth/hap_ha/prj.conf b/samples/bluetooth/hap_ha/prj.conf index 179b5a5f4d7..ca019bbafb4 100644 --- a/samples/bluetooth/hap_ha/prj.conf +++ b/samples/bluetooth/hap_ha/prj.conf @@ -21,11 +21,6 @@ CONFIG_BT_ASCS_ASE_SRC_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=2 -# Sink Contexts Supported: Unspecified, Conversational, Media, Live -CONFIG_BT_PACS_SNK_CONTEXT=0x0047 -# Source Contexts Supported: Unspecified, Conversational -CONFIG_BT_PACS_SRC_CONTEXT=0x0003 - CONFIG_BT_PAC_SNK_LOC=y CONFIG_BT_PAC_SRC_LOC=y diff --git a/samples/bluetooth/hap_ha/src/main.c b/samples/bluetooth/hap_ha/src/main.c index 1ce47508c36..9c57bbefbcb 100644 --- a/samples/bluetooth/hap_ha/src/main.c +++ b/samples/bluetooth/hap_ha/src/main.c @@ -24,11 +24,8 @@ BT_AUDIO_CONTEXT_TYPE_MEDIA | \ BT_AUDIO_CONTEXT_TYPE_LIVE) -#define AVAILABLE_SINK_CONTEXT CONFIG_BT_PACS_SNK_CONTEXT -#define AVAILABLE_SOURCE_CONTEXT CONFIG_BT_PACS_SRC_CONTEXT - -BUILD_ASSERT((CONFIG_BT_PACS_SNK_CONTEXT & MANDATORY_SINK_CONTEXT) == MANDATORY_SINK_CONTEXT, - "Need to support mandatory Supported_Sink_Contexts"); +#define AVAILABLE_SINK_CONTEXT MANDATORY_SINK_CONTEXT +#define AVAILABLE_SOURCE_CONTEXT MANDATORY_SINK_CONTEXT static uint8_t unicast_server_addata[] = { BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */ diff --git a/samples/bluetooth/tmap_peripheral/prj.conf b/samples/bluetooth/tmap_peripheral/prj.conf index 756f86db3ab..6b7d7d390a8 100644 --- a/samples/bluetooth/tmap_peripheral/prj.conf +++ b/samples/bluetooth/tmap_peripheral/prj.conf @@ -32,11 +32,6 @@ CONFIG_BT_ASCS_ASE_SRC_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=2 -# Sink Contexts Supported: Unspecified, Conversational, Media -CONFIG_BT_PACS_SNK_CONTEXT=0x0007 -# Source Contexts Supported: Unspecified, Conversational, Media -CONFIG_BT_PACS_SRC_CONTEXT=0x0007 - # Sink PAC Location Support CONFIG_BT_PAC_SNK_LOC=y # Source PAC Location Support diff --git a/subsys/bluetooth/audio/Kconfig.pacs b/subsys/bluetooth/audio/Kconfig.pacs index 112475ea99c..fba32e709fd 100644 --- a/subsys/bluetooth/audio/Kconfig.pacs +++ b/subsys/bluetooth/audio/Kconfig.pacs @@ -13,24 +13,6 @@ config BT_PAC_SNK This option enables support for Sink Published Audio Capabilities. if BT_PAC_SNK -config BT_PACS_SNK_CONTEXT - hex "Supported Sink Contexts" - default 0x03ff - range 0x0000 0x03ff - help - The Supported Sink Contexts exposes the server’s support for - reception of audio data associated with specific Context Types: - 0x0001: Unspecified - 0x0002: Conversational - 0x0004: Media - 0x0008: Instructional - 0x0010: AttentionSeeking - 0x0020: ImmediateAlert - 0x0040: ManMachine - 0x0080: EmergencyAlert - 0x0100: Ringtone - 0x0200: TV - config BT_PAC_SNK_NOTIFIABLE bool "Sink PAC Notifiable Support" help @@ -65,23 +47,6 @@ config BT_PAC_SRC This option enables support for Source Published Audio Capabilities. if BT_PAC_SRC -config BT_PACS_SRC_CONTEXT - hex "Supported Source Contexts" - default 0x03ff - range 0x0000 0x03ff - help - The Supported Source Contexts exposes the server’s support for - transmission of audio data associated with specific Context Types: - 0x0001: Unspecified - 0x0002: Conversational - 0x0004: Media - 0x0008: Instructional - 0x0010: AttentionSeeking - 0x0020: ImmediateAlert - 0x0040: ManMachine - 0x0080: EmergencyAlert - 0x0100: Ringtone - 0x0200: TV config BT_PAC_SRC_NOTIFIABLE bool "Source PAC Notifiable Support" From 843f66f52d2f4d206411de7393cac1b29a4768e4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 09:31:28 +0000 Subject: [PATCH 0819/4498] intc: plic: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_plic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index fe061b89b0a..bbab421d253 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -210,7 +210,7 @@ static void plic_irq_handler(const void *arg) * * @retval 0 on success. */ -static int plic_init(void) +static int plic_init(const struct device *dev) { volatile uint32_t *en = (volatile uint32_t *)PLIC_IRQ_EN; @@ -247,4 +247,5 @@ static int plic_init(void) return 0; } -SYS_INIT(plic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, plic_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From 1539ca906e6eb311fbbb7be92d91e4e0c71e8b7a Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 09:49:43 +0000 Subject: [PATCH 0820/4498] intc: irqmp: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_irqmp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_irqmp.c b/drivers/interrupt_controller/intc_irqmp.c index ce2ffc9d6ae..6f023f38dcd 100644 --- a/drivers/interrupt_controller/intc_irqmp.c +++ b/drivers/interrupt_controller/intc_irqmp.c @@ -17,7 +17,7 @@ #define DT_DRV_COMPAT gaisler_irqmp #include -#include +#include /* * Register description for IRQMP and IRQAMP interrupt controllers @@ -108,7 +108,7 @@ int z_sparc_int_get_source(int irl) return source; } -static int irqmp_init(void) +static int irqmp_init(const struct device *dev) { volatile struct irqmp_regs *regs = get_irqmp_regs(); @@ -121,4 +121,5 @@ static int irqmp_init(void) return 0; } -SYS_INIT(irqmp_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, irqmp_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From 17ae9a768001c0b0dca1884776fa11279537eb8c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 09:59:41 +0000 Subject: [PATCH 0821/4498] intc: gic: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_gic.c | 16 ++++++++++++---- drivers/interrupt_controller/intc_gicv3.c | 10 ++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/interrupt_controller/intc_gic.c b/drivers/interrupt_controller/intc_gic.c index d664288df56..82eda22da27 100644 --- a/drivers/interrupt_controller/intc_gic.c +++ b/drivers/interrupt_controller/intc_gic.c @@ -10,7 +10,7 @@ * NOTE: This driver implements the GICv1 and GICv2 interfaces. */ -#include +#include #include #include #include @@ -18,6 +18,14 @@ #include #include +#if defined(CONFIG_GIC_V1) +#define DT_DRV_COMPAT arm_gic_v1 +#elif defined(CONFIG_GIC_V2) +#define DT_DRV_COMPAT arm_gic_v2 +#else +#error "Unknown GIC controller compatible for this configuration" +#endif + static const uint64_t cpu_mpid_list[] = { DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,)) }; @@ -253,9 +261,8 @@ static void gic_cpu_init(void) /** * @brief Initialize the GIC device driver */ -int arm_gic_init(void) +int arm_gic_init(const struct device *dev) { - /* Init of Distributor interface registers */ gic_dist_init(); @@ -265,7 +272,8 @@ int arm_gic_init(void) return 0; } -SYS_INIT(arm_gic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, arm_gic_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); #ifdef CONFIG_SMP void arm_gic_secondary_init(void) diff --git a/drivers/interrupt_controller/intc_gicv3.c b/drivers/interrupt_controller/intc_gicv3.c index 9c7611ad3c6..e3c25c4d8b8 100644 --- a/drivers/interrupt_controller/intc_gicv3.c +++ b/drivers/interrupt_controller/intc_gicv3.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include @@ -17,6 +17,8 @@ #include +#define DT_DRV_COMPAT arm_gic_v3 + /* Redistributor base addresses for each core */ mem_addr_t gic_rdists[CONFIG_MP_MAX_NUM_CPUS]; @@ -596,16 +598,16 @@ static void __arm_gic_init(void) gicv3_cpuif_init(); } -int arm_gic_init(void) +int arm_gic_init(const struct device *dev) { - gicv3_dist_init(); __arm_gic_init(); return 0; } -SYS_INIT(arm_gic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, arm_gic_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); #ifdef CONFIG_SMP void arm_gic_secondary_init(void) From 6fbe62bdb5aa9061a03e6776ef0ec64832ae7469 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 10:03:40 +0000 Subject: [PATCH 0822/4498] intc: arcv2: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_arcv2_irq_unit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_arcv2_irq_unit.c b/drivers/interrupt_controller/intc_arcv2_irq_unit.c index 5c06d936893..8825e1a7345 100644 --- a/drivers/interrupt_controller/intc_arcv2_irq_unit.c +++ b/drivers/interrupt_controller/intc_arcv2_irq_unit.c @@ -19,7 +19,9 @@ #include #include #include -#include +#include + +#define DT_DRV_COMPAT snps_arcv2_intc #ifdef CONFIG_ARC_CONNECT static void arc_shared_intc_init(void) @@ -134,7 +136,7 @@ void arc_core_private_intc_init(void) #endif /* CONFIG_ARC_CONNECT */ } -static int arc_irq_init(void) +static int arc_irq_init(const struct device *dev) { #ifdef CONFIG_ARC_CONNECT arc_shared_intc_init(); @@ -149,4 +151,5 @@ static int arc_irq_init(void) return 0; } -SYS_INIT(arc_irq_init, PRE_KERNEL_1, 0); +DEVICE_DT_INST_DEFINE(0, arc_irq_init, NULL, NULL, NULL, + PRE_KERNEL_1, 0, NULL); From a7e0cb0c80153c188a9342f1ae84cd19fb8e1556 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 10:22:40 +0000 Subject: [PATCH 0823/4498] intc: vexriscv_litex: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Fix an incorrectly declared compatible and adjust some DT macros as well. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_vexriscv_litex.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/interrupt_controller/intc_vexriscv_litex.c b/drivers/interrupt_controller/intc_vexriscv_litex.c index 719bd98ec36..efec4d2478e 100644 --- a/drivers/interrupt_controller/intc_vexriscv_litex.c +++ b/drivers/interrupt_controller/intc_vexriscv_litex.c @@ -4,17 +4,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT litex_eth0 +#define DT_DRV_COMPAT vexriscv_intc0 #include #include -#include #include #include #include -#define IRQ_MASK DT_REG_ADDR_BY_NAME(DT_INST(0, vexriscv_intc0), irq_mask) -#define IRQ_PENDING DT_REG_ADDR_BY_NAME(DT_INST(0, vexriscv_intc0), irq_pending) +#define IRQ_MASK DT_INST_REG_ADDR_BY_NAME(0, irq_mask) +#define IRQ_PENDING DT_INST_REG_ADDR_BY_NAME(0, irq_pending) #define TIMER0_IRQ DT_IRQN(DT_INST(0, litex_timer0)) #define UART0_IRQ DT_IRQN(DT_INST(0, litex_uart0)) @@ -120,7 +119,7 @@ int arch_irq_is_enabled(unsigned int irq) return vexriscv_litex_irq_getmask() & (1 << irq); } -static int vexriscv_litex_irq_init(void) +static int vexriscv_litex_irq_init(const struct device *dev) { __asm__ volatile ("csrrs x0, mie, %0" :: "r"(1 << RISCV_MACHINE_EXT_IRQ)); @@ -131,5 +130,5 @@ static int vexriscv_litex_irq_init(void) return 0; } -SYS_INIT(vexriscv_litex_irq_init, PRE_KERNEL_2, - CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, vexriscv_litex_irq_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From aea618ebc01182020014ca04f83c50388e24543a Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 10:29:30 +0000 Subject: [PATCH 0824/4498] intc: nuclei_eclic: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_nuclei_eclic.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_nuclei_eclic.c b/drivers/interrupt_controller/intc_nuclei_eclic.c index 19f1d682f55..9f831e56530 100644 --- a/drivers/interrupt_controller/intc_nuclei_eclic.c +++ b/drivers/interrupt_controller/intc_nuclei_eclic.c @@ -11,12 +11,14 @@ #include #include #include -#include +#include #include #include #include +#define DT_DRV_COMPAT nuclei_eclic + union CLICCFG { struct { uint8_t _reserved0 : 1; @@ -159,7 +161,7 @@ void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags) ECLIC_CTRL[irq].INTATTR.b.trg = (uint8_t)(flags & CLIC_INTATTR_TRIG_Msk); } -static int nuclei_eclic_init(void) +static int nuclei_eclic_init(const struct device *dev) { /* check hardware support required interrupt levels */ __ASSERT_NO_MSG(ECLIC_INFO.b.intctlbits >= INTERRUPT_LEVEL); @@ -182,4 +184,5 @@ static int nuclei_eclic_init(void) return 0; } -SYS_INIT(nuclei_eclic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, nuclei_eclic_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From e9a67aabf77ee03e2fae7fd68d9fc2c51d9e6a87 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 10:33:24 +0000 Subject: [PATCH 0825/4498] intc: swerv_pic: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_swerv_pic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_swerv_pic.c b/drivers/interrupt_controller/intc_swerv_pic.c index 65266cf8f9f..5c52ab49614 100644 --- a/drivers/interrupt_controller/intc_swerv_pic.c +++ b/drivers/interrupt_controller/intc_swerv_pic.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -143,7 +143,7 @@ static void swerv_pic_irq_handler(const void *arg) swerv_pic_write(SWERV_PIC_meigwclr(irq), 0); } -static int swerv_pic_init(void) +static int swerv_pic_init(const struct device *dev) { int i; @@ -236,4 +236,5 @@ int arch_irq_is_enabled(unsigned int irq) return !!(mie & (1 << irq)); } -SYS_INIT(swerv_pic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, swerv_pic_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From ceb02b3f31e2c1aa7e96ffdb2b74087317b483b4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 10:41:43 +0000 Subject: [PATCH 0826/4498] intc: intc_nxp_pint: convert SYS_INIT to DEVICE_DT_INST_DEFINE Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Adjust some DT_INST macro as well while at it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_nxp_pint.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/interrupt_controller/intc_nxp_pint.c b/drivers/interrupt_controller/intc_nxp_pint.c index ac497700e64..e05e2d30535 100644 --- a/drivers/interrupt_controller/intc_nxp_pint.c +++ b/drivers/interrupt_controller/intc_nxp_pint.c @@ -6,7 +6,7 @@ /* Based on STM32 EXTI driver, which is (c) 2016 Open-RnD Sp. z o.o. */ -#include +#include #include #include #include @@ -15,9 +15,7 @@ #define DT_DRV_COMPAT nxp_pint -#define PINT_NODE DT_INST(0, DT_DRV_COMPAT) - -static PINT_Type *pint_base = (PINT_Type *)DT_REG_ADDR(PINT_NODE); +static PINT_Type *pint_base = (PINT_Type *)DT_INST_REG_ADDR(0); /* Describes configuration of PINT IRQ slot */ struct pint_irq_slot { @@ -30,9 +28,9 @@ struct pint_irq_slot { #define NO_PINT_ID 0xFF /* Tracks IRQ configuration for each pint interrupt source */ -static struct pint_irq_slot pint_irq_cfg[DT_PROP(PINT_NODE, num_lines)]; +static struct pint_irq_slot pint_irq_cfg[DT_INST_PROP(0, num_lines)]; /* Tracks pint interrupt source selected for each pin */ -static uint8_t pin_pint_id[DT_PROP(PINT_NODE, num_inputs)]; +static uint8_t pin_pint_id[DT_INST_PROP(0, num_inputs)]; #define PIN_TO_INPUT_MUX_CONNECTION(pin) \ ((PINTSEL_PMUX_ID << PMUX_SHIFT) + (pin)) @@ -188,17 +186,17 @@ static void nxp_pint_isr(uint8_t *slot) irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ } while (false))) -static int intc_nxp_pint_init(void) +static int intc_nxp_pint_init(const struct device *dev) { /* First, connect IRQs for each interrupt. * The IRQ handler will receive the PINT slot as a * parameter. */ - LISTIFY(8, NXP_PINT_IRQ, (;), PINT_NODE); + LISTIFY(8, NXP_PINT_IRQ, (;), DT_INST(0, DT_DRV_COMPAT)); PINT_Init(pint_base); memset(pin_pint_id, NO_PINT_ID, ARRAY_SIZE(pin_pint_id)); return 0; } -SYS_INIT(intc_nxp_pint_init, PRE_KERNEL_1, - CONFIG_INTC_INIT_PRIORITY); +DEVICE_DT_INST_DEFINE(0, intc_nxp_pint_init, NULL, NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); From 794893315afa7f4a557ec83784e040a3bfec850a Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 15 Sep 2023 20:46:42 +0000 Subject: [PATCH 0827/4498] intc: loapic: convert DEVICE_DEFINE to DEVICE_DT_INST_DEFINE Convert DEVICE_DEFINE to DEVICE_DT_INST_DEFINE, this allows the build system to track the device dependencies and ensure that the interrupt controller is initialized before other devices using it. Signed-off-by: Fabio Baltieri --- drivers/interrupt_controller/intc_loapic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_loapic.c b/drivers/interrupt_controller/intc_loapic.c index 52722c5de45..742ae530596 100644 --- a/drivers/interrupt_controller/intc_loapic.c +++ b/drivers/interrupt_controller/intc_loapic.c @@ -413,10 +413,10 @@ static int loapic_pm_action(const struct device *dev, } #endif /* CONFIG_PM_DEVICE */ -PM_DEVICE_DEFINE(loapic, loapic_pm_action); +PM_DEVICE_DT_INST_DEFINE(0, loapic_pm_action); -DEVICE_DEFINE(loapic, "loapic", loapic_init, PM_DEVICE_GET(loapic), NULL, NULL, - PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); +DEVICE_DT_INST_DEFINE(0, loapic_init, PM_DEVICE_DT_INST_GET(0), NULL, NULL, + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); #if CONFIG_LOAPIC_SPURIOUS_VECTOR extern void z_loapic_spurious_handler(void); From 68dd26574c20be7460b0a9380c124f0ba5e21382 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Tue, 2 May 2023 02:37:54 -0700 Subject: [PATCH 0828/4498] boards: arm: npcx: add support for npcx4m8f_evb Add support for npcx4m8f_evb board that is a development platform to evaluate the Nuvoton NPCX4 embedded controller. Signed-off-by: Mulin Chao --- boards/arm/npcx4m8f_evb/Kconfig.board | 6 + boards/arm/npcx4m8f_evb/Kconfig.defconfig | 15 ++ boards/arm/npcx4m8f_evb/board.cmake | 6 + boards/arm/npcx4m8f_evb/doc/index.rst | 131 ++++++++++++++++++ boards/arm/npcx4m8f_evb/doc/npcx4m8f_evb.jpg | Bin 0 -> 96434 bytes .../npcx4m8f_evb/npcx4m8f_evb-pinctrl.dtsi | 16 +++ boards/arm/npcx4m8f_evb/npcx4m8f_evb.dts | 120 ++++++++++++++++ boards/arm/npcx4m8f_evb/npcx4m8f_evb.yaml | 26 ++++ .../arm/npcx4m8f_evb/npcx4m8f_evb_defconfig | 38 +++++ boards/arm/npcx4m8f_evb/support/openocd.cfg | 15 ++ .../adc/adc_api/boards/npcx4m8f_evb.overlay | 32 +++++ 11 files changed, 405 insertions(+) create mode 100644 boards/arm/npcx4m8f_evb/Kconfig.board create mode 100644 boards/arm/npcx4m8f_evb/Kconfig.defconfig create mode 100644 boards/arm/npcx4m8f_evb/board.cmake create mode 100644 boards/arm/npcx4m8f_evb/doc/index.rst create mode 100644 boards/arm/npcx4m8f_evb/doc/npcx4m8f_evb.jpg create mode 100644 boards/arm/npcx4m8f_evb/npcx4m8f_evb-pinctrl.dtsi create mode 100644 boards/arm/npcx4m8f_evb/npcx4m8f_evb.dts create mode 100644 boards/arm/npcx4m8f_evb/npcx4m8f_evb.yaml create mode 100644 boards/arm/npcx4m8f_evb/npcx4m8f_evb_defconfig create mode 100644 boards/arm/npcx4m8f_evb/support/openocd.cfg create mode 100644 tests/drivers/adc/adc_api/boards/npcx4m8f_evb.overlay diff --git a/boards/arm/npcx4m8f_evb/Kconfig.board b/boards/arm/npcx4m8f_evb/Kconfig.board new file mode 100644 index 00000000000..093faa1cade --- /dev/null +++ b/boards/arm/npcx4m8f_evb/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NPCX4M8F_EVB + bool "Nuvoton NPCX4M8F EVB Development board" + depends on SOC_NPCX4M8F diff --git a/boards/arm/npcx4m8f_evb/Kconfig.defconfig b/boards/arm/npcx4m8f_evb/Kconfig.defconfig new file mode 100644 index 00000000000..ae6ce213595 --- /dev/null +++ b/boards/arm/npcx4m8f_evb/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NPCX4M8F_EVB + +config BOARD + default "npcx4m8f_evb" + +endif # BOARD_NPCX4M8F_EVB + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config INPUT + default y if KSCAN diff --git a/boards/arm/npcx4m8f_evb/board.cmake b/boards/arm/npcx4m8f_evb/board.cmake new file mode 100644 index 00000000000..51e7fd4c66f --- /dev/null +++ b/boards/arm/npcx4m8f_evb/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-load "npcx_write_image") +board_runner_args(openocd --cmd-verify "npcx_verify_image") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/npcx4m8f_evb/doc/index.rst b/boards/arm/npcx4m8f_evb/doc/index.rst new file mode 100644 index 00000000000..a73d65d33da --- /dev/null +++ b/boards/arm/npcx4m8f_evb/doc/index.rst @@ -0,0 +1,131 @@ +.. _npcx4m8f_evb: + +Nuvoton NPCX4M8F_EVB +#################### + +Overview +******** + +The NPCX4M8F_EVB kit is a development platform to evaluate the +Nuvoton NPCX4 series microcontrollers. This board needs to be mated with +part number NPCX498F. + +.. image:: npcx4m8f_evb.jpg + :align: center + :alt: NPCX4M8F Evaluation Board + +Hardware +******** + +- ARM Cortex-M4F Processor +- 512 KB RAM and 64 KB boot ROM +- ADC & GPIO headers +- UART0 and UART1 +- FAN PWM interface +- Jtag interface +- Intel Modular Embedded Controller Card (MECC) headers + +Supported Features +================== + +The following features are supported: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc controller | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c port/controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| PM | on-chip | power management | ++-----------+------------+-------------------------------------+ +| PSL | on-chip | power switch logic | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pulse width modulator | ++-----------+------------+-------------------------------------+ +| TACH | on-chip | tachometer sensor | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by Zephyr (at the moment) + +The default configuration can be found in the defconfig file: +``boards/arm/npcx4m8f_evb/npcx4m8f_evb_defconfig`` + + +Connections and IOs +=================== + +Nuvoton to provide the schematic for this board. + +System Clock +============ + +The NPCX4M8F MCU is configured to use the 120Mhz internal oscillator with the +on-chip PLL to generate a resulting EC clock rate of 15 MHz. See Processor clock +control register (chapter 4 in user manual) + +Serial Port +=========== + +UART1 is configured for serial logs. + +Programming and Debugging +************************* + +This board comes with a Cortex ETM port which facilitates tracing and debugging +using a single physical connection. In addition, it comes with sockets for +JTAG-only sessions. + +Flashing +======== + +If the correct headers are installed, this board supports both J-TAG and also +the ChromiumOS servo. + +To flash using Servo V2, μServo, or Servo V4 (CCD), see the +`Chromium EC Flashing Documentation`_ for more information. + +To flash with J-TAG, install the drivers for your programmer, for example: +SEGGER J-link's drivers are at https://www.segger.com/downloads/jlink/ + +The openocd from Zephyr SDK 0.16.1 doesn't include npcx4 support, so build openocd from source.:: + + sudo apt-get install libftdi-dev libusb-1.0.0-dev + git clone https://git.code.sf.net/p/openocd/code ~/openocd + cd ~/openocd + ./bootstrap + ./configure --enable-jlink --enable-ftdi + make clean + make + sudo make install + +Build and flash the blinky sample.:: + + west build -t clean && \ + west build -c -p auto -b npcx4m8f_evb samples/basic/blinky && \ + west flash --openocd /usr/local/bin/openocd + +Debugging +========= + +Use JTAG/SWD with a J-Link + +References +********** +.. target-notes:: + +.. _Chromium EC Flashing Documentation: + https://chromium.googlesource.com/chromiumos/platform/ec#Flashing-via-the-servo-debug-board diff --git a/boards/arm/npcx4m8f_evb/doc/npcx4m8f_evb.jpg b/boards/arm/npcx4m8f_evb/doc/npcx4m8f_evb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..369dd8b015015a7b505c28b3295c344f7ae55e51 GIT binary patch literal 96434 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�IUL>WRCSptKuA*EM=dd?btMWAq=M=jPQRNb@@xu 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 VDQ=jsMK7~?Xczzh literal 0 HcmV?d00001 diff --git a/boards/arm/npcx4m8f_evb/npcx4m8f_evb-pinctrl.dtsi b/boards/arm/npcx4m8f_evb/npcx4m8f_evb-pinctrl.dtsi new file mode 100644 index 00000000000..ab9df9c474a --- /dev/null +++ b/boards/arm/npcx4m8f_evb/npcx4m8f_evb-pinctrl.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&i2c0_0_sda_scl_gpb4_b5 { + bias-pull-up; /* Enable internal pull-up for i2c0_0 */ + pinmux-locked; /* Lock pinmuxing */ +}; + +&pwm6_gpc0 { + drive-open-drain; +}; diff --git a/boards/arm/npcx4m8f_evb/npcx4m8f_evb.dts b/boards/arm/npcx4m8f_evb/npcx4m8f_evb.dts new file mode 100644 index 00000000000..a34002e8bc8 --- /dev/null +++ b/boards/arm/npcx4m8f_evb/npcx4m8f_evb.dts @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "npcx4m8f_evb-pinctrl.dtsi" + +/ { + model = "Nuvoton NPCX4M8F evaluation board"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart1; + zephyr,flash = &flash0; + zephyr,keyboard-scan = &kscan_input; + }; + + aliases { + pwm-led0 = &pwm_led0_green; + led0 = &gpio_led_red; + pwm-0 = &pwm6; + i2c-0 = &i2c0_0; + watchdog0 = &twd0; + peci-0 = &peci0; + spi-flash0 = &int_flash; + kscan0 = &kscan_input; + }; + + leds-pwm { + compatible = "pwm-leds"; + pwm_led0_green: pwm_led_0 { + pwms = <&pwm6 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "User D7 green"; + }; + }; + + leds-gpio { + compatible = "gpio-leds"; + gpio_led_red: led_0 { + gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; + label = "User D8 red"; + }; + }; +}; + +/* Overwrite default device properties with overlays in board dt file here. */ +&uart1 { + status = "okay"; + current-speed = <115200>; + /* Use UART1_SL2 ie. PIN64.65 */ + pinctrl-0 = <&uart1_2_sin_gp64 &uart1_2_sout_gp65>; + pinctrl-names = "default"; +}; + +&pwm6 { + status = "okay"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +&adc0 { + status = "okay"; + /* Use adc0 channel 0 and 2 for 'adc_api' driver tests */ + pinctrl-0 = <&adc0_chan0_gp45 &adc0_chan2_gp43>; + pinctrl-names = "default"; +}; + +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&tach1 { + status = "okay"; + pinctrl-0 = <&ta1_1_in_gp40>; + pinctrl-names = "default"; + port = ; + sample-clk = ; + pulses-per-round = <1>; +}; + +&peci0 { + status = "okay"; + pinctrl-0 = <&peci_dat_gp81>; + pinctrl-names = "default"; +}; + +&kbd { + /* Demonstrate a 13 x 8 keyboard matrix on evb */ + pinctrl-0 = <&ksi0_gp31 &ksi1_gp30 &ksi2_gp27 &ksi3_gp26 + &ksi4_gp25 &ksi5_gp24 &ksi6_gp23 &ksi7_gp22 + &kso00_gp21 &kso01_gp20 &kso02_gp17 &kso03_gp16 + &kso04_gp15 &kso05_gp14 &kso06_gp13 &kso07_gp12 + &kso08_gp11 &kso09_gp10 &kso10_gp07 &kso11_gp06 + &kso12_gp05>; + pinctrl-names = "default"; + row-size = <8>; + col-size = <13>; + status = "okay"; + + kscan_input: kscan-input { + compatible = "zephyr,kscan-input"; + }; +}; diff --git a/boards/arm/npcx4m8f_evb/npcx4m8f_evb.yaml b/boards/arm/npcx4m8f_evb/npcx4m8f_evb.yaml new file mode 100644 index 00000000000..9e225f6163c --- /dev/null +++ b/boards/arm/npcx4m8f_evb/npcx4m8f_evb.yaml @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Nuvoton Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: npcx4m8f_evb +name: Nuvoton NPCX4M8F EVB +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 114 +flash: 384 +supported: + - adc + - clock + - gpio + - i2c + - pm + - pwm + - psl + - tach + - uart + - watchdog diff --git a/boards/arm/npcx4m8f_evb/npcx4m8f_evb_defconfig b/boards/arm/npcx4m8f_evb/npcx4m8f_evb_defconfig new file mode 100644 index 00000000000..4ec779de482 --- /dev/null +++ b/boards/arm/npcx4m8f_evb/npcx4m8f_evb_defconfig @@ -0,0 +1,38 @@ +# +# Copyright (c) 2023 Nuvoton Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_NPCX4M8F=y +CONFIG_SOC_SERIES_NPCX4=y +CONFIG_BOARD_NPCX4M8F_EVB=y + +# Enable NPCX firmware header +CONFIG_NPCX_HEADER=y +CONFIG_NPCX_IMAGE_OUTPUT_HEX=y +CONFIG_NPCX_HEADER_SPI_MAX_CLOCK_50=y +CONFIG_NPCX_HEADER_SPI_READ_MODE_DUAL=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y + +# General Kernel Options +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=15000000 + +# UART Driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# GPIO Driver +CONFIG_GPIO=y + +# Pin Controller Driver +CONFIG_PINCTRL=y + +# Console Driver +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/npcx4m8f_evb/support/openocd.cfg b/boards/arm/npcx4m8f_evb/support/openocd.cfg new file mode 100644 index 00000000000..924de78080f --- /dev/null +++ b/boards/arm/npcx4m8f_evb/support/openocd.cfg @@ -0,0 +1,15 @@ +# script for Nuvoton NPCX Cortex-M4 Series + +source [find interface/jlink.cfg] +transport select swd + +set FIUNAME npcx_v2.fiu +source [find target/npcx.cfg] + +proc npcx_write_image {target_image} { + flash write_image erase $target_image 0x64000000 ihex +} + +proc npcx_verify_image {target_image} { + verify_image $target_image 0x64000000 ihex +} diff --git a/tests/drivers/adc/adc_api/boards/npcx4m8f_evb.overlay b/tests/drivers/adc/adc_api/boards/npcx4m8f_evb.overlay new file mode 100644 index 00000000000..5614d545114 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/npcx4m8f_evb.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Benjamin Björnsson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 2>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <10>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <10>; + }; +}; From eeea64a19ce04e12d8d85b9c11bf654e2a771009 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 15 Sep 2023 11:34:48 +0200 Subject: [PATCH 0829/4498] drivers/nvme: Add debug information in case of request error This will provide a detailed error status report. As for most of the original code of the driver, this is a backport of the work done by Jim Harris in FreeBSD. Signed-off-by: Tomasz Bursztyka --- drivers/disk/nvme/nvme_cmd.c | 168 ++++++++++++++++++++++++++++ drivers/disk/nvme/nvme_cmd.h | 8 +- drivers/disk/nvme/nvme_controller.c | 5 +- drivers/disk/nvme/nvme_disk.c | 3 + 4 files changed, 182 insertions(+), 2 deletions(-) diff --git a/drivers/disk/nvme/nvme_cmd.c b/drivers/disk/nvme/nvme_cmd.c index f6633b7dec1..14c662ffe4e 100644 --- a/drivers/disk/nvme/nvme_cmd.c +++ b/drivers/disk/nvme/nvme_cmd.c @@ -26,6 +26,174 @@ static void request_timeout(struct k_work *work); static K_WORK_DELAYABLE_DEFINE(request_timer, request_timeout); +#ifdef CONFIG_NVME_LOG_LEVEL_DBG +struct nvme_status_string { + uint16_t sc; + const char *str; +}; + +static struct nvme_status_string generic_status[] = { + { NVME_SC_SUCCESS, "SUCCESS" }, + { NVME_SC_INVALID_OPCODE, "INVALID OPCODE" }, + { NVME_SC_INVALID_FIELD, "INVALID_FIELD" }, + { NVME_SC_COMMAND_ID_CONFLICT, "COMMAND ID CONFLICT" }, + { NVME_SC_DATA_TRANSFER_ERROR, "DATA TRANSFER ERROR" }, + { NVME_SC_ABORTED_POWER_LOSS, "ABORTED - POWER LOSS" }, + { NVME_SC_INTERNAL_DEVICE_ERROR, "INTERNAL DEVICE ERROR" }, + { NVME_SC_ABORTED_BY_REQUEST, "ABORTED - BY REQUEST" }, + { NVME_SC_ABORTED_SQ_DELETION, "ABORTED - SQ DELETION" }, + { NVME_SC_ABORTED_FAILED_FUSED, "ABORTED - FAILED FUSED" }, + { NVME_SC_ABORTED_MISSING_FUSED, "ABORTED - MISSING FUSED" }, + { NVME_SC_INVALID_NAMESPACE_OR_FORMAT, "INVALID NAMESPACE OR FORMAT" }, + { NVME_SC_COMMAND_SEQUENCE_ERROR, "COMMAND SEQUENCE ERROR" }, + { NVME_SC_INVALID_SGL_SEGMENT_DESCR, "INVALID SGL SEGMENT DESCRIPTOR" }, + { NVME_SC_INVALID_NUMBER_OF_SGL_DESCR, "INVALID NUMBER OF SGL DESCRIPTORS" }, + { NVME_SC_DATA_SGL_LENGTH_INVALID, "DATA SGL LENGTH INVALID" }, + { NVME_SC_METADATA_SGL_LENGTH_INVALID, "METADATA SGL LENGTH INVALID" }, + { NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID, "SGL DESCRIPTOR TYPE INVALID" }, + { NVME_SC_INVALID_USE_OF_CMB, "INVALID USE OF CONTROLLER MEMORY BUFFER" }, + { NVME_SC_PRP_OFFSET_INVALID, "PRP OFFSET INVALID" }, + { NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED, "ATOMIC WRITE UNIT EXCEEDED" }, + { NVME_SC_OPERATION_DENIED, "OPERATION DENIED" }, + { NVME_SC_SGL_OFFSET_INVALID, "SGL OFFSET INVALID" }, + { NVME_SC_HOST_ID_INCONSISTENT_FORMAT, "HOST IDENTIFIER INCONSISTENT FORMAT" }, + { NVME_SC_KEEP_ALIVE_TIMEOUT_EXPIRED, "KEEP ALIVE TIMEOUT EXPIRED" }, + { NVME_SC_KEEP_ALIVE_TIMEOUT_INVALID, "KEEP ALIVE TIMEOUT INVALID" }, + { NVME_SC_ABORTED_DUE_TO_PREEMPT, "COMMAND ABORTED DUE TO PREEMPT AND ABORT" }, + { NVME_SC_SANITIZE_FAILED, "SANITIZE FAILED" }, + { NVME_SC_SANITIZE_IN_PROGRESS, "SANITIZE IN PROGRESS" }, + { NVME_SC_SGL_DATA_BLOCK_GRAN_INVALID, "SGL_DATA_BLOCK_GRANULARITY_INVALID" }, + { NVME_SC_NOT_SUPPORTED_IN_CMB, "COMMAND NOT SUPPORTED FOR QUEUE IN CMB" }, + { NVME_SC_NAMESPACE_IS_WRITE_PROTECTED, "NAMESPACE IS WRITE PROTECTED" }, + { NVME_SC_COMMAND_INTERRUPTED, "COMMAND INTERRUPTED" }, + { NVME_SC_TRANSIENT_TRANSPORT_ERROR, "TRANSIENT TRANSPORT ERROR" }, + { NVME_SC_LBA_OUT_OF_RANGE, "LBA OUT OF RANGE" }, + { NVME_SC_CAPACITY_EXCEEDED, "CAPACITY EXCEEDED" }, + { NVME_SC_NAMESPACE_NOT_READY, "NAMESPACE NOT READY" }, + { NVME_SC_RESERVATION_CONFLICT, "RESERVATION CONFLICT" }, + { NVME_SC_FORMAT_IN_PROGRESS, "FORMAT IN PROGRESS" }, + { 0xFFFF, "GENERIC" } +}; + +static struct nvme_status_string command_specific_status[] = { + { NVME_SC_COMPLETION_QUEUE_INVALID, "INVALID COMPLETION QUEUE" }, + { NVME_SC_INVALID_QUEUE_IDENTIFIER, "INVALID QUEUE IDENTIFIER" }, + { NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED, "MAX QUEUE SIZE EXCEEDED" }, + { NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED, "ABORT CMD LIMIT EXCEEDED" }, + { NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED, "ASYNC LIMIT EXCEEDED" }, + { NVME_SC_INVALID_FIRMWARE_SLOT, "INVALID FIRMWARE SLOT" }, + { NVME_SC_INVALID_FIRMWARE_IMAGE, "INVALID FIRMWARE IMAGE" }, + { NVME_SC_INVALID_INTERRUPT_VECTOR, "INVALID INTERRUPT VECTOR" }, + { NVME_SC_INVALID_LOG_PAGE, "INVALID LOG PAGE" }, + { NVME_SC_INVALID_FORMAT, "INVALID FORMAT" }, + { NVME_SC_FIRMWARE_REQUIRES_RESET, "FIRMWARE REQUIRES RESET" }, + { NVME_SC_INVALID_QUEUE_DELETION, "INVALID QUEUE DELETION" }, + { NVME_SC_FEATURE_NOT_SAVEABLE, "FEATURE IDENTIFIER NOT SAVEABLE" }, + { NVME_SC_FEATURE_NOT_CHANGEABLE, "FEATURE NOT CHANGEABLE" }, + { NVME_SC_FEATURE_NOT_NS_SPECIFIC, "FEATURE NOT NAMESPACE SPECIFIC" }, + { NVME_SC_FW_ACT_REQUIRES_NVMS_RESET, "FIRMWARE ACTIVATION REQUIRES NVM SUBSYSTEM RESET" }, + { NVME_SC_FW_ACT_REQUIRES_RESET, "FIRMWARE ACTIVATION REQUIRES RESET" }, + { NVME_SC_FW_ACT_REQUIRES_TIME, "FIRMWARE ACTIVATION REQUIRES MAXIMUM TIME VIOLATION" }, + { NVME_SC_FW_ACT_PROHIBITED, "FIRMWARE ACTIVATION PROHIBITED" }, + { NVME_SC_OVERLAPPING_RANGE, "OVERLAPPING RANGE" }, + { NVME_SC_NS_INSUFFICIENT_CAPACITY, "NAMESPACE INSUFFICIENT CAPACITY" }, + { NVME_SC_NS_ID_UNAVAILABLE, "NAMESPACE IDENTIFIER UNAVAILABLE" }, + { NVME_SC_NS_ALREADY_ATTACHED, "NAMESPACE ALREADY ATTACHED" }, + { NVME_SC_NS_IS_PRIVATE, "NAMESPACE IS PRIVATE" }, + { NVME_SC_NS_NOT_ATTACHED, "NS NOT ATTACHED" }, + { NVME_SC_THIN_PROV_NOT_SUPPORTED, "THIN PROVISIONING NOT SUPPORTED" }, + { NVME_SC_CTRLR_LIST_INVALID, "CONTROLLER LIST INVALID" }, + { NVME_SC_SELF_TEST_IN_PROGRESS, "DEVICE SELF-TEST IN PROGRESS" }, + { NVME_SC_BOOT_PART_WRITE_PROHIB, "BOOT PARTITION WRITE PROHIBITED" }, + { NVME_SC_INVALID_CTRLR_ID, "INVALID CONTROLLER IDENTIFIER" }, + { NVME_SC_INVALID_SEC_CTRLR_STATE, "INVALID SECONDARY CONTROLLER STATE" }, + { NVME_SC_INVALID_NUM_OF_CTRLR_RESRC, "INVALID NUMBER OF CONTROLLER RESOURCES" }, + { NVME_SC_INVALID_RESOURCE_ID, "INVALID RESOURCE IDENTIFIER" }, + { NVME_SC_SANITIZE_PROHIBITED_WPMRE, + "SANITIZE PROHIBITED WRITE PERSISTENT MEMORY REGION ENABLED" }, + { NVME_SC_ANA_GROUP_ID_INVALID, "ANA GROUP IDENTIFIED INVALID" }, + { NVME_SC_ANA_ATTACH_FAILED, "ANA ATTACH FAILED" }, + { NVME_SC_CONFLICTING_ATTRIBUTES, "CONFLICTING ATTRIBUTES" }, + { NVME_SC_INVALID_PROTECTION_INFO, "INVALID PROTECTION INFO" }, + { NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE, "WRITE TO RO PAGE" }, + { 0xFFFF, "COMMAND SPECIFIC" } +}; + +static struct nvme_status_string media_error_status[] = { + { NVME_SC_WRITE_FAULTS, "WRITE FAULTS" }, + { NVME_SC_UNRECOVERED_READ_ERROR, "UNRECOVERED READ ERROR" }, + { NVME_SC_GUARD_CHECK_ERROR, "GUARD CHECK ERROR" }, + { NVME_SC_APPLICATION_TAG_CHECK_ERROR, "APPLICATION TAG CHECK ERROR" }, + { NVME_SC_REFERENCE_TAG_CHECK_ERROR, "REFERENCE TAG CHECK ERROR" }, + { NVME_SC_COMPARE_FAILURE, "COMPARE FAILURE" }, + { NVME_SC_ACCESS_DENIED, "ACCESS DENIED" }, + { NVME_SC_DEALLOCATED_OR_UNWRITTEN, "DEALLOCATED OR UNWRITTEN LOGICAL BLOCK" }, + { 0xFFFF, "MEDIA ERROR" } +}; + +static struct nvme_status_string path_related_status[] = { + { NVME_SC_INTERNAL_PATH_ERROR, "INTERNAL PATH ERROR" }, + { NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS, "ASYMMETRIC ACCESS PERSISTENT LOSS" }, + { NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE, "ASYMMETRIC ACCESS INACCESSIBLE" }, + { NVME_SC_ASYMMETRIC_ACCESS_TRANSITION, "ASYMMETRIC ACCESS TRANSITION" }, + { NVME_SC_CONTROLLER_PATHING_ERROR, "CONTROLLER PATHING ERROR" }, + { NVME_SC_HOST_PATHING_ERROR, "HOST PATHING ERROR" }, + { NVME_SC_COMMAND_ABORTED_BY_HOST, "COMMAND ABORTED BY HOST" }, + { 0xFFFF, "PATH RELATED" }, +}; + +static const char *get_status_string(uint16_t sct, uint16_t sc) +{ + struct nvme_status_string *entry; + + switch (sct) { + case NVME_SCT_GENERIC: + entry = generic_status; + break; + case NVME_SCT_COMMAND_SPECIFIC: + entry = command_specific_status; + break; + case NVME_SCT_MEDIA_ERROR: + entry = media_error_status; + break; + case NVME_SCT_PATH_RELATED: + entry = path_related_status; + break; + case NVME_SCT_VENDOR_SPECIFIC: + return "VENDOR SPECIFIC"; + default: + return "RESERVED"; + } + + while (entry->sc != 0xFFFF) { + if (entry->sc == sc) { + return entry->str; + } + + entry++; + } + return entry->str; +} + +void nvme_completion_print(const struct nvme_completion *cpl) +{ + uint8_t sct, sc, crd, m, dnr, p; + + sct = NVME_STATUS_GET_SCT(cpl->status); + sc = NVME_STATUS_GET_SC(cpl->status); + crd = NVME_STATUS_GET_CRD(cpl->status); + m = NVME_STATUS_GET_M(cpl->status); + dnr = NVME_STATUS_GET_DNR(cpl->status); + p = NVME_STATUS_GET_P(cpl->status); + + LOG_DBG("%s (%02x/%02x) crd:%x m:%x dnr:%x p:%d " + "sqid:%d cid:%d cdw0:%x\n", + get_status_string(sct, sc), sct, sc, crd, m, dnr, p, + cpl->sqid, cpl->cid, cpl->cdw0); +} + +#endif /* CONFIG_NVME_LOG_LEVEL_DBG */ + void nvme_cmd_init(void) { int idx; diff --git a/drivers/disk/nvme/nvme_cmd.h b/drivers/disk/nvme/nvme_cmd.h index 5dc17b8e8c4..c0e4e512ab4 100644 --- a/drivers/disk/nvme/nvme_cmd.h +++ b/drivers/disk/nvme/nvme_cmd.h @@ -197,7 +197,7 @@ enum nvme_path_related_status_code { NVME_SC_ASYMMETRIC_ACCESS_TRANSITION = 0x03, NVME_SC_CONTROLLER_PATHING_ERROR = 0x60, NVME_SC_HOST_PATHING_ERROR = 0x70, - NVME_SC_COMMAND_ABOTHED_BY_HOST = 0x71, + NVME_SC_COMMAND_ABORTED_BY_HOST = 0x71, }; /* admin opcodes */ @@ -377,6 +377,12 @@ void nvme_cmd_init(void); void nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl); +#ifdef CONFIG_NVME_LOG_LEVEL_DBG +void nvme_completion_print(const struct nvme_completion *cpl); +#else +#define nvme_completion_print(...) +#endif /* CONFIG_NVME_LOG_LEVEL_DBG */ + void nvme_cmd_request_free(struct nvme_request *request); struct nvme_request *nvme_cmd_request_alloc(void); diff --git a/drivers/disk/nvme/nvme_controller.c b/drivers/disk/nvme/nvme_controller.c index c387da71d20..699df325add 100644 --- a/drivers/disk/nvme/nvme_controller.c +++ b/drivers/disk/nvme/nvme_controller.c @@ -183,6 +183,7 @@ static int nvme_controller_setup_io_queues(const struct device *dev) if (nvme_cpl_status_is_error(&status)) { LOG_ERR("Could not set IO num queues to %u", nvme_ctrlr->num_io_queues); + nvme_completion_print(&status.cpl); return -EIO; } @@ -225,6 +226,7 @@ static int nvme_controller_setup_io_queues(const struct device *dev) nvme_completion_poll(&status); if (nvme_cpl_status_is_error(&status)) { LOG_ERR("IO CQ creation failed"); + nvme_completion_print(&status.cpl); return -EIO; } @@ -240,6 +242,7 @@ static int nvme_controller_setup_io_queues(const struct device *dev) nvme_completion_poll(&status); if (nvme_cpl_status_is_error(&status)) { LOG_ERR("IO CQ creation failed"); + nvme_completion_print(&status.cpl); return -EIO; } } @@ -372,9 +375,9 @@ static int nvme_controller_identify(struct nvme_controller *nvme_ctrlr) nvme_ctrlr_cmd_identify_controller(nvme_ctrlr, nvme_completion_poll_cb, &status); nvme_completion_poll(&status); - if (nvme_cpl_status_is_error(&status)) { LOG_ERR("Could not identify the controller"); + nvme_completion_print(&status.cpl); return -EIO; } diff --git a/drivers/disk/nvme/nvme_disk.c b/drivers/disk/nvme/nvme_disk.c index ff22e3bad41..3308e04db5b 100644 --- a/drivers/disk/nvme/nvme_disk.c +++ b/drivers/disk/nvme/nvme_disk.c @@ -57,6 +57,7 @@ static int nvme_disk_read(struct disk_info *disk, if (nvme_cpl_status_is_error(&status)) { LOG_WRN("Reading at sector %u (count %d) on disk %s failed", start_sector, num_sector, ns->name); + nvme_completion_print(&status.cpl); ret = -EIO; } out: @@ -100,6 +101,7 @@ static int nvme_disk_write(struct disk_info *disk, if (nvme_cpl_status_is_error(&status)) { LOG_WRN("Writing at sector %u (count %d) on disk %s failed", start_sector, num_sector, ns->name); + nvme_completion_print(&status.cpl); ret = -EIO; } out: @@ -128,6 +130,7 @@ static int nvme_disk_flush(struct nvme_namespace *ns) nvme_completion_poll(&status); if (nvme_cpl_status_is_error(&status)) { LOG_ERR("Flushing disk %s failed", ns->name); + nvme_completion_print(&status.cpl); return -EIO; } From 0b456883350dafd8967d836448d8c0423864775e Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 15 Sep 2023 12:14:51 +0200 Subject: [PATCH 0830/4498] drivers/nvme: Rely on CONFIG_MMU_PAGE_SIZE for PRP Getting rid of 4Kib page size hardcoded value on PRP handling. Signed-off-by: Tomasz Bursztyka --- drivers/disk/nvme/nvme_cmd.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/disk/nvme/nvme_cmd.h b/drivers/disk/nvme/nvme_cmd.h index c0e4e512ab4..24351570f10 100644 --- a/drivers/disk/nvme/nvme_cmd.h +++ b/drivers/disk/nvme/nvme_cmd.h @@ -306,16 +306,14 @@ enum nvme_feature { #define CACHE_LINE_SIZE CONFIG_DCACHE_LINE_SIZE #endif -/* Assuming page size it always 4Kib - * ToDo: define it accorditng to CONFIG_MMU_PAGE_SIZE - */ -#define NVME_PBAO_MASK 0xFFF +#define NVME_PBAO_MASK (CONFIG_MMU_PAGE_SIZE - 1) -#define NVME_PRP_NEXT_PAGE(_addr) ((_addr & (~NVME_PBAO_MASK)) + 0x1000) +#define NVME_PRP_NEXT_PAGE(_addr) \ + ((_addr & ~NVME_PBAO_MASK) + CONFIG_MMU_PAGE_SIZE) struct nvme_prp_list { uintptr_t prp[CONFIG_MMU_PAGE_SIZE / sizeof(uintptr_t)] - __aligned(0x1000); + __aligned(CONFIG_MMU_PAGE_SIZE); sys_dnode_t node; }; From f21760252a23fc306f09cbe5aee5f9529ae9834b Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 15 Sep 2023 12:21:34 +0200 Subject: [PATCH 0831/4498] drivers/nvme: Make sure PRP2 value is encoded in little endian. To avoid issue in address translation when CPU is running in big endian. Signed-off-by: Tomasz Bursztyka --- drivers/disk/nvme/nvme_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/disk/nvme/nvme_cmd.c b/drivers/disk/nvme/nvme_cmd.c index 14c662ffe4e..8942e80576d 100644 --- a/drivers/disk/nvme/nvme_cmd.c +++ b/drivers/disk/nvme/nvme_cmd.c @@ -591,9 +591,9 @@ static int nvme_cmd_qpair_fill_dptr(struct nvme_cmd_qpair *qpair, request->cmd.dptr.prp1 = (uint64_t)sys_cpu_to_le64(request->payload); if ((uintptr_t)request->payload & NVME_PBAO_MASK) { - request->cmd.dptr.prp2 = + request->cmd.dptr.prp2 = (uint64_t)sys_cpu_to_le64( NVME_PRP_NEXT_PAGE( - (uintptr_t)request->payload); + (uintptr_t)request->payload)); } else { request->cmd.dptr.prp2 = 0; } From 2caced752ab4f7ddf3f029b2e3852fa4e427af6b Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Mon, 18 Sep 2023 13:45:56 +0200 Subject: [PATCH 0832/4498] drivers/nvme: Rewrite how data pointer is filled Former way was difficult to read, so let's have a better way which easily follows the specifications. Signed-off-by: Tomasz Bursztyka --- drivers/disk/nvme/nvme_cmd.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/disk/nvme/nvme_cmd.c b/drivers/disk/nvme/nvme_cmd.c index 8942e80576d..fb0bcb2d70c 100644 --- a/drivers/disk/nvme/nvme_cmd.c +++ b/drivers/disk/nvme/nvme_cmd.c @@ -567,6 +567,32 @@ static int nvme_cmd_qpair_fill_prp_list(struct nvme_cmd_qpair *qpair, return 0; } +static int compute_n_prp(uintptr_t addr, uint32_t size) +{ + int n_prp; + + /* See Common Command Format, Data Pointer (DPTR) field */ + + n_prp = size / CONFIG_MMU_PAGE_SIZE; + if (n_prp == 0) { + n_prp = 1; + } + + if (size != CONFIG_MMU_PAGE_SIZE) { + size = size % CONFIG_MMU_PAGE_SIZE; + } + + if (n_prp == 1) { + if ((addr + (uintptr_t)size) > NVME_PRP_NEXT_PAGE(addr)) { + n_prp++; + } + } else if (size > 0) { + n_prp++; + } + + return n_prp; +} + static int nvme_cmd_qpair_fill_dptr(struct nvme_cmd_qpair *qpair, struct nvme_request *request) { @@ -581,16 +607,12 @@ static int nvme_cmd_qpair_fill_dptr(struct nvme_cmd_qpair *qpair, return -EINVAL; } - n_prp = request->payload_size / qpair->ctrlr->page_size; - if ((request->payload_size % qpair->ctrlr->page_size) || - ((uintptr_t)request->payload & NVME_PBAO_MASK)) { - n_prp++; - } - + n_prp = compute_n_prp((uintptr_t)request->payload, + request->payload_size); if (n_prp <= 2) { request->cmd.dptr.prp1 = (uint64_t)sys_cpu_to_le64(request->payload); - if ((uintptr_t)request->payload & NVME_PBAO_MASK) { + if (n_prp == 2) { request->cmd.dptr.prp2 = (uint64_t)sys_cpu_to_le64( NVME_PRP_NEXT_PAGE( (uintptr_t)request->payload)); From 95b84938573fe876ae99ed27b2680a7604ddae9a Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Wed, 20 Sep 2023 10:27:42 +0200 Subject: [PATCH 0833/4498] drivers/nvme: Return an error in case of non dword-aligned data buffer This is a specific case for NVMe where given data buffer pointers must be dword (4 bytes) aligned. There is no virtual memory management between the user thread and NVMe driver (which one could detect such wrong alignement on physical memory and thus reallocate the memory properly, so it would be fully transparent for the user thread), thus the need to push that check to the user. This has been going under the radar so far as Qemu does not seem to follow NVMe specifications where PRP1 (in DPTR) must always be dword-aligned. It really does not follow the rule: specifications details that if bits 1:0 of PRP1 are set, the controller may generate an error or treat the address as if these bits were unset. Seems like a bug in Qemu, I did not check the code there however. Signed-off-by: Tomasz Bursztyka --- drivers/disk/nvme/nvme_disk.c | 10 ++++++++++ drivers/disk/nvme/nvme_helpers.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/disk/nvme/nvme_disk.c b/drivers/disk/nvme/nvme_disk.c index 3308e04db5b..834a6e2e6c7 100644 --- a/drivers/disk/nvme/nvme_disk.c +++ b/drivers/disk/nvme/nvme_disk.c @@ -34,6 +34,11 @@ static int nvme_disk_read(struct disk_info *disk, uint32_t payload_size; int ret = 0; + if (!NVME_IS_BUFFER_DWORD_ALIGNED(data_buf)) { + LOG_WRN("Data buffer pointer needs to be 4-bytes aligned"); + return -EINVAL; + } + nvme_lock(disk->dev); payload_size = num_sector * nvme_namespace_get_sector_size(ns); @@ -78,6 +83,11 @@ static int nvme_disk_write(struct disk_info *disk, uint32_t payload_size; int ret = 0; + if (!NVME_IS_BUFFER_DWORD_ALIGNED(data_buf)) { + LOG_WRN("Data buffer pointer needs to be 4-bytes aligned"); + return -EINVAL; + } + nvme_lock(disk->dev); payload_size = num_sector * nvme_namespace_get_sector_size(ns); diff --git a/drivers/disk/nvme/nvme_helpers.h b/drivers/disk/nvme/nvme_helpers.h index fb8165be519..325c6e9b842 100644 --- a/drivers/disk/nvme/nvme_helpers.h +++ b/drivers/disk/nvme/nvme_helpers.h @@ -514,4 +514,6 @@ enum shst_value { (mm_reg_t)b_a + nvme_mmio_offsetof(reg) + 4); \ } while (0) +#define NVME_IS_BUFFER_DWORD_ALIGNED(_buf_addr) (!((uintptr_t)_buf_addr & 0x3)) + #endif /* ZEPHYR_DRIVERS_DISK_NVME_NHME_HELPERS_H_ */ From ba02d85c7476fff60e2b37dc0ca09836edb3e128 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Tue, 19 Sep 2023 15:02:16 +0200 Subject: [PATCH 0834/4498] doc/nvme: NVMe mandates dword-aligned buffer addresses In Zephyr, this is let to the disk access API user. There is nothing the driver can do about it. Signed-off-by: Tomasz Bursztyka --- doc/services/storage/disk/nvme.rst | 11 +++++++++++ include/zephyr/storage/disk_access.h | 6 ++++++ tests/drivers/disk/disk_access/src/main.c | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/services/storage/disk/nvme.rst b/doc/services/storage/disk/nvme.rst index 3c6f9713a6a..4f8f94818f2 100644 --- a/doc/services/storage/disk/nvme.rst +++ b/doc/services/storage/disk/nvme.rst @@ -67,3 +67,14 @@ Options Note that NVME requires the target to support PCIe multi-vector MSI-X in order to function. * :kconfig:option:`CONFIG_NVME_MAX_NAMESPACES` + +Important note for users +************************ + +NVMe specifications mandate the data buffer to be placed in a dword (4 bytes) aligned address. +While this is not a problem for advanced OS managing virtual memory and dynamic allocations +below the user processes, this can become an issue in Zephyr as soon as buffer addresses +map directly to physical memory. + +At this stage then, it is up to the user to make sure the buffer address being provided to +:c:func:`disk_access_read` and :c:func:`disk_access_write` are dword aligned. diff --git a/include/zephyr/storage/disk_access.h b/include/zephyr/storage/disk_access.h index 66b513853a7..53774e7666e 100644 --- a/include/zephyr/storage/disk_access.h +++ b/include/zephyr/storage/disk_access.h @@ -63,6 +63,9 @@ int disk_access_status(const char *pdrv); * * Function to read data from disk to a memory buffer. * + * Note: if he disk is of NVMe type, user will need to ensure data_buf + * pointer is 4-bytes aligned. + * * @param[in] pdrv Disk name * @param[in] data_buf Pointer to the memory buffer to put data. * @param[in] start_sector Start disk sector to read from @@ -78,6 +81,9 @@ int disk_access_read(const char *pdrv, uint8_t *data_buf, * * Function write data from memory buffer to disk. * + * Note: if he disk is of NVMe type, user will need to ensure data_buf + * pointer is 4-bytes aligned. + * * @param[in] pdrv Disk name * @param[in] data_buf Pointer to the memory buffer * @param[in] start_sector Start disk sector to write to diff --git a/tests/drivers/disk/disk_access/src/main.c b/tests/drivers/disk/disk_access/src/main.c index 7dd58359f95..97fafae9d8c 100644 --- a/tests/drivers/disk/disk_access/src/main.c +++ b/tests/drivers/disk/disk_access/src/main.c @@ -41,7 +41,8 @@ static const char *disk_pdrv = DISK_NAME; static uint32_t disk_sector_count; static uint32_t disk_sector_size; -static uint8_t scratch_buf[2][SECTOR_COUNT4 * SECTOR_SIZE + 1]; +/* + 4 to make sure the second buffer is dword-aligned for NVME */ +static uint8_t scratch_buf[2][SECTOR_COUNT4 * SECTOR_SIZE + 4]; /* Sets up test by initializing disk */ From e22f634f33a2b0008b8f2c47367c511550ea01c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 19 Sep 2023 17:10:50 +0700 Subject: [PATCH 0835/4498] counter: nxp_pit: support multiple instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for multiple device instances. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_mcux_pit.c | 92 ++++++++++++++---------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/drivers/counter/counter_mcux_pit.c b/drivers/counter/counter_mcux_pit.c index 19bfad4e125..ff60cfb039e 100644 --- a/drivers/counter/counter_mcux_pit.c +++ b/drivers/counter/counter_mcux_pit.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 NXP + * Copyright 2020,2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ struct mcux_pit_config { PIT_Type *base; bool enableRunInDebug; pit_chnl_t pit_channel; + uint32_t pit_period; void (*irq_config_func)(const struct device *dev); }; @@ -144,7 +145,7 @@ static int mcux_pit_set_alarm(const struct device *dev, uint8_t chan_id, uint32_t ticks = alarm_cfg->ticks; - if (chan_id != DT_INST_PROP(0, pit_channel)) { + if (chan_id != config->pit_channel) { LOG_ERR("Invalid channel id"); return -EINVAL; } @@ -168,7 +169,7 @@ static int mcux_pit_cancel_alarm(const struct device *dev, uint8_t chan_id) const struct mcux_pit_config *config = dev->config; struct mcux_pit_data *data = dev->data; - if (chan_id != DT_INST_PROP(0, pit_channel)) { + if (chan_id != config->pit_channel) { LOG_ERR("Invalid channel id"); return -EINVAL; } @@ -194,7 +195,7 @@ static int mcux_pit_init(const struct device *dev) config->irq_config_func(dev); PIT_SetTimerPeriod(config->base, config->pit_channel, - USEC_TO_COUNT(DT_INST_PROP(0, pit_period), + USEC_TO_COUNT(config->pit_period, CLOCK_GetFreq(kCLOCK_BusClk))); return 0; @@ -211,48 +212,43 @@ static const struct counter_driver_api mcux_pit_driver_api = { .get_top_value = mcux_pit_get_top_value, }; -/* - * This driver is single-instance. If the devicetree contains multiple - * instances, this will fail and the driver needs to be revisited. - */ -BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1, - "unsupported pit instance"); - -static struct mcux_pit_data mcux_pit_data_0; - -static void mcux_pit_irq_config_0(const struct device *dev); - -static const struct mcux_pit_config mcux_pit_config_0 = { - .info = { - .max_top_value = UINT32_MAX, - .channels = 1, - .freq = DT_INST_PROP(0, clock_frequency), - }, - .base = (PIT_Type *)DT_INST_REG_ADDR(0), - .pit_channel = DT_INST_PROP(0, pit_channel), - .irq_config_func = mcux_pit_irq_config_0, -}; - -DEVICE_DT_INST_DEFINE(0, &mcux_pit_init, NULL, - &mcux_pit_data_0, &mcux_pit_config_0, POST_KERNEL, - CONFIG_COUNTER_INIT_PRIORITY, &mcux_pit_driver_api); +#define COUNTER_MCUX_PIT_DEVICE(n) \ + static void mcux_pit_irq_config_##n(const struct device *dev); \ + static struct mcux_pit_data mcux_pit_data_##n; \ + static const struct mcux_pit_config mcux_pit_config_##n = { \ + .info = { \ + .max_top_value = UINT32_MAX, \ + .channels = 1, \ + .freq = DT_INST_PROP(n, clock_frequency), \ + }, \ + .base = (PIT_Type *)DT_INST_REG_ADDR(n), \ + .pit_channel = DT_INST_PROP(n, pit_channel), \ + .pit_period = DT_INST_PROP(n, pit_period), \ + .irq_config_func = mcux_pit_irq_config_##n, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &mcux_pit_init, NULL, \ + &mcux_pit_data_##n, &mcux_pit_config_##n, POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, &mcux_pit_driver_api); \ + \ + static void mcux_pit_irq_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 0, irq), \ + DT_INST_IRQ_BY_IDX(0, 0, priority), mcux_pit_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(0, 0, irq)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 1, irq), \ + DT_INST_IRQ_BY_IDX(0, 1, priority), mcux_pit_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(0, 1, irq)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 2, irq), \ + DT_INST_IRQ_BY_IDX(0, 2, priority), mcux_pit_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(0, 2, irq)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 3, irq), \ + DT_INST_IRQ_BY_IDX(0, 3, priority), mcux_pit_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(0, 3, irq)); \ + } -static void mcux_pit_irq_config_0(const struct device *dev) -{ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 0, irq), - DT_INST_IRQ_BY_IDX(0, 0, priority), mcux_pit_isr, - DEVICE_DT_INST_GET(0), 0); - irq_enable(DT_INST_IRQ_BY_IDX(0, 0, irq)); - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 1, irq), - DT_INST_IRQ_BY_IDX(0, 1, priority), mcux_pit_isr, - DEVICE_DT_INST_GET(0), 0); - irq_enable(DT_INST_IRQ_BY_IDX(0, 1, irq)); - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 2, irq), - DT_INST_IRQ_BY_IDX(0, 2, priority), mcux_pit_isr, - DEVICE_DT_INST_GET(0), 0); - irq_enable(DT_INST_IRQ_BY_IDX(0, 2, irq)); - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 3, irq), - DT_INST_IRQ_BY_IDX(0, 3, priority), mcux_pit_isr, - DEVICE_DT_INST_GET(0), 0); - irq_enable(DT_INST_IRQ_BY_IDX(0, 3, irq)); -} +DT_INST_FOREACH_STATUS_OKAY(COUNTER_MCUX_PIT_DEVICE) From d590fb2f782374e14871a5bc9aff6d23eebfd8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 19 Sep 2023 16:53:12 +0700 Subject: [PATCH 0836/4498] counter: nxp_pit: support only top callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This periodic timer (PIT) has a single load value register for each channel, which is currently used for both alarm and top callback APIs. If using both APIs together (which is a valid use-case) it will write to the same register causing unexpected behavior of the timer. The nature of the PIT is to trigger an event (like interrupts) at a certain rate, and not to produce single-shot events. Hence keep only top callback functionality. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_mcux_pit.c | 57 +----------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/drivers/counter/counter_mcux_pit.c b/drivers/counter/counter_mcux_pit.c index ff60cfb039e..df07c28efbf 100644 --- a/drivers/counter/counter_mcux_pit.c +++ b/drivers/counter/counter_mcux_pit.c @@ -24,9 +24,7 @@ struct mcux_pit_config { }; struct mcux_pit_data { - counter_alarm_callback_t alarm_callback; counter_top_callback_t top_callback; - void *alarm_user_data; void *top_user_data; }; @@ -121,7 +119,6 @@ static void mcux_pit_isr(const struct device *dev) const struct mcux_pit_config *config = dev->config; struct mcux_pit_data *data = dev->data; uint32_t flags; - uint32_t current = 0; LOG_DBG("pit counter isr"); flags = PIT_GetStatusFlags(config->base, config->pit_channel); @@ -129,56 +126,6 @@ static void mcux_pit_isr(const struct device *dev) if (data->top_callback) { data->top_callback(dev, data->top_user_data); } - if (data->alarm_callback) { - PIT_StopTimer(config->base, config->pit_channel); - mcux_pit_get_value(dev, ¤t); - data->alarm_callback(dev, config->pit_channel, current, - data->alarm_user_data); - } -} - -static int mcux_pit_set_alarm(const struct device *dev, uint8_t chan_id, - const struct counter_alarm_cfg *alarm_cfg) -{ - const struct mcux_pit_config *config = dev->config; - struct mcux_pit_data *data = dev->data; - - uint32_t ticks = alarm_cfg->ticks; - - if (chan_id != config->pit_channel) { - LOG_ERR("Invalid channel id"); - return -EINVAL; - } - - if (ticks > mcux_pit_get_top_value(dev)) { - LOG_ERR("Invalid ticks"); - return -EINVAL; - } - - PIT_StopTimer(config->base, chan_id); - PIT_SetTimerPeriod(config->base, chan_id, ticks); - data->alarm_callback = alarm_cfg->callback; - data->alarm_user_data = alarm_cfg->user_data; - LOG_DBG("set alarm to %d", ticks); - PIT_StartTimer(config->base, chan_id); - return 0; -} - -static int mcux_pit_cancel_alarm(const struct device *dev, uint8_t chan_id) -{ - const struct mcux_pit_config *config = dev->config; - struct mcux_pit_data *data = dev->data; - - if (chan_id != config->pit_channel) { - LOG_ERR("Invalid channel id"); - return -EINVAL; - } - - PIT_DisableInterrupts(config->base, chan_id, kPIT_TimerInterruptEnable); - PIT_StopTimer(config->base, chan_id); - data->alarm_callback = NULL; - - return 0; } static int mcux_pit_init(const struct device *dev) @@ -206,8 +153,6 @@ static const struct counter_driver_api mcux_pit_driver_api = { .stop = mcux_pit_stop, .get_value = mcux_pit_get_value, .set_top_value = mcux_pit_set_top_value, - .set_alarm = mcux_pit_set_alarm, - .cancel_alarm = mcux_pit_cancel_alarm, .get_pending_int = mcux_pit_get_pending_int, .get_top_value = mcux_pit_get_top_value, }; @@ -218,7 +163,7 @@ static const struct counter_driver_api mcux_pit_driver_api = { static const struct mcux_pit_config mcux_pit_config_##n = { \ .info = { \ .max_top_value = UINT32_MAX, \ - .channels = 1, \ + .channels = 0, \ .freq = DT_INST_PROP(n, clock_frequency), \ }, \ .base = (PIT_Type *)DT_INST_REG_ADDR(n), \ From f8e16ae81a4d6cbe1a3f68186e9da10303f69a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 19 Sep 2023 17:24:25 +0700 Subject: [PATCH 0837/4498] counter: nxp_pit: support flexible number of interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on the SoC design, the PIT channel interrupts can be individual or OR'ed together to a single interrupt line. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_mcux_pit.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/counter/counter_mcux_pit.c b/drivers/counter/counter_mcux_pit.c index df07c28efbf..311529074c9 100644 --- a/drivers/counter/counter_mcux_pit.c +++ b/drivers/counter/counter_mcux_pit.c @@ -157,6 +157,16 @@ static const struct counter_driver_api mcux_pit_driver_api = { .get_top_value = mcux_pit_get_top_value, }; +#define COUNTER_MCUX_PIT_IRQ_CONFIG(idx, n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + DT_INST_IRQ_BY_IDX(n, idx, priority), \ + mcux_pit_isr, DEVICE_DT_INST_GET(n), \ + COND_CODE_1(DT_INST_IRQ_HAS_NAME(n, flags), \ + (DT_INST_IRQ_BY_IDX(n, idx, flags)), (0))); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ + } while (0) + #define COUNTER_MCUX_PIT_DEVICE(n) \ static void mcux_pit_irq_config_##n(const struct device *dev); \ static struct mcux_pit_data mcux_pit_data_##n; \ @@ -178,22 +188,8 @@ static const struct counter_driver_api mcux_pit_driver_api = { \ static void mcux_pit_irq_config_##n(const struct device *dev) \ { \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 0, irq), \ - DT_INST_IRQ_BY_IDX(0, 0, priority), mcux_pit_isr, \ - DEVICE_DT_INST_GET(0), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(0, 0, irq)); \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 1, irq), \ - DT_INST_IRQ_BY_IDX(0, 1, priority), mcux_pit_isr, \ - DEVICE_DT_INST_GET(0), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(0, 1, irq)); \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 2, irq), \ - DT_INST_IRQ_BY_IDX(0, 2, priority), mcux_pit_isr, \ - DEVICE_DT_INST_GET(0), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(0, 2, irq)); \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 3, irq), \ - DT_INST_IRQ_BY_IDX(0, 3, priority), mcux_pit_isr, \ - DEVICE_DT_INST_GET(0), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(0, 3, irq)); \ + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \ + COUNTER_MCUX_PIT_IRQ_CONFIG, (;), n); \ } DT_INST_FOREACH_STATUS_OKAY(COUNTER_MCUX_PIT_DEVICE) From ddaacd9ee8138aba85bdd3611e2c5dbf8612a922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 19 Sep 2023 18:27:53 +0700 Subject: [PATCH 0838/4498] counter: nxp_pit: allow to specify max load value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIT maximum load value may not be always 32-bit. Allow the SoC to define this value from devicetree. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_mcux_pit.c | 2 +- dts/arm/nxp/nxp_k6x.dtsi | 1 + dts/arm/nxp/nxp_k8x.dtsi | 1 + dts/bindings/rtc/nxp,kinetis-pit.yaml | 7 ++++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/counter/counter_mcux_pit.c b/drivers/counter/counter_mcux_pit.c index 311529074c9..7603f9bd544 100644 --- a/drivers/counter/counter_mcux_pit.c +++ b/drivers/counter/counter_mcux_pit.c @@ -172,7 +172,7 @@ static const struct counter_driver_api mcux_pit_driver_api = { static struct mcux_pit_data mcux_pit_data_##n; \ static const struct mcux_pit_config mcux_pit_config_##n = { \ .info = { \ - .max_top_value = UINT32_MAX, \ + .max_top_value = DT_INST_PROP(n, max_load_value), \ .channels = 0, \ .freq = DT_INST_PROP(n, clock_frequency), \ }, \ diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index 91a5a2e32e1..a0ea8bdbf1a 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -536,6 +536,7 @@ pit-channel = <0>; pit-period = <1000000>; clock-frequency = <60000000>; + max-load-value = <0xffffffff>; }; }; }; diff --git a/dts/arm/nxp/nxp_k8x.dtsi b/dts/arm/nxp/nxp_k8x.dtsi index effa5b0c37c..e9f6bf7aff8 100644 --- a/dts/arm/nxp/nxp_k8x.dtsi +++ b/dts/arm/nxp/nxp_k8x.dtsi @@ -395,6 +395,7 @@ pit-channel = <0>; pit-period = <1000000>; clock-frequency = <60000000>; + max-load-value = <0xffffffff>; }; edma0: dma-controller@40008000 { diff --git a/dts/bindings/rtc/nxp,kinetis-pit.yaml b/dts/bindings/rtc/nxp,kinetis-pit.yaml index 6d2f478ecb0..37d6d7ebd41 100644 --- a/dts/bindings/rtc/nxp,kinetis-pit.yaml +++ b/dts/bindings/rtc/nxp,kinetis-pit.yaml @@ -1,4 +1,4 @@ -# Copyright 2020 NXP +# Copyright 2020,2023 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP MCUX Periodic Interrupt Timer (PIT) @@ -20,3 +20,8 @@ properties: type: int required: true description: pit default period in us + + max-load-value: + type: int + required: true + description: maximum load value supported From 45c8cb234330ad2ca933eabad69b9b10a7c5b529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 19 Sep 2023 18:49:40 +0700 Subject: [PATCH 0839/4498] counter: nxp_pit: use clock control to obtain module's clock rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use standard clock control API to retrieve the PIT clock rate instead of using the HAL. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_mcux_pit.c | 34 +++++++++++++++++++++++---- dts/arm/nxp/nxp_k6x.dtsi | 1 - dts/arm/nxp/nxp_k8x.dtsi | 1 - dts/bindings/rtc/nxp,kinetis-pit.yaml | 3 +++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/counter/counter_mcux_pit.c b/drivers/counter/counter_mcux_pit.c index 7603f9bd544..94e57bd4325 100644 --- a/drivers/counter/counter_mcux_pit.c +++ b/drivers/counter/counter_mcux_pit.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT nxp_kinetis_pit #include +#include #include #include @@ -21,6 +22,8 @@ struct mcux_pit_config { pit_chnl_t pit_channel; uint32_t pit_period; void (*irq_config_func)(const struct device *dev); + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; }; struct mcux_pit_data { @@ -114,6 +117,19 @@ static uint32_t mcux_pit_get_pending_int(const struct device *dev) return ((flags & mask) == mask); } +static uint32_t mcux_pit_get_frequency(const struct device *dev) +{ + const struct mcux_pit_config *config = dev->config; + uint32_t clock_rate; + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_rate)) { + LOG_ERR("Failed to get clock rate"); + return 0; + } + + return clock_rate; +} + static void mcux_pit_isr(const struct device *dev) { const struct mcux_pit_config *config = dev->config; @@ -130,9 +146,14 @@ static void mcux_pit_isr(const struct device *dev) static int mcux_pit_init(const struct device *dev) { - const struct mcux_pit_config *config = - (struct mcux_pit_config *)dev->config; + const struct mcux_pit_config *config = dev->config; pit_config_t pit_config; + uint32_t clock_rate; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock control device not ready"); + return -ENODEV; + } PIT_GetDefaultConfig(&pit_config); pit_config.enableRunInDebug = config->enableRunInDebug; @@ -141,9 +162,9 @@ static int mcux_pit_init(const struct device *dev) config->irq_config_func(dev); + clock_rate = mcux_pit_get_frequency(dev); PIT_SetTimerPeriod(config->base, config->pit_channel, - USEC_TO_COUNT(config->pit_period, - CLOCK_GetFreq(kCLOCK_BusClk))); + USEC_TO_COUNT(config->pit_period, clock_rate)); return 0; } @@ -155,6 +176,7 @@ static const struct counter_driver_api mcux_pit_driver_api = { .set_top_value = mcux_pit_set_top_value, .get_pending_int = mcux_pit_get_pending_int, .get_top_value = mcux_pit_get_top_value, + .get_freq = mcux_pit_get_frequency, }; #define COUNTER_MCUX_PIT_IRQ_CONFIG(idx, n) \ @@ -174,12 +196,14 @@ static const struct counter_driver_api mcux_pit_driver_api = { .info = { \ .max_top_value = DT_INST_PROP(n, max_load_value), \ .channels = 0, \ - .freq = DT_INST_PROP(n, clock_frequency), \ }, \ .base = (PIT_Type *)DT_INST_REG_ADDR(n), \ .pit_channel = DT_INST_PROP(n, pit_channel), \ .pit_period = DT_INST_PROP(n, pit_period), \ .irq_config_func = mcux_pit_irq_config_##n, \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL(n, name), \ }; \ \ DEVICE_DT_INST_DEFINE(n, &mcux_pit_init, NULL, \ diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index a0ea8bdbf1a..661be1478c8 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -535,7 +535,6 @@ status = "disabled"; pit-channel = <0>; pit-period = <1000000>; - clock-frequency = <60000000>; max-load-value = <0xffffffff>; }; }; diff --git a/dts/arm/nxp/nxp_k8x.dtsi b/dts/arm/nxp/nxp_k8x.dtsi index e9f6bf7aff8..61e0cd1fc39 100644 --- a/dts/arm/nxp/nxp_k8x.dtsi +++ b/dts/arm/nxp/nxp_k8x.dtsi @@ -394,7 +394,6 @@ status = "disabled"; pit-channel = <0>; pit-period = <1000000>; - clock-frequency = <60000000>; max-load-value = <0xffffffff>; }; diff --git a/dts/bindings/rtc/nxp,kinetis-pit.yaml b/dts/bindings/rtc/nxp,kinetis-pit.yaml index 37d6d7ebd41..ad3ee44ab4c 100644 --- a/dts/bindings/rtc/nxp,kinetis-pit.yaml +++ b/dts/bindings/rtc/nxp,kinetis-pit.yaml @@ -11,6 +11,9 @@ properties: reg: required: true + clocks: + required: true + pit-channel: type: int required: true From ac050455c51e542e6dd852ceaff82c8f58de99c9 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 15 Sep 2023 16:02:21 +0200 Subject: [PATCH 0840/4498] Bluetooth: Mesh: Fix printing device UUID IS_ENABLED was incorrectly used here. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/prov_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 48d852cb1a7..20735f49fa5 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -675,7 +675,7 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } -#if IS_ENABLED(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) +#if defined(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) if (CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL > 2) { struct bt_uuid_128 uuid = { .uuid = { BT_UUID_TYPE_128 } }; From b4998c357e43ff99714dc9f33ea5721e397557b1 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 20 Sep 2023 14:02:48 +0300 Subject: [PATCH 0841/4498] mm_drv: tlb: Fix compile time warning This fixes the following compile time warning; drivers/mm/mm_drv_intel_adsp_mtl_tlb.c: In function 'sys_mm_drv_mm_init': include/zephyr/sys/__assert.h:44:52: error: format '%p' expects argument of type 'void *', but argument 2 has type 'long unsigned int' [-Werror=format=] __ASSERT_PRINT("\t" fmt "\n", ##__VA_ARGS__) Signed-off-by: Daniel Baluta --- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index 6e9b75b11f7..899b75cefe4 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -668,7 +668,7 @@ static int sys_mm_drv_mm_init(const struct device *dev) __ASSERT(false, "unused l2 pointer is outside of l2 sram range %p\n", - UNUSED_L2_START_ALIGNED); + (void *)UNUSED_L2_START_ALIGNED); return -EFAULT; } From be08ce18d0ba6a03e007291c02466b0b8718e219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 18 Sep 2023 12:14:45 +0700 Subject: [PATCH 0842/4498] wdt: nxp_s32: use clock control APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use clock control API to retrieve the module's frequency and update the boards using it to provide the source clocks. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 17 ---------- drivers/watchdog/Kconfig.nxp_s32 | 3 +- drivers/watchdog/wdt_nxp_s32.c | 34 ++++++++++++++++--- dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi | 7 +++- dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi | 7 +++- dts/bindings/watchdog/nxp,s32-swt.yaml | 6 ++-- 6 files changed, 45 insertions(+), 29 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 59c46f7896b..a0dc5df74c3 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -64,26 +64,9 @@ }; &swt0 { - clock-frequency = <48000000>; status = "okay"; }; -&swt1 { - clock-frequency = <48000000>; -}; - -&swt2 { - clock-frequency = <48000000>; -}; - -&swt3 { - clock-frequency = <48000000>; -}; - -&swt4 { - clock-frequency = <48000000>; -}; - &emdio { pinctrl-0 = <&emdio_default>; pinctrl-names = "default"; diff --git a/drivers/watchdog/Kconfig.nxp_s32 b/drivers/watchdog/Kconfig.nxp_s32 index 3f2dd42efb5..1db0a208b38 100644 --- a/drivers/watchdog/Kconfig.nxp_s32 +++ b/drivers/watchdog/Kconfig.nxp_s32 @@ -1,10 +1,11 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 config WDT_NXP_S32 bool "NXP S32 SWT driver" default y depends on DT_HAS_NXP_S32_SWT_ENABLED + select CLOCK_CONTROL select NOCACHE_MEMORY help Enable the Software Watchdog Timer (SWT) driver. diff --git a/drivers/watchdog/wdt_nxp_s32.c b/drivers/watchdog/wdt_nxp_s32.c index 0b41d52312a..2d380264b94 100644 --- a/drivers/watchdog/wdt_nxp_s32.c +++ b/drivers/watchdog/wdt_nxp_s32.c @@ -1,10 +1,11 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include #include @@ -16,8 +17,9 @@ LOG_MODULE_REGISTER(swt_nxp_s32); #define PARAM_UNUSED 0 struct swt_nxp_s32_config { - uint32_t clock_freq; uint8_t instance; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; }; struct swt_nxp_s32_data { @@ -76,18 +78,26 @@ static int swt_nxp_s32_install_timeout(const struct device *dev, { const struct swt_nxp_s32_config *config = dev->config; struct swt_nxp_s32_data *data = dev->data; + uint32_t clock_rate; + int err; if (data->timeout_valid) { LOG_ERR("No more timeouts can be installed"); return -ENOMEM; } - data->swt_config.u32TimeoutValue = config->clock_freq / 1000U * cfg->window.max; + err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_rate); + if (err) { + LOG_ERR("Failed to get module clock frequency"); + return err; + } + + data->swt_config.u32TimeoutValue = clock_rate / 1000U * cfg->window.max; if (cfg->window.min) { data->swt_config.bEnWindow = true; data->swt_config.u32WindowValue = - config->clock_freq / 1000U * (cfg->window.max - cfg->window.min); + clock_rate / 1000U * (cfg->window.max - cfg->window.min); } else { data->swt_config.bEnWindow = false; data->swt_config.u32WindowValue = 0; @@ -161,12 +171,26 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { }, \ }; \ static const struct swt_nxp_s32_config swt_nxp_s32_config_##n = { \ - .clock_freq = DT_PROP(SWT_NODE(n), clock_frequency), \ .instance = (uint8_t)(RTU_SWT(n)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SWT_NODE(n))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_CLOCKS_CELL(SWT_NODE(n), name), \ }; \ \ static int swt_nxp_s32_##n##_init(const struct device *dev) \ { \ + const struct swt_nxp_s32_config *config = dev->config; \ + int err; \ + \ + if (!device_is_ready(config->clock_dev)) { \ + return -ENODEV; \ + } \ + \ + err = clock_control_on(config->clock_dev, config->clock_subsys);\ + if (err) { \ + return err; \ + } \ + \ IRQ_CONNECT(DT_IRQN(SWT_NODE(n)), \ DT_IRQ(SWT_NODE(n), priority), \ Swt_Ip_IrqHandler, \ diff --git a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi index 4c429b535e9..bc8ff76a850 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,6 +48,7 @@ compatible = "nxp,s32-swt"; reg = <0x76000000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -55,6 +56,7 @@ compatible = "nxp,s32-swt"; reg = <0x76010000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -62,6 +64,7 @@ compatible = "nxp,s32-swt"; reg = <0x76220000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -69,6 +72,7 @@ compatible = "nxp,s32-swt"; reg = <0x76230000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -76,6 +80,7 @@ compatible = "nxp,s32-swt"; reg = <0x76140000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; }; diff --git a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi index a399f1b1e00..dd2e41d8464 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,6 +48,7 @@ compatible = "nxp,s32-swt"; reg = <0x76800000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -55,6 +56,7 @@ compatible = "nxp,s32-swt"; reg = <0x76810000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -62,6 +64,7 @@ compatible = "nxp,s32-swt"; reg = <0x76a20000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -69,6 +72,7 @@ compatible = "nxp,s32-swt"; reg = <0x76a30000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; @@ -76,6 +80,7 @@ compatible = "nxp,s32-swt"; reg = <0x76940000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; }; diff --git a/dts/bindings/watchdog/nxp,s32-swt.yaml b/dts/bindings/watchdog/nxp,s32-swt.yaml index 25fbbaa2f30..39179aaf5bc 100644 --- a/dts/bindings/watchdog/nxp,s32-swt.yaml +++ b/dts/bindings/watchdog/nxp,s32-swt.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 description: Software Watchdog Timer (SWT) @@ -14,7 +14,5 @@ properties: interrupts: required: true - clock-frequency: - type: int + clocks: required: true - description: Software Watchdog Timer module clock frequency, in Hz. From cdcba384bc544cd9859cf1e635cb8d5cbe002633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 15 Sep 2023 18:54:28 +0700 Subject: [PATCH 0843/4498] spi: nxp_s32: use clock control APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use clock control API to retrieve the module's frequency and update the boards using it to provide the source clocks. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 40 ----------------- drivers/spi/spi_nxp_s32.c | 43 +++++++++++++++---- drivers/spi/spi_nxp_s32.h | 5 ++- dts/arm/nxp/nxp_s32z27x_r52.dtsi | 10 +++++ dts/bindings/spi/nxp,s32-spi.yaml | 7 +-- 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index a0dc5df74c3..0176ebc4458 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -7,46 +7,6 @@ #include #include "s32z270dc2_r52-pinctrl-common.dtsi" -&spi0 { - clock-frequency = <100000000>; -}; - -&spi1 { - clock-frequency = <100000000>; -}; - -&spi2 { - clock-frequency = <100000000>; -}; - -&spi3 { - clock-frequency = <120000000>; -}; - -&spi4 { - clock-frequency = <120000000>; -}; - -&spi5 { - clock-frequency = <120000000>; -}; - -&spi6 { - clock-frequency = <120000000>; -}; - -&spi7 { - clock-frequency = <100000000>; -}; - -&spi8 { - clock-frequency = <100000000>; -}; - -&spi9 { - clock-frequency = <100000000>; -}; - &stm0 { clock-frequency = <133333333>; }; diff --git a/drivers/spi/spi_nxp_s32.c b/drivers/spi/spi_nxp_s32.c index 30dbe4d134a..f0d59ea443d 100644 --- a/drivers/spi/spi_nxp_s32.c +++ b/drivers/spi/spi_nxp_s32.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include "spi_nxp_s32.h" @@ -273,12 +274,20 @@ static int spi_nxp_s32_configure(const struct device *dev, uint8_t frame_size; struct spi_nxp_s32_baudrate_param best_baud = {0}; + uint32_t clock_rate; + int err; if (spi_context_configured(&data->ctx, spi_cfg)) { /* This configuration is already in use */ return 0; } + err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_rate); + if (err) { + LOG_ERR("Failed to get clock frequency"); + return err; + } + clk_phase = !!(SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA); clk_polarity = !!(SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL); @@ -340,7 +349,7 @@ static int spi_nxp_s32_configure(const struct device *dev, return -ENOTSUP; } - spi_nxp_s32_getbestfreq(config->clock_frequency, spi_cfg->frequency, &best_baud); + spi_nxp_s32_getbestfreq(clock_rate, spi_cfg->frequency, &best_baud); data->transfer_cfg.Ctar &= ~(SPI_CTAR_BR_MASK | SPI_CTAR_PBR_MASK); data->transfer_cfg.Ctar |= SPI_CTAR_BR(best_baud.scaler) | @@ -486,12 +495,29 @@ static int spi_nxp_s32_init(const struct device *dev) { const struct spi_nxp_s32_config *config = dev->config; struct spi_nxp_s32_data *data = dev->data; - + uint32_t clock_rate; uint8_t scaler, prescaler; uint32_t ctar = 0; int ret = 0; + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock control device not ready"); + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret) { + LOG_ERR("Failed to enable clock"); + return ret; + } + + ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_rate); + if (ret) { + LOG_ERR("Failed to get clock frequency"); + return ret; + } + ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; @@ -513,18 +539,15 @@ static int spi_nxp_s32_init(const struct device *dev) * Update the delay timings configuration that are * applied for all inner CS signals of SPI module. */ - spi_nxp_s32_getbestdelay(config->clock_frequency, - config->sck_cs_delay, &scaler, &prescaler); + spi_nxp_s32_getbestdelay(clock_rate, config->sck_cs_delay, &scaler, &prescaler); ctar |= SPI_CTAR_ASC(scaler) | SPI_CTAR_PASC(prescaler); - spi_nxp_s32_getbestdelay(config->clock_frequency, - config->cs_sck_delay, &scaler, &prescaler); + spi_nxp_s32_getbestdelay(clock_rate, config->cs_sck_delay, &scaler, &prescaler); ctar |= SPI_CTAR_CSSCK(scaler) | SPI_CTAR_PCSSCK(prescaler); - spi_nxp_s32_getbestdelay(config->clock_frequency, - config->cs_cs_delay, &scaler, &prescaler); + spi_nxp_s32_getbestdelay(clock_rate, config->cs_cs_delay, &scaler, &prescaler); ctar |= SPI_CTAR_DT(scaler) | SPI_CTAR_PDT(prescaler); @@ -654,7 +677,9 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { static const struct spi_nxp_s32_config spi_nxp_s32_config_##n = { \ .instance = n, \ .num_cs = SPI_NXP_S32_NUM_CS(n), \ - .clock_frequency = DT_PROP(SPI_NXP_S32_NODE(n), clock_frequency), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SPI_NXP_S32_NODE(n))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_CLOCKS_CELL(SPI_NXP_S32_NODE(n), name), \ .sck_cs_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_sck_cs_delay, 0U), \ .cs_sck_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_cs_sck_delay, 0U), \ .cs_cs_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_cs_cs_delay, 0U), \ diff --git a/drivers/spi/spi_nxp_s32.h b/drivers/spi/spi_nxp_s32.h index 39bf630e646..3d01d1625bf 100644 --- a/drivers/spi/spi_nxp_s32.h +++ b/drivers/spi/spi_nxp_s32.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,7 +49,8 @@ struct spi_nxp_s32_data { struct spi_nxp_s32_config { uint8_t instance; uint8_t num_cs; - uint32_t clock_frequency; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; uint32_t sck_cs_delay; uint32_t cs_sck_delay; uint32_t cs_cs_delay; diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 5728e3e3ff9..691df7750f5 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -457,6 +457,7 @@ compatible = "nxp,s32-spi"; reg = <0x40130000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI0_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -467,6 +468,7 @@ compatible = "nxp,s32-spi"; reg = <0x40140000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI1_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -477,6 +479,7 @@ compatible = "nxp,s32-spi"; reg = <0x40930000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI2_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -487,6 +490,7 @@ compatible = "nxp,s32-spi"; reg = <0x40940000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI3_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -497,6 +501,7 @@ compatible = "nxp,s32-spi"; reg = <0x40950000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI4_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -507,6 +512,7 @@ compatible = "nxp,s32-spi"; reg = <0x42130000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI5_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -517,6 +523,7 @@ compatible = "nxp,s32-spi"; reg = <0x42140000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI6_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -527,6 +534,7 @@ compatible = "nxp,s32-spi"; reg = <0x42150000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI7_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -537,6 +545,7 @@ compatible = "nxp,s32-spi"; reg = <0x42930000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI8_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; @@ -547,6 +556,7 @@ compatible = "nxp,s32-spi"; reg = <0x42940000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_SPI9_CLK>; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/bindings/spi/nxp,s32-spi.yaml b/dts/bindings/spi/nxp,s32-spi.yaml index 722b3add3db..f505da6d8d1 100644 --- a/dts/bindings/spi/nxp,s32-spi.yaml +++ b/dts/bindings/spi/nxp,s32-spi.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP S32 SPI controller @@ -20,11 +20,8 @@ properties: description: | The number of the Chip Select signals. - clock-frequency: - type: int + clocks: required: true - description: | - Module clock frequency in Hz. pinctrl-0: required: true From c57fa2c231ba1628f23241444f93a62a54c2be75 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Mon, 11 Sep 2023 15:02:48 +0800 Subject: [PATCH 0844/4498] arch: arm64: Fix the cache coherence issue Accessing mem before mmu or mpu init will cause a cache coherence issue. To avoid such a problem, move the safe exception stack init function after the mmu or mpu is initiated. Also change the data section attribute from INNER_SHAREABLE to OUTER_SHAREABLE. Otherwise there will be a cache coherence issue during the memory regions switch. Because we are using background region to do the regions switch, and the default background region is OUTER_SHAREABLE, if we use INNER_SHAREABLE as the foreground region, then we have to flush all cache regions to make sure the cached values are right. However, flushing all regions is too heavy, so we set OUTER_SHAREABLE to fix this issue. Signed-off-by: Jaxson Han --- arch/arm64/core/smp.c | 5 +++-- include/zephyr/arch/arm64/cortex_r/arm_mpu.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index 3fdb1b333d5..6d21e5e9d7b 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -141,12 +141,13 @@ void z_arm64_secondary_start(void) /* Initialize tpidrro_el0 with our struct _cpu instance address */ write_tpidrro_el0((uintptr_t)&_kernel.cpus[cpu_num]); + + z_arm64_mm_init(false); + #ifdef CONFIG_ARM64_SAFE_EXCEPTION_STACK z_arm64_safe_exception_stack_init(); #endif - z_arm64_mm_init(false); - #ifdef CONFIG_SMP arm_gic_secondary_init(); diff --git a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h index 74426005fb7..077b6664fb1 100644 --- a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h +++ b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h @@ -143,7 +143,7 @@ #define REGION_RAM_ATTR \ { \ /* AP, XN, SH */ \ - .rbar = NOT_EXEC | P_RW_U_NA_Msk | INNER_SHAREABLE_Msk, \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | OUTER_SHAREABLE_Msk, \ /* Cache-ability */ \ .mair_idx = MPU_MAIR_INDEX_SRAM, \ } From 1ac3d1cc5e32e6c03cb62c1cec2757afb1e702eb Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Sat, 16 Sep 2023 15:26:45 +0800 Subject: [PATCH 0845/4498] arch: arm64: thread: Clean thread arch when creating thread Clean the thread->arch during the arch_new_thread to avoid unexpected behavior. If the thread struct is allocated from heap or in stack, the data in thread->arch might be dirty. Signed-off-by: Jaxson Han --- arch/arm64/core/thread.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index e8902d505e7..a0e604ef979 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -69,6 +69,12 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, extern void z_arm64_exit_exc(void); z_arch_esf_t *pInitCtx; + /* + * Clean the thread->arch to avoid unexpected behavior because the + * thread->arch might be dirty + */ + memset(&thread->arch, 0, sizeof(thread->arch)); + /* * The ESF is now hosted at the top of the stack. For user threads this * is also fine because at this stage they are still running in EL1. @@ -100,9 +106,6 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, pInitCtx->elr = (uint64_t)z_thread_entry; } -#if defined(CONFIG_ARM_MPU) - atomic_clear(&thread->arch.flushing); -#endif #else pInitCtx->elr = (uint64_t)z_thread_entry; #endif From 1fe9a06d8bd4bcfc0fa5ea59d222cb58ddac0830 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Fri, 20 Jan 2023 10:29:38 +0800 Subject: [PATCH 0846/4498] arch: arm64: Kconfig: Introduce ARM64_STACK_PROTECTION Introduce the ARM64_STACK_PROTECTION config. This option leverages the MMU or MPU to cause a system fatal error if the bounds of the current process stack are overflowed. This is done by preceding all stack areas with a fixed guard region. The config depends on MPU for now since MMU stack protection is not ready. Signed-off-by: Jaxson Han --- arch/arm64/core/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index e0963211238..6aa996bb0fb 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -168,6 +168,17 @@ config ARM64_FALLBACK_ON_RESERVED_CORES then that core will be skipped and the next core in the device tree will be used. +config ARM64_STACK_PROTECTION + bool + default y if HW_STACK_PROTECTION + depends on ARM_MPU + select THREAD_STACK_INFO + select ARM64_SAFE_EXCEPTION_STACK + help + This option leverages the MMU or MPU to cause a system fatal error if + the bounds of the current process stack are overflowed. This is done + by preceding all stack areas with a fixed guard region. + if CPU_CORTEX_A config ARMV8_A_NS From d4dd47b9c5bf716f07f0656f90c8688dd62baee9 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Fri, 20 Jan 2023 10:53:51 +0800 Subject: [PATCH 0847/4498] arch: arm64: Add stack check at z_arm64_fatal_error Add the stack check function z_arm64_stack_corruption_check at z_arm64_fatal_error to handle the stack overflow triggered by the hardware region. Signed-off-by: Jaxson Han --- arch/arm64/core/fatal.c | 52 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/arch/arm64/core/fatal.c b/arch/arm64/core/fatal.c index 8a36c50f506..1139a818e1f 100644 --- a/arch/arm64/core/fatal.c +++ b/arch/arm64/core/fatal.c @@ -18,6 +18,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -233,6 +234,47 @@ static void esf_unwind(const z_arch_esf_t *esf) #endif /* CONFIG_EXCEPTION_DEBUG */ +#ifdef CONFIG_ARM64_STACK_PROTECTION +static bool z_arm64_stack_corruption_check(z_arch_esf_t *esf, uint64_t esr, uint64_t far) +{ + uint64_t sp, sp_limit, guard_start; + /* 0x25 means data abort from current EL */ + if (GET_ESR_EC(esr) == 0x25) { + sp_limit = arch_curr_cpu()->arch.current_stack_limit; + guard_start = sp_limit - Z_ARM64_STACK_GUARD_SIZE; + sp = arch_curr_cpu()->arch.corrupted_sp; + if ((sp != 0 && sp <= sp_limit) || (guard_start <= far && far <= sp_limit)) { +#ifdef CONFIG_FPU_SHARING + /* + * We are in exception stack, and now we are sure the stack does overflow, + * so flush the fpu context to its owner, and then set no fpu trap to avoid + * a new nested exception triggered by FPU accessing (var_args). + */ + z_arm64_flush_local_fpu(); + write_cpacr_el1(read_cpacr_el1() | CPACR_EL1_FPEN_NOTRAP); +#endif + arch_curr_cpu()->arch.corrupted_sp = 0UL; + LOG_ERR("STACK OVERFLOW FROM KERNEL, SP: 0x%llx OR FAR: 0x%llx INVALID," + " SP LIMIT: 0x%llx", sp, far, sp_limit); + return true; + } + } +#ifdef CONFIG_USERSPACE + else if ((_current->base.user_options & K_USER) != 0 && GET_ESR_EC(esr) == 0x24) { + sp_limit = (uint64_t)_current->stack_info.start; + guard_start = sp_limit - Z_ARM64_STACK_GUARD_SIZE; + sp = esf->sp; + if (sp <= sp_limit || (guard_start <= far && far <= sp_limit)) { + LOG_ERR("STACK OVERFLOW FROM USERSPACE, SP: 0x%llx OR FAR: 0x%llx INVALID," + " SP LIMIT: 0x%llx", sp, far, sp_limit); + return true; + } + } +#endif + return false; +} +#endif + static bool is_recoverable(z_arch_esf_t *esf, uint64_t esr, uint64_t far, uint64_t elr) { @@ -278,6 +320,12 @@ void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf) break; } +#ifdef CONFIG_ARM64_STACK_PROTECTION + if (z_arm64_stack_corruption_check(esf, esr, far)) { + reason = K_ERR_STACK_CHK_FAIL; + } +#endif + if (GET_EL(el) != MODE_EL0) { #ifdef CONFIG_EXCEPTION_DEBUG bool dump_far = false; @@ -292,8 +340,10 @@ void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf) LOG_ERR("TPIDRRO: 0x%016llx", read_tpidrro_el0()); #endif /* CONFIG_EXCEPTION_DEBUG */ - if (is_recoverable(esf, esr, far, elr)) + if (is_recoverable(esf, esr, far, elr) && + reason != K_ERR_STACK_CHK_FAIL) { return; + } } } From d3ec98806d812d3332456021da97d61b7257cc46 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Fri, 20 Jan 2023 11:46:31 +0800 Subject: [PATCH 0848/4498] arch: arm64: Refactor the stack relevant macros Refactor the stack relevant macros to prepare to introduce the stack guard. Also add comments about the changes related to stack layout. Signed-off-by: Jaxson Han --- arch/arm64/core/reset.S | 3 ++- arch/arm64/core/thread.c | 28 ++++++++++++++++++++---- include/zephyr/arch/arm64/thread_stack.h | 21 +++++++++++++----- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/arch/arm64/core/reset.S b/arch/arm64/core/reset.S index 387e82b341a..9b3b4462e85 100644 --- a/arch/arm64/core/reset.S +++ b/arch/arm64/core/reset.S @@ -7,6 +7,7 @@ #include #include #include +#include #include "boot.h" #include "macro_priv.inc" @@ -149,7 +150,7 @@ resetwait: primary_core: #endif /* load primary stack and entry point */ - ldr x24, =(z_interrupt_stacks + CONFIG_ISR_STACK_SIZE) + ldr x24, =(z_interrupt_stacks + __z_interrupt_stack_SIZEOF) ldr x25, =z_arm64_prep_c 2: /* Prepare for calling C code */ diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index a0e604ef979..4bb77626a73 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -28,19 +28,35 @@ * normal execution. When at exception is taken or a syscall is called the * stack pointer switches to SP_EL1 and the execution starts using the * privileged portion of the user stack without touching SP_EL0. This portion - * is marked as not user accessible in the MMU. + * is marked as not user accessible in the MMU/MPU. + * + * - a stack guard region will be added bellow the kernel stack when + * ARM64_STACK_PROTECTION is enabled. In this case, SP_EL0 will always point + * to the safe exception stack in the kernel space. For the kernel thread, + * SP_EL0 will not change always pointing to safe exception stack. For the + * userspace thread, SP_EL0 will switch from the user stack to the safe + * exception stack when entering the EL1 mode, and restore to the user stack + * when backing to userspace (EL0). * * Kernel threads: * + * High memory addresses + * * +---------------+ <- stack_ptr * E | ESF | * L |<<<<<<<<<<<<<<<| <- SP_EL1 * 1 | | - * +---------------+ - + * +---------------+ <- stack limit + * | Stack guard | } Z_ARM64_STACK_GUARD_SIZE (protected by MMU/MPU) + * +---------------+ <- stack_obj + * + * Low Memory addresses + * * * User threads: * + * High memory addresses + * * +---------------+ <- stack_ptr * E | | * L |<<<<<<<<<<<<<<<| <- SP_EL0 @@ -49,7 +65,11 @@ * E | ESF | | Privileged portion of the stack * L +>>>>>>>>>>>>>>>+ <- SP_EL1 |_ used during exceptions and syscalls * 1 | | | of size ARCH_THREAD_STACK_RESERVED - * +---------------+ <- stack_obj..| + * +---------------+ <- stack limit| + * | Stack guard | } Z_ARM64_STACK_GUARD_SIZE (protected by MMU/MPU) + * +---------------+ <- stack_obj + * + * Low Memory addresses * * When a kernel thread switches to user mode the SP_EL0 and SP_EL1 * values are reset accordingly in arch_user_mode_enter(). diff --git a/include/zephyr/arch/arm64/thread_stack.h b/include/zephyr/arch/arm64/thread_stack.h index aea9bc412c7..9ad29239135 100644 --- a/include/zephyr/arch/arm64/thread_stack.h +++ b/include/zephyr/arch/arm64/thread_stack.h @@ -7,11 +7,11 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_THREAD_STACK_H_ #define ZEPHYR_INCLUDE_ARCH_ARM64_THREAD_STACK_H_ +#include #define ARCH_STACK_PTR_ALIGN 16 -#if CONFIG_USERSPACE -#include +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) #define Z_ARM64_STACK_BASE_ALIGN MEM_DOMAIN_ALIGN_AND_SIZE #define Z_ARM64_STACK_SIZE_ALIGN MEM_DOMAIN_ALIGN_AND_SIZE #else @@ -19,6 +19,14 @@ #define Z_ARM64_STACK_SIZE_ALIGN ARCH_STACK_PTR_ALIGN #endif +#if defined(CONFIG_ARM64_STACK_PROTECTION) +#define Z_ARM64_STACK_GUARD_SIZE MEM_DOMAIN_ALIGN_AND_SIZE +#define Z_ARM64_K_STACK_BASE_ALIGN MEM_DOMAIN_ALIGN_AND_SIZE +#else +#define Z_ARM64_STACK_GUARD_SIZE 0 +#define Z_ARM64_K_STACK_BASE_ALIGN ARCH_STACK_PTR_ALIGN +#endif + /* * [ see also comments in arch/arm64/core/thread.c ] * @@ -36,6 +44,8 @@ * | | * +-------------------+ <- thread.stack_info.start * | Privileged stack | } K_(THREAD|KERNEL)_STACK_RESERVED + * +-------------------+ <- thread stack limit (update on every context switch) + * | Stack guard | } Z_ARM64_STACK_GUARD_SIZE (protected by MMU/MPU) * +-------------------+ <- thread.stack_obj * * Low Memory addresses @@ -45,11 +55,12 @@ #define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_ARM64_STACK_BASE_ALIGN #define ARCH_THREAD_STACK_SIZE_ADJUST(size) \ ROUND_UP((size), Z_ARM64_STACK_SIZE_ALIGN) -#define ARCH_THREAD_STACK_RESERVED CONFIG_PRIVILEGED_STACK_SIZE +#define ARCH_THREAD_STACK_RESERVED CONFIG_PRIVILEGED_STACK_SIZE + \ + Z_ARM64_STACK_GUARD_SIZE /* kernel stack */ -#define ARCH_KERNEL_STACK_RESERVED 0 -#define ARCH_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN +#define ARCH_KERNEL_STACK_RESERVED Z_ARM64_STACK_GUARD_SIZE +#define ARCH_KERNEL_STACK_OBJ_ALIGN Z_ARM64_K_STACK_BASE_ALIGN #ifndef _ASMLANGUAGE From 58788983283eecbafa0c49476e8cbca9b07b9f63 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Fri, 20 Jan 2023 23:08:18 +0800 Subject: [PATCH 0849/4498] arch: arm64: Add stack guard support for MPU To make the stack guard works well, clean and refine the MPU code. To save the MPU regions (the number of MPU regions are limited), we choose to remove the guard region. Comparing to add an individual region to guard the stack, removing the guard region can at least save 2 regions per core. Similarly with userspace, the stack guard will leverage the dynamic regions switching mechanism which means we need a region switch during the context switch. Otherwise, the other option is using stack guard region, but this is very limited since the number of MPU regions is limited. Signed-off-by: Jaxson Han --- arch/arm64/core/cortex_r/arm_mpu.c | 388 +++++++++++++------ include/zephyr/arch/arm64/cortex_r/arm_mpu.h | 3 +- include/zephyr/arch/arm64/thread.h | 2 +- 3 files changed, 262 insertions(+), 131 deletions(-) diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 7ee56c52ea4..9976772dee0 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -27,11 +28,24 @@ BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); -#define MPU_DYNAMIC_REGION_AREAS_NUM 1 +#define MPU_DYNAMIC_REGION_AREAS_NUM 3 -#ifdef CONFIG_USERSPACE +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) +static struct dynamic_region_info + sys_dyn_regions[CONFIG_MP_MAX_NUM_CPUS][MPU_DYNAMIC_REGION_AREAS_NUM]; +static int sys_dyn_regions_num[CONFIG_MP_MAX_NUM_CPUS]; + +static void dynamic_regions_init(void); static int dynamic_areas_init(uintptr_t start, size_t size); +static int flush_dynamic_regions_to_mpu(struct dynamic_region_info *dyn_regions, + uint8_t region_num); + +#if defined(CONFIG_USERSPACE) #define MPU_DYNAMIC_REGIONS_AREA_START ((uintptr_t)&_app_smem_start) +#else +#define MPU_DYNAMIC_REGIONS_AREA_START ((uintptr_t)&__kernel_ram_start) +#endif + #define MPU_DYNAMIC_REGIONS_AREA_SIZE ((size_t)((uintptr_t)&__kernel_ram_end - \ MPU_DYNAMIC_REGIONS_AREA_START)) #endif @@ -58,7 +72,7 @@ static int dynamic_areas_init(uintptr_t start, size_t size); static uint8_t static_regions_num; /* Get the number of supported MPU regions. */ -static inline uint8_t get_num_regions(void) +static ALWAYS_INLINE uint8_t get_num_regions(void) { uint64_t type; @@ -140,7 +154,7 @@ static ALWAYS_INLINE void mpu_set_region(uint32_t rnr, uint64_t rbar, barrier_isync_fence_full(); } -static inline void mpu_clr_region(uint32_t rnr) +static ALWAYS_INLINE void mpu_clr_region(uint32_t rnr) { write_prselr_el1(rnr); barrier_dsync_fence_full(); @@ -248,6 +262,7 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) { uint64_t val; uint32_t r_index; + uint8_t tmp_static_num; /* Current MPU code supports only EL1 */ val = read_currentel(); @@ -287,10 +302,10 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) } /* Update the number of programmed MPU regions. */ - static_regions_num = mpu_config.num_regions; + tmp_static_num = mpu_config.num_regions; /* DT-defined MPU regions. */ - if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + if (mpu_configure_regions_from_dt(&tmp_static_num) == -EINVAL) { __ASSERT(0, "Failed to allocate MPU regions from DT\n"); return; } @@ -298,25 +313,38 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) arm_core_mpu_enable(); if (!is_primary_core) { - return; + /* + * primary core might reprogram the sys_regions, so secondary cores + * should re-flush the sys regions + */ + goto out; } -#ifdef CONFIG_USERSPACE + /* Only primary core init the static_regions_num */ + static_regions_num = tmp_static_num; + +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) + dynamic_regions_init(); /* Only primary core do the dynamic_areas_init. */ int rc = dynamic_areas_init(MPU_DYNAMIC_REGIONS_AREA_START, MPU_DYNAMIC_REGIONS_AREA_SIZE); - if (rc <= 0) { + if (rc < 0) { __ASSERT(0, "Dynamic areas init fail"); return; } #endif +out: +#if defined(CONFIG_ARM64_STACK_PROTECTION) + (void)flush_dynamic_regions_to_mpu(sys_dyn_regions[arch_curr_cpu()->id], + sys_dyn_regions_num[arch_curr_cpu()->id]); +#endif + return; } -#ifdef CONFIG_USERSPACE - -static struct dynamic_region_info sys_dyn_regions[MPU_DYNAMIC_REGION_AREAS_NUM]; -static int sys_dyn_regions_num; +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) +static int insert_region(struct dynamic_region_info *dyn_regions, uint8_t region_num, + uintptr_t start, size_t size, struct arm_mpu_region_attr *attr); static void arm_core_mpu_background_region_enable(void) { @@ -333,6 +361,8 @@ static void arm_core_mpu_background_region_disable(void) { uint64_t val; + /* Force any outstanding transfers to complete before disabling MPU */ + barrier_dmem_fence_full(); val = read_sctlr_el1(); val &= ~SCTLR_BR_BIT; write_sctlr_el1(val); @@ -340,144 +370,215 @@ static void arm_core_mpu_background_region_disable(void) barrier_isync_fence_full(); } +static void dynamic_regions_init(void) +{ + for (int cpuid = 0; cpuid < arch_num_cpus(); cpuid++) { + for (int i = 0; i < MPU_DYNAMIC_REGION_AREAS_NUM; i++) { + sys_dyn_regions[cpuid][i].index = -1; + } + } +} + static int dynamic_areas_init(uintptr_t start, size_t size) { const struct arm_mpu_region *region; struct dynamic_region_info *tmp_info; + int ret = -ENOENT; uint64_t base = start; uint64_t limit = base + size; - if (sys_dyn_regions_num + 1 > MPU_DYNAMIC_REGION_AREAS_NUM) { - return -1; - } + for (int cpuid = 0; cpuid < arch_num_cpus(); cpuid++) { + /* Check the following searching does not overflow the room */ + if (sys_dyn_regions_num[cpuid] + 1 > MPU_DYNAMIC_REGION_AREAS_NUM) { + return -ENOSPC; + } - for (size_t i = 0; i < mpu_config.num_regions; i++) { - region = &mpu_config.mpu_regions[i]; - tmp_info = &sys_dyn_regions[sys_dyn_regions_num]; - if (base >= region->base && limit <= region->limit) { - tmp_info->index = i; - tmp_info->region_conf = *region; - return ++sys_dyn_regions_num; + ret = -ENOENT; + + for (int i = 0; i < mpu_config.num_regions; i++) { + region = &mpu_config.mpu_regions[i]; + tmp_info = &sys_dyn_regions[cpuid][sys_dyn_regions_num[cpuid]]; + + if (base >= region->base && limit <= region->limit) { + tmp_info->index = i; + tmp_info->region_conf = *region; + sys_dyn_regions_num[cpuid] += 1; + /* find the region, reset ret to no error */ + ret = 0; + break; + } } +#if defined(CONFIG_ARM64_STACK_PROTECTION) + ret = insert_region(sys_dyn_regions[cpuid], + MPU_DYNAMIC_REGION_AREAS_NUM, + (uintptr_t)z_interrupt_stacks[cpuid], + Z_ARM64_STACK_GUARD_SIZE, + NULL /* delete this region */); + if (ret < 0) { + break; + } + /* + * No need to check here if (sys_dyn_regions[cpuid] + ret) overflows, + * because the insert_region has checked it. + */ + sys_dyn_regions_num[cpuid] += ret; +#endif + } + + return ret < 0 ? ret : 0; +} + +static void set_region(struct arm_mpu_region *region, + uint64_t base, uint64_t limit, + struct arm_mpu_region_attr *attr) +{ + region->base = base; + region->limit = limit; + if (attr != NULL) { + region->attr = *attr; + } else { + memset(®ion->attr, 0, sizeof(struct arm_mpu_region_attr)); } +} - return -1; +static void clear_region(struct arm_mpu_region *region) +{ + set_region(region, 0, 0, NULL); } static int dup_dynamic_regions(struct dynamic_region_info *dst, int len) { size_t i; - int ret = sys_dyn_regions_num; + int num = sys_dyn_regions_num[arch_curr_cpu()->id]; - CHECKIF(!(sys_dyn_regions_num < len)) { + if (num >= len) { LOG_ERR("system dynamic region nums too large."); - ret = -EINVAL; - goto out; + return -EINVAL; } - for (i = 0; i < sys_dyn_regions_num; i++) { - dst[i] = sys_dyn_regions[i]; + for (i = 0; i < num; i++) { + dst[i] = sys_dyn_regions[arch_curr_cpu()->id][i]; } for (; i < len; i++) { + clear_region(&dst[i].region_conf); dst[i].index = -1; } -out: - return ret; -} - -static void set_region(struct arm_mpu_region *region, - uint64_t base, uint64_t limit, - struct arm_mpu_region_attr *attr) -{ - region->base = base; - region->limit = limit; - region->attr = *attr; + return num; } -static int get_underlying_region_idx(struct dynamic_region_info *dyn_regions, - uint8_t region_num, uint64_t base, - uint64_t limit) +static struct dynamic_region_info *get_underlying_region(struct dynamic_region_info *dyn_regions, + uint8_t region_num, uint64_t base, + uint64_t limit) { - for (size_t idx = 0; idx < region_num; idx++) { + for (int idx = 0; idx < region_num; idx++) { struct arm_mpu_region *region = &(dyn_regions[idx].region_conf); if (base >= region->base && limit <= region->limit) { - return idx; + return &(dyn_regions[idx]); } } - return -1; + + return NULL; } -static int insert_region(struct dynamic_region_info *dyn_regions, - uint8_t region_idx, uint8_t region_num, - uintptr_t start, size_t size, - struct arm_mpu_region_attr *attr) +static struct dynamic_region_info *find_available_region(struct dynamic_region_info *dyn_regions, + uint8_t region_num) +{ + return get_underlying_region(dyn_regions, region_num, 0, 0); +} + +/* + * return -ENOENT if there is no more available region + * do nothing if attr is NULL + */ +static int _insert_region(struct dynamic_region_info *dyn_regions, uint8_t region_num, + uint64_t base, uint64_t limit, struct arm_mpu_region_attr *attr) { + struct dynamic_region_info *tmp_region; + + if (attr == NULL) { + return 0; + } + + tmp_region = find_available_region(dyn_regions, region_num); + + if (tmp_region == NULL) { + return -ENOENT; + } + + set_region(&tmp_region->region_conf, base, limit, attr); + return 0; +} + +static int insert_region(struct dynamic_region_info *dyn_regions, uint8_t region_num, + uintptr_t start, size_t size, struct arm_mpu_region_attr *attr) +{ + + int ret = 0; /* base: inclusive, limit: exclusive */ uint64_t base = (uint64_t)start; uint64_t limit = base + size; - int u_idx; - struct arm_mpu_region *u_region; + struct dynamic_region_info *u_region; uint64_t u_base; uint64_t u_limit; - struct arm_mpu_region_attr *u_attr; - int ret = 0; + struct arm_mpu_region_attr u_attr; - CHECKIF(!(region_idx < region_num)) { - LOG_ERR("Out-of-bounds error for dynamic region map. " - "region idx: %d, region num: %d", - region_idx, region_num); - ret = -EINVAL; - goto out; - } + int count = 0; - u_idx = get_underlying_region_idx(dyn_regions, region_idx, base, limit); + u_region = get_underlying_region(dyn_regions, region_num, base, limit); - CHECKIF(!(u_idx >= 0)) { - LOG_ERR("Invalid underlying region index"); - ret = -ENOENT; - goto out; + if (u_region == NULL) { + return -ENOENT; } - /* Get underlying region range and attr */ - u_region = &(dyn_regions[u_idx].region_conf); - u_base = u_region->base; - u_limit = u_region->limit; - u_attr = &u_region->attr; + /* restore the underlying region range and attr */ + u_base = u_region->region_conf.base; + u_limit = u_region->region_conf.limit; + u_attr = u_region->region_conf.attr; - /* Temporally holding new region available to be configured */ - struct arm_mpu_region *curr_region = &(dyn_regions[region_idx].region_conf); + clear_region(&u_region->region_conf); + count--; + /* if attr is NULL, meaning we are going to delete a region */ if (base == u_base && limit == u_limit) { /* * The new region overlaps entirely with the * underlying region. Simply update the attr. */ - set_region(u_region, base, limit, attr); + ret += _insert_region(dyn_regions, region_num, base, limit, attr); + count++; } else if (base == u_base) { - set_region(curr_region, base, limit, attr); - set_region(u_region, limit, u_limit, u_attr); - region_idx++; + ret += _insert_region(dyn_regions, region_num, limit, u_limit, &u_attr); + count++; + ret += _insert_region(dyn_regions, region_num, base, limit, attr); + count++; } else if (limit == u_limit) { - set_region(u_region, u_base, base, u_attr); - set_region(curr_region, base, limit, attr); - region_idx++; + ret += _insert_region(dyn_regions, region_num, u_base, base, &u_attr); + count++; + ret += _insert_region(dyn_regions, region_num, base, limit, attr); + count++; } else { - set_region(u_region, u_base, base, u_attr); - set_region(curr_region, base, limit, attr); - region_idx++; - curr_region = &(dyn_regions[region_idx].region_conf); - set_region(curr_region, limit, u_limit, u_attr); - region_idx++; + ret += _insert_region(dyn_regions, region_num, u_base, base, &u_attr); + count++; + ret += _insert_region(dyn_regions, region_num, base, limit, attr); + count++; + ret += _insert_region(dyn_regions, region_num, limit, u_limit, &u_attr); + count++; } - ret = region_idx; + if (ret < 0) { + return -ENOENT; + } -out: - return ret; + if (attr == NULL) { + /* meanning we removed a region, so fix the count by decreasing 1 */ + count--; + } + + return count; } static int flush_dynamic_regions_to_mpu(struct dynamic_region_info *dyn_regions, @@ -486,7 +587,13 @@ static int flush_dynamic_regions_to_mpu(struct dynamic_region_info *dyn_regions, __ASSERT(read_daif() & DAIF_IRQ_BIT, "mpu flushing must be called with IRQs disabled"); int reg_avail_idx = static_regions_num; - int ret = 0; + + if (region_num >= get_num_regions()) { + LOG_ERR("Out-of-bounds error for mpu regions. " + "region num: %d, total mpu regions: %d", + region_num, get_num_regions()); + return -ENOENT; + } arm_core_mpu_background_region_enable(); @@ -518,18 +625,12 @@ static int flush_dynamic_regions_to_mpu(struct dynamic_region_info *dyn_regions, if (region_idx < 0) { region_idx = reg_avail_idx++; } - CHECKIF(!(region_idx < get_num_regions())) { - LOG_ERR("Out-of-bounds error for mpu regions. " - "region idx: %d, total mpu regions: %d", - region_idx, get_num_regions()); - ret = -ENOENT; - } region_init(region_idx, &(dyn_regions[i].region_conf)); } arm_core_mpu_background_region_disable(); - return ret; + return 0; } static int configure_dynamic_mpu_regions(struct k_thread *thread) @@ -538,21 +639,24 @@ static int configure_dynamic_mpu_regions(struct k_thread *thread) struct dynamic_region_info *dyn_regions = thread->arch.regions; const uint8_t max_region_num = ARM64_MPU_MAX_DYNAMIC_REGIONS; - uint8_t region_num; - int ret = 0, ret2; + int region_num; + int ret = 0; /* Busy wait if it is flushing somewhere else */ while (!atomic_cas(&thread->arch.flushing, 0, 1)) { } - ret2 = dup_dynamic_regions(dyn_regions, max_region_num); - CHECKIF(ret2 < 0) { - ret = ret2; + thread->arch.region_num = 0; + + ret = dup_dynamic_regions(dyn_regions, max_region_num); + + if (ret < 0) { goto out; } - region_num = (uint8_t)ret2; + region_num = ret; +#if defined(CONFIG_USERSPACE) struct k_mem_domain *mem_domain = thread->mem_domain_info.mem_domain; if (mem_domain) { @@ -567,41 +671,61 @@ static int configure_dynamic_mpu_regions(struct k_thread *thread) if (partition->size == 0) { continue; } - LOG_DBG("set region 0x%lx 0x%lx", + LOG_DBG("set region 0x%lx 0x%lx\n", partition->start, partition->size); - ret2 = insert_region(dyn_regions, - region_num, - max_region_num, - partition->start, - partition->size, - &partition->attr); - CHECKIF(ret2 < 0) { - ret = ret2; + ret = insert_region(dyn_regions, + max_region_num, + partition->start, + partition->size, + &partition->attr); + + if (ret < 0) { goto out; } - region_num = (uint8_t)ret2; + region_num += ret; } } LOG_DBG("configure user thread %p's context", thread); if ((thread->base.user_options & K_USER) != 0) { /* K_USER thread stack needs a region */ - ret2 = insert_region(dyn_regions, - region_num, - max_region_num, - thread->stack_info.start, - thread->stack_info.size, - &K_MEM_PARTITION_P_RW_U_RW); - CHECKIF(ret2 < 0) { - ret = ret2; + ret = insert_region(dyn_regions, + max_region_num, + thread->stack_info.start, + thread->stack_info.size, + &K_MEM_PARTITION_P_RW_U_RW); + if (ret < 0) { goto out; } - region_num = (uint8_t)ret2; + region_num += ret; } +#endif - thread->arch.region_num = region_num; +#if defined(CONFIG_ARM64_STACK_PROTECTION) + uintptr_t guard_start; + + if (thread->arch.stack_limit != 0) { + guard_start = (uintptr_t)thread->arch.stack_limit - Z_ARM64_STACK_GUARD_SIZE; + ret = insert_region(dyn_regions, + max_region_num, + guard_start, + Z_ARM64_STACK_GUARD_SIZE, + NULL); + if (ret < 0) { + goto out; + } + region_num += ret; + } +#endif + + /* + * There is no need to check if region_num is overflow the uint8_t, + * because the insert_region make sure there is enough room to store a region, + * otherwise the insert_region will return a negtive error number + */ + thread->arch.region_num = (uint8_t)region_num; if (thread == _current) { ret = flush_dynamic_regions_to_mpu(dyn_regions, region_num); @@ -609,9 +733,11 @@ static int configure_dynamic_mpu_regions(struct k_thread *thread) out: atomic_clear(&thread->arch.flushing); - return ret; + return ret < 0 ? ret : 0; } +#endif /* defined(CONFIG_USERSPACE) || defined(CONFIG_HW_STACK_PROTECTION) */ +#if defined(CONFIG_USERSPACE) int arch_mem_domain_max_partitions_get(void) { int remaining_regions = get_num_regions() - static_regions_num + 1; @@ -692,7 +818,9 @@ int arch_mem_domain_thread_remove(struct k_thread *thread) return ret; } +#endif /* CONFIG_USERSPACE */ +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) void z_arm64_thread_mem_domains_init(struct k_thread *thread) { unsigned int key = arch_irq_lock(); @@ -703,18 +831,20 @@ void z_arm64_thread_mem_domains_init(struct k_thread *thread) void z_arm64_swap_mem_domains(struct k_thread *thread) { + int cpuid = arch_curr_cpu()->id; /* Busy wait if it is configuring somewhere else */ while (!atomic_cas(&thread->arch.flushing, 0, 1)) { } if (thread->arch.region_num == 0) { - (void)flush_dynamic_regions_to_mpu(sys_dyn_regions, sys_dyn_regions_num); + (void)flush_dynamic_regions_to_mpu(sys_dyn_regions[cpuid], + sys_dyn_regions_num[cpuid]); } else { - (void)flush_dynamic_regions_to_mpu(thread->arch.regions, thread->arch.region_num); + (void)flush_dynamic_regions_to_mpu(thread->arch.regions, + thread->arch.region_num); } atomic_clear(&thread->arch.flushing); } - -#endif /* CONFIG_USERSPACE */ +#endif diff --git a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h index 077b6664fb1..8df9aaf15f3 100644 --- a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h +++ b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h @@ -256,7 +256,8 @@ struct dynamic_region_info { #define ARM64_MPU_MAX_DYNAMIC_REGIONS \ 1 + /* data section */ \ (CONFIG_MAX_DOMAIN_PARTITIONS + 2) + \ - 2 /* user stack */ + (IS_ENABLED(CONFIG_ARM64_STACK_PROTECTION) ? 2 : 0) + \ + (IS_ENABLED(CONFIG_USERSPACE) ? 2 : 0) #endif /* _ASMLANGUAGE */ diff --git a/include/zephyr/arch/arm64/thread.h b/include/zephyr/arch/arm64/thread.h index f458dcc2976..457a8c07839 100644 --- a/include/zephyr/arch/arm64/thread.h +++ b/include/zephyr/arch/arm64/thread.h @@ -51,7 +51,7 @@ struct z_arm64_fp_context { }; struct _thread_arch { -#if defined(CONFIG_USERSPACE) +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) #if defined(CONFIG_ARM_MMU) struct arm_mmu_ptables *ptables; #endif From 0928830409d069c8075a8a81b3bc6f4abd40d6a7 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Sat, 21 Jan 2023 00:07:24 +0800 Subject: [PATCH 0850/4498] arch: arm64: Enable stack guard for v8R Enable stack guard for v8R which is backed by MPU. Signed-off-by: Jaxson Han --- arch/arm64/core/Kconfig | 1 + arch/arm64/core/switch.S | 2 +- arch/arm64/core/thread.c | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index 6aa996bb0fb..fd74a526416 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -23,6 +23,7 @@ config CPU_AARCH64_CORTEX_R select HAS_FLASH_LOAD_OFFSET select CPU_HAS_DCACHE select CPU_HAS_ICACHE + select ARCH_HAS_STACK_PROTECTION select CPU_HAS_FPU imply FPU imply FPU_SHARING diff --git a/arch/arm64/core/switch.S b/arch/arm64/core/switch.S index 142103dee2f..333b8f0b21e 100644 --- a/arch/arm64/core/switch.S +++ b/arch/arm64/core/switch.S @@ -115,7 +115,7 @@ SECTION_FUNC(TEXT, z_arm64_context_switch) str x2, [x4, #_cpu_offset_to_current_stack_limit] #endif -#ifdef CONFIG_USERSPACE +#if defined(CONFIG_USERSPACE) || defined(CONFIG_ARM64_STACK_PROTECTION) str lr, [sp, #-16]! bl z_arm64_swap_mem_domains ldr lr, [sp], #16 diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index 4bb77626a73..a0269501c19 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -145,6 +145,10 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, thread->callee_saved.lr = (uint64_t)z_arm64_exit_exc; thread->switch_handle = thread; +#if defined(CONFIG_ARM64_STACK_PROTECTION) + thread->arch.stack_limit = (uint64_t)stack + Z_ARM64_STACK_GUARD_SIZE; + z_arm64_thread_mem_domains_init(thread); +#endif } #ifdef CONFIG_USERSPACE From eeaf3bdb2d6c911648e8a70963bfb393886cba84 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Wed, 6 Sep 2023 15:05:26 +0800 Subject: [PATCH 0851/4498] tests: posix: eventfd: Move thread from stack to data section The test case allocate struct k_thread thread in the stack. This will lead the random initial value of thread and thus cause the test cases randomly hang. To fix such issue, move the declartion of struct k_thread thread outside the function as a stacic variable. Signed-off-by: Jaxson Han --- tests/posix/eventfd/src/blocking.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/posix/eventfd/src/blocking.c b/tests/posix/eventfd/src/blocking.c index 4c5ce5b982a..6ff4decd0c4 100644 --- a/tests/posix/eventfd/src/blocking.c +++ b/tests/posix/eventfd/src/blocking.c @@ -72,6 +72,7 @@ ZTEST_F(eventfd, test_unset_poll_event_block) } K_THREAD_STACK_DEFINE(thread_stack, CONFIG_TEST_STACK_SIZE); +static struct k_thread thread; static void thread_eventfd_read_42(void *arg1, void *arg2, void *arg3) { @@ -84,8 +85,6 @@ static void thread_eventfd_read_42(void *arg1, void *arg2, void *arg3) ZTEST_F(eventfd, test_read_then_write_block) { - struct k_thread thread; - k_thread_create(&thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack), thread_eventfd_read_42, fixture, NULL, NULL, 0, 0, K_NO_WAIT); @@ -107,7 +106,6 @@ static void thread_eventfd_write(void *arg1, void *arg2, void *arg3) ZTEST_F(eventfd, test_write_while_pollin) { - struct k_thread thread; struct zsock_pollfd fds[] = { { .fd = fixture->fd, @@ -143,7 +141,6 @@ static void thread_eventfd_read(void *arg1, void *arg2, void *arg3) ZTEST_F(eventfd, test_read_while_pollout) { - struct k_thread thread; struct zsock_pollfd fds[] = { { .fd = fixture->fd, From 64086d04d502662c96eea3d40aa05fc69d55aaa9 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Thu, 7 Sep 2023 11:05:17 +0800 Subject: [PATCH 0852/4498] tests: kernel: threads: dynamic_thread: increase the heap size The heap size is not enough so that it will cause the testcase fail. Increase to 32k to make sure it works for a long time in the future. Signed-off-by: Jaxson Han --- tests/kernel/threads/dynamic_thread/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kernel/threads/dynamic_thread/prj.conf b/tests/kernel/threads/dynamic_thread/prj.conf index f7d01312787..da83027ca77 100644 --- a/tests/kernel/threads/dynamic_thread/prj.conf +++ b/tests/kernel/threads/dynamic_thread/prj.conf @@ -1,4 +1,4 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y -CONFIG_HEAP_MEM_POOL_SIZE=21504 +CONFIG_HEAP_MEM_POOL_SIZE=32768 From 5b8df16ef6bf4c4e64da3e5ccd9b3c4c4afb95ca Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Thu, 7 Sep 2023 14:05:40 +0800 Subject: [PATCH 0853/4498] samples: arch: smp: pi: fix the stack overflow issue The stack guard report this testcase has the stack overflow issue. To fix the issue, slightly increse the stack size. Signed-off-by: Jaxson Han --- samples/arch/smp/pi/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/arch/smp/pi/src/main.c b/samples/arch/smp/pi/src/main.c index 95937e3b275..e141f8f5f1b 100644 --- a/samples/arch/smp/pi/src/main.c +++ b/samples/arch/smp/pi/src/main.c @@ -17,7 +17,7 @@ #define DIGITS_NUM 240 #define LENGTH ((DIGITS_NUM / 4) * 14) -#define STACK_SIZE ((LENGTH * sizeof(int) + 1024)) +#define STACK_SIZE ((LENGTH * sizeof(int) + 1280)) #ifdef CONFIG_SMP #define CORES_NUM arch_num_cpus() From 2a8548b036a43fabefa4702451a7282573d3b933 Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Thu, 21 Sep 2023 10:45:29 +0800 Subject: [PATCH 0854/4498] tests: Kernel: semaphore: semaphore: Set test case to 1cpu The test_sem_take_timeout_isr depends on the thread's priority. But for SMP platforms, the priority is different with no-SMP. High-priority threads and low-priority threads might run simultaneously at different cores. Set the test case run at 1cpu to fix such an issue. Signed-off-by: Jaxson Han --- tests/kernel/semaphore/semaphore/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kernel/semaphore/semaphore/src/main.c b/tests/kernel/semaphore/semaphore/src/main.c index cff315f119b..3d146559607 100644 --- a/tests/kernel/semaphore/semaphore/src/main.c +++ b/tests/kernel/semaphore/semaphore/src/main.c @@ -565,7 +565,7 @@ ZTEST_USER(semaphore, test_sem_take_timeout_forever) * @brief Test k_sem_take() with timeout in ISR context * @see k_sem_take() */ -ZTEST(semaphore, test_sem_take_timeout_isr) +ZTEST(semaphore_1cpu, test_sem_take_timeout_isr) { /* * Signal the semaphore upon which the another thread is waiting. The From b94641697fdb54ad21bb2fcc0615b3070357bc96 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Thu, 21 Sep 2023 10:12:15 +0200 Subject: [PATCH 0855/4498] samples/modules: Add LVGL demo sample Adds a sample which allows to build the LVGL upstream demo applications (music, benchmark, stress). Resolves issue #62744. Signed-off-by: Fabian Blatz --- samples/modules/lvgl/demos/CMakeLists.txt | 83 +++++++++++++++++++ samples/modules/lvgl/demos/Kconfig | 30 +++++++ samples/modules/lvgl/demos/README.rst | 51 ++++++++++++ .../lvgl/demos/boards/m5stack_core2.conf | 4 + .../lvgl/demos/boards/mimxrt1060_evk.conf | 8 ++ .../lvgl/demos/boards/mimxrt1170_evk_cm7.conf | 8 ++ .../lvgl/demos/boards/native_posix.conf | 4 + .../lvgl/demos/boards/native_posix.overlay | 11 +++ .../lvgl/demos/boards/native_posix_64.conf | 4 + .../lvgl/demos/boards/native_posix_64.overlay | 6 ++ .../modules/lvgl/demos/boards/native_sim.conf | 4 + .../lvgl/demos/boards/native_sim.overlay | 6 ++ .../lvgl/demos/boards/native_sim_64.conf | 4 + .../lvgl/demos/boards/native_sim_64.overlay | 6 ++ samples/modules/lvgl/demos/prj.conf | 18 ++++ samples/modules/lvgl/demos/sample.yaml | 19 +++++ samples/modules/lvgl/demos/src/main.c | 45 ++++++++++ 17 files changed, 311 insertions(+) create mode 100644 samples/modules/lvgl/demos/CMakeLists.txt create mode 100644 samples/modules/lvgl/demos/Kconfig create mode 100644 samples/modules/lvgl/demos/README.rst create mode 100644 samples/modules/lvgl/demos/boards/m5stack_core2.conf create mode 100644 samples/modules/lvgl/demos/boards/mimxrt1060_evk.conf create mode 100644 samples/modules/lvgl/demos/boards/mimxrt1170_evk_cm7.conf create mode 100644 samples/modules/lvgl/demos/boards/native_posix.conf create mode 100644 samples/modules/lvgl/demos/boards/native_posix.overlay create mode 100644 samples/modules/lvgl/demos/boards/native_posix_64.conf create mode 100644 samples/modules/lvgl/demos/boards/native_posix_64.overlay create mode 100644 samples/modules/lvgl/demos/boards/native_sim.conf create mode 100644 samples/modules/lvgl/demos/boards/native_sim.overlay create mode 100644 samples/modules/lvgl/demos/boards/native_sim_64.conf create mode 100644 samples/modules/lvgl/demos/boards/native_sim_64.overlay create mode 100644 samples/modules/lvgl/demos/prj.conf create mode 100644 samples/modules/lvgl/demos/sample.yaml create mode 100644 samples/modules/lvgl/demos/src/main.c diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt new file mode 100644 index 00000000000..78185c61196 --- /dev/null +++ b/samples/modules/lvgl/demos/CMakeLists.txt @@ -0,0 +1,83 @@ +# Copyright (c) 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(lvgl_sample) + +set(LVGL_DIR ${ZEPHYR_LVGL_MODULE_DIR}) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +target_include_directories(app PRIVATE + ${LVGL_DIR}/demos/ +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_MUSIC app PRIVATE + ${LVGL_DIR}/demos/music/lv_demo_music_list.c + ${LVGL_DIR}/demos/music/lv_demo_music.c + ${LVGL_DIR}/demos/music/lv_demo_music_main.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_corner_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_logo.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop_large.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE + ${LVGL_DIR}/demos/benchmark/lv_demo_benchmark.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_indexed16.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_28_compr_az.c.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_16_compr_az.c.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_argb.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_alpha16.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_12_compr_az.c.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_chroma_keyed.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb565a8.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE + ${LVGL_DIR}/demos/stress/lv_demo_stress.c +) diff --git a/samples/modules/lvgl/demos/Kconfig b/samples/modules/lvgl/demos/Kconfig new file mode 100644 index 00000000000..01cf2f40195 --- /dev/null +++ b/samples/modules/lvgl/demos/Kconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +choice LV_Z_DEMO + prompt "LVGL demo to build" + default LV_Z_DEMO_MUSIC + help + Demo application to build. + +config LV_Z_DEMO_MUSIC + bool "LVGL music demo" + select LV_USE_DEMO_MUSIC + help + Build music player demo application. + +config LV_Z_DEMO_BENCHMARK + bool "LVGL benchmark demo" + select LV_USE_DEMO_BENCHMARK + help + Build benchmarking demo application. + +config LV_Z_DEMO_STRESS + bool "LVGL stress demo" + select LV_USE_DEMO_STRESS + help + Build stress testing demo application. + +endchoice + +source "Kconfig.zephyr" diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst new file mode 100644 index 00000000000..c27c71fa04d --- /dev/null +++ b/samples/modules/lvgl/demos/README.rst @@ -0,0 +1,51 @@ +.. zephyr:code-sample:: lvgl-demos + :name: LVGL demos + :relevant-api: display_interface + + Run LVGL built-in demos. + +Overview +******** + +A sample showcasing upstream LVGL demos. + +* Music + The music player demo shows what kind of modern, smartphone-like user interfaces can be created on LVGL. +* Benchmark + The benchmark demo tests the performance in various cases. For example rectangle, border, shadow, text, image blending, image transformation, blending modes, etc. +* Stress + A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks. + +Requirements +************ + +* A board with display, ideally with 480x272 resolution or higher. + +Building and Running +******************** + +These demos can be built as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_posix + :gen-args: -DCONFIG_LV_Z_DEMO_MUSIC=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_posix + :gen-args: -DCONFIG_LV_Z_DEMO_BENCHMARK=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_posix + :gen-args: -DCONFIG_LV_Z_DEMO_STRESS=y + :goals: run + :compact: diff --git a/samples/modules/lvgl/demos/boards/m5stack_core2.conf b/samples/modules/lvgl/demos/boards/m5stack_core2.conf new file mode 100644 index 00000000000..c1da6a053d2 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/m5stack_core2.conf @@ -0,0 +1,4 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/modules/lvgl/demos/boards/mimxrt1060_evk.conf b/samples/modules/lvgl/demos/boards/mimxrt1060_evk.conf new file mode 100644 index 00000000000..30b4edca858 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/mimxrt1060_evk.conf @@ -0,0 +1,8 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +# Enable PXP DMA engine and set rotation angle to 0 degrees. +# This allows us to verify the DMA driver functions without altering +# the output image +CONFIG_DMA=y +CONFIG_MCUX_ELCDIF_PXP=y diff --git a/samples/modules/lvgl/demos/boards/mimxrt1170_evk_cm7.conf b/samples/modules/lvgl/demos/boards/mimxrt1170_evk_cm7.conf new file mode 100644 index 00000000000..30b4edca858 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/mimxrt1170_evk_cm7.conf @@ -0,0 +1,8 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +# Enable PXP DMA engine and set rotation angle to 0 degrees. +# This allows us to verify the DMA driver functions without altering +# the output image +CONFIG_DMA=y +CONFIG_MCUX_ELCDIF_PXP=y diff --git a/samples/modules/lvgl/demos/boards/native_posix.conf b/samples/modules/lvgl/demos/boards/native_posix.conf new file mode 100644 index 00000000000..a99f38b8d84 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_posix.conf @@ -0,0 +1,4 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_COLOR_DEPTH_32=y diff --git a/samples/modules/lvgl/demos/boards/native_posix.overlay b/samples/modules/lvgl/demos/boards/native_posix.overlay new file mode 100644 index 00000000000..eab17f916bd --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_posix.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023, Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sdl_dc { + compatible = "zephyr,sdl-dc"; + height = <272>; + width = <480>; +}; diff --git a/samples/modules/lvgl/demos/boards/native_posix_64.conf b/samples/modules/lvgl/demos/boards/native_posix_64.conf new file mode 100644 index 00000000000..a99f38b8d84 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_posix_64.conf @@ -0,0 +1,4 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_COLOR_DEPTH_32=y diff --git a/samples/modules/lvgl/demos/boards/native_posix_64.overlay b/samples/modules/lvgl/demos/boards/native_posix_64.overlay new file mode 100644 index 00000000000..ab50aa66f82 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_posix_64.overlay @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2023, Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "native_posix.overlay" diff --git a/samples/modules/lvgl/demos/boards/native_sim.conf b/samples/modules/lvgl/demos/boards/native_sim.conf new file mode 100644 index 00000000000..a99f38b8d84 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_sim.conf @@ -0,0 +1,4 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_COLOR_DEPTH_32=y diff --git a/samples/modules/lvgl/demos/boards/native_sim.overlay b/samples/modules/lvgl/demos/boards/native_sim.overlay new file mode 100644 index 00000000000..ab50aa66f82 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_sim.overlay @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2023, Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "native_posix.overlay" diff --git a/samples/modules/lvgl/demos/boards/native_sim_64.conf b/samples/modules/lvgl/demos/boards/native_sim_64.conf new file mode 100644 index 00000000000..a99f38b8d84 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_sim_64.conf @@ -0,0 +1,4 @@ +# Copyright 2023 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_COLOR_DEPTH_32=y diff --git a/samples/modules/lvgl/demos/boards/native_sim_64.overlay b/samples/modules/lvgl/demos/boards/native_sim_64.overlay new file mode 100644 index 00000000000..47fdc4be34c --- /dev/null +++ b/samples/modules/lvgl/demos/boards/native_sim_64.overlay @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2023, Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "native_sim.overlay" diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf new file mode 100644 index 00000000000..f7e061ef696 --- /dev/null +++ b/samples/modules/lvgl/demos/prj.conf @@ -0,0 +1,18 @@ +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_LOG=y +CONFIG_SHELL=y + +CONFIG_LVGL=y +CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8 +CONFIG_LV_Z_SHELL=y +CONFIG_LV_USE_MONKEY=y + +CONFIG_DISPLAY=y +CONFIG_INPUT=y + +CONFIG_LV_FONT_MONTSERRAT_12=y +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_FONT_MONTSERRAT_16=y + +# Benchmark Demo +CONFIG_LV_USE_FONT_COMPRESSED=y diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml new file mode 100644 index 00000000000..b928d9f37f0 --- /dev/null +++ b/samples/modules/lvgl/demos/sample.yaml @@ -0,0 +1,19 @@ +sample: + description: LVGL sample, containing all upstream demos + name: LVGL demos +common: + modules: + - lvgl + harness: none + filter: dt_chosen_enabled("zephyr,display") + tags: samples lvgl display gui +tests: + sample.modules.lvgl.demo_music: + extra_configs: + - CONFIG_LV_Z_DEMO_MUSIC=y + sample.modules.lvgl.demo_benchmark: + extra_configs: + - CONFIG_LV_Z_DEMO_BENCHMARK=y + sample.modules.lvgl.demo_stress: + extra_configs: + - CONFIG_LV_Z_DEMO_STRESS=y diff --git a/samples/modules/lvgl/demos/src/main.c b/samples/modules/lvgl/demos/src/main.c new file mode 100644 index 00000000000..c17ba02c88f --- /dev/null +++ b/samples/modules/lvgl/demos/src/main.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#include +LOG_MODULE_REGISTER(app); + +int main(void) +{ + const struct device *display_dev; + + display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); + if (!device_is_ready(display_dev)) { + LOG_ERR("Device not ready, aborting test"); + return 0; + } + +#if defined(CONFIG_LV_USE_DEMO_MUSIC) + lv_demo_music(); +#elif defined(CONFIG_LV_USE_DEMO_BENCHMARK) + lv_demo_benchmark(); +#elif defined(CONFIG_LV_USE_DEMO_STRESS) + lv_demo_stress(); +#else +#error Enable one of the demos CONFIG_LV_USE_DEMO_MUSIC, CONFIG_LV_USE_DEMO_BENCHMARK \ +or CONFIG_LV_USE_DEMO_STRESS. +#endif + + lv_task_handler(); + display_blanking_off(display_dev); + + while (1) { + k_msleep(lv_task_handler()); + } + + return 0; +} From 05e974cab0665827bdfab1739799b1873e2e9b45 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 21 Sep 2023 12:07:47 +0200 Subject: [PATCH 0856/4498] net: openthread: Fix TX time inconsistency in multi-CCA TX mode docs Align with other delayed TX modes, by specifying the transmit time as the start of the frame PHR, not SHR. Signed-off-by: Robert Lubos --- include/zephyr/net/ieee802154_radio_openthread.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/ieee802154_radio_openthread.h b/include/zephyr/net/ieee802154_radio_openthread.h index 56a9bd8de0d..39a316b3251 100644 --- a/include/zephyr/net/ieee802154_radio_openthread.h +++ b/include/zephyr/net/ieee802154_radio_openthread.h @@ -34,7 +34,7 @@ enum ieee802154_openthread_tx_mode { * This mode is a non-standard experimental OpenThread feature. It allows transmission * of a packet within a certain time window. * The earliest transmission time is specified as in the other TXTIME modes: - * When the first CCA reports an idle channel then the first symbol of the packet's SHR + * When the first CCA reports an idle channel then the first symbol of the packet's PHR * SHALL be present at the local antenna at the time represented by the scheduled * TX timestamp (referred to as T_tx below). * @@ -48,7 +48,7 @@ enum ieee802154_openthread_tx_mode { * (see @ref IEEE802154_OPENTHREAD_ATTR_T_RECCA and * @ref IEEE802154_OPENTHREAD_ATTR_T_CCATX). Based on these attributes the upper layer * can calculate the latest point in time (T_txmax) that the first symbol of the scheduled - * packet's SHR SHALL be present at the local antenna: + * packet's PHR SHALL be present at the local antenna: * * T_maxtxdelay = max_extra_cca_attempts * (aCcaTime + T_recca) - T_recca + T_ccatx * T_txmax = T_tx + T_maxtxdelay From b2fb3d49bf56f31594eb286d257d81a881859a2b Mon Sep 17 00:00:00 2001 From: Petr Hlineny Date: Thu, 21 Sep 2023 12:22:07 +0200 Subject: [PATCH 0857/4498] drivers: i2c: stm32: Fix for i2c PM Remove unwanted "pm_device_runtime_get" lock which makes i2c power management working incorrectly. Fixes: #62790 Signed-off-by: Petr Hlineny --- drivers/i2c/i2c_ll_stm32.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 1dffd246412..0ee35f69134 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -146,11 +146,6 @@ static int i2c_stm32_transfer(const struct device *dev, struct i2c_msg *msg, return ret; } - ret = pm_device_runtime_get(dev); - if (ret < 0) { - return ret; - } - /* Send out messages */ k_sem_take(&data->bus_mutex, K_FOREVER); From 85c4111002d837e570df89317e727cea7cde67cb Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Thu, 21 Sep 2023 12:56:23 +0200 Subject: [PATCH 0858/4498] memory-attr: Rationalize _MASK and _GET(x) macros Let's make this official: we use the suffix `_MASK` for the define carrying the GENMASK for the attributes, and the suffix `_GET(x)` for the actual macro extracting the attributes. Signed-off-by: Carlo Caione --- arch/arm/core/mpu/arm_mpu.c | 2 +- arch/arm/core/mpu/nxp_mpu.c | 2 +- arch/arm64/core/cortex_r/arm_mpu.c | 2 +- include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h | 3 ++- include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h | 3 ++- include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h | 3 ++- include/zephyr/dt-bindings/memory-attr/memory-attr.h | 3 +++ tests/kernel/mem_heap/shared_multi_heap/src/main.c | 2 +- 8 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index 6c95fe044b2..9b2feffe5ee 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -102,7 +102,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) for (size_t idx = 0; idx < num_regions; idx++) { struct arm_mpu_region region_conf; - switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + switch (DT_MEM_ARM_GET(region[idx].dt_attr)) { case DT_MEM_ARM_MPU_RAM: region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); break; diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index 71b55ae7c11..f3d3bd715ae 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -163,7 +163,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) for (size_t idx = 0; idx < num_regions; idx++) { struct nxp_mpu_region region_conf; - switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + switch (DT_MEM_ARM_GET(region[idx].dt_attr)) { case DT_MEM_ARM_MPU_RAM: region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); break; diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 9976772dee0..e303a7c0379 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -210,7 +210,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) for (size_t idx = 0; idx < num_regions; idx++) { struct arm_mpu_region region_conf; - switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + switch (DT_MEM_ARM_GET(region[idx].dt_attr)) { case DT_MEM_ARM_MPU_RAM: region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); break; diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h index 5ffe1f3a3a8..a0e8736712e 100644 --- a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h @@ -18,7 +18,8 @@ * This is legacy and it should NOT be extended further. If new MPU region * types must be added, these must rely on the generic memory attributes. */ -#define DT_MEM_ARM_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_ARM_MASK DT_MEM_ARCH_ATTR_MASK +#define DT_MEM_ARM_GET(x) ((x) & DT_MEM_ARM_MASK) #define DT_MEM_ARM(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) #define ATTR_MPU_RAM BIT(0) diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h index c51cd010ef1..5aebb111a56 100644 --- a/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h @@ -12,7 +12,8 @@ /* * Architecture specific RISCV related attributes. */ -#define DT_MEM_RISCV_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_RISCV_MASK DT_MEM_ARCH_ATTR_MASK +#define DT_MEM_RISCV_GET(x) ((x) & DT_MEM_RISCV_MASK) #define DT_MEM_RISCV(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) #define ATTR_RISCV_TYPE_MAIN BIT(0) diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h index c845b071a6b..ba48e0c21e8 100644 --- a/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h @@ -12,7 +12,8 @@ /* * Architecture specific Xtensa related attributes. */ -#define DT_MEM_XTENSA_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_XTENSA_MASK DT_MEM_ARCH_ATTR_MASK +#define DT_MEM_XTENSA_GET(x) ((x) & DT_MEM_XTENSA_MASK) #define DT_MEM_XTENSA(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) #define ATTR_XTENSA_INSTR_ROM BIT(0) diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr.h b/include/zephyr/dt-bindings/memory-attr/memory-attr.h index ea4ac04cafe..9023a2b56a6 100644 --- a/include/zephyr/dt-bindings/memory-attr/memory-attr.h +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr.h @@ -14,6 +14,7 @@ * Generic memory attributes that should be common to all architectures. */ #define DT_MEM_ATTR_MASK GENMASK(15, 0) +#define DT_MEM_ATTR_GET(x) ((x) & DT_MEM_ATTR_MASK) #define DT_MEM_ATTR_SHIFT (0) #define DT_MEM_CACHEABLE BIT(0) /* cacheable */ @@ -30,6 +31,7 @@ * provided mask. */ #define DT_MEM_SW_ATTR_MASK GENMASK(19, 16) +#define DT_MEM_SW_ATTR_GET(x) ((x) & DT_MEM_SW_ATTR_MASK) #define DT_MEM_SW_ATTR_SHIFT (16) #define DT_MEM_SW_ATTR_UNKNOWN BIT(19) @@ -42,6 +44,7 @@ * See for example `include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` */ #define DT_MEM_ARCH_ATTR_MASK GENMASK(31, 20) +#define DT_MEM_ARCH_ATTR_GET(x) ((x) & DT_MEM_ARCH_ATTR_MASK) #define DT_MEM_ARCH_ATTR_SHIFT (20) #define DT_MEM_ARCH_ATTR_UNKNOWN BIT(31) diff --git a/tests/kernel/mem_heap/shared_multi_heap/src/main.c b/tests/kernel/mem_heap/shared_multi_heap/src/main.c index ae324d10b22..bee594c56f3 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/src/main.c +++ b/tests/kernel/mem_heap/shared_multi_heap/src/main.c @@ -83,7 +83,7 @@ static inline enum shared_multi_heap_attr mpu_to_reg_attr(uint32_t dt_attr) * RAM -> SMH_REG_ATTR_CACHEABLE * RAM_NOCACHE -> SMH_REG_ATTR_NON_CACHEABLE */ - switch (DT_MEM_ARM_MASK(dt_attr)) { + switch (DT_MEM_ARM_GET(dt_attr)) { case DT_MEM_ARM_MPU_RAM: return SMH_REG_ATTR_CACHEABLE; case DT_MEM_ARM_MPU_RAM_NOCACHE: From 3966d30a4f1f90339efb0f0c8ca7519ec9d9f5b0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 10 Jun 2023 00:55:21 +0000 Subject: [PATCH 0859/4498] twister: support filtering by vendor Add a new option --vendor which allows filtering by vendors tracked in the board/platform yaml file. The vendor string is compatible with DTS and is what we have in dts/bindings/vendor-prefixes.txt. Providing multiple vendors is also supported. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/environment.py | 4 ++++ scripts/pylib/twister/twisterlib/platform.py | 4 ++++ scripts/pylib/twister/twisterlib/testplan.py | 15 ++++++++++++--- scripts/schemas/twister/platform-schema.yaml | 4 ++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 160233a66fe..0517e8ce2b7 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -481,6 +481,10 @@ def add_parse_arguments(parser = None): that support this feature (currently only Linux). """) + parser.add_argument( + "--vendor", action="append", default=[], + help="Vendor filter for testing") + parser.add_argument( "-p", "--platform", action="append", default=[], help="Platform filter for testing. This option may be used multiple " diff --git a/scripts/pylib/twister/twisterlib/platform.py b/scripts/pylib/twister/twisterlib/platform.py index fbbd10523b1..f3773ef4c67 100644 --- a/scripts/pylib/twister/twisterlib/platform.py +++ b/scripts/pylib/twister/twisterlib/platform.py @@ -36,6 +36,8 @@ def __init__(self): self.supported = set() self.arch = "" + self.vendor = "" + self.tier = -1 self.type = "na" self.simulation = "na" self.simulation_exec = None @@ -67,6 +69,8 @@ def load(self, platform_file): self.supported.add(item) self.arch = data['arch'] + self.vendor = data.get('vendor', '') + self.tier = data.get("tier", -1) self.type = data.get('type', "na") self.simulation = data.get('simulation', "na") self.simulation_exec = data.get('simulation_exec') diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 1a524a67019..bbe86c6fc64 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -623,6 +623,7 @@ def apply_filters(self, **kwargs): toolchain = self.env.toolchain platform_filter = self.options.platform + vendor_filter = self.options.vendor exclude_platform = self.options.exclude_platform testsuite_filter = self.run_individual_testsuite arch_filter = self.options.arch @@ -637,29 +638,35 @@ def apply_filters(self, **kwargs): emu_filter = self.options.emulation_only logger.debug("platform filter: " + str(platform_filter)) + logger.debug(" vendor filter: " + str(vendor_filter)) logger.debug(" arch_filter: " + str(arch_filter)) logger.debug(" tag_filter: " + str(tag_filter)) logger.debug(" exclude_tag: " + str(exclude_tag)) default_platforms = False + vendor_platforms = False emulation_platforms = False if all_filter: logger.info("Selecting all possible platforms per test case") # When --all used, any --platform arguments ignored platform_filter = [] - elif not platform_filter and not emu_filter: + elif not platform_filter and not emu_filter and not vendor_filter: logger.info("Selecting default platforms per test case") default_platforms = True elif emu_filter: logger.info("Selecting emulation platforms per test case") emulation_platforms = True + elif vendor_filter: + vendor_platforms = True if platform_filter: self.verify_platforms_existence(platform_filter, f"platform_filter") platforms = list(filter(lambda p: p.name in platform_filter, self.platforms)) elif emu_filter: platforms = list(filter(lambda p: p.simulation != 'na', self.platforms)) + elif vendor_filter: + platforms = list(filter(lambda p: p.vendor in vendor_filter, self.platforms)) elif arch_filter: platforms = list(filter(lambda p: p.arch in arch_filter, self.platforms)) elif default_platforms: @@ -706,8 +713,6 @@ def apply_filters(self, **kwargs): if not c: platform_scope = list(filter(lambda item: item.name in ts.platform_allow, \ self.platforms)) - - # list of instances per testsuite, aka configurations. instance_list = [] for plat in platform_scope: @@ -935,6 +940,10 @@ def apply_filters(self, **kwargs): self.add_instances(instance_list) for instance in list(filter(lambda inst: not inst.platform.simulation != 'na', instance_list)): instance.add_filter("Not an emulated platform", Filters.CMD_LINE) + elif vendor_platforms: + self.add_instances(instance_list) + for instance in list(filter(lambda inst: not inst.platform.vendor in vendor_filter, instance_list)): + instance.add_filter("Not a selected vendor platform", Filters.CMD_LINE) else: self.add_instances(instance_list) diff --git a/scripts/schemas/twister/platform-schema.yaml b/scripts/schemas/twister/platform-schema.yaml index 6524e5f8769..f1ba2d88748 100644 --- a/scripts/schemas/twister/platform-schema.yaml +++ b/scripts/schemas/twister/platform-schema.yaml @@ -41,6 +41,10 @@ mapping: type: str "arch": type: str + "vendor": + type: str + "tier": + type: int "toolchain": type: seq seq: From c3827ec48e2acf5f4c6ec9a2c57e8e38b864b1c0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 22 Jun 2023 18:47:45 +0000 Subject: [PATCH 0860/4498] boards: add vendor to board yaml This is coming from devicetree and corrosponds to what we have in the dts/bindings/vendor-prefixes.txt file. This will allow for static filtering, especially with twister, i.e. no need to build anything to know the vendor of a board All of the vendor data was extracted automatically from the devicetree, so some platforms might not have the right vendor or no vendor at all right now, we need to fix some of the DTS information or do this manually to get this 100% correct. But we are close. Signed-off-by: Anas Nashif --- boards/arc/em_starterkit/em_starterkit.yaml | 1 + boards/arc/em_starterkit/em_starterkit_em11d.yaml | 1 + boards/arc/em_starterkit/em_starterkit_em7d.yaml | 1 + boards/arc/em_starterkit/em_starterkit_em7d_v22.yaml | 1 + boards/arc/emsdp/emsdp.yaml | 1 + boards/arc/emsdp/emsdp_em4.yaml | 1 + boards/arc/emsdp/emsdp_em5d.yaml | 1 + boards/arc/emsdp/emsdp_em6.yaml | 1 + boards/arc/emsdp/emsdp_em7d.yaml | 1 + boards/arc/emsdp/emsdp_em7d_esp.yaml | 1 + boards/arc/emsdp/emsdp_em9d.yaml | 1 + boards/arc/hsdk/hsdk.yaml | 1 + boards/arc/hsdk/hsdk_2cores.yaml | 1 + boards/arc/hsdk4xd/hsdk4xd.yaml | 1 + boards/arc/iotdk/iotdk.yaml | 1 + boards/arc/nsim/nsim_em.yaml | 1 + boards/arc/nsim/nsim_em11d.yaml | 1 + boards/arc/nsim/nsim_em7d_v22.yaml | 1 + boards/arc/nsim/nsim_hs.yaml | 1 + boards/arc/nsim/nsim_hs3x_hostlink.yaml | 1 + boards/arc/nsim/nsim_hs5x.yaml | 1 + boards/arc/nsim/nsim_hs5x_smp.yaml | 1 + boards/arc/nsim/nsim_hs6x.yaml | 1 + boards/arc/nsim/nsim_hs6x_smp.yaml | 1 + boards/arc/nsim/nsim_hs_flash_xip.yaml | 1 + boards/arc/nsim/nsim_hs_mpuv6.yaml | 1 + boards/arc/nsim/nsim_hs_smp.yaml | 1 + boards/arc/nsim/nsim_hs_sram.yaml | 1 + boards/arc/nsim/nsim_sem.yaml | 1 + boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml | 1 + boards/arc/nsim/nsim_vpx5.yaml | 1 + boards/arc/qemu_arc/qemu_arc_em.yaml | 1 + boards/arc/qemu_arc/qemu_arc_hs.yaml | 1 + boards/arc/qemu_arc/qemu_arc_hs5x.yaml | 1 + boards/arc/qemu_arc/qemu_arc_hs6x.yaml | 1 + boards/arc/qemu_arc/qemu_arc_hs_xip.yaml | 1 + boards/arm/96b_aerocore2/96b_aerocore2.yaml | 1 + boards/arm/96b_avenger96/96b_avenger96.yaml | 1 + boards/arm/96b_carbon/96b_carbon.yaml | 1 + boards/arm/96b_carbon_nrf51/96b_carbon_nrf51.yaml | 1 + boards/arm/96b_meerkat96/96b_meerkat96.yaml | 1 + boards/arm/96b_nitrogen/96b_nitrogen.yaml | 1 + boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.yaml | 1 + boards/arm/actinius_icarus/actinius_icarus.yaml | 1 + boards/arm/actinius_icarus/actinius_icarus_ns.yaml | 1 + boards/arm/actinius_icarus_bee/actinius_icarus_bee.yaml | 1 + boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns.yaml | 1 + boards/arm/actinius_icarus_som/actinius_icarus_som.yaml | 1 + boards/arm/actinius_icarus_som/actinius_icarus_som_ns.yaml | 1 + boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk.yaml | 1 + .../arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns.yaml | 1 + .../adafruit_feather_m0_basic_proto.yaml | 1 + .../arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.yaml | 1 + .../adafruit_feather_nrf52840/adafruit_feather_nrf52840.yaml | 1 + .../adafruit_feather_stm32f405/adafruit_feather_stm32f405.yaml | 1 + .../adafruit_itsybitsy_m4_express.yaml | 1 + .../adafruit_itsybitsy_nrf52840.yaml | 1 + boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml | 1 + boards/arm/am62x_m4/am62x_m4_phyboard_lyra.yaml | 1 + boards/arm/am62x_m4/am62x_m4_sk.yaml | 1 + boards/arm/apollo4p_evb/apollo4p_evb.yaml | 1 + boards/arm/arduino_due/arduino_due.yaml | 1 + boards/arm/arduino_giga_r1/arduino_giga_r1_m4.yaml | 1 + boards/arm/arduino_giga_r1/arduino_giga_r1_m7.yaml | 1 + boards/arm/arduino_mkrzero/arduino_mkrzero.yaml | 1 + boards/arm/arduino_nano_33_ble/arduino_nano_33_ble.yaml | 1 + boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense.yaml | 1 + boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml | 1 + boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.yaml | 1 + boards/arm/arduino_portenta_h7/arduino_portenta_h7_m4.yaml | 1 + boards/arm/arduino_portenta_h7/arduino_portenta_h7_m7.yaml | 1 + boards/arm/arduino_zero/arduino_zero.yaml | 1 + boards/arm/ast1030_evb/ast1030_evb.yaml | 1 + boards/arm/atsamc21n_xpro/atsamc21n_xpro.yaml | 1 + boards/arm/atsamd20_xpro/atsamd20_xpro.yaml | 1 + boards/arm/atsamd21_xpro/atsamd21_xpro.yaml | 1 + boards/arm/atsame54_xpro/atsame54_xpro.yaml | 1 + boards/arm/atsaml21_xpro/atsaml21_xpro.yaml | 1 + boards/arm/atsamr21_xpro/atsamr21_xpro.yaml | 1 + boards/arm/atsamr34_xpro/atsamr34_xpro.yaml | 1 + boards/arm/b_g474e_dpow1/b_g474e_dpow1.yaml | 1 + boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml | 1 + boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml | 1 + boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml | 1 + boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns.yaml | 1 + boards/arm/bcm958401m2/bcm958401m2.yaml | 1 + boards/arm/bcm958402m2_m7/bcm958402m2_m7.yaml | 1 + boards/arm/beagle_bcf/beagleconnect_freedom.yaml | 1 + boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.yaml | 1 + boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.yaml | 1 + boards/arm/bl5340_dvk/bl5340_dvk_cpunet.yaml | 1 + boards/arm/bl652_dvk/bl652_dvk.yaml | 1 + boards/arm/bl653_dvk/bl653_dvk.yaml | 1 + boards/arm/bl654_dvk/bl654_dvk.yaml | 1 + boards/arm/bl654_sensor_board/bl654_sensor_board.yaml | 1 + boards/arm/bl654_usb/bl654_usb.yaml | 1 + boards/arm/blackpill_f401cc/blackpill_f401cc.yaml | 1 + boards/arm/blackpill_f401ce/blackpill_f401ce.yaml | 1 + boards/arm/blackpill_f411ce/blackpill_f411ce.yaml | 1 + .../blueclover_plt_demo_v2_nrf52832.yaml | 1 + boards/arm/bt510/bt510.yaml | 1 + boards/arm/bt610/bt610.yaml | 1 + boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml | 1 + boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml | 1 + boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml | 1 + boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml | 1 + boards/arm/cc3220sf_launchxl/cc3220sf_launchxl.yaml | 1 + boards/arm/cc3235sf_launchxl/cc3235sf_launchxl.yaml | 1 + boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.yaml | 1 + .../contextualelectronics_abc/contextualelectronics_abc.yaml | 1 + boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml | 1 + boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml | 1 + boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml | 1 + boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml | 1 + boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml | 1 + boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml | 1 + boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml | 1 + boards/arm/cyclonev_socdk/cyclonev_socdk.yaml | 1 + boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml | 1 + boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml | 1 + boards/arm/degu_evk/degu_evk.yaml | 1 + boards/arm/disco_l475_iot1/disco_l475_iot1.yaml | 1 + boards/arm/efm32gg_sltb009a/efm32gg_sltb009a.yaml | 1 + boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml | 1 + boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml | 1 + boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml | 1 + boards/arm/efm32pg_stk3401a/efm32pg_stk3401a.yaml | 1 + boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml | 1 + boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml | 1 + boards/arm/efm32wg_stk3800/efm32wg_stk3800.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4104a.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4170a.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4180a.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4187c.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4250b.yaml | 1 + boards/arm/efr32_radio/efr32_radio_brd4255a.yaml | 1 + boards/arm/efr32_thunderboard/efr32bg22_brd4184a.yaml | 1 + boards/arm/efr32_thunderboard/efr32bg22_brd4184b.yaml | 1 + boards/arm/efr32_thunderboard/efr32bg27_brd2602a.yaml | 1 + boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.yaml | 1 + boards/arm/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml | 1 + boards/arm/ev11l78a/ev11l78a.yaml | 1 + boards/arm/faze/faze.yaml | 1 + boards/arm/frdm_k22f/frdm_k22f.yaml | 1 + boards/arm/frdm_k64f/frdm_k64f.yaml | 1 + boards/arm/frdm_k82f/frdm_k82f.yaml | 1 + boards/arm/frdm_kl25z/frdm_kl25z.yaml | 1 + boards/arm/frdm_kw41z/frdm_kw41z.yaml | 1 + boards/arm/gd32a503v_eval/gd32a503v_eval.yaml | 1 + boards/arm/gd32e103v_eval/gd32e103v_eval.yaml | 1 + boards/arm/gd32e507v_start/gd32e507v_start.yaml | 1 + boards/arm/gd32e507z_eval/gd32e507z_eval.yaml | 1 + boards/arm/gd32f350r_eval/gd32f350r_eval.yaml | 1 + boards/arm/gd32f403z_eval/gd32f403z_eval.yaml | 1 + boards/arm/gd32f407v_start/gd32f407v_start.yaml | 1 + boards/arm/gd32f450i_eval/gd32f450i_eval.yaml | 1 + boards/arm/gd32f450v_start/gd32f450v_start.yaml | 1 + boards/arm/gd32f450z_eval/gd32f450z_eval.yaml | 1 + boards/arm/gd32f470i_eval/gd32f470i_eval.yaml | 1 + boards/arm/gd32l233r_eval/gd32l233r_eval.yaml | 1 + boards/arm/google_dragonclaw/google_dragonclaw.yaml | 1 + boards/arm/google_kukui/google_kukui.yaml | 1 + boards/arm/google_twinkie_v2/google_twinkie_v2.yaml | 1 + boards/arm/hexiwear_k64/hexiwear_k64.yaml | 1 + boards/arm/hexiwear_kw40z/hexiwear_kw40z.yaml | 1 + boards/arm/ip_k66f/ip_k66f.yaml | 1 + boards/arm/kv260_r5/kv260_r5.yaml | 1 + boards/arm/legend/legend.yaml | 1 + boards/arm/lora_e5_dev_board/lora_e5_dev_board.yaml | 1 + boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml | 1 + boards/arm/lpcxpresso51u68/lpcxpresso51u68.yaml | 1 + boards/arm/lpcxpresso54114/lpcxpresso54114_m0.yaml | 1 + boards/arm/lpcxpresso54114/lpcxpresso54114_m4.yaml | 1 + boards/arm/lpcxpresso55s06/lpcxpresso55s06.yaml | 1 + boards/arm/lpcxpresso55s16/lpcxpresso55s16.yaml | 1 + boards/arm/lpcxpresso55s28/lpcxpresso55s28.yaml | 1 + boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml | 1 + boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml | 1 + boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml | 1 + boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml | 1 + .../arm/mec1501modular_assy6885/mec1501modular_assy6885.yaml | 1 + boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.yaml | 1 + boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml | 1 + .../arm/mec172xmodular_assy6930/mec172xmodular_assy6930.yaml | 1 + boards/arm/mercury_xu/mercury_xu.yaml | 1 + boards/arm/mg100/mg100.yaml | 1 + boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml | 1 + .../arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml | 1 + boards/arm/mimx8mm_evk/mimx8mm_evk.yaml | 1 + boards/arm/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis.yaml | 1 + boards/arm/mimx8mp_evk/mimx8mp_evk_ddr.yaml | 1 + boards/arm/mimx8mp_evk/mimx8mp_evk_itcm.yaml | 1 + .../arm/mimx8mp_phyboard_pollux/mimx8mp_phyboard_pollux.yaml | 1 + boards/arm/mimx8mq_evk/mimx8mq_evk_cm4.yaml | 1 + boards/arm/mimxrt1010_evk/mimxrt1010_evk.yaml | 1 + boards/arm/mimxrt1015_evk/mimxrt1015_evk.yaml | 1 + boards/arm/mimxrt1020_evk/mimxrt1020_evk.yaml | 1 + boards/arm/mimxrt1024_evk/mimxrt1024_evk.yaml | 1 + boards/arm/mimxrt1040_evk/mimxrt1040_evk.yaml | 1 + boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml | 1 + boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml | 1 + boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml | 1 + boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml | 1 + boards/arm/mimxrt1060_evk/mimxrt1060_evkb.yaml | 1 + boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml | 1 + boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml | 1 + boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm4.yaml | 1 + boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm7.yaml | 1 + boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm4.yaml | 1 + boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.yaml | 1 + boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.yaml | 1 + boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7.yaml | 1 + boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.yaml | 1 + boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml | 1 + boards/arm/mm_feather/mm_feather.yaml | 1 + boards/arm/mm_swiftio/mm_swiftio.yaml | 1 + boards/arm/mps2_an385/mps2_an385.yaml | 1 + boards/arm/mps2_an521/mps2_an521.yaml | 1 + boards/arm/mps3_an547/mps3_an547.yaml | 1 + boards/arm/mr_canhubk3/mr_canhubk3.yaml | 1 + .../arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml | 1 + boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml | 1 + boards/arm/nrf51_ble400/nrf51_ble400.yaml | 1 + boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml | 1 + boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.yaml | 1 + boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.yaml | 1 + boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.yaml | 1 + boards/arm/nrf52840_blip/nrf52840_blip.yaml | 1 + boards/arm/nrf52840_mdk/nrf52840_mdk.yaml | 1 + boards/arm/nrf52840_papyr/nrf52840_papyr.yaml | 1 + boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.yaml | 1 + boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml | 1 + .../arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.yaml | 1 + boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml | 1 + boards/arm/nrf52_sparkfun/nrf52_sparkfun.yaml | 1 + boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml | 1 + boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.yaml | 1 + boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml | 1 + .../nrf5340_audio_dk_nrf5340_cpuapp.yaml | 1 + .../nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml | 1 + .../nrf5340_audio_dk_nrf5340_cpunet.yaml | 1 + boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml | 1 + boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.yaml | 1 + boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml | 1 + boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.yaml | 1 + boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml | 1 + boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns.yaml | 1 + boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161.yaml | 1 + boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.yaml | 1 + boards/arm/nucleo_c031c6/nucleo_c031c6.yaml | 1 + boards/arm/nucleo_f030r8/nucleo_f030r8.yaml | 1 + boards/arm/nucleo_f070rb/nucleo_f070rb.yaml | 1 + boards/arm/nucleo_f091rc/nucleo_f091rc.yaml | 1 + boards/arm/nucleo_f103rb/nucleo_f103rb.yaml | 1 + boards/arm/nucleo_f207zg/nucleo_f207zg.yaml | 1 + boards/arm/nucleo_f302r8/nucleo_f302r8.yaml | 1 + boards/arm/nucleo_f303k8/nucleo_f303k8.yaml | 1 + boards/arm/nucleo_f303re/nucleo_f303re.yaml | 1 + boards/arm/nucleo_f334r8/nucleo_f334r8.yaml | 1 + boards/arm/nucleo_f401re/nucleo_f401re.yaml | 1 + boards/arm/nucleo_f410rb/nucleo_f410rb.yaml | 1 + boards/arm/nucleo_f411re/nucleo_f411re.yaml | 1 + boards/arm/nucleo_f412zg/nucleo_f412zg.yaml | 1 + boards/arm/nucleo_f413zh/nucleo_f413zh.yaml | 1 + boards/arm/nucleo_f429zi/nucleo_f429zi.yaml | 1 + boards/arm/nucleo_f446re/nucleo_f446re.yaml | 1 + boards/arm/nucleo_f446ze/nucleo_f446ze.yaml | 1 + boards/arm/nucleo_f746zg/nucleo_f746zg.yaml | 1 + boards/arm/nucleo_f756zg/nucleo_f756zg.yaml | 1 + boards/arm/nucleo_f767zi/nucleo_f767zi.yaml | 1 + boards/arm/nucleo_g031k8/nucleo_g031k8.yaml | 1 + boards/arm/nucleo_g070rb/nucleo_g070rb.yaml | 1 + boards/arm/nucleo_g071rb/nucleo_g071rb.yaml | 1 + boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml | 1 + boards/arm/nucleo_g431rb/nucleo_g431rb.yaml | 1 + boards/arm/nucleo_g474re/nucleo_g474re.yaml | 1 + boards/arm/nucleo_h563zi/nucleo_h563zi.yaml | 1 + boards/arm/nucleo_h723zg/nucleo_h723zg.yaml | 1 + boards/arm/nucleo_h743zi/nucleo_h743zi.yaml | 1 + boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml | 1 + boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml | 1 + boards/arm/nucleo_h753zi/nucleo_h753zi.yaml | 1 + boards/arm/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml | 1 + boards/arm/nucleo_l031k6/nucleo_l031k6.yaml | 1 + boards/arm/nucleo_l053r8/nucleo_l053r8.yaml | 1 + boards/arm/nucleo_l073rz/nucleo_l073rz.yaml | 1 + boards/arm/nucleo_l152re/nucleo_l152re.yaml | 1 + boards/arm/nucleo_l412rb_p/nucleo_l412rb_p.yaml | 1 + boards/arm/nucleo_l432kc/nucleo_l432kc.yaml | 1 + boards/arm/nucleo_l433rc_p/nucleo_l433rc_p.yaml | 1 + boards/arm/nucleo_l452re/nucleo_l452re.yaml | 1 + boards/arm/nucleo_l452re/nucleo_l452re_p.yaml | 1 + boards/arm/nucleo_l476rg/nucleo_l476rg.yaml | 1 + boards/arm/nucleo_l496zg/nucleo_l496zg.yaml | 1 + boards/arm/nucleo_l4a6zg/nucleo_l4a6zg.yaml | 1 + boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml | 1 + boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.yaml | 1 + boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml | 1 + boards/arm/nucleo_u575zi_q/nucleo_u575zi_q.yaml | 1 + boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml | 1 + boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml | 1 + boards/arm/nucleo_wl55jc/nucleo_wl55jc.yaml | 1 + boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml | 3 +++ boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml | 1 + .../olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.yaml | 1 + boards/arm/olimex_stm32_e407/olimex_stm32_e407.yaml | 1 + boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml | 1 + boards/arm/olimex_stm32_h405/olimex_stm32_h405.yaml | 1 + boards/arm/olimex_stm32_h407/olimex_stm32_h407.yaml | 1 + boards/arm/olimex_stm32_p405/olimex_stm32_p405.yaml | 1 + boards/arm/olimexino_stm32/olimexino_stm32.yaml | 1 + boards/arm/particle_argon/particle_argon.yaml | 1 + boards/arm/particle_boron/particle_boron.yaml | 1 + boards/arm/particle_xenon/particle_xenon.yaml | 1 + boards/arm/pico_pi_m4/pico_pi_m4.yaml | 1 + boards/arm/pinetime_devkit0/pinetime_devkit0.yaml | 3 +++ boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml | 1 + boards/arm/qemu_cortex_a9/qemu_cortex_a9.yaml | 1 + boards/arm/qemu_cortex_m3/qemu_cortex_m3.yaml | 1 + boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml | 1 + boards/arm/qomu/qomu.yaml | 1 + boards/arm/quick_feather/quick_feather.yaml | 1 + boards/arm/rak4631_nrf52840/rak4631_nrf52840.yaml | 1 + boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml | 1 + boards/arm/rcar_h3_salvatorx/rcar_h3_salvatorx_cr7.yaml | 1 + boards/arm/rcar_h3ulcb/rcar_h3ulcb_cr7.yaml | 1 + boards/arm/rddrone_fmuk66/rddrone_fmuk66.yaml | 1 + boards/arm/reel_board/reel_board.yaml | 1 + boards/arm/reel_board/reel_board_v2.yaml | 1 + boards/arm/rm1xx_dvk/rm1xx_dvk.yaml | 1 + boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml | 1 + boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml | 1 + boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml | 1 + boards/arm/sam4e_xpro/sam4e_xpro.yaml | 1 + boards/arm/sam4l_ek/sam4l_ek.yaml | 1 + boards/arm/sam4s_xplained/sam4s_xplained.yaml | 1 + boards/arm/sam_e70_xplained/sam_e70_xplained.yaml | 1 + boards/arm/sam_e70_xplained/sam_e70b_xplained.yaml | 1 + boards/arm/sam_v71_xult/sam_v71_xult.yaml | 1 + boards/arm/sam_v71_xult/sam_v71b_xult.yaml | 1 + boards/arm/seeeduino_xiao/seeeduino_xiao.yaml | 1 + boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml | 1 + boards/arm/sensortile_box/sensortile_box.yaml | 1 + .../sparkfun_thing_plus_nrf9160.yaml | 1 + .../sparkfun_thing_plus_nrf9160_ns.yaml | 1 + boards/arm/steval_fcu001v1/steval_fcu001v1.yaml | 1 + boards/arm/stm3210c_eval/stm3210c_eval.yaml | 1 + boards/arm/stm32373c_eval/stm32373c_eval.yaml | 1 + boards/arm/stm32_min_dev/stm32_min_dev_black.yaml | 1 + boards/arm/stm32_min_dev/stm32_min_dev_blue.yaml | 1 + boards/arm/stm32f072_eval/stm32f072_eval.yaml | 1 + boards/arm/stm32f072b_disco/stm32f072b_disco.yaml | 1 + boards/arm/stm32f0_disco/stm32f0_disco.yaml | 1 + boards/arm/stm32f103_mini/stm32f103_mini.yaml | 1 + boards/arm/stm32f3_disco/stm32f3_disco.yaml | 1 + boards/arm/stm32f411e_disco/stm32f411e_disco.yaml | 1 + boards/arm/stm32f412g_disco/stm32f412g_disco.yaml | 1 + boards/arm/stm32f429i_disc1/stm32f429i_disc1.yaml | 1 + boards/arm/stm32f469i_disco/stm32f469i_disco.yaml | 1 + boards/arm/stm32f4_disco/stm32f4_disco.yaml | 1 + boards/arm/stm32f723e_disco/stm32f723e_disco.yaml | 1 + boards/arm/stm32f746g_disco/stm32f746g_disco.yaml | 1 + boards/arm/stm32f7508_dk/stm32f7508_dk.yaml | 1 + boards/arm/stm32f769i_disco/stm32f769i_disco.yaml | 2 ++ boards/arm/stm32g0316_disco/stm32g0316_disco.yaml | 1 + boards/arm/stm32g071b_disco/stm32g071b_disco.yaml | 1 + boards/arm/stm32g081b_eval/stm32g081b_eval.yaml | 1 + boards/arm/stm32h573i_dk/stm32h573i_dk.yaml | 1 + boards/arm/stm32h735g_disco/stm32h735g_disco.yaml | 1 + boards/arm/stm32h747i_disco/stm32h747i_disco_m4.yaml | 1 + boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml | 1 + boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.yaml | 1 + boards/arm/stm32l1_disco/stm32l1_disco.yaml | 1 + boards/arm/stm32l476g_disco/stm32l476g_disco.yaml | 1 + boards/arm/stm32l496g_disco/stm32l496g_disco.yaml | 1 + boards/arm/stm32l562e_dk/stm32l562e_dk.yaml | 1 + boards/arm/stm32l562e_dk/stm32l562e_dk_ns.yaml | 1 + boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml | 1 + boards/arm/stm32vl_disco/stm32vl_disco.yaml | 1 + boards/arm/swan_r5/swan_r5.yaml | 1 + boards/arm/tdk_robokit1/tdk_robokit1.yaml | 1 + boards/arm/teensy4/teensy40.yaml | 1 + boards/arm/teensy4/teensy41.yaml | 1 + boards/arm/thingy52_nrf52832/thingy52_nrf52832.yaml | 1 + boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp.yaml | 1 + boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns.yaml | 1 + boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.yaml | 1 + boards/arm/twr_ke18f/twr_ke18f.yaml | 1 + boards/arm/twr_kv58f220m/twr_kv58f220m.yaml | 1 + .../arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.yaml | 1 + .../arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.yaml | 1 + .../arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.yaml | 1 + .../arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.yaml | 1 + .../arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.yaml | 1 + .../arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.yaml | 1 + boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.yaml | 1 + boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.yaml | 1 + boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.yaml | 1 + boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.yaml | 1 + boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.yaml | 1 + boards/arm/usb_kw24d512/usb_kw24d512.yaml | 1 + boards/arm/v2m_beetle/v2m_beetle.yaml | 1 + boards/arm/v2m_musca_b1/v2m_musca_b1.yaml | 1 + boards/arm/v2m_musca_b1/v2m_musca_b1_ns.yaml | 1 + boards/arm/v2m_musca_s1/v2m_musca_s1.yaml | 1 + boards/arm/v2m_musca_s1/v2m_musca_s1_ns.yaml | 1 + boards/arm/vmu_rt1170/vmu_rt1170.yaml | 1 + boards/arm/warp7_m4/warp7_m4.yaml | 1 + boards/arm/waveshare_open103z/waveshare_open103z.yaml | 1 + boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.yaml | 1 + boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.yaml | 1 + boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.yaml | 1 + boards/arm/wio_terminal/wio_terminal.yaml | 1 + boards/arm/xiao_ble/xiao_ble.yaml | 1 + boards/arm/xiao_ble/xiao_ble_sense.yaml | 1 + boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml | 1 + boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml | 1 + boards/arm/zybo/zybo.yaml | 1 + boards/arm64/bcm958402m2_a72/bcm958402m2_a72.yaml | 1 + .../arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.yaml | 1 + .../fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_smp_ns.yaml | 1 + boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.yaml | 1 + boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r_smp.yaml | 1 + .../intel_socfpga_agilex5_socdk.yaml | 1 + .../intel_socfpga_agilex_socdk/intel_socfpga_agilex_socdk.yaml | 1 + boards/arm64/khadas_edgev/khadas_edgev.yaml | 1 + boards/arm64/mimx8mm_evk/mimx8mm_evk_a53.yaml | 1 + boards/arm64/mimx8mm_evk/mimx8mm_evk_a53_smp.yaml | 1 + boards/arm64/mimx8mn_evk/mimx8mn_evk_a53.yaml | 1 + boards/arm64/mimx8mn_evk/mimx8mn_evk_a53_smp.yaml | 1 + boards/arm64/mimx8mp_evk/mimx8mp_evk_a53.yaml | 1 + boards/arm64/mimx8mp_evk/mimx8mp_evk_a53_smp.yaml | 1 + boards/arm64/mimx93_evk/mimx93_evk_a55.yaml | 1 + boards/arm64/mimx93_evk/mimx93_evk_a55_sof.yaml | 1 + boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb.yaml | 1 + boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_2cores.yaml | 1 + boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_4cores.yaml | 1 + boards/arm64/phycore_am62x_a53/phycore_am62x_a53.yaml | 1 + boards/arm64/qemu_cortex_a53/qemu_cortex_a53.yaml | 1 + boards/arm64/qemu_cortex_a53/qemu_cortex_a53_smp.yaml | 1 + boards/arm64/qemu_cortex_a53/qemu_cortex_a53_xip.yaml | 1 + boards/arm64/qemu_kvm_arm64/qemu_kvm_arm64.yaml | 1 + boards/arm64/rcar_h3ulcb_ca57/rcar_h3ulcb_ca57.yaml | 1 + boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml | 1 + boards/arm64/xenvm/xenvm.yaml | 1 + boards/arm64/xenvm/xenvm_gicv3.yaml | 1 + boards/mips/qemu_malta/qemu_malta.yaml | 1 + boards/mips/qemu_malta/qemu_malta_be.yaml | 1 + boards/nios2/altera_max10/altera_max10.yaml | 1 + boards/nios2/qemu_nios2/qemu_nios2.yaml | 1 + boards/posix/native_posix/native_posix.yaml | 1 + boards/posix/native_posix/native_posix_64.yaml | 1 + boards/posix/native_sim/native_sim.yaml | 1 + boards/posix/native_sim/native_sim_64.yaml | 1 + boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml | 1 + boards/riscv/esp32c3_devkitm/esp32c3_devkitm.yaml | 1 + boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml | 1 + boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml | 1 + boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml | 1 + boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml | 1 + boards/riscv/hifive1/hifive1.yaml | 1 + boards/riscv/hifive1_revb/hifive1_revb.yaml | 1 + boards/riscv/hifive_unleashed/hifive_unleashed.yaml | 1 + boards/riscv/hifive_unmatched/hifive_unmatched.yaml | 1 + boards/riscv/icev_wireless/icev_wireless.yaml | 1 + boards/riscv/it82xx2_evb/it82xx2_evb.yaml | 1 + boards/riscv/it8xxx2_evb/it8xxx2_evb.yaml | 1 + boards/riscv/litex_vexriscv/litex_vexriscv.yaml | 1 + boards/riscv/longan_nano/longan_nano.yaml | 1 + boards/riscv/longan_nano/longan_nano_lite.yaml | 1 + boards/riscv/m2gl025_miv/m2gl025_miv.yaml | 1 + boards/riscv/mpfs_icicle/mpfs_icicle.yaml | 1 + boards/riscv/niosv_g/niosv_g.yaml | 1 + boards/riscv/niosv_m/niosv_m.yaml | 1 + boards/riscv/opentitan_earlgrey/opentitan_earlgrey.yaml | 1 + boards/riscv/rv32m1_vega/rv32m1_vega_ri5cy.yaml | 1 + boards/riscv/rv32m1_vega/rv32m1_vega_zero_riscy.yaml | 1 + .../sparkfun_red_v_things_plus/sparkfun_red_v_things_plus.yaml | 1 + boards/riscv/stamp_c3/stamp_c3.yaml | 1 + boards/riscv/titanium_ti60_f225/titanium_ti60_f225.yaml | 1 + boards/riscv/tlsr9518adk80d/tlsr9518adk80d.yaml | 1 + boards/riscv/xiao_esp32c3/xiao_esp32c3.yaml | 1 + boards/sparc/generic_leon3/generic_leon3.yaml | 1 + boards/sparc/gr716a_mini/gr716a_mini.yaml | 1 + boards/x86/intel_adl/intel_adl_crb.yaml | 1 + boards/x86/intel_adl/intel_adl_rvp.yaml | 1 + boards/x86/intel_ehl/intel_ehl_crb.yaml | 1 + boards/x86/intel_ehl/intel_ehl_crb_sbl.yaml | 1 + boards/x86/intel_ish/intel_ish_5_4_1.yaml | 1 + boards/x86/intel_ish/intel_ish_5_6_0.yaml | 1 + boards/x86/intel_ish/intel_ish_5_8_0.yaml | 1 + boards/x86/intel_rpl/intel_rpl_s_crb.yaml | 1 + boards/x86/qemu_x86/qemu_x86.yaml | 1 + boards/x86/qemu_x86/qemu_x86_64.yaml | 1 + boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml | 1 + boards/x86/qemu_x86/qemu_x86_lakemont.yaml | 1 + boards/x86/qemu_x86/qemu_x86_nokpti.yaml | 1 + boards/x86/qemu_x86/qemu_x86_nommu.yaml | 1 + boards/x86/qemu_x86/qemu_x86_nopae.yaml | 1 + boards/x86/qemu_x86/qemu_x86_tiny.yaml | 1 + boards/x86/qemu_x86/qemu_x86_virt.yaml | 1 + boards/x86/qemu_x86/qemu_x86_xip.yaml | 1 + boards/xtensa/esp32_devkitc_wroom/esp32_devkitc_wroom.yaml | 1 + boards/xtensa/esp32_devkitc_wrover/esp32_devkitc_wrover.yaml | 1 + boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.yaml | 1 + boards/xtensa/esp32_net/esp32_net.yaml | 1 + boards/xtensa/esp32s2_franzininho/esp32s2_franzininho.yaml | 1 + boards/xtensa/esp32s2_saola/esp32s2_saola.yaml | 1 + boards/xtensa/esp32s3_devkitm/esp32s3_devkitm.yaml | 1 + boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core.yaml | 1 + boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core_usb.yaml | 1 + boards/xtensa/esp_wrover_kit/esp_wrover_kit.yaml | 1 + boards/xtensa/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2.yaml | 1 + boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.yaml | 1 + boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.yaml | 1 + boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml | 1 + boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.yaml | 1 + boards/xtensa/m5stack_core2/m5stack_core2.yaml | 1 + boards/xtensa/m5stickc_plus/m5stickc_plus.yaml | 1 + boards/xtensa/odroid_go/odroid_go.yaml | 1 + boards/xtensa/olimex_esp32_evb/olimex_esp32_evb.yaml | 1 + boards/xtensa/qemu_xtensa/qemu_xtensa.yaml | 1 + boards/xtensa/xiao_esp32s3/xiao_esp32s3.yaml | 1 + boards/xtensa/yd_esp32/yd_esp32.yaml | 1 + scripts/pylib/twister/twisterlib/testplan.py | 1 + 525 files changed, 530 insertions(+) diff --git a/boards/arc/em_starterkit/em_starterkit.yaml b/boards/arc/em_starterkit/em_starterkit.yaml index f2590fcac76..f489b0a28ac 100644 --- a/boards/arc/em_starterkit/em_starterkit.yaml +++ b/boards/arc/em_starterkit/em_starterkit.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/em_starterkit/em_starterkit_em11d.yaml b/boards/arc/em_starterkit/em_starterkit_em11d.yaml index 7d8b863f4bb..f06dccbc8e7 100644 --- a/boards/arc/em_starterkit/em_starterkit_em11d.yaml +++ b/boards/arc/em_starterkit/em_starterkit_em11d.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/em_starterkit/em_starterkit_em7d.yaml b/boards/arc/em_starterkit/em_starterkit_em7d.yaml index 9d3e6d6cf7f..d4ab57393b4 100644 --- a/boards/arc/em_starterkit/em_starterkit_em7d.yaml +++ b/boards/arc/em_starterkit/em_starterkit_em7d.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_v22.yaml b/boards/arc/em_starterkit/em_starterkit_em7d_v22.yaml index 0b7d9de3127..b7eb883286f 100644 --- a/boards/arc/em_starterkit/em_starterkit_em7d_v22.yaml +++ b/boards/arc/em_starterkit/em_starterkit_em7d_v22.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp.yaml b/boards/arc/emsdp/emsdp.yaml index 44de46e8a7a..b6fa38fb515 100644 --- a/boards/arc/emsdp/emsdp.yaml +++ b/boards/arc/emsdp/emsdp.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em4.yaml b/boards/arc/emsdp/emsdp_em4.yaml index bd3757519d5..a146eb72bff 100644 --- a/boards/arc/emsdp/emsdp_em4.yaml +++ b/boards/arc/emsdp/emsdp_em4.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em5d.yaml b/boards/arc/emsdp/emsdp_em5d.yaml index 5ab93b86d47..d0117790975 100644 --- a/boards/arc/emsdp/emsdp_em5d.yaml +++ b/boards/arc/emsdp/emsdp_em5d.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em6.yaml b/boards/arc/emsdp/emsdp_em6.yaml index 804cdb91186..2584fb8a953 100644 --- a/boards/arc/emsdp/emsdp_em6.yaml +++ b/boards/arc/emsdp/emsdp_em6.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em7d.yaml b/boards/arc/emsdp/emsdp_em7d.yaml index 3bf708259fc..57f78c3c7e7 100644 --- a/boards/arc/emsdp/emsdp_em7d.yaml +++ b/boards/arc/emsdp/emsdp_em7d.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em7d_esp.yaml b/boards/arc/emsdp/emsdp_em7d_esp.yaml index cdf45ea786f..e3387d64798 100644 --- a/boards/arc/emsdp/emsdp_em7d_esp.yaml +++ b/boards/arc/emsdp/emsdp_em7d_esp.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/emsdp/emsdp_em9d.yaml b/boards/arc/emsdp/emsdp_em9d.yaml index d495ec11eb3..7bdf0340232 100644 --- a/boards/arc/emsdp/emsdp_em9d.yaml +++ b/boards/arc/emsdp/emsdp_em9d.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/hsdk/hsdk.yaml b/boards/arc/hsdk/hsdk.yaml index fba768d57d4..3547f1a313b 100644 --- a/boards/arc/hsdk/hsdk.yaml +++ b/boards/arc/hsdk/hsdk.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/hsdk/hsdk_2cores.yaml b/boards/arc/hsdk/hsdk_2cores.yaml index ea811866a28..d21fa765887 100644 --- a/boards/arc/hsdk/hsdk_2cores.yaml +++ b/boards/arc/hsdk/hsdk_2cores.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/hsdk4xd/hsdk4xd.yaml b/boards/arc/hsdk4xd/hsdk4xd.yaml index 053de272808..798d7be5f2b 100644 --- a/boards/arc/hsdk4xd/hsdk4xd.yaml +++ b/boards/arc/hsdk4xd/hsdk4xd.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/iotdk/iotdk.yaml b/boards/arc/iotdk/iotdk.yaml index 0f64c574bc4..5ec9fdc8d15 100644 --- a/boards/arc/iotdk/iotdk.yaml +++ b/boards/arc/iotdk/iotdk.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_em.yaml b/boards/arc/nsim/nsim_em.yaml index 7df93725121..9eb0c88ad50 100644 --- a/boards/arc/nsim/nsim_em.yaml +++ b/boards/arc/nsim/nsim_em.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_em11d.yaml b/boards/arc/nsim/nsim_em11d.yaml index f88f0dbdc64..a37c9c3888d 100644 --- a/boards/arc/nsim/nsim_em11d.yaml +++ b/boards/arc/nsim/nsim_em11d.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_em7d_v22.yaml b/boards/arc/nsim/nsim_em7d_v22.yaml index 34ec2889029..036e9b37bae 100644 --- a/boards/arc/nsim/nsim_em7d_v22.yaml +++ b/boards/arc/nsim/nsim_em7d_v22.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs.yaml b/boards/arc/nsim/nsim_hs.yaml index 757fffa95e3..18f2a71039a 100644 --- a/boards/arc/nsim/nsim_hs.yaml +++ b/boards/arc/nsim/nsim_hs.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs3x_hostlink.yaml b/boards/arc/nsim/nsim_hs3x_hostlink.yaml index 4c7d60f42f5..f23cdc18501 100644 --- a/boards/arc/nsim/nsim_hs3x_hostlink.yaml +++ b/boards/arc/nsim/nsim_hs3x_hostlink.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs5x.yaml b/boards/arc/nsim/nsim_hs5x.yaml index 7572a51a294..14d6cf03f8e 100644 --- a/boards/arc/nsim/nsim_hs5x.yaml +++ b/boards/arc/nsim/nsim_hs5x.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs5x_smp.yaml b/boards/arc/nsim/nsim_hs5x_smp.yaml index 70bb7cdb84e..21015ecee69 100644 --- a/boards/arc/nsim/nsim_hs5x_smp.yaml +++ b/boards/arc/nsim/nsim_hs5x_smp.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs6x.yaml b/boards/arc/nsim/nsim_hs6x.yaml index d2ed2ec1741..08b881eb743 100644 --- a/boards/arc/nsim/nsim_hs6x.yaml +++ b/boards/arc/nsim/nsim_hs6x.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs6x_smp.yaml b/boards/arc/nsim/nsim_hs6x_smp.yaml index 1b40e67483d..d05faa51b29 100644 --- a/boards/arc/nsim/nsim_hs6x_smp.yaml +++ b/boards/arc/nsim/nsim_hs6x_smp.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs_flash_xip.yaml b/boards/arc/nsim/nsim_hs_flash_xip.yaml index 8ee16f6bdfd..02da85f5864 100644 --- a/boards/arc/nsim/nsim_hs_flash_xip.yaml +++ b/boards/arc/nsim/nsim_hs_flash_xip.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs_mpuv6.yaml b/boards/arc/nsim/nsim_hs_mpuv6.yaml index 2f25b48f9b9..cf1fdba06a7 100644 --- a/boards/arc/nsim/nsim_hs_mpuv6.yaml +++ b/boards/arc/nsim/nsim_hs_mpuv6.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs_smp.yaml b/boards/arc/nsim/nsim_hs_smp.yaml index e4d7a3c8397..ccc1fab694d 100644 --- a/boards/arc/nsim/nsim_hs_smp.yaml +++ b/boards/arc/nsim/nsim_hs_smp.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_hs_sram.yaml b/boards/arc/nsim/nsim_hs_sram.yaml index 0d17dd55ff3..7a99a91ceff 100644 --- a/boards/arc/nsim/nsim_hs_sram.yaml +++ b/boards/arc/nsim/nsim_hs_sram.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_sem.yaml b/boards/arc/nsim/nsim_sem.yaml index 3f33ce0392b..13afb56ca69 100644 --- a/boards/arc/nsim/nsim_sem.yaml +++ b/boards/arc/nsim/nsim_sem.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml b/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml index 58baff5e916..45949212a00 100644 --- a/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml +++ b/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/nsim/nsim_vpx5.yaml b/boards/arc/nsim/nsim_vpx5.yaml index 585a107c3b0..4d5a3c8e96e 100644 --- a/boards/arc/nsim/nsim_vpx5.yaml +++ b/boards/arc/nsim/nsim_vpx5.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/qemu_arc/qemu_arc_em.yaml b/boards/arc/qemu_arc/qemu_arc_em.yaml index d9bcc21f2e5..2c1db9ed374 100644 --- a/boards/arc/qemu_arc/qemu_arc_em.yaml +++ b/boards/arc/qemu_arc/qemu_arc_em.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/qemu_arc/qemu_arc_hs.yaml b/boards/arc/qemu_arc/qemu_arc_hs.yaml index 05b4428710f..468b3a05215 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs.yaml +++ b/boards/arc/qemu_arc/qemu_arc_hs.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/qemu_arc/qemu_arc_hs5x.yaml b/boards/arc/qemu_arc/qemu_arc_hs5x.yaml index 29e57d185fd..0abe51e0472 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs5x.yaml +++ b/boards/arc/qemu_arc/qemu_arc_hs5x.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/qemu_arc/qemu_arc_hs6x.yaml b/boards/arc/qemu_arc/qemu_arc_hs6x.yaml index 6c8d0c1102f..5346dbc1251 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs6x.yaml +++ b/boards/arc/qemu_arc/qemu_arc_hs6x.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arc/qemu_arc/qemu_arc_hs_xip.yaml b/boards/arc/qemu_arc/qemu_arc_hs_xip.yaml index 65203386eed..829045078d2 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_xip.yaml +++ b/boards/arc/qemu_arc/qemu_arc_hs_xip.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: snps diff --git a/boards/arm/96b_aerocore2/96b_aerocore2.yaml b/boards/arm/96b_aerocore2/96b_aerocore2.yaml index d2ea3962b12..b066c364322 100644 --- a/boards/arm/96b_aerocore2/96b_aerocore2.yaml +++ b/boards/arm/96b_aerocore2/96b_aerocore2.yaml @@ -19,3 +19,4 @@ supported: - adc ram: 256 flash: 2048 +vendor: gumstix diff --git a/boards/arm/96b_avenger96/96b_avenger96.yaml b/boards/arm/96b_avenger96/96b_avenger96.yaml index 2b1c86243ef..e1e21e4d4c7 100644 --- a/boards/arm/96b_avenger96/96b_avenger96.yaml +++ b/boards/arm/96b_avenger96/96b_avenger96.yaml @@ -22,3 +22,4 @@ testing: - nfc ram: 256 flash: 64 +vendor: arrow diff --git a/boards/arm/96b_carbon/96b_carbon.yaml b/boards/arm/96b_carbon/96b_carbon.yaml index 53bb4aa953f..3b465d9e676 100644 --- a/boards/arm/96b_carbon/96b_carbon.yaml +++ b/boards/arm/96b_carbon/96b_carbon.yaml @@ -15,3 +15,4 @@ supported: - usb_device ram: 96 flash: 512 +vendor: seeed diff --git a/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51.yaml b/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51.yaml index e83f8cdf140..5ae43e121c7 100644 --- a/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51.yaml +++ b/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51.yaml @@ -10,3 +10,4 @@ toolchain: - xtools supported: - ble +vendor: seeed diff --git a/boards/arm/96b_meerkat96/96b_meerkat96.yaml b/boards/arm/96b_meerkat96/96b_meerkat96.yaml index fe13eb1fe22..b06b2ef5268 100644 --- a/boards/arm/96b_meerkat96/96b_meerkat96.yaml +++ b/boards/arm/96b_meerkat96/96b_meerkat96.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: novtech diff --git a/boards/arm/96b_nitrogen/96b_nitrogen.yaml b/boards/arm/96b_nitrogen/96b_nitrogen.yaml index c3ad4157aed..12b1f6c73e1 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen.yaml +++ b/boards/arm/96b_nitrogen/96b_nitrogen.yaml @@ -13,3 +13,4 @@ supported: - spi ram: 64 flash: 512 +vendor: seeed diff --git a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.yaml b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.yaml index e0fc7bd2db4..160bb802380 100644 --- a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.yaml +++ b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.yaml @@ -12,3 +12,4 @@ supported: - i2c - spi - counter +vendor: st diff --git a/boards/arm/actinius_icarus/actinius_icarus.yaml b/boards/arm/actinius_icarus/actinius_icarus.yaml index 960c1c9704e..d547560af6f 100644 --- a/boards/arm/actinius_icarus/actinius_icarus.yaml +++ b/boards/arm/actinius_icarus/actinius_icarus.yaml @@ -20,3 +20,4 @@ supported: - feather_spi - arduino_i2c - arduino_spi +vendor: actinius diff --git a/boards/arm/actinius_icarus/actinius_icarus_ns.yaml b/boards/arm/actinius_icarus/actinius_icarus_ns.yaml index 57eef9a4849..7fe1ea2ef47 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_ns.yaml +++ b/boards/arm/actinius_icarus/actinius_icarus_ns.yaml @@ -20,3 +20,4 @@ supported: - feather_spi - arduino_i2c - arduino_spi +vendor: actinius diff --git a/boards/arm/actinius_icarus_bee/actinius_icarus_bee.yaml b/boards/arm/actinius_icarus_bee/actinius_icarus_bee.yaml index be2865ea3ac..87052c0a149 100644 --- a/boards/arm/actinius_icarus_bee/actinius_icarus_bee.yaml +++ b/boards/arm/actinius_icarus_bee/actinius_icarus_bee.yaml @@ -15,3 +15,4 @@ supported: - spi - watchdog - counter +vendor: actinius diff --git a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns.yaml b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns.yaml index d4f50773719..6255c80c010 100644 --- a/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns.yaml +++ b/boards/arm/actinius_icarus_bee/actinius_icarus_bee_ns.yaml @@ -15,3 +15,4 @@ supported: - spi - watchdog - counter +vendor: actinius diff --git a/boards/arm/actinius_icarus_som/actinius_icarus_som.yaml b/boards/arm/actinius_icarus_som/actinius_icarus_som.yaml index e2d4a2b1903..db7c14011b5 100644 --- a/boards/arm/actinius_icarus_som/actinius_icarus_som.yaml +++ b/boards/arm/actinius_icarus_som/actinius_icarus_som.yaml @@ -14,3 +14,4 @@ supported: - pwm - watchdog - counter +vendor: actinius diff --git a/boards/arm/actinius_icarus_som/actinius_icarus_som_ns.yaml b/boards/arm/actinius_icarus_som/actinius_icarus_som_ns.yaml index 84e46877826..6f4d731867d 100644 --- a/boards/arm/actinius_icarus_som/actinius_icarus_som_ns.yaml +++ b/boards/arm/actinius_icarus_som/actinius_icarus_som_ns.yaml @@ -14,3 +14,4 @@ supported: - pwm - watchdog - counter +vendor: actinius diff --git a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk.yaml b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk.yaml index f0448ccdb30..aea5ef27753 100644 --- a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk.yaml +++ b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk.yaml @@ -19,3 +19,4 @@ supported: - arduino_i2c - arduino_serial - arduino_spi +vendor: actinius diff --git a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns.yaml b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns.yaml index 1d966832c87..2ecf72e7a57 100644 --- a/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns.yaml +++ b/boards/arm/actinius_icarus_som_dk/actinius_icarus_som_dk_ns.yaml @@ -19,3 +19,4 @@ supported: - arduino_i2c - arduino_serial - arduino_spi +vendor: actinius diff --git a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml index cd413794323..859ae9feb17 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml +++ b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml @@ -8,3 +8,4 @@ toolchain: - zephyr - gnuarmemb - xtools +vendor: adafruit diff --git a/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.yaml b/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.yaml index c3f13456776..de9b44f8820 100644 --- a/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.yaml +++ b/boards/arm/adafruit_feather_m0_lora/adafruit_feather_m0_lora.yaml @@ -8,3 +8,4 @@ toolchain: - zephyr - gnuarmemb - xtools +vendor: adafruit diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.yaml b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.yaml index fde385eea8c..f626fd46a4a 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.yaml +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.yaml @@ -16,3 +16,4 @@ supported: - feather_serial - feather_i2c - feather_spi +vendor: adafruit diff --git a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.yaml b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.yaml index 43cd2e57739..f71d8d7cab3 100644 --- a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.yaml +++ b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.yaml @@ -15,3 +15,4 @@ supported: - feather_serial - feather_i2c - feather_spi +vendor: adafruit diff --git a/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml index 8a239a1d5a1..7de6fd7a3f2 100644 --- a/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml +++ b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml @@ -17,3 +17,4 @@ supported: - uart - usb_device - watchdog +vendor: adafruit diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.yaml b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.yaml index eba07de2022..a95f91e9b12 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.yaml +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.yaml @@ -19,3 +19,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: adafruit diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml index 9fd5a490df6..f1d21a5c63d 100644 --- a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml +++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml @@ -19,3 +19,4 @@ supported: - uart - usb_device - watchdog +vendor: adafruit diff --git a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.yaml b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.yaml index cff2ea9ee3b..b77fb449347 100644 --- a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.yaml +++ b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.yaml @@ -5,3 +5,4 @@ arch: arm toolchain: - zephyr ram: 192 +vendor: phytec diff --git a/boards/arm/am62x_m4/am62x_m4_sk.yaml b/boards/arm/am62x_m4/am62x_m4_sk.yaml index 8d9443f184a..ef07d5a99d9 100644 --- a/boards/arm/am62x_m4/am62x_m4_sk.yaml +++ b/boards/arm/am62x_m4/am62x_m4_sk.yaml @@ -5,3 +5,4 @@ arch: arm toolchain: - zephyr ram: 192 +vendor: ti diff --git a/boards/arm/apollo4p_evb/apollo4p_evb.yaml b/boards/arm/apollo4p_evb/apollo4p_evb.yaml index 38cfcd2514b..b2c0ecd954b 100644 --- a/boards/arm/apollo4p_evb/apollo4p_evb.yaml +++ b/boards/arm/apollo4p_evb/apollo4p_evb.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: ambiq diff --git a/boards/arm/arduino_due/arduino_due.yaml b/boards/arm/arduino_due/arduino_due.yaml index 3532f3a66e8..779271c0e12 100644 --- a/boards/arm/arduino_due/arduino_due.yaml +++ b/boards/arm/arduino_due/arduino_due.yaml @@ -12,3 +12,4 @@ supported: - watchdog - gpio - arduino_i2c +vendor: arduino diff --git a/boards/arm/arduino_giga_r1/arduino_giga_r1_m4.yaml b/boards/arm/arduino_giga_r1/arduino_giga_r1_m4.yaml index cd071eb7a73..58b71369e12 100644 --- a/boards/arm/arduino_giga_r1/arduino_giga_r1_m4.yaml +++ b/boards/arm/arduino_giga_r1/arduino_giga_r1_m4.yaml @@ -16,3 +16,4 @@ testing: - mpu - nfc - net +vendor: arduino diff --git a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.yaml b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.yaml index 53370f743d2..2e844a14804 100644 --- a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.yaml +++ b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.yaml @@ -16,3 +16,4 @@ supported: - memc - usb_cdc - usb_device +vendor: arduino diff --git a/boards/arm/arduino_mkrzero/arduino_mkrzero.yaml b/boards/arm/arduino_mkrzero/arduino_mkrzero.yaml index ca3a108932f..9b695e86097 100644 --- a/boards/arm/arduino_mkrzero/arduino_mkrzero.yaml +++ b/boards/arm/arduino_mkrzero/arduino_mkrzero.yaml @@ -20,3 +20,4 @@ supported: - uart - usb_device - watchdog +vendor: arduino diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble.yaml b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble.yaml index ad9a58b286e..733309555cb 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble.yaml +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble.yaml @@ -17,3 +17,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: arduino diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense.yaml b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense.yaml index 7c3a4bb5326..cdd9ead370c 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense.yaml +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense.yaml @@ -17,3 +17,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: arduino diff --git a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml index 6a698d32894..f7ded1f5239 100644 --- a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml +++ b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml @@ -19,3 +19,4 @@ supported: - uart - usb_device - watchdog +vendor: arduino diff --git a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.yaml b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.yaml index d7d3ef72756..74e8cab3c6b 100644 --- a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.yaml +++ b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.yaml @@ -17,3 +17,4 @@ supported: - nvs - pwm - watchdog +vendor: arduino diff --git a/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m4.yaml b/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m4.yaml index f544786e63c..b84e35835c6 100644 --- a/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m4.yaml +++ b/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m4.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - mpu - nfc +vendor: arduino diff --git a/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m7.yaml b/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m7.yaml index 4751a7d8ad9..af23aee83d4 100644 --- a/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m7.yaml +++ b/boards/arm/arduino_portenta_h7/arduino_portenta_h7_m7.yaml @@ -10,3 +10,4 @@ ram: 512 flash: 1024 supported: - gpio +vendor: arduino diff --git a/boards/arm/arduino_zero/arduino_zero.yaml b/boards/arm/arduino_zero/arduino_zero.yaml index caf279614b4..771199f1e8f 100644 --- a/boards/arm/arduino_zero/arduino_zero.yaml +++ b/boards/arm/arduino_zero/arduino_zero.yaml @@ -20,3 +20,4 @@ supported: - uart - usb_device - watchdog +vendor: arduino diff --git a/boards/arm/ast1030_evb/ast1030_evb.yaml b/boards/arm/ast1030_evb/ast1030_evb.yaml index 39f271716e6..e5c5678336b 100644 --- a/boards/arm/ast1030_evb/ast1030_evb.yaml +++ b/boards/arm/ast1030_evb/ast1030_evb.yaml @@ -10,3 +10,4 @@ ram: 768 flash: 1024 supported: - serial +vendor: aspeed diff --git a/boards/arm/atsamc21n_xpro/atsamc21n_xpro.yaml b/boards/arm/atsamc21n_xpro/atsamc21n_xpro.yaml index bd449a7aff0..16420223b24 100644 --- a/boards/arm/atsamc21n_xpro/atsamc21n_xpro.yaml +++ b/boards/arm/atsamc21n_xpro/atsamc21n_xpro.yaml @@ -19,3 +19,4 @@ supported: - pwm - spi - uart +vendor: atmel diff --git a/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml b/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml index 71aa6be7fd1..d0a541196fb 100644 --- a/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml +++ b/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml @@ -15,3 +15,4 @@ supported: - spi - uart - watchdog +vendor: atmel diff --git a/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml b/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml index a055c521be2..5eebbdfe813 100644 --- a/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml +++ b/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml @@ -22,3 +22,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: atmel diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.yaml b/boards/arm/atsame54_xpro/atsame54_xpro.yaml index 95b78f016d2..27238959131 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.yaml +++ b/boards/arm/atsame54_xpro/atsame54_xpro.yaml @@ -19,3 +19,4 @@ supported: - uart - usb_device - netif:eth +vendor: atmel diff --git a/boards/arm/atsaml21_xpro/atsaml21_xpro.yaml b/boards/arm/atsaml21_xpro/atsaml21_xpro.yaml index b659c2a7ab5..03c5c226209 100644 --- a/boards/arm/atsaml21_xpro/atsaml21_xpro.yaml +++ b/boards/arm/atsaml21_xpro/atsaml21_xpro.yaml @@ -22,3 +22,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: atmel diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml index 613cbcc96b3..5ecfcb166c2 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml @@ -24,3 +24,4 @@ supported: - xpro_i2c - xpro_serial - xpro_spi +vendor: atmel diff --git a/boards/arm/atsamr34_xpro/atsamr34_xpro.yaml b/boards/arm/atsamr34_xpro/atsamr34_xpro.yaml index 932fec34bf2..fb5c574b321 100644 --- a/boards/arm/atsamr34_xpro/atsamr34_xpro.yaml +++ b/boards/arm/atsamr34_xpro/atsamr34_xpro.yaml @@ -22,3 +22,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: atmel diff --git a/boards/arm/b_g474e_dpow1/b_g474e_dpow1.yaml b/boards/arm/b_g474e_dpow1/b_g474e_dpow1.yaml index 3009e5fb02c..04dc5fb08d6 100644 --- a/boards/arm/b_g474e_dpow1/b_g474e_dpow1.yaml +++ b/boards/arm/b_g474e_dpow1/b_g474e_dpow1.yaml @@ -14,3 +14,4 @@ supported: - watchdog - tcpc - usb +vendor: st diff --git a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml index ea82e670ada..895fab02c5a 100644 --- a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml +++ b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml @@ -20,3 +20,4 @@ supported: - eeprom - nvs - lora +vendor: st diff --git a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml index 01c99a43640..63b445b8038 100644 --- a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml +++ b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml @@ -21,3 +21,4 @@ supported: - spi - vl53l0x - watchdog +vendor: st diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml index 45cf413fa60..9faefebf0bc 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml @@ -22,3 +22,4 @@ supported: - backup_sram - pwm - counter +vendor: st diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns.yaml b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns.yaml index 29e69d99b76..0867becc701 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns.yaml +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 786 flash: 512 +vendor: st diff --git a/boards/arm/bcm958401m2/bcm958401m2.yaml b/boards/arm/bcm958401m2/bcm958401m2.yaml index 2c61d67d10d..2dd64839807 100644 --- a/boards/arm/bcm958401m2/bcm958401m2.yaml +++ b/boards/arm/bcm958401m2/bcm958401m2.yaml @@ -5,3 +5,4 @@ arch: arm toolchain: - zephyr - gnuarmemb +vendor: brcm diff --git a/boards/arm/bcm958402m2_m7/bcm958402m2_m7.yaml b/boards/arm/bcm958402m2_m7/bcm958402m2_m7.yaml index 004a84124c4..21c94f61721 100644 --- a/boards/arm/bcm958402m2_m7/bcm958402m2_m7.yaml +++ b/boards/arm/bcm958402m2_m7/bcm958402m2_m7.yaml @@ -5,3 +5,4 @@ arch: arm toolchain: - zephyr - gnuarmemb +vendor: brcm diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom.yaml b/boards/arm/beagle_bcf/beagleconnect_freedom.yaml index d85ea8bd355..0d1cd99730b 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom.yaml +++ b/boards/arm/beagle_bcf/beagleconnect_freedom.yaml @@ -13,3 +13,4 @@ supported: - i2c - spi - uart +vendor: beagle diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.yaml b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.yaml index b5ed7165345..10ade88c8b1 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.yaml +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.yaml @@ -19,3 +19,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: lairdconnect diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.yaml b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.yaml index c754614833f..5d94e8e7629 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.yaml +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.yaml @@ -18,3 +18,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: lairdconnect diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.yaml b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.yaml index af81eeac4fc..d8a17394be7 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.yaml +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.yaml @@ -15,3 +15,4 @@ supported: - spi - uart - watchdog +vendor: lairdconnect diff --git a/boards/arm/bl652_dvk/bl652_dvk.yaml b/boards/arm/bl652_dvk/bl652_dvk.yaml index 0eb83f54489..a2fd4370d7f 100644 --- a/boards/arm/bl652_dvk/bl652_dvk.yaml +++ b/boards/arm/bl652_dvk/bl652_dvk.yaml @@ -15,3 +15,4 @@ supported: - pwm - spi - watchdog +vendor: lairdconnect diff --git a/boards/arm/bl653_dvk/bl653_dvk.yaml b/boards/arm/bl653_dvk/bl653_dvk.yaml index ffbde56b11d..6a2792ea521 100644 --- a/boards/arm/bl653_dvk/bl653_dvk.yaml +++ b/boards/arm/bl653_dvk/bl653_dvk.yaml @@ -16,3 +16,4 @@ supported: - counter - spi - i2c +vendor: lairdconnect diff --git a/boards/arm/bl654_dvk/bl654_dvk.yaml b/boards/arm/bl654_dvk/bl654_dvk.yaml index c15f0d5b0af..27eec7dcaeb 100644 --- a/boards/arm/bl654_dvk/bl654_dvk.yaml +++ b/boards/arm/bl654_dvk/bl654_dvk.yaml @@ -12,3 +12,4 @@ supported: - ble - pwm - watchdog +vendor: lairdconnect diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board.yaml b/boards/arm/bl654_sensor_board/bl654_sensor_board.yaml index 24110c9d88b..856805fbd16 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board.yaml +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board.yaml @@ -17,3 +17,4 @@ supported: - pwm - watchdog - netif:openthread +vendor: lairdconnect diff --git a/boards/arm/bl654_usb/bl654_usb.yaml b/boards/arm/bl654_usb/bl654_usb.yaml index 0187d8e5b27..620275a516d 100644 --- a/boards/arm/bl654_usb/bl654_usb.yaml +++ b/boards/arm/bl654_usb/bl654_usb.yaml @@ -13,3 +13,4 @@ supported: - pwm - watchdog - counter +vendor: lairdconnect diff --git a/boards/arm/blackpill_f401cc/blackpill_f401cc.yaml b/boards/arm/blackpill_f401cc/blackpill_f401cc.yaml index 536fc752d38..2601e64546b 100644 --- a/boards/arm/blackpill_f401cc/blackpill_f401cc.yaml +++ b/boards/arm/blackpill_f401cc/blackpill_f401cc.yaml @@ -14,3 +14,4 @@ supported: - uart - pwm - adc +vendor: weact diff --git a/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml b/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml index 5b835b9be07..813781644f2 100644 --- a/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml +++ b/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml @@ -14,3 +14,4 @@ supported: - uart - pwm - adc +vendor: weact diff --git a/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml b/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml index b6729fa9bc5..d0b145fc1e4 100644 --- a/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml +++ b/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml @@ -14,3 +14,4 @@ supported: - uart - pwm - adc +vendor: weact diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.yaml b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.yaml index 8b8544dedeb..f031e5105ef 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.yaml +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.yaml @@ -17,3 +17,4 @@ supported: - pwm - spi - watchdog +vendor: blueclover diff --git a/boards/arm/bt510/bt510.yaml b/boards/arm/bt510/bt510.yaml index 4852a82632e..c9b6823d188 100644 --- a/boards/arm/bt510/bt510.yaml +++ b/boards/arm/bt510/bt510.yaml @@ -13,3 +13,4 @@ supported: - watchdog - i2c - sm351lt +vendor: lairdconnect diff --git a/boards/arm/bt610/bt610.yaml b/boards/arm/bt610/bt610.yaml index fded74157a3..80cbe9975da 100644 --- a/boards/arm/bt610/bt610.yaml +++ b/boards/arm/bt610/bt610.yaml @@ -19,3 +19,4 @@ supported: - counter - sm351lt - qspi +vendor: lairdconnect diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml index 90b2cdabf5a..ac4cabbc16b 100644 --- a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml @@ -13,3 +13,4 @@ supported: - i2c - spi - watchdog +vendor: ti diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml index 2491ca0c0a7..b986a52a43f 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml @@ -14,3 +14,4 @@ supported: - spi - watchdog - adc +vendor: ti diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml index 835d928942a..a5234f005e3 100644 --- a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml @@ -14,3 +14,4 @@ supported: - spi - watchdog - adc +vendor: ti diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml index 6972c004f22..0db9c598d92 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml @@ -14,3 +14,4 @@ supported: - spi - watchdog - adc +vendor: ti diff --git a/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl.yaml b/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl.yaml index 9ef17d92176..2158d5ec453 100644 --- a/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl.yaml +++ b/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl.yaml @@ -12,3 +12,4 @@ supported: - gpio - adc - watchdog +vendor: ti diff --git a/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl.yaml b/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl.yaml index b40e926d24c..4761555359a 100644 --- a/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl.yaml +++ b/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl.yaml @@ -12,3 +12,4 @@ supported: - gpio - adc - watchdog +vendor: ti diff --git a/boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.yaml b/boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.yaml index 4d7dc764e3e..ce87d91e4cd 100644 --- a/boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.yaml +++ b/boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.yaml @@ -20,3 +20,4 @@ testing: - bluetooth supported: - pwm +vendor: nxp diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.yaml b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.yaml index f6ac7c3fd31..f96fa8c29bf 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.yaml +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.yaml @@ -15,3 +15,4 @@ supported: - i2c - spi - netif:openthread +vendor: contextualelectronics diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml index e67d1d069ab..ee63e4356a5 100644 --- a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml @@ -20,3 +20,4 @@ supported: - arduino_spi - gpio - spi +vendor: cypress diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml index 5349458cbd0..b490c8f3fbe 100644 --- a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml @@ -18,3 +18,4 @@ toolchain: supported: - arduino_gpio - gpio +vendor: cypress diff --git a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml index 026450be3fd..a639fc9b700 100644 --- a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml @@ -16,3 +16,4 @@ toolchain: - xtools supported: - gpio +vendor: cypress diff --git a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml index b212d41be3e..70c6db96740 100644 --- a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml @@ -16,3 +16,4 @@ toolchain: - xtools supported: - gpio +vendor: cypress diff --git a/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml index 4cf64830fcf..19391fa39c4 100644 --- a/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml +++ b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml @@ -12,3 +12,4 @@ toolchain: - gnuarmemb supported: - gpio +vendor: cypress diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml index 0989469474e..36d08b2a4d0 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml @@ -18,3 +18,4 @@ supported: - gpio - uart - i2c +vendor: cypress diff --git a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml index c9d851c5ffc..1aaef3040d3 100644 --- a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml +++ b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.yaml @@ -19,3 +19,4 @@ supported: - i2c - watchdog - spi +vendor: cypress diff --git a/boards/arm/cyclonev_socdk/cyclonev_socdk.yaml b/boards/arm/cyclonev_socdk/cyclonev_socdk.yaml index 89214e6455e..52f9635c760 100644 --- a/boards/arm/cyclonev_socdk/cyclonev_socdk.yaml +++ b/boards/arm/cyclonev_socdk/cyclonev_socdk.yaml @@ -5,3 +5,4 @@ arch: arm toolchain: - zephyr - gnuarmemb +vendor: altr diff --git a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml index 4cf50541c1e..10687f70eae 100644 --- a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml +++ b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml @@ -15,3 +15,4 @@ supported: - i2c - spi - usb_device +vendor: renesas diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml index 3b9bb82c967..6503c5a3aae 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml @@ -11,3 +11,4 @@ flash: 512 supported: - spi - i2c +vendor: decawave diff --git a/boards/arm/degu_evk/degu_evk.yaml b/boards/arm/degu_evk/degu_evk.yaml index f58303f0b1a..3fd220f4df2 100644 --- a/boards/arm/degu_evk/degu_evk.yaml +++ b/boards/arm/degu_evk/degu_evk.yaml @@ -8,3 +8,4 @@ supported: - i2c - adc - usb_device +vendor: atmarktechno diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml b/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml index 4bbb0cfe33f..ca90da9607a 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml @@ -27,3 +27,4 @@ supported: - dma ram: 96 flash: 1024 +vendor: st diff --git a/boards/arm/efm32gg_sltb009a/efm32gg_sltb009a.yaml b/boards/arm/efm32gg_sltb009a/efm32gg_sltb009a.yaml index 44370cc391d..ddea24692fa 100644 --- a/boards/arm/efm32gg_sltb009a/efm32gg_sltb009a.yaml +++ b/boards/arm/efm32gg_sltb009a/efm32gg_sltb009a.yaml @@ -13,3 +13,4 @@ supported: testing: ignore_tags: - bluetooth +vendor: silabs diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml index 057e565b9a4..9e976e5ccaa 100644 --- a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml @@ -18,3 +18,4 @@ supported: testing: ignore_tags: - bluetooth +vendor: silabs diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml index c2cad793872..426328eae97 100644 --- a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml @@ -16,3 +16,4 @@ supported: testing: ignore_tags: - bluetooth +vendor: silabs diff --git a/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml b/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml index 5ca83c3d259..d14ffbbd10a 100644 --- a/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml +++ b/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efm32pg_stk3401a/efm32pg_stk3401a.yaml b/boards/arm/efm32pg_stk3401a/efm32pg_stk3401a.yaml index 0c77d371c51..ee707a08caa 100644 --- a/boards/arm/efm32pg_stk3401a/efm32pg_stk3401a.yaml +++ b/boards/arm/efm32pg_stk3401a/efm32pg_stk3401a.yaml @@ -17,3 +17,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml index 707e1b02169..ebfe95c91ba 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml @@ -17,3 +17,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml index 66e272e8cef..8d7e590e393 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efm32wg_stk3800/efm32wg_stk3800.yaml b/boards/arm/efm32wg_stk3800/efm32wg_stk3800.yaml index 449ea45eb83..acd28a6623d 100644 --- a/boards/arm/efm32wg_stk3800/efm32wg_stk3800.yaml +++ b/boards/arm/efm32wg_stk3800/efm32wg_stk3800.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4104a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4104a.yaml index 163de36c884..62e253011c7 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4104a.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4104a.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml index 6a231fa7db1..88ed4089379 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4170a.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml index 93681703fde..ea286ce3c65 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4187c.yaml b/boards/arm/efr32_radio/efr32_radio_brd4187c.yaml index 3e9b730855c..a5602114a36 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4187c.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4187c.yaml @@ -18,3 +18,4 @@ testing: - bluetooth - pm - hwinfo +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4250b.yaml b/boards/arm/efr32_radio/efr32_radio_brd4250b.yaml index 9a3b3996733..0d45527eced 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4250b.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4250b.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_radio/efr32_radio_brd4255a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4255a.yaml index 34923d504c5..a5b7fc7cb90 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4255a.yaml +++ b/boards/arm/efr32_radio/efr32_radio_brd4255a.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_thunderboard/efr32bg22_brd4184a.yaml b/boards/arm/efr32_thunderboard/efr32bg22_brd4184a.yaml index 560ce77335f..37bc5bed239 100644 --- a/boards/arm/efr32_thunderboard/efr32bg22_brd4184a.yaml +++ b/boards/arm/efr32_thunderboard/efr32bg22_brd4184a.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_thunderboard/efr32bg22_brd4184b.yaml b/boards/arm/efr32_thunderboard/efr32bg22_brd4184b.yaml index 86e8e01dae3..40c6377a277 100644 --- a/boards/arm/efr32_thunderboard/efr32bg22_brd4184b.yaml +++ b/boards/arm/efr32_thunderboard/efr32bg22_brd4184b.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32_thunderboard/efr32bg27_brd2602a.yaml b/boards/arm/efr32_thunderboard/efr32bg27_brd2602a.yaml index 819e07ed65e..844a48854d5 100644 --- a/boards/arm/efr32_thunderboard/efr32bg27_brd2602a.yaml +++ b/boards/arm/efr32_thunderboard/efr32bg27_brd2602a.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.yaml b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.yaml index 7565e1288c5..3c8cbd773d0 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.yaml +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: silabs diff --git a/boards/arm/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml b/boards/arm/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml index 48743de3b97..2b803cca1ab 100644 --- a/boards/arm/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml +++ b/boards/arm/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml @@ -16,3 +16,4 @@ testing: - bluetooth - pm - hwinfo +vendor: silabs diff --git a/boards/arm/ev11l78a/ev11l78a.yaml b/boards/arm/ev11l78a/ev11l78a.yaml index c181bd12f0d..f9b2a1a53a2 100644 --- a/boards/arm/ev11l78a/ev11l78a.yaml +++ b/boards/arm/ev11l78a/ev11l78a.yaml @@ -14,3 +14,4 @@ supported: - i2c - spi - uart +vendor: atmel diff --git a/boards/arm/faze/faze.yaml b/boards/arm/faze/faze.yaml index 0801354ec53..92deff91f49 100644 --- a/boards/arm/faze/faze.yaml +++ b/boards/arm/faze/faze.yaml @@ -18,3 +18,4 @@ supported: - gpio - i2c - serial +vendor: seagate diff --git a/boards/arm/frdm_k22f/frdm_k22f.yaml b/boards/arm/frdm_k22f/frdm_k22f.yaml index 9d8f553af53..caad4fe8519 100644 --- a/boards/arm/frdm_k22f/frdm_k22f.yaml +++ b/boards/arm/frdm_k22f/frdm_k22f.yaml @@ -19,3 +19,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/frdm_k64f/frdm_k64f.yaml b/boards/arm/frdm_k64f/frdm_k64f.yaml index 5b03ef23623..a9e99911776 100644 --- a/boards/arm/frdm_k64f/frdm_k64f.yaml +++ b/boards/arm/frdm_k64f/frdm_k64f.yaml @@ -26,3 +26,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/frdm_k82f/frdm_k82f.yaml b/boards/arm/frdm_k82f/frdm_k82f.yaml index 755ad72d5db..49480e2404b 100644 --- a/boards/arm/frdm_k82f/frdm_k82f.yaml +++ b/boards/arm/frdm_k82f/frdm_k82f.yaml @@ -22,3 +22,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/frdm_kl25z/frdm_kl25z.yaml b/boards/arm/frdm_kl25z/frdm_kl25z.yaml index 1fc6c948d0c..d930aed2127 100644 --- a/boards/arm/frdm_kl25z/frdm_kl25z.yaml +++ b/boards/arm/frdm_kl25z/frdm_kl25z.yaml @@ -18,3 +18,4 @@ supported: - gpio - i2c - usb_device +vendor: nxp diff --git a/boards/arm/frdm_kw41z/frdm_kw41z.yaml b/boards/arm/frdm_kw41z/frdm_kw41z.yaml index 42c84fd6d9b..72c7cb4abf3 100644 --- a/boards/arm/frdm_kw41z/frdm_kw41z.yaml +++ b/boards/arm/frdm_kw41z/frdm_kw41z.yaml @@ -19,3 +19,4 @@ supported: testing: ignore_tags: - bluetooth +vendor: nxp diff --git a/boards/arm/gd32a503v_eval/gd32a503v_eval.yaml b/boards/arm/gd32a503v_eval/gd32a503v_eval.yaml index ea5a264f5b4..396e68d24b6 100644 --- a/boards/arm/gd32a503v_eval/gd32a503v_eval.yaml +++ b/boards/arm/gd32a503v_eval/gd32a503v_eval.yaml @@ -21,3 +21,4 @@ supported: - spi - uart - watchdog +vendor: gd diff --git a/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml b/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml index 3e3a89759b8..a5dd9ba759b 100644 --- a/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml +++ b/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml @@ -16,3 +16,4 @@ supported: - counter - watchdog - dma +vendor: gd diff --git a/boards/arm/gd32e507v_start/gd32e507v_start.yaml b/boards/arm/gd32e507v_start/gd32e507v_start.yaml index 8801a73c6c6..8a1b4e4b89b 100644 --- a/boards/arm/gd32e507v_start/gd32e507v_start.yaml +++ b/boards/arm/gd32e507v_start/gd32e507v_start.yaml @@ -17,3 +17,4 @@ supported: - watchdog - counter - dma +vendor: gd diff --git a/boards/arm/gd32e507z_eval/gd32e507z_eval.yaml b/boards/arm/gd32e507z_eval/gd32e507z_eval.yaml index 74beaeaf6f1..594df3a5f8d 100644 --- a/boards/arm/gd32e507z_eval/gd32e507z_eval.yaml +++ b/boards/arm/gd32e507z_eval/gd32e507z_eval.yaml @@ -15,3 +15,4 @@ supported: - pwm - gpio - counter +vendor: gd diff --git a/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml b/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml index b8c508f98ae..17834719ff1 100644 --- a/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml +++ b/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml @@ -14,3 +14,4 @@ toolchain: supported: - watchdog - dma +vendor: gd diff --git a/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml b/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml index cd086bd14a4..1bec175723a 100644 --- a/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml +++ b/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml @@ -17,3 +17,4 @@ supported: - watchdog - dma - spi +vendor: gd diff --git a/boards/arm/gd32f407v_start/gd32f407v_start.yaml b/boards/arm/gd32f407v_start/gd32f407v_start.yaml index 6076e41b265..e79982ef6e8 100644 --- a/boards/arm/gd32f407v_start/gd32f407v_start.yaml +++ b/boards/arm/gd32f407v_start/gd32f407v_start.yaml @@ -17,3 +17,4 @@ supported: - counter - dma - spi +vendor: gd diff --git a/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml b/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml index a54cc4d59d8..88ac1c0f558 100644 --- a/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml +++ b/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml @@ -18,3 +18,4 @@ supported: - counter - dma - spi +vendor: gd diff --git a/boards/arm/gd32f450v_start/gd32f450v_start.yaml b/boards/arm/gd32f450v_start/gd32f450v_start.yaml index d3261355724..62cf201bcd2 100644 --- a/boards/arm/gd32f450v_start/gd32f450v_start.yaml +++ b/boards/arm/gd32f450v_start/gd32f450v_start.yaml @@ -17,3 +17,4 @@ supported: - counter - dma - spi +vendor: gd diff --git a/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml b/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml index f8091bd1b33..3cc5f359495 100644 --- a/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml +++ b/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml @@ -21,3 +21,4 @@ supported: - uart - watchdog - dma +vendor: gd diff --git a/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml b/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml index e0d4b21017a..868e4907f3f 100644 --- a/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml +++ b/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml @@ -22,3 +22,4 @@ supported: - watchdog - dma - spi +vendor: gd diff --git a/boards/arm/gd32l233r_eval/gd32l233r_eval.yaml b/boards/arm/gd32l233r_eval/gd32l233r_eval.yaml index a69a61f14b0..04e38f9e46c 100644 --- a/boards/arm/gd32l233r_eval/gd32l233r_eval.yaml +++ b/boards/arm/gd32l233r_eval/gd32l233r_eval.yaml @@ -11,3 +11,4 @@ toolchain: - zephyr - gnuarmemb - xtools +vendor: gd diff --git a/boards/arm/google_dragonclaw/google_dragonclaw.yaml b/boards/arm/google_dragonclaw/google_dragonclaw.yaml index 5a99a50928b..ddb4f3a7713 100644 --- a/boards/arm/google_dragonclaw/google_dragonclaw.yaml +++ b/boards/arm/google_dragonclaw/google_dragonclaw.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 256 flash: 1024 +vendor: google diff --git a/boards/arm/google_kukui/google_kukui.yaml b/boards/arm/google_kukui/google_kukui.yaml index f0c170231d7..ad95d286cb2 100644 --- a/boards/arm/google_kukui/google_kukui.yaml +++ b/boards/arm/google_kukui/google_kukui.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: google diff --git a/boards/arm/google_twinkie_v2/google_twinkie_v2.yaml b/boards/arm/google_twinkie_v2/google_twinkie_v2.yaml index 77f018d136d..bc9028b4e9a 100644 --- a/boards/arm/google_twinkie_v2/google_twinkie_v2.yaml +++ b/boards/arm/google_twinkie_v2/google_twinkie_v2.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: google diff --git a/boards/arm/hexiwear_k64/hexiwear_k64.yaml b/boards/arm/hexiwear_k64/hexiwear_k64.yaml index ae8c77edecf..c14e75c35da 100644 --- a/boards/arm/hexiwear_k64/hexiwear_k64.yaml +++ b/boards/arm/hexiwear_k64/hexiwear_k64.yaml @@ -13,3 +13,4 @@ supported: - i2c - pwm - watchdog +vendor: nxp diff --git a/boards/arm/hexiwear_kw40z/hexiwear_kw40z.yaml b/boards/arm/hexiwear_kw40z/hexiwear_kw40z.yaml index 33732674fd5..0e5b4935673 100644 --- a/boards/arm/hexiwear_kw40z/hexiwear_kw40z.yaml +++ b/boards/arm/hexiwear_kw40z/hexiwear_kw40z.yaml @@ -11,3 +11,4 @@ toolchain: testing: ignore_tags: - net +vendor: nxp diff --git a/boards/arm/ip_k66f/ip_k66f.yaml b/boards/arm/ip_k66f/ip_k66f.yaml index 0126d463648..ef2de5f4467 100644 --- a/boards/arm/ip_k66f/ip_k66f.yaml +++ b/boards/arm/ip_k66f/ip_k66f.yaml @@ -15,3 +15,4 @@ supported: - netif:eth ram: 256 flash: 2048 +vendor: nxp diff --git a/boards/arm/kv260_r5/kv260_r5.yaml b/boards/arm/kv260_r5/kv260_r5.yaml index 32cb6211866..9cc92025e91 100644 --- a/boards/arm/kv260_r5/kv260_r5.yaml +++ b/boards/arm/kv260_r5/kv260_r5.yaml @@ -9,3 +9,4 @@ testing: ignore_tags: - net - bluetooth +vendor: xlnx diff --git a/boards/arm/legend/legend.yaml b/boards/arm/legend/legend.yaml index b8c8d7d7628..1762e786318 100644 --- a/boards/arm/legend/legend.yaml +++ b/boards/arm/legend/legend.yaml @@ -17,3 +17,4 @@ testing: ignore_tags: - net - bluetooth +vendor: seagate diff --git a/boards/arm/lora_e5_dev_board/lora_e5_dev_board.yaml b/boards/arm/lora_e5_dev_board/lora_e5_dev_board.yaml index 26d3365a6cc..446bc1934cb 100644 --- a/boards/arm/lora_e5_dev_board/lora_e5_dev_board.yaml +++ b/boards/arm/lora_e5_dev_board/lora_e5_dev_board.yaml @@ -17,3 +17,4 @@ supported: - uart - watchdog - lora +vendor: seeed diff --git a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml index 35c3257948d..e59360c084b 100644 --- a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml +++ b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml @@ -11,3 +11,4 @@ supported: - i2c - serial - eeprom +vendor: nxp diff --git a/boards/arm/lpcxpresso51u68/lpcxpresso51u68.yaml b/boards/arm/lpcxpresso51u68/lpcxpresso51u68.yaml index f2ccc4c612b..1c7a0644a10 100644 --- a/boards/arm/lpcxpresso51u68/lpcxpresso51u68.yaml +++ b/boards/arm/lpcxpresso51u68/lpcxpresso51u68.yaml @@ -19,3 +19,4 @@ supported: - gpio - i2c - spi +vendor: nxp diff --git a/boards/arm/lpcxpresso54114/lpcxpresso54114_m0.yaml b/boards/arm/lpcxpresso54114/lpcxpresso54114_m0.yaml index 78aaf27c87f..4fea41d5526 100644 --- a/boards/arm/lpcxpresso54114/lpcxpresso54114_m0.yaml +++ b/boards/arm/lpcxpresso54114/lpcxpresso54114_m0.yaml @@ -17,3 +17,4 @@ toolchain: - xtools - zephyr - gnuarmemb +vendor: nxp diff --git a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.yaml b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.yaml index 5451d22000d..d8410a51893 100644 --- a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.yaml +++ b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.yaml @@ -20,3 +20,4 @@ supported: - gpio - i2c - spi +vendor: nxp diff --git a/boards/arm/lpcxpresso55s06/lpcxpresso55s06.yaml b/boards/arm/lpcxpresso55s06/lpcxpresso55s06.yaml index 43497c89c5b..fcf89bfe0ad 100644 --- a/boards/arm/lpcxpresso55s06/lpcxpresso55s06.yaml +++ b/boards/arm/lpcxpresso55s06/lpcxpresso55s06.yaml @@ -16,3 +16,4 @@ toolchain: supported: - gpio - can +vendor: nxp diff --git a/boards/arm/lpcxpresso55s16/lpcxpresso55s16.yaml b/boards/arm/lpcxpresso55s16/lpcxpresso55s16.yaml index 8f3d0e47acc..e08460382fd 100644 --- a/boards/arm/lpcxpresso55s16/lpcxpresso55s16.yaml +++ b/boards/arm/lpcxpresso55s16/lpcxpresso55s16.yaml @@ -23,3 +23,4 @@ supported: - i2c - spi - usb_device +vendor: nxp diff --git a/boards/arm/lpcxpresso55s28/lpcxpresso55s28.yaml b/boards/arm/lpcxpresso55s28/lpcxpresso55s28.yaml index 2ffd6657175..77bdb93e90f 100644 --- a/boards/arm/lpcxpresso55s28/lpcxpresso55s28.yaml +++ b/boards/arm/lpcxpresso55s28/lpcxpresso55s28.yaml @@ -23,3 +23,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml index 499536b1e80..5a28b2149c5 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.yaml @@ -19,3 +19,4 @@ supported: - gpio - pwm - dac +vendor: nxp diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml index 9feb083ea1f..d0bafc9cd4b 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml @@ -27,3 +27,4 @@ supported: - sdhc - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml index 928c884506d..818d29535fa 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml @@ -16,3 +16,4 @@ toolchain: - xtools supported: - gpio +vendor: nxp diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml index 2a2544bcfdf..d7333e026d7 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml @@ -22,3 +22,4 @@ supported: - gpio - spi - watchdog +vendor: nxp diff --git a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.yaml b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.yaml index b1c69db9514..d78477f825f 100644 --- a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.yaml +++ b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885.yaml @@ -23,3 +23,4 @@ supported: - watchdog - kscan - tach +vendor: microchip diff --git a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.yaml b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.yaml index b197fb8562f..8b8190d20d8 100644 --- a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.yaml +++ b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.yaml @@ -22,3 +22,4 @@ supported: - pwm - watchdog - kscan +vendor: microchip diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml index ad15ecfaf80..2279b2a7e97 100644 --- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml +++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml @@ -25,3 +25,4 @@ testing: ignore_tags: - bluetooth - net +vendor: microchip diff --git a/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.yaml b/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.yaml index 58bf4384d9c..26778c083c6 100644 --- a/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.yaml +++ b/boards/arm/mec172xmodular_assy6930/mec172xmodular_assy6930.yaml @@ -17,3 +17,4 @@ supported: - gpio - pinmux - i2c +vendor: microchip diff --git a/boards/arm/mercury_xu/mercury_xu.yaml b/boards/arm/mercury_xu/mercury_xu.yaml index ce965defd4a..df01c2b112a 100644 --- a/boards/arm/mercury_xu/mercury_xu.yaml +++ b/boards/arm/mercury_xu/mercury_xu.yaml @@ -6,3 +6,4 @@ arch: arm toolchain: - zephyr - gnuarmemb +vendor: xlnx diff --git a/boards/arm/mg100/mg100.yaml b/boards/arm/mg100/mg100.yaml index adeb9e91121..917eb7f0d86 100644 --- a/boards/arm/mg100/mg100.yaml +++ b/boards/arm/mg100/mg100.yaml @@ -18,3 +18,4 @@ supported: - spi - watchdog - netif:modem +vendor: lairdconnect diff --git a/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml index 695407a13ea..b69a800360b 100644 --- a/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml +++ b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml @@ -12,3 +12,4 @@ supported: - spi - i2c - adc +vendor: mikroe diff --git a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml index 097c18249e2..479eb6e4887 100644 --- a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml +++ b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml @@ -15,3 +15,4 @@ supported: - spi - pwm - usb +vendor: mikroe diff --git a/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml b/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml index 1bec3704872..8854d16ac55 100644 --- a/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml +++ b/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: nxp diff --git a/boards/arm/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis.yaml b/boards/arm/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis.yaml index 02118d9bda4..ee0fd50bf5f 100644 --- a/boards/arm/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis.yaml +++ b/boards/arm/mimx8mm_phyboard_polis/mimx8mm_phyboard_polis.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: nxp diff --git a/boards/arm/mimx8mp_evk/mimx8mp_evk_ddr.yaml b/boards/arm/mimx8mp_evk/mimx8mp_evk_ddr.yaml index fc897e4b1e0..7e4b407380b 100644 --- a/boards/arm/mimx8mp_evk/mimx8mp_evk_ddr.yaml +++ b/boards/arm/mimx8mp_evk/mimx8mp_evk_ddr.yaml @@ -20,3 +20,4 @@ testing: - bluetooth supported: - uart +vendor: nxp diff --git a/boards/arm/mimx8mp_evk/mimx8mp_evk_itcm.yaml b/boards/arm/mimx8mp_evk/mimx8mp_evk_itcm.yaml index ed059c18aed..66c3c9b553d 100644 --- a/boards/arm/mimx8mp_evk/mimx8mp_evk_itcm.yaml +++ b/boards/arm/mimx8mp_evk/mimx8mp_evk_itcm.yaml @@ -20,3 +20,4 @@ testing: - bluetooth supported: - uart +vendor: nxp diff --git a/boards/arm/mimx8mp_phyboard_pollux/mimx8mp_phyboard_pollux.yaml b/boards/arm/mimx8mp_phyboard_pollux/mimx8mp_phyboard_pollux.yaml index 27dd7d5ec22..c696532393d 100644 --- a/boards/arm/mimx8mp_phyboard_pollux/mimx8mp_phyboard_pollux.yaml +++ b/boards/arm/mimx8mp_phyboard_pollux/mimx8mp_phyboard_pollux.yaml @@ -21,3 +21,4 @@ testing: supported: - uart - gpio +vendor: nxp diff --git a/boards/arm/mimx8mq_evk/mimx8mq_evk_cm4.yaml b/boards/arm/mimx8mq_evk/mimx8mq_evk_cm4.yaml index d2462daff35..580b8cef0f3 100644 --- a/boards/arm/mimx8mq_evk/mimx8mq_evk_cm4.yaml +++ b/boards/arm/mimx8mq_evk/mimx8mq_evk_cm4.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: nxp diff --git a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.yaml b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.yaml index 73cd21480fc..302b3c64d80 100644 --- a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.yaml +++ b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.yaml @@ -26,3 +26,4 @@ supported: - usb_device - spi - adc +vendor: nxp diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.yaml b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.yaml index 7cddda02d16..b3c0b6d4d9c 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.yaml +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.yaml @@ -24,3 +24,4 @@ supported: - usb_device - spi - adc +vendor: nxp diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.yaml b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.yaml index d8b3d824b1c..eebbc18ba84 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.yaml +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.yaml @@ -26,3 +26,4 @@ supported: - usb_device - adc - sdhc +vendor: nxp diff --git a/boards/arm/mimxrt1024_evk/mimxrt1024_evk.yaml b/boards/arm/mimxrt1024_evk/mimxrt1024_evk.yaml index 0305793dd0d..4a0350c9cd4 100644 --- a/boards/arm/mimxrt1024_evk/mimxrt1024_evk.yaml +++ b/boards/arm/mimxrt1024_evk/mimxrt1024_evk.yaml @@ -25,3 +25,4 @@ supported: - adc - usb_device - pwm +vendor: nxp diff --git a/boards/arm/mimxrt1040_evk/mimxrt1040_evk.yaml b/boards/arm/mimxrt1040_evk/mimxrt1040_evk.yaml index 71b431a0a70..415ca704d60 100644 --- a/boards/arm/mimxrt1040_evk/mimxrt1040_evk.yaml +++ b/boards/arm/mimxrt1040_evk/mimxrt1040_evk.yaml @@ -21,3 +21,4 @@ supported: - adc - spi - i2c +vendor: nxp diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml index 5fe02de586b..a19f9f10dba 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml @@ -28,3 +28,4 @@ supported: - usb_device - watchdog - adc +vendor: nxp diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml index 8789741b15f..baadda8c061 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml @@ -28,3 +28,4 @@ supported: - usb_device - watchdog - adc +vendor: nxp diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml index 7daace5558e..82e15486159 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml @@ -32,3 +32,4 @@ supported: - can - watchdog - adc +vendor: nxp diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml index 2107790685a..fa29bdfaa14 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml @@ -29,3 +29,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evkb.yaml b/boards/arm/mimxrt1060_evk/mimxrt1060_evkb.yaml index 1e14219497a..3f9306c1e03 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evkb.yaml +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evkb.yaml @@ -31,3 +31,4 @@ supported: - can - watchdog - adc +vendor: nxp diff --git a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml index 35732dd66b4..01824d0b3bc 100644 --- a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml +++ b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml @@ -28,3 +28,4 @@ supported: - watchdog - adc - pwm +vendor: nxp diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml index 1c5a3cbfde1..a9d454a5083 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml @@ -32,3 +32,4 @@ supported: - can - watchdog - adc +vendor: nxp diff --git a/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm4.yaml b/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm4.yaml index 08bfd467151..8d0d041c14f 100644 --- a/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm4.yaml +++ b/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm4.yaml @@ -20,3 +20,4 @@ supported: - gpio - pwm - uart +vendor: nxp diff --git a/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm7.yaml b/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm7.yaml index b5b91c00591..48e4f372355 100644 --- a/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm7.yaml +++ b/boards/arm/mimxrt1160_evk/mimxrt1160_evk_cm7.yaml @@ -26,3 +26,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm4.yaml b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm4.yaml index ea1382d4233..69232196b62 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm4.yaml +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm4.yaml @@ -19,3 +19,4 @@ supported: - gpio - i2c - pwm +vendor: nxp diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.yaml b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.yaml index db9980a083e..ba3ae1b201b 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.yaml +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.yaml @@ -28,3 +28,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.yaml b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.yaml index e9519f594cd..77a684f23ed 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.yaml +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.yaml @@ -20,3 +20,4 @@ supported: - i2c - spi - pwm +vendor: nxp diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7.yaml b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7.yaml index 9bb5b1d809f..03376fd15c3 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7.yaml +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7.yaml @@ -26,3 +26,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.yaml b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.yaml index eebf9db3991..6e35595c078 100644 --- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.yaml +++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.yaml @@ -28,3 +28,4 @@ supported: - sdhc - pwm - i2s +vendor: nxp diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml index 21aaa88535b..d940cbe35f8 100644 --- a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml @@ -31,3 +31,4 @@ supported: - spi - watchdog - usb_device +vendor: nxp diff --git a/boards/arm/mm_feather/mm_feather.yaml b/boards/arm/mm_feather/mm_feather.yaml index 2645f42f5bc..a8af021d856 100644 --- a/boards/arm/mm_feather/mm_feather.yaml +++ b/boards/arm/mm_feather/mm_feather.yaml @@ -23,3 +23,4 @@ supported: - uart - pwm - spi +vendor: nxp diff --git a/boards/arm/mm_swiftio/mm_swiftio.yaml b/boards/arm/mm_swiftio/mm_swiftio.yaml index 943268dece1..cc27cbe2540 100644 --- a/boards/arm/mm_swiftio/mm_swiftio.yaml +++ b/boards/arm/mm_swiftio/mm_swiftio.yaml @@ -17,3 +17,4 @@ flash: 8192 supported: - counter - sdhc +vendor: nxp diff --git a/boards/arm/mps2_an385/mps2_an385.yaml b/boards/arm/mps2_an385/mps2_an385.yaml index c008aa63697..0236f2a137d 100644 --- a/boards/arm/mps2_an385/mps2_an385.yaml +++ b/boards/arm/mps2_an385/mps2_an385.yaml @@ -13,3 +13,4 @@ supported: - gpio testing: default: true +vendor: arm diff --git a/boards/arm/mps2_an521/mps2_an521.yaml b/boards/arm/mps2_an521/mps2_an521.yaml index 964258a32d9..acc2d95127b 100644 --- a/boards/arm/mps2_an521/mps2_an521.yaml +++ b/boards/arm/mps2_an521/mps2_an521.yaml @@ -18,3 +18,4 @@ testing: - bluetooth - net - timer +vendor: arm diff --git a/boards/arm/mps3_an547/mps3_an547.yaml b/boards/arm/mps3_an547/mps3_an547.yaml index e8f2b551404..3ade98161c8 100644 --- a/boards/arm/mps3_an547/mps3_an547.yaml +++ b/boards/arm/mps3_an547/mps3_an547.yaml @@ -23,3 +23,4 @@ testing: - bluetooth - net - timer +vendor: arm diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.yaml b/boards/arm/mr_canhubk3/mr_canhubk3.yaml index a9d1ebf7c86..a9f5f68b720 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.yaml +++ b/boards/arm/mr_canhubk3/mr_canhubk3.yaml @@ -19,3 +19,4 @@ supported: - watchdog - netif:eth - pwm +vendor: nxp diff --git a/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml b/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml index e1b1478370e..c60f1b65de8 100644 --- a/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml +++ b/boards/arm/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 64 flash: 256 +vendor: ti diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml index a93e1ccb62a..985dba241e1 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml @@ -22,3 +22,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: nordic diff --git a/boards/arm/nrf51_ble400/nrf51_ble400.yaml b/boards/arm/nrf51_ble400/nrf51_ble400.yaml index 622c7d7d74a..93c73fcd84f 100644 --- a/boards/arm/nrf51_ble400/nrf51_ble400.yaml +++ b/boards/arm/nrf51_ble400/nrf51_ble400.yaml @@ -14,3 +14,4 @@ supported: testing: ignore_tags: - net +vendor: waveshare diff --git a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml index 1ccd377906f..8b521b57d90 100644 --- a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml +++ b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml @@ -21,3 +21,4 @@ supported: testing: ignore_tags: - net +vendor: nordic diff --git a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.yaml b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.yaml index d0e29a7e3b5..906fce5febf 100644 --- a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.yaml +++ b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.yaml @@ -11,3 +11,4 @@ flash: 256 supported: - ble - nvs +vendor: nordic diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.yaml b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.yaml index 1c129df76c7..1e31da83439 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.yaml +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.yaml @@ -15,3 +15,4 @@ supported: - watchdog - counter - netif:openthread +vendor: nordic diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.yaml b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.yaml index 109024f1070..24cacd6ffa3 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.yaml +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.yaml @@ -20,3 +20,4 @@ supported: - watchdog - counter - netif:openthread +vendor: nordic diff --git a/boards/arm/nrf52840_blip/nrf52840_blip.yaml b/boards/arm/nrf52840_blip/nrf52840_blip.yaml index 9c375172b54..694c2c251b8 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip.yaml +++ b/boards/arm/nrf52840_blip/nrf52840_blip.yaml @@ -11,3 +11,4 @@ supported: - i2c - usb_device - ble +vendor: electronutlabs diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk.yaml b/boards/arm/nrf52840_mdk/nrf52840_mdk.yaml index 9a8e27235d6..c3be56dacaa 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk.yaml +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk.yaml @@ -10,3 +10,4 @@ supported: - usb_device - ble - pwm +vendor: makerdiary diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr.yaml b/boards/arm/nrf52840_papyr/nrf52840_papyr.yaml index c5c4d62cccc..446c5205f96 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr.yaml +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr.yaml @@ -12,3 +12,4 @@ supported: - ble - pwm - watchdog +vendor: electronutlabs diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.yaml b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.yaml index 9c1ac768c68..40d927db116 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.yaml +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.yaml @@ -13,3 +13,4 @@ supported: - pwm - netif:openthread - gpio +vendor: nordic diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml index fd739bf001a..00ee8701a97 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml @@ -25,3 +25,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: nordic diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.yaml b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.yaml index 1328f9be256..f0fb4cdafbf 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.yaml +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.yaml @@ -19,3 +19,4 @@ supported: - counter - netif:openthread - gpio +vendor: nordic diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml index 30a4788644a..0bfa59a6c1b 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml @@ -11,3 +11,4 @@ flash: 512 supported: - feather_serial - feather_i2c +vendor: adafruit diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.yaml b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.yaml index 81482c334ea..a377d060073 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.yaml +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 64 flash: 512 +vendor: sparkfun diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml index c720c3da41b..3ebff8db1a4 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml @@ -11,3 +11,4 @@ supported: - gpio ram: 24 flash: 192 +vendor: nordic diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.yaml b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.yaml index 7ce6d3d6582..05e07eeba2a 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.yaml +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.yaml @@ -11,3 +11,4 @@ supported: - gpio ram: 24 flash: 192 +vendor: nordic diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml index 5a5337412c6..209069df379 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml @@ -20,3 +20,4 @@ supported: - pwm - spi - watchdog +vendor: nordic diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.yaml b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.yaml index 5d752b69566..d5598ed9efc 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.yaml +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.yaml @@ -17,3 +17,4 @@ supported: - watchdog - usb_cdc - usb_device +vendor: nordic diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml index a094083158b..7b670992a87 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml @@ -16,3 +16,4 @@ supported: - watchdog - usb_cdc - usb_device +vendor: nordic diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.yaml b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.yaml index 7a28066f0a1..28ecb10a8b5 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.yaml +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.yaml @@ -10,3 +10,4 @@ ram: 64 flash: 256 supported: - watchdog +vendor: nordic diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml index d4f9717fe97..545a41e9cd6 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml @@ -18,3 +18,4 @@ supported: - usb_device - netif:openthread - gpio +vendor: nordic diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.yaml index 71a8270225e..9519f50f3e9 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.yaml +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.yaml @@ -16,3 +16,4 @@ supported: - usb_device - netif:openthread - gpio +vendor: nordic diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml index d6435438e82..2f92bb86440 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml @@ -11,3 +11,4 @@ flash: 256 supported: - watchdog - gpio +vendor: nordic diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.yaml b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.yaml index 4f411fb3782..4b9ffc34035 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.yaml +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.yaml @@ -11,3 +11,4 @@ supported: - ble - netif:openthread - gpio +vendor: nordic diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml index 92ef46bc05d..7a6d3362b23 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml @@ -19,3 +19,4 @@ supported: - spi - watchdog - counter +vendor: nordic diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns.yaml b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns.yaml index 9eac3a41b30..c2a98dcad05 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns.yaml +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_ns.yaml @@ -18,3 +18,4 @@ supported: - watchdog - netif:modem - gpio +vendor: nordic diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161.yaml b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161.yaml index efca7888f56..af076428810 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161.yaml +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161.yaml @@ -19,3 +19,4 @@ supported: - spi - watchdog - counter +vendor: nordic diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.yaml b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.yaml index b0b16fc403a..2d2da2026f4 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.yaml +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.yaml @@ -17,3 +17,4 @@ supported: - pwm - watchdog - netif:modem +vendor: nordic diff --git a/boards/arm/nucleo_c031c6/nucleo_c031c6.yaml b/boards/arm/nucleo_c031c6/nucleo_c031c6.yaml index d7fff9f984e..c4766287cc5 100644 --- a/boards/arm/nucleo_c031c6/nucleo_c031c6.yaml +++ b/boards/arm/nucleo_c031c6/nucleo_c031c6.yaml @@ -16,3 +16,4 @@ supported: - dma ram: 12 flash: 32 +vendor: st diff --git a/boards/arm/nucleo_f030r8/nucleo_f030r8.yaml b/boards/arm/nucleo_f030r8/nucleo_f030r8.yaml index 2d348327740..814f2a7fc1b 100644 --- a/boards/arm/nucleo_f030r8/nucleo_f030r8.yaml +++ b/boards/arm/nucleo_f030r8/nucleo_f030r8.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/nucleo_f070rb/nucleo_f070rb.yaml b/boards/arm/nucleo_f070rb/nucleo_f070rb.yaml index 366bef569cc..60af06296a9 100644 --- a/boards/arm/nucleo_f070rb/nucleo_f070rb.yaml +++ b/boards/arm/nucleo_f070rb/nucleo_f070rb.yaml @@ -22,3 +22,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml index 3bf62e60ee7..c19aa47d955 100644 --- a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml +++ b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml @@ -27,3 +27,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml b/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml index a36b1373bcc..e231aa5e1d2 100644 --- a/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml +++ b/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml @@ -20,3 +20,4 @@ supported: - dma - nvs - counter +vendor: st diff --git a/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml b/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml index 0856304d880..f89510912be 100644 --- a/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml +++ b/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml @@ -24,3 +24,4 @@ supported: - pwm - rng - dma +vendor: st diff --git a/boards/arm/nucleo_f302r8/nucleo_f302r8.yaml b/boards/arm/nucleo_f302r8/nucleo_f302r8.yaml index 85abfd6acd9..a5e3758b6a6 100644 --- a/boards/arm/nucleo_f302r8/nucleo_f302r8.yaml +++ b/boards/arm/nucleo_f302r8/nucleo_f302r8.yaml @@ -18,3 +18,4 @@ supported: - pwm - counter - adc +vendor: st diff --git a/boards/arm/nucleo_f303k8/nucleo_f303k8.yaml b/boards/arm/nucleo_f303k8/nucleo_f303k8.yaml index 1466d0bafc3..3442ef50d0d 100644 --- a/boards/arm/nucleo_f303k8/nucleo_f303k8.yaml +++ b/boards/arm/nucleo_f303k8/nucleo_f303k8.yaml @@ -15,3 +15,4 @@ supported: - gpio - pwm - counter +vendor: st diff --git a/boards/arm/nucleo_f303re/nucleo_f303re.yaml b/boards/arm/nucleo_f303re/nucleo_f303re.yaml index f1aa776b762..525a83f252a 100644 --- a/boards/arm/nucleo_f303re/nucleo_f303re.yaml +++ b/boards/arm/nucleo_f303re/nucleo_f303re.yaml @@ -15,3 +15,4 @@ supported: - can - i2c - spi +vendor: st diff --git a/boards/arm/nucleo_f334r8/nucleo_f334r8.yaml b/boards/arm/nucleo_f334r8/nucleo_f334r8.yaml index 2c72db14686..a4533b015a0 100644 --- a/boards/arm/nucleo_f334r8/nucleo_f334r8.yaml +++ b/boards/arm/nucleo_f334r8/nucleo_f334r8.yaml @@ -23,3 +23,4 @@ supported: - watchdog - counter - nvs +vendor: st diff --git a/boards/arm/nucleo_f401re/nucleo_f401re.yaml b/boards/arm/nucleo_f401re/nucleo_f401re.yaml index 3d6336f7d37..ea1d89798c0 100644 --- a/boards/arm/nucleo_f401re/nucleo_f401re.yaml +++ b/boards/arm/nucleo_f401re/nucleo_f401re.yaml @@ -19,3 +19,4 @@ supported: - watchdog ram: 96 flash: 512 +vendor: st diff --git a/boards/arm/nucleo_f410rb/nucleo_f410rb.yaml b/boards/arm/nucleo_f410rb/nucleo_f410rb.yaml index a1ce4005e07..81eef793cdd 100644 --- a/boards/arm/nucleo_f410rb/nucleo_f410rb.yaml +++ b/boards/arm/nucleo_f410rb/nucleo_f410rb.yaml @@ -16,3 +16,4 @@ supported: - i2c ram: 32 flash: 128 +vendor: st diff --git a/boards/arm/nucleo_f411re/nucleo_f411re.yaml b/boards/arm/nucleo_f411re/nucleo_f411re.yaml index 1a7a9fafa51..90a57f93720 100644 --- a/boards/arm/nucleo_f411re/nucleo_f411re.yaml +++ b/boards/arm/nucleo_f411re/nucleo_f411re.yaml @@ -17,3 +17,4 @@ supported: - i2c ram: 96 flash: 512 +vendor: st diff --git a/boards/arm/nucleo_f412zg/nucleo_f412zg.yaml b/boards/arm/nucleo_f412zg/nucleo_f412zg.yaml index 1742dc95f1d..10fd21fc705 100644 --- a/boards/arm/nucleo_f412zg/nucleo_f412zg.yaml +++ b/boards/arm/nucleo_f412zg/nucleo_f412zg.yaml @@ -18,3 +18,4 @@ supported: - gpio - usb_device - counter +vendor: st diff --git a/boards/arm/nucleo_f413zh/nucleo_f413zh.yaml b/boards/arm/nucleo_f413zh/nucleo_f413zh.yaml index d81b743115d..415b1d08f56 100644 --- a/boards/arm/nucleo_f413zh/nucleo_f413zh.yaml +++ b/boards/arm/nucleo_f413zh/nucleo_f413zh.yaml @@ -18,3 +18,4 @@ supported: - gpio - usb_device - counter +vendor: st diff --git a/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml b/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml index e4afaa797fa..762ede6fb2c 100644 --- a/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml +++ b/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml @@ -24,3 +24,4 @@ supported: - dac - dma - nvs +vendor: st diff --git a/boards/arm/nucleo_f446re/nucleo_f446re.yaml b/boards/arm/nucleo_f446re/nucleo_f446re.yaml index 38cf4a4b5a7..9d45982d995 100644 --- a/boards/arm/nucleo_f446re/nucleo_f446re.yaml +++ b/boards/arm/nucleo_f446re/nucleo_f446re.yaml @@ -18,3 +18,4 @@ supported: - backup_sram ram: 96 flash: 512 +vendor: st diff --git a/boards/arm/nucleo_f446ze/nucleo_f446ze.yaml b/boards/arm/nucleo_f446ze/nucleo_f446ze.yaml index f8a93e59e2a..f363608c3be 100644 --- a/boards/arm/nucleo_f446ze/nucleo_f446ze.yaml +++ b/boards/arm/nucleo_f446ze/nucleo_f446ze.yaml @@ -21,3 +21,4 @@ supported: - quadspi ram: 128 flash: 512 +vendor: st diff --git a/boards/arm/nucleo_f746zg/nucleo_f746zg.yaml b/boards/arm/nucleo_f746zg/nucleo_f746zg.yaml index 32b17d86aa6..015b1e3e642 100644 --- a/boards/arm/nucleo_f746zg/nucleo_f746zg.yaml +++ b/boards/arm/nucleo_f746zg/nucleo_f746zg.yaml @@ -26,3 +26,4 @@ supported: - dac - dma - backup_sram +vendor: st diff --git a/boards/arm/nucleo_f756zg/nucleo_f756zg.yaml b/boards/arm/nucleo_f756zg/nucleo_f756zg.yaml index 01d78747f06..ddcf34064ad 100644 --- a/boards/arm/nucleo_f756zg/nucleo_f756zg.yaml +++ b/boards/arm/nucleo_f756zg/nucleo_f756zg.yaml @@ -19,3 +19,4 @@ supported: - i2c - pwm - spi +vendor: st diff --git a/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml b/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml index d6b46f15bbc..e3be20e3780 100644 --- a/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml +++ b/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml @@ -25,3 +25,4 @@ supported: - counter - can - dac +vendor: st diff --git a/boards/arm/nucleo_g031k8/nucleo_g031k8.yaml b/boards/arm/nucleo_g031k8/nucleo_g031k8.yaml index 9a19f3e6338..34ea35189ab 100644 --- a/boards/arm/nucleo_g031k8/nucleo_g031k8.yaml +++ b/boards/arm/nucleo_g031k8/nucleo_g031k8.yaml @@ -12,3 +12,4 @@ supported: - spi ram: 8 flash: 64 +vendor: st diff --git a/boards/arm/nucleo_g070rb/nucleo_g070rb.yaml b/boards/arm/nucleo_g070rb/nucleo_g070rb.yaml index cb12531bebd..6cac29d4db1 100644 --- a/boards/arm/nucleo_g070rb/nucleo_g070rb.yaml +++ b/boards/arm/nucleo_g070rb/nucleo_g070rb.yaml @@ -22,3 +22,4 @@ supported: - pwm - adc - nvs +vendor: st diff --git a/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml b/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml index 87921bf7b76..755196fec16 100644 --- a/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml +++ b/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml @@ -25,3 +25,4 @@ supported: - dma - lptim - nvs +vendor: st diff --git a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml index f52eb20db29..259a1abcd90 100644 --- a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml +++ b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml @@ -21,3 +21,4 @@ supported: - dma - usb_device - lptim +vendor: st diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml index 6ad1f6f12f9..642b8a68c49 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml @@ -21,3 +21,4 @@ supported: - spi - dac - watchdog +vendor: st diff --git a/boards/arm/nucleo_g474re/nucleo_g474re.yaml b/boards/arm/nucleo_g474re/nucleo_g474re.yaml index eee22d085f5..d473be929bf 100644 --- a/boards/arm/nucleo_g474re/nucleo_g474re.yaml +++ b/boards/arm/nucleo_g474re/nucleo_g474re.yaml @@ -24,3 +24,4 @@ supported: - dac - dma - can +vendor: st diff --git a/boards/arm/nucleo_h563zi/nucleo_h563zi.yaml b/boards/arm/nucleo_h563zi/nucleo_h563zi.yaml index 0d1b1758a22..9e04cd2b7de 100644 --- a/boards/arm/nucleo_h563zi/nucleo_h563zi.yaml +++ b/boards/arm/nucleo_h563zi/nucleo_h563zi.yaml @@ -22,3 +22,4 @@ supported: - usb_device - usb - rtc +vendor: st diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml index 91c47848192..622c268ecea 100644 --- a/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml @@ -21,3 +21,4 @@ supported: - netif:eth - backup_sram - usb_device +vendor: st diff --git a/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml b/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml index a1246f75714..e67e8d0e54e 100644 --- a/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml +++ b/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml @@ -25,3 +25,4 @@ supported: - can - dac - dma +vendor: st diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml index 4d4ee02380e..3299fb78496 100644 --- a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - mpu - nfc +vendor: st diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml index 656b23bbacf..8c124a0a906 100644 --- a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml @@ -17,3 +17,4 @@ supported: - i2c - pwm - netif:eth +vendor: st diff --git a/boards/arm/nucleo_h753zi/nucleo_h753zi.yaml b/boards/arm/nucleo_h753zi/nucleo_h753zi.yaml index d63bd6b2c93..7bca456c26e 100644 --- a/boards/arm/nucleo_h753zi/nucleo_h753zi.yaml +++ b/boards/arm/nucleo_h753zi/nucleo_h753zi.yaml @@ -21,3 +21,4 @@ supported: - spi - usb_device - can +vendor: st diff --git a/boards/arm/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml b/boards/arm/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml index 381d2fdf53b..65cd30b3e0b 100644 --- a/boards/arm/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml +++ b/boards/arm/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml @@ -15,3 +15,4 @@ supported: - pwm - adc - backup_sram +vendor: st diff --git a/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml b/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml index 650438636a6..e3ce901c4ee 100644 --- a/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml +++ b/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml @@ -13,3 +13,4 @@ supported: - eeprom ram: 8 flash: 32 +vendor: st diff --git a/boards/arm/nucleo_l053r8/nucleo_l053r8.yaml b/boards/arm/nucleo_l053r8/nucleo_l053r8.yaml index 5605e0ce837..384d5294913 100644 --- a/boards/arm/nucleo_l053r8/nucleo_l053r8.yaml +++ b/boards/arm/nucleo_l053r8/nucleo_l053r8.yaml @@ -16,3 +16,4 @@ supported: - eeprom ram: 8 flash: 64 +vendor: st diff --git a/boards/arm/nucleo_l073rz/nucleo_l073rz.yaml b/boards/arm/nucleo_l073rz/nucleo_l073rz.yaml index dc82c77449c..f97973c4854 100644 --- a/boards/arm/nucleo_l073rz/nucleo_l073rz.yaml +++ b/boards/arm/nucleo_l073rz/nucleo_l073rz.yaml @@ -22,3 +22,4 @@ supported: - counter - rng - eeprom +vendor: st diff --git a/boards/arm/nucleo_l152re/nucleo_l152re.yaml b/boards/arm/nucleo_l152re/nucleo_l152re.yaml index 8cfcaee9c2d..cc550b993c9 100644 --- a/boards/arm/nucleo_l152re/nucleo_l152re.yaml +++ b/boards/arm/nucleo_l152re/nucleo_l152re.yaml @@ -23,3 +23,4 @@ supported: - pwm - dma - nvs +vendor: st diff --git a/boards/arm/nucleo_l412rb_p/nucleo_l412rb_p.yaml b/boards/arm/nucleo_l412rb_p/nucleo_l412rb_p.yaml index c46de0ee7bb..8c663aae012 100644 --- a/boards/arm/nucleo_l412rb_p/nucleo_l412rb_p.yaml +++ b/boards/arm/nucleo_l412rb_p/nucleo_l412rb_p.yaml @@ -18,3 +18,4 @@ supported: - arduino_gpio - arduino_i2c - arduino_spi +vendor: st diff --git a/boards/arm/nucleo_l432kc/nucleo_l432kc.yaml b/boards/arm/nucleo_l432kc/nucleo_l432kc.yaml index 06cead72758..345fcb7e44f 100644 --- a/boards/arm/nucleo_l432kc/nucleo_l432kc.yaml +++ b/boards/arm/nucleo_l432kc/nucleo_l432kc.yaml @@ -14,3 +14,4 @@ supported: - can - counter - spi +vendor: st diff --git a/boards/arm/nucleo_l433rc_p/nucleo_l433rc_p.yaml b/boards/arm/nucleo_l433rc_p/nucleo_l433rc_p.yaml index 94ec419e9a4..ee3a41bce02 100644 --- a/boards/arm/nucleo_l433rc_p/nucleo_l433rc_p.yaml +++ b/boards/arm/nucleo_l433rc_p/nucleo_l433rc_p.yaml @@ -17,3 +17,4 @@ supported: - i2c - arduino_i2c - arduino_spi +vendor: st diff --git a/boards/arm/nucleo_l452re/nucleo_l452re.yaml b/boards/arm/nucleo_l452re/nucleo_l452re.yaml index 49e3d93f39f..0b3aa645bf4 100644 --- a/boards/arm/nucleo_l452re/nucleo_l452re.yaml +++ b/boards/arm/nucleo_l452re/nucleo_l452re.yaml @@ -14,3 +14,4 @@ supported: - can - counter - spi +vendor: st diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml b/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml index 0f02e07d1a4..7ca93a9c9bc 100644 --- a/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml +++ b/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml @@ -14,3 +14,4 @@ supported: - can - counter - spi +vendor: st diff --git a/boards/arm/nucleo_l476rg/nucleo_l476rg.yaml b/boards/arm/nucleo_l476rg/nucleo_l476rg.yaml index 6c48781032e..d0330751a75 100644 --- a/boards/arm/nucleo_l476rg/nucleo_l476rg.yaml +++ b/boards/arm/nucleo_l476rg/nucleo_l476rg.yaml @@ -19,3 +19,4 @@ supported: - adc ram: 96 flash: 1024 +vendor: st diff --git a/boards/arm/nucleo_l496zg/nucleo_l496zg.yaml b/boards/arm/nucleo_l496zg/nucleo_l496zg.yaml index 9f969025a56..39734163f3d 100644 --- a/boards/arm/nucleo_l496zg/nucleo_l496zg.yaml +++ b/boards/arm/nucleo_l496zg/nucleo_l496zg.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/nucleo_l4a6zg/nucleo_l4a6zg.yaml b/boards/arm/nucleo_l4a6zg/nucleo_l4a6zg.yaml index fc671d1dfae..bdc87910a4f 100644 --- a/boards/arm/nucleo_l4a6zg/nucleo_l4a6zg.yaml +++ b/boards/arm/nucleo_l4a6zg/nucleo_l4a6zg.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml index 5c1cb0e1e76..ee4115fc1e6 100644 --- a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml +++ b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml @@ -20,3 +20,4 @@ supported: - adc ram: 640 flash: 2048 +vendor: st diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.yaml b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.yaml index 43f12c43465..e0a2c89d389 100644 --- a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.yaml +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.yaml @@ -14,3 +14,4 @@ supported: - spi ram: 192 flash: 512 +vendor: st diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml index 5677f5187d6..1eb62f85b96 100644 --- a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml @@ -10,3 +10,4 @@ supported: - dac ram: 192 flash: 328 +vendor: st diff --git a/boards/arm/nucleo_u575zi_q/nucleo_u575zi_q.yaml b/boards/arm/nucleo_u575zi_q/nucleo_u575zi_q.yaml index 4874beb6561..0c65b8361ff 100644 --- a/boards/arm/nucleo_u575zi_q/nucleo_u575zi_q.yaml +++ b/boards/arm/nucleo_u575zi_q/nucleo_u575zi_q.yaml @@ -22,3 +22,4 @@ supported: - dma ram: 786 flash: 2048 +vendor: st diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml index a4a8e181077..f455356048c 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml @@ -22,3 +22,4 @@ supported: - arduino_spi - usb_device - nvs +vendor: st diff --git a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml index 22e888c7ac3..a5eb79afc42 100644 --- a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml +++ b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml @@ -17,3 +17,4 @@ supported: - arduino_spi ram: 128 flash: 1024 +vendor: st diff --git a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.yaml b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.yaml index 93be2f6ed91..b741d372805 100644 --- a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.yaml +++ b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.yaml @@ -23,3 +23,4 @@ supported: - watchdog - nvs - lora +vendor: st diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml index 41f6d4c88cf..74adba17eb0 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml @@ -13,3 +13,6 @@ ram: 512 flash: 1024 supported: - gpio +testing: + default: true +vendor: nuvoton diff --git a/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml index 33af96d6bc9..c56fb1fd78e 100644 --- a/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml +++ b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 160 flash: 512 +vendor: nuvoton diff --git a/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.yaml b/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.yaml index a2ac552b4b2..5fdb67ec933 100644 --- a/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.yaml +++ b/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.yaml @@ -17,3 +17,4 @@ supported: - uart - watchdog - lora +vendor: olimex diff --git a/boards/arm/olimex_stm32_e407/olimex_stm32_e407.yaml b/boards/arm/olimex_stm32_e407/olimex_stm32_e407.yaml index 675ac2631a0..beefd5d2c8a 100644 --- a/boards/arm/olimex_stm32_e407/olimex_stm32_e407.yaml +++ b/boards/arm/olimex_stm32_e407/olimex_stm32_e407.yaml @@ -11,3 +11,4 @@ flash: 1024 supported: - counter - usb_device +vendor: olimex diff --git a/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml index 392d559fc73..b863460fda4 100644 --- a/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml +++ b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - bluetooth - net +vendor: olimex diff --git a/boards/arm/olimex_stm32_h405/olimex_stm32_h405.yaml b/boards/arm/olimex_stm32_h405/olimex_stm32_h405.yaml index 57237445572..9930505236f 100644 --- a/boards/arm/olimex_stm32_h405/olimex_stm32_h405.yaml +++ b/boards/arm/olimex_stm32_h405/olimex_stm32_h405.yaml @@ -10,3 +10,4 @@ ram: 128 flash: 1024 supported: - counter +vendor: olimex diff --git a/boards/arm/olimex_stm32_h407/olimex_stm32_h407.yaml b/boards/arm/olimex_stm32_h407/olimex_stm32_h407.yaml index fe6d3237849..fea55c8a3d4 100644 --- a/boards/arm/olimex_stm32_h407/olimex_stm32_h407.yaml +++ b/boards/arm/olimex_stm32_h407/olimex_stm32_h407.yaml @@ -10,3 +10,4 @@ ram: 128 flash: 1024 supported: - counter +vendor: olimex diff --git a/boards/arm/olimex_stm32_p405/olimex_stm32_p405.yaml b/boards/arm/olimex_stm32_p405/olimex_stm32_p405.yaml index 6f5c5b9357d..d3c23913f35 100644 --- a/boards/arm/olimex_stm32_p405/olimex_stm32_p405.yaml +++ b/boards/arm/olimex_stm32_p405/olimex_stm32_p405.yaml @@ -11,3 +11,4 @@ flash: 1024 supported: - counter - can +vendor: olimex diff --git a/boards/arm/olimexino_stm32/olimexino_stm32.yaml b/boards/arm/olimexino_stm32/olimexino_stm32.yaml index b5b2afa8bb2..b4cf8b26bfb 100644 --- a/boards/arm/olimexino_stm32/olimexino_stm32.yaml +++ b/boards/arm/olimexino_stm32/olimexino_stm32.yaml @@ -16,3 +16,4 @@ supported: - usb_device - watchdog - can +vendor: olimex diff --git a/boards/arm/particle_argon/particle_argon.yaml b/boards/arm/particle_argon/particle_argon.yaml index 7e3d9e642d6..489b8c9dd1e 100644 --- a/boards/arm/particle_argon/particle_argon.yaml +++ b/boards/arm/particle_argon/particle_argon.yaml @@ -17,3 +17,4 @@ supported: - feather_serial - feather_i2c - feather_spi +vendor: particle diff --git a/boards/arm/particle_boron/particle_boron.yaml b/boards/arm/particle_boron/particle_boron.yaml index 77ddd5953b5..bec2a0cbb03 100644 --- a/boards/arm/particle_boron/particle_boron.yaml +++ b/boards/arm/particle_boron/particle_boron.yaml @@ -17,3 +17,4 @@ supported: - feather_serial - feather_i2c - feather_spi +vendor: particle diff --git a/boards/arm/particle_xenon/particle_xenon.yaml b/boards/arm/particle_xenon/particle_xenon.yaml index 8129178543f..0aa6a4afa15 100644 --- a/boards/arm/particle_xenon/particle_xenon.yaml +++ b/boards/arm/particle_xenon/particle_xenon.yaml @@ -22,3 +22,4 @@ supported: - feather_serial - feather_i2c - feather_spi +vendor: particle diff --git a/boards/arm/pico_pi_m4/pico_pi_m4.yaml b/boards/arm/pico_pi_m4/pico_pi_m4.yaml index c0225f8fc42..8cc013a4e36 100644 --- a/boards/arm/pico_pi_m4/pico_pi_m4.yaml +++ b/boards/arm/pico_pi_m4/pico_pi_m4.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: nxp diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.yaml b/boards/arm/pinetime_devkit0/pinetime_devkit0.yaml index 245346b1db8..081daced8ab 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0.yaml +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.yaml @@ -8,3 +8,6 @@ toolchain: - xtools ram: 64 flash: 512 +supported: + - kscan:touch +vendor: pine64 diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml index c935d100c32..153fb6cab08 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml @@ -20,3 +20,4 @@ supported: - usb_device - watchdog - netif:modem +vendor: lairdconnect diff --git a/boards/arm/qemu_cortex_a9/qemu_cortex_a9.yaml b/boards/arm/qemu_cortex_a9/qemu_cortex_a9.yaml index e896b273b6d..cf8853c3d5f 100644 --- a/boards/arm/qemu_cortex_a9/qemu_cortex_a9.yaml +++ b/boards/arm/qemu_cortex_a9/qemu_cortex_a9.yaml @@ -24,3 +24,4 @@ testing: ignore_tags: - bluetooth - gpio +vendor: xlnx diff --git a/boards/arm/qemu_cortex_m3/qemu_cortex_m3.yaml b/boards/arm/qemu_cortex_m3/qemu_cortex_m3.yaml index 51388617d0e..cceafa8942e 100644 --- a/boards/arm/qemu_cortex_m3/qemu_cortex_m3.yaml +++ b/boards/arm/qemu_cortex_m3/qemu_cortex_m3.yaml @@ -15,3 +15,4 @@ flash: 256 testing: ignore_tags: - net +vendor: ti diff --git a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml index 9a7212909df..17fbb1c8d94 100644 --- a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml +++ b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: xlnx diff --git a/boards/arm/qomu/qomu.yaml b/boards/arm/qomu/qomu.yaml index 9ed10212dde..7e47a163ac9 100644 --- a/boards/arm/qomu/qomu.yaml +++ b/boards/arm/qomu/qomu.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: quicklogic diff --git a/boards/arm/quick_feather/quick_feather.yaml b/boards/arm/quick_feather/quick_feather.yaml index 7f92a190b64..9342b75994e 100644 --- a/boards/arm/quick_feather/quick_feather.yaml +++ b/boards/arm/quick_feather/quick_feather.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: quicklogic diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.yaml b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.yaml index 8a1c5a2272c..fb56f5275f6 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.yaml +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.yaml @@ -19,3 +19,4 @@ supported: - usb_device - watchdog - lora +vendor: rak diff --git a/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml index c32726dccec..1238add9d37 100644 --- a/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml +++ b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml @@ -18,3 +18,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: rak diff --git a/boards/arm/rcar_h3_salvatorx/rcar_h3_salvatorx_cr7.yaml b/boards/arm/rcar_h3_salvatorx/rcar_h3_salvatorx_cr7.yaml index 17a5d80668a..f751adbcc47 100644 --- a/boards/arm/rcar_h3_salvatorx/rcar_h3_salvatorx_cr7.yaml +++ b/boards/arm/rcar_h3_salvatorx/rcar_h3_salvatorx_cr7.yaml @@ -13,3 +13,4 @@ supported: testing: ignore_tags: - isotp +vendor: renesas diff --git a/boards/arm/rcar_h3ulcb/rcar_h3ulcb_cr7.yaml b/boards/arm/rcar_h3ulcb/rcar_h3ulcb_cr7.yaml index 61f8cbc3ac2..09d5ae1c93f 100644 --- a/boards/arm/rcar_h3ulcb/rcar_h3ulcb_cr7.yaml +++ b/boards/arm/rcar_h3ulcb/rcar_h3ulcb_cr7.yaml @@ -14,3 +14,4 @@ supported: testing: ignore_tags: - isotp +vendor: renesas diff --git a/boards/arm/rddrone_fmuk66/rddrone_fmuk66.yaml b/boards/arm/rddrone_fmuk66/rddrone_fmuk66.yaml index ecab5d4c34d..44723b330b3 100644 --- a/boards/arm/rddrone_fmuk66/rddrone_fmuk66.yaml +++ b/boards/arm/rddrone_fmuk66/rddrone_fmuk66.yaml @@ -17,3 +17,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/reel_board/reel_board.yaml b/boards/arm/reel_board/reel_board.yaml index d47f29b350d..07b5087b6c6 100644 --- a/boards/arm/reel_board/reel_board.yaml +++ b/boards/arm/reel_board/reel_board.yaml @@ -19,3 +19,4 @@ supported: - arduino_i2c - arduino_spi - arduino_gpio +vendor: phytec diff --git a/boards/arm/reel_board/reel_board_v2.yaml b/boards/arm/reel_board/reel_board_v2.yaml index 4785e376fa0..2b27622e089 100644 --- a/boards/arm/reel_board/reel_board_v2.yaml +++ b/boards/arm/reel_board/reel_board_v2.yaml @@ -19,3 +19,4 @@ supported: - arduino_i2c - arduino_spi - arduino_gpio +vendor: phytec diff --git a/boards/arm/rm1xx_dvk/rm1xx_dvk.yaml b/boards/arm/rm1xx_dvk/rm1xx_dvk.yaml index 00cb5f4c96f..c673fd4d55e 100644 --- a/boards/arm/rm1xx_dvk/rm1xx_dvk.yaml +++ b/boards/arm/rm1xx_dvk/rm1xx_dvk.yaml @@ -14,3 +14,4 @@ supported: testing: ignore_tags: - net +vendor: lairdconnect diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml index 43bbfae0fc6..151e614cbfb 100644 --- a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml @@ -16,3 +16,4 @@ supported: - counter - nvs - watchdog +vendor: ruuvi diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml index 9d229e27b98..dbf4d3bd840 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml @@ -14,3 +14,4 @@ supported: - watchdog - netif:eth - can +vendor: nxp diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml index 845d7b09291..2a722ee4606 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml @@ -14,3 +14,4 @@ supported: - watchdog - netif:eth - can +vendor: nxp diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.yaml b/boards/arm/sam4e_xpro/sam4e_xpro.yaml index 79c357b5df5..76ca997b1a0 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.yaml +++ b/boards/arm/sam4e_xpro/sam4e_xpro.yaml @@ -16,3 +16,4 @@ supported: - xpro_i2c - xpro_serial - xpro_spi +vendor: atmel diff --git a/boards/arm/sam4l_ek/sam4l_ek.yaml b/boards/arm/sam4l_ek/sam4l_ek.yaml index 2a8ecf8c0e1..cdadbee508a 100644 --- a/boards/arm/sam4l_ek/sam4l_ek.yaml +++ b/boards/arm/sam4l_ek/sam4l_ek.yaml @@ -14,3 +14,4 @@ supported: - spi - usart - usb_device +vendor: atmel diff --git a/boards/arm/sam4s_xplained/sam4s_xplained.yaml b/boards/arm/sam4s_xplained/sam4s_xplained.yaml index 3b537a2b56e..20e5949b0fe 100644 --- a/boards/arm/sam4s_xplained/sam4s_xplained.yaml +++ b/boards/arm/sam4s_xplained/sam4s_xplained.yaml @@ -18,3 +18,4 @@ supported: - xplained_serial - xplained_spi - hwinfo +vendor: atmel diff --git a/boards/arm/sam_e70_xplained/sam_e70_xplained.yaml b/boards/arm/sam_e70_xplained/sam_e70_xplained.yaml index ae2fa89bbc7..714795a2104 100644 --- a/boards/arm/sam_e70_xplained/sam_e70_xplained.yaml +++ b/boards/arm/sam_e70_xplained/sam_e70_xplained.yaml @@ -20,3 +20,4 @@ supported: - pwm - can - hwinfo +vendor: atmel diff --git a/boards/arm/sam_e70_xplained/sam_e70b_xplained.yaml b/boards/arm/sam_e70_xplained/sam_e70b_xplained.yaml index 99c53142c18..8cd515dca40 100644 --- a/boards/arm/sam_e70_xplained/sam_e70b_xplained.yaml +++ b/boards/arm/sam_e70_xplained/sam_e70b_xplained.yaml @@ -19,3 +19,4 @@ supported: - pwm - can - hwinfo +vendor: atmel diff --git a/boards/arm/sam_v71_xult/sam_v71_xult.yaml b/boards/arm/sam_v71_xult/sam_v71_xult.yaml index c71bcd3f83d..01055202950 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult.yaml +++ b/boards/arm/sam_v71_xult/sam_v71_xult.yaml @@ -24,3 +24,4 @@ supported: - xpro_spi - can - hwinfo +vendor: atmel diff --git a/boards/arm/sam_v71_xult/sam_v71b_xult.yaml b/boards/arm/sam_v71_xult/sam_v71b_xult.yaml index 3090a3a155d..9dbb670075f 100644 --- a/boards/arm/sam_v71_xult/sam_v71b_xult.yaml +++ b/boards/arm/sam_v71_xult/sam_v71b_xult.yaml @@ -24,3 +24,4 @@ supported: - xpro_spi - can - hwinfo +vendor: atmel diff --git a/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml b/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml index 657136f693a..73bfc8b114d 100644 --- a/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml +++ b/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml @@ -18,3 +18,4 @@ supported: - uart - usb_device - watchdog +vendor: seeed diff --git a/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml index 594663d6a39..911c3764802 100644 --- a/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml +++ b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml @@ -17,3 +17,4 @@ testing: - net - shell - console +vendor: segger diff --git a/boards/arm/sensortile_box/sensortile_box.yaml b/boards/arm/sensortile_box/sensortile_box.yaml index f9cbce1bc80..e67e105021b 100644 --- a/boards/arm/sensortile_box/sensortile_box.yaml +++ b/boards/arm/sensortile_box/sensortile_box.yaml @@ -16,3 +16,4 @@ supported: - counter ram: 640 flash: 2048 +vendor: st diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160.yaml b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160.yaml index 1b00c842f04..8758b385c9d 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160.yaml +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160.yaml @@ -13,3 +13,4 @@ supported: - pwm - watchdog - counter +vendor: sparkfun diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml index e667a231774..438b2df7392 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml @@ -12,3 +12,4 @@ supported: - i2c - pwm - watchdog +vendor: sparkfun diff --git a/boards/arm/steval_fcu001v1/steval_fcu001v1.yaml b/boards/arm/steval_fcu001v1/steval_fcu001v1.yaml index 951cb1b76dc..64ac751a2fc 100644 --- a/boards/arm/steval_fcu001v1/steval_fcu001v1.yaml +++ b/boards/arm/steval_fcu001v1/steval_fcu001v1.yaml @@ -14,3 +14,4 @@ supported: - watchdog ram: 64 flash: 256 +vendor: st diff --git a/boards/arm/stm3210c_eval/stm3210c_eval.yaml b/boards/arm/stm3210c_eval/stm3210c_eval.yaml index ecd46ace145..ae64ea9fe47 100644 --- a/boards/arm/stm3210c_eval/stm3210c_eval.yaml +++ b/boards/arm/stm3210c_eval/stm3210c_eval.yaml @@ -10,3 +10,4 @@ ram: 64 flash: 256 supported: - watchdog +vendor: st diff --git a/boards/arm/stm32373c_eval/stm32373c_eval.yaml b/boards/arm/stm32373c_eval/stm32373c_eval.yaml index 6342f2a587c..6d06bffe951 100644 --- a/boards/arm/stm32373c_eval/stm32373c_eval.yaml +++ b/boards/arm/stm32373c_eval/stm32373c_eval.yaml @@ -10,3 +10,4 @@ ram: 32 supported: - watchdog - counter +vendor: st diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_black.yaml b/boards/arm/stm32_min_dev/stm32_min_dev_black.yaml index c0062720aef..28739cf2b63 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_black.yaml +++ b/boards/arm/stm32_min_dev/stm32_min_dev_black.yaml @@ -13,3 +13,4 @@ supported: - spi - adc - gpio +vendor: st diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_blue.yaml b/boards/arm/stm32_min_dev/stm32_min_dev_blue.yaml index 2d39e25b8b0..ed907a960ce 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_blue.yaml +++ b/boards/arm/stm32_min_dev/stm32_min_dev_blue.yaml @@ -12,3 +12,4 @@ supported: - pwm - spi - adc +vendor: st diff --git a/boards/arm/stm32f072_eval/stm32f072_eval.yaml b/boards/arm/stm32f072_eval/stm32f072_eval.yaml index ddcdef183e0..b6655a01722 100644 --- a/boards/arm/stm32f072_eval/stm32f072_eval.yaml +++ b/boards/arm/stm32f072_eval/stm32f072_eval.yaml @@ -13,3 +13,4 @@ supported: testing: ignore_tags: - net +vendor: st diff --git a/boards/arm/stm32f072b_disco/stm32f072b_disco.yaml b/boards/arm/stm32f072b_disco/stm32f072b_disco.yaml index 5e24b081bd8..186d733ca7d 100644 --- a/boards/arm/stm32f072b_disco/stm32f072b_disco.yaml +++ b/boards/arm/stm32f072b_disco/stm32f072b_disco.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: st diff --git a/boards/arm/stm32f0_disco/stm32f0_disco.yaml b/boards/arm/stm32f0_disco/stm32f0_disco.yaml index 2a5cbec6e7a..53954e2a4ed 100644 --- a/boards/arm/stm32f0_disco/stm32f0_disco.yaml +++ b/boards/arm/stm32f0_disco/stm32f0_disco.yaml @@ -9,3 +9,4 @@ toolchain: ram: 8 supported: - watchdog +vendor: st diff --git a/boards/arm/stm32f103_mini/stm32f103_mini.yaml b/boards/arm/stm32f103_mini/stm32f103_mini.yaml index 7ce2c6ee5bd..ef1427ba5f9 100644 --- a/boards/arm/stm32f103_mini/stm32f103_mini.yaml +++ b/boards/arm/stm32f103_mini/stm32f103_mini.yaml @@ -16,3 +16,4 @@ supported: - watchdog - adc - counter +vendor: st diff --git a/boards/arm/stm32f3_disco/stm32f3_disco.yaml b/boards/arm/stm32f3_disco/stm32f3_disco.yaml index ef5b77054cc..0d0aafdc5a2 100644 --- a/boards/arm/stm32f3_disco/stm32f3_disco.yaml +++ b/boards/arm/stm32f3_disco/stm32f3_disco.yaml @@ -21,3 +21,4 @@ supported: - adc - dac - dma +vendor: st diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.yaml b/boards/arm/stm32f411e_disco/stm32f411e_disco.yaml index 7ede09caf04..725a9fd46bd 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.yaml +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.yaml @@ -8,3 +8,4 @@ toolchain: - xtools supported: - counter +vendor: st diff --git a/boards/arm/stm32f412g_disco/stm32f412g_disco.yaml b/boards/arm/stm32f412g_disco/stm32f412g_disco.yaml index 78f2cb5bd6e..5bf836929ba 100644 --- a/boards/arm/stm32f412g_disco/stm32f412g_disco.yaml +++ b/boards/arm/stm32f412g_disco/stm32f412g_disco.yaml @@ -12,3 +12,4 @@ supported: - arduino_i2c - arduino_spi - counter +vendor: st diff --git a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.yaml b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.yaml index ce8b9d2ae78..5d4b25c8312 100644 --- a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.yaml +++ b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.yaml @@ -13,3 +13,4 @@ supported: - i2c - spi - display +vendor: st diff --git a/boards/arm/stm32f469i_disco/stm32f469i_disco.yaml b/boards/arm/stm32f469i_disco/stm32f469i_disco.yaml index fc65586446f..fef17c354b8 100644 --- a/boards/arm/stm32f469i_disco/stm32f469i_disco.yaml +++ b/boards/arm/stm32f469i_disco/stm32f469i_disco.yaml @@ -17,3 +17,4 @@ supported: - gpio - arduino_gpio - usb_device +vendor: st diff --git a/boards/arm/stm32f4_disco/stm32f4_disco.yaml b/boards/arm/stm32f4_disco/stm32f4_disco.yaml index 525c948ec36..5bdfaca3b7b 100644 --- a/boards/arm/stm32f4_disco/stm32f4_disco.yaml +++ b/boards/arm/stm32f4_disco/stm32f4_disco.yaml @@ -13,3 +13,4 @@ supported: - pwm - counter - usb +vendor: st diff --git a/boards/arm/stm32f723e_disco/stm32f723e_disco.yaml b/boards/arm/stm32f723e_disco/stm32f723e_disco.yaml index 95e18e63515..d8f5b1a14a7 100644 --- a/boards/arm/stm32f723e_disco/stm32f723e_disco.yaml +++ b/boards/arm/stm32f723e_disco/stm32f723e_disco.yaml @@ -16,3 +16,4 @@ supported: - spi - arduino_spi - usb_device +vendor: st diff --git a/boards/arm/stm32f746g_disco/stm32f746g_disco.yaml b/boards/arm/stm32f746g_disco/stm32f746g_disco.yaml index edc6635e0b4..f3ef45a7906 100644 --- a/boards/arm/stm32f746g_disco/stm32f746g_disco.yaml +++ b/boards/arm/stm32f746g_disco/stm32f746g_disco.yaml @@ -20,3 +20,4 @@ supported: - usb_device - display - memc +vendor: st diff --git a/boards/arm/stm32f7508_dk/stm32f7508_dk.yaml b/boards/arm/stm32f7508_dk/stm32f7508_dk.yaml index fca291ee3d1..b474319510d 100644 --- a/boards/arm/stm32f7508_dk/stm32f7508_dk.yaml +++ b/boards/arm/stm32f7508_dk/stm32f7508_dk.yaml @@ -23,3 +23,4 @@ supported: - usb_device - display - memc +vendor: st diff --git a/boards/arm/stm32f769i_disco/stm32f769i_disco.yaml b/boards/arm/stm32f769i_disco/stm32f769i_disco.yaml index 520d6437ef5..69f06949e2a 100644 --- a/boards/arm/stm32f769i_disco/stm32f769i_disco.yaml +++ b/boards/arm/stm32f769i_disco/stm32f769i_disco.yaml @@ -17,3 +17,5 @@ supported: - arduino_gpio - netif:eth - memc + - kscan:touch +vendor: st diff --git a/boards/arm/stm32g0316_disco/stm32g0316_disco.yaml b/boards/arm/stm32g0316_disco/stm32g0316_disco.yaml index 0dc20f26d67..3b6cb215ce4 100644 --- a/boards/arm/stm32g0316_disco/stm32g0316_disco.yaml +++ b/boards/arm/stm32g0316_disco/stm32g0316_disco.yaml @@ -13,3 +13,4 @@ supported: - uart - watchdog - dma +vendor: st diff --git a/boards/arm/stm32g071b_disco/stm32g071b_disco.yaml b/boards/arm/stm32g071b_disco/stm32g071b_disco.yaml index e1830d15f33..817860f27ac 100644 --- a/boards/arm/stm32g071b_disco/stm32g071b_disco.yaml +++ b/boards/arm/stm32g071b_disco/stm32g071b_disco.yaml @@ -14,3 +14,4 @@ supported: - i2c - watchdog - tcpc +vendor: st diff --git a/boards/arm/stm32g081b_eval/stm32g081b_eval.yaml b/boards/arm/stm32g081b_eval/stm32g081b_eval.yaml index e22b6e4207c..313faf236a8 100644 --- a/boards/arm/stm32g081b_eval/stm32g081b_eval.yaml +++ b/boards/arm/stm32g081b_eval/stm32g081b_eval.yaml @@ -14,3 +14,4 @@ supported: - gpio - watchdog - tcpc +vendor: st diff --git a/boards/arm/stm32h573i_dk/stm32h573i_dk.yaml b/boards/arm/stm32h573i_dk/stm32h573i_dk.yaml index e7ed5b5d3cb..8eea15d5d02 100644 --- a/boards/arm/stm32h573i_dk/stm32h573i_dk.yaml +++ b/boards/arm/stm32h573i_dk/stm32h573i_dk.yaml @@ -22,3 +22,4 @@ supported: - can - usb_device - usb +vendor: st diff --git a/boards/arm/stm32h735g_disco/stm32h735g_disco.yaml b/boards/arm/stm32h735g_disco/stm32h735g_disco.yaml index 16d056e600d..a679deb18d4 100644 --- a/boards/arm/stm32h735g_disco/stm32h735g_disco.yaml +++ b/boards/arm/stm32h735g_disco/stm32h735g_disco.yaml @@ -15,3 +15,4 @@ supported: - memc - adc - counter +vendor: st diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.yaml b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.yaml index 5038a8e5aca..e167c87f64d 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.yaml +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.yaml @@ -16,3 +16,4 @@ testing: - mpu - nfc - net +vendor: st diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml index fb67ae1e398..52e516cda95 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml @@ -18,3 +18,4 @@ supported: - memc - usb_cdc - usb_device +vendor: st diff --git a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.yaml b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.yaml index d3c2894fb74..3779381d564 100644 --- a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.yaml +++ b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.yaml @@ -17,3 +17,4 @@ supported: - backup_sram - display - can +vendor: st diff --git a/boards/arm/stm32l1_disco/stm32l1_disco.yaml b/boards/arm/stm32l1_disco/stm32l1_disco.yaml index 6ef79ef4341..75fa0045fa4 100644 --- a/boards/arm/stm32l1_disco/stm32l1_disco.yaml +++ b/boards/arm/stm32l1_disco/stm32l1_disco.yaml @@ -12,3 +12,4 @@ supported: - gpio - i2c - spi +vendor: st diff --git a/boards/arm/stm32l476g_disco/stm32l476g_disco.yaml b/boards/arm/stm32l476g_disco/stm32l476g_disco.yaml index 50de851c41a..671e1738519 100644 --- a/boards/arm/stm32l476g_disco/stm32l476g_disco.yaml +++ b/boards/arm/stm32l476g_disco/stm32l476g_disco.yaml @@ -11,3 +11,4 @@ flash: 1024 supported: - gpio - counter +vendor: st diff --git a/boards/arm/stm32l496g_disco/stm32l496g_disco.yaml b/boards/arm/stm32l496g_disco/stm32l496g_disco.yaml index edf64edc3a4..3544d15980c 100644 --- a/boards/arm/stm32l496g_disco/stm32l496g_disco.yaml +++ b/boards/arm/stm32l496g_disco/stm32l496g_disco.yaml @@ -18,3 +18,4 @@ supported: - sdhc - adc - qspi +vendor: st diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml index a6759c10c25..dcb6a01d5db 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml @@ -24,3 +24,4 @@ supported: - nvs ram: 192 flash: 512 +vendor: st diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_ns.yaml b/boards/arm/stm32l562e_dk/stm32l562e_dk_ns.yaml index 43038b862b0..8d743536e74 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk_ns.yaml +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_ns.yaml @@ -18,3 +18,4 @@ supported: - usb_device ram: 192 flash: 512 +vendor: st diff --git a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml index a78e1d2fb9f..d552a6d6aa0 100644 --- a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml +++ b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml @@ -26,3 +26,4 @@ testing: - nfc ram: 256 flash: 64 +vendor: st diff --git a/boards/arm/stm32vl_disco/stm32vl_disco.yaml b/boards/arm/stm32vl_disco/stm32vl_disco.yaml index 2c73413ed49..5e37731dfcc 100644 --- a/boards/arm/stm32vl_disco/stm32vl_disco.yaml +++ b/boards/arm/stm32vl_disco/stm32vl_disco.yaml @@ -12,3 +12,4 @@ supported: - gpio - i2c - spi +vendor: st diff --git a/boards/arm/swan_r5/swan_r5.yaml b/boards/arm/swan_r5/swan_r5.yaml index 9f52d6b5cb3..5e0efea6540 100644 --- a/boards/arm/swan_r5/swan_r5.yaml +++ b/boards/arm/swan_r5/swan_r5.yaml @@ -17,3 +17,4 @@ supported: - adc ram: 640 flash: 2048 +vendor: blues diff --git a/boards/arm/tdk_robokit1/tdk_robokit1.yaml b/boards/arm/tdk_robokit1/tdk_robokit1.yaml index 33ec11e6014..4c4d8b19e13 100644 --- a/boards/arm/tdk_robokit1/tdk_robokit1.yaml +++ b/boards/arm/tdk_robokit1/tdk_robokit1.yaml @@ -18,3 +18,4 @@ supported: - pwm - can - hwinfo +vendor: tdk diff --git a/boards/arm/teensy4/teensy40.yaml b/boards/arm/teensy4/teensy40.yaml index 36ea176ed4b..11a7f0b284d 100644 --- a/boards/arm/teensy4/teensy40.yaml +++ b/boards/arm/teensy4/teensy40.yaml @@ -22,3 +22,4 @@ testing: ignore_tags: - net - posix +vendor: nxp diff --git a/boards/arm/teensy4/teensy41.yaml b/boards/arm/teensy4/teensy41.yaml index 45c40b7fdc8..b2ad1e303ca 100644 --- a/boards/arm/teensy4/teensy41.yaml +++ b/boards/arm/teensy4/teensy41.yaml @@ -23,3 +23,4 @@ testing: ignore_tags: - net - posix +vendor: nxp diff --git a/boards/arm/thingy52_nrf52832/thingy52_nrf52832.yaml b/boards/arm/thingy52_nrf52832/thingy52_nrf52832.yaml index 22882bc081b..c4aa66f67ce 100644 --- a/boards/arm/thingy52_nrf52832/thingy52_nrf52832.yaml +++ b/boards/arm/thingy52_nrf52832/thingy52_nrf52832.yaml @@ -12,3 +12,4 @@ supported: - gpio - i2c - hts221 +vendor: nordic diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp.yaml b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp.yaml index 542de24bbcb..b4651427a22 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp.yaml +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp.yaml @@ -16,3 +16,4 @@ supported: - usb_cdc - usb_device - netif:openthread +vendor: nordic diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns.yaml b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns.yaml index 5b180a30ad2..d8db4ae1520 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns.yaml +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpuapp_ns.yaml @@ -16,3 +16,4 @@ supported: - usb_cdc - usb_device - netif:openthread +vendor: nordic diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.yaml b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.yaml index 6a2e6001e71..a41d496937f 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.yaml +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.yaml @@ -11,3 +11,4 @@ flash: 256 supported: - gpio - watchdog +vendor: nordic diff --git a/boards/arm/twr_ke18f/twr_ke18f.yaml b/boards/arm/twr_ke18f/twr_ke18f.yaml index 7f55809d69e..ddd4df467f0 100644 --- a/boards/arm/twr_ke18f/twr_ke18f.yaml +++ b/boards/arm/twr_ke18f/twr_ke18f.yaml @@ -18,3 +18,4 @@ supported: - pwm - spi - watchdog +vendor: nxp diff --git a/boards/arm/twr_kv58f220m/twr_kv58f220m.yaml b/boards/arm/twr_kv58f220m/twr_kv58f220m.yaml index 480c61273bf..810d96c2ae6 100644 --- a/boards/arm/twr_kv58f220m/twr_kv58f220m.yaml +++ b/boards/arm/twr_kv58f220m/twr_kv58f220m.yaml @@ -10,3 +10,4 @@ ram: 256 flash: 1024 supported: - i2c +vendor: nxp diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.yaml b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.yaml index 3afd6fb2d3a..09d6a50ed74 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.yaml +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.yaml @@ -20,3 +20,4 @@ supported: - pwm - spi - watchdog +vendor: u-blox diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.yaml b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.yaml index e09fd51842c..3554db7451f 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.yaml +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.yaml @@ -20,3 +20,4 @@ supported: - pwm - spi - watchdog +vendor: u-blox diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.yaml b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.yaml index bef9951282c..dbe7c648911 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.yaml +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.yaml @@ -24,3 +24,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: u-blox diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.yaml b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.yaml index 4f109f0ae61..7d8201f2093 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.yaml +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.yaml @@ -23,3 +23,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: u-blox diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.yaml b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.yaml index 130de31a7ac..3da084eb1ac 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.yaml +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.yaml @@ -20,3 +20,4 @@ supported: - pwm - spi - watchdog +vendor: u-blox diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.yaml b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.yaml index 3fac915b953..afd074165c1 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.yaml +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.yaml @@ -21,3 +21,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: u-blox diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.yaml b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.yaml index fd7c6b02115..39de6903d44 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.yaml +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.yaml @@ -20,3 +20,4 @@ supported: - pwm - spi - watchdog +vendor: u-blox diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.yaml b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.yaml index a5d025a7d1f..125efd94a1c 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.yaml +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.yaml @@ -19,3 +19,4 @@ supported: - pwm - spi - watchdog +vendor: u-blox diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.yaml b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.yaml index 4c34a42d8d3..34590896e55 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.yaml +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.yaml @@ -22,3 +22,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: u-blox diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.yaml b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.yaml index 38bfc53d6c7..4134fe918c8 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.yaml +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.yaml @@ -17,3 +17,4 @@ supported: - pwm - watchdog - counter +vendor: u-blox diff --git a/boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.yaml b/boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.yaml index 2a1fd2099c5..8e2876ca5ab 100644 --- a/boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.yaml +++ b/boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.yaml @@ -18,3 +18,4 @@ supported: - counter - gpio - uart +vendor: nxp diff --git a/boards/arm/usb_kw24d512/usb_kw24d512.yaml b/boards/arm/usb_kw24d512/usb_kw24d512.yaml index 33e33c7a6c2..5344593b029 100644 --- a/boards/arm/usb_kw24d512/usb_kw24d512.yaml +++ b/boards/arm/usb_kw24d512/usb_kw24d512.yaml @@ -11,3 +11,4 @@ toolchain: supported: - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/v2m_beetle/v2m_beetle.yaml b/boards/arm/v2m_beetle/v2m_beetle.yaml index 5ccd4f60623..ca1e17d2d8d 100644 --- a/boards/arm/v2m_beetle/v2m_beetle.yaml +++ b/boards/arm/v2m_beetle/v2m_beetle.yaml @@ -8,3 +8,4 @@ toolchain: - xtools supported: - counter +vendor: arm diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml b/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml index 5893c9f009c..76ddda99468 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml @@ -8,3 +8,4 @@ toolchain: - xtools supported: - gpio +vendor: arm diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1_ns.yaml b/boards/arm/v2m_musca_b1/v2m_musca_b1_ns.yaml index 7a43ef19844..f116e1e52b9 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1_ns.yaml +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1_ns.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 64 flash: 1663 +vendor: arm diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml b/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml index 4fda7c2b4e0..194666cba50 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml @@ -8,3 +8,4 @@ toolchain: - xtools supported: - gpio +vendor: arm diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1_ns.yaml b/boards/arm/v2m_musca_s1/v2m_musca_s1_ns.yaml index e70129e968e..7494e2aff38 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1_ns.yaml +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1_ns.yaml @@ -8,3 +8,4 @@ toolchain: - xtools ram: 256 flash: 511 +vendor: arm diff --git a/boards/arm/vmu_rt1170/vmu_rt1170.yaml b/boards/arm/vmu_rt1170/vmu_rt1170.yaml index 0b60cd42e75..2eb4ce0e588 100644 --- a/boards/arm/vmu_rt1170/vmu_rt1170.yaml +++ b/boards/arm/vmu_rt1170/vmu_rt1170.yaml @@ -27,3 +27,4 @@ supported: - spi - usb_device - watchdog +vendor: nxp diff --git a/boards/arm/warp7_m4/warp7_m4.yaml b/boards/arm/warp7_m4/warp7_m4.yaml index 108ce07c600..67ed8dc2745 100644 --- a/boards/arm/warp7_m4/warp7_m4.yaml +++ b/boards/arm/warp7_m4/warp7_m4.yaml @@ -21,3 +21,4 @@ testing: supported: - gpio - i2c +vendor: nxp diff --git a/boards/arm/waveshare_open103z/waveshare_open103z.yaml b/boards/arm/waveshare_open103z/waveshare_open103z.yaml index 82fd93e99e4..c4df844c682 100644 --- a/boards/arm/waveshare_open103z/waveshare_open103z.yaml +++ b/boards/arm/waveshare_open103z/waveshare_open103z.yaml @@ -16,3 +16,4 @@ supported: - watchdog - adc - usb_device +vendor: waveshare diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.yaml b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.yaml index 68fb1650d52..b0697278931 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.yaml +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.yaml @@ -16,3 +16,4 @@ supported: - i2c - spi - uart +vendor: we diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.yaml b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.yaml index 1e1e4267143..4cc87992655 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.yaml +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.yaml @@ -17,3 +17,4 @@ supported: - i2c - pwm - spi +vendor: we diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.yaml b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.yaml index 12fc336500e..544029d3d9c 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.yaml +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.yaml @@ -17,3 +17,4 @@ supported: - gpio - i2c - spi +vendor: we diff --git a/boards/arm/wio_terminal/wio_terminal.yaml b/boards/arm/wio_terminal/wio_terminal.yaml index 3612a32d33b..e78e041719b 100644 --- a/boards/arm/wio_terminal/wio_terminal.yaml +++ b/boards/arm/wio_terminal/wio_terminal.yaml @@ -19,3 +19,4 @@ supported: - usb_cdc - usb_device - watchdog +vendor: seeed diff --git a/boards/arm/xiao_ble/xiao_ble.yaml b/boards/arm/xiao_ble/xiao_ble.yaml index e1156429c84..f8dfa743a86 100644 --- a/boards/arm/xiao_ble/xiao_ble.yaml +++ b/boards/arm/xiao_ble/xiao_ble.yaml @@ -21,3 +21,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: seeed diff --git a/boards/arm/xiao_ble/xiao_ble_sense.yaml b/boards/arm/xiao_ble/xiao_ble_sense.yaml index a27be3dc1bd..7d11907651a 100644 --- a/boards/arm/xiao_ble/xiao_ble_sense.yaml +++ b/boards/arm/xiao_ble/xiao_ble_sense.yaml @@ -21,3 +21,4 @@ supported: - usb_device - watchdog - netif:openthread +vendor: seeed diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml index 035c48e7d62..520632af5c6 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml @@ -14,3 +14,4 @@ supported: - uart ram: 160 flash: 1024 +vendor: infineon diff --git a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml index d1b96e3635b..61ab8ca25c4 100644 --- a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml +++ b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml @@ -16,3 +16,4 @@ supported: - arduino_serial ram: 352 flash: 2048 +vendor: infineon diff --git a/boards/arm/zybo/zybo.yaml b/boards/arm/zybo/zybo.yaml index 24054386106..573fb74f666 100644 --- a/boards/arm/zybo/zybo.yaml +++ b/boards/arm/zybo/zybo.yaml @@ -12,3 +12,4 @@ toolchain: ram: 524288 supported: - gpio +vendor: digilent diff --git a/boards/arm64/bcm958402m2_a72/bcm958402m2_a72.yaml b/boards/arm64/bcm958402m2_a72/bcm958402m2_a72.yaml index 08d49c3cf59..d59dd34439c 100644 --- a/boards/arm64/bcm958402m2_a72/bcm958402m2_a72.yaml +++ b/boards/arm64/bcm958402m2_a72/bcm958402m2_a72.yaml @@ -5,3 +5,4 @@ arch: arm64 toolchain: - zephyr - cross-compile +vendor: brcm diff --git a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.yaml b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.yaml index c7035277efc..ce4bdb8a5f1 100644 --- a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.yaml +++ b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.yaml @@ -10,3 +10,4 @@ toolchain: - cross-compile ram: 2048 flash: 64 +vendor: arm diff --git a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_smp_ns.yaml b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_smp_ns.yaml index 00baea468fd..68ef6a664e8 100644 --- a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_smp_ns.yaml +++ b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_smp_ns.yaml @@ -10,3 +10,4 @@ toolchain: - cross-compile ram: 2048 flash: 64 +vendor: arm diff --git a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.yaml b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.yaml index b9d67b6a27f..840fa70e5c9 100644 --- a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.yaml +++ b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.yaml @@ -12,3 +12,4 @@ ram: 2048 flash: 64 testing: timeout_multiplier: 8 +vendor: arm diff --git a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r_smp.yaml b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r_smp.yaml index 97d0d6dc8c0..1e0dfa4a9b2 100644 --- a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r_smp.yaml +++ b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r_smp.yaml @@ -14,3 +14,4 @@ supported: - smp testing: timeout_multiplier: 20 +vendor: arm diff --git a/boards/arm64/intel_socfpga_agilex5_socdk/intel_socfpga_agilex5_socdk.yaml b/boards/arm64/intel_socfpga_agilex5_socdk/intel_socfpga_agilex5_socdk.yaml index 22f713dea09..1548281bd9b 100644 --- a/boards/arm64/intel_socfpga_agilex5_socdk/intel_socfpga_agilex5_socdk.yaml +++ b/boards/arm64/intel_socfpga_agilex5_socdk/intel_socfpga_agilex5_socdk.yaml @@ -5,3 +5,4 @@ arch: arm64 toolchain: - zephyr - cross-compile +vendor: intel diff --git a/boards/arm64/intel_socfpga_agilex_socdk/intel_socfpga_agilex_socdk.yaml b/boards/arm64/intel_socfpga_agilex_socdk/intel_socfpga_agilex_socdk.yaml index 775ab2774de..b3b01f1b494 100644 --- a/boards/arm64/intel_socfpga_agilex_socdk/intel_socfpga_agilex_socdk.yaml +++ b/boards/arm64/intel_socfpga_agilex_socdk/intel_socfpga_agilex_socdk.yaml @@ -5,3 +5,4 @@ arch: arm64 toolchain: - zephyr - cross-compile +vendor: intel diff --git a/boards/arm64/khadas_edgev/khadas_edgev.yaml b/boards/arm64/khadas_edgev/khadas_edgev.yaml index a8805daa362..6d1fb7a533c 100644 --- a/boards/arm64/khadas_edgev/khadas_edgev.yaml +++ b/boards/arm64/khadas_edgev/khadas_edgev.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 8192 +vendor: khadas diff --git a/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53.yaml b/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53.yaml index 2e09f841320..72295bdb7eb 100644 --- a/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53.yaml +++ b/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53_smp.yaml b/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53_smp.yaml index 459cadedcea..b6a23c923e0 100644 --- a/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53_smp.yaml +++ b/boards/arm64/mimx8mm_evk/mimx8mm_evk_a53_smp.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53.yaml b/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53.yaml index 50c2b2edd0b..4b6bd284846 100644 --- a/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53.yaml +++ b/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53_smp.yaml b/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53_smp.yaml index 63c3f629909..487c1bb8d3a 100644 --- a/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53_smp.yaml +++ b/boards/arm64/mimx8mn_evk/mimx8mn_evk_a53_smp.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53.yaml b/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53.yaml index b5c587ec64a..dbee1a28ef2 100644 --- a/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53.yaml +++ b/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53_smp.yaml b/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53_smp.yaml index b7217fceedb..c44defa6a5b 100644 --- a/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53_smp.yaml +++ b/boards/arm64/mimx8mp_evk/mimx8mp_evk_a53_smp.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx93_evk/mimx93_evk_a55.yaml b/boards/arm64/mimx93_evk/mimx93_evk_a55.yaml index 636e1067925..72e4c677fc0 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk_a55.yaml +++ b/boards/arm64/mimx93_evk/mimx93_evk_a55.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/mimx93_evk/mimx93_evk_a55_sof.yaml b/boards/arm64/mimx93_evk/mimx93_evk_a55_sof.yaml index 514b102f495..7fffa3f990e 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk_a55_sof.yaml +++ b/boards/arm64/mimx93_evk/mimx93_evk_a55_sof.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: fsl diff --git a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb.yaml b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb.yaml index 4fbc8a9a0f8..e00a5475b1b 100644 --- a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb.yaml +++ b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 1024 +vendor: nxp diff --git a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_2cores.yaml b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_2cores.yaml index 51ceb492ead..93e56887e22 100644 --- a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_2cores.yaml +++ b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_2cores.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 1024 +vendor: nxp diff --git a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_4cores.yaml b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_4cores.yaml index bdda428e8fa..c74af99c1be 100644 --- a/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_4cores.yaml +++ b/boards/arm64/nxp_ls1046ardb/nxp_ls1046ardb_smp_4cores.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 1024 +vendor: nxp diff --git a/boards/arm64/phycore_am62x_a53/phycore_am62x_a53.yaml b/boards/arm64/phycore_am62x_a53/phycore_am62x_a53.yaml index f9b8854bc5c..fe65e6b4a36 100644 --- a/boards/arm64/phycore_am62x_a53/phycore_am62x_a53.yaml +++ b/boards/arm64/phycore_am62x_a53/phycore_am62x_a53.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: ti diff --git a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53.yaml b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53.yaml index ee4b31be15e..b447db17f67 100644 --- a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53.yaml +++ b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_smp.yaml b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_smp.yaml index 17b451074ce..9a6e87c0a70 100644 --- a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_smp.yaml +++ b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_smp.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_xip.yaml b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_xip.yaml index 04a92840c6d..5654908d3d2 100644 --- a/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_xip.yaml +++ b/boards/arm64/qemu_cortex_a53/qemu_cortex_a53_xip.yaml @@ -11,3 +11,4 @@ testing: default: true only_tags: - xip +vendor: qemu diff --git a/boards/arm64/qemu_kvm_arm64/qemu_kvm_arm64.yaml b/boards/arm64/qemu_kvm_arm64/qemu_kvm_arm64.yaml index 93135232eb6..3dd2e974d0d 100644 --- a/boards/arm64/qemu_kvm_arm64/qemu_kvm_arm64.yaml +++ b/boards/arm64/qemu_kvm_arm64/qemu_kvm_arm64.yaml @@ -10,3 +10,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/arm64/rcar_h3ulcb_ca57/rcar_h3ulcb_ca57.yaml b/boards/arm64/rcar_h3ulcb_ca57/rcar_h3ulcb_ca57.yaml index 25616679c3d..e34235c2d43 100644 --- a/boards/arm64/rcar_h3ulcb_ca57/rcar_h3ulcb_ca57.yaml +++ b/boards/arm64/rcar_h3ulcb_ca57/rcar_h3ulcb_ca57.yaml @@ -14,3 +14,4 @@ testing: - net - bluetooth - isotp +vendor: renesas diff --git a/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml b/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml index 80903847d59..84d4a864a35 100644 --- a/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml +++ b/boards/arm64/rcar_salvator_xs_m3/rcar_salvator_xs_m3.yaml @@ -14,3 +14,4 @@ testing: - net - bluetooth - isotp +vendor: renesas diff --git a/boards/arm64/xenvm/xenvm.yaml b/boards/arm64/xenvm/xenvm.yaml index 13fcc815424..2cd38e3c399 100644 --- a/boards/arm64/xenvm/xenvm.yaml +++ b/boards/arm64/xenvm/xenvm.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 16384 +vendor: xen diff --git a/boards/arm64/xenvm/xenvm_gicv3.yaml b/boards/arm64/xenvm/xenvm_gicv3.yaml index 8bcd02c03ff..91026d183d2 100644 --- a/boards/arm64/xenvm/xenvm_gicv3.yaml +++ b/boards/arm64/xenvm/xenvm_gicv3.yaml @@ -6,3 +6,4 @@ toolchain: - zephyr - cross-compile ram: 16384 +vendor: xen diff --git a/boards/mips/qemu_malta/qemu_malta.yaml b/boards/mips/qemu_malta/qemu_malta.yaml index adc81837ff2..3749da567ea 100644 --- a/boards/mips/qemu_malta/qemu_malta.yaml +++ b/boards/mips/qemu_malta/qemu_malta.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/mips/qemu_malta/qemu_malta_be.yaml b/boards/mips/qemu_malta/qemu_malta_be.yaml index 97de3fe1e70..80eab182050 100644 --- a/boards/mips/qemu_malta/qemu_malta_be.yaml +++ b/boards/mips/qemu_malta/qemu_malta_be.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/nios2/altera_max10/altera_max10.yaml b/boards/nios2/altera_max10/altera_max10.yaml index a59497a4509..eb068f21f47 100644 --- a/boards/nios2/altera_max10/altera_max10.yaml +++ b/boards/nios2/altera_max10/altera_max10.yaml @@ -4,3 +4,4 @@ type: mcu arch: nios2 toolchain: - zephyr +vendor: altr diff --git a/boards/nios2/qemu_nios2/qemu_nios2.yaml b/boards/nios2/qemu_nios2/qemu_nios2.yaml index d491aa236ae..6f170873486 100644 --- a/boards/nios2/qemu_nios2/qemu_nios2.yaml +++ b/boards/nios2/qemu_nios2/qemu_nios2.yaml @@ -13,3 +13,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/posix/native_posix/native_posix.yaml b/boards/posix/native_posix/native_posix.yaml index b74534f1eca..7d10c080474 100644 --- a/boards/posix/native_posix/native_posix.yaml +++ b/boards/posix/native_posix/native_posix.yaml @@ -20,3 +20,4 @@ supported: - rtc testing: default: true +vendor: zephyr diff --git a/boards/posix/native_posix/native_posix_64.yaml b/boards/posix/native_posix/native_posix_64.yaml index b503ff2241b..62d3b168497 100644 --- a/boards/posix/native_posix/native_posix_64.yaml +++ b/boards/posix/native_posix/native_posix_64.yaml @@ -16,3 +16,4 @@ supported: - adc - gpio - rtc +vendor: zephyr diff --git a/boards/posix/native_sim/native_sim.yaml b/boards/posix/native_sim/native_sim.yaml index 327cf2f6049..daa76cdab92 100644 --- a/boards/posix/native_sim/native_sim.yaml +++ b/boards/posix/native_sim/native_sim.yaml @@ -18,3 +18,4 @@ supported: - spi - gpio - rtc +vendor: zephyr diff --git a/boards/posix/native_sim/native_sim_64.yaml b/boards/posix/native_sim/native_sim_64.yaml index c2c8b3ac530..487f623894d 100644 --- a/boards/posix/native_sim/native_sim_64.yaml +++ b/boards/posix/native_sim/native_sim_64.yaml @@ -16,3 +16,4 @@ supported: - adc - gpio - rtc +vendor: zephyr diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml index b7e792cac8a..6d5233e3cd8 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml @@ -18,3 +18,4 @@ supported: testing: ignore_tags: - bluetooth +vendor: andestech diff --git a/boards/riscv/esp32c3_devkitm/esp32c3_devkitm.yaml b/boards/riscv/esp32c3_devkitm/esp32c3_devkitm.yaml index 552255dee0a..d52d2bd30eb 100644 --- a/boards/riscv/esp32c3_devkitm/esp32c3_devkitm.yaml +++ b/boards/riscv/esp32c3_devkitm/esp32c3_devkitm.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml index da27504e274..6b5641273e2 100644 --- a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml index 5e5b13c76cf..81acd4d0bb3 100644 --- a/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml +++ b/boards/riscv/esp32c3_luatos_core/esp32c3_luatos_core_usb.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml b/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml index 67027110d15..546e54d2cd1 100644 --- a/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml +++ b/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml @@ -16,3 +16,4 @@ supported: - watchdog - dma - spi +vendor: gd diff --git a/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml b/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml index 27696651e4d..306d3e11498 100644 --- a/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml +++ b/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml @@ -16,3 +16,4 @@ supported: - watchdog - dma - spi +vendor: gd diff --git a/boards/riscv/hifive1/hifive1.yaml b/boards/riscv/hifive1/hifive1.yaml index 1e716ed5de9..d2a8280bc2d 100644 --- a/boards/riscv/hifive1/hifive1.yaml +++ b/boards/riscv/hifive1/hifive1.yaml @@ -19,3 +19,4 @@ testing: - bluetooth - flash - newlib +vendor: sifive diff --git a/boards/riscv/hifive1_revb/hifive1_revb.yaml b/boards/riscv/hifive1_revb/hifive1_revb.yaml index 1de32bb61fd..8b3576b1fc7 100644 --- a/boards/riscv/hifive1_revb/hifive1_revb.yaml +++ b/boards/riscv/hifive1_revb/hifive1_revb.yaml @@ -14,3 +14,4 @@ supported: - arduino_i2c - gpio - i2c +vendor: sifive diff --git a/boards/riscv/hifive_unleashed/hifive_unleashed.yaml b/boards/riscv/hifive_unleashed/hifive_unleashed.yaml index 072677cc45e..9600aa0218d 100644 --- a/boards/riscv/hifive_unleashed/hifive_unleashed.yaml +++ b/boards/riscv/hifive_unleashed/hifive_unleashed.yaml @@ -17,3 +17,4 @@ testing: supported: - gpio - spi +vendor: sifive diff --git a/boards/riscv/hifive_unmatched/hifive_unmatched.yaml b/boards/riscv/hifive_unmatched/hifive_unmatched.yaml index e054abf43c6..8b62698b61b 100644 --- a/boards/riscv/hifive_unmatched/hifive_unmatched.yaml +++ b/boards/riscv/hifive_unmatched/hifive_unmatched.yaml @@ -12,3 +12,4 @@ testing: supported: - spi - memc +vendor: sifive diff --git a/boards/riscv/icev_wireless/icev_wireless.yaml b/boards/riscv/icev_wireless/icev_wireless.yaml index 9321db80125..cf87f3f1165 100644 --- a/boards/riscv/icev_wireless/icev_wireless.yaml +++ b/boards/riscv/icev_wireless/icev_wireless.yaml @@ -8,3 +8,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.yaml b/boards/riscv/it82xx2_evb/it82xx2_evb.yaml index 45eb44557a4..b38957ccf4d 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb.yaml +++ b/boards/riscv/it82xx2_evb/it82xx2_evb.yaml @@ -21,3 +21,4 @@ supported: - tach - uart - watchdog +vendor: ite diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.yaml b/boards/riscv/it8xxx2_evb/it8xxx2_evb.yaml index 79824947db1..3374ea96c32 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.yaml +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.yaml @@ -16,3 +16,4 @@ supported: - kscan - pwm - watchdog +vendor: ite diff --git a/boards/riscv/litex_vexriscv/litex_vexriscv.yaml b/boards/riscv/litex_vexriscv/litex_vexriscv.yaml index d3dbcec17d8..1c4a6ef664e 100644 --- a/boards/riscv/litex_vexriscv/litex_vexriscv.yaml +++ b/boards/riscv/litex_vexriscv/litex_vexriscv.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - bluetooth - xip +vendor: litex diff --git a/boards/riscv/longan_nano/longan_nano.yaml b/boards/riscv/longan_nano/longan_nano.yaml index 3af7c9efa6f..bf89492aabc 100644 --- a/boards/riscv/longan_nano/longan_nano.yaml +++ b/boards/riscv/longan_nano/longan_nano.yaml @@ -11,3 +11,4 @@ supported: - watchdog - dma - spi +vendor: sipeed diff --git a/boards/riscv/longan_nano/longan_nano_lite.yaml b/boards/riscv/longan_nano/longan_nano_lite.yaml index 1ef7ddfb177..71cbb12c3f3 100644 --- a/boards/riscv/longan_nano/longan_nano_lite.yaml +++ b/boards/riscv/longan_nano/longan_nano_lite.yaml @@ -11,3 +11,4 @@ supported: - watchdog - dma - spi +vendor: sipeed diff --git a/boards/riscv/m2gl025_miv/m2gl025_miv.yaml b/boards/riscv/m2gl025_miv/m2gl025_miv.yaml index 283269bb32e..658ede0e9f5 100644 --- a/boards/riscv/m2gl025_miv/m2gl025_miv.yaml +++ b/boards/riscv/m2gl025_miv/m2gl025_miv.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: microchip diff --git a/boards/riscv/mpfs_icicle/mpfs_icicle.yaml b/boards/riscv/mpfs_icicle/mpfs_icicle.yaml index 0623d31795e..239d10e1ebc 100644 --- a/boards/riscv/mpfs_icicle/mpfs_icicle.yaml +++ b/boards/riscv/mpfs_icicle/mpfs_icicle.yaml @@ -9,3 +9,4 @@ testing: ignore_tags: - net - bluetooth +vendor: microchip diff --git a/boards/riscv/niosv_g/niosv_g.yaml b/boards/riscv/niosv_g/niosv_g.yaml index e88c658cd18..408b83df9eb 100644 --- a/boards/riscv/niosv_g/niosv_g.yaml +++ b/boards/riscv/niosv_g/niosv_g.yaml @@ -5,3 +5,4 @@ arch: riscv32 toolchain: - zephyr ram: 256 +vendor: intel diff --git a/boards/riscv/niosv_m/niosv_m.yaml b/boards/riscv/niosv_m/niosv_m.yaml index c1333752a68..fee0aa30a69 100644 --- a/boards/riscv/niosv_m/niosv_m.yaml +++ b/boards/riscv/niosv_m/niosv_m.yaml @@ -5,3 +5,4 @@ arch: riscv32 toolchain: - zephyr ram: 256 +vendor: intel diff --git a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey.yaml b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey.yaml index 0f01dc5748b..a66cb6d4384 100644 --- a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey.yaml +++ b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey.yaml @@ -11,3 +11,4 @@ testing: - bluetooth supported: - watchdog +vendor: lowrisc diff --git a/boards/riscv/rv32m1_vega/rv32m1_vega_ri5cy.yaml b/boards/riscv/rv32m1_vega/rv32m1_vega_ri5cy.yaml index f350b82691f..334582e31c3 100644 --- a/boards/riscv/rv32m1_vega/rv32m1_vega_ri5cy.yaml +++ b/boards/riscv/rv32m1_vega/rv32m1_vega_ri5cy.yaml @@ -12,3 +12,4 @@ supported: - i2c - pwm - spi +vendor: openisa diff --git a/boards/riscv/rv32m1_vega/rv32m1_vega_zero_riscy.yaml b/boards/riscv/rv32m1_vega/rv32m1_vega_zero_riscy.yaml index cd64714625f..9afb8da41f6 100644 --- a/boards/riscv/rv32m1_vega/rv32m1_vega_zero_riscy.yaml +++ b/boards/riscv/rv32m1_vega/rv32m1_vega_zero_riscy.yaml @@ -10,3 +10,4 @@ supported: - arduino_i2c - i2c - pwm +vendor: openisa diff --git a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus.yaml b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus.yaml index 33b56514443..f25cf16f093 100644 --- a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus.yaml +++ b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus.yaml @@ -16,3 +16,4 @@ supported: - spi - pwm - watchdog +vendor: sparkfun diff --git a/boards/riscv/stamp_c3/stamp_c3.yaml b/boards/riscv/stamp_c3/stamp_c3.yaml index b73d85c982b..9e43f10401d 100644 --- a/boards/riscv/stamp_c3/stamp_c3.yaml +++ b/boards/riscv/stamp_c3/stamp_c3.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: m5stack diff --git a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225.yaml b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225.yaml index b52f6d8660a..7ed90e8447e 100644 --- a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225.yaml +++ b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225.yaml @@ -8,3 +8,4 @@ ram: 196608 supported: - gpio - uart +vendor: efinix diff --git a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d.yaml b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d.yaml index dd2bd76f585..c1879da43e4 100644 --- a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d.yaml +++ b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d.yaml @@ -13,3 +13,4 @@ supported: - pwm - spi - netif:openthread +vendor: telink diff --git a/boards/riscv/xiao_esp32c3/xiao_esp32c3.yaml b/boards/riscv/xiao_esp32c3/xiao_esp32c3.yaml index 6a34ba08bc6..ce2a47ec982 100644 --- a/boards/riscv/xiao_esp32c3/xiao_esp32c3.yaml +++ b/boards/riscv/xiao_esp32c3/xiao_esp32c3.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: seeed diff --git a/boards/sparc/generic_leon3/generic_leon3.yaml b/boards/sparc/generic_leon3/generic_leon3.yaml index a59d7b93854..7f16d2f25d5 100644 --- a/boards/sparc/generic_leon3/generic_leon3.yaml +++ b/boards/sparc/generic_leon3/generic_leon3.yaml @@ -11,3 +11,4 @@ toolchain: - xtools supported: - netif +vendor: gaisler diff --git a/boards/sparc/gr716a_mini/gr716a_mini.yaml b/boards/sparc/gr716a_mini/gr716a_mini.yaml index c8ddfc1720e..09e39864a62 100644 --- a/boards/sparc/gr716a_mini/gr716a_mini.yaml +++ b/boards/sparc/gr716a_mini/gr716a_mini.yaml @@ -9,3 +9,4 @@ toolchain: - xtools supported: - netif +vendor: gaisler diff --git a/boards/x86/intel_adl/intel_adl_crb.yaml b/boards/x86/intel_adl/intel_adl_crb.yaml index d567fee4242..58810300c16 100644 --- a/boards/x86/intel_adl/intel_adl_crb.yaml +++ b/boards/x86/intel_adl/intel_adl_crb.yaml @@ -17,3 +17,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_adl/intel_adl_rvp.yaml b/boards/x86/intel_adl/intel_adl_rvp.yaml index 7c5e2c62578..a93e5eea549 100644 --- a/boards/x86/intel_adl/intel_adl_rvp.yaml +++ b/boards/x86/intel_adl/intel_adl_rvp.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_ehl/intel_ehl_crb.yaml b/boards/x86/intel_ehl/intel_ehl_crb.yaml index 6b1d11e1a52..7b0cddebc15 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb.yaml +++ b/boards/x86/intel_ehl/intel_ehl_crb.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_ehl/intel_ehl_crb_sbl.yaml b/boards/x86/intel_ehl/intel_ehl_crb_sbl.yaml index 734aac58fe8..52cfa670ae6 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb_sbl.yaml +++ b/boards/x86/intel_ehl/intel_ehl_crb_sbl.yaml @@ -9,3 +9,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_ish/intel_ish_5_4_1.yaml b/boards/x86/intel_ish/intel_ish_5_4_1.yaml index a04b3c0e5d0..2894e667001 100644 --- a/boards/x86/intel_ish/intel_ish_5_4_1.yaml +++ b/boards/x86/intel_ish/intel_ish_5_4_1.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_ish/intel_ish_5_6_0.yaml b/boards/x86/intel_ish/intel_ish_5_6_0.yaml index 42044c0d14c..904c09cba45 100644 --- a/boards/x86/intel_ish/intel_ish_5_6_0.yaml +++ b/boards/x86/intel_ish/intel_ish_5_6_0.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_ish/intel_ish_5_8_0.yaml b/boards/x86/intel_ish/intel_ish_5_8_0.yaml index e750d236d06..09dd57f5e30 100644 --- a/boards/x86/intel_ish/intel_ish_5_8_0.yaml +++ b/boards/x86/intel_ish/intel_ish_5_8_0.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/intel_rpl/intel_rpl_s_crb.yaml b/boards/x86/intel_rpl/intel_rpl_s_crb.yaml index ad4c413cdeb..ca0be3de697 100644 --- a/boards/x86/intel_rpl/intel_rpl_s_crb.yaml +++ b/boards/x86/intel_rpl/intel_rpl_s_crb.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/x86/qemu_x86/qemu_x86.yaml b/boards/x86/qemu_x86/qemu_x86.yaml index bb662c7c93b..ae8bd13f9ca 100644 --- a/boards/x86/qemu_x86/qemu_x86.yaml +++ b/boards/x86/qemu_x86/qemu_x86.yaml @@ -17,3 +17,4 @@ supported: - rtc testing: default: true +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_64.yaml b/boards/x86/qemu_x86/qemu_x86_64.yaml index d4c8787f2e5..afa50057b6a 100644 --- a/boards/x86/qemu_x86/qemu_x86_64.yaml +++ b/boards/x86/qemu_x86/qemu_x86_64.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - net - bluetooth +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml b/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml index 7b440601625..531ebd4d3e1 100644 --- a/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml +++ b/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml @@ -15,3 +15,4 @@ testing: - userspace ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_lakemont.yaml b/boards/x86/qemu_x86/qemu_x86_lakemont.yaml index 447b6b86664..1f1d7bb83c9 100644 --- a/boards/x86/qemu_x86/qemu_x86_lakemont.yaml +++ b/boards/x86/qemu_x86/qemu_x86_lakemont.yaml @@ -13,3 +13,4 @@ testing: - kernel ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_nokpti.yaml b/boards/x86/qemu_x86/qemu_x86_nokpti.yaml index 7e483a9d77b..75ab0d13d5f 100644 --- a/boards/x86/qemu_x86/qemu_x86_nokpti.yaml +++ b/boards/x86/qemu_x86/qemu_x86_nokpti.yaml @@ -13,3 +13,4 @@ testing: - userspace ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_nommu.yaml b/boards/x86/qemu_x86/qemu_x86_nommu.yaml index a2874f08135..8d7aee97b7e 100644 --- a/boards/x86/qemu_x86/qemu_x86_nommu.yaml +++ b/boards/x86/qemu_x86/qemu_x86_nommu.yaml @@ -11,3 +11,4 @@ testing: only_tags: - kernel - userspace +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_nopae.yaml b/boards/x86/qemu_x86/qemu_x86_nopae.yaml index a4e3256b245..7dbd449cebc 100644 --- a/boards/x86/qemu_x86/qemu_x86_nopae.yaml +++ b/boards/x86/qemu_x86/qemu_x86_nopae.yaml @@ -13,3 +13,4 @@ testing: - userspace ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_tiny.yaml b/boards/x86/qemu_x86/qemu_x86_tiny.yaml index d8c9606cff7..8807d57d8d0 100644 --- a/boards/x86/qemu_x86/qemu_x86_tiny.yaml +++ b/boards/x86/qemu_x86/qemu_x86_tiny.yaml @@ -13,3 +13,4 @@ testing: - userspace ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_virt.yaml b/boards/x86/qemu_x86/qemu_x86_virt.yaml index c80052a158c..1f3eb2fb18b 100644 --- a/boards/x86/qemu_x86/qemu_x86_virt.yaml +++ b/boards/x86/qemu_x86/qemu_x86_virt.yaml @@ -13,3 +13,4 @@ testing: - userspace ignore_tags: - benchmark +vendor: qemu diff --git a/boards/x86/qemu_x86/qemu_x86_xip.yaml b/boards/x86/qemu_x86/qemu_x86_xip.yaml index 6b08ba3afe7..c33acd4db16 100644 --- a/boards/x86/qemu_x86/qemu_x86_xip.yaml +++ b/boards/x86/qemu_x86/qemu_x86_xip.yaml @@ -10,3 +10,4 @@ testing: default: true only_tags: - xip +vendor: qemu diff --git a/boards/xtensa/esp32_devkitc_wroom/esp32_devkitc_wroom.yaml b/boards/xtensa/esp32_devkitc_wroom/esp32_devkitc_wroom.yaml index 4a937b09491..0481a96df00 100644 --- a/boards/xtensa/esp32_devkitc_wroom/esp32_devkitc_wroom.yaml +++ b/boards/xtensa/esp32_devkitc_wroom/esp32_devkitc_wroom.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32_devkitc_wrover/esp32_devkitc_wrover.yaml b/boards/xtensa/esp32_devkitc_wrover/esp32_devkitc_wrover.yaml index 3680afba27a..7ae68f8e9de 100644 --- a/boards/xtensa/esp32_devkitc_wrover/esp32_devkitc_wrover.yaml +++ b/boards/xtensa/esp32_devkitc_wrover/esp32_devkitc_wrover.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.yaml b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.yaml index e80b9a07a64..8f1167e1fac 100644 --- a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.yaml +++ b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32_net/esp32_net.yaml b/boards/xtensa/esp32_net/esp32_net.yaml index 0c4d3aa470f..14739928f62 100644 --- a/boards/xtensa/esp32_net/esp32_net.yaml +++ b/boards/xtensa/esp32_net/esp32_net.yaml @@ -19,3 +19,4 @@ testing: - logging - kernel - pm +vendor: espressif diff --git a/boards/xtensa/esp32s2_franzininho/esp32s2_franzininho.yaml b/boards/xtensa/esp32s2_franzininho/esp32s2_franzininho.yaml index 87fb655e204..9cc2a260342 100644 --- a/boards/xtensa/esp32s2_franzininho/esp32s2_franzininho.yaml +++ b/boards/xtensa/esp32s2_franzininho/esp32s2_franzininho.yaml @@ -16,3 +16,4 @@ testing: - heap - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32s2_saola/esp32s2_saola.yaml b/boards/xtensa/esp32s2_saola/esp32s2_saola.yaml index 77ea683f54b..261d7d0eb8f 100644 --- a/boards/xtensa/esp32s2_saola/esp32s2_saola.yaml +++ b/boards/xtensa/esp32s2_saola/esp32s2_saola.yaml @@ -20,3 +20,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm.yaml b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm.yaml index b44b2ec9357..160e01f4d6e 100644 --- a/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm.yaml +++ b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core.yaml b/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core.yaml index d6548d80c98..eb850a58f95 100644 --- a/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core.yaml +++ b/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core_usb.yaml b/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core_usb.yaml index c8346274c09..a8680bb6544 100644 --- a/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core_usb.yaml +++ b/boards/xtensa/esp32s3_luatos_core/esp32s3_luatos_core_usb.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/esp_wrover_kit/esp_wrover_kit.yaml b/boards/xtensa/esp_wrover_kit/esp_wrover_kit.yaml index 0d92719606e..3d1b9921904 100644 --- a/boards/xtensa/esp_wrover_kit/esp_wrover_kit.yaml +++ b/boards/xtensa/esp_wrover_kit/esp_wrover_kit.yaml @@ -20,3 +20,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2.yaml b/boards/xtensa/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2.yaml index 05a5445554d..740755b5e6a 100644 --- a/boards/xtensa/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2.yaml +++ b/boards/xtensa/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2.yaml @@ -14,3 +14,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.yaml b/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.yaml index de626d6a1fe..9493e4c08da 100644 --- a/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.yaml +++ b/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.yaml b/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.yaml index 9d9c3277d2c..693f3ad2ce6 100644 --- a/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.yaml +++ b/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.yaml @@ -13,3 +13,4 @@ testing: - net - bluetooth - mcumgr +vendor: intel diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml index 590e408a26a..8d175cbc621 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml @@ -12,3 +12,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.yaml b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.yaml index 644e4f497a8..f11256de9bf 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.yaml +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: intel diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.yaml b/boards/xtensa/m5stack_core2/m5stack_core2.yaml index 1ee36021b39..bb929e2abc0 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.yaml +++ b/boards/xtensa/m5stack_core2/m5stack_core2.yaml @@ -18,3 +18,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml b/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml index d648d4119e4..dbd09151be1 100644 --- a/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml +++ b/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml @@ -16,3 +16,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/boards/xtensa/odroid_go/odroid_go.yaml b/boards/xtensa/odroid_go/odroid_go.yaml index 5cbf1bb0d49..8a487018654 100644 --- a/boards/xtensa/odroid_go/odroid_go.yaml +++ b/boards/xtensa/odroid_go/odroid_go.yaml @@ -15,3 +15,4 @@ testing: ignore_tags: - net - bluetooth +vendor: hardkernel diff --git a/boards/xtensa/olimex_esp32_evb/olimex_esp32_evb.yaml b/boards/xtensa/olimex_esp32_evb/olimex_esp32_evb.yaml index 7240bdcf89a..83320db1529 100644 --- a/boards/xtensa/olimex_esp32_evb/olimex_esp32_evb.yaml +++ b/boards/xtensa/olimex_esp32_evb/olimex_esp32_evb.yaml @@ -17,3 +17,4 @@ testing: ignore_tags: - net - bluetooth +vendor: olimex diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa.yaml b/boards/xtensa/qemu_xtensa/qemu_xtensa.yaml index 7bd4c605ed6..1190d0d3f8e 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa.yaml +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa.yaml @@ -11,3 +11,4 @@ testing: ignore_tags: - net - bluetooth +vendor: cdns diff --git a/boards/xtensa/xiao_esp32s3/xiao_esp32s3.yaml b/boards/xtensa/xiao_esp32s3/xiao_esp32s3.yaml index c5d8fec4b14..59ddcaec1e1 100644 --- a/boards/xtensa/xiao_esp32s3/xiao_esp32s3.yaml +++ b/boards/xtensa/xiao_esp32s3/xiao_esp32s3.yaml @@ -19,3 +19,4 @@ testing: ignore_tags: - net - bluetooth +vendor: seeed diff --git a/boards/xtensa/yd_esp32/yd_esp32.yaml b/boards/xtensa/yd_esp32/yd_esp32.yaml index 99f149df488..2a73436066b 100644 --- a/boards/xtensa/yd_esp32/yd_esp32.yaml +++ b/boards/xtensa/yd_esp32/yd_esp32.yaml @@ -21,3 +21,4 @@ testing: ignore_tags: - net - bluetooth +vendor: espressif diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index bbe86c6fc64..b6a590b752a 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -667,6 +667,7 @@ def apply_filters(self, **kwargs): platforms = list(filter(lambda p: p.simulation != 'na', self.platforms)) elif vendor_filter: platforms = list(filter(lambda p: p.vendor in vendor_filter, self.platforms)) + logger.info(f"Selecting platforms by vendors: {','.join(vendor_filter)}") elif arch_filter: platforms = list(filter(lambda p: p.arch in arch_filter, self.platforms)) elif default_platforms: From e560bd6b8cf48c7f1b81551357fb2cc8dc890181 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 23 Jun 2023 10:25:55 +0000 Subject: [PATCH 0861/4498] boards: intel_adsp: fix board compatible compatible was missing the hardware information. Signed-off-by: Anas Nashif --- boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.dts | 2 +- boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.dts | 2 +- boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts | 2 +- boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.dts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.dts b/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.dts index f4a88d99252..cc0fc9d0803 100644 --- a/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.dts +++ b/boards/xtensa/intel_adsp_ace15_mtpm/intel_adsp_ace15_mtpm.dts @@ -10,7 +10,7 @@ / { model = "intel_adsp_ace15_mtpm"; - compatible = "intel"; + compatible = "intel,intel_adsp_ace20_lnl"; aliases { dma0 = &lpgpdma0; diff --git a/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.dts b/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.dts index 0a68f186424..6df8089a508 100644 --- a/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.dts +++ b/boards/xtensa/intel_adsp_ace20_lnl/intel_adsp_ace20_lnl.dts @@ -10,7 +10,7 @@ / { model = "intel_adsp_ace20_lnl"; - compatible = "intel"; + compatible = "intel,intel_adsp_ace20_lnl"; chosen { zephyr,sram = &sram0; diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts index 52a0ea3c8c5..ac7a8c058aa 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts @@ -10,7 +10,7 @@ / { model = "intel_adsp_cavs25"; - compatible = "intel"; + compatible = "intel,intel_adsp_cavs25"; aliases { dma0 = &lpgpdma0; diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.dts b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.dts index cadd7de32c1..5b916c9ee3a 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.dts +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_tgph.dts @@ -10,7 +10,7 @@ / { model = "intel_adsp_cavs25_tgph"; - compatible = "intel"; + compatible = "intel,intel_adsp_cavs25_tgph"; aliases { dma0 = &lpgpdma0; From 7d2c91aa7ecc0fb25119054313ce8f00cd908876 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 23 Jun 2023 10:27:43 +0000 Subject: [PATCH 0862/4498] boards: lpcxpresso11u68: add vendor to compatible Add nxp as the vendor in the compatible. Signed-off-by: Anas Nashif --- boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts index 680b662e0c4..22e2e9f97f5 100644 --- a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts +++ b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts @@ -13,7 +13,7 @@ / { model = "NXP LPCXPRESSO11U68 board"; - compatible = "lpcxpresso11u68", "nxp,lpc"; + compatible = "nxp,lpcxpresso11u68", "nxp,lpc"; chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; From 08cf158926d4b4de38535725d75bf3de04cfe52a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 23 Jun 2023 10:29:17 +0000 Subject: [PATCH 0863/4498] boards: laird BLXX: fix vendor in compatible Fix vendor in compatible and match vendor database. Signed-off-by: Anas Nashif --- boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.dts | 2 +- boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.dts | 2 +- boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.dts b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.dts index 12528e19bb7..6052502552e 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.dts +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp.dts @@ -10,7 +10,7 @@ / { model = "Laird Connectivity BL5340 (nRF5340) Application"; - compatible = "lairdconnectivity,bl5340-dvk-cpuapp"; + compatible = "lairdconnect,bl5340-dvk-cpuapp"; chosen { zephyr,sram = &sram0_image; diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.dts b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.dts index cfa5b763241..b943c5bdfbf 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.dts +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_ns.dts @@ -10,7 +10,7 @@ / { model = "Laird Connectivity BL5340 (nRF5340) Application"; - compatible = "lairdconnectivity,bl5340-dvk-cpuapp"; + compatible = "lairdconnect,bl5340-dvk-cpuapp"; chosen { zephyr,sram = &sram0_ns; diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts index 0cacac7cd62..7e6b6022e7a 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts @@ -11,7 +11,7 @@ / { model = "Laird Connectivity BL5340 (nRF5340) Network"; - compatible = "lairdconnectivity,bl5340-dvk-cpunet"; + compatible = "lairdconnect,bl5340-dvk-cpunet"; chosen { zephyr,console = &uart0; From 9a0e8325f91c62b0d366d4b5c8fc1655bec84b95 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 23 Jun 2023 10:29:54 +0000 Subject: [PATCH 0864/4498] boards: cypress cy8xx: fix vendor in compatible Fix vendor in compatible and match vendor database. Signed-off-by: Anas Nashif --- boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts | 2 +- boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts | 2 +- boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts | 2 +- boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts index 6496dcca734..fff6d89ea5d 100644 --- a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts @@ -12,7 +12,7 @@ / { model = "cy8ckit_062_wifi_bt_m0 with a Cypress PSoC6 SoC"; - compatible = "cy8ckit_062_wifi_bt_m0", "PSoC6"; + compatible = "cypress,cy8ckit_062_wifi_bt_m0", "cypress,PSoC6"; aliases { sw0 = &user_bt; diff --git a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts index 1dfb48fcbeb..e192f94580d 100644 --- a/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts @@ -10,7 +10,7 @@ / { model = "cy8ckit_062_wifi_bt_m4 with a Cypress PSoC6 SoC"; - compatible = "cy8ckit_062_wifi_bt_m4", "PSoC6"; + compatible = "cypress,cy8ckit_062_wifi_bt_m4", "cypress,PSoC6"; aliases { uart-5 = &uart5; diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 5ad82d742a6..4d9149b198a 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -11,7 +11,7 @@ / { model = "cy8cproto_062_4343w with an Cypress PSoC™ 6 SoC"; - compatible = "cy8cproto_062_4343w", "PSoC6"; + compatible = "cypress,cy8cproto_062_4343w", "cypress,PSoC6"; aliases { uart-5 = &uart5; diff --git a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts index 228fdeae613..e918f547bd2 100644 --- a/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts +++ b/boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts @@ -13,7 +13,7 @@ / { model = "CY8CPROTO-063-BLE PSoC™ 6 BLE Prototyping Kit"; - compatible = "cy8cproto_063_ble", "PSoC6"; + compatible = "cypress,cy8cproto_063_ble", "cypress,PSoC6"; aliases { uart-5 = &uart5; From 2857f781b41d96b07314eccc946fec0cb3b11976 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 23 Jun 2023 10:30:17 +0000 Subject: [PATCH 0865/4498] boards: atmel atsamr34: fix vendor in compatible Fix vendor in compatible and match vendor database. Signed-off-by: Anas Nashif --- boards/arm/atsamr34_xpro/atsamr34_xpro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/atsamr34_xpro/atsamr34_xpro.dts b/boards/arm/atsamr34_xpro/atsamr34_xpro.dts index 3e3abee6b2e..aba04a1b3e6 100644 --- a/boards/arm/atsamr34_xpro/atsamr34_xpro.dts +++ b/boards/arm/atsamr34_xpro/atsamr34_xpro.dts @@ -11,7 +11,7 @@ / { model = "SAM R34 Xplained Pro"; - compatible = "atsamr34,xpro", "atmel,samr34j18b", "atmel,samr34"; + compatible = "atmel,atsamr34xpro", "atmel,samr34j18b", "atmel,samr34"; chosen { zephyr,console = &sercom0; From bf830ba780b8a76bf8962857b72b551c41f628ee Mon Sep 17 00:00:00 2001 From: Brunon Blok Date: Fri, 11 Aug 2023 16:03:03 +0200 Subject: [PATCH 0866/4498] drivers: input: add driver for stmpe811 i2c touch controller This commit adds STMPE811 I2C touch controller driver. Signed-off-by: Brunon Blok Signed-off-by: Mateusz Sierszulski --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.stmpe811 | 10 + drivers/input/input_stmpe811.c | 548 ++++++++++++++++++++++ dts/bindings/input/st,stmpe811.yaml | 127 +++++ tests/drivers/build_all/input/app.overlay | 10 + 6 files changed, 697 insertions(+) create mode 100644 drivers/input/Kconfig.stmpe811 create mode 100644 drivers/input/input_stmpe811.c create mode 100644 dts/bindings/input/st,stmpe811.yaml diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 51b25155911..683a3de9f12 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KEYS input_gpio_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_QDEC input_gpio_qdec.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GT911 input_gt911.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c) if (CONFIG_INPUT_SDL_TOUCH) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 3aa5271bf4e..0e33eef6607 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -13,6 +13,7 @@ source "drivers/input/Kconfig.gpio_qdec" source "drivers/input/Kconfig.gt911" source "drivers/input/Kconfig.npcx" source "drivers/input/Kconfig.sdl" +source "drivers/input/Kconfig.stmpe811" source "drivers/input/Kconfig.xpt2046" endmenu # Input Drivers diff --git a/drivers/input/Kconfig.stmpe811 b/drivers/input/Kconfig.stmpe811 new file mode 100644 index 00000000000..08a4307b9fb --- /dev/null +++ b/drivers/input/Kconfig.stmpe811 @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_STMPE811 + bool "STMPE811 touch driver" + default y + depends on DT_HAS_ST_STMPE811_ENABLED + select I2C + help + Enable driver for STMPE811 touch panel. diff --git a/drivers/input/input_stmpe811.c b/drivers/input/input_stmpe811.c new file mode 100644 index 00000000000..38ae921e8d7 --- /dev/null +++ b/drivers/input/input_stmpe811.c @@ -0,0 +1,548 @@ +/** + * Copyright (c) 2023 Antmicro + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT st_stmpe811 + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(stmpe811, CONFIG_INPUT_LOG_LEVEL); + +#define CHIP_ID 0x0811U + +/* Touch Screen Pins definition */ +#define STMPE811_GPIO_PIN_4 BIT(4) +#define STMPE811_GPIO_PIN_5 BIT(5) +#define STMPE811_GPIO_PIN_6 BIT(6) +#define STMPE811_GPIO_PIN_7 BIT(7) + +#define STMPE811_TOUCH_YD STMPE811_GPIO_PIN_7 +#define STMPE811_TOUCH_XD STMPE811_GPIO_PIN_6 +#define STMPE811_TOUCH_YU STMPE811_GPIO_PIN_5 +#define STMPE811_TOUCH_XU STMPE811_GPIO_PIN_4 +#define STMPE811_TOUCH_IO_ALL \ + (STMPE811_TOUCH_YD | STMPE811_TOUCH_XD | STMPE811_TOUCH_YU | STMPE811_TOUCH_XU) + +/* Registers */ +#define STMPE811_CHP_ID_LSB_REG 0x00U +#define STMPE811_ADC_CTRL1_REG 0x20U +#define STMPE811_ADC_CTRL2_REG 0x21U +#define STMPE811_SYS_CTRL1_REG 0x03U +#define STMPE811_SYS_CTRL2_REG 0x04U +#define STMPE811_TSC_CFG_REG 0x41U +#define STMPE811_IO_AF_REG 0x17U +#define STMPE811_FIFO_TH_REG 0x4AU +#define STMPE811_FIFO_STA_REG 0x4BU +#define STMPE811_FIFO_SIZE_REG 0x4CU +#define STMPE811_TSC_FRACT_XYZ_REG 0x56U +#define STMPE811_TSC_I_DRIVE_REG 0x58U +#define STMPE811_TSC_CTRL_REG 0x40U +#define STMPE811_INT_STA_REG 0x0BU +#define STMPE811_TSC_DATA_NON_INC_REG 0xD7U +#define STMPE811_INT_CTRL_REG 0x09U +#define STMPE811_INT_EN_REG 0x0AU + +/* Touch detected bit */ +#define STMPE811_TSC_CTRL_BIT_TOUCH_DET BIT(7) + +/* Global interrupt enable bit */ +#define STMPE811_INT_CTRL_BIT_GLOBAL_INT BIT(0) + +/* IO expander functionalities */ +#define STMPE811_SYS_CTRL2_BIT_ADC_FCT BIT(0) +#define STMPE811_SYS_CTRL2_BIT_TS_FCT BIT(1) +#define STMPE811_SYS_CTRL2_BIT_IO_FCT BIT(2) + +/* Global Interrupts definitions */ +#define STMPE811_INT_BIT_FIFO_THRESHOLD BIT(1) /* FIFO above threshold interrupt */ +#define STMPE811_INT_BIT_TOUCH BIT(0) /* Touch/release is detected interrupt */ +#define STMPE811_INT_ALL BIT_MASK(8) /* All interrupts */ + +/* Reset control */ +#define STMPE811_SYS_CTRL1_RESET_ON 0 +#define STMPE811_SYS_CTRL1_RESET_SOFT BIT(1) /* Soft reset */ + +/* Delays to ensure registers erasing */ +#define STMPE811_RESET_DELAY_MS 10 +#define STMPE811_WAIT_DELAY_MS 2 + +/* Configuration */ +#define STMPE811_FIFO_TH_SINGLE_POINT 1 +#define STMPE811_FIFO_STA_CLEAR 1 +#define STMPE811_FIFO_STA_OPERATIONAL 0 +#define STMPE811_TSC_I_DRIVE_LIMIT 1 + +/** + * Touch Screen Control + * + * - bits [1-3] X, Y only acquisition mode + */ +#define STMPE811_TSC_CTRL_CONF 3U + +/** + * Analog-to-digital Converter + * + * - bit [3] selects 12 bit ADC + * - bits [4-6] select ADC conversion time = 80 + */ +#define STMPE811_ADC_CTRL1_CONF 0x48U + +/** + * ADC clock speed: 3.25 MHz + * + * - 00 : 1.625 MHz + * - 01 : 3.25 MHz + * - 10 : 6.5 MHz + * - 11 : 6.5 MHz + */ +#define STMPE811_ADC_CLOCK_SPEED 1 + +/** + * Range and accuracy of the pressure measurement (Z) + * + * - Fractional part : 7 + * - Whole part : 1 + */ +#define STMPE811_TSC_FRACT_XYZ_CONF 1 + +struct stmpe811_config { + struct i2c_dt_spec bus; + struct gpio_dt_spec int_gpio; + uint8_t panel_driver_settling_time_us; + uint8_t touch_detect_delay_us; + uint8_t touch_average_control; + uint8_t tracking_index; + uint16_t screen_width; + uint16_t screen_height; + int raw_x_min; + int raw_y_min; + uint16_t raw_x_max; + uint16_t raw_y_max; +}; + +struct stmpe811_data { + const struct device *dev; + struct k_work processing_work; + struct gpio_callback int_gpio_cb; + uint32_t touch_x; + uint32_t touch_y; +}; + +static int stmpe811_reset(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + + /* Power down the stmpe811 */ + int ret = i2c_reg_write_byte_dt(&config->bus, STMPE811_SYS_CTRL1_REG, + STMPE811_SYS_CTRL1_RESET_SOFT); + + if (ret < 0) { + return ret; + } + k_msleep(STMPE811_RESET_DELAY_MS); + + /* Power on the stmpe811 after the power off => all registers are reinitialized */ + ret = i2c_reg_write_byte_dt(&config->bus, STMPE811_SYS_CTRL1_REG, + STMPE811_SYS_CTRL1_RESET_ON); + if (ret < 0) { + return ret; + } + k_msleep(STMPE811_WAIT_DELAY_MS); + + return 0; +} + +static int stmpe811_io_enable_af(const struct device *dev, uint32_t io_pin) +{ + const struct stmpe811_config *config = dev->config; + + /* Apply ~io_pin as a mask to the current register value */ + return i2c_reg_update_byte_dt(&config->bus, STMPE811_IO_AF_REG, io_pin, 0); +} + +static uint8_t stmpe811_tsc_config_bits(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + + /** + * Configuration: + * - bits [0-2] : panel driver settling time + * - bits [3-5] : touch detect delay + * - bits [6-7] : touch average control + */ + + return config->panel_driver_settling_time_us | config->touch_detect_delay_us << 3 | + config->touch_average_control << 6; +} + +static uint8_t stmpe811_tsc_control_bits(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + + /** + * Touch Screen Control + * + * - bit [0] enables TSC + * - bits [1-3] X, Y only acquisition mode + * - bits [4-6] window tracking index (set from config) + * - bit [7] TSC status (writing has no effect) + */ + + return STMPE811_TSC_CTRL_CONF | config->tracking_index << 4; +} + +static int stmpe811_ts_init(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + int err; + + err = stmpe811_reset(dev); + if (err < 0) { + return err; + } + + /* Select TSC pins in TSC alternate mode */ + err = stmpe811_io_enable_af(dev, STMPE811_TOUCH_IO_ALL); + if (err < 0) { + return err; + } + + /** + * Set the functionalities to be enabled + * Bits [0-3] disable functionalities if set to 1 (reset value: 0x0f) + * + * Apply inverted sum of chosen FCT bits as a mask to the currect register value + */ + err = i2c_reg_update_byte_dt(&config->bus, STMPE811_SYS_CTRL2_REG, + STMPE811_SYS_CTRL2_BIT_IO_FCT | STMPE811_SYS_CTRL2_BIT_TS_FCT | + STMPE811_SYS_CTRL2_BIT_ADC_FCT, 0); + if (err < 0) { + return err; + } + + /* Select sample time, bit number and ADC reference */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_ADC_CTRL1_REG, STMPE811_ADC_CTRL1_CONF); + if (err < 0) { + return err; + } + + /* Select the ADC clock speed */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_ADC_CTRL2_REG, STMPE811_ADC_CLOCK_SPEED); + if (err < 0) { + return err; + } + + /* Touch screen configuration */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_TSC_CFG_REG, + stmpe811_tsc_config_bits(dev)); + if (err < 0) { + return err; + } + + /* Configure the touch FIFO threshold */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_FIFO_TH_REG, + STMPE811_FIFO_TH_SINGLE_POINT); + if (err < 0) { + return err; + } + + /* Clear the FIFO memory content */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_FIFO_STA_REG, STMPE811_FIFO_STA_CLEAR); + if (err < 0) { + return err; + } + + /* Set the range and accuracy of the pressure measurement (Z) */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_TSC_FRACT_XYZ_REG, + STMPE811_TSC_FRACT_XYZ_CONF); + if (err < 0) { + return err; + } + + /* Set the driving capability (limit) of the device for TSC pins */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_TSC_I_DRIVE_REG, + STMPE811_TSC_I_DRIVE_LIMIT); + if (err < 0) { + return err; + } + + /* Touch screen control configuration */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_TSC_CTRL_REG, + stmpe811_tsc_control_bits(dev)); + if (err < 0) { + return err; + } + + /** + * Clear all the status pending bits if any. + * Writing '1' to this register clears the corresponding bits. + * This is an 8-bit register, so writing 0xFF clears all. + */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_INT_STA_REG, STMPE811_INT_ALL); + if (err < 0) { + return err; + } + + /* Put the FIFO back into operation mode */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_FIFO_STA_REG, + STMPE811_FIFO_STA_OPERATIONAL); + if (err < 0) { + return err; + } + + /* Enable FIFO and touch interrupts */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_INT_EN_REG, + STMPE811_INT_BIT_TOUCH | STMPE811_INT_BIT_FIFO_THRESHOLD); + if (err < 0) { + LOG_ERR("Could not enable interrupt types (%d)", err); + return err; + } + + return 0; +} + +static int stmpe811_ts_get_data(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + struct stmpe811_data *data = dev->data; + + uint8_t data_xy[3]; + uint32_t uldata_xy; + + int ret = i2c_burst_read_dt(&config->bus, STMPE811_TSC_DATA_NON_INC_REG, data_xy, + sizeof(data_xy)); + if (ret < 0) { + return ret; + } + + /* Calculate positions values */ + uldata_xy = (data_xy[0] << 16) | (data_xy[1] << 8) | data_xy[2]; + data->touch_x = (uldata_xy >> 12U) & BIT_MASK(12); + data->touch_y = uldata_xy & BIT_MASK(12); + + return 0; +} + +static void stmpe811_report_touch(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + struct stmpe811_data *data = dev->data; + int x = data->touch_x; + int y = data->touch_y; + + if (config->screen_width > 0 && config->screen_height > 0) { + x = (((int)data->touch_x - config->raw_x_min) * config->screen_width) / + (config->raw_x_max - config->raw_x_min); + y = (((int)data->touch_y - config->raw_y_min) * config->screen_height) / + (config->raw_y_max - config->raw_y_min); + + x = CLAMP(x, 0, config->screen_width); + y = CLAMP(y, 0, config->screen_height); + } + + input_report_abs(dev, INPUT_ABS_X, x, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, y, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); +} + +static int stmpe811_process(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + + int err; + uint8_t int_sta, fifo_size, tsc_ctrl; + + err = i2c_reg_read_byte_dt(&config->bus, STMPE811_INT_STA_REG, &int_sta); + if (err < 0) { + return err; + } + + /* Clear processed interrupts */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_INT_STA_REG, int_sta); + if (err < 0) { + return err; + } + + if (int_sta & STMPE811_INT_BIT_FIFO_THRESHOLD) { + /** + * Report every element in FIFO + * + * This requires a while loop to avoid a race condition + * in which an element is added after reading FIFO_SIZE. + * + * Exiting ISR without handling every element in FIFO + * would prevent FIFO_THRESHOLD interrupt from being triggered again. + */ + while (true) { + err = i2c_reg_read_byte_dt(&config->bus, STMPE811_FIFO_SIZE_REG, + &fifo_size); + if (err < 0) { + return err; + } + + if (fifo_size == 0) { + break; + } + + for (int i = 0; i < fifo_size; i++) { + err = stmpe811_ts_get_data(dev); + if (err < 0) { + return err; + } + + stmpe811_report_touch(dev); + } + } + } + + /* TOUCH interrupt also gets triggered at release */ + if (int_sta & STMPE811_INT_BIT_TOUCH) { + err = i2c_reg_read_byte_dt(&config->bus, STMPE811_TSC_CTRL_REG, &tsc_ctrl); + if (err < 0) { + return err; + } + + /* TOUCH interrupt + no touch detected in TSC_CTRL reg <=> release */ + if (!(tsc_ctrl & STMPE811_TSC_CTRL_BIT_TOUCH_DET)) { + input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); + } + } + + return 0; +} + +static void stmpe811_work_handler(struct k_work *work) +{ + struct stmpe811_data *data = CONTAINER_OF(work, struct stmpe811_data, processing_work); + const struct stmpe811_config *config = data->dev->config; + + stmpe811_process(data->dev); + /** + * Reschedule ISR if there was an interrupt triggered during handling (race condition). + * IRQ is edge-triggered, so otherwise it would never be triggered again. + */ + if (gpio_pin_get_dt(&config->int_gpio)) { + k_work_submit(&data->processing_work); + } +} + +static void stmpe811_interrupt_handler(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct stmpe811_data *data = CONTAINER_OF(cb, struct stmpe811_data, int_gpio_cb); + + k_work_submit(&data->processing_work); +} + +static int stmpe811_verify_chip_id(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + uint8_t buf[2]; + + i2c_burst_read_dt(&config->bus, STMPE811_CHP_ID_LSB_REG, buf, 2); + + if (sys_get_be16(buf) != CHIP_ID) { + return -EINVAL; + } + + return 0; +} + +static int stmpe811_init(const struct device *dev) +{ + const struct stmpe811_config *config = dev->config; + struct stmpe811_data *data = dev->data; + int err; + + if (!i2c_is_ready_dt(&config->bus)) { + LOG_ERR("I2C controller device not ready"); + return -ENODEV; + } + + data->dev = dev; + + k_work_init(&data->processing_work, stmpe811_work_handler); + + /* Verify CHIP_ID */ + err = stmpe811_verify_chip_id(dev); + if (err) { + LOG_ERR("CHIP ID verification failed (%d)", err); + return err; + } + + /* Initialize */ + err = stmpe811_ts_init(dev); + if (err) { + LOG_ERR("Touch screen controller initialization failed (%d)", err); + return err; + } + + /* Initialize GPIO interrupt */ + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("Interrupt GPIO controller device not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (err < 0) { + LOG_ERR("Could not configure interrupt GPIO pin (%d)", err); + return err; + } + + err = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (err < 0) { + LOG_ERR("Could not configure GPIO interrupt (%d)", err); + return err; + } + + gpio_init_callback(&data->int_gpio_cb, stmpe811_interrupt_handler, + BIT(config->int_gpio.pin)); + err = gpio_add_callback_dt(&config->int_gpio, &data->int_gpio_cb); + if (err < 0) { + LOG_ERR("Could not set GPIO callback (%d)", err); + return err; + } + + /* Enable global interrupts */ + err = i2c_reg_write_byte_dt(&config->bus, STMPE811_INT_CTRL_REG, + STMPE811_INT_CTRL_BIT_GLOBAL_INT); + if (err < 0) { + LOG_ERR("Could not enable global interrupts (%d)", err); + return err; + } + + return 0; +} + +#define STMPE811_DEFINE(index) \ + BUILD_ASSERT(DT_INST_PROP_OR(index, raw_x_max, 4096) > \ + DT_INST_PROP_OR(index, raw_x_min, 0), \ + "raw-x-max should be larger than raw-x-min"); \ + BUILD_ASSERT(DT_INST_PROP_OR(index, raw_y_max, 4096) > \ + DT_INST_PROP_OR(index, raw_y_min, 0), \ + "raw-y-max should be larger than raw-y-min"); \ + static const struct stmpe811_config stmpe811_config_##index = { \ + .bus = I2C_DT_SPEC_INST_GET(index), \ + .int_gpio = GPIO_DT_SPEC_INST_GET(index, int_gpios), \ + .panel_driver_settling_time_us = \ + DT_INST_ENUM_IDX(index, panel_driver_settling_time_us), \ + .screen_width = DT_INST_PROP(index, screen_width), \ + .screen_height = DT_INST_PROP(index, screen_height), \ + .raw_x_min = DT_INST_PROP_OR(index, raw_x_min, 0), \ + .raw_y_min = DT_INST_PROP_OR(index, raw_y_min, 0), \ + .raw_x_max = DT_INST_PROP_OR(index, raw_x_max, 4096), \ + .raw_y_max = DT_INST_PROP_OR(index, raw_y_max, 4096), \ + .touch_detect_delay_us = DT_INST_ENUM_IDX(index, touch_detect_delay_us), \ + .touch_average_control = DT_INST_ENUM_IDX(index, touch_average_control), \ + .tracking_index = DT_INST_ENUM_IDX(index, tracking_index)}; \ + static struct stmpe811_data stmpe811_data_##index; \ + DEVICE_DT_INST_DEFINE(index, stmpe811_init, NULL, &stmpe811_data_##index, \ + &stmpe811_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(STMPE811_DEFINE) diff --git a/dts/bindings/input/st,stmpe811.yaml b/dts/bindings/input/st,stmpe811.yaml new file mode 100644 index 00000000000..2a39595d13f --- /dev/null +++ b/dts/bindings/input/st,stmpe811.yaml @@ -0,0 +1,127 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: STMPE811 I2C touchscreen controller + +compatible: "st,stmpe811" + +include: i2c-device.yaml + +properties: + int-gpios: + type: phandle-array + description: | + Interrupt GPIO. Used by the controller to signal touch data is + available. Active low. + + screen-width: + type: int + default: 0 + description: | + Screen width for scaling the reported coordinates. + Default: raw touchscreen resolution. + + screen-height: + type: int + default: 0 + description: | + Screen height for scaling the reported coordinates. + Default: raw touchscreen resolution. + + raw-x-min: + type: int + description: | + Signed raw X axis start for scaling the reported coordinates. + No effect if screen size is not set. + + raw-y-min: + type: int + description: | + Signed raw Y axis start for scaling the reported coordinates. + No effect if screen size is not set. + + raw-x-max: + type: int + description: | + Raw X axis end for scaling the reported coordinates. + No effect if screen size is not set. + + raw-y-max: + type: int + description: | + Raw Y axis end for scaling the reported coordinates. + No effect if screen size is not set. + + panel-driver-settling-time-us: + type: int + enum: + - 10 + - 100 + - 500 + - 1000 + - 5000 + - 10000 + - 50000 + - 100000 + required: true + description: | + Panel driver settling time (microseconds). For large panels (> 6"), a capacitor of 10 nF + is recommended at the touchscreen terminals for noise filtering. + As a general rule, 1-5 nF capacitors require around 500 us settling time, and 5-10 nF need + around 1 ms. When a larger capacitor is used, this value should be changed, as it can + lead to inaccuracy of the measurement. + + touch-detect-delay-us: + type: int + enum: + - 10 + - 50 + - 100 + - 500 + - 1000 + - 5000 + - 10000 + - 50000 + required: true + description: | + Touch detect delay (microseconds) is the delay from the activation of the pull-up resistor + in the X+ line to the time the device performs touch detection. + If no capacitor, or a smaller capacitor is used, this value can be lowered to + minimize detection latency, but it could lower the position stability. + + touch-average-control: + type: int + enum: + - 1 + - 2 + - 4 + - 8 + required: true + description: | + Average control (number of samples). + This parameter can be set to any of the possible values. + Higher values result in more filtering of noise, but also introduce + more latency in the touch detection process. + + Use cases that require low touch detection latency + may benefit from using a lower value for this parameter, + at the cost of less noise filtering. + + tracking-index: + type: int + enum: + - 0 + - 4 + - 8 + - 16 + - 32 + - 64 + - 92 + - 127 + required: true + description: | + Tracking index determines the minimal distance between + the current touch position and the previous touch position. + If the distance is shorter than the tracking index, it is discarded. + Lowering the tracking index increases the frequency of touch events, + but also increases the load on the system. diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index 4a1956be5d2..71f1d9a212a 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -78,6 +78,16 @@ int-gpios = <&gpio0 0 0>; input-codes = <0 1 2>; }; + + stmpe811@4 { + compatible = "st,stmpe811"; + reg = <0x4>; + int-gpios = <&gpio0 0 0>; + panel-driver-settling-time-us = <10>; + touch-detect-delay-us = <10>; + touch-average-control = <1>; + tracking-index = <0>; + }; }; spi@2 { From bac9b73442761d0b2549cb69e1159a48bbe15f09 Mon Sep 17 00:00:00 2001 From: Brunon Blok Date: Fri, 11 Aug 2023 16:04:22 +0200 Subject: [PATCH 0867/4498] boards: arm: enable stmpe811 on stm32f429i_disc1 Enable STMPE811 driver on stm32f429i_disc1 board. Signed-off-by: Brunon Blok Signed-off-by: Mateusz Sierszulski --- boards/arm/stm32f429i_disc1/Kconfig.defconfig | 3 +++ .../arm/stm32f429i_disc1/stm32f429i_disc1.dts | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/boards/arm/stm32f429i_disc1/Kconfig.defconfig b/boards/arm/stm32f429i_disc1/Kconfig.defconfig index 37fefc2292a..b6e1113e010 100644 --- a/boards/arm/stm32f429i_disc1/Kconfig.defconfig +++ b/boards/arm/stm32f429i_disc1/Kconfig.defconfig @@ -8,6 +8,9 @@ if BOARD_STM32F429I_DISC1 config BOARD default "stm32f429i_disc1" +config INPUT + default y if DISPLAY + config MEMC default y if DISPLAY diff --git a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts index 6bd6b450130..60b8c2874f9 100644 --- a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts @@ -55,6 +55,13 @@ led0 = &green_led_3; sw0 = &user_button; }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <&stmpe811>; + invert-x; + invert-y; + }; }; &clk_lsi { @@ -115,6 +122,23 @@ pinctrl-names = "default"; status = "okay"; clock-frequency = ; + + stmpe811: stmpe811@41 { + compatible = "st,stmpe811"; + status = "okay"; + reg = <0x41>; + int-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; + screen-width = <240>; + screen-height = <320>; + raw-x-min = <240>; + raw-y-min = <200>; + raw-x-max = <3680>; + raw-y-max = <3800>; + panel-driver-settling-time-us = <1000>; + touch-detect-delay-us = <5000>; + touch-average-control = <8>; + tracking-index = <127>; + }; }; &spi5 { From 6267259f91d2561666a97dd836e4ea7e2aabbc3a Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 15 Sep 2023 14:42:57 +0200 Subject: [PATCH 0868/4498] Bluetooth: Mesh: Use decimals instead of hex nums in DFD shell cmds JSON doesn't support hexdecimals as numbers. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/shell/dfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index b7daf42af1c..0415929dfec 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -29,7 +29,7 @@ static void print_dfd_status(const struct shell *sh, struct bt_mesh_dfd_srv *srv srv->phase); if (srv->phase != BT_MESH_DFD_PHASE_IDLE && srv->dfu.xfer.slot) { - shell_fprintf(sh, SHELL_NORMAL, ", \"group\": 0x%04x, \"app_idx\": %d, " + shell_fprintf(sh, SHELL_NORMAL, ", \"group\": %d, \"app_idx\": %d, " "\"ttl\": %d, \"timeout_base\": %d, \"xfer_mode\": %d, " "\"apply\": %d, \"slot_idx\": %d", srv->inputs.group, srv->inputs.app_idx, srv->inputs.ttl, srv->inputs.timeout_base, @@ -165,7 +165,7 @@ static int cmd_dfd_receivers_get(const struct shell *sh, size_t argc, char *argv for (int i = 0; i < cnt; i++) { const struct bt_mesh_dfu_target *t = &dfd_srv->targets[i + first]; - shell_print(sh, "\t\t\"%d\": { \"blob_addr\": 0x%04x, \"phase\": %d, " + shell_print(sh, "\t\t\"%d\": { \"blob_addr\": %d, \"phase\": %d, " "\"status\": %d, \"blob_status\": %d, \"progress\": %d, " "\"img_idx\": %d }%s", i + first, t->blob.addr, t->phase, t->status, t->blob.status, progress, t->img_idx, (i == cnt - 1) ? "" : ","); From b6165e01caa42a5c2cc3e05744575e11ae142d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Sep 2023 11:00:25 +0200 Subject: [PATCH 0869/4498] doc: can: samples: fix bad reference to can-counter sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a dangling reference that was silently ignored before. Signed-off-by: Benjamin Cabé --- doc/hardware/peripherals/canbus/controller.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/hardware/peripherals/canbus/controller.rst b/doc/hardware/peripherals/canbus/controller.rst index 182141c6045..8724b96515a 100644 --- a/doc/hardware/peripherals/canbus/controller.rst +++ b/doc/hardware/peripherals/canbus/controller.rst @@ -332,7 +332,7 @@ Samples ******* We have two ready-to-build samples demonstrating use of the Zephyr CAN API: -:zephyr:code-sample:`Zephyr CAN counter sample ` and +:zephyr:code-sample:`Zephyr CAN counter sample ` and :zephyr:code-sample:`SocketCAN sample `. From 4cba9e6d425e322e68c464d33e9a988e17b8baf3 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 14 Sep 2023 22:30:33 +0000 Subject: [PATCH 0870/4498] cmake: warn the user that the toolchain cache hides errors When `toolchain_is_ok` fails, the error message points the user at the CMake logs. But those logs will be empty if the user tried to compile more than once (typically: cleans everything and tries again). So tell the user that cleaning the toolchain cache is required to see the error. Tell the user to "move" the cache instead of removing it in case technical support needs the cache for forensics. Some finicky toolchains can be "non-deterministic" and fail _sometimes_. For instance a license server can be flaky, or the toolchain can require an "elaborate" set of environment variables triggering some configuration "trial-and-error". In such a non-deterministic case deleting the cache is enough to get rid of the issue and move on! Looking at logs is not even required; even better. Once the toolchain cache believes that the toolchain works, any future toolchain glitch will be obvious at actual compilation time. To test all this: ``` # Verify that the toolchain can compile a dummy file, if it is not we # won't be able to test for compatibility with certain C flags. -zephyr_check_compiler_flag(C "" toolchain_is_ok) +zephyr_check_compiler_flag(C "-fubar" toolchain_is_ok) assert(toolchain_is_ok "The toolchain is unable to build a dummy C file.\ ``` Signed-off-by: Marc Herbert --- cmake/modules/kernel.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 7e65c9cd186..a093d46691f 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -142,7 +142,8 @@ enable_language(C CXX ASM) # Verify that the toolchain can compile a dummy file, if it is not we # won't be able to test for compatibility with certain C flags. zephyr_check_compiler_flag(C "" toolchain_is_ok) -assert(toolchain_is_ok "The toolchain is unable to build a dummy C file. See CMakeError.log.") +assert(toolchain_is_ok "The toolchain is unable to build a dummy C file.\ + Move ${USER_CACHE_DIR}, re-run and look at CMakeError.log") include(${ZEPHYR_BASE}/cmake/target_toolchain_flags.cmake) From e24bb4a5a0b7570ad69ed8a0335ed9c161cffdb7 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 22 Sep 2023 09:15:48 +0200 Subject: [PATCH 0871/4498] net: http: service: Fix typo in HTTP_RESOURCE_FOREACH doc Fixed a documentation typo. Signed-off-by: Pieter De Gendt --- include/zephyr/net/http/service.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/http/service.h b/include/zephyr/net/http/service.h index a7af97cb500..b6997334de4 100644 --- a/include/zephyr/net/http/service.h +++ b/include/zephyr/net/http/service.h @@ -135,7 +135,7 @@ struct http_service_desc { #define HTTP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(http_service_desc, _it) /** - * @brief Iterate over static HTTP reesources associated with a given @p _service. + * @brief Iterate over static HTTP resources associated with a given @p _service. * * @note This macro requires that @p _service is defined with @ref HTTP_SERVICE_DEFINE. * From 09e58e1ecc91f454d53c743c1168977a0d6df2e4 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 22 Sep 2023 09:16:55 +0200 Subject: [PATCH 0872/4498] test: http_server: Fix copy-paste references Fixed HTTP resource references in test_HTTP_RESOURCE_DEFINE. Signed-off-by: Pieter De Gendt --- tests/net/lib/http_server/common/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/net/lib/http_server/common/src/main.c b/tests/net/lib/http_server/common/src/main.c index c0aee694c84..b85940e8e21 100644 --- a/tests/net/lib/http_server/common/src/main.c +++ b/tests/net/lib/http_server/common/src/main.c @@ -240,8 +240,8 @@ ZTEST(http_service, test_HTTP_RESOURCE_DEFINE) zassert_equal(res->detail, RES(3)); } else { zassert_unreachable( - "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res, - &resource_0, &resource_1); + "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res, + &resource_2, &resource_3); } } } From 9a193ac1c34419d54bbb8046111d1a0535ce1155 Mon Sep 17 00:00:00 2001 From: Daniel Stuart Date: Wed, 13 Sep 2023 11:04:06 -0300 Subject: [PATCH 0873/4498] settings: shell: Add value type and allow for strings to be used This can be further extended to support other data types. Signed-off-by: Daniel Stuart --- subsys/settings/src/settings_shell.c | 101 +++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 12 deletions(-) diff --git a/subsys/settings/src/settings_shell.c b/subsys/settings/src/settings_shell.c index 7a9de6416e6..e8132eeeb49 100644 --- a/subsys/settings/src/settings_shell.c +++ b/subsys/settings/src/settings_shell.c @@ -56,8 +56,14 @@ static int cmd_list(const struct shell *shell_ptr, size_t argc, char *argv[]) return err; } +enum settings_value_types { + SETTINGS_VALUE_HEX, + SETTINGS_VALUE_STRING, +}; + struct settings_read_callback_params { const struct shell *shell_ptr; + const enum settings_value_types value_type; bool value_found; }; @@ -84,7 +90,23 @@ static int settings_read_callback(const char *key, return 0; } - shell_hexdump(params->shell_ptr, buffer, num_read_bytes); + if (num_read_bytes == 0) { + shell_warn(params->shell_ptr, "Value is empty"); + return 0; + } + + switch (params->value_type) { + case SETTINGS_VALUE_HEX: + shell_hexdump(params->shell_ptr, buffer, num_read_bytes); + break; + case SETTINGS_VALUE_STRING: + if (buffer[num_read_bytes - 1] != '\0') { + shell_error(params->shell_ptr, "Value is not a string"); + return 0; + } + shell_print(params->shell_ptr, "%s", buffer); + break; + } if (len > SETTINGS_MAX_VAL_LEN) { shell_print(params->shell_ptr, "(The output has been truncated)"); @@ -93,17 +115,40 @@ static int settings_read_callback(const char *key, return 0; } +static int settings_parse_type(const char *type, enum settings_value_types *value_type) +{ + if (strcmp(type, "string") == 0) { + *value_type = SETTINGS_VALUE_STRING; + } else if (strcmp(type, "hex") == 0) { + *value_type = SETTINGS_VALUE_HEX; + } else { + return -EINVAL; + } + + return 0; +} + static int cmd_read(const struct shell *shell_ptr, size_t argc, char *argv[]) { int err; - const char *name = argv[1]; + + enum settings_value_types value_type = SETTINGS_VALUE_HEX; + + if (argc > 2) { + err = settings_parse_type(argv[1], &value_type); + if (err) { + shell_error(shell_ptr, "Invalid type: %s", argv[1]); + return err; + } + } struct settings_read_callback_params params = { .shell_ptr = shell_ptr, + .value_type = value_type, .value_found = false }; - err = settings_load_subtree_direct(name, settings_read_callback, ¶ms); + err = settings_load_subtree_direct(argv[argc - 1], settings_read_callback, ¶ms); if (err) { shell_error(shell_ptr, "Failed to load setting: %d", err); @@ -119,16 +164,34 @@ static int cmd_write(const struct shell *shell_ptr, size_t argc, char *argv[]) { int err; uint8_t buffer[CONFIG_SHELL_CMD_BUFF_SIZE / 2]; - size_t buffer_len; + size_t buffer_len = 0; + enum settings_value_types value_type = SETTINGS_VALUE_HEX; + + if (argc > 3) { + err = settings_parse_type(argv[1], &value_type); + if (err) { + shell_error(shell_ptr, "Invalid type: %s", argv[1]); + return err; + } + } - buffer_len = hex2bin(argv[2], strlen(argv[2]), buffer, sizeof(buffer)); + switch (value_type) { + case SETTINGS_VALUE_HEX: + buffer_len = hex2bin(argv[argc - 1], strlen(argv[argc - 1]), + buffer, sizeof(buffer)); + break; + case SETTINGS_VALUE_STRING: + buffer_len = strlen(argv[argc - 1]) + 1; + memcpy(buffer, argv[argc - 1], buffer_len); + break; + } if (buffer_len == 0) { - shell_error(shell_ptr, "Failed to parse hex value"); + shell_error(shell_ptr, "Failed to parse value"); return -EINVAL; } - err = settings_save_one(argv[1], buffer, buffer_len); + err = settings_save_one(argv[argc - 2], buffer, buffer_len); if (err) { shell_error(shell_ptr, "Failed to write setting: %d", err); @@ -151,11 +214,25 @@ static int cmd_delete(const struct shell *shell_ptr, size_t argc, char *argv[]) } SHELL_STATIC_SUBCMD_SET_CREATE(settings_cmds, - SHELL_CMD_ARG(list, NULL, "[]", cmd_list, 1, 1), - SHELL_CMD_ARG(read, NULL, "", cmd_read, 2, 0), - SHELL_CMD_ARG(write, NULL, " ", cmd_write, 3, 0), - SHELL_CMD_ARG(delete, NULL, "", cmd_delete, 2, 0), - SHELL_SUBCMD_SET_END); + SHELL_CMD_ARG(list, NULL, + "List all settings in a subtree (omit to list all)\n" + "Usage: settings list [subtree]", + cmd_list, 1, 1), + SHELL_CMD_ARG(read, NULL, + "Read a specific setting\n" + "Usage: settings read [type] \n" + "type: string or hex (default: hex)", + cmd_read, 2, 1), + SHELL_CMD_ARG(write, NULL, + "Write to a specific setting\n" + "Usage: settings write [type] \n" + "type: string or hex (default: hex)", + cmd_write, 3, 1), + SHELL_CMD_ARG(delete, NULL, + "Delete a specific setting\n" + "Usage: settings delete ", + cmd_delete, 2, 0), + SHELL_SUBCMD_SET_END); static int cmd_settings(const struct shell *shell_ptr, size_t argc, char **argv) { From ea6129cd7c21299c8cd65db5722f0a7d7aafaeae Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 23 Jun 2023 16:19:25 +0000 Subject: [PATCH 0874/4498] mgmt/MCUmgr/grp/img: Add support for three image configuration The commit adds support for uploading images to secondary slots of three images. Signed-off-by: Dominik Ermel --- subsys/dfu/Kconfig | 2 +- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 2 +- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 65 +++++++++---------- .../mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 36 ++++++++-- 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/subsys/dfu/Kconfig b/subsys/dfu/Kconfig index f998b2ef9f2..121fa3964f6 100644 --- a/subsys/dfu/Kconfig +++ b/subsys/dfu/Kconfig @@ -89,7 +89,7 @@ if !MCUBOOT config UPDATEABLE_IMAGE_NUMBER int "Number of updateable images" default 1 - range 1 2 + range 1 3 help If value is set to 2 or greater then, this enables support needed when application is combined with MCUboot multi-image boot. diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 641e16bd703..81fc57d9238 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -46,7 +46,7 @@ endif config MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER int "Number of supported images" default UPDATEABLE_IMAGE_NUMBER - range 1 2 + range 1 3 help Sets how many application images are supported (pairs of secondary and primary slots). Setting this to 2 requires MCUMGR_TRANSPORT_NETBUF_SIZE to be at least 512b. diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 0d733ce7abc..300948d5c88 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -41,43 +41,38 @@ #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ (FIXED_PARTITION_OFFSET(label) == CONFIG_FLASH_LOAD_OFFSET) -#if FIXED_PARTITION_EXISTS(slot0_partition) -#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) -#define NUMBER_OF_ACTIVE_IMAGE 0 -#endif -#endif - -#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot0_ns_partition) -#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) -#define NUMBER_OF_ACTIVE_IMAGE 0 -#endif -#endif - -#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot1_partition) -#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) -#define NUMBER_OF_ACTIVE_IMAGE 0 -#endif -#endif - -#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot2_partition) -#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition) -#define NUMBER_OF_ACTIVE_IMAGE 1 -#endif -#endif - -#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot3_partition) -#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot3_partition) -#define NUMBER_OF_ACTIVE_IMAGE 1 -#endif +BUILD_ASSERT(sizeof(struct image_header) == IMAGE_HEADER_SIZE, + "struct image_header not required size"); + +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 +#if FIXED_PARTITION_EXISTS(slot0_ns_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) +#define ACTIVE_IMAGE_IS 0 +#elif FIXED_PARTITION_EXISTS(slot0_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) +#define ACTIVE_IMAGE_IS 0 +#elif FIXED_PARTITION_EXISTS(slot1_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) +#define ACTIVE_IMAGE_IS 0 +#elif FIXED_PARTITION_EXISTS(slot2_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition) +#define ACTIVE_IMAGE_IS 1 +#elif FIXED_PARTITION_EXISTS(slot3_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot3_partition) +#define ACTIVE_IMAGE_IS 1 +#elif FIXED_PARTITION_EXISTS(slot4_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot4_partition) +#define ACTIVE_IMAGE_IS 2 +#elif FIXED_PARTITION_EXISTS(slot5_partition) && \ + FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot5_partition) +#define ACTIVE_IMAGE_IS 2 +#else +#define ACTIVE_IMAGE_IS 0 #endif - -#ifndef NUMBER_OF_ACTIVE_IMAGE -#error "Unsupported code parition is set as active application partition" +#else +#define ACTIVE_IMAGE_IS 0 #endif -_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, - "struct image_header not required size"); - LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; @@ -159,7 +154,7 @@ int img_mgmt_active_slot(int image) int img_mgmt_active_image(void) { - return NUMBER_OF_ACTIVE_IMAGE; + return ACTIVE_IMAGE_IS; } /* diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index c3641986fd2..addde1e9a2c 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -25,12 +25,26 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); #define SLOT1_PARTITION slot1_partition #define SLOT2_PARTITION slot2_partition #define SLOT3_PARTITION slot3_partition +#define SLOT4_PARTITION slot4_partition +#define SLOT5_PARTITION slot5_partition + +/* SLOT0_PARTITION and SLOT1_PARTITION are not checked because + * there is not conditional code that depends on them. If they do + * not exist compilation will fail, but in case if some of other + * partitions do not exist, code will compile and will not work + * properly. + */ +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 +BUILD_ASSERT(FIXED_PARTITION_EXISTS(SLOT2_PARTITION) && + FIXED_PARTITION_EXISTS(SLOT3_PARTITION), + "Missing partitions?"); +#endif -BUILD_ASSERT(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 1 || - (CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 && - FIXED_PARTITION_EXISTS(SLOT2_PARTITION) && - FIXED_PARTITION_EXISTS(SLOT3_PARTITION)), +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 3 +BUILD_ASSERT(FIXED_PARTITION_EXISTS(SLOT4_PARTITION) && + FIXED_PARTITION_EXISTS(SLOT5_PARTITION), "Missing partitions?"); +#endif /** * Determines if the specified area of flash is completely unwritten. @@ -137,6 +151,18 @@ img_mgmt_flash_area_id(int slot) break; #endif +#if FIXED_PARTITION_EXISTS(SLOT4_PARTITION) + case 4: + fa_id = FIXED_PARTITION_ID(SLOT4_PARTITION); + break; +#endif + +#if FIXED_PARTITION_EXISTS(SLOT5_PARTITION) + case 5: + fa_id = FIXED_PARTITION_ID(SLOT5_PARTITION); + break; +#endif + default: fa_id = -1; break; @@ -194,7 +220,7 @@ static int img_mgmt_get_unused_slot_area_id(int slot) return slot != -1 ? img_mgmt_flash_area_id(slot) : -1; #endif } -#elif CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 +#elif CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 static int img_mgmt_get_unused_slot_area_id(int image) { int area_id = -1; From 09e7e2db51a4461bb4d4c47d77c2283da6a19048 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Thu, 21 Sep 2023 12:02:20 +0800 Subject: [PATCH 0875/4498] soc: arm: Add support for Ambiq Apollo4 Blue Plus. Added devicetree and Kconfig for Apollo4 Blue Plus SoC. They are needed for the apollo4p_blue_kxr_evb board. Signed-off-by: Aaron Ye --- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 122 ++++++++++++++++++ .../apollo4x/Kconfig.defconfig.apollo4p_blue | 18 +++ soc/arm/ambiq/apollo4x/Kconfig.soc | 4 + 3 files changed, 144 insertions(+) create mode 100644 dts/arm/ambiq/ambiq_apollo4p_blue.dtsi create mode 100644 soc/arm/ambiq/apollo4x/Kconfig.defconfig.apollo4p_blue diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi new file mode 100644 index 00000000000..85937de51e2 --- /dev/null +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +/ { + clocks { + uartclk: apb-pclk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m4f"; + reg = <0>; + }; + }; + + /* MRAM region */ + flash0: flash@18000 { + compatible = "soc-nv-flash"; + reg = <0x00018000 0x1e8000>; + }; + + /* TCM */ + tcm: tcm@10000000 { + compatible = "zephyr,memory-region"; + reg = <0x10000000 0x10000>; + zephyr,memory-region = "ITCM"; + }; + + /* SRAM */ + sram0: memory@10010000 { + compatible = "mmio-sram"; + reg = <0x10010000 0x2B0000>; + }; + + soc { + pwrcfg: pwrcfg@40021000 { + compatible = "ambiq,pwrctrl"; + reg = <0x40021000 0x400>; + #pwrcfg-cells = <2>; + }; + + stimer0: stimer@40008800 { + compatible = "ambiq,stimer"; + reg = <0x40008800 0x80>; + interrupts = <32 0>; + status = "okay"; + }; + + counter0: counter@40008000 { + compatible = "ambiq,counter"; + reg = <0x40008000 0x80>; + interrupts = <67 0>; + status = "disabled"; + }; + + uart0: uart@4001c000 { + compatible = "ambiq,uart", "arm,pl011"; + reg = <0x4001c000 0x1000>; + interrupts = <15 0>; + interrupt-names = "UART0"; + status = "disabled"; + clocks = <&uartclk>; + ambiq,pwrcfg = <&pwrcfg 0x4 0x200>; + }; + uart1: uart@4001d000 { + compatible = "ambiq,uart", "arm,pl011"; + reg = <0x4001d000 0x1000>; + interrupts = <16 0>; + interrupt-names = "UART1"; + status = "disabled"; + clocks = <&uartclk>; + ambiq,pwrcfg = <&pwrcfg 0x4 0x400>; + }; + + uart2: uart@4001e000 { + compatible = "ambiq,uart", "arm,pl011"; + reg = <0x4001e000 0x1000>; + interrupts = <17 0>; + interrupt-names = "UART2"; + status = "disabled"; + clocks = <&uartclk>; + ambiq,pwrcfg = <&pwrcfg 0x4 0x800>; + }; + + uart3: uart@4001f000 { + compatible = "ambiq,uart", "arm,pl011"; + reg = <0x4001f000 0x1000>; + interrupts = <18 0>; + interrupt-names = "UART3"; + status = "disabled"; + clocks = <&uartclk>; + ambiq,pwrcfg = <&pwrcfg 0x4 0x1000>; + }; + + pinctrl: pin-controller@40010000 { + compatible = "ambiq,apollo4-pinctrl"; + reg = <0x40010000 0x800>; + }; + + wdt0: watchdog@40024000 { + compatible = "ambiq,watchdog"; + reg = <0x40024000 0x400>; + interrupts = <1 0>; + clock-frequency = <16>; + status = "disabled"; + }; + + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/soc/arm/ambiq/apollo4x/Kconfig.defconfig.apollo4p_blue b/soc/arm/ambiq/apollo4x/Kconfig.defconfig.apollo4p_blue new file mode 100644 index 00000000000..2d791dd4a46 --- /dev/null +++ b/soc/arm/ambiq/apollo4x/Kconfig.defconfig.apollo4p_blue @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Ambiq Micro Inc. + +if SOC_APOLLO4P_BLUE + +config NUM_IRQS + default 83 + +DT_NODE_SRAM := /memory@0 + +config SRAM_NC_SIZE + default $(dt_node_reg_size_int,$(DT_NODE_SRAM),1,K) + +config SRAM_NC_BASE_ADDRESS + default $(dt_node_reg_addr_hex,$(DT_NODE_SRAM),1) + +endif # SOC_APOLLO4P_BLUE diff --git a/soc/arm/ambiq/apollo4x/Kconfig.soc b/soc/arm/ambiq/apollo4x/Kconfig.soc index 215367c4855..a9b5cf00824 100644 --- a/soc/arm/ambiq/apollo4x/Kconfig.soc +++ b/soc/arm/ambiq/apollo4x/Kconfig.soc @@ -1,6 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # # Copyright (c) 2023 Antmicro +# Copyright (c) 2023 Ambiq Micro Inc. choice prompt "Ambiq Apollo4X Selection" @@ -9,4 +10,7 @@ choice config SOC_APOLLO4P bool "Apollo4P" +config SOC_APOLLO4P_BLUE + bool "Apollo4 Blue Plus" + endchoice From 7c9b76ecdfaa2f37057b43607e25911597c95809 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Thu, 21 Sep 2023 12:02:20 +0800 Subject: [PATCH 0876/4498] board: arm: Add support for apollo4p_blue_kxr_evb board. Add devicetree, Kconfig and doc for Ambiq Apollo4 Blue Plus KXR EVB board. Signed-off-by: Aaron Ye --- .../arm/apollo4p_blue_kxr_evb/Kconfig.board | 7 ++ .../apollo4p_blue_kxr_evb/Kconfig.defconfig | 7 ++ .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 19 ++++ .../apollo4p_blue_kxr_evb.dts | 36 ++++++ .../apollo4p_blue_kxr_evb.yaml | 14 +++ .../apollo4p_blue_kxr_evb_defconfig | 10 ++ boards/arm/apollo4p_blue_kxr_evb/board.cmake | 6 + .../apollo4-blue-plus-kxr-soc-eval-board.jpg | Bin 0 -> 97629 bytes .../arm/apollo4p_blue_kxr_evb/doc/index.rst | 104 ++++++++++++++++++ 9 files changed, 203 insertions(+) create mode 100644 boards/arm/apollo4p_blue_kxr_evb/Kconfig.board create mode 100644 boards/arm/apollo4p_blue_kxr_evb/Kconfig.defconfig create mode 100644 boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi create mode 100644 boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts create mode 100644 boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml create mode 100644 boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb_defconfig create mode 100644 boards/arm/apollo4p_blue_kxr_evb/board.cmake create mode 100644 boards/arm/apollo4p_blue_kxr_evb/doc/apollo4-blue-plus-kxr-soc-eval-board.jpg create mode 100644 boards/arm/apollo4p_blue_kxr_evb/doc/index.rst diff --git a/boards/arm/apollo4p_blue_kxr_evb/Kconfig.board b/boards/arm/apollo4p_blue_kxr_evb/Kconfig.board new file mode 100644 index 00000000000..0ae2283f97d --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/Kconfig.board @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Ambiq Micro Inc. + +config BOARD_APOLLO4P_BLUE_KXR_EVB + bool "Ambiq Apollo4 Blue Plus KXR Evaluation Board" + depends on SOC_APOLLO4P_BLUE diff --git a/boards/arm/apollo4p_blue_kxr_evb/Kconfig.defconfig b/boards/arm/apollo4p_blue_kxr_evb/Kconfig.defconfig new file mode 100644 index 00000000000..f14c801d3b3 --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/Kconfig.defconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Ambiq Micro Inc. + +config BOARD + default "apollo4p_blue_kxr_evb" + depends on BOARD_APOLLO4P_BLUE_KXR_EVB diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi new file mode 100644 index 00000000000..840f2343310 --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Ambiq Micro Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; +}; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts new file mode 100644 index 00000000000..93a55c4bc44 --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -0,0 +1,36 @@ +/dts-v1/; +#include + +#include "apollo4p_blue_kxr_evb-pinctrl.dtsi" + +/ { + model = "Ambiq Apollo4 Blue Plus KXR evaluation board"; + compatible = "ambiq,apollo4p_blue_kxr_evb"; + chosen { + zephyr,itcm = &tcm; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-pipe = &uart0; + }; + aliases { + watchdog0 = &wdt0; + }; + +}; + +&uart0 { + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&counter0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml new file mode 100644 index 00000000000..bbdf0477a36 --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml @@ -0,0 +1,14 @@ +identifier: apollo4p_blue_kxr_evb +name: Apollo4 Blue Plus KXR EVB +type: mcu +arch: arm +ram: 2816 +flash: 1952 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart +testing: + ignore_tags: + - net diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb_defconfig b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb_defconfig new file mode 100644 index 00000000000..4c940d417fd --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Ambiq Micro Inc. + +CONFIG_SOC_SERIES_APOLLO4X=y +CONFIG_SOC_APOLLO4P_BLUE=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/arm/apollo4p_blue_kxr_evb/board.cmake b/boards/arm/apollo4p_blue_kxr_evb/board.cmake new file mode 100644 index 00000000000..f19b79f968f --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=AMAP42KK-KBR" "--iface=swd" "--speed=1000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/apollo4p_blue_kxr_evb/doc/apollo4-blue-plus-kxr-soc-eval-board.jpg b/boards/arm/apollo4p_blue_kxr_evb/doc/apollo4-blue-plus-kxr-soc-eval-board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c1825eb4c06f76a352a97b101a511582e15e5c3e GIT binary patch literal 97629 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 YZb4RT`~NVG{@=vt|DV21_s`6~0Xo8~Qvd(} literal 0 HcmV?d00001 diff --git a/boards/arm/apollo4p_blue_kxr_evb/doc/index.rst b/boards/arm/apollo4p_blue_kxr_evb/doc/index.rst new file mode 100644 index 00000000000..35592c0b911 --- /dev/null +++ b/boards/arm/apollo4p_blue_kxr_evb/doc/index.rst @@ -0,0 +1,104 @@ +.. _apollo4p_blue_kxr_evb: + +Ambiq Apollo4 Blue Plus KXR EVB +############################### + +Apollo4 Blue Plus KXR EVB is a board by Ambiq featuring their ultra-low power Apollo4 Blue Plus SoC. + +.. image:: ./apollo4-blue-plus-kxr-soc-eval-board.jpg + :align: center + :alt: Apollo4 Blue Plus KXR EVB + +Hardware +******** + +- Apollo4 Blue Plus SoC with upto 192 MHz operating frequency +- ARM® Cortex® M4F core +- 64 kB 2-way Associative/Direct-Mapped Cache per core +- Up to 2 MB of non-volatile memory (NVM) for code/data +- Up to 2.75 MB of low leakage / low power RAM for code/data +- 384 kB Tightly Coupled RAM +- 384 kB Extended RAM +- Bluetooth 5.1 Low Energy + +For more information about the Apollo4 Blue Plus SoC and Apollo4 Blue Plus KXR EVB board: + +- `Apollo4 Blue Plus Website`_ +- `Apollo4 Blue Plus Datasheet`_ +- `Apollo4 Blue Plus KXR EVB Website`_ + +Supported Features +================== + +The Apollo4 Blue Plus KXR EVB board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| STIMER | on-chip | stimer | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| RADIO | on-chip | bluetooth | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +``boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb_defconfig``. + +Programming and Debugging +========================= + +Flashing an application +----------------------- + +Connect your device to your host computer using the JLINK USB port. +The sample application :ref:`hello_world` is used for this example. +Build the Zephyr kernel and application, then flash it to the device: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: apollo4p_blue_kxr_evb + :goals: flash + +.. note:: + `west flash` requires `SEGGER J-Link software`_ and `pylink`_ Python module + to be installed on you host computer. + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should be able to see on the corresponding Serial Port +the following message: + +.. code-block:: console + + Hello World! apollo4p_blue_kxr_evb + +.. _Apollo4 Blue Plus Website: + https://ambiq.com/apollo4-blue-plus/ + +.. _Apollo4 Blue Plus Datasheet: + https://contentportal.ambiq.com/documents/20123/388410/Apollo4-Blue-Plus-SoC-Datasheet.pdf + +.. _Apollo4 Blue Plus KXR EVB Website: + https://www.ambiq.top/en/apollo4-blue-plus-kxr-soc-eval-board + +.. _SEGGER J-Link software: + https://www.segger.com/downloads/jlink + +.. _pylink: + https://github.com/Square/pylink From 0691079f477eb7908a2262cd217eb35064fc3aea Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Thu, 21 Sep 2023 12:02:21 +0800 Subject: [PATCH 0877/4498] manifest: Update hal_ambiq revision. This change adds Apollo4 Blue Plus SoC support. Signed-off-by: Aaron Ye --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 788eb9dfe3d..0bb013112d4 100644 --- a/west.yml +++ b/west.yml @@ -142,7 +142,7 @@ manifest: groups: - hal - name: hal_ambiq - revision: 0e15e4becd49c40cb054672d9525eccfe98b440f + revision: 0a7c99325aa73a1ef777501da91c2c6608661e56 path: modules/hal/ambiq groups: - hal From 723b24fc58847d940bab7d82596957376bdc045d Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 14:02:22 +0200 Subject: [PATCH 0878/4498] dts: bindings: adc: stm32: add a property for adc sequencer type Add a property for STM32 ADC to indicate which type of sequencer is used by the device (fully configurable or not). Add defines to help with this setting. Signed-off-by: Guillaume Gautier --- dts/bindings/adc/st,stm32-adc.yaml | 11 +++++++++++ include/zephyr/dt-bindings/adc/stm32_adc.h | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/dts/bindings/adc/st,stm32-adc.yaml b/dts/bindings/adc/st,stm32-adc.yaml index 1134fa684a1..df3eff62dbb 100644 --- a/dts/bindings/adc/st,stm32-adc.yaml +++ b/dts/bindings/adc/st,stm32-adc.yaml @@ -97,5 +97,16 @@ properties: description: | Number of sampling time common channels for this ADC instance, if any. + st,adc-sequencer: + type: int + required: true + enum: + - 0 # NOT_FULLY_CONFIGURABLE + - 1 # FULLY_CONFIGURABLE + description: | + Type of ADC sequencer: + - : Not fully configurable sequencer + - : Fully configurable sequencer + io-channel-cells: - input diff --git a/include/zephyr/dt-bindings/adc/stm32_adc.h b/include/zephyr/dt-bindings/adc/stm32_adc.h index 527a55ef9ed..20f257275e9 100644 --- a/include/zephyr/dt-bindings/adc/stm32_adc.h +++ b/include/zephyr/dt-bindings/adc/stm32_adc.h @@ -74,4 +74,14 @@ #define ASYNC 2 /** @} */ +/** + * @name STM32 ADC sequencer type + * This value is to set + * One or both values may not apply to all series. Refer to the RefMan + * @{ + */ +#define NOT_FULLY_CONFIGURABLE 0 +#define FULLY_CONFIGURABLE 1 +/** @} */ + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_STM32_ADC_H_ */ From 6d6d7b5607d54b9d7e8a9f94bd8183516d693e80 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 14:06:55 +0200 Subject: [PATCH 0879/4498] dts: arm: st: add st,adc-sequencer properties to all stm32 adc Add st,adc-sequencer to all STM32 ADC instances. Signed-off-by: Guillaume Gautier --- dts/arm/st/c0/stm32c0.dtsi | 1 + dts/arm/st/f0/stm32f0.dtsi | 1 + dts/arm/st/f1/stm32f1.dtsi | 1 + dts/arm/st/f2/stm32f2.dtsi | 1 + dts/arm/st/f3/stm32f302.dtsi | 1 + dts/arm/st/f3/stm32f303.dtsi | 2 ++ dts/arm/st/f3/stm32f334.dtsi | 1 + dts/arm/st/f3/stm32f373.dtsi | 1 + dts/arm/st/f4/stm32f4.dtsi | 1 + dts/arm/st/f4/stm32f405.dtsi | 2 ++ dts/arm/st/f7/stm32f7.dtsi | 3 +++ dts/arm/st/g0/stm32g0.dtsi | 1 + dts/arm/st/g4/stm32g4.dtsi | 2 ++ dts/arm/st/g4/stm32g473.dtsi | 2 ++ dts/arm/st/g4/stm32g491.dtsi | 1 + dts/arm/st/h5/stm32h5.dtsi | 1 + dts/arm/st/h5/stm32h562.dtsi | 1 + dts/arm/st/h7/stm32h7.dtsi | 4 ++++ dts/arm/st/h7/stm32h723.dtsi | 1 + dts/arm/st/l0/stm32l0.dtsi | 1 + dts/arm/st/l1/stm32l1.dtsi | 1 + dts/arm/st/l4/stm32l4.dtsi | 2 ++ dts/arm/st/l5/stm32l5.dtsi | 2 ++ dts/arm/st/u5/stm32u5.dtsi | 2 ++ dts/arm/st/wb/stm32wb.dtsi | 1 + dts/arm/st/wba/stm32wba.dtsi | 1 + dts/arm/st/wl/stm32wl.dtsi | 1 + 27 files changed, 39 insertions(+) diff --git a/dts/arm/st/c0/stm32c0.dtsi b/dts/arm/st/c0/stm32c0.dtsi index 0ee56ff36dd..ef71f835ba2 100644 --- a/dts/arm/st/c0/stm32c0.dtsi +++ b/dts/arm/st/c0/stm32c0.dtsi @@ -299,6 +299,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/f0/stm32f0.dtsi b/dts/arm/st/f0/stm32f0.dtsi index 7a8944a05d6..e9e521cd47e 100644 --- a/dts/arm/st/f0/stm32f0.dtsi +++ b/dts/arm/st/f0/stm32f0.dtsi @@ -344,6 +344,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 8 14 29 42 56 72 240>; num-sampling-time-common-channels = <1>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/f1/stm32f1.dtsi b/dts/arm/st/f1/stm32f1.dtsi index 8676b402de1..b70130db308 100644 --- a/dts/arm/st/f1/stm32f1.dtsi +++ b/dts/arm/st/f1/stm32f1.dtsi @@ -341,6 +341,7 @@ #io-channel-cells = <1>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index 7fa86bf6dc5..845cd6fb5a2 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -372,6 +372,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 58 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; dma1: dma@40026000 { diff --git a/dts/arm/st/f3/stm32f302.dtsi b/dts/arm/st/f3/stm32f302.dtsi index 19f51aa4d13..59f4b2f7077 100644 --- a/dts/arm/st/f3/stm32f302.dtsi +++ b/dts/arm/st/f3/stm32f302.dtsi @@ -114,6 +114,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; + st,adc-sequencer = ; }; }; }; diff --git a/dts/arm/st/f3/stm32f303.dtsi b/dts/arm/st/f3/stm32f303.dtsi index c57fb46e917..01e5d4233df 100644 --- a/dts/arm/st/f3/stm32f303.dtsi +++ b/dts/arm/st/f3/stm32f303.dtsi @@ -153,6 +153,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; + st,adc-sequencer = ; }; adc2: adc@50000100 { @@ -168,6 +169,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; + st,adc-sequencer = ; }; }; }; diff --git a/dts/arm/st/f3/stm32f334.dtsi b/dts/arm/st/f3/stm32f334.dtsi index 4fc389f67cb..f24fefc22df 100644 --- a/dts/arm/st/f3/stm32f334.dtsi +++ b/dts/arm/st/f3/stm32f334.dtsi @@ -40,6 +40,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; + st,adc-sequencer = ; }; rtc@40002800 { diff --git a/dts/arm/st/f3/stm32f373.dtsi b/dts/arm/st/f3/stm32f373.dtsi index 39a9e9c08d4..9c42331c36e 100644 --- a/dts/arm/st/f3/stm32f373.dtsi +++ b/dts/arm/st/f3/stm32f373.dtsi @@ -193,6 +193,7 @@ #io-channel-cells = <1>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; + st,adc-sequencer = ; }; rtc@40002800 { diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index 9b07a6d6d67..36cbd9c8fed 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -519,6 +519,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; dma1: dma@40026000 { diff --git a/dts/arm/st/f4/stm32f405.dtsi b/dts/arm/st/f4/stm32f405.dtsi index dfcd1a94fc5..445c7df7b9d 100644 --- a/dts/arm/st/f4/stm32f405.dtsi +++ b/dts/arm/st/f4/stm32f405.dtsi @@ -258,6 +258,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; adc3: adc@40012200 { @@ -273,6 +274,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; dac1: dac@40007400 { diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index cc2d60cb95e..87bb8545b72 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -749,6 +749,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; adc2: adc@40012100 { @@ -764,6 +765,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; adc3: adc@40012200 { @@ -779,6 +781,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; st,adc-clock-source = ; + st,adc-sequencer = ; }; dac1: dac@40007400 { diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index 1373dc7e970..5f37fc667db 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -408,6 +408,7 @@ */ sampling-times = <3 5 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 38a0222d8bf..2ab13841dc9 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -114,6 +114,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; adc2: adc@50000100 { @@ -128,6 +129,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; dac1: dac@50000800 { diff --git a/dts/arm/st/g4/stm32g473.dtsi b/dts/arm/st/g4/stm32g473.dtsi index abeff20c2c9..4bfe01b7b3d 100644 --- a/dts/arm/st/g4/stm32g473.dtsi +++ b/dts/arm/st/g4/stm32g473.dtsi @@ -39,6 +39,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; adc5: adc@50000600 { @@ -53,6 +54,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; spi4: spi@40013c00 { diff --git a/dts/arm/st/g4/stm32g491.dtsi b/dts/arm/st/g4/stm32g491.dtsi index 20acca5e7a4..5bdac5010dd 100644 --- a/dts/arm/st/g4/stm32g491.dtsi +++ b/dts/arm/st/g4/stm32g491.dtsi @@ -69,6 +69,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; uart5: serial@40005000 { diff --git a/dts/arm/st/h5/stm32h5.dtsi b/dts/arm/st/h5/stm32h5.dtsi index 6ce6a902257..f8f9e64e092 100644 --- a/dts/arm/st/h5/stm32h5.dtsi +++ b/dts/arm/st/h5/stm32h5.dtsi @@ -268,6 +268,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; rtc: rtc@44007800 { diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index 66df580219e..eeaf65ab7da 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -178,6 +178,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; timers4: timers@40000800 { diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index ac0aefdb6f3..8c66a67b057 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -814,6 +814,7 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; + st,adc-sequencer = ; }; adc2: adc@40022100 { @@ -829,6 +830,7 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; + st,adc-sequencer = ; }; /* dual mode: adc1 and adc2 coupled */ @@ -845,6 +847,7 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; + st,adc-sequencer = ; }; adc3: adc@58026000 { @@ -860,6 +863,7 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; + st,adc-sequencer = ; }; dac1: dac@40007400 { diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index 91efcb23636..8c3fa0b1d8b 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -52,6 +52,7 @@ STM32H72X_ADC3_RES(8, 0x02) STM32H72X_ADC3_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; dmamux1: dmamux@40020800 { diff --git a/dts/arm/st/l0/stm32l0.dtsi b/dts/arm/st/l0/stm32l0.dtsi index 2448656c98d..b05dbff210d 100644 --- a/dts/arm/st/l0/stm32l0.dtsi +++ b/dts/arm/st/l0/stm32l0.dtsi @@ -315,6 +315,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <1>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/l1/stm32l1.dtsi b/dts/arm/st/l1/stm32l1.dtsi index e43859d598a..0203f740c83 100644 --- a/dts/arm/st/l1/stm32l1.dtsi +++ b/dts/arm/st/l1/stm32l1.dtsi @@ -222,6 +222,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <4 9 16 24 48 96 192 384>; st,adc-clock-source = ; + st,adc-sequencer = ; }; dac1: dac@40007400 { diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index 7158289c9e0..f2b8c1a2ff6 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -395,6 +395,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; adc2: adc@50040100 { @@ -409,6 +410,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; dma1: dma@40020000 { diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 8455fa09f45..c8c94319353 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -664,6 +664,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; adc2: adc@42028100 { @@ -678,6 +679,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; usb: usb@4000d400 { diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 7c8e038c8fe..20d4806f92f 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -749,6 +749,7 @@ STM32_ADC_RES(8, 0x03)>; sampling-times = <5 6 12 20 36 68 391 814>; st,adc-clock-source = ; + st,adc-sequencer = ; }; adc4: adc@46021000 { @@ -765,6 +766,7 @@ sampling-times = <2 4 8 13 20 40 80 815>; num-sampling-time-common-channels = <2>; st,adc-clock-source = ; + st,adc-sequencer = ; }; fdcan1: can@4000a400 { diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index aff898dfd2e..63687c09e8d 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -418,6 +418,7 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; + st,adc-sequencer = ; }; iwdg: watchdog@40003000 { diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index 42ecc4efd8f..c93b042babf 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -395,6 +395,7 @@ sampling-times = <2 4 8 13 20 40 80 815>; num-sampling-time-common-channels = <2>; st,adc-clock-source = ; + st,adc-sequencer = ; }; lptim1: timers@46004400 { diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index 14f1c65e0b6..85c40256e51 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -338,6 +338,7 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; + st,adc-sequencer = ; }; dac1: dac@40007400 { From c201d2196479c607939817c6759b66680a7efe43 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 22 Jun 2023 11:52:34 +0200 Subject: [PATCH 0880/4498] drivers: adc: rework stm32 adc sequencer Add sequencer support for all STM32 series. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 229 ++++++++++++++++++++++++---------------- 1 file changed, 136 insertions(+), 93 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 875e9f2ba94..e254a7fb572 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -68,18 +68,18 @@ LOG_MODULE_REGISTER(adc_stm32); num_sampling_time_common_channels,\ 0, value) 0) +#define ANY_ADC_SEQUENCER_TYPE_IS(value) \ + (DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_PROP_OR, \ + st_adc_sequencer,\ + 0, value) 0) + #define IS_EQ_PROP_OR(inst, prop, default_value, compare_value) \ IS_EQ(DT_INST_PROP_OR(inst, prop, default_value), compare_value) || /* reference voltage for the ADC */ #define STM32_ADC_VREF_MV DT_INST_PROP(0, vref_mv) -#if !defined(CONFIG_SOC_SERIES_STM32C0X) && \ - !defined(CONFIG_SOC_SERIES_STM32F0X) && \ - !defined(CONFIG_SOC_SERIES_STM32G0X) && \ - !defined(CONFIG_SOC_SERIES_STM32L0X) && \ - !defined(CONFIG_SOC_SERIES_STM32WBAX) && \ - !defined(CONFIG_SOC_SERIES_STM32WLX) +#if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) #define RANK(n) LL_ADC_REG_RANK_##n static const uint32_t table_rank[] = { RANK(1), @@ -98,6 +98,22 @@ static const uint32_t table_rank[] = { RANK(14), RANK(15), RANK(16), +#if defined(LL_ADC_REG_RANK_17) + RANK(17), + RANK(18), + RANK(19), + RANK(20), + RANK(21), + RANK(22), + RANK(23), + RANK(24), + RANK(25), + RANK(26), + RANK(27), +#if defined(LL_ADC_REG_RANK_28) + RANK(28), +#endif /* LL_ADC_REG_RANK_28 */ +#endif /* LL_ADC_REG_RANK_17 */ }; #define SEQ_LEN(n) LL_ADC_REG_SEQ_SCAN_ENABLE_##n##RANKS @@ -119,8 +135,24 @@ static const uint32_t table_seq_len[] = { SEQ_LEN(14), SEQ_LEN(15), SEQ_LEN(16), +#if defined(LL_ADC_REG_SEQ_SCAN_ENABLE_17RANKS) + SEQ_LEN(17), + SEQ_LEN(18), + SEQ_LEN(19), + SEQ_LEN(20), + SEQ_LEN(21), + SEQ_LEN(22), + SEQ_LEN(23), + SEQ_LEN(24), + SEQ_LEN(25), + SEQ_LEN(26), + SEQ_LEN(27), +#if defined(LL_ADC_REG_SEQ_SCAN_ENABLE_28RANKS) + SEQ_LEN(28), +#endif /* LL_ADC_REG_SEQ_SCAN_ENABLE_28RANKS */ +#endif /* LL_ADC_REG_SEQ_SCAN_ENABLE_17RANKS */ }; -#endif +#endif /* ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) */ /* External channels (maximum). */ #define STM32_CHANNEL_COUNT 20 @@ -167,6 +199,7 @@ struct adc_stm32_cfg { const struct pinctrl_dev_config *pcfg; const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME]; int8_t num_sampling_time_common_channels; + int8_t sequencer_type; int8_t res_table_size; const uint32_t res_table[]; }; @@ -724,6 +757,70 @@ static int set_resolution(const struct device *dev, return 0; } +static int set_sequencer(const struct device *dev) +{ + const struct adc_stm32_cfg *config = dev->config; + struct adc_stm32_data *data = dev->data; + ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + + uint8_t channel_id; + uint8_t channel_index = 0; + uint32_t channels_mask = 0; + + /* Iterate over selected channels in bitmask keeping track of: + * - channel_index: ranging from 0 -> ( data->channel_count - 1 ) + * - channel_id: ordinal position of channel in data->channels bitmask + */ + for (uint32_t channels = data->channels; channels; + channels &= ~BIT(channel_id), channel_index++) { + channel_id = find_lsb_set(channels) - 1; + + uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(channel_id); + + channels_mask |= channel; + +#if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) + if (config->sequencer_type == FULLY_CONFIGURABLE) { +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32U5X) + /* + * Each channel in the sequence must be previously enabled in PCSEL. + * This register controls the analog switch integrated in the IO level. + */ + LL_ADC_SetChannelPreselection(adc, channel); +#endif /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32U5X */ + LL_ADC_REG_SetSequencerRanks(adc, table_rank[channel_index], channel); + LL_ADC_REG_SetSequencerLength(adc, table_seq_len[channel_index]); + } +#endif /* ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) */ + } + +#if ANY_ADC_SEQUENCER_TYPE_IS(NOT_FULLY_CONFIGURABLE) + if (config->sequencer_type == NOT_FULLY_CONFIGURABLE) { + LL_ADC_REG_SetSequencerChannels(adc, channels_mask); + +#if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ + !defined(CONFIG_SOC_SERIES_STM32L0X) && \ + !defined(CONFIG_SOC_SERIES_STM32U5X) && \ + !defined(CONFIG_SOC_SERIES_STM32WBAX) + /* + * After modifying sequencer it is mandatory to wait for the + * assertion of CCRDY flag + */ + while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) { + } + LL_ADC_ClearFlag_CCRDY(adc); +#endif /* !CONFIG_SOC_SERIES_STM32F0X && !L0X && !U5X && !WBAX */ + } +#endif /* ANY_ADC_SEQUENCER_TYPE_IS(NOT_FULLY_CONFIGURABLE) */ + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) || \ + DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + LL_ADC_SetSequencersScanMode(adc, LL_ADC_SEQ_SCAN_ENABLE); +#endif /* st_stm32f1_adc || st_stm32f4_adc */ + + return 0; +} + static int start_read(const struct device *dev, const struct adc_sequence *sequence) { @@ -747,22 +844,20 @@ static int start_read(const struct device *dev, return -EINVAL; } -#if !defined(CONFIG_SOC_SERIES_STM32C0X) && \ - !defined(CONFIG_SOC_SERIES_STM32F0X) && \ - !defined(CONFIG_SOC_SERIES_STM32G0X) && \ - !defined(CONFIG_SOC_SERIES_STM32L0X) && \ - !defined(CONFIG_SOC_SERIES_STM32WBAX) && \ - !defined(CONFIG_SOC_SERIES_STM32WLX) +#if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) if (data->channel_count > ARRAY_SIZE(table_seq_len)) { LOG_ERR("Too many channels for sequencer. Max: %d", ARRAY_SIZE(table_seq_len)); return -EINVAL; } -#else +#endif /* ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) */ + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && !defined(CONFIG_ADC_STM32_DMA) + /* Multiple samplings is only supported with DMA for F1 */ if (data->channel_count > 1) { - LOG_ERR("This device only supports single channel sampling"); + LOG_ERR("Without DMA, this device only supports single channel sampling"); return -EINVAL; } -#endif +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && !CONFIG_ADC_STM32_DMA */ /* Check and set the resolution */ err = set_resolution(dev, sequence); @@ -770,77 +865,10 @@ static int start_read(const struct device *dev, return err; } - uint8_t channel_id; - uint8_t channel_index = 0; - - /* Iterate over selected channels in bitmask keeping track of: - * - channel_index: ranging from 0 -> ( data->channel_count - 1 ) - * - channel_id: ordinal position of channel in data->channels bitmask - */ - for (uint32_t channels = data->channels; channels; - channels &= ~BIT(channel_id), channel_index++) { - channel_id = find_lsb_set(channels) - 1; - - uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(channel_id); - -#if defined(CONFIG_SOC_SERIES_STM32H7X) - /* - * Each channel in the sequence must be previously enabled in PCSEL. - * This register controls the analog switch integrated in the IO level. - */ - LL_ADC_SetChannelPreSelection(adc, channel); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) - /* - * Each channel in the sequence must be previously enabled in PCSEL. - * This register controls the analog switch integrated in the IO level. - * Only for ADC1 instance (ADC4 has no Channel preselection capability). - */ - if (adc == ADC1) { - LL_ADC_SetChannelPreselection(adc, channel); - } -#endif - -#if defined(CONFIG_SOC_SERIES_STM32F0X) || \ - defined(CONFIG_SOC_SERIES_STM32L0X) - LL_ADC_REG_SetSequencerChannels(adc, channel); -#elif defined(CONFIG_SOC_SERIES_STM32WLX) - /* Init the the ADC group for REGULAR conversion*/ - LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_CONFIGURABLE); - LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE); - LL_ADC_REG_SetSequencerLength(adc, LL_ADC_REG_SEQ_SCAN_DISABLE); - LL_ADC_REG_SetOverrun(adc, LL_ADC_REG_OVR_DATA_OVERWRITTEN); - LL_ADC_REG_SetSequencerRanks(adc, LL_ADC_REG_RANK_1, channel); - LL_ADC_REG_SetSequencerChannels(adc, channel); - /* Wait for config complete config is ready */ - while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) { - } - LL_ADC_ClearFlag_CCRDY(adc); -#elif defined(CONFIG_SOC_SERIES_STM32C0X) || defined(CONFIG_SOC_SERIES_STM32G0X) - /* C0 and G0 in "not fully configurable" sequencer mode */ - LL_ADC_REG_SetSequencerChannels(adc, channel); - LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED); - while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) { - } - LL_ADC_ClearFlag_CCRDY(adc); -#elif defined(CONFIG_SOC_SERIES_STM32WBAX) - LL_ADC_REG_StopConversion(adc); - while (LL_ADC_REG_IsStopConversionOngoing(adc) != 0) { - } - LL_ADC_REG_SetSequencerChannels(adc, channel); - LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) - if (adc != ADC4) { - LL_ADC_REG_SetSequencerRanks(adc, table_rank[channel_index], channel); - LL_ADC_REG_SetSequencerLength(adc, table_seq_len[channel_index]); - } else { - LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED); - LL_ADC_REG_SetSequencerLength(adc, - BIT(__LL_ADC_CHANNEL_TO_DECIMAL_NB(channel))); - } -#else - LL_ADC_REG_SetSequencerRanks(adc, table_rank[channel_index], channel); - LL_ADC_REG_SetSequencerLength(adc, table_seq_len[channel_index]); -#endif + /* Configure the sequencer */ + err = set_sequencer(dev); + if (err < 0) { + return err; } err = check_buffer(sequence, data->channel_count); @@ -886,6 +914,8 @@ static int start_read(const struct device *dev, #if !defined(CONFIG_ADC_STM32_DMA) #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + /* Trigger an ISR after each sampling (not just end of sequence) */ + LL_ADC_REG_SetFlagEndOfConversion(adc, LL_ADC_REG_FLAG_EOC_UNITARY_CONV); LL_ADC_EnableIT_EOCS(adc); #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) LL_ADC_EnableIT_EOS(adc); @@ -939,12 +969,19 @@ static void adc_stm32_isr(const struct device *dev) (const struct adc_stm32_cfg *)dev->config; ADC_TypeDef *adc = config->base; - *data->buffer++ = LL_ADC_REG_ReadConversionData32(adc); - - /* ISR is triggered after each conversion, and at the end-of-sequence. */ - if (++data->samples_count == data->channel_count) { - data->samples_count = 0; - adc_context_on_sampling_done(&data->ctx, dev); +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) + if (LL_ADC_IsActiveFlag_EOS(adc) == 1) { +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + if (LL_ADC_IsActiveFlag_EOCS(adc) == 1) { +#else + if (LL_ADC_IsActiveFlag_EOC(adc) == 1) { +#endif + *data->buffer++ = LL_ADC_REG_ReadConversionData32(adc); + /* ISR is triggered after each conversion, and at the end-of-sequence. */ + if (++data->samples_count == data->channel_count) { + data->samples_count = 0; + adc_context_on_sampling_done(&data->ctx, dev); + } } LOG_DBG("%s ISR triggered.", dev->name); @@ -963,6 +1000,11 @@ static void adc_context_on_complete(struct adc_context *ctx, int status) adc_stm32_disable(adc); LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), LL_ADC_PATH_INTERNAL_NONE); + +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32U5X) + /* Reset channel preselection register */ + LL_ADC_SetChannelPreselection(adc, 0); +#endif /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32U5X */ } static int adc_stm32_read(const struct device *dev, @@ -1450,6 +1492,7 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \ .pclk_len = DT_INST_NUM_CLOCKS(index), \ .clk_prescaler = ADC_STM32_DT_PRESC(index), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .sequencer_type = DT_INST_PROP(index, st_adc_sequencer), \ .sampling_time_table = DT_INST_PROP(index, sampling_times), \ .num_sampling_time_common_channels = \ DT_INST_PROP_OR(index, num_sampling_time_common_channels, 0),\ From e09c594711d2d7c961f6dca7143884b6044403a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 7 Sep 2023 16:37:13 +0200 Subject: [PATCH 0881/4498] drivers: adc: stm32: remove channel count limit Remove CHANNEL_COUNT limit used to check the channel bitmask. This value was not applicable on STM32L1 where channel can go up to 31. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index e254a7fb572..ec73d80e239 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -154,9 +154,6 @@ static const uint32_t table_seq_len[] = { }; #endif /* ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) */ -/* External channels (maximum). */ -#define STM32_CHANNEL_COUNT 20 - /* Number of different sampling time values */ #define STM32_NB_SAMPLING_TIME 8 @@ -839,11 +836,6 @@ static int start_read(const struct device *dev, return -EINVAL; } - if (data->channels > BIT(STM32_CHANNEL_COUNT) - 1) { - LOG_ERR("Channels bitmask uses out of range channel"); - return -EINVAL; - } - #if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) if (data->channel_count > ARRAY_SIZE(table_seq_len)) { LOG_ERR("Too many channels for sequencer. Max: %d", ARRAY_SIZE(table_seq_len)); @@ -1113,11 +1105,6 @@ static int adc_stm32_channel_setup(const struct device *dev, struct adc_stm32_data *data = dev->data; int acq_time_index; - if (channel_cfg->channel_id >= STM32_CHANNEL_COUNT) { - LOG_ERR("Channel %d is not valid", channel_cfg->channel_id); - return -EINVAL; - } - acq_time_index = adc_stm32_check_acq_time(dev, channel_cfg->acquisition_time); if (acq_time_index < 0) { From 0473cf5bb0051a217993f0179c47f4b15a6acf20 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 22 Jun 2023 11:54:19 +0200 Subject: [PATCH 0882/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo g071rb Add multiple channels in overlay to test the sequencer. Change clock source to correctly pass the test. Signed-off-by: Guillaume Gautier --- boards/arm/nucleo_g071rb/nucleo_g071rb.dts | 2 +- .../drivers/adc/adc_api/boards/nucleo_g071rb.overlay | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts index c9f1a2b6575..76b2369280e 100644 --- a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts @@ -140,7 +140,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = ; st,adc-prescaler = <4>; status = "okay"; vref-mv = <3300>; diff --git a/tests/drivers/adc/adc_api/boards/nucleo_g071rb.overlay b/tests/drivers/adc/adc_api/boards/nucleo_g071rb.overlay index f0d65c1e941..a40478a6ee1 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_g071rb.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_g071rb.overlay @@ -7,7 +7,7 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 1>; }; }; @@ -19,7 +19,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 06842bc2e042f5dfb161afb41327fedc6e43071a Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:14:09 +0200 Subject: [PATCH 0883/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo f401re Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_f401re.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_f401re.overlay b/tests/drivers/adc/adc_api/boards/nucleo_f401re.overlay index f0d65c1e941..ebb788c73b7 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_f401re.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_f401re.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 1>; }; }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@10 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 7a19b995bb9ebce9d68df8aa3d6f91a28b7c87b5 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:16:20 +0200 Subject: [PATCH 0884/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo f091rc Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_f091rc.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_f091rc.overlay b/tests/drivers/adc/adc_api/boards/nucleo_f091rc.overlay index f0d65c1e941..d8d89d460a0 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_f091rc.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_f091rc.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 1>; }; }; &adc1 { + pinctrl-0 = <&adc_in0_pa0 &adc_in1_pa1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 0986c074431eca22006ec6be07e092a0d798c1e2 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:16:50 +0200 Subject: [PATCH 0885/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo f207zg Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_f207zg.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_f207zg.overlay b/tests/drivers/adc/adc_api/boards/nucleo_f207zg.overlay index f0d65c1e941..3f87caeb294 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_f207zg.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_f207zg.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 3>; }; }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0 &adc1_in3_pa3>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 3c82c6fb7c4c73709d0fc77c6c611a269093eba2 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:17:17 +0200 Subject: [PATCH 0886/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo f429zi Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_f429zi.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_f429zi.overlay b/tests/drivers/adc/adc_api/boards/nucleo_f429zi.overlay index f0d65c1e941..3f87caeb294 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_f429zi.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_f429zi.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 3>; }; }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0 &adc1_in3_pa3>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 0446f59c300091ce5e6c339adc5e31896b26dfda Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:17:36 +0200 Subject: [PATCH 0887/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo f746zg Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_f746zg.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_f746zg.overlay b/tests/drivers/adc/adc_api/boards/nucleo_f746zg.overlay index f0d65c1e941..3f87caeb294 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_f746zg.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_f746zg.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 3>; }; }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0 &adc1_in3_pa3>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From c833abc15c3a6d14a8a7e6549f26246d84653312 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:17:53 +0200 Subject: [PATCH 0888/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo g474re Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../drivers/adc/adc_api/boards/nucleo_g474re.overlay | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_g474re.overlay b/tests/drivers/adc/adc_api/boards/nucleo_g474re.overlay index 33188a18cf4..7407481014a 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_g474re.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_g474re.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 1>; + io-channels = <&adc1 1>, <&adc1 2>; }; }; &adc1 { + pinctrl-0 = <&adc1_in1_pa0 &adc1_in2_pa1>; #address-cells = <1>; #size-cells = <0>; @@ -22,4 +23,12 @@ zephyr,acquisition-time = ; zephyr,resolution = <12>; }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; }; From 8d145da53c6b4f0e9cb5e12558b117989a0e4e2c Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:19:09 +0200 Subject: [PATCH 0889/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo l073rz Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_l073rz.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_l073rz.overlay b/tests/drivers/adc/adc_api/boards/nucleo_l073rz.overlay index f0d65c1e941..d8d89d460a0 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_l073rz.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_l073rz.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 1>; }; }; &adc1 { + pinctrl-0 = <&adc_in0_pa0 &adc_in1_pa1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 6224784a0b45cf44be3efe0a68d5bbb39f9ac6e5 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:22:34 +0200 Subject: [PATCH 0890/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo l152re Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_l152re.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_l152re.overlay b/tests/drivers/adc/adc_api/boards/nucleo_l152re.overlay index f0d65c1e941..d8d89d460a0 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_l152re.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_l152re.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 0>, <&adc1 1>; }; }; &adc1 { + pinctrl-0 = <&adc_in0_pa0 &adc_in1_pa1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From ec51e3978bff7b693eb96f644e012a344a8e4084 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:25:47 +0200 Subject: [PATCH 0891/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo l552ze_q Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_l552ze_q.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_l552ze_q.overlay b/tests/drivers/adc/adc_api/boards/nucleo_l552ze_q.overlay index 33188a18cf4..ab283660858 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_l552ze_q.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_l552ze_q.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 1>; + io-channels = <&adc1 1>, <&adc1 2>; }; }; &adc1 { + pinctrl-0 = <&adc1_in1_pc0 &adc1_in2_pc1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,15 @@ reg = <1>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 7eec6ea1e40cc652dfca28a095d4d803fbee291b Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:26:14 +0200 Subject: [PATCH 0892/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo wb55rg Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_wb55rg.overlay | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_wb55rg.overlay b/tests/drivers/adc/adc_api/boards/nucleo_wb55rg.overlay index 33188a18cf4..82f3300458c 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_wb55rg.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_wb55rg.overlay @@ -7,19 +7,28 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 1>; + io-channels = <&adc1 3>, <&adc1 4>; }; }; &adc1 { + pinctrl-0 = <&adc1_in3_pc2 &adc1_in4_pc3>; #address-cells = <1>; #size-cells = <0>; - channel@1 { - reg = <1>; + channel@3 { + reg = <3>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 83ab36f2a1c69683907b2588a6fc80f509a003af Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:26:34 +0200 Subject: [PATCH 0893/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo wba52cg Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_wba52cg.overlay | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_wba52cg.overlay b/tests/drivers/adc/adc_api/boards/nucleo_wba52cg.overlay index 6b96b54ef63..ae2f4afc58c 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_wba52cg.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_wba52cg.overlay @@ -7,19 +7,28 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc4 8>; + io-channels = <&adc4 7>, <&adc4 8>; }; }; &adc4 { + pinctrl-0 = <&adc4_in7_pa2 &adc4_in8_pa1>; #address-cells = <1>; #size-cells = <0>; + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + channel@8 { reg = <8>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From a6ece6a0c894aec6fa556406f7c6c32546ed7038 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:26:54 +0200 Subject: [PATCH 0894/4498] tests: drivers: adc: adc_api: boards: add sequence for nucleo wl55jc Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/nucleo_wl55jc.overlay | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/nucleo_wl55jc.overlay b/tests/drivers/adc/adc_api/boards/nucleo_wl55jc.overlay index f0d65c1e941..6e8e84b6678 100644 --- a/tests/drivers/adc/adc_api/boards/nucleo_wl55jc.overlay +++ b/tests/drivers/adc/adc_api/boards/nucleo_wl55jc.overlay @@ -7,19 +7,28 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 4>, <&adc1 5>; }; }; &adc1 { + pinctrl-0 = <&adc_in4_pb2 &adc_in5_pb1>; #address-cells = <1>; #size-cells = <0>; - channel@0 { - reg = <0>; + channel@4 { + reg = <4>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@5 { + reg = <5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 6a725d08ddfe3d5fe8f1d3883c51c4ee86c21146 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:27:33 +0200 Subject: [PATCH 0895/4498] tests: drivers: adc: adc_api: boards: add sequence for stm32f3 disco Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/stm32f3_disco.overlay | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/stm32f3_disco.overlay b/tests/drivers/adc/adc_api/boards/stm32f3_disco.overlay index f0d65c1e941..06897f4a6e4 100644 --- a/tests/drivers/adc/adc_api/boards/stm32f3_disco.overlay +++ b/tests/drivers/adc/adc_api/boards/stm32f3_disco.overlay @@ -7,19 +7,28 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 0>; + io-channels = <&adc1 1>, <&adc1 2>; }; }; &adc1 { + pinctrl-0 = <&adc1_in1_pa0 &adc1_in2_pa1>; #address-cells = <1>; #size-cells = <0>; - channel@0 { - reg = <0>; + channel@1 { + reg = <1>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From 3716a1b4e59cd60594176b3ef0f7595eb3b6a696 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:28:00 +0200 Subject: [PATCH 0896/4498] tests: drivers: adc: adc_api: boards: add sequence for stm32h573i dk Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/stm32h573i_dk.overlay | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/stm32h573i_dk.overlay b/tests/drivers/adc/adc_api/boards/stm32h573i_dk.overlay index af607867c7b..4a71e03421d 100644 --- a/tests/drivers/adc/adc_api/boards/stm32h573i_dk.overlay +++ b/tests/drivers/adc/adc_api/boards/stm32h573i_dk.overlay @@ -8,16 +8,25 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 1>; + io-channels = <&adc1 3>, <&adc1 6>; }; }; &adc1 { + pinctrl-0 = < &adc1_inp3_pa6 &adc1_inp6_pf12>; #address-cells = <1>; #size-cells = <0>; - channel@1 { - reg = <1>; + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@6 { + reg = <6>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; zephyr,acquisition-time = ; From 80b3b2a7dd3863e71bcfc0849700384a8cd852b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:28:32 +0200 Subject: [PATCH 0897/4498] tests: drivers: adc: adc_api: boards: add sequence for stm32l562e dk Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/stm32l562e_dk.overlay | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/stm32l562e_dk.overlay b/tests/drivers/adc/adc_api/boards/stm32l562e_dk.overlay index 33188a18cf4..fbeba28dcd6 100644 --- a/tests/drivers/adc/adc_api/boards/stm32l562e_dk.overlay +++ b/tests/drivers/adc/adc_api/boards/stm32l562e_dk.overlay @@ -7,19 +7,28 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 1>; + io-channels = <&adc1 13>, <&adc1 14>; }; }; &adc1 { + pinctrl-0 = <&adc1_in13_pc4 &adc1_in14_pc5>; #address-cells = <1>; #size-cells = <0>; - channel@1 { - reg = <1>; + channel@d { + reg = <13>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@e { + reg = <14>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; }; From d79bf2383a3786fc5bfc512a1d8a83a625e7092f Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:29:08 +0200 Subject: [PATCH 0898/4498] tests: drivers: adc: adc_api: boards: add sequence for disco l475 iot1 Add multiple channels in overlay to test the sequencer. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/disco_l475_iot1.overlay | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/disco_l475_iot1.overlay b/tests/drivers/adc/adc_api/boards/disco_l475_iot1.overlay index 9f35165ef87..42d8f177261 100644 --- a/tests/drivers/adc/adc_api/boards/disco_l475_iot1.overlay +++ b/tests/drivers/adc/adc_api/boards/disco_l475_iot1.overlay @@ -7,7 +7,7 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 5>; + io-channels = <&adc1 4>, <&adc1 5>; }; }; @@ -15,11 +15,19 @@ #address-cells = <1>; #size-cells = <0>; + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + channel@5 { reg = <5>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <10>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; }; }; From b72e4910cc8790d80d80ce9659657101739dc4b2 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:29:58 +0200 Subject: [PATCH 0899/4498] tests: drivers: adc: adc_api: boards: add sequence for b_u585i_iot02a Add multiple channels in overlay to test the sequencer for ADC1. Signed-off-by: Guillaume Gautier --- .../adc/adc_api/boards/b_u585i_iot02a.overlay | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/drivers/adc/adc_api/boards/b_u585i_iot02a.overlay b/tests/drivers/adc/adc_api/boards/b_u585i_iot02a.overlay index 52f641d34e5..90377971a58 100644 --- a/tests/drivers/adc/adc_api/boards/b_u585i_iot02a.overlay +++ b/tests/drivers/adc/adc_api/boards/b_u585i_iot02a.overlay @@ -7,11 +7,12 @@ / { zephyr,user { /* adjust channel number according to pinmux in board.dts */ - io-channels = <&adc1 15>; + io-channels = <&adc1 15>, <&adc1 16>; }; }; &adc1 { + pinctrl-0 = <&adc1_in15_pb0 &adc1_in16_pb1>; #address-cells = <1>; #size-cells = <0>; @@ -19,7 +20,19 @@ reg = <15>; zephyr,gain = "ADC_GAIN_1"; zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,resolution = <12>; }; + + channel@10 { + reg = <16>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc4 { + status = "disabled"; }; From 47d1dcda4e40b413cdf0cbf978f6a84b3cd31061 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 8 Sep 2023 10:30:55 +0200 Subject: [PATCH 0900/4498] tests: drivers: adc: adc_api: boards: add sequence for b_u585i_iot02a Add multiple channels in overlay to test the sequencer for ADC4. Signed-off-by: Guillaume Gautier --- .../boards/b_u585i_iot02a_adc4.overlay | 38 +++++++++++++++++++ tests/drivers/adc/adc_api/testcase.yaml | 5 +++ 2 files changed, 43 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/b_u585i_iot02a_adc4.overlay diff --git a/tests/drivers/adc/adc_api/boards/b_u585i_iot02a_adc4.overlay b/tests/drivers/adc/adc_api/boards/b_u585i_iot02a_adc4.overlay new file mode 100644 index 00000000000..3020a0c5997 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/b_u585i_iot02a_adc4.overlay @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc4 18>, <&adc4 19>; + }; +}; + +&adc4 { + pinctrl-0 = <&adc4_in18_pb0 &adc4_in19_pb1>; + #address-cells = <1>; + #size-cells = <0>; + + channel@12 { + reg = <18>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@13 { + reg = <19>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc1 { + status = "disabled"; +}; diff --git a/tests/drivers/adc/adc_api/testcase.yaml b/tests/drivers/adc/adc_api/testcase.yaml index b29afdf561c..5e8217cb2c3 100644 --- a/tests/drivers/adc/adc_api/testcase.yaml +++ b/tests/drivers/adc/adc_api/testcase.yaml @@ -7,3 +7,8 @@ tests: drivers.adc: depends_on: adc min_flash: 40 + drivers.adc.b_u585i_iot02a_adc4: + extra_args: + DTC_OVERLAY_FILE="boards/b_u585i_iot02a_adc4.overlay" + platform_allow: + - b_u585i_iot02a From f4c901b82dc13a43215a9a8b048c6d07851917a9 Mon Sep 17 00:00:00 2001 From: Roland Lezuo Date: Thu, 14 Sep 2023 15:48:43 +0200 Subject: [PATCH 0901/4498] soc: arm: st_stm32: add config to allow debugger attach in sleep/stop modes Adds CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP to allow debugger attaching in sleep/stop mode of STM32 parts. Mainly useful for debugging. Move DBGMCU from part-sepcific power.c to common soc_config.c. CONFIG_USE_SEGGER_RTT depends on this as well. Signed-off-by: Roland Lezuo --- modules/segger/Kconfig | 1 + soc/arm/st_stm32/Kconfig | 10 ++++++ soc/arm/st_stm32/common/soc_config.c | 48 ++++++++++++++++++++++++++-- soc/arm/st_stm32/stm32g0/power.c | 7 ---- soc/arm/st_stm32/stm32g4/power.c | 7 ---- soc/arm/st_stm32/stm32l0/power.c | 7 ---- soc/arm/st_stm32/stm32l4/power.c | 5 --- soc/arm/st_stm32/stm32l5/power.c | 5 --- soc/arm/st_stm32/stm32u5/power.c | 5 --- soc/arm/st_stm32/stm32wb/power.c | 6 ---- soc/arm/st_stm32/stm32wba/power.c | 5 --- soc/arm/st_stm32/stm32wl/power.c | 6 ---- 12 files changed, 56 insertions(+), 56 deletions(-) diff --git a/modules/segger/Kconfig b/modules/segger/Kconfig index 1324df8cb81..04a2a813b98 100644 --- a/modules/segger/Kconfig +++ b/modules/segger/Kconfig @@ -12,6 +12,7 @@ config HAS_SEGGER_RTT config USE_SEGGER_RTT bool "SEGGER RTT libraries." depends on HAS_SEGGER_RTT + select STM32_ENABLE_DEBUG_SLEEP_STOP if SOC_FAMILY_STM32 help Enable Segger J-Link RTT libraries for platforms that support it. Selection of this option enables use of RTT for various subsystems. diff --git a/soc/arm/st_stm32/Kconfig b/soc/arm/st_stm32/Kconfig index a75bf6094f6..c644b50a5ff 100644 --- a/soc/arm/st_stm32/Kconfig +++ b/soc/arm/st_stm32/Kconfig @@ -6,6 +6,7 @@ config SOC_FAMILY_STM32 bool select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select STM32_ENABLE_DEBUG_SLEEP_STOP if DEBUG select BUILD_OUTPUT_HEX if SOC_FAMILY_STM32 @@ -14,6 +15,15 @@ config SOC_FAMILY string default "st_stm32" +config STM32_ENABLE_DEBUG_SLEEP_STOP + bool "Allow debugger attach in stop/sleep Mode" + help + Some STM32 parts disable the DBGMCU in sleep/stop modes because + of power consumption. As a side-effects this prevents + debuggers from attaching w/o resetting the target. This + effectivly destroys the use-case of `west attach`. Also + SEGGER RTT and similar technologies need this. + source "soc/arm/st_stm32/*/Kconfig.soc" endif # SOC_FAMILY_STM32 diff --git a/soc/arm/st_stm32/common/soc_config.c b/soc/arm/st_stm32/common/soc_config.c index 5027ad0493c..a791f334be4 100644 --- a/soc/arm/st_stm32/common/soc_config.c +++ b/soc/arm/st_stm32/common/soc_config.c @@ -60,13 +60,55 @@ static int st_stm32_common_config(void) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU); #endif /* LL_APB1_GRP1_PERIPH_DBGMCU */ +#endif /* CONFIG_USE_SEGGER_RTT */ + + +#if defined(CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP) + #if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32MP1X) - HAL_EnableDBGSleepMode(); -#else + HAL_EnableDBGStopMode(); +#else /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32MP1X */ +#if defined(SOC_SERIES_STM32G0X) || defined(SOC_SERIES_STM32C0X) + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DBGMCU); + LL_DBGMCU_EnableDBGStopMode(); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_DBGMCU); +#elif defined(SOC_SERIES_STM32F0X) + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_DBGMCU); + LL_DBGMCU_EnableDBGStopMode(); + LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_DBGMCU); +#elif defined(SOC_SERIES_STM32L0X) + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU); + LL_DBGMCU_EnableDBGStopMode(); + LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU); +#else /* all other parts */ LL_DBGMCU_EnableDBGStopMode(); +#endif #endif /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32MP1X */ -#endif /* CONFIG_USE_SEGGER_RTT */ +#else + +/* keeping in mind that debugging draws a lot of power we explcitly disable when not needed */ +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32MP1X) + HAL_DisableDBGStopMode(); +#else /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32MP1X */ +#if defined(SOC_SERIES_STM32G0X) || defined(SOC_SERIES_STM32C0X) + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DBGMCU); + LL_DBGMCU_DisableDBGStopMode(); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_DBGMCU); +#elif defined(SOC_SERIES_STM32F0X) + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_DBGMCU); + LL_DBGMCU_DisableDBGStopMode(); + LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_DBGMCU); +#elif defined(SOC_SERIES_STM32L0X) + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU); + LL_DBGMCU_DisableDBGStopMode(); + LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU); +#else /* all other parts */ + LL_DBGMCU_DisableDBGStopMode(); +#endif +#endif /* CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32MP1X */ + +#endif /* CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP */ return 0; } diff --git a/soc/arm/st_stm32/stm32g0/power.c b/soc/arm/st_stm32/stm32g0/power.c index d13ec265679..b2dfd18bb52 100644 --- a/soc/arm/st_stm32/stm32g0/power.c +++ b/soc/arm/st_stm32/stm32g0/power.c @@ -87,13 +87,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during all and any Low power mode */ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DBGMCU); - LL_DBGMCU_EnableDBGStopMode(); - LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_DBGMCU); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32g4/power.c b/soc/arm/st_stm32/stm32g4/power.c index dadb0711468..3f2295e9440 100644 --- a/soc/arm/st_stm32/stm32g4/power.c +++ b/soc/arm/st_stm32/stm32g4/power.c @@ -85,13 +85,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); - /* keep in mind that debugging draws a lot of power */ -#ifdef CONFIG_DEBUG - LL_DBGMCU_EnableDBGStopMode(); -#else - LL_DBGMCU_DisableDBGStopMode(); -#endif - return 0; } diff --git a/soc/arm/st_stm32/stm32l0/power.c b/soc/arm/st_stm32/stm32l0/power.c index bf7cc7bad11..cfa2281fd6a 100644 --- a/soc/arm/st_stm32/stm32l0/power.c +++ b/soc/arm/st_stm32/stm32l0/power.c @@ -80,13 +80,6 @@ static int stm32_power_init(void) /* Enable Power clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during STOP mode */ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU); - LL_DBGMCU_EnableDBGStopMode(); - LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32l4/power.c b/soc/arm/st_stm32/stm32l4/power.c index 94b02f5213f..ff87553836e 100644 --- a/soc/arm/st_stm32/stm32l4/power.c +++ b/soc/arm/st_stm32/stm32l4/power.c @@ -120,11 +120,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during STOP mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32l5/power.c b/soc/arm/st_stm32/stm32l5/power.c index 1d5316c6963..fa8d57c894d 100644 --- a/soc/arm/st_stm32/stm32l5/power.c +++ b/soc/arm/st_stm32/stm32l5/power.c @@ -104,11 +104,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during all and any Low power mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32u5/power.c b/soc/arm/st_stm32/stm32u5/power.c index f880ffa1d08..a3214f93d96 100644 --- a/soc/arm/st_stm32/stm32u5/power.c +++ b/soc/arm/st_stm32/stm32u5/power.c @@ -118,11 +118,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during all and any Low power mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32wb/power.c b/soc/arm/st_stm32/stm32wb/power.c index e3dcdfa6cab..6836e88c4ed 100644 --- a/soc/arm/st_stm32/stm32wb/power.c +++ b/soc/arm/st_stm32/stm32wb/power.c @@ -141,12 +141,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) /* Initialize STM32 Power */ static int stm32_power_init(void) { - -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during STOP mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32wba/power.c b/soc/arm/st_stm32/stm32wba/power.c index 691424c2b25..018c27ee0b8 100644 --- a/soc/arm/st_stm32/stm32wba/power.c +++ b/soc/arm/st_stm32/stm32wba/power.c @@ -104,11 +104,6 @@ static int stm32_power_init(void) /* enable Power clock */ LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR); -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during all and any Low power mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } diff --git a/soc/arm/st_stm32/stm32wl/power.c b/soc/arm/st_stm32/stm32wl/power.c index aaf43db4817..dab500ecb77 100644 --- a/soc/arm/st_stm32/stm32wl/power.c +++ b/soc/arm/st_stm32/stm32wl/power.c @@ -85,12 +85,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) /* Initialize STM32 Power */ static int stm32_power_init(void) { - -#ifdef CONFIG_DEBUG - /* Enable the Debug Module during STOP mode */ - LL_DBGMCU_EnableDBGStopMode(); -#endif /* CONFIG_DEBUG */ - return 0; } From c45e9ec715e24c8787459b6c4d03ab0e3046e3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 21 Sep 2023 11:57:39 +0700 Subject: [PATCH 0902/4498] MAINTAINERS: add NXP collaborator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Dat-NguyenDuy to NXP collaborators. Signed-off-by: Manuel Argüelles --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index ac8b22c424b..38a36545fd5 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2458,6 +2458,7 @@ NXP Platforms: - bperseghetti - dbaluta - iuliana-prodan + - Dat-NguyenDuy files: - boards/arm/mimx*/ - boards/arm/frdm_k*/ From 49ab0b22f0872bea9a4aa7ac9bfbc877bcf903af Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 20 Sep 2023 17:40:07 +0200 Subject: [PATCH 0903/4498] drivers: can: switch to CAN_DEVICE_DT_INST_DEFINE for remaining drivers Switch from using DEVICE_DT_DEFINE()/DEVICE_DT_INST_DEFINE() to using CAN_DEVICE_DT_DEFINE()/CAN_DEVICE_DT_INST_DEFINE() for remaining drivers. This unifies CAN controller device driver initialization regardless of the driver implementing CAN statistics support or not. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_esp32_twai.c | 6 +++--- drivers/can/can_fake.c | 8 ++++---- drivers/can/can_kvaser_pci.c | 6 +++--- drivers/can/can_loopback.c | 8 ++++---- drivers/can/can_mcp2515.c | 6 +++--- drivers/can/can_native_posix_linux.c | 8 ++++---- drivers/can/can_nxp_s32_canxl.c | 16 ++++++++-------- drivers/can/can_stm32_bxcan.c | 8 ++++---- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/can/can_esp32_twai.c b/drivers/can/can_esp32_twai.c index 794b3bdb8cd..c26768ac003 100644 --- a/drivers/can/can_esp32_twai.c +++ b/drivers/can/can_esp32_twai.c @@ -301,8 +301,8 @@ const struct can_driver_api can_esp32_twai_driver_api = { static struct can_sja1000_data can_sja1000_data_##inst = \ CAN_SJA1000_DATA_INITIALIZER(NULL); \ \ - DEVICE_DT_INST_DEFINE(inst, can_esp32_twai_init, NULL, &can_sja1000_data_##inst, \ - &can_sja1000_config_##inst, POST_KERNEL, \ - CONFIG_CAN_INIT_PRIORITY, &can_esp32_twai_driver_api); + CAN_DEVICE_DT_INST_DEFINE(inst, can_esp32_twai_init, NULL, &can_sja1000_data_##inst, \ + &can_sja1000_config_##inst, POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, &can_esp32_twai_driver_api); DT_INST_FOREACH_STATUS_OKAY(CAN_ESP32_TWAI_INIT) diff --git a/drivers/can/can_fake.c b/drivers/can/can_fake.c index 5fc94319159..cdc2fd34a86 100644 --- a/drivers/can/can_fake.c +++ b/drivers/can/can_fake.c @@ -138,9 +138,9 @@ static const struct can_driver_api fake_can_driver_api = { #endif /* CONFIG_CAN_FD_MODE */ }; -#define FAKE_CAN_INIT(inst) \ - DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, NULL, POST_KERNEL,\ - CONFIG_CAN_INIT_PRIORITY, \ - &fake_can_driver_api); +#define FAKE_CAN_INIT(inst) \ + CAN_DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, NULL, POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, \ + &fake_can_driver_api); DT_INST_FOREACH_STATUS_OKAY(FAKE_CAN_INIT) diff --git a/drivers/can/can_kvaser_pci.c b/drivers/can/can_kvaser_pci.c index 39ed411cc67..2aa002efd8c 100644 --- a/drivers/can/can_kvaser_pci.c +++ b/drivers/can/can_kvaser_pci.c @@ -176,9 +176,9 @@ const struct can_driver_api can_kvaser_pci_driver_api = { static struct can_sja1000_data can_sja1000_data_##inst = \ CAN_SJA1000_DATA_INITIALIZER(&can_kvaser_pci_data_##inst); \ \ - DEVICE_DT_INST_DEFINE(inst, can_kvaser_pci_init, NULL, &can_sja1000_data_##inst, \ - &can_sja1000_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_kvaser_pci_driver_api); \ + CAN_DEVICE_DT_INST_DEFINE(inst, can_kvaser_pci_init, NULL, &can_sja1000_data_##inst, \ + &can_sja1000_config_##inst, POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, &can_kvaser_pci_driver_api); \ \ static void can_kvaser_pci_config_func_##inst(const struct device *dev) \ { \ diff --git a/drivers/can/can_loopback.c b/drivers/can/can_loopback.c index 6eaea400ee0..8eb4074cc45 100644 --- a/drivers/can/can_loopback.c +++ b/drivers/can/can_loopback.c @@ -460,9 +460,9 @@ static int can_loopback_init(const struct device *dev) #define CAN_LOOPBACK_INIT(inst) \ static struct can_loopback_data can_loopback_dev_data_##inst; \ \ - DEVICE_DT_INST_DEFINE(inst, &can_loopback_init, NULL, \ - &can_loopback_dev_data_##inst, NULL, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_loopback_driver_api); + CAN_DEVICE_DT_INST_DEFINE(inst, can_loopback_init, NULL, \ + &can_loopback_dev_data_##inst, NULL, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY,\ + &can_loopback_driver_api); DT_INST_FOREACH_STATUS_OKAY(CAN_LOOPBACK_INIT) diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index d91a73602d4..7de5d714fee 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -1057,8 +1057,8 @@ static int mcp2515_init(const struct device *dev) .max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(inst, 1000000), \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, &mcp2515_init, NULL, &mcp2515_data_##inst, \ - &mcp2515_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_api_funcs); + CAN_DEVICE_DT_INST_DEFINE(inst, mcp2515_init, NULL, &mcp2515_data_##inst, \ + &mcp2515_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_api_funcs); DT_INST_FOREACH_STATUS_OKAY(MCP2515_INIT) diff --git a/drivers/can/can_native_posix_linux.c b/drivers/can/can_native_posix_linux.c index c3a12c9441f..d03ca78841e 100644 --- a/drivers/can/can_native_posix_linux.c +++ b/drivers/can/can_native_posix_linux.c @@ -488,9 +488,9 @@ static const struct can_npl_config can_npl_cfg_##inst = { \ \ static struct can_npl_data can_npl_data_##inst; \ \ -DEVICE_DT_INST_DEFINE(inst, &can_npl_init, NULL, \ - &can_npl_data_##inst, &can_npl_cfg_##inst, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_npl_driver_api); +CAN_DEVICE_DT_INST_DEFINE(inst, can_npl_init, NULL, \ + &can_npl_data_##inst, &can_npl_cfg_##inst, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_npl_driver_api); DT_INST_FOREACH_STATUS_OKAY(CAN_NATIVE_POSIX_LINUX_INIT) diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index a601399e82e..bf6b4dd86f3 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -1092,14 +1092,14 @@ static const struct can_driver_api can_nxp_s32_driver_api = { { \ return can_nxp_s32_init(dev); \ } \ - DEVICE_DT_DEFINE(CAN_NXP_S32_NODE(n), \ - &can_nxp_s32_##n##_init, \ - NULL, \ - &can_nxp_s32_data_##n, \ - &can_nxp_s32_config_##n, \ - POST_KERNEL, \ - CONFIG_CAN_INIT_PRIORITY, \ - &can_nxp_s32_driver_api); + CAN_DEVICE_DT_DEFINE(CAN_NXP_S32_NODE(n), \ + can_nxp_s32_##n##_init, \ + NULL, \ + &can_nxp_s32_data_##n, \ + &can_nxp_s32_config_##n, \ + POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, \ + &can_nxp_s32_driver_api); #if DT_NODE_HAS_STATUS(CAN_NXP_S32_NODE(0), okay) CAN_NXP_S32_INIT_DEVICE(0) diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index cbba04d84ae..b99b1f390ec 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -1189,10 +1189,10 @@ static const struct can_stm32_config can_stm32_cfg_##inst = { \ static struct can_stm32_data can_stm32_dev_data_##inst; #define CAN_STM32_DEFINE_INST(inst) \ -DEVICE_DT_INST_DEFINE(inst, &can_stm32_init, NULL, \ - &can_stm32_dev_data_##inst, &can_stm32_cfg_##inst, \ - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ - &can_api_funcs); +CAN_DEVICE_DT_INST_DEFINE(inst, can_stm32_init, NULL, \ + &can_stm32_dev_data_##inst, &can_stm32_cfg_##inst, \ + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_api_funcs); #define CAN_STM32_INST(inst) \ CAN_STM32_IRQ_INST(inst) \ From d30ec30a85bb872f10d644ef1defccbf7e3b51d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Sep 2023 15:21:21 +0200 Subject: [PATCH 0904/4498] doc: guides: Update PDF output path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The zephyr.pdf file is to be found in _build/latex folder, not _build/pdf. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/generation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index 7e985dbda65..7c5466ee5ed 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -220,7 +220,7 @@ folder, here are the commands to generate the html content locally: Depending on your development system, it will take up to 15 minutes to collect and generate the HTML content. When done, you can view the HTML output with your browser started at ``doc/_build/html/index.html`` and -if generated, the PDF file is available at ``doc/_build/pdf/zephyr.pdf``. +if generated, the PDF file is available at ``doc/_build/latex/zephyr.pdf``. If you want to build the documentation from scratch just delete the contents of the build folder and run ``cmake`` and then ``ninja`` again. From ee3b9c117e40ea609d2c0d0c37c62bb8e7694e2a Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Wed, 23 Aug 2023 22:24:56 +1000 Subject: [PATCH 0905/4498] sensor: vl53l0x: pm resume fix When active XSHUT resets the chip so we must re-initialise chip when resuming from PM suspend. Signed-off-by: Nick Ward --- drivers/sensor/vl53l0x/vl53l0x.c | 60 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/sensor/vl53l0x/vl53l0x.c b/drivers/sensor/vl53l0x/vl53l0x.c index 33143656443..6fc675a7934 100644 --- a/drivers/sensor/vl53l0x/vl53l0x.c +++ b/drivers/sensor/vl53l0x/vl53l0x.c @@ -300,36 +300,6 @@ static const struct sensor_driver_api vl53l0x_api_funcs = { .channel_get = vl53l0x_channel_get, }; -#ifdef CONFIG_PM_DEVICE -static int vl53l0x_pm_action(const struct device *dev, - enum pm_device_action action) -{ - const struct vl53l0x_config *const config = dev->config; - int ret; - - switch (action) { - case PM_DEVICE_ACTION_RESUME: - ret = gpio_pin_set_dt(&config->xshut, 0); - if (ret < 0) { - LOG_ERR("[%s] XSHUT pin inactive", dev->name); - return ret; - } - break; - case PM_DEVICE_ACTION_SUSPEND: - ret = gpio_pin_set_dt(&config->xshut, 1); - if (ret < 0) { - LOG_ERR("[%s] XSHUT pin active", dev->name); - return ret; - } - break; - default: - return -ENOTSUP; - } - - return 0; -} -#endif - static int vl53l0x_init(const struct device *dev) { int r; @@ -378,6 +348,36 @@ static int vl53l0x_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int vl53l0x_pm_action(const struct device *dev, + enum pm_device_action action) +{ + const struct vl53l0x_config *const config = dev->config; + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = vl53l0x_init(dev); + if (ret != 0) { + LOG_ERR("resume init: %d", ret); + } + break; + case PM_DEVICE_ACTION_SUSPEND: + /* HW Standby */ + ret = gpio_pin_set_dt(&config->xshut, 1); + if (ret < 0) { + LOG_ERR("[%s] XSHUT pin active", dev->name); + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif + #define VL53L0X_INIT(inst) \ static struct vl53l0x_config vl53l0x_##inst##_config = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ From 667a37374ce346ae4178ff65fc276daa23eeb856 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 21 Sep 2023 12:46:35 +0000 Subject: [PATCH 0906/4498] ci: workflows: run twister tests on collab branches Include CI runs to push and pull request against collab- branches so that thay can be used for detecting CI breakages before trying to open PRs against main. Signed-off-by: Fabio Baltieri --- .github/workflows/twister.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 4b414a7c9b4..52316f58a6a 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -5,10 +5,12 @@ on: branches: - main - v*-branch + - collab-* pull_request_target: branches: - main - v*-branch + - collab-* schedule: # Run at 03:00 UTC on every Sunday - cron: '0 3 * * 0' From 3ebb8953e4769697ee7a3c203ee3339e3c34828d Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0907/4498] samples: net: wifi: support esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- samples/net/wifi/boards/esp32s3_luatos_core.conf | 11 +++++++++++ samples/net/wifi/boards/esp32s3_luatos_core.overlay | 9 +++++++++ samples/net/wifi/boards/esp32s3_luatos_core_usb.conf | 11 +++++++++++ .../net/wifi/boards/esp32s3_luatos_core_usb.overlay | 9 +++++++++ 4 files changed, 40 insertions(+) create mode 100644 samples/net/wifi/boards/esp32s3_luatos_core.conf create mode 100644 samples/net/wifi/boards/esp32s3_luatos_core.overlay create mode 100644 samples/net/wifi/boards/esp32s3_luatos_core_usb.conf create mode 100644 samples/net/wifi/boards/esp32s3_luatos_core_usb.overlay diff --git a/samples/net/wifi/boards/esp32s3_luatos_core.conf b/samples/net/wifi/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..a72fdf39efa --- /dev/null +++ b/samples/net/wifi/boards/esp32s3_luatos_core.conf @@ -0,0 +1,11 @@ +CONFIG_WIFI=y + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y + +CONFIG_NET_LOG=y diff --git a/samples/net/wifi/boards/esp32s3_luatos_core.overlay b/samples/net/wifi/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..4d69fe29493 --- /dev/null +++ b/samples/net/wifi/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; diff --git a/samples/net/wifi/boards/esp32s3_luatos_core_usb.conf b/samples/net/wifi/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..a72fdf39efa --- /dev/null +++ b/samples/net/wifi/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1,11 @@ +CONFIG_WIFI=y + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y + +CONFIG_NET_LOG=y diff --git a/samples/net/wifi/boards/esp32s3_luatos_core_usb.overlay b/samples/net/wifi/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..4d69fe29493 --- /dev/null +++ b/samples/net/wifi/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; From 196ce41f63b7015ad0bba0138370a493e9149ccc Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0908/4498] samples: subsys: settings: add esp32s3_luatos_core add support for esp32s3_luatos_core Signed-off-by: YuLong Yao --- samples/subsys/settings/boards/esp32s3_luatos_core.conf | 4 ++++ samples/subsys/settings/boards/esp32s3_luatos_core_usb.conf | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 samples/subsys/settings/boards/esp32s3_luatos_core.conf create mode 100644 samples/subsys/settings/boards/esp32s3_luatos_core_usb.conf diff --git a/samples/subsys/settings/boards/esp32s3_luatos_core.conf b/samples/subsys/settings/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..498fb072287 --- /dev/null +++ b/samples/subsys/settings/boards/esp32s3_luatos_core.conf @@ -0,0 +1,4 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/samples/subsys/settings/boards/esp32s3_luatos_core_usb.conf b/samples/subsys/settings/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..498fb072287 --- /dev/null +++ b/samples/subsys/settings/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1,4 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y From 24b35d0ddbbe34a9800285d46554fa69ed7af378 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0909/4498] samples: drivers: adc: add esp32s3_luatos_core add support for esp32s3_luatos_core Signed-off-by: YuLong Yao --- .../adc/boards/esp32s3_luatos_core.overlay | 41 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 41 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 samples/drivers/adc/boards/esp32s3_luatos_core.overlay create mode 100644 samples/drivers/adc/boards/esp32s3_luatos_core_usb.overlay diff --git a/samples/drivers/adc/boards/esp32s3_luatos_core.overlay b/samples/drivers/adc/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..d43209179f7 --- /dev/null +++ b/samples/drivers/adc/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = + <&adc0 0>, + <&adc1 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/boards/esp32s3_luatos_core_usb.overlay b/samples/drivers/adc/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..d43209179f7 --- /dev/null +++ b/samples/drivers/adc/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = + <&adc0 0>, + <&adc1 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From e69616291baa5b7a56a17e3e0f0a04a449e3fe33 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0910/4498] samples: drivers: counter: add esp32s3_luatos_core add support for esp32s3_luatos_core Signed-off-by: YuLong Yao --- .../drivers/counter/alarm/boards/esp32s3_luatos_core.overlay | 3 +++ .../counter/alarm/boards/esp32s3_luatos_core_usb.overlay | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 samples/drivers/counter/alarm/boards/esp32s3_luatos_core.overlay create mode 100644 samples/drivers/counter/alarm/boards/esp32s3_luatos_core_usb.overlay diff --git a/samples/drivers/counter/alarm/boards/esp32s3_luatos_core.overlay b/samples/drivers/counter/alarm/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_usb.overlay b/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..241947b0643 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,3 @@ +&timer0 { + status = "okay"; +}; From cf8ac53d0d9d21124364a19f06c98efbf1bc8d2a Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0911/4498] samples: basic: blinky_pwm: add esp32s3_luatos_core add support for esp32s3_luatos_core Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.overlay | 44 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 samples/basic/blinky_pwm/boards/esp32s3_luatos_core.overlay create mode 100644 samples/basic/blinky_pwm/boards/esp32s3_luatos_core_usb.overlay diff --git a/samples/basic/blinky_pwm/boards/esp32s3_luatos_core.overlay b/samples/basic/blinky_pwm/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..61152f82f94 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 YuLong Yao + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + pwm-led0 = &pwm_led_blue; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led_blue: pwm_led_gpio0_10 { + label = "PWM LED0"; + pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/samples/basic/blinky_pwm/boards/esp32s3_luatos_core_usb.overlay b/samples/basic/blinky_pwm/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..61152f82f94 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 YuLong Yao + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + pwm-led0 = &pwm_led_blue; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led_blue: pwm_led_gpio0_10 { + label = "PWM LED0"; + pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; From 0b1cc77aff2b6f47985f2924a4e9f776d859456c Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 11:53:47 +0800 Subject: [PATCH 0912/4498] samples: sensor: qdec: add esp32s3_luatos_core add support for esp32s3_luatos_core Signed-off-by: YuLong Yao --- .../qdec/boards/esp32s3_luatos_core.overlay | 44 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 samples/sensor/qdec/boards/esp32s3_luatos_core.overlay create mode 100644 samples/sensor/qdec/boards/esp32s3_luatos_core_usb.overlay diff --git a/samples/sensor/qdec/boards/esp32s3_luatos_core.overlay b/samples/sensor/qdec/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..d347ea85345 --- /dev/null +++ b/samples/sensor/qdec/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include + +/ { + aliases { + qdec0 = &pcnt; + }; +}; + +&pinctrl { + pcnt_default: pcnt_default { + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; +}; + +&pcnt { + pinctrl-0 = <&pcnt_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + unit0@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + filter = <100>; + channelA@0 { + reg = <0>; + sig-pos-mode = <2>; + sig-neg-mode = <1>; + ctrl-h-mode = <0>; + ctrl-l-mode = <1>; + }; + }; +}; diff --git a/samples/sensor/qdec/boards/esp32s3_luatos_core_usb.overlay b/samples/sensor/qdec/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..d347ea85345 --- /dev/null +++ b/samples/sensor/qdec/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include + +/ { + aliases { + qdec0 = &pcnt; + }; +}; + +&pinctrl { + pcnt_default: pcnt_default { + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; +}; + +&pcnt { + pinctrl-0 = <&pcnt_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + unit0@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + filter = <100>; + channelA@0 { + reg = <0>; + sig-pos-mode = <2>; + sig-neg-mode = <1>; + ctrl-h-mode = <0>; + ctrl-l-mode = <1>; + }; + }; +}; From 36cd04c8e5cba20384ffe4003213d1b98e83477b Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:04:24 +0800 Subject: [PATCH 0913/4498] tests: drivers: adc: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../adc_api/boards/esp32s3_luatos_core.conf | 1 + .../boards/esp32s3_luatos_core.overlay | 39 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.conf | 1 + .../boards/esp32s3_luatos_core_usb.overlay | 39 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.conf create mode 100644 tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.conf create mode 100644 tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.conf b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..b6c5c80f924 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_ADC_ASYNC=n diff --git a/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.overlay b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..76683e1e993 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + + / { + zephyr,user { + io-channels = <&adc0 9>, <&adc1 0>; + }; + }; + + &adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + }; + + &adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + }; diff --git a/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.conf b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..b6c5c80f924 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_ADC_ASYNC=n diff --git a/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..76683e1e993 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + + / { + zephyr,user { + io-channels = <&adc0 9>, <&adc1 0>; + }; + }; + + &adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + }; + + &adc1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + }; From b89e90b2b53e1582154dabd85de44f12036500fb Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:04:52 +0800 Subject: [PATCH 0914/4498] tests: drivers: counter: add esp32s3_luatos_core add overlay for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../counter_basic_api/boards/esp32s3_luatos_core.overlay | 3 +++ .../counter_basic_api/boards/esp32s3_luatos_core_usb.overlay | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core.overlay b/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..2b3ef4f24ca --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,3 @@ +&timer3 { + status = "okay"; +}; diff --git a/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..2b3ef4f24ca --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,3 @@ +&timer3 { + status = "okay"; +}; From a553ab97bf54dba7c69cfc3f764b0ac4caf39333 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:05:40 +0800 Subject: [PATCH 0915/4498] tests: drivers: dma: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.conf | 2 ++ .../boards/esp32s3_luatos_core.overlay | 11 +++++++++++ .../boards/esp32s3_luatos_core_usb.conf | 2 ++ .../boards/esp32s3_luatos_core_usb.overlay | 11 +++++++++++ 4 files changed, 26 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.conf b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..d8c5932fbe9 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=5 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=0 diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.overlay b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..ca3f3ca2c99 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.conf b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..d8c5932fbe9 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=5 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=0 diff --git a/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..ca3f3ca2c99 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; From 23253ab503b8074de524e14c1c151fd7cee97248 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:05:51 +0800 Subject: [PATCH 0916/4498] tests: drivers: dma: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../dma/loop_transfer/boards/esp32s3_luatos_core.conf | 2 ++ .../loop_transfer/boards/esp32s3_luatos_core.overlay | 11 +++++++++++ .../loop_transfer/boards/esp32s3_luatos_core_usb.conf | 2 ++ .../boards/esp32s3_luatos_core_usb.overlay | 11 +++++++++++ 4 files changed, 26 insertions(+) create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.conf b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..60eda4cd0fd --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR=4 +CONFIG_DMA_LOOP_TRANSFER_SIZE=4094 diff --git a/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.overlay b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..ca3f3ca2c99 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; diff --git a/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.conf b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..60eda4cd0fd --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR=4 +CONFIG_DMA_LOOP_TRANSFER_SIZE=4094 diff --git a/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..ca3f3ca2c99 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +test_dma0: &dma { }; From 6060082914879dabd15db4a19251e64bd3cc37db Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:06:03 +0800 Subject: [PATCH 0917/4498] tests: drivers: gpio: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.overlay | 13 +++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core.overlay b/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..6c4f3e2e226 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio0 4 0>; + in-gpios = <&gpio0 5 0>; + }; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..6c4f3e2e226 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio0 4 0>; + in-gpios = <&gpio0 5 0>; + }; +}; From 32fe3619b5b6f9428f7ec58f2241cf4d47524111 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:06:19 +0800 Subject: [PATCH 0918/4498] tests: drivers: pwm: add esp32s3_luatos_core add overlay for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.overlay | 35 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 35 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core.overlay b/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..23fd331d41a --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..23fd331d41a --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include + +/ { + aliases { + pwm-0 = &ledc0; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; From c884d7f0c491d838e5c6ee98cff34517474e4e10 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:06:47 +0800 Subject: [PATCH 0919/4498] tests: drivers: pwm: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.overlay | 37 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 37 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core.overlay b/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..4c9f9e5ff53 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + /* first index must be a 32-Bit timer */ + pwms = <&mcpwm0 0 0 PWM_POLARITY_NORMAL>, + <&mcpwm0 6 0 PWM_POLARITY_NORMAL>; + }; +}; + +&pinctrl { + mcpwm0_default: mcpwm0_default { + group1 { + pinmux = ; + output-enable; + }; + group2 { + pinmux = ; + }; + }; +}; + +&mcpwm0 { + pinctrl-0 = <&mcpwm0_default>; + pinctrl-names = "default"; + prescale = <255>; + prescale-timer0 = <103>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..4c9f9e5ff53 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + /* first index must be a 32-Bit timer */ + pwms = <&mcpwm0 0 0 PWM_POLARITY_NORMAL>, + <&mcpwm0 6 0 PWM_POLARITY_NORMAL>; + }; +}; + +&pinctrl { + mcpwm0_default: mcpwm0_default { + group1 { + pinmux = ; + output-enable; + }; + group2 { + pinmux = ; + }; + }; +}; + +&mcpwm0 { + pinctrl-0 = <&mcpwm0_default>; + pinctrl-names = "default"; + prescale = <255>; + prescale-timer0 = <103>; + status = "okay"; +}; From 676eed840cebef8f94d461d08a0c3e03754f0732 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:06:56 +0800 Subject: [PATCH 0920/4498] tests: drivers: spi: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.conf | 1 + .../boards/esp32s3_luatos_core.overlay | 40 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.conf | 1 + .../boards/esp32s3_luatos_core_usb.overlay | 40 +++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.conf b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..fb0909611c8 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_SPI_ESP32_INTERRUPT=y diff --git a/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.overlay b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..ce9c8e7891b --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Kumar Gala + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spim3_loopback: spim3_loopback { + group1 { + pinmux = ; + output-enable; /* Enable internal loopback */ + }; + group2 { + pinmux = ; + input-enable; /* Enable internal loopback */ + }; + group3 { + pinmux = , + ; + }; + }; +}; + +&spi3 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <100000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&spi3 { + dma-enabled; + pinctrl-0 = <&spim3_loopback>; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.conf b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..fb0909611c8 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_SPI_ESP32_INTERRUPT=y diff --git a/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..ce9c8e7891b --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Kumar Gala + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spim3_loopback: spim3_loopback { + group1 { + pinmux = ; + output-enable; /* Enable internal loopback */ + }; + group2 { + pinmux = ; + input-enable; /* Enable internal loopback */ + }; + group3 { + pinmux = , + ; + }; + }; +}; + +&spi3 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <100000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&spi3 { + dma-enabled; + pinctrl-0 = <&spim3_loopback>; +}; From 1a2a8fd49b543ff718841dc9922f2b80b3256537 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 14:03:53 +0800 Subject: [PATCH 0921/4498] tests: drivers: uart: add esp32s3_luatos_core add overlay and conf for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.conf | 1 + .../boards/esp32s3_luatos_core.overlay | 30 ++++++++++++++++ .../boards/esp32s3_luatos_core_usb.conf | 1 + .../boards/esp32s3_luatos_core_usb.overlay | 35 +++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.conf create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.overlay create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.conf create mode 100644 tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.conf b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.conf new file mode 100644 index 00000000000..73aff8957e7 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.conf @@ -0,0 +1 @@ +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.overlay b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..50d6012d7bd --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + dmas = <&dma 0>, <&dma 1>; + dma-names = "rx", "tx"; +}; + +&dma { + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.conf b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.conf new file mode 100644 index 00000000000..73aff8957e7 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.conf @@ -0,0 +1 @@ +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.overlay b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..c43f4e551ec --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2023 YuLong Yao + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + dmas = <&dma 0>, <&dma 1>; + dma-names = "rx", "tx"; +}; + +&dma { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; From 21fcf61c87a4e0712e45c958f15d393f9def20a8 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 10 Sep 2023 12:07:37 +0800 Subject: [PATCH 0922/4498] tests: drivers: debug: add esp32s3_luatos_core add overlay for esp32s3_luatos_core board Signed-off-by: YuLong Yao --- .../boards/esp32s3_luatos_core.overlay | 25 +++++++++++++++++++ .../boards/esp32s3_luatos_core_usb.overlay | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core.overlay create mode 100644 tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core_usb.overlay diff --git a/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core.overlay b/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core.overlay new file mode 100644 index 00000000000..eb707ee7221 --- /dev/null +++ b/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + partitions { + /* + * Reduce storage_partition to make space for + * coredump_partition + */ + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00005000>; + }; + + coredump_partition: partition@255000 { + label = "coredump-partition"; + reg = <0x255000 DT_SIZE_K(4)>; + }; + + }; +}; diff --git a/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core_usb.overlay b/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core_usb.overlay new file mode 100644 index 00000000000..eb707ee7221 --- /dev/null +++ b/tests/subsys/debug/coredump_backends/boards/esp32s3_luatos_core_usb.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + partitions { + /* + * Reduce storage_partition to make space for + * coredump_partition + */ + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00005000>; + }; + + coredump_partition: partition@255000 { + label = "coredump-partition"; + reg = <0x255000 DT_SIZE_K(4)>; + }; + + }; +}; From 2e5f56665be7fe24c5d4d212c6e007f758df3544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 14 Sep 2023 20:00:15 +0200 Subject: [PATCH 0923/4498] doc: tracing: fix formatting issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The list of user-defined functions in "User-Defined Tracing" section was not properly formatted (missing blank line). Switched the (broken) list to a code block to now provide C syntax highlighting. Signed-off-by: Benjamin Cabé --- doc/services/tracing/index.rst | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/doc/services/tracing/index.rst b/doc/services/tracing/index.rst index 48124416c8d..74212d2f5a1 100644 --- a/doc/services/tracing/index.rst +++ b/doc/services/tracing/index.rst @@ -154,23 +154,25 @@ Examples include: not be supported by the other tracing systems The following functions can be defined by the user: -- ``void sys_trace_thread_create_user(struct k_thread *thread)`` -- ``void sys_trace_thread_abort_user(struct k_thread *thread)`` -- ``void sys_trace_thread_suspend_user(struct k_thread *thread)`` -- ``void sys_trace_thread_resume_user(struct k_thread *thread)`` -- ``void sys_trace_thread_name_set_user(struct k_thread *thread)`` -- ``void sys_trace_thread_switched_in_user(struct k_thread *thread)`` -- ``void sys_trace_thread_switched_out_user(struct k_thread *thread)`` -- ``void sys_trace_thread_info_user(struct k_thread *thread)`` -- ``void sys_trace_thread_sched_ready_user(struct k_thread *thread)`` -- ``void sys_trace_thread_pend_user(struct k_thread *thread)`` -- ``void sys_trace_thread_priority_set_user(struct k_thread *thread, int prio)`` -- ``void sys_trace_isr_enter_user(int nested_interrupts)`` -- ``void sys_trace_isr_exit_user(int nested_interrupts)`` -- ``void sys_trace_idle_user()`` -Enable this format with the :kconfig:option:`CONFIG_TRACING_USER` option. +.. code-block:: c + + void sys_trace_thread_create_user(struct k_thread *thread); + void sys_trace_thread_abort_user(struct k_thread *thread); + void sys_trace_thread_suspend_user(struct k_thread *thread); + void sys_trace_thread_resume_user(struct k_thread *thread); + void sys_trace_thread_name_set_user(struct k_thread *thread); + void sys_trace_thread_switched_in_user(struct k_thread *thread); + void sys_trace_thread_switched_out_user(struct k_thread *thread); + void sys_trace_thread_info_user(struct k_thread *thread); + void sys_trace_thread_sched_ready_user(struct k_thread *thread); + void sys_trace_thread_pend_user(struct k_thread *thread); + void sys_trace_thread_priority_set_user(struct k_thread *thread, int prio); + void sys_trace_isr_enter_user(int nested_interrupts); + void sys_trace_isr_exit_user(int nested_interrupts); + void sys_trace_idle_user(); +Enable this format with the :kconfig:option:`CONFIG_TRACING_USER` option. Transport Backends ****************** From 341590545ac80b7a2abd9902b7f10d577323ccde Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 22 Sep 2023 10:58:48 +0000 Subject: [PATCH 0924/4498] tests: kernel: xip: exclude qemu_riscv32_xip This board seems to have issue with data alignemnt after 843f66f and is failing in CI. Exclude it while the problem is investigated. Signed-off-by: Fabio Baltieri --- tests/kernel/xip/testcase.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/kernel/xip/testcase.yaml b/tests/kernel/xip/testcase.yaml index 0992d219064..82cd883b6bc 100644 --- a/tests/kernel/xip/testcase.yaml +++ b/tests/kernel/xip/testcase.yaml @@ -7,6 +7,8 @@ tests: integration_platforms: - qemu_arc_em - qemu_x86_xip + platform_exclude: + - qemu_riscv32_xip # See issue #62975 arch.common.xip.minimallibc: filter: CONFIG_XIP and CONFIG_MINIMAL_LIBC_SUPPORTED tags: @@ -15,5 +17,7 @@ tests: integration_platforms: - qemu_arc_em - qemu_x86_xip + platform_exclude: + - qemu_riscv32_xip # See issue #62975 extra_configs: - CONFIG_MINIMAL_LIBC=y From 799c8ddf9f5e9d5f31cdad00f147cc17388dea63 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 22 Sep 2023 22:02:47 +0100 Subject: [PATCH 0925/4498] ci: doc-build: add a rebase step Add a rebase step after checkout for the documentation build CI run. This is in line with what pretty much all other workfloww already do, and means that if a PR is opened on a broken tree and the breakage get fixed, the PR run just have to be retried for the test to pass and we don't have to ask the authors to rebase and lose any pending approvals. Signed-off-by: Fabio Baltieri --- .github/workflows/doc-build.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 40e170ddc8a..351cb041a83 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -44,6 +44,20 @@ jobs: steps: - name: checkout uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Rebase + continue-on-error: true + env: + BASE_REF: ${{ github.base_ref }} + PR_HEAD: ${{ github.event.pull_request.head.sha }} + run: | + git config --global user.email "actions@zephyrproject.org" + git config --global user.name "Github Actions" + git rebase origin/${BASE_REF} + git log --graph --oneline HEAD...${PR_HEAD} - name: install-pkgs run: | From 51a300c66b5885d3ca6abeaca979e1d4d5bfcf49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 22 Sep 2023 16:20:54 +0700 Subject: [PATCH 0926/4498] boards: s32z270dc2_r52: remove duplicated DT include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This DT source is already included on each RTU board. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 0176ebc4458..14a1375a2e0 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include "s32z270dc2_r52-pinctrl-common.dtsi" &stm0 { From 0459d594a2f0212e13217ca05042a9e466c00d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Fri, 22 Sep 2023 07:17:13 +0200 Subject: [PATCH 0927/4498] MAINTAINERS.yml: Move LoRa to subsys section and add LoRaWAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LoRaWAN is not a driver. LoRa and LoRaWAN together are better categorized as a subsystem. Signed-off-by: Martin Jäger --- MAINTAINERS.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 38a36545fd5..b3c11d3cf50 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1120,24 +1120,6 @@ Release Notes: labels: - "area: LED" -"Drivers: lora": - status: maintained - maintainers: - - Mani-Sadhasivam - collaborators: - - mniestroj - - JordanYates - files: - - drivers/lora/ - - include/zephyr/drivers/lora.h - - samples/drivers/lora/ - - include/zephyr/lorawan/ - - subsys/lorawan/ - - samples/subsys/lorawan/ - - doc/connectivity/lora_lorawan/index.rst - labels: - - "area: LoRa" - "Drivers: Modem": status: maintained maintainers: @@ -1718,6 +1700,24 @@ Logging: labels: - "area: Logging" +LoRa and LoRaWAN: + status: maintained + maintainers: + - Mani-Sadhasivam + collaborators: + - mniestroj + - JordanYates + files: + - drivers/lora/ + - include/zephyr/drivers/lora.h + - samples/drivers/lora/ + - include/zephyr/lorawan/ + - subsys/lorawan/ + - samples/subsys/lorawan/ + - doc/connectivity/lora_lorawan/index.rst + labels: + - "area: LoRa" + MAINTAINERS file: status: maintained maintainers: From 81e641f8b67a5ee88aa3a46efdb471ba9afb62c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Fri, 22 Sep 2023 07:21:27 +0200 Subject: [PATCH 0928/4498] MAINTAINERS.yml: LoRa and LoRaWAN: make JordanYates the maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous maintainer Mani-Sadhasivam is presumably busy with other work and has not been very active in Zephyr recently. JordanYates has reviewed all recent PRs and driven the discussions around LoRa/LoRaWAN, so he should become the new maintainer. Signed-off-by: Martin Jäger --- MAINTAINERS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b3c11d3cf50..6f673a4d513 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1703,10 +1703,10 @@ Logging: LoRa and LoRaWAN: status: maintained maintainers: - - Mani-Sadhasivam + - JordanYates collaborators: + - Mani-Sadhasivam - mniestroj - - JordanYates files: - drivers/lora/ - include/zephyr/drivers/lora.h From bedf5dd5f991e7afe73a717254dd32be0f08ed43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Fri, 22 Sep 2023 07:25:49 +0200 Subject: [PATCH 0929/4498] MAINTAINERS.yml: LoRa and LoRaWAN: add martinjaeger as collaborator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit He has contributed time synchronization services and some bug fixes in the past and is going to work con Class B support in the future. Signed-off-by: Martin Jäger --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 6f673a4d513..dc5867e3f59 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1706,6 +1706,7 @@ LoRa and LoRaWAN: - JordanYates collaborators: - Mani-Sadhasivam + - martinjaeger - mniestroj files: - drivers/lora/ From a1e2fdcc4d2ea5904d5d650dc427cbd6b2fbec4e Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 10 Sep 2023 17:56:31 +0300 Subject: [PATCH 0930/4498] drivers: mdio: add bit-bang driver Add MDIO driver that works through GPIO pins. This driver is useful when a microcontroller doesn't have MDIO bus or when multiple separate MDIO buses are required. The driver provides access to the MDIO bus through GPIO pins for any SoC that has GPIO pin control available. Signed-off-by: Aleksandr Senin --- drivers/mdio/CMakeLists.txt | 1 + drivers/mdio/Kconfig | 1 + drivers/mdio/Kconfig.gpio | 9 ++ drivers/mdio/mdio_gpio.c | 195 ++++++++++++++++++++++++ drivers/mdio/mdio_shell.c | 2 + dts/bindings/mdio/zephyr,mdio-gpio.yaml | 19 +++ 6 files changed, 227 insertions(+) create mode 100644 drivers/mdio/Kconfig.gpio create mode 100644 drivers/mdio/mdio_gpio.c create mode 100644 dts/bindings/mdio/zephyr,mdio-gpio.yaml diff --git a/drivers/mdio/CMakeLists.txt b/drivers/mdio/CMakeLists.txt index 7fc03a8fc8f..4972626cdb5 100644 --- a/drivers/mdio/CMakeLists.txt +++ b/drivers/mdio/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_MDIO_ATMEL_SAM mdio_sam.c) zephyr_library_sources_ifdef(CONFIG_MDIO_ESP32 mdio_esp32.c) zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_S32_NETC mdio_nxp_s32_netc.c) zephyr_library_sources_ifdef(CONFIG_MDIO_ADIN2111 mdio_adin2111.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_GPIO mdio_gpio.c) diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index 0f2d3b84a84..ddca38359fa 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -29,6 +29,7 @@ source "drivers/mdio/Kconfig.esp32" source "drivers/mdio/Kconfig.sam" source "drivers/mdio/Kconfig.nxp_s32" source "drivers/mdio/Kconfig.adin2111" +source "drivers/mdio/Kconfig.gpio" config MDIO_INIT_PRIORITY int "Init priority" diff --git a/drivers/mdio/Kconfig.gpio b/drivers/mdio/Kconfig.gpio new file mode 100644 index 00000000000..1ab5dd70dc4 --- /dev/null +++ b/drivers/mdio/Kconfig.gpio @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Aleksandr Senin +# SPDX-License-Identifier: Apache-2.0 + +config MDIO_GPIO + bool "GPIO bitbang MDIO controller driver" + default y + depends on DT_HAS_ZEPHYR_MDIO_GPIO_ENABLED + help + Enable software driven (bit banging) MDIO support using GPIO pins diff --git a/drivers/mdio/mdio_gpio.c b/drivers/mdio/mdio_gpio.c new file mode 100644 index 00000000000..46b99963d3c --- /dev/null +++ b/drivers/mdio/mdio_gpio.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2023 Aleksandr Senin + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_mdio_gpio + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mdio_gpio, CONFIG_MDIO_LOG_LEVEL); + +#define MDIO_GPIO_READ_OP 0 +#define MDIO_GPIO_WRITE_OP 1 +#define MDIO_GPIO_MSB 0x80000000 + +struct mdio_gpio_data { + struct k_sem sem; +}; + +struct mdio_gpio_config { + struct gpio_dt_spec mdc_gpio; + struct gpio_dt_spec mdio_gpio; +}; + +static ALWAYS_INLINE void mdio_gpio_clock_the_bit(const struct mdio_gpio_config *dev_cfg) +{ + k_busy_wait(1); + gpio_pin_set_dt(&dev_cfg->mdc_gpio, 1); + k_busy_wait(1); + gpio_pin_set_dt(&dev_cfg->mdc_gpio, 0); +} + +static ALWAYS_INLINE void mdio_gpio_dir(const struct mdio_gpio_config *dev_cfg, uint8_t dir) +{ + gpio_pin_configure_dt(&dev_cfg->mdio_gpio, dir ? GPIO_OUTPUT_ACTIVE : GPIO_INPUT); + if (dir == 0) { + mdio_gpio_clock_the_bit(dev_cfg); + } +} + +static ALWAYS_INLINE void mdio_gpio_read(const struct mdio_gpio_config *dev_cfg, uint16_t *pdata) +{ + uint16_t data = 0; + + for (uint16_t i = 0; i < 16; i++) { + data <<= 1; + mdio_gpio_clock_the_bit(dev_cfg); + if (gpio_pin_get_dt(&dev_cfg->mdio_gpio) == 1) { + data |= 1; + } + } + + *pdata = data; +} + +static ALWAYS_INLINE void mdio_gpio_write(const struct mdio_gpio_config *dev_cfg, + uint32_t data, uint8_t len) +{ + uint32_t v_data = data; + uint32_t v_len = len; + + v_data <<= 32 - v_len; + for (; v_len > 0; v_len--) { + gpio_pin_set_dt(&dev_cfg->mdio_gpio, (v_data & MDIO_GPIO_MSB) ? 1 : 0); + mdio_gpio_clock_the_bit(dev_cfg); + v_data <<= 1; + } +} + +static int mdio_gpio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, uint8_t rw, + uint16_t data_in, uint16_t *data_out) +{ + const struct mdio_gpio_config *const dev_cfg = dev->config; + struct mdio_gpio_data *const dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); + + /* DIR: output */ + mdio_gpio_dir(dev_cfg, MDIO_GPIO_WRITE_OP); + /* PRE32: 32 bits '1' for sync*/ + mdio_gpio_write(dev_cfg, 0xFFFFFFFF, 32); + /* ST: 2 bits start of frame */ + mdio_gpio_write(dev_cfg, 0x1, 2); + /* OP: 2 bits opcode, read '10' or write '01' */ + mdio_gpio_write(dev_cfg, rw ? 0x1 : 0x2, 2); + /* PA5: 5 bits PHY address */ + mdio_gpio_write(dev_cfg, prtad, 5); + /* RA5: 5 bits register address */ + mdio_gpio_write(dev_cfg, devad, 5); + + if (rw) { /* Write data */ + /* TA: 2 bits turn-around */ + mdio_gpio_write(dev_cfg, 0x2, 2); + mdio_gpio_write(dev_cfg, data_in, 16); + } else { /* Read data */ + /* Release the MDIO line */ + mdio_gpio_dir(dev_cfg, MDIO_GPIO_READ_OP); + mdio_gpio_read(dev_cfg, data_out); + } + + /* DIR: input. Tristate MDIO line */ + mdio_gpio_dir(dev_cfg, MDIO_GPIO_READ_OP); + + k_sem_give(&dev_data->sem); + + return 0; +} + +static int mdio_gpio_read_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t *data) +{ + return mdio_gpio_transfer(dev, prtad, devad, MDIO_GPIO_READ_OP, 0, data); +} + +static int mdio_gpio_write_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t data) +{ + return mdio_gpio_transfer(dev, prtad, devad, MDIO_GPIO_WRITE_OP, data, NULL); +} + +static int mdio_gpio_initialize(const struct device *dev) +{ + const struct mdio_gpio_config *const dev_cfg = dev->config; + struct mdio_gpio_data *const dev_data = dev->data; + int rc; + + k_sem_init(&dev_data->sem, 1, 1); + + if (!device_is_ready(dev_cfg->mdc_gpio.port)) { + LOG_ERR("GPIO port for MDC pin is not ready"); + return -ENODEV; + } + + if (!device_is_ready(dev_cfg->mdio_gpio.port)) { + LOG_ERR("GPIO port for MDIO pin is not ready"); + return -ENODEV; + } + + rc = gpio_pin_configure_dt(&dev_cfg->mdc_gpio, GPIO_OUTPUT_INACTIVE); + if (rc < 0) { + LOG_ERR("Couldn't configure MDC pin; (%d)", rc); + return rc; + } + + rc = gpio_pin_configure_dt(&dev_cfg->mdio_gpio, GPIO_INPUT); + if (rc < 0) { + LOG_ERR("Couldn't configure MDIO pin; (%d)", rc); + return rc; + } + + return 0; +} + +static void mdio_gpio_bus_enable(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static void mdio_gpio_bus_disable(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static const struct mdio_driver_api mdio_gpio_driver_api = { + .read = mdio_gpio_read_mmi, + .write = mdio_gpio_write_mmi, + .bus_enable = mdio_gpio_bus_enable, + .bus_disable = mdio_gpio_bus_disable, +}; + +#define MDIO_GPIO_CONFIG(inst) \ + static struct mdio_gpio_config mdio_gpio_dev_config_##inst = { \ + .mdc_gpio = GPIO_DT_SPEC_INST_GET(inst, mdc_gpios), \ + .mdio_gpio = GPIO_DT_SPEC_INST_GET(inst, mdio_gpios), \ + }; + +#define MDIO_GPIO_PROTOCOL_ASSERT(inst) \ + BUILD_ASSERT(DT_INST_ENUM_IDX(inst, protocol) == CLAUSE_22, \ + "MDIO GPIO only supports CLAUSE_22 protocol") + +#define MDIO_GPIO_DEVICE(inst) \ + MDIO_GPIO_PROTOCOL_ASSERT(inst); \ + MDIO_GPIO_CONFIG(inst); \ + static struct mdio_gpio_data mdio_gpio_dev_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, &mdio_gpio_initialize, NULL, &mdio_gpio_dev_data_##inst, \ + &mdio_gpio_dev_config_##inst, POST_KERNEL, \ + CONFIG_MDIO_INIT_PRIORITY, &mdio_gpio_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MDIO_GPIO_DEVICE) diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index 090cde16ece..9ca57e12c3e 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -24,6 +24,8 @@ LOG_MODULE_REGISTER(mdio_shell, CONFIG_LOG_DEFAULT_LEVEL); #define DT_DRV_COMPAT adi_adin2111_mdio #elif DT_HAS_COMPAT_STATUS_OKAY(smsc_lan91c111_mdio) #define DT_DRV_COMPAT smsc_lan91c111_mdio +#elif DT_HAS_COMPAT_STATUS_OKAY(zephyr_mdio_gpio) +#define DT_DRV_COMPAT zephyr_mdio_gpio #else #error "No known devicetree compatible match for MDIO shell" #endif diff --git a/dts/bindings/mdio/zephyr,mdio-gpio.yaml b/dts/bindings/mdio/zephyr,mdio-gpio.yaml new file mode 100644 index 00000000000..6e847f969e4 --- /dev/null +++ b/dts/bindings/mdio/zephyr,mdio-gpio.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Aleksandr Senin +# SPDX-License-Identifier: Apache-2.0 + +description: Zephyr MDIO bitbang driver + +compatible: "zephyr,mdio-gpio" + +include: mdio-controller.yaml + +properties: + mdc-gpios: + type: phandle-array + required: true + description: GPIO pin for the MDC + + mdio-gpios: + type: phandle-array + required: true + description: GPIO pin for the MDIO From cec9bc29ba0c5024f896da9edf53af66b1afba17 Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 10 Sep 2023 18:02:01 +0300 Subject: [PATCH 0931/4498] tests: drivers: build_all: mdio: add bit bang testsuite - Add mdio to a build_all testsuite - Add mdio bit bang to a build_all testsuite Signed-off-by: Aleksandr Senin --- tests/drivers/build_all/mdio/CMakeLists.txt | 8 ++++ tests/drivers/build_all/mdio/app.overlay | 42 +++++++++++++++++++++ tests/drivers/build_all/mdio/prj.conf | 5 +++ tests/drivers/build_all/mdio/src/main.c | 10 +++++ tests/drivers/build_all/mdio/testcase.yaml | 8 ++++ 5 files changed, 73 insertions(+) create mode 100644 tests/drivers/build_all/mdio/CMakeLists.txt create mode 100644 tests/drivers/build_all/mdio/app.overlay create mode 100644 tests/drivers/build_all/mdio/prj.conf create mode 100644 tests/drivers/build_all/mdio/src/main.c create mode 100644 tests/drivers/build_all/mdio/testcase.yaml diff --git a/tests/drivers/build_all/mdio/CMakeLists.txt b/tests/drivers/build_all/mdio/CMakeLists.txt new file mode 100644 index 00000000000..518596a02f7 --- /dev/null +++ b/tests/drivers/build_all/mdio/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(build_all) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/build_all/mdio/app.overlay b/tests/drivers/build_all/mdio/app.overlay new file mode 100644 index 00000000000..82392465d23 --- /dev/null +++ b/tests/drivers/build_all/mdio/app.overlay @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Aleksandr Senin + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for testing driver builds + * + * Names in this file should be chosen in a way that won't conflict + * with real-world devicetree nodes, to allow these tests to run on + * (and be extended to test) real hardware. + */ + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_gpio: gpio@deadbeef { + compatible = "vnd,gpio"; + gpio-controller; + reg = <0xdeadbeef 0x1000>; + #gpio-cells = <0x2>; + status = "okay"; + }; + + test_mdio0: mdio@11112222 { + compatible = "zephyr,mdio-gpio"; + reg = <0x11112222 1>; + mdc-gpios = <&test_gpio 0 0>; + mdio-gpios = <&test_gpio 0 0>; + status = "okay"; + }; + + test_mdio1: mdio@33334444 { + compatible = "zephyr,mdio-gpio"; + reg = <0x33334444 1>; + mdc-gpios = <&test_gpio 0 0>; + mdio-gpios = <&test_gpio 0 0>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/build_all/mdio/prj.conf b/tests/drivers/build_all/mdio/prj.conf new file mode 100644 index 00000000000..1e4bd3763fb --- /dev/null +++ b/tests/drivers/build_all/mdio/prj.conf @@ -0,0 +1,5 @@ +CONFIG_TEST=y +CONFIG_TEST_USERSPACE=y +CONFIG_GPIO=y +CONFIG_MDIO=y +CONFIG_MDIO_GPIO=y diff --git a/tests/drivers/build_all/mdio/src/main.c b/tests/drivers/build_all/mdio/src/main.c new file mode 100644 index 00000000000..4c52a4c62a6 --- /dev/null +++ b/tests/drivers/build_all/mdio/src/main.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2023 Aleksandr Senin + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + return 0; +} diff --git a/tests/drivers/build_all/mdio/testcase.yaml b/tests/drivers/build_all/mdio/testcase.yaml new file mode 100644 index 00000000000..19e16e0f2be --- /dev/null +++ b/tests/drivers/build_all/mdio/testcase.yaml @@ -0,0 +1,8 @@ +common: + build_only: true + tags: + - drivers + - mdio +tests: + drivers.mdio.build: + platform_allow: qemu_cortex_m0 From c1ad82e5fbce7b8f24091d5e64a2f90d13bc1531 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 22 Sep 2023 13:24:29 +0200 Subject: [PATCH 0932/4498] drivers: can: mcux: flexcan: fix initial of CAN-FD timing when using TQs Fix the assignment of initial CAN bus timing parameters for the CAN-FD data phase. Fixes: #62979 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcux_flexcan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index d212903f34b..e5efe2e3065 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -1227,9 +1227,9 @@ static int mcux_flexcan_init(const struct device *dev) data->timing_data.phase_seg2); LOG_DBG("Sample-point err : %d", err); } else { - data->timing_data.prop_seg = config->prop_seg; - data->timing_data.phase_seg1 = config->phase_seg1; - data->timing_data.phase_seg2 = config->phase_seg2; + data->timing_data.prop_seg = config->prop_seg_data; + data->timing_data.phase_seg1 = config->phase_seg1_data; + data->timing_data.phase_seg2 = config->phase_seg2_data; err = can_calc_prescaler(dev, &data->timing_data, config->bitrate_data); if (err) { LOG_WRN("Bitrate error: %d", err); From 104ea2ccca1f62048fcc9535e182809ffdf6fd8b Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sat, 15 Apr 2023 17:26:09 -0700 Subject: [PATCH 0933/4498] modules: cmsis-dsp: add cmsis-dsp module Use CMSIS-DSP from its new realm. This also changes change how you initialize FFT tables as well to use arm_cfft_init_64_f32 if you know the FFT size in advance rather than the generic initialization arm_cfft_init_f32. Signed-off-by: Ryan McClelland --- MAINTAINERS.yml | 15 +- modules/cmsis/Kconfig | 8 - modules/cmsis/Kconfig.cmsis_dsp | 803 --------------- modules/cmsis_dsp/CMakeLists.txt | 931 ++++++++++++++++++ modules/cmsis_dsp/Kconfig | 79 ++ tests/benchmarks/cmsis_dsp/basicmath/prj.conf | 1 - tests/lib/cmsis_dsp/bayes/prj.conf | 1 - tests/lib/cmsis_dsp/complexmath/prj.conf | 1 - tests/lib/cmsis_dsp/distance/prj.conf | 1 - tests/lib/cmsis_dsp/fastmath/prj.conf | 1 - tests/lib/cmsis_dsp/filtering/prj.conf | 1 - tests/lib/cmsis_dsp/filtering/prj_base.conf | 1 - tests/lib/cmsis_dsp/interpolation/prj.conf | 1 - tests/lib/cmsis_dsp/matrix/prj.conf | 1 - tests/lib/cmsis_dsp/matrix/prj_base.conf | 1 - tests/lib/cmsis_dsp/quaternionmath/prj.conf | 1 - tests/lib/cmsis_dsp/statistics/prj.conf | 1 - tests/lib/cmsis_dsp/support/prj.conf | 1 - tests/lib/cmsis_dsp/svm/prj.conf | 1 - tests/lib/cmsis_dsp/transform/prj.conf | 1 - tests/lib/cmsis_dsp/transform/prj_base.conf | 1 - tests/subsys/dsp/basicmath/prj.conf | 1 - tests/subsys/dsp/basicmath/prj_arc.conf | 1 - west.yml | 3 + 24 files changed, 1026 insertions(+), 831 deletions(-) delete mode 100644 modules/cmsis/Kconfig.cmsis_dsp create mode 100644 modules/cmsis_dsp/CMakeLists.txt create mode 100644 modules/cmsis_dsp/Kconfig diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index dc5867e3f59..a1d0b8cc516 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -422,8 +422,9 @@ CMSIS-DSP integration: - stephanosio collaborators: - galak + - XenuIsWatching files: - - modules/cmsis/Kconfig.cmsis_dsp + - modules/cmsis_dsp/ - tests/benchmarks/cmsis_dsp/ - tests/lib/cmsis_dsp/ labels: @@ -2940,11 +2941,21 @@ West: - povergoing files: - modules/cmsis/Kconfig - - modules/cmsis/Kconfig.cmsis_dsp - modules/cmsis/Kconfig.cmsis_nn labels: - "area: ARM" +"West project: cmsis-dsp": + status: maintained + maintainers: + - XenuIsWatching + collaborators: + - stephanosio + files: + - modules/cmsis_dsp/ + labels: + - "area: ARM" + "West project: edtt": status: maintained maintainers: diff --git a/modules/cmsis/Kconfig b/modules/cmsis/Kconfig index 0bbcddd55e7..2ef84f0bfce 100644 --- a/modules/cmsis/Kconfig +++ b/modules/cmsis/Kconfig @@ -20,14 +20,6 @@ config HAS_CMSIS_CORE_M endif -menuconfig CMSIS_DSP - bool "CMSIS-DSP Library Support" - select REQUIRES_FULL_LIBC if !ARCH_POSIX - -if CMSIS_DSP -source "modules/cmsis/Kconfig.cmsis_dsp" -endif - menuconfig CMSIS_NN bool "CMSIS-NN Library Support" depends on CPU_CORTEX_M diff --git a/modules/cmsis/Kconfig.cmsis_dsp b/modules/cmsis/Kconfig.cmsis_dsp deleted file mode 100644 index 6b5f936ccc3..00000000000 --- a/modules/cmsis/Kconfig.cmsis_dsp +++ /dev/null @@ -1,803 +0,0 @@ -# Copyright (c) 2020 Stephanos Ioannidis -# SPDX-License-Identifier: Apache-2.0 - -comment "Components" - -config CMSIS_DSP_BASICMATH - bool "Basic Math Functions" - default y - help - This option enables the Basic Math Functions, which support the - following operations: - - * Elementwise Clipping - * Vector Absolute Value - * Vector Addition - * Vector Subtraction - * Vector Multiplication - * Vector Dot Product - * Vector Absolute Value - * Vector Negate - * Vector Offset - * Vector Scale - * Vector Shift - * Vector Bitwise AND - * Vector Bitwise OR - * Vector Bitwise Exclusive OR - * Vector Bitwise NOT - -config CMSIS_DSP_COMPLEXMATH - bool "Complex Math Functions" - imply CMSIS_DSP_FASTMATH - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Complex Math Functions, which support the - following operations: - - * Complex-by-Complex Multiplication - * Complex-by-Real Multiplication - * Complex Dot Product - * Complex Magnitude - * Complex Magnitude Squared - * Complex Conjugate - -config CMSIS_DSP_CONTROLLER - bool "Controller Functions" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Controller Functions, which support the - following operations: - - * PID Control - * Vector Clarke Transform - * Vector Inverse Clarke Transform - * Vector Park Transform - * Vector Inverse Park Transform - * Sine-Cosine - - These functions can be used to implement a generic PID controller, as - well as field oriented motor control using Space Vector Modulation - algorithm. - -config CMSIS_DSP_FASTMATH - bool "Fast Math Functions" - select CMSIS_DSP_TABLES - imply CMSIS_DSP_TABLES_ALL_FAST - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Fast Math Functions, which support the - following operations: - - * Fixed-Point Division - * Sine - * Cosine - * Square Root - -config CMSIS_DSP_FILTERING - bool "Filtering Functions" - imply CMSIS_DSP_FASTMATH - imply CMSIS_DSP_SUPPORT - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Filtering Functions, which support the - following operations: - - * Convolution - * Partial Convolution - * Correlation - * Levinson-Durbin Algorithm - - The following filter types are supported: - - * FIR (finite impulse response) Filter - * FIR Lattice Filter - * FIR Sparse Filter - * FIR Filter with Decimator - * FIR Filter with Interpolator - * IIR (infinite impulse response) Lattice Filter - * Biquad Cascade IIR Filter, Direct Form I Structure - * Biquad Cascade IIR Filter, Direct Form II Transposed Structure - * High Precision Q31 Biquad Cascade Filter - * LMS (least mean square) Filter - * Normalized LMS Filter - -config CMSIS_DSP_INTERPOLATION - bool "Interpolation Functions" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Interpolation Functions, which support the - following operations: - - * Bilinear Interpolation - * Linear Interpolation - * Cubic Spline Interpolation - -config CMSIS_DSP_MATRIX - bool "Matrix Functions" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Matrix Functions, which support the following - operations: - - * Matrix Initialization - * Matrix Addition - * Matrix Subtraction - * Matrix Multiplication - * Complex Matrix Multiplication - * Matrix Vector Multiplication - * Matrix Inverse - * Matrix Scale - * Matrix Transpose - * Complex Matrix Transpose - * Cholesky and LDLT Decompositions - -config CMSIS_DSP_QUATERNIONMATH - bool "Quaternion Math Functions" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Quaternion Math Functions, which support the - following operations: - - * Quaternion Conversions - * Quaternion Conjugate - * Quaternion Inverse - * Quaternion Norm - * Quaternion Normalization - * Quaternion Product - -config CMSIS_DSP_STATISTICS - bool "Statistics Functions" - imply CMSIS_DSP_BASICMATH - imply CMSIS_DSP_FASTMATH - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Statistics Functions, which support the - following operations: - - * Minimum - * Absolute Minimum - * Maximum - * Absolute Maximum - * Mean - * Root Mean Square (RMS) - * Variance - * Standard Deviation - * Power - * Entropy - * Kullback-Leibler Divergence - * LogSumExp (LSE) - -config CMSIS_DSP_SUPPORT - bool "Support Functions" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Support Functions, which support the - following operations: - - * Vector 8-bit Integer Value Conversion - * Vector 16-bit Integer Value Conversion - * Vector 32-bit Integer Value Conversion - * Vector 16-bit Floating-Point Value Conversion - * Vector 32-bit Floating-Point Value Conversion - * Vector Copy - * Vector Fill - * Vector Sorting - * Weighted Sum - * Barycenter - -config CMSIS_DSP_TRANSFORM - bool "Transform Functions" - select CMSIS_DSP_TABLES - imply CMSIS_DSP_TABLES_ALL_FFT - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Transform Functions, which support the - following transformations: - - * Real Fast Fourier Transform (RFFT) - * Complex Fast Fourier Transform (CFFT) - * Type IV Discrete Cosine Transform (DCT4) - -config CMSIS_DSP_SVM - bool "Support Vector Machine Functions" - select CMSIS_DSP_TABLES - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Support Vector Machine Functions, which - support the following algorithms: - - * Linear - * Polynomial - * Sigmoid - * Radial Basis Function (RBF) - -config CMSIS_DSP_BAYES - bool "Bayesian Estimators" - imply CMSIS_DSP_STATISTICS - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Bayesian Estimator Functions, which - implements the naive gaussian Bayes estimator. - -config CMSIS_DSP_DISTANCE - bool "Distance Functions" - imply CMSIS_DSP_STATISTICS - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the Distance Functions, which support the - following distance computation algorithms: - - * Boolean Vectors - * Hamming - * Jaccard - * Kulsinski - * Rogers-Tanimoto - * Russell-Rao - * Sokal-Michener - * Sokal-Sneath - * Yule - * Dice - - * Floating-Point Vectors - * Canberra - * Chebyshev - * Cityblock - * Correlation - * Cosine - * Euclidean - * Jensen-Shannon - * Minkowski - * Bray-Curtis - -menuconfig CMSIS_DSP_TABLES - bool "Look-up Tables" - depends on CPU_CORTEX || ARCH_POSIX - help - This option enables the static look-up tables used by the DSP - functions to compute results. - -if CMSIS_DSP_TABLES - -config CMSIS_DSP_TABLES_ALL_FAST - bool "Include all fast interpolation tables" - select CMSIS_DSP_TABLES_ARM_COS_F32 - select CMSIS_DSP_TABLES_ARM_COS_Q31 - select CMSIS_DSP_TABLES_ARM_COS_Q15 - select CMSIS_DSP_TABLES_ARM_SIN_F32 - select CMSIS_DSP_TABLES_ARM_SIN_Q31 - select CMSIS_DSP_TABLES_ARM_SIN_Q15 - select CMSIS_DSP_TABLES_ARM_SIN_COS_F32 - select CMSIS_DSP_TABLES_ARM_SIN_COS_Q31 - select CMSIS_DSP_TABLES_ARM_LMS_NORM_Q31 - select CMSIS_DSP_TABLES_ARM_LMS_NORM_Q15 - select CMSIS_DSP_TABLES_ARM_CMPLX_MAG_Q31 - select CMSIS_DSP_TABLES_ARM_CMPLX_MAG_Q15 - -config CMSIS_DSP_TABLES_ALL_FFT - bool "Include all FFT tables" - select CMSIS_DSP_TABLES_CFFT_F64_16 - select CMSIS_DSP_TABLES_CFFT_F64_32 - select CMSIS_DSP_TABLES_CFFT_F64_64 - select CMSIS_DSP_TABLES_CFFT_F64_128 - select CMSIS_DSP_TABLES_CFFT_F64_256 - select CMSIS_DSP_TABLES_CFFT_F64_512 - select CMSIS_DSP_TABLES_CFFT_F64_1024 - select CMSIS_DSP_TABLES_CFFT_F64_2048 - select CMSIS_DSP_TABLES_CFFT_F64_4096 - select CMSIS_DSP_TABLES_CFFT_F32_16 - select CMSIS_DSP_TABLES_CFFT_F32_32 - select CMSIS_DSP_TABLES_CFFT_F32_64 - select CMSIS_DSP_TABLES_CFFT_F32_128 - select CMSIS_DSP_TABLES_CFFT_F32_256 - select CMSIS_DSP_TABLES_CFFT_F32_512 - select CMSIS_DSP_TABLES_CFFT_F32_1024 - select CMSIS_DSP_TABLES_CFFT_F32_2048 - select CMSIS_DSP_TABLES_CFFT_F32_4096 - select CMSIS_DSP_TABLES_CFFT_F16_16 - select CMSIS_DSP_TABLES_CFFT_F16_32 - select CMSIS_DSP_TABLES_CFFT_F16_64 - select CMSIS_DSP_TABLES_CFFT_F16_128 - select CMSIS_DSP_TABLES_CFFT_F16_256 - select CMSIS_DSP_TABLES_CFFT_F16_512 - select CMSIS_DSP_TABLES_CFFT_F16_1024 - select CMSIS_DSP_TABLES_CFFT_F16_2048 - select CMSIS_DSP_TABLES_CFFT_F16_4096 - select CMSIS_DSP_TABLES_CFFT_Q31_16 - select CMSIS_DSP_TABLES_CFFT_Q31_32 - select CMSIS_DSP_TABLES_CFFT_Q31_64 - select CMSIS_DSP_TABLES_CFFT_Q31_128 - select CMSIS_DSP_TABLES_CFFT_Q31_256 - select CMSIS_DSP_TABLES_CFFT_Q31_512 - select CMSIS_DSP_TABLES_CFFT_Q31_1024 - select CMSIS_DSP_TABLES_CFFT_Q31_2048 - select CMSIS_DSP_TABLES_CFFT_Q31_4096 - select CMSIS_DSP_TABLES_CFFT_Q15_16 - select CMSIS_DSP_TABLES_CFFT_Q15_32 - select CMSIS_DSP_TABLES_CFFT_Q15_64 - select CMSIS_DSP_TABLES_CFFT_Q15_128 - select CMSIS_DSP_TABLES_CFFT_Q15_256 - select CMSIS_DSP_TABLES_CFFT_Q15_512 - select CMSIS_DSP_TABLES_CFFT_Q15_1024 - select CMSIS_DSP_TABLES_CFFT_Q15_2048 - select CMSIS_DSP_TABLES_CFFT_Q15_4096 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_32 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_64 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_128 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_256 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_512 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_1024 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_2048 - select CMSIS_DSP_TABLES_RFFT_FAST_F64_4096 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_32 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_64 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_128 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_256 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_512 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_1024 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_2048 - select CMSIS_DSP_TABLES_RFFT_FAST_F32_4096 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_32 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_64 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_128 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_256 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_512 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_1024 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_2048 - select CMSIS_DSP_TABLES_RFFT_FAST_F16_4096 - select CMSIS_DSP_TABLES_RFFT_F32_128 - select CMSIS_DSP_TABLES_RFFT_F32_512 - select CMSIS_DSP_TABLES_RFFT_F32_2048 - select CMSIS_DSP_TABLES_RFFT_F32_8192 - select CMSIS_DSP_TABLES_RFFT_F16_128 - select CMSIS_DSP_TABLES_RFFT_F16_512 - select CMSIS_DSP_TABLES_RFFT_F16_2048 - select CMSIS_DSP_TABLES_RFFT_F16_8192 - select CMSIS_DSP_TABLES_RFFT_Q31_32 - select CMSIS_DSP_TABLES_RFFT_Q31_64 - select CMSIS_DSP_TABLES_RFFT_Q31_128 - select CMSIS_DSP_TABLES_RFFT_Q31_256 - select CMSIS_DSP_TABLES_RFFT_Q31_512 - select CMSIS_DSP_TABLES_RFFT_Q31_1024 - select CMSIS_DSP_TABLES_RFFT_Q31_2048 - select CMSIS_DSP_TABLES_RFFT_Q31_4096 - select CMSIS_DSP_TABLES_RFFT_Q31_8192 - select CMSIS_DSP_TABLES_RFFT_Q15_32 - select CMSIS_DSP_TABLES_RFFT_Q15_64 - select CMSIS_DSP_TABLES_RFFT_Q15_128 - select CMSIS_DSP_TABLES_RFFT_Q15_256 - select CMSIS_DSP_TABLES_RFFT_Q15_512 - select CMSIS_DSP_TABLES_RFFT_Q15_1024 - select CMSIS_DSP_TABLES_RFFT_Q15_2048 - select CMSIS_DSP_TABLES_RFFT_Q15_4096 - select CMSIS_DSP_TABLES_RFFT_Q15_8192 - select CMSIS_DSP_TABLES_DCT4_F32_128 - select CMSIS_DSP_TABLES_DCT4_F32_512 - select CMSIS_DSP_TABLES_DCT4_F32_2048 - select CMSIS_DSP_TABLES_DCT4_F32_8192 - select CMSIS_DSP_TABLES_DCT4_Q31_128 - select CMSIS_DSP_TABLES_DCT4_Q31_512 - select CMSIS_DSP_TABLES_DCT4_Q31_2048 - select CMSIS_DSP_TABLES_DCT4_Q31_8192 - select CMSIS_DSP_TABLES_DCT4_Q15_128 - select CMSIS_DSP_TABLES_DCT4_Q15_512 - select CMSIS_DSP_TABLES_DCT4_Q15_2048 - select CMSIS_DSP_TABLES_DCT4_Q15_8192 - -comment "Interpolation Tables" - -config CMSIS_DSP_TABLES_ARM_COS_F32 - bool "cos f32" - -config CMSIS_DSP_TABLES_ARM_COS_Q31 - bool "cos q31" - -config CMSIS_DSP_TABLES_ARM_COS_Q15 - bool "cos q15" - -config CMSIS_DSP_TABLES_ARM_SIN_F32 - bool "sin f32" - -config CMSIS_DSP_TABLES_ARM_SIN_Q31 - bool "sin q31" - -config CMSIS_DSP_TABLES_ARM_SIN_Q15 - bool "sin q15" - -config CMSIS_DSP_TABLES_ARM_SIN_COS_F32 - bool "sin cos f32" - -config CMSIS_DSP_TABLES_ARM_SIN_COS_Q31 - bool "sin cos q31" - -config CMSIS_DSP_TABLES_ARM_LMS_NORM_Q31 - bool "lms norm q31" - -config CMSIS_DSP_TABLES_ARM_LMS_NORM_Q15 - bool "lms norm q15" - -config CMSIS_DSP_TABLES_ARM_CMPLX_MAG_Q31 - bool "cmplx mag q31" - -config CMSIS_DSP_TABLES_ARM_CMPLX_MAG_Q15 - bool "cmplx mag q15" - -comment "Transformation Tables" - -config CMSIS_DSP_TABLES_CFFT_F64_16 - bool "cfft f64 16" - -config CMSIS_DSP_TABLES_CFFT_F64_32 - bool "cfft f64 32" - -config CMSIS_DSP_TABLES_CFFT_F64_64 - bool "cfft f64 64" - -config CMSIS_DSP_TABLES_CFFT_F64_128 - bool "cfft f64 128" - -config CMSIS_DSP_TABLES_CFFT_F64_256 - bool "cfft f64 256" - -config CMSIS_DSP_TABLES_CFFT_F64_512 - bool "cfft f64 512" - -config CMSIS_DSP_TABLES_CFFT_F64_1024 - bool "cfft f64 1024" - -config CMSIS_DSP_TABLES_CFFT_F64_2048 - bool "cfft f64 2048" - -config CMSIS_DSP_TABLES_CFFT_F64_4096 - bool "cfft f64 4096" - -config CMSIS_DSP_TABLES_CFFT_F32_16 - bool "cfft f32 16" - -config CMSIS_DSP_TABLES_CFFT_F32_32 - bool "cfft f32 32" - -config CMSIS_DSP_TABLES_CFFT_F32_64 - bool "cfft f32 64" - -config CMSIS_DSP_TABLES_CFFT_F32_128 - bool "cfft f32 128" - -config CMSIS_DSP_TABLES_CFFT_F32_256 - bool "cfft f32 256" - -config CMSIS_DSP_TABLES_CFFT_F32_512 - bool "cfft f32 512" - -config CMSIS_DSP_TABLES_CFFT_F32_1024 - bool "cfft f32 1024" - -config CMSIS_DSP_TABLES_CFFT_F32_2048 - bool "cfft f32 2048" - -config CMSIS_DSP_TABLES_CFFT_F32_4096 - bool "cfft f32 4096" - -config CMSIS_DSP_TABLES_CFFT_F16_16 - bool "cfft f16 16" - -config CMSIS_DSP_TABLES_CFFT_F16_32 - bool "cfft f16 32" - -config CMSIS_DSP_TABLES_CFFT_F16_64 - bool "cfft f16 64" - -config CMSIS_DSP_TABLES_CFFT_F16_128 - bool "cfft f16 128" - -config CMSIS_DSP_TABLES_CFFT_F16_256 - bool "cfft f16 256" - -config CMSIS_DSP_TABLES_CFFT_F16_512 - bool "cfft f16 512" - -config CMSIS_DSP_TABLES_CFFT_F16_1024 - bool "cfft f16 1024" - -config CMSIS_DSP_TABLES_CFFT_F16_2048 - bool "cfft f16 2048" - -config CMSIS_DSP_TABLES_CFFT_F16_4096 - bool "cfft f16 4096" - -config CMSIS_DSP_TABLES_CFFT_Q31_16 - bool "cfft q31 16" - -config CMSIS_DSP_TABLES_CFFT_Q31_32 - bool "cfft q31 32" - -config CMSIS_DSP_TABLES_CFFT_Q31_64 - bool "cfft q31 64" - -config CMSIS_DSP_TABLES_CFFT_Q31_128 - bool "cfft q31 128" - -config CMSIS_DSP_TABLES_CFFT_Q31_256 - bool "cfft q31 256" - -config CMSIS_DSP_TABLES_CFFT_Q31_512 - bool "cfft q31 512" - -config CMSIS_DSP_TABLES_CFFT_Q31_1024 - bool "cfft q31 1024" - -config CMSIS_DSP_TABLES_CFFT_Q31_2048 - bool "cfft q31 2048" - -config CMSIS_DSP_TABLES_CFFT_Q31_4096 - bool "cfft q31 4096" - -config CMSIS_DSP_TABLES_CFFT_Q15_16 - bool "cfft q15 16" - -config CMSIS_DSP_TABLES_CFFT_Q15_32 - bool "cfft q15 32" - -config CMSIS_DSP_TABLES_CFFT_Q15_64 - bool "cfft q15 64" - -config CMSIS_DSP_TABLES_CFFT_Q15_128 - bool "cfft q15 128" - -config CMSIS_DSP_TABLES_CFFT_Q15_256 - bool "cfft q15 256" - -config CMSIS_DSP_TABLES_CFFT_Q15_512 - bool "cfft q15 512" - -config CMSIS_DSP_TABLES_CFFT_Q15_1024 - bool "cfft q15 1024" - -config CMSIS_DSP_TABLES_CFFT_Q15_2048 - bool "cfft q15 2048" - -config CMSIS_DSP_TABLES_CFFT_Q15_4096 - bool "cfft q15 4096" - -config CMSIS_DSP_TABLES_CFFT_RADIX4_Q31 - bool "cfft radix4 q31 (deprecated)" - -config CMSIS_DSP_TABLES_CFFT_RADIX4_Q15 - bool "cfft radix4 q15 (deprecated)" - -config CMSIS_DSP_TABLES_CFFT_RADIX2_Q31 - bool "cfft radix2 q31 (deprecated)" - -config CMSIS_DSP_TABLES_CFFT_RADIX2_Q15 - bool "cfft radix2 q15 (deprecated)" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_32 - bool "rfft fast f64 32" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_64 - bool "rfft fast f64 64" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_128 - bool "rfft fast f64 128" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_256 - bool "rfft fast f64 256" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_512 - bool "rfft fast f64 512" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_1024 - bool "rfft fast f64 1024" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_2048 - bool "rfft fast f64 2048" - -config CMSIS_DSP_TABLES_RFFT_FAST_F64_4096 - bool "rfft fast f64 4096" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_32 - bool "rfft fast f32 32" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_64 - bool "rfft fast f32 64" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_128 - bool "rfft fast f32 128" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_256 - bool "rfft fast f32 256" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_512 - bool "rfft fast f32 512" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_1024 - bool "rfft fast f32 1024" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_2048 - bool "rfft fast f32 2048" - -config CMSIS_DSP_TABLES_RFFT_FAST_F32_4096 - bool "rfft fast f32 4096" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_32 - bool "rfft fast f16 32" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_64 - bool "rfft fast f16 64" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_128 - bool "rfft fast f16 128" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_256 - bool "rfft fast f16 256" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_512 - bool "rfft fast f16 512" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_1024 - bool "rfft fast f16 1024" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_2048 - bool "rfft fast f16 2048" - -config CMSIS_DSP_TABLES_RFFT_FAST_F16_4096 - bool "rfft fast f16 4096" - -config CMSIS_DSP_TABLES_RFFT_F32_128 - bool "rfft f32 128" - -config CMSIS_DSP_TABLES_RFFT_F32_512 - bool "rfft f32 512" - -config CMSIS_DSP_TABLES_RFFT_F32_2048 - bool "rfft f32 2048" - -config CMSIS_DSP_TABLES_RFFT_F32_8192 - bool "rfft f32 8192" - -config CMSIS_DSP_TABLES_RFFT_F16_128 - bool "rfft f16 128" - -config CMSIS_DSP_TABLES_RFFT_F16_512 - bool "rfft f16 512" - -config CMSIS_DSP_TABLES_RFFT_F16_2048 - bool "rfft f16 2048" - -config CMSIS_DSP_TABLES_RFFT_F16_8192 - bool "rfft f16 8192" - -config CMSIS_DSP_TABLES_RFFT_Q31_32 - bool "rfft q31 32" - -config CMSIS_DSP_TABLES_RFFT_Q31_64 - bool "rfft q31 64" - -config CMSIS_DSP_TABLES_RFFT_Q31_128 - bool "rfft q31 128" - -config CMSIS_DSP_TABLES_RFFT_Q31_256 - bool "rfft q31 256" - -config CMSIS_DSP_TABLES_RFFT_Q31_512 - bool "rfft q31 512" - -config CMSIS_DSP_TABLES_RFFT_Q31_1024 - bool "rfft q31 1024" - -config CMSIS_DSP_TABLES_RFFT_Q31_2048 - bool "rfft q31 2048" - -config CMSIS_DSP_TABLES_RFFT_Q31_4096 - bool "rfft q31 4096" - -config CMSIS_DSP_TABLES_RFFT_Q31_8192 - bool "rfft q31 8192" - -config CMSIS_DSP_TABLES_RFFT_Q15_32 - bool "rfft q15 32" - -config CMSIS_DSP_TABLES_RFFT_Q15_64 - bool "rfft q15 64" - -config CMSIS_DSP_TABLES_RFFT_Q15_128 - bool "rfft q15 128" - -config CMSIS_DSP_TABLES_RFFT_Q15_256 - bool "rfft q15 256" - -config CMSIS_DSP_TABLES_RFFT_Q15_512 - bool "rfft q15 512" - -config CMSIS_DSP_TABLES_RFFT_Q15_1024 - bool "rfft q15 1024" - -config CMSIS_DSP_TABLES_RFFT_Q15_2048 - bool "rfft q15 2048" - -config CMSIS_DSP_TABLES_RFFT_Q15_4096 - bool "rfft q15 4096" - -config CMSIS_DSP_TABLES_RFFT_Q15_8192 - bool "rfft q15 8192" - -config CMSIS_DSP_TABLES_DCT4_F32_128 - bool "dct4 f32 128" - -config CMSIS_DSP_TABLES_DCT4_F32_512 - bool "dct4 f32 512" - -config CMSIS_DSP_TABLES_DCT4_F32_2048 - bool "dct4 f32 2048" - -config CMSIS_DSP_TABLES_DCT4_F32_8192 - bool "dct4 f32 8192" - -config CMSIS_DSP_TABLES_DCT4_Q31_128 - bool "dct4 q31 128" - -config CMSIS_DSP_TABLES_DCT4_Q31_512 - bool "dct4 q31 512" - -config CMSIS_DSP_TABLES_DCT4_Q31_2048 - bool "dct4 q31 2048" - -config CMSIS_DSP_TABLES_DCT4_Q31_8192 - bool "dct4 q31 8192" - -config CMSIS_DSP_TABLES_DCT4_Q15_128 - bool "dct4 q15 128" - -config CMSIS_DSP_TABLES_DCT4_Q15_512 - bool "dct4 q15 512" - -config CMSIS_DSP_TABLES_DCT4_Q15_2048 - bool "dct4 q15 2048" - -config CMSIS_DSP_TABLES_DCT4_Q15_8192 - bool "dct4 q15 8192" - -endif # CMSIS_DSP_TABLES - -comment "Instruction Set" -# NOTE: These configurations should eventually be derived from the arch ISA and -# FP support configurations. - -config CMSIS_DSP_NEON - bool "Neon Instruction Set" - default y - depends on CPU_CORTEX_A - help - This option enables the NEON Advanced SIMD instruction set, which is - available on most Cortex-A and some Cortex-R processors. - -comment "Features" - -config CMSIS_DSP_LOOPUNROLL - bool "Loop Unrolling" - help - This option enables manual loop unrolling in the DSP functions. - -config CMSIS_DSP_ROUNDING - bool "Rounding" - help - This option enables rounding on the support functions. - -config CMSIS_DSP_MATRIXCHECK - bool "Matrix Check" - help - This option enables validation of the input and output sizes of - matrices. - -config CMSIS_DSP_AUTOVECTORIZE - bool "Auto Vectorize" - help - This option prefers autovectorizable code to one using C intrinsics - in the DSP functions. - -config CMSIS_DSP_FLOAT16 - bool "Half-Precision (16-bit Float) Support" - default y - depends on FP16 - help - This option enables the half-precision (16-bit) floating-point - operations support. diff --git a/modules/cmsis_dsp/CMakeLists.txt b/modules/cmsis_dsp/CMakeLists.txt new file mode 100644 index 00000000000..9afaa32b89d --- /dev/null +++ b/modules/cmsis_dsp/CMakeLists.txt @@ -0,0 +1,931 @@ +# Copyright (c) 2023 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_CMSIS_DSP) + + set(CMSIS_DSP_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) + set(cmsis_glue_path ${ZEPHYR_CMSIS_MODULE_DIR}) + + zephyr_library() + + zephyr_library_compile_options(-Ofast) + + zephyr_include_directories( + ${CMSIS_DSP_DIR}/Include + ) + + zephyr_library_include_directories( + ${CMSIS_DSP_DIR}/PrivateInclude + ${cmsis_glue_path}/CMSIS/Core/Include + ) + + # Global Feature Definitions + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_NEON ARM_MATH_NEON) + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_NEON_EXPERIMENTAL ARM_MATH_NEON_EXPERIMENTAL) + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_LOOPUNROLL ARM_MATH_LOOPUNROLL) + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_ROUNDING ARM_MATH_ROUNDING) + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_MATRIXCHECK ARM_MATH_MATRIX_CHECK) + zephyr_library_compile_definitions_ifndef(CONFIG_CMSIS_DSP_FLOAT16 DISABLEFLOAT16) + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_AUTOVECTORIZE ARM_MATH_AUTOVECTORIZE) + + # Helium is automatically enabled by CMSIS-DSP if the processor supports it + zephyr_library_compile_definitions_ifdef(CONFIG_CMSIS_DSP_HELIUM_EXPERIMENTAL ARM_MATH_HELIUM_EXPERIMENTAL) + + zephyr_compile_definitions_ifndef(CONFIG_ARM __GNUC_PYTHON__) + + if (CONFIG_CMSIS_DSP_NEON OR CONFIG_CMSIS_DSP_NEON_EXPERIMENTAL) + zephyr_library_include_directories("${CMSIS_DSP_DIR}/ComputeLibrary/Include") + endif() + + if (CONFIG_ARMV8_1_M_MVEI OR CONFIG_ARMV8_1_M_MVEF) + if (CONFIG_CMSIS_DSP_LAX_VECTOR_CONVERSIONS) + zephyr_library_compile_options($<$:-flax-vector-conversions>) + zephyr_library_compile_options($<$:-flax-vector-conversions=integer>) + else() + zephyr_library_compile_options($<$:-fno-lax-vector-conversions>) + zephyr_library_compile_options($<$:-flax-vector-conversions=none>) + endif() + endif() + + zephyr_library_compile_options(-Ofast) + + zephyr_compile_definitions_ifndef(CONFIG_ARM __GNUC_PYTHON__) + + # BasicMathFunctions + + set(SRCF64 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_f64.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_f64.c + ) + + set(SRCF32 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_clip_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_f32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_f32.c + ) + + set(SRCF16 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_clip_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_f16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_f16.c + ) + + set(SRCQ31 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_clip_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_shift_q31.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_q31.c + ) + + set(SRCQ15 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_clip_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_shift_q15.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_q15.c + ) + + set(SRCQ7 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_abs_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_add_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_clip_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_dot_prod_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_mult_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_negate_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_offset_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_scale_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_shift_q7.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_sub_q7.c + ) + + set(SRCU32 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_and_u32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_not_u32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_or_u32.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_xor_u32.c + ) + + set(SRCU16 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_and_u16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_not_u16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_or_u16.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_xor_u16.c + ) + + set(SRCU8 ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_and_u8.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_or_u8.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_not_u8.c + ${CMSIS_DSP_DIR}/Source/BasicMathFunctions/arm_xor_u8.c) + + zephyr_library_sources(${SRCF64}) + zephyr_library_sources(${SRCF32}) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${SRCF16}) + endif() + + zephyr_library_sources(${SRCQ31}) + zephyr_library_sources(${SRCQ15}) + zephyr_library_sources(${SRCQ7}) + + zephyr_library_sources(${SRCU32}) + zephyr_library_sources(${SRCU16}) + zephyr_library_sources(${SRCU8}) + + # BayesFunctions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/BayesFunctions/arm_gaussian_naive_bayes_predict_f32.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/BayesFunctions/arm_gaussian_naive_bayes_predict_f16.c) + endif() + + # Common Tables + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/CommonTables/arm_common_tables.c + ${CMSIS_DSP_DIR}/Source/CommonTables/arm_common_tables_f16.c) + + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/CommonTables/arm_const_structs.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/CommonTables/arm_const_structs_f16.c) + + + if (CONFIG_CMSIS_DSP_NEON OR CONFIG_CMSIS_DSP_NEON_EXPERIMENTAL) + zephyr_library_sources("${CMSIS_DSP_DIR}/ComputeLibrary/Source/arm_cl_tables.c") + endif() + + if (CONFIG_ARMV8_1_M_MVEI OR CONFIG_ARMV8_1_M_MVEF) + zephyr_library_sources("${CMSIS_DSP_DIR}/Source/CommonTables/arm_mve_tables.c") + zephyr_library_sources("${CMSIS_DSP_DIR}/Source/CommonTables/arm_mve_tables_f16.c") + endif() + + + if (WRAPPER) + target_compile_definitions(CMSISDSP PUBLIC ARM_TABLE_BITREV_1024) + target_compile_definitions(CMSISDSP PUBLIC ARM_TABLE_TWIDDLECOEF_F32_4096) + target_compile_definitions(CMSISDSP PUBLIC ARM_TABLE_TWIDDLECOEF_Q31_4096) + target_compile_definitions(CMSISDSP PUBLIC ARM_TABLE_TWIDDLECOEF_Q15_4096) + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + target_compile_definitions(CMSISDSP PUBLIC ARM_TABLE_TWIDDLECOEF_F16_4096) + endif() + endif() + + # ComplexMathFunctions + # MVE code is using a table for computing the fast sqrt arm_cmplx_mag_q31 + # There is the possibility of not compiling this function and not including + # the table. + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_fast_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_conj_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ComplexMathFunctions/arm_cmplx_mult_real_f16.c) + endif() + + # Controller Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_reset_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_reset_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_pid_reset_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_sin_cos_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/ControllerFunctions/arm_sin_cos_q31.c) + + # Distance Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_boolean_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_braycurtis_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_canberra_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_chebyshev_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_chebyshev_distance_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cityblock_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cityblock_distance_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_correlation_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cosine_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cosine_distance_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_dice_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_euclidean_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_euclidean_distance_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_hamming_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_jaccard_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_jensenshannon_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_kulsinski_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_minkowski_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_rogerstanimoto_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_russellrao_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_sokalmichener_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_sokalsneath_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_yule_distance.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_dtw_distance_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_dtw_path_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_dtw_init_window_q7.c) + + + zephyr_library_include_directories("${CMSIS_DSP_DIR}/Source/DistanceFunctions") + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_braycurtis_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_canberra_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_chebyshev_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cityblock_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_correlation_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_cosine_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_euclidean_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_jensenshannon_distance_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/DistanceFunctions/arm_minkowski_distance_f16.c) + endif() + + # Fast Math Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_cos_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_cos_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_cos_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_sin_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_sin_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_sin_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_sqrt_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_sqrt_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vlog_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vlog_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vexp_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vexp_f64.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vlog_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vlog_q15.c) + + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vlog_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vexp_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_vinverse_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_atan2_f16.c) + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_divide_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_divide_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_atan2_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_atan2_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FastMathFunctions/arm_atan2_q15.c) + + # Filtering Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_init_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_init_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_fast_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_opt_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_opt_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_partial_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_conv_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_opt_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_opt_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_decimate_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_fast_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_fast_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_interpolate_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_lattice_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_init_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_sparse_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_iir_lattice_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_norm_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_lms_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_levinson_durbin_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_levinson_durbin_q31.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_fir_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_correlate_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/FilteringFunctions/arm_levinson_durbin_f16.c) + endif() + + # Interpolation Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_bilinear_interp_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_bilinear_interp_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_bilinear_interp_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_bilinear_interp_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_linear_interp_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_linear_interp_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_linear_interp_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_linear_interp_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_spline_interp_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_spline_interp_init_f32.c) + + + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_bilinear_interp_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/InterpolationFunctions/arm_linear_interp_f16.c) + endif() + + # Matrix Functions + set(SRCF64 ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cholesky_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_inverse_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_ldlt_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_lower_triangular_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_upper_triangular_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_sub_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_qr_f64.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_householder_f64.c + ) + + set(SRCF32 ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_add_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cholesky_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_trans_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_init_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_inverse_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_ldlt_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_scale_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_lower_triangular_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_upper_triangular_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_sub_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_vec_mult_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_qr_f32.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_householder_f32.c + ) + + set(SRCQ31 ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_add_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_trans_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_init_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_fast_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_opt_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_scale_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_sub_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_q31.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_vec_mult_q31.c + ) + + set(SRCQ15 ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_add_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_trans_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_init_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_fast_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_scale_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_sub_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_q15.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_vec_mult_q15.c + ) + + set(SRCQ7 ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_q7.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_vec_mult_q7.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_q7.c + ) + + + zephyr_library_sources(${SRCF64}) + zephyr_library_sources(${SRCF32}) + + zephyr_library_sources(${SRCQ31}) + zephyr_library_sources(${SRCQ15}) + zephyr_library_sources(${SRCQ7}) + + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_add_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cholesky_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_mult_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_cmplx_trans_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_init_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_inverse_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_mult_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_scale_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_lower_triangular_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_solve_upper_triangular_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_sub_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_trans_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_vec_mult_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_mat_qr_f16.c + ${CMSIS_DSP_DIR}/Source/MatrixFunctions/arm_householder_f16.c + ) + endif() + + # Quaternion Math Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_norm_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_inverse_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_conjugate_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_normalize_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_product_single_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion_product_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_quaternion2rotation_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/QuaternionMathFunctions/arm_rotation2quaternion_f32.c) + + # Statistics Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_entropy_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_entropy_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_kullback_leibler_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_kullback_leibler_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_logsumexp_dot_prod_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_logsumexp_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_rms_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_rms_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_rms_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_std_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_std_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_std_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_std_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_var_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_var_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_var_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_var_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_q7.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_q7.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_q7.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_q7.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mse_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_accumulate_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_accumulate_f32.c) + + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_mean_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_power_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_rms_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_std_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_var_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_entropy_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_kullback_leibler_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_logsumexp_dot_prod_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_logsumexp_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_max_no_idx_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_min_no_idx_f16.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmax_no_idx_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_absmin_no_idx_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/StatisticsFunctions/arm_accumulate_f16.c) + endif() + + # Support Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_barycenter_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_bitonic_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_bubble_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f16_to_float.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f16_to_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f64_to_float.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f64_to_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f64_to_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f64_to_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_float_to_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_float_to_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_float_to_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_float_to_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_heap_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_insertion_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_merge_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_merge_sort_init_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q15_to_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q15_to_float.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q15_to_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q15_to_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q31_to_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q31_to_float.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q31_to_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q31_to_q7.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q7_to_f64.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q7_to_float.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q7_to_q15.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q7_to_q31.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_quick_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_selection_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_sort_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_sort_init_f32.c + ${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_weighted_sum_f32.c + ) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_copy_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_fill_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f16_to_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_q15_to_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_float_to_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f16_to_float.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_weighted_sum_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_barycenter_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f16_to_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SupportFunctions/arm_f64_to_f16.c) + endif() + + # SVM Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_linear_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_rbf_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_linear_predict_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_rbf_predict_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_polynomial_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_sigmoid_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_polynomial_predict_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_sigmoid_predict_f32.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_linear_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_rbf_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_linear_predict_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_rbf_predict_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_polynomial_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_sigmoid_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_polynomial_predict_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/SVMFunctions/arm_svm_sigmoid_predict_f16.c) + endif() + + # Transform Functions + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_bitreversal.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_bitreversal2.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_bitreversal_f16.c) + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix8_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_f32.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_f16.c) + endif() + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_f16.c) + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_f64.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q31.c) + + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_init_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_init_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_dct4_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix8_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_f64.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_init_f64.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_fast_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix8_f16.c) + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q15.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_rfft_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_q31.c) + + if (WRAPPER) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_init_q31.c) + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix4_init_q31.c) + + + # For scipy or wrappers or benchmarks + if (WRAPPER) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_init_f32.c) + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_cfft_radix2_init_f16.c) + endif() + endif() + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_init_f32.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_f32.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_init_q31.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_q31.c) + + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_init_q15.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_q15.c) + + if ((NOT ARMAC5) AND (NOT DISABLEFLOAT16)) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_init_f16.c) + zephyr_library_sources(${CMSIS_DSP_DIR}/Source/TransformFunctions/arm_mfcc_f16.c) + endif() + + # Window Functions + set(SRCF64 ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_welch_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_bartlett_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hamming_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hanning_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3a_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3b_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4a_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_blackman_harris_92db_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4b_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4c_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft90d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft95_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft116d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft144d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft169d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft196d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft223d_f64.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft248d_f64.c + ) + + set(SRCF32 ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_welch_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_bartlett_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hamming_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hanning_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3a_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall3b_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4a_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_blackman_harris_92db_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4b_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_nuttall4c_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft90d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft95_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft116d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft144d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft169d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft196d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft223d_f32.c + ${CMSIS_DSP_DIR}/Source/WindowFunctions/arm_hft248d_f32.c + ) + + zephyr_library_sources(${SRCF64}) + zephyr_library_sources(${SRCF32}) + +endif() diff --git a/modules/cmsis_dsp/Kconfig b/modules/cmsis_dsp/Kconfig new file mode 100644 index 00000000000..2159f1f6c2e --- /dev/null +++ b/modules/cmsis_dsp/Kconfig @@ -0,0 +1,79 @@ +# Copyright (c) 2023 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +config ZEPHYR_CMSIS_DSP_MODULE + bool + +menuconfig CMSIS_DSP + bool "CMSIS-DSP Library Support" + help + This option enables the CMSIS-DSP library. + +if CMSIS_DSP + +comment "Instruction Set" +# NOTE: These configurations should eventually be derived from the arch ISA and +# FP support configurations. + +config CMSIS_DSP_NEON + bool "Neon Instruction Set" + default y + depends on CPU_CORTEX_A + help + This option enables the NEON Advanced SIMD instruction set, which is + available on most Cortex-A and some Cortex-R processors. + +config CMSIS_DSP_NEON_EXPERIMENTAL + bool "Neon Instruction Set" + depends on CPU_CORTEX_A + help + This option enables the NEON Advanced SIMD instruction set, which is + available on most Cortex-A and some Cortex-R processors. + +config CMSIS_DSP_HELIUM_EXPERIMENTAL + bool "Helium Instruction Set" + depends on FP_HARDABI && (ARMV8_1_M_MVEI || ARMV8_1_M_MVEF) + help + This option enables the Helium Advanced SIMD instruction set, which is + available on some Cortex-M processors. + +comment "Features" + +config CMSIS_DSP_LOOPUNROLL + bool "Loop Unrolling" + help + This option enables manual loop unrolling in the DSP functions. + +config CMSIS_DSP_ROUNDING + bool "Rounding" + help + This option enables rounding on the support functions. + +config CMSIS_DSP_MATRIXCHECK + bool "Matrix Check" + help + This option enables validation of the input and output sizes of + matrices. + +config CMSIS_DSP_AUTOVECTORIZE + bool "Auto Vectorize" + help + This option prefers autovectorizable code to one using C intrinsics + in the DSP functions. + +config CMSIS_DSP_FLOAT16 + bool "Half-Precision (16-bit Float) Support" + default y + depends on FP16 + help + This option enables the half-precision (16-bit) floating-point + operations support. + +config CMSIS_DSP_LAX_VECTOR_CONVERSIONS + bool "Lax Vector Conversions" + default y + depends on FP_HARDABI && (ARMV8_1_M_MVEI || ARMV8_1_M_MVEF) + help + This option enables lax vector conversions + +endif #CMSIS_DSP diff --git a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf index ad76c3a269a..75aa99c4887 100644 --- a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf +++ b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_BASICMATH=y diff --git a/tests/lib/cmsis_dsp/bayes/prj.conf b/tests/lib/cmsis_dsp/bayes/prj.conf index 4699ae06e09..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/bayes/prj.conf +++ b/tests/lib/cmsis_dsp/bayes/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_BAYES=y diff --git a/tests/lib/cmsis_dsp/complexmath/prj.conf b/tests/lib/cmsis_dsp/complexmath/prj.conf index c9ccc0fc0d5..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/complexmath/prj.conf +++ b/tests/lib/cmsis_dsp/complexmath/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_COMPLEXMATH=y diff --git a/tests/lib/cmsis_dsp/distance/prj.conf b/tests/lib/cmsis_dsp/distance/prj.conf index 4ac4431074f..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/distance/prj.conf +++ b/tests/lib/cmsis_dsp/distance/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_DISTANCE=y diff --git a/tests/lib/cmsis_dsp/fastmath/prj.conf b/tests/lib/cmsis_dsp/fastmath/prj.conf index c47d04656b0..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/fastmath/prj.conf +++ b/tests/lib/cmsis_dsp/fastmath/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_FASTMATH=y diff --git a/tests/lib/cmsis_dsp/filtering/prj.conf b/tests/lib/cmsis_dsp/filtering/prj.conf index e7885f018d8..b40c98d36e5 100644 --- a/tests/lib/cmsis_dsp/filtering/prj.conf +++ b/tests/lib/cmsis_dsp/filtering/prj.conf @@ -2,7 +2,6 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_FILTERING=y # Test Options CONFIG_CMSIS_DSP_TEST_FILTERING_BIQUAD=y diff --git a/tests/lib/cmsis_dsp/filtering/prj_base.conf b/tests/lib/cmsis_dsp/filtering/prj_base.conf index 48cde7ba869..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/filtering/prj_base.conf +++ b/tests/lib/cmsis_dsp/filtering/prj_base.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_FILTERING=y diff --git a/tests/lib/cmsis_dsp/interpolation/prj.conf b/tests/lib/cmsis_dsp/interpolation/prj.conf index 0fbd97dded0..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/interpolation/prj.conf +++ b/tests/lib/cmsis_dsp/interpolation/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_INTERPOLATION=y diff --git a/tests/lib/cmsis_dsp/matrix/prj.conf b/tests/lib/cmsis_dsp/matrix/prj.conf index f3cf8bc423c..744d8f3d75d 100644 --- a/tests/lib/cmsis_dsp/matrix/prj.conf +++ b/tests/lib/cmsis_dsp/matrix/prj.conf @@ -2,7 +2,6 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_MATRIX=y # Test Options CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q7=y diff --git a/tests/lib/cmsis_dsp/matrix/prj_base.conf b/tests/lib/cmsis_dsp/matrix/prj_base.conf index a4c8db100f3..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/matrix/prj_base.conf +++ b/tests/lib/cmsis_dsp/matrix/prj_base.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_MATRIX=y diff --git a/tests/lib/cmsis_dsp/quaternionmath/prj.conf b/tests/lib/cmsis_dsp/quaternionmath/prj.conf index 8de8c52d3c5..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/quaternionmath/prj.conf +++ b/tests/lib/cmsis_dsp/quaternionmath/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_QUATERNIONMATH=y diff --git a/tests/lib/cmsis_dsp/statistics/prj.conf b/tests/lib/cmsis_dsp/statistics/prj.conf index 2eb1011afe3..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/statistics/prj.conf +++ b/tests/lib/cmsis_dsp/statistics/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_STATISTICS=y diff --git a/tests/lib/cmsis_dsp/support/prj.conf b/tests/lib/cmsis_dsp/support/prj.conf index 80c8923b3a7..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/support/prj.conf +++ b/tests/lib/cmsis_dsp/support/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_SUPPORT=y diff --git a/tests/lib/cmsis_dsp/svm/prj.conf b/tests/lib/cmsis_dsp/svm/prj.conf index 18b34694a5f..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/svm/prj.conf +++ b/tests/lib/cmsis_dsp/svm/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_SVM=y diff --git a/tests/lib/cmsis_dsp/transform/prj.conf b/tests/lib/cmsis_dsp/transform/prj.conf index 9889f3b9aed..219f62788d8 100644 --- a/tests/lib/cmsis_dsp/transform/prj.conf +++ b/tests/lib/cmsis_dsp/transform/prj.conf @@ -2,7 +2,6 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y CONFIG_ZTEST_NEW_API=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_TRANSFORM=y # Test Options CONFIG_CMSIS_DSP_TEST_TRANSFORM_CQ15=y diff --git a/tests/lib/cmsis_dsp/transform/prj_base.conf b/tests/lib/cmsis_dsp/transform/prj_base.conf index 40e0627c4ff..75aa99c4887 100644 --- a/tests/lib/cmsis_dsp/transform/prj_base.conf +++ b/tests/lib/cmsis_dsp/transform/prj_base.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_TRANSFORM=y diff --git a/tests/subsys/dsp/basicmath/prj.conf b/tests/subsys/dsp/basicmath/prj.conf index 912a703fd9e..4e2cb0cae14 100644 --- a/tests/subsys/dsp/basicmath/prj.conf +++ b/tests/subsys/dsp/basicmath/prj.conf @@ -3,5 +3,4 @@ CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_BASICMATH=y CONFIG_DSP_BACKEND_CMSIS=y diff --git a/tests/subsys/dsp/basicmath/prj_arc.conf b/tests/subsys/dsp/basicmath/prj_arc.conf index c84bec1f3d9..865604bbd25 100644 --- a/tests/subsys/dsp/basicmath/prj_arc.conf +++ b/tests/subsys/dsp/basicmath/prj_arc.conf @@ -4,5 +4,4 @@ CONFIG_ARCMWDT_LIBC=y CONFIG_CPLUSPLUS=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y -CONFIG_CMSIS_DSP_BASICMATH=y CONFIG_DSP_BACKEND_ARCMWDT=y diff --git a/west.yml b/west.yml index 0bb013112d4..21c70feebc2 100644 --- a/west.yml +++ b/west.yml @@ -126,6 +126,9 @@ manifest: path: modules/hal/cmsis groups: - hal + - name: cmsis-dsp + revision: ff7b5fd1ea5f094665c090c343ec44e74dc0b193 + path: modules/lib/cmsis-dsp - name: edtt revision: 64e5105ad82390164fb73fc654be3f73a608209a path: tools/edtt From b0920948157876648de16d5817cc26a5b1cab9fb Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Wed, 19 Apr 2023 12:58:43 -0700 Subject: [PATCH 0934/4498] modules: cmsis-nn: add cmsis-nn module This adds the cmsis-nn module since it moved to its own realm. This also adds a kconfig for the long short-term memory. Signed-off-by: Ryan McClelland --- MAINTAINERS.yml | 15 +- modules/cmsis/Kconfig | 9 - modules/cmsis_nn/CMakeLists.txt | 85 +++ .../Kconfig.cmsis_nn => cmsis_nn/Kconfig} | 26 +- modules/tflite-micro/Kconfig | 1 + tests/lib/cmsis_nn/src/main.c | 519 +++++++++--------- west.yml | 3 + 7 files changed, 383 insertions(+), 275 deletions(-) create mode 100644 modules/cmsis_nn/CMakeLists.txt rename modules/{cmsis/Kconfig.cmsis_nn => cmsis_nn/Kconfig} (77%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a1d0b8cc516..959c7991408 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -436,8 +436,9 @@ CMSIS-NN integration: - JordanYates collaborators: - stephanosio + - XenuIsWatching files: - - modules/cmsis/Kconfig.cmsis_nn + - modules/cmsis_nn/ - tests/lib/cmsis_nn/ labels: - "area: CMSIS-NN" @@ -2941,7 +2942,6 @@ West: - povergoing files: - modules/cmsis/Kconfig - - modules/cmsis/Kconfig.cmsis_nn labels: - "area: ARM" @@ -2956,6 +2956,17 @@ West: labels: - "area: ARM" +"West project: cmsis-nn": + status: maintained + maintainers: + - XenuIsWatching + collaborators: + - stephanosio + files: + - modules/cmsis_nn/ + labels: + - "area: ARM" + "West project: edtt": status: maintained maintainers: diff --git a/modules/cmsis/Kconfig b/modules/cmsis/Kconfig index 2ef84f0bfce..6007292ff2e 100644 --- a/modules/cmsis/Kconfig +++ b/modules/cmsis/Kconfig @@ -19,12 +19,3 @@ config HAS_CMSIS_CORE_M bool endif - -menuconfig CMSIS_NN - bool "CMSIS-NN Library Support" - depends on CPU_CORTEX_M - select CMSIS_DSP - -if CMSIS_NN -source "modules/cmsis/Kconfig.cmsis_nn" -endif diff --git a/modules/cmsis_nn/CMakeLists.txt b/modules/cmsis_nn/CMakeLists.txt new file mode 100644 index 00000000000..9393a5ff21e --- /dev/null +++ b/modules/cmsis_nn/CMakeLists.txt @@ -0,0 +1,85 @@ +# Copyright (c) 2023 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_CMSIS_NN) + + set(CMSIS_NN_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) + set(cmsis_glue_path ${ZEPHYR_CMSIS_MODULE_DIR}) + + zephyr_library() + + zephyr_library_compile_options(-Ofast) + + zephyr_include_directories(${CMSIS_NN_DIR}/Include) + + zephyr_library_include_directories(${cmsis_glue_path}/CMSIS/Core/Include) + + if(CONFIG_CMSIS_NN_ACTIVATION) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/ActivationFunctions/*_s8*.c") + file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/ActivationFunctions/*_s16*.c") + zephyr_library_sources(${SRC} ${SRC_S16} + ${CMSIS_NN_DIR}/Source/ActivationFunctions/arm_relu_q7.c + ${CMSIS_NN_DIR}/Source/ActivationFunctions/arm_relu_q15.c) + endif() + + if(CONFIG_CMSIS_NN_BASICMATH) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/BasicMathFunctions/*_*.c") + zephyr_library_sources(${SRC}) + endif() + + if(CONFIG_CMSIS_NN_CONCATENATION) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/ConcatenationFunctions/*_*.c") + zephyr_library_sources(${SRC}) + endif() + + if(CONFIG_CMSIS_NN_CONVOLUTION) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s8*.c") + file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/ConvolutionFunctions/*_s16*.c") + zephyr_library_sources(${SRC} ${SRC_S16}) + endif() + + if(CONFIG_CMSIS_NN_FULLYCONNECTED) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s8.c") + file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/FullyConnectedFunctions/*_s16*.c") + zephyr_library_sources(${SRC} ${SRC_S16}) + endif() + + if(CONFIG_CMSIS_NN_NNSUPPORT) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s8*.c") + file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/NNSupportFunctions/*_s16*.c") + zephyr_library_sources(${SRC} ${SRC_S16} + ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_nntables.c + ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_q7_to_q15_with_offset.c + ${CMSIS_NN_DIR}/Source/NNSupportFunctions/arm_s8_to_s16_unordered_with_offset.c) + endif() + + if(CONFIG_CMSIS_NN_POOLING) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/PoolingFunctions/*_s8.c") + file(GLOB SRC_S16 "${CMSIS_NN_DIR}/Source/PoolingFunctions/*_s16.c") + zephyr_library_sources(${SRC} ${SRC_S16}) + endif() + + if(CONFIG_CMSIS_NN_RESHAPE) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/ReshapeFunctions/*_*.c") + zephyr_library_sources(${SRC}) + endif() + + if(CONFIG_CMSIS_NN_SOFTMAX) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/SoftmaxFunctions/*_s8.c") + zephyr_library_sources(${SRC} + ${CMSIS_NN_DIR}/Source/SoftmaxFunctions/arm_softmax_s8_s16.c + ${CMSIS_NN_DIR}/Source/SoftmaxFunctions/arm_softmax_s16.c + ${CMSIS_NN_DIR}/Source/SoftmaxFunctions/arm_nn_softmax_common_s8.c) + endif() + + if(CONFIG_CMSIS_NN_SVD) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/SVDFunctions/*_s8.c") + zephyr_library_sources(${SRC}) + endif() + + if(CONFIG_CMSIS_NN_LSTM) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/LSTMFunctions/*_s16.c") + zephyr_library_sources(${SRC}) + endif() + +endif() diff --git a/modules/cmsis/Kconfig.cmsis_nn b/modules/cmsis_nn/Kconfig similarity index 77% rename from modules/cmsis/Kconfig.cmsis_nn rename to modules/cmsis_nn/Kconfig index 084fcf3a656..53c3aa4987d 100644 --- a/modules/cmsis/Kconfig.cmsis_nn +++ b/modules/cmsis_nn/Kconfig @@ -1,15 +1,24 @@ -# Copyright (c) 2021, Commonwealth Scientific and Industrial Research -# Organisation (CSIRO) ABN 41 687 119 230. +# Copyright (c) 2023 Meta Platforms # SPDX-License-Identifier: Apache-2.0 -comment "CMSIS-NN Components" +config ZEPHYR_CMSIS_NN_MODULE + bool + +menuconfig CMSIS_NN + bool "CMSIS-NN Library Support" + depends on CPU_CORTEX_M + select CMSIS_DSP + help + This option enables the CMSIS-NN library. + +if CMSIS_NN config CMSIS_NN_ACTIVATION bool "Activation" help This option enables the NN libraries for the activation layers It can perform activation layers, including ReLU (Rectified - Linear Unit), sigmoid and tanh. + Linear Unit), sigmoid, and tanh. config CMSIS_NN_BASICMATH bool "Basic Math for NN" @@ -45,7 +54,7 @@ config CMSIS_NN_POOLING bool "Pooling" imply CMSIS_NN_NNSUPPORT help - This option enables pooling layers, including max pooling + This option enables pooling layers, including max pooling, and average pooling. config CMSIS_NN_RESHAPE @@ -63,3 +72,10 @@ config CMSIS_NN_SVD imply CMSIS_NN_NNSUPPORT help This option enabled the NN libraries for Single Value Decomposition Filter layers. + +config CMSIS_NN_LSTM + bool "Long Short-Term Memory" + help + This option enables the NN libraries for Long Short-Term Memory. + +endif #CMSIS_NN diff --git a/modules/tflite-micro/Kconfig b/modules/tflite-micro/Kconfig index d2c92f6e126..72789bd51de 100644 --- a/modules/tflite-micro/Kconfig +++ b/modules/tflite-micro/Kconfig @@ -27,6 +27,7 @@ config TENSORFLOW_LITE_MICRO_CMSIS_NN_KERNELS select CMSIS_NN_RESHAPE select CMSIS_NN_SOFTMAX select CMSIS_NN_SVD + select CMSIS_NN_LSTM help This option adds support for CMSIS-NN optimized kernels when using TensorFlow Lite Micro. diff --git a/tests/lib/cmsis_nn/src/main.c b/tests/lib/cmsis_nn/src/main.c index f653d5a6aaf..3eb7c200590 100644 --- a/tests/lib/cmsis_nn/src/main.c +++ b/tests/lib/cmsis_nn/src/main.c @@ -18,41 +18,39 @@ #define REPEAT_NUM 3 -#define AVGPOOLING_2_OUT_CH 5 -#define AVGPOOLING_2_IN_CH 5 -#define AVGPOOLING_2_INPUT_W 12 -#define AVGPOOLING_2_INPUT_H 1 -#define AVGPOOLING_2_DST_SIZE 60 -#define AVGPOOLING_2_INPUT_SIZE 60 +#define AVGPOOLING_2_OUT_CH 5 +#define AVGPOOLING_2_IN_CH 5 +#define AVGPOOLING_2_INPUT_W 12 +#define AVGPOOLING_2_INPUT_H 1 +#define AVGPOOLING_2_DST_SIZE 60 +#define AVGPOOLING_2_INPUT_SIZE 60 #define AVGPOOLING_2_OUT_ACTIVATION_MIN -128 #define AVGPOOLING_2_OUT_ACTIVATION_MAX 127 -#define AVGPOOLING_2_INPUT_BATCHES 1 -#define AVGPOOLING_2_FILTER_X 3 -#define AVGPOOLING_2_FILTER_Y 1 -#define AVGPOOLING_2_STRIDE_X 1 -#define AVGPOOLING_2_STRIDE_Y 2 -#define AVGPOOLING_2_PAD_X 1 -#define AVGPOOLING_2_PAD_Y 0 -#define AVGPOOLING_2_OUTPUT_W 12 -#define AVGPOOLING_2_OUTPUT_H 1 +#define AVGPOOLING_2_INPUT_BATCHES 1 +#define AVGPOOLING_2_FILTER_X 3 +#define AVGPOOLING_2_FILTER_Y 1 +#define AVGPOOLING_2_STRIDE_X 1 +#define AVGPOOLING_2_STRIDE_Y 2 +#define AVGPOOLING_2_PAD_X 1 +#define AVGPOOLING_2_PAD_Y 0 +#define AVGPOOLING_2_OUTPUT_W 12 +#define AVGPOOLING_2_OUTPUT_H 1 const int8_t avgpooling_2_input[60] = { - 80, 16, -80, -96, 96, -64, -112, -112, 48, 16, -80, -80, 80, 64, -80, - 16, 48, -112, 0, 48, 96, -80, -112, -64, -32, -16, -112, -64, -64, 80, - -96, -112, -16, -80, -80, -112, -64, -48, 16, 64, 32, 48, 16, 64, 16, - -48, -64, -32, -80, 64, -48, -32, -32, -112, 32, 32, -112, -96, -96, 48 -}; + -82, -104, 10, -28, -52, -51, -66, 52, 124, -74, -21, 4, 37, -7, -33, + 102, 110, 24, 52, 121, 13, -55, -79, -92, -35, -103, 86, 95, 46, 32, + -24, -123, 120, 29, -77, -97, -69, -68, 58, 38, 3, 3, 79, -47, 112, + -52, -113, -46, 107, 68, 83, -70, 91, 14, 113, 74, 73, -103, -98, 25}; const int8_t avgpooling_2_output_ref[60] = { - 8, -48, -96, -24, 56, -21, -59, -37, 5, 11, -43, -48, -48, 37, -5, - 11, -37, -48, 0, -21, 32, -48, -96, -43, 32, -5, -101, -64, -69, -11, - -75, -96, -43, -43, 21, -59, -43, -16, 0, 0, -43, -27, -21, 0, 48, - -21, -16, -16, -43, 37, -21, -69, -53, -96, 48, -8, -72, -64, -104, 40 -}; + -67, -85, 31, 48, -63, -51, -55, 33, 30, -53, 10, 16, 38, 56, 5, + 31, 20, -6, -16, 18, 4, 47, 13, 2, 39, -38, -31, 45, -6, -27, + -75, -35, 49, 44, -2, -39, -63, 44, 13, 24, -49, -60, -12, 39, 73, + 11, -60, 41, 25, 98, 35, -37, -19, 8, 69, 79, 2, -6, -42, 69}; ZTEST(cmsis_nn, test_avgpool) { - q7_t output[AVGPOOLING_2_DST_SIZE] = { 0 }; + int8_t output[AVGPOOLING_2_DST_SIZE] = {0}; cmsis_nn_context ctx; cmsis_nn_pool_params pool_params; @@ -81,74 +79,78 @@ ZTEST(cmsis_nn, test_avgpool) ctx.size = arm_avgpool_s8_get_buffer_size(AVGPOOLING_2_OUTPUT_W, AVGPOOLING_2_IN_CH); ctx.buf = malloc(ctx.size); - arm_status result = arm_avgpool_s8(&ctx, &pool_params, &input_dims, avgpooling_2_input, - &filter_dims, &output_dims, output); + arm_cmsis_nn_status result = arm_avgpool_s8(&ctx, + &pool_params, + &input_dims, + avgpooling_2_input, + &filter_dims, + &output_dims, + output); free(ctx.buf); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(avgpooling_2_output_ref, output, sizeof(output), ""); } -#define CONV_4_OUT_CH 3 -#define CONV_4_IN_CH 3 -#define CONV_4_INPUT_W 5 -#define CONV_4_INPUT_H 5 -#define CONV_4_DST_SIZE 36 -#define CONV_4_INPUT_SIZE 75 -#define CONV_4_OUT_ACTIVATION_MIN -128 -#define CONV_4_OUT_ACTIVATION_MAX 127 -#define CONV_4_INPUT_BATCHES 3 -#define CONV_4_INPUT_OFFSET 0 -#define CONV_4_OUTPUT_OFFSET 0 -#define CONV_4_FILTER_X 2 -#define CONV_4_FILTER_Y 3 -#define CONV_4_STRIDE_X 2 -#define CONV_4_STRIDE_Y 2 -#define CONV_4_PAD_X 0 -#define CONV_4_PAD_Y 0 -#define CONV_4_OUTPUT_W 2 -#define CONV_4_OUTPUT_H 2 - -const int32_t conv_4_biases[3] = { 2699, -5398, -2699 }; - -const q7_t conv_4_weights[54] = { - -127, 64, 64, -64, 0, 0, 64, -64, 0, -64, 64, 64, 64, -127, - 64, 0, -127, -64, 64, 64, -64, -64, -64, -64, -64, 0, 0, 64, - 64, 64, 0, 0, 0, -127, -64, -127, -127, 0, 0, 0, 0, -127, - -127, -127, -127, 64, -127, 64, 64, 0, 0, -64, -127, 64 +#define CONV_4_OUT_CH 3 +#define CONV_4_IN_CH 3 +#define CONV_4_INPUT_W 5 +#define CONV_4_INPUT_H 5 +#define CONV_4_DST_SIZE 36 +#define CONV_4_INPUT_SIZE 75 +#define CONV_4_OUT_ACTIVATION_MIN -109 +#define CONV_4_OUT_ACTIVATION_MAX 127 +#define CONV_4_INPUT_BATCHES 3 +#define CONV_4_FILTER_X 2 +#define CONV_4_FILTER_Y 3 +#define CONV_4_STRIDE_X 2 +#define CONV_4_STRIDE_Y 2 +#define CONV_4_PAD_X 0 +#define CONV_4_PAD_Y 0 +#define CONV_4_OUTPUT_W 2 +#define CONV_4_OUTPUT_H 2 +#define CONV_4_INPUT_OFFSET 128 +#define CONV_4_OUTPUT_OFFSET -128 +#define CONV_4_DILATION_X 1 +#define CONV_4_DILATION_Y 1 + +const int32_t conv_4_biases[3] = {13175, 9050, 18215}; + +const int8_t conv_4_weights[54] = { + -25, -83, -74, 105, 30, 118, -32, 127, 34, 127, -112, 39, -43, 104, 41, -124, 115, 5, + 42, -48, -119, 93, 17, 57, 41, -41, -42, 23, 127, 18, 70, -99, 71, 67, 83, 76, + -50, 98, 66, 64, 127, -6, -77, -48, -26, 45, 77, 1, 81, 27, 124, -103, 37, 36}; + +const int8_t conv_4_input[225] = { + 82, 120, -97, -44, -118, 73, 4, -84, -53, -122, -15, 77, 83, 43, 37, + 85, -11, 103, 45, -69, -12, -8, 21, 6, -68, -83, -15, -99, 90, -62, + 95, 62, -38, -32, -35, -105, -53, 70, 112, 14, -4, -33, -26, -93, -98, + 22, -5, 22, -104, 57, -92, 30, -62, 0, -43, -82, 60, 99, -83, 32, + 94, 49, 10, 112, -71, -27, -91, -79, 52, -92, -71, 86, -79, -15, -80, + -74, -4, 76, -119, 91, -23, -12, -111, -72, 26, 11, 64, 116, 38, 99, + 125, 17, 6, -4, 46, 119, 113, -116, -125, 80, -57, 122, 75, 119, -117, + 87, -121, -70, -75, -127, 16, -124, -110, 10, 71, 29, 27, 37, -24, 52, + 28, -100, 86, -75, 117, -31, -115, -86, -122, 121, -96, -118, 32, 111, 25, + -90, -8, 110, 37, 35, 124, -123, 94, -122, -114, 37, 85, -36, 53, -40, + 73, -99, 27, 10, 37, 41, 64, -97, -123, 75, 0, -107, -72, 58, -100, + 17, 77, 114, 120, -83, -96, 75, -12, -27, 3, 35, 85, 4, 119, -20, + 28, 99, 104, -78, -51, -82, -92, -40, -116, 35, -107, 39, 9, -120, -50, + -102, -114, 25, -77, 25, 7, 64, 110, 80, -93, -20, 34, 115, 75, 37, + 47, 16, 6, -92, -25, 37, 69, 82, -61, -100, -85, -51, 6, -95, 58 }; -const q7_t conv_4_input[225] = { - 42, -85, -85, 0, 42, 42, -42, -42, -42, -85, 42, 42, -42, -42, -85, - 0, -85, 0, 42, -42, 0, -42, 42, -42, -42, 42, -42, 42, -85, -42, - -85, -42, 0, -42, -42, -42, 42, -85, -42, -42, -42, 0, -42, 0, 0, - 0, 42, -42, 42, 0, -42, 0, 0, -85, 0, 42, 42, 0, 42, 42, -85, 42, - 42, -85, -42, 0, -85, 42, -42, -85, -42, -85, 42, 42, -85, -85, 42, - 42, 42, -85, 42, -85, -42, -42, 0, -42, -85, -85, 42, -85, 0, -85, - 42, 42, 0, 42, 42, 42, 42, -85, 42, -85, -42, 0, 42, 0, 0, -85, -42, - 0, -85, 0, 42, -85, -42, 0, -42, 0, 42, -42, -42, -85, 0, -85, -42, - -85, 0, 42, -85, -85, -85, -85, 0, -85, 42, 42, 0, -42, -85, -85, 0, - -42, 0, 0, -85, -85, -42, 42, -85, -42, -42, 42, -85, 0, 42, 0, -85, - 0, 0, 42, 42, -85, -85, -85, 0, 42, 0, 0, 42, -85, -85, 42, -85, -42, - -42, 0, -85, -85, 42, -85, 0, -85, -42, -85, 42, 0, 42, 42, 0, -85, - 0, 0, 0, 0, 0, -42, -85, 42, 0, -85, -42, 0, -42, 42, 42, -85, 0, - 42, 42, 0, -42, -85, -42, -85, 0, 42, -85, -85, -42, 42, -42, -42, - -42, -42, 42 -}; +const int32_t conv_4_output_mult[3] = {2039209398, 2005068758, 2023002003}; -const int32_t conv_4_output_mult[3] = { 1629660588, 1629660588, 1629660588 }; +const int32_t conv_4_output_shift[3] = {-9, -9, -9}; -const int32_t conv_4_output_shift[3] = { -11, -11, -11 }; - -const q7_t conv_4_output_ref[36] = { - -2, 2, 2, 8, 0, 1, 1, 3, 7, -2, 11, 0, 8, 4, 4, 1, -1, -5, - 4, 5, 14, 2, 5, 7, -1, -2, 2, 5, -4, 11, -1, -2, 8, 4, 2, 0 -}; +const int8_t conv_4_output_ref[36] = {-5, -39, -31, 20, -37, -26, -109, -7, -10, -51, -58, 48, + -100, -32, 24, 4, 69, -38, -64, 65, -34, 95, -55, 39, + 95, -54, 27, -49, 25, -68, -109, -66, 72, 38, -44, -40}; ZTEST(cmsis_nn, test_convolve) { - q7_t output[CONV_4_DST_SIZE] = { 0 }; + int8_t output[CONV_4_DST_SIZE] = {0}; cmsis_nn_context ctx; cmsis_nn_conv_params conv_params; @@ -158,9 +160,9 @@ ZTEST(cmsis_nn, test_convolve) cmsis_nn_dims bias_dims; cmsis_nn_dims output_dims; - const q31_t *bias_data = conv_4_biases; - const q7_t *kernel_data = conv_4_weights; - const q7_t *input_data = conv_4_input; + const int32_t *bias_data = conv_4_biases; + const int8_t *kernel_data = conv_4_weights; + const int8_t *input_data = conv_4_input; input_dims.n = CONV_4_INPUT_BATCHES; input_dims.w = CONV_4_INPUT_W; @@ -176,6 +178,8 @@ ZTEST(cmsis_nn, test_convolve) conv_params.padding.h = CONV_4_PAD_Y; conv_params.stride.w = CONV_4_STRIDE_X; conv_params.stride.h = CONV_4_STRIDE_Y; + conv_params.dilation.w = CONV_4_DILATION_X; + conv_params.dilation.h = CONV_4_DILATION_Y; conv_params.input_offset = CONV_4_INPUT_OFFSET; conv_params.output_offset = CONV_4_OUTPUT_OFFSET; @@ -189,7 +193,7 @@ ZTEST(cmsis_nn, test_convolve) ctx.buf = malloc(buf_size); ctx.size = 0; - arm_status result = arm_convolve_s8(&ctx, + arm_cmsis_nn_status result = arm_convolve_s8(&ctx, &conv_params, &quant_params, &input_dims, @@ -202,7 +206,7 @@ ZTEST(cmsis_nn, test_convolve) output); free(ctx.buf); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(conv_4_output_ref, output, sizeof(output), ""); buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, @@ -223,63 +227,63 @@ ZTEST(cmsis_nn, test_convolve) output); free(ctx.buf); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(conv_4_output_ref, output, sizeof(output), ""); } -#define STRIDE2PAD1_OUT_CH 1 -#define STRIDE2PAD1_IN_CH 1 -#define STRIDE2PAD1_INPUT_W 7 -#define STRIDE2PAD1_INPUT_H 7 -#define STRIDE2PAD1_DST_SIZE 16 -#define STRIDE2PAD1_INPUT_SIZE 49 -#define STRIDE2PAD1_OUT_ACTIVATION_MIN -128 -#define STRIDE2PAD1_OUT_ACTIVATION_MAX 127 -#define STRIDE2PAD1_INPUT_BATCHES 1 -#define STRIDE2PAD1_INPUT_OFFSET 128 -#define STRIDE2PAD1_OUTPUT_OFFSET 0 -#define STRIDE2PAD1_FILTER_X 3 -#define STRIDE2PAD1_FILTER_Y 3 -#define STRIDE2PAD1_STRIDE_X 2 -#define STRIDE2PAD1_STRIDE_Y 2 -#define STRIDE2PAD1_PAD_X 1 -#define STRIDE2PAD1_PAD_Y 1 -#define STRIDE2PAD1_OUTPUT_W 4 -#define STRIDE2PAD1_OUTPUT_H 4 - -const int32_t stride2pad1_biases[1] = { 4318 }; - -const q7_t stride2pad1_weights[9] = { 42, 127, 127, 127, 42, 127, 85, 42, 85 }; - -const q7_t stride2pad1_input[49] = { - -26, -77, -26, -26, 25, -77, -77, -26, 25, -26, -77, -26, -26, -77, 25, -77, -26, - -26, -77, -26, -77, -26, -77, -26, 25, -77, -26, -26, -26, 25, -26, -77, -77, -77, - -26, 25, 25, -26, -77, -26, -26, -26, -26, -26, -77, -26, 25, -77, -26 -}; - -const int32_t stride2pad1_output_mult[1] = { 2037075735 }; - -const int32_t stride2pad1_output_shift[1] = { -11 }; - -const q7_t stride2pad1_output_ref[16] = { - 15, 23, 22, 11, 27, 35, 39, 20, 31, 42, 29, 21, 28, 27, 27, 15 -}; +#define STRIDE2PAD1_OUT_CH 1 +#define STRIDE2PAD1_IN_CH 1 +#define STRIDE2PAD1_INPUT_W 7 +#define STRIDE2PAD1_INPUT_H 7 +#define STRIDE2PAD1_DST_SIZE 16 +#define STRIDE2PAD1_INPUT_SIZE 49 +#define STRIDE2PAD1_OUT_ACTIVATION_MIN -128 +#define STRIDE2PAD1_OUT_ACTIVATION_MAX 127 +#define STRIDE2PAD1_INPUT_BATCHES 1 +#define STRIDE2PAD1_FILTER_X 3 +#define STRIDE2PAD1_FILTER_Y 3 +#define STRIDE2PAD1_STRIDE_X 2 +#define STRIDE2PAD1_STRIDE_Y 2 +#define STRIDE2PAD1_PAD_X 1 +#define STRIDE2PAD1_PAD_Y 1 +#define STRIDE2PAD1_OUTPUT_W 4 +#define STRIDE2PAD1_OUTPUT_H 4 +#define STRIDE2PAD1_INPUT_OFFSET 128 +#define STRIDE2PAD1_OUTPUT_OFFSET -20 +#define STRIDE2PAD1_DILATION_X 1 +#define STRIDE2PAD1_DILATION_Y 1 + +const int32_t stride2pad1_biases[1] = {-9794}; + +const int8_t stride2pad1_weights[9] = {-54, 57, -19, -127, 87, 70, 74, -110, 66}; + +const int8_t stride2pad1_input[49] = { + -91, -30, -57, -76, 32, -13, 14, -96, 108, -4, 41, 48, 107, -68, -101, 30, 95, + 95, 91, -66, -80, 114, -49, 7, -67, -35, -1, -88, -77, -56, -103, 5, -39, -118, + -24, -32, 67, 11, 38, -16, -124, 44, -46, -92, -24, 108, 80, -29, -3}; + +const int32_t stride2pad1_output_mult[1] = {2033801520}; + +const int32_t stride2pad1_output_shift[1] = {-8}; + +const int8_t stride2pad1_output_ref[16] = {26, -11, 33, -25, -96, -52, -78, -86, + 33, -2, -88, -113, -14, 0, -84, -27}; ZTEST(cmsis_nn, test_depthwise_convolve) { - q7_t output[STRIDE2PAD1_DST_SIZE] = { 0 }; + int8_t output[STRIDE2PAD1_DST_SIZE] = {0}; cmsis_nn_context ctx; cmsis_nn_dw_conv_params dw_conv_params; cmsis_nn_per_channel_quant_params quant_params; cmsis_nn_dims input_dims; cmsis_nn_dims filter_dims; - cmsis_nn_dims bias_dims = { 0 }; + cmsis_nn_dims bias_dims = {0}; cmsis_nn_dims output_dims; - const q31_t *bias_data = stride2pad1_biases; - const q7_t *kernel_data = stride2pad1_weights; - const q7_t *input_data = stride2pad1_input; + const int32_t *bias_data = stride2pad1_biases; + const int8_t *kernel_data = stride2pad1_weights; + const int8_t *input_data = stride2pad1_input; input_dims.n = STRIDE2PAD1_INPUT_BATCHES; input_dims.w = STRIDE2PAD1_INPUT_W; @@ -295,6 +299,9 @@ ZTEST(cmsis_nn, test_depthwise_convolve) dw_conv_params.padding.h = STRIDE2PAD1_PAD_Y; dw_conv_params.stride.w = STRIDE2PAD1_STRIDE_X; dw_conv_params.stride.h = STRIDE2PAD1_STRIDE_Y; + dw_conv_params.dilation.w = STRIDE2PAD1_DILATION_X; + dw_conv_params.dilation.h = STRIDE2PAD1_DILATION_Y; + dw_conv_params.ch_mult = 1; dw_conv_params.input_offset = STRIDE2PAD1_INPUT_OFFSET; @@ -307,7 +314,7 @@ ZTEST(cmsis_nn, test_depthwise_convolve) ctx.buf = NULL; ctx.size = 0; - arm_status result = arm_depthwise_conv_s8(&ctx, + arm_cmsis_nn_status result = arm_depthwise_conv_s8(&ctx, &dw_conv_params, &quant_params, &input_dims, @@ -320,46 +327,47 @@ ZTEST(cmsis_nn, test_depthwise_convolve) output); free(ctx.buf); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(stride2pad1_output_ref, output, sizeof(output), ""); } -#define FULLY_CONNECTED_MVE_0_OUT_CH 9 -#define FULLY_CONNECTED_MVE_0_IN_CH 16 -#define FULLY_CONNECTED_MVE_0_INPUT_W 1 -#define FULLY_CONNECTED_MVE_0_INPUT_H 1 -#define FULLY_CONNECTED_MVE_0_DST_SIZE 9 -#define FULLY_CONNECTED_MVE_0_INPUT_SIZE 16 -#define FULLY_CONNECTED_MVE_0_OUT_ACTIVATION_MIN -128 -#define FULLY_CONNECTED_MVE_0_OUT_ACTIVATION_MAX 127 -#define FULLY_CONNECTED_MVE_0_INPUT_BATCHES 1 -#define FULLY_CONNECTED_MVE_0_INPUT_OFFSET 3 -#define FULLY_CONNECTED_MVE_0_OUTPUT_OFFSET -2 -#define FULLY_CONNECTED_MVE_0_OUTPUT_MULTIPLIER 1073741824 -#define FULLY_CONNECTED_MVE_0_OUTPUT_SHIFT 1 -#define FULLY_CONNECTED_MVE_0_ACCUMULATION_DEPTH 16 - -const int32_t fully_connected_mve_0_biases[9] = { -1, 0, 0, 2, -1, -1, 1, -3, -4 }; - -const q7_t fully_connected_mve_0_input[16] = { - -5, -3, -5, -3, -3, -6, -1, -5, -4, -3, -2, 0, -2, -1, -2, -6 -}; - -const q7_t fully_connected_mve_0_output_ref[9] = { 0, -29, 33, -5, 28, -5, 19, -7, 16 }; - -const q7_t fully_connected_mve_0_weights[144] = { - 1, 0, -1, -3, -4, -3, 3, -2, 3, 3, 1, 2, -2, -4, -4, 2, 3, 2, 3, -1, -2, 2, - -4, 0, 1, -3, -3, -3, 1, 1, -3, -4, -3, 3, 2, 3, 1, -4, 3, -3, -1, 3, 1, -2, - 2, 3, -4, -3, 2, -4, 0, 3, 0, -2, 0, -1, -2, 0, 3, -3, -1, -2, -3, -1, -4, - 1, 2, -1, -4, -4, 1, -3, -3, 2, 3, 1, -3, -2, -4, -3, -2, 2, 1, 1, 1, -2, 0, - 3, -3, -2, -1, -4, -2, 2, 1, -1, -4, 2, 2, 3, 3, 2, 0, -3, 2, 3, 0, 3, 3, -1, - -4, -4, 0, 1, -4, -1, -3, 3, 2, 3, 2, -3, -1, -3, 0, 3, -2, -3, -2, 3, -4, 3, - -1, -4, 2, 2, 3, 1, -1, 1, 0, -4, -2, -3 -}; +#define FULLY_CONNECTED_MVE_0_OUT_CH 9 +#define FULLY_CONNECTED_MVE_0_IN_CH 16 +#define FULLY_CONNECTED_MVE_0_INPUT_W 1 +#define FULLY_CONNECTED_MVE_0_INPUT_H 1 +#define FULLY_CONNECTED_MVE_0_DST_SIZE 9 +#define FULLY_CONNECTED_MVE_0_INPUT_SIZE 16 +#define FULLY_CONNECTED_MVE_0_OUT_ACTIVATION_MIN -128 +#define FULLY_CONNECTED_MVE_0_OUT_ACTIVATION_MAX 127 +#define FULLY_CONNECTED_MVE_0_INPUT_BATCHES 1 +#define FULLY_CONNECTED_MVE_0_OUTPUT_MULTIPLIER 1244038257 +#define FULLY_CONNECTED_MVE_0_OUTPUT_SHIFT -9 +#define FULLY_CONNECTED_MVE_0_ACCUMULATION_DEPTH 16 +#define FULLY_CONNECTED_MVE_0_INPUT_OFFSET 128 +#define FULLY_CONNECTED_MVE_0_OUTPUT_OFFSET -26 + +const int32_t fully_connected_mve_0_biases[9] = {11295, -30752, -3196, 10489, -5120, + 18598, 27393, 29746, 22967}; + +const int8_t fully_connected_mve_0_input[16] = {-43, 68, 79, -12, -119, -56, -102, -46, + 107, -65, -109, -7, 92, -99, -80, -29}; + +const int8_t fully_connected_mve_0_output_ref[9] = {-9, -3, 26, 8, 3, -88, 75, 34, 5}; + +const int8_t fully_connected_mve_0_weights[144] = { + 37, -46, 75, -33, -52, -82, -94, 64, 71, 65, 64, 16, -66, -5, -65, -44, + 82, 42, 84, 105, 18, 79, -103, -75, -95, 65, 87, 103, 43, -25, -66, 75, + 125, 40, -34, 24, 9, -79, 4, 73, 98, -75, 42, 81, 18, -58, -119, 92, + 0, -72, 48, 23, -69, 11, -95, -103, 66, 117, 107, -96, 114, -29, 75, -93, + 118, 66, -19, 83, -14, 86, -110, 44, 37, -9, 17, -107, 50, -116, -116, -27, + -84, -126, -108, -127, -71, 8, 81, 108, -61, 126, 69, -45, 37, -78, -102, -55, + 116, 112, -111, -89, -57, 82, -47, 22, 125, -84, 97, -9, 88, 74, -15, 118, + -95, 112, 89, 44, -17, -112, -71, -94, 1, -117, 112, -92, 52, 57, -22, 80, + -60, 95, -106, -1, -27, 105, 6, 123, 6, 96, 126, -65, -29, 103, 19, -45}; ZTEST(cmsis_nn, test_fully_connected) { - q7_t output[FULLY_CONNECTED_MVE_0_DST_SIZE] = { 0 }; + int8_t output[FULLY_CONNECTED_MVE_0_DST_SIZE] = {0}; cmsis_nn_context ctx; cmsis_nn_fc_params fc_params; @@ -369,9 +377,9 @@ ZTEST(cmsis_nn, test_fully_connected) cmsis_nn_dims bias_dims; cmsis_nn_dims output_dims; - const q31_t *bias_data = fully_connected_mve_0_biases; - const q7_t *kernel_data = fully_connected_mve_0_weights; - const q7_t *input_data = fully_connected_mve_0_input; + const int32_t *bias_data = fully_connected_mve_0_biases; + const int8_t *kernel_data = fully_connected_mve_0_weights; + const int8_t *input_data = fully_connected_mve_0_input; input_dims.n = FULLY_CONNECTED_MVE_0_INPUT_BATCHES; input_dims.w = FULLY_CONNECTED_MVE_0_INPUT_W; @@ -395,7 +403,7 @@ ZTEST(cmsis_nn, test_fully_connected) ctx.buf = malloc(buf_size); ctx.size = buf_size; - arm_status result = arm_fully_connected_s8(&ctx, + arm_cmsis_nn_status result = arm_fully_connected_s8(&ctx, &fc_params, &quant_params, &input_dims, @@ -408,45 +416,43 @@ ZTEST(cmsis_nn, test_fully_connected) output); free(ctx.buf); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(fully_connected_mve_0_output_ref, output, sizeof(output), ""); } -#define MAXPOOLING_2_OUT_CH 5 -#define MAXPOOLING_2_IN_CH 5 -#define MAXPOOLING_2_INPUT_W 12 -#define MAXPOOLING_2_INPUT_H 1 -#define MAXPOOLING_2_DST_SIZE 60 -#define MAXPOOLING_2_INPUT_SIZE 60 +#define MAXPOOLING_2_OUT_CH 5 +#define MAXPOOLING_2_IN_CH 5 +#define MAXPOOLING_2_INPUT_W 12 +#define MAXPOOLING_2_INPUT_H 1 +#define MAXPOOLING_2_DST_SIZE 60 +#define MAXPOOLING_2_INPUT_SIZE 60 #define MAXPOOLING_2_OUT_ACTIVATION_MIN -128 #define MAXPOOLING_2_OUT_ACTIVATION_MAX 127 -#define MAXPOOLING_2_INPUT_BATCHES 1 -#define MAXPOOLING_2_FILTER_X 3 -#define MAXPOOLING_2_FILTER_Y 1 -#define MAXPOOLING_2_STRIDE_X 1 -#define MAXPOOLING_2_STRIDE_Y 2 -#define MAXPOOLING_2_PAD_X 1 -#define MAXPOOLING_2_PAD_Y 0 -#define MAXPOOLING_2_OUTPUT_W 12 -#define MAXPOOLING_2_OUTPUT_H 1 +#define MAXPOOLING_2_INPUT_BATCHES 1 +#define MAXPOOLING_2_FILTER_X 3 +#define MAXPOOLING_2_FILTER_Y 1 +#define MAXPOOLING_2_STRIDE_X 1 +#define MAXPOOLING_2_STRIDE_Y 2 +#define MAXPOOLING_2_PAD_X 1 +#define MAXPOOLING_2_PAD_Y 0 +#define MAXPOOLING_2_OUTPUT_W 12 +#define MAXPOOLING_2_OUTPUT_H 1 const int8_t maxpooling_2_input[60] = { - -16, 32, -16, -48, -16, 16, 64, 0, -112, 80, -64, 48, -64, 80, -16, - -80, -96, 48, 32, 96, 64, 80, 16, -96, 32, -112, -16, -80, -48, 32, - -64, -32, -16, 80, 48, -80, 96, -96, 64, -64, -112, 32, 96, -16, -16, - 96, 0, -16, -16, -32, 64, -96, 96, 96, -48, -64, -16, 32, 16, 64 -}; + 75, -52, -42, -30, 56, 64, 106, -36, 120, -3, 34, -105, 69, 75, -39, + 15, 93, -71, 39, 34, -11, 65, 22, 59, 106, 105, 45, -116, -75, 123, + -65, 75, -61, 13, -25, -123, 59, 110, -65, 86, -108, -107, -17, 38, 27, + -1, -115, -123, 75, -75, 68, 52, 12, -35, 116, -68, 22, 15, 76, -81}; const int8_t maxpooling_2_output_ref[60] = { - 16, 64, 0, -48, 80, 16, 64, 0, 80, 80, 16, 64, 48, 80, 96, - 64, 80, 48, 80, 96, 64, 80, 48, 32, 96, 64, 80, 16, 80, 48, - -64, 96, -16, 80, 48, -64, 96, 96, 80, 48, 96, 96, 96, 64, -16, - 96, 32, 96, 96, -16, 96, 0, 96, 96, 64, 64, -16, 96, 96, 64 -}; + 75, 106, -36, 120, 56, 75, 106, 69, 120, 56, 64, 106, 69, 120, 34, + 34, 93, 69, 75, 106, 105, 93, 22, 59, 123, 105, 75, 22, 59, 123, + 105, 75, 110, 13, 123, -65, 75, 110, 38, 86, -1, 59, 110, 75, 86, + 68, 52, 12, 75, 116, 68, 52, 15, 76, 116, 68, 52, 15, 76, 116}; ZTEST(cmsis_nn, test_max_pool) { - q7_t output[MAXPOOLING_2_DST_SIZE] = { 0 }; + int8_t output[MAXPOOLING_2_DST_SIZE] = {0}; cmsis_nn_context ctx; cmsis_nn_pool_params pool_params; @@ -454,7 +460,7 @@ ZTEST(cmsis_nn, test_max_pool) cmsis_nn_dims filter_dims; cmsis_nn_dims output_dims; - const q7_t *input_data = maxpooling_2_input; + const int8_t *input_data = maxpooling_2_input; input_dims.n = MAXPOOLING_2_INPUT_BATCHES; input_dims.w = MAXPOOLING_2_INPUT_W; @@ -475,24 +481,25 @@ ZTEST(cmsis_nn, test_max_pool) pool_params.activation.max = MAXPOOLING_2_OUT_ACTIVATION_MAX; for (int i = 0; i < REPEAT_NUM; i++) { - arm_status result = arm_max_pool_s8(&ctx, &pool_params, &input_dims, input_data, - &filter_dims, &output_dims, output); + arm_cmsis_nn_status result = + arm_max_pool_s8(&ctx, &pool_params, &input_dims, input_data, &filter_dims, + &output_dims, output); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); zassert_mem_equal(maxpooling_2_output_ref, output, sizeof(output), ""); } } -#define SOFTMAX_NUM_ROWS 1 -#define SOFTMAX_ROW_SIZE 5 -#define SOFTMAX_INPUT_MULT 1077952576 -#define SOFTMAX_INPUT_LEFT_SHIFT 23 -#define SOFTMAX_DIFF_MIN -248 -#define SOFTMAX_DST_SIZE 5 +#define SOFTMAX_NUM_ROWS 2 +#define SOFTMAX_ROW_SIZE 5 +#define SOFTMAX_INPUT_MULT 1077952640 +#define SOFTMAX_INPUT_LEFT_SHIFT 19 +#define SOFTMAX_DIFF_MIN -3968 +#define SOFTMAX_DST_SIZE 10 -const q7_t softmax_input[5] = { -80, -48, 16, 0, -96 }; +const int8_t softmax_input[10] = {101, 49, 6, -34, -75, -79, -38, 120, -55, 115}; -const q7_t softmax_output_ref[5] = { -128, -125, 56, -60, -128 }; +const int8_t softmax_output_ref[10] = {-57, -70, -79, -86, -92, -94, -88, -54, -91, -56}; ZTEST(cmsis_nn, test_softmax) { @@ -501,7 +508,7 @@ ZTEST(cmsis_nn, test_softmax) const int32_t mult = SOFTMAX_INPUT_MULT; const int32_t shift = SOFTMAX_INPUT_LEFT_SHIFT; const int32_t diff_min = SOFTMAX_DIFF_MIN; - const q7_t *input_data = softmax_input; + const int8_t *input_data = softmax_input; int8_t output[SOFTMAX_DST_SIZE]; for (int i = 0; i < REPEAT_NUM; i++) { @@ -510,52 +517,46 @@ ZTEST(cmsis_nn, test_softmax) } } -#define SVDF_2_INPUT_OFFSET 0 -#define SVDF_2_OUTPUT_OFFSET 0 -#define SVDF_2_MULTIPLIER_IN 1347440720 -#define SVDF_2_MULTIPLIER_OUT 1073741824 -#define SVDF_2_SHIFT_1 -4 -#define SVDF_2_SHIFT_2 1 -#define SVDF_2_IN_ACTIVATION_MIN -32767 -#define SVDF_2_IN_ACTIVATION_MAX 32767 -#define SVDF_2_RANK 2 -#define SVDF_2_FEATURE_BATCHES 10 -#define SVDF_2_TIME_BATCHES 2 -#define SVDF_2_INPUT_SIZE 7 -#define SVDF_2_DST_SIZE 15 -#define SVDF_2_OUT_ACTIVATION_MIN -128 -#define SVDF_2_OUT_ACTIVATION_MAX 127 -#define SVDF_2_INPUT_BATCHES 3 - -const int32_t svdf_2_biases[5] = { 0, 0, 0, 0, 0 }; - - -const q15_t svdf_2_state[60] = { - 3, 1, -1, 2, 1, 4, 3, 2, 2, 1, 4, -1, -3, 3, 4, 3, 1, -1, 3, 2, - 0, -2, -1, -2, -1, -3, 0, -3, 4, 3, -1, 4, -4, -1, 2, 3, -4, -3, -2, 1, - 1, 4, 3, -2, -3, -2, 4, 0, -2, 1, -2, -3, -4, 2, 0, -2, -3, 0, -1, 0 -}; - -const q7_t svdf_2_weights_feature[70] = { - -4, 0, 2, -2, 1, 1, -1, 0, -1, 2, -1, 1, 1, 3, -3, -2, -2, 3, - 3, -3, 1, 2, 1, -4, 0, 2, -2, -1, 3, 1, 0, 0, 1, -2, 0, 2, - 1, 0, -1, 2, 3, -1, 3, -1, -1, -2, -4, -3, 1, 1, 2, -3, 3, -3, - 0, 0, 2, 0, 2, -1, -1, -3, -3, 1, 2, 2, 3, -2, 3, 1 -}; - -const q15_t svdf_2_weights_time[20] = { - -4, 3, 0, -3, -2, 0, 3, 0, -3, -2, 2, 1, -4, 3, 1, 0, 3, -2, 1, 1 -}; - -const q7_t svdf_2_input_sequence[42] = { - -51, 0, -26, 76, -102, -102, -76, 0, -51, -26, -51, -26, 51, 0, - 51, -102, 51, -102, -76, 51, 76, -26, 26, -51, -76, -26, -102, -76, - -26, 26, 0, 51, 76, 0, 0, 26, -26, 76, -26, 76, 76, 26 -}; - -const q7_t svdf_2_output_ref[15] = { - 80, -19, -61, 17, -17, -3, 6, 30, -84, -4, -24, -11, 35, -128, 19 -}; +#define SVDF_2_MULTIPLIER_IN 1717987072 +#define SVDF_2_MULTIPLIER_OUT 1099511552 +#define SVDF_2_SHIFT_1 -3 +#define SVDF_2_SHIFT_2 -11 +#define SVDF_2_IN_ACTIVATION_MIN -32768 +#define SVDF_2_IN_ACTIVATION_MAX 32767 +#define SVDF_2_RANK 2 +#define SVDF_2_FEATURE_BATCHES 10 +#define SVDF_2_TIME_BATCHES 2 +#define SVDF_2_INPUT_SIZE 7 +#define SVDF_2_DST_SIZE 15 +#define SVDF_2_OUT_ACTIVATION_MIN -128 +#define SVDF_2_OUT_ACTIVATION_MAX 127 +#define SVDF_2_INPUT_BATCHES 3 +#define SVDF_2_INPUT_OFFSET 0 +#define SVDF_2_OUTPUT_OFFSET 0 + +const int32_t svdf_2_biases[5] = {0, 0, 0, 0, 0}; + +const int16_t svdf_2_state[60] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const int8_t svdf_2_weights_feature[70] = { + 27, 82, -108, -127, 85, 3, -51, 32, 110, -6, -14, -16, 31, 101, + -122, 19, 76, 74, -80, 12, -22, -17, 10, -28, 55, 109, 2, -107, + -4, 72, -65, -59, 36, -69, 105, -97, 25, 38, 110, -121, -88, -126, + -14, 16, -88, -66, 3, -93, 69, -64, 44, 103, 95, -95, 68, -46, + 106, -31, -63, 23, -38, 36, -95, -43, 93, 77, 91, -26, 33, 59}; + +const int16_t svdf_2_weights_time[20] = {-31, -88, -10, -72, -119, -6, -70, 63, -10, 93, + 5, 42, -6, 22, 6, 51, 37, -38, 5, 117}; + +const int8_t svdf_2_input_sequence[42] = { + 29, 81, -38, 17, -116, 43, 119, -127, 74, 115, 9, 118, 7, -56, + -53, -14, -98, 60, -128, 10, 28, -18, 12, -28, -126, 87, -115, -44, + -123, -109, -59, -87, -69, 121, -128, -95, -70, 2, 81, -119, 84, -122}; + +const int8_t svdf_2_output_ref[15] = {-53, 45, 27, -24, -53, 26, -82, -38, + 11, -85, 94, -16, -32, 31, 4}; static bool check_null_bias(const int32_t *bias, int32_t size) { @@ -585,8 +586,8 @@ ZTEST(cmsis_nn, test_svdf) cmsis_nn_per_tensor_quant_params output_quant_params; int8_t output_data[SVDF_2_DST_SIZE]; - const q7_t *weights_feature_data = svdf_2_weights_feature; - const q15_t *weights_time_data = svdf_2_weights_time; + const int8_t *weights_feature_data = svdf_2_weights_feature; + const int16_t *weights_time_data = svdf_2_weights_time; input_dims.n = SVDF_2_INPUT_BATCHES; input_dims.h = SVDF_2_INPUT_SIZE; @@ -616,7 +617,7 @@ ZTEST(cmsis_nn, test_svdf) output_ctx.buf = malloc(scratch_size_out); int8_t *input_data = malloc(input_round_size); - q15_t *state_data = malloc(sizeof(svdf_2_state)); + int16_t *state_data = malloc(sizeof(svdf_2_state)); const bool null_bias = check_null_bias(svdf_2_biases, SVDF_2_DST_SIZE / SVDF_2_INPUT_BATCHES); @@ -625,7 +626,7 @@ ZTEST(cmsis_nn, test_svdf) for (int j = 0; j < number_inputs; j++) { memcpy(input_data, svdf_2_input_sequence + j * input_round_size, input_round_size); - arm_status result = arm_svdf_s8(&input_ctx, + arm_cmsis_nn_status result = arm_svdf_state_s16_s8(&input_ctx, &output_ctx, &svdf_2_params, &input_quant_params, @@ -642,7 +643,7 @@ ZTEST(cmsis_nn, test_svdf) null_bias == true ? NULL : svdf_2_biases, &output_dims, output_data); - zassert_equal(ARM_MATH_SUCCESS, result, ""); + zassert_equal(ARM_CMSIS_NN_SUCCESS, result, ""); } zassert_mem_equal(svdf_2_output_ref, output_data, sizeof(output_data), ""); diff --git a/west.yml b/west.yml index 21c70feebc2..255ef61e450 100644 --- a/west.yml +++ b/west.yml @@ -129,6 +129,9 @@ manifest: - name: cmsis-dsp revision: ff7b5fd1ea5f094665c090c343ec44e74dc0b193 path: modules/lib/cmsis-dsp + - name: cmsis-nn + revision: 0c8669d81381ccf3b1a01d699f3b68b50134a99f + path: modules/lib/cmsis-nn - name: edtt revision: 64e5105ad82390164fb73fc654be3f73a608209a path: tools/edtt From d2f82648cd350b9586b803b81c3180f83dd35727 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sun, 16 Apr 2023 22:23:02 -0700 Subject: [PATCH 0935/4498] modules: tflite-micro: update to latest Update tflite-micro to use the latest. This also updates to use the cmsis-nn module. Signed-off-by: Ryan McClelland --- modules/tflite-micro/CMakeLists.txt | 67 ++++++++++++++++++++++++++--- west.yml | 5 +-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/modules/tflite-micro/CMakeLists.txt b/modules/tflite-micro/CMakeLists.txt index b1eb41ca998..ce1cd370c1a 100644 --- a/modules/tflite-micro/CMakeLists.txt +++ b/modules/tflite-micro/CMakeLists.txt @@ -13,11 +13,12 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/third_party_static/gemmlowp ${TENSORFLOW_LITE_MICRO_DIR}/third_party_static/flatbuffers/include ${TENSORFLOW_LITE_MICRO_DIR}/third_party_static/ruy + ${TENSORFLOW_LITE_MICRO_DIR}/third_party_static/kissfft ) if(CONFIG_TENSORFLOW_LITE_MICRO_CMSIS_NN_KERNELS) set(CMSIS_NN_OPTIMIZED_KERNEL_DIR cmsis_nn) - set(tflm_cmsis_nn_glue_path ${ZEPHYR_CMSIS_MODULE_DIR}) + set(tflm_cmsis_nn_glue_path ${ZEPHYR_CMSIS_NN_MODULE_DIR}) zephyr_library_include_directories(${tflm_cmsis_nn_glue_path}) zephyr_library_compile_definitions(CMSIS_NN) @@ -28,15 +29,28 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) endif() zephyr_library_sources( - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/simple_memory_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/python/tflite_micro/python_ops_resolver.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/micro/kernels/fft_flexbuffers_generated_data.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/micro/kernels/rfft.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/micro/kernels/window.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/micro/kernels/window_flexbuffers_generated_data.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/rfft_float.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/rfft_int16.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/rfft_int32.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/window.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_float.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_int16.cc + ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_int32.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/array.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/c/common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/debug_log.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_error_reporter.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/all_ops_resolver.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/fake_micro_context.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/memory_helpers.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_allocation_info.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/test_helpers.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/test_helper_custom_ops.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/recording_micro_allocator.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_time.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/recording_simple_memory_allocator.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_string.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_profiler.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_utils.cc @@ -45,11 +59,26 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/mock_micro_graph.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_interpreter.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_context.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_log.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_op_resolver.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_resource_variable.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/system_setup.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/arena_allocator/non_persistent_arena_buffer_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/arena_allocator/persistent_arena_buffer_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/arena_allocator/recording_single_arena_buffer_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/arena_allocator/single_arena_buffer_allocator.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/tflite_bridge/flatbuffer_conversions_bridge.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/memory_planner/linear_memory_planner.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/memory_planner/greedy_memory_planner.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/c/common.c + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/quantization_util.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/portable_tensor_utils.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/tensor_ctypes.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/tensor_utils.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/reference/comparisons.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/kernel_util.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/flatbuffer_conversions.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/error_reporter.cc @@ -59,12 +88,18 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/add.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/add_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/add_n.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/arg_min_max.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/assign_variable.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/batch_to_space_nd.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/broadcast_args.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/broadcast_to.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/call_once.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/cast.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/ceil.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/circular_buffer.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/circular_buffer_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/comparisons.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/concatenation.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/conv.cc @@ -74,9 +109,12 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/depthwise_conv.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/depthwise_conv_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/dequantize.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/dequantize_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/detection_postprocess.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/div.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/elementwise.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/elu.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/embedding_lookup.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${ETHOSU_CO_PROCESSOR}/ethosu.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/exp.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/expand_dims.cc @@ -96,42 +134,59 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/l2norm.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/l2_pool_2d.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/leaky_relu.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/leaky_relu_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/logical.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/logical_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/logistic.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/logistic_common.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/lstm_eval.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/lstm_eval_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/log_softmax.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/maximum_minimum.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/micro_tensor_utils.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/mirror_pad.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/mul.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/mul_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/neg.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/pack.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/pad.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/pooling.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/pooling_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/prelu.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/prelu_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/quantize.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/quantize_common.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/read_variable.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/reduce.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/reduce_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/reshape.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/reshape_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/resize_bilinear.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/round.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/select.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/shape.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/slice.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/softmax.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/softmax_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/space_to_batch_nd.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/space_to_depth.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/split.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/split_v.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/squared_difference.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/squeeze.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/strided_slice.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/sub.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/sub_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/svdf.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/svdf_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/tanh.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/transpose.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/transpose_conv.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/unidirectional_sequence_lstm.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/unpack.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/var_handle.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/while.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/zeros_like.cc ) diff --git a/west.yml b/west.yml index 255ef61e450..d23243ad03c 100644 --- a/west.yml +++ b/west.yml @@ -122,7 +122,7 @@ manifest: revision: b7955c27e50485b7dafdc3888d7d6afdc2ac6d96 path: modules/lib/chre - name: cmsis - revision: 1abf29132e608826752e2edd1f4799a065db4031 + revision: 5a00331455dd74e31e80efa383a489faea0590e3 path: modules/hal/cmsis groups: - hal @@ -328,9 +328,8 @@ manifest: revision: c0f20b69daa44e3563f970b366e49ccfcfa1b71c path: modules/audio/sof - name: tflite-micro - revision: 9156d050927012da87079064db59d07f03b8baf6 + revision: 1a34dcab41e7e0e667db72d6a40999c1ec9c510c path: modules/lib/tflite-micro - repo-path: tflite-micro - name: tinycrypt revision: 3e9a49d2672ec01435ffbf0d788db6d95ef28de0 path: modules/crypto/tinycrypt From 65a15e929933190ebc635856a77cca8b964dce8e Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 18 Apr 2023 11:35:10 -0700 Subject: [PATCH 0936/4498] samples: tflite-micro: update samples for latest tflite-micro tflite-micro now uses MicroPrintf instead of MicroErrorReporter. Update the samples to use this function instead. AllOpsResolver is now removed from tflite-micro. AllOpsResolver was also removed in the latest tflite-micro. Use MicroMutableOpResolver and only include the kernels used instead. Signed-off-by: Ryan McClelland --- .../modules/tflite-micro/hello_world/prj.conf | 1 + .../hello_world/src/main_functions.cpp | 34 +++++++------------ .../hello_world/src/output_handler.cpp | 9 +++-- .../hello_world/src/output_handler.hpp | 5 ++- .../modules/tflite-micro/magic_wand/prj.conf | 1 + .../magic_wand/src/accelerometer_handler.cpp | 18 +++++----- .../magic_wand/src/accelerometer_handler.hpp | 7 ++-- .../magic_wand/src/main_functions.cpp | 33 ++++++------------ .../magic_wand/src/output_handler.cpp | 11 +++--- .../magic_wand/src/output_handler.hpp | 4 +-- .../modules/tflite-micro/tflm_ethosu/prj.conf | 1 + .../tflm_ethosu/src/inference_process.cpp | 11 +++--- 12 files changed, 54 insertions(+), 81 deletions(-) diff --git a/samples/modules/tflite-micro/hello_world/prj.conf b/samples/modules/tflite-micro/hello_world/prj.conf index 33f91a57e72..c4652d4f7c3 100644 --- a/samples/modules/tflite-micro/hello_world/prj.conf +++ b/samples/modules/tflite-micro/hello_world/prj.conf @@ -13,5 +13,6 @@ # limitations under the License. # ==============================================================================s CONFIG_CPP=y +CONFIG_STD_CPP17=y CONFIG_TENSORFLOW_LITE_MICRO=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/modules/tflite-micro/hello_world/src/main_functions.cpp b/samples/modules/tflite-micro/hello_world/src/main_functions.cpp index 7ebfea59c7c..1666e161cf9 100644 --- a/samples/modules/tflite-micro/hello_world/src/main_functions.cpp +++ b/samples/modules/tflite-micro/hello_world/src/main_functions.cpp @@ -16,18 +16,17 @@ #include "main_functions.h" -#include +#include #include "constants.h" #include "model.hpp" #include "output_handler.hpp" -#include +#include #include #include #include /* Globals, used for compatibility with Arduino-style sketches. */ namespace { - tflite::ErrorReporter *error_reporter = nullptr; const tflite::Model *model = nullptr; tflite::MicroInterpreter *interpreter = nullptr; TfLiteTensor *input = nullptr; @@ -41,40 +40,32 @@ namespace { /* The name of this function is important for Arduino compatibility. */ void setup(void) { - /* Set up logging. Google style is to avoid globals or statics because of - * lifetime uncertainty, but since this has a trivial destructor it's okay. - * NOLINTNEXTLINE(runtime-global-variables) - */ - static tflite::MicroErrorReporter micro_error_reporter; - - error_reporter = µ_error_reporter; - /* Map the model into a usable data structure. This doesn't involve any * copying or parsing, it's a very lightweight operation. */ model = tflite::GetModel(g_model); if (model->version() != TFLITE_SCHEMA_VERSION) { - TF_LITE_REPORT_ERROR(error_reporter, - "Model provided is schema version %d not equal " - "to supported version %d.", - model->version(), TFLITE_SCHEMA_VERSION); + MicroPrintf("Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); return; } - /* This pulls in all the operation implementations we need. + /* This pulls in the operation implementations we need. * NOLINTNEXTLINE(runtime-global-variables) */ - static tflite::AllOpsResolver resolver; + static tflite::MicroMutableOpResolver <1> resolver; + resolver.AddFullyConnected(); /* Build an interpreter to run the model with. */ static tflite::MicroInterpreter static_interpreter( - model, resolver, tensor_arena, kTensorArenaSize, error_reporter); + model, resolver, tensor_arena, kTensorArenaSize); interpreter = &static_interpreter; /* Allocate memory from the tensor_arena for the model's tensors. */ TfLiteStatus allocate_status = interpreter->AllocateTensors(); if (allocate_status != kTfLiteOk) { - TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed"); + MicroPrintf("AllocateTensors() failed"); return; } @@ -106,8 +97,7 @@ void loop(void) /* Run inference, and report any error */ TfLiteStatus invoke_status = interpreter->Invoke(); if (invoke_status != kTfLiteOk) { - TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed on x: %f\n", - static_cast < double > (x)); + MicroPrintf("Invoke failed on x: %f\n", static_cast < double > (x)); return; } @@ -119,7 +109,7 @@ void loop(void) /* Output the results. A custom HandleOutput function can be implemented * for each supported hardware target. */ - HandleOutput(error_reporter, x, y); + HandleOutput(x, y); /* Increment the inference_counter, and reset it if we have reached * the total number per cycle diff --git a/samples/modules/tflite-micro/hello_world/src/output_handler.cpp b/samples/modules/tflite-micro/hello_world/src/output_handler.cpp index c26f6a019fe..ef7e4f0d02e 100644 --- a/samples/modules/tflite-micro/hello_world/src/output_handler.cpp +++ b/samples/modules/tflite-micro/hello_world/src/output_handler.cpp @@ -16,11 +16,10 @@ #include "output_handler.hpp" -void HandleOutput(tflite::ErrorReporter *error_reporter, float x_value, - float y_value) +void HandleOutput(float x_value, float y_value) { /* Log the current X and Y values */ - TF_LITE_REPORT_ERROR(error_reporter, "x_value: %f, y_value: %f\n", - static_cast < double > (x_value), - static_cast < double > (y_value)); + MicroPrintf("x_value: %f, y_value: %f\n", + static_cast < double > (x_value), + static_cast < double > (y_value)); } diff --git a/samples/modules/tflite-micro/hello_world/src/output_handler.hpp b/samples/modules/tflite-micro/hello_world/src/output_handler.hpp index dbf51ebe8fb..0c16c3c18b1 100644 --- a/samples/modules/tflite-micro/hello_world/src/output_handler.hpp +++ b/samples/modules/tflite-micro/hello_world/src/output_handler.hpp @@ -18,10 +18,9 @@ #define TENSORFLOW_LITE_MICRO_EXAMPLES_HELLO_WORLD_OUTPUT_HANDLER_H_ #include -#include +#include /* Called by the main loop to produce some output based on the x and y values */ -void HandleOutput(tflite::ErrorReporter *error_reporter, float x_value, - float y_value); +void HandleOutput(float x_value, float y_value); #endif /* TENSORFLOW_LITE_MICRO_EXAMPLES_HELLO_WORLD_OUTPUT_HANDLER_H_ */ diff --git a/samples/modules/tflite-micro/magic_wand/prj.conf b/samples/modules/tflite-micro/magic_wand/prj.conf index 5801d104a49..ff2119e62b8 100644 --- a/samples/modules/tflite-micro/magic_wand/prj.conf +++ b/samples/modules/tflite-micro/magic_wand/prj.conf @@ -13,6 +13,7 @@ # limitations under the License. # ============================================================================== CONFIG_CPP=y +CONFIG_STD_CPP17=y CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y CONFIG_SENSOR=y CONFIG_NETWORKING=n diff --git a/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.cpp b/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.cpp index 894cba004ea..0491f7a7962 100644 --- a/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.cpp +++ b/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.cpp @@ -33,7 +33,7 @@ float bufz[BUFLEN] = { 0.0f }; bool initial = true; -TfLiteStatus SetupAccelerometer(tflite::ErrorReporter *error_reporter) +TfLiteStatus SetupAccelerometer() { if (!device_is_ready(sensor)) { printk("%s: device not ready.\n", sensor->name); @@ -41,18 +41,16 @@ TfLiteStatus SetupAccelerometer(tflite::ErrorReporter *error_reporter) } if (sensor == NULL) { - TF_LITE_REPORT_ERROR(error_reporter, - "Failed to get accelerometer, name: %s\n", - sensor->name); + MicroPrintf("Failed to get accelerometer, name: %s\n", + sensor->name); } else { - TF_LITE_REPORT_ERROR(error_reporter, "Got accelerometer, name: %s\n", - sensor->name); + MicroPrintf("Got accelerometer, name: %s\n", + sensor->name); } return kTfLiteOk; } -bool ReadAccelerometer(tflite::ErrorReporter *error_reporter, float *input, - int length) +bool ReadAccelerometer(float *input, int length) { int rc; struct sensor_value accel[3]; @@ -60,7 +58,7 @@ bool ReadAccelerometer(tflite::ErrorReporter *error_reporter, float *input, rc = sensor_sample_fetch(sensor); if (rc < 0) { - TF_LITE_REPORT_ERROR(error_reporter, "Fetch failed\n"); + MicroPrintf("Fetch failed\n"); return false; } /* Skip if there is no data */ @@ -72,7 +70,7 @@ bool ReadAccelerometer(tflite::ErrorReporter *error_reporter, float *input, for (int i = 0; i < samples_count; i++) { rc = sensor_channel_get(sensor, SENSOR_CHAN_ACCEL_XYZ, accel); if (rc < 0) { - TF_LITE_REPORT_ERROR(error_reporter, "ERROR: Update failed: %d\n", rc); + MicroPrintf("ERROR: Update failed: %d\n", rc); return false; } bufx[begin_index] = (float)sensor_value_to_double(&accel[0]); diff --git a/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.hpp b/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.hpp index c74382d3cb4..282126e2c1a 100644 --- a/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.hpp +++ b/samples/modules/tflite-micro/magic_wand/src/accelerometer_handler.hpp @@ -20,11 +20,10 @@ #define kChannelNumber 3 #include -#include +#include extern int begin_index; -extern TfLiteStatus SetupAccelerometer(tflite::ErrorReporter *error_reporter); -extern bool ReadAccelerometer(tflite::ErrorReporter *error_reporter, - float *input, int length); +extern TfLiteStatus SetupAccelerometer(); +extern bool ReadAccelerometer(float *input, int length); #endif /* TENSORFLOW_LITE_MICRO_EXAMPLES_MAGIC_WAND_ACCELEROMETER_HANDLER_H_ */ diff --git a/samples/modules/tflite-micro/magic_wand/src/main_functions.cpp b/samples/modules/tflite-micro/magic_wand/src/main_functions.cpp index 6c8f9e23400..69186d95997 100644 --- a/samples/modules/tflite-micro/magic_wand/src/main_functions.cpp +++ b/samples/modules/tflite-micro/magic_wand/src/main_functions.cpp @@ -21,14 +21,13 @@ #include "gesture_predictor.hpp" #include "magic_wand_model_data.hpp" #include "output_handler.hpp" -#include +#include #include #include #include /* Globals, used for compatibility with Arduino-style sketches. */ namespace { - tflite::ErrorReporter *error_reporter = nullptr; const tflite::Model *model = nullptr; tflite::MicroInterpreter *interpreter = nullptr; TfLiteTensor *model_input = nullptr; @@ -45,22 +44,14 @@ namespace { /* The name of this function is important for Arduino compatibility. */ void setup(void) { - /* Set up logging. Google style is to avoid globals or statics because of - * lifetime uncertainty, but since this has a trivial destructor it's okay. - */ - static tflite::MicroErrorReporter micro_error_reporter; /* NOLINT */ - - error_reporter = µ_error_reporter; - /* Map the model into a usable data structure. This doesn't involve any * copying or parsing, it's a very lightweight operation. */ model = tflite::GetModel(g_magic_wand_model_data); if (model->version() != TFLITE_SCHEMA_VERSION) { - TF_LITE_REPORT_ERROR(error_reporter, - "Model provided is schema version %d not equal " - "to supported version %d.", - model->version(), TFLITE_SCHEMA_VERSION); + MicroPrintf("Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); return; } @@ -79,7 +70,7 @@ void setup(void) /* Build an interpreter to run the model with. */ static tflite::MicroInterpreter static_interpreter( - model, micro_op_resolver, tensor_arena, kTensorArenaSize, error_reporter); + model, micro_op_resolver, tensor_arena, kTensorArenaSize); interpreter = &static_interpreter; /* Allocate memory from the tensor_arena for the model's tensors. */ @@ -91,16 +82,15 @@ void setup(void) (model_input->dims->data[1] != 128) || (model_input->dims->data[2] != kChannelNumber) || (model_input->type != kTfLiteFloat32)) { - TF_LITE_REPORT_ERROR(error_reporter, - "Bad input tensor parameters in model"); + MicroPrintf("Bad input tensor parameters in model"); return; } input_length = model_input->bytes / sizeof(float); - TfLiteStatus setup_status = SetupAccelerometer(error_reporter); + TfLiteStatus setup_status = SetupAccelerometer(); if (setup_status != kTfLiteOk) { - TF_LITE_REPORT_ERROR(error_reporter, "Set up failed\n"); + MicroPrintf("Set up failed\n"); } } @@ -108,7 +98,7 @@ void loop(void) { /* Attempt to read new data from the accelerometer. */ bool got_data = - ReadAccelerometer(error_reporter, model_input->data.f, input_length); + ReadAccelerometer(model_input->data.f, input_length); /* If there was no new data, wait until next time. */ if (!got_data) { @@ -118,13 +108,12 @@ void loop(void) /* Run inference, and report any error */ TfLiteStatus invoke_status = interpreter->Invoke(); if (invoke_status != kTfLiteOk) { - TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed on index: %d\n", - begin_index); + MicroPrintf("Invoke failed on index: %d\n", begin_index); return; } /* Analyze the results to obtain a prediction */ int gesture_index = PredictGesture(interpreter->output(0)->data.f); /* Produce an output */ - HandleOutput(error_reporter, gesture_index); + HandleOutput(gesture_index); } diff --git a/samples/modules/tflite-micro/magic_wand/src/output_handler.cpp b/samples/modules/tflite-micro/magic_wand/src/output_handler.cpp index d00aeaf46c8..373131d632e 100644 --- a/samples/modules/tflite-micro/magic_wand/src/output_handler.cpp +++ b/samples/modules/tflite-micro/magic_wand/src/output_handler.cpp @@ -16,24 +16,21 @@ #include "output_handler.hpp" -void HandleOutput(tflite::ErrorReporter *error_reporter, int kind) +void HandleOutput(int kind) { /* light (red: wing, blue: ring, green: slope) */ if (kind == 0) { - TF_LITE_REPORT_ERROR( - error_reporter, + MicroPrintf( "WING:\n\r* * *\n\r * * * " "*\n\r * * * *\n\r * * * *\n\r * * " "* *\n\r * *\n\r"); } else if (kind == 1) { - TF_LITE_REPORT_ERROR( - error_reporter, + MicroPrintf( "RING:\n\r *\n\r * *\n\r * *\n\r " " * *\n\r * *\n\r * *\n\r " " *\n\r"); } else if (kind == 2) { - TF_LITE_REPORT_ERROR( - error_reporter, + MicroPrintf( "SLOPE:\n\r *\n\r *\n\r *\n\r *\n\r " "*\n\r *\n\r *\n\r * * * * * * * *\n\r"); } diff --git a/samples/modules/tflite-micro/magic_wand/src/output_handler.hpp b/samples/modules/tflite-micro/magic_wand/src/output_handler.hpp index c5f1aebb046..ae041ae72c0 100644 --- a/samples/modules/tflite-micro/magic_wand/src/output_handler.hpp +++ b/samples/modules/tflite-micro/magic_wand/src/output_handler.hpp @@ -18,8 +18,8 @@ #define TENSORFLOW_LITE_MICRO_EXAMPLES_MAGIC_WAND_OUTPUT_HANDLER_H_ #include -#include +#include -void HandleOutput(tflite::ErrorReporter *error_reporter, int kind); +void HandleOutput(int kind); #endif /* TENSORFLOW_LITE_MICRO_EXAMPLES_MAGIC_WAND_OUTPUT_HANDLER_H_ */ diff --git a/samples/modules/tflite-micro/tflm_ethosu/prj.conf b/samples/modules/tflite-micro/tflm_ethosu/prj.conf index 37107d7a78c..e4d4947b298 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/prj.conf +++ b/samples/modules/tflite-micro/tflm_ethosu/prj.conf @@ -1,6 +1,7 @@ #application default configuration # include TFLM based on CMSIS NN optimization and ETHOSU acceleration CONFIG_CPP=y +CONFIG_STD_CPP17=y CONFIG_TENSORFLOW_LITE_MICRO=y CONFIG_ARM_ETHOS_U=y CONFIG_HEAP_MEM_POOL_SIZE=16384 diff --git a/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp b/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp index 25adcec70c6..5807588302e 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp +++ b/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp @@ -6,9 +6,9 @@ #include "inference_process.hpp" -#include +#include #include -#include +#include #include #include #include @@ -118,11 +118,10 @@ bool InferenceProcess::runJob(InferenceJob &job) } /* Create the TFL micro interpreter */ - tflite::AllOpsResolver resolver; - tflite::MicroErrorReporter errorReporter; + tflite::MicroMutableOpResolver <1> resolver; + resolver.AddEthosU(); - tflite::MicroInterpreter interpreter(model, resolver, tensorArena, tensorArenaSize, - &errorReporter); + tflite::MicroInterpreter interpreter(model, resolver, tensorArena, tensorArenaSize); /* Allocate tensors */ TfLiteStatus allocate_status = interpreter.AllocateTensors(); From 9bcd8e9b3e9d37824868ac0bee0f878201932197 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 5 May 2023 15:16:40 +0000 Subject: [PATCH 0937/4498] drivers: mipi_dsi: dsi_mcux: limit DSI TX to max payload size Limit DSI data TX to the max payload size possible with this peripheral, rather than relying on display drivers to respect this limitation. Signed-off-by: Daniel DeGrasse --- drivers/mipi_dsi/dsi_mcux.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/mipi_dsi/dsi_mcux.c b/drivers/mipi_dsi/dsi_mcux.c index f0eceb4697e..0093a2467a0 100644 --- a/drivers/mipi_dsi/dsi_mcux.c +++ b/drivers/mipi_dsi/dsi_mcux.c @@ -39,6 +39,9 @@ LOG_MODULE_REGISTER(dsi_mcux, CONFIG_MIPI_DSI_LOG_LEVEL); #define DSI_DPHY_PLL_CO_MIN 0 #define DSI_DPHY_PLL_CO_MAX 3 +/* MAX DSI TX payload */ +#define DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U) + struct display_mcux_mipi_dsi_config { MIPI_DSI_Type base; dsi_dpi_config_t dpi_config; @@ -251,6 +254,14 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, dsi_xfer.dscCmd = msg->cmd; dsi_xfer.flags = kDSI_TransferUseHighSpeed; dsi_xfer.txDataType = kDSI_TxDataDcsLongWr; + /* + * Cap transfer size. Note that we subtract six bytes here, + * one for the DSC command and one to insure that + * transfers are still aligned on a pixel boundary + * (two or three byte pixel sizes are supported). + */ + dsi_xfer.txDataSize = MIN(dsi_xfer.txDataSize, + (DSI_TX_MAX_PAYLOAD_BYTE - 6)); break; case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: dsi_xfer.txDataType = kDSI_TxDataGenShortWrNoParam; @@ -285,11 +296,11 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, if (msg->rx_len != 0) { /* Return rx_len on a read */ - return msg->rx_len; + return dsi_xfer.rxDataSize; } /* Return tx_len on a write */ - return msg->tx_len; + return dsi_xfer.txDataSize; } From 8d2f4633f2f1333dc305a290434033b8c2c23476 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 5 Apr 2023 17:09:10 +0000 Subject: [PATCH 0938/4498] drivers: dma: introduce SMARTDMA dma driver Introduce SMARTDMA dma driver. The SMARTDMA is a peripheral present on some NXP SOCs, which implements a programmable DMA engine. The DMA engine does not use channels, but rather provides a series of API functions implemented by the firmware provided with MCUX SDK. These API functions can be selected by the dma_config slot parameter. A custom API is also provided to allow the user to install an alternate firmware into the SMARTDMA. Signed-off-by: Daniel DeGrasse --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 3 + drivers/dma/Kconfig.mcux_smartdma | 9 + drivers/dma/dma_mcux_smartdma.c | 252 ++++++++++++++++++ dts/bindings/dma/nxp,smartdma.yaml | 28 ++ .../zephyr/drivers/dma/dma_mcux_smartdma.h | 53 ++++ 6 files changed, 346 insertions(+) create mode 100644 drivers/dma/Kconfig.mcux_smartdma create mode 100644 drivers/dma/dma_mcux_smartdma.c create mode 100644 dts/bindings/dma/nxp,smartdma.yaml create mode 100644 include/zephyr/drivers/dma/dma_mcux_smartdma.h diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 3cb622ae9e8..bd96efbf0a5 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -32,3 +32,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCHP_XEC dma_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_DMA_XMC4XXX dma_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) +zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 5023d9af9dd..37cd83383d8 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -61,4 +61,7 @@ source "drivers/dma/Kconfig.rpi_pico" source "drivers/dma/Kconfig.intel_lpss" source "drivers/dma/Kconfig.mcux_pxp" + +source "drivers/dma/Kconfig.mcux_smartdma" + endif # DMA diff --git a/drivers/dma/Kconfig.mcux_smartdma b/drivers/dma/Kconfig.mcux_smartdma new file mode 100644 index 00000000000..e4258038ee5 --- /dev/null +++ b/drivers/dma/Kconfig.mcux_smartdma @@ -0,0 +1,9 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config DMA_MCUX_SMARTDMA + bool "MCUX SmartDMA Driver" + default y + depends on DT_HAS_NXP_SMARTDMA_ENABLED + help + MCUX SmartDMA driver. diff --git a/drivers/dma/dma_mcux_smartdma.c b/drivers/dma/dma_mcux_smartdma.c new file mode 100644 index 00000000000..b1870b3959c --- /dev/null +++ b/drivers/dma/dma_mcux_smartdma.c @@ -0,0 +1,252 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DT_DRV_COMPAT nxp_smartdma + +LOG_MODULE_REGISTER(dma_mcux_smartdma, CONFIG_DMA_LOG_LEVEL); + +/* SMARTDMA peripheral registers, taken from MCUX driver implementation*/ +struct smartdma_periph { + volatile uint32_t BOOT; + volatile uint32_t CTRL; + volatile uint32_t PC; + volatile uint32_t SP; + volatile uint32_t BREAK_ADDR; + volatile uint32_t BREAK_VECT; + volatile uint32_t EMER_VECT; + volatile uint32_t EMER_SEL; + volatile uint32_t ARM2SMARTDMA; + volatile uint32_t SMARTDMA2ARM; + volatile uint32_t PENDTRAP; +}; + +struct dma_mcux_smartdma_config { + struct smartdma_periph *base; + void (*irq_config_func)(const struct device *dev); + + void (**smartdma_progs)(void); +}; + +struct dma_mcux_smartdma_data { + uint32_t smartdma_stack[32]; /* Stack for SMARTDMA */ + /* Installed DMA callback and user data */ + dma_callback_t callback; + void *user_data; +}; + +/* Seems to be written to smartDMA control register when it is configured */ +#define SMARTDMA_MAGIC 0xC0DE0000U +/* These bits are set when the SMARTDMA boots, cleared to reset it */ +#define SMARTDMA_BOOT 0x11 + +static inline bool dma_mcux_smartdma_prog_is_mipi(uint32_t prog) +{ + return ((prog == kSMARTDMA_MIPI_RGB565_DMA) || + (prog == kSMARTDMA_MIPI_RGB888_DMA) || + (prog == kSMARTDMA_MIPI_RGB565_R180_DMA) || + (prog == kSMARTDMA_MIPI_RGB888_R180_DMA)); +} + +/* Configure a channel */ +static int dma_mcux_smartdma_configure(const struct device *dev, + uint32_t channel, struct dma_config *config) +{ + const struct dma_mcux_smartdma_config *dev_config = dev->config; + struct dma_mcux_smartdma_data *data = dev->data; + uint32_t prog_idx; + bool swap_pixels = false; + + /* SMARTDMA does not have channels */ + ARG_UNUSED(channel); + + data->callback = config->dma_callback; + data->user_data = config->user_data; + + /* Reset smartDMA */ + SMARTDMA_Reset(); + + /* + * The dma_slot parameter is used to determine which SMARTDMA program + * to run. First, convert the Zephyr define to a HAL enum. + */ + switch (config->dma_slot) { + case DMA_SMARTDMA_MIPI_RGB565_DMA: + prog_idx = kSMARTDMA_MIPI_RGB565_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB888_DMA: + prog_idx = kSMARTDMA_MIPI_RGB888_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB565_180: + prog_idx = kSMARTDMA_MIPI_RGB565_R180_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB888_180: + prog_idx = kSMARTDMA_MIPI_RGB888_R180_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP: + swap_pixels = true; + prog_idx = kSMARTDMA_MIPI_RGB565_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB888_DMA_SWAP: + swap_pixels = true; + prog_idx = kSMARTDMA_MIPI_RGB888_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB565_180_SWAP: + swap_pixels = true; + prog_idx = kSMARTDMA_MIPI_RGB565_R180_DMA; + break; + case DMA_SMARTDMA_MIPI_RGB888_180_SWAP: + swap_pixels = true; + prog_idx = kSMARTDMA_MIPI_RGB888_R180_DMA; + break; + default: + prog_idx = config->dma_slot; + break; + } + + if (dma_mcux_smartdma_prog_is_mipi(prog_idx)) { + smartdma_dsi_param_t param = {.disablePixelByteSwap = (swap_pixels == false)}; + + if (config->block_count != 1) { + return -ENOTSUP; + } + /* Setup SMARTDMA */ + param.p_buffer = (uint8_t *)config->head_block->source_address; + param.buffersize = config->head_block->block_size; + param.smartdma_stack = data->smartdma_stack; + /* Save configuration to SMARTDMA */ + dev_config->base->ARM2SMARTDMA = (uint32_t)(¶m); + } else { + /* For other cases, we simply pass the entire DMA config + * struct to the SMARTDMA. The user's application could either + * populate this structure with data, or choose to write + * different configuration data to the SMARTDMA in their + * application + */ + dev_config->base->ARM2SMARTDMA = ((uint32_t)config); + } + /* Save program */ + dev_config->base->BOOT = (uint32_t)dev_config->smartdma_progs[prog_idx]; + LOG_DBG("Boot address set to 0x%X", dev_config->base->BOOT); + return 0; +} + +static int dma_mcux_smartdma_start(const struct device *dev, uint32_t channel) +{ + const struct dma_mcux_smartdma_config *config = dev->config; + +#ifdef CONFIG_PM + /* Block PM transition until DMA completes */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif + /* Kick off SMARTDMA */ + config->base->CTRL = SMARTDMA_MAGIC | SMARTDMA_BOOT; + return 0; +} + + +static int dma_mcux_smartdma_stop(const struct device *dev, uint32_t channel) +{ + ARG_UNUSED(dev); + ARG_UNUSED(channel); + /* Stop DMA */ + SMARTDMA_Reset(); +#ifdef CONFIG_PM + /* Release PM lock */ + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif + return 0; +} + +static int dma_mcux_smartdma_init(const struct device *dev) +{ + const struct dma_mcux_smartdma_config *config = dev->config; + /* + * Initialize the SMARTDMA with firmware. The default firmware + * from MCUX SDK is a display firmware, which has functions + * implemented above in the dma configuration function. The + * user can install another firmware using `dma_smartdma_install_fw` + */ + SMARTDMA_Init((uint32_t)config->smartdma_progs, + s_smartdmaDisplayFirmware, + SMARTDMA_DISPLAY_FIRMWARE_SIZE); + config->irq_config_func(dev); + + return 0; +} + +static void dma_mcux_smartdma_irq(const struct device *dev) +{ + const struct dma_mcux_smartdma_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->user_data, 0, 0); + } +#ifdef CONFIG_PM + /* Release PM lock */ + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif +} + +/** + * @brief install SMARTDMA firmware + * + * Install a custom firmware for the smartDMA. This function allows the user + * to install a custom firmware into the smartDMA, which implements + * different API functions than the standard MCUX SDK firmware. + * @param dev: smartDMA device + * @param firmware: address of buffer containing smartDMA firmware + * @param len: length of firmware buffer + */ +void dma_smartdma_install_fw(const struct device *dev, uint8_t *firmware, + uint32_t len) +{ + const struct dma_mcux_smartdma_config *config = dev->config; + + SMARTDMA_InstallFirmware((uint32_t)config->smartdma_progs, firmware, len); +} + +static const struct dma_driver_api dma_mcux_smartdma_api = { + .config = dma_mcux_smartdma_configure, + .start = dma_mcux_smartdma_start, + .stop = dma_mcux_smartdma_stop, +}; + + +#define SMARTDMA_INIT(n) \ + static void dma_mcux_smartdma_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + dma_mcux_smartdma_irq, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + static const struct dma_mcux_smartdma_config smartdma_##n##_config = { \ + .base = (struct smartdma_periph *)DT_INST_REG_ADDR(n), \ + .smartdma_progs = (void (**)(void))DT_INST_PROP(n, program_mem),\ + .irq_config_func = dma_mcux_smartdma_config_func_##n, \ + }; \ + static struct dma_mcux_smartdma_data smartdma_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &dma_mcux_smartdma_init, \ + NULL, \ + &smartdma_##n##_data, &smartdma_##n##_config, \ + POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \ + &dma_mcux_smartdma_api); + +DT_INST_FOREACH_STATUS_OKAY(SMARTDMA_INIT) diff --git a/dts/bindings/dma/nxp,smartdma.yaml b/dts/bindings/dma/nxp,smartdma.yaml new file mode 100644 index 00000000000..0724616b5c1 --- /dev/null +++ b/dts/bindings/dma/nxp,smartdma.yaml @@ -0,0 +1,28 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP SmartDMA controller + +compatible: "nxp,smartdma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + program-mem: + type: int + required: true + description: | + Program memory to load SMARTDMA routines into. Must be set to a RAM + region that the SMARTDMA can access on the chip. + + # SmartDMA does not support channels, so no DMA cells should be provided. + # the driver or application using SMARTDMA can set the DMA program to run + # using the `dma_slot` parameter. + "#dma-cells": + const: 0 diff --git a/include/zephyr/drivers/dma/dma_mcux_smartdma.h b/include/zephyr/drivers/dma/dma_mcux_smartdma.h new file mode 100644 index 00000000000..0e09d348d8f --- /dev/null +++ b/include/zephyr/drivers/dma/dma_mcux_smartdma.h @@ -0,0 +1,53 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_MCUX_SMARTDMA_H_ +#define ZEPHYR_INCLUDE_DRIVERS_DMA_MCUX_SMARTDMA_H_ + +/* Write RGB565 data to MIPI DSI via DMA. */ +#define DMA_SMARTDMA_MIPI_RGB565_DMA 0 +/* Write RGB888 data to MIPI DSI via DMA */ +#define DMA_SMARTDMA_MIPI_RGB888_DMA 1 +/* Write RGB565 data to MIPI DSI via DMA. Rotate output data by 180 degrees */ +#define DMA_SMARTDMA_MIPI_RGB565_180 2 +/* Write RGB888 data to MIPI DSI via DMA. Rotate output data by 180 degrees */ +#define DMA_SMARTDMA_MIPI_RGB888_180 3 + +/* Write RGB565 data to MIPI DSI via DMA. Swap data endianness, so that + * little endian RGB565 data will be written big endian style. + */ +#define DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP 4 +/* Write RGB888 data to MIPI DSI via DMA. Swap data endianness, so that + * little endian RGB888 data will be written big endian style. + */ +#define DMA_SMARTDMA_MIPI_RGB888_DMA_SWAP 5 +/* Write RGB565 data to MIPI DSI via DMA. Rotate output data by 180 degrees, + * and swap data endianness + */ +#define DMA_SMARTDMA_MIPI_RGB565_180_SWAP 6 +/* Write RGB888 data to MIPI DSI via DMA. Rotate output data by 180 degrees, + * and swap data endianness + */ +#define DMA_SMARTDMA_MIPI_RGB888_180_SWAP 7 + + + +/** + * @brief install SMARTDMA firmware + * + * Install a custom firmware for the smartDMA. This function allows the user + * to install a custom firmware into the smartDMA, which implements + * different API functions than the standard MCUX SDK firmware. + * @param dev: smartDMA device + * @param firmware: address of buffer containing smartDMA firmware + * @param len: length of firmware buffer + */ +void dma_smartdma_install_fw(const struct device *dev, uint8_t *firmware, + uint32_t len); + +#define GD32_DMA_FEATURES_FIFO_THRESHOLD(threshold) (threshold & 0x3) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_MCUX_SMARTDMA_H_ */ From 9e5188353e4729c3a978292b4f3d0f58d142b61f Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 5 Apr 2023 17:11:44 +0000 Subject: [PATCH 0939/4498] soc: arm: nxp_imx: add support for SMARTDMA for RT5xx Add support for SMARTDMA to RT5xx SOCs. SMARTDMA ram banks will be powered up, so code can be programmed into this region for the SMARTDMA engine. Signed-off-by: Daniel DeGrasse --- dts/arm/nxp/nxp_rt5xx_common.dtsi | 9 +++++++++ soc/arm/nxp_imx/rt5xx/soc.c | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 54469d3a56f..9165b26441e 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -476,6 +476,15 @@ #io-channel-cells = <1>; }; + smartdma: dma@27020 { + compatible = "nxp,smartdma"; + reg = <0x27020 0x1000>; + program-mem = <0x24100000>; + interrupts = <73 0>; + status = "disabled"; + #dma-cells = <0>; + }; + ctimer0: ctimer@28000 { compatible = "nxp,lpc-ctimer"; reg = <0x28000 0x1000>; diff --git a/soc/arm/nxp_imx/rt5xx/soc.c b/soc/arm/nxp_imx/rt5xx/soc.c index 2fbb7d609b3..c216f63890d 100644 --- a/soc/arm/nxp_imx/rt5xx/soc.c +++ b/soc/arm/nxp_imx/rt5xx/soc.c @@ -364,6 +364,16 @@ static void clock_init(void) RESET_PeripheralReset(kSDIO0_RST_SHIFT_RSTn); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(smartdma), okay) && CONFIG_DMA_MCUX_SMARTDMA + /* Power up SMARTDMA ram */ + POWER_DisablePD(kPDRUNCFG_APD_SMARTDMA_SRAM); + POWER_DisablePD(kPDRUNCFG_PPD_SMARTDMA_SRAM); + POWER_ApplyPD(); + + RESET_ClearPeripheralReset(kSMART_DMA_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_Smartdma); +#endif + DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) /* Set up dividers. */ From 61515cf31fb344e5a11210dee485c571361523b2 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 5 Apr 2023 17:12:47 +0000 Subject: [PATCH 0940/4498] drivers: mipi_dsi: dsi_mcux_2l add support for SMARTDMA, and byte swapping Add support for SMARTDMA transfers, and byte swapping of RGB565 data. Additionally, the limits on TX data size have been impelemented in the MIPI DSI driver, as opposed to the RM67162 display where they were previously added. Signed-off-by: Daniel DeGrasse --- drivers/mipi_dsi/Kconfig.mcux | 21 ++ drivers/mipi_dsi/dsi_mcux_2l.c | 238 +++++++++++++++--- .../drivers/mipi_dsi/mipi_dsi_mcux_2l.h | 16 ++ 3 files changed, 244 insertions(+), 31 deletions(-) create mode 100644 include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h diff --git a/drivers/mipi_dsi/Kconfig.mcux b/drivers/mipi_dsi/Kconfig.mcux index 7e9c15f2d40..17d8d437dfe 100644 --- a/drivers/mipi_dsi/Kconfig.mcux +++ b/drivers/mipi_dsi/Kconfig.mcux @@ -14,3 +14,24 @@ config MIPI_DSI_MCUX_2L depends on DT_HAS_NXP_MIPI_DSI_2L_ENABLED help NXP MIPI DSI 2L controller driver + +if MIPI_DSI_MCUX_2L + +config MIPI_DSI_MCUX_2L_SMARTDMA + bool "Use smartDMA controller with MIPI DSI" + default y + depends on DMA_MCUX_SMARTDMA + help + Use SMARTDMA. This accelerator will automatically + convert RGB565 input data to BGR565 (little endian to big endian), + and write it to the MIPI DSI. + +config MIPI_DSI_MCUX_2L_SWAP16 + bool "Swap 16 byte color" + help + Swap 16 byte color data from little to big endian format. When + this Kconfig is enabled, the DSI expects RGB565 data in little endian + format, which will then be byte swapped. + + +endif # MIPI_DSI_MCUX_2L diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 9f4dcdf0957..05d56f9b6a1 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -11,9 +11,14 @@ #include #include #include +#include +#include +#include +#include + +#include #include #include -#include #include @@ -30,7 +35,11 @@ struct mcux_mipi_dsi_config { const struct device *pixel_clk_dev; clock_control_subsys_t pixel_clk_subsys; uint32_t dphy_ref_freq; +#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA + const struct device *smart_dma; +#else void (*irq_config_func)(const struct device *dev); +#endif }; struct mcux_mipi_dsi_data { @@ -38,6 +47,97 @@ struct mcux_mipi_dsi_data { struct k_sem transfer_sem; }; + +/* MAX DSI TX payload */ +#define DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U) + + +#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA + +/* Callback for DSI DMA transfer completion, called in ISR context */ +static void dsi_mcux_dma_cb(const struct device *dma_dev, + void *user_data, uint32_t channel, int status) +{ + const struct device *dev = user_data; + const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; + uint32_t int_flags1, int_flags2; + + if (status != 0) { + LOG_ERR("SMARTDMA transfer failed"); + } else { + /* Disable DSI interrupts at transfer completion */ + DSI_DisableInterrupts(config->base, kDSI_InterruptGroup1ApbTxDone | + kDSI_InterruptGroup1HtxTo, 0U); + DSI_GetAndClearInterruptStatus(config->base, &int_flags1, &int_flags2); + k_sem_give(&data->transfer_sem); + } +} + +/* Helper function to transfer DSI color (DMA based implementation) */ +static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + /* + * Color streams are a special case for this DSI peripheral, because + * the SMARTDMA peripheral (if enabled) can be used to accelerate + * the transfer of data to the DSI. The SMARTDMA has the additional + * advantage over traditional DMA of being able to to automatically + * byte swap color data. This is advantageous, as most graphical + * frameworks store RGB data in little endian format, but many + * MIPI displays expect color data in big endian format. + */ + const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; + struct dma_config dma_cfg = {0}; + struct dma_block_config block = {0}; + int ret; + + if (channel != 0) { + return -ENOTSUP; /* DMA can only transfer on virtual channel 0 */ + } + + /* Configure smartDMA device, and run transfer */ + block.source_address = (uint32_t)msg->tx_buf; + block.block_size = msg->tx_len; + + dma_cfg.dma_callback = dsi_mcux_dma_cb; + dma_cfg.user_data = (struct device *)dev; + dma_cfg.head_block = █ + dma_cfg.block_count = 1; + if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) { + dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP; + } else { + dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA; + } + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + ret = dma_config(config->smart_dma, 0, &dma_cfg); + if (ret < 0) { + LOG_ERR("Could not configure SMARTDMA"); + return ret; + } + /* + * SMARTDMA uses DSI interrupt line as input for the DMA + * transfer trigger. Therefore, we need to enable DSI TX + * interrupts in order to trigger the DMA engine. + * Note that if the MIPI IRQ is enabled in + * the NVIC, it will fire on every SMARTDMA transfer + */ + DSI_EnableInterrupts(config->base, kDSI_InterruptGroup1ApbTxDone | + kDSI_InterruptGroup1HtxTo, 0U); + /* Trigger DMA engine */ + ret = dma_start(config->smart_dma, 0); + if (ret < 0) { + LOG_ERR("Could not start SMARTDMA"); + return ret; + } + /* Wait for TX completion */ + k_sem_take(&data->transfer_sem, K_FOREVER); + return msg->tx_len; +} + +#else /* CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA is not set */ + /* Callback for DSI transfer completion, called in ISR context */ static void dsi_transfer_complete(MIPI_DSI_HOST_Type *base, dsi_handle_t *handle, status_t status, void *userData) @@ -47,14 +147,74 @@ static void dsi_transfer_complete(MIPI_DSI_HOST_Type *base, k_sem_give(&data->transfer_sem); } + +/* Helper function to transfer DSI color (Interrupt based implementation) */ +static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; + status_t status; + dsi_transfer_t xfer = { + .virtualChannel = channel, + .txData = msg->tx_buf, + .rxDataSize = (uint16_t)msg->rx_len, + .rxData = msg->rx_buf, + .sendDscCmd = true, + .dscCmd = msg->cmd, + .txDataType = kDSI_TxDataDcsLongWr, + .flags = kDSI_TransferUseHighSpeed, + }; + + /* + * Cap transfer size. Note that we subtract six bytes here, + * one for the DSC command and five to insure that + * transfers are still aligned on a pixel boundary + * (two or three byte pixel sizes are supported). + */ + xfer.txDataSize = MIN(msg->tx_len, (DSI_TX_MAX_PAYLOAD_BYTE - 6)); + + if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) { + /* Manually swap the 16 byte color data in software */ + uint8_t *src = (uint8_t *)xfer.txData; + uint8_t tmp; + + for (uint32_t i = 0; i < xfer.txDataSize; i += 2) { + tmp = src[i]; + src[i] = src[i + 1]; + src[i + 1] = tmp; + } + } + /* Send TX data using non-blocking DSI API */ + status = DSI_TransferNonBlocking(config->base, + &data->mipi_handle, &xfer); + /* Wait for transfer completion */ + k_sem_take(&data->transfer_sem, K_FOREVER); + if (status != kStatus_Success) { + LOG_ERR("Transmission failed"); + return -EIO; + } + return xfer.txDataSize; +} + +/* ISR is used for DSI interrupt based implementation, unnecessary if DMA is used */ +static int mipi_dsi_isr(const struct device *dev) +{ + const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; + + DSI_TransferHandleIRQ(config->base, &data->mipi_handle); + return 0; +} + +#endif + static int dsi_mcux_attach(const struct device *dev, uint8_t channel, const struct mipi_dsi_device *mdev) { const struct mcux_mipi_dsi_config *config = dev->config; - struct mcux_mipi_dsi_data *data = dev->data; dsi_dphy_config_t dphy_config; - status_t status; dsi_config_t dsi_config; uint32_t dphy_bit_clk_freq; uint32_t dphy_esc_clk_freq; @@ -68,13 +228,28 @@ static int dsi_mcux_attach(const struct device *dev, /* Init the DSI module. */ DSI_Init(config->base, &dsi_config); - /* Create transfer handle */ - status = DSI_TransferCreateHandle(config->base, &data->mipi_handle, - dsi_transfer_complete, data); +#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA + /* Connect DSI IRQ line to SMARTDMA trigger via + * INPUTMUX. + */ + /* Attach INPUTMUX from MIPI to SMARTDMA */ + INPUTMUX_Init(INPUTMUX); + INPUTMUX_AttachSignal(INPUTMUX, 0, kINPUTMUX_MipiIrqToSmartDmaInput); + /* Gate inputmux clock to save power */ + INPUTMUX_Deinit(INPUTMUX); - if (status != kStatus_Success) { + if (!device_is_ready(config->smart_dma)) { return -ENODEV; } +#else + struct mcux_mipi_dsi_data *data = dev->data; + + /* Create transfer handle */ + if (DSI_TransferCreateHandle(config->base, &data->mipi_handle, + dsi_transfer_complete, data) != kStatus_Success) { + return -ENODEV; + } +#endif /* Get the DPHY bit clock frequency */ if (clock_control_get_rate(config->bit_clk_dev, @@ -152,9 +327,9 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, struct mipi_dsi_msg *msg) { const struct mcux_mipi_dsi_config *config = dev->config; - struct mcux_mipi_dsi_data *data = dev->data; dsi_transfer_t dsi_xfer = {0}; status_t status; + int ret; dsi_xfer.virtualChannel = channel; dsi_xfer.txDataSize = msg->tx_len; @@ -179,8 +354,21 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, case MIPI_DSI_DCS_LONG_WRITE: dsi_xfer.sendDscCmd = true; dsi_xfer.dscCmd = msg->cmd; - dsi_xfer.flags = kDSI_TransferUseHighSpeed; dsi_xfer.txDataType = kDSI_TxDataDcsLongWr; + dsi_xfer.flags = kDSI_TransferUseHighSpeed; + if (msg->flags & MCUX_DSI_2L_FB_DATA) { + /* + * Special case- transfer framebuffer data using + * SMARTDMA or non blocking DSI API. The framebuffer + * will also be color swapped, if enabled. + */ + ret = dsi_mcux_tx_color(dev, channel, msg); + if (ret < 0) { + LOG_ERR("Transmission failed"); + return -EIO; + } + return ret; + } break; case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: dsi_xfer.txDataType = kDSI_TxDataGenShortWrNoParam; @@ -206,16 +394,7 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, return -ENOTSUP; } - if (msg->type == MIPI_DSI_DCS_LONG_WRITE) { - /* Use a non-blocking transfer */ - status = DSI_TransferNonBlocking(config->base, - &data->mipi_handle, &dsi_xfer); - /* Wait for transfer completion */ - k_sem_take(&data->transfer_sem, K_FOREVER); - } else { - status = DSI_TransferBlocking(config->base, &dsi_xfer); - } - + status = DSI_TransferBlocking(config->base, &dsi_xfer); if (status != kStatus_Success) { LOG_ERR("Transmission failed"); return -EIO; @@ -236,22 +415,15 @@ static struct mipi_dsi_driver_api dsi_mcux_api = { .transfer = dsi_mcux_transfer, }; -static int mipi_dsi_isr(const struct device *dev) -{ - const struct mcux_mipi_dsi_config *config = dev->config; - struct mcux_mipi_dsi_data *data = dev->data; - - DSI_TransferHandleIRQ(config->base, &data->mipi_handle); - return 0; -} - static int mcux_mipi_dsi_init(const struct device *dev) { const struct mcux_mipi_dsi_config *config = dev->config; struct mcux_mipi_dsi_data *data = dev->data; +#ifndef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA /* Enable IRQ */ config->irq_config_func(dev); +#endif k_sem_init(&data->transfer_sem, 0, 1); @@ -295,16 +467,20 @@ static int mcux_mipi_dsi_init(const struct device *dev) },)) #define MCUX_MIPI_DSI_DEVICE(id) \ - static void mipi_dsi_##n##_irq_config_func(const struct device *dev) \ + COND_CODE_1(CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA, \ + (), (static void mipi_dsi_##n##_irq_config_func(const struct device *dev) \ { \ IRQ_CONNECT(DT_INST_IRQN(id), DT_INST_IRQ(id, priority), \ mipi_dsi_isr, DEVICE_DT_INST_GET(id), 0); \ irq_enable(DT_INST_IRQN(id)); \ - } \ + })) \ + \ static const struct mcux_mipi_dsi_config mipi_dsi_config_##id = { \ MCUX_DSI_DPI_CONFIG(id) \ + COND_CODE_1(CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA, \ + (.smart_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(id, smartdma)),), \ + (.irq_config_func = mipi_dsi_##n##_irq_config_func,)) \ .base = (MIPI_DSI_HOST_Type *)DT_INST_REG_ADDR(id), \ - .irq_config_func = mipi_dsi_##n##_irq_config_func, \ .auto_insert_eotp = DT_INST_PROP(id, autoinsert_eotp), \ .dphy_ref_freq = DT_INST_PROP_OR(id, dphy_ref_frequency, 0), \ .bit_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, dphy)), \ diff --git a/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h b/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h new file mode 100644 index 00000000000..927fcba5e55 --- /dev/null +++ b/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h @@ -0,0 +1,16 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DRIVERS_MIPI_DSI_MCUX_2L_ +#define ZEPHYR_INCLUDE_DRIVERS_MIPI_DSI_MCUX_2L_ + +/* + * HW specific flag- indicates to the MIPI DSI 2L peripheral that the + * data being sent is framebuffer data, which the DSI peripheral may + * byte swap depending on KConfig settings + */ +#define MCUX_DSI_2L_FB_DATA BIT(0x1) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MIPI_DSI_MCUX_2L_ */ From 36ad0b10b36db29124309b20f348b2ae22bfc7f7 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 5 Apr 2023 17:14:06 +0000 Subject: [PATCH 0941/4498] drivers: display: rm67162: write full buffer to MIPI_DSI With update to handle DSI transfer length in MIPI_DSI driver, the logic can be removed from the RM67162 driver. The driver now will simply continue writing data until the full buffer is sent. Signed-off-by: Daniel DeGrasse --- drivers/display/display_rm67162.c | 45 ++++++++++++++----------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/display/display_rm67162.c b/drivers/display/display_rm67162.c index c23abef6dc0..edf9d6eb55d 100644 --- a/drivers/display/display_rm67162.c +++ b/drivers/display/display_rm67162.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -181,8 +182,6 @@ static const struct { {.cmd = 0x35, .param = 0x00}, }; -#define DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U) - struct rm67162_config { const struct device *mipi_dsi; uint8_t channel; @@ -345,42 +344,38 @@ static int rm67162_init(const struct device *dev) MIPI_DCS_SET_DISPLAY_ON, NULL, 0); } -/* Helper to write data to rm67162 via MIPI interface. */ -static int rm67162_write_buf(const struct device *dev, bool first_write, +/* Helper to write framebuffer data to rm67162 via MIPI interface. */ +static int rm67162_write_fb(const struct device *dev, bool first_write, const uint8_t *src, uint32_t len) { const struct rm67162_config *config = dev->config; - struct rm67162_data *data = dev->data; - int ret = 0; - uint32_t max_write, wlen; - uint8_t cmd; + uint32_t wlen = 0; + struct mipi_dsi_msg msg = {0}; - /* - * Max write len: one byte is reserved for DSC command, and - * pixels should not be split across transfers + /* Note- we need to set custom flags on the DCS message, + * so we bypass the mipi_dsi_dcs_write API */ - max_write = ((DSI_TX_MAX_PAYLOAD_BYTE - 1) / data->bytes_per_pixel) * - data->bytes_per_pixel; if (first_write) { - cmd = MIPI_DCS_WRITE_MEMORY_START; + msg.cmd = MIPI_DCS_WRITE_MEMORY_START; } else { - cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE; + msg.cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE; } + msg.type = MIPI_DSI_DCS_LONG_WRITE; + msg.flags = MCUX_DSI_2L_FB_DATA; while (len > 0) { - /* Cap each tx to max DSI APB transfer size */ - wlen = MIN(max_write, len); - ret = mipi_dsi_dcs_write(config->mipi_dsi, config->channel, - cmd, src, wlen); - if (ret < 0) { - return ret; + msg.tx_len = len; + msg.tx_buf = src; + wlen = mipi_dsi_transfer(config->mipi_dsi, config->channel, &msg); + if (wlen < 0) { + return wlen; } /* Advance source pointer and decrement remaining */ src += wlen; len -= wlen; /* All future commands should use WRITE_MEMORY_CONTINUE */ - cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE; + msg.cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE; } - return ret; + return wlen; } static int rm67162_write(const struct device *dev, const uint16_t x, @@ -456,12 +451,12 @@ static int rm67162_write(const struct device *dev, const uint16_t x, if (desc->pitch == desc->width) { /* Buffer is contiguous, we can perform entire transfer */ - rm67162_write_buf(dev, first_cmd, src, + rm67162_write_fb(dev, first_cmd, src, desc->height * desc->width * data->bytes_per_pixel); } else { /* Buffer is not contiguous, we must write each line separately */ for (h_idx = 0; h_idx < desc->height; h_idx++) { - rm67162_write_buf(dev, first_cmd, src, + rm67162_write_fb(dev, first_cmd, src, desc->width * data->bytes_per_pixel); first_cmd = false; /* The pitch is not equal to width, account for it here */ From 40a52eb4864372029389ac34e9b026e2baa5008a Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 5 Apr 2023 17:15:14 +0000 Subject: [PATCH 0942/4498] boards: add support for SMARTDMA when using RM67162 display shield Add support for using SMARTDMA when using RM67162 display shield with Zephyr, so that the DMA engine can be leveraged for improved performance when using the MIPI DSI in command mode. Signed-off-by: Daniel DeGrasse --- boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts | 11 +++++++++++ boards/shields/g1120b0mipi/Kconfig.defconfig | 10 +++++++++- .../g1120b0mipi/boards/mimxrt595_evk_cm33.conf | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.conf diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts index f919ba00ea0..49dd4f424be 100644 --- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts +++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts @@ -467,3 +467,14 @@ zephyr_udc0: &usbhs { &sram1 { status = "okay"; }; + +/* Enable smartDMA controller */ +&smartdma { + status = "okay"; +}; + +/* Add smartDMA to mipi DSI */ +&mipi_dsi { + dmas = <&smartdma>; + dma-names = "smartdma"; +}; diff --git a/boards/shields/g1120b0mipi/Kconfig.defconfig b/boards/shields/g1120b0mipi/Kconfig.defconfig index 807183c4742..64b784035e7 100644 --- a/boards/shields/g1120b0mipi/Kconfig.defconfig +++ b/boards/shields/g1120b0mipi/Kconfig.defconfig @@ -11,9 +11,17 @@ config INPUT config INPUT_FT5336_INTERRUPT default y +if MIPI_DSI_MCUX_2L +# Enable color swap in driver + +config MIPI_DSI_MCUX_2L_SWAP16 + default y + +endif # MIPI_DSI_MCUX_2L + # Swap 16 bit color setting for LVGL, to send high byte first config LV_COLOR_16_SWAP - default y + default y if !MIPI_DSI_MCUX_2L_SWAP16 config LV_Z_VDB_SIZE default 16 diff --git a/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.conf b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.conf new file mode 100644 index 00000000000..ffe50a964ed --- /dev/null +++ b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.conf @@ -0,0 +1,2 @@ +# Enable DMA, so that DSI MCUX will use SMARTDMA +CONFIG_DMA=y From 71db18809177809e8e385a178d122347bdd28e12 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 11 Jun 2023 19:23:44 +1000 Subject: [PATCH 0943/4498] drivers: sensor: voltage: add driver Add voltage sensor driver. Co-authored-by: Marco Argiolas Signed-off-by: Nick Ward --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/voltage_divider/CMakeLists.txt | 5 + drivers/sensor/voltage_divider/Kconfig | 13 ++ drivers/sensor/voltage_divider/voltage.c | 181 ++++++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 drivers/sensor/voltage_divider/CMakeLists.txt create mode 100644 drivers/sensor/voltage_divider/Kconfig create mode 100644 drivers/sensor/voltage_divider/voltage.c diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index e2d46e88fd6..7ec05baff81 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -145,6 +145,7 @@ add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040) add_subdirectory_ifdef(CONFIG_VEML7700 veml7700) add_subdirectory_ifdef(CONFIG_VL53L0X vl53l0x) add_subdirectory_ifdef(CONFIG_VL53L1X vl53l1x) +add_subdirectory_ifdef(CONFIG_VOLTAGE_DIVIDER voltage_divider) add_subdirectory_ifdef(CONFIG_WSEN_HIDS wsen_hids) add_subdirectory_ifdef(CONFIG_WSEN_PADS wsen_pads) add_subdirectory_ifdef(CONFIG_WSEN_PDUS wsen_pdus) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index cd4faef46e4..942b1bee1d0 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -200,6 +200,7 @@ source "drivers/sensor/vcnl4040/Kconfig" source "drivers/sensor/veml7700/Kconfig" source "drivers/sensor/vl53l0x/Kconfig" source "drivers/sensor/vl53l1x/Kconfig" +source "drivers/sensor/voltage_divider/Kconfig" source "drivers/sensor/wsen_hids/Kconfig" source "drivers/sensor/wsen_itds/Kconfig" source "drivers/sensor/wsen_pads/Kconfig" diff --git a/drivers/sensor/voltage_divider/CMakeLists.txt b/drivers/sensor/voltage_divider/CMakeLists.txt new file mode 100644 index 00000000000..ec2af44de5c --- /dev/null +++ b/drivers/sensor/voltage_divider/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(voltage.c) diff --git a/drivers/sensor/voltage_divider/Kconfig b/drivers/sensor/voltage_divider/Kconfig new file mode 100644 index 00000000000..19027aa9361 --- /dev/null +++ b/drivers/sensor/voltage_divider/Kconfig @@ -0,0 +1,13 @@ +# Voltage sensor driver +# +# Copyright (c) 2023 FTP Technologies +# +# SPDX-License-Identifier: Apache-2.0 + +config VOLTAGE_DIVIDER + bool "Voltage sensor driver" + default y + depends on DT_HAS_VOLTAGE_DIVIDER_ENABLED + depends on ADC + help + Enable voltage sensor driver. diff --git a/drivers/sensor/voltage_divider/voltage.c b/drivers/sensor/voltage_divider/voltage.c new file mode 100644 index 00000000000..ef2b34c74b3 --- /dev/null +++ b/drivers/sensor/voltage_divider/voltage.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2023 FTP Technologies + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT voltage_divider + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(voltage, CONFIG_SENSOR_LOG_LEVEL); + +struct voltage_config { + struct voltage_divider_dt_spec voltage; +#ifdef CONFIG_PM_DEVICE + struct gpio_dt_spec gpio_power; +#endif +}; + +struct voltage_data { + struct adc_sequence sequence; + int16_t raw; +}; + +static int fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct voltage_config *config = dev->config; + struct voltage_data *data = dev->data; + int ret; + + if ((chan != SENSOR_CHAN_VOLTAGE) && (chan != SENSOR_CHAN_ALL)) { + return -ENOTSUP; + } + + ret = adc_read(config->voltage.port.dev, &data->sequence); + if (ret != 0) { + LOG_ERR("adc_read: %d", ret); + } + + return ret; +} + +static int get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) +{ + const struct voltage_config *config = dev->config; + struct voltage_data *data = dev->data; + int32_t raw_val = data->raw; + int32_t v_mv; + int ret; + + __ASSERT_NO_MSG(val != NULL); + + if (chan != SENSOR_CHAN_VOLTAGE) { + return -ENOTSUP; + } + + ret = adc_raw_to_millivolts_dt(&config->voltage.port, &raw_val); + if (ret != 0) { + LOG_ERR("raw_to_mv: %d", ret); + return ret; + } + + v_mv = raw_val; + + /* Note if full_ohms is not specified then unscaled voltage is returned */ + (void)voltage_divider_scale_dt(&config->voltage, &v_mv); + + LOG_DBG("%d of %d, %dmV, voltage:%dmV", data->raw, + (1 << data->sequence.resolution) - 1, raw_val, v_mv); + val->val1 = v_mv / 1000; + val->val2 = (v_mv * 1000) % 1000000; + + return ret; +} + +static const struct sensor_driver_api voltage_api = { + .sample_fetch = fetch, + .channel_get = get, +}; + +#ifdef CONFIG_PM_DEVICE +static int pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct voltage_config *config = dev->config; + int ret; + + if (config->gpio_power.port == NULL) { + LOG_ERR("PM not supported"); + return -ENOTSUP; + } + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = gpio_pin_set_dt(&config->gpio_power, 1); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM resume"); + } + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = gpio_pin_set_dt(&config->gpio_power, 0); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM suspend"); + } + break; + default: + return -ENOTSUP; + } + + return ret; +} +#endif + +static int voltage_init(const struct device *dev) +{ + const struct voltage_config *config = dev->config; + struct voltage_data *data = dev->data; + int ret; + + if (!adc_is_ready_dt(&config->voltage.port)) { + LOG_ERR("ADC is not ready"); + return -ENODEV; + } + +#ifdef CONFIG_PM_DEVICE + if (config->gpio_power.port != NULL) { + if (!gpio_is_ready_dt(&config->gpio_power)) { + LOG_ERR("Power GPIO is not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->gpio_power, GPIO_OUTPUT_ACTIVE); + if (ret != 0) { + LOG_ERR("failed to initialize GPIO for reset"); + } + } +#endif + + ret = adc_channel_setup_dt(&config->voltage.port); + if (ret != 0) { + LOG_ERR("setup: %d", ret); + return ret; + } + + ret = adc_sequence_init_dt(&config->voltage.port, &data->sequence); + if (ret != 0) { + LOG_ERR("sequence init: %d", ret); + return ret; + } + + data->sequence.buffer = &data->raw; + data->sequence.buffer_size = sizeof(data->raw); + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +#define POWER_GPIOS(inst) .gpio_power = GPIO_DT_SPEC_INST_GET_OR(inst, power_gpios, {0}), +#else +#define POWER_GPIOS(inst) +#endif + +#define VOLTAGE_INIT(inst) \ + static struct voltage_data voltage_##inst##_data; \ + \ + static const struct voltage_config voltage_##inst##_config = { \ + .voltage = VOLTAGE_DIVIDER_DT_SPEC_GET(DT_DRV_INST(inst)), \ + POWER_GPIOS(inst) \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &voltage_init, PM_DEVICE_DT_INST_GET(inst), \ + &voltage_##inst##_data, &voltage_##inst##_config, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &voltage_api); + +DT_INST_FOREACH_STATUS_OKAY(VOLTAGE_INIT) From a55d7eefef83d76e374ffd6e310c501eb3cef278 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 11 Jun 2023 21:32:37 +1000 Subject: [PATCH 0944/4498] tests: drivers: build all: sensor: add voltage Add voltage sensor driver to tests. Signed-off-by: Nick Ward --- tests/drivers/build_all/sensor/adc.dtsi | 10 ++++++++++ tests/drivers/build_all/sensor/app.overlay | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index fb004abaf37..e5d24cc4f31 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -14,6 +14,16 @@ test_adc_mcp9700a: mcp9700a { io-channels = <&test_adc 0>; }; +test_voltage: voltage { + status = "okay"; + compatible = "voltage-divider"; + io-channels = <&test_adc 1>; + io-channel-names = "VOLTAGE"; + output-ohms = <47000>; /* R1 */ + full-ohms = <(100000 + 47000)>; /* R2 + R1 */ + power-gpios = <&test_gpio 0 0>; +}; + test_current: current_amp { status = "okay"; compatible = "current-sense-amplifier"; diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 6348c648e3c..629334bc396 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -32,6 +32,15 @@ zephyr,resolution = <12>; }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1_6"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = <0>; + zephyr,resolution = <12>; + }; + channel@2 { reg = <2>; zephyr,gain = "ADC_GAIN_1_6"; From acc5501118b2148de8f15e70396cc239e99769b1 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Fri, 19 May 2023 14:12:30 -0600 Subject: [PATCH 0945/4498] zdsp: Add Q value print formatting helpers for Introduce PRI style formatting for DSP values. These require the use of another separate macro to set up the argument (PRIq_arg). Signed-off-by: Yuval Peress --- include/zephyr/dsp/dsp.h | 2 + include/zephyr/dsp/print_format.h | 66 ++++++++ tests/subsys/dsp/print_format/CMakeLists.txt | 8 + tests/subsys/dsp/print_format/prj.conf | 5 + tests/subsys/dsp/print_format/src/main.c | 161 +++++++++++++++++++ tests/subsys/dsp/print_format/testcase.yaml | 8 + 6 files changed, 250 insertions(+) create mode 100644 include/zephyr/dsp/print_format.h create mode 100644 tests/subsys/dsp/print_format/CMakeLists.txt create mode 100644 tests/subsys/dsp/print_format/prj.conf create mode 100644 tests/subsys/dsp/print_format/src/main.c create mode 100644 tests/subsys/dsp/print_format/testcase.yaml diff --git a/include/zephyr/dsp/dsp.h b/include/zephyr/dsp/dsp.h index d475c68a007..cfaa817cf2e 100644 --- a/include/zephyr/dsp/dsp.h +++ b/include/zephyr/dsp/dsp.h @@ -38,6 +38,8 @@ #include +#include + #include "zdsp_backend.h" #endif /* INCLUDE_ZEPHYR_DSP_DSP_H_ */ diff --git a/include/zephyr/dsp/print_format.h b/include/zephyr/dsp/print_format.h new file mode 100644 index 00000000000..695691424df --- /dev/null +++ b/include/zephyr/dsp/print_format.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_DSP_PRINT_FORMAT_H +#define ZEPHYR_INCLUDE_ZEPHYR_DSP_PRINT_FORMAT_H + +#include +#include +#include + +/** + * @ingroup math_dsp + * @defgroup math_printing Helper macros for printing Q values. + * + * Extends the existing inttypes headers for print formatting. Useage: + * @code{c} + * printk("Value=%" PRIq "\n", PRIq_arg(value, 6, 2)); + * @endcode + * + * For a Q value representing 0.5, the expected output will be: + * "Value=2.000000" + * + * @{ + */ + +/** + * @brief Insert Q value format string + */ +#define PRIq(precision) "s%" PRIu32 ".%0" STRINGIFY(precision) PRIu32 + +static inline int64_t ___PRIq_arg_shift(int64_t q, int shift) +{ + if (shift < 0) { + return llabs(q) >> -shift; + } else { + return llabs(q) << shift; + } +} + +#define __EXP2(a, b) a ## b +#define __EXP(a, b) __EXP2(a ## e, b) +#define __CONSTPOW(C, x) __EXP(C, x) + +#define __PRIq_arg_shift(q, shift) ___PRIq_arg_shift(q, ((shift) + (8 * (4 - (int)sizeof(q))))) +#define __PRIq_arg_get(q, shift, h, l) FIELD_GET(GENMASK64(h, l), __PRIq_arg_shift(q, shift)) +#define __PRIq_arg_get_int(q, shift) __PRIq_arg_get(q, shift, 63, 31) +#define __PRIq_arg_get_frac(q, precision, shift) \ + ((__PRIq_arg_get(q, shift, 30, 0) * __CONSTPOW(1, precision)) / INT32_MAX) + +/** + * @brief Insert Q value arguments to print format + * + * @param[in] q The q value + * @param[in] precision Number of decimal points to print + * @param[in] shift The "scale" to shift @p q by + */ +#define PRIq_arg(q, precision, shift) \ + ((q) < 0 ? "-" : ""), (uint32_t)__PRIq_arg_get_int(q, shift), \ + (uint32_t)__PRIq_arg_get_frac(q, precision, shift) + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_ZEPHYR_DSP_PRINT_FORMAT_H */ diff --git a/tests/subsys/dsp/print_format/CMakeLists.txt b/tests/subsys/dsp/print_format/CMakeLists.txt new file mode 100644 index 00000000000..08878fc0c41 --- /dev/null +++ b/tests/subsys/dsp/print_format/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(zdsp_conversions) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/dsp/print_format/prj.conf b/tests/subsys/dsp/print_format/prj.conf new file mode 100644 index 00000000000..9f0a63c9804 --- /dev/null +++ b/tests/subsys/dsp/print_format/prj.conf @@ -0,0 +1,5 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_NEWLIB_LIBC=y +CONFIG_DSP=y +CONFIG_CMSIS_DSP=y diff --git a/tests/subsys/dsp/print_format/src/main.c b/tests/subsys/dsp/print_format/src/main.c new file mode 100644 index 00000000000..fcaff86113a --- /dev/null +++ b/tests/subsys/dsp/print_format/src/main.c @@ -0,0 +1,161 @@ +/* Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define float_multiplier(type) ((INT64_C(1) << (8 * sizeof(type) - 1)) - 1) + +#define assert_strings(expected, actual) \ + zexpect_equal(strlen(expected), strlen(actual), "Expected %d(%s), got %d(%s)", \ + strlen(expected), expected, strlen(actual), actual); \ + zexpect_mem_equal(expected, actual, MIN(strlen(expected), strlen(actual)), \ + "Expected '%s', got '%s'", expected, actual) + +ZTEST_SUITE(zdsp_print_format, NULL, NULL, NULL, NULL, NULL); + +ZTEST(zdsp_print_format, test_print_q31_precision_positive) +{ + char buffer[256]; + q31_t q = (q31_t)0x0f5c28f0; /* 0.119999997 */ + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, 0)); + assert_strings("0.119999", buffer); + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, 1)); + assert_strings("0.239999", buffer); + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, -2)); + assert_strings("0.029999", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 0)); + assert_strings("0.1199", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 1)); + assert_strings("0.2399", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, -2)); + assert_strings("0.0299", buffer); +} + +ZTEST(zdsp_print_format, test_print_q31_precision_negative) +{ + char buffer[256]; + q31_t q = (q31_t)0x83d70a00; /* -0.970000029 */ + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, 0)); + assert_strings("-0.970000", buffer); + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, 1)); + assert_strings("-1.940000", buffer); + + snprintf(buffer, 256, "%" PRIq(6), PRIq_arg(q, 6, -2)); + assert_strings("-0.242500", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 0)); + assert_strings("-0.9700", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 1)); + assert_strings("-1.9400", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, -2)); + assert_strings("-0.2425", buffer); +} + +ZTEST(zdsp_print_format, test_print_q15_precision_positive) +{ + char buffer[256]; + q15_t q = (q15_t)0x28f5; /* 0.319986672 */ + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, 0)); + assert_strings("0.31997", buffer); + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, 1)); + assert_strings("0.63995", buffer); + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, -2)); + assert_strings("0.07999", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, 0)); + assert_strings("0.319", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, 1)); + assert_strings("0.639", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, -2)); + assert_strings("0.079", buffer); +} + +ZTEST(zdsp_print_format, test_print_q15_precision_negative) +{ + char buffer[256]; + q15_t q = (q15_t)0xc4bd; /* -0.462965789 */ + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, 0)); + assert_strings("-0.46298", buffer); + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, 1)); + assert_strings("-0.92596", buffer); + + snprintf(buffer, 256, "%" PRIq(5), PRIq_arg(q, 5, -2)); + assert_strings("-0.11574", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, 0)); + assert_strings("-0.462", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, 1)); + assert_strings("-0.925", buffer); + + snprintf(buffer, 256, "%" PRIq(3), PRIq_arg(q, 3, -2)); + assert_strings("-0.115", buffer); +} + +ZTEST(zdsp_print_format, test_print_q7_precision_positive) +{ + char buffer[256]; + q7_t q = (q7_t)0x01; /* 0.007874016 */ + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 0)); + assert_strings("0.0078", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 1)); + assert_strings("0.0156", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, -2)); + assert_strings("0.0019", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, 0)); + assert_strings("0.00", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, 1)); + assert_strings("0.01", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, -2)); + assert_strings("0.00", buffer); +} + +ZTEST(zdsp_print_format, test_print_q7_precision_negative) +{ + char buffer[256]; + q7_t q = (q7_t)0xe2; /* -0.228346457 */ + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 0)); + assert_strings("-0.2343", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, 1)); + assert_strings("-0.4687", buffer); + + snprintf(buffer, 256, "%" PRIq(4), PRIq_arg(q, 4, -2)); + assert_strings("-0.0585", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, 0)); + assert_strings("-0.23", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, 1)); + assert_strings("-0.46", buffer); + + snprintf(buffer, 256, "%" PRIq(2), PRIq_arg(q, 2, -2)); + assert_strings("-0.05", buffer); +} diff --git a/tests/subsys/dsp/print_format/testcase.yaml b/tests/subsys/dsp/print_format/testcase.yaml new file mode 100644 index 00000000000..0c45be47262 --- /dev/null +++ b/tests/subsys/dsp/print_format/testcase.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 +tests: + zdsp.print_format: + filter: TOOLCHAIN_HAS_NEWLIB == 1 or CONFIG_ARCH_POSIX + tags: zdsp + min_flash: 128 + min_ram: 64 From 5e14088a3fd23d54b6e33a3fd39c8c05f6187ff4 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Mon, 7 Aug 2023 01:03:10 -0600 Subject: [PATCH 0946/4498] sensors: vertically decode raw data Update the decoder APIs to vertically decode the raw sensor data. This means that instead of getting each channel on a frame by frame basis, the API takes a channel specifier and returns as many frames of that given channel as there's room. The goal of this is to make the end decoded result the most useful and usable for the Zephyr application. See #60944 for details. Signed-off-by: Yuval Peress --- drivers/sensor/akm09918c/akm09918c.c | 4 +- drivers/sensor/default_rtio_sensor.c | 317 +++++++++++++++++---- drivers/sensor/icm42688/icm42688_decoder.c | 196 +++++++++---- drivers/sensor/sensor_shell.c | 111 +++++--- include/zephyr/drivers/sensor.h | 169 ++++++----- include/zephyr/drivers/sensor_data_types.h | 168 +++++++++++ 6 files changed, 740 insertions(+), 225 deletions(-) create mode 100644 include/zephyr/drivers/sensor_data_types.h diff --git a/drivers/sensor/akm09918c/akm09918c.c b/drivers/sensor/akm09918c/akm09918c.c index f9c72ec21b9..1225d69a3d2 100644 --- a/drivers/sensor/akm09918c/akm09918c.c +++ b/drivers/sensor/akm09918c/akm09918c.c @@ -27,7 +27,7 @@ static int akm09918c_sample_fetch(const struct device *dev, enum sensor_channel if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_MAGN_X && chan != SENSOR_CHAN_MAGN_Y && chan != SENSOR_CHAN_MAGN_Z && chan != SENSOR_CHAN_MAGN_XYZ) { - LOG_WRN("Invalid channel %d", chan); + LOG_DBG("Invalid channel %d", chan); return -EINVAL; } @@ -85,7 +85,7 @@ static int akm09918c_channel_get(const struct device *dev, enum sensor_channel c } else if (chan == SENSOR_CHAN_MAGN_Z) { akm09918c_convert(val, data->z_sample); } else { - LOG_WRN("Invalid channel %d", chan); + LOG_DBG("Invalid channel %d", chan); return -ENOTSUP; } diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index 55db893f4d8..60534c84d28 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -251,66 +251,205 @@ void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callbac * Default reader can only ever service a single frame at a time. * * @param[in] buffer The data buffer to parse + * @param[in] channel The channel to get the count for + * @param[in] channel_idx The index of the channel * @param[out] frame_count The number of frames in the buffer (always 1) * @return 0 in all cases */ -static int get_frame_count(const uint8_t *buffer, uint16_t *frame_count) +static int get_frame_count(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx, + uint16_t *frame_count) { - ARG_UNUSED(buffer); - *frame_count = 1; - return 0; + struct sensor_data_generic_header *header = (struct sensor_data_generic_header *)buffer; + size_t count = 0; + + switch (channel) { + case SENSOR_CHAN_ACCEL_XYZ: + channel = SENSOR_CHAN_ACCEL_X; + break; + case SENSOR_CHAN_GYRO_XYZ: + channel = SENSOR_CHAN_GYRO_X; + break; + case SENSOR_CHAN_MAGN_XYZ: + channel = SENSOR_CHAN_MAGN_X; + break; + default: + break; + } + for (size_t i = 0; i < header->num_channels; ++i) { + if (header->channels[i] == channel) { + if (channel_idx == count) { + *frame_count = 1; + return 0; + } + ++count; + } + } + + return -ENOTSUP; } -/** - * @brief Default decoder get the timestamp of the first frame - * - * @param[in] buffer The data buffer to parse - * @param[out] timestamp_ns The timestamp of the first frame - * @return 0 in all cases - */ -static int get_timestamp(const uint8_t *buffer, uint64_t *timestamp_ns) +int sensor_natively_supported_channel_size_info(enum sensor_channel channel, size_t *base_size, + size_t *frame_size) { - *timestamp_ns = ((struct sensor_data_generic_header *)buffer)->timestamp_ns; - return 0; + __ASSERT_NO_MSG(base_size != NULL); + __ASSERT_NO_MSG(frame_size != NULL); + + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: + case SENSOR_CHAN_POS_DX: + case SENSOR_CHAN_POS_DY: + case SENSOR_CHAN_POS_DZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + case SENSOR_CHAN_DIE_TEMP: + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_PRESS: + case SENSOR_CHAN_HUMIDITY: + case SENSOR_CHAN_LIGHT: + case SENSOR_CHAN_IR: + case SENSOR_CHAN_RED: + case SENSOR_CHAN_GREEN: + case SENSOR_CHAN_BLUE: + case SENSOR_CHAN_ALTITUDE: + case SENSOR_CHAN_PM_1_0: + case SENSOR_CHAN_PM_2_5: + case SENSOR_CHAN_PM_10: + case SENSOR_CHAN_DISTANCE: + case SENSOR_CHAN_CO2: + case SENSOR_CHAN_VOC: + case SENSOR_CHAN_GAS_RES: + case SENSOR_CHAN_VOLTAGE: + case SENSOR_CHAN_CURRENT: + case SENSOR_CHAN_POWER: + case SENSOR_CHAN_RESISTANCE: + case SENSOR_CHAN_ROTATION: + case SENSOR_CHAN_RPM: + case SENSOR_CHAN_GAUGE_VOLTAGE: + case SENSOR_CHAN_GAUGE_AVG_CURRENT: + case SENSOR_CHAN_GAUGE_STDBY_CURRENT: + case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT: + case SENSOR_CHAN_GAUGE_TEMP: + case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE: + case SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY: + case SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY: + case SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY: + case SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY: + case SENSOR_CHAN_GAUGE_AVG_POWER: + case SENSOR_CHAN_GAUGE_STATE_OF_HEALTH: + case SENSOR_CHAN_GAUGE_TIME_TO_EMPTY: + case SENSOR_CHAN_GAUGE_TIME_TO_FULL: + case SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE: + case SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE: + case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT: + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + case SENSOR_CHAN_PROX: + *base_size = sizeof(struct sensor_byte_data); + *frame_size = sizeof(struct sensor_byte_sample_data); + return 0; + case SENSOR_CHAN_GAUGE_CYCLE_COUNT: + *base_size = sizeof(struct sensor_uint64_data); + *frame_size = sizeof(struct sensor_uint64_sample_data); + return 0; + default: + return -ENOTSUP; + } } -/** - * @brief Default decoder get the bitshift of the given channel (if possible) - * - * @param[in] buffer The data buffer to parse - * @param[in] channel_type The channel to query - * @param[out] shift The bitshift for the q31 value - * @return 0 on success - * @return -EINVAL if the @p channel_type couldn't be found - */ -static int get_shift(const uint8_t *buffer, enum sensor_channel channel_type, int8_t *shift) +static int get_q31_value(const struct sensor_data_generic_header *header, const q31_t *values, + enum sensor_channel channel, size_t channel_idx, q31_t *out) { - struct sensor_data_generic_header *header = (struct sensor_data_generic_header *)buffer; + size_t count = 0; - ARG_UNUSED(channel_type); - *shift = header->shift; - return 0; + for (size_t i = 0; i < header->num_channels; ++i) { + if (channel != header->channels[i]) { + continue; + } + if (count == channel_idx) { + *out = values[i]; + return 0; + } + ++count; + } + return -EINVAL; +} + +static int decode_three_axis(const struct sensor_data_generic_header *header, const q31_t *values, + struct sensor_three_axis_data *data_out, enum sensor_channel x, + enum sensor_channel y, enum sensor_channel z, size_t channel_idx) +{ + int rc; + + data_out->header.base_timestamp_ns = header->timestamp_ns; + data_out->header.reading_count = 1; + data_out->shift = header->shift; + data_out->readings[0].timestamp_delta = 0; + + rc = get_q31_value(header, values, x, channel_idx, &data_out->readings[0].values[0]); + if (rc < 0) { + return rc; + } + rc = get_q31_value(header, values, y, channel_idx, &data_out->readings[0].values[1]); + if (rc < 0) { + return rc; + } + rc = get_q31_value(header, values, z, channel_idx, &data_out->readings[0].values[2]); + if (rc < 0) { + return rc; + } + return 1; +} + +static int decode_q31(const struct sensor_data_generic_header *header, const q31_t *values, + struct sensor_q31_data *data_out, enum sensor_channel channel, + size_t channel_idx) +{ + int rc; + + data_out->header.base_timestamp_ns = header->timestamp_ns; + data_out->header.reading_count = 1; + data_out->shift = header->shift; + data_out->readings[0].timestamp_delta = 0; + + rc = get_q31_value(header, values, channel, channel_idx, &data_out->readings[0].value); + if (rc < 0) { + return rc; + } + return 1; } /** - * @brief Default decoder decode N samples + * @brief Decode up to N samples from the buffer * - * Decode up to N samples starting at the provided @p fit and @p cit. The appropriate channel types - * and q31 values will be placed in @p values and @p channels respectively. + * This function will never wrap frames. If 1 channel is available in the current frame and + * @p max_count is 2, only 1 channel will be decoded and the frame iterator will be modified + * so that the next call to decode will begin at the next frame. * - * @param[in] buffer The data buffer to decode - * @param[in,out] fit The starting frame iterator - * @param[in,out] cit The starting channel iterator - * @param[out] channels The decoded channel types - * @param[out] values The decoded q31 values - * @param[in] max_count The maximum number of values to decode - * @return > 0 The number of decoded values - * @return 0 Nothing else to decode on this @p buffer - * @return < 0 Error + * @param[in] buffer The buffer provided on the :c:struct:`rtio` context + * @param[in] channel The channel to decode + * @param[in] channel_idx The index of the channel + * @param[in,out] fit The current frame iterator + * @param[in] max_count The maximum number of channels to decode. + * @param[out] data_out The decoded data + * @return 0 no more samples to decode + * @return >0 the number of decoded frames + * @return <0 on error */ -static int decode(const uint8_t *buffer, sensor_frame_iterator_t *fit, - sensor_channel_iterator_t *cit, enum sensor_channel *channels, q31_t *values, - uint8_t max_count) +static int decode(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx, + uint32_t *fit, uint16_t max_count, void *data_out) { const struct sensor_data_generic_header *header = (const struct sensor_data_generic_header *)buffer; @@ -319,32 +458,92 @@ static int decode(const uint8_t *buffer, sensor_frame_iterator_t *fit, header->num_channels * sizeof(enum sensor_channel)); int count = 0; - if (*fit != 0 || *cit >= header->num_channels) { + if (*fit != 0 || max_count < 1) { return -EINVAL; } - /* Skip invalid channels */ - while (*cit < header->num_channels && header->channels[*cit] == SENSOR_CHAN_MAX) { - *cit += 1; + /* Check for 3d channel mappings */ + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + count = decode_three_axis(header, q, data_out, SENSOR_CHAN_ACCEL_X, + SENSOR_CHAN_ACCEL_Y, SENSOR_CHAN_ACCEL_Z, channel_idx); + break; + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + count = decode_three_axis(header, q, data_out, SENSOR_CHAN_GYRO_X, + SENSOR_CHAN_GYRO_Y, SENSOR_CHAN_GYRO_Z, channel_idx); + break; + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: + count = decode_three_axis(header, q, data_out, SENSOR_CHAN_MAGN_X, + SENSOR_CHAN_MAGN_Y, SENSOR_CHAN_MAGN_Z, channel_idx); + break; + case SENSOR_CHAN_POS_DX: + case SENSOR_CHAN_POS_DY: + case SENSOR_CHAN_POS_DZ: + count = decode_three_axis(header, q, data_out, SENSOR_CHAN_POS_DX, + SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DZ, channel_idx); + break; + case SENSOR_CHAN_DIE_TEMP: + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_PRESS: + case SENSOR_CHAN_HUMIDITY: + case SENSOR_CHAN_LIGHT: + case SENSOR_CHAN_IR: + case SENSOR_CHAN_RED: + case SENSOR_CHAN_GREEN: + case SENSOR_CHAN_BLUE: + case SENSOR_CHAN_ALTITUDE: + case SENSOR_CHAN_PM_1_0: + case SENSOR_CHAN_PM_2_5: + case SENSOR_CHAN_PM_10: + case SENSOR_CHAN_DISTANCE: + case SENSOR_CHAN_CO2: + case SENSOR_CHAN_VOC: + case SENSOR_CHAN_GAS_RES: + case SENSOR_CHAN_VOLTAGE: + case SENSOR_CHAN_CURRENT: + case SENSOR_CHAN_POWER: + case SENSOR_CHAN_RESISTANCE: + case SENSOR_CHAN_ROTATION: + case SENSOR_CHAN_RPM: + case SENSOR_CHAN_GAUGE_VOLTAGE: + case SENSOR_CHAN_GAUGE_AVG_CURRENT: + case SENSOR_CHAN_GAUGE_STDBY_CURRENT: + case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT: + case SENSOR_CHAN_GAUGE_TEMP: + case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE: + case SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY: + case SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY: + case SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY: + case SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY: + case SENSOR_CHAN_GAUGE_AVG_POWER: + case SENSOR_CHAN_GAUGE_STATE_OF_HEALTH: + case SENSOR_CHAN_GAUGE_TIME_TO_EMPTY: + case SENSOR_CHAN_GAUGE_TIME_TO_FULL: + case SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE: + case SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE: + case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT: + count = decode_q31(header, q, data_out, channel, channel_idx); + break; + default: + break; } - - for (; *cit < header->num_channels && count < max_count; ++count) { - channels[count] = header->channels[*cit]; - values[count] = q[*cit]; - LOG_DBG("Decoding q[%u]@%p=%d", *cit, (void *)&q[*cit], q[*cit]); - *cit += 1; - } - - if (*cit >= header->num_channels) { + if (count > 0) { *fit = 1; - *cit = 0; } return count; } const struct sensor_decoder_api __sensor_default_decoder = { .get_frame_count = get_frame_count, - .get_timestamp = get_timestamp, - .get_shift = get_shift, + .get_size_info = sensor_natively_supported_channel_size_info, .decode = decode, }; diff --git a/drivers/sensor/icm42688/icm42688_decoder.c b/drivers/sensor/icm42688/icm42688_decoder.c index 781e7567ffd..91fbfc6f683 100644 --- a/drivers/sensor/icm42688/icm42688_decoder.c +++ b/drivers/sensor/icm42688/icm42688_decoder.c @@ -220,91 +220,183 @@ int icm42688_encode(const struct device *dev, const enum sensor_channel *const c return 0; } -static int icm42688_one_shot_decode(const uint8_t *buffer, sensor_frame_iterator_t *fit, - sensor_channel_iterator_t *cit, enum sensor_channel *channels, - q31_t *values, uint8_t max_count) +static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, sensor_frame_iterator_t *fit, + uint16_t max_count, void *data_out) { const struct icm42688_encoded_data *edata = (const struct icm42688_encoded_data *)buffer; - uint8_t channel_pos_read = edata->channels; + const struct icm42688_decoder_header *header = &edata->header; struct icm42688_cfg cfg = { .accel_fs = edata->header.accel_fs, .gyro_fs = edata->header.gyro_fs, }; - enum sensor_channel chan; - int pos; - int count = 0; - int num_samples = __builtin_popcount(channel_pos_read); - - channel_pos_read = edata->channels; + uint8_t channel_request; + int rc; if (*fit != 0) { return 0; } - - /* Skip channels already decoded */ - for (int i = 0; i < *cit && channel_pos_read; i++) { - pos = __builtin_ctz(channel_pos_read); - channel_pos_read &= ~BIT(pos); + if (max_count == 0 || channel_idx != 0) { + return -EINVAL; } - /* Decode remaining channels */ - while (channel_pos_read && *cit < num_samples && count < max_count) { - pos = __builtin_ctz(channel_pos_read); - chan = icm42688_get_channel_from_position(pos); + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: { + channel_request = icm42688_encode_channel(SENSOR_CHAN_ACCEL_XYZ); + if ((channel_request & edata->channels) != channel_request) { + return -ENODATA; + } - channels[count] = chan; + struct sensor_three_axis_data *out = data_out; - icm42688_convert_raw_to_q31(&cfg, chan, edata->readings[pos], &values[count]); + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + rc = icm42688_get_shift(SENSOR_CHAN_ACCEL_XYZ, header->accel_fs, header->gyro_fs, + &out->shift); + if (rc != 0) { + return -EINVAL; + } - count++; - channel_pos_read &= ~BIT(pos); - *cit += 1; + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_ACCEL_X, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_X)], + &out->readings[0].x); + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_ACCEL_Y, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Y)], + &out->readings[0].y); + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_ACCEL_Z, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Z)], + &out->readings[0].z); + *fit = 1; + return 1; } + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: { + channel_request = icm42688_encode_channel(SENSOR_CHAN_GYRO_XYZ); + if ((channel_request & edata->channels) != channel_request) { + return -ENODATA; + } - if (*cit >= __builtin_popcount(edata->channels)) { - *fit += 1; - *cit = 0; + struct sensor_three_axis_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + rc = icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, header->accel_fs, header->gyro_fs, + &out->shift); + if (rc != 0) { + return -EINVAL; + } + + out->readings[0].timestamp_delta = 0; + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_GYRO_X, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_X)], + &out->readings[0].x); + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_GYRO_Y, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_Y)], + &out->readings[0].y); + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_GYRO_Z, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_Z)], + &out->readings[0].z); + *fit = 1; + return 1; } + case SENSOR_CHAN_DIE_TEMP: { + channel_request = icm42688_encode_channel(SENSOR_CHAN_DIE_TEMP); + if ((channel_request & edata->channels) != channel_request) { + return -ENODATA; + } - return count; -} + struct sensor_q31_data *out = data_out; -static int icm42688_decoder_decode(const uint8_t *buffer, sensor_frame_iterator_t *fit, - sensor_channel_iterator_t *cit, enum sensor_channel *channels, - q31_t *values, uint8_t max_count) -{ - return icm42688_one_shot_decode(buffer, fit, cit, channels, values, max_count); + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + + rc = icm42688_get_shift(SENSOR_CHAN_DIE_TEMP, header->accel_fs, header->gyro_fs, + &out->shift); + if (rc != 0) { + return -EINVAL; + } + out->readings[0].timestamp_delta = 0; + icm42688_convert_raw_to_q31( + &cfg, SENSOR_CHAN_DIE_TEMP, + edata->readings[icm42688_get_channel_position(SENSOR_CHAN_DIE_TEMP)], + &out->readings[0].temperature); + *fit = 1; + return 1; + } + default: + return -EINVAL; + } } -static int icm42688_decoder_get_frame_count(const uint8_t *buffer, uint16_t *frame_count) +static int icm42688_decoder_decode(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, sensor_frame_iterator_t *fit, + uint16_t max_count, void *data_out) { - ARG_UNUSED(buffer); - *frame_count = 1; - return 0; + return icm42688_one_shot_decode(buffer, channel, channel_idx, fit, max_count, data_out); } -static int icm42688_decoder_get_timestamp(const uint8_t *buffer, uint64_t *timestamp_ns) +static int icm42688_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, uint16_t *frame_count) { - const struct icm42688_decoder_header *header = - (const struct icm42688_decoder_header *)buffer; - - *timestamp_ns = header->timestamp; - return 0; + ARG_UNUSED(buffer); + if (channel_idx != 0) { + return -ENOTSUP; + } + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_DIE_TEMP: + *frame_count = 1; + return 0; + default: + return -ENOTSUP; + } } -static int icm42688_decoder_get_shift(const uint8_t *buffer, enum sensor_channel channel_type, - int8_t *shift) +static int icm42688_decoder_get_size_info(enum sensor_channel channel, size_t *base_size, + size_t *frame_size) { - const struct icm42688_decoder_header *header = - (const struct icm42688_decoder_header *)buffer; - - return icm42688_get_shift(channel_type, header->accel_fs, header->gyro_fs, shift); + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + case SENSOR_CHAN_DIE_TEMP: + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } } SENSOR_DECODER_API_DT_DEFINE() = { .get_frame_count = icm42688_decoder_get_frame_count, - .get_timestamp = icm42688_decoder_get_timestamp, - .get_shift = icm42688_decoder_get_shift, + .get_size_info = icm42688_decoder_get_size_info, .decode = icm42688_decoder_decode, }; diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index 459ea0882f7..a85eab23e43 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -244,11 +244,7 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t { struct sensor_shell_processing_context *ctx = userdata; const struct sensor_decoder_api *decoder; - sensor_frame_iterator_t fit = {0}; - sensor_channel_iterator_t cit = {0}; - uint64_t timestamp; - enum sensor_channel channel; - q31_t q; + uint8_t decoded_buffer[128]; int rc; ARG_UNUSED(buf_len); @@ -264,45 +260,85 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t return; } - rc = decoder->get_timestamp(buf, ×tamp); - if (rc != 0) { - shell_error(ctx->sh, "Failed to get fetch timestamp for '%s'", ctx->dev->name); - return; - } - shell_print(ctx->sh, "Got samples at %" PRIu64 " ns", timestamp); + for (int channel = 0; channel < SENSOR_CHAN_ALL; ++channel) { + uint32_t fit = 0; + size_t base_size; + size_t frame_size; + size_t channel_idx = 0; + uint16_t frame_count; - while (decoder->decode(buf, &fit, &cit, &channel, &q, 1) > 0) { - int8_t shift; + if (channel == SENSOR_CHAN_ACCEL_X || channel == SENSOR_CHAN_ACCEL_Y || + channel == SENSOR_CHAN_ACCEL_Z || channel == SENSOR_CHAN_GYRO_X || + channel == SENSOR_CHAN_GYRO_Y || channel == SENSOR_CHAN_GYRO_Z || + channel == SENSOR_CHAN_MAGN_X || channel == SENSOR_CHAN_MAGN_Y || + channel == SENSOR_CHAN_MAGN_Z || channel == SENSOR_CHAN_POS_DY || + channel == SENSOR_CHAN_POS_DZ) { + continue; + } - rc = decoder->get_shift(buf, channel, &shift); + rc = decoder->get_size_info(channel, &base_size, &frame_size); if (rc != 0) { - shell_error(ctx->sh, "Failed to get bitshift for channel %d", channel); + /* Channel not supported, skipping */ continue; } - int64_t scaled_value = (int64_t)q << shift; - bool is_negative = scaled_value < 0; - int numerator; - int denominator; - - scaled_value = llabs(scaled_value); - numerator = (int)FIELD_GET(GENMASK64(31 + shift, 31), scaled_value); - denominator = (int)DIV_ROUND_CLOSEST( - FIELD_GET(GENMASK64(30, 0), scaled_value) * 1000000, - INT32_MAX); - - if (denominator == 1000000) { - numerator++; - denominator = 0; + if (base_size > ARRAY_SIZE(decoded_buffer)) { + shell_error(ctx->sh, + "Channel (%d) requires %zu bytes to decode, but only %zu are " + "available", + channel, base_size, ARRAY_SIZE(decoded_buffer)); + continue; } - if (channel >= ARRAY_SIZE(sensor_channel_name)) { - shell_print(ctx->sh, "channel idx=%d value=%s%d.%06d", channel, - is_negative ? "-" : "", numerator, denominator); - } else { - shell_print(ctx->sh, "channel idx=%d %s value=%s%d.%06d", channel, - sensor_channel_name[channel], is_negative ? "-" : "", numerator, - denominator); + while (decoder->get_frame_count(buf, channel, channel_idx, &frame_count) == 0) { + fit = 0; + while (decoder->decode(buf, channel, channel_idx, &fit, 1, decoded_buffer) > + 0) { + + switch (channel) { + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_MAGN_XYZ: + case SENSOR_CHAN_POS_DX: { + struct sensor_three_axis_data *data = + (struct sensor_three_axis_data *)decoded_buffer; + + shell_info(ctx->sh, + "channel idx=%d %s shift=%d " + "value=%" PRIsensor_three_axis_data, + channel, sensor_channel_name[channel], + data->shift, + PRIsensor_three_axis_data_arg(*data, 0)); + break; + } + case SENSOR_CHAN_PROX: { + struct sensor_byte_data *data = + (struct sensor_byte_data *)decoded_buffer; + + shell_info(ctx->sh, + "channel idx=%d %s value=%" PRIsensor_byte_data( + is_near), + channel, sensor_channel_name[channel], + PRIsensor_byte_data_arg(*data, 0, is_near)); + break; + } + default: { + struct sensor_q31_data *data = + (struct sensor_q31_data *)decoded_buffer; + + shell_info(ctx->sh, + "channel idx=%d %s shift=%d " + "value=%" PRIsensor_q31_data, + channel, + (channel >= ARRAY_SIZE(sensor_channel_name)) + ? "" + : sensor_channel_name[channel], + data->shift, PRIsensor_q31_data_arg(*data, 0)); + break; + } + } + } + ++channel_idx; } } } @@ -621,8 +657,7 @@ static int cmd_get_sensor_info(const struct shell *sh, size_t argc, char **argv) #ifdef CONFIG_SENSOR_INFO const char *null_str = "(null)"; - STRUCT_SECTION_FOREACH(sensor_info, sensor) - { + STRUCT_SECTION_FOREACH(sensor_info, sensor) { shell_print(sh, "device name: %s, vendor: %s, model: %s, " "friendly name: %s", diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 1569f4a27b3..76b65da4880 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -403,46 +404,6 @@ typedef int (*sensor_channel_get_t)(const struct device *dev, enum sensor_channel chan, struct sensor_value *val); -/** - * @typedef sensor_frame_iterator_t - * @brief Used for iterating over the data frames via the sensor_decoder_api. - * - * Example usage: - * - * @code(.c) - * sensor_frame_iterator_t fit = {0}, fit_last; - * sensor_channel_iterator_t cit = {0}, cit_last; - * - * while (true) { - * int num_decoded_channels; - * enum sensor_channel channel; - * q31_t value; - * - * fit_last = fit; - * num_decoded_channels = decoder->decode(buffer, &fit, &cit, &channel, &value, 1); - * - * if (num_decoded_channels <= 0) { - * printk("Done decoding buffer\n"); - * break; - * } - * - * printk("Decoded channel (%d) with value %s0.%06" PRIi64 "\n", q < 0 ? "-" : "", - * abs(q) * INT64_C(1000000) / (INT64_C(1) << 31)); - * - * if (fit_last != fit) { - * printk("Finished decoding frame\n"); - * } - * } - * @endcode - */ -typedef uint32_t sensor_frame_iterator_t; - -/** - * @typedef sensor_channel_iterator_t - * @brief Used for iterating over data channels in the same frame via sensor_decoder_api - */ -typedef uint32_t sensor_channel_iterator_t; - /** * @brief Decodes a single raw data buffer * @@ -454,60 +415,120 @@ struct sensor_decoder_api { * @brief Get the number of frames in the current buffer. * * @param[in] buffer The buffer provided on the @ref rtio context. + * @param[in] channel The channel to get the count for + * @param[in] channel_idx The index of the channel * @param[out] frame_count The number of frames on the buffer (at least 1) * @return 0 on success - * @return <0 on error + * @return -ENOTSUP if the channel/channel_idx aren't found */ - int (*get_frame_count)(const uint8_t *buffer, uint16_t *frame_count); + int (*get_frame_count)(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, uint16_t *frame_count); /** - * @brief Get the timestamp associated with the first frame. + * @brief Get the size required to decode a given channel * - * @param[in] buffer The buffer provided on the @ref rtio context. - * @param[out] timestamp_ns The closest timestamp for when the first frame was generated - * as attained by k_uptime_ticks(). + * When decoding a single frame, use @p base_size. For every additional frame, add another + * @p frame_size. As an example, to decode 3 frames use: 'base_size + 2 * frame_size'. + * + * @param[in] channel The channel to query + * @param[out] base_size The size of decoding the first frame + * @param[out] frame_size The additional size of every additional frame * @return 0 on success - * @return <0 on error + * @return -ENOTSUP if the channel is not supported */ - int (*get_timestamp)(const uint8_t *buffer, uint64_t *timestamp_ns); + int (*get_size_info)(enum sensor_channel channel, size_t *base_size, size_t *frame_size); /** - * @brief Get the shift count of a particular channel (multiplier) + * @brief Decode up to @p max_count samples from the buffer * - * This value can be used by shifting the q31_t value resulting in the SI unit of the - * reading. It is guaranteed that the shift for a channel will not change between frames. + * Decode samples of channel @ref sensor_channel across multiple frames. If there exist + * multiple instances of the same channel, @p channel_index is used to differentiate them. + * As an example, assume a sensor provides 2 distance measurements: * - * @param[in] buffer The buffer provided on the @ref rtio context. - * @param[in] channel_type The c:enum:`sensor_channel` to query - * @param[out] shift The bit shift of the channel for this data buffer. - * @return 0 on success - * @return -EINVAL if the @p channel_type doesn't exist in the buffer - * @return <0 on error - */ - int (*get_shift)(const uint8_t *buffer, enum sensor_channel channel_type, int8_t *shift); - - /** - * @brief Decode up to N samples from the buffer + * @code{.c} + * // Decode the first channel instance of 'distance' + * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 0, &fit, 5, out); + * ... * - * This function will never wrap frames. If 1 channel is available in the current frame and - * @p max_count is 2, only 1 channel will be decoded and the frame iterator will be modified - * so that the next call to decode will begin at the next frame. + * // Decode the second channel instance of 'distance' + * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 1, &fit, 5, out); + * @endcode * * @param[in] buffer The buffer provided on the @ref rtio context + * @param[in] channel The channel to decode + * @param[in] channel_idx The index of the channel * @param[in,out] fit The current frame iterator - * @param[in,out] cit The current channel iterator - * @param[out] channels The channels that were decoded - * @param[out] values The scaled data that was decoded * @param[in] max_count The maximum number of channels to decode. - * @retval > 0 The number of decoded values - * @retval 0 Nothing else to decode on the @p buffer - * @retval < 0 Error + * @param[out] data_out The decoded data + * @return 0 no more samples to decode + * @return >0 the number of decoded frames + * @return <0 on error */ - int (*decode)(const uint8_t *buffer, sensor_frame_iterator_t *fit, - sensor_channel_iterator_t *cit, enum sensor_channel *channels, q31_t *values, - uint8_t max_count); + int (*decode)(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx, + uint32_t *fit, uint16_t max_count, void *data_out); }; +/** + * @brief Used for iterating over the data frames via the sensor_decoder_api. + * + * Example usage: + * + * @code(.c) + * struct sensor_decode_context ctx = SENSOR_DECODE_CONTEXT_INIT( + * decoder, buffer, SENSOR_CHAN_ACCEL_XYZ, 0); + * + * while (true) { + * struct sensor_three_axis_data accel_out_data; + * + * num_decoded_channels = sensor_decode(ctx, &accel_out_data, 1); + * + * if (num_decoded_channels <= 0) { + * printk("Done decoding buffer\n"); + * break; + * } + * + * printk("Decoded (%" PRId32 ", %" PRId32 ", %" PRId32 ")\n", accel_out_data.readings[0].x, + * accel_out_data.readings[0].y, accel_out_data.readings[0].z); + * } + * @endcode + */ +struct sensor_decode_context { + const struct sensor_decoder_api *decoder; + const uint8_t *buffer; + enum sensor_channel channel; + size_t channel_idx; + uint32_t fit; +}; + +/** + * @brief Initialize a sensor_decode_context + */ +#define SENSOR_DECODE_CONTEXT_INIT(decoder_, buffer_, channel_, channel_index_) \ + { \ + .decoder = (decoder_), \ + .buffer = (buffer_), \ + .channel = (channel_), \ + .channel_idx = (channel_index_), \ + .fit = 0, \ + } + +/** + * @brief Decode N frames using a sensor_decode_context + * + * @param[in,out] ctx The context to use for decoding + * @param[out] out The output buffer + * @param[in] max_count Maximum number of frames to decode + * @return The decode result from sensor_decoder_api's decode function + */ +static inline int sensor_decode(struct sensor_decode_context *ctx, void *out, uint16_t max_count) +{ + return ctx->decoder->decode(ctx->buffer, ctx->channel, ctx->channel_idx, &ctx->fit, + max_count, out); +} + +int sensor_natively_supported_channel_size_info(enum sensor_channel channel, size_t *base_size, + size_t *frame_size); + /** * @typedef sensor_get_decoder_t * @brief Get the decoder associate with the given device diff --git a/include/zephyr/drivers/sensor_data_types.h b/include/zephyr/drivers/sensor_data_types.h new file mode 100644 index 00000000000..dd7f1f39c6d --- /dev/null +++ b/include/zephyr/drivers/sensor_data_types.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_DATA_TYPES_H +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_DATA_TYPES_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sensor_data_header { + /** + * The closest timestamp for when the first frame was generated as attained by + * :c:func:`k_uptime_ticks`. + */ + uint64_t base_timestamp_ns; + /** + * The number of elements in the 'readings' array. + * + * This must be at least 1 + */ + uint16_t reading_count; +}; + +/** + * Data for a sensor channel which reports on three axes. This is used by: + * - :c:enum:`SENSOR_CHAN_ACCEL_X` + * - :c:enum:`SENSOR_CHAN_ACCEL_Y` + * - :c:enum:`SENSOR_CHAN_ACCEL_Z` + * - :c:enum:`SENSOR_CHAN_ACCEL_XYZ` + * - :c:enum:`SENSOR_CHAN_GYRO_X` + * - :c:enum:`SENSOR_CHAN_GYRO_Y` + * - :c:enum:`SENSOR_CHAN_GYRO_Z` + * - :c:enum:`SENSOR_CHAN_GYRO_XYZ` + * - :c:enum:`SENSOR_CHAN_MAGN_X` + * - :c:enum:`SENSOR_CHAN_MAGN_Y` + * - :c:enum:`SENSOR_CHAN_MAGN_Z` + * - :c:enum:`SENSOR_CHAN_MAGN_XYZ` + * - :c:enum:`SENSOR_CHAN_POS_DX` + * - :c:enum:`SENSOR_CHAN_POS_DY` + * - :c:enum:`SENSOR_CHAN_POS_DZ` + */ +struct sensor_three_axis_data { + struct sensor_data_header header; + int8_t shift; + struct sensor_three_axis_sample_data { + uint32_t timestamp_delta; + union { + q31_t values[3]; + q31_t v[3]; + struct { + q31_t x; + q31_t y; + q31_t z; + }; + }; + } readings[1]; +}; + +#define PRIsensor_three_axis_data PRIu64 "ns, (%" PRIq(6) ", %" PRIq(6) ", %" PRIq(6) ")" + +#define PRIsensor_three_axis_data_arg(data_, readings_offset_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta, \ + PRIq_arg((data_).readings[(readings_offset_)].x, 6, (data_).shift), \ + PRIq_arg((data_).readings[(readings_offset_)].y, 6, (data_).shift), \ + PRIq_arg((data_).readings[(readings_offset_)].z, 6, (data_).shift) + +/** + * Data from a sensor where we only care about an event occurring. This is used to report triggers. + */ +struct sensor_occurrence_data { + struct sensor_data_header header; + struct sensor_occurrence_sample_data { + uint32_t timestamp_delta; + } readings[1]; +}; + +#define PRIsensor_occurrence_data PRIu64 "ns" + +#define PRIsensor_occurrence_data_arg(data_, readings_offset_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta + +struct sensor_q31_data { + struct sensor_data_header header; + int8_t shift; + struct sensor_q31_sample_data { + uint32_t timestamp_delta; + union { + q31_t value; + q31_t light; /**< Unit: lux */ + q31_t pressure; /**< Unit: kilopascal */ + q31_t temperature; /**< Unit: degrees Celsius */ + q31_t percent; /**< Unit: percent */ + q31_t distance; /**< Unit: meters */ + q31_t density; /**< Unit: ug/m^3 */ + q31_t density_ppm; /**< Unit: parts per million */ + q31_t density_ppb; /**< Unit: parts per billion */ + q31_t resistance; /**< Unit: ohms */ + q31_t voltage; /**< Unit: volts */ + q31_t current; /**< Unit: amps */ + q31_t power; /**< Unit: watts */ + q31_t angle; /**< Unit: degrees */ + q31_t electric_charge; /**< Unit: mAh */ + }; + } readings[1]; +}; + +#define PRIsensor_q31_data PRIu64 "ns (%" PRIq(6) ")" + +#define PRIsensor_q31_data_arg(data_, readings_offset_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta, \ + PRIq_arg((data_).readings[(readings_offset_)].value, 6, (data_).shift) + +/** + * Data from a sensor that produces a byte of data. This is used by: + * - :c:enum:`SENSOR_CHAN_PROX` + */ +struct sensor_byte_data { + struct sensor_data_header header; + struct sensor_byte_sample_data { + uint32_t timestamp_delta; + union { + uint8_t value; + struct { + uint8_t is_near: 1; + uint8_t padding: 7; + }; + }; + } readings[1]; +}; + +#define PRIsensor_byte_data(field_name_) PRIu64 "ns (" STRINGIFY(field_name_) " = %" PRIu8 ")" + +#define PRIsensor_byte_data_arg(data_, readings_offset_, field_name_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta, \ + (data_).readings[(readings_offset_)].field_name_ + +/** + * Data from a sensor that produces a count like value. This is used by: + * - :c:enum:`SENSOR_CHAN_GAUGE_CYCLE_COUNT` + */ +struct sensor_uint64_data { + struct sensor_data_header header; + struct sensor_uint64_sample_data { + uint32_t timestamp_delta; + uint64_t value; + } readings[1]; +}; + +#define PRIsensor_uint64_data PRIu64 "ns (%" PRIu64 ")" + +#define PRIsensor_uint64_data_arg(data_, readings_offset_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta, \ + (data_).readings[(readings_offset_)].value + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_DATA_TYPES_H */ From 2b06884afe44edb29b61ff331d27f69a58eb171d Mon Sep 17 00:00:00 2001 From: Tristan Honscheid Date: Wed, 23 Aug 2023 16:39:37 -0600 Subject: [PATCH 0947/4498] sensors: icm42688: Remove unused function from driver This function is no longer used and causes a compiler error. Signed-off-by: Tristan Honscheid --- drivers/sensor/icm42688/icm42688_decoder.c | 26 ++-------------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/drivers/sensor/icm42688/icm42688_decoder.c b/drivers/sensor/icm42688/icm42688_decoder.c index 91fbfc6f683..0a340aff369 100644 --- a/drivers/sensor/icm42688/icm42688_decoder.c +++ b/drivers/sensor/icm42688/icm42688_decoder.c @@ -77,28 +77,6 @@ static int icm42688_get_shift(enum sensor_channel channel, int accel_fs, int gyr } } -static enum sensor_channel icm42688_get_channel_from_position(int pos) -{ - switch (pos) { - case 0: - return SENSOR_CHAN_DIE_TEMP; - case 1: - return SENSOR_CHAN_ACCEL_X; - case 2: - return SENSOR_CHAN_ACCEL_Y; - case 3: - return SENSOR_CHAN_ACCEL_Z; - case 4: - return SENSOR_CHAN_GYRO_X; - case 5: - return SENSOR_CHAN_GYRO_Y; - case 6: - return SENSOR_CHAN_GYRO_Z; - default: - return SENSOR_CHAN_MAX; - } -} - int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel chan, int32_t reading, q31_t *out) { @@ -221,7 +199,7 @@ int icm42688_encode(const struct device *dev, const enum sensor_channel *const c } static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel channel, - size_t channel_idx, sensor_frame_iterator_t *fit, + size_t channel_idx, uint32_t *fit, uint16_t max_count, void *data_out) { const struct icm42688_encoded_data *edata = (const struct icm42688_encoded_data *)buffer; @@ -340,7 +318,7 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel c } static int icm42688_decoder_decode(const uint8_t *buffer, enum sensor_channel channel, - size_t channel_idx, sensor_frame_iterator_t *fit, + size_t channel_idx, uint32_t *fit, uint16_t max_count, void *data_out) { return icm42688_one_shot_decode(buffer, channel, channel_idx, fit, max_count, data_out); From 80ed7afab225598831e40c6c82333e324754638b Mon Sep 17 00:00:00 2001 From: Tristan Honscheid Date: Wed, 23 Aug 2023 11:10:01 -0600 Subject: [PATCH 0948/4498] sensors: akm09918c: Add RTIO one-shot implementation Implement the RTIO/Sensors V2/Async API for the AKM09918C. Add a decoder API implementation as well. Signed-off-by: Tristan Honscheid --- drivers/sensor/akm09918c/CMakeLists.txt | 3 +- drivers/sensor/akm09918c/akm09918c.c | 46 +++++++--- drivers/sensor/akm09918c/akm09918c.h | 21 +++++ drivers/sensor/akm09918c/akm09918c_async.c | 42 +++++++++ drivers/sensor/akm09918c/akm09918c_decoder.c | 96 ++++++++++++++++++++ 5 files changed, 196 insertions(+), 12 deletions(-) create mode 100644 drivers/sensor/akm09918c/akm09918c_async.c create mode 100644 drivers/sensor/akm09918c/akm09918c_decoder.c diff --git a/drivers/sensor/akm09918c/CMakeLists.txt b/drivers/sensor/akm09918c/CMakeLists.txt index 356b78dc8eb..7bfe5c3187f 100644 --- a/drivers/sensor/akm09918c/CMakeLists.txt +++ b/drivers/sensor/akm09918c/CMakeLists.txt @@ -4,5 +4,6 @@ zephyr_library() zephyr_library_sources(akm09918c.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_AKM09918C akm09918c_emul.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_AKM09918C akm09918c_emul.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API akm09918c_async.c akm09918c_decoder.c) zephyr_include_directories_ifdef(CONFIG_EMUL_AKM09918C .) diff --git a/drivers/sensor/akm09918c/akm09918c.c b/drivers/sensor/akm09918c/akm09918c.c index 1225d69a3d2..50664bcdbc5 100644 --- a/drivers/sensor/akm09918c/akm09918c.c +++ b/drivers/sensor/akm09918c/akm09918c.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,18 @@ LOG_MODULE_REGISTER(AKM09918C, CONFIG_SENSOR_LOG_LEVEL); -static int akm09918c_sample_fetch(const struct device *dev, enum sensor_channel chan) +/** + * @brief Perform the bus transaction to fetch samples + * + * @param dev Sensor device to operate on + * @param chan Channel ID to fetch + * @param x Location to write X channel sample. + * @param y Location to write Y channel sample. + * @param z Location to write Z channel sample. + * @return int 0 if successful or error code + */ +int akm09918c_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, int16_t *x, + int16_t *y, int16_t *z) { struct akm09918c_data *data = dev->data; const struct akm09918c_config *cfg = dev->config; @@ -54,13 +66,21 @@ static int akm09918c_sample_fetch(const struct device *dev, enum sensor_channel return -EBUSY; } - data->x_sample = sys_le16_to_cpu(buf[1] | (buf[2] << 8)); - data->y_sample = sys_le16_to_cpu(buf[3] | (buf[4] << 8)); - data->z_sample = sys_le16_to_cpu(buf[5] | (buf[6] << 8)); + *x = sys_le16_to_cpu(buf[1] | (buf[2] << 8)); + *y = sys_le16_to_cpu(buf[3] | (buf[4] << 8)); + *z = sys_le16_to_cpu(buf[5] | (buf[6] << 8)); return 0; } +static int akm09918c_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct akm09918c_data *data = dev->data; + + return akm09918c_sample_fetch_helper(dev, chan, &data->x_sample, &data->y_sample, + &data->z_sample); +} + static void akm09918c_convert(struct sensor_value *val, int16_t sample) { int64_t conv_val = sample * AKM09918C_MICRO_GAUSS_PER_BIT; @@ -149,13 +169,6 @@ static int akm09918c_attr_set(const struct device *dev, enum sensor_channel chan return 0; } -static const struct sensor_driver_api akm09918c_driver_api = { - .sample_fetch = akm09918c_sample_fetch, - .channel_get = akm09918c_channel_get, - .attr_get = akm09918c_attr_get, - .attr_set = akm09918c_attr_set, -}; - static inline int akm09918c_check_who_am_i(const struct i2c_dt_spec *i2c) { uint8_t buffer[2]; @@ -204,6 +217,17 @@ static int akm09918c_init(const struct device *dev) return 0; } +static const struct sensor_driver_api akm09918c_driver_api = { + .sample_fetch = akm09918c_sample_fetch, + .channel_get = akm09918c_channel_get, + .attr_get = akm09918c_attr_get, + .attr_set = akm09918c_attr_set, +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = akm09918c_submit, + .get_decoder = akm09918c_get_decoder, +#endif +}; + #define AKM09918C_DEFINE(inst) \ static struct akm09918c_data akm09918c_data_##inst; \ \ diff --git a/drivers/sensor/akm09918c/akm09918c.h b/drivers/sensor/akm09918c/akm09918c.h index 1745715287e..742c7d3be38 100644 --- a/drivers/sensor/akm09918c/akm09918c.h +++ b/drivers/sensor/akm09918c/akm09918c.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "akm09918c_reg.h" @@ -74,4 +75,24 @@ static inline void akm09918c_reg_to_hz(uint8_t reg, struct sensor_value *val) } } +/* + * RTIO types + */ + +struct akm09918c_decoder_header { + uint64_t timestamp; +} __attribute__((__packed__)); + +struct akm09918c_encoded_data { + struct akm09918c_decoder_header header; + int16_t readings[3]; +}; + +int akm09918c_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, int16_t *x, + int16_t *y, int16_t *z); + +int akm09918c_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); + +int akm09918c_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + #endif /* ZEPHYR_DRIVERS_SENSOR_AKM09918C_AKM09918C_H_ */ diff --git a/drivers/sensor/akm09918c/akm09918c_async.c b/drivers/sensor/akm09918c/akm09918c_async.c new file mode 100644 index 00000000000..438ca24780d --- /dev/null +++ b/drivers/sensor/akm09918c/akm09918c_async.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "akm09918c.h" + +LOG_MODULE_DECLARE(AKM09918C, CONFIG_SENSOR_LOG_LEVEL); + +int akm09918c_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + uint32_t min_buf_len = sizeof(struct akm09918c_encoded_data); + int rc; + uint8_t *buf; + uint32_t buf_len; + struct akm09918c_encoded_data *edata; + + /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */ + rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); + if (rc != 0) { + LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); + rtio_iodev_sqe_err(iodev_sqe, rc); + return rc; + } + + edata = (struct akm09918c_encoded_data *)buf; + edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + + rc = akm09918c_sample_fetch_helper(dev, SENSOR_CHAN_MAGN_XYZ, &edata->readings[0], + &edata->readings[1], &edata->readings[2]); + if (rc != 0) { + LOG_ERR("Failed to fetch samples"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return rc; + } + + rtio_iodev_sqe_ok(iodev_sqe, 0); + + return 0; +} diff --git a/drivers/sensor/akm09918c/akm09918c_decoder.c b/drivers/sensor/akm09918c/akm09918c_decoder.c new file mode 100644 index 00000000000..9bd6b312b7a --- /dev/null +++ b/drivers/sensor/akm09918c/akm09918c_decoder.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "akm09918c.h" + +static int akm09918c_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, uint16_t *frame_count) +{ + ARG_UNUSED(buffer); + ARG_UNUSED(channel); + ARG_UNUSED(channel_idx); + + /* This sensor lacks a FIFO; there will always only be one frame at a time. */ + *frame_count = 1; + return 0; +} + +static int akm09918c_decoder_get_size_info(enum sensor_channel channel, size_t *base_size, + size_t *frame_size) +{ + switch (channel) { + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + +/** Fixed shift value to use. All channels (MAGN_X, _Y, and _Z) have the same fixed range of + * +/- 49.12 Gauss. + */ +#define AKM09918C_SHIFT (6) + +static int akm09918c_convert_raw_to_q31(int16_t reading, q31_t *out) +{ + int64_t intermediate = ((int64_t)reading * AKM09918C_MICRO_GAUSS_PER_BIT) * + ((int64_t)INT32_MAX + 1) / + ((1 << AKM09918C_SHIFT) * INT64_C(1000000)); + + *out = CLAMP(intermediate, INT32_MIN, INT32_MAX); + return 0; +} + +static int akm09918c_decoder_decode(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, uint32_t *fit, + uint16_t max_count, void *data_out) +{ + const struct akm09918c_encoded_data *edata = (const struct akm09918c_encoded_data *)buffer; + + if (*fit != 0) { + return 0; + } + + switch (channel) { + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: { + struct sensor_three_axis_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + out->shift = AKM09918C_SHIFT; + + akm09918c_convert_raw_to_q31(edata->readings[0], &out->readings[0].x); + akm09918c_convert_raw_to_q31(edata->readings[1], &out->readings[0].y); + akm09918c_convert_raw_to_q31(edata->readings[2], &out->readings[0].z); + *fit = 1; + + return 1; + } + default: + return -EINVAL; + } +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = akm09918c_decoder_get_frame_count, + .get_size_info = akm09918c_decoder_get_size_info, + .decode = akm09918c_decoder_decode, +}; + +int akm09918c_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + + return 0; +} From 0bf220161b3e8741651100f6e9a21b5dcb92b69b Mon Sep 17 00:00:00 2001 From: Tristan Honscheid Date: Wed, 23 Aug 2023 11:11:12 -0600 Subject: [PATCH 0949/4498] test: Update generic sensor test to use new vertical decoder API Update the code in the generic test to work with the updated sensor decoder API that retrieves data vertically by channel. Signed-off-by: Tristan Honscheid --- .../build_all/sensor/src/generic_test.c | 85 +++++++++++++++---- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/tests/drivers/build_all/sensor/src/generic_test.c b/tests/drivers/build_all/sensor/src/generic_test.c index 53c79820c90..256a16cf3c6 100644 --- a/tests/drivers/build_all/sensor/src/generic_test.c +++ b/tests/drivers/build_all/sensor/src/generic_test.c @@ -8,12 +8,24 @@ #include #include #include +#include #include #include #include LOG_MODULE_REGISTER(generic_test); +/** + * A union of all sensor data types. + */ +union sensor_data_union { + struct sensor_three_axis_data three_axis; + struct sensor_occurrence_data occurrence; + struct sensor_q31_data q31; + struct sensor_byte_data byte; + struct sensor_uint64_data uint64; +}; + /* * Set up an RTIO context that can be shared for all sensors */ @@ -176,36 +188,72 @@ static void run_generic_test(const struct device *dev) /* Release the CQE */ rtio_cqe_release(&sensor_read_rtio_ctx, cqe); - enum sensor_channel channel; - sensor_frame_iterator_t fit = {0}; - sensor_channel_iterator_t cit = {0}; const struct sensor_decoder_api *decoder; - int8_t shift; - q31_t q; + union sensor_data_union decoded_data; zassert_ok(sensor_get_decoder(dev, &decoder)); - /* Decode the buffer and verify all channels */ - while (decoder->decode(buf, &fit, &cit, &channel, &q, 1) > 0) { - zassert_true(channel_table[channel].supported); - zassert_false(channel_table[channel].received); - channel_table[channel].received = true; + /* Loop through each channel */ + for (int ch = 0; ch < ARRAY_SIZE(channel_table); ch++) { + if (!channel_table[ch].supported) { + continue; + } - zassert_ok(decoder->get_shift(buf, channel, &shift)); + struct sensor_decode_context ctx = + SENSOR_DECODE_CONTEXT_INIT(decoder, buf, ch, 0); + + rv = sensor_decode(&ctx, &decoded_data, 1); + zassert_equal(1, rv, "Could not decode (error %d, ch %d, iteration %d/%d)", + rv, ch, iteration + 1, + CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS); + + channel_table[ch].received = true; + + /* Retrieve the actual value */ + q31_t q; + int8_t shift; + + switch (ch) { + /* Special handling to break out triplet samples. */ + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_GYRO_X: + q = decoded_data.three_axis.readings[0].x; + shift = decoded_data.three_axis.shift; + break; + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_GYRO_Y: + q = decoded_data.three_axis.readings[0].y; + shift = decoded_data.three_axis.shift; + break; + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_GYRO_Z: + q = decoded_data.three_axis.readings[0].z; + shift = decoded_data.three_axis.shift; + break; + + /* Default case for single Q31 samples */ + default: + q = decoded_data.q31.readings[0].value; + shift = decoded_data.q31.shift; + break; + } /* Align everything to be a 64-bit Q32.32 number for comparison */ int64_t expected_shifted = - (int64_t)channel_table[channel].expected_values[iteration] - << channel_table[channel].expected_value_shift; + (int64_t)channel_table[ch].expected_values[iteration] + << channel_table[ch].expected_value_shift; int64_t actual_shifted = (int64_t)q << shift; - int64_t epsilon_shifted = (int64_t)channel_table[channel].epsilon - << channel_table[channel].expected_value_shift; + int64_t epsilon_shifted = (int64_t)channel_table[ch].epsilon + << channel_table[ch].expected_value_shift; zassert_within(expected_shifted, actual_shifted, epsilon_shifted, "Expected %lld, got %lld (shift %d, ch %d, iteration %d/%d, " "Error %lld, Epsilon %lld)", - expected_shifted, actual_shifted, shift, channel, - iteration + 1, CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS, + expected_shifted, actual_shifted, shift, ch, iteration + 1, + CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS, expected_shifted - actual_shifted, epsilon_shifted); } @@ -221,7 +269,8 @@ static void run_generic_test(const struct device *dev) } } - zassert_equal(0, missing_channel_count); + zassert_equal(0, missing_channel_count, "%d channel(s) not received", + missing_channel_count); } } From 049aaac696e8ba028ff0100633c874b816c8fae7 Mon Sep 17 00:00:00 2001 From: Sri Surya Date: Fri, 4 Aug 2023 21:51:53 +0530 Subject: [PATCH 0950/4498] drivers: rtc: new ambiq am1805 rtc driver Added RTC driver for am1805 with rtc time, alarm set/get, callback and calibration. Signed-off-by: Sri Surya --- drivers/rtc/CMakeLists.txt | 1 + drivers/rtc/Kconfig | 1 + drivers/rtc/Kconfig.am1805 | 27 ++ drivers/rtc/rtc_am1805.c | 599 +++++++++++++++++++++++++++++ dts/bindings/rtc/ambiq,am1805.yaml | 20 + 5 files changed, 648 insertions(+) create mode 100644 drivers/rtc/Kconfig.am1805 create mode 100644 drivers/rtc/rtc_am1805.c create mode 100644 dts/bindings/rtc/ambiq,am1805.yaml diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index a770523f33b..94cda7627c4 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/rtc.h) zephyr_library() +zephyr_library_sources_ifdef(CONFIG_RTC_AM1805 rtc_am1805.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE rtc_handlers.c) zephyr_library_sources_ifdef(CONFIG_RTC_EMUL rtc_emul.c) zephyr_library_sources_ifdef(CONFIG_RTC_PCF8523 rtc_pcf8523.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8df08f38009..97cc21fef0e 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -41,6 +41,7 @@ config RTC_SHELL help RTC Shell commands +source "drivers/rtc/Kconfig.am1805" source "drivers/rtc/Kconfig.emul" source "drivers/rtc/Kconfig.fake" source "drivers/rtc/Kconfig.pcf8523" diff --git a/drivers/rtc/Kconfig.am1805 b/drivers/rtc/Kconfig.am1805 new file mode 100644 index 00000000000..4c7319ebd0b --- /dev/null +++ b/drivers/rtc/Kconfig.am1805 @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Linumiz +# Author: Sri Surya + +config RTC_AM1805 + bool "AMBIQ AM1805 RTC driver" + default y + depends on DT_HAS_AMBIQ_AM1805_ENABLED + select I2C + help + Enable the AMBIQ AM1805 RTC driver. + +if RTC_AM1805 + +config RTC_AM1805_THREAD_STACK_SIZE + int "Stack size for the am1805 interrupt thread" + default 512 + help + Size of the stack used for the thread handling interrupts and dispatching callbacks. + +config RTC_AM1805_THREAD_PRIO + int "Priority for the am1805 interrupt thread" + default 0 + help + Priority level for the thread handling interrupts and dispatching callbacks. + +endif diff --git a/drivers/rtc/rtc_am1805.c b/drivers/rtc/rtc_am1805.c new file mode 100644 index 00000000000..b6282d0f8ae --- /dev/null +++ b/drivers/rtc/rtc_am1805.c @@ -0,0 +1,599 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Linumiz + * Author: Sri Surya + */ + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT ambiq_am1805 + +LOG_MODULE_REGISTER(am1805, CONFIG_RTC_LOG_LEVEL); + +#define AM1805_IDENTITY_CODE 0x69 + +/* AM1805 register address */ +#define REG_HUNDREDS_ADDR 0x00 +#define REG_SECONDS_ADDR 0x01 +#define REG_MINUTES_ADDR 0x02 +#define REG_HOURS_ADDR 0x03 +#define REG_MDAY_ADDR 0x04 +#define REG_MONTH_ADDR 0x05 +#define REG_YEAR_ADDR 0x06 +#define REG_WDAY_ADDR 0x07 + +#define REG_ALM_HUNDREDS_ADDR 0x08 +#define REG_ALM_SECONDS_ADDR 0x09 +#define REG_ALM_MINUTES_ADDR 0x0A +#define REG_ALM_HOURS_ADDR 0x0B +#define REG_ALM_MDAY_ADDR 0x0C +#define REG_ALM_MONTH_ADDR 0x0D +#define REG_ALM_WDAY_ADDR 0x0E +#define REG_STATUS_ADDR 0x0F +#define REG_CONTROL1_ADDR 0x10 +#define REG_CONTROL2_ADDR 0x11 +#define REG_XT_CALIB_ADDR 0x14 +#define REG_TIMER_CTRL_ADDR 0x18 +#define REG_IRQ_MASK_ADDR 0x12 +#define REG_WATCHDOG_ADDR 0x1B +#define REG_OSC_STATUS_ADDR 0x1D + +/* AM1805 control bits */ +#define SECONDS_BITS GENMASK(6, 0) +#define MINUTES_BITS GENMASK(6, 0) +#define HOURS_BITS GENMASK(5, 0) +#define DATE_BITS GENMASK(5, 0) +#define MONTHS_BITS GENMASK(4, 0) +#define WEEKDAY_BITS GENMASK(2, 0) +#define YEAR_BITS GENMASK(7, 0) +#define REG_CONTROL2_OUT2S_BITS GENMASK(4, 2) +#define REG_TIMER_CTRL_RPT_BITS GENMASK(4, 2) +#define REG_XT_CALIB_OFF_MASK GENMASK(6, 0) + +#define REG_STATUS_ALM BIT(2) +#define REG_CONTROL1_STOP BIT(7) +#define REG_IRQ_MASK_AIE BIT(2) +#define REG_XT_CALIB_CMDX BIT(7) + +#define TIMER_CTRL_ALM_OFF 0x00 +#define TIMER_CTRL_ALM_DAY BIT(4) +#define TIMER_CTRL_ALM_YEAR BIT(2) +#define TIMER_CTRL_ALM_HR (BIT(2) | BIT(4)) +#define TIMER_CTRL_ALM_SEC GENMASK(4, 2) +#define TIMER_CTRL_ALM_MIN GENMASK(4, 3) +#define TIMER_CTRL_ALM_WEEK GENMASK(3, 2) + +#define REG_WATCHDOG_WDS BIT(7) +#define WRB_1_SECOND BIT(1) +#define WRB_4_SECONDS GENMASK(1, 0) + +#define REG_OSC_STATUS_ACAL_0 0x00 +#define REG_OSC_STATUS_ACAL_1 BIT(6) +#define REG_OSC_STATUS_ACAL_2 BIT(7) +#define REG_OSC_STATUS_ACAL_3 GENMASK(7, 6) +#define REG_OSC_STATUS_MASK BIT(1) +#define REG_STATUS_DEFAULT 0x00 + +#define AM1805_RTC_ALARM_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_WEEKDAY) + +#ifdef CONFIG_RTC_ALARM +/* am1805-gpios property must be in the devicetree inorder to use the RTC_ALARM */ +#if !DT_ANY_INST_HAS_PROP_STATUS_OKAY(am1805_gpios) +#error "am1805-gpios" - property not available in devicetree. +#endif +#endif + +struct am1805_config { + const struct i2c_dt_spec int_i2c; +#ifdef CONFIG_RTC_ALARM + struct gpio_dt_spec int_gpio; +#endif +}; + +struct am1805_data { + struct k_mutex lock; +#ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_user_callback; + void *alarm_user_data; + /* For gpio-interrupt */ + struct gpio_callback am1805_callback; + struct k_thread am1805_thread; + struct k_sem int_sem; + + K_KERNEL_STACK_MEMBER(am1805_stack, CONFIG_RTC_AM1805_THREAD_STACK_SIZE); +#endif +}; + +/* To set the timer registers */ +static int am1805_set_time(const struct device *dev, const struct rtc_time *tm) +{ + int err; + uint8_t regs[7]; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + k_mutex_lock(&data->lock, K_FOREVER); + + /* To unlock Stop-bit */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_CONTROL1_ADDR, + REG_CONTROL1_STOP, REG_CONTROL1_STOP); + if (err != 0) { + goto unlock; + } + + LOG_DBG("set time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + regs[0] = bin2bcd(tm->tm_sec) & SECONDS_BITS; + regs[1] = bin2bcd(tm->tm_min) & MINUTES_BITS; + regs[2] = bin2bcd(tm->tm_hour) & HOURS_BITS; + regs[3] = bin2bcd(tm->tm_mday) & DATE_BITS; + regs[4] = bin2bcd(tm->tm_mon) & MONTHS_BITS; + regs[5] = bin2bcd(tm->tm_year) & YEAR_BITS; + regs[6] = bin2bcd(tm->tm_wday) & WEEKDAY_BITS; + + err = i2c_burst_write_dt(&config->int_i2c, REG_SECONDS_ADDR, regs, sizeof(regs)); + if (err != 0) { + goto unlock; + } + + /* To lock Stop-bit */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_CONTROL1_ADDR, REG_CONTROL1_STOP, 0); + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} + +/* To get from the timer registers */ +static int am1805_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + int err; + uint8_t ctl_reg; + uint8_t regs[7]; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + k_mutex_lock(&data->lock, K_FOREVER); + + err = i2c_reg_read_byte_dt(&config->int_i2c, REG_CONTROL1_ADDR, &ctl_reg); + if (err != 0) { + goto unlock; + } + + err = ctl_reg & REG_CONTROL1_STOP; + if (err != 0) { + LOG_WRN("No control to get time now!!"); + goto unlock; + } + + err = i2c_burst_read_dt(&config->int_i2c, REG_SECONDS_ADDR, regs, sizeof(regs)); + if (err != 0) { + goto unlock; + } + + timeptr->tm_sec = bcd2bin(regs[0] & SECONDS_BITS); + timeptr->tm_min = bcd2bin(regs[1] & MINUTES_BITS); + timeptr->tm_hour = bcd2bin(regs[2] & HOURS_BITS); + timeptr->tm_mday = bcd2bin(regs[3] & DATE_BITS); + timeptr->tm_mon = bcd2bin(regs[4] & MONTHS_BITS); + timeptr->tm_year = bcd2bin(regs[5] & YEAR_BITS); + timeptr->tm_wday = bcd2bin(regs[6] & WEEKDAY_BITS); + + LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} + +#ifdef CONFIG_RTC_CALIBRATION +/* To Calibrate the XT oscillator */ +static int am1805_set_calibration(const struct device *dev, int32_t xt_clock_adj) +{ + int err; + uint8_t xt_calib_value; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + uint8_t reg = REG_OSC_STATUS_MASK; + + if (xt_clock_adj < -320 || xt_clock_adj > 127) { + LOG_DBG("Cannot be calibrated adj = %d\n", xt_clock_adj); + return -EINVAL; + } else if (xt_clock_adj < -256) { + /* XTCAL=3 CMDX=1 OFFSETX=(adj+192)/2 */ + reg |= REG_OSC_STATUS_ACAL_3; + xt_calib_value = ((uint8_t)(xt_clock_adj + 192) >> 1); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + xt_calib_value |= REG_XT_CALIB_CMDX; + } else if (xt_clock_adj < -192) { + /* XTCAL=3 CMDX=0 OFFSETX=(adj+192) */ + reg |= REG_OSC_STATUS_ACAL_3; + xt_calib_value = (uint8_t)(xt_clock_adj + 192); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + } else if (xt_clock_adj < -128) { + /* XTCAL=2 CMDX=0 OFFSETX=(adj+128) */ + reg |= REG_OSC_STATUS_ACAL_2; + xt_calib_value = (uint8_t)(xt_clock_adj + 128); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + } else if (xt_clock_adj < -64) { + /* XTCAL=1 CMDX=0 OFFSETX=(adj+64) */ + reg |= REG_OSC_STATUS_ACAL_1; + xt_calib_value = (uint8_t)(xt_clock_adj + 64); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + } else if (xt_clock_adj < 64) { + /* XTCAL=0 CMDX=0 OFFSETX=(adj) */ + reg |= REG_OSC_STATUS_ACAL_0; + xt_calib_value = (uint8_t)(xt_clock_adj); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + } else if (xt_clock_adj < 128) { + /* XTCAL=0 CMDX=1 OFFSETX=(adj)/2 */ + reg |= REG_OSC_STATUS_ACAL_0; + xt_calib_value = ((uint8_t)(xt_clock_adj >> 1)); + xt_calib_value &= REG_XT_CALIB_OFF_MASK; + xt_calib_value |= REG_XT_CALIB_CMDX; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + err = i2c_reg_write_byte_dt(&config->int_i2c, REG_OSC_STATUS_ADDR, reg); + if (err != 0) { + LOG_DBG("fail to set oscillator status register\n"); + goto unlock; + } + + /* Calibration XT Register */ + reg = xt_calib_value; + err = i2c_reg_write_byte_dt(&config->int_i2c, REG_XT_CALIB_ADDR, reg); + if (err != 0) { + LOG_DBG("fail to set XT calibration register\n"); + } + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} + +static int am1805_get_calibration(const struct device *dev, int32_t *calib) +{ + int err; + bool cmdx; + uint8_t reg; + uint8_t xtcal; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + k_mutex_lock(&data->lock, K_FOREVER); + + err = i2c_reg_read_byte_dt(&config->int_i2c, REG_OSC_STATUS_ADDR, ®); + if (err != 0) { + goto unlock; + } + + /* First 2-bits (from MSB) */ + xtcal = reg >> 6; + + err = i2c_reg_read_byte_dt(&config->int_i2c, REG_XT_CALIB_ADDR, ®); + if (err != 0) { + goto unlock; + } + + *calib = reg; + /* First bit (from MSB) */ + cmdx = reg & BIT(7); + /* Set or Clear the bit-7 based on bit-6, to achieve the given range (in datasheet) */ + WRITE_BIT(reg, 7, (reg & BIT(6))); + WRITE_BIT(reg, 6, 0); + + LOG_DBG("XTCAL = %d, CMDX = %d, OFFSETX = %d\n", xtcal, cmdx, (int8_t) reg); + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} +#endif + +#ifdef CONFIG_RTC_ALARM +/* To get from the alarm registers */ +static int am1805_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + + int err; + uint8_t regs[6]; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + err = i2c_burst_read_dt(&config->int_i2c, REG_ALM_SECONDS_ADDR, regs, sizeof(regs)); + if (err != 0) { + goto unlock; + } + + timeptr->tm_sec = bcd2bin(regs[0] & SECONDS_BITS); + timeptr->tm_min = bcd2bin(regs[1] & MINUTES_BITS); + timeptr->tm_hour = bcd2bin(regs[2] & HOURS_BITS); + timeptr->tm_mday = bcd2bin(regs[3] & DATE_BITS); + timeptr->tm_mon = bcd2bin(regs[4] & MONTHS_BITS); + timeptr->tm_wday = bcd2bin(regs[5] & WEEKDAY_BITS); + + *mask = (AM1805_RTC_ALARM_TIME_MASK); + + LOG_DBG("get alarm: wday = %d, mon = %d, mday = %d, hour = %d, min = %d, sec = %d, " + "mask = 0x%04x", timeptr->tm_wday, timeptr->tm_mon, timeptr->tm_mday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, *mask); + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} + +static int am1805_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + int err; + uint8_t regs[6]; + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + if ((mask & ~(AM1805_RTC_ALARM_TIME_MASK)) != 0U) { + LOG_ERR("unsupported alarm field mask 0x%04x", mask); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + /* Disable timer control registers before the initialization */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_TIMER_CTRL_ADDR, + REG_TIMER_CTRL_RPT_BITS, 0); + if (err != 0) { + goto unlock; + } + + /* Clear the interrupt mask for alarm */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_IRQ_MASK_ADDR, + REG_IRQ_MASK_AIE, 0); + if (err != 0) { + goto unlock; + } + + /* Clear the status bit */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_STATUS_ADDR, + REG_STATUS_ALM, 0); + if (err != 0) { + goto unlock; + } + + /* When mask is 0 */ + if (mask == 0) { + LOG_DBG("The alarm is disabled"); + goto unlock; + } + + regs[0] = bin2bcd(timeptr->tm_sec) & SECONDS_BITS; + regs[1] = bin2bcd(timeptr->tm_min) & MINUTES_BITS; + regs[2] = bin2bcd(timeptr->tm_hour) & HOURS_BITS; + regs[3] = bin2bcd(timeptr->tm_mday) & DATE_BITS; + regs[4] = bin2bcd(timeptr->tm_mon) & MONTHS_BITS; + regs[5] = bin2bcd(timeptr->tm_wday) & WEEKDAY_BITS; + + LOG_DBG("set alarm: second = %d, min = %d, hour = %d, mday = %d, month = %d," + "wday = %d, mask = 0x%04x", + timeptr->tm_sec, timeptr->tm_min, timeptr->tm_hour, timeptr->tm_mday, + timeptr->tm_mon, timeptr->tm_wday, mask); + + err = i2c_burst_write_dt(&config->int_i2c, REG_ALM_SECONDS_ADDR, regs, sizeof(regs)); + if (err != 0) { + goto unlock; + } + + /* Enable irq timer after the initialization */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_IRQ_MASK_ADDR, + REG_IRQ_MASK_AIE, REG_IRQ_MASK_AIE); + if (err != 0) { + goto unlock; + } + + /* Enable timer after the initialization for the config of repetation */ + err = i2c_reg_update_byte_dt(&config->int_i2c, REG_TIMER_CTRL_ADDR, + TIMER_CTRL_ALM_SEC, TIMER_CTRL_ALM_SEC); + +unlock: + k_mutex_unlock(&data->lock); + + return err; +} + +static int am1805_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) +{ + ARG_UNUSED(dev); + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + *mask = AM1805_RTC_ALARM_TIME_MASK; + + return 0; +} + +static int am1805_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + + struct am1805_data *data = dev->data; + const struct am1805_config *config = dev->config; + + if (config->int_gpio.port == NULL) { + return -ENOTSUP; + } + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + /* Passing the callback function and userdata filled by the user */ + data->alarm_user_callback = callback; + data->alarm_user_data = user_data; + + k_mutex_unlock(&data->lock); + + return 0; +} + +static void am1805_interrupt_thread(const struct device *dev) +{ + struct am1805_data *data = dev->data; + + while (1) { + k_sem_take(&data->int_sem, K_FOREVER); + + if (data->alarm_user_callback == NULL) { + LOG_DBG("Interrupt received, But No Alarm-Callback Initilized!!\n"); + continue; + } + data->alarm_user_callback(dev, 0, data->alarm_user_data); + } +} + +static void am1805_gpio_callback_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ + struct am1805_data *data = CONTAINER_OF(cb, struct am1805_data, am1805_callback); + + ARG_UNUSED(port); + ARG_UNUSED(pins); + + k_sem_give(&data->int_sem); +} +#endif + +static int am1805_init(const struct device *dev) +{ + int err; + uint8_t reg; + + const struct am1805_config *config = dev->config; + struct am1805_data *data = dev->data; + + k_mutex_init(&data->lock); + + if (!i2c_is_ready_dt(&config->int_i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + err = i2c_reg_read_byte_dt(&config->int_i2c, REG_STATUS_ADDR, ®); + if (err != 0) { + LOG_ERR("failed to read the status register"); + return -ENODEV; + } + +#ifdef CONFIG_RTC_ALARM + k_tid_t tid; + + k_sem_init(&data->int_sem, 0, INT_MAX); + + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (err != 0) { + LOG_ERR("failed to configure GPIO (err %d)", err); + return -ENODEV; + } + + err = gpio_pin_interrupt_configure_dt(&config->int_gpio, + GPIO_INT_EDGE_TO_INACTIVE); + if (err != 0) { + LOG_ERR("failed to configure interrupt (err %d)", err); + return -ENODEV; + } + + gpio_init_callback(&data->am1805_callback, am1805_gpio_callback_handler, + BIT(config->int_gpio.pin)); + + err = gpio_add_callback_dt(&config->int_gpio, &data->am1805_callback); + if (err != 0) { + LOG_ERR("failed to add GPIO callback (err %d)", err); + return -ENODEV; + } + + tid = k_thread_create(&data->am1805_thread, data->am1805_stack, + K_THREAD_STACK_SIZEOF(data->am1805_stack), + (k_thread_entry_t)am1805_interrupt_thread, (void *)dev, NULL, + NULL, CONFIG_RTC_AM1805_THREAD_PRIO, 0, K_NO_WAIT); + k_thread_name_set(tid, dev->name); +#endif + return 0; +} + +static const struct rtc_driver_api am1805_driver_api = { + .set_time = am1805_set_time, + .get_time = am1805_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = am1805_alarm_get_supported_fields, + .alarm_set_time = am1805_alarm_set_time, + .alarm_get_time = am1805_alarm_get_time, + .alarm_set_callback = am1805_alarm_set_callback, +#endif +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = am1805_set_calibration, + .get_calibration = am1805_get_calibration, +#endif +}; + +#define AM1805_INIT(inst) \ +static const struct am1805_config am1805_config_##inst = { \ + .int_i2c = I2C_DT_SPEC_INST_GET(inst), \ + IF_ENABLED(CONFIG_RTC_ALARM, \ + (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, am1805_gpios, {0})))}; \ + \ +static struct am1805_data am1805_data_##inst; \ + \ +DEVICE_DT_INST_DEFINE(inst, &am1805_init, NULL, &am1805_data_##inst, \ + &am1805_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &am1805_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(AM1805_INIT) diff --git a/dts/bindings/rtc/ambiq,am1805.yaml b/dts/bindings/rtc/ambiq,am1805.yaml new file mode 100644 index 00000000000..be807778f2c --- /dev/null +++ b/dts/bindings/rtc/ambiq,am1805.yaml @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Linumiz +# Author: Sri Surya + +description: AMBIQ AM1805 RTC + +compatible: "ambiq,am1805" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml + +properties: + reg: + required: true + + am1805-gpios: + type: phandle-array + description: | + GPIO connected to the AM1805 INT1 interrupt output. This signal is open-drain, active low. From 0aaa5a9ac25ca8619e9bd6d63f2f7cb5ec813a99 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 8 Sep 2023 13:01:57 +0300 Subject: [PATCH 0951/4498] samples: webusb: Copy needed file from the external repository Copy file index.html from the external repository finikorg/webusb-sample. Signed-off-by: Andrei Emeltchenko --- doc/conf.py | 1 + samples/subsys/usb/webusb/index.html | 125 +++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 samples/subsys/usb/webusb/index.html diff --git a/doc/conf.py b/doc/conf.py index 05e4eb3d803..592e3d19def 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -284,6 +284,7 @@ (ZEPHYR_BASE / "doc", "[!_]*"), (ZEPHYR_BASE, "boards/**/*.rst"), (ZEPHYR_BASE, "boards/**/doc"), + (ZEPHYR_BASE, "samples/**/*.html"), (ZEPHYR_BASE, "samples/**/*.rst"), (ZEPHYR_BASE, "samples/**/doc"), (ZEPHYR_BASE, "snippets/**/*.rst"), diff --git a/samples/subsys/usb/webusb/index.html b/samples/subsys/usb/webusb/index.html new file mode 100644 index 00000000000..a8d3efb9f24 --- /dev/null +++ b/samples/subsys/usb/webusb/index.html @@ -0,0 +1,125 @@ + + + WebUSB Serial Sample Application + + + + + + +


+ +
+

+
+ + From 43c139a5f6635cc36146dbb30c92fec4fe478d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 7 Sep 2023 16:32:41 +0200 Subject: [PATCH 0952/4498] samples: webusb: Include demo.rst to documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include demo.rst to the webusb sample documentation. Signed-off-by: Benjamin Cabé --- samples/subsys/usb/webusb/README.rst | 2 ++ samples/subsys/usb/webusb/demo.rst | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 samples/subsys/usb/webusb/demo.rst diff --git a/samples/subsys/usb/webusb/README.rst b/samples/subsys/usb/webusb/README.rst index ac8ca57b698..b49182a667d 100644 --- a/samples/subsys/usb/webusb/README.rst +++ b/samples/subsys/usb/webusb/README.rst @@ -62,6 +62,8 @@ Follow these steps to run the demo on your host system: interface, as well as demonstrate the communication between browser and WebUSB enabled device. + see :doc:`demo` + #. To access JS app go to https://finikorg.github.io/webusb-sample/ #. To host the demo page locally: Clone the repo and start a web server diff --git a/samples/subsys/usb/webusb/demo.rst b/samples/subsys/usb/webusb/demo.rst new file mode 100644 index 00000000000..6925a802580 --- /dev/null +++ b/samples/subsys/usb/webusb/demo.rst @@ -0,0 +1,7 @@ +:orphan: + +WebUSB HTML Demo App +==================== + +.. raw:: html + :file: index.html From 17fcf58a5ebeb4a450292c19e7bc9c4e06e9b914 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 8 Sep 2023 11:35:19 +0300 Subject: [PATCH 0953/4498] doc: samples: usb: Include only README to TOC Include only README.rst to docs, skipping helpers included with :doc: directive. Signed-off-by: Andrei Emeltchenko --- samples/subsys/usb/usb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/usb/usb.rst b/samples/subsys/usb/usb.rst index 90b1c783b4c..5da80b0e219 100644 --- a/samples/subsys/usb/usb.rst +++ b/samples/subsys/usb/usb.rst @@ -7,4 +7,4 @@ USB device support samples :maxdepth: 1 :glob: - **/* + **/README From 5942343a81e25eca427f2d32d692f75f5ba8221b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 8 Sep 2023 13:43:40 +0300 Subject: [PATCH 0954/4498] samples: webusb: Update README Update webusb README with recent changes after index.html was moved to sample from the external repository. Signed-off-by: Andrei Emeltchenko --- samples/subsys/usb/webusb/README.rst | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/samples/subsys/usb/webusb/README.rst b/samples/subsys/usb/webusb/README.rst index b49182a667d..228bf822d80 100644 --- a/samples/subsys/usb/webusb/README.rst +++ b/samples/subsys/usb/webusb/README.rst @@ -14,7 +14,7 @@ Overview ******** This simple echo application demonstrates the WebUSB sample application. -This application receives the data and echoed back to the WebUSB +This application receives the data and echoes back to the WebUSB based web application (web page) running in the browser at host. This application is intended for testing purposes only. For running real usecase, implement applications based on the WebUSB API. @@ -38,15 +38,15 @@ Build and flash webusb sample with: :goals: flash :compact: -Testing with latest Google Chrome on host -***************************************** +Testing with the latest Google Chrome on host +********************************************* -This sample application requires latest Google Chrome, a web page +This sample application requires the latest Google Chrome, a web page based on WebUSB API to connect to the USB device and optionally http server running on localhost to serve the web page. WebUSB is a powerful new feature added to the Web and it is available -only to secure origins. This means the web page/site that used to +only to secure origins. This means the web page/site that is used to connect to the device must be served over a secure connection (HTTPS). Follow these steps to run the demo on your host system: @@ -56,22 +56,25 @@ Follow these steps to run the demo on your host system: #. Implement a web app (web page) using WebUSB API and run it on localhost. - See the sample at https://github.com/finikorg/webusb-sample + The sample can be found in the webusb sample directory: + :zephyr_file:`samples/subsys/usb/webusb/index.html`. - This sample web page demonstrate how to create and use a WebUSB + This sample web page demonstrates how to create and use a WebUSB interface, as well as demonstrate the communication between browser and WebUSB enabled device. - see :doc:`demo` + There are two ways to access this sample page: - #. To access JS app go to https://finikorg.github.io/webusb-sample/ + * Using Chrome browser go to :doc:`demo` - #. To host the demo page locally: Clone the repo and start a web server - in the appropriate directory. + * Host the demo page locally: Start a web server + in the webusb sample directory. - .. code-block:: console + .. code-block:: console - $ python -m http.server + $ python -m http.server + + Using Chrome browser open url http://localhost:8001/ #. Connect the board to your host. @@ -81,7 +84,8 @@ Follow these steps to run the demo on your host system: Note that at the moment WebUSB landing page notification is disabled in Chrome on Windows. See https://github.com/WICG/webusb#implementation-status -#. Click on Connect button to connect to the device. +#. Click on the :guilabel:`Connect` button to connect to the device. -#. Send some text to the device by clicking on the Send button. The demo app - will receive the same text from the device and display it in the textarea. +#. Send some text to the device by clicking on the :guilabel:`Send` button. + The demo app will receive the same text from the device and display it in + the text area. From c702b03abd99b6fbcd2fe46d68491e81d3aca080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 14 Sep 2023 17:39:04 +0200 Subject: [PATCH 0955/4498] samples: webusb: Fix HTML validator issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running the HTML code through W3C Validator revealed several issues with the markup that this commit fixes. Signed-off-by: Benjamin Cabé --- samples/subsys/usb/webusb/index.html | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/samples/subsys/usb/webusb/index.html b/samples/subsys/usb/webusb/index.html index a8d3efb9f24..b6cfc96d447 100644 --- a/samples/subsys/usb/webusb/index.html +++ b/samples/subsys/usb/webusb/index.html @@ -1,9 +1,9 @@ - + + WebUSB Serial Sample Application - -


- +


+


-
- +
+ + From 8940343eadef26d3220142ac6bd72d27c82b7633 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 16 Sep 2023 15:34:31 +1000 Subject: [PATCH 0956/4498] net: wifi_mgmt: avoid declaring zero length array Zero length arrays are a GNUism not supported by all compilers. If `zephyr/net/wifi_mgmt.h` is included by an application without WiFi enabled, ensure array is at least one element long. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_mgmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ee94ca58559..f22e15101fb 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -38,7 +38,7 @@ extern "C" { #ifdef CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX #define WIFI_MGMT_SCAN_SSID_FILT_MAX CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX #else -#define WIFI_MGMT_SCAN_SSID_FILT_MAX 0 +#define WIFI_MGMT_SCAN_SSID_FILT_MAX 1 #endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ #define WIFI_MGMT_BAND_STR_SIZE_MAX 8 From 6a428f19b66b9603205b29b300557c14f77a0bc0 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 16 Sep 2023 15:47:17 +1000 Subject: [PATCH 0957/4498] net: wifi_mgmt: make number of scan channels configurable Make the maximum number of channels that can be manually scanned configurable by the application. The previous value of 233 was vastly overallocating memory as the largest band only contains 60 allocated channels. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_mgmt.h | 8 +++++++- subsys/net/l2/wifi/Kconfig | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index f22e15101fb..8e3373279da 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -41,6 +41,12 @@ extern "C" { #define WIFI_MGMT_SCAN_SSID_FILT_MAX 1 #endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ +#ifdef CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL +#define WIFI_MGMT_SCAN_CHAN_MAX_MANUAL CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL +#else +#define WIFI_MGMT_SCAN_CHAN_MAX_MANUAL 1 +#endif /* CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL */ + #define WIFI_MGMT_BAND_STR_SIZE_MAX 8 /** Wi-Fi management commands */ @@ -252,7 +258,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; + uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index ccf5ce31ca6..5644852c2a0 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -47,6 +47,14 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. +config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL + int "Maximum number of channels that can be manually specified per-band" + range 1 70 + default 3 + help + There are currently 60 channels allocated in the largest band (6GHz). + The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. + config WIFI_NM bool "Wi-Fi Network manager support" help From b54951b86e440e92dcdd41598d38f67987ce3cf2 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 16 Sep 2023 15:54:28 +1000 Subject: [PATCH 0958/4498] net: wifi_mgmt: linearise `scan_params->chan` arrays Turn the nested arrays of `scan_params->chan` into a single array. This adds the requirement to specify the band for each channel, but eliminates the large amount of dead memory for unused bands. Overall, this saves 50% of the RAM space for this variable. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_mgmt.h | 18 ++++++++++++++---- include/zephyr/net/wifi_utils.h | 4 +++- subsys/net/l2/wifi/Kconfig | 6 +++--- subsys/net/l2/wifi/wifi_shell.c | 4 +++- subsys/net/l2/wifi/wifi_utils.c | 32 ++++++++++++++++++++++++-------- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8e3373279da..ce7b720197b 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -209,6 +209,16 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) +/** + * @brief Wi-Fi structure to uniquely identify a band-channel pair + */ +struct wifi_band_channel { + /** Frequency band */ + uint8_t band; + /** Channel */ + uint8_t channel; +}; + /** * @brief Wi-Fi scan parameters structure. * Used to specify parameters which can control how the Wi-Fi scan @@ -248,9 +258,9 @@ struct wifi_scan_params { * band. * E.g. to scan channel 6 and 11 on the 2.4 GHz band, channel 36 on the 5 GHz band: * @code{.c} - * chan[WIFI_FREQ_BAND_2_4_GHZ][0] = 6; - * chan[WIFI_FREQ_BAND_2_4_GHZ][1] = 11; - * chan[WIFI_FREQ_BAND_5_GHZ][0] = 36; + * chan[0] = {WIFI_FREQ_BAND_2_4_GHZ, 6}; + * chan[1] = {WIFI_FREQ_BAND_2_4_GHZ, 11}; + * chan[2] = {WIFI_FREQ_BAND_5_GHZ, 36}; * @endcode * * This list specifies the channels to be __considered for scan__. The underlying @@ -258,7 +268,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; + struct wifi_band_channel band_chan[WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index b005d075847..4284138b6f3 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -95,12 +95,14 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, * * @param scan_chan_str List of channels expressed in the format described above. * @param chan Pointer to an array where the parsed channels are to be stored. + * @param max_channels Maximum number of channels to store * * @retval 0 on success. * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint8_t chan[][WIFI_CHANNEL_MAX]); + struct wifi_band_channel *chan, + uint8_t max_channels); /** * @} diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 5644852c2a0..8fbd6aff4d6 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -48,11 +48,11 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX This can be set based on the underlying chipsets limitations. config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL - int "Maximum number of channels that can be manually specified per-band" - range 1 70 + int "Maximum number of channels that can be manually specified" + range 1 110 default 3 help - There are currently 60 channels allocated in the largest band (6GHz). + There are approximately 100 channels allocated across the three supported bands. The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. config WIFI_NM diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 74284e56e98..e2ff20a105d 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -774,7 +774,9 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'c': - if (wifi_utils_parse_scan_chan(optarg, params->chan)) { + if (wifi_utils_parse_scan_chan(optarg, + params->band_chan, + ARRAY_SIZE(params->band_chan))) { shell_fprintf(sh, SHELL_ERROR, "Invalid band or channel value(s)\n"); diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index a77e225bfbf..4c50b817d26 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -105,7 +105,7 @@ static bool wifi_utils_validate_chan(uint8_t band, static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, uint8_t chan_end, - uint8_t chan[][WIFI_CHANNEL_MAX], + struct wifi_band_channel *band_chan, uint8_t band_idx, uint8_t *chan_idx) { @@ -136,7 +136,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, idx = *chan_idx; for (i = chan_start; i <= chan_end; i++) { - chan[band_idx][idx++] = i; + band_chan[idx].band = band_idx; + band_chan[idx].channel = i; + idx++; } *chan_idx = idx; @@ -155,7 +157,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, } if (start) { - chan[band_idx][idx++] = valid_5g_chans_20mhz[i]; + band_chan[idx].band = band_idx; + band_chan[idx].channel = valid_5g_chans_20mhz[i]; + idx++; } if (end) { @@ -171,7 +175,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, i = chan_start; while (i <= chan_end) { - chan[band_idx][idx++] = i; + band_chan[idx].band = band_idx; + band_chan[idx].channel = i; + idx++; if (i == 1) { i++; @@ -310,7 +316,8 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint8_t chan[][WIFI_CHANNEL_MAX]) + struct wifi_band_channel *band_chan, + uint8_t max_channels) { char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; @@ -349,7 +356,6 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, } i++; - chan_idx = 0; chan_str_start_idx = i; valid_band = true; @@ -383,9 +389,13 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, memset(chan_str, 0, sizeof(chan_str)); if (chan_start) { + if ((chan_idx + (chan_val - chan_start)) >= max_channels) { + NET_ERR("Too many channels specified (%d)", max_channels); + return -EINVAL; + } if (wifi_utils_get_all_chans_in_range(chan_start, chan_val, - chan, + band_chan, band, &chan_idx)) { NET_ERR("Channel range invalid"); @@ -399,8 +409,14 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, NET_ERR("Invalid channel %d", chan_val); return -EINVAL; } + if (chan_idx == max_channels) { + NET_ERR("Too many channels specified (%d)", max_channels); + return -EINVAL; + } - chan[band][chan_idx++] = chan_val; + band_chan[chan_idx].band = band; + band_chan[chan_idx].channel = chan_val; + chan_idx++; } valid_chan = true; From e51ac69156368008fca17cad0212ec4f4e954b15 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Sep 2023 13:12:19 +0200 Subject: [PATCH 0959/4498] Bluetooth: Audio: Add bt_audio_codec_cap_get helper functions Add helper function to get specific values from a codec capability struct. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 95 ++++++++++++++- include/zephyr/bluetooth/audio/lc3.h | 17 +++ subsys/bluetooth/audio/codec.c | 160 +++++++++++++++++++++++++ 3 files changed, 266 insertions(+), 6 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 943681189bc..9e05e4e4682 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -651,12 +651,7 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default); -/** @brief Lookup a specific codec configuration value based on type - * * - * Typically types used are: - * @ref bt_audio_codec_capability_type - * @ref bt_audio_codec_config_type - * @ref bt_audio_metadata_type +/** @brief Lookup a specific codec configuration value * * @param[in] codec_cfg The codec data to search in. * @param[in] type The type id to look for @@ -853,6 +848,94 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta); /** @} */ /* End of bt_audio_codec_meta */ + +/** + * @brief Audio codec capabilities APIs + * @defgroup bt_audio_codec_cap Codec capability parsing APIs + * + * Functions to parse codec capability data when formatted as LTV wrapped into @ref + * bt_audio_codec_cap. + * + * @{ + */ + +/** + * @brief Lookup a specific value based on type + * + * @param[in] codec_cap The codec data to search in. + * @param[in] type The type id to look for + * @param[out] data Pointer to the data-pointer to update when item is found + * + * @return Length of found @p data or 0 if not found + */ +uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, + const uint8_t **data); + +/** + * @brief Extract the frequency from a codec capability. + * + * @param codec_cap The codec configuration to extract data from. + * + * @retval Bitfield of supported frequencies if 0 or positive + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value + */ +int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap); + +/** + * @brief Extract the frequency from a codec capability. + * + * @param codec_cap The codec configuration to extract data from. + * + * @retval Bitfield of supported frame durations if 0 or positive + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value + */ +int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap); + +/** + * @brief Extract the frequency from a codec capability. + * + * @param codec_cap The codec configuration to extract data from. + * + * @retval Bitfield of supported channel counts if 0 or positive + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value + */ +int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap); + +/** + * @brief Extract the frequency from a codec capability. + * + * @param[in] codec_cap The codec configuration to extract data from. + * @param[out] codec_frame Struct to place the resulting values in + * + * @retval 0 on success + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value + */ +int bt_audio_codec_cap_get_octets_per_frame( + const struct bt_audio_codec_cap *codec_cap, + struct bt_audio_codec_octets_per_codec_frame *codec_frame); + +/** + * @brief Extract the frequency from a codec capability. + * + * @param codec_cap The codec configuration to extract data from. + * + * @retval Maximum number of codec frames per SDU supported + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value + */ +int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap); + +/** @} */ /* End of bt_audio_codec_cap */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index caac8aebc33..198f8185b13 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -26,6 +26,11 @@ extern "C" { #endif +/** + * @brief LC3 codec ID + */ +#define BT_HCI_CODING_FORMAT_LC3 0x06 + /** * @brief Codec capability type id's * @@ -145,6 +150,18 @@ enum bt_audio_codec_capability_type { #define BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(...) \ ((uint8_t)((FOR_EACH(BIT, (|), __VA_ARGS__)) >> 1)) +struct BT_AUDIO_CODEC_LC3_frame_len { + uint16_t min; + uint16_t max; +}; + +struct bt_audio_codec_octets_per_codec_frame { + /** Minimum number of octets supported per codec frame */ + uint16_t min; + /** Maximum number of octets supported per codec frame */ + uint16_t max; +}; + /** * @brief Codec configuration type IDs * diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index adf5ad2884f..e3d8ca1c2a7 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -545,3 +545,163 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ */ + +#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 + +uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, + const uint8_t **data) +{ + struct search_type_param param = { + .type = type, + .data_len = 0, + .data = data, + }; + int err; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return 0; + } + + CHECKIF(data == NULL) { + LOG_DBG("data is NULL"); + return 0; + } + + *data = NULL; + + err = bt_audio_data_parse(codec_cap->data, codec_cap->data_len, parse_cb, ¶m); + if (err != 0 && err != -ECANCELED) { + LOG_DBG("Could not parse the data: %d", err); + return 0; + } + + if (param.data == NULL) { + LOG_DBG("Could not find the type %u", type); + return 0; + } + + return param.data_len; +} + +int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap) +{ + const uint8_t *data; + uint8_t data_len; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FREQ, &data); + if (data == NULL) { + return -ENODATA; + } + + if (data_len != sizeof(uint16_t)) { + return -EBADMSG; + } + + return sys_get_le16(data); +} + +int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap) +{ + const uint8_t *data; + uint8_t data_len; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_DURATION, &data); + if (data == NULL) { + return -ENODATA; + } + + if (data_len != sizeof(uint8_t)) { + return -EBADMSG; + } + + return data[0]; +} + +int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap) +{ + const uint8_t *data; + uint8_t data_len; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_CHAN_COUNT, &data); + if (data == NULL) { + return -ENODATA; + } + + if (data_len != sizeof(uint8_t)) { + return -EBADMSG; + } + + return data[0]; +} + +int bt_audio_codec_cap_get_octets_per_frame( + const struct bt_audio_codec_cap *codec_cap, + struct bt_audio_codec_octets_per_codec_frame *codec_frame) +{ + const uint8_t *data; + uint8_t data_len; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + CHECKIF(codec_frame == NULL) { + LOG_DBG("codec_frame is NULL"); + return -EINVAL; + } + + data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_LEN, &data); + if (data == NULL) { + return -ENODATA; + } + + if (data_len != sizeof(uint32_t)) { + return -EBADMSG; + } + + codec_frame->min = sys_get_le16(data); + codec_frame->max = sys_get_le16(data + sizeof(codec_frame->min)); + + return 0; +} + +int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap) +{ + const uint8_t *data; + uint8_t data_len; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_COUNT, &data); + if (data == NULL) { + return -ENODATA; + } + + if (data_len != sizeof(uint8_t)) { + return -EBADMSG; + } + + return data[0]; +} + +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */ From 63badb0fa7861f4fd17e78c11c66d0d734941638 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Sep 2023 13:13:06 +0200 Subject: [PATCH 0960/4498] tests: Bluetooth: Audio: bt_audio_codec_cap_get unit tests Add unit tests for the bt_audio_codec_cap_get* functions. Signed-off-by: Emil Gydesen --- tests/bluetooth/audio/codec/src/main.c | 74 ++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index e4727dfec78..5ad50c1c0c6 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -218,3 +218,77 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_vendor) zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_freq) +{ + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_freq(&codec_cap); + zassert_equal(ret, 4, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_frame_duration) +{ + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_frame_duration(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_supported_audio_chan_counts) +{ + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(2), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_supported_audio_chan_counts(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_octets_per_frame) +{ + struct bt_audio_codec_octets_per_codec_frame expected = { + .min = 40U, + .max = 120U, + }; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + struct bt_audio_codec_octets_per_codec_frame codec_frame; + + int ret; + + ret = bt_audio_codec_cap_get_octets_per_frame(&codec_cap, &codec_frame); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_equal(codec_frame.min, expected.min, "Unexpected minimum value %d", + codec_frame.min); + zassert_equal(codec_frame.max, expected.max, "Unexpected maximum value %d", + codec_frame.max); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_max_codec_frames_per_sdu) +{ + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} From dca9cbff0860563b63b2e514dd1689d861c706c0 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 18 Sep 2023 17:43:59 +0800 Subject: [PATCH 0961/4498] ITE: drivers/pinctrl: Add alternate function additional setting When the alternate setting is configured as func3, in addition to the setting of func3-gcr, some pins require external setting. Signed-off-by: Tim Lin --- drivers/pinctrl/pinctrl_ite_it8xxx2.c | 56 +++++++++++-------- .../pinctrl/ite,it8xxx2-pinctrl-func.yaml | 9 +++ dts/riscv/ite/it81xx2.dtsi | 4 ++ dts/riscv/ite/it8xxx2-pinctrl-map.dtsi | 6 ++ 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/drivers/pinctrl/pinctrl_ite_it8xxx2.c b/drivers/pinctrl/pinctrl_ite_it8xxx2.c index 3c8af74baf3..886a035483f 100644 --- a/drivers/pinctrl/pinctrl_ite_it8xxx2.c +++ b/drivers/pinctrl/pinctrl_ite_it8xxx2.c @@ -24,6 +24,10 @@ struct pinctrl_it8xxx2_gpio { uintptr_t func3_gcr[GPIO_GROUP_MEMBERS]; /* function 3 enable mask */ uint8_t func3_en_mask[GPIO_GROUP_MEMBERS]; + /* function 3 external control register */ + uintptr_t func3_ext[GPIO_GROUP_MEMBERS]; + /* function 3 external mask */ + uint8_t func3_ext_mask[GPIO_GROUP_MEMBERS]; /* function 4 general control register */ uintptr_t func4_gcr[GPIO_GROUP_MEMBERS]; /* function 4 enable mask */ @@ -132,6 +136,7 @@ static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins) volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin; volatile uint8_t *reg_func3_gcr = (uint8_t *)(gpio->func3_gcr[pin]); volatile uint8_t *reg_func4_gcr = (uint8_t *)(gpio->func4_gcr[pin]); + volatile uint8_t *reg_func3_ext = (uint8_t *)(gpio->func3_ext[pin]); /* Handle PIN configuration. */ if (pinctrl_it8xxx2_set(pins)) { @@ -155,6 +160,11 @@ static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins) /* Common settings for alternate function. */ *reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT | GPCR_PORT_PIN_MODE_OUTPUT); + /* Ensure that func3-ext setting is in default state. */ + if (reg_func3_ext != NULL) { + *reg_func3_ext &= ~gpio->func3_ext_mask[pin]; + } + switch (pins->alt_func) { case IT8XXX2_ALT_FUNC_1: /* Func1: Alternate function has been set above. */ @@ -169,6 +179,11 @@ static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins) * Func3 also need to set the general control. */ *reg_func3_gcr |= gpio->func3_en_mask[pin]; + + /* Func3-external: Some pins require external setting. */ + if (reg_func3_ext != NULL) { + *reg_func3_ext |= gpio->func3_ext_mask[pin]; + } break; case IT8XXX2_ALT_FUNC_4: /* @@ -327,11 +342,6 @@ static int pinctrl_it8xxx2_init(const struct device *dev) */ gpio_base->GPIO_GCR &= ~IT8XXX2_GPIO_LPCRSTEN; - /* - * TODO: If UART2 swaps from bit2:1 to bit6:5 in H group, we - * have to set UART1PSEL = 1 in UART1PMR register. - */ - #ifdef CONFIG_SOC_IT8XXX2_REG_SET_V2 /* * Swap the default I2C2 SMCLK2/SMDAT2 pins from GPC7/GPD0 to GPF6/GPF7, @@ -345,23 +355,25 @@ static int pinctrl_it8xxx2_init(const struct device *dev) return 0; } -#define INIT_UNION_CONFIG(inst) \ - COND_CODE_1(DT_INST_PROP(inst, gpio_group), \ - (.gpio = { \ - .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ - .func3_gcr = DT_INST_PROP(inst, func3_gcr), \ - .func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \ - .func4_gcr = DT_INST_PROP(inst, func4_gcr), \ - .func4_en_mask = DT_INST_PROP(inst, func4_en_mask), \ - .volt_sel = DT_INST_PROP(inst, volt_sel), \ - .volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask), \ - }), \ - (.ksi_kso = { \ - .reg_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ - .reg_ctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1), \ - .pp_od_mask = (uint8_t)DT_INST_PROP(inst, pp_od_mask), \ - .pullup_mask = (uint8_t)DT_INST_PROP(inst, pullup_mask), \ - }) \ +#define INIT_UNION_CONFIG(inst) \ + COND_CODE_1(DT_INST_PROP(inst, gpio_group), \ + (.gpio = { \ + .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .func3_gcr = DT_INST_PROP(inst, func3_gcr), \ + .func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \ + .func3_ext = DT_INST_PROP_OR(inst, func3_ext, {0}), \ + .func3_ext_mask = DT_INST_PROP_OR(inst, func3_ext_mask, {0}), \ + .func4_gcr = DT_INST_PROP(inst, func4_gcr), \ + .func4_en_mask = DT_INST_PROP(inst, func4_en_mask), \ + .volt_sel = DT_INST_PROP(inst, volt_sel), \ + .volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask), \ + }), \ + (.ksi_kso = { \ + .reg_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .reg_ctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1), \ + .pp_od_mask = (uint8_t)DT_INST_PROP(inst, pp_od_mask), \ + .pullup_mask = (uint8_t)DT_INST_PROP(inst, pullup_mask), \ + }) \ ) #define PINCTRL_ITE_INIT(inst) \ diff --git a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml index 21bdf2b6c5e..4fe47c5ba03 100644 --- a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml +++ b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml @@ -14,6 +14,15 @@ properties: func3-en-mask: type: array + func3-ext: + type: array + description: | + When the alternate setting is configured as func3, in addition to + the setting of func3-gcr, some pins require external setting. + + func3-ext-mask: + type: array + func4-gcr: type: array diff --git a/dts/riscv/ite/it81xx2.dtsi b/dts/riscv/ite/it81xx2.dtsi index b9e8ba4e69d..e8975c4c496 100644 --- a/dts/riscv/ite/it81xx2.dtsi +++ b/dts/riscv/ite/it81xx2.dtsi @@ -198,6 +198,10 @@ NO_FUNC 0xf016f5 0xf016f5 NO_FUNC>; func3-en-mask = <0 0x20 0x20 0 0 0x04 0x08 0 >; + func3-ext = ; + func3-ext-mask = <0 0 0 0 + 0 0x01 0x01 0 >; func4-gcr = ; func4-en-mask = <0 0x04 0x08 0 diff --git a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi index 6e4ab0e6fac..b553c4fee8a 100644 --- a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi +++ b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi @@ -383,6 +383,12 @@ uart2_tx_gph2_default: uart2_tx_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_4>; }; + uart2_rx_gph5_default: uart2_rx_gph5_default { + pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_FUNC_3>; + }; + uart2_tx_gph6_default: uart2_tx_gph6_default { + pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_FUNC_3>; + }; uart2_rx_gpf0_default: uart2_rx_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_3>; }; From baeda6ada053e0ca2cf5fdacb1fec4cb5c929129 Mon Sep 17 00:00:00 2001 From: Nikolay Agishev Date: Wed, 20 Sep 2023 15:35:58 +0300 Subject: [PATCH 0962/4498] ARC: fix dynamic thread stack allocation ACR use the same logic for dynamic thread stacks allocation as ARM. This fixup reuses ARM code. Signed-off-by: Nikolay Agishev --- kernel/userspace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/userspace.c b/kernel/userspace.c index 000310c3ab0..27988805b7d 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -51,19 +51,19 @@ static struct k_spinlock lists_lock; /* kobj dlist */ static struct k_spinlock objfree_lock; /* k_object_free */ #ifdef CONFIG_GEN_PRIV_STACKS -/* On ARM MPU we may have two different alignment requirement +/* On ARM & ARC MPU we may have two different alignment requirement * when dynamically allocating thread stacks, one for the privileged * stack and other for the user stack, so we need to account the * worst alignment scenario and reserve space for that. */ -#ifdef CONFIG_ARM_MPU +#if defined(CONFIG_ARM_MPU) || defined(CONFIG_ARC_MPU) #define STACK_ELEMENT_DATA_SIZE(size) \ (sizeof(struct z_stack_data) + CONFIG_PRIVILEGED_STACK_SIZE + \ Z_THREAD_STACK_OBJ_ALIGN(size) + Z_THREAD_STACK_SIZE_ADJUST(size)) #else #define STACK_ELEMENT_DATA_SIZE(size) (sizeof(struct z_stack_data) + \ Z_THREAD_STACK_SIZE_ADJUST(size)) -#endif /* CONFIG_ARM_MPU */ +#endif /* CONFIG_ARM_MPU || CONFIG_ARC_MPU */ #else #define STACK_ELEMENT_DATA_SIZE(size) Z_THREAD_STACK_SIZE_ADJUST(size) #endif /* CONFIG_GEN_PRIV_STACKS */ @@ -342,7 +342,7 @@ static struct z_object *dynamic_object_create(enum k_objects otype, size_t align ((uint8_t *)dyn->data + adjusted_size - sizeof(*stack_data)); stack_data->priv = (uint8_t *)dyn->data; dyn->kobj.data.stack_data = stack_data; -#ifdef CONFIG_ARM_MPU +#if defined(CONFIG_ARM_MPU) || defined(CONFIG_ARC_MPU) dyn->kobj.name = (void *)ROUND_UP( ((uint8_t *)dyn->data + CONFIG_PRIVILEGED_STACK_SIZE), Z_THREAD_STACK_OBJ_ALIGN(size)); From 54e07316669db7e38f4d6d002ca80fb2ebd84e9d Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Tue, 19 Sep 2023 22:20:36 +0100 Subject: [PATCH 0963/4498] kernel: SMP: allow more than 5 CPU cores Previously we limit maximum number of CPU cores to 5, now be bumping this restriction so we can use 12 cores. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- include/zephyr/kernel/thread.h | 4 ++++ kernel/Kconfig | 4 ++-- kernel/sched.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index eaed5b5d21d..3394a65bae2 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -121,8 +121,12 @@ struct _thread_base { #ifdef CONFIG_SCHED_CPU_MASK /* "May run on" bits for each CPU */ +#if CONFIG_MP_MAX_NUM_CPUS <= 8 uint8_t cpu_mask; +#else + uint16_t cpu_mask; #endif +#endif /* CONFIG_SCHED_CPU_MASK */ /* data returned by APIs */ void *swap_data; diff --git a/kernel/Kconfig b/kernel/Kconfig index fce7598aa18..7b4fd19c85f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -989,7 +989,7 @@ config SMP_BOOT_DELAY config MP_NUM_CPUS int "Number of CPUs/cores" default MP_MAX_NUM_CPUS - range 1 5 + range 1 12 help Number of multiprocessing-capable cores available to the multicpu API and SMP features. @@ -997,7 +997,7 @@ config MP_NUM_CPUS config MP_MAX_NUM_CPUS int "Maximum number of CPUs/cores" default 1 - range 1 5 + range 1 12 help Maximum number of multiprocessing-capable cores available to the multicpu API and SMP features. diff --git a/kernel/sched.c b/kernel/sched.c index ea157459dd2..f668c181a27 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1621,8 +1621,8 @@ static inline int z_vrfy_k_is_preempt_thread(void) #ifdef CONFIG_SCHED_CPU_MASK # ifdef CONFIG_SMP -/* Right now we use a single byte for this mask */ -BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 8, "Too many CPUs for mask word"); +/* Right now we use a two byte for this mask */ +BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 16, "Too many CPUs for mask word"); # endif From 06b28fc4eaeddf659d53fdaed61b38b913da19b5 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Tue, 16 May 2023 21:46:08 +0100 Subject: [PATCH 0964/4498] ARC: west: mdb runner: support 12 cores targets Bump number of cores limit in mdb west runner. As we are here - adjust core number in runner test closer to the limit. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- scripts/west_commands/runners/mdb.py | 2 +- scripts/west_commands/tests/test_mdb.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/west_commands/runners/mdb.py b/scripts/west_commands/runners/mdb.py index 3a7410969af..656d41618a6 100644 --- a/scripts/west_commands/runners/mdb.py +++ b/scripts/west_commands/runners/mdb.py @@ -72,7 +72,7 @@ def mdb_do_run(mdb_runner, command): if mdb_runner.cores == 1: # single core's mdb command is different with multicores mdb_cmd = [commander] + mdb_basic_options + mdb_target + mdb_run + [mdb_runner.elf_name] - elif 1 < mdb_runner.cores <= 4: + elif 1 < mdb_runner.cores <= 12: mdb_multifiles = '-multifiles=' for i in range(mdb_runner.cores): mdb_sub_cmd = [commander] + ['-pset={}'.format(i + 1), '-psetname=core{}'.format(i)] diff --git a/scripts/west_commands/tests/test_mdb.py b/scripts/west_commands/tests/test_mdb.py index a6690f4ac5a..ca07b5d1640 100644 --- a/scripts/west_commands/tests/test_mdb.py +++ b/scripts/west_commands/tests/test_mdb.py @@ -92,8 +92,8 @@ 'i': ['--jtag=test_debug', '--cores=1'], 'e': "unsupported jtag adapter test_debug" },{ - 'i': ['--jtag=digilent', '--cores=16'], - 'e': "unsupported cores 16" + 'i': ['--jtag=digilent', '--cores=13'], + 'e': "unsupported cores 13" }] TEST_HW_DEBUG_CASES = [ @@ -116,8 +116,8 @@ 'i': ['--jtag=test_debug', '--cores=1'], 'e': "unsupported jtag adapter test_debug" }, { - 'i': ['--jtag=digilent', '--cores=16'], - 'e': "unsupported cores 16" + 'i': ['--jtag=digilent', '--cores=13'], + 'e': "unsupported cores 13" }] TEST_HW_MULTICORE_CASES = [['--jtag=digilent', '--cores=2']] From d76f345688306e0226ddd5c317a3218358daa3be Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Tue, 19 Sep 2023 22:32:56 +0100 Subject: [PATCH 0965/4498] ARC: boards: nSIM: add 12-core SMP HS5x platform Add new simulation (nSIM) SMP platform based on 12-core ARCv3 HS5x Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/nsim/nsim_hs5x_smp_12cores.dts | 92 +++++++++++++++++++ boards/arc/nsim/nsim_hs5x_smp_12cores.yaml | 17 ++++ .../arc/nsim/nsim_hs5x_smp_12cores_defconfig | 17 ++++ .../nsim/support/mdb_hs5x_smp_12cores.args | 65 +++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 boards/arc/nsim/nsim_hs5x_smp_12cores.dts create mode 100644 boards/arc/nsim/nsim_hs5x_smp_12cores.yaml create mode 100644 boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig create mode 100644 boards/arc/nsim/support/mdb_hs5x_smp_12cores.args diff --git a/boards/arc/nsim/nsim_hs5x_smp_12cores.dts b/boards/arc/nsim/nsim_hs5x_smp_12cores.dts new file mode 100644 index 00000000000..b37b6de6fbf --- /dev/null +++ b/boards/arc/nsim/nsim_hs5x_smp_12cores.dts @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "nsim-smp.dtsi" +#include "nsim-flat-mem.dtsi" + +/ { + model = "snps,nsim_hs"; + compatible = "snps,nsim_hs"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <3>; + }; + + cpu@4 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <4>; + }; + + cpu@5 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <5>; + }; + + cpu@6 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <6>; + }; + + cpu@7 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <7>; + }; + + cpu@8 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <8>; + }; + + cpu@9 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <9>; + }; + + cpu@a { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <10>; + }; + + cpu@b { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <11>; + }; + }; +}; diff --git a/boards/arc/nsim/nsim_hs5x_smp_12cores.yaml b/boards/arc/nsim/nsim_hs5x_smp_12cores.yaml new file mode 100644 index 00000000000..416dcd2133d --- /dev/null +++ b/boards/arc/nsim/nsim_hs5x_smp_12cores.yaml @@ -0,0 +1,17 @@ +identifier: nsim_hs5x_smp_12cores +name: Multi-core HS5x nSIM simulator +type: sim +simulation: mdb-nsim +simulation_exec: mdb +arch: arc +toolchain: + - zephyr + - arcmwdt + - cross-compile +supported: + - smp +testing: + timeout_multiplier: 4 + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig b/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig new file mode 100644 index 00000000000..0f327874e5b --- /dev/null +++ b/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ISA_ARCV3=y +CONFIG_SOC_NSIM=y +CONFIG_SOC_NSIM_HS5X_SMP=y +CONFIG_BOARD_NSIM=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=n +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=12 diff --git a/boards/arc/nsim/support/mdb_hs5x_smp_12cores.args b/boards/arc/nsim/support/mdb_hs5x_smp_12cores.args new file mode 100644 index 00000000000..f1eb7cdcc9b --- /dev/null +++ b/boards/arc/nsim/support/mdb_hs5x_smp_12cores.args @@ -0,0 +1,65 @@ +-arcv3hs +-core0 +-Xdual_issue +-uarch_rev=0:0 +-rgf_num_banks=1 +-rgf_num_wr_ports=2 +-lpc_width=0 +-Xatomic=2 +-Xll64 +-Xunaligned +-Xdiv_rem=radix4 +-Xmpy_option=qmpyh +-Xtimer0 +-Xtimer0_level=0 +-Xtimer1 +-Xtimer1_level=0 +-Xrtc +-action_points=8 +-ap_feature=1 +-Xstack_check +-bpu_bc_entries=2048 +-bpu_pt_entries=16384 +-bpu_rs_entries=4 +-bpu_bc_full_tag=1 +-bpu_tosq_entries=5 +-bpu_fb_entries=2 +-bpu_debug +-smart_version=4 +-smart_stack_entries=8 +-mmuv16 +-mmu_dtlb_entries=16 +-mmu_itlb_entries=16 +-mmu_l2tlb_entries=2048 +-mmu_pgsz=4K +-mmu_address_space=32 +-interrupts=32 +-interrupt_priorities=2 +-ext_interrupts=27 +-interrupt_base=0x0 +-dcache=32768,64,2,a +-dcache_version=5 +-dcache_feature=2 +-dcache_mem_cycles=1 +-dcache_hw_prefetch +-icache=32768,64,4,a +-icache_version=6 +-icache_feature=2 +-Xpct_counters=8 +-Xpct_interrupt +-cluster_version=32 +-arconnect +-connect_ics=1 +-connect_ics_num_semas=16 +-connect_icm=1 +-connect_icm_sram_size=512 +-connect_icm_sram_prot=none +-connect_pmu=1 +-connect_idu=2 +-connect_idu_cirqnum=64 +-connect_gfrc=3 +-connect_icd=2 +-connect_ici=2 +-noprofile +-prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 +-instrs_per_pass=512 From 6048269f952fa4886ce577470dff82c25bd5e5e3 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Fri, 22 Sep 2023 03:48:18 +0100 Subject: [PATCH 0966/4498] ARC: boards: nSIM: add 12-core SMP HS6x platform Add new simulation (nSIM) SMP platform based on 12-core ARCv3 HS6x Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/nsim/nsim_hs6x_smp_12cores.dts | 92 +++++++++++++++++++ boards/arc/nsim/nsim_hs6x_smp_12cores.yaml | 17 ++++ .../arc/nsim/nsim_hs6x_smp_12cores_defconfig | 17 ++++ .../nsim/support/mdb_hs6x_smp_12cores.args | 64 +++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 boards/arc/nsim/nsim_hs6x_smp_12cores.dts create mode 100644 boards/arc/nsim/nsim_hs6x_smp_12cores.yaml create mode 100644 boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig create mode 100644 boards/arc/nsim/support/mdb_hs6x_smp_12cores.args diff --git a/boards/arc/nsim/nsim_hs6x_smp_12cores.dts b/boards/arc/nsim/nsim_hs6x_smp_12cores.dts new file mode 100644 index 00000000000..b37b6de6fbf --- /dev/null +++ b/boards/arc/nsim/nsim_hs6x_smp_12cores.dts @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "nsim-smp.dtsi" +#include "nsim-flat-mem.dtsi" + +/ { + model = "snps,nsim_hs"; + compatible = "snps,nsim_hs"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <3>; + }; + + cpu@4 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <4>; + }; + + cpu@5 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <5>; + }; + + cpu@6 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <6>; + }; + + cpu@7 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <7>; + }; + + cpu@8 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <8>; + }; + + cpu@9 { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <9>; + }; + + cpu@a { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <10>; + }; + + cpu@b { + device_type = "cpu"; + compatible = "snps,arcv3-hs"; + reg = <11>; + }; + }; +}; diff --git a/boards/arc/nsim/nsim_hs6x_smp_12cores.yaml b/boards/arc/nsim/nsim_hs6x_smp_12cores.yaml new file mode 100644 index 00000000000..3113b84e8d6 --- /dev/null +++ b/boards/arc/nsim/nsim_hs6x_smp_12cores.yaml @@ -0,0 +1,17 @@ +identifier: nsim_hs6x_smp_12cores +name: Multi-core HS6x nSIM simulator +type: sim +simulation: mdb-nsim +simulation_exec: mdb +arch: arc +toolchain: + - cross-compile + - zephyr + - arcmwdt +supported: + - smp +testing: + timeout_multiplier: 4 + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig b/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig new file mode 100644 index 00000000000..453f4782d72 --- /dev/null +++ b/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ISA_ARCV3=y +CONFIG_SOC_NSIM=y +CONFIG_SOC_NSIM_HS6X_SMP=y +CONFIG_BOARD_NSIM=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=n +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=12 diff --git a/boards/arc/nsim/support/mdb_hs6x_smp_12cores.args b/boards/arc/nsim/support/mdb_hs6x_smp_12cores.args new file mode 100644 index 00000000000..56722052471 --- /dev/null +++ b/boards/arc/nsim/support/mdb_hs6x_smp_12cores.args @@ -0,0 +1,64 @@ + -arc64 + -core0 + -Xdual_issue + -uarch_rev=0:0 + -rgf_num_banks=1 + -rgf_num_wr_ports=2 + -Xm128 + -Xatomic=2 + -Xunaligned + -Xmpy_cycles=3 + -Xtimer0 + -Xtimer0_level=0 + -Xtimer1 + -Xtimer1_level=0 + -Xrtc + -action_points=8 + -ap_feature=1 + -Xstack_check + -bpu_bc_entries=2048 + -bpu_pt_entries=16384 + -bpu_rs_entries=4 + -bpu_bc_full_tag=1 + -bpu_tosq_entries=5 + -bpu_fb_entries=2 + -bpu_debug + -smart_version=5 + -smart_stack_entries=8 + -mmuv16 + -mmu_dtlb_entries=16 + -mmu_itlb_entries=16 + -mmu_l2tlb_entries=2048 + -mmu_pgsz=4K + -mmu_address_space=48 + -interrupts=32 + -interrupt_priorities=2 + -ext_interrupts=27 + -interrupt_base=0x0 + -dcache=32768,64,2,a + -dcache_version=5 + -dcache_feature=2 + -dcache_mem_cycles=1 + -dcache_hw_prefetch + -icache=32768,64,4,a + -icache_version=6 + -icache_feature=2 + -Xpct_counters=8 + -Xpct_interrupt + -cluster_version=32 + -arconnect + -connect_ics=1 + -connect_ics_num_semas=16 + -connect_icm=1 + -connect_icm_sram_size=512 + -connect_icm_sram_prot=none + -connect_pmu=1 + -connect_idu=2 + -connect_idu_cirqnum=64 + -connect_gfrc=3 + -connect_icd=2 + -connect_ici=2 + -nogoifmain + -noprofile + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -instrs_per_pass=512 From 7ce5a2e6297c904eb827ee2fb3a2f1072d2b9493 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Fri, 22 Sep 2023 06:44:08 +0100 Subject: [PATCH 0967/4498] ARC: board: nSIM: update documentation about new platforms Update nSIM board documentation about new platforms (12 cores HS5x & HS6x) Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/nsim/doc/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arc/nsim/doc/index.rst b/boards/arc/nsim/doc/index.rst index ee87b4f2aab..64f6f4666f4 100644 --- a/boards/arc/nsim/doc/index.rst +++ b/boards/arc/nsim/doc/index.rst @@ -33,6 +33,8 @@ available configurations are listed below: * ``nsim_vpx5`` - ARCv2 VPX5 core, close to vpx5_integer_full template * ``nsim_hs5x`` - 32-bit ARCv3 HS core with rich set of options * ``nsim_hs6x`` - 64-bit ARCv3 HS core with rich set of options +* ``nsim_hs5x_smp_12cores`` - SMP 12 cores 32-bit ARCv3 HS platform +* ``nsim_hs5x_smp_12cores`` - SMP 12 cores 64-bit ARCv3 HS platform .. _board_arc_nsim_prop_args_files: From 910d417a92f0092d35a6941fd7279dac7209f7e0 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 15 Jun 2023 15:48:19 +0700 Subject: [PATCH 0968/4498] drivers: spi_mcux_lpspi: add support dma per instance Currently, the driver imply understand that all instances will use dma when CONFIG_SPI_MCUX_LPSPI_DMA is set. There might be an instance doesn't need DMA, so instead of enforce spi_transceive API to use DMA, add more flexible to enable DMA only when required Signed-off-by: Dat Nguyen Duy --- drivers/spi/spi_mcux_lpspi.c | 89 ++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/drivers/spi/spi_mcux_lpspi.c b/drivers/spi/spi_mcux_lpspi.c index 2ddee4a2b09..8af05a28434 100644 --- a/drivers/spi/spi_mcux_lpspi.c +++ b/drivers/spi/spi_mcux_lpspi.c @@ -472,7 +472,7 @@ static int transceive_dma(const struct device *dev, return ret; } -#else +#endif static int transceive(const struct device *dev, const struct spi_config *spi_cfg, @@ -505,7 +505,6 @@ static int transceive(const struct device *dev, return ret; } -#endif /*CONFIG_SPI_MCUX_LPSPI_DMA */ static int spi_mcux_transceive(const struct device *dev, const struct spi_config *spi_cfg, @@ -513,10 +512,14 @@ static int spi_mcux_transceive(const struct device *dev, const struct spi_buf_set *rx_bufs) { #ifdef CONFIG_SPI_MCUX_LPSPI_DMA - return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); -#else - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); + const struct spi_mcux_data *data = dev->data; + + if (data->dma_rx.dma_dev && data->dma_tx.dma_dev) { + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); + } #endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ + + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -559,14 +562,16 @@ static int spi_mcux_init(const struct device *dev) data->dev = dev; #ifdef CONFIG_SPI_MCUX_LPSPI_DMA - if (!device_is_ready(data->dma_tx.dma_dev)) { - LOG_ERR("%s device is not ready", data->dma_tx.dma_dev->name); - return -ENODEV; - } + if (data->dma_tx.dma_dev && data->dma_rx.dma_dev) { + if (!device_is_ready(data->dma_tx.dma_dev)) { + LOG_ERR("%s device is not ready", data->dma_tx.dma_dev->name); + return -ENODEV; + } - if (!device_is_ready(data->dma_rx.dma_dev)) { - LOG_ERR("%s device is not ready", data->dma_rx.dma_dev->name); - return -ENODEV; + if (!device_is_ready(data->dma_rx.dma_dev)) { + LOG_ERR("%s device is not ready", data->dma_rx.dma_dev->name); + return -ENODEV; + } } #endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ @@ -589,33 +594,39 @@ static const struct spi_driver_api spi_mcux_driver_api = { }; #ifdef CONFIG_SPI_MCUX_LPSPI_DMA -#define SPI_DMA_CHANNELS(n) \ - .dma_tx = { \ - .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \ - .channel = \ - DT_INST_DMAS_CELL_BY_NAME(n, tx, mux), \ - .dma_cfg = { \ - .channel_direction = MEMORY_TO_PERIPHERAL, \ - .dma_callback = spi_mcux_dma_callback, \ - .source_data_size = 1, \ - .dest_data_size = 1, \ - .block_count = 1, \ - .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, source) \ - } \ - }, \ - .dma_rx = { \ - .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, rx)), \ - .channel = \ - DT_INST_DMAS_CELL_BY_NAME(n, rx, mux), \ - .dma_cfg = { \ - .channel_direction = PERIPHERAL_TO_MEMORY, \ - .dma_callback = spi_mcux_dma_callback, \ - .source_data_size = 1, \ - .dest_data_size = 1, \ - .block_count = 1, \ - .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, rx, source) \ - } \ - } +#define SPI_DMA_CHANNELS(n) \ + IF_ENABLED(DT_INST_DMAS_HAS_NAME(n, tx), \ + ( \ + .dma_tx = { \ + .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \ + .channel = \ + DT_INST_DMAS_CELL_BY_NAME(n, tx, mux), \ + .dma_cfg = { \ + .channel_direction = MEMORY_TO_PERIPHERAL, \ + .dma_callback = spi_mcux_dma_callback, \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .block_count = 1, \ + .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, source) \ + } \ + }, \ + )) \ + IF_ENABLED(DT_INST_DMAS_HAS_NAME(n, rx), \ + ( \ + .dma_rx = { \ + .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, rx)), \ + .channel = \ + DT_INST_DMAS_CELL_BY_NAME(n, rx, mux), \ + .dma_cfg = { \ + .channel_direction = PERIPHERAL_TO_MEMORY, \ + .dma_callback = spi_mcux_dma_callback, \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .block_count = 1, \ + .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, rx, source) \ + } \ + } \ + )) #else #define SPI_DMA_CHANNELS(n) #endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ From fef887a7b3c690ed0a962264f7e027520b9abb5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Sep 2023 15:02:18 +0200 Subject: [PATCH 0969/4498] doc: bluetooth: mesh: Fix LaTeX math equations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it doesn't seem to be an issue for HTML rendering, the use of \verb is not allowed within LaTeX equations and breaks the PDF build. Signed-off-by: Benjamin Cabé --- .../bluetooth/api/mesh/sar_cfg.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst index 1191ec3e2ab..93186f2988e 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst @@ -60,9 +60,9 @@ and :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`, and is defined .. math:: \begin{aligned} - \max(&\verb|CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT| \\ - &+ \text{TTL} \times \verb|CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT| \\ - &+ \text{number of un-acked segments} \times \verb|CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT| , 400) + \max(&\mathtt{CONFIG\_BT\_MESH\_SEG\_ACK\_BASE\_TIMEOUT} \\ + &+ \text{TTL} \times \mathtt{CONFIG\_BT\_MESH\_SEG\_ACK\_PER\_HOP\_TIMEOUT} \\ + &+ \text{number of un-acked segments} \times \mathtt{CONFIG\_BT\_MESH\_SEG\_ACK\_PER\_SEGMENT\_TIMEOUT} , 400) \end{aligned} Segmentation and reassembly (SAR) Configuration models @@ -161,7 +161,7 @@ Segment transmission interval is then calculated using the following formula: .. math:: - (\verb|CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP| + 1) \times 10~\text{ms} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_TX\_SEG\_INT\_STEP} + 1) \times 10~\text{ms} SAR Unicast Retransmissions Count @@ -188,7 +188,7 @@ This value is then used to calculate the interval step using the following formu .. math:: - (\verb|CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP| + 1) \times 25~\text{ms} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_TX\_UNICAST\_RETRANS\_INT\_STEP} + 1) \times 25~\text{ms} SAR Unicast Retransmissions Interval Increment @@ -202,7 +202,7 @@ The Kconfig option value is used to calculate the increment using the following .. math:: - (\verb|CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC| + 1) \times 25~\text{ms} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_TX\_UNICAST\_RETRANS\_INT\_INC} + 1) \times 25~\text{ms} SAR Multicast Retransmissions Count @@ -222,7 +222,7 @@ using the following formula: .. math:: - (\verb|CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT| + 1) \times 25~\text{ms} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_TX\_MULTICAST\_RETRANS\_INT} + 1) \times 25~\text{ms} SAR Discard Timeout @@ -234,7 +234,7 @@ default value. The discard timeout will be calculated using the following formul .. math:: - (\verb|CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT| + 1) \times 5~\text{seconds} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_RX\_DISCARD\_TIMEOUT} + 1) \times 5~\text{seconds} SAR Acknowledgment Delay Increment @@ -275,4 +275,4 @@ Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP` to s .. math:: - (\verb|CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP| + 1) \times 10~\text{ms} + (\mathtt{CONFIG\_BT\_MESH\_SAR\_RX\_SEG\_INT\_STEP} + 1) \times 10~\text{ms} From a05c88daa5ba34968b97265054ed97e225d50521 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 22 Sep 2023 15:20:28 -0400 Subject: [PATCH 0970/4498] drivers: console: uart_console: avoid infinite loop in isr Previously, the `uart_console_isr()` routine assumed that the return value of several uart API functions would only ever return the equivalent of a boolean value. In fact, an integer is returned on occasion, and that integer can take on many values. Since unary operations would either go to "true" or "false" and since any non-zero integer evaluates to "true", even a return value of something like `-ENODEV` would evalueate to true. Explicitly compare against the integer-equivalent value of the expected boolean output. With this, in the case of errors, negative return values do not evaluate to "true", and the infinite loop is avoied. Signed-off-by: Christopher Friedt --- drivers/console/uart_console.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c index 4800180b3f8..378bbe91ff3 100644 --- a/drivers/console/uart_console.c +++ b/drivers/console/uart_console.c @@ -446,13 +446,18 @@ static void uart_console_isr(const struct device *unused, void *user_data) ARG_UNUSED(user_data); static uint8_t last_char = '\0'; - while (uart_irq_update(uart_console_dev) && - uart_irq_is_pending(uart_console_dev)) { + while (uart_irq_update(uart_console_dev) > 0 && + uart_irq_is_pending(uart_console_dev) > 0) { static struct console_input *cmd; uint8_t byte; int rx; - if (!uart_irq_rx_ready(uart_console_dev)) { + rx = uart_irq_rx_ready(uart_console_dev); + if (rx < 0) { + return; + } + + if (rx == 0) { continue; } @@ -561,7 +566,7 @@ static void console_input_init(void) uart_irq_callback_set(uart_console_dev, uart_console_isr); /* Drain the fifo */ - while (uart_irq_rx_ready(uart_console_dev)) { + while (uart_irq_rx_ready(uart_console_dev) > 0) { uart_fifo_read(uart_console_dev, &c, 1); } From 451568c645a4bb9120739ca664706e80b67cb68a Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sat, 23 Sep 2023 09:25:38 +1000 Subject: [PATCH 0971/4498] drivers: adc: add adc_read_dt api This was missing from the ADC Devicetree API set. Signed-off-by: Nick Ward --- include/zephyr/drivers/adc.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index d7e11bbee9b..989ec79ce11 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -681,6 +681,21 @@ static inline int z_impl_adc_read(const struct device *dev, return api->read(dev, sequence); } +/** + * @brief Set a read request from a struct adc_dt_spec. + * + * @param spec ADC specification from Devicetree. + * @param sequence Structure specifying requested sequence of samplings. + * + * @return A value from adc_read(). + * @see adc_read() + */ +static inline int adc_read_dt(const struct adc_dt_spec *spec, + const struct adc_sequence *sequence) +{ + return adc_read(spec->dev, sequence); +} + /** * @brief Set an asynchronous read request. * From ead0c4f865176c84f72e39b4a7ae643f9c028d3e Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sat, 23 Sep 2023 09:27:39 +1000 Subject: [PATCH 0972/4498] drivers: adc: use adc_read_dt api Where struct adc_dt_spec is in use use adc_read_dt(). Signed-off-by: Nick Ward --- drivers/sensor/current_amp/current_amp.c | 2 +- drivers/sensor/mcp970x/mcp970x.c | 2 +- samples/boards/google_twinkie_v2_pda/src/meas.c | 2 +- samples/drivers/adc/src/main.c | 2 +- tests/drivers/adc/adc_api/src/test_adc.c | 12 ++++++------ tests/drivers/adc/adc_rescale/src/main.c | 6 +++--- tests/drivers/regulator/voltage/src/main.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/sensor/current_amp/current_amp.c b/drivers/sensor/current_amp/current_amp.c index 947969c4313..8a62a1e61f5 100644 --- a/drivers/sensor/current_amp/current_amp.c +++ b/drivers/sensor/current_amp/current_amp.c @@ -28,7 +28,7 @@ static int fetch(const struct device *dev, enum sensor_channel chan) return -ENOTSUP; } - ret = adc_read(config->port.dev, &data->sequence); + ret = adc_read_dt(&config->port, &data->sequence); if (ret != 0) { LOG_ERR("adc_read: %d", ret); } diff --git a/drivers/sensor/mcp970x/mcp970x.c b/drivers/sensor/mcp970x/mcp970x.c index 61d95fc5505..fb43f4d92e3 100644 --- a/drivers/sensor/mcp970x/mcp970x.c +++ b/drivers/sensor/mcp970x/mcp970x.c @@ -46,7 +46,7 @@ static int fetch(const struct device *dev, enum sensor_channel chan) return -ENOTSUP; } - ret = adc_read(config->adc.dev, &data->sequence); + ret = adc_read_dt(&config->adc, &data->sequence); if (ret != 0) { LOG_ERR("adc_read: %d", ret); } diff --git a/samples/boards/google_twinkie_v2_pda/src/meas.c b/samples/boards/google_twinkie_v2_pda/src/meas.c index 5d2ba9c793c..15b9b877931 100644 --- a/samples/boards/google_twinkie_v2_pda/src/meas.c +++ b/samples/boards/google_twinkie_v2_pda/src/meas.c @@ -33,7 +33,7 @@ int meas_vbus_v(int32_t *v) }; adc_sequence_init_dt(&adc_vbus_v.port, &sequence); - ret = adc_read(adc_vbus_v.port.dev, &sequence); + ret = adc_read_dt(&adc_vbus_v.port, &sequence); if (ret != 0) { return ret; } diff --git a/samples/drivers/adc/src/main.c b/samples/drivers/adc/src/main.c index 50f54455de6..0f781eac700 100644 --- a/samples/drivers/adc/src/main.c +++ b/samples/drivers/adc/src/main.c @@ -65,7 +65,7 @@ int main(void) (void)adc_sequence_init_dt(&adc_channels[i], &sequence); - err = adc_read(adc_channels[i].dev, &sequence); + err = adc_read_dt(&adc_channels[i], &sequence); if (err < 0) { printk("Could not read (%d)\n", err); continue; diff --git a/tests/drivers/adc/adc_api/src/test_adc.c b/tests/drivers/adc/adc_api/src/test_adc.c index 089d9c87a14..250982b1d69 100644 --- a/tests/drivers/adc/adc_api/src/test_adc.c +++ b/tests/drivers/adc/adc_api/src/test_adc.c @@ -93,7 +93,7 @@ static int test_task_one_channel(void) init_adc(); (void)adc_sequence_init_dt(&adc_channels[0], &sequence); - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); check_samples(1); @@ -124,7 +124,7 @@ static int test_task_multiple_channels(void) sequence.channels |= BIT(adc_channels[i].channel_id); } - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); if (ret == -ENOTSUP) { ztest_test_skip(); } @@ -230,7 +230,7 @@ static int test_task_with_interval(void) (void)adc_sequence_init_dt(&adc_channels[0], &sequence); - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); if (ret == -ENOTSUP) { ztest_test_skip(); } @@ -310,7 +310,7 @@ static int test_task_repeated_samplings(void) sequence.channels |= BIT(adc_channels[1].channel_id); } - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); if (ret == -ENOTSUP) { ztest_test_skip(); } @@ -339,7 +339,7 @@ static int test_task_invalid_request(void) init_adc(); - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); zassert_not_equal(ret, 0, "adc_read() unexpectedly succeeded"); #if defined(CONFIG_ADC_ASYNC) @@ -352,7 +352,7 @@ static int test_task_invalid_request(void) */ sequence.resolution = adc_channels[0].resolution; - ret = adc_read(adc_channels[0].dev, &sequence); + ret = adc_read_dt(&adc_channels[0], &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); check_samples(1); diff --git a/tests/drivers/adc/adc_rescale/src/main.c b/tests/drivers/adc/adc_rescale/src/main.c index 4bc9c3cccd8..121801b3be8 100644 --- a/tests/drivers/adc/adc_rescale/src/main.c +++ b/tests/drivers/adc/adc_rescale/src/main.c @@ -69,7 +69,7 @@ static int test_task_voltage_divider(void) }; adc_sequence_init_dt(&adc_node_0.port, &sequence); - ret = adc_read(adc_node_0.port.dev, &sequence); + ret = adc_read_dt(&adc_node_0.port, &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); ret = adc_raw_to_millivolts_dt(&adc_node_0.port, &calculated_voltage); @@ -109,7 +109,7 @@ static int test_task_current_sense_shunt(void) }; adc_sequence_init_dt(&adc_node_1.port, &sequence); - ret = adc_read(adc_node_1.port.dev, &sequence); + ret = adc_read_dt(&adc_node_1.port, &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); ret = adc_raw_to_millivolts_dt(&adc_node_1.port, &calculated_current); @@ -149,7 +149,7 @@ static int test_task_current_sense_amplifier(void) }; adc_sequence_init_dt(&adc_node_2.port, &sequence); - ret = adc_read(adc_node_2.port.dev, &sequence); + ret = adc_read_dt(&adc_node_2.port, &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); ret = adc_raw_to_millivolts_dt(&adc_node_2.port, &calculated_current); diff --git a/tests/drivers/regulator/voltage/src/main.c b/tests/drivers/regulator/voltage/src/main.c index 37db851d237..3978022130c 100644 --- a/tests/drivers/regulator/voltage/src/main.c +++ b/tests/drivers/regulator/voltage/src/main.c @@ -83,7 +83,7 @@ ZTEST(regulator_voltage, test_output_voltage) } for (unsigned int k = 0U; k < adc_avg_count; k++) { - ret = adc_read(adc_chs[i].dev, &sequence); + ret = adc_read_dt(&adc_chs[i], &sequence); zassert_equal(ret, 0); val_mv += buf; From 12720fec51bf25f1f884fd82d81aa375d6d57fb4 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 24 Sep 2023 16:33:10 +0200 Subject: [PATCH 0973/4498] drivers: ieee802154: rf2xx: Fix rf231 invalid frame The at86rf231 frame buffer access mode read differs from all other transceivers by only transfer one more byte after PSDU data instead three. This difference is not evaluated in the current version of the driver. The current change add the necessary check and read the missing data (EQ, TRAC). Signed-off-by: Gerson Fernando Budke --- drivers/ieee802154/ieee802154_rf2xx.c | 27 ++++++++++++++-------- drivers/ieee802154/ieee802154_rf2xx_regs.h | 1 + 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index bef2195b252..8f6f4a37656 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -180,7 +180,7 @@ static void rf2xx_trx_rx(const struct device *dev) } if (pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) { - LOG_ERR("invalid RX frame length"); + LOG_ERR("Invalid RX frame length"); return; } @@ -189,18 +189,26 @@ static void rf2xx_trx_rx(const struct device *dev) rf2xx_iface_frame_read(dev, rx_buf, frame_len); - trac = rx_buf[pkt_len + RX2XX_FRAME_TRAC_INDEX]; - trac = (trac >> RF2XX_RX_TRAC_STATUS) & RF2XX_RX_TRAC_BIT_MASK; + if (ctx->trx_model != RF2XX_TRX_MODEL_231) { + trac = rx_buf[pkt_len + RX2XX_FRAME_TRAC_INDEX]; + trac = (trac >> RF2XX_RX_TRAC_STATUS) & RF2XX_RX_TRAC_BIT_MASK; + + ctx->pkt_ed = rx_buf[pkt_len + RX2XX_FRAME_ED_INDEX]; + } else { + trac = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATE_REG) + >> RF2XX_TRAC_STATUS) & RF2XX_TRAC_BIT_MASK; + + ctx->pkt_ed = (rf2xx_iface_reg_read(dev, RF2XX_PHY_RSSI_REG) + >> RF2XX_RSSI) & RF2XX_RSSI_MASK; + } + ctx->pkt_lqi = rx_buf[pkt_len + RX2XX_FRAME_LQI_INDEX]; if (trac == RF2XX_TRX_PHY_STATE_TRAC_INVALID) { - LOG_ERR("invalid RX frame"); + LOG_ERR("Invalid RX frame"); return; } - ctx->pkt_lqi = rx_buf[pkt_len + RX2XX_FRAME_LQI_INDEX]; - ctx->pkt_ed = rx_buf[pkt_len + RX2XX_FRAME_ED_INDEX]; - if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && !IS_ENABLED(CONFIG_NET_L2_OPENTHREAD)) { pkt_len -= RX2XX_FRAME_FCS_LENGTH; @@ -208,9 +216,8 @@ static void rf2xx_trx_rx(const struct device *dev) pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len, AF_UNSPEC, 0, K_NO_WAIT); - if (!pkt) { - LOG_ERR("No buf available"); + LOG_ERR("No RX buffer available"); return; } @@ -224,7 +231,7 @@ static void rf2xx_trx_rx(const struct device *dev) ctx->pkt_ed); if (net_recv_data(ctx->iface, pkt) < 0) { - LOG_DBG("Packet dropped by NET stack"); + LOG_DBG("RX Packet dropped by NET stack"); net_pkt_unref(pkt); return; } diff --git a/drivers/ieee802154/ieee802154_rf2xx_regs.h b/drivers/ieee802154/ieee802154_rf2xx_regs.h index d780b9a8012..ce9c2b89acc 100644 --- a/drivers/ieee802154/ieee802154_rf2xx_regs.h +++ b/drivers/ieee802154/ieee802154_rf2xx_regs.h @@ -131,6 +131,7 @@ #define RF2XX_RX_CRC_VALID 7 #define RF2XX_RND_VALUE 5 #define RF2XX_RSSI 0 +#define RF2XX_RSSI_MASK 0x1F /* PHY_CC_CCA */ #define RF2XX_CCA_REQUEST 7 From 37b8dc17bccabda6b835a077e8b8e65c2ffadedd Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Sun, 24 Sep 2023 22:03:47 +0300 Subject: [PATCH 0974/4498] net: socket: Allow same port if different address family It is always possible to bind to same port if the sockets are in different address family. Signed-off-by: Jukka Rissanen --- subsys/net/ip/net_context.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 5bd4122efc6..7875d6e3bc3 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -132,7 +132,8 @@ static int check_used_port(enum net_ip_protocol proto, if (IS_ENABLED(CONFIG_NET_IPV6) && local_addr->sa_family == AF_INET6) { - if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL) { + if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL || + net_sin6_ptr(&contexts[i].local)->sin6_family != AF_INET6) { continue; } @@ -187,7 +188,8 @@ static int check_used_port(enum net_ip_protocol proto, } } else if (IS_ENABLED(CONFIG_NET_IPV4) && local_addr->sa_family == AF_INET) { - if (net_sin_ptr(&contexts[i].local)->sin_addr == NULL) { + if (net_sin_ptr(&contexts[i].local)->sin_addr == NULL || + net_sin_ptr(&contexts[i].local)->sin_family != AF_INET) { continue; } From c796e1bee2e312ede01f6889539e6fb4bcceb8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Mon, 25 Sep 2023 08:42:00 +0200 Subject: [PATCH 0975/4498] manifest: hal_nordic: update to prevent USBD bad DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bad DMA request was observed as SPU FLASHACCERR when building for nrf5340dk_nrf5340_cpuapp_ns target. The bad DMA request would manifest itself as device failing to reconnect after USB cable was reconnected. The issue was especially visible with CDC ACM sample because SET LINE CODING request has 7 bytes payload. Signed-off-by: Tomasz Moń --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d23243ad03c..936b90ff2ea 100644 --- a/west.yml +++ b/west.yml @@ -189,7 +189,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 03807f75485c97bd7b9094e0c20e40f8044da9f5 + revision: 092eb78ed1b1551d8f480019b9c05d7371784578 path: modules/hal/nordic groups: - hal From 62f07c67d5689155c5bf649ac8653309e7f8bbad Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 17 Jul 2023 14:46:45 +0100 Subject: [PATCH 0976/4498] sysbuild: Add support for MCUboot/app encryption keys Adds support for controlling the MCUboot (and application) signing key, and allows for generating encrypted updates. Signed-off-by: Jamie McCrae --- .../MAIN_image_default.cmake | 3 +++ .../sysbuild/images/bootloader/CMakeLists.txt | 4 ++++ share/sysbuild/images/bootloader/Kconfig | 20 +++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/share/sysbuild/image_configurations/MAIN_image_default.cmake b/share/sysbuild/image_configurations/MAIN_image_default.cmake index a6bd72d7d1a..a2ae840ef97 100644 --- a/share/sysbuild/image_configurations/MAIN_image_default.cmake +++ b/share/sysbuild/image_configurations/MAIN_image_default.cmake @@ -9,6 +9,9 @@ set_config_bool(${ZCMAKE_APPLICATION} CONFIG_BOOTLOADER_MCUBOOT "${SB_CONFIG_BOO set_config_string(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_SIGNATURE_KEY_FILE "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}" ) +set_config_string(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE + "${SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE}" +) if(SB_CONFIG_BOOTLOADER_MCUBOOT) if("${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") diff --git a/share/sysbuild/images/bootloader/CMakeLists.txt b/share/sysbuild/images/bootloader/CMakeLists.txt index c00a8e97783..2a0f12f958d 100644 --- a/share/sysbuild/images/bootloader/CMakeLists.txt +++ b/share/sysbuild/images/bootloader/CMakeLists.txt @@ -15,4 +15,8 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT) sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} ${image}) set_config_string(${image} CONFIG_BOOT_SIGNATURE_KEY_FILE "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}") + set_config_bool(${image} CONFIG_BOOT_ENCRYPT_IMAGE "${SB_CONFIG_BOOT_ENCRYPTION}") + if(SB_CONFIG_BOOT_ENCRYPTION) + set_config_string(${image} CONFIG_BOOT_ENCRYPTION_KEY_FILE "${SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE}") + endif() endif() diff --git a/share/sysbuild/images/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig index 19924a6ca18..e8c788f72c5 100644 --- a/share/sysbuild/images/bootloader/Kconfig +++ b/share/sysbuild/images/bootloader/Kconfig @@ -56,12 +56,28 @@ config BOOT_SIGNATURE_TYPE_ED25519 endchoice config BOOT_SIGNATURE_KEY_FILE - string "PEM key file" + string "Signing PEM key file" default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ed25519.pem" if BOOT_SIGNATURE_TYPE_ED25519 default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-rsa-2048.pem" if BOOT_SIGNATURE_TYPE_RSA default "" help - Absolute path to key file to use with MCUBoot. + Absolute path to signing key file to use with MCUBoot. + +config BOOT_ENCRYPTION + bool "Encrypted image support" + depends on !BOOT_SIGNATURE_TYPE_NONE + help + Support encrypted images. + +config BOOT_ENCRYPTION_KEY_FILE + string "Encryption PEM key file" + depends on BOOT_ENCRYPTION + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-ec256-priv.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-x25519-priv.pem" if BOOT_SIGNATURE_TYPE_ED25519 + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-rsa2048-priv.pem" if BOOT_SIGNATURE_TYPE_RSA + default "" + help + Absolute path to encryption key file to use with MCUBoot. endif From 97123c4f4a558967b067a2da50bc72c5f2fdb48a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 17 Jul 2023 14:54:22 +0100 Subject: [PATCH 0977/4498] scripts: ci: check_compliance: Add sysbuild Kconfig exceptions Adds exceptions for Kconfigs which sysbuild uses when configuring MCUboot. Signed-off-by: Jamie McCrae --- scripts/ci/check_compliance.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index c63007580e3..140c59d4fb2 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -615,6 +615,8 @@ def check_no_undef_outside_kconfig(self, kconf): # toolchain Kconfig which is sourced based on # Zephyr toolchain variant and therefore not # visible to compliance. + "BOOT_ENCRYPTION_KEY_FILE", # Used in sysbuild + "BOOT_ENCRYPT_IMAGE", # Used in sysbuild "BOOT_UPGRADE_ONLY", # Used in example adjusting MCUboot config, but # symbol is defined in MCUboot itself. "BOOT_SERIAL_BOOT_MODE", # Used in (sysbuild-based) test/ From 30092d1910cffbf039f7133554c00d27031382c3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 26 Jul 2023 13:44:07 +0100 Subject: [PATCH 0978/4498] doc: release: 3.5: Add note on sysbuild MCUboot encryption support Adds a note that sysbuild can now set the encryption key for MCUboot and target images. Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 0fd4fb94a95..963d83abe6c 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -124,6 +124,10 @@ Build system and infrastructure * Added support for shared interrupts +* Added support for setting MCUboot encryption key in sysbuild which is then + propagated to the bootloader and target images to automatically create + encrypted updates. + Drivers and Sensors ******************* From c350c65be8d43361e308f5d11dcca6402f3a9767 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 19 Sep 2023 09:31:49 +0100 Subject: [PATCH 0979/4498] samples: mgmt: mcumgr: smp_svr: Add sysbuild file Adds a sysbuild file which includes MCUboot, as the sample is dependent upon it. Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/sysbuild.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 samples/subsys/mgmt/mcumgr/smp_svr/sysbuild.conf diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild.conf b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild.conf new file mode 100644 index 00000000000..34f887190b3 --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild.conf @@ -0,0 +1,2 @@ +# Enable MCUboot bootloader support +SB_CONFIG_BOOTLOADER_MCUBOOT=y From 1640d37189f7fee01b942438d3d880a9c54b4c23 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 01:30:31 +0000 Subject: [PATCH 0980/4498] drivers: neural_net: remove obsolete driver This driver is not being used by anything and is not being built or tested, so remove it. Signed-off-by: Anas Nashif --- doc/hardware/peripherals/gna.rst | 7 - drivers/neural_net/CMakeLists.txt | 2 - drivers/neural_net/Kconfig | 2 - drivers/neural_net/Kconfig.intel_gna | 43 -- drivers/neural_net/intel_gna.c | 526 ------------------------- drivers/neural_net/intel_gna.h | 205 ---------- dts/bindings/neural_net/intel,gna.yaml | 19 - 7 files changed, 804 deletions(-) delete mode 100644 drivers/neural_net/Kconfig.intel_gna delete mode 100644 drivers/neural_net/intel_gna.c delete mode 100644 drivers/neural_net/intel_gna.h delete mode 100644 dts/bindings/neural_net/intel,gna.yaml diff --git a/doc/hardware/peripherals/gna.rst b/doc/hardware/peripherals/gna.rst index 212217bd42d..b5fc8365752 100644 --- a/doc/hardware/peripherals/gna.rst +++ b/doc/hardware/peripherals/gna.rst @@ -9,13 +9,6 @@ Overview The GNA API provides access to Intel's Gaussian Mixture Model and Neural Network Accelerator (GNA). -Configuration Options -********************* - -Related configuration options: - -* :kconfig:option:`CONFIG_INTEL_GNA` - API Reference ************* diff --git a/drivers/neural_net/CMakeLists.txt b/drivers/neural_net/CMakeLists.txt index 4ce3c7f3e26..28a0cecce8a 100644 --- a/drivers/neural_net/CMakeLists.txt +++ b/drivers/neural_net/CMakeLists.txt @@ -1,5 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() - -zephyr_library_sources_ifdef(CONFIG_INTEL_GNA intel_gna.c) diff --git a/drivers/neural_net/Kconfig b/drivers/neural_net/Kconfig index 001893744d7..0aefae40d0a 100644 --- a/drivers/neural_net/Kconfig +++ b/drivers/neural_net/Kconfig @@ -14,6 +14,4 @@ module = NEURAL_NET module-str = neural_net source "subsys/logging/Kconfig.template.log_config" -source "drivers/neural_net/Kconfig.*" - endif # NEURAL_NET diff --git a/drivers/neural_net/Kconfig.intel_gna b/drivers/neural_net/Kconfig.intel_gna deleted file mode 100644 index 55ddd68f1ff..00000000000 --- a/drivers/neural_net/Kconfig.intel_gna +++ /dev/null @@ -1,43 +0,0 @@ -# Neural network accelerator driver configuration options - -# Copyright (c) 2018 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -menuconfig INTEL_GNA - bool "Intel GNA Inferencing Engine" - help - Enable support for Intel's GMM and Neural Network Accelerator - -if INTEL_GNA - -config INTEL_GNA_INIT_PRIORITY - int "Init priority" - default 99 - help - Device driver initialization priority. - -config INTEL_GNA_MAX_MODELS - int "Max number of neural network models supported by driver" - default 4 - help - Max. number of unique neural network models required in the system - -config INTEL_GNA_MAX_PENDING_REQUESTS - int "Max number of pending inference requests" - default 4 - help - Maximum number of pending inference requests in the driver - -config INTEL_GNA_POWER_MODE - int "GNA operation mode" - default 0 - range 0 3 - help - Sets GNA operation mode for power saving - Levels are: - 0 ALWAYS_ON, GNA is always on with very minimal power save - 1 CLOCK_GATED, GNA clock is gated when not active - 2 POWER_GATED, GNA clock and power are gated when not active - 3 ALWAYS_OFF, GNA is tuned off and never used in the system - -endif # INTEL_GNA diff --git a/drivers/neural_net/intel_gna.c b/drivers/neural_net/intel_gna.c deleted file mode 100644 index a7b61a3554d..00000000000 --- a/drivers/neural_net/intel_gna.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation - * - * Author: Sathish Kuttan - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Intel GNA device driver - * - * Device driver implementation for Intel's - * Gaussian Mixture Model and Neural Network Accelerator (GNA) - */ - -#define DT_DRV_COMPAT intel_gna - -#include -#include -#include -#include - -#include -#include "intel_gna.h" - -#define LOG_LEVEL CONFIG_NEURAL_NET_LOG_LEVEL -#include -#include -LOG_MODULE_REGISTER(neural_net); - -#if LOG_LEVEL >= LOG_LEVEL_DBG -static void intel_gna_regs_dump(const struct device *dev); -static void intel_gna_config_desc_dump(const struct device *dev); -#define INTEL_GNA_REGS_DUMP(dev) intel_gna_regs_dump((dev)) -#define INTEL_GNA_CONFIG_DESC_DUMP(dev) intel_gna_config_desc_dump((dev)) -#else -#define INTEL_GNA_REGS_DUMP(dev) -#define INTEL_GNA_CONFIG_DESC_DUMP(dev) -#endif - -#define GNA_MODEL_VIRT_BASE_DEFAULT 0 - -DEVICE_DECLARE(gna); -static struct intel_gna_config_desc __aligned(GNA_PG_SIZE_IN_BYTES) - gna_config_desc; -static struct intel_gna_page_table __aligned(GNA_PG_SIZE_IN_BYTES) - gna_page_table[GNA_NUM_PG_TABLES_NEEDED]; - -static void intel_gna_interrupt_handler(const struct device *dev) -{ - struct intel_gna_data *const gna = dev->data; - - volatile struct intel_gna_regs *regs = gna->regs; - struct intel_gna_pending_resp pending_resp; - struct intel_gna_pending_req pending_req; - - /* check for generic / virtual address out of range error */ - if (regs->gnasts & (GNA_STS_VIRT_ADDR_OOR | GNA_STS_ERROR)) { - pending_resp.response.result = GNA_RESULT_GENERIC_ERROR; - } - - /* check for parameter out of range error */ - if (regs->gnasts & GNA_STS_PARAM_OOR) { - pending_resp.response.result = - GNA_RESULT_PARAM_OUT_OF_RANGE_ERROR; - } - - /* check for output buffer full error */ - if (regs->gnasts & GNA_STS_BUFFER_FULL) { - pending_resp.response.result = - GNA_RESULT_OUTPUT_BUFFER_FULL_ERROR; - } - - /* check for scoring completion out of range error */ - if (regs->gnasts & GNA_STS_SCORE_COMPL) { - pending_resp.response.result = GNA_RESULT_INFERENCE_COMPLETE; - } - - if (k_msgq_get(&gna->request_queue, &pending_req, K_NO_WAIT) != 0) { - LOG_ERR("Pending request queue is empty"); - } else { - sys_cache_data_invd_range(pending_req.model->output, - pending_req.output_len); - /* copy output from the model buffer to application buffer */ - memcpy(pending_req.output, pending_req.model->output, - pending_req.output_len); - pending_resp.response.output = pending_req.output; - pending_resp.response.output_len = pending_req.output_len; - pending_resp.callback = pending_req.callback; - - pending_resp.response.stats.cycles_per_sec = 200000000U; - if (regs->gnasts & GNA_STS_STATS_VALID) { - pending_resp.response.stats.total_cycles = regs->gnaptc; - pending_resp.response.stats.stall_cycles = regs->gnasc; - } else { - pending_resp.response.stats.total_cycles = 0U; - pending_resp.response.stats.stall_cycles = 0U; - } - - k_msgq_put(&gna->response_queue, &pending_resp, K_NO_WAIT); - - k_work_submit(&gna->gna_work); - } - - /* clear GNA operation and disable interrupt */ - regs->gnactrl |= GNA_CTRL_INTR_DISABLE | GNA_CTRL_ABORT_CLEAR; - gna->state = GNA_STATE_IDLE; -} - -static void gna_work_handler(struct k_work *work) -{ - struct intel_gna_data *gna = (struct intel_gna_data *)work; - struct intel_gna_pending_resp resp; - - while (k_msgq_get(&gna->response_queue, &resp, K_NO_WAIT) == 0) { - resp.callback(&resp.response); - } -} - -static int intel_gna_setup_page_table(void *physical, size_t size, - void *virtual) -{ - uint32_t page; - uint32_t dir_index; - uint32_t table_index; - uint32_t virt_addr = (uint32_t)virtual; - uint32_t phys_addr = (uint32_t)physical; - - LOG_DBG("physical %p size %u virtual %p", physical, size, virtual); - - if (((phys_addr + size - L2_SRAM_BASE) > L2_SRAM_SIZE) || - (phys_addr < L2_SRAM_BASE)) { - LOG_ERR("model at %p of size %u exceeds L2 SRAM space", - physical, size); - return -EINVAL; - } - - dir_index = GNA_VA_PG_DIR(virtual); - table_index = GNA_VA_PG_TABLE(virtual); - - if (dir_index >= GNA_NUM_PG_TABLES_NEEDED) { - LOG_ERR("virtual addr %p is in page dir %u (max %u)", - virtual, dir_index, - (uint32_t)GNA_NUM_PG_TABLES_NEEDED); - return -EINVAL; - } - - for (page = 0U; page < GNA_NUM_PAGES(size); page++) { - dir_index = GNA_VA_PG_DIR(virt_addr); - table_index = GNA_VA_PG_TABLE(virt_addr); - gna_page_table[dir_index].entry[table_index] = - GNA_PG_TABLE_ENTRY(phys_addr); - - LOG_DBG("di %u tb %u @ %p va %08x pa %08x ent %08x", - dir_index, table_index, - &gna_page_table[dir_index].entry[table_index], - virt_addr, phys_addr, - gna_page_table[dir_index].entry[table_index]); - phys_addr += GNA_PG_SIZE_IN_BYTES; - virt_addr += GNA_PG_SIZE_IN_BYTES; - } - - return 0; -} - -static int intel_gna_initialize(const struct device *dev) -{ - struct intel_gna_data *const gna = dev->data; - uint32_t page_dir_entry; - - k_msgq_init(&gna->request_queue, (char *)gna->requests, - sizeof(struct intel_gna_pending_req), - GNA_REQUEST_QUEUE_LEN); - - k_msgq_init(&gna->response_queue, (char *)gna->responses, - sizeof(struct intel_gna_pending_resp), - GNA_REQUEST_QUEUE_LEN); - - k_mem_slab_init(&gna->model_slab, (char *)gna->models, - sizeof(struct intel_gna_model), GNA_MAX_NUM_MODELS); - - k_work_init(&gna->gna_work, gna_work_handler); - - /* initialize the configuration descriptor's page directory table */ - for (int page = 0; page < GNA_CONFIG_DESC_PG_DIR_SIZE; page++) { - page_dir_entry = (page < GNA_NUM_PG_TABLES_NEEDED) ? - GNA_PG_DIR_ENTRY(&gna_page_table[page]) : (uint32_t)-1; - gna_config_desc.pagedir[page] = page_dir_entry; - LOG_DBG("%s: page %u pagetable %08x", - dev->name, page, gna_config_desc.pagedir[page]); - } - gna_config_desc.vamaxaddr = GNA_ADDRESSABLE_MEM_SIZE; - LOG_DBG("%s: max virtual address %08x", - dev->name, gna_config_desc.vamaxaddr); - - /* flush cache */ - sys_cache_data_flush_range((void *)&gna_config_desc, sizeof(gna_config_desc)); - - LOG_INF("%s: initialized (max %u models & max %u pending requests)", - dev->name, GNA_MAX_NUM_MODELS, - GNA_REQUEST_QUEUE_LEN); - LOG_INF("%s: max addressable memory %u MB", - dev->name, GNA_ADDRESSABLE_MEM_SIZE >> 20); - LOG_INF("%s: %u page table(s) at %p and %u bytes", - dev->name, (uint32_t)GNA_NUM_PG_TABLES_NEEDED, - gna_page_table, sizeof(gna_page_table)); - LOG_INF("%s: configuration descriptor at %p", - dev->name, &gna_config_desc); - - /* register interrupt handler */ - IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), - intel_gna_interrupt_handler, DEVICE_GET(gna), 0); - /* enable interrupt */ - irq_enable(INTEL_GNA_IRQ_ID); - - gna->state = GNA_STATE_INITIALIZED; - return 0; -} - -static int intel_gna_configure(const struct device *dev, - struct gna_config *cfg) -{ - struct intel_gna_data *const gna = dev->data; - volatile struct intel_gna_regs *regs = gna->regs; - - if (gna->state != GNA_STATE_INITIALIZED) { - LOG_ERR("Configuration attempt in invalid state (%u)", - gna->state); - return -EINVAL; - } - - if (cfg == NULL) { - LOG_ERR("Config pointer is NULL"); - return -EINVAL; - } - - gna->config = *cfg; - - regs->gnactrl |= GNA_CTRL_OPER_MODEL_XNN | - GNA_CTRL_ERR_INTR_ENABLE | GNA_CTRL_COMPL_INTR_ENABLE; - - switch (CONFIG_INTEL_GNA_POWER_MODE) { - case GNA_POWER_MODE_ALWAYS_ON: - regs->gnactrl |= GNA_CTRL_PM_OVRIDE_CLK_ON | - GNA_CTRL_PM_OVRIDE_PWR_ON; - break; - - case GNA_POWER_MODE_CLOCK_GATED: - regs->gnactrl |= GNA_CTRL_PM_OVRIDE_PWR_ON; - break; - - case GNA_POWER_MODE_POWER_GATED: - case GNA_POWER_MODE_ALWAYS_OFF: - break; - - default: - LOG_ERR("Invalid config CONFIG_INTEL_GNA_POWER_MODE (%u)", - CONFIG_INTEL_GNA_POWER_MODE); - break; - } - - /* assign the configuration descriptor address as the base */ - regs->gnadesbase = GNA_PHYS_ADDR_TO_PAGE(&gna_config_desc); - - INTEL_GNA_CONFIG_DESC_DUMP(dev); - - LOG_INF("Device %s (version %u.%u) configured with power mode %u", - dev->name, regs->gnaversion >> 1, - (uint32_t)(regs->gnaversion & BIT(0)), - CONFIG_INTEL_GNA_POWER_MODE); - - gna->state = GNA_STATE_IDLE; - return 0; -} - -static int intel_gna_register_model(const struct device *dev, - struct gna_model_info *model, - void **model_handle) -{ - struct intel_gna_data *const gna = dev->data; - struct intel_gna_model *gna_model; - struct gna_model_header *header; - uint32_t ro_size, rw_size = 0; - void *virtual_base; - void *ro_region; - - if ((gna->state != GNA_STATE_IDLE) && - (gna->state != GNA_STATE_ACTIVE)) { - LOG_ERR("Invalid state (%u)", gna->state); - return -EINVAL; - } - - if ((model_handle == NULL) || (model == NULL)) { - LOG_ERR("model and/or model_handle is NULL"); - return -EINVAL; - } - - if ((model->header == NULL) || (model->rw_region == NULL)) { - LOG_ERR("model header / rw_region is/are NULL"); - return -EINVAL; - } - - /* check for 64B alignment */ - if (((uint32_t)model->rw_region & BIT_MASK(6)) || - ((uint32_t)model->ro_region & BIT_MASK(6))) { - LOG_ERR("rw_region / ro_region not aligned to 64B"); - return -EINVAL; - } - - if (k_mem_slab_alloc(&gna->model_slab, (void **)&gna_model, - K_NO_WAIT)) { - LOG_ERR("No memory to register model"); - return -ENOMEM; - } - - LOG_INF("model header: %p rw: %p ro: %p", model->header, - model->rw_region, model->ro_region); - - header = model->header; - virtual_base = (void *)GNA_MODEL_VIRT_BASE_DEFAULT; - - LOG_INF("model_size: %u rw_region_size: %u", header->model_size, - header->rw_region_size); - - /* setup page table entries for RW region */ - if (model->rw_region && header->rw_region_size) { - /* calculate layer descriptor size */ - rw_size = header->layer_count * - sizeof(struct intel_gna_layer_desc); - /* round up to page boundary */ - rw_size = GNA_PAGES_TO_BYTES(GNA_NUM_PAGES(rw_size)); - /* add the input rw_region_size to get total rw_region_size */ - rw_size += header->rw_region_size; - - intel_gna_setup_page_table(model->rw_region, rw_size, - virtual_base); - sys_cache_data_flush_range(model->rw_region, rw_size); - } - - if (model->ro_region == NULL) { - ro_region = (void *)((uint32_t)model->rw_region + rw_size); - } else { - ro_region = model->ro_region; - } - - ro_size = header->model_size - rw_size; - - LOG_INF("rw_region: %p (%u) ro_region: %p (%u)", - model->rw_region, rw_size, ro_region, ro_size); - - /* setup page table entries for RO region */ - intel_gna_setup_page_table(ro_region, ro_size, - (void *)((uint32_t)virtual_base + rw_size)); - - sys_cache_data_flush_range(ro_region, ro_size); - sys_cache_data_flush_range(gna_page_table, sizeof(gna_page_table)); - - /* copy the model pointers */ - gna_model->model = *model; - gna_model->vabase = virtual_base; - gna_model->input = (void *)((uint32_t)model->rw_region + - *(uint32_t *)((uint32_t)model->rw_region + - header->input_ptr_offset)); - gna_model->output = (void *)((uint32_t)model->rw_region + - *(uint32_t *)((uint32_t)model->rw_region + - header->output_ptr_offset)); - gna_model->registered = true; - - LOG_INF("model->rw_region: %p", model->rw_region); - LOG_INF("input offset: %u", - *(uint32_t *)((uint32_t)model->rw_region + header->input_ptr_offset)); - LOG_INF("gna_model->input: %p", gna_model->input); - LOG_INF("output offset: %u", - *(uint32_t *)((uint32_t)model->rw_region + - header->output_ptr_offset)); - LOG_INF("gna_model->output: %p", gna_model->output); - LOG_DBG("returning model handle: %p", gna_model); - *model_handle = (void *)gna_model; - return 0; -} - -static int intel_gna_deregister_model(const struct device *dev, - void *model_handle) -{ - struct intel_gna_data *const gna = dev->data; - struct intel_gna_model *gna_model; - - if (model_handle == NULL) { - LOG_ERR("model_handle is NULL"); - return -EINVAL; - } - - gna_model = (struct intel_gna_model *)model_handle; - gna_model->registered = false; - k_mem_slab_free(&gna->model_slab, model_handle); - - return 0; -} - -static int intel_gna_infer(const struct device *dev, - struct gna_inference_req *req, - gna_callback callback) -{ - struct intel_gna_data *const gna = dev->data; - volatile struct intel_gna_regs *regs = gna->regs; - struct intel_gna_pending_req pending_req; - struct gna_model_header *header; - struct intel_gna_model *handle; - struct gna_model_info *model; - size_t input_size; - int ret; - - LOG_DBG("device %p", dev); - if (req == NULL) { - LOG_ERR("Invalid request pointer"); - return -EINVAL; - } - - if (callback == NULL) { - LOG_ERR("Invalid callback function pointer"); - return -EINVAL; - } - - handle = (struct intel_gna_model *)req->model_handle; - - if (handle->registered != true) { - LOG_ERR("Model is not registered. Handle %p", handle); - return -EINVAL; - } - - if (req->input == NULL) { - LOG_ERR("Invalid input buffer"); - return -EINVAL; - } - - if (req->output == NULL) { - LOG_ERR("Invalid output buffer"); - return -EINVAL; - } - - model = &handle->model; - header = model->header; - input_size = header->bytes_per_input * header->num_input_nodes; - - pending_req.model = handle; - pending_req.output = req->output; - pending_req.output_len = header->bytes_per_output * - header->num_output_nodes; - pending_req.callback = callback; - - ret = k_msgq_put(&gna->request_queue, &pending_req, K_NO_WAIT); - if (ret) { - LOG_ERR("Unable to queue request (code %d)", ret); - return ret; - } - - if (gna->state != GNA_STATE_IDLE) { - /* multiple pending requests are not yet supported */ - return -EBUSY; - } - - /* copy input */ - memcpy(handle->input, req->input, input_size); - sys_cache_data_flush_range(handle->input, input_size); - - /* assign layer descriptor base address to configuration descriptor */ - gna_config_desc.labase = (uint32_t)handle->vabase; - gna_config_desc.lacnt = (uint16_t)header->layer_count; - sys_cache_data_flush_range(&gna_config_desc, sizeof(gna_config_desc)); - - gna->state = GNA_STATE_ACTIVE; - regs->gnactrl = (regs->gnactrl & ~GNA_CTRL_INTR_DISABLE) | - GNA_CTRL_ACCEL_START | GNA_CTRL_STATS_ENABLE_STALL; - - return 0; -} - -#if LOG_LEVEL >= LOG_LEVEL_DBG -static void intel_gna_regs_dump(const struct device *dev) -{ - struct intel_gna_data *const gna = dev->data; - volatile struct intel_gna_regs *regs = gna->regs; - - LOG_DBG("gnasts :%08x", regs->gnasts); - LOG_DBG("gnactrl :%08x", regs->gnactrl); - LOG_DBG("gnamctl :%08x", regs->gnamctl); - LOG_DBG("gnaptc :%08x", regs->gnaptc); - LOG_DBG("gnasc :%08x", regs->gnasc); - LOG_DBG("gnaisi :%08x", regs->gnaisi); - LOG_DBG("gnais_low :%08x", regs->gnais_low); - LOG_DBG("gnais_high :%08x", regs->gnais_high); - LOG_DBG("gnabp_low :%08x", regs->gnabp_low); - LOG_DBG("gnabp_high :%08x", regs->gnabp_high); - LOG_DBG("gnadesbase :%08x", regs->gnadesbase); - LOG_DBG("gnaibuffs :%08x", regs->gnaibuffs); - LOG_DBG("ovrcfgctl :%08x", regs->gnaibuffs); - LOG_DBG("gnaversion :%08x", regs->gnaversion); -} - -static void intel_gna_config_desc_dump(const struct device *dev) -{ - struct intel_gna_data *const gna = dev->data; - volatile struct intel_gna_regs *regs = gna->regs; - - LOG_DBG("gnadesbase :%08x", regs->gnadesbase); - LOG_DBG("labase :%08x", gna_config_desc.labase); - LOG_DBG("lacnt :%u", gna_config_desc.lacnt); -} -#endif - -static const struct gna_driver_api gna_driver_api = { - .configure = intel_gna_configure, - .register_model = intel_gna_register_model, - .deregister_model = intel_gna_deregister_model, - .infer = intel_gna_infer, -}; - -static struct intel_gna_data intel_gna_driver_data = { - .regs = (volatile struct intel_gna_regs *)DT_INST_REG_ADDR(0), -}; - -DEVICE_DT_INST_DEFINE(0, intel_gna_initialize, - NULL, - (void *)&intel_gna_driver_data, NULL, - POST_KERNEL, CONFIG_INTEL_GNA_INIT_PRIORITY, - &gna_driver_api); diff --git a/drivers/neural_net/intel_gna.h b/drivers/neural_net/intel_gna.h deleted file mode 100644 index 9b1905ecd88..00000000000 --- a/drivers/neural_net/intel_gna.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation - * - * Author: Sathish Kuttan - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Intel GNA device driver - * - * Device driver implementation for Intel's - * Gaussian Mixture Model and Neural Network Accelerator (GNA) - */ - -#ifndef __INTEL_GNA__ -#define __INTEL_GNA__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* number of requests that could be pending in driver */ -#define GNA_REQUEST_QUEUE_LEN CONFIG_INTEL_GNA_MAX_PENDING_REQUESTS -#define GNA_MAX_NUM_MODELS CONFIG_INTEL_GNA_MAX_MODELS - -/* values must match config values in Kconfig.intel_gna */ -#define GNA_POWER_MODE_ALWAYS_ON 0 -#define GNA_POWER_MODE_CLOCK_GATED 1 -#define GNA_POWER_MODE_POWER_GATED 2 -#define GNA_POWER_MODE_ALWAYS_OFF 3 - -#define INTEL_GNA_BASE_ADDR 0x0000E800 - -#define INTEL_GNA_IRQ_ID 0x00000506 -#define INTEL_GNA_IRQ_PRIORITY 3 - -#define GNA_STS_INTR_PENDING BIT(31) -#define GNA_STS_SATURATION_OCCURRED BIT(17) -#define GNA_STS_BUFFER_FULL BIT(16) -#define GNA_STS_ERROR BIT(15) -#define GNA_STS_PARAM_OOR BIT(8) -#define GNA_STS_VIRT_ADDR_OOR BIT(7) -#define GNA_STS_STATS_VALID BIT(3) -#define GNA_STS_SUSP_PAUSE BIT(2) -#define GNA_STS_SUSP_BREAKP BIT(1) -#define GNA_STS_SCORE_COMPL BIT(0) - -#define GNA_CTRL_INTR_DISABLE BIT(31) -#define GNA_CTRL_PM_IDLE_DISABLE BIT(18) -#define GNA_CTRL_PM_OVRIDE_CLK_ON BIT(17) -#define GNA_CTRL_PM_OVRIDE_PWR_ON BIT(16) -#define GNA_CTRL_STATS_ENABLE_STALL (1 << 12) -#define GNA_CTRL_STATS_MASK (BIT_MASK(4) << 12) -#define GNA_CTRL_ERR_INTR_ENABLE (1 << 10) -#define GNA_CTRL_COMPL_INTR_ENABLE (1 << 8) -#define GNA_CTRL_OPER_MODEL_XNN (1 << 5) -#define GNA_CTRL_ABORT_CLEAR (1 << 2) -#define GNA_CTRL_ACCEL_START (1 << 0) -#define GNA_CTRL_ACCEL_BUSY GNA_CTRL_ACCEL_START - -#define GNA_CONFIG_DESC_PG_DIR_SIZE 64 - -#define GNA_LAYER_DESC_ALIGN (128) - -#define GNA_ADDRESSABLE_MEM_SIZE L2_SRAM_SIZE -#define GNA_NUM_PG_TABLE_INDEX_BITS 10 -#define GNA_NUM_PG_TABLE_ENTRIES BIT(GNA_NUM_PG_TABLE_INDEX_BITS) -#define GNA_PG_SIZE_IN_BITSHIFT 12 -#define GNA_PG_SIZE_IN_BYTES BIT(GNA_PG_SIZE_IN_BITSHIFT) - -#define GNA_SHIFT_RNDUP(value, shift) (((value) + BIT_MASK(shift)) >> (shift)) - -#define GNA_NUM_PAGES(bytes) \ - GNA_SHIFT_RNDUP((bytes), GNA_PG_SIZE_IN_BITSHIFT) - -#define GNA_PAGES_TO_BYTES(pages) ((pages) << GNA_PG_SIZE_IN_BITSHIFT) - -#define GNA_MAX_NUM_PAGES GNA_NUM_PAGES(GNA_ADDRESSABLE_MEM_SIZE) - -#define GNA_NUM_PG_TABLES_NEEDED \ - GNA_SHIFT_RNDUP(GNA_MAX_NUM_PAGES, GNA_NUM_PG_TABLE_INDEX_BITS) - -#if GNA_NUM_PG_TABLES_NEEDED > GNA_CONFIG_DESC_PG_DIR_SIZE -#error GNA_NUM_PG_TABLES_NEEDED exceeds GNA_CONFIG_DESC_PG_DIR_SIZE -#endif - -#define GNA_GET_BITS(val, b_hi, b_lo) ((((uint32_t)(val)) << (31 - (b_hi))) >> \ - (31 - (b_hi) + (b_lo))) - -#define GNA_VA_PG_DIR(virt_addr) GNA_GET_BITS(virt_addr, 27, 22) -#define GNA_VA_PG_TABLE(virt_addr) GNA_GET_BITS(virt_addr, 21, 12) - -#define GNA_PHYS_ADDR_TO_PAGE(addr) ((uint32_t)(addr) >> \ - GNA_PG_SIZE_IN_BITSHIFT) -#define GNA_PG_DIR_ENTRY(phys_addr) GNA_PHYS_ADDR_TO_PAGE(phys_addr) -#define GNA_PG_BASE(addr) ((uint32_t)(addr) & \ - ~BIT_MASK(GNA_PG_SIZE_IN_BITSHIFT)) -#define GNA_PG_OFFSET(addr) ((uint32_t)(addr) & \ - BIT_MASK(GNA_PG_SIZE_IN_BITSHIFT)) -#define GNA_PG_TABLE_ENTRY(phys_addr) GNA_PHYS_ADDR_TO_PAGE(phys_addr) - -struct intel_gna_regs { - uint32_t gnasts; - uint32_t gnactrl; - uint32_t gnamctl; - uint32_t gnaptc; - uint32_t gnasc; - uint32_t gnaisi; - uint32_t gnais_low; - uint32_t gnais_high; - uint32_t gnabp_low; - uint32_t gnabp_high; - uint32_t reserved1[2]; - uint32_t gnadesbase; - uint32_t gnaibuffs; - uint32_t reserved2[2]; - uint32_t ovrcfgctl; - uint32_t reserved3[3]; - uint32_t gnaversion; -}; - -struct intel_gna_config_desc { - uint32_t reserved1[64]; - uint32_t labase; /* layer array base */ - uint16_t lacnt; /* layer array count */ - uint16_t reserved2; - uint32_t reserved3[62]; - uint32_t vamaxaddr; /* virtual address max address */ - uint32_t reserved4[3]; - /* page directory entries */ - uint32_t pagedir[GNA_CONFIG_DESC_PG_DIR_SIZE]; -} __packed; - -struct intel_gna_page_table { - uint32_t entry[GNA_NUM_PG_TABLE_ENTRIES]; -} __aligned(GNA_PG_SIZE_IN_BYTES); - -struct intel_gna_layer_desc { - uint32_t gna_words[8]; - uint32_t inarrayptr; - uint32_t outarrayactptr; - uint32_t outarraysumptr; - uint32_t outfbarrayactptr; - uint32_t wtfltarrayptr; - uint32_t constarrayptr; - uint32_t actoutputslistptr; - uint32_t actfuncsectdefptr; - uint32_t reserved[16]; -} __packed __aligned(GNA_LAYER_DESC_ALIGN); - -struct intel_gna_config { - struct gna_config config; -}; - -struct intel_gna_model { - struct gna_model_info model; - void *input; - void *output; - void *vabase; - bool registered; -}; - -struct intel_gna_pending_req { - struct intel_gna_model *model; - void *output; - size_t output_len; - gna_callback callback; -}; - -struct intel_gna_pending_resp { - struct gna_inference_resp response; - gna_callback callback; -}; - -enum gna_state { - GNA_STATE_UNINITIALIZED, - GNA_STATE_INITIALIZED, - GNA_STATE_IDLE, - GNA_STATE_ACTIVE, -}; - -struct intel_gna_data { - /* - * gna_cb_work must be the first element in the structure - * since it will be typecast as intel_gna_data in the work handler - */ - struct k_work gna_work; - volatile struct intel_gna_regs *regs; - struct k_mem_slab model_slab; - struct intel_gna_model models[GNA_MAX_NUM_MODELS]; - struct k_msgq request_queue; - struct intel_gna_pending_req requests[GNA_REQUEST_QUEUE_LEN]; - struct k_msgq response_queue; - struct intel_gna_pending_resp responses[GNA_REQUEST_QUEUE_LEN]; - enum gna_state state; - - struct gna_config config; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* __INTEL_GNA__ */ diff --git a/dts/bindings/neural_net/intel,gna.yaml b/dts/bindings/neural_net/intel,gna.yaml deleted file mode 100644 index 9d363fededb..00000000000 --- a/dts/bindings/neural_net/intel,gna.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2021 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -description: Intel Gaussian Mixture Model and Neural Network Accelerator (GNA) - -compatible: "intel,gna" - -include: [base.yaml] - -properties: - reg: - required: true - - interrupts: - required: true - - interrupt-parent: - required: true From 927f09c1b62849e04624609b70528dd2f9394f7e Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Thu, 21 Sep 2023 11:53:09 +0100 Subject: [PATCH 0981/4498] ARC: boards: qemu: define vendor properly Set vendor to `snps` to be consistent with vendor in board yaml file. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/qemu_arc/qemu_arc_em.dts | 2 +- boards/arc/qemu_arc/qemu_arc_hs.dts | 2 +- boards/arc/qemu_arc/qemu_arc_hs5x.dts | 2 +- boards/arc/qemu_arc/qemu_arc_hs6x.dts | 2 +- boards/arc/qemu_arc/qemu_arc_hs_xip.dts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/arc/qemu_arc/qemu_arc_em.dts b/boards/arc/qemu_arc/qemu_arc_em.dts index 290f7eb7308..53ec3c2c38f 100644 --- a/boards/arc/qemu_arc/qemu_arc_em.dts +++ b/boards/arc/qemu_arc/qemu_arc_em.dts @@ -10,7 +10,7 @@ / { model = "QEMU ARC EM"; - compatible = "qemu,arcem"; + compatible = "snps,qemu-arcem"; cpus { #address-cells = <1>; diff --git a/boards/arc/qemu_arc/qemu_arc_hs.dts b/boards/arc/qemu_arc/qemu_arc_hs.dts index 751e42ea1ad..0148a83b983 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs.dts +++ b/boards/arc/qemu_arc/qemu_arc_hs.dts @@ -10,7 +10,7 @@ / { model = "QEMU ARC HS"; - compatible = "qemu,archs"; + compatible = "snps,qemu-archs"; cpus { #address-cells = <1>; diff --git a/boards/arc/qemu_arc/qemu_arc_hs5x.dts b/boards/arc/qemu_arc/qemu_arc_hs5x.dts index 3ed53dc2769..dad6f805bc6 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs5x.dts +++ b/boards/arc/qemu_arc/qemu_arc_hs5x.dts @@ -10,7 +10,7 @@ / { model = "QEMU ARC HS"; - compatible = "qemu,archs"; + compatible = "snps,qemu-archs"; cpus { #address-cells = <1>; diff --git a/boards/arc/qemu_arc/qemu_arc_hs6x.dts b/boards/arc/qemu_arc/qemu_arc_hs6x.dts index 751e42ea1ad..0148a83b983 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs6x.dts +++ b/boards/arc/qemu_arc/qemu_arc_hs6x.dts @@ -10,7 +10,7 @@ / { model = "QEMU ARC HS"; - compatible = "qemu,archs"; + compatible = "snps,qemu-archs"; cpus { #address-cells = <1>; diff --git a/boards/arc/qemu_arc/qemu_arc_hs_xip.dts b/boards/arc/qemu_arc/qemu_arc_hs_xip.dts index 3ed53dc2769..dad6f805bc6 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_xip.dts +++ b/boards/arc/qemu_arc/qemu_arc_hs_xip.dts @@ -10,7 +10,7 @@ / { model = "QEMU ARC HS"; - compatible = "qemu,archs"; + compatible = "snps,qemu-archs"; cpus { #address-cells = <1>; From c6f47155546622c0618b2ce9da062130cc1b917d Mon Sep 17 00:00:00 2001 From: Teoh Shi Lin Date: Tue, 22 Nov 2022 17:25:08 +0800 Subject: [PATCH 0982/4498] CODEOWNERS: Add code owener for gpio_altera_pio.c Add code owener for gpio_altera_pio.c Signed-off-by: Teoh Shi Lin --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 52ce1669342..55d05396f7f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -327,6 +327,7 @@ /drivers/gpio/*ads114s0x* @benediktibk /drivers/gpio/*bd8lb600fs* @benediktibk /drivers/gpio/*pcal64xxa* @benediktibk +/drivers/gpio/gpio_altera_pio.c @shilinte /drivers/hwinfo/ @alexanderwachter /drivers/i2c/i2c_common.c @sjg20 /drivers/i2c/i2c_emul.c @sjg20 From d98229c352995d90421958378d2abd997f7d6945 Mon Sep 17 00:00:00 2001 From: Teoh Shi Lin Date: Tue, 22 Nov 2022 13:52:10 +0800 Subject: [PATCH 0983/4498] drivers: gpio: Add ALTERA PIO Add driver for altera avalon pio. Signed-off-by: Teoh Shi Lin --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.altera | 9 + drivers/gpio/gpio_altera_pio.c | 295 ++++++++++++++++++++ dts/bindings/gpio/altr,pio-1.0.yaml | 42 +++ tests/drivers/build_all/gpio/altera.overlay | 37 +++ tests/drivers/build_all/gpio/testcase.yaml | 6 + 7 files changed, 392 insertions(+) create mode 100644 drivers/gpio/Kconfig.altera create mode 100644 drivers/gpio/gpio_altera_pio.c create mode 100644 dts/bindings/gpio/altr,pio-1.0.yaml create mode 100644 tests/drivers/build_all/gpio/altera.overlay diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 60ea5c52fad..b168aa38a5e 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -83,6 +83,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f0e1a63e364..b008da0bd32 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -206,4 +206,6 @@ source "drivers/gpio/Kconfig.efinix_sapphire" source "drivers/gpio/Kconfig.davinci" source "drivers/gpio/Kconfig.sedi" +source "drivers/gpio/Kconfig.altera" + endif # GPIO diff --git a/drivers/gpio/Kconfig.altera b/drivers/gpio/Kconfig.altera new file mode 100644 index 00000000000..2bb03287494 --- /dev/null +++ b/drivers/gpio/Kconfig.altera @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_ALTERA_PIO + bool "Altera PIO" + default y + depends on DT_HAS_ALTR_PIO_1_0_ENABLED + help + Enable driver for Altera PIO diff --git a/drivers/gpio/gpio_altera_pio.c b/drivers/gpio/gpio_altera_pio.c new file mode 100644 index 00000000000..be822adcfa7 --- /dev/null +++ b/drivers/gpio/gpio_altera_pio.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2023, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT altr_pio_1_0 + +#include +#include +#include +#include + +#define ALTERA_AVALON_PIO_DATA_OFFSET 0x00 +#define ALTERA_AVALON_PIO_DIRECTION_OFFSET 0x04 +#define ALTERA_AVALON_PIO_IRQ_OFFSET 0x08 +#define ALTERA_AVALON_PIO_SET_BITS 0x10 +#define ALTERA_AVALON_PIO_CLEAR_BITS 0x14 + +typedef void (*altera_cfg_func_t)(void); + +struct gpio_altera_config { + struct gpio_driver_config common; + uintptr_t reg_base; + uint32_t irq_num; + uint8_t direction; + uint8_t outset; + uint8_t outclear; + altera_cfg_func_t cfg_func; +}; + +struct gpio_altera_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* list of callbacks */ + sys_slist_t cb; + struct k_spinlock lock; +}; + +static bool gpio_pin_direction(const struct device *dev, uint32_t pin_mask) +{ + const struct gpio_altera_config *cfg = dev->config; + const int direction = cfg->direction; + uintptr_t reg_base = cfg->reg_base; + uint32_t addr; + uint32_t pin_direction; + + if (pin_mask == 0) { + return -EINVAL; + } + + /* Check if the direction is Bidirectional */ + if (direction != 0) { + return -EINVAL; + } + + addr = reg_base + ALTERA_AVALON_PIO_DIRECTION_OFFSET; + + pin_direction = sys_read32(addr); + + if (!(pin_direction & pin_mask)) { + return false; + } + + return true; +} + +static int gpio_altera_configure(const struct device *dev, + gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_altera_config *cfg = dev->config; + struct gpio_altera_data * const data = dev->data; + const int port_pin_mask = cfg->common.port_pin_mask; + const int direction = cfg->direction; + uintptr_t reg_base = cfg->reg_base; + k_spinlock_key_t key; + uint32_t addr; + + /* Check if pin number is within range */ + if ((port_pin_mask & BIT(pin)) == 0) { + return -EINVAL; + } + + /* Check if the direction is Bidirectional */ + if (direction != 0) { + return -EINVAL; + } + + addr = reg_base + ALTERA_AVALON_PIO_DIRECTION_OFFSET; + + key = k_spin_lock(&data->lock); + + if (flags == GPIO_INPUT) { + sys_clear_bits(addr, BIT(pin)); + } else if (flags == GPIO_OUTPUT) { + sys_set_bits(addr, BIT(pin)); + } else { + return -EINVAL; + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int gpio_altera_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_altera_config *cfg = dev->config; + uintptr_t reg_base = cfg->reg_base; + uint32_t addr; + + addr = reg_base + ALTERA_AVALON_PIO_DATA_OFFSET; + + *value = sys_read32((addr)); + + return 0; +} + +static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pins_t mask) +{ + const struct gpio_altera_config *cfg = dev->config; + const int outset = cfg->outset; + const int port_pin_mask = cfg->common.port_pin_mask; + uintptr_t reg_base = cfg->reg_base; + uint32_t addr; + + if ((port_pin_mask & mask) == 0) { + return -EINVAL; + } + + if (!gpio_pin_direction(dev, mask)) { + return -EINVAL; + } + + if (outset) { + addr = reg_base + ALTERA_AVALON_PIO_SET_BITS; + sys_write32(mask, addr); + } else { + addr = reg_base + ALTERA_AVALON_PIO_DATA_OFFSET; + sys_set_bits(addr, mask); + } + + return 0; +} + +static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t mask) +{ + const struct gpio_altera_config *cfg = dev->config; + const int outclear = cfg->outclear; + const int port_pin_mask = cfg->common.port_pin_mask; + uintptr_t reg_base = cfg->reg_base; + uint32_t addr; + + /* Check if mask range within 32 */ + if ((port_pin_mask & mask) == 0) { + return -EINVAL; + } + + if (!gpio_pin_direction(dev, mask)) { + return -EINVAL; + } + + if (outclear) { + addr = reg_base + ALTERA_AVALON_PIO_CLEAR_BITS; + sys_write32(mask, addr); + } else { + addr = reg_base + ALTERA_AVALON_PIO_DATA_OFFSET; + sys_clear_bits(addr, mask); + } + + return 0; +} + +static int gpio_init(const struct device *dev) +{ + const struct gpio_altera_config *cfg = dev->config; + + /* Configure GPIO device */ + cfg->cfg_func(); + + return 0; +} + +static int gpio_altera_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + ARG_UNUSED(trig); + + const struct gpio_altera_config *cfg = dev->config; + uintptr_t reg_base = cfg->reg_base; + const int port_pin_mask = cfg->common.port_pin_mask; + uint32_t addr; + + /* Check if pin number is within range */ + if ((port_pin_mask & BIT(pin)) == 0) { + return -EINVAL; + } + + addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET; + + switch (mode) { + case GPIO_INT_MODE_DISABLED: + /* Disable interrupt of pin */ + sys_clear_bits(addr, BIT(pin)); + irq_disable(cfg->irq_num); + break; + case GPIO_INT_MODE_LEVEL: + case GPIO_INT_MODE_EDGE: + /* Enable interrupt of pin */ + sys_set_bits(addr, BIT(pin)); + irq_enable(cfg->irq_num); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int gpio_altera_manage_callback(const struct device *dev, + struct gpio_callback *callback, + bool set) +{ + + struct gpio_altera_data * const data = dev->data; + + return gpio_manage_callback(&data->cb, callback, set); +} + +static void gpio_altera_irq_handler(const struct device *dev) +{ + const struct gpio_altera_config *cfg = dev->config; + struct gpio_altera_data *data = dev->data; + uintptr_t reg_base = cfg->reg_base; + uint32_t port_value; + uint32_t addr; + + addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET; + + port_value = sys_read32(addr); + + sys_clear_bits(addr, port_value); + + /* Call the corresponding callback registered for the pin */ + gpio_fire_callbacks(&data->cb, dev, port_value); +} + +static const struct gpio_driver_api gpio_altera_driver_api = { + .pin_configure = gpio_altera_configure, + .port_get_raw = gpio_altera_port_get_raw, + .port_set_masked_raw = NULL, + .port_set_bits_raw = gpio_altera_port_set_bits_raw, + .port_clear_bits_raw = gpio_altera_port_clear_bits_raw, + .port_toggle_bits = NULL, + .pin_interrupt_configure = gpio_altera_pin_interrupt_configure, + .manage_callback = gpio_altera_manage_callback +}; + +#define CREATE_GPIO_DEVICE(n) \ + static void gpio_altera_cfg_func_##n(void); \ + static struct gpio_altera_data gpio_altera_data_##n; \ + static struct gpio_altera_config gpio_config_##n = { \ + .common = { \ + .port_pin_mask = \ + GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .reg_base = DT_INST_REG_ADDR(n), \ + .direction = DT_INST_ENUM_IDX(n, direction), \ + .irq_num = DT_INST_IRQN(n), \ + .cfg_func = gpio_altera_cfg_func_##n, \ + .outset = DT_INST_PROP(n, outset), \ + .outclear = DT_INST_PROP(n, outclear), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + gpio_init, \ + NULL, \ + &gpio_altera_data_##n, \ + &gpio_config_##n, \ + POST_KERNEL, \ + CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_altera_driver_api); \ + \ + static void gpio_altera_cfg_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + gpio_altera_irq_handler, \ + DEVICE_DT_INST_GET(n), \ + 0); \ + } + +DT_INST_FOREACH_STATUS_OKAY(CREATE_GPIO_DEVICE) diff --git a/dts/bindings/gpio/altr,pio-1.0.yaml b/dts/bindings/gpio/altr,pio-1.0.yaml new file mode 100644 index 00000000000..d9711130e7c --- /dev/null +++ b/dts/bindings/gpio/altr,pio-1.0.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Altera PIO node + +compatible: "altr,pio-1.0" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + direction: + type: string + description: | + Direction can be set to bidir, input, inout or output. + It cannot be configure when during the runtime and should be + set according to the synthesized FPGA design. + default: output + enum: + - "bidir" + - "input" + - "inout" + - "output" + + outset: + type: boolean + description: | + Enable outset register to specify which bit of the output port to set. + + outclear: + type: boolean + description: | + Enable outclear register to specify which output bit to clear. + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/tests/drivers/build_all/gpio/altera.overlay b/tests/drivers/build_all/gpio/altera.overlay new file mode 100644 index 00000000000..2d92889aff4 --- /dev/null +++ b/tests/drivers/build_all/gpio/altera.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_int_gpio { + #address-cells = <1>; + #size-cells = <1>; + test_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = < 0x0 >; + #interrupt-cells = < 0x1 >; + interrupt-controller; + phandle = < 0x1 >; + }; + + test_gpio0: gpio@30070 { + interrupt-parent = < &test_intc >; + compatible = "altr,pio-1.0"; + reg = < 0x30070 0x10 >; + gpio-controller; + #gpio-cells = < 0x2 >; + status = "okay"; + ngpios = < 16 >; + #direction = "input"; + interrupts = <28>; + }; + }; + }; + +}; diff --git a/tests/drivers/build_all/gpio/testcase.yaml b/tests/drivers/build_all/gpio/testcase.yaml index bd720d569d5..a95b4625725 100644 --- a/tests/drivers/build_all/gpio/testcase.yaml +++ b/tests/drivers/build_all/gpio/testcase.yaml @@ -17,3 +17,9 @@ tests: platform_allow: titanium_ti60_f225 depends_on: gpio extra_args: DTC_OVERLAY_FILE="efinix_sapphire.overlay" + + drivers.gpio.build.altera_pio: + min_ram: 32 + platform_allow: niosv_m niosv_g + depends_on: gpio + extra_args: DTC_OVERLAY_FILE="altera.overlay" From 11a8c5cd9ed868f4421b0d5222f22ce120b27f2e Mon Sep 17 00:00:00 2001 From: Teoh Shi Lin Date: Tue, 31 Jan 2023 18:01:34 +0800 Subject: [PATCH 0984/4498] drivers: gpio: altera_pio: enhancement update to make interrupt optional since they are not always available Signed-off-by: Teoh Shi Lin --- drivers/gpio/gpio_altera_pio.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio_altera_pio.c b/drivers/gpio/gpio_altera_pio.c index be822adcfa7..1b9fac462d6 100644 --- a/drivers/gpio/gpio_altera_pio.c +++ b/drivers/gpio/gpio_altera_pio.c @@ -198,6 +198,10 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev, return -EINVAL; } + if (!gpio_pin_direction(dev, BIT(pin))) { + return -EINVAL; + } + addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET; switch (mode) { @@ -258,6 +262,12 @@ static const struct gpio_driver_api gpio_altera_driver_api = { .manage_callback = gpio_altera_manage_callback }; +#define GPIO_CFG_IRQ(idx, n) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, priority), \ + DT_INST_IRQ(n, priority), (0)), gpio_altera_irq_handler, \ + DEVICE_DT_INST_GET(n), 0); \ + #define CREATE_GPIO_DEVICE(n) \ static void gpio_altera_cfg_func_##n(void); \ static struct gpio_altera_data gpio_altera_data_##n; \ @@ -268,7 +278,7 @@ static const struct gpio_driver_api gpio_altera_driver_api = { }, \ .reg_base = DT_INST_REG_ADDR(n), \ .direction = DT_INST_ENUM_IDX(n, direction), \ - .irq_num = DT_INST_IRQN(n), \ + .irq_num = COND_CODE_1(DT_INST_IRQ_HAS_IDX(n, 0), (DT_INST_IRQN(n)), (0)),\ .cfg_func = gpio_altera_cfg_func_##n, \ .outset = DT_INST_PROP(n, outset), \ .outclear = DT_INST_PROP(n, outclear), \ @@ -285,11 +295,7 @@ static const struct gpio_driver_api gpio_altera_driver_api = { \ static void gpio_altera_cfg_func_##n(void) \ { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - gpio_altera_irq_handler, \ - DEVICE_DT_INST_GET(n), \ - 0); \ + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), GPIO_CFG_IRQ, (), n)\ } DT_INST_FOREACH_STATUS_OKAY(CREATE_GPIO_DEVICE) From 029e7560098e14741ac6bb09831d74c09c8eaf39 Mon Sep 17 00:00:00 2001 From: Goh Shun Jing Date: Fri, 4 Aug 2023 19:11:04 +0800 Subject: [PATCH 0985/4498] drivers: gpio: altera_pio add spinlock Add spinlock for write access to register Signed-off-by: Goh Shun Jing --- drivers/gpio/gpio_altera_pio.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_altera_pio.c b/drivers/gpio/gpio_altera_pio.c index 1b9fac462d6..d85c63d3245 100644 --- a/drivers/gpio/gpio_altera_pio.c +++ b/drivers/gpio/gpio_altera_pio.c @@ -111,6 +111,10 @@ static int gpio_altera_port_get_raw(const struct device *dev, uint32_t *value) addr = reg_base + ALTERA_AVALON_PIO_DATA_OFFSET; + if (value == NULL) { + return -EINVAL; + } + *value = sys_read32((addr)); return 0; @@ -119,10 +123,12 @@ static int gpio_altera_port_get_raw(const struct device *dev, uint32_t *value) static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pins_t mask) { const struct gpio_altera_config *cfg = dev->config; - const int outset = cfg->outset; + struct gpio_altera_data * const data = dev->data; + const uint8_t outset = cfg->outset; const int port_pin_mask = cfg->common.port_pin_mask; uintptr_t reg_base = cfg->reg_base; uint32_t addr; + k_spinlock_key_t key; if ((port_pin_mask & mask) == 0) { return -EINVAL; @@ -132,6 +138,8 @@ static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pin return -EINVAL; } + key = k_spin_lock(&data->lock); + if (outset) { addr = reg_base + ALTERA_AVALON_PIO_SET_BITS; sys_write32(mask, addr); @@ -140,16 +148,20 @@ static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pin sys_set_bits(addr, mask); } + k_spin_unlock(&data->lock, key); + return 0; } static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t mask) { const struct gpio_altera_config *cfg = dev->config; - const int outclear = cfg->outclear; + struct gpio_altera_data * const data = dev->data; + const uint8_t outclear = cfg->outclear; const int port_pin_mask = cfg->common.port_pin_mask; uintptr_t reg_base = cfg->reg_base; uint32_t addr; + k_spinlock_key_t key; /* Check if mask range within 32 */ if ((port_pin_mask & mask) == 0) { @@ -160,6 +172,8 @@ static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_p return -EINVAL; } + key = k_spin_lock(&data->lock); + if (outclear) { addr = reg_base + ALTERA_AVALON_PIO_CLEAR_BITS; sys_write32(mask, addr); @@ -168,6 +182,8 @@ static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_p sys_clear_bits(addr, mask); } + k_spin_unlock(&data->lock, key); + return 0; } @@ -189,9 +205,11 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev, ARG_UNUSED(trig); const struct gpio_altera_config *cfg = dev->config; + struct gpio_altera_data * const data = dev->data; uintptr_t reg_base = cfg->reg_base; const int port_pin_mask = cfg->common.port_pin_mask; uint32_t addr; + k_spinlock_key_t key; /* Check if pin number is within range */ if ((port_pin_mask & BIT(pin)) == 0) { @@ -204,6 +222,8 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev, addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET; + key = k_spin_lock(&data->lock); + switch (mode) { case GPIO_INT_MODE_DISABLED: /* Disable interrupt of pin */ @@ -220,6 +240,8 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev, return -EINVAL; } + k_spin_unlock(&data->lock, key); + return 0; } @@ -240,13 +262,18 @@ static void gpio_altera_irq_handler(const struct device *dev) uintptr_t reg_base = cfg->reg_base; uint32_t port_value; uint32_t addr; + k_spinlock_key_t key; addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET; + key = k_spin_lock(&data->lock); + port_value = sys_read32(addr); sys_clear_bits(addr, port_value); + k_spin_unlock(&data->lock, key); + /* Call the corresponding callback registered for the pin */ gpio_fire_callbacks(&data->cb, dev, port_value); } From 11f0e59d1900dd23fc573e9e53af3b61ef36fc55 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 16 Aug 2023 14:56:53 +0300 Subject: [PATCH 0986/4498] drivers: wdt_tco: Use DT_DRV_COMPAT interface DT_DRV_COMPAT was unused for this driver. To get a node identifier DT_NODELABEL() macro was used. Refactor to use the correct interfaces using instance number 0. Signed-off-by: Andrei Emeltchenko --- drivers/watchdog/wdt_tco.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/watchdog/wdt_tco.c b/drivers/watchdog/wdt_tco.c index bc0e95386f2..599871bc5f0 100644 --- a/drivers/watchdog/wdt_tco.c +++ b/drivers/watchdog/wdt_tco.c @@ -11,8 +11,6 @@ LOG_MODULE_REGISTER(wdt_tco, CONFIG_WDT_LOG_LEVEL); -#define TCO_WDT_NODE DT_NODELABEL(tco_wdt) - #define BASE(d) ((struct tco_config *)(d)->config)->base #define TCO_RLD(d) (BASE(d) + 0x00) /* TCO Timer Reload/Curr. Value */ @@ -267,9 +265,9 @@ static struct tco_data wdt_data = { }; static const struct tco_config wdt_config = { - .base = DT_REG_ADDR(TCO_WDT_NODE), + .base = DT_INST_REG_ADDR(0), }; -DEVICE_DT_DEFINE(TCO_WDT_NODE, wdt_init, NULL, &wdt_data, &wdt_config, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &tco_driver_api); +DEVICE_DT_INST_DEFINE(0, wdt_init, NULL, &wdt_data, &wdt_config, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &tco_driver_api); From 50462228f212ce8bfa03f2357a63533e69a32366 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Wed, 13 Sep 2023 17:56:57 +1000 Subject: [PATCH 0987/4498] drivers: adc: shell: fix - read result is signed Previously negative read results were being printed by the shell as large uint16_t. Signed-off-by: Nick Ward --- drivers/adc/adc_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index 4aa9209ae5f..a0174cb062b 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -305,7 +305,7 @@ static int cmd_adc_read(const struct shell *sh, size_t argc, char **argv) uint8_t adc_channel_id = strtol(argv[1], NULL, 10); /* -1 index of adc label name */ struct adc_hdl *adc = get_adc(argv[-1]); - uint16_t m_sample_buffer[BUFFER_SIZE]; + int16_t m_sample_buffer[BUFFER_SIZE]; int retval; if (!device_is_ready(adc->dev)) { From f2af46aaa081d77edb34f7fe764236fe10c5d282 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Wed, 13 Sep 2023 22:24:09 +1000 Subject: [PATCH 0988/4498] drivers: adc: shell: remove \n from logs Remove \n from logs. Signed-off-by: Nick Ward --- drivers/adc/adc_shell.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index a0174cb062b..bba6a4f46e2 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -133,7 +133,7 @@ static int cmd_adc_ch_id(const struct shell *sh, size_t argc, char **argv) adc->channel_config.channel_id = (uint8_t)strtol(argv[1], NULL, 10); retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; } @@ -157,7 +157,7 @@ static int cmd_adc_ch_neg(const struct shell *sh, size_t argc, char **argv) adc->channel_config.input_negative = (uint8_t)strtol(argv[1], NULL, 10); retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; #else @@ -184,7 +184,7 @@ static int cmd_adc_ch_pos(const struct shell *sh, size_t argc, char **argv) adc->channel_config.input_positive = (uint8_t)strtol(argv[1], NULL, 10); retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; #else @@ -211,7 +211,7 @@ static int cmd_adc_gain(const struct shell *sh, size_t argc, char **argv, memcpy(chosen_gain, argv[0], len); chosen_gain[len] = '\0'; retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; } @@ -248,7 +248,7 @@ static int cmd_adc_acq(const struct shell *sh, size_t argc, char **argv) ADC_ACQ_TIME_DEFAULT; } retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; } @@ -294,7 +294,7 @@ static int cmd_adc_ref(const struct shell *sh, size_t argc, char **argv, adc->channel_config.reference = reference; retval = adc_channel_setup(adc->dev, &adc->channel_config); - LOG_DBG("Channel setup returned %i\n", retval); + LOG_DBG("Channel setup returned %i", retval); return retval; } From 4fe5beb2c5ae2bb44151a895c60c000a53421271 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Wed, 13 Sep 2023 22:16:13 +1000 Subject: [PATCH 0989/4498] drivers: adc: shell: add differential command Add differential command. Signed-off-by: Nick Ward --- drivers/adc/adc_shell.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index bba6a4f46e2..2069b97b5ec 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -28,6 +28,10 @@ LOG_MODULE_REGISTER(adc_shell); "Configure channel id\n" \ "Usage: id \n" +#define CMD_HELP_DIFF \ + "Configure differential\n" \ + "Usage: differential <0||1>\n" + #define CMD_HELP_CH_NEG \ "Configure channel negative input\n" \ "Usage: negative \n" @@ -138,6 +142,33 @@ static int cmd_adc_ch_id(const struct shell *sh, size_t argc, char **argv) return retval; } +static int cmd_adc_ch_diff(const struct shell *sh, size_t argc, char **argv) +{ + /* -2: index of ADC label name */ + struct adc_hdl *adc = get_adc(argv[-2]); + int retval = 0; + char *endptr; + long diff; + + if (!device_is_ready(adc->dev)) { + shell_error(sh, "ADC device not ready"); + return -ENODEV; + } + + endptr = argv[1]; + diff = strtol(argv[1], &endptr, 10); + if ((endptr == argv[1]) || ((diff != 0) && (diff != 1))) { + shell_error(sh, " must be 0 or 1"); + return -EINVAL; + } + + adc->channel_config.differential = (uint8_t)diff; + retval = adc_channel_setup(adc->dev, &adc->channel_config); + LOG_DBG("Channel setup returned %i", retval); + + return retval; +} + static int cmd_adc_ch_neg(const struct shell *sh, size_t argc, char **argv) { #if CONFIG_ADC_CONFIGURABLE_INPUTS @@ -339,13 +370,23 @@ static int cmd_adc_print(const struct shell *sh, size_t argc, char **argv) "Reference: %s\n" "Acquisition Time: %u\n" "Channel ID: %u\n" + "Differential: %u\n" "Resolution: %u", adc->dev->name, chosen_gain, chosen_reference, adc->channel_config.acquisition_time, adc->channel_config.channel_id, + adc->channel_config.differential, adc->resolution); +#if CONFIG_ADC_CONFIGURABLE_INPUTS + shell_print(sh, "Input positive: %u", + adc->channel_config.input_positive); + if (adc->channel_config.differential != 0) { + shell_print(sh, "Input negative: %u", + adc->channel_config.input_negative); + } +#endif return 0; } @@ -378,6 +419,7 @@ SHELL_SUBCMD_DICT_SET_CREATE(sub_gain_cmds, cmd_adc_gain, SHELL_STATIC_SUBCMD_SET_CREATE(sub_channel_cmds, SHELL_CMD_ARG(id, NULL, CMD_HELP_CH_ID, cmd_adc_ch_id, 2, 0), + SHELL_CMD_ARG(differential, NULL, CMD_HELP_DIFF, cmd_adc_ch_diff, 2, 0), SHELL_COND_CMD_ARG(CONFIG_ADC_CONFIGURABLE_INPUTS, negative, NULL, CMD_HELP_CH_NEG, cmd_adc_ch_neg, 2, 0), SHELL_COND_CMD_ARG(CONFIG_ADC_CONFIGURABLE_INPUTS, From e4cc5838fd8f32ffa73b808a9a6505bb1b0ae6a9 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 17 Aug 2023 01:55:58 +0530 Subject: [PATCH 0990/4498] Bluetooth: Controller: Fix PHY value in HCI LE CIS Established Event Fix PHY_C_TO_P and PHY_P_TO_C value in HCI LE CIS Established Event. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/hci/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 30fb363fc9c..0adbf5ff70c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -4245,8 +4245,8 @@ static void le_cis_established(struct pdu_data *pdu_data, sys_put_le24(cis->sync_delay, sep->cis_sync_delay); sys_put_le24(cig->c_latency, sep->c_latency); sys_put_le24(cig->p_latency, sep->p_latency); - sep->c_phy = lll_cis_c->phy; - sep->p_phy = lll_cis_p->phy; + sep->c_phy = find_lsb_set(lll_cis_c->phy); + sep->p_phy = find_lsb_set(lll_cis_p->phy); sep->nse = lll_cis->nse; sep->c_bn = lll_cis_c->bn; sep->p_bn = lll_cis_p->bn; From cb28104cb08b5f9f86d043bbc8bf9bac1347c693 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 19 Aug 2023 21:29:56 +0530 Subject: [PATCH 0991/4498] Bluetooth: Controller: Fix assertion due to late PER CIS active set Fix assertion due to late Peripheral CIS active flag being initialized. CIS active flag shall be initialized when it is acquired. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index d45d89aa009..f68ca66656f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -250,7 +250,8 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->p_max_sdu = (uint16_t)(req->p_max_sdu[1] & 0x0F) << 8 | req->p_max_sdu[0]; - cis->lll.handle = 0xFFFF; + cis->lll.active = 0U; + cis->lll.handle = LLL_HANDLE_INVALID; cis->lll.acl_handle = acl->lll.handle; cis->lll.sub_interval = sys_get_le24(req->sub_interval); cis->lll.nse = req->nse; @@ -325,7 +326,6 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, cis->lll.cie = 0U; cis->lll.npi = 0U; cis->lll.flush = LLL_CIS_FLUSH_NONE; - cis->lll.active = 0U; cis->lll.datapath_ready_rx = 0U; cis->lll.tx.payload_count = 0U; cis->lll.rx.payload_count = 0U; From 94bd4837bbdc2036b60325772830fbe8c08f6870 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 20 Aug 2023 10:48:43 +0530 Subject: [PATCH 0992/4498] Bluetooth: Controller: Fix missing host feature reset Fix missing host feature reset on HCI reset command. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ll_feat.c | 5 +++++ subsys/bluetooth/controller/ll_sw/ll_feat_internal.h | 7 +++++++ subsys/bluetooth/controller/ll_sw/ull.c | 7 ++++++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 subsys/bluetooth/controller/ll_sw/ll_feat_internal.h diff --git a/subsys/bluetooth/controller/ll_sw/ll_feat.c b/subsys/bluetooth/controller/ll_sw/ll_feat.c index a1aaa99ba6d..d2ba2fefba0 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_feat.c +++ b/subsys/bluetooth/controller/ll_sw/ll_feat.c @@ -70,6 +70,11 @@ uint8_t ll_set_host_feature(uint8_t bit_number, uint8_t bit_value) return BT_HCI_ERR_SUCCESS; } +void ll_feat_reset(void) +{ + host_features = 0U; +} + uint64_t ll_feat_get(void) { return LL_FEAT | (host_features & LL_FEAT_HOST_BIT_MASK); diff --git a/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h b/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h new file mode 100644 index 00000000000..7c23cb1a4e5 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void ll_feat_reset(void); diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 3f60290dba3..916b21cee31 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -44,6 +44,7 @@ #include "lll_sync_iso.h" #include "lll_iso_tx.h" #include "lll_conn.h" +#include "lll_conn_iso.h" #include "lll_df.h" #include "ull_adv_types.h" @@ -60,6 +61,7 @@ #endif /* CONFIG_BT_CTLR_USER_EXT */ #include "isoal.h" +#include "ll_feat_internal.h" #include "ull_internal.h" #include "ull_iso_internal.h" #include "ull_adv_internal.h" @@ -69,7 +71,6 @@ #include "ull_central_internal.h" #include "ull_iso_types.h" #include "ull_conn_internal.h" -#include "lll_conn_iso.h" #include "ull_conn_iso_types.h" #include "ull_central_iso_internal.h" #include "ull_llcp.h" @@ -899,6 +900,10 @@ void ll_reset(void) LL_ASSERT(!err); #endif +#if defined(CONFIG_BT_CTLR_SET_HOST_FEATURE) + ll_feat_reset(); +#endif /* CONFIG_BT_CTLR_SET_HOST_FEATURE */ + /* clear static random address */ (void)ll_addr_set(1U, NULL); } From c7c3c82aa0104c7063879d8d4a27a0d5c6b29c0a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 08:45:38 +0200 Subject: [PATCH 0993/4498] soc nordic_nrf: Select new compatible kconfig options Select the newly introduced nrf53 compatible kconfig options. These are common both for real HW and for simulated HW, allowing SW to behave appropriately for both. Signed-off-by: Alberto Escolar Piedras --- soc/arm/nordic_nrf/nrf53/Kconfig.series | 1 + soc/arm/nordic_nrf/nrf53/Kconfig.soc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.series b/soc/arm/nordic_nrf/nrf53/Kconfig.series index 03e47bacf63..8ab81ad310b 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.series @@ -6,6 +6,7 @@ config SOC_SERIES_NRF53X bool "Nordic Semiconductor nRF53 series MCU" select ARM + select SOC_COMPATIBLE_NRF53X select CPU_CORTEX_M33 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 122c36988e5..632b754bdc1 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -10,10 +10,12 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_FPU select ARMV8_M_DSP select HAS_POWEROFF + select SOC_COMPATIBLE_NRF5340_CPUAPP config SOC_NRF5340_CPUNET bool select ARM_ON_EXIT_CPU_IDLE + select SOC_COMPATIBLE_NRF5340_CPUNET imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED choice From bab4ed16238e74f089932819de2edf3cbc1fc6c9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 08:57:08 +0200 Subject: [PATCH 0994/4498] Bluetooth controller: nrf: Switch to use SOC_COMPATIBLE Switch use of kconfig: * SOC_SERIES_NRF53X -> SOC_COPATIBLE_NRF53X * SOC_NRF5340_CPUNET -> SOC_COMPATIBLE_NRF5340_CPUNET to also select those options/code when building for the nrf53 simulated targets. Also switch three kconfig range dependencies from SOC_SERIES_NRF52X to SOC_COPATIBLE_NRF52X (IRQ priority related) for consistency. These sound not really have an impact. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/controller/Kconfig.ll_sw_split | 10 +-- .../controller/hci/nordic/hci_vendor.h | 2 +- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 72 +++++++++---------- .../nrf5/radio/radio_nrf5_dppi_resources.h | 4 +- .../controller/ll_sw/nordic/hal/nrf5/swi.h | 8 +-- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 1fa9031d47f..4cd8e200b63 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -643,7 +643,7 @@ config BT_CTLR_SLOT_RESERVATION_UPDATE config BT_CTLR_LLL_PRIO int "Lower Link Layer (Radio) IRQ priority" if (BT_CTLR_ULL_LLL_PRIO_SUPPORT && !BT_CTLR_ZLI) range 0 3 if SOC_SERIES_NRF51X - range 0 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) + range 0 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default 0 help The interrupt priority for event preparation and radio IRQ. @@ -651,7 +651,7 @@ config BT_CTLR_LLL_PRIO config BT_CTLR_ULL_HIGH_PRIO int "Upper Link Layer High IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT range BT_CTLR_LLL_PRIO 3 if SOC_SERIES_NRF51X - range BT_CTLR_LLL_PRIO 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) + range BT_CTLR_LLL_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default BT_CTLR_LLL_PRIO if (!BT_CTLR_ULL_LLL_PRIO_SUPPORT || BT_CTLR_ZLI || BT_CTLR_LOW_LAT) default 1 help @@ -661,7 +661,7 @@ config BT_CTLR_ULL_HIGH_PRIO config BT_CTLR_ULL_LOW_PRIO int "Upper Link Layer Low IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT range BT_CTLR_ULL_HIGH_PRIO 3 if SOC_SERIES_NRF51X - range BT_CTLR_ULL_HIGH_PRIO 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) + range BT_CTLR_ULL_HIGH_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default BT_CTLR_ULL_HIGH_PRIO help The interrupt priority for Ticker's Job IRQ and Upper Link Layer @@ -705,7 +705,7 @@ config BT_CTLR_RX_PDU_META config BT_CTLR_RADIO_ENABLE_FAST bool "Use tTXEN/RXEN,FAST ramp-up" - depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X + depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X default y help Enable use of fast radio ramp-up mode. @@ -719,7 +719,7 @@ config BT_CTLR_TIFS_HW config BT_CTLR_SW_SWITCH_SINGLE_TIMER bool "Single TIMER tIFS Trx SW switching" - depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X) + depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) help Implement the tIFS Trx SW switch with the same TIMER instance, as the one used for BLE event timing. Requires diff --git a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h index 4d3245728ed..bea7004f9c9 100644 --- a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h +++ b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h @@ -10,7 +10,7 @@ #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF51X #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF52X -#elif defined(CONFIG_SOC_SERIES_NRF53X) +#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF53X #endif #else diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 1875dca7896..3fc76a27bdf 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -311,7 +311,7 @@ void radio_phy_set(uint8_t phy, uint8_t flags) void radio_tx_power_set(int8_t power) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) uint32_t value; /* NOTE: TXPOWER register only accepts upto 0dBm, hence use the HAL @@ -322,12 +322,12 @@ void radio_tx_power_set(int8_t power) NRF_RADIO->TXPOWER = value; hal_radio_tx_power_high_voltage_set(power); -#else /* !CONFIG_SOC_SERIES_NRF53X */ +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ /* NOTE: valid value range is passed by Kconfig define. */ NRF_RADIO->TXPOWER = (uint32_t)power; -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } void radio_tx_power_max_set(void) @@ -345,25 +345,25 @@ int8_t radio_tx_power_min_get(void) int8_t radio_tx_power_max_get(void) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) return RADIO_TXPOWER_TXPOWER_Pos3dBm; -#else /* !CONFIG_SOC_SERIES_NRF53X */ +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ return (int8_t)hal_radio_tx_power_max_get(); -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } int8_t radio_tx_power_floor(int8_t power) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* NOTE: TXPOWER register only accepts upto 0dBm, +3dBm permitted by * use of high voltage being set for radio when TXPOWER register is set. */ if (power >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { return RADIO_TXPOWER_TXPOWER_Pos3dBm; } -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ return (int8_t)hal_radio_tx_power_floor(power); } @@ -413,7 +413,7 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) bits_s1 = RADIO_PKT_CONF_LENGTH_8BIT - bits_len; #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ - defined(CONFIG_SOC_SERIES_NRF53X) + defined(CONFIG_SOC_COMPATIBLE_NRF53X) extra = 0U; phy = RADIO_PKT_CONF_PHY_GET(flags); @@ -510,7 +510,7 @@ uint32_t radio_rx_chain_delay_get(uint8_t phy, uint8_t flags) void radio_rx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -523,7 +523,7 @@ void radio_rx_enable(void) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN); @@ -532,7 +532,7 @@ void radio_rx_enable(void) void radio_tx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -545,7 +545,7 @@ void radio_tx_enable(void) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN); @@ -891,13 +891,13 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla * time-stamp. */ hal_radio_end_time_capture_ppi_config(); -#if !defined(CONFIG_SOC_SERIES_NRF53X) +#if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* The function is not called for nRF5340 single timer configuration because * HAL_SW_SWITCH_TIMER_CLEAR_PPI is equal to HAL_RADIO_END_TIME_CAPTURE_PPI, * so channel is already enabled. */ hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ sw_tifs_toggle += 1U; @@ -1186,38 +1186,38 @@ void radio_tmr_rx_status_reset(void) void radio_tmr_tx_enable(void) { -#if defined(CONFIG_SOC_SERIES_NRF53X) -#else /* !CONFIG_SOC_SERIES_NRF53X */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(1U); #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */ -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } void radio_tmr_rx_enable(void) { -#if defined(CONFIG_SOC_SERIES_NRF53X) -#else /* !CONFIG_SOC_SERIES_NRF53X */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(0U); #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */ -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } void radio_tmr_tx_disable(void) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); -#else /* !CONFIG_SOC_SERIES_NRF53X */ -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } void radio_tmr_rx_disable(void) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); -#else /* !CONFIG_SOC_SERIES_NRF53X */ -#endif /* !CONFIG_SOC_SERIES_NRF53X */ +#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ } void radio_tmr_tifs_set(uint32_t tifs) @@ -1304,7 +1304,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) last_pdu_end_us = 0U; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1317,7 +1317,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ return remainder_us; @@ -1331,7 +1331,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) last_pdu_end_us = 0U; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1344,7 +1344,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ /* start_us could be the current count in the timer */ @@ -1464,12 +1464,12 @@ void radio_tmr_end_capture(void) * hal_sw_switch_timer_clear_ppi_config() and sw_switch(). There is no need to * configure the channel again in this function. */ -#if !defined(CONFIG_SOC_SERIES_NRF53X) || \ - (defined(CONFIG_SOC_SERIES_NRF53X) && !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) +#if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \ + (defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) hal_radio_end_time_capture_ppi_config(); hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); -#endif /* !CONFIG_SOC_SERIES_NRF53X || - * (CONFIG_SOC_SERIES_NRF53X && !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X || + * (CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) */ } @@ -1776,7 +1776,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; -#if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* Enable CCM support for 8-bit length field PDUs. */ mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h index 74fb56d9b5c..e1b47d03fd7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_NRF5340_CPUNET) || defined(DPPI_PRESENT) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(DPPI_PRESENT) /******************************************************************************* * Enable Radio on Event Timer tick: @@ -157,4 +157,4 @@ #define SW_SWITCH_TIMER_TASK_GROUP_BASE 0 #endif /* !CONFIG_BT_CTLR_TIFS_HW */ -#endif /* CONFIG_SOC_NRF5340_CPUNET || DPPI_PRESENT */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET || DPPI_PRESENT */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h index eb9da5652ff..6b364fd349a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h @@ -18,10 +18,10 @@ #endif /* nRF53 Series IRQ mapping */ -#elif defined(CONFIG_SOC_SERIES_NRF53X) +#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* nRF53 Series Engineering D and Revision 1 IRQ mapping */ -#if defined(CONFIG_SOC_NRF5340_CPUNET) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) #define HAL_SWI_RADIO_IRQ SWI2_IRQn #define HAL_SWI_WORKER_IRQ RTC0_IRQn @@ -33,9 +33,9 @@ #define HAL_SWI_JOB_IRQ SWI3_IRQn #endif -#endif /* CONFIG_SOC_NRF5340_CPUNET */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET */ -#endif /* CONFIG_SOC_SERIES_NRF53X */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ static inline void hal_swi_init(void) { From f1557804a93d61b0effe9f513985c0159144da79 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 09:21:27 +0200 Subject: [PATCH 0995/4498] Bluetooth controller nrf: ifdef some coded phy only code To avoid a build error when coded phy is not enabled for a nrf53: These three functions are only used for coded phy, and depend on macros which are only defined if coded phy is enabled. Signed-off-by: Alberto Escolar Piedras --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 71e5ffa0e6f..9ed66dc3442 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -551,6 +551,7 @@ static inline void hal_radio_sw_switch_cleanup(void) nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(1)); } +#if defined(CONFIG_BT_CTLR_PHY_CODED) static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index) { @@ -612,6 +613,7 @@ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( ppi_dis); } +#endif /* defined(CONFIG_BT_CTLR_PHY_CODED) */ static inline void hal_radio_sw_switch_ppi_group_setup(void) { From bae0dace163eddd6c60963d4cf3267125186fd99 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 09:50:56 +0200 Subject: [PATCH 0996/4498] Bluetooth controller nrf: Rename bsim radio hal header Rename the bsim header in preparation for having more simulated targets. Signed-off-by: Alberto Escolar Piedras --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 4 ++-- .../hal/nrf5/radio/{radio_sim_nrfxx.h => radio_sim_nrf52.h} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/{radio_sim_nrfxx.h => radio_sim_nrf52.h} (100%) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index a03e55f519d..9e29ab5f70b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -15,8 +15,8 @@ #define HAL_RADIO_NS2US_ROUND(ns) ((ns + 500)/1000) /* SoC specific defines */ -#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) -#include "radio_sim_nrfxx.h" +#if defined(CONFIG_BOARD_NRF52_BSIM) +#include "radio_sim_nrf52.h" #elif defined(CONFIG_SOC_SERIES_NRF51X) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrfxx.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h similarity index 100% rename from subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrfxx.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h From 663a54c6d50557906635065f75bb4af2a135feb9 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 21 Sep 2023 12:24:16 +0200 Subject: [PATCH 0997/4498] doc: Bluetooth: Mesh: Remove "draft" word from mesh 1.1 spec The specification is now adopted. Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 6adb9fb6267..6e2fca1b111 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -7,7 +7,7 @@ The Bluetooth mesh profile adds secure wireless multi-hop communication for Bluetooth Low Energy. This module implements the `Bluetooth Mesh Profile Specification v1.0.1 `_. -Implementation of the draft `Bluetooth Mesh Protocol Specification v1.1 `_ +Implementation of the `Bluetooth Mesh Protocol Specification v1.1 `_ is in experimental state. Read more about Bluetooth mesh on the From 1146f5a8ea25d36bec5c8c15a8e0fd3d4a3fc684 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 21 Sep 2023 12:27:11 +0200 Subject: [PATCH 0998/4498] doc: Bluetooth: Mesh: Fix note rendering Fix tabulation for correct note rendering. Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/access.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index d34b0078d81..151e74add28 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -170,12 +170,12 @@ Composition Data .. note:: - The implementation of the Bluetooth Mesh Protocol Specification version 1.1 - is currently in an experimental state. For Bluetooth Mesh Profile Specification - version 1.0.1, only Composition Data Page 0 is supported. Users that are developing - for Bluetooth Mesh Profile Specification version 1.0.1 may therefore disregard all - parts of the following section mentioning the :ref:`bluetooth_mesh_lcd_srv` - model and Composition Data Pages 1, 2, 128, 129 and 130. + The implementation of the Bluetooth Mesh Protocol Specification version 1.1 + is currently in an experimental state. For Bluetooth Mesh Profile Specification + version 1.0.1, only Composition Data Page 0 is supported. Users that are developing + for Bluetooth Mesh Profile Specification version 1.0.1 may therefore disregard all + parts of the following section mentioning the :ref:`bluetooth_mesh_lcd_srv` + model and Composition Data Pages 1, 2, 128, 129 and 130. The Composition Data provides information about a mesh device. A device's Composition Data holds information about the elements on the From 0e26a0ddb9db62709a67484849cf40cb138949f9 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 21 Sep 2023 12:32:45 +0200 Subject: [PATCH 0999/4498] doc: Bluetooth: Mesh: Correct DFU and BLOB models specs names Correct DFU and BLOB models specs names. Also mentioning that they are experimental yet (under BT_MESH_V1d1 option). Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/blob.rst | 2 +- doc/connectivity/bluetooth/api/mesh/dfu.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/blob.rst b/doc/connectivity/bluetooth/api/mesh/blob.rst index 069f1ac9c63..54d8e67c155 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob.rst @@ -3,7 +3,7 @@ BLOB Transfer models #################### -The Binary Large Object (BLOB) Transfer models provide functionality for sending large binary objects from a single source to many Target nodes over the Bluetooth mesh network. It is the underlying transport method for the :ref:`bluetooth_mesh_dfu`, but may be used for other object transfer purposes. +The Binary Large Object (BLOB) Transfer models implement the Bluetooth Mesh Binary Large Object Transfer Model specification version 1.0 and provide functionality for sending large binary objects from a single source to many Target nodes over the Bluetooth mesh network. It is the underlying transport method for the :ref:`bluetooth_mesh_dfu`, but may be used for other object transfer purposes. The implementation is in experimental state. The BLOB Transfer models support transfers of continuous binary objects of up to 4 GB (2 \ :sup:`32` bytes). The BLOB transfer protocol has built-in recovery procedures for packet losses, and sets up checkpoints to ensure that all targets have received all the data before moving on. Data transfer order is not guaranteed. diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 0fee2b867ca..47716fa9faf 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -3,7 +3,7 @@ Device Firmware Update (DFU) ############################ -Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth mesh DFU subsystem implements the Firmware update section of the Bluetooth Mesh Model Specification v1.1. +Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth mesh DFU subsystem implements the Bluetooth Mesh Device Firmware Update Model specification version 1.0. The implementation is in experimental state. Bluetooth mesh DFU implements a distribution mechanism for firmware images, and does not put any restrictions on the size, format or usage of the images. The primary design goal of the subsystem is to provide the qualifiable parts of the Bluetooth mesh DFU specification, and leave the usage, firmware validation and deployment to the application. From 32dcd2e523485673f515ca04942abf7bb94cacfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Sep 2023 15:38:19 +0200 Subject: [PATCH 1000/4498] samples: shields: Update Nucleo shields to new code-sample extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all Nucleo shield samples and references to them so that they use the new zephyr:code-sample extension. Signed-off-by: Benjamin Cabé --- boards/shields/x_nucleo_53l0a1/doc/index.rst | 2 +- boards/shields/x_nucleo_iks01a1/doc/index.rst | 2 +- boards/shields/x_nucleo_iks01a2/doc/index.rst | 4 ++-- boards/shields/x_nucleo_iks01a3/doc/index.rst | 4 ++-- boards/shields/x_nucleo_iks02a1/doc/index.rst | 6 +++--- samples/shields/x_nucleo_53l0a1/README.rst | 7 ++++--- samples/shields/x_nucleo_iks01a1/README.rst | 7 ++++--- samples/shields/x_nucleo_iks01a2/sensorhub/README.rst | 7 ++++--- samples/shields/x_nucleo_iks01a2/standard/README.rst | 7 ++++--- samples/shields/x_nucleo_iks01a3/sensorhub/README.rst | 7 ++++--- samples/shields/x_nucleo_iks01a3/standard/README.rst | 7 ++++--- samples/shields/x_nucleo_iks02a1/microphone/README.rst | 9 +++++---- samples/shields/x_nucleo_iks02a1/sensorhub/README.rst | 7 ++++--- samples/shields/x_nucleo_iks02a1/standard/README.rst | 7 ++++--- 14 files changed, 46 insertions(+), 37 deletions(-) diff --git a/boards/shields/x_nucleo_53l0a1/doc/index.rst b/boards/shields/x_nucleo_53l0a1/doc/index.rst index 60f780ac43d..75f1a76dbcc 100644 --- a/boards/shields/x_nucleo_53l0a1/doc/index.rst +++ b/boards/shields/x_nucleo_53l0a1/doc/index.rst @@ -61,7 +61,7 @@ Samples The sample :ref:`vl53l0x` demonstrates how to use the ranging sensor VL53L0X using the center sensor only. -The sample :ref:`x-nucleo-53l0a1-sample` demonstrates how to use the three +The sample :zephyr:code-sample:`x-nucleo-53l0a1` sample demonstrates how to use the three sensors (soldered + 2 satellites) and the 7 segments display. Programming diff --git a/boards/shields/x_nucleo_iks01a1/doc/index.rst b/boards/shields/x_nucleo_iks01a1/doc/index.rst index 5674ee69e7a..55cf9c9f9dd 100644 --- a/boards/shields/x_nucleo_iks01a1/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a1/doc/index.rst @@ -45,7 +45,7 @@ Programming *********** An example on how to use the ``x-nucleo-iks01a1`` shield is available -in the :ref:`x-nucleo-iks01a1-sample` application documentation +in the :zephyr:code-sample:`x-nucleo-iks01a1` sample application documentation (see :ref:`shields` for more details). References diff --git a/boards/shields/x_nucleo_iks01a2/doc/index.rst b/boards/shields/x_nucleo_iks01a2/doc/index.rst index 7cd19653b43..c0c764a49f8 100644 --- a/boards/shields/x_nucleo_iks01a2/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a2/doc/index.rst @@ -85,9 +85,9 @@ Programming Two samples are provided as examples for ``x-nucleo-iks01a2`` shield: -- :ref:`x-nucleo-iks01a2-std-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks01a2-std` sample application, to be used when the shield is configured in Standard Mode -- :ref:`x-nucleo-iks01a2-shub-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks01a2-shub` sample application, to be used when the shield is configured in SensorHub Mode See also :ref:`shields` for more details. diff --git a/boards/shields/x_nucleo_iks01a3/doc/index.rst b/boards/shields/x_nucleo_iks01a3/doc/index.rst index c18647cfb7f..9b65abc5df3 100644 --- a/boards/shields/x_nucleo_iks01a3/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a3/doc/index.rst @@ -82,9 +82,9 @@ Programming Two samples are provided as examples for ``x-nucleo-iks01a3`` shield: -- :ref:`x-nucleo-iks01a3-std-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks01a3-std` sample application, to be used when the shield is configured in Standard Mode -- :ref:`x-nucleo-iks01a3-shub-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks01a3-shub` sample application, to be used when the shield is configured in SensorHub Mode See also :ref:`shields` for more details. diff --git a/boards/shields/x_nucleo_iks02a1/doc/index.rst b/boards/shields/x_nucleo_iks02a1/doc/index.rst index 2dab5a453f0..128d1286ece 100644 --- a/boards/shields/x_nucleo_iks02a1/doc/index.rst +++ b/boards/shields/x_nucleo_iks02a1/doc/index.rst @@ -82,11 +82,11 @@ Programming Three samples are provided as examples for ``x-nucleo-iks02a1`` shield: -- :ref:`x-nucleo-iks02a1-std-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks02a1-std` application, to be used when the shield is configured in Standard Mode -- :ref:`x-nucleo-iks02a1-shub-sample` application, to be used when the shield is configured +- :zephyr:code-sample:`x-nucleo-iks02a1-shub` application, to be used when the shield is configured in SensorHub Mode -- :ref:`x-nucleo-iks02a1-mic-sample` application, to be used to acquire data through the +- :zephyr:code-sample:`x-nucleo-iks02a1-mic` application, to be used to acquire data through the on-board PDM microphone See also :ref:`shields` for more details. diff --git a/samples/shields/x_nucleo_53l0a1/README.rst b/samples/shields/x_nucleo_53l0a1/README.rst index ddc762ed46c..403c7ebb4f9 100644 --- a/samples/shields/x_nucleo_53l0a1/README.rst +++ b/samples/shields/x_nucleo_53l0a1/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-53l0a1-sample: +.. zephyr:code-sample:: x-nucleo-53l0a1 + :name: X-NUCLEO-53L0A1 shield + :relevant-api: sensor_interface gpio_interface -X-NUCLEO-53L0A1 ranging and gesture detection sensor expansion board -##################################################################### + Interact with the 7-segment display and VL53L0X ranging sensor of an X-NUCLEO-53L0A1 shield. Overview ******** diff --git a/samples/shields/x_nucleo_iks01a1/README.rst b/samples/shields/x_nucleo_iks01a1/README.rst index 10c9e3f75cb..f5c0d7b2bb1 100644 --- a/samples/shields/x_nucleo_iks01a1/README.rst +++ b/samples/shields/x_nucleo_iks01a1/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks01a1-sample: +.. zephyr:code-sample:: x-nucleo-iks01a1 + :name: X-NUCLEO-IKS01A1 shield + :relevant-api: sensor_interface -X-NUCLEO-IKS01A1: MEMS inertial and environmental multi-sensor shield -##################################################################### + Interact with all the sensors of an X-NUCLEO-IKS01A1 shield. Overview ******** diff --git a/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst b/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst index a1ae62691a9..664658d4b84 100644 --- a/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks01a2-shub-sample: +.. zephyr:code-sample:: x-nucleo-iks01a2-shub + :name: X-NUCLEO-IKS01A2 shield - SensorHub (Mode 2) + :relevant-api: sensor_interface -X-NUCLEO-IKS01A2: shield SensorHub (Mode 2) sample -################################################## + Interact with all the sensors of an X-NUCLEO-IKS01A2 shield using Sensor Hub mode. Overview ******** diff --git a/samples/shields/x_nucleo_iks01a2/standard/README.rst b/samples/shields/x_nucleo_iks01a2/standard/README.rst index a31a7a75b4d..28dff866309 100644 --- a/samples/shields/x_nucleo_iks01a2/standard/README.rst +++ b/samples/shields/x_nucleo_iks01a2/standard/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks01a2-std-sample: +.. zephyr:code-sample:: x-nucleo-iks01a2-std + :name: X-NUCLEO-IKS01A2 shield - Standard (Mode 1) + :relevant-api: sensor_interface -X-NUCLEO-IKS01A2: shield Standard (Mode 1) sample -################################################# + Interact with all the sensors of an X-NUCLEO-IKS01A2 shield using Standard Mode. Overview ******** diff --git a/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst b/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst index 45299badd6b..f13c0ecb8ba 100644 --- a/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks01a3-shub-sample: +.. zephyr:code-sample:: x-nucleo-iks01a3-shub + :name: X-NUCLEO-IKS01A3 shield - SensorHub (Mode 2) + :relevant-api: sensor_interface -X-NUCLEO-IKS01A3: shield (Mode 2) sample -######################################## + Interact with all the sensors of an X-NUCLEO-IKS01A3 shield using Sensor Hub mode. Overview ******** diff --git a/samples/shields/x_nucleo_iks01a3/standard/README.rst b/samples/shields/x_nucleo_iks01a3/standard/README.rst index fdca7db1d0b..0f9a554b51a 100644 --- a/samples/shields/x_nucleo_iks01a3/standard/README.rst +++ b/samples/shields/x_nucleo_iks01a3/standard/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks01a3-std-sample: +.. zephyr:code-sample:: x-nucleo-iks01a3-std + :name: X-NUCLEO-IKS01A3 shield - Standard (Mode 1) + :relevant-api: sensor_interface -X-NUCLEO-IKS01A3: shield Standard (Mode 1) sample -################################################# + Interact with all the sensors of an X-NUCLEO-IKS01A3 shield using Standard mode. Overview ******** diff --git a/samples/shields/x_nucleo_iks02a1/microphone/README.rst b/samples/shields/x_nucleo_iks02a1/microphone/README.rst index 7740f521b9b..adc6831c81d 100644 --- a/samples/shields/x_nucleo_iks02a1/microphone/README.rst +++ b/samples/shields/x_nucleo_iks02a1/microphone/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks02a1-mic-sample: +.. zephyr:code-sample:: x-nucleo-iks02a1-mic + :name: X-NUCLEO-IKS02A1 shield - MEMS microphone + :relevant-api: audio_dmic_interface -X-NUCLEO-IKS02A1 shield: Acquire MEMS microphones data -###################################################### + Acquire audio using the digital MEMS microphone on X-NUCLEO-IKS02A1 shield. Overview ******** @@ -9,7 +10,7 @@ This sample enables the digital MEMS microphone on X-NUCLEO-IKS02A1 shields This sample provides an example of how to acquire audio through -the digital MEMS microphones on X-NUCLEO-IKS02A1 shield. +the digital MEMS microphone on X-NUCLEO-IKS02A1 shield. The microphone generates a PDM stream which is acquired through I2S. The PDM stream is then converted to PCM using the OpenPDM2PCM library available in zephyrproject/modules/hal/st/audio/microphone. diff --git a/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst b/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst index 9032b014321..ed8e62b9317 100644 --- a/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks02a1-shub-sample: +.. zephyr:code-sample:: x-nucleo-iks02a1-shub + :name: X-NUCLEO-IKS02A1 shield - SensorHub (Mode 2) + :relevant-api: sensor_interface -X-NUCLEO-IKS02A1 shield: Sensorhub (Mode 2) sample -################################################## + Interact with all the sensors of an X-NUCLEO-IKS02A1 shield using Sensor Hub mode. Overview ******** diff --git a/samples/shields/x_nucleo_iks02a1/standard/README.rst b/samples/shields/x_nucleo_iks02a1/standard/README.rst index a9043eeb8e0..4e3c7e51a05 100644 --- a/samples/shields/x_nucleo_iks02a1/standard/README.rst +++ b/samples/shields/x_nucleo_iks02a1/standard/README.rst @@ -1,7 +1,8 @@ -.. _x-nucleo-iks02a1-std-sample: +.. zephyr:code-sample:: x-nucleo-iks02a1-std + :name: X-NUCLEO-IKS02A1 shield - Standard (Mode 1) + :relevant-api: sensor_interface -X-NUCLEO-IKS02A1 shield: Standard (Mode 1) sample -################################################# + Interact with all the sensors of an X-NUCLEO-IKS02A1 shield using Standard mode. Overview ******** From ca5931065c34d8042d93cd5ad117d6d6c69b6e71 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 25 Sep 2023 18:06:58 +1000 Subject: [PATCH 1001/4498] testsuite: boards: unit_testing: default HCI bus Be explicit about the HCI backend that Bluetooth unit tests require. Some unit tests depend on `BT_HAS_HCI_VS`, so also enable that. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/Kconfig | 1 + .../boards/unit_testing/unit_testing/Kconfig.defconfig | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 8a50caa92f0..195faef0985 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -99,6 +99,7 @@ config BT_PSOC6_BLESS config BT_NO_DRIVER bool "No default HCI driver" + select BT_HAS_HCI_VS help This is intended for unit tests where no internal driver should be selected. diff --git a/subsys/testsuite/boards/unit_testing/unit_testing/Kconfig.defconfig b/subsys/testsuite/boards/unit_testing/unit_testing/Kconfig.defconfig index b2efdb2bee7..939f1c97e71 100644 --- a/subsys/testsuite/boards/unit_testing/unit_testing/Kconfig.defconfig +++ b/subsys/testsuite/boards/unit_testing/unit_testing/Kconfig.defconfig @@ -2,4 +2,7 @@ # # Copyright (c) 2022 Nordic Semiconductor -# Intentionally left empty +# Bluetooth unit tests expect this backend +choice BT_HCI_BUS_TYPE + default BT_NO_DRIVER +endchoice From c667b4369711b0ee3373c37173dd1f7b24615dd9 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 22 Sep 2023 10:11:26 +1000 Subject: [PATCH 1002/4498] bluetooth: hci: enable backends by default Enable backends by default, instead of requiring some other module to turn them on. This aligns with the behaviour of sensor drivers and `BT_RPMSG`. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/Kconfig | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 195faef0985..07aa505f8b4 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -7,25 +7,23 @@ comment "Bluetooth HCI Driver Options" config BT_UART bool + select SERIAL + select UART_INTERRUPT_DRIVEN choice BT_HCI_BUS_TYPE prompt "Bluetooth HCI driver" config BT_H4 bool "H:4 UART" - select UART_INTERRUPT_DRIVEN select BT_UART - depends on SERIAL help Bluetooth H:4 UART driver. Requires hardware flow control lines to be available. config BT_H5 bool "H:5 UART [EXPERIMENTAL]" - select UART_INTERRUPT_DRIVEN select BT_UART select EXPERIMENTAL - depends on SERIAL help Bluetooth three-wire (H:5) UART driver. Implementation of HCI Three-Wire UART Transport Layer. @@ -41,7 +39,7 @@ config BT_RPMSG config BT_SPI bool "SPI HCI" - depends on SPI + select SPI help Supports Bluetooth ICs using SPI as the communication protocol. HCI packets are sent and received as single Byte transfers, From 0a0198898d770543346621f903ad4c7c1ce3a1aa Mon Sep 17 00:00:00 2001 From: Mia Koen Date: Fri, 22 Sep 2023 12:49:09 +0200 Subject: [PATCH 1003/4498] doc: bluetooth: mesh: note and spec name fix Fixed a note in Config Server model and spec name in couple of other models Signed-off-by: Mia Koen --- doc/connectivity/bluetooth/api/mesh/cfg_srv.rst | 2 +- doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst | 2 +- doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst | 2 +- doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst | 2 +- doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst index 0a26eadfc1a..84f174df88b 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst @@ -8,7 +8,7 @@ specification. The Configuration Server model controls most parameters of the mesh node. It does not have an API of its own, but relies on a :ref:`bluetooth_mesh_models_cfg_cli` to control it. -..note:: +.. note:: The :c:struct:`bt_mesh_cfg_srv` structure has been deprecated. The initial values of the Relay, Beacon, Friend, Network transmit and Relay retransmit should be set through Kconfig, and the Heartbeat feature should be diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst index cb2d1e6ab81..687fc66e3f9 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst @@ -6,7 +6,7 @@ Opcodes Aggregator Client The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` option. -The Opcodes Aggregator Client model is introduced in the Bluetooth Mesh Profile +The Opcodes Aggregator Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and is used to support the functionality of dispatching a sequence of access layer messages to nodes supporting the :ref:`bluetooth_mesh_models_op_agg_srv` model. diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst index 1f3c6946c79..d5b5e69347d 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst @@ -6,7 +6,7 @@ Opcodes Aggregator Server The Opcodes Aggregator Server model is a foundation model defined by the Bluetooth mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_SRV` option. -The Opcodes Aggregator Server model is introduced in the Bluetooth Mesh Profile +The Opcodes Aggregator Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and is used to support the functionality of processing a sequence of access layer messages. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst index 7f7d5542a7b..cb531a4c3c8 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst @@ -7,7 +7,7 @@ The Private Beacon Client model is a foundation model defined by the Bluetooth mesh specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_PRIV_BEACON_CLI` option. -The Private Beacon Client model is introduced in the Bluetooth Mesh Profile +The Private Beacon Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and provides functionality for configuring the :ref:`bluetooth_mesh_models_priv_beacon_srv` models. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst index cedd7166b09..3c17cc44675 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst @@ -7,7 +7,7 @@ The Private Beacon Server model is a foundation model defined by the Bluetooth mesh specification. It is enabled with :kconfig:option:`CONFIG_BT_MESH_PRIV_BEACON_SRV` option. -The Private Beacon Server model is introduced in the Bluetooth Mesh Profile +The Private Beacon Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and controls the mesh node's Private Beacon state, Private GATT Proxy state and Private Node Identity state. From b2f7ea0523ea77dd123f4bf0610ce97cc3e90b5d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 22 Sep 2023 15:03:34 -0700 Subject: [PATCH 1004/4498] soc: xtensa/intel_adsp/ace: fix _end location The symbol _end is used to indicate the start of heap in the common libc malloc code. On ACE, heap is in uncached area. However, _end was in the cached area while end of heap is in uncached area. This resulted in incorrect calculation of heap size. So move _end into uncached area so correct heap size can be calculated. Signed-off-by: Daniel Leung --- soc/xtensa/intel_adsp/ace/ace-link.ld | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/ace/ace-link.ld b/soc/xtensa/intel_adsp/ace/ace-link.ld index a4aaf6b8087..454893055e1 100644 --- a/soc/xtensa/intel_adsp/ace/ace-link.ld +++ b/soc/xtensa/intel_adsp/ace/ace-link.ld @@ -403,10 +403,13 @@ SECTIONS { _unused_ram_start_marker = .; *(.unused_ram_start_marker) *(.unused_ram_start_marker.*) - _end = .; z_mapped_end = .; } >ram + /* Heap start and end markers. Used with libc malloc code. */ + . = SEGSTART_UNCACHED; + _end = ALIGN(8); + . = SEGSTART_CACHED; . = L2_SRAM_BASE + L2_SRAM_SIZE; . = SEGSTART_UNCACHED; _heap_end = .; From f1bf05e63a5447c7a935c371d22182a80319c08a Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Mon, 25 Sep 2023 11:53:37 +0200 Subject: [PATCH 1005/4498] net: wifi: Added missing extern "C" This change allows to include this header directly from cpp file. Signed-off-by: Wojciech Slenska --- include/zephyr/net/wifi.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 294fdc53c5d..75cf4cf5f92 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -27,6 +27,10 @@ #define WIFI_LISTEN_INTERVAL_MIN 0 #define WIFI_LISTEN_INTERVAL_MAX 65535 +#ifdef __cplusplus +extern "C" { +#endif + /** IEEE 802.11 security types. */ enum wifi_security_type { /** No security. */ @@ -444,6 +448,10 @@ static inline const char *wifi_ps_get_config_err_code_str(int16_t err_no) return ""; } +#ifdef __cplusplus +} +#endif + /** * @} */ From b7433fd297848c4d56d60254b5cd88c7b2b4babe Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Mon, 25 Sep 2023 12:08:24 +0800 Subject: [PATCH 1006/4498] dts: arm: ambiq: Add IOM instances to Apollo4 Blue Plus SoC. This commit instantiates the IOM peripherals. IOM can be configured to SPI or I2C master. Signed-off-by: Aaron Ye --- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 73 ++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 85937de51e2..e3af97eac39 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -2,6 +2,7 @@ #include #include +#include / { clocks { @@ -101,6 +102,78 @@ ambiq,pwrcfg = <&pwrcfg 0x4 0x1000>; }; + iom0: iom@40050000 { + reg = <0x40050000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <6 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x2>; + }; + + iom1: iom@40051000 { + reg = <0x40051000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <7 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x4>; + }; + + iom2: iom@40052000 { + reg = <0x40052000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <8 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x8>; + }; + + iom3: iom@40053000 { + reg = <0x40053000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <9 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x10>; + }; + + iom4: iom@40054000 { + reg = <0x40054000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <10 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x20>; + }; + + iom5: iom@40055000 { + reg = <0x40055000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <11 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x40>; + }; + + iom6: iom@40056000 { + reg = <0x40056000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <12 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x80>; + }; + + iom7: iom@40057000 { + reg = <0x40057000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <13 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x100>; + }; + pinctrl: pin-controller@40010000 { compatible = "ambiq,apollo4-pinctrl"; reg = <0x40010000 0x800>; From 03849370bdb3668f2ecc6875ccd635348ea0a035 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Mon, 25 Sep 2023 10:24:30 +0800 Subject: [PATCH 1007/4498] dts: arm: ambiq: Add MSPI instances to Apollo4 Blue Plus SoC. This commit instantiates the MSPI peripherals. Signed-off-by: Aaron Ye --- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index e3af97eac39..80b004c84af 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -174,6 +174,36 @@ ambiq,pwrcfg = <&pwrcfg 0x4 0x100>; }; + mspi0: spi@40060000 { + compatible = "ambiq,mspi"; + reg = <0x40060000 0x400>; + interrupts = <20 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x4000>; + }; + + mspi1: spi@40061000 { + compatible = "ambiq,mspi"; + reg = <0x40061000 0x400>; + interrupts = <21 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x8000>; + }; + + mspi2: spi@40062000 { + compatible = "ambiq,mspi"; + reg = <0x40062000 0x400>; + interrupts = <22 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x4 0x10000>; + }; + pinctrl: pin-controller@40010000 { compatible = "ambiq,apollo4-pinctrl"; reg = <0x40010000 0x800>; From c2a5f031384f84ff1b6ac5e4aa4d29259805d3f0 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Mon, 25 Sep 2023 12:11:34 +0800 Subject: [PATCH 1008/4498] boards: arm: apollo4p_blue_kxr_evb: Enable I2C. This commit enables I2C instance for apollo4p_blue_kxr_evb board. Also adds pin configuration for each instance. IOM4 is used for Bluetooth HCI-SPI inside of chip. So no i2c4_default is defined. Signed-off-by: Aaron Ye --- .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 56 +++++++++++++++++++ .../apollo4p_blue_kxr_evb.dts | 8 +++ 2 files changed, 64 insertions(+) diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi index 840f2343310..b171a065bca 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -16,4 +16,60 @@ input-enable; }; }; + i2c0_default: i2c0_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c2_default: i2c2_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c3_default: i2c3_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c5_default: i2c5_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c6_default: i2c6_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; + i2c7_default: i2c7_default { + group1 { + pinmux = , ; + drive-open-drain; + drive-strength = "0.5"; + bias-pull-up; + }; + }; }; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index 93a55c4bc44..3f73bd219bc 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -34,3 +34,11 @@ &wdt0 { status = "okay"; }; + +&iom0 { + compatible = "ambiq,i2c"; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; From d91ef40a7e39a24468a515455287f5a2b25b0cf7 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Mon, 25 Sep 2023 12:12:36 +0800 Subject: [PATCH 1009/4498] boards: arm: apollo4p_blue_kxr_evb: Enable SPI. This commit enables SPI instance for apollo4p_blue_kxr_evb board. Also adds pin configuration for each instance. Signed-off-by: Aaron Ye --- .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 81 +++++++++++++++++++ .../apollo4p_blue_kxr_evb.dts | 8 ++ 2 files changed, 89 insertions(+) diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi index b171a065bca..35965f21a32 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -72,4 +72,85 @@ bias-pull-up; }; }; + + spi0_default: spi0_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <0>; + }; + }; + spi1_default: spi1_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <4>; + }; + }; + spi2_default: spi2_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <8>; + }; + }; + spi3_default: spi3_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <12>; + }; + }; + spi4_default: spi4_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <16>; + }; + }; + spi5_default: spi5_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <20>; + }; + }; + spi6_default: spi6_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <24>; + }; + }; + spi7_default: spi7_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + drive-push-pull; + ambiq,iom-nce-module = <28>; + }; + }; }; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index 3f73bd219bc..b09ba535109 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -42,3 +42,11 @@ clock-frequency = ; status = "okay"; }; + +&iom1 { + compatible = "ambiq,spi"; + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + clock-frequency = <1000000>; + status = "okay"; +}; From d404f018a646f701da4fc54295489fd4e0d25cf3 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Mon, 25 Sep 2023 12:45:52 +0800 Subject: [PATCH 1010/4498] boards: arm: apollo4p_blue_kxr_evb: Enable MSPI. This commit enables MSPI instance for apollo4p_blue_kxr_evb board. Also adds pin configuration for each instance. Signed-off-by: Aaron Ye --- .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 39 +++++++++++++++++++ .../apollo4p_blue_kxr_evb.dts | 6 +++ 2 files changed, 45 insertions(+) diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi index 35965f21a32..4d8f6cb0525 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -153,4 +153,43 @@ ambiq,iom-nce-module = <28>; }; }; + mspi0_default: mspi0_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <32>; + }; + }; + mspi1_default: mspi1_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <34>; + }; + }; + mspi2_default: mspi2_default{ + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + drive-push-pull; + drive-strength = "0.5"; + ambiq,iom-nce-module = <36>; + }; + }; }; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index b09ba535109..1eca9ae225e 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -50,3 +50,9 @@ clock-frequency = <1000000>; status = "okay"; }; + +&mspi0 { + pinctrl-0 = <&mspi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; From 3dba54b92da8f1d68569c3929605ee0131e33f9f Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sat, 23 Sep 2023 01:34:09 +1000 Subject: [PATCH 1011/4498] drivers: current sense amp: add pm Enable power management for current sense amp. Signed-off-by: Nick Ward --- drivers/sensor/current_amp/current_amp.c | 59 ++++++++++++++++++- .../iio/afe/current-sense-amplifier.yaml | 8 +++ .../drivers/adc/current_sense_amplifier.h | 3 + 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/current_amp/current_amp.c b/drivers/sensor/current_amp/current_amp.c index 8a62a1e61f5..d760e4b34b0 100644 --- a/drivers/sensor/current_amp/current_amp.c +++ b/drivers/sensor/current_amp/current_amp.c @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include LOG_MODULE_REGISTER(current_amp, CONFIG_SENSOR_LOG_LEVEL); @@ -73,6 +75,40 @@ static const struct sensor_driver_api current_api = { .channel_get = get, }; +#ifdef CONFIG_PM_DEVICE +static int pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct current_sense_amplifier_dt_spec *config = dev->config; + int ret; + + if (config->power_gpio.port == NULL) { + LOG_ERR("PM not supported"); + return -ENOTSUP; + } + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = gpio_pin_set_dt(&config->power_gpio, 1); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM resume"); + return ret; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = gpio_pin_set_dt(&config->power_gpio, 0); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM suspend"); + return ret; + } + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + static int current_init(const struct device *dev) { const struct current_sense_amplifier_dt_spec *config = dev->config; @@ -84,6 +120,21 @@ static int current_init(const struct device *dev) return -ENODEV; } +#ifdef CONFIG_PM_DEVICE + if (config->power_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->power_gpio)) { + LOG_ERR("Power GPIO is not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_ACTIVE); + if (ret != 0) { + LOG_ERR("failed to config GPIO: %d", ret); + return ret; + } + } +#endif + ret = adc_channel_setup_dt(&config->port); if (ret != 0) { LOG_ERR("setup: %d", ret); @@ -108,8 +159,10 @@ static int current_init(const struct device *dev) static const struct current_sense_amplifier_dt_spec current_amp_##inst##_config = \ CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(DT_DRV_INST(inst)); \ \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, ¤t_init, NULL, ¤t_amp_##inst##_data, \ - ¤t_amp_##inst##_config, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, ¤t_api); + PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, ¤t_init, PM_DEVICE_DT_INST_GET(inst), \ + ¤t_amp_##inst##_data, ¤t_amp_##inst##_config, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, ¤t_api); DT_INST_FOREACH_STATUS_OKAY(CURRENT_SENSE_AMPLIFIER_INIT) diff --git a/dts/bindings/iio/afe/current-sense-amplifier.yaml b/dts/bindings/iio/afe/current-sense-amplifier.yaml index e50bda74fe4..777116d0cff 100644 --- a/dts/bindings/iio/afe/current-sense-amplifier.yaml +++ b/dts/bindings/iio/afe/current-sense-amplifier.yaml @@ -37,3 +37,11 @@ properties: default: 1 description: | Amplifier gain divider. The default is <1>. + + power-gpios: + type: phandle-array + description: | + Control power to the current amplifier. + + If present the corresponding GPIO must be set to an active level + to enable the current amplifier. diff --git a/include/zephyr/drivers/adc/current_sense_amplifier.h b/include/zephyr/drivers/adc/current_sense_amplifier.h index 6035eeb4ed2..888167b1ae9 100644 --- a/include/zephyr/drivers/adc/current_sense_amplifier.h +++ b/include/zephyr/drivers/adc/current_sense_amplifier.h @@ -8,12 +8,14 @@ #define ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ #include +#include struct current_sense_amplifier_dt_spec { const struct adc_dt_spec port; uint32_t sense_micro_ohms; uint32_t sense_gain_mult; uint32_t sense_gain_div; + struct gpio_dt_spec power_gpio; }; /** @@ -32,6 +34,7 @@ struct current_sense_amplifier_dt_spec { .sense_micro_ohms = DT_PROP(node_id, sense_resistor_micro_ohms), \ .sense_gain_mult = DT_PROP(node_id, sense_gain_mult), \ .sense_gain_div = DT_PROP(node_id, sense_gain_div), \ + .power_gpio = GPIO_DT_SPEC_GET_OR(node_id, power_gpios, {0}), \ } /** From af22475f98bf49e22871c105a123d96dcccb26b0 Mon Sep 17 00:00:00 2001 From: Warren Buffer Date: Thu, 21 Sep 2023 17:20:40 +0300 Subject: [PATCH 1012/4498] boards: efr32_radio_brd4170a: Setup console with pinctrl Prior to this patch, the BRD4170A did not enable the UART console using pinctrl, which was recently added for this SoC series. Signed-off-by: Warren Buffer --- boards/arm/efr32_radio/efr32_radio_brd4170a.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boards/arm/efr32_radio/efr32_radio_brd4170a.dts b/boards/arm/efr32_radio/efr32_radio_brd4170a.dts index effd66a8515..ed7e2f992a1 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4170a.dts +++ b/boards/arm/efr32_radio/efr32_radio_brd4170a.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "efr32_radio.dtsi" / { @@ -60,3 +61,10 @@ }; }; + +&usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; From 389f061c8d3faa198460bb1552be454ddb472c5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 22 Sep 2023 20:10:58 -0700 Subject: [PATCH 1013/4498] scripts/log_parser: Handle signed and unsigned char length modifier The C standard specifies 'hh' as a length modifier indicating an integer conversion specifier applies to a signed char or unsigned char argument. Python doesn't do that, so replace relevant %hh with %h. Also fix the handling of %ll so that it applies to all integer specifiers as well. Signed-off-by: Keith Packard --- .../dictionary/dictionary_parser/log_parser_v1.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py index 2559b5b39cd..e065837781f 100644 --- a/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py +++ b/scripts/logging/dictionary/dictionary_parser/log_parser_v1.py @@ -79,9 +79,12 @@ def formalize_fmt_string(fmt_str): """Replace unsupported formatter""" new_str = fmt_str - # Python doesn't support %lld or %llu so need to remove extra 'l' - new_str = new_str.replace("%lld", "%ld") - new_str = new_str.replace("%llu", "%lu") + for spec in ['d', 'i', 'o', 'u', 'x', 'X']: + # Python doesn't support %ll for integer specifiers, so remove extra 'l' + new_str = new_str.replace("%ll" + spec, "%l" + spec) + + # Python doesn't support %hh for integer specifiers, so remove extra 'h' + new_str = new_str.replace("%hh" + spec, "%h" + spec) # No %p for pointer either, so use %x new_str = new_str.replace("%p", "0x%x") From 3a119979d63f8c2e0f7639e497692c9c46a385c7 Mon Sep 17 00:00:00 2001 From: Pavlo Havrylyuk Date: Fri, 22 Sep 2023 11:59:35 -0700 Subject: [PATCH 1014/4498] samples: userspace: exclude cy8cproto boards from sample Excluded cy8cproto_062_4343w and cy8cproto_063_ble from samples/userspace/shared_mem sample due to a hardware limitation with number of available MPU regions. Sample throws warning: `num_parts of 4 exceeds maximum allowable partitions (2)` With the Cortex M4 on the boards only 2 mpu regions are left and available to be used with the sample. Signed-off-by: Pavlo Havrylyuk --- samples/userspace/shared_mem/sample.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/userspace/shared_mem/sample.yaml b/samples/userspace/shared_mem/sample.yaml index b9d72fbe145..3e45ba1bbd6 100644 --- a/samples/userspace/shared_mem/sample.yaml +++ b/samples/userspace/shared_mem/sample.yaml @@ -14,6 +14,9 @@ common: tests: sample.kernel.memory_protection.shared_mem: filter: CONFIG_ARCH_HAS_USERSPACE - platform_exclude: twr_ke18f + platform_exclude: + - twr_ke18f + - cy8cproto_062_4343w + - cy8cproto_063_ble extra_configs: - CONFIG_TEST_HW_STACK_PROTECTION=n From 8c9ac505dbe04585ebb6c3532c93c24884db70bb Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 22 Sep 2023 12:42:57 +0200 Subject: [PATCH 1015/4498] Bluetooth: Controller: nRF53: Fix sw switch single timer id regression Fix regression in sw switch single timer id use for nRF53x series SoC. Regression introduced in commit cfcbe5d68ed3 ("Bluetooth: Controller: Remove redudant header file includes"). Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h | 14 ++++++++++++++ tests/bluetooth/init/testcase.yaml | 13 +++++++++++++ 2 files changed, 27 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h index e0f43014508..68267490129 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h @@ -5,6 +5,20 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* Override EVENT_TIMER_ID from 4 to 0, as nRF5340 does not have 4 timer + * instances. + */ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#undef EVENT_TIMER_ID +#define EVENT_TIMER_ID 0 + +#undef EVENT_TIMER +#define EVENT_TIMER _CONCAT(NRF_TIMER, EVENT_TIMER_ID) + +#undef SW_SWITCH_TIMER +#define SW_SWITCH_TIMER EVENT_TIMER +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + /* NRF Radio HW timing constants * - provided in US and NS (for higher granularity) * - based on empirical measurements and sniffer logs diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index fa30920dc1e..c38f5bed69e 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,6 +122,19 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 + bluetooth.init.test_ctlr_sw_switch_single_timer: + extra_args: + - CONF_FILE=prj_ctlr.conf + - CONFIG_BT_CTLR_ADVANCED_FEATURES=y + - CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER=y + platform_allow: + - nrf5340dk_nrf5340_cpunet + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 + integration_platforms: + - nrf5340dk_nrf5340_cpunet + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 bluetooth.init.test_ctlr_ticker: extra_args: - CONF_FILE=prj_ctlr_ticker.conf From 90dfe9f2db97cebdf53f2f76d54b188f9310a225 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Mon, 25 Sep 2023 14:30:25 +0200 Subject: [PATCH 1016/4498] modem: chat: extend request_size to uint16_t Some AT commands, are longer than 255 chars. Also, script_send_request_pos is uint16_t, so with this change, request_size will have the same type. Signed-off-by: Wojciech Slenska --- include/zephyr/modem/chat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index 746e122135e..d46ffc7c24a 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -91,7 +91,7 @@ struct modem_chat_script_chat { /** Request to send to modem */ const uint8_t *request; /** Size of request */ - uint8_t request_size; + uint16_t request_size; /** Expected responses to request */ const struct modem_chat_match *response_matches; /** Number of elements in expected responses */ @@ -103,7 +103,7 @@ struct modem_chat_script_chat { #define MODEM_CHAT_SCRIPT_CMD_RESP(_request, _response_match) \ { \ .request = (uint8_t *)(_request), \ - .request_size = (uint8_t)(sizeof(_request) - 1), \ + .request_size = (uint16_t)(sizeof(_request) - 1), \ .response_matches = &_response_match, \ .response_matches_size = 1, \ .timeout = 0, \ @@ -112,7 +112,7 @@ struct modem_chat_script_chat { #define MODEM_CHAT_SCRIPT_CMD_RESP_MULT(_request, _response_matches) \ { \ .request = (uint8_t *)(_request), \ - .request_size = (uint8_t)(sizeof(_request) - 1), \ + .request_size = (uint16_t)(sizeof(_request) - 1), \ .response_matches = _response_matches, \ .response_matches_size = ARRAY_SIZE(_response_matches), \ .timeout = 0, \ @@ -121,7 +121,7 @@ struct modem_chat_script_chat { #define MODEM_CHAT_SCRIPT_CMD_RESP_NONE(_request, _timeout) \ { \ .request = (uint8_t *)(_request), \ - .request_size = (uint8_t)(sizeof(_request) - 1), \ + .request_size = (uint16_t)(sizeof(_request) - 1), \ .response_matches = NULL, \ .response_matches_size = 0, \ .timeout = _timeout, \ From 0ff2ba8c8ecb49a03649b19a2b0ec83d976bb1b4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 25 Sep 2023 14:30:59 +0200 Subject: [PATCH 1017/4498] tests: BT privacy: Fix printf format Fix the print format string so the "%" is printed instead of a bogus value. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c index e125f88c615..b553ee74b25 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c @@ -83,7 +83,7 @@ static void test_address(bt_addr_le_t *addr) rpa_timeout_ms = CONFIG_BT_RPA_TIMEOUT * MSEC_PER_SEC; if (abs(diff_ms - rpa_timeout_ms) > (rpa_timeout_ms / 10)) { - FAIL("RPA rotation did not occur within +-10% of CONFIG_BT_RPA_TIMEOUT\n"); + FAIL("RPA rotation did not occur within +-10%% of CONFIG_BT_RPA_TIMEOUT\n"); } bt_addr_le_copy(&adv_set_data[adv_index].old_addr, addr); From 4d10c960da80baf81e6d6be0c515fd7237fcb7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 18 Sep 2023 19:11:38 +0200 Subject: [PATCH 1018/4498] drivers: sensor: Add initial support for hm330x dust sensor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds initial support for hm330x dust sensor series. Allows to read PM1, PM2.5 and PM10 concentrations in atmospheric environment. A further update to the driver may add support for also reading "standard" CF1 concentrations by exposing of a custom sensor attribute or a Kconfig option. Tested with Grove - Laser PM2.5 Sensor (HM3301) attached to a Wio Terminal. Signed-off-by: Benjamin Cabé --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/hm330x/CMakeLists.txt | 5 + drivers/sensor/hm330x/Kconfig | 12 +++ drivers/sensor/hm330x/hm330x.c | 121 ++++++++++++++++++++++++ dts/bindings/sensor/seeed,hm330x.yaml | 9 ++ tests/drivers/build_all/sensor/i2c.dtsi | 6 ++ 7 files changed, 155 insertions(+) create mode 100644 drivers/sensor/hm330x/CMakeLists.txt create mode 100644 drivers/sensor/hm330x/Kconfig create mode 100644 drivers/sensor/hm330x/hm330x.c create mode 100644 dts/bindings/sensor/seeed,hm330x.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 7ec05baff81..2aba319c16f 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -41,6 +41,7 @@ add_subdirectory_ifdef(CONFIG_FXOS8700 fxos8700) add_subdirectory_ifdef(CONFIG_GROVE_SENSORS grove) add_subdirectory_ifdef(CONFIG_GROW_R502A grow_r502a) add_subdirectory_ifdef(CONFIG_HAS_STMEMSC stmemsc) +add_subdirectory_ifdef(CONFIG_HM330X hm330x) add_subdirectory_ifdef(CONFIG_HMC5883L hmc5883l) add_subdirectory_ifdef(CONFIG_HP206C hp206c) add_subdirectory_ifdef(CONFIG_HTS221 hts221) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 942b1bee1d0..dd4917cf64d 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -96,6 +96,7 @@ source "drivers/sensor/fxas21002/Kconfig" source "drivers/sensor/fxos8700/Kconfig" source "drivers/sensor/grove/Kconfig" source "drivers/sensor/grow_r502a/Kconfig" +source "drivers/sensor/hm330x/Kconfig" source "drivers/sensor/hmc5883l/Kconfig" source "drivers/sensor/hp206c/Kconfig" source "drivers/sensor/hts221/Kconfig" diff --git a/drivers/sensor/hm330x/CMakeLists.txt b/drivers/sensor/hm330x/CMakeLists.txt new file mode 100644 index 00000000000..5eeb7ae4849 --- /dev/null +++ b/drivers/sensor/hm330x/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(hm330x.c) diff --git a/drivers/sensor/hm330x/Kconfig b/drivers/sensor/hm330x/Kconfig new file mode 100644 index 00000000000..f1c34eea3fa --- /dev/null +++ b/drivers/sensor/hm330x/Kconfig @@ -0,0 +1,12 @@ +# Seeed Studio HM330x dust particle sensor configuration options + +# Copyright (c) 2023 Benjamin Cabé +# SPDX-License-Identifier: Apache-2.0 + +config HM330X + bool "HM330X dust particle sensor" + default y + depends on DT_HAS_SEEED_HM330X_ENABLED + select I2C + help + Enable driver for the HM330X dust particle sensor. diff --git a/drivers/sensor/hm330x/hm330x.c b/drivers/sensor/hm330x/hm330x.c new file mode 100644 index 00000000000..a1ec7baccd8 --- /dev/null +++ b/drivers/sensor/hm330x/hm330x.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 Benjamin Cabé + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT seeed_hm330x + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(HM3301, CONFIG_SENSOR_LOG_LEVEL); + +#define HM330X_SELECT_COMM_CMD 0X88 + +#define HM330X_PM_1_0_ATM 10 +#define HM330X_PM_2_5_ATM 12 +#define HM330X_PM_10_ATM 14 + +#define HM330X_FRAME_LEN 29 + +struct hm330x_data { + uint16_t pm_1_0_sample; + uint16_t pm_2_5_sample; + uint16_t pm_10_sample; +}; + +struct hm330x_config { + struct i2c_dt_spec i2c; +}; + +static int hm330x_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct hm330x_data *drv_data = dev->data; + const struct hm330x_config *config = dev->config; + uint8_t buf[HM330X_FRAME_LEN]; + uint8_t checksum = 0; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + + if (i2c_burst_read_dt(&config->i2c, + 0, buf, HM330X_FRAME_LEN) < 0) { + return -EIO; + } + + drv_data->pm_1_0_sample = (buf[HM330X_PM_1_0_ATM] << 8) | buf[HM330X_PM_1_0_ATM + 1]; + drv_data->pm_2_5_sample = (buf[HM330X_PM_2_5_ATM] << 8) | buf[HM330X_PM_2_5_ATM + 1]; + drv_data->pm_10_sample = (buf[HM330X_PM_10_ATM] << 8) | buf[HM330X_PM_10_ATM + 1]; + + for (int i = 0; i < HM330X_FRAME_LEN - 1; i++) { + checksum += buf[i]; + } + if (checksum != buf[HM330X_FRAME_LEN - 1]) { + LOG_ERR("Checksum error"); + return -EBADMSG; + } + + return 0; +} + +static int hm330x_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct hm330x_data *drv_data = dev->data; + + if (chan == SENSOR_CHAN_PM_1_0) { + val->val1 = drv_data->pm_1_0_sample; + val->val2 = 0; + } else if (chan == SENSOR_CHAN_PM_2_5) { + val->val1 = drv_data->pm_2_5_sample; + val->val2 = 0; + } else if (chan == SENSOR_CHAN_PM_10) { + val->val1 = drv_data->pm_10_sample; + val->val2 = 0; + } else { + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api hm330x_driver_api = { + .sample_fetch = hm330x_sample_fetch, + .channel_get = hm330x_channel_get +}; + +int hm330x_init(const struct device *dev) +{ + const struct hm330x_config *config = dev->config; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C bus device not ready"); + return -ENODEV; + } + + /** Enable I2C communications (module defaults to UART) */ + if (i2c_reg_write_byte_dt(&config->i2c, 0, HM330X_SELECT_COMM_CMD) < 0) { + LOG_ERR("Failed to switch to I2C"); + return -EIO; + } + + return 0; +} + +#define HM330X_DEFINE(inst) \ + static struct hm330x_data hm330x_data_##inst; \ + \ + static const struct hm330x_config hm330x_config##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst) \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, hm330x_init, NULL, &hm330x_data_##inst, \ + &hm330x_config##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &hm330x_driver_api); \ + +DT_INST_FOREACH_STATUS_OKAY(HM330X_DEFINE) diff --git a/dts/bindings/sensor/seeed,hm330x.yaml b/dts/bindings/sensor/seeed,hm330x.yaml new file mode 100644 index 00000000000..0b9e6facbb1 --- /dev/null +++ b/dts/bindings/sensor/seeed,hm330x.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2023 benjamin@zephyrproject.org +# SPDX-License-Identifier: Apache-2.0 + +description: | + Seeed Studio HM330x dust particle sensor + +compatible: "seeed,hm330x" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 1409b74ea68..b59f14f36a7 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -765,3 +765,9 @@ test_i2c_adltc2990@72 { pin-v3-voltage-divider-resistors = <100 100>; pin-v4-voltage-divider-resistors = <0 1>; }; + +test_i2c_hm330x@73 { + compatible = "seeed,hm330x"; + reg = <0x73>; + status = "okay"; +}; From d2879f9a482a692c617ee6280b74829f857be5cf Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 25 Sep 2023 11:58:57 +0000 Subject: [PATCH 1019/4498] ci: use zephyr sdk 0.16.3 Modify CI tpo use new SDK and new docker containing this SDK. Signed-off-by: Anas Nashif --- .github/workflows/blackbox_tests.yml | 4 ++-- .github/workflows/bsim-tests.yaml | 4 ++-- .github/workflows/clang.yaml | 4 ++-- .github/workflows/codecov.yaml | 4 ++-- .github/workflows/errno.yml | 4 ++-- .github/workflows/footprint-tracking.yml | 4 ++-- .github/workflows/footprint.yml | 4 ++-- .github/workflows/twister.yaml | 8 ++++---- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/blackbox_tests.yml b/.github/workflows/blackbox_tests.yml index 089b0c3e816..680baf894eb 100644 --- a/.github/workflows/blackbox_tests.yml +++ b/.github/workflows/blackbox_tests.yml @@ -30,9 +30,9 @@ jobs: python-version: [3.8, 3.9, '3.10'] os: [ubuntu-22.04] container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 steps: - name: Apply Container Owner Mismatch Workaround diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 435d61c3085..37a8234a9a2 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -30,13 +30,13 @@ jobs: if: github.repository_owner == 'zephyrproject-rtos' runs-on: zephyr-runner-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' volumes: - /repo-cache/zephyrproject:/github/cache/zephyrproject env: ZEPHYR_TOOLCHAIN_VARIANT: zephyr - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components EDTT_PATH: ../tools/edtt diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 9108d31b45b..6b0762547cc 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -11,7 +11,7 @@ jobs: if: github.repository_owner == 'zephyrproject-rtos' runs-on: zephyr-runner-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' volumes: - /repo-cache/zephyrproject:/github/cache/zephyrproject @@ -20,7 +20,7 @@ jobs: matrix: platform: ["native_posix"] env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 0bf6f3ccfd2..92cf90b8299 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -13,7 +13,7 @@ jobs: if: github.repository == 'zephyrproject-rtos/zephyr' runs-on: zephyr-runner-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' volumes: - /repo-cache/zephyrproject:/github/cache/zephyrproject @@ -22,7 +22,7 @@ jobs: matrix: platform: ["native_posix", "qemu_x86", "unit_testing"] env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 steps: - name: Apply container owner mismatch workaround run: | diff --git a/.github/workflows/errno.yml b/.github/workflows/errno.yml index 6f76d43a312..537470f0a22 100644 --- a/.github/workflows/errno.yml +++ b/.github/workflows/errno.yml @@ -10,9 +10,9 @@ jobs: check-errno: runs-on: ubuntu-22.04 container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 steps: - name: Apply container owner mismatch workaround diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index 5640f7ac7cf..63a1277be17 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -25,12 +25,12 @@ jobs: runs-on: ubuntu-22.04 if: github.repository_owner == 'zephyrproject-rtos' container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' strategy: fail-fast: false env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 ZEPHYR_TOOLCHAIN_VARIANT: zephyr steps: - name: Apply container owner mismatch workaround diff --git a/.github/workflows/footprint.yml b/.github/workflows/footprint.yml index 253823b33b0..6a7005f1880 100644 --- a/.github/workflows/footprint.yml +++ b/.github/workflows/footprint.yml @@ -11,12 +11,12 @@ jobs: runs-on: ubuntu-22.04 if: github.repository == 'zephyrproject-rtos/zephyr' container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' strategy: fail-fast: false env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 ZEPHYR_TOOLCHAIN_VARIANT: zephyr steps: - name: Apply container owner mismatch workaround diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 52316f58a6a..f77980a349d 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -24,7 +24,7 @@ jobs: if: github.repository_owner == 'zephyrproject-rtos' runs-on: zephyr-runner-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' volumes: - /repo-cache/zephyrproject:/github/cache/zephyrproject @@ -36,7 +36,7 @@ jobs: MATRIX_SIZE: 10 PUSH_MATRIX_SIZE: 15 DAILY_MATRIX_SIZE: 80 - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components TESTS_PER_BUILDER: 700 @@ -122,7 +122,7 @@ jobs: needs: twister-build-prep if: needs.twister-build-prep.outputs.size != 0 container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' volumes: - /repo-cache/zephyrproject:/github/cache/zephyrproject @@ -131,7 +131,7 @@ jobs: matrix: subset: ${{fromJSON(needs.twister-build-prep.outputs.subset)}} env: - ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 + ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components TWISTER_COMMON: ' --force-color --inline-logs -v -N -M --retry-failed 3 ' From 687f2507e308a55eb951a3f0d71c29a4b0fd4bf2 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 25 Sep 2023 12:03:31 +0000 Subject: [PATCH 1020/4498] doc: point to new zephyr sdk: 0.16.3 Change docs to point to new Zephyr SDK. Signed-off-by: Anas Nashif --- doc/develop/getting_started/index.rst | 38 +++++++++---------- .../getting_started/installation_linux.rst | 12 +++--- doc/develop/toolchains/zephyr_sdk.rst | 38 +++++++++---------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index ff97c093420..636eec29788 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -497,12 +497,12 @@ that are used to emulate, flash and debug Zephyr applications. .. _ubuntu_zephyr_sdk: #. Download and verify the `Zephyr SDK bundle - `_: + `_: .. code-block:: bash cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace ``x86_64`` @@ -512,7 +512,7 @@ that are used to emulate, flash and debug Zephyr applications. .. code-block:: bash - tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz + tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz .. note:: It is recommended to extract the Zephyr SDK bundle at one of the following locations: @@ -524,15 +524,15 @@ that are used to emulate, flash and debug Zephyr applications. * ``/opt`` * ``/usr/local`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.1``. + ``$HOME/zephyr-sdk-0.16.3``. #. Run the Zephyr SDK bundle setup script: .. code-block:: bash - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 ./setup.sh .. note:: @@ -546,7 +546,7 @@ that are used to emulate, flash and debug Zephyr applications. .. code-block:: bash - sudo cp ~/zephyr-sdk-0.16.1/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d + sudo cp ~/zephyr-sdk-0.16.3/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d sudo udevadm control --reload .. group-tab:: macOS @@ -554,12 +554,12 @@ that are used to emulate, flash and debug Zephyr applications. .. _macos_zephyr_sdk: #. Download and verify the `Zephyr SDK bundle - `_: + `_: .. code-block:: bash cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_macos-x86_64.tar.xz + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace @@ -569,7 +569,7 @@ that are used to emulate, flash and debug Zephyr applications. .. code-block:: bash - tar xvf zephyr-sdk-0.16.1_macos-x86_64.tar.xz + tar xvf zephyr-sdk-0.16.3_macos-x86_64.tar.xz .. note:: It is recommended to extract the Zephyr SDK bundle at one of the following locations: @@ -581,15 +581,15 @@ that are used to emulate, flash and debug Zephyr applications. * ``/opt`` * ``/usr/local`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.1``. + ``$HOME/zephyr-sdk-0.16.3``. #. Run the Zephyr SDK bundle setup script: .. code-block:: bash - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 ./setup.sh .. note:: @@ -605,18 +605,18 @@ that are used to emulate, flash and debug Zephyr applications. #. Open a ``cmd.exe`` window by pressing the Windows key typing "cmd.exe". #. Download the `Zephyr SDK bundle - `_: + `_: .. code-block:: console cd %HOMEPATH% - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_windows-x86_64.7z + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z #. Extract the Zephyr SDK bundle archive: .. code-block:: console - 7z x zephyr-sdk-0.16.1_windows-x86_64.7z + 7z x zephyr-sdk-0.16.3_windows-x86_64.7z .. note:: It is recommended to extract the Zephyr SDK bundle at one of the following locations: @@ -624,15 +624,15 @@ that are used to emulate, flash and debug Zephyr applications. * ``%HOMEPATH%`` * ``%PROGRAMFILES%`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``%HOMEPATH%``, the resulting installation path will be - ``%HOMEPATH%\zephyr-sdk-0.16.1``. + ``%HOMEPATH%\zephyr-sdk-0.16.3``. #. Run the Zephyr SDK bundle setup script: .. code-block:: console - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 setup.cmd .. note:: diff --git a/doc/develop/getting_started/installation_linux.rst b/doc/develop/getting_started/installation_linux.rst index acb10471c6e..a7b71317fed 100644 --- a/doc/develop/getting_started/installation_linux.rst +++ b/doc/develop/getting_started/installation_linux.rst @@ -228,11 +228,11 @@ The Zephyr SDK supports the following target architectures: Follow these steps to install the Zephyr SDK: #. Download and verify the `Zephyr SDK bundle - `_: + `_: .. code-block:: bash - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing You can change ``0.16.1`` to another version if needed; the `Zephyr SDK @@ -246,13 +246,13 @@ Follow these steps to install the Zephyr SDK: .. code-block:: bash cd - tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz + tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz #. Run the Zephyr SDK bundle setup script: .. code-block:: bash - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 ./setup.sh If this fails, make sure Zephyr's dependencies were installed as described @@ -271,9 +271,9 @@ If you relocate the SDK directory, you need to re-run the setup script. * ``/opt`` * ``/usr/local`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.1``. + ``$HOME/zephyr-sdk-0.16.3``. If you install the Zephyr SDK outside any of these locations, you must register the Zephyr SDK in the CMake package registry by running the setup diff --git a/doc/develop/toolchains/zephyr_sdk.rst b/doc/develop/toolchains/zephyr_sdk.rst index 951ddb9b9a8..c128708f508 100644 --- a/doc/develop/toolchains/zephyr_sdk.rst +++ b/doc/develop/toolchains/zephyr_sdk.rst @@ -76,10 +76,10 @@ Install Zephyr SDK on Linux .. code-block:: bash - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing - You can change ``0.16.1`` to another version if needed; the `Zephyr SDK + You can change ``0.16.3`` to another version if needed; the `Zephyr SDK Releases`_ page contains all available SDK releases. If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace @@ -90,13 +90,13 @@ Install Zephyr SDK on Linux .. code-block:: bash cd - tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz + tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz #. Run the Zephyr SDK bundle setup script: .. code-block:: bash - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 ./setup.sh If this fails, make sure Zephyr's dependencies were installed as described @@ -116,9 +116,9 @@ If you relocate the SDK directory, you need to re-run the setup script. * ``/opt`` * ``/usr/local`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.1``. + ``$HOME/zephyr-sdk-0.16.3``. .. _toolchain_zephyr_sdk_install_macos: @@ -130,8 +130,8 @@ Install Zephyr SDK on macOS .. code-block:: bash cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_macos-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. @@ -140,7 +140,7 @@ Install Zephyr SDK on macOS .. code-block:: bash - tar xvf zephyr-sdk-0.16.1_macos-x86_64.tar.xz + tar xvf zephyr-sdk-0.16.3_macos-x86_64.tar.xz .. note:: It is recommended to extract the Zephyr SDK bundle at one of the following @@ -153,15 +153,15 @@ Install Zephyr SDK on macOS * ``/opt`` * ``/usr/local`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.1``. + ``$HOME/zephyr-sdk-0.16.3``. #. Run the Zephyr SDK bundle setup script: .. code-block:: bash - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 ./setup.sh .. note:: @@ -182,13 +182,13 @@ Install Zephyr SDK on Windows .. code-block:: console cd %HOMEPATH% - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_windows-x86_64.7z + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z #. Extract the Zephyr SDK bundle archive: .. code-block:: console - 7z x zephyr-sdk-0.16.1_windows-x86_64.7z + 7z x zephyr-sdk-0.16.3_windows-x86_64.7z .. note:: It is recommended to extract the Zephyr SDK bundle at one of the following @@ -197,15 +197,15 @@ Install Zephyr SDK on Windows * ``%HOMEPATH%`` * ``%PROGRAMFILES%`` - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.1`` directory and, when + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when extracted under ``%HOMEPATH%``, the resulting installation path will be - ``%HOMEPATH%\zephyr-sdk-0.16.1``. + ``%HOMEPATH%\zephyr-sdk-0.16.3``. #. Run the Zephyr SDK bundle setup script: .. code-block:: console - cd zephyr-sdk-0.16.1 + cd zephyr-sdk-0.16.3 setup.cmd .. note:: @@ -214,6 +214,6 @@ Install Zephyr SDK on Windows You must rerun the setup script if you relocate the Zephyr SDK bundle directory after the initial setup. -.. _Zephyr SDK bundle: https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.1 +.. _Zephyr SDK bundle: https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.3 .. _Zephyr SDK Releases: https://github.com/zephyrproject-rtos/sdk-ng/tags .. _Zephyr SDK Version Compatibility Matrix: https://github.com/zephyrproject-rtos/sdk-ng/wiki/Zephyr-SDK-Version-Compatibility-Matrix From 59a15818e3a947e8a4e3994c9e1cfa18ded931cc Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 11:38:22 +0000 Subject: [PATCH 1021/4498] tests: uart_emul: remove hardware dependency Remove depends_on in test, this is not needed and not part of any board. Signed-off-by: Anas Nashif --- tests/drivers/uart/uart_emul/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/drivers/uart/uart_emul/testcase.yaml b/tests/drivers/uart/uart_emul/testcase.yaml index 087a3408415..3731e8ee0b9 100644 --- a/tests/drivers/uart/uart_emul/testcase.yaml +++ b/tests/drivers/uart/uart_emul/testcase.yaml @@ -3,7 +3,6 @@ common: - drivers - uart harness: ztest - depends_on: uart_emul tests: drivers.uart_emul.polling: platform_allow: qemu_x86 From 8eedef6f9438d24acdf9fc6bd47a96431cd78173 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 11:38:53 +0000 Subject: [PATCH 1022/4498] tests: dma/chan_blen_transfer: fix hardware dependency and syntax Removed 'drivers' from supported field and fix syntax. Signed-off-by: Anas Nashif --- tests/drivers/dma/chan_blen_transfer/testcase.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/drivers/dma/chan_blen_transfer/testcase.yaml b/tests/drivers/dma/chan_blen_transfer/testcase.yaml index 972313adff0..b87f7bb9d34 100644 --- a/tests/drivers/dma/chan_blen_transfer/testcase.yaml +++ b/tests/drivers/dma/chan_blen_transfer/testcase.yaml @@ -1,15 +1,17 @@ tests: drivers.dma.chan_blen_transfer: min_ram: 16 - depends_on: dma + depends_on: + - dma tags: - - drivers - dma filter: dt_nodelabel_enabled("test_dma0") drivers.dma.chan_blen_transfer.low_footprint: - min_ram: 6 - depends_on: dma - - drivers + tags: + - dma + min_ram: 12 + depends_on: - dma filter: dt_nodelabel_enabled("test_dma0") - platform_allow: nucleo_c031c6 + platform_allow: + - nucleo_c031c6 From 3e2ada74517a105684efb9f636b8ef6f9cd8fed2 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 11:40:21 +0000 Subject: [PATCH 1023/4498] tests: tracing: TraceRecorderSource was renamed to percepio Change module name in dependencies of test. Signed-off-by: Anas Nashif --- samples/subsys/tracing/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index 75868ade861..dda98638a58 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -69,4 +69,4 @@ tests: platform_allow: frdm_k64f extra_args: CONF_FILE="prj_percepio.conf" modules: - - TraceRecorderSource + - percepio From 6ff3f622959f2f4f87b22fd03b72006e6081bb26 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 11:45:08 +0000 Subject: [PATCH 1024/4498] boards: mec172xevb_assy6906: add spi as supported Add SPI to supported features in board yaml file. Signed-off-by: Anas Nashif --- boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml index 2279b2a7e97..d7a96791cd6 100644 --- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml +++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.yaml @@ -19,6 +19,7 @@ supported: - adc - pwm - counter + - spi testing: binaries: - spi_image.bin From a833d20ffb3482d8a0c5601d8fcb0bc06b066bd6 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 12:23:10 +0000 Subject: [PATCH 1025/4498] boards: nucleo_g0b1re: add arduino_serial as supported To make some tests requiring the dependency happy. Signed-off-by: Anas Nashif --- boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml | 1 + samples/drivers/w1/scanner/sample.yaml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml index 259a1abcd90..bc267274401 100644 --- a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml +++ b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.yaml @@ -13,6 +13,7 @@ supported: - arduino_gpio - arduino_i2c - arduino_spi + - arduino_serial - uart - gpio - i2c diff --git a/samples/drivers/w1/scanner/sample.yaml b/samples/drivers/w1/scanner/sample.yaml index 1ffb7ffc930..c05df2c59e2 100644 --- a/samples/drivers/w1/scanner/sample.yaml +++ b/samples/drivers/w1/scanner/sample.yaml @@ -37,7 +37,8 @@ tests: - "Number of devices found on bus: .*" fixture: w1_scanner_ds2485 samples.drivers.w1.scanner.w1_serial: - depends_on: arduino_serial + depends_on: + - arduino_serial extra_args: DTC_OVERLAY_FILE=w1_serial.overlay platform_allow: - nrf52840dk_nrf52840 From ae92df1e4a44b01eb5206fea30d40da5d56e5c16 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Sep 2023 08:16:49 -0700 Subject: [PATCH 1026/4498] libc/common: Don't use malloc mutex when CONFIG_MULTITHREADING=n When multithreading is disabled, the whole mutex infrastructure isn't available. The common malloc code wasn't checking for this case which caused build failures. Signed-off-by: Keith Packard Tested-by: Detlev Zundel dzu@member.fsf.org --- lib/libc/common/source/stdlib/malloc.c | 46 ++++++++++++++++---------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 50c688fa7f2..a98b3e234d3 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -11,7 +11,9 @@ #include #include #include +#ifdef CONFIG_MULTITHREADING #include +#endif #include #include #include @@ -113,14 +115,31 @@ extern char _heap_sentry[]; # endif /* else ALLOCATE_HEAP_AT_STARTUP */ POOL_SECTION static struct sys_heap z_malloc_heap; + +#ifdef CONFIG_MULTITHREADING MALLOC_SECTION SYS_MUTEX_DEFINE(z_malloc_heap_mutex); -void *malloc(size_t size) -{ +static inline void +malloc_lock(void) { int lock_ret; lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); __ASSERT_NO_MSG(lock_ret == 0); +} + +static inline void +malloc_unlock(void) +{ + (void) sys_mutex_unlock(&z_malloc_heap_mutex); +} +#else +#define malloc_lock() +#define malloc_unlock() +#endif + +void *malloc(size_t size) +{ + malloc_lock(); void *ret = sys_heap_aligned_alloc(&z_malloc_heap, __alignof__(z_max_align_t), @@ -129,17 +148,14 @@ void *malloc(size_t size) errno = ENOMEM; } - (void) sys_mutex_unlock(&z_malloc_heap_mutex); + malloc_unlock(); return ret; } void *aligned_alloc(size_t alignment, size_t size) { - int lock_ret; - - lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); - __ASSERT_NO_MSG(lock_ret == 0); + malloc_lock(); void *ret = sys_heap_aligned_alloc(&z_malloc_heap, alignment, @@ -148,7 +164,7 @@ void *aligned_alloc(size_t alignment, size_t size) errno = ENOMEM; } - (void) sys_mutex_unlock(&z_malloc_heap_mutex); + malloc_unlock(); return ret; } @@ -222,10 +238,7 @@ static int malloc_prepare(void) void *realloc(void *ptr, size_t requested_size) { - int lock_ret; - - lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); - __ASSERT_NO_MSG(lock_ret == 0); + malloc_lock(); void *ret = sys_heap_aligned_realloc(&z_malloc_heap, ptr, __alignof__(z_max_align_t), @@ -235,19 +248,16 @@ void *realloc(void *ptr, size_t requested_size) errno = ENOMEM; } - (void) sys_mutex_unlock(&z_malloc_heap_mutex); + malloc_unlock(); return ret; } void free(void *ptr) { - int lock_ret; - - lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); - __ASSERT_NO_MSG(lock_ret == 0); + malloc_lock(); sys_heap_free(&z_malloc_heap, ptr); - (void) sys_mutex_unlock(&z_malloc_heap_mutex); + malloc_unlock(); } SYS_INIT(malloc_prepare, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); From 6338768b45ac415b7a681c467a6c23d53b9e8809 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 23:42:24 +0000 Subject: [PATCH 1027/4498] ci: rename twister testing workflow Rename blackbox_tests.yml -> twister_tests_blackbox.yml for clarity. Signed-off-by: Anas Nashif --- .../workflows/{blackbox_tests.yml => twister_tests_blackbox.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{blackbox_tests.yml => twister_tests_blackbox.yml} (100%) diff --git a/.github/workflows/blackbox_tests.yml b/.github/workflows/twister_tests_blackbox.yml similarity index 100% rename from .github/workflows/blackbox_tests.yml rename to .github/workflows/twister_tests_blackbox.yml From b90288b42b5083cb98e54ebac992f61bb692d2c8 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 23:43:16 +0000 Subject: [PATCH 1028/4498] ci: do not run twister tests on push events This workflow is needed for pull requests, not push events. Signed-off-by: Anas Nashif --- .github/workflows/twister_tests_blackbox.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 680baf894eb..abf8b324356 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -4,14 +4,6 @@ name: Twister BlackBox TestSuite on: - push: - branches: - - main - paths: - - 'scripts/pylib/twister/**' - - 'scripts/twister' - - 'scripts/tests/twister_blackbox/**' - - '.github/workflows/blackbox_tests.yml' pull_request: branches: - main @@ -19,7 +11,7 @@ on: - 'scripts/pylib/twister/**' - 'scripts/twister' - 'scripts/tests/twister_blackbox/**' - - '.github/workflows/blackbox_tests.yml' + - '.github/workflows/twister_tests_blackbox.yml' jobs: twister-tests: From 0b57fdb1add3489d2dbd1e3c797354bb63f84ed1 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 22 Sep 2023 19:05:17 +0530 Subject: [PATCH 1029/4498] dts: bindings: dma: intel_lpss: Added phandle dma-parent Added a phandle named dma-parent to get base address instead of adding DMA as child node because it is causing a build warning (avoid_unnecessary_addr_size) if the parent instance has "#address-cells/#size-cells" dts properties marked required and child doesn't have reg property. DMA doesn't have reg as it gets the base address from parent device Signed-off-by: Anisetti Avinash Krishna --- dts/bindings/dma/intel,lpss.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dts/bindings/dma/intel,lpss.yaml b/dts/bindings/dma/intel,lpss.yaml index d9fc4a60f11..5f1954216f0 100644 --- a/dts/bindings/dma/intel,lpss.yaml +++ b/dts/bindings/dma/intel,lpss.yaml @@ -11,5 +11,10 @@ properties: "#dma-cells": const: 1 + dma-parent: + type: phandle + description: | + Parent device for LPSS DMA to get its base address. + dma-cells: - channel From d7c353cdf458fd53fde354fb766e6e2b227f84fe Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 22 Sep 2023 19:10:09 +0530 Subject: [PATCH 1030/4498] drivers: dma: intel_lpss: Used phandle to get base address Added usage of dma_parent phandle instead of using parent-child method to get DMA base address. Signed-off-by: Anisetti Avinash Krishna --- drivers/dma/Kconfig.intel_lpss | 3 ++- drivers/dma/dma_intel_lpss.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma/Kconfig.intel_lpss b/drivers/dma/Kconfig.intel_lpss index d475c742784..3f58618d869 100644 --- a/drivers/dma/Kconfig.intel_lpss +++ b/drivers/dma/Kconfig.intel_lpss @@ -5,8 +5,9 @@ config DMA_INTEL_LPSS bool "INTEL LPSS DMA driver" - default n + default y depends on DT_HAS_INTEL_LPSS_ENABLED + select DEVICE_DEPS help INTEL LPSS DMA driver. diff --git a/drivers/dma/dma_intel_lpss.c b/drivers/dma/dma_intel_lpss.c index c1ae1763e50..b76d0820815 100644 --- a/drivers/dma/dma_intel_lpss.c +++ b/drivers/dma/dma_intel_lpss.c @@ -82,7 +82,7 @@ static const struct dma_driver_api dma_intel_lpss_driver_api = { .dw_cfg = { \ .base = 0, \ }, \ - .parent = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .parent = DEVICE_DT_GET(DT_INST_PHANDLE(n, dma_parent)),\ }; \ \ static struct dw_dma_dev_data dma_intel_lpss##n##_data = { \ From d118ef5fde0ce74d7220c28324568e0937898394 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Mon, 25 Sep 2023 17:36:18 +0200 Subject: [PATCH 1031/4498] doc: migration: Move picolibc section to required changes After having migrated a bunch of apps to the new default C library we have realized that some of the caveats described in the existing picolibc section of the migration guide do require action on the user more often than previously thought. In order to ensure that all users see those and can act upon them, move the picolibc migration info to the required changes section. Signed-off-by: Carles Cufi --- doc/releases/migration-guide-3.5.rst | 93 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 8c53ae0bf97..b59c8093f9f 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -63,6 +63,51 @@ Required changes channels for temperature and Vbat are identical, and the impossibility of determining what we want to measure using solely the ADC API. +* The default C library used on most targets has changed from the built-in + minimal C library to Picolibc. While both provide standard C library + interfaces and shouldn't cause any behavioral regressions for applications, + there are a few side effects to be aware of when migrating to Picolibc. + + * Picolibc enables thread local storage + (:kconfig:option:`CONFIG_THREAD_LOCAL_STORAGE`) where supported. This + changes some internal operations within the kernel that improve + performance using some TLS variables. Zephyr places TLS variables in the + memory reserved for the stack, so stack usage for every thread will + increase by 8-16 bytes. + + * Picolibc uses the same malloc implementation as the minimal C library, but + the default heap size depends on which C library is in use. When using the + minimal C library, the default heap is zero bytes, which means that malloc + will always fail. When using Picolibc, the default is 16kB with + :kconfig:option:`CONFIG_MMU` or :kconfig:option:`ARCH_POSIX`, 2kB with + :kconfig:option:`CONFIG_USERSPACE` and + :kconfig:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`. For all + other targets, the default heap uses all remaining memory on the system. + You can change this by adjusting + :kconfig:option:`CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE`. + + * Picolibc can either be built as part of the OS build or pulled from the + toolchain. When building as part of the OS, the build will increase by + approximately 1000 files. + + * When using the standard C++ library with Picolibc, both of those must come + from the toolchain as the standard C++ library depends upon the C library + ABI. + + * Picolibc removes the ``-ffreestanding`` compiler option. This allows + significant compiler optimization improvements, but also means that the + compiler will now warn about declarations of `main` which don't conform to + the Zephyr required type -- ``int main(void)``. + + * Picolibc's default floating point input/output code is larger than the + minimal C library version (this is necessary to conform with the C + language "round trip" requirements for these operations). If you use + :kconfig:option:`CONFIG_CBPRINTF_FP_SUPPORT`, you will see increased + memory usage unless you also disable + :kconfig:option:`CONFIG_PICOLIBC_IO_FLOAT_EXACT`, which switches Picolibc + to a smaller, but inexact conversion algorithm. This requires building + Picolibc as a module. + Recommended Changes ******************* @@ -106,51 +151,3 @@ Recommended Changes will be removed in future releases. Note that these changes do not apply to initialization levels used in the context of the ``init.h`` API, e.g. :c:macro:`SYS_INIT`. - -Picolibc-related Changes -************************ - -The default C library used on most targets has changed from the built-in -minimal C library to Picolibc. While both provide standard C library -interfaces and shouldn't cause any behavioral regressions for applications, -there are a few side effects to be aware of when migrating to Picolibc. - -* Picolibc enables thread local storage - (:kconfig:option:`CONFIG_THREAD_LOCAL_STORAGE`) where supported. This - changes some internal operations within the kernel that improve - performance using some TLS variables. Zephyr places TLS variables in the - memory reserved for the stack, so stack usage for every thread will - increase by 8-16 bytes. - -* Picolibc uses the same malloc implementation as the minimal C library, but - the default heap size depends on which C library is in use. When using the - minimal C library, the default heap is zero bytes, which means that malloc - will always fail. When using Picolibc, the default is 16kB with - :kconfig:option:`CONFIG_MMU` or :kconfig:option:`ARCH_POSIX`, 2kB with - :kconfig:option:`CONFIG_USERSPACE` and - :kconfig:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`. For all - other targets, the default heap uses all remaining memory on the system. - You can change this by adjusting - :kconfig:option:`CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE`. - -* Picolibc can either be built as part of the OS build or pulled from the - toolchain. When building as part of the OS, the build will increase by - approximately 1000 files. - -* When using the standard C++ library with Picolibc, both of those must come - from the toolchain as the standard C++ library depends upon the C library - ABI. - -* Picolibc removes the ``-ffreestanding`` compiler option. This allows - significant compiler optimization improvements, but also means that the - compiler will now warn about declarations of `main` which don't conform to - the Zephyr required type -- ``int main(void)``. - -* Picolibc's default floating point input/output code is larger than the - minimal C library version (this is necessary to conform with the C - language "round trip" requirements for these operations). If you use - :kconfig:option:`CONFIG_CBPRINTF_FP_SUPPORT`, you will see increased - memory usage unless you also disable - :kconfig:option:`CONFIG_PICOLIBC_IO_FLOAT_EXACT`, which switches Picolibc - to a smaller, but inexact conversion algorithm. This requires building - Picolibc as a module. From 39aa2ad719a87df8b426a925faded60ca34d017c Mon Sep 17 00:00:00 2001 From: Michal Morsisko Date: Wed, 9 Aug 2023 21:14:16 +0200 Subject: [PATCH 1032/4498] lib: crc: Add CRC4 Add two new functions: crc4 for generic calculations of CRC4, and crc4_ti which use look-up table for faster calculations of CRC4 algortihms that base on 0x03 polynomial. Signed-off-by: Michal Morsisko --- include/zephyr/sys/crc.h | 41 +++++++++++++++++++++++++++++++ lib/crc/CMakeLists.txt | 1 + lib/crc/crc4_sw.c | 53 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 lib/crc/crc4_sw.c diff --git a/include/zephyr/sys/crc.h b/include/zephyr/sys/crc.h index 7c131f4cbfd..e29fce45d9e 100644 --- a/include/zephyr/sys/crc.h +++ b/include/zephyr/sys/crc.h @@ -47,6 +47,8 @@ extern "C" { * These values should be used with the @ref crc dispatch function. */ enum crc_type { + CRC4, /**< Use @ref crc4 */ + CRC4_TI, /**< Use @ref crc4_ti */ CRC7_BE, /**< Use @ref crc7_be */ CRC8, /**< Use @ref crc8 */ CRC8_CCITT, /**< Use @ref crc8_ccitt */ @@ -278,6 +280,41 @@ uint8_t crc8_ccitt(uint8_t initial_value, const void *buf, size_t len); */ uint8_t crc7_be(uint8_t seed, const uint8_t *src, size_t len); +/** + * @brief Compute the CRC-4 checksum of a buffer. + * + * Used by the TMAG5170 sensor. Uses 0x03 as the + * polynomial with no reflection. 4 most significant + * bits of the CRC result will be set to zero. + * + * @param seed Value to seed the CRC with + * @param src Input bytes for the computation + * @param len Length of the input in bytes + * + * @return The computed CRC4 value + */ +uint8_t crc4_ti(uint8_t seed, const uint8_t *src, size_t len); + +/** + * @brief Generic function for computing CRC 4 + * + * Compute CRC 4 by passing in the address of the input, the input length + * and polynomial used in addition to the initial value. The input buffer + * must be aligned to a whole byte. It is guaranteed that 4 most significant + * bits of the result will be set to zero. + * + * @param src Input bytes for the computation + * @param len Length of the input in bytes + * @param polynomial The polynomial to use omitting the leading x^4 + * coefficient + * @param initial_value Initial value for the CRC computation + * @param reversed Should we use reflected/reversed values or not + * + * @return The computed CRC4 value + */ +uint8_t crc4(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value, + bool reversed); + /** * @brief Compute a CRC checksum, in a generic way. * @@ -305,6 +342,10 @@ static inline uint32_t crc_by_type(enum crc_type type, const uint8_t *src, size_ bool last) { switch (type) { + case CRC4: + return crc4(src, len, poly, seed, reflect); + case CRC4_TI: + return crc4_ti(seed, src, len); case CRC7_BE: return crc7_be(seed, src, len); case CRC8: diff --git a/lib/crc/CMakeLists.txt b/lib/crc/CMakeLists.txt index bf652ba4fcf..a85cc3b05cc 100644 --- a/lib/crc/CMakeLists.txt +++ b/lib/crc/CMakeLists.txt @@ -6,5 +6,6 @@ zephyr_sources_ifdef(CONFIG_CRC crc16_sw.c crc8_sw.c crc7_sw.c + crc4_sw.c ) zephyr_sources_ifdef(CONFIG_CRC_SHELL crc_shell.c) diff --git a/lib/crc/crc4_sw.c b/lib/crc/crc4_sw.c new file mode 100644 index 00000000000..e636a2c8fae --- /dev/null +++ b/lib/crc/crc4_sw.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Michal Morsisko + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +uint8_t crc4(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value, + bool reversed) +{ + uint8_t crc = initial_value; + size_t i, j, k; + + for (i = 0; i < len; i++) { + for (j = 0; j < 2; j++) { + crc ^= ((src[i] >> (4 * (1 - j))) & 0xf); + + for (k = 0; k < 4; k++) { + if (reversed) { + if (crc & 0x01) { + crc = (crc >> 1) ^ polynomial; + } else { + crc >>= 1; + } + } else { + if (crc & 0x8) { + crc = (crc << 1) ^ polynomial; + } else { + crc <<= 1; + } + } + } + } + } + + return crc & 0xF; +} + +uint8_t crc4_ti(uint8_t seed, const uint8_t *src, size_t len) +{ + static const uint8_t lookup[8] = { 0x03, 0x65, 0xcf, 0xa9, 0xb8, 0xde, 0x74, 0x12 }; + uint8_t index; + + for (size_t i = 0; i < len; i++) { + for (size_t j = 0U; j < 2U; j++) { + index = seed ^ ((src[i] >> (4*(1-j))) & 0xf); + seed = (lookup[index >> 1] >> (1 - (index & 1)) * 4) & 0xf; + } + } + + return seed; +} From 8e32b5ee0a97e8a8a6ffcd094b617ffbf2a91e66 Mon Sep 17 00:00:00 2001 From: Michal Morsisko Date: Wed, 9 Aug 2023 21:34:05 +0200 Subject: [PATCH 1033/4498] drivers: sensor: Add suport for TMAG5170 3D Hall sensor Introduce support for Texas Instruments TMAG5170 high-precision linear 3D Hall-effect SPI sensor. This driver allows to configure measurements on magnetic and temperature channels. It is also possible to read rotation of the magnet. Signed-off-by: Michal Morsisko --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/tmag5170/CMakeLists.txt | 6 + drivers/sensor/tmag5170/Kconfig | 69 +++ drivers/sensor/tmag5170/tmag5170.c | 586 ++++++++++++++++++ drivers/sensor/tmag5170/tmag5170.h | 66 ++ drivers/sensor/tmag5170/tmag5170_trigger.c | 149 +++++ dts/bindings/sensor/ti,tmag5170.yaml | 213 +++++++ tests/drivers/build_all/sensor/app.overlay | 3 +- .../sensor/sensors_trigger_global.conf | 1 + .../sensor/sensors_trigger_none.conf | 1 + .../build_all/sensor/sensors_trigger_own.conf | 1 + tests/drivers/build_all/sensor/spi.dtsi | 8 + 13 files changed, 1104 insertions(+), 1 deletion(-) create mode 100644 drivers/sensor/tmag5170/CMakeLists.txt create mode 100644 drivers/sensor/tmag5170/Kconfig create mode 100644 drivers/sensor/tmag5170/tmag5170.c create mode 100644 drivers/sensor/tmag5170/tmag5170.h create mode 100644 drivers/sensor/tmag5170/tmag5170_trigger.c create mode 100644 dts/bindings/sensor/ti,tmag5170.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 2aba319c16f..782115ca130 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -135,6 +135,7 @@ add_subdirectory_ifdef(CONFIG_TEMP_NRF5 nrf5) add_subdirectory_ifdef(CONFIG_TH02 th02) add_subdirectory_ifdef(CONFIG_TI_HDC ti_hdc) add_subdirectory_ifdef(CONFIG_TI_HDC20XX ti_hdc20xx) +add_subdirectory_ifdef(CONFIG_TMAG5170 tmag5170) add_subdirectory_ifdef(CONFIG_TMD2620 tmd2620) add_subdirectory_ifdef(CONFIG_TMP007 tmp007) add_subdirectory_ifdef(CONFIG_TMP108 tmp108) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index dd4917cf64d..f406b6d1ffe 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -191,6 +191,7 @@ source "drivers/sensor/tcs3400/Kconfig" source "drivers/sensor/th02/Kconfig" source "drivers/sensor/ti_hdc/Kconfig" source "drivers/sensor/ti_hdc20xx/Kconfig" +source "drivers/sensor/tmag5170/Kconfig" source "drivers/sensor/tmd2620/Kconfig" source "drivers/sensor/tmp007/Kconfig" source "drivers/sensor/tmp108/Kconfig" diff --git a/drivers/sensor/tmag5170/CMakeLists.txt b/drivers/sensor/tmag5170/CMakeLists.txt new file mode 100644 index 00000000000..f196c2019a2 --- /dev/null +++ b/drivers/sensor/tmag5170/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(tmag5170.c) +zephyr_library_sources_ifdef(CONFIG_TMAG5170_TRIGGER tmag5170_trigger.c) diff --git a/drivers/sensor/tmag5170/Kconfig b/drivers/sensor/tmag5170/Kconfig new file mode 100644 index 00000000000..592b2382448 --- /dev/null +++ b/drivers/sensor/tmag5170/Kconfig @@ -0,0 +1,69 @@ +# Texas Instruments TMAG5170 high-precision, linear 3D Hall-effect sensor with SPI bus interface + +# Copyright (c) 2023 Michal Morsisko +# SPDX-License-Identifier: Apache-2.0 + +menuconfig TMAG5170 + bool "TMAG5170 SPI Hall-effect sensor driver" + default y + depends on DT_HAS_TI_TMAG5170_ENABLED + select SPI + help + Enable driver for TMAG5170 Hall-effect sensor driver + +if TMAG5170 + +choice TMAG5170_TRIGGER_MODE + prompt "Trigger mode" + help + Specify the type of triggering to be used by the driver. + +config TMAG5170_TRIGGER_NONE + bool "No trigger" + +config TMAG5170_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select TMAG5170_TRIGGER + +config TMAG5170_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select TMAG5170_TRIGGER + +config TMAG5170_TRIGGER_DIRECT + bool "Process trigger within interrupt context" + depends on GPIO + select TMAG5170_TRIGGER + +endchoice + +config TMAG5170_CRC + bool "Use CRC error detection" + default y + select CRC + help + Verify CRC of RX data and append CRC to TX data + +config TMAG5170_TRIGGER + bool + +if TMAG5170_TRIGGER + +config TMAG5170_THREAD_PRIORITY + int "Thread priority" + depends on TMAG5170_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config TMAG5170_THREAD_STACK_SIZE + int "Thread stack size" + depends on TMAG5170_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +endif # TMAG5170_TRIGGER + +endif # TMAG5170 diff --git a/drivers/sensor/tmag5170/tmag5170.c b/drivers/sensor/tmag5170/tmag5170.c new file mode 100644 index 00000000000..2e34f52dfab --- /dev/null +++ b/drivers/sensor/tmag5170/tmag5170.c @@ -0,0 +1,586 @@ +/* + * Copyright (c) 2023 Michal Morsisko + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tmag5170 + +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_TMAG5170_CRC) +#include +#endif + +#include "tmag5170.h" + +#define TMAG5170_REG_DEVICE_CONFIG 0x0U +#define TMAG5170_REG_SENSOR_CONFIG 0x1U +#define TMAG5170_REG_SYSTEM_CONFIG 0x2U +#define TMAG5170_REG_ALERT_CONFIG 0x3U +#define TMAG5170_REG_X_THRX_CONFIG 0x4U +#define TMAG5170_REG_Y_THRX_CONFIG 0x5U +#define TMAG5170_REG_Z_THRX_CONFIG 0x6U +#define TMAG5170_REG_T_THRX_CONFIG 0x7U +#define TMAG5170_REG_CONV_STATUS 0x8U +#define TMAG5170_REG_X_CH_RESULT 0x9U +#define TMAG5170_REG_Y_CH_RESULT 0xAU +#define TMAG5170_REG_Z_CH_RESULT 0xBU +#define TMAG5170_REG_TEMP_RESULT 0xCU +#define TMAG5170_REG_AFE_STATUS 0xDU +#define TMAG5170_REG_SYS_STATUS 0xEU +#define TMAG5170_REG_TEST_CONFIG 0xFU +#define TMAG5170_REG_OSC_MONITOR 0x10U +#define TMAG5170_REG_MAG_GAIN_CONFIG 0x11U +#define TMAG5170_REG_MAG_OFFSET_CONFIG 0x12U +#define TMAG5170_REG_ANGLE_RESULT 0x13U +#define TMAG5170_REG_MAGNITUDE_RESULT 0x14U + +#define TMAG5170_CONV_AVG_POS 12U +#define TMAG5170_CONV_AVG_MASK (BIT_MASK(3U) << TMAG5170_CONV_AVG_POS) +#define TMAG5170_CONV_AVG_SET(value) (((value) << TMAG5170_CONV_AVG_POS) &\ + TMAG5170_CONV_AVG_MASK) + +#define TMAG5170_MAG_TEMPCO_POS 8U +#define TMAG5170_MAG_TEMPCO_MASK (BIT_MASK(2U) << TMAG5170_MAG_TEMPCO_POS) +#define TMAG5170_MAG_TEMPCO_SET(value) (((value) << TMAG5170_MAG_TEMPCO_POS) &\ + TMAG5170_MAG_TEMPCO_MASK) + +#define TMAG5170_OPERATING_MODE_POS 4U +#define TMAG5170_OPERATING_MODE_MASK (BIT_MASK(3U) << TMAG5170_OPERATING_MODE_POS) +#define TMAG5170_OPERATING_MODE_SET(value) (((value) << TMAG5170_OPERATING_MODE_POS) &\ + TMAG5170_OPERATING_MODE_MASK) + +#define TMAG5170_T_CH_EN_POS 3U +#define TMAG5170_T_CH_EN_MASK (BIT_MASK(1U) << TMAG5170_T_CH_EN_POS) +#define TMAG5170_T_CH_EN_SET(value) (((value) << TMAG5170_T_CH_EN_POS) &\ + TMAG5170_T_CH_EN_MASK) + +#define TMAG5170_T_RATE_POS 2U +#define TMAG5170_T_RATE_MASK (BIT_MASK(1U) << TMAG5170_T_RATE_POS) +#define TMAG5170_T_RATE_SET(value) (((value) << TMAG5170_T_RATE_POS) &\ + TMAG5170_T_RATE_MASK) + +#define TMAG5170_ANGLE_EN_POS 14U +#define TMAG5170_ANGLE_EN_MASK (BIT_MASK(2U) << TMAG5170_ANGLE_EN_POS) +#define TMAG5170_ANGLE_EN_SET(value) (((value) << TMAG5170_ANGLE_EN_POS) &\ + TMAG5170_ANGLE_EN_MASK) + +#define TMAG5170_SLEEPTIME_POS 10U +#define TMAG5170_SLEEPTIME_MASK (BIT_MASK(4U) << TMAG5170_SLEEPTIME_POS) +#define TMAG5170_SLEEPTIME_SET(value) (((value) << TMAG5170_SLEEPTIME_POS) &\ + TMAG5170_SLEEPTIME_MASK) + +#define TMAG5170_MAG_CH_EN_POS 6U +#define TMAG5170_MAG_CH_EN_MASK (BIT_MASK(4U) << TMAG5170_MAG_CH_EN_POS) +#define TMAG5170_MAG_CH_EN_SET(value) (((value) << TMAG5170_MAG_CH_EN_POS) &\ + TMAG5170_MAG_CH_EN_MASK) + +#define TMAG5170_Z_RANGE_POS 4U +#define TMAG5170_Z_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Z_RANGE_POS) +#define TMAG5170_Z_RANGE_SET(value) (((value) << TMAG5170_Z_RANGE_POS) &\ + TMAG5170_Z_RANGE_MASK) + +#define TMAG5170_Y_RANGE_POS 2U +#define TMAG5170_Y_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Y_RANGE_POS) +#define TMAG5170_Y_RANGE_SET(value) (((value) << TMAG5170_Y_RANGE_POS) &\ + TMAG5170_Y_RANGE_MASK) + +#define TMAG5170_X_RANGE_POS 0U +#define TMAG5170_X_RANGE_MASK (BIT_MASK(2U) << TMAG5170_X_RANGE_POS) +#define TMAG5170_X_RANGE_SET(value) (((value) << TMAG5170_X_RANGE_POS) &\ + TMAG5170_X_RANGE_MASK) + +#define TMAG5170_RSLT_ALRT_POS 8U +#define TMAG5170_RSLT_ALRT_MASK (BIT_MASK(1U) << TMAG5170_RSLT_ALRT_POS) +#define TMAG5170_RSLT_ALRT_SET(value) (((value) << TMAG5170_RSLT_ALRT_POS) &\ + TMAG5170_RSLT_ALRT_MASK) + +#define TMAG5170_VER_POS 4U +#define TMAG5170_VER_MASK (BIT_MASK(2U) << TMAG5170_VER_POS) +#define TMAG5170_VER_GET(value) (((value) & TMAG5170_VER_MASK) >> TMAG5170_VER_POS) + +#define TMAG5170_A1_REV 0x0U +#define TMAG5170_A2_REV 0x1U + +#define TMAG5170_MAX_RANGE_50MT_IDX 0x0U +#define TMAG5170_MAX_RANGE_25MT_IDX 0x1U +#define TMAG5170_MAX_RANGE_100MT_IDX 0x2U +#define TMAG5170_MAX_RANGE_EXTEND_FACTOR 0x3U + +#define TMAG5170_CONFIGURATION_MODE 0x0U +#define TMAG5170_STAND_BY_MODE 0x1U +#define TMAG5170_ACTIVE_TRIGGER_MODE 0x3U +#define TMAG5170_SLEEP_MODE 0x5U +#define TMAG5170_DEEP_SLEEP_MODE 0x6U + +#define TMAG5170_MT_TO_GAUSS_RATIO 10U +#define TMAG5170_T_SENS_T0 25U +#define TMAG5170_T_ADC_T0 17522U +#define TMAG5170_T_ADC_RES 60U + +#define TMAG5170_CMD_TRIGGER_CONVERSION BIT(0U) + +#define TMAG5170_CRC_SEED 0xFU +#define TMAG5170_CRC_POLY 0x3U +#define TMAG5170_SPI_BUFFER_LEN 4U +#define TMAG5170_SET_CRC(buf, crc) ((uint8_t *)(buf))[3] |= (crc & 0x0F) +#define TMAG5170_ZERO_CRC(buf) ((uint8_t *)(buf))[3] &= 0xF0 +#define TMAG5170_GET_CRC(buf) ((uint8_t *)(buf))[3] & 0x0F + +LOG_MODULE_REGISTER(TMAG5170, CONFIG_SENSOR_LOG_LEVEL); + +static int tmag5170_transmit_raw(const struct tmag5170_dev_config *config, + uint8_t *buffer_tx, + uint8_t *buffer_rx) +{ + const struct spi_buf tx_buf = { + .buf = buffer_tx, + .len = TMAG5170_SPI_BUFFER_LEN, + }; + + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + + const struct spi_buf rx_buf = { + .buf = buffer_rx, + .len = TMAG5170_SPI_BUFFER_LEN, + }; + + const struct spi_buf_set rx = { + .buffers = &rx_buf, + .count = 1 + }; + + int ret = spi_transceive_dt(&config->bus, &tx, &rx); + + return ret; +} + +static int tmag5170_transmit(const struct device *dev, uint8_t *buffer_tx, uint8_t *buffer_rx) +{ +#if defined(CONFIG_TMAG5170_CRC) + TMAG5170_ZERO_CRC(buffer_tx); + uint8_t crc = crc4_ti(TMAG5170_CRC_SEED, buffer_tx, TMAG5170_SPI_BUFFER_LEN); + + TMAG5170_SET_CRC(buffer_tx, crc); +#endif + int ret = tmag5170_transmit_raw(dev->config, buffer_tx, buffer_rx); +#if defined(CONFIG_TMAG5170_CRC) + if (buffer_rx != NULL && ret == 0) { + uint8_t read_crc = TMAG5170_GET_CRC(buffer_rx); + + TMAG5170_ZERO_CRC(buffer_rx); + crc = crc4_ti(TMAG5170_CRC_SEED, buffer_rx, TMAG5170_SPI_BUFFER_LEN); + if (read_crc != crc) { + return -EIO; + } + } +#endif + + return ret; +} + +static int tmag5170_write_register(const struct device *dev, uint32_t reg, uint16_t data) +{ + uint8_t buffer_tx[4] = { reg, (data >> 8) & 0xFF, data & 0xFF, 0x00U }; + + return tmag5170_transmit(dev, buffer_tx, NULL); +} + +static int tmag5170_read_register(const struct device *dev, + uint32_t reg, + uint16_t *output, + uint8_t cmd) +{ + uint8_t buffer_tx[4] = { BIT(7) | reg, 0x00U, 0x00U, (cmd & BIT_MASK(4U)) << 4U }; + uint8_t buffer_rx[4] = { 0x00U }; + + int ret = tmag5170_transmit(dev, buffer_tx, buffer_rx); + + *output = (buffer_rx[1] << 8) | buffer_rx[2]; + + return ret; +} + +static int tmag5170_convert_magn_reading_to_gauss(struct sensor_value *output, + uint16_t chan_reading, + uint8_t chan_range, + uint8_t chip_revision) +{ + uint16_t max_range_mt = 0U; + + if (chan_range == TMAG5170_MAX_RANGE_50MT_IDX) { + max_range_mt = 50U; + } else if (chan_range == TMAG5170_MAX_RANGE_25MT_IDX) { + max_range_mt = 25U; + } else if (chan_range == TMAG5170_MAX_RANGE_100MT_IDX) { + max_range_mt = 100U; + } else { + return -ENOTSUP; + } + + if (chip_revision == TMAG5170_A2_REV) { + max_range_mt *= TMAG5170_MAX_RANGE_EXTEND_FACTOR; + } + + max_range_mt *= 2U; + + /* The sensor returns data in mT, we need to convert it to Gauss */ + uint32_t max_range_gauss = max_range_mt * TMAG5170_MT_TO_GAUSS_RATIO; + + /* Convert from 2's complementary system */ + int64_t result = chan_reading - ((chan_reading & 0x8000) << 1); + + result *= max_range_gauss; + + /* Scale to increase accuracy */ + result *= 100000; + + /* Divide as it is shown in datasheet */ + result /= 65536; + + /* Remove scale from the final result */ + output->val1 = result / 100000; + output->val2 = result % 100000; + + return 0; +} + +static void tmag5170_convert_temp_reading_to_celsius(struct sensor_value *output, + uint16_t chan_reading) +{ + int32_t result = chan_reading - TMAG5170_T_ADC_T0; + + result = (TMAG5170_T_SENS_T0 * 100000) + (100000 * result / (int32_t)TMAG5170_T_ADC_RES); + + output->val1 = result / 100000; + output->val2 = (result % 100000) * 10; +} + +static void tmag5170_covert_angle_reading_to_degrees(struct sensor_value *output, + uint16_t chan_reading) +{ + /* 12 MSBs store the integer part of the result, + * 4 LSBs store the fractional part of the result + */ + output->val1 = chan_reading >> 4; + output->val2 = ((chan_reading & 0xF) * 1000000) / 16; +} + +static int tmag5170_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + const struct tmag5170_dev_config *cfg = dev->config; + struct tmag5170_data *drv_data = dev->data; + int ret = 0; + + if (cfg->operating_mode == TMAG5170_STAND_BY_MODE || + cfg->operating_mode == TMAG5170_ACTIVE_TRIGGER_MODE) { + uint16_t read_status; + + tmag5170_read_register(dev, + TMAG5170_REG_SYS_STATUS, + &read_status, + TMAG5170_CMD_TRIGGER_CONVERSION); + + /* Wait for the measurement to be ready. + * The waiting time will vary depending on the configuration + */ + k_sleep(K_MSEC(5U)); + } + + switch (chan) { + case SENSOR_CHAN_MAGN_X: + ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U); + break; + case SENSOR_CHAN_MAGN_Y: + ret = tmag5170_read_register(dev, TMAG5170_REG_Y_CH_RESULT, &drv_data->y, 0U); + break; + case SENSOR_CHAN_MAGN_Z: + ret = tmag5170_read_register(dev, TMAG5170_REG_Z_CH_RESULT, &drv_data->z, 0U); + break; + case SENSOR_CHAN_MAGN_XYZ: + ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U); + + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_Y_CH_RESULT, + &drv_data->y, + 0U); + } + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_Z_CH_RESULT, + &drv_data->z, + 0U); + } + break; + case SENSOR_CHAN_ROTATION: + ret = tmag5170_read_register(dev, + TMAG5170_REG_ANGLE_RESULT, + &drv_data->angle, + 0U); + break; + case SENSOR_CHAN_AMBIENT_TEMP: + ret = tmag5170_read_register(dev, + TMAG5170_REG_TEMP_RESULT, + &drv_data->temperature, + 0U); + break; + case SENSOR_CHAN_ALL: + ret = tmag5170_read_register(dev, + TMAG5170_REG_TEMP_RESULT, + &drv_data->temperature, + 0U); + + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_ANGLE_RESULT, + &drv_data->angle, + 0U); + } + + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_X_CH_RESULT, + &drv_data->x, + 0U); + } + + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_Y_CH_RESULT, + &drv_data->y, + 0U); + } + + if (ret == 0) { + ret = tmag5170_read_register(dev, + TMAG5170_REG_Z_CH_RESULT, + &drv_data->z, + 0U); + } + + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +static int tmag5170_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + const struct tmag5170_dev_config *cfg = dev->config; + struct tmag5170_data *drv_data = dev->data; + int ret = 0; + + switch (chan) { + case SENSOR_CHAN_MAGN_XYZ: + ret = tmag5170_convert_magn_reading_to_gauss(val, + drv_data->x, + cfg->x_range, + drv_data->chip_revision); + + if (ret == 0) { + ret = tmag5170_convert_magn_reading_to_gauss(val + 1, + drv_data->y, + cfg->y_range, + drv_data->chip_revision); + } + + if (ret == 0) { + ret = tmag5170_convert_magn_reading_to_gauss(val + 2, + drv_data->z, + cfg->z_range, + drv_data->chip_revision); + } + break; + case SENSOR_CHAN_MAGN_X: + ret = tmag5170_convert_magn_reading_to_gauss(val, + drv_data->x, + cfg->x_range, + drv_data->chip_revision); + break; + case SENSOR_CHAN_MAGN_Y: + ret = tmag5170_convert_magn_reading_to_gauss(val, + drv_data->y, + cfg->y_range, + drv_data->chip_revision); + break; + case SENSOR_CHAN_MAGN_Z: + ret = tmag5170_convert_magn_reading_to_gauss(val, + drv_data->z, + cfg->z_range, + drv_data->chip_revision); + break; + case SENSOR_CHAN_ROTATION: + tmag5170_covert_angle_reading_to_degrees(val, drv_data->angle); + break; + case SENSOR_CHAN_AMBIENT_TEMP: + tmag5170_convert_temp_reading_to_celsius(val, drv_data->temperature); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +static int tmag5170_init_registers(const struct device *dev) +{ + const struct tmag5170_dev_config *cfg = dev->config; + struct tmag5170_data *drv_data = dev->data; + uint16_t test_cfg_reg = 0U; + int ret = 0; + +#if !defined(CONFIG_TMAG5170_CRC) + const uint8_t disable_crc_packet[4] = { 0x0FU, 0x0U, 0x04U, 0x07U }; + + ret = tmag5170_transmit_raw(cfg, disable_crc_packet, NULL); +#endif + if (ret == 0) { + ret = tmag5170_read_register(dev, TMAG5170_REG_TEST_CONFIG, &test_cfg_reg, 0U); + } + + if (ret == 0) { + drv_data->chip_revision = TMAG5170_VER_GET(test_cfg_reg); + + ret = tmag5170_write_register(dev, + TMAG5170_REG_SENSOR_CONFIG, + TMAG5170_ANGLE_EN_SET(cfg->angle_measurement) | + TMAG5170_SLEEPTIME_SET(cfg->sleep_time) | + TMAG5170_MAG_CH_EN_SET(cfg->magnetic_channels) | + TMAG5170_Z_RANGE_SET(cfg->z_range) | + TMAG5170_Y_RANGE_SET(cfg->y_range) | + TMAG5170_X_RANGE_SET(cfg->x_range)); + } + +#if defined(CONFIG_TMAG5170_TRIGGER) + if (ret == 0) { + ret = tmag5170_write_register(dev, + TMAG5170_REG_ALERT_CONFIG, + TMAG5170_RSLT_ALRT_SET(1U)); + } +#endif + if (ret == 0) { + ret = tmag5170_write_register(dev, + TMAG5170_REG_DEVICE_CONFIG, + TMAG5170_OPERATING_MODE_SET(cfg->operating_mode) | + TMAG5170_CONV_AVG_SET(cfg->oversampling) | + TMAG5170_MAG_TEMPCO_SET(cfg->magnet_type) | + TMAG5170_T_CH_EN_SET(cfg->tempeature_measurement) | + TMAG5170_T_RATE_SET(cfg->disable_temperature_oversampling)); + } + + return ret; +} + +#ifdef CONFIG_PM_DEVICE +static int tmag5170_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret_val = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + tmag5170_write_register(dev, + TMAG5170_REG_DEVICE_CONFIG, + TMAG5170_OPERATING_MODE_SET(TMAG5170_CONFIGURATION_MODE)); + /* As per datasheet, waking up from deep-sleep can take up to 500us */ + k_sleep(K_USEC(500)); + ret_val = tmag5170_init_registers(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + ret_val = tmag5170_write_register(dev, + TMAG5170_REG_DEVICE_CONFIG, + TMAG5170_OPERATING_MODE_SET(TMAG5170_DEEP_SLEEP_MODE)); + break; + default: + ret_val = -ENOTSUP; + } + + return ret_val; +} +#endif /* CONFIG_PM_DEVICE */ + +static const struct sensor_driver_api tmag5170_driver_api = { + .sample_fetch = tmag5170_sample_fetch, + .channel_get = tmag5170_channel_get, +#if defined(CONFIG_TMAG5170_TRIGGER) + .trigger_set = tmag5170_trigger_set +#endif +}; + +static int tmag5170_init(const struct device *dev) +{ + const struct tmag5170_dev_config *cfg = dev->config; + int ret = 0; + + if (!spi_is_ready_dt(&cfg->bus)) { + LOG_ERR("SPI dev %s not ready", cfg->bus.bus->name); + return -ENODEV; + } + + ret = tmag5170_init_registers(dev); + if (ret != 0) { + return ret; + } + +#if defined(CONFIG_TMAG5170_TRIGGER) + if (cfg->int_gpio.port) { + ret = tmag5170_trigger_init(dev); + } +#endif + + return ret; +} + +#define DEFINE_TMAG5170(_num) \ + static struct tmag5170_data tmag5170_data_##_num; \ + static const struct tmag5170_dev_config tmag5170_config_##_num = { \ + .bus = SPI_DT_SPEC_INST_GET(_num, \ + SPI_OP_MODE_MASTER | \ + SPI_TRANSFER_MSB | \ + SPI_WORD_SET(32), \ + 0), \ + .magnetic_channels = DT_INST_ENUM_IDX(_num, magnetic_channels), \ + .x_range = DT_INST_ENUM_IDX(_num, x_range), \ + .y_range = DT_INST_ENUM_IDX(_num, y_range), \ + .z_range = DT_INST_ENUM_IDX(_num, z_range), \ + .operating_mode = DT_INST_PROP(_num, operating_mode), \ + .oversampling = DT_INST_ENUM_IDX(_num, oversampling), \ + .tempeature_measurement = DT_INST_PROP(_num, enable_temperature_channel), \ + .magnet_type = DT_INST_ENUM_IDX(_num, magnet_type), \ + .angle_measurement = DT_INST_ENUM_IDX(_num, angle_measurement), \ + .disable_temperature_oversampling = DT_INST_PROP(_num, \ + disable_temperature_oversampling), \ + .sleep_time = DT_INST_ENUM_IDX(_num, sleep_time), \ + IF_ENABLED(CONFIG_TMAG5170_TRIGGER, \ + (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, int_gpios, { 0 }),)) \ + }; \ + PM_DEVICE_DT_INST_DEFINE(_num, tmag5170_pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(_num, \ + tmag5170_init, \ + PM_DEVICE_DT_INST_GET(_num), \ + &tmag5170_data_##_num, \ + &tmag5170_config_##_num, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &tmag5170_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMAG5170) diff --git a/drivers/sensor/tmag5170/tmag5170.h b/drivers/sensor/tmag5170/tmag5170.h new file mode 100644 index 00000000000..91778e81c56 --- /dev/null +++ b/drivers/sensor/tmag5170/tmag5170.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Michal Morsisko + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_TMAG5170_TMAG5170_H_ +#define ZEPHYR_DRIVERS_SENSOR_TMAG5170_TMAG5170_H_ + +#include +#include +#include +#include + +struct tmag5170_dev_config { + struct spi_dt_spec bus; + uint8_t magnetic_channels; + uint8_t x_range; + uint8_t y_range; + uint8_t z_range; + uint8_t oversampling; + bool tempeature_measurement; + uint8_t magnet_type; + uint8_t angle_measurement; + bool disable_temperature_oversampling; + uint8_t sleep_time; + uint8_t operating_mode; +#if defined(CONFIG_TMAG5170_TRIGGER) + struct gpio_dt_spec int_gpio; +#endif +}; + +struct tmag5170_data { + uint8_t chip_revision; + uint16_t x; + uint16_t y; + uint16_t z; + uint16_t temperature; + uint16_t angle; +#if defined(CONFIG_TMAG5170_TRIGGER) + struct gpio_callback gpio_cb; + sensor_trigger_handler_t handler_drdy; + const struct sensor_trigger *trigger_drdy; + const struct device *dev; +#endif + +#if defined(CONFIG_TMAG5170_TRIGGER_OWN_THREAD) + struct k_sem sem; + struct k_thread thread; + + K_THREAD_STACK_MEMBER(thread_stack, + CONFIG_TMAG5170_THREAD_STACK_SIZE); +#elif defined(CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif +}; + +#if defined(CONFIG_TMAG5170_TRIGGER) +int tmag5170_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int tmag5170_trigger_init(const struct device *dev); +#endif + +#endif /* ZEPHYR_DRIVERS_SENSOR_TMAG5170_TMAG5170_H_ */ diff --git a/drivers/sensor/tmag5170/tmag5170_trigger.c b/drivers/sensor/tmag5170/tmag5170_trigger.c new file mode 100644 index 00000000000..c1be9cd4e1f --- /dev/null +++ b/drivers/sensor/tmag5170/tmag5170_trigger.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023 Michal Morsisko + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tmag5170 + +#include +#include +#include +#include +#include + +#include "tmag5170.h" + +LOG_MODULE_DECLARE(TMAG5170, CONFIG_SENSOR_LOG_LEVEL); + +static void tmag5170_handle_interrupts(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct tmag5170_data *data = dev->data; + + if (data->handler_drdy) { + data->handler_drdy(dev, data->trigger_drdy); + } +} + +#if defined(CONFIG_TMAG5170_TRIGGER_OWN_THREAD) +static void tmag5170_thread_main(void *arg1, void *unused1, void *unused2) +{ + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + const struct device *dev = (const struct device *)arg1; + struct tmag5170_data *data = dev->data; + + while (1) { + k_sem_take(&data->sem, K_FOREVER); + tmag5170_handle_interrupts(dev); + } +} +#endif + +#if defined(CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD) +static void tmag5170_work_handler(struct k_work *work) +{ + struct tmag5170_data *data = CONTAINER_OF(work, + struct tmag5170_data, + work); + + tmag5170_handle_interrupts(data->dev); +} +#endif + +static void tmag5170_gpio_callback(const struct device *port, + struct gpio_callback *cb, + uint32_t pin) +{ + struct tmag5170_data *data = CONTAINER_OF(cb, + struct tmag5170_data, + gpio_cb); + + ARG_UNUSED(port); + ARG_UNUSED(pin); + +#if defined(CONFIG_TMAG5170_TRIGGER_OWN_THREAD) + k_sem_give(&data->sem); +#elif defined(CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#elif defined(CONFIG_TMAG5170_TRIGGER_DIRECT) + tmag5170_handle_interrupts(data->dev); +#endif +} + +int tmag5170_trigger_set( + const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + struct tmag5170_data *data = dev->data; + +#if defined(CONFIG_PM_DEVICE) + enum pm_device_state state; + + (void)pm_device_state_get(dev, &state); + if (state != PM_DEVICE_STATE_ACTIVE) { + return -EBUSY; + } +#endif + + if (trig->type != SENSOR_TRIG_DATA_READY) { + return -ENOTSUP; + } + + data->trigger_drdy = trig; + data->handler_drdy = handler; + + return 0; +} + +int tmag5170_trigger_init(const struct device *dev) +{ + struct tmag5170_data *data = dev->data; + const struct tmag5170_dev_config *cfg = dev->config; + int ret; + + if (!device_is_ready(cfg->int_gpio.port)) { + LOG_ERR("%s: device %s is not ready", dev->name, cfg->int_gpio.port->name); + return -ENODEV; + } + + data->dev = dev; + +#if defined(CONFIG_TMAG5170_TRIGGER_OWN_THREAD) + k_sem_init(&data->sem, 0, 1); + k_thread_create( + &data->thread, + data->thread_stack, + CONFIG_TMAG5170_THREAD_STACK_SIZE, + tmag5170_thread_main, + (void *)dev, + NULL, + NULL, + K_PRIO_COOP(CONFIG_TMAG5170_THREAD_PRIORITY), + 0, + K_NO_WAIT); +#elif defined(CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD) + data->work.handler = tmag5170_work_handler; +#endif + ret = gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT); + + if (ret < 0) { + return ret; + } + + gpio_init_callback(&data->gpio_cb, tmag5170_gpio_callback, BIT(cfg->int_gpio.pin)); + + ret = gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb); + if (ret < 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_EDGE_FALLING); + if (ret < 0) { + return ret; + } + + return ret; +} diff --git a/dts/bindings/sensor/ti,tmag5170.yaml b/dts/bindings/sensor/ti,tmag5170.yaml new file mode 100644 index 00000000000..c68e704c900 --- /dev/null +++ b/dts/bindings/sensor/ti,tmag5170.yaml @@ -0,0 +1,213 @@ +# Copyright (c) 2023 Michal Morsisko +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments TMAG5170 high-precision, linear 3D Hall-effect sensor. + +compatible: "ti,tmag5170" + +include: [sensor-device.yaml, spi-device.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + This property specifies the connection to ALERT sensor pin. + It will be used by the driver to notify the application about + data ready event. For this property to take effect, the + TMAG5170_TRIGGER must be set in project configuration + operating-mode: + type: int + required: true + description: | + Operating mode of the device. + 1 - stand-by mode - in this mode the device waits for application to trigger + the measurement. + 2 - active measure mode - continuous sampling on all enabled channels + as fast as possible. Recommended for devices that haven't got + strict power requirements and need frequent sampling. + 3 - active trigger mode - in this mode, similar to stand-by mode, the device + wait for application to trigger the measurement, but the time needed to finish + the conversion is shorter than in stand-by mode, on the cost of increased power + consumption. + 4 - duty-cycled - after each sample the device goes to sleep and then + automatically wakes up to take another sample. The sleep time is determined + by `sleep-time` property. Recommended for low-power devices that don't need + high frequency sampling. + enum: + - 1 + - 2 + - 3 + - 4 + magnetic-channels: + type: string + default: "XYZ" + description: | + Enables data acquisition of the magnetic axis channel(s) + If axis is enabled more than once, sensor will do pseudo-simultaneous + sampling. Refer to datasheet for more information, By default all axes + are enabled (XYZ) to allow the user to check if the sensor work as expected. + Following options are allowed: + None (chip reset value) + X + Y + XY + Z + ZX + YZ + XYZ (default) + XYX + YXY + YZY + ZYZ + ZXZ + XZX + XYZYX + XYZZYX + enum: + - "None" + - "X" + - "Y" + - "XY" + - "Z" + - "ZX" + - "YZ" + - "XYZ" + - "XYX" + - "YXY" + - "YZY" + - "ZYZ" + - "ZXZ" + - "XZX" + - "XYZYX" + - "XYZZYX" + x-range: + type: int + default: 0 + description: | + The maximum and minimum values that can be measured on X axis. + The wider the range, the worse the resolution. + 0 = ±50mT (TMAG5170A1)/ ±150mT(TMAG5170A2) - (default; chip reset value) + 1 = ±25mT (TMAG5170A1)/ ±75mT(TMAG5170A2) + 2 = ±100mT (TMAG5170A1)/ ±300mT(TMAG5170A2) + enum: + - 0 + - 1 + - 2 + y-range: + type: int + default: 0 + description: | + The maximum and minimum values that can be measured on Y axis. + The wider the range, the worse the resolution. + 0 = ±50mT (TMAG5170A1)/ ±150mT(TMAG5170A2) - (default; chip reset value) + 1 = ±25mT (TMAG5170A1)/ ±75mT(TMAG5170A2) + 2 = ±100mT (TMAG5170A1)/ ±300mT(TMAG5170A2) + enum: + - 0 + - 1 + - 2 + z-range: + type: int + default: 0 + description: | + The maximum and minimum values that can be measured on Z axis. + The wider the range, the worse the resolution. + 0 = ±50mT (TMAG5170A1)/ ±150mT(TMAG5170A2) - (default; chip reset value) + 1 = ±25mT (TMAG5170A1)/ ±75mT(TMAG5170A2) + 2 = ±100mT (TMAG5170A1)/ ±300mT(TMAG5170A2) + enum: + - 0 + - 1 + - 2 + oversampling: + type: int + default: 1 + description: | + Enables additional sampling of the sensor data to reduce the noise + effect. If temperature channel is enabled, temperature will be oversampled + too, unless `disable-temperature-oversampling` property is present. + Following options are allowed: + 1 (default; chip reset value) + 2 + 4 + 8 + 16 + 32 + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + enable-temperature-channel: + type: boolean + description: | + Enables temperature measurement + magnet-type: + type: string + default: "None" + description: | + Enables temperature compensation basing on the type of magnet. + Following options are allowed: + None (default; chip reset value) + NdBFe = 0.12%/deg C + SmCo = 0.03%/deg C + Ceramic = 0.2%/deg C + enum: + - "None" + - "NdBFe" + - "SmCo" + - "Ceramic" + angle-measurement: + type: string + default: "None" + description: | + Enable angle calculation using two axis data: + None (default; chip reset value) + XY + YZ + XZ + enum: + - "None" + - "XY" + - "YZ" + - "XZ" + disable-temperature-oversampling: + type: boolean + description: | + If true, temperature is always sampled once per conversion set + If false, temperature is oversampled according to `oversampling` + property. + sleep-time: + type: int + default: 1 + description: | + The time in miliseconds the sensor will be in sleep during conversions. + For this property to take effect sensor must be in `duty-cycled` mode. + Note that to calculate total time between conversions, the conversion time + itself must be taken into account. The conversion time is dependent + on the values of `oversampling`, `magnetic-channels`, `temperature-channel-enabled` + and `disable-temperature-oversampling` properties. + Following value are allowed: + 1 (default; chip reset value) + 5 + 10 + 15 + 20 + 30 + 50 + 100 + 500 + 1000 + enum: + - 1 + - 5 + - 10 + - 15 + - 20 + - 30 + - 50 + - 100 + - 500 + - 1000 diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 629334bc396..a589b62cfa1 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -119,7 +119,8 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, - <&test_gpio 0 0>; /* 0x24 */ + <&test_gpio 0 0>, + <&test_gpio 0 0>; /* 0x25 */ #include "spi.dtsi" }; diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index cf4fce093e4..f0c34845ce0 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -48,6 +48,7 @@ CONFIG_SM351LT_TRIGGER_GLOBAL_THREAD=y CONFIG_STTS751_TRIGGER_GLOBAL_THREAD=y CONFIG_SX9500_TRIGGER_GLOBAL_THREAD=y CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD=y +CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD=y CONFIG_TMD2620_TRIGGER_GLOBAL_THREAD=y CONFIG_TMP007_TRIGGER_GLOBAL_THREAD=y CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index f89a07de1c4..2c4b51c2184 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -48,6 +48,7 @@ CONFIG_SM351LT_TRIGGER_NONE=y CONFIG_STTS751_TRIGGER_NONE=y CONFIG_SX9500_TRIGGER_NONE=y CONFIG_TCN75A_TRIGGER_NONE=y +CONFIG_TMAG5170_TRIGGER_NONE=y CONFIG_TMD2620_TRIGGER_NONE=y CONFIG_TMP007_TRIGGER_NONE=y CONFIG_TSL2540_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index 3447061c16f..17e1b6c29fa 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -46,6 +46,7 @@ CONFIG_SM351LT_TRIGGER_OWN_THREAD=y CONFIG_STTS751_TRIGGER_OWN_THREAD=y CONFIG_SX9500_TRIGGER_OWN_THREAD=y CONFIG_TCN75A_TRIGGER_OWN_THREAD=y +CONFIG_TMAG5170_TRIGGER_OWN_THREAD=y CONFIG_TMP007_TRIGGER_OWN_THREAD=y CONFIG_TSL2540_TRIGGER_OWN_THREAD=y CONFIG_VCNL4040_TRIGGER_OWN_THREAD=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index d6764f14d9b..513ffbf4e37 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -287,3 +287,11 @@ test_spi_bmi08x_gyro: bmi08x@24 { gyro-hz = "1000_116"; gyro-fs = <1000>; }; + +test_spi_tmag5170: tmag5170@25 { + compatible = "ti,tmag5170"; + reg = <0x25>; + spi-max-frequency = <0>; + int-gpios = <&test_gpio 0 0>; + operating-mode = <1>; +}; From 862cd57a2a98052b12077846c90990f37c629591 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Mon, 4 Sep 2023 12:46:38 +0200 Subject: [PATCH 1034/4498] tests: drivers: Move the DHT22 sensor to gpio.dtsi Move the DHT22 GPIO sensor to the gpio.dtsi overlay file. Signed-off-by: Franciszek Zdobylak --- tests/drivers/build_all/sensor/app.overlay | 7 ------- tests/drivers/build_all/sensor/gpio.dtsi | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index a589b62cfa1..506cc1848b2 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -142,13 +142,6 @@ #include "w1.dtsi" }; - - dht22 { - compatible = "aosong,dht"; - status = "okay"; - dio-gpios = <&test_gpio 0 0>; - /* dht22; */ - }; }; }; diff --git a/tests/drivers/build_all/sensor/gpio.dtsi b/tests/drivers/build_all/sensor/gpio.dtsi index 6994cc23b09..95626ae9015 100644 --- a/tests/drivers/build_all/sensor/gpio.dtsi +++ b/tests/drivers/build_all/sensor/gpio.dtsi @@ -10,3 +10,10 @@ test_gpio_sm351lt: sm351lt0 { compatible = "honeywell,sm351lt"; gpios = <&test_gpio 0 0>; }; + +test_gpio_dht22: dht22 { + compatible = "aosong,dht"; + status = "okay"; + dio-gpios = <&test_gpio 0 0>; + /* dht22; */ +}; From fc4ae7ae84f8ce63088cb071c0bec6a29d483cda Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Mon, 4 Sep 2023 12:48:47 +0200 Subject: [PATCH 1035/4498] tests: drivers: Unify labels of sensors Unify labels of all sensors used in tests/drivers/build_all/sensor test. Signed-off-by: Franciszek Zdobylak --- tests/drivers/build_all/sensor/adc.dtsi | 6 +++--- tests/drivers/build_all/sensor/i2c.dtsi | 4 ++-- tests/drivers/build_all/sensor/uart.dtsi | 10 +++++----- tests/drivers/build_all/sensor/w1.dtsi | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index e5d24cc4f31..e6e14ea0979 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -34,7 +34,7 @@ test_current: current_amp { sense-gain-div = <1>; }; -test_adc_emul: adc { +test_adc_emul: adc-emul { compatible = "zephyr,adc-emul"; nchannels = <2>; ref-internal-mv = <3300>; @@ -43,7 +43,7 @@ test_adc_emul: adc { status = "okay"; }; -test_ntc_thermistor_generic: ntc-thermistor-generic { +test_adc_ntc_thermistor_generic: ntc-thermistor-generic { compatible = "ntc-thermistor-generic"; io-channels = <&adc0 0>; pullup-uv = <3300000>; @@ -53,7 +53,7 @@ test_ntc_thermistor_generic: ntc-thermistor-generic { zephyr,compensation-table = <0 0>, <1 1>; }; -test_epcos_b57861s0103a039: epcos-b57861s0103a039 { +test_adc_epcos_b57861s0103a039: epcos-b57861s0103a039 { compatible = "epcos,b57861s0103a039"; io-channels = <&adc0 0>; pullup-uv = <3300000>; diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b59f14f36a7..618905d78b6 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -709,7 +709,7 @@ test_i2c_tcs3400: tcs3400@6b { int-gpios = <&test_gpio 0 0>; }; -test_tcn75a: tcn75a@6c { +test_i2c_tcn75a: tcn75a@6c { compatible = "microchip,tcn75a"; reg = <0x6c>; alert-gpios = <&test_gpio 0 0>; @@ -737,7 +737,7 @@ test_i2c_bmi08x_gyro: bmi08x@6e { gyro-fs = <1000>; }; -test_i2c_ist8310@6f { +test_i2c_ist8310: ist8310@6f { compatible = "isentek,ist8310"; reg = <0x6f>; status = "okay"; diff --git a/tests/drivers/build_all/sensor/uart.dtsi b/tests/drivers/build_all/sensor/uart.dtsi index 9d63ee3555f..11b08dd99eb 100644 --- a/tests/drivers/build_all/sensor/uart.dtsi +++ b/tests/drivers/build_all/sensor/uart.dtsi @@ -7,26 +7,26 @@ * Application overlay for uart devices */ -test_uart_mhz19b { +test_uart_mhz19b: mhz19b { compatible = "winsen,mhz19b"; maximum-range = <10000>; abc-on; }; -test_uart_pms7003 { +test_uart_pms7003: pms7003 { compatible = "plantower,pms7003"; }; -test_uart_grow_r502a { +grow_r502a { #address-cells=<1>; #size-cells=<0>; - grow_r502a@0 { + test_uart_grow_r502a: grow_r502a@0 { compatible = "hzgrow,r502a"; reg = <0x0>; int-gpios = <&test_gpio 0 0>; }; }; -test_uart_a01nyub { +test_uart_a01nyub: a01nyub { compatible = "dfrobot,a01nyub"; }; diff --git a/tests/drivers/build_all/sensor/w1.dtsi b/tests/drivers/build_all/sensor/w1.dtsi index 49734624231..a7a6a554eb0 100644 --- a/tests/drivers/build_all/sensor/w1.dtsi +++ b/tests/drivers/build_all/sensor/w1.dtsi @@ -6,7 +6,7 @@ * Application overlay for w1 devices */ -test-w1-ds18b20 { +test_w1_ds18b20: ds18b20 { compatible = "maxim,ds18b20"; family-code = <0x28>; resolution = <12>; From fcf22e59b89c630451da4e2343ccf57b91deb030 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 6 Sep 2023 14:34:51 -0700 Subject: [PATCH 1036/4498] xtensa: mark arch_switch ALWAYS_INLINE arch_switch() is basically an alias to xtensa_switch() so we can mark arch_switch() as ALWAYS_INLINE to avoid another function call, especially when no optimization is used when debugging. Signed-off-by: Daniel Leung --- arch/xtensa/include/kernel_arch_func.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/include/kernel_arch_func.h b/arch/xtensa/include/kernel_arch_func.h index 44811a5b2a8..6427b306e62 100644 --- a/arch/xtensa/include/kernel_arch_func.h +++ b/arch/xtensa/include/kernel_arch_func.h @@ -70,7 +70,7 @@ static ALWAYS_INLINE void arch_kernel_init(void) void xtensa_switch(void *switch_to, void **switched_from); -static inline void arch_switch(void *switch_to, void **switched_from) +static ALWAYS_INLINE void arch_switch(void *switch_to, void **switched_from) { return xtensa_switch(switch_to, switched_from); } From 1194a35aa22a4187aa86689a58cf55020a75981a Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 25 Aug 2023 14:29:12 -0700 Subject: [PATCH 1037/4498] xtensa: cast char* to void* during stack dump with %p cbprintf_package() warns about using char* for %p. So cast it to void* to avoid the warning. Signed-off-by: Daniel Leung --- arch/xtensa/core/xtensa-asm2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/core/xtensa-asm2.c b/arch/xtensa/core/xtensa-asm2.c index cf032c3e98f..c2371ac8f55 100644 --- a/arch/xtensa/core/xtensa-asm2.c +++ b/arch/xtensa/core/xtensa-asm2.c @@ -122,7 +122,7 @@ void z_xtensa_dump_stack(const z_arch_esf_t *stack) LOG_ERR(" ** A0 %p SP %p A2 %p A3 %p", (void *)bsa->a0, - ((char *)bsa + sizeof(*bsa)), + (void *)((char *)bsa + sizeof(*bsa)), (void *)bsa->a2, (void *)bsa->a3); if (reg_blks_remaining > 0) { From ba6c9c2136f42b1cc4b52369526db95b38842e62 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 24 Aug 2023 13:58:26 -0700 Subject: [PATCH 1038/4498] xtensa: dc233c: enable backtrace support Adds the necessary bits to enable backtrace support for Xtensa DC233C core. Signed-off-by: Daniel Leung --- arch/xtensa/Kconfig | 2 +- arch/xtensa/core/xtensa_backtrace.c | 6 ++++ soc/xtensa/dc233c/include/backtrace_helpers.h | 28 +++++++++++++++++++ soc/xtensa/dc233c/include/xtensa-dc233c.ld | 6 ++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 soc/xtensa/dc233c/include/backtrace_helpers.h diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 5d042c1d475..6095a7046d7 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -46,7 +46,7 @@ config XTENSA_USE_CORE_CRT1 config XTENSA_ENABLE_BACKTRACE bool "Backtrace on panic exception" default y - depends on SOC_SERIES_ESP32 || SOC_FAMILY_INTEL_ADSP + depends on SOC_SERIES_ESP32 || SOC_FAMILY_INTEL_ADSP || SOC_XTENSA_DC233C help Enable this config option to print backtrace on panic exception diff --git a/arch/xtensa/core/xtensa_backtrace.c b/arch/xtensa/core/xtensa_backtrace.c index 4f767f69042..e0abe09049b 100644 --- a/arch/xtensa/core/xtensa_backtrace.c +++ b/arch/xtensa/core/xtensa_backtrace.c @@ -11,6 +11,8 @@ #include "soc/soc_memory_layout.h" #elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP) #include "debug_helpers.h" +#elif defined(CONFIG_SOC_XTENSA_DC233C) +#include "backtrace_helpers.h" #endif static int mask, cause; @@ -38,6 +40,8 @@ static inline bool z_xtensa_stack_ptr_is_sane(uint32_t sp) return esp_stack_ptr_is_sane(sp); #elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP) return intel_adsp_ptr_is_sane(sp); +#elif defined(CONFIG_SOC_XTENSA_DC233C) + return xtensa_dc233c_stack_ptr_is_sane(sp); #else #warning "z_xtensa_stack_ptr_is_sane is not defined for this platform" #endif @@ -49,6 +53,8 @@ static inline bool z_xtensa_ptr_executable(const void *p) return esp_ptr_executable(p); #elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP) return intel_adsp_ptr_executable(p); +#elif defined(CONFIG_SOC_XTENSA_DC233C) + return xtensa_dc233c_ptr_executable(p); #else #warning "z_xtensa_ptr_executable is not defined for this platform" #endif diff --git a/soc/xtensa/dc233c/include/backtrace_helpers.h b/soc/xtensa/dc233c/include/backtrace_helpers.h new file mode 100644 index 00000000000..8793ebcd7a1 --- /dev/null +++ b/soc/xtensa/dc233c/include/backtrace_helpers.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2022, 2023 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + + +#ifndef ZEPHYR_SOC_XTENSA_DC233C_BACKTRACE_HELPERS_H_ +#define ZEPHYR_SOC_XTENSA_DC233C_BACKTRACE_HELPERS_H_ + +#include + +#include + +static inline bool xtensa_dc233c_ptr_executable(const void *p) +{ + bool in_text = ((p >= (void *)__text_region_start) && + (p <= (void *)__text_region_end)); + bool in_vecbase = ((p >= (void *)XCHAL_VECBASE_RESET_VADDR) && + (p < (void *)CONFIG_SRAM_OFFSET)); + + return (in_text || in_vecbase); +} + +static inline bool xtensa_dc233c_stack_ptr_is_sane(uint32_t sp) +{ + return ((char *)sp >= __text_region_start); +} + +#endif /* ZEPHYR_SOC_XTENSA_DC233C_BACKTRACE_HELPERS_H_ */ diff --git a/soc/xtensa/dc233c/include/xtensa-dc233c.ld b/soc/xtensa/dc233c/include/xtensa-dc233c.ld index d6c57e36499..65f47f5ce9b 100644 --- a/soc/xtensa/dc233c/include/xtensa-dc233c.ld +++ b/soc/xtensa/dc233c/include/xtensa-dc233c.ld @@ -322,6 +322,12 @@ SECTIONS *(.text.arch_is_in_isr) + /* To support backtracing */ + *libarch__xtensa__core.a:xtensa_backtrace.c.obj(.literal.*) + *libarch__xtensa__core.a:xtensa_backtrace.c.obj(.text.*) + *libarch__xtensa__core.a:debug_helpers_asm.S.obj(.iram1.literal) + *libarch__xtensa__core.a:debug_helpers_asm.S.obj(.iram1) + *libkernel.a:fatal.c.obj(.literal.*) *libkernel.a:fatal.c.obj(.text.*) From 8b9e06482359bcfead9e684b5fa44d9ec1075f8c Mon Sep 17 00:00:00 2001 From: Lucas Dietrich Date: Fri, 22 Sep 2023 13:37:02 +0200 Subject: [PATCH 1039/4498] lorawan: Update data type of dev_nonce in lorawan_join_otaa struct Make the dev_nonce size match the LoRaWAN specification, which is 2 bytes. Signed-off-by: Lucas Dietrich --- include/zephyr/lorawan/lorawan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/lorawan/lorawan.h b/include/zephyr/lorawan/lorawan.h index 924ed6ec276..519e6e4bea1 100644 --- a/include/zephyr/lorawan/lorawan.h +++ b/include/zephyr/lorawan/lorawan.h @@ -107,7 +107,7 @@ struct lorawan_join_otaa { * increasing for each OTAA join with the same EUI. The DevNonce * should be stored in non-volatile memory by the application. */ - uint32_t dev_nonce; + uint16_t dev_nonce; }; /** From 66b131928b1e3ba317c54deb27afe97c381963a7 Mon Sep 17 00:00:00 2001 From: Lucas Dietrich Date: Fri, 22 Sep 2023 13:38:33 +0200 Subject: [PATCH 1040/4498] lorawan: Set dev_nonce to 0 during join_cfg initialization Ensure the LoRaWAN dev nonce is initialized with a known state in the class_a sample. Signed-off-by: Lucas Dietrich --- samples/subsys/lorawan/class_a/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/subsys/lorawan/class_a/src/main.c b/samples/subsys/lorawan/class_a/src/main.c index 9209bcaffb6..76ff5529f57 100644 --- a/samples/subsys/lorawan/class_a/src/main.c +++ b/samples/subsys/lorawan/class_a/src/main.c @@ -90,6 +90,7 @@ int main(void) join_cfg.otaa.join_eui = join_eui; join_cfg.otaa.app_key = app_key; join_cfg.otaa.nwk_key = app_key; + join_cfg.otaa.dev_nonce = 0u; LOG_INF("Joining network over OTAA"); ret = lorawan_join(&join_cfg); From 03b601f0a95edc8990987edc30f7b2ec461579de Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 25 Sep 2023 14:34:24 +0200 Subject: [PATCH 1041/4498] tests BT privacy: Simplify a bit scripts Reduce the unnecessary hidding and indirection, as it makes the scripts more difficult to follow for no benefit. If somebody wants to debug these tests, they'll want to see the sim_id, and won't benefit from going around opening files needlessly. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/host/privacy/central/test_scripts/_env.sh | 3 --- .../bluetooth/host/privacy/central/test_scripts/run_test.sh | 2 ++ tests/bsim/bluetooth/host/privacy/device/test_scripts/_env.sh | 3 --- .../bluetooth/host/privacy/device/test_scripts/run_tests.sh | 2 ++ tests/bsim/bluetooth/host/privacy/legacy/test_scripts/_env.sh | 3 --- .../bluetooth/host/privacy/legacy/test_scripts/run_test.sh | 2 ++ .../bluetooth/host/privacy/peripheral/test_scripts/_env.sh | 3 --- .../bluetooth/host/privacy/peripheral/test_scripts/run_test.sh | 2 ++ 8 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/bsim/bluetooth/host/privacy/central/test_scripts/_env.sh b/tests/bsim/bluetooth/host/privacy/central/test_scripts/_env.sh index 18c60bb7c45..0db56a594dc 100755 --- a/tests/bsim/bluetooth/host/privacy/central/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/privacy/central/test_scripts/_env.sh @@ -5,10 +5,7 @@ set -eu bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" -test_name="$(basename "$(realpath "$bash_source_dir/..")")" bsim_bin="${BSIM_OUT_PATH}/bin" -verbosity_level=2 BOARD="${BOARD:-nrf52_bsim}" -simulation_id="$test_name" central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_central_prj_conf" peripheral_exe="${central_exe}" diff --git a/tests/bsim/bluetooth/host/privacy/central/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/privacy/central/test_scripts/run_test.sh index 3ba95eab78c..ce65d58f6ce 100755 --- a/tests/bsim/bluetooth/host/privacy/central/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/privacy/central/test_scripts/run_test.sh @@ -8,6 +8,8 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" source "${bash_source_dir}/_env.sh" source ${ZEPHYR_BASE}/tests/bsim/sh_common.source +verbosity_level=2 +simulation_id="$(basename "$(realpath "$bash_source_dir/..")")" EXECUTE_TIMEOUT=30 cd ${BSIM_OUT_PATH}/bin diff --git a/tests/bsim/bluetooth/host/privacy/device/test_scripts/_env.sh b/tests/bsim/bluetooth/host/privacy/device/test_scripts/_env.sh index bb1b50678cc..ee8b534d1db 100755 --- a/tests/bsim/bluetooth/host/privacy/device/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/privacy/device/test_scripts/_env.sh @@ -7,9 +7,6 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" : "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" -test_name="$(basename "$(realpath "$bash_source_dir/..")")" bsim_bin="${BSIM_OUT_PATH}/bin" -verbosity_level=2 BOARD="${BOARD:-nrf52_bsim}" -simulation_id="$test_name" test_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_device_prj_conf" diff --git a/tests/bsim/bluetooth/host/privacy/device/test_scripts/run_tests.sh b/tests/bsim/bluetooth/host/privacy/device/test_scripts/run_tests.sh index 89c180cf57a..d02b58df58d 100755 --- a/tests/bsim/bluetooth/host/privacy/device/test_scripts/run_tests.sh +++ b/tests/bsim/bluetooth/host/privacy/device/test_scripts/run_tests.sh @@ -8,6 +8,8 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" source "${bash_source_dir}/_env.sh" source ${ZEPHYR_BASE}/tests/bsim/sh_common.source +verbosity_level=2 +simulation_id="$(basename "$(realpath "$bash_source_dir/..")")" EXECUTE_TIMEOUT=30 cd ${BSIM_OUT_PATH}/bin diff --git a/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/_env.sh b/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/_env.sh index 241e989c100..714fe3eb996 100755 --- a/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/_env.sh @@ -5,10 +5,7 @@ set -eu bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" -test_name="$(basename "$(realpath "$bash_source_dir/..")")" bsim_bin="${BSIM_OUT_PATH}/bin" -verbosity_level=2 BOARD="${BOARD:-nrf52_bsim}" -simulation_id="$test_name" central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_legacy_prj_conf" peripheral_exe="${central_exe}" diff --git a/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/run_test.sh index 2a574a29742..ccbe6e844f2 100755 --- a/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/privacy/legacy/test_scripts/run_test.sh @@ -8,6 +8,8 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" source "${bash_source_dir}/_env.sh" source ${ZEPHYR_BASE}/tests/bsim/sh_common.source +verbosity_level=2 +simulation_id="$(basename "$(realpath "$bash_source_dir/..")")" EXECUTE_TIMEOUT=30 cd ${BSIM_OUT_PATH}/bin diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh index 2e3593a3df4..13cf18ceec4 100755 --- a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh @@ -5,10 +5,7 @@ set -eu bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" -test_name="$(basename "$(realpath "$bash_source_dir/..")")" bsim_bin="${BSIM_OUT_PATH}/bin" -verbosity_level=2 BOARD="${BOARD:-nrf52_bsim}" -simulation_id="$test_name" central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_peripheral_prj_conf" peripheral_exe="${central_exe}" diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh index 2a574a29742..ccbe6e844f2 100755 --- a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh @@ -8,6 +8,8 @@ bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" source "${bash_source_dir}/_env.sh" source ${ZEPHYR_BASE}/tests/bsim/sh_common.source +verbosity_level=2 +simulation_id="$(basename "$(realpath "$bash_source_dir/..")")" EXECUTE_TIMEOUT=30 cd ${BSIM_OUT_PATH}/bin From d0f27ac7ed3df4d0d9178fd67d9d1c01ab2aaaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 25 Sep 2023 11:02:20 +0200 Subject: [PATCH 1042/4498] doc: samples: Fix typos introduced by f6a4217a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed typos in references to several doc pages introduced with f6a4217a. Signed-off-by: Benjamin Cabé --- samples/drivers/dac/README.rst | 2 +- samples/drivers/eeprom/README.rst | 2 +- samples/drivers/spi_flash/README.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/drivers/dac/README.rst b/samples/drivers/dac/README.rst index 16cbd170ce0..2803abd8ba7 100644 --- a/samples/drivers/dac/README.rst +++ b/samples/drivers/dac/README.rst @@ -7,7 +7,7 @@ Overview ******** -This sample demonstrates how to use the `DAC driver API `. +This sample demonstrates how to use the :ref:`DAC driver API `. Building and Running ******************** diff --git a/samples/drivers/eeprom/README.rst b/samples/drivers/eeprom/README.rst index 7202456e3f3..25007274a05 100644 --- a/samples/drivers/eeprom/README.rst +++ b/samples/drivers/eeprom/README.rst @@ -7,7 +7,7 @@ Overview ******** -This sample demonstrates the `EEPROM driver API ` in a simple boot counter +This sample demonstrates the :ref:`EEPROM driver API ` in a simple boot counter application. Building and Running diff --git a/samples/drivers/spi_flash/README.rst b/samples/drivers/spi_flash/README.rst index f7bbb0d792b..70b523a58a4 100644 --- a/samples/drivers/spi_flash/README.rst +++ b/samples/drivers/spi_flash/README.rst @@ -7,7 +7,7 @@ Overview ******** -This sample demonstrates using the `flash API ` on a SPI NOR serial flash +This sample demonstrates using the :ref:`flash API ` on a SPI NOR serial flash memory device. While trivial it is an example of direct access and allows confirmation that the flash is working and that automatic power savings is correctly implemented. From 480e228a504ed1290bc00d582ea59339ee6b940f Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Mon, 25 Sep 2023 16:19:10 +0200 Subject: [PATCH 1043/4498] Bluetooth: host: document settings backend requirement This requirement was implicit as the only backend the host is currently tested with behaves this way. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index a4cf2e0959b..72a65eebf6f 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -204,6 +204,9 @@ config BT_SETTINGS which case it's more efficient to load all settings in one go, instead of each subsystem doing it independently. + Warning: The Bluetooth host expects a settings backend that loads + settings items in handle order. + if BT_SETTINGS config BT_SETTINGS_CCC_LAZY_LOADING bool "Load CCC values from settings when peer connects" From f4baa2b0947e3994a355c8fb6010516f69d68d2c Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 14:53:27 -0700 Subject: [PATCH 1044/4498] doc: vuln: Add information about CVE-2023-4258 Information about CVE-2023-4258 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 92ccc0f3a7d..fa12af7e9a7 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1339,6 +1339,25 @@ This has been fixed in main for v3.4.0 - `PR 56709 fix for main `_ +CVE-2023-4258 +------------- + +bt: mesh: vulnerability in provisioning protocol implementation on provisionee side + +- `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 + `_ + +This has been fixed in main for v3.5.0 + +- `PR 59467 fix for main + `_ + +- `PR 60078 fix for 3.4 + `_ + +- `PR 60079 fix for 3.3 + `_ + CVE-2023-4265 ------------- From acc4dcec1e5984fd6a8025f9826595f7007e23aa Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 15:01:00 -0700 Subject: [PATCH 1045/4498] doc: release: 3.5 Add info about CVE-2023-4258 Add security related information in 3.5 release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 963d83abe6c..5d2e730e5a1 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -13,6 +13,14 @@ The following sections provide detailed lists of changes by component. Security Vulnerability Related ****************************** +The following CVEs are addressed by this release: + +More detailed information can be found in: +https://docs.zephyrproject.org/latest/security/vulnerabilities.html + +* CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 + `_ + Kernel ****** From c5191ba5b78127d9b530d586c45fea58c2958155 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 15:37:45 +0200 Subject: [PATCH 1046/4498] Bluetooth: Controller: nrf: Use HAL for DPPI configuration The following changes have been done: 1. HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(channel) has been convered into HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index, channel) 2. HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) = HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK Which was only used in one place, has been replaced with the equivalent HAL call 3. HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) = 0 was replaced with the HAL subscribe clear function nrf_dppi_subscribe_clear(NRF_DPPIC, HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(index))); 4. NRF_DPPIC->SUBSCRIBE_CHG[group].EN/DIS = 0; have been replaced with the equivalent HAL clear call 5. NRF_DPPIC->TASKS_CHG[group].DIS = 1; have been replaced with the equivalent hal task_trigger() call 6. Manually setting the CHG registers, has been replaced with a clear + add (because the hal does not have a set function yet) So, NRF_DPPIC->CHG[group] = value has been replaced with nrf_dppi_group_clear(NRF_DPPIC, group); nrf_dppi_channels_include_in_group(NRF_DPPIC, value, group); (A set function has been requested from the HAL team) Note: There is other direct registes writes to the dppi subscribe and CHG registers in the coded phy parts which have not been changed yet. Signed-off-by: Alberto Escolar Piedras --- .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 102 ++++++++++-------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 9ed66dc3442..69069288141 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -317,6 +317,20 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #define SW_SWITCH_TIMER_S2_EVTS_COMP(index) \ (SW_SWITCH_TIMER_EVTS_COMP_S2_BASE + (index)) +/* + * Convert a dppi channel group number into the *enable* task enumerate value + * the nrfx hal accepts + */ +#define HAL_SW_DPPI_TASK_EN_FROM_IDX(index) \ + (NRF_DPPI_TASK_CHG0_EN + ((index) * (NRF_DPPI_TASK_CHG1_EN - NRF_DPPI_TASK_CHG0_EN))) + +/* + * Convert a dppi channel group number into the *disable* task enumerate value + * the nrfx hal accepts + */ +#define HAL_SW_DPPI_TASK_DIS_FROM_IDX(index) \ + (NRF_DPPI_TASK_CHG0_DIS + ((index) * (NRF_DPPI_TASK_CHG1_EN - NRF_DPPI_TASK_CHG0_EN))) + /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; @@ -332,14 +346,10 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ & TIMER_PUBLISH_COMPARE_EN_Msk)) -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index) \ - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].DIS -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(chan) \ - (((chan << DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Pos) \ - & DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Msk) | \ - ((DPPIC_SUBSCRIBE_CHG_DIS_EN_Enabled << \ - DPPIC_SUBSCRIBE_CHG_DIS_EN_Pos) \ - & DPPIC_SUBSCRIBE_CHG_DIS_EN_Msk)) +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index, channel) \ + nrf_dppi_subscribe_set(NRF_DPPIC, \ + HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(index)), \ + channel); /* Enable the SW Switch PPI Group on RADIO END Event. * @@ -353,15 +363,6 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & RADIO_PUBLISH_END_CHIDX_Msk) | \ ((RADIO_PUBLISH_END_EN_Enabled << RADIO_PUBLISH_END_EN_Pos) \ & RADIO_PUBLISH_END_EN_Msk)) -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) \ - (NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].EN) -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK \ - (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ - DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Pos) \ - & DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Msk) | \ - ((DPPIC_SUBSCRIBE_CHG_EN_EN_Enabled << \ - DPPIC_SUBSCRIBE_CHG_EN_EN_Pos) \ - & DPPIC_SUBSCRIBE_CHG_EN_EN_Msk)) /* Enable Radio on SW Switch timer event. * Wire a SW SWITCH TIMER EVENTS_COMPARE[] event @@ -473,12 +474,15 @@ static inline void hal_radio_sw_switch_setup( */ HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(ppi_group_index) = - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK; + nrf_dppi_subscribe_set(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(ppi_group_index)), + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI); /* We need to un-subscribe the other group from the PPI channel. */ - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK( - (ppi_group_index + 1) & 0x01) = 0; + uint8_t other_grp = (ppi_group_index + 1) & 0x01; + + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(other_grp))); /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do @@ -537,8 +541,10 @@ static inline void hal_radio_sw_switch_disable(void) * So we simply cancel the task subscription. */ nrf_timer_subscribe_clear(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR); - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); } static inline void hal_radio_sw_switch_cleanup(void) @@ -567,8 +573,8 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_s2) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(ppi_dis); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(ppi_dis); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index, + ppi_dis); /* Capture CC to cancel the timer that has assumed * S8 reception, if packet will be received in S2. @@ -609,9 +615,7 @@ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( ppi_dis); HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK( - group_index) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( - ppi_dis); + group_index, ppi_dis); } #endif /* defined(CONFIG_BT_CTLR_PHY_CODED) */ @@ -624,21 +628,33 @@ static inline void hal_radio_sw_switch_ppi_group_setup(void) * registers are written, therefore, we clear the task registers * here. */ - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].EN = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].EN = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 0; - - NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 1; - NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 1; + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); + nrf_dppi_subscribe_clear(NRF_DPPIC, + HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); + + nrf_dppi_task_trigger(NRF_DPPIC, + HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); + nrf_dppi_task_trigger(NRF_DPPIC, + HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); /* Include the appropriate PPI channels in the two PPI Groups. */ - NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(0)] = + nrf_dppi_group_clear(NRF_DPPIC, + SW_SWITCH_TIMER_TASK_GROUP(0)); + nrf_dppi_channels_include_in_group(NRF_DPPIC, BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)); - NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(1)] = + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)), + SW_SWITCH_TIMER_TASK_GROUP(0)); + nrf_dppi_group_clear(NRF_DPPIC, + SW_SWITCH_TIMER_TASK_GROUP(1)); + nrf_dppi_channels_include_in_group(NRF_DPPIC, BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)); + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)), + SW_SWITCH_TIMER_TASK_GROUP(1)); /* Sanity build-time check that RADIO Enable and Group Disable * tasks are going to be subscribed on the same PPIs. @@ -663,8 +679,7 @@ static inline void hal_radio_group_task_disable_ppi_setup(void) SW_SWITCH_TIMER_EVTS_COMP(0)) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0, HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); /* Wire SW SWITCH TIMER event to @@ -674,9 +689,8 @@ static inline void hal_radio_group_task_disable_ppi_setup(void) SW_SWITCH_TIMER_EVTS_COMP(1)) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1, + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); } #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) From 07bb88d28ad366b0b3ba0ea0a9353140b7523efe Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 22 Sep 2023 09:50:22 +0200 Subject: [PATCH 1047/4498] Bluetooth: Controller: nrf: HAL for DPPI configuration cleanup Remove a few macros which are not used anywhere in the tree. For the sake of simplifying the header and easing its understanding. Signed-off-by: Alberto Escolar Piedras --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 69069288141..c28cc35a617 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -388,21 +388,6 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ & TIMER_PUBLISH_COMPARE_EN_Msk)) -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_TX \ - NRF_RADIO->SUBSCRIBE_TXEN -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_RX \ - NRF_RADIO->SUBSCRIBE_RXEN -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX_SET(chan) \ - (((chan << RADIO_SUBSCRIBE_TXEN_CHIDX_Pos) \ - & RADIO_SUBSCRIBE_TXEN_CHIDX_Msk) | \ - ((RADIO_SUBSCRIBE_TXEN_EN_Enabled << \ - RADIO_SUBSCRIBE_TXEN_EN_Pos) \ - & RADIO_SUBSCRIBE_TXEN_EN_Msk)) -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX_SET(chan) \ - (((chan << RADIO_SUBSCRIBE_RXEN_CHIDX_Pos) \ - & RADIO_SUBSCRIBE_RXEN_CHIDX_Msk) | \ - ((RADIO_SUBSCRIBE_RXEN_EN_Enabled << RADIO_SUBSCRIBE_RXEN_EN_Pos) \ - & RADIO_SUBSCRIBE_RXEN_EN_Msk)) /* Cancel the SW switch timer running considering S8 timing: * wire the RADIO EVENTS_RATEBOOST event to SW_SWITCH_TIMER TASKS_CAPTURE task. From 865f3c161496a66d818e8bb2a59ecfc9ad77eae4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 10:09:47 +0200 Subject: [PATCH 1048/4498] Bluetooth controller nrf: nrf52 bsim radio hal header minor updates Align the header a bit with the one for the real radio, adding missing Tx power levels and removing TODO which did not need doing. The old one originated as a copy of the nrf52833 one, and did not evolve like the real ones. Signed-off-by: Alberto Escolar Piedras --- .../nordic/hal/nrf5/radio/radio_sim_nrf52.h | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h index a767fe1ab30..3d53462326a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h @@ -185,14 +185,10 @@ static inline void hal_radio_reset(void) { - /* TODO: Add any required setup for each radio event - */ } static inline void hal_radio_stop(void) { - /* TODO: Add any required cleanup of actions taken in hal_radio_reset() - */ } static inline void hal_radio_ram_prio_setup(void) @@ -226,25 +222,39 @@ static inline uint32_t hal_radio_tx_power_min_get(void) static inline uint32_t hal_radio_tx_power_max_get(void) { -#if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm) - return RADIO_TXPOWER_TXPOWER_Pos4dBm; -#else - return RADIO_TXPOWER_TXPOWER_0dBm; -#endif + return RADIO_TXPOWER_TXPOWER_Pos8dBm; } static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) { -#if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm) + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos8dBm) { + return RADIO_TXPOWER_TXPOWER_Pos8dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos7dBm) { + return RADIO_TXPOWER_TXPOWER_Pos7dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos6dBm) { + return RADIO_TXPOWER_TXPOWER_Pos6dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos5dBm) { + return RADIO_TXPOWER_TXPOWER_Pos5dBm; + } + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { return RADIO_TXPOWER_TXPOWER_Pos4dBm; } -#endif -#if defined(RADIO_TXPOWER_TXPOWER_Pos3dBm) + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { return RADIO_TXPOWER_TXPOWER_Pos3dBm; } -#endif + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos2dBm) { + return RADIO_TXPOWER_TXPOWER_Pos2dBm; + } + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { return RADIO_TXPOWER_TXPOWER_0dBm; } @@ -269,10 +279,7 @@ static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) return RADIO_TXPOWER_TXPOWER_Neg20dBm; } - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg30dBm) { - return RADIO_TXPOWER_TXPOWER_Neg30dBm; - } - + /* Note: The -30 dBm power level is deprecated so ignore it! */ return RADIO_TXPOWER_TXPOWER_Neg40dBm; } From 292ca93795598e02210bc8c2114ed46db5ea4cc0 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 22 Sep 2023 14:00:44 +0200 Subject: [PATCH 1049/4498] Bluetooth controller nrf: nrf52 bsim radio hal fix hal_radio_tx_chain_delay_ns_get() was incorrectly returning the microsecond value, resulting in a 1us error in the timing => Fix it. Signed-off-by: Alberto Escolar Piedras --- .../ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h index 3d53462326a..1b8c1583547 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h @@ -14,7 +14,10 @@ /* NRF Radio HW timing constants * - provided in US and NS (for higher granularity) - * - based on empirical measurements and sniffer logs + * - based on the timings configured in the HW models, which are based + * on the product specification + * - Note that this timings are approx. the same as in the real HW, + * but tend to be rounded to the nearest microsecond */ /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) @@ -361,7 +364,7 @@ static inline uint32_t hal_radio_tx_chain_delay_ns_get(uint8_t phy, uint8_t flag ARG_UNUSED(phy); ARG_UNUSED(flags); - return HAL_RADIO_NRF52833_TX_CHAIN_DELAY_US; + return HAL_RADIO_NRF52833_TX_CHAIN_DELAY_NS; } static inline uint32_t hal_radio_rx_chain_delay_ns_get(uint8_t phy, uint8_t flags) From 877208dc7855fb7c40c40c328819cf35008ec170 Mon Sep 17 00:00:00 2001 From: Bindu S Date: Tue, 8 Aug 2023 10:45:49 +0530 Subject: [PATCH 1050/4498] drivers: i2c: i2c_dw: Added intel lpss dma support for I2C Enabled intel LPSS DMA interface using dw common to support usage of internal DMA in LPSS I2C to transfer and receive data. Signed-off-by: Bindu S --- drivers/i2c/Kconfig.dw | 9 ++ drivers/i2c/i2c_dw.c | 191 ++++++++++++++++++++++++++++++++- drivers/i2c/i2c_dw.h | 7 ++ drivers/i2c/i2c_dw_registers.h | 19 ++++ 4 files changed, 224 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/Kconfig.dw b/drivers/i2c/Kconfig.dw index b6350b269f4..c84215f4571 100644 --- a/drivers/i2c/Kconfig.dw +++ b/drivers/i2c/Kconfig.dw @@ -12,3 +12,12 @@ config I2C_DW_CLOCK_SPEED int "Set the clock speed for I2C" depends on I2C_DW default 32 + +config I2C_DW_LPSS_DMA + bool "Use I2C integrated DMA for asynchronous transfer" + select DMA + select DMA_INTEL_LPSS + help + This option enables I2C DMA feature to be used for asynchrounous + data transfers. All Tx operaton are done using dma channel 0 and + all Rx operations are done using dma channel 1. diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index bb5ecc3779f..ca4485606b7 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -30,6 +30,11 @@ #include +#if defined(CONFIG_I2C_DW_LPSS_DMA) +#include +#include +#endif + #ifdef CONFIG_IOAPIC #include #endif @@ -48,6 +53,147 @@ static inline uint32_t get_regs(const struct device *dev) return (uint32_t)DEVICE_MMIO_GET(dev); } +#ifdef CONFIG_I2C_DW_LPSS_DMA +void i2c_dw_enable_idma(const struct device *dev, bool enable) +{ + uint32_t reg; + uint32_t reg_base = get_regs(dev); + + if (enable) { + write_dma_cr(DW_IC_DMA_ENABLE, reg_base); + reg = sys_read32(reg_base + DW_IC_REG_DMA_CR); + } else { + reg = read_dma_cr(reg_base); + reg &= ~DW_IC_DMA_ENABLE; + write_dma_cr(reg, reg_base); + reg = sys_read32(reg_base + DW_IC_REG_DMA_CR); + } +} + +void cb_i2c_idma_transfer(const struct device *dma, void *user_data, + uint32_t channel, int status) +{ + const struct device *dev = (const struct device *)user_data; + struct i2c_dw_dev_config *const dw = dev->data; + + dma_stop(dw->dma_dev, channel); + i2c_dw_enable_idma(dev, false); + + if (status) { + dw->xfr_status = true; + } else { + dw->xfr_status = false; + } +} + +void i2c_dw_set_fifo_th(const struct device *dev, uint8_t fifo_depth) +{ + uint32_t reg_base = get_regs(dev); + + write_tdlr(fifo_depth, reg_base); + write_rdlr(fifo_depth - 1, reg_base); +} + +inline void *i2c_dw_dr_phy_addr(const struct device *dev) +{ + struct i2c_dw_dev_config *const dw = dev->data; + + return (void *) (dw->phy_addr + DW_IC_REG_DATA_CMD); +} + +int32_t i2c_dw_idma_rx_transfer(const struct device *dev) +{ + struct i2c_dw_dev_config *const dw = dev->data; + + struct dma_config dma_cfg = { 0 }; + struct dma_block_config dma_block_cfg = { 0 }; + + if (!device_is_ready(dw->dma_dev)) { + LOG_DBG("DMA device is not ready"); + return -ENODEV; + } + + dma_cfg.dma_slot = 1U; + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1U; + dma_cfg.dest_data_size = 1U; + dma_cfg.source_burst_length = 1U; + dma_cfg.dest_burst_length = 1U; + dma_cfg.dma_callback = cb_i2c_idma_transfer; + dma_cfg.user_data = (void *)dev; + dma_cfg.complete_callback_en = 0U; + dma_cfg.error_callback_en = 1U; + dma_cfg.block_count = 1U; + dma_cfg.head_block = &dma_block_cfg; + + dma_block_cfg.block_size = dw->xfr_len; + dma_block_cfg.dest_address = (uint64_t)&dw->xfr_buf[0]; + dma_block_cfg.source_address = (uint64_t)i2c_dw_dr_phy_addr(dev); + dw->xfr_status = false; + + if (dma_config(dw->dma_dev, DMA_INTEL_LPSS_RX_CHAN, &dma_cfg)) { + LOG_DBG("Error transfer"); + return -EIO; + } + + if (dma_start(dw->dma_dev, DMA_INTEL_LPSS_RX_CHAN)) { + LOG_DBG("Error transfer"); + return -EIO; + } + + i2c_dw_enable_idma(dev, true); + i2c_dw_set_fifo_th(dev, 1); + + return 0; +} + +int32_t i2c_dw_idma_tx_transfer(const struct device *dev, + uint64_t data) +{ + struct i2c_dw_dev_config *const dw = dev->data; + + struct dma_config dma_cfg = { 0 }; + struct dma_block_config dma_block_cfg = { 0 }; + + if (!device_is_ready(dw->dma_dev)) { + LOG_DBG("DMA device is not ready"); + return -ENODEV; + } + + dma_cfg.dma_slot = 0U; + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.source_data_size = 1U; + dma_cfg.dest_data_size = 1U; + dma_cfg.source_burst_length = 1U; + dma_cfg.dest_burst_length = 1U; + dma_cfg.dma_callback = cb_i2c_idma_transfer; + dma_cfg.user_data = (void *)dev; + dma_cfg.complete_callback_en = 0U; + dma_cfg.error_callback_en = 1U; + dma_cfg.block_count = 1U; + dma_cfg.head_block = &dma_block_cfg; + + dma_block_cfg.block_size = 1; + dma_block_cfg.source_address = (uint64_t)&data; + dma_block_cfg.dest_address = (uint64_t)i2c_dw_dr_phy_addr(dev); + dw->xfr_status = false; + + if (dma_config(dw->dma_dev, DMA_INTEL_LPSS_TX_CHAN, &dma_cfg)) { + LOG_DBG("Error transfer"); + return -EIO; + } + + if (dma_start(dw->dma_dev, DMA_INTEL_LPSS_TX_CHAN)) { + LOG_DBG("Error trnasfer"); + return -EIO; + } + i2c_dw_enable_idma(dev, true); + i2c_dw_set_fifo_th(dev, 1); + + return 0; +} +#endif + static inline void i2c_dw_data_ask(const struct device *dev) { struct i2c_dw_dev_config * const dw = dev->data; @@ -119,6 +265,13 @@ static void i2c_dw_data_read(const struct device *dev) struct i2c_dw_dev_config * const dw = dev->data; uint32_t reg_base = get_regs(dev); +#ifdef CONFIG_I2C_DW_LPSS_DMA + if (test_bit_status_rfne(reg_base) && (dw->xfr_len > 0)) { + i2c_dw_idma_rx_transfer(dev); + dw->xfr_len = 0; + dw->rx_pending = 0; + } +#else while (test_bit_status_rfne(reg_base) && (dw->xfr_len > 0)) { dw->xfr_buf[0] = (uint8_t)read_cmd_data(reg_base); @@ -130,7 +283,7 @@ static void i2c_dw_data_read(const struct device *dev) break; } } - +#endif /* Nothing to receive anymore */ if (dw->xfr_len == 0U) { dw->state &= ~I2C_DW_CMD_RECV; @@ -169,8 +322,11 @@ static int i2c_dw_data_send(const struct device *dev) data |= IC_DATA_CMD_STOP; } +#ifdef CONFIG_I2C_DW_LPSS_DMA + i2c_dw_idma_tx_transfer(dev, data); +#else write_cmd_data(data, reg_base); - +#endif dw->xfr_len--; dw->xfr_buf++; @@ -230,6 +386,16 @@ static void i2c_dw_isr(const struct device *port) /* Check if we are configured as a master device */ if (test_bit_con_master_mode(reg_base)) { +#ifdef CONFIG_I2C_DW_LPSS_DMA + uint32_t stat = sys_read32(reg_base + IDMA_REG_INTR_STS); + + if (stat & IDMA_TX_RX_CHAN_MASK) { + /* Handle the DMA interrupt */ + dma_intel_lpss_isr(dw->dma_dev); + + } +#endif + /* Bail early if there is any error. */ if ((DW_INTR_STAT_TX_ABRT | DW_INTR_STAT_TX_OVER | DW_INTR_STAT_RX_OVER | DW_INTR_STAT_RX_UNDER) & @@ -879,6 +1045,26 @@ static int i2c_dw_initialize(const struct device *dev) device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE); + + pcie_set_cmd(rom->pcie->bdf, PCIE_CONF_CMDSTAT_MASTER, true); + +#ifdef CONFIG_I2C_DW_LPSS_DMA + size_t nhdls = 0; + const device_handle_t *hdls; + + hdls = device_supported_handles_get(dev, &nhdls); + dw->dma_dev = device_from_handle(*hdls); + + /* Assign physical & virtual address to dma instance */ + dw->phy_addr = mbar.phys_addr; + dw->base_addr = (uint32_t)(DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_OFFSET); + sys_write32((uint32_t)dw->phy_addr, + DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_REMAP_LOW); + sys_write32((uint32_t)(dw->phy_addr >> DMA_INTEL_LPSS_ADDR_RIGHT_SHIFT), + DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_REMAP_HI); + LOG_DBG("i2c instance physical addr: [0x%lx], virtual addr: [0x%lx]", + dw->phy_addr, dw->base_addr); +#endif } else #endif { @@ -889,6 +1075,7 @@ static int i2c_dw_initialize(const struct device *dev) k_mutex_init(&dw->bus_mutex); uint32_t reg_base = get_regs(dev); + clear_bit_enable_en(reg_base); /* verify that we have a valid DesignWare register first */ diff --git a/drivers/i2c/i2c_dw.h b/drivers/i2c/i2c_dw.h index 1aac3d20340..34427504708 100644 --- a/drivers/i2c/i2c_dw.h +++ b/drivers/i2c/i2c_dw.h @@ -123,6 +123,13 @@ struct i2c_dw_dev_config { uint8_t request_bytes; uint8_t xfr_flags; bool support_hs_mode; +#ifdef CONFIG_I2C_DW_LPSS_DMA + const struct device *dma_dev; + uintptr_t phy_addr; + uintptr_t base_addr; + /* For dma transfer */ + bool xfr_status; +#endif struct i2c_target_config *slave_cfg; }; diff --git a/drivers/i2c/i2c_dw_registers.h b/drivers/i2c/i2c_dw_registers.h index be76cbdaad9..6b2a11dffa4 100644 --- a/drivers/i2c/i2c_dw_registers.h +++ b/drivers/i2c/i2c_dw_registers.h @@ -144,14 +144,25 @@ union ic_comp_param_1_register { #define DW_IC_REG_STATUS (0x70) #define DW_IC_REG_TXFLR (0x74) #define DW_IC_REG_RXFLR (0x78) +#define DW_IC_REG_DMA_CR (0x88) +#define DW_IC_REG_TDLR (0x8C) +#define DW_IC_REG_RDLR (0x90) #define DW_IC_REG_FS_SPKLEN (0xA0) #define DW_IC_REG_HS_SPKLEN (0xA4) #define DW_IC_REG_COMP_PARAM_1 (0xF4) #define DW_IC_REG_COMP_TYPE (0xFC) +#define IDMA_REG_INTR_STS 0xAE8 +#define IDMA_TX_RX_CHAN_MASK 0x3 + /* CON Bit */ #define DW_IC_CON_MASTER_MODE_BIT (0) +/* DMA control bits */ +#define DW_IC_DMA_RX_ENABLE BIT(0) +#define DW_IC_DMA_TX_ENABLE BIT(1) +#define DW_IC_DMA_ENABLE (BIT(0) | BIT(1)) + DEFINE_TEST_BIT_OP(con_master_mode, DW_IC_REG_CON, DW_IC_CON_MASTER_MODE_BIT) DEFINE_MM_REG_WRITE(con, DW_IC_REG_CON, 32) DEFINE_MM_REG_READ(con, DW_IC_REG_CON, 32) @@ -209,6 +220,14 @@ DEFINE_TEST_BIT_OP(status_rfne, DW_IC_REG_STATUS, DW_IC_STATUS_RFNE_BIT) DEFINE_MM_REG_READ(txflr, DW_IC_REG_TXFLR, 32) DEFINE_MM_REG_READ(rxflr, DW_IC_REG_RXFLR, 32) +DEFINE_MM_REG_READ(dma_cr, DW_IC_REG_DMA_CR, 32) +DEFINE_MM_REG_WRITE(dma_cr, DW_IC_REG_DMA_CR, 32) + +DEFINE_MM_REG_READ(tdlr, DW_IC_REG_TDLR, 32) +DEFINE_MM_REG_WRITE(tdlr, DW_IC_REG_TDLR, 32) +DEFINE_MM_REG_READ(rdlr, DW_IC_REG_RDLR, 32) +DEFINE_MM_REG_WRITE(rdlr, DW_IC_REG_RDLR, 32) + DEFINE_MM_REG_READ(fs_spklen, DW_IC_REG_FS_SPKLEN, 32) DEFINE_MM_REG_READ(hs_spklen, DW_IC_REG_HS_SPKLEN, 32) From a1654585bf879126ba477fbb9eafa23344eb732f Mon Sep 17 00:00:00 2001 From: Bindu S Date: Tue, 8 Aug 2023 10:52:23 +0530 Subject: [PATCH 1051/4498] dts: x86: intel: Added dts changes to support dma for RPL Added dts changes to support lpss dma for I2C driver for RPL platform. Signed-off-by: Bindu S --- dts/x86/intel/raptor_lake.dtsi | 62 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index 1e412336ae8..91a6d933260 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -75,6 +75,13 @@ status = "okay"; }; + i2c0_dma: i2c0_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c0>; + #dma-cells = <1>; + status = "okay"; + }; + i2c1: i2c1 { compatible = "snps,designware-i2c"; clock-frequency = ; @@ -85,7 +92,14 @@ interrupts = ; interrupt-parent = <&intc>; - status = "okay"; + status = "disabled"; + }; + + i2c1_dma: i2c1_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c1>; + #dma-cells = <1>; + status = "disabled"; }; i2c2: i2c2 { @@ -93,12 +107,21 @@ clock-frequency = ; #address-cells = <1>; #size-cells = <0>; + #address-cells = <1>; + #size-cells = <0>; vendor-id = <0x8086>; device-id = <0x7ace>; interrupts = ; interrupt-parent = <&intc>; - status = "okay"; + status = "disabled"; + }; + + i2c2_dma: i2c2_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c2>; + #dma-cells = <1>; + status = "disabled"; }; i2c3: i2c3 { @@ -114,6 +137,13 @@ status = "disabled"; }; + i2c3_dma: i2c3_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c3>; + #dma-cells = <1>; + status = "disabled"; + }; + i2c4: i2c4 { compatible = "snps,designware-i2c"; clock-frequency = ; @@ -127,6 +157,13 @@ status = "disabled"; }; + i2c4_dma: i2c4_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c4>; + #dma-cells = <1>; + status = "disabled"; + }; + i2c5: i2c5 { compatible = "snps,designware-i2c"; clock-frequency = ; @@ -140,6 +177,13 @@ status = "disabled"; }; + i2c5_dma: i2c5_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c5>; + #dma-cells = <1>; + status = "disabled"; + }; + i2c6: i2c6 { compatible = "snps,designware-i2c"; clock-frequency = ; @@ -153,6 +197,13 @@ status = "disabled"; }; + i2c6_dma: i2c6_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c6>; + #dma-cells = <1>; + status = "disabled"; + }; + i2c7: i2c7 { compatible = "snps,designware-i2c"; clock-frequency = ; @@ -166,6 +217,13 @@ status = "disabled"; }; + i2c7_dma: i2c7_dma { + compatible = "intel,lpss"; + dma-parent = <&i2c7>; + #dma-cells = <1>; + status = "disabled"; + }; + spi0: spi0 { compatible = "intel,penwell-spi"; vendor-id = <0x8086>; From 361555721bac318717a7e7810f708769a08e2945 Mon Sep 17 00:00:00 2001 From: Bindu S Date: Tue, 8 Aug 2023 10:55:43 +0530 Subject: [PATCH 1052/4498] boards: x86: rpl_crb: Added lpss dma support for raptor lake crb added intel lpss dma support for raptor lake crb Signed-off-by: Bindu S --- boards/x86/intel_rpl/Kconfig.defconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/boards/x86/intel_rpl/Kconfig.defconfig b/boards/x86/intel_rpl/Kconfig.defconfig index ee81baa21f3..99d9f8d08f2 100644 --- a/boards/x86/intel_rpl/Kconfig.defconfig +++ b/boards/x86/intel_rpl/Kconfig.defconfig @@ -29,6 +29,15 @@ endif config ACPI default y +if DMA +config DMA_64BIT + default y +config DMA_DW_HW_LLI + default n +config DMA_DW_CHANNEL_COUNT + default 2 +endif + if SHELL config SHELL_STACK_SIZE default 320000 From 79852e216e078af93df6acb8b63be98321cb6dc0 Mon Sep 17 00:00:00 2001 From: Bindu S Date: Tue, 8 Aug 2023 11:08:16 +0530 Subject: [PATCH 1053/4498] drivers: dma: dma_dw_common: Updated check condition of DMA channel updating check condition for dma channel for correct limit Signed-off-by: Bindu S --- drivers/dma/dma_dw_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dma_dw_common.c b/drivers/dma/dma_dw_common.c index e3210658dfc..bb000298385 100644 --- a/drivers/dma/dma_dw_common.c +++ b/drivers/dma/dma_dw_common.c @@ -809,7 +809,7 @@ int dw_dma_get_status(const struct device *dev, uint32_t channel, const struct dw_dma_dev_cfg *const dev_cfg = dev->config; struct dw_dma_chan_data *chan_data; - if (channel >= DW_MAX_CHAN) { + if (channel >= DW_CHAN_COUNT) { return -EINVAL; } From 7a6f251edbaefe02cea58bad222d5b6eddecbc16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Sep 2023 15:39:39 +0200 Subject: [PATCH 1054/4498] doc: samples: tfm: remove extra title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed the redundant title heading from this page. Signed-off-by: Benjamin Cabé --- samples/tfm_integration/tfm_integration.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/samples/tfm_integration/tfm_integration.rst b/samples/tfm_integration/tfm_integration.rst index 2ca5804d595..02cd3e97855 100644 --- a/samples/tfm_integration/tfm_integration.rst +++ b/samples/tfm_integration/tfm_integration.rst @@ -9,9 +9,6 @@ TF-M Integration Samples */* -Trusted Firmware-M (TF-M) -######################### - Overview ******** These TF-M integration examples can be used with a supported Armv8-M board, and From 2479af21f6694b07ead68b40e1082ccde760d957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Sep 2023 15:40:44 +0200 Subject: [PATCH 1055/4498] doc: samples: Fix incorrect maxdepth for some toctrees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The table of contents for the samples' catalog was showing too many levels for some sections. Signed-off-by: Benjamin Cabé --- samples/index.rst | 1 + samples/modules/index.rst | 3 ++- samples/subsys/portability/portability.rst | 2 +- samples/subsys/subsys.rst | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/index.rst b/samples/index.rst index 0ba36eeaebb..8581a330d40 100644 --- a/samples/index.rst +++ b/samples/index.rst @@ -5,6 +5,7 @@ Samples and Demos .. toctree:: + :titlesonly: :maxdepth: 2 :glob: diff --git a/samples/modules/index.rst b/samples/modules/index.rst index 79828d002a2..5316bb6e244 100644 --- a/samples/modules/index.rst +++ b/samples/modules/index.rst @@ -4,7 +4,8 @@ External Module Samples ####################### .. toctree:: - :maxdepth: 2 + :titlesonly: + :maxdepth: 1 :glob: **/* diff --git a/samples/subsys/portability/portability.rst b/samples/subsys/portability/portability.rst index 1be238d794c..b47ee35edc9 100644 --- a/samples/subsys/portability/portability.rst +++ b/samples/subsys/portability/portability.rst @@ -4,7 +4,7 @@ Portability Samples ################### .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: **/* diff --git a/samples/subsys/subsys.rst b/samples/subsys/subsys.rst index 0ea09d7a7d3..bf58c7dda63 100644 --- a/samples/subsys/subsys.rst +++ b/samples/subsys/subsys.rst @@ -4,6 +4,7 @@ Various Subsystems Samples ########################## .. toctree:: + :titlesonly: :maxdepth: 2 :glob: From 2899df629f491960543521718a37837b0f7a7f06 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 10:54:29 -0700 Subject: [PATCH 1056/4498] uart: ns16550: remove unused forward declaration Remove the unused forward declaration of the driver API struct. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index c7357d076f1..8124733c2fb 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -367,8 +367,6 @@ static inline uint8_t reg_interval(const struct device *dev) return config->reg_interval; } -static const struct uart_driver_api uart_ns16550_driver_api; - static inline uintptr_t get_port(const struct device *dev) { uintptr_t port; From fe10897f70e9bdfcd90fa00f96ddf322d65938eb Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 13:32:15 -0700 Subject: [PATCH 1057/4498] uart: ns16550: simplify DLF and PCP related macros This simplifies DLF and PCP enabling devicetree macros with DT_ANY_INST_HAS_PROP_STATUS_OKAY() instead of the complicated ones. Also, this moves the macro to initialize struct elements into the struct initializer itself. This makes it clearer on which element is being initialized directly inside the struct initializer instead of having to do mental macro trampoline to find the correct macro. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 8124733c2fb..49d8416f950 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -43,13 +43,8 @@ LOG_MODULE_REGISTER(uart_ns16550, CONFIG_UART_LOG_LEVEL); -#define INST_HAS_PCP_HELPER(inst) DT_INST_NODE_HAS_PROP(inst, pcp) || -#define INST_HAS_DLF_HELPER(inst) DT_INST_NODE_HAS_PROP(inst, dlf) || - -#define UART_NS16550_PCP_ENABLED \ - (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_PCP_HELPER) 0) -#define UART_NS16550_DLF_ENABLED \ - (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_DLF_HELPER) 0) +#define UART_NS16550_PCP_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(pcp) +#define UART_NS16550_DLF_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(dlf) #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); @@ -1300,12 +1295,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define UART_NS16550_IRQ_FUNC_DEFINE(n) #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#if UART_NS16550_PCP_ENABLED -#define DEV_CONFIG_PCP_INIT(n) .pcp = DT_INST_PROP_OR(n, pcp, 0), -#else -#define DEV_CONFIG_PCP_INIT(n) -#endif - #define DEV_CONFIG_PCIE0(n) #define DEV_CONFIG_PCIE1(n) DEVICE_PCIE_INST_INIT(n, pcie) #define DEV_CONFIG_PCIE_INIT(n) \ @@ -1321,12 +1310,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define DEV_DATA_FLOW_CTRL(n) \ _CONCAT(DEV_DATA_FLOW_CTRL, DT_INST_PROP_OR(n, hw_flow_control, 0)) -#define DEV_DATA_DLF0(n) -#define DEV_DATA_DLF1(n) \ - .dlf = DT_INST_PROP(n, dlf), -#define DEV_DATA_DLF_INIT(n) \ - _CONCAT(DEV_DATA_DLF, DT_INST_NODE_HAS_PROP(n, dlf))(n) - #ifdef CONFIG_UART_NS16550_PARENT_INIT_LEVEL #define NS16550_BOOT_LEVEL0 PRE_KERNEL_1 #define NS16550_BOOT_LEVEL1 POST_KERNEL @@ -1357,7 +1340,8 @@ static const struct uart_driver_api uart_ns16550_driver_api = { ) \ ) \ DEV_CONFIG_IRQ_FUNC_INIT(n) \ - DEV_CONFIG_PCP_INIT(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pcp), \ + (.pcp = DT_INST_PROP_OR(n, pcp, 0),)) \ .reg_interval = (1 << DT_INST_PROP(n, reg_shift)), \ DEV_CONFIG_PCIE_INIT(n) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ @@ -1371,7 +1355,8 @@ static const struct uart_driver_api uart_ns16550_driver_api = { .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ .uart_config.data_bits = UART_CFG_DATA_BITS_8, \ .uart_config.flow_ctrl = DEV_DATA_FLOW_CTRL(n), \ - DEV_DATA_DLF_INIT(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, dlf), \ + (.dlf = DT_INST_PROP_OR(n, dlf, 0),)) \ }; \ DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \ &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \ From 39f8b7d51d5d531f7ef8350d925bb308d7f12e7d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 15:40:12 -0700 Subject: [PATCH 1058/4498] uart: ns16550: simplify UART_NS16550_IRQ_FLAGS Using COND_CODE_1() is more intuitive when looking at the code, instead of some macro trampoline magic. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 49d8416f950..65aa1c38770 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1220,10 +1220,10 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #endif }; -#define UART_NS16550_IRQ_FLAGS_SENSE0(n) 0 -#define UART_NS16550_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) #define UART_NS16550_IRQ_FLAGS(n) \ - _CONCAT(UART_NS16550_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, sense), \ + (DT_INST_IRQ(n, sense)), \ + (0)) /* not PCI(e) */ #define UART_NS16550_IRQ_CONFIG_PCIE0(n) \ From 7d0e223112c1c44e0fc5549dfcbe014d59d24583 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 15:49:33 -0700 Subject: [PATCH 1059/4498] uart: ns16550: simplify DEV_CONFIG_PCIE_INIT/DEV_PCIE_DECLARE Use COND_CODE_1() instead of macro trampolines. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 65aa1c38770..e9a4398e7f8 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1295,15 +1295,11 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define UART_NS16550_IRQ_FUNC_DEFINE(n) #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define DEV_CONFIG_PCIE0(n) -#define DEV_CONFIG_PCIE1(n) DEVICE_PCIE_INST_INIT(n, pcie) #define DEV_CONFIG_PCIE_INIT(n) \ - _CONCAT(DEV_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) + COND_CODE_1(DT_INST_ON_BUS(n, pcie), (DEVICE_PCIE_INST_INIT(n, pcie)), ()) -#define DEV_DECLARE_PCIE0(n) -#define DEV_DECLARE_PCIE1(n) DEVICE_PCIE_INST_DECLARE(n) #define DEV_PCIE_DECLARE(n) \ - _CONCAT(DEV_DECLARE_PCIE, DT_INST_ON_BUS(n, pcie))(n) + COND_CODE_1(DT_INST_ON_BUS(n, pcie), (DEVICE_PCIE_INST_DECLARE(n)), ()) #define DEV_DATA_FLOW_CTRL0 UART_CFG_FLOW_CTRL_NONE #define DEV_DATA_FLOW_CTRL1 UART_CFG_FLOW_CTRL_RTS_CTS From 8b54cb859e3c48f06ec51ab04bb5bebece5db1d3 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 15:51:10 -0700 Subject: [PATCH 1060/4498] uart: ns16550: simplify BOOT_LEVEL Use CODE_CODE_1() instead of macro trampolines when CONFIG_UART_NS16550_PARENT_INIT_LEVEL is enabled. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index e9a4398e7f8..0783fc11d66 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1307,10 +1307,8 @@ static const struct uart_driver_api uart_ns16550_driver_api = { _CONCAT(DEV_DATA_FLOW_CTRL, DT_INST_PROP_OR(n, hw_flow_control, 0)) #ifdef CONFIG_UART_NS16550_PARENT_INIT_LEVEL -#define NS16550_BOOT_LEVEL0 PRE_KERNEL_1 -#define NS16550_BOOT_LEVEL1 POST_KERNEL #define BOOT_LEVEL(n) \ - _CONCAT(NS16550_BOOT_LEVEL, DT_INST_ON_BUS(n, pcie)) + COND_CODE_1(DT_INST_ON_BUS(n, pcie), (POST_KERNEL), (PRE_KERNEL_1)) #else #define BOOT_LEVEL(n) PRE_KERNEL_1 #endif From 566d21804cdbde585742d677c69206959de1f3b4 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 15:54:41 -0700 Subject: [PATCH 1061/4498] uart: ns16550: simplify DEV_DATA_FLOW_CTRL Use COND_CODE_1() instead of macro trampoline and move it into struct initializer. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 0783fc11d66..71b90b25f96 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1301,11 +1301,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define DEV_PCIE_DECLARE(n) \ COND_CODE_1(DT_INST_ON_BUS(n, pcie), (DEVICE_PCIE_INST_DECLARE(n)), ()) -#define DEV_DATA_FLOW_CTRL0 UART_CFG_FLOW_CTRL_NONE -#define DEV_DATA_FLOW_CTRL1 UART_CFG_FLOW_CTRL_RTS_CTS -#define DEV_DATA_FLOW_CTRL(n) \ - _CONCAT(DEV_DATA_FLOW_CTRL, DT_INST_PROP_OR(n, hw_flow_control, 0)) - #ifdef CONFIG_UART_NS16550_PARENT_INIT_LEVEL #define BOOT_LEVEL(n) \ COND_CODE_1(DT_INST_ON_BUS(n, pcie), (POST_KERNEL), (PRE_KERNEL_1)) @@ -1348,7 +1343,10 @@ static const struct uart_driver_api uart_ns16550_driver_api = { .uart_config.parity = UART_CFG_PARITY_NONE, \ .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ .uart_config.data_bits = UART_CFG_DATA_BITS_8, \ - .uart_config.flow_ctrl = DEV_DATA_FLOW_CTRL(n), \ + .uart_config.flow_ctrl = \ + COND_CODE_1(DT_INST_PROP_OR(n, hw_flow_control, 0), \ + (UART_CFG_FLOW_CTRL_RTS_CTS), \ + (UART_CFG_FLOW_CTRL_NONE)), \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, dlf), \ (.dlf = DT_INST_PROP_OR(n, dlf, 0),)) \ }; \ From 53bc95e21873344f9e528ef4ddcc90310a9518ce Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 18 Sep 2023 15:58:32 -0700 Subject: [PATCH 1062/4498] uart: ns16550: refactor UART_NS16550_IRQ_CONFIG_* Instead of PCIE0 and PCIE1, use no suffix for IO port/MMIO IRQ configuration funct, and suffix PCIE for IRQ config on PCIE bus. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 71b90b25f96..39b6f1dfe27 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1225,8 +1225,8 @@ static const struct uart_driver_api uart_ns16550_driver_api = { (DT_INST_IRQ(n, sense)), \ (0)) -/* not PCI(e) */ -#define UART_NS16550_IRQ_CONFIG_PCIE0(n) \ +/* IO-port or MMIO based UART */ +#define UART_NS16550_IRQ_CONFIG(n) \ static void irq_config_func##n(const struct device *dev) \ { \ ARG_UNUSED(dev); \ @@ -1237,7 +1237,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { } /* PCI(e) with auto IRQ detection */ -#define UART_NS16550_IRQ_CONFIG_PCIE1(n) \ +#define UART_NS16550_IRQ_CONFIG_PCIE(n) \ static void irq_config_func##n(const struct device *dev) \ { \ BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \ @@ -1287,7 +1287,9 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define UART_NS16550_IRQ_FUNC_DECLARE(n) \ static void irq_config_func##n(const struct device *dev); #define UART_NS16550_IRQ_FUNC_DEFINE(n) \ - _CONCAT(UART_NS16550_IRQ_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) + COND_CODE_1(DT_INST_ON_BUS(n, pcie), \ + (UART_NS16550_IRQ_CONFIG_PCIE(n)), \ + (UART_NS16550_IRQ_CONFIG(n))) #else /* !CONFIG_UART_INTERRUPT_DRIVEN */ #define DEV_CONFIG_IRQ_FUNC_INIT(n) From 32969563313fcfabbffa87628c8ac136b99220d1 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 19 Sep 2023 15:11:05 -0700 Subject: [PATCH 1063/4498] uart: ns16550: move setting .reset_spec inside initializer This moves setting .reset_spec inside struct initializer instead of using macro trampoline. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 39b6f1dfe27..08bcd4a38c1 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1309,8 +1309,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #else #define BOOT_LEVEL(n) PRE_KERNEL_1 #endif -#define UART_RESET_FUNC_INIT(n) \ - .reset_spec = RESET_DT_SPEC_INST_GET(n), #define UART_NS16550_DEVICE_INIT(n) \ UART_NS16550_IRQ_FUNC_DECLARE(n); \ @@ -1338,7 +1336,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ (.pincfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(n)),)) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, resets), \ - (UART_RESET_FUNC_INIT(n))) \ + (.reset_spec = RESET_DT_SPEC_INST_GET(n),)) \ }; \ static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \ .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \ From 9f9b4a8afa98e05d0478f5f2c318b665f445bd67 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 21 Sep 2023 17:17:13 -0700 Subject: [PATCH 1064/4498] uart: ns16550: use io-mapped DT property for IO port access The old CONFIG_UART_NS16550_ACCESS_IOPORT has been used to indicate whether to access the NS16550 UART via IO port before device tree is used to describe hardware. Now we have device tree, and we can specify whether a particular UART needs to be accessed via IO port using property io-mapped. Therefore, CONFIG_UART_NS16550_ACCESS_IOPORT is no longer needed (and thus also CONFIG_UART_NS16550_SIMULT_ACCESS). Remove these two kconfigs and modify code to use device tree to figure out how to access the UART hardware. Signed-off-by: Daniel Leung --- arch/x86/core/early_serial.c | 7 ++- boards/x86/intel_adl/Kconfig.defconfig | 7 --- boards/x86/qemu_x86/Kconfig.defconfig | 3 -- boards/x86/qemu_x86/qemu_x86_lakemont.dts | 1 + drivers/serial/Kconfig.ns16550 | 12 ----- drivers/serial/uart_ns16550.c | 61 +++++++++++------------ dts/arc/synopsys/arc_iot.dtsi | 4 ++ dts/x86/intel/alder_lake.dtsi | 1 + dts/x86/intel/atom.dtsi | 2 + dts/x86/intel/ia32.dtsi | 2 + dts/x86/intel/raptor_lake.dtsi | 1 + soc/arc/snps_arc_iot/Kconfig.defconfig | 3 -- soc/x86/atom/Kconfig.defconfig | 3 -- soc/x86/ia32/Kconfig.defconfig | 3 -- soc/x86/raptor_lake/Kconfig.defconfig | 3 -- 15 files changed, 45 insertions(+), 68 deletions(-) diff --git a/arch/x86/core/early_serial.c b/arch/x86/core/early_serial.c index 0c102300a51..572b71cf5a0 100644 --- a/arch/x86/core/early_serial.c +++ b/arch/x86/core/early_serial.c @@ -11,7 +11,10 @@ #include -#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT +#define UART_IS_IOPORT_ACCESS \ + DT_NODE_HAS_PROP(DT_CHOSEN(zephyr_console), io_mapped) + +#if UART_IS_IOPORT_ACCESS /* Legacy I/O Port Access to a NS16550 UART */ #define IN(reg) sys_in8(reg + DT_REG_ADDR(DT_CHOSEN(zephyr_console))) #define OUT(reg, val) sys_out8(val, reg + DT_REG_ADDR(DT_CHOSEN(zephyr_console))) @@ -86,7 +89,7 @@ int arch_printk_char_out(int c) void z_x86_early_serial_init(void) { -#if defined(DEVICE_MMIO_IS_IN_RAM) && !defined(CONFIG_UART_NS16550_ACCESS_IOPORT) +#if defined(DEVICE_MMIO_IS_IN_RAM) && !UART_IS_IOPORT_ACCESS #ifdef X86_SOC_EARLY_SERIAL_PCIDEV struct pcie_bar mbar; pcie_get_mbar(X86_SOC_EARLY_SERIAL_PCIDEV, 0, &mbar); diff --git a/boards/x86/intel_adl/Kconfig.defconfig b/boards/x86/intel_adl/Kconfig.defconfig index 0bc114e4693..9e2255a7471 100644 --- a/boards/x86/intel_adl/Kconfig.defconfig +++ b/boards/x86/intel_adl/Kconfig.defconfig @@ -44,10 +44,3 @@ endif # SHELL endif # ACPI endif # BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP - -if BOARD_INTEL_ADL_RVP - -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - -endif # BOARD_INTEL_ADL_RVP diff --git a/boards/x86/qemu_x86/Kconfig.defconfig b/boards/x86/qemu_x86/Kconfig.defconfig index 1ea60480f64..4ed71964aa3 100644 --- a/boards/x86/qemu_x86/Kconfig.defconfig +++ b/boards/x86/qemu_x86/Kconfig.defconfig @@ -81,9 +81,6 @@ config QEMU_ICOUNT config QEMU_ICOUNT_SHIFT default 5 -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif # BOARD_QEMU_X86_LAKEMONT if BOARD_QEMU_X86_TINY diff --git a/boards/x86/qemu_x86/qemu_x86_lakemont.dts b/boards/x86/qemu_x86/qemu_x86_lakemont.dts index 9c6a6da82ec..87056f9cf65 100644 --- a/boards/x86/qemu_x86/qemu_x86_lakemont.dts +++ b/boards/x86/qemu_x86/qemu_x86_lakemont.dts @@ -40,6 +40,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 22988f5f699..90c29046044 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -60,18 +60,6 @@ config UART_NS16550_ACCESS_WORD_ONLY 16550 (DesignWare UART) only allows word access, byte access will raise exception. -config UART_NS16550_ACCESS_IOPORT - bool - help - When enabled, NS16550 will not be a memory mapped device. This option - must be selected at SoC/board level if needed. - -config UART_NS16550_SIMULT_ACCESS - bool - help - When enabled, NS16550 supports IO, MMIO, PCIe UART devices simultaneously. - For io-mapped instances, io-mapped DTS property need to be added in dtsi. - config UART_NS16550_PARENT_INIT_LEVEL bool "Boot level based on parent node" default y if ACPI diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 08bcd4a38c1..b0b7f4e1a26 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -58,6 +58,21 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); #include #endif +/* If any node has property io-mapped set, we need to support IO port + * access in the code and device config struct. + * + * Note that DT_ANY_INST_HAS_PROP_STATUS_OKAY() always returns true + * as io-mapped property is considered always exists and present, + * even if its value is zero. Therefore we cannot use it, and has to + * resort to the follow helper to see if any okay nodes have io-mapped + * as 1. + */ +#define UART_NS16550_DT_PROP_IOMAPPED_HELPER(inst, prop, def) \ + DT_INST_PROP_OR(inst, prop, def) || + +#define UART_NS16550_IOPORT_ENABLED \ + (DT_INST_FOREACH_STATUS_OKAY_VARGS(UART_NS16550_DT_PROP_IOMAPPED_HELPER, io_mapped, 0) 0) + /* register definitions */ #define REG_THR 0x00 /* Transmitter holding reg. */ @@ -249,7 +264,7 @@ struct uart_ns16550_device_config { #if defined(CONFIG_PINCTRL) const struct pinctrl_dev_config *pincfg; #endif -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED bool io_map; #endif #if UART_NS16550_RESET_ENABLED @@ -282,7 +297,7 @@ struct uart_ns16550_dev_data { static void ns16550_outbyte(const struct uart_ns16550_device_config *cfg, uintptr_t port, uint8_t val) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) { sys_out32(val, port); @@ -305,7 +320,7 @@ static void ns16550_outbyte(const struct uart_ns16550_device_config *cfg, static uint8_t ns16550_inbyte(const struct uart_ns16550_device_config *cfg, uintptr_t port) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) { return sys_in32(port); @@ -330,7 +345,7 @@ static uint8_t ns16550_inbyte(const struct uart_ns16550_device_config *cfg, static void ns16550_outword(const struct uart_ns16550_device_config *cfg, uintptr_t port, uint32_t val) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { sys_out32(val, port); } else { @@ -345,7 +360,7 @@ static void ns16550_outword(const struct uart_ns16550_device_config *cfg, static uint32_t ns16550_inword(const struct uart_ns16550_device_config *cfg, uintptr_t port) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { return sys_in32(port); } @@ -365,7 +380,7 @@ static inline uint8_t reg_interval(const struct device *dev) static inline uintptr_t get_port(const struct device *dev) { uintptr_t port; -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED const struct uart_ns16550_device_config *config = dev->config; if (config->io_map) { @@ -658,7 +673,7 @@ static int uart_ns16550_init(const struct device *dev) } else #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) */ { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED /* Map directly from DTS */ if (!dev_cfg->io_map) { #else @@ -1257,30 +1272,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { pcie_irq_enable(dev_cfg->pcie->bdf, irq); \ } -#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT -#define REG_INIT(n) \ - .port = DT_INST_REG_ADDR(n), \ - .io_map = true, -#else -#define REG_INIT_PCIE1(n) -#define REG_INIT_PCIE0(n) DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), - -#define DEV_REG_PORT_IO_1(n) \ - .port = DT_INST_REG_ADDR(n), -#define DEV_REG_PORT_IO_0(n) \ - _CONCAT(REG_INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) -#ifdef CONFIG_UART_NS16550_SIMULT_ACCESS -#define DEV_IO_INIT(n) \ - .io_map = DT_INST_PROP(n, io_mapped), -#else -#define DEV_IO_INIT(n) -#endif - -#define REG_INIT(n) \ - _CONCAT(DEV_REG_PORT_IO_, DT_INST_PROP(n, io_mapped))(n) \ - DEV_IO_INIT(n) -#endif - #ifdef CONFIG_UART_INTERRUPT_DRIVEN #define DEV_CONFIG_IRQ_FUNC_INIT(n) \ .irq_config_func = irq_config_func##n, @@ -1316,7 +1307,13 @@ static const struct uart_driver_api uart_ns16550_driver_api = { IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ (PINCTRL_DT_INST_DEFINE(n))); \ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ - REG_INIT(n) \ + COND_CODE_0(DT_INST_ON_BUS(n, pcie), \ + (COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.port = DT_INST_REG_ADDR(n),), \ + (DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),))), \ + ()) \ + IF_ENABLED(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.io_map = true,)) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, clock_frequency), ( \ .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ .clock_dev = NULL, \ diff --git a/dts/arc/synopsys/arc_iot.dtsi b/dts/arc/synopsys/arc_iot.dtsi index 1e8a67d443e..7d04321e0ee 100644 --- a/dts/arc/synopsys/arc_iot.dtsi +++ b/dts/arc/synopsys/arc_iot.dtsi @@ -76,6 +76,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014000 0x100>; + io-mapped; interrupts = <86 0>; interrupt-parent = <&intc>; dlf = <0x01>; @@ -86,6 +87,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014100 0x100>; + io-mapped; interrupts = <87 0>; interrupt-parent = <&intc>; reg-shift = <2>; @@ -96,6 +98,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014200 0x1000>; + io-mapped; interrupts = <88 0>; interrupt-parent = <&intc>; reg-shift = <2>; @@ -106,6 +109,7 @@ compatible = "ns16550"; clock-frequency = <144000000>; reg = <0x80014300 0x100>; + io-mapped; interrupts = <89 0>; interrupt-parent = <&intc>; reg-shift = <2>; diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index b0cca7e5200..43f552609a4 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -239,6 +239,7 @@ uart0_legacy: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/atom.dtsi b/dts/x86/intel/atom.dtsi index fe8340163ba..f1aee1502df 100644 --- a/dts/x86/intel/atom.dtsi +++ b/dts/x86/intel/atom.dtsi @@ -49,6 +49,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; @@ -59,6 +60,7 @@ uart1: uart@2f8 { compatible = "ns16550"; reg = <0x000002f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/ia32.dtsi b/dts/x86/intel/ia32.dtsi index 6058fff6123..9d1715aa840 100644 --- a/dts/x86/intel/ia32.dtsi +++ b/dts/x86/intel/ia32.dtsi @@ -51,6 +51,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; @@ -61,6 +62,7 @@ uart1: uart@2f8 { compatible = "ns16550"; reg = <0x000002f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index 91a6d933260..bc3c59c2159 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -373,6 +373,7 @@ uart_ec_0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/soc/arc/snps_arc_iot/Kconfig.defconfig b/soc/arc/snps_arc_iot/Kconfig.defconfig index 8abaa3382d5..202697a7cf9 100644 --- a/soc/arc/snps_arc_iot/Kconfig.defconfig +++ b/soc/arc/snps_arc_iot/Kconfig.defconfig @@ -34,7 +34,4 @@ config HARVARD config ARC_FIRQ default y -config UART_NS16550_ACCESS_IOPORT - default y - endif # ARC_IOT diff --git a/soc/x86/atom/Kconfig.defconfig b/soc/x86/atom/Kconfig.defconfig index 2658fa7220b..743b43465f4 100644 --- a/soc/x86/atom/Kconfig.defconfig +++ b/soc/x86/atom/Kconfig.defconfig @@ -11,7 +11,4 @@ config SOC config SYS_CLOCK_HW_CYCLES_PER_SEC default 25000000 if HPET_TIMER -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif diff --git a/soc/x86/ia32/Kconfig.defconfig b/soc/x86/ia32/Kconfig.defconfig index cd6f6f20790..87600183a20 100644 --- a/soc/x86/ia32/Kconfig.defconfig +++ b/soc/x86/ia32/Kconfig.defconfig @@ -11,7 +11,4 @@ config SOC config SYS_CLOCK_HW_CYCLES_PER_SEC default 25000000 if HPET_TIMER -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif diff --git a/soc/x86/raptor_lake/Kconfig.defconfig b/soc/x86/raptor_lake/Kconfig.defconfig index 70abc51438b..f9b14da95d0 100644 --- a/soc/x86/raptor_lake/Kconfig.defconfig +++ b/soc/x86/raptor_lake/Kconfig.defconfig @@ -15,7 +15,4 @@ config X86_DYNAMIC_IRQ_STUBS default 16 depends on DYNAMIC_INTERRUPTS -config UART_NS16550_SIMULT_ACCESS - default y if UART_NS16550 - endif # SOC_RAPTOR_LAKE From 3374e81438204d3585176718114ad92c87e43d17 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 21 Sep 2023 17:56:53 -0700 Subject: [PATCH 1065/4498] uart: ns16550: separate IO/MMIO and PCIe init macros This separates the DT device init macros into two: one for UART accessed via IO port or MMIO, the other for PCIe UART. All the conditions needed to setup the device structs are getting complicated. Hopefully separating them would make them easier to decode, and to avoid the conditions having too many levels. Signed-off-by: Daniel Leung --- drivers/serial/uart_ns16550.c | 104 +++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index b0b7f4e1a26..c3f74b30dd5 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1242,7 +1242,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { /* IO-port or MMIO based UART */ #define UART_NS16550_IRQ_CONFIG(n) \ - static void irq_config_func##n(const struct device *dev) \ + static void uart_ns16550_irq_config_func##n(const struct device *dev) \ { \ ARG_UNUSED(dev); \ IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ @@ -1253,7 +1253,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { /* PCI(e) with auto IRQ detection */ #define UART_NS16550_IRQ_CONFIG_PCIE(n) \ - static void irq_config_func##n(const struct device *dev) \ + static void uart_ns16550_irq_config_func##n(const struct device *dev) \ { \ BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \ "Only runtime IRQ configuration is supported"); \ @@ -1274,46 +1274,30 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #ifdef CONFIG_UART_INTERRUPT_DRIVEN #define DEV_CONFIG_IRQ_FUNC_INIT(n) \ - .irq_config_func = irq_config_func##n, + .irq_config_func = uart_ns16550_irq_config_func##n, #define UART_NS16550_IRQ_FUNC_DECLARE(n) \ - static void irq_config_func##n(const struct device *dev); + static void uart_ns16550_irq_config_func##n(const struct device *dev); #define UART_NS16550_IRQ_FUNC_DEFINE(n) \ - COND_CODE_1(DT_INST_ON_BUS(n, pcie), \ - (UART_NS16550_IRQ_CONFIG_PCIE(n)), \ - (UART_NS16550_IRQ_CONFIG(n))) + UART_NS16550_IRQ_CONFIG(n) + +#define DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) \ + .irq_config_func = uart_ns16550_irq_config_func##n, +#define UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n) \ + static void uart_ns16550_irq_config_func##n(const struct device *dev); +#define UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n) \ + UART_NS16550_IRQ_CONFIG_PCIE(n) #else /* !CONFIG_UART_INTERRUPT_DRIVEN */ #define DEV_CONFIG_IRQ_FUNC_INIT(n) #define UART_NS16550_IRQ_FUNC_DECLARE(n) #define UART_NS16550_IRQ_FUNC_DEFINE(n) -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ - -#define DEV_CONFIG_PCIE_INIT(n) \ - COND_CODE_1(DT_INST_ON_BUS(n, pcie), (DEVICE_PCIE_INST_INIT(n, pcie)), ()) - -#define DEV_PCIE_DECLARE(n) \ - COND_CODE_1(DT_INST_ON_BUS(n, pcie), (DEVICE_PCIE_INST_DECLARE(n)), ()) -#ifdef CONFIG_UART_NS16550_PARENT_INIT_LEVEL -#define BOOT_LEVEL(n) \ - COND_CODE_1(DT_INST_ON_BUS(n, pcie), (POST_KERNEL), (PRE_KERNEL_1)) -#else -#define BOOT_LEVEL(n) PRE_KERNEL_1 -#endif +#define DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) +#define UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n) +#define UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define UART_NS16550_DEVICE_INIT(n) \ - UART_NS16550_IRQ_FUNC_DECLARE(n); \ - DEV_PCIE_DECLARE(n); \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ - (PINCTRL_DT_INST_DEFINE(n))); \ - static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ - COND_CODE_0(DT_INST_ON_BUS(n, pcie), \ - (COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \ - (.port = DT_INST_REG_ADDR(n),), \ - (DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),))), \ - ()) \ - IF_ENABLED(DT_INST_PROP_OR(n, io_mapped, 0), \ - (.io_map = true,)) \ +#define UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, clock_frequency), ( \ .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ .clock_dev = NULL, \ @@ -1325,17 +1309,15 @@ static const struct uart_driver_api uart_ns16550_driver_api = { 0, clocks, clkid), \ ) \ ) \ - DEV_CONFIG_IRQ_FUNC_INIT(n) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pcp), \ (.pcp = DT_INST_PROP_OR(n, pcp, 0),)) \ .reg_interval = (1 << DT_INST_PROP(n, reg_shift)), \ - DEV_CONFIG_PCIE_INIT(n) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ (.pincfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(n)),)) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, resets), \ - (.reset_spec = RESET_DT_SPEC_INST_GET(n),)) \ - }; \ - static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \ + (.reset_spec = RESET_DT_SPEC_INST_GET(n),)) + +#define UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \ .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \ .uart_config.parity = UART_CFG_PARITY_NONE, \ .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ @@ -1345,12 +1327,54 @@ static const struct uart_driver_api uart_ns16550_driver_api = { (UART_CFG_FLOW_CTRL_RTS_CTS), \ (UART_CFG_FLOW_CTRL_NONE)), \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, dlf), \ - (.dlf = DT_INST_PROP_OR(n, dlf, 0),)) \ + (.dlf = DT_INST_PROP_OR(n, dlf, 0),)) + +#define UART_NS16550_DEVICE_IO_MMIO_INIT(n) \ + UART_NS16550_IRQ_FUNC_DECLARE(n); \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ + (PINCTRL_DT_INST_DEFINE(n))); \ + static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ + COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.port = DT_INST_REG_ADDR(n),), \ + (DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),)) \ + IF_ENABLED(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.io_map = true,)) \ + UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \ + DEV_CONFIG_IRQ_FUNC_INIT(n) \ + }; \ + static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \ + UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \ }; \ DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \ &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \ - BOOT_LEVEL(n), CONFIG_SERIAL_INIT_PRIORITY, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ &uart_ns16550_driver_api); \ UART_NS16550_IRQ_FUNC_DEFINE(n) +#define UART_NS16550_DEVICE_PCIE_INIT(n) \ + UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n); \ + DEVICE_PCIE_INST_DECLARE(n); \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ + (PINCTRL_DT_INST_DEFINE(n))); \ + static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ + UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \ + DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) \ + DEVICE_PCIE_INST_INIT(n, pcie) \ + }; \ + static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \ + UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \ + }; \ + DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \ + &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \ + COND_CODE_1(CONFIG_UART_NS16550_PARENT_INIT_LEVEL, \ + (POST_KERNEL), (PRE_KERNEL_1)), \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_ns16550_driver_api); \ + UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n) + +#define UART_NS16550_DEVICE_INIT(n) \ + COND_CODE_1(DT_INST_ON_BUS(n, pcie), \ + (UART_NS16550_DEVICE_PCIE_INIT(n)), \ + (UART_NS16550_DEVICE_IO_MMIO_INIT(n))) + DT_INST_FOREACH_STATUS_OKAY(UART_NS16550_DEVICE_INIT) From c1e488c2edb349c38876cbe4a5e32245a68344e8 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 21 Sep 2023 18:07:29 -0700 Subject: [PATCH 1066/4498] doc: release: 3.5: add a note on UART ns16550 driver changes This adds a note on the changes related to the device initialization macros and removal of two kconfigs. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 5d2e730e5a1..5af4179e317 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -240,6 +240,12 @@ Drivers and Sensors * Added support for Nuvoton NuMaker M46x + * NS16550: Reworked how device initialization macros. + + * CONFIG_UART_NS16550_ACCESS_IOPORT and CONFIG_UART_NS16550_SIMULT_ACCESS + are removed. For UART using IO port access, add "io-mapped" property to + device tree node. + * SPI * Remove npcx spi driver implemented by Flash Interface Unit (FIU) module. From e4fbf769c9cf17be7fd1f653b1e1739975c07b4c Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 26 Sep 2023 13:50:36 +0800 Subject: [PATCH 1067/4498] kernel: mmu: fix compilation error when base addr is 0 When these base addresses are defined to be zero, the assertions test will be comparing an unsigned int against zero which result in compilation warning, and will be raised to error in Twister Fix them by conditional compilation Signed-off-by: Yong Cong Sin --- include/zephyr/sys/mem_manage.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/mem_manage.h b/include/zephyr/sys/mem_manage.h index 3f0c0f4b5fd..1dfbabcc3b0 100644 --- a/include/zephyr/sys/mem_manage.h +++ b/include/zephyr/sys/mem_manage.h @@ -149,13 +149,19 @@ static inline uintptr_t z_mem_phys_addr(void *virt) uintptr_t addr = (uintptr_t)virt; #ifdef CONFIG_MMU - __ASSERT((addr >= CONFIG_KERNEL_VM_BASE) && + __ASSERT( +#if CONFIG_KERNEL_VM_BASE != 0 + (addr >= CONFIG_KERNEL_VM_BASE) && +#endif (addr < (CONFIG_KERNEL_VM_BASE + (CONFIG_KERNEL_VM_SIZE))), "address %p not in permanent mappings", virt); #else /* Should be identity-mapped */ - __ASSERT((addr >= CONFIG_SRAM_BASE_ADDRESS) && + __ASSERT( +#if CONFIG_SRAM_BASE_ADDRESS != 0 + (addr >= CONFIG_SRAM_BASE_ADDRESS) && +#endif (addr < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL))), "physical address 0x%lx not in RAM", @@ -172,7 +178,10 @@ static inline uintptr_t z_mem_phys_addr(void *virt) /* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */ static inline void *z_mem_virt_addr(uintptr_t phys) { - __ASSERT((phys >= CONFIG_SRAM_BASE_ADDRESS) && + __ASSERT( +#if CONFIG_SRAM_BASE_ADDRESS != 0 + (phys >= CONFIG_SRAM_BASE_ADDRESS) && +#endif (phys < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL))), "physical address 0x%lx not in RAM", (unsigned long)phys); From b49d0addc5c749b7e401256ff311efc7cb41dbba Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 26 Sep 2023 13:51:58 +0800 Subject: [PATCH 1068/4498] soc: ti_k3: guard the soc header Add macro guard to the soc header to prevent multiple inclusion Signed-off-by: Yong Cong Sin --- soc/arm/ti_k3/am62x_m4/soc.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/arm/ti_k3/am62x_m4/soc.h b/soc/arm/ti_k3/am62x_m4/soc.h index 089479dc6fd..01ff4b07080 100644 --- a/soc/arm/ti_k3/am62x_m4/soc.h +++ b/soc/arm/ti_k3/am62x_m4/soc.h @@ -4,4 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __SOC_H_ +#define __SOC_H_ + #include + +#endif /* __SOC_H */ From 3300b31de80e0c1c63d350c908d282fd1c7049b3 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 26 Sep 2023 13:55:51 +0800 Subject: [PATCH 1069/4498] boards: ti_k3: prevent header dependencies These headers are using things like `uint32_t` & devicetree macros, so they should include the `devicetree.h` & `types.h`. Otherwise they depend on the parent file to have those headers included before they are included. Signed-off-by: Yong Cong Sin --- soc/arm/ti_k3/pinctrl_soc.h | 3 +++ soc/arm64/ti_k3/pinctrl_soc.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/soc/arm/ti_k3/pinctrl_soc.h b/soc/arm/ti_k3/pinctrl_soc.h index fb9fcfa5a7e..d85797bc2b2 100644 --- a/soc/arm/ti_k3/pinctrl_soc.h +++ b/soc/arm/ti_k3/pinctrl_soc.h @@ -7,6 +7,9 @@ #ifndef ZEPHYR_SOC_ARM_TI_K3_PINCTRL_SOC_H_ #define ZEPHYR_SOC_ARM_TI_K3_PINCTRL_SOC_H_ +#include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/soc/arm64/ti_k3/pinctrl_soc.h b/soc/arm64/ti_k3/pinctrl_soc.h index 0328f52b390..055215db7f2 100644 --- a/soc/arm64/ti_k3/pinctrl_soc.h +++ b/soc/arm64/ti_k3/pinctrl_soc.h @@ -7,6 +7,9 @@ #ifndef ZEPHYR_SOC_ARM64_TI_K3_PINCTRL_SOC_H_ #define ZEPHYR_SOC_ARM64_TI_K3_PINCTRL_SOC_H_ +#include +#include + #ifdef __cplusplus extern "C" { #endif From cb4fb765f08ce50aafa49e185e9177f08ae388d2 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 26 Sep 2023 08:57:09 +0200 Subject: [PATCH 1070/4498] net: if: Add ASSERT in net_if_ipv4/6_select_src_addr Add an assert for the destination address provided to find the best source address. Signed-off-by: Pieter De Gendt --- subsys/net/ip/net_if.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 4aaccecd2be..09e91e2bdcb 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -2864,6 +2864,8 @@ const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *dst_iface, const struct in6_addr *src = NULL; uint8_t best_match = 0U; + NET_ASSERT(dst); + if (!net_ipv6_is_ll_addr(dst) && !net_ipv6_is_addr_mcast_link(dst)) { /* If caller has supplied interface, then use that */ if (dst_iface) { @@ -3405,6 +3407,8 @@ const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *dst_iface, const struct in_addr *src = NULL; uint8_t best_match = 0U; + NET_ASSERT(dst); + if (!net_ipv4_is_ll_addr(dst)) { /* If caller has supplied interface, then use that */ From f3067f2364b2051990575e2dc849d02b391b518d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 2 Jun 2023 19:40:24 +0000 Subject: [PATCH 1071/4498] mgmt/MCUmgr/grp/img: Add support for DirectXIP with revert The commit adds support for uploading image to board with MCUboot configured with DirectXIP with revert. It allows to set uploaded image either for test or as permanent boot application, until newer image gets confirmed. Note that in DirectXIP with revert MCUboot will remove image that has not been set for test nor confirmed and MCUmgr does not set either mode unless image has the mode set within uploaded binary. The commit adds Kconfig option CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT that enabled the new mode of operation within MCUmgr. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 24 +++ .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 201 ++++++++++++++---- 2 files changed, 185 insertions(+), 40 deletions(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 0bb47d8854c..5f83098a577 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -176,6 +176,21 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER is also selected that enables comparison of build number. +config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT + bool "MCUboot has been configured for DirectXIP with revert" + select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP + help + MCUboot expects slot0_partition and slot1_partition to exist in DT. + In this mode MCUboot will boot the application with the higher version + from either slot, as long as it has been marked to be boot + next time for test or permanently. In case when application is marked + for test it needs to confirm itself, on the first boot, or it will + be removed and MCUboot will revert to booting previously approved + application. + This mode does not allow freely switching between application + versions, as, once higher version application is approved, it is + not possible to select lower version for boot. + endchoice # MCUBOOT_BOOTLOADER_MODE endif # BOOTLOADER_MCUBOOT @@ -208,4 +223,13 @@ config BOOT_IMAGE_ACCESS_HOOKS It is up to the application project to add source file which implements hooks to the build. +if MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT + +config MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP + bool + help + Adds support for setting for test and confirming images + when bootloader is in DirectXIP-revert mode. +endif + endif # MCUBOOT_BOOTUTIL_LIB diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index a782acb92ee..0968694c614 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -55,6 +55,14 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); #define REPORT_SLOT_PENDING BIT(1) #define REPORT_SLOT_CONFIRMED BIT(2) #define REPORT_SLOT_PERMANENT BIT(3) + +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) +#define DIRECT_XIP_BOOT_UNSET 0 +#define DIRECT_XIP_BOOT_ONCE 1 +#define DIRECT_XIP_BOOT_REVERT 2 +#define DIRECT_XIP_BOOT_FOREVER 3 +#endif + /** * Collects information about the specified image slot. */ @@ -139,7 +147,8 @@ img_mgmt_state_flags(int query_slot) } #endif -#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP +#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \ + !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) { const int active_slot = img_mgmt_active_slot(image); @@ -188,27 +197,115 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) return slot; } #else + +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) + +static int read_directxip_state(int slot) +{ + struct boot_swap_state bss; + int fa_id = img_mgmt_flash_area_id(slot); + const struct flash_area *fa; + int rc = 0; + + __ASSERT(fa_id != -1, "Could not map slot to area ID"); + + rc = flash_area_open(fa_id, &fa); + if (rc < 0) { + return rc; + } + rc = boot_read_swap_state(fa, &bss); + flash_area_close(fa); + if (rc != 0) { + LOG_ERR("Failed to read state of slot %d with error %d", slot, rc); + return -1; + } + + if (bss.magic == BOOT_MAGIC_GOOD) { + if (bss.image_ok == BOOT_FLAG_SET) { + return DIRECT_XIP_BOOT_FOREVER; + } else if (bss.copy_done == BOOT_FLAG_SET) { + return DIRECT_XIP_BOOT_REVERT; + } + return DIRECT_XIP_BOOT_ONCE; + } + return DIRECT_XIP_BOOT_UNSET; +} +#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ + int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) { struct image_version aver; struct image_version over; int active_slot = img_mgmt_active_slot(image); int other_slot = img_mgmt_get_opposite_slot(active_slot); +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) + int active_slot_state; + int other_slot_state; +#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ + enum img_mgmt_next_boot_type lt = NEXT_BOOT_TYPE_NORMAL; + int return_slot = active_slot; - if (type != NULL) { - *type = NEXT_BOOT_TYPE_NORMAL; - } int rcs = img_mgmt_read_info(other_slot, &over, NULL, NULL); int rca = img_mgmt_read_info(active_slot, &aver, NULL, NULL); +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) + active_slot_state = read_directxip_state(active_slot); + other_slot_state = read_directxip_state(other_slot); + if (rca != 0 || + (rcs != 0 && rcs != IMG_MGMT_ERR_NO_IMAGE)) { + /* We do not really know what will happen, as we can not + * read states from bootloader. + */ + LOG_ERR("img_mgmt_read_info_failed rca = %d, rcs = %d", + rca, rcs); + goto out; + } + if (other_slot_state < 0 || active_slot_state < 0) { + LOG_ERR("Slot state read failed with status: active %d, other %d", + active_slot_state, other_slot_state); + /* We do not really know what will happen, as we can not + * read states from bootloader. + */ + goto out; + } + + /* There is not other image, the active one will boot next time */ + if (rcs == IMG_MGMT_ERR_NO_IMAGE) { + goto out; + } + + if (active_slot_state == DIRECT_XIP_BOOT_REVERT) { + lt = NEXT_BOOT_TYPE_REVERT; + return_slot = other_slot; + } else if (other_slot_state == DIRECT_XIP_BOOT_UNSET) { + if (active_slot_state == DIRECT_XIP_BOOT_ONCE) { + lt = NEXT_BOOT_TYPE_TEST; + } + } else if (img_mgmt_vercmp(&aver, &over) < 0) { + if (other_slot_state == DIRECT_XIP_BOOT_FOREVER) { + return_slot = other_slot; + } else if (other_slot_state == DIRECT_XIP_BOOT_ONCE) { + lt = NEXT_BOOT_TYPE_TEST; + return_slot = other_slot; + } + } +#else if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &over) < 0) { - return other_slot; + return_slot = other_slot; } +#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ - return active_slot; +out: + if (type != NULL) { + *type = lt; + } + + return return_slot; } -#endif +#endif /* !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \ + * !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) + */ /** @@ -422,11 +519,53 @@ img_mgmt_state_read(struct smp_streamer *ctxt) return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } -int img_mgmt_set_next_boot_slot(int slot, bool confirm) +static int img_mgmt_set_next_boot_slot_common(int slot, int active_slot, bool confirm) { const struct flash_area *fa; int area_id = img_mgmt_flash_area_id(slot); int rc = 0; + + if (flash_area_open(area_id, &fa) != 0) { + return IMG_MGMT_ERR_FLASH_OPEN_FAILED; + } + + rc = boot_set_next(fa, slot == active_slot, confirm); + if (rc != 0) { + /* Failed to set next slot for boot as desired */ + LOG_ERR("Faled boot_set_next with code %d, for slot %d," + " with active slot %d and confirm %d", + rc, slot, active_slot, confirm); + + /* Translate from boot util error code to IMG mgmt group error code */ + if (rc == BOOT_EFLASH) { + rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED; + } else if (rc == BOOT_EBADVECT) { + rc = IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE; + } else if (rc == BOOT_EBADIMAGE) { + rc = IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC; + } else { + rc = IMG_MGMT_ERR_UNKNOWN; + } + } + flash_area_close(fa); + +#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) + if (rc == 0 && slot == active_slot && confirm) { + int32_t err_rc; + uint16_t err_group; + + /* Confirm event is only sent for active slot */ + (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0, &err_rc, + &err_group); + } +#endif + + return rc; +} + +#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT +int img_mgmt_set_next_boot_slot(int slot, bool confirm) +{ /* image the requested slot is defined within */ int image = img_mgmt_slot_to_image(slot); /* active_slot is slot that is considered active/primary/executing @@ -498,43 +637,25 @@ int img_mgmt_set_next_boot_slot(int slot, bool confirm) /* Allow confirming slot == active_slot */ } - if (flash_area_open(area_id, &fa) != 0) { - return IMG_MGMT_ERR_FLASH_OPEN_FAILED; - } - - rc = boot_set_next(fa, slot == active_slot, confirm); - if (rc != 0) { - /* Failed to set next slot for boot as desired */ - LOG_ERR("Faled boot_set_next with code %d, for slot %d," - " with active slot %d and confirm %d", - rc, slot, active_slot, confirm); - - /* Translate from boot util error code to IMG mgmt group error code */ - if (rc == BOOT_EFLASH) { - rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED; - } else if (rc == BOOT_EBADVECT) { - rc = IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE; - } else if (rc == BOOT_EBADIMAGE) { - rc = IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC; - } else { - rc = IMG_MGMT_ERR_UNKNOWN; - } - } - flash_area_close(fa); + return img_mgmt_set_next_boot_slot_common(slot, active_slot, confirm); +} +#else +int img_mgmt_set_next_boot_slot(int slot, bool confirm) +{ + int active_image = img_mgmt_active_image(); + int active_slot = img_mgmt_active_slot(active_image); -#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) - if (slot == active_slot && confirm) { - int32_t err_rc; - uint16_t err_group; + LOG_DBG("(%d, %s)", slot, confirm ? "confirm" : "test"); + LOG_DBG("aimg = %d, aslot = %d, slot = %d", + active_image, active_slot, slot); - /* Confirm event is only sent for active slot */ - (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0, &err_rc, - &err_group); + if (slot == active_slot && !confirm) { + return IMG_MGMT_ERR_IMAGE_SETTING_TEST_TO_ACTIVE_DENIED; } -#endif - return rc; + return img_mgmt_set_next_boot_slot_common(slot, active_slot, confirm); } +#endif /** * Command handler: image state write From 11ab88f10c83e2bc5ed4120f19a6babf85ea2572 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 21 Jun 2023 11:42:05 +0000 Subject: [PATCH 1072/4498] samples/mcumgr/smp_svr: Build for DirectXIP with revert Adds sample build for CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT=y Signed-off-by: Dominik Ermel --- samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index ed7ffe8f33e..a13270e5845 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -43,6 +43,19 @@ tests: - mg100 integration_platforms: - nrf52840dk_nrf52840 + # In mcuboot_flags test overlay-serial.conf is used for convenience as it is the simplest + # transport. Transport does not affect flags so it does not really matter which is selected, + # flags should affect any transport the same way. + sample.mcumgr.smp_svr.mcuboot_flags.direct_xip_withrevert: + extra_args: OVERLAY_CONFIG="overlay-serial.conf" + extra_configs: + - CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT=y + platform_allow: + - nrf52840dk_nrf52840 + - pinnacle_100_dvk + - mg100 + integration_platforms: + - nrf52840dk_nrf52840 sample.mcumgr.smp_svr.serial-console: extra_args: OVERLAY_CONFIG="overlay-serial-console.conf" platform_allow: From 54f848cfaa4ec5f46e61790f03b95c00ca107b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Tue, 26 Sep 2023 12:42:42 +0200 Subject: [PATCH 1073/4498] boards: nrf9160dk_nrf52840: Add missing inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This code uses the `NRF_DT_GPIOS_TO_PSEL` macro, so it should include `` explicitly and not rely on the header being included by some other one. Signed-off-by: Andrzej Głąbek --- boards/arm/nrf9160dk_nrf52840/board.c | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/nrf9160dk_nrf52840/board.c b/boards/arm/nrf9160dk_nrf52840/board.c index cdf00f8f3dd..adf137df196 100644 --- a/boards/arm/nrf9160dk_nrf52840/board.c +++ b/boards/arm/nrf9160dk_nrf52840/board.c @@ -9,6 +9,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_NRF9160DK_LOG_LEVEL); From ad53863d1a1059daa371ca486225468f8f415063 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 16 Aug 2023 09:43:14 +0200 Subject: [PATCH 1074/4498] counter: stm32 rtc: improve assigning configs The config values have been hardcoded as magic values. Introduce universal calculation based on the DTS entries. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/counter_ll_stm32_rtc.c | 37 ++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index 8ad9bd0d619..68bbbc92fcf 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -61,6 +61,23 @@ LOG_MODULE_REGISTER(counter_rtc_stm32, CONFIG_COUNTER_LOG_LEVEL); #define COUNTER_NO_DATE #endif +#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI +/* LSI */ +#define RTCCLK_FREQ STM32_LSI_FREQ +#else +/* LSE */ +#define RTCCLK_FREQ STM32_LSE_FREQ +#endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI */ + +#if !defined(CONFIG_SOC_SERIES_STM32F1X) +#define RTC_ASYNCPRE BIT_MASK(7) +#else /* CONFIG_SOC_SERIES_STM32F1X */ +#define RTC_ASYNCPRE (RTCCLK_FREQ - 1) +#endif /* CONFIG_SOC_SERIES_STM32F1X */ + +/* Adjust the second sync prescaler to get 1Hz on ck_spre */ +#define RTC_SYNCPRE ((RTCCLK_FREQ / (1 + RTC_ASYNCPRE)) - 1) + struct rtc_stm32_config { struct counter_config_info counter_info; LL_RTC_InitTypeDef ll_rtc_config; @@ -477,30 +494,16 @@ static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); static const struct rtc_stm32_config rtc_config = { .counter_info = { .max_top_value = UINT32_MAX, - .freq = 1, + .freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)), .flags = COUNTER_CONFIG_INFO_COUNT_UP, .channels = 1, }, .ll_rtc_config = { + .AsynchPrescaler = RTC_ASYNCPRE, #if !defined(CONFIG_SOC_SERIES_STM32F1X) .HourFormat = LL_RTC_HOURFORMAT_24HOUR, -#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI - /* prescaler values for LSI @ 32 KHz */ - .AsynchPrescaler = 0x7F, - .SynchPrescaler = 0x00F9, -#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ - /* prescaler values for LSE @ 32768 Hz */ - .AsynchPrescaler = 0x7F, - .SynchPrescaler = 0x00FF, -#endif + .SynchPrescaler = RTC_SYNCPRE, #else /* CONFIG_SOC_SERIES_STM32F1X */ -#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI - /* prescaler values for LSI @ 40 KHz */ - .AsynchPrescaler = 0x9C3F, -#else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */ - /* prescaler values for LSE @ 32768 Hz */ - .AsynchPrescaler = 0x7FFF, -#endif .OutPutSource = LL_RTC_CALIB_OUTPUT_NONE, #endif /* CONFIG_SOC_SERIES_STM32F1X */ }, From 16370a259a3642273b8cdc3faaf7d8e2b9e772c2 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 16 Aug 2023 10:12:37 +0200 Subject: [PATCH 1075/4498] counter: stm32 rtc: improve reading registers Synchronize reading two separate registers. In some edge cases the read registers could point different dates. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/counter_ll_stm32_rtc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index 68bbbc92fcf..681d3a6d143 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -192,10 +192,17 @@ static uint32_t rtc_stm32_read(const struct device *dev) #endif ARG_UNUSED(dev); - /* Read time and date registers */ - rtc_time = LL_RTC_TIME_Get(RTC); + /* Read time and date registers. Make sure value of the previous register + * hasn't been changed while reading the next one. + */ #if !defined(COUNTER_NO_DATE) - rtc_date = LL_RTC_DATE_Get(RTC); + do { + rtc_date = LL_RTC_DATE_Get(RTC); + rtc_time = LL_RTC_TIME_Get(RTC); + + } while (rtc_date != LL_RTC_DATE_Get(RTC)); +#else + rtc_time = LL_RTC_TIME_Get(RTC); #endif #if !defined(COUNTER_NO_DATE) From c7d779f6e29d533f6fb7bfbfba4518dab1442c0e Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 26 Sep 2023 08:56:09 +0200 Subject: [PATCH 1076/4498] counter: stm32 rtc: fix indentations Fix indentations of the API definition. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/counter_ll_stm32_rtc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index 681d3a6d143..19cffe1b33f 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -519,14 +519,14 @@ static const struct rtc_stm32_config rtc_config = { static const struct counter_driver_api rtc_stm32_driver_api = { - .start = rtc_stm32_start, - .stop = rtc_stm32_stop, - .get_value = rtc_stm32_get_value, - .set_alarm = rtc_stm32_set_alarm, - .cancel_alarm = rtc_stm32_cancel_alarm, - .set_top_value = rtc_stm32_set_top_value, - .get_pending_int = rtc_stm32_get_pending_int, - .get_top_value = rtc_stm32_get_top_value, + .start = rtc_stm32_start, + .stop = rtc_stm32_stop, + .get_value = rtc_stm32_get_value, + .set_alarm = rtc_stm32_set_alarm, + .cancel_alarm = rtc_stm32_cancel_alarm, + .set_top_value = rtc_stm32_set_top_value, + .get_pending_int = rtc_stm32_get_pending_int, + .get_top_value = rtc_stm32_get_top_value, }; DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, From 322f7980c5b6bb44df2058af05d7624f02ee7f6f Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 26 Sep 2023 08:56:26 +0200 Subject: [PATCH 1077/4498] counter: stm32 rtc: simplify calculation RTC drivers uses only seconds, so transition to microseconds is necessary. Change way of calculation tick<->time to avoid unnecessary conversations. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/counter_ll_stm32_rtc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index 19cffe1b33f..19be15a87e1 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -225,7 +225,7 @@ static uint32_t rtc_stm32_read(const struct device *dev) ts -= T_TIME_OFFSET; __ASSERT(sizeof(time_t) == 8, "unexpected time_t definition"); - ticks = counter_us_to_ticks(dev, ts * USEC_PER_SEC); + ticks = ts * counter_get_frequency(dev); #else ticks = rtc_time; #endif @@ -271,10 +271,9 @@ static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id, * that tick+1 event occurs before alarm setting is finished. */ ticks += now + 1; - alarm_val = (time_t)(counter_ticks_to_us(dev, ticks) / USEC_PER_SEC) - + T_TIME_OFFSET; + alarm_val = (time_t)(ticks / counter_get_frequency(dev)) + T_TIME_OFFSET; } else { - alarm_val = (time_t)(counter_ticks_to_us(dev, ticks) / USEC_PER_SEC); + alarm_val = (time_t)(ticks / counter_get_frequency(dev)); } #else if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) { From 49f9aa7d12873ebb8930cd37bddbc4e453be300f Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 16 Aug 2023 11:45:55 +0200 Subject: [PATCH 1078/4498] counter: stm32 rtc: handle sub second registers Add support for using the sub second registers. It allows reading and setting alarm with the sub second tick resolution. The RTC module is configured to get as high frequency as possible, which equals the source clock (RTCCLK) divided by 2. To get such frequency, the asynchronous prescaler is set to 1. According to RM, setting the asynchronous prescaler to a high value minimize consumption, so the change increase the power consumption. Use a config to enable the sub second support. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/Kconfig.stm32_rtc | 9 ++ drivers/counter/counter_ll_stm32_rtc.c | 129 ++++++++++++++++-- .../counter/counter_basic_api/testcase.yaml | 9 ++ 3 files changed, 137 insertions(+), 10 deletions(-) diff --git a/drivers/counter/Kconfig.stm32_rtc b/drivers/counter/Kconfig.stm32_rtc index 03e72babc60..0e1268557df 100644 --- a/drivers/counter/Kconfig.stm32_rtc +++ b/drivers/counter/Kconfig.stm32_rtc @@ -44,4 +44,13 @@ config COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS help Keep the counter value after each reset. +config COUNTER_RTC_STM32_SUBSECONDS + bool "Use the subseconds as a basic tick." + depends on !SOC_SERIES_STM32F1X + help + Use the subseconds as the basic time tick. It increases resolution + of the counter. The frequency of the time is RTC Source Clock divided + by 2. It is the clock after the first asynchronous prescaler. + The config increases power consumption. + endif # COUNTER_RTC_STM32 diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index 19be15a87e1..efb7cf61f8b 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -70,7 +70,12 @@ LOG_MODULE_REGISTER(counter_rtc_stm32, CONFIG_COUNTER_LOG_LEVEL); #endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI */ #if !defined(CONFIG_SOC_SERIES_STM32F1X) +#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS #define RTC_ASYNCPRE BIT_MASK(7) +#else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ +/* Get the highest possible clock for the subsecond register */ +#define RTC_ASYNCPRE 1 +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ #else /* CONFIG_SOC_SERIES_STM32F1X */ #define RTC_ASYNCPRE (RTCCLK_FREQ - 1) #endif /* CONFIG_SOC_SERIES_STM32F1X */ @@ -78,6 +83,12 @@ LOG_MODULE_REGISTER(counter_rtc_stm32, CONFIG_COUNTER_LOG_LEVEL); /* Adjust the second sync prescaler to get 1Hz on ck_spre */ #define RTC_SYNCPRE ((RTCCLK_FREQ / (1 + RTC_ASYNCPRE)) - 1) +#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS +typedef uint32_t tick_t; +#else +typedef uint64_t tick_t; +#endif + struct rtc_stm32_config { struct counter_config_info counter_info; LL_RTC_InitTypeDef ll_rtc_config; @@ -88,6 +99,9 @@ struct rtc_stm32_data { counter_alarm_callback_t callback; uint32_t ticks; void *user_data; +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + bool irq_on_late; +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ }; static inline ErrorStatus ll_func_init_alarm(RTC_TypeDef *rtc, uint32_t format, @@ -136,6 +150,17 @@ static inline void ll_func_disable_interrupt_alarm(RTC_TypeDef *rtc) #endif } +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS +static inline uint32_t ll_func_isenabled_interrupt_alarm(RTC_TypeDef *rtc) +{ +#if defined(CONFIG_SOC_SERIES_STM32F1X) + return LL_RTC_IsEnabledIT_ALR(rtc); +#else + return LL_RTC_IsEnabledIT_ALRA(rtc); +#endif +} +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + static inline void ll_func_enable_alarm(RTC_TypeDef *rtc) { #if defined(CONFIG_SOC_SERIES_STM32F1X) @@ -180,13 +205,16 @@ static int rtc_stm32_stop(const struct device *dev) return 0; } - -static uint32_t rtc_stm32_read(const struct device *dev) +tick_t rtc_stm32_read(const struct device *dev) { #if !defined(COUNTER_NO_DATE) struct tm now = { 0 }; time_t ts; - uint32_t rtc_date, rtc_time, ticks; + uint32_t rtc_date, rtc_time; + tick_t ticks; +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + uint32_t rtc_subseconds; +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ #else uint32_t rtc_time, ticks; #endif @@ -198,7 +226,15 @@ static uint32_t rtc_stm32_read(const struct device *dev) #if !defined(COUNTER_NO_DATE) do { rtc_date = LL_RTC_DATE_Get(RTC); + +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + do { + rtc_time = LL_RTC_TIME_Get(RTC); + rtc_subseconds = LL_RTC_TIME_GetSubSecond(RTC); + } while (rtc_time != LL_RTC_TIME_Get(RTC)); +#else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ rtc_time = LL_RTC_TIME_Get(RTC); +#endif } while (rtc_date != LL_RTC_DATE_Get(RTC)); #else @@ -225,7 +261,16 @@ static uint32_t rtc_stm32_read(const struct device *dev) ts -= T_TIME_OFFSET; __ASSERT(sizeof(time_t) == 8, "unexpected time_t definition"); + ticks = ts * counter_get_frequency(dev); +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + /* The RTC counts up, except for the subsecond register which counts + * down starting from the sync prescaler value. Add already counted + * ticks. + */ + ticks += RTC_SYNCPRE - rtc_subseconds; +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + #else ticks = rtc_time; #endif @@ -234,25 +279,43 @@ static uint32_t rtc_stm32_read(const struct device *dev) } static int rtc_stm32_get_value(const struct device *dev, uint32_t *ticks) +{ + *ticks = (uint32_t)rtc_stm32_read(dev); + return 0; +} + +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS +static int rtc_stm32_get_value_64(const struct device *dev, uint64_t *ticks) { *ticks = rtc_stm32_read(dev); return 0; } +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS +static void rtc_stm32_set_int_pending(void) +{ + NVIC_SetPendingIRQ(DT_INST_IRQN(0)); +} +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg) { #if !defined(COUNTER_NO_DATE) struct tm alarm_tm; - time_t alarm_val; + time_t alarm_val_s; +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + uint32_t alarm_val_ss; +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ #else uint32_t remain; #endif LL_RTC_AlarmTypeDef rtc_alarm; struct rtc_stm32_data *data = dev->data; - uint32_t now = rtc_stm32_read(dev); - uint32_t ticks = alarm_cfg->ticks; + tick_t now = rtc_stm32_read(dev); + tick_t ticks = alarm_cfg->ticks; if (data->callback != NULL) { LOG_DBG("Alarm busy\n"); @@ -271,10 +334,14 @@ static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id, * that tick+1 event occurs before alarm setting is finished. */ ticks += now + 1; - alarm_val = (time_t)(ticks / counter_get_frequency(dev)) + T_TIME_OFFSET; + alarm_val_s = (time_t)(ticks / counter_get_frequency(dev)) + T_TIME_OFFSET; } else { - alarm_val = (time_t)(ticks / counter_get_frequency(dev)); + alarm_val_s = (time_t)(ticks / counter_get_frequency(dev)); } +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + alarm_val_ss = ticks % counter_get_frequency(dev); +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + #else if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) { remain = ticks + now + 1; @@ -289,9 +356,13 @@ static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id, #endif #if !defined(COUNTER_NO_DATE) +#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS LOG_DBG("Set Alarm: %d\n", ticks); +#else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + LOG_DBG("Set Alarm: %llu\n", ticks); +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ - gmtime_r(&alarm_val, &alarm_tm); + gmtime_r(&alarm_val_s, &alarm_tm); /* Apply ALARM_A */ rtc_alarm.AlarmTime.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24; @@ -319,11 +390,34 @@ static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id, } LL_RTC_DisableWriteProtection(RTC); +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + /* Care about all bits of the subsecond register */ + LL_RTC_ALMA_SetSubSecondMask(RTC, 0xF); + LL_RTC_ALMA_SetSubSecond(RTC, RTC_SYNCPRE - alarm_val_ss); +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ ll_func_enable_alarm(RTC); ll_func_clear_alarm_flag(RTC); ll_func_enable_interrupt_alarm(RTC); LL_RTC_EnableWriteProtection(RTC); +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + /* The reference manual says: + * "Each change of the RTC_CR register is taken into account after + * 1 to 2 RTCCLK clock cycles due to clock synchronization." + * It means we need at least two cycles after programming the CR + * register. It is confirmed experimentally. + * + * It should happen only if one tick alarm is requested and a tick + * occurs while processing the function. Trigger the irq manually in + * this case. + */ + now = rtc_stm32_read(dev); + if ((ticks - now < 2) || (now > ticks)) { + data->irq_on_late = 1; + rtc_stm32_set_int_pending(); + } +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + return 0; } @@ -380,13 +474,20 @@ void rtc_stm32_isr(const struct device *dev) uint32_t now = rtc_stm32_read(dev); - if (ll_func_is_active_alarm(RTC) != 0) { + if (ll_func_is_active_alarm(RTC) != 0 +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + || (data->irq_on_late && ll_func_isenabled_interrupt_alarm(RTC)) +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + ) { LL_RTC_DisableWriteProtection(RTC); ll_func_clear_alarm_flag(RTC); ll_func_disable_interrupt_alarm(RTC); ll_func_disable_alarm(RTC); LL_RTC_EnableWriteProtection(RTC); +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + data->irq_on_late = 0; +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ if (alarm_callback != NULL) { data->callback = NULL; @@ -500,7 +601,12 @@ static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0); static const struct rtc_stm32_config rtc_config = { .counter_info = { .max_top_value = UINT32_MAX, +#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + /* freq = 1Hz for not subsec based driver */ .freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)), +#else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ + .freq = RTCCLK_FREQ / (RTC_ASYNCPRE + 1), +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ .flags = COUNTER_CONFIG_INFO_COUNT_UP, .channels = 1, }, @@ -521,6 +627,9 @@ static const struct counter_driver_api rtc_stm32_driver_api = { .start = rtc_stm32_start, .stop = rtc_stm32_stop, .get_value = rtc_stm32_get_value, +#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS + .get_value_64 = rtc_stm32_get_value_64, +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ .set_alarm = rtc_stm32_set_alarm, .cancel_alarm = rtc_stm32_cancel_alarm, .set_top_value = rtc_stm32_set_top_value, diff --git a/tests/drivers/counter/counter_basic_api/testcase.yaml b/tests/drivers/counter/counter_basic_api/testcase.yaml index f31fa8f3af9..6e68f4480f4 100644 --- a/tests/drivers/counter/counter_basic_api/testcase.yaml +++ b/tests/drivers/counter/counter_basic_api/testcase.yaml @@ -18,3 +18,12 @@ tests: - CONFIG_ZERO_LATENCY_IRQS=y extra_args: DTC_OVERLAY_FILE="boards/nrf52840dk_nrf52840.overlay;boards/nrf52840dk_nrf52840_zli.overlay" + drivers.counter.basic_api.stm32_subsec: + tags: + - drivers + - counter + depends_on: counter + platform_allow: nucleo_f429zi + timeout: 600 + extra_configs: + - CONFIG_COUNTER_RTC_STM32_SUBSECONDS=y From 68292b0310a537e456367c43d0dccbf0a4595678 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 26 Sep 2023 08:56:33 +0200 Subject: [PATCH 1079/4498] counter: stm32 rtc: improve readability Split the read function into 2 versions (date and no date) since they don't have common code. It improves readability. Signed-off-by: Dawid Niedzwiecki --- drivers/counter/counter_ll_stm32_rtc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index efb7cf61f8b..bb8a119409b 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -205,9 +205,9 @@ static int rtc_stm32_stop(const struct device *dev) return 0; } +#if !defined(COUNTER_NO_DATE) tick_t rtc_stm32_read(const struct device *dev) { -#if !defined(COUNTER_NO_DATE) struct tm now = { 0 }; time_t ts; uint32_t rtc_date, rtc_time; @@ -215,15 +215,11 @@ tick_t rtc_stm32_read(const struct device *dev) #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS uint32_t rtc_subseconds; #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ -#else - uint32_t rtc_time, ticks; -#endif ARG_UNUSED(dev); /* Read time and date registers. Make sure value of the previous register * hasn't been changed while reading the next one. */ -#if !defined(COUNTER_NO_DATE) do { rtc_date = LL_RTC_DATE_Get(RTC); @@ -237,11 +233,7 @@ tick_t rtc_stm32_read(const struct device *dev) #endif } while (rtc_date != LL_RTC_DATE_Get(RTC)); -#else - rtc_time = LL_RTC_TIME_Get(RTC); -#endif -#if !defined(COUNTER_NO_DATE) /* Convert calendar datetime to UNIX timestamp */ /* RTC start time: 1st, Jan, 2000 */ /* time_t start: 1st, Jan, 1970 */ @@ -271,12 +263,22 @@ tick_t rtc_stm32_read(const struct device *dev) ticks += RTC_SYNCPRE - rtc_subseconds; #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ -#else + return ticks; +} +#else /* defined(COUNTER_NO_DATE) */ +tick_t rtc_stm32_read(const struct device *dev) +{ + uint32_t rtc_time, ticks; + + ARG_UNUSED(dev); + + rtc_time = LL_RTC_TIME_Get(RTC); + ticks = rtc_time; -#endif return ticks; } +#endif /* !defined(COUNTER_NO_DATE) */ static int rtc_stm32_get_value(const struct device *dev, uint32_t *ticks) { From e364a095a61e8bfd9aaca8d9678cc640f7ea22be Mon Sep 17 00:00:00 2001 From: Jatty Andriean Date: Tue, 19 Sep 2023 03:25:34 +0000 Subject: [PATCH 1080/4498] drivers: clock_control: Add PLL fracn for STM32U5 Based on RM0456, each PLL in the STM32U5 has the capability to work either in integer or fractional mode. In this update, the fractional mode can be enabled by setting the fracn value in the device tree. Signed-off-by: Jatty Andriean --- drivers/clock_control/clock_stm32_ll_u5.c | 12 ++++++++++++ dts/bindings/clock/st,stm32u5-pll-clock.yaml | 6 ++++++ .../drivers/clock_control/stm32_clock_control.h | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index e7cc8da677b..52d6bd42d62 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -519,6 +519,10 @@ static int set_up_plls(void) LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER); LL_RCC_PLL1FRACN_Disable(); + if (IS_ENABLED(STM32_PLL_FRACN_ENABLED)) { + LL_RCC_PLL1_SetFRACN(STM32_PLL_FRACN_VALUE); + LL_RCC_PLL1FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL_P_ENABLED)) { LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR); @@ -569,6 +573,10 @@ static int set_up_plls(void) LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER); LL_RCC_PLL2FRACN_Disable(); + if (IS_ENABLED(STM32_PLL2_FRACN_ENABLED)) { + LL_RCC_PLL2_SetFRACN(STM32_PLL2_FRACN_VALUE); + LL_RCC_PLL2FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL2_P_ENABLED)) { LL_RCC_PLL2_SetP(STM32_PLL2_P_DIVISOR); @@ -617,6 +625,10 @@ static int set_up_plls(void) LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER); LL_RCC_PLL3FRACN_Disable(); + if (IS_ENABLED(STM32_PLL3_FRACN_ENABLED)) { + LL_RCC_PLL3_SetFRACN(STM32_PLL3_FRACN_VALUE); + LL_RCC_PLL3FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL3_P_ENABLED)) { LL_RCC_PLL3_SetP(STM32_PLL3_P_DIVISOR); diff --git a/dts/bindings/clock/st,stm32u5-pll-clock.yaml b/dts/bindings/clock/st,stm32u5-pll-clock.yaml index 6185050eac6..241c8acb841 100644 --- a/dts/bindings/clock/st,stm32u5-pll-clock.yaml +++ b/dts/bindings/clock/st,stm32u5-pll-clock.yaml @@ -71,3 +71,9 @@ properties: On PLL1, only division by 1 and even division values are allowed. No restrictions for PLL2 and PLL3 Valid range: 1 - 128 + + fracn: + type: int + description: | + PLLx FRACN value + Valid range: 0 - 8191 diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index c69718f1048..36df690220b 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -143,6 +143,8 @@ #define STM32_PLL_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_q, 1) #define STM32_PLL_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_r) #define STM32_PLL_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_r, 1) +#define STM32_PLL_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), fracn) +#define STM32_PLL_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll), fracn, 1) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f4_plli2s_clock, okay) @@ -172,6 +174,8 @@ #define STM32_PLL2_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_q, 1) #define STM32_PLL2_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_r) #define STM32_PLL2_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_r, 1) +#define STM32_PLL2_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), fracn) +#define STM32_PLL2_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll2), fracn, 1) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7_pll_clock, okay) || \ @@ -185,6 +189,8 @@ #define STM32_PLL3_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_q, 1) #define STM32_PLL3_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_r) #define STM32_PLL3_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_r, 1) +#define STM32_PLL3_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), fracn) +#define STM32_PLL3_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll3), fracn, 1) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f1_pll_clock, okay) From 3eea17c5debf0121f50dd23d98b0ad2ccd394c06 Mon Sep 17 00:00:00 2001 From: Jatty Andriean Date: Tue, 26 Sep 2023 07:57:22 +0000 Subject: [PATCH 1081/4498] tests: drivers: clock_control: Add PLL fracn test Added a test case that generates a 160 MHz system clock using a 16777216 Hz HSE clock and also using a 16 MHz HSI Signed-off-by: Jatty Andriean --- .../boards/pll_hse_fracn_160.overlay | 40 +++++++++++++++++++ .../boards/pll_hsi_fracn_160.overlay | 34 ++++++++++++++++ .../stm32u5_core/testcase.yaml | 6 +++ 3 files changed, 80 insertions(+) create mode 100644 tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hse_fracn_160.overlay create mode 100644 tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hsi_fracn_160.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hse_fracn_160.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hse_fracn_160.overlay new file mode 100644 index 00000000000..014ef48fd7d --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hse_fracn_160.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Jatty Andriean + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after clear_clocks.overlay file. + */ + +/* + * Warning: HSE is not implemented on available boards, hence: + * This configuration is only available for build + */ + +&clk_hse { + status = "okay"; + clock-frequency = <16777216>; +}; + +&pll1 { + div-m = <2>; + mul-n = <19>; + div-p = <1>; + div-q = <1>; + div-r = <1>; + fracn = <602>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hsi_fracn_160.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hsi_fracn_160.overlay new file mode 100644 index 00000000000..ffc339ad184 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_hsi_fracn_160.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Jatty Andriean + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after clear_clocks.overlay file. + */ + +&clk_hsi { + status = "okay"; +}; + +&pll1 { + div-m = <1>; + mul-n = <20>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + fracn = <0>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml index 6443e08f139..7a45d2c5e62 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml @@ -24,3 +24,9 @@ tests: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_160.overlay" # Build only as HSE not implemened on available boards build_only: true + drivers.stm32_clock_configuration.u5.sysclksrc_pll_hse_fracn_160: + extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_fracn_160.overlay" + # Build only as HSE not implemened on available boards + build_only: true + drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_fracn_160: + extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_fracn_160.overlay" From 0e5016e5026fb1f83bd32c1255a9edb2bdf53127 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 11 Sep 2023 17:54:13 +0300 Subject: [PATCH 1082/4498] net: arp: Directly send the queued pkt We must send the packet without queueing it. The pkt has already been queued for sending, once by net_if and second time in the ARP queue. We must not queue it twice in net_if so that the statistics of the pkt are not counted twice and the packet filter callbacks are only called once. Fixes #62483 Signed-off-by: Jukka Rissanen --- subsys/net/l2/ethernet/arp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index f26c2f7ba96..35a2ec63a64 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -514,6 +514,8 @@ static void arp_update(struct net_if *iface, sys_slist_prepend(&arp_table, &entry->node); while (!k_fifo_is_empty(&entry->pending_queue)) { + int ret; + pkt = k_fifo_get(&entry->pending_queue, K_FOREVER); /* Set the dst in the pending packet */ @@ -525,7 +527,17 @@ static void arp_update(struct net_if *iface, net_sprint_ipv4_addr(&entry->ip), pkt, pkt->frags); - net_if_queue_tx(iface, pkt); + /* We directly send the packet without first queueing it. + * The pkt has already been queued for sending, once by + * net_if and second time in the ARP queue. We must not + * queue it twice in net_if so that the statistics of + * the pkt are not counted twice and the packet filter + * callbacks are only called once. + */ + ret = net_if_l2(iface)->send(iface, pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } } k_mutex_unlock(&arp_mutex); From ed5883d9a07383a1651cb178f23b8c1c5bd7ab52 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 17 Sep 2023 06:13:40 +0200 Subject: [PATCH 1083/4498] Bluetooth: Controller: Use unique goto label in scan aux code Use unique goto label in scan aux connect response ISR. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index 50bcb0e6662..c8188d87cb6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -1510,7 +1510,7 @@ static void isr_rx_connect_rsp(void *param) rx = ftr->extra; rx->hdr.type = NODE_RX_TYPE_RELEASE; - goto isr_rx_do_close; + goto isr_rx_connect_rsp_do_close; } /* Update the max Tx and Rx time; and connection PHY based on the @@ -1548,7 +1548,7 @@ static void isr_rx_connect_rsp(void *param) } #endif /* CONFIG_BT_CTLR_PRIVACY */ -isr_rx_do_close: +isr_rx_connect_rsp_do_close: if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { lll_prof_cputime_capture(); } From 16b0a7ba68222d05ad7246d5c604c1302f52d2c4 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 25 Sep 2023 17:10:08 +1000 Subject: [PATCH 1084/4498] manifest: update loramac-node to v4.7.0 Update loramac-node to release v4.7.0 from v4.6.0. The `v4.7.0-zephyr` branch contains the same 4 additional commits as `v4.6.0-zephyr`. Signed-off-by: Jordan Yates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 936b90ff2ea..3de82d777d7 100644 --- a/west.yml +++ b/west.yml @@ -273,7 +273,7 @@ manifest: - fs revision: ca583fd297ceb48bced3c2548600dc615d67af24 - name: loramac-node - revision: 466089c8726397e3fb68ee611d82712f6e14aa55 + revision: 842413c5fb98707eb5f26e619e8e792453877897 path: modules/lib/loramac-node - name: lvgl revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd From 0538411c0911ec1eacaaf4ff07ab3a230df5a757 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 26 Sep 2023 10:32:01 +0800 Subject: [PATCH 1085/4498] drivers: mm: refine includes of the header Refines the `system_mm.h` to include `zephyr/types.h` instead of `zephyr/kernel.h` as that is all it needs. Updated the includes of `mm_drv_ti_rat.c` accordingly. Signed-off-by: Yong Cong Sin --- drivers/mm/mm_drv_ti_rat.c | 1 + include/zephyr/drivers/mm/system_mm.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mm/mm_drv_ti_rat.c b/drivers/mm/mm_drv_ti_rat.c index da085b72f23..b82bbc162ac 100644 --- a/drivers/mm/mm_drv_ti_rat.c +++ b/drivers/mm/mm_drv_ti_rat.c @@ -19,6 +19,7 @@ * the address space. */ +#include #include #include #include diff --git a/include/zephyr/drivers/mm/system_mm.h b/include/zephyr/drivers/mm/system_mm.h index e407041889e..c76f1097f65 100644 --- a/include/zephyr/drivers/mm/system_mm.h +++ b/include/zephyr/drivers/mm/system_mm.h @@ -15,7 +15,7 @@ #ifndef ZEPHYR_INCLUDE_DRIVERS_SYSTEM_MM_H_ #define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_MM_H_ -#include +#include #ifndef _ASMLANGUAGE From 9e01c4df53370c5700f2d41a8d017f6e4f6925e8 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 25 Sep 2023 20:36:41 +0200 Subject: [PATCH 1086/4498] Bluetooth: Controller: nRF53: Fix missing NRF_CCM subscribe clear Fix missing NRF_CCM subscribe clear which can lead to spurious trigger of TASK_CRYPT in NRF_CCM. This may lead to corruption of Rx PDU buffers. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 6 ++++++ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 8 ++++++++ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 3fc76a27bdf..0b41a9bbfb6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -1084,6 +1084,8 @@ void radio_tmr_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); + hal_trigger_crypt_ppi_disable(); + hal_radio_nrf_ppi_channels_disable( BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) | BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) | @@ -1116,6 +1118,8 @@ void radio_tmr_tx_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); + hal_trigger_crypt_ppi_disable(); + hal_radio_nrf_ppi_channels_disable( #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \ !defined(DPPI_PRESENT) @@ -1152,6 +1156,8 @@ void radio_tmr_rx_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); + hal_trigger_crypt_ppi_disable(); + hal_radio_nrf_ppi_channels_disable( #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \ !defined(DPPI_PRESENT) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index c28cc35a617..3792111292a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -127,6 +127,14 @@ static inline void hal_trigger_crypt_ppi_config(void) nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_CRYPT, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); } +/******************************************************************************* + * Disable trigger encryption task + */ +static inline void hal_trigger_crypt_ppi_disable(void) +{ + nrf_ccm_subscribe_clear(NRF_CCM, NRF_CCM_TASK_CRYPT); +} + #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) /******************************************************************************* * Trigger encryption task on Bit counter match: diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 866769c95eb..d964129bfa1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -205,6 +205,16 @@ static inline void hal_trigger_crypt_ppi_config(void) /* No need to configure anything for the pre-programmed channel. */ } +/******************************************************************************* + * Disable trigger encryption task + */ +static inline void hal_trigger_crypt_ppi_disable(void) +{ + /* No need to disable anything as ppi channel will be disabled in a + * separate disable ppi call by the caller of this function. + */ +} + #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) /******************************************************************************* * Trigger encryption task on Bit counter match: From ca3310145f8f1bbf932cd04ed83536dff14fd620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 26 Sep 2023 11:31:13 +0700 Subject: [PATCH 1087/4498] drivers: select nocache only when supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NOCACHE_MEMORY depends on ARCH_HAS_NOCACHE_MEMORY_SUPPORT, so don't try to select the symbol if not supported. Signed-off-by: Manuel Argüelles --- drivers/crypto/Kconfig.mcux_dcp | 2 +- drivers/ethernet/Kconfig.dwmac | 2 +- drivers/ethernet/Kconfig.nxp_s32_gmac | 2 +- drivers/ethernet/Kconfig.nxp_s32_netc | 2 +- drivers/gpio/Kconfig.nxp_s32 | 2 +- drivers/interrupt_controller/Kconfig.nxp_s32 | 2 +- drivers/mbox/Kconfig.nxp_s32 | 2 +- drivers/mdio/Kconfig.nxp_s32 | 2 +- drivers/pwm/Kconfig.nxp_s32_emios | 2 +- drivers/serial/Kconfig.nxp_s32 | 2 +- drivers/spi/Kconfig.nxp_s32 | 2 +- drivers/watchdog/Kconfig.nxp_s32 | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/Kconfig.mcux_dcp b/drivers/crypto/Kconfig.mcux_dcp index 38f725b4092..e16517e2815 100644 --- a/drivers/crypto/Kconfig.mcux_dcp +++ b/drivers/crypto/Kconfig.mcux_dcp @@ -6,7 +6,7 @@ config CRYPTO_MCUX_DCP default y depends on HAS_MCUX_CACHE depends on DT_HAS_NXP_MCUX_DCP_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT select CACHE_MANAGEMENT if DCACHE help Enable NXP Data Co-Processor (DCP) driver. diff --git a/drivers/ethernet/Kconfig.dwmac b/drivers/ethernet/Kconfig.dwmac index 547a8a7a1f1..47acdffd0b1 100644 --- a/drivers/ethernet/Kconfig.dwmac +++ b/drivers/ethernet/Kconfig.dwmac @@ -30,7 +30,7 @@ if ETH_DWMAC config ETH_DWMAC_STM32H7X bool depends on SOC_SERIES_STM32H7X - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT default y config ETH_DWMAC_MMU diff --git a/drivers/ethernet/Kconfig.nxp_s32_gmac b/drivers/ethernet/Kconfig.nxp_s32_gmac index 1d78ea5ff99..a1d0f3f7c3d 100644 --- a/drivers/ethernet/Kconfig.nxp_s32_gmac +++ b/drivers/ethernet/Kconfig.nxp_s32_gmac @@ -5,7 +5,7 @@ menuconfig ETH_NXP_S32_GMAC bool "NXP S32 GMAC driver" default y depends on DT_HAS_NXP_S32_GMAC_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT select PINCTRL help Enable GMAC/EMAC Ethernet driver for NXP S32 SoCs. diff --git a/drivers/ethernet/Kconfig.nxp_s32_netc b/drivers/ethernet/Kconfig.nxp_s32_netc index d56c38916ba..e73f65502a3 100644 --- a/drivers/ethernet/Kconfig.nxp_s32_netc +++ b/drivers/ethernet/Kconfig.nxp_s32_netc @@ -8,7 +8,7 @@ menuconfig ETH_NXP_S32_NETC depends on !NET_TEST select MBOX select MDIO if DT_HAS_NXP_S32_NETC_PSI_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable Ethernet Switch and Controller (NETC) driver for NXP S32 SoCs. diff --git a/drivers/gpio/Kconfig.nxp_s32 b/drivers/gpio/Kconfig.nxp_s32 index 159402b10ea..0c478c324df 100644 --- a/drivers/gpio/Kconfig.nxp_s32 +++ b/drivers/gpio/Kconfig.nxp_s32 @@ -5,6 +5,6 @@ config GPIO_NXP_S32 bool "NXP S32 GPIO driver" default y depends on DT_HAS_NXP_S32_GPIO_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable the GPIO driver for NXP S32 processors. diff --git a/drivers/interrupt_controller/Kconfig.nxp_s32 b/drivers/interrupt_controller/Kconfig.nxp_s32 index e9d573ed77d..95bba9ec7d8 100644 --- a/drivers/interrupt_controller/Kconfig.nxp_s32 +++ b/drivers/interrupt_controller/Kconfig.nxp_s32 @@ -7,6 +7,6 @@ config NXP_S32_EIRQ bool "External interrupt controller driver for NXP S32 MCUs" default y depends on DT_HAS_NXP_S32_SIUL2_EIRQ_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help External interrupt controller driver for NXP S32 MCUs diff --git a/drivers/mbox/Kconfig.nxp_s32 b/drivers/mbox/Kconfig.nxp_s32 index ca3a81614a3..91c661eaa64 100644 --- a/drivers/mbox/Kconfig.nxp_s32 +++ b/drivers/mbox/Kconfig.nxp_s32 @@ -5,6 +5,6 @@ config MBOX_NXP_S32_MRU bool "NXP S32 Message Receive Unit (MRU) driver" default y depends on DT_HAS_NXP_S32_MRU_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Driver for NXP S32 Message Receive Unit (MRU). diff --git a/drivers/mdio/Kconfig.nxp_s32 b/drivers/mdio/Kconfig.nxp_s32 index e13b1b5b2ef..07674f7a57d 100644 --- a/drivers/mdio/Kconfig.nxp_s32 +++ b/drivers/mdio/Kconfig.nxp_s32 @@ -5,6 +5,6 @@ config MDIO_NXP_S32_NETC bool "NXP S32 NETC External MDIO driver" default y depends on DT_HAS_NXP_S32_NETC_EMDIO_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable NETC External MDIO Controller driver for NXP S32 SoCs. diff --git a/drivers/pwm/Kconfig.nxp_s32_emios b/drivers/pwm/Kconfig.nxp_s32_emios index 363e676822e..5d976ea2d59 100644 --- a/drivers/pwm/Kconfig.nxp_s32_emios +++ b/drivers/pwm/Kconfig.nxp_s32_emios @@ -6,6 +6,6 @@ config PWM_NXP_S32_EMIOS default y depends on DT_HAS_NXP_S32_EMIOS_PWM_ENABLED select NXP_S32_EMIOS - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable support for the NXP S32 PWM-eMIOS. diff --git a/drivers/serial/Kconfig.nxp_s32 b/drivers/serial/Kconfig.nxp_s32 index bd8b3c4a4c8..84555fd9e83 100644 --- a/drivers/serial/Kconfig.nxp_s32 +++ b/drivers/serial/Kconfig.nxp_s32 @@ -7,7 +7,7 @@ config UART_NXP_S32_LINFLEXD depends on DT_HAS_NXP_S32_LINFLEXD_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable the LINFlexD UART driver for NXP S32 family processors. diff --git a/drivers/spi/Kconfig.nxp_s32 b/drivers/spi/Kconfig.nxp_s32 index 6183c49a4ae..b1e431877c1 100644 --- a/drivers/spi/Kconfig.nxp_s32 +++ b/drivers/spi/Kconfig.nxp_s32 @@ -5,7 +5,7 @@ config NXP_S32_SPI bool "NXP S32 SPI driver" default y depends on DT_HAS_NXP_S32_SPI_ENABLED - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable support for NXP S32 SPI driver. diff --git a/drivers/watchdog/Kconfig.nxp_s32 b/drivers/watchdog/Kconfig.nxp_s32 index 1db0a208b38..a44decb500c 100644 --- a/drivers/watchdog/Kconfig.nxp_s32 +++ b/drivers/watchdog/Kconfig.nxp_s32 @@ -6,6 +6,6 @@ config WDT_NXP_S32 default y depends on DT_HAS_NXP_S32_SWT_ENABLED select CLOCK_CONTROL - select NOCACHE_MEMORY + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable the Software Watchdog Timer (SWT) driver. From f17e4f1b76dd10bcf464dbc718073284e61d16fa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 25 Sep 2023 13:38:15 +0000 Subject: [PATCH 1088/4498] modules/MCUboot: Add new Kconfig indicating downgrade prevention Add the MCUBOOT_BOOTLOADER_NO_DOWNGRADE Kconfig option that allows, when paired with MCUboot mode Kconfig, to indicate that the MCUboot has been configured with downgrade prevention, which means that only application with version higher than running can be swapped on next boot. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 5f83098a577..ab1dd44fbd5 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -116,7 +116,7 @@ config MCUBOOT_EXTRA_IMGTOOL_ARGS help When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty string) you can use this option to pass extra options to - imgtool. For example, you could set this to "--version 1.2". + imgtool. For example, you could set this to "--version 1.2". config MCUBOOT_GENERATE_UNSIGNED_IMAGE bool "Generate unsigned binary image bootable with MCUboot" @@ -136,6 +136,8 @@ config MCUBOOT_GENERATE_CONFIRMED_IMAGE The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN and CONFIG_BUILD_OUTPUT_HEX. +menu "On board MCUboot operation mode" + choice MCUBOOT_BOOTLOADER_MODE prompt "Application assumed MCUboot mode of operation" default MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH # MCUBOOT_BOOTLOADER_MODE @@ -154,31 +156,43 @@ config MCUBOOT_BOOTLOADER_MODE_SINGLE_APP config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH bool "MCUboot has been configured for swap without scratch operation" + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to be present in DT and application will boot from slot0_partition. + MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected + if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH bool "MCUboot has been configured for swap using scratch operation" + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE help MCUboot expects slot0_partition, slot1_partition and scratch_partition to be present in DT, and application will boot from slot0_partition. In this mode scratch_partition is used as temporary storage when MCUboot swaps application from the secondary slot to the primary slot. + MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected + if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP bool "MCUboot has been configured for DirectXIP operation" + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE + select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. In this mode MCUboot can boot from either partition and will select one with higher application image version, which usually means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER is also selected that enables comparison of build number. + This option automatically selectes + MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible + to swap back to older version of application. config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT bool "MCUboot has been configured for DirectXIP with revert" select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP + select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. In this mode MCUboot will boot the application with the higher version @@ -190,9 +204,30 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT This mode does not allow freely switching between application versions, as, once higher version application is approved, it is not possible to select lower version for boot. + This mode selects MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible + to downgrade running application, but note that MCUboot may do that + if application with higher version will not get confirmed. endchoice # MCUBOOT_BOOTLOADER_MODE +config MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE + bool + help + Selected mode supports downgrade prevention, where you cannot switch to + an application with lower version than the currently running application. + +if MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE +config MCUBOOT_BOOTLOADER_NO_DOWNGRADE + bool "MCUboot mode has downgrade prevention enabled" + help + Selected MCUboot mode has downgrade prevention enabled, where you are not + able to change back to image with lower version number. + This options should be selected when MCUboot has been built with + MCUBOOT_DOWNGRADE_PREVENTION option enabled. +endif + +endmenu # On board MCUboot operation mode + endif # BOOTLOADER_MCUBOOT menuconfig MCUBOOT_BOOTUTIL_LIB From a43107299f6d4217f6730ccccf6a0e771357c3ca Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 25 Sep 2023 13:47:32 +0000 Subject: [PATCH 1089/4498] doc/release-notes: Add info on downgrade prevention Kconfig Adds note on addition of MCUBOOT_BOOTLOADER_MODE_WITH_DOWNGRADE_PREVENTION to MCUboot Kconfig module. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 5af4179e317..9f5e2319dd2 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -367,6 +367,11 @@ HALs MCUboot ******* + * Added :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_NO_DOWNGRADE` + that allows to inform application that the on-board MCUboot has been configured + with downgrade prevention enabled. This option is automatically selected for + DirectXIP mode and is available for both swap modes. + Storage ******* From 652544e3967161a66cf99a4202b9011343e2ec01 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 10 Aug 2023 00:37:01 +0530 Subject: [PATCH 1090/4498] Bluetooth: Controller: Fix CIS assymmetric PHY usage Fix CIS assymmetric PHY usage by adding implementation to use correct PHY in radio when switching transceiver. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_central_iso.c | 12 +++++++++--- .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 11 ++++++++++- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 4 ++++ .../bluetooth/controller/ll_sw/ull_peripheral_iso.c | 2 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 6135cc9d863..d287bc794a6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -488,14 +488,17 @@ static void isr_tx(void *param) /* Get reference to CIS LLL context */ cis_lll = param; + /* Acquire rx node for reception */ + node_rx = ull_iso_pdu_rx_alloc_peek(1U); + LL_ASSERT(node_rx); + #if defined(CONFIG_BT_CTLR_LE_ENC) /* Get reference to ACL context */ const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ - /* Acquire rx node for reception */ - node_rx = ull_iso_pdu_rx_alloc_peek(1U); - LL_ASSERT(node_rx); + /* PHY */ + radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); /* Encryption */ if (false) { @@ -1087,6 +1090,9 @@ static void isr_prepare_subevent(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ + /* PHY */ + radio_phy_set(cis_lll->tx.phy, cis_lll->tx.phy_flags); + /* Encryption */ if (false) { diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 4796696ce73..f089a07bb0b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -244,7 +244,7 @@ static int prepare_cb(struct lll_prepare_param *p) #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ phy = cis_lll->rx.phy; - radio_phy_set(phy, cis_lll->rx.phy_flags); + radio_phy_set(phy, PHY_FLAGS_S8); radio_aa_set(cis_lll->access_addr); radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(conn_lll->crc_init)); lll_chan_set(data_chan_use); @@ -738,6 +738,9 @@ static void isr_rx(void *param) pdu_tx->rfu0 = 0U; pdu_tx->rfu1 = 0U; + /* PHY */ + radio_phy_set(cis_lll->tx.phy, cis_lll->tx.phy_flags); + /* Encryption */ if (false) { @@ -880,6 +883,9 @@ static void isr_tx(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ + /* PHY */ + radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); + /* Encryption */ if (false) { @@ -1094,6 +1100,9 @@ static void isr_prepare_subevent_common(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ + /* PHY */ + radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); + /* Encryption */ if (false) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 2a19e03bde5..aac5d2057d2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -136,7 +136,9 @@ uint8_t ll_cis_parameters_set(uint8_t cis_id, ll_iso_setup.stream[cis_idx].c_max_sdu = c_sdu; ll_iso_setup.stream[cis_idx].p_max_sdu = p_sdu; ll_iso_setup.stream[cis_idx].lll.tx.phy = c_phy; + ll_iso_setup.stream[cis_idx].lll.tx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.rx.phy = p_phy; + ll_iso_setup.stream[cis_idx].lll.rx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].central.c_rtn = c_rtn; ll_iso_setup.stream[cis_idx].central.p_rtn = p_rtn; ll_iso_setup.cis_idx++; @@ -635,7 +637,9 @@ uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t nse, ll_iso_setup.stream[cis_idx].lll.tx.max_pdu = c_bn ? c_pdu : 0U; ll_iso_setup.stream[cis_idx].lll.rx.max_pdu = p_bn ? p_pdu : 0U; ll_iso_setup.stream[cis_idx].lll.tx.phy = c_phy; + ll_iso_setup.stream[cis_idx].lll.tx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.rx.phy = p_phy; + ll_iso_setup.stream[cis_idx].lll.rx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.tx.bn = c_bn; ll_iso_setup.stream[cis_idx].lll.rx.bn = p_bn; ll_iso_setup.cis_idx++; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index f68ca66656f..d2627502ac2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -257,11 +257,13 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->lll.nse = req->nse; cis->lll.rx.phy = req->c_phy; + cis->lll.rx.phy_flags = PHY_FLAGS_S8; cis->lll.rx.bn = req->c_bn; cis->lll.rx.ft = req->c_ft; cis->lll.rx.max_pdu = sys_le16_to_cpu(req->c_max_pdu); cis->lll.tx.phy = req->p_phy; + cis->lll.tx.phy_flags = PHY_FLAGS_S8; cis->lll.tx.bn = req->p_bn; cis->lll.tx.ft = req->p_ft; cis->lll.tx.max_pdu = sys_le16_to_cpu(req->p_max_pdu); From 7b4f22edd17acafa55add96da96cdae6d90ce973 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 1 Jun 2023 12:00:44 +0300 Subject: [PATCH 1091/4498] net: lwm2m: Add functional tests for LwM2M against Leshan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new Pytest integration to run testcases against Leshan. Test with: twister -T tests/net/lib/lwm2m/functional -p native_posix -vv This requires Leshan running in localhost using following setup: tcp/8080 Leshan web interface and REST API tcp/8081 Leshan bootstrap server REST API udp/5683 Leshan non-secure CoAP udp/5684 Leshan DTLS CoAP udp/5783 non-secure Bootstrap CoAP udp/5684 DTLS Bootstrap CoAP Leshan and Boostrap server must be reachable from native_posix run using IP address 192.0.2.2 as in most of the examples. Tests are written from test spec; OMA Enabler Test Specification (Interoperability) for Lightweight M2M Following tests are implemented in this commit: * LightweightM2M-1.1-int-0 – Client Initiated Bootstrap * LightweightM2M-1.1-int-1 – Client Initiated Bootstrap Full (PSK) * LightweightM2M-1.1-int-101 – Initial Registration * LightweightM2M-1.1-int-102 – Registration Update * LightweightM2M-1.1-int-104 – Registration Update Trigge * LightweightM2M-1.1-int-105 - Discarded Register Update * LightweightM2M-1.1-int-107 – Extending the lifetime of a registration * LightweightM2M-1.1-int-108 – Turn on Queue Mode * LightweightM2M-1.1-int-109 – Behavior in Queue Mode * LightweightM2M-1.1-int-201 – Querying basic information in Plain Text * LightweightM2M-1.1-int-203 – Querying basic information in TLV format * LightweightM2M-1.1-int-204 – Querying basic information in JSON format * LightweightM2M-1.1-int-205 – Setting basic information in Plain Text * LightweightM2M-1.1-int-211 – Querying basic information in CBOR format * LightweightM2M-1.1-int-212 – Setting basic information in CBOR format * LightweightM2M-1.1-int-215 – Setting basic information in TLV format * LightweightM2M-1.1-int-220 – Setting basic information in JSON format * LightweightM2M-1.1-int-221 – Attempt to perform operations on Security * LightweightM2M-1.1-int-401 – UDP Channel Security – PSK Mode Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/interop/CMakeLists.txt | 10 + tests/net/lib/lwm2m/interop/README.md | 103 ++++ .../lwm2m/interop/boards/native_posix.conf | 7 + .../lwm2m/interop/boards/qemu_cortex_m3.conf | 20 + tests/net/lib/lwm2m/interop/prj.conf | 90 ++++ tests/net/lib/lwm2m/interop/pytest/leshan.py | 104 ++++ .../lib/lwm2m/interop/pytest/test_lwm2m.py | 446 ++++++++++++++++++ tests/net/lib/lwm2m/interop/requirements.txt | 1 + .../net/lib/lwm2m/interop/src/lwm2m-client.c | 171 +++++++ tests/net/lib/lwm2m/interop/testcase.yaml | 14 + 10 files changed, 966 insertions(+) create mode 100644 tests/net/lib/lwm2m/interop/CMakeLists.txt create mode 100644 tests/net/lib/lwm2m/interop/README.md create mode 100644 tests/net/lib/lwm2m/interop/boards/native_posix.conf create mode 100644 tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf create mode 100644 tests/net/lib/lwm2m/interop/prj.conf create mode 100644 tests/net/lib/lwm2m/interop/pytest/leshan.py create mode 100644 tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py create mode 100644 tests/net/lib/lwm2m/interop/requirements.txt create mode 100644 tests/net/lib/lwm2m/interop/src/lwm2m-client.c create mode 100644 tests/net/lib/lwm2m/interop/testcase.yaml diff --git a/tests/net/lib/lwm2m/interop/CMakeLists.txt b/tests/net/lib/lwm2m/interop/CMakeLists.txt new file mode 100644 index 00000000000..89c4d33e43e --- /dev/null +++ b/tests/net/lib/lwm2m/interop/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(lwm2m_interop_tests) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +include(${ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md new file mode 100644 index 00000000000..858f5007f64 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/README.md @@ -0,0 +1,103 @@ +# LwM2M Interoperability tests using Leshan demo server + +This directory contains list of testcases that use +the Twister's Pytest integration to run testcases against Leshan demo server. +These tests use emulated hardware (native_posix). + +These tests require setup that is not done in Twister run, so follow this documentation to set +up the test environment. + +## Network setup + +As with typical network samples, host machine uses IP address `192.0.2.2` and the emulated device +running Zephyr is using address `192.0.2.1`. + +Follow [Networking with the host system](https://docs.zephyrproject.org/latest/connectivity/networking/networking_with_host.html#networking-with-the-host-system) +from Zephyr's documentation how to set it up, or follow [Create NAT and routing for Zephyr native network on Linux](https://github.com/zephyrproject-rtos/net-tools/blob/master/README%20NAT.md). + +### Leshan server setup + +* Leshan server must be reachable from the device using IP address `192.0.2.2`. + Configure the port forwarding, if you use Docker to run Leshan. +* Leshan demo server REST API must be reachable from localhost. +* tcp/8080 Leshan web interface and REST API +* tcp/8081 Leshan bootstrap server REST API +* udp/5683 Leshan non-secure CoAP +* udp/5684 Leshan DTLS CoAP +* udp/5783 non-secure Bootstrap CoAP +* udp/5684 DTLS Bootstrap CoAP +* Download Leshan JAR file from https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar +* Download Leshan Bootstrap server JAR file from https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar + +Both server can be started like this: +``` +java -jar ./leshan-server-demo.jar -wp 8080 -vv +java -jar ./leshan-bsserver-demo.jar -lp=5783 -slp=5784 -wp 8081 +``` + +Or create a helper script that does everything, including download: +``` +#!/bin/sh -eu + +# Download Leshan if needed +if [ ! -f leshan-server-demo.jar ]; then + wget https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar +fi + +if [ ! -f leshan-bsserver-demo.jar ]; then + wget 'https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar' +fi + +mkdir -p log + +start-stop-daemon --make-pidfile --pidfile log/leshan.pid --chdir $(pwd) --background --start \ + --startas /bin/bash -- -c "exec java -jar ./leshan-server-demo.jar -wp 8080 -vv --models-folder objects >log/leshan.log 2>&1" + +start-stop-daemon --make-pidfile --pidfile log/leshan_bs.pid --chdir $(pwd) --background --start \ + --startas /bin/bash -- -c "exec java -jar ./leshan-bsserver-demo.jar -lp=5783 -slp=5784 -wp 8081 -vv >log/leshan_bs.log 2>&1" +``` + +Then stopping would require similar script: +``` +#!/bin/sh -eu + +start-stop-daemon --remove-pidfile --pidfile log/leshan.pid --stop +start-stop-daemon --remove-pidfile --pidfile log/leshan_bs.pid --stop +``` + +## Python package requirements + +These tests require extra package that is not installed when you follow the Zephyr's setup. +Install with `pip install CoAPthon3` + +## Running tests + +``` +twister -p native_posix -vv --enable-slow -T tests/net/lib/lwm2m/interop +`````` + +## Test specification + +Tests are written from test spec; +[OMA Enabler Test Specification (Interoperability) for Lightweight M2M](https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf) + +Following tests are implemented: +* LightweightM2M-1.1-int-0 – Client Initiated Bootstrap +* LightweightM2M-1.1-int-1 – Client Initiated Bootstrap Full (PSK) +* LightweightM2M-1.1-int-101 – Initial Registration +* LightweightM2M-1.1-int-102 – Registration Update +* LightweightM2M-1.1-int-104 – Registration Update Trigge +* LightweightM2M-1.1-int-105 - Discarded Register Update +* LightweightM2M-1.1-int-107 – Extending the lifetime of a registration +* LightweightM2M-1.1-int-108 – Turn on Queue Mode +* LightweightM2M-1.1-int-109 – Behavior in Queue Mode +* LightweightM2M-1.1-int-201 – Querying basic information in Plain Text +* LightweightM2M-1.1-int-203 – Querying basic information in TLV format +* LightweightM2M-1.1-int-204 – Querying basic information in JSON format +* LightweightM2M-1.1-int-205 – Setting basic information in Plain Text +* LightweightM2M-1.1-int-211 – Querying basic information in CBOR format +* LightweightM2M-1.1-int-212 – Setting basic information in CBOR format +* LightweightM2M-1.1-int-215 – Setting basic information in TLV format +* LightweightM2M-1.1-int-220 – Setting basic information in JSON format +* LightweightM2M-1.1-int-221 – Attempt to perform operations on Security +* LightweightM2M-1.1-int-401 – UDP Channel Security – PSK Mode diff --git a/tests/net/lib/lwm2m/interop/boards/native_posix.conf b/tests/net/lib/lwm2m/interop/boards/native_posix.conf new file mode 100644 index 00000000000..44346db12ed --- /dev/null +++ b/tests/net/lib/lwm2m/interop/boards/native_posix.conf @@ -0,0 +1,7 @@ +CONFIG_DNS_RESOLVER=y +CONFIG_DNS_SERVER_IP_ADDRESSES=y +CONFIG_DNS_SERVER1="192.0.2.2" +CONFIG_LWM2M_DNS_SUPPORT=y +CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" +CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf b/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf new file mode 100644 index 00000000000..7a3fd344e50 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf @@ -0,0 +1,20 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_ETH_DRIVER=y +CONFIG_ETH_STELLARIS=y +CONFIG_NET_QEMU_ETHERNET=y + +# RAM/ROM tuning +CONFIG_IDLE_STACK_SIZE=128 +CONFIG_MBEDTLS_HEAP_SIZE=7000 +CONFIG_ISR_STACK_SIZE=512 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1024 +CONFIG_LWM2M_ENGINE_STACK_SIZE=2000 +CONFIG_LWM2M_LOG_LEVEL_INF=y +CONFIG_LWM2M_ENGINE_MAX_MESSAGES=3 +CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE=0 +CONFIG_LWM2M_ENGINE_MAX_OBSERVER=5 +CONFIG_LWM2M_SECURITY_DTLS_TLS_CIPHERSUITE_MAX=3 +CONFIG_LWM2M_DEVICE_PWRSRC_MAX=2 +CONFIG_LWM2M_DEVICE_ERROR_CODE_MAX=5 +CONFIG_LWM2M_DEVICE_EXT_DEV_INFO_MAX=2 +CONFIG_LWM2M_NUM_ATTR=10 diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf new file mode 100644 index 00000000000..5d255e0513e --- /dev/null +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -0,0 +1,90 @@ +CONFIG_NETWORKING=y +CONFIG_LOG=y +CONFIG_LWM2M_LOG_LEVEL_DBG=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NET_IPV6=y +CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 +CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=2 +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=n +CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 +CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT=2 +CONFIG_PRINTK=y +CONFIG_NET_PKT_RX_COUNT=10 +CONFIG_NET_PKT_TX_COUNT=10 +CONFIG_NET_BUF_RX_COUNT=10 +CONFIG_NET_BUF_TX_COUNT=10 +CONFIG_NET_MAX_CONTEXTS=5 +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" + +CONFIG_NET_LOG=y + +CONFIG_NET_CONFIG_NEED_IPV6=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_SETTINGS=y + +CONFIG_LWM2M=y +CONFIG_LWM2M_COAP_BLOCK_SIZE=512 +CONFIG_LWM2M_IPSO_SUPPORT=y +CONFIG_LWM2M_SHELL=y +CONFIG_LWM2M_ACCESS_CONTROL_ENABLE=n + +#Enable Portfolio object +CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y + +#LwM2M v1.1 configure +CONFIG_LWM2M_VERSION_1_1=y +CONFIG_LWM2M_DTLS_SUPPORT=y +CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=y + +#Enable SenML JSON content format +CONFIG_JSON_LIBRARY=y +CONFIG_BASE64=y +CONFIG_LWM2M_RW_SENML_JSON_SUPPORT=y + +#Enable SenML CBOR content format +CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT=y +CONFIG_LWM2M_RW_SENML_CBOR_RECORDS=60 +CONFIG_ZCBOR_CANONICAL=y + +#Enable legacy content formats +CONFIG_LWM2M_RW_JSON_SUPPORT=y +CONFIG_LWM2M_RW_OMA_TLV_SUPPORT=y + +# Longer endpoint name might be returned in a registration reply +CONFIG_COAP_EXTENDED_OPTIONS_LEN=y +CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 + +# Use QUEUE mode by default +CONFIG_LWM2M_QUEUE_MODE_ENABLED=y +CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 + +# LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 +CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 +CONFIG_LWM2M_SERVER_DEFAULT_PMIN=1 +CONFIG_LWM2M_SERVER_DEFAULT_PMAX=10 + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_TLS_VERSION_1_2=y + +# Special MbedTLS changes +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=8192 +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1500 +CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y + +# Disable RSA, we don't parse certs: saves flash/memory +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n +# Enable PSK instead +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y + +CONFIG_NET_SOCKETS_SOCKOPT_TLS=y +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 +CONFIG_NET_SOCKETS_ENABLE_DTLS=y + +# MbedTLS needs a larger stack +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py new file mode 100644 index 00000000000..4d69a3a977f --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -0,0 +1,104 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import json +import requests +import binascii + +class Leshan: + def __init__(self, url: str): + self.api_url = url + self.timeout = 10 + self.format = 'TLV' + # self.format = "SENML_CBOR" + try: + resp = self.get('/security/clients') + if not isinstance(resp, list): + raise RuntimeError('Did not receive list of endpoints') + except requests.exceptions.ConnectionError: + raise RuntimeError('Leshan not responding') + + @staticmethod + def handle_response(resp: requests.models.Response): + """Generic response handler for all queries""" + if resp.status_code >= 300 or resp.status_code < 200: + raise RuntimeError(f'Error {resp.status_code}: {resp.text}') + if len(resp.text): + obj = json.loads(resp.text) + return obj + else: + return None + + def get(self, path: str): + """Send HTTP GET query""" + resp = requests.get(f'{self.api_url}{path}?timeout={self.timeout}&format={self.format}') + return Leshan.handle_response(resp) + + def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): + resp = requests.put(f'{self.api_url}{path}', data=data, headers=headers) + return Leshan.handle_response(resp) + + def put(self, path: str, data: str | dict, uri_options: str = ''): + if isinstance(data, dict): + data = json.dumps(data) + return self.put_raw(f'{path}?timeout={self.timeout}&format={self.format}' + uri_options, data=data, headers={'content-type': 'application/json'}) + + def post(self, path: str, data: str | dict | None = None): + resp = requests.post(f'{self.api_url}{path}', data=data, headers={'content-type': 'application/json'}) + return Leshan.handle_response(resp) + + def delete(self, path: str): + resp = requests.delete(f'{self.api_url}{path}') + return Leshan.handle_response(resp) + + def execute(self, endpoint: str, path: str): + return self.post(f'/clients/{endpoint}/{path}') + + def write(self, endpoint: str, path: str, value: bool | int | str): + if isinstance(value, bool): + type = 'boolean' + value = "true" if value else "false" + elif isinstance(value, int): + type = 'integer' + value = str(value) + elif isinstance(value, str): + type = 'string' + value = '"' + value + '"' + id = path.split('/')[2] + return self.put(f'/clients/{endpoint}/{path}', f'{{"id":{id},"kind":"singleResource","value":{value},"type":"{type}"}}') + + def read(self, endpoint: str, path: str): + resp = self.get(f'/clients/{endpoint}/{path}') + if not resp['success']: + return resp + content = resp['content'] + if content['kind'] == 'instance': + return content['resources'] + elif content['kind'] == 'singleResource': + return content['value'] + elif content['kind'] == 'multiResource': + return content['values'] + raise RuntimeError(f'Unhandled type {content["kind"]}') + + def create_psk_device(self, endpoint: str, passwd: str): + psk = binascii.b2a_hex(passwd.encode()).decode() + self.put('/security/clients/', f'{{"endpoint":"{endpoint}","tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}} }} }}') + + def delete_device(self, endpoint: str): + self.delete(f'/security/clients/{endpoint}') + + def create_bs_device(self, endpoint: str, server_uri: str, passwd: str): + psk = binascii.b2a_hex(passwd.encode()).decode() + data = f'{{"tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}}}},"endpoint":"{endpoint}"}}' + self.put('/security/clients/', data) + id = str([ord(n) for n in endpoint]) + key = str([ord(n) for n in passwd]) + content = '{"servers":{"0":{"binding":"U","defaultMinPeriod":1,"lifetime":86400,"notifIfDisabled":false,"shortId":1}},"security":{"1":{"bootstrapServer":false,"clientOldOffTime":1,"publicKeyOrId":' + id + ',"secretKey":' + key + ',"securityMode":"PSK","serverId":1,"serverSmsNumber":"","smsBindingKeyParam":[],"smsBindingKeySecret":[],"smsSecurityMode":"NO_SEC","uri":"'+server_uri+'"}},"oscore":{},"toDelete":["/0","/1"]}' + self.post(f'/bootstrap/{endpoint}', content) + + def delete_bs_device(self, endpoint: str): + self.delete(f'/security/clients/{endpoint}') + self.delete(f'/bootstrap/{endpoint}') diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py new file mode 100644 index 00000000000..21ed51ef1e6 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -0,0 +1,446 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import time +import logging +import pytest +from leshan import Leshan +import os +import binascii +import random +import string + +from twister_harness import Shell + +LESHAN_IP: str = '192.0.2.2' +COAP_PORT: int = 5683 +COAPS_PORT: int = 5684 +BOOTSTRAP_COAPS_PORT: int = 5784 + +logger = logging.getLogger(__name__) + +@pytest.fixture(scope='module') +def helperclient() -> object: + try: + from coapthon.client.helperclient import HelperClient + except ModuleNotFoundError: + pytest.skip('CoAPthon3 package not installed') + return HelperClient(server=('127.0.0.1', COAP_PORT)) + +@pytest.fixture(scope='session') +def leshan() -> Leshan: + try: + return Leshan("http://localhost:8080/api") + except RuntimeError: + pytest.skip('Leshan server not available') + +@pytest.fixture(scope='session') +def leshan_bootstrap() -> Leshan: + try: + return Leshan("http://localhost:8081/api") + except RuntimeError: + pytest.skip('Leshan Bootstrap server not available') + +# +# Test specification: +# https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf +# + +def verify_LightweightM2M_1_1_int_0(shell: Shell): + logger.info("LightweightM2M-1.1-int-0 - Client Initiated Bootstrap") + shell._device.readlines_until(regex='.*Bootstrap started with endpoint', timeout=5.0) + shell._device.readlines_until(regex='.*Bootstrap registration done', timeout=5.0) + shell._device.readlines_until(regex='.*Bootstrap data transfer done', timeout=5.0) + +def verify_LightweightM2M_1_1_int_1(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)") + verify_LightweightM2M_1_1_int_0(shell) + verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint) + +def verify_LightweightM2M_1_1_int_101(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-101 - Initial Registration") + shell._device.readlines_until(regex='.*Registration Done', timeout=5.0) + assert leshan.get(f'/clients/{endpoint}') + +def verify_LightweightM2M_1_1_int_102(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-102 - Registration Update") + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) + litetime = int(lines[0]) + lifetime = litetime + 10 + start_time = time.time() * 1000 + leshan.write(endpoint, '1/0/1', lifetime) + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + latest = leshan.get(f'/clients/{endpoint}') + assert latest["lastUpdate"] > start_time + assert latest["lastUpdate"] <= time.time()*1000 + assert latest["lifetime"] == lifetime + shell.exec_command('lwm2m write 1/0/1 -u32 86400') + +def verify_LightweightM2M_1_1_int_103(): + """LightweightM2M-1.1-int-103 - Deregistration""" + # Unsupported. We don't have "disabled" functionality in server object + +def verify_LightweightM2M_1_1_int_104(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-104 - Registration Update Trigger") + shell.exec_command('lwm2m update') + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + leshan.execute(endpoint, '1/0/8') + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + +def verify_LightweightM2M_1_1_int_105(shell: Shell, leshan: Leshan, endpoint: str, helperclient: object): + logger.info("LightweightM2M-1.1-int-105 - Discarded Register Update") + status = leshan.get(f'/clients/{endpoint}') + if status["secure"]: + logger.debug("Skip, requires non-secure connection") + return + id = status["registrationId"] + assert id + # Fake unregister message + helperclient.delete(f'rd/{id}', timeout=0.1) + helperclient.stop() + time.sleep(1) + shell.exec_command('lwm2m update') + shell._device.readlines_until(regex=r'.*Failed with code 4\.4', timeout=5.0) + shell._device.readlines_until(regex='.*Registration Done', timeout=10.0) + +def verify_LightweightM2M_1_1_int_107(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-107 - Extending the lifetime of a registration") + leshan.write(endpoint, '1/0/1', 120) + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) + lifetime = int(lines[0]) + assert lifetime == 120 + logger.debug(f'sleeping for {lifetime} s') + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=lifetime) + assert leshan.get(f'/clients/{endpoint}') + +def verify_LightweightM2M_1_1_int_108(leshan, endpoint): + logger.info("LightweightM2M-1.1-int-108 - Turn on Queue Mode") + assert leshan.get(f'/clients/{endpoint}')["queuemode"] + +def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-109 - Behavior in Queue Mode") + verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) + shell._device.readlines_until(regex='.*Queue mode RX window closed', timeout=120) + # Restore previous value + shell.exec_command('lwm2m write 1/0/1 -u32 86400') + shell._device.readlines_until(regex='.*Registration update complete', timeout=10) + +def verify_LightweightM2M_1_1_int_201(shell: Shell, leshan: Leshan, endpoint: str): + + logger.info("LightweightM2M-1.1-int-201 - Querying basic information in Plain Text format") + fmt = leshan.format + leshan.format = 'TEXT' + assert leshan.get(f'/clients/{endpoint}/3/0/0')['content']['value'] == 'Zephyr' + assert leshan.get(f'/clients/{endpoint}/3/0/1')['content']['value'] == 'client-1' + assert leshan.get(f'/clients/{endpoint}/3/0/2')['content']['value'] == 'serial-1' + leshan.format = fmt + +def verify_device_object(resp): + ''' Verify that Device object match Configuration 3 ''' + assert resp['valid'] is True + found = 0 + for res in resp['content']['resources']: + if res['id'] == 0: + assert res['value'] == 'Zephyr' + found += 1 + elif res['id'] == 1: + assert res['value'] == 'client-1' + found += 1 + elif res['id'] == 2: + assert res['value'] == 'serial-1' + found += 1 + elif res['id'] == 3: + assert res['value'] == '1.2.3' + found += 1 + elif res['id'] == 11: + assert res['kind'] == 'multiResource' + assert res['values']['0'] == '0' + found += 1 + elif res['id'] == 16: + assert res['value'] == 'U' + found += 1 + assert found == 6 + +def verify_server_object(obj): + ''' Verify that server object match Configuration 3 ''' + found = 0 + for res in obj['resources']: + if res['id'] == 0: + assert res['value'] == '1' + found += 1 + elif res['id'] == 1: + assert res['value'] == '86400' + found += 1 + elif res['id'] == 2: + assert res['value'] == '1' + found += 1 + elif res['id'] == 3: + assert res['value'] == '10' + found += 1 + elif res['id'] == 5: + assert res['value'] == '86400' + found += 1 + elif res['id'] == 6: + assert res['value'] is False + found += 1 + elif res['id'] == 7: + assert res['value'] == 'U' + found += 1 + assert found == 7 + +def verify_LightweightM2M_1_1_int_203(shell: Shell, leshan: Leshan, endpoint: str): + shell.exec_command('lwm2m update') + logger.info('LightweightM2M-1.1-int-203 - Querying basic information in TLV format') + fmt = leshan.format + leshan.format = 'TLV' + resp = leshan.get(f'/clients/{endpoint}/3/0') + verify_device_object(resp) + leshan.format = fmt + +def verify_LightweightM2M_1_1_int_204(shell: Shell, leshan: Leshan, endpoint: str): + shell.exec_command('lwm2m update') + logger.info('LightweightM2M-1.1-int-204 - Querying basic information in JSON format') + fmt = leshan.format + leshan.format = 'JSON' + resp = leshan.get(f'/clients/{endpoint}/3/0') + verify_device_object(resp) + leshan.format = fmt + +def verify_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-205 - Setting basic information in Plain Text format') + fmt = leshan.format + leshan.format = 'TEXT' + leshan.write(endpoint, '1/0/2', 101) + leshan.write(endpoint, '1/0/3', 1010) + leshan.write(endpoint, '1/0/5', 2000) + assert leshan.read(endpoint, '1/0/2') == '101' + assert leshan.read(endpoint, '1/0/3') == '1010' + assert leshan.read(endpoint, '1/0/5') == '2000' + leshan.write(endpoint, '1/0/2', 1) + leshan.write(endpoint, '1/0/3', 10) + leshan.write(endpoint, '1/0/5', 86400) + assert leshan.read(endpoint, '1/0/2') == '1' + assert leshan.read(endpoint, '1/0/3') == '10' + assert leshan.read(endpoint, '1/0/5') == '86400' + leshan.format = fmt + +def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-211 - Querying basic information in CBOR format') + fmt = leshan.format + leshan.format = 'CBOR' + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) + id = lines[0] + assert leshan.read(endpoint, '1/0/0') == id + assert leshan.read(endpoint, '1/0/6') is False + assert leshan.read(endpoint, '1/0/7') == 'U' + leshan.format = fmt + +def verify_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-212 - Setting basic information in CBOR format') + fmt = leshan.format + leshan.format = 'CBOR' + leshan.write(endpoint, '1/0/2', 101) + leshan.write(endpoint, '1/0/3', 1010) + leshan.write(endpoint, '1/0/6', True) + assert leshan.read(endpoint, '1/0/2') == '101' + assert leshan.read(endpoint, '1/0/3') == '1010' + assert leshan.read(endpoint, '1/0/6') is True + leshan.write(endpoint, '1/0/2', 1) + leshan.write(endpoint, '1/0/3', 10) + leshan.write(endpoint, '1/0/6', False) + leshan.format = fmt + +def verify_setting_basic_in_format(shell, leshan, endpoint, format): + fmt = leshan.format + leshan.format = format + server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] + verify_server_object(server_obj) + # Remove Read-Only resources, so we don't end up writing those + for res in server_obj['resources']: + if res['id'] in (0, 11, 12): + server_obj['resources'].remove(res) + data = '''{ + "kind": "instance", + "id": 0, + "resources": [ + { + "id": 2, + "kind": "singleResource", + "value": "101", + "type": "integer" + }, + { + "id": 3, + "kind": "singleResource", + "value": "1010", + "type": "integer" + }, + { + "id": 5, + "kind": "singleResource", + "value": "2000", + "type": "integer" + }, + { + "id": 6, + "kind": "singleResource", + "value": true, + "type": "boolean" + }, + { + "id": 7, + "kind": "singleResource", + "value": "U", + "type": "string" + } + ] + }''' + assert leshan.put(f'/clients/{endpoint}/1/0', data, uri_options = '&replace=false')['status'] == 'CHANGED(204)' + resp = leshan.get(f'/clients/{endpoint}/1/0') + assert resp['valid'] is True + found = 0 + for res in resp['content']['resources']: + if res['id'] == 2: + assert res['value'] == '101' + found += 1 + elif res['id'] == 3: + assert res['value'] == '1010' + found += 1 + elif res['id'] == 5: + assert res['value'] == '2000' + found += 1 + elif res['id'] == 6: + assert res['value'] is True + found += 1 + elif res['id'] == 7: + assert res['value'] == 'U' + found += 1 + assert found == 5 + assert leshan.put(f'/clients/{endpoint}/1/0', data = server_obj, uri_options = '&replace=true')['status'] == 'CHANGED(204)' + server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] + verify_server_object(server_obj) + leshan.format = fmt + +def verify_LightweightM2M_1_1_int_215(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-215 - Setting basic information in TLV format') + verify_setting_basic_in_format(shell, leshan, endpoint, 'TLV') + +def verify_LightweightM2M_1_1_int_220(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-220 - Setting basic information in JSON format') + verify_setting_basic_in_format(shell, leshan, endpoint, 'JSON') + +def verify_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: str): + logger.info('LightweightM2M-1.1-int-221 - Attempt to perform operations on Security') + assert leshan.read(endpoint, '0/0')['status'] == 'UNAUTHORIZED(401)' + assert leshan.write(endpoint, '0/0/0', 'coap://localhost')['status'] == 'UNAUTHORIZED(401)' + assert leshan.put_raw(f'/clients/{endpoint}/0/attributes?pmin=10')['status'] == 'UNAUTHORIZED(401)' + +def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode") + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) + host = lines[0] + assert 'coaps://' in host + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/2 -u8')) + mode = int(lines[0]) + assert mode == 0 + resp = leshan.get(f'/clients/{endpoint}') + assert resp["secure"] + +def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): + try: + # Generate randon device id and password (PSK key) + endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() + passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) + + + # Create device entries in Leshan and Bootstrap server + leshan_bootstrap.create_bs_device(endpoint, f'coaps://{LESHAN_IP}:{COAPS_PORT}', passwd) + leshan.create_psk_device(endpoint, passwd) + + # Allow engine to start & stop once. + time.sleep(2) + + # + # Verify PSK security using Bootstrap + # + + # Write bootsrap server information and PSK keys + shell.exec_command(f'lwm2m write 0/0/0 -s coaps://{LESHAN_IP}:{BOOTSTRAP_COAPS_PORT}') + shell.exec_command('lwm2m write 0/0/1 -b 1') + shell.exec_command('lwm2m write 0/0/2 -u8 0') + shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') + shell.exec_command(f'lwm2m write 0/0/5 -s {passwd}') + shell.exec_command(f'lwm2m start {endpoint} -b 1') + + + # + # Bootstrap Interface test cases + # LightweightM2M-1.1-int-0 (included) + # LightweightM2M-1.1-int-401 (included) + verify_LightweightM2M_1_1_int_1(shell, leshan, endpoint) + + # + # Registration Interface test cases (using PSK security) + # + verify_LightweightM2M_1_1_int_102(shell, leshan, endpoint) + # skip, not implemented verify_LightweightM2M_1_1_int_103() + verify_LightweightM2M_1_1_int_104(shell, leshan, endpoint) + # skip, included in 109: verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_108(leshan, endpoint) + verify_LightweightM2M_1_1_int_109(shell, leshan, endpoint) + + # + # Device management & Service Enablement Interface test cases + # + verify_LightweightM2M_1_1_int_201(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_203(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_204(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_205(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_211(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_212(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) + + shell.exec_command('lwm2m stop') + shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) + + finally: + # Remove device and bootstrap information + # Leshan does not accept non-secure connection if device information is provided with PSK + leshan.delete_device(endpoint) + leshan_bootstrap.delete_bs_device(endpoint) + + +def test_lwm2m_nosecure(shell: Shell, leshan, helperclient): + + # Allow engine to start & stop once. + time.sleep(2) + + # Generate randon device id and password (PSK key) + endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() + + # + # Registration Interface test cases (using Non-secure mode) + # + shell.exec_command(f'lwm2m write 0/0/0 -s coap://{LESHAN_IP}:{COAP_PORT}') + shell.exec_command('lwm2m write 0/0/1 -b 0') + shell.exec_command('lwm2m write 0/0/2 -u8 3') + shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') + shell.exec_command('lwm2m create 1/0') + shell.exec_command('lwm2m write 0/0/10 -u16 1') + shell.exec_command('lwm2m write 1/0/0 -u16 1') + shell.exec_command('lwm2m write 1/0/1 -u32 86400') + shell.exec_command(f'lwm2m start {endpoint} -b 0') + shell._device.readlines_until(regex=f"RD Client started with endpoint '{endpoint}'", timeout=10.0) + + verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_105(shell, leshan, endpoint, helperclient) # needs no-security + verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_220(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_221(shell, leshan, endpoint) + + # All done + shell.exec_command('lwm2m stop') + shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) diff --git a/tests/net/lib/lwm2m/interop/requirements.txt b/tests/net/lib/lwm2m/interop/requirements.txt new file mode 100644 index 00000000000..38c501218ee --- /dev/null +++ b/tests/net/lib/lwm2m/interop/requirements.txt @@ -0,0 +1 @@ +CoAPthon3 diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c new file mode 100644 index 00000000000..1278d807b71 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 Linaro Limited + * Copyright (c) 2017-2019 Foundries.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_MODULE_NAME net_lwm2m_client_app +#define LOG_LEVEL LOG_LEVEL_DBG + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); +#include +#include +#include +#include +#include +#include + +#define APP_BANNER "Run LWM2M client" + +#define WAIT_TIME K_SECONDS(10) +#define CONNECT_TIME K_SECONDS(10) + +#define NAME "Zephyr" +#define MODEL "client-1" +#define SERIAL "serial-1" +#define VERSION "1.2.3" + +static struct lwm2m_ctx client; + +static int device_reboot_cb(uint16_t obj_inst_id, + uint8_t *args, uint16_t args_len) +{ + LOG_INF("DEVICE: REBOOT"); + return 0; +} + + +static int lwm2m_setup(void) +{ + /* setup DEVICE object */ + + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 0), NAME, sizeof(NAME), + sizeof(NAME), LWM2M_RES_DATA_FLAG_RO); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 1), MODEL, sizeof(MODEL), + sizeof(MODEL), LWM2M_RES_DATA_FLAG_RO); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 2), SERIAL, sizeof(SERIAL), + sizeof(SERIAL), LWM2M_RES_DATA_FLAG_RO); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 3), VERSION, sizeof(VERSION), + sizeof(VERSION), LWM2M_RES_DATA_FLAG_RO); + lwm2m_register_exec_callback(&LWM2M_OBJ(3, 0, 4), device_reboot_cb); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 17), CONFIG_BOARD, sizeof(CONFIG_BOARD), + sizeof(CONFIG_BOARD), LWM2M_RES_DATA_FLAG_RO); + + return 0; +} + +static void rd_client_event(struct lwm2m_ctx *client, + enum lwm2m_rd_client_event client_event) +{ + switch (client_event) { + + case LWM2M_RD_CLIENT_EVENT_NONE: + /* do nothing */ + break; + + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: + LOG_DBG("Bootstrap registration failure!"); + break; + + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE: + LOG_DBG("Bootstrap registration complete"); + break; + + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE: + LOG_DBG("Bootstrap transfer complete"); + break; + + case LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE: + LOG_DBG("Registration failure!"); + break; + + case LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE: + LOG_DBG("Registration complete"); + break; + + case LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT: + LOG_DBG("Registration timeout!"); + break; + + case LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE: + LOG_DBG("Registration update complete"); + break; + + case LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE: + LOG_DBG("Deregister failure!"); + break; + + case LWM2M_RD_CLIENT_EVENT_DISCONNECT: + LOG_DBG("Disconnected"); + break; + + case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF: + LOG_DBG("Queue mode RX window closed"); + break; + + case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED: + LOG_DBG("LwM2M engine suspended"); + break; + + case LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR: + LOG_ERR("LwM2M engine reported a network error."); + lwm2m_rd_client_stop(client, rd_client_event, true); + break; + + case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: + LOG_DBG("Registration update"); + break; + } +} + +static void observe_cb(enum lwm2m_observe_event event, + struct lwm2m_obj_path *path, void *user_data) +{ + char buf[LWM2M_MAX_PATH_STR_SIZE]; + + switch (event) { + + case LWM2M_OBSERVE_EVENT_OBSERVER_ADDED: + LOG_INF("Observer added for %s", lwm2m_path_log_buf(buf, path)); + break; + + case LWM2M_OBSERVE_EVENT_OBSERVER_REMOVED: + LOG_INF("Observer removed for %s", lwm2m_path_log_buf(buf, path)); + break; + + case LWM2M_OBSERVE_EVENT_NOTIFY_ACK: + LOG_INF("Notify acknowledged for %s", lwm2m_path_log_buf(buf, path)); + break; + + case LWM2M_OBSERVE_EVENT_NOTIFY_TIMEOUT: + LOG_INF("Notify timeout for %s, trying registration update", + lwm2m_path_log_buf(buf, path)); + + lwm2m_rd_client_update(); + break; + } +} + +int main(void) +{ + int ret; + +#if defined(CONFIG_BOARD_NATIVE_POSIX) + srandom(time(NULL)); +#endif + + ret = lwm2m_setup(); + if (ret < 0) { + LOG_ERR("Cannot setup LWM2M fields (%d)", ret); + return 0; + } + + client.tls_tag = 1; + + lwm2m_rd_client_start(&client, CONFIG_BOARD, 0, rd_client_event, observe_cb); + lwm2m_rd_client_stop(&client, rd_client_event, false); + + return 0; +} diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml new file mode 100644 index 00000000000..aeba64748df --- /dev/null +++ b/tests/net/lib/lwm2m/interop/testcase.yaml @@ -0,0 +1,14 @@ +tests: + net.lwm2m.interop: + harness: pytest + timeout: 300 + slow: true + integration_platforms: + - native_posix + platform_allow: + - native_posix + - qemu_cortex_m3 + tags: + - testing + - pytest + - shell From 83de11d9f39f89bc7456b41ada307358abb1f043 Mon Sep 17 00:00:00 2001 From: Jeff Daly Date: Thu, 10 Aug 2023 15:44:36 -0400 Subject: [PATCH 1092/4498] Microchip MEC172X: Rework GPIO definitions to separate package types. MEC172X has 2 package sizes with additional pins on the -LJ package. This commit separates the package-specific parts into different files. In addition, this patch removes unnecessary package-specific enums in favor of calculated offsets into the desired registers. Signed-off-by: Jeff Daly --- .../microchip_mec/mec172x/reg/gpio_pkg_lj.h | 17 + .../microchip_mec/mec172x/reg/gpio_pkg_sz.h | 21 + .../microchip_mec/mec172x/reg/mec172x_gpio.h | 514 +----------------- 3 files changed, 44 insertions(+), 508 deletions(-) create mode 100644 soc/arm/microchip_mec/mec172x/reg/gpio_pkg_lj.h create mode 100644 soc/arm/microchip_mec/mec172x/reg/gpio_pkg_sz.h diff --git a/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_lj.h b/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_lj.h new file mode 100644 index 00000000000..71e1c089f07 --- /dev/null +++ b/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_lj.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _MEC172X_GPIO_LJ_H +#define _MEC172X_GPIO_LJ_H + +#define MCHP_GPIO_PORT_A_BITMAP 0x7FFFFFFFu /* GPIO_0000 - 0036 GIRQ11 */ +#define MCHP_GPIO_PORT_B_BITMAP 0x7FFFFFFFu /* GPIO_0040 - 0076 GIRQ10 */ +#define MCHP_GPIO_PORT_C_BITMAP 0x3FFFFFF7u /* GPIO_0100 - 0136 GIRQ09 */ +#define MCHP_GPIO_PORT_D_BITMAP 0x3F67FFFFu /* GPIO_0140 - 0176 GIRQ08 */ +#define MCHP_GPIO_PORT_E_BITMAP 0x7FFFFFFFu /* GPIO_0200 - 0236 GIRQ12 */ +#define MCHP_GPIO_PORT_F_BITMAP 0x00003F7Fu /* GPIO_0240 - 0276 GIRQ26 */ + +#endif /* #ifndef _MEC172X_GPIO_LJ_H */ diff --git a/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_sz.h b/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_sz.h new file mode 100644 index 00000000000..bfd89788237 --- /dev/null +++ b/soc/arm/microchip_mec/mec172x/reg/gpio_pkg_sz.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _MEC172X_GPIO_SZ_H +#define _MEC172X_GPIO_SZ_H + +#include +#include + +/* MEC172XH-B0-SZ (144-pin) */ +#define MCHP_GPIO_PORT_A_BITMAP 0x7FFFFF9Du /* GPIO_0000 - 0036 GIRQ11 */ +#define MCHP_GPIO_PORT_B_BITMAP 0x7FFFFFFDu /* GPIO_0040 - 0076 GIRQ10 */ +#define MCHP_GPIO_PORT_C_BITMAP 0x07FFFCF7u /* GPIO_0100 - 0136 GIRQ09 */ +#define MCHP_GPIO_PORT_D_BITMAP 0x272EFFFFu /* GPIO_0140 - 0176 GIRQ08 */ +#define MCHP_GPIO_PORT_E_BITMAP 0x00DE00FFu /* GPIO_0200 - 0236 GIRQ12 */ +#define MCHP_GPIO_PORT_F_BITMAP 0x0000397Fu /* GPIO_0240 - 0276 GIRQ26 */ + +#endif /* #ifndef _MEC172X_GPIO_SZ_H */ diff --git a/soc/arm/microchip_mec/mec172x/reg/mec172x_gpio.h b/soc/arm/microchip_mec/mec172x/reg/mec172x_gpio.h index 82b53c4af00..39ed59d279d 100644 --- a/soc/arm/microchip_mec/mec172x/reg/mec172x_gpio.h +++ b/soc/arm/microchip_mec/mec172x/reg/mec172x_gpio.h @@ -10,49 +10,15 @@ #include #include +#if defined(CONFIG_SOC_MEC172X_NSZ) +#include "gpio_pkg_sz.h" +#elif defined(CONFIG_SOC_MEC172X_NLJ) +#include "gpio_pkg_lj.h" +#endif + #define NUM_MCHP_GPIO_PORTS 6u #define MAX_NUM_MCHP_GPIO (NUM_MCHP_GPIO_PORTS * 32u) -#define MCHP_GPIO_CTRL_OFS 0u -#define MCHP_GPIO_PARIN_OFS 0x0300u -#define MCHP_GPIO_PAROUT_OFS 0x0380u -#define MCHP_GPIO_LOCK_OFS 0x03e8u -#define MCHP_GPIO_CTRL2_OFS 0x0500u - -/* MEC172XH-B0-SZ (144-pin) */ -#define MCHP_GPIO_PORT_A_BITMAP 0x7FFFFF9Du /* GPIO_0000 - 0036 GIRQ11 */ -#define MCHP_GPIO_PORT_B_BITMAP 0x7FFFFFFDu /* GPIO_0040 - 0076 GIRQ10 */ -#define MCHP_GPIO_PORT_C_BITMAP 0x07FFFCF7u /* GPIO_0100 - 0136 GIRQ09 */ -#define MCHP_GPIO_PORT_D_BITMAP 0x272EFFFFu /* GPIO_0140 - 0176 GIRQ08 */ -#define MCHP_GPIO_PORT_E_BITMAP 0x00DE00FFu /* GPIO_0200 - 0236 GIRQ12 */ -#define MCHP_GPIO_PORT_F_BITMAP 0x0000397Fu /* GPIO_0240 - 0276 GIRQ26 */ - -#define MCHP_GPIO_PORT_A_DRVSTR_BITMAP 0x7FFFFF9Du -#define MCHP_GPIO_PORT_B_DRVSTR_BITMAP 0x7FFFFFFDu -#define MCHP_GPIO_PORT_C_DRVSTR_BITMAP 0x07FFFCF7u -#define MCHP_GPIO_PORT_D_DRVSTR_BITMAP 0x272EFFFFu -#define MCHP_GPIO_PORT_E_DRVSTR_BITMAP 0x00DE00FFu -#define MCHP_GPIO_PORT_F_DRVSTR_BITMAP 0x0000397Fu - -/* 32-bit Control register */ -#define MCHP_GPIO_CTRL_MASK 0x0101ffffu -/* bits[15:0] of Control register */ -#define MCHP_GPIO_CTRL_CFG_MASK 0xffffu - -/* Disable interrupt detect and pad */ -#define MCHP_GPIO_CTRL_DIS_PIN 0x8040u - -#define MCHP_GPIO_CTRL_DFLT 0x8040u -#define MCHP_GPIO_CTRL_DFLT_MASK 0xffffu - -#define GPIO000_CTRL_DFLT 0x1040u -#define GPIO062_CTRL_DFLT 0x8240u -#define GPIO116_CTRL_DFLT 0x0041u -#define GPIO161_CTRL_DFLT 0x1040u -#define GPIO162_CTRL_DFLT 0x1040u -#define GPIO170_CTRL_DFLT 0x0041u -#define GPIO234_CTRL_DFLT 0x1040u - /* GPIO Control register field definitions. */ /* bits[1:0] internal pull up/down selection */ @@ -156,7 +122,6 @@ * 10b = 8mA * 11b = 12mA */ -#define MCHP_GPIO_CTRL2_OFFSET 0x0500u #define MCHP_GPIO_CTRL2_SLEW_POS 0 #define MCHP_GPIO_CTRL2_SLEW_MASK 0x01u #define MCHP_GPIO_CTRL2_SLEW_SLOW 0 @@ -173,149 +138,8 @@ extern "C" { #endif -/* GPIO pin numbers SZ (144-pin) package */ -enum mec_gpio_idx { - MCHP_GPIO_0000_ID = 0, - MCHP_GPIO_0002_ID = 2, - MCHP_GPIO_0003_ID, - MCHP_GPIO_0004_ID, - MCHP_GPIO_0007_ID = 7, - MCHP_GPIO_0010_ID, - MCHP_GPIO_0011_ID, - MCHP_GPIO_0012_ID, - MCHP_GPIO_0013_ID, - MCHP_GPIO_0014_ID, - MCHP_GPIO_0015_ID, - MCHP_GPIO_0016_ID, - MCHP_GPIO_0017_ID, - MCHP_GPIO_0020_ID, - MCHP_GPIO_0021_ID, - MCHP_GPIO_0022_ID, - MCHP_GPIO_0023_ID, - MCHP_GPIO_0024_ID, - MCHP_GPIO_0025_ID, - MCHP_GPIO_0026_ID, - MCHP_GPIO_0027_ID, - MCHP_GPIO_0030_ID, - MCHP_GPIO_0031_ID, - MCHP_GPIO_0032_ID, - MCHP_GPIO_0033_ID, - MCHP_GPIO_0034_ID, - MCHP_GPIO_0035_ID, - MCHP_GPIO_0036_ID, - MCHP_GPIO_0040_ID = 32, - MCHP_GPIO_0042_ID = 34, - MCHP_GPIO_0043_ID, - MCHP_GPIO_0044_ID, - MCHP_GPIO_0045_ID, - MCHP_GPIO_0046_ID, - MCHP_GPIO_0047_ID, - MCHP_GPIO_0050_ID, - MCHP_GPIO_0051_ID, - MCHP_GPIO_0052_ID, - MCHP_GPIO_0053_ID, - MCHP_GPIO_0054_ID, - MCHP_GPIO_0055_ID, - MCHP_GPIO_0056_ID, - MCHP_GPIO_0057_ID, - MCHP_GPIO_0060_ID, - MCHP_GPIO_0061_ID, - MCHP_GPIO_0062_ID, - MCHP_GPIO_0063_ID, - MCHP_GPIO_0064_ID, - MCHP_GPIO_0065_ID, - MCHP_GPIO_0066_ID, - MCHP_GPIO_0067_ID, - MCHP_GPIO_0070_ID, - MCHP_GPIO_0071_ID, - MCHP_GPIO_0072_ID, - MCHP_GPIO_0073_ID, - MCHP_GPIO_0074_ID, - MCHP_GPIO_0075_ID, - MCHP_GPIO_0076_ID, - MCHP_GPIO_0100_ID = 64, - MCHP_GPIO_0101_ID, - MCHP_GPIO_0102_ID, - MCHP_GPIO_0104_ID = 68, - MCHP_GPIO_0105_ID, - MCHP_GPIO_0106_ID, - MCHP_GPIO_0107_ID, - MCHP_GPIO_0112_ID = 74, - MCHP_GPIO_0113_ID, - MCHP_GPIO_0114_ID, - MCHP_GPIO_0115_ID, - MCHP_GPIO_0116_ID, - MCHP_GPIO_0117_ID, - MCHP_GPIO_0120_ID = 80, - MCHP_GPIO_0121_ID, - MCHP_GPIO_0122_ID, - MCHP_GPIO_0123_ID, - MCHP_GPIO_0124_ID, - MCHP_GPIO_0125_ID, - MCHP_GPIO_0126_ID, - MCHP_GPIO_0127_ID, - MCHP_GPIO_0130_ID, - MCHP_GPIO_0131_ID, - MCHP_GPIO_0132_ID, - MCHP_GPIO_0140_ID = 96, - MCHP_GPIO_0141_ID, - MCHP_GPIO_0142_ID, - MCHP_GPIO_0143_ID, - MCHP_GPIO_0144_ID, - MCHP_GPIO_0145_ID, - MCHP_GPIO_0146_ID, - MCHP_GPIO_0147_ID, - MCHP_GPIO_0150_ID, - MCHP_GPIO_0151_ID, - MCHP_GPIO_0152_ID, - MCHP_GPIO_0153_ID, - MCHP_GPIO_0154_ID, - MCHP_GPIO_0155_ID, - MCHP_GPIO_0156_ID, - MCHP_GPIO_0157_ID, - MCHP_GPIO_0161_ID = 113, - MCHP_GPIO_0162_ID, - MCHP_GPIO_0165_ID = 117, - MCHP_GPIO_0170_ID = 120, - MCHP_GPIO_0171_ID, - MCHP_GPIO_0175_ID = 125, - MCHP_GPIO_0200_ID = 128, - MCHP_GPIO_0201_ID, - MCHP_GPIO_0202_ID, - MCHP_GPIO_0203_ID, - MCHP_GPIO_0204_ID, - MCHP_GPIO_0205_ID, - MCHP_GPIO_0206_ID, - MCHP_GPIO_0207_ID, - MCHP_GPIO_0221_ID = 145, - MCHP_GPIO_0222_ID, - MCHP_GPIO_0223_ID, - MCHP_GPIO_0224_ID, - MCHP_GPIO_0226_ID = 150, - MCHP_GPIO_0227_ID, - MCHP_GPIO_0240_ID = 160, - MCHP_GPIO_0241_ID, - MCHP_GPIO_0242_ID, - MCHP_GPIO_0243_ID, - MCHP_GPIO_0244_ID, - MCHP_GPIO_0245_ID, - MCHP_GPIO_0246_ID, - MCHP_GPIO_0254_ID = 172, - MCHP_GPIO_0255_ID, - MCHP_GPIO_MAX_ID -}; - #define MCHP_GPIO_PIN2PORT(pin_id) ((uint32_t)(pin_id) >> 5) -#define MAX_MCHP_GPIO_BANK 6u -#define MCHP_GPIO_LOCK5_IDX 0u -#define MCHP_GPIO_LOCK4_IDX 1u -#define MCHP_GPIO_LOCK3_IDX 2u -#define MCHP_GPIO_LOCK2_IDX 3u -#define MCHP_GPIO_LOCK1_IDX 4u -#define MCHP_GPIO_LOCK0_IDX 5u -#define MCHP_GPIO_LOCK_MAX_IDX 6u - /* Helper functions */ enum mchp_gpio_pud { MCHP_GPIO_NO_PUD = 0, @@ -393,332 +217,6 @@ enum mchp_gpio_drv_str { MCHP_GPIO_DRV_STR_12MA, }; -/** @brief GPIO control registers by pin name */ -struct gpio_ctrl_regs { - volatile uint32_t CTRL_0000; - uint32_t RSVD1[1]; - volatile uint32_t CTRL_0002; - volatile uint32_t CTRL_0003; - volatile uint32_t CTRL_0004; - uint32_t RSVD2[2]; - volatile uint32_t CTRL_0007; - volatile uint32_t CTRL_0010; - volatile uint32_t CTRL_0011; - volatile uint32_t CTRL_0012; - volatile uint32_t CTRL_0013; - volatile uint32_t CTRL_0014; - volatile uint32_t CTRL_0015; - volatile uint32_t CTRL_0016; - volatile uint32_t CTRL_0017; - volatile uint32_t CTRL_0020; - volatile uint32_t CTRL_0021; - volatile uint32_t CTRL_0022; - volatile uint32_t CTRL_0023; - volatile uint32_t CTRL_0024; - volatile uint32_t CTRL_0025; - volatile uint32_t CTRL_0026; - volatile uint32_t CTRL_0027; - volatile uint32_t CTRL_0030; - volatile uint32_t CTRL_0031; - volatile uint32_t CTRL_0032; - volatile uint32_t CTRL_0033; - volatile uint32_t CTRL_0034; - volatile uint32_t CTRL_0035; - volatile uint32_t CTRL_0036; - uint32_t RSVD3[1]; - volatile uint32_t CTRL_0040; - uint32_t RSVD4[1]; - volatile uint32_t CTRL_0042; - volatile uint32_t CTRL_0043; - volatile uint32_t CTRL_0044; - volatile uint32_t CTRL_0045; - volatile uint32_t CTRL_0046; - volatile uint32_t CTRL_0047; - volatile uint32_t CTRL_0050; - volatile uint32_t CTRL_0051; - volatile uint32_t CTRL_0052; - volatile uint32_t CTRL_0053; - volatile uint32_t CTRL_0054; - volatile uint32_t CTRL_0055; - volatile uint32_t CTRL_0056; - volatile uint32_t CTRL_0057; - volatile uint32_t CTRL_0060; - volatile uint32_t CTRL_0061; - volatile uint32_t CTRL_0062; - volatile uint32_t CTRL_0063; - volatile uint32_t CTRL_0064; - volatile uint32_t CTRL_0065; - volatile uint32_t CTRL_0066; - volatile uint32_t CTRL_0067; - volatile uint32_t CTRL_0070; - volatile uint32_t CTRL_0071; - volatile uint32_t CTRL_0072; - volatile uint32_t CTRL_0073; - volatile uint32_t CTRL_0074; - volatile uint32_t CTRL_0075; - volatile uint32_t CTRL_0076; - uint32_t RSVD5[1]; - volatile uint32_t CTRL_0100; - volatile uint32_t CTRL_0101; - volatile uint32_t CTRL_0102; - uint32_t RSVD6[1]; - volatile uint32_t CTRL_0104; - volatile uint32_t CTRL_0105; - volatile uint32_t CTRL_0106; - volatile uint32_t CTRL_0107; - uint32_t RSVD7[2]; - volatile uint32_t CTRL_0112; - volatile uint32_t CTRL_0113; - volatile uint32_t CTRL_0114; - volatile uint32_t CTRL_0115; - volatile uint32_t CTRL_0116; - volatile uint32_t CTRL_0117; - volatile uint32_t CTRL_0120; - volatile uint32_t CTRL_0121; - volatile uint32_t CTRL_0122; - volatile uint32_t CTRL_0123; - volatile uint32_t CTRL_0124; - volatile uint32_t CTRL_0125; - volatile uint32_t CTRL_0126; - volatile uint32_t CTRL_0127; - volatile uint32_t CTRL_0130; - volatile uint32_t CTRL_0131; - volatile uint32_t CTRL_0132; - uint32_t RSVD9[5]; - volatile uint32_t CTRL_0140; - volatile uint32_t CTRL_0141; - volatile uint32_t CTRL_0142; - volatile uint32_t CTRL_0143; - volatile uint32_t CTRL_0144; - volatile uint32_t CTRL_0145; - volatile uint32_t CTRL_0146; - volatile uint32_t CTRL_0147; - volatile uint32_t CTRL_0150; - volatile uint32_t CTRL_0151; - volatile uint32_t CTRL_0152; - volatile uint32_t CTRL_0153; - volatile uint32_t CTRL_0154; - volatile uint32_t CTRL_0155; - volatile uint32_t CTRL_0156; - volatile uint32_t CTRL_0157; - uint32_t RSVD10[1]; - volatile uint32_t CTRL_0161; - volatile uint32_t CTRL_0162; - uint32_t RSVD11[2]; - volatile uint32_t CTRL_0165; - uint32_t RSVD12[2]; - volatile uint32_t CTRL_0170; - volatile uint32_t CTRL_0171; - uint32_t RSVD13[3]; - volatile uint32_t CTRL_0175; - uint32_t RSVD14[2]; - volatile uint32_t CTRL_0200; - volatile uint32_t CTRL_0201; - volatile uint32_t CTRL_0202; - volatile uint32_t CTRL_0203; - volatile uint32_t CTRL_0204; - volatile uint32_t CTRL_0205; - volatile uint32_t CTRL_0206; - volatile uint32_t CTRL_0207; - uint32_t RSVD15[9]; - volatile uint32_t CTRL_0221; - volatile uint32_t CTRL_0222; - volatile uint32_t CTRL_0223; - volatile uint32_t CTRL_0224; - uint32_t RSVD16[1]; - volatile uint32_t CTRL_0226; - volatile uint32_t CTRL_0227; - uint32_t RSVD17[8]; - volatile uint32_t CTRL_0240; - volatile uint32_t CTRL_0241; - volatile uint32_t CTRL_0242; - volatile uint32_t CTRL_0243; - volatile uint32_t CTRL_0244; - volatile uint32_t CTRL_0245; - volatile uint32_t CTRL_0246; - uint32_t RSVD18[5]; - volatile uint32_t CTRL_0254; - volatile uint32_t CTRL_0255; -}; - -/** @brief GPIO Control 2 registers by pin name */ -struct gpio_ctrl2_regs { - volatile uint32_t CTRL2_0000; - uint32_t RSVD1[1]; - volatile uint32_t CTRL2_0002; - volatile uint32_t CTRL2_0003; - volatile uint32_t CTRL2_0004; - uint32_t RSVD2[2]; - volatile uint32_t CTRL2_0007; - volatile uint32_t CTRL2_0010; - volatile uint32_t CTRL2_0011; - volatile uint32_t CTRL2_0012; - volatile uint32_t CTRL2_0013; - volatile uint32_t CTRL2_0014; - volatile uint32_t CTRL2_0015; - volatile uint32_t CTRL2_0016; - volatile uint32_t CTRL2_0017; - volatile uint32_t CTRL2_0020; - volatile uint32_t CTRL2_0021; - volatile uint32_t CTRL2_0022; - volatile uint32_t CTRL2_0023; - volatile uint32_t CTRL2_0024; - volatile uint32_t CTRL2_0025; - volatile uint32_t CTRL2_0026; - volatile uint32_t CTRL2_0027; - volatile uint32_t CTRL2_0030; - volatile uint32_t CTRL2_0031; - volatile uint32_t CTRL2_0032; - volatile uint32_t CTRL2_0033; - volatile uint32_t CTRL2_0034; - volatile uint32_t CTRL2_0035; - volatile uint32_t CTRL2_0036; - uint32_t RSVD3[1]; - volatile uint32_t CTRL2_0040; - uint32_t RSVD4[1]; - volatile uint32_t CTRL2_0042; - volatile uint32_t CTRL2_0043; - volatile uint32_t CTRL2_0044; - volatile uint32_t CTRL2_0045; - volatile uint32_t CTRL2_0046; - volatile uint32_t CTRL2_0047; - volatile uint32_t CTRL2_0050; - volatile uint32_t CTRL2_0051; - volatile uint32_t CTRL2_0052; - volatile uint32_t CTRL2_0053; - volatile uint32_t CTRL2_0054; - volatile uint32_t CTRL2_0055; - volatile uint32_t CTRL2_0056; - volatile uint32_t CTRL2_0057; - volatile uint32_t CTRL2_0060; - volatile uint32_t CTRL2_0061; - volatile uint32_t CTRL2_0062; - volatile uint32_t CTRL2_0063; - volatile uint32_t CTRL2_0064; - volatile uint32_t CTRL2_0065; - volatile uint32_t CTRL2_0066; - volatile uint32_t CTRL2_0067; - volatile uint32_t CTRL2_0070; - volatile uint32_t CTRL2_0071; - volatile uint32_t CTRL2_0072; - volatile uint32_t CTRL2_0073; - volatile uint32_t CTRL2_0074; - volatile uint32_t CTRL2_0075; - volatile uint32_t CTRL2_0076; - uint32_t RSVD5[1]; - volatile uint32_t CTRL2_0100; - volatile uint32_t CTRL2_0101; - volatile uint32_t CTRL2_0102; - uint32_t RSVD6[1]; - volatile uint32_t CTRL2_0104; - volatile uint32_t CTRL2_0105; - volatile uint32_t CTRL2_0106; - volatile uint32_t CTRL2_0107; - uint32_t RSVD7[2]; - volatile uint32_t CTRL2_0112; - volatile uint32_t CTRL2_0113; - volatile uint32_t CTRL2_0114; - volatile uint32_t CTRL2_0115; - volatile uint32_t CTRL2_0116; - volatile uint32_t CTRL2_0117; - volatile uint32_t CTRL2_0120; - volatile uint32_t CTRL2_0121; - volatile uint32_t CTRL2_0122; - volatile uint32_t CTRL2_0123; - volatile uint32_t CTRL2_0124; - volatile uint32_t CTRL2_0125; - volatile uint32_t CTRL2_0126; - volatile uint32_t CTRL2_0127; - volatile uint32_t CTRL2_0130; - volatile uint32_t CTRL2_0131; - volatile uint32_t CTRL2_0132; - uint32_t RSVD9[5]; - volatile uint32_t CTRL2_0140; - volatile uint32_t CTRL2_0141; - volatile uint32_t CTRL2_0142; - volatile uint32_t CTRL2_0143; - volatile uint32_t CTRL2_0144; - volatile uint32_t CTRL2_0145; - volatile uint32_t CTRL2_0146; - volatile uint32_t CTRL2_0147; - volatile uint32_t CTRL2_0150; - volatile uint32_t CTRL2_0151; - volatile uint32_t CTRL2_0152; - volatile uint32_t CTRL2_0153; - volatile uint32_t CTRL2_0154; - volatile uint32_t CTRL2_0155; - volatile uint32_t CTRL2_0156; - volatile uint32_t CTRL2_0157; - uint32_t RSVD10[1]; - volatile uint32_t CTRL2_0161; - volatile uint32_t CTRL2_0162; - uint32_t RSVD11[2]; - volatile uint32_t CTRL2_0165; - uint32_t RSVD12[2]; - volatile uint32_t CTRL2_0170; - volatile uint32_t CTRL2_0171; - uint32_t RSVD13[3]; - volatile uint32_t CTRL2_0175; - uint32_t RSVD14[2]; - volatile uint32_t CTRL2_0200; - volatile uint32_t CTRL2_0201; - volatile uint32_t CTRL2_0202; - volatile uint32_t CTRL2_0203; - volatile uint32_t CTRL2_0204; - volatile uint32_t CTRL2_0205; - volatile uint32_t CTRL2_0206; - volatile uint32_t CTRL2_0207; - uint32_t RSVD15[9]; - volatile uint32_t CTRL2_0221; - volatile uint32_t CTRL2_0222; - volatile uint32_t CTRL2_0223; - volatile uint32_t CTRL2_0224; - uint32_t RSVD16[1]; - volatile uint32_t CTRL2_0226; - volatile uint32_t CTRL2_0227; - uint32_t RSVD17[8]; - volatile uint32_t CTRL2_0240; - volatile uint32_t CTRL2_0241; - volatile uint32_t CTRL2_0242; - volatile uint32_t CTRL2_0243; - volatile uint32_t CTRL2_0244; - volatile uint32_t CTRL2_0245; - volatile uint32_t CTRL2_0246; - uint32_t RSVD18[5]; - volatile uint32_t CTRL2_0254; - volatile uint32_t CTRL2_0255; -}; - -/** @brief GPIO Parallel Input register. 32 GPIO pins per bank */ -struct gpio_parin_regs { - volatile uint32_t PARIN0; - volatile uint32_t PARIN1; - volatile uint32_t PARIN2; - volatile uint32_t PARIN3; - volatile uint32_t PARIN4; - volatile uint32_t PARIN5; -}; - -/** @brief GPIO Parallel Output register. 32 GPIO pins per bank */ -struct gpio_parout_regs { - volatile uint32_t PAROUT0; - volatile uint32_t PAROUT1; - volatile uint32_t PAROUT2; - volatile uint32_t PAROUT3; - volatile uint32_t PAROUT4; - volatile uint32_t PAROUT5; -}; - -/** @brief GPIO Lock registers. 32 GPIO pins per bank. Write-once bits */ -struct gpio_lock_regs { - volatile uint32_t LOCK5; - volatile uint32_t LOCK4; - volatile uint32_t LOCK3; - volatile uint32_t LOCK2; - volatile uint32_t LOCK1; - volatile uint32_t LOCK0; -}; - #ifdef __cplusplus } #endif From 814864388122de1ccfbe5cb7f59aec5f6066fd6c Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Fri, 18 Aug 2023 16:58:27 +0300 Subject: [PATCH 1093/4498] ipm: imx: send firmware ready reply to check for fw boot completion Send a fw ready reply message as soon as possible. This is usually used on host side which is waiting for this message in order to establish the communication with the remote processor - see imx_dsp_rproc driver from Linux. This can be enabled by IPM_IMX_FW_READY_REPLY config, which is by default N. Set CONFIG_IPM_IMX_FW_READY_REPLY as Y for openamp_rsc_table sample, running on nxp_adsp_imx8m. Signed-off-by: Iuliana Prodan --- drivers/ipm/Kconfig.imx | 6 ++++++ drivers/ipm/ipm_imx.c | 16 ++++++++++++++++ .../openamp_rsc_table/boards/nxp_adsp_imx8m.conf | 1 + 3 files changed, 23 insertions(+) diff --git a/drivers/ipm/Kconfig.imx b/drivers/ipm/Kconfig.imx index 503d32b708c..f945483f0be 100644 --- a/drivers/ipm/Kconfig.imx +++ b/drivers/ipm/Kconfig.imx @@ -64,3 +64,9 @@ config IPM_IMX_MAX_ID_VAL default 1 if IPM_IMX_MAX_DATA_SIZE_8 default 0 if IPM_IMX_MAX_DATA_SIZE_16 depends on IPM_IMX || IPM_IMX_REV2 + +config IPM_IMX_FW_READY_REPLY + bool "Send FW_READY reply message" + depends on IPM_IMX || IPM_IMX_REV2 + help + Send FW_READY reply to check for FW boot completion diff --git a/drivers/ipm/ipm_imx.c b/drivers/ipm/ipm_imx.c index c38117cbde5..65e525f815a 100644 --- a/drivers/ipm/ipm_imx.c +++ b/drivers/ipm/ipm_imx.c @@ -321,6 +321,22 @@ static int imx_mu_init(const struct device *dev) MU_Init(MU(config)); config->irq_config_func(dev); +#if defined(CONFIG_IPM_IMX_FW_READY_REPLY) + /* Send FW_READY reply message - this is used on host side, + * for handshake communication. + * + * An example is in Linux, imx_dsp_rproc driver, where + * after starting the remote processor, the host is waiting for a + * FW_READY reply. + */ + MU_Type * base = MU(config); + + MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | + kMU_GenInt1InterruptTrigger | + kMU_GenInt2InterruptTrigger | + kMU_GenInt3InterruptTrigger); +#endif + return 0; } diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf index 0f7274227ce..01dd4f8ca3f 100644 --- a/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf +++ b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf @@ -2,3 +2,4 @@ CONFIG_LOG_PRINTK=n CONFIG_IPM_IMX_MAX_DATA_SIZE_16=n CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y CONFIG_OPENAMP_WITH_DCACHE=y +CONFIG_IPM_IMX_FW_READY_REPLY=y From 6c4b9c9933fe60665c418a1754268ed4c0f40045 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 25 Sep 2023 14:52:21 +0200 Subject: [PATCH 1094/4498] bluetooth: tester: AICS BTP event Enhance AICS BTP Events Functionality for invalid behavior tests. Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/src/btp/btp_aics.h | 28 ++++-- tests/bluetooth/tester/src/btp_aics.c | 111 +++++++++++++++++++--- 2 files changed, 121 insertions(+), 18 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_aics.h b/tests/bluetooth/tester/src/btp/btp_aics.h index 0f3cba97a0e..8057f9a4a21 100644 --- a/tests/bluetooth/tester/src/btp/btp_aics.h +++ b/tests/bluetooth/tester/src/btp/btp_aics.h @@ -20,13 +20,15 @@ struct btp_aics_instance { extern struct bt_aics_cb aics_client_cb; extern struct btp_aics_instance aics_client_instance; extern struct btp_aics_instance aics_server_instance; -void btp_send_aics_state_changed_ev(struct bt_conn *conn); -void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uint8_t mode); -void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t units, int8_t minimum, - int8_t maximum); -void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t input_type); -void btp_send_aics_status_ev(struct bt_conn *conn, bool active); -void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t data_len, char *description); +void btp_send_aics_state_ev(struct bt_conn *conn, uint8_t att_status, int8_t gain, uint8_t mute, + uint8_t mode); +void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t att_status, uint8_t units, + int8_t minimum, int8_t maximum); +void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t att_status, uint8_t input_type); +void btp_send_aics_status_ev(struct bt_conn *conn, uint8_t att_status, bool active); +void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t att_status, uint8_t data_len, + char *description); +void btp_send_aics_procedure_ev(struct bt_conn *conn, uint8_t att_status, uint8_t opcode); #define BTP_AICS_READ_SUPPORTED_COMMANDS 0x01 struct btp_aics_read_supported_commands_rp { @@ -98,6 +100,7 @@ struct btp_aics_desc_cmd { #define BTP_AICS_STATE_EV 0x80 struct btp_aics_state_ev { bt_addr_le_t address; + uint8_t att_status; int8_t gain; uint8_t mute; uint8_t mode; @@ -106,6 +109,7 @@ struct btp_aics_state_ev { #define BTP_GAIN_SETTING_PROPERTIES_EV 0x81 struct btp_gain_setting_properties_ev { bt_addr_le_t address; + uint8_t att_status; uint8_t units; int8_t minimum; int8_t maximum; @@ -114,18 +118,28 @@ struct btp_gain_setting_properties_ev { #define BTP_AICS_INPUT_TYPE_EV 0x82 struct btp_aics_input_type_ev { bt_addr_le_t address; + uint8_t att_status; uint8_t input_type; } __packed; #define BTP_AICS_STATUS_EV 0x83 struct btp_aics_status_ev { bt_addr_le_t address; + uint8_t att_status; bool active; } __packed; #define BTP_AICS_DESCRIPTION_EV 0x84 struct btp_aics_description_ev { bt_addr_le_t address; + uint8_t att_status; uint8_t data_len; char data[0]; } __packed; + +#define BTP_AICS_PROCEDURE_EV 0x85 +struct btp_aics_procedure_ev { + bt_addr_le_t address; + uint8_t att_status; + uint8_t opcode; +} __packed; diff --git a/tests/bluetooth/tester/src/btp_aics.c b/tests/bluetooth/tester/src/btp_aics.c index 035f88fbbb2..e3a1ad106df 100644 --- a/tests/bluetooth/tester/src/btp_aics.c +++ b/tests/bluetooth/tester/src/btp_aics.c @@ -65,12 +65,14 @@ static uint8_t aics_supported_commands(const void *cmd, uint16_t cmd_len, void * return BTP_STATUS_SUCCESS; } -void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uint8_t mode) +void btp_send_aics_state_ev(struct bt_conn *conn, uint8_t att_status, int8_t gain, uint8_t mute, + uint8_t mode) { struct btp_aics_state_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.gain = gain; ev.mute = mute; ev.mode = mode; @@ -78,13 +80,14 @@ void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uin tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_STATE_EV, &ev, sizeof(ev)); } -void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t units, int8_t minimum, - int8_t maximum) +void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t att_status, uint8_t units, + int8_t minimum, int8_t maximum) { struct btp_gain_setting_properties_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.units = units; ev.minimum = minimum; ev.maximum = maximum; @@ -92,29 +95,32 @@ void btp_send_gain_setting_properties_ev(struct bt_conn *conn, uint8_t units, in tester_event(BTP_SERVICE_ID_AICS, BTP_GAIN_SETTING_PROPERTIES_EV, &ev, sizeof(ev)); } -void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t input_type) +void btp_send_aics_input_type_event(struct bt_conn *conn, uint8_t att_status, uint8_t input_type) { struct btp_aics_input_type_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.input_type = input_type; tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_INPUT_TYPE_EV, &ev, sizeof(ev)); } -void btp_send_aics_status_ev(struct bt_conn *conn, bool active) +void btp_send_aics_status_ev(struct bt_conn *conn, uint8_t att_status, bool active) { struct btp_aics_status_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.active = active; tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_STATUS_EV, &ev, sizeof(ev)); } -void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t data_len, char *description) +void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t att_status, uint8_t data_len, + char *description) { struct btp_aics_description_ev *ev; @@ -124,12 +130,25 @@ void btp_send_aics_description_ev(struct bt_conn *conn, uint8_t data_len, char * bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); + ev->att_status = att_status; ev->data_len = data_len; memcpy(ev->data, description, data_len); tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_DESCRIPTION_EV, ev, sizeof(*ev) + data_len); } +void btp_send_aics_procedure_ev(struct bt_conn *conn, uint8_t att_status, uint8_t opcode) +{ + struct btp_aics_procedure_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.opcode = opcode; + + tester_event(BTP_SERVICE_ID_AICS, BTP_AICS_PROCEDURE_EV, &ev, sizeof(ev)); +} + static uint8_t aics_set_gain(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { const struct btp_aics_set_gain_cmd *cp = cmd; @@ -497,7 +516,15 @@ static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, uint8_t mu struct bt_conn *conn; bt_aics_client_conn_get(inst, &conn); - btp_send_aics_state_ev(conn, gain, mute, mode); + + if (err) { + if (err < 0) { + err = BT_ATT_ERR_UNLIKELY; + } + btp_send_aics_state_ev(conn, err, 0, 0, 0); + } else { + btp_send_aics_state_ev(conn, 0, gain, mute, mode); + } LOG_DBG("AICS state callback (%d)", err); } @@ -508,7 +535,7 @@ static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, i struct bt_conn *conn; bt_aics_client_conn_get(inst, &conn); - btp_send_gain_setting_properties_ev(conn, units, minimum, maximum); + btp_send_gain_setting_properties_ev(conn, err, units, minimum, maximum); LOG_DBG("AICS gain setting callback (%d)", err); } @@ -518,7 +545,7 @@ static void aics_input_type_cb(struct bt_aics *inst, int err, uint8_t input_type struct bt_conn *conn; bt_aics_client_conn_get(inst, &conn); - btp_send_aics_input_type_event(conn, input_type); + btp_send_aics_input_type_event(conn, err, input_type); LOG_DBG("AICS input type callback (%d)", err); } @@ -528,7 +555,7 @@ static void aics_status_cb(struct bt_aics *inst, int err, bool active) struct bt_conn *conn; bt_aics_client_conn_get(inst, &conn); - btp_send_aics_status_ev(conn, active); + btp_send_aics_status_ev(conn, err, active); LOG_DBG("AICS status callback (%d)", err); } @@ -539,17 +566,79 @@ static void aics_description_cb(struct bt_aics *inst, int err, char *description uint8_t data_len = strlen(description); bt_aics_client_conn_get(inst, &conn); - btp_send_aics_description_ev(conn, data_len, description); + btp_send_aics_description_ev(conn, err, data_len, description); LOG_DBG("AICS description callback (%d)", err); } +static void aics_set_gain_cb(struct bt_aics *inst, int err) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + + btp_send_aics_procedure_ev(conn, err, BTP_AICS_SET_GAIN); + + LOG_DBG("AICS set gain cb (%d)", err); +} + +static void aics_mute_cb(struct bt_aics *inst, int err) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + + btp_send_aics_procedure_ev(conn, err, BTP_AICS_MUTE); + + LOG_DBG("AICS mute cb (%d)", err); +} + +static void aics_unmute_cb(struct bt_aics *inst, int err) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + + btp_send_aics_procedure_ev(conn, err, BTP_AICS_UNMUTE); + + LOG_DBG("AICS unmute cb (%d)", err); +} + +static void aics_set_man_gain_cb(struct bt_aics *inst, int err) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + + btp_send_aics_procedure_ev(conn, err, BTP_AICS_MAN_GAIN_SET); + + LOG_DBG("AICS set manual gain cb (%d)", err); +} + +static void aics_set_auto_gain_cb(struct bt_aics *inst, int err) +{ + struct bt_conn *conn; + + bt_aics_client_conn_get(inst, &conn); + + btp_send_aics_procedure_ev(conn, err, BTP_AICS_AUTO_GAIN_SET); + + LOG_DBG("AICS set automatic gain cb (%d)", err); +} + struct bt_aics_cb aics_client_cb = { .state = aics_state_cb, .gain_setting = aics_gain_setting_cb, .type = aics_input_type_cb, .status = aics_status_cb, .description = aics_description_cb, +#if defined(CONFIG_BT_AICS_CLIENT) + .set_gain = aics_set_gain_cb, + .unmute = aics_unmute_cb, + .mute = aics_mute_cb, + .set_manual_mode = aics_set_man_gain_cb, + .set_auto_mode = aics_set_auto_gain_cb +#endif /* CONFIG_BT_AICS_CLIENT */ }; uint8_t tester_init_aics(void) From d20c95e5299dc7f62d5f3e11d8bd03a218f986c1 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 25 Sep 2023 15:14:58 +0200 Subject: [PATCH 1095/4498] bluetooth: tester: MICP BTP event Enhance AICS BTP events functionality for invalid behavior tests. Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/src/btp/btp_micp.h | 2 ++ tests/bluetooth/tester/src/btp_micp.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_micp.h b/tests/bluetooth/tester/src/btp/btp_micp.h index 000e879e5f4..02220917b08 100644 --- a/tests/bluetooth/tester/src/btp/btp_micp.h +++ b/tests/bluetooth/tester/src/btp/btp_micp.h @@ -31,6 +31,7 @@ struct btp_micp_mute_cmd { #define BTP_MICP_DISCOVERED_EV 0x80 struct btp_micp_discovered_ev { bt_addr_le_t address; + uint8_t att_status; uint16_t mute_handle; uint16_t state_handle; uint16_t gain_handle; @@ -43,5 +44,6 @@ struct btp_micp_discovered_ev { #define BTP_MICP_MUTE_STATE_EV 0x81 struct btp_micp_mute_state_ev { bt_addr_le_t address; + uint8_t att_status; uint8_t mute; } __packed; diff --git a/tests/bluetooth/tester/src/btp_micp.c b/tests/bluetooth/tester/src/btp_micp.c index 8e0d59ee4fb..b9e596f3c2c 100644 --- a/tests/bluetooth/tester/src/btp_micp.c +++ b/tests/bluetooth/tester/src/btp_micp.c @@ -50,12 +50,14 @@ extern struct bt_aics_cb aics_client_cb; #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ /* Microphone Control Profile */ -static void btp_send_micp_found_ev(struct bt_conn *conn, const struct chrc_handles *micp_handles) +static void btp_send_micp_found_ev(struct bt_conn *conn, uint8_t att_status, + const struct chrc_handles *micp_handles) { struct btp_micp_discovered_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.mute_handle = sys_cpu_to_le16(micp_handles->mute_handle); ev.state_handle = sys_cpu_to_le16(micp_handles->state_handle); ev.gain_handle = sys_cpu_to_le16(micp_handles->gain_handle); @@ -67,12 +69,13 @@ static void btp_send_micp_found_ev(struct bt_conn *conn, const struct chrc_handl tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_DISCOVERED_EV, &ev, sizeof(ev)); } -static void btp_send_micp_mute_state_ev(struct bt_conn *conn, uint8_t mute) +static void btp_send_micp_mute_state_ev(struct bt_conn *conn, uint8_t att_status, uint8_t mute) { struct btp_micp_mute_state_ev ev; bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.att_status = att_status; ev.mute = mute; tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_MUTE_STATE_EV, &ev, sizeof(ev)); @@ -83,7 +86,7 @@ static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, ui struct bt_conn *conn; bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); - btp_send_micp_mute_state_ev(conn, mute); + btp_send_micp_mute_state_ev(conn, err, mute); LOG_DBG("MICP Mute cb (%d)", err); } @@ -94,7 +97,7 @@ static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); - btp_send_micp_mute_state_ev(conn, mute_state); + btp_send_micp_mute_state_ev(conn, err, mute_state); LOG_DBG("MICP Mute Written cb (%d))", err); } @@ -105,7 +108,7 @@ static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, i uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); - btp_send_micp_mute_state_ev(conn, mute_state); + btp_send_micp_mute_state_ev(conn, err, mute_state); LOG_DBG("MICP Mute Unwritten cb (%d))", err); } @@ -144,7 +147,7 @@ static void micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ micp_handles.mute_handle = mic_ctlr->mute_handle; - btp_send_micp_found_ev(conn, &micp_handles); + btp_send_micp_found_ev(conn, err, &micp_handles); } static struct bt_micp_mic_ctlr_cb micp_cbs = { From 4e262bf83a00803a9455a6a0c58e5a8da2d72fb9 Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Mon, 25 Sep 2023 21:15:39 +0200 Subject: [PATCH 1096/4498] fix: drivers: remove redundant config checks in cmake files This commit does not introduce any functional change to the codebase. Just removes certain redundant checks from various CMakeLists.txt files in order to bring more coherence in the codebase. Signed-off-by: Jilay Pandya --- drivers/sensor/adt7310/CMakeLists.txt | 2 +- drivers/sensor/bmi08x/CMakeLists.txt | 6 +++--- drivers/sensor/ds18b20/CMakeLists.txt | 2 +- drivers/sensor/max31855/CMakeLists.txt | 2 +- drivers/sensor/pcnt_esp32/CMakeLists.txt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/adt7310/CMakeLists.txt b/drivers/sensor/adt7310/CMakeLists.txt index 91b77949d8b..ad7205182ed 100644 --- a/drivers/sensor/adt7310/CMakeLists.txt +++ b/drivers/sensor/adt7310/CMakeLists.txt @@ -2,5 +2,5 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_ADT7310 adt7310.c) +zephyr_library_sources(adt7310.c) zephyr_library_sources_ifdef(CONFIG_ADT7310_TRIGGER adt7310_trigger.c) diff --git a/drivers/sensor/bmi08x/CMakeLists.txt b/drivers/sensor/bmi08x/CMakeLists.txt index a3a13c2390a..0282cc73d20 100644 --- a/drivers/sensor/bmi08x/CMakeLists.txt +++ b/drivers/sensor/bmi08x/CMakeLists.txt @@ -2,8 +2,8 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_BMI08X bmi08x_accel.c) -zephyr_library_sources_ifdef(CONFIG_BMI08X bmi08x_gyro.c) -zephyr_library_sources_ifdef(CONFIG_BMI08X bmi08x.c) +zephyr_library_sources(bmi08x_accel.c) +zephyr_library_sources(bmi08x_gyro.c) +zephyr_library_sources(bmi08x.c) zephyr_library_sources_ifdef(CONFIG_BMI08X_ACCEL_TRIGGER bmi08x_accel_trigger.c) zephyr_library_sources_ifdef(CONFIG_BMI08X_GYRO_TRIGGER bmi08x_gyro_trigger.c) diff --git a/drivers/sensor/ds18b20/CMakeLists.txt b/drivers/sensor/ds18b20/CMakeLists.txt index d95181e74c1..e7a2a706f86 100644 --- a/drivers/sensor/ds18b20/CMakeLists.txt +++ b/drivers/sensor/ds18b20/CMakeLists.txt @@ -2,4 +2,4 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_DS18B20 ds18b20.c) +zephyr_library_sources(ds18b20.c) diff --git a/drivers/sensor/max31855/CMakeLists.txt b/drivers/sensor/max31855/CMakeLists.txt index 6ee5f2df493..b3ef4064956 100644 --- a/drivers/sensor/max31855/CMakeLists.txt +++ b/drivers/sensor/max31855/CMakeLists.txt @@ -2,4 +2,4 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_MAX31855 max31855.c) +zephyr_library_sources(max31855.c) diff --git a/drivers/sensor/pcnt_esp32/CMakeLists.txt b/drivers/sensor/pcnt_esp32/CMakeLists.txt index 3445c493e55..1dadd4c6cd8 100644 --- a/drivers/sensor/pcnt_esp32/CMakeLists.txt +++ b/drivers/sensor/pcnt_esp32/CMakeLists.txt @@ -2,4 +2,4 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_PCNT_ESP32 pcnt_esp32.c) +zephyr_library_sources(pcnt_esp32.c) From 14c92da96d5613b48610fa9bfe284528a814a4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 10:57:38 +0200 Subject: [PATCH 1097/4498] doc: stm32: Update all st.com links to use HTTPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While recent browsers seem to transparently try to use https for http://www.st.com/... URLs, they are effectively not working anymore, so use https://www.st.com/... URLs instead. curl http://www.st.com/en/evaluation-tools/nucleo-g070rb.html -m 5 -v * Trying 104.89.117.48:80... * Connected to www.st.com (104.89.117.48) port 80 (#0) > GET /en/evaluation-tools/nucleo-g070rb.html HTTP/1.1 > Host: www.st.com > User-Agent: curl/8.1.2 > Accept: */* > * Operation timed out after 5002 milliseconds with 0 bytes received * Closing connection 0 curl: (28) Operation timed out after 5002 milliseconds with 0 bytes received Signed-off-by: Benjamin Cabé --- boards/arm/96b_aerocore2/doc/index.rst | 2 +- boards/arm/96b_argonkey/doc/index.rst | 2 +- boards/arm/96b_carbon/doc/index.rst | 6 +++--- boards/arm/96b_stm32_sensor_mez/doc/index.rst | 4 ++-- boards/arm/arduino_giga_r1/doc/index.rst | 2 +- boards/arm/arduino_portenta_h7/doc/index.rst | 2 +- boards/arm/b_l072z_lrwan1/doc/index.rst | 4 ++-- boards/arm/black_f407ve/doc/index.rst | 2 +- boards/arm/blackpill_f401cc/doc/index.rst | 4 ++-- boards/arm/blackpill_f401ce/doc/index.rst | 4 ++-- boards/arm/blackpill_f411ce/doc/index.rst | 4 ++-- boards/arm/disco_l475_iot1/doc/index.rst | 6 +++--- boards/arm/dragino_lsn50/doc/index.rst | 4 ++-- boards/arm/dragino_nbsn95/doc/index.rst | 4 ++-- boards/arm/legend/doc/index.rst | 2 +- boards/arm/nucleo_c031c6/doc/index.rst | 2 +- boards/arm/nucleo_f070rb/doc/index.rst | 6 +++--- boards/arm/nucleo_f091rc/doc/index.rst | 6 +++--- boards/arm/nucleo_f103rb/doc/index.rst | 8 ++++---- boards/arm/nucleo_f207zg/doc/index.rst | 8 ++++---- boards/arm/nucleo_f302r8/doc/index.rst | 10 +++++----- boards/arm/nucleo_f303k8/doc/index.rst | 4 ++-- boards/arm/nucleo_f303re/doc/index.rst | 8 ++++---- boards/arm/nucleo_f334r8/doc/index.rst | 6 +++--- boards/arm/nucleo_f401re/doc/index.rst | 8 ++++---- boards/arm/nucleo_f410rb/doc/index.rst | 6 +++--- boards/arm/nucleo_f411re/doc/index.rst | 8 ++++---- boards/arm/nucleo_f412zg/doc/index.rst | 8 ++++---- boards/arm/nucleo_f413zh/doc/index.rst | 8 ++++---- boards/arm/nucleo_f429zi/doc/index.rst | 10 +++++----- boards/arm/nucleo_f446re/doc/index.rst | 8 ++++---- boards/arm/nucleo_f446ze/doc/index.rst | 6 +++--- boards/arm/nucleo_f746zg/doc/index.rst | 2 +- boards/arm/nucleo_f756zg/doc/index.rst | 2 +- boards/arm/nucleo_f767zi/doc/index.rst | 2 +- boards/arm/nucleo_g031k8/doc/index.rst | 2 +- boards/arm/nucleo_g031k8/support/openocd.cfg | 2 +- boards/arm/nucleo_g070rb/doc/index.rst | 6 +++--- boards/arm/nucleo_g071rb/doc/index.rst | 8 ++++---- boards/arm/nucleo_g0b1re/doc/index.rst | 8 ++++---- boards/arm/nucleo_g431rb/doc/index.rst | 4 ++-- boards/arm/nucleo_g474re/doc/index.rst | 4 ++-- boards/arm/nucleo_h563zi/doc/index.rst | 2 +- boards/arm/nucleo_h743zi/doc/index.rst | 2 +- boards/arm/nucleo_h753zi/doc/index.rst | 2 +- boards/arm/nucleo_l011k4/doc/index.rst | 2 +- boards/arm/nucleo_l011k4/support/openocd.cfg | 2 +- boards/arm/nucleo_l031k6/doc/index.rst | 2 +- boards/arm/nucleo_l031k6/support/openocd.cfg | 2 +- boards/arm/nucleo_l053r8/doc/index.rst | 6 +++--- boards/arm/nucleo_l053r8/support/openocd.cfg | 2 +- boards/arm/nucleo_l073rz/doc/index.rst | 6 +++--- boards/arm/nucleo_l073rz/support/openocd.cfg | 2 +- boards/arm/nucleo_l432kc/doc/index.rst | 8 ++++---- boards/arm/nucleo_l433rc_p/doc/index.rst | 2 +- boards/arm/nucleo_l476rg/doc/index.rst | 8 ++++---- boards/arm/nucleo_l496zg/doc/index.rst | 8 ++++---- boards/arm/nucleo_l4a6zg/doc/index.rst | 8 ++++---- boards/arm/nucleo_l4r5zi/doc/index.rst | 10 +++++----- boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst | 8 ++++---- boards/arm/nucleo_u575zi_q/doc/index.rst | 4 ++-- boards/arm/olimex_stm32_e407/doc/index.rst | 2 +- boards/arm/olimex_stm32_h407/doc/index.rst | 2 +- boards/arm/olimex_stm32_p405/doc/index.rst | 2 +- boards/arm/olimexino_stm32/doc/index.rst | 2 +- boards/arm/pandora_stm32l475/support/openocd.cfg | 2 +- boards/arm/sensortile_box/doc/index.rst | 2 +- boards/arm/steval_fcu001v1/doc/index.rst | 2 +- boards/arm/stm3210c_eval/doc/index.rst | 4 ++-- boards/arm/stm32373c_eval/doc/index.rst | 4 ++-- boards/arm/stm32_min_dev/doc/index.rst | 2 +- boards/arm/stm32f072_eval/doc/index.rst | 4 ++-- boards/arm/stm32f072b_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f0_disco/doc/index.rst | 6 +++--- boards/arm/stm32f103_mini/doc/index.rst | 4 ++-- boards/arm/stm32f3_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f3_seco_d23/doc/index.rst | 2 +- boards/arm/stm32f411e_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f412g_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f429i_disc1/doc/index.rst | 8 ++++---- boards/arm/stm32f469i_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f4_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f723e_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f746g_disco/doc/index.rst | 8 ++++---- boards/arm/stm32f7508_dk/doc/index.rst | 6 +++--- boards/arm/stm32f769i_disco/doc/index.rst | 6 +++--- boards/arm/stm32g071b_disco/doc/index.rst | 4 ++-- boards/arm/stm32g081b_eval/doc/index.rst | 2 +- boards/arm/stm32h747i_disco/doc/index.rst | 4 ++-- boards/arm/stm32l476g_disco/doc/index.rst | 8 ++++---- boards/arm/stm32l496g_disco/doc/index.rst | 8 ++++---- boards/arm/stm32l562e_dk/doc/index.rst | 2 +- boards/shields/x_nucleo_idb05a1/doc/index.rst | 2 +- boards/shields/x_nucleo_iks01a1/doc/index.rst | 4 ++-- boards/shields/x_nucleo_iks01a2/doc/index.rst | 4 ++-- boards/shields/x_nucleo_iks01a3/doc/index.rst | 2 +- boards/shields/x_nucleo_iks02a1/doc/index.rst | 2 +- drivers/sensor/vl53l0x/vl53l0x.c | 4 ++-- samples/sensor/hts221/README.rst | 2 +- samples/sensor/lis2dh/README.rst | 2 +- samples/sensor/lps22hb/README.rst | 2 +- samples/sensor/lps22hh/README.rst | 2 +- samples/sensor/lps22hh_i3c/README.rst | 2 +- samples/sensor/lsm303dlhc/README.rst | 2 +- samples/sensor/lsm6dsl/README.rst | 2 +- samples/sensor/lsm6dso/README.rst | 2 +- samples/sensor/lsm6dso_i2c_on_i3c/README.rst | 2 +- samples/sensor/vl53l0x/README.rst | 2 +- samples/shields/x_nucleo_iks01a1/README.rst | 2 +- samples/shields/x_nucleo_iks01a2/sensorhub/README.rst | 2 +- samples/shields/x_nucleo_iks01a2/standard/README.rst | 2 +- samples/shields/x_nucleo_iks01a3/sensorhub/README.rst | 2 +- samples/shields/x_nucleo_iks01a3/standard/README.rst | 2 +- samples/shields/x_nucleo_iks02a1/sensorhub/README.rst | 2 +- samples/shields/x_nucleo_iks02a1/standard/README.rst | 2 +- 115 files changed, 251 insertions(+), 251 deletions(-) diff --git a/boards/arm/96b_aerocore2/doc/index.rst b/boards/arm/96b_aerocore2/doc/index.rst index fbfee1f0081..79bac17ad27 100644 --- a/boards/arm/96b_aerocore2/doc/index.rst +++ b/boards/arm/96b_aerocore2/doc/index.rst @@ -347,4 +347,4 @@ terminal: http://dfu-util.sourceforge.net/build.html .. _AN2606: - http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf + https://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf diff --git a/boards/arm/96b_argonkey/doc/index.rst b/boards/arm/96b_argonkey/doc/index.rst index 0cbed592156..6221adee72c 100644 --- a/boards/arm/96b_argonkey/doc/index.rst +++ b/boards/arm/96b_argonkey/doc/index.rst @@ -234,7 +234,7 @@ References https://sourceforge.net/p/stm32flash/wiki/Home/ .. _ST-LINK/V2: - http://www.st.com/en/development-tools/st-link-v2.html + https://www.st.com/en/development-tools/st-link-v2.html .. _TTL-232RG: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232RG_CABLES.pdf diff --git a/boards/arm/96b_carbon/doc/index.rst b/boards/arm/96b_carbon/doc/index.rst index 608e77e2b42..b4a37cc985d 100644 --- a/boards/arm/96b_carbon/doc/index.rst +++ b/boards/arm/96b_carbon/doc/index.rst @@ -369,16 +369,16 @@ STM32F401RET using an SWD scan. http://dfu-util.sourceforge.net/build.html .. _AN2606: - http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf + https://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf .. _96Boards website: http://www.96boards.org/documentation .. _STM32F401RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f401re.html + https://www.st.com/en/microcontrollers/stm32f401re.html .. _STM32F401 reference manual: - http://www.st.com/resource/en/reference_manual/dm00096844.pdf + https://www.st.com/resource/en/reference_manual/dm00096844.pdf .. _96Boards IE Specification: https://linaro.co/ie-specification diff --git a/boards/arm/96b_stm32_sensor_mez/doc/index.rst b/boards/arm/96b_stm32_sensor_mez/doc/index.rst index 1160777bb0f..95d11d2bacc 100644 --- a/boards/arm/96b_stm32_sensor_mez/doc/index.rst +++ b/boards/arm/96b_stm32_sensor_mez/doc/index.rst @@ -242,7 +242,7 @@ References https://www.96boards.org/documentation/mezzanine/stm32/ .. _STM32F446VE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f446ve.html + https://www.st.com/en/microcontrollers/stm32f446ve.html .. _STM32F446 reference manual: - http://www.st.com/resource/en/reference_manual/dm00135183.pdf + https://www.st.com/resource/en/reference_manual/dm00135183.pdf diff --git a/boards/arm/arduino_giga_r1/doc/index.rst b/boards/arm/arduino_giga_r1/doc/index.rst index 2b9debb4549..80f4cb956fc 100644 --- a/boards/arm/arduino_giga_r1/doc/index.rst +++ b/boards/arm/arduino_giga_r1/doc/index.rst @@ -177,7 +177,7 @@ as "JTAG". For example:: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32h7-series/stm32h747-757/stm32h747xi.html .. _STM32H747xx reference manual: - http://www.st.com/resource/en/reference_manual/dm00176879.pdf + https://www.st.com/resource/en/reference_manual/dm00176879.pdf .. _STM32H747xx datasheet: https://www.st.com/resource/en/datasheet/stm32h747xi.pdf diff --git a/boards/arm/arduino_portenta_h7/doc/index.rst b/boards/arm/arduino_portenta_h7/doc/index.rst index d0ed9df377a..999a659f773 100644 --- a/boards/arm/arduino_portenta_h7/doc/index.rst +++ b/boards/arm/arduino_portenta_h7/doc/index.rst @@ -135,7 +135,7 @@ Here is an example for the :zephyr:code-sample:`blinky` application on M4 core. https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32h7-series/stm32h747-757/stm32h747xi.html .. _STM32H747xx reference manual: - http://www.st.com/resource/en/reference_manual/dm00176879.pdf + https://www.st.com/resource/en/reference_manual/dm00176879.pdf .. _STM32H747xx datasheet: https://www.st.com/resource/en/datasheet/stm32h747xi.pdf diff --git a/boards/arm/b_l072z_lrwan1/doc/index.rst b/boards/arm/b_l072z_lrwan1/doc/index.rst index 9a28af18e39..a45ead85652 100644 --- a/boards/arm/b_l072z_lrwan1/doc/index.rst +++ b/boards/arm/b_l072z_lrwan1/doc/index.rst @@ -244,7 +244,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/b-l072z-lrwan1.html .. _STM32L072CZ on www.st.com: - http://www.st.com/en/microcontrollers/stm32l072cz.html + https://www.st.com/en/microcontrollers/stm32l072cz.html .. _STM32L0x2 reference manual: - http://www.st.com/resource/en/reference_manual/DM00108281.pdf + https://www.st.com/resource/en/reference_manual/DM00108281.pdf diff --git a/boards/arm/black_f407ve/doc/index.rst b/boards/arm/black_f407ve/doc/index.rst index 315894d3b36..4862514d480 100644 --- a/boards/arm/black_f407ve/doc/index.rst +++ b/boards/arm/black_f407ve/doc/index.rst @@ -235,7 +235,7 @@ You can debug an application in the usual way. Here is an example for the https://stm32-base.org/boards/STM32F407VET6-STM32-F4VE-V2.0.html .. _STM32F407VE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f407ve.html + https://www.st.com/en/microcontrollers/stm32f407ve.html .. _STM32F407VET6 black board: https://os.mbed.com/users/hudakz/code/STM32F407VET6_Hello/ diff --git a/boards/arm/blackpill_f401cc/doc/index.rst b/boards/arm/blackpill_f401cc/doc/index.rst index 348f0f6f7cb..8c662a11fda 100644 --- a/boards/arm/blackpill_f401cc/doc/index.rst +++ b/boards/arm/blackpill_f401cc/doc/index.rst @@ -168,7 +168,7 @@ References http://dfu-util.sourceforge.net/build.html .. _STM32F401CC website: - http://www.st.com/en/microcontrollers/stm32f401cc.html + https://www.st.com/en/microcontrollers/stm32f401cc.html .. _STM32F401x reference manual: - http://www.st.com/resource/en/reference_manual/dm00096844.pdf + https://www.st.com/resource/en/reference_manual/dm00096844.pdf diff --git a/boards/arm/blackpill_f401ce/doc/index.rst b/boards/arm/blackpill_f401ce/doc/index.rst index dc3a43fdf24..265d0fd038e 100644 --- a/boards/arm/blackpill_f401ce/doc/index.rst +++ b/boards/arm/blackpill_f401ce/doc/index.rst @@ -173,7 +173,7 @@ References http://dfu-util.sourceforge.net/build.html .. _STM32F401CE website: - http://www.st.com/en/microcontrollers/stm32f401ce.html + https://www.st.com/en/microcontrollers/stm32f401ce.html .. _STM32F401x reference manual: - http://www.st.com/resource/en/reference_manual/dm00096844.pdf + https://www.st.com/resource/en/reference_manual/dm00096844.pdf diff --git a/boards/arm/blackpill_f411ce/doc/index.rst b/boards/arm/blackpill_f411ce/doc/index.rst index 5dd7e68fa35..4d3023b462c 100644 --- a/boards/arm/blackpill_f411ce/doc/index.rst +++ b/boards/arm/blackpill_f411ce/doc/index.rst @@ -173,7 +173,7 @@ References http://dfu-util.sourceforge.net/build.html .. _STM32F411CE website: - http://www.st.com/en/microcontrollers/stm32f411ce.html + https://www.st.com/en/microcontrollers/stm32f411ce.html .. _STM32F411x reference manual: - http://www.st.com/resource/en/reference_manual/dm00119316.pdf + https://www.st.com/resource/en/reference_manual/dm00119316.pdf diff --git a/boards/arm/disco_l475_iot1/doc/index.rst b/boards/arm/disco_l475_iot1/doc/index.rst index e62bae9b5af..906729fcf8e 100644 --- a/boards/arm/disco_l475_iot1/doc/index.rst +++ b/boards/arm/disco_l475_iot1/doc/index.rst @@ -236,13 +236,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Disco L475 IoT1 website: - http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits/b-l475e-iot01a.html + https://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits/b-l475e-iot01a.html .. _STM32 Disco L475 IoT1 board User Manual: - http://www.st.com/resource/en/user_manual/dm00347848.pdf + https://www.st.com/resource/en/user_manual/dm00347848.pdf .. _STM32L475VG on www.st.com: https://www.st.com/en/microcontrollers-microprocessors/stm32l475vg.html .. _STM32L475 reference manual: - http://www.st.com/resource/en/reference_manual/dm00083560.pdf + https://www.st.com/resource/en/reference_manual/dm00083560.pdf diff --git a/boards/arm/dragino_lsn50/doc/index.rst b/boards/arm/dragino_lsn50/doc/index.rst index 68c7732cf69..7931d8f9db8 100644 --- a/boards/arm/dragino_lsn50/doc/index.rst +++ b/boards/arm/dragino_lsn50/doc/index.rst @@ -188,7 +188,7 @@ You can debug an application in the usual way. Here is an example for the https://www.dragino.com/products/lora-lorawan-end-node/item/128-lsn50.html .. _STM32L072CZ on www.st.com: - http://www.st.com/en/microcontrollers/stm32l072cz.html + https://www.st.com/en/microcontrollers/stm32l072cz.html .. _STM32L0x2 reference manual: - http://www.st.com/resource/en/reference_manual/DM00108281.pdf + https://www.st.com/resource/en/reference_manual/DM00108281.pdf diff --git a/boards/arm/dragino_nbsn95/doc/index.rst b/boards/arm/dragino_nbsn95/doc/index.rst index 762125afb3d..71e9f2c9711 100644 --- a/boards/arm/dragino_nbsn95/doc/index.rst +++ b/boards/arm/dragino_nbsn95/doc/index.rst @@ -187,7 +187,7 @@ You can debug an application in the usual way. Here is an example for the https://www.dragino.com/products/nb-iot/item/163-nbsn95.html .. _STM32L072CZ on www.st.com: - http://www.st.com/en/microcontrollers/stm32l072cz.html + https://www.st.com/en/microcontrollers/stm32l072cz.html .. _STM32L0x2 reference manual: - http://www.st.com/resource/en/reference_manual/DM00108281.pdf + https://www.st.com/resource/en/reference_manual/DM00108281.pdf diff --git a/boards/arm/legend/doc/index.rst b/boards/arm/legend/doc/index.rst index c744281d651..1156a792317 100644 --- a/boards/arm/legend/doc/index.rst +++ b/boards/arm/legend/doc/index.rst @@ -136,4 +136,4 @@ References - `STM32F070 reference manual`_ .. _STM32F070 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf diff --git a/boards/arm/nucleo_c031c6/doc/index.rst b/boards/arm/nucleo_c031c6/doc/index.rst index b4f8e484fc1..fcf134f497e 100644 --- a/boards/arm/nucleo_c031c6/doc/index.rst +++ b/boards/arm/nucleo_c031c6/doc/index.rst @@ -142,7 +142,7 @@ References .. target-notes:: .. _Nucleo C031C6 website: - http://www.st.com/en/evaluation-tools/nucleo-c031c6.html + https://www.st.com/en/evaluation-tools/nucleo-c031c6.html .. _STM32C0x1 reference manual: https://www.st.com/resource/en/reference_manual/rm0490-stm32c0x1-advanced-armbased-64bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_f070rb/doc/index.rst b/boards/arm/nucleo_f070rb/doc/index.rst index f61a63cd289..5d7e214bd1b 100644 --- a/boards/arm/nucleo_f070rb/doc/index.rst +++ b/boards/arm/nucleo_f070rb/doc/index.rst @@ -171,10 +171,10 @@ References .. target-notes:: .. _Nucleo F070RB website: - http://www.st.com/en/evaluation-tools/nucleo-f070rb.html + https://www.st.com/en/evaluation-tools/nucleo-f070rb.html .. _STM32F070 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_f091rc/doc/index.rst b/boards/arm/nucleo_f091rc/doc/index.rst index 5aa41419893..f1f0df58e10 100644 --- a/boards/arm/nucleo_f091rc/doc/index.rst +++ b/boards/arm/nucleo_f091rc/doc/index.rst @@ -188,10 +188,10 @@ References .. target-notes:: .. _Nucleo F091RC website: - http://www.st.com/en/evaluation-tools/nucleo-f091rc.html + https://www.st.com/en/evaluation-tools/nucleo-f091rc.html .. _STM32F091 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_f103rb/doc/index.rst b/boards/arm/nucleo_f103rb/doc/index.rst index 72ed5ce0e8a..b717c75b58a 100644 --- a/boards/arm/nucleo_f103rb/doc/index.rst +++ b/boards/arm/nucleo_f103rb/doc/index.rst @@ -178,13 +178,13 @@ References .. target-notes:: .. _Nucleo F103RB website: - http://www.st.com/en/evaluation-tools/nucleo-f103rb.html + https://www.st.com/en/evaluation-tools/nucleo-f103rb.html .. _STM32F103 reference manual: - http://www.st.com/resource/en/reference_manual/cd00171190.pdf + https://www.st.com/resource/en/reference_manual/cd00171190.pdf .. _STM32F103 data sheet: - http://www.st.com/resource/en/datasheet/stm32f103rb.pdf + https://www.st.com/resource/en/datasheet/stm32f103rb.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_f207zg/doc/index.rst b/boards/arm/nucleo_f207zg/doc/index.rst index d4ae50dd7f6..e9696365b1c 100644 --- a/boards/arm/nucleo_f207zg/doc/index.rst +++ b/boards/arm/nucleo_f207zg/doc/index.rst @@ -194,13 +194,13 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F207ZG website: - http://www.st.com/en/evaluation-tools/nucleo-f207zg.html + https://www.st.com/en/evaluation-tools/nucleo-f207zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32F207ZG on www.st.com: - http://www.st.com/en/microcontrollers/stm32f207zg.html + https://www.st.com/en/microcontrollers/stm32f207zg.html .. _STM32F207 reference manual: - http://www.st.com/resource/en/reference_manual/cd00225773.pdf + https://www.st.com/resource/en/reference_manual/cd00225773.pdf diff --git a/boards/arm/nucleo_f302r8/doc/index.rst b/boards/arm/nucleo_f302r8/doc/index.rst index e774c8282c9..e554549a6fe 100644 --- a/boards/arm/nucleo_f302r8/doc/index.rst +++ b/boards/arm/nucleo_f302r8/doc/index.rst @@ -153,16 +153,16 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F302R8 website: - http://www.st.com/en/evaluation-tools/nucleo-f302r8.html + https://www.st.com/en/evaluation-tools/nucleo-f302r8.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F302R8 on www.st.com: - http://www.st.com/en/microcontrollers/stm32f302r8.html + https://www.st.com/en/microcontrollers/stm32f302r8.html .. _STM32F302R8 reference manual: - http://www.st.com/resource/en/reference_manual/dm00094349.pdf + https://www.st.com/resource/en/reference_manual/dm00094349.pdf .. _STM32F302R8 datasheet: - http://www.st.com/resource/en/datasheet/stm32f302r8.pdf + https://www.st.com/resource/en/datasheet/stm32f302r8.pdf diff --git a/boards/arm/nucleo_f303k8/doc/index.rst b/boards/arm/nucleo_f303k8/doc/index.rst index 78cf267a1be..5aab3540663 100644 --- a/boards/arm/nucleo_f303k8/doc/index.rst +++ b/boards/arm/nucleo_f303k8/doc/index.rst @@ -144,13 +144,13 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F303K8 website: - http://www.st.com/en/evaluation-tools/nucleo-F303K8.html + https://www.st.com/en/evaluation-tools/nucleo-F303K8.html .. _STM32 Nucleo-32 board User Manual: https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf .. _STM32F303K8 on www.st.com: - http://www.st.com/en/microcontrollers/stm32F303K8.html + https://www.st.com/en/microcontrollers/stm32F303K8.html .. _STM32F303K8 reference manual: https://www.st.com/resource/en/reference_manual/dm00043574-stm32f303xbcde-stm32f303x68-stm32f328x8-stm32f358xc-stm32f398xe-advanced-armbased-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_f303re/doc/index.rst b/boards/arm/nucleo_f303re/doc/index.rst index 4fc6c911a7d..387a2bc28d2 100644 --- a/boards/arm/nucleo_f303re/doc/index.rst +++ b/boards/arm/nucleo_f303re/doc/index.rst @@ -147,16 +147,16 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F303RE website: - http://www.st.com/en/evaluation-tools/nucleo-f303re.html + https://www.st.com/en/evaluation-tools/nucleo-f303re.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F303RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f303re.html + https://www.st.com/en/microcontrollers/stm32f303re.html .. _STM32F303RE reference manual: https://www.st.com/resource/en/reference_manual/dm00043574.pdf .. _STM32F303RE datasheet: - http://www.st.com/resource/en/datasheet/stm32f303re.pdf + https://www.st.com/resource/en/datasheet/stm32f303re.pdf diff --git a/boards/arm/nucleo_f334r8/doc/index.rst b/boards/arm/nucleo_f334r8/doc/index.rst index 7d05c42c69a..d44ee9e51d7 100644 --- a/boards/arm/nucleo_f334r8/doc/index.rst +++ b/boards/arm/nucleo_f334r8/doc/index.rst @@ -170,10 +170,10 @@ References .. target-notes:: .. _Nucleo F334R8 website: - http://www.st.com/en/evaluation-tools/nucleo-f334r8.html + https://www.st.com/en/evaluation-tools/nucleo-f334r8.html .. _STM32F334 reference manual: - http://www.st.com/resource/en/reference_manual/dm00093941.pdf + https://www.st.com/resource/en/reference_manual/dm00093941.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_f401re/doc/index.rst b/boards/arm/nucleo_f401re/doc/index.rst index c4aaff7c73f..c844ef9ab9c 100644 --- a/boards/arm/nucleo_f401re/doc/index.rst +++ b/boards/arm/nucleo_f401re/doc/index.rst @@ -194,13 +194,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo F401RE website: - http://www.st.com/en/evaluation-tools/nucleo-f401re.html + https://www.st.com/en/evaluation-tools/nucleo-f401re.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F401RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f401re.html + https://www.st.com/en/microcontrollers/stm32f401re.html .. _STM32F401 reference manual: - http://www.st.com/resource/en/reference_manual/dm00096844.pdf + https://www.st.com/resource/en/reference_manual/dm00096844.pdf diff --git a/boards/arm/nucleo_f410rb/doc/index.rst b/boards/arm/nucleo_f410rb/doc/index.rst index d629044fc11..c5702552ca8 100644 --- a/boards/arm/nucleo_f410rb/doc/index.rst +++ b/boards/arm/nucleo_f410rb/doc/index.rst @@ -200,13 +200,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo F410RB website: - http://www.st.com/en/evaluation-tools/nucleo-F410RB.html + https://www.st.com/en/evaluation-tools/nucleo-F410RB.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F410RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32f410rb.html + https://www.st.com/en/microcontrollers/stm32f410rb.html .. _STM32F410 reference manual: https://www.st.com/resource/en/reference_manual/dm00180366.pdf diff --git a/boards/arm/nucleo_f411re/doc/index.rst b/boards/arm/nucleo_f411re/doc/index.rst index 48e4813eb77..ee7d652d1c5 100644 --- a/boards/arm/nucleo_f411re/doc/index.rst +++ b/boards/arm/nucleo_f411re/doc/index.rst @@ -188,13 +188,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo F411RE website: - http://www.st.com/en/evaluation-tools/nucleo-f411re.html + https://www.st.com/en/evaluation-tools/nucleo-f411re.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F411RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f411re.html + https://www.st.com/en/microcontrollers/stm32f411re.html .. _STM32F411 reference manual: - http://www.st.com/resource/en/reference_manual/dm00119316.pdf + https://www.st.com/resource/en/reference_manual/dm00119316.pdf diff --git a/boards/arm/nucleo_f412zg/doc/index.rst b/boards/arm/nucleo_f412zg/doc/index.rst index 024382af888..678971ecf1e 100644 --- a/boards/arm/nucleo_f412zg/doc/index.rst +++ b/boards/arm/nucleo_f412zg/doc/index.rst @@ -160,13 +160,13 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F412ZG website: - http://www.st.com/en/evaluation-tools/nucleo-f412zg.html + https://www.st.com/en/evaluation-tools/nucleo-f412zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32F412ZG on www.st.com: - http://www.st.com/en/microcontrollers/stm32f412zg.html + https://www.st.com/en/microcontrollers/stm32f412zg.html .. _STM32F412 reference manual: - http://www.st.com/resource/en/reference_manual/dm00180369.pdf + https://www.st.com/resource/en/reference_manual/dm00180369.pdf diff --git a/boards/arm/nucleo_f413zh/doc/index.rst b/boards/arm/nucleo_f413zh/doc/index.rst index ca6bfd52a15..b00213ced7e 100644 --- a/boards/arm/nucleo_f413zh/doc/index.rst +++ b/boards/arm/nucleo_f413zh/doc/index.rst @@ -162,13 +162,13 @@ This interface is supported by the openocd version included in Zephyr SDK. .. _Nucleo F413ZH website: - http://www.st.com/en/evaluation-tools/nucleo-f413zh.html + https://www.st.com/en/evaluation-tools/nucleo-f413zh.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32F413ZH on www.st.com: - http://www.st.com/en/microcontrollers/stm32f413zh.html + https://www.st.com/en/microcontrollers/stm32f413zh.html .. _STM32F413/423 reference manual: - http://www.st.com/resource/en/reference_manual/dm00305666.pdf + https://www.st.com/resource/en/reference_manual/dm00305666.pdf diff --git a/boards/arm/nucleo_f429zi/doc/index.rst b/boards/arm/nucleo_f429zi/doc/index.rst index 8bb1d0fee85..3b20f6a7a0c 100644 --- a/boards/arm/nucleo_f429zi/doc/index.rst +++ b/boards/arm/nucleo_f429zi/doc/index.rst @@ -199,19 +199,19 @@ A specific application can adjust each partition size based on its needs. .. _Nucleo F429ZI website: - http://www.st.com/en/evaluation-tools/nucleo-f429zi.html + https://www.st.com/en/evaluation-tools/nucleo-f429zi.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32F429ZI on www.st.com: - http://www.st.com/en/microcontrollers/stm32f429zi.html + https://www.st.com/en/microcontrollers/stm32f429zi.html .. _STM32F429 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031020.pdf + https://www.st.com/resource/en/reference_manual/dm00031020.pdf .. _STM32F429 datasheet: - http://www.st.com/resource/en/datasheet/DM00071990.pdf + https://www.st.com/resource/en/datasheet/DM00071990.pdf .. _MCUBoot: https://github.com/JuulLabs-OSS/mcuboot/blob/master/README.md diff --git a/boards/arm/nucleo_f446re/doc/index.rst b/boards/arm/nucleo_f446re/doc/index.rst index 07005c58cda..a835d963d2b 100644 --- a/boards/arm/nucleo_f446re/doc/index.rst +++ b/boards/arm/nucleo_f446re/doc/index.rst @@ -211,16 +211,16 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo F446RE website: - http://www.st.com/en/evaluation-tools/nucleo-f446re.html + https://www.st.com/en/evaluation-tools/nucleo-f446re.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F446RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f446re.html + https://www.st.com/en/microcontrollers/stm32f446re.html .. _STM32F446 reference manual: - http://www.st.com/resource/en/reference_manual/dm00135183.pdf + https://www.st.com/resource/en/reference_manual/dm00135183.pdf .. _RS485 CAN Shield: https://www.waveshare.com/wiki/RS485_CAN_Shield diff --git a/boards/arm/nucleo_f446ze/doc/index.rst b/boards/arm/nucleo_f446ze/doc/index.rst index 0c7b4fcb874..b0a8f431462 100644 --- a/boards/arm/nucleo_f446ze/doc/index.rst +++ b/boards/arm/nucleo_f446ze/doc/index.rst @@ -236,13 +236,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo F446ZE website: - http://www.st.com/en/evaluation-tools/nucleo-f446ze.html + https://www.st.com/en/evaluation-tools/nucleo-f446ze.html .. _STM32 Nucleo-144 board User Manual: https://www.st.com/resource/en/user_manual/um1974-stm32-nucleo144-boards-mb1137-stmicroelectronics.pdf .. _STM32F446ZE on www.st.com: - http://www.st.com/en/microcontrollers/stm32f446ze.html + https://www.st.com/en/microcontrollers/stm32f446ze.html .. _STM32F446 reference manual: - http://www.st.com/resource/en/reference_manual/dm00135183.pdf + https://www.st.com/resource/en/reference_manual/dm00135183.pdf diff --git a/boards/arm/nucleo_f746zg/doc/index.rst b/boards/arm/nucleo_f746zg/doc/index.rst index bc419c612c4..ef9fdf9d20e 100644 --- a/boards/arm/nucleo_f746zg/doc/index.rst +++ b/boards/arm/nucleo_f746zg/doc/index.rst @@ -226,7 +226,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/nucleo-f746zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32F746ZG on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x6/stm32f746zg.html diff --git a/boards/arm/nucleo_f756zg/doc/index.rst b/boards/arm/nucleo_f756zg/doc/index.rst index 299eb9e4c7b..2616a3b6dcc 100644 --- a/boards/arm/nucleo_f756zg/doc/index.rst +++ b/boards/arm/nucleo_f756zg/doc/index.rst @@ -209,7 +209,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/nucleo-f756zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32F756ZG on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x6/stm32f756zg.html diff --git a/boards/arm/nucleo_f767zi/doc/index.rst b/boards/arm/nucleo_f767zi/doc/index.rst index bf6f1c68b92..bed503e2609 100644 --- a/boards/arm/nucleo_f767zi/doc/index.rst +++ b/boards/arm/nucleo_f767zi/doc/index.rst @@ -227,7 +227,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/nucleo-f767zi.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32f767zi on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x&/stm32f767zi.html diff --git a/boards/arm/nucleo_g031k8/doc/index.rst b/boards/arm/nucleo_g031k8/doc/index.rst index 3e0f72f4811..6f933b08546 100644 --- a/boards/arm/nucleo_g031k8/doc/index.rst +++ b/boards/arm/nucleo_g031k8/doc/index.rst @@ -159,7 +159,7 @@ References .. target-notes:: .. _Nucleo G031K8 website: - http://www.st.com/en/evaluation-tools/nucleo-g031k8.html + https://www.st.com/en/evaluation-tools/nucleo-g031k8.html .. _STM32G0x1 reference manual: https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_g031k8/support/openocd.cfg b/boards/arm/nucleo_g031k8/support/openocd.cfg index 6bb5b17874f..f4b1bc9142c 100644 --- a/boards/arm/nucleo_g031k8/support/openocd.cfg +++ b/boards/arm/nucleo_g031k8/support/openocd.cfg @@ -1,5 +1,5 @@ # This is an ST NUCLEO-G031K8 board with single STM32G031K8 chip. -# http://www.st.com/en/evaluation-tools/nucleo-g031k8.html +# https://www.st.com/en/evaluation-tools/nucleo-g031k8.html source [find interface/stlink-dap.cfg] diff --git a/boards/arm/nucleo_g070rb/doc/index.rst b/boards/arm/nucleo_g070rb/doc/index.rst index 9ceca0731a0..056bb298c4f 100644 --- a/boards/arm/nucleo_g070rb/doc/index.rst +++ b/boards/arm/nucleo_g070rb/doc/index.rst @@ -182,10 +182,10 @@ References .. target-notes:: .. _Nucleo G070RB website: - http://www.st.com/en/evaluation-tools/nucleo-g070rb.html + https://www.st.com/en/evaluation-tools/nucleo-g070rb.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00452640.pdf + https://www.st.com/resource/en/user_manual/dm00452640.pdf .. _G070RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32g070rb.html + https://www.st.com/en/microcontrollers/stm32g070rb.html diff --git a/boards/arm/nucleo_g071rb/doc/index.rst b/boards/arm/nucleo_g071rb/doc/index.rst index 7cc230fe0e2..f6aebe8f12b 100644 --- a/boards/arm/nucleo_g071rb/doc/index.rst +++ b/boards/arm/nucleo_g071rb/doc/index.rst @@ -186,13 +186,13 @@ References .. target-notes:: .. _Nucleo G071RB website: - http://www.st.com/en/evaluation-tools/nucleo-g071rb.html + https://www.st.com/en/evaluation-tools/nucleo-g071rb.html .. _STM32G071 reference manual: - http://www.st.com/resource/en/reference_manual/dm00371828.pdf + https://www.st.com/resource/en/reference_manual/dm00371828.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00452640.pdf + https://www.st.com/resource/en/user_manual/dm00452640.pdf .. _G071RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32g071rb.html + https://www.st.com/en/microcontrollers/stm32g071rb.html diff --git a/boards/arm/nucleo_g0b1re/doc/index.rst b/boards/arm/nucleo_g0b1re/doc/index.rst index 22782af46af..66e6a9ba87d 100644 --- a/boards/arm/nucleo_g0b1re/doc/index.rst +++ b/boards/arm/nucleo_g0b1re/doc/index.rst @@ -195,13 +195,13 @@ References .. target-notes:: .. _Nucleo G0B1RE website: - http://www.st.com/en/evaluation-tools/nucleo-g0b1re.html + https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html .. _STM32G0B1 reference manual: - http://www.st.com/resource/en/reference_manual/dm00371828.pdf + https://www.st.com/resource/en/reference_manual/dm00371828.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00452640.pdf + https://www.st.com/resource/en/user_manual/dm00452640.pdf .. _G0B1RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32g0b1re.html + https://www.st.com/en/microcontrollers/stm32g0b1re.html diff --git a/boards/arm/nucleo_g431rb/doc/index.rst b/boards/arm/nucleo_g431rb/doc/index.rst index db18f702cdc..dfe1b680fe6 100644 --- a/boards/arm/nucleo_g431rb/doc/index.rst +++ b/boards/arm/nucleo_g431rb/doc/index.rst @@ -249,13 +249,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo G431RB website: - http://www.st.com/en/evaluation-tools/nucleo-g431rb.html + https://www.st.com/en/evaluation-tools/nucleo-g431rb.html .. _STM32G4 Nucleo-64 board User Manual: https://www.st.com/resource/en/user_manual/dm00556337.pdf .. _STM32G431RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32g431rb.html + https://www.st.com/en/microcontrollers/stm32g431rb.html .. _STM32G4 reference manual: https://www.st.com/resource/en/reference_manual/dm00355726.pdf diff --git a/boards/arm/nucleo_g474re/doc/index.rst b/boards/arm/nucleo_g474re/doc/index.rst index b21265795be..437668ed42e 100644 --- a/boards/arm/nucleo_g474re/doc/index.rst +++ b/boards/arm/nucleo_g474re/doc/index.rst @@ -239,13 +239,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo G474RE website: - http://www.st.com/en/evaluation-tools/nucleo-g474re.html + https://www.st.com/en/evaluation-tools/nucleo-g474re.html .. _STM32G4 Nucleo-64 board User Manual: https://www.st.com/resource/en/user_manual/dm00556337.pdf .. _STM32G474RE on www.st.com: - http://www.st.com/en/microcontrollers/stm32g474re.html + https://www.st.com/en/microcontrollers/stm32g474re.html .. _STM32G4 reference manual: https://www.st.com/resource/en/reference_manual/dm00355726.pdf diff --git a/boards/arm/nucleo_h563zi/doc/index.rst b/boards/arm/nucleo_h563zi/doc/index.rst index 051b7aa3118..9b6f880ac4c 100644 --- a/boards/arm/nucleo_h563zi/doc/index.rst +++ b/boards/arm/nucleo_h563zi/doc/index.rst @@ -308,7 +308,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/resource/en/user_manual/um3115-stm32h5-nucleo144-board-mb1404-stmicroelectronics.pdf .. _STM32H563ZI on www.st.com: - http://www.st.com/en/microcontrollers/stm32h563zi.html + https://www.st.com/en/microcontrollers/stm32h563zi.html .. _STM32H563 reference manual: https://www.st.com/resource/en/reference_manual/rm0481-stm32h563h573-and-stm32h562-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_h743zi/doc/index.rst b/boards/arm/nucleo_h743zi/doc/index.rst index b2c2b7e6d4f..af0ee0186ec 100644 --- a/boards/arm/nucleo_h743zi/doc/index.rst +++ b/boards/arm/nucleo_h743zi/doc/index.rst @@ -237,7 +237,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/nucleo-h743zi.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32H743ZI on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32h7-series/stm32h743-753/stm32h743zi.html diff --git a/boards/arm/nucleo_h753zi/doc/index.rst b/boards/arm/nucleo_h753zi/doc/index.rst index 8c52f7a4a27..41a9af20954 100644 --- a/boards/arm/nucleo_h753zi/doc/index.rst +++ b/boards/arm/nucleo_h753zi/doc/index.rst @@ -224,7 +224,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/evaluation-tools/nucleo-h753zi.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00244518.pdf + https://www.st.com/resource/en/user_manual/dm00244518.pdf .. _STM32H753ZI on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32h7-series/stm32h743-753/stm32h753zi.html diff --git a/boards/arm/nucleo_l011k4/doc/index.rst b/boards/arm/nucleo_l011k4/doc/index.rst index 590906ff57c..9b815ede4de 100644 --- a/boards/arm/nucleo_l011k4/doc/index.rst +++ b/boards/arm/nucleo_l011k4/doc/index.rst @@ -158,7 +158,7 @@ References .. target-notes:: .. _Nucleo L011K4 website: - http://www.st.com/en/evaluation-tools/nucleo-l011k4.html + https://www.st.com/en/evaluation-tools/nucleo-l011k4.html .. _STM32L0x1 reference manual: https://www.st.com/resource/en/reference_manual/dm00108282-ultralowpower-stm32l0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_l011k4/support/openocd.cfg b/boards/arm/nucleo_l011k4/support/openocd.cfg index 399b76d1e2f..a6ca36d73b0 100644 --- a/boards/arm/nucleo_l011k4/support/openocd.cfg +++ b/boards/arm/nucleo_l011k4/support/openocd.cfg @@ -1,5 +1,5 @@ # This is an ST NUCLEO-L011K4 board with single STM32L011K4 chip. -# http://www.st.com/en/evaluation-tools/nucleo-l011k4.html +# https://www.st.com/en/evaluation-tools/nucleo-l011k4.html source [find interface/stlink.cfg] transport select hla_swd diff --git a/boards/arm/nucleo_l031k6/doc/index.rst b/boards/arm/nucleo_l031k6/doc/index.rst index 229851d829d..eb1f6e25387 100644 --- a/boards/arm/nucleo_l031k6/doc/index.rst +++ b/boards/arm/nucleo_l031k6/doc/index.rst @@ -151,7 +151,7 @@ References .. target-notes:: .. _Nucleo L031K6 website: - http://www.st.com/en/evaluation-tools/nucleo-l031k6.html + https://www.st.com/en/evaluation-tools/nucleo-l031k6.html .. _STM32L0x1 reference manual: https://www.st.com/resource/en/reference_manual/dm00108282-ultralowpower-stm32l0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_l031k6/support/openocd.cfg b/boards/arm/nucleo_l031k6/support/openocd.cfg index c9394171884..be154d927e4 100644 --- a/boards/arm/nucleo_l031k6/support/openocd.cfg +++ b/boards/arm/nucleo_l031k6/support/openocd.cfg @@ -1,5 +1,5 @@ # This is an ST NUCLEO-L031K6 board with single STM32L031K6 chip. -# http://www.st.com/en/evaluation-tools/nucleo-l031k6.html +# https://www.st.com/en/evaluation-tools/nucleo-l031k6.html source [find interface/stlink.cfg] transport select hla_swd diff --git a/boards/arm/nucleo_l053r8/doc/index.rst b/boards/arm/nucleo_l053r8/doc/index.rst index 5f66a6d3cdf..33f84b14e6c 100644 --- a/boards/arm/nucleo_l053r8/doc/index.rst +++ b/boards/arm/nucleo_l053r8/doc/index.rst @@ -167,10 +167,10 @@ References .. target-notes:: .. _Nucleo L053R8 website: - http://www.st.com/en/evaluation-tools/nucleo-l053r8.html + https://www.st.com/en/evaluation-tools/nucleo-l053r8.html .. _STM32L0x3 reference manual: - http://www.st.com/resource/en/reference_manual/dm00095744.pdf + https://www.st.com/resource/en/reference_manual/dm00095744.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_l053r8/support/openocd.cfg b/boards/arm/nucleo_l053r8/support/openocd.cfg index 9eddb05d195..fec9da07d55 100644 --- a/boards/arm/nucleo_l053r8/support/openocd.cfg +++ b/boards/arm/nucleo_l053r8/support/openocd.cfg @@ -1,5 +1,5 @@ # This is an ST NUCLEO-L053R8 board with single STM32L053R8 chip. -# http://www.st.com/en/evaluation-tools/nucleo-l053r8.html +# https://www.st.com/en/evaluation-tools/nucleo-l053r8.html source [find interface/stlink.cfg] transport select hla_swd diff --git a/boards/arm/nucleo_l073rz/doc/index.rst b/boards/arm/nucleo_l073rz/doc/index.rst index e498addbc9a..de662f5b14f 100644 --- a/boards/arm/nucleo_l073rz/doc/index.rst +++ b/boards/arm/nucleo_l073rz/doc/index.rst @@ -181,10 +181,10 @@ References .. target-notes:: .. _Nucleo L073RZ website: - http://www.st.com/en/evaluation-tools/nucleo-l073rz.html + https://www.st.com/en/evaluation-tools/nucleo-l073rz.html .. _STM32L0x3 reference manual: - http://www.st.com/resource/en/reference_manual/dm00095744.pdf + https://www.st.com/resource/en/reference_manual/dm00095744.pdf .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf diff --git a/boards/arm/nucleo_l073rz/support/openocd.cfg b/boards/arm/nucleo_l073rz/support/openocd.cfg index 00f68a63ac8..b28dd29e5c1 100644 --- a/boards/arm/nucleo_l073rz/support/openocd.cfg +++ b/boards/arm/nucleo_l073rz/support/openocd.cfg @@ -1,5 +1,5 @@ # This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip. -# http://www.st.com/en/evaluation-tools/nucleo-l073rz.html +# https://www.st.com/en/evaluation-tools/nucleo-l073rz.html source [find interface/stlink.cfg] transport select hla_swd diff --git a/boards/arm/nucleo_l432kc/doc/index.rst b/boards/arm/nucleo_l432kc/doc/index.rst index fc9bfc51d08..94d6f6f20f0 100644 --- a/boards/arm/nucleo_l432kc/doc/index.rst +++ b/boards/arm/nucleo_l432kc/doc/index.rst @@ -217,13 +217,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L432KC website: - http://www.st.com/en/evaluation-tools/nucleo-l432kc.html + https://www.st.com/en/evaluation-tools/nucleo-l432kc.html .. _STM32 Nucleo-32 board User Manual: - http://www.st.com/resource/en/user_manual/dm00231744.pdf + https://www.st.com/resource/en/user_manual/dm00231744.pdf .. _STM32L432KC on www.st.com: - http://www.st.com/en/microcontrollers/stm32l432kc.html + https://www.st.com/en/microcontrollers/stm32l432kc.html .. _STM32L432 reference manual: - http://www.st.com/resource/en/reference_manual/dm00151940.pdf + https://www.st.com/resource/en/reference_manual/dm00151940.pdf diff --git a/boards/arm/nucleo_l433rc_p/doc/index.rst b/boards/arm/nucleo_l433rc_p/doc/index.rst index f4903d59b16..da2660417c0 100644 --- a/boards/arm/nucleo_l433rc_p/doc/index.rst +++ b/boards/arm/nucleo_l433rc_p/doc/index.rst @@ -222,7 +222,7 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L433RC-P website: - http://www.st.com/en/evaluation-tools/nucleo-l433rc-p.html + https://www.st.com/en/evaluation-tools/nucleo-l433rc-p.html .. _ST Nucleo L433RC-P User Manual: https://www.st.com/resource/en/user_manual/dm00387966.pdf diff --git a/boards/arm/nucleo_l476rg/doc/index.rst b/boards/arm/nucleo_l476rg/doc/index.rst index 765657b6a9e..cfbf949df57 100644 --- a/boards/arm/nucleo_l476rg/doc/index.rst +++ b/boards/arm/nucleo_l476rg/doc/index.rst @@ -231,13 +231,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L476RG website: - http://www.st.com/en/evaluation-tools/nucleo-l476rg.html + https://www.st.com/en/evaluation-tools/nucleo-l476rg.html .. _STM32 Nucleo-64 board User Manual: - http://www.st.com/resource/en/user_manual/dm00105823.pdf + https://www.st.com/resource/en/user_manual/dm00105823.pdf .. _STM32L476RG on www.st.com: - http://www.st.com/en/microcontrollers/stm32l476rg.html + https://www.st.com/en/microcontrollers/stm32l476rg.html .. _STM32L476 reference manual: - http://www.st.com/resource/en/reference_manual/DM00083560.pdf + https://www.st.com/resource/en/reference_manual/DM00083560.pdf diff --git a/boards/arm/nucleo_l496zg/doc/index.rst b/boards/arm/nucleo_l496zg/doc/index.rst index 9f7c9959717..43f6e1fdb4c 100644 --- a/boards/arm/nucleo_l496zg/doc/index.rst +++ b/boards/arm/nucleo_l496zg/doc/index.rst @@ -232,13 +232,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L496ZG website: - http://www.st.com/en/evaluation-tools/nucleo-l496zg.html + https://www.st.com/en/evaluation-tools/nucleo-l496zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00368330.pdf + https://www.st.com/resource/en/user_manual/dm00368330.pdf .. _STM32L496ZG on www.st.com: - http://www.st.com/en/microcontrollers/stm32l496zg.html + https://www.st.com/en/microcontrollers/stm32l496zg.html .. _STM32L496 reference manual: - http://www.st.com/resource/en/reference_manual/dm00083560.pdf + https://www.st.com/resource/en/reference_manual/dm00083560.pdf diff --git a/boards/arm/nucleo_l4a6zg/doc/index.rst b/boards/arm/nucleo_l4a6zg/doc/index.rst index 895e55ca546..79c7caca7bb 100644 --- a/boards/arm/nucleo_l4a6zg/doc/index.rst +++ b/boards/arm/nucleo_l4a6zg/doc/index.rst @@ -231,13 +231,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L4A6ZG website: - http://www.st.com/en/evaluation-tools/nucleo-l4a6zg.html + https://www.st.com/en/evaluation-tools/nucleo-l4a6zg.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00368330.pdf + https://www.st.com/resource/en/user_manual/dm00368330.pdf .. _STM32L4A6ZG on www.st.com: - http://www.st.com/en/microcontrollers-microprocessors/stm32l4a6zg.html + https://www.st.com/en/microcontrollers-microprocessors/stm32l4a6zg.html .. _STM32L4A6 reference manual: - http://www.st.com/resource/en/reference_manual/dm00083560.pdf + https://www.st.com/resource/en/reference_manual/dm00083560.pdf diff --git a/boards/arm/nucleo_l4r5zi/doc/index.rst b/boards/arm/nucleo_l4r5zi/doc/index.rst index f2d27399913..9adb38a2c59 100644 --- a/boards/arm/nucleo_l4r5zi/doc/index.rst +++ b/boards/arm/nucleo_l4r5zi/doc/index.rst @@ -243,16 +243,16 @@ You should see the following message on the console: Hello World! arm .. _Nucleo L4R5ZI website: - http://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html + https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00368330.pdf + https://www.st.com/resource/en/user_manual/dm00368330.pdf .. _STM32L4R5ZI on www.st.com: - http://www.st.com/en/microcontrollers/stm32l4r5zi.html + https://www.st.com/en/microcontrollers/stm32l4r5zi.html .. _STM32L4R5 reference manual: - http://www.st.com/resource/en/reference_manual/DM00310109.pdf + https://www.st.com/resource/en/reference_manual/DM00310109.pdf .. _STM32 ST-LINK utility: - http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-link004.html + https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-link004.html diff --git a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst index 37dee841eab..51675477af4 100644 --- a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst +++ b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst @@ -370,16 +370,16 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _Nucleo L552ZE Q website: - http://www.st.com/en/evaluation-tools/nucleo-l552ze-q.html + https://www.st.com/en/evaluation-tools/nucleo-l552ze-q.html .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00615305.pdf + https://www.st.com/resource/en/user_manual/dm00615305.pdf .. _STM32L552ZE on www.st.com: - http://www.st.com/en/microcontrollers/stm32l552ze.html + https://www.st.com/en/microcontrollers/stm32l552ze.html .. _STM32L552 reference manual: - http://www.st.com/resource/en/reference_manual/DM00346336.pdf + https://www.st.com/resource/en/reference_manual/DM00346336.pdf .. _STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/arm/nucleo_u575zi_q/doc/index.rst b/boards/arm/nucleo_u575zi_q/doc/index.rst index 3f297372b82..0de2c364ecf 100644 --- a/boards/arm/nucleo_u575zi_q/doc/index.rst +++ b/boards/arm/nucleo_u575zi_q/doc/index.rst @@ -328,10 +328,10 @@ Note: Check the ``build/tfm`` directory to ensure that the commands required by (which is used for initialization) is available in the PATH. .. _STM32 Nucleo-144 board User Manual: - http://www.st.com/resource/en/user_manual/dm00615305.pdf + https://www.st.com/resource/en/user_manual/dm00615305.pdf .. _STM32U575ZI on www.st.com: - http://www.st.com/en/microcontrollers/stm32u575zi.html + https://www.st.com/en/microcontrollers/stm32u575zi.html .. _STM32U575 reference manual: https://www.st.com/resource/en/reference_manual/rm0456-stm32u575585-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/olimex_stm32_e407/doc/index.rst b/boards/arm/olimex_stm32_e407/doc/index.rst index de5393f4b11..6abdc3b564c 100644 --- a/boards/arm/olimex_stm32_e407/doc/index.rst +++ b/boards/arm/olimex_stm32_e407/doc/index.rst @@ -375,4 +375,4 @@ way. Here is an example for the :ref:`hello_world` application. https://www.olimex.com/Products/ARM/ST/STM32-E407/resources/STM32-E407.pdf .. _ST STM32F407ZG Datasheet: - http://www.st.com/resource/en/reference_manual/dm00031020.pdf + https://www.st.com/resource/en/reference_manual/dm00031020.pdf diff --git a/boards/arm/olimex_stm32_h407/doc/index.rst b/boards/arm/olimex_stm32_h407/doc/index.rst index 25cd752612e..3555ed52a35 100644 --- a/boards/arm/olimex_stm32_h407/doc/index.rst +++ b/boards/arm/olimex_stm32_h407/doc/index.rst @@ -372,4 +372,4 @@ way. Here is an example for the :ref:`hello_world` application. https://www.olimex.com/Products/ARM/ST/STM32-H407/resources/STM32-H407.pdf .. _ST STM32F407ZG Datasheet: - http://www.st.com/resource/en/reference_manual/dm00031020.pdf + https://www.st.com/resource/en/reference_manual/dm00031020.pdf diff --git a/boards/arm/olimex_stm32_p405/doc/index.rst b/boards/arm/olimex_stm32_p405/doc/index.rst index 9aa053e90a0..e68bcb589ca 100644 --- a/boards/arm/olimex_stm32_p405/doc/index.rst +++ b/boards/arm/olimex_stm32_p405/doc/index.rst @@ -260,4 +260,4 @@ You can debug an application in the usual way. Here is an example for the https://www.olimex.com/Products/ARM/ST/STM32-P405/resources/STM32-P405_UM.pdf .. _ST STM32F405RG Datasheet: - http://www.st.com/resource/en/reference_manual/dm00031020.pdf + https://www.st.com/resource/en/reference_manual/dm00031020.pdf diff --git a/boards/arm/olimexino_stm32/doc/index.rst b/boards/arm/olimexino_stm32/doc/index.rst index af8c880b86a..913b6faa8d6 100644 --- a/boards/arm/olimexino_stm32/doc/index.rst +++ b/boards/arm/olimexino_stm32/doc/index.rst @@ -458,7 +458,7 @@ serial adapter is required. This tutorial uses the https://www.olimex.com/Products/Duino/STM32/OLIMEXINO-STM32/resources/OLIMEXINO-STM32.pdf .. _ST STM32F103xB Datasheet: - http://www.st.com/resource/en/datasheet/stm32f103tb.pdf + https://www.st.com/resource/en/datasheet/stm32f103tb.pdf .. _stm32flash tool: https://sourceforge.net/p/stm32flash/wiki/Home/ diff --git a/boards/arm/pandora_stm32l475/support/openocd.cfg b/boards/arm/pandora_stm32l475/support/openocd.cfg index d9d989eb30e..d4c4da41053 100644 --- a/boards/arm/pandora_stm32l475/support/openocd.cfg +++ b/boards/arm/pandora_stm32l475/support/openocd.cfg @@ -1,5 +1,5 @@ # Explicitly for the STM32L475 Pandora board: -# http://www.st.com/web/en/catalog/tools/PF261635 +# https://www.st.com/web/en/catalog/tools/PF261635 # but perfectly functional for any other STM32L4 board connected via # an stlink-v2-1 interface. # This is for STM32L4 boards that are connected via stlink-v2-1. diff --git a/boards/arm/sensortile_box/doc/index.rst b/boards/arm/sensortile_box/doc/index.rst index a6cabf9b359..db9ba488dc1 100644 --- a/boards/arm/sensortile_box/doc/index.rst +++ b/boards/arm/sensortile_box/doc/index.rst @@ -197,7 +197,7 @@ References https://www.st.com/en/evaluation-tools/steval-mksbox1v1.html .. _AN2606: - http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf + https://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf .. _DFU-UTIL website: http://dfu-util.sourceforge.net/ diff --git a/boards/arm/steval_fcu001v1/doc/index.rst b/boards/arm/steval_fcu001v1/doc/index.rst index f28685e7fa9..823631dd120 100644 --- a/boards/arm/steval_fcu001v1/doc/index.rst +++ b/boards/arm/steval_fcu001v1/doc/index.rst @@ -155,4 +155,4 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/microcontrollers-microprocessors/stm32f401cc.html .. _STM32F401 reference manual: - http://www.st.com/resource/en/reference_manual/dm00096844.pdf + https://www.st.com/resource/en/reference_manual/dm00096844.pdf diff --git a/boards/arm/stm3210c_eval/doc/index.rst b/boards/arm/stm3210c_eval/doc/index.rst index 4154d45a878..9d9278e1614 100644 --- a/boards/arm/stm3210c_eval/doc/index.rst +++ b/boards/arm/stm3210c_eval/doc/index.rst @@ -159,7 +159,7 @@ References .. target-notes:: .. _STM3210C-EVAL website: - http://www.st.com/en/evaluation-tools/stm3210c-eval.html + https://www.st.com/en/evaluation-tools/stm3210c-eval.html .. _STM32F107VCT reference manual: - http://www.st.com/resource/en/reference_manual/CD00171190.pdf + https://www.st.com/resource/en/reference_manual/CD00171190.pdf diff --git a/boards/arm/stm32373c_eval/doc/index.rst b/boards/arm/stm32373c_eval/doc/index.rst index eb9ccf11153..9f6ed1d750b 100644 --- a/boards/arm/stm32373c_eval/doc/index.rst +++ b/boards/arm/stm32373c_eval/doc/index.rst @@ -153,7 +153,7 @@ References .. target-notes:: .. _STM32373C-EVAL website: - http://www.st.com/en/evaluation-tools/stm32373c-eval.html + https://www.st.com/en/evaluation-tools/stm32373c-eval.html .. _STM32F373VCT6 reference manual: - http://www.st.com/resource/en/reference_manual/dm00041563.pdf + https://www.st.com/resource/en/reference_manual/dm00041563.pdf diff --git a/boards/arm/stm32_min_dev/doc/index.rst b/boards/arm/stm32_min_dev/doc/index.rst index 8f166ea1f92..6d83f0f7ec7 100644 --- a/boards/arm/stm32_min_dev/doc/index.rst +++ b/boards/arm/stm32_min_dev/doc/index.rst @@ -181,6 +181,6 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _STM32F103x8: - http://www.st.com/resource/en/datasheet/stm32f103c8.pdf + https://www.st.com/resource/en/datasheet/stm32f103c8.pdf .. _EmbedJournal: https://embedjournal.com/tag/stm32-min-dev/ diff --git a/boards/arm/stm32f072_eval/doc/index.rst b/boards/arm/stm32f072_eval/doc/index.rst index cb623eb0aa5..4872f85785b 100644 --- a/boards/arm/stm32f072_eval/doc/index.rst +++ b/boards/arm/stm32f072_eval/doc/index.rst @@ -179,7 +179,7 @@ You can debug an application in the usual way. Here is an example for the .. _STM32F072VB on www.st.com: - http://www.st.com/en/microcontrollers/stm32f072vb.html + https://www.st.com/en/microcontrollers/stm32f072vb.html .. _STM32F072 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf diff --git a/boards/arm/stm32f072b_disco/doc/index.rst b/boards/arm/stm32f072b_disco/doc/index.rst index e442d035d95..3756926ec4c 100644 --- a/boards/arm/stm32f072b_disco/doc/index.rst +++ b/boards/arm/stm32f072b_disco/doc/index.rst @@ -203,17 +203,17 @@ References .. target-notes:: .. _STM32F072B-DISCO website: - http://www.st.com/en/evaluation-tools/32f072bdiscovery.html + https://www.st.com/en/evaluation-tools/32f072bdiscovery.html .. _STM32F072B-DISCO board User Manual: - http://www.st.com/resource/en/user_manual/dm00099401.pdf + https://www.st.com/resource/en/user_manual/dm00099401.pdf .. _STM32F072RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32f072rb.html + https://www.st.com/en/microcontrollers/stm32f072rb.html .. _STM32F072xB reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf .. _SK Pang CAN breakout board: https://www.skpang.co.uk/products/can-bus-can-fd-breakout-board-5v-supply-and-5v-logic diff --git a/boards/arm/stm32f0_disco/doc/index.rst b/boards/arm/stm32f0_disco/doc/index.rst index b7b40b1bf09..e2910793d72 100644 --- a/boards/arm/stm32f0_disco/doc/index.rst +++ b/boards/arm/stm32f0_disco/doc/index.rst @@ -134,10 +134,10 @@ References .. target-notes:: .. _STM32F0DISCOVERY website: - http://www.st.com/en/evaluation-tools/stm32f0discovery.html + https://www.st.com/en/evaluation-tools/stm32f0discovery.html .. _STM32F0x8 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031936.pdf + https://www.st.com/resource/en/reference_manual/dm00031936.pdf .. _STM32F0DISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00050135.pdf + https://www.st.com/resource/en/user_manual/dm00050135.pdf diff --git a/boards/arm/stm32f103_mini/doc/index.rst b/boards/arm/stm32f103_mini/doc/index.rst index ab3bbbd9188..57e812d0c3a 100644 --- a/boards/arm/stm32f103_mini/doc/index.rst +++ b/boards/arm/stm32f103_mini/doc/index.rst @@ -160,7 +160,7 @@ References .. target-notes:: .. _STM32F103 reference manual: - http://www.st.com/resource/en/reference_manual/cd00171190.pdf + https://www.st.com/resource/en/reference_manual/cd00171190.pdf .. _STM32F103 data sheet: - http://www.st.com/resource/en/datasheet/stm32f103rc.pdf + https://www.st.com/resource/en/datasheet/stm32f103rc.pdf diff --git a/boards/arm/stm32f3_disco/doc/index.rst b/boards/arm/stm32f3_disco/doc/index.rst index f0ccbfd7fca..a94083fa2c7 100644 --- a/boards/arm/stm32f3_disco/doc/index.rst +++ b/boards/arm/stm32f3_disco/doc/index.rst @@ -269,13 +269,13 @@ Again you have to use the adapted command for newer PCB revisions (E and newer): :goals: debug .. _STM32F3DISCOVERY website: - http://www.st.com/en/evaluation-tools/stm32f3discovery.html + https://www.st.com/en/evaluation-tools/stm32f3discovery.html .. _STM32F3DISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00063382.pdf + https://www.st.com/resource/en/user_manual/dm00063382.pdf .. _STM32F303VC on www.st.com: - http://www.st.com/en/microcontrollers/stm32f303vc.html + https://www.st.com/en/microcontrollers/stm32f303vc.html .. _STM32F303xC reference manual: - http://www.st.com/resource/en/reference_manual/dm00043574.pdf + https://www.st.com/resource/en/reference_manual/dm00043574.pdf diff --git a/boards/arm/stm32f3_seco_d23/doc/index.rst b/boards/arm/stm32f3_seco_d23/doc/index.rst index c551b2f3ca4..9b500e372ff 100644 --- a/boards/arm/stm32f3_seco_d23/doc/index.rst +++ b/boards/arm/stm32f3_seco_d23/doc/index.rst @@ -236,7 +236,7 @@ You should see the following message on the console: https://www.seco.com/Manuals/SBC-D23_Manual.pdf .. _STM32F302VC on www.st.com: - http://www.st.com/en/microcontrollers/stm32f302vc.html + https://www.st.com/en/microcontrollers/stm32f302vc.html .. _STM32F302xC reference manual: https://www.st.com/resource/en/reference_manual/rm0365-stm32f302xbcde-and-stm32f302x68-advanced-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/stm32f411e_disco/doc/index.rst b/boards/arm/stm32f411e_disco/doc/index.rst index 7744da987ab..d15dc7728c7 100644 --- a/boards/arm/stm32f411e_disco/doc/index.rst +++ b/boards/arm/stm32f411e_disco/doc/index.rst @@ -176,13 +176,13 @@ References .. target-notes:: .. _32F411EDISCOVERY website: - http://www.st.com/en/evaluation-tools/32f411ediscovery.html + https://www.st.com/en/evaluation-tools/32f411ediscovery.html .. _32F411EDISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00148985.pdf + https://www.st.com/resource/en/user_manual/dm00148985.pdf .. _STM32F411VE website: - http://www.st.com/en/microcontrollers/stm32f411ve.html + https://www.st.com/en/microcontrollers/stm32f411ve.html .. _STM32F411x reference manual: - http://www.st.com/resource/en/reference_manual/dm00119316.pdf + https://www.st.com/resource/en/reference_manual/dm00119316.pdf diff --git a/boards/arm/stm32f412g_disco/doc/index.rst b/boards/arm/stm32f412g_disco/doc/index.rst index 3849a0d7b9d..b79f9b18a0a 100644 --- a/boards/arm/stm32f412g_disco/doc/index.rst +++ b/boards/arm/stm32f412g_disco/doc/index.rst @@ -190,13 +190,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _32F412GDISCOVERY website: - http://www.st.com/en/evaluation-tools/32f412gdiscovery.html + https://www.st.com/en/evaluation-tools/32f412gdiscovery.html .. _32F412GDISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00275919.pdf + https://www.st.com/resource/en/user_manual/dm00275919.pdf .. _STM32F412ZG on www.st.com: - http://www.st.com/en/microcontrollers/stm32f412zg.html + https://www.st.com/en/microcontrollers/stm32f412zg.html .. _STM32F412 reference manual: - http://www.st.com/resource/en/reference_manual/dm00180369.pdf + https://www.st.com/resource/en/reference_manual/dm00180369.pdf diff --git a/boards/arm/stm32f429i_disc1/doc/index.rst b/boards/arm/stm32f429i_disc1/doc/index.rst index d397c414e4f..1a8defe5340 100644 --- a/boards/arm/stm32f429i_disc1/doc/index.rst +++ b/boards/arm/stm32f429i_disc1/doc/index.rst @@ -196,13 +196,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _STM32F429I-DISC1 website: - http://www.st.com/en/evaluation-tools/32f429idiscovery.html + https://www.st.com/en/evaluation-tools/32f429idiscovery.html .. _STM32F429I-DISC1 board User Manual: - http://www.st.com/web/en/resource/technical/document/user_manual/DM00097320.pdf + https://www.st.com/web/en/resource/technical/document/user_manual/DM00097320.pdf .. _STM32F429ZI on www.st.com: - http://www.st.com/en/microcontrollers/stm32f429-439.html + https://www.st.com/en/microcontrollers/stm32f429-439.html .. _STM32F429 Reference Manual: - http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf + https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf diff --git a/boards/arm/stm32f469i_disco/doc/index.rst b/boards/arm/stm32f469i_disco/doc/index.rst index b2c5fd5d3a0..7ba1d7c71e3 100644 --- a/boards/arm/stm32f469i_disco/doc/index.rst +++ b/boards/arm/stm32f469i_disco/doc/index.rst @@ -196,13 +196,13 @@ You can debug an application in the usual way. Here is an example for the .. _32F469IDISCOVERY website: - http://www.st.com/en/evaluation-tools/32f469idiscovery.html + https://www.st.com/en/evaluation-tools/32f469idiscovery.html .. _32F469IDISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00218846.pdf + https://www.st.com/resource/en/user_manual/dm00218846.pdf .. _STM32F469NI on www.st.com: - http://www.st.com/en/microcontrollers/stm32f469ni.html + https://www.st.com/en/microcontrollers/stm32f469ni.html .. _STM32F469 reference manual: - http://www.st.com/resource/en/reference_manual/dm00127514.pdf + https://www.st.com/resource/en/reference_manual/dm00127514.pdf diff --git a/boards/arm/stm32f4_disco/doc/index.rst b/boards/arm/stm32f4_disco/doc/index.rst index 2a0bd07cd27..8ea4ef9893c 100644 --- a/boards/arm/stm32f4_disco/doc/index.rst +++ b/boards/arm/stm32f4_disco/doc/index.rst @@ -199,16 +199,16 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _STM32F4DISCOVERY website: - http://www.st.com/en/evaluation-tools/stm32f4discovery.html + https://www.st.com/en/evaluation-tools/stm32f4discovery.html .. _STM32F4DISCOVERY board User Manual: - http://www.st.com/resource/en/user_manual/dm00039084.pdf + https://www.st.com/resource/en/user_manual/dm00039084.pdf .. _STM32F407VG on www.st.com: - http://www.st.com/en/microcontrollers/stm32f407vg.html + https://www.st.com/en/microcontrollers/stm32f407vg.html .. _STM32F407 reference manual: - http://www.st.com/resource/en/reference_manual/dm00031020.pdf + https://www.st.com/resource/en/reference_manual/dm00031020.pdf .. _SK Pang CAN breakout board: https://www.skpang.co.uk/products/can-bus-can-fd-breakout-board-5v-supply-and-3-3v-logic diff --git a/boards/arm/stm32f723e_disco/doc/index.rst b/boards/arm/stm32f723e_disco/doc/index.rst index 8fe202a75c3..5ebcc65c392 100644 --- a/boards/arm/stm32f723e_disco/doc/index.rst +++ b/boards/arm/stm32f723e_disco/doc/index.rst @@ -180,13 +180,13 @@ You can debug an application in the usual way. Here is an example for the .. _32F723E-DISCO website: - http://www.st.com/en/evaluation-tools/32f723ediscovery.html + https://www.st.com/en/evaluation-tools/32f723ediscovery.html .. _32F723E-DISCO board User Manual: - http://www.st.com/resource/en/user_manual/dm00342318.pdf + https://www.st.com/resource/en/user_manual/dm00342318.pdf .. _STM32F723IEK6 on www.st.com: - http://www.st.com/en/microcontrollers/stm32f723ie.html + https://www.st.com/en/microcontrollers/stm32f723ie.html .. _STM32F72xxx reference manual: - http://www.st.com/resource/en/reference_manual/dm00305990.pdf + https://www.st.com/resource/en/reference_manual/dm00305990.pdf diff --git a/boards/arm/stm32f746g_disco/doc/index.rst b/boards/arm/stm32f746g_disco/doc/index.rst index 579b19cffc8..c9b77967be9 100644 --- a/boards/arm/stm32f746g_disco/doc/index.rst +++ b/boards/arm/stm32f746g_disco/doc/index.rst @@ -231,13 +231,13 @@ You can debug an application in the usual way. Here is an example for the .. _32F746G-DISCO website: - http://www.st.com/en/evaluation-tools/32f746gdiscovery.html + https://www.st.com/en/evaluation-tools/32f746gdiscovery.html .. _32F746G-DISCO board User Manual: - http://www.st.com/resource/en/user_manual/dm00190424.pdf + https://www.st.com/resource/en/user_manual/dm00190424.pdf .. _STM32F746NGH6 on www.st.com: - http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html + https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html .. _STM32F74xxx reference manual: - http://www.st.com/resource/en/reference_manual/dm00124865.pdf + https://www.st.com/resource/en/reference_manual/dm00124865.pdf diff --git a/boards/arm/stm32f7508_dk/doc/index.rst b/boards/arm/stm32f7508_dk/doc/index.rst index e20d0ea3236..a3f39f37e5e 100644 --- a/boards/arm/stm32f7508_dk/doc/index.rst +++ b/boards/arm/stm32f7508_dk/doc/index.rst @@ -226,13 +226,13 @@ You can debug an application in the usual way. Here is an example for the .. _32F7508-DK website: - http://www.st.com/en/evaluation-tools/stm32f7508-dk.html + https://www.st.com/en/evaluation-tools/stm32f7508-dk.html .. _32F7508-DK board User Manual: - http://www.st.com/resource/en/user_manual/dm00537062-discovery-kit-for-stm32f7-series-with-stm32f750n8-mcu-stmicroelectronics.pdf + https://www.st.com/resource/en/user_manual/dm00537062-discovery-kit-for-stm32f7-series-with-stm32f750n8-mcu-stmicroelectronics.pdf .. _STM32F750x8 on www.st.com: https://www.st.com/resource/en/datasheet/stm32f750z8.pdf .. _STM32F74xxx reference manual: - http://www.st.com/resource/en/reference_manual/dm00124865.pdf + https://www.st.com/resource/en/reference_manual/dm00124865.pdf diff --git a/boards/arm/stm32f769i_disco/doc/index.rst b/boards/arm/stm32f769i_disco/doc/index.rst index 4346f67fbc1..d2183087b95 100644 --- a/boards/arm/stm32f769i_disco/doc/index.rst +++ b/boards/arm/stm32f769i_disco/doc/index.rst @@ -213,13 +213,13 @@ You can debug an application in the usual way. Here is an example for the .. _32F769I-DISCO website: - http://www.st.com/en/evaluation-tools/32f769idiscovery.html + https://www.st.com/en/evaluation-tools/32f769idiscovery.html .. _32F769I-DISCO board User Manual: - http://www.st.com/resource/en/user_manual/dm00276557.pdf + https://www.st.com/resource/en/user_manual/dm00276557.pdf .. _STM32F769NIH6 on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x9/stm32f769ni.html .. _STM32F76xxx reference manual: - http://www.st.com/resource/en/reference_manual/dm00224583.pdf + https://www.st.com/resource/en/reference_manual/dm00224583.pdf diff --git a/boards/arm/stm32g071b_disco/doc/index.rst b/boards/arm/stm32g071b_disco/doc/index.rst index a01020557ea..d7071c3d3d2 100644 --- a/boards/arm/stm32g071b_disco/doc/index.rst +++ b/boards/arm/stm32g071b_disco/doc/index.rst @@ -160,10 +160,10 @@ References https://www.st.com/en/evaluation-tools/stm32g071b-disco.html .. _STM32G071 reference manual: - http://www.st.com/resource/en/reference_manual/dm00371828.pdf + https://www.st.com/resource/en/reference_manual/dm00371828.pdf .. _STM32G0 Discovery board User Manual: https://www.st.com/resource/en/user_manual/dm00496511.pdf .. _G071RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32g071rb.html + https://www.st.com/en/microcontrollers/stm32g071rb.html diff --git a/boards/arm/stm32g081b_eval/doc/index.rst b/boards/arm/stm32g081b_eval/doc/index.rst index 6975509a62e..3e2268446c3 100644 --- a/boards/arm/stm32g081b_eval/doc/index.rst +++ b/boards/arm/stm32g081b_eval/doc/index.rst @@ -204,4 +204,4 @@ References https://www.st.com/resource/en/user_manual/um2403-evaluation-board-with-stm32g081rb-mcu-stmicroelectronics.pdf .. _G081RB on www.st.com: - http://www.st.com/en/microcontrollers/stm32g081rb.html + https://www.st.com/en/microcontrollers/stm32g081rb.html diff --git a/boards/arm/stm32h747i_disco/doc/index.rst b/boards/arm/stm32h747i_disco/doc/index.rst index 5610ad0e554..d020a3ed94e 100644 --- a/boards/arm/stm32h747i_disco/doc/index.rst +++ b/boards/arm/stm32h747i_disco/doc/index.rst @@ -281,13 +281,13 @@ In order to debug a Zephyr application on Cortex M4 side, you can use `STM32CubeIDE`_. .. _STM32H747I-DISCO website: - http://www.st.com/en/evaluation-tools/stm32h747i-disco.html + https://www.st.com/en/evaluation-tools/stm32h747i-disco.html .. _STM32H747XI on www.st.com: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32h7-series/stm32h747-757/stm32h747xi.html .. _STM32H747xx reference manual: - http://www.st.com/resource/en/reference_manual/dm00176879.pdf + https://www.st.com/resource/en/reference_manual/dm00176879.pdf .. _STM32H747xx datasheet: https://www.st.com/resource/en/datasheet/stm32h747xi.pdf diff --git a/boards/arm/stm32l476g_disco/doc/index.rst b/boards/arm/stm32l476g_disco/doc/index.rst index 61f2e5b59a4..bd4b2a5a6d5 100644 --- a/boards/arm/stm32l476g_disco/doc/index.rst +++ b/boards/arm/stm32l476g_disco/doc/index.rst @@ -206,13 +206,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _STM32L476G Discovery website: - http://www.st.com/en/evaluation-tools/32l476gdiscovery.html + https://www.st.com/en/evaluation-tools/32l476gdiscovery.html .. _STM32L476G Discovery board User Manual: - http://www.st.com/resource/en/user_manual/dm00172179.pdf + https://www.st.com/resource/en/user_manual/dm00172179.pdf .. _STM32L476VG on www.st.com: - http://www.st.com/en/microcontrollers/stm32l476vg.html + https://www.st.com/en/microcontrollers/stm32l476vg.html .. _STM32L476 reference manual: - http://www.st.com/resource/en/reference_manual/DM00083560.pdf + https://www.st.com/resource/en/reference_manual/DM00083560.pdf diff --git a/boards/arm/stm32l496g_disco/doc/index.rst b/boards/arm/stm32l496g_disco/doc/index.rst index 681969f08af..0bd31e72c38 100644 --- a/boards/arm/stm32l496g_disco/doc/index.rst +++ b/boards/arm/stm32l496g_disco/doc/index.rst @@ -247,13 +247,13 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _STM32L496G Discovery website: - http://www.st.com/en/evaluation-tools/32l496gdiscovery.html + https://www.st.com/en/evaluation-tools/32l496gdiscovery.html .. _STM32L496G Discovery board User Manual: - http://www.st.com/resource/en/user_manual/dm00353127.pdf + https://www.st.com/resource/en/user_manual/dm00353127.pdf .. _STM32L496AG on www.st.com: - http://www.st.com/en/microcontrollers/stm32l496ag.html + https://www.st.com/en/microcontrollers/stm32l496ag.html .. _STM32L496 reference manual: - http://www.st.com/resource/en/reference_manual/DM00083560.pdf + https://www.st.com/resource/en/reference_manual/DM00083560.pdf diff --git a/boards/arm/stm32l562e_dk/doc/index.rst b/boards/arm/stm32l562e_dk/doc/index.rst index e26887732ac..5a4f5845617 100644 --- a/boards/arm/stm32l562e_dk/doc/index.rst +++ b/boards/arm/stm32l562e_dk/doc/index.rst @@ -381,7 +381,7 @@ You can debug an application in the usual way. Here is an example for the https://www.st.com/en/microcontrollers/stm32l562qe.html .. _STM32L562 reference manual: - http://www.st.com/resource/en/reference_manual/DM00346336.pdf + https://www.st.com/resource/en/reference_manual/DM00346336.pdf .. _STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/shields/x_nucleo_idb05a1/doc/index.rst b/boards/shields/x_nucleo_idb05a1/doc/index.rst index 11ae6a7213a..c210e6ac6f1 100644 --- a/boards/shields/x_nucleo_idb05a1/doc/index.rst +++ b/boards/shields/x_nucleo_idb05a1/doc/index.rst @@ -95,7 +95,7 @@ References .. target-notes:: .. _X-NUCLEO-IDB05A1 website: - http://www.st.com/en/ecosystems/x-nucleo-idb05a1.html + https://www.st.com/en/ecosystems/x-nucleo-idb05a1.html .. _X-NUCLEO-IDB05A1 databrief: https://www.st.com/resource/en/data_brief/x-nucleo-idb05a1.pdf diff --git a/boards/shields/x_nucleo_iks01a1/doc/index.rst b/boards/shields/x_nucleo_iks01a1/doc/index.rst index 55cf9c9f9dd..329471e89f1 100644 --- a/boards/shields/x_nucleo_iks01a1/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a1/doc/index.rst @@ -54,7 +54,7 @@ References .. target-notes:: .. _X-NUCLEO-IKS01A1 website: - http://www.st.com/en/ecosystems/x-nucleo-iks01a1.html + https://www.st.com/en/ecosystems/x-nucleo-iks01a1.html .. _X-NUCLEO-IKS01A1 data sheet: - http://www.st.com/resource/en/datasheet/x-nucleo-iks01a1.pdf + https://www.st.com/resource/en/datasheet/x-nucleo-iks01a1.pdf diff --git a/boards/shields/x_nucleo_iks01a2/doc/index.rst b/boards/shields/x_nucleo_iks01a2/doc/index.rst index c0c764a49f8..9fa9d253520 100644 --- a/boards/shields/x_nucleo_iks01a2/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a2/doc/index.rst @@ -98,7 +98,7 @@ References .. target-notes:: .. _X-NUCLEO-IKS01A2 website: - http://www.st.com/en/ecosystems/x-nucleo-iks01a2.html + https://www.st.com/en/ecosystems/x-nucleo-iks01a2.html .. _X-NUCLEO-IKS01A2 databrief: - http://www.st.com/resource/en/data_brief/x-nucleo-iks01a2.pdf + https://www.st.com/resource/en/data_brief/x-nucleo-iks01a2.pdf diff --git a/boards/shields/x_nucleo_iks01a3/doc/index.rst b/boards/shields/x_nucleo_iks01a3/doc/index.rst index 9b65abc5df3..8da7bec906d 100644 --- a/boards/shields/x_nucleo_iks01a3/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a3/doc/index.rst @@ -95,7 +95,7 @@ References .. target-notes:: .. _X-NUCLEO-IKS01A3 website: - http://www.st.com/en/ecosystems/x-nucleo-iks01a3.html + https://www.st.com/en/ecosystems/x-nucleo-iks01a3.html .. _X-NUCLEO-IKS01A3 user manual: https://www.st.com/resource/en/user_manual/dm00601501.pdf diff --git a/boards/shields/x_nucleo_iks02a1/doc/index.rst b/boards/shields/x_nucleo_iks02a1/doc/index.rst index 128d1286ece..9dd1fc716b0 100644 --- a/boards/shields/x_nucleo_iks02a1/doc/index.rst +++ b/boards/shields/x_nucleo_iks02a1/doc/index.rst @@ -97,7 +97,7 @@ References .. target-notes:: .. _X-NUCLEO-IKS02A1 website: - http://www.st.com/en/ecosystems/x-nucleo-iks02a1.html + https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html .. _X-NUCLEO-IKS02A1 user manual: https://www.st.com/resource/en/user_manual/DM00651686.pdf diff --git a/drivers/sensor/vl53l0x/vl53l0x.c b/drivers/sensor/vl53l0x/vl53l0x.c index 6fc675a7934..bd822e9e6f2 100644 --- a/drivers/sensor/vl53l0x/vl53l0x.c +++ b/drivers/sensor/vl53l0x/vl53l0x.c @@ -28,9 +28,9 @@ LOG_MODULE_REGISTER(VL53L0X, CONFIG_SENSOR_LOG_LEVEL); /* All the values used in this driver are coming from ST datasheet and examples. * It can be found here: - * http://www.st.com/en/embedded-software/stsw-img005.html + * https://www.st.com/en/embedded-software/stsw-img005.html * There are also examples of use in the L4 cube FW: - * http://www.st.com/en/embedded-software/stm32cubel4.html + * https://www.st.com/en/embedded-software/stm32cubel4.html */ #define VL53L0X_INITIAL_ADDR 0x29 #define VL53L0X_REG_WHO_AM_I 0xC0 diff --git a/samples/sensor/hts221/README.rst b/samples/sensor/hts221/README.rst index 746bb1fa0a4..56734c08c35 100644 --- a/samples/sensor/hts221/README.rst +++ b/samples/sensor/hts221/README.rst @@ -17,7 +17,7 @@ This sample uses the HTS221 sensor controlled using the I2C interface. References ********** - - HTS211: http://www.st.com/en/mems-and-sensors/hts221.html + - HTS211: https://www.st.com/en/mems-and-sensors/hts221.html Building and Running ******************** diff --git a/samples/sensor/lis2dh/README.rst b/samples/sensor/lis2dh/README.rst index de4bd3d0b91..3e68414abce 100644 --- a/samples/sensor/lis2dh/README.rst +++ b/samples/sensor/lis2dh/README.rst @@ -20,7 +20,7 @@ References ********** For more information about the LIS2DH motion sensor see -http://www.st.com/en/mems-and-sensors/lis2dh.html. +https://www.st.com/en/mems-and-sensors/lis2dh.html. Building and Running ******************** diff --git a/samples/sensor/lps22hb/README.rst b/samples/sensor/lps22hb/README.rst index efbc20ca009..f469f05b6db 100644 --- a/samples/sensor/lps22hb/README.rst +++ b/samples/sensor/lps22hb/README.rst @@ -17,7 +17,7 @@ This sample uses the LPS22HB sensor controlled using the I2C interface. References ********** -- LPS22HB: http://www.st.com/en/mems-and-sensors/lps22hb.html +- LPS22HB: https://www.st.com/en/mems-and-sensors/lps22hb.html Building and Running ******************** diff --git a/samples/sensor/lps22hh/README.rst b/samples/sensor/lps22hh/README.rst index 545a6a59d48..ad0e780a076 100644 --- a/samples/sensor/lps22hh/README.rst +++ b/samples/sensor/lps22hh/README.rst @@ -17,7 +17,7 @@ This sample uses the LPS22HH sensor controlled using the I2C interface. References ********** -- LPS22HH: http://www.st.com/en/mems-and-sensors/lps22hh.html +- LPS22HH: https://www.st.com/en/mems-and-sensors/lps22hh.html Building and Running ******************** diff --git a/samples/sensor/lps22hh_i3c/README.rst b/samples/sensor/lps22hh_i3c/README.rst index 1077524037e..1f4ff486241 100644 --- a/samples/sensor/lps22hh_i3c/README.rst +++ b/samples/sensor/lps22hh_i3c/README.rst @@ -18,7 +18,7 @@ STEVALMKI192-V1 connected to the I3C header on :ref:`mimxrt685_evk`. References ********** -- LPS22HH: http://www.st.com/en/mems-and-sensors/lps22hh.html +- LPS22HH: https://www.st.com/en/mems-and-sensors/lps22hh.html Building and Running ******************** diff --git a/samples/sensor/lsm303dlhc/README.rst b/samples/sensor/lsm303dlhc/README.rst index b2da84cd413..1b8eed7c935 100644 --- a/samples/sensor/lsm303dlhc/README.rst +++ b/samples/sensor/lsm303dlhc/README.rst @@ -20,7 +20,7 @@ References ********** For more information about the LSM303DLHC eCompass module, see -http://www.st.com/en/mems-and-sensors/lsm303dlhc.html +https://www.st.com/en/mems-and-sensors/lsm303dlhc.html Building and Running ******************** diff --git a/samples/sensor/lsm6dsl/README.rst b/samples/sensor/lsm6dsl/README.rst index fb4d4d20bc8..e75cbe773db 100644 --- a/samples/sensor/lsm6dsl/README.rst +++ b/samples/sensor/lsm6dsl/README.rst @@ -20,7 +20,7 @@ It has been tested on both :ref:`96b_argonkey` and disco_l475_iot1 board. References ********** -- LSM6DSL http://www.st.com/en/mems-and-sensors/lsm6dsl.html +- LSM6DSL https://www.st.com/en/mems-and-sensors/lsm6dsl.html Building and Running ******************** diff --git a/samples/sensor/lsm6dso/README.rst b/samples/sensor/lsm6dso/README.rst index d9240d0d811..f0fda1781a4 100644 --- a/samples/sensor/lsm6dso/README.rst +++ b/samples/sensor/lsm6dso/README.rst @@ -18,7 +18,7 @@ It has been tested on the :ref:`stm32l562e_dk_board`. References ********** -- LSM6DSO http://www.st.com/en/mems-and-sensors/lsm6dso.html +- LSM6DSO https://www.st.com/en/mems-and-sensors/lsm6dso.html Building and Running ******************** diff --git a/samples/sensor/lsm6dso_i2c_on_i3c/README.rst b/samples/sensor/lsm6dso_i2c_on_i3c/README.rst index eb449879638..a4e42306d58 100644 --- a/samples/sensor/lsm6dso_i2c_on_i3c/README.rst +++ b/samples/sensor/lsm6dso_i2c_on_i3c/README.rst @@ -20,7 +20,7 @@ on :ref:`mimxrt685_evk`. References ********** -- LSM6DSO http://www.st.com/en/mems-and-sensors/lsm6dso.html +- LSM6DSO https://www.st.com/en/mems-and-sensors/lsm6dso.html Building and Running ******************** diff --git a/samples/sensor/vl53l0x/README.rst b/samples/sensor/vl53l0x/README.rst index 8f0b6a31984..242ddf455cc 100644 --- a/samples/sensor/vl53l0x/README.rst +++ b/samples/sensor/vl53l0x/README.rst @@ -18,7 +18,7 @@ This sample uses the VL53L0X sensor controlled using the I2C interface. References ********** - - VL53L0X: http://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html + - VL53L0X: https://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks01a1/README.rst b/samples/shields/x_nucleo_iks01a1/README.rst index f5c0d7b2bb1..58121c1f951 100644 --- a/samples/shields/x_nucleo_iks01a1/README.rst +++ b/samples/shields/x_nucleo_iks01a1/README.rst @@ -28,7 +28,7 @@ does not yet support sensors multiple instances. References ********** --X-NUCLEO-IKS01A1: http://www.st.com/en/ecosystems/x-nucleo-iks01a1.html +-X-NUCLEO-IKS01A1: https://www.st.com/en/ecosystems/x-nucleo-iks01a1.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst b/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst index 664658d4b84..5b97f057172 100644 --- a/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks01a2/sensorhub/README.rst @@ -36,7 +36,7 @@ does not yet support sensors multiple instances. References ********** --X-NUCLEO-IKS01A2: http://www.st.com/en/ecosystems/x-nucleo-iks01a2.html +-X-NUCLEO-IKS01A2: https://www.st.com/en/ecosystems/x-nucleo-iks01a2.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks01a2/standard/README.rst b/samples/shields/x_nucleo_iks01a2/standard/README.rst index 28dff866309..ccfedc1cfcb 100644 --- a/samples/shields/x_nucleo_iks01a2/standard/README.rst +++ b/samples/shields/x_nucleo_iks01a2/standard/README.rst @@ -32,7 +32,7 @@ does not yet support sensors multiple instances. References ********** --X-NUCLEO-IKS01A2: http://www.st.com/en/ecosystems/x-nucleo-iks01a2.html +-X-NUCLEO-IKS01A2: https://www.st.com/en/ecosystems/x-nucleo-iks01a2.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst b/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst index f13c0ecb8ba..ddd06b483a1 100644 --- a/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks01a3/sensorhub/README.rst @@ -46,7 +46,7 @@ as sensors multiple instances are not supported. References ********** -- X-NUCLEO-IKS01A3: http://www.st.com/en/ecosystems/x-nucleo-iks01a3.html +- X-NUCLEO-IKS01A3: https://www.st.com/en/ecosystems/x-nucleo-iks01a3.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks01a3/standard/README.rst b/samples/shields/x_nucleo_iks01a3/standard/README.rst index 0f9a554b51a..03213d0006c 100644 --- a/samples/shields/x_nucleo_iks01a3/standard/README.rst +++ b/samples/shields/x_nucleo_iks01a3/standard/README.rst @@ -39,7 +39,7 @@ as sensors multiple instances are not supported. References ********** -- X-NUCLEO-IKS01A3: http://www.st.com/en/ecosystems/x-nucleo-iks01a3.html +- X-NUCLEO-IKS01A3: https://www.st.com/en/ecosystems/x-nucleo-iks01a3.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst b/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst index ed8e62b9317..e8b17efc65c 100644 --- a/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst +++ b/samples/shields/x_nucleo_iks02a1/sensorhub/README.rst @@ -41,7 +41,7 @@ as sensors multiple instances are not supported. References ********** -- X-NUCLEO-IKS02A1: http://www.st.com/en/ecosystems/x-nucleo-iks02a1.html +- X-NUCLEO-IKS02A1: https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html Building and Running ******************** diff --git a/samples/shields/x_nucleo_iks02a1/standard/README.rst b/samples/shields/x_nucleo_iks02a1/standard/README.rst index 4e3c7e51a05..faa60e8387a 100644 --- a/samples/shields/x_nucleo_iks02a1/standard/README.rst +++ b/samples/shields/x_nucleo_iks02a1/standard/README.rst @@ -36,7 +36,7 @@ as sensors multiple instances are not supported. References ********** -- X-NUCLEO-IKS02A1: http://www.st.com/en/ecosystems/x-nucleo-iks02a1.html +- X-NUCLEO-IKS02A1: https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html Building and Running ******************** From ebfbf831531c182ecd9de6878d6e63f2ec3155cf Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 26 Sep 2023 14:06:16 +0300 Subject: [PATCH 1098/4498] net: lwm2m: Clean up shell documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move commands that require parameters first into the list. Move syntax line first, command documentation second, flags last. This is much like Unix commands do ❯ /bin/ls --help Usage: /bin/ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Compared to: uart:~$ lwm2m lwm2m - LwM2M commands Subcommands: read :read PATH [OPTIONS] Read value from LwM2M resource -x Read value as hex stream (default) -s Read value as string Signed-off-by: Seppo Takalo --- doc/connectivity/networking/api/lwm2m.rst | 68 ++++++++++++++--------- subsys/net/lib/lwm2m/lwm2m_shell.c | 22 ++++---- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 6ddc66a1836..eb699017f97 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -633,40 +633,58 @@ required actions from the server side. .. code-block:: console - uart:~$ lwm2m - lwm2m - LwM2M commands - Subcommands: - exec :Execute a resource - exec PATH - - read :Read value from LwM2M resource - read PATH [OPTIONS] - -s Read value as string (default) + uart:~$ lwm2m + lwm2m - LwM2M commands + Subcommands: + send :send PATHS + LwM2M SEND operation + + exec :exec PATH [PARAM] + Execute a resource + + read :read PATH [OPTIONS] + Read value from LwM2M resource + -x Read value as hex stream (default) + -s Read value as string -b Read value as bool (1/0) -uX Read value as uintX_t -sX Read value as intX_t -f Read value as float - - write :Write into LwM2M resource - write PATH [OPTIONS] VALUE - -s Value as string (default) - -b Value as bool - -uX Value as uintX_t - -sX Value as intX_t - -f Value as float - - start :Start the LwM2M RD (Registration / Discovery) Client - start EP_NAME [BOOTSTRAP FLAG] + -t Read value as time_t + + write :write PATH [OPTIONS] VALUE + Write into LwM2M resource + -s Write value as string (default) + -b Write value as bool + -uX Write value as uintX_t + -sX Write value as intX_t + -f Write value as float + -t Write value as time_t + + create :create PATH + Create object instance + + cache :cache PATH NUM + Enable data cache for resource + PATH is LwM2M path + NUM how many elements to cache + + start :start EP_NAME [BOOTSTRAP FLAG] + Start the LwM2M RD (Registration / Discovery) Client -b Set the bootstrap flag (default 0) - stop :Stop the LwM2M RD (De-register) Client - stop [OPTIONS] + stop :stop [OPTIONS] + Stop the LwM2M RD (De-register) Client -f Force close the connection - update :Trigger Registration Update of the LwM2M RD Client + update :Trigger Registration Update of the LwM2M RD Client + + pause :LwM2M engine thread pause + resume :LwM2M engine thread resume + lock :Lock the LwM2M registry + unlock :Unlock the LwM2M registry + - pause :LwM2M engine thread pause - resume :LwM2M engine thread resume .. _lwm2m_api_reference: diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index 2a86aa88d69..335004ec5d5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -22,10 +22,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #define LWM2M_HELP_CMD "LwM2M commands" -#define LWM2M_HELP_SEND "LwM2M SEND operation\nsend [OPTION]... [PATH]...\n" \ - "Root-level operation is unsupported" -#define LWM2M_HELP_EXEC "Execute a resource\nexec PATH [PARAM]\n" -#define LWM2M_HELP_READ "Read value from LwM2M resource\nread PATH [OPTIONS]\n" \ +#define LWM2M_HELP_SEND "send PATHS\nLwM2M SEND operation\n" +#define LWM2M_HELP_EXEC "exec PATH [PARAM]\nExecute a resource\n" +#define LWM2M_HELP_READ "read PATH [OPTIONS]\nRead value from LwM2M resource\n" \ "-x \tRead value as hex stream (default)\n" \ "-s \tRead value as string\n" \ "-b \tRead value as bool (1/0)\n" \ @@ -33,26 +32,25 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "-sX\tRead value as intX_t\n" \ "-f \tRead value as float\n" \ "-t \tRead value as time_t\n" -#define LWM2M_HELP_WRITE "Write into LwM2M resource\nwrite PATH [OPTIONS] VALUE\n" \ +#define LWM2M_HELP_WRITE "write PATH [OPTIONS] VALUE\nWrite into LwM2M resource\n" \ "-s \tWrite value as string (default)\n" \ "-b \tWrite value as bool\n" \ "-uX\tWrite value as uintX_t\n" \ "-sX\tWrite value as intX_t\n" \ "-f \tWrite value as float\n" \ "-t \tWrite value as time_t\n" -#define LWM2M_HELP_CREATE "Create object instance\ncreate PATH\n" -#define LWM2M_HELP_START "Start the LwM2M RD (Registration / Discovery) Client\n" \ - "start EP_NAME [BOOTSTRAP FLAG]\n" \ +#define LWM2M_HELP_CREATE "create PATH\nCreate object instance\n" +#define LWM2M_HELP_START "start EP_NAME [BOOTSTRAP FLAG]\n" \ + "Start the LwM2M RD (Registration / Discovery) Client\n" \ "-b \tSet the bootstrap flag (default 0)\n" -#define LWM2M_HELP_STOP "Stop the LwM2M RD (De-register) Client\nstop [OPTIONS]\n" \ +#define LWM2M_HELP_STOP "stop [OPTIONS]\nStop the LwM2M RD (De-register) Client\n" \ "-f \tForce close the connection\n" #define LWM2M_HELP_UPDATE "Trigger Registration Update of the LwM2M RD Client\n" #define LWM2M_HELP_PAUSE "LwM2M engine thread pause" #define LWM2M_HELP_RESUME "LwM2M engine thread resume" #define LWM2M_HELP_LOCK "Lock the LwM2M registry" #define LWM2M_HELP_UNLOCK "Unlock the LwM2M registry" -#define LWM2M_HELP_CACHE "Enable data cache for resource\n" \ - "cache PATH NUM\n" \ +#define LWM2M_HELP_CACHE "cache PATH NUM\nEnable data cache for resource\n" \ "PATH is LwM2M path\n" \ "NUM how many elements to cache\n" \ @@ -597,6 +595,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(read, NULL, LWM2M_HELP_READ, cmd_read, 2, 1), SHELL_CMD_ARG(write, NULL, LWM2M_HELP_WRITE, cmd_write, 3, 1), SHELL_CMD_ARG(create, NULL, LWM2M_HELP_CREATE, cmd_create, 2, 0), + SHELL_CMD_ARG(cache, NULL, LWM2M_HELP_CACHE, cmd_cache, 3, 0), SHELL_CMD_ARG(start, NULL, LWM2M_HELP_START, cmd_start, 2, 2), SHELL_CMD_ARG(stop, NULL, LWM2M_HELP_STOP, cmd_stop, 1, 1), SHELL_CMD_ARG(update, NULL, LWM2M_HELP_UPDATE, cmd_update, 1, 0), @@ -604,7 +603,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(resume, NULL, LWM2M_HELP_RESUME, cmd_resume, 1, 0), SHELL_CMD_ARG(lock, NULL, LWM2M_HELP_LOCK, cmd_lock, 1, 0), SHELL_CMD_ARG(unlock, NULL, LWM2M_HELP_UNLOCK, cmd_unlock, 1, 0), - SHELL_CMD_ARG(cache, NULL, LWM2M_HELP_CACHE, cmd_cache, 3, 0), SHELL_SUBCMD_SET_END); SHELL_COND_CMD_ARG_REGISTER(CONFIG_LWM2M_SHELL, lwm2m, &sub_lwm2m, From 4b934551ffca1cf146f154d9778899bbd4ca69f0 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Tue, 26 Sep 2023 15:06:20 +0200 Subject: [PATCH 1099/4498] scripts: pylib: twister: twisterlib: Fix size_calc error checking Fixes #63042 Signed-off-by: Lukasz Mrugala --- scripts/pylib/twister/twisterlib/size_calc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/size_calc.py b/scripts/pylib/twister/twisterlib/size_calc.py index 29d8ee2542e..8a98c447eba 100644 --- a/scripts/pylib/twister/twisterlib/size_calc.py +++ b/scripts/pylib/twister/twisterlib/size_calc.py @@ -257,9 +257,9 @@ def _get_info_elf_sections(self) -> None: # If build.log file exists, check errors (unrecognized sections # in ELF file). if self.buildlog_filename: - if name in SizeCalculator.alloc_sections or\ - SizeCalculator.rw_sections or\ - SizeCalculator.ro_sections: + if name in SizeCalculator.alloc_sections or \ + name in SizeCalculator.rw_sections or \ + name in SizeCalculator.ro_sections: continue else: stype = "unknown" From a50343cf6216f16495d9c7f52d4c518fa8754ab1 Mon Sep 17 00:00:00 2001 From: Franciszek Pindel Date: Fri, 1 Sep 2023 13:34:09 +0200 Subject: [PATCH 1100/4498] tests: twister: robot: Fix setting testcases status Currently, when a Robot test is run, the test case status value is reported as `None`, which causes the XML to contain information about the test being skipped due to misconfiguration. This commit fixes the value reported in Twister XML test result by assigning the test result to the `status` variable of a testcase instance after the test has finished running. Signed-off-by: Franciszek Pindel Signed-off-by: Piotr Zierhoffer --- scripts/pylib/twister/twisterlib/harness.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 6ae2622c810..b34c5a8b68c 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -143,10 +143,15 @@ def run_robot_test(self, command, handler): if cmake_proc.returncode == 0: self.instance.status = "passed" + # all tests in one Robot file are treated as a single test case, + # so its status should be set accordingly to the instance status + # please note that there should be only one testcase in testcases list + self.instance.testcases[0].status = "passed" else: logger.error("Robot test failure: %s for %s" % (handler.sourcedir, self.instance.platform.name)) self.instance.status = "failed" + self.instance.testcases[0].status = "failed" if out: with open(os.path.join(self.instance.build_dir, handler.log), "wt") as log: From b1b4932373c6a9b2665432b68df520223243886f Mon Sep 17 00:00:00 2001 From: Al Semjonovs Date: Thu, 14 Sep 2023 10:56:46 -0600 Subject: [PATCH 1101/4498] logging: Unused arg in log_msg_get_tid Resolve unused arg compiler error Signed-off-by: Al Semjonovs --- include/zephyr/logging/log_msg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index 4eee566bdc5..0279fb0d2cd 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -669,6 +669,7 @@ static inline void *log_msg_get_tid(struct log_msg *msg) #if CONFIG_LOG_THREAD_ID_PREFIX return msg->hdr.tid; #else + ARG_UNUSED(msg); return NULL; #endif } From f51575212b3574e9d97b804d87c3803e8ed31480 Mon Sep 17 00:00:00 2001 From: Joshua Lilly Date: Wed, 20 Sep 2023 12:50:28 -0700 Subject: [PATCH 1102/4498] testsuite: coverage: extend code coverage to include risc-v This PR adds regions for gcov symbols in bss to enable gcov functionality for risc-v Signed-off-by: Joshua Lilly --- subsys/testsuite/coverage/coverage_ram.ld | 23 +++++++++++--------- subsys/testsuite/coverage/coverage_rodata.ld | 4 ++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/subsys/testsuite/coverage/coverage_ram.ld b/subsys/testsuite/coverage/coverage_ram.ld index 108829fed05..df348cb8aba 100644 --- a/subsys/testsuite/coverage/coverage_ram.ld +++ b/subsys/testsuite/coverage/coverage_ram.ld @@ -26,9 +26,6 @@ SECTION_DATA_PROLOGUE(_GCOV_BSS_SECTION_NAME,(NOLOAD),) __gcov_bss_end = .; } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - -__gcov_bss_num_words = ((__gcov_bss_end - __gcov_bss_start) >> 2); -__gcov_bss_size = __gcov_bss_end - __gcov_bss_start; #endif #ifdef CONFIG_X86_64 @@ -42,9 +39,6 @@ SECTION_PROLOGUE(_GCOV_BSS_SECTION_NAME, (NOLOAD), ALIGN(16)) __gcov_bss_end = .; }GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -__gcov_bss_num_words = ((__gcov_bss_end - __gcov_bss_start) >> 2); -__gcov_bss_size = __gcov_bss_end - __gcov_bss_start; - #elif CONFIG_X86 SECTION_PROLOGUE(_GCOV_BSS_SECTION_NAME, (NOLOAD),) { @@ -55,9 +49,6 @@ SECTION_PROLOGUE(_GCOV_BSS_SECTION_NAME, (NOLOAD),) MMU_PAGE_ALIGN __gcov_bss_end = .; } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - -__gcov_bss_num_words = ((__gcov_bss_end - __gcov_bss_start) >> 2); -__gcov_bss_size = __gcov_bss_end - __gcov_bss_start; #endif #ifdef CONFIG_ARC @@ -73,7 +64,19 @@ SECTION_PROLOGUE(_GCOV_BSS_SECTION_NAME, (NOLOAD),) #endif __gcov_bss_end = .; } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif + +#ifdef CONFIG_RISCV +SECTION_PROLOGUE(_GCOV_BSS_SECTION_NAME, (NOLOAD),) +{ + MPU_MIN_SIZE_ALIGN + __gcov_bss_start = .; + *(".bss.__gcov0.*"); + . = ALIGN(4); + MPU_MIN_SIZE_ALIGN + __gcov_bss_end = .; +} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif __gcov_bss_num_words = ((__gcov_bss_end - __gcov_bss_start) >> 2); __gcov_bss_size = __gcov_bss_end - __gcov_bss_start; -#endif diff --git a/subsys/testsuite/coverage/coverage_rodata.ld b/subsys/testsuite/coverage/coverage_rodata.ld index 08654fba65a..03c1cd089e2 100644 --- a/subsys/testsuite/coverage/coverage_rodata.ld +++ b/subsys/testsuite/coverage/coverage_rodata.ld @@ -3,7 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifdef CONFIG_64BIT +. = ALIGN(8); +#else . = ALIGN(4); +#endif PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) From d732a8678bb34196b0231308278a2b0e3ce14ed2 Mon Sep 17 00:00:00 2001 From: David Corbeil Date: Tue, 26 Sep 2023 09:31:12 -0400 Subject: [PATCH 1103/4498] logging: runtime setting of syslog server ip address Added functionality to change the syslog server's ip address at runtime as well as sample for syslog network backend Signed-off-by: David Corbeil --- include/zephyr/logging/log_backend_net.h | 34 +++++++++++++++++ samples/net/syslog_net/Kconfig | 16 ++++++++ .../syslog_net/overlay-runtime-srv-addr.conf | 3 ++ samples/net/syslog_net/sample.yaml | 6 +++ samples/net/syslog_net/src/main.c | 11 ++++++ subsys/logging/backends/log_backend_net.c | 37 +++++++++++++++---- 6 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 include/zephyr/logging/log_backend_net.h create mode 100644 samples/net/syslog_net/overlay-runtime-srv-addr.conf diff --git a/include/zephyr/logging/log_backend_net.h b/include/zephyr/logging/log_backend_net.h new file mode 100644 index 00000000000..9141b481b8d --- /dev/null +++ b/include/zephyr/logging/log_backend_net.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 David Corbeil + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LOG_BACKEND_NET_H_ +#define ZEPHYR_LOG_BACKEND_NET_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Allows user to set a server IP address at runtime + * + * @details This function allows the user to set an IPv4 or IPv6 address at runtime. It can be + * called either before or after the backend has been initialized. If it gets called when + * the net logger backend context is running, it'll release it and create another one with + * the new address next time process() gets called. + * + * @param addr String that contains the IP address. + * + * @return True if parsing could be done, false otherwise. + */ +bool log_backend_net_set_addr(const char *addr); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LOG_BACKEND_NET_H_ */ diff --git a/samples/net/syslog_net/Kconfig b/samples/net/syslog_net/Kconfig index f7d18e9391c..e355e5683ec 100644 --- a/samples/net/syslog_net/Kconfig +++ b/samples/net/syslog_net/Kconfig @@ -12,4 +12,20 @@ config NET_SAMPLE_SEND_ITERATIONS Send sample data this many times before exiting. A value of zero means that the defaults in the application are used. + +config NET_SAMPLE_SERVER_RUNTIME + string "Syslog server IP address set at runtime" + help + Server address for the syslog server. + This server address gets set at rumtime by the sample + app defore the backend is initialized. This can be + either IPv4 or IPv6 address. Server listen UDP port + number can be configured here too. + Following syntax is supported: + 192.0.2.1:514 + 192.0.2.42 + [2001:db8::1]:514 + [2001:db8::2] + 2001:db::42 + source "Kconfig.zephyr" diff --git a/samples/net/syslog_net/overlay-runtime-srv-addr.conf b/samples/net/syslog_net/overlay-runtime-srv-addr.conf new file mode 100644 index 00000000000..55bc234183f --- /dev/null +++ b/samples/net/syslog_net/overlay-runtime-srv-addr.conf @@ -0,0 +1,3 @@ +CONFIG_LOG_BACKEND_NET_SERVER="" +CONFIG_LOG_BACKEND_NET_AUTOSTART=n +CONFIG_NET_SAMPLE_SERVER_RUNTIME="192.0.2.2:514" diff --git a/samples/net/syslog_net/sample.yaml b/samples/net/syslog_net/sample.yaml index 6eb8440e2c6..6a84d7d51cd 100644 --- a/samples/net/syslog_net/sample.yaml +++ b/samples/net/syslog_net/sample.yaml @@ -31,3 +31,9 @@ tests: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_LOG_BACKEND_NET_AUTOSTART=n + sample.net.syslog.runtime_srv_addr: + filter: TOOLCHAIN_HAS_NEWLIB == 1 + extra_configs: + - CONFIG_LOG_BACKEND_NET_AUTOSTART=n + - CONFIG_LOG_BACKEND_NET_SERVER="" + - CONFIG_NET_SAMPLE_SERVER_RUNTIME="192.0.2.2:514" diff --git a/samples/net/syslog_net/src/main.c b/samples/net/syslog_net/src/main.c index 50bf55668b2..b842e0ec03b 100644 --- a/samples/net/syslog_net/src/main.c +++ b/samples/net/syslog_net/src/main.c @@ -10,6 +10,7 @@ LOG_MODULE_REGISTER(net_syslog, LOG_LEVEL_DBG); #include #include +#include #include #include @@ -36,6 +37,16 @@ int main(void) const struct log_backend *backend = log_backend_net_get(); if (!log_backend_is_active(backend)) { + + /* Specifying an address by calling this function will + * override the value given to LOG_BACKEND_NET_SERVER. + It can also be called at any other time after the backend + is started. The net context will be released and + restarted with the newly specified address. + */ + if (strlen(CONFIG_LOG_BACKEND_NET_SERVER) == 0) { + log_backend_net_set_addr(CONFIG_NET_SAMPLE_SERVER_RUNTIME); + } log_backend_init(backend); log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_MAX_LEVEL); } diff --git a/subsys/logging/backends/log_backend_net.c b/subsys/logging/backends/log_backend_net.c index 7b99a05856f..c2236f98b66 100644 --- a/subsys/logging/backends/log_backend_net.c +++ b/subsys/logging/backends/log_backend_net.c @@ -10,6 +10,7 @@ LOG_MODULE_REGISTER(log_backend_net, CONFIG_LOG_DEFAULT_LEVEL); #include #include #include +#include #include #include @@ -196,19 +197,39 @@ static int format_set(const struct log_backend *const backend, uint32_t log_type return 0; } +bool log_backend_net_set_addr(const char *addr) +{ + if (net_init_done) { + const struct log_backend *backend = log_backend_net_get(); + /* Release context so it can be recreated with the specified ip address + * next time process() is called + */ + net_context_put(backend->cb->ctx); + net_init_done = false; + } + + net_sin(&server_addr)->sin_port = htons(514); + + bool ret = net_ipaddr_parse(addr, strlen(addr), &server_addr); + + if (!ret) { + LOG_ERR("Cannot parse syslog server address"); + return ret; + } + + return ret; +} + static void init_net(struct log_backend const *const backend) { ARG_UNUSED(backend); - int ret; - net_sin(&server_addr)->sin_port = htons(514); + if (strlen(CONFIG_LOG_BACKEND_NET_SERVER) != 0) { + bool ret = log_backend_net_set_addr(CONFIG_LOG_BACKEND_NET_SERVER); - ret = net_ipaddr_parse(CONFIG_LOG_BACKEND_NET_SERVER, - sizeof(CONFIG_LOG_BACKEND_NET_SERVER) - 1, - &server_addr); - if (ret == 0) { - LOG_ERR("Cannot configure syslog server address"); - return; + if (!ret) { + return; + } } log_backend_deactivate(log_backend_net_get()); From 1402d2d8b4265e059e82fe67dee9b3e837a5fa2d Mon Sep 17 00:00:00 2001 From: Jonas Otto Date: Thu, 21 Sep 2023 23:24:36 +0200 Subject: [PATCH 1104/4498] drivers: i2c_ll_stm32_v2: add warning about i2c speeds above fast The i2c_ll_stm32_v2 driver requires manual timing configuration for "fast mode plus" speed. This adds an error message linking to the appropriate documentation. Signed-off-by: Jonas Otto --- drivers/i2c/i2c_ll_stm32_v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index ea2e626f8ec..3f83bde5ddb 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -702,6 +702,8 @@ int stm32_i2c_configure_timing(const struct device *dev, uint32_t clock) i2c_setup_time_min = 500U; break; default: + LOG_ERR("i2c: speed above \"fast\" requires manual timing configuration, " + "see \"timings\" property of st,stm32-i2c-v2 devicetree binding"); return -EINVAL; } From e39d98302d9f9e7640b74f39335b9d59a9bf08ad Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 24 Sep 2023 07:10:31 +0200 Subject: [PATCH 1105/4498] Bluetooth: Controller: nRF53: Cleanup dppi and dppi resources file Minor cleanup typo, redundant conditional compile and refinition. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 4 ++-- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h | 2 +- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h | 5 ----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 3792111292a..787755866ab 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -341,7 +341,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). - * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; + * 2 adjacent PPIs (14 & 15) and 2 adjacent PPI groups are used for this wiring; * must be 0 or 1. must be a valid TIMER CC register offset. */ #define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) \ @@ -429,10 +429,10 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) (SW_SWITCH_TIMER_EVTS_COMP_PHYEND_DELAY_COMPENSATION_BASE + (index)) #define HAL_SW_SWITCH_RADIO_ENABLE_PHYEND_DELAY_COMPENSATION_PPI(index) \ HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) + /* Cancel the SW switch timer running considering PHYEND delay compensation timing: * wire the RADIO EVENTS_CTEPRESENT event to SW_SWITCH_TIMER TASKS_CAPTURE task. */ -#define HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI 16 #define HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI_REGISTER_EVT \ NRF_RADIO->PUBLISH_CTEPRESENT diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h index e1b47d03fd7..a8bbe8e63b4 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h @@ -98,7 +98,7 @@ /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). - * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; + * 2 adjacent PPIs (14 & 15) and 2 adjacent PPI groups are used for this wiring; * must be 0 or 1. must be a valid TIMER CC register offset. */ #define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE 14 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h index 5c5093f4b52..ab196e17d58 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h @@ -143,9 +143,6 @@ #define HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE 12 #endif -#if defined(CONFIG_BT_CTLR_PHY_CODED) && \ - defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) - /* Wire the SW SWITCH TIMER EVENTS_COMPARE[] event * to RADIO TASKS_TXEN/RXEN task. */ @@ -156,8 +153,6 @@ */ #define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI 19 -#endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ - #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) /* Wire the SW SWITCH PHYEND delay compensation TIMER EVENTS_COMPARE[] event to software * switch TIMER0->CLEAR taks task. From b61bd2364c1a4267f489910987d7d2c0d14e62c2 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 25 Sep 2023 10:17:22 +0200 Subject: [PATCH 1106/4498] Bluetooth: Controller: nrf53: Fix back-to-back Tx Rx implementation Back-to-back Tx Rx implementation was incorrect for nRF53 that uses DPPI. Both current and next DPPI channels where enabled in the implementation which only worked correctly to have the right tIFS when current and next PDU length were same. Fix ensures that the correct current DPPI is subscribed to by the radio subscribe. The implementation has been refactor to be able to use the current sw_tifs_toggle value in the HAL implementation. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 30 +++++- .../ll_sw/nordic/hal/nrf5/radio/radio.h | 2 + .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 100 ++++++++++++------ .../nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 66 +++++++----- .../controller/ll_sw/nordic/lll/lll_adv_iso.c | 2 +- 5 files changed, 133 insertions(+), 67 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 0b41a9bbfb6..a657ab95dfe 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -718,7 +718,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */ uint32_t delay; - hal_radio_sw_switch_setup(cc, ppi, sw_tifs_toggle); + hal_radio_sw_switch_setup(sw_tifs_toggle); /* NOTE: As constants are passed to dir_curr and dir_next, the * compiler should optimize out the redundant code path @@ -736,7 +736,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla hal_radio_tx_chain_delay_ns_get(phy_curr, flags_curr)); - hal_radio_b2b_txen_on_sw_switch(ppi); + hal_radio_b2b_txen_on_sw_switch(cc, ppi); } else { /* If RX PHY is LE Coded, calculate for S8 coding. * Assumption being, S8 has higher delay. @@ -746,7 +746,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_next) + hal_radio_rx_chain_delay_ns_get(phy_curr, 1)); - hal_radio_txen_on_sw_switch(ppi); + hal_radio_txen_on_sw_switch(cc, ppi); } #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) @@ -839,7 +839,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_curr)) + (EVENT_CLOCK_JITTER_US << 1); - hal_radio_rxen_on_sw_switch(ppi); + hal_radio_rxen_on_sw_switch(cc, ppi); } else { delay = HAL_RADIO_NS2US_CEIL( hal_radio_rx_ready_delay_ns_get(phy_next, @@ -848,7 +848,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_curr)) + (EVENT_CLOCK_JITTER_US << 1); - hal_radio_b2b_rxen_on_sw_switch(ppi); + hal_radio_b2b_rxen_on_sw_switch(cc, ppi); } @@ -982,6 +982,26 @@ void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr, #endif /* !CONFIG_BT_CTLR_TIFS_HW */ } +void radio_switch_complete_and_b2b_tx_disable(void) +{ +#if defined(CONFIG_BT_CTLR_TIFS_HW) + NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); +#else /* CONFIG_BT_CTLR_TIFS_HW */ + NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_PDU_END_DISABLE); + hal_radio_sw_switch_b2b_tx_disable(sw_tifs_toggle); +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ +} + +void radio_switch_complete_and_b2b_rx_disable(void) +{ +#if defined(CONFIG_BT_CTLR_TIFS_HW) + NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); +#else /* CONFIG_BT_CTLR_TIFS_HW */ + NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_PDU_END_DISABLE); + hal_radio_sw_switch_b2b_rx_disable(sw_tifs_toggle); +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ +} + void radio_switch_complete_and_disable(void) { #if defined(CONFIG_BT_CTLR_TIFS_HW) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index 600d7e95481..4bf833b233a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -106,6 +106,8 @@ void radio_switch_complete_and_b2b_tx(uint8_t phy_curr, uint8_t flags_curr, uint8_t phy_next, uint8_t flags_next); void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr, uint8_t phy_next, uint8_t flags_next); +void radio_switch_complete_and_b2b_tx_disable(void); +void radio_switch_complete_and_b2b_rx_disable(void); void radio_switch_complete_and_disable(void); uint8_t radio_phy_flags_rx_get(void); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 787755866ab..1fdf7d90d30 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -455,10 +455,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */ -static inline void hal_radio_sw_switch_setup( - uint8_t compare_reg, - uint8_t radio_enable_ppi, - uint8_t ppi_group_index) +static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) { /* Set up software switch mechanism for next Radio switch. */ @@ -466,7 +463,7 @@ static inline void hal_radio_sw_switch_setup( * over PPI[] */ HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; nrf_dppi_subscribe_set(NRF_DPPIC, HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(ppi_group_index)), HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI); @@ -476,55 +473,70 @@ static inline void hal_radio_sw_switch_setup( nrf_dppi_subscribe_clear(NRF_DPPIC, HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(other_grp))); +} +static inline void hal_radio_txen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) +{ /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do * not wire the task; it is done by the caller of * the function depending on the desired direction * (TX/RX). */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); -} -static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) -{ - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); } -static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t compare_reg_index, + uint8_t radio_enable_ppi) { - /* NOTE: Calling radio_tmr_start/radio_tmr_start_us/radio_tmr_start_now - * after the radio_switch_complete_and_b2b_tx() call would have - * changed the PPI channel to HAL_RADIO_ENABLE_ON_TICK_PPI as we - * cannot double buffer the subscribe buffer. Hence, lets have - * both DPPI channel enabled (other one was enabled by the DPPI - * group when the Radio End occurred) so that when both timer - * trigger one of the DPPI is correct in the radio tx - * subscription. + /* Wire SW Switch timer event to the + * PPI[] for enabling Radio. Do + * not wire the task; it is done by the caller of + * the function depending on the desired direction + * (TX/RX). */ - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); - nrf_dppi_channels_enable(NRF_DPPIC, BIT(ppi)); + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); + + uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + + radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); } -static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_rxen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) { - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); + /* Wire SW Switch timer event to the + * PPI[] for enabling Radio. Do + * not wire the task; it is done by the caller of + * the function depending on the desired direction + * (TX/RX). + */ + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); + + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); } -static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t compare_reg_index, + uint8_t radio_enable_ppi) { - /* NOTE: Calling radio_tmr_start/radio_tmr_start_us/radio_tmr_start_now - * after the radio_switch_complete_and_b2b_rx() call would have - * changed the PPI channel to HAL_RADIO_ENABLE_ON_TICK_PPI as we - * cannot double buffer the subscribe buffer. Hence, lets have - * both DPPI channel enabled (other one was enabled by the DPPI - * group when the Radio End occurred) so that when both timer - * trigger one of the DPPI is correct in the radio rx - * subscription. + /* Wire SW Switch timer event to the + * PPI[] for enabling Radio. Do + * not wire the task; it is done by the caller of + * the function depending on the desired direction + * (TX/RX). */ - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); - nrf_dppi_channels_enable(NRF_DPPIC, BIT(ppi)); + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); + + uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + + radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); } static inline void hal_radio_sw_switch_disable(void) @@ -540,6 +552,26 @@ static inline void hal_radio_sw_switch_disable(void) HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); } +static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index) +{ + hal_radio_sw_switch_disable(); + + uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); + + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); +} + +static inline void hal_radio_sw_switch_b2b_rx_disable(uint8_t compare_reg_index) +{ + hal_radio_sw_switch_disable(); + + uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); + + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); +} + static inline void hal_radio_sw_switch_cleanup(void) { hal_radio_sw_switch_disable(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index d964129bfa1..44cec4621a3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -420,10 +420,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX \ ((uint32_t)&(NRF_RADIO->TASKS_RXEN)) -static inline void hal_radio_sw_switch_setup( - uint8_t compare_reg, - uint8_t radio_enable_ppi, - uint8_t ppi_group_index) +static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) { /* Set up software switch mechanism for next Radio switch. */ @@ -435,53 +432,58 @@ static inline void hal_radio_sw_switch_setup( HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI, HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT, HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK(ppi_group_index)); +} +static inline void hal_radio_txen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) +{ /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do * not wire the task; it is done by the caller of * the function depending on the desired direction * (TX/RX). */ - nrf_ppi_event_endpoint_setup( - NRF_PPI, - radio_enable_ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg)); -} + nrf_ppi_event_endpoint_setup(NRF_PPI, radio_enable_ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg_index)); -static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) -{ - nrf_ppi_task_endpoint_setup( - NRF_PPI, - ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX); + nrf_ppi_task_endpoint_setup(NRF_PPI, radio_enable_ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX); } -static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t compare_reg_index, + uint8_t radio_enable_ppi) { /* NOTE: As independent PPI are used to trigger the Radio Tx task, * double buffers implementation works for sw_switch using PPIs, * simply reuse the hal_radio_txen_on_sw_switch() functon to set * the next PPIs task to be Radio Tx enable. */ - hal_radio_txen_on_sw_switch(ppi); + hal_radio_txen_on_sw_switch(compare_reg_index, radio_enable_ppi); } -static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_rxen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) { - nrf_ppi_task_endpoint_setup( - NRF_PPI, - ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX); + /* Wire SW Switch timer event to the + * PPI[] for enabling Radio. Do + * not wire the task; it is done by the caller of + * the function depending on the desired direction + * (TX/RX). + */ + nrf_ppi_event_endpoint_setup(NRF_PPI, radio_enable_ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg_index)); + + nrf_ppi_task_endpoint_setup(NRF_PPI, radio_enable_ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX); } -static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t ppi) +static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t compare_reg_index, + uint8_t radio_enable_ppi) { - /* NOTE: As independent PPI are used to trigger the Radio Rx task, + /* NOTE: As independent PPI are used to trigger the Radio Tx task, * double buffers implementation works for sw_switch using PPIs, - * simply reuse the hal_radio_rxen_on_sw_switch() functon to set - * the next PPIs task to be Radio Rx enable. + * simply reuse the hal_radio_txen_on_sw_switch() functon to set + * the next PPIs task to be Radio Tx enable. */ - hal_radio_rxen_on_sw_switch(ppi); + hal_radio_rxen_on_sw_switch(compare_reg_index, radio_enable_ppi); } static inline void hal_radio_sw_switch_disable(void) @@ -496,6 +498,16 @@ static inline void hal_radio_sw_switch_disable(void) BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI)); } +static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index) +{ + hal_radio_sw_switch_disable(); +} + +static inline void hal_radio_sw_switch_b2b_rx_disable(uint8_t compare_reg_index) +{ + hal_radio_sw_switch_disable(); +} + static inline void hal_radio_sw_switch_cleanup(void) { hal_radio_sw_switch_disable(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c index 87849d0e1fd..20e3fe528e1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c @@ -717,7 +717,7 @@ static void isr_tx_common(void *param, pkt_flags); } - radio_switch_complete_and_disable(); + radio_switch_complete_and_b2b_tx_disable(); radio_isr_set(isr_done_term, lll); } else { From 037618a638ec9be1c89511972d89622213f6ee2c Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 24 Sep 2023 17:57:28 +0200 Subject: [PATCH 1107/4498] drivers: ieee802154: rf2xx: Fix rx promiscuous behaviour When radio is set to promiscuous mode it is desirable to receive invalid frames. This skip a few checks and allow an invalid and non-standard frames be delivered for diagnose. Signed-off-by: Gerson Fernando Budke --- drivers/ieee802154/ieee802154_rf2xx.c | 12 ++++++++---- drivers/ieee802154/ieee802154_rf2xx.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index 8f6f4a37656..cdefa26f66e 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -179,7 +179,7 @@ static void rf2xx_trx_rx(const struct device *dev) pkt_len = rx_buf[RX2XX_FRAME_PHR_INDEX]; } - if (pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) { + if (!ctx->promiscuous && pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) { LOG_ERR("Invalid RX frame length"); return; } @@ -203,14 +203,14 @@ static void rf2xx_trx_rx(const struct device *dev) } ctx->pkt_lqi = rx_buf[pkt_len + RX2XX_FRAME_LQI_INDEX]; - if (trac == RF2XX_TRX_PHY_STATE_TRAC_INVALID) { + if (!ctx->promiscuous && trac == RF2XX_TRX_PHY_STATE_TRAC_INVALID) { LOG_ERR("Invalid RX frame"); - return; } if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && - !IS_ENABLED(CONFIG_NET_L2_OPENTHREAD)) { + !IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) && + pkt_len >= RX2XX_FRAME_FCS_LENGTH) { pkt_len -= RX2XX_FRAME_FCS_LENGTH; } @@ -775,8 +775,11 @@ static int rf2xx_pan_coord_set(const struct device *dev, bool pan_coordinator) static int rf2xx_promiscuous_set(const struct device *dev, bool promiscuous) { + struct rf2xx_context *ctx = dev->data; uint8_t reg; + ctx->promiscuous = promiscuous; + if (promiscuous) { reg = rf2xx_iface_reg_read(dev, RF2XX_XAH_CTRL_1_REG); reg |= (1 << RF2XX_AACK_PROM_MODE); @@ -903,6 +906,7 @@ static int power_on_and_setup(const struct device *dev) } ctx->tx_mode = IEEE802154_TX_MODE_CSMA_CA; + ctx->promiscuous = false; /* Configure INT behaviour */ config = (1 << RF2XX_RX_START) | diff --git a/drivers/ieee802154/ieee802154_rf2xx.h b/drivers/ieee802154/ieee802154_rf2xx.h index 04d15533c78..b77ec254d3a 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.h +++ b/drivers/ieee802154/ieee802154_rf2xx.h @@ -122,6 +122,7 @@ struct rf2xx_context { int8_t trx_rssi_base; uint8_t trx_version; uint8_t rx_phr; + bool promiscuous; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_RF2XX_H_ */ From 31c22c9a770654c1aefd88de997fd68ed17cdd28 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 25 Sep 2023 15:19:19 +0000 Subject: [PATCH 1108/4498] samples: gdbstub: test using pytest Test gdb stub using pytest. Co-developed-by: Grzegorz Chwierut Signed-off-by: Anas Nashif --- .../debug/gdbstub/pytest/test_gdbstub.py | 34 +++++++++++++++++++ samples/subsys/debug/gdbstub/run.gdbinit | 4 +-- samples/subsys/debug/gdbstub/sample.yaml | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100755 samples/subsys/debug/gdbstub/pytest/test_gdbstub.py diff --git a/samples/subsys/debug/gdbstub/pytest/test_gdbstub.py b/samples/subsys/debug/gdbstub/pytest/test_gdbstub.py new file mode 100755 index 00000000000..41dca1cfcae --- /dev/null +++ b/samples/subsys/debug/gdbstub/pytest/test_gdbstub.py @@ -0,0 +1,34 @@ +# Copyright (c) 2023 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 + +import os +import subprocess +from twister_harness import DeviceAdapter +import sys +import logging +import shlex + +ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") +sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "pylib", "twister")) +from twisterlib.cmakecache import CMakeCache + +logger = logging.getLogger(__name__) + + +def test_gdbstub(dut: DeviceAdapter): + """ + Test gdbstub feature using a gdb script. We connect to the DUT and run some + basic gdb commands and evaluate return code to determine pass or failure. + """ + build_dir = dut.device_config.build_dir + cmake_cache = CMakeCache.from_file(build_dir / 'CMakeCache.txt') + gdb = cmake_cache.get('CMAKE_GDB', None) + assert gdb + source_dir = cmake_cache.get('APPLICATION_SOURCE_DIR', None) + assert source_dir + cmd = [gdb, '-x', f'{source_dir}/run.gdbinit', f'{build_dir}/zephyr/zephyr.elf'] + logger.info(f'Test command: {shlex.join(cmd)}') + result = subprocess.run(cmd, capture_output=True, text=True, timeout=20) + logger.debug('Output:\n%s' % result.stdout) + assert result.returncode == 0 diff --git a/samples/subsys/debug/gdbstub/run.gdbinit b/samples/subsys/debug/gdbstub/run.gdbinit index 49181157ae2..abce598f54a 100644 --- a/samples/subsys/debug/gdbstub/run.gdbinit +++ b/samples/subsys/debug/gdbstub/run.gdbinit @@ -1,6 +1,6 @@ set pagination off -symbol-file zephyr/zephyr.elf -target remote 127.0.0.1:1234 +#symbol-file build/zephyr/zephyr.elf +target remote :5678 b test b main.c:33 c diff --git a/samples/subsys/debug/gdbstub/sample.yaml b/samples/subsys/debug/gdbstub/sample.yaml index 5f75a801541..638c5ec16cc 100644 --- a/samples/subsys/debug/gdbstub/sample.yaml +++ b/samples/subsys/debug/gdbstub/sample.yaml @@ -8,8 +8,8 @@ sample: name: gdbstub sample tests: sample.debug.gdbstub: - build_only: true platform_allow: qemu_x86 + harness: pytest tags: - debug - gdbstub From b16220916e6456bf02d7a9612e3988124c949f37 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Tue, 26 Sep 2023 12:30:45 +0300 Subject: [PATCH 1109/4498] manifest: update hal_xtensa Update hal_xtensa for NXP RT500 overlay support. Signed-off-by: Iuliana Prodan --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3de82d777d7..9ccc779c964 100644 --- a/west.yml +++ b/west.yml @@ -255,7 +255,7 @@ manifest: groups: - hal - name: hal_xtensa - revision: 86b7ddf984d54f34b79f52b328a4fecdae307956 + revision: e6da34fc07dfe96161ab8743f5dbeb6e6307ab93 path: modules/hal/xtensa groups: - hal From 36dec835c42bc395a0dd44dfbeb06c2a0282168b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 26 Sep 2023 14:16:02 +0200 Subject: [PATCH 1110/4498] samples: net: sockets: big_http_download: Update root certificate The download server that the origin server redirects to seems now to use different certificate (signed by a different root CA). Therefore add the additional root CA to the certificate list and refactor the sample code a bit to allow to easily extend/replace certificates in the future. Bump the mbed TLS heap size a bit to accommodate the extra registered certificate. Signed-off-by: Robert Lubos --- .../big_http_download/overlay-tls.conf | 2 +- .../src/DigiCertGlobalRootG2.crt.pem | 22 +++++++++++++++++++ .../big_http_download/src/big_http_download.c | 15 +++++++++---- .../big_http_download/src/ca_certificate.h | 10 ++++++--- 4 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 samples/net/sockets/big_http_download/src/DigiCertGlobalRootG2.crt.pem diff --git a/samples/net/sockets/big_http_download/overlay-tls.conf b/samples/net/sockets/big_http_download/overlay-tls.conf index 28ac8d4bc7d..78d1a7cef13 100644 --- a/samples/net/sockets/big_http_download/overlay-tls.conf +++ b/samples/net/sockets/big_http_download/overlay-tls.conf @@ -5,7 +5,7 @@ CONFIG_NET_PKT_TX_COUNT=10 CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=60000 +CONFIG_MBEDTLS_HEAP_SIZE=65000 CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y diff --git a/samples/net/sockets/big_http_download/src/DigiCertGlobalRootG2.crt.pem b/samples/net/sockets/big_http_download/src/DigiCertGlobalRootG2.crt.pem new file mode 100644 index 00000000000..51a0085fa1a --- /dev/null +++ b/samples/net/sockets/big_http_download/src/DigiCertGlobalRootG2.crt.pem @@ -0,0 +1,22 @@ +"-----BEGIN CERTIFICATE-----\n" +"MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\n" +"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n" +"MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\n" +"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" +"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\n" +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\n" +"2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\n" +"1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\n" +"q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\n" +"tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\n" +"vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\n" +"BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\n" +"5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\n" +"1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\n" +"NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\n" +"Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\n" +"8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\n" +"pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\n" +"MrY=\n" +"-----END CERTIFICATE-----\n" diff --git a/samples/net/sockets/big_http_download/src/big_http_download.c b/samples/net/sockets/big_http_download/src/big_http_download.c index c28c22b3159..b4e9ccffeda 100644 --- a/samples/net/sockets/big_http_download/src/big_http_download.c +++ b/samples/net/sockets/big_http_download/src/big_http_download.c @@ -274,9 +274,12 @@ bool download(struct addrinfo *ai, bool is_tls, bool *redirect) #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) if (is_tls) { - sec_tag_t sec_tag_opt[] = { - CA_CERTIFICATE_TAG, + sec_tag_t sec_tag_opt[ARRAY_SIZE(ca_certificates)]; + + for (int i = 0; i < ARRAY_SIZE(ca_certificates); i++) { + sec_tag_opt[i] = CA_CERTIFICATE_TAG + i; }; + CHECK(setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof(sec_tag_opt))); @@ -369,8 +372,12 @@ int main(void) bool redirect = false; #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) - tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, - ca_certificate, sizeof(ca_certificate)); + for (int i = 0; i < ARRAY_SIZE(ca_certificates); i++) { + tls_credential_add(CA_CERTIFICATE_TAG + i, + TLS_CREDENTIAL_CA_CERTIFICATE, + ca_certificates[i], + strlen(ca_certificates[i]) + 1); + } #endif setbuf(stdout, NULL); diff --git a/samples/net/sockets/big_http_download/src/ca_certificate.h b/samples/net/sockets/big_http_download/src/ca_certificate.h index 4f3e2e266b5..462f8f0052b 100644 --- a/samples/net/sockets/big_http_download/src/ca_certificate.h +++ b/samples/net/sockets/big_http_download/src/ca_certificate.h @@ -13,10 +13,14 @@ * certificate in PEM format, you can enable support for it in Kconfig. */ -/* ISRG Root X1 for https://launchpad.net/ubuntu */ -static const unsigned char ca_certificate[] = +/* ISRG Root X1 for https://launchpad.net/ubuntu + * DigiCert Global Root G2 for possible redirects + */ +static const unsigned char *ca_certificates[] = { #include "isrgrootx1.pem" -; +, +#include "DigiCertGlobalRootG2.crt.pem" +}; #endif /* __CA_CERTIFICATE_H__ */ From bcea9f7c92184151521ea1329bb1b3b3b8dd97ca Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 26 Sep 2023 14:30:41 +0200 Subject: [PATCH 1111/4498] samples: net: sockets: big_http_download: Align documentation Update the TLS part of the big_http_download sample to reference the currently used server used for file download. Signed-off-by: Robert Lubos --- samples/net/sockets/big_http_download/README.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/net/sockets/big_http_download/README.rst b/samples/net/sockets/big_http_download/README.rst index 222af88d573..d0b4551648b 100644 --- a/samples/net/sockets/big_http_download/README.rst +++ b/samples/net/sockets/big_http_download/README.rst @@ -79,11 +79,11 @@ An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The TLS version of this sample downloads a file from -https://www.7-zip.org/a/7z1805.exe (1.1MB). The certificate -used by the sample is in the sample's ``src`` directory and is configured -to access the default website configured in the sample for TLS -communication (https://www.7-zip.org). To access a different -web page over TLS, you'll need to provide a different certificate +https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/git/1:2.34.1-1ubuntu1/git_2.34.1.orig.tar.xz +(6.6MB). The certificates used by the sample are in the sample's ``src`` +directory and are used to access the default website configured in the sample +for TLS communication (https://launchpad.net) and possible redirects. To access +a different web page over TLS, you'll need to provide a different certificate to authenticate to that server. Note, that TLS support in the sample depends on non-posix, TLS socket From c7f8033f2b982a0d5548da458e00bee2e3a19502 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Tue, 26 Sep 2023 15:26:07 +0200 Subject: [PATCH 1112/4498] modules: lvgl: simplify sys_heap memory size configs Changes the Kconfig symbols for the sys_heap based memory management option and removes the notion of `BLOCKS` with a more concise single `LV_Z_MEM_POOL_SIZE` option. Also adds `LV_MEM_CUSTOM` to the lv_conf.h, since in any option the memory management is considered to be custom. Signed-off-by: Fabian Blatz --- modules/lvgl/Kconfig.memory | 23 ++++------------------- modules/lvgl/include/lv_conf.h | 1 + modules/lvgl/lvgl_mem.c | 6 ++---- samples/modules/lvgl/demos/prj.conf | 2 +- samples/subsys/display/lvgl/prj.conf | 2 +- tests/lib/gui/lvgl/prj.conf | 2 +- tests/lib/gui/lvgl/testcase.yaml | 3 +-- 7 files changed, 11 insertions(+), 28 deletions(-) diff --git a/modules/lvgl/Kconfig.memory b/modules/lvgl/Kconfig.memory index 29ccc8e910a..efd74540466 100644 --- a/modules/lvgl/Kconfig.memory +++ b/modules/lvgl/Kconfig.memory @@ -31,27 +31,12 @@ choice LV_Z_MEMORY_POOL endchoice -if LV_Z_MEM_POOL_SYS_HEAP - -config LV_Z_MEM_POOL_MIN_SIZE - int "Minimum memory pool block size" - default 16 - help - Size of the smallest block in the memory pool in bytes - -config LV_Z_MEM_POOL_MAX_SIZE - int "Maximum memory pool block size" +config LV_Z_MEM_POOL_SIZE + int "Memory pool size" default 2048 + depends on LV_Z_MEM_POOL_SYS_HEAP help - Size of the largest block in the memory pool in bytes - -config LV_Z_MEM_POOL_NUMBER_BLOCKS - int "Number of max size blocks in memory pool" - default 1 - help - Number of maximum sized blocks in the memory pool. - -endif + Size of the memory pool in bytes config LV_Z_VDB_SIZE int "Rendering buffer size" diff --git a/modules/lvgl/include/lv_conf.h b/modules/lvgl/include/lv_conf.h index 20e60058ae3..9dd7b510f73 100644 --- a/modules/lvgl/include/lv_conf.h +++ b/modules/lvgl/include/lv_conf.h @@ -11,6 +11,7 @@ /* Memory manager settings */ #define LV_MEMCPY_MEMSET_STD 1 +#define LV_MEM_CUSTOM 1 #if defined(CONFIG_LV_Z_MEM_POOL_HEAP_LIB_C) diff --git a/modules/lvgl/lvgl_mem.c b/modules/lvgl/lvgl_mem.c index ab6c912847f..001546a23ad 100644 --- a/modules/lvgl/lvgl_mem.c +++ b/modules/lvgl/lvgl_mem.c @@ -10,9 +10,7 @@ #include #include -#define HEAP_BYTES (CONFIG_LV_Z_MEM_POOL_MAX_SIZE * CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS) - -static char lvgl_heap_mem[HEAP_BYTES] __aligned(8); +static char lvgl_heap_mem[CONFIG_LV_Z_MEM_POOL_SIZE] __aligned(8); static struct sys_heap lvgl_heap; static struct k_spinlock lvgl_heap_lock; @@ -60,5 +58,5 @@ void lvgl_print_heap_info(bool dump_chunks) void lvgl_heap_init(void) { - sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], HEAP_BYTES); + sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], CONFIG_LV_Z_MEM_POOL_SIZE); } diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf index f7e061ef696..0b7217242f2 100644 --- a/samples/modules/lvgl/demos/prj.conf +++ b/samples/modules/lvgl/demos/prj.conf @@ -3,7 +3,7 @@ CONFIG_LOG=y CONFIG_SHELL=y CONFIG_LVGL=y -CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8 +CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_Z_SHELL=y CONFIG_LV_USE_MONKEY=y diff --git a/samples/subsys/display/lvgl/prj.conf b/samples/subsys/display/lvgl/prj.conf index 32ce28965ef..41c0eca6e70 100644 --- a/samples/subsys/display/lvgl/prj.conf +++ b/samples/subsys/display/lvgl/prj.conf @@ -1,4 +1,4 @@ -CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8 +CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_Z_SHELL=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/lib/gui/lvgl/prj.conf b/tests/lib/gui/lvgl/prj.conf index 6a784fd28cd..3e88939a88a 100644 --- a/tests/lib/gui/lvgl/prj.conf +++ b/tests/lib/gui/lvgl/prj.conf @@ -13,7 +13,7 @@ CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_LITTLEFS=y CONFIG_LVGL=y -CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8 +CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_Z_USE_FILESYSTEM=y CONFIG_LV_MEM_CUSTOM=y CONFIG_LV_USE_LOG=y diff --git a/tests/lib/gui/lvgl/testcase.yaml b/tests/lib/gui/lvgl/testcase.yaml index a2e7cc3e841..898c6d58806 100644 --- a/tests/lib/gui/lvgl/testcase.yaml +++ b/tests/lib/gui/lvgl/testcase.yaml @@ -22,8 +22,7 @@ tests: extra_configs: - CONFIG_LV_Z_BUFFER_ALLOC_DYNAMIC=y - CONFIG_LV_Z_MEM_POOL_SYS_HEAP=y - - CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=3 - - CONFIG_LV_Z_MEM_POOL_MAX_SIZE=32768 + - CONFIG_LV_Z_MEM_POOL_SIZE=98304 libraries.gui.lvgl.16bit: tags: - display From a2b238eee77cf9137db858618eb2881c53963330 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 26 Sep 2023 17:45:55 +0000 Subject: [PATCH 1113/4498] modules/MCUboot: Fix missing dependency The CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP has been missing select of CONFIG_MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index ab1dd44fbd5..1679bfeb8a9 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -192,6 +192,7 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT bool "MCUboot has been configured for DirectXIP with revert" select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. From acb4e2748ca37160db91dd9cdb59b3d72dc69213 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Mon, 25 Sep 2023 16:09:47 +0200 Subject: [PATCH 1114/4498] actions: greet: Update the PR greeting text Update the text so it points to useful parts of the documentation regarding CI and contribution guidelines. Also invite users to join Discord to ask for help. Signed-off-by: Carles Cufi --- .../workflows/greet_first_time_contributor.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/greet_first_time_contributor.yml b/.github/workflows/greet_first_time_contributor.yml index c4f9b5764e6..5984b29fe1f 100644 --- a/.github/workflows/greet_first_time_contributor.yml +++ b/.github/workflows/greet_first_time_contributor.yml @@ -29,12 +29,18 @@ jobs: Hello @${{ github.event.pull_request.user.login }}, and thank you very much for your first pull request to the Zephyr project! - - A project maintainer just triggered our CI pipeline to run it against your PR and - ensure it's compliant and doesn't cause any issues. You might want to take this - opportunity to review the project's [Contributor + Our Continuous Integration pipeline will execute a series of checks on your Pull Request + commit messages and code, and you are expected to address any failures by updating the PR. + Please take a look at [our commit message guidelines](https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-message-guidelines) + to find out how to format your commit messages, and at [our contribution workflow](https://docs.zephyrproject.org/latest/contribute/guidelines.html#contribution-workflow) + to understand how to update your Pull Request. + If you haven't already, please make sure to review the project's [Contributor Expectations](https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html) - and make any updates to your pull request if necessary. 😊 + and update (by amending and force-pushing the commits) your pull request if necessary. + + If you are stuck or need help please join us on [Discord](https://chat.zephyrproject.org/) + and ask your question there. Additionally, you can [escalate the review](https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html#pr-review-escalation) + when applicable. 😊 pr-merged-message: > Hi @${{ github.event.pull_request.user.login }}! From 7c0137afa61bef62d0890d2860e3283877cab9dc Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 27 Sep 2023 07:51:27 +0100 Subject: [PATCH 1115/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 6c8c76fc37f10d7f3ce44474dc2a450f61ff46e0 Brings following Zephyr relevant fixes: - 4da51013 zephyr: Add shared data support - 9bef51ce bootutil/crypto: Do not include import key with PSA - db2024eb espressif: update secure boot and flash encryption Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9ccc779c964..bed5974b0cb 100644 --- a/west.yml +++ b/west.yml @@ -287,7 +287,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 736234caa5ee0b3090cf02e5af0c2dc798aa4beb + revision: 6c8c76fc37f10d7f3ce44474dc2a450f61ff46e0 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From df64ae2d2d8dba1efd9f6e09d698c035e15e5e25 Mon Sep 17 00:00:00 2001 From: Neal Liu Date: Fri, 15 Sep 2023 08:01:46 +0800 Subject: [PATCH 1116/4498] dts: bindings: reset: ast10x0: revise cells' name Revise property's name & cells' name for further devicetree reset macro used. Signed-off-by: Neal Liu Signed-off-by: Dylan Hung --- dts/bindings/reset/aspeed,ast10x0-reset.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/bindings/reset/aspeed,ast10x0-reset.yaml b/dts/bindings/reset/aspeed,ast10x0-reset.yaml index a6d7a14ecce..b4864cb5594 100644 --- a/dts/bindings/reset/aspeed,ast10x0-reset.yaml +++ b/dts/bindings/reset/aspeed,ast10x0-reset.yaml @@ -11,5 +11,5 @@ properties: "#reset-cells": const: 1 -clock-cells: - - reset_id +reset-cells: + - id From bdda8ac48e31bb7e1c0309f4146b3e964cb33499 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 30 Aug 2023 17:10:01 -0300 Subject: [PATCH 1117/4498] soc: esp32s3: add esp32s3_appcpu for AMP support Adds esp32s3_appcpu SoC and update default esp32s3 SoC to support AMP feature. Signed-off-by: Sylvio Alves --- drivers/clock_control/clock_control_esp32.c | 5 + drivers/ipm/ipm_esp32.c | 18 +- drivers/serial/serial_esp32_usb.c | 4 +- .../espressif/esp32s3/esp32s3_appcpu.dtsi | 7 + .../espressif/esp32s3/esp32s3_common.dtsi | 20 + .../espressif_esp32/esp32s3/CMakeLists.txt | 52 ++- .../espressif_esp32/esp32s3/Kconfig.series | 14 +- .../espressif_esp32/esp32s3/Kconfig.soc | 17 +- soc/xtensa/espressif_esp32/esp32s3/default.ld | 14 +- .../espressif_esp32/esp32s3/default_appcpu.ld | 372 ++++++++++++++++++ .../espressif_esp32/esp32s3/esp32s3-mp.c | 45 +++ soc/xtensa/espressif_esp32/esp32s3/linker.ld | 7 +- soc/xtensa/espressif_esp32/esp32s3/soc.c | 48 ++- .../espressif_esp32/esp32s3/soc_appcpu.c | 172 ++++++++ tests/drivers/pwm/pwm_api/src/test_pwm.c | 2 +- west.yml | 2 +- 16 files changed, 769 insertions(+), 30 deletions(-) create mode 100644 dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi create mode 100644 soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld create mode 100644 soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c create mode 100644 soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index ea8836d8d75..fba7091b871 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -328,6 +328,11 @@ static void esp32_clock_perip_init(void) #if defined(CONFIG_SOC_SERIES_ESP32S3) static void esp32_clock_perip_init(void) { +#if defined(CONFIG_SOC_ESP32S3_APPCPU) + /* skip APPCPU configuration */ + return; +#endif + uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; uint32_t common_perip_clk1 = 0; diff --git a/drivers/ipm/ipm_esp32.c b/drivers/ipm/ipm_esp32.c index 9f7e6063519..cbe6e42d90f 100644 --- a/drivers/ipm/ipm_esp32.c +++ b/drivers/ipm/ipm_esp32.c @@ -54,9 +54,17 @@ IRAM_ATTR static void esp32_ipm_isr(const struct device *dev) /* clear interrupt flag */ if (core_id == 0) { +#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); +#elif defined(CONFIG_SOC_SERIES_ESP32S3) + WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0); +#endif } else { +#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); +#elif defined(CONFIG_SOC_SERIES_ESP32S3) + WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0); +#endif } /* first of all take the own of the shared memory */ @@ -130,12 +138,21 @@ static int esp32_ipm_send(const struct device *dev, int wait, uint32_t id, memcpy(dev_data->shm.app_cpu_shm, data, size); atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL); LOG_DBG("Generating interrupt on remote CPU 1 from CPU 0"); +#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1); +#elif defined(CONFIG_SOC_SERIES_ESP32S3) + WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1); +#endif + } else { memcpy(dev_data->shm.pro_cpu_shm, data, size); atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL); LOG_DBG("Generating interrupt on remote CPU 0 from CPU 1"); +#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0); +#elif defined(CONFIG_SOC_SERIES_ESP32S3) + WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0); +#endif } irq_unlock(key); @@ -217,7 +234,6 @@ static int esp32_ipm_init(const struct device *dev) NULL); LOG_DBG("Waiting CPU0 to sync"); - while (!atomic_cas(&data->control->lock, ESP32_IPM_LOCK_FREE_VAL, data->this_core_id)) ; diff --git a/drivers/serial/serial_esp32_usb.c b/drivers/serial/serial_esp32_usb.c index 06b93e79329..14e4b798a8f 100644 --- a/drivers/serial/serial_esp32_usb.c +++ b/drivers/serial/serial_esp32_usb.c @@ -13,7 +13,7 @@ #include #include #include -#if defined(CONFIG_SOC_ESP32C3) +#if defined(CONFIG_SOC_SERIES_ESP32C3) #include #else #include @@ -22,7 +22,7 @@ #include #include -#ifdef CONFIG_SOC_ESP32C3 +#ifdef CONFIG_SOC_SERIES_ESP32C3 #define ISR_HANDLER isr_handler_t #else #define ISR_HANDLER intr_handler_t diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi new file mode 100644 index 00000000000..c405bfedecd --- /dev/null +++ b/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp32s3_common.dtsi" diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index a5b98a9f52b..7655b3537db 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -58,6 +58,16 @@ reg = <0x3fc88000 0x77FFF>; }; + ipmmem0: memory@3fcbd000 { + compatible = "mmio-sram"; + reg = <0x3fcbd000 0x400>; + }; + + shm0: memory@3fcbd400 { + compatible = "mmio-sram"; + reg = <0x3fcbd400 0x4000>; + }; + intc: interrupt-controller@600c2000 { #interrupt-cells = <1>; compatible = "espressif,esp32-intc"; @@ -107,6 +117,16 @@ status = "disabled"; }; + ipm0: ipm@3fcc1400 { + compatible = "espressif,esp32-ipm"; + reg = <0x3fcc1400 0x8>; + status = "disabled"; + shared-memory = <&ipmmem0>; + shared-memory-size = <0x400>; + interrupts = ; + interrupt-parent = <&intc>; + }; + uart0: uart@60000000 { compatible = "espressif,esp32-uart"; reg = <0x60000000 0x1000>; diff --git a/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt b/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt index 87d71798159..dc9e86d6604 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt +++ b/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt @@ -1,21 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( - soc.c - soc_cache.c - loader.c - ) +if (CONFIG_SOC_ESP32S3_APPCPU) + zephyr_sources(soc_appcpu.c) +else() + zephyr_sources( + soc.c + soc_cache.c + loader.c + esp32s3-mp.c + ) +endif() zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c) -# get code-partition slot0 address -dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -dt_reg_addr(img_0_off PATH ${dts_partition_path}) - -# get code-partition boot address -dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -dt_reg_addr(boot_off PATH ${dts_partition_path}) - # get flash size to use in esptool as string math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") @@ -87,8 +84,31 @@ if(CONFIG_MCUBOOT OR CONFIG_BOOTLOADER_ESP_IDF) endif() -set_property(TARGET bintools PROPERTY disassembly_flag_inline_source) +## When building for APPCPU +if (CONFIG_SOC_ESP32S3_APPCPU) + + if(CONFIG_BUILD_OUTPUT_BIN) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/esp_bin2c_array.py + ARGS -i ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.c + -a "esp32s3_appcpu_fw_array") + endif() -board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}") +else() -board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") + set_property(TARGET bintools PROPERTY disassembly_flag_inline_source) + + # get code-partition slot0 address + dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") + dt_reg_addr(img_0_off PATH ${dts_partition_path}) + + # get code-partition boot address + dt_nodelabel(dts_partition_path NODELABEL "boot_partition") + dt_reg_addr(boot_off PATH ${dts_partition_path}) + + board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}") + + board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") + +endif() diff --git a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.series b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.series index 1265375c12a..6f5fcf88c17 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.series +++ b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.series @@ -12,5 +12,17 @@ config SOC_SERIES_ESP32S3 select XIP if !MCUBOOT select HAS_ESPRESSIF_HAL select CPU_HAS_FPU + +config SOC_ESP32S3_PROCPU + bool "Application runs in ESP32S3 PROCPU (core 0)" + depends on SOC_SERIES_ESP32S3 + help + When this SOC is enabled, it will run application on PROCPU (core 0). It will automatically + enable AMP support by building, flashing and loading APPCPU (core 1) image if exists. + +config SOC_ESP32S3_APPCPU + bool "Application runs in ESP32S3 APPCPU (core 1)" + depends on SOC_SERIES_ESP32S3 help - Enable support for Espressif ESP32-S3 + When this SOC is enabled, it will run application on APPCPU (core 1). It is expected that + there is another image running on PROCPU (core 0) to trigger the AMP support. diff --git a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc index ac265e5edb0..b8cc95b62cb 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc +++ b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc @@ -13,11 +13,8 @@ config SOC_TOOLCHAIN_NAME choice SOC_PART_NUMBER prompt "ESP32-S3 SOC Selection" - depends on SOC_SERIES_ESP32S3 # SoC with/without embedded flash - config SOC_ESP32S3 - bool "ESP32S3" config SOC_ESP32S3_R2 bool "ESP32S3_R2" config SOC_ESP32S3_R8 @@ -50,6 +47,20 @@ choice SOC_PART_NUMBER endchoice # SOC_PART_NUMBER +config ESP32S3_APPCPU_IRAM + hex "ESP32S3 APPCPU IRAM size" + depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU + default 0x20000 + help + Defines APPCPU IRAM area in bytes. + +config ESP32S3_APPCPU_DRAM + hex "ESP32S3 APPCPU DRAM size" + depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU + default 0x10000 + help + Defines APPCPU DRAM area in bytes. + choice ESP32S3_RTC_CLK_SRC prompt "RTC clock source" default ESP32S3_RTC_CLK_SRC_INT_RC diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index fc6a4e47d0e..c9bab6f3cad 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -57,6 +57,14 @@ #define IROM_SEG_LEN FLASH_SIZE #endif +#ifdef CONFIG_SOC_ESP32S3_PROCPU +#define APPCPU_IRAM_SIZE CONFIG_ESP32S3_APPCPU_IRAM +#define APPCPU_DRAM_SIZE CONFIG_ESP32S3_APPCPU_DRAM +#else +#define APPCPU_IRAM_SIZE 0x0 +#define APPCPU_DRAM_SIZE 0x0 +#endif + #define IROM_SEG_ALIGN 0x10000 /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. @@ -69,9 +77,10 @@ MEMORY mcuboot_hdr (RX): org = 0x0, len = 0x20 metadata (RX): org = 0x20, len = 0x20 ROM (RX): org = 0x40, len = FLASH_SIZE - 0x40 - iram0_0_seg(RX): org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE + iram0_0_seg(RX): org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE - APPCPU_IRAM_SIZE + dram0_0_seg(RW): org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN - APPCPU_DRAM_SIZE + irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN - dram0_0_seg(RW): org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN /* DROM is the first segment placed in generated binary. * MCUboot binary for ESP32 has image header of 0x20 bytes. @@ -86,6 +95,7 @@ MEMORY #if defined(CONFIG_ESP_SPIRAM) ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE #endif + /* RTC fast memory (executable). Persists over deep sleep. */ rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000 diff --git a/soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld b/soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld new file mode 100644 index 00000000000..d5e0e2fe3e9 --- /dev/null +++ b/soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define SRAM_IRAM_START 0x40370000 +#define SRAM_DIRAM_I_START 0x40378000 +#define SRAM_IRAM_END 0x403BA000 +#define I_D_SRAM_OFFSET (SRAM_DIRAM_I_START - SRAM_DRAM_START) + +#define SRAM_DRAM_START 0x3FC88000 +#define SRAM_DRAM_END (SRAM_IRAM_END - I_D_SRAM_OFFSET) + +#define IRAM_REGION iram0_0_seg +#define RAMABLE_REGION dram0_0_seg +#define ROMABLE_REGION iram0_0_seg + +#define IROM_SEG_ALIGN 0x4 + +MEMORY +{ + iram0_0_seg(RX): org = SRAM_IRAM_END - CONFIG_ESP32S3_APPCPU_IRAM, len = CONFIG_ESP32S3_APPCPU_IRAM + dram0_0_seg(RW): org = SRAM_DRAM_END - CONFIG_ESP32S3_APPCPU_DRAM, len = CONFIG_ESP32S3_APPCPU_DRAM +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* Default entry point: */ +ENTRY(__app_cpu_start) + +SECTIONS +{ + #include + + /* Send .iram0 code to iram */ + .iram0.vectors : ALIGN(4) + { + /* Vectors go to IRAM */ + _init_start = ABSOLUTE(.); + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + . = 0x0; + KEEP(*(.WindowVectors.text)); + . = 0x180; + KEEP(*(.Level2InterruptVector.text)); + . = 0x1c0; + KEEP(*(.Level3InterruptVector.text)); + . = 0x200; + KEEP(*(.Level4InterruptVector.text)); + . = 0x240; + KEEP(*(.Level5InterruptVector.text)); + . = 0x280; + KEEP(*(.DebugExceptionVector.text)); + . = 0x2c0; + KEEP(*(.NMIExceptionVector.text)); + . = 0x300; + KEEP(*(.KernelExceptionVector.text)); + . = 0x340; + KEEP(*(.UserExceptionVector.text)); + . = 0x3C0; + KEEP(*(.DoubleExceptionVector.text)); + . = 0x400; + _invalid_pc_placeholder = ABSOLUTE(.); + *(.*Vector.literal) + + *(.UserEnter.literal); + *(.UserEnter.text); + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN (4); + _init_end = ABSOLUTE(.); + + _iram_start = ABSOLUTE(.); + } GROUP_LINK_IN(IRAM_REGION) + + SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) + { + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *libesp32.a:panic.*(.literal .text .literal.* .text.*) + *librtc.a:(.literal .text .literal.* .text.*) + *libarch__xtensa__core.a:(.literal .text .literal.* .text.*) + *libkernel.a:(.literal .text .literal.* .text.*) + *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) + *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) + *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) + *libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) + *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) + *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_core.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_complete.*(.literal .text .literal.* .text.*) + *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) + *libzephyr.a:log_msg.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_list.*(.literal .text .literal.* .text.*) + *libdrivers__console.a:uart_console.*(.literal.console_out .text.console_out) + *libzephyr.a:log_output.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*) + *libzephyr.a:loader.*(.literal .text .literal.* .text.*) + *liblib__libc__minimal.a:string.*(.literal .text .literal.* .text.*) + *liblib__libc__newlib.a:string.*(.literal .text .literal.* .text.*) + *libc.a:*(.literal .text .literal.* .text.*) + *libphy.a:(.phyiram .phyiram.*) + *libgcov.a:(.literal .text .literal.* .text.*) + + . = ALIGN(4); + _iram_end = ABSOLUTE(.); + . = ALIGN(4) + 16; + + } GROUP_LINK_IN(IRAM_REGION) + + SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) + { + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + __rodata_region_start = ABSOLUTE(.); + . = ALIGN(4); + #include + + . = ALIGN(4); + *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__serial.a:uart_esp32.*) .rodata) + *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__serial.a:uart_esp32.*) .rodata.*) + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); + __rodata_region_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + *(.rodata_wlog) + *(.rodata_wlog*) + _thread_local_end = ABSOLUTE(.); + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + + /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. + * Executing directly from LMA is not possible. */ + #pragma push_macro("GROUP_ROM_LINK_IN") + #undef GROUP_ROM_LINK_IN + #define GROUP_ROM_LINK_IN(vregion, lregion) > RAMABLE_REGION AT > lregion + #include + #include + #include + #include + #include + #include + #include + #pragma pop_macro("GROUP_ROM_LINK_IN") + + /* Create an explicit section at the end of all the data that shall be mapped into drom. + * This is used to calculate the size of the _image_drom_size variable */ + SECTION_PROLOGUE(_RODATA_SECTION_END,,) + { + . = ALIGN(16); + _image_rodata_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + +#include + + .dram0.data : + { + . = ALIGN (8); + __data_start = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + /* rodata for panic handler(libarch__xtensa__core.a) and all + * dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libarch__xtensa__core.a:(.rodata .rodata.*) + *libkernel.a:fatal.*(.rodata .rodata.*) + *libkernel.a:init.*(.rodata .rodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.*) + *libzephyr.a:loader.*(.rodata .rodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + + #include + #include + #include + #include + #include + + /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ + #pragma push_macro("GROUP_ROM_LINK_IN") + #undef GROUP_ROM_LINK_IN + #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN + #include + #pragma pop_macro("GROUP_ROM_LINK_IN") + + .dram0.end : + { + . = ALIGN(4); + + #include + + . = ALIGN(4); + _end = ABSOLUTE(.); + _heap_sentry = .; + . = ALIGN(4); + __data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + + /* Shared RAM */ + SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); /* required by bluetooth library */ + __bss_start = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + ASSERT(((__bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") + + SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),) + { + . = ALIGN(8); + *(.noinit) + *(.noinit.*) + . = ALIGN(8) ; + } GROUP_LINK_IN(RAMABLE_REGION) + + .flash.text : ALIGN(IROM_SEG_ALIGN) + { + _stext = .; + _text_start = ABSOLUTE(.); + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + *(.literal .text .literal.* .text.*) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + . = ALIGN(4); + _flash_cache_start = ABSOLUTE(0); + } GROUP_LINK_IN(IRAM_REGION) + +#ifdef CONFIG_GEN_ISR_TABLES +#include +#endif + +#include + + .xtensa.info 0 : { *(.xtensa.info) } + .xt.insn 0 : + { + KEEP (*(.xt.insn)) + KEEP (*(.gnu.linkonce.x.*)) + } + .xt.prop 0 : + { + KEEP (*(.xt.prop)) + KEEP (*(.xt.prop.*)) + KEEP (*(.gnu.linkonce.prop.*)) + } + .xt.lit 0 : + { + KEEP (*(.xt.lit)) + KEEP (*(.xt.lit.*)) + KEEP (*(.gnu.linkonce.p.*)) + } + .xt.profile_range 0 : + { + KEEP (*(.xt.profile_range)) + KEEP (*(.gnu.linkonce.profile_range.*)) + } + .xt.profile_ranges 0 : + { + KEEP (*(.xt.profile_ranges)) + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) + } + .xt.profile_files 0 : + { + KEEP (*(.xt.profile_files)) + KEEP (*(.gnu.linkonce.xt.profile_files.*)) + } + +} + +ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") diff --git a/soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c b/soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c new file mode 100644 index 00000000000..5f20b64c27a --- /dev/null +++ b/soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct k_spinlock loglock; + +void smp_log(const char *msg) +{ + while (*msg) { + esp_rom_uart_tx_one_char(*msg++); + } + esp_rom_uart_tx_one_char('\r'); + esp_rom_uart_tx_one_char('\n'); +} + +void esp_appcpu_start(void *entry_point) +{ + soc_ll_unstall_core(1); + + if (!REG_GET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN)) { + REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN); + REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL); + REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING); + REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING); + } + + esp_rom_ets_set_appcpu_boot_addr((void *)entry_point); + + ets_delay_us(50000); + + smp_log("ESP32S3: CPU1 start sequence complete"); +} diff --git a/soc/xtensa/espressif_esp32/esp32s3/linker.ld b/soc/xtensa/espressif_esp32/esp32s3/linker.ld index 6cfbce9433f..9303f5a325d 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/linker.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/linker.ld @@ -14,7 +14,12 @@ #include "mcuboot.ld" #else + /* Application default linker script */ - #include "default.ld" + #if defined(CONFIG_SOC_ESP32S3_APPCPU) + #include "default_appcpu.ld" + #else + #include "default.ld" + #endif #endif /* CONFIG_MCUBOOT */ diff --git a/soc/xtensa/espressif_esp32/esp32s3/soc.c b/soc/xtensa/espressif_esp32/esp32s3/soc.c index 617ee05aabb..ad971b907b2 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/soc.c +++ b/soc/xtensa/espressif_esp32/esp32s3/soc.c @@ -5,7 +5,7 @@ */ /* Include esp-idf headers first to avoid redefining BIT() macro */ -#include "soc.h" +#include #include #include #include @@ -48,6 +48,45 @@ extern int _ext_ram_bss_end; extern void z_cstart(void); +#ifdef CONFIG_SOC_ESP32S3_PROCPU +extern const unsigned char esp32s3_appcpu_fw_array[]; + +void IRAM_ATTR esp_start_appcpu(void) +{ + esp_image_header_t *header = (esp_image_header_t *)&esp32s3_appcpu_fw_array[0]; + esp_image_segment_header_t *segment = + (esp_image_segment_header_t *)&esp32s3_appcpu_fw_array[sizeof(esp_image_header_t)]; + uint8_t *segment_payload; + uint32_t entry_addr = header->entry_addr; + uint32_t idx = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t); + + for (int i = 0; i < header->segment_count; i++) { + segment_payload = (uint8_t *)&esp32s3_appcpu_fw_array[idx]; + + if (segment->load_addr >= SOC_IRAM_LOW && segment->load_addr < SOC_IRAM_HIGH) { + /* IRAM segment only accepts 4 byte access, avoid memcpy usage here */ + volatile uint32_t *src = (volatile uint32_t *)segment_payload; + volatile uint32_t *dst = (volatile uint32_t *)segment->load_addr; + + for (int i = 0; i < segment->data_len / 4; i++) { + dst[i] = src[i]; + } + + } else if (segment->load_addr >= SOC_DRAM_LOW && + segment->load_addr < SOC_DRAM_HIGH) { + memcpy((void *)segment->load_addr, (const void *)segment_payload, + segment->data_len); + } + + idx += segment->data_len; + segment = (esp_image_segment_header_t *)&esp32s3_appcpu_fw_array[idx]; + idx += sizeof(esp_image_segment_header_t); + } + + esp_appcpu_start((void *)entry_addr); +} +#endif /* CONFIG_SOC_ESP32S3_PROCPU*/ + #ifndef CONFIG_MCUBOOT /* * This function is a container for SoC patches @@ -92,7 +131,7 @@ void IRAM_ATTR __esp_platform_start(void) * initialization code wants a valid _current before * arch_kernel_init() is invoked. */ - __asm__ volatile("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); + __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); #ifdef CONFIG_MCUBOOT /* MCUboot early initialisation. */ @@ -149,6 +188,11 @@ void IRAM_ATTR __esp_platform_start(void) esp_timer_early_init(); +#if CONFIG_SOC_ESP32S3_PROCPU + /* start the ESP32S3 APP CPU */ + esp_start_appcpu(); +#endif + #if CONFIG_SOC_FLASH_ESP32 spi_flash_guard_set(&g_flash_guard_default_ops); #endif diff --git a/soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c b/soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c new file mode 100644 index 00000000000..583f0b8119a --- /dev/null +++ b/soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void z_cstart(void); + +static void core_intr_matrix_clear(void) +{ + uint32_t core_id = cpu_hal_get_core_id(); + + for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { + intr_matrix_set(core_id, i, ETS_INVALID_INUM); + } +} + +void IRAM_ATTR __app_cpu_start(void) +{ + extern uint32_t _init_start; + extern uint32_t _bss_start; + extern uint32_t _bss_end; + + /* Move the exception vector table to IRAM. */ + __asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start)); + + /* Zero out BSS. Clobber _bss_start to avoid memset() elision. */ + z_bss_zero(); + + __asm__ __volatile__("" : : "g"(&__bss_start) : "memory"); + + /* Disable normal interrupts. */ + __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); + + /* Initialize the architecture CPU pointer. Some of the + * initialization code wants a valid _current before + * arch_kernel_init() is invoked. + */ + __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[1])); + + core_intr_matrix_clear(); + + esp_intr_initialize(); + + /* Start Zephyr */ + z_cstart(); + + CODE_UNREACHABLE; +} + +/* Boot-time static default printk handler, possibly to be overridden later. */ +int IRAM_ATTR arch_printk_char_out(int c) +{ + ARG_UNUSED(c); + return 0; +} + +void sys_arch_reboot(int type) +{ + esp_restart_noos(); +} + +void IRAM_ATTR esp_restart_noos(void) +{ + /* disable interrupts */ + z_xt_ints_off(0xFFFFFFFF); + + /* enable RTC watchdog for 1 second */ + wdt_hal_context_t wdt_ctx; + uint32_t timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + + wdt_hal_init(&wdt_ctx, WDT_RWDT, 0, false); + wdt_hal_write_protect_disable(&wdt_ctx); + wdt_hal_config_stage(&wdt_ctx, WDT_STAGE0, timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_config_stage(&wdt_ctx, WDT_STAGE1, timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + + /* enable flash boot mode so that flash booting after restart is protected by the RTC WDT */ + wdt_hal_set_flashboot_en(&wdt_ctx, true); + wdt_hal_write_protect_enable(&wdt_ctx); + + /* disable TG0/TG1 watchdogs */ + wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + + wdt_hal_write_protect_disable(&wdt0_context); + wdt_hal_disable(&wdt0_context); + wdt_hal_write_protect_enable(&wdt0_context); + + wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1}; + + wdt_hal_write_protect_disable(&wdt1_context); + wdt_hal_disable(&wdt1_context); + wdt_hal_write_protect_enable(&wdt1_context); + + /* Flush any data left in UART FIFOs */ + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + esp_rom_uart_tx_wait_idle(2); + + /* Disable cache */ + Cache_Disable_ICache(); + Cache_Disable_DCache(); + + /* 2nd stage bootloader reconfigures SPI flash signals. */ + /* Reset them to the defaults expected by ROM */ + WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30); + WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30); + WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30); + WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30); + WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); + WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); + + /* Reset wifi/bluetooth/ethernet/sdio (bb/mac) */ + SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, + SYSTEM_BB_RST | SYSTEM_FE_RST | SYSTEM_MAC_RST | SYSTEM_BT_RST | + SYSTEM_BTMAC_RST | SYSTEM_SDIO_RST | SYSTEM_SDIO_HOST_RST | + SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | SYSTEM_RW_BTMAC_RST | + SYSTEM_RW_BTLP_RST | SYSTEM_BLE_REG_RST | SYSTEM_PWR_REG_RST); + REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + + /* Reset timer/spi/uart */ + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | + SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); + + /* Reset DMA */ + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); + + SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); + CLEAR_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); + + rtc_clk_cpu_freq_set_xtal(); + + /* Running on APP CPU: need to reset PRO CPU and unstall it, */ + /* then reset APP CPU */ + soc_ll_reset_core(0); + soc_ll_stall_core(0); + soc_ll_reset_core(1); + + while (true) { + ; + } +} diff --git a/tests/drivers/pwm/pwm_api/src/test_pwm.c b/tests/drivers/pwm/pwm_api/src/test_pwm.c index 28b7ea541f2..867025d99b1 100644 --- a/tests/drivers/pwm/pwm_api/src/test_pwm.c +++ b/tests/drivers/pwm/pwm_api/src/test_pwm.c @@ -56,7 +56,7 @@ #if defined(CONFIG_BOARD_COLIBRI_IMX7D_M4) || defined(CONFIG_SOC_MK64F12) || \ defined(CONFIG_SOC_MKW41Z4) || defined(CONFIG_SOC_SERIES_ESP32S2) || \ - defined(CONFIG_SOC_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3) + defined(CONFIG_SOC_SERIES_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3) #define DEFAULT_PERIOD_CYCLE 1024 #define DEFAULT_PULSE_CYCLE 512 #define DEFAULT_PERIOD_NSEC 2000000 diff --git a/west.yml b/west.yml index bed5974b0cb..d8fa2096031 100644 --- a/west.yml +++ b/west.yml @@ -158,7 +158,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 80d910ca89eab9bce03f59a4ade33f1fc30ce0ad + revision: 9e4115fcbd6b737ec36488cd88c643eb7efc8b1b path: modules/hal/espressif west-commands: west/west-commands.yml groups: From 5c85c45e7d98d026a417ccd385920492e4e6451f Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 30 Aug 2023 17:11:07 -0300 Subject: [PATCH 1118/4498] boards: esp32s3_devkitm: add appcpu board model Adds into esp32s3_devkitm the appcpu board to allow building applications running in ESP32S3 2nd core (appcpu). Signed-off-by: Sylvio Alves --- boards/xtensa/esp32s3_devkitm/Kconfig.board | 4 +++ .../xtensa/esp32s3_devkitm/Kconfig.defconfig | 23 ++++++++++--- boards/xtensa/esp32s3_devkitm/doc/index.rst | 7 ++++ .../esp32s3_devkitm_appcpu.dts | 34 +++++++++++++++++++ .../esp32s3_devkitm_appcpu.yaml | 26 ++++++++++++++ .../esp32s3_devkitm_appcpu_defconfig | 9 +++++ 6 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts create mode 100644 boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.yaml create mode 100644 boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig diff --git a/boards/xtensa/esp32s3_devkitm/Kconfig.board b/boards/xtensa/esp32s3_devkitm/Kconfig.board index 96de0fb06f7..3f899740c0d 100644 --- a/boards/xtensa/esp32s3_devkitm/Kconfig.board +++ b/boards/xtensa/esp32s3_devkitm/Kconfig.board @@ -6,6 +6,10 @@ config BOARD_ESP32S3_DEVKITM bool "ESP32S3 DevKitM Board" depends on SOC_SERIES_ESP32S3 +config BOARD_ESP32S3_DEVKITM_APPCPU + bool "ESP32S3 Board configuration for APPCPU (core 1)." + depends on SOC_SERIES_ESP32S3 && SOC_ESP32S3_APPCPU + choice SOC_PART_NUMBER default SOC_ESP32S3_MINI_N8 endchoice diff --git a/boards/xtensa/esp32s3_devkitm/Kconfig.defconfig b/boards/xtensa/esp32s3_devkitm/Kconfig.defconfig index e0dc279412f..cb102b4ee64 100644 --- a/boards/xtensa/esp32s3_devkitm/Kconfig.defconfig +++ b/boards/xtensa/esp32s3_devkitm/Kconfig.defconfig @@ -3,12 +3,10 @@ # Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 +if BOARD_ESP32S3_DEVKITM + config BOARD default "esp32s3_devkitm" - depends on BOARD_ESP32S3_DEVKITM - -config ENTROPY_GENERATOR - default y config HEAP_MEM_POOL_SIZE default 98304 if WIFI @@ -18,3 +16,20 @@ config HEAP_MEM_POOL_SIZE choice BT_HCI_BUS_TYPE default BT_ESP32 if BT endchoice + +endif + +if BOARD_ESP32S3_DEVKITM_APPCPU + +config BOARD + default "esp32s3_devkitm_appcpu" + +config HEAP_MEM_POOL_SIZE + default 4096 + +config KERNEL_BIN_NAME + default "esp32_net_firmware" +endif + +config ENTROPY_GENERATOR + default y diff --git a/boards/xtensa/esp32s3_devkitm/doc/index.rst b/boards/xtensa/esp32s3_devkitm/doc/index.rst index 5684ad69118..caa9f6a240f 100644 --- a/boards/xtensa/esp32s3_devkitm/doc/index.rst +++ b/boards/xtensa/esp32s3_devkitm/doc/index.rst @@ -71,6 +71,13 @@ Security: - 4-Kbit OTP, up to 1792 bits for users - Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) +Asymmetric Multiprocessing (AMP) +******************************** + +ESP32S3-DevKitM allows 2 different applications to be executed in ESP32-S3 SoC. Due to its dual-core +architecture, each core can be enabled to execute customized tasks in stand-alone mode +and/or exchanging data over OpenAMP framework. See :ref:`ipc_samples` folder as code reference. + For more information, check the datasheet at `ESP32-S3 Datasheet`_. Supported Features diff --git a/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts new file mode 100644 index 00000000000..ae68f094e14 --- /dev/null +++ b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/dts-v1/; + +#include +/ { + model = "esp32s3_appcpu"; + compatible = "espressif,esp32s3_appcpu"; + + chosen { + zephyr,sram = &sram0; + zephyr,ipc_shm = &shm0; + zephyr,ipc = &ipm0; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&cpu1 { + clock-frequency = ; +}; + +&trng0 { + status = "okay"; +}; + +&ipm0 { + status = "okay"; +}; diff --git a/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.yaml b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.yaml new file mode 100644 index 00000000000..b6145d0f965 --- /dev/null +++ b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu.yaml @@ -0,0 +1,26 @@ +identifier: esp32s3_devkitm_appcpu +name: ESP32S3 DEVKITM APPCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - uart +testing: + ignore_tags: + - net + - bluetooth + - flash + - cpp + - posix + - watchdog + - logging + - kernel + - pm + - gpio + - crypto + - eeprom + - heap + - cmsis_rtos + - jwt + - zdsp diff --git a/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig new file mode 100644 index 00000000000..e554a951263 --- /dev/null +++ b/boards/xtensa/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_ESP32S3=y +CONFIG_SOC_ESP32S3_APPCPU=y +CONFIG_BOARD_ESP32S3_DEVKITM_APPCPU=y + +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_CLOCK_CONTROL=y +CONFIG_MINIMAL_LIBC=y From 41e615c7ac47056dca793a6ece89314a0eb566dd Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 30 Aug 2023 17:11:54 -0300 Subject: [PATCH 1119/4498] samples: ipc: add esp32s3_devkitm as supported board Add IPC same code for esp32s3_devkitm enabling second core. Signed-off-by: Sylvio Alves --- .../subsys/ipc/rpmsg_service/CMakeLists.txt | 6 ++++-- .../rpmsg_service/boards/esp32s3_devkitm.conf | 1 + .../boards/esp32s3_devkitm.overlay | 19 +++++++++++++++++++ .../ipc/rpmsg_service/remote/CMakeLists.txt | 3 ++- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.conf create mode 100644 samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.overlay diff --git a/samples/subsys/ipc/rpmsg_service/CMakeLists.txt b/samples/subsys/ipc/rpmsg_service/CMakeLists.txt index 18108f25fa0..83667bb1690 100644 --- a/samples/subsys/ipc/rpmsg_service/CMakeLists.txt +++ b/samples/subsys/ipc/rpmsg_service/CMakeLists.txt @@ -20,6 +20,8 @@ elseif("${BOARD}" STREQUAL "v2m_musca_b1") set(BOARD_REMOTE "v2m_musca_b1_ns") elseif("${BOARD}" STREQUAL "esp32") set(BOARD_REMOTE "esp32_net") +elseif("${BOARD}" STREQUAL "esp32s3_devkitm") + set(BOARD_REMOTE "esp32s3_devkitm_appcpu") else() message(FATAL_ERROR "${BOARD} was not supported for this sample") endif() @@ -33,7 +35,7 @@ enable_language(C ASM) target_sources(app PRIVATE src/main.c) -if("${BOARD}" STREQUAL "esp32") +if("${BOARD}" STREQUAL "esp32" OR "${BOARD}" STREQUAL "esp32s3_devkitm") set_source_files_properties(${REMOTE_ZEPHYR_DIR}/esp32_net_firmware.c PROPERTIES GENERATED TRUE) target_sources(app PRIVATE src/main.c ${REMOTE_ZEPHYR_DIR}/esp32_net_firmware.c) endif() @@ -52,7 +54,7 @@ ExternalProject_Add( if(("${BOARD}" STREQUAL "lpcxpresso54114_m4")) add_dependencies(core_m0_inc_target rpmsg_service_remote) -elseif("${BOARD}" STREQUAL "esp32") +elseif("${BOARD}" STREQUAL "esp32" OR "${BOARD}" STREQUAL "esp32s3_devkitm") add_dependencies(app rpmsg_service_remote) endif() diff --git a/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.conf b/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.conf new file mode 100644 index 00000000000..a8ee714a955 --- /dev/null +++ b/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.conf @@ -0,0 +1 @@ +CONFIG_SOC_ESP32S3_PROCPU=y diff --git a/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.overlay b/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.overlay new file mode 100644 index 00000000000..ad437c16e49 --- /dev/null +++ b/samples/subsys/ipc/rpmsg_service/boards/esp32s3_devkitm.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Felipe Neves + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + zephyr,ipc_shm = &shm0; + zephyr,ipc = &ipm0; + }; +}; + +&ipm0 { + status = "okay"; +}; diff --git a/samples/subsys/ipc/rpmsg_service/remote/CMakeLists.txt b/samples/subsys/ipc/rpmsg_service/remote/CMakeLists.txt index fa4fe6ebad5..76fc92e6307 100644 --- a/samples/subsys/ipc/rpmsg_service/remote/CMakeLists.txt +++ b/samples/subsys/ipc/rpmsg_service/remote/CMakeLists.txt @@ -10,7 +10,8 @@ if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet" OR "${BOARD}" STREQUAL "lpcxpresso54114_m0" OR "${BOARD}" STREQUAL "mps2_an521_remote" OR "${BOARD}" STREQUAL "v2m_musca_b1_ns" - OR "${BOARD}" STREQUAL "esp32_net") + OR "${BOARD}" STREQUAL "esp32_net" + OR "${BOARD}" STREQUAL "esp32s3_devkitm_appcpu") message(STATUS "${BOARD} compile as slave in this sample") else() message(FATAL_ERROR "${BOARD} was not supported for this sample") From 18eff4ea0052598c98a270a97586363e893962e3 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 12 Sep 2023 10:17:11 -0300 Subject: [PATCH 1120/4498] samples: ipc: update esp32 board reference After esp32 board was split into several different models, rpmsg sample code was missing the change. Make esp32_devkitc_wrover the default option. Signed-off-by: Sylvio Alves --- samples/subsys/ipc/rpmsg_service/CMakeLists.txt | 6 +++--- .../{esp32_devkitc_wroom.conf => esp32_devkitc_wrover.conf} | 0 ...2_devkitc_wroom.overlay => esp32_devkitc_wrover.overlay} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename samples/subsys/ipc/rpmsg_service/boards/{esp32_devkitc_wroom.conf => esp32_devkitc_wrover.conf} (100%) rename samples/subsys/ipc/rpmsg_service/boards/{esp32_devkitc_wroom.overlay => esp32_devkitc_wrover.overlay} (100%) diff --git a/samples/subsys/ipc/rpmsg_service/CMakeLists.txt b/samples/subsys/ipc/rpmsg_service/CMakeLists.txt index 83667bb1690..7411ab59dae 100644 --- a/samples/subsys/ipc/rpmsg_service/CMakeLists.txt +++ b/samples/subsys/ipc/rpmsg_service/CMakeLists.txt @@ -18,7 +18,7 @@ elseif("${BOARD}" STREQUAL "mps2_an521") set(BOARD_REMOTE "mps2_an521_remote") elseif("${BOARD}" STREQUAL "v2m_musca_b1") set(BOARD_REMOTE "v2m_musca_b1_ns") -elseif("${BOARD}" STREQUAL "esp32") +elseif("${BOARD}" STREQUAL "esp32_devkitc_wrover") set(BOARD_REMOTE "esp32_net") elseif("${BOARD}" STREQUAL "esp32s3_devkitm") set(BOARD_REMOTE "esp32s3_devkitm_appcpu") @@ -35,7 +35,7 @@ enable_language(C ASM) target_sources(app PRIVATE src/main.c) -if("${BOARD}" STREQUAL "esp32" OR "${BOARD}" STREQUAL "esp32s3_devkitm") +if("${BOARD}" STREQUAL "esp32_devkitc_wrover" OR "${BOARD}" STREQUAL "esp32s3_devkitm") set_source_files_properties(${REMOTE_ZEPHYR_DIR}/esp32_net_firmware.c PROPERTIES GENERATED TRUE) target_sources(app PRIVATE src/main.c ${REMOTE_ZEPHYR_DIR}/esp32_net_firmware.c) endif() @@ -54,7 +54,7 @@ ExternalProject_Add( if(("${BOARD}" STREQUAL "lpcxpresso54114_m4")) add_dependencies(core_m0_inc_target rpmsg_service_remote) -elseif("${BOARD}" STREQUAL "esp32" OR "${BOARD}" STREQUAL "esp32s3_devkitm") +elseif("${BOARD}" STREQUAL "esp32_devkitc_wrover" OR "${BOARD}" STREQUAL "esp32s3_devkitm") add_dependencies(app rpmsg_service_remote) endif() diff --git a/samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wroom.conf b/samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wrover.conf similarity index 100% rename from samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wroom.conf rename to samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wrover.conf diff --git a/samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wroom.overlay b/samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wrover.overlay similarity index 100% rename from samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wroom.overlay rename to samples/subsys/ipc/rpmsg_service/boards/esp32_devkitc_wrover.overlay From e294b16a2f8a672faa2db9c244dfe24d66d8b5d3 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Tue, 19 Sep 2023 11:40:10 -0600 Subject: [PATCH 1121/4498] fuel_gauge: Add fuel_guage_get_props() The fuel_gauge_get_prop() function prototype declares a function that retrieves multiple fuel gauge properties at once. The naming suggests it ought to fetch a singular property at a time. Moreso, some clients may just want to fetch properties one at a time and may feel uncomfortable using a prototype for fetching multiple properties when wanting to fetch them one at a time. Modify fuel_gauge_get_prop() to fetch a single property and add fuel_gauge_get_props() to support fetching multiple properties. Modify existing tests/drivers/samples. This is part of #61818 work. Signed-off-by: Aaron Massey --- doc/hardware/peripherals/fuel_gauge.rst | 5 +- drivers/fuel_gauge/bq27z746/bq27z746.c | 18 +----- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 28 ++++++++-- drivers/fuel_gauge/max17048/max17048.c | 22 +++----- drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 18 +----- include/zephyr/drivers/fuel_gauge.h | 56 +++++++++++++++---- samples/fuel_gauge/max17048/src/main.c | 2 +- .../fuel_gauge/bq27z746/src/test_bq27z746.c | 6 +- .../fuel_gauge/max17048/src/test_max17048.c | 8 +-- .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 35 ++++++------ 10 files changed, 105 insertions(+), 93 deletions(-) diff --git a/doc/hardware/peripherals/fuel_gauge.rst b/doc/hardware/peripherals/fuel_gauge.rst index ee6ba3ddbad..6dc6b81f0b7 100644 --- a/doc/hardware/peripherals/fuel_gauge.rst +++ b/doc/hardware/peripherals/fuel_gauge.rst @@ -20,8 +20,9 @@ Fundamentally, a property is a quantity that a fuel gauge device can measure. Fuel gauges typically support multiple properties, such as temperature readings of the battery-pack or present-time current/voltage. -Properties are fetched using a client allocated array of :c:struct:`fuel_gauge_property`. This -array is then populated by values as according to its `property_type` field. +Properties are fetched one at a time using a client allocated :c:struct:`fuel_gauge_property` or +fetched all at once using a client allocated array of :c:struct:`fuel_gauge_property`. Each +:c:struct:`fuel_gauge_property` is populated by values according to its `property_type` field. Battery Cutoff ============== diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index 41086fb8699..b307f1646e5 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -260,22 +260,6 @@ static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_propert return rc; } -static int bq27z746_get_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len) -{ - int err_count = 0; - - for (int i = 0; i < len; i++) { - int ret = bq27z746_get_prop(dev, props + i); - - err_count += ret ? 1 : 0; - } - - err_count = (err_count == len) ? -1 : err_count; - - return err_count; -} - static int bq27z746_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { @@ -307,7 +291,7 @@ static int bq27z746_init(const struct device *dev) } static const struct fuel_gauge_driver_api bq27z746_driver_api = { - .get_property = &bq27z746_get_props, + .get_property = &bq27z746_get_prop, .set_property = &bq27z746_set_props, .get_buffer_property = &bq27z746_get_buffer_prop, }; diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 2db583bfdb5..327ca60ba9d 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -9,24 +9,40 @@ #include static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_property *props, - size_t props_len) + struct fuel_gauge_property *prop) +{ + struct fuel_gauge_property k_prop; + + Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); + + Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); + + int ret = z_impl_fuel_gauge_get_prop(dev, &k_prop); + + Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property))); + + return ret; +} + +#include + +static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, + struct fuel_gauge_property *props, size_t props_len) { struct fuel_gauge_property k_props[props_len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(z_user_from_copy(k_props, props, - props_len * sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); - int ret = z_impl_fuel_gauge_get_prop(dev, k_props, props_len); + int ret = z_impl_fuel_gauge_get_props(dev, k_props, props_len); Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); return ret; } -#include +#include static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *props, diff --git a/drivers/fuel_gauge/max17048/max17048.c b/drivers/fuel_gauge/max17048/max17048.c index 76f14e67d91..ef74f335f0e 100644 --- a/drivers/fuel_gauge/max17048/max17048.c +++ b/drivers/fuel_gauge/max17048/max17048.c @@ -175,7 +175,7 @@ static int max17048_init(const struct device *dev) /** * Get a single property from the fuel gauge */ -static int max17048_get_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_gauge_property *prop) { struct max17048_data *data = dev->data; int rc = 0; @@ -203,15 +203,14 @@ static int max17048_get_prop(const struct device *dev, struct fuel_gauge_propert } /** - * Get all possible properties from the fuel gague + * Get properties from the fuel gauge */ -static int max17048_get_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len) +static int max17048_get_prop(const struct device *dev, struct fuel_gauge_property *prop) { - int err_count = 0; struct max17048_data *data = dev->data; int rc = max17048_percent(dev, &data->charge); int16_t crate; + int ret; if (rc < 0) { LOG_ERR("Error while reading battery percentage"); @@ -242,7 +241,6 @@ static int max17048_get_props(const struct device *dev, struct fuel_gauge_proper */ data->charging = crate > 0; - /** * In the following code, we multiply by 1000 the charge to increase the * precision. If we just truncate the division without this multiplier, @@ -266,12 +264,6 @@ static int max17048_get_props(const struct device *dev, struct fuel_gauge_proper data->time_to_empty = hours_pending * 60 / 1000; data->time_to_full = 0; } - - for (int i = 0; i < len; i++) { - int ret = max17048_get_prop(dev, props + i); - - err_count += ret ? 1 : 0; - } } else { /** * This case is to avoid a division by 0 when the charge rate is the same @@ -283,13 +275,13 @@ static int max17048_get_props(const struct device *dev, struct fuel_gauge_proper data->time_to_empty = 0; } - err_count = (err_count == len) ? -1 : err_count; + ret = max17048_get_single_prop_impl(dev, prop); - return err_count; + return ret; } static const struct fuel_gauge_driver_api max17048_driver_api = { - .get_property = &max17048_get_props, + .get_property = &max17048_get_prop, }; #define MAX17048_DEFINE(inst) \ diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index 1cb855fd03d..7f0bdf7283a 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -274,22 +274,6 @@ static int sbs_gauge_get_buffer_prop(const struct device *dev, return rc; } -static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len) -{ - int err_count = 0; - - for (int i = 0; i < len; i++) { - int ret = sbs_gauge_get_prop(dev, props + i); - - err_count += ret ? 1 : 0; - } - - err_count = (err_count == len) ? -1 : err_count; - - return err_count; -} - static int sbs_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { @@ -326,7 +310,7 @@ static int sbs_gauge_init(const struct device *dev) } static const struct fuel_gauge_driver_api sbs_gauge_driver_api = { - .get_property = &sbs_gauge_get_props, + .get_property = &sbs_gauge_get_prop, .set_property = &sbs_gauge_set_props, .get_buffer_property = &sbs_gauge_get_buffer_prop, .battery_cutoff = &sbs_gauge_do_battery_cutoff, diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 9b878c0ae0c..4304dd93a49 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -222,7 +222,7 @@ struct sbs_gauge_device_chemistry { * See fuel_gauge_get_property() for argument description */ typedef int (*fuel_gauge_get_property_t)(const struct device *dev, - struct fuel_gauge_property *props, size_t props_len); + struct fuel_gauge_property *prop); /** * @typedef fuel_gauge_set_property_t @@ -254,6 +254,12 @@ typedef int (*fuel_gauge_battery_cutoff_t)(const struct device *dev); /* Caching is entirely on the onus of the client */ __subsystem struct fuel_gauge_driver_api { + /** + * Note: Historically this API allowed drivers to implement a custom multi-get/set property + * function, this was added so drivers could potentially optimize batch read with their + * specific chip. However, it was removed because of no existing concrete case upstream. + * If this need is demonstrated, we can add this back in as an API field. + */ fuel_gauge_get_property_t get_property; fuel_gauge_set_property_t set_property; fuel_gauge_get_buffer_property_t get_buffer_property; @@ -264,21 +270,17 @@ __subsystem struct fuel_gauge_driver_api { * @brief Fetch a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param props pointer to array of fuel_gauge_property struct where the property struct + * @param prop pointer to a fuel_gauge_property struct where the property struct * field is set by the caller to determine what property is read from the * fuel gauge device into the fuel_gauge_property struct's value field. The props array * maintains the same order of properties as it was given. - * @param props_len number of properties in props array * - * @return return=0 if successful, return < 0 if getting all properties failed, return > 0 if some - * properties failed where return=number of failing properties. + * @return 0 if successful, negative errno code if failure. */ -__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *props, - size_t props_len); +__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop); static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_property *props, - size_t props_len) + struct fuel_gauge_property *prop) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; @@ -286,7 +288,41 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, return -ENOSYS; } - return api->get_property(dev, props, props_len); + return api->get_property(dev, prop); +} + +/** + * @brief Fetch multiple battery fuel-gauge properies. The default implementation is the same as + * calling fuel_gauge_get_prop() multiple times. A driver may implement the `get_properties` field + * of the fuel gauge driver APIs struct to override this implementation. + * + * @param dev Pointer to the battery fuel-gauge device + * @param props pointer to array of fuel_gauge_property struct where the property struct + * field is set by the caller to determine what property is read from the + * fuel gauge device into the fuel_gauge_property struct's value field. The props array + * maintains the same order of properties as it was given. + * @param len number of properties in props array + * + * @return return=0 if successful, return < 0 if getting all properties failed, return > 0 if some + * properties failed where return=number of failing properties. + */ +__syscall int fuel_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, + size_t len); +static inline int z_impl_fuel_gauge_get_props(const struct device *dev, + struct fuel_gauge_property *props, size_t len) +{ + int err_count = 0; + const struct fuel_gauge_driver_api *api = dev->api; + + for (int i = 0; i < len; i++) { + int ret = api->get_property(dev, props + i); + + err_count += ret ? 1 : 0; + } + + err_count = (err_count == len) ? -1 : err_count; + + return err_count; } /** diff --git a/samples/fuel_gauge/max17048/src/main.c b/samples/fuel_gauge/max17048/src/main.c index 62121f6da82..fd28271a4b6 100644 --- a/samples/fuel_gauge/max17048/src/main.c +++ b/samples/fuel_gauge/max17048/src/main.c @@ -53,7 +53,7 @@ int main(void) } }; - ret = fuel_gauge_get_prop(dev, props, ARRAY_SIZE(props)); + ret = fuel_gauge_get_props(dev, props, ARRAY_SIZE(props)); if (ret < 0) { printk("Error: cannot get properties\n"); } else { diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c index ec6cbcb1488..73c7b2958e3 100644 --- a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -40,7 +40,7 @@ ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) }, }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -66,7 +66,7 @@ ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -191,7 +191,7 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) }, }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); /* All props shall have a good status */ for (int i = 0; i < ARRAY_SIZE(props); i++) { diff --git a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c index fbb495d5ebf..2cf14afe274 100644 --- a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c +++ b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c @@ -41,7 +41,7 @@ ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) }, }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -67,7 +67,7 @@ ZTEST_USER_F(max17048, test_get_some_props_failed_returns_failed_prop_count) }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -101,7 +101,7 @@ ZTEST_USER_F(max17048, test_get_props__returns_ok) } }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); for (int i = 0; i < ARRAY_SIZE(props); i++) { zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, @@ -128,7 +128,7 @@ ZTEST_USER_F(max17048, test_current_rate_zero) * it will cause a division by zero */ emul_max17048_set_crate_status(0); - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); for (int i = 0; i < ARRAY_SIZE(props); i++) { zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 6eee40c19ca..9d734531781 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -41,7 +41,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_all_props_failed_returns_negative) }, }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -67,7 +67,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_c }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", props[0].property_type); @@ -184,7 +184,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) set_props[i].property_type); } - zassert_ok(fuel_gauge_get_prop(fixture->dev, get_props, ARRAY_SIZE(get_props))); + zassert_ok(fuel_gauge_get_props(fixture->dev, get_props, ARRAY_SIZE(get_props))); for (int i = 0; i < ARRAY_SIZE(get_props); i++) { zassert_ok(get_props[i].status, "Property %d getting %d has a bad status.", i, get_props[i].property_type); @@ -276,7 +276,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) }, }; - int ret = fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); for (int i = 0; i < ARRAY_SIZE(props); i++) { zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, @@ -350,26 +350,25 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) uint32_t expected_uV = 5000 * 1000; uint32_t expected_uA = 3000 * 1000; - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_CURRENT, - }, + struct fuel_gauge_property voltage = { + .property_type = FUEL_GAUGE_VOLTAGE, + }; + struct fuel_gauge_property current = { + .property_type = FUEL_GAUGE_CURRENT, }; zassume_ok(emul_fuel_gauge_set_battery_charging(fixture->sbs_fuel_gauge, expected_uV, expected_uA)); - zassert_ok(fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props))); + zassert_ok(fuel_gauge_get_prop(fixture->dev, &voltage)); + zassert_ok(fuel_gauge_get_prop(fixture->dev, ¤t)); - zassert_ok(props[0].status); - zassert_equal(props[0].value.voltage, expected_uV, "Got %d instead of %d", - props[0].value.voltage, expected_uV); + zassert_ok(voltage.status); + zassert_equal(voltage.value.voltage, expected_uV, "Got %d instead of %d", + voltage.value.voltage, expected_uV); - zassert_ok(props[1].status); - zassert_equal(props[1].value.current, expected_uA, "Got %d instead of %d", - props[1].value.current, expected_uA); + zassert_ok(current.status); + zassert_equal(current.value.current, expected_uA, "Got %d instead of %d", + current.value.current, expected_uA); } ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL); From bddd88955d30c8dcd1e9642abfa4192dfde971f4 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Wed, 20 Sep 2023 16:16:41 -0600 Subject: [PATCH 1122/4498] fuel_gauge: Add fuel_guage_set_props() The fuel_gauge_set_prop() function prototype declares a function that sets multiple fuel gauge properties at once. The naming suggests it ought to fetch a singular property at a time. Moreso, some clients may just want to set properties one at a time and may feel uncomfortable using a prototype for fetching multiple properties when wanting to fetch them one at a time. Modify fuel_gauge_set_prop() to fetch a single property and add fuel_gauge_set_props() to support fetching multiple properties. Modify existing tests/drivers/samples. This is part of #61818 work. Signed-off-by: Aaron Massey --- drivers/fuel_gauge/bq27z746/bq27z746.c | 18 +------ .../fuel_gauge/fuel_gauge_syscall_handlers.c | 28 ++++++++--- drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 18 +------ include/zephyr/drivers/fuel_gauge.h | 47 +++++++++++++++---- .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 27 +++++++++-- 5 files changed, 84 insertions(+), 54 deletions(-) diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index b307f1646e5..988034465a8 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -260,22 +260,6 @@ static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_propert return rc; } -static int bq27z746_set_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len) -{ - int err_count = 0; - - for (int i = 0; i < len; i++) { - int ret = bq27z746_set_prop(dev, props + i); - - err_count += ret ? 1 : 0; - } - - err_count = (err_count == len) ? -1 : err_count; - - return err_count; -} - static int bq27z746_init(const struct device *dev) { const struct bq27z746_config *cfg; @@ -292,7 +276,7 @@ static int bq27z746_init(const struct device *dev) static const struct fuel_gauge_driver_api bq27z746_driver_api = { .get_property = &bq27z746_get_prop, - .set_property = &bq27z746_set_props, + .set_property = &bq27z746_set_prop, .get_buffer_property = &bq27z746_get_buffer_prop, }; diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 327ca60ba9d..c3dc6cfeecc 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -45,24 +45,40 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, #include static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_property *props, - size_t props_len) + struct fuel_gauge_property *prop) +{ + struct fuel_gauge_property k_prop; + + Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); + + Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); + + int ret = z_impl_fuel_gauge_set_prop(dev, &k_prop); + + Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property))); + + return ret; +} + +#include + +static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, + struct fuel_gauge_property *props, size_t props_len) { struct fuel_gauge_property k_props[props_len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); - Z_OOPS(z_user_from_copy(k_props, props, - props_len * sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); - int ret = z_impl_fuel_gauge_set_prop(dev, k_props, props_len); + int ret = z_impl_fuel_gauge_set_props(dev, k_props, props_len); Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); return ret; } -#include +#include static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, struct fuel_gauge_buffer_property *prop, diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index 7f0bdf7283a..88710ffec26 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -274,22 +274,6 @@ static int sbs_gauge_get_buffer_prop(const struct device *dev, return rc; } -static int sbs_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len) -{ - int err_count = 0; - - for (int i = 0; i < len; i++) { - int ret = sbs_gauge_set_prop(dev, props + i); - - err_count += ret ? 1 : 0; - } - - err_count = (err_count == len) ? -1 : err_count; - - return err_count; -} - /** * @brief initialize the fuel gauge * @@ -311,7 +295,7 @@ static int sbs_gauge_init(const struct device *dev) static const struct fuel_gauge_driver_api sbs_gauge_driver_api = { .get_property = &sbs_gauge_get_prop, - .set_property = &sbs_gauge_set_props, + .set_property = &sbs_gauge_set_prop, .get_buffer_property = &sbs_gauge_get_buffer_prop, .battery_cutoff = &sbs_gauge_do_battery_cutoff, }; diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 4304dd93a49..3f4e11871f3 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -231,7 +231,7 @@ typedef int (*fuel_gauge_get_property_t)(const struct device *dev, * See fuel_gauge_set_property() for argument description */ typedef int (*fuel_gauge_set_property_t)(const struct device *dev, - struct fuel_gauge_property *props, size_t props_len); + struct fuel_gauge_property *prop); /** * @typedef fuel_gauge_get_buffer_property_t @@ -325,6 +325,30 @@ static inline int z_impl_fuel_gauge_get_props(const struct device *dev, return err_count; } +/** + * @brief Set a battery fuel-gauge property + * + * @param dev Pointer to the battery fuel-gauge device + * @param prop pointer to fuel_gauge_property struct where the property struct + * field is set by the caller to determine what property is written to the fuel gauge device from + * the fuel_gauge_property struct's value field. + * + * @return 0 if successful, negative errno code if failure. + */ +__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop); + +static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, + struct fuel_gauge_property *prop) +{ + const struct fuel_gauge_driver_api *api = dev->api; + + if (api->set_property == NULL) { + return -ENOSYS; + } + + return api->set_property(dev, prop); +} + /** * @brief Set a battery fuel-gauge property * @@ -337,20 +361,23 @@ static inline int z_impl_fuel_gauge_get_props(const struct device *dev, * @return return=0 if successful, return < 0 if setting all properties failed, return > 0 if some * properties failed where return=number of failing properties. */ -__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *props, - size_t props_len); +__syscall int fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, + size_t props_len); -static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_property *props, - size_t props_len) +static inline int z_impl_fuel_gauge_set_props(const struct device *dev, + struct fuel_gauge_property *props, size_t props_len) { - const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; + int err_count = 0; - if (api->set_property == NULL) { - return -ENOSYS; + for (int i = 0; i < props_len; i++) { + int ret = fuel_gauge_set_prop(dev, props + i); + + err_count += ret ? 1 : 0; } - return api->set_property(dev, props, props_len); + err_count = (err_count == props_len) ? -1 : err_count; + + return err_count; } /** diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 9d734531781..5621f9e80bf 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -90,7 +90,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative) }, }; - int ret = fuel_gauge_set_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.", props[0].property_type); @@ -118,7 +118,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_c }; - int ret = fuel_gauge_set_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.", props[0].property_type); @@ -178,7 +178,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) }, }; - zassert_ok(fuel_gauge_set_prop(fixture->dev, set_props, ARRAY_SIZE(set_props))); + zassert_ok(fuel_gauge_set_props(fixture->dev, set_props, ARRAY_SIZE(set_props))); for (int i = 0; i < ARRAY_SIZE(set_props); i++) { zassert_ok(set_props[i].status, "Property %d writing %d has a bad status.", i, set_props[i].property_type); @@ -308,7 +308,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) }, }; - int ret = fuel_gauge_set_prop(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); for (int i = 0; i < ARRAY_SIZE(props); i++) { zassert_ok(props[i].status, "Property %d writing %d has a bad status.", i, @@ -371,4 +371,23 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) current.value.current, expected_uA); } +ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop) +{ + /* Validate what props are supported by the driver */ + + uint16_t test_value = 0x1001; + + struct fuel_gauge_property mfr_acc_set = { + .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, + .value.sbs_mfr_access_word = test_value, + }; + struct fuel_gauge_property mfr_acc_get = { + .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, + }; + + zassert_ok(fuel_gauge_set_prop(fixture->dev, &mfr_acc_set)); + zassert_ok(fuel_gauge_get_prop(fixture->dev, &mfr_acc_get)); + zassert_equal(mfr_acc_get.value.sbs_mfr_access_word, test_value); +} + ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL); From 329ecd1e1228f0656c4c776d48f3629393a58345 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Thu, 21 Sep 2023 11:38:39 -0600 Subject: [PATCH 1123/4498] fuel_gauge: Remove status from fuel gauge properties Based on review of the similar charger driver API, it's been demonstrated from the community that embedding a per value status code when fetching multiple properties isn't particularly wanted or needed. It was largely considered not worth the additional maintenance to have the extra per property error information. Remove the status field from the fuel_gauge property value structs. Signed-off-by: Aaron Massey --- drivers/fuel_gauge/bq27z746/bq27z746.c | 5 - drivers/fuel_gauge/max17048/max17048.c | 2 - drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 5 - include/zephyr/drivers/fuel_gauge.h | 33 +++---- samples/fuel_gauge/max17048/src/main.c | 50 ++-------- .../fuel_gauge/bq27z746/src/test_bq27z746.c | 29 +----- .../fuel_gauge/max17048/src/test_max17048.c | 31 +------ .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 91 +++---------------- 8 files changed, 37 insertions(+), 209 deletions(-) diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index 988034465a8..a0f66d8b2cf 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -192,8 +192,6 @@ static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_propert rc = -ENOTSUP; } - prop->status = rc; - return rc; } @@ -232,7 +230,6 @@ static int bq27z746_get_buffer_prop(const struct device *dev, rc = -ENOTSUP; } - prop->status = rc; return rc; } @@ -255,8 +252,6 @@ static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_propert rc = -ENOTSUP; } - prop->status = rc; - return rc; } diff --git a/drivers/fuel_gauge/max17048/max17048.c b/drivers/fuel_gauge/max17048/max17048.c index ef74f335f0e..2725a8da871 100644 --- a/drivers/fuel_gauge/max17048/max17048.c +++ b/drivers/fuel_gauge/max17048/max17048.c @@ -197,8 +197,6 @@ static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_g rc = -ENOTSUP; } - prop->status = rc; - return rc; } diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index 88710ffec26..f246cc87e5b 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -172,8 +172,6 @@ static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_proper rc = -ENOTSUP; } - prop->status = rc; - return rc; } @@ -230,8 +228,6 @@ static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_proper rc = -ENOTSUP; } - prop->status = rc; - return rc; } @@ -270,7 +266,6 @@ static int sbs_gauge_get_buffer_prop(const struct device *dev, rc = -ENOTSUP; } - prop->status = rc; return rc; } diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 3f4e11871f3..b110ac1d1c1 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -119,9 +119,6 @@ struct fuel_gauge_property { /** Battery fuel gauge property to get */ fuel_gauge_prop_t property_type; - /** Negative error status set by callee e.g. -ENOTSUP for an unsupported property */ - int status; - /** Property field for getting */ union { /* Fields have the format: */ @@ -188,9 +185,6 @@ struct fuel_gauge_property { struct fuel_gauge_buffer_property { /** Battery fuel gauge property to get */ fuel_gauge_prop_t property_type; - - /** Negative error status set by callee e.g. -ENOTSUP for an unsupported property */ - int status; }; /** @@ -303,26 +297,24 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, * maintains the same order of properties as it was given. * @param len number of properties in props array * - * @return return=0 if successful, return < 0 if getting all properties failed, return > 0 if some - * properties failed where return=number of failing properties. + * @return 0 if successful, negative errno code of first failing property */ __syscall int fuel_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, size_t len); static inline int z_impl_fuel_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, size_t len) { - int err_count = 0; const struct fuel_gauge_driver_api *api = dev->api; for (int i = 0; i < len; i++) { int ret = api->get_property(dev, props + i); - err_count += ret ? 1 : 0; + if (ret) { + return ret; + } } - err_count = (err_count == len) ? -1 : err_count; - - return err_count; + return 0; } /** @@ -333,7 +325,7 @@ static inline int z_impl_fuel_gauge_get_props(const struct device *dev, * field is set by the caller to determine what property is written to the fuel gauge device from * the fuel_gauge_property struct's value field. * - * @return 0 if successful, negative errno code if failure. + * @return 0 if successful, negative errno code of first failing property */ __syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop); @@ -358,8 +350,7 @@ static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, * the fuel_gauge_property struct's value field. * @param props_len number of properties in props array * - * @return return=0 if successful, return < 0 if setting all properties failed, return > 0 if some - * properties failed where return=number of failing properties. + * @return return=0 if successful. Otherwise, return array index of failing property. */ __syscall int fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t props_len); @@ -367,17 +358,15 @@ __syscall int fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_p static inline int z_impl_fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, size_t props_len) { - int err_count = 0; - for (int i = 0; i < props_len; i++) { int ret = fuel_gauge_set_prop(dev, props + i); - err_count += ret ? 1 : 0; + if (ret) { + return ret; + } } - err_count = (err_count == props_len) ? -1 : err_count; - - return err_count; + return 0; } /** diff --git a/samples/fuel_gauge/max17048/src/main.c b/samples/fuel_gauge/max17048/src/main.c index fd28271a4b6..d0e022d9212 100644 --- a/samples/fuel_gauge/max17048/src/main.c +++ b/samples/fuel_gauge/max17048/src/main.c @@ -50,54 +50,20 @@ int main(void) }, { .property_type = FUEL_GAUGE_VOLTAGE, - } - }; + }}; ret = fuel_gauge_get_props(dev, props, ARRAY_SIZE(props)); if (ret < 0) { printk("Error: cannot get properties\n"); } else { - if (ret != 0) { - printk("Warning: Some properties failed\n"); - } - - if (props[0].status == 0) { - printk("Time to empty %d\n", props[0].value.runtime_to_empty); - } else { - printk( - "Property FUEL_GAUGE_RUNTIME_TO_EMPTY failed with error %d\n", - props[0].status - ); - } - - if (props[1].status == 0) { - printk("Time to full %d\n", props[1].value.runtime_to_full); - } else { - printk( - "Property FUEL_GAUGE_RUNTIME_TO_FULL failed with error %d\n", - props[1].status - ); - } - - if (props[2].status == 0) { - printk("Charge %d%%\n", props[2].value.relative_state_of_charge); - } else { - printk( - "Property FUEL_GAUGE_STATE_OF_CHARGE failed with error %d\n", - props[2].status - ); - } - - if (props[3].status == 0) { - printk("Voltage %d\n", props[3].value.voltage); - } else { - printk( - "Property FUEL_GAUGE_VOLTAGE failed with error %d\n", - props[3].status - ); - } - } + printk("Time to empty %d\n", props[0].value.runtime_to_empty); + + printk("Time to full %d\n", props[1].value.runtime_to_full); + printk("Charge %d%%\n", props[2].value.relative_state_of_charge); + + printk("Voltage %d\n", props[3].value.voltage); + } k_sleep(K_MSEC(5000)); } diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c index 73c7b2958e3..c5b599ac06c 100644 --- a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -42,10 +42,7 @@ ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_true(ret < 0); + zassert_equal(ret, -ENOTSUP); } ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) @@ -68,16 +65,7 @@ ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_equal(props[1].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[1].property_type); - - zassert_ok(props[2].status, "Property %d getting %d has a bad status.", 2, - props[2].property_type); - - zassert_equal(ret, 2); + zassert_equal(ret, -ENOTSUP); } ZTEST_USER_F(bq27z746, test_get_buffer_prop) @@ -91,7 +79,6 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop) prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name)); zassert_ok(ret); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ /* reprogrammed and respond with different values */ @@ -107,7 +94,6 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop) prop.property_type = FUEL_GAUGE_DEVICE_NAME; ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name)); zassert_ok(ret); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ /* reprogrammed and respond with different values */ @@ -122,7 +108,6 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop) ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &device_chemistry, sizeof(device_chemistry)); zassert_ok(ret); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ /* reprogrammed and respond with different values */ @@ -191,13 +176,7 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) }, }; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - /* All props shall have a good status */ - for (int i = 0; i < ARRAY_SIZE(props); i++) { - zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, - props[i].property_type); - } + zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); /* Check properties for valid ranges */ #if CONFIG_EMUL @@ -239,8 +218,6 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) /* Not testing props[15]. This property is the status and only has only status bits */ zassert_between_inclusive(props[16].value.design_cap, 0, 32767); #endif - - zassert_ok(ret); } ZTEST_SUITE(bq27z746, NULL, bq27z746_setup, NULL, NULL, NULL); diff --git a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c index 2cf14afe274..c2452bc60f5 100644 --- a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c +++ b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c @@ -43,13 +43,10 @@ ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_true(ret < 0); + zassert_equal(-ENOTSUP, ret); } -ZTEST_USER_F(max17048, test_get_some_props_failed_returns_failed_prop_count) +ZTEST_USER_F(max17048, test_get_some_props_failed_returns_errno) { struct fuel_gauge_property props[] = { { @@ -69,16 +66,7 @@ ZTEST_USER_F(max17048, test_get_some_props_failed_returns_failed_prop_count) int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_equal(props[1].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[1].property_type); - - zassert_ok(props[2].status, "Property %d getting %d has a bad status.", 2, - props[2].property_type); - - zassert_equal(ret, 2); + zassert_equal(ret, -ENOTSUP); } @@ -101,14 +89,7 @@ ZTEST_USER_F(max17048, test_get_props__returns_ok) } }; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - for (int i = 0; i < ARRAY_SIZE(props); i++) { - zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, - props[i].property_type); - } - - zassert_ok(ret); + zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); } ZTEST_USER_F(max17048, test_current_rate_zero) @@ -130,10 +111,6 @@ ZTEST_USER_F(max17048, test_current_rate_zero) emul_max17048_set_crate_status(0); int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - for (int i = 0; i < ARRAY_SIZE(props); i++) { - zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, - props[i].property_type); - } zassert_equal(props[0].value.runtime_to_empty, 0, "Runtime to empty is %d but it should be 0.", props[0].value.runtime_to_full diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 5621f9e80bf..2fd71433c28 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -32,24 +32,7 @@ static void *sbs_gauge_new_api_setup(void) return &fixture; } -ZTEST_USER_F(sbs_gauge_new_api, test_get_all_props_failed_returns_negative) -{ - struct fuel_gauge_property props[] = { - { - /* Invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - }; - - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_true(ret < 0); -} - -ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_count) +ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_bad_status) { struct fuel_gauge_property props[] = { { @@ -69,19 +52,10 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_c int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[0].property_type); - - zassert_equal(props[1].status, -ENOTSUP, "Getting bad property %d has a good status.", - props[1].property_type); - - zassert_ok(props[2].status, "Property %d getting %d has a bad status.", 2, - props[2].property_type); - - zassert_equal(ret, 2); + zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); } -ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative) +ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_err) { struct fuel_gauge_property props[] = { { @@ -92,13 +66,10 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative) int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.", - props[0].property_type); - - zassert_true(ret < 0); + zassert_equal(ret, -ENOTSUP); } -ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_count) +ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err) { struct fuel_gauge_property props[] = { { @@ -120,16 +91,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_c int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); - zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.", - props[0].property_type); - - zassert_equal(props[1].status, -ENOTSUP, "Setting bad property %d has a good status.", - props[1].property_type); - - zassert_ok(props[2].status, "Property %d setting %d has a bad status.", 2, - props[2].property_type); - - zassert_equal(ret, 2); + zassert_equal(ret, -ENOTSUP); } ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) @@ -179,16 +141,8 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) }; zassert_ok(fuel_gauge_set_props(fixture->dev, set_props, ARRAY_SIZE(set_props))); - for (int i = 0; i < ARRAY_SIZE(set_props); i++) { - zassert_ok(set_props[i].status, "Property %d writing %d has a bad status.", i, - set_props[i].property_type); - } zassert_ok(fuel_gauge_get_props(fixture->dev, get_props, ARRAY_SIZE(get_props))); - for (int i = 0; i < ARRAY_SIZE(get_props); i++) { - zassert_ok(get_props[i].status, "Property %d getting %d has a bad status.", i, - get_props[i].property_type); - } zassert_equal(get_props[0].value.sbs_mfr_access_word, word); zassert_equal(get_props[1].value.sbs_remaining_capacity_alarm, word); @@ -276,14 +230,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) }, }; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - for (int i = 0; i < ARRAY_SIZE(props); i++) { - zassert_ok(props[i].status, "Property %d getting %d has a bad status.", i, - props[i].property_type); - } - - zassert_ok(ret); + zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); } ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) @@ -308,14 +255,7 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) }, }; - int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); - - for (int i = 0; i < ARRAY_SIZE(props); i++) { - zassert_ok(props[i].status, "Property %d writing %d has a bad status.", i, - props[i].property_type); - } - - zassert_ok(ret); + zassert_ok(fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props))); } @@ -326,22 +266,15 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) struct sbs_gauge_manufacturer_name mfg_name; struct sbs_gauge_device_name dev_name; struct sbs_gauge_device_chemistry chem; - int ret; prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name)); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); - zassert_ok(ret); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name))); prop.property_type = FUEL_GAUGE_DEVICE_NAME; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name)); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); - zassert_ok(ret); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name))); prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &chem, sizeof(chem)); - zassert_ok(prop.status, "Property %d has a bad status.", prop.property_type); - zassert_ok(ret); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &chem, sizeof(chem))); } ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) @@ -362,11 +295,9 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) zassert_ok(fuel_gauge_get_prop(fixture->dev, &voltage)); zassert_ok(fuel_gauge_get_prop(fixture->dev, ¤t)); - zassert_ok(voltage.status); zassert_equal(voltage.value.voltage, expected_uV, "Got %d instead of %d", voltage.value.voltage, expected_uV); - zassert_ok(current.status); zassert_equal(current.value.current, expected_uA, "Got %d instead of %d", current.value.current, expected_uA); } From 12cbfcf3976dce5220f44a514f7e9b704d7e6a4e Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Fri, 22 Sep 2023 12:17:27 -0600 Subject: [PATCH 1124/4498] fuel_gauge: Repl property struct w/ union Based on review of the similar charger driver API, it's been demonstrated from the community that embedding a per value property type when fetching properties. Separating off the property types from the property values themselves also allow an array of property types to declared as static const. Break up fuel_gauge_property struct into a fuel_gauge_prop_val union and a fuel_gauge_prop_t property type as inputs into fuel gauge API functions. Signed-off-by: Aaron Massey --- doc/hardware/peripherals/fuel_gauge.rst | 8 +- drivers/fuel_gauge/bq27z746/bq27z746.c | 95 +++--- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 67 ++-- drivers/fuel_gauge/max17048/max17048.c | 18 +- drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 134 ++++---- include/zephyr/drivers/fuel_gauge.h | 225 ++++++------- samples/fuel_gauge/max17048/src/main.c | 34 +- .../fuel_gauge/bq27z746/src/test_bq27z746.c | 193 ++++------- .../fuel_gauge/max17048/src/test_max17048.c | 91 ++---- .../fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 306 +++++++----------- 10 files changed, 491 insertions(+), 680 deletions(-) diff --git a/doc/hardware/peripherals/fuel_gauge.rst b/doc/hardware/peripherals/fuel_gauge.rst index 6dc6b81f0b7..e7131c440bf 100644 --- a/doc/hardware/peripherals/fuel_gauge.rst +++ b/doc/hardware/peripherals/fuel_gauge.rst @@ -20,9 +20,11 @@ Fundamentally, a property is a quantity that a fuel gauge device can measure. Fuel gauges typically support multiple properties, such as temperature readings of the battery-pack or present-time current/voltage. -Properties are fetched one at a time using a client allocated :c:struct:`fuel_gauge_property` or -fetched all at once using a client allocated array of :c:struct:`fuel_gauge_property`. Each -:c:struct:`fuel_gauge_property` is populated by values according to its `property_type` field. +Properties are fetched by the client one at a time using :c:func:`fuel_gauge_get_prop`, or fetched +in a batch using :c:func:`fuel_gauge_get_props`. + +Properties are set by the client one at a time using :c:func:`fuel_gauge_set_prop`, or set in a +batch using :c:func:`fuel_gauge_set_props`. Battery Cutoff ============== diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index a0f66d8b2cf..b028e590b1c 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -109,84 +109,85 @@ static int bq27z746_read_mac(const struct device *dev, uint16_t cmd, uint8_t *da return ret; } -static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int bq27z746_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { int rc = 0; - uint16_t val = 0; + uint16_t tmp_val = 0; /* * Possibly negative values must be cast from uint16 to int16 first to * then correctly end up in the wider datatypes of `prop`. */ - switch (prop->property_type) { + switch (prop) { case FUEL_GAUGE_AVG_CURRENT: - rc = bq27z746_read16(dev, BQ27Z746_AVERAGECURRENT, &val); - prop->value.avg_current = (int16_t)val * 1000; + rc = bq27z746_read16(dev, BQ27Z746_AVERAGECURRENT, &tmp_val); + val->avg_current = (int16_t)tmp_val * 1000; break; case FUEL_GAUGE_CYCLE_COUNT: - rc = bq27z746_read16(dev, BQ27Z746_CYCLECOUNT, &val); - prop->value.cycle_count = val * 100; + rc = bq27z746_read16(dev, BQ27Z746_CYCLECOUNT, &tmp_val); + val->cycle_count = tmp_val * 100; break; case FUEL_GAUGE_CURRENT: - rc = bq27z746_read16(dev, BQ27Z746_CURRENT, &val); - prop->value.current = (int16_t)val * 1000; + rc = bq27z746_read16(dev, BQ27Z746_CURRENT, &tmp_val); + val->current = (int16_t)tmp_val * 1000; break; case FUEL_GAUGE_FULL_CHARGE_CAPACITY: - rc = bq27z746_read16(dev, BQ27Z746_FULLCHARGECAPACITY, &val); - prop->value.full_charge_capacity = val * 1000; + rc = bq27z746_read16(dev, BQ27Z746_FULLCHARGECAPACITY, &tmp_val); + val->full_charge_capacity = tmp_val * 1000; break; case FUEL_GAUGE_REMAINING_CAPACITY: - rc = bq27z746_read16(dev, BQ27Z746_REMAININGCAPACITY, &val); - prop->value.remaining_capacity = val * 1000; + rc = bq27z746_read16(dev, BQ27Z746_REMAININGCAPACITY, &tmp_val); + val->remaining_capacity = tmp_val * 1000; break; case FUEL_GAUGE_RUNTIME_TO_EMPTY: - rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOEMPTY, &val); - prop->value.runtime_to_empty = val; + rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOEMPTY, &tmp_val); + val->runtime_to_empty = tmp_val; break; case FUEL_GAUGE_RUNTIME_TO_FULL: - rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOFULL, &val); - prop->value.runtime_to_full = val; + rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOFULL, &tmp_val); + val->runtime_to_full = tmp_val; break; case FUEL_GAUGE_SBS_MFR_ACCESS: - rc = bq27z746_read16(dev, BQ27Z746_MANUFACTURERACCESS, &val); - prop->value.sbs_mfr_access_word = val; + rc = bq27z746_read16(dev, BQ27Z746_MANUFACTURERACCESS, &tmp_val); + val->sbs_mfr_access_word = tmp_val; break; case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: - rc = bq27z746_read16(dev, BQ27Z746_RELATIVESTATEOFCHARGE, &val); - prop->value.relative_state_of_charge = val; + rc = bq27z746_read16(dev, BQ27Z746_RELATIVESTATEOFCHARGE, &tmp_val); + val->relative_state_of_charge = tmp_val; break; case FUEL_GAUGE_TEMPERATURE: - rc = bq27z746_read16(dev, BQ27Z746_TEMPERATURE, &val); - prop->value.temperature = val; + rc = bq27z746_read16(dev, BQ27Z746_TEMPERATURE, &tmp_val); + val->temperature = tmp_val; break; case FUEL_GAUGE_VOLTAGE: - rc = bq27z746_read16(dev, BQ27Z746_VOLTAGE, &val); - prop->value.voltage = val * 1000; + rc = bq27z746_read16(dev, BQ27Z746_VOLTAGE, &tmp_val); + val->voltage = tmp_val * 1000; break; case FUEL_GAUGE_SBS_ATRATE: - rc = bq27z746_read16(dev, BQ27Z746_ATRATE, &val); - prop->value.sbs_at_rate = (int16_t)val; + rc = bq27z746_read16(dev, BQ27Z746_ATRATE, &tmp_val); + val->sbs_at_rate = (int16_t)tmp_val; break; case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY: - rc = bq27z746_read16(dev, BQ27Z746_ATRATETIMETOEMPTY, &val); - prop->value.sbs_at_rate_time_to_empty = val; + rc = bq27z746_read16(dev, BQ27Z746_ATRATETIMETOEMPTY, &tmp_val); + val->sbs_at_rate_time_to_empty = tmp_val; break; case FUEL_GAUGE_CHARGE_VOLTAGE: - rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &val); - prop->value.chg_voltage = val; + rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &tmp_val); + val->chg_voltage = tmp_val; break; case FUEL_GAUGE_CHARGE_CURRENT: - rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &val); - prop->value.chg_current = val; + rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &tmp_val); + val->chg_current = tmp_val; break; case FUEL_GAUGE_STATUS: - rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &val); - prop->value.fg_status = val; + rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &tmp_val); + val->fg_status = tmp_val; break; case FUEL_GAUGE_DESIGN_CAPACITY: - rc = bq27z746_read16(dev, BQ27Z746_DESIGNCAPACITY, &val); - prop->value.design_cap = val; + rc = bq27z746_read16(dev, BQ27Z746_DESIGNCAPACITY, &tmp_val); + val->design_cap = tmp_val; break; default: rc = -ENOTSUP; @@ -196,12 +197,12 @@ static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_propert } static int bq27z746_get_buffer_prop(const struct device *dev, - struct fuel_gauge_buffer_property *prop, void *dst, + fuel_gauge_prop_t property_type, void *dst, size_t dst_len) { int rc = 0; - switch (prop->property_type) { + switch (property_type) { case FUEL_GAUGE_MANUFACTURER_NAME: if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) { rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_MANUFACTURER_NAME, @@ -233,20 +234,20 @@ static int bq27z746_get_buffer_prop(const struct device *dev, return rc; } -static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int bq27z746_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val) { int rc = 0; - uint16_t val = 0; + uint16_t tmp_val = 0; - switch (prop->property_type) { + switch (prop) { case FUEL_GAUGE_SBS_MFR_ACCESS: - rc = bq27z746_write16(dev, BQ27Z746_MANUFACTURERACCESS, - prop->value.sbs_mfr_access_word); - prop->value.sbs_mfr_access_word = val; + rc = bq27z746_write16(dev, BQ27Z746_MANUFACTURERACCESS, val.sbs_mfr_access_word); + val.sbs_mfr_access_word = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE: - rc = bq27z746_write16(dev, BQ27Z746_ATRATE, prop->value.sbs_at_rate); - prop->value.sbs_at_rate = val; + rc = bq27z746_write16(dev, BQ27Z746_ATRATE, val.sbs_at_rate); + val.sbs_at_rate = tmp_val; break; default: rc = -ENOTSUP; diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index c3dc6cfeecc..6bcd5bd2205 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -8,72 +8,71 @@ #include #include -static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_property *prop) +static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { - struct fuel_gauge_property k_prop; + union fuel_gauge_prop_val k_val; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); - int ret = z_impl_fuel_gauge_get_prop(dev, &k_prop); + int ret = z_impl_fuel_gauge_get_prop(dev, prop, &k_val); - Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val))); return ret; } #include -static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, - struct fuel_gauge_property *props, size_t props_len) +static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len) { - struct fuel_gauge_property k_props[props_len]; + union fuel_gauge_prop_val k_vals[len]; + fuel_gauge_prop_t k_props[len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); - int ret = z_impl_fuel_gauge_get_props(dev, k_props, props_len); + int ret = z_impl_fuel_gauge_get_props(dev, k_props, k_vals, len); - Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } #include -static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_property *prop) +static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val) { - struct fuel_gauge_property k_prop; - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); - Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); - - int ret = z_impl_fuel_gauge_set_prop(dev, &k_prop); - - Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property))); + int ret = z_impl_fuel_gauge_set_prop(dev, prop, val); return ret; } #include -static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, - struct fuel_gauge_property *props, size_t props_len) +static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len) { - struct fuel_gauge_property k_props[props_len]; + union fuel_gauge_prop_val k_vals[len]; + fuel_gauge_prop_t k_props[len]; Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); - Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); + Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); - int ret = z_impl_fuel_gauge_set_props(dev, k_props, props_len); + int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len); - Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); + /* We only copy back vals because props will never be modified */ + Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } @@ -81,22 +80,14 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, #include static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_buffer_property *prop, - void *dst, size_t dst_len) + fuel_gauge_prop_t prop, void *dst, + size_t dst_len) { - struct fuel_gauge_buffer_property k_prop; - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); - Z_OOPS(z_user_from_copy(&k_prop, prop, - sizeof(struct fuel_gauge_buffer_property))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, dst_len)); - int ret = z_impl_fuel_gauge_get_buffer_prop(dev, &k_prop, dst, dst_len); - - Z_OOPS(z_user_to_copy(prop, &k_prop, - sizeof(struct fuel_gauge_buffer_property))); + int ret = z_impl_fuel_gauge_get_buffer_prop(dev, prop, dst, dst_len); return ret; } diff --git a/drivers/fuel_gauge/max17048/max17048.c b/drivers/fuel_gauge/max17048/max17048.c index 2725a8da871..4a39f108495 100644 --- a/drivers/fuel_gauge/max17048/max17048.c +++ b/drivers/fuel_gauge/max17048/max17048.c @@ -175,23 +175,24 @@ static int max17048_init(const struct device *dev) /** * Get a single property from the fuel gauge */ -static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_gauge_property *prop) +static int max17048_get_single_prop_impl(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { struct max17048_data *data = dev->data; int rc = 0; - switch (prop->property_type) { + switch (prop) { case FUEL_GAUGE_RUNTIME_TO_EMPTY: - prop->value.runtime_to_empty = data->time_to_empty; + val->runtime_to_empty = data->time_to_empty; break; case FUEL_GAUGE_RUNTIME_TO_FULL: - prop->value.runtime_to_full = data->time_to_full; + val->runtime_to_full = data->time_to_full; break; case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: - prop->value.relative_state_of_charge = data->charge; + val->relative_state_of_charge = data->charge; break; case FUEL_GAUGE_VOLTAGE: - prop->value.voltage = data->voltage; + val->voltage = data->voltage; break; default: rc = -ENOTSUP; @@ -203,7 +204,8 @@ static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_g /** * Get properties from the fuel gauge */ -static int max17048_get_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int max17048_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { struct max17048_data *data = dev->data; int rc = max17048_percent(dev, &data->charge); @@ -273,7 +275,7 @@ static int max17048_get_prop(const struct device *dev, struct fuel_gauge_propert data->time_to_empty = 0; } - ret = max17048_get_single_prop_impl(dev, prop); + ret = max17048_get_single_prop_impl(dev, prop, val); return ret; } diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index f246cc87e5b..01740f858f9 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -66,107 +66,108 @@ static int sbs_cmd_buffer_read(const struct device *dev, uint8_t reg_addr, char return 0; } -static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int sbs_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { int rc = 0; - uint16_t val = 0; + uint16_t tmp_val = 0; - switch (prop->property_type) { + switch (prop) { case FUEL_GAUGE_AVG_CURRENT: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_CURRENT, &val); - prop->value.avg_current = val * 1000; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_CURRENT, &tmp_val); + val->avg_current = tmp_val * 1000; break; case FUEL_GAUGE_CYCLE_COUNT: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CYCLE_COUNT, &val); - prop->value.cycle_count = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CYCLE_COUNT, &tmp_val); + val->cycle_count = tmp_val; break; case FUEL_GAUGE_CURRENT: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CURRENT, &val); - prop->value.current = val * 1000; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CURRENT, &tmp_val); + val->current = tmp_val * 1000; break; case FUEL_GAUGE_FULL_CHARGE_CAPACITY: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FULL_CAPACITY, &val); - prop->value.full_charge_capacity = val * 1000; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FULL_CAPACITY, &tmp_val); + val->full_charge_capacity = tmp_val * 1000; break; case FUEL_GAUGE_REMAINING_CAPACITY: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY, &val); - prop->value.remaining_capacity = val * 1000; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY, &tmp_val); + val->remaining_capacity = tmp_val * 1000; break; case FUEL_GAUGE_RUNTIME_TO_EMPTY: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RUNTIME2EMPTY, &val); - prop->value.runtime_to_empty = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RUNTIME2EMPTY, &tmp_val); + val->runtime_to_empty = tmp_val; break; case FUEL_GAUGE_RUNTIME_TO_FULL: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_TIME2FULL, &val); - prop->value.runtime_to_full = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_TIME2FULL, &tmp_val); + val->runtime_to_full = tmp_val; break; case FUEL_GAUGE_SBS_MFR_ACCESS: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, &val); - prop->value.sbs_mfr_access_word = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, &tmp_val); + val->sbs_mfr_access_word = tmp_val; break; case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ASOC, &val); - prop->value.absolute_state_of_charge = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ASOC, &tmp_val); + val->absolute_state_of_charge = tmp_val; break; case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RSOC, &val); - prop->value.relative_state_of_charge = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RSOC, &tmp_val); + val->relative_state_of_charge = tmp_val; break; case FUEL_GAUGE_TEMPERATURE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_TEMP, &val); - prop->value.temperature = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_TEMP, &tmp_val); + val->temperature = tmp_val; break; case FUEL_GAUGE_VOLTAGE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_VOLTAGE, &val); - prop->value.voltage = val * 1000; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_VOLTAGE, &tmp_val); + val->voltage = tmp_val * 1000; break; case FUEL_GAUGE_SBS_MODE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_BATTERY_MODE, &val); - prop->value.sbs_mode = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_BATTERY_MODE, &tmp_val); + val->sbs_mode = tmp_val; break; case FUEL_GAUGE_CHARGE_CURRENT: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_CURRENT, &val); - prop->value.chg_current = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_CURRENT, &tmp_val); + val->chg_current = tmp_val; break; case FUEL_GAUGE_CHARGE_VOLTAGE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_VOLTAGE, &val); - prop->value.chg_voltage = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_VOLTAGE, &tmp_val); + val->chg_voltage = tmp_val; break; case FUEL_GAUGE_STATUS: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FLAGS, &val); - prop->value.fg_status = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FLAGS, &tmp_val); + val->fg_status = tmp_val; break; case FUEL_GAUGE_DESIGN_CAPACITY: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_NOM_CAPACITY, &val); - prop->value.design_cap = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_NOM_CAPACITY, &tmp_val); + val->design_cap = tmp_val; break; case FUEL_GAUGE_DESIGN_VOLTAGE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_DESIGN_VOLTAGE, &val); - prop->value.design_volt = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_DESIGN_VOLTAGE, &tmp_val); + val->design_volt = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AR, &val); - prop->value.sbs_at_rate = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AR, &tmp_val); + val->sbs_at_rate = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTF, &val); - prop->value.sbs_at_rate_time_to_full = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTF, &tmp_val); + val->sbs_at_rate_time_to_full = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTE, &val); - prop->value.sbs_at_rate_time_to_empty = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTE, &tmp_val); + val->sbs_at_rate_time_to_empty = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE_OK: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AROK, &val); - prop->value.sbs_at_rate_ok = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AROK, &tmp_val); + val->sbs_at_rate_ok = tmp_val; break; case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, &val); - prop->value.sbs_remaining_capacity_alarm = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, &tmp_val); + val->sbs_remaining_capacity_alarm = tmp_val; break; case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM: - rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, &val); - prop->value.sbs_remaining_time_alarm = val; + rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, &tmp_val); + val->sbs_remaining_time_alarm = tmp_val; break; default: rc = -ENOTSUP; @@ -194,35 +195,36 @@ static int sbs_gauge_do_battery_cutoff(const struct device *dev) return rc; } -static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop) +static int sbs_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val) { int rc = 0; - uint16_t val = 0; + uint16_t tmp_val = 0; - switch (prop->property_type) { + switch (prop) { case FUEL_GAUGE_SBS_MFR_ACCESS: rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, - prop->value.sbs_mfr_access_word); - prop->value.sbs_mfr_access_word = val; + val.sbs_mfr_access_word); + val.sbs_mfr_access_word = tmp_val; break; case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM: rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, - prop->value.sbs_remaining_capacity_alarm); - prop->value.sbs_remaining_capacity_alarm = val; + val.sbs_remaining_capacity_alarm); + val.sbs_remaining_capacity_alarm = tmp_val; break; case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM: rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, - prop->value.sbs_remaining_time_alarm); - prop->value.sbs_remaining_time_alarm = val; + val.sbs_remaining_time_alarm); + val.sbs_remaining_time_alarm = tmp_val; break; case FUEL_GAUGE_SBS_MODE: - rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_BATTERY_MODE, prop->value.sbs_mode); - prop->value.sbs_mode = val; + rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_BATTERY_MODE, val.sbs_mode); + val.sbs_mode = tmp_val; break; case FUEL_GAUGE_SBS_ATRATE: - rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_AR, prop->value.sbs_at_rate); - prop->value.sbs_at_rate = val; + rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_AR, val.sbs_at_rate); + val.sbs_at_rate = tmp_val; break; default: rc = -ENOTSUP; @@ -232,12 +234,12 @@ static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_proper } static int sbs_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_buffer_property *prop, void *dst, + fuel_gauge_prop_t prop_type, void *dst, size_t dst_len) { int rc = 0; - switch (prop->property_type) { + switch (prop_type) { case FUEL_GAUGE_MANUFACTURER_NAME: if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) { rc = sbs_cmd_buffer_read(dev, SBS_GAUGE_CMD_MANUFACTURER_NAME, (char *)dst, diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index b110ac1d1c1..81bffc11ae8 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -115,76 +115,65 @@ enum fuel_gauge_prop_type { typedef uint16_t fuel_gauge_prop_t; -struct fuel_gauge_property { - /** Battery fuel gauge property to get */ - fuel_gauge_prop_t property_type; - - /** Property field for getting */ - union { - /* Fields have the format: */ - /* FUEL_GAUGE_PROPERTY_FIELD */ - /* type property_field; */ - - /* Dynamic Battery Info */ - /** FUEL_GAUGE_AVG_CURRENT */ - int avg_current; - /** FUEL_GAUGE_CHARGE_CUTOFF */ - bool cutoff; - /** FUEL_GAUGE_CURRENT */ - int current; - /** FUEL_GAUGE_CYCLE_COUNT */ - uint32_t cycle_count; - /** FUEL_GAUGE_FLAGS */ - uint32_t flags; - /** FUEL_GAUGE_FULL_CHARGE_CAPACITY */ - uint32_t full_charge_capacity; - /** FUEL_GAUGE_REMAINING_CAPACITY */ - uint32_t remaining_capacity; - /** FUEL_GAUGE_RUNTIME_TO_EMPTY */ - uint32_t runtime_to_empty; - /** FUEL_GAUGE_RUNTIME_TO_FULL */ - uint32_t runtime_to_full; - /** FUEL_GAUGE_SBS_MFR_ACCESS */ - uint16_t sbs_mfr_access_word; - /** FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE */ - uint8_t absolute_state_of_charge; - /** FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE */ - uint8_t relative_state_of_charge; - /** FUEL_GAUGE_TEMPERATURE */ - uint16_t temperature; - /** FUEL_GAUGE_VOLTAGE */ - int voltage; - /** FUEL_GAUGE_SBS_MODE */ - uint16_t sbs_mode; - /** FUEL_GAUGE_CHARGE_CURRENT */ - uint16_t chg_current; - /** FUEL_GAUGE_CHARGE_VOLTAGE */ - uint16_t chg_voltage; - /** FUEL_GAUGE_STATUS */ - uint16_t fg_status; - /** FUEL_GAUGE_DESIGN_CAPACITY */ - uint16_t design_cap; - /** FUEL_GAUGE_DESIGN_VOLTAGE */ - uint16_t design_volt; - /** FUEL_GAUGE_SBS_ATRATE */ - int16_t sbs_at_rate; - /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL */ - uint16_t sbs_at_rate_time_to_full; - /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY */ - uint16_t sbs_at_rate_time_to_empty; - /** FUEL_GAUGE_SBS_ATRATE_OK */ - bool sbs_at_rate_ok; - /** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */ - uint16_t sbs_remaining_capacity_alarm; - /** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */ - uint16_t sbs_remaining_time_alarm; - } value; -}; - -/** Buffer properties are separated due to size */ -struct fuel_gauge_buffer_property { - /** Battery fuel gauge property to get */ - fuel_gauge_prop_t property_type; +/** Property field to value/type union */ +union fuel_gauge_prop_val { + /* Fields have the format: */ + /* FUEL_GAUGE_PROPERTY_FIELD */ + /* type property_field; */ + + /* Dynamic Battery Info */ + /** FUEL_GAUGE_AVG_CURRENT */ + int avg_current; + /** FUEL_GAUGE_CHARGE_CUTOFF */ + bool cutoff; + /** FUEL_GAUGE_CURRENT */ + int current; + /** FUEL_GAUGE_CYCLE_COUNT */ + uint32_t cycle_count; + /** FUEL_GAUGE_FLAGS */ + uint32_t flags; + /** FUEL_GAUGE_FULL_CHARGE_CAPACITY */ + uint32_t full_charge_capacity; + /** FUEL_GAUGE_REMAINING_CAPACITY */ + uint32_t remaining_capacity; + /** FUEL_GAUGE_RUNTIME_TO_EMPTY */ + uint32_t runtime_to_empty; + /** FUEL_GAUGE_RUNTIME_TO_FULL */ + uint32_t runtime_to_full; + /** FUEL_GAUGE_SBS_MFR_ACCESS */ + uint16_t sbs_mfr_access_word; + /** FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE */ + uint8_t absolute_state_of_charge; + /** FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE */ + uint8_t relative_state_of_charge; + /** FUEL_GAUGE_TEMPERATURE */ + uint16_t temperature; + /** FUEL_GAUGE_VOLTAGE */ + int voltage; + /** FUEL_GAUGE_SBS_MODE */ + uint16_t sbs_mode; + /** FUEL_GAUGE_CHARGE_CURRENT */ + uint16_t chg_current; + /** FUEL_GAUGE_CHARGE_VOLTAGE */ + uint16_t chg_voltage; + /** FUEL_GAUGE_STATUS */ + uint16_t fg_status; + /** FUEL_GAUGE_DESIGN_CAPACITY */ + uint16_t design_cap; + /** FUEL_GAUGE_DESIGN_VOLTAGE */ + uint16_t design_volt; + /** FUEL_GAUGE_SBS_ATRATE */ + int16_t sbs_at_rate; + /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL */ + uint16_t sbs_at_rate_time_to_full; + /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY */ + uint16_t sbs_at_rate_time_to_empty; + /** FUEL_GAUGE_SBS_ATRATE_OK */ + bool sbs_at_rate_ok; + /** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */ + uint16_t sbs_remaining_capacity_alarm; + /** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */ + uint16_t sbs_remaining_time_alarm; }; /** @@ -215,8 +204,8 @@ struct sbs_gauge_device_chemistry { * * See fuel_gauge_get_property() for argument description */ -typedef int (*fuel_gauge_get_property_t)(const struct device *dev, - struct fuel_gauge_property *prop); +typedef int (*fuel_gauge_get_property_t)(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val); /** * @typedef fuel_gauge_set_property_t @@ -224,8 +213,8 @@ typedef int (*fuel_gauge_get_property_t)(const struct device *dev, * * See fuel_gauge_set_property() for argument description */ -typedef int (*fuel_gauge_set_property_t)(const struct device *dev, - struct fuel_gauge_property *prop); +typedef int (*fuel_gauge_set_property_t)(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val); /** * @typedef fuel_gauge_get_buffer_property_t @@ -234,7 +223,7 @@ typedef int (*fuel_gauge_set_property_t)(const struct device *dev, * See fuel_gauge_get_buffer_property() for argument description */ typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev, - struct fuel_gauge_buffer_property *prop, + fuel_gauge_prop_t prop_type, void *dst, size_t dst_len); /** @@ -264,17 +253,16 @@ __subsystem struct fuel_gauge_driver_api { * @brief Fetch a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param prop pointer to a fuel_gauge_property struct where the property struct - * field is set by the caller to determine what property is read from the - * fuel gauge device into the fuel_gauge_property struct's value field. The props array - * maintains the same order of properties as it was given. - * + * @param prop Type of property to be fetched from device + * @param val pointer to a union fuel_gauge_prop_val where the property is read into from the + * fuel gauge device. * @return 0 if successful, negative errno code if failure. */ -__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop); +__syscall int fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val); -static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, - struct fuel_gauge_property *prop) +static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; @@ -282,7 +270,7 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, return -ENOSYS; } - return api->get_property(dev, prop); + return api->get_property(dev, prop, val); } /** @@ -291,23 +279,25 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, * of the fuel gauge driver APIs struct to override this implementation. * * @param dev Pointer to the battery fuel-gauge device - * @param props pointer to array of fuel_gauge_property struct where the property struct - * field is set by the caller to determine what property is read from the - * fuel gauge device into the fuel_gauge_property struct's value field. The props array - * maintains the same order of properties as it was given. - * @param len number of properties in props array + * @param props Array of the type of property to be fetched from device, each index corresponds + * to the same index of the vals input array. + * @param vals Pointer to array of union fuel_gauge_prop_val where the property is read into from + * the fuel gauge device. The vals array is not permuted. + * @param len number of properties in props & vals array * * @return 0 if successful, negative errno code of first failing property */ -__syscall int fuel_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props, - size_t len); + +__syscall int fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len); static inline int z_impl_fuel_gauge_get_props(const struct device *dev, - struct fuel_gauge_property *props, size_t len) + fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len) { const struct fuel_gauge_driver_api *api = dev->api; for (int i = 0; i < len; i++) { - int ret = api->get_property(dev, props + i); + int ret = api->get_property(dev, props[i], vals + i); if (ret) { return ret; @@ -321,16 +311,16 @@ static inline int z_impl_fuel_gauge_get_props(const struct device *dev, * @brief Set a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param prop pointer to fuel_gauge_property struct where the property struct - * field is set by the caller to determine what property is written to the fuel gauge device from - * the fuel_gauge_property struct's value field. + * @param prop Type of property that's being set + * @param val Value to set associated prop property. * * @return 0 if successful, negative errno code of first failing property */ -__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop); +__syscall int fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val); -static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, - struct fuel_gauge_property *prop) +static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val) { const struct fuel_gauge_driver_api *api = dev->api; @@ -338,28 +328,29 @@ static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, return -ENOSYS; } - return api->set_property(dev, prop); + return api->set_property(dev, prop, val); } - /** * @brief Set a battery fuel-gauge property * * @param dev Pointer to the battery fuel-gauge device - * @param props pointer to array of fuel_gauge_property struct where the property struct - * field is set by the caller to determine what property is written to the fuel gauge device from - * the fuel_gauge_property struct's value field. - * @param props_len number of properties in props array + * @param props Array of the type of property to be set, each index corresponds + * to the same index of the vals input array. + * @param vals Pointer to array of union fuel_gauge_prop_val where the property is written + * the fuel gauge device. The vals array is not permuted. + * @param len number of properties in props array * * @return return=0 if successful. Otherwise, return array index of failing property. */ -__syscall int fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, - size_t props_len); +__syscall int fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len); static inline int z_impl_fuel_gauge_set_props(const struct device *dev, - struct fuel_gauge_property *props, size_t props_len) + fuel_gauge_prop_t *props, + union fuel_gauge_prop_val *vals, size_t len) { - for (int i = 0; i < props_len; i++) { - int ret = fuel_gauge_set_prop(dev, props + i); + for (int i = 0; i < len; i++) { + int ret = fuel_gauge_set_prop(dev, props[i], vals[i]); if (ret) { return ret; @@ -373,20 +364,18 @@ static inline int z_impl_fuel_gauge_set_props(const struct device *dev, * @brief Fetch a battery fuel-gauge buffer property * * @param dev Pointer to the battery fuel-gauge device - * @param prop pointer to single fuel_gauge_get_buffer_property struct where the property struct - * field is set by the caller to determine what property is read from the - * fuel gauge device into the dst field. + * @param prop_type Type of property to be fetched from device * @param dst byte array or struct that will hold the buffer data that is read from the fuel gauge * @param dst_len the length of the destination array in bytes * * @return return=0 if successful, return < 0 if getting property failed, return 0 on success */ -__syscall int fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_buffer_property *prop, void *dst, - size_t dst_len); + +__syscall int fuel_gauge_get_buffer_prop(const struct device *dev, fuel_gauge_prop_t prop_type, + void *dst, size_t dst_len); static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev, - struct fuel_gauge_buffer_property *prop, + fuel_gauge_prop_t prop_type, void *dst, size_t dst_len) { const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; @@ -395,7 +384,7 @@ static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev, return -ENOSYS; } - return api->get_buffer_property(dev, prop, dst, dst_len); + return api->get_buffer_property(dev, prop_type, dst, dst_len); } /** diff --git a/samples/fuel_gauge/max17048/src/main.c b/samples/fuel_gauge/max17048/src/main.c index d0e022d9212..26bb94b3852 100644 --- a/samples/fuel_gauge/max17048/src/main.c +++ b/samples/fuel_gauge/max17048/src/main.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "zephyr/sys/util.h" #include #include #include @@ -38,31 +39,26 @@ int main(void) while (1) { - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, - }, - { - .property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, - }, - { - .property_type = FUEL_GAUGE_VOLTAGE, - }}; - - ret = fuel_gauge_get_props(dev, props, ARRAY_SIZE(props)); + fuel_gauge_prop_t props[] = { + FUEL_GAUGE_RUNTIME_TO_EMPTY, + FUEL_GAUGE_RUNTIME_TO_FULL, + FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, + FUEL_GAUGE_VOLTAGE, + }; + + union fuel_gauge_prop_val vals[ARRAY_SIZE(props)]; + + ret = fuel_gauge_get_props(dev, props, vals, ARRAY_SIZE(props)); if (ret < 0) { printk("Error: cannot get properties\n"); } else { - printk("Time to empty %d\n", props[0].value.runtime_to_empty); + printk("Time to empty %d\n", vals[0].runtime_to_empty); - printk("Time to full %d\n", props[1].value.runtime_to_full); + printk("Time to full %d\n", vals[1].runtime_to_full); - printk("Charge %d%%\n", props[2].value.relative_state_of_charge); + printk("Charge %d%%\n", vals[2].relative_state_of_charge); - printk("Voltage %d\n", props[3].value.voltage); + printk("Voltage %d\n", vals[3].voltage); } k_sleep(K_MSEC(5000)); diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c index c5b599ac06c..644d66c7b6c 100644 --- a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -31,53 +31,32 @@ static void *bq27z746_setup(void) return &fixture; } -ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) +ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_bad_status) { - struct fuel_gauge_property props[] = { - { - /* Invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, + fuel_gauge_prop_t props[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_VOLTAGE, }; + union fuel_gauge_prop_val vals[ARRAY_SIZE(props)]; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props)); - zassert_equal(ret, -ENOTSUP); -} - -ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count) -{ - struct fuel_gauge_property props[] = { - { - /* First invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Second invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Valid property */ - .property_type = FUEL_GAUGE_VOLTAGE, - }, - - }; - - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - zassert_equal(ret, -ENOTSUP); + zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); } ZTEST_USER_F(bq27z746, test_get_buffer_prop) { - struct fuel_gauge_buffer_property prop; int ret; { struct sbs_gauge_manufacturer_name mfg_name; - prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name)); + ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_MANUFACTURER_NAME, + &mfg_name, sizeof(mfg_name)); zassert_ok(ret); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ @@ -91,8 +70,8 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop) { struct sbs_gauge_device_name dev_name; - prop.property_type = FUEL_GAUGE_DEVICE_NAME; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name)); + ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_NAME, &dev_name, + sizeof(dev_name)); zassert_ok(ret); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ @@ -104,9 +83,8 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop) { struct sbs_gauge_device_chemistry device_chemistry; - prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; - ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &device_chemistry, - sizeof(device_chemistry)); + ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_CHEMISTRY, + &device_chemistry, sizeof(device_chemistry)); zassert_ok(ret); #if CONFIG_EMUL /* Only test for fixed values in emulation since the real device might be */ @@ -122,101 +100,68 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_AVG_CURRENT, - }, - { - .property_type = FUEL_GAUGE_CYCLE_COUNT, - }, - { - .property_type = FUEL_GAUGE_CURRENT, - }, - { - .property_type = FUEL_GAUGE_FULL_CHARGE_CAPACITY, - }, - { - .property_type = FUEL_GAUGE_REMAINING_CAPACITY, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, - }, - { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - }, - { - .property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, - }, - { - .property_type = FUEL_GAUGE_TEMPERATURE, - }, - { - .property_type = FUEL_GAUGE_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_CHARGE_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_CHARGE_CURRENT, - }, - { - .property_type = FUEL_GAUGE_STATUS, - }, - { - .property_type = FUEL_GAUGE_DESIGN_CAPACITY, - }, + fuel_gauge_prop_t props[] = { + FUEL_GAUGE_AVG_CURRENT, + FUEL_GAUGE_CYCLE_COUNT, + FUEL_GAUGE_CURRENT, + FUEL_GAUGE_FULL_CHARGE_CAPACITY, + FUEL_GAUGE_REMAINING_CAPACITY, + FUEL_GAUGE_RUNTIME_TO_EMPTY, + FUEL_GAUGE_RUNTIME_TO_FULL, + FUEL_GAUGE_SBS_MFR_ACCESS, + FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, + FUEL_GAUGE_TEMPERATURE, + FUEL_GAUGE_VOLTAGE, + FUEL_GAUGE_SBS_ATRATE, + FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY, + FUEL_GAUGE_CHARGE_VOLTAGE, + FUEL_GAUGE_CHARGE_CURRENT, + FUEL_GAUGE_STATUS, + FUEL_GAUGE_DESIGN_CAPACITY, }; + union fuel_gauge_prop_val vals[ARRAY_SIZE(props)]; - zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); + zassert_ok(fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props))); /* Check properties for valid ranges */ #if CONFIG_EMUL /* When emulating, check for the fixed values coming from the emulator */ - zassert_equal(props[0].value.avg_current, -2000); - zassert_equal(props[1].value.cycle_count, 100); - zassert_equal(props[2].value.current, -2000); - zassert_equal(props[3].value.full_charge_capacity, 1000); - zassert_equal(props[4].value.remaining_capacity, 1000); - zassert_equal(props[5].value.runtime_to_empty, 1); - zassert_equal(props[6].value.runtime_to_full, 1); - zassert_equal(props[7].value.sbs_mfr_access_word, 1); - zassert_equal(props[8].value.relative_state_of_charge, 1); - zassert_equal(props[9].value.temperature, 1); - zassert_equal(props[10].value.voltage, 1000); - zassert_equal(props[11].value.sbs_at_rate, -2); - zassert_equal(props[12].value.sbs_at_rate_time_to_empty, 1); - zassert_equal(props[13].value.chg_voltage, 1); - zassert_equal(props[14].value.chg_current, 1); - zassert_equal(props[15].value.fg_status, 1); - zassert_equal(props[16].value.design_cap, 1); + zassert_equal(vals[0].avg_current, -2000); + zassert_equal(vals[1].cycle_count, 100); + zassert_equal(vals[2].current, -2000); + zassert_equal(vals[3].full_charge_capacity, 1000); + zassert_equal(vals[4].remaining_capacity, 1000); + zassert_equal(vals[5].runtime_to_empty, 1); + zassert_equal(vals[6].runtime_to_full, 1); + zassert_equal(vals[7].sbs_mfr_access_word, 1); + zassert_equal(vals[8].relative_state_of_charge, 1); + zassert_equal(vals[9].temperature, 1); + zassert_equal(vals[10].voltage, 1000); + zassert_equal(vals[11].sbs_at_rate, -2); + zassert_equal(vals[12].sbs_at_rate_time_to_empty, 1); + zassert_equal(vals[13].chg_voltage, 1); + zassert_equal(vals[14].chg_current, 1); + zassert_equal(vals[15].fg_status, 1); + zassert_equal(vals[16].design_cap, 1); #else /* When having a real device, check for the valid ranges */ - zassert_between_inclusive(props[0].value.avg_current, -32768 * 1000, 32767 * 1000); - zassert_between_inclusive(props[1].value.cycle_count, 0, 6553500); - zassert_between_inclusive(props[2].value.current, -32768 * 1000, 32767 * 1000); - zassert_between_inclusive(props[3].value.full_charge_capacity, 0, 32767 * 1000); - zassert_between_inclusive(props[4].value.remaining_capacity, 0, 32767 * 1000); - zassert_between_inclusive(props[5].value.runtime_to_empty, 0, 65535); - zassert_between_inclusive(props[6].value.runtime_to_full, 0, 65535); + zassert_between_inclusive(props[0].avg_current, -32768 * 1000, 32767 * 1000); + zassert_between_inclusive(props[1].cycle_count, 0, 6553500); + zassert_between_inclusive(props[2].current, -32768 * 1000, 32767 * 1000); + zassert_between_inclusive(props[3].full_charge_capacity, 0, 32767 * 1000); + zassert_between_inclusive(props[4].remaining_capacity, 0, 32767 * 1000); + zassert_between_inclusive(props[5].runtime_to_empty, 0, 65535); + zassert_between_inclusive(props[6].runtime_to_full, 0, 65535); /* Not testing props[7]. This is the manufacturer access and has only status bits */ - zassert_between_inclusive(props[8].value.relative_state_of_charge, 0, 100); - zassert_between_inclusive(props[9].value.temperature, 0, 32767); - zassert_between_inclusive(props[10].value.voltage, 0, 32767 * 1000); - zassert_between_inclusive(props[11].value.sbs_at_rate, -32768, 32767); - zassert_between_inclusive(props[12].value.sbs_at_rate_time_to_empty, 0, 65535); - zassert_between_inclusive(props[13].value.chg_voltage, 0, 32767); - zassert_between_inclusive(props[14].value.chg_current, 0, 32767); + zassert_between_inclusive(props[8].relative_state_of_charge, 0, 100); + zassert_between_inclusive(props[9].temperature, 0, 32767); + zassert_between_inclusive(props[10].voltage, 0, 32767 * 1000); + zassert_between_inclusive(props[11].sbs_at_rate, -32768, 32767); + zassert_between_inclusive(props[12].sbs_at_rate_time_to_empty, 0, 65535); + zassert_between_inclusive(props[13].chg_voltage, 0, 32767); + zassert_between_inclusive(props[14].chg_current, 0, 32767); /* Not testing props[15]. This property is the status and only has only status bits */ - zassert_between_inclusive(props[16].value.design_cap, 0, 32767); + zassert_between_inclusive(props[16].design_cap, 0, 32767); #endif } diff --git a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c index c2452bc60f5..957a632ad4a 100644 --- a/tests/drivers/fuel_gauge/max17048/src/test_max17048.c +++ b/tests/drivers/fuel_gauge/max17048/src/test_max17048.c @@ -32,98 +32,63 @@ static void *max17048_setup(void) return &fixture; } -ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) +ZTEST_USER_F(max17048, test_get_some_props_failed_returns_bad_status) { - struct fuel_gauge_property props[] = { - { - /* Invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, + fuel_gauge_prop_t prop_types[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_VOLTAGE, }; + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); - zassert_equal(-ENOTSUP, ret); + zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); } -ZTEST_USER_F(max17048, test_get_some_props_failed_returns_errno) -{ - struct fuel_gauge_property props[] = { - { - /* First invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Second invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Valid property */ - .property_type = FUEL_GAUGE_VOLTAGE, - }, - - }; - - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); - - zassert_equal(ret, -ENOTSUP); -} - - ZTEST_USER_F(max17048, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, - }, - { - .property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, - }, - { - .property_type = FUEL_GAUGE_VOLTAGE, - } + fuel_gauge_prop_t prop_types[] = { + FUEL_GAUGE_VOLTAGE, + FUEL_GAUGE_RUNTIME_TO_EMPTY, + FUEL_GAUGE_RUNTIME_TO_FULL, + FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, }; - zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; + + zassert_ok(fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props))); } ZTEST_USER_F(max17048, test_current_rate_zero) { /* Test when crate is 0, which is a special case */ - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, - } + fuel_gauge_prop_t prop_types[] = { + FUEL_GAUGE_RUNTIME_TO_EMPTY, + FUEL_GAUGE_RUNTIME_TO_FULL, }; + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; /** Null value, not charging either discharging. If not handled correctly, * it will cause a division by zero */ emul_max17048_set_crate_status(0); - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); - zassert_equal(props[0].value.runtime_to_empty, 0, - "Runtime to empty is %d but it should be 0.", - props[0].value.runtime_to_full - ); - zassert_equal(props[1].value.runtime_to_full, 0, - "Runtime to full is %d but it should be 0.", - props[1].value.runtime_to_full - ); + zassert_equal(props[0].runtime_to_empty, 0, "Runtime to empty is %d but it should be 0.", + props[0].runtime_to_full); + zassert_equal(props[1].runtime_to_full, 0, "Runtime to full is %d but it should be 0.", + props[1].runtime_to_full); zassert_ok(ret); /* Return value to the original state */ emul_max17048_set_crate_status(0x4000); } - ZTEST_SUITE(max17048, NULL, max17048_setup, NULL, NULL, NULL); diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 2fd71433c28..98adf73afaf 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -34,62 +34,58 @@ static void *sbs_gauge_new_api_setup(void) ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_bad_status) { - struct fuel_gauge_property props[] = { - { - /* First invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Second invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Valid property */ - .property_type = FUEL_GAUGE_VOLTAGE, - }, - + fuel_gauge_prop_t prop_types[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_VOLTAGE, }; + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; - int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); } ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_err) { - struct fuel_gauge_property props[] = { - { - /* Invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, + fuel_gauge_prop_t prop_types[] = { + /* Invalid property */ + FUEL_GAUGE_PROP_MAX, }; + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; - int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); + int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); zassert_equal(ret, -ENOTSUP); } ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err) { - struct fuel_gauge_property props[] = { - { - /* First invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Second invalid property */ - .property_type = FUEL_GAUGE_PROP_MAX, - }, - { - /* Valid property */ - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - /* Set Manufacturer's Access to arbitrary word */ - .value.sbs_mfr_access_word = 1, - }, + fuel_gauge_prop_t prop_types[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_SBS_MFR_ACCESS, + /* Set Manufacturer's Access to arbitrary word */ }; - int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); + union fuel_gauge_prop_val props[] = { + /* First invalid property */ + {0}, + /* Second invalid property */ + {0}, + /* Valid property */ + /* Set Manufacturer's Access to arbitrary word */ + {.sbs_mfr_access_word = 1}, + }; + + int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); zassert_equal(ret, -ENOTSUP); } @@ -97,184 +93,116 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err) ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) { uint16_t word = BIT(15) | BIT(0); - struct fuel_gauge_property set_props[] = { - { - /* Valid property */ - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - /* Set Manufacturer's Access to 16 bit word */ - .value.sbs_mfr_access_word = word, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, - .value.sbs_remaining_capacity_alarm = word, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, - .value.sbs_remaining_time_alarm = word, - }, - { - .property_type = FUEL_GAUGE_SBS_MODE, - .value.sbs_mode = word, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE, - .value.sbs_at_rate = (int16_t)word, - }, + + fuel_gauge_prop_t prop_types[] = { + FUEL_GAUGE_SBS_MFR_ACCESS, + FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, + FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, + FUEL_GAUGE_SBS_MODE, + FUEL_GAUGE_SBS_ATRATE, }; - struct fuel_gauge_property get_props[] = { + union fuel_gauge_prop_val set_props[] = { { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, + .sbs_mfr_access_word = word, }, { - .property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, + .sbs_remaining_capacity_alarm = word, }, { - .property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, + .sbs_remaining_time_alarm = word, }, { - .property_type = FUEL_GAUGE_SBS_MODE, + .sbs_mode = word, }, { - .property_type = FUEL_GAUGE_SBS_ATRATE, + .sbs_at_rate = (int16_t)word, }, }; - zassert_ok(fuel_gauge_set_props(fixture->dev, set_props, ARRAY_SIZE(set_props))); + union fuel_gauge_prop_val get_props[ARRAY_SIZE(prop_types)]; + + zassert_ok( + fuel_gauge_set_props(fixture->dev, prop_types, set_props, ARRAY_SIZE(set_props))); - zassert_ok(fuel_gauge_get_props(fixture->dev, get_props, ARRAY_SIZE(get_props))); + zassert_ok( + fuel_gauge_get_props(fixture->dev, prop_types, get_props, ARRAY_SIZE(get_props))); - zassert_equal(get_props[0].value.sbs_mfr_access_word, word); - zassert_equal(get_props[1].value.sbs_remaining_capacity_alarm, word); - zassert_equal(get_props[2].value.sbs_remaining_time_alarm, word); - zassert_equal(get_props[3].value.sbs_mode, word); - zassert_equal(get_props[4].value.sbs_at_rate, (int16_t)word); + zassert_equal(get_props[0].sbs_mfr_access_word, word); + zassert_equal(get_props[1].sbs_remaining_capacity_alarm, word); + zassert_equal(get_props[2].sbs_remaining_time_alarm, word); + zassert_equal(get_props[3].sbs_mode, word); + zassert_equal(get_props[4].sbs_at_rate, (int16_t)word); } ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_CURRENT, - }, - { - .property_type = FUEL_GAUGE_AVG_CURRENT, - }, - { - .property_type = FUEL_GAUGE_TEMPERATURE, - }, - { - .property_type = FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE, - }, - { - .property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_FULL, - }, - { - .property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_REMAINING_CAPACITY, - }, - { - .property_type = FUEL_GAUGE_FULL_CHARGE_CAPACITY, - }, - { - .property_type = FUEL_GAUGE_CYCLE_COUNT, - }, - { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - }, - { - .property_type = FUEL_GAUGE_SBS_MODE, - }, - { - .property_type = FUEL_GAUGE_CHARGE_CURRENT, - }, - { - .property_type = FUEL_GAUGE_CHARGE_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_STATUS, - }, - { - .property_type = FUEL_GAUGE_DESIGN_CAPACITY, - }, - { - .property_type = FUEL_GAUGE_DESIGN_VOLTAGE, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE_OK, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, - }, + fuel_gauge_prop_t prop_types[] = { + FUEL_GAUGE_VOLTAGE, + FUEL_GAUGE_CURRENT, + FUEL_GAUGE_AVG_CURRENT, + FUEL_GAUGE_TEMPERATURE, + FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE, + FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, + FUEL_GAUGE_RUNTIME_TO_FULL, + FUEL_GAUGE_RUNTIME_TO_EMPTY, + FUEL_GAUGE_REMAINING_CAPACITY, + FUEL_GAUGE_FULL_CHARGE_CAPACITY, + FUEL_GAUGE_CYCLE_COUNT, + FUEL_GAUGE_SBS_MFR_ACCESS, + FUEL_GAUGE_SBS_MODE, + FUEL_GAUGE_CHARGE_CURRENT, + FUEL_GAUGE_CHARGE_VOLTAGE, + FUEL_GAUGE_STATUS, + FUEL_GAUGE_DESIGN_CAPACITY, + FUEL_GAUGE_DESIGN_VOLTAGE, + FUEL_GAUGE_SBS_ATRATE, + FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL, + FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY, + FUEL_GAUGE_SBS_ATRATE_OK, + FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, + FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, }; - zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; + + zassert_ok(fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props))); } ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) { /* Validate what props are supported by the driver */ - struct fuel_gauge_property props[] = { - { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, - }, - { - .property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, - }, - { - .property_type = FUEL_GAUGE_SBS_MODE, - }, - { - .property_type = FUEL_GAUGE_SBS_ATRATE, - }, + fuel_gauge_prop_t prop_types[] = { + FUEL_GAUGE_SBS_MFR_ACCESS, + FUEL_GAUGE_SBS_MODE, + FUEL_GAUGE_SBS_ATRATE, + FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, + FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, + }; + union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)]; - zassert_ok(fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props))); + zassert_ok(fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props))); } - ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) { /* Validate what properties are supported by the driver */ - struct fuel_gauge_buffer_property prop; struct sbs_gauge_manufacturer_name mfg_name; struct sbs_gauge_device_name dev_name; struct sbs_gauge_device_chemistry chem; - prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; - zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name))); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_MANUFACTURER_NAME, &mfg_name, + sizeof(mfg_name))); - prop.property_type = FUEL_GAUGE_DEVICE_NAME; - zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name))); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_NAME, &dev_name, + sizeof(dev_name))); - prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; - zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &chem, sizeof(chem))); + zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_CHEMISTRY, &chem, + sizeof(chem))); } ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) @@ -283,23 +211,16 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) uint32_t expected_uV = 5000 * 1000; uint32_t expected_uA = 3000 * 1000; - struct fuel_gauge_property voltage = { - .property_type = FUEL_GAUGE_VOLTAGE, - }; - struct fuel_gauge_property current = { - .property_type = FUEL_GAUGE_CURRENT, - }; + union fuel_gauge_prop_val voltage; + union fuel_gauge_prop_val current; zassume_ok(emul_fuel_gauge_set_battery_charging(fixture->sbs_fuel_gauge, expected_uV, expected_uA)); - zassert_ok(fuel_gauge_get_prop(fixture->dev, &voltage)); - zassert_ok(fuel_gauge_get_prop(fixture->dev, ¤t)); + zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_VOLTAGE, &voltage)); + zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_CURRENT, ¤t)); - zassert_equal(voltage.value.voltage, expected_uV, "Got %d instead of %d", - voltage.value.voltage, expected_uV); - - zassert_equal(current.value.current, expected_uA, "Got %d instead of %d", - current.value.current, expected_uA); + zassert_equal(voltage.voltage, expected_uV, "Got %d instead of %d", voltage, expected_uV); + zassert_equal(current.current, expected_uA, "Got %d instead of %d", current, expected_uA); } ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop) @@ -308,17 +229,14 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop) uint16_t test_value = 0x1001; - struct fuel_gauge_property mfr_acc_set = { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, - .value.sbs_mfr_access_word = test_value, - }; - struct fuel_gauge_property mfr_acc_get = { - .property_type = FUEL_GAUGE_SBS_MFR_ACCESS, + union fuel_gauge_prop_val mfr_acc_set = { + .sbs_mfr_access_word = test_value, }; + union fuel_gauge_prop_val mfr_acc_get; - zassert_ok(fuel_gauge_set_prop(fixture->dev, &mfr_acc_set)); - zassert_ok(fuel_gauge_get_prop(fixture->dev, &mfr_acc_get)); - zassert_equal(mfr_acc_get.value.sbs_mfr_access_word, test_value); + zassert_ok(fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_SBS_MFR_ACCESS, mfr_acc_set)); + zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_SBS_MFR_ACCESS, &mfr_acc_get)); + zassert_equal(mfr_acc_get.sbs_mfr_access_word, test_value); } ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL); From 9e87bd7ad67afeb3af91f8d82e1b3e2020b8e22f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 23:04:33 +0000 Subject: [PATCH 1125/4498] gitlint: exclude long line with co-authored-by Treat co-authored-by like signed-off-by. Signed-off-by: Anas Nashif --- scripts/gitlint/zephyr_commit_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gitlint/zephyr_commit_rules.py b/scripts/gitlint/zephyr_commit_rules.py index 8979292bbb6..ea31c6737f3 100644 --- a/scripts/gitlint/zephyr_commit_rules.py +++ b/scripts/gitlint/zephyr_commit_rules.py @@ -109,7 +109,7 @@ class MaxLineLengthExceptions(LineRule): def validate(self, line, _commit): max_length = self.options['line-length'].value urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', line) - if line.startswith('Signed-off-by'): + if line.lower().startswith('signed-off-by') or line.lower().startswith('co-authored-by'): return if urls: From e0a0b357a8d757fb602b3d12231ee722227cb918 Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Tue, 26 Sep 2023 09:53:50 +0200 Subject: [PATCH 1126/4498] boards: arm: cc1352*/cc26x2* based: add hwinfo as supported Add 'hwinfo' to supported features list in CC1352* and CC26x2* based boards yaml and documentation files. Driver for this platform was included in 634416bc49. Signed-off-by: Piotr Dymacz --- boards/arm/beagle_bcf/beagleconnect_freedom.yaml | 1 + boards/arm/beagle_bcf/doc/index.rst | 2 ++ boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml | 1 + boards/arm/cc1352p1_launchxl/doc/index.rst | 2 ++ boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml | 1 + boards/arm/cc1352r1_launchxl/doc/index.rst | 2 ++ boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml | 1 + boards/arm/cc1352r_sensortag/doc/index.rst | 2 ++ boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml | 1 + boards/arm/cc26x2r1_launchxl/doc/index.rst | 2 ++ 10 files changed, 15 insertions(+) diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom.yaml b/boards/arm/beagle_bcf/beagleconnect_freedom.yaml index 0d1cd99730b..46cfaf5de3f 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom.yaml +++ b/boards/arm/beagle_bcf/beagleconnect_freedom.yaml @@ -13,4 +13,5 @@ supported: - i2c - spi - uart + - hwinfo vendor: beagle diff --git a/boards/arm/beagle_bcf/doc/index.rst b/boards/arm/beagle_bcf/doc/index.rst index 311e99449c2..c208d41e431 100644 --- a/boards/arm/beagle_bcf/doc/index.rst +++ b/boards/arm/beagle_bcf/doc/index.rst @@ -54,6 +54,8 @@ The board configuration supports the following hardware features: +-----------+------------+----------------------+ | SPI | on-chip | spi | +-----------+------------+----------------------+ +| HWINFO | on-chip | hwinfo | ++-----------+------------+----------------------+ | I2C | off-chip | OPT3001 | +-----------+------------+----------------------+ | I2C | off-chip | HDC2010 | diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml index ac4cabbc16b..57e62c2ddec 100644 --- a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml @@ -13,4 +13,5 @@ supported: - i2c - spi - watchdog + - hwinfo vendor: ti diff --git a/boards/arm/cc1352p1_launchxl/doc/index.rst b/boards/arm/cc1352p1_launchxl/doc/index.rst index 7c934fd0cc6..5e9690fefbd 100644 --- a/boards/arm/cc1352p1_launchxl/doc/index.rst +++ b/boards/arm/cc1352p1_launchxl/doc/index.rst @@ -58,6 +58,8 @@ features: +-----------+------------+----------------------+ | WDT | on-chip | watchdog | +-----------+------------+----------------------+ +| HWINFO | on-chip | hwinfo | ++-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml index b986a52a43f..7c37a902893 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.yaml @@ -14,4 +14,5 @@ supported: - spi - watchdog - adc + - hwinfo vendor: ti diff --git a/boards/arm/cc1352r1_launchxl/doc/index.rst b/boards/arm/cc1352r1_launchxl/doc/index.rst index adece79d1b4..b3c999a1494 100644 --- a/boards/arm/cc1352r1_launchxl/doc/index.rst +++ b/boards/arm/cc1352r1_launchxl/doc/index.rst @@ -57,6 +57,8 @@ features: +-----------+------------+----------------------+ | AUX_ADC | on-chip | adc | +-----------+------------+----------------------+ +| HWINFO | on-chip | hwinfo | ++-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml index a5234f005e3..ab974002e38 100644 --- a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml @@ -14,4 +14,5 @@ supported: - spi - watchdog - adc + - hwinfo vendor: ti diff --git a/boards/arm/cc1352r_sensortag/doc/index.rst b/boards/arm/cc1352r_sensortag/doc/index.rst index f3843c9505f..c270e85fd57 100644 --- a/boards/arm/cc1352r_sensortag/doc/index.rst +++ b/boards/arm/cc1352r_sensortag/doc/index.rst @@ -65,6 +65,8 @@ features: +-----------+------------+------------------+ | WDT | on-chip | watchdog | +-----------+------------+------------------+ +| HWINFO | on-chip | hwinfo | ++-----------+------------+------------------+ Other hardware features have not been enabled yet for this board. diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml index 0db9c598d92..1c2bd9d8876 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml @@ -14,4 +14,5 @@ supported: - spi - watchdog - adc + - hwinfo vendor: ti diff --git a/boards/arm/cc26x2r1_launchxl/doc/index.rst b/boards/arm/cc26x2r1_launchxl/doc/index.rst index 8f2004be90f..89bdb035a31 100644 --- a/boards/arm/cc26x2r1_launchxl/doc/index.rst +++ b/boards/arm/cc26x2r1_launchxl/doc/index.rst @@ -57,6 +57,8 @@ features: +-----------+------------+----------------------+ | AUX_ADC | on-chip | adc | +-----------+------------+----------------------+ +| HWINFO | on-chip | hwinfo | ++-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. From ad08b3c300208749956ba339f8489d1a60aa525c Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 26 Sep 2023 16:46:26 +0200 Subject: [PATCH 1127/4498] dts: bindings: add missing pinctrl-device.yaml includes These worked because edtlib allows 'pinctrl-.*' properties without specifying them on the bindings. However, this has never been an anounced pinctrl feature, the reference documents explicitly mention that usage of pinctrl-device.yaml is mandatory. Signed-off-by: Gerard Marull-Paretas --- dts/bindings/dac/nxp,lpdac.yaml | 2 +- dts/bindings/i2c/sifive,i2c0.yaml | 2 +- dts/bindings/i2c/telink,b91-i2c.yaml | 3 +-- dts/bindings/pwm/telink,b91-pwm.yaml | 3 +-- dts/bindings/serial/quicklogic,usbserialport_s3b.yaml | 2 +- dts/bindings/serial/telink,b91-uart.yaml | 3 +-- dts/bindings/spi/telink,b91-spi.yaml | 3 +-- dts/bindings/test/vnd,adc-temp-sensor.yaml | 11 +---------- 8 files changed, 8 insertions(+), 21 deletions(-) diff --git a/dts/bindings/dac/nxp,lpdac.yaml b/dts/bindings/dac/nxp,lpdac.yaml index 2a79af254b7..4b9e67f310f 100644 --- a/dts/bindings/dac/nxp,lpdac.yaml +++ b/dts/bindings/dac/nxp,lpdac.yaml @@ -5,7 +5,7 @@ description: NXP MCUX LPDAC compatible: "nxp,lpdac" -include: dac-controller.yaml +include: [dac-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/i2c/sifive,i2c0.yaml b/dts/bindings/i2c/sifive,i2c0.yaml index 81c94e29e6c..8adb27eaa23 100644 --- a/dts/bindings/i2c/sifive,i2c0.yaml +++ b/dts/bindings/i2c/sifive,i2c0.yaml @@ -5,7 +5,7 @@ description: SiFive Freedom I2C interface compatible: "sifive,i2c0" -include: i2c-controller.yaml +include: [i2c-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/i2c/telink,b91-i2c.yaml b/dts/bindings/i2c/telink,b91-i2c.yaml index d0de9f93891..fe700641748 100644 --- a/dts/bindings/i2c/telink,b91-i2c.yaml +++ b/dts/bindings/i2c/telink,b91-i2c.yaml @@ -3,7 +3,7 @@ description: Telink B91 I2C -include: i2c-controller.yaml +include: [i2c-controller.yaml, pinctrl-device.yaml] compatible: "telink,b91-i2c" @@ -12,5 +12,4 @@ properties: required: true pinctrl-0: - type: phandles required: true diff --git a/dts/bindings/pwm/telink,b91-pwm.yaml b/dts/bindings/pwm/telink,b91-pwm.yaml index 7c96698f0f6..798cfcfb3ca 100644 --- a/dts/bindings/pwm/telink,b91-pwm.yaml +++ b/dts/bindings/pwm/telink,b91-pwm.yaml @@ -4,14 +4,13 @@ description: Telink B91 PWM -include: [pwm-controller.yaml, base.yaml] +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] compatible: "telink,b91-pwm" properties: pinctrl-0: - type: phandles required: true clock-frequency: diff --git a/dts/bindings/serial/quicklogic,usbserialport_s3b.yaml b/dts/bindings/serial/quicklogic,usbserialport_s3b.yaml index 55661083585..36800dcd782 100644 --- a/dts/bindings/serial/quicklogic,usbserialport_s3b.yaml +++ b/dts/bindings/serial/quicklogic,usbserialport_s3b.yaml @@ -5,7 +5,7 @@ description: QuickLogic USBserialport_S3B serial interface compatible: "quicklogic,usbserialport-s3b" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/serial/telink,b91-uart.yaml b/dts/bindings/serial/telink,b91-uart.yaml index b3affa70c68..b38be5dfd42 100644 --- a/dts/bindings/serial/telink,b91-uart.yaml +++ b/dts/bindings/serial/telink,b91-uart.yaml @@ -5,7 +5,7 @@ description: Telink B91 UART compatible: "telink,b91-uart" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: @@ -15,5 +15,4 @@ properties: required: true pinctrl-0: - type: phandles required: true diff --git a/dts/bindings/spi/telink,b91-spi.yaml b/dts/bindings/spi/telink,b91-spi.yaml index e49e660d41d..7e66217f3dd 100644 --- a/dts/bindings/spi/telink,b91-spi.yaml +++ b/dts/bindings/spi/telink,b91-spi.yaml @@ -3,7 +3,7 @@ description: Telink B91 SPI -include: spi-controller.yaml +include: [spi-controller.yaml, pinctrl-device.yaml] compatible: "telink,b91-spi" @@ -19,7 +19,6 @@ properties: - "HSPI_MODULE" pinctrl-0: - type: phandles required: true cs0-pin: diff --git a/dts/bindings/test/vnd,adc-temp-sensor.yaml b/dts/bindings/test/vnd,adc-temp-sensor.yaml index 8bc33a7373a..89389b05401 100644 --- a/dts/bindings/test/vnd,adc-temp-sensor.yaml +++ b/dts/bindings/test/vnd,adc-temp-sensor.yaml @@ -5,7 +5,7 @@ description: Test ADC-based temperature sensor compatible: "vnd,adc-temp-sensor" -include: [base.yaml, reset-device.yaml] +include: [base.yaml, pinctrl-device.yaml, reset-device.yaml] properties: io-channels: @@ -18,12 +18,3 @@ properties: clocks: required: true - - pinctrl-0: - type: phandles - - pinctrl-1: - type: phandles - - pinctrl-2: - type: phandles From 7ff50882e928c15cd409b66a38645efee0be68f4 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 26 Sep 2023 17:47:14 +0200 Subject: [PATCH 1128/4498] boards: vmu_rt1170: remove regulator-fixed pinctrl entries regulator-fixed is not a pinctrl-device, so these entries were invalid (and not used). Signed-off-by: Gerard Marull-Paretas --- boards/arm/vmu_rt1170/vmu_rt1170-pinctrl.dtsi | 18 ------------------ boards/arm/vmu_rt1170/vmu_rt1170.dts | 18 ------------------ 2 files changed, 36 deletions(-) diff --git a/boards/arm/vmu_rt1170/vmu_rt1170-pinctrl.dtsi b/boards/arm/vmu_rt1170/vmu_rt1170-pinctrl.dtsi index 4f9cdf77857..3f27e5c3a33 100644 --- a/boards/arm/vmu_rt1170/vmu_rt1170-pinctrl.dtsi +++ b/boards/arm/vmu_rt1170/vmu_rt1170-pinctrl.dtsi @@ -9,24 +9,6 @@ #include &pinctrl { - - - pinmux_regulator: pinmux_regulator { - group0 { - pinmux = <&iomuxc_gpio_emc_b1_34_gpio_mux2_io02>, - <&iomuxc_gpio_emc_b1_37_gpio_mux2_io05>, - <&iomuxc_gpio_emc_b1_33_gpio_mux2_io01>, - <&iomuxc_gpio_emc_b1_22_gpio_mux1_io22>, - <&iomuxc_gpio_emc_b1_14_gpio_mux1_io14>, - <&iomuxc_gpio_emc_b1_36_gpio_mux2_io04>, - <&iomuxc_gpio_emc_b1_38_gpio_mux2_io06>, - <&iomuxc_gpio_emc_b1_01_gpio_mux1_io01>, - <&iomuxc_gpio_disp_b2_08_gpio_mux5_io09>; - bias-pull-up; - slew-rate = "fast"; - }; - }; - pinmux_enet: pinmux_enet { group0 { pinmux = <&iomuxc_gpio_disp_b2_09_gpio_mux5_io10>, diff --git a/boards/arm/vmu_rt1170/vmu_rt1170.dts b/boards/arm/vmu_rt1170/vmu_rt1170.dts index 0b4298b24df..265fedef389 100644 --- a/boards/arm/vmu_rt1170/vmu_rt1170.dts +++ b/boards/arm/vmu_rt1170/vmu_rt1170.dts @@ -36,8 +36,6 @@ /* This regulator controls VDD_3V3_SD_CARD onboard supply */ reg-3v3-sdcard { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sdcard"; enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; @@ -47,8 +45,6 @@ /* This regulator controls VDD_5V_PERIPH onboard supply */ reg-5v-periph { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-5v-periph"; enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; @@ -58,8 +54,6 @@ /* This regulator controls VDD_5V_HIPOWER onboard supply */ reg-5v-hipower { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-5v-hipower"; enable-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; @@ -69,8 +63,6 @@ /* This regulator controls the VDD_3V3_SENSORS1 onboard supply. */ reg-3v3-sensors-1 { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sensors-1"; enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; @@ -81,8 +73,6 @@ /* This regulator controls the VDD_3V3_SENSORS2 onboard supply. */ reg-3v3-sensors-2 { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sensors-2"; enable-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; @@ -93,8 +83,6 @@ /* This regulator controls the VDD_3V3_SENSORS3 onboard supply. */ reg-3v3-sensors-3 { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sensors-3"; enable-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; @@ -105,8 +93,6 @@ /* This regulator controls the VDD_3V3_SENSORS4 onboard supply. */ reg-3v3-sensors-4 { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sensors-4"; enable-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; @@ -117,8 +103,6 @@ /* This regulator controls VDD_3V3_SPEKTRUM onboard supply */ reg-3v3-spektrum { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-spektrum"; enable-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; @@ -128,8 +112,6 @@ /* This regulator controls ETH_VDD_3V3 supply to power up the TJA1103 PHY */ reg-eth-power { - pinctrl-0 = <&pinmux_regulator>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-eth-power"; enable-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; From 078d6c9b419340bb3bf2acfc8a14a993bb2881ac Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 26 Sep 2023 17:55:14 +0200 Subject: [PATCH 1129/4498] boards: mimxrt1062_fmurt6: remove regulator-fixed pinctrl entries regulator-fixed is not a pinctrl-device, so these entries were invalid (and not used). Signed-off-by: Gerard Marull-Paretas --- .../mimxrt1062_fmurt6-pinctrl.dtsi | 14 -------------- boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.dts | 12 ------------ 2 files changed, 26 deletions(-) diff --git a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6-pinctrl.dtsi b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6-pinctrl.dtsi index 9c22377dfe2..03b2c29c0d1 100644 --- a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6-pinctrl.dtsi +++ b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6-pinctrl.dtsi @@ -59,20 +59,6 @@ }; }; - pinmux_sensor: pinmux_sensor { - group0 { - pinmux = <&iomuxc_gpio_emc_13_gpio4_io13>, - <&iomuxc_gpio_emc_09_gpio4_io09>, - <&iomuxc_gpio_emc_06_gpio4_io06>, - <&iomuxc_gpio_emc_41_gpio3_io27>, - <&iomuxc_gpio_ad_b0_00_gpio1_io00>, - <&iomuxc_snvs_pmic_on_req_gpio5_io01>; - drive-strength = "r0-7"; - bias-pull-up; - slew-rate = "fast"; - }; - }; - pinmux_flexcan1: pinmux_flexcan1 { group0 { pinmux = <&iomuxc_gpio_ad_b1_08_flexcan1_tx>, diff --git a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.dts b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.dts index 17caea7f2b1..c3af13f1f0d 100644 --- a/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.dts +++ b/boards/arm/mimxrt1062_fmurt6/mimxrt1062_fmurt6.dts @@ -51,8 +51,6 @@ /* This regulator controls VDD_3V3_SD_CARD onboard supply */ reg-3v3-sdcard { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sdcard"; enable-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; @@ -62,8 +60,6 @@ /* This regulator controls VDD_5V_PERIPH onboard supply */ reg-5v-periph { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-5v-periph"; enable-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; @@ -73,8 +69,6 @@ /* This regulator controls VDD_5V_HIPOWER onboard supply */ reg-5v-hipower { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-5v-hipower"; enable-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; @@ -84,8 +78,6 @@ /* This regulator controls the 3V3_S line, which powers sensors on-board. */ reg-3v3-sensor { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-sensor"; enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; @@ -96,8 +88,6 @@ /* This regulator controls VDD_3V3_SPEKTRUM onboard supply */ reg-3v3-spektrum { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-3v3-spektrum"; enable-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; @@ -107,8 +97,6 @@ /* This regulator controls ETH_VDD_3V3 supply to power up the TJA1103 PHY */ reg-eth-power { - pinctrl-0 = <&pinmux_sensor>; - pinctrl-names = "default"; compatible = "regulator-fixed"; regulator-name = "reg-eth-power"; enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; From 73b803ab4b50847f3865f3da1b175b07038a9f62 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 26 Sep 2023 15:09:56 +0200 Subject: [PATCH 1130/4498] edtlib: pinctrl properties are required in the binding Consumers need to include `pinctrl-device.yaml` where this is defined. Signed-off-by: Gerard Marull-Paretas --- scripts/dts/python-devicetree/src/devicetree/edtlib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 502f5a7e1a5..b52a516d454 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -1551,7 +1551,6 @@ def _check_undeclared_props(self) -> None: # Allow a few special properties to not be declared in the binding if prop_name.endswith("-controller") or \ prop_name.startswith("#") or \ - prop_name.startswith("pinctrl-") or \ prop_name in { "compatible", "status", "ranges", "phandle", "interrupt-parent", "interrupts-extended", "device_type"}: From cf6bb282e2bf2343108aba0d8f2809c0ec0856db Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 14 Sep 2023 13:09:33 +0000 Subject: [PATCH 1131/4498] scripts: set_assignee: set reviewers for modules Add support for setting reviewers as well for module PRs, in addition to the assignees. Note that this still only works on repositories with an assignee on record since it does not seem to be possible to query for PRs that have no reviewers. Signed-off-by: Fabio Baltieri --- scripts/set_assignees.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/set_assignees.py b/scripts/set_assignees.py index 2a4575eb3c4..fb1987cd9b9 100755 --- a/scripts/set_assignees.py +++ b/scripts/set_assignees.py @@ -286,7 +286,10 @@ def process_modules(gh, maintainers_file): log(f"No maintainers for: {area}") continue - log(f"Found {area}, maintainers={maintainers}") + collaborators = maintainers_file.areas[area].collaborators + + log(f"Found {area}, maintainers={maintainers}, collaborators={collaborators}") + repo_name = f"{args.org}/{project.name}" repos[repo_name] = maintainers_file.areas[area] @@ -309,9 +312,15 @@ def process_modules(gh, maintainers_file): area = repos[repo_name] for maintainer in area.maintainers: - log(f"Adding {maintainer} to {pull.html_url}") + log(f"Assigning {maintainer} to {pull.html_url}") if not args.dry_run: pull.add_to_assignees(maintainer) + pull.create_review_request(maintainer) + + for collaborator in area.collaborators: + log(f"Adding {collaborator} to {pull.html_url}") + if not args.dry_run: + pull.create_review_request(collaborator) def main(): From ae336f69c35fd56100886ff522636718fa7c849f Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Wed, 27 Sep 2023 13:31:59 +0200 Subject: [PATCH 1132/4498] tests: mcuboot: pytest: Add image swap test with mcumgr Added application based on SMP Server Sample. Application is built together with MCUboot using sysbuild and is flashed onto device in one step. Tests are automated with pytest - new harness of Twister. The image for upgrade is prepared using west sign command then is uploaded by mcumgr into device and tested. Automated scenarios to test upgrade (image upload, test, revert, confirm), to test downgrade prevention mechanism and to test upgrade with image, that is signed with an invalid key. Signed-off-by: Grzegorz Chwierut --- .../src/twister_harness/helpers/shell.py | 51 +++++ .../shell_mcuboot_command_parser_test.py | 56 +++++ tests/boot/with_mcumgr/CMakeLists.txt | 9 + tests/boot/with_mcumgr/README.rst | 30 +++ tests/boot/with_mcumgr/prj.conf | 22 ++ .../pytest/test_downgrade_prevention.py | 62 ++++++ tests/boot/with_mcumgr/pytest/test_upgrade.py | 204 ++++++++++++++++++ tests/boot/with_mcumgr/pytest/utils.py | 50 +++++ .../with_mcumgr/pytest/west_sign_wrapper.py | 45 ++++ tests/boot/with_mcumgr/src/main.c | 14 ++ tests/boot/with_mcumgr/sysbuild.conf | 1 + tests/boot/with_mcumgr/sysbuild/mcuboot.conf | 1 + tests/boot/with_mcumgr/testcase.yaml | 34 +++ 13 files changed, 579 insertions(+) create mode 100644 scripts/pylib/pytest-twister-harness/tests/helpers/shell_mcuboot_command_parser_test.py create mode 100644 tests/boot/with_mcumgr/CMakeLists.txt create mode 100644 tests/boot/with_mcumgr/README.rst create mode 100644 tests/boot/with_mcumgr/prj.conf create mode 100755 tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py create mode 100755 tests/boot/with_mcumgr/pytest/test_upgrade.py create mode 100644 tests/boot/with_mcumgr/pytest/utils.py create mode 100644 tests/boot/with_mcumgr/pytest/west_sign_wrapper.py create mode 100644 tests/boot/with_mcumgr/src/main.c create mode 100644 tests/boot/with_mcumgr/sysbuild.conf create mode 100644 tests/boot/with_mcumgr/sysbuild/mcuboot.conf create mode 100644 tests/boot/with_mcumgr/testcase.yaml diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index 047d6029a6e..f6eb8074451 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -8,6 +8,9 @@ import re import time +from dataclasses import dataclass, field +from inspect import signature + from twister_harness.device.device_adapter import DeviceAdapter from twister_harness.exceptions import TwisterHarnessTimeoutException @@ -78,3 +81,51 @@ def get_filtered_output(self, command_lines: list[str]) -> list[str]: ]) ) return list(filter(lambda l: not regex_filter.search(l), command_lines)) + + +@dataclass +class ShellMCUbootArea: + name: str + version: str + image_size: str + magic: str = 'unset' + swap_type: str = 'none' + copy_done: str = 'unset' + image_ok: str = 'unset' + + @classmethod + def from_kwargs(cls, **kwargs) -> ShellMCUbootArea: + cls_fields = {field for field in signature(cls).parameters} + native_args = {} + for name, val in kwargs.items(): + if name in cls_fields: + native_args[name] = val + return cls(**native_args) + + +@dataclass +class ShellMCUbootCommandParsed: + """ + Helper class to keep data from `mcuboot` shell command. + """ + areas: list[ShellMCUbootArea] = field(default_factory=list) + + @classmethod + def create_from_cmd_output(cls, cmd_output: list[str]) -> ShellMCUbootCommandParsed: + """ + Factory to create class from the output of `mcuboot` shell command. + """ + areas: list[dict] = [] + re_area = re.compile(r'(.+ area.*):\s*$') + re_key = re.compile(r'(?P.+):(?P.+)') + for line in cmd_output: + if m := re_area.search(line): + areas.append({'name': m.group(1)}) + elif areas: + if m := re_key.search(line): + areas[-1][m.group('key').strip().replace(' ', '_')] = m.group('val').strip() + data_areas: list[ShellMCUbootArea] = [] + for area in areas: + data_areas.append(ShellMCUbootArea.from_kwargs(**area)) + + return cls(data_areas) diff --git a/scripts/pylib/pytest-twister-harness/tests/helpers/shell_mcuboot_command_parser_test.py b/scripts/pylib/pytest-twister-harness/tests/helpers/shell_mcuboot_command_parser_test.py new file mode 100644 index 00000000000..c6ebf46c2c2 --- /dev/null +++ b/scripts/pylib/pytest-twister-harness/tests/helpers/shell_mcuboot_command_parser_test.py @@ -0,0 +1,56 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import textwrap + +from twister_harness.helpers.shell import ShellMCUbootCommandParsed, ShellMCUbootArea + + +def test_if_mcuboot_command_output_is_parsed_two_areas() -> None: + cmd_output = textwrap.dedent(""" + \x1b[1;32muart:~$ \x1b[mmcuboot + swap type: revert + confirmed: 0 + primary area (1): + version: 0.0.2+0 + image size: 68240 + magic: good + swap type: test + copy done: set + image ok: unset + secondary area (3): + version: 0.0.0+0 + image size: 68240 + magic: unset + swap type: none + copy done: unset + image ok: unset + \x1b[1;32muart:~$ \x1b[m + """) + mcuboot_parsed = ShellMCUbootCommandParsed.create_from_cmd_output(cmd_output.splitlines()) + assert isinstance(mcuboot_parsed, ShellMCUbootCommandParsed) + assert isinstance(mcuboot_parsed.areas[0], ShellMCUbootArea) + assert len(mcuboot_parsed.areas) == 2 + assert mcuboot_parsed.areas[0].version == '0.0.2+0' + assert mcuboot_parsed.areas[0].swap_type == 'test' + + +def test_if_mcuboot_command_output_is_parsed_with_failed_area() -> None: + cmd_output = textwrap.dedent(""" + \x1b[1;32muart:~$ \x1b[mmcuboot + swap type: revert + confirmed: 0 + primary area (1): + version: 1.1.1+1 + image size: 68240 + magic: good + swap type: test + copy done: set + image ok: unset + failed to read secondary area (1) header: -5 + \x1b[1;32muart:~$ \x1b[m + """) + mcuboot_parsed = ShellMCUbootCommandParsed.create_from_cmd_output(cmd_output.splitlines()) + assert len(mcuboot_parsed.areas) == 1 + assert mcuboot_parsed.areas[0].version == '1.1.1+1' diff --git a/tests/boot/with_mcumgr/CMakeLists.txt b/tests/boot/with_mcumgr/CMakeLists.txt new file mode 100644 index 00000000000..640c52434a4 --- /dev/null +++ b/tests/boot/with_mcumgr/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(with_mcumgr) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/boot/with_mcumgr/README.rst b/tests/boot/with_mcumgr/README.rst new file mode 100644 index 00000000000..5f0ef82d30a --- /dev/null +++ b/tests/boot/with_mcumgr/README.rst @@ -0,0 +1,30 @@ +Upgrade testing with MCUmgr +########################### + +This application is based on :ref:`smp_svr_sample`. It is built +using **sysbuild**. Tests are automated with pytest, a new harness of Twister +(more information can be found here :ref:`integration-with-pytest`) + +.. note:: + Pytest uses the MCUmgr fixture which requires the ``mcumgr`` available + in the system PATH. + More information about MCUmgr can be found here :ref:`mcu_mgr`. + +To run tests with Twister on ``nrf52840dk_nrf52840`` platform, +use following command: + +.. code-block:: console + + ./zephyr/scripts/twister -vv --west-flash --enable-slow -T zephyr/tests/boot/with_mcumgr \ + -p nrf52840dk_nrf52840 --device-testing --device-serial /dev/ttyACM0 + +.. note:: + Twister requires ``--west-flash`` flag enabled (without additional parameters + like ``erase``) to use sysbuild. + +Test scripts can be found in ``pytest`` directory. To list available +scenarios with described procedures, one can use a pytest command: + +.. code-block:: console + + pytest zephyr/tests/boot/with_mcumgr/pytest --collect-only -v diff --git a/tests/boot/with_mcumgr/prj.conf b/tests/boot/with_mcumgr/prj.conf new file mode 100644 index 00000000000..5d09b05144a --- /dev/null +++ b/tests/boot/with_mcumgr/prj.conf @@ -0,0 +1,22 @@ +# Enable MCUmgr and dependencies. +CONFIG_NET_BUF=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +CONFIG_MCUMGR=y +CONFIG_STREAM_FLASH=y +CONFIG_FLASH_MAP=y + +# Enable the shell MCUmgr transport. +CONFIG_BASE64=y +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_MCUMGR_TRANSPORT_SHELL=y + +# Enable most core commands. +CONFIG_FLASH=y +CONFIG_IMG_MANAGER=y +CONFIG_MCUMGR_GRP_IMG=y +CONFIG_MCUMGR_GRP_OS=y + +# mcumgr-cli application doesn't accepts log in the channel it uses +CONFIG_SHELL_LOG_BACKEND=n diff --git a/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py b/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py new file mode 100755 index 00000000000..a4439c26fba --- /dev/null +++ b/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py @@ -0,0 +1,62 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import logging + +from pathlib import Path +from twister_harness import DeviceAdapter, Shell, MCUmgr +from utils import ( + find_in_config, + match_lines, + match_no_lines, + check_with_shell_command, + check_with_mcumgr_command, +) +from test_upgrade import create_signed_image, PROJECT_NAME + + +logger = logging.getLogger(__name__) + + +def test_downgrade_prevention(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): + """ + Verify that the application is not downgraded + 1) Device flashed with MCUboot and an application that contains SMP server. + Image version is 1.1.1+1 + 2) Prepare an update of an application containing the SMP server, where + image version is 0.0.0 (lower than version of the original app) + 3) Upload the application update to slot 1 using mcumgr + 4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test' + 5) Restart the device, verify that downgrade prevention mechanism + blocked the image swap + 6) Verify that the original application is booted (version 1.1.1) + """ + origin_version = find_in_config( + Path(dut.device_config.build_dir) / PROJECT_NAME / 'zephyr' / '.config', + 'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION' + ) + check_with_shell_command(shell, origin_version) + assert origin_version != '0.0.0+0' + + logger.info('Prepare upgrade image with lower version') + image_to_test = create_signed_image(dut.device_config.build_dir, '0.0.0+0') + + logger.info('Upload image with mcumgr') + dut.disconnect() + mcumgr.image_upload(image_to_test) + + logger.info('Test uploaded APP image') + second_hash = mcumgr.get_hash_to_test() + mcumgr.image_test(second_hash) + mcumgr.reset_device() + + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_no_lines(output, ['Starting swap using move algorithm']) + match_lines(output, ['erased due to downgrade prevention']) + logger.info('Verify that the original APP is booted') + check_with_shell_command(shell, origin_version) + dut.disconnect() + check_with_mcumgr_command(mcumgr, origin_version) diff --git a/tests/boot/with_mcumgr/pytest/test_upgrade.py b/tests/boot/with_mcumgr/pytest/test_upgrade.py new file mode 100755 index 00000000000..7772bd197ee --- /dev/null +++ b/tests/boot/with_mcumgr/pytest/test_upgrade.py @@ -0,0 +1,204 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import pytest +import logging + +from pathlib import Path +from twister_harness import DeviceAdapter, Shell, MCUmgr +from west_sign_wrapper import west_sign_with_imgtool +from utils import ( + find_in_config, + match_lines, + match_no_lines, + check_with_shell_command, + check_with_mcumgr_command, +) + +logger = logging.getLogger(__name__) +PROJECT_NAME = 'with_mcumgr' + + +def create_signed_image(build_dir: Path, version: str) -> Path: + image_to_test = Path(build_dir) / 'test_{}.signed.bin'.format( + version.replace('.', '_').replace('+', '_')) + origin_key_file = find_in_config( + Path(build_dir) / 'mcuboot' / 'zephyr' / '.config', + 'CONFIG_BOOT_SIGNATURE_KEY_FILE' + ) + west_sign_with_imgtool( + build_dir=Path(build_dir) / PROJECT_NAME, + output_bin=image_to_test, + key_file=Path(origin_key_file), + version=version + ) + assert image_to_test.is_file() + return image_to_test + + +def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): + """ + Verify that the application can be updated + 1) Device flashed with MCUboot and an application that contains SMP server + 2) Prepare an update of an application containing the SMP server + 3) Upload the application update to slot 1 using mcumgr + 4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test' + 5) Restart the device, verify that swapping process is initiated + 6) Verify that the updated application is booted + 7) Confirm the image using mcumgr + 8) Restart the device, and verify that the new application is still booted + """ + origin_version = find_in_config( + Path(dut.device_config.build_dir) / PROJECT_NAME / 'zephyr' / '.config', + 'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION' + ) + check_with_shell_command(shell, origin_version) + + logger.info('Prepare upgrade image') + new_version = '0.0.2+0' + image_to_test = create_signed_image(dut.device_config.build_dir, new_version) + + logger.info('Upload image with mcumgr') + dut.disconnect() + mcumgr.image_upload(image_to_test) + + logger.info('Test uploaded APP image') + second_hash = mcumgr.get_hash_to_test() + mcumgr.image_test(second_hash) + mcumgr.reset_device() + + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_lines(output, [ + 'Swap type: test', + 'Starting swap using move algorithm' + ]) + logger.info('Verify new APP is booted') + check_with_shell_command(shell, new_version, swap_type='test') + dut.disconnect() + check_with_mcumgr_command(mcumgr, new_version) + + logger.info('Confirm the image') + mcumgr.image_confirm(second_hash) + mcumgr.reset_device() + + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_no_lines(output, [ + 'Starting swap using move algorithm' + ]) + logger.info('Verify new APP is still booted') + check_with_shell_command(shell, new_version) + + +def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): + """ + Verify that MCUboot will roll back an image that is not confirmed + 1) Device flashed with MCUboot and an application that contains SMP server + 2) Prepare an update of an application containing the SMP server + 3) Upload the application update to slot 1 using mcumgr + 4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test' + 5) Restart the device, verify that swapping process is initiated + 6) Verify that the updated application is booted + 7) Reset the device without confirming the image + 8) Verify that MCUboot reverts update + """ + origin_version = find_in_config( + Path(dut.device_config.build_dir) / PROJECT_NAME / 'zephyr' / '.config', + 'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION' + ) + check_with_shell_command(shell, origin_version) + + logger.info('Prepare upgrade image') + new_version = '0.0.3+0' + image_to_test = create_signed_image(dut.device_config.build_dir, new_version) + + logger.info('Upload image with mcumgr') + dut.disconnect() + mcumgr.image_upload(image_to_test) + + logger.info('Test uploaded APP image') + second_hash = mcumgr.get_hash_to_test() + mcumgr.image_test(second_hash) + mcumgr.reset_device() + + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_lines(output, [ + 'Swap type: test', + 'Starting swap using move algorithm' + ]) + logger.info('Verify new APP is booted') + check_with_shell_command(shell, new_version, swap_type='test') + dut.disconnect() + check_with_mcumgr_command(mcumgr, new_version) + + logger.info('Revert images') + mcumgr.reset_device() + + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_lines(output, [ + 'Swap type: revert', + 'Starting swap using move algorithm' + ]) + logger.info('Verify that MCUboot reverts update') + check_with_shell_command(shell, origin_version) + + +@pytest.mark.parametrize( + 'key_file', [None, 'root-ec-p256.pem'], + ids=[ + 'no_key', + 'invalid_key' + ]) +def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key_file): + """ + Verify that the application is not updated when app is not signed or signed with invalid key + 1) Device flashed with MCUboot and an application that contains SMP server + 2) Prepare an update of an application containing the SMP server that has + been signed: + a) without any key + b) with a different key than MCUboot was compiled with + 3) Upload the application update to slot 1 using mcumgr + 4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test' + 5) Restart the device, verify that swap is not started + """ + if key_file: + origin_key_file = find_in_config( + Path(dut.device_config.build_dir) / 'mcuboot' / 'zephyr' / '.config', + 'CONFIG_BOOT_SIGNATURE_KEY_FILE' + ).strip('"\'') + key_file = Path(origin_key_file).parent / key_file + assert key_file.is_file() + assert not key_file.samefile(origin_key_file) + image_to_test = image_to_test = Path(dut.device_config.build_dir) / 'test_invalid_key.bin' + logger.info('Sign second image with an invalid key') + else: + image_to_test = image_to_test = Path(dut.device_config.build_dir) / 'test_no_key.bin' + logger.info('Sign second imagewith no key') + + west_sign_with_imgtool( + build_dir=Path(dut.device_config.build_dir) / PROJECT_NAME, + output_bin=image_to_test, + key_file=key_file, + version='0.0.3+4' # must differ from the origin version, if not then hash is not updated + ) + assert image_to_test.is_file() + + logger.info('Upload image with mcumgr') + dut.disconnect() + mcumgr.image_upload(image_to_test) + + logger.info('Test uploaded APP image') + second_hash = mcumgr.get_hash_to_test() + mcumgr.image_test(second_hash) + mcumgr.reset_device() + + logger.info('Verify that swap is not started') + dut.connect() + output = dut.readlines_until('Launching primary slot application') + match_no_lines(output, ['Starting swap using move algorithm']) + match_lines(output, ['Image in the secondary slot is not valid']) diff --git a/tests/boot/with_mcumgr/pytest/utils.py b/tests/boot/with_mcumgr/pytest/utils.py new file mode 100644 index 00000000000..208bd92d166 --- /dev/null +++ b/tests/boot/with_mcumgr/pytest/utils.py @@ -0,0 +1,50 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import logging +import re + +from pathlib import Path +from twister_harness import Shell, MCUmgr +from twister_harness.helpers.shell import ShellMCUbootCommandParsed + + +logger = logging.getLogger(__name__) + + +def find_in_config(config_file: Path | str, config_key: str) -> str: + re_key = re.compile(rf'{config_key}=(.+)') + with open(config_file) as f: + lines = f.readlines() + for line in lines: + if m := re_key.match(line): + logger.debug('Found matching key: %s' % line.strip()) + return m.group(1).strip('"\'') + return '' + + +def match_lines(output_lines: list[str], searched_lines: list[str]) -> None: + """Check all lines exist in the output""" + for sl in searched_lines: + assert any(sl in line for line in output_lines) + + +def match_no_lines(output_lines: list[str], searched_lines: list[str]) -> None: + """Check lines not found in the output""" + for sl in searched_lines: + assert all(sl not in line for line in output_lines) + + +def check_with_shell_command(shell: Shell, version: str, swap_type: str | None = None) -> None: + mcuboot_areas = ShellMCUbootCommandParsed.create_from_cmd_output(shell.exec_command('mcuboot')) + assert mcuboot_areas.areas[0].version == version + if swap_type: + assert mcuboot_areas.areas[0].swap_type == swap_type + + +def check_with_mcumgr_command(mcumgr: MCUmgr, version: str) -> None: + image_list = mcumgr.get_image_list() + # version displayed by MCUmgr does not print +0 and changes + to '.' for non-zero values + assert image_list[0].version == version.replace('+0', '').replace('+', '.') diff --git a/tests/boot/with_mcumgr/pytest/west_sign_wrapper.py b/tests/boot/with_mcumgr/pytest/west_sign_wrapper.py new file mode 100644 index 00000000000..daabac6c32e --- /dev/null +++ b/tests/boot/with_mcumgr/pytest/west_sign_wrapper.py @@ -0,0 +1,45 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import logging +import shlex + +from subprocess import check_output +from pathlib import Path + + +logger = logging.getLogger(__name__) + + +def west_sign_with_imgtool( + build_dir: Path, + output_bin: Path | None = None, + key_file: Path | None = None, + version: str | None = None, + timeout: int = 10 +): + """Wrapper method for `west sign -t imgtool` comamnd""" + command = [ + 'west', 'sign', + '-t', 'imgtool', + '--no-hex', + '--build-dir', str(build_dir) + ] + if output_bin: + command.extend(['--sbin', str(output_bin)]) + + command_extra_args = [] + if key_file: + command_extra_args.extend(['--key', str(key_file)]) + if version: + command_extra_args.extend(['--version', version]) + + if command_extra_args: + command.append('--') + command.extend(command_extra_args) + + logger.info(f"CMD: {shlex.join(command)}") + output = check_output(command, text=True, timeout=timeout) + logger.debug('OUT: %s' % output) diff --git a/tests/boot/with_mcumgr/src/main.c b/tests/boot/with_mcumgr/src/main.c new file mode 100644 index 00000000000..ac05fd8ff51 --- /dev/null +++ b/tests/boot/with_mcumgr/src/main.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Main entry point */ +int main(void) +{ + printk("Launching primary slot application on %s\n", CONFIG_BOARD); + return 0; +} diff --git a/tests/boot/with_mcumgr/sysbuild.conf b/tests/boot/with_mcumgr/sysbuild.conf new file mode 100644 index 00000000000..47f00ff3cff --- /dev/null +++ b/tests/boot/with_mcumgr/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_BOOTLOADER_MCUBOOT=y diff --git a/tests/boot/with_mcumgr/sysbuild/mcuboot.conf b/tests/boot/with_mcumgr/sysbuild/mcuboot.conf new file mode 100644 index 00000000000..69938a0f972 --- /dev/null +++ b/tests/boot/with_mcumgr/sysbuild/mcuboot.conf @@ -0,0 +1 @@ +CONFIG_MCUBOOT_LOG_LEVEL_INF=y diff --git a/tests/boot/with_mcumgr/testcase.yaml b/tests/boot/with_mcumgr/testcase.yaml new file mode 100644 index 00000000000..08904c177bd --- /dev/null +++ b/tests/boot/with_mcumgr/testcase.yaml @@ -0,0 +1,34 @@ +common: + sysbuild: true + platform_allow: + - nrf52840dk_nrf52840 + - nrf5340dk_nrf5340_cpuapp + - nrf9160dk_nrf9160 + integration_platforms: + - nrf52840dk_nrf52840 + timeout: 600 + slow: true +tests: + boot.with_mcumgr.test_upgrade: + tags: + - pytest + - mcuboot + - mcumgr + harness: pytest + harness_config: + pytest_root: + - "pytest/test_upgrade.py" + + boot.with_mcumgr.test_downgrade_prevention: + tags: + - pytest + - mcuboot + - mcumgr + harness: pytest + harness_config: + pytest_root: + - "pytest/test_downgrade_prevention.py" + extra_args: + - mcuboot_CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y + extra_configs: + - CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="1.1.1+1" From a5384bbf1ab6872918fffb25e4fb800550c84f58 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 17 Aug 2023 13:15:12 +0200 Subject: [PATCH 1133/4498] tests: Bluetooth: BAP: Initial Broadcast reconfigure test Add a simple initial test for the reconfigure unittest. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index fbf32ed146a..c00cf2c1cf3 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -162,6 +162,7 @@ ZTEST_SUITE(bap_broadcast_source_test_suite, NULL, bap_broadcast_source_test_sui ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) { struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_stream *stream = create_param->params[0].params[0].stream; int err; printk("Creating broadcast source with %zu subgroups with %zu streams\n", @@ -170,6 +171,10 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) err = bt_bap_broadcast_source_create(create_param, &fixture->source); zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + zassert_equal(create_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); + zassert_equal(create_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); + zassert_equal(create_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); + err = bt_bap_broadcast_source_delete(fixture->source); zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); fixture->source = NULL; @@ -268,3 +273,35 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_doubl err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); zassert_not_equal(0, err, "Did not fail with starting already started source"); } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure) +{ + struct bt_bap_broadcast_source_param *reconf_param = fixture->param; + struct bt_bap_stream *stream = reconf_param->params[0].params[0].stream; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + reconf_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(reconf_param, &fixture->source); + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); + + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + reconf_param->qos->sdu = 100U; + reconf_param->qos->rtn = 3U; + reconf_param->qos->phy = 1U; + + err = bt_bap_broadcast_source_reconfig(fixture->source, reconf_param); + zassert_equal(0, err, "Unable to reconfigure broadcast source: err %d", err); + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} From 42ce4bbfd76535765c1837734f39aff805714815 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 8 Aug 2023 13:28:11 +0300 Subject: [PATCH 1134/4498] net: lwm2m: Allow content formats to support only some data types Partial content format support is required to have a proper support for content format OPAQUE instead of threading it as a part of plain text format. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_object.h | 143 ++++++++++++++++++---------- 1 file changed, 91 insertions(+), 52 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index ca8fdf12fd0..05bc818c99c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -705,71 +705,95 @@ static inline int engine_put_end_ri(struct lwm2m_output_context *out, return 0; } -static inline int engine_put_s8(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, int8_t value) +static inline int engine_put_s8(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + int8_t value) { - return out->writer->put_s8(out, path, value); + if (out->writer->put_s8) { + return out->writer->put_s8(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_s16(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, int16_t value) +static inline int engine_put_s16(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + int16_t value) { - return out->writer->put_s16(out, path, value); + if (out->writer->put_s16) { + return out->writer->put_s16(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_s32(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, int32_t value) +static inline int engine_put_s32(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + int32_t value) { - return out->writer->put_s32(out, path, value); + if (out->writer->put_s32) { + return out->writer->put_s32(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_s64(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, int64_t value) +static inline int engine_put_s64(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + int64_t value) { - return out->writer->put_s64(out, path, value); + if (out->writer->put_s64) { + return out->writer->put_s64(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_string(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, char *buf, - size_t buflen) +static inline int engine_put_string(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + char *buf, size_t buflen) { - return out->writer->put_string(out, path, buf, buflen); + if (out->writer->put_string) { + return out->writer->put_string(out, path, buf, buflen); + } + return -ENOTSUP; } -static inline int engine_put_float(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, double *value) +static inline int engine_put_float(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + double *value) { - return out->writer->put_float(out, path, value); + if (out->writer->put_float) { + return out->writer->put_float(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_time(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, time_t value) +static inline int engine_put_time(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + time_t value) { - return out->writer->put_time(out, path, value); + if (out->writer->put_time) { + return out->writer->put_time(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_bool(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, bool value) +static inline int engine_put_bool(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + bool value) { - return out->writer->put_bool(out, path, value); + if (out->writer->put_bool) { + return out->writer->put_bool(out, path, value); + } + return -ENOTSUP; } -static inline int engine_put_opaque(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, char *buf, - size_t buflen) +static inline int engine_put_opaque(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, + char *buf, size_t buflen) { if (out->writer->put_opaque) { return out->writer->put_opaque(out, path, buf, buflen); } - return 0; + return -ENOTSUP; } -static inline int engine_put_objlnk(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, +static inline int engine_put_objlnk(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, struct lwm2m_objlnk *value) { - return out->writer->put_objlnk(out, path, value); + if (out->writer->put_objlnk) { + return out->writer->put_objlnk(out, path, value); + } + return -ENOTSUP; } static inline int engine_put_corelink(struct lwm2m_output_context *out, @@ -793,53 +817,68 @@ static inline int engine_put_timestamp(struct lwm2m_output_context *out, time_t static inline int engine_get_s32(struct lwm2m_input_context *in, int32_t *value) { - return in->reader->get_s32(in, value); + if (in->reader->get_s32) { + return in->reader->get_s32(in, value); + } + return -ENOTSUP; } static inline int engine_get_s64(struct lwm2m_input_context *in, int64_t *value) { - return in->reader->get_s64(in, value); + if (in->reader->get_s64) { + return in->reader->get_s64(in, value); + } + return -ENOTSUP; } -static inline int engine_get_string(struct lwm2m_input_context *in, - uint8_t *buf, size_t buflen) +static inline int engine_get_string(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen) { - return in->reader->get_string(in, buf, buflen); + if (in->reader->get_string) { + return in->reader->get_string(in, buf, buflen); + } + return -ENOTSUP; } static inline int engine_get_time(struct lwm2m_input_context *in, time_t *value) { - return in->reader->get_time(in, value); + if (in->reader->get_time) { + return in->reader->get_time(in, value); + } + return -ENOTSUP; } -static inline int engine_get_float(struct lwm2m_input_context *in, - double *value) +static inline int engine_get_float(struct lwm2m_input_context *in, double *value) { - return in->reader->get_float(in, value); + if (in->reader->get_float) { + return in->reader->get_float(in, value); + } + return -ENOTSUP; } static inline int engine_get_bool(struct lwm2m_input_context *in, bool *value) { - return in->reader->get_bool(in, value); + if (in->reader->get_bool) { + return in->reader->get_bool(in, value); + } + return -ENOTSUP; } -static inline int engine_get_opaque(struct lwm2m_input_context *in, - uint8_t *buf, size_t buflen, - struct lwm2m_opaque_context *opaque, - bool *last_block) +static inline int engine_get_opaque(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen, + struct lwm2m_opaque_context *opaque, bool *last_block) { if (in->reader->get_opaque) { - return in->reader->get_opaque(in, buf, buflen, - opaque, last_block); + return in->reader->get_opaque(in, buf, buflen, opaque, last_block); } - return 0; + return -ENOTSUP; } -static inline int engine_get_objlnk(struct lwm2m_input_context *in, - struct lwm2m_objlnk *value) +static inline int engine_get_objlnk(struct lwm2m_input_context *in, struct lwm2m_objlnk *value) { - return in->reader->get_objlnk(in, value); + if (in->reader->get_objlnk) { + return in->reader->get_objlnk(in, value); + } + return -ENOTSUP; } #endif /* LWM2M_OBJECT_H_ */ From f227b5679221a57c85d0ad39ebb2024cb8590105 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 8 Aug 2023 13:31:40 +0300 Subject: [PATCH 1135/4498] net: lwm2m: Separate opaque content format into its own Opaque content format is not part of clear-text, so it should be separated into its own file. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/CMakeLists.txt | 1 + subsys/net/lib/lwm2m/lwm2m_message_handling.c | 12 ++ subsys/net/lib/lwm2m/lwm2m_rw_opaque.c | 165 ++++++++++++++++++ subsys/net/lib/lwm2m/lwm2m_rw_opaque.h | 18 ++ subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c | 44 ----- .../lib/lwm2m/content_plain_text/src/main.c | 31 ---- 6 files changed, 196 insertions(+), 75 deletions(-) create mode 100644 subsys/net/lib/lwm2m/lwm2m_rw_opaque.c create mode 100644 subsys/net/lib/lwm2m/lwm2m_rw_opaque.h diff --git a/subsys/net/lib/lwm2m/CMakeLists.txt b/subsys/net/lib/lwm2m/CMakeLists.txt index 5cb0ab158d5..2e895ec381b 100644 --- a/subsys/net/lib/lwm2m/CMakeLists.txt +++ b/subsys/net/lib/lwm2m/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources( lwm2m_obj_device.c lwm2m_rw_link_format.c lwm2m_rw_plain_text.c + lwm2m_rw_opaque.c lwm2m_util.c lwm2m_rd_client.c ) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 1a7d023ceb2..8b18f918752 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -47,6 +47,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_rw_link_format.h" #include "lwm2m_rw_oma_tlv.h" #include "lwm2m_rw_plain_text.h" +#include "lwm2m_rw_opaque.h" #include "lwm2m_util.h" #include "lwm2m_rd_client.h" #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) @@ -807,6 +808,10 @@ static int select_writer(struct lwm2m_output_context *out, uint16_t accept) out->writer = &link_format_writer; break; + case LWM2M_FORMAT_APP_OCTET_STREAM: + out->writer = &opaque_writer; + break; + case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: out->writer = &plain_text_writer; @@ -857,6 +862,9 @@ static int select_reader(struct lwm2m_input_context *in, uint16_t format) switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: + in->reader = &opaque_reader; + break; + case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: in->reader = &plain_text_reader; @@ -1537,6 +1545,8 @@ static int do_read_op(struct lwm2m_message *msg, uint16_t content_format) switch (content_format) { case LWM2M_FORMAT_APP_OCTET_STREAM: + return do_read_op_opaque(msg, content_format); + case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: return do_read_op_plain_text(msg, content_format); @@ -1919,6 +1929,8 @@ static int do_write_op(struct lwm2m_message *msg, uint16_t format) switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: + return do_write_op_opaque(msg); + case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: return do_write_op_plain_text(msg); diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c new file mode 100644 index 00000000000..90cb4619d9a --- /dev/null +++ b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LOG_MODULE_NAME net_lwm2m_opaque +#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include +#include +#include +#include +#include + +#include "lwm2m_object.h" +#include "lwm2m_rw_opaque.h" +#include "lwm2m_engine.h" +#include "lwm2m_util.h" + +static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, + size_t buflen, struct lwm2m_opaque_context *opaque, + bool *last_block) +{ + uint16_t in_len; + + if (opaque->remaining == 0) { + coap_packet_get_payload(in->in_cpkt, &in_len); + + if (in_len == 0) { + return -ENODATA; + } + + if (in->block_ctx != NULL) { + uint32_t block_num = + in->block_ctx->ctx.current / + coap_block_size_to_bytes( + in->block_ctx->ctx.block_size); + + if (block_num == 0) { + opaque->len = in->block_ctx->ctx.total_size; + } + + if (opaque->len == 0) { + /* No size1 option provided, use current + * payload size. This will reset on next packet + * received. + */ + opaque->remaining = in_len; + } else { + opaque->remaining = opaque->len; + } + + } else { + opaque->len = in_len; + opaque->remaining = in_len; + } + } + + return lwm2m_engine_get_opaque_more(in, value, buflen, + opaque, last_block); +} + +static int put_opaque(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, char *buf, + size_t buflen) +{ + int ret; + + ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), buf, buflen); + if (ret < 0) { + return ret; + } + + return buflen; +} + + +const struct lwm2m_writer opaque_writer = { + .put_opaque = put_opaque, +}; + +const struct lwm2m_reader opaque_reader = { + .get_opaque = get_opaque, +}; + +int do_read_op_opaque(struct lwm2m_message *msg, int content_format) +{ + /* Opaque can only return single resource (instance) */ + if (msg->path.level < LWM2M_PATH_LEVEL_RESOURCE) { + return -EPERM; + } else if (msg->path.level > LWM2M_PATH_LEVEL_RESOURCE) { + if (!IS_ENABLED(CONFIG_LWM2M_VERSION_1_1)) { + return -ENOENT; + } else if (msg->path.level > LWM2M_PATH_LEVEL_RESOURCE_INST) { + return -ENOENT; + } + } + + return lwm2m_perform_read_op(msg, content_format); +} + +int do_write_op_opaque(struct lwm2m_message *msg) +{ + struct lwm2m_engine_obj_inst *obj_inst = NULL; + struct lwm2m_engine_obj_field *obj_field; + struct lwm2m_engine_res *res = NULL; + struct lwm2m_engine_res_inst *res_inst = NULL; + int ret; + uint8_t created = 0U; + + ret = lwm2m_get_or_create_engine_obj(msg, &obj_inst, &created); + if (ret < 0) { + return ret; + } + + ret = lwm2m_engine_validate_write_access(msg, obj_inst, &obj_field); + if (ret < 0) { + return ret; + } + + ret = lwm2m_engine_get_create_res_inst(&msg->path, &res, &res_inst); + if (ret < 0) { + return -ENOENT; + } + + if (msg->path.level < LWM2M_PATH_LEVEL_RESOURCE) { + msg->path.level = LWM2M_PATH_LEVEL_RESOURCE; + } + + return lwm2m_write_handler(obj_inst, res, res_inst, obj_field, msg); +} diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h new file mode 100644 index 00000000000..4118049efe8 --- /dev/null +++ b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LWM2M_RW_OPAQUE_H_ +#define LWM2M_RW_OPAQUE_H_ + +#include "lwm2m_object.h" + +extern const struct lwm2m_writer opaque_writer; +extern const struct lwm2m_reader opaque_reader; + +int do_read_op_opaque(struct lwm2m_message *msg, int content_format); +int do_write_op_opaque(struct lwm2m_message *msg); + +#endif /* LWM2M_RW_OPAQUE_H_ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c index 9650b33fc29..3ec69e8db82 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c @@ -341,49 +341,6 @@ static int get_bool(struct lwm2m_input_context *in, bool *value) return sizeof(uint8_t); } -static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, - size_t buflen, struct lwm2m_opaque_context *opaque, - bool *last_block) -{ - uint16_t in_len; - - if (opaque->remaining == 0) { - coap_packet_get_payload(in->in_cpkt, &in_len); - - if (in_len == 0) { - return -ENODATA; - } - - if (in->block_ctx != NULL) { - uint32_t block_num = - in->block_ctx->ctx.current / - coap_block_size_to_bytes( - in->block_ctx->ctx.block_size); - - if (block_num == 0) { - opaque->len = in->block_ctx->ctx.total_size; - } - - if (opaque->len == 0) { - /* No size1 option provided, use current - * payload size. This will reset on next packet - * received. - */ - opaque->remaining = in_len; - } else { - opaque->remaining = opaque->len; - } - - } else { - opaque->len = in_len; - opaque->remaining = in_len; - } - } - - return lwm2m_engine_get_opaque_more(in, value, buflen, - opaque, last_block); -} - static int get_objlnk(struct lwm2m_input_context *in, struct lwm2m_objlnk *value) { @@ -432,7 +389,6 @@ const struct lwm2m_reader plain_text_reader = { .get_time = get_time, .get_float = get_float, .get_bool = get_bool, - .get_opaque = get_opaque, .get_objlnk = get_objlnk, }; diff --git a/tests/net/lib/lwm2m/content_plain_text/src/main.c b/tests/net/lib/lwm2m/content_plain_text/src/main.c index c7cc857224c..7bc77a82327 100644 --- a/tests/net/lib/lwm2m/content_plain_text/src/main.c +++ b/tests/net/lib/lwm2m/content_plain_text/src/main.c @@ -470,37 +470,6 @@ ZTEST(net_content_plain_text_nodata, test_get_bool_nodata) zassert_equal(ret, -ENODATA, "Invalid error code returned"); } -ZTEST(net_content_plain_text, test_get_opaque) -{ - int ret; - const char *payload = "test_payload"; - uint8_t buf[16]; - bool last_block; - struct lwm2m_opaque_context ctx = { 0 }; - - test_payload_set(payload); - - ret = plain_text_reader.get_opaque(&test_in, buf, sizeof(buf), - &ctx, &last_block); - zassert_equal(ret, strlen(payload), "Invalid length returned"); - zassert_mem_equal(buf, payload, strlen(payload), - "Invalid value parsed"); - zassert_equal(test_in.offset, strlen(payload) + 1, - "Invalid packet offset"); -} - -ZTEST(net_content_plain_text_nodata, test_get_opaque_nodata) -{ - int ret; - uint8_t value[4]; - bool last_block; - struct lwm2m_opaque_context ctx = { 0 }; - - ret = plain_text_reader.get_opaque(&test_in, value, sizeof(value), - &ctx, &last_block); - zassert_equal(ret, 0, "Invalid error code returned"); -} - ZTEST(net_content_plain_text, test_get_objlnk) { int ret; From 4e97607c27b5dfff3ab5d0ee7075ee6249c5174b Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 9 Aug 2023 15:34:23 +0300 Subject: [PATCH 1136/4498] net: lwm2m: Only parse block1 option for WRITE operation In reality, single-write is the only operation that handles BLOCK1 operations when receiving paylod. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 398 ++++++++++-------- 1 file changed, 213 insertions(+), 185 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 8b18f918752..299b0330c0b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -1926,50 +1926,179 @@ static int do_discover_op(struct lwm2m_message *msg, uint16_t content_format) static int do_write_op(struct lwm2m_message *msg, uint16_t format) { + int r; + switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: - return do_write_op_opaque(msg); + r = do_write_op_opaque(msg); + break; case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: - return do_write_op_plain_text(msg); + r = do_write_op_plain_text(msg); + break; #ifdef CONFIG_LWM2M_RW_OMA_TLV_SUPPORT case LWM2M_FORMAT_OMA_TLV: case LWM2M_FORMAT_OMA_OLD_TLV: - return do_write_op_tlv(msg); + r = do_write_op_tlv(msg); + break; #endif #ifdef CONFIG_LWM2M_RW_JSON_SUPPORT case LWM2M_FORMAT_OMA_JSON: case LWM2M_FORMAT_OMA_OLD_JSON: - return do_write_op_json(msg); + r = do_write_op_json(msg); + break; #endif #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) case LWM2M_FORMAT_APP_SEML_JSON: - return do_write_op_senml_json(msg); + r = do_write_op_senml_json(msg); + break; #endif #ifdef CONFIG_LWM2M_RW_CBOR_SUPPORT case LWM2M_FORMAT_APP_CBOR: - return do_write_op_cbor(msg); + r = do_write_op_cbor(msg); + break; #endif #ifdef CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT case LWM2M_FORMAT_APP_SENML_CBOR: - return do_write_op_senml_cbor(msg); + r = do_write_op_senml_cbor(msg); + break; #endif default: LOG_ERR("Unsupported format: %u", format); - return -ENOMSG; + r = -ENOMSG; + break; + } + + return r; +} + +static int parse_write_op(struct lwm2m_message *msg, uint16_t format) +{ + int block_opt, block_num; + struct lwm2m_block_context *block_ctx = NULL; + enum coap_block_size block_size; + bool last_block = false; + int r; + uint16_t payload_len = 0U; + const uint8_t *payload_start; + + /* setup incoming data */ + payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); + if (payload_len > 0) { + msg->in.offset = payload_start - msg->in.in_cpkt->data; + } else { + msg->in.offset = msg->in.in_cpkt->offset; + } + + /* Check for block transfer */ + block_opt = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1); + if (block_opt > 0) { + last_block = !GET_MORE(block_opt); + + /* RFC7252: 4.6. Message Size */ + block_size = GET_BLOCK_SIZE(block_opt); + if (!last_block && coap_block_size_to_bytes(block_size) > payload_len) { + LOG_DBG("Trailing payload is discarded!"); + return -EFBIG; + } + + block_num = GET_BLOCK_NUM(block_opt); + + /* Try to retrieve existing block context. If one not exists, + * and we've received first block, allocate new context. + */ + r = get_block_ctx(&msg->path, &block_ctx); + if (r < 0 && block_num == 0) { + r = init_block_ctx(&msg->path, &block_ctx); + } + + if (r < 0) { + LOG_ERR("Cannot find block context"); + return r; + } + + msg->in.block_ctx = block_ctx; + + if (block_num < block_ctx->expected) { + LOG_WRN("Block already handled %d, expected %d", block_num, + block_ctx->expected); + return 0; + } + if (block_num > block_ctx->expected) { + LOG_WRN("Block out of order %d, expected %d", block_num, + block_ctx->expected); + r = -EFAULT; + return r; + } + r = coap_update_from_block(msg->in.in_cpkt, &block_ctx->ctx); + if (r < 0) { + LOG_ERR("Error from block update: %d", r); + return r; + } + + block_ctx->last_block = last_block; + + /* Initial block sent by the server might be larger than + * our block size therefore it is needed to take this + * into account when calculating next expected block + * number. + */ + block_ctx->expected += GET_BLOCK_SIZE(block_opt) - block_ctx->ctx.block_size + 1; + + /* Handle blockwise 1 (Part 1): Set response code */ + if (!last_block) { + msg->code = COAP_RESPONSE_CODE_CONTINUE; + } + } + + r = do_write_op(msg, format); + + /* Handle blockwise 1 (Part 2): Append BLOCK1 option / free context */ + if (block_ctx) { + if (r >= 0 && !last_block) { + /* More to come, ack with correspond block # */ + r = coap_append_block1_option(msg->out.out_cpkt, &block_ctx->ctx); + if (r < 0) { + /* report as internal server error */ + LOG_ERR("Fail adding block1 option: %d", r); + r = -EINVAL; + } + } + if (r < 0 || last_block) { + /* Free context when finished or when there is error */ + free_block_ctx(block_ctx); + + } } + + return r; } static int do_composite_write_op(struct lwm2m_message *msg, uint16_t format) { + uint16_t payload_len = 0U; + const uint8_t *payload_start; + + /* setup incoming data */ + payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); + if (payload_len > 0) { + msg->in.offset = payload_start - msg->in.in_cpkt->data; + } else { + msg->in.offset = msg->in.in_cpkt->offset; + } + + if (coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1) >= 0) { + return -ENOTSUP; + } + switch (format) { #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) case LWM2M_FORMAT_APP_SEML_JSON: @@ -2074,13 +2203,6 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) uint8_t tkl = 0U; uint16_t format = LWM2M_FORMAT_NONE, accept; int observe = -1; /* default to -1, 0 = ENABLE, 1 = DISABLE */ - int block_opt, block_num; - struct lwm2m_block_context *block_ctx = NULL; - enum coap_block_size block_size; - uint16_t payload_len = 0U; - bool last_block = false; - bool ignore = false; - const uint8_t *payload_start; /* set CoAP request / message */ msg->in.in_cpkt = request; @@ -2252,202 +2374,111 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) break; } - /* setup incoming data */ - payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); - if (payload_len > 0) { - msg->in.offset = payload_start - msg->in.in_cpkt->data; - } else { - msg->in.offset = msg->in.in_cpkt->offset; - } - - /* Check for block transfer */ - - block_opt = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1); - if (block_opt > 0) { - last_block = !GET_MORE(block_opt); - - /* RFC7252: 4.6. Message Size */ - block_size = GET_BLOCK_SIZE(block_opt); - if (!last_block && coap_block_size_to_bytes(block_size) > payload_len) { - LOG_DBG("Trailing payload is discarded!"); - r = -EFBIG; - goto error; - } - - block_num = GET_BLOCK_NUM(block_opt); - - /* Try to retrieve existing block context. If one not exists, - * and we've received first block, allocate new context. - */ - r = get_block_ctx(&msg->path, &block_ctx); - if (r < 0 && block_num == 0) { - r = init_block_ctx(&msg->path, &block_ctx); - } - - if (r < 0) { - LOG_ERR("Cannot find block context"); - goto error; - } - - msg->in.block_ctx = block_ctx; - - if (block_num < block_ctx->expected) { - LOG_WRN("Block already handled %d, expected %d", block_num, - block_ctx->expected); - ignore = true; - } else if (block_num > block_ctx->expected) { - LOG_WRN("Block out of order %d, expected %d", block_num, - block_ctx->expected); - r = -EFAULT; - goto error; - } else { - r = coap_update_from_block(msg->in.in_cpkt, &block_ctx->ctx); - if (r < 0) { - LOG_ERR("Error from block update: %d", r); - goto error; - } - - block_ctx->last_block = last_block; - - /* Initial block sent by the server might be larger than - * our block size therefore it is needed to take this - * into account when calculating next expected block - * number. - */ - block_ctx->expected += - GET_BLOCK_SIZE(block_opt) - block_ctx->ctx.block_size + 1; - } - - /* Handle blockwise 1 (Part 1): Set response code */ - if (!last_block) { - msg->code = COAP_RESPONSE_CODE_CONTINUE; - } - } - /* render CoAP packet header */ r = lwm2m_init_message(msg); if (r < 0) { goto error; } - if (!ignore) { #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) - r = access_control_check_access(msg->path.obj_id, msg->path.obj_inst_id, - msg->ctx->srv_obj_inst, msg->operation, - msg->ctx->bootstrap_mode); - if (r < 0) { - LOG_ERR("Access denied - Server obj %u does not have proper access to " - "resource", - msg->ctx->srv_obj_inst); - goto error; - } + r = access_control_check_access(msg->path.obj_id, msg->path.obj_inst_id, + msg->ctx->srv_obj_inst, msg->operation, + msg->ctx->bootstrap_mode); + if (r < 0) { + LOG_ERR("Access denied - Server obj %u does not have proper access to " + "resource", + msg->ctx->srv_obj_inst); + goto error; + } #endif - if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { - r = -EACCES; - goto error; - } + if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { + r = -EACCES; + goto error; + } + + switch (msg->operation) { - switch (msg->operation) { + case LWM2M_OP_READ: + if (observe >= 0) { + /* Validate That Token is valid for Observation */ + if (!msg->token) { + LOG_ERR("OBSERVE request missing token"); + r = -EINVAL; + goto error; + } - case LWM2M_OP_READ: - if (observe >= 0) { - /* Validate That Token is valid for Observation */ - if (!msg->token) { - LOG_ERR("OBSERVE request missing token"); - r = -EINVAL; + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { + /* Normal Observation Request or Cancel */ + r = lwm2m_engine_observation_handler(msg, observe, accept, + false); + if (r < 0) { goto error; } - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { - /* Normal Observation Request or Cancel */ - r = lwm2m_engine_observation_handler(msg, observe, accept, - false); - if (r < 0) { - goto error; - } - - r = do_read_op(msg, accept); - } else { - /* Composite Observation request & cancel handler */ - r = lwm2m_engine_observation_handler(msg, observe, accept, - true); - if (r < 0) { - goto error; - } - } + r = do_read_op(msg, accept); } else { - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { - r = do_read_op(msg, accept); - } else { - r = do_composite_read_op(msg, accept); + /* Composite Observation request & cancel handler */ + r = lwm2m_engine_observation_handler(msg, observe, accept, + true); + if (r < 0) { + goto error; } } - break; - - case LWM2M_OP_DISCOVER: - r = do_discover_op(msg, accept); - break; - - case LWM2M_OP_WRITE: - case LWM2M_OP_CREATE: - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_IPATCH) { - /* iPATCH is for Composite purpose */ - r = do_composite_write_op(msg, format); + } else { + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { + r = do_read_op(msg, accept); } else { - /* Single resource write Operation */ - r = do_write_op(msg, format); + r = do_composite_read_op(msg, accept); } + } + break; + + case LWM2M_OP_DISCOVER: + r = do_discover_op(msg, accept); + break; + + case LWM2M_OP_WRITE: + case LWM2M_OP_CREATE: + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_IPATCH) { + /* iPATCH is for Composite purpose */ + r = do_composite_write_op(msg, format); + } else { + /* Single resource write Operation */ + r = parse_write_op(msg, format); + } #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) - if (msg->operation == LWM2M_OP_CREATE && r >= 0) { - access_control_add(msg->path.obj_id, msg->path.obj_inst_id, - msg->ctx->srv_obj_inst); - } + if (msg->operation == LWM2M_OP_CREATE && r >= 0) { + access_control_add(msg->path.obj_id, msg->path.obj_inst_id, + msg->ctx->srv_obj_inst); + } #endif - break; + break; - case LWM2M_OP_WRITE_ATTR: - r = lwm2m_write_attr_handler(obj, msg); - break; + case LWM2M_OP_WRITE_ATTR: + r = lwm2m_write_attr_handler(obj, msg); + break; - case LWM2M_OP_EXECUTE: - r = lwm2m_exec_handler(msg); - break; + case LWM2M_OP_EXECUTE: + r = lwm2m_exec_handler(msg); + break; - case LWM2M_OP_DELETE: + case LWM2M_OP_DELETE: #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (msg->ctx->bootstrap_mode) { - r = bootstrap_delete(msg); - break; - } -#endif - r = lwm2m_delete_handler(msg); + if (msg->ctx->bootstrap_mode) { + r = bootstrap_delete(msg); break; - - default: - LOG_ERR("Unknown operation: %u", msg->operation); - r = -EINVAL; } +#endif + r = lwm2m_delete_handler(msg); + break; - if (r < 0) { - goto error; - } + default: + LOG_ERR("Unknown operation: %u", msg->operation); + r = -EINVAL; } - /* Handle blockwise 1 (Part 2): Append BLOCK1 option / free context */ - if (block_ctx) { - if (!last_block) { - /* More to come, ack with correspond block # */ - r = coap_append_block1_option(msg->out.out_cpkt, &block_ctx->ctx); - if (r < 0) { - /* report as internal server error */ - LOG_ERR("Fail adding block1 option: %d", r); - r = -EINVAL; - goto error; - } - } else { - /* Free context when finished */ - free_block_ctx(block_ctx); - } + if (r < 0) { + goto error; } return 0; @@ -2482,9 +2513,6 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) LOG_ERR("Error recreating message: %d", r); } - /* Free block context when error happened */ - free_block_ctx(block_ctx); - return 0; } From b9028bb7222bd15ba31b3e7d310fc60537a60422 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Fri, 11 Aug 2023 15:39:58 +0300 Subject: [PATCH 1137/4498] net: lwm2m: Remove unneeded function pointer parameter lwm2m_udp_receive() is only called with same function pointer, so there no need to carry that in the parameter. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_engine.c | 2 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 14 +++++--------- subsys/net/lib/lwm2m/lwm2m_message_handling.h | 6 +----- tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 4 ++-- tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h | 2 +- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 91d8c3bd605..d38c081ed34 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -642,7 +642,7 @@ static int socket_recv_message(struct lwm2m_ctx *client_ctx) } in_buf[len] = 0U; - lwm2m_udp_receive(client_ctx, in_buf, len, &from_addr, handle_request); + lwm2m_udp_receive(client_ctx, in_buf, len, &from_addr); return 0; } diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 299b0330c0b..4eea849750b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -97,6 +97,7 @@ sys_slist_t *lwm2m_engine_obj_list(void); sys_slist_t *lwm2m_engine_obj_inst_list(void); +static int handle_request(struct coap_packet *request, struct lwm2m_message *msg); #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) struct coap_block_context *lwm2m_output_block_context(void); #endif @@ -2193,7 +2194,7 @@ static int lwm2m_exec_handler(struct lwm2m_message *msg) return -ENOENT; } -int handle_request(struct coap_packet *request, struct lwm2m_message *msg) +static int handle_request(struct coap_packet *request, struct lwm2m_message *msg) { int r; uint8_t code; @@ -2557,7 +2558,7 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) } void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, - struct sockaddr *from_addr, udp_request_handler_cb_t udp_request_handler) + struct sockaddr *from_addr) { struct lwm2m_message *msg = NULL; struct coap_pending *pending; @@ -2684,12 +2685,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ return; } - /* - * If no normal response handler is found, then this is - * a new request coming from the server. Let's look - * at registered objects to find a handler. - */ - if (udp_request_handler && coap_header_get_type(&response) == COAP_TYPE_CON) { + if (coap_header_get_type(&response) == COAP_TYPE_CON) { msg = lwm2m_get_message(client_ctx); if (!msg) { LOG_ERR("Unable to get a lwm2m message!"); @@ -2707,7 +2703,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ lwm2m_registry_lock(); /* process the response to this request */ - r = udp_request_handler(&response, msg); + r = handle_request(&response, msg); lwm2m_registry_unlock(); if (r < 0) { return; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index 12ba9e762fd..a98be3f8dc2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -39,8 +39,6 @@ #define NUM_OUTPUT_BLOCK_CONTEXT CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT #endif -/* Establish a request handler callback type */ -typedef int (*udp_request_handler_cb_t)(struct coap_packet *request, struct lwm2m_message *msg); /* LwM2M message functions */ struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx); struct lwm2m_message *find_msg(struct coap_pending *pending, struct coap_reply *reply); @@ -49,10 +47,8 @@ void lm2m_message_clear_allocations(struct lwm2m_message *msg); int lwm2m_init_message(struct lwm2m_message *msg); int lwm2m_send_message_async(struct lwm2m_message *msg); -int handle_request(struct coap_packet *request, struct lwm2m_message *msg); - void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, - struct sockaddr *from_addr, udp_request_handler_cb_t udp_request_handler); + struct sockaddr *from_addr); int generate_notify_message(struct lwm2m_ctx *ctx, struct observe_node *obs, void *user_data); /* Notification and Send operation */ diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 93f5cce1012..5db155f1e29 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -24,8 +24,8 @@ DEFINE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct DEFINE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t, const int64_t); DEFINE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *); -DEFINE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, struct sockaddr *, - udp_request_handler_cb_t); +DEFINE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, + struct sockaddr *); DEFINE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *); DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *, diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h index 088d72d4623..7b8ca481f85 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h @@ -39,7 +39,7 @@ DECLARE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct obser const int64_t); DECLARE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *); DECLARE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, - struct sockaddr *, udp_request_handler_cb_t); + struct sockaddr *); DECLARE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *, From 69cd5978875329e4eac6c55626e51f9f008e9eb3 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 10 Aug 2023 16:39:49 +0300 Subject: [PATCH 1138/4498] net: lwm2m: Refactor blockwise SEND to support GET and FETCH Allow blockwise-send buffers to be used with GET and FETCH queries as well. When outgoing packet is split into multiple blocks, don't free it when first block is send. Keep it in memory until some other requests come. Following queries to next block are matched using CoAP token. However, this required Leshan to use COAP.BLOCKWISE_REUSE_TOKEN=true option from Californium. Signed-off-by: Seppo Takalo --- include/zephyr/net/coap.h | 14 +++ subsys/net/lib/coap/coap.c | 13 +++ subsys/net/lib/lwm2m/lwm2m_engine.c | 4 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 92 +++++++++++++++++-- subsys/net/lib/lwm2m/lwm2m_message_handling.h | 1 + subsys/net/lib/lwm2m/lwm2m_object.h | 5 +- 6 files changed, 121 insertions(+), 8 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 95bb0b45c65..55776bfc6d8 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -713,6 +713,20 @@ int coap_get_option_int(const struct coap_packet *cpkt, uint16_t code); */ int coap_get_block1_option(const struct coap_packet *cpkt, bool *has_more, uint8_t *block_number); +/** + * @brief Get values from CoAP block2 option. + * + * Decode block number and block size from option. Ignore the has_more flag + * as it should always be zero on queries. + * + * @param cpkt Packet to be inspected + * @param block_number Is set to the number of the block + * + * @return Integer value of the block size in case of success + * or negative in case of error. + */ +int coap_get_block2_option(const struct coap_packet *cpkt, uint8_t *block_number); + /** * @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a cpkt and updates * @a ctx accordingly. diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index a5c300bf0e2..e3427844bb5 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1303,6 +1303,19 @@ int coap_get_block1_option(const struct coap_packet *cpkt, bool *has_more, uint8 return ret; } +int coap_get_block2_option(const struct coap_packet *cpkt, uint8_t *block_number) +{ + int ret = coap_get_option_int(cpkt, COAP_OPTION_BLOCK2); + + if (ret < 0) { + return ret; + } + + *block_number = GET_NUM(ret); + ret = 1 << (GET_BLOCK_SIZE(ret) + 4); + return ret; +} + int insert_option(struct coap_packet *cpkt, uint16_t code, const uint8_t *value, uint16_t len) { uint16_t offset = cpkt->hdr_len; diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index d38c081ed34..651baa30ff6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -675,7 +675,9 @@ static int socket_send_message(struct lwm2m_ctx *client_ctx) } if (msg->type != COAP_TYPE_CON) { - lwm2m_reset_message(msg, true); + if (!lwm2m_outgoing_is_part_of_blockwise(msg)) { + lwm2m_reset_message(msg, true); + } } return rc; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 4eea849750b..df940cf4adb 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -81,6 +81,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* Shared set of in-flight LwM2M messages */ static struct lwm2m_message messages[CONFIG_LWM2M_ENGINE_MAX_MESSAGES]; static struct lwm2m_block_context block1_contexts[NUM_BLOCK1_CONTEXT]; +static struct lwm2m_message *ongoing_block2_tx; #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) /* we need 1 more buffer as the payload is encoded in that buffer first even if @@ -99,6 +100,7 @@ sys_slist_t *lwm2m_engine_obj_inst_list(void); static int handle_request(struct coap_packet *request, struct lwm2m_message *msg); #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) +STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num); struct coap_block_context *lwm2m_output_block_context(void); #endif @@ -301,10 +303,16 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu } msg->cpkt.hdr_len = msg->body_encode_buffer.hdr_len; } else { - /* reuse message for next block */ - tkl = coap_header_get_token(&msg->cpkt, token); + /* reuse message for next block. Copy token from the new query to allow + * CoAP clients to use new token for every query of ongoing transaction + */ + tkl = coap_header_get_token(msg->in.in_cpkt, token); lwm2m_reset_message(msg, false); - msg->mid = coap_next_id(); + if (msg->type == COAP_TYPE_ACK) { + msg->mid = coap_header_get_id(msg->in.in_cpkt); + } else { + msg->mid = coap_next_id(); + } msg->token = token; msg->tkl = tkl; ret = lwm2m_init_message(msg); @@ -333,10 +341,14 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu return ret; } ret = coap_block_transfer_init(msg->out.block_ctx, lwm2m_default_block_size(), - msg->body_encode_buffer.offset); + complete_payload_len); if (ret < 0) { return ret; } + if (msg->type == COAP_TYPE_ACK) { + ongoing_block2_tx = msg; + } + msg->block_send = true; } else { /* update block context */ msg->out.block_ctx->current = block_num * block_size_bytes; @@ -402,8 +414,15 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) return 0; } + #endif +bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) +{ + return msg->block_send; +} + + void lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx) { struct lwm2m_message *msg; @@ -2557,6 +2576,56 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) return ret; } +static struct lwm2m_message *find_ongoing_block2_tx(void) +{ + /* TODO: I could try to check if there is Request-Tags attached, and then match queries + * for those, but currently popular LwM2M servers don't attach those tags, so in reality + * I have no way of properly matching query with BLOCK2 option to a previous query. + * Therefore we can only support one ongoing BLOCK2 transfer and assume all BLOCK2 requests + * are part of currently ongoing one. + */ + return ongoing_block2_tx; +} + +static void clear_ongoing_block2_tx(void) +{ + if (ongoing_block2_tx) { + LOG_DBG("clear"); + lwm2m_reset_message(ongoing_block2_tx, true); + ongoing_block2_tx = NULL; + } +} + +static void handle_ongoing_block2_tx(struct lwm2m_message *msg, struct coap_packet *cpkt) +{ +#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) + int r; + uint8_t block; + + r = coap_get_block2_option(cpkt, &block); + if (r < 0) { + LOG_ERR("Failed to parse BLOCK2"); + return; + } + + msg->in.in_cpkt = cpkt; + + r = build_msg_block_for_send(msg, block); + if (r < 0) { + clear_ongoing_block2_tx(); + LOG_ERR("Unable to build next block of lwm2m message! r=%d", r); + return; + } + + r = lwm2m_send_message_async(msg); + if (r < 0) { + clear_ongoing_block2_tx(); + LOG_ERR("Unable to send next block of lwm2m message!"); + return; + } +#endif +} + void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, struct sockaddr *from_addr) { @@ -2565,12 +2634,12 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ struct coap_reply *reply; struct coap_packet response; int r; - uint8_t token[8]; #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) bool more_blocks = false; uint8_t block_num; uint8_t last_block_num; #endif + bool has_block2; r = coap_packet_parse(&response, buf, buf_len, NULL, 0); if (r < 0) { @@ -2578,7 +2647,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ return; } - (void)coap_header_get_token(&response, token); + has_block2 = coap_get_option_int(&response, COAP_OPTION_BLOCK2) > 0 ? true : false; pending = coap_pending_received(&response, client_ctx->pendings, ARRAY_SIZE(client_ctx->pendings)); if (pending && coap_header_get_type(&response) == COAP_TYPE_ACK) { @@ -2686,6 +2755,17 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ } if (coap_header_get_type(&response) == COAP_TYPE_CON) { + if (has_block2 && IS_ENABLED(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)) { + msg = find_ongoing_block2_tx(); + if (msg) { + return handle_ongoing_block2_tx(msg, &response); + } + return; + } + + /* Clear out existing Block2 transfers when new requests come */ + clear_ongoing_block2_tx(); + msg = lwm2m_get_message(client_ctx); if (!msg) { LOG_ERR("Unable to get a lwm2m message!"); diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index a98be3f8dc2..fd6c4470d84 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -75,5 +75,6 @@ enum coap_block_size lwm2m_default_block_size(void); int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri); void lwm2m_clear_block_contexts(void); +bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg); #endif /* LWM2M_MESSAGE_HANDLING_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index 05bc818c99c..170a99c023d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -521,8 +521,11 @@ struct lwm2m_message { /** Incoming message action */ uint8_t operation; - /* Information whether the message was acknowledged. */ + /** Information whether the message was acknowledged. */ bool acknowledged : 1; + + /** Indicate that this is part of outgoing block transfer. */ + bool block_send : 1; }; /* LWM2M format writer for the various formats supported */ From ebb90c5184cf296d324685862bd8a02a02e6bd23 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 24 Aug 2023 16:42:00 +0300 Subject: [PATCH 1139/4498] net: lwm2m: Fix composite read on SenML-CBOR Composite read was incorrectly trying to parse CoAP packet instead of payload of the packet. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 6 ------ subsys/net/lib/lwm2m/lwm2m_message_handling.h | 6 +++++- subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c | 5 ++++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index df940cf4adb..06cc1b5ecf8 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -417,12 +417,6 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) #endif -bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) -{ - return msg->block_send; -} - - void lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx) { struct lwm2m_message *msg; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index fd6c4470d84..c41fbbac0ee 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -75,6 +75,10 @@ enum coap_block_size lwm2m_default_block_size(void); int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri); void lwm2m_clear_block_contexts(void); -bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg); + +static inline bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) +{ + return msg->block_send; +} #endif /* LWM2M_MESSAGE_HANDLING_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c index d62af88200b..15dc9a9451e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c @@ -836,12 +836,15 @@ static uint8_t parse_composite_read_paths(struct lwm2m_message *msg, uint_fast8_t dret; int len; int ret; + char *payload; + uint16_t in_len; setup_in_fmt_data(msg); fd = engine_get_in_user_data(&msg->in); + payload = (char *)coap_packet_get_payload(msg->in.in_cpkt, &in_len); - dret = cbor_decode_lwm2m_senml(ICTX_BUF_R_REGION(&msg->in), &fd->dcd, &isize); + dret = cbor_decode_lwm2m_senml(payload, in_len, &fd->dcd, &isize); if (dret != ZCBOR_SUCCESS) { __ASSERT_NO_MSG(false); From 1606d352e1c3a108762c54681bee1e9133877c06 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Fri, 8 Sep 2023 14:21:18 +0300 Subject: [PATCH 1140/4498] net: lwm2m: Append CoAP Etag to protect integrity of blockwise To protect the integrity of outgoing block-wise transfers, append Etag option that allows client to see if the received block is generated from same content as it is expecting. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/Kconfig | 2 ++ subsys/net/lib/lwm2m/lwm2m_message_handling.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index 41ac5bcf1ce..d826e5cd599 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -83,6 +83,8 @@ config LWM2M_COAP_BLOCK_TRANSFER help LwM2M messages with a big body that exceed the block size will be split into blocks for sending. + To append CoAP ETag option into outgoing block transfers, CONFIG_SYS_HASH_FUNC32 should + be enabled. config LWM2M_CANCEL_OBSERVE_BY_PATH bool "Use path matching as fallback for cancel-observe" diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 06cc1b5ecf8..7aaa42c20ab 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -33,6 +33,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #if defined(CONFIG_LWM2M_DTLS_SUPPORT) #include @@ -378,6 +379,7 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) { int ret; uint16_t len; + const uint8_t *payload; /* save the big buffer for later use (splitting blocks) */ msg->body_encode_buffer = msg->cpkt; @@ -387,7 +389,7 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) msg->cpkt.offset = 0; msg->cpkt.max_len = MAX_PACKET_SIZE; - coap_packet_get_payload(&msg->body_encode_buffer, &len); + payload = coap_packet_get_payload(&msg->body_encode_buffer, &len); if (len <= CONFIG_LWM2M_COAP_MAX_MSG_SIZE) { /* copy the packet */ @@ -406,6 +408,16 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) NET_ASSERT(msg->out.block_ctx == NULL, "Expecting to have no context to release"); } else { + /* Before splitting the content, append Etag option to protect the integrity of + * the payload. + */ + if (IS_ENABLED(CONFIG_SYS_HASH_FUNC32)) { + uint32_t hash = sys_hash32(payload, len); + + coap_packet_append_option(&msg->body_encode_buffer, COAP_OPTION_ETAG, + (const uint8_t *)&hash, sizeof(hash)); + } + ret = build_msg_block_for_send(msg, 0); if (ret != 0) { return ret; From a8f977758637d1cf3f246e2bc330b0f6382e4d52 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 21 Sep 2023 16:34:11 +0300 Subject: [PATCH 1141/4498] net: lwm2m: Generate new tokens for LwM2M SEND blocks Previously each piece of LwM2M SEND was using token length of zero. I think this was unintentional. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 7aaa42c20ab..678f358d1ee 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -307,12 +307,13 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu /* reuse message for next block. Copy token from the new query to allow * CoAP clients to use new token for every query of ongoing transaction */ - tkl = coap_header_get_token(msg->in.in_cpkt, token); lwm2m_reset_message(msg, false); if (msg->type == COAP_TYPE_ACK) { msg->mid = coap_header_get_id(msg->in.in_cpkt); + tkl = coap_header_get_token(msg->in.in_cpkt, token); } else { msg->mid = coap_next_id(); + tkl = LWM2M_MSG_TOKEN_GENERATE_NEW; } msg->token = token; msg->tkl = tkl; From c870fb70ced5501348fbdc4c4974f05d855328ff Mon Sep 17 00:00:00 2001 From: Daniel Gaston Ochoa Date: Sat, 9 Sep 2023 18:08:46 +0100 Subject: [PATCH 1142/4498] drivers: spi: Test rx bigger than tx Test that SPI works when the rx buffer is longer than the tx one. Signed-off-by: Daniel Gaston Ochoa --- tests/drivers/spi/spi_loopback/src/spi.c | 81 +++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index 2d7eeef6663..d044c9a3fb4 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -12,6 +12,7 @@ LOG_MODULE_REGISTER(spi_loopback); #include #include #include +#include #include #include @@ -442,6 +443,80 @@ static int spi_rx_every_4(struct spi_dt_spec *spec) return 0; } +static int spi_rx_bigger_than_tx(struct spi_dt_spec *spec) +{ + const uint32_t tx_buf_size = 8; + + BUILD_ASSERT(tx_buf_size < BUF_SIZE, + "Transmit buffer is expected to be smaller than the receive buffer"); + + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = tx_buf_size, + }, + }; + const struct spi_buf rx_bufs[] = { + { + .buf = buffer_rx, + .len = BUF_SIZE, + } + }; + const struct spi_buf_set tx = { + .buffers = tx_bufs, + .count = ARRAY_SIZE(tx_bufs) + }; + const struct spi_buf_set rx = { + .buffers = rx_bufs, + .count = ARRAY_SIZE(rx_bufs) + }; + int ret; + + if (IS_ENABLED(CONFIG_SPI_STM32_DMA)) { + LOG_INF("Skip rx bigger than tx"); + return 0; + } + + LOG_INF("Start rx bigger than tx"); + + (void)memset(buffer_rx, 0xff, BUF_SIZE); + + ret = spi_transceive_dt(spec, &tx, &rx); + if (ret) { + LOG_ERR("Code %d", ret); + zassert_false(ret, "SPI transceive failed"); + return -1; + } + + if (memcmp(buffer_tx, buffer_rx, tx_buf_size)) { + to_display_format(buffer_tx, tx_buf_size, buffer_print_tx); + to_display_format(buffer_rx, tx_buf_size, buffer_print_rx); + LOG_ERR("Buffer contents are different: %s", buffer_print_tx); + LOG_ERR(" vs: %s", buffer_print_rx); + zassert_false(1, "Buffer contents are different"); + return -1; + } + + const uint8_t all_zeroes_buf[BUF_SIZE] = {0}; + + if (memcmp(all_zeroes_buf, buffer_rx + tx_buf_size, BUF_SIZE - tx_buf_size)) { + to_display_format( + buffer_rx + tx_buf_size, BUF_SIZE - tx_buf_size, buffer_print_tx); + + to_display_format( + all_zeroes_buf, BUF_SIZE - tx_buf_size, buffer_print_rx); + + LOG_ERR("Buffer contents are different: %s", buffer_print_tx); + LOG_ERR(" vs: %s", buffer_print_rx); + zassert_false(1, "Buffer contents are different"); + return -1; + } + + LOG_INF("Passed"); + + return 0; +} + #if (CONFIG_SPI_ASYNC) static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(async_sig); static struct k_poll_event async_evt = @@ -574,7 +649,8 @@ ZTEST(spi_loopback, test_spi_loopback) spi_null_tx_buf(&spi_slow) || spi_rx_half_start(&spi_slow) || spi_rx_half_end(&spi_slow) || - spi_rx_every_4(&spi_slow) + spi_rx_every_4(&spi_slow) || + spi_rx_bigger_than_tx(&spi_slow) #if (CONFIG_SPI_ASYNC) || spi_async_call(&spi_slow) #endif @@ -591,7 +667,8 @@ ZTEST(spi_loopback, test_spi_loopback) spi_null_tx_buf(&spi_fast) || spi_rx_half_start(&spi_fast) || spi_rx_half_end(&spi_fast) || - spi_rx_every_4(&spi_fast) + spi_rx_every_4(&spi_fast) || + spi_rx_bigger_than_tx(&spi_fast) #if (CONFIG_SPI_ASYNC) || spi_async_call(&spi_fast) #endif From 8d253086c3791c6bd2fc40417e73a1b7361680ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Tue, 26 Sep 2023 10:13:52 +0200 Subject: [PATCH 1143/4498] tests: Bluetooth: Mesh: Fix bug in priv beacon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix several pointer related bugs in the private beacon test framework. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/src/test_beacon.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index 117a90c1d86..062d0fc39e1 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -979,13 +979,13 @@ static void test_rx_secure_beacon_interval(void) static bool private_beacon_check(const uint8_t *net_id, void *ctx) { bool ret; - bool same_random = (bool *)ctx; + bool same_random = *(bool *)ctx; - if (memcmp(beacon.adv_addr.a.val, &last_beacon_adv_addr, BT_ADDR_SIZE) == 0) { + if (memcmp(beacon.adv_addr.a.val, last_beacon_adv_addr.a.val, BT_ADDR_SIZE) == 0) { return false; } - memcpy(&last_beacon_adv_addr, beacon.adv_addr.a.val, BT_ADDR_SIZE); + memcpy(&last_beacon_adv_addr.a.val, beacon.adv_addr.a.val, BT_ADDR_SIZE); if (same_random) { ret = memcmp(beacon.random, last_random, 13) == 0; @@ -1322,6 +1322,7 @@ static void test_tx_priv_interleave(void) static void test_rx_priv_interleave(void) { int err; + bool same_random = false; bt_mesh_test_cfg_set(&rx_cfg, BEACON_INTERVAL_WAIT_TIME); bt_mesh_crypto_init(); @@ -1341,10 +1342,10 @@ static void test_rx_priv_interleave(void) ASSERT_TRUE(wait_for_beacon(NULL, NULL)); expected_beacon = BEACON_TYPE_PRIVATE; - ASSERT_TRUE(wait_for_beacon(private_beacon_check, false)); + ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); /* IVU was started here */ - ASSERT_TRUE(wait_for_beacon(private_beacon_check, false)); + ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -1364,7 +1365,7 @@ static void test_rx_priv_interleave(void) err = bt_mesh_private_beacon_key(net_key_new, &priv_beacon_key); - ASSERT_TRUE(wait_for_beacon(private_beacon_check, false)); + ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); ASSERT_EQUAL(0x03, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); From c2677fe2e41814759ee0988c79a9953d7ef2977b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Tue, 26 Sep 2023 10:13:52 +0200 Subject: [PATCH 1144/4498] tests: Bluetooth: Mesh: Add PRB proxy bsim test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Bsim test for checking behavior of private Net ID and private Node ID. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/CMakeLists.txt | 6 + tests/bsim/bluetooth/mesh/overlay_gatt.conf | 1 - tests/bsim/bluetooth/mesh/src/main.c | 7 + tests/bsim/bluetooth/mesh/src/mesh_test.h | 8 + tests/bsim/bluetooth/mesh/src/test_beacon.c | 434 ++++++++++++++++-- .../priv_beacon/priv_proxy_net_id.sh | 31 ++ .../priv_beacon/priv_proxy_net_id_multi.sh | 28 ++ .../priv_beacon/priv_proxy_node_id.sh | 36 ++ 8 files changed, 501 insertions(+), 50 deletions(-) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id_multi.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_node_id.sh diff --git a/tests/bsim/bluetooth/mesh/CMakeLists.txt b/tests/bsim/bluetooth/mesh/CMakeLists.txt index b1be544ed86..0fb2357826c 100644 --- a/tests/bsim/bluetooth/mesh/CMakeLists.txt +++ b/tests/bsim/bluetooth/mesh/CMakeLists.txt @@ -46,6 +46,12 @@ elseif(CONFIG_BT_MESH_GATT_PROXY) src/test_advertiser.c ) + if(CONFIG_BT_MESH_V1d1) + target_sources(app PRIVATE + src/test_beacon.c + ) + endif() + elseif(CONFIG_BT_CTLR_LOW_LAT) target_sources(app PRIVATE diff --git a/tests/bsim/bluetooth/mesh/overlay_gatt.conf b/tests/bsim/bluetooth/mesh/overlay_gatt.conf index b2c1bba7fbf..a8ecf87d113 100644 --- a/tests/bsim/bluetooth/mesh/overlay_gatt.conf +++ b/tests/bsim/bluetooth/mesh/overlay_gatt.conf @@ -4,4 +4,3 @@ CONFIG_BT_MESH_PB_GATT=y CONFIG_BT_MESH_LOW_POWER=n CONFIG_BT_MESH_FRIEND=n -CONFIG_BT_MESH_IV_UPDATE_TEST=n diff --git a/tests/bsim/bluetooth/mesh/src/main.c b/tests/bsim/bluetooth/mesh/src/main.c index 3c314e24a58..ea7ceff0883 100644 --- a/tests/bsim/bluetooth/mesh/src/main.c +++ b/tests/bsim/bluetooth/mesh/src/main.c @@ -18,6 +18,10 @@ extern struct bst_test_list *test_sar_pst_install(struct bst_test_list *test); #endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_MESH_GATT_PROXY) extern struct bst_test_list *test_adv_install(struct bst_test_list *test); +#if defined(CONFIG_BT_MESH_V1d1) +extern struct bst_test_list *test_beacon_install(struct bst_test_list *tests); +#endif /* defined(CONFIG_BT_MESH_V1d1) */ + #elif defined(CONFIG_BT_CTLR_LOW_LAT) extern struct bst_test_list *test_transport_install(struct bst_test_list *tests); extern struct bst_test_list *test_friendship_install(struct bst_test_list *tests); @@ -51,6 +55,9 @@ bst_test_install_t test_installers[] = { #endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_MESH_GATT_PROXY) test_adv_install, +#if defined(CONFIG_BT_MESH_V1d1) + test_beacon_install, +#endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_CTLR_LOW_LAT) test_transport_install, test_friendship_install, diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index 8e7f41cf978..7bbd30c2685 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -94,6 +94,14 @@ } \ } while (0) +#define ASSERT_IN_RANGE(got, min, max) \ + do { \ + if (!IN_RANGE(got, min, max)) { \ + bst_result = Failed; \ + bs_trace_error_time_line(#got " not in range %d <-> %d, " #got " = %d\n", \ + (min), (max), (got)); \ + } \ + } while (0) struct bt_mesh_test_cfg { uint16_t addr; diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index 062d0fc39e1..fd2477f3907 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -315,6 +315,8 @@ static struct { uint32_t iv_index; #if CONFIG_BT_MESH_V1d1 uint8_t random[13]; + uint64_t pp_hash; + uint64_t pp_random; bt_addr_le_t adv_addr; #endif bool (*process_cb)(const uint8_t *net_id, void *ctx); @@ -363,8 +365,9 @@ static void beacon_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_ty } } -/* Listens to beacons for one beacon interval (10 seconds). */ -static bool wait_for_beacon(bool (*process_cb)(const uint8_t *net_id, void *ctx), void *ctx) +/* Listens to beacons */ +static bool wait_for_beacon(bt_le_scan_cb_t scan_cb, uint16_t wait, + bool (*process_cb)(const uint8_t *net_id, void *ctx), void *ctx) { struct bt_le_scan_param scan_param = { .type = BT_HCI_LE_SCAN_PASSIVE, @@ -378,7 +381,7 @@ static bool wait_for_beacon(bool (*process_cb)(const uint8_t *net_id, void *ctx) beacon.process_cb = process_cb; beacon.user_ctx = ctx; - err = bt_le_scan_start(&scan_param, beacon_scan_cb); + err = bt_le_scan_start(&scan_param, scan_cb); if (err && err != -EALREADY) { FAIL("starting scan failed (err %d)", err); } @@ -392,7 +395,7 @@ static bool wait_for_beacon(bool (*process_cb)(const uint8_t *net_id, void *ctx) * waiting time (BEACON_INTERVAL + 1) to guarantee that beacon comes * before timer expiration. */ - err = k_sem_take(&observer_sem, K_SECONDS(BEACON_INTERVAL + 1)); + err = k_sem_take(&observer_sem, K_SECONDS(wait)); if (!err) { received = true; } else { @@ -486,8 +489,8 @@ static void corrupted_beacon_test(const uint8_t *offsets, send_beacon(buf); buf->data[offsets[i]] ^= 0xFF; /* Ensure that interval is not affected. */ - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x00, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); } @@ -500,8 +503,8 @@ static void corrupted_beacon_test(const uint8_t *offsets, /* The beacon interval shall be changed and the node shall skip transmission of the next * beacon. */ - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); } @@ -588,16 +591,16 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key, 0x01, 0x0000); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x00, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); /* The old Net Key can still initiate IV Index update. */ beacon_create(&buf, test_net_key, 0x02, 0x0001); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -607,8 +610,8 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key_secondary, 0x03, 0x0001); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x03, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -617,8 +620,8 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key, 0x01, 0x0001); send_beacon(&buf); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x03, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -627,8 +630,8 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key_secondary, 0x02, 0x0001); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -637,8 +640,8 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key, 0x00, 0x0001); send_beacon(&buf); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -647,8 +650,8 @@ static void test_tx_kr_old_key(void) */ beacon_create(&buf, test_net_key_secondary, 0x00, 0x0001); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x00, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -784,8 +787,10 @@ static void test_tx_multiple_netkeys(void) */ beacon_create(&buf, net_key_pairs[i].primary, 0x01, 0x0000); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(beacon_confirm_by_subnet, &buf.data[2])); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_by_subnet, &buf.data[2])); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, &buf.data[2])); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, &buf.data[2])); ASSERT_EQUAL(0x00, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); @@ -794,8 +799,10 @@ static void test_tx_multiple_netkeys(void) */ beacon_create(&buf, net_key_pairs[i].secondary, 0x01, 0x0000); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); ASSERT_EQUAL(0x01, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); @@ -804,8 +811,10 @@ static void test_tx_multiple_netkeys(void) */ beacon_create(&buf, net_key_pairs[i].primary, 0x00, 0x0000); send_beacon(&buf); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); ASSERT_EQUAL(0x01, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); @@ -814,8 +823,10 @@ static void test_tx_multiple_netkeys(void) */ beacon_create(&buf, net_key_pairs[i].secondary, 0x00, 0x0000); send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, + beacon_confirm_by_subnet, net_id_secondary)); ASSERT_EQUAL(0x00, beacon.flags); ASSERT_EQUAL(0x0000, beacon.iv_index); } @@ -823,13 +834,15 @@ static void test_tx_multiple_netkeys(void) /* Create a valid beacon secured with unknown Net Key. The node shall ignore the beacon and * continue sending beacons regularly. */ - uint8_t unknown_net_key[16] = { 0xde, 0xad, 0xbe, 0xef }; + uint8_t unknown_net_key[16] = {0xde, 0xad, 0xbe, 0xef}; beacon_create(&buf, unknown_net_key, 0x00, 0x0000); send_beacon(&buf); /* Ensure that interval is not affected. */ - ASSERT_TRUE(wait_for_beacon(beacon_confirm_all_subnets, NULL)); - ASSERT_TRUE(wait_for_beacon(beacon_confirm_all_subnets, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, beacon_confirm_all_subnets, + NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, beacon_confirm_all_subnets, + NULL)); PASS(); } @@ -930,7 +943,7 @@ static void test_rx_secure_beacon_interval(void) beacon_create(&buf, test_net_key, 0, 0); k_sleep(K_SECONDS(5)); /*wait provisioned tx node to send the first beacon*/ - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); k_sleep(K_SECONDS(2)); /** @@ -941,9 +954,11 @@ static void test_rx_secure_beacon_interval(void) for (size_t i = 1; i < 5; i++) { if (i % 2) { send_beacon(&buf); - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE( + wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); } else { - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE( + wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); } } @@ -951,9 +966,9 @@ static void test_rx_secure_beacon_interval(void) * Verify that tx node keeps the 20s SNB interval until adapts itself and * sends SNB in 10s again. */ - ASSERT_FALSE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); beacon_recv_time = k_uptime_get(); /* Start sending SNB */ k_work_schedule(&beacon_timer, K_NO_WAIT); @@ -965,7 +980,7 @@ static void test_rx_secure_beacon_interval(void) */ delta = 0; for (size_t i = 0; i < 60; i++) { - if (wait_for_beacon(NULL, NULL)) { + if (wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)) { delta = k_uptime_delta(&beacon_recv_time); break; } @@ -1119,7 +1134,8 @@ static void test_rx_priv_adv(void) * and with Random Interval = 0 for another 6 */ for (i = 0; i < 12; i++) { - wait_for_beacon(private_beacon_check, &same_random); + wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random); } /* TX device is advertising with Random Interval = 3 */ @@ -1127,14 +1143,16 @@ static void test_rx_priv_adv(void) same_random = true; for (int j = 0; j < 2; j++) { - wait_for_beacon(private_beacon_check, &same_random); + wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random); } k_sleep(K_SECONDS(BEACON_INTERVAL)); /* Beacon random should change here */ same_random = true; - wait_for_beacon(private_beacon_check, &same_random); + wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random); } PASS(); @@ -1339,25 +1357,27 @@ static void test_rx_priv_interleave(void) } expected_beacon = BEACON_TYPE_SECURE; - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); expected_beacon = BEACON_TYPE_PRIVATE; - ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random)); /* IVU was started here */ - ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); memset(&beacon, 0, sizeof(beacon)); expected_beacon = BEACON_TYPE_SECURE; - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x02, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); /* KR was started here */ - ASSERT_TRUE(wait_for_beacon(NULL, NULL)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_EQUAL(0x03, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); @@ -1365,12 +1385,318 @@ static void test_rx_priv_interleave(void) err = bt_mesh_private_beacon_key(net_key_new, &priv_beacon_key); - ASSERT_TRUE(wait_for_beacon(private_beacon_check, &same_random)); + ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, private_beacon_check, + &same_random)); ASSERT_EQUAL(0x03, beacon.flags); ASSERT_EQUAL(0x0001, beacon.iv_index); PASS(); } + +#if IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) + +#define BEACON_TYPE_PRIVATE_NET_ID 2 +#define BEACON_TYPE_PRIVATE_NODE_ID 3 +#define BEACON_TYPE_PRIVATE_LEN 28 +#define TEST_NET_IDX1 0 +#define TEST_NET_IDX2 1 +#define MAX_TIMEOUT ((CONFIG_BT_MESH_NODE_ID_TIMEOUT * 1000) / 6) + +#define PP_NET_ID_WAIT_TIME 610 /*seconds*/ +#define PP_NODE_ID_WAIT_TIME 80 /*seconds*/ +#define PP_MULT_NET_ID_WAIT_TIME 50 /*seconds*/ + +struct pp_netkey_ctx { + uint8_t *net_key; + uint8_t net_id[8]; + struct bt_mesh_key id_key; +}; + +static struct pp_netkey_ctx pp_net0 = {.net_key = (uint8_t *)test_net_key}; +static struct pp_netkey_ctx pp_net1 = {.net_key = (uint8_t *)test_net_key_secondary}; + +struct priv_test_ctx { + uint8_t beacon_type; + uint16_t *node_id_addr; +}; + +static void pp_netkey_ctx_init(struct pp_netkey_ctx *net) +{ + ASSERT_OK_MSG(bt_mesh_identity_key(net->net_key, &net->id_key), + "Failed to generate ID key"); + ASSERT_OK_MSG(bt_mesh_k3(net->net_key, net->net_id), "Failed to generate Net ID"); +} + +static bool pp_type_check(uint16_t expected_beacon, uint8_t adv_type, struct net_buf_simple *buf) +{ + if (adv_type != BT_GAP_ADV_TYPE_ADV_IND || buf->len != BEACON_TYPE_PRIVATE_LEN) { + return false; + } + + /* Remove Header */ + (void)net_buf_simple_pull_mem(buf, 11); + + uint8_t beacon_type = net_buf_simple_pull_u8(buf); + + if (beacon_type != expected_beacon) { + return false; + } + + return true; +} + +static uint64_t pp_hash_calc(struct pp_netkey_ctx *net, uint64_t random, uint16_t *addr) +{ + uint64_t hash; + uint8_t tmp[16] = {0, 0, 0, 0, 0, 3}; + + if (addr) { + memcpy(&tmp[6], &random, 8); + sys_put_be16(*addr, &tmp[14]); + + } else { + memcpy(&tmp[0], net->net_id, 8); + memcpy(&tmp[8], &random, 8); + } + + bt_mesh_encrypt(&net->id_key, tmp, tmp); + memcpy(&hash, &tmp[8], 8); + + return hash; +} + +static bool pp_beacon_check(const uint8_t *net_id, void *ctx) +{ + struct priv_test_ctx *test_ctx = (struct priv_test_ctx *)ctx; + + ASSERT_EQUAL(beacon.pp_hash, + pp_hash_calc(&pp_net0, beacon.pp_random, test_ctx->node_id_addr)); + + if (memcmp(beacon.adv_addr.a.val, last_beacon_adv_addr.a.val, BT_ADDR_SIZE) == 0) { + return false; + } + + memcpy(&last_beacon_adv_addr.a.val, beacon.adv_addr.a.val, BT_ADDR_SIZE); + + return true; +} + +static void priv_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, + struct net_buf_simple *buf) +{ + struct priv_test_ctx *ctx = (struct priv_test_ctx *)beacon.user_ctx; + + if (!pp_type_check(ctx->beacon_type, adv_type, buf)) { + /* Wrong message type */ + return; + } + + bt_addr_le_copy(&beacon.adv_addr, addr); + + beacon.pp_hash = net_buf_simple_pull_le64(buf); + beacon.pp_random = net_buf_simple_pull_le64(buf); + + if (!beacon.process_cb || beacon.process_cb(NULL, beacon.user_ctx)) { + k_sem_give(&observer_sem); + } +} + +static void rx_priv_common_init(uint16_t wait) +{ + bt_mesh_test_cfg_set(&rx_cfg, wait); + bt_mesh_crypto_init(); + pp_netkey_ctx_init(&pp_net0); + k_sem_init(&observer_sem, 0, 1); + ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed"); +} + +static void tx_priv_common_init(uint16_t wait) +{ + bt_mesh_test_cfg_set(NULL, wait); + bt_mesh_device_setup(&prov, &prb_comp); + provision(&tx_cfg); + + /* Disable GATT proxy */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), + "Failed to disable gatt proxy"); +} + +static void test_tx_priv_net_id(void) +{ + tx_priv_common_init(PP_NET_ID_WAIT_TIME); + + /* Enable private GATT proxy */ + ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to set private gatt proxy"); + + PASS(); +} + +static void test_rx_priv_net_id(void) +{ + struct priv_test_ctx ctx = { + .beacon_type = BEACON_TYPE_PRIVATE_NET_ID, + .node_id_addr = NULL, + }; + + rx_priv_common_init(PP_NET_ID_WAIT_TIME); + + /* Scan for first net ID */ + ASSERT_TRUE( + wait_for_beacon(priv_scan_cb, 1, pp_beacon_check, &ctx)); + + uint64_t last_pp_random = beacon.pp_random; + + /* Wait for 10 minutes, then scan for another net + * ID beacon and verify that random field has changed + */ + k_sleep(K_SECONDS(600)); + ASSERT_TRUE( + wait_for_beacon(priv_scan_cb, 1, pp_beacon_check, &ctx)); + ASSERT_FALSE(beacon.pp_random == last_pp_random); + + PASS(); +} + +static void test_tx_priv_node_id(void) +{ + enum bt_mesh_feat_state state; + + tx_priv_common_init(PP_NODE_ID_WAIT_TIME); + + /* Start first node advertisement */ + ASSERT_OK_MSG(bt_mesh_subnet_priv_node_id_set(TEST_NET_IDX1, BT_MESH_NODE_IDENTITY_RUNNING), + "Failed to set private node ID"); + + /* Wait for Node ID advertising to end */ + k_sleep(K_SECONDS(65)); + + /* Check that advertisment has stopped */ + ASSERT_OK_MSG(bt_mesh_subnet_priv_node_id_get(TEST_NET_IDX1, &state), + "Failed to get private node ID"); + ASSERT_EQUAL(state, BT_MESH_NODE_IDENTITY_STOPPED); + + /* Start second node advertisement */ + ASSERT_OK_MSG(bt_mesh_subnet_priv_node_id_set(TEST_NET_IDX1, BT_MESH_NODE_IDENTITY_RUNNING), + "Failed to set private node ID"); + + /* Wait to let node ID advertise for a while */ + k_sleep(K_SECONDS(5)); + + PASS(); +} + +static void test_rx_priv_node_id(void) +{ + struct priv_test_ctx ctx = { + .beacon_type = BEACON_TYPE_PRIVATE_NODE_ID, + .node_id_addr = (uint16_t *)&tx_cfg.addr, + }; + + rx_priv_common_init(PP_NODE_ID_WAIT_TIME); + + /* Scan for first node ID */ + ASSERT_TRUE( + wait_for_beacon(priv_scan_cb, 1, pp_beacon_check, &ctx)); + + uint64_t last_pp_random = beacon.pp_random; + + /* Wait for first node ID advertisment to finish, then scan for + * second node ID and verify that random field has changed + */ + + k_sleep(K_SECONDS(65)); + ASSERT_TRUE( + wait_for_beacon(priv_scan_cb, 1, pp_beacon_check, &ctx)); + ASSERT_FALSE(beacon.pp_random == last_pp_random); + + PASS(); +} + +static void test_tx_priv_multi_net_id(void) +{ + tx_priv_common_init(PP_MULT_NET_ID_WAIT_TIME); + + /* TODO: This should be removed as soon as + * SNB/proxy service advertising issue has + * been resolved. + */ + bt_mesh_beacon_set(false); + + /* Add second network */ + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_secondary), + "Failed to add second subnet"); + + /* Enable private GATT proxy */ + ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to set private gatt proxy"); + + PASS(); +} + +static void test_rx_priv_multi_net_id(void) +{ + rx_priv_common_init(PP_MULT_NET_ID_WAIT_TIME); + pp_netkey_ctx_init(&pp_net1); + + struct priv_test_ctx ctx = { + .beacon_type = BEACON_TYPE_PRIVATE_NET_ID, + .node_id_addr = NULL, + }; + + uint16_t itr = 4; + static uint8_t old_idx = 0xff; + static struct { + struct pp_netkey_ctx *net; + uint16_t recv_cnt; + int64_t start; + } net_ctx[2] = { + {.net = &pp_net0}, + + {.net = &pp_net1}, + }; + + while (itr) { + /* Scan for net ID from both networks */ + ASSERT_TRUE(wait_for_beacon(priv_scan_cb, 2, NULL, &ctx)); + + for (size_t i = 0; i < ARRAY_SIZE(net_ctx); i++) { + if (beacon.pp_hash == + pp_hash_calc(net_ctx[i].net, beacon.pp_random, NULL)) { + if (old_idx == 0xff) { + /* Received first Net ID advertisment */ + old_idx = i; + net_ctx[i].start = k_uptime_get(); + net_ctx[i].recv_cnt++; + } else if (old_idx != i) { + /* Received Net ID adv for new subnet */ + + /* Verify last Net ID adv result */ + ASSERT_IN_RANGE(k_uptime_get() - net_ctx[old_idx].start, + MAX_TIMEOUT - 1000, MAX_TIMEOUT); + ASSERT_IN_RANGE(net_ctx[old_idx].recv_cnt, 9, 10); + net_ctx[old_idx].recv_cnt = 0; + old_idx = i; + + /* The test ends when all itterations are completed */ + itr--; + + net_ctx[i].start = k_uptime_get(); + net_ctx[i].recv_cnt++; + } else { + /* Received another Net ID adv from same subnet*/ + net_ctx[i].recv_cnt++; + } + + break; + } + } + } + + PASS(); +} +#endif + #endif /* CONFIG_BT_MESH_V1d1 */ #define TEST_CASE(role, name, description) \ @@ -1396,6 +1722,11 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(tx, priv_adv, "Private Beacon: advertise Private Beacons"), TEST_CASE(tx, priv_invalid, "Private Beacon: advertise invalid beacons"), TEST_CASE(tx, priv_interleave, "Private Beacon: advertise interleaved with SNB"), +#if CONFIG_BT_MESH_GATT_PROXY + TEST_CASE(tx, priv_net_id, "Private Proxy: advertise Net ID"), + TEST_CASE(tx, priv_node_id, "Private Proxy: advertise Node ID"), + TEST_CASE(tx, priv_multi_net_id, "Private Proxy: advertise multiple Net ID"), +#endif #endif TEST_CASE(rx, on_iv_update, "Beacon: receive with IV update flag"), @@ -1408,6 +1739,11 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(rx, priv_adv, "Private Beacon: verify random regeneration"), TEST_CASE(rx, priv_invalid, "Private Beacon: receive invalid beacons"), TEST_CASE(rx, priv_interleave, "Private Beacon: interleaved with SNB"), +#if CONFIG_BT_MESH_GATT_PROXY + TEST_CASE(rx, priv_net_id, "Private Proxy: scan for Net ID"), + TEST_CASE(rx, priv_node_id, "Private Proxy: scan for Node ID"), + TEST_CASE(rx, priv_multi_net_id, "Private Proxy: scan for multiple Net ID"), +#endif #endif BSTEST_END_MARKER }; diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id.sh new file mode 100755 index 00000000000..02fcf03c001 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Private Net ID advertisment +# +# Test procedure: +# 0. TX device disables GATT proxy and enables Private GATT proxy. +# 1. RX device enables scanner and scans for Net ID advertisments. +# 2. RX device scans for a single Net ID advertisment and stores +# the random field of that message. +# 3. RX device waits for 10 minutes. +# 4. RX device scans for a another Private Net ID advertisement and compares +# the random field of that message with the random field +# of the previous Private Net ID. +# 5. Test passes if the random field of the two Private Net ID advertisements +# are NOT equal. + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf +RunTest mesh_priv_proxy_net_id \ + beacon_tx_priv_net_id \ + beacon_rx_priv_net_id + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_priv_proxy_net_id \ + beacon_tx_priv_net_id \ + beacon_rx_priv_net_id diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id_multi.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id_multi.sh new file mode 100755 index 00000000000..9d89b5af36c --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_net_id_multi.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Private Net ID advertisment with multiple networks +# +# Test procedure: +# 0. TX device disables GATT proxy, adds a second network to the device +# and enables Private GATT proxy. +# 1. RX device enables scanner and scans for Private Net ID advertisements from +# both of the networks. +# 2. Test passes when RX device verifies reception of one Private Net ID +# advertisemen from each of the networks within the given time +# limit. + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf +RunTest mesh_priv_proxy_net_id_multi \ + beacon_tx_priv_multi_net_id \ + beacon_rx_priv_multi_net_id + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_priv_proxy_net_id_multi \ + beacon_tx_priv_multi_net_id \ + beacon_rx_priv_multi_net_id diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_node_id.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_node_id.sh new file mode 100755 index 00000000000..2aff351bd78 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_node_id.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Private Node ID advertisment +# +# Test procedure: +# 0. TX device disables GATT proxy and enables the Private Node +# Identity state for the network. Then it waits for the +# advertisment to complete. +# 1. RX device enables scanner and scans for Private Node ID advertisements. +# 2. RX device scans for a single Private Node ID advertisement and stores +# the random field of that message. Then it waits for the +# advertisement to complete. +# 3. TC device verifies that the previous advertisement is finished +# and enables the Private Node Identity state for the network +# again. +# 4. RX device scans for a another Private Node ID advertisement and compares +# the random field of that message with the random field +# of the previous Net ID. +# 5. Test passes if the random field of the two Private Node ID advertisements +# are NOT equal. + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf +RunTest mesh_priv_proxy_node_id \ + beacon_tx_priv_node_id \ + beacon_rx_priv_node_id + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_priv_proxy_node_id \ + beacon_tx_priv_node_id \ + beacon_rx_priv_node_id From 147796b36f7af410ab5e11e8d965e4875af84d56 Mon Sep 17 00:00:00 2001 From: Fredrik Danebjer Date: Thu, 31 Aug 2023 10:38:46 +0200 Subject: [PATCH 1145/4498] Bluetooth: Audio: Change CSIP notification to use Atomic flags Reformated csip_set_member to use atomic flags for notifications instead of a pending notification array. This better conforms the style of the code to how its done in other LE Audio services. Signed-off-by: Fredrik Danebjer --- subsys/bluetooth/audio/csip_internal.h | 14 --- subsys/bluetooth/audio/csip_set_member.c | 133 +++++++++++++---------- 2 files changed, 76 insertions(+), 71 deletions(-) diff --git a/subsys/bluetooth/audio/csip_internal.h b/subsys/bluetooth/audio/csip_internal.h index deccab6815d..cfbd1974e68 100644 --- a/subsys/bluetooth/audio/csip_internal.h +++ b/subsys/bluetooth/audio/csip_internal.h @@ -16,20 +16,6 @@ #define BT_CSIP_RELEASE_VALUE 0x01 #define BT_CSIP_LOCK_VALUE 0x02 -struct csip_pending_notifications { - bt_addr_le_t addr; - bool pending; - bool active; - -/* Since there's a 1-to-1 connection between bonded devices, and devices in - * the array containing this struct, if the security manager overwrites - * the oldest keys, we also overwrite the oldest entry - */ -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - uint32_t age; -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ -}; - struct bt_csip_set_sirk { uint8_t type; uint8_t value[BT_CSIP_SET_SIRK_SIZE]; diff --git a/subsys/bluetooth/audio/csip_set_member.c b/subsys/bluetooth/audio/csip_set_member.c index 2af43bd4233..d32cdfc5285 100644 --- a/subsys/bluetooth/audio/csip_set_member.c +++ b/subsys/bluetooth/audio/csip_set_member.c @@ -39,6 +39,27 @@ LOG_MODULE_REGISTER(bt_csip_set_member, CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL); +enum { + FLAG_ACTIVE, + FLAG_SET_MEMBER_LOCK, + FLAG_NUM, +}; + +struct csip_client { + bt_addr_le_t addr; + +/* Since there's a 1-to-1 connection between bonded devices, and devices in + * the array containing this struct, if the security manager overwrites + * the oldest keys, we also overwrite the oldest entry + */ +#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) + uint32_t age; +#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ + + /* Pending notification flags */ + ATOMIC_DEFINE(flags, FLAG_NUM); +}; + struct bt_csip_set_member_svc_inst { struct bt_csip_set_sirk set_sirk; uint8_t set_size; @@ -48,7 +69,7 @@ struct bt_csip_set_member_svc_inst { struct k_work_delayable set_lock_timer; bt_addr_le_t lock_client_addr; struct bt_gatt_service *service_p; - struct csip_pending_notifications pend_notify[CONFIG_BT_MAX_PAIRED]; + struct csip_client clients[CONFIG_BT_MAX_PAIRED]; #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) uint32_t age_counter; #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ @@ -95,14 +116,14 @@ static void notify_client(struct bt_conn *conn, void *data) notify_lock_value(svc_inst, conn); - for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (pend_notify->pending && - bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { - pend_notify->pending = false; + if (atomic_test_bit(client->flags, FLAG_SET_MEMBER_LOCK) && + bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { + atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); break; } } @@ -119,18 +140,18 @@ static void notify_clients(struct bt_csip_set_member_svc_inst *svc_inst, /* Mark all bonded devices as pending notifications, and clear those * that are notified in `notify_client` */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (pend_notify->active) { + if (atomic_test_bit(client->flags, FLAG_ACTIVE)) { if (excluded_client != NULL && - bt_addr_le_eq(bt_conn_get_dst(excluded_client), &pend_notify->addr)) { + bt_addr_le_eq(bt_conn_get_dst(excluded_client), &client->addr)) { continue; } - pend_notify->pending = true; + atomic_set_bit(client->flags, FLAG_SET_MEMBER_LOCK); } } @@ -474,15 +495,15 @@ static void csip_security_changed(struct bt_conn *conn, bt_security_t level, for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; - for (int j = 0; j < ARRAY_SIZE(svc_inst->pend_notify); j++) { - struct csip_pending_notifications *pend_notify; + for (int j = 0; j < ARRAY_SIZE(svc_inst->clients); j++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[j]; + client = &svc_inst->clients[i]; - if (pend_notify->pending && - bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { + if (atomic_test_bit(client->flags, FLAG_SET_MEMBER_LOCK) && + bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { notify_lock_value(svc_inst, conn); - pend_notify->pending = false; + atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); break; } } @@ -509,13 +530,13 @@ static void handle_csip_disconnect(struct bt_csip_set_member_svc_inst *svc_inst, /* Check if the disconnected device once was bonded and stored * here as a bonded device */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { - (void)memset(pend_notify, 0, sizeof(*pend_notify)); + if (bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { + (void)memset(client, 0, sizeof(*client)); break; } } @@ -536,54 +557,54 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in struct bt_conn *conn) { /* Check if already in list, and do nothing if it is */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (pend_notify->active && - bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { + if (atomic_test_bit(client->flags, FLAG_ACTIVE) && + bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - pend_notify->age = svc_inst->age_counter++; + client->age = svc_inst->age_counter++; #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ return; } } - /* Copy addr to list over devices to save notifications for */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + /* Else add the device */ + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (!pend_notify->active) { - bt_addr_le_copy(&pend_notify->addr, - bt_conn_get_dst(conn)); - pend_notify->active = true; + if (!atomic_test_bit(client->flags, FLAG_ACTIVE)) { + atomic_set_bit(client->flags, FLAG_ACTIVE); + memcpy(&client->addr, bt_conn_get_dst(conn), sizeof(bt_addr_le_t)); #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - pend_notify->age = svc_inst->age_counter++; + client->age = svc_inst->age_counter++; #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ + return; } } #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - struct csip_pending_notifications *oldest; + struct csip_client *oldest; - oldest = &svc_inst->pend_notify[0]; + oldest = &svc_inst->clients[0]; - for (int i = 1; i < ARRAY_SIZE(svc_inst->pend_notify); i++) { - struct csip_pending_notifications *pend_notify; + for (int i = 1; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; - pend_notify = &svc_inst->pend_notify[i]; + client = &svc_inst->clients[i]; - if (pend_notify->age < oldest->age) { - oldest = pend_notify; + if (client->age < oldest->age) { + oldest = client; } } (void)memset(oldest, 0, sizeof(*oldest)); bt_addr_le_copy(&oldest->addr, &conn->le.dst); - oldest->active = true; + atomic_set_bit(client->flags, FLAG_ACTIVE); oldest->age = svc_inst->age_counter++; #else LOG_WRN("Could not add device to pending notification list"); @@ -596,9 +617,9 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) /** * If a pairing is complete for a bonded device, then we * 1) Store the connection pointer to later validate SIRK encryption - * 2) Check if the device is already in the `pend_notify`, and if it is + * 2) Check if the device is already in the `clients`, and if it is * not, then we - * 3) Check if there's room for another device in the `pend_notify` + * 3) Check if there's room for another device in the `clients` * array. If there are no more room for a new device, then * 4) Either we ignore this new device (bad luck), or we overwrite * the oldest entry, following the behavior of the key storage. @@ -621,15 +642,13 @@ static void csip_bond_deleted(uint8_t id, const bt_addr_le_t *peer) for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; - for (int j = 0; j < ARRAY_SIZE(svc_inst->pend_notify); j++) { - struct csip_pending_notifications *pend_notify; - - pend_notify = &svc_inst->pend_notify[j]; + for (int j = 0; j < ARRAY_SIZE(svc_inst->clients); j++) { - if (pend_notify->active && - bt_addr_le_eq(peer, &pend_notify->addr)) { - (void)memset(pend_notify, 0, - sizeof(*pend_notify)); + /* Check if match, and if active, if so, reset */ + if (atomic_test_bit(svc_inst->clients[i].flags, FLAG_ACTIVE) && + bt_addr_le_eq(peer, &svc_inst->clients[i].addr)) { + atomic_clear(svc_inst->clients[i].flags); + (void)memset(&svc_inst->clients[i].addr, 0, sizeof(bt_addr_le_t)); break; } } From 078b00b15534a53691ee9b75e6056339d4e1d1b6 Mon Sep 17 00:00:00 2001 From: Fredrik Danebjer Date: Fri, 22 Sep 2023 08:57:36 +0200 Subject: [PATCH 1146/4498] Bluetooth: Audio: Add resend mechanic to CSIP notifications Added retry mechanic to CSIP notifications by adding them into system workqueue. Bookkeeping is done for notifications for all clients, and potentially disconncted clients will also receive notifications on reconnect. This also adds mechanic to restore the local clients list upon registration of the service, as well as BSIMs to test notify on reconnect. Signed-off-by: Fredrik Danebjer --- subsys/bluetooth/audio/csip_set_coordinator.c | 7 +- subsys/bluetooth/audio/csip_set_member.c | 183 +++++++++++++++--- .../audio/src/csip_notify_client_test.c | 133 +++++++++++++ .../audio/src/csip_notify_server_test.c | 135 +++++++++++++ tests/bsim/bluetooth/audio/src/main.c | 4 + .../audio/test_scripts/csip_notify.sh | 26 +++ 6 files changed, 459 insertions(+), 29 deletions(-) create mode 100644 tests/bsim/bluetooth/audio/src/csip_notify_client_test.c create mode 100644 tests/bsim/bluetooth/audio/src/csip_notify_server_test.c create mode 100755 tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh diff --git a/subsys/bluetooth/audio/csip_set_coordinator.c b/subsys/bluetooth/audio/csip_set_coordinator.c index 7d506e72580..36e5803b45c 100644 --- a/subsys/bluetooth/audio/csip_set_coordinator.c +++ b/subsys/bluetooth/audio/csip_set_coordinator.c @@ -1214,7 +1214,8 @@ static void csip_set_coordinator_lock_state_read_cb(int err, bool locked) if (err || locked) { cur_member = active.members[active.members_handled]; - } else if (!active.oap_cb(info, active.members, active.members_count)) { + } else if (active.oap_cb == NULL || !active.oap_cb(info, active.members, + active.members_count)) { err = -ECANCELED; } @@ -1575,8 +1576,8 @@ static int bt_csip_set_coordinator_get_lock_state( * so we can just initiate the ordered access procedure (oap) callback directly * here. */ - - if (!active.oap_cb(active.info, active.members, active.members_count)) { + if (active.oap_cb == NULL || + !active.oap_cb(active.info, active.members, active.members_count)) { err = -ECANCELED; } diff --git a/subsys/bluetooth/audio/csip_set_member.c b/subsys/bluetooth/audio/csip_set_member.c index d32cdfc5285..1d1b0c57fea 100644 --- a/subsys/bluetooth/audio/csip_set_member.c +++ b/subsys/bluetooth/audio/csip_set_member.c @@ -39,7 +39,7 @@ LOG_MODULE_REGISTER(bt_csip_set_member, CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL); -enum { +enum csip_pending_notify_flag { FLAG_ACTIVE, FLAG_SET_MEMBER_LOCK, FLAG_NUM, @@ -78,6 +78,12 @@ struct bt_csip_set_member_svc_inst { static struct bt_csip_set_member_svc_inst svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT]; static bt_addr_le_t server_dummy_addr; /* 0'ed address */ +static atomic_t notify_in_progress; + +static void deferred_nfy_work_handler(struct k_work *work); + +static K_WORK_DEFINE(deferred_nfy_work, deferred_nfy_work_handler); + struct csip_notify_foreach { struct bt_conn *excluded_client; struct bt_csip_set_member_svc_inst *svc_inst; @@ -95,13 +101,63 @@ static bool is_last_client_to_write(const struct bt_csip_set_member_svc_inst *sv } } -static void notify_lock_value(const struct bt_csip_set_member_svc_inst *svc_inst, +static void csip_gatt_notify_complete_cb(struct bt_conn *conn, void *user_data) +{ + /* Notification done, clear bit and reschedule work */ + atomic_clear(¬ify_in_progress); + k_work_submit(&deferred_nfy_work); +} + +static int csip_gatt_notify_set_lock(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *data, + uint16_t len) +{ + int err; + struct bt_gatt_notify_params params; + + memset(¶ms, 0, sizeof(params)); + params.uuid = BT_UUID_CSIS_SET_LOCK; + params.attr = attr; + params.data = data; + params.len = len; + params.func = csip_gatt_notify_complete_cb; + + /* Mark notification in progress */ + atomic_set(¬ify_in_progress, 1); + + err = bt_gatt_notify_cb(conn, ¶ms); + if (err != 0) { + atomic_clear(¬ify_in_progress); + + if (err != -ENOTCONN) { + return err; + } + } + + return 0; +} + +static void csip_set_notify_bit(struct bt_csip_set_member_svc_inst *svc_inst, + enum csip_pending_notify_flag flag) +{ + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { + struct csip_client *client; + + client = &svc_inst->clients[i]; + if (atomic_test_bit(client->flags, FLAG_ACTIVE)) { + atomic_set_bit(client->flags, flag); + } + } +} + +static int notify_lock_value(const struct bt_csip_set_member_svc_inst *svc_inst, struct bt_conn *conn) { - bt_gatt_notify_uuid(conn, BT_UUID_CSIS_SET_LOCK, - svc_inst->service_p->attrs, - &svc_inst->set_lock, - sizeof(svc_inst->set_lock)); + LOG_DBG(""); + return csip_gatt_notify_set_lock(conn, svc_inst->service_p->attrs, + &svc_inst->set_lock, + sizeof(svc_inst->set_lock)); } static void notify_client(struct bt_conn *conn, void *data) @@ -114,17 +170,26 @@ static void notify_client(struct bt_conn *conn, void *data) return; } - notify_lock_value(svc_inst, conn); - for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { struct csip_client *client; client = &svc_inst->clients[i]; if (atomic_test_bit(client->flags, FLAG_SET_MEMBER_LOCK) && bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { - atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); - break; + /* First try to send the notification directly, and if it fails add it + * to system workqueue for retry. We do it like this here as the client + * wants the lock notification asap to begin ordered access procedure + */ + if (notify_lock_value(svc_inst, conn) != 0) { + csip_set_notify_bit(svc_inst, FLAG_SET_MEMBER_LOCK); + k_work_submit(&deferred_nfy_work); + } else { + atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); + break; + } } } } @@ -140,7 +205,7 @@ static void notify_clients(struct bt_csip_set_member_svc_inst *svc_inst, /* Mark all bonded devices as pending notifications, and clear those * that are notified in `notify_client` */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { struct csip_client *client; client = &svc_inst->clients[i]; @@ -492,18 +557,17 @@ static void csip_security_changed(struct bt_conn *conn, bt_security_t level, return; } - for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; - for (int j = 0; j < ARRAY_SIZE(svc_inst->clients); j++) { + for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) { struct csip_client *client; client = &svc_inst->clients[i]; if (atomic_test_bit(client->flags, FLAG_SET_MEMBER_LOCK) && bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { - notify_lock_value(svc_inst, conn); - atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); + k_work_submit(&deferred_nfy_work); break; } } @@ -530,7 +594,7 @@ static void handle_csip_disconnect(struct bt_csip_set_member_svc_inst *svc_inst, /* Check if the disconnected device once was bonded and stored * here as a bonded device */ - for (int i = 0; i < ARRAY_SIZE(svc_inst->clients); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) { struct csip_client *client; client = &svc_inst->clients[i]; @@ -547,7 +611,7 @@ static void csip_disconnected(struct bt_conn *conn, uint8_t reason) LOG_DBG("Disconnected: %s (reason %u)", bt_addr_le_str(bt_conn_get_dst(conn)), reason); if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { - for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { handle_csip_disconnect(&svc_insts[i], conn); } } @@ -584,6 +648,8 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in client->age = svc_inst->age_counter++; #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ + /* Send out all pending notifications */ + k_work_submit(&deferred_nfy_work); return; } } @@ -593,7 +659,7 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in oldest = &svc_inst->clients[0]; - for (int i = 1; i < ARRAY_SIZE(svc_inst->clients); i++) { + for (int i = 1U; i < ARRAY_SIZE(svc_inst->clients); i++) { struct csip_client *client; client = &svc_inst->clients[i]; @@ -604,7 +670,7 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in } (void)memset(oldest, 0, sizeof(*oldest)); bt_addr_le_copy(&oldest->addr, &conn->le.dst); - atomic_set_bit(client->flags, FLAG_ACTIVE); + atomic_set_bit(oldest->flags, FLAG_ACTIVE); oldest->age = svc_inst->age_counter++; #else LOG_WRN("Could not add device to pending notification list"); @@ -632,21 +698,21 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) return; } - for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { handle_csip_auth_complete(&svc_insts[i], conn); } } static void csip_bond_deleted(uint8_t id, const bt_addr_le_t *peer) { - for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; - for (int j = 0; j < ARRAY_SIZE(svc_inst->clients); j++) { + for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) { /* Check if match, and if active, if so, reset */ if (atomic_test_bit(svc_inst->clients[i].flags, FLAG_ACTIVE) && - bt_addr_le_eq(peer, &svc_inst->clients[i].addr)) { + bt_addr_le_eq(peer, &svc_inst->clients[i].addr)) { atomic_clear(svc_inst->clients[i].flags); (void)memset(&svc_inst->clients[i].addr, 0, sizeof(bt_addr_le_t)); break; @@ -765,10 +831,72 @@ static void remove_csis_char(const struct bt_uuid *uuid, struct bt_gatt_service __ASSERT(false, "Failed to remove CSIS char %s", bt_uuid_str(uuid)); } +static void notify_cb(struct bt_conn *conn, void *data) +{ + struct bt_conn_info info; + int err = 0; + + err = bt_conn_get_info(conn, &info); + if (err != 0) { + return; + } + + if (info.state != BT_CONN_STATE_CONNECTED) { + /* Not connected */ + LOG_DBG("Not connected"); + return; + } + + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { + struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; + struct csip_client *client = &svc_inst->clients[bt_conn_index(conn)]; + + if (atomic_test_bit(client->flags, FLAG_SET_MEMBER_LOCK)) { + err = notify_lock_value(svc_inst, conn); + if (!err) { + atomic_clear_bit(client->flags, FLAG_SET_MEMBER_LOCK); + } + } + } +} + +static void deferred_nfy_work_handler(struct k_work *work) +{ + /* Check if we have unverified notifications in progress */ + if (atomic_get(¬ify_in_progress)) { + return; + } + + bt_conn_foreach(BT_CONN_TYPE_LE, notify_cb, NULL); +} + +static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void *data) +{ + + for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) { + struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i]; + + for (size_t j = 1U; j < ARRAY_SIZE(svc_inst->clients); i++) { + /* Check if device is registered, it not, add it */ + if (!atomic_test_bit(svc_inst->clients[j].flags, FLAG_ACTIVE)) { + char addr_str[BT_ADDR_LE_STR_LEN]; + + atomic_set_bit(svc_inst->clients[j].flags, FLAG_ACTIVE); + memcpy(&svc_inst->clients[j].addr, &info->addr, + sizeof(bt_addr_le_t)); + bt_addr_le_to_str(&svc_inst->clients[j].addr, addr_str, + sizeof(addr_str)); + LOG_DBG("Added %s to bonded list\n", addr_str); + return; + } + } + } +} + int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param, struct bt_csip_set_member_svc_inst **svc_inst) { - static bool callbacks_registered; + static bool first_register; static uint8_t instance_cnt; struct bt_csip_set_member_svc_inst *inst; int err; @@ -792,11 +920,14 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param * inst->service_p = &csip_set_member_service_list[instance_cnt]; instance_cnt++; - if (!callbacks_registered) { + if (!first_register) { bt_conn_cb_register(&conn_callbacks); bt_conn_auth_info_cb_register(&auth_callbacks); - callbacks_registered = true; + /* Restore bonding list */ + bt_foreach_bond(BT_ID_DEFAULT, add_bonded_addr_to_client_list, NULL); + + first_register = true; } /* The removal of the optional characteristics should be done in reverse order of the order diff --git a/tests/bsim/bluetooth/audio/src/csip_notify_client_test.c b/tests/bsim/bluetooth/audio/src/csip_notify_client_test.c new file mode 100644 index 00000000000..2ccad4046ba --- /dev/null +++ b/tests/bsim/bluetooth/audio/src/csip_notify_client_test.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023 Demant A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "common.h" +#include "common/bt_str.h" + +extern enum bst_result_t bst_result; + +CREATE_FLAG(flag_csip_set_lock_discovered); +CREATE_FLAG(flag_all_notifications_received); + +static void csip_discover_cb(struct bt_conn *conn, + const struct bt_csip_set_coordinator_set_member *member, + int err, size_t set_count) +{ + if (err != 0) { + printk("CSIP Lock Discover failed (err = %d)\n", err); + return; + } + + if (member->insts->info.lockable) { + SET_FLAG(flag_csip_set_lock_discovered); + } +} + +static void csip_lock_changed(struct bt_csip_set_coordinator_csis_inst *inst, bool locked) +{ + SET_FLAG(flag_all_notifications_received); +} + +static struct bt_csip_set_coordinator_cb cbs = { + .lock_changed = csip_lock_changed, + .discover = csip_discover_cb, +}; + +static void test_main(void) +{ + int err; + + printk("Enabling Bluetooth\n"); + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth enable failed (err %d)\n", err); + return; + } + + bt_le_scan_cb_register(&common_scan_cb); + bt_csip_set_coordinator_register_cb(&cbs); + + printk("Starting scan\n"); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + if (err != 0) { + FAIL("Could not start scanning (err %d)\n", err); + return; + } + + printk("Waiting for connect\n"); + WAIT_FOR_FLAG(flag_connected); + + printk("Raising security\n"); + err = bt_conn_set_security(default_conn, BT_SECURITY_L2); + if (err) { + FAIL("Failed to ser security level %d (err %d)\n", BT_SECURITY_L2, err); + return; + } + + printk("Starting Discovery\n"); + bt_csip_set_coordinator_discover(default_conn); + WAIT_FOR_FLAG(flag_csip_set_lock_discovered); + + printk("Waiting for all notifications to be received\n"); + + WAIT_FOR_FLAG(flag_all_notifications_received); + + /* Disconnect and wait for server to advertise again (after notifications are triggered) */ + bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + UNSET_FLAG(flag_all_notifications_received); + UNSET_FLAG(flag_csip_set_lock_discovered); + + printk("Waiting for disconnect\n"); + WAIT_FOR_UNSET_FLAG(flag_connected); + + printk("Starting scan\n"); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + if (err != 0) { + FAIL("Could not start scanning (err %d)\n", err); + return; + } + + printk("Waiting for reconnect\n"); + WAIT_FOR_FLAG(flag_connected); + + printk("Raising security\n"); + err = bt_conn_set_security(default_conn, BT_SECURITY_L2); + if (err) { + FAIL("Failed to ser security level %d (err %d)\n", BT_SECURITY_L2, err); + return; + } + + printk("Starting Discovery\n"); + bt_csip_set_coordinator_discover(default_conn); + WAIT_FOR_FLAG(flag_csip_set_lock_discovered); + + printk("Waiting for all notifications to be received\n"); + WAIT_FOR_FLAG(flag_all_notifications_received); + + bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + WAIT_FOR_UNSET_FLAG(flag_connected); + + PASS("CSIP Notify client Passed\n"); +} + +static const struct bst_test_instance test_csip_notify_client[] = { + { + .test_id = "csip_notify_client", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_csip_notify_client_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_csip_notify_client); +} diff --git a/tests/bsim/bluetooth/audio/src/csip_notify_server_test.c b/tests/bsim/bluetooth/audio/src/csip_notify_server_test.c new file mode 100644 index 00000000000..ec94a320ffd --- /dev/null +++ b/tests/bsim/bluetooth/audio/src/csip_notify_server_test.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023 Demant A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "common.h" + +extern enum bst_result_t bst_result; + +static struct bt_csip_set_member_svc_inst *svc_inst; + +static bool is_peer_subscribed(struct bt_conn *conn) +{ + struct bt_gatt_attr *attr; + + attr = bt_gatt_find_by_uuid(NULL, 0, BT_UUID_CSIS_SET_LOCK); + if (!attr) { + printk("No BT_UUID_PACS_SNK attribute found\n"); + return false; + } + + return bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY); +} + +static void csip_set_member_lock_changed_cb(struct bt_conn *conn, + struct bt_csip_set_member_svc_inst *svc_inst, + bool locked) +{ + printk("Client %p %s the lock\n", conn, locked ? "locked" : "released"); +} + +static struct bt_csip_set_member_cb csip_cb = { + .lock_changed = csip_set_member_lock_changed_cb, +}; + +static void test_main(void) +{ + int err; + const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + }; + struct bt_csip_set_member_register_param csip_params = { + .set_size = 1, + .rank = 1, + .lockable = true, + .cb = &csip_cb, + }; + + printk("Enabling Bluetooth\n"); + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth enable failed (err %d)\n", err); + return; + } + + printk("Registering CSIP Set Member\n"); + + err = bt_cap_acceptor_register(&csip_params, &svc_inst); + if (err != 0) { + printk("Failed to register csip\n"); + return; + } + + printk("Start Advertising\n"); + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); + if (err != 0) { + FAIL("Advertising failed to start (err %d)\n", err); + return; + } + + printk("Waiting to be connected\n"); + WAIT_FOR_FLAG(flag_connected); + printk("Connected\n"); + printk("Waiting to be subscribed\n"); + + while (!is_peer_subscribed(default_conn)) { + (void)k_sleep(K_MSEC(10)); + } + printk("Subscribed\n"); + + err = bt_csip_set_member_lock(svc_inst, true, false); + if (err != 0) { + FAIL("Failed to set lock (err %d)\n", err); + return; + } + + /* Now wait for client to disconnect, then stop adv so it does not reconnect */ + printk("Wait for client disconnect\n"); + WAIT_FOR_UNSET_FLAG(flag_connected); + printk("Client disconnected\n"); + + err = bt_le_adv_stop(); + if (err != 0) { + FAIL("Advertising failed to stop (err %d)\n", err); + return; + } + + /* Trigger changes while device is disconnected */ + err = bt_csip_set_member_lock(svc_inst, false, false); + if (err != 0) { + FAIL("Failed to set lock (err %d)\n", err); + return; + } + + printk("Start Advertising\n"); + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); + if (err != 0) { + FAIL("Advertising failed to start (err %d)\n", err); + return; + } + + WAIT_FOR_FLAG(flag_connected); + WAIT_FOR_UNSET_FLAG(flag_connected); + + PASS("CSIP Notify Server passed\n"); +} + +static const struct bst_test_instance test_csip_notify_server[] = { + { + .test_id = "csip_notify_server", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_csip_notify_server_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_csip_notify_server); +} diff --git a/tests/bsim/bluetooth/audio/src/main.c b/tests/bsim/bluetooth/audio/src/main.c index 95df4844002..f4ef6294545 100644 --- a/tests/bsim/bluetooth/audio/src/main.c +++ b/tests/bsim/bluetooth/audio/src/main.c @@ -35,6 +35,8 @@ extern struct bst_test_list *test_tmap_client_install(struct bst_test_list *test extern struct bst_test_list *test_tmap_server_install(struct bst_test_list *tests); extern struct bst_test_list *test_pacs_notify_client_install(struct bst_test_list *tests); extern struct bst_test_list *test_pacs_notify_server_install(struct bst_test_list *tests); +extern struct bst_test_list *test_csip_notify_client_install(struct bst_test_list *tests); +extern struct bst_test_list *test_csip_notify_server_install(struct bst_test_list *tests); bst_test_install_t test_installers[] = { test_vcp_install, @@ -66,6 +68,8 @@ bst_test_install_t test_installers[] = { test_tmap_client_install, test_pacs_notify_client_install, test_pacs_notify_server_install, + test_csip_notify_client_install, + test_csip_notify_server_install, NULL }; diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh new file mode 100755 index 00000000000..7f1d8a48cd2 --- /dev/null +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2023 Demant A/S +# +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +SIMULATION_ID="csip_notify" +VERBOSITY_LEVEL=2 +EXECUTE_TIMEOUT=200 + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n======== Running CSIP Notify test =========\n\n" + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_notify_server -rs=24 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_notify_client -rs=46 + +Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs From c2a13a0bec20f18d8f643c1f6e7a8e666da2c6ac Mon Sep 17 00:00:00 2001 From: Fredrik Danebjer Date: Mon, 25 Sep 2023 14:28:41 +0200 Subject: [PATCH 1147/4498] Bluetooth: Audio: Make CSIP delete bonds in cache locally This change from using the mechanic of CONFIG_BT_KEYS_OVERWRITE_OLDEST to instead handle the bonding cache through bond_deleted. Signed-off-by: Fredrik Danebjer --- subsys/bluetooth/audio/csip_set_member.c | 38 ------------------------ 1 file changed, 38 deletions(-) diff --git a/subsys/bluetooth/audio/csip_set_member.c b/subsys/bluetooth/audio/csip_set_member.c index 1d1b0c57fea..b6bd487af82 100644 --- a/subsys/bluetooth/audio/csip_set_member.c +++ b/subsys/bluetooth/audio/csip_set_member.c @@ -48,14 +48,6 @@ enum csip_pending_notify_flag { struct csip_client { bt_addr_le_t addr; -/* Since there's a 1-to-1 connection between bonded devices, and devices in - * the array containing this struct, if the security manager overwrites - * the oldest keys, we also overwrite the oldest entry - */ -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - uint32_t age; -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ - /* Pending notification flags */ ATOMIC_DEFINE(flags, FLAG_NUM); }; @@ -70,9 +62,6 @@ struct bt_csip_set_member_svc_inst { bt_addr_le_t lock_client_addr; struct bt_gatt_service *service_p; struct csip_client clients[CONFIG_BT_MAX_PAIRED]; -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - uint32_t age_counter; -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ }; static struct bt_csip_set_member_svc_inst svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT]; @@ -628,9 +617,6 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in if (atomic_test_bit(client->flags, FLAG_ACTIVE) && bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) { -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - client->age = svc_inst->age_counter++; -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ return; } } @@ -644,9 +630,6 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in if (!atomic_test_bit(client->flags, FLAG_ACTIVE)) { atomic_set_bit(client->flags, FLAG_ACTIVE); memcpy(&client->addr, bt_conn_get_dst(conn), sizeof(bt_addr_le_t)); -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - client->age = svc_inst->age_counter++; -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ /* Send out all pending notifications */ k_work_submit(&deferred_nfy_work); @@ -654,28 +637,7 @@ static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_in } } -#if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) - struct csip_client *oldest; - - oldest = &svc_inst->clients[0]; - - for (int i = 1U; i < ARRAY_SIZE(svc_inst->clients); i++) { - struct csip_client *client; - - client = &svc_inst->clients[i]; - - if (client->age < oldest->age) { - oldest = client; - } - } - (void)memset(oldest, 0, sizeof(*oldest)); - bt_addr_le_copy(&oldest->addr, &conn->le.dst); - atomic_set_bit(oldest->flags, FLAG_ACTIVE); - oldest->age = svc_inst->age_counter++; -#else LOG_WRN("Could not add device to pending notification list"); -#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ - } static void auth_pairing_complete(struct bt_conn *conn, bool bonded) From 1ab007a2ba01bf5888eb13e700c4ecd526602f60 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 21 Sep 2023 13:18:19 +0200 Subject: [PATCH 1148/4498] Bluetooth: Controller: Fix compile error when BT_CTLR_CENTRAL_SPACING=n Fix compile error when CONFIG_BT_CTLR_CENTRAL_SPACING is undefined. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index aac5d2057d2..19dec37c937 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -857,13 +857,19 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, cis->offset = cis_offset; #else /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ - if (IS_ENABLED(CONFIG_BT_CTLR_CENTRAL_SPACING) && (CONFIG_BT_CTLR_CENTRAL_SPACING > 0)) { + + if (false) { + +#if defined(CONFIG_BT_CTLR_CENTRAL_SPACING) + } else if (CONFIG_BT_CTLR_CENTRAL_SPACING > 0) { uint32_t cis_offset; cis_offset = MAX((HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + (EVENT_TICKER_RES_MARGIN_US << 1U) + cig->sync_delay - cis->sync_delay), *cis_offset_min); cis->offset = cis_offset; +#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING */ + } else { cis->offset = *cis_offset_min; } From 3c2b1f952cdf982635cccf2164a42aa3ef08f814 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 5 May 2023 10:15:02 +0530 Subject: [PATCH 1149/4498] Bluetooth: Controller: Add BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX Kconfig Add BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX Kconfig to allow the omit of EVENT_OVERHEAD_START_US and EVENT_OVERHEAD_END_US in the time reservation calculations. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 11 +++ .../bluetooth/controller/ll_sw/ull_central.c | 12 ++- .../controller/ll_sw/ull_central_iso.c | 18 +++-- subsys/bluetooth/controller/ll_sw/ull_conn.c | 18 +++-- .../bluetooth/controller/ll_sw/ull_conn_iso.c | 4 +- .../controller/ll_sw/ull_peripheral.c | 23 ++++-- .../controller/ll_sw/ull_peripheral_iso.c | 4 + tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 76 +++++++++++++++++++ tests/bluetooth/init/testcase.yaml | 10 +++ 9 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 tests/bluetooth/init/prj_ctlr_5_x_dbg.conf diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 4cd8e200b63..3f6f3c10382 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -632,6 +632,17 @@ config BT_CTLR_CENTRAL_RESERVE_MAX Note, currently this value is only used to space multiple central connections and not for actual ticker time reservations. +config BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX + bool "Reserve maximum event overhead in time reservations" + default y + help + Use radio event scheduling CPU time overhead in calculations of event + time reservations. + + If this option is disabled, then Peripheral ACL and Peripheral ISO + role will not include CPU time overhead. Other role will continue to + use CPU overheads in their event time reservations. + config BT_CTLR_SLOT_RESERVATION_UPDATE bool "Update event length reservation after PHY or DLE update" depends on (BT_CTLR_DATA_LENGTH || BT_CTLR_PHY) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index de14395f840..b189c65fa21 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -97,6 +97,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, uint16_t max_tx_time; uint16_t max_rx_time; memq_link_t *link; + uint32_t slot_us; uint8_t hop; int err; @@ -360,10 +361,13 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, #endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay_us + max_tx_time + EVENT_IFS_US + max_rx_time + - (EVENT_CLOCK_JITTER_US << 1)); + /* Calculate event time reservation */ + slot_us = max_tx_time + max_rx_time; + slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); + slot_us += ready_delay_us; + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); #if defined(CONFIG_BT_CTLR_PRIVACY) ull_filter_scan_update(filter_policy); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 19dec37c937..8c516826e06 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -864,9 +864,15 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, } else if (CONFIG_BT_CTLR_CENTRAL_SPACING > 0) { uint32_t cis_offset; - cis_offset = MAX((HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + - (EVENT_TICKER_RES_MARGIN_US << 1U) + cig->sync_delay - - cis->sync_delay), *cis_offset_min); + cis_offset = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + + (EVENT_TICKER_RES_MARGIN_US << 1U); + + cis_offset += cig->sync_delay - cis->sync_delay; + + if (cis_offset < *cis_offset_min) { + cis_offset = *cis_offset_min; + } + cis->offset = cis_offset; #endif /* CONFIG_BT_CTLR_CENTRAL_SPACING */ @@ -942,8 +948,9 @@ int ull_central_iso_cis_offset_get(uint16_t cis_handle, #endif /* CONFIG_BT_CTLR_CENTRAL_SPACING != 0 */ *cis_offset_min = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + - (EVENT_TICKER_RES_MARGIN_US << 1U) + - cig->sync_delay - cis->sync_delay; + (EVENT_TICKER_RES_MARGIN_US << 1U); + + *cis_offset_min += cig->sync_delay - cis->sync_delay; return 0; } @@ -984,7 +991,6 @@ static void mfy_cig_offset_get(void *param) offset_min_us += cig->sync_delay - cis->sync_delay; conn = ll_conn_get(cis->lll.acl_handle); - conn_interval_us = (uint32_t)conn->lll.interval * CONN_INT_UNIT_US; while (offset_min_us >= (conn_interval_us + PDU_CIS_OFFSET_MIN_US)) { offset_min_us -= conn_interval_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index a8d3178e020..9d78af7acc1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1233,7 +1233,7 @@ void ull_conn_done(struct node_rx_event_done *done) #if defined(CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE) #if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY) if (lll->evt_len_upd) { - uint32_t ready_delay, rx_time, tx_time, ticks_slot; + uint32_t ready_delay, rx_time, tx_time, ticks_slot, slot_us; lll->evt_len_upd = 0; #if defined(CONFIG_BT_CTLR_PHY) @@ -1257,10 +1257,18 @@ void ull_conn_done(struct node_rx_event_done *done) tx_time = PDU_DC_MAX_US(lll->dle.eff.max_tx_octets, 0); rx_time = PDU_DC_MAX_US(lll->dle.eff.max_rx_octets, 0); #endif /* CONFIG_BT_CTLR_PHY */ - ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay + EVENT_IFS_US + rx_time + tx_time + - (EVENT_CLOCK_JITTER_US << 1)); + + /* Calculate event time reservation */ + slot_us = tx_time + rx_time; + slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); + slot_us += ready_delay; + + if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX) || + !conn->lll.role) { + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + } + + ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); if (ticks_slot > conn->ull.ticks_slot) { ticks_slot_plus = ticks_slot - conn->ull.ticks_slot; } else { diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 46c00c305fe..2ec6a73b4a4 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -972,7 +972,9 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, /* Below is time reservation for sequential packing */ slot_us = cis->lll.sub_interval * cis->lll.nse; - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + } /* FIXME: How to use ready_delay_us in the time reservation? * i.e. when CISes use different PHYs? Is that even diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index 8b813fda9fd..5a34f787ec7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -89,6 +89,7 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, uint16_t max_rx_time; uint16_t win_offset; memq_link_t *link; + uint32_t slot_us; uint8_t chan_sel; void *node; @@ -360,10 +361,19 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, #endif /* !CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_PHY) - ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy_rx, 1); -#else - ready_delay_us = lll_radio_rx_ready_delay_get(0, 0); -#endif + ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy_rx, PHY_FLAGS_S8); +#else /* CONFIG_BT_CTLR_PHY */ + ready_delay_us = lll_radio_rx_ready_delay_get(0U, 0U); +#endif /* CONFIG_BT_CTLR_PHY */ + + /* Calculate event time reservation */ + slot_us = max_rx_time + max_tx_time; + slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); + slot_us += ready_delay_us; + + if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + } /* TODO: active_to_start feature port */ conn->ull.ticks_active_to_start = 0U; @@ -371,10 +381,7 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); conn->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay_us + max_rx_time + EVENT_IFS_US + max_tx_time + - (EVENT_CLOCK_JITTER_US << 1)); + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); ticks_slot_offset = MAX(conn->ull.ticks_active_to_start, conn->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index d2627502ac2..eeef778734b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -110,6 +110,10 @@ uint8_t ll_cis_accept(uint16_t handle) } else { cis_offset_min = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + (EVENT_TICKER_RES_MARGIN_US << 1U); + + if (!IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { + cis_offset_min += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; + } } /* Accept request */ diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf new file mode 100644 index 00000000000..df0d006a13e --- /dev/null +++ b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf @@ -0,0 +1,76 @@ +CONFIG_BT=y +CONFIG_BT_CTLR=y +CONFIG_BT_LL_SW_SPLIT=y +CONFIG_BT_CTLR_DUP_FILTER_LEN=16 +CONFIG_BT_CTLR_CONN_PARAM_REQ=y +CONFIG_BT_CTLR_LE_PING=y +CONFIG_BT_CTLR_PRIVACY=n +CONFIG_BT_CTLR_EXT_SCAN_FP=n +CONFIG_BT_DATA_LEN_UPDATE=n +CONFIG_BT_PHY_UPDATE=y +CONFIG_BT_CTLR_CHAN_SEL_2=y +CONFIG_BT_CTLR_MIN_USED_CHAN=y +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_PERIODIC=y +CONFIG_BT_CTLR_ADV_ISO=y +CONFIG_BT_CTLR_SYNC_PERIODIC=y +CONFIG_BT_CTLR_SYNC_ISO=y +CONFIG_BT_CTLR_CENTRAL_ISO=y +CONFIG_BT_CTLR_PERIPHERAL_ISO=y +CONFIG_BT_CTLR_DTM_HCI=y +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_PHY_2M=y +CONFIG_BT_CTLR_PHY_2M_NRF=y +CONFIG_BT_CTLR_PHY_CODED=y +CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y +CONFIG_BT_CTLR_LLL_PRIO=0 +CONFIG_BT_CTLR_ULL_HIGH_PRIO=1 +CONFIG_BT_CTLR_XTAL_ADVANCED=n +CONFIG_BT_CTLR_SCHED_ADVANCED=y +CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y +CONFIG_BT_CTLR_TIFS_HW=n +CONFIG_BT_CTLR_FAST_ENC=y +CONFIG_BT_CTLR_TX_RETRY_DISABLE=y +CONFIG_BT_CTLR_CONN_RSSI=y +CONFIG_BT_CTLR_ADV_INDICATION=y +CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y +CONFIG_BT_CTLR_SCAN_REQ_RSSI=y +CONFIG_BT_CTLR_SCAN_INDICATION=y +CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX=n +CONFIG_BT_CTLR_PROFILE_ISR=y +CONFIG_BT_CTLR_DEBUG_PINS=y +CONFIG_BT_CTLR_TEST=y +CONFIG_BT_HCI_VS_EXT=y +CONFIG_BT_HCI_MESH_EXT=n +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV=y +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_ISO_BROADCASTER=y +CONFIG_BT_ISO_SYNC_RECEIVER=y +CONFIG_BT_ISO_CENTRAL=y +CONFIG_BT_ISO_PERIPHERAL=y +CONFIG_BT_SMP=y +CONFIG_BT_SIGNING=y +CONFIG_BT_SMP_SC_ONLY=y +CONFIG_BT_TINYCRYPT_ECC=y +CONFIG_BT_USE_DEBUG_KEYS=y +CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_DEBUG_MONITOR_UART=y +CONFIG_BT_HCI_CORE_LOG_LEVEL_DBG=y +CONFIG_BT_CONN_LOG_LEVEL_DBG=y +CONFIG_BT_KEYS_LOG_LEVEL_DBG=y +CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y +CONFIG_BT_SMP_LOG_LEVEL_DBG=y +CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=y +CONFIG_BT_SMP_SELFTEST=y +CONFIG_BT_ATT_LOG_LEVEL_DBG=y +CONFIG_BT_GATT_LOG_LEVEL_DBG=y +CONFIG_BT_BREDR=n +CONFIG_DEBUG=y +CONFIG_FLASH=y +CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index c38f5bed69e..17d57ec9d47 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,6 +122,16 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 + bluetooth.init.test_ctlr_5_x_dbg: + extra_args: + - CONF_FILE=prj_ctlr_5_x_dbg.conf + - DTC_OVERLAY_FILE=pa_lna.overlay + platform_allow: + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 + integration_platforms: + - nrf52840dk_nrf52840 + - nrf52dk_nrf52832 bluetooth.init.test_ctlr_sw_switch_single_timer: extra_args: - CONF_FILE=prj_ctlr.conf From 707d1ed81941e425c77a9fd77db43a68d92f76be Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 26 Sep 2023 12:11:00 +0200 Subject: [PATCH 1150/4498] Bluetooth: Mesh: fix static oob setting According to specification it is possible to provide static oob value with any length. Mesh should trim or append\prepend by zeroes if it is longer\shorter than required value. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/prov_device.c | 11 ++++++++--- subsys/bluetooth/mesh/provisioner.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 20735f49fa5..a83ace178db 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -183,9 +183,14 @@ static void prov_start(const uint8_t *data) } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { - memcpy(bt_mesh_prov_link.auth + auth_size - bt_mesh_prov->static_val_len, - bt_mesh_prov->static_val, bt_mesh_prov->static_val_len); - memset(bt_mesh_prov_link.auth, 0, auth_size - bt_mesh_prov->static_val_len); + + uint8_t tail_size = bt_mesh_prov->static_val_len < auth_size + ? auth_size - bt_mesh_prov->static_val_len + : 0; + + memcpy(bt_mesh_prov_link.auth + tail_size, bt_mesh_prov->static_val, + tail_size ? bt_mesh_prov->static_val_len : auth_size); + memset(bt_mesh_prov_link.auth, 0, tail_size); } } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 25f0a299480..673e14578d2 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -254,8 +254,7 @@ static void prov_capabilities(const uint8_t *data) return; } - if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && - (caps.oob_type & BT_MESH_OOB_AUTH_REQUIRED)) { + if (caps.oob_type & BT_MESH_OOB_AUTH_REQUIRED) { bool oob_availability = caps.output_size > 0 || caps.input_size > 0 || (caps.oob_type & BT_MESH_STATIC_OOB_AVAILABLE); @@ -752,18 +751,18 @@ int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size) int bt_mesh_auth_method_set_static(const uint8_t *static_val, uint8_t size) { - uint8_t auth_size = bt_mesh_prov_auth_size_get(); + uint8_t tail_size = size < PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN - size : 0; - if (!size || !static_val || size > auth_size) { + if (!size || !static_val) { return -EINVAL; } prov_set_method(AUTH_METHOD_STATIC, 0, 0); - memcpy(bt_mesh_prov_link.auth + auth_size - size, static_val, size); - if (size < auth_size) { - (void)memset(bt_mesh_prov_link.auth, 0, auth_size - size); - } + memcpy(bt_mesh_prov_link.auth + tail_size, static_val, + tail_size ? size : PROV_AUTH_MAX_LEN); + memset(bt_mesh_prov_link.auth, 0, tail_size); + return 0; } From 236e3b64db062b7ae9e5c9abfc964ea188345db7 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 26 Sep 2023 12:15:40 +0200 Subject: [PATCH 1151/4498] Bluetooth: Mesh: shell supports 32 bytes static oob Commit adds support of 32 bytes static oob in mesh shell. Signed-off-by: Aleksandr Khromykh --- doc/connectivity/bluetooth/api/mesh/shell.rst | 4 ++-- subsys/bluetooth/mesh/shell/shell.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index e6609f40e5c..6f102b5490f 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -297,7 +297,7 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT * ``String``: Unquoted alphanumeric authentication string. -``mesh prov static-oob [Val(1-16 hex)]`` +``mesh prov static-oob [Val(1-32 hex)]`` ---------------------------------------- Set or clear the static OOB authentication value. The static OOB authentication value must be set before provisioning starts to have any effect. The static OOB value must be same on both participants in the provisioning. To enable this command, the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. @@ -358,7 +358,7 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ------------------------------------------------ From the provisioner device, instruct the unprovisioned device to use static OOB authentication, and use the given static authentication value when provisioning. - * ``Val`` - Static OOB value. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. + * ``Val`` - Static OOB value. Providing a hex-string shorter than 32 bytes will populate the N most significant bytes of the array and zero-pad the rest. ``mesh prov auth-method none`` ------------------------------ diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index 243166441fe..c5592db02cf 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -611,7 +611,7 @@ static void link_close(bt_mesh_prov_bearer_t bearer) shell_print_ctx("Provisioning link closed on %s", bearer2str(bearer)); } -static uint8_t static_val[16]; +static uint8_t static_val[32]; struct bt_mesh_prov bt_mesh_shell_prov = { .uuid = dev_uuid, @@ -645,7 +645,7 @@ static int cmd_static_oob(const struct shell *sh, size_t argc, char *argv[]) bt_mesh_shell_prov.static_val_len = 0U; } else { bt_mesh_shell_prov.static_val_len = hex2bin(argv[1], strlen(argv[1]), - static_val, 16); + static_val, 32); if (bt_mesh_shell_prov.static_val_len) { bt_mesh_shell_prov.static_val = static_val; } else { @@ -886,7 +886,7 @@ static int cmd_auth_method_set_output(const struct shell *sh, size_t argc, char static int cmd_auth_method_set_static(const struct shell *sh, size_t argc, char *argv[]) { size_t len; - uint8_t static_oob_auth[16]; + uint8_t static_oob_auth[32]; int err = 0; len = hex2bin(argv[1], strlen(argv[1]), static_oob_auth, sizeof(static_oob_auth)); From 0e98a35e39f001d9e5a4c4f0b9f348668bc1451b Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 26 Sep 2023 12:17:21 +0200 Subject: [PATCH 1152/4498] Bluetooth: Mesh: refactor mandatory oob for mesh1d1 Provisioner should be able to manage received capabilities unconditionally. Mandatory oob authentication is the node feature and it is still compile time feature. Split handling of this feature on provisioner and node part. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/prov.c | 6 ------ subsys/bluetooth/mesh/prov_device.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/mesh/prov.c b/subsys/bluetooth/mesh/prov.c index f44fffde649..fbbcde58185 100644 --- a/subsys/bluetooth/mesh/prov.c +++ b/subsys/bluetooth/mesh/prov.c @@ -181,12 +181,6 @@ int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8 uint8_t auth_size = bt_mesh_prov_auth_size_get(); int err; - if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && - (method == AUTH_METHOD_NO_OOB || - bt_mesh_prov_link.algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM)) { - return -EINVAL; - } - switch (method) { case AUTH_METHOD_NO_OOB: if (action || size) { diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index a83ace178db..0184463568f 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -94,15 +94,16 @@ static void prov_invite(const uint8_t *data) bt_mesh_prov->input_size > 0 || bt_mesh_prov->static_val; if (IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)) { - algorithm_bm |= BIT(BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM); + WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM, 1); } if (IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM)) { - algorithm_bm |= BIT(BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM); + WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM, 1); } if (oob_availability && IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED)) { oob_type |= BT_MESH_OOB_AUTH_REQUIRED; + WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM, 0); } /* Supported algorithms */ @@ -176,10 +177,18 @@ static void prov_start(const uint8_t *data) bt_mesh_prov_link.oob_action = data[3]; bt_mesh_prov_link.oob_size = data[4]; + if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && + (bt_mesh_prov_link.oob_method == AUTH_METHOD_NO_OOB || + bt_mesh_prov_link.algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM)) { + prov_fail(PROV_ERR_NVAL_FMT); + return; + } + if (bt_mesh_prov_auth(false, data[2], data[3], data[4]) < 0) { LOG_ERR("Invalid authentication method: 0x%02x; " "action: 0x%02x; size: 0x%02x", data[2], data[3], data[4]); prov_fail(PROV_ERR_NVAL_FMT); + return; } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { From 4cf78b1e6da90f80bd6449ae01abbcbaccbabbbc Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 26 Sep 2023 12:20:28 +0200 Subject: [PATCH 1153/4498] tests: Bluetooth: tester: fix mesh1d1 EHP pts tests Mesh1d1 uses EHP wth SHA256 algorithm as the main one. This mandates to use 32 bytes static oob if static oob has been chosen. Signed-off-by: Aleksandr Khromykh --- tests/bluetooth/tester/src/btp/btp_mesh.h | 10 ++++++++-- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index d7d2b2cdc7b..bf73d6839d2 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -30,9 +30,15 @@ struct btp_mesh_read_supported_commands_rp { #define BTP_MESH_CONFIG_PROVISIONING 0x02 +#if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) +#define BTP_MESH_PROV_AUTH_MAX_LEN 32 +#else +#define BTP_MESH_PROV_AUTH_MAX_LEN 16 +#endif + struct btp_mesh_config_provisioning_cmd { uint8_t uuid[16]; - uint8_t static_auth[16]; + uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; uint8_t out_size; uint16_t out_actions; uint8_t in_size; @@ -41,7 +47,7 @@ struct btp_mesh_config_provisioning_cmd { } __packed; struct btp_mesh_config_provisioning_cmd_v2 { uint8_t uuid[16]; - uint8_t static_auth[16]; + uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; uint8_t out_size; uint16_t out_actions; uint8_t in_size; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c922c812631..c56c0ff9c1c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -43,7 +43,7 @@ static uint8_t priv_key[32]; /* Configured provisioning data */ static uint8_t dev_uuid[16]; -static uint8_t static_auth[16]; +static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; /* Vendor Model data */ #define VND_MODEL_ID_1 0x1234 From f8e34e6684bc85caf655ff4fdf417a2cd53e3718 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 26 Sep 2023 13:15:54 +0200 Subject: [PATCH 1154/4498] tests/drivers/flash common: Allow on nrf52_bsim 903a79431aefed48bc1c918a7fca14b7a96444bb seems to have attempted to limit in how many platforms this test runs due to issues in some platforms. But how it was done (using platform allow apart from integration platform) it prevents it running on other platforms in which it works. Add the nrf52_bsim target to this allow list so the test can be run on it too. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/flash/common/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index d0bf791236b..6a06a61d011 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -41,6 +41,7 @@ tests: - it8xxx2_evb - mimxrt685_evk_cm33 - mimxrt595_evk_cm33 + - nrf52_bsim drivers.flash.common.tfm_ns: build_only: true filter: (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE From dfccc473a652c6346073e24b104698400f353ced Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 26 Sep 2023 14:36:51 +0000 Subject: [PATCH 1155/4498] Bluetooth: Host: Use memcpy instad of strncpy in bt_set_name memcpy makes more sense here. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b3a7e05891a..8e1227c0bf5 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -4110,7 +4110,7 @@ int bt_set_name(const char *name) return 0; } - strncpy(bt_dev.name, name, len); + memcpy(bt_dev.name, name, len); bt_dev.name[len] = '\0'; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { From 7af967a2f5dff86f400d7f53be7da79cdc23f2d6 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 26 Sep 2023 22:41:33 +0200 Subject: [PATCH 1156/4498] Bluetooth: Controller: Fix BIS payload sliding window overrun check Fix BIS implementation for checking overrun of the BIS PDU sliding window buffer overrun. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/ll_sw/lll_sync_iso.h | 1 - .../ll_sw/nordic/lll/lll_sync_iso.c | 52 +++++++++++++++---- .../bluetooth/controller/ll_sw/ull_sync_iso.c | 3 +- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h b/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h index 2426f51105e..c47aa433c63 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h @@ -74,7 +74,6 @@ struct lll_sync_iso { struct node_rx_pdu *payload[BT_CTLR_SYNC_ISO_STREAM_MAX] [PDU_BIG_PAYLOAD_COUNT_MAX]; uint8_t payload_count_max; - uint8_t payload_head; uint8_t payload_tail; uint32_t window_widening_periodic_us; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c index 5089c6ccde7..12e9fd342b9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c @@ -489,7 +489,6 @@ static void isr_rx(void *param) uint8_t access_addr[4]; uint16_t data_chan_id; uint8_t data_chan_use; - uint8_t payload_index; uint8_t crc_init[3]; uint8_t rssi_ready; uint32_t start_us; @@ -556,6 +555,8 @@ static void isr_rx(void *param) if (crc_ok) { struct lll_sync_iso_stream *sync_stream; uint16_t stream_handle; + uint8_t payload_offset; + uint8_t payload_index; struct pdu_bis *pdu; /* Check if Control Subevent being received */ @@ -593,21 +594,28 @@ static void isr_rx(void *param) /* TODO: check same CSSN is used in every subevent */ } - /* calculate the payload index in the sliding window */ - payload_index = lll->payload_tail + (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); + /* Check payload buffer overflow */ + payload_offset = (lll->bn_curr - 1U) + + (lll->ptc_curr * lll->pto); + if (payload_offset > lll->payload_count_max) { + goto isr_rx_done; + } + + /* Calculate the payload index in the sliding window */ + payload_index = lll->payload_tail + payload_offset; if (payload_index >= lll->payload_count_max) { payload_index -= lll->payload_count_max; } + /* Get reference to stream context */ stream_handle = lll->stream_handle[lll->stream_curr]; sync_stream = ull_sync_iso_lll_stream_get(stream_handle); - /* store the received PDU */ + /* Store the received PDU if selected stream and not already + * received (say in previous event as pre-transmitted PDU. + */ if ((lll->bis_curr == sync_stream->bis_index) && pdu->len && - !lll->payload[bis_idx][payload_index] && - ((payload_index >= lll->payload_tail) || - (payload_index < lll->payload_head))) { + !lll->payload[bis_idx][payload_index]) { uint16_t handle; if (lll->enc) { @@ -644,10 +652,23 @@ static void isr_rx(void *param) /* Find the next (bn_curr)th subevent to receive PDU */ while (lll->bn_curr < lll->bn) { + uint8_t payload_offset; + uint8_t payload_index; + + /* Next burst number to check for reception required */ lll->bn_curr++; + /* Check payload buffer overflow */ + payload_offset = (lll->bn_curr - 1U); + if (payload_offset > lll->payload_count_max) { + /* (bn_curr)th Rx PDU skip subevent */ + skipped++; + + continue; + } + /* Find the index of the (bn_curr)th Rx PDU buffer */ - payload_index = lll->payload_tail + (lll->bn_curr - 1U); + payload_index = lll->payload_tail + payload_offset; if (payload_index >= lll->payload_count_max) { payload_index -= lll->payload_count_max; } @@ -667,6 +688,11 @@ static void isr_rx(void *param) /* Find the next repetition (irc_curr)th subevent to receive PDU */ if (lll->irc_curr < lll->irc) { if (!new_burst) { + uint8_t payload_index; + + /* Increment to next repetition count and be at first + * burst count for it. + */ lll->bn_curr = 1U; lll->irc_curr++; @@ -715,6 +741,10 @@ static void isr_rx(void *param) if (lll->ptc_curr < lll->ptc) { lll->ptc_curr++; + /* TODO: optimize to skip pre-transmission subevent in case + * of insufficient buffers in sliding window. + */ + /* Receive the (ptc_curr)th Rx PDU of bis_curr */ bis = lll->bis_curr; @@ -733,6 +763,7 @@ static void isr_rx(void *param) stream_handle = lll->stream_handle[lll->stream_curr]; sync_stream = ull_sync_iso_lll_stream_get(stream_handle); if (sync_stream->bis_index <= lll->num_bis) { + uint8_t payload_index; uint8_t bis_idx_new; lll->bis_curr = sync_stream->bis_index; @@ -1058,8 +1089,7 @@ static void isr_rx_done(void *param) bn = lll->bn; while (bn--) { if (lll->payload[bis_idx][payload_tail]) { - node_rx = - lll->payload[bis_idx][payload_tail]; + node_rx = lll->payload[bis_idx][payload_tail]; lll->payload[bis_idx][payload_tail] = NULL; iso_rx_put(node_rx->hdr.link, node_rx); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index ff3327ce393..513ee3cdbed 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -454,10 +454,9 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, /* Initialize payload pointers */ lll->payload_count_max = PDU_BIG_PAYLOAD_COUNT_MAX; - lll->payload_head = 0U; lll->payload_tail = 0U; for (int i = 0; i < CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX; i++) { - for (int j = 0; j < PDU_BIG_PAYLOAD_COUNT_MAX; j++) { + for (int j = 0; j < lll->payload_count_max; j++) { lll->payload[i][j] = NULL; } } From 545f17b722d8947ede3b3a32cacd4d615204c453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Wed, 27 Sep 2023 08:15:58 +0200 Subject: [PATCH 1157/4498] Bluetooth: Host: Fix `SYS_SLIST_FOR_EACH_NODE_SAFE` misuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `gatt_write_ccc_rsp`, the third field of `SYS_SLIST_FOR_EACH_NODE_SAFE` was use as the `prev` sys_node when calling `gatt_sub_remove`. This was wrong because the third field of `SYS_SLIST_FOR_EACH_NODE_SAFE` is actually the next node. Fix the issue by adding a pointer to the previous node and passing it to `gatt_sub_remove`. Signed-off-by: Théo Battrel --- subsys/bluetooth/host/gatt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 39f01bc45b4..b75517c4cb6 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -5145,18 +5145,21 @@ static void gatt_write_ccc_rsp(struct bt_conn *conn, uint8_t err, /* if write to CCC failed we remove subscription and notify app */ if (err) { struct gatt_sub *sub; - sys_snode_t *node, *tmp; + sys_snode_t *node, *tmp, *prev; sub = gatt_sub_find(conn); if (!sub) { return; } + prev = NULL; + SYS_SLIST_FOR_EACH_NODE_SAFE(&sub->list, node, tmp) { if (node == ¶ms->node) { - gatt_sub_remove(conn, sub, tmp, params); + gatt_sub_remove(conn, sub, prev, params); break; } + prev = node; } } else if (!params->value) { /* Notify with NULL data to complete unsubscribe */ From 14348c53d41c5f080648b71f8fa1817b0da6b304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 27 Sep 2023 12:18:40 +0200 Subject: [PATCH 1158/4498] net: doc: coap: Eclipse Titan is now on Gitlab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eclipse Titan is now hosted on Gitlab (previously GitHub). Update URLs accordingly. Signed-off-by: Benjamin Cabé --- doc/connectivity/networking/api/coap.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/connectivity/networking/api/coap.rst b/doc/connectivity/networking/api/coap.rst index a7d54f02235..4f0654a57d4 100644 --- a/doc/connectivity/networking/api/coap.rst +++ b/doc/connectivity/networking/api/coap.rst @@ -172,14 +172,14 @@ Install eclipse-titan and set symbolic links for titan tools export TTCN3_DIR=/usr/share/titan - git clone https://github.com/eclipse/titan.misc.git + git clone https://gitlab.eclipse.org/eclipse/titan/titan.misc.git cd titan.misc Follow the instruction to setup CoAP test suite from here: -- https://github.com/eclipse/titan.misc -- https://github.com/eclipse/titan.misc/tree/master/CoAP_Conf +- https://gitlab.eclipse.org/eclipse/titan/titan.misc +- https://gitlab.eclipse.org/eclipse/titan/titan.misc/-/tree/master/CoAP_Conf After the build is complete, the :zephyr:code-sample:`coap-server` sample can be built and executed on QEMU as described in :ref:`networking_with_qemu`. From 05d77690736b5ad022ee1d0f7dc9b4fea2bd2c24 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 25 Sep 2023 12:45:10 +0200 Subject: [PATCH 1159/4498] sysbuild: Do not exclude images from domains.yaml The recent support for BUILD_ONLY images was implemented by excluding them from `domains.yaml`, in order to crudely prevent them from being picked up by `west flash`. Arguably, this is incorrect or unexpected, because the sysbuild documentation defines a "domain" as: Every Zephyr CMake build system managed by sysbuild. Another consequence is that, given a build-only ``, this makes it impossible to pass `--domain ` to `west flash`, `west debug`, and ironically `west build`. To fix that, `domains.yaml` should again represent all domains, and the build-only ones should be indicated in another way. Enter `flash_order`: a new top-level key in the domains YAML schema. It contains the default sequence of images used by `west flash`, where the build-only images are excluded, and the order is influenced by `sysbuild_add_dependencies()`. Signed-off-by: Grzegorz Swiderski --- scripts/pylib/build_helpers/domains.py | 43 +++++++++++++------------- scripts/west_commands/build_helpers.py | 3 +- scripts/west_commands/flash.py | 3 +- share/sysbuild/cmake/domains.cmake | 11 ++++--- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index c748a94a14f..8cacac7b4e8 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -38,6 +38,11 @@ build_dir: required: true type: str + flash_order: + required: false + type: seq + sequence: + - type: str ''' schema = yaml.safe_load(DOMAINS_SCHEMA) @@ -52,21 +57,19 @@ class Domains: def __init__(self, data): - self._domains = [] - self._domain_names = [] - self._domain_default = [] - self._build_dir = data.get('build_dir') - domain_list = data.get('domains') + domain_list = data.get('domains') or [] if not domain_list: logger.warning("no domains defined; this probably won't work") - for d in domain_list: - domain = Domain(d['name'], d['build_dir']) - self._domains.append(domain) - self._domain_names.append(domain.name) - if domain.name == data['default']: - self._default_domain = domain + self._domains = { + d['name']: Domain(d['name'], d['build_dir']) + for d in domain_list + } + self._default_domain = self._domains.get(data['default']) + + domains_flash_order = data.get('flash_order') or [] + self._flash_order = list(map(self._domains.get, domains_flash_order)) @staticmethod def from_file(domains_file): @@ -97,25 +100,21 @@ def from_data(domains_data): ''' return Domains(domains_data) - def get_domains(self, names=None): + def get_domains(self, names=None, default_flash_order=False): ret = [] if not names: - return self._domains + if default_flash_order: + return self._flash_order + return list(self._domains.values()) for n in names: - found = False - for d in self._domains: - if n == d.name: - ret.append(d) - found = True - break - # Getting here means the domain was not found. - # Todo: throw an error. + found = self._domains.get(n) if not found: logger.critical(f'domain {n} not found, ' - f'valid domains are:', *self._domain_names) + f'valid domains are: {", ".join(self._domains)}') exit(1) + ret.append(found) return ret def get_default_domain(self): diff --git a/scripts/west_commands/build_helpers.py b/scripts/west_commands/build_helpers.py index e4352ff1f28..88845e50f4b 100644 --- a/scripts/west_commands/build_helpers.py +++ b/scripts/west_commands/build_helpers.py @@ -153,6 +153,7 @@ def load_domains(path): if not domains_file.is_file(): return Domains.from_data({'default': 'app', 'build_dir': path, - 'domains': [{'name': 'app', 'build_dir': path}]}) + 'domains': [{'name': 'app', 'build_dir': path}], + 'flash_order': ['app']}) return Domains.from_file(domains_file) diff --git a/scripts/west_commands/flash.py b/scripts/west_commands/flash.py index 073a1ab2a28..4f173535be8 100644 --- a/scripts/west_commands/flash.py +++ b/scripts/west_commands/flash.py @@ -28,5 +28,6 @@ def do_add_parser(self, parser_adder): def do_run(self, my_args, runner_args): build_dir = get_build_dir(my_args) - domains = load_domains(build_dir).get_domains(my_args.domain) + domains = load_domains(build_dir).get_domains(my_args.domain, + default_flash_order=True) do_run_common(self, my_args, runner_args, domains=domains) diff --git a/share/sysbuild/cmake/domains.cmake b/share/sysbuild/cmake/domains.cmake index c46d261aff2..1d197059bf1 100644 --- a/share/sysbuild/cmake/domains.cmake +++ b/share/sysbuild/cmake/domains.cmake @@ -7,12 +7,13 @@ sysbuild_images_order(IMAGES_FLASHING_ORDER FLASH IMAGES ${IMAGES}) set(domains_yaml "default: ${DEFAULT_IMAGE}") set(domains_yaml "${domains_yaml}\nbuild_dir: ${CMAKE_BINARY_DIR}") set(domains_yaml "${domains_yaml}\ndomains:") -foreach(image ${IMAGES_FLASHING_ORDER}) - get_target_property(image_is_build_only ${image} BUILD_ONLY) - if(image_is_build_only) - continue() - endif() +foreach(image ${IMAGES}) set(domains_yaml "${domains_yaml}\n - name: ${image}") set(domains_yaml "${domains_yaml}\n build_dir: $") endforeach() +set(domains_yaml "${domains_yaml}\nflash_order:") +foreach(image ${IMAGES_FLASHING_ORDER}) + set(flash_cond "$>>") + set(domains_yaml "${domains_yaml}$<${flash_cond}:\n - ${image}>") +endforeach() file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/domains.yaml CONTENT "${domains_yaml}") From 8b273a45a678a62bcf3fa7e90cdb4c8faddf4553 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 25 Sep 2023 12:45:24 +0200 Subject: [PATCH 1160/4498] doc: sysbuild: Update documentation about BUILD_ONLY It is now possible to `west flash` or `west debug` a build-only image. Signed-off-by: Grzegorz Swiderski --- doc/build/sysbuild/index.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index 2c53cb0e88a..e09ee3e5617 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -569,13 +569,19 @@ You can mark ``my_sample`` as a build-only application in this manner: ) As a result, ``my_sample`` will be built as part of the sysbuild build invocation, -but neither ``west flash`` nor ``west debug`` will be aware of this application. +but it will be excluded from the default image sequence used by ``west flash``. Instead, you may use the outputs of this domain for other purposes - for example, to produce a secondary image for DFU, or to merge multiple images together. You can also replace ``TRUE`` with another boolean constant in CMake, such as a Kconfig option, which would make ``my_sample`` conditionally build-only. +.. note:: + + Applications marked as build-only can still be flashed manually, using + ``west flash --domain my_sample``. As such, the ``BUILD_ONLY`` option only + controls the default behavior of ``west flash``. + Zephyr application configuration ================================ From eafe6a9a3101c187849849c4e0f3c3f9696ccdb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 20 Sep 2023 12:12:50 +0200 Subject: [PATCH 1161/4498] drivers: spi_nrfx_spis: Handle empty spi_buf_set structures properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPI API allows `spi_buf_set` structures with no buffers linked to them (with `.buffers = NULL`). Correct the spi_nrfx_spis driver so that it is able to deal with such structures. Signed-off-by: Andrzej Głąbek --- drivers/spi/spi_nrfx_spis.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index 6ba36a139a0..d2a61530f00 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -170,6 +170,8 @@ static int transceive(const struct device *dev, { struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; + const struct spi_buf *tx_buf = tx_bufs ? tx_bufs->buffers : NULL; + const struct spi_buf *rx_buf = rx_bufs ? rx_bufs->buffers : NULL; int error; spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); @@ -181,8 +183,7 @@ static int transceive(const struct device *dev, (rx_bufs && rx_bufs->count > 1)) { LOG_ERR("Scattered buffers are not supported"); error = -ENOTSUP; - } else if (tx_bufs && tx_bufs->buffers[0].len && - !nrfx_is_in_ram(tx_bufs->buffers[0].buf)) { + } else if (tx_buf && tx_buf->len && !nrfx_is_in_ram(tx_buf->buf)) { LOG_ERR("Only buffers located in RAM are supported"); error = -ENOTSUP; } else { @@ -193,10 +194,10 @@ static int transceive(const struct device *dev, } error = prepare_for_transfer(dev, - tx_bufs ? tx_bufs->buffers[0].buf : NULL, - tx_bufs ? tx_bufs->buffers[0].len : 0, - rx_bufs ? rx_bufs->buffers[0].buf : NULL, - rx_bufs ? rx_bufs->buffers[0].len : 0); + tx_buf ? tx_buf->buf : NULL, + tx_buf ? tx_buf->len : 0, + rx_buf ? rx_buf->buf : NULL, + rx_buf ? rx_buf->len : 0); if (error == 0) { if (dev_config->wake_gpio.port) { /* Set the WAKE line low (tie it to ground) From dce3df81d456417055601b7a439f02ac6949b57c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Sep 2023 14:42:10 +0200 Subject: [PATCH 1162/4498] boards: wio-terminal: Default to swapped 16-bit colors for LVGL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set default value for LV_COLOR_16_SWAP when LVGL is enabled to get correct colors out-of-the-box. Signed-off-by: Benjamin Cabé --- boards/arm/wio_terminal/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm/wio_terminal/Kconfig.defconfig b/boards/arm/wio_terminal/Kconfig.defconfig index a8974dbd566..cca0d78a232 100644 --- a/boards/arm/wio_terminal/Kconfig.defconfig +++ b/boards/arm/wio_terminal/Kconfig.defconfig @@ -6,3 +6,6 @@ config BOARD default "wio_terminal" depends on BOARD_WIO_TERMINAL + +config LV_COLOR_16_SWAP + default y if LVGL From ea6248b8709b534d52d8ea439aaf4d9aa67a2fd0 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 25 Sep 2023 13:54:07 +0200 Subject: [PATCH 1163/4498] drivers: ieee802154: cc1200: SUN-FSK compatibility Preparative change to introduce build-time configured channel pages. This fixes the description of the driver's available PHYs and makes channel page and channel range independent from runtime attributes. Signed-off-by: Florian Grandel --- drivers/ieee802154/Kconfig.cc1200 | 15 +++++++++++--- drivers/ieee802154/ieee802154_cc1200.c | 25 ++++++++++++++++------- drivers/ieee802154/ieee802154_cc1200_rf.h | 9 +++++--- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/drivers/ieee802154/Kconfig.cc1200 b/drivers/ieee802154/Kconfig.cc1200 index 0e8329ed153..b1f18a7520d 100644 --- a/drivers/ieee802154/Kconfig.cc1200 +++ b/drivers/ieee802154/Kconfig.cc1200 @@ -85,13 +85,22 @@ choice Set the RF preset you want to use. config IEEE802154_CC1200_RF_SET_0 - bool "868MHz - 50Kbps - 2-GFSK - IEEE 802.15.4g compliant - ETSI" + bool "IEEE 802.15.4g SUN MR-FSK, 863MHz band, mode #1 - channel page 9, 34 channels, 50Kbps (ETSI)" + help + This is a legacy IEEE 802.15.4g-2012 SUN MR-FSK PHY that does no + longer exist in recent standards (IEEE 802.15.4-2015+). config IEEE802154_CC1200_RF_SET_1 - bool "920MHz - 50Kbps - 2-GFSK - IEEE 802.15.4g compliant - ARIB" + bool "IEEE 802.15.4g SUN MR-FSK 920MHz band, mode #1 - channel page 9, 39 channels, 50Kbps (ARIB)" + help + This is a legacy IEEE 802.15.4g-2012 SUN MR-FSK PHY that does no + longer exist in recent standards (IEEE 802.15.4-2015+). config IEEE802154_CC1200_RF_SET_2 - bool "434MHz - 50Kbps - 2-GFSK - IEEE 802.15.4g compliant - ETSI" + bool "IEEE 802.15.4 Non-Standard 2-GFSK 433MHz band - channel page 9, 15 channels, 50Kbps (ETSI)" + help + This is a non-standard PHY similar to the IEEE 802.15.4g-2012 SUN + MR-FSK PHY but not in one of the standard bands. endchoice diff --git a/drivers/ieee802154/ieee802154_cc1200.c b/drivers/ieee802154/ieee802154_cc1200.c index a5c4f37c47f..396f8878bf2 100644 --- a/drivers/ieee802154/ieee802154_cc1200.c +++ b/drivers/ieee802154/ieee802154_cc1200.c @@ -543,6 +543,15 @@ static int cc1200_cca(const struct device *dev) static int cc1200_set_channel(const struct device *dev, uint16_t channel) { struct cc1200_context *cc1200 = dev->data; + uint32_t freq; + + /* As SUN FSK provides a host of configurations with extremely different + * channel counts it doesn't make sense to validate (aka -EINVAL) a + * global upper limit on the number of supported channels on this page. + */ + if (channel > IEEE802154_CC1200_CHANNEL_LIMIT) { + return -ENOTSUP; + } /* Unlike usual 15.4 chips, cc1200 is closer to a bare metal radio modem * and thus does not provide any means to select a channel directly, but @@ -552,14 +561,16 @@ static int cc1200_set_channel(const struct device *dev, uint16_t channel) * See rf_evaluate_freq_setting() above. */ - if (atomic_get(&cc1200->rx) == 0) { - uint32_t freq = rf_evaluate_freq_setting(dev, channel); + if (atomic_get(&cc1200->rx) != 0) { + return -EIO; + } - if (!write_reg_freq(dev, freq) || - rf_calibrate(dev)) { - LOG_ERR("Could not set channel %u", channel); - return -EIO; - } + freq = rf_evaluate_freq_setting(dev, channel); + + if (!write_reg_freq(dev, freq) || + rf_calibrate(dev)) { + LOG_ERR("Could not set channel %u", channel); + return -EIO; } return 0; diff --git a/drivers/ieee802154/ieee802154_cc1200_rf.h b/drivers/ieee802154/ieee802154_cc1200_rf.h index 8135fcad3cf..e3788d7d7c2 100644 --- a/drivers/ieee802154/ieee802154_cc1200_rf.h +++ b/drivers/ieee802154/ieee802154_cc1200_rf.h @@ -23,9 +23,10 @@ #if defined(CONFIG_IEEE802154_CC1200_RF_SET_0) +#define IEEE802154_CC1200_CHANNEL_LIMIT 33 + const struct cc1200_rf_registers_set cc1200_rf_settings = { .chan_center_freq0 = 863125, - .channel_limit = 33, .channel_spacing = 2000, /* 200 KHz */ .registers = { 0x6F, /* SYNC3 */ @@ -133,9 +134,10 @@ const struct cc1200_rf_registers_set cc1200_rf_settings = { #elif defined(CONFIG_IEEE802154_CC1200_RF_SET_1) +#define IEEE802154_CC1200_CHANNEL_LIMIT 38 + const struct cc1200_rf_registers_set cc1200_rf_settings = { .chan_center_freq0 = 920600, - .channel_limit = 38, .channel_spacing = 2000, /* 200 KHz */ .registers = { 0x6F, /* SYNC3 */ @@ -243,9 +245,10 @@ const struct cc1200_rf_registers_set cc1200_rf_settings = { #elif defined(CONFIG_IEEE802154_CC1200_RF_SET_2) +#define IEEE802154_CC1200_CHANNEL_LIMIT 14 + const struct cc1200_rf_registers_set cc1200_rf_settings = { .chan_center_freq0 = 433164, - .channel_limit = 14, .channel_spacing = 2000, /* 200 KHz */ .registers = { 0x6F, /* SYNC3 */ From 7c00b81705707085e37641ab7bd64d554cce4ccc Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 25 Sep 2023 13:58:11 +0200 Subject: [PATCH 1164/4498] drivers: ieee802154: cc13xx_cc26xx: readability improvement Aligns the name of the return value variable with what is used elsewhere in the driver and the subsystem for improved readability and consistency. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx.c | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index 2068e08a475..95db189fb6d 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -171,26 +171,20 @@ static inline int ieee802154_cc13xx_cc26xx_channel_to_frequency( static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, uint16_t channel) { - int r; + int ret; RF_CmdHandle cmd_handle; RF_EventMask reason; uint16_t freq, fract; struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data; - /* TODO Support sub-GHz for CC13xx */ - if (channel < 11 || channel > 26) { - return -EINVAL; - } - - r = ieee802154_cc13xx_cc26xx_channel_to_frequency( - channel, &freq, &fract); - if (r < 0) { - return -EINVAL; + ret = ieee802154_cc13xx_cc26xx_channel_to_frequency(channel, &freq, &fract); + if (ret < 0) { + return ret; } /* Abort FG and BG processes */ if (ieee802154_cc13xx_cc26xx_stop(dev) < 0) { - r = -EIO; + ret = -EIO; goto out; } @@ -205,7 +199,7 @@ static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, RF_PriorityNormal, NULL, 0); if (reason != RF_EventLastCmdDone) { LOG_ERR("Failed to set frequency: 0x%" PRIx64, reason); - r = -EIO; + ret = -EIO; goto out; } @@ -217,15 +211,15 @@ static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, cmd_ieee_rx_callback, RF_EventRxEntryDone); if (cmd_handle < 0) { LOG_ERR("Failed to post RX command (%d)", cmd_handle); - r = -EIO; + ret = -EIO; goto out; } - r = 0; + ret = 0; out: k_mutex_unlock(&drv_data->tx_mutex); - return r; + return ret; } /* TODO remove when rf driver bugfix is pulled in */ From a12a6ab5b94a0aa4cc53c4b507bd8c5085a30910 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Sat, 2 Sep 2023 14:26:44 +0200 Subject: [PATCH 1165/4498] drivers: ieee802154: introduce channel pages Replaces the previous approach to define bands via hardware capabilities by the standard conforming concept of channel pages. In the short term this allows us to correctly calculate the PHY specific symbol rate and several parameters that directly depend from the symbol rate and were previously not being correctly calculated for some of the drivers whose channel pages could not be represented previously: * We now support sub-nanosecond precision symbol rates for UWB. Rounding errors are being minimized by switching from a divide-then-multiply approach to a multiply-then-divide approach. * UWB HRP: symbol rate depends on channel page specific preamble symbol rate which again requires the pulse repetition value to be known * Several MAC timings are being corrected based on the now correctly calculated symbol rates, namely aTurnaroundTime, aUnitBackoffPeriod, aBaseSuperframeDuration. In the long term, this change unlocks such highly promising functional areas as UWB ranging and SUN-PHY channel hopping in the SubG area (plus of course any other PHY specific feature). Signed-off-by: Florian Grandel --- doc/releases/release-notes-3.5.rst | 17 + drivers/ieee802154/Kconfig.cc1200 | 1 - drivers/ieee802154/Kconfig.cc13xx_cc26xx | 1 - drivers/ieee802154/Kconfig.rf2xx | 1 - drivers/ieee802154/ieee802154_b91.c | 25 +- drivers/ieee802154/ieee802154_cc1200.c | 18 +- drivers/ieee802154/ieee802154_cc13xx_cc26xx.c | 27 +- drivers/ieee802154/ieee802154_cc13xx_cc26xx.h | 2 +- .../ieee802154_cc13xx_cc26xx_subg.c | 60 +- drivers/ieee802154/ieee802154_cc2520.c | 22 +- drivers/ieee802154/ieee802154_dw1000.c | 56 +- drivers/ieee802154/ieee802154_kw41z.c | 18 +- drivers/ieee802154/ieee802154_mcr20a.c | 18 +- drivers/ieee802154/ieee802154_nrf5.c | 13 +- drivers/ieee802154/ieee802154_rf2xx.c | 75 ++- drivers/ieee802154/ieee802154_rf2xx.h | 13 +- drivers/ieee802154/ieee802154_uart_pipe.c | 19 +- include/zephyr/drivers/ieee802154/cc1200.h | 1 - include/zephyr/net/ieee802154.h | 8 - include/zephyr/net/ieee802154_mgmt.h | 5 +- include/zephyr/net/ieee802154_radio.h | 527 ++++++++++++++---- subsys/net/l2/ieee802154/CMakeLists.txt | 1 + subsys/net/l2/ieee802154/Kconfig | 16 - subsys/net/l2/ieee802154/ieee802154_mgmt.c | 71 +-- .../l2/ieee802154/ieee802154_radio_csma_ca.c | 13 +- subsys/net/l2/ieee802154/ieee802154_utils.c | 72 +++ subsys/net/l2/ieee802154/ieee802154_utils.h | 251 ++++++--- .../l2/src/ieee802154_fake_driver.c | 17 +- tests/subsys/openthread/radio_test.c | 19 +- 29 files changed, 1035 insertions(+), 352 deletions(-) create mode 100644 subsys/net/l2/ieee802154/ieee802154_utils.c diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9f5e2319dd2..869382ee4cd 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -200,6 +200,23 @@ Drivers and Sensors * IEEE 802.15.4 + * A new mandatory method attr_get() was introduced into ieee802154_radio_api. + Drivers need to implement at least + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES and + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES. + * The hardware capabilities IEEE802154_HW_2_4_GHZ and IEEE802154_HW_SUB_GHZ + were removed as they were not aligned with the standard and some already + existing drivers couldn't properly express their channel page and channel + range (notably SUN FSK and HRP UWB drivers). The capabilities were replaced + by the standard conforming new driver attribute + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES that fits all in-tree drivers. + * The method get_subg_channel_count() was removed from ieee802154_radio_api. + This method could not properly express the channel range of existing drivers + (notably SUN FSK drivers that implement channel pages > 0 and may not have + zero-based channel ranges or UWB drivers that could not be represented at + all). The method was replaced by the new driver attribute + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES that fits all in-tree drivers. + * Interrupt Controller * GIC: Architecture version selection is now based on the device tree diff --git a/drivers/ieee802154/Kconfig.cc1200 b/drivers/ieee802154/Kconfig.cc1200 index b1f18a7520d..de75ce5530d 100644 --- a/drivers/ieee802154/Kconfig.cc1200 +++ b/drivers/ieee802154/Kconfig.cc1200 @@ -6,7 +6,6 @@ menuconfig IEEE802154_CC1200 bool "TI CC1200 Driver support" default y depends on DT_HAS_TI_CC1200_ENABLED - select NET_L2_IEEE802154_SUB_GHZ if IEEE802154_CC1200 diff --git a/drivers/ieee802154/Kconfig.cc13xx_cc26xx b/drivers/ieee802154/Kconfig.cc13xx_cc26xx index e3ccf944abc..2414b16967f 100644 --- a/drivers/ieee802154/Kconfig.cc13xx_cc26xx +++ b/drivers/ieee802154/Kconfig.cc13xx_cc26xx @@ -59,7 +59,6 @@ menuconfig IEEE802154_CC13XX_CC26XX_SUB_GHZ bool "TI CC13xx / CC26xx IEEE 802.15.4g driver support" default y depends on DT_HAS_TI_CC13XX_CC26XX_IEEE802154_SUBGHZ_ENABLED - select NET_L2_IEEE802154_SUB_GHZ if NET_L2_IEEE802154 if IEEE802154_CC13XX_CC26XX_SUB_GHZ diff --git a/drivers/ieee802154/Kconfig.rf2xx b/drivers/ieee802154/Kconfig.rf2xx index 156cbcdcaea..80eb7f20876 100644 --- a/drivers/ieee802154/Kconfig.rf2xx +++ b/drivers/ieee802154/Kconfig.rf2xx @@ -9,7 +9,6 @@ menuconfig IEEE802154_RF2XX depends on DT_HAS_ATMEL_RF2XX_ENABLED select SPI select GPIO - select NET_L2_IEEE802154_SUB_GHZ if NET_L2_IEEE802154 if IEEE802154_RF2XX diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 8361d3e8aa2..16a3c794f18 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -30,7 +30,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* B91 data structure */ -static struct b91_data data; +static struct b91_data data; /* Set filter PAN ID */ static int b91_set_pan_id(uint16_t pan_id) @@ -403,7 +403,7 @@ static enum ieee802154_hw_caps b91_get_capabilities(const struct device *dev) { ARG_UNUSED(dev); - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_FILTER | + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK; } @@ -428,10 +428,14 @@ static int b91_set_channel(const struct device *dev, uint16_t channel) { ARG_UNUSED(dev); - if (channel < 11 || channel > 26) { + if (channel > 26) { return -EINVAL; } + if (channel < 11) { + return -ENOTSUP; + } + if (data.current_channel != channel) { data.current_channel = channel; rf_set_chn(B91_LOGIC_CHANNEL_TO_PHYSICAL(channel)); @@ -585,6 +589,20 @@ static int b91_configure(const struct device *dev, return -ENOTSUP; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +/* API implementation: attr_get */ +static int b91_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + /* IEEE802154 driver APIs structure */ static struct ieee802154_radio_api b91_radio_api = { .iface_api.init = b91_iface_init, @@ -598,6 +616,7 @@ static struct ieee802154_radio_api b91_radio_api = { .tx = b91_tx, .ed_scan = b91_ed_scan, .configure = b91_configure, + .attr_get = b91_attr_get, }; diff --git a/drivers/ieee802154/ieee802154_cc1200.c b/drivers/ieee802154/ieee802154_cc1200.c index 396f8878bf2..464417731de 100644 --- a/drivers/ieee802154/ieee802154_cc1200.c +++ b/drivers/ieee802154/ieee802154_cc1200.c @@ -519,7 +519,7 @@ static void cc1200_rx(void *arg) *******************/ static enum ieee802154_hw_caps cc1200_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | IEEE802154_HW_SUB_GHZ; + return IEEE802154_HW_FCS; } static int cc1200_cca(const struct device *dev) @@ -703,11 +703,19 @@ static int cc1200_stop(const struct device *dev) return 0; } -static uint16_t cc1200_get_channel_count(const struct device *dev) +/* driver-allocated attribute memory - constant across all driver instances as + * this driver's channel range is configured via a global KConfig setting. + */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 0, IEEE802154_CC1200_CHANNEL_LIMIT); + +static int cc1200_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) { - struct cc1200_context *cc1200 = dev->data; + ARG_UNUSED(dev); - return cc1200->rf_settings->channel_limit; + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_NINE_SUN_PREDEFINED, + &drv_attr.phy_supported_channels, value); } /****************** @@ -812,7 +820,7 @@ static struct ieee802154_radio_api cc1200_radio_api = { .tx = cc1200_tx, .start = cc1200_start, .stop = cc1200_stop, - .get_subg_channel_count = cc1200_get_channel_count, + .attr_get = cc1200_attr_get, }; NET_DEVICE_DT_INST_DEFINE(0, cc1200_init, NULL, &cc1200_context_data, diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index 95db189fb6d..cd3cd298bd1 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -122,7 +122,7 @@ static void client_event_callback(RF_Handle h, RF_ClientEvent event, void *arg) static enum ieee802154_hw_caps ieee802154_cc13xx_cc26xx_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_FILTER | + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER | IEEE802154_HW_RX_TX_ACK | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_CSMA | IEEE802154_HW_RETRANSMISSION; } @@ -155,17 +155,17 @@ static inline int ieee802154_cc13xx_cc26xx_channel_to_frequency( __ASSERT_NO_MSG(frequency != NULL); __ASSERT_NO_MSG(fractFreq != NULL); - if (channel >= IEEE802154_2_4_GHZ_CHANNEL_MIN - && channel <= IEEE802154_2_4_GHZ_CHANNEL_MAX) { - *frequency = 2405 + 5 * (channel - IEEE802154_2_4_GHZ_CHANNEL_MIN); + /* See IEEE 802.15.4-2020, section 10.1.3.3. */ + if (channel >= 11 && channel <= 26) { + *frequency = 2405 + 5 * (channel - 11); *fractFreq = 0; + return 0; } else { + /* TODO: Support sub-GHz for CC13xx rather than having separate drivers */ *frequency = 0; *fractFreq = 0; - return -EINVAL; + return channel < 11 ? -ENOTSUP : -EINVAL; } - - return 0; } static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, @@ -508,6 +508,18 @@ ieee802154_cc13xx_cc26xx_configure(const struct device *dev, return -ENOTSUP; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +static int ieee802154_cc13xx_cc26xx_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} static void ieee802154_cc13xx_cc26xx_data_init(const struct device *dev) { @@ -570,6 +582,7 @@ static struct ieee802154_radio_api ieee802154_cc13xx_cc26xx_radio_api = { .start = ieee802154_cc13xx_cc26xx_start, .stop = ieee802154_cc13xx_cc26xx_stop_if, .configure = ieee802154_cc13xx_cc26xx_configure, + .attr_get = ieee802154_cc13xx_cc26xx_attr_get, }; /** RF patches to use (note: RF core keeps a pointer to this, so no stack). */ diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h index ac3cc29a630..185e445a175 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h @@ -23,7 +23,7 @@ /* For O-QPSK the physical and MAC timing symbol rates are the same, see section 12.3.3. */ #define IEEE802154_2450MHZ_OQPSK_SYMBOLS_PER_SECOND \ - IEEE802154_PHY_SYMBOLS_PER_SECOND(IEEE802154_PHY_OQPSK_2450MHZ_SYMBOL_PERIOD_US) + IEEE802154_PHY_SYMBOLS_PER_SECOND(IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS) /* PHY PIB attribute phyCcaMode - CCA Mode 3: Carrier sense with energy above threshold, see * section 11.3, table 11-2 and section 10.2.8 diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index e06ab05207c..1b1891bc14e 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -263,25 +263,26 @@ static inline int ieee802154_cc13xx_cc26xx_subg_channel_to_frequency( __ASSERT_NO_MSG(frequency != NULL); __ASSERT_NO_MSG(fractFreq != NULL); - /* See IEEE 802.15.4, section 10.1.3.3. */ - if (channel == IEEE802154_SUB_GHZ_CHANNEL_MIN) { + /* See IEEE 802.15.4-2020, section 10.1.3.3. */ + if (channel == 0) { *frequency = 868; /* * uint16_t fractional part of 868.3 MHz * equivalent to (0.3 * 1000 * BIT(16)) / 1000, rounded up */ *fractFreq = 0x4ccd; - } else if (channel <= IEEE802154_SUB_GHZ_CHANNEL_MAX) { + } else if (channel <= 10) { *frequency = 906 + 2 * (channel - 1); *fractFreq = 0; } else { *frequency = 0; *fractFreq = 0; - return -EINVAL; + return channel <= 26 ? -ENOTSUP : -EINVAL; } - /* TODO: This incorrectly mixes up legacy O-QPSK SubGHz PHY channel page zero - * frequency calculation with SUN FSK operating mode #3 PHY radio settings. + /* TODO: This incorrectly mixes up legacy BPSK SubGHz PHY channel page + * zero frequency calculation with SUN FSK operating mode #3 PHY radio + * settings. * * The correct channel frequency calculation for this PHY is on channel page 9, * using the formula ChanCenterFreq = ChanCenterFreq0 + channel * ChanSpacing. @@ -299,16 +300,15 @@ static inline int ieee802154_cc13xx_cc26xx_subg_channel_to_frequency( * Making derived MAC/PHY PIB attributes available to L2 requires an additional * attribute getter, see * https://github.com/zephyrproject-rtos/zephyr/issues/50336#issuecomment-1251122582. + * + * We resolve this bug right now by basing all timing on SUN FSK + * parameters while maintaining the channel/channel page assignment of a + * BPSK PHY. */ return 0; } -static inline bool is_subghz(uint16_t channel) -{ - return (channel <= IEEE802154_SUB_GHZ_CHANNEL_MAX); -} - static void cmd_prop_tx_adv_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { @@ -362,7 +362,7 @@ static enum ieee802154_hw_caps ieee802154_cc13xx_cc26xx_subg_get_capabilities(const struct device *dev) { /* TODO: enable IEEE802154_HW_FILTER */ - return IEEE802154_HW_FCS | IEEE802154_HW_SUB_GHZ; + return IEEE802154_HW_FCS; } static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) @@ -449,13 +449,9 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( bool was_rx_on; int ret; - if (!is_subghz(channel)) { - return -EINVAL; - } - ret = ieee802154_cc13xx_cc26xx_subg_channel_to_frequency(channel, &freq, &fract); if (ret < 0) { - return -EINVAL; + return ret; } was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; @@ -590,6 +586,20 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, return ret; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 0, 10); + +static int ieee802154_cc13xx_cc26xx_subg_attr_get(const struct device *dev, + enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + static void ieee802154_cc13xx_cc26xx_subg_rx_done( struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { @@ -711,15 +721,6 @@ ieee802154_cc13xx_cc26xx_subg_configure(const struct device *dev, return -ENOTSUP; } -uint16_t ieee802154_cc13xx_cc26xx_subg_get_subg_channel_count( - const struct device *dev) -{ - ARG_UNUSED(dev); - - /* IEEE 802.15.4 SubGHz channels range from 0 to 10 for channel page zero. */ - return 11; -} - static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers( struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { @@ -791,8 +792,7 @@ static struct ieee802154_radio_api .start = ieee802154_cc13xx_cc26xx_subg_start, .stop = ieee802154_cc13xx_cc26xx_subg_stop_if, .configure = ieee802154_cc13xx_cc26xx_subg_configure, - .get_subg_channel_count = - ieee802154_cc13xx_cc26xx_subg_get_subg_channel_count, + .attr_get = ieee802154_cc13xx_cc26xx_subg_attr_get, }; static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) @@ -896,7 +896,7 @@ static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_d /* see IEEE 802.15.4, section 11.3, table 11-1 and section 10.2.8 */ .csEndTime = RF_convertUsToRatTicks( IEEE802154_PHY_A_CCA_TIME * - IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_US), + IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS), }, .cmd_prop_tx_adv = { @@ -916,7 +916,7 @@ static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_d }, }; -#if defined(CONFIG_NET_L2_IEEE802154_SUB_GHZ) +#if defined(CONFIG_NET_L2_IEEE802154) NET_DEVICE_DT_INST_DEFINE(0, ieee802154_cc13xx_cc26xx_subg_init, NULL, &ieee802154_cc13xx_cc26xx_subg_data, NULL, CONFIG_IEEE802154_CC13XX_CC26XX_SUB_GHZ_INIT_PRIO, diff --git a/drivers/ieee802154/ieee802154_cc2520.c b/drivers/ieee802154/ieee802154_cc2520.c index 184b0bf13af..688a6827a77 100644 --- a/drivers/ieee802154/ieee802154_cc2520.c +++ b/drivers/ieee802154/ieee802154_cc2520.c @@ -668,7 +668,7 @@ static void cc2520_rx(void *arg) static enum ieee802154_hw_caps cc2520_get_capabilities(const struct device *dev) { /* TODO: Add support for IEEE802154_HW_PROMISC */ - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_FILTER | + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER | IEEE802154_HW_RX_TX_ACK; } @@ -686,10 +686,14 @@ static int cc2520_set_channel(const struct device *dev, uint16_t channel) { LOG_DBG("%u", channel); - if (channel < 11 || channel > 26) { + if (channel > 26) { return -EINVAL; } + if (channel < 11) { + return -ENOTSUP; + } + /* See chapter 16 */ channel = 11 + (channel - 11) * 5U; @@ -878,6 +882,19 @@ static int cc2520_stop(const struct device *dev) return 0; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +static int cc2520_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + /****************** * Initialization * *****************/ @@ -1048,6 +1065,7 @@ static struct ieee802154_radio_api cc2520_radio_api = { .start = cc2520_start, .stop = cc2520_stop, .tx = cc2520_tx, + .attr_get = cc2520_attr_get, }; #if defined(CONFIG_IEEE802154_RAW_MODE) diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index 174f97b879e..d48fd715ae1 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -46,8 +46,8 @@ LOG_MODULE_REGISTER(dw1000, LOG_LEVEL_INF); #define DW1000_RX_ANT_DLY 16450 /* SHR Symbol Duration in ns */ -#define UWB_PHY_TPSYM_PRF64 1017.63 -#define UWB_PHY_TPSYM_PRF16 993.59 +#define UWB_PHY_TPSYM_PRF64 IEEE802154_PHY_HRP_UWB_PRF64_TPSYM_SYMBOL_PERIOD_NS +#define UWB_PHY_TPSYM_PRF16 IEEE802154_PHY_HRP_UWB_PRF16_TPSYM_SYMBOL_PERIOD_NS #define UWB_PHY_NUMOF_SYM_SHR_SFD 8 @@ -624,9 +624,8 @@ static void dwt_gpio_callback(const struct device *dev, static enum ieee802154_hw_caps dwt_get_capabilities(const struct device *dev) { - /* TODO: Add channel page attribute with channel page four. */ /* TODO: Implement HW-supported AUTOACK + frame pending bit handling. */ - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_FILTER | + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER | IEEE802154_HW_TXTIME; } @@ -684,6 +683,14 @@ static int dwt_set_channel(const struct device *dev, uint16_t channel) struct dwt_context *ctx = dev->data; struct dwt_phy_config *rf_cfg = &ctx->rf_cfg; + if (channel > 15) { + return -EINVAL; + } + + if (channel == 0 || channel == 6 || channel > 7) { + return -ENOTSUP; + } + rf_cfg->channel = channel; LOG_INF("Set channel %u", channel); @@ -940,6 +947,46 @@ static int dwt_configure(const struct device *dev, return -ENOTSUP; } +/* driver-allocated attribute memory - constant across all driver instances */ +static const struct { + const struct ieee802154_phy_channel_range phy_channel_range[2]; + const struct ieee802154_phy_supported_channels phy_supported_channels; +} drv_attr = { + .phy_channel_range = { + { .from_channel = 1, .to_channel = 5 }, + { .from_channel = 7, .to_channel = 7 }, + }, + .phy_supported_channels = { + .ranges = drv_attr.phy_channel_range, + .num_ranges = 2U, + }, +}; + +static int dwt_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + if (ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_FOUR_HRP_UWB, + &drv_attr.phy_supported_channels, value) == 0) { + return 0; + } + + switch (attr) { + case IEEE802154_ATTR_PHY_HRP_UWB_SUPPORTED_PRFS: { + struct dwt_context *ctx = dev->data; + struct dwt_phy_config *rf_cfg = &ctx->rf_cfg; + + value->phy_hrp_uwb_supported_nominal_prfs = + rf_cfg->prf == DWT_PRF_64M ? IEEE802154_PHY_HRP_UWB_NOMINAL_64_M + : IEEE802154_PHY_HRP_UWB_NOMINAL_16_M; + return 0; + } + + default: + return -ENOENT; + } +} + /* * Note, the DW_RESET pin should not be driven high externally. */ @@ -1633,6 +1680,7 @@ static struct ieee802154_radio_api dwt_radio_api = { .configure = dwt_configure, .ed_scan = dwt_ed, .tx = dwt_tx, + .attr_get = dwt_attr_get, }; #define DWT_PSDU_LENGTH (127 - DWT_FCS_LENGTH) diff --git a/drivers/ieee802154/ieee802154_kw41z.c b/drivers/ieee802154/ieee802154_kw41z.c index 3720ec0fd53..4947c4733ff 100644 --- a/drivers/ieee802154/ieee802154_kw41z.c +++ b/drivers/ieee802154/ieee802154_kw41z.c @@ -359,7 +359,7 @@ static void kw41z_tmr3_disable(void) static enum ieee802154_hw_caps kw41z_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_FILTER | + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK; } @@ -385,7 +385,7 @@ static int kw41z_cca(const struct device *dev) static int kw41z_set_channel(const struct device *dev, uint16_t channel) { if (channel < 11 || channel > 26) { - return -EINVAL; + return channel < 11 ? -ENOTSUP : -EINVAL; } ZLL->CHANNEL_NUM0 = channel; @@ -1078,6 +1078,19 @@ static int kw41z_configure(const struct device *dev, return 0; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +static int kw41z_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + static struct ieee802154_radio_api kw41z_radio_api = { .iface_api.init = kw41z_iface_init, @@ -1090,6 +1103,7 @@ static struct ieee802154_radio_api kw41z_radio_api = { .stop = kw41z_stop, .tx = kw41z_tx, .configure = kw41z_configure, + .attr_get = kw41z_attr_get, }; #if defined(CONFIG_NET_L2_IEEE802154) diff --git a/drivers/ieee802154/ieee802154_mcr20a.c b/drivers/ieee802154/ieee802154_mcr20a.c index 1448e32e5cf..96907cad145 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.c +++ b/drivers/ieee802154/ieee802154_mcr20a.c @@ -854,7 +854,7 @@ static int mcr20a_set_cca_mode(const struct device *dev, uint8_t mode) static enum ieee802154_hw_caps mcr20a_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | + return IEEE802154_HW_FCS | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK | IEEE802154_HW_FILTER; } @@ -916,7 +916,7 @@ static int mcr20a_set_channel(const struct device *dev, uint16_t channel) if (channel < 11 || channel > 26) { LOG_ERR("Unsupported channel %u", channel); - return -EINVAL; + return channel < 11 ? -ENOTSUP : -EINVAL; } k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER); @@ -1265,6 +1265,19 @@ static int mcr20a_stop(const struct device *dev) return -EIO; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +static int mcr20a_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + static int mcr20a_update_overwrites(const struct device *dev) { if (!write_reg_overwrite_ver(dev, overwrites_direct[0].data)) { @@ -1447,6 +1460,7 @@ static struct ieee802154_radio_api mcr20a_radio_api = { .start = mcr20a_start, .stop = mcr20a_stop, .tx = mcr20a_tx, + .attr_get = mcr20a_attr_get, }; #if defined(CONFIG_IEEE802154_RAW_MODE) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index f636da67983..3391add641a 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -223,7 +223,6 @@ static void nrf5_get_capabilities_at_boot(void) IEEE802154_HW_PROMISC | IEEE802154_HW_FILTER | ((caps & NRF_802154_CAPABILITY_CSMA) ? IEEE802154_HW_CSMA : 0UL) | - IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK | IEEE802154_HW_ENERGY_SCAN | @@ -270,7 +269,7 @@ static int nrf5_set_channel(const struct device *dev, uint16_t channel) LOG_DBG("%u", channel); if (channel < 11 || channel > 26) { - return -EINVAL; + return channel < 11 ? -ENOTSUP : -EINVAL; } nrf_802154_channel_set(channel); @@ -954,12 +953,20 @@ static int nrf5_configure(const struct device *dev, return 0; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + static int nrf5_attr_get(const struct device *dev, enum ieee802154_attr attr, struct ieee802154_attr_value *value) { ARG_UNUSED(dev); - ARG_UNUSED(value); + + if (ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value) == 0) { + return 0; + } switch ((uint32_t)attr) { #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index cdefa26f66e..54894910829 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -141,11 +141,11 @@ static void rf2xx_set_rssi_base(const struct device *dev, uint16_t channel) struct rf2xx_context *ctx = dev->data; int8_t base; - if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) { + if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { base = channel == 0 ? RF2XX_RSSI_BPSK_20 : RF2XX_RSSI_BPSK_40; - } else if (ctx->cc_page == RF2XX_TRX_CC_PAGE_2) { + } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { base = channel == 0 ? RF2XX_RSSI_OQPSK_SIN_RC_100 : RF2XX_RSSI_OQPSK_SIN_250; @@ -364,8 +364,6 @@ static inline uint8_t *get_mac(const struct device *dev) static enum ieee802154_hw_caps rf2xx_get_capabilities(const struct device *dev) { - struct rf2xx_context *ctx = dev->data; - LOG_DBG("HW Caps"); return IEEE802154_HW_FCS | @@ -374,10 +372,7 @@ static enum ieee802154_hw_caps rf2xx_get_capabilities(const struct device *dev) IEEE802154_HW_CSMA | IEEE802154_HW_RETRANSMISSION | IEEE802154_HW_TX_RX_ACK | - IEEE802154_HW_RX_TX_ACK | - (ctx->trx_model == RF2XX_TRX_MODEL_212 - ? IEEE802154_HW_SUB_GHZ - : IEEE802154_HW_2_4_GHZ); + IEEE802154_HW_RX_TX_ACK; } static int rf2xx_configure_sub_channel(const struct device *dev, uint16_t channel) @@ -386,11 +381,11 @@ static int rf2xx_configure_sub_channel(const struct device *dev, uint16_t channe uint8_t reg; uint8_t cc_mask; - if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) { + if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { cc_mask = channel == 0 ? RF2XX_CC_BPSK_20 : RF2XX_CC_BPSK_40; - } else if (ctx->cc_page == RF2XX_TRX_CC_PAGE_2) { + } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { cc_mask = channel == 0 ? RF2XX_CC_OQPSK_SIN_RC_100 : RF2XX_CC_OQPSK_SIN_250; @@ -404,13 +399,14 @@ static int rf2xx_configure_sub_channel(const struct device *dev, uint16_t channe return 0; } + static int rf2xx_configure_trx_path(const struct device *dev) { struct rf2xx_context *ctx = dev->data; uint8_t reg; uint8_t gc_tx_offset; - if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) { + if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { gc_tx_offset = 0x03; } else { gc_tx_offset = 0x02; @@ -440,24 +436,26 @@ static int rf2xx_set_channel(const struct device *dev, uint16_t channel) LOG_DBG("Set Channel %d", channel); if (ctx->trx_model == RF2XX_TRX_MODEL_212) { - if ((ctx->cc_page == RF2XX_TRX_CC_PAGE_0 - || ctx->cc_page == RF2XX_TRX_CC_PAGE_2) + if ((ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915 + || ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) && channel > 10) { LOG_ERR("Unsupported channel %u", channel); - return -EINVAL; + return channel > 26 ? -EINVAL : -ENOTSUP; } - if (ctx->cc_page == RF2XX_TRX_CC_PAGE_5 && channel > 3) { + if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780 && + channel > 3) { LOG_ERR("Unsupported channel %u", channel); - return -EINVAL; + return channel > 7 ? -EINVAL : -ENOTSUP; } rf2xx_configure_sub_channel(dev, channel); rf2xx_configure_trx_path(dev); rf2xx_set_rssi_base(dev, channel); } else { + /* 2.4G O-QPSK, channel page zero */ if (channel < 11 || channel > 26) { LOG_ERR("Unsupported channel %u", channel); - return -EINVAL; + return channel < 11 ? -ENOTSUP : -EINVAL; } } @@ -830,11 +828,23 @@ int rf2xx_configure(const struct device *dev, return ret; } -uint16_t rf2xx_get_subgiga_channel_count(const struct device *dev) +static int rf2xx_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) { struct rf2xx_context *ctx = dev->data; - return ctx->cc_page == RF2XX_TRX_CC_PAGE_5 ? 4 : 11; + switch (attr) { + case IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES: + value->phy_supported_channel_pages = ctx->cc_page; + return 0; + + case IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES: + value->phy_supported_channels = &ctx->cc_channels; + return 0; + + default: + return -ENOENT; + } } static int power_on_and_setup(const struct device *dev) @@ -1049,6 +1059,25 @@ static void rf2xx_iface_init(struct net_if *iface) ctx->iface = iface; + if (ctx->trx_model == RF2XX_TRX_MODEL_212) { + if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915 || + ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { + ctx->cc_range.from_channel = 0U; + ctx->cc_range.to_channel = 10U; + } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780) { + ctx->cc_range.from_channel = 0U; + ctx->cc_range.to_channel = 3U; + } else { + __ASSERT(false, "Unsupported channel page %u.", ctx->cc_page); + } + } else { + __ASSERT(ctx->cc_page == + IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + "Unsupported channel page %u.", ctx->cc_page); + ctx->cc_range.from_channel = 11U; + ctx->cc_range.to_channel = 26U; + } + ieee802154_init(iface); } @@ -1064,7 +1093,7 @@ static struct ieee802154_radio_api rf2xx_radio_api = { .start = rf2xx_start, .stop = rf2xx_stop, .configure = rf2xx_configure, - .get_subg_channel_count = rf2xx_get_subgiga_channel_count, + .attr_get = rf2xx_attr_get, }; #if !defined(CONFIG_IEEE802154_RAW_MODE) @@ -1113,7 +1142,11 @@ static struct ieee802154_radio_api rf2xx_radio_api = { #define IEEE802154_RF2XX_DEVICE_DATA(n) \ static struct rf2xx_context rf2xx_ctx_data_##n = { \ .mac_addr = { DRV_INST_LOCAL_MAC_ADDRESS(n) }, \ - .cc_page = DT_INST_ENUM_IDX_OR(n, channel_page, 0), \ + .cc_page = BIT(DT_INST_ENUM_IDX_OR(n, channel_page, 0)),\ + .cc_channels = { \ + .ranges = &rf2xx_ctx_data_##n.cc_range, \ + .num_ranges = 1U, \ + } \ } #define IEEE802154_RF2XX_RAW_DEVICE_INIT(n) \ diff --git a/drivers/ieee802154/ieee802154_rf2xx.h b/drivers/ieee802154/ieee802154_rf2xx.h index b77ec254d3a..9a337214afb 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.h +++ b/drivers/ieee802154/ieee802154_rf2xx.h @@ -74,12 +74,6 @@ enum rf2xx_trx_model_t { RF2XX_TRX_MODEL_233 = 0x0B, }; -enum rf2xx_trx_channel_page_t { - RF2XX_TRX_CC_PAGE_0 = 0x00, - RF2XX_TRX_CC_PAGE_2 = 0x02, - RF2XX_TRX_CC_PAGE_5 = 0x05, -}; - struct rf2xx_config { struct gpio_dt_spec irq_gpio; struct gpio_dt_spec reset_gpio; @@ -112,7 +106,12 @@ struct rf2xx_context { struct k_sem trx_tx_sync; enum rf2xx_trx_model_t trx_model; - enum rf2xx_trx_channel_page_t cc_page; + + /* PHY specific driver attributes */ + enum ieee802154_phy_channel_page cc_page; + struct ieee802154_phy_channel_range cc_range; + struct ieee802154_phy_supported_channels cc_channels; + enum rf2xx_trx_state_trac_t trx_trac; enum ieee802154_tx_mode tx_mode; diff --git a/drivers/ieee802154/ieee802154_uart_pipe.c b/drivers/ieee802154/ieee802154_uart_pipe.c index 158097e2ad2..299c9824d83 100644 --- a/drivers/ieee802154/ieee802154_uart_pipe.c +++ b/drivers/ieee802154/ieee802154_uart_pipe.c @@ -181,9 +181,7 @@ static uint8_t *upipe_rx(uint8_t *buf, size_t *off) static enum ieee802154_hw_caps upipe_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | - IEEE802154_HW_2_4_GHZ | - IEEE802154_HW_FILTER; + return IEEE802154_HW_FCS | IEEE802154_HW_FILTER; } static int upipe_cca(const struct device *dev) @@ -329,6 +327,20 @@ static int upipe_stop(const struct device *dev) return 0; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +/* API implementation: attr_get */ +static int upipe_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + static int upipe_init(const struct device *dev) { struct upipe_context *upipe = dev->data; @@ -391,6 +403,7 @@ static struct ieee802154_radio_api upipe_radio_api = { .tx = upipe_tx, .start = upipe_start, .stop = upipe_stop, + .attr_get = upipe_attr_get, }; NET_DEVICE_DT_INST_DEFINE(0, upipe_init, NULL, &upipe_context_data, NULL, diff --git a/include/zephyr/drivers/ieee802154/cc1200.h b/include/zephyr/drivers/ieee802154/cc1200.h index 3581a26e15d..2ef9e2f6b73 100644 --- a/include/zephyr/drivers/ieee802154/cc1200.h +++ b/include/zephyr/drivers/ieee802154/cc1200.h @@ -23,7 +23,6 @@ */ struct cc1200_rf_registers_set { uint32_t chan_center_freq0; - uint16_t channel_limit; /* to fit in uint16_t, spacing is a multiple of 100 Hz, * 12.5KHz for instance will be 125. */ diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index a17405b1000..24455b645cc 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -52,14 +52,6 @@ extern "C" { #define IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED IEEE802154_BROADCAST_ADDRESS #define IEEE802154_PAN_ID_NOT_ASSOCIATED IEEE802154_BROADCAST_PAN_ID -/* MAC PIB attribute aUnitBackoffPeriod, see section 8.4.2, table 8-93, in symbol periods, valid for - * all PHYs except SUN PHY in the 920 MHz band. - */ -#define IEEE802154_A_UNIT_BACKOFF_PERIOD(turnaround_time) \ - (turnaround_time + IEEE802154_PHY_A_CCA_TIME) -#define IEEE802154_A_UNIT_BACKOFF_PERIOD_US(turnaround_time, symbol_period) \ - (IEEE802154_A_UNIT_BACKOFF_PERIOD(turnaround_time) * symbol_period) - struct ieee802154_security_ctx { uint32_t frame_counter; struct cipher_ctx enc; diff --git a/include/zephyr/net/ieee802154_mgmt.h b/include/zephyr/net/ieee802154_mgmt.h index 07aa688232f..d52abda6271 100644 --- a/include/zephyr/net/ieee802154_mgmt.h +++ b/include/zephyr/net/ieee802154_mgmt.h @@ -212,10 +212,7 @@ enum net_event_ieee802154_cmd { #define IEEE802154_IS_CHAN_UNSCANNED(_channel_set, _chan) \ (!IEEE802154_IS_CHAN_SCANNED(_channel_set, _chan)) -/* Useful define to request all 16 channels of channel page zero - * in the 2450 MHz band to be scanned, from 11 to 26 included. - */ -#define IEEE802154_ALL_CHANNELS (0x03FFFC00) +#define IEEE802154_ALL_CHANNELS UINT32_MAX /** * @brief Scanning parameters diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index cbe45d97664..6a6f01957a8 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -31,72 +31,311 @@ extern "C" { * @{ */ -/* See section 6.1: "Some of the timing parameters in definition of the MAC are in units of PHY - * symbols. For PHYs that have multiple symbol periods, the duration to be used for the MAC - * parameters is defined in that PHY clause." +/** + * MAC functional description (section 6) + */ + +/** + * The symbol period (and therefore symbol rate) is defined in section 6.1: "Some + * of the timing parameters in definition of the MAC are in units of PHY symbols. + * For PHYs that have multiple symbol periods, the duration to be used for the + * MAC parameters is defined in that PHY clause." + * + * This is not necessarily the true physical symbol period, so take care to use + * this macro only when either the symbol period used for MAC timing is the same + * as the physical symbol period or if you actually mean the MAC timing symbol + * period. + * + * PHY specific symbol periods are defined in PHY specific sections below. */ -#define IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_US 20U /* see section 19.1, table 19-1 */ -#define IEEE802154_PHY_OQPSK_2450MHZ_SYMBOL_PERIOD_US 16U /* see section 12.3.3 */ +#define IEEE802154_PHY_SYMBOLS_PER_SECOND(symbol_period_ns) (NSEC_PER_SEC / symbol_period_ns) -/* TODO: Get PHY-specific symbol period from radio API. Requires an attribute getter, see - * https://github.com/zephyrproject-rtos/zephyr/issues/50336#issuecomment-1251122582. - * For now we assume PHYs that current drivers actually implement. +/** + * MAC services (section 8) */ -#define IEEE802154_PHY_SYMBOL_PERIOD_US(is_subg_phy) \ - ((is_subg_phy) ? IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_US \ - : IEEE802154_PHY_OQPSK_2450MHZ_SYMBOL_PERIOD_US) -/* The inverse of the symbol period as defined in section 6.1. This is not necessarily the true - * physical symbol period, so take care to use this macro only when either the symbol period used - * for MAC timing is the same as the physical symbol period or if you actually mean the MAC timing - * symbol period. +/** + * The number of PHY symbols forming a superframe slot when the superframe order + * is equal to zero, see sections 8.4.2, table 8-93, aBaseSlotDuration and + * section 6.2.1. */ -#define IEEE802154_PHY_SYMBOLS_PER_SECOND(symbol_period) (USEC_PER_SEC / symbol_period) +#define IEEE802154_MAC_A_BASE_SLOT_DURATION 60U -/* in bytes, see section 19.2.4 */ -#define IEEE802154_PHY_SUN_FSK_PHR_LEN 2 +/** + * The number of slots contained in any superframe, see section 8.4.2, + * table 8-93, aNumSuperframeSlots. + */ +#define IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS 16U + +/** + * The number of PHY symbols forming a superframe when the superframe order is + * equal to zero, see section 8.4.2, table 8-93, aBaseSuperframeDuration. + */ +#define IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION \ + (IEEE802154_MAC_A_BASE_SLOT_DURATION * IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS) + +/** + * MAC PIB attribute aUnitBackoffPeriod, see section 8.4.2, table 8-93, in symbol + * periods, valid for all PHYs except SUN PHY in the 920 MHz band. + */ +#define IEEE802154_MAC_A_UNIT_BACKOFF_PERIOD(turnaround_time) \ + (turnaround_time + IEEE802154_PHY_A_CCA_TIME) + +/** + * Default macResponseWaitTime in multiples of aBaseSuperframeDuration as + * defined in section 8.4.3.1, table 8-94. + */ +#define IEEE802154_MAC_RESPONSE_WAIT_TIME_DEFAULT 32U + +/** + * General PHY requirements (section 10) + */ + +/** + * @brief PHY channel pages, see section 10.1.3 + * + * @details A device driver must support the mandatory channel pages, frequency + * bands and channels of at least one IEEE 802.15.4 PHY. + * + * Channel page and number assignments have developed over several versions of + * the standard and are not particularly well documented. Therefore some notes + * about peculiarities of channel pages and channel numbering: + * - The 2006 version of the standard had a read-only phyChannelsSupported PHY + * PIB attribute that represented channel page/number combinations as a + * bitmap. This attribute was removed in later versions of the standard as the + * number of channels increased beyond what could be represented by a bit map. + * That's the reason why we chose to represent supported channels as a + * combination of channel pages and ranges instead. + * - In the 2020 version of the standard, 13 channel pages are explicitly + * defined, but up to 32 pages could in principle be supported. This was a + * hard requirement in the 2006 standard. In later standards it is implicit + * from field specifications, e.g. the MAC PIB attribute macChannelPage + * (section 8.4.3.4, table 8-100) or channel page fields used in the SRM + * protocol (see section 8.2.26.5). + * - ASK PHY (channel page one) was deprecated in the 2015 version of the + * standard. The 2020 version of the standard is a bit ambivalent whether + * channel page one disappeared as well or should be interpreted as O-QPSK now + * (see section 10.1.3.3). We resolve this ambivalence by deprecating channel + * page one. + * - For some PHYs the standard doesn't clearly specify a channel page, namely + * the GFSK, RS-GFSK, CMB and TASK PHYs. These are all rather new and left out + * in our list as long as no driver wants to implement them. + * + * @warning The bit numbers are not arbitrary but represent the channel + * page numbers as defined by the standard. Therefore do not change the + * bit numbering. + */ +enum ieee802154_phy_channel_page { + /** + * Channel page zero supports the 2.4G channels of the O-QPSK PHY and + * all channels from the BPSK PHYs initially defined in the 2003 + * editions of the standard. For channel page zero, 16 channels are + * available in the 2450 MHz band (channels 11-26, O-QPSK), 10 in the + * 915 MHz band (channels 1-10, BPSK), and 1 in the 868 MHz band + * (channel 0, BPSK). + * + * You can retrieve the channels supported by a specific driver on this + * page via IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES attribute. + * + * see section 10.1.3.3 + */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915 = BIT(0), + + /** Formerly ASK PHY - deprecated in IEEE 802.15.4-2015 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_ONE_DEPRECATED = BIT(1), + + /** O-QPSK PHY - 868 MHz and 915 MHz bands, see section 10.1.3.3 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915 = BIT(2), + + /** CSS PHY - 2450 MHz band, see section 10.1.3.4 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_THREE_CSS = BIT(3), + + /** UWB PHY - SubG, low and high bands, see section 10.1.3.5 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_FOUR_HRP_UWB = BIT(4), + + /** O-QPSK PHY - 780 MHz band, see section 10.1.3.2 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780 = BIT(5), -/* Default PHY PIB attribute aTurnaroundTime, in PHY symbols, see section 11.3, table 11-1. */ + /** reserved - not currently assigned */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_SIX_RESERVED = BIT(6), + + /** MSK PHY - 780 MHz and 2450 MHz bands, see sections 10.1.3.6, 10.1.3.7 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_SEVEN_MSK = BIT(7), + + /** LRP UWB PHY, see sections 10.1.3.8 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_EIGHT_LRP_UWB = BIT(8), + + /** + * SUN FSK/OFDM/O-QPSK PHYs - predefined bands, operating modes and + * channels, see sections 10.1.3.9 + */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_NINE_SUN_PREDEFINED = BIT(9), + + /** + * SUN FSK/OFDM/O-QPSK PHYs - generic modulation and channel + * description, see sections 10.1.3.9, 7.4.4.11 + */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_TEN_SUN_FSK_GENERIC = BIT(10), + + /** O-QPSK PHY - 2380 MHz band, see section 10.1.3.10 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_ELEVEN_OQPSK_2380 = BIT(11), + + /** LECIM DSSS/FSK PHYs, see section 10.1.3.11 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWELVE_LECIM = BIT(12), + + /** RCC PHY, see section 10.1.3.12 */ + IEEE802154_ATTR_PHY_CHANNEL_PAGE_THIRTEEN_RCC = BIT(13), +}; + +struct ieee802154_phy_channel_range { + uint16_t from_channel; + uint16_t to_channel; +}; + +struct ieee802154_phy_supported_channels { + /** + * @brief Pointer to an array of channel range structures. + * + * @warning The pointer must be stable and valid throughout the life of + * the interface. + */ + const struct ieee802154_phy_channel_range *const ranges; + + /** @brief The number of currently available channel ranges. */ + const uint8_t num_ranges; +}; + +/** + * @brief Allocate memory for the supported channels driver attribute with a + * single channel range constant across all driver instances. This is what most + * IEEE 802.15.4 drivers need. + * + * @details Example usage: + * + * @code{.c} + * IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + * @endcode + * + * The attribute may then be referenced like this: + * + * @code{.c} + * ... &drv_attr.phy_supported_channels ... + * @endcode + * + * See @ref ieee802154_attr_get_channel_page_and_range() for a further shortcut + * that can be combined with this macro. + * + * @param drv_attr name of the local static variable to be declared for the + * local attributes structure + * @param from the first channel to be supported + * @param to the last channel to be supported + */ +#define IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, from, to) \ + static const struct { \ + const struct ieee802154_phy_channel_range phy_channel_range; \ + const struct ieee802154_phy_supported_channels phy_supported_channels; \ + } drv_attr = { \ + .phy_channel_range = {.from_channel = (from), .to_channel = (to)}, \ + .phy_supported_channels = \ + { \ + .ranges = &drv_attr.phy_channel_range, \ + .num_ranges = 1U, \ + }, \ + } + + +/** + * PHY services (section 11) + */ + +/* Default PHY PIB attribute aTurnaroundTime, in PHY symbols, + * see section 11.3, table 11-1. + */ #define IEEE802154_PHY_A_TURNAROUND_TIME_DEFAULT 12U /* PHY PIB attribute aTurnaroundTime for SUN, RS-GFSK, TVWS, and LECIM FSK PHY, * in PHY symbols, see section 11.3, table 11-1. */ -#define IEEE802154_PHY_A_TURNAROUND_TIME_1MS(symbol_period) \ - DIV_ROUND_UP(USEC_PER_MSEC, symbol_period) - -/* TODO: Get PHY-specific turnaround time from radio API, see - * https://github.com/zephyrproject-rtos/zephyr/issues/50336#issuecomment-1251122582. - * For now we assume PHYs that current drivers actually implement. - */ -#define IEEE802154_PHY_A_TURNAROUND_TIME(is_subg_phy) \ - ((is_subg_phy) ? IEEE802154_PHY_A_TURNAROUND_TIME_1MS( \ - IEEE802154_PHY_SYMBOL_PERIOD_US(is_subg_phy)) \ - : IEEE802154_PHY_A_TURNAROUND_TIME_DEFAULT) +#define IEEE802154_PHY_A_TURNAROUND_TIME_1MS(symbol_period_ns) \ + DIV_ROUND_UP(NSEC_PER_MSEC, symbol_period_ns) /* PHY PIB attribute aCcaTime, in PHY symbols, all PHYs except for SUN O-QPSK, * see section 11.3, table 11-1. */ #define IEEE802154_PHY_A_CCA_TIME 8U + /** - * @brief IEEE 802.15.4 Channel assignments - * - * Channel numbering for 868 MHz, 915 MHz, and 2450 MHz bands (channel page zero). - * - * - Channel 0 is for 868.3 MHz. - * - Channels 1-10 are for 906 to 924 MHz with 2 MHz channel spacing. - * - Channels 11-26 are for 2405 to 2530 MHz with 5 MHz channel spacing. - * - * For more information, please refer to section 10.1.3. + * Q-OPSK PHY (section 12) + */ + +/* Symbol periods, section 12.3.3 */ +#define IEEE802154_PHY_OQPSK_868MHZ_SYMBOL_PERIOD_NS 40000LL +#define IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS 16000LL + + +/** + * BPSK PHY (section 13) + */ + +/* Symbol periods, section 13.3.3 */ +#define IEEE802154_PHY_BPSK_868MHZ_SYMBOL_PERIOD_NS 50000LL +#define IEEE802154_PHY_BPSK_915MHZ_SYMBOL_PERIOD_NS 25000LL + + +/** + * HRP UWB PHY (section 15) + */ + +/* For HRP UWB the symbol period is derived from the preamble symbol period + * (T_psym), see section 11.3, table 11-1 and section 15.2.5, table 15-4 + * (confirmed in IEEE 802.15.4z, section 15.1). Choosing among those periods + * cannot be done based on channel page and channel alone. The mean pulse + * repetition frequency must also be known, see the 'UwbPrf' parameter of the + * MCPS-DATA.request primitive (section 8.3.2, table 8-88) and the preamble + * parameters for HRP-ERDEV length 91 codes (IEEE 802.15.4z, section 15.2.6.2, + * table 15-7b). */ -enum ieee802154_channel { - IEEE802154_SUB_GHZ_CHANNEL_MIN = 0, - IEEE802154_SUB_GHZ_CHANNEL_MAX = 10, - IEEE802154_2_4_GHZ_CHANNEL_MIN = 11, - IEEE802154_2_4_GHZ_CHANNEL_MAX = 26, +#define IEEE802154_PHY_HRP_UWB_PRF4_TPSYM_SYMBOL_PERIOD_NS 3974.36F +#define IEEE802154_PHY_HRP_UWB_PRF16_TPSYM_SYMBOL_PERIOD_NS 993.59F +#define IEEE802154_PHY_HRP_UWB_PRF64_TPSYM_SYMBOL_PERIOD_NS 1017.63F +#define IEEE802154_PHY_HRP_UWB_ERDEV_TPSYM_SYMBOL_PERIOD_NS 729.17F + +/** @brief represents the nominal pulse rate frequency of an HRP UWB PHY */ +enum ieee802154_phy_hrp_uwb_nominal_prf { + /* standard modes, see section 8.3.2, table 8-88. */ + IEEE802154_PHY_HRP_UWB_PRF_OFF = 0, + IEEE802154_PHY_HRP_UWB_NOMINAL_4_M = BIT(0), + IEEE802154_PHY_HRP_UWB_NOMINAL_16_M = BIT(1), + IEEE802154_PHY_HRP_UWB_NOMINAL_64_M = BIT(2), + /* enhanced ranging device (ERDEV) modes not specified in table 8-88, + * see IEEE 802.15.4z, section 15.1, section 15.2.6.2, table 15-7b, + * section 15.3.4.2 and section 15.3.4.3. + */ + IEEE802154_PHY_HRP_UWB_NOMINAL_64_M_BPRF = BIT(3), + IEEE802154_PHY_HRP_UWB_NOMINAL_128_M_HPRF = BIT(4), + IEEE802154_PHY_HRP_UWB_NOMINAL_256_M_HPRF = BIT(5), }; +#define IEEE802154_PHY_HRP_UWB_RDEV \ + (IEEE802154_PHY_HRP_UWB_NOMINAL_4_M | IEEE802154_PHY_HRP_UWB_NOMINAL_16_M | \ + IEEE802154_PHY_HRP_UWB_NOMINAL_64_M) + +#define IEEE802154_PHY_HRP_UWB_ERDEV \ + (IEEE802154_PHY_HRP_UWB_NOMINAL_64_M_BPRF | IEEE802154_PHY_HRP_UWB_NOMINAL_128_M_HPRF | \ + IEEE802154_PHY_HRP_UWB_NOMINAL_256_M_HPRF) + + +/** + * SUN FSK PHY (section 19) + */ + +/* symbol periods, section 19.1, table 19-1 */ +#define IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS 20000LL + +/* in bytes, see section 19.2.4 */ +#define IEEE802154_PHY_SUN_FSK_PHR_LEN 2 + /** * IEEE 802.15.4 driver capabilities * @@ -112,28 +351,10 @@ enum ieee802154_hw_caps { * * The following capabilities describe features of the underlying radio * hardware (PHY/L1). - * - * Note: A device driver must support the mandatory channel pages, - * frequency bands and channels of at least one IEEE 802.15.4 PHY. */ - /** - * 2.4Ghz radio supported - * - * TODO: Replace with channel page attribute. - */ - IEEE802154_HW_2_4_GHZ = BIT(0), - - /** - * Sub-GHz radio supported - * - * TODO: Replace with channel page attribute. - */ - IEEE802154_HW_SUB_GHZ = BIT(1), - /** Energy detection (ED) supported (optional) */ - IEEE802154_HW_ENERGY_SCAN = BIT(2), - + IEEE802154_HW_ENERGY_SCAN = BIT(0), /* * MAC offloading capabilities (optional) @@ -151,37 +372,37 @@ enum ieee802154_hw_caps { */ /** Frame checksum verification supported */ - IEEE802154_HW_FCS = BIT(3), + IEEE802154_HW_FCS = BIT(1), /** Filtering of PAN ID, extended and short address supported */ - IEEE802154_HW_FILTER = BIT(4), + IEEE802154_HW_FILTER = BIT(2), /** Promiscuous mode supported */ - IEEE802154_HW_PROMISC = BIT(5), + IEEE802154_HW_PROMISC = BIT(3), /** CSMA-CA procedure supported on TX */ - IEEE802154_HW_CSMA = BIT(6), + IEEE802154_HW_CSMA = BIT(4), /** Waits for ACK on TX if AR bit is set in TX pkt */ - IEEE802154_HW_TX_RX_ACK = BIT(7), + IEEE802154_HW_TX_RX_ACK = BIT(5), /** Supports retransmission on TX ACK timeout */ - IEEE802154_HW_RETRANSMISSION = BIT(8), + IEEE802154_HW_RETRANSMISSION = BIT(6), /** Sends ACK on RX if AR bit is set in RX pkt */ - IEEE802154_HW_RX_TX_ACK = BIT(9), + IEEE802154_HW_RX_TX_ACK = BIT(7), /** TX at specified time supported */ - IEEE802154_HW_TXTIME = BIT(10), + IEEE802154_HW_TXTIME = BIT(8), /** TX directly from sleep supported */ - IEEE802154_HW_SLEEP_TO_TX = BIT(11), + IEEE802154_HW_SLEEP_TO_TX = BIT(9), /** Timed RX window scheduling supported */ - IEEE802154_HW_RXTIME = BIT(12), + IEEE802154_HW_RXTIME = BIT(10), /** TX security supported (key management, encryption and authentication) */ - IEEE802154_HW_TX_SEC = BIT(13), + IEEE802154_HW_TX_SEC = BIT(11), /* Note: Update also IEEE802154_HW_CAPS_BITS_COMMON_COUNT when changing * the ieee802154_hw_caps type. @@ -189,7 +410,7 @@ enum ieee802154_hw_caps { }; /** @brief Number of bits used by ieee802154_hw_caps type. */ -#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (14) +#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (12) /** @brief This and higher values are specific to the protocol- or driver-specific extensions. */ #define IEEE802154_HW_CAPS_BITS_PRIV_START IEEE802154_HW_CAPS_BITS_COMMON_COUNT @@ -502,10 +723,32 @@ struct ieee802154_config { * details. */ enum ieee802154_attr { + /** + * Retrieves a bit field with supported channel pages. This attribute + * SHALL be implemented by all drivers. + */ + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES, + + /** + * Retrieves a pointer to the array of supported channel ranges within + * the currently configured channel page. This attribute SHALL be + * implemented by all drivers. + */ + IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES, + + /** + * Retrieves a bit field with supported HRP UWB nominal pulse repetition + * frequencies. This attribute SHALL be implemented by all devices that + * support channel page four (HRP UWB). + */ + IEEE802154_ATTR_PHY_HRP_UWB_SUPPORTED_PRFS, + /** Number of attributes defined in ieee802154_attr. */ IEEE802154_ATTR_COMMON_COUNT, - /** This and higher values are specific to the protocol- or driver-specific extensions. */ + /** This and higher values are specific to the protocol- or + * driver-specific extensions. + */ IEEE802154_ATTR_PRIV_START = IEEE802154_ATTR_COMMON_COUNT, }; @@ -519,21 +762,121 @@ enum ieee802154_attr { * configuration data that originate from L2. * * @note To keep this union reasonably small, any attribute requiring a large - * memory area, SHALL be provided pointing to memory allocated from the driver's - * stack. Clients that need to persist the attribute value SHALL therefore copy - * such memory before returning control to the driver. + * memory area, SHALL be provided pointing to stable memory allocated by the + * driver. */ struct ieee802154_attr_value { union { - /* TODO: Please remove when first attribute is added. */ - uint8_t dummy; + /** + * @brief A bit field that represents the supported channel + * pages, see ieee802154_phy_channel_page. + * + * @note To keep the API extensible as required by the standard, + * we model supported pages as a bitmap to support drivers that + * implement runtime switching between multiple channel pages. + * + * @note Currently none of the Zephyr drivers implements more + * than one channel page at runtime, therefore only one bit will + * be set and we consider the current channel page (see the PHY + * PIB attribute phyCurrentPage, section 11.3, table 11-2) to be + * read-only, fixed and "well known" via the supported channel + * pages attribute. + * + * TODO: Implement configuration of phyCurrentPage once drivers + * need to support channel page switching at runtime. + */ + uint32_t phy_supported_channel_pages; + + /** + * @brief Pointer to a structure representing channel ranges + * currently available on the selected channel page. + * + * @warning The pointer must be stable and valid throughout the + * life of the interface. + * + * @details The selected channel page corresponds to the + * phyCurrentPage PHY PIB attribute, see the description of + * phy_supported_channel_pages above. Currently it can be + * retrieved via the IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES + * attribute. + * + * Most drivers will expose a single channel page with a single, + * often zero-based, fixed channel range. + * + * Some notable exceptions: + * * The legacy channel page (zero) exposes ranges in different + * bands and even PHYs that are usually not implemented by a + * single driver. + * * SUN and LECIM PHYs specify a large number of bands and + * operating modes on a single page with overlapping channel + * ranges each. Some of these ranges are not zero-based or + * contain "holes". This explains why several ranges may be + * necessary to represent all available channels. + * * UWB PHYs often support partial channel ranges on the same + * channel page depending on the supported bands. + * + * In these cases, drivers may expose custom configuration + * attributes (Kconfig, devicetree, runtime, ...) that allow + * switching between sub-ranges within the same channel page + * (e.g. switching between SubG and 2.4G bands on channel page + * zero or switching between multiple operating modes in the SUN + * or LECIM PHYs. + */ + const struct ieee802154_phy_supported_channels *phy_supported_channels; - /* TODO: Add driver specific PHY attributes (symbol rate, - * aTurnaroundTime, aCcaTime, channels, channel pages, etc.) + /** + * @brief A bit field representing supported HRP UWB pulse + * repetition frequencies (PRF), see enum + * ieee802154_phy_hrp_uwb_nominal_prf. + * + * @note Currently none of the Zephyr HRP UWB drivers implements + * more than one nominal PRF at runtime, therefore only one bit + * will be set and we consider the current PRF (UwbPrf, + * MCPS-DATA.request, section 8.3.2, table 8-88) to be + * read-only, fixed and "well known" via the supported PRF + * attribute. + * + * TODO: Allow the PRF to be configured for each TX call once + * drivers need to support PRF switching at runtime. */ + uint32_t phy_hrp_uwb_supported_nominal_prfs; }; }; +/** + * @brief Helper function to handle channel page and rank to be called from + * drivers' attr_get() implementation. This only applies to drivers with a + * single channel page. + * + * @param attr The attribute to be retrieved. + * @param phy_supported_channel_page The driver's unique channel page. + * @param phy_supported_channels Pointer to the structure that contains the + * driver's channel range or ranges. + * @param value The pointer to the value struct provided by the user. + * + * @retval 0 if the attribute could be resolved + * @retval -ENOENT if the attribute could not be resolved + */ +static inline int ieee802154_attr_get_channel_page_and_range( + enum ieee802154_attr attr, + const enum ieee802154_phy_channel_page phy_supported_channel_page, + const struct ieee802154_phy_supported_channels *phy_supported_channels, + struct ieee802154_attr_value *value) +{ + switch (attr) { + case IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES: + value->phy_supported_channel_pages = phy_supported_channel_page; + return 0; + + case IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES: + value->phy_supported_channels = phy_supported_channels; + return 0; + + default: + return -ENOENT; + } +} + /** * @brief IEEE 802.15.4 driver interface API. * @@ -592,7 +935,8 @@ struct ieee802154_radio_api { * * @retval 0 channel was successfully set * @retval -EINVAL The given channel is not within the range of valid - * channels of the driver's current channel page. + * channels of the driver's current channel page, see the + * IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES driver attribute. * @retval -ENOTSUP The given channel is within the range of valid * channels of the driver's current channel page but unsupported by the * current driver. @@ -734,18 +1078,6 @@ struct ieee802154_radio_api { enum ieee802154_config_type type, const struct ieee802154_config *config); - /** - * @brief Get the available amount of Sub-GHz channels. - * - * TODO: Replace with a combination of channel page and channel - * attributes. - * - * @param dev pointer to radio device - * - * @return number of available channels in the sub-gigahertz band - */ - uint16_t (*get_subg_channel_count)(const struct device *dev); - /** * @brief Run an energy detection scan. * @@ -819,7 +1151,8 @@ struct ieee802154_radio_api { * member. * * @retval -ENOENT The driver does not provide the requested attribute. - * The value structure has does not been updated with attribute data. + * The value structure has not been updated with attribute data. The + * content of the value attribute is undefined. */ int (*attr_get)(const struct device *dev, enum ieee802154_attr attr, diff --git a/subsys/net/l2/ieee802154/CMakeLists.txt b/subsys/net/l2/ieee802154/CMakeLists.txt index 65fbebe0391..e9d1318d81e 100644 --- a/subsys/net/l2/ieee802154/CMakeLists.txt +++ b/subsys/net/l2/ieee802154/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_compile_definitions_ifdef( zephyr_library_sources( ieee802154.c ieee802154_frame.c + ieee802154_utils.c ) zephyr_library_sources_ifdef( diff --git a/subsys/net/l2/ieee802154/Kconfig b/subsys/net/l2/ieee802154/Kconfig index 244d7f9da01..6aa03db01ff 100644 --- a/subsys/net/l2/ieee802154/Kconfig +++ b/subsys/net/l2/ieee802154/Kconfig @@ -14,22 +14,6 @@ config NET_L2_IEEE802154_MGMT select NET_MGMT select NET_MGMT_EVENT -# TODO: Selecting PHYs and frequency bands is abstracted by the concept -# of channel pages in recent versions of the standard (see -# IEEE 802.15.4-2020, 10.1.3). -# This option will be replaced by configuration options on driver -# instance level that allow selection of a channel page as well -# as other PHY-specific configuration options (frequency bands, -# operating modes, etc.). -# New and existing drivers should not introduce additional -# references to this option. -config NET_L2_IEEE802154_SUB_GHZ - bool - help - Enable support for Sub-GHz devices. This will add a tiny bit more - logic in L2 code for channel management. This option is automatically - selected when relevant device driver is enabled. - module = NET_L2_IEEE802154 module-dep = NET_LOG module-str = Log level for IEEE 802.15.4 diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index d1132d902ce..30ac0f836cd 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -94,10 +94,11 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_IEEE802154_CANCEL_SCAN, static int ieee802154_scan(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { + const struct ieee802154_phy_supported_channels *supported_channels; struct ieee802154_context *ctx = net_if_l2_data(iface); + struct ieee802154_attr_value attr_value; struct ieee802154_req_params *scan; struct net_pkt *pkt = NULL; - uint8_t channel; int ret; if (len != sizeof(struct ieee802154_req_params) || !data) { @@ -152,44 +153,52 @@ static int ieee802154_scan(uint32_t mgmt_request, struct net_if *iface, goto out; } - /* TODO: For now, we assume we are on 2.4Ghz - * (device will have to export current channel page) - */ - for (channel = 11U; channel <= 26U; channel++) { - if (IEEE802154_IS_CHAN_UNSCANNED(scan->channel_set, channel)) { - continue; - } + if (ieee802154_radio_attr_get(iface, IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES, + &attr_value)) { + NET_DBG("Could not determine supported channels"); + ret = -ENOENT; + goto out; + } + supported_channels = attr_value.phy_supported_channels; - scan->channel = channel; - NET_DBG("Scanning channel %u", channel); - ieee802154_radio_set_channel(iface, channel); + for (int channel_range = 0; channel_range < supported_channels->num_ranges; + channel_range++) { + for (uint16_t channel = supported_channels->ranges[channel_range].from_channel; + channel <= supported_channels->ranges[channel_range].to_channel; channel++) { + if (IEEE802154_IS_CHAN_UNSCANNED(scan->channel_set, channel)) { + continue; + } - /* Active scan sends a beacon request */ - if (mgmt_request == NET_REQUEST_IEEE802154_ACTIVE_SCAN) { - net_pkt_ref(pkt); - net_pkt_frag_ref(pkt->buffer); + scan->channel = channel; + NET_DBG("Scanning channel %u", channel); + ieee802154_radio_set_channel(iface, channel); - ret = ieee802154_radio_send(iface, pkt, pkt->buffer); - if (ret) { - NET_DBG("Could not send Beacon Request (%d)", - ret); - net_pkt_unref(pkt); - goto out; + /* Active scan sends a beacon request */ + if (mgmt_request == NET_REQUEST_IEEE802154_ACTIVE_SCAN) { + net_pkt_ref(pkt); + net_pkt_frag_ref(pkt->buffer); + + ret = ieee802154_radio_send(iface, pkt, pkt->buffer); + if (ret) { + NET_DBG("Could not send Beacon Request (%d)", ret); + net_pkt_unref(pkt); + goto out; + } } - } - /* Context aware sleep */ - k_sleep(K_MSEC(scan->duration)); + /* Context aware sleep */ + k_sleep(K_MSEC(scan->duration)); - k_sem_take(&ctx->scan_ctx_lock, K_FOREVER); + k_sem_take(&ctx->scan_ctx_lock, K_FOREVER); - if (!ctx->scan_ctx) { - NET_DBG("Scan request cancelled"); - ret = -ECANCELED; - goto out; - } + if (!ctx->scan_ctx) { + NET_DBG("Scan request cancelled"); + ret = -ECANCELED; + goto out; + } - k_sem_give(&ctx->scan_ctx_lock); + k_sem_give(&ctx->scan_ctx_lock); + } } out: diff --git a/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c b/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c index 2457eb503d6..29556d43df1 100644 --- a/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c +++ b/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c @@ -28,9 +28,15 @@ BUILD_ASSERT(CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE <= /* See section 6.2.5.1. */ static inline int unslotted_csma_ca_channel_access(struct net_if *iface) { - uint32_t turnaround_time = ieee802154_radio_get_a_turnaround_time(iface); - uint32_t symbol_period = ieee802154_radio_get_symbol_period_us(iface); + struct ieee802154_context *ctx = net_if_l2_data(iface); uint8_t be = CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE; + uint32_t turnaround_time, unit_backoff_period_us; + + turnaround_time = ieee802154_radio_get_a_turnaround_time(iface); + unit_backoff_period_us = ieee802154_radio_get_multiple_of_symbol_period( + iface, ctx->channel, + IEEE802154_MAC_A_UNIT_BACKOFF_PERIOD(turnaround_time)) / + NSEC_PER_USEC; for (uint8_t nb = 0U; nb <= CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MAX_BO; nb++) { int ret; @@ -42,8 +48,7 @@ static inline int unslotted_csma_ca_channel_access(struct net_if *iface) * radio API should expose a precise radio clock instead (which may * fall back to k_busy_wait() if the radio does not have a clock). */ - k_busy_wait(bo_n * IEEE802154_A_UNIT_BACKOFF_PERIOD_US(turnaround_time, - symbol_period)); + k_busy_wait(bo_n * unit_backoff_period_us); } ret = ieee802154_radio_cca(iface); diff --git a/subsys/net/l2/ieee802154/ieee802154_utils.c b/subsys/net/l2/ieee802154/ieee802154_utils.c new file mode 100644 index 00000000000..7058bbe70eb --- /dev/null +++ b/subsys/net/l2/ieee802154/ieee802154_utils.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023 Florian Grandel, Zephyr Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief IEEE 802.15.4 internal MAC and PHY Utils Implementation + * + * All references to the standard in this file cite IEEE 802.15.4-2020. + */ + +#include +LOG_MODULE_DECLARE(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL); + +#include "ieee802154_utils.h" + +/** + * PHY utilities + */ + +bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_t channel) +{ + struct ieee802154_attr_value value; + + if (channel == IEEE802154_NO_CHANNEL) { + return false; + } + + if (ieee802154_radio_attr_get(iface, IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES, + &value)) { + return false; + } + + for (int channel_range_index = 0; + channel_range_index < value.phy_supported_channels->num_ranges; + channel_range_index++) { + const struct ieee802154_phy_channel_range *const channel_range = + &value.phy_supported_channels->ranges[channel_range_index]; + + if (channel >= channel_range->from_channel && + channel <= channel_range->to_channel) { + return true; + } + } + + return false; +} + +uint16_t ieee802154_radio_number_of_channels(struct net_if *iface) +{ + struct ieee802154_attr_value value; + uint16_t num_channels = 0; + + if (ieee802154_radio_attr_get(iface, IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES, + &value)) { + return 0; + } + + for (int channel_range_index = 0; + channel_range_index < value.phy_supported_channels->num_ranges; + channel_range_index++) { + const struct ieee802154_phy_channel_range *const channel_range = + &value.phy_supported_channels->ranges[channel_range_index]; + + __ASSERT_NO_MSG(channel_range->to_channel >= channel_range->from_channel); + num_channels += channel_range->to_channel - channel_range->from_channel + 1U; + } + + return num_channels; +} diff --git a/subsys/net/l2/ieee802154/ieee802154_utils.h b/subsys/net/l2/ieee802154/ieee802154_utils.h index 4294ba7bd9f..ec80adff20e 100644 --- a/subsys/net/l2/ieee802154/ieee802154_utils.h +++ b/subsys/net/l2/ieee802154/ieee802154_utils.h @@ -123,7 +123,7 @@ static inline int ieee802154_radio_attr_get(struct net_if *iface, /** * Sets the radio drivers extended address filter. * - * @param iface Pointer to the IEEE 802.15.4 interface + * @param iface pointer to the IEEE 802.15.4 interface * @param ieee_addr Pointer to an extended address in little endian byte order */ static inline void ieee802154_radio_filter_ieee_addr(struct net_if *iface, uint8_t *ieee_addr) @@ -278,112 +278,204 @@ static inline void ieee802154_radio_remove_pan_id(struct net_if *iface, uint16_t } } + /** - * @brief Calculates the PHY's symbol period in microseconds. - * - * @details The PHY's symbol period depends on the interface's current PHY which - * can be derived from the currently chosen channel page (phyCurrentPage). - * - * Examples: - * * SUN FSK: see section 19.1, table 19-1 - * * O-QPSK: see section 12.3.3 - * * HRP UWB: derived from the preamble symbol period (T_psym), see section - * 11.3, table 11-1 and section 15.2.5, table 15-4 + * MAC utilities * - * @note Currently the symbol period can only be calculated for SUN FSK and O-QPSK. + * @note While MAC utilities may refer to PHY utilities, the inverse is not + * true. + */ + +/** + * @brief Retrieves the currently selected channel page from the driver (see + * phyCurrentPage, section 11.3, table 11-2). This is PHY-related information + * not configured by L2 but directly provided by the driver. * - * @param iface The interface for which the symbol period should be calculated. + * @param iface pointer to the IEEE 802.15.4 interface * - * @returns The symbol period for the given interface in microseconds. + * @returns The currently active channel page. + * @retval 0 if an error occurred */ -static inline uint32_t ieee802154_radio_get_symbol_period_us(struct net_if *iface) +static inline enum ieee802154_phy_channel_page +ieee802154_radio_current_channel_page(struct net_if *iface) { - /* TODO: Move symbol period calculation to radio driver. */ + struct ieee802154_attr_value value; - if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_SUB_GHZ) && - ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_SUB_GHZ) { - return IEEE802154_PHY_SYMBOL_PERIOD_US(true); + /* Currently we assume that drivers are statically configured to only + * support a single channel page. Once drivers need to switch channels at + * runtime this can be changed here w/o affecting clients. + */ + if (ieee802154_radio_attr_get(iface, IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES, &value)) { + return 0; } - return IEEE802154_PHY_SYMBOL_PERIOD_US(false); + return value.phy_supported_channel_pages; } /** - * @brief Calculates the PHY's turnaround time (see section 11.3, table 11-1, - * aTurnaroundTime) in PHY symbols. + * @brief Calculates a multiple of the PHY's symbol period in nanoseconds. * - * @details The PHY's turnaround time is used to calculate - among other - * parameters - the TX-to-RX turnaround time (see section 10.2.2) and the - * RX-to-TX turnaround time (see section 10.2.3). + * @details The PHY's symbol period depends on the interface's current PHY + * configuration which usually can be derived from the currently chosen channel + * page and channel (phyCurrentPage and phyCurrentChannel, section 11.3, table + * 11-2). + * + * To calculate the symbol period of HRP UWB PHYs, the nominal pulse repetition + * frequency (PRF) is required. HRP UWB drivers will be expected to expose the + * supported norminal PRF rates as a driver attribute. Existing drivers do not + * allow for runtime switching of the PRF, so currently the PRF is considered to + * be read-only and known. + * + * TODO: Add an UwbPrf argument once drivers need to support PRF switching at + * runtime. * - * @note Currently the turnaround time can only be calculated for SUN FSK and O-QPSK. + * @note We do not expose an API for a single symbol period to avoid having to + * deal with floats for PHYs that don't require it while maintaining precision + * in calculations where PHYs operate at symbol periods involving fractions of + * nanoseconds. * - * @param iface The interface for which the turnaround time should be calculated. + * @param iface pointer to the IEEE 802.15.4 interface + * @param channel The channel for which the symbol period is to be calculated. + * @param multiplier The factor by which the symbol period is to be multiplied. * - * @returns The turnaround time for the given interface. + * @returns A multiple of the symbol period for the given interface with + * nanosecond precision. + * @retval 0 if an error occurred. */ -static inline uint32_t ieee802154_radio_get_a_turnaround_time(struct net_if *iface) +static inline net_time_t ieee802154_radio_get_multiple_of_symbol_period(struct net_if *iface, + uint16_t channel, + uint16_t multiplier) { - if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_SUB_GHZ) && - ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_SUB_GHZ) { - return IEEE802154_PHY_A_TURNAROUND_TIME(true); - } + /* To keep things simple we only calculate symbol periods for channel + * pages that are implemented by existing in-tree drivers. Add additional + * channel pages as required. + */ + switch (ieee802154_radio_current_channel_page(iface)) { + case IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915: + return (channel >= 11 + ? IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS + : (channel > 0 ? IEEE802154_PHY_BPSK_915MHZ_SYMBOL_PERIOD_NS + : IEEE802154_PHY_BPSK_868MHZ_SYMBOL_PERIOD_NS)) * + multiplier; + + case IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915: + return (channel > 0 ? IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS + : IEEE802154_PHY_OQPSK_868MHZ_SYMBOL_PERIOD_NS) * + multiplier; + + case IEEE802154_ATTR_PHY_CHANNEL_PAGE_FOUR_HRP_UWB: { + struct ieee802154_attr_value value; + + /* Currently we assume that drivers are statically configured to + * only support a single PRF. Once drivers support switching PRF + * at runtime an UWB PRF argument needs to be added to this + * function which then must be validated against the set of + * supported PRFs. + */ + if (ieee802154_radio_attr_get(iface, IEEE802154_ATTR_PHY_HRP_UWB_SUPPORTED_PRFS, + &value)) { + return 0; + } - return IEEE802154_PHY_A_TURNAROUND_TIME(false); -} + switch (value.phy_hrp_uwb_supported_nominal_prfs) { + case IEEE802154_PHY_HRP_UWB_NOMINAL_4_M: + return IEEE802154_PHY_HRP_UWB_PRF4_TPSYM_SYMBOL_PERIOD_NS * multiplier; -static inline bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_t channel) -{ - if (channel == IEEE802154_NO_CHANNEL) { - return false; - } + case IEEE802154_PHY_HRP_UWB_NOMINAL_16_M: + return IEEE802154_PHY_HRP_UWB_PRF16_TPSYM_SYMBOL_PERIOD_NS * multiplier; -#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ - const struct ieee802154_radio_api *radio = - net_if_get_device(iface)->api; + case IEEE802154_PHY_HRP_UWB_NOMINAL_64_M: + return IEEE802154_PHY_HRP_UWB_PRF64_TPSYM_SYMBOL_PERIOD_NS * multiplier; - if (!radio) { - return false; - } + case IEEE802154_PHY_HRP_UWB_NOMINAL_64_M_BPRF: + case IEEE802154_PHY_HRP_UWB_NOMINAL_128_M_HPRF: + case IEEE802154_PHY_HRP_UWB_NOMINAL_256_M_HPRF: + return IEEE802154_PHY_HRP_UWB_ERDEV_TPSYM_SYMBOL_PERIOD_NS * multiplier; - if (radio->get_capabilities(net_if_get_device(iface)) & - IEEE802154_HW_SUB_GHZ) { - if (channel > - radio->get_subg_channel_count(net_if_get_device(iface))) { - return false; + default: + CODE_UNREACHABLE; } } -#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */ - return true; -} + case IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780: + return IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS * multiplier; + + case IEEE802154_ATTR_PHY_CHANNEL_PAGE_NINE_SUN_PREDEFINED: + /* Current SUN FSK drivers only implement legacy IEEE 802.15.4g + * 863 MHz (Europe) and 915 MHz (US ISM) bands, see IEEE + * 802.15.4g, section 5.1, table 0. Once more bands are required + * we need to request the currently active frequency band from + * the driver. + */ + return IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS * multiplier; + default: + CODE_UNREACHABLE; + } +} /** - * MAC utilities + * @brief Calculates the PHY's turnaround time for the current channel page (see + * section 11.3, table 11-1, aTurnaroundTime) in PHY symbols. + * + * @details The PHY's turnaround time is used to calculate - among other + * parameters - the TX-to-RX turnaround time (see section 10.2.2) and the + * RX-to-TX turnaround time (see section 10.2.3). + * + * @param iface pointer to the IEEE 802.15.4 interface * - * Note: While MAC utilities may refer to PHY utilities, - * the inverse is not true. + * @returns The turnaround time for the given interface in symbols. + * @retval 0 if an error occurred. */ +static inline uint32_t ieee802154_radio_get_a_turnaround_time(struct net_if *iface) +{ + enum ieee802154_phy_channel_page channel_page = + ieee802154_radio_current_channel_page(iface); -/** - * The number of PHY symbols forming a superframe slot when the superframe order - * is equal to zero, see sections 8.4.2, table 8-93, aBaseSlotDuration and 6.2.1. - */ -#define IEEE802154_MAC_A_BASE_SLOT_DURATION 60U + if (!channel_page) { + return 0; + } + + /* Section 11.3, table 11-1, aTurnaroundTime: "For the SUN [...] PHYs, + * the value is 1 ms expressed in symbol periods, rounded up to the next + * integer number of symbol periods using the ceiling() function. [...] + * The value is 12 [symbol periods] for all other PHYs. + */ + + if (channel_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_NINE_SUN_PREDEFINED) { + /* Current SUN FSK drivers only implement legacy IEEE 802.15.4g + * 863 MHz (Europe) and 915 MHz (US ISM) bands, see IEEE + * 802.15.4g, section 5.1, table 0. Once more bands are required + * we need to request the currently active frequency band from + * the driver. + */ + return IEEE802154_PHY_A_TURNAROUND_TIME_1MS( + IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS); + } + + return IEEE802154_PHY_A_TURNAROUND_TIME_DEFAULT; +} /** - * The number of slots contained in any superframe, see section 8.4.2, - * table 8-93, aNumSuperframeSlots. + * @brief Verify if the given channel lies within the allowed range of available + * channels of the driver's currently selected channel page. + * + * @param iface pointer to the IEEE 802.15.4 interface + * @param channel The channel to verify or IEEE802154_NO_CHANNEL + * + * @returns true if the channel is available, false otherwise */ -#define IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS 16U +bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_t channel); /** - * The number of PHY symbols forming a superframe when the superframe order is - * equal to zero, see section 8.4.2, table 8-93, aBaseSuperframeDuration. + * @brief Counts all available channels of the driver's currently selected + * channel page. + * + * @param iface pointer to the IEEE 802.15.4 interface + * + * @returns The number of available channels. */ -#define IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION \ - (IEEE802154_MAC_A_BASE_SLOT_DURATION * IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS) +uint16_t ieee802154_radio_number_of_channels(struct net_if *iface); /** * @brief Calculates the MAC's superframe duration (see section 8.4.2, @@ -392,22 +484,18 @@ static inline bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_ * @details The number of symbols forming a superframe when the superframe order * is equal to zero. * - * @param iface The interface for which the base superframe duration should be - * calculated. + * @param iface pointer to the IEEE 802.15.4 interface * * @returns The base superframe duration for the given interface in microseconds. */ static inline uint32_t ieee802154_get_a_base_superframe_duration(struct net_if *iface) { - return IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION * - ieee802154_radio_get_symbol_period_us(iface); -} + struct ieee802154_context *ctx = net_if_l2_data(iface); -/** - * Default macResponseWaitTime in multiples of aBaseSuperframeDuration as - * defined in section 8.4.3.1, table 8-94. - */ -#define IEEE802154_MAC_RESONSE_WAIT_TIME_DEFAULT 32U + return ieee802154_radio_get_multiple_of_symbol_period( + iface, ctx->channel, IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION) / + NSEC_PER_USEC; +} /** * @brief Retrieves macResponseWaitTime, see section 8.4.3.1, table 8-94, @@ -423,16 +511,15 @@ static inline uint32_t ieee802154_get_a_base_superframe_duration(struct net_if * * * @note Currently this parameter is read-only and uses the specified default of 32. * - * @param iface The interface for which the response wait time should be calculated. + * @param iface pointer to the IEEE 802.15.4 interface * * @returns The response wait time for the given interface in microseconds. */ static inline uint32_t ieee802154_get_response_wait_time_us(struct net_if *iface) { /* TODO: Make this parameter configurable. */ - return IEEE802154_MAC_RESONSE_WAIT_TIME_DEFAULT * + return IEEE802154_MAC_RESPONSE_WAIT_TIME_DEFAULT * ieee802154_get_a_base_superframe_duration(iface); } - #endif /* __IEEE802154_UTILS_H__ */ diff --git a/tests/net/ieee802154/l2/src/ieee802154_fake_driver.c b/tests/net/ieee802154/l2/src/ieee802154_fake_driver.c index 0d3d15d6c69..ab6509ef0a6 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_fake_driver.c +++ b/tests/net/ieee802154/l2/src/ieee802154_fake_driver.c @@ -26,7 +26,7 @@ uint8_t mock_ext_addr_be[8] = {0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2}; static enum ieee802154_hw_caps fake_get_capabilities(const struct device *dev) { - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ; + return IEEE802154_HW_FCS; } static int fake_cca(const struct device *dev) @@ -119,6 +119,20 @@ static int fake_stop(const struct device *dev) return 0; } +/* driver-allocated attribute memory - constant across all driver instances */ +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +/* API implementation: attr_get */ +static int fake_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + return ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value); +} + static void fake_iface_init(struct net_if *iface) { struct ieee802154_context *ctx = net_if_l2_data(iface); @@ -152,6 +166,7 @@ static struct ieee802154_radio_api fake_radio_api = { .start = fake_start, .stop = fake_stop, .tx = fake_tx, + .attr_get = fake_attr_get, }; NET_DEVICE_INIT(fake, "fake_ieee802154", diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index 87a7013a0d5..ab251e6807f 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -68,9 +68,6 @@ static struct ieee802154_radio_api rapi = {.get_capabilities = get_capabilities, .start = start_mock, .stop = stop_mock, .configure = configure_mock, -#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ - .get_subg_channel_count = NULL, -#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */ .ed_scan = scan_mock}; #define DT_DRV_COMPAT vnd_ieee802154 @@ -126,8 +123,8 @@ static enum ieee802154_hw_caps get_capabilities(const struct device *dev) zassert_equal(dev, radio, "Device handle incorrect."); - caps = IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | - IEEE802154_HW_FILTER | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_SLEEP_TO_TX; + caps = IEEE802154_HW_FCS | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_FILTER | + IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_SLEEP_TO_TX; if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) { caps |= IEEE802154_HW_TXTIME; } @@ -542,7 +539,6 @@ ZTEST(openthread_radio, test_promiscuous_mode_set_test) * @brief Test of proper radio to OT capabilities mapping * Tests if different radio capabilities map for their corresponding OpenThread * capability - * */ ZTEST(openthread_radio, test_get_caps_test) { @@ -555,12 +551,6 @@ ZTEST(openthread_radio, test_get_caps_test) /* not used by OT */ get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_FCS; - zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE, - "Incorrect capabilities returned."); - get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_2_4_GHZ; - zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE, - "Incorrect capabilities returned."); - get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_SUB_GHZ; zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE, "Incorrect capabilities returned."); @@ -595,9 +585,8 @@ ZTEST(openthread_radio, test_get_caps_test) /* all at once */ get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_FCS | IEEE802154_HW_PROMISC | IEEE802154_HW_FILTER | - IEEE802154_HW_CSMA | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | - IEEE802154_HW_SUB_GHZ | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_TXTIME | - IEEE802154_HW_SLEEP_TO_TX; + IEEE802154_HW_CSMA | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_ENERGY_SCAN | + IEEE802154_HW_TXTIME | IEEE802154_HW_SLEEP_TO_TX; zassert_equal( otPlatRadioGetCaps(ot), OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | From 6654d18596351f52193c6db6c779d2b97b7f4a62 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 13:00:57 -0700 Subject: [PATCH 1166/4498] ipm: mcux: Fix possible buffer overflow It is possible to happen a buffer overflow in ipm_send callback due a wrong comparison between signed/unsigned types. Signed-off-by: Flavio Ceolin --- drivers/ipm/ipm_mcux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ipm/ipm_mcux.c b/drivers/ipm/ipm_mcux.c index 176b858f20a..93267f5c58b 100644 --- a/drivers/ipm/ipm_mcux.c +++ b/drivers/ipm/ipm_mcux.c @@ -93,7 +93,7 @@ static int mcux_mailbox_ipm_send(const struct device *d, int wait, return -EINVAL; } - if (size > MCUX_IPM_DATA_REGS * sizeof(uint32_t)) { + if ((size < 0) || (size > MCUX_IPM_DATA_REGS * sizeof(uint32_t))) { return -EMSGSIZE; } From 4ff32d9290da561365f063aa0c4394bc6d531e0d Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 13:19:57 -0700 Subject: [PATCH 1167/4498] ipm: mcux: Initialize variable before using it Since the driver is passing the whole buffer, let's zero it to avoid pass garbage in case of size != buffer's size. Signed-off-by: Flavio Ceolin --- drivers/ipm/ipm_mcux.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ipm/ipm_mcux.c b/drivers/ipm/ipm_mcux.c index 93267f5c58b..2365f58aacc 100644 --- a/drivers/ipm/ipm_mcux.c +++ b/drivers/ipm/ipm_mcux.c @@ -81,9 +81,8 @@ static int mcux_mailbox_ipm_send(const struct device *d, int wait, { const struct mcux_mailbox_config *config = d->config; MAILBOX_Type *base = config->base; - uint32_t data32[MCUX_IPM_DATA_REGS]; /* Until we change API - * to uint32_t array - */ + /* Until we change API to uint32_t array */ + uint32_t data32[MCUX_IPM_DATA_REGS] = {0}; unsigned int flags; int i; From 0a12a05e630b270e465cf5d92063b9676ebeb631 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 13:10:18 -0700 Subject: [PATCH 1168/4498] ipm: imx: Fix possible buffer overflow It is possible to happen a buffer overflow in ipm_send due the lack of a checking for negative value. Signed-off-by: Flavio Ceolin --- drivers/ipm/ipm_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ipm/ipm_imx.c b/drivers/ipm/ipm_imx.c index 65e525f815a..da8a450982b 100644 --- a/drivers/ipm/ipm_imx.c +++ b/drivers/ipm/ipm_imx.c @@ -175,7 +175,7 @@ static int imx_mu_ipm_send(const struct device *dev, int wait, uint32_t id, return -EINVAL; } - if (size > CONFIG_IPM_IMX_MAX_DATA_SIZE) { + if ((size < 0) || (size > CONFIG_IPM_IMX_MAX_DATA_SIZE)) { return -EMSGSIZE; } From 98857c267d5825f8b3f3fd1040b7ce222b7f3958 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 13:22:42 -0700 Subject: [PATCH 1169/4498] ipm: imx: Initialize variable before using it Since the driver is passing the whole buffer, let's zero it to avoid pass garbage in case of size != buffer's size. Signed-off-by: Flavio Ceolin --- drivers/ipm/ipm_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ipm/ipm_imx.c b/drivers/ipm/ipm_imx.c index da8a450982b..f0fc5488670 100644 --- a/drivers/ipm/ipm_imx.c +++ b/drivers/ipm/ipm_imx.c @@ -165,7 +165,7 @@ static int imx_mu_ipm_send(const struct device *dev, int wait, uint32_t id, { const struct imx_mu_config *config = dev->config; MU_Type *base = MU(config); - uint32_t data32[IMX_IPM_DATA_REGS]; + uint32_t data32[IMX_IPM_DATA_REGS] = {0}; #if !IS_ENABLED(CONFIG_IPM_IMX_REV2) mu_status_t status; #endif From eeea26d20651e7f91de5e7d216a5398551d164da Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 26 Sep 2023 10:39:00 -0700 Subject: [PATCH 1170/4498] ipm: cavs: Fix possible buffer overflow A buffer overflow happens in send() when size is negative because it is promoted to signed when used in memcpy. Signed-off-by: Flavio Ceolin --- drivers/ipm/ipm_cavs_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ipm/ipm_cavs_host.c b/drivers/ipm/ipm_cavs_host.c index 308acd8a9a2..5877309d48d 100644 --- a/drivers/ipm/ipm_cavs_host.c +++ b/drivers/ipm/ipm_cavs_host.c @@ -56,7 +56,7 @@ static int send(const struct device *dev, int wait, uint32_t id, return -EBUSY; } - if (size > MAX_MSG) { + if ((size < 0) || (size > MAX_MSG)) { return -EMSGSIZE; } From eba567cf1877903c629f03089a65d5ae64fe81bc Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 21 Sep 2023 16:21:32 -0700 Subject: [PATCH 1171/4498] random: ctr_drbg: Remove unused variable state_sem was statically defined but never used. Signed-off-by: Flavio Ceolin --- subsys/random/rand32_ctr_drbg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/random/rand32_ctr_drbg.c b/subsys/random/rand32_ctr_drbg.c index 7d4b858a068..ef1b58a8a3d 100644 --- a/subsys/random/rand32_ctr_drbg.c +++ b/subsys/random/rand32_ctr_drbg.c @@ -26,8 +26,6 @@ #endif /* CONFIG_MBEDTLS */ -static K_SEM_DEFINE(state_sem, 1, 1); - /* * entropy_dev is initialized at runtime to allow first time initialization * of the ctr_drbg engine. From 37be80ddbe2d4a0c4665429d0cf492b7d00248df Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 21 Sep 2023 17:20:27 -0700 Subject: [PATCH 1172/4498] random: ctr_drbg: Thread safe in SMP irq_lock() does not make this this csprng api thread safe in SMP systems. Change it to use a mutex. Signed-off-by: Flavio Ceolin --- subsys/random/rand32_ctr_drbg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/random/rand32_ctr_drbg.c b/subsys/random/rand32_ctr_drbg.c index ef1b58a8a3d..88c591075f1 100644 --- a/subsys/random/rand32_ctr_drbg.c +++ b/subsys/random/rand32_ctr_drbg.c @@ -33,6 +33,7 @@ static const struct device *entropy_dev; static const unsigned char drbg_seed[] = CONFIG_CS_CTR_DRBG_PERSONALIZATION; static bool ctr_initialised; +static struct k_mutex ctr_lock; #if defined(CONFIG_MBEDTLS) @@ -105,7 +106,8 @@ static int ctr_drbg_initialize(void) int z_impl_sys_csrand_get(void *dst, uint32_t outlen) { int ret; - unsigned int key = irq_lock(); + + k_mutex_lock(&ctr_lock, K_FOREVER); if (unlikely(!ctr_initialised)) { ret = ctr_drbg_initialize(); @@ -151,7 +153,7 @@ int z_impl_sys_csrand_get(void *dst, uint32_t outlen) } #endif end: - irq_unlock(key); + k_mutex_unlock(&ctr_lock); return ret; } From 8be60b40b6b03ef5904d327ffc659134439dcea0 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 21 Sep 2023 22:33:34 -0700 Subject: [PATCH 1173/4498] drivers: entropy: Add thread safeness note Add a note in entropy_get_entropy about thread safeness, since this is used by the random subsystem in its CSPRNG. Signed-off-by: Flavio Ceolin --- include/zephyr/drivers/entropy.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/zephyr/drivers/entropy.h b/include/zephyr/drivers/entropy.h index 2c9ce51f307..9bf4f37c3a8 100644 --- a/include/zephyr/drivers/entropy.h +++ b/include/zephyr/drivers/entropy.h @@ -33,6 +33,9 @@ extern "C" { * @typedef entropy_get_entropy_t * @brief Callback API to get entropy. * + * @note This call has to be thread safe to satisfy requirements + * of the random subsystem. + * * See entropy_get_entropy() for argument description */ typedef int (*entropy_get_entropy_t)(const struct device *dev, From 23106b81c82f50090cd4ae59857f4a05f93dd7fd Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 21 Sep 2023 23:42:51 -0700 Subject: [PATCH 1174/4498] random: Remove deprecated Kconfig symbol XOROSHIRO_RANDOM_GENERATOR has been deprecated in Zephyr 1.12 (???), time to remove it. Signed-off-by: Flavio Ceolin --- subsys/random/CMakeLists.txt | 4 ---- subsys/random/Kconfig | 5 ----- 2 files changed, 9 deletions(-) diff --git a/subsys/random/CMakeLists.txt b/subsys/random/CMakeLists.txt index 1cb72f2bea1..e8bbd0f0dd8 100644 --- a/subsys/random/CMakeLists.txt +++ b/subsys/random/CMakeLists.txt @@ -15,11 +15,7 @@ if (CONFIG_TIMER_RANDOM_GENERATOR) Use it carefully.") endif() -# XOROSHIRO builds the XOSHIRO implementation because a Kconfig choice cannot -# select another choice as a means of deprecating the symbol. Swapping out the -# implementation lets out-of-tree users still build until the symbol is removed. zephyr_library_sources_ifdef(CONFIG_TIMER_RANDOM_GENERATOR rand32_timer.c) -zephyr_library_sources_ifdef(CONFIG_XOROSHIRO_RANDOM_GENERATOR rand32_xoshiro128.c) zephyr_library_sources_ifdef(CONFIG_XOSHIRO_RANDOM_GENERATOR rand32_xoshiro128.c) zephyr_library_sources_ifdef(CONFIG_CTR_DRBG_CSPRNG_GENERATOR rand32_ctr_drbg.c) diff --git a/subsys/random/Kconfig b/subsys/random/Kconfig index d945bbbcec0..6629b0d6b08 100644 --- a/subsys/random/Kconfig +++ b/subsys/random/Kconfig @@ -57,11 +57,6 @@ config ENTROPY_DEVICE_RANDOM_GENERATOR selected if hardware entropy driver is designed to be a random number generator source. -config XOROSHIRO_RANDOM_GENERATOR - bool "Use Xoroshiro128+ as PRNG (DEPRECATED)" - help - This is deprecated, please use XOSHIRO_RANDOM_GENERATOR instead. - config XOSHIRO_RANDOM_GENERATOR bool "Use Xoshiro128++ as PRNG" depends on ENTROPY_HAS_DRIVER From 646a06c9fec2ed2ccb5c9147287e9d6715831181 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 22 Sep 2023 14:04:03 -0700 Subject: [PATCH 1175/4498] random: Fix kconfig symbol name s/CSPRING_ENABLED/CSPRNG_ENABLED/g Signed-off-by: Flavio Ceolin --- soc/arm/nxp_imx/rt/Kconfig.defconfig.series | 2 +- soc/arm/nxp_imx/rt5xx/Kconfig.defconfig.series | 2 +- soc/arm/nxp_imx/rt6xx/Kconfig.defconfig.series | 2 +- subsys/jwt/Kconfig | 2 +- subsys/mgmt/osdp/Kconfig | 2 +- subsys/random/Kconfig | 3 +-- tests/crypto/rand32/src/main.c | 4 ++-- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/soc/arm/nxp_imx/rt/Kconfig.defconfig.series b/soc/arm/nxp_imx/rt/Kconfig.defconfig.series index cc9cc9b5480..7a1aac41ce3 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.defconfig.series +++ b/soc/arm/nxp_imx/rt/Kconfig.defconfig.series @@ -113,7 +113,7 @@ endchoice # config MBEDTLS #config TINYCRYPT - default y if CSPRING_ENABLED + default y if CSPRNG_ENABLED depends on ENTROPY_GENERATOR if MBEDTLS diff --git a/soc/arm/nxp_imx/rt5xx/Kconfig.defconfig.series b/soc/arm/nxp_imx/rt5xx/Kconfig.defconfig.series index 9ee952cff78..31b6a2c70db 100644 --- a/soc/arm/nxp_imx/rt5xx/Kconfig.defconfig.series +++ b/soc/arm/nxp_imx/rt5xx/Kconfig.defconfig.series @@ -62,7 +62,7 @@ endif # config MBEDTLS #config TINYCRYPT - default y if CSPRING_ENABLED + default y if CSPRNG_ENABLED depends on ENTROPY_GENERATOR if MBEDTLS diff --git a/soc/arm/nxp_imx/rt6xx/Kconfig.defconfig.series b/soc/arm/nxp_imx/rt6xx/Kconfig.defconfig.series index 40bb1ab7b6a..7bcbc4e8e80 100644 --- a/soc/arm/nxp_imx/rt6xx/Kconfig.defconfig.series +++ b/soc/arm/nxp_imx/rt6xx/Kconfig.defconfig.series @@ -63,7 +63,7 @@ endif # config MBEDTLS #config TINYCRYPT - default y if CSPRING_ENABLED + default y if CSPRNG_ENABLED depends on ENTROPY_GENERATOR if MBEDTLS diff --git a/subsys/jwt/Kconfig b/subsys/jwt/Kconfig index dfbdbc3c889..ef4f93238fe 100644 --- a/subsys/jwt/Kconfig +++ b/subsys/jwt/Kconfig @@ -16,7 +16,7 @@ choice config JWT_SIGN_RSA bool "Use RSA signature (RS-256)" - depends on CSPRING_ENABLED + depends on CSPRNG_ENABLED select MBEDTLS config JWT_SIGN_ECDSA diff --git a/subsys/mgmt/osdp/Kconfig b/subsys/mgmt/osdp/Kconfig index 8fee4185189..2d19d796043 100644 --- a/subsys/mgmt/osdp/Kconfig +++ b/subsys/mgmt/osdp/Kconfig @@ -70,7 +70,7 @@ config OSDP_SKIP_MARK_BYTE config OSDP_SC_ENABLED bool "OSDP Secure Channel" - depends on CSPRING_ENABLED + depends on CSPRNG_ENABLED default y select CRYPTO select CRYPTO_MBEDTLS_SHIM diff --git a/subsys/random/Kconfig b/subsys/random/Kconfig index 6629b0d6b08..b8b6b2135c2 100644 --- a/subsys/random/Kconfig +++ b/subsys/random/Kconfig @@ -72,8 +72,7 @@ endchoice # RNG_GENERATOR_CHOICE # enabling CS generators. ENTROPY_HAS_DRIVER is the flag indicating the # CS entropy source. # -config CSPRING_ENABLED -# bool "Cryptographically secure RNG functions enabled" +config CSPRNG_ENABLED bool default y depends on ENTROPY_HAS_DRIVER diff --git a/tests/crypto/rand32/src/main.c b/tests/crypto/rand32/src/main.c index 7b5a06083f1..7500fb42382 100644 --- a/tests/crypto/rand32/src/main.c +++ b/tests/crypto/rand32/src/main.c @@ -85,7 +85,7 @@ ZTEST(rand32_common, test_rand32) "random numbers returned same value with high probability"); } -#if defined(CONFIG_CSPRING_ENABLED) +#if defined(CONFIG_CSPRNG_ENABLED) printk("Generating bulk fill cryptographically secure random numbers\n"); @@ -109,7 +109,7 @@ ZTEST(rand32_common, test_rand32) printk("Cryptographically secure random number APIs not enabled\n"); -#endif /* CONFIG_CSPRING_ENABLED */ +#endif /* CONFIG_CSPRNG_ENABLED */ } ZTEST_SUITE(rand32_common, NULL, NULL, NULL, NULL, NULL); From 5d505c7b28dbd0399db6948db1859ac82c575726 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 22 Sep 2023 14:28:08 -0700 Subject: [PATCH 1176/4498] random: Fix feature dependency usage Code using sys_csrand_get should depend on CONFIG_CSPRNG_ENABLED symbol and not in ENTROPY_HAS_DRIVER since they are not using the entropy device directly. Signed-off-by: Flavio Ceolin --- modules/openthread/platform/entropy.c | 2 +- subsys/net/lib/sockets/sockets_tls.c | 4 ++-- subsys/random/rand32_handlers.c | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/openthread/platform/entropy.c b/modules/openthread/platform/entropy.c index fd5d797a469..b02ab3c3ee9 100644 --- a/modules/openthread/platform/entropy.c +++ b/modules/openthread/platform/entropy.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(net_otPlat_entropy, CONFIG_OPENTHREAD_L2_LOG_LEVEL); -#if !defined(CONFIG_ENTROPY_HAS_DRIVER) +#if !defined(CONFIG_CSPRNG_ENABLED) #error OpenThread requires an entropy source for a TRNG #endif diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index a6950243392..a4aab077beb 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -272,7 +272,7 @@ static int tls_ctr_drbg_random(void *ctx, unsigned char *buf, size_t len) { ARG_UNUSED(ctx); -#if defined(CONFIG_ENTROPY_HAS_DRIVER) +#if defined(CONFIG_CSPRNG_ENABLED) return sys_csrand_get(buf, len); #else sys_rand_get(buf, len); @@ -1681,7 +1681,7 @@ static int tls_opt_dtls_connection_id_set(struct tls_context *context, context->options.dtls_cid.enabled = true; if (context->options.dtls_cid.cid_len == 0) { /* generate random self cid */ -#if defined(CONFIG_ENTROPY_HAS_DRIVER) +#if defined(CONFIG_CSPRNG_ENABLED) sys_csrand_get(context->options.dtls_cid.cid, MBEDTLS_SSL_CID_OUT_LEN_MAX); #else diff --git a/subsys/random/rand32_handlers.c b/subsys/random/rand32_handlers.c index d1e8cd8c15a..4a407c01e65 100644 --- a/subsys/random/rand32_handlers.c +++ b/subsys/random/rand32_handlers.c @@ -22,8 +22,7 @@ static inline void z_vrfy_sys_rand_get(void *dst, size_t len) } #include -#if defined(CONFIG_CTR_DRBG_CSPRNG_GENERATOR) || \ - defined(CONFIG_HARDWARE_DEVICE_CS_GENERATOR) +#ifdef CONFIG_CSPRNG_ENABLED static inline int z_vrfy_sys_csrand_get(void *dst, size_t len) { Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, len)); From a49720ab08c85324c832183a2f8bdb732080d4e0 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Tue, 19 Sep 2023 10:08:25 +0200 Subject: [PATCH 1177/4498] west.yml: use latest STM32 HAL to get PTP to work In the HAL_ETH_ReadData function where it checks for the last descriptor, I added a checked if the TSA bit was set in DESC1 If the TSA bit is set then have a peak at the context descriptor which should be the one after the last descriptor If the CTXT bit is set in the context descriptor then extract the timestamps Signed-off-by: Marc Desvaux --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d8fa2096031..b7f6f496c59 100644 --- a/west.yml +++ b/west.yml @@ -235,7 +235,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 1bc72c299d0365c0ee2575a97918b22df0899e10 + revision: 89ef0a3383edebf661073073bcdf6e2836fe90ee path: modules/hal/stm32 groups: - hal From 0b0aa435afc8b0102b437ae145203daada6c616b Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Sat, 2 Sep 2023 13:35:14 -0300 Subject: [PATCH 1178/4498] zbus: Add Message subscriber Besides the changed channel reference, the message subscribers receive a copy of the message during the VDED execution. ZBus guarantees message delivery for `MSG_SUBSCRIBERS`. Signed-off-by: Rodrigo Peixoto --- include/zephyr/zbus/zbus.h | 68 +++++++++++++++++- subsys/zbus/Kconfig | 30 ++++++++ subsys/zbus/zbus.c | 144 +++++++++++++++++++++++++++++++------ 3 files changed, 219 insertions(+), 23 deletions(-) diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index 466a2ad9dcf..8a4188aa821 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -92,7 +92,8 @@ struct zbus_channel { */ enum __packed zbus_observer_type { ZBUS_OBSERVER_LISTENER_TYPE, - ZBUS_OBSERVER_SUBSCRIBER_TYPE + ZBUS_OBSERVER_SUBSCRIBER_TYPE, + ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, }; /** @@ -127,6 +128,13 @@ struct zbus_observer { /** Observer callback function. It turns the observer into a listener. */ void (*const callback)(const struct zbus_channel *chan); + +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__) + /** Observer message FIFO. It turns the observer into a message subscriber. It only + * exists if the @kconfig{CONFIG_ZBUS_MSG_SUBSCRIBER} is enabled. + */ + struct k_fifo *const message_fifo; +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ }; }; @@ -156,8 +164,10 @@ struct zbus_channel_observation { #if defined(CONFIG_ZBUS_CHANNEL_NAME) #define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name, +#define _ZBUS_CHAN_NAME(_chan) (_chan)->name #else #define ZBUS_CHANNEL_NAME_INIT(_name) +#define _ZBUS_CHAN_NAME(_chan) "" #endif #if defined(CONFIG_ZBUS_OBSERVER_NAME) @@ -379,6 +389,37 @@ k_timeout_t _zbus_timeout_remainder(uint64_t end_ticks); */ #define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true) +/** + * @brief Define and initialize a message subscriber. + * + * This macro defines an observer of @ref ZBUS_OBSERVER_SUBSCRIBER_TYPE type. It defines a FIFO + * where the subscriber will receive the message asynchronously and initialize the @ref + * zbus_observer defining the subscriber. + * + * @param[in] _name The subscriber's name. + * @param[in] _enable The subscriber's initial state. + */ +#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \ + static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \ + STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \ + ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \ + .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \ + .enabled = _enable, \ + .message_fifo = &_zbus_observer_fifo_##_name, \ + } + +/** + * @brief Define and initialize an enabled message subscriber. + * + * This macro defines an observer of message subscriber type. It defines a FIFO where the + * subscriber will receive the message asynchronously and initialize the @ref + * zbus_observer defining the subscriber. The message subscribers are defined in the enabled state + * with this macro. + + * + * @param[in] _name The subscriber's name. + */ +#define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true) /** * * @brief Publish to a channel @@ -741,6 +782,31 @@ static inline const char *zbus_obs_name(const struct zbus_observer *obs) int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan, k_timeout_t timeout); +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__) + +/** + * @brief Wait for a channel message. + * + * This routine makes the subscriber wait for the new message in case of channel publication. + * + * @param[in] sub The subscriber's reference. + * @param[out] chan The notification channel's reference. + * @param[out] msg A reference to a copy of the published message. + * @param[in] timeout Waiting period for a notification arrival, + * or one of the special values, K_NO_WAIT and K_FOREVER. + * + * @retval 0 Message received. + * @retval -EINVAL The observer is not a subscriber. + * @retval -ENOMSG Could not retrieve the net_buf from the subscriber FIFO. + * @retval -EILSEQ Received an invalid channel reference. + * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The + * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled. + */ +int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg, + k_timeout_t timeout); + +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + /** * * @brief Iterate over channels. diff --git a/subsys/zbus/Kconfig b/subsys/zbus/Kconfig index 622f89641a2..f250865b466 100644 --- a/subsys/zbus/Kconfig +++ b/subsys/zbus/Kconfig @@ -18,6 +18,36 @@ config ZBUS_CHANNEL_NAME config ZBUS_OBSERVER_NAME bool "Observer name field" +config ZBUS_MSG_SUBSCRIBER + select NET_BUF + bool "Message subscribers will receive all messages in sequence." + +if ZBUS_MSG_SUBSCRIBER + +choice + prompt "ZBus msg_subscribers buffer allocation" + +config ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC + bool "Use heap to allocate msg_subscriber buffers data" + +config ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC + bool "Use fixed data size for msg_subscriber buffers pool" + +endchoice + +config ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE + default 16 + int "The count of net_buf available to be used simutaneously." + +if ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC + +config ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE + int "The size of the biggest message used with ZBus." + +endif # ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC + +endif # ZBUS_MSG_SUBSCRIBER + config ZBUS_RUNTIME_OBSERVERS bool "Runtime observers support." default n diff --git a/subsys/zbus/zbus.c b/subsys/zbus/zbus.c index abaf92c8641..4ea2d986a3f 100644 --- a/subsys/zbus/zbus.c +++ b/subsys/zbus/zbus.c @@ -8,11 +8,47 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(zbus, CONFIG_ZBUS_LOG_LEVEL); +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) + +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC) + +NET_BUF_POOL_HEAP_DEFINE(_zbus_msg_subscribers_pool, CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE, + sizeof(struct zbus_channel *), NULL); +BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE > 0, "MSG_SUBSCRIBER feature requires heap memory pool."); + +static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, size_t size, + k_timeout_t timeout) +{ + return net_buf_alloc_len(&_zbus_msg_subscribers_pool, size, timeout); +} + +#else + +NET_BUF_POOL_FIXED_DEFINE(_zbus_msg_subscribers_pool, + (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE), + (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE), + sizeof(struct zbus_channel *), NULL); + +static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, size_t size, + k_timeout_t timeout) +{ + __ASSERT(size <= CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE, + "CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE must be greater or equal to " + "%d", + (int)size); + return net_buf_alloc(&_zbus_msg_subscribers_pool, timeout); +} +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */ + +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + int _zbus_init(void) { + const struct zbus_channel *curr = NULL; const struct zbus_channel *prev = NULL; @@ -44,32 +80,62 @@ int _zbus_init(void) SYS_INIT(_zbus_init, APPLICATION, CONFIG_ZBUS_CHANNELS_SYS_INIT_PRIORITY); static inline int _zbus_notify_observer(const struct zbus_channel *chan, - const struct zbus_observer *obs, k_timepoint_t end_time) + const struct zbus_observer *obs, k_timepoint_t end_time, + struct net_buf *buf) { - int err = 0; - - if (obs->type == ZBUS_OBSERVER_LISTENER_TYPE) { + switch (obs->type) { + case ZBUS_OBSERVER_LISTENER_TYPE: { obs->callback(chan); + break; + } + case ZBUS_OBSERVER_SUBSCRIBER_TYPE: { + return k_msgq_put(obs->queue, &chan, sys_timepoint_timeout(end_time)); + } +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) + case ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE: { + struct net_buf *cloned_buf = net_buf_clone(buf, sys_timepoint_timeout(end_time)); - } else if (obs->type == ZBUS_OBSERVER_SUBSCRIBER_TYPE) { - err = k_msgq_put(obs->queue, &chan, sys_timepoint_timeout(end_time)); - } else { - CODE_UNREACHABLE; + if (cloned_buf == NULL) { + return -ENOMEM; + } + memcpy(net_buf_user_data(cloned_buf), &chan, sizeof(struct zbus_channel *)); + + net_buf_put(obs->message_fifo, cloned_buf); + + break; } - return err; +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + + default: + _ZBUS_ASSERT(false, "Unreachable"); + } + return 0; } static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t end_time) { int err = 0; int last_error = 0; - - _ZBUS_ASSERT(chan != NULL, "chan is required"); + struct net_buf *buf = NULL; /* Static observer event dispatcher logic */ struct zbus_channel_observation *observation; struct zbus_channel_observation_mask *observation_mask; +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) + buf = _zbus_create_net_buf(&_zbus_msg_subscribers_pool, zbus_chan_msg_size(chan), + sys_timepoint_timeout(end_time)); + + _ZBUS_ASSERT(buf != NULL, "net_buf zbus_msg_subscribers_pool is " + "unavailable or heap is full"); + + net_buf_add_mem(buf, zbus_chan_msg(chan), zbus_chan_msg_size(chan)); +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + + LOG_DBG("Notifing %s's observers. Starting VDED:", _ZBUS_CHAN_NAME(chan)); + + int __maybe_unused index = 0; + for (int16_t i = chan->data->observers_start_idx, limit = chan->data->observers_end_idx; i < limit; ++i) { STRUCT_SECTION_GET(zbus_channel_observation, i, &observation); @@ -83,15 +149,21 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t continue; } - err = _zbus_notify_observer(chan, obs, end_time); - - _ZBUS_ASSERT(err == 0, - "could not deliver notification to observer %s. Error code %d", - _ZBUS_OBS_NAME(obs), err); + err = _zbus_notify_observer(chan, obs, end_time, buf); if (err) { last_error = err; + LOG_ERR("could not deliver notification to observer %s. Error code %d", + _ZBUS_OBS_NAME(obs), err); + if (err == -ENOMEM) { + if (IS_ENABLED(CONFIG_ZBUS_MSG_SUBSCRIBER)) { + net_buf_unref(buf); + } + return err; + } } + + LOG_DBG(" %d -> %s", index++, _ZBUS_OBS_NAME(obs)); } #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) @@ -100,15 +172,13 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&chan->data->observers, obs_nd, tmp, node) { - _ZBUS_ASSERT(obs_nd != NULL, "observer node is NULL"); - const struct zbus_observer *obs = obs_nd->obs; if (!obs->enabled) { continue; } - err = _zbus_notify_observer(chan, obs, end_time); + err = _zbus_notify_observer(chan, obs, end_time, buf); if (err) { last_error = err; @@ -116,6 +186,8 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t } #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */ + IF_ENABLED(CONFIG_ZBUS_MSG_SUBSCRIBER, (net_buf_unref(buf);)) + return last_error; } @@ -215,15 +287,43 @@ int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **c { _ZBUS_ASSERT(!k_is_in_isr(), "zbus cannot be used inside ISRs"); _ZBUS_ASSERT(sub != NULL, "sub is required"); + _ZBUS_ASSERT(sub->type == ZBUS_OBSERVER_SUBSCRIBER_TYPE, "sub must be a SUBSCRIBER"); + _ZBUS_ASSERT(sub->queue != NULL, "sub queue is required"); + _ZBUS_ASSERT(chan != NULL, "chan is required"); + + return k_msgq_get(sub->queue, chan, timeout); +} + +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) + +int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg, + k_timeout_t timeout) +{ + _ZBUS_ASSERT(!k_is_in_isr(), "zbus subscribers cannot be used inside ISRs"); + _ZBUS_ASSERT(sub != NULL, "sub is required"); + _ZBUS_ASSERT(sub->type == ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, + "sub must be a MSG_SUBSCRIBER"); + _ZBUS_ASSERT(sub->message_fifo != NULL, "sub message_fifo is required"); _ZBUS_ASSERT(chan != NULL, "chan is required"); + _ZBUS_ASSERT(msg != NULL, "msg is required"); + + struct net_buf *buf = net_buf_get(sub->message_fifo, timeout); - if (sub->queue == NULL) { - return -EINVAL; + if (buf == NULL) { + return -ENOMSG; } - return k_msgq_get(sub->queue, chan, timeout); + *chan = *((struct zbus_channel **)net_buf_user_data(buf)); + + memcpy(msg, net_buf_remove_mem(buf, zbus_chan_msg_size(*chan)), zbus_chan_msg_size(*chan)); + + net_buf_unref(buf); + + return 0; } +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + int zbus_obs_set_chan_notification_mask(const struct zbus_observer *obs, const struct zbus_channel *chan, bool masked) { From 94f98b6cf05c0834e3bc3c8b7274138da15f9540 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Tue, 11 Jul 2023 16:32:29 -0300 Subject: [PATCH 1179/4498] samples: zbus: add Message subscriber sample This sample illustrates how to use message subscribers with ZBus. Signed-off-by: Rodrigo Peixoto --- .../subsys/zbus/msg_subscriber/CMakeLists.txt | 8 + samples/subsys/zbus/msg_subscriber/Kconfig | 10 + samples/subsys/zbus/msg_subscriber/README.rst | 78 +++++++ samples/subsys/zbus/msg_subscriber/prj.conf | 12 ++ .../subsys/zbus/msg_subscriber/sample.yaml | 183 +++++++++++++++++ samples/subsys/zbus/msg_subscriber/src/main.c | 194 ++++++++++++++++++ 6 files changed, 485 insertions(+) create mode 100644 samples/subsys/zbus/msg_subscriber/CMakeLists.txt create mode 100644 samples/subsys/zbus/msg_subscriber/Kconfig create mode 100644 samples/subsys/zbus/msg_subscriber/README.rst create mode 100644 samples/subsys/zbus/msg_subscriber/prj.conf create mode 100644 samples/subsys/zbus/msg_subscriber/sample.yaml create mode 100644 samples/subsys/zbus/msg_subscriber/src/main.c diff --git a/samples/subsys/zbus/msg_subscriber/CMakeLists.txt b/samples/subsys/zbus/msg_subscriber/CMakeLists.txt new file mode 100644 index 00000000000..3d8f35c0925 --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(msg_subscriber) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/zbus/msg_subscriber/Kconfig b/samples/subsys/zbus/msg_subscriber/Kconfig new file mode 100644 index 00000000000..3d9e72ce843 --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Rodrigo Peixoto +# SPDX-License-Identifier: Apache-2.0 + +config ZBUS_MSG_SUBSCRIBER_SAMPLE + bool "Force selection of heap listener configurations" + default y + select SYS_HEAP_LISTENER + select SYS_HEAP_RUNTIME_STATS + +source "Kconfig.zephyr" diff --git a/samples/subsys/zbus/msg_subscriber/README.rst b/samples/subsys/zbus/msg_subscriber/README.rst new file mode 100644 index 00000000000..79d52e006f0 --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/README.rst @@ -0,0 +1,78 @@ +.. zephyr:code-sample:: zbus-msg-subscriber + :name: Message subscriber + :relevant-api: zbus_apis + + Use zbus message subscribers to listen to messages published to channels. + +Overview +******** +This sample illustrates how to use a message subscriber in different +ways in conjunction with other types of observers. + +Building and Running +******************** + +This project outputs to the console. It can be built and executed +on QEMU as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/zbus/msg_subscriber + :host-os: unix + :board: qemu_x86 + :goals: run + +Sample Output +============= + +.. code-block:: console + + -- west build: running target run + [0/1] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: qemu32,+nx,+pae + Booting from ROM.. + I: ----> Publishing to acc_data_chan channel + I: AL Memory allocated 28 bytes. Total allocated 28 bytes + I: From listener foo_lis -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub1 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub2 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub3 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub4 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub5 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub6 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub7 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub8 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub9 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub10 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub11 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub12 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub13 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub14 -> Acc x=1, y=10, z=100 + I: From msg subscriber bar_msg_sub15 -> Acc x=1, y=10, z=100 + I: FR Memory freed 28 bytes. Total allocated 0 bytes + I: From msg subscriber bar_msg_sub16 -> Acc x=1, y=10, z=100 + I: From subscriber bar_sub1 -> Acc x=1, y=10, z=100 + I: From subscriber bar_sub2 -> Acc x=1, y=10, z=100 + I: ----> Publishing to acc_data_chan channel + I: AL Memory allocated 28 bytes. Total allocated 28 bytes + I: From listener foo_lis -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub1 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub2 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub3 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub4 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub5 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub6 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub7 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub8 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub9 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub10 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub11 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub12 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub13 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub14 -> Acc x=2, y=20, z=200 + I: From msg subscriber bar_msg_sub15 -> Acc x=2, y=20, z=200 + I: FR Memory freed 28 bytes. Total allocated 0 bytes + I: From msg subscriber bar_msg_sub16 -> Acc x=2, y=20, z=200 + I: From subscriber bar_sub1 -> Acc x=2, y=20, z=200 + I: From subscriber bar_sub2 -> Acc x=2, y=20, z=200 + + +Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. diff --git a/samples/subsys/zbus/msg_subscriber/prj.conf b/samples/subsys/zbus/msg_subscriber/prj.conf new file mode 100644 index 00000000000..3e786a6d7ed --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/prj.conf @@ -0,0 +1,12 @@ +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y +CONFIG_ASSERT=y +CONFIG_BOOT_BANNER=n +CONFIG_MAIN_THREAD_PRIORITY=5 +CONFIG_ZBUS=y +CONFIG_ZBUS_LOG_LEVEL_INF=y +CONFIG_ZBUS_CHANNEL_NAME=y +CONFIG_ZBUS_OBSERVER_NAME=y +CONFIG_ZBUS_MSG_SUBSCRIBER=y +CONFIG_HEAP_MEM_POOL_SIZE=1024 +CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE=32 diff --git a/samples/subsys/zbus/msg_subscriber/sample.yaml b/samples/subsys/zbus/msg_subscriber/sample.yaml new file mode 100644 index 00000000000..a344a9ee087 --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/sample.yaml @@ -0,0 +1,183 @@ +sample: + name: Message subscriber +tests: + sample.zbus.msg_subscriber_dynamic: + harness: console + extra_configs: + - CONFIG_ZBUS_LOG_LEVEL_DBG=y + harness_config: + type: multi_line + ordered: false + regex: + - "^.*?I: ----> Publishing to acc_data_chan channel" + - "^.*?I: AL Memory allocated \\d{1,3} bytes. Total allocated \\d{1,3} bytes$" + - "^.*?I: FR Memory freed \\d{1,3} bytes. Total allocated 0 bytes$" + - "^.*?D: 0 -> bar_sub1" + - "^.*?D: 1 -> bar_msg_sub1" + - "^.*?D: 2 -> bar_msg_sub2" + - "^.*?D: 3 -> bar_msg_sub3" + - "^.*?D: 4 -> bar_msg_sub4" + - "^.*?D: 5 -> bar_msg_sub5" + - "^.*?D: 6 -> bar_msg_sub6" + - "^.*?D: 7 -> bar_msg_sub7" + - "^.*?D: 8 -> bar_msg_sub8" + - "^.*?D: 9 -> bar_msg_sub9" + - "^.*?D: 10 -> foo_lis" + - "^.*?D: 11 -> bar_msg_sub10" + - "^.*?D: 12 -> bar_msg_sub11" + - "^.*?D: 13 -> bar_msg_sub12" + - "^.*?D: 14 -> bar_msg_sub13" + - "^.*?D: 15 -> bar_msg_sub14" + - "^.*?D: 16 -> bar_msg_sub15" + - "^.*?D: 17 -> bar_msg_sub16" + - "^.*?D: 18 -> bar_sub2" + - "^.*?I: From listener foo_lis -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=1, y=10, z=100" + - "^.*?I: From subscriber bar_sub1 -> Acc x=1, y=10, z=100" + - "^.*?I: From subscriber bar_sub2 -> Acc x=1, y=10, z=100" + - "^.*?I: From listener foo_lis -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=2, y=20, z=200" + - "^.*?I: From subscriber bar_sub1 -> Acc x=2, y=20, z=200" + - "^.*?I: From subscriber bar_sub2 -> Acc x=2, y=20, z=200" + - "^.*?I: From listener foo_lis -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=3, y=30, z=300" + - "^.*?I: From subscriber bar_sub1 -> Acc x=3, y=30, z=300" + - "^.*?I: From subscriber bar_sub2 -> Acc x=3, y=30, z=300" + tags: zbus + integration_platforms: + - qemu_x86 + sample.zbus.msg_subscriber_static: + harness: console + extra_configs: + - CONFIG_ZBUS_LOG_LEVEL_DBG=y + - CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC=y + - CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE=16 + harness_config: + type: multi_line + ordered: false + regex: + - "^.*?I: ----> Publishing to acc_data_chan channel" + - "^.*?D: 0 -> bar_sub1" + - "^.*?D: 1 -> bar_msg_sub1" + - "^.*?D: 2 -> bar_msg_sub2" + - "^.*?D: 3 -> bar_msg_sub3" + - "^.*?D: 4 -> bar_msg_sub4" + - "^.*?D: 5 -> bar_msg_sub5" + - "^.*?D: 6 -> bar_msg_sub6" + - "^.*?D: 7 -> bar_msg_sub7" + - "^.*?D: 8 -> bar_msg_sub8" + - "^.*?D: 9 -> bar_msg_sub9" + - "^.*?D: 10 -> foo_lis" + - "^.*?D: 11 -> bar_msg_sub10" + - "^.*?D: 12 -> bar_msg_sub11" + - "^.*?D: 13 -> bar_msg_sub12" + - "^.*?D: 14 -> bar_msg_sub13" + - "^.*?D: 15 -> bar_msg_sub14" + - "^.*?D: 16 -> bar_msg_sub15" + - "^.*?D: 17 -> bar_msg_sub16" + - "^.*?D: 18 -> bar_sub2" + - "^.*?I: From listener foo_lis -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=1, y=10, z=100" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=1, y=10, z=100" + - "^.*?I: From subscriber bar_sub1 -> Acc x=1, y=10, z=100" + - "^.*?I: From subscriber bar_sub2 -> Acc x=1, y=10, z=100" + - "^.*?I: From listener foo_lis -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=2, y=20, z=200" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=2, y=20, z=200" + - "^.*?I: From subscriber bar_sub1 -> Acc x=2, y=20, z=200" + - "^.*?I: From subscriber bar_sub2 -> Acc x=2, y=20, z=200" + - "^.*?I: From listener foo_lis -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub1 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub2 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub3 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub4 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub5 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub6 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub7 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub8 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub9 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub10 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub11 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub12 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub13 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub14 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub15 -> Acc x=3, y=30, z=300" + - "^.*?I: From msg subscriber bar_msg_sub16 -> Acc x=3, y=30, z=300" + - "^.*?I: From subscriber bar_sub1 -> Acc x=3, y=30, z=300" + - "^.*?I: From subscriber bar_sub2 -> Acc x=3, y=30, z=300" + tags: zbus + integration_platforms: + - qemu_x86 diff --git a/samples/subsys/zbus/msg_subscriber/src/main.c b/samples/subsys/zbus/msg_subscriber/src/main.c new file mode 100644 index 00000000000..03f9cead113 --- /dev/null +++ b/samples/subsys/zbus/msg_subscriber/src/main.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2022 Rodrigo Peixoto + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +LOG_MODULE_REGISTER(sample, CONFIG_LOG_MAX_LEVEL); + +extern struct sys_heap _system_heap; +static size_t total_allocated; + +void on_heap_alloc(uintptr_t heap_id, void *mem, size_t bytes) +{ + total_allocated += bytes; + LOG_INF(" AL Memory allocated %u bytes. Total allocated %u bytes", (unsigned int)bytes, + (unsigned int)total_allocated); +} + +void on_heap_free(uintptr_t heap_id, void *mem, size_t bytes) +{ + total_allocated -= bytes; + LOG_INF(" FR Memory freed %u bytes. Total allocated %u bytes", (unsigned int)bytes, + (unsigned int)total_allocated); +} + +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC) + +HEAP_LISTENER_ALLOC_DEFINE(my_heap_listener_alloc, HEAP_ID_FROM_POINTER(&_system_heap), + on_heap_alloc); + +HEAP_LISTENER_FREE_DEFINE(my_heap_listener_free, HEAP_ID_FROM_POINTER(&_system_heap), on_heap_free); + +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */ +struct acc_msg { + int x; + int y; + int z; +}; + +ZBUS_CHAN_DEFINE(acc_data_chan, /* Name */ + struct acc_msg, /* Message type */ + + NULL, /* Validator */ + NULL, /* User data */ + ZBUS_OBSERVERS(bar_sub1, bar_msg_sub1, bar_msg_sub2, bar_msg_sub3, bar_msg_sub4, + bar_msg_sub5, bar_msg_sub6, bar_msg_sub7, bar_msg_sub8, + bar_msg_sub9, foo_lis), /* observers */ + ZBUS_MSG_INIT(.x = 0, .y = 0, .z = 0) /* Initial value */ +); + +static void listener_callback_example(const struct zbus_channel *chan) +{ + const struct acc_msg *acc = zbus_chan_const_msg(chan); + + LOG_INF("From listener foo_lis -> Acc x=%d, y=%d, z=%d", acc->x, acc->y, acc->z); +} + +ZBUS_LISTENER_DEFINE(foo_lis, listener_callback_example); + +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub1); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub2); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub3); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub4); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub5); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub6); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub7); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub8); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub9); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub10); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub11); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub12); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub13); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub14); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub15); +ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub16); + +ZBUS_SUBSCRIBER_DEFINE(bar_sub1, 4); +ZBUS_SUBSCRIBER_DEFINE(bar_sub2, 4); + +static void msg_subscriber_task(void *sub) +{ + const struct zbus_channel *chan; + + struct acc_msg acc; + + const struct zbus_observer *subscriber = sub; + + while (!zbus_sub_wait_msg(subscriber, &chan, &acc, K_FOREVER)) { + if (&acc_data_chan != chan) { + LOG_ERR("Wrong channel %p!", chan); + + continue; + } + LOG_INF("From msg subscriber %s -> Acc x=%d, y=%d, z=%d", zbus_obs_name(subscriber), + acc.x, acc.y, acc.z); + } +} + +K_THREAD_DEFINE(subscriber_task_id1, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub1, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id2, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub2, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id3, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub3, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id4, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub4, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id5, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub5, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id6, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub6, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id7, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub7, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id8, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub8, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id9, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub9, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id10, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub10, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id11, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub11, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id12, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub12, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id13, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub13, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id14, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub14, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id15, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub15, + NULL, NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id16, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub16, + NULL, NULL, 3, 0, 0); + +static void subscriber_task(void *sub) +{ + const struct zbus_channel *chan; + + struct acc_msg acc; + + const struct zbus_observer *subscriber = sub; + + while (!zbus_sub_wait(subscriber, &chan, K_FOREVER)) { + if (&acc_data_chan != chan) { + LOG_ERR("Wrong channel %p!", chan); + + continue; + } + zbus_chan_read(chan, &acc, K_MSEC(250)); + + LOG_INF("From subscriber %s -> Acc x=%d, y=%d, z=%d", zbus_obs_name(subscriber), + acc.x, acc.y, acc.z); + } +} + +K_THREAD_DEFINE(subscriber_task_id17, CONFIG_MAIN_STACK_SIZE, subscriber_task, &bar_sub1, NULL, + NULL, 3, 0, 0); +K_THREAD_DEFINE(subscriber_task_id18, CONFIG_MAIN_STACK_SIZE, subscriber_task, &bar_sub2, NULL, + NULL, 3, 0, 0); + +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_sub2, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub10, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub11, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub12, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub13, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub14, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub15, 3); +ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub16, 3); + +int main(void) +{ + struct acc_msg acc = {.x = 1, .y = 10, .z = 100}; + + total_allocated = 0; + +#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC) + + heap_listener_register(&my_heap_listener_alloc); + heap_listener_register(&my_heap_listener_free); + +#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */ + + while (1) { + LOG_INF("----> Publishing to %s channel", zbus_chan_name(&acc_data_chan)); + zbus_chan_pub(&acc_data_chan, &acc, K_SECONDS(1)); + acc.x += 1; + acc.y += 10; + acc.z += 100; + + k_msleep(1000); + } + + return 0; +} From 43c8df789394eba9070e57414a59dce251ce21bc Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Sat, 2 Sep 2023 21:36:00 -0300 Subject: [PATCH 1180/4498] test: zbus: Add tests for MSG_SUBSCRIBERS Add specification-based and integration tests for `MSG_SUBSCRIBERS`. Signed-off-by: Rodrigo Peixoto --- tests/subsys/zbus/integration/prj.conf | 2 + tests/subsys/zbus/integration/src/channels.c | 9 ++ tests/subsys/zbus/integration/src/main.c | 60 ++++++++- tests/subsys/zbus/integration/src/messages.h | 4 + tests/subsys/zbus/unittests/prj.conf | 2 + tests/subsys/zbus/unittests/src/main.c | 134 ++++++++++++++++++- 6 files changed, 204 insertions(+), 7 deletions(-) diff --git a/tests/subsys/zbus/integration/prj.conf b/tests/subsys/zbus/integration/prj.conf index 4d2bd32315d..2735cb28b7c 100644 --- a/tests/subsys/zbus/integration/prj.conf +++ b/tests/subsys/zbus/integration/prj.conf @@ -5,3 +5,5 @@ CONFIG_LOG=y CONFIG_ZBUS=y CONFIG_ZBUS_LOG_LEVEL_DBG=y CONFIG_ZBUS_CHANNEL_NAME=y +CONFIG_ZBUS_MSG_SUBSCRIBER=y +CONFIG_HEAP_MEM_POOL_SIZE=1024 diff --git a/tests/subsys/zbus/integration/src/channels.c b/tests/subsys/zbus/integration/src/channels.c index 82fe1e00bbb..a7197def47a 100644 --- a/tests/subsys/zbus/integration/src/channels.c +++ b/tests/subsys/zbus/integration/src/channels.c @@ -34,6 +34,15 @@ ZBUS_CHAN_DEFINE(net_pkt_chan, /* Name */ ZBUS_MSG_INIT(.total = 0) /* Initial value */ ); +ZBUS_CHAN_DEFINE(net_log_chan, /* Name */ + struct net_log_msg, /* Message type */ + + NULL, /* Validator */ + NULL, /* User data */ + ZBUS_OBSERVERS(net_log_sub), /* observers */ + ZBUS_MSG_INIT(0) /* Initial value */ +); + ZBUS_CHAN_DEFINE(start_measurement_chan, /* Name */ struct action_msg, /* Message type */ diff --git a/tests/subsys/zbus/integration/src/main.c b/tests/subsys/zbus/integration/src/main.c index 147c4e264ab..9539a0c7206 100644 --- a/tests/subsys/zbus/integration/src/main.c +++ b/tests/subsys/zbus/integration/src/main.c @@ -12,7 +12,8 @@ #include LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL); -ZBUS_CHAN_DECLARE(version_chan, sensor_data_chan, net_pkt_chan, start_measurement_chan, busy_chan); +ZBUS_CHAN_DECLARE(version_chan, sensor_data_chan, net_pkt_chan, net_log_chan, + start_measurement_chan, busy_chan); static int count_callback; @@ -69,12 +70,38 @@ static void net_thread(void) zbus_chan_read(&net_pkt_chan, &pkt, K_NO_WAIT); LOG_DBG("[Net] Total %d", pkt.total); + + struct net_log_msg log_msg = {.count_net = count_net, + .pkt_total = pkt.total}; + + zbus_chan_pub(&net_log_chan, &log_msg, K_MSEC(500)); } } } K_THREAD_DEFINE(net_thread_id, 1024, net_thread, NULL, NULL, NULL, 3, 0, 0); +static int count_net_log; + +ZBUS_MSG_SUBSCRIBER_DEFINE(net_log_sub); + +static void net_log_thread(void) +{ + const struct zbus_channel *chan; + struct net_log_msg log_msg; + + while (1) { + if (!zbus_sub_wait_msg(&net_log_sub, &chan, &log_msg, K_FOREVER)) { + count_net_log++; + + LOG_DBG("[Net log]: count_net = %d, pkt.total = %d", log_msg.count_net, + log_msg.pkt_total); + } + } +} + +K_THREAD_DEFINE(net_log_thread_id, 1024, net_log_thread, NULL, NULL, NULL, 3, 0, 0); + static int a; static int b; static int count_peripheral; @@ -116,6 +143,7 @@ static void context_reset(void *f) count_callback = 0; count_core = 0; count_net = 0; + count_net_log = 0; count_peripheral = 0; pkt.total = 0; struct net_pkt_msg *p; @@ -134,15 +162,22 @@ static void context_reset(void *f) zbus_obs_set_enable(&critical_lis, true); zbus_obs_set_enable(&peripheral_sub, true); zbus_chan_claim(&start_measurement_chan, K_NO_WAIT); - struct action_msg *act = (struct action_msg *)start_measurement_chan.message; + struct action_msg *act = (struct action_msg *)zbus_chan_msg(&start_measurement_chan); act->status = false; zbus_chan_finish(&start_measurement_chan); + zbus_chan_claim(&net_log_chan, K_NO_WAIT); + struct net_log_msg *lm = (struct net_log_msg *)zbus_chan_msg(&net_log_chan); + + lm->count_net = 0; + lm->pkt_total = 0; + zbus_chan_finish(&net_log_chan); } ZTEST(integration, test_basic) { struct action_msg start = {true}; + struct net_log_msg *lm = (struct net_log_msg *)zbus_chan_const_msg(&net_log_chan); zassert_equal(0, zbus_chan_pub(&start_measurement_chan, &start, K_MSEC(200)), NULL); @@ -152,6 +187,8 @@ ZTEST(integration, test_basic) zassert_equal(count_core, 1, NULL); zassert_equal(count_net, 1, NULL); zassert_equal(count_peripheral, 1, NULL); + zassert_equal(count_net_log, 1, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(0, zbus_chan_pub(&start_measurement_chan, &start, K_MSEC(200)), NULL); @@ -161,6 +198,8 @@ ZTEST(integration, test_basic) zassert_equal(count_core, 2, NULL); zassert_equal(count_net, 2, NULL); zassert_equal(count_peripheral, 2, NULL); + zassert_equal(count_net_log, 2, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(0, zbus_chan_pub(&start_measurement_chan, &start, K_MSEC(200)), NULL); @@ -170,13 +209,17 @@ ZTEST(integration, test_basic) zassert_equal(count_core, 3, NULL); zassert_equal(count_net, 3, NULL); zassert_equal(count_peripheral, 3, NULL); + zassert_equal(count_net_log, 3, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(pkt.total, 6, "result was %d", pkt.total); + zassert_equal(pkt.total, lm->pkt_total, NULL); } ZTEST(integration, test_channel_set_enable) { struct action_msg start = {true}; + const struct net_log_msg *lm = zbus_chan_const_msg(&net_log_chan); zassert_equal(0, zbus_obs_set_enable(&critical_lis, false), NULL); zassert_equal(0, zbus_obs_set_enable(&peripheral_sub, false), NULL); @@ -186,8 +229,10 @@ ZTEST(integration, test_channel_set_enable) zassert_equal(count_callback, 0, NULL); zassert_equal(count_core, 0, NULL); - zassert_equal(count_net, 0, NULL); zassert_equal(count_peripheral, 0, NULL); + zassert_equal(count_net, 0, NULL); + zassert_equal(count_net_log, 0, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(0, zbus_obs_set_enable(&critical_lis, false), NULL); zassert_equal(0, zbus_obs_set_enable(&peripheral_sub, true), NULL); @@ -199,6 +244,8 @@ ZTEST(integration, test_channel_set_enable) zassert_equal(count_core, 1, NULL); zassert_equal(count_net, 1, NULL); zassert_equal(count_peripheral, 1, NULL); + zassert_equal(count_net_log, 1, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(0, zbus_obs_set_enable(&critical_lis, true), NULL); zassert_equal(0, zbus_obs_set_enable(&peripheral_sub, false), NULL); @@ -210,6 +257,8 @@ ZTEST(integration, test_channel_set_enable) zassert_equal(count_core, 1, NULL); zassert_equal(count_net, 1, NULL); zassert_equal(count_peripheral, 1, NULL); + zassert_equal(count_net_log, 1, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(0, zbus_obs_set_enable(&critical_lis, true), NULL); zassert_equal(0, zbus_obs_set_enable(&peripheral_sub, true), NULL); @@ -219,10 +268,13 @@ ZTEST(integration, test_channel_set_enable) zassert_equal(count_callback, 2, NULL); zassert_equal(count_core, 2, NULL); - zassert_equal(count_net, 2, NULL); zassert_equal(count_peripheral, 2, NULL); + zassert_equal(count_net, 2, NULL); + zassert_equal(count_net_log, 2, NULL); + zassert_equal(count_net, lm->count_net, NULL); zassert_equal(pkt.total, 4, "result was %d", pkt.total); + zassert_equal(pkt.total, lm->pkt_total, NULL); } static void greedy_thread_entry(void *p1, void *p2, void *p3) diff --git a/tests/subsys/zbus/integration/src/messages.h b/tests/subsys/zbus/integration/src/messages.h index aa80c1d7176..76f129246bd 100644 --- a/tests/subsys/zbus/integration/src/messages.h +++ b/tests/subsys/zbus/integration/src/messages.h @@ -26,4 +26,8 @@ struct action_msg { bool status; }; +struct net_log_msg { + int count_net; + int pkt_total; +}; #endif /* _ZBUS_MESSAGES_H_ */ diff --git a/tests/subsys/zbus/unittests/prj.conf b/tests/subsys/zbus/unittests/prj.conf index 736b5ed68cc..db4fd92b3b9 100644 --- a/tests/subsys/zbus/unittests/prj.conf +++ b/tests/subsys/zbus/unittests/prj.conf @@ -6,6 +6,8 @@ CONFIG_ZBUS=y CONFIG_ZBUS_LOG_LEVEL_DBG=y CONFIG_ZBUS_ASSERT_MOCK=y CONFIG_IRQ_OFFLOAD=y +CONFIG_ZBUS_MSG_SUBSCRIBER=y +CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE=2 CONFIG_ZBUS_RUNTIME_OBSERVERS=y CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_ZBUS_CHANNEL_NAME=y diff --git a/tests/subsys/zbus/unittests/src/main.c b/tests/subsys/zbus/unittests/src/main.c index a6aeb2310a4..7c3ff76230a 100644 --- a/tests/subsys/zbus/unittests/src/main.c +++ b/tests/subsys/zbus/unittests/src/main.c @@ -86,6 +86,20 @@ ZBUS_CHAN_DEFINE(stuck_chan, /* Name */ ZBUS_MSG_INIT(0) /* Initial value major 0, minor 1, build 1023 */ ); +ZBUS_CHAN_DEFINE(msg_sub_fail_chan, /* Name */ + int, /* Message type */ + NULL, /* Validator */ + NULL, /* User data */ + ZBUS_OBSERVERS(foo_msg_sub, invalid_obs), /* observers */ + ZBUS_MSG_INIT(0) /* Initial value major 0, minor 1, build 1023 */ +); +ZBUS_CHAN_DEFINE(msg_sub_no_pool_chan, /* Name */ + int, /* Message type */ + NULL, /* Validator */ + NULL, /* User data */ + ZBUS_OBSERVERS(foo_msg_sub, foo2_msg_sub), /* observers */ + ZBUS_MSG_INIT(0) /* Initial value major 0, minor 1, build 1023 */ +); static int count_fast; static void callback(const struct zbus_channel *chan) @@ -207,6 +221,15 @@ static void wq_dh_cb(struct k_work *item) } ZBUS_SUBSCRIBER_DEFINE(sub1, 1); +ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(foo_msg_sub, false); +ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(foo2_msg_sub, false); +static K_FIFO_DEFINE(_zbus_observer_fifo_invalid_obs); +STRUCT_SECTION_ITERABLE(zbus_observer, invalid_obs) = { + ZBUS_OBSERVER_NAME_INIT(invalid_obs) /* Name field */ + .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE + 10, + .enabled = false, + .message_fifo = &_zbus_observer_fifo_invalid_obs, +}; ZTEST(basic, test_specification_based__zbus_chan) { @@ -268,6 +291,14 @@ ZTEST(basic, test_specification_based__zbus_chan) zassert_equal(0, zbus_chan_finish(&aux2_chan), "It must finish correctly"); + int fail = 10; + + zbus_obs_set_enable(&invalid_obs, true); + int err = zbus_chan_pub(&msg_sub_fail_chan, &fail, K_MSEC(200)); + + zassert_equal(-EFAULT, err, "It must reach the default on the switch. Err %d", err); + zbus_obs_set_enable(&invalid_obs, false); + struct action_msg repeated = {.status = false}; zbus_chan_pub(&aux3_on_change_chan, &repeated, K_NO_WAIT); @@ -307,6 +338,19 @@ ZTEST(basic, test_specification_based__zbus_chan) ISR_OP(ADD_OBS_ISR_INVAL, -EFAULT); ISR_OP(RM_OBS_ISR, -EFAULT); ISR_OP(RM_OBS_ISR_INVAL, -EFAULT); + + int msg; + const struct zbus_channel *chan; + + zbus_obs_set_enable(&foo_msg_sub, true); + zbus_obs_set_enable(&foo2_msg_sub, true); + zassert_equal(-ENOMEM, zbus_chan_notify(&msg_sub_no_pool_chan, K_MSEC(200)), + "It must return an error, the pool only have 2 slots. For publishing to " + "MSG_SUBSCRIBERS it is necessary at least one per each and a spare one."); + + zassert_equal(0, zbus_sub_wait_msg(&foo_msg_sub, &chan, &msg, K_MSEC(500)), NULL); + zbus_obs_set_enable(&foo_msg_sub, false); + zbus_obs_set_enable(&foo2_msg_sub, false); } static bool always_true_chan_iterator(const struct zbus_channel *chan) @@ -353,9 +397,17 @@ static bool check_chan_iterator(const struct zbus_channel *chan, void *user_data zassert_mem_equal__(zbus_chan_name(chan), "hard_chan", 9, "Must be equal"); break; case 5: - zassert_mem_equal__(zbus_chan_name(chan), "stuck_chan", 10, "Must be equal"); + zassert_mem_equal__(zbus_chan_name(chan), "msg_sub_fail_chan", + sizeof("msg_sub_fail_chan"), "Must be equal"); break; case 6: + zassert_mem_equal__(zbus_chan_name(chan), "msg_sub_no_pool_chan", + sizeof("msg_sub_no_pool_chan"), "Must be equal"); + break; + case 7: + zassert_mem_equal__(zbus_chan_name(chan), "stuck_chan", 10, "Must be equal"); + break; + case 8: zassert_mem_equal__(zbus_chan_name(chan), "version_chan", 12, "Must be equal"); break; default: @@ -380,12 +432,31 @@ static bool check_obs_iterator(const struct zbus_observer *obs, void *user_data) zassert_mem_equal__(zbus_obs_name(obs), "fast_lis", 8, "Must be equal"); break; case 2: - zassert_mem_equal__(zbus_obs_name(obs), "foo_sub", 7, "Must be equal"); + zassert_mem_equal__(zbus_obs_name(obs), "foo2_msg_sub", sizeof("foo2_msg_sub"), + "Must be equal"); break; case 3: - zassert_mem_equal__(zbus_obs_name(obs), "rt_fast_lis", 11, "Must be equal"); + zassert_mem_equal__(zbus_obs_name(obs), "foo_msg_sub", 11, "Must be equal"); break; case 4: + zassert_mem_equal__(zbus_obs_name(obs), "foo_sub", 7, "Must be equal"); + break; + case 5: + zassert_mem_equal__(zbus_obs_name(obs), "invalid_obs", strlen("invalid_obs"), + "Must be equal"); + break; + case 6: + zassert_mem_equal__(zbus_obs_name(obs), "invalid_sub", strlen("invalid_sub"), + "Must be equal"); + break; + case 7: + zassert_mem_equal__(zbus_obs_name(obs), "not_observing_sub", + strlen("not_observing_sub"), "Must be equal"); + break; + case 8: + zassert_mem_equal__(zbus_obs_name(obs), "rt_fast_lis", 11, "Must be equal"); + break; + case 9: zassert_mem_equal__(zbus_obs_name(obs), "sub1", 4, "Must be equal"); break; default: @@ -570,9 +641,12 @@ ZTEST(basic, test_specification_based__zbus_obs_set_enable) zassert_equal(0, zbus_chan_rm_obs(&aux1_chan, &rt_fast_lis, K_MSEC(200)), NULL); } +ZBUS_SUBSCRIBER_DEFINE(not_observing_sub, 0); + ZTEST(basic, test_specification_based__zbus_obs_set_chan_notification_mask) { bool enabled = false; + bool masked = false; count_fast = 0; @@ -584,6 +658,24 @@ ZTEST(basic, test_specification_based__zbus_obs_set_chan_notification_mask) zassert_equal(-EFAULT, zbus_obs_set_chan_notification_mask(NULL, &aux1_chan, true), NULL); + zassert_equal(-ESRCH, + zbus_obs_set_chan_notification_mask(¬_observing_sub, &aux1_chan, true), + NULL); + + zassert_equal(-EFAULT, zbus_obs_is_chan_notification_masked(NULL, NULL, NULL), NULL); + + zassert_equal(-EFAULT, zbus_obs_is_chan_notification_masked(NULL, NULL, &masked), NULL); + + zassert_equal(-EFAULT, zbus_obs_is_chan_notification_masked(&fast_lis, NULL, &masked), + NULL); + + zassert_equal(-EFAULT, zbus_obs_is_chan_notification_masked(NULL, &aux1_chan, &masked), + NULL); + + zassert_equal(-ESRCH, + zbus_obs_is_chan_notification_masked(¬_observing_sub, &aux1_chan, &masked), + NULL); + zbus_obs_set_chan_notification_mask(&fast_lis, &aux1_chan, true); zbus_obs_is_chan_notification_masked(&fast_lis, &aux1_chan, &enabled); @@ -608,6 +700,10 @@ ZTEST(basic, test_specification_based__zbus_obs_set_chan_notification_mask) ZBUS_SUBSCRIBER_DEFINE(foo_sub, 1); +STRUCT_SECTION_ITERABLE(zbus_observer, + invalid_sub) = {ZBUS_OBSERVER_NAME_INIT(invalid_sub) /* Name field */ + .type = ZBUS_OBSERVER_SUBSCRIBER_TYPE, + .enabled = false, .queue = NULL}; static void isr_sub_wait(const void *operation) { const struct zbus_channel *chan; @@ -616,6 +712,7 @@ static void isr_sub_wait(const void *operation) zassert_equal(-EFAULT, zbus_sub_wait(NULL, NULL, K_NO_WAIT), NULL); zassert_equal(-EFAULT, zbus_sub_wait(&foo_sub, NULL, K_NO_WAIT), NULL); zassert_equal(-EFAULT, zbus_sub_wait(&foo_sub, &chan, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait(&invalid_sub, &chan, K_NO_WAIT), NULL); } ZTEST(basic, test_specification_based__zbus_sub_wait) @@ -625,11 +722,42 @@ ZTEST(basic, test_specification_based__zbus_sub_wait) zassert_equal(-EFAULT, zbus_sub_wait(NULL, NULL, K_NO_WAIT), NULL); zassert_equal(-EFAULT, zbus_sub_wait(&foo_sub, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait(&foo_msg_sub, NULL, K_NO_WAIT), NULL); /* It must run but return a -ENOMSG because of the K_NO_WAIT */ zassert_equal(-ENOMSG, zbus_sub_wait(&foo_sub, &chan, K_NO_WAIT), NULL); + zassert_equal(-EAGAIN, zbus_sub_wait(&foo_sub, &chan, K_MSEC(200)), NULL); irq_offload(isr_sub_wait, NULL); } +static void isr_sub_wait_msg(const void *operation) +{ + const struct zbus_channel *chan; + + /* All the calls must not work. Zbus cannot work in IRSs */ + zassert_equal(-EFAULT, zbus_sub_wait_msg(NULL, NULL, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait_msg(&foo_sub, NULL, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait(&foo_msg_sub, NULL, K_NO_WAIT), NULL); + int a = 0; + + zassert_equal(-EFAULT, zbus_sub_wait_msg(&foo_msg_sub, &chan, &a, K_NO_WAIT), NULL); +} +ZTEST(basic, test_specification_based__zbus_sub_wait_msg) +{ + count_fast = 0; + const struct zbus_channel *chan; + + zassert_equal(-EFAULT, zbus_sub_wait_msg(NULL, NULL, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait_msg(&foo_sub, NULL, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait_msg(&foo_msg_sub, NULL, NULL, K_NO_WAIT), NULL); + zassert_equal(-EFAULT, zbus_sub_wait_msg(&foo_msg_sub, &chan, NULL, K_NO_WAIT), NULL); + int a = 0; + + zassert_equal(-ENOMSG, zbus_sub_wait_msg(&foo_msg_sub, &chan, &a, K_NO_WAIT), NULL); + zassert_equal(-ENOMSG, zbus_sub_wait_msg(&foo_msg_sub, &chan, &a, K_MSEC(200)), NULL); + + irq_offload(isr_sub_wait_msg, NULL); +} + ZTEST_SUITE(basic, NULL, NULL, NULL, NULL, NULL); From d7fd3db32e49139d3e5a5292fc94c414b4cd7516 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 26 Sep 2023 13:19:32 +0300 Subject: [PATCH 1181/4498] drivers: smbus: pch: Simplify IRQ flags Use COND_CODE_1() macro instead of macro trampoline. Signed-off-by: Andrei Emeltchenko --- drivers/smbus/intel_pch_smbus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/smbus/intel_pch_smbus.c b/drivers/smbus/intel_pch_smbus.c index c5713d984a6..e40fc3d0cb6 100644 --- a/drivers/smbus/intel_pch_smbus.c +++ b/drivers/smbus/intel_pch_smbus.c @@ -1005,10 +1005,10 @@ static void smbus_isr(const struct device *dev) /* Device macro initialization / DTS hackery */ -#define SMBUS_PCH_IRQ_FLAGS_SENSE0(n) 0 -#define SMBUS_PCH_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) -#define SMBUS_PCH_IRQ_FLAGS(n) \ - _CONCAT(SMBUS_PCH_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) +#define SMBUS_PCH_IRQ_FLAGS(n) \ + COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, sense), \ + (DT_INST_IRQ(n, sense)), \ + (0)) #define SMBUS_IRQ_CONFIG(n) \ BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), \ From 1dc6a8aa13fa73f9276e411d46d72d983ede0487 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 26 Sep 2023 13:55:56 +0300 Subject: [PATCH 1182/4498] boards: x86: Detect SMBus IRQ instead of hardcoding Detect IRQ for SMBus instead of hardcoding. Signed-off-by: Andrei Emeltchenko --- dts/x86/intel/alder_lake.dtsi | 2 +- dts/x86/intel/elkhart_lake.dtsi | 2 +- dts/x86/intel/raptor_lake.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index 43f552609a4..1cb7a591680 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -57,7 +57,7 @@ #size-cells = <0>; vendor-id = <0x8086>; device-id = <0x54a3>; - interrupts = <16 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; diff --git a/dts/x86/intel/elkhart_lake.dtsi b/dts/x86/intel/elkhart_lake.dtsi index c499497e294..75574d9fcfb 100644 --- a/dts/x86/intel/elkhart_lake.dtsi +++ b/dts/x86/intel/elkhart_lake.dtsi @@ -204,7 +204,7 @@ #size-cells = <0>; vendor-id = <0x8086>; device-id = <0x4b23>; - interrupts = <16 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index bc3c59c2159..d7f9517dda9 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -56,7 +56,7 @@ #size-cells = <0>; vendor-id = <0x8086>; device-id = <0x7a23>; - interrupts = <18 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; From 90c3547479be39c53cc2f017a6906d4184677496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 10:40:12 +0200 Subject: [PATCH 1183/4498] boards: riscv: doc: Fix dead link in Telink TLSR9518ADK80D documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated a link to a Telink wiki page that was an HTTP 404. Signed-off-by: Benjamin Cabé --- boards/riscv/tlsr9518adk80d/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/riscv/tlsr9518adk80d/doc/index.rst b/boards/riscv/tlsr9518adk80d/doc/index.rst index 62c6b93cf3a..8f478709934 100644 --- a/boards/riscv/tlsr9518adk80d/doc/index.rst +++ b/boards/riscv/tlsr9518adk80d/doc/index.rst @@ -7,7 +7,7 @@ Overview ******** The TLSR9518A Generic Starter Kit is a hardware platform which -can be used to verify the `Telink TLSR9 series chipset`_ and develop applications +can be used to verify the `Telink TLSR951x series chipset`_ and develop applications for several 2.4 GHz air interface standards including Bluetooth 5.2 (Basic data rate, Enhanced data rate, LE, Indoor positioning and BLE Mesh), Zigbee 3.0, Homekit, 6LoWPAN, Thread and 2.4 Ghz proprietary. @@ -259,7 +259,7 @@ References .. target-notes:: -.. _Telink TLSR9 series chipset: http://wiki.telink-semi.cn/wiki/chip-series/TLSR9-Series/ +.. _Telink TLSR951x series chipset: http://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series/ .. _Telink B91 Generic Starter Kit Hardware Guide: http://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/ .. _Telink RISC-V Linux Toolchain: http://wiki.telink-semi.cn/tools_and_sdk/Tools/IDE/telink_riscv_linux_toolchain.zip .. _Burning and Debugging Tools for all Series: http://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-all-Series/ From 3055401607f85d33d5ed55294a6e807e00bae496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 10:50:04 +0200 Subject: [PATCH 1184/4498] boards: riscv: doc: Use https for links to Telink wiki MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update URLs to Telink wiki to use https instead of http. Signed-off-by: Benjamin Cabé --- boards/riscv/tlsr9518adk80d/doc/index.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/riscv/tlsr9518adk80d/doc/index.rst b/boards/riscv/tlsr9518adk80d/doc/index.rst index 8f478709934..aad7ef3ae91 100644 --- a/boards/riscv/tlsr9518adk80d/doc/index.rst +++ b/boards/riscv/tlsr9518adk80d/doc/index.rst @@ -259,10 +259,10 @@ References .. target-notes:: -.. _Telink TLSR951x series chipset: http://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series/ -.. _Telink B91 Generic Starter Kit Hardware Guide: http://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/ -.. _Telink RISC-V Linux Toolchain: http://wiki.telink-semi.cn/tools_and_sdk/Tools/IDE/telink_riscv_linux_toolchain.zip -.. _Burning and Debugging Tools for all Series: http://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-all-Series/ -.. _Burning and Debugging Tools for TLSR9 Series: http://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-TLSR9-Series/ -.. _Burning and Debugging Tools for TLSR9 Series in Linux: http://wiki.telink-semi.cn/wiki/IDE-and-Tools/BDT_for_TLSR9_Series_in_Linux/ +.. _Telink TLSR951x series chipset: https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series/ +.. _Telink B91 Generic Starter Kit Hardware Guide: https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/ +.. _Telink RISC-V Linux Toolchain: https://wiki.telink-semi.cn/tools_and_sdk/Tools/IDE/telink_riscv_linux_toolchain.zip +.. _Burning and Debugging Tools for all Series: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-all-Series/ +.. _Burning and Debugging Tools for TLSR9 Series: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-TLSR9-Series/ +.. _Burning and Debugging Tools for TLSR9 Series in Linux: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/BDT_for_TLSR9_Series_in_Linux/ .. _Zephyr Getting Started Guide: https://docs.zephyrproject.org/latest/getting_started/index.html From f5efa59fc38fe32462a6fefdc35c34b78826e0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 10:51:39 +0200 Subject: [PATCH 1185/4498] boards: riscv: doc: Fix link to getting started guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not use hardcoded http link to the getting started guide but a proper ref instead. Signed-off-by: Benjamin Cabé --- boards/riscv/tlsr9518adk80d/doc/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boards/riscv/tlsr9518adk80d/doc/index.rst b/boards/riscv/tlsr9518adk80d/doc/index.rst index aad7ef3ae91..4bf62efdf78 100644 --- a/boards/riscv/tlsr9518adk80d/doc/index.rst +++ b/boards/riscv/tlsr9518adk80d/doc/index.rst @@ -151,7 +151,7 @@ Building .. important:: These instructions assume you've set up a development environment as - described in the `Zephyr Getting Started Guide`_. + described in the :ref:`getting_started`. To build applications using the default RISC-V toolchain from Zephyr SDK, just run the west build command. Here is an example for the "hello_world" application. @@ -265,4 +265,3 @@ References .. _Burning and Debugging Tools for all Series: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-all-Series/ .. _Burning and Debugging Tools for TLSR9 Series: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-TLSR9-Series/ .. _Burning and Debugging Tools for TLSR9 Series in Linux: https://wiki.telink-semi.cn/wiki/IDE-and-Tools/BDT_for_TLSR9_Series_in_Linux/ -.. _Zephyr Getting Started Guide: https://docs.zephyrproject.org/latest/getting_started/index.html From ad08d71efaac6ddcb149e5f99c10356d6c44eb8e Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Sun, 18 Jun 2023 23:25:31 +0700 Subject: [PATCH 1186/4498] drivers: dma_mcux_edma: correct valid values for dma channel/slot The dma-channels devicetree value - 1 = maximum valid channel The dma-requests devicetree value - 1 = maximum valid request Signed-off-by: Dat Nguyen Duy --- drivers/dma/dma_mcux_edma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index 9130542ee84..e34bdc6623e 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -192,12 +192,12 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, unsigned int key; int ret = 0; - if (slot > DT_INST_PROP(0, dma_requests)) { - LOG_ERR("source number is outof scope %d", slot); + if (slot >= DT_INST_PROP(0, dma_requests)) { + LOG_ERR("source number is out of scope %d", slot); return -ENOTSUP; } - if (channel > DT_INST_PROP(0, dma_channels)) { + if (channel >= DT_INST_PROP(0, dma_channels)) { LOG_ERR("out of DMA channel %d", channel); return -EINVAL; } From f27815d645b5ea9c2fc1249f3bf6011922bc44e4 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 25 Aug 2023 17:53:16 +0700 Subject: [PATCH 1187/4498] dts: bindings: correct information in mcux edma bindings With the current implementation, the 1st cell is not DMAMUX id as mentioned in the bindings (0 for DMAMUX0 and 1 for DMAMUX1). Moreover, the referenced Linux bindings is obsoleted, it was migrated to use yaml syntax Signed-off-by: Dat Nguyen Duy --- dts/bindings/dma/nxp,mcux-edma.yaml | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/dts/bindings/dma/nxp,mcux-edma.yaml b/dts/bindings/dma/nxp,mcux-edma.yaml index 2ce3b9c6eca..7c82982132e 100644 --- a/dts/bindings/dma/nxp,mcux-edma.yaml +++ b/dts/bindings/dma/nxp,mcux-edma.yaml @@ -10,6 +10,9 @@ include: dma-controller.yaml properties: reg: required: true + description: | + Specifies base physical address(s) and size of DMA and respective DMAMUX register(s) + that routes DMA sources interrupts: required: true @@ -33,21 +36,10 @@ properties: required: true description: Number of items to expect in a DMAMUX specifier -# Parameter syntax of NXP follows the dmamux client dts syntax -# in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/tree/Bindings/dma/fsl-edma.txt -# # - #dma-cells : Must be <2>. -# The 1st cell specifies the DMAMUX(0 for DMAMUX0 and 1 for DMAMUX1). -# Specific request source can only be multiplexed by specific channels -# group called DMAMUX. -# The 2nd cell specifies the request source(slot) ID. +# The 1st cell specifies the DMA channel which will be used +# The 2nd cell specifies the request source (slot) ID. # See the SoC's reference manual for all the supported request sources. -# * DMA clients -# DMA client drivers that uses the DMA function must use the format described -# in the dma.txt file, using a two-cell specifier for each channel: the 1st -# specifies the channel group(DMAMUX) in which this request can be multiplexed, -# and the 2nd specifies the request source. dma-cells: - mux From 03b5ba59904704479c70a3013c30f31ae7493264 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Tue, 13 Jun 2023 17:21:37 +0700 Subject: [PATCH 1188/4498] drivers: dma_mcux_edma: add support for multiple DMAMuxes This adds support for platforms that have multiple DMAMUXes per DMA instance Signed-off-by: Dat Nguyen Duy --- drivers/dma/dma_mcux_edma.c | 79 ++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index e34bdc6623e..e2f7da80729 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -30,7 +30,8 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL); struct dma_mcux_edma_config { DMA_Type *base; - DMAMUX_Type *dmamux_base; + DMAMUX_Type **dmamux_base; + uint8_t channels_per_mux; int dma_channels; /* number of channels */ void (*irq_config_func)(const struct device *dev); }; @@ -102,14 +103,16 @@ struct dma_mcux_edma_data { #define DEV_DATA(dev) ((struct dma_mcux_edma_data *)dev->data) #define DEV_BASE(dev) ((DMA_Type *)DEV_CFG(dev)->base) -#define DEV_DMAMUX_BASE(dev) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base) - #define DEV_CHANNEL_DATA(dev, ch) \ ((struct call_back *)(&(DEV_DATA(dev)->data_cb[ch]))) #define DEV_EDMA_HANDLE(dev, ch) \ ((edma_handle_t *)(&(DEV_CHANNEL_DATA(dev, ch)->edma_handle))) +#define DEV_DMAMUX_BASE(dev, idx) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base[idx]) +#define DEV_DMAMUX_IDX(dev, ch) (ch / DEV_CFG(dev)->channels_per_mux) +#define DEV_DMAMUX_CHANNEL(dev, ch) (ch % DEV_CFG(dev)->channels_per_mux) + static bool data_size_valid(const size_t data_size) { return (data_size == 4U || data_size == 2U || @@ -188,6 +191,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, struct call_back *data = DEV_CHANNEL_DATA(dev, channel); struct dma_block_config *block_config = config->head_block; uint32_t slot = config->dma_slot; + uint8_t dmamux_idx, dmamux_channel; edma_transfer_type_t transfer_type; unsigned int key; int ret = 0; @@ -202,6 +206,8 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, return -EINVAL; } + dmamux_idx = DEV_DMAMUX_IDX(dev, channel); + dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); data->transfer_settings.valid = false; switch (config->channel_direction) { @@ -256,16 +262,16 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, transfer_type == kEDMA_MemoryToMemory) { /*software trigger make the channel always on*/ LOG_DBG("ALWAYS ON"); - DMAMUX_EnableAlwaysOn(DEV_DMAMUX_BASE(dev), channel, true); + DMAMUX_EnableAlwaysOn(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, true); } else { - DMAMUX_SetSource(DEV_DMAMUX_BASE(dev), channel, slot); + DMAMUX_SetSource(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, slot); } #else - DMAMUX_SetSource(DEV_DMAMUX_BASE(dev), channel, slot); + DMAMUX_SetSource(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, slot); #endif /* dam_imx_rt_set_channel_priority(dev, channel, config); */ - DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev), channel); + DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel); if (data->busy) { EDMA_AbortTransfer(p_handle); @@ -345,9 +351,11 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, static int dma_mcux_edma_start(const struct device *dev, uint32_t channel) { struct call_back *data = DEV_CHANNEL_DATA(dev, channel); + uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel); + uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); LOG_DBG("START TRANSFER"); - LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev)->CHCFG[channel]); + LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]); LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); data->busy = true; EDMA_StartTransfer(DEV_EDMA_HANDLE(dev, channel)); @@ -444,6 +452,8 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, struct dma_status *status) { edma_tcd_t *tcdRegs; + uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel); + uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); if (DEV_CHANNEL_DATA(dev, channel)->busy) { status->busy = true; @@ -454,7 +464,7 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, status->pending_length = 0; } status->dir = DEV_CHANNEL_DATA(dev, channel)->transfer_settings.direction; - LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev)->CHCFG[channel]); + LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]); LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT); LOG_DBG("DMA ERQ 0x%x", DEV_BASE(dev)->ERQ); @@ -496,9 +506,14 @@ static int dma_mcux_edma_init(const struct device *dev) struct dma_mcux_edma_data *data = dev->data; edma_config_t userConfig = { 0 }; + uint8_t i; LOG_DBG("INIT NXP EDMA"); - DMAMUX_Init(DEV_DMAMUX_BASE(dev)); + + for (i = 0; i < config->dma_channels / config->channels_per_mux; i++) { + DMAMUX_Init(DEV_DMAMUX_BASE(dev, i)); + } + EDMA_GetDefaultConfig(&userConfig); EDMA_Init(DEV_BASE(dev), &userConfig); config->irq_config_func(dev); @@ -546,27 +561,35 @@ static int dma_mcux_edma_init(const struct device *dev) LOG_DBG("install irq done"); \ } +#define DMA_MCUX_EDMA_MUX(idx, n) \ + (DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, UTIL_INC(idx)) + /* * define the dma */ -#define DMA_INIT(n) \ - static void dma_imx_config_func_##n(const struct device *dev); \ - static const struct dma_mcux_edma_config dma_config_##n = { \ - .base = (DMA_Type *)DT_INST_REG_ADDR(n), \ - .dmamux_base = \ - (DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, 1), \ - .dma_channels = DT_INST_PROP(n, dma_channels), \ - .irq_config_func = dma_imx_config_func_##n, \ - }; \ - \ - struct dma_mcux_edma_data dma_data_##n; \ - \ - DEVICE_DT_INST_DEFINE(n, \ - &dma_mcux_edma_init, NULL, \ - &dma_data_##n, &dma_config_##n, \ - PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \ - &dma_mcux_edma_api); \ - \ +#define DMA_INIT(n) \ + static void dma_imx_config_func_##n(const struct device *dev); \ + static DMAMUX_Type *dmamux_base_##n[] = { \ + LISTIFY(UTIL_DEC(DT_NUM_REGS(DT_DRV_INST(n))), \ + DMA_MCUX_EDMA_MUX, (,), n) \ + }; \ + static const struct dma_mcux_edma_config dma_config_##n = { \ + .base = (DMA_Type *)DT_INST_REG_ADDR(n), \ + .dmamux_base = &dmamux_base_##n[0], \ + .dma_channels = DT_INST_PROP(n, dma_channels), \ + .channels_per_mux = DT_INST_PROP(n, dma_channels) / \ + ARRAY_SIZE(dmamux_base_##n), \ + .irq_config_func = dma_imx_config_func_##n, \ + }; \ + \ + struct dma_mcux_edma_data dma_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &dma_mcux_edma_init, NULL, \ + &dma_data_##n, &dma_config_##n, \ + PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \ + &dma_mcux_edma_api); \ + \ DMA_MCUX_EDMA_CONFIG_FUNC(n); DT_INST_FOREACH_STATUS_OKAY(DMA_INIT) From a5cf757c9ecbaa562a4f31b58bf133a4b978da8a Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 14 Jun 2023 09:38:41 +0700 Subject: [PATCH 1189/4498] drivers: dma_mcux_edma: improve interrupt handling The current implementation iterates over all channels even if only several channels share the same irq. This introduces one more dt property to describe an offset between two channels share the same interrupt id. Beside that, the error interrupt must be put as last element of "interrupt" dt property. Signed-off-by: Dat Nguyen Duy --- drivers/dma/dma_mcux_edma.c | 105 ++++++++++++++-------------- dts/arm/nxp/nxp_rt10xx.dtsi | 1 + dts/arm/nxp/nxp_rt11xx.dtsi | 2 + dts/bindings/dma/nxp,mcux-edma.yaml | 7 ++ 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index e2f7da80729..10fc71bb6b7 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -137,23 +137,15 @@ static void nxp_edma_callback(edma_handle_t *handle, void *param, bool transferD data->dma_callback(data->dev, data->user_data, channel, ret); } - -static void dma_mcux_edma_irq_handler(const struct device *dev) +static void dma_mcux_edma_irq_handler(const struct device *dev, uint32_t channel) { - int i = 0; - - LOG_DBG("IRQ CALLED"); - for (i = 0; i < DT_INST_PROP(0, dma_channels); i++) { - uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), i); + uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), channel); - if ((flag & (uint32_t)kEDMA_InterruptFlag) != 0U) { - LOG_DBG("IRQ OCCURRED"); - EDMA_HandleIRQ(DEV_EDMA_HANDLE(dev, i)); - LOG_DBG("IRQ DONE"); -#if defined __CORTEX_M && (__CORTEX_M == 4U) - barrier_dsync_fence_full(); -#endif - } + if (flag & kEDMA_InterruptFlag) { + LOG_DBG("IRQ OCCURRED"); + /* EDMA interrupt flag is cleared here */ + EDMA_HandleIRQ(DEV_EDMA_HANDLE(dev, channel)); + LOG_DBG("IRQ DONE"); } } @@ -162,18 +154,17 @@ static void dma_mcux_edma_error_irq_handler(const struct device *dev) int i = 0; uint32_t flag = 0; - for (i = 0; i < DT_INST_PROP(0, dma_channels); i++) { + for (i = 0; i < DEV_CFG(dev)->dma_channels; i++) { if (DEV_CHANNEL_DATA(dev, i)->busy) { flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), i); - LOG_INF("channel %d error status is 0x%x", i, flag); - EDMA_ClearChannelStatusFlags(DEV_BASE(dev), i, - 0xFFFFFFFF); + EDMA_ClearChannelStatusFlags(DEV_BASE(dev), i, 0xFFFFFFFF); EDMA_AbortTransfer(DEV_EDMA_HANDLE(dev, i)); DEV_CHANNEL_DATA(dev, i)->busy = false; + LOG_INF("channel %d error status is 0x%x", i, flag); } } -#if defined __CORTEX_M && (__CORTEX_M == 4U) +#if defined(CONFIG_CPU_CORTEX_M4) barrier_dsync_fence_full(); #endif } @@ -525,40 +516,46 @@ static int dma_mcux_edma_init(const struct device *dev) return 0; } -#define IRQ_CONFIG(n, idx, fn) \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, idx), ( \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ - DT_INST_IRQ_BY_IDX(n, idx, priority), \ - fn, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ - )) - -#define DMA_MCUX_EDMA_CONFIG_FUNC(n) \ - static void dma_imx_config_func_##n(const struct device *dev) \ - { \ - ARG_UNUSED(dev); \ - \ - IRQ_CONFIG(n, 0, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 1, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 2, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 3, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 4, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 5, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 6, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 7, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 8, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 9, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 10, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 11, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 12, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 13, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 14, dma_mcux_edma_irq_handler); \ - IRQ_CONFIG(n, 15, dma_mcux_edma_irq_handler); \ - \ - IRQ_CONFIG(n, 16, dma_mcux_edma_error_irq_handler); \ - \ - LOG_DBG("install irq done"); \ +/* The shared error interrupt (if have) must be declared as the last element in devicetree */ +#define NUM_IRQS_WITHOUT_ERROR_IRQ(n) UTIL_DEC(DT_NUM_IRQS(DT_DRV_INST(n))) + +#define IRQ_CONFIG(n, idx, fn) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + DT_INST_IRQ_BY_IDX(n, idx, priority), \ + fn, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ + } + +#define DMA_MCUX_EDMA_IRQ_DEFINE(idx, n) \ + static void dma_mcux_edma_##n##_irq_##idx(const struct device *dev) \ + { \ + dma_mcux_edma_irq_handler(dev, idx); \ + \ + IF_ENABLED(UTIL_BOOL(DT_INST_PROP(n, irq_shared_offset)), \ + (dma_mcux_edma_irq_handler(dev, \ + idx + DT_INST_PROP(n, irq_shared_offset));)) \ + \ + IF_ENABLED(CONFIG_CPU_CORTEX_M4, (barrier_dsync_fence_full();)) \ + } + +#define DMA_MCUX_EDMA_IRQ_CONFIG(idx, n) \ + IRQ_CONFIG(n, idx, dma_mcux_edma_##n##_irq_##idx) + +#define DMA_MCUX_EDMA_CONFIG_FUNC(n) \ + LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), DMA_MCUX_EDMA_IRQ_DEFINE, (), n) \ + static void dma_imx_config_func_##n(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + \ + LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), \ + DMA_MCUX_EDMA_IRQ_CONFIG, (;), n) \ + \ + IRQ_CONFIG(n, NUM_IRQS_WITHOUT_ERROR_IRQ(n), \ + dma_mcux_edma_error_irq_handler); \ + \ + LOG_DBG("install irq done"); \ } #define DMA_MCUX_EDMA_MUX(idx, n) \ diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index 6e4f6278fae..1f1ff416099 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -856,6 +856,7 @@ <8 0>, <9 0>, <10 0>, <11 0>, <12 0>, <13 0>, <14 0>, <15 0>, <16 0>; + irq-shared-offset = <16>; clocks = <&ccm IMX_CCM_EDMA_CLK 0x7C 0x000000C0>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index b333816a2c8..0deede76c37 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -953,6 +953,7 @@ <8 0>, <9 0>, <10 0>, <11 0>, <12 0>, <13 0>, <14 0>, <15 0>, <16 0>; + irq-shared-offset = <16>; }; edma_lpsr0: dma-controller@40c14000 { @@ -971,6 +972,7 @@ <8 0>, <9 0>, <10 0>, <11 0>, <12 0>, <13 0>, <14 0>, <15 0>, <16 0>; + irq-shared-offset = <16>; }; pxp: pxp@40814000 { diff --git a/dts/bindings/dma/nxp,mcux-edma.yaml b/dts/bindings/dma/nxp,mcux-edma.yaml index 7c82982132e..0a0b0a66e2d 100644 --- a/dts/bindings/dma/nxp,mcux-edma.yaml +++ b/dts/bindings/dma/nxp,mcux-edma.yaml @@ -31,6 +31,13 @@ properties: type: boolean description: If the DMA controller supports always on + irq-shared-offset: + type: int + default: 0 + description: | + Describes an offset between two channels share the same interrupt entry. + Default value means each channel has separate interrupt entry. + "#dma-cells": type: int required: true From d4a2b2244f084e36d02cad534971f59425df622c Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 14 Jun 2023 08:58:39 +0700 Subject: [PATCH 1190/4498] drivers: dma_mcux_edma: add support for edma version 3 Add new dt binding for edma v3 that inherits whole dt properties from current version. One more property is added for SoCs that don't have separate error interrupt id, use same id with channel interrupt Signed-off-by: Dat Nguyen Duy --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig.mcux_edma | 11 ++++- drivers/dma/dma_mcux_edma.c | 61 ++++++++++++++++++++++---- dts/bindings/dma/nxp,mcux-edma-v3.yaml | 14 ++++++ 4 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 dts/bindings/dma/nxp,mcux-edma-v3.yaml diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index bd96efbf0a5..5a11cd7f324 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_DMA_NIOS2_MSGDMA dma_nios2_msgdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_SAM0 dma_sam0.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE dma_handlers.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA dma_mcux_edma.c) +zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V3 dma_mcux_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_DMA_PL330 dma_pl330.c) zephyr_library_sources_ifdef(CONFIG_DMA_IPROC_PAX dma_iproc_pax_v1.c) diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index d4d44cb4cf7..4edd9d4a592 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -11,7 +11,14 @@ config DMA_MCUX_EDMA help DMA driver for MCUX series SoCs. -if DMA_MCUX_EDMA +config DMA_MCUX_EDMA_V3 + bool "MCUX DMA v3 driver" + default y + depends on DT_HAS_NXP_MCUX_EDMA_V3_ENABLED + help + DMA version 3 driver for MCUX series SoCs. + +if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 config DMA_TCD_QUEUE_SIZE int "number of TCD in a queue for SG mode" @@ -33,4 +40,4 @@ config DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS When this option is activated, the descriptors for DMA transfer are located in the DTCM (Data Tightly Coupled Memory). -endif # DMA_MCUX_EDMA +endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index 10fc71bb6b7..ec940cc8f81 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -24,7 +24,11 @@ #include #include +#ifdef CONFIG_DMA_MCUX_EDMA #define DT_DRV_COMPAT nxp_mcux_edma +#elif CONFIG_DMA_MCUX_EDMA_V3 +#define DT_DRV_COMPAT nxp_mcux_edma_v3 +#endif LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL); @@ -117,8 +121,11 @@ static bool data_size_valid(const size_t data_size) { return (data_size == 4U || data_size == 2U || data_size == 1U || data_size == 8U || - data_size == 16U || - data_size == 32U); + data_size == 16U || data_size == 32U +#ifdef CONFIG_DMA_MCUX_EDMA_V3 + || data_size == 64U +#endif + ); } static void nxp_edma_callback(edma_handle_t *handle, void *param, bool transferDone, @@ -147,8 +154,19 @@ static void dma_mcux_edma_irq_handler(const struct device *dev, uint32_t channel EDMA_HandleIRQ(DEV_EDMA_HANDLE(dev, channel)); LOG_DBG("IRQ DONE"); } + +#if DT_INST_PROP(0, no_error_irq) + /* Channel shares the same irq for error and transfer complete */ + else if (flag & kEDMA_ErrorFlag) { + EDMA_ClearChannelStatusFlags(DEV_BASE(dev), channel, 0xFFFFFFFF); + EDMA_AbortTransfer(DEV_EDMA_HANDLE(dev, channel)); + DEV_CHANNEL_DATA(dev, channel)->busy = false; + LOG_INF("channel %d error status is 0x%x", channel, flag); + } +#endif } +#if !DT_INST_PROP(0, no_error_irq) static void dma_mcux_edma_error_irq_handler(const struct device *dev) { int i = 0; @@ -168,6 +186,7 @@ static void dma_mcux_edma_error_irq_handler(const struct device *dev) barrier_dsync_fence_full(); #endif } +#endif /* Configure a channel */ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, @@ -311,8 +330,11 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, LOG_ERR("Error submitting EDMA Transfer: 0x%x", submit_status); ret = -EFAULT; } - edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&p_handle->base->TCD[channel]; - LOG_DBG("data csr is 0x%x", tcdRegs->CSR); +#ifdef CONFIG_DMA_MCUX_EDMA_V3 + LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[channel].TCD_CSR); +#else + LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[channel].CSR); +#endif } if (config->dest_chaining_en) { @@ -347,7 +369,10 @@ static int dma_mcux_edma_start(const struct device *dev, uint32_t channel) LOG_DBG("START TRANSFER"); LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]); + +#ifndef CONFIG_DMA_MCUX_EDMA_V3 LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); +#endif data->busy = true; EDMA_StartTransfer(DEV_EDMA_HANDLE(dev, channel)); return 0; @@ -442,7 +467,6 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel, static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, struct dma_status *status) { - edma_tcd_t *tcdRegs; uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel); uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); @@ -456,14 +480,24 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, } status->dir = DEV_CHANNEL_DATA(dev, channel)->transfer_settings.direction; LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]); + +#ifdef CONFIG_DMA_MCUX_EDMA_V3 + LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR); + LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES); + LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[channel].CH_ES); + LOG_DBG("DMA CHx_CSR 0x%x", DEV_BASE(dev)->CH[channel].CH_CSR); + LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[channel].CH_ES); + LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->CH[channel].CH_INT); + LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[channel].TCD_CSR); +#else LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT); LOG_DBG("DMA ERQ 0x%x", DEV_BASE(dev)->ERQ); LOG_DBG("DMA ES 0x%x", DEV_BASE(dev)->ES); LOG_DBG("DMA ERR 0x%x", DEV_BASE(dev)->ERR); LOG_DBG("DMA HRS 0x%x", DEV_BASE(dev)->HRS); - tcdRegs = (edma_tcd_t *)((uint32_t)&DEV_BASE(dev)->TCD[channel]); - LOG_DBG("data csr is 0x%x", tcdRegs->CSR); + LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[channel].CSR); +#endif return 0; } @@ -507,6 +541,10 @@ static int dma_mcux_edma_init(const struct device *dev) EDMA_GetDefaultConfig(&userConfig); EDMA_Init(DEV_BASE(dev), &userConfig); +#ifdef CONFIG_DMA_MCUX_EDMA_V3 + /* Channel linking available and will be controlled by each channel's link settings */ + EDMA_EnableAllChannelLink(DEV_BASE(dev), true); +#endif config->irq_config_func(dev); memset(dev->data, 0, sizeof(struct dma_mcux_edma_data)); memset(tcdpool, 0, sizeof(tcdpool)); @@ -517,7 +555,11 @@ static int dma_mcux_edma_init(const struct device *dev) } /* The shared error interrupt (if have) must be declared as the last element in devicetree */ +#if !DT_INST_PROP(0, no_error_irq) #define NUM_IRQS_WITHOUT_ERROR_IRQ(n) UTIL_DEC(DT_NUM_IRQS(DT_DRV_INST(n))) +#else +#define NUM_IRQS_WITHOUT_ERROR_IRQ(n) DT_NUM_IRQS(DT_DRV_INST(n)) +#endif #define IRQ_CONFIG(n, idx, fn) \ { \ @@ -552,8 +594,9 @@ static int dma_mcux_edma_init(const struct device *dev) LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), \ DMA_MCUX_EDMA_IRQ_CONFIG, (;), n) \ \ - IRQ_CONFIG(n, NUM_IRQS_WITHOUT_ERROR_IRQ(n), \ - dma_mcux_edma_error_irq_handler); \ + IF_ENABLED(UTIL_NOT(DT_INST_NODE_HAS_PROP(n, no_error_irq)), \ + (IRQ_CONFIG(n, NUM_IRQS_WITHOUT_ERROR_IRQ(n), \ + dma_mcux_edma_error_irq_handler))) \ \ LOG_DBG("install irq done"); \ } diff --git a/dts/bindings/dma/nxp,mcux-edma-v3.yaml b/dts/bindings/dma/nxp,mcux-edma-v3.yaml new file mode 100644 index 00000000000..2711c3be124 --- /dev/null +++ b/dts/bindings/dma/nxp,mcux-edma-v3.yaml @@ -0,0 +1,14 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCUX EDMA version 3 controller + +compatible: "nxp,mcux-edma-v3" + +include: nxp,mcux-edma.yaml + +properties: + no-error-irq: + type: boolean + description: | + If the SoCs don't have a separate interrupt id for error IRQ. From 8185faa0cb7c3a04081d8317dab2293568080714 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 14 Jun 2023 10:23:06 +0700 Subject: [PATCH 1191/4498] drivers: dma_mcux_edma: add support dma driver for s32k344 On S32K344, the offset in memory map between each channel is 0x4000 for most channels, but there is specific case is between channel 11 and 12 which is 0x1D4000 instead. As a consequence, 32 channels are divided to two parts: one starts from channel 0 -> 11. The other is from channel 128 to 145. The channel gap is from 12 -> 127. For user and data structures in shim driver, the channel's value comes from 0 --> 31. Above constraint will be counted when interact with the mcux sdk Beside that, the DMAMUX register in this platform is very specific, not in identical with DMAMUX channel, so shim driver is updated to cover this case Signed-off-by: Dat Nguyen Duy --- drivers/dma/Kconfig.mcux_edma | 3 +- drivers/dma/dma_mcux_edma.c | 107 ++++++++++++++++++++++------ dts/arm/nxp/nxp_s32k344_m7.dtsi | 20 ++++++ dts/bindings/dma/nxp,mcux-edma.yaml | 13 ++++ soc/arm/nxp_s32/s32k/Kconfig.series | 1 + 5 files changed, 121 insertions(+), 23 deletions(-) diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index 4edd9d4a592..0362a5faad6 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -28,9 +28,10 @@ config DMA_TCD_QUEUE_SIZE config DMA_MCUX_TEST_SLOT_START int "test slot start num" - depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF) + depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_S32K3_M7) default 58 if SOC_SERIES_KINETIS_K6X default 60 if SOC_SERIES_KINETIS_KE1XF + default 62 if SOC_SERIES_S32K3_M7 help test slot start num diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index ec940cc8f81..bc40f1c3a9e 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -32,11 +32,18 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL); +#define HAS_CHANNEL_GAP(n) DT_INST_NODE_HAS_PROP(n, channel_gap) || +#define DMA_MCUX_HAS_CHANNEL_GAP (DT_INST_FOREACH_STATUS_OKAY(HAS_CHANNEL_GAP) 0) + struct dma_mcux_edma_config { DMA_Type *base; DMAMUX_Type **dmamux_base; uint8_t channels_per_mux; + uint8_t dmamux_reg_offset; int dma_channels; /* number of channels */ +#if DMA_MCUX_HAS_CHANNEL_GAP + uint32_t channel_gap[2]; +#endif void (*irq_config_func)(const struct device *dev); }; @@ -114,8 +121,42 @@ struct dma_mcux_edma_data { ((edma_handle_t *)(&(DEV_CHANNEL_DATA(dev, ch)->edma_handle))) #define DEV_DMAMUX_BASE(dev, idx) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base[idx]) -#define DEV_DMAMUX_IDX(dev, ch) (ch / DEV_CFG(dev)->channels_per_mux) -#define DEV_DMAMUX_CHANNEL(dev, ch) (ch % DEV_CFG(dev)->channels_per_mux) +#define DEV_DMAMUX_IDX(dev, ch) (ch / DEV_CFG(dev)->channels_per_mux) + +#define DEV_DMAMUX_CHANNEL(dev, ch) \ + (ch % DEV_CFG(dev)->channels_per_mux) ^ (DEV_CFG(dev)->dmamux_reg_offset) + +/* + * The hardware channel (takes the gap into account) is used when access DMA registers. + * For data structures in the shim driver still use the primitive channel. + */ +static ALWAYS_INLINE uint32_t dma_mcux_edma_add_channel_gap(const struct device *dev, + uint32_t channel) +{ +#if DMA_MCUX_HAS_CHANNEL_GAP + const struct dma_mcux_edma_config *config = DEV_CFG(dev); + + return (channel < config->channel_gap[0]) ? channel : + (channel + 1 + config->channel_gap[1] - config->channel_gap[0]); +#else + ARG_UNUSED(dev); + return channel; +#endif +} + +static ALWAYS_INLINE uint32_t dma_mcux_edma_remove_channel_gap(const struct device *dev, + uint32_t channel) +{ +#if DMA_MCUX_HAS_CHANNEL_GAP + const struct dma_mcux_edma_config *config = DEV_CFG(dev); + + return (channel < config->channel_gap[0]) ? channel : + (channel + config->channel_gap[0] - config->channel_gap[1] - 1); +#else + ARG_UNUSED(dev); + return channel; +#endif +} static bool data_size_valid(const size_t data_size) { @@ -133,7 +174,8 @@ static void nxp_edma_callback(edma_handle_t *handle, void *param, bool transferD { int ret = -EIO; struct call_back *data = (struct call_back *)param; - uint32_t channel = handle->channel; + + uint32_t channel = dma_mcux_edma_remove_channel_gap(data->dev, handle->channel); if (transferDone) { /* DMA is no longer busy when there are no remaining TCDs to transfer */ @@ -146,7 +188,8 @@ static void nxp_edma_callback(edma_handle_t *handle, void *param, bool transferD static void dma_mcux_edma_irq_handler(const struct device *dev, uint32_t channel) { - uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), channel); + uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); + uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), hw_channel); if (flag & kEDMA_InterruptFlag) { LOG_DBG("IRQ OCCURRED"); @@ -171,14 +214,16 @@ static void dma_mcux_edma_error_irq_handler(const struct device *dev) { int i = 0; uint32_t flag = 0; + uint32_t hw_channel; for (i = 0; i < DEV_CFG(dev)->dma_channels; i++) { if (DEV_CHANNEL_DATA(dev, i)->busy) { - flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), i); - EDMA_ClearChannelStatusFlags(DEV_BASE(dev), i, 0xFFFFFFFF); + hw_channel = dma_mcux_edma_add_channel_gap(dev, i); + flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), hw_channel); + EDMA_ClearChannelStatusFlags(DEV_BASE(dev), hw_channel, 0xFFFFFFFF); EDMA_AbortTransfer(DEV_EDMA_HANDLE(dev, i)); DEV_CHANNEL_DATA(dev, i)->busy = false; - LOG_INF("channel %d error status is 0x%x", i, flag); + LOG_INF("channel %d error status is 0x%x", hw_channel, flag); } } @@ -202,6 +247,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, struct dma_block_config *block_config = config->head_block; uint32_t slot = config->dma_slot; uint8_t dmamux_idx, dmamux_channel; + uint32_t hw_channel; edma_transfer_type_t transfer_type; unsigned int key; int ret = 0; @@ -216,6 +262,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, return -EINVAL; } + hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); dmamux_idx = DEV_DMAMUX_IDX(dev, channel); dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); data->transfer_settings.valid = false; @@ -286,12 +333,12 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, if (data->busy) { EDMA_AbortTransfer(p_handle); } - EDMA_ResetChannel(DEV_BASE(dev), channel); - EDMA_CreateHandle(p_handle, DEV_BASE(dev), channel); + EDMA_ResetChannel(DEV_BASE(dev), hw_channel); + EDMA_CreateHandle(p_handle, DEV_BASE(dev), hw_channel); EDMA_SetCallback(p_handle, nxp_edma_callback, (void *)data); - LOG_DBG("channel is %d", p_handle->channel); - EDMA_EnableChannelInterrupts(DEV_BASE(dev), channel, kEDMA_ErrorInterruptEnable); + LOG_DBG("channel is %d", channel); + EDMA_EnableChannelInterrupts(DEV_BASE(dev), hw_channel, kEDMA_ErrorInterruptEnable); if (block_config->source_gather_en || block_config->dest_scatter_en) { EDMA_InstallTCDMemory(p_handle, tcdpool[channel], CONFIG_DMA_TCD_QUEUE_SIZE); @@ -331,9 +378,9 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, ret = -EFAULT; } #ifdef CONFIG_DMA_MCUX_EDMA_V3 - LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[channel].TCD_CSR); + LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].TCD_CSR); #else - LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[channel].CSR); + LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[hw_channel].CSR); #endif } @@ -381,17 +428,21 @@ static int dma_mcux_edma_start(const struct device *dev, uint32_t channel) static int dma_mcux_edma_stop(const struct device *dev, uint32_t channel) { struct dma_mcux_edma_data *data = DEV_DATA(dev); + uint32_t hw_channel; + + hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); data->data_cb[channel].transfer_settings.valid = false; if (!data->data_cb[channel].busy) { return 0; } + EDMA_AbortTransfer(DEV_EDMA_HANDLE(dev, channel)); - EDMA_ClearChannelStatusFlags(DEV_BASE(dev), channel, + EDMA_ClearChannelStatusFlags(DEV_BASE(dev), hw_channel, kEDMA_DoneFlag | kEDMA_ErrorFlag | kEDMA_InterruptFlag); - EDMA_ResetChannel(DEV_BASE(dev), channel); + EDMA_ResetChannel(DEV_BASE(dev), hw_channel); data->data_cb[channel].busy = false; return 0; } @@ -470,10 +521,12 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel); uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel); + uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); + if (DEV_CHANNEL_DATA(dev, channel)->busy) { status->busy = true; status->pending_length = - EDMA_GetRemainingMajorLoopCount(DEV_BASE(dev), channel); + EDMA_GetRemainingMajorLoopCount(DEV_BASE(dev), hw_channel); } else { status->busy = false; status->pending_length = 0; @@ -484,11 +537,11 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, #ifdef CONFIG_DMA_MCUX_EDMA_V3 LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR); LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES); - LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[channel].CH_ES); - LOG_DBG("DMA CHx_CSR 0x%x", DEV_BASE(dev)->CH[channel].CH_CSR); - LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[channel].CH_ES); - LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->CH[channel].CH_INT); - LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[channel].TCD_CSR); + LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES); + LOG_DBG("DMA CHx_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_CSR); + LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES); + LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_INT); + LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].TCD_CSR); #else LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT); @@ -496,7 +549,7 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, LOG_DBG("DMA ES 0x%x", DEV_BASE(dev)->ES); LOG_DBG("DMA ERR 0x%x", DEV_BASE(dev)->ERR); LOG_DBG("DMA HRS 0x%x", DEV_BASE(dev)->HRS); - LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[channel].CSR); + LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[hw_channel].CSR); #endif return 0; } @@ -604,6 +657,14 @@ static int dma_mcux_edma_init(const struct device *dev) #define DMA_MCUX_EDMA_MUX(idx, n) \ (DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, UTIL_INC(idx)) +#if DMA_MCUX_HAS_CHANNEL_GAP +#define DMA_MCUX_EDMA_CHANNEL_GAP(n) \ + .channel_gap = DT_INST_PROP_OR(n, channel_gap, \ + {[0 ... 1] = DT_INST_PROP(n, dma_channels)}), +#else +#define DMA_MCUX_EDMA_CHANNEL_GAP(n) +#endif + /* * define the dma */ @@ -620,6 +681,8 @@ static int dma_mcux_edma_init(const struct device *dev) .channels_per_mux = DT_INST_PROP(n, dma_channels) / \ ARRAY_SIZE(dmamux_base_##n), \ .irq_config_func = dma_imx_config_func_##n, \ + .dmamux_reg_offset = DT_INST_PROP(n, dmamux_reg_offset), \ + DMA_MCUX_EDMA_CHANNEL_GAP(n) \ }; \ \ struct dma_mcux_edma_data dma_data_##n; \ diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index b5f7549bea8..dbec883c7c2 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -595,6 +595,26 @@ compatible = "nxp,s32-gmac"; interrupts = <105 0>, <106 0>, <107 0>, <108 0>; interrupt-names = "common", "tx", "rx", "safety"; + }; + + edma0: dma-controller@4020c000 { + compatible = "nxp,mcux-edma-v3"; + reg = <0x4020c000 0x3000>, <0x40280000 0x4000>, <0x40284000 0x4000>; + dma-channels = <32>; + dma-requests = <64>; + dmamux-reg-offset = <3>; + channel-gap = <12 127>; + #dma-cells = <2>; + nxp,mem2mem; + interrupts = <4 0>, <5 0>, <6 0>, <7 0>, + <8 0>, <9 0>, <10 0>, <11 0>, + <12 0>, <13 0>, <14 0>, <15 0>, + <16 0>, <17 0>, <18 0>, <19 0>, + <20 0>, <21 0>, <22 0>, <23 0>, + <24 0>, <25 0>, <26 0>, <27 0>, + <28 0>, <29 0>, <30 0>, <31 0>, + <32 0>, <33 0>, <34 0>, <35 0>; + no-error-irq; status = "disabled"; }; diff --git a/dts/bindings/dma/nxp,mcux-edma.yaml b/dts/bindings/dma/nxp,mcux-edma.yaml index 0a0b0a66e2d..50df791ebf7 100644 --- a/dts/bindings/dma/nxp,mcux-edma.yaml +++ b/dts/bindings/dma/nxp,mcux-edma.yaml @@ -23,6 +23,19 @@ properties: dma-requests: required: true + dmamux-reg-offset: + type: int + default: 0 + description: + The offset value for obtaining DMAMUX register index from DMAMUX channel. + Default value means DMAMUX channel is identical with DMAMUX register index + + channel-gap: + type: array + description: | + On some platforms, there may be a gap in the channels and + this array specifies the start and end of a single gap + nxp,mem2mem: type: boolean description: If the DMA controller supports memory to memory transfer diff --git a/soc/arm/nxp_s32/s32k/Kconfig.series b/soc/arm/nxp_s32/s32k/Kconfig.series index 566c3608fee..3567b562cd7 100644 --- a/soc/arm/nxp_s32/s32k/Kconfig.series +++ b/soc/arm/nxp_s32/s32k/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_S32K3_M7 select HAS_MCUX_FLEXCAN select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI + select HAS_MCUX_CACHE help Enable support for NXP S32K3 MCUs family on Cortex-M7 cores From b4f390e880f564fd2960c14cb2f8bf727de7da3e Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 15 Jun 2023 07:16:57 +0700 Subject: [PATCH 1192/4498] boards: arm: mr_canhubk3: enable dma support Enable dma support for mr_canhubk3 board Signed-off-by: Dat Nguyen Duy --- boards/arm/mr_canhubk3/doc/index.rst | 1 + boards/arm/mr_canhubk3/mr_canhubk3.dts | 5 +++++ west.yml | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/boards/arm/mr_canhubk3/doc/index.rst b/boards/arm/mr_canhubk3/doc/index.rst index 1bd71a064c3..a26b6dd3ec2 100644 --- a/boards/arm/mr_canhubk3/doc/index.rst +++ b/boards/arm/mr_canhubk3/doc/index.rst @@ -57,6 +57,7 @@ LPSPI on-chip spi WDT FS26 SBC watchdog EMAC on-chip ethernet eMIOS on-chip pwm +EDMA on-chip dma ============ ========== ================================ The default configuration can be found in the Kconfig file diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index ba271d7af3d..8eb00eb12d4 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -29,6 +29,7 @@ }; aliases { + dma0 = &edma0; led0 = &user_led1_red; led1 = &user_led1_green; led2 = &user_led1_blue; @@ -554,3 +555,7 @@ }; }; }; + +&edma0 { + status = "okay"; +}; diff --git a/west.yml b/west.yml index b7f6f496c59..39aa1827835 100644 --- a/west.yml +++ b/west.yml @@ -199,7 +199,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 8cc344e9091fdaf2aea821714ee806b04cfb950e + revision: 6d91c1727dadb170facc48f5370358a12ae36677 path: modules/hal/nxp groups: - hal From 11f5eb5913975af577d379760245b4ca73b27f1a Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 15 Jun 2023 07:14:32 +0700 Subject: [PATCH 1193/4498] tests: drivers: dma: enable dma test for mr_canhubk3 Add devicetree overlay for enabling dma test for mr_canhubk3 board Signed-off-by: Dat Nguyen Duy --- .../drivers/dma/chan_blen_transfer/boards/mr_canhubk3.conf | 2 ++ .../dma/chan_blen_transfer/boards/mr_canhubk3.overlay | 7 +++++++ .../dma/chan_link_transfer/boards/mr_canhubk3.overlay | 7 +++++++ tests/drivers/dma/loop_transfer/boards/mr_canhubk3.overlay | 7 +++++++ tests/drivers/dma/scatter_gather/boards/mr_canhubk3.conf | 1 + 5 files changed, 24 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.overlay create mode 100644 tests/drivers/dma/chan_link_transfer/boards/mr_canhubk3.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/mr_canhubk3.overlay create mode 100644 tests/drivers/dma/scatter_gather/boards/mr_canhubk3.conf diff --git a/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.conf b/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.conf new file mode 100644 index 00000000000..8c952de5bd9 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=12 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=31 diff --git a/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.overlay b/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.overlay new file mode 100644 index 00000000000..afc9c1b2495 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/mr_canhubk3.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma0: &edma0 { }; diff --git a/tests/drivers/dma/chan_link_transfer/boards/mr_canhubk3.overlay b/tests/drivers/dma/chan_link_transfer/boards/mr_canhubk3.overlay new file mode 100644 index 00000000000..f13c97d754e --- /dev/null +++ b/tests/drivers/dma/chan_link_transfer/boards/mr_canhubk3.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dma0: &edma0 { }; diff --git a/tests/drivers/dma/loop_transfer/boards/mr_canhubk3.overlay b/tests/drivers/dma/loop_transfer/boards/mr_canhubk3.overlay new file mode 100644 index 00000000000..afc9c1b2495 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/mr_canhubk3.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma0: &edma0 { }; diff --git a/tests/drivers/dma/scatter_gather/boards/mr_canhubk3.conf b/tests/drivers/dma/scatter_gather/boards/mr_canhubk3.conf new file mode 100644 index 00000000000..61f2d18ca3c --- /dev/null +++ b/tests/drivers/dma/scatter_gather/boards/mr_canhubk3.conf @@ -0,0 +1 @@ +CONFIG_DMA_TCD_QUEUE_SIZE=4 From 9b1e8cd3c2b9554238f7e0548f92830f25df449a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 27 Sep 2023 16:31:08 +0200 Subject: [PATCH 1194/4498] doc: boards: Fix typo in Arduino Giga R1 note directive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a minor typo causing Sphinx note to not render. Signed-off-by: Benjamin Cabé --- boards/arm/arduino_giga_r1/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/arduino_giga_r1/doc/index.rst b/boards/arm/arduino_giga_r1/doc/index.rst index 80f4cb956fc..2e2b03917cc 100644 --- a/boards/arm/arduino_giga_r1/doc/index.rst +++ b/boards/arm/arduino_giga_r1/doc/index.rst @@ -82,7 +82,7 @@ that run the command: west blobs fetch hal_infineon -.. note: Only Bluetooth functionality is currently supported. +.. note:: Only Bluetooth functionality is currently supported. Resources sharing ================= From eb956d085344f2d1333b2b24ff1bfb8130d43927 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 17:31:50 +0000 Subject: [PATCH 1195/4498] tests: pm: driver_init: use native_posix for testing Use native_posix, this is a better platform for getting test coverage. Signed-off-by: Anas Nashif --- tests/subsys/pm/device_driver_init/testcase.yaml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/subsys/pm/device_driver_init/testcase.yaml b/tests/subsys/pm/device_driver_init/testcase.yaml index e3e35d97841..8920e38741b 100644 --- a/tests/subsys/pm/device_driver_init/testcase.yaml +++ b/tests/subsys/pm/device_driver_init/testcase.yaml @@ -1,16 +1,15 @@ +common: + platform_allow: + - native_posix + tags: + - pm tests: - pm.device_driver_init: - tags: pm - platform_allow: qemu_cortex_m3 + pm.device_driver_init: {} pm.device_driver_init.pm: - tags: pm - platform_allow: qemu_cortex_m3 extra_configs: - CONFIG_PM_DEVICE=y - CONFIG_PM_DEVICE_POWER_DOMAIN=y pm.device_driver_init.pm_device_runtime: - tags: pm - platform_allow: qemu_cortex_m3 extra_configs: - CONFIG_PM_DEVICE=y - CONFIG_PM_DEVICE_POWER_DOMAIN=y From c532595519d643611669606942d302aba337ce80 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 19:28:35 +0000 Subject: [PATCH 1196/4498] tests: pm: driver_init: rename testcase, demo is ambigous Use a more descriptive testcase name. Signed-off-by: Anas Nashif --- tests/subsys/pm/device_driver_init/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/pm/device_driver_init/src/main.c b/tests/subsys/pm/device_driver_init/src/main.c index e59b130e182..f423b1d683c 100644 --- a/tests/subsys/pm/device_driver_init/src/main.c +++ b/tests/subsys/pm/device_driver_init/src/main.c @@ -27,7 +27,7 @@ zassert_equal(rc, 0, "Device state retrieval failed"); \ zassert_equal(state, value, "Unexpected device state"); -ZTEST(device_driver_init, test_demo) +ZTEST(device_driver_init, test_device_driver_init) { #if IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) enum pm_device_state state; From d885048637d6070182cf3ca832631dc91c85ad14 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 19:32:35 +0000 Subject: [PATCH 1197/4498] tests: pm: power_domains: rename testcase, demo is ambigous Rename testcase and use native_posix for coverage. Signed-off-by: Anas Nashif --- tests/subsys/pm/device_power_domains/src/main.c | 2 +- tests/subsys/pm/device_power_domains/testcase.yaml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/subsys/pm/device_power_domains/src/main.c b/tests/subsys/pm/device_power_domains/src/main.c index 50726bcef19..6123a8a5f54 100644 --- a/tests/subsys/pm/device_power_domains/src/main.c +++ b/tests/subsys/pm/device_power_domains/src/main.c @@ -29,7 +29,7 @@ PM_DEVICE_DT_DEFINE(DT_NODELABEL(test_dev), dev_pm_control); DEVICE_DT_DEFINE(DT_NODELABEL(test_dev), dev_init, PM_DEVICE_DT_GET(DT_NODELABEL(test_dev)), NULL, NULL, POST_KERNEL, 80, NULL); -ZTEST(device_power_domain, test_demo) +ZTEST(device_power_domain, test_device_power_domain) { const struct device *const reg_0 = DEVICE_DT_GET(DT_NODELABEL(test_reg_0)); const struct device *const reg_1 = DEVICE_DT_GET(DT_NODELABEL(test_reg_1)); diff --git a/tests/subsys/pm/device_power_domains/testcase.yaml b/tests/subsys/pm/device_power_domains/testcase.yaml index cc661ae8561..11b00299f5c 100644 --- a/tests/subsys/pm/device_power_domains/testcase.yaml +++ b/tests/subsys/pm/device_power_domains/testcase.yaml @@ -1,4 +1,6 @@ tests: pm.power_domain.device: - tags: pm - platform_allow: qemu_cortex_m3 + tags: + - pm + platform_allow: + - native_posix From 90c6465f1ffe1d01c334fea5fe29c89078b83b41 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 26 Sep 2023 11:49:04 -0700 Subject: [PATCH 1198/4498] modules: fix naming of cmsis-nn,cmsis-dsp folder The names have underscores within them. Somehow it was still being found within the build but not with building documents. This renames them to the correct name. Signed-off-by: Ryan McClelland --- MAINTAINERS.yml | 8 ++++---- modules/Kconfig | 6 ++++++ modules/{cmsis_dsp => cmsis-dsp}/CMakeLists.txt | 0 modules/{cmsis_dsp => cmsis-dsp}/Kconfig | 0 modules/{cmsis_nn => cmsis-nn}/CMakeLists.txt | 0 modules/{cmsis_nn => cmsis-nn}/Kconfig | 0 6 files changed, 10 insertions(+), 4 deletions(-) rename modules/{cmsis_dsp => cmsis-dsp}/CMakeLists.txt (100%) rename modules/{cmsis_dsp => cmsis-dsp}/Kconfig (100%) rename modules/{cmsis_nn => cmsis-nn}/CMakeLists.txt (100%) rename modules/{cmsis_nn => cmsis-nn}/Kconfig (100%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 959c7991408..c4cac66dde0 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -424,7 +424,7 @@ CMSIS-DSP integration: - galak - XenuIsWatching files: - - modules/cmsis_dsp/ + - modules/cmsis-dsp/ - tests/benchmarks/cmsis_dsp/ - tests/lib/cmsis_dsp/ labels: @@ -438,7 +438,7 @@ CMSIS-NN integration: - stephanosio - XenuIsWatching files: - - modules/cmsis_nn/ + - modules/cmsis-nn/ - tests/lib/cmsis_nn/ labels: - "area: CMSIS-NN" @@ -2952,7 +2952,7 @@ West: collaborators: - stephanosio files: - - modules/cmsis_dsp/ + - modules/cmsis-dsp/ labels: - "area: ARM" @@ -2963,7 +2963,7 @@ West: collaborators: - stephanosio files: - - modules/cmsis_nn/ + - modules/cmsis-nn/ labels: - "area: ARM" diff --git a/modules/Kconfig b/modules/Kconfig index a2dad7e9c4a..751884841c3 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -108,6 +108,12 @@ comment "Segger module not available." comment "LVGL module not available." depends on !ZEPHYR_LVGL_MODULE +comment "cmsis-dsp module not available." + depends on !ZEPHYR_CMSIS_DSP_MODULE + +comment "cmsis-nn module not available." + depends on !ZEPHYR_CMSIS_NN_MODULE + # This ensures that symbols are available in Kconfig for dependency checking # and referencing, while keeping the settings themselves unavailable when the # modules are not present in the workspace diff --git a/modules/cmsis_dsp/CMakeLists.txt b/modules/cmsis-dsp/CMakeLists.txt similarity index 100% rename from modules/cmsis_dsp/CMakeLists.txt rename to modules/cmsis-dsp/CMakeLists.txt diff --git a/modules/cmsis_dsp/Kconfig b/modules/cmsis-dsp/Kconfig similarity index 100% rename from modules/cmsis_dsp/Kconfig rename to modules/cmsis-dsp/Kconfig diff --git a/modules/cmsis_nn/CMakeLists.txt b/modules/cmsis-nn/CMakeLists.txt similarity index 100% rename from modules/cmsis_nn/CMakeLists.txt rename to modules/cmsis-nn/CMakeLists.txt diff --git a/modules/cmsis_nn/Kconfig b/modules/cmsis-nn/Kconfig similarity index 100% rename from modules/cmsis_nn/Kconfig rename to modules/cmsis-nn/Kconfig From 8d5ed530d7131ba411696a8a66453cb1b692980e Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 26 Sep 2023 11:51:09 -0700 Subject: [PATCH 1199/4498] modules: remove uncessary source for external cmsis kconfig CMSIS uses an external KConfig so sourcing the KConfig is uncessary. This also adds a comment if it is not available. Signed-off-by: Ryan McClelland --- modules/Kconfig | 4 +++- modules/cmsis/Kconfig | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/Kconfig b/modules/Kconfig index 751884841c3..687ce19da81 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -17,7 +17,6 @@ comment "Optional modules. Make sure they're installed, via the project manifest source "modules/Kconfig.altera" source "modules/Kconfig.atmel" source "modules/Kconfig.chre" -source "modules/cmsis/Kconfig" source "modules/Kconfig.cypress" source "modules/Kconfig.eos_s3" source "modules/Kconfig.esp32" @@ -108,6 +107,9 @@ comment "Segger module not available." comment "LVGL module not available." depends on !ZEPHYR_LVGL_MODULE +comment "cmsis module not available." + depends on !ZEPHYR_CMSIS_MODULE + comment "cmsis-dsp module not available." depends on !ZEPHYR_CMSIS_DSP_MODULE diff --git a/modules/cmsis/Kconfig b/modules/cmsis/Kconfig index 6007292ff2e..4b5a8ee2855 100644 --- a/modules/cmsis/Kconfig +++ b/modules/cmsis/Kconfig @@ -1,6 +1,9 @@ # Copyright (c) 2016 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_CMSIS_MODULE + bool + config HAS_CMSIS_CORE bool select HAS_CMSIS_CORE_A if CPU_AARCH32_CORTEX_A From 6dc15abb8558266d62587f0ea1adbdeb36be549f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 30 Aug 2023 17:16:42 +0000 Subject: [PATCH 1200/4498] doc: roles: remove reference to slide Reference to slide that does not exist. Signed-off-by: Anas Nashif --- doc/project/project_roles.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index 95d38da438c..0f24f100dbd 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -271,7 +271,7 @@ Generic guidelines for deciding and filling in the Maintainers' list * Pull requests may be re-assigned if this is needed or more appropriate - * Re-assigned by original assignee (see “Assignee” slide) + * Re-assigned by original assignee * In general, updates to the MAINTAINERS file should be in a standalone commit alongside other changes introducing new files and From 79aaa9061c75ba22c71a3dfa92fe81d825c17cea Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 30 Aug 2023 18:11:05 +0000 Subject: [PATCH 1201/4498] doc: release: update merge criteria Document 4 eye principal for reviews and merges. Signed-off-by: Anas Nashif --- doc/project/project_roles.rst | 49 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index 0f24f100dbd..c2b970c77f7 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -314,7 +314,40 @@ Release Activity Merge Criteria ++++++++++++++ -* All continuous integration checks have passed +* Minimal of 2 approvals, including an approval by the designated assignee. +* Pull requests should be reviewed by at least a maintainer or collaborator of + each affected area; Unless the changes to a given area are considered trivial + enough, in which case approvals by other affected subsystems + maintainers/collaborators would suffice. +* Four eye principle on the organisation level. We already require at least 2 + approvals (basic four eye principle), however, such reviews and approvals + might be unintentionally biased in the case where the submitter is from the + same organisation as the approvers. To allow for project wide review and + approvals, the merge criteria is extended with the guidelines below: + + * Changes or additions to common and shared code shall have approvals from + different organisations (at least one approval from an + organisation different than the submitters'). + Common and shared code is defined as anything that does not fall under + :file:`soc`, :file:`boards` and :file:`drivers/*/*`. + * Changes or additions to hardware support (driver, SoC, boards) shall at + least have the merger be from a different organisation. This applies only + to implementation of an API supporting vendor specific hardware and not the + APIs. + * Release engineers may make exceptions for areas with contributions primarily + coming from one organisation and where reviews from other organisations are + not possible, however, merges shall be completed by a person from a different + organisation. In such cases, the minimum review period of at least 2 days + shall be strictly followed to allow for additional reviews. + * Release engineers shall not merge code changes originating and reviewed + only by their own organisation. To be able to merge such changes, at least + one review shall be from a different organisation. + +* A minimum review period of 2 business days, 4 hours for trivial changes (see + :ref:`review_time`). +* Hotfixes can be merged at any time after CI has passed and are excluded from + most of the conditions listed above. +* All required checks are passing: * Codeowners * Device Tree @@ -322,7 +355,7 @@ Merge Criteria * Gitlint * Identity/Emails * Kconfig - * License + * License checks * Checkpatch (Coding Style) * Pylint * Integration Tests (Via twister) on emulation/simulation platforms @@ -335,15 +368,3 @@ Merge Criteria * Coding Guidelines * Static Analysis (Coverity) * Documentation coverage (APIs) - -* PR template with checklist - -* Minimal of 2 approvals - - * A collaborator from the same subsystem. - * Alternately another maintainer of another subsystem - * Approval by the assignee - -* A minimum review period of 2 days, 4 hours for trivial changes (see - :ref:`review_time`). Hotfixes can be merged at any time after CI passes. -* All required checks are passing From 59c501c6df5ae25e91d8ec3f7cdb6c108b4c45ed Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 16 Aug 2023 15:05:30 -0700 Subject: [PATCH 1202/4498] doc: security: Add information about backports Clarify about how to proceed with backports for vulnerabilities. Signed-off-by: Flavio Ceolin --- doc/security/reporting.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/security/reporting.rst b/doc/security/reporting.rst index c3c39677175..376237fe938 100644 --- a/doc/security/reporting.rst +++ b/doc/security/reporting.rst @@ -107,6 +107,8 @@ within the Zephyr project to fix the issues, and 60 days for external parties building products using Zephyr to be able to apply and distribute these fixes. +.. _vulnerability_fix_recommendations: + Fixes to the code shall be made through pull requests PR in the Zephyr project github. Developers shall make an attempt to not reveal the sensitive nature of what is being fixed, and shall not refer to CVE @@ -180,7 +182,12 @@ following releases: The developer of the fix shall be responsible for any necessary backports, and apply them to any of the above listed release branches, unless the fix does not apply (the vulnerability was introduced after -this release was made). +this release was made). All recommendations for +:ref:`vulnerability fixes ` apply +for backport pull requests (and associated issues). Additionally, it is +recommended that the developer privately informs the responsible +release manager that the backport pull request and issue are addressing +a vulnerability. Backports will be tracked on the security advisory. From db4febc584c86ff5a1dd2addb45874a0ef676f45 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 14 Mar 2023 12:37:49 +0000 Subject: [PATCH 1203/4498] retention: Add bootloader configuration interface Adds a bootloader configuration interface which allows for a bootloader (e.g. MCUboot) to set configuration in a shared data area which is then read by the application. Signed-off-by: Jamie McCrae --- include/zephyr/retention/blinfo.h | 58 ++++++++++++ scripts/ci/check_compliance.py | 10 ++- subsys/retention/CMakeLists.txt | 5 ++ subsys/retention/Kconfig | 4 +- subsys/retention/Kconfig.blinfo | 55 ++++++++++++ subsys/retention/blinfo_mcuboot.c | 143 ++++++++++++++++++++++++++++++ 6 files changed, 270 insertions(+), 5 deletions(-) create mode 100644 include/zephyr/retention/blinfo.h create mode 100644 subsys/retention/Kconfig.blinfo create mode 100644 subsys/retention/blinfo_mcuboot.c diff --git a/include/zephyr/retention/blinfo.h b/include/zephyr/retention/blinfo.h new file mode 100644 index 00000000000..0ecd051771f --- /dev/null +++ b/include/zephyr/retention/blinfo.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public API for boot mode interface + */ + +#ifndef ZEPHYR_INCLUDE_RETENTION_BLINFO_ +#define ZEPHYR_INCLUDE_RETENTION_BLINFO_ + +#include +#include +#include + +#if defined(CONFIG_RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Bootloader info interface + * @defgroup bootloader_info_interface Bootloader info interface + * @ingroup retention_api + * @{ + */ + +#if IS_ENABLED(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION) || defined(__DOXYGEN__) +/** + * @brief Returns bootinfo information. + * + * @param key The information to return (for MCUboot: minor TLV). + * @param val Where the return information will be placed. + * @param val_len_max The maximum size of the provided buffer. + * + * @retval 0 If successful. + * @retval -EOVERFLOW If the data is too large to fit the supplied buffer. + * @retval -EIO If the requested key was not found. + * @retval -errno Error code. + */ +int blinfo_lookup(uint16_t key, char *val, int val_len_max); +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_RETENTION_BLINFO_ */ diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 140c59d4fb2..a54d2f807ac 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -624,11 +624,13 @@ def check_no_undef_outside_kconfig(self, kconf): "BOOT_SERIAL_CDC_ACM", # Used in (sysbuild-based) test "BOOT_SERIAL_ENTRANCE_GPIO", # Used in (sysbuild-based) test "BOOT_SERIAL_IMG_GRP_HASH", # Used in documentation - "BOOT_SIGNATURE_KEY_FILE", # MCUboot setting used by sysbuild + "BOOT_SHARE_DATA", # Used in Kconfig text + "BOOT_SHARE_BACKEND_RETENTION", # Used in Kconfig text + "BOOT_SIGNATURE_KEY_FILE", # MCUboot setting used by sysbuild "BOOT_SIGNATURE_TYPE_ECDSA_P256", # MCUboot setting used by sysbuild - "BOOT_SIGNATURE_TYPE_ED25519", # MCUboot setting used by sysbuild - "BOOT_SIGNATURE_TYPE_NONE", # MCUboot setting used by sysbuild - "BOOT_SIGNATURE_TYPE_RSA", # MCUboot setting used by sysbuild + "BOOT_SIGNATURE_TYPE_ED25519", # MCUboot setting used by sysbuild + "BOOT_SIGNATURE_TYPE_NONE", # MCUboot setting used by sysbuild + "BOOT_SIGNATURE_TYPE_RSA", # MCUboot setting used by sysbuild "BOOT_VALIDATE_SLOT0", # Used in (sysbuild-based) test "BOOT_WATCHDOG_FEED", # Used in (sysbuild-based) test "BTTESTER_LOG_LEVEL", # Used in tests/bluetooth/tester diff --git a/subsys/retention/CMakeLists.txt b/subsys/retention/CMakeLists.txt index 6cea5b490df..a70469a4171 100644 --- a/subsys/retention/CMakeLists.txt +++ b/subsys/retention/CMakeLists.txt @@ -3,3 +3,8 @@ zephyr_library() zephyr_library_sources(retention.c) zephyr_library_sources_ifdef(CONFIG_RETENTION_BOOT_MODE bootmode.c) + +if(CONFIG_RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT) + zephyr_library_sources(blinfo_mcuboot.c) + zephyr_link_libraries(MCUBOOT_BOOTUTIL) +endif() diff --git a/subsys/retention/Kconfig b/subsys/retention/Kconfig index 0f3def9abc9..e42d7e7ebf9 100644 --- a/subsys/retention/Kconfig +++ b/subsys/retention/Kconfig @@ -17,7 +17,7 @@ config RETENTION_INIT_PRIORITY default 86 help Retention device initialization priority (must be higher than init - priorities for retained memory drivers. + priorities for retained memory drivers). config RETENTION_MUTEXES bool @@ -55,6 +55,8 @@ config RETENTION_BOOT_MODE byte must be created and set as the "zephyr,boot-mode" chosen node via device tree. +source "subsys/retention/Kconfig.blinfo" + endmenu module = RETENTION diff --git a/subsys/retention/Kconfig.blinfo b/subsys/retention/Kconfig.blinfo new file mode 100644 index 00000000000..57c5222511a --- /dev/null +++ b/subsys/retention/Kconfig.blinfo @@ -0,0 +1,55 @@ +# Copyright (c) 2023, Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menuconfig RETENTION_BOOTLOADER_INFO + bool "Bootloader info" + help + Adds a bootloader information sharing system which allows for + retreiving data from the bootloader when data sharing is enabled. + +if RETENTION_BOOTLOADER_INFO + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_BOOTLOADER_INFO := zephyr,bootloader-info + +config RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT + bool "MCUboot" + depends on !MCUBOOT && BOOTLOADER_MCUBOOT + depends on $(dt_chosen_enabled,$(DT_CHOSEN_BOOTLOADER_INFO)) + select MCUBOOT_BOOTUTIL_LIB + help + Adds a bootloader information sharing system for MCUboot and + applications which allows applications to read the configuration of + MCUboot and the running image. This can be used by applications so + that they know how to e.g. handle firmware updates and place them + into the correct slot. + + In order to use this, a retention area must be created and set as + the "zephyr,bootloader-info" chosen node via device tree, MCUboot + must be built with the same "zephyr,bootloader-info" DTS node and + have CONFIG_BOOT_SHARE_DATA, CONFIG_BOOT_SHARE_DATA_BOOTINFO and + CONFIG_BOOT_SHARE_BACKEND_RETENTION enabled, or the shared + information will not be accessible. + +config RETENTION_BOOTLOADER_INFO_INIT_PRIORITY + int "Bootloader info init priority" + default 87 + help + Bootloader info initialization priority (must be higher than init + priorities for for retention subsystem). + +config RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION + bool "Function" + default y + help + Allows bootloader settings to be fetched by calling a function which + will update a buffer with the requested data. + +config RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS + bool "Settings" + depends on SETTINGS + help + Allows bootloader settings to be fetched using settings with the + "blinfo" prefix. + +endif diff --git a/subsys/retention/blinfo_mcuboot.c b/subsys/retention/blinfo_mcuboot.c new file mode 100644 index 00000000000..35845dee712 --- /dev/null +++ b/subsys/retention/blinfo_mcuboot.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(blinfo_mcuboot, CONFIG_RETENTION_LOG_LEVEL); + +static const struct device *bootloader_info_dev = + DEVICE_DT_GET(DT_CHOSEN(zephyr_bootloader_info)); + +#if !defined(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION) +static +#endif +int blinfo_lookup(uint16_t key, char *val, int val_len_max) +{ + struct shared_data_tlv_header header; + struct shared_data_tlv_entry tlv_entry = {0}; + uintptr_t offset = SHARED_DATA_HEADER_SIZE; + int rc; + + rc = retention_read(bootloader_info_dev, 0, (void *)&header, sizeof(header)); + + if (rc != 0) { + return rc; + } + + /* Iterate over the whole shared MCUboot data section and look for a TLV with + * the required tag. + */ + while (offset < header.tlv_tot_len) { + rc = retention_read(bootloader_info_dev, offset, (void *)&tlv_entry, + sizeof(tlv_entry)); + + if (rc != 0) { + return rc; + } + + if (GET_MAJOR(tlv_entry.tlv_type) == TLV_MAJOR_BLINFO && + GET_MINOR(tlv_entry.tlv_type) == key) { + /* Return an error if the provided buffer is too small to fit the + * value in it, bootloader values are small and concise and should + * be able to fit in a single buffer. + */ + if (tlv_entry.tlv_len > val_len_max) { + return -EOVERFLOW; + } + + offset += SHARED_DATA_ENTRY_HEADER_SIZE; + rc = retention_read(bootloader_info_dev, offset, val, + tlv_entry.tlv_len); + + if (rc != 0) { + return rc; + } + + return tlv_entry.tlv_len; + } + + offset += SHARED_DATA_ENTRY_SIZE(tlv_entry.tlv_len); + } + + /* Return IO error as a valid key name was provided but the TLV was not found in + * the shared data section. + */ + return -EIO; +} + +#if defined(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS) +static int blinfo_handle_get(const char *name, char *val, int val_len_max); + +static struct settings_handler blinfo_handler = { + .name = "blinfo", + .h_get = blinfo_handle_get, +}; + +static int blinfo_handle_get(const char *name, char *val, int val_len_max) +{ + const char *next; + uint16_t index; + + /* Allowed keys are mode, signature_type, recovery, running_slot, bootloader_version + * and max_application_size which cannot contain any additional entries + */ + if (settings_name_steq(name, "mode", &next) && !next) { + index = BLINFO_MODE; + } else if (settings_name_steq(name, "signature_type", &next) && !next) { + index = BLINFO_SIGNATURE_TYPE; + } else if (settings_name_steq(name, "recovery", &next) && !next) { + index = BLINFO_RECOVERY; + } else if (settings_name_steq(name, "running_slot", &next) && !next) { + index = BLINFO_RUNNING_SLOT; + } else if (settings_name_steq(name, "bootloader_version", &next) && !next) { + index = BLINFO_BOOTLOADER_VERSION; + } else if (settings_name_steq(name, "max_application_size", &next) && !next) { + index = BLINFO_MAX_APPLICATION_SIZE; + } else { + return -ENOENT; + } + + return blinfo_lookup(index, val, val_len_max); +} +#endif + +static int blinfo_init(void) +{ + int rc; + + rc = retention_is_valid(bootloader_info_dev); + + if (rc == 1 || rc == -ENOTSUP) { + struct shared_data_tlv_header header; + + rc = retention_read(bootloader_info_dev, 0, (void *)&header, sizeof(header)); + + if (rc == 0 && header.tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) { + /* Unknown data present */ + LOG_ERR("MCUboot data load failed, expected magic value: 0x%x, got: 0x%x", + SHARED_DATA_TLV_INFO_MAGIC, header.tlv_magic); + rc = -EINVAL; + } + } + +#if defined(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS) + if (rc == 0) { + settings_register(&blinfo_handler); + } +#endif + + return rc; +} + +SYS_INIT(blinfo_init, APPLICATION, CONFIG_RETENTION_BOOTLOADER_INFO_INIT_PRIORITY); From ce65806cd4b46f6abc6a009e8d8c22c92232cfbe Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 9 Jun 2023 14:27:38 +0100 Subject: [PATCH 1204/4498] tests: boot: Add MCUboot data sharing test Adds a test for the data sharing retention feature of MCUboot configuration to an application. Signed-off-by: Jamie McCrae --- scripts/ci/check_compliance.py | 1 + .../boot/mcuboot_data_sharing/CMakeLists.txt | 30 +++++ .../boards/nrf52840dk_nrf52840.conf | 7 + .../boards/nrf52840dk_nrf52840.overlay | 58 +++++++++ tests/boot/mcuboot_data_sharing/prj.conf | 13 ++ tests/boot/mcuboot_data_sharing/src/main.c | 122 ++++++++++++++++++ tests/boot/mcuboot_data_sharing/sysbuild.conf | 1 + .../mcuboot/boards/nrf52840dk_nrf52840.conf | 5 + .../boards/nrf52840dk_nrf52840.overlay | 8 ++ .../sysbuild/mcuboot/prj.conf | 7 + tests/boot/mcuboot_data_sharing/testcase.yaml | 14 ++ 11 files changed, 266 insertions(+) create mode 100644 tests/boot/mcuboot_data_sharing/CMakeLists.txt create mode 100644 tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.conf create mode 100644 tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.overlay create mode 100644 tests/boot/mcuboot_data_sharing/prj.conf create mode 100644 tests/boot/mcuboot_data_sharing/src/main.c create mode 100644 tests/boot/mcuboot_data_sharing/sysbuild.conf create mode 100644 tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf create mode 100644 tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay create mode 100644 tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/prj.conf create mode 100644 tests/boot/mcuboot_data_sharing/testcase.yaml diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index a54d2f807ac..713fe21cbff 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -625,6 +625,7 @@ def check_no_undef_outside_kconfig(self, kconf): "BOOT_SERIAL_ENTRANCE_GPIO", # Used in (sysbuild-based) test "BOOT_SERIAL_IMG_GRP_HASH", # Used in documentation "BOOT_SHARE_DATA", # Used in Kconfig text + "BOOT_SHARE_DATA_BOOTINFO", # Used in (sysbuild-based) test "BOOT_SHARE_BACKEND_RETENTION", # Used in Kconfig text "BOOT_SIGNATURE_KEY_FILE", # MCUboot setting used by sysbuild "BOOT_SIGNATURE_TYPE_ECDSA_P256", # MCUboot setting used by sysbuild diff --git a/tests/boot/mcuboot_data_sharing/CMakeLists.txt b/tests/boot/mcuboot_data_sharing/CMakeLists.txt new file mode 100644 index 00000000000..6bdbb43d36b --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mcuboot_recovery_retention) + +if(NOT (DEFINED SYSBUILD)) + message(FATAL_ERROR "This test must be built with sysbuild.") +endif() + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) + +# Get MCUboot version from the VERSION file in the repository and create a local output header +# version file so that it can be compared against in the test +set(VERSION_FILE ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/VERSION) +set(VERSION_TYPE MCUBOOT) +set(BUILD_VERSION_NAME MCUBOOT_BUILD_VERSION) +include(${ZEPHYR_BASE}/cmake/modules/version.cmake) +file(READ ${ZEPHYR_BASE}/version.h.in version_content) +string(CONFIGURE "${version_content}" version_content) +string(CONFIGURE "${version_content}" version_content) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/zephyr/include/generated/mcuboot_version.h "${version_content}") diff --git a/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.conf b/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000..8f39b13f7ec --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,7 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_RETAINED_MEM_NRF_GPREGRET=n +CONFIG_RETAINED_MEM_ZEPHYR_RAM=y diff --git a/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.overlay b/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000..5aaff71d8d7 --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + sram@2003F000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2003F000 DT_SIZE_K(1)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + boot_info0: boot_info@0 { + compatible = "zephyr,retention"; + status = "okay"; + reg = <0x0 0x100>; + }; + }; + }; + + chosen { + zephyr,bootloader-info = &boot_info0; + }; +}; + +/delete-node/ &gpregret1; +/delete-node/ &gpregret2; +/delete-node/ &boot_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(255)>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00020000>; + }; + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 0x00022000>; + }; + slot1_partition: partition@42000 { + label = "image-1"; + reg = <0x00042000 0x00024000>; + }; + }; +}; diff --git a/tests/boot/mcuboot_data_sharing/prj.conf b/tests/boot/mcuboot_data_sharing/prj.conf new file mode 100644 index 00000000000..05ac5db1ab1 --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/prj.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_RETAINED_MEM=y +CONFIG_RETENTION=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y +CONFIG_RETENTION_BOOTLOADER_INFO=y +CONFIG_RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT=y diff --git a/tests/boot/mcuboot_data_sharing/src/main.c b/tests/boot/mcuboot_data_sharing/src/main.c new file mode 100644 index 00000000000..1cf3954169b --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/src/main.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define FLASH_SECTOR_SIZE 1024 +#define FLASH_SECTOR_SIZE_KB 4 +#define FLASH_MAX_APP_SECTORS 34 +#define FLASH_RESERVED_SECTORS 1 +#define FLASH_MAX_APP_SIZE ((FLASH_MAX_APP_SECTORS - FLASH_RESERVED_SECTORS) \ + * FLASH_SECTOR_SIZE_KB) +#define RUNNING_SLOT 0 + +ZTEST(mcuboot_shared_data, test_mode) +{ + uint8_t var[1]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/mode", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + zassert_equal(var[0], MCUBOOT_MODE_SWAP_USING_MOVE, "Expected data mismatch"); +} + +ZTEST(mcuboot_shared_data, test_signature_type) +{ + uint8_t var[1]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/signature_type", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + zassert_equal(var[0], MCUBOOT_SIGNATURE_TYPE_RSA, "Expected data mismatch"); +} + +ZTEST(mcuboot_shared_data, test_recovery) +{ + uint8_t var[1]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/recovery", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + zassert_equal(var[0], MCUBOOT_RECOVERY_MODE_NONE, "Expected data mismatch"); +} + +ZTEST(mcuboot_shared_data, test_running_slot) +{ + uint8_t var[1]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/running_slot", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + zassert_equal(var[0], RUNNING_SLOT, "Expected data mismatch"); +} + +ZTEST(mcuboot_shared_data, test_bootloader_version) +{ + uint8_t var[8]; + int rc; + struct image_version *version = (void *)var; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/bootloader_version", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + + zassert_equal(version->iv_major, MCUBOOT_VERSION_MAJOR, + "Expected version (major) mismatch"); + zassert_equal(version->iv_minor, MCUBOOT_VERSION_MINOR, + "Expected version (minor) mismatch"); + zassert_equal(version->iv_revision, MCUBOOT_PATCHLEVEL, + "Expected version (patch level) mismatch"); + zassert_equal(version->iv_build_num, 0, "Expected version (build number) mismatch"); +} + +ZTEST(mcuboot_shared_data, test_max_application_size) +{ + uint8_t var[4]; + uint32_t value; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/max_application_size", var, sizeof(var)); + zassert_equal(rc, sizeof(var), "Expected data length mismatch"); + memcpy(&value, var, sizeof(value)); + value /= FLASH_SECTOR_SIZE; + zassert_equal(value, FLASH_MAX_APP_SIZE, "Expected data mismatch"); +} + +ZTEST(mcuboot_shared_data, test_invalid) +{ + uint8_t var[4]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/does_not_exist", var, sizeof(var)); + zassert_not_equal(rc, sizeof(var), "Expected data length (error) mismatch"); + zassert_not_equal(rc, 0, "Expected data length (error) mismatch"); +} + +ZTEST(mcuboot_shared_data, test_bootloader_version_limited) +{ + uint8_t var[2]; + int rc; + + memset(var, 0xff, sizeof(var)); + rc = settings_runtime_get("blinfo/bootloader_version", var, sizeof(var)); + zassert_not_equal(rc, sizeof(var), "Expected data length mismatch"); +} + +ZTEST_SUITE(mcuboot_shared_data, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/boot/mcuboot_data_sharing/sysbuild.conf b/tests/boot/mcuboot_data_sharing/sysbuild.conf new file mode 100644 index 00000000000..47f00ff3cff --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_BOOTLOADER_MCUBOOT=y diff --git a/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000..0553e1bd746 --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,5 @@ +CONFIG_USE_SEGGER_RTT=n +CONFIG_NORDIC_QSPI_NOR=n +CONFIG_BOOT_VALIDATE_SLOT0=n +CONFIG_MCUBOOT_CLEANUP_ARM_CORE=n +CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000..e54f7fbf3a3 --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +#include "../../../boards/nrf52840dk_nrf52840.overlay" + +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/prj.conf b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000..102bd1bc1bf --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/sysbuild/mcuboot/prj.conf @@ -0,0 +1,7 @@ +CONFIG_RETAINED_MEM=y +CONFIG_RETENTION=y +CONFIG_BOOT_SHARE_DATA=y +CONFIG_BOOT_SHARE_DATA_BOOTINFO=y +CONFIG_BOOT_SHARE_BACKEND_RETENTION=y +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y diff --git a/tests/boot/mcuboot_data_sharing/testcase.yaml b/tests/boot/mcuboot_data_sharing/testcase.yaml new file mode 100644 index 00000000000..26eefd39523 --- /dev/null +++ b/tests/boot/mcuboot_data_sharing/testcase.yaml @@ -0,0 +1,14 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +common: + sysbuild: true +tests: + mcuboot.data.sharing: + platform_allow: nrf52840dk_nrf52840 + tags: + - mcuboot + - sysbuild + - retention From 4fe6f52175f8feb61b2b86124f8bca9d644bcdd9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 27 Sep 2023 09:37:06 +0100 Subject: [PATCH 1205/4498] doc: retention: Add blinfo subsystem documentation Adds some documentation on how to use the new subsystem Signed-off-by: Jamie McCrae --- doc/services/retention/blinfo.rst | 134 ++++++++++++++++++++++++++++++ doc/services/retention/index.rst | 11 +++ 2 files changed, 145 insertions(+) create mode 100644 doc/services/retention/blinfo.rst diff --git a/doc/services/retention/blinfo.rst b/doc/services/retention/blinfo.rst new file mode 100644 index 00000000000..6f34b0f9a35 --- /dev/null +++ b/doc/services/retention/blinfo.rst @@ -0,0 +1,134 @@ +.. _blinfo_api: + +Bootloader Information +###################### + +The bootloader information (abbreviated to blinfo) subsystem is an extension of +the :ref:`retention_api` which allows for reading shared data from a bootloader +and allowing applications to query it. It has an optional feature of organising +the information retrieved from the bootloader and storing it in the +:ref:`settings_api` with the ``blinfo/`` prefix. + +Devicetree setup +**************** + +To use the bootloader information subsystem, a retention area needs to be +created which has a retained data section as its parent, generally non-init RAM +is used for this purpose. See the following example (examples in this guide are +based on the :ref:`nrf52840dk_nrf52840` board and memory layout): + +.. code-block:: devicetree + + / { + sram@2003F000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2003F000 DT_SIZE_K(1)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + boot_info0: boot_info@0 { + compatible = "zephyr,retention"; + status = "okay"; + reg = <0x0 0x100>; + }; + }; + }; + + chosen { + zephyr,bootloader-info = &boot_info0; + }; + }; + + + /* Reduce SRAM0 usage by 1KB to account for non-init area */ + &sram0 { + reg = <0x20000000 DT_SIZE_K(255)>; + }; + +Note that this configuration needs to be applied on both the bootloader +(MCUboot) and application to be usable. It can be combined with other retention +system APIs such as the :ref:`boot_mode_api` + +MCUboot setup +************* + +Once the above devicetree configuration is applied, MCUboot needs to be +configured to store the shared data in this area, the following Kconfigs need +to be set for this: + +* :kconfig:option:`CONFIG_RETAINED_MEM` - Enables retained memory driver +* :kconfig:option:`CONFIG_RETENTION` - Enables retention system +* :kconfig:option:`CONFIG_BOOT_SHARE_DATA` - Enables shared data +* :kconfig:option:`CONFIG_BOOT_SHARE_DATA_BOOTINFO` - Enables boot information + shared data type +* :kconfig:option:`CONFIG_BOOT_SHARE_BACKEND_RETENTION` - Stores shared data + using retention/blinfo subsystem + +Application setup +***************** + +The application must enable the following base Kconfig options for the +bootloader information subsystem to function: + +* :kconfig:option:`CONFIG_RETAINED_MEM` +* :kconfig:option:`CONFIG_RETENTION` +* :kconfig:option:`CONFIG_RETENTION_BOOTLOADER_INFO` +* :kconfig:option:`CONFIG_RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT` + +The following include is needed to use the bootloader information subsystem: + +.. code-block:: C + + #include + +By default, only the lookup function is provided: :c:func:`blinfo_lookup`, the +application can call this to query the information from the bootloader. This +function is enabled by default with +:kconfig:option:`CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION`, however, +applications can optionally choose to use the settings storage feature instead. +In this mode, the bootloader information can be queries by using settings keys, +the following Kconfig options need to be enabled for this mode: + +* :kconfig:option:`CONFIG_SETTINGS` +* :kconfig:option:`CONFIG_SETTINGS_RUNTIME` +* :kconfig:option:`CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS` + +This allows the information to be queried via the +:c:func:`settings_runtime_get` function with the following keys: + +* ``blinfo/mode`` The mode that MCUboot is configured for + (``enum mcuboot_mode`` value) +* ``blinfo/signature_type`` The signature type MCUboot is configured for + (``enum mcuboot_signature_type`` value) +* ``blinfo/recovery`` The recovery type enabled in MCUboot + (``enum mcuboot_recovery_mode`` value) +* ``blinfo/running_slot`` The running slot, useful for direct-XIP mode to know + which slot to use for an update +* ``blinfo/bootloader_version`` Version of the bootloader + (``struct image_version`` object) +* ``blinfo/max_application_size`` Maximum size of an application (in bytes) + that can be loaded + +In addition to the previous include, the following includes are required for +this mode: + +.. code-block:: C + + #include + #include + #include + #include + +API Reference +************* + +Bootloader information API +========================== + +.. doxygengroup:: bootloader_info_interface diff --git a/doc/services/retention/index.rst b/doc/services/retention/index.rst index 0ae60332b0e..dc4572ec090 100644 --- a/doc/services/retention/index.rst +++ b/doc/services/retention/index.rst @@ -184,6 +184,17 @@ which will allow rebooting directly into the serial recovery mode by using: bootmode_set(BOOT_MODE_TYPE_BOOTLOADER); sys_reboot(0); +Retention system modules +************************ + +Modules can expand the functionality of the retention system by using it as a +transport (e.g. between a bootloader and application). + +.. toctree:: + :maxdepth: 1 + + blinfo.rst + API Reference ************* From 3205a5865def538791439e0fd54e0c7964237430 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 27 Sep 2023 09:37:35 +0100 Subject: [PATCH 1206/4498] doc: api: Add blinfo as experimental Adds blinfo as an experimental API Signed-off-by: Jamie McCrae --- doc/develop/api/overview.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 90935584621..8a56b9eae1d 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -37,6 +37,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Experimental - 3.4 + * - :ref:`blinfo_api` + - Experimental + - 3.5 + * - :ref:`bluetooth_api` - Stable - 1.0 From 14fe04dbf3590c4210841ca6a61726f4d58fe834 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 27 Sep 2023 09:38:09 +0100 Subject: [PATCH 1207/4498] doc: release: 3.5: Add note on new blinfo subsystem Adds a note that a new retention module, bootloader information (blinfo) has been added Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 869382ee4cd..351c6f5fd70 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -374,6 +374,10 @@ Libraries / Subsystems operation for SDMMC devices in case when we align buffers on CONFIG_SDHC_BUFFER_ALIGNMENT, because we can avoid extra copy of data from card bffer to read/prog buffer. +* Retention + + * Added the :ref:`blinfo_api` subsystem. + HALs **** From 22ba9456deaa3cbf7c6ec8b3aaa1f8dc057eb407 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 11 Sep 2023 17:10:11 -0700 Subject: [PATCH 1208/4498] tests/kernel/timer/timer_behavior: Add support for external tool This patch adds a way to simplify using an external tool to measure timer behaviour on Zephyr. It modifies the timer behaviour jitter_drift.c tests to toggle a GPIO pin (defined via a new DTS compatible, "test-kernel-timer-behavior-external") that can be connected to an external tool, such as a logic analyzer, to measure timer behaviour. This GPIO pin toggle is behind a new CONFIG_TIMER_EXTERNAL_TEST Kconfig. A new pytest test is added so that it can collect the statistics from the external tool and assert some measurements. To collect statistics from the external tool, one needs to provide a Python module which provides a `run(seconds, config)` method, that will perform the test and return the statistics. Check the README file for more information about this interface. Finally, this on twister, this new test is behind a new fixture, "gpio-timerout". Signed-off-by: Ederson de Souza Signed-off-by: Tom Burdick --- tests/kernel/timer/timer_behavior/Kconfig | 29 +++++++ tests/kernel/timer/timer_behavior/README | 63 +++++++++++++++ .../dts/bindings/timer-behavior-external.yaml | 19 +++++ .../timer/timer_behavior/pytest/conftest.py | 41 ++++++++++ .../timer/timer_behavior/pytest/test_timer.py | 77 +++++++++++++++++++ .../timer/timer_behavior/src/jitter_drift.c | 31 ++++++++ tests/kernel/timer/timer_behavior/src/main.c | 2 + .../kernel/timer/timer_behavior/testcase.yaml | 8 ++ 8 files changed, 270 insertions(+) create mode 100644 tests/kernel/timer/timer_behavior/dts/bindings/timer-behavior-external.yaml create mode 100644 tests/kernel/timer/timer_behavior/pytest/conftest.py create mode 100755 tests/kernel/timer/timer_behavior/pytest/test_timer.py diff --git a/tests/kernel/timer/timer_behavior/Kconfig b/tests/kernel/timer/timer_behavior/Kconfig index b881fdeb741..9e5d80532f1 100644 --- a/tests/kernel/timer/timer_behavior/Kconfig +++ b/tests/kernel/timer/timer_behavior/Kconfig @@ -41,3 +41,32 @@ config TIMER_TEST_PERIOD_MAX_DRIFT_PERCENT default 10 help A value of 10 means 10%. + +config TIMER_EXTERNAL_TEST + bool "Perform test using an external tool" + help + Toggles a GPIO pin, on every period, that can be used by an external + tool (such as a logic analyzer) to gather timing data. A pytest harness + is used to get the data collected by the tool and evaluate it. + +if TIMER_EXTERNAL_TEST + +config TIMER_EXTERNAL_TEST_MAX_DRIFT_PPM + int "Maximum drift in PPM for tests using external tool" + default 4500 + help + Parts Per Million of allowed drift when using an external tool + connected to a GPIO pin is used to measure time behaviour. + +config TIMER_EXTERNAL_TEST_PERIOD_MAX_DRIFT_PPM + int "Maximum timer period drift in PPM for tests using external tool" + default 100000 + help + Parts Per Million of allowed period drift when using an external tool + connected to a GPIO pin is used to measure time behaviour. + +config TIMER_EXTERNAL_TEST_SYNC_DELAY + int "Delay, in seconds, between tests, so that external tool can be ready" + default 3 + +endif # TIMER_EXTERNAL_TEST diff --git a/tests/kernel/timer/timer_behavior/README b/tests/kernel/timer/timer_behavior/README index b94b091049c..17ffc4e6897 100644 --- a/tests/kernel/timer/timer_behavior/README +++ b/tests/kernel/timer/timer_behavior/README @@ -6,3 +6,66 @@ Records and calculates statistical values against a timer validating that. 2. Periodic timers do not drift in either direction from expected total time. Timers are meant to be precise and accurate. This test validates an implementation is both. + +-------------------------------------------------------------------------------- + +External tool testing + +It's also possible to use an external tool, such as a logic analyzer, to +collect samples. The "kernel.timer.timer_behavior_external" test will toggle a +GPIO pin on every cycle - first cycle will be a rising edge. This test expects +a Python module to interface with the external tool, which will provide the +necessary statistics that the test will use to assert the test status. + +GPIO pin + +To enable external tool testing on a board, it must provide the compatible +"test-kernel-timer-behavior-external", with property "timeout-gpios" being the +GPIO pin that will be toggled each period. + +External tool interface + +In order to get data from the external tool, the test expects a Python module, +named on testcase.yaml, with the following interface: + + run(seconds: float, options: str) -> {} + +The `seconds` parameter defines for how long the data collection is expected +to run; `options` is a string defined on testcase.yaml with options known to +the external tool helper module. It should return a dictionary with the +following statistics, in seconds: + + 'mean': Mean time of each period + 'stddev': Standard deviation from the mean time + 'var': Variance from the mean time + 'min': Minimum period registered + 'max': Maximum period registered + 'total_time': Total time, between first and last period. + +Note that the collection may need to go a bit after the "seconds" parameter, +to account for expected drift in the test and between the DUT and the external +tool. + +Twister + +For Twister execute the external tool testing, the fixture "gpio_timerout" +must be available on the device. Also, testcase.yaml +"harness_config/pytest_args" from "kernel.timer.timer_behavior_external" must +have parameters "tool", with the name of a loadable Python module and +"tool-options", a string with options passed to the Python module helper. + +Configuration options + +At its heart, the external testing is actually comparing two clocks: one on +the board under test and one at the external tool (Zephyr implementation of +the timer also plays a role, and it's the real target of the test, but it +depends on the board's clock). Different clocks run at different speeds, so +they tend to drift. To be able to account for this drift, the external test +doesn't reuse CONFIG_TIMER_TEST_MAX_DRIFT and +CONFIG_TIMER_TEST_PERIOD_MAX_DRIFT_PERCENT, instead introducing +CONFIG_TIMER_EXTERNAL_TEST_MAX_DRIFT_PPM and +CONFIG_TIMER_EXTERNAL_TEST_PERIOD_MAX_DRIFT_PPM, that can be more finely tuned +for the hardware in question. + +Also, CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY is used to set a delay before a +test cycle starts, so that the external tool can be set up. diff --git a/tests/kernel/timer/timer_behavior/dts/bindings/timer-behavior-external.yaml b/tests/kernel/timer/timer_behavior/dts/bindings/timer-behavior-external.yaml new file mode 100644 index 00000000000..0809145fe29 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/dts/bindings/timer-behavior-external.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Binding providing resources required to build and run the + tests/kernel/timer/timer_behavior/kernel.timer.timer_behavior_external + test in Zephyr. + +compatible: "test-kernel-timer-behavior-external" + +properties: + timerout-gpios: + type: phandle-array + required: true + description: + GPIO pin that will toggle on each cycle of the test, to be + connected to an external tool (such as a logic analyzer) + that will collect timing information. diff --git a/tests/kernel/timer/timer_behavior/pytest/conftest.py b/tests/kernel/timer/timer_behavior/pytest/conftest.py new file mode 100644 index 00000000000..d9564664b70 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/pytest/conftest.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +import pytest + +from pathlib import Path + +def pytest_addoption(parser): + parser.addoption('--tool') + parser.addoption('--tool-options') + parser.addoption('--sys-clock-hw-cycles-per-sec', default=None) + +@pytest.fixture() +def tool(request): + return request.config.getoption('--tool') + +@pytest.fixture() +def tool_options(request): + return request.config.getoption('--tool-options') + +@pytest.fixture() +def config(request): + build_dir = Path(request.config.getoption('--build-dir')) + file_name = build_dir / 'zephyr' / '.config' + + cfgs = {} + with open(file_name) as fp: + for line in fp: + if line.startswith('CONFIG_'): + k, v = line.split('=', maxsplit=1) + cfgs[k[7:]] = v + + return cfgs + +@pytest.fixture() +def sys_clock_hw_cycles_per_sec(request, config): + if request.config.getoption('--sys-clock-hw-cycles-per-sec'): + return int(request.config.getoption('--sys-clock-hw-cycles-per-sec')) + + return int(config['SYS_CLOCK_HW_CYCLES_PER_SEC']) diff --git a/tests/kernel/timer/timer_behavior/pytest/test_timer.py b/tests/kernel/timer/timer_behavior/pytest/test_timer.py new file mode 100755 index 00000000000..c6dced949c1 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/pytest/test_timer.py @@ -0,0 +1,77 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +import logging + +from math import ceil + +from twister_harness import DeviceAdapter + +logger = logging.getLogger(__name__) + + +def do_analysys(test, stats, config, sys_clock_hw_cycles_per_sec): + logger.info('====================================================') + logger.info(f'periodic timer behaviour using {test} mechanism:') + + test_period = int(config['TIMER_TEST_PERIOD']) + test_samples = int(config['TIMER_TEST_SAMPLES']) + + seconds = (test_period * test_samples) / 1_000_000 + + periods_sec = test_period / 1_000_000 + ticks_per_sec = int(config['SYS_CLOCK_TICKS_PER_SEC']) + periods_tick = ceil(ticks_per_sec * periods_sec) + + expected_period = test_period * sys_clock_hw_cycles_per_sec / 1_000_000 + cyc_per_tick = sys_clock_hw_cycles_per_sec / ticks_per_sec + expected_period_drift = ((periods_tick * cyc_per_tick - expected_period) / + sys_clock_hw_cycles_per_sec * 1_000_000) + expected_total_drift = expected_period_drift * test_samples / 1_000_000 + + period_max_drift = (int(config['TIMER_EXTERNAL_TEST_PERIOD_MAX_DRIFT_PPM']) + / 1_000_000) + min_bound = (test_period - period_max_drift * test_period + + expected_period_drift) / 1_000_000 + max_bound = (test_period + period_max_drift * test_period + + expected_period_drift) / 1_000_000 + + max_stddev = int(config['TIMER_TEST_MAX_STDDEV']) / 1_000_000 + + max_drift_ppm = int(config['TIMER_EXTERNAL_TEST_MAX_DRIFT_PPM']) + time_diff = stats['total_time'] - seconds - expected_total_drift + + logger.info(f'min: {stats["min"] * 1_000_000:.6f} us') + logger.info(f'max: {stats["max"] * 1_000_000:.6f} us') + logger.info(f'mean: {stats["mean"] * 1_000_000:.6f} us') + logger.info(f'variance: {stats["var"] * 1_000_000:.6f} us') + logger.info(f'stddev: {stats["stddev"] * 1_000_000:.6f} us') + logger.info(f'total time: {stats["total_time"] * 1_000_000:.6f} us') + logger.info(f'expected drift: {seconds * max_drift_ppm} us') + logger.info(f'real drift: {time_diff * 1_000_000:.6f} us') + logger.info('====================================================') + + assert stats['stddev'] < max_stddev + assert stats['min'] >= min_bound + assert stats['max'] <= max_bound + assert abs(time_diff) < seconds * max_drift_ppm / 1_000_000 + + +def wait_sync_point(dut: DeviceAdapter, point): + dut.readlines_until(regex=f"===== {point} =====") + + +def test_flash(dut: DeviceAdapter, tool, tool_options, config, + sys_clock_hw_cycles_per_sec): + tool = __import__(tool) + + test_period = int(config['TIMER_TEST_PERIOD']) + test_samples = int(config['TIMER_TEST_SAMPLES']) + seconds = (test_period * test_samples) / 1_000_000 + + tests = ["builtin", "startdelay"] + for test in tests: + wait_sync_point(dut, test) + stats = tool.run(seconds, tool_options) + do_analysys(test, stats, config, sys_clock_hw_cycles_per_sec) diff --git a/tests/kernel/timer/timer_behavior/src/jitter_drift.c b/tests/kernel/timer/timer_behavior/src/jitter_drift.c index cd6afaea00d..666f916a1c9 100644 --- a/tests/kernel/timer/timer_behavior/src/jitter_drift.c +++ b/tests/kernel/timer/timer_behavior/src/jitter_drift.c @@ -9,10 +9,17 @@ #include #include +#include #include #include +#ifdef CONFIG_TIMER_EXTERNAL_TEST +#define TIMER_OUT_NODE DT_INST(0, test_kernel_timer_behavior_external) +static const struct gpio_dt_spec timer_out = GPIO_DT_SPEC_GET(TIMER_OUT_NODE, + timerout_gpios); +#endif + static uint32_t periodic_idx; static uint64_t periodic_data[CONFIG_TIMER_TEST_SAMPLES + 1]; static uint64_t periodic_start, periodic_end; @@ -28,6 +35,10 @@ static void timer_period_fn(struct k_timer *t) { uint64_t curr_cycle; +#ifdef CONFIG_TIMER_EXTERNAL_TEST + gpio_pin_toggle_dt(&timer_out); +#endif + #ifdef CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER curr_cycle = k_cycle_get_64(); #else @@ -62,6 +73,10 @@ static void timer_startdelay_fn(struct k_timer *t) { uint64_t curr_cycle; +#ifdef CONFIG_TIMER_EXTERNAL_TEST + gpio_pin_toggle_dt(&timer_out); +#endif + #ifdef CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER curr_cycle = k_cycle_get_64(); #else @@ -266,12 +281,28 @@ static void do_test_using(void (*sample_collection_fn)(void)) ZTEST(timer_jitter_drift, test_jitter_drift_timer_period) { TC_PRINT("periodic timer behavior test using built-in restart mechanism\n"); +#ifdef CONFIG_TIMER_EXTERNAL_TEST + TC_PRINT("===== External Tool Sync Point =====\n"); + TC_PRINT("===== builtin =====\n"); + TC_PRINT("===== Waiting %d seconds =====\n", + CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY); + k_sleep(K_SECONDS(CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY)); + gpio_pin_configure_dt(&timer_out, GPIO_OUTPUT_LOW); +#endif do_test_using(collect_timer_period_time_samples); } ZTEST(timer_jitter_drift, test_jitter_drift_timer_startdelay) { TC_PRINT("periodic timer behavior test using explicit start with delay\n"); +#ifdef CONFIG_TIMER_EXTERNAL_TEST + TC_PRINT("===== External Tool Sync Point =====\n"); + TC_PRINT("===== startdelay =====\n"); + TC_PRINT("===== Waiting %d seconds =====\n", + CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY); + k_sleep(K_SECONDS(CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY)); + gpio_pin_configure_dt(&timer_out, GPIO_OUTPUT_LOW); +#endif do_test_using(collect_timer_startdelay_time_samples); } diff --git a/tests/kernel/timer/timer_behavior/src/main.c b/tests/kernel/timer/timer_behavior/src/main.c index ac2e68d59c3..f3806198e8a 100644 --- a/tests/kernel/timer/timer_behavior/src/main.c +++ b/tests/kernel/timer/timer_behavior/src/main.c @@ -9,5 +9,7 @@ void test_main(void) { ztest_run_test_suite(timer_jitter_drift); +#ifndef CONFIG_TIMER_EXTERNAL_TEST ztest_run_test_suite(timer_tick_train); +#endif } diff --git a/tests/kernel/timer/timer_behavior/testcase.yaml b/tests/kernel/timer/timer_behavior/testcase.yaml index cb63b66be71..d5df6a35669 100644 --- a/tests/kernel/timer/timer_behavior/testcase.yaml +++ b/tests/kernel/timer/timer_behavior/testcase.yaml @@ -17,3 +17,11 @@ tests: - hifive_unleashed - mps2_an385 - mps2_an521_ns + kernel.timer.timer_behavior_external: + filter: dt_compat_enabled("test-kernel-timer-behavior-external") + harness: pytest + harness_config: + fixture: gpio_timerout + extra_configs: + - CONFIG_TIMER_EXTERNAL_TEST=y + - CONFIG_BOOT_DELAY=5000 From 5c65a60eabf7fc73b42ff51fd5d1d6156f7fa8fa Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 11 Sep 2023 17:24:42 -0700 Subject: [PATCH 1209/4498] tests/kernel/timer/timer_behavior: Add support for Saleae Logic 2 This patch shows an example of how to use the timer behavior external tool testing, using the Saleae Logic 2 application. Also, some board overlays were added as examples. Finally, testcase.yaml updated with parameters for the Saleae sample. Signed-off-by: Ederson de Souza --- tests/kernel/timer/timer_behavior/README | 13 +++ .../boards/esp32s3_devkitm.overlay | 13 +++ .../timer_behavior/boards/frdm_k64f.overlay | 13 +++ .../boards/mec15xxevb_assy6853.overlay | 13 +++ .../pytest/requirements-saleae.txt | 2 + .../timer_behavior/pytest/saleae_logic2.py | 88 +++++++++++++++++++ .../kernel/timer/timer_behavior/testcase.yaml | 2 + 7 files changed, 144 insertions(+) create mode 100644 tests/kernel/timer/timer_behavior/boards/esp32s3_devkitm.overlay create mode 100644 tests/kernel/timer/timer_behavior/boards/frdm_k64f.overlay create mode 100644 tests/kernel/timer/timer_behavior/boards/mec15xxevb_assy6853.overlay create mode 100644 tests/kernel/timer/timer_behavior/pytest/requirements-saleae.txt create mode 100644 tests/kernel/timer/timer_behavior/pytest/saleae_logic2.py diff --git a/tests/kernel/timer/timer_behavior/README b/tests/kernel/timer/timer_behavior/README index 17ffc4e6897..64fc2d37112 100644 --- a/tests/kernel/timer/timer_behavior/README +++ b/tests/kernel/timer/timer_behavior/README @@ -46,6 +46,9 @@ Note that the collection may need to go a bit after the "seconds" parameter, to account for expected drift in the test and between the DUT and the external tool. +One can check `pytest/saleae_logic2.py` file as a sample of external tool +helper module. + Twister For Twister execute the external tool testing, the fixture "gpio_timerout" @@ -54,6 +57,8 @@ must be available on the device. Also, testcase.yaml have parameters "tool", with the name of a loadable Python module and "tool-options", a string with options passed to the Python module helper. +Check testcase.yaml for an example using the saleae_logic2 module. + Configuration options At its heart, the external testing is actually comparing two clocks: one on @@ -69,3 +74,11 @@ for the hardware in question. Also, CONFIG_TIMER_EXTERNAL_TEST_SYNC_DELAY is used to set a delay before a test cycle starts, so that the external tool can be set up. + +Dependencies + +The external tool interface may have its own dependencies. For instance, +the saleae_logic2 module ones are listed at pytest/requirements-saleae.txt. +One can install them with pip (possibly in some virtual environment): + + pip install -r pytest/requirements-saleae.txt diff --git a/tests/kernel/timer/timer_behavior/boards/esp32s3_devkitm.overlay b/tests/kernel/timer/timer_behavior/boards/esp32s3_devkitm.overlay new file mode 100644 index 00000000000..e8bc477d394 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/boards/esp32s3_devkitm.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-kernel-timer-behavior-external"; + + timerout-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/tests/kernel/timer/timer_behavior/boards/frdm_k64f.overlay b/tests/kernel/timer/timer_behavior/boards/frdm_k64f.overlay new file mode 100644 index 00000000000..c72edf876d8 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/boards/frdm_k64f.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-kernel-timer-behavior-external"; + + timerout-gpios = <&gpioc 3 GPIO_ACTIVE_LOW>; /* Arduino D7 */ + }; +}; diff --git a/tests/kernel/timer/timer_behavior/boards/mec15xxevb_assy6853.overlay b/tests/kernel/timer/timer_behavior/boards/mec15xxevb_assy6853.overlay new file mode 100644 index 00000000000..25c39b6c390 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/boards/mec15xxevb_assy6853.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-kernel-timer-behavior-external"; + + timerout-gpios = <&gpio_140_176 14 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/tests/kernel/timer/timer_behavior/pytest/requirements-saleae.txt b/tests/kernel/timer/timer_behavior/pytest/requirements-saleae.txt new file mode 100644 index 00000000000..1a5dc09125b --- /dev/null +++ b/tests/kernel/timer/timer_behavior/pytest/requirements-saleae.txt @@ -0,0 +1,2 @@ +numpy +logic2-automation diff --git a/tests/kernel/timer/timer_behavior/pytest/saleae_logic2.py b/tests/kernel/timer/timer_behavior/pytest/saleae_logic2.py new file mode 100644 index 00000000000..7ec141dabd3 --- /dev/null +++ b/tests/kernel/timer/timer_behavior/pytest/saleae_logic2.py @@ -0,0 +1,88 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# Sample code showing an external tool Python module helper for Saleae Logic 2 +# compatible logic analyzer. +# To use it, the Saleae Logic 2 Automation server must be enabled. For more +# information on it, check +# https://saleae.github.io/logic2-automation/getting_started.html + +import numpy as np +import tempfile + +from pathlib import Path +from saleae import automation +from saleae.automation import (CaptureConfiguration, LogicDeviceConfiguration, +DigitalTriggerCaptureMode, DigitalTriggerType) + +def do_collection(device_id, port, channel, sample_rate, threshold_volts, + seconds, output_dir): + with automation.Manager.connect(port=port) as manager: + + device_configuration = LogicDeviceConfiguration( + enabled_digital_channels=[channel], + digital_sample_rate=sample_rate, + digital_threshold_volts=threshold_volts, + ) + + capture_mode = DigitalTriggerCaptureMode(DigitalTriggerType.RISING, + channel, + after_trigger_seconds=seconds) + capture_configuration = CaptureConfiguration(capture_mode=capture_mode) + + with manager.start_capture( + device_id=device_id, + device_configuration=device_configuration, + capture_configuration=capture_configuration) as capture: + + capture.wait() + + capture.export_raw_data_csv(directory=output_dir, + digital_channels=[channel]) + +def do_analysis(output_dir): + file_name = Path(output_dir) / 'digital.csv' + all_data = np.loadtxt(file_name, delimiter=',', skiprows=1, usecols=0) + + # Pre trigger data is negative on CSV + non_negative = all_data[all_data >= 0] + + # Last sample is just captured at last moment of capture, not related + # to gpio toggle. Discard it + data = non_negative[:-1] + + diff = np.diff(data) + + mean = np.mean(diff) + std = np.std(diff) + var = np.var(diff) + minimum = np.min(diff) + maximum = np.max(diff) + total_time = data[-1] + + return {'mean': mean, 'stddev': std, 'var': var, 'min': minimum, + 'max': maximum, 'total_time': total_time} + + +# options should be a string of the format: +# [device-id=,]port=, +# channel=,sample-rate=, +# threshold-volts= +def run(seconds, options): + options = [i for p in options.split(',') for i in p.split('=')] + options = dict(zip(options[::2], options[1::2])) + + device_id = options.get('device-id') + port = int(options.get('port')) + channel = int(options.get('channel')) + sample_rate = int(options.get('sample-rate')) + threshold_volts = float(options.get('threshold-volts')) + + with tempfile.TemporaryDirectory() as output_dir: + output_dir = tempfile.mkdtemp() + # Add one second to ensure all data is captured + do_collection(device_id, port, channel, sample_rate, threshold_volts, + seconds + 1, output_dir) + + return do_analysis(output_dir) diff --git a/tests/kernel/timer/timer_behavior/testcase.yaml b/tests/kernel/timer/timer_behavior/testcase.yaml index d5df6a35669..cf761006b73 100644 --- a/tests/kernel/timer/timer_behavior/testcase.yaml +++ b/tests/kernel/timer/timer_behavior/testcase.yaml @@ -21,6 +21,8 @@ tests: filter: dt_compat_enabled("test-kernel-timer-behavior-external") harness: pytest harness_config: + pytest_args: ['--tool', 'saleae_logic2', '--tool-options', + 'port=10430,channel=1,sample-rate=6_250_000,threshold-volts=3.3'] fixture: gpio_timerout extra_configs: - CONFIG_TIMER_EXTERNAL_TEST=y From 1c0178ae6e00cc0a4744f6217c24c6cfb84cff69 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 13 Sep 2023 12:42:01 -0700 Subject: [PATCH 1210/4498] boards: xtensa: rename qemu_xtensa_dc233c to qemu_xtensa_mmu This renames the board from qemu_xtensa_dc233c to qemu_xtensa_mmu to better signal that it is for testing with MMU on QEMU Xtensa. Also turn on testing by default to make sure future changes will not break Xtensa MMU support. Signed-off-by: Daniel Leung --- boards/xtensa/qemu_xtensa/Kconfig.board | 5 +++-- boards/xtensa/qemu_xtensa/Kconfig.defconfig | 4 ++-- boards/xtensa/qemu_xtensa/board.cmake | 2 +- .../{qemu_xtensa_dc233c.dts => qemu_xtensa_mmu.dts} | 2 +- .../{qemu_xtensa_dc233c.yaml => qemu_xtensa_mmu.yaml} | 6 ++++-- ...mu_xtensa_dc233c_defconfig => qemu_xtensa_mmu_defconfig} | 2 +- soc/xtensa/dc233c/Kconfig.soc | 1 - 7 files changed, 12 insertions(+), 10 deletions(-) rename boards/xtensa/qemu_xtensa/{qemu_xtensa_dc233c.dts => qemu_xtensa_mmu.dts} (89%) rename boards/xtensa/qemu_xtensa/{qemu_xtensa_dc233c.yaml => qemu_xtensa_mmu.yaml} (54%) rename boards/xtensa/qemu_xtensa/{qemu_xtensa_dc233c_defconfig => qemu_xtensa_mmu_defconfig} (89%) diff --git a/boards/xtensa/qemu_xtensa/Kconfig.board b/boards/xtensa/qemu_xtensa/Kconfig.board index 43a0b1ce76e..8c517c88dc0 100644 --- a/boards/xtensa/qemu_xtensa/Kconfig.board +++ b/boards/xtensa/qemu_xtensa/Kconfig.board @@ -8,7 +8,8 @@ config BOARD_QEMU_XTENSA depends on SOC_XTENSA_SAMPLE_CONTROLLER select QEMU_TARGET -config BOARD_QEMU_XTENSA_DC233C - bool "Xtensa emulation using QEMU (dc233c core)" +config BOARD_QEMU_XTENSA_MMU + bool "Xtensa emulation using QEMU with MMU" depends on SOC_XTENSA_DC233C select QEMU_TARGET + select XTENSA_MMU diff --git a/boards/xtensa/qemu_xtensa/Kconfig.defconfig b/boards/xtensa/qemu_xtensa/Kconfig.defconfig index fdd0daec484..a6beed9151c 100644 --- a/boards/xtensa/qemu_xtensa/Kconfig.defconfig +++ b/boards/xtensa/qemu_xtensa/Kconfig.defconfig @@ -14,13 +14,13 @@ config IPM_CONSOLE_STACK_SIZE endif # BOARD_QEMU_XTENSA -if BOARD_QEMU_XTENSA_DC233C +if BOARD_QEMU_XTENSA_MMU config BUILD_OUTPUT_BIN default n config BOARD - default "qemu_xtensa_dc233c" + default "qemu_xtensa_mmu" config IPM_CONSOLE_STACK_SIZE default 2048 if IPM_CONSOLE_RECEIVER diff --git a/boards/xtensa/qemu_xtensa/board.cmake b/boards/xtensa/qemu_xtensa/board.cmake index 0dc60dfc7f4..7d6997c702c 100644 --- a/boards/xtensa/qemu_xtensa/board.cmake +++ b/boards/xtensa/qemu_xtensa/board.cmake @@ -8,7 +8,7 @@ if(CONFIG_BOARD_QEMU_XTENSA) set(QEMU_FLAGS_${ARCH} -machine sim -semihosting -nographic -cpu sample_controller ) -elseif(CONFIG_BOARD_QEMU_XTENSA_DC233C) +elseif(CONFIG_BOARD_QEMU_XTENSA_MMU) set(QEMU_CPU_TYPE_${ARCH} dc233c) set(QEMU_FLAGS_${ARCH} diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.dts b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.dts similarity index 89% rename from boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.dts rename to boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.dts index 1af6545d8bc..8ed0eb6dbdb 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.dts +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.dts @@ -9,7 +9,7 @@ #include "dc233c.dtsi" / { - model = "qemu_xtensa_dc233c"; + model = "qemu_xtensa_mmu"; compatible = "cdns,xtensa-dc233c"; chosen { diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.yaml b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.yaml similarity index 54% rename from boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.yaml rename to boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.yaml index 9a0b11a955e..aa2ef7692d4 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c.yaml +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu.yaml @@ -1,11 +1,13 @@ -identifier: qemu_xtensa_dc233c -name: QEMU Emulation for Xtensa (dc233c core) +identifier: qemu_xtensa_mmu +name: QEMU Emulation for Xtensa with MMU type: qemu simulation: qemu arch: xtensa toolchain: + - zephyr - xtools testing: + default: true ignore_tags: - net - bluetooth diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c_defconfig b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu_defconfig similarity index 89% rename from boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c_defconfig rename to boards/xtensa/qemu_xtensa/qemu_xtensa_mmu_defconfig index 9be7283e74e..6587737bd88 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa_dc233c_defconfig +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa_mmu_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_BOARD_QEMU_XTENSA_DC233C=y +CONFIG_BOARD_QEMU_XTENSA_MMU=y CONFIG_CONSOLE=y CONFIG_SOC_XTENSA_DC233C=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000 diff --git a/soc/xtensa/dc233c/Kconfig.soc b/soc/xtensa/dc233c/Kconfig.soc index cf846b82839..89b814da4d2 100644 --- a/soc/xtensa/dc233c/Kconfig.soc +++ b/soc/xtensa/dc233c/Kconfig.soc @@ -8,5 +8,4 @@ config SOC_XTENSA_DC233C select XTENSA_HAL select ARCH_HAS_THREAD_LOCAL_STORAGE select CPU_HAS_MMU - imply XTENSA_MMU select ARCH_HAS_RESERVED_PAGE_FRAMES if XTENSA_MMU From b4da11f92967256e6a451f519c739ec95ea6175d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 14 Sep 2023 13:17:05 -0700 Subject: [PATCH 1211/4498] gdbstub: xtensa: add support for dc233c core This adds support for using coredump with Xtensa DC233C core, which are being used by qemu_xtensa and qemu_xtensa_mmu. Signed-off-by: Daniel Leung --- arch/xtensa/core/coredump.c | 3 ++ scripts/coredump/gdbstubs/arch/xtensa.py | 38 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/arch/xtensa/core/coredump.c b/arch/xtensa/core/coredump.c index 8f15ca39c58..26060dea8c3 100644 --- a/arch/xtensa/core/coredump.c +++ b/arch/xtensa/core/coredump.c @@ -19,6 +19,7 @@ enum xtensa_soc_code { XTENSA_SOC_INTEL_ADSP, XTENSA_SOC_ESP32S2, XTENSA_SOC_ESP32S3, + XTENSA_SOC_DC233C, }; struct xtensa_arch_block { @@ -117,6 +118,8 @@ void arch_coredump_info_dump(const z_arch_esf_t *esf) arch_blk.soc = XTENSA_SOC_ESP32S2; #elif CONFIG_SOC_SERIES_ESP32S3 arch_blk.soc = XTENSA_SOC_ESP32S3; + #elif CONFIG_SOC_XTENSA_DC233C + arch_blk.soc = XTENSA_SOC_DC233C; #else arch_blk.soc = XTENSA_SOC_UNKNOWN; #endif diff --git a/scripts/coredump/gdbstubs/arch/xtensa.py b/scripts/coredump/gdbstubs/arch/xtensa.py index dfc2f48453e..fbe572ac16b 100644 --- a/scripts/coredump/gdbstubs/arch/xtensa.py +++ b/scripts/coredump/gdbstubs/arch/xtensa.py @@ -25,6 +25,7 @@ class XtensaSoc(Enum): INTEL_ADSP_CAVS = 3 ESP32S2 = 4 ESP32S3 = 5 + DC233C = 6 # The previous version of this script didn't need to know @@ -68,6 +69,8 @@ def get_gdb_reg_definition(soc, toolchain): return GdbRegDef_ESP32S2 elif soc == XtensaSoc.ESP32S3: return GdbRegDef_ESP32S3 + elif soc == XtensaSoc.DC233C: + return GdbRegDef_DC233C else: raise NotImplementedError @@ -476,3 +479,38 @@ class RegNum(Enum): LCOUNT = 514 WINDOWBASE = 584 WINDOWSTART = 585 + +# sdk-ng -> overlays/xtensa_dc233c/gdb/gdb/xtensa-config.c +class GdbRegDef_DC233C: + ARCH_DATA_BLK_STRUCT_REGS = ' Date: Fri, 15 Sep 2023 10:57:38 +0200 Subject: [PATCH 1212/4498] Bluetooth: Test: SC Indication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test that SC Indication is correctly sent when the client reconnect and the server updated the GATT database since last connection. Test that the indication is sent even if the bond is not restored. Signed-off-by: Théo Battrel --- tests/bsim/bluetooth/host/compile.sh | 1 + .../host/gatt/sc_indicate/CMakeLists.txt | 25 +++ .../bluetooth/host/gatt/sc_indicate/prj.conf | 20 ++ .../host/gatt/sc_indicate/src/bs_bt_utils.c | 182 ++++++++++++++++ .../host/gatt/sc_indicate/src/bs_bt_utils.h | 67 ++++++ .../host/gatt/sc_indicate/src/central.c | 195 ++++++++++++++++++ .../host/gatt/sc_indicate/src/main.c | 58 ++++++ .../host/gatt/sc_indicate/src/peripheral.c | 86 ++++++++ .../gatt/sc_indicate/test_scripts/_compile.sh | 18 ++ .../sc_indicate/test_scripts/sc_indicate.sh | 24 +++ 10 files changed, 676 insertions(+) create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c create mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c create mode 100755 tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 266fa88ab2f..042849587bc 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -44,6 +44,7 @@ app=tests/bsim/bluetooth/host/gatt/settings compile app=tests/bsim/bluetooth/host/gatt/settings conf_file=prj_2.conf compile app=tests/bsim/bluetooth/host/gatt/ccc_store compile app=tests/bsim/bluetooth/host/gatt/ccc_store conf_file=prj_2.conf compile +app=tests/bsim/bluetooth/host/gatt/sc_indicate compile app=tests/bsim/bluetooth/host/l2cap/general compile app=tests/bsim/bluetooth/host/l2cap/userdata compile diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt b/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt new file mode 100644 index 00000000000..d734b3c054e --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +if (NOT DEFINED ENV{BSIM_COMPONENTS_PATH}) + message(FATAL_ERROR "This test requires the BabbleSim simulator. Please set \ + the environment variable BSIM_COMPONENTS_PATH to point to its \ + components folder. More information can be found in \ + https://babblesim.github.io/folder_structure_and_env.html") +endif() + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_auto_seq_req) + +target_sources(app PRIVATE + src/main.c + src/central.c + src/peripheral.c + src/bs_bt_utils.c +) + +zephyr_include_directories( + $ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/ + $ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf b/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf new file mode 100644 index 00000000000..7edaf36d10e --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf @@ -0,0 +1,20 @@ +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="SC Indication Test" + +CONFIG_LOG=y +CONFIG_BT_EXT_ADV=y + +CONFIG_BT_SMP=y +CONFIG_BT_GATT_CLIENT=y + +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_NVS=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS_NVS=y + +CONFIG_BT_GATT_DYNAMIC_DB=y diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c new file mode 100644 index 00000000000..31952cbe330 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(test_utils, LOG_LEVEL_DBG); + +#include "bs_bt_utils.h" + +struct bt_conn *g_conn; +DEFINE_FLAG(flag_is_connected); + +void wait_connected(void) +{ + LOG_DBG("Wait for connection..."); + WAIT_FOR_FLAG(flag_is_connected); +} + +void wait_disconnected(void) +{ + LOG_DBG("Wait for disconnection..."); + WAIT_FOR_FLAG_UNSET(flag_is_connected); +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + LOG_DBG("security changed"); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + UNSET_FLAG(flag_is_connected); +} + +struct bt_conn *get_g_conn(void) +{ + return g_conn; +} + +void clear_g_conn(void) +{ + struct bt_conn *conn; + + conn = g_conn; + g_conn = NULL; + BSIM_ASSERT(conn, "Test error: no g_conn!\n"); + bt_conn_unref(conn); +} + +static void connected(struct bt_conn *conn, uint8_t err) +{ + BSIM_ASSERT((!g_conn || (conn == g_conn)), "Unexpected new connection."); + + if (!g_conn) { + g_conn = bt_conn_ref(conn); + } + + if (err != 0) { + clear_g_conn(); + return; + } + + SET_FLAG(flag_is_connected); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, + .security_changed = security_changed, +}; + +static void stop_scan_and_connect(const bt_addr_le_t *addr, + int8_t rssi, + uint8_t type, + struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + int err; + + if (g_conn != NULL) { + return; + } + + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Got scan result, connecting.. dst %s, RSSI %d\n", addr_str, rssi); + + err = bt_le_scan_stop(); + BSIM_ASSERT(!err, "Err bt_le_scan_stop %d", err); + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn); + BSIM_ASSERT(!err, "Err bt_conn_le_create %d", err); +} + +void scan_connect_to_first_result(void) +{ + int err; + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, stop_scan_and_connect); + BSIM_ASSERT(!err, "Err bt_le_scan_start %d", err); +} + +void disconnect(void) +{ + int err; + + err = bt_conn_disconnect(g_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + BSIM_ASSERT(!err, "bt_conn_disconnect failed (%d)\n", err); +} + +void set_security(bt_security_t sec) +{ + int err; + + err = bt_conn_set_security(g_conn, sec); + BSIM_ASSERT(!err, "Err bt_conn_set_security %d", err); +} + +void create_adv(struct bt_le_ext_adv **adv) +{ + int err; + struct bt_le_adv_param params = {}; + + params.options |= BT_LE_ADV_OPT_CONNECTABLE; + params.options |= BT_LE_ADV_OPT_EXT_ADV; + + params.id = BT_ID_DEFAULT; + params.sid = 0; + params.interval_min = BT_GAP_ADV_FAST_INT_MIN_2; + params.interval_max = BT_GAP_ADV_FAST_INT_MAX_2; + + err = bt_le_ext_adv_create(¶ms, NULL, adv); + BSIM_ASSERT(!err, "bt_le_ext_adv_create failed (%d)\n", err); +} + +void start_adv(struct bt_le_ext_adv *adv) +{ + int err; + + err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + BSIM_ASSERT(!err, "bt_le_ext_adv_start failed (%d)\n", err); +} + +void stop_adv(struct bt_le_ext_adv *adv) +{ + int err; + + err = bt_le_ext_adv_stop(adv); + BSIM_ASSERT(!err, "bt_le_ext_adv_stop failed (%d)\n", err); +} + +/* The following flags are raised by events and lowered by test code. */ +DEFINE_FLAG(flag_pairing_complete); +DEFINE_FLAG(flag_bonded); +DEFINE_FLAG(flag_not_bonded); + +void pairing_complete(struct bt_conn *conn, bool bonded) +{ + LOG_DBG("pairing complete"); + SET_FLAG(flag_pairing_complete); + + if (bonded) { + SET_FLAG(flag_bonded); + LOG_DBG("Bonded status: true"); + } else { + SET_FLAG(flag_not_bonded); + LOG_DBG("Bonded status: false"); + } +} + +void pairing_failed(struct bt_conn *conn, enum bt_security_err err) +{ + FAIL("Pairing failed\n"); +} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h new file mode 100644 index 00000000000..5ec34005e9f --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" +#include "bs_tracing.h" + +#include +#include + +extern enum bst_result_t bst_result; + +#define DECLARE_FLAG(flag) extern atomic_t flag +#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG_UNSET(flag) \ + while ((bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define TAKE_FLAG(flag) \ + while (!(bool)atomic_cas(&flag, true, false)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define GET_FLAG(flag) (bool)atomic_get(&flag) + +#define BSIM_ASSERT(expr, ...) \ + do { \ + if (!(expr)) { \ + FAIL(__VA_ARGS__); \ + } \ + } while (0) + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +DECLARE_FLAG(flag_pairing_complete); +DECLARE_FLAG(flag_bonded); +DECLARE_FLAG(flag_not_bonded); + +void scan_connect_to_first_result(void); +struct bt_conn *get_g_conn(void); +void clear_g_conn(void); +void disconnect(void); +void wait_connected(void); +void wait_disconnected(void); +void create_adv(struct bt_le_ext_adv **adv); +void start_adv(struct bt_le_ext_adv *adv); +void stop_adv(struct bt_le_ext_adv *adv); +void set_security(bt_security_t sec); +void pairing_complete(struct bt_conn *conn, bool bonded); +void pairing_failed(struct bt_conn *conn, enum bt_security_err err); diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c new file mode 100644 index 00000000000..ca45874e9cb --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c @@ -0,0 +1,195 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(test_central, LOG_LEVEL_DBG); + +#include "bs_bt_utils.h" + +DEFINE_FLAG(flag_discovered); +DEFINE_FLAG(flag_subscribed); +DEFINE_FLAG(flag_indicated); + +enum GATT_HANDLES { + SC, + CCC, + NUM_HANDLES, +}; + +static uint16_t gatt_handles[NUM_HANDLES] = {0}; + +static struct bt_gatt_subscribe_params subscribe_params; + +static void sc_subscribed(struct bt_conn *conn, + uint8_t err, + struct bt_gatt_subscribe_params *params) +{ + LOG_DBG("subscribed"); + SET_FLAG(flag_subscribed); +} + +static uint8_t sc_indicated(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params, + const void *data, + uint16_t length) +{ + LOG_DBG("indication received"); + + SET_FLAG(flag_indicated); + + return BT_GATT_ITER_CONTINUE; +} + +static void subscribe(void) +{ + int err; + + subscribe_params.ccc_handle = gatt_handles[CCC]; + subscribe_params.value_handle = gatt_handles[SC]; + subscribe_params.value = BT_GATT_CCC_INDICATE; + subscribe_params.subscribe = sc_subscribed; + subscribe_params.notify = sc_indicated; + + err = bt_gatt_subscribe(get_g_conn(), &subscribe_params); + BSIM_ASSERT(!err, "bt_gatt_subscribe failed (%d)\n", err); + + WAIT_FOR_FLAG(flag_subscribed); +} + +static uint8_t discover_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + if (attr == NULL) { + for (size_t i = 0U; i < ARRAY_SIZE(gatt_handles); i++) { + LOG_DBG("handle[%d] = 0x%x", i, gatt_handles[i]); + BSIM_ASSERT(gatt_handles[i] != 0, "did not find all handles\n"); + } + + (void)memset(params, 0, sizeof(*params)); + SET_FLAG(flag_discovered); + + return BT_GATT_ITER_STOP; + } + + if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) { + const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + static const struct bt_uuid_16 ccc_uuid = BT_UUID_INIT_16(BT_UUID_GATT_CCC_VAL); + + if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_SC) == 0) { + int err; + + LOG_DBG("found sc"); + gatt_handles[SC] = chrc->value_handle; + + params->uuid = &ccc_uuid.uuid; + params->start_handle = attr->handle + 2; + params->type = BT_GATT_DISCOVER_DESCRIPTOR; + + err = bt_gatt_discover(conn, params); + BSIM_ASSERT(!err, "bt_gatt_discover failed (%d)\n", err); + + return BT_GATT_ITER_STOP; + } + + } else if (params->type == BT_GATT_DISCOVER_DESCRIPTOR && + bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC) == 0) { + LOG_DBG("found ccc"); + gatt_handles[CCC] = attr->handle; + SET_FLAG(flag_discovered); + + return BT_GATT_ITER_STOP; + } + + return BT_GATT_ITER_CONTINUE; +} + +static void gatt_discover(void) +{ + int err; + static struct bt_gatt_discover_params discover_params; + + discover_params.uuid = NULL; + discover_params.func = discover_func; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + + err = bt_gatt_discover(get_g_conn(), &discover_params); + BSIM_ASSERT(!err, "bt_gatt_discover failed (%d)\n", err); + + WAIT_FOR_FLAG(flag_discovered); + + LOG_DBG("sc handle: %d", gatt_handles[SC]); + LOG_DBG("ccc handle: %d", gatt_handles[CCC]); +} + +void central(void) +{ + /* + * test goal: check that service changed indication is sent on + * reconnection when the server's GATT database has been updated since + * last connection + * + * the central will connect, bond with the peripheral and then + * disconnect after doing that, the central will try to connect again, + * this time it will not elevate the security + * + * to pass the test, the central will wait to receive the service + * changed indication + */ + + int err; + struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { + .pairing_failed = pairing_failed, + .pairing_complete = pairing_complete, + }; + + err = bt_enable(NULL); + BSIM_ASSERT(!err, "bt_enable failed (%d)\n", err); + + err = bt_conn_auth_info_cb_register(&bt_conn_auth_info_cb); + BSIM_ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); + + err = settings_load(); + BSIM_ASSERT(!err, "settings_load failed (%d)\n", err); + + scan_connect_to_first_result(); + wait_connected(); + + set_security(BT_SECURITY_L2); + + TAKE_FLAG(flag_pairing_complete); + TAKE_FLAG(flag_bonded); + + /* subscribe to the service changed indication */ + gatt_discover(); + subscribe(); + + disconnect(); + wait_disconnected(); + clear_g_conn(); + + scan_connect_to_first_result(); + wait_connected(); + + /* wait for service change indication */ + WAIT_FOR_FLAG(flag_indicated); + + PASS("PASS\n"); +} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c new file mode 100644 index 00000000000..f5ffbbc4677 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" +#include "bs_bt_utils.h" + +#define BS_SECONDS_TO_US(dur_sec) ((bs_time_t)dur_sec * USEC_PER_SEC) +#define TEST_TIMEOUT_SIMULATED BS_SECONDS_TO_US(60) + +extern void central(void); +extern void peripheral(void); + +static void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +static void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "central", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = central, + }, + { + .test_id = "peripheral", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = peripheral, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c new file mode 100644 index 00000000000..e15c00b60d7 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(test_peripheral, LOG_LEVEL_DBG); + +#include "bs_bt_utils.h" + +#define UUID_1 BT_UUID_DECLARE_128(0xdb, 0x1f, 0xe2, 0x52, 0xf3, 0xc6, 0x43, 0x66, \ + 0xb3, 0x92, 0x5d, 0xc6, 0xe7, 0xc9, 0x59, 0x9d) +#define UUID_2 BT_UUID_DECLARE_128(0x3f, 0xa4, 0x7f, 0x44, 0x2e, 0x2a, 0x43, 0x05, \ + 0xab, 0x38, 0x07, 0x8d, 0x16, 0xbf, 0x99, 0xf1) + +static void new_svc_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) +{ + ARG_UNUSED(attr); + + bool notif_enabled = (value == BT_GATT_CCC_NOTIFY); + + LOG_DBG("CCC Update: notification %s", notif_enabled ? "enabled" : "disabled"); +} + +static struct bt_gatt_attr attrs[] = { + BT_GATT_PRIMARY_SERVICE(UUID_1), + BT_GATT_CHARACTERISTIC(UUID_2, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, NULL, NULL, NULL), + BT_GATT_CCC(new_svc_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +}; + +static struct bt_gatt_service svc = { + .attrs = attrs, + .attr_count = ARRAY_SIZE(attrs), +}; + +void peripheral(void) +{ + /* + * test goal: check that service changed indication is sent on + * reconnection when the server's GATT database has been updated since + * last connection + * + * the peripheral will wait for connection/disconnection, when + * disconnected it will register a new service, when reconnecting, the + * central should receive an indication + */ + + int err; + struct bt_le_ext_adv *adv = NULL; + + err = bt_enable(NULL); + BSIM_ASSERT(!err, "bt_enable failed (%d)\n", err); + + err = settings_load(); + BSIM_ASSERT(!err, "settings_load failed (%d)\n", err); + + create_adv(&adv); + start_adv(adv); + wait_connected(); + + stop_adv(adv); + + wait_disconnected(); + clear_g_conn(); + + /* add a new service to trigger the service changed indication */ + err = bt_gatt_service_register(&svc); + BSIM_ASSERT(!err, "bt_gatt_service_register failed (%d)\n", err); + LOG_DBG("New service added"); + + start_adv(adv); + wait_connected(); + + PASS("Done\n"); +} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh new file mode 100755 index 00000000000..b07577a9878 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh @@ -0,0 +1,18 @@ +#!/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu + +# Terminate running simulations (if any) +${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh + +test_name='sc_indicate' + +: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" +bsim_bin="${BSIM_OUT_PATH}/bin" +BOARD="${BOARD:-nrf52_bsim}" +test_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_gatt_${test_name}_prj_conf" + +west build -b nrf52_bsim -d build && \ + cp -v build/zephyr/zephyr.exe "${test_exe}" diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh new file mode 100755 index 00000000000..b46ae13929c --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh @@ -0,0 +1,24 @@ +#!/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_name='sc_indicate' +test_exe="bs_${BOARD}_tests_bsim_bluetooth_host_gatt_${test_name}_prj_conf" +simulation_id="${test_name}" +verbosity_level=2 +EXECUTE_TIMEOUT=30 + +cd ${BSIM_OUT_PATH}/bin + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=60e6 + +wait_for_background_jobs From c2b99c0123b4bbb8e70843604e855c5e8fd0211c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Mon, 18 Sep 2023 13:59:45 +0200 Subject: [PATCH 1213/4498] Revert "Bluetooth: Host: Fix GATT server handling of CCC" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit cfd368fef1b72e9468626ee03ed1992ceb1e8965. Signed-off-by: Théo Battrel --- include/zephyr/bluetooth/gatt.h | 5 ---- subsys/bluetooth/host/gatt.c | 43 ++++++--------------------------- 2 files changed, 7 insertions(+), 41 deletions(-) diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 4826e93e6fd..7d4ac72495b 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -736,11 +736,6 @@ struct bt_gatt_ccc_cfg { uint8_t id; /** Remote peer address. */ bt_addr_le_t peer; - /** - * Separate storage for encrypted and unencrypted context. This - * indicate that the link was encrypted when the CCC was written. - */ - bool link_encrypted; /** Configuration value. */ uint16_t value; }; diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index b75517c4cb6..069082ec67b 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -1318,7 +1318,6 @@ static void clear_ccc_cfg(struct bt_gatt_ccc_cfg *cfg) bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY); cfg->id = 0U; cfg->value = 0U; - cfg->link_encrypted = false; } static void gatt_store_ccc_cf(uint8_t id, const bt_addr_le_t *peer_addr); @@ -2050,34 +2049,6 @@ struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr) return next; } -static bool bt_gatt_ccc_cfg_is_matching_conn(const struct bt_conn *conn, - const struct bt_gatt_ccc_cfg *cfg) -{ - bool conn_encrypted = bt_conn_get_security(conn) >= BT_SECURITY_L2; - - if (cfg->link_encrypted && !conn_encrypted) { - return false; - } - - return bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer); -} - -static struct bt_conn *bt_gatt_ccc_cfg_conn_lookup(const struct bt_gatt_ccc_cfg *cfg) -{ - struct bt_conn *conn; - - conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer); - if (conn) { - if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { - return conn; - } - - bt_conn_unref(conn); - } - - return NULL; -} - static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn, struct _bt_gatt_ccc *ccc) { @@ -2085,7 +2056,8 @@ static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn, struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; if (conn) { - if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { + if (bt_conn_is_peer_addr_le(conn, cfg->id, + &cfg->peer)) { return cfg; } } else if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) { @@ -2179,7 +2151,6 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, bt_addr_le_copy(&cfg->peer, &conn->le.dst); cfg->id = conn->id; - cfg->link_encrypted = (bt_conn_get_security(conn) >= BT_SECURITY_L2); } /* Confirm write if cfg is managed by application */ @@ -3259,7 +3230,8 @@ static uint8_t update_ccc(const struct bt_gatt_attr *attr, uint16_t handle, struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; /* Ignore configuration for different peer or not active */ - if (!cfg->value || !bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { + if (!cfg->value || + !bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) { continue; } @@ -3333,11 +3305,11 @@ static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, uint16_t handle, continue; } - if (!bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { + if (!bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) { struct bt_conn *tmp; /* Skip if there is another peer connected */ - tmp = bt_gatt_ccc_cfg_conn_lookup(cfg); + tmp = bt_conn_lookup_addr_le(cfg->id, &cfg->peer); if (tmp) { if (tmp->state == BT_CONN_CONNECTED) { value_used = true; @@ -3427,7 +3399,7 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn, for (size_t i = 0; i < BT_GATT_CCC_MAX; i++) { const struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; - if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg) && + if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer) && (ccc_type & ccc->cfg[i].value)) { return true; } @@ -5581,7 +5553,6 @@ static uint8_t ccc_load(const struct bt_gatt_attr *attr, uint16_t handle, } bt_addr_le_copy(&cfg->peer, load->addr_with_id.addr); cfg->id = load->addr_with_id.id; - cfg->link_encrypted = true; } cfg->value = load->entry->value; From 2e13802a38469d5cb9a7fbbca8c029a9ce9e9f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Fri, 22 Sep 2023 13:16:37 +0200 Subject: [PATCH 1214/4498] Bluetooth: Test: Update `security/ccc_update` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous commit reverted the `link_encrypted` filed of CCC config. Update the test to match the new expected behavior. Signed-off-by: Théo Battrel --- .../host/security/ccc_update/src/central.c | 9 ++---- .../host/security/ccc_update/src/peripheral.c | 28 ++++++++++++------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/tests/bsim/bluetooth/host/security/ccc_update/src/central.c b/tests/bsim/bluetooth/host/security/ccc_update/src/central.c index fbdf7ee0108..8f2d2c17dd4 100644 --- a/tests/bsim/bluetooth/host/security/ccc_update/src/central.c +++ b/tests/bsim/bluetooth/host/security/ccc_update/src/central.c @@ -248,7 +248,7 @@ static void connect_unsubscribe(void) backchannel_sync_wait(SERVER_CLIENT_CHAN, SERVER_ID); } -static void connect_restore_sec_unsubscribe(void) +static void connect_restore_sec(void) { int err; @@ -270,10 +270,7 @@ static void connect_restore_sec_unsubscribe(void) /* wait for server to check that the subscribtion has been restored */ backchannel_sync_wait(SERVER_CLIENT_CHAN, SERVER_ID); - /* send unsubscribtion request */ - ccc_unsubscribe(); - - /* wait for server to check that the unsubscribtion has been well registered */ + /* wait for server to check that the subscription no longer exist */ backchannel_sync_send(SERVER_CLIENT_CHAN, SERVER_ID); } @@ -347,7 +344,7 @@ void run_central(void) backchannel_sync_send(CLIENT_CLIENT_CHAN, BAD_CLIENT_ID); backchannel_sync_wait(CLIENT_CLIENT_CHAN, BAD_CLIENT_ID); - connect_restore_sec_unsubscribe(); + connect_restore_sec(); disconnect(); PASS("Central test passed\n"); diff --git a/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c b/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c index b9070361577..ac6307dae6a 100644 --- a/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c @@ -194,9 +194,9 @@ static void connect_wait_unsubscribtion(struct bt_le_ext_adv *adv) stop_adv(adv); - /* check that subscribtion is not restored for bad client */ - if (is_peer_subscribed(default_conn)) { - FAIL("Subscribtion has been restored for bad client\n"); + /* check that subscribtion is restored for bad client */ + if (!is_peer_subscribed(default_conn)) { + FAIL("Subscribtion has not been restored for bad client\n"); } /* confirm to bad client that the subscribtion had not been restored */ @@ -204,12 +204,12 @@ static void connect_wait_unsubscribtion(struct bt_le_ext_adv *adv) /* wait for confirmation that bad client requested unsubscribtion */ backchannel_sync_wait(BAD_CLIENT_CHAN, BAD_CLIENT_ID); - /* check that unsubscribtion request failed */ - if (GET_FLAG(ccc_cfg_changed_flag)) { - FAIL("Bad client updated CCC config\n"); + /* check that unsubscribtion request didn't fail */ + if (!GET_FLAG(ccc_cfg_changed_flag)) { + FAIL("Bad client didn't manage to update CCC config\n"); } - /* confirm to bad client that unsubscribtion request has been ignored */ + /* confirm to bad client that unsubscribtion request has been well registered */ backchannel_sync_send(BAD_CLIENT_CHAN, BAD_CLIENT_ID); } @@ -225,9 +225,9 @@ static void connect_restore_sec_check_subscribtion(struct bt_le_ext_adv *adv) /* wait for good client end of security update */ backchannel_sync_wait(GOOD_CLIENT_CHAN, GOOD_CLIENT_ID); - /* check that subscribtion has been restored */ - if (!is_peer_subscribed(default_conn)) { - FAIL("Good client is not subscribed\n"); + /* check that subscribtion hasn't been restored */ + if (is_peer_subscribed(default_conn)) { + FAIL("Good client is subscribed\n"); } /* confirm to good client that the subscribtion has been well restored */ @@ -285,6 +285,14 @@ static void check_ccc_handle(void) void run_peripheral(void) { + /* + * test goal: demonstrate the expected behavior of the GATT server when + * a non-bonded peer try to unsubscribe from a previously subscription + * done in a bonded context + * + * test pass if the bad client manage to unsubscribe + */ + int err; struct bt_le_ext_adv *adv = NULL; From 1d29a8c3c2a79cc4834603ed692dcab1b495e3b3 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 20 Jul 2023 11:18:19 +0200 Subject: [PATCH 1215/4498] drivers: i2c: stm32 i2c driver supports 10-bit addressing When slave_address is 10 bits, data type should be uint16_t instead of uint8_t, like the data typeof data->slave_cfg->address. https://github.com/zephyrproject-rtos/zephyr/issues/55987 Signed-off-by: Francois Ramu --- drivers/i2c/i2c_ll_stm32_v2.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index 3f83bde5ddb..a05edd5c8cb 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -120,18 +120,25 @@ static void stm32_i2c_slave_event(const struct device *dev) I2C_TypeDef *i2c = cfg->i2c; const struct i2c_target_callbacks *slave_cb; struct i2c_target_config *slave_cfg; - uint8_t slave_address; - - /* Choose the right slave from the address match code */ - slave_address = LL_I2C_GetAddressMatchCode(i2c) >> 1; - if (data->slave_cfg != NULL && slave_address == data->slave_cfg->address) { - slave_cfg = data->slave_cfg; - } else if (data->slave2_cfg != NULL && slave_address == data->slave2_cfg->address) { - slave_cfg = data->slave2_cfg; - } else { - __ASSERT_NO_MSG(0); - return; + + if (data->slave_cfg->flags != I2C_TARGET_FLAGS_ADDR_10_BITS) { + uint8_t slave_address; + + /* Choose the right slave from the address match code */ + slave_address = LL_I2C_GetAddressMatchCode(i2c) >> 1; + if (data->slave_cfg != NULL && + slave_address == data->slave_cfg->address) { + slave_cfg = data->slave_cfg; + } else if (data->slave2_cfg != NULL && + slave_address == data->slave2_cfg->address) { + slave_cfg = data->slave2_cfg; + } else { + __ASSERT_NO_MSG(0); + return; + } } + + slave_cfg = data->slave_cfg; slave_cb = slave_cfg->callbacks; if (LL_I2C_IsActiveFlag_TXIS(i2c)) { From e73e78a550870d593e244226320dcd1c0acbcd41 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 23 Aug 2023 13:31:48 +0200 Subject: [PATCH 1216/4498] net: dhcpv6: Add Zephyr DHCPv6 client Add a DHCPv6 client implementation for Zephyr (RFC 8415). The implementation allows to request IPv6 address and/or prefix from the DHCPv6 server, and for now supports only the mandatory set of DHCPv6 options needed to achieve this. Currently the implementation supports the following scenarios: * Requesting new IPv6 address/prefix with Solicit/Request exchange * Refreshing existing leases with Confirm, Renew or Rebind (depending on the context). For now, no Information Request (the case where neither IPv6 address or prefix are requested) is supported. No support for Reconfigure was added either, as this is optional (the client manifests clearly to the server that it does not support Reconfigure). Support for these can be added later if needed. Signed-off-by: Robert Lubos --- include/zephyr/net/dhcpv6.h | 116 ++ include/zephyr/net/net_if.h | 70 + subsys/net/ip/CMakeLists.txt | 1 + subsys/net/ip/Kconfig.ipv6 | 14 + subsys/net/ip/dhcpv6.c | 2196 +++++++++++++++++++++++++++++++ subsys/net/ip/dhcpv6_internal.h | 196 +++ subsys/net/ip/net_core.c | 6 + 7 files changed, 2599 insertions(+) create mode 100644 include/zephyr/net/dhcpv6.h create mode 100644 subsys/net/ip/dhcpv6.c create mode 100644 subsys/net/ip/dhcpv6_internal.h diff --git a/include/zephyr/net/dhcpv6.h b/include/zephyr/net/dhcpv6.h new file mode 100644 index 00000000000..95b59f530b5 --- /dev/null +++ b/include/zephyr/net/dhcpv6.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief DHCPv6 client + */ + +#ifndef ZEPHYR_INCLUDE_NET_DHCPV6_H_ +#define ZEPHYR_INCLUDE_NET_DHCPV6_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DHCPv6 + * @defgroup dhcpv6 DHCPv6 + * @ingroup networking + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +/** Current state of DHCPv6 client address/prefix negotiation. */ +enum net_dhcpv6_state { + NET_DHCPV6_DISABLED, + NET_DHCPV6_INIT, + NET_DHCPV6_SOLICITING, + NET_DHCPV6_REQUESTING, + NET_DHCPV6_CONFIRMING, + NET_DHCPV6_RENEWING, + NET_DHCPV6_REBINDING, + NET_DHCPV6_INFO_REQUESTING, + NET_DHCPV6_BOUND, +} __packed; + +#define DHCPV6_TID_SIZE 3 +#define DHCPV6_DUID_MAX_SIZE 20 + +struct net_dhcpv6_duid_raw { + uint16_t type; + uint8_t buf[DHCPV6_DUID_MAX_SIZE]; +} __packed; + +struct net_dhcpv6_duid_storage { + struct net_dhcpv6_duid_raw duid; + uint8_t length; +}; + +struct net_if; + +/** @endcond */ + +/** @brief DHCPv6 client configuration parameters. */ +struct net_dhcpv6_params { + bool request_addr : 1; /**< Request IPv6 address. */ + bool request_prefix : 1; /**< Request IPv6 prefix. */ +}; + +/** + * @brief Start DHCPv6 client on an iface + * + * @details Start DHCPv6 client on a given interface. DHCPv6 client will start + * negotiation for IPv6 address and/or prefix, depending on the configuration. + * Once the negotiation is complete, IPv6 address/prefix details will be added + * to the interface. + * + * @param iface A valid pointer to a network interface + * @param params DHCPv6 client configuration parameters. + */ +void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params); + +/** + * @brief Stop DHCPv6 client on an iface + * + * @details Stop DHCPv6 client on a given interface. DHCPv6 client + * will remove all configuration obtained from a DHCP server from the + * interface and stop any further negotiation with the server. + * + * @param iface A valid pointer to a network interface + */ +void net_dhcpv6_stop(struct net_if *iface); + +/** + * @brief Restart DHCPv6 client on an iface + * + * @details Restart DHCPv6 client on a given interface. DHCPv6 client + * will restart the state machine without any of the initial delays. + * + * @param iface A valid pointer to a network interface + */ +void net_dhcpv6_restart(struct net_if *iface); + +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief DHCPv6 state name + * + * @internal + */ +const char *net_dhcpv6_state_name(enum net_dhcpv6_state state); + +/** @endcond */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_DHCPV6_H_ */ diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index cced3557b84..b06bf74de03 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -33,6 +33,9 @@ #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4) #include #endif +#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) +#include +#endif #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4) #include #endif @@ -275,6 +278,69 @@ struct net_if_ipv6 { uint8_t hop_limit; }; +#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) +struct net_if_dhcpv6 { + /** Used for timer list. */ + sys_snode_t node; + + /** Generated Client ID. */ + struct net_dhcpv6_duid_storage clientid; + + /** Server ID of the selected server. */ + struct net_dhcpv6_duid_storage serverid; + + /** DHCPv6 client state. */ + enum net_dhcpv6_state state; + + /** DHCPv6 client configuration parameters. */ + struct net_dhcpv6_params params; + + /** Timeout for the next event, absolute time, milliseconds. */ + uint64_t timeout; + + /** Time of the current exchange start, absolute time, milliseconds */ + uint64_t exchange_start; + + /** Renewal time, absolute time, milliseconds. */ + uint64_t t1; + + /** Rebinding time, absolute time, milliseconds. */ + uint64_t t2; + + /** The time when the last lease expires (terminates rebinding, + * DHCPv6 RFC8415, ch. 18.2.5). Absolute time, milliseconds. + */ + uint64_t expire; + + /** Generated IAID for IA_NA. */ + uint32_t addr_iaid; + + /** Generated IAID for IA_PD. */ + uint32_t prefix_iaid; + + /** Retransmit timeout for the current message, milliseconds. */ + uint32_t retransmit_timeout; + + /** Current best server preference received. */ + int16_t server_preference; + + /** Retransmission counter. */ + uint8_t retransmissions; + + /** Transaction ID for current exchange. */ + uint8_t tid[DHCPV6_TID_SIZE]; + + /** Prefix length. */ + uint8_t prefix_len; + + /** Assigned IPv6 prefix. */ + struct in6_addr prefix; + + /** Assigned IPv6 address. */ + struct in6_addr addr; +}; +#endif /* defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) */ + /** @cond INTERNAL_HIDDEN */ #if defined(CONFIG_NET_NATIVE_IPV4) #define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT @@ -413,6 +479,10 @@ struct net_if_config { struct net_if_dhcpv4 dhcpv4; #endif /* CONFIG_NET_DHCPV4 */ +#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) + struct net_if_dhcpv6 dhcpv6; +#endif /* CONFIG_NET_DHCPV6 */ + #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4) struct net_if_ipv4_autoconf ipv4auto; #endif /* CONFIG_NET_IPV4_AUTO */ diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index 70655e2f61c..7dc54935c5c 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -31,6 +31,7 @@ zephyr_library_sources(net_tc.c) zephyr_library_sources_ifdef(CONFIG_NET_IP connection.c) zephyr_library_sources_ifdef(CONFIG_NET_6LO 6lo.c) zephyr_library_sources_ifdef(CONFIG_NET_DHCPV4 dhcpv4.c) +zephyr_library_sources_ifdef(CONFIG_NET_DHCPV6 dhcpv6.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4_AUTO ipv4_autoconf.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4 icmpv4.c ipv4.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4_IGMP igmp.c) diff --git a/subsys/net/ip/Kconfig.ipv6 b/subsys/net/ip/Kconfig.ipv6 index b776d3756eb..18fb4b0ccc4 100644 --- a/subsys/net/ip/Kconfig.ipv6 +++ b/subsys/net/ip/Kconfig.ipv6 @@ -166,6 +166,12 @@ config NET_MAX_6LO_CONTEXTS 6lowpan context options table size. The value depends on your network and memory consumption. More 6CO options uses more memory. +config NET_DHCPV6 + bool "DHCPv6 client" + select NET_MGMT + select NET_MGMT_EVENT + depends on NET_UDP + if NET_6LO module = NET_6LO module-dep = NET_LOG @@ -192,5 +198,13 @@ module-str = Log level for IPv6 neighbor cache module-help = Enables IPv6 Neighbor Cache code to output debug messages. source "subsys/net/Kconfig.template.log_config.net" +if NET_DHCPV6 +module = NET_DHCPV6 +module-dep = NET_LOG +module-str = Log level for DHCPv6 client +module-help = Enables DHCPv6 client code to output debug messages. +source "subsys/net/Kconfig.template.log_config.net" +endif # NET_DHCPV6 + endif # NET_NATIVE_IPV6 endif # NET_IPV6 diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c new file mode 100644 index 00000000000..040c9fa0e06 --- /dev/null +++ b/subsys/net/ip/dhcpv6.c @@ -0,0 +1,2196 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief DHCPv6 client implementation + */ + +#include +LOG_MODULE_REGISTER(net_dhcpv6, CONFIG_NET_DHCPV6_LOG_LEVEL); + +#include +#include +#include +#include + +#include "dhcpv6_internal.h" +#include "ipv6.h" +#include "net_private.h" +#include "udp_internal.h" + +/* Maximum number of options client can request. */ +#define DHCPV6_MAX_OPTION_REQUEST 2 + +struct dhcpv6_options_include { + bool clientid : 1; + bool serverid : 1; + bool elapsed_time : 1; + bool ia_na : 1; + bool iaaddr : 1; + bool ia_pd : 1; + bool iaprefix : 1; + uint16_t oro[DHCPV6_MAX_OPTION_REQUEST]; +}; + +static K_MUTEX_DEFINE(lock); + +/* All_DHCP_Relay_Agents_and_Servers (ff02::1:2) */ +static const struct in6_addr all_dhcpv6_ra_and_servers = { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0x01, 0, 0x02 } } }; + +static sys_slist_t dhcpv6_ifaces = SYS_SLIST_STATIC_INIT(&dhcpv6_ifaces); +static struct k_work_delayable dhcpv6_timeout_work; +static struct net_mgmt_event_callback dhcpv6_mgmt_cb; + +const char *net_dhcpv6_state_name(enum net_dhcpv6_state state) +{ + static const char * const name[] = { + "disabled", + "init", + "soliciting", + "requesting", + "confirming", + "renewing", + "rebinding", + "information requesting", + "bound", + }; + + __ASSERT_NO_MSG(state >= 0 && state < sizeof(name)); + return name[state]; +} + +static void dhcpv6_generate_tid(struct net_if *iface) +{ + sys_rand_get(iface->config.dhcpv6.tid, sizeof(iface->config.dhcpv6.tid)); +} + +static void dhcvp6_update_deadlines(struct net_if *iface, int64_t now, + uint32_t t1, uint32_t t2, + uint32_t preferred_lifetime, + uint32_t valid_lifetime) +{ + uint64_t t1_abs, t2_abs, expire_abs; + + /* In case server does not set T1/T2 values, the time choice is left to + * the client discretion. + * Here, we use recommendations for the servers, where it's advised to + * set T1/T2 as 0.5 and 0.8 of the preferred lifetime. + */ + if (t1 == 0 && t2 == 0) { + if (preferred_lifetime == DHCPV6_INFINITY) { + t1 = DHCPV6_INFINITY; + t2 = DHCPV6_INFINITY; + } else { + t1 = preferred_lifetime * 0.5; + t2 = preferred_lifetime * 0.8; + } + } else if (t1 == 0) { + if (t2 == DHCPV6_INFINITY) { + t1 = DHCPV6_INFINITY; + } else { + t1 = t2 * 0.625; /* 0.5 / 0.8 */ + } + } else if (t2 == 0) { + if (t1 == DHCPV6_INFINITY) { + t2 = DHCPV6_INFINITY; + } else { + t2 = t1 * 1.6; /* 0.8 / 0.5 */ + /* Overflow check. */ + if (t2 < t1) { + t2 = DHCPV6_INFINITY; + } + } + } else if (t1 >= t2) { + NET_ERR("Invalid T1(%u)/T2(%u) values.", t1, t2); + return; + } + + if (t1 == DHCPV6_INFINITY || + u64_add_overflow(now, 1000ULL * t1, &t1_abs)) { + t1_abs = UINT64_MAX; + } + + if (t2 == DHCPV6_INFINITY || + u64_add_overflow(now, 1000ULL * t2, &t2_abs)) { + t2_abs = UINT64_MAX; + } + + if (valid_lifetime == DHCPV6_INFINITY || + u64_add_overflow(now, 1000ULL * valid_lifetime, &expire_abs)) { + expire_abs = UINT64_MAX; + } + + if (iface->config.dhcpv6.t1 > t1_abs) { + iface->config.dhcpv6.t1 = t1_abs; + } + + if (iface->config.dhcpv6.t2 > t2_abs) { + iface->config.dhcpv6.t2 = t2_abs; + } + + if (iface->config.dhcpv6.expire < expire_abs) { + iface->config.dhcpv6.expire = expire_abs; + } +} + +static void dhcpv6_set_timeout(struct net_if *iface, uint64_t timeout) +{ + int64_t now = k_uptime_get(); + + NET_DBG("sched dhcpv6 timeout iface=%p timeout=%llums", iface, timeout); + + if (u64_add_overflow(now, timeout, &iface->config.dhcpv6.timeout)) { + iface->config.dhcpv6.timeout = UINT64_MAX; + } +} + +static void dhcpv6_reschedule(void) +{ + k_work_reschedule(&dhcpv6_timeout_work, K_NO_WAIT); +} + +static int randomize_timeout(int multiplier, int timeout) +{ + int factor; + + /* DHCPv6 RFC8415, ch. 15. the randomization factor should be a random + * number between -0.1 nand +0.1. As we operate on integers here, we + * scale it to -100 and +100, and divide the result by 1000. + */ + factor = (int)(sys_rand32_get() % 201) - 100; + + return (multiplier * timeout) + ((factor * timeout) / 1000); +} + +static int dhcpv6_initial_retransmit_time(int init_retransmit_time) +{ + /* DHCPv6 RFC8415, ch. 15. Retransmission time for the first msg. */ + return randomize_timeout(1, init_retransmit_time); +} + +static uint32_t dhcpv6_next_retransmit_time(int prev_retransmit_time, + int max_retransmit_time) +{ + int retransmit_time; + + /* DHCPv6 RFC8415, ch. 15. Retransmission time for the subsequent msg. */ + retransmit_time = randomize_timeout(2, prev_retransmit_time); + + if (max_retransmit_time == 0) { + return retransmit_time; + } + + if (retransmit_time > max_retransmit_time) { + retransmit_time = randomize_timeout(1, max_retransmit_time); + } + + return retransmit_time; +} + +/* DHCPv6 packet encoding functions */ + +static int dhcpv6_add_header(struct net_pkt *pkt, enum dhcpv6_msg_type type, + uint8_t *tid) +{ + int ret; + + ret = net_pkt_write_u8(pkt, type); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write(pkt, tid, DHCPV6_TID_SIZE); + + return ret; +} + +static int dhcpv6_add_option_header(struct net_pkt *pkt, + enum dhcpv6_option_code code, + uint16_t length) +{ + int ret; + + ret = net_pkt_write_be16(pkt, code); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be16(pkt, length); + + return ret; +} + +static int dhcpv6_add_option_clientid(struct net_pkt *pkt, + struct net_dhcpv6_duid_storage *clientid) +{ + int ret; + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_CLIENTID, + clientid->length); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write(pkt, &clientid->duid, clientid->length); + + return ret; +} + +static int dhcpv6_add_option_serverid(struct net_pkt *pkt, + struct net_dhcpv6_duid_storage *serverid) +{ + int ret; + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_SERVERID, + serverid->length); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write(pkt, &serverid->duid, serverid->length); + + return ret; +} + + +static int dhcpv6_add_option_elapsed_time(struct net_pkt *pkt, uint64_t since) +{ + uint64_t elapsed; + int ret; + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_ELAPSED_TIME, + DHCPV6_OPTION_ELAPSED_TIME_SIZE); + if (ret < 0) { + return ret; + } + + /* Elapsed time should be expressed in hundredths of a second. */ + elapsed = (k_uptime_get() - since) / 10ULL; + if (elapsed > 0xFFFF) { + elapsed = 0xFFFF; + } + + ret = net_pkt_write_be16(pkt, (uint16_t)elapsed); + + return ret; +} + +static int dhcpv6_add_option_ia_na(struct net_pkt *pkt, struct dhcpv6_ia_na *ia_na, + bool include_addr) +{ + uint16_t optlen; + int ret; + + if (!include_addr) { + optlen = DHCPV6_OPTION_IA_NA_HEADER_SIZE; + } else { + optlen = DHCPV6_OPTION_IA_NA_HEADER_SIZE + + DHCPV6_OPTION_HEADER_SIZE + + DHCPV6_OPTION_IAADDR_HEADER_SIZE; + } + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IA_NA, optlen); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_na->iaid); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_na->t1); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_na->t2); + if (ret < 0) { + return ret; + } + + if (!include_addr) { + return 0; + } + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IAADDR, + DHCPV6_OPTION_IAADDR_HEADER_SIZE); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write(pkt, &ia_na->iaaddr.addr, sizeof(ia_na->iaaddr.addr)); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_na->iaaddr.preferred_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_na->iaaddr.valid_lifetime); + + return ret; +} + +static int dhcpv6_add_option_ia_pd(struct net_pkt *pkt, struct dhcpv6_ia_pd *ia_pd, + bool include_prefix) +{ + uint16_t optlen; + int ret; + + if (!include_prefix) { + optlen = DHCPV6_OPTION_IA_PD_HEADER_SIZE; + } else { + optlen = DHCPV6_OPTION_IA_PD_HEADER_SIZE + + DHCPV6_OPTION_HEADER_SIZE + + DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; + } + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IA_PD, + optlen); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_pd->iaid); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_pd->t1); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_pd->t2); + if (ret < 0) { + return ret; + } + + if (!include_prefix) { + return 0; + } + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IAPREFIX, + DHCPV6_OPTION_IAPREFIX_HEADER_SIZE); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_pd->iaprefix.preferred_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be32(pkt, ia_pd->iaprefix.valid_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_u8(pkt, ia_pd->iaprefix.prefix_len); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write(pkt, &ia_pd->iaprefix.prefix, + sizeof(ia_pd->iaprefix.prefix)); + + return ret; +} + +static int dhcpv6_add_option_oro(struct net_pkt *pkt, uint16_t *codes, + int code_cnt) +{ + int ret; + + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_ORO, + sizeof(uint16_t) * code_cnt); + if (ret < 0) { + return ret; + } + + for (int i = 0; i < code_cnt; i++) { + ret = net_pkt_write_be16(pkt, codes[i]); + if (ret < 0) { + return ret; + } + } + + return ret; +} + +static size_t dhcpv6_calculate_message_size(struct dhcpv6_options_include *options) +{ + size_t msg_size = sizeof(struct dhcpv6_msg_hdr); + uint8_t oro_cnt = 0; + + if (options->clientid) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += sizeof(struct net_dhcpv6_duid_storage); + } + + if (options->serverid) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += sizeof(struct net_dhcpv6_duid_storage); + } + + if (options->elapsed_time) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += DHCPV6_OPTION_ELAPSED_TIME_SIZE; + } + + if (options->ia_na) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += DHCPV6_OPTION_IA_NA_HEADER_SIZE; + } + + if (options->iaaddr) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += DHCPV6_OPTION_IAADDR_HEADER_SIZE; + } + + if (options->ia_pd) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += DHCPV6_OPTION_IA_PD_HEADER_SIZE; + } + + if (options->iaprefix) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; + } + + for (uint8_t i = 0; i < ARRAY_SIZE(options->oro); i++) { + if (options->oro[i] == 0) { + break; + } + + oro_cnt++; + } + + if (oro_cnt > 0) { + msg_size += DHCPV6_OPTION_HEADER_SIZE; + msg_size += oro_cnt * sizeof(uint16_t); + } + + return msg_size; +} + +static int dhcpv6_add_options(struct net_if *iface, struct net_pkt *pkt, + struct dhcpv6_options_include *options) +{ + uint8_t oro_cnt = 0; + int ret; + + if (options->clientid) { + ret = dhcpv6_add_option_clientid( + pkt, &iface->config.dhcpv6.clientid); + if (ret < 0) { + goto fail; + } + } + + if (options->serverid) { + ret = dhcpv6_add_option_serverid( + pkt, &iface->config.dhcpv6.serverid); + if (ret < 0) { + goto fail; + } + } + + if (options->elapsed_time) { + ret = dhcpv6_add_option_elapsed_time( + pkt, iface->config.dhcpv6.exchange_start); + if (ret < 0) { + goto fail; + } + } + + if (options->ia_na) { + struct dhcpv6_ia_na ia_na = { + .iaid = iface->config.dhcpv6.addr_iaid, + }; + + if (options->iaaddr) { + memcpy(&ia_na.iaaddr.addr, &iface->config.dhcpv6.addr, + sizeof(ia_na.iaaddr.addr)); + } + + ret = dhcpv6_add_option_ia_na(pkt, &ia_na, options->iaaddr); + if (ret < 0) { + goto fail; + } + } + + if (options->ia_pd) { + struct dhcpv6_ia_pd ia_pd = { + .iaid = iface->config.dhcpv6.prefix_iaid, + }; + + if (options->iaprefix) { + memcpy(&ia_pd.iaprefix.prefix, &iface->config.dhcpv6.prefix, + sizeof(ia_pd.iaprefix.prefix)); + ia_pd.iaprefix.prefix_len = iface->config.dhcpv6.prefix_len; + } + + ret = dhcpv6_add_option_ia_pd(pkt, &ia_pd, options->iaprefix); + if (ret < 0) { + goto fail; + } + } + + for (uint8_t i = 0; i < ARRAY_SIZE(options->oro); i++) { + if (options->oro[i] == 0) { + break; + } + + oro_cnt++; + } + + if (oro_cnt > 0) { + ret = dhcpv6_add_option_oro(pkt, options->oro, oro_cnt); + if (ret < 0) { + goto fail; + } + } + + return 0; + +fail: + return ret; +} + +static struct net_pkt *dhcpv6_create_message(struct net_if *iface, + enum dhcpv6_msg_type msg_type, + struct dhcpv6_options_include *options) +{ + struct in6_addr *local_addr; + struct net_pkt *pkt; + size_t msg_size; + + local_addr = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE); + if (local_addr == NULL) { + NET_ERR("No LL address"); + return NULL; + } + + msg_size = dhcpv6_calculate_message_size(options); + + pkt = net_pkt_alloc_with_buffer(iface, msg_size, AF_INET6, + IPPROTO_UDP, K_FOREVER); + if (pkt == NULL) { + return NULL; + } + + if (net_ipv6_create(pkt, local_addr, &all_dhcpv6_ra_and_servers) < 0 || + net_udp_create(pkt, htons(DHCPV6_CLIENT_PORT), + htons(DHCPV6_SERVER_PORT)) < 0) { + goto fail; + } + + dhcpv6_generate_tid(iface); + + if (dhcpv6_add_header(pkt, msg_type, iface->config.dhcpv6.tid) < 0) { + goto fail; + } + + if (dhcpv6_add_options(iface, pkt, options) < 0) { + goto fail; + } + + net_pkt_cursor_init(pkt); + net_ipv6_finalize(pkt, IPPROTO_UDP); + + return pkt; + +fail: + net_pkt_unref(pkt); + + return NULL; +} + +static int dhcpv6_send_solicit(struct net_if *iface) +{ + int ret; + struct net_pkt *pkt; + struct dhcpv6_options_include options = { + .clientid = true, + .elapsed_time = true, + .ia_na = iface->config.dhcpv6.params.request_addr, + .ia_pd = iface->config.dhcpv6.params.request_prefix, + .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, + }; + + pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_SOLICIT, &options); + if (pkt == NULL) { + return -ENOMEM; + } + + ret = net_send_data(pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } + + return ret; +} + +static int dhcpv6_send_request(struct net_if *iface) +{ + int ret; + struct net_pkt *pkt; + struct dhcpv6_options_include options = { + .clientid = true, + .serverid = true, + .elapsed_time = true, + .ia_na = iface->config.dhcpv6.params.request_addr, + .ia_pd = iface->config.dhcpv6.params.request_prefix, + .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, + }; + + pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_REQUEST, &options); + if (pkt == NULL) { + return -ENOMEM; + } + + ret = net_send_data(pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } + + return ret; +} + +static int dhcpv6_send_renew(struct net_if *iface) +{ + int ret; + struct net_pkt *pkt; + struct dhcpv6_options_include options = { + .clientid = true, + .serverid = true, + .elapsed_time = true, + .ia_na = iface->config.dhcpv6.params.request_addr, + .iaaddr = iface->config.dhcpv6.params.request_addr, + .ia_pd = iface->config.dhcpv6.params.request_prefix, + .iaprefix = iface->config.dhcpv6.params.request_prefix, + .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, + }; + + pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_RENEW, &options); + if (pkt == NULL) { + return -ENOMEM; + } + + ret = net_send_data(pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } + + return ret; +} + +static int dhcpv6_send_rebind(struct net_if *iface) +{ + int ret; + struct net_pkt *pkt; + struct dhcpv6_options_include options = { + .clientid = true, + .elapsed_time = true, + .ia_na = iface->config.dhcpv6.params.request_addr, + .iaaddr = iface->config.dhcpv6.params.request_addr, + .ia_pd = iface->config.dhcpv6.params.request_prefix, + .iaprefix = iface->config.dhcpv6.params.request_prefix, + .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, + }; + + pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_REBIND, &options); + if (pkt == NULL) { + return -ENOMEM; + } + + ret = net_send_data(pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } + + return ret; +} + +static int dhcpv6_send_confirm(struct net_if *iface) +{ + int ret; + struct net_pkt *pkt; + struct dhcpv6_options_include options = { + .clientid = true, + .elapsed_time = true, + .ia_na = true, + .iaaddr = true, + }; + + pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_CONFIRM, &options); + if (pkt == NULL) { + return -ENOMEM; + } + + ret = net_send_data(pkt); + if (ret < 0) { + net_pkt_unref(pkt); + } + + return ret; +} + +/* DHCPv6 packet parsing functions */ + +static int dhcpv6_parse_option_clientid(struct net_pkt *pkt, uint16_t length, + struct net_dhcpv6_duid_storage *clientid) +{ + struct net_dhcpv6_duid_raw duid; + int ret; + + if (length > sizeof(struct net_dhcpv6_duid_raw)) { + NET_ERR("DUID too large to handle"); + return -EMSGSIZE; + } + + ret = net_pkt_read(pkt, &duid, length); + if (ret < 0) { + return ret; + } + + clientid->length = length; + memcpy(&clientid->duid, &duid, length); + + return 0; +} + +static int dhcpv6_parse_option_serverid(struct net_pkt *pkt, uint16_t length, + struct net_dhcpv6_duid_storage *serverid) +{ + struct net_dhcpv6_duid_raw duid; + int ret; + + if (length > sizeof(struct net_dhcpv6_duid_raw)) { + NET_ERR("DUID too large to handle"); + return -EMSGSIZE; + } + + ret = net_pkt_read(pkt, &duid, length); + if (ret < 0) { + return ret; + } + + serverid->length = length; + memcpy(&serverid->duid, &duid, length); + + return 0; +} + +static int dhcpv6_parse_option_preference(struct net_pkt *pkt, uint16_t length, + uint8_t *preference) +{ + if (length != DHCPV6_OPTION_PREFERENCE_SIZE) { + return -EBADMSG; + } + + if (net_pkt_read_u8(pkt, preference) < 0) { + return -EBADMSG; + } + + return 0; +} + +static int dhcpv6_parse_option_status_code(struct net_pkt *pkt, + uint16_t length, uint16_t *status) +{ + int ret; + + if (length < DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE) { + NET_ERR("Invalid IAADDR option size"); + return -EMSGSIZE; + } + + ret = net_pkt_read_be16(pkt, status); + if (ret < 0) { + return ret; + } + + NET_DBG("status code %d", *status); + + length -= DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE; + if (length > 0) { + /* Ignore status message */ + ret = net_pkt_skip(pkt, length); + } + + return ret; +} + +static int dhcpv6_parse_option_iaaddr(struct net_pkt *pkt, uint16_t length, + struct dhcpv6_iaaddr *iaaddr) +{ + int ret; + + if (length < DHCPV6_OPTION_IAADDR_HEADER_SIZE) { + NET_ERR("Invalid IAADDR option size"); + return -EMSGSIZE; + } + + ret = net_pkt_read(pkt, &iaaddr->addr, sizeof(iaaddr->addr)); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &iaaddr->preferred_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &iaaddr->valid_lifetime); + if (ret < 0) { + return ret; + } + + /* DHCPv6 RFC8415, ch. 21.6 The client MUST discard any addresses for + * which the preferred lifetime is greater than the valid lifetime. + */ + if (iaaddr->preferred_lifetime > iaaddr->valid_lifetime) { + return -EBADMSG; + } + + NET_DBG("addr %s preferred_lifetime %d valid_lifetime %d", + net_sprint_ipv6_addr(&iaaddr->addr), iaaddr->preferred_lifetime, + iaaddr->valid_lifetime); + + iaaddr->status = DHCPV6_STATUS_SUCCESS; + + length -= DHCPV6_OPTION_IAADDR_HEADER_SIZE; + while (length > 0) { + uint16_t code, sublen; + + ret = net_pkt_read_be16(pkt, &code); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be16(pkt, &sublen); + if (ret < 0) { + return ret; + } + + switch (code) { + case DHCPV6_OPTION_CODE_STATUS_CODE: + ret = dhcpv6_parse_option_status_code(pkt, sublen, + &iaaddr->status); + if (ret < 0) { + return ret; + } + + break; + default: + net_pkt_skip(pkt, sublen); + NET_DBG("Unexpected option %d length %d", code, sublen); + break; + } + + length -= (sublen + 4); + } + + return 0; +} + +static int dhcpv6_parse_option_ia_na(struct net_pkt *pkt, uint16_t length, + struct dhcpv6_ia_na *ia_na) +{ + int ret; + + if (length < DHCPV6_OPTION_IA_NA_HEADER_SIZE) { + NET_ERR("Invalid IA_NA option size"); + return -EMSGSIZE; + } + + ret = net_pkt_read_be32(pkt, &ia_na->iaid); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &ia_na->t1); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &ia_na->t2); + if (ret < 0) { + return ret; + } + + /* DHCPv6 RFC8415, ch. 21.4 If a client receives an IA_NA with T1 + * greater than T2 and both T1 and T2 are greater than 0, the client + * discards the IA_NA option and processes the remainder of the message + * as though the server had not included the invalid IA_NA option. + */ + if (ia_na->t1 != 0 && ia_na->t2 != 0 && ia_na->t1 > ia_na->t2) { + return -ENOENT; + } + + NET_DBG("iaid %d t1 %d t2 %d", ia_na->iaid, ia_na->t1, ia_na->t2); + + /* In case there's no IAADDR option, make this visible be setting + * error status. If the option is present, option parser will overwrite + * the value. + */ + ia_na->iaaddr.status = DHCPV6_STATUS_NO_ADDR_AVAIL; + ia_na->status = DHCPV6_STATUS_SUCCESS; + + length -= DHCPV6_OPTION_IA_NA_HEADER_SIZE; + while (length > 0) { + uint16_t code, sublen; + + ret = net_pkt_read_be16(pkt, &code); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be16(pkt, &sublen); + if (ret < 0) { + return ret; + } + + switch (code) { + case DHCPV6_OPTION_CODE_IAADDR: + ret = dhcpv6_parse_option_iaaddr(pkt, sublen, + &ia_na->iaaddr); + if (ret < 0) { + return ret; + } + + break; + + case DHCPV6_OPTION_CODE_STATUS_CODE: + ret = dhcpv6_parse_option_status_code(pkt, sublen, + &ia_na->status); + if (ret < 0) { + return ret; + } + + break; + + default: + net_pkt_skip(pkt, sublen); + NET_DBG("Unexpected option %d length %d", code, sublen); + break; + } + + length -= (sublen + 4); + } + + return 0; +} + +static int dhcpv6_parse_option_iaprefix(struct net_pkt *pkt, uint16_t length, + struct dhcpv6_iaprefix *iaprefix) +{ + int ret; + + if (length < DHCPV6_OPTION_IAPREFIX_HEADER_SIZE) { + NET_ERR("Invalid IAPREFIX option size"); + return -EMSGSIZE; + } + + ret = net_pkt_read_be32(pkt, &iaprefix->preferred_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &iaprefix->valid_lifetime); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_u8(pkt, &iaprefix->prefix_len); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read(pkt, &iaprefix->prefix, sizeof(iaprefix->prefix)); + if (ret < 0) { + return ret; + } + + /* DHCPv6 RFC8415, ch. 21.22 The client MUST discard any prefixes for + * which the preferred lifetime is greater than the valid lifetime. + */ + if (iaprefix->preferred_lifetime > iaprefix->valid_lifetime) { + return -EBADMSG; + } + + NET_DBG("prefix %s/%u preferred_lifetime %d valid_lifetime %d", + net_sprint_ipv6_addr(&iaprefix->prefix), iaprefix->prefix_len, + iaprefix->preferred_lifetime, iaprefix->valid_lifetime); + + iaprefix->status = DHCPV6_STATUS_SUCCESS; + + length -= DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; + while (length > 0) { + uint16_t code, sublen; + + ret = net_pkt_read_be16(pkt, &code); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be16(pkt, &sublen); + if (ret < 0) { + return ret; + } + + switch (code) { + case DHCPV6_OPTION_CODE_STATUS_CODE: + ret = dhcpv6_parse_option_status_code(pkt, sublen, + &iaprefix->status); + if (ret < 0) { + return ret; + } + + break; + default: + net_pkt_skip(pkt, sublen); + NET_DBG("Unexpected option %d length %d", code, sublen); + break; + } + + length -= (sublen + 4); + } + + return 0; +} + +static int dhcpv6_parse_option_ia_pd(struct net_pkt *pkt, uint16_t length, + struct dhcpv6_ia_pd *ia_pd) +{ + int ret; + + if (length < DHCPV6_OPTION_IA_PD_HEADER_SIZE) { + NET_ERR("Invalid IA_PD option size"); + return -EMSGSIZE; + } + + ret = net_pkt_read_be32(pkt, &ia_pd->iaid); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &ia_pd->t1); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be32(pkt, &ia_pd->t2); + if (ret < 0) { + return ret; + } + + /* DHCPv6 RFC8415, ch. 21.21 If a client receives an IA_PD with T1 + * greater than T2 and both T1 and T2 are greater than 0, the client + * discards the IA_PD option and processes the remainder of the message + * as though the server had not included the IA_PD option. + */ + if (ia_pd->t1 != 0 && ia_pd->t2 != 0 && ia_pd->t1 > ia_pd->t2) { + return -ENOENT; + } + + NET_DBG("iaid %d t1 %d t2 %d", ia_pd->iaid, ia_pd->t1, ia_pd->t2); + + /* In case there's no IAPREFIX option, make this visible be setting + * error status. If the option is present, option parser will overwrite + * the value. + */ + ia_pd->iaprefix.status = DHCPV6_STATUS_NO_PREFIX_AVAIL; + ia_pd->status = DHCPV6_STATUS_SUCCESS; + + length -= DHCPV6_OPTION_IA_PD_HEADER_SIZE; + while (length > 0) { + uint16_t code, sublen; + + ret = net_pkt_read_be16(pkt, &code); + if (ret < 0) { + return ret; + } + + ret = net_pkt_read_be16(pkt, &sublen); + if (ret < 0) { + return ret; + } + + switch (code) { + case DHCPV6_OPTION_CODE_IAPREFIX: + ret = dhcpv6_parse_option_iaprefix(pkt, sublen, + &ia_pd->iaprefix); + if (ret < 0) { + return ret; + } + + break; + + case DHCPV6_OPTION_CODE_STATUS_CODE: + ret = dhcpv6_parse_option_status_code(pkt, sublen, + &ia_pd->status); + if (ret < 0) { + return ret; + } + + break; + default: + net_pkt_skip(pkt, sublen); + NET_DBG("Unexpected option %d length %d", code, sublen); + break; + } + + length -= (sublen + 4); + } + + return 0; +} + +static int dhcpv6_find_option(struct net_pkt *pkt, enum dhcpv6_option_code opt_code, + uint16_t *opt_len) +{ + uint16_t length; + uint16_t code; + + while (net_pkt_read_be16(pkt, &code) == 0) { + if (net_pkt_read_be16(pkt, &length) < 0) { + return -EBADMSG; + } + + if (code == opt_code) { + *opt_len = length; + return 0; + } + + net_pkt_skip(pkt, length); + } + + return -ENOENT; +} + +static int dhcpv6_find_clientid(struct net_pkt *pkt, + struct net_dhcpv6_duid_storage *clientid) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_CLIENTID, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_clientid(pkt, length, clientid); + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +static int dhcpv6_find_serverid(struct net_pkt *pkt, + struct net_dhcpv6_duid_storage *serverid) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_SERVERID, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_serverid(pkt, length, serverid); + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +static int dhcpv6_find_server_preference(struct net_pkt *pkt, + uint8_t *preference) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_PREFERENCE, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_preference(pkt, length, preference); + } else if (ret == -ENOENT) { + /* In case no preference option is present, default to 0. + * DHCPv6 RFC8415, ch. 18.2.1. + */ + *preference = 0; + ret = 0; + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +static int dhcpv6_find_ia_na(struct net_pkt *pkt, struct dhcpv6_ia_na *ia_na) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_IA_NA, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_ia_na(pkt, length, ia_na); + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +static int dhcpv6_find_ia_pd(struct net_pkt *pkt, struct dhcpv6_ia_pd *ia_pd) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_IA_PD, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_ia_pd(pkt, length, ia_pd); + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +static int dhcpv6_find_status_code(struct net_pkt *pkt, uint16_t *status) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_STATUS_CODE, &length); + if (ret == 0) { + ret = dhcpv6_parse_option_status_code(pkt, length, status); + } else if (ret == -ENOENT) { + /* In case no status option is present, default to success. + * DHCPv6 RFC8415, ch. 21.13. + */ + *status = DHCPV6_STATUS_SUCCESS; + ret = 0; + } + + net_pkt_cursor_restore(pkt, &backup); + + return ret; +} + +/* DHCPv6 state changes */ + +static void dhcpv6_enter_init(struct net_if *iface) +{ + uint32_t timeout; + + /* RFC8415 requires to wait a random period up to 1 second before + * sending the initial solicit/information request/confirm. + */ + timeout = sys_rand32_get() % DHCPV6_SOL_MAX_DELAY; + + dhcpv6_set_timeout(iface, timeout); +} + +static void dhcpv6_enter_soliciting(struct net_if *iface) +{ + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_initial_retransmit_time(DHCPV6_SOL_TIMEOUT); + iface->config.dhcpv6.retransmissions = 0; + iface->config.dhcpv6.server_preference = -1; + iface->config.dhcpv6.exchange_start = k_uptime_get(); + + (void)dhcpv6_send_solicit(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); +} + +static void dhcpv6_enter_requesting(struct net_if *iface) +{ + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_initial_retransmit_time(DHCPV6_REQ_TIMEOUT); + iface->config.dhcpv6.retransmissions = 0; + iface->config.dhcpv6.exchange_start = k_uptime_get(); + + (void)dhcpv6_send_request(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); +} + +static void dhcpv6_enter_renewing(struct net_if *iface) +{ + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_initial_retransmit_time(DHCPV6_REN_TIMEOUT); + iface->config.dhcpv6.retransmissions = 0; + iface->config.dhcpv6.exchange_start = k_uptime_get(); + + (void)dhcpv6_send_renew(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); +} + +static void dhcpv6_enter_rebinding(struct net_if *iface) +{ + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_initial_retransmit_time(DHCPV6_REB_TIMEOUT); + iface->config.dhcpv6.retransmissions = 0; + iface->config.dhcpv6.exchange_start = k_uptime_get(); + + (void)dhcpv6_send_rebind(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); +} + +static void dhcpv6_enter_confirming(struct net_if *iface) +{ + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_initial_retransmit_time(DHCPV6_CNF_TIMEOUT); + iface->config.dhcpv6.retransmissions = 0; + iface->config.dhcpv6.exchange_start = k_uptime_get(); + + (void)dhcpv6_send_confirm(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); +} + +static void dhcpv6_enter_bound(struct net_if *iface) +{ + iface->config.dhcpv6.timeout = iface->config.dhcpv6.t1; +} + +static void dhcpv6_enter_state(struct net_if *iface, enum net_dhcpv6_state state) +{ + iface->config.dhcpv6.state = state; + + NET_DBG("enter state=%s", + net_dhcpv6_state_name(iface->config.dhcpv6.state)); + + switch (iface->config.dhcpv6.state) { + case NET_DHCPV6_DISABLED: + break; + case NET_DHCPV6_INIT: + return dhcpv6_enter_init(iface); + case NET_DHCPV6_SOLICITING: + return dhcpv6_enter_soliciting(iface); + case NET_DHCPV6_REQUESTING: + return dhcpv6_enter_requesting(iface); + case NET_DHCPV6_CONFIRMING: + return dhcpv6_enter_confirming(iface); + case NET_DHCPV6_RENEWING: + return dhcpv6_enter_renewing(iface); + case NET_DHCPV6_REBINDING: + return dhcpv6_enter_rebinding(iface); + case NET_DHCPV6_INFO_REQUESTING: + break; + case NET_DHCPV6_BOUND: + return dhcpv6_enter_bound(iface); + } +} + +/* DHCPv6 input processing */ + +static int dhcpv6_handle_advertise(struct net_if *iface, struct net_pkt *pkt, + uint8_t *tid) +{ + struct net_dhcpv6_duid_storage duid = { 0 }; + struct dhcpv6_ia_pd ia_pd = { 0 }; + struct dhcpv6_ia_na ia_na = { 0 }; + uint8_t server_preference = 0; + uint16_t status = 0; + int ret; + + if (iface->config.dhcpv6.state != NET_DHCPV6_SOLICITING) { + return -EINVAL; + } + + /* Verify client ID. */ + ret = dhcpv6_find_clientid(pkt, &duid); + if (ret < 0) { + NET_ERR("Client ID missing"); + return ret; + } + + if (iface->config.dhcpv6.clientid.length != duid.length || + memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, + iface->config.dhcpv6.clientid.length) != 0) { + NET_ERR("Client ID mismatch"); + return -EBADMSG; + } + + /* Verify server ID is present. */ + memset(&duid, 0, sizeof(duid)); + ret = dhcpv6_find_serverid(pkt, &duid); + if (ret < 0) { + NET_ERR("Server ID missing"); + return ret; + } + + /* Verify TID. */ + if (memcmp(iface->config.dhcpv6.tid, tid, + sizeof(iface->config.dhcpv6.tid)) != 0) { + NET_INFO("TID mismatch"); + return -EBADMSG; + } + + /* Verify status code. */ + ret = dhcpv6_find_status_code(pkt, &status); + if (ret < 0) { + return ret; + } + + if (status != DHCPV6_STATUS_SUCCESS) { + /* Ignore. */ + return 0; + } + + /* TODO Process SOL_MAX_RT/INF_MAX_RT options. */ + + /* Verify server preference. */ + ret = dhcpv6_find_server_preference(pkt, &server_preference); + if (ret < 0) { + return ret; + } + + if ((int16_t)server_preference < iface->config.dhcpv6.server_preference) { + /* Ignore. */ + return 0; + } + + /* Find/verify address. */ + if (iface->config.dhcpv6.params.request_addr) { + ret = dhcpv6_find_ia_na(pkt, &ia_na); + if (ret < 0) { + NET_ERR("Address missing"); + return ret; + } + + if (ia_na.status != DHCPV6_STATUS_SUCCESS || + ia_na.iaaddr.status != DHCPV6_STATUS_SUCCESS) { + /* Ignore. */ + return 0; + } + } + + /* Find/verify prefix. */ + if (iface->config.dhcpv6.params.request_prefix) { + ret = dhcpv6_find_ia_pd(pkt, &ia_pd); + if (ret < 0) { + NET_ERR("Prefix missing"); + return ret; + } + + if (ia_pd.status != DHCPV6_STATUS_SUCCESS || + ia_pd.iaprefix.status != DHCPV6_STATUS_SUCCESS) { + /* Ignore. */ + return 0; + } + } + + /* Valid advertisement received, store received offer. */ + memcpy(&iface->config.dhcpv6.serverid, &duid, + sizeof(iface->config.dhcpv6.serverid)); + iface->config.dhcpv6.server_preference = server_preference; + + /* DHCPv6 RFC8415, ch. 18.2.1, if client received Advertise + * message with maximum preference, or after the first + * retransmission period, it should proceed with the exchange, + * w/o further wait. + */ + if (server_preference == DHCPV6_MAX_SERVER_PREFERENCE || + iface->config.dhcpv6.retransmissions > 0) { + /* Reschedule immediately */ + dhcpv6_enter_state(iface, NET_DHCPV6_REQUESTING); + dhcpv6_reschedule(); + } + + return 0; +} + +static int dhcpv6_handle_reply(struct net_if *iface, struct net_pkt *pkt, + uint8_t *tid) +{ + struct net_dhcpv6_duid_storage duid = { 0 }; + struct dhcpv6_ia_pd ia_pd = { 0 }; + struct dhcpv6_ia_na ia_na = { 0 }; + int64_t now = k_uptime_get(); + uint16_t status = 0; + bool rediscover = false; + int ret; + + if (iface->config.dhcpv6.state != NET_DHCPV6_REQUESTING && + iface->config.dhcpv6.state != NET_DHCPV6_CONFIRMING && + iface->config.dhcpv6.state != NET_DHCPV6_RENEWING && + iface->config.dhcpv6.state != NET_DHCPV6_REBINDING) { + return -EINVAL; + } + + /* Verify client ID. */ + ret = dhcpv6_find_clientid(pkt, &duid); + if (ret < 0) { + NET_ERR("Client ID missing"); + return ret; + } + + if (iface->config.dhcpv6.clientid.length != duid.length || + memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, + iface->config.dhcpv6.clientid.length) != 0) { + NET_ERR("Client ID mismatch"); + return -EBADMSG; + } + + /* Verify server ID is present. */ + memset(&duid, 0, sizeof(duid)); + ret = dhcpv6_find_serverid(pkt, &duid); + if (ret < 0) { + NET_ERR("Server ID missing"); + return ret; + } + + /* Verify TID. */ + if (memcmp(iface->config.dhcpv6.tid, tid, + sizeof(iface->config.dhcpv6.tid)) != 0) { + NET_INFO("TID mismatch"); + return -EBADMSG; + } + + /* TODO Process SOL_MAX_RT/INF_MAX_RT options. */ + + /* Verify status code. */ + ret = dhcpv6_find_status_code(pkt, &status); + if (ret < 0) { + return ret; + } + + if (status == DHCPV6_STATUS_UNSPEC_FAIL) { + /* Ignore and try again later. */ + return 0; + } + + /* DHCPv6 RFC8415, ch. 18.2.10.1. If the client receives a NotOnLink + * status from the server in response to (...) Request, the client can + * either reissue the message without specifying any addresses or + * restart the DHCP server discovery process. + * + * Restart discovery for our case. + */ + if (iface->config.dhcpv6.state == NET_DHCPV6_REQUESTING && + status == DHCPV6_STATUS_NOT_ON_LINK) { + rediscover = true; + goto out; + } + + /* In case of Confirm Reply, status success indicates the client can + * still use the address. + */ + if (iface->config.dhcpv6.state == NET_DHCPV6_CONFIRMING) { + if (status != DHCPV6_STATUS_SUCCESS) { + rediscover = true; + } + + goto out; + } + + /* Find/verify address. */ + if (iface->config.dhcpv6.params.request_addr) { + ret = dhcpv6_find_ia_na(pkt, &ia_na); + if (ret < 0) { + NET_ERR("Address missing"); + return ret; + } + + if (iface->config.dhcpv6.addr_iaid != ia_na.iaid) { + return -EBADMSG; + } + } + + /* Find/verify prefix. */ + if (iface->config.dhcpv6.params.request_prefix) { + ret = dhcpv6_find_ia_pd(pkt, &ia_pd); + if (ret < 0) { + NET_ERR("Prefix missing"); + return ret; + } + + if (iface->config.dhcpv6.prefix_iaid != ia_pd.iaid) { + return -EBADMSG; + } + } + + /* Valid response received, store received data. */ + iface->config.dhcpv6.t1 = UINT64_MAX; + iface->config.dhcpv6.t2 = UINT64_MAX; + iface->config.dhcpv6.expire = now; + + if (iface->config.dhcpv6.params.request_addr) { + struct net_if_addr *ifaddr; + + if (ia_na.status == DHCPV6_STATUS_NO_ADDR_AVAIL || + ia_na.iaaddr.status == DHCPV6_STATUS_NO_ADDR_AVAIL || + ia_na.iaaddr.valid_lifetime == 0) { + /* Remove old lease. */ + net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); + memset(&iface->config.dhcpv6.addr, 0, sizeof(struct in6_addr)); + rediscover = true; + goto prefix; + } + + /* TODO On nobiding (renew/rebind) go to requesting */ + + if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, + net_ipv6_unspecified_address()) && + !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, + &ia_na.iaaddr.addr)) { + /* Remove old lease. */ + net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); + } + + memcpy(&iface->config.dhcpv6.addr, &ia_na.iaaddr.addr, + sizeof(iface->config.dhcpv6.addr)); + + dhcvp6_update_deadlines(iface, now, ia_na.t1, ia_na.t2, + ia_na.iaaddr.preferred_lifetime, + ia_na.iaaddr.valid_lifetime); + + ifaddr = net_if_ipv6_addr_lookup_by_iface(iface, &ia_na.iaaddr.addr); + if (ifaddr != NULL) { + net_if_ipv6_addr_update_lifetime( + ifaddr, ia_na.iaaddr.valid_lifetime); + } else if (net_if_ipv6_addr_add(iface, &ia_na.iaaddr.addr, NET_ADDR_DHCP, + ia_na.iaaddr.valid_lifetime) == NULL) { + NET_ERR("Failed to configure DHCPv6 address"); + net_dhcpv6_stop(iface); + return -EFAULT; + } + } + +prefix: + if (iface->config.dhcpv6.params.request_prefix) { + struct net_if_ipv6_prefix *ifprefix; + + if (ia_pd.status == DHCPV6_STATUS_NO_PREFIX_AVAIL || + ia_pd.iaprefix.status == DHCPV6_STATUS_NO_PREFIX_AVAIL || + ia_pd.iaprefix.valid_lifetime == 0) { + /* Remove old lease. */ + net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, + iface->config.dhcpv6.prefix_len); + memset(&iface->config.dhcpv6.prefix, 0, sizeof(struct in6_addr)); + iface->config.dhcpv6.prefix_len = 0; + rediscover = true; + goto out; + } + + if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, + net_ipv6_unspecified_address()) && + (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, + &ia_pd.iaprefix.prefix) || + iface->config.dhcpv6.prefix_len != ia_pd.iaprefix.prefix_len)) { + /* Remove old lease. */ + net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, + iface->config.dhcpv6.prefix_len); + } + + iface->config.dhcpv6.prefix_len = ia_pd.iaprefix.prefix_len; + + memcpy(&iface->config.dhcpv6.prefix, &ia_pd.iaprefix.prefix, + sizeof(iface->config.dhcpv6.prefix)); + + dhcvp6_update_deadlines(iface, now, ia_pd.t1, ia_pd.t2, + ia_pd.iaprefix.preferred_lifetime, + ia_pd.iaprefix.valid_lifetime); + + ifprefix = net_if_ipv6_prefix_lookup(iface, &ia_pd.iaprefix.prefix, + ia_pd.iaprefix.prefix_len); + if (ifprefix != NULL) { + net_if_ipv6_prefix_set_timer(ifprefix, ia_pd.iaprefix.valid_lifetime); + } else if (net_if_ipv6_prefix_add(iface, &ia_pd.iaprefix.prefix, + ia_pd.iaprefix.prefix_len, + ia_pd.iaprefix.valid_lifetime) == NULL) { + NET_ERR("Failed to configure DHCPv6 prefix"); + net_dhcpv6_stop(iface); + return -EFAULT; + } + } + +out: + if (rediscover) { + dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); + } else { + dhcpv6_enter_state(iface, NET_DHCPV6_BOUND); + } + + dhcpv6_reschedule(); + + return 0; +} + +static int dhcpv6_handle_reconfigure(struct net_if *iface, struct net_pkt *pkt) +{ + /* Reconfigure not supported yet. */ + return -ENOTSUP; +} + +static enum net_verdict dhcpv6_input(struct net_conn *conn, + struct net_pkt *pkt, + union net_ip_header *ip_hdr, + union net_proto_header *proto_hdr, + void *user_data) +{ + struct net_if *iface; + uint8_t msg_type; + uint8_t tid[DHCPV6_TID_SIZE]; + int ret; + + if (!conn) { + NET_ERR("Invalid connection"); + return NET_DROP; + } + + if (!pkt) { + NET_ERR("Invalid packet"); + return NET_DROP; + } + + iface = net_pkt_iface(pkt); + if (!iface) { + NET_ERR("No interface"); + return NET_DROP; + } + + net_pkt_cursor_init(pkt); + + if (net_pkt_skip(pkt, NET_IPV6UDPH_LEN)) { + NET_ERR("Missing IPv6/UDP header"); + return NET_DROP; + } + + if (net_pkt_read_u8(pkt, &msg_type) < 0) { + NET_ERR("Missing message type"); + return NET_DROP; + } + + if (net_pkt_read(pkt, tid, sizeof(tid)) < 0) { + NET_ERR("Missing transaction ID"); + return NET_DROP; + } + + NET_DBG("Received DHCPv6 packet [type=%d, tid=0x%02x%02x%02x]", + msg_type, tid[0], tid[1], tid[2]); + + switch (msg_type) { + case DHCPV6_MSG_TYPE_ADVERTISE: + ret = dhcpv6_handle_advertise(iface, pkt, tid); + break; + case DHCPV6_MSG_TYPE_REPLY: + ret = dhcpv6_handle_reply(iface, pkt, tid); + break; + case DHCPV6_MSG_TYPE_RECONFIGURE: + ret = dhcpv6_handle_reconfigure(iface, pkt); + break; + case DHCPV6_MSG_TYPE_SOLICIT: + case DHCPV6_MSG_TYPE_REQUEST: + case DHCPV6_MSG_TYPE_CONFIRM: + case DHCPV6_MSG_TYPE_RENEW: + case DHCPV6_MSG_TYPE_REBIND: + case DHCPV6_MSG_TYPE_RELEASE: + case DHCPV6_MSG_TYPE_DECLINE: + case DHCPV6_MSG_TYPE_INFORMATION_REQUEST: + case DHCPV6_MSG_TYPE_RELAY_FORW: + case DHCPV6_MSG_TYPE_RELAY_REPL: + default: + goto drop; + } + + if (ret < 0) { + goto drop; + } + + net_pkt_unref(pkt); + + return NET_OK; + +drop: + return NET_DROP; +} + +/* DHCPv6 timer management */ + +static uint64_t dhcpv6_timeleft(struct net_if *iface, int64_t now) +{ + uint64_t timeout = iface->config.dhcpv6.timeout; + + if (timeout > now) { + return timeout - now; + } + + return 0; +} + +static uint64_t dhcpv6_manage_timers(struct net_if *iface, int64_t now) +{ + uint64_t timeleft = dhcpv6_timeleft(iface, now); + + NET_DBG("iface %p state=%s timeleft=%llu", iface, + net_dhcpv6_state_name(iface->config.dhcpv6.state), timeleft); + + if (timeleft != 0U) { + return iface->config.dhcpv6.timeout; + } + + if (!net_if_is_up(iface)) { + /* An interface is down, the registered event handler will + * restart DHCP procedure when the interface is back up. + */ + return UINT64_MAX; + } + + switch (iface->config.dhcpv6.state) { + case NET_DHCPV6_DISABLED: + break; + case NET_DHCPV6_INIT: { + bool have_addr = false; + bool have_prefix = false; + + if (iface->config.dhcpv6.params.request_addr && + !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, + net_ipv6_unspecified_address())) { + have_addr = true; + } + + if (iface->config.dhcpv6.params.request_prefix && + !net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, + net_ipv6_unspecified_address())) { + have_prefix = true; + } + + if ((have_addr || have_prefix) && now < iface->config.dhcpv6.expire) { + /* Try to confirm the address/prefix. In case + * prefix is requested, Rebind is used with + * Confirm timings. + */ + iface->config.dhcpv6.expire = now + DHCPV6_CNF_MAX_RD; + + if (!iface->config.dhcpv6.params.request_prefix) { + dhcpv6_enter_state(iface, NET_DHCPV6_CONFIRMING); + } else { + dhcpv6_enter_state(iface, NET_DHCPV6_REBINDING); + } + } else { + dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); + } + + return iface->config.dhcpv6.timeout; + } + case NET_DHCPV6_SOLICITING: + if (iface->config.dhcpv6.server_preference >= 0) { + dhcpv6_enter_state(iface, NET_DHCPV6_REQUESTING); + return iface->config.dhcpv6.timeout; + } + + iface->config.dhcpv6.retransmissions++; + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_next_retransmit_time( + iface->config.dhcpv6.retransmit_timeout, + DHCPV6_SOL_MAX_RT); + + (void)dhcpv6_send_solicit(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); + + return iface->config.dhcpv6.timeout; + case NET_DHCPV6_REQUESTING: + if (iface->config.dhcpv6.retransmissions >= DHCPV6_REQ_MAX_RC) { + /* Back to soliciting. */ + dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); + return iface->config.dhcpv6.timeout; + } + + iface->config.dhcpv6.retransmissions++; + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_next_retransmit_time( + iface->config.dhcpv6.retransmit_timeout, + DHCPV6_REQ_MAX_RT); + + (void)dhcpv6_send_request(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); + + return iface->config.dhcpv6.timeout; + case NET_DHCPV6_CONFIRMING: + if (now >= iface->config.dhcpv6.expire) { + dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); + return iface->config.dhcpv6.timeout; + } + + iface->config.dhcpv6.retransmissions++; + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_next_retransmit_time( + iface->config.dhcpv6.retransmit_timeout, + DHCPV6_CNF_MAX_RT); + + (void)dhcpv6_send_confirm(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); + + if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { + iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; + } + + return iface->config.dhcpv6.timeout; + case NET_DHCPV6_RENEWING: + if (now >= iface->config.dhcpv6.t2) { + dhcpv6_enter_state(iface, NET_DHCPV6_REBINDING); + return iface->config.dhcpv6.timeout; + } + + iface->config.dhcpv6.retransmissions++; + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_next_retransmit_time( + iface->config.dhcpv6.retransmit_timeout, + DHCPV6_REN_MAX_RT); + + (void)dhcpv6_send_renew(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); + + if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.t2) { + iface->config.dhcpv6.timeout = iface->config.dhcpv6.t2; + } + + return iface->config.dhcpv6.timeout; + case NET_DHCPV6_REBINDING: + if (now >= iface->config.dhcpv6.expire) { + dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); + return iface->config.dhcpv6.timeout; + } + + iface->config.dhcpv6.retransmissions++; + iface->config.dhcpv6.retransmit_timeout = + dhcpv6_next_retransmit_time( + iface->config.dhcpv6.retransmit_timeout, + DHCPV6_REB_MAX_RT); + + (void)dhcpv6_send_rebind(iface); + dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); + + if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { + iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; + } + + return iface->config.dhcpv6.timeout; + case NET_DHCPV6_INFO_REQUESTING: + break; + case NET_DHCPV6_BOUND: + dhcpv6_enter_state(iface, NET_DHCPV6_RENEWING); + return iface->config.dhcpv6.timeout; + } + + return UINT64_MAX; +} + +static void dhcpv6_timeout(struct k_work *work) +{ + uint64_t timeout_update = UINT64_MAX; + int64_t now = k_uptime_get(); + struct net_if_dhcpv6 *current, *next; + + ARG_UNUSED(work); + + k_mutex_lock(&lock, K_FOREVER); + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dhcpv6_ifaces, current, next, node) { + struct net_if *iface = CONTAINER_OF( + CONTAINER_OF(current, struct net_if_config, dhcpv6), + struct net_if, config); + uint64_t next_timeout; + + next_timeout = dhcpv6_manage_timers(iface, now); + if (next_timeout < timeout_update) { + timeout_update = next_timeout; + } + } + + k_mutex_unlock(&lock); + + if (timeout_update != UINT64_MAX) { + if (now > timeout_update) { + timeout_update = 0ULL; + } else { + timeout_update -= now; + } + + NET_DBG("Waiting for %llums", timeout_update); + k_work_reschedule(&dhcpv6_timeout_work, K_MSEC(timeout_update)); + } +} + +static void dhcpv6_iface_event_handler(struct net_mgmt_event_callback *cb, + uint32_t mgmt_event, struct net_if *iface) +{ + sys_snode_t *node = NULL; + + k_mutex_lock(&lock, K_FOREVER); + + SYS_SLIST_FOR_EACH_NODE(&dhcpv6_ifaces, node) { + if (node == &iface->config.dhcpv6.node) { + break; + } + } + + if (node == NULL) { + goto out; + } + + if (mgmt_event == NET_EVENT_IF_DOWN) { + NET_DBG("Interface %p going down", iface); + dhcpv6_set_timeout(iface, UINT64_MAX); + } else if (mgmt_event == NET_EVENT_IF_UP) { + NET_DBG("Interface %p coming up", iface); + dhcpv6_enter_state(iface, NET_DHCPV6_INIT); + } + + dhcpv6_reschedule(); + +out: + k_mutex_unlock(&lock); +} + +static void dhcpv6_generate_client_duid(struct net_if *iface) +{ + struct net_linkaddr *lladdr = net_if_get_link_addr(iface); + struct net_dhcpv6_duid_storage *clientid = &iface->config.dhcpv6.clientid; + struct dhcpv6_duid_ll *duid_ll = + (struct dhcpv6_duid_ll *)&clientid->duid.buf; + + memset(clientid, 0, sizeof(*clientid)); + + UNALIGNED_PUT(htons(DHCPV6_DUID_TYPE_LL), &clientid->duid.type); + UNALIGNED_PUT(htons(DHCPV6_HARDWARE_ETHERNET_TYPE), &duid_ll->hw_type); + memcpy(duid_ll->ll_addr, lladdr->addr, lladdr->len); + + clientid->length = DHCPV6_DUID_LL_HEADER_SIZE + lladdr->len; +} + +/* DHCPv6 public API */ + +void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) +{ + k_mutex_lock(&lock, K_FOREVER); + + if (iface->config.dhcpv6.state != NET_DHCPV6_DISABLED) { + NET_ERR("DHCPv6 already running on iface %p, state %s", iface, + net_dhcpv6_state_name(iface->config.dhcpv6.state)); + goto out; + } + + if (!params->request_addr && !params->request_addr) { + NET_ERR("Information Request not supported yet"); + goto out; + } + + NET_DBG("Starting DHCPv6 on iface %p", iface); + + iface->config.dhcpv6.params = *params; + + if (sys_slist_is_empty(&dhcpv6_ifaces)) { + net_mgmt_add_event_callback(&dhcpv6_mgmt_cb); + } + + sys_slist_append(&dhcpv6_ifaces, &iface->config.dhcpv6.node); + + if (params->request_addr) { + iface->config.dhcpv6.addr_iaid = net_if_get_by_iface(iface); + } + + if (params->request_prefix) { + iface->config.dhcpv6.prefix_iaid = net_if_get_by_iface(iface); + } + + dhcpv6_generate_client_duid(iface); + dhcpv6_enter_state(iface, NET_DHCPV6_INIT); + dhcpv6_reschedule(); + +out: + k_mutex_unlock(&lock); +} + +void net_dhcpv6_stop(struct net_if *iface) +{ + k_mutex_lock(&lock, K_FOREVER); + + switch (iface->config.dhcpv6.state) { + case NET_DHCPV6_DISABLED: + NET_INFO("DHCPv6 already disabled on iface %p", iface); + break; + + case NET_DHCPV6_INIT: + case NET_DHCPV6_SOLICITING: + case NET_DHCPV6_REQUESTING: + case NET_DHCPV6_CONFIRMING: + case NET_DHCPV6_RENEWING: + case NET_DHCPV6_REBINDING: + case NET_DHCPV6_INFO_REQUESTING: + case NET_DHCPV6_BOUND: + NET_DBG("Stopping DHCPv6 on iface %p, state %s", iface, + net_dhcpv6_state_name(iface->config.dhcpv6.state)); + + (void)dhcpv6_enter_state(iface, NET_DHCPV6_DISABLED); + + sys_slist_find_and_remove(&dhcpv6_ifaces, + &iface->config.dhcpv6.node); + + if (sys_slist_is_empty(&dhcpv6_ifaces)) { + (void)k_work_cancel_delayable(&dhcpv6_timeout_work); + net_mgmt_del_event_callback(&dhcpv6_mgmt_cb); + } + + break; + } + + k_mutex_unlock(&lock); +} + +void net_dhcpv6_restart(struct net_if *iface) +{ + struct net_dhcpv6_params params = iface->config.dhcpv6.params; + + net_dhcpv6_stop(iface); + net_dhcpv6_start(iface, ¶ms); +} + +int net_dhcpv6_init(void) +{ + struct sockaddr unspec_addr; + int ret; + + net_ipaddr_copy(&net_sin6(&unspec_addr)->sin6_addr, + net_ipv6_unspecified_address()); + unspec_addr.sa_family = AF_INET6; + + ret = net_udp_register(AF_INET6, NULL, &unspec_addr, + DHCPV6_SERVER_PORT, DHCPV6_CLIENT_PORT, + NULL, dhcpv6_input, NULL, NULL); + if (ret < 0) { + NET_DBG("UDP callback registration failed"); + return ret; + } + + k_work_init_delayable(&dhcpv6_timeout_work, dhcpv6_timeout); + net_mgmt_init_event_callback(&dhcpv6_mgmt_cb, dhcpv6_iface_event_handler, + NET_EVENT_IF_DOWN | NET_EVENT_IF_UP); + + return 0; +} diff --git a/subsys/net/ip/dhcpv6_internal.h b/subsys/net/ip/dhcpv6_internal.h new file mode 100644 index 00000000000..5ec129e601f --- /dev/null +++ b/subsys/net/ip/dhcpv6_internal.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief DHCPv6 internal header + * + * This header should not be included by the application. + */ + +#ifndef DHCPV6_INTERNAL_H_ +#define DHCPV6_INTERNAL_H_ + +#include + +#define DHCPV6_DUID_TYPE_SIZE 2 +#define DHVPV6_DUID_LL_HW_TYPE_SIZE 2 +#define DHCPV6_DUID_LL_HEADER_SIZE (DHCPV6_DUID_TYPE_SIZE + \ + DHVPV6_DUID_LL_HW_TYPE_SIZE) + +#define DHCPV6_MSG_TYPE_SIZE 1 +#define DHCPV6_HEADER_SIZE (DHCPV6_MSG_TYPE_SIZE + DHCPV6_TID_SIZE) + +#define DHCPV6_OPTION_CODE_SIZE 2 +#define DHCPV6_OPTION_LENGTH_SIZE 2 +#define DHCPV6_OPTION_HEADER_SIZE (DHCPV6_OPTION_CODE_SIZE + \ + DHCPV6_OPTION_LENGTH_SIZE) + +#define DHCPV6_OPTION_PREFERENCE_SIZE 1 +#define DHCPV6_OPTION_ELAPSED_TIME_SIZE 2 +#define DHCPV6_OPTION_ELAPSED_TIME_SIZE 2 +#define DHCPV6_OPTION_IA_NA_HEADER_SIZE 12 +#define DHCPV6_OPTION_IAADDR_HEADER_SIZE 24 +#define DHCPV6_OPTION_IA_PD_HEADER_SIZE 12 +#define DHCPV6_OPTION_IAPREFIX_HEADER_SIZE 25 +#define DHCPV6_OPTION_IAADDR_HEADER_SIZE 24 +#define DHCPV6_OPTION_IAPREFIX_HEADER_SIZE 25 +#define DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE 2 + +#define DHCPV6_INFINITY UINT32_MAX +#define DHCPV6_MAX_SERVER_PREFERENCE 255 + +#define DHCPV6_HARDWARE_ETHERNET_TYPE 1 + +#define DHCPV6_CLIENT_PORT 546 +#define DHCPV6_SERVER_PORT 547 + +/* DHCPv6 Transmission/retransmission timeouts */ +#define DHCPV6_SOL_MAX_DELAY 1000 /* Max delay of first Solicit, milliseconds */ +#define DHCPV6_SOL_TIMEOUT 1000 /* Initial Solicit timeout, milliseconds */ +#define DHCPV6_SOL_MAX_RT 3600000 /* Max Solicit timeout value, milliseconds */ +#define DHCPV6_REQ_TIMEOUT 1000 /* Initial Request timeout, milliseconds */ +#define DHCPV6_REQ_MAX_RT 30000 /* Max Request timeout value, milliseconds */ +#define DHCPV6_REQ_MAX_RC 10 /* Max Request retry attempts */ +#define DHCPV6_CNF_MAX_DELAY 1000 /* Max delay of first Confirm, milliseconds */ +#define DHCPV6_CNF_TIMEOUT 1000 /* Initial Confirm timeout, milliseconds */ +#define DHCPV6_CNF_MAX_RT 4000 /* Max Confirm timeout, milliseconds */ +#define DHCPV6_CNF_MAX_RD 10000 /* Max Confirm duration, milliseconds */ +#define DHCPV6_REN_TIMEOUT 10000 /* Initial Renew timeout, milliseconds */ +#define DHCPV6_REN_MAX_RT 600000 /* Max Renew timeout value, milliseconds */ +#define DHCPV6_REB_TIMEOUT 10000 /* Initial Rebind timeout, milliseconds */ +#define DHCPV6_REB_MAX_RT 600000 /* Max Rebind timeout value, milliseconds */ + +/* DUID structures */ +struct dhcpv6_duid_llt { + uint16_t hw_type; + uint32_t time; + uint8_t ll_addr[]; +} __packed; + +struct dhcpv6_duid_en { + uint32_t enterprise_number; + uint8_t identifier[]; +} __packed; + +struct dhcpv6_duid_ll { + uint16_t hw_type; + uint8_t ll_addr[]; +} __packed; + +struct dhcpv6_duid_uuid { + uint8_t uuid[16]; +} __packed; + +struct dhcpv6_msg_hdr { + uint8_t type; /* Message type */ + uint8_t tid[3]; /* Transaction ID */ +} __packed; + +struct dhcpv6_iaaddr { + uint32_t preferred_lifetime; + uint32_t valid_lifetime; + struct in6_addr addr; + uint16_t status; +}; + +struct dhcpv6_ia_na { + uint32_t iaid; + uint32_t t1; + uint32_t t2; + uint16_t status; + struct dhcpv6_iaaddr iaaddr; +}; + +struct dhcpv6_iaprefix { + uint32_t preferred_lifetime; + uint32_t valid_lifetime; + struct in6_addr prefix; + uint8_t prefix_len; + uint16_t status; +}; + +struct dhcpv6_ia_pd { + uint32_t iaid; + uint32_t t1; + uint32_t t2; + uint16_t status; + struct dhcpv6_iaprefix iaprefix; +}; + +/* DHCPv6 message types, RFC8415, ch. 7.3. */ +enum dhcpv6_msg_type { + DHCPV6_MSG_TYPE_SOLICIT = 1, + DHCPV6_MSG_TYPE_ADVERTISE = 2, + DHCPV6_MSG_TYPE_REQUEST = 3, + DHCPV6_MSG_TYPE_CONFIRM = 4, + DHCPV6_MSG_TYPE_RENEW = 5, + DHCPV6_MSG_TYPE_REBIND = 6, + DHCPV6_MSG_TYPE_REPLY = 7, + DHCPV6_MSG_TYPE_RELEASE = 8, + DHCPV6_MSG_TYPE_DECLINE = 9, + DHCPV6_MSG_TYPE_RECONFIGURE = 10, + DHCPV6_MSG_TYPE_INFORMATION_REQUEST = 11, + DHCPV6_MSG_TYPE_RELAY_FORW = 12, + DHCPV6_MSG_TYPE_RELAY_REPL = 13, +}; + +/* DHCPv6 option codes, RFC8415, ch. 21. */ +enum dhcpv6_option_code { + DHCPV6_OPTION_CODE_CLIENTID = 1, + DHCPV6_OPTION_CODE_SERVERID = 2, + DHCPV6_OPTION_CODE_IA_NA = 3, + DHCPV6_OPTION_CODE_IA_TA = 4, + DHCPV6_OPTION_CODE_IAADDR = 5, + DHCPV6_OPTION_CODE_ORO = 6, + DHCPV6_OPTION_CODE_PREFERENCE = 7, + DHCPV6_OPTION_CODE_ELAPSED_TIME = 8, + DHCPV6_OPTION_CODE_RELAY_MSG = 9, + DHCPV6_OPTION_CODE_AUTH = 11, + DHCPV6_OPTION_CODE_UNICAST = 12, + DHCPV6_OPTION_CODE_STATUS_CODE = 13, + DHCPV6_OPTION_CODE_RAPID_COMMIT = 14, + DHCPV6_OPTION_CODE_USER_CLASS = 15, + DHCPV6_OPTION_CODE_VENDOR_CLASS = 16, + DHCPV6_OPTION_CODE_VENDOR_OPTS = 17, + DHCPV6_OPTION_CODE_INTERFACE_ID = 18, + DHCPV6_OPTION_CODE_RECONF_MSG = 19, + DHCPV6_OPTION_CODE_RECONF_ACCEPT = 20, + DHCPV6_OPTION_CODE_IA_PD = 25, + DHCPV6_OPTION_CODE_IAPREFIX = 26, + DHCPV6_OPTION_CODE_INFORMATION_REFRESH_TIME = 32, + DHCPV6_OPTION_CODE_SOL_MAX_RT = 82, + DHCPV6_OPTION_CODE_INF_MAX_RT = 83, +}; + +/* DHCPv6 option codes, RFC8415, ch. 21.13. */ +enum dhcpv6_status_code { + DHCPV6_STATUS_SUCCESS = 0, + DHCPV6_STATUS_UNSPEC_FAIL = 1, + DHCPV6_STATUS_NO_ADDR_AVAIL = 2, + DHCPV6_STATUS_NO_BINDING = 3, + DHCPV6_STATUS_NOT_ON_LINK = 4, + DHCPV6_STATUS_USE_MULTICAST = 5, + DHCPV6_STATUS_NO_PREFIX_AVAIL = 6, +}; + +/* DHCPv6 Unique Identifier types, RFC8415, ch. 11.1. */ +enum dhcpv6_duid_type { + DHCPV6_DUID_TYPE_LLT = 1, /* Based on Link-Layer Address Plus Time */ + DHCPV6_DUID_TYPE_EN = 2, /* Assigned by Vendor Based on Enterprise Number */ + DHCPV6_DUID_TYPE_LL = 3, /* Based on Link-Layer Address */ + DHCPV6_DUID_TYPE_UUID = 4, /* Based on Universally Unique Identifier */ +}; + +#if defined(CONFIG_NET_DHCPV6) +int net_dhcpv6_init(void); +#else +static inline int net_dhcpv6_init(void) +{ + return 0; +} +#endif /* CONFIG_NET_DHCPV6 */ + +#endif /* DHCPV6_INTERNAL_H_ */ diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 00829dfcf90..c94607b4485 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -45,6 +45,7 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL); #include "ipv4.h" #include "dhcpv4.h" +#include "dhcpv6_internal.h" #include "route.h" @@ -475,6 +476,11 @@ static inline int services_init(void) return status; } + status = net_dhcpv6_init(); + if (status != 0) { + return status; + } + dns_init_resolver(); websocket_init(); From afa5887b700db5d6aef773ea07e5ceb1bde4c9c1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 23 Aug 2023 13:41:25 +0200 Subject: [PATCH 1217/4498] net: dhcpv6: Introduce net events for DHCPv6 Add net events for DHCPv6, in similar fashion as it's done for DHCPv4. Signed-off-by: Robert Lubos --- include/zephyr/net/net_event.h | 12 ++++++++++++ subsys/net/ip/dhcpv6.c | 8 ++++++++ subsys/net/ip/net_private.h | 3 +++ 3 files changed, 23 insertions(+) diff --git a/include/zephyr/net/net_event.h b/include/zephyr/net/net_event.h index 819a5ae6639..34856aec6af 100644 --- a/include/zephyr/net/net_event.h +++ b/include/zephyr/net/net_event.h @@ -79,6 +79,9 @@ enum net_event_ipv6_cmd { NET_EVENT_IPV6_CMD_DAD_FAILED, NET_EVENT_IPV6_CMD_NBR_ADD, NET_EVENT_IPV6_CMD_NBR_DEL, + NET_EVENT_IPV6_CMD_DHCP_START, + NET_EVENT_IPV6_CMD_DHCP_BOUND, + NET_EVENT_IPV6_CMD_DHCP_STOP, }; #define NET_EVENT_IPV6_ADDR_ADD \ @@ -129,6 +132,15 @@ enum net_event_ipv6_cmd { #define NET_EVENT_IPV6_NBR_DEL \ (_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_NBR_DEL) +#define NET_EVENT_IPV6_DHCP_START \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_START) + +#define NET_EVENT_IPV6_DHCP_BOUND \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_BOUND) + +#define NET_EVENT_IPV6_DHCP_STOP \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_STOP) + /* IPv4 Events*/ #define _NET_IPV4_LAYER NET_MGMT_LAYER_L3 #define _NET_IPV4_CORE_CODE 0x004 diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index 040c9fa0e06..6fae4f320bf 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -1374,6 +1374,10 @@ static void dhcpv6_enter_confirming(struct net_if *iface) static void dhcpv6_enter_bound(struct net_if *iface) { iface->config.dhcpv6.timeout = iface->config.dhcpv6.t1; + + net_mgmt_event_notify_with_info(NET_EVENT_IPV6_DHCP_BOUND, iface, + &iface->config.dhcpv6, + sizeof(iface->config.dhcpv6)); } static void dhcpv6_enter_state(struct net_if *iface, enum net_dhcpv6_state state) @@ -2101,6 +2105,8 @@ void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) goto out; } + net_mgmt_event_notify(NET_EVENT_IPV6_DHCP_START, iface); + NET_DBG("Starting DHCPv6 on iface %p", iface); iface->config.dhcpv6.params = *params; @@ -2160,6 +2166,8 @@ void net_dhcpv6_stop(struct net_if *iface) break; } + net_mgmt_event_notify(NET_EVENT_IPV6_DHCP_STOP, iface); + k_mutex_unlock(&lock); } diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 0f573ca1257..ea37cd09b6b 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -30,6 +30,9 @@ union net_mgmt_events { #if defined(CONFIG_NET_DHCPV4) struct net_if_dhcpv4 dhcpv4; #endif /* CONFIG_NET_DHCPV4 */ +#if defined(CONFIG_NET_DHCPV6) + struct net_if_dhcpv6 dhcpv6; +#endif /* CONFIG_NET_DHCPV6 */ #if defined(CONFIG_NET_L2_WIFI_MGMT) union wifi_mgmt_events wifi; #endif /* CONFIG_NET_L2_WIFI_MGMT */ From 72cf06ada44992d018cd4675292f6395ad2b0710 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 23 Aug 2023 13:41:32 +0200 Subject: [PATCH 1218/4498] net: config: Add DHCPv6 support Add DHCPv6 support to the net config library. In case DHCPv6 is enabled, net config will attempt to acquire IPv6 address and/or prefix when used. The user can select with Kconfig whether to request address or prefix (or both). Signed-off-by: Robert Lubos --- subsys/net/lib/config/Kconfig | 17 +++++++++++++ subsys/net/lib/config/init.c | 46 +++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/subsys/net/lib/config/Kconfig b/subsys/net/lib/config/Kconfig index 7d8ceb88c14..58895881ef4 100644 --- a/subsys/net/lib/config/Kconfig +++ b/subsys/net/lib/config/Kconfig @@ -195,6 +195,23 @@ config NET_CONFIG_BT_NODE endif # NET_CONFIG_SETTINGS +if NET_DHCPV6 + +config NET_CONFIG_DHCPV6_REQUEST_ADDR + bool "Request IPv6 address when configuring DHCPv6 client" + default y + help + When DHCPv6 is enabled this will configure the DHCPv6 client to + request IPv6 address from the DHCPv6 server. + +config NET_CONFIG_DHCPV6_REQUEST_PREFIX + bool "Request IPv6 prefix when configuring DHCPv6 client" + help + When DHCPv6 is enabled this will configure the DHCPv6 client to + request IPv6 prefix from the DHCPv6 server. + +endif # NET_DHCPV6 + config NET_CONFIG_CLOCK_SNTP_INIT bool "Initialize system clock using SNTP on application startup" depends on SNTP && POSIX_CLOCK diff --git a/subsys/net/lib/config/init.c b/subsys/net/lib/config/init.c index 5e5cf449b22..192cd3f5685 100644 --- a/subsys/net/lib/config/init.c +++ b/subsys/net/lib/config/init.c @@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(net_config, CONFIG_NET_CONFIG_LOG_LEVEL); #include #include #include +#include #include #include @@ -203,8 +204,26 @@ static void setup_ipv4(struct net_if *iface) #endif /* CONFIG_NET_IPV4 && !CONFIG_NET_DHCPV4 */ #if defined(CONFIG_NET_NATIVE_IPV6) -#if !defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR) -#error "You need to define an IPv6 address!" + +#if defined(CONFIG_NET_DHCPV6) +static void setup_dhcpv6(struct net_if *iface) +{ + struct net_dhcpv6_params params = { + .request_addr = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR), + .request_prefix = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_PREFIX), + }; + + NET_INFO("Running dhcpv6 client..."); + + net_dhcpv6_start(iface, ¶ms); +} +#else /* CONFIG_NET_DHCPV6 */ +#define setup_dhcpv6(...) +#endif /* CONFIG_NET_DHCPV6 */ + +#if !defined(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR) && \ + !defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR) +#error "You need to define an IPv6 address or enable DHCPv6!" #endif static struct net_mgmt_event_callback mgmt6_cb; @@ -249,6 +268,21 @@ static void ipv6_event_handler(struct net_mgmt_event_callback *cb, #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF NET_INFO("IPv6 address: %s", net_addr_ntop(AF_INET6, &laddr, hr_addr, NET_IPV6_ADDR_LEN)); + + if (ifaddr->addr_type == NET_ADDR_DHCP) { + char remaining_str[] = "infinite"; + uint32_t remaining; + + remaining = net_timeout_remaining(&ifaddr->lifetime, + k_uptime_get_32()); + + if (!ifaddr->is_infinite) { + snprintk(remaining_str, sizeof(remaining_str), + "%u", remaining); + } + + NET_INFO("Lifetime: %s seconds", remaining_str); + } #endif services_notify_ready(NET_CONFIG_NEED_IPV6); @@ -264,6 +298,9 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) struct net_if_addr *ifaddr; uint32_t mask = NET_EVENT_IPV6_DAD_SUCCEED; + net_mgmt_init_event_callback(&mgmt6_cb, ipv6_event_handler, mask); + net_mgmt_add_event_callback(&mgmt6_cb); + if (sizeof(CONFIG_NET_CONFIG_MY_IPV6_ADDR) == 1) { /* Empty address, skip setting ANY address in this case */ goto exit; @@ -279,9 +316,6 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) mask |= NET_EVENT_IPV6_ROUTER_ADD; } - net_mgmt_init_event_callback(&mgmt6_cb, ipv6_event_handler, mask); - net_mgmt_add_event_callback(&mgmt6_cb); - /* * check for CMD_ADDR_ADD bit here, NET_EVENT_IPV6_ADDR_ADD is * a combination of _NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_ADDR_ADD @@ -310,6 +344,7 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) #else #define setup_ipv6(...) +#define setup_dhcpv6(...) #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_NATIVE) @@ -408,6 +443,7 @@ int net_config_init_by_iface(struct net_if *iface, const char *app_info, setup_ipv4(iface); setup_dhcpv4(iface); setup_ipv6(iface, flags); + setup_dhcpv6(iface); /* Network interface did not come up. */ if (timeout > 0 && count < 0) { From 6fb19bc7f03cdbae897b09c3718722853a86b8b3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 23 Aug 2023 13:43:49 +0200 Subject: [PATCH 1219/4498] net: shell: Add DHCPv6 support Print DHCPv6 status in net shell (with "net iface" command). Signed-off-by: Robert Lubos --- subsys/net/ip/net_shell.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index c5b07afd6aa..e7af6e16632 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -719,6 +719,19 @@ static void iface_cb(struct net_if *iface, void *user_data) iface->config.dhcpv4.attempts); #endif /* CONFIG_NET_DHCPV4 */ +#if defined(CONFIG_NET_DHCPV6) + PR("DHCPv6 address requested : %s\n", + iface->config.dhcpv6.params.request_addr ? + net_sprint_ipv6_addr(&iface->config.dhcpv6.addr) : "none"); + PR("DHCPv6 prefix requested : %s\n", + iface->config.dhcpv6.params.request_prefix ? + net_sprint_ipv6_addr(&iface->config.dhcpv6.prefix) : "none"); + PR("DHCPv6 state : %s\n", + net_dhcpv6_state_name(iface->config.dhcpv6.state)); + PR("DHCPv6 attempts : %d\n", + iface->config.dhcpv6.retransmissions + 1); +#endif /* CONFIG_NET_DHCPV6 */ + #else ARG_UNUSED(iface); ARG_UNUSED(user_data); @@ -2513,6 +2526,29 @@ static char *get_l3_desc(struct event_msg *msg, info = net_addr_ntop(AF_INET6, msg->data, extra_info, extra_info_len); break; + case NET_EVENT_IPV6_DHCP_START: + *desc = "DHCPv6"; + *desc2 = "start"; + break; + case NET_EVENT_IPV6_DHCP_BOUND: + *desc = "DHCPv6"; + *desc2 = "bound"; +#if defined(CONFIG_NET_DHCPV6) + struct net_if_dhcpv6 *data = (struct net_if_dhcpv6 *)msg->data; + + if (data->params.request_addr) { + info = net_addr_ntop(AF_INET6, &data->addr, extra_info, + extra_info_len); + } else if (data->params.request_prefix) { + info = net_addr_ntop(AF_INET6, &data->prefix, extra_info, + extra_info_len); + } +#endif + break; + case NET_EVENT_IPV6_DHCP_STOP: + *desc = "DHCPv6"; + *desc2 = "stop"; + break; case NET_EVENT_IPV4_ADDR_ADD: *desc = "IPv4 address"; *desc2 = "add"; From d9f4c1cff0ab615a347bdae02c996af45f22dc08 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 27 Sep 2023 17:51:18 +0200 Subject: [PATCH 1220/4498] tests: net: dhcpv6: Add tests Add tests for the DHCPv6 library. The tests verify that: * message format is valid for the outgoing messages * incoming messages are only processed in respective states * processing through standard DHCPv6 transactions is correct (Solicit/Confirm/Renew/Rebind) Signed-off-by: Robert Lubos --- tests/net/dhcpv6/CMakeLists.txt | 12 + tests/net/dhcpv6/prj.conf | 18 + tests/net/dhcpv6/src/main.c | 1267 +++++++++++++++++++++++++++++++ tests/net/dhcpv6/testcase.yaml | 10 + 4 files changed, 1307 insertions(+) create mode 100644 tests/net/dhcpv6/CMakeLists.txt create mode 100644 tests/net/dhcpv6/prj.conf create mode 100644 tests/net/dhcpv6/src/main.c create mode 100644 tests/net/dhcpv6/testcase.yaml diff --git a/tests/net/dhcpv6/CMakeLists.txt b/tests/net/dhcpv6/CMakeLists.txt new file mode 100644 index 00000000000..82400500ea7 --- /dev/null +++ b/tests/net/dhcpv6/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(dhcpv6) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) +target_sources(app PRIVATE src/main.c) + +zephyr_compile_definitions(CONFIG_NET_DHCPV6) +zephyr_compile_definitions(CONFIG_NET_DHCPV6_LOG_LEVEL=LOG_LEVEL_ERR) diff --git a/tests/net/dhcpv6/prj.conf b/tests/net/dhcpv6/prj.conf new file mode 100644 index 00000000000..0992b9f1d90 --- /dev/null +++ b/tests/net/dhcpv6/prj.conf @@ -0,0 +1,18 @@ +CONFIG_NET_TEST=y +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING=y +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_IPV6=y +CONFIG_NET_IPV6_ND=n +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_UDP=y +CONFIG_NET_TC_TX_COUNT=1 + +CONFIG_NET_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y diff --git a/tests/net/dhcpv6/src/main.c b/tests/net/dhcpv6/src/main.c new file mode 100644 index 00000000000..80046c96ec9 --- /dev/null +++ b/tests/net/dhcpv6/src/main.c @@ -0,0 +1,1267 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "../../../subsys/net/ip/dhcpv6.c" + +static struct in6_addr test_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x1 } } }; +static struct in6_addr test_prefix = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 } } }; +static uint8_t test_prefix_len = 64; +static uint8_t test_preference; +static struct net_dhcpv6_duid_storage test_serverid; + +typedef void (*test_dhcpv6_pkt_fn_t)(struct net_if *iface, + struct net_pkt *pkt); + +typedef int (*test_dhcpv6_options_fn_t)(struct net_if *iface, + struct net_pkt *pkt, + enum dhcpv6_msg_type msg_type); + +struct test_dhcpv6_context { + uint8_t mac[sizeof(struct net_eth_addr)]; + struct net_if *iface; + test_dhcpv6_pkt_fn_t test_fn; + struct k_sem tx_sem; + struct k_sem exchange_complete_sem; + bool reset_dhcpv6; +}; + +struct test_dhcpv6_context test_ctx; + +static void test_iface_init(struct net_if *iface) +{ + struct test_dhcpv6_context *ctx = net_if_get_device(iface)->data; + + /* Generate and assign MAC. */ + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + ctx->mac[0] = 0x00; + ctx->mac[1] = 0x00; + ctx->mac[2] = 0x5E; + ctx->mac[3] = 0x00; + ctx->mac[4] = 0x53; + ctx->mac[5] = 0x00; + + net_if_set_link_addr(iface, ctx->mac, sizeof(ctx->mac), NET_LINK_ETHERNET); +} + +static int test_send(const struct device *dev, struct net_pkt *pkt) +{ + struct test_dhcpv6_context *ctx = dev->data; + + if (ctx->test_fn != NULL) { + ctx->test_fn(net_pkt_iface(pkt), pkt); + } + + k_sem_give(&ctx->tx_sem); + + return 0; +} + +static struct dummy_api test_if_api = { + .iface_api.init = test_iface_init, + .send = test_send, +}; + +NET_DEVICE_INIT(test_dhcpv6, "test_dhcpv6", NULL, NULL, &test_ctx, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &test_if_api, + DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), NET_IPV6_MTU); + +static void set_dhcpv6_test_fn(test_dhcpv6_pkt_fn_t test_fn) +{ + test_ctx.test_fn = test_fn; +} + +static void set_test_addr_on_iface(struct net_if *iface) +{ + memcpy(&test_ctx.iface->config.dhcpv6.addr, &test_addr, + sizeof(test_ctx.iface->config.dhcpv6.addr)); + memcpy(&test_ctx.iface->config.dhcpv6.prefix, &test_prefix, + sizeof(test_ctx.iface->config.dhcpv6.prefix)); + test_ctx.iface->config.dhcpv6.prefix_len = test_prefix_len; +} + +static void clear_test_addr_on_iface(struct net_if *iface) +{ + memset(&test_ctx.iface->config.dhcpv6.addr, 0, + sizeof(test_ctx.iface->config.dhcpv6.addr)); + memset(&test_ctx.iface->config.dhcpv6.prefix, 0, + sizeof(test_ctx.iface->config.dhcpv6.prefix)); + test_ctx.iface->config.dhcpv6.prefix_len = 0; +} + +static void generate_fake_server_duid(void) +{ + struct net_dhcpv6_duid_storage *serverid = &test_serverid; + struct dhcpv6_duid_ll *duid_ll = + (struct dhcpv6_duid_ll *)&serverid->duid.buf; + uint8_t fake_mac[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + memset(serverid, 0, sizeof(*serverid)); + + UNALIGNED_PUT(htons(DHCPV6_DUID_TYPE_LL), &serverid->duid.type); + UNALIGNED_PUT(htons(DHCPV6_HARDWARE_ETHERNET_TYPE), &duid_ll->hw_type); + memcpy(duid_ll->ll_addr, fake_mac, sizeof(fake_mac)); + + serverid->length = DHCPV6_DUID_LL_HEADER_SIZE + sizeof(fake_mac); +} + +static void set_fake_server_duid(struct net_if *iface) +{ + memcpy(&iface->config.dhcpv6.serverid, &test_serverid, + sizeof(test_serverid)); +} + +#define TEST_MSG_SIZE 256 + +static struct net_pkt *test_dhcpv6_create_message( + struct net_if *iface, enum dhcpv6_msg_type msg_type, + test_dhcpv6_options_fn_t set_options_fn) +{ + struct in6_addr *local_addr; + struct net_pkt *pkt; + + local_addr = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE); + if (local_addr == NULL) { + return NULL; + } + + pkt = net_pkt_alloc_with_buffer(iface, TEST_MSG_SIZE, AF_INET6, + IPPROTO_UDP, K_FOREVER); + if (pkt == NULL) { + return NULL; + } + + if (net_ipv6_create(pkt, local_addr, local_addr) < 0 || + net_udp_create(pkt, htons(DHCPV6_SERVER_PORT), + htons(DHCPV6_CLIENT_PORT)) < 0) { + goto fail; + } + + dhcpv6_generate_tid(iface); + + if (dhcpv6_add_header(pkt, msg_type, iface->config.dhcpv6.tid) < 0) { + goto fail; + } + + if (set_options_fn(iface, pkt, msg_type) < 0) { + goto fail; + } + + net_pkt_cursor_init(pkt); + net_ipv6_finalize(pkt, IPPROTO_UDP); + net_pkt_cursor_init(pkt); + + return pkt; + +fail: + net_pkt_unref(pkt); + + return NULL; +} + +static void *dhcpv6_tests_setup(void) +{ + struct in6_addr lladdr; + + test_ctx.iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY)); + + net_ipv6_addr_create_iid(&lladdr, net_if_get_link_addr(test_ctx.iface)); + (void)net_if_ipv6_addr_add(test_ctx.iface, &lladdr, NET_ADDR_AUTOCONF, 0); + + k_sem_init(&test_ctx.tx_sem, 0, 1); + k_sem_init(&test_ctx.exchange_complete_sem, 0, 1); + + generate_fake_server_duid(); + + return NULL; +} + +static void dhcpv6_tests_before(void *fixture) +{ + ARG_UNUSED(fixture); + + test_ctx.reset_dhcpv6 = false; + + set_dhcpv6_test_fn(NULL); + k_sem_reset(&test_ctx.tx_sem); + k_sem_reset(&test_ctx.exchange_complete_sem); + + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + dhcpv6_generate_client_duid(test_ctx.iface); + test_ctx.iface->config.dhcpv6.state = NET_DHCPV6_DISABLED; + test_ctx.iface->config.dhcpv6.addr_iaid = 10; + test_ctx.iface->config.dhcpv6.prefix_iaid = 20; + test_ctx.iface->config.dhcpv6.exchange_start = k_uptime_get(); + test_ctx.iface->config.dhcpv6.params = (struct net_dhcpv6_params){ + .request_addr = true, + .request_prefix = true, + }; + + test_preference = 100; + + net_if_ipv6_addr_rm(test_ctx.iface, &test_addr); + net_if_ipv6_prefix_rm(test_ctx.iface, &test_prefix, test_prefix_len); +} + +static void dhcpv6_tests_after(void *fixture) +{ + ARG_UNUSED(fixture); + + set_dhcpv6_test_fn(NULL); + + if (test_ctx.reset_dhcpv6) { + net_dhcpv6_stop(test_ctx.iface); + } +} + +static void verify_dhcpv6_header(struct net_if *iface, struct net_pkt *pkt, + enum dhcpv6_msg_type msg_type) +{ + uint8_t tid[DHCPV6_TID_SIZE]; + uint8_t type; + int ret; + + (void)net_pkt_skip(pkt, NET_IPV6UDPH_LEN); + + ret = net_pkt_read_u8(pkt, &type); + zassert_ok(ret, "DHCPv6 header incomplete (type)"); + zassert_equal(type, msg_type, "Invalid message type"); + + ret = net_pkt_read(pkt, tid, sizeof(tid)); + zassert_ok(ret, "DHCPv6 header incomplete (tid)"); + zassert_mem_equal(tid, iface->config.dhcpv6.tid, sizeof(tid), + "Transaction ID doesn't match ID of the current exchange"); +} + +static void verify_dhcpv6_clientid(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_dhcpv6_duid_storage duid; + int ret; + + ret = dhcpv6_find_clientid(pkt, &duid); + zassert_ok(ret, "Missing Client ID option"); + zassert_equal(duid.length, iface->config.dhcpv6.clientid.length, + "Invalid Client ID length"); + zassert_mem_equal(&duid.duid, &iface->config.dhcpv6.clientid.duid, + duid.length, "Invalid Client ID value"); +} + +static void verify_dhcpv6_serverid(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_dhcpv6_duid_storage duid; + int ret; + + ret = dhcpv6_find_serverid(pkt, &duid); + zassert_ok(ret, "Missing Server ID option"); + zassert_equal(duid.length, iface->config.dhcpv6.serverid.length, + "Invalid Server ID length"); + zassert_mem_equal(&duid.duid, &iface->config.dhcpv6.serverid.duid, + duid.length, "Invalid Server ID value"); +} + +static void verify_dhcpv6_no_serverid(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_dhcpv6_duid_storage duid; + int ret; + + ret = dhcpv6_find_serverid(pkt, &duid); + zassert_not_equal(ret, 0, "Server ID option should not be present"); +} + +static void verify_dhcpv6_elapsed_time(struct net_if *iface, struct net_pkt *pkt, + uint16_t min_accepted, uint16_t max_accepted) +{ + struct net_pkt_cursor backup; + uint16_t elapsed_time; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_ELAPSED_TIME, &length); + zassert_ok(ret, "Missing Elapsed time option"); + zassert_equal(length, sizeof(uint16_t), "Invalid Elapsed time length"); + + ret = net_pkt_read_be16(pkt, &elapsed_time); + zassert_ok(ret, "Failed to read Elapsed time option"); + zassert_between_inclusive(elapsed_time, min_accepted, max_accepted, + "Elapsed time not in accepted range"); + + net_pkt_cursor_restore(pkt, &backup); +} + +static void verify_dhcpv6_ia_na(struct net_if *iface, struct net_pkt *pkt, + struct in6_addr *addr) +{ + struct dhcpv6_ia_na ia_na; + int ret; + + ret = dhcpv6_find_ia_na(pkt, &ia_na); + zassert_ok(ret, "Missing IA NA option"); + zassert_equal(ia_na.iaid, iface->config.dhcpv6.addr_iaid, + "Incorrect IA NA IAID"); + zassert_equal(ia_na.t1, 0, "T1 should be set to 0 by the client"); + zassert_equal(ia_na.t2, 0, "T2 should be set to 0 by the client"); + + if (addr == NULL) { + zassert_equal(ia_na.iaaddr.status, DHCPV6_STATUS_NO_ADDR_AVAIL, + "Adddress should not be present"); + return; + } + + zassert_equal(ia_na.iaaddr.status, DHCPV6_STATUS_SUCCESS, "Invalid status"); + zassert_equal(ia_na.iaaddr.preferred_lifetime, 0, + "Preferred lifetime should be set to 0 by the client"); + zassert_equal(ia_na.iaaddr.valid_lifetime, 0, + "Valid lifetime should be set to 0 by the client"); + zassert_mem_equal(&ia_na.iaaddr.addr, addr, sizeof(ia_na.iaaddr.addr), + "Incorrect address"); +} + +static void verify_dhcpv6_ia_pd(struct net_if *iface, struct net_pkt *pkt, + struct in6_addr *prefix, uint8_t prefix_len) +{ + struct dhcpv6_ia_pd ia_pd; + int ret; + + ret = dhcpv6_find_ia_pd(pkt, &ia_pd); + zassert_ok(ret, "Missing IA PD option"); + zassert_equal(ia_pd.iaid, iface->config.dhcpv6.prefix_iaid, + "Incorrect IA PD IAID"); + zassert_equal(ia_pd.t1, 0, "T1 should be set to 0 by the client"); + zassert_equal(ia_pd.t2, 0, "T2 should be set to 0 by the client"); + + if (prefix == NULL) { + zassert_equal(ia_pd.iaprefix.status, DHCPV6_STATUS_NO_PREFIX_AVAIL, + "Prefix should not be present"); + return; + } + + zassert_equal(ia_pd.iaprefix.status, DHCPV6_STATUS_SUCCESS, "Invalid status"); + zassert_equal(ia_pd.iaprefix.preferred_lifetime, 0, + "Preferred lifetime should be set to 0 by the client"); + zassert_equal(ia_pd.iaprefix.valid_lifetime, 0, + "Valid lifetime should be set to 0 by the client"); + zassert_equal(ia_pd.iaprefix.prefix_len, prefix_len, + "Incorrect prefix length"); + zassert_mem_equal(&ia_pd.iaprefix.prefix, prefix, + sizeof(ia_pd.iaprefix.prefix), "Incorrect prefix"); +} + +static void verify_dhcpv6_no_reconfigure_accept(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt_cursor backup; + uint16_t length; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_RECONF_ACCEPT, &length); + zassert_not_equal(ret, 0, "Reconfigure accept option should not be present"); + + net_pkt_cursor_restore(pkt, &backup); +} + +static void verify_dhcpv6_oro_sol_max_rt(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt_cursor backup; + uint16_t length; + uint16_t oro; + int ret; + + net_pkt_cursor_backup(pkt, &backup); + + ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_ORO, &length); + zassert_ok(ret, 0, "ORO option not found"); + zassert_true(length >= sizeof(uint16_t) && length % sizeof(uint16_t) == 0, + "Invalid ORO length"); + + while (length >= sizeof(uint16_t)) { + ret = net_pkt_read_be16(pkt, &oro); + zassert_ok(ret, 0, "ORO read error"); + length -= sizeof(uint16_t); + + if (oro == DHCPV6_OPTION_CODE_SOL_MAX_RT) { + break; + } + } + + zassert_equal(oro, DHCPV6_OPTION_CODE_SOL_MAX_RT, + "No SOL_MAX_RT option request present"); + + net_pkt_cursor_restore(pkt, &backup); +} + +static void verify_solicit_message(struct net_if *iface, struct net_pkt *pkt) +{ + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_SOLICIT); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_no_serverid(iface, pkt); + verify_dhcpv6_elapsed_time(iface, pkt, 0, 10); + verify_dhcpv6_ia_na(iface, pkt, NULL); + verify_dhcpv6_ia_pd(iface, pkt, NULL, 0); + verify_dhcpv6_no_reconfigure_accept(iface, pkt); + verify_dhcpv6_oro_sol_max_rt(iface, pkt); +} + +/* Verify that outgoing DHCPv6 Solicit has a valid format and includes all + * mandatory options. + */ +ZTEST(dhcpv6_tests, test_solicit_message_format) +{ + int ret; + + set_dhcpv6_test_fn(verify_solicit_message); + + ret = dhcpv6_send_solicit(test_ctx.iface); + zassert_ok(ret, "dhcpv6_send_solicit failed"); + + ret = k_sem_take(&test_ctx.tx_sem, K_SECONDS(1)); + zassert_ok(ret, "Packet not transmitted"); +} + +static void verify_request_message(struct net_if *iface, struct net_pkt *pkt) +{ + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_REQUEST); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_serverid(iface, pkt); + verify_dhcpv6_elapsed_time(iface, pkt, 0, 10); + verify_dhcpv6_ia_na(iface, pkt, NULL); + verify_dhcpv6_ia_pd(iface, pkt, NULL, 0); + verify_dhcpv6_no_reconfigure_accept(iface, pkt); + verify_dhcpv6_oro_sol_max_rt(iface, pkt); +} + +/* Verify that outgoing DHCPv6 Request has a valid format and includes all + * mandatory options. + */ +ZTEST(dhcpv6_tests, test_request_message_format) +{ + int ret; + + set_fake_server_duid(test_ctx.iface); + set_dhcpv6_test_fn(verify_request_message); + + ret = dhcpv6_send_request(test_ctx.iface); + zassert_ok(ret, "dhcpv6_send_request failed"); + + ret = k_sem_take(&test_ctx.tx_sem, K_SECONDS(1)); + zassert_ok(ret, "Packet not transmitted"); +} + +static void verify_confirm_message(struct net_if *iface, struct net_pkt *pkt) +{ + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_CONFIRM); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_no_serverid(iface, pkt); + verify_dhcpv6_elapsed_time(iface, pkt, 0, 10); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); +} + +/* Verify that outgoing DHCPv6 Confirm has a valid format and includes all + * mandatory options. + */ +ZTEST(dhcpv6_tests, test_confirm_message_format) +{ + int ret; + + set_test_addr_on_iface(test_ctx.iface); + set_dhcpv6_test_fn(verify_confirm_message); + + ret = dhcpv6_send_confirm(test_ctx.iface); + zassert_ok(ret, "dhcpv6_send_confirm failed"); + + ret = k_sem_take(&test_ctx.tx_sem, K_SECONDS(1)); + zassert_ok(ret, "Packet not transmitted"); +} + +void verify_renew_message(struct net_if *iface, struct net_pkt *pkt) +{ + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_RENEW); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_serverid(iface, pkt); + verify_dhcpv6_elapsed_time(iface, pkt, 0, 10); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); + verify_dhcpv6_ia_pd(iface, pkt, &test_prefix, test_prefix_len); + verify_dhcpv6_oro_sol_max_rt(iface, pkt); +} + +/* Verify that outgoing DHCPv6 Renew has a valid format and includes all + * mandatory options. + */ +ZTEST(dhcpv6_tests, test_renew_message_format) +{ + int ret; + + set_test_addr_on_iface(test_ctx.iface); + set_fake_server_duid(test_ctx.iface); + set_dhcpv6_test_fn(verify_renew_message); + + ret = dhcpv6_send_renew(test_ctx.iface); + zassert_ok(ret, "dhcpv6_send_renew failed"); + + ret = k_sem_take(&test_ctx.tx_sem, K_SECONDS(1)); + zassert_ok(ret, "Packet not transmitted"); +} + +static void verify_rebind_message(struct net_if *iface, struct net_pkt *pkt) +{ + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_REBIND); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_no_serverid(iface, pkt); + verify_dhcpv6_elapsed_time(iface, pkt, 0, 10); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); + verify_dhcpv6_ia_pd(iface, pkt, &test_prefix, test_prefix_len); + verify_dhcpv6_oro_sol_max_rt(iface, pkt); +} + +/* Verify that outgoing DHCPv6 Rebind has a valid format and includes all + * mandatory options. + */ +ZTEST(dhcpv6_tests, test_rebind_message_format) +{ + int ret; + + set_test_addr_on_iface(test_ctx.iface); + set_dhcpv6_test_fn(verify_rebind_message); + + ret = dhcpv6_send_rebind(test_ctx.iface); + zassert_ok(ret, "dhcpv6_send_rebind failed"); + + ret = k_sem_take(&test_ctx.tx_sem, K_SECONDS(1)); + zassert_ok(ret, "Packet not transmitted"); +} + +static int set_generic_client_options(struct net_if *iface, struct net_pkt *pkt, + enum dhcpv6_msg_type msg_type) +{ + int ret; + + /* Simulate a minimum subset of valid options */ + ret = dhcpv6_add_option_clientid(pkt, &iface->config.dhcpv6.clientid); + if (ret < 0) { + return ret; + } + + if (msg_type == DHCPV6_MSG_TYPE_REQUEST || + msg_type == DHCPV6_MSG_TYPE_RENEW || + msg_type == DHCPV6_MSG_TYPE_RELEASE || + msg_type == DHCPV6_MSG_TYPE_DECLINE) { + ret = dhcpv6_add_option_serverid(pkt, &test_serverid); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +/* Verify that DHCPv6 client rejects all messages other than Advertise, Reply + * and Reconfigure. + */ +ZTEST(dhcpv6_tests, test_input_reject_client_initiated_messages) +{ + + enum dhcpv6_msg_type type; + enum net_verdict result; + struct net_pkt *pkt; + + test_ctx.iface->config.dhcpv6.state = NET_DHCPV6_INIT; + + for (type = DHCPV6_MSG_TYPE_SOLICIT; + type <= DHCPV6_MSG_TYPE_RELAY_REPL; type++) { + if (type == DHCPV6_MSG_TYPE_ADVERTISE || + type == DHCPV6_MSG_TYPE_REPLY || + type == DHCPV6_MSG_TYPE_RECONFIGURE) { + continue; + } + + pkt = test_dhcpv6_create_message(test_ctx.iface, type, + set_generic_client_options); + zassert_not_null(pkt, "Failed to create fake pkt"); + + result = net_ipv6_input(pkt, false); + zassert_equal(result, NET_DROP, "Should've drop the message"); + + net_pkt_unref(pkt); + } +} + +static int set_advertise_options(struct net_if *iface, struct net_pkt *pkt, + enum dhcpv6_msg_type msg_type) +{ + struct dhcpv6_ia_na test_ia_na = { + .iaid = iface->config.dhcpv6.addr_iaid, + .t1 = 60, + .t2 = 120, + .iaaddr.addr = test_addr, + .iaaddr.preferred_lifetime = 120, + .iaaddr.valid_lifetime = 240, + }; + struct dhcpv6_ia_pd test_ia_pd = { + .iaid = iface->config.dhcpv6.prefix_iaid, + .t1 = 60, + .t2 = 120, + .iaprefix.prefix = test_prefix, + .iaprefix.prefix_len = test_prefix_len, + .iaprefix.preferred_lifetime = 120, + .iaprefix.valid_lifetime = 240, + }; + int ret; + + ret = dhcpv6_add_option_clientid(pkt, &iface->config.dhcpv6.clientid); + if (ret < 0) { + return ret; + } + + ret = dhcpv6_add_option_serverid(pkt, &test_serverid); + if (ret < 0) { + return ret; + } + + if (test_ctx.iface->config.dhcpv6.params.request_addr) { + ret = dhcpv6_add_option_ia_na(pkt, &test_ia_na, true); + if (ret < 0) { + return ret; + } + } + + if (test_ctx.iface->config.dhcpv6.params.request_prefix) { + ret = dhcpv6_add_option_ia_pd(pkt, &test_ia_pd, true); + if (ret < 0) { + return ret; + } + } + + /* Server specific options */ + ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_PREFERENCE, + DHCPV6_OPTION_PREFERENCE_SIZE); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_u8(pkt, test_preference); + if (ret < 0) { + return ret; + } + + return 0; +} + +/* Verify that DHCPv6 client only accepts Advertise messages in Soliciting state */ +ZTEST(dhcpv6_tests, test_input_advertise) +{ + enum net_verdict result; + struct net_pkt *pkt; + enum net_dhcpv6_state state; + + for (state = NET_DHCPV6_DISABLED; state <= NET_DHCPV6_BOUND; state++) { + test_ctx.iface->config.dhcpv6.state = state; + + pkt = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_ADVERTISE, + set_advertise_options); + zassert_not_null(pkt, "Failed to create pkt"); + + result = net_ipv6_input(pkt, false); + + switch (state) { + case NET_DHCPV6_SOLICITING: + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify that Advertise actually updated DHPCv6 context. */ + zassert_equal(test_ctx.iface->config.dhcpv6.server_preference, + test_preference, "Preference not set"); + zassert_equal(test_ctx.iface->config.dhcpv6.serverid.length, + test_serverid.length, "Invalid Server ID length"); + zassert_mem_equal(&test_ctx.iface->config.dhcpv6.serverid.duid, + &test_serverid.duid, test_serverid.length, + "Invalid Server ID value"); + + break; + default: + zassert_equal(result, NET_DROP, "Should've drop the message"); + break; + + } + + net_pkt_unref(pkt); + } +} + +static int set_reply_options(struct net_if *iface, struct net_pkt *pkt, + enum dhcpv6_msg_type msg_type) +{ + struct dhcpv6_ia_na test_ia_na = { + .iaid = iface->config.dhcpv6.addr_iaid, + .t1 = 60, + .t2 = 120, + .iaaddr.addr = test_addr, + .iaaddr.preferred_lifetime = 120, + .iaaddr.valid_lifetime = 240, + }; + struct dhcpv6_ia_pd test_ia_pd = { + .iaid = iface->config.dhcpv6.prefix_iaid, + .t1 = 60, + .t2 = 120, + .iaprefix.prefix = test_prefix, + .iaprefix.prefix_len = test_prefix_len, + .iaprefix.preferred_lifetime = 120, + .iaprefix.valid_lifetime = 240, + }; + int ret; + + ret = dhcpv6_add_option_clientid(pkt, &iface->config.dhcpv6.clientid); + if (ret < 0) { + return ret; + } + + ret = dhcpv6_add_option_serverid(pkt, &test_serverid); + if (ret < 0) { + return ret; + } + + if (iface->config.dhcpv6.state == NET_DHCPV6_CONFIRMING) { + ret = dhcpv6_add_option_header( + pkt, DHCPV6_OPTION_CODE_STATUS_CODE, + DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE); + if (ret < 0) { + return ret; + } + + ret = net_pkt_write_be16(pkt, DHCPV6_STATUS_SUCCESS); + if (ret < 0) { + return ret; + } + + return 0; + } + + ret = dhcpv6_add_option_ia_na(pkt, &test_ia_na, true); + if (ret < 0) { + return ret; + } + + ret = dhcpv6_add_option_ia_pd(pkt, &test_ia_pd, true); + if (ret < 0) { + return ret; + } + + return 0; +} + +/* Verify that DHCPv6 client accepts Reply messages in Requesting, Confirming, + * Renewing and Rebinding states + */ +ZTEST(dhcpv6_tests, test_input_reply) +{ + enum net_verdict result; + struct net_pkt *pkt; + enum net_dhcpv6_state state; + + for (state = NET_DHCPV6_DISABLED; state <= NET_DHCPV6_BOUND; state++) { + test_ctx.iface->config.dhcpv6.state = state; + + set_fake_server_duid(test_ctx.iface); + clear_test_addr_on_iface(test_ctx.iface); + + pkt = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(pkt, "Failed to create pkt"); + + result = net_ipv6_input(pkt, false); + + switch (state) { + case NET_DHCPV6_CONFIRMING: + case NET_DHCPV6_REQUESTING: + case NET_DHCPV6_RENEWING: + case NET_DHCPV6_REBINDING: + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Confirm is an exception, as it does not update + * address on an interface (only status OK is expected). + */ + if (state == NET_DHCPV6_CONFIRMING) { + break; + } + + /* Verify that Reply actually updated DHPCv6 context. */ + zassert_mem_equal(&test_ctx.iface->config.dhcpv6.addr, + &test_addr, sizeof(test_addr), + "Invalid address (state %s)", + net_dhcpv6_state_name(state)); + zassert_mem_equal(&test_ctx.iface->config.dhcpv6.prefix, + &test_prefix, sizeof(test_prefix), + "Invalid prefix (state %s)", + net_dhcpv6_state_name(state)); + zassert_equal(test_ctx.iface->config.dhcpv6.prefix_len, + test_prefix_len, "Invalid prefix len (state %s)", + net_dhcpv6_state_name(state)); + + break; + default: + zassert_equal(result, NET_DROP, "Should've drop the message"); + break; + + } + + net_pkt_unref(pkt); + } +} + +static void test_solicit_expect_request_send_reply(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_REQUEST); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_serverid(iface, pkt); + verify_dhcpv6_ia_na(iface, pkt, NULL); + verify_dhcpv6_ia_pd(iface, pkt, NULL, 0); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_REQUESTING, + "Invalid state"); + + /* Reply with Reply message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_BOUND, + "Invalid state"); + zassert_mem_equal(&test_ctx.iface->config.dhcpv6.addr, + &test_addr, sizeof(test_addr), "Invalid address"); + zassert_mem_equal(&test_ctx.iface->config.dhcpv6.prefix, + &test_prefix, sizeof(test_prefix), "Invalid prefix"); + zassert_equal(test_ctx.iface->config.dhcpv6.prefix_len, + test_prefix_len, "Invalid prefix len"); + + k_sem_give(&test_ctx.exchange_complete_sem); +} + +static void test_solicit_expect_solicit_send_advertise(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_SOLICIT); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_ia_na(iface, pkt, NULL); + verify_dhcpv6_ia_pd(iface, pkt, NULL, 0); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_SOLICITING, + "Invalid state"); + zassert_equal(iface->config.dhcpv6.server_preference, -1, + "Invalid initial preference"); + + /* Update next expected packet handler */ + set_dhcpv6_test_fn(test_solicit_expect_request_send_reply); + + /* Reply with Advertise message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_ADVERTISE, + set_advertise_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_SOLICITING, + "Invalid state"); + zassert_equal(iface->config.dhcpv6.server_preference, test_preference, + "Invalid initial preference"); + zassert_equal(test_serverid.length, iface->config.dhcpv6.serverid.length, + "Invalid Server ID length"); + zassert_mem_equal(&test_serverid.duid, &iface->config.dhcpv6.serverid.duid, + test_serverid.length, "Invalid Server ID value"); +} + +/* Verify that DHCPv6 client can handle standard exchange (Solicit/Request) */ +ZTEST(dhcpv6_tests, test_solicit_exchange) +{ + struct net_dhcpv6_params params = { + .request_addr = true, + .request_prefix = true, + }; + struct net_if_ipv6_prefix *prefix; + struct net_if_addr *addr; + int ret; + + test_ctx.reset_dhcpv6 = true; + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + set_dhcpv6_test_fn(test_solicit_expect_solicit_send_advertise); + + net_dhcpv6_start(test_ctx.iface, ¶ms); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + + addr = net_if_ipv6_addr_lookup_by_iface(test_ctx.iface, &test_addr); + prefix = net_if_ipv6_prefix_lookup(test_ctx.iface, &test_prefix, + test_prefix_len); + zassert_not_null(addr, "Address not configured on the interface"); + zassert_not_null(prefix, "Prefix not configured on the interface"); +} + +static void expect_request_send_reply(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_REQUEST); + set_dhcpv6_test_fn(NULL); + + /* Reply with Reply message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + k_sem_give(&test_ctx.exchange_complete_sem); +} + +static void expect_solicit_send_advertise(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_SOLICIT); + set_dhcpv6_test_fn(expect_request_send_reply); + + /* Reply with Advertise message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_ADVERTISE, + set_advertise_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); +} + +static void test_dhcpv6_start_and_enter_bound(struct net_dhcpv6_params *params) +{ + int ret; + + /* Set maximum preference to speed up the process. */ + test_preference = DHCPV6_MAX_SERVER_PREFERENCE; + + set_dhcpv6_test_fn(expect_solicit_send_advertise); + net_dhcpv6_start(test_ctx.iface, params); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + zassert_equal(test_ctx.iface->config.dhcpv6.state, NET_DHCPV6_BOUND, + "Invalid state"); +} + +static void test_confirm_expect_confirm_send_reply(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_CONFIRM); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_CONFIRMING, + "Invalid state"); + + set_dhcpv6_test_fn(NULL); + + /* Reply with Advertise message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_BOUND, + "Invalid state"); + zassert_equal(test_serverid.length, iface->config.dhcpv6.serverid.length, + "Invalid Server ID length"); + zassert_mem_equal(&test_serverid.duid, &iface->config.dhcpv6.serverid.duid, + test_serverid.length, "Invalid Server ID value"); + + k_sem_give(&test_ctx.exchange_complete_sem); +} + +/* Verify that DHCPv6 client starts with Confirm when interface goes down and + * up again (no prefix). + */ +ZTEST(dhcpv6_tests, test_confirm_exchange_after_iface_down) +{ + struct net_dhcpv6_params params = { + .request_addr = true, + .request_prefix = false, + }; + struct net_if_addr *addr; + int ret; + + test_ctx.reset_dhcpv6 = true; + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + test_dhcpv6_start_and_enter_bound(¶ms); + set_dhcpv6_test_fn(test_confirm_expect_confirm_send_reply); + + net_if_down(test_ctx.iface); + net_if_up(test_ctx.iface); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + + addr = net_if_ipv6_addr_lookup_by_iface(test_ctx.iface, &test_addr); + zassert_not_null(addr, "Address not configured on the interface"); +} + +static void test_rebind_expect_rebind_send_reply(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_REBIND); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); + verify_dhcpv6_ia_pd(iface, pkt, &test_prefix, test_prefix_len); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_REBINDING, + "Invalid state"); + + set_dhcpv6_test_fn(NULL); + + /* Reply with Advertise message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_BOUND, + "Invalid state"); + zassert_equal(test_serverid.length, iface->config.dhcpv6.serverid.length, + "Invalid Server ID length"); + zassert_mem_equal(&test_serverid.duid, &iface->config.dhcpv6.serverid.duid, + test_serverid.length, "Invalid Server ID value"); + + k_sem_give(&test_ctx.exchange_complete_sem); +} + +/* Verify that DHCPv6 client starts with Rebind when interface goes down and + * up again (w/ prefix). + */ +ZTEST(dhcpv6_tests, test_rebind_exchange_after_iface_down) +{ + struct net_dhcpv6_params params = { + .request_addr = true, + .request_prefix = true, + }; + struct net_if_ipv6_prefix *prefix; + struct net_if_addr *addr; + int ret; + + test_ctx.reset_dhcpv6 = true; + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + test_dhcpv6_start_and_enter_bound(¶ms); + set_dhcpv6_test_fn(test_rebind_expect_rebind_send_reply); + + net_if_down(test_ctx.iface); + net_if_up(test_ctx.iface); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + + addr = net_if_ipv6_addr_lookup_by_iface(test_ctx.iface, &test_addr); + prefix = net_if_ipv6_prefix_lookup(test_ctx.iface, &test_prefix, + test_prefix_len); + zassert_not_null(addr, "Address not configured on the interface"); + zassert_not_null(prefix, "Prefix not configured on the interface"); +} + +static void test_renew_expect_renew_send_reply(struct net_if *iface, + struct net_pkt *pkt) +{ + struct net_pkt *reply; + int result; + + /* Verify header */ + verify_dhcpv6_header(iface, pkt, DHCPV6_MSG_TYPE_RENEW); + + /* Verify options */ + verify_dhcpv6_clientid(iface, pkt); + verify_dhcpv6_serverid(iface, pkt); + verify_dhcpv6_ia_na(iface, pkt, &test_addr); + verify_dhcpv6_ia_pd(iface, pkt, &test_prefix, test_prefix_len); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_RENEWING, + "Invalid state"); + + set_dhcpv6_test_fn(NULL); + + /* Reply with Advertise message */ + reply = test_dhcpv6_create_message(test_ctx.iface, + DHCPV6_MSG_TYPE_REPLY, + set_reply_options); + zassert_not_null(reply, "Failed to create pkt"); + + result = net_ipv6_input(reply, false); + zassert_equal(result, NET_OK, "Message should've been processed"); + + /* Verify client state */ + zassert_equal(iface->config.dhcpv6.state, NET_DHCPV6_BOUND, + "Invalid state"); + zassert_equal(test_serverid.length, iface->config.dhcpv6.serverid.length, + "Invalid Server ID length"); + zassert_mem_equal(&test_serverid.duid, &iface->config.dhcpv6.serverid.duid, + test_serverid.length, "Invalid Server ID value"); + + k_sem_give(&test_ctx.exchange_complete_sem); +} + +/* Verify that DHCPv6 client proceeds with Renew when T1 timeout expires. */ +ZTEST(dhcpv6_tests, test_renew_exchange_after_t1) +{ + struct net_dhcpv6_params params = { + .request_addr = true, + .request_prefix = true, + }; + struct net_if_ipv6_prefix *prefix; + struct net_if_addr *addr; + int ret; + + test_ctx.reset_dhcpv6 = true; + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + test_dhcpv6_start_and_enter_bound(¶ms); + set_dhcpv6_test_fn(test_renew_expect_renew_send_reply); + + /* Simulate T1 timeout */ + test_ctx.iface->config.dhcpv6.t1 = k_uptime_get(); + test_ctx.iface->config.dhcpv6.timeout = test_ctx.iface->config.dhcpv6.t1; + dhcpv6_reschedule(); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + + addr = net_if_ipv6_addr_lookup_by_iface(test_ctx.iface, &test_addr); + prefix = net_if_ipv6_prefix_lookup(test_ctx.iface, &test_prefix, + test_prefix_len); + zassert_not_null(addr, "Address not configured on the interface"); + zassert_not_null(prefix, "Prefix not configured on the interface"); +} + +/* Verify that DHCPv6 client proceeds with Rebind when T2 timeout expires. */ +ZTEST(dhcpv6_tests, test_rebind_exchange_after_t2) +{ + struct net_dhcpv6_params params = { + .request_addr = true, + .request_prefix = true, + }; + struct net_if_ipv6_prefix *prefix; + struct net_if_addr *addr; + int ret; + + test_ctx.reset_dhcpv6 = true; + memset(&test_ctx.iface->config.dhcpv6, 0, + sizeof(test_ctx.iface->config.dhcpv6)); + + test_dhcpv6_start_and_enter_bound(¶ms); + set_dhcpv6_test_fn(NULL); + + /* Simulate T1 timeout */ + test_ctx.iface->config.dhcpv6.t1 = k_uptime_get(); + test_ctx.iface->config.dhcpv6.timeout = test_ctx.iface->config.dhcpv6.t1; + dhcpv6_reschedule(); + + /* Give a state machine a chance to run, we ignore Renew message. */ + k_msleep(10); + + set_dhcpv6_test_fn(test_rebind_expect_rebind_send_reply); + + /* Simulate T2 timeout */ + test_ctx.iface->config.dhcpv6.t2 = k_uptime_get(); + test_ctx.iface->config.dhcpv6.timeout = test_ctx.iface->config.dhcpv6.t2; + dhcpv6_reschedule(); + + ret = k_sem_take(&test_ctx.exchange_complete_sem, K_SECONDS(2)); + zassert_ok(ret, "Exchange not completed in required time"); + + addr = net_if_ipv6_addr_lookup_by_iface(test_ctx.iface, &test_addr); + prefix = net_if_ipv6_prefix_lookup(test_ctx.iface, &test_prefix, + test_prefix_len); + zassert_not_null(addr, "Address not configured on the interface"); + zassert_not_null(prefix, "Prefix not configured on the interface"); +} + +ZTEST_SUITE(dhcpv6_tests, NULL, dhcpv6_tests_setup, dhcpv6_tests_before, + dhcpv6_tests_after, NULL); diff --git a/tests/net/dhcpv6/testcase.yaml b/tests/net/dhcpv6/testcase.yaml new file mode 100644 index 00000000000..faf9c67de06 --- /dev/null +++ b/tests/net/dhcpv6/testcase.yaml @@ -0,0 +1,10 @@ +common: + depends_on: netif + tags: net dhcpv6 +tests: + net.dhcpv6: + extra_configs: + - CONFIG_NET_TC_THREAD_COOPERATIVE=y + net.dhcpv6.preempt: + extra_configs: + - CONFIG_NET_TC_THREAD_PREEMPTIVE=y From 9f9aaf83f48bd554c76a55d5528f1a7129e8dfad Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 15 Jun 2023 16:37:53 +0700 Subject: [PATCH 1221/4498] tests: spi_loopback: enable lpspi + dma testing for mr_canhubk3 This enables lpspi + dma testing by default for mr_canhubk3 Signed-off-by: Dat Nguyen Duy --- tests/drivers/spi/spi_loopback/boards/mr_canhubk3.conf | 5 +++++ tests/drivers/spi/spi_loopback/boards/mr_canhubk3.overlay | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/mr_canhubk3.conf diff --git a/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.conf b/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.conf new file mode 100644 index 00000000000..f199db4f3be --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.conf @@ -0,0 +1,5 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_MCUX_LPSPI_DMA=y +CONFIG_SPI_ASYNC=n diff --git a/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.overlay b/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.overlay index 928f05a9929..9d12ceef80e 100644 --- a/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mr_canhubk3.overlay @@ -6,6 +6,9 @@ &lpspi1 { status = "okay"; + /* DMA channels 10 and 12, muxed to LPSPI1 TX and RX */ + dmas = <&edma0 10 45>, <&edma0 12 46>; + dma-names = "tx", "rx"; slow@0 { compatible = "test-spi-loopback-slow"; From 62b28cb443bae68b81b9b36fd19a5a7a968bc6c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sat, 8 Jul 2023 14:52:20 -0300 Subject: [PATCH 1222/4498] mdio: rename argument devad to regad MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename argument `devad` to `regad` to indicate this is the register address in a given PHY device and to not be confused with the Clause 45 device address within a port. Signed-off-by: Manuel Argüelles --- drivers/mdio/mdio_adin2111.c | 8 +++---- drivers/mdio/mdio_esp32.c | 12 +++++------ drivers/mdio/mdio_nxp_s32_netc.c | 8 +++---- drivers/mdio/mdio_sam.c | 14 ++++++------- drivers/mdio/mdio_shell.c | 36 ++++++++++++++++---------------- include/zephyr/drivers/mdio.h | 21 ++++++++++--------- 6 files changed, 50 insertions(+), 49 deletions(-) diff --git a/drivers/mdio/mdio_adin2111.c b/drivers/mdio/mdio_adin2111.c index 39d994c9cc3..2d07b79ff3e 100644 --- a/drivers/mdio/mdio_adin2111.c +++ b/drivers/mdio/mdio_adin2111.c @@ -131,7 +131,7 @@ int adin2111_mdio_c45_write(const struct device *dev, uint8_t prtad, } static int mdio_adin2111_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t *data) + uint8_t regad, uint16_t *data) { const struct mdio_adin2111_config *const cfg = dev->config; uint32_t read; @@ -141,7 +141,7 @@ static int mdio_adin2111_read(const struct device *dev, uint8_t prtad, cmd = BIT(28); cmd |= 0x3U << 26; cmd |= (prtad & 0x1FU) << 21; - cmd |= (devad & 0x1FU) << 16; + cmd |= (regad & 0x1FU) << 16; ret = eth_adin2111_reg_write(cfg->adin, ADIN2111_MDIOACC0, cmd); if (ret >= 0) { @@ -153,7 +153,7 @@ static int mdio_adin2111_read(const struct device *dev, uint8_t prtad, } static int mdio_adin2111_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t data) + uint8_t regad, uint16_t data) { const struct mdio_adin2111_config *const cfg = dev->config; uint32_t cmd; @@ -163,7 +163,7 @@ static int mdio_adin2111_write(const struct device *dev, uint8_t prtad, cmd = BIT(28); cmd |= BIT(26); cmd |= (prtad & 0x1FU) << 21; - cmd |= (devad & 0x1FU) << 16; + cmd |= (regad & 0x1FU) << 16; cmd |= data; ret = eth_adin2111_reg_write(cfg->adin, ADIN2111_MDIOACC0, cmd); diff --git a/drivers/mdio/mdio_esp32.c b/drivers/mdio/mdio_esp32.c index fb243346669..156a1376e71 100644 --- a/drivers/mdio/mdio_esp32.c +++ b/drivers/mdio/mdio_esp32.c @@ -30,7 +30,7 @@ struct mdio_esp32_dev_config { const struct pinctrl_dev_config *pcfg; }; -static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, +static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, bool write, uint16_t data_in, uint16_t *data_out) { struct mdio_esp32_dev_data *const dev_data = dev->data; @@ -46,7 +46,7 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, if (write) { emac_ll_set_phy_data(dev_data->hal.mac_regs, data_in); } - emac_hal_set_phy_cmd(&dev_data->hal, prtad, devad, write); + emac_hal_set_phy_cmd(&dev_data->hal, prtad, regad, write); /* Poll until operation complete */ bool success = false; @@ -73,17 +73,17 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, return 0; } -static int mdio_esp32_read(const struct device *dev, uint8_t prtad, uint8_t devad, +static int mdio_esp32_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) { - return mdio_transfer(dev, prtad, devad, false, 0, data); + return mdio_transfer(dev, prtad, regad, false, 0, data); } static int mdio_esp32_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t data) + uint8_t regad, uint16_t data) { - return mdio_transfer(dev, prtad, devad, true, data, NULL); + return mdio_transfer(dev, prtad, regad, true, data, NULL); } static void mdio_esp32_bus_enable(const struct device *dev) diff --git a/drivers/mdio/mdio_nxp_s32_netc.c b/drivers/mdio/mdio_nxp_s32_netc.c index 4ce88ac96f7..a7c52be59ee 100644 --- a/drivers/mdio/mdio_nxp_s32_netc.c +++ b/drivers/mdio/mdio_nxp_s32_netc.c @@ -25,7 +25,7 @@ struct nxp_s32_mdio_data { }; static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t *regval) + uint8_t regad, uint16_t *regval) { const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; @@ -37,14 +37,14 @@ static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, } k_mutex_lock(&data->rw_mutex, K_FOREVER); - status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, devad, regval); + status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); return status == E_OK ? 0 : -EIO; } static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regval) + uint8_t regad, uint16_t regval) { const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; @@ -56,7 +56,7 @@ static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad, } k_mutex_lock(&data->rw_mutex, K_FOREVER); - status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, devad, regval); + status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); return status == E_OK ? 0 : -EIO; diff --git a/drivers/mdio/mdio_sam.c b/drivers/mdio/mdio_sam.c index 950dfe7f00f..fef75c3c42d 100644 --- a/drivers/mdio/mdio_sam.c +++ b/drivers/mdio/mdio_sam.c @@ -34,7 +34,7 @@ struct mdio_sam_dev_config { int protocol; }; -static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, +static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, uint8_t rw, uint16_t data_in, uint16_t *data_out) { const struct mdio_sam_dev_config *const cfg = dev->config; @@ -48,7 +48,7 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, cfg->regs->GMAC_MAN = (GMAC_MAN_OP(rw ? 0x2 : 0x3)) | GMAC_MAN_WTN(0x02) | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(devad) + | GMAC_MAN_REGA(regad) | GMAC_MAN_DATA(data_in); } else if (cfg->protocol == CLAUSE_22) { @@ -56,7 +56,7 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, | (GMAC_MAN_OP(rw ? 0x2 : 0x1)) | GMAC_MAN_WTN(0x02) | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(devad) + | GMAC_MAN_REGA(regad) | GMAC_MAN_DATA(data_in); } else { @@ -84,16 +84,16 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, return 0; } -static int mdio_sam_read(const struct device *dev, uint8_t prtad, uint8_t devad, +static int mdio_sam_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) { - return mdio_transfer(dev, prtad, devad, 1, 0, data); + return mdio_transfer(dev, prtad, regad, 1, 0, data); } static int mdio_sam_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t data) + uint8_t regad, uint16_t data) { - return mdio_transfer(dev, prtad, devad, 0, data, NULL); + return mdio_transfer(dev, prtad, regad, 0, data, NULL); } static void mdio_sam_bus_enable(const struct device *dev) diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index 9ca57e12c3e..58a6cd610f6 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -35,14 +35,14 @@ LOG_MODULE_REGISTER(mdio_shell, CONFIG_LOG_DEFAULT_LEVEL); /* * Scan the entire 5-bit address space of the MDIO bus * - * scan [] + * scan [] */ static int cmd_mdio_scan(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int cnt; uint16_t data; - uint16_t dev_addr; + uint16_t reg_addr; dev = DEVICE_DT_GET(MDIO_NODE_ID); if (!device_is_ready(dev)) { @@ -52,21 +52,21 @@ static int cmd_mdio_scan(const struct shell *sh, size_t argc, char **argv) } if (argc >= 2) { - dev_addr = strtol(argv[1], NULL, 16); + reg_addr = strtol(argv[1], NULL, 16); } else { - dev_addr = 0; + reg_addr = 0; } shell_print(sh, "Scanning bus for devices. Reading register 0x%x", - dev_addr); + reg_addr); cnt = 0; mdio_bus_enable(dev); for (int i = 0; i < 32; i++) { data = 0; - if (mdio_read(dev, i, dev_addr, &data) >= 0 && + if (mdio_read(dev, i, reg_addr, &data) >= 0 && data != UINT16_MAX) { cnt++; shell_print(sh, "Found MDIO device @ 0x%x", i); @@ -80,12 +80,12 @@ static int cmd_mdio_scan(const struct shell *sh, size_t argc, char **argv) return 0; } -/* mdio write */ +/* mdio write */ static int cmd_mdio_write(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; uint16_t data; - uint16_t dev_addr; + uint16_t reg_addr; uint16_t port_addr; dev = DEVICE_DT_GET(MDIO_NODE_ID); @@ -96,12 +96,12 @@ static int cmd_mdio_write(const struct shell *sh, size_t argc, char **argv) } port_addr = strtol(argv[1], NULL, 16); - dev_addr = strtol(argv[2], NULL, 16); + reg_addr = strtol(argv[2], NULL, 16); data = strtol(argv[3], NULL, 16); mdio_bus_enable(dev); - if (mdio_write(dev, port_addr, dev_addr, data) < 0) { + if (mdio_write(dev, port_addr, reg_addr, data) < 0) { shell_error(sh, "Failed to write to device: %s", dev->name); mdio_bus_disable(dev); @@ -113,12 +113,12 @@ static int cmd_mdio_write(const struct shell *sh, size_t argc, char **argv) return 0; } -/* mdio read */ +/* mdio read */ static int cmd_mdio_read(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; uint16_t data; - uint16_t dev_addr; + uint16_t reg_addr; uint16_t port_addr; dev = DEVICE_DT_GET(MDIO_NODE_ID); @@ -129,11 +129,11 @@ static int cmd_mdio_read(const struct shell *sh, size_t argc, char **argv) } port_addr = strtol(argv[1], NULL, 16); - dev_addr = strtol(argv[2], NULL, 16); + reg_addr = strtol(argv[2], NULL, 16); mdio_bus_enable(dev); - if (mdio_read(dev, port_addr, dev_addr, &data) < 0) { + if (mdio_read(dev, port_addr, reg_addr, &data) < 0) { shell_error(sh, "Failed to read from device: %s", dev->name); mdio_bus_disable(dev); @@ -142,20 +142,20 @@ static int cmd_mdio_read(const struct shell *sh, size_t argc, char **argv) mdio_bus_disable(dev); - shell_print(sh, "%x[%x]: 0x%x", port_addr, dev_addr, data); + shell_print(sh, "%x[%x]: 0x%x", port_addr, reg_addr, data); return 0; } SHELL_STATIC_SUBCMD_SET_CREATE(sub_mdio_cmds, SHELL_CMD_ARG(scan, NULL, - "Scan MDIO bus for devices: scan []", + "Scan MDIO bus for devices: scan []", cmd_mdio_scan, 0, 1), SHELL_CMD_ARG(read, NULL, - "Read from MDIO device: read ", + "Read from MDIO device: read ", cmd_mdio_read, 3, 0), SHELL_CMD_ARG(write, NULL, - "Write to MDIO device: write ", + "Write to MDIO device: write ", cmd_mdio_write, 4, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); diff --git a/include/zephyr/drivers/mdio.h b/include/zephyr/drivers/mdio.h index 8fe0ada27ff..f02428c0602 100644 --- a/include/zephyr/drivers/mdio.h +++ b/include/zephyr/drivers/mdio.h @@ -6,6 +6,7 @@ /* * Copyright (c) 2021 IP-Logix Inc. + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,11 +48,11 @@ __subsystem struct mdio_driver_api { void (*bus_disable)(const struct device *dev); /** Read data from MDIO bus */ - int (*read)(const struct device *dev, uint8_t prtad, uint8_t devad, + int (*read)(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data); /** Write data to MDIO bus */ - int (*write)(const struct device *dev, uint8_t prtad, uint8_t devad, + int (*write)(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); }; /** @@ -98,23 +99,23 @@ static inline void z_impl_mdio_bus_disable(const struct device *dev) * * @param[in] dev Pointer to the device structure for the controller * @param[in] prtad Port address - * @param[in] devad Device address + * @param[in] regad Register address * @param data Pointer to receive read data * * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus */ -__syscall int mdio_read(const struct device *dev, uint8_t prtad, uint8_t devad, +__syscall int mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data); static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t *data) + uint8_t regad, uint16_t *data) { const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; - return api->read(dev, prtad, devad, data); + return api->read(dev, prtad, regad, data); } @@ -126,23 +127,23 @@ static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, * * @param[in] dev Pointer to the device structure for the controller * @param[in] prtad Port address - * @param[in] devad Device address + * @param[in] regad Register address * @param[in] data Data to write * * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus */ -__syscall int mdio_write(const struct device *dev, uint8_t prtad, uint8_t devad, +__syscall int mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); static inline int z_impl_mdio_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t data) + uint8_t regad, uint16_t data) { const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; - return api->write(dev, prtad, devad, data); + return api->write(dev, prtad, regad, data); } #ifdef __cplusplus From 280ddaef4a9a2ea0a309306db39137e475f1d2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 18 Aug 2023 15:58:09 +0700 Subject: [PATCH 1223/4498] mdio: introduce Clause 45 APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `mdio_read_c45()`/`mdio_write_c45()` APIs for Clause 45 access and remove the `protocol` MDIO binding property so that MDIO bus controller can support more than one protocol. A new MDIO header is introduced with generic opcodes, MMD and registers addresses, to be used by MDIO and PHY drivers. Existing MDIO drivers that support both Clause 22 and Clause 45 access are migrated to the new APIs. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 1 - drivers/ethernet/phy/phy_adin2111.c | 114 ++++----- drivers/mdio/mdio_adin2111.c | 15 +- drivers/mdio/mdio_esp32.c | 5 - drivers/mdio/mdio_gpio.c | 5 - drivers/mdio/mdio_nxp_s32_netc.c | 16 +- drivers/mdio/mdio_sam.c | 69 ++++-- dts/bindings/mdio/mdio-controller.yaml | 16 -- dts/xtensa/espressif/esp32/esp32_common.dtsi | 1 - include/zephyr/drivers/mdio.h | 94 ++++++- include/zephyr/drivers/mdio/mdio_adin2111.h | 61 ----- include/zephyr/net/mdio.h | 233 ++++++++++++++++++ 12 files changed, 421 insertions(+), 209 deletions(-) delete mode 100644 include/zephyr/drivers/mdio/mdio_adin2111.h create mode 100644 include/zephyr/net/mdio.h diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 14a1375a2e0..ba602aadd1c 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -29,7 +29,6 @@ &emdio { pinctrl-0 = <&emdio_default>; pinctrl-names = "default"; - protocol = "clause 22"; status = "okay"; phy0: ethernet-phy { diff --git a/drivers/ethernet/phy/phy_adin2111.c b/drivers/ethernet/phy/phy_adin2111.c index 86f92f6e710..eb90eddd013 100644 --- a/drivers/ethernet/phy/phy_adin2111.c +++ b/drivers/ethernet/phy/phy_adin2111.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +18,8 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #include #include #include +#include #include -#include /* PHYs out of reset check retry delay */ #define ADIN2111_PHY_AWAIT_DELAY_POLL_US 15U @@ -37,36 +38,10 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #define ADIN2111_PHY_ID 0x0283BCA1U #define ADIN1110_PHY_ID 0x0283BC91U -/* 10BASE-T1L PMA Status Register */ -#define ADIN2111_PHY_PMA_STATUS 0x000108F7U -/* Indicates PHY support of 10BASE-T1L high voltage (2.4V) tx level op mode */ -#define ADIN2111_PHY_PMA_STATUS_B10L_TX_LVL_HI_ABLE BIT(12) - -/* BASE-T1 Autonegotiation Control Register */ -#define ADIN2111_PHY_AN_CONTROL 0x00070200U -/* Autonegotiation Enable */ -#define ADIN2111_PHY_AN_CONTROL_AN_EN BIT(12) -/* Autonegotiation Restart */ -#define ADIN2111_PHY_AN_CONTROL_AN_RESTART BIT(9) - -/* BASE-T1 Autonegotiation Status Register */ -#define ADIN2111_PHY_AN_STATUS 0x00070201U -/* Autonegotiation Complete */ -#define ADIN2111_PHY_AN_STATUS_AN_COMPLETE BIT(5) -/* Link Status */ -#define ADIN2111_PHY_AN_STATUS_AN_LINK_STATUS BIT(2) - -/* 10BASE-T1 Autonegotiation Advertisement Register */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H 0x00070204U -/* Advertise PHY capability of 2.4V tx level op mode */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL BIT(13) -/* Advertise PHY request of 2.4V tx level op mode */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ BIT(12) - /* System Interrupt Mask Register */ -#define ADIN2111_PHY_CRSM_IRQ_MASK 0x001E0020U +#define ADIN2111_PHY_CRSM_IRQ_MASK 0x0020U /* System Interrupt Status Register */ -#define ADIN2111_PHY_CRSM_IRQ_STATUS 0x001E0010U +#define ADIN2111_PHY_CRSM_IRQ_STATUS 0x0010U /** * Mask of reserved interrupts that indicates a fatal error in the system. * @@ -82,21 +57,21 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #define ADIN2111_PHY_CRSM_IRQ_STATUS_FATAL_ERR 0x2BFFU /* PHY Subsystem Interrupt Mask Register */ -#define ADIN2111_PHY_SUBSYS_IRQ_MASK 0x001F0021U +#define ADIN2111_PHY_SUBSYS_IRQ_MASK 0x0021U /* PHY Subsystem Interrupt Status Register */ -#define ADIN2111_PHY_SUBSYS_IRQ_STATUS 0x001F0011U +#define ADIN2111_PHY_SUBSYS_IRQ_STATUS 0x0011U /* Link Status Change */ #define ADIN2111_PHY_SUBSYS_IRQ_STATUS_LINK_STAT_CHNG_LH BIT(1) /* Software Power-down Control Register */ -#define ADIN2111_PHY_CRSM_SFT_PD_CNTRL 0x001E8812U +#define ADIN2111_PHY_CRSM_SFT_PD_CNTRL 0x8812U /* System Status Register */ -#define ADIN2111_PHY_CRSM_STAT 0x001E8818U +#define ADIN2111_PHY_CRSM_STAT 0x8818U /* Software Power-down Status */ #define ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY BIT(1) /* LED Control Register */ -#define ADIN2111_PHY_LED_CNTRL 0x001E8C82U +#define ADIN2111_PHY_LED_CNTRL 0x8C82U /* LED 1 Enable */ #define ADIN2111_PHY_LED_CNTRL_LED1_EN BIT(15) /* LED 0 Enable */ @@ -131,22 +106,20 @@ static inline int phy_adin2111_c22_write(const struct device *dev, uint16_t reg, return mdio_write(cfg->mdio, cfg->phy_addr, reg, val); } -static inline int phy_adin2111_c45_write(const struct device *dev, uint32_t reg, - uint16_t val) +static inline int phy_adin2111_c45_write(const struct device *dev, uint16_t devad, + uint16_t reg, uint16_t val) { const struct phy_adin2111_config *cfg = dev->config; - return adin2111_mdio_c45_write(cfg->mdio, cfg->phy_addr, ((reg >> 16U) & 0x1FU), - (reg & UINT16_MAX), val); + return mdio_write_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); } -static inline int phy_adin2111_c45_read(const struct device *dev, uint32_t reg, - uint16_t *val) +static inline int phy_adin2111_c45_read(const struct device *dev, uint16_t devad, + uint16_t reg, uint16_t *val) { const struct phy_adin2111_config *cfg = dev->config; - return adin2111_mdio_c45_read(cfg->mdio, cfg->phy_addr, ((reg >> 16U) & 0x1FU), - (reg & 0xFFFFU), val); + return mdio_read_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); } static int phy_adin2111_reg_read(const struct device *dev, uint16_t reg_addr, @@ -192,7 +165,8 @@ static int phy_adin2111_await_phy(const struct device *dev) * it comes out from reset. */ for (count = 0U; count < ADIN2111_PHY_AWAIT_RETRY_COUNT; ++count) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_IRQ_MASK, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_MASK, &val); if (ret >= 0) { if (val != 0U) { break; @@ -233,8 +207,9 @@ int phy_adin2111_handle_phy_irq(const struct device *dev, uint16_t subsys_status; int ret; - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_SUBSYS_IRQ_STATUS, - &subsys_status); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_STATUS, + &subsys_status); if (ret < 0) { return ret; } @@ -262,15 +237,16 @@ static int phy_adin2111_sft_pd(const struct device *dev, bool enter) const uint16_t expected = enter ? ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY : 0U; uint16_t val; - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_CRSM_SFT_PD_CNTRL, - enter ? 1U : 0U); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_SFT_PD_CNTRL, + enter ? 1U : 0U); if (ret < 0) { return ret; } for (count = 0U; count < ADIN2111_PHY_SFT_PD_RETRY_COUNT; ++count) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_STAT, - &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_STAT, &val); if (ret >= 0) { if ((val & ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY) == expected) { break; @@ -368,20 +344,23 @@ static int phy_adin2111_init(const struct device *dev) } /* disable interrupts */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_CRSM_IRQ_MASK, 0U); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_MASK, 0U); if (ret < 0) { return ret; } /* enable link status change irq */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_SUBSYS_IRQ_MASK, + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_MASK, ADIN2111_PHY_SUBSYS_IRQ_STATUS_LINK_STAT_CHNG_LH); if (ret < 0) { return ret; } /* clear PHY IRQ status before enabling ADIN IRQs */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_IRQ_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_STATUS, &val); if (ret < 0) { return ret; } @@ -391,13 +370,15 @@ static int phy_adin2111_init(const struct device *dev) return -ENODEV; } - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_SUBSYS_IRQ_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_STATUS, &val); if (ret < 0) { return ret; } if (!cfg->led0_en || !cfg->led1_en) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_LED_CNTRL, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_LED_CNTRL, &val); if (ret < 0) { return ret; } @@ -407,19 +388,20 @@ static int phy_adin2111_init(const struct device *dev) if (!cfg->led1_en) { val &= ~(ADIN2111_PHY_LED_CNTRL_LED1_EN); } - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_LED_CNTRL, val); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_LED_CNTRL, val); if (ret < 0) { return ret; } } /* check 2.4V support */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_PMA_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_PMAPMD, MDIO_PMA_B10L_STAT, &val); if (ret < 0) { return ret; } - tx_24v_supported = !!(val & ADIN2111_PHY_PMA_STATUS_B10L_TX_LVL_HI_ABLE); + tx_24v_supported = !!(val & MDIO_PMA_B10L_STAT_2V4_ABLE); LOG_INF("PHY %u 2.4V mode %s", cfg->phy_addr, tx_24v_supported ? "supported" : "not supported"); @@ -430,16 +412,15 @@ static int phy_adin2111_init(const struct device *dev) } /* config 2.4V auto-negotiation */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_AN_ADV_ABILITY_H, - &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_AN, MDIO_AN_T1_ADV_H, &val); if (ret < 0) { return ret; } if (tx_24v_supported) { - val |= ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL; + val |= MDIO_AN_T1_ADV_H_10L_TX_HI; } else { - val &= ~ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL; + val &= ~MDIO_AN_T1_ADV_H_10L_TX_HI; } if (cfg->tx_24v) { @@ -449,20 +430,19 @@ static int phy_adin2111_init(const struct device *dev) return -EINVAL; } - val |= ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ; + val |= MDIO_AN_T1_ADV_H_10L_TX_HI_REQ; } else { - val &= ~ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ; + val &= ~MDIO_AN_T1_ADV_H_10L_TX_HI_REQ; } - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_AN_ADV_ABILITY_H, - val); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_AN, MDIO_AN_T1_ADV_H, val); if (ret < 0) { return ret; } /* enable auto-negotiation */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_AN_CONTROL, - ADIN2111_PHY_AN_CONTROL_AN_EN); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_AN, MDIO_AN_T1_CTRL, + MDIO_AN_T1_CTRL_EN); if (ret < 0) { return ret; } diff --git a/drivers/mdio/mdio_adin2111.c b/drivers/mdio/mdio_adin2111.c index 2d07b79ff3e..ff3cf80e43b 100644 --- a/drivers/mdio/mdio_adin2111.c +++ b/drivers/mdio/mdio_adin2111.c @@ -14,7 +14,6 @@ LOG_MODULE_REGISTER(mdio_adin2111, CONFIG_MDIO_LOG_LEVEL); #include #include #include -#include #include /* MDIO ready check retry delay */ @@ -56,9 +55,9 @@ static int mdio_adin2111_wait_ready(const struct device *dev, uint16_t reg, } -int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, - uint16_t *data) +static int mdio_adin2111_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t *data) { const struct mdio_adin2111_config *const cfg = dev->config; uint32_t rdy; @@ -96,9 +95,9 @@ int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, return ret; } -int adin2111_mdio_c45_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, - uint16_t data) +static int mdio_adin2111_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t data) { const struct mdio_adin2111_config *const cfg = dev->config; @@ -191,6 +190,8 @@ static void mdio_adin2111_bus_disable(const struct device *dev) static const struct mdio_driver_api mdio_adin2111_api = { .read = mdio_adin2111_read, .write = mdio_adin2111_write, + .read_c45 = mdio_adin2111_read_c45, + .write_c45 = mdio_adin2111_write_c45, .bus_enable = mdio_adin2111_bus_enable, .bus_disable = mdio_adin2111_bus_disable }; diff --git a/drivers/mdio/mdio_esp32.c b/drivers/mdio/mdio_esp32.c index 156a1376e71..871380c9a0a 100644 --- a/drivers/mdio/mdio_esp32.c +++ b/drivers/mdio/mdio_esp32.c @@ -143,12 +143,7 @@ static const struct mdio_esp32_dev_config mdio_esp32_dev_config_##n = { \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; -#define MDIO_ESP32_PROTOCOL_ASSERT(n) \ - BUILD_ASSERT(DT_INST_ENUM_IDX(n, protocol) == CLAUSE_22, \ - "ESP32 MDIO only supports CLAUSE_22 protocol") - #define MDIO_ESP32_DEVICE(n) \ - MDIO_ESP32_PROTOCOL_ASSERT(n); \ PINCTRL_DT_INST_DEFINE(n); \ MDIO_ESP32_CONFIG(n); \ static struct mdio_esp32_dev_data mdio_esp32_dev_data##n; \ diff --git a/drivers/mdio/mdio_gpio.c b/drivers/mdio/mdio_gpio.c index 46b99963d3c..25f67cd41b1 100644 --- a/drivers/mdio/mdio_gpio.c +++ b/drivers/mdio/mdio_gpio.c @@ -180,12 +180,7 @@ static const struct mdio_driver_api mdio_gpio_driver_api = { .mdio_gpio = GPIO_DT_SPEC_INST_GET(inst, mdio_gpios), \ }; -#define MDIO_GPIO_PROTOCOL_ASSERT(inst) \ - BUILD_ASSERT(DT_INST_ENUM_IDX(inst, protocol) == CLAUSE_22, \ - "MDIO GPIO only supports CLAUSE_22 protocol") - #define MDIO_GPIO_DEVICE(inst) \ - MDIO_GPIO_PROTOCOL_ASSERT(inst); \ MDIO_GPIO_CONFIG(inst); \ static struct mdio_gpio_data mdio_gpio_dev_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, &mdio_gpio_initialize, NULL, &mdio_gpio_dev_data_##inst, \ diff --git a/drivers/mdio/mdio_nxp_s32_netc.c b/drivers/mdio/mdio_nxp_s32_netc.c index a7c52be59ee..c8ce0e731b3 100644 --- a/drivers/mdio/mdio_nxp_s32_netc.c +++ b/drivers/mdio/mdio_nxp_s32_netc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,6 @@ LOG_MODULE_REGISTER(nxp_s32_emdio, CONFIG_MDIO_LOG_LEVEL); #define NETC_SWT_IDX 0 struct nxp_s32_mdio_config { - int protocol; const struct pinctrl_dev_config *pincfg; }; @@ -27,15 +26,9 @@ struct nxp_s32_mdio_data { static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *regval) { - const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; - if (cfg->protocol != CLAUSE_22) { - LOG_ERR("Unsupported protocol"); - return -ENOTSUP; - } - k_mutex_lock(&data->rw_mutex, K_FOREVER); status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); @@ -46,15 +39,9 @@ static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t regval) { - const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; - if (cfg->protocol != CLAUSE_22) { - LOG_ERR("Unsupported protocol"); - return -ENOTSUP; - } - k_mutex_lock(&data->rw_mutex, K_FOREVER); status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); @@ -96,7 +83,6 @@ PINCTRL_DT_DEFINE(MDIO_NODE); static struct nxp_s32_mdio_data nxp_s32_mdio0_data; static const struct nxp_s32_mdio_config nxp_s32_mdio0_cfg = { - .protocol = DT_ENUM_IDX(MDIO_NODE, protocol), .pincfg = PINCTRL_DT_DEV_CONFIG_GET(MDIO_NODE), }; diff --git a/drivers/mdio/mdio_sam.c b/drivers/mdio/mdio_sam.c index fef75c3c42d..078f12c9338 100644 --- a/drivers/mdio/mdio_sam.c +++ b/drivers/mdio/mdio_sam.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 IP-Logix Inc. + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +14,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(mdio_sam, CONFIG_MDIO_LOG_LEVEL); @@ -31,11 +33,11 @@ struct mdio_sam_dev_data { struct mdio_sam_dev_config { Gmac * const regs; const struct pinctrl_dev_config *pcfg; - int protocol; }; static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, - uint8_t rw, uint16_t data_in, uint16_t *data_out) + enum mdio_opcode op, bool c45, uint16_t data_in, + uint16_t *data_out) { const struct mdio_sam_dev_config *const cfg = dev->config; struct mdio_sam_dev_data *const data = dev->data; @@ -44,24 +46,12 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, k_sem_take(&data->sem, K_FOREVER); /* Write mdio transaction */ - if (cfg->protocol == CLAUSE_45) { - cfg->regs->GMAC_MAN = (GMAC_MAN_OP(rw ? 0x2 : 0x3)) - | GMAC_MAN_WTN(0x02) - | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(regad) - | GMAC_MAN_DATA(data_in); - - } else if (cfg->protocol == CLAUSE_22) { - cfg->regs->GMAC_MAN = GMAC_MAN_CLTTO - | (GMAC_MAN_OP(rw ? 0x2 : 0x1)) - | GMAC_MAN_WTN(0x02) - | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(regad) - | GMAC_MAN_DATA(data_in); - - } else { - LOG_ERR("Unsupported protocol"); - } + cfg->regs->GMAC_MAN = (c45 ? 0U : GMAC_MAN_CLTTO) + | GMAC_MAN_OP(op) + | GMAC_MAN_WTN(0x02) + | GMAC_MAN_PHYA(prtad) + | GMAC_MAN_REGA(regad) + | GMAC_MAN_DATA(data_in); /* Wait until done */ while (!(cfg->regs->GMAC_NSR & GMAC_NSR_IDLE)) { @@ -87,13 +77,45 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, static int mdio_sam_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) { - return mdio_transfer(dev, prtad, regad, 1, 0, data); + return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_READ, false, + 0, data); } static int mdio_sam_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data) { - return mdio_transfer(dev, prtad, regad, 0, data, NULL); + return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_WRITE, false, + data, NULL); +} + +static int mdio_sam_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t *data) +{ + int err; + + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, + regad, NULL); + if (!err) { + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_READ, true, + 0, data); + } + + return err; +} + +static int mdio_sam_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t data) +{ + int err; + + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, + regad, NULL); + if (!err) { + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_WRITE, true, + data, NULL); + } + + return err; } static void mdio_sam_bus_enable(const struct device *dev) @@ -126,6 +148,8 @@ static int mdio_sam_initialize(const struct device *dev) static const struct mdio_driver_api mdio_sam_driver_api = { .read = mdio_sam_read, .write = mdio_sam_write, + .read_c45 = mdio_sam_read_c45, + .write_c45 = mdio_sam_write_c45, .bus_enable = mdio_sam_bus_enable, .bus_disable = mdio_sam_bus_disable, }; @@ -134,7 +158,6 @@ static const struct mdio_driver_api mdio_sam_driver_api = { static const struct mdio_sam_dev_config mdio_sam_dev_config_##n = { \ .regs = (Gmac *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .protocol = DT_INST_ENUM_IDX(n, protocol), \ }; #define MDIO_SAM_DEVICE(n) \ diff --git a/dts/bindings/mdio/mdio-controller.yaml b/dts/bindings/mdio/mdio-controller.yaml index aed844bf8f8..b944d0a6ee8 100644 --- a/dts/bindings/mdio/mdio-controller.yaml +++ b/dts/bindings/mdio/mdio-controller.yaml @@ -6,19 +6,3 @@ include: base.yaml bus: mdio - -properties: - protocol: - type: string - description: | - MDIO bus framing protocol to use for communication. Most devices - support clause 22. - - - clause 22: IEEE802.3 clause 22 frame format - - clause 45: IEEE802.3 clause 45 frame format - - micrel SMI: Micrel Serial Management Interface frame format - enum: - - "clause 22" - - "clause 45" - - "micrel SMI" - default: "clause 22" diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index e862a653e9b..09714cd2743 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -69,7 +69,6 @@ mdio: mdio { compatible = "espressif,esp32-mdio"; - protocol = "clause 22"; clocks = <&rtc ESP32_EMAC_MODULE>; status = "disabled"; }; diff --git a/include/zephyr/drivers/mdio.h b/include/zephyr/drivers/mdio.h index f02428c0602..1d030c0f586 100644 --- a/include/zephyr/drivers/mdio.h +++ b/include/zephyr/drivers/mdio.h @@ -32,14 +32,6 @@ extern "C" { * These are for internal use only, so skip these in * public documentation. */ - -/** Order of items in this enum must match the `protocol` dts binding */ -enum MDIO_PROTOCOL { - CLAUSE_22 = 0, - CLAUSE_45 = 1, - MICREL_SMI = 2, -}; - __subsystem struct mdio_driver_api { /** Enable the MDIO bus device */ void (*bus_enable)(const struct device *dev); @@ -54,6 +46,14 @@ __subsystem struct mdio_driver_api { /** Write data to MDIO bus */ int (*write)(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); + + /** Read data from MDIO bus using Clause 45 access */ + int (*read_c45)(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data); + + /** Write data to MDIO bus using Clause 45 access */ + int (*write_c45)(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data); }; /** * @endcond @@ -105,6 +105,7 @@ static inline void z_impl_mdio_bus_disable(const struct device *dev) * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported */ __syscall int mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data); @@ -115,6 +116,10 @@ static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; + if (api->read == NULL) { + return -ENOSYS; + } + return api->read(dev, prtad, regad, data); } @@ -133,6 +138,7 @@ static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write is not supported */ __syscall int mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); @@ -143,9 +149,81 @@ static inline int z_impl_mdio_write(const struct device *dev, uint8_t prtad, const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; + if (api->write == NULL) { + return -ENOSYS; + } + return api->write(dev, prtad, regad, data); } +/** + * @brief Read from MDIO Bus using Clause 45 access + * + * This routine provides an interface to perform a read on the MDIO bus using + * IEEE 802.3 Clause 45 access. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad Device address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write using Clause 45 access is not supported + */ +__syscall int mdio_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t *data); + +static inline int z_impl_mdio_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t *data) +{ + const struct mdio_driver_api *api = + (const struct mdio_driver_api *)dev->api; + + if (api->read_c45 == NULL) { + return -ENOSYS; + } + + return api->read_c45(dev, prtad, devad, regad, data); +} + +/** + * @brief Write to MDIO bus using Clause 45 access + * + * This routine provides an interface to perform a write on the MDIO bus using + * IEEE 802.3 Clause 45 access. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad Device address + * @param[in] regad Register address + * @param[in] data Data to write + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write using Clause 45 access is not supported + */ +__syscall int mdio_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t data); + +static inline int z_impl_mdio_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t data) +{ + const struct mdio_driver_api *api = + (const struct mdio_driver_api *)dev->api; + + if (api->write_c45 == NULL) { + return -ENOSYS; + } + + return api->write_c45(dev, prtad, devad, regad, data); +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/mdio/mdio_adin2111.h b/include/zephyr/drivers/mdio/mdio_adin2111.h deleted file mode 100644 index bf971861434..00000000000 --- a/include/zephyr/drivers/mdio/mdio_adin2111.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ -#define ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Read from MDIO Bus using Clause 45 access - * - * @note The caller is responsible for device lock. - * Shall not be called from ISR. - * - * @param[in] dev MDIO device. - * @param[in] prtad Port address. - * @param[in] devad Device address. - * @param[in] regad Register address. - * @param[out] data Pointer to receive read data. - * - * @retval 0 If successful. - * @retval -EIO General input / output error. - * @retval -ETIMEDOUT If transaction timedout on the bus. - * @retval <0 Error, a negative errno code. - */ -int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, uint16_t *data); - -/** - * @brief Write to MDIO bus using Clause 45 access - * - * @note The caller is responsible for device lock. - * Shall not be called from ISR. - * - * @param[in] dev MDIO device. - * @param[in] prtad Port address. - * @param[in] devad Device address. - * @param[in] regad Register address. - * @param[in] data Data to write. - * - * @retval 0 If successful. - * @retval -EIO General input / output error. - * @retval -ETIMEDOUT If transaction timedout on the bus. - * @retval <0 Error, a negative errno code. - */ -int adin2111_mdio_c45_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, uint16_t data); - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ */ diff --git a/include/zephyr/net/mdio.h b/include/zephyr/net/mdio.h new file mode 100644 index 00000000000..e7161a7a766 --- /dev/null +++ b/include/zephyr/net/mdio.h @@ -0,0 +1,233 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for IEEE 802.3 management interface + */ + +#ifndef ZEPHYR_INCLUDE_NET_MDIO_H_ +#define ZEPHYR_INCLUDE_NET_MDIO_H_ + +/** + * @brief Definitions for IEEE 802.3 management interface + * @defgroup ethernet_mdio IEEE 802.3 management interface + * @ingroup ethernet + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** MDIO transaction operation code */ +enum mdio_opcode { + /** IEEE 802.3 22.2.4.5.4 write operation */ + MDIO_OP_C22_WRITE = 1, + + /** IEEE 802.3 22.2.4.5.4 read operation */ + MDIO_OP_C22_READ = 2, + + /** IEEE 802.3 45.3.4 address operation */ + MDIO_OP_C45_ADDRESS = 0, + + /** IEEE 802.3 45.3.4 write operation */ + MDIO_OP_C45_WRITE = 1, + + /** IEEE 802.3 45.3.4 post-read-increment-address operation */ + MDIO_OP_C45_READ_INC = 2, + + /** IEEE 802.3 45.3.4 read operation */ + MDIO_OP_C45_READ = 3 +}; + +/* MDIO Manageable Device addresses */ +/** Physical Medium Attachment / Physical Medium Dependent */ +#define MDIO_MMD_PMAPMD 0x01U +/** WAN Interface Sublayer */ +#define MDIO_MMD_WIS 0x02U +/** Physical Coding Sublayer */ +#define MDIO_MMD_PCS 0x03U +/** PHY Extender Sublayer */ +#define MDIO_MMD_PHYXS 0x04U +/** DTE Extender Sublayer */ +#define MDIO_MMD_DTEXS 0x05U +/** Transmission Convergence */ +#define MDIO_MMD_TC 0x06U +/** Auto-negotiation */ +#define MDIO_MMD_AN 0x07U +/** Separated PMA (1) */ +#define MDIO_MMD_SEPARATED_PMA1 0x08U +/** Separated PMA (2) */ +#define MDIO_MMD_SEPARATED_PMA2 0x09U +/** Separated PMA (3) */ +#define MDIO_MMD_SEPARATED_PMA3 0x0AU +/** Separated PMA (4) */ +#define MDIO_MMD_SEPARATED_PMA4 0x0BU +/** Clause 22 extension */ +#define MDIO_MMD_C22EXT 0x1DU +/** Vendor Specific 1 */ +#define MDIO_MMD_VENDOR_SPECIFIC1 0x1EU +/** Vendor Specific 2 */ +#define MDIO_MMD_VENDOR_SPECIFIC2 0x1FU + +/* MDIO generic registers */ +/** Control 1 */ +#define MDIO_CTRL1 0x0000U +/** Status 1 */ +#define MDIO_STAT1 0x0001U +/** Device identifier (1) */ +#define MDIO_DEVID1 0x0002U +/** Device identifier (2) */ +#define MDIO_DEVID2 0x0003U +/** Speed ability */ +#define MDIO_SPEED 0x0004U +/** Devices in package (1) */ +#define MDIO_DEVS1 0x0005U +/** Devices in package (2) */ +#define MDIO_DEVS2 0x0006U +/** Control 2 */ +#define MDIO_CTRL2 0x0007U +/** Status 2 */ +#define MDIO_STAT2 0x0008U +/** Package identifier (1) */ +#define MDIO_PKGID1 0x000EU +/** Package identifier (2) */ +#define MDIO_PKGID2 0x000FU + + +/* BASE-T1 registers */ +/** BASE-T1 Auto-negotiation control */ +#define MDIO_AN_T1_CTRL 0x0200U +/** BASE-T1 Auto-negotiation status */ +#define MDIO_AN_T1_STAT 0x0201U +/** BASE-T1 Auto-negotiation advertisement register [15:0] */ +#define MDIO_AN_T1_ADV_L 0x0202U +/** BASE-T1 Auto-negotiation advertisement register [31:16] */ +#define MDIO_AN_T1_ADV_M 0x0203U +/** BASE-T1 Auto-negotiation advertisement register [47:32] */ +#define MDIO_AN_T1_ADV_H 0x0204U + +/* BASE-T1 Auto-negotiation Control register */ +/** Auto-negotiation Restart */ +#define MDIO_AN_T1_CTRL_RESTART BIT(9) +/** Auto-negotiation Enable */ +#define MDIO_AN_T1_CTRL_EN BIT(12) + +/* BASE-T1 Auto-negotiation Status register */ +/** Link Status */ +#define MDIO_AN_T1_STAT_LINK_STATUS BIT(2) +/** Auto-negotiation Ability */ +#define MDIO_AN_T1_STAT_ABLE BIT(3) +/** Auto-negotiation Remote Fault */ +#define MDIO_AN_T1_STAT_REMOTE_FAULT BIT(4) +/** Auto-negotiation Complete */ +#define MDIO_AN_T1_STAT_COMPLETE BIT(5) +/** Page Received */ +#define MDIO_AN_T1_STAT_PAGE_RX BIT(6) + +/* BASE-T1 Auto-negotiation Advertisement register [15:0] */ +/** Pause Ability */ +#define MDIO_AN_T1_ADV_L_PAUSE_CAP BIT(10) +/** Pause Ability */ +#define MDIO_AN_T1_ADV_L_PAUSE_ASYM BIT(11) +/** Force Master/Slave Configuration */ +#define MDIO_AN_T1_ADV_L_FORCE_MS BIT(12) +/** Remote Fault */ +#define MDIO_AN_T1_ADV_L_REMOTE_FAULT BIT(13) +/** Acknowledge (ACK) */ +#define MDIO_AN_T1_ADV_L_ACK BIT(14) +/** Next Page Request */ +#define MDIO_AN_T1_ADV_L_NEXT_PAGE_REQ BIT(15) + +/* BASE-T1 Auto-negotiation Advertisement register [31:16] */ +/** 10BASE-T1L Ability */ +#define MDIO_AN_T1_ADV_M_B10L BIT(14) +/** Master/slave Configuration */ +#define MDIO_AN_T1_ADV_M_MST BIT(4) + +/* BASE-T1 Auto-negotiation Advertisement register [47:32] */ +/* 10BASE-T1L High Level Transmit Operating Mode Request */ +#define MDIO_AN_T1_ADV_H_10L_TX_HI_REQ BIT(12) +/* 10BASE-T1L High Level Transmit Operating Mode Ability */ +#define MDIO_AN_T1_ADV_H_10L_TX_HI BIT(13) + + +/* 10BASE-T1L registers */ +/** 10BASE-T1L PMA control */ +#define MDIO_PMA_B10L_CTRL 0x08F6U +/** 10BASE-T1L PMA status */ +#define MDIO_PMA_B10L_STAT 0x08F7U +/** 10BASE-T1L PMA link status*/ +#define MDIO_PMA_B10L_LINK_STAT 0x8302U +/** 10BASE-T1L PCS control */ +#define MDIO_PCS_B10L_CTRL 0x08E6U +/** 10BASE-T1L PCS status */ +#define MDIO_PCS_B10L_STAT 0x08E7U + +/* 10BASE-T1L PMA control register */ +/** 10BASE-T1L Transmit Disable Mode */ +#define MDIO_PMA_B10L_CTRL_TX_DIS_MODE_EN BIT(14) +/** 10BASE-T1L Transmit Voltage Amplitude Control */ +#define MDIO_PMA_B10L_CTRL_TX_LVL_HI BIT(12) +/** 10BASE-T1L EEE Enable */ +#define MDIO_PMA_B10L_CTRL_EEE BIT(10) +/** 10BASE-T1L PMA Loopback */ +#define MDIO_PMA_B10L_CTRL_LB_PMA_LOC_EN BIT(0) + +/* 10BASE-T1L PMA status register */ +/** 10BASE-T1L PMA receive link up */ +#define MDIO_PMA_B10L_STAT_LINK BIT(0) +/** 10BASE-T1L Fault condition detected */ +#define MDIO_PMA_B10L_STAT_FAULT BIT(1) +/** 10BASE-T1L Receive polarity is reversed */ +#define MDIO_PMA_B10L_STAT_POLARITY BIT(2) +/** 10BASE-T1L Able to detect fault on receive path */ +#define MDIO_PMA_B10L_STAT_RECV_FAULT BIT(9) +/** 10BASE-T1L PHY has EEE ability */ +#define MDIO_PMA_B10L_STAT_EEE BIT(10) +/** 10BASE-T1L PMA has low-power ability */ +#define MDIO_PMA_B10L_STAT_LOW_POWER BIT(11) +/** 10BASE-T1L PHY has 2.4 Vpp operating mode ability */ +#define MDIO_PMA_B10L_STAT_2V4_ABLE BIT(12) +/** 10BASE-T1L PHY has loopback ability */ +#define MDIO_PMA_B10L_STAT_LB_ABLE BIT(13) + +/* 10BASE-T1L PMA link status*/ +/** 10BASE-T1L Remote Receiver Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_REM_RCVR_STAT_OK_LL BIT(9) +/** 10BASE-T1L Remote Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_REM_RCVR_STAT_OK BIT(8) +/** 10BASE-T1L Local Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LOC_RCVR_STAT_OK_LL BIT(7) +/** 10BASE-T1L Local Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LOC_RCVR_STAT_OK BIT(6) +/** 10BASE-T1L Descrambler Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_DSCR_STAT_OK_LL BIT(5) +/** 10BASE-T1L Descrambler Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_DSCR_STAT_OK BIT(4) +/** 10BASE-T1L Link Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_LINK_STAT_OK_LL BIT(1) +/** 10BASE-T1L Link Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LINK_STAT_OK BIT(0) + +/* 10BASE-T1L PCS control */ +/** 10BASE-T1L PCS Loopback Enable */ +#define MDIO_PCS_B10L_CTRL_LB_PCS_EN BIT(14) + +/* 10BASE-T1L PCS status */ +/** 10BASE-T1L PCS Descrambler Status */ +#define MDIO_PCS_B10L_STAT_DSCR_STAT_OK_LL BIT(2) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_MDIO_H_ */ From 977ad483b41d6c0d1a5afd28de189be000548b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 23:00:37 +0700 Subject: [PATCH 1224/4498] mdio: shell: add Clause 45 commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add MDIO shell commands for Clause 45 read/write operations. Signed-off-by: Manuel Argüelles --- drivers/mdio/mdio_shell.c | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index 58a6cd610f6..b70ff7bc1a0 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 IP-Logix Inc. + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -147,6 +148,77 @@ static int cmd_mdio_read(const struct shell *sh, size_t argc, char **argv) return 0; } +/* mdio write_c45 */ +static int cmd_mdio_write_45(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + uint16_t data; + uint16_t reg_addr; + uint8_t dev_addr; + uint8_t port_addr; + + dev = DEVICE_DT_GET(MDIO_NODE_ID); + if (!device_is_ready(dev)) { + shell_error(sh, "MDIO: Device driver %s is not ready.", dev->name); + + return -ENODEV; + } + + port_addr = strtol(argv[1], NULL, 16); + dev_addr = strtol(argv[2], NULL, 16); + reg_addr = strtol(argv[3], NULL, 16); + data = strtol(argv[4], NULL, 16); + + mdio_bus_enable(dev); + + if (mdio_write_c45(dev, port_addr, dev_addr, reg_addr, data) < 0) { + shell_error(sh, "Failed to write to device: %s", dev->name); + mdio_bus_disable(dev); + + return -EIO; + } + + mdio_bus_disable(dev); + + return 0; +} + +/* mdio read_c45 */ +static int cmd_mdio_read_c45(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + uint16_t data; + uint16_t reg_addr; + uint8_t dev_addr; + uint8_t port_addr; + + dev = DEVICE_DT_GET(MDIO_NODE_ID); + if (!device_is_ready(dev)) { + shell_error(sh, "MDIO: Device driver %s is not ready.", dev->name); + + return -ENODEV; + } + + port_addr = strtol(argv[1], NULL, 16); + dev_addr = strtol(argv[2], NULL, 16); + reg_addr = strtol(argv[3], NULL, 16); + + mdio_bus_enable(dev); + + if (mdio_read_c45(dev, port_addr, dev_addr, reg_addr, &data) < 0) { + shell_error(sh, "Failed to read from device: %s", dev->name); + mdio_bus_disable(dev); + + return -EIO; + } + + mdio_bus_disable(dev); + + shell_print(sh, "%x[%x:%x]: 0x%x", port_addr, dev_addr, reg_addr, data); + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(sub_mdio_cmds, SHELL_CMD_ARG(scan, NULL, "Scan MDIO bus for devices: scan []", @@ -157,6 +229,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_mdio_cmds, SHELL_CMD_ARG(write, NULL, "Write to MDIO device: write ", cmd_mdio_write, 4, 0), + SHELL_CMD_ARG(read_c45, NULL, + "Read from MDIO Clause 45 device: " + "read_c45 ", + cmd_mdio_read_c45, 4, 0), + SHELL_CMD_ARG(write_c45, NULL, + "Write to MDIO Clause 45 device: " + "write_c45 ", + cmd_mdio_write_45, 5, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); From b2c163e1089f01054fb0d3db059481724268633f Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 12 Sep 2023 10:32:24 +0200 Subject: [PATCH 1225/4498] doc: Bluetooth: Mesh: Fix line width to 100 in mesh docs From Codying Style guideline: https://docs.zephyrproject.org/latest/contribute/guidelines.html#coding-style `The line length is 100 columns or fewer. In the documentation, longer lines for URL references are an allowed exception.` Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh/blob.rst | 113 ++++- .../bluetooth/api/mesh/blob_cli.rst | 54 ++- .../bluetooth/api/mesh/blob_flash.rst | 17 +- .../bluetooth/api/mesh/blob_srv.rst | 52 +- .../bluetooth/api/mesh/dfd_srv.rst | 27 +- doc/connectivity/bluetooth/api/mesh/dfu.rst | 242 ++++++++-- .../bluetooth/api/mesh/dfu_cli.rst | 4 +- .../bluetooth/api/mesh/dfu_srv.rst | 65 ++- .../bluetooth/api/mesh/lcd_cli.rst | 16 +- .../bluetooth/api/mesh/lcd_srv.rst | 31 +- .../bluetooth/api/mesh/od_cli.rst | 23 +- .../bluetooth/api/mesh/od_srv.rst | 18 +- .../bluetooth/api/mesh/op_agg_cli.rst | 23 +- .../bluetooth/api/mesh/op_agg_srv.rst | 3 +- doc/connectivity/bluetooth/api/mesh/proxy.rst | 51 +- .../bluetooth/api/mesh/rpr_cli.rst | 66 +-- .../bluetooth/api/mesh/rpr_srv.rst | 6 +- .../bluetooth/api/mesh/sar_cfg.rst | 220 +++++---- .../bluetooth/api/mesh/sar_cfg_cli.rst | 29 +- .../bluetooth/api/mesh/sar_cfg_srv.rst | 15 +- doc/connectivity/bluetooth/api/mesh/shell.rst | 449 +++++++++++++----- .../bluetooth/api/mesh/srpl_cli.rst | 20 +- .../bluetooth/api/mesh/srpl_srv.rst | 16 +- 23 files changed, 1088 insertions(+), 472 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/blob.rst b/doc/connectivity/bluetooth/api/mesh/blob.rst index 54d8e67c155..31f45289560 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob.rst @@ -3,11 +3,25 @@ BLOB Transfer models #################### -The Binary Large Object (BLOB) Transfer models implement the Bluetooth Mesh Binary Large Object Transfer Model specification version 1.0 and provide functionality for sending large binary objects from a single source to many Target nodes over the Bluetooth mesh network. It is the underlying transport method for the :ref:`bluetooth_mesh_dfu`, but may be used for other object transfer purposes. The implementation is in experimental state. - -The BLOB Transfer models support transfers of continuous binary objects of up to 4 GB (2 \ :sup:`32` bytes). The BLOB transfer protocol has built-in recovery procedures for packet losses, and sets up checkpoints to ensure that all targets have received all the data before moving on. Data transfer order is not guaranteed. - -BLOB transfers are constrained by the transfer speed and reliability of the underlying mesh network. Under ideal conditions, the BLOBs can be transferred at a rate of up to 1 kbps, allowing a 100 kB BLOB to be transferred in 10-15 minutes. However, network conditions, transfer capabilities and other limiting factors can easily degrade the data rate by several orders of magnitude. Tuning the parameters of the transfer according to the application and network configuration, as well as scheduling it to periods with low network traffic, will offer significant improvements on the speed and reliability of the protocol. However, achieving transfer rates close to the ideal rate is unlikely in actual deployments. +The Binary Large Object (BLOB) Transfer models implement the Bluetooth Mesh Binary Large Object +Transfer Model specification version 1.0 and provide functionality for sending large binary objects +from a single source to many Target nodes over the Bluetooth mesh network. It is the underlying +transport method for the :ref:`bluetooth_mesh_dfu`, but may be used for other object transfer +purposes. The implementation is in experimental state. + +The BLOB Transfer models support transfers of continuous binary objects of up to 4 GB (2 \ :sup:`32` +bytes). The BLOB transfer protocol has built-in recovery procedures for packet losses, and sets up +checkpoints to ensure that all targets have received all the data before moving on. Data transfer +order is not guaranteed. + +BLOB transfers are constrained by the transfer speed and reliability of the underlying mesh network. +Under ideal conditions, the BLOBs can be transferred at a rate of up to 1 kbps, allowing a 100 kB +BLOB to be transferred in 10-15 minutes. However, network conditions, transfer capabilities and +other limiting factors can easily degrade the data rate by several orders of magnitude. Tuning the +parameters of the transfer according to the application and network configuration, as well as +scheduling it to periods with low network traffic, will offer significant improvements on the speed +and reliability of the protocol. However, achieving transfer rates close to the ideal rate is +unlikely in actual deployments. There are two BLOB Transfer models: @@ -17,7 +31,8 @@ There are two BLOB Transfer models: blob_srv blob_cli -The BLOB Transfer Client is instantiated on the sender node, and the BLOB Transfer Server is instantiated on the receiver nodes. +The BLOB Transfer Client is instantiated on the sender node, and the BLOB Transfer Server is +instantiated on the receiver nodes. Concepts ******** @@ -28,23 +43,44 @@ The BLOB transfer protocol introduces several new concepts to implement the BLOB BLOBs ===== -BLOBs are binary objects up to 4 GB in size, that can contain any data the application would like to transfer through the mesh network. The BLOBs are continuous data objects, divided into blocks and chunks to make the transfers reliable and easy to process. No limitations are put on the contents or structure of the BLOB, and applications are free to define any encoding or compression they'd like on the data itself. +BLOBs are binary objects up to 4 GB in size, that can contain any data the application would like to +transfer through the mesh network. The BLOBs are continuous data objects, divided into blocks and +chunks to make the transfers reliable and easy to process. No limitations are put on the contents or +structure of the BLOB, and applications are free to define any encoding or compression they'd like +on the data itself. -The BLOB transfer protocol does not provide any built-in integrity checks, encryption or authentication of the BLOB data. However, the underlying encryption of the Bluetooth mesh protocol provides data integrity checks and protects the contents of the BLOB from third parties using network and application level encryption. +The BLOB transfer protocol does not provide any built-in integrity checks, encryption or +authentication of the BLOB data. However, the underlying encryption of the Bluetooth mesh protocol +provides data integrity checks and protects the contents of the BLOB from third parties using +network and application level encryption. Blocks ------ -The binary objects are divided into blocks, typically from a few hundred to several thousand bytes in size. Each block is transmitted separately, and the BLOB Transfer Client ensures that all BLOB Transfer Servers have received the full block before moving on to the next. The block size is determined by the transfer's ``block_size_log`` parameter, and is the same for all blocks in the transfer except the last, which may be smaller. For a BLOB stored in flash memory, the block size is typically a multiple of the flash page size of the Target devices. +The binary objects are divided into blocks, typically from a few hundred to several thousand bytes +in size. Each block is transmitted separately, and the BLOB Transfer Client ensures that all BLOB +Transfer Servers have received the full block before moving on to the next. The block size is +determined by the transfer's ``block_size_log`` parameter, and is the same for all blocks in the +transfer except the last, which may be smaller. For a BLOB stored in flash memory, the block size is +typically a multiple of the flash page size of the Target devices. Chunks ------ -Each block is divided into chunks. A chunk is the smallest data unit in the BLOB transfer, and must fit inside a single Bluetooth mesh access message excluding the opcode (379 bytes or less). The mechanism for transferring chunks depends on the transfer mode. +Each block is divided into chunks. A chunk is the smallest data unit in the BLOB transfer, and must +fit inside a single Bluetooth mesh access message excluding the opcode (379 bytes or less). The +mechanism for transferring chunks depends on the transfer mode. -When operating in Push BLOB Transfer Mode, the chunks are sent as unacknowledged packets from the BLOB Transfer Client to all targeted BLOB Transfer Servers. Once all chunks in a block have been sent, the BLOB Transfer Client asks each BLOB Transfer Server if they're missing any chunks, and resends them. This is repeated until all BLOB Transfer Servers have received all chunks, or the BLOB Transfer Client gives up. +When operating in Push BLOB Transfer Mode, the chunks are sent as unacknowledged packets from the +BLOB Transfer Client to all targeted BLOB Transfer Servers. Once all chunks in a block have been +sent, the BLOB Transfer Client asks each BLOB Transfer Server if they're missing any chunks, and +resends them. This is repeated until all BLOB Transfer Servers have received all chunks, or the BLOB +Transfer Client gives up. -When operating in Pull BLOB Transfer Mode, the BLOB Transfer Server will request a small number of chunks from the BLOB Transfer Client at a time, and wait for the BLOB Transfer Client to send them before requesting more chunks. This repeats until all chunks have been transferred, or the BLOB Transfer Server gives up. +When operating in Pull BLOB Transfer Mode, the BLOB Transfer Server will request a small number of +chunks from the BLOB Transfer Client at a time, and wait for the BLOB Transfer Client to send them +before requesting more chunks. This repeats until all chunks have been transferred, or the BLOB +Transfer Server gives up. Read more about the transfer modes in :ref:`bluetooth_mesh_blob_transfer_modes` section. @@ -53,16 +89,31 @@ Read more about the transfer modes in :ref:`bluetooth_mesh_blob_transfer_modes` BLOB streams ============ -In the BLOB Transfer models' APIs, the BLOB data handling is separated from the high-level transfer handling. This split allows reuse of different BLOB storage and transfer strategies for different applications. While the high level transfer is controlled directly by the application, the BLOB data itself is accessed through a *BLOB stream*. +In the BLOB Transfer models' APIs, the BLOB data handling is separated from the high-level transfer +handling. This split allows reuse of different BLOB storage and transfer strategies for different +applications. While the high level transfer is controlled directly by the application, the BLOB data +itself is accessed through a *BLOB stream*. -The BLOB stream is comparable to a standard library file stream. Through opening, closing, reading and writing, the BLOB Transfer model gets full access to the BLOB data, whether it's kept in flash, RAM, or on a peripheral. The BLOB stream is opened with an access mode (read or write) before it's used, and the BLOB Transfer models will move around inside the BLOB's data in blocks and chunks, using the BLOB stream as an interface. +The BLOB stream is comparable to a standard library file stream. Through opening, closing, reading +and writing, the BLOB Transfer model gets full access to the BLOB data, whether it's kept in flash, +RAM, or on a peripheral. The BLOB stream is opened with an access mode (read or write) before it's +used, and the BLOB Transfer models will move around inside the BLOB's data in blocks and chunks, +using the BLOB stream as an interface. Interaction ----------- -Before the BLOB is read or written, the stream is opened by calling its :c:member:`open ` callback. When used with a BLOB Transfer Server, the BLOB stream is always opened in write mode, and when used with a BLOB Transfer Client, it's always opened in read mode. +Before the BLOB is read or written, the stream is opened by calling its +:c:member:`open ` callback. When used with a BLOB Transfer Server, the BLOB +stream is always opened in write mode, and when used with a BLOB Transfer Client, it's always opened +in read mode. -For each block in the BLOB, the BLOB Transfer model starts by calling :c:member:`block_start `. Then, depending on the access mode, the BLOB stream's :c:member:`wr ` or :c:member:`rd ` callback is called repeatedly to move data to or from the BLOB. When the model is done processing the block, it calls :c:member:`block_end `. When the transfer is complete, the BLOB stream is closed by calling :c:member:`close `. +For each block in the BLOB, the BLOB Transfer model starts by calling +:c:member:`block_start `. Then, depending on the access mode, the BLOB +stream's :c:member:`wr ` or :c:member:`rd ` callback is +called repeatedly to move data to or from the BLOB. When the model is done processing the block, it +calls :c:member:`block_end `. When the transfer is complete, the BLOB +stream is closed by calling :c:member:`close `. Implementations --------------- @@ -78,28 +129,41 @@ The application may implement their own BLOB stream, or use the implementations Transfer capabilities ===================== -Each BLOB Transfer Server may have different transfer capabilities. The transfer capabilities of each device are controlled through the following configuration options: +Each BLOB Transfer Server may have different transfer capabilities. The transfer capabilities of +each device are controlled through the following configuration options: * :kconfig:option:`CONFIG_BT_MESH_BLOB_SIZE_MAX` * :kconfig:option:`CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN` * :kconfig:option:`CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX` * :kconfig:option:`CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX` -The :kconfig:option:`CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX` option is also used by the BLOB Transfer Client and affects memory consumption by the BLOB Transfer Client model structure. +The :kconfig:option:`CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX` option is also used by the BLOB Transfer +Client and affects memory consumption by the BLOB Transfer Client model structure. -To ensure that the transfer can be received by as many servers as possible, the BLOB Transfer Client can retrieve the capabilities of each BLOB Transfer Server before starting the transfer. The client will transfer the BLOB with the highest possible block and chunk size. +To ensure that the transfer can be received by as many servers as possible, the BLOB Transfer Client +can retrieve the capabilities of each BLOB Transfer Server before starting the transfer. The client +will transfer the BLOB with the highest possible block and chunk size. .. _bluetooth_mesh_blob_transfer_modes: Transfer modes ============== -BLOBs can be transferred using two transfer modes, Push BLOB Transfer Mode and Pull BLOB Transfer Mode. -In most cases, the transfer should be conducted in Push BLOB Transfer Mode. +BLOBs can be transferred using two transfer modes, Push BLOB Transfer Mode and Pull BLOB Transfer +Mode. In most cases, the transfer should be conducted in Push BLOB Transfer Mode. -In Push BLOB Transfer Mode, the send rate is controlled by the BLOB Transfer Client, which will push all the chunks of each block without any high level flow control. Push BLOB Transfer Mode supports any number of Target nodes, and should be the default transfer mode. +In Push BLOB Transfer Mode, the send rate is controlled by the BLOB Transfer Client, which will push +all the chunks of each block without any high level flow control. Push BLOB Transfer Mode supports +any number of Target nodes, and should be the default transfer mode. -In Pull BLOB Transfer Mode, the BLOB Transfer Server will "pull" the chunks from the BLOB Transfer Client at its own rate. Pull BLOB Transfer Mode can be conducted with multiple Target nodes, and is intended for transferring BLOBs to Target nodes acting as :ref:`bluetooth_mesh_lpn`. When operating in Pull BLOB Transfer Mode, the BLOB Transfer Server will request chunks from the BLOB Transfer Client in small batches, and wait for them all to arrive before requesting more chunks. This process is repeated until the BLOB Transfer Server has received all chunks in a block. Then, the BLOB Transfer Client starts the next block, and the BLOB Transfer Server requests all chunks of that block. +In Pull BLOB Transfer Mode, the BLOB Transfer Server will "pull" the chunks from the BLOB Transfer +Client at its own rate. Pull BLOB Transfer Mode can be conducted with multiple Target nodes, and is +intended for transferring BLOBs to Target nodes acting as :ref:`bluetooth_mesh_lpn`. When operating +in Pull BLOB Transfer Mode, the BLOB Transfer Server will request chunks from the BLOB Transfer +Client in small batches, and wait for them all to arrive before requesting more chunks. This process +is repeated until the BLOB Transfer Server has received all chunks in a block. Then, the BLOB +Transfer Client starts the next block, and the BLOB Transfer Server requests all chunks of that +block. .. _bluetooth_mesh_blob_timeout: @@ -107,7 +171,8 @@ In Pull BLOB Transfer Mode, the BLOB Transfer Server will "pull" the chunks from Transfer timeout ================ -The timeout of the BLOB transfer is based on a Timeout Base value. Both client and server use the same Timeout Base value, but they calculate timeout differently. +The timeout of the BLOB transfer is based on a Timeout Base value. Both client and server use the +same Timeout Base value, but they calculate timeout differently. The BLOB Transfer Server uses the following formula to calculate the BLOB transfer timeout:: diff --git a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst index 6d926be1b5c..2232153f549 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst @@ -3,7 +3,9 @@ BLOB Transfer Client #################### -The Binary Large Object (BLOB) Transfer Client is the sender of the BLOB transfer. It supports sending BLOBs of any size to any number of Target nodes, in both Push BLOB Transfer Mode and Pull BLOB Transfer Mode. +The Binary Large Object (BLOB) Transfer Client is the sender of the BLOB transfer. It supports +sending BLOBs of any size to any number of Target nodes, in both Push BLOB Transfer Mode and Pull +BLOB Transfer Mode. Usage ***** @@ -30,7 +32,10 @@ The BLOB Transfer Client is instantiated on an element with a set of event handl Transfer context ================ -Both the transfer capabilities retrieval procedure and the BLOB transfer uses an instance of a :c:type:`bt_mesh_blob_cli_inputs` to determine how to perform the transfer. The BLOB Transfer Client Inputs structure must at least be initialized with a list of targets, an application key and a time to live (TTL) value before it is used in a procedure: +Both the transfer capabilities retrieval procedure and the BLOB transfer uses an instance of a +:c:type:`bt_mesh_blob_cli_inputs` to determine how to perform the transfer. The BLOB Transfer Client +Inputs structure must at least be initialized with a list of targets, an application key and a time +to live (TTL) value before it is used in a procedure: .. code-block:: c @@ -55,14 +60,28 @@ Note that all BLOB Transfer Servers in the transfer must be bound to the chosen Group address ------------- -The application may additionally specify a group address in the context structure. If the group is not :c:macro:`BT_MESH_ADDR_UNASSIGNED`, the messages in the transfer will be sent to the group address, instead of being sent individually to each Target node. Mesh Manager must ensure that all Target nodes having the BLOB Transfer Server model subscribe to this group address. +The application may additionally specify a group address in the context structure. If the group is +not :c:macro:`BT_MESH_ADDR_UNASSIGNED`, the messages in the transfer will be sent to the group +address, instead of being sent individually to each Target node. Mesh Manager must ensure that all +Target nodes having the BLOB Transfer Server model subscribe to this group address. -Using group addresses for transferring the BLOBs can generally increase the transfer speed, as the BLOB Transfer Client sends each message to all Target nodes at the same time. However, sending large, segmented messages to group addresses in Bluetooth mesh is generally less reliable than sending them to unicast addresses, as there is no transport layer acknowledgment mechanism for groups. This can lead to longer recovery periods at the end of each block, and increases the risk of losing Target nodes. Using group addresses for BLOB transfers will generally only pay off if the list of Target nodes is extensive, and the effectiveness of each addressing strategy will vary heavily between different deployments and the size of the chunks. +Using group addresses for transferring the BLOBs can generally increase the transfer speed, as the +BLOB Transfer Client sends each message to all Target nodes at the same time. However, sending +large, segmented messages to group addresses in Bluetooth mesh is generally less reliable than +sending them to unicast addresses, as there is no transport layer acknowledgment mechanism for +groups. This can lead to longer recovery periods at the end of each block, and increases the risk of +losing Target nodes. Using group addresses for BLOB transfers will generally only pay off if the +list of Target nodes is extensive, and the effectiveness of each addressing strategy will vary +heavily between different deployments and the size of the chunks. Transfer timeout ---------------- -If a Target node fails to respond to an acknowledged message within the BLOB Transfer Client's time limit, the Target node is dropped from the transfer. The application can reduce the chances of this by giving the BLOB Transfer Client extra time through the context structure. The extra time may be set in 10-second increments, up to 182 hours, in addition to the base time of 20 seconds. The wait time scales automatically with the transfer TTL. +If a Target node fails to respond to an acknowledged message within the BLOB Transfer Client's time +limit, the Target node is dropped from the transfer. The application can reduce the chances of this +by giving the BLOB Transfer Client extra time through the context structure. The extra time may be +set in 10-second increments, up to 182 hours, in addition to the base time of 20 seconds. The wait +time scales automatically with the transfer TTL. Note that the BLOB Transfer Client only moves forward with the transfer in following cases: @@ -75,18 +94,33 @@ Increasing the wait time will increase this delay. BLOB transfer capabilities retrieval ==================================== -It is generally recommended to retrieve BLOB transfer capabilities before starting a transfer. The procedure populates the transfer capabilities from all Target nodes with the most liberal set of parameters that allows all Target nodes to participate in the transfer. Any Target nodes that fail to respond, or respond with incompatible transfer parameters, will be dropped. +It is generally recommended to retrieve BLOB transfer capabilities before starting a transfer. The +procedure populates the transfer capabilities from all Target nodes with the most liberal set of +parameters that allows all Target nodes to participate in the transfer. Any Target nodes that fail +to respond, or respond with incompatible transfer parameters, will be dropped. -Target nodes are prioritized according to their order in the list of Target nodes. If a Target node is found to be incompatible with any of the previous Target nodes, for instance by reporting a non-overlapping block size range, it will be dropped. Lost Target nodes will be reported through the :c:member:`lost_target ` callback. +Target nodes are prioritized according to their order in the list of Target nodes. If a Target node +is found to be incompatible with any of the previous Target nodes, for instance by reporting a +non-overlapping block size range, it will be dropped. Lost Target nodes will be reported through the +:c:member:`lost_target ` callback. -The end of the procedure is signalled through the :c:member:`caps ` callback, and the resulting capabilities can be used to determine the block and chunk sizes required for the BLOB transfer. +The end of the procedure is signalled through the :c:member:`caps ` +callback, and the resulting capabilities can be used to determine the block and chunk sizes required +for the BLOB transfer. BLOB transfer ============= -The BLOB transfer is started by calling :c:func:`bt_mesh_blob_cli_send` function, which (in addition to the aforementioned transfer inputs) requires a set of transfer parameters and a BLOB stream instance. The transfer parameters include the 64-bit BLOB ID, the BLOB size, the transfer mode, the block size in logarithmic representation and the chunk size. The BLOB ID is application defined, but must match the BLOB ID the BLOB Transfer Servers have been started with. +The BLOB transfer is started by calling :c:func:`bt_mesh_blob_cli_send` function, which (in addition +to the aforementioned transfer inputs) requires a set of transfer parameters and a BLOB stream +instance. The transfer parameters include the 64-bit BLOB ID, the BLOB size, the transfer mode, the +block size in logarithmic representation and the chunk size. The BLOB ID is application defined, but +must match the BLOB ID the BLOB Transfer Servers have been started with. -The transfer runs until it either completes successfully for at least one Target node, or it is cancelled. The end of the transfer is communicated to the application through the :c:member:`end ` callback. Lost Target nodes will be reported through the :c:member:`lost_target ` callback. +The transfer runs until it either completes successfully for at least one Target node, or it is +cancelled. The end of the transfer is communicated to the application through the :c:member:`end +` callback. Lost Target nodes will be reported through the +:c:member:`lost_target ` callback. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/blob_flash.rst b/doc/connectivity/bluetooth/api/mesh/blob_flash.rst index 0b8f69ab385..5966fe3562b 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_flash.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_flash.rst @@ -3,21 +3,30 @@ BLOB Flash ########## -The BLOB Flash Readers and Writers implement BLOB reading to and writing from flash partitions defined in the :ref:`flash map `. +The BLOB Flash Readers and Writers implement BLOB reading to and writing from flash partitions +defined in the :ref:`flash map `. BLOB Flash Reader ***************** -The BLOB Flash Reader interacts with the BLOB Transfer Client to read BLOB data directly from flash. It must be initialized by calling :c:func:`bt_mesh_blob_flash_rd_init` before being passed to the BLOB Transfer Client. Each BLOB Flash Reader only supports one transfer at the time. +The BLOB Flash Reader interacts with the BLOB Transfer Client to read BLOB data directly from flash. +It must be initialized by calling :c:func:`bt_mesh_blob_flash_rd_init` before being passed to the +BLOB Transfer Client. Each BLOB Flash Reader only supports one transfer at the time. BLOB Flash Writer ***************** -The BLOB Flash Writer interacts with the BLOB Transfer Server to write BLOB data directly to flash. It must be initialized by calling :c:func:`bt_mesh_blob_flash_rd_init` before being passed to the BLOB Transfer Server. Each BLOB Flash Writer only supports one transfer at the time, and requires a block size that is a multiple of the flash page size. If a transfer is started with a block size lower than the flash page size, the transfer will be rejected. +The BLOB Flash Writer interacts with the BLOB Transfer Server to write BLOB data directly to flash. +It must be initialized by calling :c:func:`bt_mesh_blob_flash_rd_init` before being passed to the +BLOB Transfer Server. Each BLOB Flash Writer only supports one transfer at the time, and requires a +block size that is a multiple of the flash page size. If a transfer is started with a block size +lower than the flash page size, the transfer will be rejected. -The BLOB Flash Writer copies chunk data into a buffer to accommodate chunks that are unaligned with the flash write block size. The buffer data is padded with ``0xff`` if either the start or length of the chunk is unaligned. +The BLOB Flash Writer copies chunk data into a buffer to accommodate chunks that are unaligned with +the flash write block size. The buffer data is padded with ``0xff`` if either the start or length of +the chunk is unaligned. API Reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst index 22c2540a337..a76ac34d6fb 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst @@ -3,14 +3,22 @@ BLOB Transfer Server #################### -The Binary Large Object (BLOB) Transfer Server model implements reliable receiving of large binary objects. It serves as the backend of the :ref:`bluetooth_mesh_dfu_srv`, but can also be used for receiving other binary images. +The Binary Large Object (BLOB) Transfer Server model implements reliable receiving of large binary +objects. It serves as the backend of the :ref:`bluetooth_mesh_dfu_srv`, but can also be used for +receiving other binary images. BLOBs ***** -As described in :ref:`bluetooth_mesh_blob`, the binary objects transferred by the BLOB Transfer models are divided into blocks, which are divided into chunks. As the transfer is controlled by the BLOB Transfer Client model, the BLOB Transfer Server must allow blocks to come in any order. The chunks within a block may also come in any order, but all chunks in a block must be received before the next block is started. +As described in :ref:`bluetooth_mesh_blob`, the binary objects transferred by the BLOB Transfer +models are divided into blocks, which are divided into chunks. As the transfer is controlled by the +BLOB Transfer Client model, the BLOB Transfer Server must allow blocks to come in any order. The +chunks within a block may also come in any order, but all chunks in a block must be received before +the next block is started. -The BLOB Transfer Server keeps track of the received blocks and chunks, and will process each block and chunk only once. The BLOB Transfer Server also ensures that any missing chunks are resent by the BLOB Transfer Client. +The BLOB Transfer Server keeps track of the received blocks and chunks, and will process each block +and chunk only once. The BLOB Transfer Server also ensures that any missing chunks are resent by the +BLOB Transfer Client. Usage ***** @@ -31,9 +39,16 @@ The BLOB Transfer Server is instantiated on an element with a set of event handl BT_MESH_MODEL_BLOB_SRV(&blob_srv), }; -A BLOB Transfer Server is capable of receiving a single BLOB transfer at a time. Before the BLOB Transfer Server can receive a transfer, it must be prepared by the user. The transfer ID must be passed to the BLOB Transfer Server through the :c:func:`bt_mesh_blob_srv_recv` function before the transfer is started by the BLOB Transfer Client. The ID must be shared between the BLOB Transfer Client and the BLOB Transfer Server through some higher level procedure, like a vendor specific transfer management model. +A BLOB Transfer Server is capable of receiving a single BLOB transfer at a time. Before the BLOB +Transfer Server can receive a transfer, it must be prepared by the user. The transfer ID must be +passed to the BLOB Transfer Server through the :c:func:`bt_mesh_blob_srv_recv` function before the +transfer is started by the BLOB Transfer Client. The ID must be shared between the BLOB Transfer +Client and the BLOB Transfer Server through some higher level procedure, like a vendor specific +transfer management model. -Once the transfer has been set up on the BLOB Transfer Server, it's ready for receiving the BLOB. The application is notified of the transfer progress through the event handler callbacks, and the BLOB data is sent to the BLOB stream. +Once the transfer has been set up on the BLOB Transfer Server, it's ready for receiving the BLOB. +The application is notified of the transfer progress through the event handler callbacks, and the +BLOB data is sent to the BLOB stream. The interaction between the BLOB Transfer Server, BLOB stream and application is shown below: @@ -46,21 +61,36 @@ The interaction between the BLOB Transfer Server, BLOB stream and application is Transfer suspension ******************* -The BLOB Transfer Server keeps a running timer during the transfer, that is reset on every received message. If the BLOB Transfer Client does not send a message before the transfer timer expires, the transfer is suspended by the BLOB Transfer Server. +The BLOB Transfer Server keeps a running timer during the transfer, that is reset on every received +message. If the BLOB Transfer Client does not send a message before the transfer timer expires, the +transfer is suspended by the BLOB Transfer Server. -The BLOB Transfer Server notifies the user of the suspension by calling the :c:member:`suspended ` callback. If the BLOB Transfer Server is in the middle of receiving a block, this block is discarded. +The BLOB Transfer Server notifies the user of the suspension by calling the :c:member:`suspended +` callback. If the BLOB Transfer Server is in the middle of receiving +a block, this block is discarded. -The BLOB Transfer Client may resume a suspended transfer by starting a new block transfer. The BLOB Transfer Server notifies the user by calling the :c:member:`resume ` callback. +The BLOB Transfer Client may resume a suspended transfer by starting a new block transfer. The BLOB +Transfer Server notifies the user by calling the :c:member:`resume ` +callback. Transfer recovery ***************** -The state of the BLOB transfer is stored persistently. If a reboot occurs, the BLOB Transfer Server will attempt to recover the transfer. When the Bluetooth mesh subsystem is started (for instance by calling :c:func:`bt_mesh_init`), the BLOB Transfer Server will check for aborted transfers, and call the :c:member:`recover ` callback if there is any. In the recover callback, the user must provide a BLOB stream to use for the rest of the transfer. If the recover callback doesn't return successfully or does not provide a BLOB stream, the transfer is abandoned. If no recover callback is implemented, transfers are always abandoned after a reboot. +The state of the BLOB transfer is stored persistently. If a reboot occurs, the BLOB Transfer Server +will attempt to recover the transfer. When the Bluetooth mesh subsystem is started (for instance by +calling :c:func:`bt_mesh_init`), the BLOB Transfer Server will check for aborted transfers, and call +the :c:member:`recover ` callback if there is any. In the recover +callback, the user must provide a BLOB stream to use for the rest of the transfer. If the recover +callback doesn't return successfully or does not provide a BLOB stream, the transfer is abandoned. +If no recover callback is implemented, transfers are always abandoned after a reboot. -After a transfer is successfully recovered, the BLOB Transfer Server enters the suspended state. It will stay suspended until the BLOB Transfer Client resumes the transfer, or the user cancels it. +After a transfer is successfully recovered, the BLOB Transfer Server enters the suspended state. It +will stay suspended until the BLOB Transfer Client resumes the transfer, or the user cancels it. .. note:: - The BLOB Transfer Client sending the transfer must support transfer recovery for the transfer to complete. If the BLOB Transfer Client has already given up the transfer, the BLOB Transfer Server will stay suspended until the application calls :c:func:`bt_mesh_blob_srv_cancel`. + The BLOB Transfer Client sending the transfer must support transfer recovery for the transfer to + complete. If the BLOB Transfer Client has already given up the transfer, the BLOB Transfer Server + will stay suspended until the application calls :c:func:`bt_mesh_blob_srv_cancel`. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/dfd_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfd_srv.rst index a1912e3acfb..8efc040a56c 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfd_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfd_srv.rst @@ -3,20 +3,35 @@ Firmware Distribution Server ############################ -The Firmware Distribution Server model implements the Distributor role for the :ref:`bluetooth_mesh_dfu` subsystem. It extends the :ref:`bluetooth_mesh_blob_srv`, which it uses to receive the firmware image binary from the Initiator node. It also instantiates a :ref:`bluetooth_mesh_dfu_cli`, which it uses to distribute firmware updates throughout the mesh network. +The Firmware Distribution Server model implements the Distributor role for the +:ref:`bluetooth_mesh_dfu` subsystem. It extends the :ref:`bluetooth_mesh_blob_srv`, which it uses to +receive the firmware image binary from the Initiator node. It also instantiates a +:ref:`bluetooth_mesh_dfu_cli`, which it uses to distribute firmware updates throughout the mesh +network. .. note:: - Currently, the Firmware Distribution Server supports out-of-band (OOB) retrieval of firmware images over SMP service only. + Currently, the Firmware Distribution Server supports out-of-band (OOB) retrieval of firmware + images over SMP service only. -The Firmware Distribution Server does not have an API of its own, but relies on a Firmware Distribution Client model on a different device to give it information and trigger image distribution and upload. +The Firmware Distribution Server does not have an API of its own, but relies on a Firmware +Distribution Client model on a different device to give it information and trigger image +distribution and upload. Firmware slots ************** -The Firmware Distribution Server is capable of storing multiple firmware images for distribution. Each slot contains a separate firmware image with metadata, and can be distributed to other mesh nodes in the network in any order. The contents, format and size of the firmware images are vendor specific, and may contain data from other vendors. The application should never attempt to execute or modify them. - -The slots are managed remotely by a Firmware Distribution Client, which can both upload new slots and delete old ones. The application is notified of changes to the slots through the Firmware Distribution Server's callbacks (:cpp:type:`bt_mesh_fd_srv_cb`). While the metadata for each firmware slot is stored internally, the application must provide a :ref:`bluetooth_mesh_blob_stream` for reading and writing the firmware image. +The Firmware Distribution Server is capable of storing multiple firmware images for distribution. +Each slot contains a separate firmware image with metadata, and can be distributed to other mesh +nodes in the network in any order. The contents, format and size of the firmware images are vendor +specific, and may contain data from other vendors. The application should never attempt to execute +or modify them. + +The slots are managed remotely by a Firmware Distribution Client, which can both upload new slots +and delete old ones. The application is notified of changes to the slots through the Firmware +Distribution Server's callbacks (:cpp:type:`bt_mesh_fd_srv_cb`). While the metadata for each +firmware slot is stored internally, the application must provide a :ref:`bluetooth_mesh_blob_stream` +for reading and writing the firmware image. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 47716fa9faf..a929f8a53fc 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -3,11 +3,17 @@ Device Firmware Update (DFU) ############################ -Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth mesh DFU subsystem implements the Bluetooth Mesh Device Firmware Update Model specification version 1.0. The implementation is in experimental state. +Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth +mesh DFU subsystem implements the Bluetooth Mesh Device Firmware Update Model specification version +1.0. The implementation is in experimental state. -Bluetooth mesh DFU implements a distribution mechanism for firmware images, and does not put any restrictions on the size, format or usage of the images. The primary design goal of the subsystem is to provide the qualifiable parts of the Bluetooth mesh DFU specification, and leave the usage, firmware validation and deployment to the application. +Bluetooth mesh DFU implements a distribution mechanism for firmware images, and does not put any +restrictions on the size, format or usage of the images. The primary design goal of the subsystem is +to provide the qualifiable parts of the Bluetooth mesh DFU specification, and leave the usage, +firmware validation and deployment to the application. -The DFU specification is implemented in the Zephyr Bluetooth mesh DFU subsystem as three separate models: +The DFU specification is implemented in the Zephyr Bluetooth mesh DFU subsystem as three separate +models: .. toctree:: :maxdepth: 1 @@ -22,29 +28,50 @@ Overview DFU roles ========= -The Bluetooth mesh DFU subsystem defines three different roles the mesh nodes have to assume in the distribution of firmware images: +The Bluetooth mesh DFU subsystem defines three different roles the mesh nodes have to assume in the +distribution of firmware images: Target node - Target node is the receiver and user of the transferred firmware images. All its functionality is implemented by the :ref:`bluetooth_mesh_dfu_srv` model. A transfer may be targeting any number of Target nodes, and they will all be updated concurrently. + Target node is the receiver and user of the transferred firmware images. All its functionality is + implemented by the :ref:`bluetooth_mesh_dfu_srv` model. A transfer may be targeting any number of + Target nodes, and they will all be updated concurrently. Distributor - The Distributor role serves two purposes in the DFU process. First, it's acting as the Target node in the Upload Firmware procedure, then it distributes the uploaded image to other Target nodes as the Distributor. The Distributor does not select the parameters of the transfer, but relies on an Initiator to give it a list of Target nodes and transfer parameters. The Distributor functionality is implemented in two models, :ref:`bluetooth_mesh_dfd_srv` and :ref:`bluetooth_mesh_dfu_cli`. The :ref:`bluetooth_mesh_dfd_srv` is responsible for communicating with the Initiator, and the :ref:`bluetooth_mesh_dfu_cli` is responsible for distributing the image to the Target nodes. + The Distributor role serves two purposes in the DFU process. First, it's acting as the Target + node in the Upload Firmware procedure, then it distributes the uploaded image to other Target + nodes as the Distributor. The Distributor does not select the parameters of the transfer, but + relies on an Initiator to give it a list of Target nodes and transfer parameters. The Distributor + functionality is implemented in two models, :ref:`bluetooth_mesh_dfd_srv` and + :ref:`bluetooth_mesh_dfu_cli`. The :ref:`bluetooth_mesh_dfd_srv` is responsible for communicating + with the Initiator, and the :ref:`bluetooth_mesh_dfu_cli` is responsible for distributing the + image to the Target nodes. Initiator - The Initiator role is typically implemented by the same device that implements the Bluetooth mesh :ref:`Provisioner ` and :ref:`Configurator ` roles. The Initiator needs a full overview of the potential Target nodes and their firmware, and will control (and initiate) all firmware updates. The Initiator role is not implemented in the Zephyr Bluetooth mesh DFU subsystem. + The Initiator role is typically implemented by the same device that implements the Bluetooth mesh + :ref:`Provisioner ` and :ref:`Configurator + ` roles. The Initiator needs a full overview of the potential + Target nodes and their firmware, and will control (and initiate) all firmware updates. The + Initiator role is not implemented in the Zephyr Bluetooth mesh DFU subsystem. .. figure:: images/dfu_roles_mesh.svg :align: center - :alt: Graphic overview of the DFU roles mesh nodes can have during the process of image distribution + :alt: Graphic overview of the DFU roles mesh nodes can have during the process of image + distribution DFU roles and the associated Bluetooth mesh models -Bluetooth mesh applications may combine the DFU roles in any way they'd like, and even take on multiple instances of the same role by instantiating the models on separate elements. For instance, the Distributor and Initiator role can be combined by instantiating the :ref:`bluetooth_mesh_dfu_cli` on the Initiator node and calling its API directly. +Bluetooth mesh applications may combine the DFU roles in any way they'd like, and even take on +multiple instances of the same role by instantiating the models on separate elements. For instance, +the Distributor and Initiator role can be combined by instantiating the +:ref:`bluetooth_mesh_dfu_cli` on the Initiator node and calling its API directly. -It's also possible to combine the Initiator and Distributor devices into a single device, and replace the Firmware Distribution Server model with a proprietary mechanism that will access the Firmware Update Client model directly, e.g. over a serial protocol. +It's also possible to combine the Initiator and Distributor devices into a single device, and +replace the Firmware Distribution Server model with a proprietary mechanism that will access the +Firmware Update Client model directly, e.g. over a serial protocol. .. note:: - All DFU models instantiate one or more :ref:`bluetooth_mesh_blob`, and may need to be spread over multiple elements for certain role combinations. + All DFU models instantiate one or more :ref:`bluetooth_mesh_blob`, and may need to be spread over + multiple elements for certain role combinations. Stages ====== @@ -52,28 +79,63 @@ Stages The Bluetooth mesh DFU process is designed to act in three stages: Upload stage - First, the image is uploaded to a Distributor in a mesh network by an external entity, such as a phone or gateway (the Initiator). During the Upload stage, the Initiator transfers the firmware image and all its metadata to the Distributor node inside the mesh network. The Distributor stores the firmware image and its metadata persistently, and awaits further instructions from the Initiator. The time required to complete the upload process depends on the size of the image. After the upload completes, the Initiator can disconnect from the network during the much more time-consuming Distribution stage. Once the firmware has been uploaded to the Distributor, the Initiator may trigger the Distribution stage at any time. + First, the image is uploaded to a Distributor in a mesh network by an external entity, such as a + phone or gateway (the Initiator). During the Upload stage, the Initiator transfers the firmware + image and all its metadata to the Distributor node inside the mesh network. The Distributor + stores the firmware image and its metadata persistently, and awaits further instructions from the + Initiator. The time required to complete the upload process depends on the size of the image. + After the upload completes, the Initiator can disconnect from the network during the much more + time-consuming Distribution stage. Once the firmware has been uploaded to the Distributor, the + Initiator may trigger the Distribution stage at any time. Firmware Capability Check stage (optional) - Before starting the Distribution stage, the Initiator may optionally check if Target nodes can accept the new firmware. Nodes that do not respond, or respond that they can't receive the new firmware, are excluded from the firmware distribution process. + Before starting the Distribution stage, the Initiator may optionally check if Target nodes can + accept the new firmware. Nodes that do not respond, or respond that they can't receive the new + firmware, are excluded from the firmware distribution process. Distribution stage - Before the firmware image can be distributed, the Initiator transfers the list of Target nodes and their designated firmware image index to the Distributor. Next, it tells the Distributor to start the firmware distributon process, which runs in the background while the Initiator and the mesh network perform other duties. Once the firmware image has been transferred to the Target nodes, the Distributor may ask them to apply the firmware image immediately and report back with their status and new firmware IDs. + Before the firmware image can be distributed, the Initiator transfers the list of Target nodes + and their designated firmware image index to the Distributor. Next, it tells the Distributor to + start the firmware distributon process, which runs in the background while the Initiator and the + mesh network perform other duties. Once the firmware image has been transferred to the Target + nodes, the Distributor may ask them to apply the firmware image immediately and report back with + their status and new firmware IDs. Firmware images =============== -All updatable parts of a mesh node's firmware should be represented as a firmware image. Each Target node holds a list of firmware images, each of which should be independently updatable and identifiable. +All updatable parts of a mesh node's firmware should be represented as a firmware image. Each Target +node holds a list of firmware images, each of which should be independently updatable and +identifiable. -Firmware images are represented as a BLOB (the firmware itself) with the following additional information attached to it: +Firmware images are represented as a BLOB (the firmware itself) with the following additional +information attached to it: Firmware ID - The firmware ID is used to identify a firmware image. The Initiator node may ask the Target nodes for a list of its current firmware IDs to determine whether a newer version of the firmware is available. The format of the firmware ID is vendor specific, but generally, it should include enough information for an Initiator node with knowledge of the format to determine the type of image as well as its version. The firmware ID is optional, and its max length is determined by :kconfig:option:`CONFIG_BT_MESH_DFU_FWID_MAXLEN`. + The firmware ID is used to identify a firmware image. The Initiator node may ask the Target nodes + for a list of its current firmware IDs to determine whether a newer version of the firmware is + available. The format of the firmware ID is vendor specific, but generally, it should include + enough information for an Initiator node with knowledge of the format to determine the type of + image as well as its version. The firmware ID is optional, and its max length is determined by + :kconfig:option:`CONFIG_BT_MESH_DFU_FWID_MAXLEN`. Firmware metadata - The firmware metadata is used by the Target node to determine whether it should accept an incoming firmware update, and what the effect of the update would be. The metadata format is vendor specific, and should contain all information the Target node needs to verify the image, as well as any preparation the Target node has to make before the image is applied. Typical metadata information can be image signatures, changes to the node's Composition Data and the format of the BLOB. The Target node may perform a metadata check before accepting incoming transfers to determine whether the transfer should be started. The firmware metadata can be discarded by the Target node after the metadata check, as other nodes will never request the metadata from the Target node. The firmware metadata is optional, and its maximum length is determined by :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA_MAXLEN`. - - The Bluetooth mesh DFU subsystem in Zephyr provides its own metadata format (:c:struct:`bt_mesh_dfu_metadata`) together with a set of related functions that can be used by an end product. The support for it is enabled using the :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` option. The format of the metadata is presented in the table below. + The firmware metadata is used by the Target node to determine whether it should accept an + incoming firmware update, and what the effect of the update would be. The metadata format is + vendor specific, and should contain all information the Target node needs to verify the image, as + well as any preparation the Target node has to make before the image is applied. Typical metadata + information can be image signatures, changes to the node's Composition Data and the format of the + BLOB. The Target node may perform a metadata check before accepting incoming transfers to + determine whether the transfer should be started. The firmware metadata can be discarded by the + Target node after the metadata check, as other nodes will never request the metadata from the + Target node. The firmware metadata is optional, and its maximum length is determined by + :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA_MAXLEN`. + + The Bluetooth mesh DFU subsystem in Zephyr provides its own metadata format + (:c:struct:`bt_mesh_dfu_metadata`) together with a set of related functions that can be used by + an end product. The support for it is enabled using the + :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` option. The format of the metadata is presented in + the table below. +------------------------+--------------+----------------------------------------+ | Field | Size (Bytes) | Description | @@ -109,7 +171,14 @@ Firmware metadata +------------------------+--------------+----------------------------------------+ Firmware URI - The firmware URI gives the Initiator information about where firmware updates for the image can be found. The URI points to an online resource the Initiator can interact with to get new versions of the firmware. This allows Initiators to perform updates for any node in the mesh network by interacting with the web server pointed to in the URI. The URI must point to a resource using the ``http`` or ``https`` schemes, and the targeted web server must behave according to the Firmware Check Over HTTPS procedure defined by the specification. The firmware URI is optional, and its max length is determined by :kconfig:option:`CONFIG_BT_MESH_DFU_URI_MAXLEN`. + The firmware URI gives the Initiator information about where firmware updates for the image can + be found. The URI points to an online resource the Initiator can interact with to get new + versions of the firmware. This allows Initiators to perform updates for any node in the mesh + network by interacting with the web server pointed to in the URI. The URI must point to a + resource using the ``http`` or ``https`` schemes, and the targeted web server must behave + according to the Firmware Check Over HTTPS procedure defined by the specification. The firmware + URI is optional, and its max length is determined by + :kconfig:option:`CONFIG_BT_MESH_DFU_URI_MAXLEN`. .. note:: @@ -118,18 +187,30 @@ Firmware URI Firmware effect --------------- -A new image may have the Composition Data Page 0 different from the one allocated on a Target node. This may have an effect on the provisioning data of the node and how the Distributor finalizes the DFU. Depending on the availability of the Remote Provisioning Server model on the old and new image, the device may either boot up unprovisioned after applying the new firmware or require to be re-provisioned. The complete list of available options is defined in :c:enum:`bt_mesh_dfu_effect`: +A new image may have the Composition Data Page 0 different from the one allocated on a Target node. +This may have an effect on the provisioning data of the node and how the Distributor finalizes the +DFU. Depending on the availability of the Remote Provisioning Server model on the old and new image, +the device may either boot up unprovisioned after applying the new firmware or require to be +re-provisioned. The complete list of available options is defined in :c:enum:`bt_mesh_dfu_effect`: :c:enum:`BT_MESH_DFU_EFFECT_NONE` - The device stays provisioned after the new firmware is programmed. This effect is chosen if the composition data of the new firmware doesn't change. + The device stays provisioned after the new firmware is programmed. This effect is chosen if the + composition data of the new firmware doesn't change. :c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR` - This effect is chosen when the composition data changes and the device doesn't support the remote provisioning. The new composition data takes place only after re-provisioning. + This effect is chosen when the composition data changes and the device doesn't support the remote + provisioning. The new composition data takes place only after re-provisioning. :c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE` - This effect is chosen when the composition data changes and the device supports the remote provisioning. In this case, the device stays provisioned and the new composition data takes place after re-provisioning using the Remote Provisioning models. + This effect is chosen when the composition data changes and the device supports the remote + provisioning. In this case, the device stays provisioned and the new composition data takes place + after re-provisioning using the Remote Provisioning models. :c:enum:`BT_MESH_DFU_EFFECT_UNPROV` - This effect is chosen if the composition data in the new firmware changes, the device doesn't support the remote provisioning, and the new composition data takes effect after applying the firmware. + This effect is chosen if the composition data in the new firmware changes, the device doesn't + support the remote provisioning, and the new composition data takes effect after applying the + firmware. -When the Target node receives the Firmware Update Firmware Metadata Check message, the Firmware Update Server model calls the :c:member:`bt_mesh_dfu_srv_cb.check` callback, the application can then process the metadata and provide the effect value. +When the Target node receives the Firmware Update Firmware Metadata Check message, the Firmware +Update Server model calls the :c:member:`bt_mesh_dfu_srv_cb.check` callback, the application can +then process the metadata and provide the effect value. DFU procedures @@ -137,9 +218,12 @@ DFU procedures The DFU protocol is implemented as a set of procedures that must be performed in a certain order. -The Initiator controls the Upload stage of the DFU protocol, and all Distributor side handling of the upload subprocedures is implemented in the :ref:`bluetooth_mesh_dfd_srv`. +The Initiator controls the Upload stage of the DFU protocol, and all Distributor side handling of +the upload subprocedures is implemented in the :ref:`bluetooth_mesh_dfd_srv`. -The Distribution stage is controlled by the Distributor, as implemented by the :ref:`bluetooth_mesh_dfu_cli`. The Target node implements all handling of these procedures in the :ref:`bluetooth_mesh_dfu_srv`, and notifies the application through a set of callbacks. +The Distribution stage is controlled by the Distributor, as implemented by the +:ref:`bluetooth_mesh_dfu_cli`. The Target node implements all handling of these procedures in the +:ref:`bluetooth_mesh_dfu_srv`, and notifies the application through a set of callbacks. .. figure:: images/dfu_stages_procedures_mesh.svg :align: center @@ -150,14 +234,23 @@ The Distribution stage is controlled by the Distributor, as implemented by the : Uploading the firmware ====================== -The Upload Firmware procedure uses the :ref:`bluetooth_mesh_blob` to transfer the firmware image from the Initiator to the Distributor. The Upload Firmware procedure works in two steps: +The Upload Firmware procedure uses the :ref:`bluetooth_mesh_blob` to transfer the firmware image +from the Initiator to the Distributor. The Upload Firmware procedure works in two steps: -1. The Initiator generates a BLOB ID, and sends it to the Distributor's Firmware Distribution Server along with the firmware information and other input parameters of the BLOB transfer. The Firmware Distribution Server stores the information, and prepares its BLOB Transfer Server for the incoming transfer before it responds with a status message to the Initiator. -#. The Initiator's BLOB Transfer Client model transfers the firmware image to the Distributor's BLOB Transfer Server, which stores the image in a predetermined flash partition. +1. The Initiator generates a BLOB ID, and sends it to the Distributor's Firmware Distribution Server + along with the firmware information and other input parameters of the BLOB transfer. The Firmware + Distribution Server stores the information, and prepares its BLOB Transfer Server for the + incoming transfer before it responds with a status message to the Initiator. +#. The Initiator's BLOB Transfer Client model transfers the firmware image to the Distributor's BLOB + Transfer Server, which stores the image in a predetermined flash partition. -When the BLOB transfer finishes, the firmware image is ready for distribution. The Initiator may upload several firmware images to the Distributor, and ask it to distribute them in any order or at any time. Additional procedures are available for querying and deleting firmware images from the Distributor. +When the BLOB transfer finishes, the firmware image is ready for distribution. The Initiator may +upload several firmware images to the Distributor, and ask it to distribute them in any order or at +any time. Additional procedures are available for querying and deleting firmware images from the +Distributor. -The following Distributor's capabilities related to firmware images can be configured using the configuration options: +The following Distributor's capabilities related to firmware images can be configured using the +configuration options: * :kconfig:option:`CONFIG_BT_MESH_DFU_SLOT_CNT`: Amount of image slots available on the device. * :kconfig:option:`CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE`: Maximum allowed size for each image. @@ -166,52 +259,97 @@ The following Distributor's capabilities related to firmware images can be confi Populating the Distributor's receivers list =========================================== -Before the Distributor can start distributing the firmware image, it needs a list of Target nodes to send the image to. The Initiator gets the full list of Target nodes either by querying the potential targets directly, or through some external authority. The Initiator uses this information to populate the Distributor's receivers list with the address and relevant firmware image index of each Target node. The Initiator may send one or more Firmware Distribution Receivers Add messages to build the Distributor's receivers list, and a Firmware Distribution Receivers Delete All message to clear it. +Before the Distributor can start distributing the firmware image, it needs a list of Target nodes to +send the image to. The Initiator gets the full list of Target nodes either by querying the potential +targets directly, or through some external authority. The Initiator uses this information to +populate the Distributor's receivers list with the address and relevant firmware image index of each +Target node. The Initiator may send one or more Firmware Distribution Receivers Add messages to +build the Distributor's receivers list, and a Firmware Distribution Receivers Delete All message to +clear it. -The maximum number of receivers that can be added to the Distributor is configured through the :kconfig:option:`CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX` configuration option. +The maximum number of receivers that can be added to the Distributor is configured through the +:kconfig:option:`CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX` configuration option. Initiating the distribution =========================== -Once the Distributor has stored a firmware image and received a list of Target nodes, the Initiator may initiate the distribution procedure. The BLOB transfer parameters for the distribution are passed to the Distributor along with an update policy. The update policy decides whether the Distributor should request that the firmware is applied on the Target nodes or not. The Distributor stores the transfer parameters and starts distributing the firmware image to its list of Target nodes. +Once the Distributor has stored a firmware image and received a list of Target nodes, the Initiator +may initiate the distribution procedure. The BLOB transfer parameters for the distribution are +passed to the Distributor along with an update policy. The update policy decides whether the +Distributor should request that the firmware is applied on the Target nodes or not. The Distributor +stores the transfer parameters and starts distributing the firmware image to its list of Target +nodes. Firmware distribution --------------------- -The Distributor's Firmware Update Client model uses its BLOB Transfer Client model's broadcast subsystem to communicate with all Target nodes. The firmware distribution is performed with the following steps: +The Distributor's Firmware Update Client model uses its BLOB Transfer Client model's broadcast +subsystem to communicate with all Target nodes. The firmware distribution is performed with the +following steps: -1. The Distributor's Firmware Update Client model generates a BLOB ID and sends it to each Target node's Firmware Update Server model, along with the other BLOB transfer parameters, the Target node firmware image index and the firmware image metadata. Each Target node performs a metadata check and prepares their BLOB Transfer Server model for the transfer, before sending a status response to the Firmware Update Client, indicating if the firmware update will have any effect on the Bluetooth mesh state of the node. +1. The Distributor's Firmware Update Client model generates a BLOB ID and sends it to each Target + node's Firmware Update Server model, along with the other BLOB transfer parameters, the Target + node firmware image index and the firmware image metadata. Each Target node performs a metadata + check and prepares their BLOB Transfer Server model for the transfer, before sending a status + response to the Firmware Update Client, indicating if the firmware update will have any effect on + the Bluetooth mesh state of the node. #. The Distributor's BLOB Transfer Client model transfers the firmware image to all Target nodes. -#. Once the BLOB transfer has been received, the Target nodes' applications verify that the firmware is valid by performing checks such as signature verification or image checksums against the image metadata. -#. The Distributor's Firmware Update Client model queries all Target nodes to ensure that they've all verified the firmware image. +#. Once the BLOB transfer has been received, the Target nodes' applications verify that the firmware + is valid by performing checks such as signature verification or image checksums against the image + metadata. +#. The Distributor's Firmware Update Client model queries all Target nodes to ensure that they've + all verified the firmware image. -If the distribution procedure completed with at least one Target node reporting that the image has been received and verified, the distribution procedure is considered successful. +If the distribution procedure completed with at least one Target node reporting that the image has +been received and verified, the distribution procedure is considered successful. .. note:: - The firmware distribution procedure only fails if *all* Target nodes are lost. It is up to the Initiator to request a list of failed Target nodes from the Distributor and initiate additional attempts to update the lost Target nodes after the current attempt is finished. + The firmware distribution procedure only fails if *all* Target nodes are lost. It is up to the + Initiator to request a list of failed Target nodes from the Distributor and initiate additional + attempts to update the lost Target nodes after the current attempt is finished. Suspending the distribution --------------------------- -The Initiator can also request the Distributor to suspend the firmware distribution. In this case, the Distributor will stop sending any messages to Target nodes. When the firmware distribution is resumed, the Distributor will continue sending the firmware from the last successfully transferred block. +The Initiator can also request the Distributor to suspend the firmware distribution. In this case, +the Distributor will stop sending any messages to Target nodes. When the firmware distribution is +resumed, the Distributor will continue sending the firmware from the last successfully transferred +block. Applying the firmware image =========================== -If the Initiator requested it, the Distributor can initiate the Apply Firmware on Target Node procedure on all Target nodes that successfully received and verified the firmware image. The Apply Firmware on Target Node procedure takes no parameters, and to avoid ambiguity, it should be performed before a new transfer is initiated. The Apply Firmware on Target Node procedure consists of the following steps: - -1. The Distributor's Firmware Update Client model instructs all Target nodes that have verified the firmware image to apply it. The Target nodes' Firmware Update Server models respond with a status message before calling their application's ``apply`` callback. -#. The Target node's application performs any preparations needed before applying the transfer, such as storing a snapshot of the Composition Data or clearing its configuration. -#. The Target node's application swaps the current firmware with the new image and updates its firmware image list with the new firmware ID. -#. The Distributor's Firmware Update Client model requests the full list of firmware images from each Target node, and scans through the list to make sure that the new firmware ID has replaced the old. +If the Initiator requested it, the Distributor can initiate the Apply Firmware on Target Node +procedure on all Target nodes that successfully received and verified the firmware image. The Apply +Firmware on Target Node procedure takes no parameters, and to avoid ambiguity, it should be +performed before a new transfer is initiated. The Apply Firmware on Target Node procedure consists +of the following steps: + +1. The Distributor's Firmware Update Client model instructs all Target nodes that have verified the + firmware image to apply it. The Target nodes' Firmware Update Server models respond with a status + message before calling their application's ``apply`` callback. +#. The Target node's application performs any preparations needed before applying the transfer, such + as storing a snapshot of the Composition Data or clearing its configuration. +#. The Target node's application swaps the current firmware with the new image and updates its + firmware image list with the new firmware ID. +#. The Distributor's Firmware Update Client model requests the full list of firmware images from + each Target node, and scans through the list to make sure that the new firmware ID has replaced + the old. .. note:: - During the metadata check in the distribution procedure, the Target node may have reported that it will become unprovisioned after the firmware image is applied. In this case, the Distributor's Firmware Update Client model will send a request for the full firmware image list, and expect no response. + During the metadata check in the distribution procedure, the Target node may have reported that + it will become unprovisioned after the firmware image is applied. In this case, the Distributor's + Firmware Update Client model will send a request for the full firmware image list, and expect no + response. Cancelling the distribution =========================== -The firmware distribution can be cancelled at any time by the Initiator. In this case, the Distributor starts the cancelling procedure by sending a cancelling message to all Target nodes. The Distributor waits for the response from all Target nodes. Once all Target nodes have replied, or the request has timed out, the distribution procedure is cancelled. After this the distribution procedure can be started again from the ``Firmware distribution`` section. +The firmware distribution can be cancelled at any time by the Initiator. In this case, the +Distributor starts the cancelling procedure by sending a cancelling message to all Target nodes. The +Distributor waits for the response from all Target nodes. Once all Target nodes have replied, or the +request has timed out, the distribution procedure is cancelled. After this the distribution +procedure can be started again from the ``Firmware distribution`` section. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_cli.rst b/doc/connectivity/bluetooth/api/mesh/dfu_cli.rst index c4ea98770d9..71952999caa 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_cli.rst @@ -3,7 +3,9 @@ Firmware Update Client ###################### -The Firmware Update Client is responsible for distributing firmware updates through the mesh network. The Firmware Update Client uses the :ref:`bluetooth_mesh_blob_cli` as a transport for its transfers. +The Firmware Update Client is responsible for distributing firmware updates through the mesh +network. The Firmware Update Client uses the :ref:`bluetooth_mesh_blob_cli` as a transport for its +transfers. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst index 0b98b1ec067..b78d4ce2c1d 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst @@ -3,21 +3,33 @@ Firmware Update Server ###################### -The Firmware Update Server model implements the Target node functionality of the :ref:`bluetooth_mesh_dfu` subsystem. It extends the :ref:`bluetooth_mesh_blob_srv`, which it uses to receive the firmware image binary from the Distributor node. +The Firmware Update Server model implements the Target node functionality of the +:ref:`bluetooth_mesh_dfu` subsystem. It extends the :ref:`bluetooth_mesh_blob_srv`, which it uses to +receive the firmware image binary from the Distributor node. -Together with the extended BLOB Transfer Server model, the Firmware Update Server model implements all the required functionality for receiving firmware updates over the mesh network, but does not provide any functionality for storing, applying or verifying the images. +Together with the extended BLOB Transfer Server model, the Firmware Update Server model implements +all the required functionality for receiving firmware updates over the mesh network, but does not +provide any functionality for storing, applying or verifying the images. Firmware images *************** -The Firmware Update Server holds a list of all the updatable firmware images on the device. The full list shall be passed to the server through the ``_imgs`` parameter in :c:macro:`BT_MESH_DFU_SRV_INIT`, and must be populated before the Bluetooth mesh subsystem is started. Each firmware image in the image list must be independently updatable, and should have its own firmware ID. +The Firmware Update Server holds a list of all the updatable firmware images on the device. The full +list shall be passed to the server through the ``_imgs`` parameter in +:c:macro:`BT_MESH_DFU_SRV_INIT`, and must be populated before the Bluetooth mesh subsystem is +started. Each firmware image in the image list must be independently updatable, and should have its +own firmware ID. -For instance, a device with an upgradable bootloader, an application and a peripheral chip with firmware update capabilities could have three entries in the firmware image list, each with their own separate firmware ID. +For instance, a device with an upgradable bootloader, an application and a peripheral chip with +firmware update capabilities could have three entries in the firmware image list, each with their +own separate firmware ID. Receiving transfers ******************* -The Firmware Update Server model uses a BLOB Transfer Server model on the same element to transfer the binary image. The interaction between the Firmware Update Server, BLOB Transfer Server and application is described below: +The Firmware Update Server model uses a BLOB Transfer Server model on the same element to transfer +the binary image. The interaction between the Firmware Update Server, BLOB Transfer Server and +application is described below: .. figure:: images/dfu_srv.svg :align: center @@ -28,40 +40,61 @@ The Firmware Update Server model uses a BLOB Transfer Server model on the same e Transfer check ============== -The transfer check is an optional pre-transfer check the application can perform on incoming firmware image metadata. The Firmware Update Server performs the transfer check by calling the :c:member:`check ` callback. +The transfer check is an optional pre-transfer check the application can perform on incoming +firmware image metadata. The Firmware Update Server performs the transfer check by calling the +:c:member:`check ` callback. -The result of the transfer check is a pass/fail status return and the expected :c:type:`bt_mesh_dfu_effect`. The DFU effect return parameter will be communicated back to the Distributor, and should indicate what effect the firmware update will have on the mesh state of the device. If the transfer will cause the device to change its Composition Data or become unprovisioned, this should be communicated through the effect parameter of the metadata check. +The result of the transfer check is a pass/fail status return and the expected +:c:type:`bt_mesh_dfu_effect`. The DFU effect return parameter will be communicated back to the +Distributor, and should indicate what effect the firmware update will have on the mesh state of the +device. If the transfer will cause the device to change its Composition Data or become +unprovisioned, this should be communicated through the effect parameter of the metadata check. Start ===== -The Start procedure prepares the application for the incoming transfer. It'll contain information about which image is being updated, as well as the update metadata. +The Start procedure prepares the application for the incoming transfer. It'll contain information +about which image is being updated, as well as the update metadata. -The Firmware Update Server :c:member:`start ` callback must return a pointer to the BLOB Writer the BLOB Transfer Server will send the BLOB to. +The Firmware Update Server :c:member:`start ` callback must return a +pointer to the BLOB Writer the BLOB Transfer Server will send the BLOB to. BLOB transfer ============= -After the setup stage, the Firmware Update Server prepares the BLOB Transfer Server for the incoming transfer. The entire firmware image is transferred to the BLOB Transfer Server, which passes the image to its assigned BLOB Writer. +After the setup stage, the Firmware Update Server prepares the BLOB Transfer Server for the incoming +transfer. The entire firmware image is transferred to the BLOB Transfer Server, which passes the +image to its assigned BLOB Writer. -At the end of the BLOB transfer, the Firmware Update Server calls its :c:member:`end ` callback. +At the end of the BLOB transfer, the Firmware Update Server calls its +:c:member:`end ` callback. Image verification ================== -After the BLOB transfer has finished, the application should verify the image in any way it can to ensure that it is ready for being applied. -Once the image has been verified, the application calls :c:func:`bt_mesh_dfu_srv_verified`. +After the BLOB transfer has finished, the application should verify the image in any way it can to +ensure that it is ready for being applied. Once the image has been verified, the application calls +:c:func:`bt_mesh_dfu_srv_verified`. If the image can't be verified, the application calls :c:func:`bt_mesh_dfu_srv_rejected`. Applying the image ================== -Finally, if the image was verified, the Distributor may instruct the Firmware Update Server to apply the transfer. This is communicated to the application through the :c:member:`apply ` callback. The application should swap the image and start running with the new firmware. The firmware image table should be updated to reflect the new firmware ID of the updated image. +Finally, if the image was verified, the Distributor may instruct the Firmware Update Server to apply +the transfer. This is communicated to the application through the :c:member:`apply +` callback. The application should swap the image and start running with +the new firmware. The firmware image table should be updated to reflect the new firmware ID of the +updated image. -When the transfer applies to the mesh application itself, the device might have to reboot as part of the swap. This restart can be performed from inside the apply callback, or done asynchronously. After booting up with the new firmware, the firmware image table should be updated before the Bluetooth mesh subsystem is started. +When the transfer applies to the mesh application itself, the device might have to reboot as part of +the swap. This restart can be performed from inside the apply callback, or done asynchronously. +After booting up with the new firmware, the firmware image table should be updated before the +Bluetooth mesh subsystem is started. -The Distributor will read out the firmware image table to confirm that the transfer was successfully applied. If the metadata check indicated that the device would become unprovisioned, the Target node is not required to respond to this check. +The Distributor will read out the firmware image table to confirm that the transfer was successfully +applied. If the metadata check indicated that the device would become unprovisioned, the Target node +is not required to respond to this check. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst index 27df2e493b2..0eca28f1b2a 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst @@ -3,14 +3,20 @@ Large Composition Data Client ############################# -The Large Composition Data Client model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_CLI` option. +The Large Composition Data Client model is a foundation model defined by the Bluetooth mesh +specification. The model is optional, and is enabled through the +:kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_CLI` option. -The Large Composition Data Client model was introduced in the Bluetooth Mesh Protocol Specification version 1.1, and supports the functionality of reading pages of Composition Data that do not fit in a Config Composition Data Status message and reading the metadata of the model instances on a node that supports the :ref:`bluetooth_mesh_lcd_srv` model. +The Large Composition Data Client model was introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and supports the functionality of reading pages of Composition Data that do not fit in +a Config Composition Data Status message and reading the metadata of the model instances on a node +that supports the :ref:`bluetooth_mesh_lcd_srv` model. -The Large Composition Data Client model communicates with a Large Composition Data Server model using the device key of the node containing the target Large Composition Data Server model instance. +The Large Composition Data Client model communicates with a Large Composition Data Server model +using the device key of the node containing the target Large Composition Data Server model instance. -If present, the Large Composition Data Client model must only be instantiated on the primary element. +If present, the Large Composition Data Client model must only be instantiated on the primary +element. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst index df724974b86..f96436138b7 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst @@ -3,24 +3,33 @@ Large Composition Data Server ############################# -The Large Composition Data Server model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_SRV` option. +The Large Composition Data Server model is a foundation model defined by the Bluetooth mesh +specification. The model is optional, and is enabled through the +:kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_SRV` option. -The Large Composition Data Server model was introduced in the Bluetooth Mesh Protocol Specification version 1.1, and is used to support -the functionality of exposing pages of Composition Data that do not fit in a Config Composition Data Status message and to expose metadata of the model instances. +The Large Composition Data Server model was introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and is used to support the functionality of exposing pages of Composition Data that do +not fit in a Config Composition Data Status message and to expose metadata of the model instances. -The Large Composition Data Server does not have an API of its own and relies on a :ref:`bluetooth_mesh_lcd_cli` to control it. -The model only accepts messages encrypted with the node's device key. +The Large Composition Data Server does not have an API of its own and relies on a +:ref:`bluetooth_mesh_lcd_cli` to control it. The model only accepts messages encrypted with the +node's device key. -If present, the Large Composition Data Server model must only be instantiated on the primary element. +If present, the Large Composition Data Server model must only be instantiated on the primary +element. Models metadata =============== -The Large Composition Data Server model allows each model to have a list of model's specific metadata that can be read by the Large Composition Data Client model. -The metadata list can be associated with the :c:struct:`bt_mesh_model` through the :c:member:`bt_mesh_model.metadata` field. -The metadata list consists of one or more entries defined by the :c:struct:`bt_mesh_models_metadata_entry` structure. Each entry contains the length and ID of the metadata, and a pointer to the raw data. -Entries can be created using the :c:macro:`BT_MESH_MODELS_METADATA_ENTRY` macro. The :c:macro:`BT_MESH_MODELS_METADATA_END` macro marks the end of the metadata list and must always be present. If the model has no metadata, the helper macro :c:macro:`BT_MESH_MODELS_METADATA_NONE` can be used instead. +The Large Composition Data Server model allows each model to have a list of model's specific +metadata that can be read by the Large Composition Data Client model. The metadata list can be +associated with the :c:struct:`bt_mesh_model` through the :c:member:`bt_mesh_model.metadata` field. +The metadata list consists of one or more entries defined by the +:c:struct:`bt_mesh_models_metadata_entry` structure. Each entry contains the length and ID of the +metadata, and a pointer to the raw data. Entries can be created using the +:c:macro:`BT_MESH_MODELS_METADATA_ENTRY` macro. The :c:macro:`BT_MESH_MODELS_METADATA_END` macro +marks the end of the metadata list and must always be present. If the model has no metadata, the +helper macro :c:macro:`BT_MESH_MODELS_METADATA_NONE` can be used instead. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index 85d5f0519d9..5fc841716ce 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -3,15 +3,18 @@ On-Demand Private Proxy Client ############################## -The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` option. +The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth mesh +specification. The model is optional, and is enabled with the +:kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` option. -The On-Demand Private Proxy Client model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and is used to set and retrieve the On-Demand Private GATT Proxy state. The state defines -how long a node will advertise Mesh Proxy Service with Private Network Identity type after it receives a Solicitation PDU. +The On-Demand Private Proxy Client model was introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and is used to set and retrieve the On-Demand Private GATT Proxy state. The state +defines how long a node will advertise Mesh Proxy Service with Private Network Identity type after +it receives a Solicitation PDU. The On-Demand Private Proxy Client model communicates with an On-Demand Private Proxy Server model -using the device key of the node containing the target On-Demand Private Proxy Server model instance. +using the device key of the node containing the target On-Demand Private Proxy Server model +instance. If present, the On-Demand Private Proxy Client model must only be instantiated on the primary element. @@ -19,9 +22,11 @@ element. Configurations ************** -The On-Demand Private Proxy Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`. -The :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT` controls how long the Client waits for a state response message to arrive -in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_od_priv_proxy_cli_timeout_set`. +The On-Demand Private Proxy Client model behavior can be configured with the transmission timeout +option :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`. The +:kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT` controls how long the Client waits for a +state response message to arrive in milliseconds. This value can be changed at runtime using +:c:func:`bt_mesh_od_priv_proxy_cli_timeout_set`. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 4f20340f9e3..700517e4283 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -3,19 +3,19 @@ On-Demand Private Proxy Server ############################## -The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth -mesh specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_SRV` option. +The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth mesh +specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_SRV` option. -The On-Demand Private Proxy Server model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and supports the configuration of advertising with Private Network Identity type of a node -that is a recipient of Solicitation PDUs by managing its On-Demand Private GATT Proxy state. +The On-Demand Private Proxy Server model was introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and supports the configuration of advertising with Private Network Identity type of a +node that is a recipient of Solicitation PDUs by managing its On-Demand Private GATT Proxy state. -When enabled, the :ref:`bluetooth_mesh_srpl_srv` is also enabled. The On-Demand Private Proxy Server is dependent on the -:ref:`bluetooth_mesh_models_priv_beacon_srv` to be present on the node. +When enabled, the :ref:`bluetooth_mesh_srpl_srv` is also enabled. The On-Demand Private Proxy Server +is dependent on the :ref:`bluetooth_mesh_models_priv_beacon_srv` to be present on the node. The On-Demand Private Proxy Server does not have an API of its own, and relies on a -:ref:`bluetooth_mesh_od_cli` to control it. The On-Demand Private Proxy Server -model only accepts messages encrypted with the node's device key. +:ref:`bluetooth_mesh_od_cli` to control it. The On-Demand Private Proxy Server model only accepts +messages encrypted with the node's device key. If present, the On-Demand Private Proxy Server model must only be instantiated on the primary element. diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst index 687fc66e3f9..148557a4e81 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst @@ -3,24 +3,25 @@ Opcodes Aggregator Client ######################### -The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth -mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` option. +The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth mesh +specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` +option. -The Opcodes Aggregator Client model is introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and is used to support the functionality of dispatching -a sequence of access layer messages to nodes supporting the :ref:`bluetooth_mesh_models_op_agg_srv` model. +The Opcodes Aggregator Client model is introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and is used to support the functionality of dispatching a sequence of access layer +messages to nodes supporting the :ref:`bluetooth_mesh_models_op_agg_srv` model. -The Opcodes Aggregator Client model communicates with an Opcodes Aggregator Server model -using the device key of the target node or the application keys configured by the Configuration Client. +The Opcodes Aggregator Client model communicates with an Opcodes Aggregator Server model using the +device key of the target node or the application keys configured by the Configuration Client. If present, the Opcodes Aggregator Client model must only be instantiated on the primary element. The Opcodes Aggregator Client model is implicitly bound to the device key on initialization. It -should be bound to the same application keys as the client models that are used to produce the sequence of -messages. +should be bound to the same application keys as the client models that are used to produce the +sequence of messages. -To be able to aggregate a message from a client model, it should support an asynchronous -API, for example through callbacks. +To be able to aggregate a message from a client model, it should support an asynchronous API, for +example through callbacks. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst index d5b5e69347d..81bd4a90b22 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_srv.rst @@ -4,7 +4,8 @@ Opcodes Aggregator Server ######################### The Opcodes Aggregator Server model is a foundation model defined by the Bluetooth -mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_SRV` option. +mesh specification. It is an optional model, enabled with the +:kconfig:option:`CONFIG_BT_MESH_OP_AGG_SRV` option. The Opcodes Aggregator Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and is used to support the functionality of processing diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index 87ee3b07f1d..d9212e24bc0 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -3,11 +3,10 @@ Proxy ##### -The Proxy feature allows legacy devices like phones to access the Bluetooth -mesh network through GATT. The Proxy feature is only compiled in if the -:kconfig:option:`CONFIG_BT_MESH_GATT_PROXY` option is set. The Proxy feature state is -controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, and the initial value -can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. +The Proxy feature allows legacy devices like phones to access the Bluetooth mesh network through +GATT. The Proxy feature is only compiled in if the :kconfig:option:`CONFIG_BT_MESH_GATT_PROXY` +option is set. The Proxy feature state is controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, +and the initial value can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. Nodes with the Proxy feature enabled can advertise with Network Identity and Node Identity, which is controlled by the :ref:`bluetooth_mesh_models_cfg_cli`. @@ -17,8 +16,8 @@ The GATT Proxy state indicates if the Proxy feature is supported. Private Proxy ************* -A node supporting the Proxy feature and the :ref:`bluetooth_mesh_models_priv_beacon_srv` model can advertise with -Private Network Identity and Private Node Identity types, which is controlled by the +A node supporting the Proxy feature and the :ref:`bluetooth_mesh_models_priv_beacon_srv` model can +advertise with Private Network Identity and Private Node Identity types, which is controlled by the :ref:`bluetooth_mesh_models_priv_beacon_cli`. By advertising with this set of identification types, the node allows the legacy device to connect to the network over GATT while maintaining the privacy of the network. @@ -28,28 +27,32 @@ The Private GATT Proxy state indicates whether the Private Proxy functionality i Proxy Solicitation ****************** -In the case where both GATT Proxy and Private GATT Proxy states are disabled on a node, a legacy device cannot -connect to it. A node supporting the :ref:`bluetooth_mesh_od_srv` may however be +In the case where both GATT Proxy and Private GATT Proxy states are disabled on a node, a legacy +device cannot connect to it. A node supporting the :ref:`bluetooth_mesh_od_srv` may however be solicited to advertise connectable advertising events without enabling the Private GATT Proxy state. -To solicit the node, the legacy device can send a Solicitation PDU by calling the :func:`bt_mesh_proxy_solicit` function. -To enable this feature, the client must to be compiled with the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` -option set. +To solicit the node, the legacy device can send a Solicitation PDU by calling the +:func:`bt_mesh_proxy_solicit` function. To enable this feature, the client must to be compiled with +the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` option set. -Solicitation PDUs are non-mesh, non-connectable, undirected advertising messages -containing Proxy Solicitation UUID, encrypted with the network key of the subnet that the legacy device -wants to connect to. The PDU contains the source address of the legacy device and a sequence number. The -sequence number is maintained by the legacy device and is incremented for every new Solicitation PDU sent. +Solicitation PDUs are non-mesh, non-connectable, undirected advertising messages containing Proxy +Solicitation UUID, encrypted with the network key of the subnet that the legacy device wants to +connect to. The PDU contains the source address of the legacy device and a sequence number. The +sequence number is maintained by the legacy device and is incremented for every new Solicitation PDU +sent. -Each node supporting the Solicitation PDU reception holds its own Solicitation Replay Protection List (SRPL). -The SRPL protects the solicitation mechanism from replay attacks by storing solicitation sequence number (SSEQ) -and solicitation source (SSRC) pairs of valid Solicitation PDUs processed by the node. The delay between updating the -SRPL and storing the change to the persistent storage is defined by :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. +Each node supporting the Solicitation PDU reception holds its own Solicitation Replay Protection +List (SRPL). The SRPL protects the solicitation mechanism from replay attacks by storing +solicitation sequence number (SSEQ) and solicitation source (SSRC) pairs of valid Solicitation PDUs +processed by the node. The delay between updating the SRPL and storing the change to the persistent +storage is defined by :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. The Solicitation PDU RPL Configuration models, :ref:`bluetooth_mesh_srpl_cli` and -:ref:`bluetooth_mesh_srpl_srv`, provide the functionality of saving and clearing SRPL entries. -A node that supports the Solicitation PDU RPL Configuration Client model can clear a section of the SRPL on the target by calling the :func:`bt_mesh_sol_pdu_rpl_clear` function. -Communication between the Solicitation PDU RPL Configuration Client and Server is encrypted using the application key, therefore, -the Solicitation PDU RPL Configuration Client can be instantiated on any device in the network. +:ref:`bluetooth_mesh_srpl_srv`, provide the functionality of saving and clearing SRPL entries. A +node that supports the Solicitation PDU RPL Configuration Client model can clear a section of the +SRPL on the target by calling the :func:`bt_mesh_sol_pdu_rpl_clear` function. Communication between +the Solicitation PDU RPL Configuration Client and Server is encrypted using the application key, +therefore, the Solicitation PDU RPL Configuration Client can be instantiated on any device in the +network. When the node receives the Solicitation PDU and successfully authenticates it, it will start advertising connectable advertisements with the Private Network Identity type. The duration of the diff --git a/doc/connectivity/bluetooth/api/mesh/rpr_cli.rst b/doc/connectivity/bluetooth/api/mesh/rpr_cli.rst index 38cb8849f9e..8a87939541a 100644 --- a/doc/connectivity/bluetooth/api/mesh/rpr_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/rpr_cli.rst @@ -9,7 +9,9 @@ mesh specification. It is enabled with the The Remote Provisioning Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1. -This model provides functionality to remotely provision devices into a mesh network, and perform Node Provisioning Protocol Interface procedures by interacting with mesh nodes that support the :ref:`bluetooth_mesh_models_rpr_srv` model. +This model provides functionality to remotely provision devices into a mesh network, and perform +Node Provisioning Protocol Interface procedures by interacting with mesh nodes that support the +:ref:`bluetooth_mesh_models_rpr_srv` model. The Remote Provisioning Client model communicates with a Remote Provisioning Server model using the device key of the node containing the target Remote Provisioning Server model instance. @@ -20,7 +22,9 @@ element. Scanning ******** -The scanning procedure is used to scan for unprovisioned devices located nearby the Remote Provisioning Server. The Remote Provisioning Client starts a scan procedure by using the :c:func:`bt_mesh_rpr_scan_start` call: +The scanning procedure is used to scan for unprovisioned devices located nearby the Remote +Provisioning Server. The Remote Provisioning Client starts a scan procedure by using the +:c:func:`bt_mesh_rpr_scan_start` call: .. code-block:: C @@ -49,21 +53,24 @@ The scanning procedure is used to scan for unprovisioned devices located nearby bt_mesh_rpr_scan_start(&rpr_cli, &srv, uuid, timeout, max_devs, &status); -The above example shows pseudo code for starting a scan procedure on the target Remote Provisioning Server node. This -procedure will start a ten-second, multiple-device scanning where the generated scan report will contain -a maximum of three unprovisioned devices. If the UUID argument was specified, the same procedure would -only scan for the device with the corresponding UUID. After the procedure completes, the -server sends the scan report that will be handled in the client's :c:member:`bt_mesh_rpr_cli.scan_report` callback. +The above example shows pseudo code for starting a scan procedure on the target Remote Provisioning +Server node. This procedure will start a ten-second, multiple-device scanning where the generated +scan report will contain a maximum of three unprovisioned devices. If the UUID argument was +specified, the same procedure would only scan for the device with the corresponding UUID. After the +procedure completes, the server sends the scan report that will be handled in the client's +:c:member:`bt_mesh_rpr_cli.scan_report` callback. Additionally, the Remote Provisioning Client model also supports extended scanning with the -:c:func:`bt_mesh_rpr_scan_start_ext` call. Extended scanning supplements regular scanning by allowing the -Remote Provisioning Server to report additional data for a specific device. The Remote Provisioning Server will use active scanning to request -a scan response from the unprovisioned device if it is supported by the unprovisioned device. +:c:func:`bt_mesh_rpr_scan_start_ext` call. Extended scanning supplements regular scanning by +allowing the Remote Provisioning Server to report additional data for a specific device. The Remote +Provisioning Server will use active scanning to request a scan response from the unprovisioned +device if it is supported by the unprovisioned device. Provisioning ************ -The Remote Provisioning Client starts a provisioning procedure by using the :c:func:`bt_mesh_provision_remote` call: +The Remote Provisioning Client starts a provisioning procedure by using the +:c:func:`bt_mesh_provision_remote` call: .. code-block:: C @@ -81,25 +88,27 @@ The Remote Provisioning Client starts a provisioning procedure by using the :c:f bt_mesh_provision_remote(&rpr_cli, &srv, uuid, net_idx, addr); -The above example shows pseudo code for remotely provisioning a device through a Remote Provisioning Server node. This -procedure will attempt to provision the device with the corresponding UUID, and assign the address 0x0006 -to its primary element using the network key located at index zero. +The above example shows pseudo code for remotely provisioning a device through a Remote Provisioning +Server node. This procedure will attempt to provision the device with the corresponding UUID, and +assign the address 0x0006 to its primary element using the network key located at index zero. .. note:: - During the remote provisioning, the same :c:struct:`bt_mesh_prov` callbacks are triggered as for ordinary - provisioning. See section :ref:`bluetooth_mesh_provisioning` for further details. + During the remote provisioning, the same :c:struct:`bt_mesh_prov` callbacks are triggered as for + ordinary provisioning. See section :ref:`bluetooth_mesh_provisioning` for further details. Re-provisioning *************** -In addition to scanning and provisioning functionality, the Remote Provisioning Client also provides means to -reconfigure node addresses, device keys and Composition Data on devices that support the -:ref:`bluetooth_mesh_models_rpr_srv` model. This is provided through the Node Provisioning Protocol Interface -(NPPI) which supports the following three procedures: +In addition to scanning and provisioning functionality, the Remote Provisioning Client also provides +means to reconfigure node addresses, device keys and Composition Data on devices that support the +:ref:`bluetooth_mesh_models_rpr_srv` model. This is provided through the Node Provisioning Protocol +Interface (NPPI) which supports the following three procedures: -* Device Key Refresh procedure: Used to change the device key of the Target node without a need to reconfigure the node. +* Device Key Refresh procedure: Used to change the device key of the Target node without a need to + reconfigure the node. * Node Address Refresh procedure: Used to change the node’s device key and unicast address. -* Node Composition Refresh procedure: Used to change the device key of the node, and to add or delete models or features of the node. +* Node Composition Refresh procedure: Used to change the device key of the node, and to add or + delete models or features of the node. The three NPPI procedures can be initiated with the :c:func:`bt_mesh_reprovision_remote` call: @@ -117,12 +126,13 @@ The three NPPI procedures can be initiated with the :c:func:`bt_mesh_reprovision bt_mesh_reprovision_remote(&rpr_cli, &srv, new_addr, composition_changed); -The above example shows pseudo code for triggering a Node Address Refresh procedure on the Target node. -The specific procedure is not chosen directly, but rather through the other parameters that are inputted. -In the example we can see that the current unicast address of the Target is 0x0006, while the new address is -set to 0x0009. If the two addresses were the same, and the ``composition_changed`` flag was set to true, this code -would instead trigger a Node Composition Refresh procedure. If the two addresses were the same, and -the ``composition_changed`` flag was set to false, this code would trigger a Device Key Refresh procedure. +The above example shows pseudo code for triggering a Node Address Refresh procedure on the Target +node. The specific procedure is not chosen directly, but rather through the other parameters that +are inputted. In the example we can see that the current unicast address of the Target is 0x0006, +while the new address is set to 0x0009. If the two addresses were the same, and the +``composition_changed`` flag was set to true, this code would instead trigger a Node Composition +Refresh procedure. If the two addresses were the same, and the ``composition_changed`` flag was set +to false, this code would trigger a Device Key Refresh procedure. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst index 0dfb0917541..63c159cd2b0 100644 --- a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst @@ -17,9 +17,9 @@ model only accepts messages encrypted with the node's device key. If present, the Remote Provisioning Server model must be instantiated on the primary element. -Note that after refreshing the device key, node address or Composition Data through a Node Provisioning Protocol -Interface (NPPI) procedure, the :c:member:`bt_mesh_prov.reprovisioned` callback is triggered. See section -:ref:`bluetooth_mesh_models_rpr_cli` for further details. +Note that after refreshing the device key, node address or Composition Data through a Node +Provisioning Protocol Interface (NPPI) procedure, the :c:member:`bt_mesh_prov.reprovisioned` +callback is triggered. See section :ref:`bluetooth_mesh_models_rpr_cli` for further details. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst index 93186f2988e..a0aa2b46a3e 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst @@ -3,38 +3,42 @@ Segmentation and reassembly (SAR) ################################# -Segmentation and reassembly (SAR) provides a way of handling larger upper transport layer messages in a -mesh network, with a purpose of enhancing the Bluetooth mesh throughput. The segmentation and +Segmentation and reassembly (SAR) provides a way of handling larger upper transport layer messages +in a mesh network, with a purpose of enhancing the Bluetooth mesh throughput. The segmentation and reassembly mechanism is used by the lower transport layer. -The lower transport layer defines how the upper transport layer PDUs are segmented and reassembled into multiple Lower Transport PDUs, -and sends them to the lower transport layer on a peer device. -If the Upper Transport PDU fits, it is sent in a single Lower Transport PDU. -For longer packets, which do not fit into a single Lower Transport PDU, the lower transport layer performs segmentation, splitting the Upper Transport +The lower transport layer defines how the upper transport layer PDUs are segmented and reassembled +into multiple Lower Transport PDUs, and sends them to the lower transport layer on a peer device. +If the Upper Transport PDU fits, it is sent in a single Lower Transport PDU. For longer packets, +which do not fit into a single Lower Transport PDU, the lower transport layer performs segmentation, +splitting the Upper Transport PDU into multiple segments. -The lower transport layer on the receiving device reassembles the segments into a single Upper Transport PDU before passing it -up the stack. Delivery of a segmented message is acknowledged by the lower transport layer of the receiving node, while an unsegmented message -delivery is not acknowledged. -However, an Upper Transport PDU that fits into one Lower Transport PDU can also be sent as a single-segment segmented message when acknowledgment -by the lower transport layer is required. -Set the ``send rel`` flag (see :c:struct:`bt_mesh_msg_ctx`) to use the reliable message transmission and acknowledge single-segment segmented messages. +The lower transport layer on the receiving device reassembles the segments into a single Upper +Transport PDU before passing it up the stack. Delivery of a segmented message is acknowledged by the +lower transport layer of the receiving node, while an unsegmented message delivery is not +acknowledged. However, an Upper Transport PDU that fits into one Lower Transport PDU can also be +sent as a single-segment segmented message when acknowledgment by the lower transport layer is +required. Set the ``send rel`` flag (see :c:struct:`bt_mesh_msg_ctx`) to use the reliable message +transmission and acknowledge single-segment segmented messages. -The transport layer is able to transport up to 32 segments with its SAR mechanism, with a maximum message (PDU) size of 384 octets. -To configure message size for the Bluetooth mesh stack, use the following Kconfig options: +The transport layer is able to transport up to 32 segments with its SAR mechanism, with a maximum +message (PDU) size of 384 octets. To configure message size for the Bluetooth mesh stack, use the +following Kconfig options: * :kconfig:option:`CONFIG_BT_MESH_RX_SEG_MAX` to set the maximum number of segments in an incoming message. * :kconfig:option:`CONFIG_BT_MESH_TX_SEG_MAX` to set the maximum number of segments in an outgoing message. -The Kconfig options :kconfig:option:`CONFIG_BT_MESH_TX_SEG_MSG_COUNT` and :kconfig:option:`CONFIG_BT_MESH_RX_SEG_MSG_COUNT` define how many -outgoing and incoming segmented messages can be processed simultaneously. When more than one segmented message is sent to the same destination, -the messages are queued and sent one at a time. +The Kconfig options :kconfig:option:`CONFIG_BT_MESH_TX_SEG_MSG_COUNT` and +:kconfig:option:`CONFIG_BT_MESH_RX_SEG_MSG_COUNT` define how many outgoing and incoming segmented +messages can be processed simultaneously. When more than one segmented message is sent to the same +destination, the messages are queued and sent one at a time. -Incoming and outgoing segmented messages share the same pool for allocation of their segments. This pool size is configured through the -:kconfig:option:`CONFIG_BT_MESH_SEG_BUFS` Kconfig option. -Both incoming and outgoing messages allocate segments at the start of the transaction. -The outgoing segmented message releases its segments one by one as soon as they are acknowledged by the receiver, while the incoming message releases -the segments first after the message is fully received. +Incoming and outgoing segmented messages share the same pool for allocation of their segments. This +pool size is configured through the :kconfig:option:`CONFIG_BT_MESH_SEG_BUFS` Kconfig option. +Both incoming and outgoing messages allocate segments at the start of the transaction. The outgoing +segmented message releases its segments one by one as soon as they are acknowledged by the receiver, +while the incoming message releases the segments first after the message is fully received. Keep this in mind when defining the size of the buffers. SAR does not impose extra overhead on the access layer payload per segment. @@ -46,17 +50,19 @@ The current stable stack implementation allows you to configure the following SA When sending a segmented message to a unicast address, the unacknowledged segments are repeated the :kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT` number of times before the transmission -is considered as failed. The same option configures a number of retransmissions to a group or virtual -address, but the transmission always succeedes after retransmitting all segments the configured -number of times. +is considered as failed. The same option configures a number of retransmissions to a group or +virtual address, but the transmission always succeedes after retransmitting all segments the +configured number of times. The timeout between each retransmission to a unicast address is configured by the Kconfig option -:kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST`. The timeout between each retransmission -to a group or a virtual address is configured by the Kconfig option :kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP`. +:kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST`. The timeout between each +retransmission to a group or a virtual address is configured by the Kconfig option +:kconfig:option:`CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP`. The time before sending a Segment Acknowledgment message is controlled by the Kconfig options -:kconfig:option:`CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT`, :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT` -and :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`, and is defined as: +:kconfig:option:`CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT`, +:kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT` and +:kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`, and is defined as: .. math:: \begin{aligned} @@ -68,48 +74,57 @@ and :kconfig:option:`CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`, and is defined Segmentation and reassembly (SAR) Configuration models ====================================================== -With Bluetooth Mesh Protocol Specification version 1.1, it became possible to configure SAR behavior, such as intervals, -timers and retransmission counters, over a mesh network using SAR Configuration models: +With Bluetooth Mesh Protocol Specification version 1.1, it became possible to configure SAR +behavior, such as intervals, timers and retransmission counters, over a mesh network using SAR +Configuration models: * :ref:`bluetooth_mesh_sar_cfg_cli` * :ref:`bluetooth_mesh_sar_cfg_srv` -The following SAR behavior applies regardless of the presence of a SAR Configuration Server on a node. +The following SAR behavior applies regardless of the presence of a SAR Configuration Server on a +node. -Transmission of segments is separated by a segment transmission interval (see the `SAR Segment Interval Step`_ state). -Other configurable time intervals and delays available for the segmentation and reassembly are: +Transmission of segments is separated by a segment transmission interval (see the +`SAR Segment Interval Step`_ state). Other configurable time intervals and delays available for the +segmentation and reassembly are: * Interval between unicast retransmissions (see the states `SAR Unicast Retransmissions Interval Step`_ and `SAR Unicast Retransmissions Interval Increment`_). * Interval between multicast retransmissions (see the `SAR Multicast Retransmissions Interval Step`_ state). * Segment reception interval (see the `SAR Receiver Segment Interval Step`_ state). * Acknowledgment delay increment (see the `SAR Acknowledgment Delay Increment`_ state). -When the last segment marked as unacknowledged is transmitted, the lower transport layer starts a retransmissions timer. -The initial value of the SAR Unicast Retransmissions timer depends on the value of the TTL field of the message. -If the TTL field value is greater than ``0``, the initial value for the timer is set according to the following formula: +When the last segment marked as unacknowledged is transmitted, the lower transport layer starts a +retransmissions timer. The initial value of the SAR Unicast Retransmissions timer depends on the +value of the TTL field of the message. If the TTL field value is greater than ``0``, the initial +value for the timer is set according to the following formula: .. math:: unicast~retransmissions~interval~step + unicast~retransmissions~interval~increment \times (TTL - 1) -If the TTL field value is ``0``, the initial value of the timer is set to the unicast retransmissions interval step. +If the TTL field value is ``0``, the initial value of the timer is set to the unicast +retransmissions interval step. -The initial value of the SAR Multicast Retransmissions timer is set to the multicast retransmissions interval. +The initial value of the SAR Multicast Retransmissions timer is set to the multicast retransmissions +interval. -When the lower transport layer receives a message segment, it starts a SAR Discard timer. -The discard timer tells how long the lower transport layer waits before discarding the segmented message the segment belongs to. -The initial value of the SAR Discard timer is the discard timeout value indicated by the `SAR Discard Timeout`_ state. +When the lower transport layer receives a message segment, it starts a SAR Discard timer. The +discard timer tells how long the lower transport layer waits before discarding the segmented message +the segment belongs to. The initial value of the SAR Discard timer is the discard timeout value +indicated by the `SAR Discard Timeout`_ state. -SAR Acknowledgment timer holds the time before a Segment Acknowledgment message is sent for a received segment. -The initial value of the SAR Acknowledgment timer is calculated using the following formula: +SAR Acknowledgment timer holds the time before a Segment Acknowledgment message is sent for a +received segment. The initial value of the SAR Acknowledgment timer is calculated using the +following formula: .. math:: min(SegN + 0.5 , acknowledgment~delay~increment) \times segment~reception~interval -The ``SegN`` field value identifies the total number of segments the Upper Transport PDU is segmented into. +The ``SegN`` field value identifies the total number of segments the Upper Transport PDU is +segmented into. Four counters are related to SAR behavior: @@ -117,8 +132,9 @@ Four counters are related to SAR behavior: * Multicast retransmissions count (see `SAR Multicast Retransmissions Count`_ state) * Acknowledgment retransmissions count (see `SAR Acknowledgment Retransmissions Count`_ state) -If the number of segments in the transmission is higher than the value of the `SAR Segments Threshold`_ state, Segment Acknowledgment messages are -retransmitted using the value of the `SAR Acknowledgment Retransmissions Count`_ state. +If the number of segments in the transmission is higher than the value of the +`SAR Segments Threshold`_ state, Segment Acknowledgment messages are retransmitted using the value +of the `SAR Acknowledgment Retransmissions Count`_ state. .. _bt_mesh_sar_cfg_states: @@ -130,8 +146,8 @@ There are two states defined related to segmentation and reassembly: * SAR Transmitter state * SAR Receiver state -The SAR Transmitter state is a composite state that controls the number and timing of transmissions of segmented messages. -It includes the following states: +The SAR Transmitter state is a composite state that controls the number and timing of transmissions +of segmented messages. It includes the following states: * SAR Segment Interval Step * SAR Unicast Retransmissions Count @@ -141,8 +157,9 @@ It includes the following states: * SAR Multicast Retransmissions Count * SAR Multicast Retransmissions Interval Step -The SAR Receiver state is a composite state that controls the number and timing of Segment Acknowledgment transmissions and the discarding of reassembly of a segmented message. -It includes the following states: +The SAR Receiver state is a composite state that controls the number and timing of Segment +Acknowledgment transmissions and the discarding of reassembly of a segmented message. It includes +the following states: * SAR Segments Threshold * SAR Discard Timeout @@ -153,11 +170,11 @@ It includes the following states: SAR Segment Interval Step ------------------------- -SAR Segment Interval Step state holds a value that controls the interval between transmissions of segments of a segmented message. -The interval is measured in milliseconds. +SAR Segment Interval Step state holds a value that controls the interval between transmissions of +segments of a segmented message. The interval is measured in milliseconds. -Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP` Kconfig option to set the default value. -Segment transmission interval is then calculated using the following formula: +Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP` Kconfig option to set the default +value. Segment transmission interval is then calculated using the following formula: .. math:: @@ -167,24 +184,29 @@ Segment transmission interval is then calculated using the following formula: SAR Unicast Retransmissions Count --------------------------------- -SAR Unicast Retransmissions Count holds a value that defines the maximum number of retransmissions of a segmented message to a unicast destination. -Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT` Kconfig option to set the default value for this state. +SAR Unicast Retransmissions Count holds a value that defines the maximum number of retransmissions +of a segmented message to a unicast destination. Use the +:kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT` Kconfig option to set the default +value for this state. SAR Unicast Retransmissions Without Progress Count -------------------------------------------------- -This state holds a value that defines the maximum number of retransmissions of a segmented message to a unicast address that will be sent if no acknowledgment -was received during the timeout, or if an acknowledgment with already confirmed segments was received. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT` to set the maximum number of retransmissions. +This state holds a value that defines the maximum number of retransmissions of a segmented message +to a unicast address that will be sent if no acknowledgment was received during the timeout, or if +an acknowledgment with already confirmed segments was received. Use the Kconfig option +:kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT` to set the maximum number +of retransmissions. SAR Unicast Retransmissions Interval Step ----------------------------------------- -The value of this state controls the interval step used for delaying the retransmissions of unacknowledged segments of a segmented message to a unicast address. -The interval step is measured in milliseconds. +The value of this state controls the interval step used for delaying the retransmissions of +unacknowledged segments of a segmented message to a unicast address. The interval step is measured +in milliseconds. -Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP` Kconfig option to set the default value. -This value is then used to calculate the interval step using the following formula: +Use the :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP` Kconfig option to set the +default value. This value is then used to calculate the interval step using the following formula: .. math:: @@ -194,11 +216,13 @@ This value is then used to calculate the interval step using the following formu SAR Unicast Retransmissions Interval Increment ---------------------------------------------- -SAR Unicast Retransmissions Interval Increment holds a value that controls the interval increment used for delaying the retransmissions of unacknowledged -segments of a segmented message to a unicast address. The increment is measured in milliseconds. +SAR Unicast Retransmissions Interval Increment holds a value that controls the interval increment +used for delaying the retransmissions of unacknowledged segments of a segmented message to a unicast +address. The increment is measured in milliseconds. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC` to set the default value. -The Kconfig option value is used to calculate the increment using the following formula: +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC` to set the +default value. The Kconfig option value is used to calculate the increment using the following +formula: .. math:: @@ -208,17 +232,19 @@ The Kconfig option value is used to calculate the increment using the following SAR Multicast Retransmissions Count ----------------------------------- -The state holds a value that controls the total number of retransmissions of a segmented message to a multicast address. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT` to set the total number of retransmissions. +The state holds a value that controls the total number of retransmissions of a segmented message to +a multicast address. Use the Kconfig option +:kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT` to set the total number of +retransmissions. SAR Multicast Retransmissions Interval Step ------------------------------------------- -This state holds a value that controls the interval between retransmissions of all segments in a segmented message to a multicast address. -The interval is measured in milliseconds. +This state holds a value that controls the interval between retransmissions of all segments in a +segmented message to a multicast address. The interval is measured in milliseconds. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT` to set the default value that is used to calculate the interval -using the following formula: +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT` to set the +default value that is used to calculate the interval using the following formula: .. math:: @@ -228,9 +254,10 @@ using the following formula: SAR Discard Timeout ------------------- -The value of this state defines the time in seconds that the lower transport layer waits after receiving segments of a segmented message -before discarding that segmented message. Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT` to set the -default value. The discard timeout will be calculated using the following formula: +The value of this state defines the time in seconds that the lower transport layer waits after +receiving segments of a segmented message before discarding that segmented message. Use the Kconfig +option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT` to set the default value. The discard +timeout will be calculated using the following formula: .. math:: @@ -240,38 +267,47 @@ default value. The discard timeout will be calculated using the following formul SAR Acknowledgment Delay Increment ---------------------------------- -This state holds a value that controls the delay increment of an interval used for delaying the transmission of an acknowledgment message after receiving a new segment. -The increment is measured in segments. +This state holds a value that controls the delay increment of an interval used for delaying the +transmission of an acknowledgment message after receiving a new segment. The increment is measured +in segments. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC` to set the default value. The increment value is calculated to be +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC` to set the default +value. The increment value is calculated to be :math:`\verb|CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC| + 1.5`. SAR Segments Threshold ---------------------- -SAR Segments Threshold state holds a value that defines a threshold in number of segments of a segmented message for acknowledgment retransmissions. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` to set the threshold. +SAR Segments Threshold state holds a value that defines a threshold in number of segments of a +segmented message for acknowledgment retransmissions. Use the Kconfig option +:kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` to set the threshold. -When the number of segments of a segmented message is above this threshold, the stack will additionally retransmit every acknowledgment message the -number of times given by the value of :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT`. +When the number of segments of a segmented message is above this threshold, the stack will +additionally retransmit every acknowledgment message the number of times given by the value of +:kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT`. SAR Acknowledgment Retransmissions Count ---------------------------------------- -The SAR Acknowledgment Retransmissions Count state controls the number of retransmissions of Segment Acknowledgment messages sent by the lower transport layer. -It gives the total number of retranmissions of an acknowledgment message that the stack will additionally send when the size of segments in a -segmented message is above the :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` value. +The SAR Acknowledgment Retransmissions Count state controls the number of retransmissions of Segment +Acknowledgment messages sent by the lower transport layer. It gives the total number of +retranmissions of an acknowledgment message that the stack will additionally send when the size of +segments in a segmented message is above the :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD` +value. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT` to set the default value for this state. -The maximum number of transmissions of a Segment Acknowledgment message is :math:`\verb|CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT| + 1`. +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT` to set the default +value for this state. The maximum number of transmissions of a Segment Acknowledgment message is +:math:`\verb|CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT| + 1`. SAR Receiver Segment Interval Step ---------------------------------- -The SAR Receiver Segment Interval Step defines the segments reception interval step used for delaying the transmission of an acknowledgment message after receiving a new segment. -The interval is measured in milliseconds. +The SAR Receiver Segment Interval Step defines the segments reception interval step used for +delaying the transmission of an acknowledgment message after receiving a new segment. The interval +is measured in milliseconds. -Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP` to set the default value and calculate the interval using the following formula: +Use the Kconfig option :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP` to set the default value +and calculate the interval using the following formula: .. math:: diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst index cc9dc8947a7..b017b53a01a 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst @@ -3,26 +3,33 @@ SAR Configuration Client ######################## -The SAR Configuration Client model is a foundation model defined by the Bluetooth mesh specification. -It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. +The SAR Configuration Client model is a foundation model defined by the Bluetooth mesh +specification. It is an optional model, enabled with the +:kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. -The SAR Configuration Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, -and it supports the configuration of the lower transport layer behavior of a node that supports the :ref:`bluetooth_mesh_sar_cfg_srv` model. +The SAR Configuration Client model is introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and it supports the configuration of the lower transport layer behavior of a node that +supports the :ref:`bluetooth_mesh_sar_cfg_srv` model. -The model can send messages to query or change the states supported by the SAR Configuration Server (SAR Transmitter and SAR Receiver) using SAR Configuration messages. +The model can send messages to query or change the states supported by the SAR Configuration Server +(SAR Transmitter and SAR Receiver) using SAR Configuration messages. -The SAR Transmitter procedure is used to determine and configure the SAR Transmitter state of a SAR Configuration Server. -Function calls :c:func:`bt_mesh_sar_cfg_cli_transmitter_get` and :c:func:`bt_mesh_sar_cfg_cli_transmitter_set` are used to get and set the SAR Transmitter state +The SAR Transmitter procedure is used to determine and configure the SAR Transmitter state of a SAR +Configuration Server. Function calls :c:func:`bt_mesh_sar_cfg_cli_transmitter_get` and +:c:func:`bt_mesh_sar_cfg_cli_transmitter_set` are used to get and set the SAR Transmitter state of the Target node respectively. -The SAR Receiver procedure is used to determine and configure the SAR Receiver state of a SAR Configuration Server. -Function calls :c:func:`bt_mesh_sar_cfg_cli_receiver_get` and :c:func:`bt_mesh_sar_cfg_cli_receiver_set` are used to get and set the SAR Receiver state of the +The SAR Receiver procedure is used to determine and configure the SAR Receiver state of a SAR +Configuration Server. Function calls :c:func:`bt_mesh_sar_cfg_cli_receiver_get` and +:c:func:`bt_mesh_sar_cfg_cli_receiver_set` are used to get and set the SAR Receiver state of the Target node respectively. For more information about the two states, see :ref:`bt_mesh_sar_cfg_states`. -An element can send any SAR Configuration Client message at any time to query or change the states supported by the SAR Configuration Server model of a peer node. -The SAR Configuration Client model only accepts messages encrypted with the device key of the node supporting the SAR Configuration Server model. +An element can send any SAR Configuration Client message at any time to query or change the states +supported by the SAR Configuration Server model of a peer node. The SAR Configuration Client model +only accepts messages encrypted with the device key of the node supporting the SAR Configuration +Server model. If present, the SAR Configuration Client model must only be instantiated on the primary element. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst index d1429bac8fd..2ea1446c9ea 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst @@ -3,11 +3,13 @@ SAR Configuration Server ######################## -The SAR Configuration Server model is a foundation model defined by the Bluetooth mesh specification. -It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_SRV` configuration option. +The SAR Configuration Server model is a foundation model defined by the Bluetooth mesh +specification. It is an optional model, enabled with the +:kconfig:option:`CONFIG_BT_MESH_SAR_CFG_SRV` configuration option. -The SAR Configuration Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, -and it supports the configuration of the :ref:`segmentation and reassembly (SAR) ` behavior of a Bluetooth mesh node. +The SAR Configuration Server model is introduced in the Bluetooth Mesh Protocol Specification +version 1.1, and it supports the configuration of the +:ref:`segmentation and reassembly (SAR) ` behavior of a Bluetooth mesh node. The model defines a set of states and messages for the SAR configuration. The SAR Configuration Server model defines two states, SAR Transmitter state and SAR Receiver state. @@ -15,8 +17,9 @@ For more information about the two states, see :ref:`bt_mesh_sar_cfg_states`. The model also supports the SAR Transmitter and SAR Receiver get and set messages. -The SAR Configuration Server model does not have an API of its own, but relies on a :ref:`bluetooth_mesh_sar_cfg_cli` to control it. -The SAR Configuration Server model only accepts messages encrypted with the node’s device key. +The SAR Configuration Server model does not have an API of its own, but relies on a +:ref:`bluetooth_mesh_sar_cfg_cli` to control it. The SAR Configuration Server model only accepts +messages encrypted with the node’s device key. If present, the SAR Configuration Server model must only be instantiated on the primary element. diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 6f102b5490f..2522cd9f38b 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -3,26 +3,32 @@ Bluetooth Mesh Shell #################### -The Bluetooth mesh shell subsystem provides a set of Bluetooth mesh shell commands for the :ref:`shell_api` module. -It allows for testing and exploring the Bluetooth mesh API through an interactive interface, without having to write an application. +The Bluetooth mesh shell subsystem provides a set of Bluetooth mesh shell commands for the +:ref:`shell_api` module. It allows for testing and exploring the Bluetooth mesh API through an +interactive interface, without having to write an application. -The Bluetooth mesh shell interface provides access to most Bluetooth mesh features, including provisioning, configuration, and message sending. +The Bluetooth mesh shell interface provides access to most Bluetooth mesh features, including +provisioning, configuration, and message sending. Prerequisites ************* -The Bluetooth mesh shell subsystem depends on the application to create the composition data and do the mesh initialization. +The Bluetooth mesh shell subsystem depends on the application to create the composition data and do +the mesh initialization. Application *********** -The Bluetooth mesh shell subsystem is most easily used through the Bluetooth mesh shell application under ``tests/bluetooth/mesh_shell``. -See :ref:`shell_api` for information on how to connect and interact with the Bluetooth mesh shell application. +The Bluetooth mesh shell subsystem is most easily used through the Bluetooth mesh shell application +under ``tests/bluetooth/mesh_shell``. See :ref:`shell_api` for information on how to connect and +interact with the Bluetooth mesh shell application. Basic usage *********** -The Bluetooth mesh shell subsystem adds a single ``mesh`` command, which holds a set of sub-commands. Every time the device boots up, make sure to call ``mesh init`` before any of the other Bluetooth mesh shell commands can be called:: +The Bluetooth mesh shell subsystem adds a single ``mesh`` command, which holds a set of +sub-commands. Every time the device boots up, make sure to call ``mesh init`` before any of the +other Bluetooth mesh shell commands can be called:: uart:~$ mesh init @@ -31,26 +37,36 @@ This is done to ensure that all available log will be printed to the shell outpu Provisioning ============ -The mesh node must be provisioned to become part of the network. This is only necessary the first time the device boots up, as the device will remember its provisioning data between reboots. +The mesh node must be provisioned to become part of the network. This is only necessary the first +time the device boots up, as the device will remember its provisioning data between reboots. -The simplest way to provision the device is through self-provisioning. To do this the user must provision the device with the default network key and address ``0x0001``, execute:: +The simplest way to provision the device is through self-provisioning. To do this the user must +provision the device with the default network key and address ``0x0001``, execute:: uart:~$ mesh prov local 0 0x0001 -Since all mesh nodes use the same values for the default network key, this can be done on multiple devices, as long as they're assigned non-overlapping unicast addresses. Alternatively, to provision the device into an existing network, the unprovisioned beacon can be enabled with ``mesh prov pb-adv on`` or ``mesh prov pb-gatt on``. The beacons can be picked up by an external provisioner, which can provision the node into its network. +Since all mesh nodes use the same values for the default network key, this can be done on multiple +devices, as long as they're assigned non-overlapping unicast addresses. Alternatively, to provision +the device into an existing network, the unprovisioned beacon can be enabled with +``mesh prov pb-adv on`` or ``mesh prov pb-gatt on``. The beacons can be picked up by an external +provisioner, which can provision the node into its network. -Once the mesh node is part of a network, its transmission parameters can be controlled by the general configuration commands: +Once the mesh node is part of a network, its transmission parameters can be controlled by the +general configuration commands: * To set the destination address, call ``mesh target dst ``. * To set the network key index, call ``mesh target net ``. * To set the application key index, call ``mesh target app ``. -By default, the transmission parameters are set to send messages to the provisioned address and network key. +By default, the transmission parameters are set to send messages to the provisioned address and +network key. Configuration ============= -By setting the destination address to the local unicast address (``0x0001`` in the ``mesh prov local`` command above), we can perform self-configuration through any of the :ref:`bluetooth_mesh_shell_cfg_cli` commands. +By setting the destination address to the local unicast address (``0x0001`` in the +``mesh prov local`` command above), we can perform self-configuration through any of the +:ref:`bluetooth_mesh_shell_cfg_cli` commands. A good first step is to read out the node's own composition data:: @@ -65,7 +81,8 @@ Next, since the device has no application keys by default, it's a good idea to a Message sending =============== -With an application key added (see above), the mesh node's transition parameters are all valid, and the Bluetooth mesh shell can send raw mesh messages through the network. +With an application key added (see above), the mesh node's transition parameters are all valid, and +the Bluetooth mesh shell can send raw mesh messages through the network. For example, to send a Generic OnOff Set message, call:: @@ -74,16 +91,26 @@ For example, to send a Generic OnOff Set message, call:: .. note:: All multibyte fields model messages are in little endian, except the opcode. -The message will be sent to the current destination address, using the current network and application key indexes. As the destination address points to the local unicast address by default, the device will only send packets to itself. To change the destination address to the All Nodes broadcast address, call:: +The message will be sent to the current destination address, using the current network and +application key indexes. As the destination address points to the local unicast address by default, +the device will only send packets to itself. To change the destination address to the All Nodes +broadcast address, call:: uart:~$ mesh target dst 0xffff -With the destination address set to ``0xffff``, any other mesh nodes in the network with the configured network and application keys will receive and process the messages we send. +With the destination address set to ``0xffff``, any other mesh nodes in the network with the +configured network and application keys will receive and process the messages we send. .. note:: - To change the configuration of the device, the destination address must be set back to the local unicast address before issuing any configuration commands. + To change the configuration of the device, the destination address must be set back to the + local unicast address before issuing any configuration commands. -Sending raw mesh packets is a good way to test model message handler implementations during development, as it can be done without having to implement the sending model. By default, only the reception of the model messages can be tested this way, as the Bluetooth mesh shell only includes the foundation models. To receive a packet in the mesh node, you have to add a model with a valid opcode handler list to the composition data in ``subsys/bluetooth/mesh/shell.c``, and print the incoming message to the shell in the handler callback. +Sending raw mesh packets is a good way to test model message handler implementations during +development, as it can be done without having to implement the sending model. By default, only the +reception of the model messages can be tested this way, as the Bluetooth mesh shell only includes +the foundation models. To receive a packet in the mesh node, you have to add a model with a valid +opcode handler list to the composition data in ``subsys/bluetooth/mesh/shell.c``, and print the +incoming message to the shell in the handler callback. Parameter formats ***************** @@ -98,10 +125,12 @@ The Bluetooth mesh shell commands are parsed with a variety of formats: - Description - Example * - Integers - - The default format unless something else is specified. Can be either decimal or hexadecimal. + - The default format unless something else is specified. Can be either decimal or + hexadecimal. - ``1234``, ``0xabcd01234`` * - Hexstrings - - For raw byte arrays, like UUIDs, key values and message payloads, the parameters should be formatted as an unbroken string of hexadecimal values without any prefix. + - For raw byte arrays, like UUIDs, key values and message payloads, the parameters should + be formatted as an unbroken string of hexadecimal values without any prefix. - ``deadbeef01234`` * - Booleans - Boolean values are denoted in the API documentation as ````. @@ -110,7 +139,10 @@ The Bluetooth mesh shell commands are parsed with a variety of formats: Commands ******** -The Bluetooth mesh shell implements a large set of commands. Some of the commands accept parameters, which are mentioned in brackets after the command name. For example, ``mesh lpn set ``. Mandatory parameters are marked with angle brackets (e.g. ````), and optional parameters are marked with square brackets (e.g. ``[DstAddr]``). +The Bluetooth mesh shell implements a large set of commands. Some of the commands accept parameters, +which are mentioned in brackets after the command name. For example, +``mesh lpn set ``. Mandatory parameters are marked with angle brackets (e.g. +````), and optional parameters are marked with square brackets (e.g. ``[DstAddr]``). The Bluetooth mesh shell commands are divided into the following groups: @@ -119,7 +151,9 @@ The Bluetooth mesh shell commands are divided into the following groups: :local: .. note:: - Some commands depend on specific features being enabled in the compile time configuration of the application. Not all features are enabled by default. The list of available Bluetooth mesh shell commands can be shown in the shell by calling ``mesh`` without any arguments. + Some commands depend on specific features being enabled in the compile time configuration of + the application. Not all features are enabled by default. The list of available Bluetooth + mesh shell commands can be shown in the shell by calling ``mesh`` without any arguments. General configuration ===================== @@ -132,17 +166,21 @@ General configuration ``mesh reset-local`` -------------------- - Reset the local mesh node to its initial unprovisioned state. This command will also clear the Configuration Database (CDB) if present. + Reset the local mesh node to its initial unprovisioned state. This command will also clear + the Configuration Database (CDB) if present. Target ====== -The target commands enables the user to monitor and set the target destination address, network index and application index for the shell. These parameters are used by several commands, like provisioning, Configuration Client, etc. +The target commands enables the user to monitor and set the target destination address, network +index and application index for the shell. These parameters are used by several commands, like +provisioning, Configuration Client, etc. ``mesh target dst [DstAddr]`` ----------------------------- - Get or set the message destination address. The destination address determines where mesh packets are sent with the shell, but has no effect on modules outside the shell's control. + Get or set the message destination address. The destination address determines where mesh + packets are sent with the shell, but has no effect on modules outside the shell's control. * ``DstAddr``: If present, sets the new 16-bit mesh destination address. If omitted, the current destination address is printed. @@ -150,7 +188,10 @@ The target commands enables the user to monitor and set the target destination a ``mesh target net [NetKeyIdx]`` ------------------------------- - Get or set the message network index. The network index determines which network key is used to encrypt mesh packets that are sent with the shell, but has no effect on modules outside the shell's control. The network key must already be added to the device, either through provisioning or by a Configuration Client. + Get or set the message network index. The network index determines which network key is used + to encrypt mesh packets that are sent with the shell, but has no effect on modules outside + the shell's control. The network key must already be added to the device, either through + provisioning or by a Configuration Client. * ``NetKeyIdx``: If present, sets the new network index. If omitted, the current network index is printed. @@ -158,24 +199,30 @@ The target commands enables the user to monitor and set the target destination a ``mesh target app [AppKeyIdx]`` ------------------------------- - Get or set the message application index. The application index determines which application key is used to encrypt mesh packets that are sent with the shell, but has no effect on modules outside the shell's control. The application key must already be added to the device by a Configuration Client, and must be bound to the current network index. + Get or set the message application index. The application index determines which application + key is used to encrypt mesh packets that are sent with the shell, but has no effect on + modules outside the shell's control. The application key must already be added to the device + by a Configuration Client, and must be bound to the current network index. * ``AppKeyIdx``: If present, sets the new application index. If omitted, the current application index is printed. + Low Power Node ============== ``mesh lpn set `` ------------------------------- - Enable or disable Low Power operation. Once enabled, the device will turn off its radio and start polling for friend nodes. + Enable or disable Low Power operation. Once enabled, the device will turn off its radio and + start polling for friend nodes. * ``Val``: Sets whether Low Power operation is enabled. ``mesh lpn poll`` ----------------- - Perform a poll to the friend node, to receive any pending messages. Only available when LPN is enabled. + Perform a poll to the friend node, to receive any pending messages. Only available when LPN + is enabled. Testing ======= @@ -183,7 +230,8 @@ Testing ``mesh test net-send `` ----------------------------------- - Send a raw mesh message with the current destination address, network and application index. The message opcode must be encoded manually. + Send a raw mesh message with the current destination address, network and application index. + The message opcode must be encoded manually. * ``HexString`` Raw hexadecimal representation of the message to send. @@ -208,7 +256,9 @@ Testing .. warning:: - Clearing the replay protection list breaks the security mechanisms of the mesh node, making it susceptible to message replay attacks. This should never be performed in a real deployment. + Clearing the replay protection list breaks the security mechanisms of the mesh node, making + it susceptible to message replay attacks. This should never be performed in a real + deployment. Health Server Test ------------------ @@ -231,42 +281,58 @@ Health Server Test Provisioning ============ -To allow a device to broadcast connectable unprovisioned beacons, the :kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_GATT` option. +To allow a device to broadcast connectable unprovisioned beacons, the +:kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the +:kconfig:option:`CONFIG_BT_MESH_PB_GATT` option. ``mesh prov pb-gatt `` ------------------------------------ - Start or stop advertising a connectable unprovisioned beacon. The connectable unprovisioned beacon allows the mesh node to be discovered by nearby GATT based provisioners, and provisioned through the GATT bearer. + Start or stop advertising a connectable unprovisioned beacon. The connectable unprovisioned + beacon allows the mesh node to be discovered by nearby GATT based provisioners, and + provisioned through the GATT bearer. * ``Val``: Enable or disable provisioning with GATT -To allow a device to broadcast unprovisioned beacons, the :kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_ADV` option. +To allow a device to broadcast unprovisioned beacons, the +:kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the +:kconfig:option:`CONFIG_BT_MESH_PB_ADV` option. ``mesh prov pb-adv `` ----------------------------------- - Start or stop advertising the unprovisioned beacon. The unprovisioned beacon allows the mesh node to be discovered by nearby advertising-based provisioners, and provisioned through the advertising bearer. + Start or stop advertising the unprovisioned beacon. The unprovisioned beacon allows the mesh + node to be discovered by nearby advertising-based provisioners, and provisioned through the + advertising bearer. * ``Val``: Enable or disable provisioning with advertiser -To allow a device to provision devices, the :kconfig:option:`CONFIG_BT_MESH_PROVISIONER` and :kconfig:option:`CONFIG_BT_MESH_PB_ADV` configuration options must be enabled. +To allow a device to provision devices, the :kconfig:option:`CONFIG_BT_MESH_PROVISIONER` and +:kconfig:option:`CONFIG_BT_MESH_PB_ADV` configuration options must be enabled. ``mesh prov remote-adv `` ----------------------------------------------------------------------------------- - Provision a nearby device into the mesh. The mesh node starts scanning for unprovisioned beacons with the given UUID. Once found, the unprovisioned device will be added to the mesh network with the given unicast address, and given the network key indicated by ``NetKeyIdx``. + Provision a nearby device into the mesh. The mesh node starts scanning for unprovisioned + beacons with the given UUID. Once found, the unprovisioned device will be added to the mesh + network with the given unicast address, and given the network key indicated by + ``NetKeyIdx``. * ``UUID``: UUID of the unprovisioned device. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. * ``NetKeyIdx``: Index of the network key to pass to the device. * ``Addr``: First unicast address to assign to the unprovisioned device. The device will occupy as many addresses as it has elements, and all must be available. * ``AttDur``: The duration in seconds the unprovisioned device will identify itself for, if supported. See :ref:`bluetooth_mesh_models_health_srv_attention` for details. -To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT_MESH_PROVISIONER` and :kconfig:option:`CONFIG_BT_MESH_PB_GATT_CLIENT` configuration options must be enabled. +To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT_MESH_PROVISIONER` +and :kconfig:option:`CONFIG_BT_MESH_PB_GATT_CLIENT` configuration options must be enabled. ``mesh prov remote-gatt `` ------------------------------------------------------------------------- - Provision a nearby device into the mesh. The mesh node starts scanning for connectable advertising for PB-GATT with the given UUID. Once found, the unprovisioned device will be added to the mesh network with the given unicast address, and given the network key indicated by ``NetKeyIdx``. + Provision a nearby device into the mesh. The mesh node starts scanning for connectable + advertising for PB-GATT with the given UUID. Once found, the unprovisioned device will be + added to the mesh network with the given unicast address, and given the network key + indicated by ``NetKeyIdx``. * ``UUID``: UUID of the unprovisioned device. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. * ``NetKeyIdx``: Index of the network key to pass to the device. @@ -284,7 +350,9 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov input-num `` -------------------------------- - Input a numeric OOB authentication value. Only valid when prompted by the shell during provisioning. The input number must match the number presented by the other participant in the provisioning. + Input a numeric OOB authentication value. Only valid when prompted by the shell during + provisioning. The input number must match the number presented by the other participant in + the provisioning. * ``Number``: Decimal authentication number. @@ -292,7 +360,9 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov input-str `` -------------------------------- - Input an alphanumeric OOB authentication value. Only valid when prompted by the shell during provisioning. The input string must match the string presented by the other participant in the provisioning. + Input an alphanumeric OOB authentication value. Only valid when prompted by the shell during + provisioning. The input string must match the string presented by the other participant in + the provisioning. * ``String``: Unquoted alphanumeric authentication string. @@ -300,7 +370,10 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov static-oob [Val(1-32 hex)]`` ---------------------------------------- - Set or clear the static OOB authentication value. The static OOB authentication value must be set before provisioning starts to have any effect. The static OOB value must be same on both participants in the provisioning. To enable this command, the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. + Set or clear the static OOB authentication value. The static OOB authentication value must + be set before provisioning starts to have any effect. The static OOB value must be same on + both participants in the provisioning. To enable this command, the + :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. * ``Val``: If present, indicates the new hexadecimal value of the static OOB. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. If omitted, the static OOB value is cleared. @@ -308,7 +381,8 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov local [IVI]`` -------------------------------------------- - Provision the mesh node itself. If the Configuration database is enabled, the network key must be created. Otherwise, the default key value is used. + Provision the mesh node itself. If the Configuration database is enabled, the network key + must be created. Otherwise, the default key value is used. * ``NetKeyIdx``: Index of the network key to provision. * ``Addr``: First unicast address to assign to the device. The device will occupy as many addresses as it has elements, and all must be available. @@ -318,7 +392,9 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov beacon-listen `` ------------------------------------------ - Enable or disable printing of incoming unprovisioned beacons. Allows a provisioner device to detect nearby unprovisioned devices and provision them. To enable this command, the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. + Enable or disable printing of incoming unprovisioned beacons. Allows a provisioner device to + detect nearby unprovisioned devices and provision them. To enable this command, the + :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. * ``Val``: Whether to enable the unprovisioned beacon printing. @@ -330,7 +406,8 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov auth-method input `` ----------------------------------------------- - From the provisioner device, instruct the unprovisioned device to use the specified Input OOB authentication action. + From the provisioner device, instruct the unprovisioned device to use the specified Input + OOB authentication action. * ``Action`` - Input action. Allowed values: @@ -343,7 +420,8 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov auth-method output `` ------------------------------------------------ - From the provisioner device, instruct the unprovisioned device to use the specified Output OOB authentication action. + From the provisioner device, instruct the unprovisioned device to use the specified Output + OOB authentication action. * ``Action`` - Output action. Allowed values: @@ -356,25 +434,30 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ``mesh prov auth-method static `` ------------------------------------------------ - From the provisioner device, instruct the unprovisioned device to use static OOB authentication, and use the given static authentication value when provisioning. + From the provisioner device, instruct the unprovisioned device to use static OOB + authentication, and use the given static authentication value when provisioning. * ``Val`` - Static OOB value. Providing a hex-string shorter than 32 bytes will populate the N most significant bytes of the array and zero-pad the rest. ``mesh prov auth-method none`` ------------------------------ - From the provisioner device, don't use any authentication when provisioning new devices. This is the default behavior. + From the provisioner device, don't use any authentication when provisioning new devices. + This is the default behavior. Proxy ===== -The Proxy Server module is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_GATT_PROXY` configuration option. +The Proxy Server module is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_GATT_PROXY` configuration option. ``mesh proxy identity-enable`` ------------------------------ - Enable the Proxy Node Identity beacon, allowing Proxy devices to connect explicitly to this device. The beacon will run for 60 seconds before the node returns to normal Proxy beacons. + Enable the Proxy Node Identity beacon, allowing Proxy devices to connect explicitly to this + device. The beacon will run for 60 seconds before the node returns to normal Proxy beacons. -The Proxy Client module is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_PROXY_CLIENT` configuration option. +The Proxy Client module is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_PROXY_CLIENT` configuration option. ``mesh proxy connect `` ---------------------------------- @@ -395,7 +478,8 @@ The Proxy Client module is an optional mesh subsystem that can be enabled throug ``mesh proxy solicit `` ---------------------------------- - Begin Proxy Solicitation of a subnet. Support of this feature can be enabled through the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` configuration option. + Begin Proxy Solicitation of a subnet. Support of this feature can be enabled through the + :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` configuration option. * ``NetKeyIdx``: Index of the network key to send Solicitation PDUs to. @@ -407,9 +491,24 @@ Models Configuration Client -------------------- -The Configuration Client model is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_CFG_CLI` configuration option. This is implemented as a separate module (``mesh models cfg``) inside the ``mesh models`` subcommand list. This module will work on any instance of the Configuration Client model if the mentioned shell configuration options is enabled, and as long as the Configuration Client model is present in the model composition of the application. This shell module can be used for configuring itself and other nodes in the mesh network. - -The Configuration Client uses general message parameters set by ``mesh target dst`` and ``mesh target net`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, given that the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option is enabled with the shell provisioning context initialized, the Configuration Client model targets itself by default. Similarly, when another node has been provisioned by the Bluetooth mesh shell, the Configuration Client model targets the new node. In most common use-cases, the Configuration Client is depending on the provisioning features and the Configuration database to be fully functional. The Configuration Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and the mesh nodes it provisioned. The following steps are an example of how you can set up a device to start using the Configuration Client commands: +The Configuration Client model is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_CFG_CLI` configuration option. This is implemented as a separate +module (``mesh models cfg``) inside the ``mesh models`` subcommand list. This module will work on +any instance of the Configuration Client model if the mentioned shell configuration options is +enabled, and as long as the Configuration Client model is present in the model composition of the +application. This shell module can be used for configuring itself and other nodes in the mesh +network. + +The Configuration Client uses general message parameters set by ``mesh target dst`` and +``mesh target net`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, +given that the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option is enabled with the shell +provisioning context initialized, the Configuration Client model targets itself by default. +Similarly, when another node has been provisioned by the Bluetooth mesh shell, the Configuration +Client model targets the new node. In most common use-cases, the Configuration Client is depending +on the provisioning features and the Configuration database to be fully functional. The +Configuration Client always sends messages using the Device key bound to the destination address, +so it will only be able to configure itself and the mesh nodes it provisioned. The following steps +are an example of how you can set up a device to start using the Configuration Client commands: * Initialize the client node (``mesh init``). * Create the CDB (``mesh cdb create``). @@ -417,7 +516,8 @@ The Configuration Client uses general message parameters set by ``mesh target ds * The shell module should now target itself. * Monitor the composition data of the local node (``mesh models cfg get-comp``). * Configure the local node as desired with the Configuration Client commands. -* Provision other devices (``mesh prov beacon-listen``) (``mesh prov remote-adv``) (``mesh prov remote-gatt``). +* Provision other devices (``mesh prov beacon-listen``) (``mesh prov remote-adv``) + (``mesh prov remote-gatt``). * The shell module should now target the newly added node. * Monitor the newly provisioned nodes and their addresses (``mesh cdb show``). * Monitor the composition data of the target device (``mesh models cfg get-comp``). @@ -449,7 +549,8 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg get-comp [Page]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Read a composition data page. The full composition data page will be printed. If the target does not have the given page, it will return the last page before it. + Read a composition data page. The full composition data page will be printed. If the target + does not have the given page, it will return the last page before it. * ``Page``: The composition data page to request. Defaults to 0 if omitted. @@ -506,7 +607,7 @@ The Configuration Client uses general message parameters set by ``mesh target ds * ``0x02``: The feature is not supported. * ``Count``: Sets the new relay retransmit count if ``val`` is ``on``. Ignored if ``val`` is ``off``. Legal retransmit count is 0-7. Defaults to ``2`` if omitted. - * ``Int``: Sets the new relay retransmit interval in milliseconds if ``val`` is ``on``. Legal interval range is 10-320 milliseconds. Ignored if ``val`` is ``off``. Defaults to ``20`` if omitted. + * ``Int``: Sets the new relay retransmit interval in milliseconds if ``val`` is ``on``. Legal interval range is 10-320 milliseconds. Ignored if ``val`` is ``off``. Defaults to ``20`` if omitted. ``mesh models cfg node-id [Identity]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -566,7 +667,8 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg appkey add [Key(1-16 hex)]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add an application key to the target node. Adds the key to the Configuration Database if enabled. + Add an application key to the target node. Adds the key to the Configuration Database if + enabled. * ``NetKeyIdx``: The network key index the application key is bound to. * ``AppKeyIdx``: The application key index to add. @@ -601,7 +703,8 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg model app-bind [CID]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Bind an application key to a model. Models can only encrypt and decrypt messages sent with application keys they are bound to. + Bind an application key to a model. Models can only encrypt and decrypt messages sent with + application keys they are bound to. * ``Addr``: Address of the element the model is on. * ``AppKeyIdx``: The application key to bind to the model. @@ -633,8 +736,9 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg model pub [CID] [ ]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Get or set the publication parameters of a model. If all publication parameters are included, they become the new publication parameters of the model. - If all publication parameters are omitted, print the current publication parameters of the model. + Get or set the publication parameters of a model. If all publication parameters are + included, they become the new publication parameters of the model. If all publication + parameters are omitted, print the current publication parameters of the model. * ``Addr``: Address of the element the model is on. * ``MID``: The model ID of the model to get the bound keys of. @@ -685,7 +789,9 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg model sub-add [CID]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Subscription the model to a group address. Models only receive messages sent to their unicast address or a group or virtual address they subscribe to. Models may subscribe to multiple group and virtual addresses. + Subscription the model to a group address. Models only receive messages sent to their + unicast address or a group or virtual address they subscribe to. Models may subscribe to + multiple group and virtual addresses. * ``ElemAddr``: Address of the element the model is on. * ``SubAddr``: 16-bit group address the model should subscribe to (``0xc000`` to ``0xFEFF``). @@ -707,7 +813,9 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg model sub-add-va [CID]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Subscribe the model to a virtual address. Models only receive messages sent to their unicast address or a group or virtual address they subscribe to. Models may subscribe to multiple group and virtual addresses. + Subscribe the model to a virtual address. Models only receive messages sent to their unicast + address or a group or virtual address they subscribe to. Models may subscribe to multiple + group and virtual addresses. * ``ElemAddr``: Address of the element the model is on. * ``LabelUUID``: 128-bit label UUID of the virtual address to subscribe to. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. @@ -721,7 +829,7 @@ The Configuration Client uses general message parameters set by ``mesh target ds Unsubscribe a model from a virtual address. * ``ElemAddr``: Address of the element the model is on. - * ``LabelUUID``: 128-bit label UUID of the virtual address to remove the subscription of. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. + * ``LabelUUID``: 128-bit label UUID of the virtual address to remove the subscription of. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. * ``MID``: The model ID of the model to add the subscription to. * ``CID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. @@ -738,7 +846,9 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg model sub-ow-va [CID]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Overwrite all model subscriptions with a single new virtual address. Models only receive messages sent to their unicast address or a group or virtual address they subscribe to. Models may subscribe to multiple group and virtual addresses. + Overwrite all model subscriptions with a single new virtual address. Models only receive + messages sent to their unicast address or a group or virtual address they subscribe to. + Models may subscribe to multiple group and virtual addresses. * ``ElemAddr``: Address of the element the model is on. * ``LabelUUID``: 128-bit label UUID of the virtual address as the new Address to be added to the subscription list. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. @@ -779,7 +889,10 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg hb-sub [ ]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Get or set the Heartbeat subscription parameters. A node only receives Heartbeat messages matching the Heartbeat subscription parameters. Sets the Heartbeat subscription parameters if present, or prints the current Heartbeat subscription parameters if called with no parameters. + Get or set the Heartbeat subscription parameters. A node only receives Heartbeat messages + matching the Heartbeat subscription parameters. Sets the Heartbeat subscription parameters + if present, or prints the current Heartbeat subscription parameters if called with no + parameters. * ``Src``: Unicast source address to receive Heartbeat messages from. * ``Dst``: Destination address to receive Heartbeat messages on. @@ -792,7 +905,9 @@ The Configuration Client uses general message parameters set by ``mesh target ds ``mesh models cfg hb-pub [ ]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Get or set the Heartbeat publication parameters. Sets the Heartbeat publication parameters if present, or prints the current Heartbeat publication parameters if called with no parameters. + Get or set the Heartbeat publication parameters. Sets the Heartbeat publication parameters + if present, or prints the current Heartbeat publication parameters if called with no + parameters. * ``Dst``: Destination address to publish Heartbeat messages to. * ``Count``: Logarithmic representation of the number of Heartbeat messages to publish periodically: @@ -820,11 +935,22 @@ The Configuration Client uses general message parameters set by ``mesh target ds Health Client ------------- -The Health Client model is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_HEALTH_CLI` configuration option. This is implemented as a separate module (``mesh models health``) inside the ``mesh models`` subcommand list. This module will work on any instance of the Health Client model if the mentioned shell configuration options is enabled, and as long as one or more Health Client model(s) is present in the model composition of the application. This shell module can be used to trigger interaction between Health Clients and Servers on devices in a Mesh network. +The Health Client model is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_HEALTH_CLI` configuration option. This is implemented as a separate +module (``mesh models health``) inside the ``mesh models`` subcommand list. This module will work on +any instance of the Health Client model if the mentioned shell configuration options is enabled, and +as long as one or more Health Client model(s) is present in the model composition of the +application. This shell module can be used to trigger interaction between Health Clients and Servers +on devices in a Mesh network. -By default, the module will choose the first Health Client instance in the model composition when using the Health Client commands. To choose a spesific Health Client instance the user can utilize the commands ``mesh models health instance set`` and ``mesh models health instance get-all``. +By default, the module will choose the first Health Client instance in the model composition when +using the Health Client commands. To choose a spesific Health Client instance the user can utilize +the commands ``mesh models health instance set`` and ``mesh models health instance get-all``. -The Health Client may use the general messages parameters set by ``mesh target dst``, ``mesh target net`` and ``mesh target app`` to target specific nodes. If the shell target destination address is set to zero, the targeted Health Client will attempt to publish messages using its configured publication parameters. +The Health Client may use the general messages parameters set by ``mesh target dst``, +``mesh target net`` and ``mesh target app`` to target specific nodes. If the shell target +destination address is set to zero, the targeted Health Client will attempt to publish messages +using its configured publication parameters. ``mesh models health instance set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -889,7 +1015,10 @@ The Health Client may use the general messages parameters set by ``mesh target d ``mesh models health period-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Set the current Health Server publish period divisor. When a fault is detected, the Health Server will start publishing is fault status with a reduced interval. The reduced interval is determined by the Health Server publish period divisor: Fault publish period = Publish period / 2\ :sup:`divisor`. + Set the current Health Server publish period divisor. When a fault is detected, the Health + Server will start publishing is fault status with a reduced interval. The reduced interval + is determined by the Health Server publish period divisor: Fault publish period = Publish + period / 2\ :sup:`divisor`. * ``Divisor``: The new Health Server publish period divisor. @@ -897,7 +1026,10 @@ The Health Client may use the general messages parameters set by ``mesh target d ``mesh models health period-set-unack `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Set the current Health Server publish period divisor. When a fault is detected, the Health Server will start publishing is fault status with a reduced interval. The reduced interval is determined by the Health Server publish period divisor: Fault publish period = Publish period / 2\ :sup:`divisor`. + Set the current Health Server publish period divisor. When a fault is detected, the Health + Server will start publishing is fault status with a reduced interval. The reduced interval + is determined by the Health Server publish period divisor: Fault publish period = Publish + period / 2\ :sup:`divisor`. * ``Divisor``: The new Health Server publish period divisor. @@ -927,7 +1059,9 @@ The Health Client may use the general messages parameters set by ``mesh target d Binary Large Object (BLOB) Transfer Client model ------------------------------------------------ -The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling the :kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` option, and disabling the :kconfig:option:`CONFIG_BT_MESH_DFU_CLI` option. +The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling the +:kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` option, and disabling the +:kconfig:option:`CONFIG_BT_MESH_DFU_CLI` option. ``mesh models blob cli target `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -948,11 +1082,14 @@ The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling th ``mesh models blob cli tx [ []]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Perform a BLOB transfer to Target nodes. The BLOB Transfer Client will send a dummy BLOB to all Target nodes, then post a message when the transfer is completed. Note that all Target nodes must first be configured to receive the transfer using the ``mesh models blob srv rx`` command. + Perform a BLOB transfer to Target nodes. The BLOB Transfer Client will send a dummy BLOB to + all Target nodes, then post a message when the transfer is completed. Note that all Target + nodes must first be configured to receive the transfer using the ``mesh models blob srv rx`` + command. * ``Id``: 64-bit BLOB transfer ID. * ``Size``: Size of the BLOB in bytes. - * ``BlockSizeLog`` Logarithmic representation of the BLOB's block size. The final block size will be ``1 << block size log`` bytes. + * ``BlockSizeLog``: Logarithmic representation of the BLOB's block size. The final block size will be ``1 << block size log`` bytes. * ``ChunkSize``: Chunk size in bytes. * ``Group``: Optional group address to use when communicating with Target nodes. If omitted or set to 0, the BLOB Transfer Client will address each Target node individually. * ``Mode``: BLOB transfer mode to use. Must be either ``push`` (Push BLOB Transfer Mode) or ``pull`` (Pull BLOB Transfer Mode). If omitted, ``push`` will be used by default. @@ -966,7 +1103,8 @@ The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling th ``mesh models blob cli tx-get [Group]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Determine the progress of a previously running BLOB transfer. Can be used when not performing a BLOB transfer. + Determine the progress of a previously running BLOB transfer. Can be used when not + performing a BLOB transfer. * ``Group``: Optional group address to use when communicating with Target nodes. If omitted or set to 0, the BLOB Transfer Client will address each Target node individually. @@ -985,7 +1123,8 @@ The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling th ``mesh models blob cli instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the BLOB Transfer Client model instance on the specified element when using the other BLOB Transfer Client model commands. + Use the BLOB Transfer Client model instance on the specified element when using the other + BLOB Transfer Client model commands. * ``ElemIdx``: The element on which to find the BLOB Transfer Client model instance to use. @@ -998,7 +1137,9 @@ The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling th BLOB Transfer Server model -------------------------- -The :ref:`bluetooth_mesh_blob_srv` can be added to the mesh shell by enabling the :kconfig:option:`CONFIG_BT_MESH_BLOB_SRV` option. The BLOB Transfer Server model is capable of receiving any BLOB data, but the implementation in the mesh shell will discard the incoming data. +The :ref:`bluetooth_mesh_blob_srv` can be added to the mesh shell by enabling the +:kconfig:option:`CONFIG_BT_MESH_BLOB_SRV` option. The BLOB Transfer Server model is capable of +receiving any BLOB data, but the implementation in the mesh shell will discard the incoming data. ``mesh models blob srv rx []`` @@ -1018,7 +1159,8 @@ The :ref:`bluetooth_mesh_blob_srv` can be added to the mesh shell by enabling th ``mesh models blob srv instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the BLOB Transfer Server model instance on the specified element when using the other BLOB Transfer Server model commands. + Use the BLOB Transfer Server model instance on the specified element when using the other + BLOB Transfer Server model commands. * ``ElemIdx``: The element on which to find the BLOB Transfer Server model instance to use. @@ -1031,13 +1173,19 @@ The :ref:`bluetooth_mesh_blob_srv` can be added to the mesh shell by enabling th Firmware Update Client model ---------------------------- -The Firmware Update Client model can be added to the mesh shell by enabling configuration options :kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` and :kconfig:option:`CONFIG_BT_MESH_DFU_CLI`. The Firmware Update Client demonstrates the firmware update Distributor role by transferring a dummy firmware update to a set of Target nodes. +The Firmware Update Client model can be added to the mesh shell by enabling configuration options +:kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` and :kconfig:option:`CONFIG_BT_MESH_DFU_CLI`. The Firmware +Update Client demonstrates the firmware update Distributor role by transferring a dummy firmware +update to a set of Target nodes. ``mesh models dfu slot add []`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add a virtual DFU image slot that can be transferred as a DFU image. The image slot will be assigned an image slot index, which is printed as a response, and can be used to reference the slot in other commands. To update the image slot, remove it using the ``mesh models dfu slot del`` shell command and then add it again. + Add a virtual DFU image slot that can be transferred as a DFU image. The image slot will be + assigned an image slot index, which is printed as a response, and can be used to reference + the slot in other commands. To update the image slot, remove it using the + ``mesh models dfu slot del`` shell command and then add it again. * ``Size``: DFU image slot size in bytes. * ``FwID``: Firmware ID, formatted as a hexstring. @@ -1086,7 +1234,9 @@ The Firmware Update Client model can be added to the mesh shell by enabling conf ``mesh models dfu cli target-check `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Check whether the device at the configured destination address will accept a DFU transfer from the given DFU image slot to the Target node's DFU image at the given index, and what the effect would be. + Check whether the device at the configured destination address will accept a DFU transfer + from the given DFU image slot to the Target node's DFU image at the given index, and what + the effect would be. * ``SlotIdx``: Index of the local DFU image slot to check. * ``TargetImgIdx``: Index of the Target node's DFU image to check. @@ -1104,9 +1254,10 @@ The Firmware Update Client model can be added to the mesh shell by enabling conf ``mesh models dfu cli cancel []`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Cancel the DFU procedure at any state on a specific Target node or on all Target nodes. - When a Target node address is provided, the Firmware Update Client model will try to cancel the DFU procedure on the provided Target node. - Otherwise, the Firmware Update Client model will try to cancel the ongoing DFU procedure on all Target nodes. + Cancel the DFU procedure at any state on a specific Target node or on all Target nodes. When + a Target node address is provided, the Firmware Update Client model will try to cancel the + DFU procedure on the provided Target node. Otherwise, the Firmware Update Client model will + try to cancel the ongoing DFU procedure on all Target nodes. * ``Addr``: Optional unicast address of a Target node on which to cancel the DFU procedure. @@ -1114,13 +1265,15 @@ The Firmware Update Client model can be added to the mesh shell by enabling conf ``mesh models dfu cli apply`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Apply the most recent DFU transfer on all Target nodes. Can only be called after a DFU transfer is completed. + Apply the most recent DFU transfer on all Target nodes. Can only be called after a DFU + transfer is completed. ``mesh models dfu cli confirm`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Confirm that the most recent DFU transfer was successfully applied on all Target nodes. Can only be called after a DFU transfer is completed and applied. + Confirm that the most recent DFU transfer was successfully applied on all Target nodes. Can + only be called after a DFU transfer is completed and applied. ``mesh models dfu cli suspend`` @@ -1144,7 +1297,8 @@ The Firmware Update Client model can be added to the mesh shell by enabling conf ``mesh models dfu cli instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the Firmware Update Client model instance on the specified element when using the other Firmware Update Client model commands. + Use the Firmware Update Client model instance on the specified element when using the other + Firmware Update Client model commands. * ``ElemIdx``: The element on which to find the Firmware Update Client model instance to use. @@ -1157,15 +1311,22 @@ The Firmware Update Client model can be added to the mesh shell by enabling conf Firmware Update Server model ---------------------------- -The Firmware Update Server model can be added to the mesh shell by enabling configuration options :kconfig:option:`CONFIG_BT_MESH_BLOB_SRV` and :kconfig:option:`CONFIG_BT_MESH_DFU_SRV`. The Firmware Update Server demonstrates the firmware update Target role by accepting any firmware update. The mesh shell Firmware Update Server will discard the incoming firmware data, but otherwise behave as a proper firmware update Target node. +The Firmware Update Server model can be added to the mesh shell by enabling configuration options +:kconfig:option:`CONFIG_BT_MESH_BLOB_SRV` and :kconfig:option:`CONFIG_BT_MESH_DFU_SRV`. The Firmware +Update Server demonstrates the firmware update Target role by accepting any firmware update. The +mesh shell Firmware Update Server will discard the incoming firmware data, but otherwise behave as a +proper firmware update Target node. ``mesh models dfu srv applied`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Mark the most recent DFU transfer as applied. Can only be called after a DFU transfer is completed, and the Distributor has requested that the transfer is applied. + Mark the most recent DFU transfer as applied. Can only be called after a DFU transfer is + completed, and the Distributor has requested that the transfer is applied. - As the mesh shell Firmware Update Server doesn't actually apply the incoming firmware image, this command can be used to emulate an applied status, to notify the Distributor that the transfer was successful. + As the mesh shell Firmware Update Server doesn't actually apply the incoming firmware image, + this command can be used to emulate an applied status, to notify the Distributor that the + transfer was successful. ``mesh models dfu srv progress`` @@ -1181,7 +1342,8 @@ The Firmware Update Server model can be added to the mesh shell by enabling conf ``mesh models dfu srv instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the Firmware Update Server model instance on the specified element when using the other Firmware Update Server model commands. + Use the Firmware Update Server model instance on the specified element when using the other + Firmware Update Server model commands. * ``ElemIdx``: The element on which to find the Firmware Update Server model instance to use. @@ -1196,17 +1358,19 @@ The Firmware Update Server model can be added to the mesh shell by enabling conf Firmware Distribution Server model ---------------------------------- -The Firmware Distribution Server model commands can be added to the mesh shell by enabling the :kconfig:option:`CONFIG_BT_MESH_DFD_SRV` configuration option. -The shell commands for this model mirror the messages sent to the server by a Firmware Distribution Client model. -To use these commands, a Firmware Distribution Server must be instantiated by the application. +The Firmware Distribution Server model commands can be added to the mesh shell by enabling the +:kconfig:option:`CONFIG_BT_MESH_DFD_SRV` configuration option. The shell commands for this model +mirror the messages sent to the server by a Firmware Distribution Client model. To use these +commands, a Firmware Distribution Server must be instantiated by the application. ``mesh models dfd receivers-add ,[;,]...`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add receivers to the Firmware Distribution Server. - Supply receivers as a list of comma-separated addr,fw_idx pairs, separated by semicolons, for example, ``0x0001,0;0x0002,0;0x0004,1``. - Do not use spaces in the receiver list. - Repeated calls to this command will continue populating the receivers list until ``mesh models dfd receivers-delete-all`` is called. + Add receivers to the Firmware Distribution Server. Supply receivers as a list of + comma-separated addr,fw_idx pairs, separated by semicolons, for example, + ``0x0001,0;0x0002,0;0x0004,1``. Do not use spaces in the receiver list. Repeated calls to + this command will continue populating the receivers list until + ``mesh models dfd receivers-delete-all`` is called. * ``Addr``: Address of the receiving node(s). * ``FwIdx``: Index of the firmware slot to send to ``Addr``. @@ -1291,7 +1455,8 @@ To use these commands, a Firmware Distribution Server must be instantiated by th ``mesh models dfd instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the Firmware Distribution Server model instance on the specified element when using the other Firmware Distribution Server model commands. + Use the Firmware Distribution Server model instance on the specified element when using the + other Firmware Distribution Server model commands. * ``ElemIdx``: The element on which to find the Firmware Distribution Server model instance to use. @@ -1306,7 +1471,9 @@ To use these commands, a Firmware Distribution Server must be instantiated by th DFU metadata ------------ -The DFU metadata commands allow generating metadata that can be used by a Target node to check the firmware before accepting it. The commands are enabled through the :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` configuration option. +The DFU metadata commands allow generating metadata that can be used by a Target node to check the +firmware before accepting it. The commands are enabled through the +:kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` configuration option. ``mesh models dfu metadata comp-clear`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1370,7 +1537,10 @@ The DFU metadata commands allow generating metadata that can be used by a Target Segmentation and Reassembly (SAR) Configuration Client ------------------------------------------------------ -The SAR Configuration client is an optional mesh model that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. The SAR Configuration Client model is used to support the functionality of configuring the behavior of the lower transport layer of a node that supports the SAR Configuration Server model. +The SAR Configuration client is an optional mesh model that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. The SAR Configuration Client +model is used to support the functionality of configuring the behavior of the lower transport layer +of a node that supports the SAR Configuration Server model. ``mesh models sar tx-get`` @@ -1411,7 +1581,8 @@ The SAR Configuration client is an optional mesh model that can be enabled throu Private Beacon Client --------------------- -The Private Beacon Client model is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_PRIV_BEACON_CLI` configuration option. +The Private Beacon Client model is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_PRIV_BEACON_CLI` configuration option. ``mesh models prb priv-beacon-get`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1474,32 +1645,43 @@ The Private Beacon Client model is an optional mesh subsystem that can be enable Opcodes Aggregator Client ------------------------- -The Opcodes Aggregator client is an optional Bluetooth mesh model that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` configuration option. The Opcodes Aggregator Client model is used to support the functionality of dispatching a sequence of access layer messages to nodes supporting the Opcodes Aggregator Server model. +The Opcodes Aggregator client is an optional Bluetooth mesh model that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` configuration option. The Opcodes Aggregator Client +model is used to support the functionality of dispatching a sequence of access layer messages to +nodes supporting the Opcodes Aggregator Server model. ``mesh models opagg seq-start `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Start the Opcodes Aggregator Sequence message. This command initiates the context for aggregating messages and sets the destination address for next shell commands to ``elem_addr``. + Start the Opcodes Aggregator Sequence message. This command initiates the context for + aggregating messages and sets the destination address for next shell commands to + ``elem_addr``. * ``ElemAddr``: Element address that will process the aggregated opcodes. ``mesh models opagg seq-send`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Send the Opcodes Aggregator Sequence message. This command completes the procedure, sends the aggregated sequence message to the target node and clears the context. + Send the Opcodes Aggregator Sequence message. This command completes the procedure, sends + the aggregated sequence message to the target node and clears the context. ``mesh models opagg seq-abort`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Abort the Opcodes Aggregator Sequence message. This command clears the Opcodes Aggregator Client context. + Abort the Opcodes Aggregator Sequence message. This command clears the Opcodes Aggregator + Client context. Remote Provisioning Client -------------------------- -The Remote Provisioning Client is an optional Bluetooth mesh model enabled through the :kconfig:option:`CONFIG_BT_MESH_RPR_CLI` configuration option. The Remote Provisioning Client model provides support for remote provisioning of devices into a mesh network by using the Remote Provisioning Server model. +The Remote Provisioning Client is an optional Bluetooth mesh model enabled through the +:kconfig:option:`CONFIG_BT_MESH_RPR_CLI` configuration option. The Remote Provisioning Client model +provides support for remote provisioning of devices into a mesh network by using the Remote +Provisioning Server model. -This shell module can be used to trigger interaction between Remote Provisioning Clients and Remote Provisioning Servers on devices in a mesh network. +This shell module can be used to trigger interaction between Remote Provisioning Clients and Remote +Provisioning Servers on devices in a mesh network. ``mesh models rpr scan []`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1565,12 +1747,13 @@ This shell module can be used to trigger interaction between Remote Provisioning Reprovision a mesh node using the PB-Remote provisioning bearer. * ``Addr``: Address to assign to remote device. If ``addr`` is 0, the lowest available address will be chosen. - * ``CompChanged``: The Target node has indicated that its Composition Data has changed. Defaults to false. + * ``CompChanged``: The Target node has indicated that its Composition Data has changed. Defaults to false. ``mesh models rpr instance-set `` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Use the Remote Provisioning Client model instance on the specified element when using the other Remote Provisioning Client model commands. + Use the Remote Provisioning Client model instance on the specified element when using the + other Remote Provisioning Client model commands. * ``ElemIdx``: The element on which to find the Remote Provisioning Client model instance to use. @@ -1583,14 +1766,19 @@ This shell module can be used to trigger interaction between Remote Provisioning Configuration database ====================== -The Configuration database is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_CDB` configuration option. The Configuration database is only available on provisioner devices, and allows them to store all information about the mesh network. To avoid conflicts, there should only be one mesh node in the network with the Configuration database enabled. This node is the Configurator, and is responsible for adding new nodes to the network and configuring them. +The Configuration database is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_CDB` configuration option. The Configuration database is only +available on provisioner devices, and allows them to store all information about the mesh network. +To avoid conflicts, there should only be one mesh node in the network with the Configuration +database enabled. This node is the Configurator, and is responsible for adding new nodes to the +network and configuring them. ``mesh cdb create [NetKey(1-16 hex)]`` -------------------------------------- Create a Configuration database. - * ``NetKey``: Optional network key value of the primary network key (NetKeyIndex=0). Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. Defaults to the default key value if omitted. + * ``NetKey``: Optional network key value of the primary network key (NetKeyIndex=0). Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. Defaults to the default key value if omitted. ``mesh cdb clear`` @@ -1608,7 +1796,9 @@ The Configuration database is an optional mesh subsystem that can be enabled thr ``mesh cdb node-add [DevKey(1-16 hex)]`` -------------------------------------------------------------------------------------- - Manually add a mesh node to the configuration database. Note that devices provisioned with ``mesh provision`` and ``mesh provision-adv`` will be added automatically if the Configuration Database is enabled and created. + Manually add a mesh node to the configuration database. Note that devices provisioned with + ``mesh provision`` and ``mesh provision-adv`` will be added automatically if the + Configuration Database is enabled and created. * ``UUID``: 128-bit hexadecimal UUID of the node. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. * ``Addr``: Unicast address of the node, or 0 to automatically choose the lowest available address. @@ -1620,7 +1810,9 @@ The Configuration database is an optional mesh subsystem that can be enabled thr ``mesh cdb node-del `` ---------------------------- - Delete a mesh node from the Configuration database. If possible, the node should be reset with ``mesh reset`` before it is deleted from the Configuration database, to avoid unexpected behavior and uncontrolled access to the network. + Delete a mesh node from the Configuration database. If possible, the node should be reset + with ``mesh reset`` before it is deleted from the Configuration database, to avoid + unexpected behavior and uncontrolled access to the network. * ``Addr`` Address of the node to delete. @@ -1628,7 +1820,9 @@ The Configuration database is an optional mesh subsystem that can be enabled thr ``mesh cdb subnet-add []`` -------------------------------------------------------- - Add a network key to the Configuration database. The network key can later be passed to mesh nodes in the network. Note that adding a key to the Configuration database does not automatically add it to the local node's list of known network keys. + Add a network key to the Configuration database. The network key can later be passed to mesh + nodes in the network. Note that adding a key to the Configuration database does not + automatically add it to the local node's list of known network keys. * ``NetKeyIdx``: Key index of the network key to add. * ``NetKey``: Optional 128-bit network key value. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. If omitted, a random value will be generated. @@ -1645,7 +1839,9 @@ The Configuration database is an optional mesh subsystem that can be enabled thr ``mesh cdb app-key-add []`` --------------------------------------------------------------------- - Add an application key to the Configuration database. The application key can later be passed to mesh nodes in the network. Note that adding a key to the Configuration database does not automatically add it to the local node's list of known application keys. + Add an application key to the Configuration database. The application key can later be + passed to mesh nodes in the network. Note that adding a key to the Configuration database + does not automatically add it to the local node's list of known application keys. * ``NetKeyIdx``: Network key index the application key is bound to. * ``AppKeyIdx``: Key index of the application key to add. @@ -1663,25 +1859,29 @@ The Configuration database is an optional mesh subsystem that can be enabled thr On-Demand Private GATT Proxy Client ----------------------------------- -The On-Demand Private GATT Proxy Client model is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` configuration option. +The On-Demand Private GATT Proxy Client model is an optional mesh subsystem that can be enabled +through the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` configuration option. ``mesh models od_priv_proxy od-priv-gatt-proxy [Dur(s)]`` --------------------------------------------------------- - Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this state from it. + Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this + state from it. - * ``Dur``: If given, set the state of On-Demand Private GATT Proxy to this value in seconds. Fetch this value otherwise. + * ``Dur``: If given, set the state of On-Demand Private GATT Proxy to this value in seconds. Fetch this value otherwise. Solicitation PDU RPL Client --------------------------- -The Solicitation PDU RPL Client model is an optional mesh subsystem that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` configuration option. +The Solicitation PDU RPL Client model is an optional mesh subsystem that can be enabled through the +:kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` configuration option. ``mesh models sol_pdu_rpl sol-pdu-rpl-clear [RngLen]`` ------------------------------------------------------------------------ - Clear active target's solicitation replay protection list (SRPL) in given range of solicitation source (SSRC) addresses. + Clear active target's solicitation replay protection list (SRPL) in given range of + solicitation source (SSRC) addresses. * ``RngStart``: Start address of the SSRC range. * ``Ackd``: This argument decides on whether an acknowledged or unacknowledged message will be sent. @@ -1694,7 +1894,8 @@ Frame statistic ``mesh stat get`` ----------------- - Get the frame statistic. The command prints numbers of received frames, as well as numbers of planned and succeeded transmission attempts. + Get the frame statistic. The command prints numbers of received frames, as well as numbers + of planned and succeeded transmission attempts. ``mesh stat clear`` diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst index ca437edca79..a5a9b7ba47f 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst @@ -4,14 +4,16 @@ Solicitation PDU RPL Configuration Client ######################################### The Solicitation PDU RPL Configuration Client model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` option. +mesh specification. The model is optional, and is enabled through the +:kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` option. The Solicitation PDU RPL Configuration Client model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and supports the functionality of removing addresses from the solicitation -replay protection list (SRPL) of a node that supports the :ref:`bluetooth_mesh_srpl_srv` model. +Specification version 1.1, and supports the functionality of removing addresses from the +solicitation replay protection list (SRPL) of a node that supports the +:ref:`bluetooth_mesh_srpl_srv` model. -The Solicitation PDU RPL Configuration Client model communicates with a Solicitation PDU RPL Configuration Server model -using the application keys configured by the Configuration Client. +The Solicitation PDU RPL Configuration Client model communicates with a Solicitation PDU RPL +Configuration Server model using the application keys configured by the Configuration Client. If present, the Solicitation PDU RPL Configuration Client model must only be instantiated on the primary element. @@ -19,9 +21,11 @@ primary element. Configurations ************** -The Solicitation PDU RPL Configuration Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT`. -The :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT` controls how long the Solicitation PDU RPL Configuration Client waits -for a response message to arrive in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_sol_pdu_rpl_cli_timeout_set`. +The Solicitation PDU RPL Configuration Client model behavior can be configured with the transmission +timeout option :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT`. The +:kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT` controls how long the Solicitation PDU RPL +Configuration Client waits for a response message to arrive in milliseconds. This value can be +changed at runtime using :c:func:`bt_mesh_sol_pdu_rpl_cli_timeout_set`. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst index 9ca68517f99..ad8a26e4c44 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst @@ -7,12 +7,14 @@ The Solicitation PDU RPL Configuration Server model is a foundation model define mesh specification. The model is enabled if the node has the :ref:`bluetooth_mesh_od_srv` enabled. The Solicitation PDU RPL Configuration Server model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and manages the Solicitation Replay Protection List (SRPL) saved on the device. -The SRPL is used to reject Solicitation PDUs that are already processed by a node. When a valid Solicitation PDU message is -successfully processed by a node, the SSRC field and SSEQ field of the message are stored in the node's SRPL. +Specification version 1.1, and manages the Solicitation Replay Protection List (SRPL) saved on the +device. The SRPL is used to reject Solicitation PDUs that are already processed by a node. When a +valid Solicitation PDU message is successfully processed by a node, the SSRC field and SSEQ field +of the message are stored in the node's SRPL. -The Solicitation PDU RPL Configuration Server does not have an API of its own, and relies on a :ref:`bluetooth_mesh_srpl_cli` to control it. -The model only accepts messages encrypted with an application key as configured by the Configuration Client. +The Solicitation PDU RPL Configuration Server does not have an API of its own, and relies on a +:ref:`bluetooth_mesh_srpl_cli` to control it. The model only accepts messages encrypted with an +application key as configured by the Configuration Client. If present, the Solicitation PDU RPL Configuration Server model must only be instantiated on the primary element. @@ -20,7 +22,9 @@ primary element. Configurations ************** -For the Solicitation PDU RPL Configuration Server model, the :kconfig:option:`CONFIG_BT_MESH_PROXY_SRPL_SIZE` option can be configured to set the size of the SRPL. +For the Solicitation PDU RPL Configuration Server model, the +:kconfig:option:`CONFIG_BT_MESH_PROXY_SRPL_SIZE` option can be configured to set the size of the +SRPL. API reference ************* From dccc5757679ae9b2969ae6eaaef3c3fd29e1b708 Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Wed, 27 Sep 2023 15:51:31 +0200 Subject: [PATCH 1226/4498] include: add new time macros to sys_clock.h New defines added: SEC_PER_MIN, MIN_PER_HOUR, HOUR_PER_DAY. Signed-off-by: Jakub Rzeszutko --- include/zephyr/sys_clock.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/zephyr/sys_clock.h b/include/zephyr/sys_clock.h index 9fd1f564a36..e29453a81c7 100644 --- a/include/zephyr/sys_clock.h +++ b/include/zephyr/sys_clock.h @@ -132,6 +132,15 @@ extern void z_enable_sys_clock(void); /* number of milliseconds per second */ #define MSEC_PER_SEC 1000U +/* number of seconds per minute */ +#define SEC_PER_MIN 60U + +/* number of minutes per hour */ +#define MIN_PER_HOUR 60U + +/* number of hours per day */ +#define HOUR_PER_DAY 24U + /* number of microseconds per second */ #define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC)) From c631bc775736fc81609a365d65c978827f0e28b0 Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Wed, 13 Sep 2023 10:16:55 +0200 Subject: [PATCH 1227/4498] shell: modules: kernel: add human readable uptime Added options: -p and --pretty to the kernel updtime command. Fixes: #62543 Signed-off-by: Jakub Rzeszutko --- subsys/shell/modules/kernel_service.c | 41 ++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/subsys/shell/modules/kernel_service.c b/subsys/shell/modules/kernel_service.c index 065cdcb4b96..58a3a454dc5 100644 --- a/subsys/shell/modules/kernel_service.c +++ b/subsys/shell/modules/kernel_service.c @@ -44,13 +44,45 @@ static int cmd_kernel_version(const struct shell *sh, return 0; } -static int cmd_kernel_uptime(const struct shell *sh, - size_t argc, char **argv) +#define MINUTES_FACTOR (MSEC_PER_SEC * SEC_PER_MIN) +#define HOURS_FACTOR (MINUTES_FACTOR * MIN_PER_HOUR) +#define DAYS_FACTOR (HOURS_FACTOR * HOUR_PER_DAY) + +static int cmd_kernel_uptime(const struct shell *sh, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); - shell_print(sh, "Uptime: %u ms", k_uptime_get_32()); + int64_t milliseconds = k_uptime_get(); + int64_t days; + int64_t hours; + int64_t minutes; + int64_t seconds; + + if (argc == 1) { + shell_print(sh, "Uptime: %llu ms", milliseconds); + return 0; + } + + /* No need to enable the getopt and getopt_long for just one option. */ + if (strcmp("-p", argv[1]) && strcmp("--pretty", argv[1]) != 0) { + shell_error(sh, "Usupported option: %s", argv[1]); + return -EIO; + } + + days = milliseconds / DAYS_FACTOR; + milliseconds %= DAYS_FACTOR; + hours = milliseconds / HOURS_FACTOR; + milliseconds %= HOURS_FACTOR; + minutes = milliseconds / MINUTES_FACTOR; + milliseconds %= MINUTES_FACTOR; + seconds = milliseconds / MSEC_PER_SEC; + milliseconds = milliseconds % MSEC_PER_SEC; + + shell_print(sh, + "uptime: %llu days, %llu hours, %llu minutes, %llu seconds, %llu milliseconds", + days, hours, minutes, seconds, milliseconds); + return 0; } @@ -371,7 +403,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel, #if defined(CONFIG_SYS_HEAP_RUNTIME_STATS) && (CONFIG_HEAP_MEM_POOL_SIZE > 0) SHELL_CMD(heap, NULL, "System heap usage statistics.", cmd_kernel_heap), #endif - SHELL_CMD(uptime, NULL, "Kernel uptime.", cmd_kernel_uptime), + SHELL_CMD_ARG(uptime, NULL, "Kernel uptime. Can be called with the -p or --pretty options", + cmd_kernel_uptime, 1, 1), SHELL_CMD(version, NULL, "Kernel version.", cmd_kernel_version), SHELL_CMD_ARG(sleep, NULL, "ms", cmd_kernel_sleep, 2, 0), #if defined(CONFIG_LOG_RUNTIME_FILTERING) From 31a25da8c2fdabcc6b7238993b82362cd2e55095 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 21 Sep 2023 17:22:06 +0300 Subject: [PATCH 1228/4498] net: icmp: Introduce new API to send ICMP messages Allow user to send ICMP Echo Request message a.k.a pings. The same ICMP API and framework is used for network stack internal needs in later commits. One benefit for this new API is that it allows sending Echo Requests to offlined network devices. Signed-off-by: Jukka Rissanen --- include/zephyr/net/icmp.h | 174 ++++++++++++++ subsys/net/ip/CMakeLists.txt | 1 + subsys/net/ip/icmp.c | 438 +++++++++++++++++++++++++++++++++++ subsys/net/ip/icmpv4.h | 2 - subsys/net/ip/icmpv6.h | 2 - subsys/net/ip/net_private.h | 8 + 6 files changed, 621 insertions(+), 4 deletions(-) create mode 100644 include/zephyr/net/icmp.h create mode 100644 subsys/net/ip/icmp.c diff --git a/include/zephyr/net/icmp.h b/include/zephyr/net/icmp.h new file mode 100644 index 00000000000..47ad489ecb5 --- /dev/null +++ b/include/zephyr/net/icmp.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file icmp.h + * + * @defgroup icmp Send and receive IPv4 or IPv6 ICMP Echo Request messages. + * @ingroup networking + * @{ + * @brief ICMP sending and receiving. + */ + +#ifndef ZEPHYR_INCLUDE_NET_ICMP_H_ +#define ZEPHYR_INCLUDE_NET_ICMP_H_ + +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NET_ICMPV4_ECHO_REQUEST 8 +#define NET_ICMPV4_ECHO_REPLY 0 +#define NET_ICMPV6_ECHO_REQUEST 128 +#define NET_ICMPV6_ECHO_REPLY 129 + +struct net_icmp_ctx; +struct net_icmp_ip_hdr; + +/** + * @typedef net_icmp_handler_t + * @brief Handler function that is called when ICMP response is received. + * + * @param ctx ICMP context to use. + * @param pkt Received ICMP response network packet. + * @param ip_hdr IP header of the packet. + * @param icmp_hdr ICMP header of the packet. + * @param user_data A valid pointer to user data or NULL + */ +typedef int (*net_icmp_handler_t)(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *ip_hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data); + +/** + * @brief ICMP context structure. + */ +struct net_icmp_ctx { + /** List node */ + sys_snode_t node; + + /** ICMP response handler */ + net_icmp_handler_t handler; + + /** Network interface where the ICMP request was sent */ + struct net_if *iface; + + /** Opaque user supplied data */ + void *user_data; + + /** ICMP type of the response we are waiting */ + uint8_t type; + + /** ICMP code of the response type we are waiting */ + uint8_t code; +}; + +/** + * @brief Struct presents either IPv4 or IPv6 header in ICMP response message. + */ +struct net_icmp_ip_hdr { + union { + /** IPv4 header in response message. */ + struct net_ipv4_hdr *ipv4; + + /** IPv6 header in response message. */ + struct net_ipv6_hdr *ipv6; + }; + + /** Is the header IPv4 or IPv6 one. Value of either AF_INET or AF_INET6 */ + sa_family_t family; +}; + +/** + * @brief Struct presents parameters that are needed when sending + * Echo-Request (ping) messages. + */ +struct net_icmp_ping_params { + /** An identifier to aid in matching Echo Replies to this Echo Request. + * May be zero. + */ + uint16_t identifier; + + /** A sequence number to aid in matching Echo Replies to this + * Echo Request. May be zero. + */ + uint16_t sequence; + + /** Can be either IPv4 Type-of-service field value, or IPv6 Traffic + * Class field value. Represents combined DSCP and ECN values. + */ + uint8_t tc_tos; + + /** Network packet priority. */ + int priority; + + /* Arbitrary payload data that will be included in the Echo Reply + * verbatim. May be NULL. + */ + const void *data; + + /** Size of the Payload Data in bytes. May be zero. In case data + * pointer is NULL, the function will generate the payload up to + * the requested size. + */ + size_t data_size; +}; + +/** + * @brief Initialize the ICMP context structure. Must be called before + * ICMP messages can be sent. This will register handler to the + * system. + * + * @param ctx ICMP context used in this request. + * @param type Type of ICMP message we are handling. + * @param code Code of ICMP message we are handling. + * @param handler Callback function that is called when a response is received. + */ +int net_icmp_init_ctx(struct net_icmp_ctx *ctx, uint8_t type, uint8_t code, + net_icmp_handler_t handler); + +/** + * @brief Cleanup the ICMP context structure. This will unregister the ICMP handler + * from the system. + * + * @param ctx ICMP context used in this request. + */ +int net_icmp_cleanup_ctx(struct net_icmp_ctx *ctx); + +/** + * @brief Send ICMP echo request message. + * + * @param ctx ICMP context used in this request. + * @param iface Network interface, can be set to NULL in which case the + * interface is selected according to destination address. + * @param dst IP address of the target host. + * @param params Echo-Request specific parameters. May be NULL in which case + * suitable default parameters are used. + * @param user_data User supplied opaque data passed to the handler. May be NULL. + * + * @return Return 0 if the sending succeed, <0 otherwise. + */ +int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_ICMP_H */ + +/**@} */ diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index 7dc54935c5c..84cfc523b8a 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -28,6 +28,7 @@ if(CONFIG_NET_NATIVE) zephyr_library_sources(net_context.c) zephyr_library_sources(net_pkt.c) zephyr_library_sources(net_tc.c) +zephyr_library_sources(icmp.c) zephyr_library_sources_ifdef(CONFIG_NET_IP connection.c) zephyr_library_sources_ifdef(CONFIG_NET_6LO 6lo.c) zephyr_library_sources_ifdef(CONFIG_NET_DHCPV4 dhcpv4.c) diff --git a/subsys/net/ip/icmp.c b/subsys/net/ip/icmp.c new file mode 100644 index 00000000000..81e51cdc1b6 --- /dev/null +++ b/subsys/net/ip/icmp.c @@ -0,0 +1,438 @@ +/** @file + * @brief ICMP related functions + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Use highest log level if both IPv4 and IPv6 are defined */ +#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV6) + +#if CONFIG_NET_ICMPV4_LOG_LEVEL > CONFIG_NET_ICMPV6_LOG_LEVEL +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV4_LOG_LEVEL +#else +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV6_LOG_LEVEL +#endif + +#elif defined(CONFIG_NET_IPV4) +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV4_LOG_LEVEL +#elif defined(CONFIG_NET_IPV6) +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV6_LOG_LEVEL +#else +#define ICMP_LOG_LEVEL LOG_LEVEL_INF +#endif + +#include +LOG_MODULE_REGISTER(net_icmp, ICMP_LOG_LEVEL); + +#include +#include +#include +#include +#include + +#include "net_private.h" +#include "icmpv6.h" +#include "icmpv4.h" +#include "ipv4.h" +#include "ipv6.h" +#include "net_stats.h" + +static K_MUTEX_DEFINE(lock); +static sys_slist_t handlers = SYS_SLIST_STATIC_INIT(&handlers); + +#define PKT_WAIT_TIME K_SECONDS(1) + +int net_icmp_init_ctx(struct net_icmp_ctx *ctx, uint8_t type, uint8_t code, + net_icmp_handler_t handler) +{ + if (ctx == NULL || handler == NULL) { + return -EINVAL; + } + + memset(ctx, 0, sizeof(struct net_icmp_ctx)); + + ctx->handler = handler; + ctx->type = type; + ctx->code = code; + + k_mutex_lock(&lock, K_FOREVER); + + sys_slist_prepend(&handlers, &ctx->node); + + k_mutex_unlock(&lock); + + return 0; +} + +int net_icmp_cleanup_ctx(struct net_icmp_ctx *ctx) +{ + if (ctx == NULL) { + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + sys_slist_find_and_remove(&handlers, &ctx->node); + + k_mutex_unlock(&lock); + + memset(ctx, 0, sizeof(struct net_icmp_ctx)); + + return 0; +} + +#if defined(CONFIG_NET_IPV4) +static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct in_addr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access, + struct net_icmpv4_echo_req); + int ret = -ENOBUFS; + struct net_icmpv4_echo_req *echo_req; + const struct in_addr *src; + struct net_pkt *pkt; + + if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) { + /* XXX: fixme so that we can send offloaded messages too */ + return -ENOTSUP; + } + + if (!iface->config.ip.ipv4) { + return -ENETUNREACH; + } + + src = net_if_ipv4_select_src_addr(iface, dst); + + pkt = net_pkt_alloc_with_buffer(iface, + sizeof(struct net_icmpv4_echo_req) + + params->data_size, + AF_INET, IPPROTO_ICMP, + PKT_WAIT_TIME); + if (!pkt) { + return -ENOMEM; + } + + if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && + params->priority >= NET_MAX_PRIORITIES) { + NET_ERR("Priority %d is too large, maximum allowed is %d", + params->priority, NET_MAX_PRIORITIES - 1); + return -EINVAL; + } + + if (params->priority < 0) { + net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(params->tc_tos)); + net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(params->tc_tos)); + } else { + net_pkt_set_priority(pkt, params->priority); + } + + if (net_ipv4_create(pkt, src, dst) || + net_icmpv4_create(pkt, NET_ICMPV4_ECHO_REQUEST, 0)) { + goto drop; + } + + echo_req = (struct net_icmpv4_echo_req *)net_pkt_get_data( + pkt, &icmpv4_access); + if (!echo_req) { + goto drop; + } + + echo_req->identifier = htons(params->identifier); + echo_req->sequence = htons(params->sequence); + + net_pkt_set_data(pkt, &icmpv4_access); + + if (params->data != NULL && params->data_size > 0) { + net_pkt_write(pkt, params->data, params->data_size); + } else if (params->data == NULL && params->data_size > 0) { + /* Generate payload. */ + if (params->data_size >= sizeof(uint32_t)) { + uint32_t time_stamp = htonl(k_cycle_get_32()); + + net_pkt_write(pkt, &time_stamp, sizeof(time_stamp)); + params->data_size -= sizeof(time_stamp); + } + + for (size_t i = 0; i < params->data_size; i++) { + net_pkt_write_u8(pkt, (uint8_t)i); + } + } else { + /* No payload. */ + } + + net_pkt_cursor_init(pkt); + + net_ipv4_finalize(pkt, IPPROTO_ICMP); + + NET_DBG("Sending ICMPv4 Echo Request type %d from %s to %s", + NET_ICMPV4_ECHO_REQUEST, + net_sprint_ipv4_addr(src), + net_sprint_ipv4_addr(dst)); + + ctx->user_data = user_data; + ctx->iface = iface; + + if (net_send_data(pkt) >= 0) { + net_stats_update_icmp_sent(iface); + return 0; + } + + net_stats_update_icmp_drop(iface); + + ret = -EIO; + +drop: + net_pkt_unref(pkt); + + return ret; + +} +#else +static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct in_addr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(iface); + ARG_UNUSED(dst); + ARG_UNUSED(params); + + return -ENOTSUP; +} +#endif + +#if defined(CONFIG_NET_IPV6) +static int send_icmpv6_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct in6_addr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv6_access, + struct net_icmpv6_echo_req); + int ret = -ENOBUFS; + struct net_icmpv6_echo_req *echo_req; + const struct in6_addr *src; + struct net_pkt *pkt; + + if (!iface->config.ip.ipv6) { + return -ENETUNREACH; + } + + src = net_if_ipv6_select_src_addr(iface, dst); + + pkt = net_pkt_alloc_with_buffer(iface, + sizeof(struct net_icmpv6_echo_req) + + params->data_size, + AF_INET6, IPPROTO_ICMPV6, + PKT_WAIT_TIME); + if (!pkt) { + return -ENOMEM; + } + + if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && + params->priority >= NET_MAX_PRIORITIES) { + NET_ERR("Priority %d is too large, maximum allowed is %d", + params->priority, NET_MAX_PRIORITIES - 1); + return -EINVAL; + } + + if (params->priority < 0) { + net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(params->tc_tos)); + net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(params->tc_tos)); + } else { + net_pkt_set_priority(pkt, params->priority); + } + + if (net_ipv6_create(pkt, src, dst) || + net_icmpv6_create(pkt, NET_ICMPV6_ECHO_REQUEST, 0)) { + goto drop; + } + + echo_req = (struct net_icmpv6_echo_req *)net_pkt_get_data( + pkt, &icmpv6_access); + if (!echo_req) { + goto drop; + } + + echo_req->identifier = htons(params->identifier); + echo_req->sequence = htons(params->sequence); + + net_pkt_set_data(pkt, &icmpv6_access); + + if (params->data != NULL && params->data_size > 0) { + net_pkt_write(pkt, params->data, params->data_size); + } else if (params->data == NULL && params->data_size > 0) { + /* Generate payload. */ + if (params->data_size >= sizeof(uint32_t)) { + uint32_t time_stamp = htonl(k_cycle_get_32()); + + net_pkt_write(pkt, &time_stamp, sizeof(time_stamp)); + params->data_size -= sizeof(time_stamp); + } + + for (size_t i = 0; i < params->data_size; i++) { + net_pkt_write_u8(pkt, (uint8_t)i); + } + } else { + /* No payload. */ + } + + net_pkt_cursor_init(pkt); + net_ipv6_finalize(pkt, IPPROTO_ICMPV6); + + NET_DBG("Sending ICMPv6 Echo Request type %d from %s to %s", + NET_ICMPV6_ECHO_REQUEST, + net_sprint_ipv6_addr(src), + net_sprint_ipv6_addr(dst)); + + ctx->user_data = user_data; + ctx->iface = iface; + + if (net_send_data(pkt) >= 0) { + net_stats_update_icmp_sent(iface); + return 0; + } + + net_stats_update_icmp_drop(iface); + + ret = -EIO; + +drop: + net_pkt_unref(pkt); + + return ret; +} +#else +static int send_icmpv6_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct in6_addr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(iface); + ARG_UNUSED(dst); + ARG_UNUSED(params); + + return -ENOTSUP; +} +#endif + +static struct net_icmp_ping_params *get_default_params(void) +{ + static struct net_icmp_ping_params params = { 0 }; + + params.identifier = sys_rand32_get(); + + return ¶ms; +} + +int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + if (ctx == NULL || dst == NULL) { + return -EINVAL; + } + + if (iface == NULL) { + if (IS_ENABLED(CONFIG_NET_IPV4) && dst->sa_family == AF_INET) { + iface = net_if_ipv4_select_src_iface(&net_sin(dst)->sin_addr); + } else if (IS_ENABLED(CONFIG_NET_IPV6) && dst->sa_family == AF_INET6) { + iface = net_if_ipv6_select_src_iface(&net_sin6(dst)->sin6_addr); + } + + if (iface == NULL) { + return -ENOENT; + } + } + + if (IS_ENABLED(CONFIG_NET_IPV4) && dst->sa_family == AF_INET) { + if (params == NULL) { + params = get_default_params(); + } + + return send_icmpv4_echo_request(ctx, iface, &net_sin(dst)->sin_addr, + params, user_data); + } + + if (IS_ENABLED(CONFIG_NET_IPV6) && dst->sa_family == AF_INET6) { + if (params == NULL) { + params = get_default_params(); + } + + return send_icmpv6_echo_request(ctx, iface, &net_sin6(dst)->sin6_addr, + params, user_data); + } + + return -ENOENT; +} + +static int icmp_call_handlers(struct net_pkt *pkt, + struct net_icmp_ip_hdr *ip_hdr, + struct net_icmp_hdr *icmp_hdr) +{ + struct net_icmp_ctx *ctx; + int ret = -ENOENT; + + k_mutex_lock(&lock, K_FOREVER); + + SYS_SLIST_FOR_EACH_CONTAINER(&handlers, ctx, node) { + if (ctx->type == icmp_hdr->type && + (ctx->code == icmp_hdr->code || ctx->code == 0U)) { + /* Do not use a handler that is expecting data from different + * network interface we sent the request. + */ + if (ctx->iface != NULL && ctx->iface != net_pkt_iface(pkt)) { + continue; + } + + ret = ctx->handler(ctx, pkt, ip_hdr, icmp_hdr, ctx->user_data); + if (ret < 0) { + goto out; + } + } + } + +out: + k_mutex_unlock(&lock); + + return ret; +} + + +int net_icmp_call_ipv4_handlers(struct net_pkt *pkt, + struct net_ipv4_hdr *ipv4_hdr, + struct net_icmp_hdr *icmp_hdr) +{ + struct net_icmp_ip_hdr ip_hdr; + + ip_hdr.ipv4 = ipv4_hdr; + ip_hdr.family = AF_INET; + + return icmp_call_handlers(pkt, &ip_hdr, icmp_hdr); +} + +int net_icmp_call_ipv6_handlers(struct net_pkt *pkt, + struct net_ipv6_hdr *ipv6_hdr, + struct net_icmp_hdr *icmp_hdr) +{ + struct net_icmp_ip_hdr ip_hdr; + + ip_hdr.ipv6 = ipv6_hdr; + ip_hdr.family = AF_INET6; + + return icmp_call_handlers(pkt, &ip_hdr, icmp_hdr); +} diff --git a/subsys/net/ip/icmpv4.h b/subsys/net/ip/icmpv4.h index 492fc6e84a0..1bf8aae2149 100644 --- a/subsys/net/ip/icmpv4.h +++ b/subsys/net/ip/icmpv4.h @@ -19,8 +19,6 @@ #include #define NET_ICMPV4_DST_UNREACH 3 /* Destination unreachable */ -#define NET_ICMPV4_ECHO_REQUEST 8 -#define NET_ICMPV4_ECHO_REPLY 0 #define NET_ICMPV4_TIME_EXCEEDED 11 /* Time exceeded */ #define NET_ICMPV4_BAD_IP_HEADER 12 /* Bad IP header */ diff --git a/subsys/net/ip/icmpv6.h b/subsys/net/ip/icmpv6.h index d71d9959c14..8c2e6a1d35f 100644 --- a/subsys/net/ip/icmpv6.h +++ b/subsys/net/ip/icmpv6.h @@ -144,8 +144,6 @@ struct net_icmpv6_mld_mcast_record { #define NET_ICMPV6_PACKET_TOO_BIG 2 /* Packet too big */ #define NET_ICMPV6_TIME_EXCEEDED 3 /* Time exceeded */ #define NET_ICMPV6_PARAM_PROBLEM 4 /* IPv6 header is bad */ -#define NET_ICMPV6_ECHO_REQUEST 128 -#define NET_ICMPV6_ECHO_REPLY 129 #define NET_ICMPV6_MLD_QUERY 130 /* Multicast Listener Query */ #define NET_ICMPV6_RS 133 /* Router Solicitation */ #define NET_ICMPV6_RA 134 /* Router Advertisement */ diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index ea37cd09b6b..d8d57a6bdc7 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_NET_MGMT_EVENT_INFO @@ -58,6 +59,13 @@ extern void net_if_stats_reset_all(void); extern void net_process_rx_packet(struct net_pkt *pkt); extern void net_process_tx_packet(struct net_pkt *pkt); +extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt, + struct net_ipv4_hdr *ipv4_hdr, + struct net_icmp_hdr *icmp_hdr); +extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt, + struct net_ipv6_hdr *ipv6_hdr, + struct net_icmp_hdr *icmp_hdr); + #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD) extern void net_context_init(void); extern const char *net_context_state(struct net_context *context); From 19273087f20ea53a4d8800e0f418a409bbb7174d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 21 Sep 2023 17:24:35 +0300 Subject: [PATCH 1229/4498] net: Use the ICMP API for receiving ICMP messages Modify the internal network stack code to use the ICMP API. Signed-off-by: Jukka Rissanen --- subsys/net/ip/icmpv4.c | 169 +++++++-------------------------------- subsys/net/ip/icmpv4.h | 70 +--------------- subsys/net/ip/icmpv6.c | 162 +++++++------------------------------ subsys/net/ip/icmpv6.h | 67 ---------------- subsys/net/ip/ipv6_mld.c | 29 ++++--- subsys/net/ip/ipv6_nbr.c | 88 ++++++++++++-------- 6 files changed, 126 insertions(+), 459 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 3bf7e2ce163..ea43f6052d0 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -16,6 +16,7 @@ LOG_MODULE_REGISTER(net_icmpv4, CONFIG_NET_ICMPV4_LOG_LEVEL); #include #include #include +#include #include "net_private.h" #include "ipv4.h" #include "icmpv4.h" @@ -23,14 +24,12 @@ LOG_MODULE_REGISTER(net_icmpv4, CONFIG_NET_ICMPV4_LOG_LEVEL); #define PKT_WAIT_TIME K_SECONDS(1) -static sys_slist_t handlers; - struct net_icmpv4_hdr_opts_data { struct net_pkt *reply; const struct in_addr *src; }; -static int icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code) +int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access, struct net_icmp_hdr); @@ -410,11 +409,14 @@ static int icmpv4_handle_header_options(struct net_pkt *pkt, } #endif -static enum net_verdict icmpv4_handle_echo_request(struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int icmpv4_handle_echo_request(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { struct net_pkt *reply = NULL; + struct net_ipv4_hdr *ip_hdr = hdr->ipv4; const struct in_addr *src; int16_t payload_len; @@ -471,7 +473,7 @@ static enum net_verdict icmpv4_handle_echo_request(struct net_pkt *pkt, } } - if (icmpv4_create(reply, NET_ICMPV4_ECHO_REPLY, 0) || + if (net_icmpv4_create(reply, NET_ICMPV4_ECHO_REPLY, 0) || net_pkt_copy(reply, pkt, payload_len)) { goto drop; } @@ -491,7 +493,7 @@ static enum net_verdict icmpv4_handle_echo_request(struct net_pkt *pkt, net_pkt_unref(pkt); - return NET_OK; + return 0; drop: if (reply) { net_pkt_unref(reply); @@ -499,115 +501,7 @@ static enum net_verdict icmpv4_handle_echo_request(struct net_pkt *pkt, net_stats_update_icmp_drop(net_pkt_iface(pkt)); - return NET_DROP; -} - -int net_icmpv4_send_echo_request(struct net_if *iface, - struct in_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tos, - int priority, - const void *data, - size_t data_size) -{ - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access, - struct net_icmpv4_echo_req); - int ret = -ENOBUFS; - struct net_icmpv4_echo_req *echo_req; - const struct in_addr *src; - struct net_pkt *pkt; - - if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) { - return -ENOTSUP; - } - - if (!iface->config.ip.ipv4) { - return -ENETUNREACH; - } - - /* Take the first address of the network interface */ - src = &iface->config.ip.ipv4->unicast[0].address.in_addr; - - pkt = net_pkt_alloc_with_buffer(iface, - sizeof(struct net_icmpv4_echo_req) - + data_size, - AF_INET, IPPROTO_ICMP, - PKT_WAIT_TIME); - if (!pkt) { - return -ENOMEM; - } - - if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && - priority >= NET_MAX_PRIORITIES) { - NET_ERR("Priority %d is too large, maximum allowed is %d", - priority, NET_MAX_PRIORITIES - 1); - return -EINVAL; - } - - if (priority < 0) { - net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); - net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); - } else { - net_pkt_set_priority(pkt, priority); - } - - if (net_ipv4_create(pkt, src, dst) || - icmpv4_create(pkt, NET_ICMPV4_ECHO_REQUEST, 0)) { - goto drop; - } - - echo_req = (struct net_icmpv4_echo_req *)net_pkt_get_data( - pkt, &icmpv4_access); - if (!echo_req) { - goto drop; - } - - echo_req->identifier = htons(identifier); - echo_req->sequence = htons(sequence); - - net_pkt_set_data(pkt, &icmpv4_access); - - if (data != NULL && data_size > 0) { - net_pkt_write(pkt, data, data_size); - } else if (data == NULL && data_size > 0) { - /* Generate payload. */ - if (data_size >= sizeof(uint32_t)) { - uint32_t time_stamp = htonl(k_cycle_get_32()); - - net_pkt_write(pkt, &time_stamp, sizeof(time_stamp)); - data_size -= sizeof(time_stamp); - } - - for (size_t i = 0; i < data_size; i++) { - net_pkt_write_u8(pkt, (uint8_t)i); - } - } else { - /* No payload. */ - } - - net_pkt_cursor_init(pkt); - - net_ipv4_finalize(pkt, IPPROTO_ICMP); - - NET_DBG("Sending ICMPv4 Echo Request type %d from %s to %s", - NET_ICMPV4_ECHO_REQUEST, - net_sprint_ipv4_addr(src), - net_sprint_ipv4_addr(dst)); - - if (net_send_data(pkt) >= 0) { - net_stats_update_icmp_sent(iface); - return 0; - } - - net_stats_update_icmp_drop(iface); - - ret = -EIO; - -drop: - net_pkt_unref(pkt); - - return ret; + return -EIO; } int net_icmpv4_send_error(struct net_pkt *orig, uint8_t type, uint8_t code) @@ -671,7 +565,7 @@ int net_icmpv4_send_error(struct net_pkt *orig, uint8_t type, uint8_t code) if (net_ipv4_create(pkt, (struct in_addr *)ip_hdr->dst, (struct in_addr *)ip_hdr->src) || - icmpv4_create(pkt, type, code) || + net_icmpv4_create(pkt, type, code) || net_pkt_memset(pkt, 0, NET_ICMPV4_UNUSED_LEN) || net_pkt_copy(pkt, orig, copy_len)) { goto drop; @@ -703,23 +597,13 @@ int net_icmpv4_send_error(struct net_pkt *orig, uint8_t type, uint8_t code) } -void net_icmpv4_register_handler(struct net_icmpv4_handler *handler) -{ - sys_slist_prepend(&handlers, &handler->node); -} - -void net_icmpv4_unregister_handler(struct net_icmpv4_handler *handler) -{ - sys_slist_find_and_remove(&handlers, &handler->node); -} - enum net_verdict net_icmpv4_input(struct net_pkt *pkt, struct net_ipv4_hdr *ip_hdr) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmp_hdr); struct net_icmp_hdr *icmp_hdr; - struct net_icmpv4_handler *cb; + int ret; icmp_hdr = (struct net_icmp_hdr *)net_pkt_get_data(pkt, &icmp_access); if (!icmp_hdr) { @@ -749,26 +633,29 @@ enum net_verdict net_icmpv4_input(struct net_pkt *pkt, net_stats_update_icmp_recv(net_pkt_iface(pkt)); - SYS_SLIST_FOR_EACH_CONTAINER(&handlers, cb, node) { - if (cb->type == icmp_hdr->type && - (cb->code == icmp_hdr->code || cb->code == 0U)) { - return cb->handler(pkt, ip_hdr, icmp_hdr); - } + ret = net_icmp_call_ipv4_handlers(pkt, ip_hdr, icmp_hdr); + if (ret < 0) { + NET_ERR("ICMPv4 handling failure (%d)", ret); } + net_pkt_unref(pkt); + + return NET_OK; + drop: net_stats_update_icmp_drop(net_pkt_iface(pkt)); return NET_DROP; } -static struct net_icmpv4_handler echo_request_handler = { - .type = NET_ICMPV4_ECHO_REQUEST, - .code = 0, - .handler = icmpv4_handle_echo_request, -}; - void net_icmpv4_init(void) { - net_icmpv4_register_handler(&echo_request_handler); + static struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV4_ECHO_REQUEST, 0, icmpv4_handle_echo_request); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV4_ECHO_REQUEST), + ret); + } } diff --git a/subsys/net/ip/icmpv4.h b/subsys/net/ip/icmpv4.h index 1bf8aae2149..b9680c44b34 100644 --- a/subsys/net/ip/icmpv4.h +++ b/subsys/net/ip/icmpv4.h @@ -34,18 +34,6 @@ struct net_icmpv4_echo_req { uint16_t sequence; } __packed; -typedef enum net_verdict (*icmpv4_callback_handler_t)( - struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr); - -struct net_icmpv4_handler { - sys_snode_t node; - icmpv4_callback_handler_t handler; - uint8_t type; - uint8_t code; -}; - /** * @brief Send ICMPv4 error message. * @param pkt Network packet that this error is related to. @@ -55,72 +43,16 @@ struct net_icmpv4_handler { */ int net_icmpv4_send_error(struct net_pkt *pkt, uint8_t type, uint8_t code); -/** - * @brief Send ICMPv4 echo request message. - * - * @param iface Network interface. - * @param dst IPv4 address of the target host. - * @param identifier An identifier to aid in matching Echo Replies - * to this Echo Request. May be zero. - * @param sequence A sequence number to aid in matching Echo Replies - * to this Echo Request. May be zero. - * @param tos IPv4 Type-of-service field value. Represents combined DSCP and ECN - * values. - * @param data Arbitrary payload data that will be included in the - * Echo Reply verbatim. May be NULL. - * @param data_size Size of the Payload Data in bytes. May be zero. In case data - * pointer is NULL, the function will generate the payload up to the requested - * size. - * - * @return Return 0 if the sending succeed, <0 otherwise. - */ -#if defined(CONFIG_NET_NATIVE_IPV4) -int net_icmpv4_send_echo_request(struct net_if *iface, - struct in_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tos, - int priority, - const void *data, - size_t data_size); -#else -static inline int net_icmpv4_send_echo_request(struct net_if *iface, - struct in_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tos, - int priority, - const void *data, - size_t data_size) -{ - ARG_UNUSED(iface); - ARG_UNUSED(dst); - ARG_UNUSED(identifier); - ARG_UNUSED(sequence); - ARG_UNUSED(tos); - ARG_UNUSED(priority); - ARG_UNUSED(data); - ARG_UNUSED(data_size); - - return -ENOTSUP; -} -#endif - #if defined(CONFIG_NET_NATIVE_IPV4) -void net_icmpv4_register_handler(struct net_icmpv4_handler *handler); - -void net_icmpv4_unregister_handler(struct net_icmpv4_handler *handler); - enum net_verdict net_icmpv4_input(struct net_pkt *pkt, struct net_ipv4_hdr *ip_hdr); +int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code); int net_icmpv4_finalize(struct net_pkt *pkt); void net_icmpv4_init(void); #else #define net_icmpv4_init(...) -#define net_icmpv4_register_handler(...) -#define net_icmpv4_unregister_handler(...) #endif #endif /* __ICMPV4_H */ diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index 60865d22017..c19e3d5d1d3 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_icmpv6, CONFIG_NET_ICMPV6_LOG_LEVEL); #include #include #include +#include #include "net_private.h" #include "icmpv6.h" #include "ipv6.h" @@ -24,8 +25,6 @@ LOG_MODULE_REGISTER(net_icmpv6, CONFIG_NET_ICMPV6_LOG_LEVEL); #define PKT_WAIT_TIME K_SECONDS(1) -static sys_slist_t handlers; - const char *net_icmpv6_type2str(int icmpv6_type) { switch (icmpv6_type) { @@ -58,16 +57,6 @@ const char *net_icmpv6_type2str(int icmpv6_type) return "?"; } -void net_icmpv6_register_handler(struct net_icmpv6_handler *handler) -{ - sys_slist_prepend(&handlers, &handler->node); -} - -void net_icmpv6_unregister_handler(struct net_icmpv6_handler *handler) -{ - sys_slist_find_and_remove(&handlers, &handler->node); -} - int net_icmpv6_finalize(struct net_pkt *pkt) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, @@ -105,15 +94,18 @@ int net_icmpv6_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code) return net_pkt_set_data(pkt, &icmp_access); } -static -enum net_verdict icmpv6_handle_echo_request(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { struct net_pkt *reply = NULL; + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; const struct in6_addr *src; int16_t payload_len; + ARG_UNUSED(user_data); ARG_UNUSED(icmp_hdr); NET_DBG("Received Echo Request from %s to %s", @@ -178,7 +170,7 @@ enum net_verdict icmpv6_handle_echo_request(struct net_pkt *pkt, net_pkt_unref(pkt); - return NET_OK; + return 0; drop: if (reply) { @@ -187,7 +179,7 @@ enum net_verdict icmpv6_handle_echo_request(struct net_pkt *pkt, net_stats_update_icmp_drop(net_pkt_iface(pkt)); - return NET_DROP; + return -EIO; } int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code, @@ -336,112 +328,13 @@ int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code, return err; } -int net_icmpv6_send_echo_request(struct net_if *iface, - struct in6_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tc, - int priority, - const void *data, - size_t data_size) -{ - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv6_access, - struct net_icmpv6_echo_req); - int ret = -ENOBUFS; - struct net_icmpv6_echo_req *echo_req; - const struct in6_addr *src; - struct net_pkt *pkt; - - src = net_if_ipv6_select_src_addr(iface, dst); - - pkt = net_pkt_alloc_with_buffer(iface, - sizeof(struct net_icmpv6_echo_req) - + data_size, - AF_INET6, IPPROTO_ICMPV6, - PKT_WAIT_TIME); - if (!pkt) { - return -ENOMEM; - } - - if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && - priority >= NET_MAX_PRIORITIES) { - NET_ERR("Priority %d is too large, maximum allowed is %d", - priority, NET_MAX_PRIORITIES - 1); - return -EINVAL; - } - - if (priority < 0) { - net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); - net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(tc)); - } else { - net_pkt_set_priority(pkt, priority); - } - - if (net_ipv6_create(pkt, src, dst) || - net_icmpv6_create(pkt, NET_ICMPV6_ECHO_REQUEST, 0)) { - goto drop; - } - - echo_req = (struct net_icmpv6_echo_req *)net_pkt_get_data( - pkt, &icmpv6_access); - if (!echo_req) { - goto drop; - } - - echo_req->identifier = htons(identifier); - echo_req->sequence = htons(sequence); - - net_pkt_set_data(pkt, &icmpv6_access); - - if (data != NULL && data_size > 0) { - net_pkt_write(pkt, data, data_size); - } else if (data == NULL && data_size > 0) { - /* Generate payload. */ - if (data_size >= sizeof(uint32_t)) { - uint32_t time_stamp = htonl(k_cycle_get_32()); - - net_pkt_write(pkt, &time_stamp, sizeof(time_stamp)); - data_size -= sizeof(time_stamp); - } - - for (size_t i = 0; i < data_size; i++) { - net_pkt_write_u8(pkt, (uint8_t)i); - } - } else { - /* No payload. */ - } - - net_pkt_cursor_init(pkt); - net_ipv6_finalize(pkt, IPPROTO_ICMPV6); - - NET_DBG("Sending ICMPv6 Echo Request type %d from %s to %s", - NET_ICMPV6_ECHO_REQUEST, - net_sprint_ipv6_addr(src), - net_sprint_ipv6_addr(dst)); - - if (net_send_data(pkt) >= 0) { - net_stats_update_icmp_sent(iface); - return 0; - } - - net_stats_update_icmp_drop(iface); - - ret = -EIO; - -drop: - net_pkt_unref(pkt); - - return ret; -} - enum net_verdict net_icmpv6_input(struct net_pkt *pkt, struct net_ipv6_hdr *ip_hdr) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmp_hdr); struct net_icmp_hdr *icmp_hdr; - struct net_icmpv6_handler *cb; - enum net_verdict res; + int ret; icmp_hdr = (struct net_icmp_hdr *)net_pkt_get_data(pkt, &icmp_access); if (!icmp_hdr) { @@ -465,30 +358,29 @@ enum net_verdict net_icmpv6_input(struct net_pkt *pkt, net_stats_update_icmp_recv(net_pkt_iface(pkt)); - SYS_SLIST_FOR_EACH_CONTAINER(&handlers, cb, node) { - if (cb->type == icmp_hdr->type && - (cb->code == icmp_hdr->code || cb->code == 0U)) { - res = cb->handler(pkt, ip_hdr, icmp_hdr); - if (res == NET_CONTINUE) { - continue; - } else { - return res; - } - } + ret = net_icmp_call_ipv6_handlers(pkt, ip_hdr, icmp_hdr); + if (ret < 0) { + NET_ERR("ICMPv6 handling failure (%d)", ret); } + + net_pkt_unref(pkt); + + return NET_OK; + drop: net_stats_update_icmp_drop(net_pkt_iface(pkt)); return NET_DROP; } -static struct net_icmpv6_handler echo_request_handler = { - .type = NET_ICMPV6_ECHO_REQUEST, - .code = 0, - .handler = icmpv6_handle_echo_request, -}; - void net_icmpv6_init(void) { - net_icmpv6_register_handler(&echo_request_handler); + static struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_ECHO_REQUEST, 0, icmpv6_handle_echo_request); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_ECHO_REQUEST), + ret); + } } diff --git a/subsys/net/ip/icmpv6.h b/subsys/net/ip/icmpv6.h index 8c2e6a1d35f..967111955f3 100644 --- a/subsys/net/ip/icmpv6.h +++ b/subsys/net/ip/icmpv6.h @@ -168,20 +168,8 @@ struct net_icmpv6_mld_mcast_record { /* ICMPv6 header has 4 unused bytes that must be zero, RFC 4443 ch 3.1 */ #define NET_ICMPV6_UNUSED_LEN 4 -typedef enum net_verdict (*icmpv6_callback_handler_t)( - struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr); - const char *net_icmpv6_type2str(int icmpv6_type); -struct net_icmpv6_handler { - sys_snode_t node; - icmpv6_callback_handler_t handler; - uint8_t type; - uint8_t code; -}; - /** * @brief Send ICMPv6 error message. * @param pkt Network packet that this error is related to. @@ -195,60 +183,7 @@ struct net_icmpv6_handler { int net_icmpv6_send_error(struct net_pkt *pkt, uint8_t type, uint8_t code, uint32_t param); -/** - * @brief Send ICMPv6 echo request message. - * - * @param iface Network interface. - * @param dst IPv6 address of the target host. - * @param identifier An identifier to aid in matching Echo Replies - * to this Echo Request. May be zero. - * @param sequence A sequence number to aid in matching Echo Replies - * to this Echo Request. May be zero. - * @param tc IPv6 Traffic Class field value. Represents combined DSCP and - * ECN values. - * @param data Arbitrary payload data that will be included in the - * Echo Reply verbatim. May be NULL. - * @param data_size Size of the Payload Data in bytes. May be zero. In case data - * pointer is NULL, the function will generate the payload up to the requested - * size. - * - * @return Return 0 if the sending succeed, <0 otherwise. - */ -#if defined(CONFIG_NET_NATIVE_IPV6) -int net_icmpv6_send_echo_request(struct net_if *iface, - struct in6_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tc, - int priority, - const void *data, - size_t data_size); -#else -static inline int net_icmpv6_send_echo_request(struct net_if *iface, - struct in6_addr *dst, - uint16_t identifier, - uint16_t sequence, - uint8_t tc, - int priority, - const void *data, - size_t data_size) -{ - ARG_UNUSED(iface); - ARG_UNUSED(dst); - ARG_UNUSED(identifier); - ARG_UNUSED(sequence); - ARG_UNUSED(tc); - ARG_UNUSED(priority); - ARG_UNUSED(data); - ARG_UNUSED(data_size); - - return -ENOTSUP; -} -#endif - #if defined(CONFIG_NET_NATIVE_IPV6) -void net_icmpv6_register_handler(struct net_icmpv6_handler *handler); -void net_icmpv6_unregister_handler(struct net_icmpv6_handler *handler); enum net_verdict net_icmpv6_input(struct net_pkt *pkt, struct net_ipv6_hdr *ip_hdr); @@ -258,8 +193,6 @@ int net_icmpv6_finalize(struct net_pkt *pkt); void net_icmpv6_init(void); #else #define net_icmpv6_init(...) -#define net_icmpv6_register_handler(...) -#define net_icmpv6_unregister_handler(...) #endif #endif /* __ICMPV6_H */ diff --git a/subsys/net/ip/ipv6_mld.c b/subsys/net/ip/ipv6_mld.c index 90eb1343f08..43435b0b10f 100644 --- a/subsys/net/ip/ipv6_mld.c +++ b/subsys/net/ip/ipv6_mld.c @@ -17,6 +17,7 @@ LOG_MODULE_DECLARE(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include +#include #include "net_private.h" #include "connection.h" #include "icmpv6.h" @@ -308,12 +309,15 @@ static void send_mld_report(struct net_if *iface) #define dbg_addr_recv(pkt_str, src, dst) \ dbg_addr("Received", pkt_str, src, dst) -static enum net_verdict handle_mld_query(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_mld_query(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(mld_access, struct net_icmpv6_mld_query); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; uint16_t length = net_pkt_get_len(pkt); struct net_icmpv6_mld_query *mld_query; uint16_t pkt_len; @@ -354,21 +358,22 @@ static enum net_verdict handle_mld_query(struct net_pkt *pkt, net_pkt_unref(pkt); - return NET_OK; + return 0; drop: net_stats_update_ipv6_mld_drop(net_pkt_iface(pkt)); - return NET_DROP; + return -EIO; } -static struct net_icmpv6_handler mld_query_input_handler = { - .type = NET_ICMPV6_MLD_QUERY, - .code = 0, - .handler = handle_mld_query, -}; - void net_ipv6_mld_init(void) { - net_icmpv6_register_handler(&mld_query_input_handler); + static struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_MLD_QUERY, 0, handle_mld_query); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_MLD_QUERY), + ret); + } } diff --git a/subsys/net/ip/ipv6_nbr.c b/subsys/net/ip/ipv6_nbr.c index e220980a199..cca65d9fdc4 100644 --- a/subsys/net/ip/ipv6_nbr.c +++ b/subsys/net/ip/ipv6_nbr.c @@ -24,6 +24,7 @@ LOG_MODULE_DECLARE(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include +#include #include "net_private.h" #include "connection.h" #include "icmpv6.h" @@ -1131,13 +1132,16 @@ static void ns_routing_info(struct net_pkt *pkt, } } -static enum net_verdict handle_ns_input(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_ns_input(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ns_access, struct net_icmpv6_ns_hdr); NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; uint16_t length = net_pkt_get_len(pkt); uint8_t flags = 0U; bool routing = false; @@ -1380,17 +1384,17 @@ static enum net_verdict handle_ns_input(struct net_pkt *pkt, if (!net_ipv6_send_na(net_pkt_iface(pkt), na_src, na_dst, tgt, flags)) { net_pkt_unref(pkt); - return NET_OK; + return 0; } NET_DBG("DROP: Cannot send NA"); - return NET_DROP; + return -EIO; drop: net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt)); - return NET_DROP; + return -EIO; } #endif /* CONFIG_NET_IPV6_NBR_CACHE */ @@ -1712,13 +1716,16 @@ static inline bool handle_na_neighbor(struct net_pkt *pkt, return true; } -static enum net_verdict handle_na_input(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_na_input(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(na_access, struct net_icmpv6_na_hdr); NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; uint16_t length = net_pkt_get_len(pkt); uint16_t tllao_offset = 0U; struct net_icmpv6_nd_opt_hdr *nd_opt_hdr; @@ -1817,12 +1824,12 @@ static enum net_verdict handle_na_input(struct net_pkt *pkt, net_pkt_unref(pkt); - return NET_OK; + return 0; drop: net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt)); - return NET_DROP; + return -EIO; } int net_ipv6_send_ns(struct net_if *iface, @@ -2383,13 +2390,16 @@ static inline bool handle_ra_rdnss(struct net_pkt *pkt, uint8_t len) } #endif -static enum net_verdict handle_ra_input(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_ra_input(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ra_access, struct net_icmpv6_ra_hdr); NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; uint16_t length = net_pkt_get_len(pkt); struct net_nbr *nbr = NULL; struct net_icmpv6_nd_opt_hdr *nd_opt_hdr; @@ -2398,6 +2408,8 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt, uint32_t mtu, reachable_time, retrans_timer; uint16_t router_lifetime; + ARG_UNUSED(user_data); + if (net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_IPV6_NO_ND)) { goto drop; } @@ -2600,48 +2612,54 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt, net_pkt_unref(pkt); - return NET_OK; + return 0; drop: net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt)); - return NET_DROP; + return -EIO; } #endif /* CONFIG_NET_IPV6_ND */ #if defined(CONFIG_NET_IPV6_NBR_CACHE) -static struct net_icmpv6_handler ns_input_handler = { - .type = NET_ICMPV6_NS, - .code = 0, - .handler = handle_ns_input, -}; - -static struct net_icmpv6_handler na_input_handler = { - .type = NET_ICMPV6_NA, - .code = 0, - .handler = handle_na_input, -}; +static struct net_icmp_ctx ns_ctx; +static struct net_icmp_ctx na_ctx; #endif /* CONFIG_NET_IPV6_NBR_CACHE */ #if defined(CONFIG_NET_IPV6_ND) -static struct net_icmpv6_handler ra_input_handler = { - .type = NET_ICMPV6_RA, - .code = 0, - .handler = handle_ra_input, -}; +static struct net_icmp_ctx ra_ctx; #endif /* CONFIG_NET_IPV6_ND */ void net_ipv6_nbr_init(void) { + int ret; + #if defined(CONFIG_NET_IPV6_NBR_CACHE) - net_icmpv6_register_handler(&ns_input_handler); - net_icmpv6_register_handler(&na_input_handler); + ret = net_icmp_init_ctx(&ns_ctx, NET_ICMPV6_NS, 0, handle_ns_input); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_NS), + ret); + } + + ret = net_icmp_init_ctx(&na_ctx, NET_ICMPV6_NA, 0, handle_na_input); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_NA), + ret); + } + k_work_init_delayable(&ipv6_ns_reply_timer, ipv6_ns_reply_timeout); k_sem_init(&nbr_lock, 1, K_SEM_MAX_LIMIT); #endif #if defined(CONFIG_NET_IPV6_ND) - net_icmpv6_register_handler(&ra_input_handler); + ret = net_icmp_init_ctx(&ra_ctx, NET_ICMPV6_RA, 0, handle_ra_input); + if (ret < 0) { + NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_RA), + ret); + } + k_work_init_delayable(&ipv6_nd_reachable_timer, ipv6_nd_reachable_timeout); #endif + + ARG_UNUSED(ret); } From e3fb634e7afa1a14121559e6a0b3ddbeb947c5c5 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 21 Sep 2023 17:25:47 +0300 Subject: [PATCH 1230/4498] net: shell: Use the ICMP API for ping command Change the ping command to use the ICMP API. Signed-off-by: Jukka Rissanen --- subsys/net/ip/net_shell.c | 173 ++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 80 deletions(-) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index e7af6e16632..3a113778918 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -33,6 +33,8 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #endif /* CONFIG_NET_L2_ETHERNET */ +#include + #include "route.h" #include "icmpv6.h" #include "icmpv4.h" @@ -4305,7 +4307,12 @@ static int cmd_net_nbr(const struct shell *sh, size_t argc, char *argv[]) static struct ping_context { struct k_work_delayable work; - struct net_addr addr; + struct net_icmp_ctx icmp; + union { + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + struct sockaddr addr; + }; struct net_if *iface; const struct shell *sh; @@ -4322,27 +4329,15 @@ static void ping_done(struct ping_context *ctx); #if defined(CONFIG_NET_NATIVE_IPV6) -static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr); - -static struct net_icmpv6_handler ping6_handler = { - .type = NET_ICMPV6_ECHO_REPLY, - .code = 0, - .handler = handle_ipv6_echo_reply, -}; - -static inline void remove_ipv6_ping_handler(void) -{ - net_icmpv6_unregister_handler(&ping6_handler); -} - -static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmpv6_echo_req); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; struct net_icmpv6_echo_req *icmp_echo; uint32_t cycles; char time_buf[16] = { 0 }; @@ -4350,14 +4345,14 @@ static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, icmp_echo = (struct net_icmpv6_echo_req *)net_pkt_get_data(pkt, &icmp_access); if (icmp_echo == NULL) { - return -NET_DROP; + return -EIO; } net_pkt_skip(pkt, sizeof(*icmp_echo)); if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { if (net_pkt_read_be32(pkt, &cycles)) { - return -NET_DROP; + return -EIO; } cycles = k_cycle_get_32() - cycles; @@ -4394,35 +4389,36 @@ static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, } net_pkt_unref(pkt); - return NET_OK; + return 0; } #else -#define remove_ipv6_ping_handler() +static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + + return -ENOTSUP; +} #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_NATIVE_IPV4) -static enum net_verdict handle_ipv4_echo_reply(struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr); - -static struct net_icmpv4_handler ping4_handler = { - .type = NET_ICMPV4_ECHO_REPLY, - .code = 0, - .handler = handle_ipv4_echo_reply, -}; - -static inline void remove_ipv4_ping_handler(void) -{ - net_icmpv4_unregister_handler(&ping4_handler); -} - -static enum net_verdict handle_ipv4_echo_reply(struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmpv4_echo_req); + struct net_ipv4_hdr *ip_hdr = hdr->ipv4; uint32_t cycles; struct net_icmpv4_echo_req *icmp_echo; char time_buf[16] = { 0 }; @@ -4430,14 +4426,14 @@ static enum net_verdict handle_ipv4_echo_reply(struct net_pkt *pkt, icmp_echo = (struct net_icmpv4_echo_req *)net_pkt_get_data(pkt, &icmp_access); if (icmp_echo == NULL) { - return -NET_DROP; + return -EIO; } net_pkt_skip(pkt, sizeof(*icmp_echo)); if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { if (net_pkt_read_be32(pkt, &cycles)) { - return -NET_DROP; + return -EIO; } cycles = k_cycle_get_32() - cycles; @@ -4468,11 +4464,23 @@ static enum net_verdict handle_ipv4_echo_reply(struct net_pkt *pkt, } net_pkt_unref(pkt); - return NET_OK; + return 0; } - #else -#define remove_ipv4_ping_handler() +static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + + return -ENOTSUP; +} #endif /* CONFIG_NET_IPV4 */ static int parse_arg(size_t *i, size_t argc, char *argv[]) @@ -4506,8 +4514,7 @@ static int parse_arg(size_t *i, size_t argc, char *argv[]) static void ping_cleanup(struct ping_context *ctx) { - remove_ipv6_ping_handler(); - remove_ipv4_ping_handler(); + (void)net_icmp_cleanup_ctx(&ctx->icmp); shell_set_bypass(ctx->sh, NULL); } @@ -4525,6 +4532,7 @@ static void ping_work(struct k_work *work) struct ping_context *ctx = CONTAINER_OF(dwork, struct ping_context, work); const struct shell *sh = ctx->sh; + struct net_icmp_ping_params params; int ret; ctx->sequence++; @@ -4535,26 +4543,18 @@ static void ping_work(struct k_work *work) return; } - if (ctx->addr.family == AF_INET6) { - ret = net_icmpv6_send_echo_request(ctx->iface, - &ctx->addr.in6_addr, - sys_rand32_get(), - ctx->sequence, - ctx->tos, - ctx->priority, - NULL, - ctx->payload_size); - } else { - ret = net_icmpv4_send_echo_request(ctx->iface, - &ctx->addr.in_addr, - sys_rand32_get(), - ctx->sequence, - ctx->tos, - ctx->priority, - NULL, - ctx->payload_size); - } + params.identifier = sys_rand32_get(); + params.sequence = ctx->sequence; + params.tc_tos = ctx->tos; + params.priority = ctx->priority; + params.data = NULL; + params.data_size = ctx->payload_size; + ret = net_icmp_send_echo_request(&ctx->icmp, + ctx->iface, + &ctx->addr, + ¶ms, + ctx); if (ret != 0) { PR_WARNING("Failed to send ping, err: %d", ret); ping_done(ctx); @@ -4583,7 +4583,7 @@ static void ping_bypass(const struct shell *sh, uint8_t *data, size_t len) } } -static struct net_if *ping_select_iface(int id, struct net_addr *target) +static struct net_if *ping_select_iface(int id, struct sockaddr *target) { struct net_if *iface = net_if_get_by_index(id); @@ -4591,8 +4591,8 @@ static struct net_if *ping_select_iface(int id, struct net_addr *target) goto out; } - if (IS_ENABLED(CONFIG_NET_IPV4) && target->family == AF_INET) { - iface = net_if_ipv4_select_src_iface(&target->in_addr); + if (IS_ENABLED(CONFIG_NET_IPV4) && target->sa_family == AF_INET) { + iface = net_if_ipv4_select_src_iface(&net_sin(target)->sin_addr); if (iface != NULL) { goto out; } @@ -4601,25 +4601,25 @@ static struct net_if *ping_select_iface(int id, struct net_addr *target) goto out; } - if (IS_ENABLED(CONFIG_NET_IPV6) && target->family == AF_INET6) { + if (IS_ENABLED(CONFIG_NET_IPV6) && target->sa_family == AF_INET6) { struct net_nbr *nbr; #if defined(CONFIG_NET_ROUTE) struct net_route_entry *route; #endif - iface = net_if_ipv6_select_src_iface(&target->in6_addr); + iface = net_if_ipv6_select_src_iface(&net_sin6(target)->sin6_addr); if (iface != NULL) { goto out; } - nbr = net_ipv6_nbr_lookup(NULL, &target->in6_addr); + nbr = net_ipv6_nbr_lookup(NULL, &net_sin6(target)->sin6_addr); if (nbr) { iface = nbr->iface; goto out; } #if defined(CONFIG_NET_ROUTE) - route = net_route_lookup(NULL, &target->in6_addr); + route = net_route_lookup(NULL, &net_sin6(target)->sin6_addr); if (route) { iface = route->iface; goto out; @@ -4652,6 +4652,7 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) int tos = 0; int payload_size = 4; int priority = -1; + int ret; for (size_t i = 1; i < argc; ++i) { @@ -4736,13 +4737,25 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) ping_ctx.payload_size = payload_size; if (IS_ENABLED(CONFIG_NET_IPV6) && - net_addr_pton(AF_INET6, host, &ping_ctx.addr.in6_addr) == 0) { - ping_ctx.addr.family = AF_INET6; - net_icmpv6_register_handler(&ping6_handler); + net_addr_pton(AF_INET6, host, &ping_ctx.addr6.sin6_addr) == 0) { + ping_ctx.addr6.sin6_family = AF_INET6; + + ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV6_ECHO_REPLY, 0, + handle_ipv6_echo_reply); + if (ret < 0) { + PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv6"); + return 0; + } } else if (IS_ENABLED(CONFIG_NET_IPV4) && - net_addr_pton(AF_INET, host, &ping_ctx.addr.in_addr) == 0) { - ping_ctx.addr.family = AF_INET; - net_icmpv4_register_handler(&ping4_handler); + net_addr_pton(AF_INET, host, &ping_ctx.addr4.sin_addr) == 0) { + ping_ctx.addr4.sin_family = AF_INET; + + ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV4_ECHO_REPLY, 0, + handle_ipv4_echo_reply); + if (ret < 0) { + PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv4"); + return 0; + } } else { PR_WARNING("Invalid IP address\n"); return 0; From c4736262679c7616d16ce82f7136c8742dc1e57d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 26 Sep 2023 10:59:51 +0300 Subject: [PATCH 1231/4498] net: if: Add function for network interface offloading status Add new net_if_is_offloaded(iface) that returns true if the network interface is offloaded (either IP or socket offloading is enabled for that interface) and false if the interface is not offloaded. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_if.h | 9 +++++++++ subsys/net/ip/net_if.c | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index b06bf74de03..82a1447b4f9 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -843,6 +843,15 @@ static inline bool net_if_is_ip_offloaded(struct net_if *iface) #endif } +/** + * @brief Return offload status of a given network interface. + * + * @param iface Network interface + * + * @return True if IP or socket offloading is active, false otherwise. + */ +bool net_if_is_offloaded(struct net_if *iface); + /** * @brief Return the IP offload plugin * diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 09e91e2bdcb..f620dfeb4aa 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4248,7 +4248,7 @@ void net_if_foreach(net_if_cb_t cb, void *user_data) } } -static inline bool is_iface_offloaded(struct net_if *iface) +bool net_if_is_offloaded(struct net_if *iface) { return (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) || @@ -4268,7 +4268,7 @@ static void notify_iface_up(struct net_if *iface) } else #endif /* CONFIG_NET_L2_CANBUS_RAW */ { - if (!is_iface_offloaded(iface)) { + if (!net_if_is_offloaded(iface)) { NET_ASSERT(net_if_get_link_addr(iface)->addr != NULL); } } @@ -4280,7 +4280,7 @@ static void notify_iface_up(struct net_if *iface) /* If the interface is only having point-to-point traffic then we do * not need to run DAD etc for it. */ - if (!is_iface_offloaded(iface) && + if (!net_if_is_offloaded(iface) && !(l2_flags_get(iface) & NET_L2_POINT_TO_POINT)) { iface_ipv6_start(iface); net_ipv4_autoconf_start(iface); @@ -4293,7 +4293,7 @@ static void notify_iface_down(struct net_if *iface) net_mgmt_event_notify(NET_EVENT_IF_DOWN, iface); net_virtual_disable(iface); - if (!is_iface_offloaded(iface) && + if (!net_if_is_offloaded(iface) && !(l2_flags_get(iface) & NET_L2_POINT_TO_POINT)) { net_ipv4_autoconf_reset(iface); } @@ -4724,7 +4724,7 @@ void net_if_add_tx_timestamp(struct net_pkt *pkt) bool net_if_is_wifi(struct net_if *iface) { - if (is_iface_offloaded(iface)) { + if (net_if_is_offloaded(iface)) { return net_off_is_wifi_offloaded(iface); } #if defined(CONFIG_NET_L2_ETHERNET) From 3baaa7292036fd543e6edc5d779e5077b2a32696 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 22 Sep 2023 12:28:15 +0300 Subject: [PATCH 1232/4498] net: icmp: Add offloading support Add suitable functions that offloaded network device driver can receive ICMP Echo-Request (ping) requests and give ICMP responses back when it receives them from the network. Signed-off-by: Jukka Rissanen --- include/zephyr/net/icmp.h | 85 ++++++++++++++++++++ subsys/net/ip/Kconfig | 8 ++ subsys/net/ip/icmp.c | 165 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 253 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/icmp.h b/include/zephyr/net/icmp.h index 47ad489ecb5..a5b9f6b2455 100644 --- a/include/zephyr/net/icmp.h +++ b/include/zephyr/net/icmp.h @@ -34,6 +34,7 @@ extern "C" { struct net_icmp_ctx; struct net_icmp_ip_hdr; +struct net_icmp_ping_params; /** * @typedef net_icmp_handler_t @@ -51,6 +52,28 @@ typedef int (*net_icmp_handler_t)(struct net_icmp_ctx *ctx, struct net_icmp_hdr *icmp_hdr, void *user_data); +/** + * @typedef net_icmp_offload_ping_handler_t + * @brief Handler function that is called when an Echo-Request is sent + * to offloaded device. This handler is typically setup by the + * device driver so that it can catch the ping request and send + * it to the offloaded device. + * + * @param ctx ICMP context used in this request. + * @param iface Network interface, can be set to NULL in which case the + * interface is selected according to destination address. + * @param dst IP address of the target host. + * @param params Echo-Request specific parameters. May be NULL in which case + * suitable default parameters are used. + * @param user_data User supplied opaque data passed to the handler. May be NULL. + * + */ +typedef int (*net_icmp_offload_ping_handler_t)(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + void *user_data); + /** * @brief ICMP context structure. */ @@ -165,6 +188,68 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, struct net_icmp_ping_params *params, void *user_data); +/** + * @brief ICMP offload context structure. + */ +struct net_icmp_offload { + /** List node */ + sys_snode_t node; + + /** + * ICMP response handler. Currently there is only one handler. + * This means that one offloaded ping request/response can be going + * on at the same time. + */ + net_icmp_handler_t handler; + + /** ICMP offloaded ping handler */ + net_icmp_offload_ping_handler_t ping_handler; + + /** Offloaded network interface */ + struct net_if *iface; +}; + +/** + * @brief Register a handler function that is called when an Echo-Request + * is sent to the offloaded device. This function is typically + * called by a device driver so that it can do the actual offloaded + * ping call. + * + * @param ctx ICMP offload context used for this interface. + * @param iface Network interface of the offloaded device. + * @param ping_handler Function to be called when offloaded ping request is done. + * + * @return Return 0 if the register succeed, <0 otherwise. + */ +int net_icmp_register_offload_ping(struct net_icmp_offload *ctx, + struct net_if *iface, + net_icmp_offload_ping_handler_t ping_handler); + +/** + * @brief Unregister the offload handler. + * + * @param ctx ICMP offload context used for this interface. + * + * @return Return 0 if the call succeed, <0 otherwise. + */ +int net_icmp_unregister_offload_ping(struct net_icmp_offload *ctx); + +/** + * @brief Get a ICMP response handler function for an offloaded device. + * When a ping response is received by the driver, it should call + * the handler function with proper parameters so that the ICMP response + * is received by the net stack. + * + * @param ctx ICMP offload context used in this request. + * @param resp_handler Function to be called when offloaded ping response + * is received by the offloaded driver. The ICMP response handler + * function is returned and the caller should call it when appropriate. + * + * @return Return 0 if the call succeed, <0 otherwise. + */ +int net_icmp_get_offload_rsp_handler(struct net_icmp_offload *ctx, + net_icmp_handler_t *resp_handler); + #ifdef __cplusplus } #endif diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 74f53293983..b85da2a03de 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -53,6 +53,14 @@ config NET_OFFLOAD help Enables TCP/IP stack to be offload to a co-processor. +config NET_OFFLOADING_SUPPORT + bool + default y if NET_OFFLOAD || NET_SOCKETS_OFFLOAD + help + Hidden option that is set if either NET_OFFLOAD or + NET_SOCKETS_OFFLOAD is set. This allows us to check + only one option instead of two. + if NET_OFFLOAD module = NET_OFFLOAD module-dep = NET_LOG diff --git a/subsys/net/ip/icmp.c b/subsys/net/ip/icmp.c index 81e51cdc1b6..37a8668432c 100644 --- a/subsys/net/ip/icmp.c +++ b/subsys/net/ip/icmp.c @@ -44,6 +44,10 @@ LOG_MODULE_REGISTER(net_icmp, ICMP_LOG_LEVEL); static K_MUTEX_DEFINE(lock); static sys_slist_t handlers = SYS_SLIST_STATIC_INIT(&handlers); +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) +static sys_slist_t offload_handlers = SYS_SLIST_STATIC_INIT(&offload_handlers); +#endif + #define PKT_WAIT_TIME K_SECONDS(1) int net_icmp_init_ctx(struct net_icmp_ctx *ctx, uint8_t type, uint8_t code, @@ -68,6 +72,31 @@ int net_icmp_init_ctx(struct net_icmp_ctx *ctx, uint8_t type, uint8_t code, return 0; } +static void set_offload_handler(struct net_if *iface, + net_icmp_handler_t handler) +{ + struct net_icmp_offload *offload; + + if (!IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT)) { + return; + } + + k_mutex_lock(&lock, K_FOREVER); + +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) + SYS_SLIST_FOR_EACH_CONTAINER(&offload_handlers, offload, node) { + if (offload->iface == iface) { + offload->handler = handler; + break; + } + } +#else + ARG_UNUSED(offload); +#endif + + k_mutex_unlock(&lock); +} + int net_icmp_cleanup_ctx(struct net_icmp_ctx *ctx) { if (ctx == NULL) { @@ -80,6 +109,8 @@ int net_icmp_cleanup_ctx(struct net_icmp_ctx *ctx) k_mutex_unlock(&lock); + set_offload_handler(ctx->iface, NULL); + memset(ctx, 0, sizeof(struct net_icmp_ctx)); return 0; @@ -99,11 +130,6 @@ static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx, const struct in_addr *src; struct net_pkt *pkt; - if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) { - /* XXX: fixme so that we can send offloaded messages too */ - return -ENOTSUP; - } - if (!iface->config.ip.ipv4) { return -ENETUNREACH; } @@ -337,6 +363,45 @@ static struct net_icmp_ping_params *get_default_params(void) return ¶ms; } +static int get_offloaded_ping_handler(struct net_if *iface, + net_icmp_offload_ping_handler_t *ping_handler) +{ + struct net_icmp_offload *offload; + int ret; + + if (!IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT)) { + return -ENOTSUP; + } + + if (iface == NULL) { + return -EINVAL; + } + + if (!net_if_is_offloaded(iface)) { + return -ENOENT; + } + + ret = -ENOENT; + + k_mutex_lock(&lock, K_FOREVER); + +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) + SYS_SLIST_FOR_EACH_CONTAINER(&offload_handlers, offload, node) { + if (offload->iface == iface) { + *ping_handler = offload->ping_handler; + ret = 0; + break; + } + } +#else + ARG_UNUSED(offload); +#endif + + k_mutex_unlock(&lock); + + return ret; +} + int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, struct net_if *iface, struct sockaddr *dst, @@ -359,6 +424,25 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, } } + if (IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT) && net_if_is_offloaded(iface)) { + net_icmp_offload_ping_handler_t ping_handler = NULL; + int ret; + + ret = get_offloaded_ping_handler(iface, &ping_handler); + if (ret < 0) { + return ret; + } + + if (ping_handler == NULL) { + NET_ERR("No ping handler set"); + return -ENOENT; + } + + set_offload_handler(iface, ctx->handler); + + return ping_handler(ctx, iface, dst, params, user_data); + } + if (IS_ENABLED(CONFIG_NET_IPV4) && dst->sa_family == AF_INET) { if (params == NULL) { params = get_default_params(); @@ -436,3 +520,74 @@ int net_icmp_call_ipv6_handlers(struct net_pkt *pkt, return icmp_call_handlers(pkt, &ip_hdr, icmp_hdr); } + +int net_icmp_register_offload_ping(struct net_icmp_offload *ctx, + struct net_if *iface, + net_icmp_offload_ping_handler_t ping_handler) +{ + if (!IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT)) { + return -ENOTSUP; + } + + if (iface == NULL) { + return -EINVAL; + } + + if (!net_if_is_offloaded(iface)) { + return -ENOENT; + } + + memset(ctx, 0, sizeof(struct net_icmp_offload)); + + ctx->ping_handler = ping_handler; + ctx->iface = iface; + + k_mutex_lock(&lock, K_FOREVER); + +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) + sys_slist_prepend(&offload_handlers, &ctx->node); +#endif + + k_mutex_unlock(&lock); + + return 0; +} + +int net_icmp_unregister_offload_ping(struct net_icmp_offload *ctx) +{ + if (!IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT)) { + return -ENOTSUP; + } + + if (ctx == NULL) { + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) + sys_slist_find_and_remove(&offload_handlers, &ctx->node); +#endif + + k_mutex_unlock(&lock); + + memset(ctx, 0, sizeof(struct net_icmp_offload)); + + return 0; +} + +int net_icmp_get_offload_rsp_handler(struct net_icmp_offload *ctx, + net_icmp_handler_t *resp_handler) +{ + if (!IS_ENABLED(CONFIG_NET_OFFLOADING_SUPPORT)) { + return -ENOTSUP; + } + + if (ctx == NULL) { + return -EINVAL; + } + + *resp_handler = ctx->handler; + + return 0; +} From 19d1dd747f5e7a823948261c68dfa6ead0689218 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 22 Sep 2023 17:13:39 +0300 Subject: [PATCH 1233/4498] tests: net: icmp: Add test cases for new ICMP API Tests cases for new ICMP API. Signed-off-by: Jukka Rissanen --- tests/net/icmp/CMakeLists.txt | 9 ++ tests/net/icmp/prj.conf | 21 +++ tests/net/icmp/src/main.c | 296 ++++++++++++++++++++++++++++++++++ tests/net/icmp/testcase.yaml | 22 +++ 4 files changed, 348 insertions(+) create mode 100644 tests/net/icmp/CMakeLists.txt create mode 100644 tests/net/icmp/prj.conf create mode 100644 tests/net/icmp/src/main.c create mode 100644 tests/net/icmp/testcase.yaml diff --git a/tests/net/icmp/CMakeLists.txt b/tests/net/icmp/CMakeLists.txt new file mode 100644 index 00000000000..a05c45522aa --- /dev/null +++ b/tests/net/icmp/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(icmp) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/icmp/prj.conf b/tests/net/icmp/prj.conf new file mode 100644 index 00000000000..4116a90fdf1 --- /dev/null +++ b/tests/net/icmp/prj.conf @@ -0,0 +1,21 @@ +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_NET_IPV6=y +CONFIG_NET_IPV4=y +CONFIG_NET_BUF=y +CONFIG_ZTEST_STACK_SIZE=1024 +CONFIG_NET_PKT_RX_COUNT=2 +CONFIG_NET_PKT_TX_COUNT=5 +CONFIG_NET_BUF_RX_COUNT=5 +CONFIG_NET_BUF_TX_COUNT=10 +CONFIG_NET_LOG=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_MAIN_STACK_SIZE=1280 +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_ND=n +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n diff --git a/tests/net/icmp/src/main.c b/tests/net/icmp/src/main.c new file mode 100644 index 00000000000..8ac4f5ee2f1 --- /dev/null +++ b/tests/net/icmp/src/main.c @@ -0,0 +1,296 @@ +/* main.c - Application main entry point */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Use highest log level if both IPv4 and IPv6 are defined */ +#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV6) + +#if CONFIG_NET_ICMPV4_LOG_LEVEL > CONFIG_NET_ICMPV6_LOG_LEVEL +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV4_LOG_LEVEL +#else +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV6_LOG_LEVEL +#endif + +#elif defined(CONFIG_NET_IPV4) +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV4_LOG_LEVEL +#elif defined(CONFIG_NET_IPV6) +#define ICMP_LOG_LEVEL CONFIG_NET_ICMPV6_LOG_LEVEL +#else +#define ICMP_LOG_LEVEL LOG_LEVEL_INF +#endif + +#include +LOG_MODULE_REGISTER(net_test, ICMP_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "net_private.h" +#include "icmpv4.h" +#include "icmpv6.h" +#include "ipv4.h" +#include "ipv6.h" + +#define PKT_WAIT_TIME K_SECONDS(1) +#define SEM_WAIT_TIME K_SECONDS(1) +#define TEST_DATA "dummy test data" + +static struct in6_addr send_addr_6 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x1 } } }; +static struct in6_addr recv_addr_6 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x2 } } }; +static struct in_addr send_addr_4 = { { { 192, 0, 2, 1 } } }; +static struct in_addr recv_addr_4 = { { { 192, 0, 2, 2 } } }; + +static struct net_if *sender, *receiver; + +static struct test_icmp_context { + uint8_t mac[sizeof(struct net_eth_addr)]; + struct net_if *iface; + uint8_t test_data[sizeof(TEST_DATA)]; + struct k_sem tx_sem; + bool req_received; +} send_ctx, recv_ctx; + +static void test_iface_init(struct net_if *iface) +{ + struct test_icmp_context *ctx = net_if_get_device(iface)->data; + static int counter; + + /* Generate and assign MAC. */ + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + ctx->mac[0] = 0x00; + ctx->mac[1] = 0x00; + ctx->mac[2] = 0x5E; + ctx->mac[3] = 0x00; + ctx->mac[4] = 0x53; + ctx->mac[5] = ++counter; + + net_if_set_link_addr(iface, ctx->mac, sizeof(ctx->mac), NET_LINK_ETHERNET); + + ctx->iface = iface; +} + +static int test_sender(const struct device *dev, struct net_pkt *pkt) +{ + struct net_pkt *send_pkt; + + send_pkt = net_pkt_clone(pkt, PKT_WAIT_TIME); + + net_pkt_set_iface(send_pkt, recv_ctx.iface); + + (void)net_recv_data(recv_ctx.iface, send_pkt); + + net_pkt_unref(pkt); + + return 0; +} + +static int test_receiver(const struct device *dev, struct net_pkt *pkt) +{ + struct net_pkt *send_pkt; + + send_pkt = net_pkt_clone(pkt, PKT_WAIT_TIME); + + net_pkt_set_iface(send_pkt, send_ctx.iface); + + (void)net_recv_data(send_ctx.iface, send_pkt); + + net_pkt_unref(pkt); + + return 0; +} + +static struct dummy_api send_if_api = { + .iface_api.init = test_iface_init, + .send = test_sender, +}; + +static struct dummy_api recv_if_api = { + .iface_api.init = test_iface_init, + .send = test_receiver, +}; + +NET_DEVICE_INIT(test_sender_icmp, "test_sender_icmp", NULL, NULL, &send_ctx, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &send_if_api, + DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), NET_IPV6_MTU); + +NET_DEVICE_INIT(test_receiver_icmp, "test_receiver_icmp", NULL, NULL, &recv_ctx, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &recv_if_api, + DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), NET_IPV6_MTU); + +static int icmp_handler(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + struct test_icmp_context *test = user_data; + + if (hdr->family == AF_INET) { + struct net_ipv4_hdr *ip_hdr = hdr->ipv4; + + NET_DBG("Received Echo reply from %s to %s", + net_sprint_ipv4_addr(&ip_hdr->src), + net_sprint_ipv4_addr(&ip_hdr->dst)); + + } else if (hdr->family == AF_INET6) { + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; + + NET_DBG("Received Echo Reply from %s to %s", + net_sprint_ipv6_addr(&ip_hdr->src), + net_sprint_ipv6_addr(&ip_hdr->dst)); + } else { + return -ENOENT; + } + + test->req_received = true; + k_sem_give(&test->tx_sem); + + net_pkt_unref(pkt); + + return 0; +} + +ZTEST(icmp_tests, test_icmpv6_echo_request) +{ + struct sockaddr_in6 dst6 = { 0 }; + struct net_icmp_ping_params params; + struct net_icmp_ctx ctx; + int ret; + + if (!IS_ENABLED(CONFIG_NET_IPV6)) { + return; + } + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_ECHO_REPLY, 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + dst6.sin6_family = AF_INET6; + +#if defined(CONFIG_NET_IPV6) + memcpy(&dst6.sin6_addr, &recv_addr_6, sizeof(recv_addr_6)); +#endif + + params.identifier = 1234; + params.sequence = 5678; + params.tc_tos = 1; + params.priority = 2; + params.data = send_ctx.test_data; + params.data_size = sizeof(send_ctx.test_data); + + ret = net_icmp_send_echo_request(&ctx, sender, + (struct sockaddr *)&dst6, + ¶ms, + &send_ctx); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + k_sem_take(&send_ctx.tx_sem, SEM_WAIT_TIME); + + zassert_true(send_ctx.req_received, "Did not receive Echo-Request"); + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); + + send_ctx.req_received = false; +} + +ZTEST(icmp_tests, test_icmpv4_echo_request) +{ + struct sockaddr_in dst4 = { 0 }; + struct net_icmp_ping_params params; + struct net_icmp_ctx ctx; + int ret; + + if (!IS_ENABLED(CONFIG_NET_IPV4)) { + return; + } + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV4_ECHO_REPLY, 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + dst4.sin_family = AF_INET; + +#if defined(CONFIG_NET_IPV4) + memcpy(&dst4.sin_addr, &recv_addr_4, sizeof(recv_addr_4)); +#endif + + params.identifier = 1234; + params.sequence = 5678; + params.tc_tos = 1; + params.priority = 2; + params.data = send_ctx.test_data; + params.data_size = sizeof(send_ctx.test_data); + + ret = net_icmp_send_echo_request(&ctx, sender, + (struct sockaddr *)&dst4, + ¶ms, + &send_ctx); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + k_sem_take(&send_ctx.tx_sem, SEM_WAIT_TIME); + + zassert_true(send_ctx.req_received, "Did not receive Echo-Request"); + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); + + send_ctx.req_received = false; +} + +static void *setup(void) +{ + if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) { + k_thread_priority_set(k_current_get(), + K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1)); + } else { + k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9)); + } + +#if defined(CONFIG_NET_IPV6) + (void)net_if_ipv6_addr_add(send_ctx.iface, &send_addr_6, NET_ADDR_MANUAL, 0); + (void)net_if_ipv6_addr_add(recv_ctx.iface, &recv_addr_6, NET_ADDR_MANUAL, 0); +#else + ARG_UNUSED(send_addr_6); + ARG_UNUSED(recv_addr_6); +#endif + +#if defined(CONFIG_NET_IPV4) + (void)net_if_ipv4_addr_add(send_ctx.iface, &send_addr_4, NET_ADDR_MANUAL, 0); + (void)net_if_ipv4_addr_add(recv_ctx.iface, &recv_addr_4, NET_ADDR_MANUAL, 0); +#else + ARG_UNUSED(send_addr_4); + ARG_UNUSED(recv_addr_4); +#endif + + memcpy(send_ctx.test_data, &(TEST_DATA), sizeof(TEST_DATA)); + memcpy(recv_ctx.test_data, &(TEST_DATA), sizeof(TEST_DATA)); + + k_sem_init(&send_ctx.tx_sem, 0, 1); + k_sem_init(&recv_ctx.tx_sem, 0, 1); + + sender = net_if_lookup_by_dev(DEVICE_GET(test_sender_icmp)); + zassert_equal(sender, send_ctx.iface, "Invalid interface (%p vs %p)", + sender, send_ctx.iface); + + receiver = net_if_lookup_by_dev(DEVICE_GET(test_receiver_icmp)); + zassert_equal(receiver, recv_ctx.iface, "Invalid interface (%p vs %p)", + receiver, recv_ctx.iface); + + return NULL; +} + +ZTEST_SUITE(icmp_tests, NULL, setup, NULL, NULL, NULL); diff --git a/tests/net/icmp/testcase.yaml b/tests/net/icmp/testcase.yaml new file mode 100644 index 00000000000..cfe3f1ffac9 --- /dev/null +++ b/tests/net/icmp/testcase.yaml @@ -0,0 +1,22 @@ +common: + depends_on: netif + tags: net icmp +tests: + net.icmp.coop: + extra_configs: + - CONFIG_NET_TC_THREAD_COOPERATIVE=y + - CONFIG_NET_IF_MAX_IPV6_COUNT=2 + - CONFIG_NET_IF_MAX_IPV4_COUNT=2 + net.icmp.preempt: + extra_configs: + - CONFIG_NET_TC_THREAD_PREEMPTIVE=y + - CONFIG_NET_IF_MAX_IPV6_COUNT=2 + - CONFIG_NET_IF_MAX_IPV4_COUNT=2 + net.icmp.no_ipv4: + extra_configs: + - CONFIG_NET_IPV4=n + - CONFIG_NET_IF_MAX_IPV6_COUNT=2 + net.icmp.no_ipv6: + extra_configs: + - CONFIG_NET_IPV6=n + - CONFIG_NET_IF_MAX_IPV4_COUNT=2 From 44151d5ccd3941c2a72642787d8c2c329a154b5b Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 22 Sep 2023 17:39:22 +0300 Subject: [PATCH 1234/4498] tests: net: icmp: Add offloaded ICMP API tests Add some tests that verify that offloaded ICMP API works as expected. Signed-off-by: Jukka Rissanen --- tests/net/icmp/src/main.c | 393 +++++++++++++++++++++++++++++++++++ tests/net/icmp/testcase.yaml | 10 + 2 files changed, 403 insertions(+) diff --git a/tests/net/icmp/src/main.c b/tests/net/icmp/src/main.c index 8ac4f5ee2f1..c2f97f93aa5 100644 --- a/tests/net/icmp/src/main.c +++ b/tests/net/icmp/src/main.c @@ -37,6 +37,9 @@ LOG_MODULE_REGISTER(net_test, ICMP_LOG_LEVEL); #include #include #include +#include +#include +#include #include "net_private.h" #include "icmpv4.h" @@ -65,6 +68,18 @@ static struct test_icmp_context { bool req_received; } send_ctx, recv_ctx; +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) +static struct test_icmp_context offload_ctx; +static struct net_if *offload_sender; + +static struct in6_addr offload_send_addr_6 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x3 } } }; +static struct in6_addr offload_recv_addr_6 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x4 } } }; +static struct in_addr offload_send_addr_4 = { { { 192, 0, 2, 3 } } }; +static struct in_addr offload_recv_addr_4 = { { { 192, 0, 2, 4 } } }; +#endif + static void test_iface_init(struct net_if *iface) { struct test_icmp_context *ctx = net_if_get_device(iface)->data; @@ -132,6 +147,280 @@ NET_DEVICE_INIT(test_receiver_icmp, "test_receiver_icmp", NULL, NULL, &recv_ctx, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &recv_if_api, DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), NET_IPV6_MTU); +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) +static int offload_dummy_get(sa_family_t family, + enum net_sock_type type, + enum net_ip_protocol ip_proto, + struct net_context **context) +{ + return -1; +} + +/* Placeholders, until Zephyr IP stack updated to handle a NULL net_offload */ +static struct net_offload offload_dummy = { + .get = offload_dummy_get, + .bind = NULL, + .listen = NULL, + .connect = NULL, + .accept = NULL, + .send = NULL, + .sendto = NULL, + .recv = NULL, + .put = NULL, +}; + +static struct net_icmp_offload offload_data; + +#if defined(CONFIG_NET_IPV4) +static int get_ipv4_reply(struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + struct net_pkt **reply_pkt, + struct net_ipv4_hdr **hdr_ipv4, + struct net_icmp_hdr **hdr_icmp) +{ + struct net_ipv4_hdr *ipv4_hdr = NULL; + struct net_icmp_hdr *icmp_hdr; + const struct in_addr *dest4; + struct net_pkt *reply; + struct in_addr *src4; + int ret; + + /* The code below should not be used in real life scenarios + * as it is missing filling the ICMP params etc. We just create + * a basic IPv4 header here in order to pass sanity checks + * in IP packet parsing. + */ + reply = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv4_hdr) + + sizeof(struct net_icmp_hdr) + + params->data_size, + AF_INET, IPPROTO_ICMP, + PKT_WAIT_TIME); + if (!reply) { + NET_DBG("No buffer"); + return -ENOMEM; + } + + dest4 = &offload_send_addr_4; + src4 = &net_sin(dst)->sin_addr; + + ipv4_hdr = net_pkt_cursor_get_pos(reply); + *hdr_ipv4 = ipv4_hdr; + + ret = net_ipv4_create_full(reply, src4, dest4, params->tc_tos, + params->identifier, 0, 0, 1); + if (ret < 0) { + LOG_ERR("Cannot create IPv4 pkt (%d)", ret); + return ret; + } + + icmp_hdr = net_pkt_cursor_get_pos(reply); + *hdr_icmp = icmp_hdr; + + ret = net_icmpv4_create(reply, NET_ICMPV4_ECHO_REPLY, 0); + if (ret < 0) { + LOG_ERR("Cannot create ICMPv4 pkt (%d)", ret); + return ret; + } + + ret = net_pkt_write(reply, params->data, params->data_size); + if (ret < 0) { + LOG_ERR("Cannot write payload (%d)", ret); + return ret; + } + + net_pkt_cursor_init(reply); + net_ipv4_finalize(reply, IPPROTO_ICMP); + + *reply_pkt = reply; + + return 0; +} +#else +static int get_ipv4_reply(struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + struct net_pkt **reply_pkt, + struct net_ipv4_hdr **hdr_ipv4, + struct net_icmp_hdr **hdr_icmp) +{ + return -ENOTSUP; +} +#endif + +#if defined(CONFIG_NET_IPV6) +static int get_ipv6_reply(struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + struct net_pkt **reply_pkt, + struct net_ipv6_hdr **hdr_ipv6, + struct net_icmp_hdr **hdr_icmp) +{ + struct net_ipv6_hdr *ipv6_hdr = NULL; + struct net_icmp_hdr *icmp_hdr; + const struct in6_addr *dest6; + struct net_pkt *reply; + struct in6_addr *src6; + int ret; + + reply = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv6_hdr) + + sizeof(struct net_icmp_hdr) + + params->data_size, + AF_INET6, IPPROTO_ICMP, + PKT_WAIT_TIME); + if (!reply) { + NET_DBG("No buffer"); + return -ENOMEM; + } + + dest6 = &offload_send_addr_6; + src6 = &net_sin6(dst)->sin6_addr; + + ipv6_hdr = net_pkt_cursor_get_pos(reply); + *hdr_ipv6 = ipv6_hdr; + + ret = net_ipv6_create(reply, src6, dest6); + if (ret < 0) { + LOG_ERR("Cannot create IPv6 pkt (%d)", ret); + return ret; + } + + icmp_hdr = net_pkt_cursor_get_pos(reply); + *hdr_icmp = icmp_hdr; + + ret = net_icmpv6_create(reply, NET_ICMPV6_ECHO_REPLY, 0); + if (ret < 0) { + LOG_ERR("Cannot create ICMPv6 pkt (%d)", ret); + return ret; + } + + ret = net_pkt_write(reply, params->data, params->data_size); + if (ret < 0) { + LOG_ERR("Cannot write payload (%d)", ret); + return ret; + } + + net_pkt_cursor_init(reply); + net_ipv6_finalize(reply, IPPROTO_ICMP); + + *reply_pkt = reply; + + return 0; +} +#else +static int get_ipv6_reply(struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + struct net_pkt **reply_pkt, + struct net_ipv6_hdr **hdr_ipv6, + struct net_icmp_hdr **hdr_icmp) +{ + return -ENOTSUP; +} +#endif + +static int offload_ping_handler(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + void *user_data) +{ + struct net_icmp_offload *icmp_offload_ctx = &offload_data; + struct net_icmp_hdr *icmp_hdr = NULL; + struct net_pkt *reply = NULL; + struct net_icmp_ip_hdr ip_hdr; + struct net_ipv4_hdr *ipv4_hdr; + struct net_ipv6_hdr *ipv6_hdr; + net_icmp_handler_t resp_handler; + int ret; + + ret = net_icmp_get_offload_rsp_handler(icmp_offload_ctx, &resp_handler); + if (ret < 0) { + LOG_ERR("Cannot get offload response handler."); + return -ENOENT; + } + + /* So in real life scenario, we should here send a Echo-Request via + * some offloaded way to peer. When the response is received, we + * should then return that information to the ping caller by + * calling the response handler function. + * Here we just simulate a reply as there is no need to actually + * send anything anywhere. + */ + if (IS_ENABLED(CONFIG_NET_IPV4) && dst->sa_family == AF_INET) { + ret = get_ipv4_reply(iface, dst, params, &reply, + &ipv4_hdr, &icmp_hdr); + if (ret < 0) { + LOG_ERR("Cannot create reply pkt (%d)", ret); + return ret; + } + + ip_hdr.family = AF_INET; + ip_hdr.ipv4 = ipv4_hdr; + } + + if (IS_ENABLED(CONFIG_NET_IPV6) && dst->sa_family == AF_INET6) { + ret = get_ipv6_reply(iface, dst, params, &reply, + &ipv6_hdr, &icmp_hdr); + if (ret < 0) { + LOG_ERR("Cannot create reply pkt (%d)", ret); + return ret; + } + + ip_hdr.family = AF_INET6; + ip_hdr.ipv6 = ipv6_hdr; + } + + ret = resp_handler(ctx, reply, &ip_hdr, icmp_hdr, user_data); + if (ret < 0) { + LOG_ERR("Cannot send response (%d)", ret); + } + + return ret; +} + +static void offload_iface_init(struct net_if *iface) +{ + struct test_icmp_context *ctx = net_if_get_device(iface)->data; + int ret; + + /* Generate and assign MAC. */ + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + ctx->mac[0] = 0x00; + ctx->mac[1] = 0x00; + ctx->mac[2] = 0x5E; + ctx->mac[3] = 0x00; + ctx->mac[4] = 0x53; + ctx->mac[5] = 0xF0; + + net_if_set_link_addr(iface, ctx->mac, sizeof(ctx->mac), NET_LINK_ETHERNET); + + /* A dummy placeholder to allow network stack to pass offloaded data to our interface */ + iface->if_dev->offload = &offload_dummy; + + /* This will cause ping requests to be re-directed to our offload handler */ + ret = net_icmp_register_offload_ping(&offload_data, iface, offload_ping_handler); + if (ret < 0) { + LOG_ERR("Cannot register offload ping handler (%d)", ret); + } + + ctx->iface = iface; +} + +static enum offloaded_net_if_types offload_get_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + +static const struct net_wifi_mgmt_offload offload_api = { + .wifi_iface.iface_api.init = offload_iface_init, + .wifi_iface.get_type = offload_get_type, +}; + +NET_DEVICE_OFFLOAD_INIT(test_offload, "test_offload", NULL, NULL, &offload_ctx, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &offload_api, 1500); +#endif /* CONFIG_NET_OFFLOADING_SUPPORT */ + static int icmp_handler(struct net_icmp_ctx *ctx, struct net_pkt *pkt, struct net_icmp_ip_hdr *hdr, @@ -251,6 +540,86 @@ ZTEST(icmp_tests, test_icmpv4_echo_request) send_ctx.req_received = false; } +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) +#if defined(CONFIG_NET_IPV4) +ZTEST(icmp_tests, test_offload_icmpv4_echo_request) +{ + struct sockaddr_in dst4 = { 0 }; + struct net_icmp_ping_params params; + struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV4_ECHO_REPLY, 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + dst4.sin_family = AF_INET; + + memcpy(&dst4.sin_addr, &offload_recv_addr_4, sizeof(offload_recv_addr_4)); + + params.identifier = 1234; + params.sequence = 5678; + params.tc_tos = 1; + params.priority = 2; + params.data = offload_ctx.test_data; + params.data_size = sizeof(offload_ctx.test_data); + + ret = net_icmp_send_echo_request(&ctx, offload_sender, + (struct sockaddr *)&dst4, + ¶ms, + &offload_ctx); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + k_sem_take(&offload_ctx.tx_sem, SEM_WAIT_TIME); + + zassert_true(offload_ctx.req_received, "Did not receive Echo-Request"); + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); + + offload_ctx.req_received = false; +} +#endif + +#if defined(CONFIG_NET_IPV6) +ZTEST(icmp_tests, test_offload_icmpv6_echo_request) +{ + struct sockaddr_in6 dst6 = { 0 }; + struct net_icmp_ping_params params; + struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_ECHO_REPLY, 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + dst6.sin6_family = AF_INET6; + + memcpy(&dst6.sin6_addr, &offload_recv_addr_6, sizeof(offload_recv_addr_6)); + + params.identifier = 1234; + params.sequence = 5678; + params.tc_tos = 1; + params.priority = 2; + params.data = offload_ctx.test_data; + params.data_size = sizeof(offload_ctx.test_data); + + ret = net_icmp_send_echo_request(&ctx, offload_sender, + (struct sockaddr *)&dst6, + ¶ms, + &offload_ctx); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + k_sem_take(&offload_ctx.tx_sem, SEM_WAIT_TIME); + + zassert_true(offload_ctx.req_received, "Did not receive Echo-Request"); + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); + + offload_ctx.req_received = false; +} +#endif +#endif /* CONFIG_NET_OFFLOADING_SUPPORT */ + static void *setup(void) { if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) { @@ -290,6 +659,30 @@ static void *setup(void) zassert_equal(receiver, recv_ctx.iface, "Invalid interface (%p vs %p)", receiver, recv_ctx.iface); +#if defined(CONFIG_NET_OFFLOADING_SUPPORT) + +#if defined(CONFIG_NET_IPV6) + (void)net_if_ipv6_addr_add(offload_ctx.iface, &offload_send_addr_6, NET_ADDR_MANUAL, 0); +#else + ARG_UNUSED(offload_send_addr_6); + ARG_UNUSED(offload_recv_addr_6); +#endif + +#if defined(CONFIG_NET_IPV4) + (void)net_if_ipv4_addr_add(offload_ctx.iface, &offload_send_addr_4, NET_ADDR_MANUAL, 0); +#else + ARG_UNUSED(offload_send_addr_4); + ARG_UNUSED(offload_recv_addr_4); +#endif + + memcpy(offload_ctx.test_data, &(TEST_DATA), sizeof(TEST_DATA)); + k_sem_init(&offload_ctx.tx_sem, 0, 1); + + offload_sender = net_if_lookup_by_dev(DEVICE_GET(test_offload)); + zassert_equal(offload_sender, offload_ctx.iface, "Invalid interface (%p vs %p)", + offload_sender, offload_ctx.iface); +#endif + return NULL; } diff --git a/tests/net/icmp/testcase.yaml b/tests/net/icmp/testcase.yaml index cfe3f1ffac9..f0e23579911 100644 --- a/tests/net/icmp/testcase.yaml +++ b/tests/net/icmp/testcase.yaml @@ -2,6 +2,16 @@ common: depends_on: netif tags: net icmp tests: + net.icmp.offloaded: + extra_configs: + - CONFIG_NET_OFFLOAD=y + - CONFIG_NET_IF_MAX_IPV6_COUNT=2 + - CONFIG_NET_IF_MAX_IPV4_COUNT=2 + net.icmp.socket_offloaded: + extra_configs: + - CONFIG_NET_SOCKETS_OFFLOAD=y + - CONFIG_NET_IF_MAX_IPV6_COUNT=2 + - CONFIG_NET_IF_MAX_IPV4_COUNT=2 net.icmp.coop: extra_configs: - CONFIG_NET_TC_THREAD_COOPERATIVE=y From fe5638cf0f0cb14c3238c240ac93823a3aed3a6c Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 25 Sep 2023 16:36:21 +0300 Subject: [PATCH 1235/4498] tests: net: icmpv4: Convert to use new ICMP API Converting the ICMPv4 tests to use the new ICMP API so that the tests pass. Signed-off-by: Jukka Rissanen --- tests/net/icmpv4/src/main.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/net/icmpv4/src/main.c b/tests/net/icmpv4/src/main.c index b063b752462..7915e3fbfa7 100644 --- a/tests/net/icmpv4/src/main.c +++ b/tests/net/icmpv4/src/main.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2019 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +22,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_ICMPV4_LOG_LEVEL); #include #include #include +#include #include "net_private.h" #include "icmpv4.h" @@ -114,24 +116,25 @@ static uint8_t current = TEST_ICMPV4_UNKNOWN; static struct in_addr my_addr = { { { 192, 0, 2, 1 } } }; static struct net_if *net_iface; -static enum net_verdict handle_reply_msg(struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_reply_msg(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { + ARG_UNUSED(ctx); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + if (net_pkt_get_len(pkt) != sizeof(icmpv4_echo_rep)) { - return NET_DROP; + return -ENOMSG; } net_pkt_unref(pkt); - return NET_OK; + return 0; } -static struct net_icmpv4_handler echo_rep_handler = { - .type = NET_ICMPV4_ECHO_REPLY, - .code = 0, - .handler = handle_reply_msg, -}; - struct net_icmpv4_context { uint8_t mac_addr[sizeof(struct net_eth_addr)]; struct net_linkaddr ll_addr; @@ -458,9 +461,14 @@ static void icmpv4_send_echo_req(void) static void icmpv4_send_echo_rep(void) { + static struct net_icmp_ctx ctx; struct net_pkt *pkt; + int ret; - net_icmpv4_register_handler(&echo_rep_handler); + ret = net_icmp_init_ctx(&ctx, NET_ICMPV4_ECHO_REPLY, + 0, handle_reply_msg); + zassert_equal(ret, 0, "Cannot register %s handler (%d)", + STRINGIFY(NET_ICMPV4_ECHO_REPLY), ret); pkt = prepare_echo_reply(net_iface); if (!pkt) { @@ -471,7 +479,9 @@ static void icmpv4_send_echo_rep(void) net_pkt_unref(pkt); zassert_true(false, "Failed to send"); } - net_icmpv4_unregister_handler(&echo_rep_handler); + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot unregister handler (%d)", ret); } ZTEST(net_icmpv4, test_icmpv4_send_echo_req_opt) From 8f74148bdd2f4e0d0eec6176bc678ef33da9eff3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 25 Sep 2023 18:18:11 +0300 Subject: [PATCH 1236/4498] tests: net: icmpv6: Convert to use new ICMP API Converting the ICMPv6 tests to use the new ICMP API so that the tests pass. Signed-off-by: Jukka Rissanen --- tests/net/icmpv6/prj.conf | 7 +- tests/net/icmpv6/src/main.c | 195 +++++++++++++++++++++++++----------- 2 files changed, 144 insertions(+), 58 deletions(-) diff --git a/tests/net/icmpv6/prj.conf b/tests/net/icmpv6/prj.conf index a803a29637d..dbd3d93f626 100644 --- a/tests/net/icmpv6/prj.conf +++ b/tests/net/icmpv6/prj.conf @@ -1,7 +1,7 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_NET_IPV6=y -CONFIG_NET_IPV4=y +CONFIG_NET_IPV4=n CONFIG_NET_BUF=y CONFIG_ZTEST_STACK_SIZE=1024 CONFIG_NET_PKT_RX_COUNT=2 @@ -15,3 +15,8 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_NET_L2_ETHERNET=n +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_ND=n +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n diff --git a/tests/net/icmpv6/src/main.c b/tests/net/icmpv6/src/main.c index 5546e0ff724..8594f628fc2 100644 --- a/tests/net/icmpv6/src/main.c +++ b/tests/net/icmpv6/src/main.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,10 +20,16 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_ICMPV6_LOG_LEVEL); #include #include +#include +#include +#include +#include "ipv6.h" +#include "net_private.h" #include "icmpv6.h" #include +static struct net_if *test_iface; static int handler_called; static int handler_status; @@ -30,7 +37,7 @@ static int handler_status; #define ICMPV6_MSG_SIZE 104 -static char icmpv6_echo_req[] = +static uint8_t icmpv6_echo_req[] = "\x60\x02\xea\x12\x00\x40\x3a\x40\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xda\xcb\x8a\xff\xfe\x34\xc8\xf3\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xec\x88\x2d\x63\xfd\x67\x31\x66\x80\x00\xa4\x24\x0b\x95\x00\x01" \ @@ -39,7 +46,7 @@ static char icmpv6_echo_req[] = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ "\x30\x31\x32\x33\x34\x35\x36\x37"; -static char icmpv6_echo_rep[] = +static uint8_t icmpv6_echo_rep[] = "\x60\x09\x23\xa0\x00\x40\x3a\x40\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xec\x88\x2d\x63\xfd\x67\x31\x66\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xda\xcb\x8a\xff\xfe\x34\xc8\xf3\x81\x00\xa3\x24\x0b\x95\x00\x01" \ @@ -48,7 +55,7 @@ static char icmpv6_echo_rep[] = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ "\x30\x31\x32\x33\x34\x35\x36\x37"; -static char icmpv6_inval_chksum[] = +static uint8_t icmpv6_inval_chksum[] = "\x60\x09\x23\xa0\x00\x40\x3a\x40\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xec\x88\x2d\x63\xfd\x67\x31\x66\xfe\x80\x00\x00\x00\x00\x00\x00" \ "\xda\xcb\x8a\xff\xfe\x34\xc8\xf3\x00\x00\xa3\x24\x0b\x95\x00\x01" \ @@ -57,19 +64,84 @@ static char icmpv6_inval_chksum[] = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ "\x30\x31\x32\x33\x34\x35\x36\x37"; -static enum net_verdict handle_test_msg(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +struct net_icmpv6_context { + uint8_t mac_addr[sizeof(struct net_eth_addr)]; + struct net_linkaddr ll_addr; +}; + +static struct net_icmpv6_context net_icmpv6_context_data; + +static int net_icmpv6_dev_init(const struct device *dev) +{ + struct net_icmpv6_context *net_icmpv6_context = dev->data; + + net_icmpv6_context = net_icmpv6_context; + + return 0; +} + +static uint8_t *net_icmpv6_get_mac(const struct device *dev) +{ + struct net_icmpv6_context *context = dev->data; + + if (context->mac_addr[2] == 0x00) { + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + context->mac_addr[0] = 0x00; + context->mac_addr[1] = 0x00; + context->mac_addr[2] = 0x5E; + context->mac_addr[3] = 0x00; + context->mac_addr[4] = 0x53; + context->mac_addr[5] = 0x01; + } + + return context->mac_addr; +} + +static void net_icmpv6_iface_init(struct net_if *iface) +{ + uint8_t *mac = net_icmpv6_get_mac(net_if_get_device(iface)); + + net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET); +} + +static int tester_send(const struct device *dev, struct net_pkt *pkt) +{ + net_pkt_unref(pkt); + return 0; +} + +static struct dummy_api net_icmpv6_if_api = { + .iface_api.init = net_icmpv6_iface_init, + .send = tester_send, +}; + +NET_DEVICE_INIT(net_icmpv6_test, "net_icmpv6_test", + net_icmpv6_dev_init, NULL, + &net_icmpv6_context_data, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &net_icmpv6_if_api, DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), 127); + +static int handle_test_msg(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { + ARG_UNUSED(ctx); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + struct net_buf *last = net_buf_frag_last(pkt->buffer); - enum net_verdict ret; + int ret; if (last->len != ICMPV6_MSG_SIZE) { handler_status = -EINVAL; - ret = NET_DROP; + ret = -EINVAL; } else { handler_status = 0; - ret = NET_OK; + ret = 0; } handler_called++; @@ -77,47 +149,52 @@ static enum net_verdict handle_test_msg(struct net_pkt *pkt, return ret; } -static struct net_icmpv6_handler test_handler1 = { - .type = NET_ICMPV6_ECHO_REPLY, - .code = 0, - .handler = handle_test_msg, -}; - -static struct net_icmpv6_handler test_handler2 = { - .type = NET_ICMPV6_ECHO_REQUEST, - .code = 0, - .handler = handle_test_msg, -}; - -ZTEST(icmpv6_fn, test_icmpv6) +static struct net_pkt *create_pkt(uint8_t *data, int len, + struct net_ipv6_hdr **hdr) { - if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) { - k_thread_priority_set(k_current_get(), - K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1)); - } else { - k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9)); - } - - struct net_ipv6_hdr *hdr; struct net_pkt *pkt; - int ret; - - net_icmpv6_register_handler(&test_handler1); - net_icmpv6_register_handler(&test_handler2); pkt = net_pkt_alloc_with_buffer(NULL, ICMPV6_MSG_SIZE, AF_UNSPEC, 0, K_SECONDS(1)); zassert_not_null(pkt, "Allocation failed"); + net_pkt_set_iface(pkt, test_iface); + net_pkt_set_family(pkt, AF_INET6); net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr)); - net_pkt_write(pkt, icmpv6_inval_chksum, ICMPV6_MSG_SIZE); + net_pkt_write(pkt, data, len); - hdr = (struct net_ipv6_hdr *)pkt->buffer->data; net_pkt_cursor_init(pkt); + *hdr = net_pkt_cursor_get_pos(pkt); net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr)); + /* The cursor should be at the start of the ICMPv6 header */ + + return pkt; +} + +ZTEST(icmpv6_fn, test_icmpv6) +{ + struct net_icmp_ctx ctx1; + struct net_icmp_ctx ctx2; + struct net_ipv6_hdr *hdr; + struct net_pkt *pkt; + int ret; + + ret = net_icmp_init_ctx(&ctx1, NET_ICMPV6_ECHO_REPLY, + 0, handle_test_msg); + zassert_equal(ret, 0, "Cannot register %s handler (%d)", + STRINGIFY(NET_ICMPV6_ECHO_REPLY), ret); + + ret = net_icmp_init_ctx(&ctx2, NET_ICMPV6_ECHO_REQUEST, + 0, handle_test_msg); + zassert_equal(ret, 0, "Cannot register %s handler (%d)", + STRINGIFY(NET_ICMPV6_ECHO_REQUEST), ret); + + pkt = create_pkt(icmpv6_inval_chksum, ICMPV6_MSG_SIZE, &hdr); + zassert_not_null(pkt, "Cannot create pkt"); + ret = net_icmpv6_input(pkt, hdr); /**TESTPOINT: Check input*/ @@ -125,16 +202,8 @@ ZTEST(icmpv6_fn, test_icmpv6) handler_status = -1; - net_pkt_cursor_init(pkt); - net_pkt_set_overwrite(pkt, false); - pkt->buffer->len = 0; - - net_pkt_write(pkt, icmpv6_echo_rep, ICMPV6_MSG_SIZE); - - hdr = (struct net_ipv6_hdr *)pkt->buffer->data; - net_pkt_cursor_init(pkt); - net_pkt_set_overwrite(pkt, true); - net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr)); + pkt = create_pkt(icmpv6_echo_rep, ICMPV6_MSG_SIZE, &hdr); + zassert_not_null(pkt, "Cannot create pkt"); ret = net_icmpv6_input(pkt, hdr); @@ -144,16 +213,8 @@ ZTEST(icmpv6_fn, test_icmpv6) handler_status = -1; - net_pkt_cursor_init(pkt); - net_pkt_set_overwrite(pkt, false); - pkt->buffer->len = 0; - - net_pkt_write(pkt, icmpv6_echo_req, ICMPV6_MSG_SIZE); - - hdr = (struct net_ipv6_hdr *)pkt->buffer->data; - net_pkt_cursor_init(pkt); - net_pkt_set_overwrite(pkt, true); - net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr)); + pkt = create_pkt(icmpv6_echo_req, ICMPV6_MSG_SIZE, &hdr); + zassert_not_null(pkt, "Cannot create pkt"); ret = net_icmpv6_input(pkt, hdr); @@ -163,7 +224,27 @@ ZTEST(icmpv6_fn, test_icmpv6) /**TESTPOINT: Check input*/ zassert_true(!(handler_called != 2), "Callbacks not called properly"); + + ret = net_icmp_cleanup_ctx(&ctx1); + zassert_equal(ret, 0, "Cannot unregister handler (%d)", ret); + + ret = net_icmp_cleanup_ctx(&ctx2); + zassert_equal(ret, 0, "Cannot unregister handler (%d)", ret); +} + +static void *setup(void) +{ + if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) { + k_thread_priority_set(k_current_get(), + K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1)); + } else { + k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9)); + } + + test_iface = net_if_lookup_by_dev(DEVICE_GET(net_icmpv6_test)); + + return NULL; } /**test case main entry*/ -ZTEST_SUITE(icmpv6_fn, NULL, NULL, NULL, NULL, NULL); +ZTEST_SUITE(icmpv6_fn, NULL, setup, NULL, NULL, NULL); From fa4e978fbafe16e94fbb8ab1c1062266a1de74e9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 26 Sep 2023 13:38:29 +0300 Subject: [PATCH 1237/4498] net: zperf: Fix the IPv6 ping done in shell The zperf shell sends a IPv6 ping at the start when working with IPv6. Convert the sending of the ping to use the new API. Signed-off-by: Jukka Rissanen --- subsys/net/lib/zperf/zperf_shell.c | 56 +++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 3a8a9c61c4b..3f900fa6e8a 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -501,6 +501,57 @@ static void tcp_upload_cb(enum zperf_status status, } } +static int ping_handler(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *ip_hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + struct k_sem *sem_wait = user_data; + + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(ip_hdr); + ARG_UNUSED(icmp_hdr); + + k_sem_give(sem_wait); + + return 0; +} + +static void send_ping(const struct shell *sh, + struct in6_addr *addr, + int timeout_ms) +{ + static struct k_sem sem_wait; + struct sockaddr_in6 dest_addr = { 0 }; + struct net_icmp_ctx ctx; + int ret; + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_ECHO_REPLY, 0, ping_handler); + if (ret < 0) { + shell_fprintf(sh, SHELL_WARNING, "Cannot send ping (%d)\n", ret); + return; + } + + memcpy(&dest_addr.sin6_addr, addr, sizeof(struct in6_addr)); + + k_sem_init(&sem_wait, 0, 1); + + (void)net_icmp_send_echo_request(&ctx, + net_if_get_default(), + (struct sockaddr *)&dest_addr, + NULL, &sem_wait); + + ret = k_sem_take(&sem_wait, K_MSEC(timeout_ms)); + if (ret == -EAGAIN) { + shell_fprintf(sh, SHELL_WARNING, "ping %s timeout\n", + net_sprint_ipv6_addr(addr)); + } + + (void)net_icmp_cleanup_ctx(&ctx); +} + static int execute_upload(const struct shell *sh, const struct zperf_upload_params *param, bool is_udp, bool async) @@ -525,10 +576,7 @@ static int execute_upload(const struct shell *sh, * has been done for the peer. So send ping here, wait * some time and start the test after that. */ - net_icmpv6_send_echo_request(net_if_get_default(), - &ipv6->sin6_addr, 0, 0, 0, -1, NULL, 0); - - k_sleep(K_SECONDS(1)); + send_ping(sh, &ipv6->sin6_addr, MSEC_PER_SEC); } if (is_udp && IS_ENABLED(CONFIG_NET_UDP)) { From 274f5d9a4b7b36205ce4636c16ba8449c6a5d673 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 26 Sep 2023 14:50:21 +0300 Subject: [PATCH 1238/4498] tests: net: ipv6_fragment: Fix ICMP usage in the test Convert the test to use new ICMP API. Signed-off-by: Jukka Rissanen --- tests/net/ipv6_fragment/src/main.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/net/ipv6_fragment/src/main.c b/tests/net/ipv6_fragment/src/main.c index bcf78a48285..9eff54a1582 100644 --- a/tests/net/ipv6_fragment/src/main.c +++ b/tests/net/ipv6_fragment/src/main.c @@ -2217,9 +2217,11 @@ static uint8_t ipv6_reass_frag2[] = { static uint16_t test_recv_payload_len = 1300U; -static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *ip_hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { const struct net_ipv6_hdr *hdr = NET_IPV6_HDR(pkt); uint8_t verify_buf[NET_IPV6H_LEN]; @@ -2228,6 +2230,11 @@ static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt, uint16_t i; uint8_t expected_data = 0; + ARG_UNUSED(ctx); + ARG_UNUSED(ip_hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + NET_DBG("Data %p received", pkt); zassert_equal(net_pkt_get_len(pkt), expected_pkt_length, "Invalid packet length"); @@ -2292,13 +2299,12 @@ ZTEST(net_ipv6_fragment, test_recv_ipv6_fragment) uint16_t payload2_len; uint8_t data; int ret; - static struct net_icmpv6_handler ping6_handler = { - .type = NET_ICMPV6_ECHO_REPLY, - .code = 0, - .handler = handle_ipv6_echo_reply, - }; + struct net_icmp_ctx ctx; - net_icmpv6_register_handler(&ping6_handler); + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_ECHO_REPLY, + 0, handle_ipv6_echo_reply); + zassert_equal(ret, 0, "Cannot register %s handler (%d)", + STRINGIFY(NET_ICMPV6_ECHO_REPLY), ret); /* Fragment 1 */ data = 0U; @@ -2387,7 +2393,7 @@ ZTEST(net_ipv6_fragment, test_recv_ipv6_fragment) zassert_true(false, "Timeout"); } - net_icmpv6_unregister_handler(&ping6_handler); + net_icmp_cleanup_ctx(&ctx); } ZTEST_SUITE(net_ipv6_fragment, NULL, test_setup, NULL, NULL, NULL); From 729a8e622b53f8ef59d0a1877734cfb06cf740f2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 26 Sep 2023 14:51:05 +0300 Subject: [PATCH 1239/4498] tests: net: mld: Fix ICMP usage in the test Convert the test to use new ICMP API. Signed-off-by: Jukka Rissanen --- tests/net/mld/src/main.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/net/mld/src/main.c b/tests/net/mld/src/main.c index 513fc3107c3..3846e61421f 100644 --- a/tests/net/mld/src/main.c +++ b/tests/net/mld/src/main.c @@ -429,10 +429,18 @@ static void leave_mldv2_capable_routers_group(void) } /* We are not really interested to parse the query at this point */ -static enum net_verdict handle_mld_query(struct net_pkt *pkt, - struct net_ipv6_hdr *ip_hdr, - struct net_icmp_hdr *icmp_hdr) +static int handle_mld_query(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) { + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + is_query_received = true; NET_DBG("Handling MLD query"); @@ -440,19 +448,19 @@ static enum net_verdict handle_mld_query(struct net_pkt *pkt, return NET_DROP; } -static struct net_icmpv6_handler mld_query_input_handler = { - .type = NET_ICMPV6_MLD_QUERY, - .code = 0, - .handler = handle_mld_query, -}; - static void test_catch_query(void) { + struct net_icmp_ctx ctx; + int ret; + join_mldv2_capable_routers_group(); is_query_received = false; - net_icmpv6_register_handler(&mld_query_input_handler); + ret = net_icmp_init_ctx(&ctx, NET_ICMPV6_MLD_QUERY, + 0, handle_mld_query); + zassert_equal(ret, 0, "Cannot register %s handler (%d)", + STRINGIFY(NET_ICMPV6_MLD_QUERY), ret); send_query(net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY))); @@ -468,9 +476,9 @@ static void test_catch_query(void) is_query_received = false; - net_icmpv6_unregister_handler(&mld_query_input_handler); - leave_mldv2_capable_routers_group(); + + net_icmp_cleanup_ctx(&ctx); } static void test_verify_send_report(void) From 02e4e60f2ffbace2272d7ea8d0f717fd6b5dbd98 Mon Sep 17 00:00:00 2001 From: Fabiola Kwasowiec Date: Wed, 27 Sep 2023 09:33:29 +0200 Subject: [PATCH 1240/4498] dmic: add the correct gain values to the dmic registers Zephyr increments the gain until it reaches the maximum value and then sets the registers to zero which is incorrect. The values set in the DMIC config should be restored. Signed-off-by: Fabiola Kwasowiec --- drivers/dai/intel/dmic/dmic.c | 19 ++++++++++++++----- drivers/dai/intel/dmic/dmic.h | 2 ++ drivers/dai/intel/dmic/dmic_nhlt.c | 3 +++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index fcc9b119670..3da5fb8c538 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -527,11 +527,20 @@ static void dai_dmic_gain_ramp(struct dai_intel_dmic *dmic) FIR_CONTROL_MUTE, 0); } - val = FIELD_PREP(OUT_GAIN, gval); - dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * - dmic->dai_config_params.dai_index + OUT_GAIN_LEFT, val); - dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * - dmic->dai_config_params.dai_index + OUT_GAIN_RIGHT, val); + if (gval != 0) { + val = FIELD_PREP(OUT_GAIN, gval); + dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * + dmic->dai_config_params.dai_index + OUT_GAIN_LEFT, val); + dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * + dmic->dai_config_params.dai_index + OUT_GAIN_RIGHT, val); + } else { + dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * + dmic->dai_config_params.dai_index + OUT_GAIN_LEFT, + dmic->gain_left); + dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE * + dmic->dai_config_params.dai_index + OUT_GAIN_RIGHT, + dmic->gain_right); + } } k_spin_unlock(&dmic->lock, key); diff --git a/drivers/dai/intel/dmic/dmic.h b/drivers/dai/intel/dmic/dmic.h index 52399106925..e06ed80daed 100644 --- a/drivers/dai/intel/dmic/dmic.h +++ b/drivers/dai/intel/dmic/dmic.h @@ -179,6 +179,8 @@ struct dai_intel_dmic { #endif int irq; uint32_t flags; + uint32_t gain_left; + uint32_t gain_right; }; static inline int32_t sat_int32(int64_t x) diff --git a/drivers/dai/intel/dmic/dmic_nhlt.c b/drivers/dai/intel/dmic/dmic_nhlt.c index 9e3b08072cd..17a8f385a02 100644 --- a/drivers/dai/intel/dmic/dmic_nhlt.c +++ b/drivers/dai/intel/dmic/dmic_nhlt.c @@ -621,6 +621,9 @@ static void configure_fir(struct dai_intel_dmic *dmic, const uint32_t base, dai_dmic_write(dmic, base + DC_OFFSET_RIGHT, fir_cfg->dc_offset_right); dai_dmic_write(dmic, base + OUT_GAIN_LEFT, fir_cfg->out_gain_left); dai_dmic_write(dmic, base + OUT_GAIN_RIGHT, fir_cfg->out_gain_right); + + dmic->gain_left = fir_cfg->out_gain_left; + dmic->gain_right = fir_cfg->out_gain_right; } int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cfg) From 3cc9fa45120d29f5f1772d7efe14c71bd116db8f Mon Sep 17 00:00:00 2001 From: Zoltan Havas Date: Tue, 26 Sep 2023 12:41:02 +0100 Subject: [PATCH 1241/4498] gecko: Fix sdid for xg27 part Please see the original slcc sdid value: https://github.com/SiliconLabs/gecko_sdk/blob/gsdk_4.3/platform/Device/component/efr32bg27c140f768im40.slcc#L70 Signed-off-by: Zoltan Havas --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 39aa1827835..61aa543ba4f 100644 --- a/west.yml +++ b/west.yml @@ -225,7 +225,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 32f35f1b3763b4d31021c656ff7cd4e7b192a97c + revision: 6a4521e5934d2e787f782b9e5370f3206e6cc9d2 path: modules/hal/silabs groups: - hal From df4d64c15e3df7f9b029cb51c7c3b9a0a5e71f0c Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 26 Sep 2023 11:40:31 +0200 Subject: [PATCH 1242/4498] dts: bindings: Update compats and filenames Update compatible strings and file names of Intel CPUs. Always use dash instead of underscore. This will make all the compat strings and binding files names for Intel consistent. Signed-off-by: Franciszek Zdobylak --- .../cpu/{intel,alder_lake.yaml => intel,alder-lake.yaml} | 0 .../cpu/{intel,apollo_lake.yaml => intel,apollo-lake.yaml} | 2 +- .../cpu/{intel,elkhart_lake.yaml => intel,elkhart-lake.yaml} | 2 +- .../cpu/{intel,raptor_lake.yaml => intel,raptor-lake.yaml} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename dts/bindings/cpu/{intel,alder_lake.yaml => intel,alder-lake.yaml} (100%) rename dts/bindings/cpu/{intel,apollo_lake.yaml => intel,apollo-lake.yaml} (79%) rename dts/bindings/cpu/{intel,elkhart_lake.yaml => intel,elkhart-lake.yaml} (79%) rename dts/bindings/cpu/{intel,raptor_lake.yaml => intel,raptor-lake.yaml} (100%) diff --git a/dts/bindings/cpu/intel,alder_lake.yaml b/dts/bindings/cpu/intel,alder-lake.yaml similarity index 100% rename from dts/bindings/cpu/intel,alder_lake.yaml rename to dts/bindings/cpu/intel,alder-lake.yaml diff --git a/dts/bindings/cpu/intel,apollo_lake.yaml b/dts/bindings/cpu/intel,apollo-lake.yaml similarity index 79% rename from dts/bindings/cpu/intel,apollo_lake.yaml rename to dts/bindings/cpu/intel,apollo-lake.yaml index 3ac47c0a05d..1bef2bce04f 100644 --- a/dts/bindings/cpu/intel,apollo_lake.yaml +++ b/dts/bindings/cpu/intel,apollo-lake.yaml @@ -3,6 +3,6 @@ description: Intel Apollo lake CPU -compatible: "intel,apollo_lake" +compatible: "intel,apollo-lake" include: cpu.yaml diff --git a/dts/bindings/cpu/intel,elkhart_lake.yaml b/dts/bindings/cpu/intel,elkhart-lake.yaml similarity index 79% rename from dts/bindings/cpu/intel,elkhart_lake.yaml rename to dts/bindings/cpu/intel,elkhart-lake.yaml index bafa1a317a2..14ff85838e8 100644 --- a/dts/bindings/cpu/intel,elkhart_lake.yaml +++ b/dts/bindings/cpu/intel,elkhart-lake.yaml @@ -3,6 +3,6 @@ description: Intel Elkhart Lake CPU -compatible: "intel,elkhart_lake" +compatible: "intel,elkhart-lake" include: cpu.yaml diff --git a/dts/bindings/cpu/intel,raptor_lake.yaml b/dts/bindings/cpu/intel,raptor-lake.yaml similarity index 100% rename from dts/bindings/cpu/intel,raptor_lake.yaml rename to dts/bindings/cpu/intel,raptor-lake.yaml From 5ea64eb9c6cc5b7f0a235309247a6ffe35205929 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 26 Sep 2023 11:41:34 +0200 Subject: [PATCH 1243/4498] dts: x86: intel: Update compats Update compatible strings of Intel CPUs. Always use dash instead of underscore. Signed-off-by: Franciszek Zdobylak --- dts/x86/intel/alder_lake.dtsi | 2 +- dts/x86/intel/apollo_lake.dtsi | 2 +- dts/x86/intel/elkhart_lake.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index 1cb7a591680..8c1c10bea6b 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -17,7 +17,7 @@ cpu@0 { device_type = "cpu"; - compatible = "intel,alder_lake"; + compatible = "intel,alder-lake"; d-cache-line-size = <64>; reg = <0>; }; diff --git a/dts/x86/intel/apollo_lake.dtsi b/dts/x86/intel/apollo_lake.dtsi index 4de0525ae64..ffe50483434 100644 --- a/dts/x86/intel/apollo_lake.dtsi +++ b/dts/x86/intel/apollo_lake.dtsi @@ -16,7 +16,7 @@ cpu@0 { device_type = "cpu"; - compatible = "intel,apollo_lake"; + compatible = "intel,apollo-lake"; d-cache-line-size = <64>; reg = <0>; }; diff --git a/dts/x86/intel/elkhart_lake.dtsi b/dts/x86/intel/elkhart_lake.dtsi index 75574d9fcfb..e23183df1d0 100644 --- a/dts/x86/intel/elkhart_lake.dtsi +++ b/dts/x86/intel/elkhart_lake.dtsi @@ -16,7 +16,7 @@ cpu@0 { device_type = "cpu"; - compatible = "intel,elkhart_lake"; + compatible = "intel,elkhart-lake"; d-cache-line-size = <64>; reg = <0>; }; From 510bffde45dd2ab21fec917bb38c5d6ebef49eb4 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 26 Sep 2023 11:42:20 +0200 Subject: [PATCH 1244/4498] boards: x86: Update compats Update compatible strings of Intel CPUs. Always use dash instead of underscore. Signed-off-by: Franciszek Zdobylak --- boards/x86/intel_adl/intel_adl.dts | 2 +- boards/x86/up_squared/up_squared.dts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/x86/intel_adl/intel_adl.dts b/boards/x86/intel_adl/intel_adl.dts index 55dace6427c..27c6bb3ad64 100644 --- a/boards/x86/intel_adl/intel_adl.dts +++ b/boards/x86/intel_adl/intel_adl.dts @@ -14,7 +14,7 @@ / { model = "Alder Lake"; - compatible = "intel,alder_lake"; + compatible = "intel,alder-lake"; chosen { zephyr,sram = &dram0; diff --git a/boards/x86/up_squared/up_squared.dts b/boards/x86/up_squared/up_squared.dts index 987125da950..22303e0ef16 100644 --- a/boards/x86/up_squared/up_squared.dts +++ b/boards/x86/up_squared/up_squared.dts @@ -36,14 +36,14 @@ cpu@0 { device_type = "cpu"; - compatible = "intel,apollo_lake"; + compatible = "intel,apollo-lake"; d-cache-line-size = <64>; reg = <0>; }; cpu@1 { device_type = "cpu"; - compatible = "intel,apollo_lake"; + compatible = "intel,apollo-lake"; d-cache-line-size = <64>; reg = <1>; }; From c95026a9acb29e987c0a0106e47ab2d9d13af860 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Wed, 27 Sep 2023 08:28:53 +0200 Subject: [PATCH 1245/4498] dts: bindings: rename quicklogic uart binding Rename filename of binding for quicklogic,usbserialport-s3b to make it consistent with compatible string. Signed-off-by: Franciszek Zdobylak --- ...c,usbserialport_s3b.yaml => quicklogic,usbserialport-s3b.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dts/bindings/serial/{quicklogic,usbserialport_s3b.yaml => quicklogic,usbserialport-s3b.yaml} (100%) diff --git a/dts/bindings/serial/quicklogic,usbserialport_s3b.yaml b/dts/bindings/serial/quicklogic,usbserialport-s3b.yaml similarity index 100% rename from dts/bindings/serial/quicklogic,usbserialport_s3b.yaml rename to dts/bindings/serial/quicklogic,usbserialport-s3b.yaml From 60fae8a0aa2cf05bec508b4c3b46f6abd3d5824b Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Wed, 27 Sep 2023 10:51:15 +0200 Subject: [PATCH 1246/4498] boards: x86: intel_adl: adjust models and compats Adjust model names and compats for Intel alder-lake boards. Names are now consistent with names used in other Intel boards. Signed-off-by: Franciszek Zdobylak --- boards/x86/intel_adl/intel_adl.dts | 3 --- boards/x86/intel_adl/intel_adl_crb.dts | 3 +++ boards/x86/intel_adl/intel_adl_rvp.dts | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/boards/x86/intel_adl/intel_adl.dts b/boards/x86/intel_adl/intel_adl.dts index 27c6bb3ad64..60f53a82f40 100644 --- a/boards/x86/intel_adl/intel_adl.dts +++ b/boards/x86/intel_adl/intel_adl.dts @@ -13,9 +13,6 @@ #include / { - model = "Alder Lake"; - compatible = "intel,alder-lake"; - chosen { zephyr,sram = &dram0; }; diff --git a/boards/x86/intel_adl/intel_adl_crb.dts b/boards/x86/intel_adl/intel_adl_crb.dts index 65d6b9cef99..7a5f8b9d6e0 100644 --- a/boards/x86/intel_adl/intel_adl_crb.dts +++ b/boards/x86/intel_adl/intel_adl_crb.dts @@ -7,6 +7,9 @@ #include "intel_adl.dts" / { + model = "Intel Alder Lake CRB"; + compatible = "intel,alder-lake-crb"; + chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; diff --git a/boards/x86/intel_adl/intel_adl_rvp.dts b/boards/x86/intel_adl/intel_adl_rvp.dts index eb74a98a70f..dd946c247c4 100644 --- a/boards/x86/intel_adl/intel_adl_rvp.dts +++ b/boards/x86/intel_adl/intel_adl_rvp.dts @@ -7,6 +7,9 @@ #include "intel_adl.dts" / { + model = "Intel Alder Lake RVP"; + compatible = "intel,alder-lake-rvp"; + chosen { zephyr,console = &uart0_legacy; zephyr,shell-uart = &uart0_legacy; From 1b0cb324f3827ed5dcd08b63de7b8168fc2a3ffa Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 27 Sep 2023 20:16:19 +0200 Subject: [PATCH 1247/4498] Bluetooth: Controller: nRF53: Fix back-to-back PDU chaining Fix back-to-back PDU chaining using DPPI on nRF53x SoC. Relates to commit b61bd2364c1a ("Bluetooth: Controller: nrf53: Fix back-to-back Tx Rx implementation"). Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c | 2 +- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c index ca566a04db4..6fa0204fb56 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c @@ -394,7 +394,7 @@ static void isr_tx_chain(void *param) lll->phy_s, lll->phy_flags); } else { radio_isr_set(isr_done, lll_aux); - radio_switch_complete_and_disable(); + radio_switch_complete_and_b2b_tx_disable(); } radio_pkt_tx_set(pdu); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c index 1e56f70493c..79a8c6b25cd 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c @@ -367,7 +367,7 @@ static void isr_tx(void *param) switch_radio_complete_and_b2b_tx(lll_sync, lll->phy_s); } else { radio_isr_set(isr_done, lll_sync); - radio_switch_complete_and_disable(); + radio_switch_complete_and_b2b_tx_disable(); } radio_pkt_tx_set(pdu); From cf8f92d73e714abe2920c3d029dfdc06cf219389 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 26 Sep 2023 09:45:05 +0200 Subject: [PATCH 1248/4498] net: lib: mdns_responder: Fallback IPv4/IPv6 address If an IPv4 address is requested on an IPv6 interface or vice versa use a sane default fallback address to send the response. Signed-off-by: Pieter De Gendt --- subsys/net/lib/dns/mdns_responder.c | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/dns/mdns_responder.c b/subsys/net/lib/dns/mdns_responder.c index 0542acad78d..4a61992e506 100644 --- a/subsys/net/lib/dns/mdns_responder.c +++ b/subsys/net/lib/dns/mdns_responder.c @@ -270,8 +270,14 @@ static int send_response(struct net_context *ctx, if (IS_ENABLED(CONFIG_NET_IPV4) && qtype == DNS_RR_TYPE_A) { const struct in_addr *addr; - addr = net_if_ipv4_select_src_addr(iface, - family == AF_INET ? (struct in_addr *)src_addr : NULL); + if (family == AF_INET) { + addr = net_if_ipv4_select_src_addr(iface, (struct in_addr *)src_addr); + } else { + struct sockaddr_in tmp_addr; + + create_ipv4_addr(&tmp_addr); + addr = net_if_ipv4_select_src_addr(iface, &tmp_addr.sin_addr); + } ret = create_answer(ctx, query, qtype, sizeof(struct in_addr), (uint8_t *)addr); if (ret != 0) { @@ -280,8 +286,14 @@ static int send_response(struct net_context *ctx, } else if (IS_ENABLED(CONFIG_NET_IPV6) && qtype == DNS_RR_TYPE_AAAA) { const struct in6_addr *addr; - addr = net_if_ipv6_select_src_addr(iface, - family == AF_INET6 ? (struct in6_addr *)src_addr : NULL); + if (family == AF_INET6) { + addr = net_if_ipv6_select_src_addr(iface, (struct in6_addr *)src_addr); + } else { + struct sockaddr_in6 tmp_addr; + + create_ipv6_addr(&tmp_addr); + addr = net_if_ipv6_select_src_addr(iface, &tmp_addr.sin6_addr); + } ret = create_answer(ctx, query, qtype, sizeof(struct in6_addr), (uint8_t *)addr); if (ret != 0) { @@ -361,14 +373,26 @@ static void send_sd_response(struct net_context *ctx, if (IS_ENABLED(CONFIG_NET_IPV4)) { /* Look up the local IPv4 address */ - addr4 = net_if_ipv4_select_src_addr(iface, - family == AF_INET ? (struct in_addr *)src_addr : NULL); + if (family == AF_INET) { + addr4 = net_if_ipv4_select_src_addr(iface, (struct in_addr *)src_addr); + } else { + struct sockaddr_in tmp_addr; + + create_ipv4_addr(&tmp_addr); + addr4 = net_if_ipv4_select_src_addr(iface, &tmp_addr.sin_addr); + } } if (IS_ENABLED(CONFIG_NET_IPV6)) { /* Look up the local IPv6 address */ - addr6 = net_if_ipv6_select_src_addr(iface, - family == AF_INET6 ? (struct in6_addr *)src_addr : NULL); + if (family == AF_INET6) { + addr6 = net_if_ipv6_select_src_addr(iface, (struct in6_addr *)src_addr); + } else { + struct sockaddr_in6 tmp_addr; + + create_ipv6_addr(&tmp_addr); + addr6 = net_if_ipv6_select_src_addr(iface, &tmp_addr.sin6_addr); + } } ret = dns_sd_query_extract(dns_msg->msg, From 6d23a960dbe54b5fcf38e372ebf7f57e0e3c99ce Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 25 Sep 2023 12:30:16 +0000 Subject: [PATCH 1249/4498] lib: os: build fdtable conditionally Stop building fdtable by default, make it conditional and build it only when needed. Signed-off-by: Anas Nashif --- drivers/wifi/simplelink/Kconfig.simplelink | 1 + lib/os/CMakeLists.txt | 2 +- lib/os/Kconfig | 7 +++++++ lib/posix/Kconfig.eventfd | 1 + lib/posix/Kconfig.fs | 1 + subsys/net/lib/sockets/Kconfig | 1 + tests/lib/fdtable/prj.conf | 1 + 7 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/simplelink/Kconfig.simplelink b/drivers/wifi/simplelink/Kconfig.simplelink index 6e59c3702d3..f2c5ccacbab 100644 --- a/drivers/wifi/simplelink/Kconfig.simplelink +++ b/drivers/wifi/simplelink/Kconfig.simplelink @@ -8,6 +8,7 @@ menuconfig WIFI_SIMPLELINK select SIMPLELINK_HOST_DRIVER select WIFI_OFFLOAD select NET_L2_WIFI_MGMT + select FDTABLE if WIFI_SIMPLELINK diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 5ed076b47ab..4f082716c48 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -9,7 +9,6 @@ zephyr_sources_ifdef(CONFIG_BASE64 base64.c) zephyr_sources( cbprintf_packaged.c dec.c - fdtable.c hex.c printk.c rb.c @@ -22,6 +21,7 @@ zephyr_sources( multi_heap.c ) +zephyr_sources_ifdef(CONFIG_FDTABLE fdtable.c) zephyr_sources_ifdef(CONFIG_ONOFF onoff.c) zephyr_sources_ifdef(CONFIG_NOTIFY notify.c) diff --git a/lib/os/Kconfig b/lib/os/Kconfig index 42465b24f60..f7ad7385df7 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -3,6 +3,13 @@ menu "OS Support Library" +config FDTABLE + bool "File descriptor table" + help + This file provides generic file descriptor table implementation, suitable + for any I/O object implementing POSIX I/O semantics (i.e. read/write + + aux operations). + config JSON_LIBRARY bool "Build JSON library" help diff --git a/lib/posix/Kconfig.eventfd b/lib/posix/Kconfig.eventfd index 52f9b461f55..0b6fa171741 100644 --- a/lib/posix/Kconfig.eventfd +++ b/lib/posix/Kconfig.eventfd @@ -7,6 +7,7 @@ config EVENTFD bool "Support for eventfd" depends on !NATIVE_APPLICATION select POLL + select FDTABLE default y if POSIX_API help Enable support for event file descriptors, eventfd. An eventfd can diff --git a/lib/posix/Kconfig.fs b/lib/posix/Kconfig.fs index 6ad72fbcff5..1d032910539 100644 --- a/lib/posix/Kconfig.fs +++ b/lib/posix/Kconfig.fs @@ -6,6 +6,7 @@ config POSIX_FS bool "POSIX file system API support" default y if POSIX_API depends on FILE_SYSTEM + select FDTABLE help This enables POSIX style file system related APIs. diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 655d321ab9b..80f2e94ceec 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -5,6 +5,7 @@ menuconfig NET_SOCKETS bool "BSD Sockets compatible API" + select FDTABLE help Provide BSD Sockets like API on top of native Zephyr networking API. diff --git a/tests/lib/fdtable/prj.conf b/tests/lib/fdtable/prj.conf index a6c7e5f1d54..f14a42c8a0e 100644 --- a/tests/lib/fdtable/prj.conf +++ b/tests/lib/fdtable/prj.conf @@ -1,3 +1,4 @@ CONFIG_ZTEST=y CONFIG_POSIX_API=y CONFIG_ZTEST_NEW_API=y +CONFIG_FDTABLE=y From 29bbcb1e38f84b505c7fe7e3f7ab4bb3497eea4c Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Thu, 28 Sep 2023 10:32:02 +0530 Subject: [PATCH 1250/4498] net: wifi: Move function from shell to mgmt The CONFIG_NET_L2_WIFI_SHELL isn't always enabled. But these functions might still be used, so need to move functions into mgmt. Signed-off-by: Kapil Bhatt --- subsys/net/l2/wifi/wifi_mgmt.c | 218 ++++++++++++++++++++++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 218 -------------------------------- 2 files changed, 218 insertions(+), 218 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index e9355f4f703..1b763d3db1b 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -17,6 +17,224 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #endif /* CONFIG_WIFI_NM */ +const char * const wifi_security_txt(enum wifi_security_type security) +{ + switch (security) { + case WIFI_SECURITY_TYPE_NONE: + return "OPEN"; + case WIFI_SECURITY_TYPE_WEP: + return "WEP"; + case WIFI_SECURITY_TYPE_WPA_PSK: + return "WPA-PSK"; + case WIFI_SECURITY_TYPE_PSK: + return "WPA2-PSK"; + case WIFI_SECURITY_TYPE_PSK_SHA256: + return "WPA2-PSK-SHA256"; + case WIFI_SECURITY_TYPE_SAE: + return "WPA3-SAE"; + case WIFI_SECURITY_TYPE_WAPI: + return "WAPI"; + case WIFI_SECURITY_TYPE_EAP: + return "EAP"; + case WIFI_SECURITY_TYPE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) +{ + switch (mfp) { + case WIFI_MFP_DISABLE: + return "Disable"; + case WIFI_MFP_OPTIONAL: + return "Optional"; + case WIFI_MFP_REQUIRED: + return "Required"; + case WIFI_MFP_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_band_txt(enum wifi_frequency_bands band) +{ + switch (band) { + case WIFI_FREQ_BAND_2_4_GHZ: + return "2.4GHz"; + case WIFI_FREQ_BAND_5_GHZ: + return "5GHz"; + case WIFI_FREQ_BAND_6_GHZ: + return "6GHz"; + case WIFI_FREQ_BAND_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_state_txt(enum wifi_iface_state state) +{ + switch (state) { + case WIFI_STATE_DISCONNECTED: + return "DISCONNECTED"; + case WIFI_STATE_INACTIVE: + return "INACTIVE"; + case WIFI_STATE_INTERFACE_DISABLED: + return "INTERFACE_DISABLED"; + case WIFI_STATE_SCANNING: + return "SCANNING"; + case WIFI_STATE_AUTHENTICATING: + return "AUTHENTICATING"; + case WIFI_STATE_ASSOCIATING: + return "ASSOCIATING"; + case WIFI_STATE_ASSOCIATED: + return "ASSOCIATED"; + case WIFI_STATE_4WAY_HANDSHAKE: + return "4WAY_HANDSHAKE"; + case WIFI_STATE_GROUP_HANDSHAKE: + return "GROUP_HANDSHAKE"; + case WIFI_STATE_COMPLETED: + return "COMPLETED"; + case WIFI_STATE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mode_txt(enum wifi_iface_mode mode) +{ + switch (mode) { + case WIFI_MODE_INFRA: + return "STATION"; + case WIFI_MODE_IBSS: + return "ADHOC"; + case WIFI_MODE_AP: + return "ACCESS POINT"; + case WIFI_MODE_P2P_GO: + return "P2P GROUP OWNER"; + case WIFI_MODE_P2P_GROUP_FORMATION: + return "P2P GROUP FORMATION"; + case WIFI_MODE_MESH: + return "MESH"; + case WIFI_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) +{ + switch (link_mode) { + case WIFI_0: + return "WIFI 0 (802.11)"; + case WIFI_1: + return "WIFI 1 (802.11b)"; + case WIFI_2: + return "WIFI 2 (802.11a)"; + case WIFI_3: + return "WIFI 3 (802.11g)"; + case WIFI_4: + return "WIFI 4 (802.11n/HT)"; + case WIFI_5: + return "WIFI 5 (802.11ac/VHT)"; + case WIFI_6: + return "WIFI 6 (802.11ax/HE)"; + case WIFI_6E: + return "WIFI 6E (802.11ax 6GHz/HE)"; + case WIFI_7: + return "WIFI 7 (802.11be/EHT)"; + case WIFI_LINK_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_txt(enum wifi_ps ps_name) +{ + switch (ps_name) { + case WIFI_PS_DISABLED: + return "Power save disabled"; + case WIFI_PS_ENABLED: + return "Power save enabled"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) +{ + switch (ps_mode) { + case WIFI_PS_MODE_LEGACY: + return "Legacy power save"; + case WIFI_PS_MODE_WMM: + return "WMM power save"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) +{ + switch (twt_operation) { + case WIFI_TWT_SETUP: + return "TWT setup"; + case WIFI_TWT_TEARDOWN: + return "TWT teardown"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) +{ + switch (twt_negotiation) { + case WIFI_TWT_INDIVIDUAL: + return "TWT individual negotiation"; + case WIFI_TWT_BROADCAST: + return "TWT broadcast negotiation"; + case WIFI_TWT_WAKE_TBTT: + return "TWT wake TBTT negotiation"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) +{ + switch (twt_setup) { + case WIFI_TWT_SETUP_CMD_REQUEST: + return "TWT request"; + case WIFI_TWT_SETUP_CMD_SUGGEST: + return "TWT suggest"; + case WIFI_TWT_SETUP_CMD_DEMAND: + return "TWT demand"; + case WIFI_TWT_SETUP_CMD_GROUPING: + return "TWT grouping"; + case WIFI_TWT_SETUP_CMD_ACCEPT: + return "TWT accept"; + case WIFI_TWT_SETUP_CMD_ALTERNATE: + return "TWT alternate"; + case WIFI_TWT_SETUP_CMD_DICTATE: + return "TWT dictate"; + case WIFI_TWT_SETUP_CMD_REJECT: + return "TWT reject"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) +{ + switch (ps_wakeup_mode) { + case WIFI_PS_WAKEUP_MODE_DTIM: + return "PS wakeup mode DTIM"; + case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: + return "PS wakeup mode listen interval"; + default: + return "UNKNOWN"; + } +} + static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index e2ff20a105d..d8e2ec756ba 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -97,224 +97,6 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi return true; } -const char * const wifi_security_txt(enum wifi_security_type security) -{ - switch (security) { - case WIFI_SECURITY_TYPE_NONE: - return "OPEN"; - case WIFI_SECURITY_TYPE_WEP: - return "WEP"; - case WIFI_SECURITY_TYPE_WPA_PSK: - return "WPA-PSK"; - case WIFI_SECURITY_TYPE_PSK: - return "WPA2-PSK"; - case WIFI_SECURITY_TYPE_PSK_SHA256: - return "WPA2-PSK-SHA256"; - case WIFI_SECURITY_TYPE_SAE: - return "WPA3-SAE"; - case WIFI_SECURITY_TYPE_WAPI: - return "WAPI"; - case WIFI_SECURITY_TYPE_EAP: - return "EAP"; - case WIFI_SECURITY_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) -{ - switch (mfp) { - case WIFI_MFP_DISABLE: - return "Disable"; - case WIFI_MFP_OPTIONAL: - return "Optional"; - case WIFI_MFP_REQUIRED: - return "Required"; - case WIFI_MFP_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_band_txt(enum wifi_frequency_bands band) -{ - switch (band) { - case WIFI_FREQ_BAND_2_4_GHZ: - return "2.4GHz"; - case WIFI_FREQ_BAND_5_GHZ: - return "5GHz"; - case WIFI_FREQ_BAND_6_GHZ: - return "6GHz"; - case WIFI_FREQ_BAND_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_state_txt(enum wifi_iface_state state) -{ - switch (state) { - case WIFI_STATE_DISCONNECTED: - return "DISCONNECTED"; - case WIFI_STATE_INACTIVE: - return "INACTIVE"; - case WIFI_STATE_INTERFACE_DISABLED: - return "INTERFACE_DISABLED"; - case WIFI_STATE_SCANNING: - return "SCANNING"; - case WIFI_STATE_AUTHENTICATING: - return "AUTHENTICATING"; - case WIFI_STATE_ASSOCIATING: - return "ASSOCIATING"; - case WIFI_STATE_ASSOCIATED: - return "ASSOCIATED"; - case WIFI_STATE_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case WIFI_STATE_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case WIFI_STATE_COMPLETED: - return "COMPLETED"; - case WIFI_STATE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mode_txt(enum wifi_iface_mode mode) -{ - switch (mode) { - case WIFI_MODE_INFRA: - return "STATION"; - case WIFI_MODE_IBSS: - return "ADHOC"; - case WIFI_MODE_AP: - return "ACCESS POINT"; - case WIFI_MODE_P2P_GO: - return "P2P GROUP OWNER"; - case WIFI_MODE_P2P_GROUP_FORMATION: - return "P2P GROUP FORMATION"; - case WIFI_MODE_MESH: - return "MESH"; - case WIFI_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) -{ - switch (link_mode) { - case WIFI_0: - return "WIFI 0 (802.11)"; - case WIFI_1: - return "WIFI 1 (802.11b)"; - case WIFI_2: - return "WIFI 2 (802.11a)"; - case WIFI_3: - return "WIFI 3 (802.11g)"; - case WIFI_4: - return "WIFI 4 (802.11n/HT)"; - case WIFI_5: - return "WIFI 5 (802.11ac/VHT)"; - case WIFI_6: - return "WIFI 6 (802.11ax/HE)"; - case WIFI_6E: - return "WIFI 6E (802.11ax 6GHz/HE)"; - case WIFI_7: - return "WIFI 7 (802.11be/EHT)"; - case WIFI_LINK_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_txt(enum wifi_ps ps_name) -{ - switch (ps_name) { - case WIFI_PS_DISABLED: - return "Power save disabled"; - case WIFI_PS_ENABLED: - return "Power save enabled"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) -{ - switch (ps_mode) { - case WIFI_PS_MODE_LEGACY: - return "Legacy power save"; - case WIFI_PS_MODE_WMM: - return "WMM power save"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) -{ - switch (twt_operation) { - case WIFI_TWT_SETUP: - return "TWT setup"; - case WIFI_TWT_TEARDOWN: - return "TWT teardown"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) -{ - switch (twt_negotiation) { - case WIFI_TWT_INDIVIDUAL: - return "TWT individual negotiation"; - case WIFI_TWT_BROADCAST: - return "TWT broadcast negotiation"; - case WIFI_TWT_WAKE_TBTT: - return "TWT wake TBTT negotiation"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) -{ - switch (twt_setup) { - case WIFI_TWT_SETUP_CMD_REQUEST: - return "TWT request"; - case WIFI_TWT_SETUP_CMD_SUGGEST: - return "TWT suggest"; - case WIFI_TWT_SETUP_CMD_DEMAND: - return "TWT demand"; - case WIFI_TWT_SETUP_CMD_GROUPING: - return "TWT grouping"; - case WIFI_TWT_SETUP_CMD_ACCEPT: - return "TWT accept"; - case WIFI_TWT_SETUP_CMD_ALTERNATE: - return "TWT alternate"; - case WIFI_TWT_SETUP_CMD_DICTATE: - return "TWT dictate"; - case WIFI_TWT_SETUP_CMD_REJECT: - return "TWT reject"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) -{ - switch (ps_wakeup_mode) { - case WIFI_PS_WAKEUP_MODE_DTIM: - return "PS wakeup mode DTIM"; - case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: - return "PS wakeup mode listen interval"; - default: - return "UNKNOWN"; - } -} - static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) { const struct wifi_scan_result *entry = From 0e83c66cefc5efe80675c0dcf13cfff5589d1fd0 Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Wed, 19 Jul 2023 15:35:12 +0200 Subject: [PATCH 1251/4498] dts: bindings: Remove `reg` from `vnd,serial` `vnd,serial` is a virtual device which does not have an address. Signed-off-by: Aleksander Wasaznik --- dts/bindings/test/vnd,serial.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dts/bindings/test/vnd,serial.yaml b/dts/bindings/test/vnd,serial.yaml index dc2327b4827..c2d931b0ed7 100644 --- a/dts/bindings/test/vnd,serial.yaml +++ b/dts/bindings/test/vnd,serial.yaml @@ -5,9 +5,6 @@ compatible: "vnd,serial" include: uart-controller.yaml properties: - reg: - required: true - baud-rate: type: int From 4d926ac041cea9a1947390c8a34cb7906e3da30f Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Wed, 19 Jul 2023 15:43:26 +0200 Subject: [PATCH 1252/4498] drivers: serial_test: Implement interrupt and async APIs This allows testing code that uses the UART interrupt-driven API and UART asynchronous API. Signed-off-by: Aleksander Wasaznik --- drivers/serial/serial_test.c | 319 +++++++++++++++++++++- include/zephyr/drivers/uart/serial_test.h | 2 +- 2 files changed, 318 insertions(+), 3 deletions(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index 95e036e5992..2ce4fb50f38 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -9,12 +9,21 @@ * devices for the "vnd,serial" devicetree compatible used in test code. */ +#include + +#include #include #include #include #include +#include #include +LOG_MODULE_REGISTER(mock_serial, CONFIG_LOG_DEFAULT_LEVEL); + +BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN) || IS_ENABLED(CONFIG_RING_BUFFER)); +BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_ASYNC_API) || IS_ENABLED(CONFIG_RING_BUFFER)); + #define DT_DRV_COMPAT vnd_serial struct serial_vnd_data { #ifdef CONFIG_RING_BUFFER @@ -23,8 +32,156 @@ struct serial_vnd_data { #endif serial_vnd_write_cb_t callback; void *callback_data; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t irq_isr; + bool irq_rx_enabled; + bool irq_tx_enabled; +#endif +#ifdef CONFIG_UART_ASYNC_API + uart_callback_t async_cb; + void *async_cb_user_data; + uint8_t *read_buf; + size_t read_size; + size_t read_position; +#endif }; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static bool is_irq_rx_pending(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + return !ring_buf_is_empty(data->read_queue); +} + +static bool is_irq_tx_pending(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + return ring_buf_space_get(data->written) != 0; +} + +static void irq_process(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + for (;;) { + bool rx_rdy = is_irq_rx_pending(dev); + bool tx_rdy = is_irq_tx_pending(dev); + bool rx_int = rx_rdy && data->irq_rx_enabled; + bool tx_int = tx_rdy && data->irq_tx_enabled; + + LOG_DBG("rx_rdy %d tx_rdy %d", rx_rdy, tx_rdy); + LOG_DBG("rx_int %d tx_int %d", rx_int, tx_int); + + if (!(rx_int || tx_int)) { + break; + } + + LOG_DBG("isr"); + if (!data->irq_isr) { + LOG_ERR("no isr registered"); + break; + } + data->irq_isr(dev, NULL); + }; +} + +static void irq_rx_enable(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + data->irq_rx_enabled = true; + LOG_DBG("rx enabled"); + irq_process(dev); +} + +static void irq_rx_disable(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + data->irq_rx_enabled = false; + LOG_DBG("rx disabled"); +} + +static int irq_rx_ready(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + bool ready = !ring_buf_is_empty(data->read_queue); + + LOG_DBG("rx ready: %d", ready); + return ready; +} + +static void irq_tx_enable(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + LOG_DBG("tx enabled"); + data->irq_tx_enabled = true; + irq_process(dev); +} + +static void irq_tx_disable(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + + data->irq_tx_enabled = false; + LOG_DBG("tx disabled"); +} + +static int irq_tx_ready(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + bool ready = (ring_buf_space_get(data->written) != 0); + + LOG_DBG("tx ready: %d", ready); + return ready; +} + +static void irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct serial_vnd_data *data = dev->data; + + /* Not implemented. Ok because `user_data` is always NULL in the current + * implementation of core UART API. + */ + __ASSERT_NO_MSG(user_data == NULL); + +#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_ASYNC_API) + if (data->read_buf) { + LOG_ERR("Setting callback to NULL while asynchronous API is in use."); + } + data->async_cb = NULL; + data->async_cb_user_data = NULL; +#endif + + data->irq_isr = cb; + LOG_DBG("callback set"); +} + +static int fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + struct serial_vnd_data *data = dev->data; + uint32_t write_len = ring_buf_put(data->written, tx_data, size); + + if (data->callback) { + data->callback(dev, data->callback_data); + } + return write_len; +} + +static int fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + struct serial_vnd_data *data = dev->data; + int read_len = ring_buf_get(data->read_queue, rx_data, size); + + LOG_HEXDUMP_DBG(rx_data, read_len, ""); + return read_len; +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + static int serial_vnd_poll_in(const struct device *dev, unsigned char *c) { #ifdef CONFIG_RING_BUFFER @@ -59,15 +216,35 @@ static void serial_vnd_poll_out(const struct device *dev, unsigned char c) } } +#ifdef CONFIG_UART_ASYNC_API +static void async_rx_run(const struct device *dev); +#endif + #ifdef CONFIG_RING_BUFFER -int serial_vnd_queue_in_data(const struct device *dev, unsigned char *c, uint32_t size) +int serial_vnd_queue_in_data(const struct device *dev, const unsigned char *c, uint32_t size) { struct serial_vnd_data *data = dev->data; + int write_size; if (data == NULL || data->read_queue == NULL) { return -ENOTSUP; } - return ring_buf_put(data->read_queue, c, size); + write_size = ring_buf_put(data->read_queue, c, size); + + LOG_DBG("size %u write_size %u", size, write_size); + LOG_HEXDUMP_DBG(c, write_size, ""); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + if (write_size > 0) { + irq_process(dev); + } +#endif + +#ifdef CONFIG_UART_ASYNC_API + async_rx_run(dev); +#endif + + return write_size; } uint32_t serial_vnd_out_data_size_get(const struct device *dev) @@ -130,6 +307,128 @@ static int serial_vnd_config_get(const struct device *dev, struct uart_config *c } #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#ifdef CONFIG_UART_ASYNC_API +static int serial_vnd_callback_set(const struct device *dev, uart_callback_t callback, + void *user_data) +{ + struct serial_vnd_data *data = dev->data; + + if (data == NULL) { + return -ENOTSUP; + } + +#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_INTERRUPT_DRIVEN) + data->irq_isr = cb; +#endif + + if (callback == NULL && data->read_buf) { + LOG_ERR("Setting callback to NULL while asynchronous API is in use."); + } + + data->async_cb = callback; + data->async_cb_user_data = user_data; + + return 0; +} + +static int serial_vnd_api_tx(const struct device *dev, const uint8_t *tx_data, size_t len, + int32_t timeout) +{ + struct serial_vnd_data *data = dev->data; + struct uart_event evt; + uint32_t write_len; + + if (data == NULL) { + return -ENOTSUP; + } + + if (data->async_cb == NULL) { + return -EINVAL; + } + + write_len = ring_buf_put(data->written, tx_data, len); + if (data->callback) { + data->callback(dev, data->callback_data); + } + + __ASSERT(write_len == len, "Ring buffer full. Async wait not implemented."); + + evt = (struct uart_event){ + .type = UART_TX_DONE, + .data.tx.buf = tx_data, + .data.tx.len = len, + }; + data->async_cb(dev, &evt, data->async_cb_user_data); + + return 0; +} + +static void async_rx_run(const struct device *dev) +{ + struct serial_vnd_data *data = dev->data; + struct uart_event evt; + uint32_t read_len; + uint32_t read_remaining; + + if (!data->read_buf) { + return; + } + + __ASSERT_NO_MSG(data->async_cb); + + read_remaining = data->read_size - data->read_position; + + read_len = ring_buf_get(data->read_queue, &data->read_buf[data->read_position], + read_remaining); + + if (read_len != 0) { + evt = (struct uart_event){ + .type = UART_RX_RDY, + .data.rx.buf = data->read_buf, + .data.rx.len = read_len, + .data.rx.offset = data->read_position, + }; + data->async_cb(dev, &evt, data->async_cb_user_data); + } + + data->read_position += read_len; + + if (data->read_position == data->read_size) { + data->read_buf = NULL; + evt = (struct uart_event){ + .type = UART_RX_DISABLED, + }; + data->async_cb(dev, &evt, data->async_cb_user_data); + } +} + +static int serial_vnd_rx_enable(const struct device *dev, uint8_t *read_buf, size_t read_size, + int32_t timeout) +{ + struct serial_vnd_data *data = dev->data; + + LOG_WRN("read_size %d", read_size); + + if (data == NULL) { + return -ENOTSUP; + } + + if (data->async_cb == NULL) { + return -EINVAL; + } + + __ASSERT(timeout == SYS_FOREVER_MS, "Async timeout not implemented."); + + data->read_buf = read_buf; + data->read_size = read_size; + data->read_position = 0; + + async_rx_run(dev); + + return 0; +} +#endif /* CONFIG_UART_ASYNC_API */ + static const struct uart_driver_api serial_vnd_api = { .poll_in = serial_vnd_poll_in, .poll_out = serial_vnd_poll_out, @@ -138,6 +437,22 @@ static const struct uart_driver_api serial_vnd_api = { .configure = serial_vnd_configure, .config_get = serial_vnd_config_get, #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_callback_set = irq_callback_set, + .irq_rx_enable = irq_rx_enable, + .irq_rx_disable = irq_rx_disable, + .irq_rx_ready = irq_rx_ready, + .irq_tx_enable = irq_tx_enable, + .irq_tx_disable = irq_tx_disable, + .irq_tx_ready = irq_tx_ready, + .fifo_read = fifo_read, + .fifo_fill = fifo_fill, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API + .callback_set = serial_vnd_callback_set, + .tx = serial_vnd_api_tx, + .rx_enable = serial_vnd_rx_enable, +#endif /* CONFIG_UART_ASYNC_API */ }; #define VND_SERIAL_DATA_BUFFER(n) \ diff --git a/include/zephyr/drivers/uart/serial_test.h b/include/zephyr/drivers/uart/serial_test.h index 5e011d40321..ff1a2ad6181 100644 --- a/include/zephyr/drivers/uart/serial_test.h +++ b/include/zephyr/drivers/uart/serial_test.h @@ -29,7 +29,7 @@ extern "C" { * * @retval Number of bytes written. */ -int serial_vnd_queue_in_data(const struct device *dev, unsigned char *data, uint32_t size); +int serial_vnd_queue_in_data(const struct device *dev, const unsigned char *data, uint32_t size); /** * @brief Returns size of unread written data. From 347ce7aa7f6e4be8464a4c09c615ad7c4eaa6f9f Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Tue, 10 Jan 2023 10:11:09 +0100 Subject: [PATCH 1253/4498] bluetooth: samples: Add hci_uart_async This sample is an alternative implementation of hci_uart. The new sample differs from the existing sample in that it uses the async UART API instead of the interrupt driven API. Included in this commit is a new test for HCI UART flow control. It's enabled for hci_uart_async. The test can excercise also the existing hci_uart sample (with some minimal changes to allow compiling in the mock controller and test suite). The existing hci_uart sample currently fails the flow control test. Signed-off-by: Aleksander Wasaznik --- .../bluetooth/hci_uart_async/CMakeLists.txt | 10 + samples/bluetooth/hci_uart_async/README.rst | 158 +++++++ samples/bluetooth/hci_uart_async/app.overlay | 31 ++ .../bluetooth/hci_uart_async/debug.mixin.conf | 15 + samples/bluetooth/hci_uart_async/prj.conf | 25 ++ samples/bluetooth/hci_uart_async/sample.yaml | 19 + .../hci_uart_async/src/hci_uart_async.c | 403 ++++++++++++++++++ samples/bluetooth/hci_uart_async/src/main.c | 11 + tests/bluetooth/hci_uart_async/CMakeLists.txt | 15 + tests/bluetooth/hci_uart_async/app.overlay | 11 + .../hci_uart_async/boards/native_posix.conf | 3 + tests/bluetooth/hci_uart_async/prj.conf | 10 + .../hci_uart_async/src/test_hci_uart_async.c | 238 +++++++++++ tests/bluetooth/hci_uart_async/testcase.yaml | 6 + 14 files changed, 955 insertions(+) create mode 100644 samples/bluetooth/hci_uart_async/CMakeLists.txt create mode 100644 samples/bluetooth/hci_uart_async/README.rst create mode 100644 samples/bluetooth/hci_uart_async/app.overlay create mode 100644 samples/bluetooth/hci_uart_async/debug.mixin.conf create mode 100644 samples/bluetooth/hci_uart_async/prj.conf create mode 100644 samples/bluetooth/hci_uart_async/sample.yaml create mode 100644 samples/bluetooth/hci_uart_async/src/hci_uart_async.c create mode 100644 samples/bluetooth/hci_uart_async/src/main.c create mode 100644 tests/bluetooth/hci_uart_async/CMakeLists.txt create mode 100644 tests/bluetooth/hci_uart_async/app.overlay create mode 100644 tests/bluetooth/hci_uart_async/boards/native_posix.conf create mode 100644 tests/bluetooth/hci_uart_async/prj.conf create mode 100644 tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c create mode 100644 tests/bluetooth/hci_uart_async/testcase.yaml diff --git a/samples/bluetooth/hci_uart_async/CMakeLists.txt b/samples/bluetooth/hci_uart_async/CMakeLists.txt new file mode 100644 index 00000000000..fe45a9cc371 --- /dev/null +++ b/samples/bluetooth/hci_uart_async/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(hci_uart_async) +target_sources(app PRIVATE + src/hci_uart_async.c + src/main.c +) diff --git a/samples/bluetooth/hci_uart_async/README.rst b/samples/bluetooth/hci_uart_async/README.rst new file mode 100644 index 00000000000..75bf586868d --- /dev/null +++ b/samples/bluetooth/hci_uart_async/README.rst @@ -0,0 +1,158 @@ +.. _bluetooth-hci-uart-async-sample: + +Bluetooth: HCI UART based on ASYNC UART +####################################### + +Expose a Zephyr Bluetooth Controller over a standard Bluetooth HCI UART interface. + +This sample performs the same basic function as the HCI UART sample, but it uses the UART_ASYNC_API +instead of UART_INTERRUPT_DRIVEN API. Not all boards implement both UART APIs, so the board support +of the HCI UART sample may be different. + +Requirements +************ + +* A board with BLE support + +Default UART settings +********************* + +By default the controller builds use the following settings: + +* Baudrate: 1Mbit/s +* 8 bits, no parity, 1 stop bit +* Hardware Flow Control (RTS/CTS) enabled + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/bluetooth/hci_uart_async` +in the Zephyr tree and is built as a standard Zephyr application. + +Using the controller with emulators and BlueZ +********************************************* + +The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE +controller and expose it to Linux's BlueZ. + +First, make sure you have a recent BlueZ version installed by following the +instructions in the :ref:`bluetooth_bluez` section. + +Now build and flash the sample for the Nordic nRF5x board of your choice. +All of the Nordic Development Kits come with a Segger IC that provides a +debugger interface and a CDC ACM serial port bridge. More information can be +found in :ref:`nordic_segger`. + +For example, to build for the nRF52832 Development Kit: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/hci_uart_async + :board: nrf52dk_nrf52832 + :goals: build flash + +.. _bluetooth-hci-uart-async-qemu-posix: + +Using the controller with QEMU and Native POSIX +=============================================== + +In order to use the HCI UART controller with QEMU or Native POSIX you will need +to attach it to the Linux Host first. To do so simply build the sample and +connect the UART to the Linux machine, and then attach it with this command: + +.. code-block:: console + + sudo btattach -B /dev/ttyACM0 -S 1000000 -R + +.. note:: + Depending on the serial port you are using you will need to modify the + ``/dev/ttyACM0`` string to point to the serial device your controller is + connected to. + +.. note:: + The ``-R`` flag passed to ``btattach`` instructs the kernel to avoid + interacting with the controller and instead just be aware of it in order + to proxy it to QEMU later. + +If you are running :file:`btmon` you should see a brief log showing how the +Linux kernel identifies the attached controller. + +Once the controller is attached follow the instructions in the +:ref:`bluetooth_qemu_posix` section to use QEMU with it. + +.. _bluetooth-hci-uart-async-bluez: + +Using the controller with BlueZ +=============================== + +In order to use the HCI UART controller with BlueZ you will need to attach it +to the Linux Host first. To do so simply build the sample and connect the +UART to the Linux machine, and then attach it with this command: + +.. code-block:: console + + sudo btattach -B /dev/ttyACM0 -S 1000000 + +.. note:: + Depending on the serial port you are using you will need to modify the + ``/dev/ttyACM0`` string to point to the serial device your controller is + connected to. + +If you are running :file:`btmon` you should see a comprehensive log showing how +BlueZ loads and initializes the attached controller. + +Once the controller is attached follow the instructions in the +:ref:`bluetooth_ctlr_bluez` section to use BlueZ with it. + +Debugging the controller +======================== + +The sample can be debugged using RTT since the UART is reserved used by this +application. To enable debug over RTT the debug configuration file can be used. + +.. code-block:: console + + west build samples/bluetooth/hci_uart_async -- -DEXTRA_CONFIG='debug.mixin.conf' + +Then attach RTT as described here: :ref:`Using Segger J-Link ` + +Using the controller with the Zephyr host +========================================= + +This describes how to hook up a board running this sample to a board running +an application that uses the Zephyr host. + +On the controller side, the `zephyr,bt-c2h-uart` DTS property (in the `chosen` +block) is used to select which uart device to use. For example if we want to +keep the console logs, we can keep console on uart0 and the HCI on uart1 like +so: + +.. code-block:: dts + + / { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,bt-c2h-uart = &uart1; + }; + }; + +On the host application, some config options need to be used to select the H4 +driver instead of the built-in controller: + +.. code-block:: kconfig + + CONFIG_BT_HCI=y + CONFIG_BT_CTLR=n + CONFIG_BT_H4=y + +Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: + +.. code-block:: dts + + / { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,bt-uart = &uart1; + }; + }; diff --git a/samples/bluetooth/hci_uart_async/app.overlay b/samples/bluetooth/hci_uart_async/app.overlay new file mode 100644 index 00000000000..e9a282ad78c --- /dev/null +++ b/samples/bluetooth/hci_uart_async/app.overlay @@ -0,0 +1,31 @@ +/* This is the default app device tree overlay. This file is ignored if + * there is a board-specific overlay in `./boards`. + * + * Most boards define a convenient `&uart0`. It's used here to make the + * sample 'just work' automatically for those boards. + */ + +bt_c2h_uart: &uart0 { + status = "okay"; + current-speed = <1000000>; + hw-flow-control; +}; + +/ { + chosen { + zephyr,bt-c2h-uart = &bt_c2h_uart; + }; +}; + +/* Some boards are by default assigning the &uart0 to these other + * functions. Removing the assignments will ensure a compilation error + * instead of accidental interference. + */ +/ { + chosen { + /delete-property/ zephyr,console; + /delete-property/ zephyr,shell-uart; + /delete-property/ zephyr,uart-mcumgr; + /delete-property/ zephyr,bt-mon-uart; + }; +}; diff --git a/samples/bluetooth/hci_uart_async/debug.mixin.conf b/samples/bluetooth/hci_uart_async/debug.mixin.conf new file mode 100644 index 00000000000..3255df74018 --- /dev/null +++ b/samples/bluetooth/hci_uart_async/debug.mixin.conf @@ -0,0 +1,15 @@ +CONFIG_ASSERT_ON_ERRORS=y +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_OPTIMIZATIONS=y +CONFIG_DEBUG_THREAD_INFO=y + +# Enable RTT console +CONFIG_RTT_CONSOLE=y + +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=10000 + +# This outputs all HCI traffic to a separate RTT channel. Use `btmon +# --jlink` to read it out. Add `--priority 7` for debug logs. +CONFIG_BT_DEBUG_MONITOR_RTT=y diff --git a/samples/bluetooth/hci_uart_async/prj.conf b/samples/bluetooth/hci_uart_async/prj.conf new file mode 100644 index 00000000000..1de1a46535e --- /dev/null +++ b/samples/bluetooth/hci_uart_async/prj.conf @@ -0,0 +1,25 @@ +# hci_uart_async +CONFIG_SERIAL=y +CONFIG_UART_ASYNC_API=y + +# hci_raw (dependency of hci_uart) +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_H4=y +CONFIG_BT_HCI_RAW_H4_ENABLE=y + +# Controller configuration. Modify these for your application's needs. +CONFIG_BT_MAX_CONN=16 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_CMD_TX_SIZE=255 +CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 + +# Send an initial HCI_Command_Complete event on boot without waiting for +# HCI_Reset. Make sure to use the same value for this setting in your +# host application. +#CONFIG_BT_WAIT_NOP=y + +# See `overlay.app`. The 'zephyr,console' chosen node is deleted there +# in case it has a interfering default. Those same boards set this +# config and it must be undone or the build will fail. +CONFIG_UART_CONSOLE=n diff --git a/samples/bluetooth/hci_uart_async/sample.yaml b/samples/bluetooth/hci_uart_async/sample.yaml new file mode 100644 index 00000000000..d0db2b90385 --- /dev/null +++ b/samples/bluetooth/hci_uart_async/sample.yaml @@ -0,0 +1,19 @@ +sample: + name: Bluetooth HCI UART Async + description: + This sample is a batteries-included example of a Bluetooth HCI UART + connectivity chip. + + It demonstrates a possible implementation of an HCI UART (H4) + interface on top of Zephyr's Bluetooth Raw API, and how to expose it + over a UART. + + This implementation is based on the Zephyr Asynchoronous UART API. +tests: + sample.bluetooth.hci_uart_async.nrf5: + harness: bluetooth + platform_allow: + - nrf52dk_nrf52832 + tags: + - uart + - bluetooth diff --git a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c new file mode 100644 index 00000000000..4d276e42378 --- /dev/null +++ b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c @@ -0,0 +1,403 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(hci_uart_async, LOG_LEVEL_DBG); + +static const struct device *const hci_uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart)); + +static K_THREAD_STACK_DEFINE(h2c_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); +static struct k_thread h2c_thread; + +enum h4_type { + H4_CMD = 0x01, + H4_ACL = 0x02, + H4_SCO = 0x03, + H4_EVT = 0x04, + H4_ISO = 0x05, +}; + +struct k_poll_signal uart_h2c_rx_sig; +struct k_poll_signal uart_c2h_tx_sig; + +static K_FIFO_DEFINE(c2h_queue); + +/** Send raw data on c2h UART. + * + * Blocks until completion. Not thread-safe. + * + * @retval 0 on success + * @retval -EBUSY Another transmission is in progress. This a + * thread-safety violation. + * @retval -errno @ref uart_tx error. + */ +static int uart_c2h_tx(const uint8_t *data, size_t size) +{ + int err; + struct k_poll_signal *sig = &uart_c2h_tx_sig; + struct k_poll_event done[] = { + K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig), + }; + + k_poll_signal_reset(sig); + err = uart_tx(hci_uart_dev, data, size, SYS_FOREVER_US); + + if (err) { + LOG_ERR("uart c2h tx: err %d", err); + return err; + } + + err = k_poll(done, ARRAY_SIZE(done), K_FOREVER); + __ASSERT_NO_MSG(err == 0); + + return 0; +} + +/* Function expects that type is validated and only CMD, ISO or ACL will be used. */ +static uint32_t hci_payload_size(const uint8_t *hdr_buf, enum h4_type type) +{ + switch (type) { + case H4_CMD: + return ((const struct bt_hci_cmd_hdr *)hdr_buf)->param_len; + case H4_ACL: + return sys_le16_to_cpu(((const struct bt_hci_acl_hdr *)hdr_buf)->len); + case H4_ISO: + return bt_iso_hdr_len( + sys_le16_to_cpu(((const struct bt_hci_iso_hdr *)hdr_buf)->len)); + default: + LOG_ERR("Invalid type: %u", type); + return 0; + } +} + +static uint8_t hci_hdr_size(enum h4_type type) +{ + switch (type) { + case H4_CMD: + return sizeof(struct bt_hci_cmd_hdr); + case H4_ACL: + return sizeof(struct bt_hci_acl_hdr); + case H4_ISO: + return sizeof(struct bt_hci_iso_hdr); + default: + LOG_ERR("Unexpected h4 type: %u", type); + return 0; + } +} + +/** Send raw data on c2h UART. + * + * Blocks until either @p size has been received or special UART + * condition occurs on the UART RX line, like an UART break or parity + * error. + * + * Not thread-safe. + * + * @retval 0 on success + * @retval -EBUSY Another transmission is in progress. This a + * thread-safety violation. + * @retval -errno @ref uart_rx_enable error. + * @retval +stop_reason Special condition @ref uart_rx_stop_reason. + */ +static int uart_h2c_rx(uint8_t *dst, size_t size) +{ + int err; + struct k_poll_signal *sig = &uart_h2c_rx_sig; + struct k_poll_event done[] = { + K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig), + }; + + k_poll_signal_reset(sig); + err = uart_rx_enable(hci_uart_dev, dst, size, SYS_FOREVER_US); + + if (err) { + LOG_ERR("uart h2c rx: err %d", err); + return err; + } + + k_poll(done, ARRAY_SIZE(done), K_FOREVER); + return sig->result; +} + +/** Inject a HCI EVT Hardware error into the c2h packet stream. + * + * This uses `bt_recv`, just as if the controller is sending the error. + */ +static void send_hw_error(void) +{ + const uint8_t err_code = 0; + const uint8_t hci_evt_hw_err[] = {BT_HCI_EVT_HARDWARE_ERROR, + sizeof(struct bt_hci_evt_hardware_error), err_code}; + + struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); + + net_buf_add_mem(buf, hci_evt_hw_err, sizeof(hci_evt_hw_err)); + + /* Inject the message into the c2h queue. */ + bt_recv(buf); + + /* The c2h thread will send the message at some point. The host + * will receive it and reset the controller. + */ +} + +static void recover_sync_by_reset_pattern(void) +{ + /* { H4_CMD, le_16(HCI_CMD_OP_RESET), len=0 } */ + const uint8_t h4_cmd_reset[] = {0x01, 0x03, 0x0C, 0x00}; + const uint32_t reset_pattern = sys_get_be32(h4_cmd_reset); + int err; + struct net_buf *h2c_cmd_reset; + uint32_t shift_register = 0; + + LOG_DBG("Looking for reset pattern"); + + while (shift_register != reset_pattern) { + uint8_t read_byte; + + uart_h2c_rx(&read_byte, sizeof(uint8_t)); + LOG_DBG("h2c: 0x%02x", read_byte); + shift_register = (shift_register * 0x100) + read_byte; + } + + LOG_DBG("Pattern found"); + h2c_cmd_reset = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, h4_cmd_reset, sizeof(h4_cmd_reset)); + LOG_DBG("Fowarding reset"); + + err = bt_send(h2c_cmd_reset); + __ASSERT(!err, "Failed to send reset: %d", err); +} + +static void h2c_h4_transport(void) +{ + /* When entering this function, the h2c stream should be + * 'synchronized'. I.e. The stream should be at a H4 packet + * boundary. + * + * This function returns to signal a desynchronization. + * When this happens, the caller should resynchronize before + * entering this function again. It's up to the caller to decide + * how to resynchronize. + */ + + for (;;) { + int err; + struct net_buf *buf; + uint8_t h4_type; + uint8_t hdr_size; + uint8_t *hdr_buf; + uint16_t payload_size; + + LOG_DBG("h2c: listening"); + + /* Read H4 type. */ + err = uart_h2c_rx(&h4_type, sizeof(uint8_t)); + + if (err) { + return; + } + LOG_DBG("h2c: h4_type %d", h4_type); + + /* Allocate buf. */ + buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, &h4_type, sizeof(h4_type)); + LOG_DBG("h2c: buf %p", buf); + + if (!buf) { + /* `h4_type` was invalid. */ + __ASSERT_NO_MSG(hci_hdr_size(h4_type) == 0); + + LOG_WRN("bt_buf_get_tx failed h4_type %d", h4_type); + return; + } + + /* Read HCI header. */ + hdr_size = hci_hdr_size(h4_type); + hdr_buf = net_buf_add(buf, hdr_size); + + err = uart_h2c_rx(hdr_buf, hdr_size); + if (err) { + net_buf_unref(buf); + return; + } + LOG_HEXDUMP_DBG(hdr_buf, hdr_size, "h2c: hci hdr"); + + /* Read HCI payload. */ + payload_size = hci_payload_size(hdr_buf, h4_type); + + LOG_DBG("h2c: payload_size %u", payload_size); + + if (payload_size <= net_buf_tailroom(buf)) { + uint8_t *payload_dst = net_buf_add(buf, payload_size); + + err = uart_h2c_rx(payload_dst, payload_size); + if (err) { + net_buf_unref(buf); + return; + } + LOG_HEXDUMP_DBG(payload_dst, payload_size, "h2c: hci payload"); + } else { + /* Discard oversize packet. */ + uint8_t *discard_dst; + uint16_t discard_size; + + LOG_WRN("h2c: Discarding oversize h4_type %d payload_size %d.", h4_type, + payload_size); + + /* Reset `buf` so all of it is available. */ + net_buf_reset(buf); + discard_dst = net_buf_tail(buf); + discard_size = net_buf_max_len(buf); + + while (payload_size) { + uint16_t read_size = MIN(payload_size, discard_size); + + err = uart_h2c_rx(discard_dst, read_size); + if (err) { + net_buf_unref(buf); + return; + } + + payload_size -= read_size; + } + + net_buf_unref(buf); + buf = NULL; + } + + LOG_DBG("h2c: packet done"); + + /* Route buf to Controller. */ + if (buf) { + err = bt_send(buf); + if (err) { + /* This is not a transport error. */ + LOG_ERR("bt_send err %d", err); + net_buf_unref(buf); + buf = NULL; + } + } + + k_yield(); + } +} + +static void h2c_thread_entry(void *p1, void *p2, void *p3) +{ + k_thread_name_set(k_current_get(), "HCI TX (h2c)"); + + for (;;) { + LOG_DBG("Synchronized"); + h2c_h4_transport(); + LOG_WRN("Desynchronized"); + send_hw_error(); + recover_sync_by_reset_pattern(); + } +} + +void callback(const struct device *dev, struct uart_event *evt, void *user_data) +{ + ARG_UNUSED(user_data); + + if (evt->type == UART_RX_DISABLED) { + (void)k_poll_signal_raise(&uart_h2c_rx_sig, 0); + } else if (evt->type == UART_RX_STOPPED) { + (void)k_poll_signal_raise(&uart_h2c_rx_sig, evt->data.rx_stop.reason); + } else if (evt->type == UART_TX_DONE) { + (void)k_poll_signal_raise(&uart_c2h_tx_sig, 0); + } +} + +static int hci_uart_init(void) +{ + int err; + + k_poll_signal_init(&uart_h2c_rx_sig); + k_poll_signal_init(&uart_c2h_tx_sig); + + LOG_DBG(""); + + if (!device_is_ready(hci_uart_dev)) { + LOG_ERR("HCI UART %s is not ready", hci_uart_dev->name); + return -EINVAL; + } + + BUILD_ASSERT(IS_ENABLED(CONFIG_UART_ASYNC_API)); + err = uart_callback_set(hci_uart_dev, callback, NULL); + + /* Note: Asserts if CONFIG_UART_ASYNC_API is not enabled for `hci_uart_dev`. */ + __ASSERT(!err, "err %d", err); + + return 0; +} + +SYS_INIT(hci_uart_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); + +const struct { + uint8_t h4; + struct bt_hci_evt_hdr hdr; + struct bt_hci_evt_cmd_complete cc; +} __packed cc_evt = { + .h4 = H4_EVT, + .hdr = {.evt = BT_HCI_EVT_CMD_COMPLETE, .len = sizeof(struct bt_hci_evt_cmd_complete)}, + .cc = {.ncmd = 1, .opcode = sys_cpu_to_le16(BT_OP_NOP)}, +}; + +static void c2h_thread_entry(void) +{ + k_thread_name_set(k_current_get(), "HCI RX (c2h)"); + + if (IS_ENABLED(CONFIG_BT_WAIT_NOP)) { + uart_c2h_tx((char *)&cc_evt, sizeof(cc_evt)); + } + + for (;;) { + struct net_buf *buf; + + buf = net_buf_get(&c2h_queue, K_FOREVER); + uart_c2h_tx(buf->data, buf->len); + net_buf_unref(buf); + } +} + +void hci_uart_main(void) +{ + int err; + + err = bt_enable_raw(&c2h_queue); + __ASSERT_NO_MSG(!err); + + /* TX thread. */ + k_thread_create(&h2c_thread, h2c_thread_stack, K_THREAD_STACK_SIZEOF(h2c_thread_stack), + h2c_thread_entry, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + + /* Reuse current thread as RX thread. */ + c2h_thread_entry(); +} diff --git a/samples/bluetooth/hci_uart_async/src/main.c b/samples/bluetooth/hci_uart_async/src/main.c new file mode 100644 index 00000000000..2d38d83e45c --- /dev/null +++ b/samples/bluetooth/hci_uart_async/src/main.c @@ -0,0 +1,11 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +extern int hci_uart_main(void); + +int main(void) +{ + hci_uart_main(); + return 0; +} diff --git a/tests/bluetooth/hci_uart_async/CMakeLists.txt b/tests/bluetooth/hci_uart_async/CMakeLists.txt new file mode 100644 index 00000000000..2380f9f1152 --- /dev/null +++ b/tests/bluetooth/hci_uart_async/CMakeLists.txt @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +set(EXTRA_CONF_FILE + ../../../samples/bluetooth/hci_uart_async/prj.conf +) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(test_samples_bluetooth_hci_uart_async) +target_sources(app PRIVATE + ../../../samples/bluetooth/hci_uart_async/src/hci_uart_async.c + src/test_hci_uart_async.c +) diff --git a/tests/bluetooth/hci_uart_async/app.overlay b/tests/bluetooth/hci_uart_async/app.overlay new file mode 100644 index 00000000000..d9186722ba6 --- /dev/null +++ b/tests/bluetooth/hci_uart_async/app.overlay @@ -0,0 +1,11 @@ +/ { + chosen { + zephyr,bt-c2h-uart = &test_uart; + }; + + test_uart: test_uart { + compatible = "vnd,serial"; + status = "okay"; + buffer-size = <100>; + }; +}; diff --git a/tests/bluetooth/hci_uart_async/boards/native_posix.conf b/tests/bluetooth/hci_uart_async/boards/native_posix.conf new file mode 100644 index 00000000000..e638cd6a0ef --- /dev/null +++ b/tests/bluetooth/hci_uart_async/boards/native_posix.conf @@ -0,0 +1,3 @@ +# Print logs and test results on stdout. For some reason, this not the +# default when SERIAL=y. +CONFIG_LOG_BACKEND_NATIVE_POSIX=y diff --git a/tests/bluetooth/hci_uart_async/prj.conf b/tests/bluetooth/hci_uart_async/prj.conf new file mode 100644 index 00000000000..b038c7c4312 --- /dev/null +++ b/tests/bluetooth/hci_uart_async/prj.conf @@ -0,0 +1,10 @@ +CONFIG_BT_NO_DRIVER=y + +CONFIG_RING_BUFFER=y + +CONFIG_ASSERT=y +CONFIG_LOG=y +CONFIG_TEST=y + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c b/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c new file mode 100644 index 00000000000..1996aba177a --- /dev/null +++ b/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c @@ -0,0 +1,238 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(test, LOG_LEVEL_DBG); + +/* This is a mock UART. Using `serial_vnd_...` on this simulates + * traffic from the external Host. + */ +static const struct device *const zephyr_bt_c2h_uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart)); + +/* The DUT is Sandwiched between the mock serial interface and a mock + * controller. {{{ + */ +static void serial_vnd_data_callback(const struct device *dev, void *user_data); +static int drv_send(struct net_buf *buf); +static int drv_open(void); +static const struct bt_hci_driver drv = { + .name = "Mock Controller", + .bus = BT_HCI_DRIVER_BUS_VIRTUAL, + .open = drv_open, + .send = drv_send, +}; +static int sys_init_hci_driver_register(void) +{ + serial_vnd_set_callback(zephyr_bt_c2h_uart, serial_vnd_data_callback, NULL); + bt_hci_driver_register(&drv); + return 0; +} +SYS_INIT(sys_init_hci_driver_register, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +/* }}} */ + +/* Start the DUT "main thread". The settings for this thread are selected as + * true as possible to the real main thread. {{{ + */ +static struct k_thread hci_uart_thread; +static K_THREAD_PINNED_STACK_DEFINE(hci_uart_thread_stack, CONFIG_MAIN_STACK_SIZE); +static void hci_uart_thread_entry(void *p1, void *p2, void *p3) +{ + extern void hci_uart_main(void); + hci_uart_main(); +} +static int sys_init_spawn_hci_uart(void) +{ + k_thread_name_set(&hci_uart_thread, "hci_uart_main"); + k_thread_create(&hci_uart_thread, hci_uart_thread_stack, + K_THREAD_STACK_SIZEOF(hci_uart_thread_stack), hci_uart_thread_entry, NULL, + NULL, NULL, CONFIG_MAIN_THREAD_PRIORITY, 0, K_NO_WAIT); + return 0; +} +SYS_INIT(sys_init_spawn_hci_uart, POST_KERNEL, 64); +/* }}} */ + +/* Mock controller callbacks. {{{ */ + +static int drv_open(void) +{ + LOG_DBG("drv_open"); + return 0; +} + +/** This FIFO holds the references to all h2c packets the DUT has sent + * to the controller using #bt_send. + * + * Each test should mock a controller by calling #net_buf_get on this + * FIFO and simulate a controller's #bt_hci_driver::drv_send. The mocks + * should use #bt_recv to send c2h packets to the DUT. + */ +K_FIFO_DEFINE(drv_send_fifo); /* elem T: net_buf */ +static int drv_send(struct net_buf *buf) +{ + LOG_DBG("buf %p type %d len %u", buf, bt_buf_get_type(buf), buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "buf"); + + __ASSERT_NO_MSG(buf); + net_buf_put(&drv_send_fifo, buf); + return 0; +} + +/* }}} */ + +/* Mock UART c2h TX handler. {{{ */ + +static void serial_vnd_data_callback(const struct device *dev, void *user_data) +{ + uint32_t size = serial_vnd_out_data_size_get(dev); + uint8_t data[size]; + + serial_vnd_read_out_data(dev, data, size); + LOG_HEXDUMP_DBG(data, size, "uart tx"); + + /* If a test needs to look at the c2h UART traffic, it can be + * captured here. + */ +} + +/* }}} */ + +#define HCI_NORMAL_CMD_BUF_COUNT (CONFIG_BT_BUF_CMD_TX_COUNT - 1) +#define TEST_PARAM_HOST_COMPLETE_COUNT 10 +#define TIMEOUT_PRESUME_STUCK K_SECONDS(1) + +/** Corresponds to: + * - #bt_hci_cmd_hdr + */ +const uint8_t h4_msg_cmd_dummy1[] = { + 0x01, /* H4: opcode = CMD */ + 0x01, 0x00, /* H4: CMD: opcode = 1 */ + 0x00, /* H4: CMD: len = 0 */ +}; + +/** Corresponds to: + * - #bt_hci_cmd_hdr + * - #bt_hci_cp_host_num_completed_packets + */ +const uint8_t h4_msg_cmd_host_num_complete[] = { + 0x01, /* H4: opcode = CMD */ + 0x35, 0x0c, /* H4: CMD: opcode = BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS */ + 0x05, /* H4: CMD: len = 5 */ + 0x01, /* H4: CMD: num_handles = 1 */ + 0x00, 0x00, /* H4: CMD: connection_handle = 0 */ + 0x01, 0x00, /* H4: CMD: num_complete = 1 */ +}; + +/** Corresponds to: + * - #bt_hci_evt_hdr + * - #bt_hci_evt_cmd_complete + */ +const uint8_t hci_msg_rx_evt_cmd_complete[] = { + BT_HCI_EVT_CMD_COMPLETE, /* EVT: opcode */ + 0x03, /* EVT: len */ + 0x01, /* EVT: CMDC: ncmd = 1 */ + /* EVT: CMDC: opcode */ + 0x00, + 0x00, +}; + +ZTEST_SUITE(hci_uart, NULL, NULL, NULL, NULL, NULL); +ZTEST(hci_uart, test_h2c_cmd_flow_control) +{ + /* This test assumes the DUT does not care about the contents of + * the HCI messages, other than the HCI type/endpoint and the + * size. This allows the test to cheat and skip the HCI Reset, + * connection setup etc and use dummy command-packets. + */ + + /* Send commands, saturating the controller's command pipeline. */ + for (uint16_t i = 0; i < HCI_NORMAL_CMD_BUF_COUNT; i++) { + int write_size = serial_vnd_queue_in_data(zephyr_bt_c2h_uart, h4_msg_cmd_dummy1, + sizeof(h4_msg_cmd_dummy1)); + __ASSERT_NO_MSG(write_size == sizeof(h4_msg_cmd_dummy1)); + } + + /* At this point, the HCI flow control limit for the cmd + * endpoint has been reached. It will remain so until the + * controller mock has sent a 'HCI Command Complete' event. + * + * But the 'HCI Host Number of Completed Packets' command is + * exempt from HCI flow control. (It's like it has its own + * endpoint, that has no flow control.) + * + * We now send several 'HCI Host Number of Completed Packets' + * packets before handling any commands in the controller. This + * tests whether the DUT is able to engage the lower transport + * flow controller (i.e. UART flow-control) or somehow handle + * the special packets out-of-order in real-time. + */ + for (uint16_t i = 0; i < TEST_PARAM_HOST_COMPLETE_COUNT; i++) { + int write_size = + serial_vnd_queue_in_data(zephyr_bt_c2h_uart, h4_msg_cmd_host_num_complete, + sizeof(h4_msg_cmd_host_num_complete)); + __ASSERT_NO_MSG(write_size == sizeof(h4_msg_cmd_host_num_complete)); + } + + LOG_DBG("All h2c packets queued on UART"); + + /* Then, we check that all packets are delivered without loss. */ + + /* Expect all the normal commands first. */ + for (uint16_t i = 0; i < HCI_NORMAL_CMD_BUF_COUNT; i++) { + /* The mock controller processes a command. */ + { + struct net_buf *buf = net_buf_get(&drv_send_fifo, TIMEOUT_PRESUME_STUCK); + + zassert_not_null(buf); + zassert_equal(buf->len, sizeof(h4_msg_cmd_dummy1) - 1, "Wrong length"); + zassert_mem_equal(buf->data, &h4_msg_cmd_dummy1[1], + sizeof(h4_msg_cmd_dummy1) - 1); + net_buf_unref(buf); + } + + /* The controller sends a HCI Command Complete response. */ + { + int err; + struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT); + + zassert_not_null(buf); + net_buf_add_mem(buf, hci_msg_rx_evt_cmd_complete, + sizeof(hci_msg_rx_evt_cmd_complete)); + err = bt_recv(buf); + zassert_equal(err, 0, "bt_recv failed"); + } + } + + /* Expect all the 'HCI Host Number of Completed Packets'. */ + for (uint16_t i = 0; i < TEST_PARAM_HOST_COMPLETE_COUNT; i++) { + /* The mock controller processes a 'HCI Host Number of Completed Packets'. */ + { + struct net_buf *buf = net_buf_get(&drv_send_fifo, TIMEOUT_PRESUME_STUCK); + + zassert_not_null(buf); + zassert_equal(buf->len, sizeof(h4_msg_cmd_host_num_complete) - 1, + "Wrong length"); + zassert_mem_equal(buf->data, &h4_msg_cmd_host_num_complete[1], + sizeof(h4_msg_cmd_dummy1) - 2); + net_buf_unref(buf); + } + + /* There is no response to 'HCI Host Number of Completed Packets'. */ + } + + LOG_DBG("All h2c packets received by controller."); +} diff --git a/tests/bluetooth/hci_uart_async/testcase.yaml b/tests/bluetooth/hci_uart_async/testcase.yaml new file mode 100644 index 00000000000..f7f4a6255eb --- /dev/null +++ b/tests/bluetooth/hci_uart_async/testcase.yaml @@ -0,0 +1,6 @@ +tests: + samples.bluetooth.hci_uart_async: + tags: bluetooth uart + harness: ztest + platform_allow: + - native_posix From c2328a7bc30f1ca8411390b2c12a0e884cb0c5a9 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 21 Aug 2023 10:43:43 +0200 Subject: [PATCH 1254/4498] Bluetooth: ISO: Fix issue with bt_iso_cig_reconfigure bt_iso_cig_reconfigure would almost always fail due to invalid checks that did not take the functioner properly into account. The CIS provided to bt_iso_cig_reconfigure can now be allocated beforehand, if the CIG for the CIS is the same as the one being reconfigured. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/iso.c | 51 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index af408b9dd98..49dd52d0ffb 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -1720,7 +1720,7 @@ static bool is_advanced_cig_param(const struct bt_iso_cig_param *param) static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan) { - if (iso_chan->iso == NULL) { + if (iso_chan == NULL || iso_chan->iso == NULL) { return NULL; } @@ -1751,6 +1751,10 @@ static struct bt_iso_cig *get_free_cig(void) static bool cis_is_in_cig(const struct bt_iso_cig *cig, const struct bt_iso_chan *cis) { + if (cig == NULL || cis == NULL || cis->iso == NULL) { + return false; + } + return cig->id == cis->iso->iso.cig_id; } @@ -1799,7 +1803,8 @@ static void cleanup_cig(struct bt_iso_cig *cig) memset(cig, 0, sizeof(*cig)); } -static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced) +static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, + const struct bt_iso_cig *cig) { if (param == NULL) { return false; @@ -1813,8 +1818,8 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced) return false; } - if (cis->iso != NULL) { - LOG_DBG("cis_channels[%d]: already allocated", i); + if (cis->iso != NULL && !cis_is_in_cig(cig, cis)) { + LOG_DBG("cis_channels[%d]: already allocated to CIG %p", i, get_cig(cis)); return false; } @@ -1930,7 +1935,7 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, advanced = is_advanced_cig_param(param); #endif /* CONFIG_BT_ISO_ADVANCED */ - CHECKIF(!valid_cig_param(param, advanced)) { + CHECKIF(!valid_cig_param(param, advanced, NULL)) { LOG_DBG("Invalid CIG params"); return -EINVAL; } @@ -2015,11 +2020,9 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, { struct bt_hci_rp_le_set_cig_params *cig_rsp; uint8_t existing_num_cis; - struct bt_iso_chan *cis; bool advanced = false; struct net_buf *rsp; int err; - int i; CHECKIF(cig == NULL) { LOG_DBG("cig is NULL"); @@ -2035,22 +2038,11 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, advanced = is_advanced_cig_param(param); #endif /* CONFIG_BT_ISO_ADVANCED */ - CHECKIF(!valid_cig_param(param, advanced)) { + CHECKIF(!valid_cig_param(param, advanced, cig)) { LOG_DBG("Invalid CIG params"); return -EINVAL; } - for (uint8_t j = 0; j < param->num_cis; j++) { - struct bt_iso_chan *param_cis = param->cis_channels[j]; - - if (param_cis->iso != NULL && !cis_is_in_cig(cig, param_cis)) { - LOG_DBG("Cannot reconfigure other CIG's (id 0x%02X) CIS " - "with this CIG (id 0x%02X)", - param_cis->iso->iso.cig_id, cig->id); - return -EINVAL; - } - } - /* Used to restore CIG in case of error */ existing_num_cis = cig->num_cis; @@ -2078,18 +2070,27 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, cig_rsp = (void *)rsp->data; - if (rsp->len < sizeof(cig_rsp) || - cig_rsp->num_handles != param->num_cis) { - LOG_WRN("Unexpected response to hci_le_set_cig_params"); + if (rsp->len < sizeof(*cig_rsp)) { + LOG_WRN("Unexpected response len to hci_le_set_cig_params %u != %zu", rsp->len, + sizeof(*cig_rsp)); err = -EIO; net_buf_unref(rsp); restore_cig(cig, existing_num_cis); return err; } - i = 0; - SYS_SLIST_FOR_EACH_CONTAINER(&cig->cis_channels, cis, node) { - const uint16_t handle = cig_rsp->handle[i++]; + if (cig_rsp->num_handles != param->num_cis) { + LOG_WRN("Unexpected response num_handles to hci_le_set_cig_params %u != %u", + cig_rsp->num_handles, param->num_cis); + err = -EIO; + net_buf_unref(rsp); + restore_cig(cig, existing_num_cis); + return err; + } + + for (uint8_t i = 0u; i < param->num_cis; i++) { + const uint16_t handle = cig_rsp->handle[i]; + struct bt_iso_chan *cis = param->cis_channels[i]; /* Assign the connection handle */ cis->iso->handle = sys_le16_to_cpu(handle); From cbf7312e370eba63586fbd516ab9c54e62b0203f Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 28 Aug 2023 14:02:22 +0200 Subject: [PATCH 1255/4498] Bluetooth: Controller: ISO: Fix compile issue with unicast There was a case where TICKER_ID_ADV_AUX_BASE was not available but was attempted to be used. Signed-off-by: Emil Gydesen --- subsys/bluetooth/controller/ll_sw/ull_sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index 38589a2e644..4eb7687b97d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -321,7 +321,7 @@ static int group_free_slot_get(uint8_t user_id, uint32_t ticks_slot_abs, if (false) { -#if defined(CONFIG_BT_BROADCASTER) +#if defined(CONFIG_BT_BROADCASTER) && CONFIG_BT_CTLR_ADV_AUX_SET > 0 } else if (IN_RANGE(ticker_id, TICKER_ID_ADV_AUX_BASE, TICKER_ID_ADV_AUX_LAST)) { const struct ll_adv_aux_set *aux; @@ -391,7 +391,7 @@ static int group_free_slot_get(uint8_t user_id, uint32_t ticks_slot_abs, #endif /* CONFIG_BT_CTLR_ADV_ISO */ #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */ -#endif /* CONFIG_BT_BROADCASTER */ +#endif /* CONFIG_BT_BROADCASTER && CONFIG_BT_CTLR_ADV_AUX_SET > 0 */ #if defined(CONFIG_BT_CONN) } else if (IN_RANGE(ticker_id, TICKER_ID_CONN_BASE, From 0f9f528214344a6657e7e45965b28bd6ee413f76 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 28 Aug 2023 14:03:30 +0200 Subject: [PATCH 1256/4498] tests: bsim: Bluetooth: ISO: Add host CIS tests Add a simple central and peripheral CIS test that exercises the ISO host API for unicast ISO (CIS). Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/host/compile.sh | 2 + .../bluetooth/host/iso/cis/CMakeLists.txt | 18 + tests/bsim/bluetooth/host/iso/cis/prj.conf | 23 ++ .../bluetooth/host/iso/cis/src/cis_central.c | 357 ++++++++++++++++++ .../host/iso/cis/src/cis_peripheral.c | 185 +++++++++ .../bsim/bluetooth/host/iso/cis/src/common.c | 87 +++++ .../bsim/bluetooth/host/iso/cis/src/common.h | 49 +++ tests/bsim/bluetooth/host/iso/cis/src/main.c | 22 ++ .../host/iso/cis/tests_scripts/_compile.sh | 21 ++ .../host/iso/cis/tests_scripts/_env.sh | 14 + .../host/iso/cis/tests_scripts/cis.sh | 22 ++ 11 files changed, 800 insertions(+) create mode 100644 tests/bsim/bluetooth/host/iso/cis/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/iso/cis/prj.conf create mode 100644 tests/bsim/bluetooth/host/iso/cis/src/cis_central.c create mode 100644 tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c create mode 100644 tests/bsim/bluetooth/host/iso/cis/src/common.c create mode 100644 tests/bsim/bluetooth/host/iso/cis/src/common.h create mode 100644 tests/bsim/bluetooth/host/iso/cis/src/main.c create mode 100755 tests/bsim/bluetooth/host/iso/cis/tests_scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/iso/cis/tests_scripts/_env.sh create mode 100755 tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 042849587bc..1c14fb957f4 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -46,6 +46,8 @@ app=tests/bsim/bluetooth/host/gatt/ccc_store compile app=tests/bsim/bluetooth/host/gatt/ccc_store conf_file=prj_2.conf compile app=tests/bsim/bluetooth/host/gatt/sc_indicate compile +app=tests/bsim/bluetooth/host/iso/cis compile + app=tests/bsim/bluetooth/host/l2cap/general compile app=tests/bsim/bluetooth/host/l2cap/userdata compile app=tests/bsim/bluetooth/host/l2cap/stress compile diff --git a/tests/bsim/bluetooth/host/iso/cis/CMakeLists.txt b/tests/bsim/bluetooth/host/iso/cis/CMakeLists.txt new file mode 100644 index 00000000000..b856e60fcf3 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_l2cap_send_on_connect) + +target_sources(app PRIVATE + src/common.c + src/cis_central.c + src/cis_peripheral.c + src/main.c +) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/host/iso/cis/prj.conf b/tests/bsim/bluetooth/host/iso/cis/prj.conf new file mode 100644 index 00000000000..d1a1b8cd161 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/prj.conf @@ -0,0 +1,23 @@ +CONFIG_BT=y +CONFIG_LOG=y +CONFIG_ASSERT=y +CONFIG_BT_SMP=y + +CONFIG_BT_DEVICE_NAME="CIS test" + +CONFIG_BT_ISO_CENTRAL=y +CONFIG_BT_ISO_PERIPHERAL=y +CONFIG_BT_ISO_TX_BUF_COUNT=4 +CONFIG_BT_ISO_MAX_CHAN=4 +CONFIG_BT_ISO_TX_MTU=200 +CONFIG_BT_ISO_RX_MTU=200 + +CONFIG_BT_ISO_LOG_LEVEL_DBG=y + +# Controller Connected ISO configs +CONFIG_BT_CTLR_CENTRAL_ISO=y +CONFIG_BT_CTLR_PERIPHERAL_ISO=y +CONFIG_BT_CTLR_ISOAL_SOURCES=2 +CONFIG_BT_CTLR_ISOAL_SINKS=2 + +CONFIG_BT_CTLR_ISO_TX_BUFFERS=4 diff --git a/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c new file mode 100644 index 00000000000..2c16bb110f4 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +#include +#include +#include + +#define ENQUEUE_COUNT 2 + +extern enum bst_result_t bst_result; +static struct bt_iso_chan iso_chans[CONFIG_BT_ISO_MAX_CHAN]; +static struct bt_iso_chan *default_chan = &iso_chans[0]; +static struct bt_iso_cig *cig; +static uint16_t seq_num; +static volatile size_t enqueue_cnt; +static uint32_t interval_us = 10U * USEC_PER_MSEC; /* 10 ms */ +NET_BUF_POOL_FIXED_DEFINE(tx_pool, ENQUEUE_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + +BUILD_ASSERT(CONFIG_BT_ISO_MAX_CHAN > 1, "CONFIG_BT_ISO_MAX_CHAN shall be at least 2"); + +CREATE_FLAG(flag_iso_connected); + +static void send_data_cb(struct k_work *work) +{ + static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU]; + static size_t len_to_send = 1; + static bool data_initialized; + struct net_buf *buf; + int ret; + + if (!TEST_FLAG(flag_iso_connected)) { + /* TX has been aborted */ + return; + } + + if (!data_initialized) { + for (int i = 0; i < ARRAY_SIZE(buf_data); i++) { + buf_data[i] = (uint8_t)i; + } + + data_initialized = true; + } + + buf = net_buf_alloc(&tx_pool, K_FOREVER); + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + + net_buf_add_mem(buf, buf_data, len_to_send); + + ret = bt_iso_chan_send(default_chan, buf, seq_num++, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + printk("Failed to send ISO data (%d)\n", ret); + net_buf_unref(buf); + + /* Reschedule for next interval */ + k_work_reschedule(k_work_delayable_from_work(work), K_USEC(interval_us)); + + return; + } + + len_to_send++; + if (len_to_send > ARRAY_SIZE(buf_data)) { + len_to_send = 1; + } + + enqueue_cnt--; + if (enqueue_cnt > 0U) { + /* If we have more buffers available, we reschedule the workqueue item immediately + * to trigger another encode + TX, but without blocking this call for too long + */ + k_work_reschedule(k_work_delayable_from_work(work), K_NO_WAIT); + } +} +K_WORK_DELAYABLE_DEFINE(iso_send_work, send_data_cb); + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + int err; + + err = bt_le_scan_stop(); + if (err) { + FAIL("Failed to stop scanning (err %d)\n", err); + + return; + } + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, + &default_conn); + if (err) { + FAIL("Failed to create connection (err %d)\n", err); + + return; + } +} + +static void iso_connected(struct bt_iso_chan *chan) +{ + printk("ISO Channel %p connected\n", chan); + + seq_num = 0U; + enqueue_cnt = ENQUEUE_COUNT; + + /* Start send timer */ + k_work_schedule(&iso_send_work, K_MSEC(0)); + + SET_FLAG(flag_iso_connected); +} + +static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) +{ + printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason); + + k_work_cancel_delayable(&iso_send_work); + + UNSET_FLAG(flag_iso_connected); +} + +static void sdu_sent_cb(struct bt_iso_chan *chan) +{ + int err; + + enqueue_cnt++; + + if (!TEST_FLAG(flag_iso_connected)) { + /* TX has been aborted */ + return; + } + + err = k_work_schedule(&iso_send_work, K_NO_WAIT); + if (err < 0) { + FAIL("Failed to schedule TX for chan %p: %d\n", chan, err); + } +} + +static void init(void) +{ + static struct bt_iso_chan_ops iso_ops = { + .connected = iso_connected, + .disconnected = iso_disconnected, + .sent = sdu_sent_cb, + }; + static struct bt_iso_chan_io_qos iso_tx = { + .sdu = CONFIG_BT_ISO_TX_MTU, + .phy = BT_GAP_LE_PHY_2M, + .rtn = 1, + .path = NULL, + }; + static struct bt_iso_chan_qos iso_qos = { + .tx = &iso_tx, + .rx = NULL, + }; + int err; + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth enable failed (err %d)\n", err); + + return; + } + + for (size_t i = 0U; i < ARRAY_SIZE(iso_chans); i++) { + iso_chans[i].ops = &iso_ops; + iso_chans[i].qos = &iso_qos; +#if defined(CONFIG_BT_SMP) + iso_chans[i].required_sec_level = BT_SECURITY_L2; +#endif /* CONFIG_BT_SMP */ + } +} + +static void create_cig(void) +{ + struct bt_iso_cig_param param; + int err; + + param.cis_channels = &default_chan; + param.num_cis = 1U; + param.sca = BT_GAP_SCA_UNKNOWN; + param.packing = BT_ISO_PACKING_SEQUENTIAL; + param.framing = BT_ISO_FRAMING_UNFRAMED; + param.latency = 10U; /* ms */ + param.interval = interval_us; /* us */ + + err = bt_iso_cig_create(¶m, &cig); + if (err != 0) { + FAIL("Failed to create CIG (%d)\n", err); + + return; + } +} + +static void reconfigure_cig(void) +{ + struct bt_iso_chan *channels[2]; + struct bt_iso_cig_param param; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(channels); i++) { + channels[i] = &iso_chans[i]; + } + + /* Set parameters to same as the ones used to create the CIG */ + param.cis_channels = &default_chan; + param.num_cis = 1U; + param.sca = BT_GAP_SCA_UNKNOWN; + param.packing = BT_ISO_PACKING_SEQUENTIAL; + param.framing = BT_ISO_FRAMING_UNFRAMED; + param.latency = 10U; /* ms */ + param.interval = interval_us; /* us */ + + /* Test modifying existing CIS */ + default_chan->qos->tx->rtn++; + + err = bt_iso_cig_reconfigure(cig, ¶m); + if (err != 0) { + FAIL("Failed to reconfigure CIS to new RTN (%d)\n", err); + + return; + } + + /* Test modifying CIG parameter without any CIS */ + param.num_cis = 0U; + param.interval = 7500U; /* us */ + + err = bt_iso_cig_reconfigure(cig, ¶m); + if (err != 0) { + FAIL("Failed to reconfigure CIG to new interval (%d)\n", err); + + return; + } + + /* Add CIS to the CIG and restore interval to 10ms */ + param.cis_channels = &channels[1]; + param.num_cis = 1U; + param.interval = interval_us; /* us */ + + err = bt_iso_cig_reconfigure(cig, ¶m); + if (err != 0) { + FAIL("Failed to reconfigure CIG with new CIS and original interval (%d)\n", err); + + return; + } +} + +static void connect_acl(void) +{ + int err; + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err != 0) { + FAIL("Scanning failed to start (err %d)\n", err); + + return; + } + + WAIT_FOR_FLAG_SET(flag_connected); +} + +static void connect_cis(void) +{ + const struct bt_iso_connect_param connect_param = { + .acl = default_conn, + .iso_chan = default_chan, + }; + int err; + + err = bt_iso_chan_connect(&connect_param, 1); + if (err) { + FAIL("Failed to connect ISO (%d)\n", err); + + return; + } + + WAIT_FOR_FLAG_SET(flag_iso_connected); +} + +static void disconnect_cis(void) +{ + int err; + + err = bt_iso_chan_disconnect(default_chan); + if (err) { + FAIL("Failed to disconnect ISO (err %d)\n", err); + + return; + } + + WAIT_FOR_FLAG_UNSET(flag_iso_connected); +} + +static void disconnect_acl(void) +{ + int err; + + err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err) { + FAIL("Failed to disconnect ACL (err %d)\n", err); + + return; + } + + WAIT_FOR_FLAG_UNSET(flag_connected); +} + +static void terminate_cig(void) +{ + int err; + + err = bt_iso_cig_terminate(cig); + if (err != 0) { + FAIL("Failed to terminate CIG (%d)\n", err); + + return; + } + + cig = NULL; +} + +static void test_main(void) +{ + init(); + create_cig(); + reconfigure_cig(); + connect_acl(); + connect_cis(); + + while (seq_num < 100U) { + k_sleep(K_USEC(interval_us)); + } + + disconnect_cis(); + disconnect_acl(); + terminate_cig(); + + PASS("Test passed\n"); +} + +static const struct bst_test_instance test_def[] = { + { + .test_id = "central", + .test_descr = "Central", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_main_cis_central_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_def); +} diff --git a/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c b/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c new file mode 100644 index 00000000000..fdaed6ef0ed --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +#include +#include +#include + +extern enum bst_result_t bst_result; + +CREATE_FLAG(flag_iso_connected); +CREATE_FLAG(flag_data_received); + +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), +}; +static struct bt_iso_chan iso_chan; + +/** Print data as d_0 d_1 d_2 ... d_(n-2) d_(n-1) d_(n) to show the 3 first and 3 last octets + * + * Examples: + * 01 + * 0102 + * 010203 + * 01020304 + * 0102030405 + * 010203040506 + * 010203...050607 + * 010203...060708 + * etc. + */ +static void iso_print_data(uint8_t *data, size_t data_len) +{ + /* Maximum number of octets from each end of the data */ + const uint8_t max_octets = 3; + char data_str[35]; + size_t str_len; + + str_len = bin2hex(data, MIN(max_octets, data_len), data_str, sizeof(data_str)); + if (data_len > max_octets) { + if (data_len > (max_octets * 2)) { + static const char dots[] = "..."; + + strcat(&data_str[str_len], dots); + str_len += strlen(dots); + } + + str_len += bin2hex(data + (data_len - MIN(max_octets, data_len - max_octets)), + MIN(max_octets, data_len - max_octets), data_str + str_len, + sizeof(data_str) - str_len); + } + + printk("\t %s\n", data_str); +} + +static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + if (info->flags & BT_ISO_FLAGS_VALID) { + printk("Incoming data channel %p len %u\n", chan, buf->len); + iso_print_data(buf->data, buf->len); + SET_FLAG(flag_data_received); + } +} + +static void iso_connected(struct bt_iso_chan *chan) +{ + printk("ISO Channel %p connected\n", chan); + + SET_FLAG(flag_iso_connected); +} + +static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) +{ + printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason); + + UNSET_FLAG(flag_iso_connected); +} + +static int iso_accept(const struct bt_iso_accept_info *info, struct bt_iso_chan **chan) +{ + printk("Incoming request from %p\n", (void *)info->acl); + + if (iso_chan.iso) { + FAIL("No channels available\n"); + + return -ENOMEM; + } + + *chan = &iso_chan; + + return 0; +} + +static void init(void) +{ + static struct bt_iso_chan_io_qos iso_rx = { + .sdu = CONFIG_BT_ISO_TX_MTU, + .path = NULL, + }; + static struct bt_iso_server iso_server = { +#if defined(CONFIG_BT_SMP) + .sec_level = BT_SECURITY_L2, +#endif /* CONFIG_BT_SMP */ + .accept = iso_accept, + }; + static struct bt_iso_chan_ops iso_ops = { + .recv = iso_recv, + .connected = iso_connected, + .disconnected = iso_disconnected, + }; + static struct bt_iso_chan_qos iso_qos = { + .rx = &iso_rx, + .tx = NULL, + }; + int err; + + err = bt_enable(NULL); + if (err) { + FAIL("Bluetooth enable failed (err %d)\n", err); + + return; + } + + iso_chan.ops = &iso_ops; + iso_chan.qos = &iso_qos; +#if defined(CONFIG_BT_SMP) + iso_chan.required_sec_level = BT_SECURITY_L2, +#endif /* CONFIG_BT_SMP */ + + err = bt_iso_server_register(&iso_server); + if (err) { + FAIL("Unable to register ISO server (err %d)\n", err); + + return; + } +} + +static void adv_connect(void) +{ + int err; + + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); + if (err) { + FAIL("Advertising failed to start (err %d)\n", err); + + return; + } + + printk("Advertising successfully started\n"); + + WAIT_FOR_FLAG_SET(flag_connected); +} + +static void test_main(void) +{ + init(); + adv_connect(); + WAIT_FOR_FLAG_SET(flag_iso_connected); + WAIT_FOR_FLAG_SET(flag_data_received); + WAIT_FOR_FLAG_UNSET(flag_iso_connected); + WAIT_FOR_FLAG_UNSET(flag_connected); + + PASS("Test passed\n"); +} + +static const struct bst_test_instance test_def[] = { + { + .test_id = "peripheral", + .test_descr = "Peripheral", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_main_cis_peripheral_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_def); +} diff --git a/tests/bsim/bluetooth/host/iso/cis/src/common.c b/tests/bsim/bluetooth/host/iso/cis/src/common.c new file mode 100644 index 00000000000..ef1a4e9f9dd --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/src/common.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include + +#include "common.h" + +extern enum bst_result_t bst_result; +struct bt_conn *default_conn; +atomic_t flag_connected; +atomic_t flag_conn_updated; + +static void connected(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (default_conn == NULL) { + default_conn = bt_conn_ref(conn); + } + + if (err != 0) { + bt_conn_unref(default_conn); + default_conn = NULL; + + FAIL("Failed to connect to %s (0x%02x)\n", addr, err); + + return; + } + + printk("Connected to %s\n", addr); + SET_FLAG(flag_connected); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != default_conn) { + return; + } + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Disconnected: %s (reason 0x%02x)\n", addr, reason); + + bt_conn_unref(default_conn); + default_conn = NULL; + UNSET_FLAG(flag_connected); + UNSET_FLAG(flag_conn_updated); +} + +static void conn_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout) +{ + printk("Connection parameter updated: %p 0x%04X (%u us), 0x%04X, 0x%04X\n", conn, interval, + BT_CONN_INTERVAL_TO_US(interval), latency, timeout); + + SET_FLAG(flag_conn_updated); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, + .le_param_updated = conn_param_updated_cb, +}; + +void test_init(void) +{ + bst_result = In_progress; + bst_ticker_set_next_tick_absolute(WAIT_TIME); +} + +void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + FAIL("Test failed (not passed after %i us)\n", WAIT_TIME); + } +} diff --git a/tests/bsim/bluetooth/host/iso/cis/src/common.h b/tests/bsim/bluetooth/host/iso/cis/src/common.h new file mode 100644 index 00000000000..0b41515d223 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/src/common.h @@ -0,0 +1,49 @@ +/* + * Common functions and helpers for ISO tests + * + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include "bs_types.h" +#include "bs_tracing.h" +#include "bstests.h" + +#define CREATE_FLAG(flag) static atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) +#define TEST_FLAG(flag) (atomic_get(&flag) == (atomic_t) true) +#define WAIT_FOR_FLAG_SET(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG_UNSET(flag) \ + while ((bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#define WAIT_TIME (30e6) /* 30 seconds*/ + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +extern struct bt_conn *default_conn; +extern atomic_t flag_connected; +extern atomic_t flag_conn_updated; + +void test_init(void); +void test_tick(bs_time_t HW_device_time); diff --git a/tests/bsim/bluetooth/host/iso/cis/src/main.c b/tests/bsim/bluetooth/host/iso/cis/src/main.c new file mode 100644 index 00000000000..0c30d4b3b45 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/src/main.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" + +extern struct bst_test_list *test_main_cis_peripheral_install(struct bst_test_list *tests); +extern struct bst_test_list *test_main_cis_central_install(struct bst_test_list *tests); + +bst_test_install_t test_installers[] = { + test_main_cis_central_install, + test_main_cis_peripheral_install, + NULL, +}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_compile.sh b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_compile.sh new file mode 100755 index 00000000000..f1803766794 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_compile.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +source "${bash_source_dir}/_env.sh" + +: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" +: "${BSIM_COMPONENTS_PATH:?BSIM_COMPONENTS_PATH must be defined}" +: "${ZEPHYR_BASE:?ZEPHYR_BASE must be defined}" + +WORK_DIR="${WORK_DIR:-${ZEPHYR_BASE}/bsim_out}" +BOARD="${BOARD:-nrf52_bsim}" +BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" +INCR_BUILD=1 +mkdir -p ${WORK_DIR} + +west build -b nrf52_bsim +cp build/zephyr/zephyr.exe $central_exe diff --git a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_env.sh b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_env.sh new file mode 100755 index 00000000000..f595a2006e3 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/_env.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +test_name="$(basename "$(realpath "$bash_source_dir/..")")" +bsim_bin="${BSIM_OUT_PATH}/bin" +verbosity_level=2 +BOARD="${BOARD:-nrf52_bsim}" +simulation_id="$test_name" +central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_iso_cis_prj_conf" +peripheral_exe="${central_exe}" diff --git a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh new file mode 100755 index 00000000000..258da046f70 --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="l2cap_send_on_connect" +verbosity_level=2 +EXECUTE_TIMEOUT=120 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_iso_cis_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_iso_cis_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs From 4ab658be420901f078b6bec93cf76bd5052c2049 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 7 Sep 2023 13:53:47 +0200 Subject: [PATCH 1257/4498] tests: Bluetooth: Add inval testing of bt_bap_broadcast_source_reconfigure Add invalid parameter and state testing of bt_bap_broadcast_source_reconfigure Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 438 ++++++++++++++++++ 1 file changed, 438 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index c00cf2c1cf3..ee7c4989de1 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -305,3 +305,441 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure) zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); fixture->source = NULL; } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval_param_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_reconfig(fixture->source, NULL); + zassert_not_equal(0, err, "Did not fail with null params"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval_source_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_reconfig(NULL, param); + zassert_not_equal(0, err, "Did not fail with null source"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_count_0) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + param->params_count = 0U; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with params_count %u", param->params_count); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_count_above_max) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + param->params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT + 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with params_count %u", param->params_count); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + param->params = NULL; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + param->params = subgroup_params; + zassert_not_equal(0, err, "Did not fail with NULL subgroup params"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval_qos_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_audio_codec_qos *qos = param->qos; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + param->qos = NULL; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + param->qos = qos; + zassert_not_equal(0, err, "Did not fail with NULL qos"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval_packing) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + param->packing = 0x02; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with packing %u", param->packing); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_params_count_0) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + subgroup_params->params_count = 0U; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with %u stream params", + subgroup_params->params_count); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_params_count_above_max) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + subgroup_params->params_count = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT + 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with %u stream params", + subgroup_params->params_count); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_stream_params_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + subgroup_params->params = NULL; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + subgroup_params->params = stream_params; + zassert_not_equal(0, err, "Did not fail with NULL stream params"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_codec_cfg_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + subgroup_params->codec_cfg = NULL; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + subgroup_params->codec_cfg = codec_cfg; + zassert_not_equal(0, err, "Did not fail with NULL codec_cfg"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_codec_cfg_data_len) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + codec_cfg->data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with codec_cfg->data_len %zu", codec_cfg->data_len); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_codec_cfg_meta_len) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + codec_cfg->meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with codec_cfg->meta_len %zu", codec_cfg->meta_len); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_codec_cfg_cid) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + codec_cfg->id = 0x06; + codec_cfg->cid = 0x01; /* Shall be 0 if id == 0x06 (LC3)*/ + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with codec_cfg->cid %u", codec_cfg->cid); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_subgroup_params_codec_cfg_vid) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + codec_cfg->id = 0x06; + codec_cfg->vid = 0x01; /* Shall be 0 if id == 0x06 (LC3)*/ + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with codec_cfg->vid %u", codec_cfg->vid); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_stream_params_stream_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + struct bt_bap_stream *stream = stream_params->stream; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + stream_params->stream = NULL; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + stream_params->stream = stream; + zassert_not_equal(0, err, "Did not fail with NULL stream_params->stream"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_stream_params_data_null) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + uint8_t *data = stream_params->data; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + stream_params->data = NULL; + stream_params->data_len = 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + /* Restore the params for the cleanup after function */ + stream_params->data = data; + zassert_not_equal( + 0, err, + "Did not fail with NULL stream_params->data and stream_params_>data_len %zu", + stream_params->data_len); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_reconfigure_inval_stream_params_data_len) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = ¶m->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + stream_params->data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + err = bt_bap_broadcast_source_reconfig(fixture->source, param); + zassert_not_equal(0, err, "Did not fail with stream_params_>data_len %zu", + stream_params->data_len); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval_state) +{ + struct bt_bap_broadcast_source_param *param = fixture->param; + struct bt_bap_broadcast_source *source; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + source = fixture->source; + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; + + err = bt_bap_broadcast_source_reconfig(source, param); + zassert_not_equal(0, err, "Did not fail with deleted broadcast source"); +} From b470e82a95a2107a1d8da48255b0e99dfba2a85d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 7 Sep 2023 14:06:18 +0200 Subject: [PATCH 1258/4498] tests: bsim: Bluetooth: Remove broadcast_source_reconfigure_inval Removed the tests for invalid bt_bap_broadcast_source_reconfigure parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 420 ------------------ 1 file changed, 420 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index b43bd6f3a5e..138cd6e1bfc 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -737,424 +737,6 @@ static int setup_extended_adv(struct bt_bap_broadcast_source *source, struct bt_ return 0; } -static void test_broadcast_source_reconfig_inval_state(struct bt_bap_broadcast_source *source) -{ - uint8_t bis_codec_data[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_FREQ, - BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ)), - }; - struct bt_bap_broadcast_source_stream_param - stream_params[ARRAY_SIZE(broadcast_source_streams)]; - struct bt_bap_broadcast_source_subgroup_param - subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; - struct bt_bap_broadcast_source_param reconfig_param; - int err; - - for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) { - stream_params[i].stream = &broadcast_source_streams[i]; - bt_bap_stream_cb_register(stream_params[i].stream, &stream_ops); - stream_params[i].data_len = sizeof(bis_codec_data); - stream_params[i].data = bis_codec_data; - } - - for (size_t i = 0U; i < ARRAY_SIZE(subgroup_params); i++) { - subgroup_params[i].params_count = 1U; - subgroup_params[i].params = &stream_params[i]; - subgroup_params[i].codec_cfg = &preset_16_2_2.codec_cfg; - } - - reconfig_param.params_count = ARRAY_SIZE(subgroup_params); - reconfig_param.params = subgroup_params; - reconfig_param.qos = &preset_16_2_2.qos; - reconfig_param.packing = BT_ISO_PACKING_SEQUENTIAL; - reconfig_param.encryption = false; - - printk("Test bt_bap_broadcast_source_reconfig in stopped state\n"); - err = bt_bap_broadcast_source_reconfig(source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig in stopped state did not fail\n"); - return; - } -} - -static void -test_broadcast_source_reconfig_inval_stream_param(struct bt_bap_broadcast_source *broadcast_source) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param reconfig_param; - struct bt_bap_broadcast_source_stream_param stream_param; - int err; - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Set data NULL while count is 1 */ - stream_param.data = NULL; - - printk("Test bt_bap_broadcast_source_reconfig with NULL stream_param\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param data did not " - "fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Initialize codec configuration data that is too large */ - stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_reconfig with stream_param.data_len %zu\n", - stream_param.data_len); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with stream_param data count %u " - "did not fail\n", - stream_param.data_len); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Set stream to NULL */ - stream_param.stream = NULL; - - printk("Test bt_bap_broadcast_source_reconfig with NULL stream_param.stream\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param stream " - "did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { - uint8_t bis_codec_data[sizeof(sizeof(valid_bis_codec_data))]; - - memcpy(bis_codec_data, valid_bis_codec_data, sizeof(valid_bis_codec_data)); - - /* Set LTV data to invalid size */ - stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - stream_param.data = bis_codec_data; - - printk("Test bt_bap_broadcast_source_reconfig with CC LTV size %zu\n", - sizeof(bis_codec_data)); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with CC LTV size %zu in " - "stream_param did not fail\n", - sizeof(bis_codec_data)); - return; - } - } -} - -static void test_broadcast_source_reconfig_inval_subgroup_codec_param( - struct bt_bap_broadcast_source *broadcast_source) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param reconfig_param; - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_audio_codec_cfg codec_cfg; - int err; - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); - - codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_reconfig with codec.data_len %zu\n", - codec_cfg.data_len); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high codec data len %zu did not " - "fail\n", codec_cfg.data_len); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); - - codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_reconfig with codec.meta_len %zu\n", - codec_cfg.meta_len); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high codec meta len %u did not " - "fail\n", codec_cfg.meta_len); - return; - } - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, - sizeof(preset_16_2_1.codec_cfg)); - - /* Set LTV data to invalid size */ - codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_reconfig with CC LTV len %u\n", - codec_cfg.data_len); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with CC LTV len %zu in " - "subgroup_param did not fail\n", - codec_cfg.data_len); - return; - } - } - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE < 255) { - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, - sizeof(preset_16_2_1.codec_cfg)); - - /* Set LTV data to invalid size */ - codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_reconfig with meta LTV size %u\n", - codec_cfg.meta_len); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with meta LTV size %zu in " - "subgroup_param did not fail\n", - codec_cfg.meta_len); - return; - } - } -} - -static void test_broadcast_source_reconfig_inval_subgroup_param( - struct bt_bap_broadcast_source *broadcast_source) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param reconfig_param; - struct bt_bap_broadcast_source_stream_param stream_param; - int err; - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Set count to 0 */ - subgroup_param.params_count = 0; - - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with 0 stream_param count did not fail\n"); - return; - } - - /* Set count higher than max */ - subgroup_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT + 1; - - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high stream_param count did not " - "fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Set params to NULL */ - subgroup_param.params = NULL; - - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL stream_param did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - - /* Set codec to NULL */ - subgroup_param.codec_cfg = NULL; - - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL codec did not fail\n"); - return; - } - - /* Invalid codec values */ - test_broadcast_source_reconfig_inval_subgroup_codec_param(broadcast_source); -} - -static void test_broadcast_source_reconfig_inval(struct bt_bap_broadcast_source *broadcast_source) -{ - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param reconfig_param; - struct bt_audio_codec_qos qos; - int err; - - /* Test NULL parameters */ - - printk("Test bt_bap_broadcast_source_reconfig with NULL broadcast source\n"); - err = bt_bap_broadcast_source_reconfig(NULL, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL broadcast source did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_reconfig with NULL param\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL param did not fail\n"); - return; - } - - /* Test stream_param values */ - test_broadcast_source_reconfig_inval_stream_param(broadcast_source); - - /* Test invalid subgroup_param values*/ - test_broadcast_source_reconfig_inval_subgroup_param(broadcast_source); - - /* Invalid reconfig_param values */ - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - reconfig_param.params_count = 0; - - printk("Test bt_bap_broadcast_source_reconfig with 0 params_count\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with 0 params_count did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - reconfig_param.params = NULL; - - printk("Test bt_bap_broadcast_source_reconfig with NULL params\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL params did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - reconfig_param.packing = 0x35; - - printk("Test bt_bap_broadcast_source_reconfig with packing 0x%02X\n", - reconfig_param.packing); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with invalid packing did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - reconfig_param.qos = NULL; - - printk("Test bt_bap_broadcast_source_reconfig with NULL qos\n"); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with NULL qos did not fail\n"); - return; - } - - /* Invalid QoS values */ - broadcast_source_inval_reset_param(&reconfig_param, &subgroup_param, &stream_param); - reconfig_param.qos = memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - qos.phy = BT_AUDIO_CODEC_QOS_CODED + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.phy 0x%02X\n", qos.phy); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with invalid PHY did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.framing = BT_AUDIO_CODEC_QOS_FRAMING_FRAMED + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.framing 0x%02X\n", qos.framing); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with invalid framing did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.rtn = BT_ISO_BROADCAST_RTN_MAX + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.rtn 0x%02X\n", qos.rtn); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with invalid RTN did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.sdu = BT_ISO_MAX_SDU + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.sdu 0x%02X\n", qos.sdu); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with invalid SDU size did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.latency = BT_ISO_LATENCY_MIN - 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.latency 0x%02X\n", qos.latency); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too low latency did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.latency = BT_ISO_LATENCY_MAX + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.latency 0x%02X\n", qos.latency); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high latency did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.interval = BT_ISO_SDU_INTERVAL_MIN - 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.interval 0x%02X\n", qos.interval); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too low interval did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.interval = BT_ISO_SDU_INTERVAL_MAX + 1; - - printk("Test bt_bap_broadcast_source_reconfig with qos.interval 0x%02X\n", qos.interval); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with too high interval did not fail\n"); - return; - } - - reconfig_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT + 1; - - printk("Test bt_bap_broadcast_source_reconfig with %zu subgroups\n", - reconfig_param.params_count); - err = bt_bap_broadcast_source_reconfig(broadcast_source, &reconfig_param); - if (err == 0) { - FAIL("bt_bap_broadcast_source_reconfig with %zu subgroups did not fail\n", - reconfig_param.params_count); - return; - } -} - static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *source) { uint8_t bis_codec_data[] = { @@ -1348,11 +930,9 @@ static void test_main(void) return; } - test_broadcast_source_reconfig_inval(source); test_broadcast_source_reconfig(source); test_broadcast_source_start(source, adv); - test_broadcast_source_reconfig_inval_state(source); /* Initialize sending */ for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { From 8e5898f0398fac310581a1d983765055e24db801 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Wed, 30 Aug 2023 13:33:57 +0200 Subject: [PATCH 1259/4498] bluetooth: tester: VCP Client tests Add support for VCP Client tests Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/overlay-le-audio.conf | 4 + tests/bluetooth/tester/src/btp/btp.h | 4 +- tests/bluetooth/tester/src/btp/btp_vcp.h | 115 ++++ tests/bluetooth/tester/src/btp/btp_vocs.h | 38 ++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_core.c | 8 +- tests/bluetooth/tester/src/btp_vcp.c | 659 ++++++++++++++++++- 7 files changed, 824 insertions(+), 7 deletions(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_vcp.h diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index d925d805826..4478c9e7c21 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -54,6 +54,10 @@ CONFIG_BT_VCP_VOL_REND=y CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT=2 CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT=2 CONFIG_BT_VCP_VOL_REND_LOG_LEVEL_DBG=y +CONFIG_BT_VCP_VOL_CTLR=y +CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST=1 +CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST=1 +CONFIG_BT_VCP_VOL_CTLR_LOG_LEVEL_DBG=y # IAS CONFIG_BT_IAS=y diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index bc4092c7926..c4d52c161fd 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -28,6 +28,7 @@ #include "btp_micp.h" #include "btp_mics.h" #include "btp_ccp.h" +#include "btp_vcp.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -55,8 +56,9 @@ #define BTP_SERVICE_ID_CSIS 17 #define BTP_SERVICE_ID_MICS 18 #define BTP_SERVICE_ID_CCP 19 +#define BTP_SERVICE_ID_VCP 20 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CCP +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_VCP #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/tests/bluetooth/tester/src/btp/btp_vcp.h b/tests/bluetooth/tester/src/btp/btp_vcp.h new file mode 100644 index 00000000000..1b0a729d20e --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_vcp.h @@ -0,0 +1,115 @@ +/* btp_vcp.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define BTP_VCP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_vcp_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_VCP_VOL_CTLR_DISCOVER 0x02 +struct btp_vcp_discover_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_STATE_READ 0x03 +struct btp_vcp_state_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_FLAGS_READ 0x04 +struct btp_vcp_flags_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_VOL_DOWN 0x05 +struct btp_vcp_ctlr_vol_down_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_VOL_UP 0x06 +struct btp_vcp_ctlr_vol_up_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_UNMUTE_VOL_DOWN 0x07 +struct btp_vcp_ctlr_unmute_vol_down_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_UNMUTE_VOL_UP 0x08 +struct btp_vcp_ctlr_unmute_vol_up_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_SET_VOL 0x09 +struct btp_vcp_ctlr_set_vol_cmd { + bt_addr_le_t address; + uint8_t volume; +} __packed; + +#define BTP_VCP_VOL_CTLR_UNMUTE 0x0a +struct btp_vcp_ctlr_unmute_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VCP_VOL_CTLR_MUTE 0x0b +struct btp_vcp_ctlr_mute_cmd { + bt_addr_le_t address; +} __packed; + +/* VCP events */ +#define BTP_VCP_DISCOVERED_EV 0x80 +struct btp_vcp_discovered_ev { + bt_addr_le_t address; + uint8_t att_status; + struct { + uint16_t control_handle; + uint16_t flag_handle; + uint16_t state_handle; + } vcs_handles; + + struct { + uint16_t state_handle; + uint16_t location_handle; + uint16_t control_handle; + uint16_t desc_handle; + } vocs_handles; + + struct { + uint16_t state_handle; + uint16_t gain_handle; + uint16_t type_handle; + uint16_t status_handle; + uint16_t control_handle; + uint16_t desc_handle; + } aics_handles; +} __packed; + +#define BTP_VCP_STATE_EV 0x81 +struct btp_vcp_state_ev { + bt_addr_le_t address; + uint8_t att_status; + uint8_t volume; + uint8_t mute; +} __packed; + +#define BTP_VCP_FLAGS_EV 0x82 +struct btp_vcp_volume_flags_ev { + bt_addr_le_t address; + uint8_t att_status; + uint8_t flags; +} __packed; + +#define BTP_VCP_PROCEDURE_EV 0x83 +struct btp_vcp_procedure_ev { + bt_addr_le_t address; + uint8_t att_status; + uint8_t opcode; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/btp_vocs.h b/tests/bluetooth/tester/src/btp/btp_vocs.h index cb9621c9454..e5beb6805fe 100644 --- a/tests/bluetooth/tester/src/btp/btp_vocs.h +++ b/tests/bluetooth/tester/src/btp/btp_vocs.h @@ -15,6 +15,7 @@ struct btp_vocs_read_supported_commands_rp { #define BTP_VOCS_UPDATE_LOC 0x02 struct btp_vocs_audio_loc_cmd { + bt_addr_le_t address; uint32_t loc; } __packed; @@ -23,3 +24,40 @@ struct btp_vocs_audio_desc_cmd { uint8_t desc_len; uint8_t desc[0]; } __packed; + +#define BTP_VOCS_STATE_GET 0x04 +struct btp_vocs_state_get_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VOCS_LOCATION_GET 0x05 +struct btp_vocs_location_get_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_VOCS_OFFSET_STATE_SET 0x06 +struct btp_vocs_offset_set_cmd { + bt_addr_le_t address; + int16_t offset; +} __packed; + +#define BTP_VOCS_OFFSET_STATE_EV 0x80 +struct btp_vocs_offset_state_ev { + bt_addr_le_t address; + uint8_t att_status; + int16_t offset; +} __packed; + +#define BTP_VOCS_AUDIO_LOCATION_EV 0x81 +struct btp_vocs_audio_location_ev { + bt_addr_le_t address; + uint8_t att_status; + uint32_t location; +} __packed; + +#define BTP_VOCS_PROCEDURE_EV 0x82 +struct btp_vocs_procedure_ev { + bt_addr_le_t address; + uint8_t att_status; + uint8_t opcode; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 63d70c825b7..8e30da571e1 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -101,3 +101,6 @@ uint8_t tester_unregister_mics(void); uint8_t tester_init_ccp(void); uint8_t tester_unregister_ccp(void); + +uint8_t tester_init_vcp(void); +uint8_t tester_unregister_vcp(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index c8c541e9dac..d9fc85f353b 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -86,6 +86,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_TBS_CLIENT) tester_set_bit(rp->data, BTP_SERVICE_ID_CCP); #endif /* CONFIG_BT_TBS_CLIENT */ +#if defined(CONFIG_BT_VCP_VOL_CTLR) + tester_set_bit(rp->data, BTP_SERVICE_ID_VCP); +#endif /* CONFIG_BT_VCP_VOL_CTLR */ *rsp_len = sizeof(*rp) + 2; @@ -125,7 +128,7 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_mesh(); break; #endif /* CONFIG_BT_MESH */ -#if defined(CONFIG_BT_VCP_VOL_REND) +#if defined(CONFIG_BT_VCP_VOL_REND) || defined(CONFIG_BT_VCP_VOL_CTLR) case BTP_SERVICE_ID_VCS: status = tester_init_vcs(); break; @@ -135,6 +138,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_AICS: status = tester_init_aics(); break; + case BTP_SERVICE_ID_VCP: + status = tester_init_vcp(); + break; #endif /* CONFIG_BT_VCP_VOL_REND */ #if defined(CONFIG_BT_IAS) case BTP_SERVICE_ID_IAS: diff --git a/tests/bluetooth/tester/src/btp_vcp.c b/tests/bluetooth/tester/src/btp_vcp.c index ef8f2b9c97c..04e82c35807 100644 --- a/tests/bluetooth/tester/src/btp_vcp.c +++ b/tests/bluetooth/tester/src/btp_vcp.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -14,21 +15,53 @@ #include #include #include +#include "btp/btp.h" #include <../../subsys/bluetooth/audio/micp_internal.h> #include <../../subsys/bluetooth/audio/aics_internal.h> +#include <../../subsys/bluetooth/audio/vcp_internal.h> +#include <../../subsys/bluetooth/audio/vocs_internal.h> #include + #define LOG_MODULE_NAME bttester_vcp LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); -#include "btp/btp.h" - #define BT_AICS_MAX_INPUT_DESCRIPTION_SIZE 16 #define BT_AICS_MAX_OUTPUT_DESCRIPTION_SIZE 16 static struct bt_vcp_vol_rend_register_param vcp_register_param; +static struct bt_vcp_vol_ctlr *vol_ctlr; static struct bt_vcp_included included; extern struct btp_aics_instance aics_server_instance; +extern struct btp_aics_instance aics_client_instance; +extern struct bt_aics_cb aics_client_cb; + +struct service_handles { + struct { + uint16_t ctrl_pt; + uint16_t flags; + uint16_t state; + } vcp_handles; + + struct { + uint16_t state; + uint16_t location; + uint16_t control; + uint16_t desc; + } vocs_handles; + + struct { + uint16_t mute; + uint16_t state; + uint16_t gain; + uint16_t type; + uint16_t status; + uint16_t control; + uint16_t desc; + } aics_handles; +}; + +struct service_handles chrc_handles; /* Volume Control Service */ static uint8_t vcs_supported_commands(const void *cmd, uint16_t cmd_len, @@ -170,6 +203,9 @@ static uint8_t vocs_supported_commands(const void *cmd, uint16_t cmd_len, tester_set_bit(rp->data, BTP_VOCS_READ_SUPPORTED_COMMANDS); tester_set_bit(rp->data, BTP_VOCS_UPDATE_LOC); tester_set_bit(rp->data, BTP_VOCS_UPDATE_DESC); + tester_set_bit(rp->data, BTP_VOCS_STATE_GET); + tester_set_bit(rp->data, BTP_VOCS_LOCATION_GET); + tester_set_bit(rp->data, BTP_VOCS_OFFSET_STATE_SET); *rsp_len = sizeof(*rp) + 1; @@ -198,6 +234,87 @@ static struct bt_vocs_cb vocs_cb = { .description = vocs_description_cb }; +static void btp_send_vocs_state_ev(struct bt_conn *conn, uint8_t att_status, int16_t offset) +{ + struct btp_vocs_offset_state_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.offset = sys_cpu_to_le16(offset); + + tester_event(BTP_SERVICE_ID_VOCS, BTP_VOCS_OFFSET_STATE_EV, &ev, sizeof(ev)); +} + +static void btp_send_vocs_location_ev(struct bt_conn *conn, uint8_t att_status, uint32_t location) +{ + struct btp_vocs_audio_location_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.location = sys_cpu_to_le32(location); + + tester_event(BTP_SERVICE_ID_VOCS, BTP_VOCS_AUDIO_LOCATION_EV, &ev, sizeof(ev)); +} + +static void btp_send_vocs_procedure_ev(struct bt_conn *conn, uint8_t att_status, uint8_t opcode) +{ + struct btp_vocs_procedure_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.opcode = opcode; + + tester_event(BTP_SERVICE_ID_VOCS, BTP_VOCS_PROCEDURE_EV, &ev, sizeof(ev)); +} + +static void vcp_vocs_state_cb(struct bt_vocs *inst, int err, int16_t offset) +{ + struct bt_conn *conn; + + bt_vocs_client_conn_get(inst, &conn); + btp_send_vocs_state_ev(conn, err, offset); + + LOG_DBG("VOCS Offset State callback"); +} + +static void vcp_vocs_location_cb(struct bt_vocs *inst, int err, uint32_t location) +{ + struct bt_conn *conn; + + bt_vocs_client_conn_get(inst, &conn); + btp_send_vocs_location_ev(conn, err, location); + + LOG_DBG("VOCS location callback err (%d)", err); +} + +static void vcp_vocs_description_cb(struct bt_vocs *inst, int err, + char *description) +{ + LOG_DBG("VOCS desctripion callback (%d)", err); +} + +static void vcp_vocs_set_offset_cb(struct bt_vocs *inst, int err) +{ + struct bt_conn *conn; + + bt_vocs_client_conn_get(inst, &conn); + btp_send_vocs_procedure_ev(conn, err, BTP_VOCS_OFFSET_STATE_SET); + + LOG_DBG("VOCS Set Offset callback (%d)", err); +} + +static struct bt_vocs_cb vocs_cl_cb = { + .state = vcp_vocs_state_cb, + .location = vcp_vocs_location_cb, + .description = vcp_vocs_description_cb, +#if defined(CONFIG_BT_VOCS_CLIENT) + .set_offset = vcp_vocs_set_offset_cb +#endif /* CONFIG_BT_VOCS_CLIENT */ +}; + static uint8_t vocs_audio_desc(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -225,13 +342,12 @@ static uint8_t vocs_audio_desc(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -static uint8_t vocs_audio_loc(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) +static uint8_t vocs_audio_loc(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { const struct btp_vocs_audio_loc_cmd *cp = cmd; uint32_t loc = sys_le32_to_cpu(cp->loc); - for (int i = 0; i < CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT; i++) { + for (uint8_t i = 0; i < included.vocs_cnt; i++) { if (bt_vocs_location_set(included.vocs[i], loc) != 0) { return BTP_STATUS_FAILED; } @@ -240,6 +356,51 @@ static uint8_t vocs_audio_loc(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t vocs_state_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("Volume Offset Control Service offset state get"); + + err = bt_vocs_state_get(included.vocs[0]); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vocs_state_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_vocs_offset_set_cmd *cp = cmd; + int16_t offset = sys_le16_to_cpu(cp->offset); + int err; + + LOG_DBG("VCP CTLR Set absolute volume %d", offset); + + err = bt_vocs_state_set(included.vocs[0], cp->offset); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vocs_audio_location_get(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int err; + + LOG_DBG("Volume Offset Control Service Audio Location get"); + + err = bt_vocs_location_get(included.vocs[0]); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + static const struct btp_handler vocs_handlers[] = { { .opcode = BTP_VOCS_READ_SUPPORTED_COMMANDS, @@ -257,6 +418,21 @@ static const struct btp_handler vocs_handlers[] = { .expect_len = sizeof(struct btp_vocs_audio_loc_cmd), .func = vocs_audio_loc, }, + { + .opcode = BTP_VOCS_STATE_GET, + .expect_len = sizeof(struct btp_vocs_state_get_cmd), + .func = vocs_state_get, + }, + { + .opcode = BTP_VOCS_LOCATION_GET, + .expect_len = sizeof(struct btp_vocs_location_get_cmd), + .func = vocs_audio_location_get, + }, + { + .opcode = BTP_VOCS_OFFSET_STATE_SET, + .expect_len = sizeof(struct btp_vocs_offset_set_cmd), + .func = vocs_state_set, + }, }; /* AICS Callbacks */ @@ -378,3 +554,476 @@ uint8_t tester_unregister_vocs(void) { return BTP_STATUS_SUCCESS; } + +/* Volume Control Profile */ +static void btp_send_vcp_found_ev(struct bt_conn *conn, uint8_t att_status, + const struct service_handles *chrc_handles) +{ + struct btp_vcp_discovered_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.vcs_handles.control_handle = sys_cpu_to_le16(chrc_handles->vcp_handles.ctrl_pt); + ev.vcs_handles.flag_handle = sys_cpu_to_le16(chrc_handles->vcp_handles.flags); + ev.vcs_handles.state_handle = sys_cpu_to_le16(chrc_handles->vcp_handles.state); + ev.vocs_handles.state_handle = sys_cpu_to_le16(chrc_handles->vocs_handles.state); + ev.vocs_handles.location_handle = sys_cpu_to_le16(chrc_handles->vocs_handles.location); + ev.vocs_handles.control_handle = sys_cpu_to_le16(chrc_handles->vocs_handles.control); + ev.vocs_handles.desc_handle = sys_cpu_to_le16(chrc_handles->vocs_handles.desc); + ev.aics_handles.state_handle = sys_cpu_to_le16(chrc_handles->aics_handles.state); + ev.aics_handles.gain_handle = sys_cpu_to_le16(chrc_handles->aics_handles.gain); + ev.aics_handles.type_handle = sys_cpu_to_le16(chrc_handles->aics_handles.type); + ev.aics_handles.status_handle = sys_cpu_to_le16(chrc_handles->aics_handles.status); + ev.aics_handles.control_handle = sys_cpu_to_le16(chrc_handles->aics_handles.control); + ev.aics_handles.desc_handle = sys_cpu_to_le16(chrc_handles->aics_handles.desc); + + tester_event(BTP_SERVICE_ID_VCP, BTP_VCP_DISCOVERED_EV, &ev, sizeof(ev)); +} + +static void btp_send_vcp_state_ev(struct bt_conn *conn, uint8_t att_status, uint8_t volume, + uint8_t mute) +{ + struct btp_vcp_state_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.volume = volume; + ev.mute = mute; + + tester_event(BTP_SERVICE_ID_VCP, BTP_VCP_STATE_EV, &ev, sizeof(ev)); +} + +static void btp_send_vcp_volume_flags_ev(struct bt_conn *conn, uint8_t att_status, uint8_t flags) +{ + struct btp_vcp_volume_flags_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.flags = flags; + + tester_event(BTP_SERVICE_ID_VCP, BTP_VCP_FLAGS_EV, &ev, sizeof(ev)); +} + +static void btp_send_vcp_procedure_ev(struct bt_conn *conn, uint8_t att_status, uint8_t opcode) +{ + struct btp_vcp_procedure_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.att_status = att_status; + ev.opcode = opcode; + + tester_event(BTP_SERVICE_ID_VCP, BTP_VCP_PROCEDURE_EV, &ev, sizeof(ev)); +} + +static uint8_t vcp_supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_vcp_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_VCP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_DISCOVER); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_STATE_READ); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_FLAGS_READ); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_VOL_DOWN); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_VOL_UP); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_UNMUTE_VOL_DOWN); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_UNMUTE_VOL_UP); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_SET_VOL); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_UNMUTE); + tester_set_bit(rp->data, BTP_VCP_VOL_CTLR_MUTE); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static void vcp_vol_ctlr_discover_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t vocs_count, + uint8_t aics_count) +{ + struct bt_conn *conn; + + if (err) { + LOG_DBG("Discovery failed (%d)", err); + return; + } + + LOG_DBG("Discovery done with %u VOCS, %u AICS", + vocs_count, aics_count); + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + + if (bt_vcp_vol_ctlr_included_get(vol_ctlr, &included) != 0) { + LOG_DBG("Could not get included services"); + memset(&chrc_handles.vocs_handles, 0, sizeof(chrc_handles.vocs_handles)); + memset(&chrc_handles.aics_handles, 0, sizeof(chrc_handles.aics_handles)); + } else { + aics_client_instance.aics_cnt = included.aics_cnt; + aics_client_instance.aics = included.aics; + bt_vocs_client_cb_register(vol_ctlr->vocs[0], &vocs_cl_cb); + bt_aics_client_cb_register(vol_ctlr->aics[0], &aics_client_cb); + + struct bt_vocs_client *vocs_cli = + CONTAINER_OF(vol_ctlr->vocs[0], struct bt_vocs_client, vocs); + struct bt_aics_client *aics_cli = &vol_ctlr->aics[0]->cli; + + chrc_handles.vocs_handles.state = vocs_cli->state_handle; + chrc_handles.vocs_handles.location = vocs_cli->location_handle; + chrc_handles.vocs_handles.control = vocs_cli->control_handle; + chrc_handles.vocs_handles.desc = vocs_cli->desc_handle; + chrc_handles.aics_handles.state = aics_cli->state_handle; + chrc_handles.aics_handles.gain = aics_cli->gain_handle; + chrc_handles.aics_handles.type = aics_cli->type_handle; + chrc_handles.aics_handles.status = aics_cli->status_handle; + chrc_handles.aics_handles.control = aics_cli->control_handle; + chrc_handles.aics_handles.desc = aics_cli->desc_handle; + } + + chrc_handles.vcp_handles.ctrl_pt = vol_ctlr->control_handle; + chrc_handles.vcp_handles.flags = vol_ctlr->flag_handle; + chrc_handles.vcp_handles.state = vol_ctlr->state_handle; + btp_send_vcp_found_ev(conn, err, &chrc_handles); +} + +static void vcp_vol_ctlr_state_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t volume, + uint8_t mute) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_state_ev(conn, err, volume, mute); + + LOG_DBG("VCP Volume CTLR State callback"); +} + +static void vcp_vol_ctlr_flags_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t flags) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_volume_flags_ev(conn, err, flags); + + LOG_DBG("VCP CTLR Volume Flags callback"); +} + +static void vcp_vol_ctlr_vol_down_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_VOL_DOWN); + + LOG_DBG("VCP CTLR Volume down callback"); +} + +static void vcp_vol_ctlr_vol_up_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_VOL_UP); + + LOG_DBG("VCP CTLR Volume down callback"); +} + +static void vcp_vol_ctlr_unmute_vol_down_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_UNMUTE_VOL_DOWN); + + LOG_DBG("VCP CTLR Volume down and unmute callback"); +} + +static void vcp_vol_ctlr_unmute_vol_up_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_UNMUTE_VOL_UP); + + LOG_DBG("VCP CTLR Volume down and unmute callback"); +} + +static void vcp_vol_ctlr_set_vol_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_SET_VOL); + + LOG_DBG("VCP CTLR Set absolute volume callback"); +} + +static void vcp_vol_ctlr_unmute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_UNMUTE); + + LOG_DBG("VCP CTLR Volume down and unmute callback"); +} + +static void vcp_vol_ctlr_mute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err) +{ + struct bt_conn *conn; + + bt_vcp_vol_ctlr_conn_get(vol_ctlr, &conn); + btp_send_vcp_procedure_ev(conn, err, BTP_VCP_VOL_CTLR_MUTE); + + LOG_DBG("VCP CTLR Set absolute volume callback"); +} + +static struct bt_vcp_vol_ctlr_cb vcp_cbs = { + .discover = vcp_vol_ctlr_discover_cb, + .state = vcp_vol_ctlr_state_cb, + .flags = vcp_vol_ctlr_flags_cb, + .vol_down = vcp_vol_ctlr_vol_down_cb, + .vol_up = vcp_vol_ctlr_vol_up_cb, + .mute = vcp_vol_ctlr_mute_cb, + .unmute = vcp_vol_ctlr_unmute_cb, + .vol_down_unmute = vcp_vol_ctlr_unmute_vol_down_cb, + .vol_up_unmute = vcp_vol_ctlr_unmute_vol_up_cb, + .vol_set = vcp_vol_ctlr_set_vol_cb +}; + +static uint8_t vcp_discover(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_vcp_discover_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_vcp_vol_ctlr_discover(conn, &vol_ctlr); + if (err) { + LOG_DBG("Fail: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_state_read(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP State read"); + + err = bt_vcp_vol_ctlr_read_state(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_volume_flags_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP Volume Flags read"); + + err = bt_vcp_vol_ctlr_read_flags(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_vol_down(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Volume down"); + + err = bt_vcp_vol_ctlr_vol_down(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_vol_up(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Volume up"); + + err = bt_vcp_vol_ctlr_vol_up(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_unmute_vol_down(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Unmute, vol down"); + + err = bt_vcp_vol_ctlr_unmute_vol_down(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_unmute_vol_up(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Unmute, Volume up"); + + err = bt_vcp_vol_ctlr_unmute_vol_up(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_set_vol(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_vcp_ctlr_set_vol_cmd *cp = cmd; + int err; + + LOG_DBG("VCP CTLR Set absolute volume %d", cp->volume); + + err = bt_vcp_vol_ctlr_set_vol(vol_ctlr, cp->volume); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_unmute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Unmute"); + + err = bt_vcp_vol_ctlr_unmute(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t vcp_ctlr_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG("VCP CTLR Mute"); + + err = bt_vcp_vol_ctlr_mute(vol_ctlr); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler vcp_handlers[] = { + { + .opcode = BTP_VCP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = vcp_supported_commands, + }, + { + .opcode = BTP_VCP_VOL_CTLR_DISCOVER, + .expect_len = sizeof(struct btp_vcp_discover_cmd), + .func = vcp_discover, + }, + { + .opcode = BTP_VCP_VOL_CTLR_STATE_READ, + .expect_len = sizeof(struct btp_vcp_state_read_cmd), + .func = vcp_state_read, + }, + { + .opcode = BTP_VCP_VOL_CTLR_FLAGS_READ, + .expect_len = sizeof(struct btp_vcp_flags_read_cmd), + .func = vcp_volume_flags_read, + }, + { + .opcode = BTP_VCP_VOL_CTLR_VOL_DOWN, + .expect_len = sizeof(struct btp_vcp_ctlr_vol_down_cmd), + .func = vcp_ctlr_vol_down, + }, + { + .opcode = BTP_VCP_VOL_CTLR_VOL_UP, + .expect_len = sizeof(struct btp_vcp_ctlr_vol_up_cmd), + .func = vcp_ctlr_vol_up, + }, + { + .opcode = BTP_VCP_VOL_CTLR_UNMUTE_VOL_DOWN, + .expect_len = sizeof(struct btp_vcp_ctlr_unmute_vol_down_cmd), + .func = vcp_ctlr_unmute_vol_down, + }, + { + .opcode = BTP_VCP_VOL_CTLR_UNMUTE_VOL_UP, + .expect_len = sizeof(struct btp_vcp_ctlr_unmute_vol_up_cmd), + .func = vcp_ctlr_unmute_vol_up, + }, + { + .opcode = BTP_VCP_VOL_CTLR_SET_VOL, + .expect_len = sizeof(struct btp_vcp_ctlr_set_vol_cmd), + .func = vcp_ctlr_set_vol, + }, + { + .opcode = BTP_VCP_VOL_CTLR_UNMUTE, + .expect_len = sizeof(struct btp_vcp_ctlr_unmute_cmd), + .func = vcp_ctlr_unmute, + }, + { + .opcode = BTP_VCP_VOL_CTLR_MUTE, + .expect_len = sizeof(struct btp_vcp_ctlr_mute_cmd), + .func = vcp_ctlr_mute, + }, +}; + +uint8_t tester_init_vcp(void) +{ + int err; + + err = bt_vcp_vol_ctlr_cb_register(&vcp_cbs); + + if (err) { + LOG_DBG("Failed to register callbacks: %d", err); + return BTP_STATUS_FAILED; + } + + tester_register_command_handlers(BTP_SERVICE_ID_VCP, vcp_handlers, + ARRAY_SIZE(vcp_handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_vcp(void) +{ + (void)bt_vcp_vol_ctlr_cb_register(NULL); + return BTP_STATUS_SUCCESS; +} From 54126ec4e5cc797dfcfffe8bb70a4df0d280b476 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 4 Sep 2023 14:22:27 +0200 Subject: [PATCH 1260/4498] bluetooth: audio: Add API to get VCP service ATT handles This is needed for upper tester. Signed-off-by: Piotr Narajowski --- subsys/bluetooth/audio/vcp_internal.h | 29 +++++++++++++++++++++++++++ subsys/bluetooth/audio/vcp_vol_ctlr.c | 29 --------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/subsys/bluetooth/audio/vcp_internal.h b/subsys/bluetooth/audio/vcp_internal.h index 8a1fec2c0f1..b791b526c1b 100644 --- a/subsys/bluetooth/audio/vcp_internal.h +++ b/subsys/bluetooth/audio/vcp_internal.h @@ -36,4 +36,33 @@ struct vcs_control_vol { uint8_t volume; } __packed; +struct bt_vcp_vol_ctlr { + struct vcs_state state; + uint8_t flags; + + uint16_t start_handle; + uint16_t end_handle; + uint16_t state_handle; + uint16_t control_handle; + uint16_t flag_handle; + struct bt_gatt_subscribe_params state_sub_params; + struct bt_gatt_discover_params state_sub_disc_params; + struct bt_gatt_subscribe_params flag_sub_params; + struct bt_gatt_discover_params flag_sub_disc_params; + bool cp_retried; + + bool busy; + struct vcs_control_vol cp_val; + struct bt_gatt_write_params write_params; + struct bt_gatt_read_params read_params; + struct bt_gatt_discover_params discover_params; + struct bt_uuid_16 uuid; + struct bt_conn *conn; + + uint8_t vocs_inst_cnt; + struct bt_vocs *vocs[CONFIG_BT_VOCS_CLIENT_MAX_INSTANCE_COUNT]; + uint8_t aics_inst_cnt; + struct bt_aics *aics[CONFIG_BT_AICS_CLIENT_MAX_INSTANCE_COUNT]; +}; + #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_VCP_INTERNAL_*/ diff --git a/subsys/bluetooth/audio/vcp_vol_ctlr.c b/subsys/bluetooth/audio/vcp_vol_ctlr.c index 825cedff32e..f8033ba99cf 100644 --- a/subsys/bluetooth/audio/vcp_vol_ctlr.c +++ b/subsys/bluetooth/audio/vcp_vol_ctlr.c @@ -28,35 +28,6 @@ LOG_MODULE_REGISTER(bt_vcp_vol_ctlr, CONFIG_BT_VCP_VOL_CTLR_LOG_LEVEL); #include "common/bt_str.h" -struct bt_vcp_vol_ctlr { - struct vcs_state state; - uint8_t flags; - - uint16_t start_handle; - uint16_t end_handle; - uint16_t state_handle; - uint16_t control_handle; - uint16_t flag_handle; - struct bt_gatt_subscribe_params state_sub_params; - struct bt_gatt_discover_params state_sub_disc_params; - struct bt_gatt_subscribe_params flag_sub_params; - struct bt_gatt_discover_params flag_sub_disc_params; - bool cp_retried; - - bool busy; - struct vcs_control_vol cp_val; - struct bt_gatt_write_params write_params; - struct bt_gatt_read_params read_params; - struct bt_gatt_discover_params discover_params; - struct bt_uuid_16 uuid; - struct bt_conn *conn; - - uint8_t vocs_inst_cnt; - struct bt_vocs *vocs[CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST]; - uint8_t aics_inst_cnt; - struct bt_aics *aics[CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST]; -}; - /* Callback functions */ static struct bt_vcp_vol_ctlr_cb *vcp_vol_ctlr_cb; From 34c9587539aa64361b3172eb24a8d8b5ec95920a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Sep 2023 17:32:20 +0200 Subject: [PATCH 1261/4498] samples: Bluetooth: Add broadcast sink data validation Add validation of incoming ISO data for the broadcast sink sample. Signed-off-by: Emil Gydesen --- samples/bluetooth/broadcast_audio_sink/src/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index fad1ba7c11b..c7b89b7b18c 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -90,6 +90,16 @@ static void stream_recv_cb(struct bt_bap_stream *stream, { static uint32_t recv_cnt; + if (info->flags & BT_ISO_FLAGS_ERROR) { + printk("ISO receive error\n"); + return; + } + + if (info->flags & BT_ISO_FLAGS_LOST) { + printk("ISO receive lost\n"); + return; + } + recv_cnt++; if ((recv_cnt % 1000U) == 0U) { printk("Received %u total ISO packets\n", recv_cnt); From 0efc66df5e62078ba9560070c6bafd7e7d122c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Mon, 16 Nov 2020 12:01:54 +0100 Subject: [PATCH 1262/4498] Bluetooth: tester: Use Model Receive testing callback Send a BTP event to the automation framework that a model message has been received. Signed-off-by: Michal Narajowski --- tests/bluetooth/tester/src/btp/btp_mesh.h | 8 ++++++++ tests/bluetooth/tester/src/btp_mesh.c | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bf73d6839d2..e17d8481500 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -864,3 +864,11 @@ struct btp_mesh_prov_node_added_ev { uint8_t uuid[16]; uint8_t num_elems; } __packed; + +#define BTP_MESH_EV_MODEL_RECV 0x8f +struct btp_mesh_model_recv_ev { + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[]; +} __packed; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c56c0ff9c1c..2796f6418e4 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -2963,6 +2963,28 @@ void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const voi tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_NET_RECV, buf.data, buf.len); } +void model_recv_ev(uint16_t src, uint16_t dst, const void *payload, + size_t payload_len) +{ + NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX); + struct btp_mesh_model_recv_ev *ev; + + LOG_DBG("src 0x%04x dst 0x%04x payload_len %zu", src, dst, payload_len); + + if (payload_len > net_buf_simple_tailroom(&buf)) { + LOG_ERR("Payload size exceeds buffer size"); + return; + } + + ev = net_buf_simple_add(&buf, sizeof(*ev)); + ev->src = sys_cpu_to_le16(src); + ev->dst = sys_cpu_to_le16(dst); + ev->payload_len = payload_len; + net_buf_simple_add_mem(&buf, payload, payload_len); + + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_MODEL_RECV, buf.data, buf.len); +} + static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, uint16_t key_idx) { @@ -3023,6 +3045,7 @@ static void incomp_timer_exp_cb(void) static struct bt_test_cb bt_test_cb = { .mesh_net_recv = net_recv_ev, + .mesh_model_recv = model_recv_ev, .mesh_model_bound = model_bound_cb, .mesh_model_unbound = model_unbound_cb, .mesh_prov_invalid_bearer = invalid_bearer_cb, From 959e55cdc07100bda633aab65f577e572e8dd36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Wed, 18 Nov 2020 12:52:59 +0100 Subject: [PATCH 1263/4498] Bluetooth: tester: Add ttl param to Model Send CMD Some test cases require more control over transmission parameters used when sending access messages. Signed-off-by: Michal Narajowski --- tests/bluetooth/tester/src/btp/btp_mesh.h | 1 + tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index e17d8481500..bd7af172744 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -127,6 +127,7 @@ struct btp_mesh_lpn_set_cmd { #define BTP_MESH_MODEL_SEND 0x0f struct btp_mesh_model_send_cmd { + uint8_t ttl; uint16_t src; uint16_t dst; uint8_t payload_len; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 2796f6418e4..b6ac4d91e1c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -861,7 +861,7 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, .addr = sys_le16_to_cpu(cp->dst), - .send_ttl = BT_MESH_TTL_DEFAULT, + .send_ttl = cp->ttl, }; if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) { From 11bdcb859e921a79e50dc41c30167bc544dcbcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Thu, 25 Mar 2021 15:33:18 +0100 Subject: [PATCH 1264/4498] tester: Add Large Comp Data models - Adds Large Comp Data Server and Client - Defines some dummy metadata for Health Server Signed-off-by: Michal Narajowski --- tests/bluetooth/tester/overlay-mesh.conf | 5 + tests/bluetooth/tester/src/btp/btp_mesh.h | 22 +++++ tests/bluetooth/tester/src/btp_mesh.c | 111 ++++++++++++++++++++-- 3 files changed, 129 insertions(+), 9 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 840af06c1c0..937f4d1270e 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -1,4 +1,5 @@ CONFIG_BT_MESH=y +CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PB_GATT=y @@ -12,6 +13,8 @@ CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y +CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y +CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 @@ -23,3 +26,5 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y + +CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bd7af172744..63984f0b61f 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -773,6 +773,28 @@ struct btp_proxy_connect_cmd { uint16_t net_idx; } __packed; +#define BTP_MESH_LARGE_COMP_DATA_GET 0x53 +struct btp_mesh_large_comp_data_get_cmd { + uint16_t net_idx; + uint16_t addr; + uint8_t page; + uint16_t offset; +} __packed; +struct btp_mesh_large_comp_data_get_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MESH_MODELS_METADATA_GET 0x54 +struct btp_mesh_models_metadata_get_cmd { + uint16_t net_idx; + uint16_t addr; + uint8_t page; + uint16_t offset; +} __packed; +struct btp_mesh_models_metadata_get_rp { + uint8_t data[0]; +} __packed; + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index b6ac4d91e1c..a6ccd319b2d 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -22,6 +22,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #include "btp/btp.h" #define CID_LOCAL 0x05F1 +#define COMPANY_ID_LF 0x05F1 +#define COMPANY_ID_NORDIC_SEMI 0x05F9 /* Health server data */ #define CUR_FAULTS_MAX 4 @@ -254,15 +256,6 @@ static const struct bt_mesh_health_srv_cb health_srv_cb = { .fault_test = fault_test, }; -static struct bt_mesh_health_srv health_srv = { - .cb = &health_srv_cb, -}; - -BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); - -static struct bt_mesh_cfg_cli cfg_cli = { -}; - static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) { size_t i; @@ -289,15 +282,52 @@ static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr, show_faults(test_id, cid, faults, fault_count); } +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) +static struct bt_mesh_large_comp_data_cli lcd_cli = { +}; +#endif + static struct bt_mesh_health_cli health_cli = { .current_status = health_current_status, }; + +#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV +static uint8_t health_tests[] = { + BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34, + 0x15), + BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03), +}; + +static struct bt_mesh_models_metadata_entry health_srv_meta[] = { + BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests), + BT_MESH_MODELS_METADATA_END, +}; +#endif + +static struct bt_mesh_health_srv health_srv = { + .cb = &health_srv_cb, +#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV + .metadata = health_srv_meta, +#endif +}; + +BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); + +static struct bt_mesh_cfg_cli cfg_cli = { +}; + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL_HEALTH_CLI(&health_cli), +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) + BT_MESH_MODEL_LARGE_COMP_DATA_SRV, +#endif +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) + BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), +#endif }; static struct bt_mesh_model vnd_models[] = { @@ -986,6 +1016,56 @@ static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len, } #endif +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) +static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_large_comp_data_get_cmd *cp = cmd; + struct btp_mesh_large_comp_data_get_rp *rp = rsp; + int err; + + struct bt_mesh_large_comp_data_rsp comp; + + err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx), + sys_le16_to_cpu(cp->addr), cp->page, + sys_le16_to_cpu(cp->offset), &comp); + if (err) { + LOG_ERR("Large Composition Data Get failed (err %d)", err); + + return BTP_STATUS_FAILED; + } + + memcpy(rp->data, comp.data->data, comp.data->len); + *rsp_len = comp.data->len; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_models_metadata_get_cmd *cp = cmd; + struct btp_mesh_models_metadata_get_rp *rp = rsp; + int err; + + struct bt_mesh_large_comp_data_rsp metadata; + + err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx), + sys_le16_to_cpu(cp->addr), cp->page, + sys_le16_to_cpu(cp->offset), &metadata); + + if (err) { + LOG_ERR("Models Metadata Get failed (err %d)", err); + return BTP_STATUS_FAILED; + } + + memcpy(rp->data, metadata.data->data, metadata.data->len); + *rsp_len = metadata.data->len; + + return BTP_STATUS_SUCCESS; +} +#endif + static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -2936,8 +3016,21 @@ static const struct btp_handler handlers[] = { .func = proxy_connect }, #endif +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) + { + .opcode = BTP_MESH_LARGE_COMP_DATA_GET, + .expect_len = sizeof(struct btp_mesh_large_comp_data_get_cmd), + .func = large_comp_data_get + }, + { + .opcode = BTP_MESH_MODELS_METADATA_GET, + .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd), + .func = models_metadata_get + }, +#endif }; + void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { From a73727c2fe8c7ac6972b7f2844d2949936ecc5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Tue, 31 Jan 2023 14:29:16 +0100 Subject: [PATCH 1265/4498] Bluetooth: tester: Add Transport SAR Configuration models Add support for testing the new SAR Configuration models in tester application. Signed-off-by: Michal Narajowski --- tests/bluetooth/tester/overlay-mesh.conf | 2 + tests/bluetooth/tester/src/btp/btp_mesh.h | 40 +++++++ tests/bluetooth/tester/src/btp_mesh.c | 133 +++++++++++++++++++++- 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 937f4d1270e..43e666d0eb3 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -15,6 +15,8 @@ CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y +CONFIG_BT_MESH_SAR_CFG_SRV=y +CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 63984f0b61f..67ce612c2ac 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -773,6 +773,46 @@ struct btp_proxy_connect_cmd { uint16_t net_idx; } __packed; +struct sar_transmitter { + uint8_t seg_int_step; + uint8_t unicast_retrans_count; + uint8_t unicast_retrans_without_prog_count; + uint8_t unicast_retrans_int_step; + uint8_t unicast_retrans_int_inc; + uint8_t multicast_retrans_count; + uint8_t multicast_retrans_int; +} __packed; + +struct sar_receiver { + uint8_t seg_thresh; + uint8_t ack_delay_inc; + uint8_t ack_retrans_count; + uint8_t discard_timeout; + uint8_t rx_seg_int_step; +} __packed; + +#define BTP_MESH_SAR_TRANSMITTER_GET 0x4f +struct btp_mesh_sar_transmitter_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_SAR_TRANSMITTER_SET 0x50 +struct btp_mesh_sar_transmitter_set_cmd { + uint16_t dst; + struct sar_transmitter tx; +} __packed; + +#define BTP_MESH_SAR_RECEIVER_GET 0x51 +struct btp_mesh_sar_receiver_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_SAR_RECEIVER_SET 0x52 +struct btp_mesh_sar_receiver_set_cmd { + uint16_t dst; + struct sar_receiver rx; +} __packed; + #define BTP_MESH_LARGE_COMP_DATA_GET 0x53 struct btp_mesh_large_comp_data_get_cmd { uint16_t net_idx; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index a6ccd319b2d..232e3d7d8b4 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #define LOG_MODULE_NAME bttester_mesh @@ -317,11 +318,21 @@ BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); static struct bt_mesh_cfg_cli cfg_cli = { }; +#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) +static struct bt_mesh_sar_cfg_cli sar_cfg_cli; +#endif + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL_HEALTH_CLI(&health_cli), +#if defined(CONFIG_BT_MESH_SAR_CFG_SRV) + BT_MESH_MODEL_SAR_CFG_SRV, +#endif +#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) + BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli), +#endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) BT_MESH_MODEL_LARGE_COMP_DATA_SRV, #endif @@ -1016,6 +1027,105 @@ static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len, } #endif +#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) +static uint8_t sar_transmitter_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_sar_transmitter_get_cmd *cp = cmd; + struct bt_mesh_sar_tx tx_rsp; + int err; + + LOG_DBG(""); + + bt_mesh_sar_cfg_cli_timeout_set(5000); + + err = bt_mesh_sar_cfg_cli_transmitter_get( + net_key_idx, sys_le16_to_cpu(cp->dst), &tx_rsp); + if (err) { + LOG_ERR("err=%d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t sar_transmitter_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_sar_transmitter_set_cmd *cp = cmd; + struct bt_mesh_sar_tx set, tx_rsp; + int err; + + LOG_DBG(""); + + bt_mesh_sar_cfg_cli_timeout_set(5000); + + set.seg_int_step = cp->tx.seg_int_step; + set.unicast_retrans_count = cp->tx.unicast_retrans_count; + set.unicast_retrans_int_inc = cp->tx.unicast_retrans_int_inc; + set.unicast_retrans_int_step = cp->tx.unicast_retrans_int_step; + set.unicast_retrans_without_prog_count = + cp->tx.unicast_retrans_without_prog_count; + set.multicast_retrans_count = cp->tx.multicast_retrans_count; + set.multicast_retrans_int = cp->tx.multicast_retrans_int; + + err = bt_mesh_sar_cfg_cli_transmitter_set(net_key_idx, + sys_le16_to_cpu(cp->dst), + &set, &tx_rsp); + if (err) { + LOG_ERR("err=%d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t sar_receiver_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_sar_receiver_get_cmd *cp = cmd; + struct bt_mesh_sar_rx rx_rsp; + int err; + + LOG_DBG(""); + + err = bt_mesh_sar_cfg_cli_receiver_get(net_key_idx, + sys_le16_to_cpu(cp->dst), &rx_rsp); + if (err) { + LOG_ERR("err=%d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t sar_receiver_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_sar_receiver_set_cmd *cp = cmd; + struct bt_mesh_sar_rx set, rx_rsp; + int err; + + LOG_DBG(""); + + set.ack_delay_inc = cp->rx.ack_delay_inc; + set.ack_retrans_count = cp->rx.ack_retrans_count; + set.discard_timeout = cp->rx.discard_timeout; + set.seg_thresh = cp->rx.seg_thresh; + set.rx_seg_int_step = cp->rx.rx_seg_int_step; + + err = bt_mesh_sar_cfg_cli_receiver_set(net_key_idx, + sys_le16_to_cpu(cp->dst), &set, + &rx_rsp); + if (err) { + LOG_ERR("err=%d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -3016,6 +3126,28 @@ static const struct btp_handler handlers[] = { .func = proxy_connect }, #endif +#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) + { + .opcode = BTP_MESH_SAR_TRANSMITTER_GET, + .expect_len = sizeof(struct btp_mesh_sar_transmitter_get_cmd), + .func = sar_transmitter_get + }, + { + .opcode = BTP_MESH_SAR_TRANSMITTER_SET, + .expect_len = sizeof(struct btp_mesh_sar_transmitter_set_cmd), + .func = sar_transmitter_set + }, + { + .opcode = BTP_MESH_SAR_RECEIVER_GET, + .expect_len = sizeof(struct btp_mesh_sar_receiver_get_cmd), + .func = sar_receiver_get + }, + { + .opcode = BTP_MESH_SAR_RECEIVER_SET, + .expect_len = sizeof(struct btp_mesh_sar_receiver_set_cmd), + .func = sar_receiver_set + }, +#endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) { .opcode = BTP_MESH_LARGE_COMP_DATA_GET, @@ -3030,7 +3162,6 @@ static const struct btp_handler handlers[] = { #endif }; - void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { From 68928e050f365306d92fc08f3bec91fa0e207cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 28 Jan 2022 08:03:51 +0100 Subject: [PATCH 1266/4498] Tests: Bluetooth: tester: enable Remote Provisioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables Remote Provisioning in tester application. Adds basic setup and required structures/functions. add BTP API for Remote Provisioning Client This adds BTP commands for RPR Client API. Signed-off-by: Krzysztof Kopyściński --- tests/bluetooth/tester/overlay-mesh.conf | 4 + tests/bluetooth/tester/src/btp/btp_mesh.h | 61 +++ tests/bluetooth/tester/src/btp_mesh.c | 434 +++++++++++++++++++++- 3 files changed, 495 insertions(+), 4 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 43e666d0eb3..b537ae0001e 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -28,5 +28,9 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y +CONFIG_BT_MESH_PROVISIONER=y +CONFIG_BT_MESH_RPR_SRV=y +CONFIG_BT_MESH_RPR_CLI=y +CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 67ce612c2ac..29523d02d8c 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -835,6 +835,66 @@ struct btp_mesh_models_metadata_get_rp { uint8_t data[0]; } __packed; +#define BTP_MESH_COMP_CHANGE_PREPARE 0x57 + +#define BTP_MESH_SET_COMP_ALT 0x58 + +#define BTP_MESH_RPR_SCAN_START 0x59 +struct btp_rpr_scan_start_cmd { + uint16_t dst; + uint8_t timeout; + uint8_t uuid[16]; +} __packed; + +#define BTP_MESH_RPR_EXT_SCAN_START 0x5a +struct btp_rpr_ext_scan_start_cmd { + uint16_t dst; + uint8_t timeout; + uint8_t uuid[16]; + uint8_t ad_count; + uint8_t ad_types[]; +} __packed; + +#define BTP_MESH_RPR_SCAN_CAPS_GET 0x5b +struct btp_rpr_scan_caps_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_RPR_SCAN_GET 0x5c +struct btp_rpr_scan_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_RPR_SCAN_STOP 0x5d +struct btp_rpr_scan_stop_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_RPR_LINK_GET 0x5e +struct btp_rpr_link_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_RPR_LINK_CLOSE 0x5f +struct btp_rpr_link_close_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_RPR_PROV_REMOTE 0x60 +struct btp_rpr_prov_remote_cmd { + uint16_t dst; + uint8_t uuid[16]; + uint16_t net_idx; + uint16_t addr; +} __packed; + +#define BTP_MESH_RPR_REPROV_REMOTE 0x61 +struct btp_rpr_reprov_remote_cmd { + uint16_t dst; + uint16_t addr; + bool comp_change; +} __packed; + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { @@ -858,6 +918,7 @@ struct btp_mesh_in_action_ev { #define BTP_MESH_PROV_BEARER_PB_ADV 0x00 #define BTP_MESH_PROV_BEARER_PB_GATT 0x01 +#define BTP_MESH_PROV_BEARER_REMOTE 0x04 #define BTP_MESH_EV_PROV_LINK_OPEN 0x84 struct btp_mesh_prov_link_open_ev { uint8_t bearer; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 232e3d7d8b4..40ae3a6f038 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -76,6 +76,7 @@ static struct { .dst = BT_MESH_ADDR_UNASSIGNED, }; +static bool default_comp = true; static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -322,6 +323,49 @@ static struct bt_mesh_cfg_cli cfg_cli = { static struct bt_mesh_sar_cfg_cli sar_cfg_cli; #endif +#if defined(CONFIG_BT_MESH_RPR_CLI) +static void rpr_scan_report(struct bt_mesh_rpr_cli *cli, + const struct bt_mesh_rpr_node *srv, + struct bt_mesh_rpr_unprov *unprov, + struct net_buf_simple *adv_data) +{ + char uuid_hex_str[32 + 1]; + + bin2hex(unprov->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str)); + + LOG_DBG("Server 0x%04x:\n" + "\tuuid: %s\n" + "\tOOB: 0x%04x", + srv->addr, uuid_hex_str, unprov->oob); + + while (adv_data && adv_data->len > 2) { + uint8_t len, type; + uint8_t data[31]; + + len = net_buf_simple_pull_u8(adv_data) - 1; + type = net_buf_simple_pull_u8(adv_data); + memcpy(data, net_buf_simple_pull_mem(adv_data, len), len); + data[len] = '\0'; + + if (type == BT_DATA_URI) { + LOG_DBG("\tURI: \"\\x%02x%s\"", + data[0], &data[1]); + } else if (type == BT_DATA_NAME_COMPLETE) { + LOG_DBG("\tName: \"%s\"", data); + } else { + char string[64 + 1]; + + bin2hex(data, len, string, sizeof(string)); + LOG_DBG("\t0x%02x: %s", type, string); + } + } +} + +static struct bt_mesh_rpr_cli rpr_cli = { + .scan_report = rpr_scan_report, +}; +#endif + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -339,6 +383,12 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), #endif +#if defined(CONFIG_BT_MESH_RPR_CLI) + BT_MESH_MODEL_RPR_CLI(&rpr_cli), +#endif +#if defined(CONFIG_BT_MESH_RPR_SRV) + BT_MESH_MODEL_RPR_SRV, +#endif }; static struct bt_mesh_model vnd_models[] = { @@ -363,6 +413,9 @@ static void link_open(bt_mesh_prov_bearer_t bearer) case BT_MESH_PROV_GATT: ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; + case BT_MESH_PROV_REMOTE: + ev.bearer = BTP_MESH_PROV_BEARER_REMOTE; + break; default: LOG_ERR("Invalid bearer"); @@ -385,6 +438,9 @@ static void link_close(bt_mesh_prov_bearer_t bearer) case BT_MESH_PROV_GATT: ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; + case BT_MESH_PROV_REMOTE: + ev.bearer = BTP_MESH_PROV_BEARER_REMOTE; + break; default: LOG_ERR("Invalid bearer"); @@ -476,12 +532,24 @@ static void prov_reset(void) LOG_DBG(""); bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); + + if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) { + bt_mesh_prov_enable(BT_MESH_PROV_REMOTE); + } } static const struct bt_mesh_comp comp = { .cid = CID_LOCAL, .elem = elements, .elem_count = ARRAY_SIZE(elements), + .vid = 1, +}; + +static const struct bt_mesh_comp comp_alt = { + .cid = CID_LOCAL, + .elem = elements, + .elem_count = ARRAY_SIZE(elements), + .vid = 2, }; static struct bt_mesh_prov prov = { @@ -496,6 +564,7 @@ static struct bt_mesh_prov prov = { .complete = prov_complete, .node_added = prov_node_added, .reset = prov_reset, + .uri = "Tester", }; static uint8_t config_prov(const void *cmd, uint16_t cmd_len, @@ -617,19 +686,26 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, LOG_DBG(""); - err = bt_mesh_init(&prov, &comp); - if (err) { - return BTP_STATUS_FAILED; + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + printk("Loading stored settings\n"); + settings_load(); } if (addr) { err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, addr, dev_key); - if (err) { + if (err && err != -EALREADY) { return BTP_STATUS_FAILED; } } else { err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); + if (err && err != -EALREADY) { + return BTP_STATUS_FAILED; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) { + err = bt_mesh_prov_enable(BT_MESH_PROV_REMOTE); if (err) { return BTP_STATUS_FAILED; } @@ -1205,6 +1281,62 @@ static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_mesh_comp_change_prepare(); + if (err < 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +#if IS_ENABLED(CONFIG_BT_SETTINGS) +static int comp_alt_set(const char *name, size_t len_rd, + settings_read_cb read_cb, void *store) +{ + ssize_t len; + bool alt_comp_value; + + if (len_rd == 0) { + LOG_DBG("Default composition"); + } + + len = read_cb(store, &alt_comp_value, sizeof(alt_comp_value)); + if (len < 0 || len != len_rd) { + LOG_ERR("Failed to read value (err %zd)", len); + return len; + } + + if (alt_comp_value) { + default_comp = false; + } + + return 0; +} + +SETTINGS_STATIC_HANDLER_DEFINE(tester_comp_alt, "tester/comp_alt", NULL, comp_alt_set, NULL, NULL); +#endif + +static uint8_t set_comp_alt(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ +#if !IS_ENABLED(CONFIG_BT_SETTINGS) + return BTP_STATUS_FAILED; +#else + bool comp_alt_val = true; + + settings_save_one("tester/comp_alt", &comp_alt_val, sizeof(comp_alt_val)); + + return BTP_STATUS_SUCCESS; +#endif +} + static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -2730,6 +2862,233 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if defined(CONFIG_BT_MESH_RPR_CLI) +static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_scan_start_cmd *cp = cmd; + + struct bt_mesh_rpr_scan_status status; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + uint8_t uuid[16] = {0}; + int err; + + err = bt_mesh_rpr_scan_start(&rpr_cli, &srv, + memcmp(uuid, cp->uuid, 16) ? cp->uuid : NULL, + cp->timeout, + BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &status); + + if (err) { + LOG_ERR("Scan start failed: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_ext_scan_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_ext_scan_start_cmd *cp = cmd; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_scan_start_ext(&rpr_cli, &srv, cp->uuid, + cp->timeout, cp->ad_types, + cp->ad_count); + if (err) { + LOG_ERR("Scan start failed: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_scan_caps_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_scan_caps_get_cmd *cp = cmd; + struct bt_mesh_rpr_caps caps; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_scan_caps_get(&rpr_cli, &srv, &caps); + if (err) { + LOG_ERR("Scan capabilities get failed: %d", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Remote Provisioning scan capabilities of 0x%04x:", + net.dst); + LOG_DBG("\tMax devices: %u", caps.max_devs); + LOG_DBG("\tActive scanning: %s", + caps.active_scan ? "true" : "false"); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_scan_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_scan_get_cmd *cp = cmd; + struct bt_mesh_rpr_scan_status status; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_scan_get(&rpr_cli, &srv, &status); + if (err) { + LOG_ERR("Scan get failed: %d", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Remote Provisioning scan on 0x%04x:", cp->dst); + LOG_DBG("\tStatus: %u", status.status); + LOG_DBG("\tScan type: %u", status.scan); + LOG_DBG("\tMax devices: %u", status.max_devs); + LOG_DBG("\tRemaining time: %u", status.timeout); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_scan_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_scan_stop_cmd *cp = cmd; + struct bt_mesh_rpr_scan_status status; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_scan_stop(&rpr_cli, &srv, &status); + if (err || status.status) { + LOG_DBG("Scan stop failed: %d %u", err, status.status); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Remote Provisioning scan on 0x%04x stopped.", + net.dst); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_link_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_link_get_cmd *cp = cmd; + struct bt_mesh_rpr_link link; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_link_get(&rpr_cli, &srv, &link); + if (err) { + LOG_ERR("Link get failed: %d %u", err, link.status); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst); + LOG_DBG("\tStatus: %u", link.status); + LOG_DBG("\tState: %u", link.state); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_link_close(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_link_close_cmd *cp = cmd; + struct bt_mesh_rpr_link link; + const struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_rpr_link_close(&rpr_cli, &srv, &link); + if (err) { + LOG_ERR("Link close failed: %d %u", err, link.status); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst); + LOG_DBG("\tStatus: %u", link.status); + LOG_DBG("\tState: %u", link.state); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_prov_remote(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_prov_remote_cmd *cp = cmd; + struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = bt_mesh_provision_remote(&rpr_cli, &srv, cp->uuid, + cp->net_idx, cp->addr); + if (err) { + LOG_ERR("Prov remote start failed: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_rpr_reprov_remote_cmd *cp = cmd; + struct bt_mesh_rpr_node srv = { + .addr = cp->dst, + .net_idx = net.net_idx, + .ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + if (!BT_MESH_ADDR_IS_UNICAST(cp->addr)) { + LOG_ERR("Must be a valid unicast address"); + err = -EINVAL; + return BTP_STATUS_FAILED; + } + + err = bt_mesh_reprovision_remote(&rpr_cli, &srv, cp->addr, + cp->comp_change); + if (err) { + LOG_ERR("Reprovisioning failed: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static const struct btp_handler handlers[] = { { .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, @@ -3160,6 +3519,62 @@ static const struct btp_handler handlers[] = { .func = models_metadata_get }, #endif + { + .opcode = BTP_MESH_COMP_CHANGE_PREPARE, + .expect_len = 0, + .func = change_prepare + }, + { + .opcode = BTP_MESH_SET_COMP_ALT, + .expect_len = 0, + .func = set_comp_alt + }, +#if defined(CONFIG_BT_MESH_RPR_CLI) + { + .opcode = BTP_MESH_RPR_SCAN_START, + .expect_len = sizeof(struct btp_rpr_scan_start_cmd), + .func = rpr_scan_start + }, + { + .opcode = BTP_MESH_RPR_EXT_SCAN_START, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = rpr_ext_scan_start + }, + { + .opcode = BTP_MESH_RPR_SCAN_CAPS_GET, + .expect_len = sizeof(struct btp_rpr_scan_caps_get_cmd), + .func = rpr_scan_caps_get + }, + { + .opcode = BTP_MESH_RPR_SCAN_GET, + .expect_len = sizeof(struct btp_rpr_scan_get_cmd), + .func = rpr_scan_get + }, + { + .opcode = BTP_MESH_RPR_SCAN_STOP, + .expect_len = sizeof(struct btp_rpr_scan_stop_cmd), + .func = rpr_scan_stop + }, + { + .opcode = BTP_MESH_RPR_LINK_GET, + .expect_len = sizeof(struct btp_rpr_link_get_cmd), + .func = rpr_link_get + }, + { + .opcode = BTP_MESH_RPR_LINK_CLOSE, + .expect_len = sizeof(struct btp_rpr_link_close_cmd), + .func = rpr_link_close + }, + { + .opcode = BTP_MESH_RPR_PROV_REMOTE, + .expect_len = sizeof(struct btp_rpr_prov_remote_cmd), + .func = rpr_prov_remote + }, + { + .opcode = BTP_MESH_RPR_REPROV_REMOTE, + .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd), + .func = rpr_reprov_remote + }, }; void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, @@ -3345,12 +3760,23 @@ BT_MESH_LPN_CB_DEFINE(lpn_cb) = { uint8_t tester_init_mesh(void) { + int err; + if (IS_ENABLED(CONFIG_BT_TESTING)) { bt_test_cb_register(&bt_test_cb); } tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); + if (default_comp) { + err = bt_mesh_init(&prov, &comp); + } else { + err = bt_mesh_init(&prov, &comp_alt); + } + + if (err) { + return BTP_STATUS_FAILED; + } return BTP_STATUS_SUCCESS; } From 51ec2462d60aded26a5ba4736dde0e17dfc38af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 4 May 2022 08:05:03 +0200 Subject: [PATCH 1267/4498] Bluetooth: Tester: Add Blob, DFU and DFD tests support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding support for automatic testing BLOB, DFU and DFD models. Co-authored-by: Agata Ponitka Co-authored-by: Pavel Vasilyev Signed-off-by: Krzysztof Kopyściński Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/overlay-mesh.conf | 8 +- tests/bluetooth/tester/src/btp/btp_mesh.h | 68 ++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_core.c | 6 + tests/bluetooth/tester/src/btp_mesh.c | 1277 ++++++++++++++++++--- 5 files changed, 1221 insertions(+), 141 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index b537ae0001e..3352e36f3a4 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -20,7 +20,7 @@ CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 -CONFIG_BT_MESH_TX_SEG_MSG_COUNT=3 +CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 CONFIG_BT_MESH_LPN_POLL_TIMEOUT=100 CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_CDB=y @@ -32,5 +32,11 @@ CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_RPR_SRV=y CONFIG_BT_MESH_RPR_CLI=y CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 +CONFIG_BT_MESH_BLOB_CLI=y +CONFIG_BT_MESH_DFU_CLI=y +CONFIG_BT_MESH_BLOB_SRV=y +CONFIG_BT_MESH_DFU_SRV=y +CONFIG_BT_MESH_DFD_SRV=y +CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 29523d02d8c..66a86bbb128 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -895,6 +895,72 @@ struct btp_rpr_reprov_remote_cmd { bool comp_change; } __packed; +#define BTP_MMDL_DFU_INFO_GET 0x5f +struct btp_mmdl_dfu_info_get_cmd { + uint8_t limit; +} __packed; + +#define BTP_MMDL_BLOB_INFO_GET 0x60 +struct btp_mmdl_blob_info_get_cmd { + uint8_t addr_cnt; + uint8_t addr[]; +} __packed; + +#define BTP_MMDL_DFU_UPDATE_METADATA_CHECK 0x61 +struct btp_mmdl_dfu_metadata_check_cmd { + uint8_t index; + uint8_t slot_idx; + uint8_t slot_size; + uint8_t fwid_len; + uint8_t metadata_len; + uint8_t data[]; +} __packed; + +struct btp_mmdl_dfu_metadata_check_rp { + uint8_t idx; + uint8_t status; + uint8_t effect; +} __packed; + +#define BTP_MMDL_DFU_FIRMWARE_UPDATE_GET 0x62 +#define BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL 0x63 +#define BTP_MMDL_DFU_FIRMWARE_UPDATE_START 0x64 +struct btp_mmdl_dfu_firmware_update_cmd { + uint8_t addr_cnt; + uint8_t slot_idx; + uint8_t slot_size; + uint8_t fwid_len; + uint8_t metadata_len; + uint8_t block_size; + uint16_t chunk_size; + uint8_t data[]; +} __packed; + +struct btp_mmdl_dfu_firmware_update_rp { + uint8_t status; +} __packed; + +#define BTP_MMDL_BLOB_SRV_RECV 0x65 +struct btp_mmdl_blob_srv_recv_cmd { + uint64_t id; + uint16_t timeout; +} __packed; + +#define BTP_MMDL_BLOB_TRANSFER_START 0x66 +struct btp_mmdl_blob_transfer_start_cmd { + uint64_t id; + uint16_t size; + uint8_t block_size; + uint16_t chunk_size; + uint16_t timeout; +} __packed; + +#define BTP_MMDL_BLOB_TRANSFER_CANCEL 0x67 +#define BTP_MMDL_BLOB_TRANSFER_GET 0x68 +#define BTP_MMDL_BLOB_SRV_CANCEL 0x69 +#define BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY 0x6A +#define BTP_MMDL_DFU_SRV_APPLY 0x6B + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { @@ -996,3 +1062,5 @@ struct btp_mesh_model_recv_ev { uint8_t payload_len; uint8_t payload[]; } __packed; + +#define MESH_EV_BLOB_LOST_TARGET 0x90 diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 8e30da571e1..7d9e65c2d37 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -73,6 +73,9 @@ uint8_t tester_unregister_vocs(void); uint8_t tester_init_ias(void); uint8_t tester_unregister_ias(void); +uint8_t tester_init_mmdl(void); +uint8_t tester_unregister_mmdl(void); + uint8_t tester_init_gap(void); uint8_t tester_unregister_gap(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index d9fc85f353b..522bcb5aa75 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -127,6 +127,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_init_mesh(); break; + case BTP_SERVICE_ID_MESH_MDL: + status = tester_init_mmdl(); + break; #endif /* CONFIG_BT_MESH */ #if defined(CONFIG_BT_VCP_VOL_REND) || defined(CONFIG_BT_VCP_VOL_CTLR) case BTP_SERVICE_ID_VCS: @@ -226,6 +229,9 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_unregister_mesh(); break; + case BTP_SERVICE_ID_MESH_MDL: + status = tester_unregister_mmdl(); + break; #endif /* CONFIG_BT_MESH */ #if defined(CONFIG_BT_VCP_VOL_REND) case BTP_SERVICE_ID_VCS: diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 40ae3a6f038..8c637320a11 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -12,15 +12,18 @@ #include #include #include +#include #include #include #include +#include #include #define LOG_MODULE_NAME bttester_mesh LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #include "btp/btp.h" +#include "dfu_slot.h" #define CID_LOCAL 0x05F1 #define COMPANY_ID_LF 0x05F1 @@ -54,7 +57,245 @@ static uint8_t vnd_app_key[16]; static uint16_t vnd_app_key_idx = 0x000f; /* Model send data */ -#define MODEL_BOUNDS_MAX 2 +#define MODEL_BOUNDS_MAX 100 + +#if defined(CONFIG_BT_MESH_BLOB_SRV) || defined(CONFIG_BT_MESH_BLOB_CLI) +/* BLOB Model data*/ +static uint8_t blob_rx_sum; +static bool blob_valid; +static const char *blob_data = "11111111111111111111111111111111"; + +static int blob_io_open(const struct bt_mesh_blob_io *io, + const struct bt_mesh_blob_xfer *xfer, + enum bt_mesh_blob_io_mode mode) +{ + blob_rx_sum = 0; + blob_valid = true; + return 0; +} + +static int blob_chunk_wr(const struct bt_mesh_blob_io *io, + const struct bt_mesh_blob_xfer *xfer, + const struct bt_mesh_blob_block *block, + const struct bt_mesh_blob_chunk *chunk) +{ + for (int i = 0; i < chunk->size; ++i) { + blob_rx_sum += chunk->data[i]; + if (chunk->data[i] != + blob_data[(i + chunk->offset) % strlen(blob_data)]) { + blob_valid = false; + } + } + + return 0; +} + +static int blob_chunk_rd(const struct bt_mesh_blob_io *io, + const struct bt_mesh_blob_xfer *xfer, + const struct bt_mesh_blob_block *block, + const struct bt_mesh_blob_chunk *chunk) +{ + for (int i = 0; i < chunk->size; ++i) { + chunk->data[i] = + blob_data[(i + chunk->offset) % strlen(blob_data)]; + } + + return 0; +} + +static const struct bt_mesh_blob_io dummy_blob_io = { + .open = blob_io_open, + .rd = blob_chunk_rd, + .wr = blob_chunk_wr, +}; +#endif + +#if defined(CONFIG_BT_MESH_DFD_SRV) +/* DFD Model data*/ +static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, + const struct bt_mesh_blob_io **io) +{ + LOG_DBG("Uploading new firmware image to the distributor."); + + *io = &dummy_blob_io; + + return 0; +} + +static void dfd_srv_del(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot) +{ + LOG_DBG("Deleting the firmware image from the distributor."); +} + +static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, + const struct bt_mesh_blob_io **io) +{ + LOG_DBG("Starting the firmware distribution."); + + *io = &dummy_blob_io; + + return 0; +} + +static struct bt_mesh_dfd_srv_cb dfd_srv_cb = { + .recv = dfd_srv_recv, + .del = dfd_srv_del, + .send = dfd_srv_send, +}; + +static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb); +#endif + +#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) +static struct { + struct bt_mesh_blob_cli_inputs inputs; + struct bt_mesh_blob_target targets[32]; + struct bt_mesh_blob_target_pull pull[32]; + uint8_t target_count; + struct bt_mesh_blob_xfer xfer; +} blob_cli_xfer; + +static void blob_cli_lost_target(struct bt_mesh_blob_cli *cli, + struct bt_mesh_blob_target *target, + enum bt_mesh_blob_status reason) +{ + LOG_DBG("Mesh Blob: Lost target 0x%04x (reason: %u)", target->addr, + reason); + tester_event(BTP_SERVICE_ID_MESH, MESH_EV_BLOB_LOST_TARGET, NULL, 0); +} + +static void blob_cli_caps(struct bt_mesh_blob_cli *cli, + const struct bt_mesh_blob_cli_caps *caps) +{ + const char *const modes[] = { + "none", + "push", + "pull", + "all", + }; + + if (!caps) { + LOG_DBG("None of the targets can be used for BLOB transfer"); + return; + } + + LOG_DBG("Mesh BLOB: capabilities:"); + LOG_DBG("\tMax BLOB size: %u bytes", caps->max_size); + LOG_DBG("\tBlock size: %u-%u (%u-%u bytes)", caps->min_block_size_log, + caps->max_block_size_log, 1 << caps->min_block_size_log, + 1 << caps->max_block_size_log); + LOG_DBG("\tMax chunks: %u", caps->max_chunks); + LOG_DBG("\tChunk size: %u", caps->max_chunk_size); + LOG_DBG("\tMTU size: %u", caps->mtu_size); + LOG_DBG("\tModes: %s", modes[caps->modes]); +} + +static void blob_cli_end(struct bt_mesh_blob_cli *cli, + const struct bt_mesh_blob_xfer *xfer, bool success) +{ + if (success) { + LOG_DBG("Mesh BLOB transfer complete."); + } else { + LOG_DBG("Mesh BLOB transfer failed."); + } +} + +static const struct bt_mesh_blob_cli_cb blob_cli_handlers = { + .lost_target = blob_cli_lost_target, + .caps = blob_cli_caps, + .end = blob_cli_end, +}; + +static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers }; +#endif + +#if defined(CONFIG_BT_MESH_DFU_SRV) +const char *metadata_data = "1100000000000011"; + +static uint8_t dfu_fwid[] = { + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static struct bt_mesh_dfu_img dfu_imgs[] = { { + .fwid = &dfu_fwid, + .fwid_len = sizeof(dfu_fwid), +} }; + +static int dfu_meta_check(struct bt_mesh_dfu_srv *srv, + const struct bt_mesh_dfu_img *img, + struct net_buf_simple *metadata, + enum bt_mesh_dfu_effect *effect) +{ + char string[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1]; + int i; + size_t len; + + len = bin2hex(metadata->data, metadata->len, string, sizeof(string)); + string[len] = '\0'; + + for (i = 0; i <= len; i++) { + if (string[i] != metadata_data[i]) { + LOG_ERR("Wrong Firmware Metadata"); + return -EINVAL; + } + } + + return 0; +} + +static int dfu_start(struct bt_mesh_dfu_srv *srv, + const struct bt_mesh_dfu_img *img, + struct net_buf_simple *metadata, + const struct bt_mesh_blob_io **io) +{ + LOG_DBG("DFU setup"); + + *io = &dummy_blob_io; + + return 0; +} + +static void dfu_end(struct bt_mesh_dfu_srv *srv, + const struct bt_mesh_dfu_img *img, bool success) +{ + if (!success) { + LOG_ERR("DFU failed"); + return; + } + + if (!blob_valid) { + bt_mesh_dfu_srv_rejected(srv); + return; + } + + bt_mesh_dfu_srv_verified(srv); +} + +static int dfu_apply(struct bt_mesh_dfu_srv *srv, + const struct bt_mesh_dfu_img *img) +{ + if (!blob_valid) { + return -EINVAL; + } + + LOG_DBG("Applying DFU transfer..."); + + return 0; +} + +static const struct bt_mesh_dfu_srv_cb dfu_handlers = { + .check = dfu_meta_check, + .start = dfu_start, + .end = dfu_end, + .apply = dfu_apply, +}; + +static struct bt_mesh_dfu_srv dfu_srv = + BT_MESH_DFU_SRV_INIT(&dfu_handlers, dfu_imgs, ARRAY_SIZE(dfu_imgs)); +#endif /* CONFIG_BT_MESH_DFU_SRV */ /* Model Authentication Method */ #define AUTH_METHOD_STATIC 0x01 @@ -366,6 +607,16 @@ static struct bt_mesh_rpr_cli rpr_cli = { }; #endif +#if defined(CONFIG_BT_MESH_DFU_SRV) +static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("Applying image on server"); + bt_mesh_dfu_srv_applied(&dfu_srv); + return BTP_STATUS_SUCCESS; +} +#endif + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -389,8 +640,28 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_RPR_SRV) BT_MESH_MODEL_RPR_SRV, #endif +#if defined(CONFIG_BT_MESH_DFD_SRV) + BT_MESH_MODEL_DFD_SRV(&dfd_srv), +#endif +#if defined(CONFIG_BT_MESH_DFU_SRV) + BT_MESH_MODEL_DFU_SRV(&dfu_srv), +#endif +#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) + BT_MESH_MODEL_BLOB_CLI(&blob_cli), +#endif }; +struct model_data *lookup_model_bound(uint16_t id) +{ + int i; + for (i = 0; i < ARRAY_SIZE(model_bound); i++) { + if (model_bound[i].model && model_bound[i].model->id == id) { + return &model_bound[i]; + } + } + + return NULL; +} static struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, NULL), @@ -3089,145 +3360,782 @@ static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len, } #endif -static const struct btp_handler handlers[] = { - { - .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, - .index = BTP_INDEX_NONE, - .expect_len = 0, - .func = supported_commands, - }, - { - .opcode = BTP_MESH_CONFIG_PROVISIONING, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = config_prov, - }, - { - .opcode = BTP_MESH_PROVISION_NODE, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = provision_node, - }, - { - .opcode = BTP_MESH_INIT, - .expect_len = 0, - .func = init, - }, - { - .opcode = BTP_MESH_RESET, - .expect_len = 0, - .func = reset, - }, - { - .opcode = BTP_MESH_INPUT_NUMBER, - .expect_len = sizeof(struct btp_mesh_input_number_cmd), - .func = input_number, - }, - { - .opcode = BTP_MESH_INPUT_STRING, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = input_string, - }, - { - .opcode = BTP_MESH_IVU_TEST_MODE, - .expect_len = sizeof(struct btp_mesh_ivu_test_mode_cmd), - .func = ivu_test_mode, - }, - { - .opcode = BTP_MESH_IVU_TOGGLE_STATE, - .expect_len = 0, - .func = ivu_toggle_state, - }, - { - .opcode = BTP_MESH_LPN, - .expect_len = sizeof(struct btp_mesh_lpn_set_cmd), - .func = lpn, - }, - { - .opcode = BTP_MESH_LPN_POLL, - .expect_len = 0, - .func = lpn_poll, - }, - { - .opcode = BTP_MESH_NET_SEND, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = net_send, - }, - { - .opcode = BTP_MESH_HEALTH_GENERATE_FAULTS, - .expect_len = 0, - .func = health_generate_faults, - }, - { - .opcode = BTP_MESH_HEALTH_CLEAR_FAULTS, - .expect_len = 0, - .func = health_clear_faults, - }, - { - .opcode = BTP_MESH_MODEL_SEND, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = model_send, - }, - { - .opcode = BTP_MESH_COMP_DATA_GET, - .expect_len = sizeof(struct btp_mesh_comp_data_get_cmd), - .func = composition_data_get, - }, - { - .opcode = BTP_MESH_CFG_BEACON_GET, - .expect_len = sizeof(struct btp_mesh_cfg_beacon_get_cmd), - .func = config_beacon_get, - }, - { - .opcode = BTP_MESH_CFG_BEACON_SET, - .expect_len = sizeof(struct btp_mesh_cfg_beacon_set_cmd), - .func = config_beacon_set, - }, - { - .opcode = BTP_MESH_CFG_DEFAULT_TTL_GET, - .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_get_cmd), - .func = config_default_ttl_get, - }, - { - .opcode = BTP_MESH_CFG_DEFAULT_TTL_SET, - .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_set_cmd), - .func = config_default_ttl_set, - }, - { - .opcode = BTP_MESH_CFG_GATT_PROXY_GET, - .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_get_cmd), - .func = config_gatt_proxy_get, - }, - { - .opcode = BTP_MESH_CFG_GATT_PROXY_SET, - .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_set_cmd), - .func = config_gatt_proxy_set, - }, - { - .opcode = BTP_MESH_CFG_FRIEND_GET, - .expect_len = sizeof(struct btp_mesh_cfg_friend_get_cmd), - .func = config_friend_get, - }, - { - .opcode = BTP_MESH_CFG_FRIEND_SET, - .expect_len = sizeof(struct btp_mesh_cfg_friend_set_cmd), - .func = config_friend_set, - }, - { - .opcode = BTP_MESH_CFG_RELAY_GET, - .expect_len = sizeof(struct btp_mesh_cfg_relay_get_cmd), - .func = config_relay_get, - }, - { - .opcode = BTP_MESH_CFG_RELAY_SET, - .expect_len = sizeof(struct btp_mesh_cfg_relay_set_cmd), - .func = config_relay_set, - }, - { - .opcode = BTP_MESH_CFG_MODEL_PUB_GET, - .expect_len = sizeof(struct btp_mesh_cfg_model_pub_get_cmd), - .func = config_mod_pub_get, - }, - { - .opcode = BTP_MESH_CFG_MODEL_PUB_SET, +#if defined(CONFIG_BT_MESH_DFD_SRV) +static struct { + struct bt_mesh_dfu_target targets[32]; + struct bt_mesh_blob_target_pull pull[32]; + size_t target_cnt; + struct bt_mesh_blob_cli_inputs inputs; +} dfu_tx; + +static void dfu_tx_prepare(void) +{ + sys_slist_init(&dfu_tx.inputs.targets); + + for (int i = 0; i < dfu_tx.target_cnt; i++) { + /* Reset target context. */ + uint16_t addr = dfu_tx.targets[i].blob.addr; + + memset(&dfu_tx.targets[i].blob, 0, + sizeof(struct bt_mesh_blob_target)); + memset(&dfu_tx.pull[i], 0, + sizeof(struct bt_mesh_blob_target_pull)); + dfu_tx.targets[i].blob.addr = addr; + dfu_tx.targets[i].blob.pull = &dfu_tx.pull[i]; + + sys_slist_append(&dfu_tx.inputs.targets, + &dfu_tx.targets[i].blob.n); + } +} + +static void dfu_target(uint8_t img_idx, uint16_t addr) +{ + if (dfu_tx.target_cnt == ARRAY_SIZE(dfu_tx.targets)) { + LOG_ERR("No room."); + return; + } + + for (int i = 0; i < dfu_tx.target_cnt; i++) { + if (dfu_tx.targets[i].blob.addr == addr) { + LOG_ERR("Target 0x%04x already exists", addr); + return; + } + } + + dfu_tx.targets[dfu_tx.target_cnt].blob.addr = addr; + dfu_tx.targets[dfu_tx.target_cnt].img_idx = img_idx; + sys_slist_append(&dfu_tx.inputs.targets, + &dfu_tx.targets[dfu_tx.target_cnt].blob.n); + dfu_tx.target_cnt++; + + LOG_DBG("Added target 0x%04x", addr); +} +static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len, + uint8_t *metadata, size_t metadata_len) +{ + struct bt_mesh_dfu_slot *slot; + int err; + + slot = bt_mesh_dfu_slot_reserve(); + err = bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len); + if (err) { + LOG_ERR("Failed to set slot info: %d", err); + return; + } + + err = bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len); + if (err) { + LOG_ERR("Failed to set slot fwid: %d", err); + return; + } + + bt_mesh_dfu_slot_commit(slot); + if (err) { + LOG_ERR("Failed to commit slot: %d", err); + return; + } + + LOG_DBG("Slot added."); +} +static enum bt_mesh_dfu_iter dfu_img_cb(struct bt_mesh_dfu_cli *cli, + struct bt_mesh_msg_ctx *ctx, + uint8_t idx, uint8_t total, + const struct bt_mesh_dfu_img *img, + void *cb_data) +{ + char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1]; + size_t len; + + idx = 0xff; + + if (img->fwid_len <= sizeof(fwid)) { + len = bin2hex(img->fwid, img->fwid_len, fwid, sizeof(fwid)); + } else { + LOG_ERR("FWID is too big"); + return BT_MESH_DFU_ITER_STOP; + } + + fwid[len] = '\0'; + + LOG_DBG("Image %u:", idx); + LOG_DBG("\tFWID: "); + if (img->uri) { + LOG_DBG("\tURI: "); + } + + return BT_MESH_DFU_ITER_CONTINUE; +} + +static uint8_t dfu_info_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_dfu_info_get_cmd *cp = cmd; + struct model_data *model_bound; + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + uint8_t max_count; + int err = 0; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + ctx.addr = model_bound->addr; + ctx.app_idx = model_bound->appkey_idx; + + max_count = cp->limit; + + err = bt_mesh_dfu_cli_imgs_get(&dfd_srv.dfu, &ctx, dfu_img_cb, NULL, + max_count); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t dfu_update_metadata_check(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_dfu_metadata_check_cmd *cp = cmd; + struct btp_mmdl_dfu_metadata_check_rp *rp = rsp; + const struct bt_mesh_dfu_slot *slot; + struct model_data *model_bound; + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct bt_mesh_dfu_metadata_status rsp_data; + uint8_t img_idx, slot_idx; + size_t size; + size_t fwid_len; + size_t metadata_len; + uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; + uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + ctx.addr = model_bound->addr; + ctx.app_idx = model_bound->appkey_idx; + img_idx = cp->index; + slot_idx = cp->slot_idx; + size = cp->slot_size; + fwid_len = cp->fwid_len; + metadata_len = cp->metadata_len; + + if ((metadata_len > 0) && + (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) { + memcpy(&metadata, cp->data, metadata_len); + } + + dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len); + + slot = bt_mesh_dfu_slot_at(slot_idx); + if (!slot) { + LOG_ERR("No image in slot %u", slot_idx); + return BTP_STATUS_FAILED; + } + + err = bt_mesh_dfu_cli_metadata_check(&dfd_srv.dfu, &ctx, img_idx, slot, + &rsp_data); + + if (err) { + LOG_ERR("ERR %d", err); + return BTP_STATUS_FAILED; + } + + rp->idx = rsp_data.idx; + rp->status = rsp_data.status; + rp->effect = rsp_data.effect; + + *rsp_len = sizeof(struct btp_mmdl_dfu_metadata_check_rp); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t dfu_firmware_update_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct model_data *model_bound; + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct bt_mesh_dfu_target_status rsp_data; + struct btp_mmdl_dfu_firmware_update_rp *rp = rsp; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + ctx.addr = model_bound->addr; + ctx.app_idx = model_bound->appkey_idx; + + err = bt_mesh_dfu_cli_status_get(&dfd_srv.dfu, &ctx, &rsp_data); + if (err) { + LOG_ERR("err %d", err); + return BTP_STATUS_FAILED; + } + + rp->status = rsp_data.status; + *rsp_len = sizeof(struct btp_mmdl_dfu_firmware_update_rp); + return BTP_STATUS_SUCCESS; +} + +static uint8_t dfu_firmware_update_cancel(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct model_data *model_bound; + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + ctx.addr = model_bound->addr; + ctx.app_idx = model_bound->appkey_idx; + + err = bt_mesh_dfu_cli_cancel(&dfd_srv.dfu, &ctx); + if (err) { + LOG_ERR("err %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t dfu_firmware_update_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_dfu_firmware_update_cmd *cp = cmd; + struct model_data *model_bound; + struct bt_mesh_dfu_cli_xfer xfer; + uint8_t addr_cnt; + uint16_t addr = BT_MESH_ADDR_UNASSIGNED; + uint8_t slot_idx; + size_t size; + size_t fwid_len; + size_t metadata_len; + uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; + uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; + int err = 0; + int i = 0; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + struct bt_mesh_dfu_cli_xfer_blob_params blob = { + .block_size_log = cp->block_size, + .chunk_size = cp->chunk_size, + }; + + addr_cnt = cp->addr_cnt; + slot_idx = cp->slot_idx; + size = cp->slot_size; + fwid_len = cp->fwid_len; + metadata_len = cp->metadata_len; + xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; + xfer.blob_params = &blob; + + if ((metadata_len > 0) && + (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) { + memcpy(&metadata, cp->data, metadata_len); + } + + bt_mesh_dfu_slot_del_all(); + + dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len); + + xfer.slot = bt_mesh_dfu_slot_at(slot_idx); + if (!xfer.slot) { + LOG_ERR("No image in slot %u", slot_idx); + return BTP_STATUS_FAILED; + } + + for (i = 0; i < addr_cnt; i++) { + addr = cp->data[metadata_len + 1 + i * sizeof(uint16_t)] | + (cp->data[metadata_len + i * sizeof(uint16_t)] << 8); + dfu_target(slot_idx, addr); + } + + dfu_tx_prepare(); + + if (!dfu_tx.target_cnt) { + LOG_ERR("No targets."); + return BTP_STATUS_FAILED; + } + + if (addr_cnt > 1) { + dfu_tx.inputs.group = BT_MESH_ADDR_UNASSIGNED; + } else { + dfu_tx.inputs.group = addr; + } + + dfu_tx.inputs.app_idx = model_bound->appkey_idx; + dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT; + + err = bt_mesh_dfu_cli_send(&dfd_srv.dfu, &dfu_tx.inputs, &dummy_blob_io, &xfer); + + if (err) { + LOG_ERR("err %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t dfu_firmware_update_apply(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct model_data *model_bound; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + err = bt_mesh_dfu_cli_apply(&dfd_srv.dfu); + if (err) { + LOG_ERR("err %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + +#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) +static void blob_cli_inputs_prepare(uint16_t group, uint16_t app_idx) +{ + int i; + + blob_cli_xfer.inputs.ttl = BT_MESH_TTL_DEFAULT; + blob_cli_xfer.inputs.group = group; + blob_cli_xfer.inputs.app_idx = app_idx; + sys_slist_init(&blob_cli_xfer.inputs.targets); + + for (i = 0; i < blob_cli_xfer.target_count; ++i) { + /* Reset target context. */ + uint16_t addr = blob_cli_xfer.targets[i].addr; + + memset(&blob_cli_xfer.targets[i], 0, + sizeof(struct bt_mesh_blob_target)); + memset(&blob_cli_xfer.pull[i], 0, + sizeof(struct bt_mesh_blob_target_pull)); + blob_cli_xfer.targets[i].addr = addr; + blob_cli_xfer.targets[i].pull = &blob_cli_xfer.pull[i]; + + sys_slist_append(&blob_cli_xfer.inputs.targets, + &blob_cli_xfer.targets[i].n); + } +} + +static int cmd_blob_target(uint16_t addr) +{ + struct bt_mesh_blob_target *t; + + if (blob_cli_xfer.target_count == ARRAY_SIZE(blob_cli_xfer.targets)) { + LOG_ERR("No more room"); + return 0; + } + + t = &blob_cli_xfer.targets[blob_cli_xfer.target_count]; + + t->addr = addr; + + LOG_DBG("Added target 0x%04x", t->addr); + + blob_cli_xfer.target_count++; + return 0; +} + +static uint8_t blob_info_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_blob_info_get_cmd *cp = cmd; + struct model_data *model_bound; + uint16_t addr = BT_MESH_ADDR_UNASSIGNED; + uint16_t group = BT_MESH_ADDR_UNASSIGNED; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + for (int i = 0; i < cp->addr_cnt; i++) { + addr = cp->addr[1 + i * sizeof(uint16_t)] | + (cp->addr[i * sizeof(uint16_t)] << 8); + err = cmd_blob_target(addr); + if (err) { + LOG_ERR("err target %d", err); + return BTP_STATUS_FAILED; + } + } + + if (cp->addr_cnt > 1) { + group = BT_MESH_ADDR_UNASSIGNED; + } else { + group = addr; + } + + if (!blob_cli_xfer.target_count) { + LOG_ERR("Failed: No targets"); + return BTP_STATUS_FAILED; + } + + blob_cli_inputs_prepare(group, model_bound->appkey_idx); + + err = bt_mesh_blob_cli_caps_get(&blob_cli, &blob_cli_xfer.inputs); + + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_blob_transfer_start_cmd *cp = cmd; + struct model_data *model_bound; + int err = 0; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + if (!blob_cli_xfer.target_count) { + LOG_ERR("Failed: No targets"); + return BTP_STATUS_FAILED; + } + blob_cli_xfer.xfer.id = cp->id; + blob_cli_xfer.xfer.size = cp->size; + blob_cli_xfer.xfer.block_size_log = cp->block_size; + blob_cli_xfer.xfer.chunk_size = cp->chunk_size; + + if (blob_cli.caps.modes) { + blob_cli_xfer.xfer.mode = blob_cli.caps.modes; + } else { + blob_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; + } + + if (cp->timeout) { + blob_cli_xfer.inputs.timeout_base = cp->timeout; + } + + err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs, + &blob_cli_xfer.xfer, &dummy_blob_io); + + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t blob_transfer_cancel(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG(""); + + bt_mesh_blob_cli_cancel(&blob_cli); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t blob_transfer_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct model_data *model_bound; + uint16_t group; + int err; + + LOG_DBG(""); + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + group = model_bound->addr; + + err = cmd_blob_target(group); + if (err) { + LOG_ERR("err target %d", err); + return BTP_STATUS_FAILED; + } + + if (!blob_cli_xfer.target_count) { + LOG_ERR("Failed: No targets"); + return BTP_STATUS_FAILED; + } + + blob_cli_inputs_prepare(group, model_bound->appkey_idx); + + err = bt_mesh_blob_cli_xfer_progress_get(&blob_cli, &blob_cli_xfer.inputs); + + if (err) { + LOG_ERR("ERR %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif /* CONFIG_BT_MESH_BLOB_CLI */ + +#if defined(CONFIG_BT_MESH_BLOB_SRV) +static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mmdl_blob_srv_recv_cmd *cp = cmd; + struct model_data *model_bound; + int err; + +#if defined(CONFIG_BT_MESH_DFU_SRV) + struct bt_mesh_blob_srv *srv = &dfu_srv.blob; +#elif defined(CONFIG_BT_MESH_DFD_SRV) + struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; +#endif + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + uint16_t timeout_base; + uint64_t id; + + LOG_DBG(""); + + id = cp->id; + timeout_base = cp->timeout; + + err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, BT_MESH_TTL_MAX, + timeout_base); + + if (err) { + LOG_ERR("ERR %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t blob_srv_cancel(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct model_data *model_bound; + int err; + +#if defined(CONFIG_BT_MESH_DFU_SRV) + struct bt_mesh_blob_srv *srv = &dfu_srv.blob; +#elif defined(CONFIG_BT_MESH_DFD_SRV) + struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; +#endif + + model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); + if (!model_bound) { + LOG_ERR("Model not found"); + return BTP_STATUS_FAILED; + } + + LOG_DBG(""); + + err = bt_mesh_blob_srv_cancel(srv); + + if (err) { + LOG_ERR("ERR %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + +static const struct btp_handler handlers[] = { + { + .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_MESH_CONFIG_PROVISIONING, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = config_prov, + }, + { + .opcode = BTP_MESH_PROVISION_NODE, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = provision_node, + }, + { + .opcode = BTP_MESH_INIT, + .expect_len = 0, + .func = init, + }, + { + .opcode = BTP_MESH_RESET, + .expect_len = 0, + .func = reset, + }, + { + .opcode = BTP_MESH_INPUT_NUMBER, + .expect_len = sizeof(struct btp_mesh_input_number_cmd), + .func = input_number, + }, + { + .opcode = BTP_MESH_INPUT_STRING, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = input_string, + }, + { + .opcode = BTP_MESH_IVU_TEST_MODE, + .expect_len = sizeof(struct btp_mesh_ivu_test_mode_cmd), + .func = ivu_test_mode, + }, + { + .opcode = BTP_MESH_IVU_TOGGLE_STATE, + .expect_len = 0, + .func = ivu_toggle_state, + }, + { + .opcode = BTP_MESH_LPN, + .expect_len = sizeof(struct btp_mesh_lpn_set_cmd), + .func = lpn, + }, + { + .opcode = BTP_MESH_LPN_POLL, + .expect_len = 0, + .func = lpn_poll, + }, + { + .opcode = BTP_MESH_NET_SEND, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = net_send, + }, + { + .opcode = BTP_MESH_HEALTH_GENERATE_FAULTS, + .expect_len = 0, + .func = health_generate_faults, + }, + { + .opcode = BTP_MESH_HEALTH_CLEAR_FAULTS, + .expect_len = 0, + .func = health_clear_faults, + }, + { + .opcode = BTP_MESH_MODEL_SEND, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = model_send, + }, + { + .opcode = BTP_MESH_COMP_DATA_GET, + .expect_len = sizeof(struct btp_mesh_comp_data_get_cmd), + .func = composition_data_get, + }, + { + .opcode = BTP_MESH_CFG_BEACON_GET, + .expect_len = sizeof(struct btp_mesh_cfg_beacon_get_cmd), + .func = config_beacon_get, + }, + { + .opcode = BTP_MESH_CFG_BEACON_SET, + .expect_len = sizeof(struct btp_mesh_cfg_beacon_set_cmd), + .func = config_beacon_set, + }, + { + .opcode = BTP_MESH_CFG_DEFAULT_TTL_GET, + .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_get_cmd), + .func = config_default_ttl_get, + }, + { + .opcode = BTP_MESH_CFG_DEFAULT_TTL_SET, + .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_set_cmd), + .func = config_default_ttl_set, + }, + { + .opcode = BTP_MESH_CFG_GATT_PROXY_GET, + .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_get_cmd), + .func = config_gatt_proxy_get, + }, + { + .opcode = BTP_MESH_CFG_GATT_PROXY_SET, + .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_set_cmd), + .func = config_gatt_proxy_set, + }, + { + .opcode = BTP_MESH_CFG_FRIEND_GET, + .expect_len = sizeof(struct btp_mesh_cfg_friend_get_cmd), + .func = config_friend_get, + }, + { + .opcode = BTP_MESH_CFG_FRIEND_SET, + .expect_len = sizeof(struct btp_mesh_cfg_friend_set_cmd), + .func = config_friend_set, + }, + { + .opcode = BTP_MESH_CFG_RELAY_GET, + .expect_len = sizeof(struct btp_mesh_cfg_relay_get_cmd), + .func = config_relay_get, + }, + { + .opcode = BTP_MESH_CFG_RELAY_SET, + .expect_len = sizeof(struct btp_mesh_cfg_relay_set_cmd), + .func = config_relay_set, + }, + { + .opcode = BTP_MESH_CFG_MODEL_PUB_GET, + .expect_len = sizeof(struct btp_mesh_cfg_model_pub_get_cmd), + .func = config_mod_pub_get, + }, + { + .opcode = BTP_MESH_CFG_MODEL_PUB_SET, .expect_len = sizeof(struct btp_mesh_cfg_model_pub_set_cmd), .func = config_mod_pub_set, }, @@ -3577,6 +4485,83 @@ static const struct btp_handler handlers[] = { }, }; + +static const struct btp_handler mdl_handlers[] = { +#if defined(CONFIG_BT_MESH_DFD_SRV) + { + .opcode = BTP_MMDL_DFU_INFO_GET, + .expect_len = sizeof(struct btp_mmdl_dfu_info_get_cmd), + .func = dfu_info_get, + }, + { + .opcode = BTP_MMDL_DFU_UPDATE_METADATA_CHECK, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = dfu_update_metadata_check, + }, + { + .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_GET, + .expect_len = 0, + .func = dfu_firmware_update_get, + }, + { + .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL, + .expect_len = 0, + .func = dfu_firmware_update_cancel, + }, + { + .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_START, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = dfu_firmware_update_start, + }, + { + .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY, + .expect_len = 0, + .func = dfu_firmware_update_apply, + }, +#endif +#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) + { + .opcode = BTP_MMDL_BLOB_INFO_GET, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = blob_info_get, + }, + { + .opcode = BTP_MMDL_BLOB_TRANSFER_START, + .expect_len = sizeof(struct btp_mmdl_blob_transfer_start_cmd), + .func = blob_transfer_start, + }, + { + .opcode = BTP_MMDL_BLOB_TRANSFER_CANCEL, + .expect_len = 0, + .func = blob_transfer_cancel, + }, + { + .opcode = BTP_MMDL_BLOB_TRANSFER_GET, + .expect_len = 0, + .func = blob_transfer_get, + }, +#endif +#if defined(CONFIG_BT_MESH_BLOB_SRV) + { + .opcode = BTP_MMDL_BLOB_SRV_RECV, + .expect_len = sizeof(struct btp_mmdl_blob_srv_recv_cmd), + .func = blob_srv_recv + }, + { + .opcode = BTP_MMDL_BLOB_SRV_CANCEL, + .expect_len = 0, + .func = blob_srv_cancel + }, +#endif +#if defined(CONFIG_BT_MESH_DFU_SRV) + { + .opcode = BTP_MMDL_DFU_SRV_APPLY, + .expect_len = 0, + .func = dfu_srv_apply + }, +#endif +}; + void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { @@ -3785,3 +4770,15 @@ uint8_t tester_unregister_mesh(void) { return BTP_STATUS_SUCCESS; } + +uint8_t tester_init_mmdl(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_MESH_MDL, mdl_handlers, + ARRAY_SIZE(mdl_handlers)); + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_mmdl(void) +{ + return BTP_STATUS_SUCCESS; +} From 1e5eeb83f41ae2c0dc50062ccfd921101cadaa1b Mon Sep 17 00:00:00 2001 From: Michal Narajowski Date: Mon, 13 Jun 2022 14:09:32 +0200 Subject: [PATCH 1268/4498] tests: bluetooth: tester: Add Opcodes Aggregator support - Add entry for client and server in composition data. - Add Client commands to aggregate and send messages. MESH/SR/AGG/BV-02-C requires more key slots. Signed-off-by: Michal Narajowski --- tests/bluetooth/tester/overlay-mesh.conf | 5 + tests/bluetooth/tester/src/btp/btp_mesh.h | 10 ++ tests/bluetooth/tester/src/btp_mesh.c | 115 +++++++++++++++++++--- 3 files changed, 119 insertions(+), 11 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 3352e36f3a4..60f809f77e5 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -9,6 +9,11 @@ CONFIG_BT_MESH_GATT_PROXY=y CONFIG_BT_MESH_LABEL_COUNT=2 CONFIG_BT_MESH_SUBNET_COUNT=2 CONFIG_BT_MESH_MODEL_GROUP_COUNT=2 +CONFIG_BT_MESH_OP_AGG_CLI=y +CONFIG_BT_MESH_OP_AGG_SRV=y +# PTS requires more key slots. +# First one is implicitly taken by Device Key. +CONFIG_BT_MESH_MODEL_KEY_COUNT=3 CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 66a86bbb128..63fb2adcf12 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -835,6 +835,16 @@ struct btp_mesh_models_metadata_get_rp { uint8_t data[0]; } __packed; +#define BTP_MESH_OPCODES_AGGREGATOR_INIT 0x55 +struct btp_mesh_opcodes_aggregator_init_cmd { + uint16_t net_idx; + uint16_t app_idx; + uint16_t dst; + uint16_t elem_addr; +} __packed; + +#define BTP_MESH_OPCODES_AGGREGATOR_SEND 0x56 + #define BTP_MESH_COMP_CHANGE_PREPARE 0x57 #define BTP_MESH_SET_COMP_ALT 0x58 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 8c637320a11..4f3d181fd1d 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -634,6 +634,12 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), #endif +#if defined(CONFIG_BT_MESH_OP_AGG_SRV) + BT_MESH_MODEL_OP_AGG_SRV, +#endif +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + BT_MESH_MODEL_OP_AGG_CLI, +#endif #if defined(CONFIG_BT_MESH_RPR_CLI) BT_MESH_MODEL_RPR_CLI(&rpr_cli), #endif @@ -2491,6 +2497,8 @@ static uint8_t config_model_app_bind(const void *cmd, uint16_t cmd_len, LOG_DBG(""); + bt_mesh_cfg_cli_timeout_set(5000); + err = bt_mesh_cfg_cli_mod_app_bind(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->address), sys_le16_to_cpu(cp->elem_address), @@ -2934,7 +2942,7 @@ static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len, .addr = sys_le16_to_cpu(cp->address), .app_idx = sys_le16_to_cpu(cp->app_idx), }; - uint8_t test_id; + uint8_t test_id = 0; size_t fault_count = 16; uint8_t faults[fault_count]; int err; @@ -2944,7 +2952,20 @@ static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_fault_clear(&health_cli, &ctx, sys_le16_to_cpu(cp->cid), - &test_id, faults, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif + &test_id, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif + faults, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif &fault_count); } else { err = bt_mesh_health_cli_fault_clear_unack(&health_cli, &ctx, @@ -2977,20 +2998,37 @@ static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len, }; size_t fault_count = 16; uint8_t faults[fault_count]; - uint8_t test_id; - uint16_t cid; int err; LOG_DBG(""); - test_id = cp->test_id; - cid = sys_le16_to_cpu(cp->cid); - if (cp->ack) { - err = bt_mesh_health_cli_fault_test(&health_cli, &ctx, cid, test_id, faults, + err = bt_mesh_health_cli_fault_test(&health_cli, &ctx, + sys_le16_to_cpu(cp->cid), +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + 0 : +#endif + cp->test_id, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif + faults, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif &fault_count); +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + if (bt_mesh_op_agg_cli_seq_is_started()) { + fault_count = 0; + } +#endif } else { - err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx, cid, test_id); + err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx, + sys_le16_to_cpu(cp->cid), + cp->test_id); } if (err) { @@ -3001,8 +3039,8 @@ static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len, if (cp->ack) { struct btp_mesh_health_fault_test_rp *rp = rsp; - rp->test_id = test_id; - rp->cid = sys_cpu_to_le16(cid); + rp->test_id = cp->test_id; + rp->cid = cp->cid; (void)memcpy(rp->faults, faults, fault_count); *rsp_len = sizeof(*rp) + fault_count; @@ -3051,6 +3089,10 @@ static uint8_t health_period_set(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_period_set(&health_cli, &ctx, cp->divisor, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif &updated_divisor); } else { err = bt_mesh_health_cli_period_set_unack(&health_cli, &ctx, cp->divisor); @@ -3112,6 +3154,10 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_attention_set(&health_cli, &ctx, cp->attention, +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + bt_mesh_op_agg_cli_seq_is_started() ? + NULL : +#endif &updated_attention); } else { err = bt_mesh_health_cli_attention_set_unack(&health_cli, &ctx, cp->attention); @@ -3133,6 +3179,41 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) +static uint8_t opcodes_aggregator_init(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_opcodes_aggregator_init_cmd *cp = cmd; + int err; + + LOG_DBG(""); + + err = bt_mesh_op_agg_cli_seq_start(cp->net_idx, cp->app_idx, cp->dst, cp->elem_addr); + if (err) { + LOG_ERR("Failed to init Opcodes Aggregator Context (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t opcodes_aggregator_send(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_mesh_op_agg_cli_seq_send(); + if (err) { + LOG_ERR("Failed to send Opcodes Aggregator message (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + #if defined(CONFIG_BT_MESH_RPR_CLI) static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -4426,6 +4507,18 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd), .func = models_metadata_get }, +#endif +#if defined(CONFIG_BT_MESH_OP_AGG_CLI) + { + .opcode = BTP_MESH_OPCODES_AGGREGATOR_INIT, + .expect_len = sizeof(struct btp_mesh_opcodes_aggregator_init_cmd), + .func = opcodes_aggregator_init + }, + { + .opcode = BTP_MESH_OPCODES_AGGREGATOR_SEND, + .expect_len = 0, + .func = opcodes_aggregator_send + }, #endif { .opcode = BTP_MESH_COMP_CHANGE_PREPARE, From 7b69f8faf0ee6457702fd6a37d020ceec8f9f9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 23 Jun 2022 10:32:50 +0200 Subject: [PATCH 1269/4498] Tests: Bluetooth: Tester: Add BTP command to enable Private NID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to advertise beacons with Private Node Identity on demand, like was available for regular Node Identity. Signed-off-by: Krzysztof Kopyściński --- tests/bluetooth/tester/overlay-mesh.conf | 3 + tests/bluetooth/tester/src/btp/btp_mesh.h | 38 +++++ tests/bluetooth/tester/src/btp_mesh.c | 177 ++++++++++++++++++++++ 3 files changed, 218 insertions(+) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 60f809f77e5..95a61769a1a 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -43,5 +43,8 @@ CONFIG_BT_MESH_BLOB_SRV=y CONFIG_BT_MESH_DFU_SRV=y CONFIG_BT_MESH_DFD_SRV=y CONFIG_BT_MESH_DFU_SLOT_CNT=2 +CONFIG_BT_MESH_PRIV_BEACONS=y +CONFIG_BT_MESH_PRIV_BEACON_SRV=y +CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 63fb2adcf12..e93c2ceeb3d 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -971,6 +971,44 @@ struct btp_mmdl_blob_transfer_start_cmd { #define BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY 0x6A #define BTP_MMDL_DFU_SRV_APPLY 0x6B +#define BTP_MESH_PRIV_BEACON_GET 0x6c +struct btp_priv_beacon_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_PRIV_BEACON_SET 0x6d +struct btp_priv_beacon_set_cmd { + uint16_t dst; + uint8_t enabled; + uint8_t rand_interval; +} __packed; + +#define BTP_MESH_PRIV_GATT_PROXY_GET 0x6e +struct btp_priv_gatt_proxy_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_PRIV_GATT_PROXY_SET 0x6f +struct btp_priv_gatt_proxy_set_cmd { + uint16_t dst; + uint8_t state; +} __packed; + +#define BTP_MESH_PRIV_NODE_ID_GET 0x70 +struct btp_priv_node_id_get_cmd { + uint16_t dst; + uint16_t key_net_idx; +} __packed; + +#define BTP_MESH_PRIV_NODE_ID_SET 0x71 +struct btp_priv_node_id_set_cmd { + uint16_t dst; + uint16_t net_idx; + uint8_t state; +} __packed; + +#define BTP_MESH_PROXY_PRIVATE_IDENTITY 0x72 + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 4f3d181fd1d..5a7b4bb5fd7 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -617,6 +617,139 @@ static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len, } #endif +#ifdef CONFIG_BT_MESH_PRIV_BEACON_CLI +static struct bt_mesh_priv_beacon_cli priv_beacon_cli; + +static uint8_t priv_beacon_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_beacon_get_cmd *cp = cmd; + + struct bt_mesh_priv_beacon val; + int err; + + err = bt_mesh_priv_beacon_cli_get(net.net_idx, cp->dst, &val); + if (err) { + LOG_ERR("Failed to send Private Beacon Get (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Private Beacon state: %u, %u", val.enabled, val.rand_interval); + return BTP_STATUS_SUCCESS; +} + +static uint8_t priv_beacon_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_beacon_set_cmd *cp = cmd; + struct bt_mesh_priv_beacon val; + int err; + + val.enabled = cp->enabled; + val.rand_interval = cp->rand_interval; + + err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val); + if (err) { + LOG_ERR("Failed to send Private Beacon Set (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t priv_gatt_proxy_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_gatt_proxy_get_cmd *cp = cmd; + + uint8_t state; + int err; + + err = bt_mesh_priv_beacon_cli_gatt_proxy_get(net.net_idx, cp->dst, &state); + if (err) { + LOG_ERR("Failed to send Private GATT Proxy Get (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Private GATT Proxy state: %u", state); + return BTP_STATUS_SUCCESS; +} + +static uint8_t priv_gatt_proxy_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_gatt_proxy_set_cmd *cp = cmd; + + uint8_t state; + int err; + + state = cp->state; + + err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, &state); + if (err) { + LOG_ERR("Failed to send Private GATT Proxy Set (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t priv_node_id_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_node_id_get_cmd *cp = cmd; + struct bt_mesh_priv_node_id val; + uint16_t key_net_idx; + int err; + + key_net_idx = cp->key_net_idx; + + err = bt_mesh_priv_beacon_cli_node_id_get(net.net_idx, cp->dst, key_net_idx, &val); + if (err) { + LOG_ERR("Failed to send Private Node Identity Get (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("Private Node Identity state: %u %u %u", val.net_idx, val.state, val.status); + return BTP_STATUS_SUCCESS; +} + +static uint8_t priv_node_id_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_priv_node_id_set_cmd *cp = cmd; + struct bt_mesh_priv_node_id val; + int err; + + val.net_idx = cp->net_idx; + val.state = cp->state; + + err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val); + if (err) { + LOG_ERR("Failed to send Private Node Identity Set (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_mesh_proxy_private_identity_enable(); + if (err) { + LOG_ERR("Failed to enable proxy private identity (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -655,6 +788,12 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) BT_MESH_MODEL_BLOB_CLI(&blob_cli), #endif +#if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV) + BT_MESH_MODEL_PRIV_BEACON_SRV, +#endif +#if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) + BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), +#endif }; struct model_data *lookup_model_bound(uint16_t id) { @@ -4576,6 +4715,44 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd), .func = rpr_reprov_remote }, +#endif +#if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) + { + .opcode = BTP_MESH_PRIV_BEACON_GET, + .expect_len = sizeof(struct btp_priv_beacon_get_cmd), + .func = priv_beacon_get + }, + { + .opcode = BTP_MESH_PRIV_BEACON_SET, + .expect_len = sizeof(struct btp_priv_beacon_set_cmd), + .func = priv_beacon_set + }, + { + .opcode = BTP_MESH_PRIV_GATT_PROXY_GET, + .expect_len = sizeof(struct btp_priv_gatt_proxy_get_cmd), + .func = priv_gatt_proxy_get + }, + { + .opcode = BTP_MESH_PRIV_GATT_PROXY_SET, + .expect_len = sizeof(struct btp_priv_gatt_proxy_set_cmd), + .func = priv_gatt_proxy_set + }, + { + .opcode = BTP_MESH_PRIV_NODE_ID_GET, + .expect_len = sizeof(struct btp_priv_node_id_get_cmd), + .func = priv_node_id_get + }, + { + .opcode = BTP_MESH_PRIV_NODE_ID_SET, + .expect_len = sizeof(struct btp_priv_node_id_set_cmd), + .func = priv_node_id_set + }, + { + .opcode = BTP_MESH_PROXY_PRIVATE_IDENTITY, + .expect_len = 0, + .func = proxy_private_identity_enable + }, +#endif }; From 26e697bd04ccb702268949490733d93eeab3a303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 9 Sep 2022 11:40:32 +0200 Subject: [PATCH 1270/4498] tests: Bluetooth: tester: enable Composition Data Page 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to tests this page using BTP protocol. Signed-off-by: Krzysztof Kopyściński --- tests/bluetooth/tester/overlay-mesh.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 95a61769a1a..fe4c9a62fef 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -46,5 +46,7 @@ CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_BT_MESH_PRIV_BEACONS=y CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y +CONFIG_BT_MESH_MODEL_EXTENSIONS=y +CONFIG_BT_MESH_COMP_PAGE_1=y CONFIG_SETTINGS=y From 2ad0eaa9ab548336fd37f064315f5427650a8c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Tue, 31 Jan 2023 14:44:41 +0100 Subject: [PATCH 1271/4498] tests: Bluetooth: tester: Add Models Metadata Page 128 Add Models Metadata Page 128 support to tester. Signed-off-by: Michal Narajowski Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp_mesh.c | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 5a7b4bb5fd7..2c837bfb198 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -542,8 +542,31 @@ static uint8_t health_tests[] = { BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03), }; +static uint8_t zero_metadata[100]; + static struct bt_mesh_models_metadata_entry health_srv_meta[] = { BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests), + { + .len = ARRAY_SIZE(zero_metadata), + .id = 0xABCD, + .data = zero_metadata, + }, + BT_MESH_MODELS_METADATA_END, +}; + +static uint8_t health_tests_alt[] = { + BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66), + BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x11, 0x22, 0x33), +}; + +static struct bt_mesh_models_metadata_entry health_srv_meta_alt[] = { + BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests_alt), + { + .len = ARRAY_SIZE(zero_metadata), + .id = 0xFEED, + .data = zero_metadata, + }, BT_MESH_MODELS_METADATA_END, }; #endif @@ -1709,6 +1732,13 @@ static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } +#if CONFIG_BT_MESH_LARGE_COMP_DATA_SRV + err = bt_mesh_models_metadata_change_prepare(); + if (err < 0) { + return BTP_STATUS_FAILED; + } +#endif + return BTP_STATUS_SUCCESS; } @@ -5026,6 +5056,9 @@ uint8_t tester_init_mesh(void) if (default_comp) { err = bt_mesh_init(&prov, &comp); } else { +#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV + health_srv.metadata = health_srv_meta_alt; +#endif err = bt_mesh_init(&prov, &comp_alt); } From a8334210c1fa59a662a07a8189c7313c9d0af218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 19 May 2023 14:29:50 +0200 Subject: [PATCH 1272/4498] tests: Bluetooth: tester: add support for Proxy Solicitation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds BTP commands implemantation needed to pass tests for Proxy Solicitation. Signed-off-by: Krzysztof Kopyściński --- tests/bluetooth/tester/src/btp/btp_mesh.h | 27 +++++ tests/bluetooth/tester/src/btp_mesh.c | 138 ++++++++++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index e93c2ceeb3d..ea5d89de07a 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -1009,6 +1009,33 @@ struct btp_priv_node_id_set_cmd { #define BTP_MESH_PROXY_PRIVATE_IDENTITY 0x72 +#define BTP_MESH_OD_PRIV_PROXY_GET 0x73 +struct btp_od_priv_proxy_get_cmd { + uint16_t dst; +} __packed; + +#define BTP_MESH_OD_PRIV_PROXY_SET 0x74 + +struct btp_od_priv_proxy_set_cmd { + uint16_t dst; + uint8_t val; +} __packed; + +#define BTP_MESH_SRPL_CLEAR 0x75 + +struct btp_srpl_clear_cmd { + uint16_t dst; + uint16_t range_start; + uint8_t range_len; + uint8_t acked; +} __packed; + +#define BTP_MESH_PROXY_SOLICIT 0x76 + +struct btp_proxy_solicit_cmd { + uint16_t net_idx; +} __packed; + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 2c837bfb198..b9297474860 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -773,6 +773,108 @@ static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len, } #endif +#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) +static struct bt_mesh_sol_pdu_rpl_cli srpl_cli; +#endif + + +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) +static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli; + +static uint8_t od_priv_proxy_get(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_od_priv_proxy_get_cmd *cp = cmd; + uint8_t val_rsp; + int err; + + LOG_DBG(""); + + err = bt_mesh_od_priv_proxy_cli_get(net.net_idx, cp->dst, &val_rsp); + if (err) { + LOG_ERR("Failed to get On-Demand Private Proxy state (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("On-Demand Private Proxy state: %u", val_rsp); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t od_priv_proxy_set(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_od_priv_proxy_set_cmd *cp = cmd; + uint8_t val_rsp; + int err; + + LOG_DBG(""); + + err = bt_mesh_od_priv_proxy_cli_set(net.net_idx, cp->dst, cp->val, &val_rsp); + if (err) { + LOG_ERR("Failed to set On-Demand Private Proxy state (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("On-Demand Private Proxy set state: %u", val_rsp); + + return BTP_STATUS_SUCCESS; +} + +#endif + +#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) +static uint8_t srpl_clear(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_srpl_clear_cmd *cp = cmd; + uint16_t app_idx = BT_MESH_KEY_UNUSED; + uint16_t start_rsp; + uint8_t len_rsp; + int err; + + /* Lookup source address */ + for (int i = 0; i < ARRAY_SIZE(model_bound); i++) { + if (model_bound[i].model->id == BT_MESH_MODEL_ID_SOL_PDU_RPL_CLI) { + app_idx = model_bound[i].appkey_idx; + break; + } + } + + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(app_idx, cp->dst); + + if (cp->acked) { + err = bt_mesh_sol_pdu_rpl_clear(&ctx, cp->range_start, cp->range_len, &start_rsp, + &len_rsp); + } else { + err = bt_mesh_sol_pdu_rpl_clear_unack(&ctx, cp->range_start, cp->range_len); + } + if (err) { + LOG_ERR("Failed to clear SRPL (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + +#if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) +static uint8_t proxy_solicit(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_proxy_solicit_cmd *cp = cmd; + int err; + + err = bt_mesh_proxy_solicit(cp->net_idx); + if (err) { + LOG_ERR("Failed to advertise solicitation PDU (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */ + static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -817,6 +919,16 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) + BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli), +#endif +#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) + BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli), +#endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + BT_MESH_MODEL_OD_PRIV_PROXY_SRV, +#endif + }; struct model_data *lookup_model_bound(uint16_t id) { @@ -4783,6 +4895,32 @@ static const struct btp_handler handlers[] = { .func = proxy_private_identity_enable }, #endif +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) + { + .opcode = BTP_MESH_OD_PRIV_PROXY_GET, + .expect_len = sizeof(struct btp_od_priv_proxy_get_cmd), + .func = od_priv_proxy_get + }, + { + .opcode = BTP_MESH_OD_PRIV_PROXY_SET, + .expect_len = sizeof(struct btp_od_priv_proxy_set_cmd), + .func = od_priv_proxy_set + }, +#endif +#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) + { + .opcode = BTP_MESH_SRPL_CLEAR, + .expect_len = sizeof(struct btp_srpl_clear_cmd), + .func = srpl_clear + }, +#endif +#if defined(CONFIG_BT_MESH_SOLICITATION) + { + .opcode = BTP_MESH_PROXY_SOLICIT, + .expect_len = sizeof(struct btp_proxy_solicit_cmd), + .func = proxy_solicit + }, +#endif }; From b7579065f95535f16a1b5aaffed14437b51f7520 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 22 Sep 2023 14:22:42 +0200 Subject: [PATCH 1273/4498] tests: bluetooth: tester: Move mesh-1.1 features to a separate conf This allows to compile mesh tester for 1.0.1 and 1.1 specs sepately. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 29 +++++++++++++++++++ tests/bluetooth/tester/overlay-mesh.conf | 29 +------------------ tests/bluetooth/tester/testcase.yaml | 9 ++++++ 3 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 tests/bluetooth/tester/overlay-mesh-v1d1.conf diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf new file mode 100644 index 00000000000..7a3907cc78c --- /dev/null +++ b/tests/bluetooth/tester/overlay-mesh-v1d1.conf @@ -0,0 +1,29 @@ +CONFIG_ENTROPY_GENERATOR=y + +CONFIG_BT_MESH_V1d1=y +CONFIG_BT_MESH_OP_AGG_CLI=y +CONFIG_BT_MESH_OP_AGG_SRV=y +# PTS requires more key slots. +# First one is implicitly taken by Device Key. +CONFIG_BT_MESH_MODEL_KEY_COUNT=3 +CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y +CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y +CONFIG_BT_MESH_SAR_CFG_SRV=y +CONFIG_BT_MESH_SAR_CFG_CLI=y +CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 +CONFIG_BT_MESH_RPR_SRV=y +CONFIG_BT_MESH_RPR_CLI=y +CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 +CONFIG_BT_MESH_BLOB_CLI=y +CONFIG_BT_MESH_DFU_CLI=y +CONFIG_BT_MESH_BLOB_SRV=y +CONFIG_BT_MESH_DFU_SRV=y +CONFIG_BT_MESH_DFD_SRV=y +CONFIG_BT_MESH_DFU_SLOT_CNT=2 +CONFIG_BT_MESH_PRIV_BEACONS=y +CONFIG_BT_MESH_PRIV_BEACON_SRV=y +CONFIG_BT_MESH_PRIV_BEACON_CLI=y +CONFIG_BT_MESH_MODEL_EXTENSIONS=y +CONFIG_BT_MESH_COMP_PAGE_1=y + +CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index fe4c9a62fef..840af06c1c0 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -1,5 +1,4 @@ CONFIG_BT_MESH=y -CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PB_GATT=y @@ -9,23 +8,14 @@ CONFIG_BT_MESH_GATT_PROXY=y CONFIG_BT_MESH_LABEL_COUNT=2 CONFIG_BT_MESH_SUBNET_COUNT=2 CONFIG_BT_MESH_MODEL_GROUP_COUNT=2 -CONFIG_BT_MESH_OP_AGG_CLI=y -CONFIG_BT_MESH_OP_AGG_SRV=y -# PTS requires more key slots. -# First one is implicitly taken by Device Key. -CONFIG_BT_MESH_MODEL_KEY_COUNT=3 CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y -CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y -CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y -CONFIG_BT_MESH_SAR_CFG_SRV=y -CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 -CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 +CONFIG_BT_MESH_TX_SEG_MSG_COUNT=3 CONFIG_BT_MESH_LPN_POLL_TIMEOUT=100 CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_CDB=y @@ -33,20 +23,3 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y -CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_RPR_SRV=y -CONFIG_BT_MESH_RPR_CLI=y -CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 -CONFIG_BT_MESH_BLOB_CLI=y -CONFIG_BT_MESH_DFU_CLI=y -CONFIG_BT_MESH_BLOB_SRV=y -CONFIG_BT_MESH_DFU_SRV=y -CONFIG_BT_MESH_DFD_SRV=y -CONFIG_BT_MESH_DFU_SLOT_CNT=2 -CONFIG_BT_MESH_PRIV_BEACONS=y -CONFIG_BT_MESH_PRIV_BEACON_SRV=y -CONFIG_BT_MESH_PRIV_BEACON_CLI=y -CONFIG_BT_MESH_MODEL_EXTENSIONS=y -CONFIG_BT_MESH_COMP_PAGE_1=y - -CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index 65588568994..dba67716af1 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -25,3 +25,12 @@ tests: extra_args: OVERLAY_CONFIG="overlay-mesh.conf" tags: bluetooth harness: bluetooth + bluetooth.general.tester_mesh_v1d1: + build_only: true + platform_allow: + - qemu_x86 + - native_posix + - nrf52840dk_nrf52840 + extra_args: OVERLAY_CONFIG="overlay-mesh.conf;overlay-mesh-v1d1.conf" + tags: bluetooth + harness: bluetooth From 3bfeadfa4a68666a4e7ec5b8752860c6e9efe844 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 27 Sep 2023 14:27:33 +0200 Subject: [PATCH 1274/4498] Bluetooth: Controller: Fix ULL_HIGH ticker operations count Fix ULL_HIGH ticker operations count, it is discovered in new BabbleSim test implementations that mesh tests using Extended Advertising and Scanning enqueue upto 4 ticker operations before ULL_LOW ticker_job could process it. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 916b21cee31..f315fd2d337 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -278,22 +278,21 @@ #define TICKER_USER_ULL_LOW_OPS (1 + TICKER_USER_ULL_LOW_VENDOR_OPS + 1) -/* NOTE: When ULL_LOW priority is configured to lower than ULL_HIGH, then extra - * ULL_HIGH operations queue elements are required to buffer the - * requested ticker operations. +/* NOTE: Extended Advertising needs one extra ticker operation being enqueued + * for scheduling the auxiliary PDU reception while there can already + * be three other operations being enqueued. + * + * This value also covers the case were initiator with 1M and Coded PHY + * scan window is stopping the two scan tickers, stopping one scan stop + * ticker and starting one new ticker for establishing an ACL connection. */ -#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_ADV_EXT) && \ - defined(CONFIG_BT_CTLR_PHY_CODED) +#if defined(CONFIG_BT_CTLR_ADV_EXT) #define TICKER_USER_ULL_HIGH_OPS (4 + TICKER_USER_ULL_HIGH_VENDOR_OPS + \ TICKER_USER_ULL_HIGH_FLASH_OPS + 1) -#else /* !CONFIG_BT_CENTRAL || !CONFIG_BT_CTLR_ADV_EXT || - * !CONFIG_BT_CTLR_PHY_CODED - */ +#else /* !CONFIG_BT_CTLR_ADV_EXT */ #define TICKER_USER_ULL_HIGH_OPS (3 + TICKER_USER_ULL_HIGH_VENDOR_OPS + \ TICKER_USER_ULL_HIGH_FLASH_OPS + 1) -#endif /* !CONFIG_BT_CENTRAL || !CONFIG_BT_CTLR_ADV_EXT || - * !CONFIG_BT_CTLR_PHY_CODED - */ +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ #define TICKER_USER_LLL_OPS (3 + TICKER_USER_LLL_VENDOR_OPS + 1) From 7093538c425b1bd3dd4bce3dfd3708a8281bd033 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Tue, 26 Sep 2023 16:37:26 +0200 Subject: [PATCH 1275/4498] Bluetooth: att: don't re-use the ATT buffer for confirmations If the peer is a zephyr host, there is no problem, as the Zephyr host limits sending parallel REQs and INDs. But the spec allows sending those in parallel, and it may end up that the re-used REQ buffer hasn't been destroyed when an indication comes. Only re-use the buffer when enqueuing ATT responses. This means that we may run out of buffers if the peer sends too many indications and our application also sends a lot of commands/notifications. The rationale for this is that having to handle a lot of requests is a more plausible scenario (e.g. being discovered by multiple peers) than handling lots of parallel indications. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/att.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index bea0fffaa8d..640c3acef90 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -670,11 +670,13 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t switch (att_op_get_type(op)) { case ATT_RESPONSE: - case ATT_CONFIRMATION: - /* Use a timeout only when responding/confirming */ + /* Use a timeout only when responding */ timeout = BT_ATT_TIMEOUT; re_use = true; break; + case ATT_CONFIRMATION: + timeout = BT_ATT_TIMEOUT; + break; default: timeout = K_FOREVER; } @@ -701,7 +703,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t * This is better than an assert as an assert would * allow a peer to DoS us. */ - LOG_ERR("already processing a transaction on chan %p", chan); + LOG_ERR("already processing a REQ/RSP on chan %p", chan); return NULL; } From c1baa8282d40d010c16acb0381676c0a031b1c26 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Tue, 26 Sep 2023 09:44:59 +0200 Subject: [PATCH 1276/4498] tests: Bluetooth: Add ATT sequential procedures test The purpose of this test is to prove that the zephyr host can handle the behavior described in the Bluetooth Core Specification Vol.3 Part.F 3.3.2 "Sequential protocol". The host should be able to handle all of those in parallel: one indication, one write request, multiple commands and multiple notifications. The "tester" part had to be written with a "tiny host" implementation instead of the Zephyr host, as the ZH conflates GATT client and server and doesn't allow a device to enqueue an ATT request + an ATT indication on the same bearer. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/hci_core.c | 7 + .../host/att/sequential/common/utils.h | 59 ++ .../host/att/sequential/dut/CMakeLists.txt | 16 + .../host/att/sequential/dut/prj.conf | 41 ++ .../host/att/sequential/dut/src/main.c | 356 ++++++++++ .../host/att/sequential/scripts/_compile.sh | 18 + .../host/att/sequential/scripts/sequential.sh | 28 + .../host/att/sequential/tester/CMakeLists.txt | 17 + .../host/att/sequential/tester/prj.conf | 19 + .../host/att/sequential/tester/src/main.c | 668 ++++++++++++++++++ tests/bsim/bluetooth/host/compile.sh | 2 + 11 files changed, 1231 insertions(+) create mode 100644 tests/bsim/bluetooth/host/att/sequential/common/utils.h create mode 100644 tests/bsim/bluetooth/host/att/sequential/dut/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/att/sequential/dut/prj.conf create mode 100644 tests/bsim/bluetooth/host/att/sequential/dut/src/main.c create mode 100755 tests/bsim/bluetooth/host/att/sequential/scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/att/sequential/scripts/sequential.sh create mode 100644 tests/bsim/bluetooth/host/att/sequential/tester/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/att/sequential/tester/prj.conf create mode 100644 tests/bsim/bluetooth/host/att/sequential/tester/src/main.c diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 8e1227c0bf5..710dbf3fe21 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3938,6 +3938,13 @@ static void rx_work_handler(struct k_work *work) } #endif /* !CONFIG_BT_RECV_BLOCKING */ +#if defined(CONFIG_BT_TESTING) +k_tid_t bt_testing_tx_tid_get(void) +{ + return &tx_thread_data; +} +#endif + int bt_enable(bt_ready_cb_t cb) { int err; diff --git a/tests/bsim/bluetooth/host/att/sequential/common/utils.h b/tests/bsim/bluetooth/host/att/sequential/common/utils.h new file mode 100644 index 00000000000..b4892d5a087 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/common/utils.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_tracing.h" +#include "bs_types.h" +#include "bstests.h" + +#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * USEC_PER_SEC) +#define TEST_TIMEOUT_SIMULATED BS_SECONDS(10) + +extern enum bst_result_t bst_result; + +#define DECLARE_FLAG(flag) extern atomic_t flag +#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) + +#define WAIT_FOR_VAL(var, val) \ + while (atomic_get(&var) != val) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG_UNSET(flag) \ + while ((bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define TAKE_FLAG(flag) \ + while (!(bool)atomic_cas(&flag, true, false)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#define ASSERT(expr, ...) \ + do { \ + if (!(expr)) { \ + FAIL(__VA_ARGS__); \ + } \ + } while (0) + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +#define HVX_HANDLE 0x0012 +#define INDICATION_PAYLOAD "indication" +#define NOTIFICATION_PAYLOAD "notification" diff --git a/tests/bsim/bluetooth/host/att/sequential/dut/CMakeLists.txt b/tests/bsim/bluetooth/host/att/sequential/dut/CMakeLists.txt new file mode 100644 index 00000000000..b6c34df4916 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/dut/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_sequential_dut) + +target_sources(app PRIVATE + src/main.c +) + +zephyr_include_directories( + ../common/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/att/sequential/dut/prj.conf b/tests/bsim/bluetooth/host/att/sequential/dut/prj.conf new file mode 100644 index 00000000000..34fe43f0950 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/dut/prj.conf @@ -0,0 +1,41 @@ +CONFIG_LOG=y +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="Sequential" + +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION=n + +# Enable bt_testing_tx_tid_get() +CONFIG_BT_TESTING=y + +# Replace `Execute` with `gdb --args` in the shell script +# and get a nice backtrace on assert +CONFIG_ARCH_POSIX_TRAP_ON_FATAL=y + +# Prepend logs with thread names +CONFIG_THREAD_NAME=y +CONFIG_LOG_THREAD_ID_PREFIX=y + +# Enable those as needed +# CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y +# CONFIG_BT_ATT_LOG_LEVEL_DBG=y +# CONFIG_BT_GATT_LOG_LEVEL_DBG=y + +# Allow whole L2CAP PDUs to fit on-air +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_ACL_RX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_DATA_LEN_UPDATE=y +CONFIG_BT_USER_DATA_LEN_UPDATE=y + +# Disable auto-initiated procedures so they don't +# mess with the test's execution. +CONFIG_BT_AUTO_PHY_UPDATE=n +CONFIG_BT_AUTO_DATA_LEN_UPDATE=n +CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n + +CONFIG_BT_MAX_CONN=1 diff --git a/tests/bsim/bluetooth/host/att/sequential/dut/src/main.c b/tests/bsim/bluetooth/host/att/sequential/dut/src/main.c new file mode 100644 index 00000000000..d44d172eb0c --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/dut/src/main.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "bstests.h" + +#include +LOG_MODULE_REGISTER(dut, LOG_LEVEL_INF); + +DEFINE_FLAG(is_connected); +DEFINE_FLAG(is_subscribed); +DEFINE_FLAG(one_indication); +DEFINE_FLAG(two_notifications); +DEFINE_FLAG(flag_data_length_updated); + +static atomic_t nwrites; +static atomic_t indications; +static atomic_t notifications; + +/* Defined in hci_core.c */ +extern k_tid_t bt_testing_tx_tid_get(void); + +static struct bt_conn *dconn; + +static void connected(struct bt_conn *conn, uint8_t conn_err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (conn_err) { + FAIL("Failed to connect to %s (%u)", addr, conn_err); + return; + } + + LOG_DBG("%s", addr); + + dconn = bt_conn_ref(conn); + SET_FLAG(is_connected); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + LOG_DBG("%p %s (reason 0x%02x)", conn, addr, reason); + + bt_conn_unref(dconn); + UNSET_FLAG(is_connected); +} + +static void data_len_updated(struct bt_conn *conn, + struct bt_conn_le_data_len_info *info) +{ + LOG_DBG("Data length updated: TX %d RX %d", + info->tx_max_len, + info->rx_max_len); + SET_FLAG(flag_data_length_updated); +} + +static void do_dlu(void) +{ + int err; + struct bt_conn_le_data_len_param param; + + param.tx_max_len = CONFIG_BT_CTLR_DATA_LENGTH_MAX; + param.tx_max_time = 2500; + + err = bt_conn_le_data_len_update(dconn, ¶m); + ASSERT(err == 0, "Can't update data length (err %d)\n", err); + + WAIT_FOR_FLAG(flag_data_length_updated); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, + .le_data_len_updated = data_len_updated, +}; + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + char str[BT_ADDR_LE_STR_LEN]; + struct bt_le_conn_param *param; + struct bt_conn *conn; + int err; + + err = bt_le_scan_stop(); + if (err) { + FAIL("Stop LE scan failed (err %d)", err); + return; + } + + bt_addr_le_to_str(addr, str, sizeof(str)); + LOG_DBG("Connecting to %s", str); + + param = BT_LE_CONN_PARAM_DEFAULT; + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &conn); + if (err) { + FAIL("Create conn failed (err %d)", err); + return; + } +} + +static void connect(void) +{ + int err; + struct bt_le_scan_param scan_param = { + .type = BT_LE_SCAN_TYPE_ACTIVE, + .options = BT_LE_SCAN_OPT_NONE, + .interval = BT_GAP_SCAN_FAST_INTERVAL, + .window = BT_GAP_SCAN_FAST_WINDOW, + }; + + UNSET_FLAG(is_connected); + + err = bt_le_scan_start(&scan_param, device_found); + ASSERT(!err, "Scanning failed to start (err %d)\n", err); + + LOG_DBG("Central initiating connection..."); + WAIT_FOR_FLAG(is_connected); + LOG_INF("Connected as central"); + + /* No security support on the tinyhost unfortunately */ +} + +static ssize_t written_to(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, + uint16_t len, + uint16_t offset, + uint8_t flags) +{ + LOG_INF("written to: handle 0x%x len %d flags 0x%x", + attr->handle, + len, + flags); + + LOG_HEXDUMP_DBG(buf, len, "Write data"); + + if (atomic_get(&nwrites) == 0) { + /* Suspend on the first write, which is an ATT Request */ + LOG_INF("suspending HCI TX thread"); + k_thread_suspend(bt_testing_tx_tid_get()); + } + + atomic_inc(&nwrites); + + return len; +} + +#define test_service_uuid \ + BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xf0debc9a, 0x7856, 0x3412, 0x7856, 0x341278563412)) +#define test_characteristic_uuid \ + BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xf2debc9a, 0x7856, 0x3412, 0x7856, 0x341278563412)) + +BT_GATT_SERVICE_DEFINE(test_gatt_service, BT_GATT_PRIMARY_SERVICE(test_service_uuid), + BT_GATT_CHARACTERISTIC(test_characteristic_uuid, + (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | + BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE), + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, + NULL, written_to, NULL), + BT_GATT_CCC(NULL, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),); + +static uint8_t notified(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) +{ + static uint8_t notification[] = NOTIFICATION_PAYLOAD; + static uint8_t indication[] = INDICATION_PAYLOAD; + bool is_nfy; + + ASSERT(length >= sizeof(indication), "Unexpected data"); + ASSERT(length <= sizeof(notification), "Unexpected data"); + + LOG_HEXDUMP_DBG(data, length, "HVx data"); + + is_nfy = memcmp(data, notification, length) == 0; + + LOG_INF("%s from 0x%x", is_nfy ? "notified" : "indicated", + params->value_handle); + + if (is_nfy) { + atomic_inc(¬ifications); + } else { + atomic_inc(&indications); + } + + return BT_GATT_ITER_CONTINUE; +} + +static void subscribed(struct bt_conn *conn, + uint8_t err, + struct bt_gatt_subscribe_params *params) +{ + ASSERT(!err, "Subscribe failed (err %d)\n", err); + + ASSERT(params, "params is NULL\n"); + + SET_FLAG(is_subscribed); + /* spoiler: tester doesn't really have attributes */ + LOG_INF("Subscribed to Tester attribute"); +} + +void subscribe(void) +{ + int err; + + /* Handle values don't matter, as long as they match on the tester */ + static struct bt_gatt_subscribe_params params = { + .notify = notified, + .subscribe = subscribed, + .value = BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE, + .value_handle = HVX_HANDLE, + .ccc_handle = (HVX_HANDLE + 1), + }; + + err = bt_gatt_subscribe(dconn, ¶ms); + ASSERT(!err, "Subscribe failed (err %d)\n", err); + + WAIT_FOR_FLAG(is_subscribed); +} + +static void send_write_handle(void) +{ + int err; + uint16_t handle; + uint8_t data[sizeof(handle)]; + const struct bt_gatt_attr *attr = &test_gatt_service.attrs[2]; + + /* Inform tester which handle it should write to */ + handle = bt_gatt_attr_get_handle(attr); + sys_put_le16(handle, data); + + err = bt_gatt_notify(dconn, attr, data, sizeof(data)); + ASSERT(!err, "Failed to transmit handle for write (err %d)\n", err); +} + +void test_procedure_0(void) +{ + LOG_DBG("Test start: ATT sequential protocol"); + int err; + + err = bt_enable(NULL); + ASSERT(err == 0, "Can't enable Bluetooth (err %d)\n", err); + LOG_DBG("Central: Bluetooth initialized."); + + /* Test purpose: + * Test Spec V.3 P.F 3.3.2 Sequential protocol + * + * Verify that a Zephyr host server/client combo can process + * concurrently: one Request, one Indication, multiple + * Notifications and multiple Commands. + * + * To do this, the application on the DUT will purposefully stall the + * HCI TX thread, ensuring that the responses are not sent until the + * tester has finished sending everything. + * + * Test procedure: + * + * [setup] + * - connect ACL + * - update data length (tinyhost doens't have recombination) + * - dut: subscribe to INDICATE and NOTIFY on tester CHRC + * - dut: send a handle the tester can write to + * + * [proc] + * - tester: send one ATT write request + * - tester: send one ATT indication + * - tester: send two ATT notifications + * - tester: send two ATT commands + * + * - dut: handle the REQuest, build & put the RSP PDU on the HCI TX queue + * - dut: suspend the HCI TX thread + * - dut: handle the INDication + * - dut: handle the notifications + * - dut: handle the (write) commands + * - dut: resume the TX thread after a short while + * + * [verdict] + * - all procedures complete successfully, no buffer allocation failures + * or timeouts. + */ + connect(); + subscribe(); + + do_dlu(); + + send_write_handle(); + + WAIT_FOR_VAL(indications, 1); + WAIT_FOR_VAL(notifications, 2); + /* One REQ, two CMDs */ + WAIT_FOR_VAL(nwrites, 3); + + /* Send RSP to LL */ + k_thread_resume(bt_testing_tx_tid_get()); + + PASS("DUT done\n"); +} + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "dut", + .test_pre_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_procedure_0, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/sequential/scripts/_compile.sh b/tests/bsim/bluetooth/host/att/sequential/scripts/_compile.sh new file mode 100755 index 00000000000..2e81445690f --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/scripts/_compile.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Path checks, etc +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +BOARD="${BOARD:-nrf52_bsim}" +dut_exe="bs_${BOARD}_tests_bsim_bluetooth_host_att_sequential_dut_prj_conf" +tester_exe="bs_${BOARD}_tests_bsim_bluetooth_host_att_sequential_tester_prj_conf" + +# terminate running simulations (if any) +${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh + +west build -b ${BOARD} -d build_dut dut && \ + cp build_dut/zephyr/zephyr.exe "${BSIM_OUT_PATH}/bin/${dut_exe}" && +west build -b ${BOARD} -d build_tester tester && \ + cp build_tester/zephyr/zephyr.exe "${BSIM_OUT_PATH}/bin/${tester_exe}" diff --git a/tests/bsim/bluetooth/host/att/sequential/scripts/sequential.sh b/tests/bsim/bluetooth/host/att/sequential/scripts/sequential.sh new file mode 100755 index 00000000000..61153432781 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/scripts/sequential.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +BOARD="${BOARD:-nrf52_bsim}" +dut_exe="bs_${BOARD}_tests_bsim_bluetooth_host_att_sequential_dut_prj_conf" +tester_exe="bs_${BOARD}_tests_bsim_bluetooth_host_att_sequential_tester_prj_conf" + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_name="att_sequential" +simulation_id="${test_name}" +verbosity_level=2 +EXECUTE_TIMEOUT=30 +sim_length_us=10e6 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_2G4_phy_v1 \ + -v=${verbosity_level} -s="${simulation_id}" -D=2 -sim_length=${sim_length_us} $@ + +Execute "./$tester_exe" \ + -v=${verbosity_level} -s="${simulation_id}" -d=1 -testid=tester -RealEncryption=0 -rs=100 + +Execute "./$dut_exe" \ + -v=${verbosity_level} -s="${simulation_id}" -d=0 -testid=dut -RealEncryption=0 + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/att/sequential/tester/CMakeLists.txt b/tests/bsim/bluetooth/host/att/sequential/tester/CMakeLists.txt new file mode 100644 index 00000000000..c4410ee0b9e --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/tester/CMakeLists.txt @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_sequential_tester) + +target_sources(app PRIVATE + src/main.c +) + +zephyr_include_directories( + ../common/ + ${ZEPHYR_BASE}/subsys/bluetooth/common/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf b/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf new file mode 100644 index 00000000000..461c7dd5029 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf @@ -0,0 +1,19 @@ +CONFIG_LOG=y +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_RESERVE=1 +CONFIG_BT_MAX_CONN=1 + +CONFIG_BT_BUF_CMD_TX_COUNT=10 + +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_CMD_TX_SIZE=255 +CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 + +# Allow whole L2CAP PDUs to fit on-air +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_ACL_RX_SIZE=251 +CONFIG_BT_DATA_LEN_UPDATE=y +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c b/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c new file mode 100644 index 00000000000..cecbd8cab13 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c @@ -0,0 +1,668 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "common/bt_str.h" + +#include "host/conn_internal.h" +#include "host/l2cap_internal.h" + +#include "utils.h" +#include "bstests.h" + +#include +LOG_MODULE_REGISTER(bt_tinyhost, LOG_LEVEL_INF); + +#define BT_ATT_OP_MTU_REQ 0x02 +#define BT_ATT_OP_MTU_RSP 0x03 +#define BT_ATT_OP_WRITE_REQ 0x12 +#define BT_ATT_OP_WRITE_RSP 0x13 +#define BT_ATT_OP_NOTIFY 0x1b +#define BT_ATT_OP_INDICATE 0x1d +#define BT_ATT_OP_CONFIRM 0x1e +#define BT_ATT_OP_WRITE_CMD 0x52 +#define BT_L2CAP_CID_ATT 0x0004 + +DEFINE_FLAG(is_connected); +DEFINE_FLAG(flag_data_length_updated); +DEFINE_FLAG(flag_handle); +DEFINE_FLAG(flag_notified); +DEFINE_FLAG(flag_write_ack); +DEFINE_FLAG(flag_indication_ack); + +static uint16_t server_write_handle; + +static K_FIFO_DEFINE(rx_queue); + +#define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, + CMD_BUF_SIZE, 8, NULL); + +static K_SEM_DEFINE(cmd_sem, 1, 1); +static struct k_sem acl_pkts; +static uint16_t conn_handle; + +static volatile uint16_t active_opcode = 0xFFFF; +static struct net_buf *cmd_rsp; + +struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) +{ + struct bt_hci_cmd_hdr *hdr; + struct net_buf *buf; + + LOG_DBG("opcode 0x%04x param_len %u", opcode, param_len); + + buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER); + ASSERT(buf, "failed allocation"); + + LOG_DBG("buf %p", buf); + + net_buf_reserve(buf, BT_BUF_RESERVE); + + bt_buf_set_type(buf, BT_BUF_CMD); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->opcode = sys_cpu_to_le16(opcode); + hdr->param_len = param_len; + + return buf; +} + +static void handle_cmd_complete(struct net_buf *buf) +{ + struct bt_hci_evt_hdr *hdr; + uint8_t status, ncmd; + uint16_t opcode; + struct net_buf_simple_state state; + + net_buf_simple_save(&buf->b, &state); + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + + if (hdr->evt == BT_HCI_EVT_CMD_COMPLETE) { + struct bt_hci_evt_cmd_complete *evt; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + status = 0; + ncmd = evt->ncmd; + opcode = sys_le16_to_cpu(evt->opcode); + + } else if (hdr->evt == BT_HCI_EVT_CMD_STATUS) { + struct bt_hci_evt_cmd_status *evt; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + status = buf->data[0]; + ncmd = evt->ncmd; + opcode = sys_le16_to_cpu(evt->opcode); + + } else { + FAIL("unhandled event 0x%x", hdr->evt); + } + + LOG_DBG("opcode 0x%04x status %x", opcode, status); + + ASSERT(status == 0x00, "cmd status: %x", status); + + ASSERT(active_opcode == opcode, "unexpected opcode %x != %x", active_opcode, opcode); + + if (active_opcode) { + active_opcode = 0xFFFF; + cmd_rsp = net_buf_ref(buf); + net_buf_simple_restore(&buf->b, &state); + } + + if (ncmd) { + k_sem_give(&cmd_sem); + } +} + +static void handle_meta_event(struct net_buf *buf) +{ + uint8_t code = buf->data[2]; + + switch (code) { + case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: + case BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2: + conn_handle = sys_get_le16(&buf->data[4]); + LOG_DBG("connected: handle: %d", conn_handle); + SET_FLAG(is_connected); + break; + case BT_HCI_EVT_LE_DATA_LEN_CHANGE: + SET_FLAG(flag_data_length_updated); + break; + case BT_HCI_EVT_LE_CHAN_SEL_ALGO: + /* do nothing */ + break; + default: + LOG_ERR("unhandled meta event %x", code); + LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI META EVT"); + } +} + +static void handle_ncp(struct net_buf *buf) +{ + struct bt_hci_evt_num_completed_packets *evt; + struct bt_hci_evt_hdr *hdr; + uint16_t handle, count; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + + evt = (void *)buf->data; + handle = sys_le16_to_cpu(evt->h[0].handle); + count = sys_le16_to_cpu(evt->h[0].count); + + LOG_DBG("sent %d packets", count); + + while (count--) { + k_sem_give(&acl_pkts); + } +} + +static void handle_att_notification(struct net_buf *buf) +{ + uint16_t handle = net_buf_pull_le16(buf); + + LOG_INF("Got notification for 0x%04x len %d", handle, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "payload"); + + server_write_handle = net_buf_pull_le16(buf); + LOG_INF("Retrieved handle to write to: 0x%x", server_write_handle); + SET_FLAG(flag_handle); +} + +struct net_buf *alloc_l2cap_pdu(void); +static void send_l2cap_packet(struct net_buf *buf, uint16_t cid); + +static void send_write_rsp(void) +{ + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, BT_ATT_OP_WRITE_RSP); + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void handle_att_write(struct net_buf *buf) +{ + uint16_t handle = net_buf_pull_le16(buf); + + LOG_INF("Got write for 0x%04x len %d", handle, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "payload"); + + send_write_rsp(); +} + +static void handle_att(struct net_buf *buf) +{ + uint8_t op = net_buf_pull_u8(buf); + + switch (op) { + case BT_ATT_OP_NOTIFY: + handle_att_notification(buf); + return; + case BT_ATT_OP_WRITE_REQ: + handle_att_write(buf); + return; + case BT_ATT_OP_WRITE_RSP: + LOG_INF("got ATT write RSP"); + SET_FLAG(flag_write_ack); + return; + case BT_ATT_OP_CONFIRM: + LOG_INF("got ATT indication confirm"); + SET_FLAG(flag_indication_ack); + return; + case BT_ATT_OP_MTU_RSP: + LOG_INF("got ATT MTU RSP"); + return; + default: + LOG_HEXDUMP_ERR(buf->data, buf->len, "payload"); + FAIL("unhandled opcode %x\n", op); + return; + } +} + +static void handle_l2cap(struct net_buf *buf) +{ + struct bt_l2cap_hdr *hdr; + uint16_t cid; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + cid = sys_le16_to_cpu(hdr->cid); + + LOG_DBG("Packet for CID %u len %u", cid, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "l2cap"); + + /* Make sure we don't have to recombine packets */ + ASSERT(buf->len == hdr->len, "buflen = %d != hdrlen %d", + buf->len, hdr->len); + + ASSERT(cid == BT_L2CAP_CID_ATT, "We only support (U)ATT"); + + /* (U)ATT PDU */ + handle_att(buf); +} + +static void handle_acl(struct net_buf *buf) +{ + struct bt_hci_acl_hdr *hdr; + uint16_t len, handle; + uint8_t flags; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + len = sys_le16_to_cpu(hdr->len); + handle = sys_le16_to_cpu(hdr->handle); + + flags = bt_acl_flags(handle); + handle = bt_acl_handle(handle); + + ASSERT(flags == BT_ACL_START, + "Fragmentation not supported"); + + LOG_DBG("ACL: conn %d len %d flags %d", handle, len, flags); + LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI ACL"); + + handle_l2cap(buf); +} + +static void recv(struct net_buf *buf) +{ + LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI RX"); + + uint8_t code = buf->data[0]; + + if (bt_buf_get_type(buf) == BT_BUF_EVT) { + switch (code) { + case BT_HCI_EVT_CMD_COMPLETE: + case BT_HCI_EVT_CMD_STATUS: + handle_cmd_complete(buf); + break; + case BT_HCI_EVT_LE_META_EVENT: + handle_meta_event(buf); + break; + case BT_HCI_EVT_DISCONN_COMPLETE: + UNSET_FLAG(is_connected); + break; + case BT_HCI_EVT_NUM_COMPLETED_PACKETS: + handle_ncp(buf); + break; + default: + LOG_ERR("unhandled msg %x", code); + LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI EVT"); + } + + /* handlers should take a ref if they want to access the buffer + * later + */ + net_buf_unref(buf); + return; + } + + if (bt_buf_get_type(buf) == BT_BUF_ACL_IN) { + handle_acl(buf); + net_buf_unref(buf); + return; + } + + LOG_ERR("HCI RX (not data or event)"); + net_buf_unref(buf); +} + +static void send_cmd(uint16_t opcode, struct net_buf *cmd, struct net_buf **rsp) +{ + LOG_DBG("opcode %x", opcode); + + if (!cmd) { + cmd = bt_hci_cmd_create(opcode, 0); + } + + k_sem_take(&cmd_sem, K_FOREVER); + ASSERT(active_opcode == 0xFFFF, ""); + + active_opcode = opcode; + + LOG_HEXDUMP_DBG(cmd->data, cmd->len, "HCI TX"); + bt_send(cmd); + + /* Wait until the command completes */ + k_sem_take(&cmd_sem, K_FOREVER); + k_sem_give(&cmd_sem); + + net_buf_unref(cmd); + + /* return response. it's okay if cmd_rsp gets overwritten, since the app + * gets the ref to the underlying buffer when this fn returns. + */ + if (rsp) { + *rsp = cmd_rsp; + } else { + net_buf_unref(cmd_rsp); + cmd_rsp = NULL; + } +} + +static K_THREAD_STACK_DEFINE(rx_thread_stack, 1024); +static struct k_thread rx_thread_data; + +static void rx_thread(void *p1, void *p2, void *p3) +{ + LOG_DBG("start HCI rx"); + + while (true) { + struct net_buf *buf; + + /* Wait until a buffer is available */ + buf = net_buf_get(&rx_queue, K_FOREVER); + recv(buf); + } +} + +static void le_read_buffer_size_complete(struct net_buf *rsp) +{ + struct bt_hci_rp_le_read_buffer_size *rp = (void *)rsp->data; + + LOG_DBG("status 0x%02x", rp->status); + LOG_DBG("max len %d max num %d", rp->le_max_len, rp->le_max_num); + + k_sem_init(&acl_pkts, rp->le_max_num, rp->le_max_num); + net_buf_unref(rsp); +} + +static void read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time) +{ + struct bt_hci_rp_le_read_max_data_len *rp; + struct net_buf *rsp; + + send_cmd(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp); + + rp = (void *)rsp->data; + *tx_octets = sys_le16_to_cpu(rp->max_tx_octets); + *tx_time = sys_le16_to_cpu(rp->max_tx_time); + net_buf_unref(rsp); +} + +static void write_default_data_len(uint16_t tx_octets, uint16_t tx_time) +{ + struct bt_hci_cp_le_write_default_data_len *cp; + struct net_buf *buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, sizeof(*cp)); + + ASSERT(buf, ""); + + cp = net_buf_add(buf, sizeof(*cp)); + cp->max_tx_octets = sys_cpu_to_le16(tx_octets); + cp->max_tx_time = sys_cpu_to_le16(tx_time); + + send_cmd(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, buf, NULL); +} + +static void set_data_len(void) +{ + uint16_t tx_octets, tx_time; + + read_max_data_len(&tx_octets, &tx_time); + write_default_data_len(tx_octets, tx_time); +} + +static void set_event_mask(uint16_t opcode) +{ + struct bt_hci_cp_set_event_mask *cp_mask; + struct net_buf *buf; + uint64_t mask = 0U; + + /* The two commands have the same length/params */ + buf = bt_hci_cmd_create(opcode, sizeof(*cp_mask)); + ASSERT(buf, ""); + + /* Forward all events */ + cp_mask = net_buf_add(buf, sizeof(*cp_mask)); + mask = UINT64_MAX; + sys_put_le64(mask, cp_mask->events); + + send_cmd(opcode, buf, NULL); +} + +static void set_random_address(void) +{ + struct net_buf *buf; + bt_addr_le_t addr = {BT_ADDR_LE_RANDOM, {{0x0A, 0x89, 0x67, 0x45, 0x23, 0xC1}}}; + + LOG_DBG("%s", bt_addr_str(&addr.a)); + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(addr.a)); + ASSERT(buf, ""); + + net_buf_add_mem(buf, &addr.a, sizeof(addr.a)); + send_cmd(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, buf, NULL); +} + +void start_adv(void) +{ + struct bt_hci_cp_le_set_adv_param set_param; + struct net_buf *buf; + uint16_t interval = 60; /* Interval doesn't matter */ + + (void)memset(&set_param, 0, sizeof(set_param)); + + set_param.min_interval = sys_cpu_to_le16(interval); + set_param.max_interval = sys_cpu_to_le16(interval); + set_param.channel_map = 0x07; + set_param.filter_policy = BT_LE_ADV_FP_NO_FILTER; + set_param.type = BT_HCI_ADV_IND; + set_param.own_addr_type = 0x01; /* random */ + + /* configure */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(set_param)); + net_buf_add_mem(buf, &set_param, sizeof(set_param)); + send_cmd(BT_HCI_OP_LE_SET_ADV_PARAM, buf, NULL); + + /* start */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1); + net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE); + send_cmd(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); +} + +NET_BUF_POOL_DEFINE(acl_tx_pool, 5, BT_L2CAP_BUF_SIZE(200), 8, NULL); + +struct net_buf *alloc_l2cap_pdu(void) +{ + struct net_buf *buf; + uint16_t reserve; + + buf = net_buf_alloc(&acl_tx_pool, K_FOREVER); + ASSERT(buf, "failed ACL allocation"); + + reserve = sizeof(struct bt_l2cap_hdr); + reserve += sizeof(struct bt_hci_acl_hdr) + BT_BUF_RESERVE; + + net_buf_reserve(buf, reserve); + + return buf; +} + +static int send_acl(struct net_buf *buf) +{ + struct bt_hci_acl_hdr *hdr; + uint8_t flags = BT_ACL_START_NO_FLUSH; + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn_handle, flags)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + + bt_buf_set_type(buf, BT_BUF_ACL_OUT); + + k_sem_take(&acl_pkts, K_FOREVER); + + return bt_send(buf); +} + +static void send_l2cap_packet(struct net_buf *buf, uint16_t cid) +{ + struct bt_l2cap_hdr *hdr; + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + hdr->cid = sys_cpu_to_le16(cid); + + /* Always entire packets, no HCI fragmentation */ + ASSERT(buf->len <= CONFIG_BT_BUF_ACL_TX_SIZE, + "Fragmentation not supported"); + + send_acl(buf); +} + +static void gatt_write(uint16_t op) +{ + static uint8_t data[] = "write"; + uint16_t handle = server_write_handle; + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, op); + net_buf_add_le16(buf, handle); + net_buf_add_mem(buf, data, sizeof(data)); + + LOG_INF("send ATT write %s", + op == BT_ATT_OP_WRITE_REQ ? "REQ" : "CMD"); + + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void gatt_notify(void) +{ + static uint8_t data[] = NOTIFICATION_PAYLOAD; + uint16_t handle = HVX_HANDLE; + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, BT_ATT_OP_NOTIFY); + net_buf_add_le16(buf, handle); + net_buf_add_mem(buf, data, sizeof(data)); + + LOG_INF("send ATT notification"); + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void gatt_indicate(void) +{ + static uint8_t data[] = INDICATION_PAYLOAD; + uint16_t handle = HVX_HANDLE; + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, BT_ATT_OP_INDICATE); + net_buf_add_le16(buf, handle); + net_buf_add_mem(buf, data, sizeof(data)); + + LOG_INF("send ATT indication"); + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void prepare_controller(void) +{ + /* Initialize controller */ + struct net_buf *rsp; + + send_cmd(BT_HCI_OP_RESET, NULL, NULL); + send_cmd(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp); + le_read_buffer_size_complete(rsp); + + set_data_len(); + set_event_mask(BT_HCI_OP_SET_EVENT_MASK); + set_event_mask(BT_HCI_OP_LE_SET_EVENT_MASK); + set_random_address(); +} + +static void init_tinyhost(void) +{ + bt_enable_raw(&rx_queue); + + /* Start the RX thread */ + k_thread_create(&rx_thread_data, rx_thread_stack, + K_THREAD_STACK_SIZEOF(rx_thread_stack), rx_thread, + NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); + k_thread_name_set(&rx_thread_data, "HCI RX"); + + k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(0)); + + prepare_controller(); +} + +void test_procedure_0(void) +{ + init_tinyhost(); + + /* Start advertising & wait for a connection */ + start_adv(); + WAIT_FOR_FLAG(is_connected); + LOG_INF("connected"); + + /* We need this to be able to send whole L2CAP PDUs on-air. */ + WAIT_FOR_FLAG(flag_data_length_updated); + + /* Get handle we will write to */ + WAIT_FOR_FLAG(flag_handle); + + LOG_INF("##################### START TEST #####################"); + + gatt_write(BT_ATT_OP_WRITE_REQ); /* will prompt a response PDU */ + gatt_indicate(); /* will prompt a confirmation PDU */ + + gatt_notify(); + gatt_write(BT_ATT_OP_WRITE_CMD); + + gatt_notify(); + gatt_write(BT_ATT_OP_WRITE_CMD); + + WAIT_FOR_FLAG(flag_write_ack); + WAIT_FOR_FLAG(flag_indication_ack); + + PASS("Tester done\n"); +} + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "tester", + .test_pre_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_procedure_0, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 1c14fb957f4..4f9cd0409b8 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -35,6 +35,8 @@ app=tests/bsim/bluetooth/host/att/eatt_notif conf_file=prj.conf compile app=tests/bsim/bluetooth/host/att/mtu_update compile app=tests/bsim/bluetooth/host/att/read_fill_buf/client compile app=tests/bsim/bluetooth/host/att/read_fill_buf/server compile +app=tests/bsim/bluetooth/host/att/sequential/dut compile +app=tests/bsim/bluetooth/host/att/sequential/tester compile app=tests/bsim/bluetooth/host/gatt/caching compile app=tests/bsim/bluetooth/host/gatt/general compile From 28ed48cbac70c8aaa3905b13040a658830b4d5b7 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 27 Sep 2023 22:02:24 +0200 Subject: [PATCH 1277/4498] Bluetooth: Controller: Fix connected ISO dynamic tx power Fix connected ISO dynamic tx power support compilation error. Signed-off-by: Vinayak Kariappa Chettimada --- .../hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf | 3 +++ samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf | 3 +++ .../bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c | 4 ++-- .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf b/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf index bb95b6ea74e..e9e5ac63483 100644 --- a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf @@ -112,3 +112,6 @@ CONFIG_BT_CTLR_ISOAL_SOURCES=2 # ISO Receptions CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 CONFIG_BT_CTLR_ISOAL_SINKS=2 + +# Tx Power Dynamic Control +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf b/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf index 1f976f75f22..3774532c424 100644 --- a/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf @@ -104,3 +104,6 @@ CONFIG_BT_CTLR_ISOAL_SOURCES=2 # ISO Receptions CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 CONFIG_BT_CTLR_ISOAL_SINKS=2 + +# Tx Power Dynamic Control +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index d287bc794a6..46360ef88d7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -220,7 +220,7 @@ static int prepare_cb(struct lll_prepare_param *p) radio_reset(); #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(cis_lll->tx_pwr_lvl); + radio_tx_power_set(conn_lll->tx_pwr_lvl); #else /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ radio_tx_power_set(RADIO_TXP_DEFAULT); #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ @@ -986,7 +986,7 @@ static void isr_rx(void *param) next_cis_lll->rx.bn_curr = 1U; #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(next_cis_lll->tx_pwr_lvl); + radio_tx_power_set(next_conn_lll->tx_pwr_lvl); #else radio_tx_power_set(RADIO_TXP_DEFAULT); #endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index f089a07bb0b..13238c081cf 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -238,7 +238,7 @@ static int prepare_cb(struct lll_prepare_param *p) radio_reset(); #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(cis_lll->tx_pwr_lvl); + radio_tx_power_set(conn_lll->tx_pwr_lvl); #else /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ radio_tx_power_set(RADIO_TXP_DEFAULT); #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ From efb5c0902b0827a2eb2ddbe845a5387e2a148f06 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Wed, 16 Aug 2023 11:21:55 +0200 Subject: [PATCH 1278/4498] bluetooth: tester: Add support for BAP broadcast Support for BAP/BSRC and BAP/BSNK test cases. Add partial support for GAP/PADV as periodic advertising is needed for BAP/BSRC tests and they can share common code. Signed-off-by: Magdalena Kasenberg --- tests/bluetooth/tester/overlay-le-audio.conf | 12 + tests/bluetooth/tester/src/btp.c | 31 + tests/bluetooth/tester/src/btp/btp_ascs.h | 4 +- tests/bluetooth/tester/src/btp/btp_bap.h | 131 +++- tests/bluetooth/tester/src/btp/btp_gap.h | 123 +++- tests/bluetooth/tester/src/btp/bttester.h | 4 + tests/bluetooth/tester/src/btp_bap.c | 734 ++++++++++++++++++- tests/bluetooth/tester/src/btp_gap.c | 484 ++++++++++-- 8 files changed, 1443 insertions(+), 80 deletions(-) diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 4478c9e7c21..99cb4f8f8ef 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -25,6 +25,18 @@ CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT=1 CONFIG_BT_MICP_MIC_CTLR=y CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST=1 +# Broadcast Source +CONFIG_BT_BAP_BROADCAST_SOURCE=y +CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2 +CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2 +CONFIG_BT_ISO_TX_BUF_COUNT=4 + +# Broadcast Sink +CONFIG_BT_BAP_SCAN_DELEGATOR=y +CONFIG_BT_BAP_BROADCAST_SINK=y +CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 +CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 + # ASCS CONFIG_BT_ASCS_ASE_SNK_COUNT=2 CONFIG_BT_ASCS_ASE_SRC_COUNT=2 diff --git a/tests/bluetooth/tester/src/btp.c b/tests/bluetooth/tester/src/btp.c index ced25b2210e..60f3bc1cbbd 100644 --- a/tests/bluetooth/tester/src/btp.c +++ b/tests/bluetooth/tester/src/btp.c @@ -50,6 +50,9 @@ static struct { size_t num; } service_handler[BTP_SERVICE_ID_MAX + 1]; +static struct net_buf_simple *rsp_buf = NET_BUF_SIMPLE(BTP_MTU); +static K_MUTEX_DEFINE(rsp_buf_mutex); + static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, const uint8_t *data, size_t len); static void tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index, @@ -241,6 +244,34 @@ void tester_init(void) BTP_INDEX_NONE, NULL, 0); } +int tester_rsp_buffer_lock(void) +{ + if (k_mutex_lock(&rsp_buf_mutex, Z_FOREVER) != 0) { + LOG_ERR("Cannot lock rsp_ring_buf"); + + return -EACCES; + } + + return 0; +} + +void tester_rsp_buffer_unlock(void) +{ + k_mutex_unlock(&rsp_buf_mutex); +} + +void tester_rsp_buffer_free(void) +{ + net_buf_simple_init(rsp_buf, 0); +} + +void tester_rsp_buffer_allocate(size_t len, uint8_t **data) +{ + tester_rsp_buffer_free(); + + *data = net_buf_simple_add(rsp_buf, len); +} + static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, const uint8_t *data, size_t len) { diff --git a/tests/bluetooth/tester/src/btp/btp_ascs.h b/tests/bluetooth/tester/src/btp/btp_ascs.h index a5968a919af..f14cb5de3d4 100644 --- a/tests/bluetooth/tester/src/btp/btp_ascs.h +++ b/tests/bluetooth/tester/src/btp/btp_ascs.h @@ -19,8 +19,8 @@ struct btp_ascs_configure_codec_cmd { uint8_t coding_format; uint16_t vid; uint16_t cid; - uint8_t ltvs_len; - uint8_t ltvs[0]; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[0]; } __packed; #define BTP_ASCS_CONFIGURE_QOS 0x03 diff --git a/tests/bluetooth/tester/src/btp/btp_bap.h b/tests/bluetooth/tester/src/btp/btp_bap.h index 2157d6c79fc..ede3448f2cf 100644 --- a/tests/bluetooth/tester/src/btp/btp_bap.h +++ b/tests/bluetooth/tester/src/btp/btp_bap.h @@ -7,12 +7,12 @@ */ /* BAP commands */ -#define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 +#define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 struct btp_bap_read_supported_commands_rp { uint8_t data[0]; } __packed; -#define BTP_BAP_DISCOVER 0x02 +#define BTP_BAP_DISCOVER 0x02 struct btp_bap_discover_cmd { bt_addr_le_t address; } __packed; @@ -20,7 +20,7 @@ struct btp_bap_discover_cmd { #define BTP_BAP_DISCOVERY_STATUS_SUCCESS 0x00 #define BTP_BAP_DISCOVERY_STATUS_FAILED 0x01 -#define BTP_BAP_SEND 0x03 +#define BTP_BAP_SEND 0x03 struct btp_bap_send_cmd { bt_addr_le_t address; uint8_t ase_id; @@ -32,14 +32,91 @@ struct btp_bap_send_rp { uint8_t data_len; } __packed; +#define BTP_BAP_BROADCAST_SOURCE_SETUP 0x04 +struct btp_bap_broadcast_source_setup_cmd { + uint8_t streams_per_subgroup; + uint8_t subgroups; + uint8_t sdu_interval[3]; + uint8_t framing; + uint16_t max_sdu; + uint8_t retransmission_num; + uint16_t max_transport_latency; + uint8_t presentation_delay[3]; + uint8_t coding_format; + uint16_t vid; + uint16_t cid; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[]; +} __packed; +struct btp_bap_broadcast_source_setup_rp { + uint32_t gap_settings; + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 +struct btp_bap_broadcast_source_release_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_ADV_START 0x06 +struct btp_bap_broadcast_adv_start_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_ADV_STOP 0x07 +struct btp_bap_broadcast_adv_stop_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_START 0x08 +struct btp_bap_broadcast_source_start_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 +struct btp_bap_broadcast_source_stop_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_SETUP 0x0a +struct btp_bap_broadcast_sink_setup_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SINK_RELEASE 0x0b +struct btp_bap_broadcast_sink_release_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SCAN_START 0x0c +struct btp_bap_broadcast_scan_start_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SCAN_STOP 0x0d +struct btp_bap_broadcast_scan_stop_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SINK_SYNC 0x0e +struct btp_bap_broadcast_sink_sync_cmd { + bt_addr_le_t address; + uint8_t broadcast_id[3]; + uint8_t advertiser_sid; + uint16_t skip; + uint16_t sync_timeout; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_STOP 0x0f +struct btp_bap_broadcast_sink_stop_cmd { + bt_addr_le_t address; + uint8_t broadcast_id[3]; +} __packed; + /* BAP events */ -#define BTP_BAP_EV_DISCOVERY_COMPLETED 0x80 +#define BTP_BAP_EV_DISCOVERY_COMPLETED 0x80 struct btp_bap_discovery_completed_ev { bt_addr_le_t address; uint8_t status; } __packed; -#define BTP_BAP_EV_CODEC_CAP_FOUND 0x81 +#define BTP_BAP_EV_CODEC_CAP_FOUND 0x81 struct btp_bap_codec_cap_found_ev { bt_addr_le_t address; uint8_t dir; @@ -50,17 +127,55 @@ struct btp_bap_codec_cap_found_ev { uint8_t channel_counts; } __packed; -#define BTP_BAP_EV_ASE_FOUND 0x82 +#define BTP_BAP_EV_ASE_FOUND 0x82 struct btp_ascs_ase_found_ev { bt_addr_le_t address; uint8_t dir; uint8_t ase_id; } __packed; -#define BTP_BAP_EV_STREAM_RECEIVED 0x83 +#define BTP_BAP_EV_STREAM_RECEIVED 0x83 struct btp_bap_stream_received_ev { bt_addr_le_t address; uint8_t ase_id; uint8_t data_len; - uint8_t data[0]; + uint8_t data[]; +} __packed; + +#define BTP_BAP_EV_BAA_FOUND 0x84 +struct btp_bap_baa_found_ev { + bt_addr_le_t address; + uint8_t broadcast_id[3]; + uint8_t advertiser_sid; + uint16_t padv_interval; +} __packed; + +#define BTP_BAP_EV_BIS_FOUND 0x85 +struct btp_bap_bis_found_ev { + bt_addr_le_t address; + uint8_t broadcast_id[3]; + uint8_t presentation_delay[3]; + uint8_t subgroup_id; + uint8_t bis_id; + uint8_t coding_format; + uint16_t vid; + uint16_t cid; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[]; +} __packed; + +#define BTP_BAP_EV_BIS_SYNCED 0x86 +struct btp_bap_bis_syned_ev { + bt_addr_le_t address; + uint8_t broadcast_id[3]; + uint8_t bis_id; +} __packed; + +#define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 +struct btp_bap_bis_stream_received_ev { + bt_addr_le_t address; + uint8_t broadcast_id[3]; + uint8_t bis_id; + uint8_t data_len; + uint8_t data[]; } __packed; diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index dee7d5be517..960d810e025 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -101,6 +101,10 @@ struct btp_gap_set_bondable_rp { uint32_t current_settings; } __packed; +#define BTP_GAP_ADDR_TYPE_IDENTITY 0 +#define BTP_GAP_ADDR_TYPE_RESOLVABLE_PRIVATE 1 +#define BTP_GAP_ADDR_TYPE_NON_RESOLVABLE_PRIVATE 2 + #define BTP_GAP_START_ADVERTISING 0x0a struct btp_gap_start_advertising_cmd { uint8_t adv_data_len; @@ -233,7 +237,7 @@ struct btp_gap_set_mitm { #define BTP_GAP_SET_FILTER_LIST 0x1c struct btp_gap_set_filter_list { uint8_t cnt; - bt_addr_le_t addr[0]; + bt_addr_le_t addr[]; } __packed; #define BTP_GAP_SET_PRIVACY 0x1d @@ -249,6 +253,69 @@ struct btp_gap_set_extended_advertising_rp { uint32_t current_settings; } __packed; +#define BTP_GAP_PADV_CONFIGURE 0x22 +/* bitmap of flags*/ +#define BTP_GAP_PADV_INCLUDE_TX_POWER BIT(0) +struct btp_gap_padv_configure_cmd { + uint8_t flags; + uint16_t interval_min; + uint16_t interval_max; +} __packed; +struct btp_gap_padv_configure_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_PADV_START 0x23 +struct btp_gap_padv_start_cmd { + uint8_t flags; +} __packed; +struct btp_gap_padv_start_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_PADV_STOP 0x24 +struct btp_gap_padv_stop_cmd { +} __packed; +struct btp_gap_padv_stop_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_PADV_SET_DATA 0x25 +struct btp_gap_padv_set_data_cmd { + uint16_t data_len; + uint8_t data[]; +} __packed; + +#define BTP_GAP_PADV_CREATE_SYNC 0x26 +struct btp_gap_padv_create_sync_cmd { + bt_addr_le_t address; + uint8_t advertiser_sid; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; + +#define BTP_GAP_PADV_SYNC_TRANSFER_SET_INFO 0x27 +struct btp_gap_padv_sync_transfer_set_info_cmd { + bt_addr_le_t address; + uint16_t service_data; +} __packed; + +#define BTP_GAP_PADV_SYNC_TRANSFER_START 0x28 +struct btp_gap_padv_sync_transfer_start_cmd { + uint16_t sync_handle; + bt_addr_le_t address; + uint16_t service_data; +} __packed; + +#define BTP_GAP_PADV_SYNC_TRANSFER_RECV 0x29 +struct btp_gap_padv_sync_transfer_recv_cmd { + bt_addr_le_t address; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; + /* events */ #define BTP_GAP_EV_NEW_SETTINGS 0x80 struct btp_gap_new_settings_ev { @@ -337,3 +404,57 @@ struct btp_gap_bond_pairing_failed_ev { bt_addr_le_t address; uint8_t reason; } __packed; + +#define BTP_GAP_EV_PERIODIC_SYNC_ESTABLISHED 0x8d +struct btp_gap_ev_periodic_sync_established_ev { + bt_addr_le_t address; + uint16_t sync_handle; + uint8_t status; +} __packed; + +#define BTP_GAP_EV_PERIODIC_SYNC_LOST 0x8e +struct btp_gap_ev_periodic_sync_lost_ev { + uint16_t sync_handle; + uint8_t reason; +} __packed; + +#define BTP_GAP_EV_PERIODIC_REPORT 0x8f +struct btp_gap_ev_periodic_report_ev { + uint16_t sync_handle; + uint8_t tx_power; + uint8_t rssi; + uint8_t cte_type; + uint8_t data_status; + uint8_t data_len; + uint8_t data[]; +} __packed; + +#define BTP_GAP_EV_PERIODIC_TRANSFER_RECEIVED 0x90 +struct btp_gap_ev_periodic_transfer_received_ev { + uint16_t sync_handle; + uint8_t tx_power; + uint8_t rssi; + uint8_t cte_type; + uint8_t data_status; + uint8_t data_len; + uint8_t data[]; +} __packed; + +#if defined(CONFIG_BT_EXT_ADV) +struct bt_le_per_adv_param; +struct bt_le_per_adv_sync_param; +struct bt_le_adv_param; +struct bt_data; +struct bt_le_ext_adv *tester_gap_ext_adv_get(void); +struct bt_le_per_adv_sync *tester_gap_padv_get(void); +int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len, uint32_t *settings); +int tester_gap_stop_ext_adv(void); +int tester_gap_start_ext_adv(void); +int tester_gap_padv_configure(const struct bt_le_per_adv_param *param); +int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len); +int tester_gap_padv_start(void); +int tester_gap_padv_stop(void); +int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params); +#endif /* defined(CONFIG_BT_EXT_ADV) */ diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 7d9e65c2d37..1602658ad17 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -31,6 +31,10 @@ void tester_init(void); void tester_rsp(uint8_t service, uint8_t opcode, uint8_t status); void tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len); void tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len); +int tester_rsp_buffer_lock(void); +void tester_rsp_buffer_unlock(void); +void tester_rsp_buffer_free(void); +void tester_rsp_buffer_allocate(size_t len, uint8_t **data); /* Used to indicate that command length is variable and that validation will * be done in handler. diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index fd084c2aa4b..ba34d9613fc 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "bap_endpoint.h" #include @@ -44,8 +45,6 @@ static const struct bt_audio_codec_cap vendor_codec_cap = BT_AUDIO_CODEC_CAP( struct audio_stream { struct bt_bap_stream stream; - uint8_t ase_id; - uint8_t conn_id; atomic_t seq_num; uint16_t last_req_seq_num; uint16_t last_sent_seq_num; @@ -53,10 +52,25 @@ struct audio_stream { size_t len_to_send; struct k_work_delayable audio_clock_work; struct k_work_delayable audio_send_work; - uint8_t cig_id; - uint8_t cis_id; - struct bt_bap_unicast_group **cig; bool already_sent; + bool broadcast; + + union { + /* Unicast */ + struct { + uint8_t ase_id; + uint8_t conn_id; + uint8_t cig_id; + uint8_t cis_id; + struct bt_bap_unicast_group **cig; + }; + + /* Broadcast */ + struct { + uint8_t bis_id; + bool bis_synced; + }; + }; }; #define MAX_STREAMS_COUNT MAX(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT, \ @@ -72,7 +86,7 @@ struct audio_connection { struct bt_audio_codec_qos qos; struct bt_bap_ep *end_points[MAX_END_POINTS_COUNT]; size_t end_points_count; -} connections[CONFIG_BT_MAX_CONN]; +} connections[CONFIG_BT_MAX_CONN], broadcast_connection; static struct bt_bap_unicast_group *cigs[CONFIG_BT_ISO_MAX_CIG]; @@ -95,6 +109,17 @@ static void audio_send_timeout(struct k_work *work); K_THREAD_STACK_DEFINE(iso_data_thread_stack_area, ISO_DATA_THREAD_STACK_SIZE); static struct k_work_q iso_data_work_q; +static struct bt_bap_broadcast_source *broadcast_source; +static struct audio_connection *broadcaster; +static struct bt_bap_broadcast_sink *broadcast_sink; +static bt_addr_le_t broadcaster_addr; +static uint32_t broadcaster_broadcast_id; +static struct bt_bap_stream *sink_streams[MAX_STREAMS_COUNT]; +/* A mask for the maximum BIS we can sync to. +1 since the BIS indexes start from 1. */ +static const uint32_t bis_index_mask = BIT_MASK(MAX_STREAMS_COUNT + 1); +static uint32_t bis_index_bitfield; +#define INVALID_BROADCAST_ID (BT_AUDIO_BROADCAST_ID_MAX + 1) + static bool print_cb(struct bt_data *data, void *user_data) { const char *str = (const char *)user_data; @@ -474,6 +499,39 @@ static void btp_send_stream_received_ev(struct bt_conn *conn, struct bt_bap_ep * tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_STREAM_RECEIVED, ev, sizeof(*ev) + data_len); } +static void btp_send_bis_syced_ev(const bt_addr_le_t *address, uint32_t broadcast_id, + uint8_t bis_id) +{ + struct btp_bap_bis_syned_ev ev; + + bt_addr_le_copy(&ev.address, address); + sys_put_le24(broadcast_id, ev.broadcast_id); + ev.bis_id = bis_id; + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_SYNCED, &ev, sizeof(ev)); +} + +static void btp_send_bis_stream_received_ev(const bt_addr_le_t *address, uint32_t broadcast_id, + uint8_t bis_id, uint8_t data_len, uint8_t *data) +{ + struct btp_bap_bis_stream_received_ev *ev; + + LOG_DBG("Stream received, len %d", data_len); + + net_buf_simple_init(rx_ev_buf, 0); + + ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev)); + + bt_addr_le_copy(&ev->address, address); + sys_put_le24(broadcast_id, ev->broadcast_id); + ev->bis_id = bis_id; + ev->data_len = data_len; + memcpy(ev->data, data, data_len); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_STREAM_RECEIVED, ev, + sizeof(*ev) + data_len); +} + static void stream_configured(struct bt_bap_stream *stream, const struct bt_audio_codec_qos_pref *pref) { @@ -613,8 +671,13 @@ static void stream_started(struct bt_bap_stream *stream) K_USEC(a_stream->stream.qos->interval)); } - btp_send_ascs_ase_state_changed_ev(stream->conn, a_stream->ase_id, - stream->ep->status.state); + if (a_stream->broadcast) { + btp_send_bis_syced_ev(&broadcaster_addr, broadcaster_broadcast_id, + a_stream->bis_id); + } else { + btp_send_ascs_ase_state_changed_ev(stream->conn, a_stream->ase_id, + stream->ep->status.state); + } } static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) @@ -627,8 +690,10 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) k_work_cancel_delayable(&a_stream->audio_clock_work); k_work_cancel_delayable(&a_stream->audio_send_work); - btp_send_ascs_operation_completed_ev(stream->conn, a_stream->ase_id, - BT_ASCS_STOP_OP, BTP_STATUS_SUCCESS); + if (!a_stream->broadcast) { + btp_send_ascs_operation_completed_ev(stream->conn, a_stream->ase_id, + BT_ASCS_STOP_OP, BTP_STATUS_SUCCESS); + } } static void stream_recv(struct bt_bap_stream *stream, @@ -643,7 +708,13 @@ static void stream_recv(struct bt_bap_stream *stream, */ LOG_DBG("Incoming audio on stream %p len %u", stream, buf->len); a_stream->already_sent = true; - btp_send_stream_received_ev(stream->conn, stream->ep, buf->len, buf->data); + + if (a_stream->broadcast) { + btp_send_bis_stream_received_ev(&broadcaster_addr, broadcaster_broadcast_id, + a_stream->bis_id, buf->len, buf->data); + } else { + btp_send_stream_received_ev(stream->conn, stream->ep, buf->len, buf->data); + } } } @@ -1020,6 +1091,10 @@ static void audio_send_timeout(struct k_work *work) size = ring_buf_get_claim(&audio_ring_buf, &data, stream->stream.qos->sdu); if (size != 0) { net_buf_add_mem(buf, data, size); + } else { + k_work_schedule_for_queue(&iso_data_work_q, dwork, + K_USEC(stream->stream.qos->interval)); + return; } /* Because the seq_num field of the audio_stream struct is atomic_val_t (4 bytes), @@ -1027,13 +1102,12 @@ static void audio_send_timeout(struct k_work *work) */ stream->last_req_seq_num = (uint16_t)atomic_get(&stream->seq_num); - LOG_DBG("Sending data to ASE: ase_id %d len %d seq %d", stream->stream.ep->status.id, - size, stream->last_req_seq_num); + LOG_DBG("Sending data to stream %p len %d seq %d", &stream->stream, size, + stream->last_req_seq_num); err = bt_bap_stream_send(&stream->stream, buf, 0, BT_ISO_TIMESTAMP_NONE); if (err != 0) { - LOG_ERR("Failed to send audio data to stream: ase_id %d dir %d seq %d err %d", - stream->ase_id, stream->stream.ep->dir, stream->last_req_seq_num, err); + LOG_ERR("Failed to send audio data to stream %p, err %d", &stream->stream, err); net_buf_unref(buf); } @@ -1086,6 +1160,566 @@ static uint8_t bap_send(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static int setup_broadcast_source(uint8_t streams_per_subgroup, uint8_t subgroups, + struct bt_bap_broadcast_source **source) +{ + int err; + struct bt_bap_broadcast_source_stream_param + stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; + struct bt_bap_broadcast_source_subgroup_param + subgroup_param[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; + struct bt_bap_broadcast_source_create_param create_param; + + if (streams_per_subgroup * subgroups > CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT || + subgroups > CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT) { + return -EINVAL; + } + + for (size_t i = 0U; i < subgroups; i++) { + subgroup_param[i].params_count = streams_per_subgroup; + subgroup_param[i].params = stream_params + i * streams_per_subgroup; + subgroup_param[i].codec_cfg = &broadcaster->codec_cfg; + } + + for (size_t j = 0U; j < streams_per_subgroup; j++) { + broadcaster->streams[j].broadcast = true; + stream_params[j].stream = &broadcaster->streams[j].stream; + stream_params[j].data = NULL; + stream_params[j].data_len = 0U; + bt_bap_stream_cb_register(stream_params[j].stream, &stream_ops); + } + + create_param.params_count = subgroups; + create_param.params = subgroup_param; + create_param.qos = &broadcaster->qos; + create_param.encryption = false; + create_param.packing = BT_ISO_PACKING_SEQUENTIAL; + + LOG_DBG("Creating broadcast source with %zu subgroups with %zu streams", + subgroups, subgroups * streams_per_subgroup); + + err = bt_bap_broadcast_source_create(&create_param, source); + if (err != 0) { + LOG_DBG("Unable to create broadcast source: %d", err); + + return err; + } + + return 0; +} + +static uint8_t broadcast_source_setup(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_bap_broadcast_source_setup_cmd *cp = cmd; + struct btp_bap_broadcast_source_setup_rp *rp = rsp; + struct bt_le_adv_param *param = BT_LE_EXT_ADV_NCONN_NAME; + uint32_t broadcast_id; + uint32_t gap_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) | + BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + + NET_BUF_SIMPLE_DEFINE(ad_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE); + NET_BUF_SIMPLE_DEFINE(base_buf, 128); + + /* Broadcast Audio Streaming Endpoint advertising data */ + struct bt_data base_ad; + struct bt_data per_ad; + + LOG_DBG(""); + + broadcaster->codec_cfg.id = cp->coding_format; + broadcaster->codec_cfg.vid = cp->vid; + broadcaster->codec_cfg.cid = cp->cid; + broadcaster->codec_cfg.data_len = cp->cc_ltvs_len; + memcpy(broadcaster->codec_cfg.data, cp->cc_ltvs, cp->cc_ltvs_len); + + broadcaster->qos.phy = BT_AUDIO_CODEC_QOS_2M; + broadcaster->qos.framing = cp->framing; + broadcaster->qos.rtn = cp->retransmission_num; + broadcaster->qos.latency = sys_le16_to_cpu(cp->max_transport_latency); + broadcaster->qos.interval = sys_get_le24(cp->sdu_interval); + broadcaster->qos.pd = sys_get_le24(cp->presentation_delay); + broadcaster->qos.sdu = sys_le16_to_cpu(cp->max_sdu); + + if (broadcast_source == NULL) { + err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, + &broadcast_source); + } else { + err = bt_bap_broadcast_source_reconfig(broadcast_source, &broadcaster->codec_cfg, + &broadcaster->qos); + } + + if (err != 0) { + LOG_DBG("Unable to setup broadcast source: %d", err); + + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_source_get_id(broadcast_source, &broadcast_id); + if (err != 0) { + LOG_DBG("Unable to get broadcast ID: %d", err); + + return BTP_STATUS_FAILED; + } + + /* Setup extended advertising data */ + net_buf_simple_add_le16(&ad_buf, BT_UUID_BROADCAST_AUDIO_VAL); + net_buf_simple_add_le24(&ad_buf, broadcast_id); + base_ad.type = BT_DATA_SVC_DATA16; + base_ad.data_len = ad_buf.len; + base_ad.data = ad_buf.data; + err = tester_gap_create_adv_instance(param, BTP_GAP_ADDR_TYPE_IDENTITY, &base_ad, 1, NULL, + 0, &gap_settings); + if (err != 0) { + LOG_DBG("Failed to create extended advertising instance: %d", err); + + return BTP_STATUS_FAILED; + } + + err = tester_gap_padv_configure(BT_LE_PER_ADV_PARAM(BT_GAP_PER_ADV_FAST_INT_MIN_2, + BT_GAP_PER_ADV_FAST_INT_MAX_2, + BT_LE_PER_ADV_OPT_USE_TX_POWER)); + if (err != 0) { + LOG_DBG("Failed to configure periodic advertising: %d", err); + + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_source_get_base(broadcast_source, &base_buf); + if (err != 0) { + LOG_DBG("Failed to get encoded BASE: %d\n", err); + + return BTP_STATUS_FAILED; + } + + per_ad.type = BT_DATA_SVC_DATA16; + per_ad.data_len = base_buf.len; + per_ad.data = base_buf.data; + err = tester_gap_padv_set_data(&per_ad, 1); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + rp->gap_settings = gap_settings; + sys_put_le24(broadcast_id, rp->broadcast_id); + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_source_release(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_bap_broadcast_source_delete(broadcast_source); + if (err != 0) { + LOG_DBG("Unable to delete broadcast source: %d", err); + + return BTP_STATUS_FAILED; + } + + memset(broadcaster, 0, sizeof(*broadcaster)); + broadcast_source = NULL; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_adv_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(); + + LOG_DBG(""); + + if (ext_adv == NULL) { + return BTP_STATUS_FAILED; + } + + err = tester_gap_start_ext_adv(); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + err = tester_gap_padv_start(); + if (err != 0) { + LOG_DBG("Unable to start periodic advertising: %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_adv_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = tester_gap_padv_stop(); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + err = tester_gap_stop_ext_adv(); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_source_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(); + + LOG_DBG(""); + + if (ext_adv == NULL) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_source_start(broadcast_source, ext_adv); + if (err != 0) { + LOG_DBG("Unable to start broadcast source: %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_source_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_bap_broadcast_source_stop(broadcast_source); + if (err != 0) { + LOG_DBG("Unable to stop broadcast source: %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static int broadcast_sink_reset(void) +{ + bis_index_bitfield = 0U; + (void)memset(&broadcaster_addr, 0, sizeof(broadcaster_addr)); + (void)memset(broadcaster, 0, sizeof(*broadcaster)); + broadcaster_broadcast_id = INVALID_BROADCAST_ID; + + return 0; +} + +static void btp_send_baa_found_ev(const bt_addr_le_t *address, uint32_t broadcast_id, + uint8_t sid, uint16_t interval) +{ + struct btp_bap_baa_found_ev ev; + + bt_addr_le_copy(&ev.address, address); + sys_put_le24(broadcast_id, ev.broadcast_id); + ev.advertiser_sid = sid; + ev.padv_interval = interval; + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BAA_FOUND, &ev, sizeof(ev)); +} + +static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) +{ + const struct bt_le_scan_recv_info *info = user_data; + char le_addr[BT_ADDR_LE_STR_LEN]; + struct bt_uuid_16 adv_uuid; + uint32_t broadcast_id; + + if (data->type != BT_DATA_SVC_DATA16) { + return true; + } + + if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) { + return true; + } + + if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) { + return true; + } + + if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) { + return true; + } + + broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16); + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + + LOG_DBG("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X", broadcast_id, + le_addr, info->sid); + + btp_send_baa_found_ev(info->addr, broadcast_id, info->sid, info->interval); + + /* Stop parsing */ + return false; +} + +static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) +{ + /* If 0 there is no periodic advertising. */ + if (info->interval != 0U) { + bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info); + } +} + +static struct bt_le_scan_cb bap_scan_cb = { + .recv = broadcast_scan_recv, +}; + +static void btp_send_bis_found_ev(const bt_addr_le_t *address, uint32_t broadcast_id, uint32_t pd, + uint8_t subgroup_index, uint8_t bis_index, + const struct bt_audio_codec_cfg *codec_cfg) +{ + struct btp_bap_bis_found_ev *ev; + + tester_rsp_buffer_lock(); + tester_rsp_buffer_allocate(sizeof(*ev) + codec_cfg->data_len, (uint8_t **)&ev); + + bt_addr_le_copy(&ev->address, address); + sys_put_le24(broadcast_id, ev->broadcast_id); + sys_put_le24(pd, ev->presentation_delay); + ev->subgroup_id = subgroup_index; + ev->bis_id = bis_index; + ev->coding_format = codec_cfg->id; + ev->vid = sys_cpu_to_le16(codec_cfg->vid); + ev->cid = sys_cpu_to_le16(codec_cfg->cid); + + ev->cc_ltvs_len = codec_cfg->data_len; + memcpy(ev->cc_ltvs, codec_cfg->data, ev->cc_ltvs_len); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_FOUND, ev, + sizeof(*ev) + ev->cc_ltvs_len); + + tester_rsp_buffer_free(); + tester_rsp_buffer_unlock(); +} + +static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base) +{ + size_t stream_count = 0U; + uint32_t base_bis_index_bitfield = 0U; + const struct bt_audio_codec_cfg *codec_cfg; + + LOG_DBG(""); + + if (broadcaster_broadcast_id != sink->broadcast_id) { + return; + } + + LOG_DBG("Received BASE with %u subgroups from broadcast sink %p", base->subgroup_count, + sink); + + for (size_t i = 0U; i < base->subgroup_count; i++) { + for (size_t j = 0U; j < base->subgroups[i].bis_count; j++) { + const uint8_t index = base->subgroups[i].bis_data[j].index; + + codec_cfg = &base->subgroups[i].codec_cfg; + base_bis_index_bitfield |= BIT(index); + + if (stream_count < MAX_STREAMS_COUNT) { + broadcaster->streams[stream_count++].bis_id = index; + } + + btp_send_bis_found_ev(&broadcaster_addr, sink->broadcast_id, + sink->base.pd, i, index, codec_cfg); + } + } + + bis_index_bitfield = base_bis_index_bitfield & bis_index_mask; +} + +static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted) +{ + int err; + + LOG_DBG(""); + + err = bt_bap_broadcast_sink_sync(broadcast_sink, bis_index_bitfield, sink_streams, NULL); + if (err != 0) { + LOG_DBG("Unable to sync to broadcast source: %d", err); + } +} + +static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { + .base_recv = base_recv_cb, + .syncable = syncable_cb, +}; + +static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync, + struct bt_le_per_adv_sync_synced_info *info) +{ + int err; + struct bt_le_per_adv_sync *pa_sync; + + LOG_DBG(""); + + pa_sync = tester_gap_padv_get(); + + if (sync != pa_sync) { + return; + } + + err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, &broadcast_sink); + if (err != 0) { + LOG_DBG("Failed to create broadcast sink: ID 0x%06X, err %d", + broadcaster_broadcast_id, err); + } +} + +static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = { + .synced = bap_pa_sync_synced_cb, +}; + +static uint8_t broadcast_sink_setup(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = broadcast_sink_reset(); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + for (size_t i = 0U; i < MAX_STREAMS_COUNT; i++) { + broadcaster->streams[i].broadcast = true; + sink_streams[i] = &broadcaster->streams[i].stream; + sink_streams[i]->ops = &stream_ops; + } + + bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs); + bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb); + bt_le_scan_cb_register(&bap_scan_cb); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_sink_release(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = broadcast_sink_reset(); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_scan_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL); + if (err != 0 && err != -EALREADY) { + LOG_DBG("Unable to start scan for broadcast sources: %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_scan_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_le_scan_stop(); + if (err != 0) { + LOG_DBG("Failed to stop scan, %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_sink_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_bap_broadcast_sink_sync_cmd *cp = cmd; + struct bt_le_per_adv_sync_param create_params = {0}; + + LOG_DBG(""); + + /* Sink Sync steps: + * 1. bt_le_per_adv_sync_create() + * 2. bap_pa_sync_synced_cb() + * 3. bt_bap_broadcast_sink_create() + * 4. - base_recv_cb() + * - syncable_cb() + * - broadcast_code_cb() <- only with scan delegator + * - bis_sync_req_cb() <- only for scan delegator + * 5. bt_bap_broadcast_sink_sync() + * 6. stream_started() + * 7. stream_recv_cb() + * 8. bap_pa_sync_terminated_cb() + * 9. stream_stopped_cb() + */ + + broadcaster_broadcast_id = sys_get_le24(cp->broadcast_id); + bt_addr_le_copy(&broadcaster_addr, &cp->address); + bt_addr_le_copy(&create_params.addr, &cp->address); + create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; + create_params.sid = cp->advertiser_sid; + create_params.skip = cp->skip; + create_params.timeout = cp->sync_timeout; + + err = tester_padv_create_sync(&create_params); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_sink_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + LOG_DBG(""); + + err = bt_bap_broadcast_sink_stop(broadcast_sink); + if (err != 0) { + LOG_DBG("Unable to sync to broadcast source: %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + static void connected(struct bt_conn *conn, uint8_t err) { struct audio_connection *audio_conn; @@ -1196,7 +1830,7 @@ static uint8_t client_add_ase_to_cis(struct audio_connection *audio_conn, uint8_ } static int client_create_unicast_group(struct audio_connection *audio_conn, uint8_t ase_id, - uint8_t cig_id) + uint8_t cig_id) { int err; struct bt_bap_unicast_group_stream_pair_param pair_params[MAX_STREAMS_COUNT]; @@ -1383,9 +2017,9 @@ static uint8_t ascs_configure_codec(const void *cmd, uint16_t cmd_len, codec_cfg->vid = cp->vid; codec_cfg->cid = cp->cid; - if (cp->ltvs_len != 0) { - codec_cfg->data_len = cp->ltvs_len; - memcpy(codec_cfg->data, cp->ltvs, cp->ltvs_len); + if (cp->cc_ltvs_len != 0) { + codec_cfg->data_len = cp->cc_ltvs_len; + memcpy(codec_cfg->data, cp->cc_ltvs, cp->cc_ltvs_len); } if (conn_info.role == BT_HCI_ROLE_CENTRAL) { @@ -1938,6 +2572,66 @@ static const struct btp_handler bap_handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = bap_send, }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_SETUP, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_source_setup, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_RELEASE, + .expect_len = sizeof(struct btp_bap_broadcast_source_release_cmd), + .func = broadcast_source_release, + }, + { + .opcode = BTP_BAP_BROADCAST_ADV_START, + .expect_len = sizeof(struct btp_bap_broadcast_adv_start_cmd), + .func = broadcast_adv_start, + }, + { + .opcode = BTP_BAP_BROADCAST_ADV_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_adv_stop_cmd), + .func = broadcast_adv_stop, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_START, + .expect_len = sizeof(struct btp_bap_broadcast_source_start_cmd), + .func = broadcast_source_start, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_source_stop_cmd), + .func = broadcast_source_stop, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_SETUP, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_sink_setup, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_RELEASE, + .expect_len = sizeof(struct btp_bap_broadcast_sink_release_cmd), + .func = broadcast_sink_release, + }, + { + .opcode = BTP_BAP_BROADCAST_SCAN_START, + .expect_len = sizeof(struct btp_bap_broadcast_scan_start_cmd), + .func = broadcast_scan_start, + }, + { + .opcode = BTP_BAP_BROADCAST_SCAN_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_scan_stop_cmd), + .func = broadcast_scan_stop, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_SYNC, + .expect_len = sizeof(struct btp_bap_broadcast_sink_sync_cmd), + .func = broadcast_sink_sync, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_sink_stop_cmd), + .func = broadcast_sink_stop, + }, }; uint8_t tester_init_pacs(void) @@ -1999,6 +2693,8 @@ uint8_t tester_init_bap(void) /* reset data */ (void)memset(connections, 0, sizeof(connections)); + broadcaster = &broadcast_connection; + err = bt_bap_unicast_client_register_cb(&unicast_client_cbs); if (err != 0) { LOG_DBG("Failed to register client callbacks: %d", err); diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 65792e7da65..2191da79534 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -32,10 +32,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #define BT_LE_AD_DISCOV_MASK (BT_LE_AD_LIMITED | BT_LE_AD_GENERAL) #define ADV_BUF_LEN (sizeof(struct btp_gap_device_found_ev) + 2 * 31) -#if defined(CONFIG_BT_EXT_ADV) -static struct bt_le_ext_adv *ext_adv; -#endif - static atomic_t current_settings; struct bt_conn_auth_cb cb; static uint8_t oob_legacy_tk[16] = { 0 }; @@ -476,6 +472,47 @@ static struct bt_data ad[10] = { }; static struct bt_data sd[10]; +#if defined(CONFIG_BT_EXT_ADV) +static struct bt_le_ext_adv *ext_adv; + +struct bt_le_ext_adv *tester_gap_ext_adv_get(void) +{ + return ext_adv; +} + +int tester_gap_start_ext_adv(void) +{ + int err; + + err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + LOG_ERR("Failed to start advertising"); + + return -EINVAL; + } + + atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING); + + return 0; +} + +int tester_gap_stop_ext_adv(void) +{ + int err; + + err = bt_le_ext_adv_stop(ext_adv); + if (err != 0) { + LOG_ERR("Failed to stop advertising"); + + return -EINVAL; + } + + atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING); + + return 0; +} +#endif /* defined(CONFIG_BT_EXT_ADV) */ + static uint8_t set_discoverable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -528,6 +565,66 @@ static uint8_t set_bondable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len, + uint32_t *settings) +{ + int err = 0; + + if (settings != NULL) { + atomic_set(¤t_settings, *settings); + } + + if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { + param->options |= BT_LE_ADV_OPT_CONNECTABLE; + } + + switch (own_addr_type) { + case BTP_GAP_ADDR_TYPE_IDENTITY: + param->options |= BT_LE_ADV_OPT_USE_IDENTITY; + break; +#if defined(CONFIG_BT_PRIVACY) + case BTP_GAP_ADDR_TYPE_RESOLVABLE_PRIVATE: + /* RPA usage is is controlled via privacy settings */ + if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY)) { + return -EINVAL; + } + break; + case BTP_GAP_ADDR_TYPE_NON_RESOLVABLE_PRIVATE: + /* NRPA is used only for non-connectable advertising */ + if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { + return -EINVAL; + } + break; +#endif + default: + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BT_EXT_ADV) && atomic_test_bit(¤t_settings, + BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) { + param->options |= BT_LE_ADV_OPT_EXT_ADV; + if (ext_adv != NULL) { + err = bt_le_ext_adv_delete(ext_adv); + if (err != 0) { + return err; + } + + ext_adv = NULL; + } + + err = bt_le_ext_adv_create(param, NULL, &ext_adv); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + err = bt_le_ext_adv_set_data(ext_adv, ad, ad_len, sd_len ? sd : NULL, sd_len); + } + + return err; +} + static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -583,57 +680,16 @@ static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, i += sd[sd_len].data_len; } - if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { - param.options |= BT_LE_ADV_OPT_CONNECTABLE; - } - - switch (own_addr_type) { - case 0x00: - param.options |= BT_LE_ADV_OPT_USE_IDENTITY; - break; -#if defined(CONFIG_BT_PRIVACY) - case 0x01: - /* RPA usage is is controlled via privacy settings */ - if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY)) { - return BTP_STATUS_FAILED; - } - break; - case 0x02: - /* NRPA is used only for non-connectable advertising */ - if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { - return BTP_STATUS_FAILED; - } - break; -#endif - default: + err = tester_gap_create_adv_instance(¶m, own_addr_type, ad, adv_len, sd, sd_len, NULL); + if (err != 0) { return BTP_STATUS_FAILED; } - if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) { #if defined(CONFIG_BT_EXT_ADV) - param.options |= BT_LE_ADV_OPT_EXT_ADV; - if (ext_adv != NULL) { - err = bt_le_ext_adv_delete(ext_adv); - if (err) { - return BTP_STATUS_FAILED; - } - - ext_adv = NULL; - } - - err = bt_le_ext_adv_create(¶m, NULL, &ext_adv); - if (err) { - return BTP_STATUS_FAILED; - } - - err = bt_le_ext_adv_set_data(ext_adv, ad, adv_len, sd_len ? sd : NULL, sd_len); - if (err) { - return BTP_STATUS_FAILED; - } - + if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) { err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); #else - return BTP_STATUS_FAILED; + if (0) { #endif } else { err = bt_le_adv_start(¶m, ad, adv_len, sd_len ? sd : NULL, sd_len); @@ -642,6 +698,7 @@ static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, /* BTP API don't allow to set empty scan response data. */ if (err < 0) { LOG_ERR("Failed to start advertising"); + return BTP_STATUS_FAILED; } @@ -1273,6 +1330,287 @@ static uint8_t set_extended_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if defined(CONFIG_BT_PER_ADV) +static struct bt_data padv[10]; +static struct bt_le_per_adv_sync *pa_sync; + +struct bt_le_per_adv_sync *tester_gap_padv_get(void) +{ + return pa_sync; +} + +static void pa_sync_synced_cb(struct bt_le_per_adv_sync *sync, + struct bt_le_per_adv_sync_synced_info *info) +{ + LOG_DBG(""); +} + +static void pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_term_info *info) +{ + LOG_DBG(""); + + if (sync == pa_sync) { + LOG_DBG("PA sync lost with reason %u", info->reason); + pa_sync = NULL; + } +} + +static struct bt_le_per_adv_sync_cb pa_sync_cb = { + .synced = pa_sync_synced_cb, + .term = pa_sync_terminated_cb, +}; + +int tester_gap_padv_configure(const struct bt_le_per_adv_param *param) +{ + int err; + struct bt_le_adv_param ext_adv_param = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_ONE_TIME, + param->interval_min, + param->interval_max, + NULL); + + if (ext_adv == NULL) { + current_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) | + BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY, ad, + 1, NULL, 0, NULL); + if (err != 0) { + return -EINVAL; + } + } + + /* Set periodic advertising parameters and the required + * bit in AD Flags of extended advertising. + */ + err = bt_le_per_adv_set_param(ext_adv, param); + if (err != 0) { + LOG_DBG("Failed to set periodic advertising parameters (err %d)\n", err); + } + + return err; +} + +static uint8_t padv_configure(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + uint32_t options = BT_LE_PER_ADV_OPT_NONE; + const struct btp_gap_padv_configure_cmd *cp = cmd; + struct btp_gap_padv_configure_rp *rp = rsp; + + if (cp->flags & BTP_GAP_PADV_INCLUDE_TX_POWER) { + options |= BT_LE_PER_ADV_OPT_USE_TX_POWER; + } + + err = tester_gap_padv_configure(BT_LE_PER_ADV_PARAM(sys_le16_to_cpu(cp->interval_min), + sys_le16_to_cpu(cp->interval_max), + options)); + if (err) { + return BTP_STATUS_FAILED; + } + + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +int tester_gap_padv_start(void) +{ + int err; + + if (ext_adv == NULL) { + return -EINVAL; + } + + if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING)) { + err = tester_gap_start_ext_adv(); + if (err != 0) { + return -EINVAL; + } + } + + /* Enable Periodic Advertising */ + err = bt_le_per_adv_start(ext_adv); + if (err != 0) { + LOG_DBG("Failed to start periodic advertising data: %d", err); + } + + return err; +} + +static uint8_t padv_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct btp_gap_padv_start_rp *rp = rsp; + + err = tester_gap_padv_start(); + + if (err) { + return BTP_STATUS_FAILED; + } + + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +int tester_gap_padv_stop(void) +{ + int err; + + if (ext_adv == NULL) { + return -EINVAL; + } + + /* Enable Periodic Advertising */ + err = bt_le_per_adv_stop(ext_adv); + if (err != 0) { + LOG_DBG("Failed to stop periodic advertising data: %d", err); + } + + return err; +} + +static uint8_t padv_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct btp_gap_padv_stop_rp *rp = rsp; + + err = tester_gap_padv_stop(); + + if (err) { + return BTP_STATUS_FAILED; + } + + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len) +{ + int err; + + if (ext_adv == NULL) { + return -EINVAL; + } + + /* Set Periodic Advertising data */ + err = bt_le_per_adv_set_data(ext_adv, per_ad, ad_len); + if (err != 0) { + LOG_DBG("Failed to set periodic advertising data: %d", err); + } + + return err; +} + +static uint8_t padv_set_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + uint8_t padv_len = 0U; + const struct btp_gap_padv_set_data_cmd *cp = cmd; + + for (uint8_t i = 0; i < cp->data_len; padv_len++) { + if (padv_len >= ARRAY_SIZE(padv)) { + LOG_ERR("padv[] Out of memory"); + return BTP_STATUS_FAILED; + } + + padv[padv_len].data_len = cp->data[i++] - 1; + padv[padv_len].type = cp->data[i++]; + padv[padv_len].data = &cp->data[i]; + i += padv[padv_len].data_len; + } + + err = tester_gap_padv_set_data(padv, padv_len); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) +{ + int err; + + if (pa_sync != NULL) { + return -EBUSY; + } + + err = bt_le_per_adv_sync_create(create_params, &pa_sync); + + if (err != 0) { + LOG_DBG("Unable to sync to PA: %d", err); + } + + return err; +} + +static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_gap_padv_create_sync_cmd *cp = cmd; + struct bt_le_per_adv_sync_param create_params = {0}; + + bt_addr_le_copy(&create_params.addr, &cp->address); + create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; + create_params.sid = cp->advertiser_sid; + create_params.skip = cp->skip; + create_params.timeout = cp->sync_timeout; + + err = tester_padv_create_sync(&create_params); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t padv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gap_padv_sync_transfer_set_info_cmd *cp = cmd; + (void)cp; + + /* TODO */ + + return BTP_STATUS_FAILED; +} + +static uint8_t padv_sync_transfer_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gap_padv_sync_transfer_start_cmd *cp = cmd; + (void)cp; + + /* TODO */ + + return BTP_STATUS_FAILED; +} + +static uint8_t padv_sync_transfer_recv(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gap_padv_sync_transfer_recv_cmd *cp = cmd; + (void)cp; + + /* TODO */ + + return BTP_STATUS_FAILED; +} +#endif /* defined(CONFIG_BT_PER_ADV) */ + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -1404,7 +1742,49 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_gap_set_extended_advertising_cmd), .func = set_extended_advertising, }, -#endif +#if defined(CONFIG_BT_PER_ADV) + { + .opcode = BTP_GAP_PADV_CONFIGURE, + .expect_len = sizeof(struct btp_gap_padv_configure_cmd), + .func = padv_configure, + }, + { + .opcode = BTP_GAP_PADV_START, + .expect_len = sizeof(struct btp_gap_padv_start_cmd), + .func = padv_start, + }, + { + .opcode = BTP_GAP_PADV_STOP, + .expect_len = sizeof(struct btp_gap_padv_stop_cmd), + .func = padv_stop, + }, + { + .opcode = BTP_GAP_PADV_SET_DATA, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = padv_set_data, + }, + { + .opcode = BTP_GAP_PADV_CREATE_SYNC, + .expect_len = sizeof(struct btp_gap_padv_create_sync_cmd), + .func = padv_create_sync, + }, + { + .opcode = BTP_GAP_PADV_SYNC_TRANSFER_SET_INFO, + .expect_len = sizeof(struct btp_gap_padv_sync_transfer_set_info_cmd), + .func = padv_sync_transfer_set_info, + }, + { + .opcode = BTP_GAP_PADV_SYNC_TRANSFER_START, + .expect_len = sizeof(struct btp_gap_padv_sync_transfer_start_cmd), + .func = padv_sync_transfer_start, + }, + { + .opcode = BTP_GAP_PADV_SYNC_TRANSFER_RECV, + .expect_len = sizeof(struct btp_gap_padv_sync_transfer_recv_cmd), + .func = padv_sync_transfer_recv, + }, +#endif /* defined(CONFIG_BT_PER_ADV) */ +#endif /* defined(CONFIG_BT_EXT_ADV) */ }; uint8_t tester_init_gap(void) @@ -1436,6 +1816,10 @@ uint8_t tester_init_gap(void) bt_conn_cb_register(&conn_callbacks); bt_conn_auth_info_cb_register(&auth_info_cb); +#if defined(CONFIG_BT_PER_ADV) + bt_le_per_adv_sync_cb_register(&pa_sync_cb); +#endif /* defined(CONFIG_BT_PER_ADV) */ + tester_register_command_handlers(BTP_SERVICE_ID_GAP, handlers, ARRAY_SIZE(handlers)); From 6e188d975733fd9992a4e3cf78dd2bacb61fec6e Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sun, 4 Jun 2023 00:52:43 +0300 Subject: [PATCH 1279/4498] arch: Add ARCH_SUPPORTS_ROM_START kconfig symbol Add an ARCH_SUPPORTS_ROM_START kconfig symbol to mark architectures that support ROM_START as an argument to zephyr_linker_sources. This was added so that features relying on this feature could depend on this kconfig symbol. Signed-off-by: Yonatan Schachter --- arch/Kconfig | 6 ++++++ arch/arm/core/Kconfig | 2 ++ 2 files changed, 8 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 4560fdfcc51..110938528ed 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -22,6 +22,7 @@ config ARC select HAS_DTS imply XIP select ARCH_HAS_THREAD_LOCAL_STORAGE + select ARCH_SUPPORTS_ROM_START help ARC architecture @@ -81,6 +82,7 @@ config X86 select ATOMIC_OPERATIONS_BUILTIN select HAS_DTS select ARCH_SUPPORTS_COREDUMP + select ARCH_SUPPORTS_ROM_START if !X86_64 select CPU_HAS_MMU select ARCH_MEM_DOMAIN_DATA if USERSPACE && !X86_COMMON_PAGE_TABLE select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE @@ -111,6 +113,7 @@ config RISCV select ARCH_IS_SET select HAS_DTS select ARCH_SUPPORTS_COREDUMP + select ARCH_SUPPORTS_ROM_START if !SOC_SERIES_ESP32C3 select ARCH_HAS_CODE_DATA_RELOCATION select ARCH_HAS_THREAD_LOCAL_STORAGE select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD @@ -597,6 +600,9 @@ config ARCH_SUPPORTS_COREDUMP config ARCH_SUPPORTS_ARCH_HW_INIT bool +config ARCH_SUPPORTS_ROM_START + bool + config ARCH_HAS_EXTRA_EXCEPTION_INFO bool diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index a14bcd0cb62..a06b4cb5e95 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -23,6 +23,7 @@ config CPU_CORTEX_M select ARCH_SUPPORTS_ARCH_HW_INIT select ARCH_HAS_SUSPEND_TO_RAM select ARCH_HAS_CODE_DATA_RELOCATION + select ARCH_SUPPORTS_ROM_START imply XIP help This option signifies the use of a CPU of the Cortex-M family. @@ -37,6 +38,7 @@ config CPU_AARCH32_CORTEX_R select ARCH_HAS_EXTRA_EXCEPTION_INFO select ARCH_HAS_CODE_DATA_RELOCATION select ARCH_HAS_NOCACHE_MEMORY_SUPPORT if ARM_MPU && CPU_HAS_ARM_MPU && CPU_HAS_DCACHE + select ARCH_SUPPORTS_ROM_START help This option signifies the use of a CPU of the Cortex-R family. From 111b181b14f665bcebefc0c1a843b7e0b8bf6ff8 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Mon, 25 Sep 2023 22:50:42 +0300 Subject: [PATCH 1280/4498] byteorder: Add macros for converting ints to arrays Add three macros: sys_uint{16,32,64}_to_array, to convert integers to byte arrays in a byte order aware manner. For example, sys_uint16_to_array(0x0123) evaluates to: {0x01, 0x23} for big endian machines, and {0x23, 0x01} for little endian machines. Signed-off-by: Yonatan Schachter --- include/zephyr/sys/byteorder.h | 85 ++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/include/zephyr/sys/byteorder.h b/include/zephyr/sys/byteorder.h index eebab0fb0be..978255fd02d 100644 --- a/include/zephyr/sys/byteorder.h +++ b/include/zephyr/sys/byteorder.h @@ -168,6 +168,49 @@ * @return 48-bit integer in big-endian format. */ +/** @def sys_uint16_to_array + * @brief Convert 16-bit unsigned integer to byte array. + * + * @details Byte order aware macro to treat an unsigned integer + * as an array, rather than an integer literal. For example, + * `0x0123` would be converted to `{0x01, 0x23}` for big endian + * machines, and `{0x23, 0x01}` for little endian machines. + * + * @param val 16-bit unsigned integer. + * + * @return 16-bit unsigned integer as byte array. + */ + +/** @def sys_uint32_to_array + * @brief Convert 32-bit unsigned integer to byte array. + * + * @details Byte order aware macro to treat an unsigned integer + * as an array, rather than an integer literal. For example, + * `0x01234567` would be converted to `{0x01, 0x23, 0x45, 0x67}` + * for big endian machines, and `{0x67, 0x45, 0x23, 0x01}` for + * little endian machines. + * + * @param val 32-bit unsigned integer. + * + * @return 32-bit unsigned integer as byte array. + */ + +/** @def sys_uint64_to_array + * @brief Convert 64-bit unsigned integer to byte array. + * + * @details Byte order aware macro to treat an unsigned integer + * as an array, rather than an integer literal. For example, + * `0x0123456789abcdef` would be converted to + * `{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}` + * for big endian machines, and + * `{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01}` for + * little endian machines. + * + * @param val 64-bit unsigned integer. + * + * @return 64-bit unsigned integer as byte array. + */ + #ifdef CONFIG_LITTLE_ENDIAN #define sys_le16_to_cpu(val) (val) #define sys_cpu_to_le16(val) (val) @@ -189,6 +232,27 @@ #define sys_cpu_to_be48(val) __bswap_48(val) #define sys_be64_to_cpu(val) __bswap_64(val) #define sys_cpu_to_be64(val) __bswap_64(val) + +#define sys_uint16_to_array(val) { \ + ((val) & 0xff), \ + (((val) >> 8) & 0xff)} + +#define sys_uint32_to_array(val) { \ + ((val) & 0xff), \ + (((val) >> 8) & 0xff), \ + (((val) >> 16) & 0xff), \ + (((val) >> 24) & 0xff)} + +#define sys_uint64_to_array(val) { \ + ((val) & 0xff), \ + (((val) >> 8) & 0xff), \ + (((val) >> 16) & 0xff), \ + (((val) >> 24) & 0xff), \ + (((val) >> 32) & 0xff), \ + (((val) >> 40) & 0xff), \ + (((val) >> 48) & 0xff), \ + (((val) >> 56) & 0xff)} + #else #define sys_le16_to_cpu(val) __bswap_16(val) #define sys_cpu_to_le16(val) __bswap_16(val) @@ -210,6 +274,27 @@ #define sys_cpu_to_be48(val) (val) #define sys_be64_to_cpu(val) (val) #define sys_cpu_to_be64(val) (val) + +#define sys_uint16_to_array(val) { \ + (((val) >> 8) & 0xff), \ + ((val) & 0xff)} + +#define sys_uint32_to_array(val) { \ + (((val) >> 24) & 0xff), \ + (((val) >> 16) & 0xff), \ + (((val) >> 8) & 0xff), \ + ((val) & 0xff)} + +#define sys_uint64_to_array(val) { \ + (((val) >> 56) & 0xff), \ + (((val) >> 48) & 0xff), \ + (((val) >> 40) & 0xff), \ + (((val) >> 32) & 0xff), \ + (((val) >> 24) & 0xff), \ + (((val) >> 16) & 0xff), \ + (((val) >> 8) & 0xff), \ + ((val) & 0xff)} + #endif /** From a7df77cd99d5ad958c81f354f01b319635c5d1cd Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Mon, 25 Sep 2023 23:31:13 +0300 Subject: [PATCH 1281/4498] tests: byteorder: Add tests for sys_uint*_to_array macros Add tests for sys_uint*_to_array macros to the byteorder suite. Signed-off-by: Yonatan Schachter --- tests/kernel/common/src/byteorder.c | 63 +++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/kernel/common/src/byteorder.c b/tests/kernel/common/src/byteorder.c index 1357c2e6926..8fcda358a7f 100644 --- a/tests/kernel/common/src/byteorder.c +++ b/tests/kernel/common/src/byteorder.c @@ -456,6 +456,69 @@ ZTEST(byteorder, test_sys_put_le64) zassert_mem_equal(tmp, buf, sizeof(uint64_t), "sys_put_le64() failed"); } +/** + * @brief Test sys_uint16_to_array() functionality + * + * @details Test if sys_uint16_to_array() correctly handles endianness. + * + * @see sys_uint16_to_array() + */ +ZTEST(byteorder, test_sys_uint16_to_array) +{ + #define VAL 0xf0e1 + uint8_t tmp[sizeof(uint16_t)] = sys_uint16_to_array(VAL); + uint8_t buf[] = { + COND_CODE_1(CONFIG_LITTLE_ENDIAN, + (0xe1, 0xf0), + (0xf0, 0xe1)) + }; + + zassert_mem_equal(tmp, buf, sizeof(uint16_t), "sys_uint16_to_array() failed"); + #undef VAL +} + +/** + * @brief Test sys_uint32_to_array() functionality + * + * @details Test if sys_uint32_to_array() correctly handles endianness. + * + * @see sys_uint32_to_array() + */ +ZTEST(byteorder, test_sys_uint32_to_array) +{ + #define VAL 0xf0e1d2c3 + uint8_t tmp[sizeof(uint32_t)] = sys_uint32_to_array(VAL); + uint8_t buf[] = { + COND_CODE_1(CONFIG_LITTLE_ENDIAN, + (0xc3, 0xd2, 0xe1, 0xf0), + (0xf0, 0xe1, 0xd2, 0xc3)) + }; + + zassert_mem_equal(tmp, buf, sizeof(uint32_t), "sys_uint32_to_array() failed"); + #undef VAL +} + +/** + * @brief Test sys_uint64_to_array() functionality + * + * @details Test if sys_uint64_to_array() correctly handles endianness. + * + * @see sys_uint64_to_array() + */ +ZTEST(byteorder, test_sys_uint64_to_array) +{ + #define VAL 0xf0e1d2c3b4a59687 + uint8_t tmp[sizeof(uint64_t)] = sys_uint64_to_array(VAL); + uint8_t buf[] = { + COND_CODE_1(CONFIG_LITTLE_ENDIAN, + (0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0), + (0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87)) + }; + + zassert_mem_equal(tmp, buf, sizeof(uint64_t), "sys_uint64_to_array() failed"); + #undef VAL +} + extern void *common_setup(void); ZTEST_SUITE(byteorder, NULL, common_setup, NULL, NULL, NULL); From 5508b17fb4143e61853c69636efbff49cedafcae Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 23 Mar 2023 17:54:31 +0200 Subject: [PATCH 1282/4498] bindesc: Add initial support for binary descriptor definition Binary descriptors are data objects stored at a known location of a binary image. They can be read by an external tool or image, and are used mostly for build information: version, build time, host information, etc. This commit adds initial support for defining such descriptors. Signed-off-by: Yonatan Schachter --- include/zephyr/bindesc.h | 398 ++++++++++++++++++++++++++++ subsys/CMakeLists.txt | 1 + subsys/Kconfig | 1 + subsys/bindesc/CMakeLists.txt | 78 ++++++ subsys/bindesc/Kconfig | 25 ++ subsys/bindesc/Kconfig.build_time | 106 ++++++++ subsys/bindesc/Kconfig.host_info | 36 +++ subsys/bindesc/Kconfig.version | 65 +++++ subsys/bindesc/bindesc.ld | 13 + subsys/bindesc/bindesc_build_time.c | 49 ++++ subsys/bindesc/bindesc_host_info.c | 29 ++ subsys/bindesc/bindesc_no_vt.ld | 9 + subsys/bindesc/bindesc_version.c | 64 +++++ subsys/bindesc/x86/bindesc_skip.S | 9 + 14 files changed, 883 insertions(+) create mode 100644 include/zephyr/bindesc.h create mode 100644 subsys/bindesc/CMakeLists.txt create mode 100644 subsys/bindesc/Kconfig create mode 100644 subsys/bindesc/Kconfig.build_time create mode 100644 subsys/bindesc/Kconfig.host_info create mode 100644 subsys/bindesc/Kconfig.version create mode 100644 subsys/bindesc/bindesc.ld create mode 100644 subsys/bindesc/bindesc_build_time.c create mode 100644 subsys/bindesc/bindesc_host_info.c create mode 100644 subsys/bindesc/bindesc_no_vt.ld create mode 100644 subsys/bindesc/bindesc_version.c create mode 100644 subsys/bindesc/x86/bindesc_skip.S diff --git a/include/zephyr/bindesc.h b/include/zephyr/bindesc.h new file mode 100644 index 00000000000..4280cf91d21 --- /dev/null +++ b/include/zephyr/bindesc.h @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Corresponds to the definitions in scripts/west_commands/bindesc.py. + * Do not change without syncing the definitions in both files! + */ +#define BINDESC_MAGIC 0xb9863e5a7ea46046 +#define BINDESC_ALIGNMENT 4 +#define BINDESC_TYPE_UINT 0x0 +#define BINDESC_TYPE_STR 0x1 +#define BINDESC_TYPE_BYTES 0x2 +#define BINDESC_TYPE_DESCRIPTORS_END 0xf + +/** + * @brief Binary Descriptor Definition + * @defgroup bindesc_define Bindesc Define + * @{ + */ + +/* + * Corresponds to the definitions in scripts/west_commands/bindesc.py. + * Do not change without syncing the definitions in both files! + */ + +/** The app version string such as "1.2.3" */ +#define BINDESC_ID_APP_VERSION_STRING 0x800 + +/** The app version major such as 1 */ +#define BINDESC_ID_APP_VERSION_MAJOR 0x801 + +/** The app version minor such as 2 */ +#define BINDESC_ID_APP_VERSION_MINOR 0x802 + +/** The app version patchlevel such as 3 */ +#define BINDESC_ID_APP_VERSION_PATCHLEVEL 0x803 + +/** The app version number such as 0x10203 */ +#define BINDESC_ID_APP_VERSION_NUMBER 0x804 + +/** The kernel version string such as "3.4.0" */ +#define BINDESC_ID_KERNEL_VERSION_STRING 0x900 + +/** The kernel version major such as 3 */ +#define BINDESC_ID_KERNEL_VERSION_MAJOR 0x901 + +/** The kernel version minor such as 4 */ +#define BINDESC_ID_KERNEL_VERSION_MINOR 0x902 + +/** The kernel version patchlevel such as 0 */ +#define BINDESC_ID_KERNEL_VERSION_PATCHLEVEL 0x903 + +/** The kernel version number such as 0x30400 */ +#define BINDESC_ID_KERNEL_VERSION_NUMBER 0x904 + +/** The year the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_YEAR 0xa00 + +/** The month of the year the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_MONTH 0xa01 + +/** The day of the month the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_DAY 0xa02 + +/** The hour of the day the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_HOUR 0xa03 + +/** The minute the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_MINUTE 0xa04 + +/** The second the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_SECOND 0xa05 + +/** The UNIX time (seconds since midnight of 1970/01/01) the image was compiled in */ +#define BINDESC_ID_BUILD_TIME_UNIX 0xa06 + +/** The date and time of compilation such as "2023/02/05 00:07:04" */ +#define BINDESC_ID_BUILD_DATE_TIME_STRING 0xa07 + +/** The date of compilation such as "2023/02/05" */ +#define BINDESC_ID_BUILD_DATE_STRING 0xa08 + +/** The time of compilation such as "00:07:04" */ +#define BINDESC_ID_BUILD_TIME_STRING 0xa09 + +/** The name of the host that compiled the image */ +#define BINDESC_ID_HOST_NAME 0xb00 + +/** The C compiler name */ +#define BINDESC_ID_C_COMPILER_NAME 0xb01 + +/** The C compiler version */ +#define BINDESC_ID_C_COMPILER_VERSION 0xb02 + +/** The C++ compiler name */ +#define BINDESC_ID_CXX_COMPILER_NAME 0xb03 + +/** The C++ compiler version */ +#define BINDESC_ID_CXX_COMPILER_VERSION 0xb04 + +#define BINDESC_TAG_DESCRIPTORS_END BINDESC_TAG(DESCRIPTORS_END, 0x0fff) + +/** + * @cond INTERNAL_HIDDEN + */ + +/* + * Utility macro to generate a tag from a type and an ID + * + * type - Type of the descriptor, UINT, STR or BYTES + * id - Unique ID for the descriptor, must fit in 12 bits + */ +#define BINDESC_TAG(type, id) ((BINDESC_TYPE_##type & 0xf) << 12 | (id & 0x0fff)) + +/** + * @endcond + */ + +#if !IS_ENABLED(_LINKER) + +#include + +/** + * @cond INTERNAL_HIDDEN + */ + +/* + * Utility macro to get the name of a bindesc entry + */ +#define BINDESC_NAME(name) bindesc_entry_##name + +/* Convenience helper for declaring a binary descriptor entry. */ +#define __BINDESC_ENTRY_DEFINE(name) \ + __aligned(BINDESC_ALIGNMENT) const struct bindesc_entry BINDESC_NAME(name) \ + __in_section(_bindesc_entry, static, name) __used __noasan + +/** + * @endcond + */ + +/** + * @brief Define a binary descriptor of type string. + * + * @details + * Define a string that is registered in the binary descriptor header. + * The defined string can be accessed using @ref BINDESC_GET_STR + * + * @note The defined string is not static, so its name must not collide with + * any other symbol in the executable. + * + * @param name Name of the descriptor + * @param id Unique ID of the descriptor + * @param value A string value for the descriptor + */ +#define BINDESC_STR_DEFINE(name, id, value) \ + __BINDESC_ENTRY_DEFINE(name) = { \ + .tag = BINDESC_TAG(STR, id), \ + .len = (uint16_t)sizeof(value), \ + .data = value, \ + } + +/** + * @brief Define a binary descriptor of type uint. + * + * @details + * Define an integer that is registered in the binary descriptor header. + * The defined integer can be accessed using @ref BINDESC_GET_UINT + * + * @note The defined integer is not static, so its name must not collide with + * any other symbol in the executable. + * + * @param name Name of the descriptor + * @param id Unique ID of the descriptor + * @param value An integer value for the descriptor + */ +#define BINDESC_UINT_DEFINE(name, id, value) \ + __BINDESC_ENTRY_DEFINE(name) = { \ + .tag = BINDESC_TAG(UINT, id), \ + .len = (uint16_t)sizeof(uint32_t), \ + .data = sys_uint32_to_array(value), \ + } + +/** + * @brief Define a binary descriptor of type bytes. + * + * @details + * Define a uint8_t array that is registered in the binary descriptor header. + * The defined array can be accessed using @ref BINDESC_GET_BYTES. + * The value should be given as an array literal, wrapped in parentheses, for + * example: + * + * BINDESC_BYTES_DEFINE(name, id, ({1, 2, 3, 4})); + * + * @note The defined array is not static, so its name must not collide with + * any other symbol in the executable. + * + * @param name Name of the descriptor + * @param id Unique ID of the descriptor + * @param value A uint8_t array as data for the descriptor + */ +#define BINDESC_BYTES_DEFINE(name, id, value) \ + __BINDESC_ENTRY_DEFINE(name) = { \ + .tag = BINDESC_TAG(BYTES, id), \ + .len = (uint16_t)sizeof((uint8_t [])__DEBRACKET value), \ + .data = __DEBRACKET value, \ + } + +/** + * @brief Get the value of a string binary descriptor + * + * @details + * Get the value of a string binary descriptor, previously defined by + * BINDESC_STR_DEFINE. + * + * @param name Name of the descriptor + */ +#define BINDESC_GET_STR(name) BINDESC_NAME(name).data + +/** + * @brief Get the value of a uint binary descriptor + * + * @details + * Get the value of a uint binary descriptor, previously defined by + * BINDESC_UINT_DEFINE. + * + * @param name Name of the descriptor + */ +#define BINDESC_GET_UINT(name) *(uint32_t *)&(BINDESC_NAME(name).data) + +/** + * @brief Get the value of a bytes binary descriptor + * + * @details + * Get the value of a string binary descriptor, previously defined by + * BINDESC_BYTES_DEFINE. The returned value can be accessed as an array: + * + * for (size_t i = 0; i < BINDESC_GET_SIZE(name); i++) + * BINDESC_GET_BYTES(name)[i]; + * + * @param name Name of the descriptor + */ +#define BINDESC_GET_BYTES(name) BINDESC_NAME(name).data + +/** + * @brief Get the size of a binary descriptor + * + * @details + * Get the size of a binary descriptor. This is particularly useful for + * bytes binary descriptors where there's no null terminator. + * + * @param name Name of the descriptor + */ +#define BINDESC_GET_SIZE(name) BINDESC_NAME(name).len + +/** + * @} + */ + +/* + * An entry of the binary descriptor header. Each descriptor is + * described by one of these entries. + */ +struct bindesc_entry { + /** Tag of the entry */ + uint16_t tag; + /** Length of the descriptor data */ + uint16_t len; + /** Value of the entry. This is either an integer or a string */ + uint8_t data[]; +} __packed; + +/* + * We're assuming that `struct bindesc_entry` has a specific layout in + * memory, so it's worth making sure that the layout is really what we + * think it is. If these assertions fail for your toolchain/platform, + * please open a bug report. + */ +BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout"); +BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout"); +BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout"); + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) +extern const struct bindesc_entry BINDESC_NAME(kernel_version_string); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) +extern const struct bindesc_entry BINDESC_NAME(kernel_version_major); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) +extern const struct bindesc_entry BINDESC_NAME(kernel_version_minor); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) +extern const struct bindesc_entry BINDESC_NAME(kernel_version_patchlevel); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) +extern const struct bindesc_entry BINDESC_NAME(kernel_version_number); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) +extern const struct bindesc_entry BINDESC_NAME(app_version_string); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) +extern const struct bindesc_entry BINDESC_NAME(app_version_major); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) +extern const struct bindesc_entry BINDESC_NAME(app_version_minor); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) +extern const struct bindesc_entry BINDESC_NAME(app_version_patchlevel); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) +extern const struct bindesc_entry BINDESC_NAME(app_version_number); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) +extern const struct bindesc_entry BINDESC_NAME(build_time_year); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) +extern const struct bindesc_entry BINDESC_NAME(build_time_month); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) +extern const struct bindesc_entry BINDESC_NAME(build_time_day); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) +extern const struct bindesc_entry BINDESC_NAME(build_time_hour); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) +extern const struct bindesc_entry BINDESC_NAME(build_time_minute); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) +extern const struct bindesc_entry BINDESC_NAME(build_time_second); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) +extern const struct bindesc_entry BINDESC_NAME(build_time_unix); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) +extern const struct bindesc_entry BINDESC_NAME(build_date_time_string); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) +extern const struct bindesc_entry BINDESC_NAME(build_date_string); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) +extern const struct bindesc_entry BINDESC_NAME(build_time_string); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME) +extern const struct bindesc_entry BINDESC_NAME(host_name); +#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) +extern const struct bindesc_entry BINDESC_NAME(c_compiler_name); +#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) +extern const struct bindesc_entry BINDESC_NAME(c_compiler_version); +#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */ + +#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) +extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_name); +#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) +extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version); +#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ + +#endif /* !IS_ENABLED(_LINKER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ */ diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index f72add5d914..d1d9147484a 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -32,6 +32,7 @@ add_subdirectory(testsuite) add_subdirectory(tracing) add_subdirectory(usb) +add_subdirectory_ifdef(CONFIG_BINDESC bindesc) add_subdirectory_ifdef(CONFIG_BT bluetooth) add_subdirectory_ifdef(CONFIG_CONSOLE_SUBSYS console) add_subdirectory_ifdef(CONFIG_DEMAND_PAGING demand_paging) diff --git a/subsys/Kconfig b/subsys/Kconfig index 7121dc586fe..e5a7e8af2b3 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -6,6 +6,7 @@ menu "Subsystems and OS Services" +source "subsys/bindesc/Kconfig" source "subsys/bluetooth/Kconfig" source "subsys/canbus/Kconfig" source "subsys/console/Kconfig" diff --git a/subsys/bindesc/CMakeLists.txt b/subsys/bindesc/CMakeLists.txt new file mode 100644 index 00000000000..72634be12e6 --- /dev/null +++ b/subsys/bindesc/CMakeLists.txt @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +if(CONFIG_X86) + zephyr_linker_sources(ROM_START SORT_KEY 0x1bindesc bindesc_no_vt.ld) + zephyr_library_sources(x86/bindesc_skip.S) +else() + zephyr_linker_sources(ROM_START SORT_KEY 0x1bindesc bindesc.ld) +endif() + +macro(gen_build_time_int_definition def_name format) + if(CONFIG_BINDESC_${def_name}) + string(TIMESTAMP ${def_name} ${format}) + # remove leading zeros so that the output will not be interpreted as octal + math(EXPR ${def_name} ${${def_name}}) + zephyr_library_compile_definitions(${def_name}=${${def_name}}) + endif() +endmacro() + +macro(gen_build_time_str_definition def_name format) + if(CONFIG_BINDESC_${def_name}) + string(TIMESTAMP ${def_name} ${${format}}) + zephyr_library_compile_definitions(${def_name}="${${def_name}}") + endif() +endmacro() + +macro(gen_str_definition def_name value) + if(CONFIG_BINDESC_${def_name}) + zephyr_library_compile_definitions(${def_name}="${value}") + endif() +endmacro() + +if(CONFIG_BINDESC_DEFINE_BUILD_TIME) + zephyr_library_sources(bindesc_build_time.c) + gen_build_time_int_definition(BUILD_TIME_YEAR "%Y") + gen_build_time_int_definition(BUILD_TIME_MONTH "%m") + gen_build_time_int_definition(BUILD_TIME_DAY "%d") + gen_build_time_int_definition(BUILD_TIME_HOUR "%H") + gen_build_time_int_definition(BUILD_TIME_MINUTE "%M") + gen_build_time_int_definition(BUILD_TIME_SECOND "%S") + gen_build_time_int_definition(BUILD_TIME_UNIX "%s") + + gen_build_time_str_definition(BUILD_DATE_TIME_STRING + CONFIG_BINDESC_BUILD_DATE_TIME_STRING_FORMAT) + gen_build_time_str_definition(BUILD_DATE_STRING + CONFIG_BINDESC_BUILD_DATE_STRING_FORMAT) + gen_build_time_str_definition(BUILD_TIME_STRING + CONFIG_BINDESC_BUILD_TIME_STRING_FORMAT) + + if(CONFIG_BINDESC_BUILD_TIME_ALWAYS_REBUILD) + # By adding a custom target that invokes cmake, + # CMake is forced to rebuild this target on every build. This is + # done to ensure that the timestamp is always up to date. + add_custom_target( + bindesc_time_force_rebuild + COMMAND ${CMAKE_COMMAND} ${CMAKE_BINARY_DIR} + ) + add_dependencies(${ZEPHYR_CURRENT_LIBRARY} bindesc_time_force_rebuild) + endif() +endif() + +if(CONFIG_BINDESC_DEFINE_VERSION) + zephyr_library_sources(bindesc_version.c) + if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION) + zephyr_library_compile_definitions(HAS_APP_VERSION=1) + endif() +endif() + +if(CONFIG_BINDESC_DEFINE_HOST_INFO) + cmake_host_system_information(RESULT hostname QUERY HOSTNAME) + zephyr_library_sources(bindesc_host_info.c) + gen_str_definition(HOST_NAME ${hostname}) + gen_str_definition(C_COMPILER_NAME ${CMAKE_C_COMPILER_ID}) + gen_str_definition(C_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION}) + gen_str_definition(CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER_ID}) + gen_str_definition(CXX_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION}) +endif() diff --git a/subsys/bindesc/Kconfig b/subsys/bindesc/Kconfig new file mode 100644 index 00000000000..0f55564d460 --- /dev/null +++ b/subsys/bindesc/Kconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +menuconfig BINDESC + bool "Binary Descriptors" + depends on ARCH_SUPPORTS_ROM_START || BOARD_NATIVE_POSIX + help + Binary Descriptors - constant data accessible outside of the executable image + +if BINDESC + +config BINDESC_DEFINE + bool "Binary Descriptors Define" + help + Enable the app to define its own binary descriptors + +if BINDESC_DEFINE + +source "subsys/bindesc/Kconfig.version" +source "subsys/bindesc/Kconfig.build_time" +source "subsys/bindesc/Kconfig.host_info" + +endif # BINDESC_DEFINE + +endif # BINDESC diff --git a/subsys/bindesc/Kconfig.build_time b/subsys/bindesc/Kconfig.build_time new file mode 100644 index 00000000000..4c1a4c7c7de --- /dev/null +++ b/subsys/bindesc/Kconfig.build_time @@ -0,0 +1,106 @@ +# Copyright (c) 2023 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +menuconfig BINDESC_DEFINE_BUILD_TIME + bool "Build Time binary descriptors" + help + Add the build time binary descriptors + +if BINDESC_DEFINE_BUILD_TIME + +config BINDESC_BUILD_TIME_ALWAYS_REBUILD + bool "Always rebuild" + default y + help + If enabled, the file containing the build time definitions will + always be rebuilt. This results in the timestamp always being + accurate, but also in slightly longer build times. + +config BINDESC_BUILD_TIME_YEAR + bool "Year of build" + help + The year the image was compiled, such as 2023 + +config BINDESC_BUILD_TIME_MONTH + bool "Month of build" + help + The month the image was compiled, such as 5 (May) + +config BINDESC_BUILD_TIME_DAY + bool "Day of build" + help + The day of the month the image was compiled, such as 9 + +config BINDESC_BUILD_TIME_HOUR + bool "Hour of build" + help + The hour of the day the image was compiled, such as 13 in 13:34:52 + +config BINDESC_BUILD_TIME_MINUTE + bool "Minute of build" + help + The minute the image was compiled, such as 34 in 13:34:52 + +config BINDESC_BUILD_TIME_SECOND + bool "Second of build" + help + The second the image was compiled, such as 52 in 13:34:52 + +config BINDESC_BUILD_TIME_UNIX + bool "Build time as UNIX time" + help + The UNIX time at which the image was compiled. This is an integer + counting the seconds since midnight of January 1st 1970 + +config BINDESC_BUILD_DATE_TIME_STRING + bool "Build date and time as string" + help + The date and time of compilation as a string, such as "2023/02/05 00:07:04" + +config BINDESC_BUILD_DATE_STRING + bool "Build date as string" + help + The date of compilation as a string, such as "2023/02/05" + +config BINDESC_BUILD_TIME_STRING + bool "Build time as string" + help + The time of compilation as a string, such as "00:07:04" + +config BINDESC_BUILD_DATE_TIME_STRING_FORMAT + depends on BINDESC_BUILD_DATE_TIME_STRING + string "Date-Time format" + default "%Y/%m/%d %H:%M:%S" + help + Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...) + function, so refer to string's documentation for more info on the different formats. + This can also be used to set a specific time, when trying to reproduce an image. For + example, setting the format to "2023/02/05 00:07:04" will set it as the build time, + regardless of the actual build time. + Example of the default format: 2023/02/05 00:07:04 + +config BINDESC_BUILD_DATE_STRING_FORMAT + depends on BINDESC_BUILD_DATE_STRING + string "Date format" + default "%Y/%m/%d" + help + Format of the build date string. This value is passed to cmake's string(TIMESTAMP ...) + function, so refer to string's documentation for more info on the different formats. + This can also be used to set a specific time, when trying to reproduce an image. For + example, setting the format to "2023/02/05" will set it as the build time, + regardless of the actual build time. + Example of the default format: 2023/02/05 + +config BINDESC_BUILD_TIME_STRING_FORMAT + depends on BINDESC_BUILD_TIME_STRING + string "Time format" + default "%H:%M:%S" + help + Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...) + function, so refer to string's documentation for more info on the different formats. + This can also be used to set a specific time, when trying to reproduce an image. For + example, setting the format to "00:07:04" will set it as the build time, + regardless of the actual build time. + Example of the default format: 00:07:04 + +endif # BINDESC_DEFINE_BUILD_TIME diff --git a/subsys/bindesc/Kconfig.host_info b/subsys/bindesc/Kconfig.host_info new file mode 100644 index 00000000000..8c2c9d24bb4 --- /dev/null +++ b/subsys/bindesc/Kconfig.host_info @@ -0,0 +1,36 @@ +# Copyright (c) 2023 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +menuconfig BINDESC_DEFINE_HOST_INFO + bool "Host info binary descriptors" + help + Add the host info binary descriptors + +if BINDESC_DEFINE_HOST_INFO + +config BINDESC_HOST_NAME + bool "Host name" + help + The name of the host that the image was compiled on + +config BINDESC_C_COMPILER_NAME + bool "C compiler name" + help + The C compiler name, such as "GNU" + +config BINDESC_C_COMPILER_VERSION + bool "C compiler version" + help + The C compiler version, such as "12.3.0" + +config BINDESC_CXX_COMPILER_NAME + bool "C++ compiler name" + help + The C++ compiler name, such as "GNU" + +config BINDESC_CXX_COMPILER_VERSION + bool "C++ compiler version" + help + The C++ compiler version, such as "12.3.0" + +endif # BINDESC_DEFINE_HOST_INFO diff --git a/subsys/bindesc/Kconfig.version b/subsys/bindesc/Kconfig.version new file mode 100644 index 00000000000..ee7696e8064 --- /dev/null +++ b/subsys/bindesc/Kconfig.version @@ -0,0 +1,65 @@ +# Copyright (c) 2023 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +menuconfig BINDESC_DEFINE_VERSION + bool "Version binary descriptors" + help + Add the version binary descriptors + +if BINDESC_DEFINE_VERSION + +config BINDESC_KERNEL_VERSION_STRING + bool "Kernel version string" + help + The kernel version string, such as "3.4.0" + +config BINDESC_KERNEL_VERSION_MAJOR + bool "Kernel version major" + help + The major version number, such as 3 in 3.4.0 + +config BINDESC_KERNEL_VERSION_MINOR + bool "Kernel version minor" + help + The minor version number, such as 4 in 3.4.0 + +config BINDESC_KERNEL_VERSION_PATCHLEVEL + bool "Kernel version patchlevel" + help + The patchlevel version number, such as 0 in 3.4.0 + +config BINDESC_KERNEL_VERSION_NUMBER + bool "Kernel version number" + help + The kernel version as binary coded decimal, computed as + (major << 16 | minor << 8 | patchlevel). For example, + 3.4.0 would be represented as 0x30400 + +config BINDESC_APP_VERSION_STRING + bool "App version string" + help + The app version string, such as "1.0.0" + +config BINDESC_APP_VERSION_MAJOR + bool "App version major" + help + The app major version number, such as 1 in 1.0.0 + +config BINDESC_APP_VERSION_MINOR + bool "App version minor" + help + The app minor version number, such as 0 in 1.0.0 + +config BINDESC_APP_VERSION_PATCHLEVEL + bool "App version patchlevel" + help + The app patchlevel version number, such as 0 in 1.0.0 + +config BINDESC_APP_VERSION_NUMBER + bool "App version number" + help + The app version as binary coded decimal, computed as + (major << 16 | minor << 8 | patchlevel). For example, + 1.0.0 would be represented as 0x10000 + +endif # BINDESC_DEFINE_VERSION diff --git a/subsys/bindesc/bindesc.ld b/subsys/bindesc/bindesc.ld new file mode 100644 index 00000000000..e07222d5f10 --- /dev/null +++ b/subsys/bindesc/bindesc.ld @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +SQUAD(BINDESC_MAGIC); +Z_LINK_ITERABLE(bindesc_entry); +. = ALIGN(BINDESC_ALIGNMENT); +LONG(BINDESC_TAG_DESCRIPTORS_END) diff --git a/subsys/bindesc/bindesc_build_time.c b/subsys/bindesc/bindesc_build_time.c new file mode 100644 index 00000000000..c741ce0ffd8 --- /dev/null +++ b/subsys/bindesc/bindesc_build_time.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) +BINDESC_UINT_DEFINE(build_time_year, BINDESC_ID_BUILD_TIME_YEAR, BUILD_TIME_YEAR); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) +BINDESC_UINT_DEFINE(build_time_month, BINDESC_ID_BUILD_TIME_MONTH, BUILD_TIME_MONTH); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) +BINDESC_UINT_DEFINE(build_time_day, BINDESC_ID_BUILD_TIME_DAY, BUILD_TIME_DAY); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) +BINDESC_UINT_DEFINE(build_time_hour, BINDESC_ID_BUILD_TIME_HOUR, BUILD_TIME_HOUR); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) +BINDESC_UINT_DEFINE(build_time_minute, BINDESC_ID_BUILD_TIME_MINUTE, BUILD_TIME_MINUTE); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) +BINDESC_UINT_DEFINE(build_time_second, BINDESC_ID_BUILD_TIME_SECOND, BUILD_TIME_SECOND); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) +BINDESC_UINT_DEFINE(build_time_unix, BINDESC_ID_BUILD_TIME_UNIX, BUILD_TIME_UNIX); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) +BINDESC_STR_DEFINE(build_date_time_string, BINDESC_ID_BUILD_DATE_TIME_STRING, + BUILD_DATE_TIME_STRING); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) +BINDESC_STR_DEFINE(build_date_string, BINDESC_ID_BUILD_DATE_STRING, BUILD_DATE_STRING); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) +BINDESC_STR_DEFINE(build_time_string, BINDESC_ID_BUILD_TIME_STRING, BUILD_TIME_STRING); +#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */ diff --git a/subsys/bindesc/bindesc_host_info.c b/subsys/bindesc/bindesc_host_info.c new file mode 100644 index 00000000000..6ecc43495d4 --- /dev/null +++ b/subsys/bindesc/bindesc_host_info.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME) +BINDESC_STR_DEFINE(host_name, BINDESC_ID_HOST_NAME, HOST_NAME); +#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) +BINDESC_STR_DEFINE(c_compiler_name, BINDESC_ID_C_COMPILER_NAME, C_COMPILER_NAME); +#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) +BINDESC_STR_DEFINE(c_compiler_version, BINDESC_ID_C_COMPILER_VERSION, C_COMPILER_VERSION); +#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */ + +#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) +BINDESC_STR_DEFINE(cxx_compiler_name, BINDESC_ID_CXX_COMPILER_NAME, CXX_COMPILER_NAME); +#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */ + +#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) +BINDESC_STR_DEFINE(cxx_compiler_version, BINDESC_ID_CXX_COMPILER_VERSION, + CXX_COMPILER_VERSION); +#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ diff --git a/subsys/bindesc/bindesc_no_vt.ld b/subsys/bindesc/bindesc_no_vt.ld new file mode 100644 index 00000000000..4362fc721f0 --- /dev/null +++ b/subsys/bindesc/bindesc_no_vt.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +KEEP(*(.bindesc_skip)); +. = ALIGN(4); +#include "bindesc.ld" diff --git a/subsys/bindesc/bindesc_version.c b/subsys/bindesc/bindesc_version.c new file mode 100644 index 00000000000..d1c3a905aa0 --- /dev/null +++ b/subsys/bindesc/bindesc_version.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) +BINDESC_STR_DEFINE(kernel_version_string, BINDESC_ID_KERNEL_VERSION_STRING, + KERNEL_VERSION_STRING); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) +BINDESC_UINT_DEFINE(kernel_version_major, BINDESC_ID_KERNEL_VERSION_MAJOR, + KERNEL_VERSION_MAJOR); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) +BINDESC_UINT_DEFINE(kernel_version_minor, BINDESC_ID_KERNEL_VERSION_MINOR, + KERNEL_VERSION_MINOR); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) +BINDESC_UINT_DEFINE(kernel_version_patchlevel, BINDESC_ID_KERNEL_VERSION_PATCHLEVEL, + KERNEL_PATCHLEVEL); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ + +#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) +BINDESC_UINT_DEFINE(kernel_version_number, BINDESC_ID_KERNEL_VERSION_NUMBER, + KERNEL_VERSION_NUMBER); +#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ + +#if IS_ENABLED(HAS_APP_VERSION) +#include + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) +BINDESC_STR_DEFINE(app_version_string, BINDESC_ID_APP_VERSION_STRING, + APP_VERSION_STRING); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) +BINDESC_UINT_DEFINE(app_version_major, BINDESC_ID_APP_VERSION_MAJOR, + APP_VERSION_MAJOR); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) +BINDESC_UINT_DEFINE(app_version_minor, BINDESC_ID_APP_VERSION_MINOR, + APP_VERSION_MINOR); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) +BINDESC_UINT_DEFINE(app_version_patchlevel, BINDESC_ID_APP_VERSION_PATCHLEVEL, + APP_PATCHLEVEL); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ + +#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) +BINDESC_UINT_DEFINE(app_version_number, BINDESC_ID_APP_VERSION_NUMBER, + APP_VERSION_NUMBER); +#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */ + +#endif /* IS_ENABLED(HAS_APP_VERSION) */ diff --git a/subsys/bindesc/x86/bindesc_skip.S b/subsys/bindesc/x86/bindesc_skip.S new file mode 100644 index 00000000000..c0a1982f37b --- /dev/null +++ b/subsys/bindesc/x86/bindesc_skip.S @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +.section .bindesc_skip +_bindesc_skip: + jmp __start From c42a7dff4d04e55566fa9f523da0a90ebecdd92f Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Fri, 24 Mar 2023 14:37:24 +0300 Subject: [PATCH 1283/4498] west: commands: Add bindesc command Added the bindesc command to west, for working with binary descriptors. Currently it supports dump, list and search subcommands, for bin, hex, elf and uf2 file types. Signed-off-by: Yonatan Schachter --- scripts/west-commands.yml | 5 + scripts/west_commands/bindesc.py | 316 +++++++++++++++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 scripts/west_commands/bindesc.py diff --git a/scripts/west-commands.yml b/scripts/west-commands.yml index 5f63b44225c..803d2b7b2d1 100644 --- a/scripts/west-commands.yml +++ b/scripts/west-commands.yml @@ -56,3 +56,8 @@ west-commands: - name: blobs class: Blobs help: work with binary blobs + - file: scripts/west_commands/bindesc.py + commands: + - name: bindesc + class: Bindesc + help: work with Binary Descriptors diff --git a/scripts/west_commands/bindesc.py b/scripts/west_commands/bindesc.py new file mode 100644 index 00000000000..a4bc852bfab --- /dev/null +++ b/scripts/west_commands/bindesc.py @@ -0,0 +1,316 @@ +# Copyright (c) 2023 Yonatan Schachter +# +# SPDX-License-Identifier: Apache-2.0 + +from textwrap import dedent +import struct + +from west.commands import WestCommand +from west import log + + +try: + from elftools.elf.elffile import ELFFile + from intelhex import IntelHex + MISSING_REQUIREMENTS = False +except ImportError: + MISSING_REQUIREMENTS = True + + +# Based on scripts/build/uf2conv.py +def convert_from_uf2(buf): + UF2_MAGIC_START0 = 0x0A324655 # First magic number ('UF2\n') + UF2_MAGIC_START1 = 0x9E5D5157 # Second magic number + numblocks = len(buf) // 512 + curraddr = None + outp = [] + for blockno in range(numblocks): + ptr = blockno * 512 + block = buf[ptr:ptr + 512] + hd = struct.unpack(b' 476: + log.die(f'Invalid UF2 data size at {ptr}') + newaddr = hd[3] + if curraddr is None: + curraddr = newaddr + padding = newaddr - curraddr + if padding < 0: + log.die(f'Block out of order at {ptr}') + if padding > 10*1024*1024: + log.die(f'More than 10M of padding needed at {ptr}') + if padding % 4 != 0: + log.die(f'Non-word padding size at {ptr}') + while padding > 0: + padding -= 4 + outp += b'\x00\x00\x00\x00' + outp.append(block[32 : 32 + datalen]) + curraddr = newaddr + datalen + return b''.join(outp) + + +class Bindesc(WestCommand): + EXTENSIONS = ['bin', 'hex', 'elf', 'uf2'] + + # Corresponds to the definitions in include/zephyr/bindesc.h. + # Do not change without syncing the definitions in both files! + TYPE_UINT = 0 + TYPE_STR = 1 + TYPE_BYTES = 2 + MAGIC = 0xb9863e5a7ea46046 + DESCRIPTORS_END = 0xffff + + def __init__(self): + self.TAG_TO_NAME = { + # Corresponds to the definitions in include/zephyr/bindesc.h. + # Do not change without syncing the definitions in both files! + self.bindesc_gen_tag(self.TYPE_STR, 0x800): 'APP_VERSION_STRING', + self.bindesc_gen_tag(self.TYPE_UINT, 0x801): 'APP_VERSION_MAJOR', + self.bindesc_gen_tag(self.TYPE_UINT, 0x802): 'APP_VERSION_MINOR', + self.bindesc_gen_tag(self.TYPE_UINT, 0x803): 'APP_VERSION_PATCHLEVEL', + self.bindesc_gen_tag(self.TYPE_UINT, 0x804): 'APP_VERSION_NUMBER', + self.bindesc_gen_tag(self.TYPE_STR, 0x900): 'KERNEL_VERSION_STRING', + self.bindesc_gen_tag(self.TYPE_UINT, 0x901): 'KERNEL_VERSION_MAJOR', + self.bindesc_gen_tag(self.TYPE_UINT, 0x902): 'KERNEL_VERSION_MINOR', + self.bindesc_gen_tag(self.TYPE_UINT, 0x903): 'KERNEL_VERSION_PATCHLEVEL', + self.bindesc_gen_tag(self.TYPE_UINT, 0x904): 'KERNEL_VERSION_NUMBER', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa00): 'BUILD_TIME_YEAR', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa01): 'BUILD_TIME_MONTH', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa02): 'BUILD_TIME_DAY', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa03): 'BUILD_TIME_HOUR', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa04): 'BUILD_TIME_MINUTE', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa05): 'BUILD_TIME_SECOND', + self.bindesc_gen_tag(self.TYPE_UINT, 0xa06): 'BUILD_TIME_UNIX', + self.bindesc_gen_tag(self.TYPE_STR, 0xa07): 'BUILD_DATE_TIME_STRING', + self.bindesc_gen_tag(self.TYPE_STR, 0xa08): 'BUILD_DATE_STRING', + self.bindesc_gen_tag(self.TYPE_STR, 0xa09): 'BUILD_TIME_STRING', + self.bindesc_gen_tag(self.TYPE_STR, 0xb00): 'HOST_NAME', + self.bindesc_gen_tag(self.TYPE_STR, 0xb01): 'C_COMPILER_NAME', + self.bindesc_gen_tag(self.TYPE_STR, 0xb02): 'C_COMPILER_VERSION', + self.bindesc_gen_tag(self.TYPE_STR, 0xb03): 'CXX_COMPILER_NAME', + self.bindesc_gen_tag(self.TYPE_STR, 0xb04): 'CXX_COMPILER_VERSION', + } + self.NAME_TO_TAG = {v: k for k, v in self.TAG_TO_NAME.items()} + + super().__init__( + 'bindesc', + 'work with Binary Descriptors', + dedent(''' + Work with Binary Descriptors - constant data objects + describing a binary image + ''')) + + def do_add_parser(self, parser_adder): + parser = parser_adder.add_parser(self.name, + help=self.help, + description=self.description) + + subparsers = parser.add_subparsers(help='sub-command to run') + + dump_parser = subparsers.add_parser('dump', help='Dump all binary descriptors in the image') + dump_parser.add_argument('file', type=str, help='Executable file') + dump_parser.add_argument('--file-type', type=str, choices=self.EXTENSIONS, help='File type') + dump_parser.add_argument('-b', '--big-endian', action='store_true', + help='Target CPU is big endian') + dump_parser.set_defaults(subcmd='dump', big_endian=False) + + search_parser = subparsers.add_parser('search', help='Search for a specific descriptor') + search_parser.add_argument('descriptor', type=str, help='Descriptor name') + search_parser.add_argument('file', type=str, help='Executable file') + search_parser.add_argument('--file-type', type=str, choices=self.EXTENSIONS, help='File type') + search_parser.add_argument('-b', '--big-endian', action='store_true', + help='Target CPU is big endian') + search_parser.set_defaults(subcmd='search', big_endian=False) + + custom_search_parser = subparsers.add_parser('custom_search', + help='Search for a custom descriptor') + custom_search_parser.add_argument('type', type=str, choices=['UINT', 'STR', 'BYTES'], + help='Descriptor type') + custom_search_parser.add_argument('id', type=str, help='Descriptor ID in hex') + custom_search_parser.add_argument('file', type=str, help='Executable file') + custom_search_parser.add_argument('--file-type', type=str, choices=self.EXTENSIONS, + help='File type') + custom_search_parser.add_argument('-b', '--big-endian', action='store_true', + help='Target CPU is big endian') + custom_search_parser.set_defaults(subcmd='custom_search', big_endian=False) + + list_parser = subparsers.add_parser('list', help='List all known descriptors') + list_parser.set_defaults(subcmd='list', big_endian=False) + + return parser + + def dump(self, args): + image = self.get_image_data(args.file) + + descriptors = self.parse_descriptors(image) + for tag, value in descriptors.items(): + if tag in self.TAG_TO_NAME: + tag = self.TAG_TO_NAME[tag] + log.inf(f'{tag}', self.bindesc_repr(value)) + + def list(self, args): + for tag in self.TAG_TO_NAME.values(): + log.inf(f'{tag}') + + def common_search(self, args, search_term): + image = self.get_image_data(args.file) + + descriptors = self.parse_descriptors(image) + + if search_term in descriptors: + value = descriptors[search_term] + log.inf(self.bindesc_repr(value)) + else: + log.die('Descriptor not found') + + def search(self, args): + try: + search_term = self.NAME_TO_TAG[args.descriptor] + except KeyError: + log.die(f'Descriptor {args.descriptor} is invalid') + + self.common_search(args, search_term) + + def custom_search(self, args): + custom_type = { + 'STR': self.TYPE_STR, + 'UINT': self.TYPE_UINT, + 'BYTES': self.TYPE_BYTES + }[args.type] + custom_tag = self.bindesc_gen_tag(custom_type, int(args.id, 16)) + self.common_search(args, custom_tag) + + def do_run(self, args, _): + if MISSING_REQUIREMENTS: + raise RuntimeError('one or more Python dependencies were missing; ' + 'see the getting started guide for details on ' + 'how to fix') + self.is_big_endian = args.big_endian + self.file_type = self.guess_file_type(args) + subcmd = getattr(self, args.subcmd) + subcmd(args) + + def get_image_data(self, file_name): + if self.file_type == 'bin': + with open(file_name, 'rb') as bin_file: + return bin_file.read() + + if self.file_type == 'hex': + return IntelHex(file_name).tobinstr() + + if self.file_type == 'uf2': + with open(file_name, 'rb') as uf2_file: + return convert_from_uf2(uf2_file.read()) + + if self.file_type == 'elf': + with open(file_name, 'rb') as f: + elffile = ELFFile(f) + + section = elffile.get_section_by_name('rom_start') + if section: + return section.data() + + section = elffile.get_section_by_name('text') + if section: + return section.data() + + log.die('No "rom_start" or "text" section found') + + log.die('Unknown file type') + + def parse_descriptors(self, image): + magic = struct.pack('>Q' if self.is_big_endian else 'Q', self.MAGIC) + index = image.find(magic) + if index == -1: + log.die('Could not find binary descriptor magic') + + descriptors = {} + + index += len(magic) # index points to first descriptor + current_tag = self.bytes_to_short(image[index:index+2]) + while current_tag != self.DESCRIPTORS_END: + index += 2 # index points to length + length = self.bytes_to_short(image[index:index+2]) + index += 2 # index points to data + data = image[index:index+length] + + tag_type = self.bindesc_get_type(current_tag) + if tag_type == self.TYPE_STR: + decoded_data = data[:-1].decode('ascii') + elif tag_type == self.TYPE_UINT: + decoded_data = self.bytes_to_uint(data) + elif tag_type == self.TYPE_BYTES: + decoded_data = data + else: + log.die(f'Unknown type for tag 0x{current_tag:04x}') + + key = f'0x{current_tag:04x}' + descriptors[key] = decoded_data + index += length + index = self.align(index, 4) + current_tag = self.bytes_to_short(image[index:index+2]) + + return descriptors + + def guess_file_type(self, args): + if "file" not in args: + return None + + # If file type is explicitly given, use it + if args.file_type is not None: + return args.file_type + + # If the file has a known extension, use it + for extension in self.EXTENSIONS: + if args.file.endswith(f'.{extension}'): + return extension + + with open(args.file, 'rb') as f: + header = f.read(1024) + + # Try the elf magic + if header.startswith(b'\x7fELF'): + return 'elf' + + # Try the uf2 magic + if header.startswith(b'UF2\n'): + return 'uf2' + + try: + # if the file is textual it's probably hex + header.decode('ascii') + return 'hex' + except UnicodeDecodeError: + # Default to bin + return 'bin' + + def bytes_to_uint(self, b): + return struct.unpack('>I' if self.is_big_endian else 'I', b)[0] + + def bytes_to_short(self, b): + return struct.unpack('>H' if self.is_big_endian else 'H', b)[0] + + @staticmethod + def bindesc_gen_tag(_type, _id): + return f'0x{(_type << 12 | _id):04x}' + + @staticmethod + def bindesc_get_type(tag): + return tag >> 12 + + @staticmethod + def align(x, alignment): + return (x + alignment - 1) & (~(alignment - 1)) + + @staticmethod + def bindesc_repr(value): + if isinstance(value, str): + return f'"{value}"' + if isinstance(value, (int, bytes)): + return f'{value}' From fd5fe8fe10bb2e1f2e0494d5074185041e631219 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Fri, 24 Mar 2023 16:16:13 +0300 Subject: [PATCH 1284/4498] samples: bindesc: Add hello_bindesc sample Add the hello_bindesc sample which shows the basic usage of binary descriptors. Signed-off-by: Yonatan Schachter --- samples/subsys/bindesc/bindesc.rst | 10 ++++++ .../bindesc/hello_bindesc/CMakeLists.txt | 8 +++++ .../subsys/bindesc/hello_bindesc/README.rst | 26 ++++++++++++++ samples/subsys/bindesc/hello_bindesc/VERSION | 5 +++ samples/subsys/bindesc/hello_bindesc/prj.conf | 21 +++++++++++ .../subsys/bindesc/hello_bindesc/sample.yaml | 9 +++++ .../subsys/bindesc/hello_bindesc/src/main.c | 35 +++++++++++++++++++ 7 files changed, 114 insertions(+) create mode 100644 samples/subsys/bindesc/bindesc.rst create mode 100644 samples/subsys/bindesc/hello_bindesc/CMakeLists.txt create mode 100644 samples/subsys/bindesc/hello_bindesc/README.rst create mode 100644 samples/subsys/bindesc/hello_bindesc/VERSION create mode 100644 samples/subsys/bindesc/hello_bindesc/prj.conf create mode 100644 samples/subsys/bindesc/hello_bindesc/sample.yaml create mode 100644 samples/subsys/bindesc/hello_bindesc/src/main.c diff --git a/samples/subsys/bindesc/bindesc.rst b/samples/subsys/bindesc/bindesc.rst new file mode 100644 index 00000000000..105d6f80dc8 --- /dev/null +++ b/samples/subsys/bindesc/bindesc.rst @@ -0,0 +1,10 @@ +.. _bindesc_samples: + +Binary Descriptor Samples +######################### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/samples/subsys/bindesc/hello_bindesc/CMakeLists.txt b/samples/subsys/bindesc/hello_bindesc/CMakeLists.txt new file mode 100644 index 00000000000..3e70363ba31 --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(hello_bindesc) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/subsys/bindesc/hello_bindesc/README.rst b/samples/subsys/bindesc/hello_bindesc/README.rst new file mode 100644 index 00000000000..e72f6934608 --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/README.rst @@ -0,0 +1,26 @@ +.. _hello_bindesc-sample: + +hello_bindesc Sample Application +################################ + +Overview +******** + +A simple sample of binary descriptor definition and usage. + +Building and Running +******************** + +Follow these steps to build the `hello_bindesc` sample application: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/bindesc/hello_bindesc + :board: + :goals: build + :compact: + +To see all binary descriptors, run: + +.. code-block:: bash + + west bindesc dump build/zephyr/zephyr.bin diff --git a/samples/subsys/bindesc/hello_bindesc/VERSION b/samples/subsys/bindesc/hello_bindesc/VERSION new file mode 100644 index 00000000000..16a13732e3a --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/VERSION @@ -0,0 +1,5 @@ +VERSION_MAJOR = 1 +VERSION_MINOR = 0 +PATCHLEVEL = 0 +VERSION_TWEAK = 0 +EXTRAVERSION = diff --git a/samples/subsys/bindesc/hello_bindesc/prj.conf b/samples/subsys/bindesc/hello_bindesc/prj.conf new file mode 100644 index 00000000000..0b22906d9f5 --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/prj.conf @@ -0,0 +1,21 @@ +# Enable binary descriptors +CONFIG_BINDESC=y + +# Enable definition of binary descriptors +CONFIG_BINDESC_DEFINE=y + +# Enable default build time binary descriptors +CONFIG_BINDESC_DEFINE_BUILD_TIME=y +CONFIG_BINDESC_BUILD_DATE_TIME_STRING=y + +# Enable default version binary descriptors +CONFIG_BINDESC_DEFINE_VERSION=y +CONFIG_BINDESC_KERNEL_VERSION_STRING=y +CONFIG_BINDESC_KERNEL_VERSION_MAJOR=y + +CONFIG_BINDESC_APP_VERSION_STRING=y + +# Enable default host info binary descriptors +CONFIG_BINDESC_DEFINE_HOST_INFO=y +CONFIG_BINDESC_C_COMPILER_NAME=y +CONFIG_BINDESC_C_COMPILER_VERSION=y diff --git a/samples/subsys/bindesc/hello_bindesc/sample.yaml b/samples/subsys/bindesc/hello_bindesc/sample.yaml new file mode 100644 index 00000000000..e923744c3d8 --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: Hello Bindesc +tests: + sample.bindesc: + tags: bindesc + filter: CONFIG_ARCH_SUPPORTS_ROM_START + build_only: true + integration_platforms: + - native_posix diff --git a/samples/subsys/bindesc/hello_bindesc/src/main.c b/samples/subsys/bindesc/hello_bindesc/src/main.c new file mode 100644 index 00000000000..22837247d8d --- /dev/null +++ b/samples/subsys/bindesc/hello_bindesc/src/main.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +BINDESC_STR_DEFINE(my_string, 1, "Hello world!"); +BINDESC_UINT_DEFINE(my_int, 2, 5); +BINDESC_BYTES_DEFINE(my_bytes, 3, ({1, 2, 3, 4})); + +int main(void) +{ + size_t i; + + /* Builtin descriptors */ + printk("Zephyr version: %s\n", BINDESC_GET_STR(kernel_version_string)); + printk("App version: %s\n", BINDESC_GET_STR(app_version_string)); + printk("Build time: %s\n", BINDESC_GET_STR(build_date_time_string)); + printk("Compiler: %s %s\n", BINDESC_GET_STR(c_compiler_name), + BINDESC_GET_STR(c_compiler_version)); + + /* Custom descriptors */ + printk("my_string: %s\n", BINDESC_GET_STR(my_string)); + printk("my_int: %d\n", BINDESC_GET_UINT(my_int)); + printk("my_bytes: "); + for (i = 0; i < BINDESC_GET_SIZE(my_bytes); i++) { + printk("%02x ", BINDESC_GET_BYTES(my_bytes)[i]); + } + printk("\n"); + + return 0; +} From 726e14e475c67fd08460d94ab25998ca75a873cb Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sat, 25 Mar 2023 22:52:41 +0300 Subject: [PATCH 1285/4498] doc: bindesc: Add documentation for binary descriptors Add documentation for binary descriptors under "OS Services" Signed-off-by: Yonatan Schachter --- doc/develop/west/zephyr-cmds.rst | 25 +++++ doc/services/binary_descriptors/index.rst | 125 ++++++++++++++++++++++ doc/services/index.rst | 1 + scripts/ci/check_compliance.py | 1 + 4 files changed, 152 insertions(+) create mode 100644 doc/services/binary_descriptors/index.rst diff --git a/doc/develop/west/zephyr-cmds.rst b/doc/develop/west/zephyr-cmds.rst index d1d96d07ceb..056d22e48eb 100644 --- a/doc/develop/west/zephyr-cmds.rst +++ b/doc/develop/west/zephyr-cmds.rst @@ -185,3 +185,28 @@ Twister can then be invoked via west as follows:: west twister -help west twister -T tests/ztest/base + +.. _west-bindesc: + +Working with binary descriptors: ``west bindesc`` +************************************************* + +The ``bindesc`` command allows users to read :ref:`binary descriptors` +of executable files. It currently supports ``.bin``, ``.hex``, ``.elf`` and ``.uf2`` files +as input. + +You can search for a specific descriptor in an image, for example:: + + west bindesc search KERNEL_VERSION_STRING build/zephyr/zephyr.bin + +You can search for a custom descriptor by type and ID, for example:: + + west bindesc custom_search STR 0x200 build/zephyr/zephyr.bin + +You can dump all of the descriptors in an image using:: + + west bindesc dump build/zephyr/zephyr.bin + +You can list all known standard descriptor names using:: + + west bindesc list diff --git a/doc/services/binary_descriptors/index.rst b/doc/services/binary_descriptors/index.rst new file mode 100644 index 00000000000..ef44b8265af --- /dev/null +++ b/doc/services/binary_descriptors/index.rst @@ -0,0 +1,125 @@ +.. _binary_descriptors: + +Binary Descriptors +################## + +Binary Descriptors are constant data objects storing information about the binary executable. +Unlike "regular" constants, binary descriptors are linked to a known offset in the binary, making +them accesible to other programs, such as a different image running on the same device or a host tool. +A few examples of constants that would make useful binary descriptors are: kernel version, app version, +build time, compiler version, environment variables, compiling host name, etc. + +Binary descriptors are created by using the ``DEFINE_BINDESC_*`` macros. For example: + +.. code-block:: c + + #include + + BINDESC_STR_DEFINE(my_string, 2, "Hello world!"); // Unique ID is 2 + +``my_string`` could then be accessed using: + +.. code-block:: c + + printk("my_string: %s\n", BINDESC_GET_STR(my_string)); + +But it could also be retrieved by ``west bindesc``: + +.. code-block:: bash + + $ west bindesc custom_search STR 2 build/zephyr/zephyr.bin + "Hello world!" + +Internals +********* +Binary descriptors are implemented with a TLV (tag, length, value) header linked +to a known offset in the binary image. This offset may vary between architectures, +but generally the descriptors are linked as close to the beginning of the image as +possible. In architectures where the image must begin with a vector table (such as +ARM), the descriptors are linked right after the vector table. The reset vector points +to the beginning of the text section, which is after the descriptors. In architectures +where the image must begin with executable code (e.g. x86), a jump instruction is injected at +the beginning of the image, in order to skip over the binary descriptors, which are right +after the jump instruction. + +Each tag is a 16 bit unsigned integer, where the most significant nibble (4 bits) is the type +(currently uint, string or bytes), and the rest is the ID. The ID is globally unique to each +descriptor. For example, the ID of the app version string is ``0x800``, and a string +is denoted by 0x1, making the app version tag ``0x1800``. The length is a 16 bit +number equal to the length of the data in bytes. The data is the actual descriptor +value. All binary descriptor numbers (magic, tags, uints) are laid out in memory +in the endianness native to the SoC. ``west bindesc`` assumes little endian by default, +so if the image belongs to a big endian SoC, the appropriate flag should be given to the +tool. + +The binary descriptor header starts with the magic number ``0xb9863e5a7ea46046``. It's followed +by the TLVs, and ends with the ``DESCRIPTORS_END`` (``0xffff``) tag. The tags are +always aligned to 32 bits. If the value of the previous descriptor had a non-aligned +length, zero padding will be added to ensure that the current tag is aligned. + +Putting it all together, here is what the example above would look like in memory +(of a little endian SoC): + +.. code-block:: + + 46 60 a4 7e 5a 3e 86 b9 02 10 0d 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 00 00 00 ff ff + | magic | tag |length| H e l l o w o r l d ! | pad | end | + +Usage +***** +Binary descriptors are always created by the ``BINDESC_*_DEFINE`` macros. As shown in +the example above, a descriptor can be generated from any string or integer, with any +ID. However, it is recommended to comply with the standard tags defined in +``include/zephyr/bindesc.h``, as that would have the following benefits: + + 1. The ``west bindesc`` tool would be able to recognize what the descriptor means and + print a meaningful tag + 2. It would enforce consistency between various apps from various sources + 3. It allows upstream-ability of descriptor generation (see Standard Descriptors) + +To define a descriptor with a standard tag, just use the tags included from ``bindesc.h``: + +.. code-block:: c + + #include + + BINDESC_STR_DEFINE(app_version, BINDESC_ID_APP_VERSION_STRING, "1.2.3"); + +Standard Descriptors +==================== +Some descriptors might be trivial to implement, and could therefore be implemented +in a standard way in upstream Zephyr. These could then be enabled via Kconfig, instead +of requiring every user to reimplement them. These include build times, kernel version, +and host info. For example, to add the build date and time as a string, the following +configs should be enabled: + +.. code-block:: kconfig + + # Enable binary descriptors + CONFIG_BINDESC=y + + # Enable definition of binary descriptors + CONFIG_BINDESC_DEFINE=y + + # Enable default build time binary descriptors + CONFIG_BINDESC_DEFINE_BUILD_TIME=y + CONFIG_BINDESC_BUILD_DATE_TIME_STRING=y + +To avoid collisions with user defined descriptors, the standard descriptors were alloted +the range between ``0x800-0xfff``. This leaves ``0x000-0x7ff`` to users. +For more information read the ``help`` sections of these Kconfig symbols. +By convention, each Kconfig symbol corresponds to a binary descriptor whose +name is the Kconfig name (with ``CONFIG_BINDESC_`` removed) in lower case. For example, +``CONFIG_BINDESC_KERNEL_VERSION_STRING`` creates a descriptor that can be +accessed using ``BINDESC_GET_STR(kernel_version_string)``. + +west bindesc tool +================= +``west`` is able to parse and display binary descriptors from a given executable image. + +For more information refer to ``west bindesc --help`` or the :ref:`documentation`. + +API Reference +************* + +.. doxygengroup:: bindesc_define diff --git a/doc/services/index.rst b/doc/services/index.rst index 990f0cfea49..286d2d2c14b 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -7,6 +7,7 @@ OS Services :maxdepth: 1 + binary_descriptors/index.rst crypto/index debugging/index.rst device_mgmt/index diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 713fe21cbff..22406b6734a 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -617,6 +617,7 @@ def check_no_undef_outside_kconfig(self, kconf): # visible to compliance. "BOOT_ENCRYPTION_KEY_FILE", # Used in sysbuild "BOOT_ENCRYPT_IMAGE", # Used in sysbuild + "BINDESC_", # Used in documentation as a prefix "BOOT_UPGRADE_ONLY", # Used in example adjusting MCUboot config, but # symbol is defined in MCUboot itself. "BOOT_SERIAL_BOOT_MODE", # Used in (sysbuild-based) test/ From 859be8cb730b6aff0142fb4add2a8e3959495421 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sun, 9 Apr 2023 17:15:52 +0300 Subject: [PATCH 1286/4498] tests: bindesc: Added definition tests Added tests for the bindesc subsystem, testing definition of binary descriptors on several qemu architectures, and using several C standards (c99, c11, etc.). Signed-off-by: Yonatan Schachter --- .../subsys/bindesc/definition/CMakeLists.txt | 10 ++++ tests/subsys/bindesc/definition/prj.conf | 12 +++++ tests/subsys/bindesc/definition/src/main.c | 49 +++++++++++++++++++ tests/subsys/bindesc/definition/testcase.yaml | 31 ++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 tests/subsys/bindesc/definition/CMakeLists.txt create mode 100644 tests/subsys/bindesc/definition/prj.conf create mode 100644 tests/subsys/bindesc/definition/src/main.c create mode 100644 tests/subsys/bindesc/definition/testcase.yaml diff --git a/tests/subsys/bindesc/definition/CMakeLists.txt b/tests/subsys/bindesc/definition/CMakeLists.txt new file mode 100644 index 00000000000..4a1a0136fed --- /dev/null +++ b/tests/subsys/bindesc/definition/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2023 Yonatan Schachter +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bindesc) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/bindesc/definition/prj.conf b/tests/subsys/bindesc/definition/prj.conf new file mode 100644 index 00000000000..d264ff631de --- /dev/null +++ b/tests/subsys/bindesc/definition/prj.conf @@ -0,0 +1,12 @@ +# Copyright 2023 Yonatan Schachter +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_BINDESC=y +CONFIG_BINDESC_DEFINE=y + +CONFIG_BINDESC_DEFINE_VERSION=y +CONFIG_BINDESC_KERNEL_VERSION_NUMBER=y diff --git a/tests/subsys/bindesc/definition/src/main.c b/tests/subsys/bindesc/definition/src/main.c new file mode 100644 index 00000000000..487fa186790 --- /dev/null +++ b/tests/subsys/bindesc/definition/src/main.c @@ -0,0 +1,49 @@ +/* + * Copyright 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define STR_ID 1 +#define UINT_ID 2 +#define BYTES_ID 3 + +#define STR_DATA "Hello world!" +#define UINT_DATA 5 +#define BYTES_DATA {1, 2, 3, 4} + +BINDESC_STR_DEFINE(bindesc_string, STR_ID, STR_DATA); +BINDESC_UINT_DEFINE(bindesc_uint, UINT_ID, UINT_DATA); +BINDESC_BYTES_DEFINE(bindesc_bytes, BYTES_ID, (BYTES_DATA)); + +ZTEST(bindesc_define, test_version_number) +{ + zassert_equal(BINDESC_GET_UINT(kernel_version_number), KERNEL_VERSION_NUMBER, + "bindesc kernel version number is incorrect"); +} + +ZTEST(bindesc_define, test_custom_bindesc_str) +{ + zassert_equal(BINDESC_GET_SIZE(bindesc_string), sizeof(STR_DATA)); + zassert_mem_equal(BINDESC_GET_STR(bindesc_string), STR_DATA, sizeof(STR_DATA)); +} + +ZTEST(bindesc_define, test_custom_bindesc_uint) +{ + zassert_equal(BINDESC_GET_SIZE(bindesc_uint), 4); + zassert_equal(BINDESC_GET_UINT(bindesc_uint), UINT_DATA); +} + +ZTEST(bindesc_define, test_custom_bindesc_bytes) +{ + uint8_t expected_data[] = BYTES_DATA; + + zassert_equal(BINDESC_GET_SIZE(bindesc_bytes), 4); + zassert_mem_equal(BINDESC_GET_STR(bindesc_bytes), expected_data, 4); +} + +ZTEST_SUITE(bindesc_define, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/bindesc/definition/testcase.yaml b/tests/subsys/bindesc/definition/testcase.yaml new file mode 100644 index 00000000000..72ede27a059 --- /dev/null +++ b/tests/subsys/bindesc/definition/testcase.yaml @@ -0,0 +1,31 @@ +tests: + bindesc.define: + tags: bindesc + platform_allow: > + native_posix qemu_x86 qemu_cortex_m0 qemu_cortex_m3 + qemu_cortex_r5 qemu_arc_em qemu_arc_hs qemu_arc_hs5x + qemu_arc_hs6x qemu_riscv32 qemu_riscv32e qemu_riscv64 + bindesc.define.c99: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="c99" + bindesc.define.c11: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="c11" + bindesc.define.c17: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="c17" + bindesc.define.gnu99: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="gnu99" + bindesc.define.gnu11: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="gnu11" + bindesc.define.gnu17: + platform_allow: native_posix + tags: bindesc + extra_args: CSTD="gnu17" From c4f102fd8b68c48a7fbfd32a27630578a2e1f4b2 Mon Sep 17 00:00:00 2001 From: honglin leng Date: Thu, 28 Sep 2023 14:46:18 +0800 Subject: [PATCH 1287/4498] boards: arm64: add support for Raspberry Pi 4 Model B This is an AArch64 board. We also add BCM2711 SoC support Signed-off-by: honglin leng --- boards/arm64/rpi_4b/CMakeLists.txt | 1 + boards/arm64/rpi_4b/Kconfig.board | 6 + boards/arm64/rpi_4b/Kconfig.defconfig | 6 + boards/arm64/rpi_4b/board.cmake | 1 + boards/arm64/rpi_4b/doc/index.rst | 46 +++ boards/arm64/rpi_4b/rpi_4b.dts | 26 ++ boards/arm64/rpi_4b/rpi_4b.yaml | 7 + boards/arm64/rpi_4b/rpi_4b_defconfig | 23 ++ drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 2 + drivers/serial/Kconfig.bcm2711 | 11 + drivers/serial/uart_bcm2711.c | 329 ++++++++++++++++++ dts/arm64/broadcom/bcm2711.dtsi | 61 ++++ .../serial/brcm,bcm2711-aux-uart.yaml | 15 + soc/arm64/bcm2711/CMakeLists.txt | 2 + soc/arm64/bcm2711/Kconfig.defconfig | 17 + soc/arm64/bcm2711/Kconfig.soc | 8 + soc/arm64/bcm2711/linker.ld | 6 + soc/arm64/bcm2711/linker_a72.ld | 7 + soc/arm64/bcm2711/mmu_regions.c | 25 ++ 20 files changed, 600 insertions(+) create mode 100644 boards/arm64/rpi_4b/CMakeLists.txt create mode 100644 boards/arm64/rpi_4b/Kconfig.board create mode 100644 boards/arm64/rpi_4b/Kconfig.defconfig create mode 100644 boards/arm64/rpi_4b/board.cmake create mode 100644 boards/arm64/rpi_4b/doc/index.rst create mode 100644 boards/arm64/rpi_4b/rpi_4b.dts create mode 100644 boards/arm64/rpi_4b/rpi_4b.yaml create mode 100644 boards/arm64/rpi_4b/rpi_4b_defconfig create mode 100644 drivers/serial/Kconfig.bcm2711 create mode 100644 drivers/serial/uart_bcm2711.c create mode 100644 dts/arm64/broadcom/bcm2711.dtsi create mode 100644 dts/bindings/serial/brcm,bcm2711-aux-uart.yaml create mode 100644 soc/arm64/bcm2711/CMakeLists.txt create mode 100644 soc/arm64/bcm2711/Kconfig.defconfig create mode 100644 soc/arm64/bcm2711/Kconfig.soc create mode 100644 soc/arm64/bcm2711/linker.ld create mode 100644 soc/arm64/bcm2711/linker_a72.ld create mode 100644 soc/arm64/bcm2711/mmu_regions.c diff --git a/boards/arm64/rpi_4b/CMakeLists.txt b/boards/arm64/rpi_4b/CMakeLists.txt new file mode 100644 index 00000000000..9881313609a --- /dev/null +++ b/boards/arm64/rpi_4b/CMakeLists.txt @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/rpi_4b/Kconfig.board b/boards/arm64/rpi_4b/Kconfig.board new file mode 100644 index 00000000000..9b0e9c80985 --- /dev/null +++ b/boards/arm64/rpi_4b/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright 2023 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RPI_4B + bool "Broadcom BCM2711" + depends on SOC_BCM2711 diff --git a/boards/arm64/rpi_4b/Kconfig.defconfig b/boards/arm64/rpi_4b/Kconfig.defconfig new file mode 100644 index 00000000000..c04170c5751 --- /dev/null +++ b/boards/arm64/rpi_4b/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright 2023 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "Raspberry Pi 4 Model B" + depends on BOARD_RPI_4B diff --git a/boards/arm64/rpi_4b/board.cmake b/boards/arm64/rpi_4b/board.cmake new file mode 100644 index 00000000000..9881313609a --- /dev/null +++ b/boards/arm64/rpi_4b/board.cmake @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/rpi_4b/doc/index.rst b/boards/arm64/rpi_4b/doc/index.rst new file mode 100644 index 00000000000..cdc9d9cc148 --- /dev/null +++ b/boards/arm64/rpi_4b/doc/index.rst @@ -0,0 +1,46 @@ +.. rpi_4b: + +Raspberry Pi 4 Model B (Cortex-A72) +################################### + +Overview +******** +see + +Hardware +******** +see + +Supported Features +================== +The Raspberry Pi 4 Model B board configuration supports the following +hardware features: + ++-----------+------------+--------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================================+ +| GIC-400 | on-chip | GICv2 interrupt controller | ++-----------+------------+--------------------------------------+ +| UART | on-chip | Mini uart serial port | ++-----------+------------+--------------------------------------+ + +Other hardware features have not been enabled yet for this board. + +The default configuration can be found in the defconfig file: + + ``boards/arm/rpi_4b/rpi_4b_defconfig`` + +Programming and Debugging +************************* + +Flashing +======== + +1. Install Raspberry Pi OS using Raspberry Pi Imager. see . + +2. add `kernel=zephyr.bin` in `config.txt`. see + +.. code-block:: console + + *** Booting Zephyr OS build XXXXXXXXXXXX *** + Hello World! Raspberry Pi 4 Model B! diff --git a/boards/arm64/rpi_4b/rpi_4b.dts b/boards/arm64/rpi_4b/rpi_4b.dts new file mode 100644 index 00000000000..371ca3c09e8 --- /dev/null +++ b/boards/arm64/rpi_4b/rpi_4b.dts @@ -0,0 +1,26 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +/ { + model = "Raspberry Pi 4 Model B"; + compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + }; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm64/rpi_4b/rpi_4b.yaml b/boards/arm64/rpi_4b/rpi_4b.yaml new file mode 100644 index 00000000000..475979827c5 --- /dev/null +++ b/boards/arm64/rpi_4b/rpi_4b.yaml @@ -0,0 +1,7 @@ +identifier: rpi_4b +name: Raspberry Pi 4 Model B +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile diff --git a/boards/arm64/rpi_4b/rpi_4b_defconfig b/boards/arm64/rpi_4b/rpi_4b_defconfig new file mode 100644 index 00000000000..fb79c77a1f6 --- /dev/null +++ b/boards/arm64/rpi_4b/rpi_4b_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_SOC_BCM2711=y +CONFIG_BOARD_RPI_4B=y +CONFIG_ARM64_VA_BITS_36=y +CONFIG_ARM64_PA_BITS_36=y + +# Zephyr Kernel Configuration +CONFIG_XIP=n +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Timer Drivers +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 9150078d66f..658ab50a71d 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -64,6 +64,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_EMUL uart_emul.c) zephyr_library_sources_ifdef(CONFIG_UART_NUMAKER uart_numaker.c) zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) +zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 39156777336..e4ab0953861 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -241,4 +241,6 @@ source "drivers/serial/Kconfig.efinix_sapphire" source "drivers/serial/Kconfig.sedi" +source "drivers/serial/Kconfig.bcm2711" + endif # SERIAL diff --git a/drivers/serial/Kconfig.bcm2711 b/drivers/serial/Kconfig.bcm2711 new file mode 100644 index 00000000000..8f60fcf0b7f --- /dev/null +++ b/drivers/serial/Kconfig.bcm2711 @@ -0,0 +1,11 @@ +# Copyright (c) 2023 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +config UART_BCM2711_MU + bool "bcm2711_mu" + default y + depends on DT_HAS_BRCM_BCM2711_AUX_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + bcm2711_mu Low Power Serial Port. diff --git a/drivers/serial/uart_bcm2711.c b/drivers/serial/uart_bcm2711.c new file mode 100644 index 00000000000..c8de51bf5e2 --- /dev/null +++ b/drivers/serial/uart_bcm2711.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT brcm_bcm2711_aux_uart + +/** + * @brief BCM2711 Miniuart Serial Driver + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BCM2711_MU_IO 0x00 +#define BCM2711_MU_IER 0x04 +#define BCM2711_MU_IIR 0x08 +#define BCM2711_MU_LCR 0x0c +#define BCM2711_MU_MCR 0x10 +#define BCM2711_MU_LSR 0x14 +#define BCM2711_MU_MSR 0x18 +#define BCM2711_MU_SCRATCH 0x1c +#define BCM2711_MU_CNTL 0x20 +#define BCM2711_MU_STAT 0x24 +#define BCM2711_MU_BAUD 0x28 + +#define BCM2711_MU_IER_TX_INTERRUPT BIT(1) +#define BCM2711_MU_IER_RX_INTERRUPT BIT(0) + +#define BCM2711_MU_IIR_RX_INTERRUPT BIT(2) +#define BCM2711_MU_IIR_TX_INTERRUPT BIT(1) +#define BCM2711_MU_IIR_FLUSH 0xc6 + +#define BCM2711_MU_LCR_7BIT 0x02 +#define BCM2711_MU_LCR_8BIT 0x03 + +#define BCM2711_MU_LSR_TX_IDLE BIT(6) +#define BCM2711_MU_LSR_TX_EMPTY BIT(5) +#define BCM2711_MU_LSR_RX_OVERRUN BIT(1) +#define BCM2711_MU_LSR_RX_READY BIT(0) + +#define BCM2711_MU_CNTL_RX_ENABLE BIT(0) +#define BCM2711_MU_CNTL_TX_ENABLE BIT(1) + +struct bcm2711_uart_config { + DEVICE_MMIO_ROM; /* Must be first */ + uint32_t baud_rate; + uint32_t clocks; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct bcm2711_uart_data { + DEVICE_MMIO_RAM; /* Must be first */ + mem_addr_t uart_addr; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *cb_data; +#endif +}; + +static bool bcm2711_mu_lowlevel_can_getc(mem_addr_t base) +{ + return sys_read32(base + BCM2711_MU_LSR) & BCM2711_MU_LSR_RX_READY; +} + +static bool bcm2711_mu_lowlevel_can_putc(mem_addr_t base) +{ + return sys_read32(base + BCM2711_MU_LSR) & BCM2711_MU_LSR_TX_EMPTY; +} + +static void bcm2711_mu_lowlevel_putc(mem_addr_t base, uint8_t ch) +{ + /* Wait until there is data in the FIFO */ + while (!bcm2711_mu_lowlevel_can_putc(base)) + ; + + /* Send the character */ + sys_write32(ch, base + BCM2711_MU_IO); +} + +static void bcm2711_mu_lowlevel_init(mem_addr_t base, bool skip_baudrate_config, + uint32_t baudrate, uint32_t input_clock) +{ + uint32_t divider; + + /* Wait until there is data in the FIFO */ + while (!bcm2711_mu_lowlevel_can_putc(base)) + ; + + /* Disable port */ + sys_write32(0x0, base + BCM2711_MU_CNTL); + + /* Disable interrupts */ + sys_write32(0x0, base + BCM2711_MU_IER); + + /* Setup 8bit data width and baudrate */ + sys_write32(BCM2711_MU_LCR_8BIT, base + BCM2711_MU_LCR); + if (!skip_baudrate_config) { + divider = (input_clock / (baudrate * 8)); + sys_write32(divider - 1, base + BCM2711_MU_BAUD); + } + + /* Enable RX & TX port */ + sys_write32(BCM2711_MU_CNTL_RX_ENABLE | BCM2711_MU_CNTL_TX_ENABLE, base + BCM2711_MU_CNTL); +} + +/** + * @brief Initialize UART channel + * + * This routine is called to reset the chip in a quiescent state. + * It is assumed that this function is called only once per UART. + * + * @param dev UART device struct + * + * @return 0 + */ +static int uart_bcm2711_init(const struct device *dev) +{ + const struct bcm2711_uart_config *uart_cfg = dev->config; + struct bcm2711_uart_data *uart_data = dev->data; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + uart_data->uart_addr = DEVICE_MMIO_GET(dev); + bcm2711_mu_lowlevel_init(uart_data->uart_addr, 1, uart_cfg->baud_rate, uart_cfg->clocks); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_cfg->irq_config_func(dev); +#endif + return 0; +} + +static void uart_bcm2711_poll_out(const struct device *dev, unsigned char c) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + bcm2711_mu_lowlevel_putc(uart_data->uart_addr, c); +} + +static int uart_bcm2711_poll_in(const struct device *dev, unsigned char *c) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + while (!bcm2711_mu_lowlevel_can_getc(uart_data->uart_addr)) + ; + + return sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_bcm2711_fifo_fill(const struct device *dev, + const uint8_t *tx_data, + int size) +{ + int num_tx = 0U; + struct bcm2711_uart_data *uart_data = dev->data; + + while ((size - num_tx) > 0) { + /* Send a character */ + bcm2711_mu_lowlevel_putc(uart_data->uart_addr, tx_data[num_tx]); + num_tx++; + } + + return num_tx; +} + +static int uart_bcm2711_fifo_read(const struct device *dev, uint8_t *rx_data, + const int size) +{ + int num_rx = 0U; + struct bcm2711_uart_data *uart_data = dev->data; + + while ((size - num_rx) > 0 && bcm2711_mu_lowlevel_can_getc(uart_data->uart_addr)) { + /* Receive a character */ + rx_data[num_rx++] = sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; + } + return num_rx; +} + +static void uart_bcm2711_irq_tx_enable(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + sys_write32(BCM2711_MU_IER_TX_INTERRUPT, uart_data->uart_addr + BCM2711_MU_IER); +} + +static void uart_bcm2711_irq_tx_disable(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + sys_write32((uint32_t)(~BCM2711_MU_IER_TX_INTERRUPT), + uart_data->uart_addr + BCM2711_MU_IER); +} + +static int uart_bcm2711_irq_tx_ready(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + return bcm2711_mu_lowlevel_can_putc(uart_data->uart_addr); +} + +static void uart_bcm2711_irq_rx_enable(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + sys_write32(BCM2711_MU_IER_RX_INTERRUPT, uart_data->uart_addr + BCM2711_MU_IER); +} + +static void uart_bcm2711_irq_rx_disable(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + sys_write32((uint32_t)(~BCM2711_MU_IER_RX_INTERRUPT), + uart_data->uart_addr + BCM2711_MU_IER); +} + +static int uart_bcm2711_irq_rx_ready(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + return bcm2711_mu_lowlevel_can_getc(uart_data->uart_addr); +} + +static int uart_bcm2711_irq_is_pending(const struct device *dev) +{ + struct bcm2711_uart_data *uart_data = dev->data; + + return bcm2711_mu_lowlevel_can_getc(uart_data->uart_addr) || + bcm2711_mu_lowlevel_can_putc(uart_data->uart_addr); +} + +static int uart_bcm2711_irq_update(const struct device *dev) +{ + return 1; +} + +static void uart_bcm2711_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct bcm2711_uart_data *data = dev->data; + + data->callback = cb; + data->cb_data = cb_data; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * Note: imx UART Tx interrupts when ready to send; Rx interrupts when char + * received. + * + * @param arg Argument to ISR. + */ +void uart_isr(const struct device *dev) +{ + struct bcm2711_uart_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->cb_data); + } +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api uart_bcm2711_driver_api = { + .poll_in = uart_bcm2711_poll_in, + .poll_out = uart_bcm2711_poll_out, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_bcm2711_fifo_fill, + .fifo_read = uart_bcm2711_fifo_read, + .irq_tx_enable = uart_bcm2711_irq_tx_enable, + .irq_tx_disable = uart_bcm2711_irq_tx_disable, + .irq_tx_ready = uart_bcm2711_irq_tx_ready, + .irq_rx_enable = uart_bcm2711_irq_rx_enable, + .irq_rx_disable = uart_bcm2711_irq_rx_disable, + .irq_rx_ready = uart_bcm2711_irq_rx_ready, + .irq_is_pending = uart_bcm2711_irq_is_pending, + .irq_update = uart_bcm2711_irq_update, + .irq_callback_set = uart_bcm2711_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +}; + +#define UART_DECLARE_CFG(n, IRQ_FUNC_INIT) \ + static const struct bcm2711_uart_config bcm2711_uart_##n##_config = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), .baud_rate = DT_INST_PROP(n, current_speed), \ + .clocks = DT_INST_PROP(n, clock_frequency), IRQ_FUNC_INIT} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_CONFIG_FUNC(n) \ + static void irq_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } +#define UART_IRQ_CFG_FUNC_INIT(n) .irq_config_func = irq_config_func_##n +#define UART_INIT_CFG(n) UART_DECLARE_CFG(n, UART_IRQ_CFG_FUNC_INIT(n)) +#else +#define UART_CONFIG_FUNC(n) +#define UART_IRQ_CFG_FUNC_INIT +#define UART_INIT_CFG(n) UART_DECLARE_CFG(n, UART_IRQ_CFG_FUNC_INIT) +#endif + +#define UART_INIT(n) \ + static struct bcm2711_uart_data bcm2711_uart_##n##_data; \ + \ + static const struct bcm2711_uart_config bcm2711_uart_##n##_config; \ + \ + DEVICE_DT_INST_DEFINE(n, &uart_bcm2711_init, NULL, &bcm2711_uart_##n##_data, \ + &bcm2711_uart_##n##_config, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, &uart_bcm2711_driver_api); \ + \ + UART_CONFIG_FUNC(n) \ + \ + UART_INIT_CFG(n); + +DT_INST_FOREACH_STATUS_OKAY(UART_INIT) diff --git a/dts/arm64/broadcom/bcm2711.dtsi b/dts/arm64/broadcom/bcm2711.dtsi new file mode 100644 index 00000000000..716e29006e7 --- /dev/null +++ b/dts/arm64/broadcom/bcm2711.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + soc { + sram0: memory@200000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x200000 0x80000>; + }; + + gic: interrupt-controller@ff841000 { + compatible = "arm,gic-v2", "arm,gic"; + reg = <0xff841000 0x1000>, + <0xff842000 0x2000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + uart1: uart@fe215040 { + compatible = "brcm,bcm2711-aux-uart"; + reg = <0xfe215040 0x40>; + clock-frequency = <500000000>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; +}; diff --git a/dts/bindings/serial/brcm,bcm2711-aux-uart.yaml b/dts/bindings/serial/brcm,bcm2711-aux-uart.yaml new file mode 100644 index 00000000000..2f14db1d877 --- /dev/null +++ b/dts/bindings/serial/brcm,bcm2711-aux-uart.yaml @@ -0,0 +1,15 @@ +description: BCM2711 UART + +compatible: "brcm,bcm2711-aux-uart" + +include: [uart-controller.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + clock-frequency: + required: true diff --git a/soc/arm64/bcm2711/CMakeLists.txt b/soc/arm64/bcm2711/CMakeLists.txt new file mode 100644 index 00000000000..fb2dcd9c15f --- /dev/null +++ b/soc/arm64/bcm2711/CMakeLists.txt @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: Apache-2.0 +zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) diff --git a/soc/arm64/bcm2711/Kconfig.defconfig b/soc/arm64/bcm2711/Kconfig.defconfig new file mode 100644 index 00000000000..0016ca57d03 --- /dev/null +++ b/soc/arm64/bcm2711/Kconfig.defconfig @@ -0,0 +1,17 @@ +# Copyright 2023 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +if SOC_BCM2711 + +config SOC + default "bcm2711" + +config NUM_IRQS + int + default 260 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 54000000 + +endif diff --git a/soc/arm64/bcm2711/Kconfig.soc b/soc/arm64/bcm2711/Kconfig.soc new file mode 100644 index 00000000000..4e1b69462ea --- /dev/null +++ b/soc/arm64/bcm2711/Kconfig.soc @@ -0,0 +1,8 @@ +# Copyright 2023 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +config SOC_BCM2711 + bool "bcm2711" + select ARM64 + select CPU_CORTEX_A72 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS diff --git a/soc/arm64/bcm2711/linker.ld b/soc/arm64/bcm2711/linker.ld new file mode 100644 index 00000000000..fb3fabcecfe --- /dev/null +++ b/soc/arm64/bcm2711/linker.ld @@ -0,0 +1,6 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include diff --git a/soc/arm64/bcm2711/linker_a72.ld b/soc/arm64/bcm2711/linker_a72.ld new file mode 100644 index 00000000000..6f187219b29 --- /dev/null +++ b/soc/arm64/bcm2711/linker_a72.ld @@ -0,0 +1,7 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/arm64/bcm2711/mmu_regions.c b/soc/arm64/bcm2711/mmu_regions.c new file mode 100644 index 00000000000..41a0bf1f367 --- /dev/null +++ b/soc/arm64/bcm2711/mmu_regions.c @@ -0,0 +1,25 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; From 146d025aa0b7e3f35a32d96bf4cc6bde07abdf5a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 27 Sep 2023 16:41:19 +0200 Subject: [PATCH 1288/4498] tests bluetooth mesh: Fix a incorrect assert This ASSERT_TRUE should have been an assert equal (ASSERT_TRUE checks that the first paramters != 0) and the condition was not correct. Fix it. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/mesh/src/test_blob.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index 564fb6fe8d1..0418e6b9cb0 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -1525,7 +1525,7 @@ static void srv_check_reboot_and_continue(void) ASSERT_EQUAL(0, blob_srv.state.ttl); ASSERT_EQUAL(BLOB_CLI_ADDR, blob_srv.state.cli); ASSERT_EQUAL(1, blob_srv.state.timeout_base); - ASSERT_TRUE(BT_MESH_TX_SDU_MAX, blob_srv.state.mtu_size); + ASSERT_EQUAL(BT_MESH_RX_SDU_MAX - BT_MESH_MIC_SHORT, blob_srv.state.mtu_size); ASSERT_EQUAL(CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX * 2, blob_srv.state.xfer.size); ASSERT_EQUAL(12, blob_srv.state.xfer.block_size_log); ASSERT_EQUAL(1, blob_srv.state.xfer.id); From 25897f8baa645cfe79e3a92dad316f0ea5b374cd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 27 Sep 2023 17:03:36 +0200 Subject: [PATCH 1289/4498] tests bluetooth mesh: Fix ASSERT_TRUE/FALSE with messages The previous ASSERT_TRUE/FALSE macros looked like they could take extra printf like parameters but did not (those extra arguments were just dropped). Define 2 new macros that can take those extra parameters and fix all uses that intended to print those extra messages. Also add an extra "\n" as the underlaying print functions do not add end of lines on their own. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/mesh/src/mesh_test.h | 27 +++++++++++++++--- .../bsim/bluetooth/mesh/src/test_advertiser.c | 28 +++++++++---------- tests/bsim/bluetooth/mesh/src/test_blob.c | 6 ++-- tests/bsim/bluetooth/mesh/src/test_dfu.c | 22 +++++++-------- .../bsim/bluetooth/mesh/src/test_provision.c | 2 +- .../bluetooth/mesh/src/test_replay_cache.c | 4 +-- 6 files changed, 54 insertions(+), 35 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index 7bbd30c2685..cfcf5a838dc 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -66,21 +66,40 @@ } \ } while (0) -#define ASSERT_TRUE(cond, ...) \ +#define ASSERT_TRUE(cond) \ do { \ if (!(cond)) { \ bst_result = Failed; \ bs_trace_error_time_line( \ - #cond " is false.", ##__VA_ARGS__); \ + #cond " is false.\n"); \ } \ } while (0) -#define ASSERT_FALSE(cond, ...) \ +#define ASSERT_TRUE_MSG(cond, fmt, ...) \ + do { \ + if (!(cond)) { \ + bst_result = Failed; \ + bs_trace_error_time_line( \ + #cond " is false. " fmt, ##__VA_ARGS__); \ + } \ + } while (0) + + +#define ASSERT_FALSE(cond) \ + do { \ + if (cond) { \ + bst_result = Failed; \ + bs_trace_error_time_line( \ + #cond " is true.\n"); \ + } \ + } while (0) + +#define ASSERT_FALSE_MSG(cond, fmt, ...) \ do { \ if (cond) { \ bst_result = Failed; \ bs_trace_error_time_line( \ - #cond " is true.", ##__VA_ARGS__); \ + #cond " is true. " fmt, ##__VA_ARGS__); \ } \ } while (0) diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 590eed8eebc..70d3e2f4a17 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -84,7 +84,7 @@ static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmi *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); - ASSERT_FALSE(!*buf, "Out of buffers"); + ASSERT_FALSE_MSG(!*buf, "Out of buffers\n"); buf++; } } @@ -96,7 +96,7 @@ static void verify_adv_queue_overflow(void) /* Verity Queue overflow */ dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_TRUE(!dummy_buf, "Unexpected extra buffer"); + ASSERT_TRUE_MSG(!dummy_buf, "Unexpected extra buffer\n"); } static bool check_delta_time(uint8_t transmit, uint64_t interval) @@ -162,7 +162,7 @@ static void realloc_end_cb(int err, void *cb_data) ASSERT_EQUAL(0, err); buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_FALSE(!buf, "Out of buffers"); + ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); k_sem_give(&observer_sem); } @@ -248,13 +248,13 @@ static void rx_gatt_beacons(void) int err; err = bt_le_scan_start(&scan_param, gatt_scan_cb); - ASSERT_FALSE(err && err != -EALREADY, "starting scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err); err = k_sem_take(&observer_sem, K_SECONDS(20)); ASSERT_OK(err); err = bt_le_scan_stop(); - ASSERT_FALSE(err && err != -EALREADY, "stopping scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err); } static void xmit_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, @@ -294,13 +294,13 @@ static void rx_xmit_adv(void) int err; err = bt_le_scan_start(&scan_param, xmit_scan_cb); - ASSERT_FALSE(err && err != -EALREADY, "starting scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err); err = k_sem_take(&observer_sem, K_SECONDS(20)); ASSERT_OK(err); err = bt_le_scan_stop(); - ASSERT_FALSE(err && err != -EALREADY, "stopping scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err); } static void send_order_start_cb(uint16_t duration, int err, void *user_data) @@ -324,7 +324,7 @@ static void send_order_end_cb(int err, void *user_data) struct net_buf *buf = (struct net_buf *)user_data; ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err); - ASSERT_TRUE(!buf->data, "Data not cleared!"); + ASSERT_TRUE_MSG(!buf->data, "Data not cleared!\n"); seq_checker++; LOG_INF("tx end: seq(%d)", seq_checker); @@ -368,7 +368,7 @@ static void receive_order(int expect_adv) int err; err = bt_le_scan_start(&scan_param, receive_order_scan_cb); - ASSERT_FALSE(err && err != -EALREADY, "starting scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err); previous_checker = 0xff; for (int i = 0; i < expect_adv; i++) { @@ -377,7 +377,7 @@ static void receive_order(int expect_adv) } err = bt_le_scan_stop(); - ASSERT_FALSE(err && err != -EALREADY, "stopping scan failed (err %d)", err); + ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err); } static void send_adv_buf(struct net_buf *buf, uint8_t curr, uint8_t prev) @@ -427,7 +427,7 @@ static void test_tx_cb_single(void) buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_FALSE(!buf, "Out of buffers"); + ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); send_cb.start = single_start_cb; send_cb.end = single_end_cb; @@ -638,16 +638,16 @@ static void test_tx_random_order(void) previous_checker = 0xff; buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); - ASSERT_FALSE(!buf[0], "Out of buffers"); + ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n"); buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); - ASSERT_FALSE(!buf[1], "Out of buffers"); + ASSERT_FALSE_MSG(!buf[1], "Out of buffers\n"); send_adv_buf(buf[0], 0, 0xff); buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); - ASSERT_FALSE(!buf[2], "Out of buffers"); + ASSERT_FALSE_MSG(!buf[2], "Out of buffers\n"); send_adv_buf(buf[2], 2, 0); diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index 0418e6b9cb0..e3c564d9739 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -77,13 +77,13 @@ static int blob_chunk_wr(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_chunk *chunk) { partial_block += chunk->size; - ASSERT_TRUE(partial_block <= block->size, "Received block is too large"); + ASSERT_TRUE_MSG(partial_block <= block->size, "Received block is too large\n"); if (partial_block == block->size) { partial_block = 0; - ASSERT_FALSE(atomic_test_and_set_bit(block_bitfield, block->number), - "Received duplicate block"); + ASSERT_FALSE_MSG(atomic_test_and_set_bit(block_bitfield, block->number), + "Received duplicate block\n"); } if (atomic_test_bit(block_bitfield, 0)) { diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index a235e86eeec..08631cba6b6 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -601,8 +601,8 @@ static void test_dist_dfu_slot_create(void) size_t metadata_len = 4; int err, i; - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3"); + ASSERT_TRUE_MSG(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3\n"); bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); @@ -613,7 +613,7 @@ static void test_dist_dfu_slot_create(void) metadata[0] = i; slot[i] = slot_reserve_and_set(size, fwid, fwid_len, metadata, metadata_len); - ASSERT_FALSE(slot[i] == NULL, "Failed to add slot"); + ASSERT_FALSE_MSG(slot[i] == NULL, "Failed to add slot\n"); if (i > 0) { /* All but first slot are committed */ @@ -668,8 +668,8 @@ static void test_dist_dfu_slot_create_recover(void) size_t metadata_len = 4; int i, idx; - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3"); + ASSERT_TRUE_MSG(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3\n"); bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); @@ -698,8 +698,8 @@ static void check_delete_all(void) const struct bt_mesh_dfu_slot *slot; size_t slot_count; - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3"); + ASSERT_TRUE_MSG(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3\n"); slot_count = bt_mesh_dfu_slot_foreach(NULL, NULL); ASSERT_EQUAL(0, slot_count); @@ -712,8 +712,8 @@ static void check_delete_all(void) static void test_dist_dfu_slot_delete_all(void) { - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3"); + ASSERT_TRUE_MSG(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 3\n"); bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); @@ -763,8 +763,8 @@ static void test_dist_dfu_slot_idempotency(void) size_t fwid_len = 4; struct bt_mesh_dfu_slot *slot; - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 1, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 1"); + ASSERT_TRUE_MSG(CONFIG_BT_MESH_DFU_SLOT_CNT >= 1, + "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 1\n"); bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 9f31cb77faf..e1c0da46bdd 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -565,7 +565,7 @@ static void node_configure_and_reset(void) BT_MESH_MODEL_ID_HEALTH_SRV, &healthpub, &status)); ASSERT_EQUAL(0, status); - ASSERT_TRUE(healthpub.addr == BT_MESH_ADDR_UNASSIGNED, "Pub not cleared"); + ASSERT_TRUE_MSG(healthpub.addr == BT_MESH_ADDR_UNASSIGNED, "Pub not cleared\n"); /* Set pub and sub to check that they are reset */ healthpub.addr = 0xc001; diff --git a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c index dbab05661cb..5479387a4f4 100644 --- a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c +++ b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c @@ -178,7 +178,7 @@ static void test_rx_immediate_replay_attack(void) k_sleep(K_SECONDS(6 * TEST_DATA_WAITING_TIME)); - ASSERT_TRUE(rx_cnt == 3, "Device didn't receive expected data"); + ASSERT_TRUE_MSG(rx_cnt == 3, "Device didn't receive expected data\n"); PASS(); } @@ -235,7 +235,7 @@ static void test_rx_power_replay_attack(void) k_sleep(K_SECONDS(6 * TEST_DATA_WAITING_TIME)); - ASSERT_TRUE(rx_cnt == 3, "Device didn't receive expected data"); + ASSERT_TRUE_MSG(rx_cnt == 3, "Device didn't receive expected data\n"); PASS(); } From 730f7caa21ff178e928263c0f148f198df7be98a Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Wed, 16 Aug 2023 10:22:49 +0200 Subject: [PATCH 1290/4498] Bluetooth: controller: add missing NTF alloc in central CIS Create If a CIS create is requested prior to having a complete feature exchange the central will initiate a feat exch before enqueing the CIS create. IF then the feature exchange results in peripheral NOT supporting CIS create the central needs to allocate an RX node for the NTF Signed-off-by: Erik Brockhoff --- .../bluetooth/controller/ll_sw/ull_llcp_cc.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c index 387cc884dea..69dc80bda13 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c @@ -643,6 +643,7 @@ static void lp_cc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ /* LLCP Local Procedure FSM states */ enum { LP_CC_STATE_IDLE, + LP_CC_STATE_WAIT_NTF_AVAIL, LP_CC_STATE_WAIT_OFFSET_CALC, LP_CC_STATE_WAIT_OFFSET_CALC_TX_REQ, LP_CC_STATE_WAIT_TX_CIS_REQ, @@ -839,7 +840,7 @@ static void lp_cc_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t ev } else { /* Peer doesn't support CIS Peripheral so report unsupported */ ctx->data.cis_create.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; - lp_cc_complete(conn, ctx, evt, param); + ctx->state = LP_CC_STATE_WAIT_NTF_AVAIL; } break; default: @@ -854,6 +855,26 @@ static void lp_cc_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t ev } } +static void lp_cc_state_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, + void *param) +{ + switch (evt) { + case LP_CC_EVT_RUN: + if (llcp_ntf_alloc_is_available()) { + ctx->node_ref.rx = llcp_ntf_alloc(); + /* Mark node as RETAIN to trigger put/sched */ + ctx->node_ref.rx->hdr.type = NODE_RX_TYPE_RETAIN; + + /* Now we're good to complete procedure*/ + lp_cc_complete(conn, ctx, evt, param); + } + break; + default: + /* Ignore other evts */ + break; + } +} + static void cc_prepare_cis_ind(struct ll_conn *conn, struct proc_ctx *ctx) { uint8_t err; @@ -1040,6 +1061,9 @@ static void lp_cc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ case LP_CC_STATE_IDLE: lp_cc_st_idle(conn, ctx, evt, param); break; + case LP_CC_STATE_WAIT_NTF_AVAIL: + lp_cc_state_wait_ntf_avail(conn, ctx, evt, param); + break; case LP_CC_STATE_WAIT_OFFSET_CALC_TX_REQ: lp_cc_st_wait_offset_calc_tx_req(conn, ctx, evt, param); break; From 1de8a76f58bf3f18a8c604d63e7e82070e324c0e Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Wed, 16 Aug 2023 14:50:04 +0200 Subject: [PATCH 1291/4498] Bluetooth: controller: adding API for unmasking peer features For asymetrical features there needs to be a separate mechanism to unmask features in peer. This must be used in central for unmasking in case of 'unsupported in peer' condition for CIS Create. Signed-off-by: Erik Brockhoff --- subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c | 4 ++-- subsys/bluetooth/controller/ll_sw/ull_llcp_features.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c index 69dc80bda13..59c23e7a0f6 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c @@ -921,14 +921,14 @@ static void lp_cc_st_wait_rx_cis_rsp(struct ll_conn *conn, struct proc_ctx *ctx, break; case LP_CC_EVT_UNKNOWN: /* Unsupported in peer, so disable locally for this connection */ - feature_unmask_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); + feature_unmask_peer_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); ctx->data.cis_create.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; lp_cc_complete(conn, ctx, evt, param); break; case LP_CC_EVT_REJECT: if (pdu->llctrl.reject_ext_ind.error_code == BT_HCI_ERR_UNSUPP_REMOTE_FEATURE) { /* Unsupported in peer, so disable locally for this connection */ - feature_unmask_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); + feature_unmask_peer_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); } ctx->data.cis_create.error = pdu->llctrl.reject_ext_ind.error_code; lp_cc_complete(conn, ctx, evt, param); diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h b/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h index ac60206bc70..75d92d5524e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h @@ -9,6 +9,11 @@ static inline void feature_unmask_features(struct ll_conn *conn, uint64_t ll_fea conn->llcp.fex.features_used &= ~ll_feat_mask; } +static inline void feature_unmask_peer_features(struct ll_conn *conn, uint64_t ll_feat_mask) +{ + conn->llcp.fex.features_peer &= ~ll_feat_mask; +} + static inline bool feature_le_encryption(struct ll_conn *conn) { #if defined(CONFIG_BT_CTLR_LE_ENC) From 551b9afe11b8673e1b30c8198948d456eff6535d Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Wed, 16 Aug 2023 14:55:41 +0200 Subject: [PATCH 1292/4498] Bluetooth: controller: adding unittest for Central CIS Create Adding unittests for basic Central CIS Create functionality Signed-off-by: Erik Brockhoff --- .../controller/common/src/helper_pdu.c | 4 +- .../controller/ctrl_cis_create/src/main.c | 392 +++++++++++++++++- .../controller/mock_ctrl/src/ull_central.c | 2 +- .../controller/mock_ctrl/src/ull_conn_iso.c | 2 +- 4 files changed, 385 insertions(+), 15 deletions(-) diff --git a/tests/bluetooth/controller/common/src/helper_pdu.c b/tests/bluetooth/controller/common/src/helper_pdu.c index 87454dda432..fe2af51bd67 100644 --- a/tests/bluetooth/controller/common/src/helper_pdu.c +++ b/tests/bluetooth/controller/common/src/helper_pdu.c @@ -1213,8 +1213,8 @@ void helper_pdu_verify_cis_ind(const char *file, uint32_t line, struct pdu_data zassert_mem_equal(pdu->llctrl.cis_ind.cis_sync_delay, p->cis_sync_delay, sizeof(p->cis_sync_delay), "cis_sync_delay mismatch.\nCalled at %s:%d\n", file, line); - - pdu->llctrl.cis_ind.conn_event_count = p->conn_event_count; + zassert_equal(pdu->llctrl.cis_ind.conn_event_count, p->conn_event_count, + "conn_event_count mismatch.\nCalled at %s:%d\n", file, line); } void helper_pdu_verify_cis_terminate_ind(const char *file, uint32_t line, struct pdu_data *pdu, diff --git a/tests/bluetooth/controller/ctrl_cis_create/src/main.c b/tests/bluetooth/controller/ctrl_cis_create/src/main.c index 853eaa0e570..54a8d742208 100644 --- a/tests/bluetooth/controller/ctrl_cis_create/src/main.c +++ b/tests/bluetooth/controller/ctrl_cis_create/src/main.c @@ -39,6 +39,7 @@ DEFINE_FFF_GLOBALS; #include "ull_iso_types.h" #include "ull_conn_types.h" #include "ull_conn_iso_types.h" +#include "ull_conn_iso_internal.h" #include "ull_llcp.h" #include "ull_conn_internal.h" #include "ull_llcp_internal.h" @@ -48,6 +49,9 @@ DEFINE_FFF_GLOBALS; static struct ll_conn conn; +static struct ll_conn_iso_group cig_mock = { 0 }; +static struct ll_conn_iso_stream cis_mock = { .established = 1, .group = &cig_mock }; + /* struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle); */ FAKE_VALUE_FUNC(struct ll_conn_iso_stream *, ll_conn_iso_stream_get, uint16_t); @@ -63,15 +67,16 @@ static bool is_instant_reached(struct ll_conn *conn, uint16_t instant) return ((event_counter(conn) - instant) & 0xFFFF) <= 0x7FFF; } +#define MAX_xDU 160 static struct pdu_data_llctrl_cis_req remote_cis_req = { .cig_id = 0x01, .cis_id = 0x02, .c_phy = 0x01, .p_phy = 0x01, - .c_max_sdu_packed = { 0, 160}, - .p_max_sdu = { 0, 160}, - .c_max_pdu = 160, - .p_max_pdu = 160, + .c_max_sdu_packed = { MAX_xDU, 0 }, + .p_max_sdu = { MAX_xDU, 0 }, + .c_max_pdu = MAX_xDU, + .p_max_pdu = MAX_xDU, .nse = 2, .p_bn = 1, .c_bn = 1, @@ -94,6 +99,37 @@ static struct pdu_data_llctrl_cis_ind remote_cis_ind = { .conn_event_count = 12 }; +static struct pdu_data_llctrl_cis_req local_cis_req = { + .cig_id = 0x00, + .cis_id = 0x02, + .c_phy = 0x01, + .p_phy = 0x01, + .c_max_sdu_packed = { MAX_xDU, 0 }, + .p_max_sdu = { MAX_xDU, 0 }, + .c_max_pdu = MAX_xDU, + .p_max_pdu = MAX_xDU, + .nse = 2, + .p_bn = 1, + .c_bn = 1, + .c_ft = 1, + .p_ft = 1, + .iso_interval = 6, + .conn_event_count = 0, + .c_sdu_interval = { 0, 0, 0}, + .p_sdu_interval = { 0, 0, 0}, + .sub_interval = { 0, 0, 0}, + .cis_offset_min = { 0, 0, 0}, + .cis_offset_max = { 0, 0, 0} +}; + +static struct pdu_data_llctrl_cis_ind local_cis_ind = { + .aa = { 0, 0, 0, 0}, + .cig_sync_delay = { 0, 0, 0}, + .cis_offset = { 0, 0, 0}, + .cis_sync_delay = { 0, 0, 0}, + .conn_event_count = 13 +}; + #define ERROR_CODE 0x17 /* * Central-initiated CIS Create procedure. @@ -141,10 +177,9 @@ ZTEST(cis_create, test_cc_create_periph_rem_host_accept) .cis_handle = 0x00, .status = 0x00 }; - struct ll_conn_iso_stream cis = { 0 }; /* Prepare mocked call to ll_conn_iso_stream_get() */ - ll_conn_iso_stream_get_fake.return_val = &cis; + ll_conn_iso_stream_get_fake.return_val = &cis_mock; /* Role */ test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL); @@ -237,7 +272,7 @@ ZTEST(cis_create, test_cc_create_periph_rem_host_accept) event_done(&conn); /* NODE_CIS_ESTABLISHED carry extra information in header rx footer param field */ - zassert_equal_ptr(ntf->hdr.rx_ftr.param, &cis); + zassert_equal_ptr(ntf->hdr.rx_ftr.param, &cis_mock); zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(), "Free CTX buffers %d", llcp_ctx_buffers_free()); @@ -438,10 +473,10 @@ ZTEST(cis_create, test_cc_create_periph_rem_invalid_phy) .cis_id = 0x02, .c_phy = 0x03, .p_phy = 0x01, - .c_max_sdu_packed = { 0, 160}, - .p_max_sdu = { 0, 160}, - .c_max_pdu = 160, - .p_max_pdu = 160, + .c_max_sdu_packed = { MAX_xDU, 0 }, + .p_max_sdu = { MAX_xDU, 0 }, + .c_max_pdu = MAX_xDU, + .p_max_pdu = MAX_xDU, .nse = 2, .p_bn = 1, .c_bn = 1, @@ -490,4 +525,339 @@ ZTEST(cis_create, test_cc_create_periph_rem_invalid_phy) "Free CTX buffers %d", llcp_ctx_buffers_free()); } +/* + * Central-initiated CIS Create procedure. + * Host requests CIS, LL replies with 'remote feature unsupported' + * + * +-----+ +-------+ +-----+ + * | UT | | LL_C | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | LE CIS Create | | + * |-------------------------->| | + * | | | + * | | (FEAT unsupported) | + * | | | + * | | | + * | LE CIS ESTABLISHED | | + * | (rem feat unsupported) | | + * |<--------------------------| | + */ +ZTEST(cis_create, test_cc_create_central_rem_unsupported) +{ + struct ll_conn_iso_stream *cis; + struct node_rx_pdu *ntf; + uint8_t err; + + struct node_rx_conn_iso_estab cis_estab = { + .cis_handle = 0x00, + .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE + }; + + /* Prepare mocked call to ll_conn_iso_stream_get() */ + ll_conn_iso_stream_get_fake.return_val = &cis_mock; + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_CENTRAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + conn.llcp.fex.valid = 1; + + cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE); + cis->lll.acl_handle = conn.lll.handle; + + err = ull_cp_cis_create(&conn, cis); + zassert_equal(err, BT_HCI_ERR_SUCCESS); + + /* Prepare */ + event_prepare(&conn); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* There should be excactly one host notification + * with status BT_HCI_ERR_UNSUPP_REMOTE_FEATURE + */ + ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab); + ut_rx_q_is_empty(); + + /* Done */ + event_done(&conn); + + zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", llcp_ctx_buffers_free()); +} + +/* + * Central-initiated CIS Create procedure. + * Central requests CIS, peripheral accepts + * + * +-----+ +-------+ +-----+ + * | UT | | LL_C | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | LE CIS Create | | + * |-------------------------->| | + * | | LL_CIS_REQ | + * | |-------------------------->| + * | | | + * | | LL_CIS_RSP | + * | |<--------------------------| + * | | | + * | | | + * | | LL_CIS_IND | + * | |-------------------------->| + * | | | + * | | | + * | | | + * | | | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * | | | + * | LE CIS ESTABLISHED | | + * |<--------------------------| | + */ +ZTEST(cis_create, test_cc_create_central_rem_accept) +{ + struct pdu_data_llctrl_cis_rsp remote_cis_rsp = { + .cis_offset_max = { 0, 0, 0}, + .cis_offset_min = { 0, 0, 0}, + .conn_event_count = 13 + }; + struct node_rx_conn_iso_estab cis_estab = { + .cis_handle = 0x00, + .status = BT_HCI_ERR_SUCCESS + }; + struct ll_conn_iso_stream *cis; + struct node_rx_pdu *ntf; + struct node_tx *tx; + uint8_t err; + + /* Prepare mocked call to ll_conn_iso_stream_get() */ + ll_conn_iso_stream_get_fake.return_val = &cis_mock; + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_CENTRAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + conn.llcp.fex.valid = 1; + conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL); + + /* Setup default CIS/CIG parameters */ + cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE); + cis->lll.acl_handle = conn.lll.handle; + cis->group->cig_id = local_cis_req.cig_id; + cis->cis_id = local_cis_req.cis_id; + cis->lll.tx.phy = local_cis_req.c_phy; + cis->lll.rx.phy = local_cis_req.p_phy; + cis->group->c_sdu_interval = 0; + cis->group->p_sdu_interval = 0; + cis->lll.tx.max_pdu = MAX_xDU; + cis->lll.rx.max_pdu = MAX_xDU; + cis->c_max_sdu = MAX_xDU; + cis->p_max_sdu = MAX_xDU; + cis->group->iso_interval = local_cis_req.iso_interval; + cis->framed = 0; + cis->lll.nse = local_cis_req.nse; + cis->lll.sub_interval = 0; + cis->lll.tx.bn = local_cis_req.c_bn; + cis->lll.rx.bn = local_cis_req.p_bn; + cis->lll.tx.ft = local_cis_req.c_ft; + cis->lll.rx.ft = local_cis_req.p_ft; + + err = ull_cp_cis_create(&conn, cis); + zassert_equal(err, BT_HCI_ERR_SUCCESS); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* Rx */ + lt_tx(LL_CIS_RSP, &conn, &remote_cis_rsp); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_CIS_IND, &conn, &tx, &local_cis_ind); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* */ + while (!is_instant_reached(&conn, remote_cis_rsp.conn_event_count)) { + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should NOT have a LL Control PDU */ + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* There should NOT be a host notification */ + ut_rx_q_is_empty(); + } + + /* Prepare */ + event_prepare(&conn); + + /* Done */ + event_done(&conn); + + /* Emulate CIS becoming established */ + ull_cp_cc_established(&conn, 0); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should NOT have a LL Control PDU */ + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* There should be excactly one host notification */ + ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab); + ut_rx_q_is_empty(); + + /* Done */ + event_done(&conn); + + zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", llcp_ctx_buffers_free()); +} + +/* + * Central-initiated CIS Create procedure. + * Central requests CIS, peripheral rejects with 'unsupported remote feature' + * + * +-----+ +-------+ +-----+ + * | UT | | LL_C | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | LE CIS Create | | + * |-------------------------->| | + * | | LL_CIS_REQ | + * | |-------------------------->| + * | | | + * | | LL_REJECT_EXT_IND | + * | | (unsupported remote feat) | + * | |<--------------------------| + * | | | + * | | | + * | | | + * | | | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * | | | + * | LE CIS ESTABLISHED | | + * |<--------------------------| | + */ +ZTEST(cis_create, test_cc_create_central_rem_reject) +{ + struct node_rx_conn_iso_estab cis_estab = { + .cis_handle = 0x00, + .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE + }; + struct pdu_data_llctrl_reject_ext_ind remote_reject = { + .error_code = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE, + .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ + }; + struct ll_conn_iso_stream *cis; + struct node_rx_pdu *ntf; + struct node_tx *tx; + uint8_t err; + + /* Prepare mocked call to ll_conn_iso_stream_get() */ + ll_conn_iso_stream_get_fake.return_val = &cis_mock; + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_CENTRAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + conn.llcp.fex.valid = 1; + conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL); + + /* Setup default CIS/CIG parameters */ + cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE); + cis->lll.acl_handle = conn.lll.handle; + cis->group->cig_id = local_cis_req.cig_id; + cis->cis_id = local_cis_req.cis_id; + cis->lll.tx.phy = local_cis_req.c_phy; + cis->lll.rx.phy = local_cis_req.p_phy; + cis->group->c_sdu_interval = 0; + cis->group->p_sdu_interval = 0; + cis->lll.tx.max_pdu = MAX_xDU; + cis->lll.rx.max_pdu = MAX_xDU; + cis->c_max_sdu = MAX_xDU; + cis->p_max_sdu = MAX_xDU; + cis->group->iso_interval = local_cis_req.iso_interval; + cis->framed = 0; + cis->lll.nse = local_cis_req.nse; + cis->lll.sub_interval = 0; + cis->lll.tx.bn = local_cis_req.c_bn; + cis->lll.rx.bn = local_cis_req.p_bn; + cis->lll.tx.ft = local_cis_req.c_ft; + cis->lll.rx.ft = local_cis_req.p_ft; + + err = ull_cp_cis_create(&conn, cis); + zassert_equal(err, BT_HCI_ERR_SUCCESS); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* Rx */ + lt_tx(LL_REJECT_EXT_IND, &conn, &remote_reject); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* There should be excactly one host notification */ + ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab); + ut_rx_q_is_empty(); + + zassert_equal(conn.llcp.fex.features_peer & BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL), 0); + + /* Done */ + event_done(&conn); + + zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", llcp_ctx_buffers_free()); +} + + ZTEST_SUITE(cis_create, NULL, NULL, cis_create_setup, NULL, NULL); diff --git a/tests/bluetooth/controller/mock_ctrl/src/ull_central.c b/tests/bluetooth/controller/mock_ctrl/src/ull_central.c index 8cdf86b5db4..ab067dcbb9d 100644 --- a/tests/bluetooth/controller/mock_ctrl/src/ull_central.c +++ b/tests/bluetooth/controller/mock_ctrl/src/ull_central.c @@ -42,7 +42,7 @@ int ull_central_reset(void) } uint16_t ull_central_iso_cis_offset_get(uint16_t cis_handle, uint32_t *cis_offset_min, - uint32_t *cis_offset_max) + uint32_t *cis_offset_max, uint16_t *conn_event_count) { return 0; } diff --git a/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c b/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c index 031d856e67e..36e457ee284 100644 --- a/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c +++ b/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c @@ -42,7 +42,7 @@ #include "hal/debug.h" static struct ll_conn_iso_group cig = { 0 }; -static struct ll_conn_iso_stream cis = { 0 }; +static struct ll_conn_iso_stream cis = { .established = 1, .group = &cig }; __weak struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_acl(struct ll_conn *conn, uint16_t *cis_iter) From 85bb2624bc562becde8b1b6e3b570e2d4b45c7e5 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Sep 2023 12:25:22 +0200 Subject: [PATCH 1293/4498] Bluetooth: Audio: Refactor codec_cfg_get_freq Refactor the codec_cfg_get_freq function to return the assigned numbers value, instead of a converted value, but with support for converting the value. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 50 +++- include/zephyr/bluetooth/audio/lc3.h | 117 +++++----- samples/bluetooth/hap_ha/src/bap_unicast_sr.c | 11 +- .../tmap_peripheral/src/bap_unicast_sr.c | 11 +- .../bluetooth/unicast_audio_client/src/main.c | 19 +- .../bluetooth/unicast_audio_server/src/main.c | 21 +- subsys/bluetooth/audio/codec.c | 219 +++++++++++++++--- subsys/bluetooth/audio/shell/bap.c | 54 ++++- tests/bluetooth/audio/codec/src/main.c | 53 ++++- tests/bluetooth/tester/src/btp_bap.c | 19 +- 10 files changed, 449 insertions(+), 125 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 9e05e4e4682..e09d7a18cf2 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -566,17 +566,50 @@ struct bt_audio_codec_qos_pref { * @{ */ +/** + * @brief Convert assigned numbers frequency to frequency value. + * + * @param freq The assigned numbers frequency to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The converted frequency value in Hz. + */ +int bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_config_freq freq); + +/** + * @brief Convert frequency value to assigned numbers frequency. + * + * @param freq_hz The frequency value to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The assigned numbers frequency (@ref bt_audio_codec_config_freq). + */ +int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz); + /**@brief Extract the frequency from a codec configuration. * * @param codec_cfg The codec configuration to extract data from. * - * @retval The frequency in Hz + * @retval A @ref bt_audio_codec_config_freq value * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the frequency of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param freq The assigned numbers frequency to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_freq freq); + /** @brief Extract frame duration from BT codec config * * @param codec_cfg The codec configuration to extract data from. @@ -661,6 +694,21 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data); +/** + * @brief Set or add a specific codec configuration value + * + * @param codec_cfg The codec data to set the value in. + * @param type The type id to set + * @param data Pointer to the data-pointer to set + * @param data_len Length of @p data + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t *data, size_t data_len); + /** @} */ /* End of bt_audio_codec_cfg */ /** diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 198f8185b13..28737fc367f 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -173,73 +173,75 @@ struct bt_audio_codec_octets_per_codec_frame { enum bt_audio_codec_config_type { /** @brief LC3 Sample Frequency configuration type. */ - BT_AUDIO_CODEC_CONFIG_LC3_FREQ = 0x01, + BT_AUDIO_CODEC_CONFIG_LC3_FREQ = 0x01, /** @brief LC3 Frame Duration configuration type. */ - BT_AUDIO_CODEC_CONFIG_LC3_DURATION = 0x02, + BT_AUDIO_CODEC_CONFIG_LC3_DURATION = 0x02, /** @brief LC3 channel Allocation configuration type. */ - BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC = 0x03, + BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC = 0x03, /** @brief LC3 Frame Length configuration type. */ - BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN = 0x04, + BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN = 0x04, /** @brief Codec frame blocks, per SDU configuration type. */ - BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU = 0x05, + BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU = 0x05, }; -/** - * @brief 8 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ 0x01 -/** - * @brief 11.025 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ 0x02 -/** - * @brief 16 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ 0x03 -/** - * @brief 22.05 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ 0x04 -/** - * @brief 24 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ 0x05 -/** - * @brief 32 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ 0x06 -/** - * @brief 44.1 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ 0x07 -/** - * @brief 48 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ 0x08 -/** - * @brief 88.2 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ 0x09 -/** - * @brief 96 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ 0x0a -/** - * @brief 176.4 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ 0x0b -/** - * @brief 192 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ 0x0c -/** - * @brief 384 Khz codec Sample Frequency configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ 0x0d +enum bt_audio_codec_config_freq { + /** + * @brief 8 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ = 0x01, + /** + * @brief 11.025 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ = 0x02, + /** + * @brief 16 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ = 0x03, + /** + * @brief 22.05 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ = 0x04, + /** + * @brief 24 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ = 0x05, + /** + * @brief 32 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ = 0x06, + /** + * @brief 44.1 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ = 0x07, + /** + * @brief 48 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ = 0x08, + /** + * @brief 88.2 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ = 0x09, + /** + * @brief 96 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ = 0x0a, + /** + * @brief 176.4 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ = 0x0b, + /** + * @brief 192 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ = 0x0c, + /** + * @brief 384 Khz codec Sample Frequency configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ = 0x0d, +}; /** * @brief LC3 7.5 msec Frame Duration configuration @@ -250,7 +252,6 @@ enum bt_audio_codec_config_type { */ #define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 0x01 - /** * @brief Helper to declare LC3 codec capability * diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 90724b68cc2..c185297ee20 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -75,13 +75,18 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) codec_cfg->vid, codec_cfg->data_len); if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { - /* LC3 uses the generic LTV format - other codecs might do as well */ - enum bt_audio_location chan_allocation; + int ret; + + /* LC3 uses the generic LTV format - other codecs might do as well */ bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, "data"); - printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_get_freq(codec_cfg)); + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); + } + printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index bfb0588b497..d05406dd1e9 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -64,13 +64,18 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) codec_cfg->vid, codec_cfg->data_len); if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { - /* LC3 uses the generic LTV format - other codecs might do as well */ - enum bt_audio_location chan_allocation; + int ret; + + /* LC3 uses the generic LTV format - other codecs might do as well */ bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, "data"); - printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_get_freq(codec_cfg)); + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); + } + printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index be17e887e08..a3aca0424fa 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -221,12 +221,19 @@ static void lc3_audio_timer_timeout(struct k_work *work) } } -static void init_lc3(void) +static int init_lc3(void) { const struct bt_audio_codec_cfg *codec_cfg = &codec_configuration.codec_cfg; unsigned int num_samples; + int ret; + + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); + } else { + return ret; + } - freq_hz = bt_audio_codec_cfg_get_freq(codec_cfg); frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); @@ -271,7 +278,7 @@ static void init_lc3(void) #else -#define init_lc3(...) +#define init_lc3(...) 0 /** * @brief Send audio data on timeout @@ -979,7 +986,11 @@ static int set_stream_qos(void) static int enable_streams(void) { if (IS_ENABLED(CONFIG_LIBLC3)) { - init_lc3(); + int err = init_lc3(); + + if (err != 0) { + return err; + } } for (size_t i = 0U; i < configured_stream_count; i++) { diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index d1e9dfb2737..fd9415650ae 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -135,13 +135,18 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) codec_cfg->vid, codec_cfg->data_len); if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { - /* LC3 uses the generic LTV format - other codecs might do as well */ - enum bt_audio_location chan_allocation; + int ret; + + /* LC3 uses the generic LTV format - other codecs might do as well */ bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, "data"); - printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_get_freq(codec_cfg)); + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); + } + printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { @@ -349,15 +354,19 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t #if defined(CONFIG_LIBLC3) { - const int freq = bt_audio_codec_cfg_get_freq(stream->codec_cfg); const int frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); + int freq; + int ret; - if (freq < 0) { + ret = bt_audio_codec_cfg_get_freq(stream->codec_cfg); + if (ret > 0) { + freq = bt_audio_codec_cfg_freq_to_freq_hz(ret); + } else { printk("Error: Codec frequency not set, cannot start codec."); *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID, BT_BAP_ASCS_REASON_CODEC_DATA); - return -1; + return ret; } if (frame_duration_us < 0) { diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index e3d8ca1c2a7..bdcf8978bd4 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -10,6 +10,8 @@ * Generic Audio. */ +#include + #include #include #include @@ -18,6 +20,74 @@ LOG_MODULE_REGISTER(bt_audio_codec, CONFIG_BT_AUDIO_CODEC_LOG_LEVEL); +int bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_config_freq freq) +{ + switch (freq) { + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ: + return 8000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ: + return 11025; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ: + return 16000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ: + return 22050; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ: + return 24000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ: + return 32000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ: + return 44100; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ: + return 48000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ: + return 88200; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ: + return 96000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ: + return 176400; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ: + return 192000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ: + return 384000; + default: + return -EINVAL; + } +} + +int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz) +{ + switch (freq_hz) { + case 8000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ; + case 11025U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ; + case 16000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ; + case 22050U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ; + case 24000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ; + case 32000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ; + case 44100U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ; + case 48000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ; + case 88200U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ; + case 96000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ; + case 176400U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ; + case 192000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ; + case 384000U: + return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ; + default: + return -EINVAL; + } +} + struct search_type_param { bool found; uint8_t type; @@ -42,6 +112,15 @@ static bool parse_cb(struct bt_data *data, void *user_data) #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 +static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf, + struct bt_audio_codec_cfg *codec_cfg) +{ + buf->__buf = codec_cfg->data; + buf->data = codec_cfg->data; + buf->size = sizeof(codec_cfg->data); + buf->len = codec_cfg->data_len; +} + uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data) { @@ -79,8 +158,99 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u return param.data_len; } +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t *data, size_t data_len) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + CHECKIF(data == NULL) { + LOG_DBG("data is NULL"); + return -EINVAL; + } + + CHECKIF(data_len == 0U || data_len > UINT8_MAX) { + LOG_DBG("Invalid data_len %zu", data_len); + return -EINVAL; + } + + for (uint16_t i = 0U; i < codec_cfg->data_len;) { + const uint8_t len = codec_cfg->data[i++]; + const uint8_t data_type = codec_cfg->data[i++]; + const uint8_t value_len = len - sizeof(data_type); + + if (data_type == type) { + uint8_t *value = &codec_cfg->data[i]; + + if (data_len == value_len) { + memcpy(value, data, data_len); + } else { + const uint8_t *old_next_data_start = value + value_len + 1; + const uint8_t data_len_to_move = + codec_cfg->data_len - + (old_next_data_start - codec_cfg->data); + uint8_t *new_next_data_start = value + data_len + 1; + const int16_t diff = data_len - value_len; + + if (diff < 0) { + /* In this case we need to move memory around after the copy + * to fit the new shorter data + */ + + memcpy(value, data, data_len); + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + } else { + /* In this case we need to move memory around before + * the copy to fit the new longer data + */ + if ((codec_cfg->data_len + diff) > + ARRAY_SIZE(codec_cfg->data)) { + LOG_DBG("Cannot fit data_len %zu in buf with len " + "%u and size %u", + data_len, codec_cfg->data_len, + ARRAY_SIZE(codec_cfg->data)); + return -ENOMEM; + } + + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + memcpy(value, data, data_len); + } + + codec_cfg->data_len += diff; + } + + return codec_cfg->data_len; + } + + i += value_len; + } + + /* If we reach here, we did not find the data in the buffer, so we simply add it */ + if ((codec_cfg->data_len + data_len) <= ARRAY_SIZE(codec_cfg->data)) { + struct net_buf_simple buf; + + init_net_buf_simple_from_codec_cfg(&buf, codec_cfg); + + net_buf_simple_add_u8(&buf, data_len + sizeof(type)); + net_buf_simple_add_u8(&buf, type); + net_buf_simple_add_mem(&buf, data, data_len); + codec_cfg->data_len = buf.len; + } else { + LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len, + codec_cfg->data_len, ARRAY_SIZE(codec_cfg->data)); + return -ENOMEM; + } + + return codec_cfg->data_len; +} + int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) { + enum bt_audio_codec_config_freq freq; const uint8_t *data; uint8_t data_len; @@ -98,36 +268,29 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) return -EBADMSG; } - switch (data[0]) { - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ: - return 8000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ: - return 11025; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ: - return 16000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ: - return 22050; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ: - return 24000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ: - return 32000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ: - return 44100; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ: - return 48000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ: - return 88200; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ: - return 96000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ: - return 176400; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ: - return 192000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ: - return 384000; - default: + freq = data[0]; + if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) { + LOG_DBG("Invalid freq value: 0x%02X", freq); return -EBADMSG; } + + return freq; +} + +int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_freq freq) +{ + uint8_t freq_u8; + + if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) { + LOG_DBG("Invalid freq value: %d", freq); + return -EINVAL; + } + + freq_u8 = (uint8_t)freq; + + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &freq_u8, + sizeof(freq_u8)); } int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index c238a882e13..82ed1d3c5e4 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -228,16 +228,23 @@ static void fill_audio_buf_sin(int16_t *buf, int length_us, int frequency_hz, in } } -static void init_lc3(const struct bt_bap_stream *stream) +static int init_lc3(const struct bt_bap_stream *stream) { size_t num_samples; + int ret; if (stream == NULL || stream->codec_cfg == NULL) { shell_error(ctx_shell, "invalid stream to init LC3"); - return; + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_freq(stream->codec_cfg); + if (ret > 0) { + lc3_freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); + } else { + return ret; } - lc3_freq_hz = bt_audio_codec_cfg_get_freq(stream->codec_cfg); lc3_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg); lc3_frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(stream->codec_cfg, true); @@ -245,17 +252,17 @@ static void init_lc3(const struct bt_bap_stream *stream) if (lc3_freq_hz < 0) { printk("Error: Codec frequency not set, cannot start codec."); - return; + return -EINVAL; } if (lc3_frame_duration_us < 0) { printk("Error: Frame duration not set, cannot start codec."); - return; + return -EINVAL; } if (lc3_octets_per_frame < 0) { printk("Error: Octets per frame not set, cannot start codec."); - return; + return -EINVAL; } lc3_frame_duration_100us = lc3_frame_duration_us / 100; @@ -274,7 +281,10 @@ static void init_lc3(const struct bt_bap_stream *stream) if (lc3_encoder == NULL) { printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); + return -EINVAL; } + + return 0; } static void lc3_audio_send_data(struct k_work *work) @@ -2603,7 +2613,6 @@ static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream) { int stream_frame_duration_us; struct bt_bap_ep_info info; - int stream_freq_hz; int err; if (bap_stream == NULL || bap_stream->qos == NULL) { @@ -2619,8 +2628,12 @@ static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream) return false; } - stream_freq_hz = bt_audio_codec_cfg_get_freq(bap_stream->codec_cfg); - if (stream_freq_hz != lc3_freq_hz) { + err = bt_audio_codec_cfg_get_freq(bap_stream->codec_cfg); + if (err > 0) { + if (bt_audio_codec_cfg_freq_to_freq_hz(err) != lc3_freq_hz) { + return false; + } + } else { return false; } @@ -2671,7 +2684,13 @@ static int cmd_start_sine(const struct shell *sh, size_t argc, char *argv[]) struct bt_bap_stream *bap_stream = &unicast_streams[i].stream.bap_stream; if (!lc3_initialized) { - init_lc3(bap_stream); + err = init_lc3(bap_stream); + if (err != 0) { + shell_error(sh, "Failed to init LC3 %d", err); + + return -ENOEXEC; + } + lc3_initialized = true; } @@ -2694,7 +2713,13 @@ static int cmd_start_sine(const struct shell *sh, size_t argc, char *argv[]) &broadcast_source_streams[i].stream.bap_stream; if (!lc3_initialized) { - init_lc3(bap_stream); + err = init_lc3(bap_stream); + if (err != 0) { + shell_error(sh, "Failed to init LC3 %d", err); + + return -ENOEXEC; + } + lc3_initialized = true; } @@ -2717,7 +2742,12 @@ static int cmd_start_sine(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - init_lc3(default_stream); + err = init_lc3(default_stream); + if (err != 0) { + shell_error(sh, "Failed to init LC3 %d", err); + + return -ENOEXEC; + } err = stream_start_sine(default_stream); if (err != 0) { diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 5ad50c1c0c6..28633716355 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -15,6 +15,37 @@ DEFINE_FFF_GLOBALS; ZTEST_SUITE(audio_codec_test_suite, NULL, NULL, NULL, NULL, NULL); +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_freq_to_freq_hz) +{ + const struct freq_test_input { + enum bt_audio_codec_config_freq freq; + uint32_t freq_hz; + } freq_test_inputs[] = { + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ, .freq_hz = 8000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ, .freq_hz = 11025U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ, .freq_hz = 16000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ, .freq_hz = 22050U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ, .freq_hz = 24000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ, .freq_hz = 32000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ, .freq_hz = 44100U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, .freq_hz = 48000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ, .freq_hz = 88200U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ, .freq_hz = 96000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ, .freq_hz = 176400U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ, .freq_hz = 192000U}, + {.freq = BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ, .freq_hz = 384000U}, + }; + + for (size_t i = 0U; i < ARRAY_SIZE(freq_test_inputs); i++) { + const struct freq_test_input *fti = &freq_test_inputs[i]; + + zassert_equal(bt_audio_codec_cfg_freq_to_freq_hz(fti->freq), fti->freq_hz, + "freq %d was not coverted to %u", fti->freq, fti->freq_hz); + zassert_equal(bt_audio_codec_cfg_freq_hz_to_freq(fti->freq_hz), fti->freq, + "freq_hz %u was not coverted to %d", fti->freq_hz, fti->freq); + } +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_freq) { const struct bt_bap_lc3_preset preset = @@ -23,7 +54,23 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_freq) int ret; ret = bt_audio_codec_cfg_get_freq(&preset.codec_cfg); - zassert_equal(ret, 16000u, "unexpected return value %d", ret); + zassert_equal(ret, 0x03, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_freq) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + int ret; + + ret = bt_audio_codec_cfg_get_freq(&preset.codec_cfg); + zassert_equal(ret, 0x03, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_freq(&preset.codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_freq(&preset.codec_cfg); + zassert_equal(ret, 0x06, "Unexpected return value %d", ret); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_duration_us) @@ -47,8 +94,8 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation_val) err = bt_audio_codec_cfg_get_chan_allocation_val(&preset.codec_cfg, &chan_allocation); zassert_false(err, "unexpected error %d", err); - zassert_equal(chan_allocation, BT_AUDIO_LOCATION_FRONT_LEFT, - "unexpected return value %d", chan_allocation); + zassert_equal(chan_allocation, BT_AUDIO_LOCATION_FRONT_LEFT, "unexpected return value %d", + chan_allocation); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_octets_per_frame) diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index ba34d9613fc..71a12dcbc54 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -136,13 +136,18 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) codec_cfg->vid, codec_cfg->data_len); if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { - /* LC3 uses the generic LTV format - other codecs might do as well */ - enum bt_audio_location chan_allocation; + int ret; + + /* LC3 uses the generic LTV format - other codecs might do as well */ bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, "data"); - LOG_DBG(" Frequency: %d Hz", bt_audio_codec_cfg_get_freq(codec_cfg)); + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + LOG_DBG(" Frequency: %d Hz", bt_audio_codec_cfg_freq_to_freq_hz(ret)); + } + LOG_DBG(" Frame Duration: %d us", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { @@ -255,22 +260,22 @@ static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) { - int freq_hz; int frame_duration_us; int frames_per_sdu; int octets_per_frame; int chan_allocation_err; enum bt_audio_location chan_allocation; + int ret; - freq_hz = bt_audio_codec_cfg_get_freq(codec_cfg); frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); chan_allocation_err = bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); - if (freq_hz < 0) { - LOG_DBG("Error: Invalid codec frequency."); + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret < 0) { + LOG_DBG("Error: Invalid codec frequency: %d", ret); return -EINVAL; } From 86763727f00ea57971a7b84998003605df49ae2a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 28 Sep 2023 07:38:32 +0100 Subject: [PATCH 1294/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: ae2aeedfe8bb66f7fdddc25271689144d3579959 Brings following Zephyr relevant fixes: - 268433e zephyr: Allow user-defined boot serial extensions - 50f8b5f bootutil: Add shared data support for XIP with revert mode - 8d0b35a bootutil: Add mode for XIP with revert Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 61aa543ba4f..98a13d4216e 100644 --- a/west.yml +++ b/west.yml @@ -287,7 +287,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 6c8c76fc37f10d7f3ce44474dc2a450f61ff46e0 + revision: ae2aeedfe8bb66f7fdddc25271689144d3579959 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From c9686e18b6f75844c7ae3ed4df97e553b5978e5d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 28 Sep 2023 12:22:30 +0200 Subject: [PATCH 1295/4498] dts: bindings: nxp,kinetis-*: do not re-specify pinctrl-0 type It's already defined in pinctrl-device.yaml. Signed-off-by: Gerard Marull-Paretas --- dts/bindings/i2c/nxp,kinetis-i2c.yaml | 1 - dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml | 1 - dts/bindings/pwm/nxp,kinetis-tpm.yaml | 1 - dts/bindings/serial/nxp,kinetis-uart.yaml | 1 - dts/bindings/spi/nxp,kinetis-dspi.yaml | 1 - 5 files changed, 5 deletions(-) diff --git a/dts/bindings/i2c/nxp,kinetis-i2c.yaml b/dts/bindings/i2c/nxp,kinetis-i2c.yaml index 86bf2897a93..32c41632140 100644 --- a/dts/bindings/i2c/nxp,kinetis-i2c.yaml +++ b/dts/bindings/i2c/nxp,kinetis-i2c.yaml @@ -15,5 +15,4 @@ properties: required: true pinctrl-0: - type: phandles required: true diff --git a/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml b/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml index 5dd363efb05..fd195c12086 100644 --- a/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml +++ b/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml @@ -12,7 +12,6 @@ properties: const: 3 pinctrl-0: - type: phandles required: true pwm-cells: diff --git a/dts/bindings/pwm/nxp,kinetis-tpm.yaml b/dts/bindings/pwm/nxp,kinetis-tpm.yaml index 1035b5242b6..7c710a5e39c 100644 --- a/dts/bindings/pwm/nxp,kinetis-tpm.yaml +++ b/dts/bindings/pwm/nxp,kinetis-tpm.yaml @@ -15,7 +15,6 @@ properties: required: true pinctrl-0: - type: phandles required: true "#pwm-cells": diff --git a/dts/bindings/serial/nxp,kinetis-uart.yaml b/dts/bindings/serial/nxp,kinetis-uart.yaml index 6a109b20143..394ce11bea5 100644 --- a/dts/bindings/serial/nxp,kinetis-uart.yaml +++ b/dts/bindings/serial/nxp,kinetis-uart.yaml @@ -15,5 +15,4 @@ properties: required: true pinctrl-0: - type: phandles required: true diff --git a/dts/bindings/spi/nxp,kinetis-dspi.yaml b/dts/bindings/spi/nxp,kinetis-dspi.yaml index 8d01c74e04e..61746937c39 100644 --- a/dts/bindings/spi/nxp,kinetis-dspi.yaml +++ b/dts/bindings/spi/nxp,kinetis-dspi.yaml @@ -36,7 +36,6 @@ properties: select assert. If not set, the minimum supported delay is used. pinctrl-0: - type: phandles required: true nxp,rx-tx-chn-share: From fe61d65b2e42e4bdccdc49a9cbbd3f5248c8a5ae Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Mon, 25 Sep 2023 13:41:11 -0700 Subject: [PATCH 1296/4498] net: conn_mgr: Fix connectivity event enum type Connectivity event enum type was erroneously named net_event_ethernet_cmd. This PR corrects the name to net_event_conn_cmd. Signed-off-by: Georges Oates_Larsen --- include/zephyr/net/conn_mgr_connectivity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 0af270cd5b9..6bbcdeda91a 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -39,7 +39,7 @@ extern "C" { NET_MGMT_EVENT_BIT) #define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) -enum net_event_ethernet_cmd { +enum net_event_conn_cmd { NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, NET_EVENT_CONN_CMD_IF_FATAL_ERROR, }; From 98a506f3412fafd1fc8e4b1aeae9bbe10be56ba3 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Thu, 10 Aug 2023 11:41:23 -0700 Subject: [PATCH 1297/4498] net: conn_mgr: Write documentation Write documentation for conn_mgr and its subsystems, especially guidelines for writing connectivity implementations Signed-off-by: Georges Oates_Larsen --- doc/connectivity/networking/api/net_if.rst | 4 + doc/connectivity/networking/api/net_mgmt.rst | 2 + .../networking/conn_mgr/figures/.gitignore | 2 + .../integration_diagram_detailed.drawio | 205 ++++++++ .../figures/integration_diagram_detailed.svg | 3 + .../integration_diagram_simplified.drawio | 100 ++++ .../integration_diagram_simplified.svg | 3 + .../networking/conn_mgr/implementation.rst | 475 ++++++++++++++++++ .../networking/conn_mgr/index.rst | 10 + doc/connectivity/networking/conn_mgr/main.rst | 446 ++++++++++++++++ doc/connectivity/networking/index.rst | 1 + include/zephyr/net/conn_mgr_connectivity.h | 39 +- .../zephyr/net/conn_mgr_connectivity_impl.h | 26 +- include/zephyr/net/conn_mgr_monitor.h | 25 +- subsys/net/CMakeLists.txt | 5 +- subsys/net/conn_mgr/conn_mgr_private.h | 3 + 16 files changed, 1316 insertions(+), 33 deletions(-) create mode 100644 doc/connectivity/networking/conn_mgr/figures/.gitignore create mode 100644 doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.drawio create mode 100644 doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.svg create mode 100644 doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.drawio create mode 100644 doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.svg create mode 100644 doc/connectivity/networking/conn_mgr/implementation.rst create mode 100644 doc/connectivity/networking/conn_mgr/index.rst create mode 100644 doc/connectivity/networking/conn_mgr/main.rst diff --git a/doc/connectivity/networking/api/net_if.rst b/doc/connectivity/networking/api/net_if.rst index f2cf7ca521f..590e328df9f 100644 --- a/doc/connectivity/networking/api/net_if.rst +++ b/doc/connectivity/networking/api/net_if.rst @@ -31,6 +31,8 @@ pointer or by a network interface index. The network interface can be resolved from its index by calling ``net_if_get_by_index()`` and from interface pointer by calling ``net_if_get_by_iface()``. +.. _net_if_interface_ip_management: + The IP address for network devices must be set for them to be connectable. In a typical dynamic network environment, IP addresses are set automatically by DHCPv4, for example. If needed though, the application can set a device's @@ -55,6 +57,8 @@ network technology supports promiscuous mode, then it is possible to receive all the network packets that the network device driver is able to receive. See :ref:`promiscuous_interface` API for more details. +.. _net_if_interface_state_management: + Network interface state management ********************************** diff --git a/doc/connectivity/networking/api/net_mgmt.rst b/doc/connectivity/networking/api/net_mgmt.rst index f99089260b6..ed6c512a742 100644 --- a/doc/connectivity/networking/api/net_mgmt.rst +++ b/doc/connectivity/networking/api/net_mgmt.rst @@ -42,6 +42,8 @@ To avoid extra cost, all :c:func:`net_mgmt` calls are direct. Though this may change in a future release, it will not affect the users of this function. +.. _net_mgmt_listening: + Listening to network events *************************** diff --git a/doc/connectivity/networking/conn_mgr/figures/.gitignore b/doc/connectivity/networking/conn_mgr/figures/.gitignore new file mode 100644 index 00000000000..e73bdb62608 --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/figures/.gitignore @@ -0,0 +1,2 @@ +# Ignore drawio backup files +.$* diff --git a/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.drawio b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.drawio new file mode 100644 index 00000000000..5585c18149a --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.drawio @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.svg b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.svg new file mode 100644 index 00000000000..0838db0396d --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_detailed.svg @@ -0,0 +1,3 @@ + + +
network
readiness
events
network...
Application
Application






Zephyr ifaces (bound)



Zephyr ifaces (bound)...
iface
iface
iface
iface
iface
iface
Zephyr ifaces (unbound)



Zephyr ifaces (unbound)...
iface
iface
iface
iface
iface
iface
binding
binding
binding
binding
binding
binding
Connectivity
Implementation
(LTE)
Connectivity...
Connectivity
Implementation
(Wi-Fi)
Connectivity...
Connectivity
Bindings
Connectivi...
Zephyr
ifaces
Zephy...
LTE L2
LTE L2
network
commands
network...
iface state
change events
iface state...
Wi-Fi L2
Wi-Fi L2
iface commands and events,
binding state updates,
network commands
iface commands and events,...
iface commands
and events
iface commands...
iface commands
and events
iface commands...
Connectivity Control
Connectivity Control
Connectivity Monitoring
Connectivity Monitoring
network
commands
network...
Connection Manager
Connection Manager
Text is not SVG - cannot display
\ No newline at end of file diff --git a/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.drawio b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.drawio new file mode 100644 index 00000000000..4796e986b1e --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.drawio @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.svg b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.svg new file mode 100644 index 00000000000..1a65c73aedc --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/figures/integration_diagram_simplified.svg @@ -0,0 +1,3 @@ + + +
network
readiness
events
network...
Application
Application
L2
L2
connectivity
commands
connectivity...
iface commands
and events
iface commands...
iface commands
and events
iface commands...
Connectivity Control
Connectivity Control
Connectivity Monitoring
Connectivity Monitoring
network
commands
network...
Connection Manager
Connection Manager
Zephyr ifaces
Zephyr ifaces
Connectivity Implementations
Connectivity Implementat...
connectivity
commands
and events
connectivity...
iface events
iface events
Text is not SVG - cannot display
\ No newline at end of file diff --git a/doc/connectivity/networking/conn_mgr/implementation.rst b/doc/connectivity/networking/conn_mgr/implementation.rst new file mode 100644 index 00000000000..932ec7668d2 --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/implementation.rst @@ -0,0 +1,475 @@ +.. _conn_mgr_impl: + +Connectivity Implementations +############################ + +.. _conn_mgr_impl_overview: + +Overview +======== + +Connectivity implementations are technology-specific modules that allow specific Zephyr ifaces to support :ref:`Connectivity Control `. +They are responsible for translating generic :ref:`connectivity control API ` calls into hardware-specific operations. +They are also responsible for implementing standardized :ref:`persistence and timeout ` behaviors. + +See the :ref:`implementation guidelines ` for details on writing conformant connectivity implementations. + +.. _conn_mgr_impl_architecture: + +Architecture +============ + +The :ref:`implementation API ` allows connectivity implementations to be :ref:`defined ` at build time using :c:macro:`CONN_MGR_CONN_DEFINE`. + +This creates a static instance of the :c:struct:`conn_mgr_conn_impl` struct, which then stores a reference to the passed in :c:struct:`conn_mgr_conn_api` struct (which should be populated with implementation callbacks). + +Once defined, you can reference implementations by name and bind them to any unbound iface using :c:macro:`CONN_MGR_BIND_CONN`. +Make sure not to accidentally bind two connectivity implementations to a single iface. + +Once the iface is bound, :ref:`connectivity control API ` functions can be called on the iface, and they will be translated to the corresponding implementation functions in :c:struct:`conn_mgr_conn_api`. + +Binding an iface does not directly modify its :c:struct:`iface struct `. + +Instead, an instance of :c:struct:`conn_mgr_conn_binding` is created and appended an internal :ref:`iterable section `. + +This binding structure will contain a reference to the bound iface, the connectivity implementation it is bound to, as well as a pointer to a per-iface :ref:`context pointer `. + +This iterable section can then be iterated over to find out what (if any) connectivity implementation has been bound to a given iface. +This search process is used by most of the functions in the :ref:`connectivity control API `. +As such, these functions should be called sparingly, due to their relatively high search cost. + +A single connectivity implementation may be bound to multiple ifaces. +See :ref:`conn_mgr_impl_guidelines_no_instancing` for more details. + +.. _conn_mgr_integration_diagram_detailed: + +.. figure:: figures/integration_diagram_detailed.svg + :alt: A detailed view of how Connection Manager integrates with Zephyr and the application. + :figclass: align-center + + A detailed view of how Connection Manager integrates with Zephyr and the application. + + See :ref:`here ` for a simplified version. + +.. _conn_mgr_impl_ctx: + +Context Pointer +=============== + +Since a single connectivity implementation may be shared by several Zephyr ifaces, each binding instantiates a context container (of :ref:`configurable type `) unique to that binding. +Each binding is then instantiated with a reference to that container, which implementations can then use to access per-iface state information. + +See also :ref:`conn_mgr_impl_guidelines_binding_access` and :ref:`conn_mgr_impl_guidelines_no_instancing`. + +.. _conn_mgr_impl_defining: + +Defining an implementation +========================== + +A connectivity implementation may be defined as follows: + +.. code-block:: c + + /* Create the API implementation functions */ + int my_connect_impl(struct conn_mgr_conn_binding *const binding) { + /* Cause your underlying technology to associate */ + } + int my_disconnect_impl(struct conn_mgr_conn_binding *const binding) { + /* Cause your underlying technology to disassociate */ + } + void my_init_impl(struct conn_mgr_conn_binding *const binding) { + /* Perform any required initialization for your underlying technology */ + } + + /* Declare the API struct */ + static struct conn_mgr_conn_api my_impl_api = { + .connect = my_connect_impl, + .disconnect = my_disconnect_impl, + .init = my_init_impl, + /* ... so on */ + }; + + /* Define the implementation (named MY_CONNECTIVITY_IMPL) */ + CONN_MGR_CONN_DEFINE(MY_CONNECTIVITY_IMPL, &my_impl_api); + +.. note:: + This does not work unless you also :ref:`declare the context pointer type `. + +.. _conn_mgr_impl_declaring: + +Declaring an implementation publicly +==================================== + +Once defined, you can make a connectivity implementation available to other compilation units by declaring it (in a header file) as follows: + +.. code-block:: c + :caption: ``my_connectivity_header.h`` + + CONN_MGR_CONN_DECLARE_PUBLIC(MY_CONNECTIVITY_IMPL); + +The header file that contains this declaration must be included in any compilation units that need to reference the implementation. + +.. _conn_mgr_impl_declaring_ctx: + +Declaring a context type +======================== + +For :c:macro:`CONN_MGR_CONN_DEFINE` to work, you must declare a corresponding context pointer type. +This is because all connectivity bindings contain a :ref:`conn_mgr_impl_ctx` of their associated context pointer type. + +If you are using :c:macro:`CONN_MGR_CONN_DECLARE_PUBLIC`, declare this type alongside the declaration: + +.. code-block:: c + :caption: ``my_connectivity_impl.h`` + + #define MY_CONNECTIVITY_IMPL_CTX_TYPE struct my_context_type * + CONN_MGR_CONN_DECLARE_PUBLIC(MY_CONNECTIVITY_IMPL); + +Then, make sure to include the header file before calling :c:macro:`CONN_MGR_CONN_DEFINE`: + +.. code-block:: c + :caption: ``my_connectivity_impl.c`` + + #include "my_connectivity_impl.h" + + CONN_MGR_CONN_DEFINE(MY_CONNECTIVITY_IMPL, &my_impl_api); + +Otherwise, it is sufficient to simply declare the context pointer type immediately before the call to :c:macro:`CONN_MGR_CONN_DEFINE`: + +.. code-block:: c + + #define MY_CONNECTIVITY_IMPL_CTX_TYPE struct my_context_type * + CONN_MGR_CONN_DEFINE(MY_CONNECTIVITY_IMPL, &my_impl_api); + +.. note:: + + Naming is important. + Your context pointer type declaration must use the same name as your implementation declaration, but with ``_CTX_TYPE`` appended. + + In the previous example, the context type is named ``MY_CONNECTIVITY_IMPL_CTX_TYPE``, because ``MY_CONNECTIVITY_IMPL`` was used as the connectivity implementation name. + +If your connectivity implementation does not need a context pointer, simply declare the type as void: + +.. code-block:: c + + #define MY_CONNECTIVITY_IMPL_CTX_TYPE void * + +.. _conn_mgr_impl_binding: + +Binding an iface to an implementation +===================================== + +A defined connectivity implementation may be bound to an iface by calling :c:macro:`CONN_MGR_BIND_CONN` anywhere after the iface's device definition: + +.. code-block:: c + + /* Define an iface */ + NET_DEVICE_INIT(my_iface, + /* ... the specifics here don't matter ... */ + ); + + /* Now bind MY_CONNECTIVITY_IMPL to that iface -- + * the name used should match with the above + */ + CONN_MGR_BIND_CONN(my_iface, MY_CONNECTIVITY_IMPL); + +.. _conn_mgr_impl_guidelines: + +Connectivity implementation guidelines +====================================== + +Rather than implement all features centrally, Connection Manager relies on each connectivity implementation to implement many behaviors and features individually. + +This approach allows Connection Manager to remain lean, and allows each connectivity implementation to choose the most appropriate approach to these behaviors for itself. +However, it relies on trust that all connectivity implementations will faithfully implement the features that have been delegated to them. + +To maintain consistency between all connectivity implementations, observe the following guidelines when writing your own implementation: + +.. _conn_mgr_impl_guidelines_timeout_persistence: + +*Completely implement timeout and persistence* +---------------------------------------------- + +All connectivity implementations must offer complete support for :ref:`timeout and persistence `, such that a user can disable or enable these features, regardless of the inherent behavior of the underlying technology. +In other words, no matter how the underlying technology behaves, your implementation must make it appear to the end user to behave exactly as specified in the :ref:`conn_mgr_control_persistence_timeouts` section. + +See :ref:`conn_mgr_impl_timeout_persistence` for a detailed technical discussion on implementing timeouts and persistence. + +.. _conn_mgr_impl_guidelines_conformity: + +*Conform to API specifications* +------------------------------- + +Each :c:struct:`implementation API function ` you implement should behave as-described in the corresponding connectivity control API function. + +For example, your implementation of :c:member:`conn_mgr_conn_api.connect` should conform to the behavior described for :c:func:`conn_mgr_if_connect`. + +.. _conn_mgr_impl_guidelines_preconfig: + +*Allow connectivity pre-configuration* +-------------------------------------- + +Connectivity implementations should provide means for applications to pre-configure all necessary connection parameters (for example, network SSID, or PSK, if applicable), before the call to :c:func:`conn_mgr_if_connect`. +It should not be necessary to provide this information as part of, or following the :c:func:`conn_mgr_if_connect` call, although implementations :ref:`should await this information if it is not provided `. + +.. _conn_mgr_impl_guidelines_await_config: + +*Await valid connectivity configuration* +---------------------------------------- + +If network association fails because the application pre-configured invalid connection parameters, or did not configure connection parameters at all, this should be treated as a network failure. + +In other words, the connectivity implementation should not give up on the connection attempt, even if valid connection parameters have not been configured. + +Instead, the connectivity implementation should asynchronously wait for valid connection parameters to be configured, either indefinitely, or until the configured :ref:`connectivity timeout ` elapses. + +.. _conn_mgr_impl_guidelines_iface_state_reporting: + +*Implement iface state reporting* +--------------------------------- + +All connectivity implementations must keep bound iface state up to date. + +To be specific: + +* Set the iface to dormant, carrier-down, or both during :c:member:`binding init `. + + * See :ref:`net_if_interface_state_management` for details regarding iface carrier and dormant states. + +* Update dormancy and carrier state so that the iface is non-dormant and carrier-up whenever (and only when) association is complete and connectivity is ready. +* Set the iface either to dormant or to carrier-down as soon as interruption of service is detected. + + * It is acceptable to gate this behind a small timeout (separate from the connection timeout) for network technologies where service is commonly intermittent. + +* If the technology also handles IP assignment, ensure those IP addresses are :ref:`assigned to the iface `. + +.. note:: + + iface state updates do not necessarily need to be performed directly by connectivity implementations. + + For instance: + + * IP assignment is not necessary if :ref:`DHCP ` is used for the iface. + * The connectivity implementation does not need to update iface dormancy if the underlying :ref:`L2 implementation ` already does so. + +.. _conn_mgr_impl_guidelines_iface_state_writeonly: + +*Do not use iface state as implementation state* +------------------------------------------------ + +Zephyr ifaces may be accessed from other threads without respecting the binding mutex. +As such, Zephyr iface state may change unpredictably during connectivity implementation callbacks. + +Therefore, do not base implementation behaviors on iface state. + +Keep iface state updated to reflect network availability, but do not read iface state for any purpose. + +If you need to keep track of dormancy or IP assignment, use a separate state variable stored in the :ref:`context pointer `. + +.. _conn_mgr_impl_guidelines_non_interference: + +*Remain non-interferent* +------------------------ + +Connectivity implementations should not prevent applications from interacting directly with associated technology-specific APIs. + +In other words, it should be possible for an application to directly use your underlying technology without breaking your connectivity implementation. + +If exceptions to this are absolutely necessary, they should be constrained to specific API calls and should be documented. + +.. note:: + + While connectivity implementations must not break, it is acceptable for implementations to have potentially unexpected behavior if applications attempt to directly control the association state. + + For instance, if an application directly instructs an underlying technology to dissassociate, it would be acceptable for the connectivity implementation to interpret this as an unexpected connection loss and immediately attempt to re-associate. + +.. _conn_mgr_impl_guidelines_non_blocking: + +*Remain non-blocking* +--------------------- + +All connectivity implementation callbacks should be non-blocking. + +For instance, calls to :c:member:`conn_mgr_conn_api.connect` should initiate a connection process and return immediately. + +One exception is :c:member:`conn_mgr_conn_api.init`, whose implementations are permitted to block. + +However, bear in mind that blocking during this callback will delay system init, so still consider offloading time-consuming tasks to a background thread. + +.. _conn_mgr_impl_guidelines_immediate_api_readiness: + +*Make API immediately ready* +---------------------------- + +Connectivity implementations must be ready to receive API calls immediately after :c:member:`conn_mgr_conn_api.init`. + +For instance, a call to :c:member:`conn_mgr_conn_api.connect` must eventually lead to an association attempt, even if called immediately after :c:member:`conn_mgr_conn_api.init`. + +If the underlying technology cannot be made ready for connect commands immediately when :c:member:`conn_mgr_conn_api.init` is called, calls to :c:member:`conn_mgr_conn_api.connect` must be queued in a non-blocking fashion, and then executed later when ready. + +.. _conn_mgr_impl_guidelines_context_pointer: + +*Do not store state information outside the context pointer* +------------------------------------------------------------ + +Connection Manager provides a context pointer to each binding. + +Connectivity implementations should store all state information in this context pointer. + +The only exception is connectivity implementations that are meant to be bound to only a single iface. +Such implementations may use statically declared state instead. + +See also :ref:`conn_mgr_impl_guidelines_no_instancing`. + +.. _conn_mgr_impl_guidelines_iface_access: + +*Access ifaces only through binding structs* +-------------------------------------------- + +Do not use statically declared ifaces or externally acquire references to ifaces. + +For example, do not use :c:func:`net_if_get_default` under the assumption that the bound iface will be the default iface. + +Instead, always use the :c:member:`iface pointer ` provided by the relevant :c:struct:`binding struct `. +See also :ref:`conn_mgr_impl_guidelines_binding_access`. + +.. _conn_mgr_impl_guidelines_bindings_optional: + +*Make implementations optional at compile-time* +----------------------------------------------- + +Connectivity implementations should provide a Kconfig option to enable or disable the implementation without affecting bound iface availability. + +In other words, it should be possible to configure builds that include Connectivity Manager, as well as the iface that would have been bound to the implementation, but not the implementation itself, nor its binding. + +.. _conn_mgr_impl_guidelines_no_instancing: + +*Do not instance implementations* +--------------------------------- + +Do not declare a separate connectivity implementation for every iface you are going to bind to. + +Instead, bind one global connectivity implementation to all of your ifaces, and use the context pointer to store state relevant to individual ifaces. + +See also :ref:`conn_mgr_impl_guidelines_binding_access` and :ref:`conn_mgr_impl_guidelines_iface_access`. + +.. _conn_mgr_impl_guidelines_binding_access: + +*Do not access bindings without locking them* +--------------------------------------------- + +Bindings may be accessed and modified at random by multiple threads, so modifying or reading from a binding without first :c:func:`locking it ` may lead to unpredictable behavior. + +This applies to all descendents of the binding, including anything in the :ref:`context container `. + +Make sure to :c:func:`unlock ` the binding when you are done accessing it. + +.. note:: + + A possible exception to this rule is if the resource in question is inherently thread-safe. + + However, be careful taking advantage of this exception. + It may still be possible to create a race condition, for instance when accessing multiple thread-safe resources simultaneously. + + Therefore, it is recommended to simply always lock the binding, whether or not the resource being accessed is inherently thread-safe. + +.. _conn_mgr_impl_guidelines_support_builtins: + +*Do not disable built-in features* +---------------------------------- + +Do not attempt to prevent the use of built-in features (such as :ref:`conn_mgr_control_persistence_timeouts` or :ref:`conn_mgr_control_automations`). + +All connectivity implementations must fully support these features. +Implementations must not attempt to force certain features to be always enabled or always disabled. + +.. _conn_mgr_impl_guidelines_trigger_events: + +*Trigger connectivity control events* +------------------------------------- + +Connectivity control :ref:`network management ` events are not triggered automatically by Connection Manager. + +Connectivity implementations must trigger these events themselves. + +Trigger :c:macro:`NET_EVENT_CONN_CMD_IF_TIMEOUT` when a connection :ref:`timeout ` occurs. +See :ref:`conn_mgr_control_events_timeout` for details. + +Trigger :c:macro:`NET_EVENT_CONN_IF_FATAL_ERROR` when a fatal (non-recoverable) connection error occurs. +See :ref:`conn_mgr_control_events_fatal_error` for details. + +See :ref:`net_mgmt_interface` for details on firing network management events. + +.. _conn_mgr_impl_timeout_persistence: + +Implementing timeouts and persistence +===================================== + +First, see :ref:`conn_mgr_control_persistence_timeouts` for a high-level description of the expected behavior of timeouts and persistence. + +Connectivity implementations must fully conform to that description, regardless of the behavior of the underlying connectivity technology. + +Sometimes this means writing extra logic in the connectivity implementation to fake certain behaviors. +The following sections discuss various common edge-cases and nuances and how to handle them. + +.. _conn_mgr_impl_tp_inherent_persistence: + +*Inherently persistent technologies* +------------------------------------ + +If the underlying technology automatically attempts to reconnect or retry connection after connection loss or failure, the connectivity implementation must manually cancel such attempts when they are in conflict with timeout or persistence settings. + +For example: + + * If the underlying technology automatically attempts to reconnect after losing connection, and persistence is disabled for the iface, the connectivity implementation should immediately cancel this reconnection attempt. + * If a connection attempt times out on an iface whose underlying technology does not have a built-in timeout, the connectivity implementation must simulate a timeout by cancelling the connection attempt manually. + +.. _conn_mgr_impl_tp_inherent_nonpersistence: + +*Technologiess that give up on connection attempts* +--------------------------------------------------- + +If the underlying technology has no mechanism to retry connection attempts, or would give up on them before the user-configured timeout, or would not reconnect after connection loss, the connectivity implementation must manually re-request connection to counteract these deviances. + +* If your underlying technology is not persistent, you must manually trigger reconnect attempts when persistence is enabled. +* If your underlying technology does not support a timeout, you must manually cancel connection attempts if the timeout is enabled. +* If your underlying technology forces a timeout, you must manually trigger a new connection attempts if that timeout is shorter than the Connection Manager timeout. + +.. _conn_mgr_impl_tp_assoc_retry: + +*Technologies with association retry* +------------------------------------- + +Many underlying technologies do not usually associate in a single attempt. + +Instead, these underlying technologies may need to make multiple back-to-back association attempts in a row, usually with a small delay. + +In these situations, the connectivity implementation should treat this series of back-to-back association sub-attempts as a single unified connection attempt. + +For instance, after a sub-attempt failure, persistence being disabled should not prevent further sub-attempts, since they all count as one single overall connection attempt. +See also :ref:`conn_mgr_impl_tp_persistence_during_connect`. + +At which point a series of failed sub-attempts should be considered a failure of the connection attempt as a whole is up to each implementation to decide. + +If the connection attempt crosses this threshold, but the configured timeout has not yet elapsed, or there is no timeout, sub-attempts should continue. + +.. _conn_mgr_impl_tp_persistence_during_connect: + +*Persistence during connection attempts* +---------------------------------------- + +Persistence should not affect any aspect of implementation behavior during a connection attempt. +Persistence should only affect whether or not connection attempts are automatically triggered after a connection loss. + +The configured timeout should fully determine whether connection retry should be performed. + +.. _conn_mgr_impl_api: + +Implementation API +================== + +Include header file :file:`include/zephyr/net/conn_mgr_connectivity_impl.h` to access these. + +Only for use by connectivity implementations. + +.. doxygengroup:: conn_mgr_connectivity_impl diff --git a/doc/connectivity/networking/conn_mgr/index.rst b/doc/connectivity/networking/conn_mgr/index.rst new file mode 100644 index 00000000000..75129877fc9 --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/index.rst @@ -0,0 +1,10 @@ +.. _conn_mgr_docs: + +Connection Manager +################## + +.. toctree:: + :maxdepth: 1 + + main.rst + implementation.rst diff --git a/doc/connectivity/networking/conn_mgr/main.rst b/doc/connectivity/networking/conn_mgr/main.rst new file mode 100644 index 00000000000..4bde856f0ce --- /dev/null +++ b/doc/connectivity/networking/conn_mgr/main.rst @@ -0,0 +1,446 @@ +.. _conn_mgr_overview: + +Overview +######## + +Connection Manager is a collection of optional Zephyr features that aim to allow applications to monitor and control connectivity (access to IP-capable networks) with minimal concern for the specifics of underlying network technologies. + +Using Connection Manager, applications can use a single abstract API to control network association and monitor Internet access, and avoid excessive use of technology-specific boilerplate. + +This allows an application to potentially support several very different connectivity technologies (for example, Wi-Fi and LTE) with a single codebase. + +Applications can also use Connection Manager to generically manage and use multiple connectivity technologies simultaneously. + +Structure +========= + +Connection Manager is split into the following two subsystems: + +* :ref:`Connectivity monitoring ` (header file :file:`include/zephyr/net/conn_mgr_monitoring.h`) monitors all available :ref:`Zephyr network interfaces (ifaces) ` and triggers :ref:`network management ` events indicating when IP connectivity is gained or lost. + +* :ref:`Connectivity control ` (header file :file:`include/zephyr/net/conn_mgr_connectivity.h`) provides an abstract API for controlling iface network association. + +.. _conn_mgr_integration_diagram_simple: + +.. figure:: figures/integration_diagram_simplified.svg + :alt: A simplified view of how Connection Manager integrates with Zephyr and the application. + :figclass: align-center + + A simplified view of how Connection Manager integrates with Zephyr and the application. + + See :ref:`here ` for a more detailed version. + +.. _conn_mgr_monitoring: + +Connectivity monitoring +####################### + +Connectivity monitoring tracks all available ifaces (whether or not they support :ref:`Connectivity control `) as they transition through various :ref:`operational states ` and acquire or lose assigned IP addresses. + +Each available iface is considered ready if it meets the following criteria: + +* The iface is admin-up + + * This means the iface has been instructed to become operational-up (ready for use). This is done by a call to :c:func:`net_if_up`. + +* The iface is oper-up + + * This means the interface is completely ready for use; It is online, and if applicable, has associated with a network. + * See :ref:`net_if_interface_state_management` for details. + +* The iface has at least one assigned IP address + + * Both IPv4 and IPv6 addresses are acceptable. + This condition is met as soon as one or both of these is assigned. + * See :ref:`net_if_interface` for details on iface IP assignment. + +* The iface has not been ignored + + * Ignored ifaces are always treated as unready. + * See :ref:`conn_mgr_monitoring_ignoring_ifaces` for more details. + +.. note:: + + Typically, iface state and IP assignment are updated either by the iface's :ref:`L2 implementation ` or bound :ref:`connectivity implementation `. + + See :ref:`conn_mgr_impl_guidelines_iface_state_reporting` for details. + +A ready iface ceases to be ready the moment any of the above conditions is lost. + +When at least one iface is ready, the :c:macro:`NET_EVENT_L4_CONNECTED` :ref:`network management ` event is triggered, and IP connectivity is said to be ready. + +Afterwards, ifaces can become ready or unready without firing additional events, so long as there always remains at least one ready iface. + +When there are no longer any ready ifaces left, the :c:macro:`NET_EVENT_L4_DISCONNECTED` :ref:`network management ` event is triggered, and IP connectivity is said to be unready. + +.. _conn_mgr_monitoring_usage: + +Usage +===== + +Connectivity monitoring is enabled if the :kconfig:option:`CONFIG_NET_CONNECTION_MANAGER` Kconfig option is enabled. + +To receive connectivity updates, create and register a listener for the :c:macro:`NET_EVENT_L4_CONNECTED` and :c:macro:`NET_EVENT_L4_DISCONNECTED` :ref:`network management ` events: + +.. code-block:: c + + /* Callback struct where the callback will be stored */ + struct net_mgmt_event_callback l4_callback; + + /* Callback handler */ + static void l4_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, struct net_if *iface) + { + if (event == NET_EVENT_L4_CONNECTED) { + LOG_INF("Network connectivity gained!"); + } else if (event == NET_EVENT_L4_DISCONNECTED) { + LOG_INF("Network connectivity lost!"); + } + + /* Otherwise, it's some other event type we didn't register for. */ + } + + /* Call this before Connection Manager monitoring initializes */ + static void my_application_setup(void) + { + /* Configure the callback struct to respond to (at least) the L4_CONNECTED + * and L4_DISCONNECTED events. + * + * + * Note that the callback may also be triggered for events other than those specified here! + * (See the net_mgmt documentation) + */ + net_mgmt_init_event_callback( + &l4_callback, l4_event_handler, + NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED + ); + + /* Register the callback */ + net_mgmt_add_event_callback(&l4_callback); + } + +See :ref:`net_mgmt_listening` for more details on listening for net_mgmt events. + +.. note:: + To avoid missing initial connectivity events, you should register your listener(s) before Connection Manager monitoring initializes. + See :ref:`conn_mgr_monitoring_missing_notifications` for strategies to ensure this. + +.. _conn_mgr_monitoring_missing_notifications: + +Avoiding missed notifications +============================= + +Connectivity monitoring may trigger events immediately upon initialization. + +If your application registers its event listeners after connectivity monitoring initializes, it is possible to miss this first wave of events, and not be informed the first time network connectivity is gained. + +If this is a concern, your application should :ref:`register its event listeners ` before connectivity monitoring initializes. + +Connectivity monitoring initializes using the :c:macro:`SYS_INIT` ``APPLICATION`` initialization priority specified by the :kconfig:option:`CONFIG_NET_CONNECTION_MANAGER_MONITOR_PRIORITY` Kconfig option. + +You can register your callbacks before this initialization by using :c:macro:`SYS_INIT` with an earlier initialization priority than this value, for instance priority 0: + +.. code-block:: C + + static int my_application_setup(void) + { + /* Register callbacks here */ + return 0; + } + + SYS_INIT(my_application_setup, APPLICATION, 0); + +If this is not feasible, you can instead request that connectivity monitoring resend the latest connectivity events at any time by calling :c:func:`conn_mgr_mon_resend_status`: + +.. code-block:: C + + static void my_late_application_setup(void) + { + /* Register callbacks here */ + + /* Once done, request that events be re-triggered */ + conn_mgr_mon_resend_status(); + } + +.. _conn_mgr_monitoring_ignoring_ifaces: + +Ignoring ifaces +=============== + +Applications can request that ifaces be ignored by Connection Manager by calling :c:func:`conn_mgr_ignore_iface` with the iface to be ignored. + +Alternatively, an entire :ref:`L2 implementation ` can be ignored by calling :c:func:`conn_mgr_ignore_l2`. + +This has the effect of individually ignoring all the ifaces using that :ref:`L2 implementation `. + +While ignored, the iface is treated by Connection Manager as though it were unready for network traffic, no matter its actual state. + +This may be useful, for instance, if your application has configured one or more ifaces that cannot (or for whatever reason should not) be used to contact the wider Internet. + +:ref:`Bulk convenience functions ` optionally skip ignored ifaces. + +See :c:func:`conn_mgr_ignore_iface` and :c:func:`conn_mgr_watch_iface` for more details. + +.. _conn_mgr_monitoring_api: + +Connectivity monitoring API +=========================== + +Include header file :file:`include/zephyr/net/conn_mgr_monitoring.h` to access these. + +.. doxygengroup:: conn_mgr + +.. _conn_mgr_control: + +Connectivity control +#################### + +Many network interfaces require a network association procedure to be completed before being usable. + +For such ifaces, connectivity control can provide a generic API to request network association (:c:func:`conn_mgr_if_connect`) and dissasociation (:c:func:`conn_mgr_if_disconnect`). +Network interfaces implement support for this API by :ref:`binding themselves to a connectivity implementation `. + +Using this API, applications can associate with networks with minimal technology-specific boilerplate. + +Connectivity control also provides the following additional features: + +* Standardized :ref:`persistence and timeout ` behaviors during association. +* :ref:`Bulk functions ` for controlling the admin state and network association of all available ifaces simultaneously. +* Optional :ref:`convenience automations ` for common connectivity actions. + +.. _conn_mgr_control_operation: + +Basic operation +=============== + +The following sections outline the basic operation of Connection Manager's connectivity control. + +.. _conn_mgr_control_operation_binding: + +Binding +------- + +Before an iface can be commanded to associate or dissasociate using Connection Manager, it must first be bound to a :ref:`connectivity implementation `. +Binding is performed by the provider of the iface, not by the application (see :ref:`conn_mgr_impl_binding`), and can be thought of as an extension of the iface declaration. + +Once an iface is bound, all connectivity commands passed to it (such as :c:func:`conn_mgr_if_connect` or :c:func:`conn_mgr_if_disconnect`) will be routed to the corresponding implementation function in the connectivity implementation. + +.. note:: + + To avoid inconsistent behavior, all connectivity implementations must adhere to the :ref:`implementation guidelines `. + +.. _conn_mgr_control_operation_connecting: + +Connecting +---------- + +Once a bound iface is admin-up (see :ref:`net_if_interface_state_management`), :c:func:`conn_mgr_if_connect` can be called to cause it to associate with a network. + +If association succeeds, the connectivity implementation will mark the iface as operational-up (see :ref:`net_if_interface_state_management`). + +If association fails unrecoverably, the :ref:`fatal error event ` will be triggered. + +You can configure an optional :ref:`timeout ` for this process. + +.. note:: + The :c:func:`conn_mgr_if_connect` function is intentionally minimalistic, and does not take any kind of configuration. + Each connectivity implementation should provide a way to pre-configure or automatically configure any required association settings or credentials. + See :ref:`conn_mgr_impl_guidelines_preconfig` for details. + +.. _conn_mgr_control_operation_loss: + +Connection loss +--------------- + +If connectivity is lost due to external factors, the connectivity implementation will mark the iface as operational-down. + +Depending on whether :ref:`persistence ` is set, the iface may then attempt to reconnect. + +.. _conn_mgr_control_operation_disconnection: + +Manual disconnection +-------------------- + +The application can also request that connectivity be intentionally abandoned by calling :c:func:`conn_mgr_if_disconnect`. + +In this case, the connectivity implementation will disassociate the iface from its network and mark the iface as operational-down (see :ref:`net_if_interface_state_management`). +A new connection attempt will not be initiated, regardless of whether persistence is enabled. + +.. _conn_mgr_control_persistence_timeouts: + +Timeouts and Persistence +======================== + +Connection Manager requires that all connectivity implementations support the following standard key features: + +* :ref:`Connection timeouts ` +* :ref:`Connection persistence ` + +These features describe how ifaces should behave during connect and disconnect events. +You can individually set them for each iface. + +.. note:: + It is left to connectivity implementations to successfully and accurately implement these two features as described below. + See :ref:`conn_mgr_impl_timeout_persistence` for more details from the connectivity implementation perspective. + +.. _conn_mgr_control_timeouts: + +Connection Timeouts +------------------- + +When :c:func:`conn_mgr_if_connect` is called on an iface, a connection attempt begins. + +The connection attempt continues indefinitely until it succeeds, unless a timeout has been specified for the iface (using :c:func:`conn_mgr_if_set_timeout`). + +In that case, the connection attempt will be abandoned if the timeout elapses before it succeeds. +If this happens, the :ref:`timeout event` is raised. + +.. _conn_mgr_control_persistence: + +Connection Persistence +---------------------- + +Each iface also has a connection persistence setting that you can enable or disable by setting the :c:enumerator:`~conn_mgr_if_flag.CONN_MGR_IF_PERSISTENT` flag with :c:func:`conn_mgr_binding_set_flag`. + +This setting specifies how the iface should handle unintentional connection loss. + +If persistence is enabled, any unintentional connection loss will initiate a new connection attempt, with a new timeout if applicable. + +Otherwise, the iface will not attempt to reconnect. + +.. note:: + Persistence not does affect connection attempt behavior. + Only the timeout setting affects this. + + For instance, if a connection attempt on an iface times out, the iface will not attempt to reconnect, even if it is persistent. + + Conversely, if there is not a specified timeout, the iface will try to connect forever until it succeeds, even if it is not persistent. + + See :ref:`conn_mgr_impl_tp_persistence_during_connect` for the equivalent implementation guideline. + +.. _conn_mgr_control_events: + +Control events +============== + +Connectivity control triggers :ref:`network management ` events to inform the application of important state changes. + +See :ref:`conn_mgr_impl_guidelines_trigger_events` for the corresponding connectivity implementation guideline. + +.. _conn_mgr_control_events_fatal_error: + +Fatal Error +----------- + +The :c:macro:`NET_EVENT_CONN_IF_FATAL_ERROR` event is raised when an iface encounters an error from which it cannot recover (meaning any subsequent attempts to associate are guaranteed to fail, and all such attempts should be abandoned). + +Handlers of this event will be passed a pointer to the iface for which the fatal error occurred. +Individual connectivity implementations may also pass an application-specific data pointer. + +.. _conn_mgr_control_events_timeout: + +Timeout +------- + +The :c:macro:`NET_EVENT_CONN_IF_TIMEOUT` event is raised when an :ref:`iface association ` attempt :ref:`times out `. + +Handlers of this event will be passed a pointer to the iface that timed out attempting to associate. + +.. _conn_mgr_control_events_listening: + +Listening for control events +---------------------------- + +You can listen for control events as follows: + +.. code-block:: c + + /* Declare a net_mgmt callback struct to store the callback */ + struct net_mgmt_event_callback my_conn_evt_callback; + + /* Declare a handler to receive control events */ + static void my_conn_evt_handler(struct net_mgmt_event_callback *cb, + uint32_t event, struct net_if *iface) + { + if (event == NET_EVENT_CONN_IF_TIMEOUT) { + /* Timeout occurred, handle it */ + } else if (event == NET_EVENT_CONN_IF_FATAL_ERROR) { + /* Fatal error occurred, handle it */ + } + + /* Otherwise, it's some other event type we didn't register for. */ + } + + int main() + { + /* Configure the callback struct to respond to (at least) the CONN_IF_TIMEOUT + * and CONN_IF_FATAL_ERROR events. + * + * Note that the callback may also be triggered for events other than those specified here! + * (See the net_mgmt documentation) + */ + + net_mgmt_init_event_callback( + &conn_mgr_conn_callback, conn_mgr_conn_handler, + NET_EVENT_CONN_IF_TIMEOUT | NET_EVENT_CONN_IF_FATAL_ERROR + ); + + /* Register the callback */ + net_mgmt_add_event_callback(&conn_mgr_conn_callback); + return 0; + } + +See :ref:`net_mgmt_listening` for more details on listening for net_mgmt events. + +.. _conn_mgr_control_automations: + +Automated behaviors +=================== + +There are a few actions related to connectivity that are (by default at least) performed automatically for the user. + +.. _conn_mgr_control_automations_auto_up: + +.. topic:: Automatic admin-up + + In Zephyr, ifaces are automatically taken admin-up (see :ref:`net_if_interface_state_management` for details on iface states) during initialization. + + Applications can disable this behavior by setting the :c:enumerator:`~net_if_flag.NET_IF_NO_AUTO_START` interface flag with :c:func:`net_if_flag_set`. + +.. _conn_mgr_control_automations_auto_connect: + +.. topic:: Automatic connect + + By default, Connection Manager will automatically connect any :ref:`bound ` iface that becomes admin-up. + + Applications can disable this by setting the :c:enumerator:`~conn_mgr_if_flag.CONN_MGR_IF_NO_AUTO_CONNECT` connectivity flag with :c:func:`conn_mgr_if_set_flag`. + +.. _conn_mgr_control_automations_auto_down: + +.. topic:: Automatic admin-down + + By default, Connection Manager will automatically take any bound iface admin-down if it has given up on associating. + + Applications can disable this for all ifaces by disabling the :kconfig:option:`CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN` Kconfig option, or for individual ifaces by setting the :c:enumerator:`~conn_mgr_if_flag.CONN_MGR_IF_NO_AUTO_DOWN` connectivity flag with with :c:func:`conn_mgr_if_set_flag`. + +.. _conn_mgr_control_api: + +Connectivity control API +======================== + +Include header file :file:`include/zephyr/net/conn_mgr_connectivity.h` to access these. + +.. doxygengroup:: conn_mgr_connectivity + +.. _conn_mgr_control_api_bulk: + +Bulk API +-------- + +Connectivity control provides several bulk functions allowing all ifaces to be controlled at once. + +You can restrict these functions to operate only on non-:ref:`ignored ` ifaces if desired. + +Include header file :file:`include/zephyr/net/conn_mgr_connectivity.h` to access these. + +.. doxygengroup:: conn_mgr_connectivity_bulk diff --git a/doc/connectivity/networking/index.rst b/doc/connectivity/networking/index.rst index 8f25a823879..f900bb56330 100644 --- a/doc/connectivity/networking/index.rst +++ b/doc/connectivity/networking/index.rst @@ -16,3 +16,4 @@ operation of the stacks and how they were implemented. networking_with_host.rst network_monitoring.rst api/index.rst + conn_mgr/index.rst diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 6bbcdeda91a..0d92cdbf8d7 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -39,18 +39,25 @@ extern "C" { NET_MGMT_EVENT_BIT) #define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) +/** @endcond */ + enum net_event_conn_cmd { NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, NET_EVENT_CONN_CMD_IF_FATAL_ERROR, }; +/** + * @brief net_mgmt event raised when a connection attempt times out + */ #define NET_EVENT_CONN_IF_TIMEOUT \ (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_TIMEOUT) +/** + * @brief net_mgmt event raised when a non-recoverable connectivity error occurs on an iface + */ #define NET_EVENT_CONN_IF_FATAL_ERROR \ (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_FATAL_ERROR) -/** @endcond */ /** * @brief Per-iface connectivity flags @@ -76,7 +83,7 @@ enum conn_mgr_if_flag { * No auto-down * * When set, conn_mgr will not automatically take the iface admin-down when it stops - * trying to connect, even if NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled. + * trying to connect, even if CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled. */ CONN_MGR_IF_NO_AUTO_DOWN, @@ -86,7 +93,9 @@ enum conn_mgr_if_flag { /** @endcond */ }; -/** Value to use with @ref conn_mgr_conn_binding.timeout to indicate no timeout */ +/** Value to use with @ref conn_mgr_if_set_timeout and @ref conn_mgr_conn_binding.timeout to + * indicate no timeout + */ #define CONN_MGR_IF_NO_TIMEOUT 0 /** @@ -95,7 +104,7 @@ enum conn_mgr_if_flag { * If the provided iface has been bound to a connectivity implementation, initiate * network connect/association. * - * Automatically takes the iface admin-up (by calling net_if_up) if it isn't already. + * Automatically takes the iface admin-up (by calling @ref net_if_up) if it isn't already. * * Non-Blocking. * @@ -231,23 +240,27 @@ int conn_mgr_if_get_timeout(struct net_if *iface); * * @param iface - Pointer to the network interface to modify. * @param timeout - The timeout value to set (in seconds). - * Pass CONN_MGR_IF_NO_TIMEOUT to disable the timeout. + * Pass @ref CONN_MGR_IF_NO_TIMEOUT to disable the timeout. * @retval 0 on success. * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation. */ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); /** - * @brief Initialize all connectivity implementation bindings - * - * + * @} + */ + +/** + * @brief Connection Manager Bulk API + * @defgroup conn_mgr_connectivity_bulk Connection Manager Connectivity Bulk API + * @ingroup networking + * @{ */ -void conn_mgr_conn_init(void); /** * @brief Convenience function that takes all available ifaces into the admin-up state. * - * Essentially a wrapper for net_if_up. + * Essentially a wrapper for @ref net_if_up. * * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. * Otherwise, affect all ifaces. @@ -260,7 +273,7 @@ int conn_mgr_all_if_up(bool skip_ignored); /** * @brief Convenience function that takes all available ifaces into the admin-down state. * - * Essentially a wrapper for net_if_down. + * Essentially a wrapper for @ref net_if_down. * * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. * Otherwise, affect all ifaces. @@ -273,7 +286,7 @@ int conn_mgr_all_if_down(bool skip_ignored); * @brief Convenience function that takes all available ifaces into the admin-up state, and * connects those that support connectivity. * - * Essentially a wrapper for net_if_up and conn_mgr_if_connect. + * Essentially a wrapper for @ref net_if_up and @ref conn_mgr_if_connect. * * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. * Otherwise, affect all ifaces. @@ -286,7 +299,7 @@ int conn_mgr_all_if_connect(bool skip_ignored); * @brief Convenience function that disconnects all available ifaces that support connectivity * without putting them into admin-down state (unless auto-down is enabled for the iface). * - * Essentially a wrapper for net_if_down. + * Essentially a wrapper for @ref net_if_down. * * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. * Otherwise, affect all ifaces. diff --git a/include/zephyr/net/conn_mgr_connectivity_impl.h b/include/zephyr/net/conn_mgr_connectivity_impl.h index 8e8218bda0b..51b826d3491 100644 --- a/include/zephyr/net/conn_mgr_connectivity_impl.h +++ b/include/zephyr/net/conn_mgr_connectivity_impl.h @@ -41,12 +41,12 @@ struct conn_mgr_conn_binding; struct conn_mgr_conn_api { /** * @brief When called, the connectivity implementation should start attempting to - * establish connectivity for (associate with a network) the bound iface pointed + * establish connectivity (association with a network) for the bound iface pointed * to by if_conn->iface. * * Must be non-blocking. * - * Called by conn_mgr_if_connect. + * Called by @ref conn_mgr_if_connect. */ int (*connect)(struct conn_mgr_conn_binding *const binding); @@ -57,7 +57,7 @@ struct conn_mgr_conn_api { * * Must be non-blocking. * - * Called by conn_mgr_if_disconnect. + * Called by @ref conn_mgr_if_disconnect. */ int (*disconnect)(struct conn_mgr_conn_binding *const binding); @@ -189,7 +189,7 @@ struct conn_mgr_conn_binding { * The connectivity implementation should give up on establishing connectivity after this * timeout, even if persistence is enabled. * - * Set to CONN_MGR_IF_NO_TIMEOUT to indicate that no timeout should be used. + * Set to @ref CONN_MGR_IF_NO_TIMEOUT to indicate that no timeout should be used. */ int timeout; @@ -273,7 +273,7 @@ static inline void conn_mgr_binding_lock(struct conn_mgr_conn_binding *binding) /** * @brief Unlocks the passed-in binding. * - * Call this after any call to conn_mgr_binding_lock once done accessing binding data. + * Call this after any call to @ref conn_mgr_binding_lock once done accessing binding data. * * Reentrant. * @@ -289,13 +289,13 @@ static inline void conn_mgr_binding_unlock(struct conn_mgr_conn_binding *binding /** * @brief Set the value of the specified connectivity flag for the provided binding * - * Can be used from any thread or callback without calling conn_mgr_binding_lock. + * Can be used from any thread or callback without calling @ref conn_mgr_binding_lock. * * For use only by connectivity implementations * - * @param binding - The binding to check - * @param flag - The flag to check - * @param value - New value for the specified flag + * @param binding The binding to check + * @param flag The flag to check + * @param value New value for the specified flag */ static inline void conn_mgr_binding_set_flag(struct conn_mgr_conn_binding *binding, enum conn_mgr_if_flag flag, bool value) @@ -313,13 +313,13 @@ static inline void conn_mgr_binding_set_flag(struct conn_mgr_conn_binding *bindi /** * @brief Check the value of the specified connectivity flag for the provided binding * - * Can be used from any thread or callback without calling conn_mgr_binding_lock. + * Can be used from any thread or callback without calling @ref conn_mgr_binding_lock. * * For use only by connectivity implementations * - * @param binding - The binding to check - * @param flag - The flag to check - * @return bool - The value of the specified flag + * @param binding The binding to check + * @param flag The flag to check + * @return bool The value of the specified flag */ static inline bool conn_mgr_binding_get_flag(struct conn_mgr_conn_binding *binding, enum conn_mgr_if_flag flag) diff --git a/include/zephyr/net/conn_mgr_monitor.h b/include/zephyr/net/conn_mgr_monitor.h index 1bff698a86c..94c50d90f19 100644 --- a/include/zephyr/net/conn_mgr_monitor.h +++ b/include/zephyr/net/conn_mgr_monitor.h @@ -11,7 +11,14 @@ extern "C" { #endif -#if defined(CONFIG_NET_CONNECTION_MANAGER) +#if defined(CONFIG_NET_CONNECTION_MANAGER) || defined(__DOXYGEN__) + +/** + * @brief Connection Manager API + * @defgroup conn_mgr Connection Manager API + * @ingroup networking + * @{ + */ struct net_if; struct net_l2; @@ -31,7 +38,7 @@ void conn_mgr_mon_resend_status(void); * and if the iface was connected before being ignored, events will be fired as though it * disconnected at that moment. * - * @param iface - iface to be ignored. + * @param iface iface to be ignored. */ void conn_mgr_ignore_iface(struct net_if *iface); @@ -44,14 +51,16 @@ void conn_mgr_ignore_iface(struct net_if *iface); * and if the iface was connected before being watched, events will be fired as though * it connected in that moment. * - * @param iface - iface to no longer ignore. + * All ifaces default to watched at boot. + * + * @param iface iface to no longer ignore. */ void conn_mgr_watch_iface(struct net_if *iface); /** * @brief Check whether the provided iface is currently ignored. * - * @param iface - The iface to check. + * @param iface The iface to check. * @retval true if the iface is being ignored by conn_mgr. * @retval false if the iface is being watched by conn_mgr. */ @@ -62,7 +71,7 @@ bool conn_mgr_is_iface_ignored(struct net_if *iface); * * This is a wrapper for conn_mgr_ignore_iface that ignores all ifaces that use the L2. * - * @param l2 - L2 to be ignored. + * @param l2 L2 to be ignored. */ void conn_mgr_ignore_l2(const struct net_l2 *l2); @@ -71,10 +80,14 @@ void conn_mgr_ignore_l2(const struct net_l2 *l2); * * This is a wrapper for conn_mgr_watch_iface that watches all ifaces that use the L2. * - * @param l2 - L2 to watch. + * @param l2 L2 to watch. */ void conn_mgr_watch_l2(const struct net_l2 *l2); +/** + * @} + */ + #else #define conn_mgr_mon_resend_status(...) diff --git a/subsys/net/CMakeLists.txt b/subsys/net/CMakeLists.txt index f9cf4940a43..d8ef4ab0f36 100644 --- a/subsys/net/CMakeLists.txt +++ b/subsys/net/CMakeLists.txt @@ -20,4 +20,7 @@ if(CONFIG_NETWORKING) endif() add_subdirectory(lib) -add_subdirectory_ifdef(CONFIG_NET_CONNECTION_MANAGER conn_mgr) + +if(CONFIG_NET_CONNECTION_MANAGER) + add_subdirectory(conn_mgr) +endif() diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index cf86e4ddc77..99aa98567a3 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -56,4 +56,7 @@ extern struct k_mutex conn_mgr_mon_lock; void conn_mgr_init_events_handler(void); +/* Cause conn_mgr_connectivity to Initialize all connectivity implementation bindings */ +void conn_mgr_conn_init(void); + #endif /* __CONN_MGR_PRV_H__ */ From 034f0fca93d84035d057dccb6c884eac19021a2a Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Thu, 14 Sep 2023 15:52:13 -0700 Subject: [PATCH 1298/4498] MAINTAINERS: Update maintainers/codeowners for conn_mgr docs conn_mgr now has docs, so add them to the maintainers/codeowners files. Signed-off-by: Georges Oates_Larsen --- CODEOWNERS | 1 + MAINTAINERS.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 55d05396f7f..2aabb0a3299 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -220,6 +220,7 @@ /doc/CMakeLists.txt @carlescufi /doc/_scripts/ @carlescufi /doc/connectivity/bluetooth/ @alwa-nordic @jhedberg @Vudentz +/doc/connectivity/networking/conn_mgr @carlescufi @glarsennordic /doc/build/dts/ @galak @mbolivar-ampere /doc/build/sysbuild/ @tejlmand @nordicjm /doc/hardware/peripherals/canbus/ @alexanderwachter @henrikbrixandersen diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index c4cac66dde0..d05c2768577 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1924,6 +1924,7 @@ Networking: - subsys/net/conn_mgr/ - tests/net/conn_mgr_monitor/ - tests/net/conn_mgr_conn/ + - doc/connectivity/networking/conn_mgr/ labels: - "area: Networking" From 0fad5812116aa08f2aeb13f66543fc64f5bbe9be Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 10:54:19 +0200 Subject: [PATCH 1299/4498] doc: connectivity/networking/utils: minor fixes Fixes bugs in USB and DSA group titles (networking) and a minor bug in sys/utils. Signed-off-by: Florian Grandel --- doc/_doxygen/groups.dox | 4 ++-- include/zephyr/net/dsa.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/_doxygen/groups.dox b/doc/_doxygen/groups.dox index cd4efcd6294..dbb67e7e694 100644 --- a/doc/_doxygen/groups.dox +++ b/doc/_doxygen/groups.dox @@ -36,14 +36,14 @@ @brief Connectivity @defgroup connectivity Connectivity @{ +@} @brief USB @defgroup usb USB +@ingroup connectivity @{ @} -@} - @brief Utilities @defgroup utilities Utilities @{ diff --git a/include/zephyr/net/dsa.h b/include/zephyr/net/dsa.h index 755521b1325..479690509a3 100644 --- a/include/zephyr/net/dsa.h +++ b/include/zephyr/net/dsa.h @@ -16,7 +16,7 @@ /** * @brief DSA definitions and helpers - * @defgroup DSA - Distributed Switch Architecture definitions and helpers + * @defgroup DSA Distributed Switch Architecture definitions and helpers * @ingroup networking * @{ */ From 80fc3508497faa0c5af21ca6bfc4c5fd56745015 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 09:00:16 +0200 Subject: [PATCH 1300/4498] doc: ieee802154: improved API documentation structure Improves the API documentation including it's structure and integration into the Zephyr documentation. Previously the API status of the IEEE 802.15.4 API (and its sub-APIs) was unclear. This change adds three APIs in an "unstable" state: - IEEE 802.15.4 L2 for subsystem developers - IEEE 802.15.4 drivers for driver developers - IEEE 802.15.4 net_mgmt for application developers The corresponding APIs are documented at a group level. These sub-APIs need to be separately versioned as they have different audiences, change velocities and levels of stability. Signed-off-by: Florian Grandel --- .../networking/api/ieee802154.rst | 85 +++++++++++++++---- doc/develop/api/overview.rst | 12 +++ include/zephyr/net/ieee802154.h | 61 ++++++++++++- include/zephyr/net/ieee802154_mgmt.h | 12 ++- include/zephyr/net/ieee802154_radio.h | 28 +++++- 5 files changed, 175 insertions(+), 23 deletions(-) diff --git a/doc/connectivity/networking/api/ieee802154.rst b/doc/connectivity/networking/api/ieee802154.rst index ab838477e1f..8801f896f41 100644 --- a/doc/connectivity/networking/api/ieee802154.rst +++ b/doc/connectivity/networking/api/ieee802154.rst @@ -7,30 +7,81 @@ IEEE 802.15.4 :local: :depth: 2 -Overview -******** +Introduction +************ + IEEE 802.15.4 is a technical standard which defines the operation of low-rate -wireless personal area networks (LR-WPANs). For more detailed overview of this -standard, see this -`IEEE 802.15.4 Wikipedia article `_. -Also, see `IEEE GET Program -`_ -for creating an IEEE account and downloading the specification. - -Zephyr supports IEEE 802.15.4 with Thread and 6LoWPAN. The Thread implementation -is based on `OpenThread `_. -The IPv6 header compression in 6LoWPAN is shared with -the Bluetooth IPSP (IP support profile). +wireless personal area networks (LR-WPANs). For a more detailed overview of this +standard, see the `IEEE 802.15.4 Wikipedia article +`_. + +The most recent version of the standard is accessible through the `IEEE GET +Program +`_. +You need to create a free IEEE account and can then downloading it. + +We're currently following the IEEE 802.15.4-2020 specification. This version is +backwards compatible with IEEE 802.15.4-2015, parts of which are contained in +the Thread protocol stack. The 2020 version also includes prior extensions that +were accepted into the standard, namely IEEE 802.15.4g (SUN FSK) and IEEE +802.15.4e (TSCH) which are of relevance to industrial IoT and automation. For +recent developments in UWB ranging technology, see IEEE 802.15.4z which is not +yet integrated into the standard's mainline. + +Whenever sections from the standard are cited in the documentation, they refer +to IEEE 802.15.4-2020 section, table and figure numbering - unless otherwise +specified. + +Zephyr supports bot native IEEE 802.15.4 and Thread with 6LoWPAN. The Thread +implementation is based on `OpenThread `_. The IPv6 +header compression in 6LoWPAN is shared among native IEEE 802.15.4, OpenThread +and the Bluetooth IPSP (IP support profile). API Reference ************* -IEEE 802.15.4 -============= +IEEE 802.15.4 API Overview +========================== + +Gives an introduction and overview over the whole IEEE 802.15.4 subsystem and +all of its APIs, configuration and user interfaces for all audiences. .. doxygengroup:: ieee802154 -IEEE 802.15.4 Management -======================== + +.. _ieee802154_mgmt_api: + +IEEE 802.15.4 Management API +============================ + +This is the main subsystem-specific API of interest to IEEE 802.15.4 +**application developers** as it allows to configure the IEEE 802.15.4 subsystem +at runtime. Other relevant interfaces for application developers are the +typical shell, socket, Kconfig and devicetree APIs that can be accessed through +Zephyr's generic subsystem-independent documentation. Look out for +IEEE802154/ieee802154 prefixes there. .. doxygengroup:: ieee802154_mgmt + + +.. _ieee802154_driver_api: + +IEEE 802.15.4 Driver API +======================== + +This is the main API of interest to IEEE 802.15.4 **driver developers**. + +.. doxygengroup:: ieee802154_driver + + +.. _ieee802154_l2_api: + +IEEE 802.15.4 L2 / Native Stack API +=================================== + +This documents the IEEE 802.15.4 L2 native stack, which neither applications nor +drivers will ever access directly. It is called internally by Zephyr's upper +network layers (L3+), its socket and network context abstractions. This API is +therefore of interest to IEEE 802.15.4 **subsystem contributors** only. + +.. doxygengroup:: ieee802154_l2 diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 8a56b9eae1d..5e0ae969d87 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -169,6 +169,18 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Experimental - 3.2 + * - :ref:`ieee802154_driver_api` + - Unstable + - 1.0 + + * - :ref:`ieee802154_l2_api` + - Unstable + - 1.0 + + * - :ref:`ieee802154_mgmt_api` + - Unstable + - 1.0 + * - :ref:`input` - Experimental - 3.4 diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index 24455b645cc..f85da7e59fd 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -23,9 +23,64 @@ extern "C" { #endif /** - * @brief IEEE 802.15.4 library - * @defgroup ieee802154 IEEE 802.15.4 Library - * @ingroup networking + * @defgroup ieee802154 IEEE 802.15.4 APIs + * @ingroup connectivity + * + * @brief IEEE 802.15.4 L2, configuration and driver APIs + * + * @details The IEEE 802.15.4 subsystem API comprises the native IEEE 802.15.4 + * L2 subsystem ("Soft" MAC), a mostly vendor and protocol agnostic driver API + * shared between the OpenThread and native L2 stacks ("Hard" MAC and PHY) as + * well as several APIs to configure the subsystem (shell, net management, + * Kconfig, devicetree, etc.). + * + * The IEEE 802.15.4 subsystem APIs are exposed at different levels and address + * several audiences: + * - shell (end users, application developers): + * - a set of IEEE 802.15.4 shell commands (see `shell> ieee802154 help`) + * - application API (application developers): + * - IPv6, DGRAM and RAW sockets for actual peer-to-peer, multicast and + * broadcast data exchange between nodes including connection specific + * configuration (sample coming soon, see + * https://github.com/linux-wpan/wpan-tools/tree/master/examples for now + * which inspired our API and therefore has a similar socket API), + * - Kconfig and devicetree configuration options (net config library + * extension, subsystem-wide MAC and PHY Kconfig/DT options, driver/vendor + * specific Kconfig/DT options, watch out for options prefixed with + * IEEE802154/ieee802154), + * - Network Management: runtime configuration of the IEEE 802.15.4 + * protocols stack at the MAC (L2) and PHY (L1) levels + * (see @ref ieee802154_mgmt), + * - driver API (driver maintainers/contributors): + * - see @ref ieee802154_driver + * - a basic, mostly PHY-level driver API to be implemented by all drivers, + * - several "hard MAC" (hardware/firmware offloading) extension points for + * performance critical or timing sensitive aspects of the protocol + * - L2 integration (subsystem contributors): + * - see @ref ieee802154_l2 + * - implementation of Zephyr's internal L2-level socket and network context + * abstractions (context/socket operations, see @ref net_l2), + * - protocol-specific extension to the interface structure (see @ref net_if) + * - protocol-specific extensions to the network packet structure + * (see @ref net_pkt), + */ + +/** + * @defgroup ieee802154_l2 IEEE 802.15.4 L2 + * @ingroup ieee802154 + * + * @brief IEEE 802.15.4 L2 APIs + * + * @details This API provides integration with Zephyr's sockets and network + * contexts. **Application and driver developers should never interface directly + * with this API.** It is of interest to subsystem maintainers only. + * + * The API implements and extends the following structures: + * - implements Zephyr's internal L2-level socket and network context + * abstractions (context/socket operations, see @ref net_l2), + * - protocol-specific extension to the interface structure (see @ref net_if) + * - protocol-specific extensions to the network packet structure + * (see @ref net_pkt), * @{ */ diff --git a/include/zephyr/net/ieee802154_mgmt.h b/include/zephyr/net/ieee802154_mgmt.h index d52abda6271..ff91edd3ab8 100644 --- a/include/zephyr/net/ieee802154_mgmt.h +++ b/include/zephyr/net/ieee802154_mgmt.h @@ -22,9 +22,17 @@ extern "C" { #endif /** + * @defgroup ieee802154_mgmt IEEE 802.15.4 Net Management + * @ingroup ieee802154 + * * @brief IEEE 802.15.4 net management library - * @defgroup ieee802154_mgmt IEEE 802.15.4 Net Management Library - * @ingroup networking + * + * @details The IEEE 802.15.4 net management library provides runtime + * configuration features that applications can interface with directly. + * + * Most of these commands are also accessible via shell commands. See the + * shell's help feature (`shell> ieee802154 help`). + * * @{ */ diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 6a6f01957a8..68864aedc0c 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -27,7 +27,33 @@ extern "C" { #endif /** - * @addtogroup ieee802154 + * @defgroup ieee802154_driver IEEE 802.15.4 Drivers + * @ingroup ieee802154 + * + * @brief IEEE 802.15.4 driver API + * + * @details This API provides a common representation of vendor-specific + * hardware and firmware to the native IEEE 802.15.4 L2 and OpenThread stacks. + * **Application developers should never interface directly with this API.** It + * is of interest to driver maintainers only. + * + * The IEEE 802.15.4 driver API consists of two separate parts: + * - a basic, mostly PHY-level driver API to be implemented by all drivers, + * - several optional MAC-level extension points to offload performance + * critical or timing sensitive aspects at MAC level to the driver hardware + * or firmware ("hard" MAC). + * + * Implementing the basic driver API will ensure integration with the native L2 + * stack as well as basic support for OpenThread. Depending on the hardware, + * offloading to vendor-specific hardware or firmware features may be required + * to achieve full compliance with the Thread protocol or IEEE 802.15.4 + * subprotocols (e.g. fast enough ACK packages, precise timing of timed TX/RX in + * the TSCH or CSL subprotocols). + * + * Whether or not MAC-level offloading extension points need to be implemented + * is to be decided by individual driver maintainers. Upper layers SHOULD + * provide a "soft" MAC fallback whenever possible. + * * @{ */ From 9864d03c6e181ed4555f3a94ee9270ba980a0227 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 10:52:58 +0200 Subject: [PATCH 1301/4498] doc: openthread: integrate ot/ieee802154 docs Integrates and cross-references OpenThread and native IEEE 802.15.4 docs as they share a common driver layer. While OpenThread is of course not an IEEE 802.15.4 subsystem API it is still included in the ieee802154 documentation group, purely for convenience to the documentation readers. For organizational purposes OT is considered a separate area of maintenance and therefore keeps its dedicated documentation page - but the two subsystems now cross-reference each other for convenience. Signed-off-by: Florian Grandel --- .../networking/api/ieee802154.rst | 18 +++++++--- doc/connectivity/networking/api/thread.rst | 22 ++++++++++++ include/zephyr/net/ieee802154.h | 35 +++++++++++-------- include/zephyr/net/openthread.h | 4 +-- 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/doc/connectivity/networking/api/ieee802154.rst b/doc/connectivity/networking/api/ieee802154.rst index 8801f896f41..ba641b1e4e3 100644 --- a/doc/connectivity/networking/api/ieee802154.rst +++ b/doc/connectivity/networking/api/ieee802154.rst @@ -32,10 +32,10 @@ Whenever sections from the standard are cited in the documentation, they refer to IEEE 802.15.4-2020 section, table and figure numbering - unless otherwise specified. -Zephyr supports bot native IEEE 802.15.4 and Thread with 6LoWPAN. The Thread -implementation is based on `OpenThread `_. The IPv6 -header compression in 6LoWPAN is shared among native IEEE 802.15.4, OpenThread -and the Bluetooth IPSP (IP support profile). +Zephyr supports both, native IEEE 802.15.4 and Thread, with 6LoWPAN. Zephyr's +:ref:`thread_protocol_interface` implementation is based on `OpenThread +`_. The IPv6 header compression in 6LoWPAN is shared +among native IEEE 802.15.4 and the Bluetooth IPSP (IP support profile). API Reference ************* @@ -85,3 +85,13 @@ network layers (L3+), its socket and network context abstractions. This API is therefore of interest to IEEE 802.15.4 **subsystem contributors** only. .. doxygengroup:: ieee802154_l2 + +OpenThread L2 Adaptation Layer API +================================== + +Zephyr's OpenThread L2 platform adaptation layer glues the external OpenThread +stack together with Zephyr's IEEE 802.15.4 protocol agnostic driver API. This +API is of interest to OpenThread L2 **subsystem contributors** only. + +The OpenThread API is part of the :ref:`thread_protocol_interface` subsystem and +documented there. diff --git a/doc/connectivity/networking/api/thread.rst b/doc/connectivity/networking/api/thread.rst index 280758078fa..155b794d7c1 100644 --- a/doc/connectivity/networking/api/thread.rst +++ b/doc/connectivity/networking/api/thread.rst @@ -40,3 +40,25 @@ which provide out-of-the-box configuration for OpenThread. To enable OpenThread support in these samples, build them with ``overlay-ot.conf`` overlay config file. See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` samples for details. + +Thread related APIs +******************* + +OpenThread Driver API +======================== + +OpenThread L2 uses Zephyr's protocol agnostic IEEE 802.15.4 driver API +internally. This API is of interest to **driver developers** that want to +support OpenThread. + +The driver API is part of the :ref:`ieee802154_driver_api` subsystem and +documented there. + +OpenThread L2 Adaptation Layer API +================================== + +Zephyr's OpenThread L2 platform adaptation layer glues the external OpenThread +stack together with Zephyr's IEEE 802.15.4 protocol agnostic driver API. This +API is of interest to OpenThread L2 **subsystem contributors** only. + +.. doxygengroup:: openthread diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index f85da7e59fd..e557fa5ac09 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -23,19 +23,24 @@ extern "C" { #endif /** - * @defgroup ieee802154 IEEE 802.15.4 APIs + * @defgroup ieee802154 IEEE 802.15.4 and Thread APIs * @ingroup connectivity * - * @brief IEEE 802.15.4 L2, configuration and driver APIs + * @brief IEEE 802.15.4 native and OpenThread L2, configuration, management and + * driver APIs * - * @details The IEEE 802.15.4 subsystem API comprises the native IEEE 802.15.4 - * L2 subsystem ("Soft" MAC), a mostly vendor and protocol agnostic driver API - * shared between the OpenThread and native L2 stacks ("Hard" MAC and PHY) as - * well as several APIs to configure the subsystem (shell, net management, - * Kconfig, devicetree, etc.). + * @details The IEEE 802.15.4 and Thread subsystems comprise the OpenThread L2 + * subsystem, the native IEEE 802.15.4 L2 subsystem ("Soft" MAC), a mostly + * vendor and protocol agnostic driver API shared between the OpenThread and + * native L2 stacks ("Hard" MAC and PHY) as well as several APIs to configure + * the subsystem (shell, net management, Kconfig, devicetree, etc.). * - * The IEEE 802.15.4 subsystem APIs are exposed at different levels and address - * several audiences: + * The **OpenThread subsystem API** integrates the external
OpenThread stack into Zephyr. It builds upon + * Zephyr's native IEEE 802.15.4 driver API. + * + * The **native IEEE 802.15.4 subsystem APIs** are exposed at different levels + * and address several audiences: * - shell (end users, application developers): * - a set of IEEE 802.15.4 shell commands (see `shell> ieee802154 help`) * - application API (application developers): @@ -51,11 +56,6 @@ extern "C" { * - Network Management: runtime configuration of the IEEE 802.15.4 * protocols stack at the MAC (L2) and PHY (L1) levels * (see @ref ieee802154_mgmt), - * - driver API (driver maintainers/contributors): - * - see @ref ieee802154_driver - * - a basic, mostly PHY-level driver API to be implemented by all drivers, - * - several "hard MAC" (hardware/firmware offloading) extension points for - * performance critical or timing sensitive aspects of the protocol * - L2 integration (subsystem contributors): * - see @ref ieee802154_l2 * - implementation of Zephyr's internal L2-level socket and network context @@ -63,6 +63,13 @@ extern "C" { * - protocol-specific extension to the interface structure (see @ref net_if) * - protocol-specific extensions to the network packet structure * (see @ref net_pkt), + * + * - OpenThread and native IEEE 802.15.4 share a common **driver API** (driver + * maintainers/contributors): + * - see @ref ieee802154_driver + * - a basic, mostly PHY-level driver API to be implemented by all drivers, + * - several "hard MAC" (hardware/firmware offloading) extension points for + * performance critical or timing sensitive aspects of the protocol */ /** diff --git a/include/zephyr/net/openthread.h b/include/zephyr/net/openthread.h index d928f9cb056..81c2629d6c0 100644 --- a/include/zephyr/net/openthread.h +++ b/include/zephyr/net/openthread.h @@ -5,7 +5,7 @@ */ /** @file - * @brief OpenThread l2 stack public header + * @brief OpenThread L2 stack public header */ #ifndef ZEPHYR_INCLUDE_NET_OPENTHREAD_H_ @@ -14,7 +14,7 @@ /** * @brief OpenThread Layer 2 abstraction layer * @defgroup openthread OpenThread L2 abstraction layer - * @ingroup networking + * @ingroup ieee802154 * @{ */ From bd038fc743537f89574ec5f2b29bc5f143a95e4d Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 16:45:13 +0200 Subject: [PATCH 1302/4498] doc: ieee802154: l2: improved docs Hides types used in the IEEE 802.15.4 L2 sub-API and L2-internal APIs that are of no public interest and improves documentation of the remainder. The changes are mostly minor as the API documentation had already been improved and clarified in previous changes. Also includes non-visible documentation to the subsystem-internal Frame API by adding references to the specification. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154.h | 204 ++++++++++++++++---- subsys/net/l2/ieee802154/ieee802154_frame.h | 69 ++++--- 2 files changed, 198 insertions(+), 75 deletions(-) diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index e557fa5ac09..bb400cbbd6d 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -6,7 +6,9 @@ /** * @file - * @brief IEEE 802.15.4 L2 stack public header + * @brief IEEE 802.15.4 native L2 stack public header + * + * @note All references to the standard in this file cite IEEE 802.15.4-2020. */ #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_H_ @@ -88,41 +90,118 @@ extern "C" { * - protocol-specific extension to the interface structure (see @ref net_if) * - protocol-specific extensions to the network packet structure * (see @ref net_pkt), + * + * @note All section, table and figure references are to the IEEE 802.15.4-2020 + * standard. + * * @{ */ -/* References are to the IEEE 802.15.4-2020 standard */ -#define IEEE802154_MAX_PHY_PACKET_SIZE 127 /* see section 11.3, aMaxPhyPacketSize */ -#define IEEE802154_FCS_LENGTH 2 /* see section 7.2.1.1 */ +#define IEEE802154_MAX_PHY_PACKET_SIZE 127 /**< see section 11.3, aMaxPhyPacketSize */ +#define IEEE802154_FCS_LENGTH 2 /**< see section 7.2.1.1 */ + +/** + * @brief IEEE 802.15.4 "hardware" MTU (not to be confused with L3/IP MTU), i.e. + * the actual payload available to the next higher layer. + * + * @details This is equivalent to the IEEE 802.15.4 MAC frame length minus + * checksum bytes which is again equivalent to the PHY payload aka PSDU length + * minus checksum bytes. This definition exists for compatibility with the same + * concept in Linux and Zephyr's L3. It is not a concept from the IEEE 802.15.4 + * standard. + * + * @note Currently we only support the original frame size from the 2006 + * standard version and earlier. The 2015+ standard introduced PHYs with larger + * PHY payload. These are not (yet) supported in Zephyr. + */ #define IEEE802154_MTU (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_FCS_LENGTH) + /* TODO: Support flexible MTU and FCS lengths for IEEE 802.15.4-2015ff */ +/** IEEE 802.15.4 short address length. */ #define IEEE802154_SHORT_ADDR_LENGTH 2 + +/** IEEE 802.15.4 extended address length. */ #define IEEE802154_EXT_ADDR_LENGTH 8 + +/** IEEE 802.15.4 maximum address length. */ #define IEEE802154_MAX_ADDR_LENGTH IEEE802154_EXT_ADDR_LENGTH +/** + * A special channel value that symbolizes "all" channels or "any" channel - + * depending on context. + */ #define IEEE802154_NO_CHANNEL USHRT_MAX -/* See IEEE 802.15.4-2020, sections 6.1 and 7.3.5 */ +/** + * @{ + * See sections 6.1 and 7.3.5 + */ #define IEEE802154_BROADCAST_ADDRESS 0xffff #define IEEE802154_NO_SHORT_ADDRESS_ASSIGNED 0xfffe +/** @} */ -/* See IEEE 802.15.4-2020, section 6.1 */ +/* See section 6.1 */ #define IEEE802154_BROADCAST_PAN_ID 0xffff -/* See IEEE 802.15.4-2020, section 7.3.5 */ +/* See section 7.3.5 */ #define IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED IEEE802154_BROADCAST_ADDRESS #define IEEE802154_PAN_ID_NOT_ASSOCIATED IEEE802154_BROADCAST_PAN_ID +/** interface-level security attributes, see section 9.5. */ struct ieee802154_security_ctx { + /** section 9.5, secFrameCounter */ uint32_t frame_counter; + + /** @cond INTERNAL_HIDDEN */ struct cipher_ctx enc; struct cipher_ctx dec; + /** INTERNAL_HIDDEN @endcond */ + + /** + * @brief frame-level security key material + * + * @details Currently native L2 only supports a single secKeySource, see + * section 9.5, table 9-9, in combination with secKeyMode zero (implicit + * key mode), see section 9.4.2.3, table 9-7. + * + * @warning This is no longer in accordance with the current version of + * the standard and needs to be extended in the future for full security + * procedure compliance. + */ uint8_t key[16]; + + /** frame-level security key material */ uint8_t key_len; + + /** + * @brief security level + * + * @details Currently native L2 supports a single security level for all + * frame types, commands and information elements, see section 9.4.2.2, + * table 9-6 and ieee802154_security_level. + * + * @warning This is no longer in accordance with the current version of + * the standard and needs to be extended in the future for full security + * procedure compliance. + */ uint8_t level : 3; + + /** + * @brief key_mode + * + * @details Currently only implicit key mode is partially supported, see + * section 9.4.2.3, table 9-7, secKeyMode. + * + * @warning This is no longer in accordance with the current version of + * the standard and needs to be extended in the future for full security + * procedure compliance. + */ uint8_t key_mode : 2; + + /** @cond INTERNAL_HIDDEN */ uint8_t _unused : 3; + /** INTERNAL_HIDDEN @endcond */ }; enum ieee802154_device_role { @@ -131,63 +210,77 @@ enum ieee802154_device_role { IEEE802154_DEVICE_ROLE_PAN_COORDINATOR, }; -/* This not meant to be used by any code but the IEEE 802.15.4 L2 stack */ +/** IEEE 802.15.4 L2 context. */ struct ieee802154_context { - /* PAN ID + /** + * @brief PAN ID * - * The identifier of the PAN on which the device is operating. If this - * value is 0xffff, the device is not associated. See section 8.4.3.1, - * table 8-94, macPanId. + * @details The identifier of the PAN on which the device is operating. + * If this value is 0xffff, the device is not associated. See section + * 8.4.3.1, table 8-94, macPanId. * * in CPU byte order */ uint16_t pan_id; - /* Channel Number + /** + * @brief Channel Number * - * The RF channel to use for all transmissions and receptions, see - * section 11.3, table 11-2, phyCurrentChannel. The allowable range + * @details The RF channel to use for all transmissions and receptions, + * see section 11.3, table 11-2, phyCurrentChannel. The allowable range * of values is PHY dependent as defined in section 10.1.3. * * in CPU byte order */ uint16_t channel; - /* Short Address + /** + * @brief Short Address (in CPU byte order) * - * Range: + * @details Range: * * 0x0000–0xfffd: associated, short address was assigned * * 0xfffe: associated but no short address assigned * * 0xffff: not associated (default), * * See section 6.4.1, table 6-4 (Usage of the shart address) and * section 8.4.3.1, table 8-94, macShortAddress. - * - * in CPU byte order */ uint16_t short_addr; - /* Extended Address + /** + * @brief Extended Address (in little endian) * - * The extended address is device specific, usually permanently stored - * on the device and immutable. + * @details The extended address is device specific, usually permanently + * stored on the device and immutable. * * See section 8.4.3.1, table 8-94, macExtendedAddress. - * - * in little endian */ uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH]; - struct net_linkaddr_storage linkaddr; /* in big endian */ + /** Link layer address (in big endian) */ + struct net_linkaddr_storage linkaddr; + #ifdef CONFIG_NET_L2_IEEE802154_SECURITY + /** Security context */ struct ieee802154_security_ctx sec_ctx; #endif + #ifdef CONFIG_NET_L2_IEEE802154_MGMT - struct ieee802154_req_params *scan_ctx; /* guarded by scan_ctx_lock */ + /** Pointer to scanning parameters and results, guarded by scan_ctx_lock */ + struct ieee802154_req_params *scan_ctx; + + /** + * Used to maintain integrity of data for all fields in this struct + * unless otherwise documented on field level. + */ struct k_sem scan_ctx_lock; - /* see section 8.4.3.1, table 8-94, macCoordExtendedAddress, the address - * of the coordinator through which the device is associated. + /** + * @brief Coordinator extended address + * + * @details see section 8.4.3.1, table 8-94, macCoordExtendedAddress, + * the address of the coordinator through which the device is + * associated. * * A value of zero indicates that a coordinator extended address is * unknown (default). @@ -196,8 +289,11 @@ struct ieee802154_context { */ uint8_t coord_ext_addr[IEEE802154_MAX_ADDR_LENGTH]; - /* see section 8.4.3.1, table 8-94, macCoordShortAddress, the short - * address assigned to the coordinator through which the device is + /** + * @brief Coordinator short address + * + * @details see section 8.4.3.1, table 8-94, macCoordShortAddress, the + * short address assigned to the coordinator through which the device is * associated. * * A value of 0xfffe indicates that the coordinator is only using its @@ -208,36 +304,64 @@ struct ieee802154_context { */ uint16_t coord_short_addr; #endif + + /** transmission power */ int16_t tx_power; + + /** L2 flags */ enum net_l2_flags flags; - /* The sequence number added to the transmitted Data frame or MAC - * command, see section 8.4.3.1, table 8-94, macDsn. + /** + * @brief DSN + * + * @details The sequence number added to the transmitted Data frame or + * MAC command, see section 8.4.3.1, table 8-94, macDsn. */ uint8_t sequence; - /* See section 6.1: A device may be operating as end device - * (0 - default), coordinator (1), or PAN coordinator (2). + /** + * @brief Device Role + * + * @details See section 6.1: A device may be operating as end device (0 + * - default), coordinator (1), or PAN coordinator (2). * * A value of 3 is undefined. * - * Can be read/set via enum ieee802154_device_role. + * Can be read/set via @ref ieee802154_device_role. */ uint8_t device_role : 2; + /** @cond INTERNAL_HIDDEN */ uint8_t _unused : 5; + /** INTERNAL_HIDDEN @endcond */ - uint8_t ack_requested : 1; /* guarded by ack_lock */ - uint8_t ack_seq; /* guarded by ack_lock */ + /** + * ACK requested flag, guarded by ack_lock + */ + uint8_t ack_requested: 1; + + /** ACK expected sequence number, guarded by ack_lock */ + uint8_t ack_seq; + + /** ACK lock, guards ack_* fields */ struct k_sem ack_lock; - struct k_sem ctx_lock; /* guards all mutable context attributes unless - * otherwise mentioned on attribute level - */ + /** + * @brief Context lock + * + * @details guards all mutable context attributes unless otherwise + * mentioned on attribute level + */ + struct k_sem ctx_lock; }; +/** @cond INTERNAL_HIDDEN */ + +/* L2 context type to be used with NET_L2_GET_CTX_TYPE */ #define IEEE802154_L2_CTX_TYPE struct ieee802154_context +/** INTERNAL_HIDDEN @endcond */ + #ifdef __cplusplus } #endif diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.h b/subsys/net/l2/ieee802154/ieee802154_frame.h index a68945a0eab..2a24a5b6029 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.h +++ b/subsys/net/l2/ieee802154/ieee802154_frame.h @@ -8,13 +8,13 @@ * @file * @brief IEEE 802.15.4 MAC frame related functions * - * This is not to be included by the application. + * @details This is not to be included by the application. * - * All specification references in this file refer to IEEE 802.15.4-2020. + * @note All references to the standard in this file cite IEEE 802.15.4-2020. * - * Note: All structs and attributes (e.g. PAN id, ext address and short - * address) in this file that directly represent IEEE 802.15.4 frames - * are in LITTLE ENDIAN, see section 4, especially section 4.3. + * @note All structs and attributes (e.g. PAN id, ext address and short address) + * in this file that directly represent parts of IEEE 802.15.4 frames are in + * LITTLE ENDIAN, see section 4, especially section 4.3. */ #ifndef __IEEE802154_FRAME_H__ @@ -42,7 +42,7 @@ #define IEEE802154_BEACON_GTS_RX 1 #define IEEE802154_BEACON_GTS_TX 0 -/* See section 7.2.2.2 */ +/** see section 7.2.2.2 */ enum ieee802154_frame_type { IEEE802154_FRAME_TYPE_BEACON = 0x0, IEEE802154_FRAME_TYPE_DATA = 0x1, @@ -54,7 +54,7 @@ enum ieee802154_frame_type { IEEE802154_FRAME_TYPE_EXTENDED = 0x7, }; -/* See section 7.2.2.9, table 7-3 */ +/** see section 7.2.2.9, table 7-3 */ enum ieee802154_addressing_mode { IEEE802154_ADDR_MODE_NONE = 0x0, IEEE802154_ADDR_MODE_RESERVED = 0x1, @@ -62,7 +62,7 @@ enum ieee802154_addressing_mode { IEEE802154_ADDR_MODE_EXTENDED = 0x3, }; -/* See section 7.2.2.10 */ +/** see section 7.2.2.10 */ enum ieee802154_version { IEEE802154_VERSION_802154_2003 = 0x0, IEEE802154_VERSION_802154_2006 = 0x1, @@ -70,9 +70,7 @@ enum ieee802154_version { IEEE802154_VERSION_RESERVED = 0x3, }; -/* - * Frame Control Field, see section 7.2.2 - */ +/** Frame Control Field, see section 7.2.2 */ struct ieee802154_fcf_seq { struct { #ifdef CONFIG_LITTLE_ENDIAN @@ -128,7 +126,7 @@ struct ieee802154_address_field { }; } __packed; -/* See section 9.4.2.2, table 9-6 */ +/** see section 9.4.2.2, table 9-6 */ enum ieee802154_security_level { IEEE802154_SECURITY_LEVEL_NONE = 0x0, IEEE802154_SECURITY_LEVEL_MIC_32 = 0x1, @@ -140,15 +138,15 @@ enum ieee802154_security_level { IEEE802154_SECURITY_LEVEL_ENC_MIC_128 = 0x7, }; -/* Levels above this level will be encrypted. */ +/** Levels above this level will be encrypted. */ #define IEEE802154_SECURITY_LEVEL_ENC IEEE802154_SECURITY_LEVEL_RESERVED -/* This will match above *_MIC_<32/64/128> */ +/** This will match above *_MIC_<32/64/128> */ #define IEEE802154_AUTH_TAG_LENGTH_32 4 #define IEEE802154_AUTH_TAG_LENGTH_64 8 #define IEEE802154_AUTH_TAG_LENGTH_128 16 -/* See section 9.4.2.3, table 9-7 */ +/** see section 9.4.2.3, table 9-7 */ enum ieee802154_key_id_mode { IEEE802154_KEY_ID_MODE_IMPLICIT = 0x0, IEEE802154_KEY_ID_MODE_INDEX = 0x1, @@ -162,7 +160,7 @@ enum ieee802154_key_id_mode { #define IEEE802154_KEY_MAX_LEN 16 -/* See section 9.4.2 */ +/** see section 9.4.2 */ struct ieee802154_security_control_field { #ifdef CONFIG_LITTLE_ENDIAN uint8_t security_level : 3; @@ -177,10 +175,14 @@ struct ieee802154_security_control_field { #define IEEE802154_SECURITY_CF_LENGTH 1 -/* see section 9.4.4 */ +/** + * @brief see section 9.4.4 + * + * @note Currently only mode 0 is supported, so this structure holds no info, + * yet. + */ struct ieee802154_key_identifier_field { union { - /* mode_0 being implicit, it holds no info here */ struct { uint8_t key_index; } mode_1; @@ -197,10 +199,7 @@ struct ieee802154_key_identifier_field { }; } __packed; -/* - * Auxiliary Security Header - * see section 9.4 - */ +/** Auxiliary Security Header, see section 9.4 */ struct ieee802154_aux_security_hdr { struct ieee802154_security_control_field control; uint32_t frame_counter; @@ -209,7 +208,7 @@ struct ieee802154_aux_security_hdr { #define IEEE802154_SECURITY_FRAME_COUNTER_LENGTH 4 -/* MAC header and footer, see section 7.2.1 */ +/** MAC header and footer, see section 7.2.1 */ struct ieee802154_mhr { struct ieee802154_fcf_seq *fs; struct ieee802154_address_field *dst_addr; @@ -219,7 +218,7 @@ struct ieee802154_mhr { #endif }; -/* see section 7.3.1.5, figure 7-10 */ +/** see section 7.3.1.5, figure 7-10 */ struct ieee802154_gts_dir { #ifdef CONFIG_LITTLE_ENDIAN uint8_t mask : 7; @@ -230,7 +229,7 @@ struct ieee802154_gts_dir { #endif } __packed; -/* see section 7.3.1.5, figure 7-11 */ +/** see section 7.3.1.5, figure 7-11 */ struct ieee802154_gts { uint16_t short_address; #ifdef CONFIG_LITTLE_ENDIAN @@ -242,7 +241,7 @@ struct ieee802154_gts { #endif } __packed; -/* see section 7.3.1.5, figure 7-9 */ +/** see section 7.3.1.5, figure 7-9 */ struct ieee802154_gts_spec { #ifdef CONFIG_LITTLE_ENDIAN /* Descriptor Count */ @@ -259,7 +258,7 @@ struct ieee802154_gts_spec { #endif } __packed; -/* see section 7.3.1.6, figure 7-13 */ +/** see section 7.3.1.6, figure 7-13 */ struct ieee802154_pas_spec { #ifdef CONFIG_LITTLE_ENDIAN /* Number of Short Addresses Pending */ @@ -278,7 +277,7 @@ struct ieee802154_pas_spec { #endif } __packed; -/* see section 7.3.1.4, figure 7-7 */ +/** see section 7.3.1.4, figure 7-7 */ struct ieee802154_beacon_sf { #ifdef CONFIG_LITTLE_ENDIAN /* Beacon Order*/ @@ -311,7 +310,7 @@ struct ieee802154_beacon_sf { #endif } __packed; -/* see section 7.3.1.1, figure 7-5 */ +/** see section 7.3.1.1, figure 7-5 */ struct ieee802154_beacon { struct ieee802154_beacon_sf sf; @@ -319,7 +318,7 @@ struct ieee802154_beacon { struct ieee802154_gts_spec gts; } __packed; -/* see section 7.5.2 */ +/** See section 7.5.2 */ struct ieee802154_cmd_assoc_req { struct { #ifdef CONFIG_LITTLE_ENDIAN @@ -346,7 +345,7 @@ struct ieee802154_cmd_assoc_req { #define IEEE802154_CMD_ASSOC_REQ_LENGTH 1 -/* See section 7.5.3 */ +/** see section 7.5.3 */ enum ieee802154_association_status_field { IEEE802154_ASF_SUCCESSFUL = 0x00, IEEE802154_ASF_PAN_AT_CAPACITY = 0x01, @@ -362,7 +361,7 @@ struct ieee802154_cmd_assoc_res { #define IEEE802154_CMD_ASSOC_RES_LENGTH 3 -/* See section 7.5.4 */ +/** see section 7.5.4 */ enum ieee802154_disassociation_reason_field { IEEE802154_DRF_RESERVED_1 = 0x00, IEEE802154_DRF_COORDINATOR_WISH = 0x01, @@ -377,7 +376,7 @@ struct ieee802154_cmd_disassoc_note { #define IEEE802154_CMD_DISASSOC_NOTE_LENGTH 1 -/* Coordinator realignment, see section 7.5.10 */ +/** Coordinator realignment, see section 7.5.10 */ struct ieee802154_cmd_coord_realign { uint16_t pan_id; uint16_t coordinator_short_addr; @@ -388,7 +387,7 @@ struct ieee802154_cmd_coord_realign { #define IEEE802154_CMD_COORD_REALIGN_LENGTH 3 -/* GTS request, see section 7.5.11 */ +/** GTS request, see section 7.5.11 */ struct ieee802154_gts_request { struct { #ifdef CONFIG_LITTLE_ENDIAN @@ -407,7 +406,7 @@ struct ieee802154_gts_request { #define IEEE802154_GTS_REQUEST_LENGTH 1 -/* Command Frame Identifiers (CFI), see section 7.5.1 */ +/** Command Frame Identifiers (CFI), see section 7.5.1 */ enum ieee802154_cfi { IEEE802154_CFI_UNKNOWN = 0x00, IEEE802154_CFI_ASSOCIATION_REQUEST = 0x01, From c315d131025c94e77189505323c89b08d437a533 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 16:46:29 +0200 Subject: [PATCH 1303/4498] doc: ieee802154: driver: improved docs Hides types in the IEEE 802.15.4 driver sub-API that are of no public interest and improves documentation of the remainder. Apart from extending and clarifying many details of the driver API, this change also specifies certain formal properties of API calls, such as "sleeps" or "isr-ok". Plus it removes semantic ambivalence that had been resolved and hidden in existing implementation details but is highly relevant to the way the API can be used and shall be implemented. As far as possible this change introduces formal requirements language (MAY, SHALL/MUST, SHOULD) to specify driver implementation requirements. This change also introduces two definitions - for the moment being of purely documentary relevance (i.e. to be referred in the documentation): * IEEE802154_CONFIG_RX_SLOT_NONE * IEEE802154_CONFIG_RX_SLOT_OFF These "magic" values are required to clarify the exact semantics of RX slots as to receiver activity. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154_radio.h | 662 +++++++++++++++++++++----- 1 file changed, 535 insertions(+), 127 deletions(-) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 68864aedc0c..c837a2991bd 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -9,7 +9,7 @@ * @file * @brief Public IEEE 802.15.4 Driver API * - * All references to the spec refer to IEEE 802.15.4-2020. + * @note All references to the standard in this file cite IEEE 802.15.4-2020. */ #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_H_ @@ -54,11 +54,15 @@ extern "C" { * is to be decided by individual driver maintainers. Upper layers SHOULD * provide a "soft" MAC fallback whenever possible. * + * @note All section, table and figure references are to the IEEE 802.15.4-2020 + * standard. + * * @{ */ /** - * MAC functional description (section 6) + * @name MAC functional description (section 6) + * @{ */ /** @@ -76,8 +80,12 @@ extern "C" { */ #define IEEE802154_PHY_SYMBOLS_PER_SECOND(symbol_period_ns) (NSEC_PER_SEC / symbol_period_ns) +/** @} */ + + /** - * MAC services (section 8) + * @name MAC services (section 8) + * @{ */ /** @@ -113,8 +121,12 @@ extern "C" { */ #define IEEE802154_MAC_RESPONSE_WAIT_TIME_DEFAULT 32U +/** @} */ + + /** - * General PHY requirements (section 10) + * @name General PHY requirements (section 10) + * @{ */ /** @@ -161,7 +173,7 @@ enum ieee802154_phy_channel_page { * (channel 0, BPSK). * * You can retrieve the channels supported by a specific driver on this - * page via IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES attribute. + * page via @ref IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES attribute. * * see section 10.1.3.3 */ @@ -213,11 +225,19 @@ enum ieee802154_phy_channel_page { IEEE802154_ATTR_PHY_CHANNEL_PAGE_THIRTEEN_RCC = BIT(13), }; +/** + * Represents a supported channel range, see @ref + * ieee802154_phy_supported_channels. + */ struct ieee802154_phy_channel_range { uint16_t from_channel; uint16_t to_channel; }; +/** + * Represents a list channels supported by a driver for a given interface, see + * @ref IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES. + */ struct ieee802154_phy_supported_channels { /** * @brief Pointer to an array of channel range structures. @@ -269,51 +289,72 @@ struct ieee802154_phy_supported_channels { }, \ } +/** @} */ + /** - * PHY services (section 11) + * @name PHY services (section 11) + * @{ */ -/* Default PHY PIB attribute aTurnaroundTime, in PHY symbols, - * see section 11.3, table 11-1. +/** + * Default PHY PIB attribute aTurnaroundTime, in PHY symbols, see section 11.3, + * table 11-1. */ #define IEEE802154_PHY_A_TURNAROUND_TIME_DEFAULT 12U -/* PHY PIB attribute aTurnaroundTime for SUN, RS-GFSK, TVWS, and LECIM FSK PHY, +/** + * PHY PIB attribute aTurnaroundTime for SUN, RS-GFSK, TVWS, and LECIM FSK PHY, * in PHY symbols, see section 11.3, table 11-1. */ #define IEEE802154_PHY_A_TURNAROUND_TIME_1MS(symbol_period_ns) \ DIV_ROUND_UP(NSEC_PER_MSEC, symbol_period_ns) -/* PHY PIB attribute aCcaTime, in PHY symbols, all PHYs except for SUN O-QPSK, +/** + * PHY PIB attribute aCcaTime, in PHY symbols, all PHYs except for SUN O-QPSK, * see section 11.3, table 11-1. */ #define IEEE802154_PHY_A_CCA_TIME 8U +/** @} */ + + /** - * Q-OPSK PHY (section 12) + * @name O-QPSK PHY (section 12) + * @{ */ -/* Symbol periods, section 12.3.3 */ +/** O-QPSK 868Mhz band symbol period, see section 12.3.3 */ #define IEEE802154_PHY_OQPSK_868MHZ_SYMBOL_PERIOD_NS 40000LL + +/** + * O-QPSK 780MHz, 915MHz, 2380MHz and 2450MHz bands symbol period, + * see section 12.3.3 + */ #define IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS 16000LL +/** @} */ + /** - * BPSK PHY (section 13) + * @name BPSK PHY (section 13) + * @{ */ -/* Symbol periods, section 13.3.3 */ +/** BPSK 868MHz band symbol period, see section 13.3.3 */ #define IEEE802154_PHY_BPSK_868MHZ_SYMBOL_PERIOD_NS 50000LL + +/** BPSK 915MHz band symbol period, see section 13.3.3 */ #define IEEE802154_PHY_BPSK_915MHZ_SYMBOL_PERIOD_NS 25000LL +/** @} */ -/** - * HRP UWB PHY (section 15) - */ -/* For HRP UWB the symbol period is derived from the preamble symbol period +/** + * @name HRP UWB PHY (section 15) + * + * @details For HRP UWB the symbol period is derived from the preamble symbol period * (T_psym), see section 11.3, table 11-1 and section 15.2.5, table 15-4 * (confirmed in IEEE 802.15.4z, section 15.1). Choosing among those periods * cannot be done based on channel page and channel alone. The mean pulse @@ -321,20 +362,28 @@ struct ieee802154_phy_supported_channels { * MCPS-DATA.request primitive (section 8.3.2, table 8-88) and the preamble * parameters for HRP-ERDEV length 91 codes (IEEE 802.15.4z, section 15.2.6.2, * table 15-7b). + * @{ */ + +/** Nominal PRF 4MHz symbol period */ #define IEEE802154_PHY_HRP_UWB_PRF4_TPSYM_SYMBOL_PERIOD_NS 3974.36F +/** Nominal PRF 16MHz symbol period */ #define IEEE802154_PHY_HRP_UWB_PRF16_TPSYM_SYMBOL_PERIOD_NS 993.59F +/** Nominal PRF 64MHz symbol period */ #define IEEE802154_PHY_HRP_UWB_PRF64_TPSYM_SYMBOL_PERIOD_NS 1017.63F +/** ERDEV symbol period */ #define IEEE802154_PHY_HRP_UWB_ERDEV_TPSYM_SYMBOL_PERIOD_NS 729.17F /** @brief represents the nominal pulse rate frequency of an HRP UWB PHY */ enum ieee802154_phy_hrp_uwb_nominal_prf { - /* standard modes, see section 8.3.2, table 8-88. */ + /** standard modes, see section 8.3.2, table 8-88. */ IEEE802154_PHY_HRP_UWB_PRF_OFF = 0, IEEE802154_PHY_HRP_UWB_NOMINAL_4_M = BIT(0), IEEE802154_PHY_HRP_UWB_NOMINAL_16_M = BIT(1), IEEE802154_PHY_HRP_UWB_NOMINAL_64_M = BIT(2), - /* enhanced ranging device (ERDEV) modes not specified in table 8-88, + + /** + * enhanced ranging device (ERDEV) modes not specified in table 8-88, * see IEEE 802.15.4z, section 15.1, section 15.2.6.2, table 15-7b, * section 15.3.4.2 and section 15.3.4.3. */ @@ -343,25 +392,37 @@ enum ieee802154_phy_hrp_uwb_nominal_prf { IEEE802154_PHY_HRP_UWB_NOMINAL_256_M_HPRF = BIT(5), }; +/** RDEV device mask */ #define IEEE802154_PHY_HRP_UWB_RDEV \ (IEEE802154_PHY_HRP_UWB_NOMINAL_4_M | IEEE802154_PHY_HRP_UWB_NOMINAL_16_M | \ IEEE802154_PHY_HRP_UWB_NOMINAL_64_M) +/** ERDEV device mask */ #define IEEE802154_PHY_HRP_UWB_ERDEV \ (IEEE802154_PHY_HRP_UWB_NOMINAL_64_M_BPRF | IEEE802154_PHY_HRP_UWB_NOMINAL_128_M_HPRF | \ IEEE802154_PHY_HRP_UWB_NOMINAL_256_M_HPRF) +/** @} */ + /** - * SUN FSK PHY (section 19) + * @name SUN FSK PHY (section 19) + * @{ */ -/* symbol periods, section 19.1, table 19-1 */ +/** SUN FSK 863Mhz and 915MHz band symbol periods, see section 19.1, table 19-1 */ #define IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS 20000LL -/* in bytes, see section 19.2.4 */ +/** SUN FSK PHY header length, in bytes, see section 19.2.4 */ #define IEEE802154_PHY_SUN_FSK_PHR_LEN 2 +/** @} */ + +/** + * @name IEEE 802.15.4 driver + * @{ + */ + /** * IEEE 802.15.4 driver capabilities * @@ -441,6 +502,7 @@ enum ieee802154_hw_caps { /** @brief This and higher values are specific to the protocol- or driver-specific extensions. */ #define IEEE802154_HW_CAPS_BITS_PRIV_START IEEE802154_HW_CAPS_BITS_COMMON_COUNT +/** Filter type, see @ref ieee802154_radio_api::filter */ enum ieee802154_filter_type { IEEE802154_FILTER_TYPE_IEEE_ADDR, IEEE802154_FILTER_TYPE_SHORT_ADDR, @@ -449,36 +511,58 @@ enum ieee802154_filter_type { IEEE802154_FILTER_TYPE_SRC_SHORT_ADDR, }; +/** Driver events, see @ref IEEE802154_CONFIG_EVENT_HANDLER */ enum ieee802154_event { - IEEE802154_EVENT_TX_STARTED, /* Data transmission started */ - IEEE802154_EVENT_RX_FAILED, /* Data reception failed */ - IEEE802154_EVENT_SLEEP, /* Sleep pending */ + /** Data transmission started */ + IEEE802154_EVENT_TX_STARTED, + /** Data reception failed */ + IEEE802154_EVENT_RX_FAILED, + /** An RX slot ended, requires @ref IEEE802154_HW_RXTIME + * + * @note This event SHALL not be triggered by drivers when RX is + * synchronously switched of due to a call to `stop()` or an RX slot + * being configured. + */ + IEEE802154_EVENT_SLEEP, }; +/** RX failed event reasons, see @ref IEEE802154_EVENT_RX_FAILED */ enum ieee802154_rx_fail_reason { - IEEE802154_RX_FAIL_NOT_RECEIVED, /* Nothing received */ - IEEE802154_RX_FAIL_INVALID_FCS, /* Frame had invalid checksum */ - IEEE802154_RX_FAIL_ADDR_FILTERED, /* Address did not match */ - IEEE802154_RX_FAIL_OTHER /* General reason */ + /** Nothing received */ + IEEE802154_RX_FAIL_NOT_RECEIVED, + /** Frame had invalid checksum */ + IEEE802154_RX_FAIL_INVALID_FCS, + /** Address did not match */ + IEEE802154_RX_FAIL_ADDR_FILTERED, + /** General reason */ + IEEE802154_RX_FAIL_OTHER }; +/** Energy scan callback */ typedef void (*energy_scan_done_cb_t)(const struct device *dev, int16_t max_ed); +/** Driver event callback */ typedef void (*ieee802154_event_cb_t)(const struct device *dev, enum ieee802154_event evt, void *event_params); +/** Filter value, see @ref ieee802154_radio_api::filter */ struct ieee802154_filter { -/** @cond INTERNAL_HIDDEN */ union { - uint8_t *ieee_addr; /* in little endian */ - uint16_t short_addr; /* in CPU byte order */ - uint16_t pan_id; /* in CPU byte order */ + /** Extended address, in little endian */ + uint8_t *ieee_addr; + /** Short address, in CPU byte order */ + uint16_t short_addr; + /** PAN ID, in CPU byte order */ + uint16_t pan_id; }; -/** @endcond */ }; +/** + * Key configuration for transmit security offloading, see @ref + * IEEE802154_CONFIG_MAC_KEYS. + */ struct ieee802154_key { uint8_t *key_value; uint32_t key_frame_counter; @@ -503,7 +587,7 @@ enum ieee802154_tx_mode { IEEE802154_TX_MODE_CSMA_CA, /** - * Transmit packet in the future, at specified time, no CCA. + * Transmit packet in the future, at the specified time, no CCA. * * @note requires IEEE802154_HW_TXTIME capability. */ @@ -525,85 +609,160 @@ enum ieee802154_tx_mode { /** IEEE 802.15.4 Frame Pending Bit table address matching mode. */ enum ieee802154_fpb_mode { - /** The pending bit shall be set only for addresses found in the list. - */ + /** The pending bit shall be set only for addresses found in the list. */ IEEE802154_FPB_ADDR_MATCH_THREAD, - /** The pending bit shall be cleared for short addresses found in - * the list. + /** The pending bit shall be cleared for short addresses found in the + * list. */ IEEE802154_FPB_ADDR_MATCH_ZIGBEE, }; /** IEEE 802.15.4 driver configuration types. */ enum ieee802154_config_type { - /** Indicates how the driver should set Frame Pending bit in ACK - * responses for Data Requests. If enabled, the driver should - * determine whether to set the bit or not based on the information - * provided with ``IEEE802154_CONFIG_ACK_FPB`` config and FPB address - * matching mode specified. Otherwise, Frame Pending bit should be set - * to ``1`` (see section 6.7.3). - * Requires IEEE802154_HW_TX_RX_ACK capability. + /** Indicates how the driver should set the Frame Pending bit in ACK + * responses for Data Requests. If enabled, the driver should determine + * whether to set the bit or not based on the information provided with + * @ref IEEE802154_CONFIG_ACK_FPB config and FPB address matching mode + * specified. Otherwise, Frame Pending bit should be set to ``1`` (see + * section 6.7.3). + * + * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is + * available in any interface operational state. */ IEEE802154_CONFIG_AUTO_ACK_FPB, /** Indicates whether to set ACK Frame Pending bit for specific address * or not. Disabling the Frame Pending bit with no address provided * (NULL pointer) should disable it for all enabled addresses. - * Requires IEEE802154_HW_TX_RX_ACK capability. + * + * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is + * available in any interface operational state. */ IEEE802154_CONFIG_ACK_FPB, - /** Indicates whether the device is a PAN coordinator. */ + /** Indicates whether the device is a PAN coordinator. This influences + * packet filtering. + * + * @note Available in any interface operational state. + */ IEEE802154_CONFIG_PAN_COORDINATOR, - /** Enable/disable promiscuous mode. */ + /** Enable/disable promiscuous mode. + * + * @note Available in any interface operational state. + */ IEEE802154_CONFIG_PROMISCUOUS, /** Specifies new IEEE 802.15.4 driver event handler. Specifying NULL as * a handler will disable events notification. + * + * @note Available in any interface operational state. */ IEEE802154_CONFIG_EVENT_HANDLER, - /** Updates MAC keys and key index for drivers supporting transmit - * security offloading. + /** Updates MAC keys, key index and the per-key frame counter for drivers + * supporting transmit security offloading, see section 9.5, tables 9-9 + * and 9-10. The key configuration SHALL NOT be accepted if the frame + * counter (in case frame counter per key is true) is not strictly + * larger than the current frame counter associated with the same key, + * see sections 8.2.2, 9.2.4 g/h) and 9.4.3. + * + * @note Available in any interface operational state. */ IEEE802154_CONFIG_MAC_KEYS, - /** Sets the current MAC frame counter value for drivers supporting - * transmit security offloading. + /** Sets the current MAC frame counter value associated with the + * interface for drivers supporting transmit security offloading, see + * section 9.5, table 9-8, secFrameCounter. + * + * @warning The frame counter MUST NOT be accepted if it is not + * strictly greater than the current frame counter associated with the + * interface, see sections 8.2.2, 9.2.4 g/h) and 9.4.3. Otherwise the + * replay protection provided by the frame counter may be compromised. + * Drivers SHALL return -EINVAL in case the configured frame counter + * does not conform to this requirement. + * + * @note Available in any interface operational state. */ IEEE802154_CONFIG_FRAME_COUNTER, /** Sets the current MAC frame counter value if the provided value is greater than * the current one. + * + * @note Available in any interface operational state. + * + * @note This configuration option does not conform to the requirements + * specified in #61227 as it is redundant with @ref + * IEEE802154_CONFIG_FRAME_COUNTER, and will therefore be deprecated in + * the future. */ IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER, - /** Configure a radio reception window. This can be used for any - * scheduled reception, e.g.: Zigbee GP device, CSL, TSCH, etc. + /** Set or unset a radio reception window (RX slot). This can be used for + * any scheduled reception, e.g.: Zigbee GP device, CSL, TSCH, etc. + * + * @details The start and duration parameters of the RX slot are + * relative to the network subsystem's local clock. If the start + * parameter of the RX slot is -1 then any previously configured RX + * slot SHALL be canceled immediately. If the start parameter is any + * value in the past (including 0) or the duration parameter is zero + * then the receiver SHALL remain off forever until the RX slot has + * either been removed or re-configured to point to a future start + * time. If an RX slot is configured while the previous RX slot is + * still scheduled, then the previous slot SHALL be cancelled and the + * new slot scheduled instead. + * + * RX slots MAY be programmed while the driver is "DOWN". If any past + * or future RX slot is configured when calling `start()` then the + * interface SHALL be placed in "UP" state but the receiver SHALL not + * be started. + * + * The driver SHALL take care to start/stop the receiver autonomously, + * asynchronously and automatically around the RX slot. The driver + * SHALL resume power just before the RX slot and suspend it again + * after the slot unless another programmed event forces the driver not + * to suspend. The driver SHALL switch to the programmed channel + * before the RX slot and back to the channel set with set_channel() + * after the RX slot. If the driver interface is "DOWN" when the start + * time of an RX slot arrives, then the RX slot SHALL not be observed + * and the receiver SHALL remain off. * - * @note requires IEEE802154_HW_RXTIME capability. + * If the driver is "UP" while configuring an RX slot, the driver SHALL + * turn off the receiver immediately and (possibly asynchronously) put + * the driver into the lowest possible power saving mode until the + * start of the RX slot. If the driver is "UP" while the RX slot is + * deleted, then the driver SHALL enable the receiver immediately. The + * receiver MUST be ready to receive packets before returning from the + * `configure()` operation in this case. + * + * This behavior means that setting an RX slot implicitly sets the MAC + * PIB attribute macRxOnWhenIdle (see section 8.4.3.1, table 8-94) to + * "true" while deleting the RX slot implicitly sets macRxOnWhenIdle to + * "false". + * + * @note requires @ref IEEE802154_HW_RXTIME capability and is available + * in any interface operational state. */ IEEE802154_CONFIG_RX_SLOT, /** Configure CSL receiver (Endpoint) period * - * In order to configure a CSL receiver the upper layer should combine several + * @details In order to configure a CSL receiver the upper layer should combine several * configuration options in the following way: - * 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the driver of the + * 1. Use @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE once to inform the driver of the * short and extended addresses of the peer to which it should inject CSL IEs. - * 2. Use ``IEEE802154_CONFIG_CSL_RX_TIME`` periodically, before each use of - * ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, + * 2. Use @ref IEEE802154_CONFIG_CSL_RX_TIME periodically, before each use of + * @ref IEEE802154_CONFIG_CSL_PERIOD setting parameters of the nearest CSL RX window, * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not * the nearest one) CSL RX window, to allow the driver to calculate the proper * CSL Phase to the nearest CSL window to inject in the CSL IEs for both transmitted * data and ACK frames. - * 3. Use ``IEEE802154_CONFIG_CSL_PERIOD`` on each value change to update the current CSL - * period value which will be injected in the CSL IEs together with the CSL Phase - * based on ``IEEE802154_CONFIG_CSL_RX_TIME``. - * 4. Use ``IEEE802154_CONFIG_RX_SLOT`` periodically to schedule the immediate receive - * window earlier enough before the expected window start time, taking into account + * 3. Use @ref IEEE802154_CONFIG_CSL_PERIOD on each value change to update the current + * CSL period value which will be injected in the CSL IEs together with the CSL Phase + * based on @ref IEEE802154_CONFIG_CSL_RX_TIME. + * 4. Use @ref IEEE802154_CONFIG_RX_SLOT periodically to schedule the immediate receive + * window early enough before the expected window start time, taking into account * possible clock drifts and scheduling uncertainties. * * This diagram shows the usage of the four options over time: @@ -620,17 +779,35 @@ enum ieee802154_config_type { * ^ | * | | * +--------------------- loop ---------+ + * + * @note Available in any interface operational state. + * + * @note This configuration option does not conform to the requirements + * specified in #61227 as it is incompatible with standard primitives + * and may therefore be deprecated in the future. */ IEEE802154_CONFIG_CSL_PERIOD, /** Configure the next CSL receive window (i.e. "channel sample") center, * in units of nanoseconds relative to the network subsystem's local clock. + * + * @note Available in any interface operational state. + * + * @note This configuration option does not conform to the requirements + * specified in #61227 as it is incompatible with standard primitives + * and may therefore be deprecated in the future. */ IEEE802154_CONFIG_CSL_RX_TIME, /** Indicates whether to inject IE into ENH ACK Frame for specific address * or not. Disabling the ENH ACK with no address provided (NULL pointer) * should disable it for all enabled addresses. + * + * @note Available in any interface operational state. + * + * @note This configuration option does not conform to the requirements + * specified in #61227 as it is incompatible with standard primitives + * and may therefore be modified in the future. */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, @@ -641,33 +818,49 @@ enum ieee802154_config_type { IEEE802154_CONFIG_PRIV_START = IEEE802154_CONFIG_COMMON_COUNT, }; +/** + * Configuring an RX slot with the start parameter set to this value will cancel + * and delete any previously configured RX slot. + */ +#define IEEE802154_CONFIG_RX_SLOT_NONE -1LL + +/** + * Configuring an RX slot with this start parameter while the driver is "down", + * will keep RX off when the driver is being started. Configuring an RX slot + * with this start value while the driver is "up" will immediately switch RX off + * until either the slot is deleted, see @ref IEEE802154_CONFIG_RX_SLOT_NONE or + * a slot with a future start parameter is configured and that start time + * arrives. + */ +#define IEEE802154_CONFIG_RX_SLOT_OFF 0LL + /** IEEE 802.15.4 driver configuration data. */ struct ieee802154_config { /** Configuration data. */ union { - /** ``IEEE802154_CONFIG_AUTO_ACK_FPB`` */ + /** see @ref IEEE802154_CONFIG_AUTO_ACK_FPB */ struct { bool enabled; enum ieee802154_fpb_mode mode; } auto_ack_fpb; - /** ``IEEE802154_CONFIG_ACK_FPB`` */ + /** see @ref IEEE802154_CONFIG_ACK_FPB */ struct { uint8_t *addr; /* in little endian for both, short and extended address */ bool extended; bool enabled; } ack_fpb; - /** ``IEEE802154_CONFIG_PAN_COORDINATOR`` */ + /** see @ref IEEE802154_CONFIG_PAN_COORDINATOR */ bool pan_coordinator; - /** ``IEEE802154_CONFIG_PROMISCUOUS`` */ + /** see @ref IEEE802154_CONFIG_PROMISCUOUS */ bool promiscuous; - /** ``IEEE802154_CONFIG_EVENT_HANDLER`` */ + /** see @ref IEEE802154_CONFIG_EVENT_HANDLER */ ieee802154_event_cb_t event_handler; - /** ``IEEE802154_CONFIG_MAC_KEYS`` + /** see @ref IEEE802154_CONFIG_MAC_KEYS * Pointer to an array containing a list of keys used * for MAC encryption. Refer to secKeyIdLookupDescriptor and * secKeyDescriptor in IEEE 802.15.4 @@ -680,17 +873,21 @@ struct ieee802154_config { */ struct ieee802154_key *mac_keys; - /** ``IEEE802154_CONFIG_FRAME_COUNTER`` */ + /** see @ref IEEE802154_CONFIG_FRAME_COUNTER */ uint32_t frame_counter; - /** ``IEEE802154_CONFIG_RX_SLOT`` */ + /** see @ref IEEE802154_CONFIG_RX_SLOT */ struct { /** * Nanosecond resolution timestamp relative to the * network subsystem's local clock defining the start of * the RX window during which the receiver is expected - * to be listening (i.e. not including any startup - * times). + * to be listening (i.e. not including any driver + * startup times). + * + * Configuring an rx_slot with the start attribute set + * to -1 will cancel and delete any previously active rx + * slot. */ net_time_t start; @@ -698,7 +895,11 @@ struct ieee802154_config { * Nanosecond resolution duration of the RX window * relative to the above RX window start time during * which the receiver is expected to be listening (i.e. - * not including any shutdown times). + * not including any shutdown times). Only positive + * values larger than or equal zero are allowed. + * + * Setting the duration to zero will disable the + * receiver, no matter what the start parameter. */ net_time_t duration; @@ -706,7 +907,7 @@ struct ieee802154_config { } rx_slot; /** - * ``IEEE802154_CONFIG_CSL_PERIOD`` + * see @ref IEEE802154_CONFIG_CSL_PERIOD * * The CSL period in units of 10 symbol periods, * see section 7.4.2.3. @@ -716,16 +917,16 @@ struct ieee802154_config { uint32_t csl_period; /** - * ``IEEE802154_CONFIG_CSL_RX_TIME`` + * see @ref IEEE802154_CONFIG_CSL_RX_TIME * * Nanosecond resolution timestamp relative to the network * subsystem's local clock defining the center of the CSL RX window * at which the receiver is expected to be fully started up - * (i.e. not including any startup times). + * (i.e. not including any startup times). */ net_time_t csl_rx_time; - /** ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` */ + /** see @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE */ struct { /** * header IEs to be added to the Enh-Ack frame @@ -733,10 +934,26 @@ struct ieee802154_config { * in little endian */ const uint8_t *data; + + /** length of the header IEs */ uint16_t data_len; - /** in CPU byte order */ + + /** + * Filters the devices that will receive this IE by + * short address. MAY be set to @ref + * IEEE802154_BROADCAST_ADDRESS to disable the filter. + * + * in CPU byte order + */ uint16_t short_addr; - /** in big endian */ + + /** + * Filters the devices that will receive this IE by + * extended address. MAY be set to NULL to disable the + * filter. + * + * in big endian + */ const uint8_t *ext_addr; } ack_ie; }; @@ -795,7 +1012,7 @@ struct ieee802154_attr_value { union { /** * @brief A bit field that represents the supported channel - * pages, see ieee802154_phy_channel_page. + * pages, see @ref ieee802154_phy_channel_page. * * @note To keep the API extensible as required by the standard, * we model supported pages as a bitmap to support drivers that @@ -823,8 +1040,8 @@ struct ieee802154_attr_value { * @details The selected channel page corresponds to the * phyCurrentPage PHY PIB attribute, see the description of * phy_supported_channel_pages above. Currently it can be - * retrieved via the IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES - * attribute. + * retrieved via the @ref + * IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_PAGES attribute. * * Most drivers will expose a single channel page with a single, * often zero-based, fixed channel range. @@ -911,16 +1128,72 @@ static inline int ieee802154_attr_get_channel_page_and_range( * only implement L1/radio (PHY) features but also L2 (MAC) features if the * vendor-specific driver hardware or firmware offers offloading opportunities. * - * While L1-level driver features are exclusively implemented by drivers and MAY - * be mandatory to support certain application requirements, L2 features SHOULD - * be optional by default and only need to be implemented for performance - * optimization or precise timing as deemed necessary by driver maintainers. - * Fallback implementations ("Soft MAC") SHOULD be provided in the + * @details While L1-level driver features are exclusively implemented by + * drivers and MAY be mandatory to support certain application requirements, L2 + * features SHOULD be optional by default and only need to be implemented for + * performance optimization or precise timing as deemed necessary by driver + * maintainers. Fallback implementations ("Soft MAC") SHOULD be provided in the * driver-independent L2 layer for all L2/MAC features especially if these * features are not implemented in vendor hardware/firmware by a majority of * existing in-tree drivers. If, however, a driver offers offloading * opportunities then L2 implementations SHALL delegate performance critical or * resource intensive tasks to the driver. + * + * All drivers SHALL support two externally observable interface operational + * states: "UP" and "DOWN". Drivers MAY additionally support a "TESTING" + * interface state (see `continuous_carrier()`). + * + * The following rules apply: + * * An interface is considered "UP" when it is able to transmit and receive + * packets, "DOWN" otherwise (see precise definitions of the corresponding + * ifOperStatus values in RFC 2863, section 3.1.14, @ref net_if_oper_state and + * the `continuous_carrier()` exception below). A device that has its receiver + * temporarily disabled during "UP" state due to an active receive window + * configuration is still considered "UP". + * * Upper layers will assume that the interface managed by the driver is "UP" + * after a call to `start()` returned zero or `-EALREADY`. Upper layers assume + * that the interface is "DOWN" after calling `stop()` returned zero or + * `-EALREADY`. + * * The driver SHALL block `start()`/`stop()` calls until the interface fully + * transitioned to the new state (e.g. the receiver is operational, ongoing + * transmissions were finished, etc.). Drivers SHOULD yield the calling thread + * (i.e. "sleep") if waiting for the new state without CPU interaction is + * possible. + * * Drivers are responsible of guaranteeing atomicity of state changes. + * Appropriate means of synchronization SHALL be implemented (locking, atomic + * flags, ...). + * * While the interface is "DOWN", the driver SHALL be placed in the lowest + * possible power state. The driver MAY return from a call to `stop()` before + * it reaches the lowest possible power state, i.e. manage power + * asynchronously. While the interface is "UP", the driver SHOULD + * autonomously and asynchronously transition to lower power states whenever + * possible. If the driver claims to support timed RX/TX capabilities and the + * upper layers configure an RX slot, then the driver SHALL immediately + * transition (asynchronously) to the lowest possible power state until the + * start of the RX slot or until a scheduled packet needs to be transmitted. + * * The driver SHALL NOT change the interface's "UP"/"DOWN" state on its own. + * Initially, the interface SHALL be in the "DOWN" state. + * * Drivers that implement the optional `continuous_carrier()` operation will + * be considered to be in the RFC 2863 "testing" ifOperStatus state if that + * operation returns zero. This state is active until either `start()` or + * `stop()` is called. If `continuous_carrier()` returns a non-zero value then + * the previous state is assumed by upper layers. + * * If calls to `start()`/`stop()` return any other value than zero or + * `-EALREADY`, upper layers will consider the interface to be in a + * "lowerLayerDown" state as defined in RFC 2863. + * * The RFC 2863 "dormant", "unknown" and "notPresent" ifOperStatus states are + * currently not supported. The "lowerLevelUp" state. + * * The `ed_scan()`, `cca()` and `tx()` operations SHALL only be supported in + * the "UP" state and return `-ENETDOWN` in any other state. See the + * function-level API documentation below for further details. + * + * @note In case of devices that support timed RX/TX, the "UP" state is not + * equal to "receiver enabled". If a receive window (i.e. RX slot, see @ref + * IEEE802154_CONFIG_RX_SLOT) is configured before calling `start()` then the + * receiver will not be enabled when transitioning to the "UP" state. + * Configuring a receive window while the interface is "UP" will cause the + * receiver to be disabled immediately until the configured reception time has + * arrived. */ struct ieee802154_radio_api { /** @@ -935,6 +1208,10 @@ struct ieee802154_radio_api { /** * @brief Get the device driver capabilities. * + * @note Implementations SHALL be **isr-ok** and MUST NOT **sleep**. MAY + * be called in any interface state once the driver is fully initialized + * ("ready"). + * * @param dev pointer to IEEE 802.15.4 driver device * * @return Bit field with all supported device driver capabilities. @@ -944,25 +1221,38 @@ struct ieee802154_radio_api { /** * @brief Clear Channel Assessment - Check channel's activity * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. SHALL + * return -ENETDOWN unless the interface is "UP". + * * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 the channel is available * @retval -EBUSY The channel is busy. - * @retval -EIO The CCA procedure could not be executed. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. + * @retval -ENETDOWN The interface is not "UP". * @retval -ENOTSUP CCA is not supported by this driver. + * @retval -EIO The CCA procedure could not be executed. */ int (*cca)(const struct device *dev); /** * @brief Set current channel * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. SHALL + * return -EIO unless the interface is either "UP" or "DOWN". + * * @param dev pointer to IEEE 802.15.4 driver device * @param channel the number of the channel to be set in CPU byte order * * @retval 0 channel was successfully set + * @retval -EALREADY The previous channel is the same as the requested + * channel. * @retval -EINVAL The given channel is not within the range of valid * channels of the driver's current channel page, see the * IEEE802154_ATTR_PHY_SUPPORTED_CHANNEL_RANGES driver attribute. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. * @retval -ENOTSUP The given channel is within the range of valid * channels of the driver's current channel page but unsupported by the * current driver. @@ -975,6 +1265,9 @@ struct ieee802154_radio_api { * * @note requires IEEE802154_HW_FILTER capability. * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. SHALL + * return -EIO unless the interface is either "UP" or "DOWN". + * * @param dev pointer to IEEE 802.15.4 driver device * @param set true to set the filter, false to remove it * @param type the type of entity to be added/removed from the filter @@ -984,6 +1277,8 @@ struct ieee802154_radio_api { * @retval 0 The filter was successfully added/removed. * @retval -EINVAL The given filter entity or filter entity type * was not valid. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. * @retval -ENOTSUP Setting/removing this filter or filter type * is not supported by this driver. * @retval -EIO Error while setting/removing the filter. @@ -996,12 +1291,17 @@ struct ieee802154_radio_api { /** * @brief Set TX power level in dbm * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. SHALL + * return -EIO unless the interface is either "UP" or "DOWN". + * * @param dev pointer to IEEE 802.15.4 driver device * @param dbm TX power in dbm * * @retval 0 The TX power was successfully set. * @retval -EINVAL The given dbm value is invalid or not supported by * the driver. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. * @retval -EIO The TX power could not be set. */ int (*set_txpower)(const struct device *dev, int16_t dbm); @@ -1009,21 +1309,53 @@ struct ieee802154_radio_api { /** * @brief Transmit a packet fragment as a single frame * - * @warning The driver must not take ownership of the given network + * @details Depending on the level of offloading features supported by + * the driver, the frame MAY not be fully encrypted/authenticated or it + * MAY not contain an FCS. It is the responsibility of L2 + * implementations to prepare the frame according to the offloading + * capabilities announced by the driver and to decide whether CCA, + * CSMA/CA, ACK or retransmission procedures need to be executed outside + * ("soft MAC") or inside ("hard MAC") the driver . + * + * All frames originating from L2 SHALL have all required IEs + * pre-allocated and pre-filled such that the driver does not have to + * parse and manipulate IEs at all. This includes ACK packets if the + * driver does not have the @ref IEEE802154_HW_RX_TX_ACK capability. + * Also see @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE for drivers that + * have the @ref IEEE802154_HW_RX_TX_ACK capability. + * + * IEs that cannot be prepared by L2 unless the TX time is known (e.g. + * CSL IE, Rendezvous Time IE, Time Correction IE, ...) SHALL be sent in + * any of the timed TX modes with appropriate timing information + * pre-filled in the IE such that drivers do not have to parse and + * manipulate IEs at all unless the frame is generated by the driver + * itself. + * + * In case any of the timed TX modes is supported and used (see @ref + * ieee802154_hw_caps and @ref ieee802154_tx_mode), the driver SHALL + * take responsibility of scheduling and sending the packet at the + * precise programmed time autonomously without further interaction by + * upper layers. The call to `tx()` will block until the package has + * either been sent successfully (possibly including channel acquisition + * and packet acknowledgment) or a terminal transmission error occurred. + * The driver SHALL sleep and keep power consumption to the lowest + * possible level until the scheduled transmission time arrives or + * during any other idle waiting time. + * + * @warning The driver SHALL NOT take ownership of the given network * packet and frame (fragment) buffer. Any data required by the driver - * (including the actual frame content) must be read synchronously and - * copied internally if transmission is delayed or executed - * asynchronously. Both, the packet and the buffer may be re-used or - * released immediately after the function returns. - * - * @note Depending on the level of offloading features supported by the - * driver, the frame may not be fully encrypted/authenticated, may not - * contain an FCS or may contain incomplete information elements (IEs). - * It is the responsibility of L2 implementations to prepare the frame - * according to the offloading capabilities announced by the driver and - * to decide whether CCA, CSMA/CA or ACK procedures need to be executed - * in software ("soft MAC") or will be provided by the driver itself - * ("hard MAC"). + * including the actual frame content must be read synchronously and + * copied internally if needed at a later time (e.g. the contents of IEs + * required for protocol configuration, states of frame counters, + * sequence numbers, etc). Both, the packet and the buffer MAY be + * re-used or released by upper layers immediately after the function + * returns. + * + * @note Implementations MAY **sleep** and will usually NOT be + * **isr-ok** - especially when timed TX, CSMA/CA, retransmissions, + * auto-ACK or any other offloading feature is supported that implies + * considerable idle waiting time. SHALL return `-ENETDOWN` unless the + * interface is "UP". * * @param dev pointer to IEEE 802.15.4 driver device * @param mode the transmission mode, some of which require specific @@ -1036,35 +1368,65 @@ struct ieee802154_radio_api { * supports ACK offloading and the frame requested acknowlegment (AR bit * set), this means that the packet was successfully acknowledged by its * peer. - * @retval -ENOTSUP The given TX mode is not supported. - * @retval -EIO The frame could not be sent due to some unspecified - * error. + * @retval -EINVAL Invalid packet (e.g. an expected IE is missing or the + * encryption/authentication state is not as expected). * @retval -EBUSY The frame could not be sent because the medium was * busy (CSMA/CA or CCA offloading feature only). * @retval -ENOMSG The frame was not confirmed by an ACK packet (TX ACK * offloading feature only). * @retval -ENOBUFS The frame could not be scheduled due to missing - * internal buffer resources (timed TX offloading feature only). + * internal resources (timed TX offloading feature only). + * @retval -ENETDOWN The interface is not "UP". + * @retval -ENOTSUP The given TX mode is not supported. + * @retval -EIO The frame could not be sent due to some unspecified + * driver error (e.g. the driver being busy). */ int (*tx)(const struct device *dev, enum ieee802154_tx_mode mode, struct net_pkt *pkt, struct net_buf *frag); /** - * @brief Start the device and place it in receive mode. + * @brief Start the device. + * + * @details Upper layers will assume the interface is "UP" if this + * operation returns with zero or `-EALREADY`. The interface is placed + * in receive mode before returning from this operation unless an RX + * slot has been configured (even if it lies in the past, see @ref + * IEEE802154_CONFIG_RX_SLOT). + * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. MAY be + * called in any interface state once the driver is fully initialized + * ("ready"). * * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 The driver was successfully started. + * @retval -EALREADY The driver was already "UP". + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. * @retval -EIO The driver could not be started. */ int (*start)(const struct device *dev); /** - * @brief Stop the device and switch off the receiver (sleep mode). + * @brief Stop the device. + * + * @details Upper layers will assume the interface is "DOWN" if this + * operation returns with zero or `-EALREADY`. The driver switches off + * the receiver before returning if it was previously on. The driver + * enters the lowest possible power mode after this operation is called. + * This MAY happen asynchronously (i.e. after the operation already + * returned control). + * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. MAY be + * called in any interface state once the driver is fully initialized + * ("ready"). * * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 The driver was successfully stopped. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. + * @retval -EALREADY The driver was already "DOWN". * @retval -EIO The driver could not be stopped. */ int (*stop)(const struct device *dev); @@ -1072,18 +1434,36 @@ struct ieee802154_radio_api { /** * @brief Start continuous carrier wave transmission. * - * @details To leave this mode, `start()` or `stop()` should be called, - * putting the driver in receive or sleep mode, respectively. + * @details The method blocks until the interface has started to emit a + * continuous carrier. To leave this mode, `start()` or `stop()` should + * be called, which will put the driver back into the "UP" or "DOWN" + * states, respectively. + * + * @note Implementations MAY **sleep** and will usually NOT be + * **isr-ok**. MAY be called in any interface state once the driver is + * fully initialized ("ready"). * * @param dev pointer to IEEE 802.15.4 driver device * * @retval 0 continuous carrier wave transmission started + * @retval -EALREADY The driver was already in "TESTING" state and + * emitting a continuous carrier. * @retval -EIO not started */ int (*continuous_carrier)(const struct device *dev); /** - * @brief Set driver configuration. + * @brief Set or update driver configuration. + * + * @details The method blocks until the interface has been reconfigured + * atomically with respect to ongoing package reception, transmission or + * any other ongoing driver operation. + * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. MAY be + * called in any interface state once the driver is fully initialized + * ("ready"). Some configuration options may not be supported in all + * interface operational states, see the detailed specifications in @ref + * ieee802154_config_type. In this case the operation returns `-EACCES`. * * @param dev pointer to IEEE 802.15.4 driver device * @param type the configuration type to be set @@ -1091,14 +1471,21 @@ struct ieee802154_radio_api { * configuration type * * @retval 0 configuration successful - * @retval -ENOTSUP The given configuration type is not supported by - * this driver. * @retval -EINVAL The configuration parameters are invalid for the * given configuration type. + * @retval -ENOTSUP The given configuration type is not supported by + * this driver. + * @retval -EACCES The given configuration type is supported by this + * driver but cannot be configured in the current interface operational + * state. * @retval -ENOMEM The configuration cannot be saved due to missing * memory resources. * @retval -ENOENT The resource referenced in the configuration * parameters cannot be found in the configuration. + * @retval -EWOULDBLOCK The operation is called from ISR context but + * temporarily cannot be executed without blocking. + * @retval -EIO An internal error occurred while trying to configure the + * given configuration parameter. */ int (*configure)(const struct device *dev, enum ieee802154_config_type type, @@ -1111,6 +1498,9 @@ struct ieee802154_radio_api { * * @note The radio channel must be set prior to calling this function. * + * @note Implementations SHALL be **isr-ok** and MAY **sleep**. SHALL + * return `-ENETDOWN` unless the interface is "UP". + * * @param dev pointer to IEEE 802.15.4 driver device * @param duration duration of energy scan in ms * @param done_cb function called when the energy scan has finished @@ -1121,7 +1511,9 @@ struct ieee802154_radio_api { * this time * @retval -EALREADY a previous energy detection scan has not finished * yet. + * @retval -ENETDOWN The interface is not "UP". * @retval -ENOTSUP This driver does not support energy scans. + * @retval -EIO The energy detection procedure could not be executed. */ int (*ed_scan)(const struct device *dev, uint16_t duration, @@ -1135,11 +1527,14 @@ struct ieee802154_radio_api { * See @ref net_time_t for semantic details. * * @note requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME - * capabilities. + * capabilities. Implementations SHALL be **isr-ok** and MUST NOT + * **sleep**. MAY be called in any interface state once the driver is + * fully initialized ("ready"). * * @param dev pointer to IEEE 802.15.4 driver device * - * @return nanoseconds relative to the network subsystem's local clock + * @return nanoseconds relative to the network subsystem's local clock, + * -1 if an error occurred or the operation is not supported */ net_time_t (*get_time)(const struct device *dev); @@ -1155,7 +1550,9 @@ struct ieee802154_radio_api { * capabilities. * * @note Implementations may estimate this value based on current - * operating conditions (e.g. temperature). + * operating conditions (e.g. temperature). Implementations SHALL be + * **isr-ok** and MUST NOT **sleep**. MAY be called in any interface + * state once the driver is fully initialized ("ready"). * * @param dev pointer to IEEE 802.15.4 driver device * @@ -1172,6 +1569,10 @@ struct ieee802154_radio_api { * and cannot be directly or indirectly derived by L2. Boolean * attributes SHALL be implemented as @ref ieee802154_hw_caps. * + * @note Implementations SHALL be **isr-ok** and MUST NOT **sleep**. MAY + * be called in any interface state once the driver is fully initialized + * ("ready"). + * * @retval 0 The requested attribute is supported by the driver and the * value can be retrieved from the corresponding @ref ieee802154_attr_value * member. @@ -1190,11 +1591,16 @@ struct ieee802154_radio_api { */ BUILD_ASSERT(offsetof(struct ieee802154_radio_api, iface_api) == 0); +/** @} */ + /** - * IEEE 802.15.4 driver utils + * @name IEEE 802.15.4 driver utils + * @{ */ +/** @cond INTERNAL_HIDDEN */ #define IEEE802154_AR_FLAG_SET (0x20) +/** INTERNAL_HIDDEN @endcond */ /** * @brief Check if AR flag is set on the frame inside given net_pkt @@ -1223,9 +1629,9 @@ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) * fast and re-usable generic implementation of this callback for * drivers to call when receiving an ACK packet. * - * Note: This function is part of Zephyr's 802.15.4 stack L1 -> L2 - * "inversion-of-control" adaptation API and must be implemented by - * all IEEE 802.15.4 L2 stacks. + * Note: This function is part of Zephyr's 802.15.4 stack driver -> L2 + * "inversion-of-control" adaptation API and must be implemented by all + * IEEE 802.15.4 L2 stacks. * * @param iface A valid pointer on a network interface that received the packet * @param pkt A valid pointer on a packet to check @@ -1246,9 +1652,9 @@ extern enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_p * @details Drivers must call this function as part of their own initialization * routine. * - * Note: This function is part of Zephyr's 802.15.4 stack L1 -> L2 - * "inversion-of-control" adaptation API and must be implemented by - * all IEEE 802.15.4 L2 stacks. + * Note: This function is part of Zephyr's 802.15.4 stack driver -> L2 + * "inversion-of-control" adaptation API and must be implemented by all + * IEEE 802.15.4 L2 stacks. * * @param iface A valid pointer on a network interface */ @@ -1258,6 +1664,8 @@ extern void ieee802154_init(struct net_if *iface); #define ieee802154_init(_iface_) #endif /* CONFIG_IEEE802154_RAW_MODE */ +/** @} */ + #ifdef __cplusplus } #endif From e63969521c3316f6fff35d06eb4514d572d47af5 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 11 Sep 2023 14:07:20 +0200 Subject: [PATCH 1304/4498] doc: ieee802154: mgmt: improved docs Hides types in the IEEE 802.15.4 net_mgmt sub-API that are of no public interest and improves documentation of the remainder. All constants that are not meant to be used by applications have been hidden. Only the API actually being of relevance to application developers is now publicly visible and documented. Signed-off-by: Florian Grandel --- doc/zephyr.doxyfile.in | 2 + include/zephyr/net/ieee802154_mgmt.h | 231 ++++++++++++++++++--------- 2 files changed, 157 insertions(+), 76 deletions(-) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 7565a7401ec..4ab6a73a894 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -2368,6 +2368,8 @@ PREDEFINED = __DOXYGEN__ \ CONFIG_HEAP_MEM_POOL_SIZE \ CONFIG_MMU \ CONFIG_NET_L2_ETHERNET_MGMT \ + CONFIG_NET_L2_IEEE802154_MGMT \ + CONFIG_NET_L2_IEEE802154_SECURITY \ CONFIG_NET_MGMT_EVENT \ CONFIG_NET_SOCKETS_POSIX_NAMES \ CONFIG_NET_TCP \ diff --git a/include/zephyr/net/ieee802154_mgmt.h b/include/zephyr/net/ieee802154_mgmt.h index ff91edd3ab8..3711e818d24 100644 --- a/include/zephyr/net/ieee802154_mgmt.h +++ b/include/zephyr/net/ieee802154_mgmt.h @@ -8,7 +8,7 @@ * @file * @brief IEEE 802.15.4 Management interface public header * - * All references to the standard in this file cite IEEE 802.15.4-2020. + * @note All references to the standard in this file cite IEEE 802.15.4-2020. */ #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_MGMT_H_ @@ -33,9 +33,15 @@ extern "C" { * Most of these commands are also accessible via shell commands. See the * shell's help feature (`shell> ieee802154 help`). * + * @note All section, table and figure references are to the IEEE 802.15.4-2020 + * standard. + * * @{ */ +/** + * @cond INTERNAL_HIDDEN + */ #define _NET_IEEE802154_LAYER NET_MGMT_LAYER_L2 #define _NET_IEEE802154_CODE 0x154 @@ -44,176 +50,245 @@ extern "C" { NET_MGMT_LAYER_CODE(_NET_IEEE802154_CODE)) #define _NET_IEEE802154_EVENT (_NET_IEEE802154_BASE | NET_MGMT_EVENT_BIT) -/* All attributes and parameters are given in CPU byte order - * (scalars) or big endian (byte arrays) unless otherwise - * specified. +enum net_request_ieee802154_cmd { + NET_REQUEST_IEEE802154_CMD_SET_ACK = 1, + NET_REQUEST_IEEE802154_CMD_UNSET_ACK, + NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN, + NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN, + NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN, + NET_REQUEST_IEEE802154_CMD_ASSOCIATE, + NET_REQUEST_IEEE802154_CMD_DISASSOCIATE, + NET_REQUEST_IEEE802154_CMD_SET_CHANNEL, + NET_REQUEST_IEEE802154_CMD_GET_CHANNEL, + NET_REQUEST_IEEE802154_CMD_SET_PAN_ID, + NET_REQUEST_IEEE802154_CMD_GET_PAN_ID, + NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR, + NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR, + NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR, + NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR, + NET_REQUEST_IEEE802154_CMD_GET_TX_POWER, + NET_REQUEST_IEEE802154_CMD_SET_TX_POWER, + NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS, + NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS, +}; + +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @name Command Macros + * + * @brief IEEE 802.15.4 net management commands. + * + * @details These IEEE 802.15.4 subsystem net management commands can be called + * by applications via @ref net_mgmt macro. * - * The following IEEE 802.15.4 MAC management service primitives - * are referenced below: + * All attributes and parameters are given in CPU byte order (scalars) or big + * endian (byte arrays) unless otherwise specified. + * + * The following IEEE 802.15.4 MAC management service primitives are referenced + * in this enumeration: * - MLME-ASSOCIATE.request, see section 8.2.3 * - MLME-DISASSOCIATE.request, see section 8.2.4 * - MLME-SET/GET.request, see section 8.2.6 * - MLME-SCAN.request, see section 8.2.11 * - * The following IEEE 802.15.4 MAC data service primitives - * are referenced below: + * The following IEEE 802.15.4 MAC data service primitives are referenced in + * this enumeration: * - MLME-DATA.request, see section 8.3.2 * * MAC PIB attributes (mac.../sec...): see sections 8.4.3 and 9.5. * PHY PIB attributes (phy...): see section 11.3. * Both are accessed through MLME-SET/GET primitives. + * + * @{ */ -enum net_request_ieee802154_cmd { - NET_REQUEST_IEEE802154_CMD_SET_ACK = 1, /* sets AckTx for all subsequent - * MLME-DATA (aka TX) requests - */ - NET_REQUEST_IEEE802154_CMD_UNSET_ACK, /* unsets AckTx for all subsequent - * MLME-DATA requests - */ - NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN, /* MLME-SCAN(PASSIVE, ...) request */ - NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN, /* MLME-SCAN(ACTIVE, ...) request */ - NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN, /* not-standard */ - NET_REQUEST_IEEE802154_CMD_ASSOCIATE, /* MLME-ASSOCIATE(...) request */ - NET_REQUEST_IEEE802154_CMD_DISASSOCIATE, /* MLME-DISASSOCIATE(...) request */ - NET_REQUEST_IEEE802154_CMD_SET_CHANNEL, /* MLME-SET(phyCurrentChannel) request */ - NET_REQUEST_IEEE802154_CMD_GET_CHANNEL, /* MLME-GET(phyCurrentChannel) request */ - NET_REQUEST_IEEE802154_CMD_SET_PAN_ID, /* MLME-SET(macPanId) request */ - NET_REQUEST_IEEE802154_CMD_GET_PAN_ID, /* MLME-GET(macPanId) request */ - NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR, /* non-standard, see chapters 7.1 and 8.4.3.1, in - * big endian byte order - */ - NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR, /* like MLME-GET(macExtendedAddress) but in big - * endian byte order - */ - NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR, /* MLME-SET(macShortAddress) request, only - * allowed for co-ordinators - */ - NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR, /* MLME-GET(macShortAddress) request */ - NET_REQUEST_IEEE802154_CMD_GET_TX_POWER, /* MLME-SET(phyUnicastTxPower/phyBroadcastTxPower) - * request (currently not distinguished) - */ - NET_REQUEST_IEEE802154_CMD_SET_TX_POWER, /* MLME-GET(phyUnicastTxPower/phyBroadcastTxPower) - * request - */ - - NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS, /* implies macSecurityEnabled=true, - * configures basic sec* MAC PIB - * attributes - */ - NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS, /* gets the configured sec* attributes */ -}; - -#define NET_REQUEST_IEEE802154_SET_ACK \ - (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_ACK) +/** Sets AckTx for all subsequent MLME-DATA (aka TX) requests. */ +#define NET_REQUEST_IEEE802154_SET_ACK (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_ACK) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_ACK); -#define NET_REQUEST_IEEE802154_UNSET_ACK \ +/** Unsets AckTx for all subsequent MLME-DATA requests. */ +#define NET_REQUEST_IEEE802154_UNSET_ACK \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_UNSET_ACK) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_UNSET_ACK); -#define NET_REQUEST_IEEE802154_PASSIVE_SCAN \ +/** + * MLME-SCAN(PASSIVE, ...) request + * + * See @ref ieee802154_req_params for associated command parameters. + */ +#define NET_REQUEST_IEEE802154_PASSIVE_SCAN \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_PASSIVE_SCAN); -#define NET_REQUEST_IEEE802154_ACTIVE_SCAN \ +/** + * MLME-SCAN(ACTIVE, ...) request + * + * See @ref ieee802154_req_params for associated command parameters. + */ +#define NET_REQUEST_IEEE802154_ACTIVE_SCAN \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ACTIVE_SCAN); -#define NET_REQUEST_IEEE802154_CANCEL_SCAN \ +/** Cancels an ongoing MLME-SCAN(...) command (non-standard). */ +#define NET_REQUEST_IEEE802154_CANCEL_SCAN \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_CANCEL_SCAN); -#define NET_REQUEST_IEEE802154_ASSOCIATE \ +/** MLME-ASSOCIATE(...) request */ +#define NET_REQUEST_IEEE802154_ASSOCIATE \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_ASSOCIATE) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ASSOCIATE); -#define NET_REQUEST_IEEE802154_DISASSOCIATE \ +/** MLME-DISASSOCIATE(...) request */ +#define NET_REQUEST_IEEE802154_DISASSOCIATE \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_DISASSOCIATE) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_DISASSOCIATE); -#define NET_REQUEST_IEEE802154_SET_CHANNEL \ +/** MLME-SET(phyCurrentChannel) request */ +#define NET_REQUEST_IEEE802154_SET_CHANNEL \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_CHANNEL) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_CHANNEL); -#define NET_REQUEST_IEEE802154_GET_CHANNEL \ +/** MLME-GET(phyCurrentChannel) request */ +#define NET_REQUEST_IEEE802154_GET_CHANNEL \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_CHANNEL) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_CHANNEL); -#define NET_REQUEST_IEEE802154_SET_PAN_ID \ +/** MLME-SET(macPanId) request */ +#define NET_REQUEST_IEEE802154_SET_PAN_ID \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_PAN_ID) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_PAN_ID); -#define NET_REQUEST_IEEE802154_GET_PAN_ID \ +/** MLME-GET(macPanId) request */ +#define NET_REQUEST_IEEE802154_GET_PAN_ID \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_PAN_ID) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_PAN_ID); -#define NET_REQUEST_IEEE802154_SET_EXT_ADDR \ +/** + * Sets the extended interface address (non-standard), see sections 7.1 + * and 8.4.3.1, in big endian byte order + */ +#define NET_REQUEST_IEEE802154_SET_EXT_ADDR \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_EXT_ADDR); -#define NET_REQUEST_IEEE802154_GET_EXT_ADDR \ +/** like MLME-GET(macExtendedAddress) but in big endian byte order */ +#define NET_REQUEST_IEEE802154_GET_EXT_ADDR \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_EXT_ADDR); -#define NET_REQUEST_IEEE802154_SET_SHORT_ADDR \ +/** MLME-SET(macShortAddress) request, only allowed for co-ordinators */ +#define NET_REQUEST_IEEE802154_SET_SHORT_ADDR \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_SHORT_ADDR); -#define NET_REQUEST_IEEE802154_GET_SHORT_ADDR \ +/** MLME-GET(macShortAddress) request */ +#define NET_REQUEST_IEEE802154_GET_SHORT_ADDR \ (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_SHORT_ADDR); -#define NET_REQUEST_IEEE802154_GET_TX_POWER \ - (_NET_IEEE802154_BASE | \ - NET_REQUEST_IEEE802154_CMD_GET_TX_POWER) +/** + * MLME-SET(phyUnicastTxPower/phyBroadcastTxPower) request (currently + * not distinguished) + */ +#define NET_REQUEST_IEEE802154_GET_TX_POWER \ + (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_TX_POWER) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_TX_POWER); -#define NET_REQUEST_IEEE802154_SET_TX_POWER \ - (_NET_IEEE802154_BASE | \ - NET_REQUEST_IEEE802154_CMD_SET_TX_POWER) +/** MLME-GET(phyUnicastTxPower/phyBroadcastTxPower) request */ +#define NET_REQUEST_IEEE802154_SET_TX_POWER \ + (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_TX_POWER) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_TX_POWER); #ifdef CONFIG_NET_L2_IEEE802154_SECURITY -#define NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS \ - (_NET_IEEE802154_BASE | \ - NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS) +/** + * Configures basic sec* MAC PIB attributes, implies + * macSecurityEnabled=true. + * + * See @ref ieee802154_security_params for associated command parameters. + */ +#define NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS \ + (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS); -#define NET_REQUEST_IEEE802154_GET_SECURITY_SETTINGS \ - (_NET_IEEE802154_BASE | \ - NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS) +/** + * Gets the configured sec* attributes. + * + * See @ref ieee802154_security_params for associated command parameters. + */ +#define NET_REQUEST_IEEE802154_GET_SECURITY_SETTINGS \ + (_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_GET_SECURITY_SETTINGS); #endif /* CONFIG_NET_L2_IEEE802154_SECURITY */ +/** + * @} + */ + +/** + * @cond INTERNAL_HIDDEN + */ + enum net_event_ieee802154_cmd { NET_EVENT_IEEE802154_CMD_SCAN_RESULT = 1, }; +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @name Event Macros + * + * @brief IEEE 802.15.4 net management events. + * + * @details These IEEE 802.15.4 subsystem net management events can be + * subscribed to by applications via @ref net_mgmt_init_event_callback, @ref + * net_mgmt_add_event_callback and @ref net_mgmt_del_event_callback. + * + * @{ + */ + +/** + * Signals the result of the @ref NET_REQUEST_IEEE802154_ACTIVE_SCAN or @ref + * NET_REQUEST_IEEE802154_PASSIVE_SCAN net management commands. + * + * See @ref ieee802154_req_params for associated event parameters. + */ #define NET_EVENT_IEEE802154_SCAN_RESULT \ (_NET_IEEE802154_EVENT | NET_EVENT_IEEE802154_CMD_SCAN_RESULT) +/** + * @} + */ + +/** + * @cond INTERNAL_HIDDEN + */ #define IEEE802154_IS_CHAN_SCANNED(_channel_set, _chan) \ (_channel_set & BIT(_chan - 1)) @@ -222,6 +297,10 @@ enum net_event_ieee802154_cmd { #define IEEE802154_ALL_CHANNELS UINT32_MAX +/** + * INTERNAL_HIDDEN @endcond + */ + /** * @brief Scanning parameters * From e836427f97e291b6ccc5271f51f8eea5b5359f7b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 25 Sep 2023 11:43:39 +0200 Subject: [PATCH 1305/4498] tests: net: socket: reuseaddr_reuseport: Fix userspace testing net_context_foreach() is not a systemcall, therefore should not be used from userspace threads. Usage of this API made SO_REUSADDR/SO_REUSEPORT userspace tests unfunctional (crashing). Fix this by using CONFIG_NET_TCP_TIME_WAIT_DELAY instead for tests that involve TCP connections. Other tests don't really need to wait as there's no teardown delay on UDP or unconnected TCP contexts. Additionally, remove the platform exclude for qemu_x86 platform, as this was the sole reason the tests were crashing on that platform. Signed-off-by: Robert Lubos --- tests/net/socket/reuseaddr_reuseport/prj.conf | 1 + .../net/socket/reuseaddr_reuseport/src/main.c | 67 +++---------------- .../socket/reuseaddr_reuseport/testcase.yaml | 2 - 3 files changed, 9 insertions(+), 61 deletions(-) diff --git a/tests/net/socket/reuseaddr_reuseport/prj.conf b/tests/net/socket/reuseaddr_reuseport/prj.conf index 7ff751c8785..63b9e737e51 100644 --- a/tests/net/socket/reuseaddr_reuseport/prj.conf +++ b/tests/net/socket/reuseaddr_reuseport/prj.conf @@ -39,6 +39,7 @@ CONFIG_TEST_RANDOM_GENERATOR=y # Reduce the retry count, so the close always finishes within a second CONFIG_NET_TCP_RETRY_COUNT=3 CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT=120 +CONFIG_NET_TCP_TIME_WAIT_DELAY=200 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y diff --git a/tests/net/socket/reuseaddr_reuseport/src/main.c b/tests/net/socket/reuseaddr_reuseport/src/main.c index db047ac9cf4..1ab9be96e9a 100644 --- a/tests/net/socket/reuseaddr_reuseport/src/main.c +++ b/tests/net/socket/reuseaddr_reuseport/src/main.c @@ -237,51 +237,6 @@ static void test_recv_fail(int sock, void *buf, size_t max_len, int flags) zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno); } -static void calc_net_context(struct net_context *context, void *user_data) -{ - int *count = user_data; - - (*count)++; -} - -/* Wait until the number of TCP contexts reaches a certain level - * exp_num_contexts : The number of contexts to wait for - * timeout : The time to wait for - */ -int wait_for_n_tcp_contexts(int exp_num_contexts, k_timeout_t timeout) -{ - uint32_t start_time = k_uptime_get_32(); - uint32_t time_diff; - int context_count = 0; - - /* After the client socket closing, the context count should be 1 less */ - net_context_foreach(calc_net_context, &context_count); - - time_diff = k_uptime_get_32() - start_time; - - /* Eventually the client socket should be cleaned up */ - while (context_count != exp_num_contexts) { - context_count = 0; - net_context_foreach(calc_net_context, &context_count); - k_sleep(K_MSEC(50)); - time_diff = k_uptime_get_32() - start_time; - - if (K_MSEC(time_diff).ticks > timeout.ticks) { - return -ETIMEDOUT; - } - } - - return 0; -} - -static void test_context_cleanup(void) -{ - zassert_equal(wait_for_n_tcp_contexts(0, TCP_TEARDOWN_TIMEOUT), - 0, - "Not all TCP contexts properly cleaned up"); -} - - ZTEST_USER(socket_reuseaddr_test_suite, test_enable_disable) { int server_sock = -1; @@ -321,8 +276,6 @@ ZTEST_USER(socket_reuseaddr_test_suite, test_enable_disable) zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value); close(server_sock); - - test_context_cleanup(); } @@ -359,8 +312,6 @@ static void test_reuseaddr_unspecified_specified_common(sa_family_t family, close(server_sock1); close(server_sock2); - - test_context_cleanup(); } ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_first_unspecified) @@ -440,8 +391,6 @@ static void test_reuseaddr_tcp_listening_common(sa_family_t family, close(server_sock1); close(server_sock2); - - test_context_cleanup(); } ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_unspecified_listening) @@ -526,7 +475,10 @@ static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family, close(client_sock); close(server_sock); - test_context_cleanup(); + /* Connection is in TIME_WAIT state, context will be released + * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it. + */ + k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY)); } ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_unspecified) @@ -601,8 +553,6 @@ ZTEST_USER(socket_reuseport_test_suite, test_enable_disable) zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value); close(server_sock); - - test_context_cleanup(); } @@ -644,8 +594,6 @@ static void test_reuseport_unspecified_specified_common(sa_family_t family, close(server_sock1); close(server_sock2); - - test_context_cleanup(); } ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_bad) @@ -879,8 +827,6 @@ static void test_reuseport_udp_server_client_common(sa_family_t family, close(accept_sock); close(client_sock); close(server_sock); - - test_context_cleanup(); } ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_both_not_set) @@ -990,7 +936,10 @@ static void test_reuseport_tcp_identical_clients_common(sa_family_t family, close(client_sock2); close(server_sock); - test_context_cleanup(); + /* Connection is in TIME_WAIT state, context will be released + * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it. + */ + k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY)); } ZTEST_USER(socket_reuseport_test_suite, test_ipv4_tcp_identical_clients) diff --git a/tests/net/socket/reuseaddr_reuseport/testcase.yaml b/tests/net/socket/reuseaddr_reuseport/testcase.yaml index b2d864d934c..dc3b15ca139 100644 --- a/tests/net/socket/reuseaddr_reuseport/testcase.yaml +++ b/tests/net/socket/reuseaddr_reuseport/testcase.yaml @@ -16,5 +16,3 @@ tests: net.socket.reuseaddr_reuseport.userspace: extra_configs: - CONFIG_TEST_USERSPACE=y - # FIXME: This test fails with an unknown error on qemu_x86 - platform_exclude: qemu_x86 From 3ffa1d5550928180cf24fcc5eb218bbc90d0eee1 Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Thu, 28 Sep 2023 10:09:26 +0300 Subject: [PATCH 1306/4498] net: coap: Fix coap client timeout Fix bug in timeout_expired() function. Coap client was resending pending messages after 500 ms (COAP_PERIODIC_TIMEOUT) and didn't wait for retransmission timeout. Use 64-bit k_uptime_get() Signed-off-by: Juha Ylinen --- subsys/net/lib/coap/coap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index f8ba4283648..d096e39c62f 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -369,7 +369,7 @@ static void report_callback_error(struct coap_client_internal_request *internal_ static bool timeout_expired(struct coap_client_internal_request *internal_req) { return (internal_req->request_ongoing && - internal_req->pending.timeout <= k_uptime_get_32()); + internal_req->pending.timeout <= (k_uptime_get() - internal_req->pending.t0)); } static int resend_request(struct coap_client *client, @@ -649,7 +649,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet /* Separate response coming */ if (payload_len == 0 && response_type == COAP_TYPE_ACK && response_code == COAP_CODE_EMPTY) { - internal_req->pending.t0 = k_uptime_get_32(); + internal_req->pending.t0 = k_uptime_get(); internal_req->pending.timeout = internal_req->pending.t0 + COAP_SEPARATE_TIMEOUT; internal_req->pending.retries = 0; return 1; From cc5766bc4b42faa49b0170cca97bd3c6ce5143ce Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 28 Sep 2023 15:00:39 +0200 Subject: [PATCH 1307/4498] tests: Bluetooth: Fix for btp_bap broadcast create/reconfig This updates the struct name for the create parameter, and fixes the call to reconfig. Signed-off-by: Emil Gydesen --- tests/bluetooth/tester/src/btp_bap.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 71a12dcbc54..5fc38c81dbb 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -1173,7 +1173,7 @@ static int setup_broadcast_source(uint8_t streams_per_subgroup, uint8_t subgroup stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; struct bt_bap_broadcast_source_subgroup_param subgroup_param[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; - struct bt_bap_broadcast_source_create_param create_param; + struct bt_bap_broadcast_source_param create_param; if (streams_per_subgroup * subgroups > CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT || subgroups > CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT) { @@ -1203,11 +1203,20 @@ static int setup_broadcast_source(uint8_t streams_per_subgroup, uint8_t subgroup LOG_DBG("Creating broadcast source with %zu subgroups with %zu streams", subgroups, subgroups * streams_per_subgroup); - err = bt_bap_broadcast_source_create(&create_param, source); - if (err != 0) { - LOG_DBG("Unable to create broadcast source: %d", err); + if (*source == NULL) { + err = bt_bap_broadcast_source_create(&create_param, source); + if (err != 0) { + LOG_DBG("Unable to create broadcast source: %d", err); - return err; + return err; + } + } else { + err = bt_bap_broadcast_source_reconfig(*source, &create_param); + if (err != 0) { + LOG_DBG("Unable to reconfig broadcast source: %d", err); + + return err; + } } return 0; @@ -1247,14 +1256,7 @@ static uint8_t broadcast_source_setup(const void *cmd, uint16_t cmd_len, broadcaster->qos.pd = sys_get_le24(cp->presentation_delay); broadcaster->qos.sdu = sys_le16_to_cpu(cp->max_sdu); - if (broadcast_source == NULL) { - err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, - &broadcast_source); - } else { - err = bt_bap_broadcast_source_reconfig(broadcast_source, &broadcaster->codec_cfg, - &broadcaster->qos); - } - + err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, &broadcast_source); if (err != 0) { LOG_DBG("Unable to setup broadcast source: %d", err); From 1f3605de21ef1ace85ba4aeced725411c1ed8ef4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 20 Sep 2023 19:17:26 +0000 Subject: [PATCH 1308/4498] drivers/flash/nrf: Workaround for nrf91 errata 7 Fix UICR read access. Signed-off-by: Dominik Ermel --- drivers/flash/soc_flash_nrf.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index fa433d1044b..cc840309264 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Nordic Semiconductor ASA + * Copyright (c) 2017-2023 Nordic Semiconductor ASA * Copyright (c) 2016 Linaro Limited * Copyright (c) 2016 Intel Corporation * @@ -116,6 +116,26 @@ static inline bool is_uicr_addr_valid(off_t addr, size_t len) #endif /* CONFIG_SOC_FLASH_NRF_UICR */ } +#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND) +static inline void nrf91_errata_7_enter(void) +{ + __disable_irq(); +} + +static inline void nrf91_errata_7_exit(void) +{ + __DSB(); + __enable_irq(); +} + +static void nrf_buffer_read_91_uicr(void *data, off_t addr, size_t len) +{ + nrf91_errata_7_enter(); + nrf_nvmc_buffer_read(data, (uint32_t)addr, len); + nrf91_errata_7_exit(); +} +#endif + static void nvmc_wait_ready(void) { while (!nrfx_nvmc_write_done_check()) { @@ -125,9 +145,11 @@ static void nvmc_wait_ready(void) static int flash_nrf_read(const struct device *dev, off_t addr, void *data, size_t len) { + const bool within_uicr = is_uicr_addr_valid(addr, len); + if (is_regular_addr_valid(addr, len)) { addr += DT_REG_ADDR(SOC_NV_FLASH_NODE); - } else if (!is_uicr_addr_valid(addr, len)) { + } else if (!within_uicr) { LOG_ERR("invalid address: 0x%08lx:%zu", (unsigned long)addr, len); return -EINVAL; @@ -137,6 +159,13 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return 0; } +#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND) + if (within_uicr) { + nrf_buffer_read_91_uicr(data, (uint32_t)addr, len); + return 0; + } +#endif + nrf_nvmc_buffer_read(data, (uint32_t)addr, len); return 0; From a32e7aaa102d87aa06bb2105e3678844956d2b71 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 23 Sep 2023 17:41:46 +1000 Subject: [PATCH 1309/4498] net: wifi_mgmt: update SSID storage type Update the storage type of the SSID strings to pointers to the strings, instead of needing to copy the strings into the struct. This substantially reduces the parameter struct size. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_mgmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ce7b720197b..ae5bf27370d 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -245,7 +245,7 @@ struct wifi_scan_params { uint16_t dwell_time_passive; /** Array of SSID strings to scan. */ - char ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX][WIFI_SSID_MAX_LEN + 1]; + const char *ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX]; /** Specifies the maximum number of scan results to return. These results would be the * BSSIDS with the best RSSI values, in all the scanned channels. This should only be * used to limit the number of returned scan results, and cannot be counted upon to limit From 3b7237e6cd9592abba074822690c49bb774634e8 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 23 Sep 2023 17:47:30 +1000 Subject: [PATCH 1310/4498] net: wifi: shell: update SSID argument format Instead of providing a comma seperated list of SSIDs, provide the SSIDs individually. This substantially simplifies the implementation. Signed-off-by: Jordan Yates --- include/zephyr/net/wifi_utils.h | 6 +++-- subsys/net/l2/wifi/wifi_shell.c | 8 ++++--- subsys/net/l2/wifi/wifi_utils.c | 41 ++++++++------------------------- 3 files changed, 19 insertions(+), 36 deletions(-) diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index 4284138b6f3..c9ef9979f91 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -63,13 +63,15 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); * as a comma separated string and convert it to an array. * * @param scan_ssids_str List of SSIDs expressed as a comma separated list. - * @param ssids Pointer to an array where the parsed SSIDs are to be stored. + * @param ssids Pointer to an array where the SSIDs pointers are to be stored. + * @param num_ssids Maximum number of SSIDs that can be stored. * * @retval 0 on success. * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, - char ssids[][WIFI_SSID_MAX_LEN + 1]); + const char *ssids[], + uint8_t num_ssids); /** diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d8e2ec756ba..a39f75919f5 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -480,7 +480,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"bands", required_argument, 0, 'b'}, {"dwell_time_active", required_argument, 0, 'a'}, {"dwell_time_passive", required_argument, 0, 'p'}, - {"ssids", required_argument, 0, 's'}, + {"ssid", required_argument, 0, 's'}, {"max_bss", required_argument, 0, 'm'}, {"chans", required_argument, 0, 'c'}, {"help", no_argument, 0, 'h'}, @@ -537,7 +537,9 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 's': - if (wifi_utils_parse_scan_ssids(optarg, params->ssids)) { + if (wifi_utils_parse_scan_ssids(optarg, + params->ssids, + ARRAY_SIZE(params->ssids))) { shell_fprintf(sh, SHELL_ERROR, "Invalid SSID(s)\n"); return -ENOEXEC; } @@ -1653,7 +1655,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" - "[-s, --ssids ] : SSID list to scan for.\n" + "[-s, --ssid : SSID to scan for. Can be provided multiple times.\n" "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" "[-h, --help] : Print out the help for the scan command.", diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 4c50b817d26..52d25d90566 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -263,12 +263,9 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) } int wifi_utils_parse_scan_ssids(char *scan_ssids_str, - char ssids[][WIFI_SSID_MAX_LEN + 1]) + const char *ssids[], + uint8_t num_ssids) { - char parse_str[(WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1)) + 1]; - char *ssid = NULL; - char *ctx = NULL; - uint8_t i = 0; int len; if (!scan_ssids_str) { @@ -276,41 +273,23 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, } len = strlen(scan_ssids_str); - - if (len > (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))) { + if (len > WIFI_SSID_MAX_LEN) { NET_ERR("SSID string (%s) size (%d) exceeds maximum allowed value (%d)", scan_ssids_str, len, - (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))); + WIFI_SSID_MAX_LEN); return -EINVAL; } - strncpy(parse_str, scan_ssids_str, len); - parse_str[len] = '\0'; - - ssid = strtok_r(parse_str, ",", &ctx); - - while (ssid) { - if (strlen(ssid) > WIFI_SSID_MAX_LEN) { - NET_ERR("SSID length (%zu) exceeds maximum value (%d) for SSID %s", - strlen(ssid), - WIFI_SSID_MAX_LEN, - ssid); - return -EINVAL; - } - - if (i >= WIFI_MGMT_SCAN_SSID_FILT_MAX) { - NET_WARN("Exceeded maximum allowed (%d) SSIDs. Ignoring SSIDs %s onwards", - WIFI_MGMT_SCAN_SSID_FILT_MAX, - ssid); - break; + for (int i = 0; i < num_ssids; i++) { + if (ssids[i] != NULL) { + continue; } - - strcpy(&ssids[i++][0], ssid); - - ssid = strtok_r(NULL, ",", &ctx); + ssids[i] = scan_ssids_str; + return 0; } + NET_WARN("Exceeded maximum allowed SSIDs (%d)", num_ssids); return 0; } From 2b92598df12ce66d6fc42327636c72c25fe6222b Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 23 Sep 2023 17:59:34 +1000 Subject: [PATCH 1311/4498] net: wifi: re-add `WIFI_MGMT_FORCED_PASSIVE_SCAN` Re-add the `WIFI_MGMT_FORCED_PASSIVE_SCAN` option removed in #62751. Now that `struct wifi_scan_params` is a reasonable size, we can enforce the passive scan request even when no parameter struct is supplied by the user. Signed-off-by: Jordan Yates --- subsys/net/l2/wifi/Kconfig | 9 +++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 8fbd6aff4d6..134448aa57f 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -39,6 +39,15 @@ config WIFI_MGMT_TWT_CHECK_IP even when it is awake intervals. Rejecting TWT setup till Wi-Fi interface has a valid IP address might be desirable in most scenarios. +config WIFI_MGMT_FORCED_PASSIVE_SCAN + bool "Force passive Wi-Fi scanning" + help + Always request a passive scan, regardless of the user supplied parameters. + This is typically used when the underlying hardware is not certified for + RF transmissions. This doesn't guarantee that passive scan will be used, + it depends on the underlying chip implementation to support and honour + scan type. + config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 1b763d3db1b..fd8fb3f865f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -326,6 +326,15 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } +#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN + struct wifi_scan_params default_params = {0}; + + if (params == NULL) { + params = &default_params; + } + params->scan_type = WIFI_SCAN_TYPE_PASSIVE; +#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */ + return wifi_mgmt_api->scan(dev, params, scan_result_cb); } From a3959af4f5e26a3caa3a6e05868b2efbff80c79c Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 22 Sep 2023 11:35:22 +0300 Subject: [PATCH 1312/4498] tests: spinlock: Increase thread execution to prevent quick exit On Intel boards (like intel_ehl_crb and intel_rpl_s_crb) for the trylock_test some part is executed very fast and since there is no synchronization, there might be situation when there is no trylock_failures. Increasing time spend in this part fixes the issue. Signed-off-by: Andrei Emeltchenko --- tests/kernel/spinlock/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/kernel/spinlock/src/main.c b/tests/kernel/spinlock/src/main.c index 656e986d4cd..248d7c83008 100644 --- a/tests/kernel/spinlock/src/main.c +++ b/tests/kernel/spinlock/src/main.c @@ -97,8 +97,9 @@ void bounce_once(int id, bool trylock) */ bounce_owner = id; - for (i = 0; i < 100; i++) { + for (i = 0; i < 5; i++) { zassert_true(bounce_owner == id, "Locked data changed"); + k_busy_wait(1); } /* Release the lock */ From bf4dc3101541a7ba5da47bc299811f45c0193a7b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 22 Sep 2023 12:02:56 +0300 Subject: [PATCH 1313/4498] tests: spinlock: Make local functions static Make local functions static. Signed-off-by: Andrei Emeltchenko --- tests/kernel/spinlock/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/kernel/spinlock/src/main.c b/tests/kernel/spinlock/src/main.c index 248d7c83008..49652537bab 100644 --- a/tests/kernel/spinlock/src/main.c +++ b/tests/kernel/spinlock/src/main.c @@ -55,7 +55,7 @@ ZTEST(spinlock, test_spinlock_basic) zassert_true(!z_spin_is_locked(&l), "Spinlock failed to unlock"); } -void bounce_once(int id, bool trylock) +static void bounce_once(int id, bool trylock) { int ret; int i, locked; @@ -106,7 +106,7 @@ void bounce_once(int id, bool trylock) k_spin_unlock(&bounce_lock, key); } -void cpu1_fn(void *p1, void *p2, void *p3) +static void cpu1_fn(void *p1, void *p2, void *p3) { ARG_UNUSED(p1); ARG_UNUSED(p2); @@ -188,7 +188,7 @@ ZTEST(spinlock, test_spinlock_mutual_exclusion) zassert_true(!z_spin_is_locked(&lock_runtime), "Spinlock failed to unlock"); } -void trylock_fn(void *p1, void *p2, void *p3) +static void trylock_fn(void *p1, void *p2, void *p3) { ARG_UNUSED(p1); ARG_UNUSED(p2); From 9e6960fe90af0ab77cb9805d99536fe1cbf805bb Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 21 Sep 2023 11:47:58 +0300 Subject: [PATCH 1314/4498] boards: x86: Indicate smp support for ADL and EHL boards Indicate SMP support to be able to run related tests on the boards. Signed-off-by: Andrei Emeltchenko --- boards/x86/intel_adl/intel_adl_crb.yaml | 1 + boards/x86/intel_adl/intel_adl_rvp.yaml | 1 + boards/x86/intel_ehl/intel_ehl_crb.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/boards/x86/intel_adl/intel_adl_crb.yaml b/boards/x86/intel_adl/intel_adl_crb.yaml index 58810300c16..a49e0864f92 100644 --- a/boards/x86/intel_adl/intel_adl_crb.yaml +++ b/boards/x86/intel_adl/intel_adl_crb.yaml @@ -12,6 +12,7 @@ supported: - rtc - i2c - spi + - smp testing: timeout_multiplier: 4 ignore_tags: diff --git a/boards/x86/intel_adl/intel_adl_rvp.yaml b/boards/x86/intel_adl/intel_adl_rvp.yaml index a93e5eea549..ce009bfe33b 100644 --- a/boards/x86/intel_adl/intel_adl_rvp.yaml +++ b/boards/x86/intel_adl/intel_adl_rvp.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr ram: 2048 supported: + - smp - watchdog testing: timeout_multiplier: 4 diff --git a/boards/x86/intel_ehl/intel_ehl_crb.yaml b/boards/x86/intel_ehl/intel_ehl_crb.yaml index 7b0cddebc15..4e9d07e9caf 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb.yaml +++ b/boards/x86/intel_ehl/intel_ehl_crb.yaml @@ -9,6 +9,7 @@ ram: 2048 supported: - gpio - smbus + - smp - rtc - watchdog testing: From 21d7c2db6da781c224809e2cc9e5d1dc6b13a180 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Thu, 21 Sep 2023 23:43:32 -0700 Subject: [PATCH 1315/4498] drivers: sensor: npcx: fix debug message when port B is captured Fix wrong debug message when port B of tachometer is captured. Signed-off-by: Evan Chang Signed-off-by: Mulin Chao --- drivers/sensor/nuvoton_tach_npcx/tach_nuvoton_npcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/nuvoton_tach_npcx/tach_nuvoton_npcx.c b/drivers/sensor/nuvoton_tach_npcx/tach_nuvoton_npcx.c index c1654afee39..b373d998b64 100644 --- a/drivers/sensor/nuvoton_tach_npcx/tach_nuvoton_npcx.c +++ b/drivers/sensor/nuvoton_tach_npcx/tach_nuvoton_npcx.c @@ -176,7 +176,7 @@ static inline bool tach_npcx_is_captured(const struct device *dev) LOG_DBG("port A is captured %d, port b is captured %d", IS_BIT_SET(inst->TECTRL, NPCX_TECTRL_TAPND), - IS_BIT_SET(inst->TECTRL, NPCX_TECTRL_TAPND)); + IS_BIT_SET(inst->TECTRL, NPCX_TECTRL_TBPND)); /* * In mode 5, the flag TAPND or TBPND indicates a input captured on From a46f1b9c3304d870a8e3c774d10929473d0b1956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 21 Aug 2023 15:30:26 +0200 Subject: [PATCH 1316/4498] kernel: Fix unused-parameter warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing ARG_UNUSED where needed. Signed-off-by: Benjamin Cabé --- kernel/queue.c | 3 +++ kernel/sched.c | 9 +++++++++ kernel/thread.c | 9 +++++++++ kernel/work.c | 3 +++ 4 files changed, 24 insertions(+) diff --git a/kernel/queue.c b/kernel/queue.c index 07435973307..7e6102ee4de 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -88,6 +88,9 @@ static inline void handle_poll_events(struct k_queue *queue, uint32_t state) { #ifdef CONFIG_POLL z_handle_obj_poll_events(&queue->poll_events, state); +#else + ARG_UNUSED(queue); + ARG_UNUSED(state); #endif } diff --git a/kernel/sched.c b/kernel/sched.c index f668c181a27..028827666ee 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -77,6 +77,7 @@ static inline int is_metairq(struct k_thread *thread) return (thread->base.prio - K_HIGHEST_THREAD_PRIO) < CONFIG_NUM_METAIRQ_PRIORITIES; #else + ARG_UNUSED(thread); return 0; #endif } @@ -219,6 +220,7 @@ static ALWAYS_INLINE void *thread_runq(struct k_thread *thread) return &_kernel.cpus[cpu].ready_q.runq; #else + ARG_UNUSED(thread); return &_kernel.ready_q.runq; #endif } @@ -443,6 +445,8 @@ static inline int slice_time(struct k_thread *thread) if (thread->base.slice_ticks != 0) { ret = thread->base.slice_ticks; } +#else + ARG_UNUSED(thread); #endif return ret; } @@ -558,6 +562,8 @@ static void update_metairq_preempt(struct k_thread *thread) /* Returning from existing preemption */ _current_cpu->metairq_preempted = NULL; } +#else + ARG_UNUSED(thread); #endif } @@ -607,6 +613,7 @@ static bool thread_active_elsewhere(struct k_thread *thread) } } #endif + ARG_UNUSED(thread); return false; } @@ -1153,6 +1160,8 @@ void *z_get_next_switch_handle(void *interrupted) void z_priq_dumb_remove(sys_dlist_t *pq, struct k_thread *thread) { + ARG_UNUSED(pq); + __ASSERT_NO_MSG(!z_is_idle_thread_object(thread)); sys_dlist_remove(&thread->base.qnode_dlist); diff --git a/kernel/thread.c b/kernel/thread.c index 4f330b628cd..49b97e6cb4b 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -69,6 +69,9 @@ void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data) SYS_PORT_TRACING_FUNC_EXIT(k_thread, foreach); k_spin_unlock(&z_thread_monitor_lock, key); +#else + ARG_UNUSED(user_cb); + ARG_UNUSED(user_data); #endif } @@ -93,6 +96,9 @@ void k_thread_foreach_unlocked(k_thread_user_cb_t user_cb, void *user_data) SYS_PORT_TRACING_FUNC_EXIT(k_thread, foreach_unlocked); k_spin_unlock(&z_thread_monitor_lock, key); +#else + ARG_UNUSED(user_cb); + ARG_UNUSED(user_data); #endif } @@ -895,6 +901,7 @@ int z_impl_k_float_disable(struct k_thread *thread) #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) return arch_float_disable(thread); #else + ARG_UNUSED(thread); return -ENOTSUP; #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ } @@ -904,6 +911,8 @@ int z_impl_k_float_enable(struct k_thread *thread, unsigned int options) #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) return arch_float_enable(thread, options); #else + ARG_UNUSED(thread); + ARG_UNUSED(options); return -ENOTSUP; #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ } diff --git a/kernel/work.c b/kernel/work.c index 402b2f80517..010cd732183 100644 --- a/kernel/work.c +++ b/kernel/work.c @@ -598,6 +598,9 @@ bool k_work_cancel_sync(struct k_work *work, */ static void work_queue_main(void *workq_ptr, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct k_work_q *queue = (struct k_work_q *)workq_ptr; while (true) { From a8497c5216815a054a5229389c269a0c7ae30eb9 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Sat, 9 Sep 2023 13:39:39 +1200 Subject: [PATCH 1317/4498] kernel: msg_q: Remove alignment requirements from message queue docs Alignment of the message queue's ring buffer is not necessary. The underlying implementation uses memcpy (which is alignment-agnostic) and does not expose any internal pointers Signed-off-by: Grant Ramsay --- .../services/data_passing/message_queues.rst | 29 +++++-------------- include/zephyr/kernel.h | 14 ++++----- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/doc/kernel/services/data_passing/message_queues.rst b/doc/kernel/services/data_passing/message_queues.rst index 5e8d43eb4f2..afa33310484 100644 --- a/doc/kernel/services/data_passing/message_queues.rst +++ b/doc/kernel/services/data_passing/message_queues.rst @@ -25,11 +25,6 @@ A message queue has the following key properties: * A **maximum quantity** of data items that can be queued in the ring buffer. -The message queue's ring buffer must be aligned to an N-byte boundary, where -N is a power of 2 (i.e. 1, 2, 4, 8, ...). To ensure that the messages stored in -the ring buffer are similarly aligned to this boundary, the data item size -must also be a multiple of N. - A message queue must be initialized before it can be used. This sets its ring buffer to empty. @@ -64,6 +59,11 @@ the size of the receiving area *must* equal the message queue's data item size. The kernel does allow an ISR to receive an item from a message queue, however the ISR must not attempt to wait if the message queue is empty. +.. note:: + Alignment of the message queue's ring buffer is not necessary. + The underlying implementation uses :c:func:`memcpy` (which is + alignment-agnostic) and does not expose any internal pointers. + Implementation ************** @@ -84,7 +84,7 @@ that is capable of holding 10 items, each of which is 12 bytes long. uint32_t field3; }; - char __aligned(4) my_msgq_buffer[10 * sizeof(struct data_item_type)]; + char my_msgq_buffer[10 * sizeof(struct data_item_type)]; struct k_msgq my_msgq; k_msgq_init(&my_msgq, my_msgq_buffer, sizeof(struct data_item_type), 10); @@ -97,22 +97,7 @@ that the macro defines both the message queue and its buffer. .. code-block:: c - K_MSGQ_DEFINE(my_msgq, sizeof(struct data_item_type), 10, 4); - -The following code demonstrates an alignment implementation for the -structure defined in the previous example code. ``aligned`` means each -:c:struct:`data_item_type` will begin on the specified byte boundary. -``aligned(4)`` means that the structure is aligned to an address that -is divisible by 4. - -.. code-block:: c - - typedef struct { - uint32_t field1; - uint32_t field2; - uint32_t field3; - }__attribute__((aligned(4))) data_item_type; - + K_MSGQ_DEFINE(my_msgq, sizeof(struct data_item_type), 10, 1); Writing to a Message Queue ========================== diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index efaad0ce8ec..0ab33e85d42 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -4418,10 +4418,8 @@ struct k_msgq_attrs { * @brief Statically define and initialize a message queue. * * The message queue's ring buffer contains space for @a q_max_msgs messages, - * each of which is @a q_msg_size bytes long. The buffer is aligned to a - * @a q_align -byte boundary, which must be a power of 2. To ensure that each - * message is similarly aligned to this boundary, @a q_msg_size must also be - * a multiple of @a q_align. + * each of which is @a q_msg_size bytes long. Alignment of the message queue's + * ring buffer is not necessary, setting @a q_align to 1 is sufficient. * * The message queue can be accessed outside the module where it is defined * using: @@ -4431,7 +4429,7 @@ struct k_msgq_attrs { * @param q_name Name of the message queue. * @param q_msg_size Message size (in bytes). * @param q_max_msgs Maximum number of messages that can be queued. - * @param q_align Alignment of the message queue's ring buffer. + * @param q_align Alignment of the message queue's ring buffer (power of 2). * */ #define K_MSGQ_DEFINE(q_name, q_msg_size, q_max_msgs, q_align) \ @@ -4447,10 +4445,8 @@ struct k_msgq_attrs { * This routine initializes a message queue object, prior to its first use. * * The message queue's ring buffer must contain space for @a max_msgs messages, - * each of which is @a msg_size bytes long. The buffer must be aligned to an - * N-byte boundary, where N is a power of 2 (i.e. 1, 2, 4, ...). To ensure - * that each message is similarly aligned to this boundary, @a q_msg_size - * must also be a multiple of N. + * each of which is @a msg_size bytes long. Alignment of the message queue's + * ring buffer is not necessary. * * @param msgq Address of the message queue. * @param buffer Pointer to ring buffer that holds queued messages. From 8f5d0791bfc5c1a8be8d98e4b838ccd634fdc6db Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Sep 2023 14:30:30 -0700 Subject: [PATCH 1318/4498] sys/time_units.h: Convert time conversion to macros The intent of this patch is to leave all of the semantics of the macros unchanged, only replacing the easy-to-read static inline conversion function with a pile of ?: operators. Ick. This is not a cleanup. However, what it does enable is using constant results while initializing global variables, which cannot be done with either static inline functions or even statement expressions, even when those generate constant results. Signed-off-by: Keith Packard --- include/zephyr/sys/time_units.h | 1475 +++++++++++++++++-------------- lib/os/timeutil.c | 1 + 2 files changed, 815 insertions(+), 661 deletions(-) diff --git a/include/zephyr/sys/time_units.h b/include/zephyr/sys/time_units.h index 527b7371f23..359d73d8e7d 100644 --- a/include/zephyr/sys/time_units.h +++ b/include/zephyr/sys/time_units.h @@ -89,7 +89,7 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) * @retval true Use faster algorithm. * @retval false Use algorithm preventing overflow of intermediate value. */ -#define Z_TMCVT_USE_FAST_ALGO(from_hz, to_hz) \ +#define z_tmcvt_use_fast_algo(from_hz, to_hz) \ ((DIV_ROUND_UP(CONFIG_SYS_CLOCK_MAX_TIMEOUT_DAYS * 24ULL * 3600ULL * from_hz, \ UINT32_MAX) * to_hz) <= UINT32_MAX) @@ -111,70 +111,134 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) * round_up - Return the ceiling of the resulting fraction * round_off - Return the nearest value to the resulting fraction * (pass both round_up/off as false to get "round_down") + * + * All of this must be implemented as expressions so that, when constant, + * the results may be used to initialize global variables. */ -static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_hz, - uint32_t to_hz, bool const_hz, - bool result32, bool round_up, - bool round_off) -{ - bool mul_ratio = const_hz && - (to_hz > from_hz) && ((to_hz % from_hz) == 0U); - bool div_ratio = const_hz && - (from_hz > to_hz) && ((from_hz % to_hz) == 0U); - - if (from_hz == to_hz) { - return result32 ? ((uint32_t)t) : t; - } - - uint64_t off = 0; - - if (!mul_ratio) { - uint32_t rdivisor = div_ratio ? (from_hz / to_hz) : from_hz; - - if (round_up) { - off = rdivisor - 1U; - } - if (round_off) { - off = rdivisor / 2U; - } - } - - /* Select (at build time!) between three different expressions for - * the same mathematical relationship, each expressed with and - * without truncation to 32 bits (I couldn't find a way to make - * the compiler correctly guess at the 32 bit result otherwise). - */ - if (div_ratio) { - t += off; - if (result32 && (t < BIT64(32))) { - return ((uint32_t)t) / (from_hz / to_hz); - } else { - return t / ((uint64_t)from_hz / to_hz); - } - } else if (mul_ratio) { - if (result32) { - return ((uint32_t)t) * (to_hz / from_hz); - } else { - return t * ((uint64_t)to_hz / from_hz); - } - } else { - if (result32) { - return (uint32_t)((t * to_hz + off) / from_hz); - } else if (const_hz && Z_TMCVT_USE_FAST_ALGO(from_hz, to_hz)) { - /* Faster algorithm but source is first multiplied by target frequency - * and it can overflow even though final result would not overflow. - * Kconfig option shall prevent use of this algorithm when there is a - * risk of overflow. - */ - return ((t * to_hz + off) / from_hz); - } else { - /* Slower algorithm but input is first divided before being multiplied - * which prevents overflow of intermediate value. - */ - return (t / from_hz) * to_hz + ((t % from_hz) * to_hz + off) / from_hz; - } - } -} + +/* true if the conversion is the identity */ +#define z_tmcvt_is_identity(__from_hz, __to_hz) \ + ((__to_hz) == (__from_hz)) + +/* true if the conversion requires a simple integer multiply */ +#define z_tmcvt_is_int_mul(__from_hz, __to_hz) \ + ((__to_hz) > (__from_hz) && (__to_hz) % (__from_hz) == 0U) + +/* true if the conversion requires a simple integer division */ +#define z_tmcvt_is_int_div(__from_hz, __to_hz) \ + ((__from_hz) > (__to_hz) && (__from_hz) % (__to_hz) == 0U) + +/* + * Compute the offset needed to round the result correctly when + * the conversion requires a simple integer division + */ +#define z_tmcvt_off_div(__from_hz, __to_hz, __round_up, __round_off) \ + ((__round_off) ? ((__from_hz) / (__to_hz)) / 2 : \ + (__round_up) ? ((__from_hz) / (__to_hz)) - 1 : \ + 0) + +/* + * Compute the offset needed to round the result correctly when + * the conversion requires a full mul/div + */ +#define z_tmcvt_off_gen(__from_hz, __to_hz, __round_up, __round_off) \ + ((__round_off) ? (__from_hz) / 2 : \ + (__round_up) ? (__from_hz) - 1 : \ + 0) + +/* Integer division 32-bit conversion */ +#define z_tmcvt_int_div_32(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ((uint64_t) (__t) <= 0xffffffffU - \ + z_tmcvt_off_div(__from_hz, __to_hz, __round_up, __round_off) ? \ + ((uint32_t)((__t) + \ + z_tmcvt_off_div(__from_hz, __to_hz, \ + __round_up, __round_off)) / \ + ((__from_hz) / (__to_hz))) \ + : \ + (uint32_t) (((uint64_t) (__t) + \ + z_tmcvt_off_div(__from_hz, __to_hz, \ + __round_up, __round_off)) / \ + ((__from_hz) / (__to_hz))) \ + ) + +/* Integer multiplication 32-bit conversion */ +#define z_tmcvt_int_mul_32(__t, __from_hz, __to_hz) \ + (uint32_t) (__t)*((__to_hz) / (__from_hz)) + +/* General 32-bit conversion */ +#define z_tmcvt_gen_32(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ((uint32_t) (((uint64_t) (__t)*(__to_hz) + \ + z_tmcvt_off_gen(__from_hz, __to_hz, __round_up, __round_off)) / (__from_hz))) + +/* Integer division 64-bit conversion */ +#define z_tmcvt_int_div_64(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ((uint64_t) (__t) + z_tmcvt_off_div(__from_hz, __to_hz, \ + __round_up, __round_off)) / \ + ((__from_hz) / (__to_hz)) + +/* Integer multiplcation 64-bit conversion */ +#define z_tmcvt_int_mul_64(__t, __from_hz, __to_hz) \ + (uint64_t) (__t)*((__to_hz) / (__from_hz)) + +/* Fast 64-bit conversion. This relies on the multiply not overflowing */ +#define z_tmcvt_gen_64_fast(__t, __from_hz, __to_hz, __round_up, __round_off) \ + (((uint64_t) (__t)*(__to_hz) + \ + z_tmcvt_off_gen(__from_hz, __to_hz, __round_up, __round_off)) / (__from_hz)) + +/* Slow 64-bit conversion. This avoids overflowing the multiply */ +#define z_tmcvt_gen_64_slow(__t, __from_hz, __to_hz, __round_up, __round_off) \ + (((uint64_t) (__t) / (__from_hz))*(__to_hz) + \ + (((uint64_t) (__t) % (__from_hz))*(__to_hz) + \ + z_tmcvt_off_gen(__from_hz, __to_hz, __round_up, __round_off)) / (__from_hz)) + +/* General 64-bit conversion. Uses one of the two above macros */ +#define z_tmcvt_gen_64(__t, __from_hz, __to_hz, __round_up, __round_off) \ + (z_tmcvt_use_fast_algo(__from_hz, __to_hz) ? \ + z_tmcvt_gen_64_fast(__t, __from_hz, __to_hz, __round_up, __round_off) : \ + z_tmcvt_gen_64_slow(__t, __from_hz, __to_hz, __round_up, __round_off)) + +/* Convert, generating a 32-bit result */ +#define z_tmcvt_32(__t, __from_hz, __to_hz, __const_hz, __round_up, __round_off) \ + ((__const_hz) ? \ + ( \ + z_tmcvt_is_identity(__from_hz, __to_hz) ? \ + (uint32_t) (__t) \ + : \ + z_tmcvt_is_int_div(__from_hz, __to_hz) ? \ + z_tmcvt_int_div_32(__t, __from_hz, __to_hz, __round_up, __round_off) \ + : \ + z_tmcvt_is_int_mul(__from_hz, __to_hz) ? \ + z_tmcvt_int_mul_32(__t, __from_hz, __to_hz) \ + : \ + z_tmcvt_gen_32(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ) \ + : \ + z_tmcvt_gen_32(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ) + +/* Convert, generating a 64-bit result */ +#define z_tmcvt_64(__t, __from_hz, __to_hz, __const_hz, __round_up, __round_off) \ + ((__const_hz) ? \ + ( \ + z_tmcvt_is_identity(__from_hz, __to_hz) ? \ + (uint64_t) (__t) \ + : \ + z_tmcvt_is_int_div(__from_hz, __to_hz) ? \ + z_tmcvt_int_div_64(__t, __from_hz, __to_hz, __round_up, __round_off) \ + : \ + z_tmcvt_is_int_mul(__from_hz, __to_hz) ? \ + z_tmcvt_int_mul_64(__t, __from_hz, __to_hz) \ + : \ + z_tmcvt_gen_64(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ) \ + : \ + z_tmcvt_gen_64_slow(__t, __from_hz, __to_hz, __round_up, __round_off) \ + ) + +#define z_tmcvt(__t, __from_hz, __to_hz, __const_hz, __result32, __round_up, __round_off) \ + ((__result32) ? \ + z_tmcvt_32(__t, __from_hz, __to_hz, __const_hz, __round_up, __round_off) : \ + z_tmcvt_64(__t, __from_hz, __to_hz, __const_hz, __round_up, __round_off)) /* The following code is programmatically generated using this perl * code, which enumerates all possible combinations of units, rounding @@ -194,6 +258,9 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h * "ns" => "nanoseconds", * "cyc" => "hardware cycles", * "ticks" => "ticks"); + * my %human_round = ("ceil" => "Rounds up", + * "near" => "Round nearest", + * "floor" => "Truncates"); * * sub big { return $_[0] eq "us" || $_[0] eq "ns"; } * sub prefix { return $_[0] eq "ms" || $_[0] eq "us" || $_[0] eq "ns"; } @@ -206,16 +273,17 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h * for(my $big=0; $big <= 1; $big++) { * my $sz = $big ? 64 : 32; * my $sym = "k_${from_unit}_to_${to_unit}_$round$sz"; - * my $type = "u${sz}_t"; + * my $type = "uint${sz}_t"; * my $const_hz = ($from_unit eq "cyc" || $to_unit eq "cyc") * ? "Z_CCYC" : "true"; - * my $ret32 = $big ? "false" : "true"; + * my $ret32 = $big ? "64" : "32"; * my $rup = $round eq "ceil" ? "true" : "false"; * my $roff = $round eq "near" ? "true" : "false"; * * my $hfrom = $human{$from_unit}; * my $hto = $human{$to_unit}; - * print "/", "** \@brief Convert $hfrom to $hto\n"; + * my $hround = $human_round{$round}; + * print "/", "** \@brief Convert $hfrom to $hto. $ret32 bits. $hround.\n"; * print " *\n"; * print " * Converts time values in $hfrom to $hto.\n"; * print " * Computes result in $sz bit precision.\n"; @@ -227,14 +295,16 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h * print " * Truncates to the next lowest output unit.\n"; * } * print " *\n"; - * print " * \@return The converted time value\n"; + * print " * \@param t Source time in $hfrom. uint64_t\n"; + * print " *\n"; + * print " * \@return The converted time value in $hto. $type\n"; * print " *", "/\n"; * - * print "static TIME_CONSTEXPR inline $type $sym($type t)\n{\n\t"; - * print "/", "* Generated. Do not edit. See above. *", "/\n\t"; - * print "return z_tmcvt(t, Z_HZ_$from_unit, Z_HZ_$to_unit,"; - * print " $const_hz, $ret32, $rup, $roff);\n"; - * print "}\n\n"; + * print "/", "* Generated. Do not edit. See above. *", "/\n"; + * print "#define $sym(t) \\\n"; + * print "\tz_tmcvt_$ret32(t, Z_HZ_$from_unit, Z_HZ_$to_unit,"; + * print " $const_hz, $rup, $roff)\n"; + * print "\n\n"; * } * } * } @@ -251,1181 +321,1264 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h #define Z_HZ_ticks CONFIG_SYS_CLOCK_TICKS_PER_SEC #define Z_CCYC (!IS_ENABLED(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME)) -/** @brief Convert milliseconds to hardware cycles +/** @brief Convert milliseconds to hardware cycles. 32 bits. Truncates. * * Converts time values in milliseconds to hardware cycles. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_cyc_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, false) -/** @brief Convert milliseconds to hardware cycles + +/** @brief Convert milliseconds to hardware cycles. 64 bits. Truncates. * * Converts time values in milliseconds to hardware cycles. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_cyc_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert milliseconds to hardware cycles +/** @brief Convert milliseconds to hardware cycles. 32 bits. Round nearest. * * Converts time values in milliseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_cyc_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_near32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, true) -/** @brief Convert milliseconds to hardware cycles + +/** @brief Convert milliseconds to hardware cycles. 64 bits. Round nearest. * * Converts time values in milliseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_cyc_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_near64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, true) + -/** @brief Convert milliseconds to hardware cycles +/** @brief Convert milliseconds to hardware cycles. 32 bits. Rounds up. * * Converts time values in milliseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_cyc_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, true, false) + -/** @brief Convert milliseconds to hardware cycles +/** @brief Convert milliseconds to hardware cycles. 64 bits. Rounds up. * * Converts time values in milliseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_cyc_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_cyc_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_cyc, Z_CCYC, true, false) + -/** @brief Convert milliseconds to ticks +/** @brief Convert milliseconds to ticks. 32 bits. Truncates. * * Converts time values in milliseconds to ticks. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_ticks_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_ticks, true, false, false) + -/** @brief Convert milliseconds to ticks +/** @brief Convert milliseconds to ticks. 64 bits. Truncates. * * Converts time values in milliseconds to ticks. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_ticks_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_ticks, true, false, false) -/** @brief Convert milliseconds to ticks + +/** @brief Convert milliseconds to ticks. 32 bits. Round nearest. * * Converts time values in milliseconds to ticks. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_ticks_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_near32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_ticks, true, false, true) + -/** @brief Convert milliseconds to ticks +/** @brief Convert milliseconds to ticks. 64 bits. Round nearest. * * Converts time values in milliseconds to ticks. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_ticks_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_near64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_ticks, true, false, true) -/** @brief Convert milliseconds to ticks + +/** @brief Convert milliseconds to ticks. 32 bits. Rounds up. * * Converts time values in milliseconds to ticks. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ms_to_ticks_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ms, Z_HZ_ticks, true, true, false) + -/** @brief Convert milliseconds to ticks +/** @brief Convert milliseconds to ticks. 64 bits. Rounds up. * * Converts time values in milliseconds to ticks. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in milliseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ms_to_ticks_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ms, Z_HZ_ticks, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ms_to_ticks_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ms, Z_HZ_ticks, true, true, false) -/** @brief Convert microseconds to hardware cycles + +/** @brief Convert microseconds to hardware cycles. 32 bits. Truncates. * * Converts time values in microseconds to hardware cycles. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_cyc_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_floor32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert microseconds to hardware cycles +/** @brief Convert microseconds to hardware cycles. 64 bits. Truncates. * * Converts time values in microseconds to hardware cycles. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_cyc_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_floor64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, false) -/** @brief Convert microseconds to hardware cycles + +/** @brief Convert microseconds to hardware cycles. 32 bits. Round nearest. * * Converts time values in microseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_cyc_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_near32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, true) + -/** @brief Convert microseconds to hardware cycles +/** @brief Convert microseconds to hardware cycles. 64 bits. Round nearest. * * Converts time values in microseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_cyc_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_near64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, true) + -/** @brief Convert microseconds to hardware cycles +/** @brief Convert microseconds to hardware cycles. 32 bits. Rounds up. * * Converts time values in microseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_cyc_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, true, false) + -/** @brief Convert microseconds to hardware cycles +/** @brief Convert microseconds to hardware cycles. 64 bits. Rounds up. * * Converts time values in microseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_cyc_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_cyc_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_cyc, Z_CCYC, true, false) -/** @brief Convert microseconds to ticks + +/** @brief Convert microseconds to ticks. 32 bits. Truncates. * * Converts time values in microseconds to ticks. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_ticks_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_floor32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_ticks, true, false, false) + -/** @brief Convert microseconds to ticks +/** @brief Convert microseconds to ticks. 64 bits. Truncates. * * Converts time values in microseconds to ticks. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_ticks_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_floor64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_ticks, true, false, false) -/** @brief Convert microseconds to ticks + +/** @brief Convert microseconds to ticks. 32 bits. Round nearest. * * Converts time values in microseconds to ticks. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_ticks_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_near32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_ticks, true, false, true) + -/** @brief Convert microseconds to ticks +/** @brief Convert microseconds to ticks. 64 bits. Round nearest. * * Converts time values in microseconds to ticks. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_ticks_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_near64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_ticks, true, false, true) -/** @brief Convert microseconds to ticks + +/** @brief Convert microseconds to ticks. 32 bits. Rounds up. * * Converts time values in microseconds to ticks. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_us_to_ticks_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_us, Z_HZ_ticks, true, true, false) + -/** @brief Convert microseconds to ticks +/** @brief Convert microseconds to ticks. 64 bits. Rounds up. * * Converts time values in microseconds to ticks. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in microseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_us_to_ticks_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_us, Z_HZ_ticks, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_us_to_ticks_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_us, Z_HZ_ticks, true, true, false) + -/** @brief Convert nanoseconds to hardware cycles +/** @brief Convert nanoseconds to hardware cycles. 32 bits. Truncates. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_cyc_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert nanoseconds to hardware cycles +/** @brief Convert nanoseconds to hardware cycles. 64 bits. Truncates. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_cyc_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert nanoseconds to hardware cycles +/** @brief Convert nanoseconds to hardware cycles. 32 bits. Round nearest. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_cyc_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_near32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, true) -/** @brief Convert nanoseconds to hardware cycles + +/** @brief Convert nanoseconds to hardware cycles. 64 bits. Round nearest. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_cyc_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_near64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, true) + -/** @brief Convert nanoseconds to hardware cycles +/** @brief Convert nanoseconds to hardware cycles. 32 bits. Rounds up. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_cyc_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, true, false) + -/** @brief Convert nanoseconds to hardware cycles +/** @brief Convert nanoseconds to hardware cycles. 64 bits. Rounds up. * * Converts time values in nanoseconds to hardware cycles. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_cyc_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_cyc_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_cyc, Z_CCYC, true, false) -/** @brief Convert nanoseconds to ticks + +/** @brief Convert nanoseconds to ticks. 32 bits. Truncates. * * Converts time values in nanoseconds to ticks. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_ticks_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_ticks, true, false, false) + -/** @brief Convert nanoseconds to ticks +/** @brief Convert nanoseconds to ticks. 64 bits. Truncates. * * Converts time values in nanoseconds to ticks. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_ticks_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_ticks, true, false, false) + -/** @brief Convert nanoseconds to ticks +/** @brief Convert nanoseconds to ticks. 32 bits. Round nearest. * * Converts time values in nanoseconds to ticks. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_ticks_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_near32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_ticks, true, false, true) + -/** @brief Convert nanoseconds to ticks +/** @brief Convert nanoseconds to ticks. 64 bits. Round nearest. * * Converts time values in nanoseconds to ticks. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_ticks_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_near64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_ticks, true, false, true) + -/** @brief Convert nanoseconds to ticks +/** @brief Convert nanoseconds to ticks. 32 bits. Rounds up. * * Converts time values in nanoseconds to ticks. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ns_to_ticks_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ns, Z_HZ_ticks, true, true, false) -/** @brief Convert nanoseconds to ticks + +/** @brief Convert nanoseconds to ticks. 64 bits. Rounds up. * * Converts time values in nanoseconds to ticks. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in nanoseconds. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ns_to_ticks_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ns, Z_HZ_ticks, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ns_to_ticks_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ns, Z_HZ_ticks, true, true, false) + -/** @brief Convert hardware cycles to milliseconds +/** @brief Convert hardware cycles to milliseconds. 32 bits. Truncates. * * Converts time values in hardware cycles to milliseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ms_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_floor32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, false) -/** @brief Convert hardware cycles to milliseconds + +/** @brief Convert hardware cycles to milliseconds. 64 bits. Truncates. * * Converts time values in hardware cycles to milliseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ms_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_floor64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, false) + -/** @brief Convert hardware cycles to milliseconds +/** @brief Convert hardware cycles to milliseconds. 32 bits. Round nearest. * * Converts time values in hardware cycles to milliseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ms_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_near32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, true) -/** @brief Convert hardware cycles to milliseconds + +/** @brief Convert hardware cycles to milliseconds. 64 bits. Round nearest. * * Converts time values in hardware cycles to milliseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ms_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_near64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, true) + -/** @brief Convert hardware cycles to milliseconds +/** @brief Convert hardware cycles to milliseconds. 32 bits. Rounds up. * * Converts time values in hardware cycles to milliseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ms_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, true, false) + -/** @brief Convert hardware cycles to milliseconds +/** @brief Convert hardware cycles to milliseconds. 64 bits. Rounds up. * * Converts time values in hardware cycles to milliseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ms_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ms_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ms, Z_CCYC, true, false) + -/** @brief Convert hardware cycles to microseconds +/** @brief Convert hardware cycles to microseconds. 32 bits. Truncates. * * Converts time values in hardware cycles to microseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_us_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_floor32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, false) -/** @brief Convert hardware cycles to microseconds + +/** @brief Convert hardware cycles to microseconds. 64 bits. Truncates. * * Converts time values in hardware cycles to microseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_us_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_floor64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, false) + -/** @brief Convert hardware cycles to microseconds +/** @brief Convert hardware cycles to microseconds. 32 bits. Round nearest. * * Converts time values in hardware cycles to microseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_us_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_near32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, true) -/** @brief Convert hardware cycles to microseconds + +/** @brief Convert hardware cycles to microseconds. 64 bits. Round nearest. * * Converts time values in hardware cycles to microseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_us_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_near64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, true) + -/** @brief Convert hardware cycles to microseconds +/** @brief Convert hardware cycles to microseconds. 32 bits. Rounds up. * * Converts time values in hardware cycles to microseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_us_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, true, false) -/** @brief Convert hardware cycles to microseconds + +/** @brief Convert hardware cycles to microseconds. 64 bits. Rounds up. * * Converts time values in hardware cycles to microseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_us_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_us_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_us, Z_CCYC, true, false) + -/** @brief Convert hardware cycles to nanoseconds +/** @brief Convert hardware cycles to nanoseconds. 32 bits. Truncates. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ns_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_floor32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, false) -/** @brief Convert hardware cycles to nanoseconds + +/** @brief Convert hardware cycles to nanoseconds. 64 bits. Truncates. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ns_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_floor64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, false) + -/** @brief Convert hardware cycles to nanoseconds +/** @brief Convert hardware cycles to nanoseconds. 32 bits. Round nearest. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ns_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_near32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, true) + -/** @brief Convert hardware cycles to nanoseconds +/** @brief Convert hardware cycles to nanoseconds. 64 bits. Round nearest. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ns_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_near64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, true) + -/** @brief Convert hardware cycles to nanoseconds +/** @brief Convert hardware cycles to nanoseconds. 32 bits. Rounds up. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ns_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, true, false) + -/** @brief Convert hardware cycles to nanoseconds +/** @brief Convert hardware cycles to nanoseconds. 64 bits. Rounds up. * * Converts time values in hardware cycles to nanoseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ns_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ns_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ns, Z_CCYC, true, false) -/** @brief Convert hardware cycles to ticks + +/** @brief Convert hardware cycles to ticks. 32 bits. Truncates. * * Converts time values in hardware cycles to ticks. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ticks_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_floor32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, false) + -/** @brief Convert hardware cycles to ticks +/** @brief Convert hardware cycles to ticks. 64 bits. Truncates. * * Converts time values in hardware cycles to ticks. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ticks_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_floor64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, false) -/** @brief Convert hardware cycles to ticks + +/** @brief Convert hardware cycles to ticks. 32 bits. Round nearest. * * Converts time values in hardware cycles to ticks. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ticks_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_near32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, true) + -/** @brief Convert hardware cycles to ticks +/** @brief Convert hardware cycles to ticks. 64 bits. Round nearest. * * Converts time values in hardware cycles to ticks. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ticks_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_near64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, true) -/** @brief Convert hardware cycles to ticks + +/** @brief Convert hardware cycles to ticks. 32 bits. Rounds up. * * Converts time values in hardware cycles to ticks. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_cyc_to_ticks_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, true, false) + -/** @brief Convert hardware cycles to ticks +/** @brief Convert hardware cycles to ticks. 64 bits. Rounds up. * * Converts time values in hardware cycles to ticks. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in hardware cycles. uint64_t + * + * @return The converted time value in ticks. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_cyc_to_ticks_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_cyc_to_ticks_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_cyc, Z_HZ_ticks, Z_CCYC, true, false) -/** @brief Convert ticks to milliseconds + +/** @brief Convert ticks to milliseconds. 32 bits. Truncates. * * Converts time values in ticks to milliseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ms_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ms, true, false, false) + -/** @brief Convert ticks to milliseconds +/** @brief Convert ticks to milliseconds. 64 bits. Truncates. * * Converts time values in ticks to milliseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ms_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ms, true, false, false) -/** @brief Convert ticks to milliseconds + +/** @brief Convert ticks to milliseconds. 32 bits. Round nearest. * * Converts time values in ticks to milliseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ms_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_near32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ms, true, false, true) + -/** @brief Convert ticks to milliseconds +/** @brief Convert ticks to milliseconds. 64 bits. Round nearest. * * Converts time values in ticks to milliseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ms_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_near64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ms, true, false, true) -/** @brief Convert ticks to milliseconds + +/** @brief Convert ticks to milliseconds. 32 bits. Rounds up. * * Converts time values in ticks to milliseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ms_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ms, true, true, false) + -/** @brief Convert ticks to milliseconds +/** @brief Convert ticks to milliseconds. 64 bits. Rounds up. * * Converts time values in ticks to milliseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in milliseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ms_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ms, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ms_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ms, true, true, false) -/** @brief Convert ticks to microseconds + +/** @brief Convert ticks to microseconds. 32 bits. Truncates. * * Converts time values in ticks to microseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_us_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_us, true, false, false) + -/** @brief Convert ticks to microseconds +/** @brief Convert ticks to microseconds. 64 bits. Truncates. * * Converts time values in ticks to microseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_us_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_us, true, false, false) -/** @brief Convert ticks to microseconds + +/** @brief Convert ticks to microseconds. 32 bits. Round nearest. * * Converts time values in ticks to microseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_us_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_near32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_us, true, false, true) + -/** @brief Convert ticks to microseconds +/** @brief Convert ticks to microseconds. 64 bits. Round nearest. * * Converts time values in ticks to microseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_us_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_near64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_us, true, false, true) + -/** @brief Convert ticks to microseconds +/** @brief Convert ticks to microseconds. 32 bits. Rounds up. * * Converts time values in ticks to microseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_us_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_us, true, true, false) + -/** @brief Convert ticks to microseconds +/** @brief Convert ticks to microseconds. 64 bits. Rounds up. * * Converts time values in ticks to microseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in microseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_us_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_us, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_us_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_us, true, true, false) -/** @brief Convert ticks to nanoseconds + +/** @brief Convert ticks to nanoseconds. 32 bits. Truncates. * * Converts time values in ticks to nanoseconds. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ns_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ns, true, false, false) + -/** @brief Convert ticks to nanoseconds +/** @brief Convert ticks to nanoseconds. 64 bits. Truncates. * * Converts time values in ticks to nanoseconds. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ns_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ns, true, false, false) -/** @brief Convert ticks to nanoseconds + +/** @brief Convert ticks to nanoseconds. 32 bits. Round nearest. * * Converts time values in ticks to nanoseconds. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ns_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_near32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ns, true, false, true) + -/** @brief Convert ticks to nanoseconds +/** @brief Convert ticks to nanoseconds. 64 bits. Round nearest. * * Converts time values in ticks to nanoseconds. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ns_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_near64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ns, true, false, true) -/** @brief Convert ticks to nanoseconds + +/** @brief Convert ticks to nanoseconds. 32 bits. Rounds up. * * Converts time values in ticks to nanoseconds. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_ns_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_ns, true, true, false) + -/** @brief Convert ticks to nanoseconds +/** @brief Convert ticks to nanoseconds. 64 bits. Rounds up. * * Converts time values in ticks to nanoseconds. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in nanoseconds. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_ns_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_ns, true, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_ns_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_ns, true, true, false) + -/** @brief Convert ticks to hardware cycles +/** @brief Convert ticks to hardware cycles. 32 bits. Truncates. * * Converts time values in ticks to hardware cycles. * Computes result in 32 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_cyc_floor32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, true, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_floor32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert ticks to hardware cycles +/** @brief Convert ticks to hardware cycles. 64 bits. Truncates. * * Converts time values in ticks to hardware cycles. * Computes result in 64 bit precision. * Truncates to the next lowest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_cyc_floor64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, false, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_floor64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, false) + -/** @brief Convert ticks to hardware cycles +/** @brief Convert ticks to hardware cycles. 32 bits. Round nearest. * * Converts time values in ticks to hardware cycles. * Computes result in 32 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_cyc_near32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, true, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_near32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, true) -/** @brief Convert ticks to hardware cycles + +/** @brief Convert ticks to hardware cycles. 64 bits. Round nearest. * * Converts time values in ticks to hardware cycles. * Computes result in 64 bit precision. * Rounds to the nearest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_cyc_near64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, false, true); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_near64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, true) + -/** @brief Convert ticks to hardware cycles +/** @brief Convert ticks to hardware cycles. 32 bits. Rounds up. * * Converts time values in ticks to hardware cycles. * Computes result in 32 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint32_t */ -static TIME_CONSTEXPR inline uint32_t k_ticks_to_cyc_ceil32(uint32_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, true, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_ceil32(t) \ + z_tmcvt_32(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, true, false) + -/** @brief Convert ticks to hardware cycles +/** @brief Convert ticks to hardware cycles. 64 bits. Rounds up. * * Converts time values in ticks to hardware cycles. * Computes result in 64 bit precision. * Rounds up to the next highest output unit. * - * @return The converted time value + * @param t Source time in ticks. uint64_t + * + * @return The converted time value in hardware cycles. uint64_t */ -static TIME_CONSTEXPR inline uint64_t k_ticks_to_cyc_ceil64(uint64_t t) -{ - /* Generated. Do not edit. See above. */ - return z_tmcvt(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, false, true, false); -} +/* Generated. Do not edit. See above. */ +#define k_ticks_to_cyc_ceil64(t) \ + z_tmcvt_64(t, Z_HZ_ticks, Z_HZ_cyc, Z_CCYC, true, false) #if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME) #include diff --git a/lib/os/timeutil.c b/lib/os/timeutil.c index 4a3b8428f71..18c173acc8d 100644 --- a/lib/os/timeutil.c +++ b/lib/os/timeutil.c @@ -13,6 +13,7 @@ #include #include #include +#include #include /** Convert a civil (proleptic Gregorian) date to days relative to From 9c47239264e7e5e946e49eb06c80f9381d7ae865 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 26 Sep 2023 10:10:40 -0700 Subject: [PATCH 1319/4498] sys/time_units.h: Make SYS_TIMEOUT_MS usable as constant initializer To make this macro usable as an initializer for static or global data, it cannot have struct values within the expression, instead it must compute the tick value as a primitive value and then wrap that in the struct as the final step. Signed-off-by: Keith Packard --- include/zephyr/sys/time_units.h | 3 ++- include/zephyr/sys_clock.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/zephyr/sys/time_units.h b/include/zephyr/sys/time_units.h index 359d73d8e7d..318ffd3d0ce 100644 --- a/include/zephyr/sys/time_units.h +++ b/include/zephyr/sys/time_units.h @@ -40,7 +40,8 @@ extern "C" { /** @brief System-wide macro to convert milliseconds to kernel timeouts */ -#define SYS_TIMEOUT_MS(ms) ((ms) == SYS_FOREVER_MS ? K_FOREVER : K_MSEC(ms)) +#define SYS_TIMEOUT_MS(ms) Z_TIMEOUT_TICKS((ms) == SYS_FOREVER_MS ? \ + K_TICKS_FOREVER : Z_TIMEOUT_MS_TICKS(ms)) /* Exhaustively enumerated, highly optimized time unit conversion API */ diff --git a/include/zephyr/sys_clock.h b/include/zephyr/sys_clock.h index e29453a81c7..039c6b49744 100644 --- a/include/zephyr/sys_clock.h +++ b/include/zephyr/sys_clock.h @@ -92,11 +92,13 @@ typedef struct { # define Z_TIMEOUT_US(t) Z_TIMEOUT_TICKS((k_ticks_t)k_us_to_ticks_ceil64(MAX(t, 0))) # define Z_TIMEOUT_NS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ns_to_ticks_ceil64(MAX(t, 0))) # define Z_TIMEOUT_CYC(t) Z_TIMEOUT_TICKS((k_ticks_t)k_cyc_to_ticks_ceil64(MAX(t, 0))) +# define Z_TIMEOUT_MS_TICKS(t) ((k_ticks_t)k_ms_to_ticks_ceil64(MAX(t, 0))) #else # define Z_TIMEOUT_MS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ms_to_ticks_ceil32(MAX(t, 0))) # define Z_TIMEOUT_US(t) Z_TIMEOUT_TICKS((k_ticks_t)k_us_to_ticks_ceil32(MAX(t, 0))) # define Z_TIMEOUT_NS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ns_to_ticks_ceil32(MAX(t, 0))) # define Z_TIMEOUT_CYC(t) Z_TIMEOUT_TICKS((k_ticks_t)k_cyc_to_ticks_ceil32(MAX(t, 0))) +# define Z_TIMEOUT_MS_TICKS(t) ((k_ticks_t)k_ms_to_ticks_ceil32(MAX(t, 0))) #endif /* Converts between absolute timeout expiration values (packed into From 4269bbc4eab92b1b9c14ccba84b3d5522a71f3c1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Sep 2023 21:35:47 -0700 Subject: [PATCH 1320/4498] test/kernel: Adjust timer test to deal with time_units macros All of the time_units conversion routines are now macros which means the test cannot reference them as functions. Instead, create local static functions which call each one of them and use those instead. Signed-off-by: Keith Packard --- .../timer/timer_api/src/timer_convert.c | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/tests/kernel/timer/timer_api/src/timer_convert.c b/tests/kernel/timer/timer_api/src/timer_convert.c index f8911f240c2..f29af361cee 100644 --- a/tests/kernel/timer/timer_api/src/timer_convert.c +++ b/tests/kernel/timer/timer_api/src/timer_convert.c @@ -30,9 +30,99 @@ struct test_rec { #define TESTREC(src, dst, round, prec) { \ UNIT_##src, UNIT_##dst, prec, ROUND_##round, \ - (void *)k_##src##_to_##dst##_##round##prec \ + (void *)test_##src##_to_##dst##_##round##prec \ } \ +#define TESTFUNC(src, dst, round, prec) \ + static uint##prec##_t test_##src##_to_##dst##_##round##prec(uint##prec##_t t) { \ + return k_##src##_to_##dst##_##round##prec(t); \ + } + +TESTFUNC(ms, cyc, floor, 32) +TESTFUNC(ms, cyc, floor, 64) +TESTFUNC(ms, cyc, near, 32) +TESTFUNC(ms, cyc, near, 64) +TESTFUNC(ms, cyc, ceil, 32) +TESTFUNC(ms, cyc, ceil, 64) +TESTFUNC(ms, ticks, floor, 32) +TESTFUNC(ms, ticks, floor, 64) +TESTFUNC(ms, ticks, near, 32) +TESTFUNC(ms, ticks, near, 64) +TESTFUNC(ms, ticks, ceil, 32) +TESTFUNC(ms, ticks, ceil, 64) +TESTFUNC(us, cyc, floor, 32) +TESTFUNC(us, cyc, floor, 64) +TESTFUNC(us, cyc, near, 32) +TESTFUNC(us, cyc, near, 64) +TESTFUNC(us, cyc, ceil, 32) +TESTFUNC(us, cyc, ceil, 64) +TESTFUNC(us, ticks, floor, 32) +TESTFUNC(us, ticks, floor, 64) +TESTFUNC(us, ticks, near, 32) +TESTFUNC(us, ticks, near, 64) +TESTFUNC(us, ticks, ceil, 32) +TESTFUNC(us, ticks, ceil, 64) +TESTFUNC(cyc, ms, floor, 32) +TESTFUNC(cyc, ms, floor, 64) +TESTFUNC(cyc, ms, near, 32) +TESTFUNC(cyc, ms, near, 64) +TESTFUNC(cyc, ms, ceil, 32) +TESTFUNC(cyc, ms, ceil, 64) +TESTFUNC(cyc, us, floor, 32) +TESTFUNC(cyc, us, floor, 64) +TESTFUNC(cyc, us, near, 32) +TESTFUNC(cyc, us, near, 64) +TESTFUNC(cyc, us, ceil, 32) +TESTFUNC(cyc, us, ceil, 64) +TESTFUNC(cyc, ticks, floor, 32) +TESTFUNC(cyc, ticks, floor, 64) +TESTFUNC(cyc, ticks, near, 32) +TESTFUNC(cyc, ticks, near, 64) +TESTFUNC(cyc, ticks, ceil, 32) +TESTFUNC(cyc, ticks, ceil, 64) +TESTFUNC(ticks, ms, floor, 32) +TESTFUNC(ticks, ms, floor, 64) +TESTFUNC(ticks, ms, near, 32) +TESTFUNC(ticks, ms, near, 64) +TESTFUNC(ticks, ms, ceil, 32) +TESTFUNC(ticks, ms, ceil, 64) +TESTFUNC(ticks, us, floor, 32) +TESTFUNC(ticks, us, floor, 64) +TESTFUNC(ticks, us, near, 32) +TESTFUNC(ticks, us, near, 64) +TESTFUNC(ticks, us, ceil, 32) +TESTFUNC(ticks, us, ceil, 64) +TESTFUNC(ticks, cyc, floor, 32) +TESTFUNC(ticks, cyc, floor, 64) +TESTFUNC(ticks, cyc, near, 32) +TESTFUNC(ticks, cyc, near, 64) +TESTFUNC(ticks, cyc, ceil, 32) +TESTFUNC(ticks, cyc, ceil, 64) +TESTFUNC(ns, cyc, floor, 32) +TESTFUNC(ns, cyc, floor, 64) +TESTFUNC(ns, cyc, near, 32) +TESTFUNC(ns, cyc, near, 64) +TESTFUNC(ns, cyc, ceil, 32) +TESTFUNC(ns, cyc, ceil, 64) +TESTFUNC(ns, ticks, floor, 32) +TESTFUNC(ns, ticks, floor, 64) +TESTFUNC(ns, ticks, near, 32) +TESTFUNC(ns, ticks, near, 64) +TESTFUNC(ns, ticks, ceil, 32) +TESTFUNC(ns, ticks, ceil, 64) +TESTFUNC(cyc, ns, floor, 32) +TESTFUNC(cyc, ns, floor, 64) +TESTFUNC(cyc, ns, near, 32) +TESTFUNC(cyc, ns, near, 64) +TESTFUNC(cyc, ns, ceil, 32) +TESTFUNC(cyc, ns, ceil, 64) +TESTFUNC(ticks, ns, floor, 32) +TESTFUNC(ticks, ns, floor, 64) +TESTFUNC(ticks, ns, near, 32) +TESTFUNC(ticks, ns, near, 64) +TESTFUNC(ticks, ns, ceil, 32) +TESTFUNC(ticks, ns, ceil, 64) + static struct test_rec tests[] = { TESTREC(ms, cyc, floor, 32), TESTREC(ms, cyc, floor, 64), From 477bf558dea2a6766db1958223b346853583a128 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 22 Sep 2023 19:12:58 -0700 Subject: [PATCH 1321/4498] west: Pull in espressif linker alignment fix This PR fixes the espressif esptool to deal with ELF section alignment which would otherwise create holes in the resulting binary. Signed-off-by: Keith Packard --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 98a13d4216e..c9398be0d5c 100644 --- a/west.yml +++ b/west.yml @@ -158,7 +158,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 9e4115fcbd6b737ec36488cd88c643eb7efc8b1b + revision: 635063971ee16d1fcdfd35136feda99a90926327 path: modules/hal/espressif west-commands: west/west-commands.yml groups: From 41e8b44619c7dd60ccf91ac642c49e68d14f7ede Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Sep 2023 00:07:28 -0700 Subject: [PATCH 1322/4498] kernel: Make thread 'init_delay' k_timeout_t rather than int msecs Storing this value in milliseconds rather than using k_timeout_t requires the system to perform division at runtime to convert types. This pulls in the 64-bit soft division code on platforms without hardware for this. Perform the conversion at build time instead by using the runtime time directly. The init_delay field was moved within the _static_thread_data structure to avoid introducing a hole for alignment on 32-bit systems when using 64-bit timeouts. Use SYS_TIMEOUT_MS instead of K_MSEC so that the initial delay can be set to forever. Signed-off-by: Keith Packard --- include/zephyr/kernel.h | 4 ++-- kernel/thread.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 0ab33e85d42..e3c467f1dbc 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -686,8 +686,8 @@ struct _static_thread_data { void *init_p3; int init_prio; uint32_t init_options; - int32_t init_delay; const char *init_name; + k_timeout_t init_delay; }; #define Z_THREAD_INITIALIZER(thread, stack, stack_size, \ @@ -703,7 +703,7 @@ struct _static_thread_data { .init_p3 = (void *)p3, \ .init_prio = (prio), \ .init_options = (options), \ - .init_delay = (delay), \ + .init_delay = SYS_TIMEOUT_MS(delay), \ .init_name = STRINGIFY(tname), \ } diff --git a/kernel/thread.c b/kernel/thread.c index 49b97e6cb4b..2b0b5ce0aac 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -790,9 +790,9 @@ void z_init_static_threads(void) */ k_sched_lock(); _FOREACH_STATIC_THREAD(thread_data) { - if (thread_data->init_delay != K_TICKS_FOREVER) { + if (!K_TIMEOUT_EQ(thread_data->init_delay, K_FOREVER)) { schedule_new_thread(thread_data->init_thread, - K_MSEC(thread_data->init_delay)); + thread_data->init_delay); } } k_sched_unlock(); From 0a50ff366ed76f76391d657c5b9b97fb90242a59 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 25 Sep 2023 11:56:10 -0700 Subject: [PATCH 1323/4498] kernel: rename z_current_get() to k_sched_current_thread_query() The original idea of z_current_get() was to be the counterpart of k_current_get() when thread local variable for current has not been initialized if TLS is enabled, otherwise they are the same function. Now since z_current_get() is being used outside of core kernel, rename it under kernel namespace so other subsystem can conceptually use them too. Signed-off-by: Daniel Leung --- include/zephyr/kernel.h | 12 +++++++++--- include/zephyr/kernel_structs.h | 2 +- kernel/events.c | 2 +- kernel/sched.c | 8 ++++---- lib/libc/armstdc/src/threading_weak.c | 2 +- lib/os/thread_entry.c | 2 +- samples/subsys/tracing/src/tracing_user.c | 4 ++-- subsys/tracing/ctf/ctf_top.c | 4 ++-- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index e3c467f1dbc..567c06a3194 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -568,14 +568,20 @@ __syscall void k_yield(void); __syscall void k_wakeup(k_tid_t thread); /** - * @brief Get thread ID of the current thread. + * @brief Query thread ID of the current thread. * * This unconditionally queries the kernel via a system call. * + * @note Use k_current_get() unless absolutely sure this is necessary. + * This should only be used directly where the thread local + * variable cannot be used or may contain invalid values + * if thread local storage (TLS) is enabled. If TLS is not + * enabled, this is the same as k_current_get(). + * * @return ID of current thread. */ __attribute_const__ -__syscall k_tid_t z_current_get(void); +__syscall k_tid_t k_sched_current_thread_query(void); #ifdef CONFIG_THREAD_LOCAL_STORAGE /* Thread-local cache of current thread ID, set in z_thread_entry() */ @@ -594,7 +600,7 @@ static inline k_tid_t k_current_get(void) #ifdef CONFIG_THREAD_LOCAL_STORAGE return z_tls_current; #else - return z_current_get(); + return k_sched_current_thread_query(); #endif } diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index aa1379d66af..728986686aa 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -205,7 +205,7 @@ bool z_smp_cpu_mobile(void); #define _current_cpu ({ __ASSERT_NO_MSG(!z_smp_cpu_mobile()); \ arch_curr_cpu(); }) -#define _current z_current_get() +#define _current k_sched_current_thread_query() #else #define _current_cpu (&_kernel.cpus[0]) diff --git a/kernel/events.c b/kernel/events.c index 18ab4656dd1..a4fcf1710d0 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -248,7 +248,7 @@ static uint32_t k_event_wait_internal(struct k_event *event, uint32_t events, } wait_condition = options & K_EVENT_WAIT_MASK; - thread = z_current_get(); + thread = k_sched_current_thread_query(); k_spinlock_key_t key = k_spin_lock(&event->lock); diff --git a/kernel/sched.c b/kernel/sched.c index 028827666ee..fa641179880 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1589,7 +1589,7 @@ static inline void z_vrfy_k_wakeup(k_tid_t thread) #include #endif -k_tid_t z_impl_z_current_get(void) +k_tid_t z_impl_k_sched_current_thread_query(void) { #ifdef CONFIG_SMP /* In SMP, _current is a field read from _current_cpu, which @@ -1608,11 +1608,11 @@ k_tid_t z_impl_z_current_get(void) } #ifdef CONFIG_USERSPACE -static inline k_tid_t z_vrfy_z_current_get(void) +static inline k_tid_t z_vrfy_k_sched_current_thread_query(void) { - return z_impl_z_current_get(); + return z_impl_k_sched_current_thread_query(); } -#include +#include #endif int z_impl_k_is_preempt_thread(void) diff --git a/lib/libc/armstdc/src/threading_weak.c b/lib/libc/armstdc/src/threading_weak.c index 2f1b31a8745..f94f48766a6 100644 --- a/lib/libc/armstdc/src/threading_weak.c +++ b/lib/libc/armstdc/src/threading_weak.c @@ -49,7 +49,7 @@ int __weak z_impl_k_sem_take(struct k_sem *sem, k_timeout_t timeout) return 0; } -k_tid_t __weak z_impl_z_current_get(void) +k_tid_t __weak z_impl_k_sched_current_thread_query(void) { return 0; } diff --git a/lib/os/thread_entry.c b/lib/os/thread_entry.c index 0add601489c..4fd03f3357e 100644 --- a/lib/os/thread_entry.c +++ b/lib/os/thread_entry.c @@ -36,7 +36,7 @@ FUNC_NORETURN void z_thread_entry(k_thread_entry_t entry, void *p1, void *p2, void *p3) { #ifdef CONFIG_THREAD_LOCAL_STORAGE - z_tls_current = z_current_get(); + z_tls_current = k_sched_current_thread_query(); #endif #ifdef CONFIG_STACK_CANARIES_TLS uintptr_t stack_guard; diff --git a/samples/subsys/tracing/src/tracing_user.c b/samples/subsys/tracing/src/tracing_user.c index 1e05957cd83..7f9370c5d2a 100644 --- a/samples/subsys/tracing/src/tracing_user.c +++ b/samples/subsys/tracing/src/tracing_user.c @@ -14,7 +14,7 @@ void sys_trace_thread_switched_in_user(void) __ASSERT_NO_MSG(nested_interrupts[_current_cpu->id] == 0); /* Can't use k_current_get as thread base and z_tls_current might be incorrect */ - printk("%s: %p\n", __func__, z_current_get()); + printk("%s: %p\n", __func__, k_sched_current_thread_query()); irq_unlock(key); } @@ -25,7 +25,7 @@ void sys_trace_thread_switched_out_user(void) __ASSERT_NO_MSG(nested_interrupts[_current_cpu->id] == 0); /* Can't use k_current_get as thread base and z_tls_current might be incorrect */ - printk("%s: %p\n", __func__, z_current_get()); + printk("%s: %p\n", __func__, k_sched_current_thread_query()); irq_unlock(key); } diff --git a/subsys/tracing/ctf/ctf_top.c b/subsys/tracing/ctf/ctf_top.c index 38cbb30ffec..64708c075f4 100644 --- a/subsys/tracing/ctf/ctf_top.c +++ b/subsys/tracing/ctf/ctf_top.c @@ -27,7 +27,7 @@ void sys_trace_k_thread_switched_out(void) ctf_bounded_string_t name = { "unknown" }; struct k_thread *thread; - thread = z_current_get(); + thread = k_sched_current_thread_query(); _get_thread_name(thread, &name); ctf_top_thread_switched_out((uint32_t)(uintptr_t)thread, name); @@ -38,7 +38,7 @@ void sys_trace_k_thread_switched_in(void) struct k_thread *thread; ctf_bounded_string_t name = { "unknown" }; - thread = z_current_get(); + thread = k_sched_current_thread_query(); _get_thread_name(thread, &name); ctf_top_thread_switched_in((uint32_t)(uintptr_t)thread, name); From 9686f6e000c746538ec7ab78f6d8abf299d24e95 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 25 Sep 2023 12:07:56 -0700 Subject: [PATCH 1324/4498] kernel: do not expose z_tls_current in kernel.h This moves the declaration of z_tls_current inside k_current_get() so it will not be exposed as a public variable. Signed-off-by: Daniel Leung --- include/zephyr/kernel.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 567c06a3194..c3f2562e567 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -583,11 +583,6 @@ __syscall void k_wakeup(k_tid_t thread); __attribute_const__ __syscall k_tid_t k_sched_current_thread_query(void); -#ifdef CONFIG_THREAD_LOCAL_STORAGE -/* Thread-local cache of current thread ID, set in z_thread_entry() */ -extern __thread k_tid_t z_tls_current; -#endif - /** * @brief Get thread ID of the current thread. * @@ -598,6 +593,9 @@ __attribute_const__ static inline k_tid_t k_current_get(void) { #ifdef CONFIG_THREAD_LOCAL_STORAGE + /* Thread-local cache of current thread ID, set in z_thread_entry() */ + extern __thread k_tid_t z_tls_current; + return z_tls_current; #else return k_sched_current_thread_query(); From 5d28fdea63b513582b975a276a20b2d5faff7a7a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 28 Sep 2023 11:39:32 +0000 Subject: [PATCH 1325/4498] modules/MCUboot: Add overwrite mode for MCUboot Add MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY mode. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 1679bfeb8a9..8df4bde8829 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -175,6 +175,18 @@ config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. +config MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY + bool "MCUboot has been configured to just overwrite primary slot" + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE + help + MCUboot will take contents of secondary slot of an image and will + overwrite primary slot with it. + In this mode it is not possible to revert back to previous version + as it is not stored in the secondary slot. + This mode supports MCUBOOT_BOOTLOADER_NO_DOWNGRADE which means + that the overwrite will not happen unless the version of secondary + slot is higher than the version in primary slot. + config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP bool "MCUboot has been configured for DirectXIP operation" select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE From 83d69f50ada1fb22bee848a501e82a1683fc0aef Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 28 Sep 2023 11:44:39 +0000 Subject: [PATCH 1326/4498] doc/release-notes: MCUboot overwrite mode Kconfig info Note on CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 351c6f5fd70..b9d1d027ea5 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -393,6 +393,11 @@ MCUboot with downgrade prevention enabled. This option is automatically selected for DirectXIP mode and is available for both swap modes. + * Added :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY` + that allows to inform application that the on-board MCUboot will overwrite + the primary slot with secondary slot contents, without saving the original + image in primary slot. + Storage ******* From 7668b4fbb35b98ca1c61029aedf72ff544b70236 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 11 May 2023 15:15:08 +0000 Subject: [PATCH 1327/4498] doc/services/device_mgmt: Bootloader info request definition Specification for MCUmgr OS group command allowing to query for bootloader information. Provide information on supported MCUboot parameters query by MCUmgr group OS. Signed-off-by: Dominik Ermel --- .../device_mgmt/smp_groups/smp_group_0.rst | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index 761f2a4df43..c77c212c512 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -28,6 +28,8 @@ OS management group defines following commands: +-------------------+-----------------------------------------------+ | ``7`` | OS/Application info | +-------------------+-----------------------------------------------+ + | ``8`` | Bootloader information | + +-------------------+-----------------------------------------------+ Echo command ************ @@ -840,3 +842,200 @@ where: | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | | | using SMP version 1 or for SMP errors when using SMP version 2. | +------------------+-------------------------------------------------------------------------+ + +Bootloader Information +********************** + +Allows retrieving information about the on-board bootloader and its parameters. + +Bootloader Information Request +============================== + +Bootloader information request header: + +.. table:: + :align: center + + +--------+--------------+----------------+ + | ``OP`` | ``Group ID`` | ``Command ID`` | + +========+==============+================+ + | ``0`` | ``0`` | ``8`` | + +--------+--------------+----------------+ + +CBOR data of request: + +.. code-block:: none + + { + (str,opt)"query" : (str) + } + +where: + +.. table:: + :align: center + + +--------------+-----------------------------------------------+ + | "query" | Is string representing query for parameters, | + | | with no restrictions how the query looks like | + | | as processing of query is left for bootloader | + | | backend. | + | | If there is no query, then response will | + | | return string identifying the bootloader. | + +--------------+-----------------------------------------------+ + +Bootloader Information Response +=============================== + +Bootloader information response header: + +.. table:: + :align: center + + +--------+--------------+----------------+ + | ``OP`` | ``Group ID`` | ``Command ID`` | + +========+==============+================+ + | ``1`` | ``0`` | ``8`` | + +--------+--------------+----------------+ + +In case when no "query" has been provided in request, +CBOR data of response: + +.. code-block:: none + + { + (str)"bootloader" : (str) + } + +where: + +.. table:: + :align: center + + +--------------+-----------------------------------------------+ + | "bootloader" | String representing bootloader name | + +--------------+-----------------------------------------------+ + +In case when "query" is provided: + +.. code-block:: none + + { + (str,opt) : () + ... + } + +where: + +.. table:: + :align: center + + +------------------+-------------------------------------------------------------------------+ + | | Response to "query". This is optional and may be left out in case when | + | | query yields no response, SMP version 2 error code of | + | | `OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER` is expected. | + | | Response may have more than one parameter reported back or it may be | + | | a map, that is dependent on bootloader backednd and query. | + +------------------+-------------------------------------------------------------------------+ + | ... | Parameter characteristic information. | + +------------------+-------------------------------------------------------------------------+ + +Parameter may be accompanied by additional, parameter specific, information keywords with +assigned values. + +In case of error the CBOR data takes the form: + +.. tabs:: + + .. group-tab:: SMP version 2 + + .. code-block:: none + + { + (str)"err" : { + (str)"group" : (uint) + (str)"rc" : (uint) + } + } + + .. group-tab:: SMP version 1 (and non-group SMP version 2) + + .. code-block:: none + + { + (str)"rc" : (int) + } + +where: + +.. table:: + :align: center + + +------------------+-------------------------------------------------------------------------+ + | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | + | | appears if an error is returned when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "err" -> "rc" | contains the index of the group-based error code. Only appears if | + | | non-zero (error condition) when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | + | | using SMP version 1 or for SMP errors when using SMP version 2. | + +------------------+-------------------------------------------------------------------------+ + +Bootloader Information: MCUboot +=============================== + +In case when MCUboot is application bootloader empty request will +be responded with: + +.. code-block:: none + + { + (str)"bootloader" : (str)"MCUboot" + } + +Currently "MCUboot" supports querying for mode of operation: + +.. code-block:: none + + { + (str)"query" : (str)"mode" + } + +Response to "mode" is: + +.. code-block:: none + + { + (str)"mode" : (int) + (str,opt)"no-downgrade" : (bool) + } + +where "mode" is one of: + +.. table:: + :align: center + + +-----+-----------------------------------------------------+ + | -1 | Unknown mode of MCUboot. | + +-----+-----------------------------------------------------+ + | 0 | MCUboot is in single application mode. | + +-----+-----------------------------------------------------+ + | 1 | MCUboot is in swap using scratch partition mode. | + +-----+-----------------------------------------------------+ + | 2 | MCUboot is in overwrite (upgrade-only) mode. | + +-----+-----------------------------------------------------+ + | 3 | MCUboot is in swap without scratch mode. | + +-----+-----------------------------------------------------+ + | 4 | MCUboot is in DirectXIP without revert mode. | + +-----+-----------------------------------------------------+ + | 5 | MCUboot is in DirectXIP with revert mode. | + +-----+-----------------------------------------------------+ + | 6 | MCUboot is in RAM loader mode. | + +-----+-----------------------------------------------------+ + +The "no-downgrade" is a flag, which is always sent when true, indicating that +mode has downgrade prevention enabled; downgrade prevention means that +if uploaded image has lower version than running, it will notbe taken +for exectuion by MCUboot. +MCUmgr may reject image with lower version in that MCUboot configuration. From e48354455acbea481c102cf97be46d0abc720268 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 15 May 2023 12:48:14 +0000 Subject: [PATCH 1328/4498] mgmt/MCUmgr/grp/os: Add booloader info support Adds command allowing to query information on bootloader. In this case support is provided to query MCUboot information. Signed-off-by: Dominik Ermel --- .../zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h | 4 ++ subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt | 8 ++- subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig | 10 +++ subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 70 ++++++++++++++++++- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h index 9c541e11c29..e1ac45e6389 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h @@ -24,6 +24,7 @@ extern "C" { #define OS_MGMT_ID_RESET 5 #define OS_MGMT_ID_MCUMGR_PARAMS 6 #define OS_MGMT_ID_INFO 7 +#define OS_MGMT_ID_BOOTLOADER_INFO 8 /** * Command result codes for OS management group. @@ -37,6 +38,9 @@ enum os_mgmt_err_code_t { /** The provided format value is not valid. */ OS_MGMT_ERR_INVALID_FORMAT, + + /** Query was not recognized. */ + OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER, }; /* Bitmask values used by the os info command handler. Note that the width of this variable is diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt index e712acf6e94..35123fa1159 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2018-2021 mcumgr authors -# Copyright (c) 2022 Nordic Semiconductor ASA +# Copyright (c) 2022-2023 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # @@ -12,6 +12,12 @@ zephyr_library_sources(src/os_mgmt.c) zephyr_library_include_directories(include) +if (CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) + zephyr_include_directories( + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include + ) +endif() + if(DEFINED CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME) set(MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR ${PROJECT_BINARY_DIR}/os_mgmt_auto) file(MAKE_DIRECTORY ${MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR}) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index 897db735982..fa743b53caf 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -173,6 +173,16 @@ config MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME endif +if BOOTLOADER_MCUBOOT + +config MCUMGR_GRP_OS_BOOTLOADER_INFO + bool "Bootloader information" + help + Allows to query MCUmgr about bootloader used by device and various bootloader + parameters. + +endif # BOOTLOADER_MCUBOOT + module = MCUMGR_GRP_OS module-str = mcumgr_grp_os source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index 55a6fa81564..a42e2f4022f 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -33,10 +33,15 @@ #include #endif -#ifdef CONFIG_MCUMGR_GRP_OS_INFO +#if defined(CONFIG_MCUMGR_GRP_OS_INFO) || defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) #include #include +#if defined(CONFIG_MCUMGR_GRP_OS_INFO) #include +#endif +#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) +#include +#endif #include #if defined(CONFIG_NET_HOSTNAME_ENABLE) #include @@ -370,6 +375,64 @@ os_mgmt_mcumgr_params(struct smp_streamer *ctxt) } #endif +#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) + +#if IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP) +#define BOOTLOADER_MODE MCUBOOT_MODE_SINGLE_SLOT +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) +#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_SCRATCH +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) +#define BOOTLOADER_MODE MCUBOOT_MODE_UPGRADE_ONLY +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) +#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_MOVE +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) +#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) +#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT +#else +#define BOOTLOADER_MODE -1 +#endif + +static int +os_mgmt_bootloader_info(struct smp_streamer *ctxt) +{ + zcbor_state_t *zse = ctxt->writer->zs; + zcbor_state_t *zsd = ctxt->reader->zs; + struct zcbor_string query = { 0 }; + size_t decoded; + bool ok; + + struct zcbor_map_decode_key_val bootloader_info[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("query", zcbor_tstr_decode, &query), + }; + + if (zcbor_map_decode_bulk(zsd, bootloader_info, ARRAY_SIZE(bootloader_info), &decoded)) { + return MGMT_ERR_EINVAL; + } + + /* If no parameter is recognized then just introduce the bootloader. */ + if (decoded == 0) { + ok = zcbor_tstr_put_lit(zse, "bootloader") && + zcbor_tstr_put_lit(zse, "MCUboot"); + } else if (zcbor_map_decode_bulk_key_found(bootloader_info, ARRAY_SIZE(bootloader_info), + "query") && + (sizeof("mode") - 1) == query.len && + memcmp("mode", query.value, query.len) == 0) { + + ok = zcbor_tstr_put_lit(zse, "mode") && + zcbor_int32_put(zse, BOOTLOADER_MODE); +#if IS_ENABLED(MCUBOOT_BOOTLOADER_NO_DOWNGRADE) + ok = zcbor_tstr_put_lit(zse, "no-downgrade") && + zcbor_bool_encode(zse, true); +#endif + } else { + return OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER; + } + + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; +} +#endif + #ifdef CONFIG_MCUMGR_GRP_OS_INFO /** * Command handler: os info @@ -733,6 +796,11 @@ static const struct mgmt_handler os_mgmt_group_handlers[] = { os_mgmt_info, NULL }, #endif +#ifdef CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO + [OS_MGMT_ID_BOOTLOADER_INFO] = { + os_mgmt_bootloader_info, NULL + }, +#endif }; #define OS_MGMT_GROUP_SZ ARRAY_SIZE(os_mgmt_group_handlers) From e397b85eb861e892a6aa60fdb2c1f73db4799809 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 22 Sep 2023 11:58:16 +0200 Subject: [PATCH 1329/4498] drivers: can: calculate a default SJW value Change the CAN timing calculation APIs to automatically calculate a default (Re-)Synchronization Jump Width (SJW) value. The calculated value can be overwritten by the caller if desired. This allows automatically scaling the SJW according to the number of Time Quanta (TQ) used for phase segment 2 instead of relying on a compile-time fallback value defined in devicetree. This reduces the can_set_timing()/can_set_timing_data() API functions to simple setters (with validation). Fixes: #63033 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_common.c | 26 +++++++------- drivers/can/can_shell.c | 66 ++++++++++++++---------------------- include/zephyr/drivers/can.h | 4 --- 3 files changed, 39 insertions(+), 57 deletions(-) diff --git a/drivers/can/can_common.c b/drivers/can/can_common.c index c7902ee9d20..6541c977255 100644 --- a/drivers/can/can_common.c +++ b/drivers/can/can_common.c @@ -170,7 +170,7 @@ static int can_calc_timing_int(uint32_t core_clock, struct can_timing *res, CAN_SYNC_SEG; uint16_t sp_err_min = UINT16_MAX; int sp_err; - struct can_timing tmp_res; + struct can_timing tmp_res = { 0 }; if (bitrate == 0 || sp >= 1000) { return -EINVAL; @@ -209,6 +209,10 @@ static int can_calc_timing_int(uint32_t core_clock, struct can_timing *res, LOG_DBG("SP error: %d 1/1000", sp_err_min); } + /* Calculate default sjw as phase_seg2 / 2 and clamp the result */ + res->sjw = MIN(res->phase_seg1, res->phase_seg2 / 2); + res->sjw = CLAMP(res->sjw, min->sjw, max->sjw); + return sp_err_min == UINT16_MAX ? -ENOTSUP : (int)sp_err_min; } @@ -300,18 +304,18 @@ static int check_timing_in_range(const struct can_timing *timing, const struct can_timing *min, const struct can_timing *max) { - if (timing->sjw != CAN_SJW_NO_CHANGE && - !IN_RANGE(timing->sjw, min->sjw, max->sjw)) { - return -ENOTSUP; - } - - if (!IN_RANGE(timing->prop_seg, min->prop_seg, max->prop_seg) || + if (!IN_RANGE(timing->sjw, min->sjw, max->sjw) || + !IN_RANGE(timing->prop_seg, min->prop_seg, max->prop_seg) || !IN_RANGE(timing->phase_seg1, min->phase_seg1, max->phase_seg1) || !IN_RANGE(timing->phase_seg2, min->phase_seg2, max->phase_seg2) || !IN_RANGE(timing->prescaler, min->prescaler, max->prescaler)) { return -ENOTSUP; } + if ((timing->sjw > timing->phase_seg1) || (timing->sjw > timing->phase_seg2)) { + return -ENOTSUP; + } + return 0; } @@ -333,7 +337,7 @@ int z_impl_can_set_timing(const struct device *dev, int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate) { - struct can_timing timing; + struct can_timing timing = { 0 }; uint32_t max_bitrate; uint16_t sample_pnt; int ret; @@ -360,8 +364,6 @@ int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate) return -ERANGE; } - timing.sjw = CAN_SJW_NO_CHANGE; - return can_set_timing(dev, &timing); } @@ -388,7 +390,7 @@ int z_impl_can_set_timing_data(const struct device *dev, int z_impl_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data) { - struct can_timing timing_data; + struct can_timing timing_data = { 0 }; uint32_t max_bitrate; uint16_t sample_pnt; int ret; @@ -415,8 +417,6 @@ int z_impl_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data) return -ERANGE; } - timing_data.sjw = CAN_SJW_NO_CHANGE; - return can_set_timing_data(dev, &timing_data); } #endif /* CONFIG_CAN_FD_MODE */ diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index a6e3e8045af..e07de338952 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -368,7 +368,7 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) { const struct device *dev = device_get_binding(argv[1]); - struct can_timing timing; + struct can_timing timing = { 0 }; uint16_t sample_pnt; uint32_t bitrate; char *endptr; @@ -392,16 +392,6 @@ static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } - if (argc >= 5) { - timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10); - if (*endptr != '\0') { - shell_error(sh, "failed to parse SJW"); - return -EINVAL; - } - } else { - timing.sjw = CAN_SJW_NO_CHANGE; - } - err = can_calc_timing(dev, &timing, bitrate, sample_pnt); if (err < 0) { shell_error(sh, "failed to calculate timing for " @@ -410,17 +400,20 @@ static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) return err; } - if (timing.sjw == CAN_SJW_NO_CHANGE) { - shell_print(sh, "setting bitrate to %d bps, sample point %d.%d%% " - "(+/- %d.%d%%)", - bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10); - } else { - shell_print(sh, "setting bitrate to %d bps, sample point %d.%d%% " - "(+/- %d.%d%%), sjw %d", - bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10, - timing.sjw); + if (argc >= 5) { + /* Overwrite calculated default SJW with user-provided value */ + timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse SJW"); + return -EINVAL; + } } + shell_print(sh, "setting bitrate to %d bps, sample point %d.%d%% " + "(+/- %d.%d%%), sjw %d", + bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10, + timing.sjw); + LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2, timing.prescaler); @@ -446,7 +439,7 @@ static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv) { const struct device *dev = device_get_binding(argv[1]); - struct can_timing timing; + struct can_timing timing = { 0 }; uint16_t sample_pnt; uint32_t bitrate; char *endptr; @@ -470,16 +463,6 @@ static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv return -EINVAL; } - if (argc >= 5) { - timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10); - if (*endptr != '\0') { - shell_error(sh, "failed to parse SJW"); - return -EINVAL; - } - } else { - timing.sjw = CAN_SJW_NO_CHANGE; - } - err = can_calc_timing_data(dev, &timing, bitrate, sample_pnt); if (err < 0) { shell_error(sh, "failed to calculate timing for " @@ -488,17 +471,20 @@ static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv return err; } - if (timing.sjw == CAN_SJW_NO_CHANGE) { - shell_print(sh, "setting data bitrate to %d bps, sample point %d.%d%% " - "(+/- %d.%d%%)", - bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10); - } else { - shell_print(sh, "setting data bitrate to %d bps, sample point %d.%d%% " - "(+/- %d.%d%%), sjw %d", - bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10, - timing.sjw); + if (argc >= 5) { + /* Overwrite calculated default SJW with user-provided value */ + timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse SJW"); + return -EINVAL; + } } + shell_print(sh, "setting data bitrate to %d bps, sample point %d.%d%% " + "(+/- %d.%d%%), sjw %d", + bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10, + timing.sjw); + LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2, timing.prescaler); diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 15387afd2c4..db3d961db8b 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -865,8 +865,6 @@ __syscall int can_calc_timing_data(const struct device *dev, struct can_timing * /** * @brief Configure the bus timing for the data phase of a CAN-FD controller. * - * If the sjw equals CAN_SJW_NO_CHANGE, the sjw parameter is not changed. - * * @note @kconfig{CONFIG_CAN_FD_MODE} must be selected for this function to be * available. * @@ -936,8 +934,6 @@ int can_calc_prescaler(const struct device *dev, struct can_timing *timing, /** * @brief Configure the bus timing of a CAN controller. * - * If the sjw equals CAN_SJW_NO_CHANGE, the sjw parameter is not changed. - * * @see can_set_timing_data() * * @param dev Pointer to the device structure for the driver instance. From a9d3935fa011e449af5933dc4b06cb64b3af32c5 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 22 Sep 2023 12:07:16 +0200 Subject: [PATCH 1330/4498] drivers: can: solely use sjw from devicetree for initial timing Update the CAN controller drivers to solely use the sjw and sjw-data devicetree properties for setting the initial timing when devicetree timing parameters are specified in Time Quanta (TQ). Any timing set via the CAN timing APIs will contain either user-provided or automatically calculated SJW values. This includes any timing parameters calculated from bus-speed and bus-speed-data devicetree properties. Update the CAN controller driver tests accordingly and remove the CAN_SJW_NO_CHANGE definition as it has lost its meaning. Fixes: #63033 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_esp32_twai.c | 13 +----- drivers/can/can_mcan.c | 54 +++++++++--------------- drivers/can/can_mcp2515.c | 11 ++--- drivers/can/can_mcp2515.h | 1 - drivers/can/can_mcux_flexcan.c | 10 +---- drivers/can/can_rcar.c | 6 +-- drivers/can/can_sja1000.c | 19 ++------- drivers/can/can_stm32_bxcan.c | 15 +++---- include/zephyr/drivers/can.h | 5 --- include/zephyr/drivers/can/can_sja1000.h | 1 - tests/drivers/can/api/src/canfd.c | 4 +- tests/drivers/can/api/src/classic.c | 4 +- tests/drivers/can/shell/src/main.c | 8 +--- tests/drivers/can/timing/src/main.c | 11 +++-- 14 files changed, 50 insertions(+), 112 deletions(-) diff --git a/drivers/can/can_esp32_twai.c b/drivers/can/can_esp32_twai.c index c26768ac003..6bec2638ae4 100644 --- a/drivers/can/can_esp32_twai.c +++ b/drivers/can/can_esp32_twai.c @@ -118,10 +118,8 @@ static int can_esp32_twai_set_timing(const struct device *dev, const struct can_ struct can_sja1000_data *data = dev->data; uint8_t btr0; uint8_t btr1; - uint8_t sjw; - __ASSERT_NO_MSG(timing->sjw == CAN_SJW_NO_CHANGE || - (timing->sjw >= 0x1 && timing->sjw <= 0x4)); + __ASSERT_NO_MSG(timing->sjw >= 0x1 && timing->sjw <= 0x4); __ASSERT_NO_MSG(timing->prop_seg == 0); __ASSERT_NO_MSG(timing->phase_seg1 >= 0x1 && timing->phase_seg1 <= 0x10); __ASSERT_NO_MSG(timing->phase_seg2 >= 0x1 && timing->phase_seg2 <= 0x8); @@ -133,15 +131,8 @@ static int can_esp32_twai_set_timing(const struct device *dev, const struct can_ k_mutex_lock(&data->mod_lock, K_FOREVER); - if (timing->sjw == CAN_SJW_NO_CHANGE) { - sjw = data->sjw; - } else { - sjw = timing->sjw; - data->sjw = timing->sjw; - } - btr0 = TWAI_BAUD_PRESC_PREP(timing->prescaler - 1) | - TWAI_SYNC_JUMP_WIDTH_PREP(sjw - 1); + TWAI_SYNC_JUMP_WIDTH_PREP(timing->sjw - 1); btr1 = TWAI_TIME_SEG1_PREP(timing->phase_seg1 - 1) | TWAI_TIME_SEG2_PREP(timing->phase_seg2 - 1); diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index 103c80400d8..e83ee991c23 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -208,23 +208,12 @@ int can_mcan_set_timing(const struct device *dev, const struct can_timing *timin __ASSERT_NO_MSG(timing->phase_seg1 <= 0x100 && timing->phase_seg1 > 1U); __ASSERT_NO_MSG(timing->phase_seg2 <= 0x80 && timing->phase_seg2 > 1U); __ASSERT_NO_MSG(timing->prescaler <= 0x200 && timing->prescaler > 0U); - __ASSERT_NO_MSG(timing->sjw == CAN_SJW_NO_CHANGE || - (timing->sjw <= 0x80 && timing->sjw > 0U)); + __ASSERT_NO_MSG(timing->sjw <= 0x80 && timing->sjw > 0U); k_mutex_lock(&data->lock, K_FOREVER); - if (timing->sjw == CAN_SJW_NO_CHANGE) { - err = can_mcan_read_reg(dev, CAN_MCAN_NBTP, &nbtp); - if (err != 0) { - goto unlock; - } - - nbtp &= CAN_MCAN_NBTP_NSJW; - } else { - nbtp |= FIELD_PREP(CAN_MCAN_NBTP_NSJW, timing->sjw - 1UL); - } - - nbtp |= FIELD_PREP(CAN_MCAN_NBTP_NTSEG1, timing->phase_seg1 - 1UL) | + nbtp |= FIELD_PREP(CAN_MCAN_NBTP_NSJW, timing->sjw - 1UL) | + FIELD_PREP(CAN_MCAN_NBTP_NTSEG1, timing->phase_seg1 - 1UL) | FIELD_PREP(CAN_MCAN_NBTP_NTSEG2, timing->phase_seg2 - 1UL) | FIELD_PREP(CAN_MCAN_NBTP_NBRP, timing->prescaler - 1UL); @@ -254,23 +243,12 @@ int can_mcan_set_timing_data(const struct device *dev, const struct can_timing * __ASSERT_NO_MSG(timing_data->phase_seg1 <= 0x20 && timing_data->phase_seg1 > 0U); __ASSERT_NO_MSG(timing_data->phase_seg2 <= 0x10 && timing_data->phase_seg2 > 0U); __ASSERT_NO_MSG(timing_data->prescaler <= 0x20 && timing_data->prescaler > 0U); - __ASSERT_NO_MSG(timing_data->sjw == CAN_SJW_NO_CHANGE || - (timing_data->sjw <= 0x10 && timing_data->sjw > 0U)); + __ASSERT_NO_MSG(timing_data->sjw <= 0x10 && timing_data->sjw > 0U); k_mutex_lock(&data->lock, K_FOREVER); - if (timing_data->sjw == CAN_SJW_NO_CHANGE) { - err = can_mcan_read_reg(dev, CAN_MCAN_DBTP, &dbtp); - if (err != 0) { - goto unlock; - } - - dbtp &= CAN_MCAN_DBTP_DSJW; - } else { - dbtp |= FIELD_PREP(CAN_MCAN_DBTP_DSJW, timing_data->sjw - 1UL); - } - - dbtp |= FIELD_PREP(CAN_MCAN_DBTP_DTSEG1, timing_data->phase_seg1 - 1UL) | + dbtp |= FIELD_PREP(CAN_MCAN_DBTP_DSJW, timing_data->sjw - 1UL) | + FIELD_PREP(CAN_MCAN_DBTP_DTSEG1, timing_data->phase_seg1 - 1UL) | FIELD_PREP(CAN_MCAN_DBTP_DTSEG2, timing_data->phase_seg2 - 1UL) | FIELD_PREP(CAN_MCAN_DBTP_DBRP, timing_data->prescaler - 1UL); @@ -1357,9 +1335,9 @@ int can_mcan_init(const struct device *dev) const struct can_mcan_config *config = dev->config; const struct can_mcan_callbacks *cbs = config->callbacks; struct can_mcan_data *data = dev->data; - struct can_timing timing; + struct can_timing timing = { 0 }; #ifdef CONFIG_CAN_FD_MODE - struct can_timing timing_data; + struct can_timing timing_data = { 0 }; #endif /* CONFIG_CAN_FD_MODE */ uint32_t reg; int err; @@ -1485,6 +1463,7 @@ int can_mcan_init(const struct device *dev) timing.phase_seg2); LOG_DBG("Sample-point err : %d", err); } else if (config->prop_ts1) { + timing.sjw = config->sjw; timing.prop_seg = 0U; timing.phase_seg1 = config->prop_ts1; timing.phase_seg2 = config->ts2; @@ -1504,6 +1483,7 @@ int can_mcan_init(const struct device *dev) LOG_DBG("Sample-point err data phase: %d", err); } else if (config->prop_ts1_data) { + timing_data.sjw = config->sjw_data; timing_data.prop_seg = 0U; timing_data.phase_seg1 = config->prop_ts1_data; timing_data.phase_seg2 = config->ts2_data; @@ -1514,12 +1494,18 @@ int can_mcan_init(const struct device *dev) } #endif /* CONFIG_CAN_FD_MODE */ - timing.sjw = config->sjw; - can_mcan_set_timing(dev, &timing); + err = can_set_timing(dev, &timing); + if (err != 0) { + LOG_ERR("failed to set timing (err %d)", err); + return -ENODEV; + } #ifdef CONFIG_CAN_FD_MODE - timing_data.sjw = config->sjw_data; - can_mcan_set_timing_data(dev, &timing_data); + err = can_set_timing_data(dev, &timing_data); + if (err != 0) { + LOG_ERR("failed to set data phase timing (err %d)", err); + return -ENODEV; + } #endif /* CONFIG_CAN_FD_MODE */ reg = CAN_MCAN_IE_BOE | CAN_MCAN_IE_EWE | CAN_MCAN_IE_EPE | CAN_MCAN_IE_MRAFE | diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 7de5d714fee..8a1b40d0a7b 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -361,11 +361,8 @@ static int mcp2515_set_timing(const struct device *dev, /* CNF1; SJW<7:6> | BRP<5:0> */ __ASSERT(timing->prescaler > 0, "Prescaler should be bigger than zero"); uint8_t brp = timing->prescaler - 1; - if (timing->sjw != CAN_SJW_NO_CHANGE) { - dev_data->sjw = (timing->sjw - 1) << 6; - } - - uint8_t cnf1 = dev_data->sjw | brp; + uint8_t sjw = (timing->sjw - 1) << 6; + uint8_t cnf1 = sjw | brp; /* CNF2; BTLMODE<7>|SAM<6>|PHSEG1<5:3>|PRSEG<2:0> */ const uint8_t btlmode = 1 << 7; @@ -937,7 +934,7 @@ static int mcp2515_init(const struct device *dev) { const struct mcp2515_config *dev_cfg = dev->config; struct mcp2515_data *dev_data = dev->data; - struct can_timing timing; + struct can_timing timing = { 0 }; k_tid_t tid; int ret; @@ -998,7 +995,6 @@ static int mcp2515_init(const struct device *dev) (void)memset(dev_data->filter, 0, sizeof(dev_data->filter)); dev_data->old_state = CAN_STATE_ERROR_ACTIVE; - timing.sjw = dev_cfg->tq_sjw; if (dev_cfg->sample_point && USE_SP_ALGO) { ret = can_calc_timing(dev, &timing, dev_cfg->bus_speed, dev_cfg->sample_point); @@ -1010,6 +1006,7 @@ static int mcp2515_init(const struct device *dev) timing.prescaler, timing.phase_seg1, timing.phase_seg2); LOG_DBG("Sample-point err : %d", ret); } else { + timing.sjw = dev_cfg->tq_sjw; timing.prop_seg = dev_cfg->tq_prop; timing.phase_seg1 = dev_cfg->tq_bs1; timing.phase_seg2 = dev_cfg->tq_bs2; diff --git a/drivers/can/can_mcp2515.h b/drivers/can/can_mcp2515.h index 8d9277b7db8..f8e2921ba63 100644 --- a/drivers/can/can_mcp2515.h +++ b/drivers/can/can_mcp2515.h @@ -46,7 +46,6 @@ struct mcp2515_data { enum can_state old_state; uint8_t mcp2515_mode; bool started; - uint8_t sjw; }; struct mcp2515_config { diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index e5efe2e3065..44355a480e4 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -182,7 +182,6 @@ static int mcux_flexcan_set_timing(const struct device *dev, const struct can_timing *timing) { struct mcux_flexcan_data *data = dev->data; - uint8_t sjw_backup = data->timing.sjw; if (!timing) { return -EINVAL; @@ -193,9 +192,6 @@ static int mcux_flexcan_set_timing(const struct device *dev, } data->timing = *timing; - if (timing->sjw == CAN_SJW_NO_CHANGE) { - data->timing.sjw = sjw_backup; - } return 0; } @@ -205,7 +201,6 @@ static int mcux_flexcan_set_timing_data(const struct device *dev, const struct can_timing *timing_data) { struct mcux_flexcan_data *data = dev->data; - uint8_t sjw_backup = data->timing_data.sjw; if (!timing_data) { return -EINVAL; @@ -216,9 +211,6 @@ static int mcux_flexcan_set_timing_data(const struct device *dev, } data->timing_data = *timing_data; - if (timing_data->sjw == CAN_SJW_NO_CHANGE) { - data->timing_data.sjw = sjw_backup; - } return 0; } @@ -1203,6 +1195,7 @@ static int mcux_flexcan_init(const struct device *dev) data->timing.phase_seg2); LOG_DBG("Sample-point err : %d", err); } else { + data->timing.sjw = config->sjw; data->timing.prop_seg = config->prop_seg; data->timing.phase_seg1 = config->phase_seg1; data->timing.phase_seg2 = config->phase_seg2; @@ -1227,6 +1220,7 @@ static int mcux_flexcan_init(const struct device *dev) data->timing_data.phase_seg2); LOG_DBG("Sample-point err : %d", err); } else { + data->timing_data.sjw = config->sjw_data; data->timing_data.prop_seg = config->prop_seg_data; data->timing_data.phase_seg1 = config->phase_seg1_data; data->timing_data.phase_seg2 = config->phase_seg2_data; diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index 7e108ebd42a..85dfbc8916c 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -987,7 +987,7 @@ static int can_rcar_init(const struct device *dev) { const struct can_rcar_cfg *config = dev->config; struct can_rcar_data *data = dev->data; - struct can_timing timing; + struct can_timing timing = { 0 }; int ret; uint16_t ctlr; @@ -1053,7 +1053,6 @@ static int can_rcar_init(const struct device *dev) return ret; } - timing.sjw = config->sjw; if (config->sample_point) { ret = can_calc_timing(dev, &timing, config->bus_speed, config->sample_point); @@ -1065,6 +1064,7 @@ static int can_rcar_init(const struct device *dev) timing.prescaler, timing.phase_seg1, timing.phase_seg2); LOG_DBG("Sample-point err : %d", ret); } else { + timing.sjw = config->sjw; timing.prop_seg = config->prop_seg; timing.phase_seg1 = config->phase_seg1; timing.phase_seg2 = config->phase_seg2; @@ -1074,7 +1074,7 @@ static int can_rcar_init(const struct device *dev) } } - ret = can_rcar_set_timing(dev, &timing); + ret = can_set_timing(dev, &timing); if (ret) { return ret; } diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index a83cecf4fee..4c38ae196a1 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -107,9 +107,8 @@ int can_sja1000_set_timing(const struct device *dev, const struct can_timing *ti struct can_sja1000_data *data = dev->data; uint8_t btr0; uint8_t btr1; - uint8_t sjw; - __ASSERT_NO_MSG(timing->sjw == CAN_SJW_NO_CHANGE || (timing->sjw >= 1 && timing->sjw <= 4)); + __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 4); __ASSERT_NO_MSG(timing->prop_seg == 0); __ASSERT_NO_MSG(timing->phase_seg1 >= 1 && timing->phase_seg1 <= 16); __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 8); @@ -121,15 +120,8 @@ int can_sja1000_set_timing(const struct device *dev, const struct can_timing *ti k_mutex_lock(&data->mod_lock, K_FOREVER); - if (timing->sjw == CAN_SJW_NO_CHANGE) { - sjw = data->sjw; - } else { - sjw = timing->sjw; - data->sjw = timing->sjw; - } - btr0 = CAN_SJA1000_BTR0_BRP_PREP(timing->prescaler - 1) | - CAN_SJA1000_BTR0_SJW_PREP(sjw - 1); + CAN_SJA1000_BTR0_SJW_PREP(timing->sjw - 1); btr1 = CAN_SJA1000_BTR1_TSEG1_PREP(timing->phase_seg1 - 1) | CAN_SJA1000_BTR1_TSEG2_PREP(timing->phase_seg2 - 1); @@ -668,7 +660,7 @@ int can_sja1000_init(const struct device *dev) { const struct can_sja1000_config *config = dev->config; struct can_sja1000_data *data = dev->data; - struct can_timing timing; + struct can_timing timing = { 0 }; int err; __ASSERT_NO_MSG(config->read_reg != NULL); @@ -708,10 +700,6 @@ int can_sja1000_init(const struct device *dev) can_sja1000_write_reg(dev, CAN_SJA1000_AMR2, 0xFF); can_sja1000_write_reg(dev, CAN_SJA1000_AMR3, 0xFF); - /* Calculate initial timing parameters */ - data->sjw = config->sjw; - timing.sjw = CAN_SJW_NO_CHANGE; - if (config->sample_point != 0) { err = can_calc_timing(dev, &timing, config->bitrate, config->sample_point); if (err == -EINVAL) { @@ -721,6 +709,7 @@ int can_sja1000_init(const struct device *dev) LOG_DBG("initial sample point error: %d", err); } else { + timing.sjw = config->sjw; timing.prop_seg = 0; timing.phase_seg1 = config->phase_seg1; timing.phase_seg2 = config->phase_seg2; diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index b99b1f390ec..abae476e7d1 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -555,16 +555,13 @@ static int can_stm32_set_timing(const struct device *dev, return -EBUSY; } - can->BTR = (can->BTR & ~(CAN_BTR_BRP_Msk | CAN_BTR_TS1_Msk | CAN_BTR_TS2_Msk)) | + can->BTR = (can->BTR & ~(CAN_BTR_SJW_Msk | CAN_BTR_BRP_Msk | + CAN_BTR_TS1_Msk | CAN_BTR_TS2_Msk)) | + (((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk) | (((timing->phase_seg1 - 1) << CAN_BTR_TS1_Pos) & CAN_BTR_TS1_Msk) | (((timing->phase_seg2 - 1) << CAN_BTR_TS2_Pos) & CAN_BTR_TS2_Msk) | (((timing->prescaler - 1) << CAN_BTR_BRP_Pos) & CAN_BTR_BRP_Msk); - if (timing->sjw != CAN_SJW_NO_CHANGE) { - can->BTR = (can->BTR & ~CAN_BTR_SJW_Msk) | - (((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk); - } - k_mutex_unlock(&data->inst_mutex); return 0; @@ -614,7 +611,7 @@ static int can_stm32_init(const struct device *dev) const struct can_stm32_config *cfg = dev->config; struct can_stm32_data *data = dev->data; CAN_TypeDef *can = cfg->can; - struct can_timing timing; + struct can_timing timing = { 0 }; const struct device *clock; uint32_t bank_offset; int ret; @@ -675,7 +672,6 @@ static int can_stm32_init(const struct device *dev) #ifdef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY can->MCR |= CAN_MCR_ABOM; #endif - timing.sjw = cfg->sjw; if (cfg->sample_point && USE_SP_ALGO) { ret = can_calc_timing(dev, &timing, cfg->bus_speed, cfg->sample_point); @@ -687,6 +683,7 @@ static int can_stm32_init(const struct device *dev) timing.prescaler, timing.phase_seg1, timing.phase_seg2); LOG_DBG("Sample-point err : %d", ret); } else { + timing.sjw = cfg->sjw; timing.prop_seg = 0; timing.phase_seg1 = cfg->prop_ts1; timing.phase_seg2 = cfg->ts2; @@ -696,7 +693,7 @@ static int can_stm32_init(const struct device *dev) } } - ret = can_stm32_set_timing(dev, &timing); + ret = can_set_timing(dev, &timing); if (ret) { return ret; } diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index db3d961db8b..54a75b93dc3 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -234,11 +234,6 @@ struct can_bus_err_cnt { uint8_t rx_err_cnt; }; -/** Synchronization Jump Width (SJW) value to indicate that the SJW should not - * be changed by the timing calculation. - */ -#define CAN_SJW_NO_CHANGE 0 - /** * @brief CAN bus timing structure * diff --git a/include/zephyr/drivers/can/can_sja1000.h b/include/zephyr/drivers/can/can_sja1000.h index a85dc2ffa53..fe826296db9 100644 --- a/include/zephyr/drivers/can/can_sja1000.h +++ b/include/zephyr/drivers/can/can_sja1000.h @@ -176,7 +176,6 @@ struct can_sja1000_data { struct k_sem tx_idle; can_tx_callback_t tx_callback; void *tx_user_data; - uint32_t sjw; void *custom; }; diff --git a/tests/drivers/can/api/src/canfd.c b/tests/drivers/can/api/src/canfd.c index 852d1fad7e1..4fde63a36ae 100644 --- a/tests/drivers/can/api/src/canfd.c +++ b/tests/drivers/can/api/src/canfd.c @@ -389,11 +389,9 @@ ZTEST_USER(canfd, test_set_bitrate_data_while_started) */ ZTEST_USER(canfd, test_set_timing_data_while_started) { - struct can_timing timing; + struct can_timing timing = { 0 }; int err; - timing.sjw = CAN_SJW_NO_CHANGE; - err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE_3, TEST_SAMPLE_POINT); zassert_ok(err, "failed to calculate data timing (err %d)", err); diff --git a/tests/drivers/can/api/src/classic.c b/tests/drivers/can/api/src/classic.c index 1b40dc0deac..5044b600ff9 100644 --- a/tests/drivers/can/api/src/classic.c +++ b/tests/drivers/can/api/src/classic.c @@ -1031,11 +1031,9 @@ ZTEST_USER(can_classic, test_set_bitrate_while_started) */ ZTEST_USER(can_classic, test_set_timing_while_started) { - struct can_timing timing; + struct can_timing timing = { 0 }; int err; - timing.sjw = CAN_SJW_NO_CHANGE; - err = can_calc_timing(can_dev, &timing, TEST_BITRATE_1, TEST_SAMPLE_POINT); zassert_ok(err, "failed to calculate timing (err %d)", err); diff --git a/tests/drivers/can/shell/src/main.c b/tests/drivers/can/shell/src/main.c index cf2f5cc348c..8b7ec053c5a 100644 --- a/tests/drivers/can/shell/src/main.c +++ b/tests/drivers/can/shell/src/main.c @@ -136,11 +136,9 @@ static void can_shell_test_bitrate(const char *cmd, uint32_t expected_bitrate, uint16_t expected_sample_pnt) { const struct shell *sh = shell_backend_dummy_get_ptr(); - struct can_timing expected; + struct can_timing expected = { 0 }; int err; - expected.sjw = CAN_SJW_NO_CHANGE; - err = can_calc_timing(fake_can_dev, &expected, expected_bitrate, expected_sample_pnt); zassert_ok(err, "failed to calculate reference timing (err %d)", err); @@ -180,13 +178,11 @@ static void can_shell_test_dbitrate(const char *cmd, uint32_t expected_bitrate, uint16_t expected_sample_pnt) { const struct shell *sh = shell_backend_dummy_get_ptr(); - struct can_timing expected; + struct can_timing expected = { 0 }; int err; Z_TEST_SKIP_IFNDEF(CONFIG_CAN_FD_MODE); - expected.sjw = CAN_SJW_NO_CHANGE; - err = can_calc_timing_data(fake_can_dev, &expected, expected_bitrate, expected_sample_pnt); zassert_ok(err, "failed to calculate reference timing (err %d)", err); diff --git a/tests/drivers/can/timing/src/main.c b/tests/drivers/can/timing/src/main.c index 2c90863ad64..878d48ad208 100644 --- a/tests/drivers/can/timing/src/main.c +++ b/tests/drivers/can/timing/src/main.c @@ -115,13 +115,13 @@ static void assert_timing_within_bounds(struct can_timing *timing, const struct can_timing *min, const struct can_timing *max) { - zassert_true(timing->sjw == CAN_SJW_NO_CHANGE, "sjw does not equal CAN_SJW_NO_CHANGE"); - + zassert_true(timing->sjw <= max->sjw, "sjw exceeds max"); zassert_true(timing->prop_seg <= max->prop_seg, "prop_seg exceeds max"); zassert_true(timing->phase_seg1 <= max->phase_seg1, "phase_seg1 exceeds max"); zassert_true(timing->phase_seg2 <= max->phase_seg2, "phase_seg2 exceeds max"); zassert_true(timing->prescaler <= max->prescaler, "prescaler exceeds max"); + zassert_true(timing->sjw >= min->sjw, "sjw lower than min"); zassert_true(timing->prop_seg >= min->prop_seg, "prop_seg lower than min"); zassert_true(timing->phase_seg1 >= min->phase_seg1, "phase_seg1 lower than min"); zassert_true(timing->phase_seg2 >= min->phase_seg2, "phase_seg2 lower than min"); @@ -169,8 +169,6 @@ static void test_timing_values(const struct device *dev, const struct can_timing printk("testing bitrate %u, sample point %u.%u%% (%s): ", test->bitrate, test->sp / 10, test->sp % 10, test->invalid ? "invalid" : "valid"); - timing.sjw = CAN_SJW_NO_CHANGE; - if (data_phase) { if (IS_ENABLED(CONFIG_CAN_FD_MODE)) { min = can_get_timing_data_min(dev); @@ -193,8 +191,9 @@ static void test_timing_values(const struct device *dev, const struct can_timing zassert_true(sp_err <= SAMPLE_POINT_MARGIN, "sample point error %d too large", sp_err); - printk("prop_seg = %u, phase_seg1 = %u, phase_seg2 = %u, prescaler = %u ", - timing.prop_seg, timing.phase_seg1, timing.phase_seg2, timing.prescaler); + printk("sjw = %u, prop_seg = %u, phase_seg1 = %u, phase_seg2 = %u, prescaler = %u ", + timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2, + timing.prescaler); assert_bitrate_correct(dev, &timing, test->bitrate); assert_timing_within_bounds(&timing, min, max); From 9783ed56d936949f353beecf3e2b6efc6e4728f1 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 22 Sep 2023 12:18:22 +0200 Subject: [PATCH 1331/4498] dts: bindings: can: deprecate the sjw and sjw-data properties Update the descriptions for the various CAN devicetree timing properties specified in Time Quanta (TQ) to make it clear that these, if present, are only used for the initial timing parameters. Deprecate the (Re-)Synchronization Jump Width (SJW) devicetree properties for both arbitration and data phase timing as these are now only used in combination with the other TQ-based CAN timing properties, which are all deprecated. Signed-off-by: Henrik Brix Andersen --- boards/arm/mr_canhubk3/mr_canhubk3.dts | 12 ---------- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 4 ---- boards/posix/native_posix/native_posix.dts | 2 -- .../mcp2515/adafruit_can_picowbell.overlay | 1 - .../mcp2515/dfrobot_can_bus_v2_0.overlay | 1 - .../mcp2515/keyestudio_can_bus_ks0411.overlay | 1 - .../shields/tcan4550evm/tcan4550evm.overlay | 2 -- boards/x86/qemu_x86/qemu_x86.dts | 1 - dts/arm/atmel/samc21.dtsi | 4 ---- dts/arm/atmel/same70.dtsi | 4 ---- dts/arm/nxp/nxp_k66.dtsi | 1 - dts/arm/nxp/nxp_k6x.dtsi | 1 - dts/arm/nxp/nxp_ke1xf.dtsi | 2 -- dts/arm/nxp/nxp_lpc55S0x_common.dtsi | 2 -- dts/arm/nxp/nxp_lpc55S1x_common.dtsi | 2 -- dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 2 -- dts/arm/nxp/nxp_rt10xx.dtsi | 4 ---- dts/arm/nxp/nxp_rt11xx.dtsi | 6 ----- dts/arm/renesas/rcar/gen3/rcar_gen3_cr7.dtsi | 1 - dts/arm/st/f0/stm32f042.dtsi | 1 - dts/arm/st/f0/stm32f072.dtsi | 1 - dts/arm/st/f0/stm32f091.dtsi | 1 - dts/arm/st/f1/stm32f103X8.dtsi | 1 - dts/arm/st/f1/stm32f105.dtsi | 2 -- dts/arm/st/f3/stm32f3.dtsi | 1 - dts/arm/st/f4/stm32f405.dtsi | 2 -- dts/arm/st/f4/stm32f412.dtsi | 2 -- dts/arm/st/f4/stm32f413.dtsi | 1 - dts/arm/st/f4/stm32f446.dtsi | 2 -- dts/arm/st/f7/stm32f7.dtsi | 1 - dts/arm/st/f7/stm32f745.dtsi | 1 - dts/arm/st/g0/stm32g0b1.dtsi | 2 -- dts/arm/st/g4/stm32g4.dtsi | 2 -- dts/arm/st/g4/stm32g473.dtsi | 2 -- dts/arm/st/g4/stm32g491.dtsi | 2 -- dts/arm/st/h5/stm32h5.dtsi | 2 -- dts/arm/st/h5/stm32h562.dtsi | 2 -- dts/arm/st/h7/stm32h7.dtsi | 4 ---- dts/arm/st/h7/stm32h723.dtsi | 2 -- dts/arm/st/l4/stm32l431.dtsi | 1 - dts/arm/st/l4/stm32l432.dtsi | 1 - dts/arm/st/l4/stm32l451.dtsi | 1 - dts/arm/st/l4/stm32l471.dtsi | 1 - dts/arm/st/l4/stm32l496.dtsi | 1 - dts/arm/st/l4/stm32l4p5.dtsi | 1 - dts/arm/st/u5/stm32u5.dtsi | 2 -- dts/bindings/can/can-controller.yaml | 24 ++++++++++++------- dts/bindings/can/can-fd-controller.yaml | 24 ++++++++++++------- dts/bindings/can/nxp,flexcan-fd.yaml | 2 -- dts/bindings/can/nxp,flexcan.yaml | 1 - dts/bindings/can/ti,tcan4x5x.yaml | 2 -- .../espressif/esp32c3/esp32c3_common.dtsi | 1 - dts/xtensa/espressif/esp32/esp32_common.dtsi | 1 - .../espressif/esp32s2/esp32s2_common.dtsi | 1 - .../espressif/esp32s3/esp32s3_common.dtsi | 1 - tests/drivers/can/shell/app.overlay | 2 -- tests/lib/devicetree/api/app.overlay | 2 -- 57 files changed, 32 insertions(+), 124 deletions(-) diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index 8eb00eb12d4..a89047e926e 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -272,10 +272,8 @@ phys = <&can_phy0>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; status = "okay"; }; @@ -285,10 +283,8 @@ phys = <&can_phy1>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; &flexcan2 { @@ -297,10 +293,8 @@ phys = <&can_phy2>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; &flexcan3 { @@ -309,10 +303,8 @@ phys = <&can_phy3>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; &flexcan4 { @@ -321,10 +313,8 @@ phys = <&can_phy4>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; &flexcan5 { @@ -333,10 +323,8 @@ phys = <&can_phy5>; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; &lpi2c0 { diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index ba602aadd1c..6bf924802ff 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -52,10 +52,8 @@ pinctrl-names = "default"; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; status = "okay"; }; @@ -64,8 +62,6 @@ pinctrl-names = "default"; bus-speed = <125000>; sample-point = <875>; - sjw = <1>; bus-speed-data = <1000000>; sample-point-data = <875>; - sjw-data = <1>; }; diff --git a/boards/posix/native_posix/native_posix.dts b/boards/posix/native_posix/native_posix.dts index 124cc188967..75af8bdb1fd 100644 --- a/boards/posix/native_posix/native_posix.dts +++ b/boards/posix/native_posix/native_posix.dts @@ -189,7 +189,6 @@ can_loopback0: can_loopback0 { status = "okay"; compatible = "zephyr,can-loopback"; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; }; @@ -201,7 +200,6 @@ * name, e.g.: sudo ip link property add dev vcan0 altname zcan0 */ host-interface = "zcan0"; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; }; diff --git a/boards/shields/mcp2515/adafruit_can_picowbell.overlay b/boards/shields/mcp2515/adafruit_can_picowbell.overlay index 861839de9c3..163d7958318 100644 --- a/boards/shields/mcp2515/adafruit_can_picowbell.overlay +++ b/boards/shields/mcp2515/adafruit_can_picowbell.overlay @@ -16,7 +16,6 @@ reg = <0x0>; osc-freq = <16000000>; bus-speed = <125000>; - sjw = <1>; sample-point = <875>; can-transceiver { diff --git a/boards/shields/mcp2515/dfrobot_can_bus_v2_0.overlay b/boards/shields/mcp2515/dfrobot_can_bus_v2_0.overlay index 04130f29410..397fac2ef70 100644 --- a/boards/shields/mcp2515/dfrobot_can_bus_v2_0.overlay +++ b/boards/shields/mcp2515/dfrobot_can_bus_v2_0.overlay @@ -16,7 +16,6 @@ reg = <0x0>; osc-freq = <16000000>; bus-speed = <125000>; - sjw = <1>; sample-point = <875>; can-transceiver { diff --git a/boards/shields/mcp2515/keyestudio_can_bus_ks0411.overlay b/boards/shields/mcp2515/keyestudio_can_bus_ks0411.overlay index 79d2365ca31..43089f65d84 100644 --- a/boards/shields/mcp2515/keyestudio_can_bus_ks0411.overlay +++ b/boards/shields/mcp2515/keyestudio_can_bus_ks0411.overlay @@ -16,7 +16,6 @@ reg = <0x0>; osc-freq = <16000000>; bus-speed = <125000>; - sjw = <1>; sample-point = <875>; can-transceiver { diff --git a/boards/shields/tcan4550evm/tcan4550evm.overlay b/boards/shields/tcan4550evm/tcan4550evm.overlay index 8874dbdffdd..61c62ef4c0c 100644 --- a/boards/shields/tcan4550evm/tcan4550evm.overlay +++ b/boards/shields/tcan4550evm/tcan4550evm.overlay @@ -28,8 +28,6 @@ reset-gpios = <&arduino_header 14 GPIO_ACTIVE_HIGH>; /* D8 */ int-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ bosch,mram-cfg = <0x0 15 15 7 7 0 10 10>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; bus-speed = <125000>; diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 806e1cad8b4..62dfaf57b05 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -59,7 +59,6 @@ device-id = <0x8406>; interrupts = <11 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; - sjw = <1>; bus-speed = <125000>; sample-point = <875>; diff --git a/dts/arm/atmel/samc21.dtsi b/dts/arm/atmel/samc21.dtsi index 63421dbdb63..d3cdfbda777 100644 --- a/dts/arm/atmel/samc21.dtsi +++ b/dts/arm/atmel/samc21.dtsi @@ -53,9 +53,7 @@ clock-names = "GCLK", "MCLK"; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; divider = <12>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; @@ -69,9 +67,7 @@ clock-names = "GCLK", "MCLK"; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; divider = <12>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index cd021e8a3bd..7256a2bc0be 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -417,9 +417,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; divider = <6>; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; @@ -432,9 +430,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; divider = <6>; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_k66.dtsi b/dts/arm/nxp/nxp_k66.dtsi index 6ee4f202f44..2c2470fcf88 100644 --- a/dts/arm/nxp/nxp_k66.dtsi +++ b/dts/arm/nxp/nxp_k66.dtsi @@ -31,7 +31,6 @@ "rx-warning", "wake-up"; clocks = <&sim KINETIS_SIM_BUS_CLK 0x1030 4>; clk-source = <1>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index 661be1478c8..909e07e3792 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -504,7 +504,6 @@ interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", "wake-up"; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 4>; clk-source = <1>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index e0ad94d0894..0a834b2b67f 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -405,7 +405,6 @@ "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; @@ -418,7 +417,6 @@ "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_lpc55S0x_common.dtsi b/dts/arm/nxp/nxp_lpc55S0x_common.dtsi index 9f7abe6169b..ca7a25b765e 100644 --- a/dts/arm/nxp/nxp_lpc55S0x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S0x_common.dtsi @@ -223,9 +223,7 @@ interrupts = <43 0>, <44 0>; clocks = <&syscon MCUX_MCAN_CLK>; bosch,mram-cfg = <0x0 15 15 8 8 0 15 15>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi index c6b21b7495f..9e4ee4841db 100644 --- a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi @@ -218,9 +218,7 @@ interrupts = <43 0>, <44 0>; clocks = <&syscon MCUX_MCAN_CLK>; bosch,mram-cfg = <0x0 15 15 8 8 0 15 15>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 24b326f2ce8..381a0b07391 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -328,9 +328,7 @@ interrupts = <43 0>, <44 0>; clocks = <&syscon MCUX_MCAN_CLK>; bosch,mram-cfg = <0x0 15 15 8 8 0 15 15>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index 1f1ff416099..fede96dece6 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -868,7 +868,6 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 14>; clk-source = <2>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; @@ -880,7 +879,6 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 18>; clk-source = <2>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; @@ -892,8 +890,6 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x84 6>; clk-source = <2>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index 0deede76c37..ee61909255f 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -808,8 +808,6 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; clk-source = <0>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; status = "disabled"; @@ -822,8 +820,6 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 18>; clk-source = <0>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; status = "disabled"; @@ -836,8 +832,6 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN3_CLK 0x84 6>; clk-source = <0>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; status = "disabled"; diff --git a/dts/arm/renesas/rcar/gen3/rcar_gen3_cr7.dtsi b/dts/arm/renesas/rcar/gen3/rcar_gen3_cr7.dtsi index 549443ee995..0f1cecf7d89 100644 --- a/dts/arm/renesas/rcar/gen3/rcar_gen3_cr7.dtsi +++ b/dts/arm/renesas/rcar/gen3/rcar_gen3_cr7.dtsi @@ -94,7 +94,6 @@ interrupt-parent = <&gic>; interrupts = ; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/arm/st/f0/stm32f042.dtsi b/dts/arm/st/f0/stm32f042.dtsi index e8aed739bd7..52744d1ff47 100644 --- a/dts/arm/st/f0/stm32f042.dtsi +++ b/dts/arm/st/f0/stm32f042.dtsi @@ -44,7 +44,6 @@ interrupts = <30 0>; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f0/stm32f072.dtsi b/dts/arm/st/f0/stm32f072.dtsi index 368ea324e4f..1c7ad8b1b67 100644 --- a/dts/arm/st/f0/stm32f072.dtsi +++ b/dts/arm/st/f0/stm32f072.dtsi @@ -16,7 +16,6 @@ interrupts = <30 0>; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f0/stm32f091.dtsi b/dts/arm/st/f0/stm32f091.dtsi index 2b68394f507..b1ad8f0646e 100644 --- a/dts/arm/st/f0/stm32f091.dtsi +++ b/dts/arm/st/f0/stm32f091.dtsi @@ -58,7 +58,6 @@ interrupts = <30 0>; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f1/stm32f103X8.dtsi b/dts/arm/st/f1/stm32f103X8.dtsi index a70d4c83a39..ae7150291be 100644 --- a/dts/arm/st/f1/stm32f103X8.dtsi +++ b/dts/arm/st/f1/stm32f103X8.dtsi @@ -54,7 +54,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; }; diff --git a/dts/arm/st/f1/stm32f105.dtsi b/dts/arm/st/f1/stm32f105.dtsi index 9ff6104bf12..1a2ec793d99 100644 --- a/dts/arm/st/f1/stm32f105.dtsi +++ b/dts/arm/st/f1/stm32f105.dtsi @@ -40,7 +40,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; @@ -52,7 +51,6 @@ /* also enabling clock for can1 (master instance) */ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f3/stm32f3.dtsi b/dts/arm/st/f3/stm32f3.dtsi index bef28bd44dc..a426a84ea3e 100644 --- a/dts/arm/st/f3/stm32f3.dtsi +++ b/dts/arm/st/f3/stm32f3.dtsi @@ -420,7 +420,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f4/stm32f405.dtsi b/dts/arm/st/f4/stm32f405.dtsi index 445c7df7b9d..a462d48a266 100644 --- a/dts/arm/st/f4/stm32f405.dtsi +++ b/dts/arm/st/f4/stm32f405.dtsi @@ -212,7 +212,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; @@ -225,7 +224,6 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f4/stm32f412.dtsi b/dts/arm/st/f4/stm32f412.dtsi index bf15b9f67fd..07f93afc963 100644 --- a/dts/arm/st/f4/stm32f412.dtsi +++ b/dts/arm/st/f4/stm32f412.dtsi @@ -222,7 +222,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; @@ -235,7 +234,6 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; }; diff --git a/dts/arm/st/f4/stm32f413.dtsi b/dts/arm/st/f4/stm32f413.dtsi index 17d8137badd..ac61c7d351b 100644 --- a/dts/arm/st/f4/stm32f413.dtsi +++ b/dts/arm/st/f4/stm32f413.dtsi @@ -79,7 +79,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x08000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; }; diff --git a/dts/arm/st/f4/stm32f446.dtsi b/dts/arm/st/f4/stm32f446.dtsi index d7039c4ff1b..7b15fe2a9cf 100644 --- a/dts/arm/st/f4/stm32f446.dtsi +++ b/dts/arm/st/f4/stm32f446.dtsi @@ -65,7 +65,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; @@ -78,7 +77,6 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index 87bb8545b72..2df24d0c8d2 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -404,7 +404,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/f7/stm32f745.dtsi b/dts/arm/st/f7/stm32f745.dtsi index 895525f9bc0..d63ddd881ba 100644 --- a/dts/arm/st/f7/stm32f745.dtsi +++ b/dts/arm/st/f7/stm32f745.dtsi @@ -72,7 +72,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x04000000>; status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/g0/stm32g0b1.dtsi b/dts/arm/st/g0/stm32g0b1.dtsi index fd65aa54c08..621214b080c 100644 --- a/dts/arm/st/g0/stm32g0b1.dtsi +++ b/dts/arm/st/g0/stm32g0b1.dtsi @@ -38,9 +38,7 @@ interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00001000>; bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 2ab13841dc9..feec71388aa 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -390,9 +390,7 @@ interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/g4/stm32g473.dtsi b/dts/arm/st/g4/stm32g473.dtsi index 4bfe01b7b3d..97565c33e73 100644 --- a/dts/arm/st/g4/stm32g473.dtsi +++ b/dts/arm/st/g4/stm32g473.dtsi @@ -103,9 +103,7 @@ interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; bosch,mram-cfg = <0x6a0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/g4/stm32g491.dtsi b/dts/arm/st/g4/stm32g491.dtsi index 5bdac5010dd..865d3700d96 100644 --- a/dts/arm/st/g4/stm32g491.dtsi +++ b/dts/arm/st/g4/stm32g491.dtsi @@ -17,10 +17,8 @@ interrupts = <86 0>, <87 0>; interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; - sjw = <1>; bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/h5/stm32h5.dtsi b/dts/arm/st/h5/stm32h5.dtsi index f8f9e64e092..d8a93a58619 100644 --- a/dts/arm/st/h5/stm32h5.dtsi +++ b/dts/arm/st/h5/stm32h5.dtsi @@ -442,9 +442,7 @@ interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>; bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index eeaf65ab7da..66ed8d3d927 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -303,9 +303,7 @@ /* common clock FDCAN 1 & 2 */ clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>; bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 8c66a67b057..c835040b7e0 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -475,9 +475,7 @@ interrupts = <19 0>, <21 0>, <63 0>; interrupt-names = "LINE_0", "LINE_1", "CALIB"; bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; @@ -490,9 +488,7 @@ interrupts = <20 0>, <22 0>, <63 0>; interrupt-names = "LINE_0", "LINE_1", "CALIB"; bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index 8c3fa0b1d8b..f1b0836f6e8 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -123,9 +123,7 @@ interrupts = <159 0>, <160 0>, <63 0>; interrupt-names = "LINE_0", "LINE_1", "CALIB"; bosch,mram-cfg = <0x6a0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/arm/st/l4/stm32l431.dtsi b/dts/arm/st/l4/stm32l431.dtsi index d25d3bc1c22..9a9892a0f4d 100644 --- a/dts/arm/st/l4/stm32l431.dtsi +++ b/dts/arm/st/l4/stm32l431.dtsi @@ -107,7 +107,6 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; interrupts = <19 0>, <20 0>, <21 0>, <22 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/arm/st/l4/stm32l432.dtsi b/dts/arm/st/l4/stm32l432.dtsi index 3ad6a2e3aae..9db0a1e244e 100644 --- a/dts/arm/st/l4/stm32l432.dtsi +++ b/dts/arm/st/l4/stm32l432.dtsi @@ -57,7 +57,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; //RCC_APB1ENR1_CAN1EN status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/l4/stm32l451.dtsi b/dts/arm/st/l4/stm32l451.dtsi index a8722ed5890..b566db4336a 100644 --- a/dts/arm/st/l4/stm32l451.dtsi +++ b/dts/arm/st/l4/stm32l451.dtsi @@ -141,7 +141,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; //RCC_APB1ENR1_CAN1EN status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/l4/stm32l471.dtsi b/dts/arm/st/l4/stm32l471.dtsi index 5a7cd657785..c1f5b5978a0 100644 --- a/dts/arm/st/l4/stm32l471.dtsi +++ b/dts/arm/st/l4/stm32l471.dtsi @@ -232,7 +232,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; //RCC_APB1ENR1_CAN1EN status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/l4/stm32l496.dtsi b/dts/arm/st/l4/stm32l496.dtsi index d253a945415..12d74f6859b 100644 --- a/dts/arm/st/l4/stm32l496.dtsi +++ b/dts/arm/st/l4/stm32l496.dtsi @@ -55,7 +55,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x04000000>; //RCC_APB1ENR1_CAN2EN status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/l4/stm32l4p5.dtsi b/dts/arm/st/l4/stm32l4p5.dtsi index d84f2d164e7..03973dcf077 100644 --- a/dts/arm/st/l4/stm32l4p5.dtsi +++ b/dts/arm/st/l4/stm32l4p5.dtsi @@ -291,7 +291,6 @@ interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; //RCC_APB1ENR1_CAN1EN status = "disabled"; - sjw = <1>; sample-point = <875>; }; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 20d4806f92f..95bb4173c65 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -777,9 +777,7 @@ interrupt-names = "LINE_0", "LINE_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>; bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; - sjw = <1>; sample-point = <875>; - sjw-data = <1>; sample-point-data = <875>; status = "disabled"; }; diff --git a/dts/bindings/can/can-controller.yaml b/dts/bindings/can/can-controller.yaml index 0a6309ecd68..a0e31045c70 100644 --- a/dts/bindings/can/can-controller.yaml +++ b/dts/bindings/can/can-controller.yaml @@ -9,26 +9,34 @@ properties: description: bus speed in Baud/s sjw: type: int - required: true - description: Resynchronization jump width (ISO 11898-1) + deprecated: true + default: 1 + description: | + Initial time quanta of resynchronization jump width (ISO 11898-1). + + Deprecated in favor of automatic calculation of a suitable default SJW based on existing + timing parameters. Default of 1 matches the default value previously used for all in-tree CAN + controller devicetree instances. + + Applications can still manually set the SJW using the CAN timing APIs. prop-seg: type: int deprecated: true description: | - Time quantums of propagation segment (ISO 11898-1). Deprecated in favor of setting advanced - timing parameters from the application. + Initial time quanta of propagation segment (ISO 11898-1). Deprecated in favor of setting + advanced timing parameters from the application. phase-seg1: type: int deprecated: true description: | - Time quantums of phase buffer 1 segment (ISO 11898-1). Deprecated in favor of setting advanced - timing parameters from the application. + Initial time quanta of phase buffer 1 segment (ISO 11898-1). Deprecated in favor of setting + advanced timing parameters from the application. phase-seg2: type: int deprecated: true description: | - Time quantums of phase buffer 2 segment (ISO 11898-1). Deprecated in favor of setting advanced - timing parameters from the application. + Initial time quanta of phase buffer 2 segment (ISO 11898-1). Deprecated in favor of setting + advanced timing parameters from the application. sample-point: type: int description: > diff --git a/dts/bindings/can/can-fd-controller.yaml b/dts/bindings/can/can-fd-controller.yaml index 176013f775f..e6842403ac6 100644 --- a/dts/bindings/can/can-fd-controller.yaml +++ b/dts/bindings/can/can-fd-controller.yaml @@ -9,26 +9,34 @@ properties: description: data phase bus speed in Baud/s sjw-data: type: int - required: true - description: Resynchronization jump width for the data phase. (ISO11898-1:2015) + deprecated: true + default: 1 + description: | + Initial time quanta of resynchronization jump width for the data phase (ISO11898-1:2015). + + Deprecated in favor of automatic calculation of a suitable default SJW based on existing + timing parameters. Default of 1 matches the default value previously used for all in-tree CAN + controller devicetree instances. + + Applications can still manually set the SJW using the CAN timing APIs. prop-seg-data: type: int deprecated: true description: | - Time quantums of propagation segment for the data phase (ISO11898-1:2015). Deprecated in favor - of setting advanced timing parameters from the application. + Initial time quanta of propagation segment for the data phase (ISO11898-1:2015). Deprecated in + favor of setting advanced timing parameters from the application. phase-seg1-data: type: int deprecated: true description: | - Time quantums of phase buffer 1 segment for the data phase (ISO11898-1:2015). Deprecated in - favor of setting advanced timing parameters from the application. + Initial time quanta of phase buffer 1 segment for the data phase (ISO11898-1:2015). Deprecated + in favor of setting advanced timing parameters from the application. phase-seg2-data: type: int deprecated: true description: | - Time quantums of phase buffer 2 segment for the data phase (ISO11898-1:2015). Deprecated in - favor of setting advanced timing parameters from the application. + Initial time quanta of phase buffer 2 segment for the data phase (ISO11898-1:2015). Deprecated + in favor of setting advanced timing parameters from the application. sample-point-data: type: int description: > diff --git a/dts/bindings/can/nxp,flexcan-fd.yaml b/dts/bindings/can/nxp,flexcan-fd.yaml index 5661c919c51..890cbd8de94 100644 --- a/dts/bindings/can/nxp,flexcan-fd.yaml +++ b/dts/bindings/can/nxp,flexcan-fd.yaml @@ -15,8 +15,6 @@ description: | interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x84 6>; clk-source = <2>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; bus-speed = <125000>; diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index dca50aa8a65..f23d0f45d81 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -13,7 +13,6 @@ description: | interrupt-names = "warning", "error", "wake-up", "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; pinctrl-0 = <&pinmux_flexcan0>; diff --git a/dts/bindings/can/ti,tcan4x5x.yaml b/dts/bindings/can/ti,tcan4x5x.yaml index 7434da00613..567a158a205 100644 --- a/dts/bindings/can/ti,tcan4x5x.yaml +++ b/dts/bindings/can/ti,tcan4x5x.yaml @@ -16,8 +16,6 @@ description: | reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; - sjw = <1>; - sjw-data = <1>; sample-point = <875>; sample-point-data = <875>; bus-speed = <125000>; diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 19e621e528f..3b2bb6d0781 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -218,7 +218,6 @@ interrupts = ; interrupt-parent = <&intc>; clocks = <&rtc ESP32_TWAI_MODULE>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index 09714cd2743..c7b735dd779 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -344,7 +344,6 @@ interrupts = ; interrupt-parent = <&intc>; clocks = <&rtc ESP32_TWAI_MODULE>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi index 696e77a8ffb..b523ec53364 100644 --- a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi +++ b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi @@ -331,7 +331,6 @@ interrupts = ; interrupt-parent = <&intc>; clocks = <&rtc ESP32_TWAI_MODULE>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index 7655b3537db..3c373272593 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -261,7 +261,6 @@ interrupts = ; interrupt-parent = <&intc>; clocks = <&rtc ESP32_TWAI_MODULE>; - sjw = <1>; sample-point = <875>; status = "disabled"; }; diff --git a/tests/drivers/can/shell/app.overlay b/tests/drivers/can/shell/app.overlay index 60366fc3a52..2e6c8c99790 100644 --- a/tests/drivers/can/shell/app.overlay +++ b/tests/drivers/can/shell/app.overlay @@ -8,11 +8,9 @@ fake_can: fake_can { compatible = "zephyr,fake-can"; status = "okay"; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; sample-point = <875>; - sjw-data = <1>; bus-speed-data = <1000000>; sample-point-data = <750>; }; diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 2a5f4bd5135..585008a8837 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -483,7 +483,6 @@ test_can0: can@55553333 { compatible = "vnd,can-controller"; reg = < 0x55553333 0x1000 >; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; status = "okay"; @@ -493,7 +492,6 @@ test_can1: can@55554444 { compatible = "vnd,can-controller"; reg = < 0x55554444 0x1000 >; - sjw = <1>; sample-point = <875>; bus-speed = <125000>; status = "okay"; From ddd2b490b006e36c2565ac5d53eda272a7a68488 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 27 Sep 2023 19:50:19 +0200 Subject: [PATCH 1332/4498] doc: releases: update v3.5 migration guide with changes in CAN timing Update the migration guide for v3.5 to mention the changes related to setting CAN timing. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-3.5.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index b59c8093f9f..ab891988aa9 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -108,6 +108,16 @@ Required changes to a smaller, but inexact conversion algorithm. This requires building Picolibc as a module. +* The CAN controller timing API functions :c:func:`can_set_timing` and :c:func:`can_set_timing_data` + no longer fallback to the (Re-)Synchronization Jump Width (SJW) value set in the devicetree + properties for the given CAN controller upon encountering an SJW value corresponding to + ``CAN_SJW_NO_CHANGE`` (which is no longer available). The caller will therefore need to fill in + the ``sjw`` field in :c:struct:`can_timing`. To aid in this, the :c:func:`can_calc_timing` and + :c:func:`can_calc_timing_data` functions now automatically calculate a suitable SJW. The + calculated SJW can be overwritten by the caller if needed. The CAN controller API functions + :c:func:`can_set_bitrate` and :c:func:`can_set_bitrate_data` now also automatically calculate a + suitable SJW, but their SJW cannot be overwritten by the caller. + Recommended Changes ******************* @@ -151,3 +161,15 @@ Recommended Changes will be removed in future releases. Note that these changes do not apply to initialization levels used in the context of the ``init.h`` API, e.g. :c:macro:`SYS_INIT`. + +* The following CAN controller devicetree properties are now deprecated in favor specifying the + initial CAN bitrate using the ``bus-speed``, ``sample-point``, ``bus-speed-data``, and + ``sample-point-data`` properties: + * ``sjw`` + * ``prop-seg`` + * ``phase-seg1`` + * ``phase-seg1`` + * ``sjw-data`` + * ``prop-seg-data`` + * ``phase-seg1-data`` + * ``phase-seg1-data`` From 1134245ac9dd83da5a3d9f4af351c78e5b2a531c Mon Sep 17 00:00:00 2001 From: Jeroen Reeskamp Date: Mon, 19 Jun 2023 14:33:30 +0200 Subject: [PATCH 1333/4498] sensors: lsm6dso: Values now match better with the ODR values. Values are specified in the datasheet(page 30, table 18). Values match with values defined in lsm6dso-common.yaml Signed-off-by: Jeroen Reeskamp --- drivers/sensor/lsm6dso/lsm6dso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/lsm6dso/lsm6dso.c b/drivers/sensor/lsm6dso/lsm6dso.c index 2344d2c02ee..fe6b65edbec 100644 --- a/drivers/sensor/lsm6dso/lsm6dso.c +++ b/drivers/sensor/lsm6dso/lsm6dso.c @@ -23,8 +23,8 @@ LOG_MODULE_REGISTER(LSM6DSO, CONFIG_SENSOR_LOG_LEVEL); -static const uint16_t lsm6dso_odr_map[] = {0, 12, 26, 52, 104, 208, 416, 833, - 1660, 3330, 6660}; +static const uint16_t lsm6dso_odr_map[] = {0, 12, 26, 52, 104, 208, 417, 833, + 1667, 3333, 6667}; static int lsm6dso_freq_to_odr_val(uint16_t freq) { From 2d38c095a612e38b209484328f4b7408879d116b Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 26 Sep 2023 13:09:06 +0200 Subject: [PATCH 1334/4498] west: runners: Add support for a common --reset argument Some of the runners in the tree have been adding their own, class-specific versions of a switch to instruct the runner to reset or not the device after flashing. In order to better support multi-image builds that require more than one flash operation, introduce a new --reset,--no-reset command-line parameter that is part of the RunnerCaps so taht this functionality can be accessed in a standardized manner. Implementations for the new parameter are provided for the runner classes that were already configurable in this regard. Signed-off-by: Carles Cufi Signed-off-by: Jamie McCrae --- scripts/west_commands/runners/core.py | 19 ++++++++++++++++++- scripts/west_commands/runners/esp32.py | 17 +++++++++++------ scripts/west_commands/runners/ezflashcli.py | 12 ++++++++---- scripts/west_commands/runners/jlink.py | 18 +++++++++--------- scripts/west_commands/runners/nrf_common.py | 10 +++++++--- scripts/west_commands/runners/nrfjprog.py | 1 + scripts/west_commands/runners/nrfutil.py | 5 +++-- scripts/west_commands/runners/stm32flash.py | 7 +++---- 8 files changed, 60 insertions(+), 29 deletions(-) diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index b569625e4e6..68ad0eea024 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -229,6 +229,9 @@ class RunnerCaps: erased by the underlying tool before flashing; UICR on nRF SoCs is one example.) + - reset: whether the runner supports a --reset option, which + resets the device after a flash operation is complete. + - tool_opt: whether the runner supports a --tool-opt (-O) option, which can be given multiple times and is passed on to the underlying tool that the runner wraps. @@ -240,12 +243,14 @@ def __init__(self, dev_id: bool = False, flash_addr: bool = False, erase: bool = False, + reset: bool = False, tool_opt: bool = False, file: bool = False): self.commands = commands self.dev_id = dev_id self.flash_addr = bool(flash_addr) self.erase = bool(erase) + self.reset = bool(reset) self.tool_opt = bool(tool_opt) self.file = bool(file) @@ -254,6 +259,7 @@ def __str__(self): f'dev_id={self.dev_id}, ' f'flash_addr={self.flash_addr}, ' f'erase={self.erase}, ' + f'reset={self.reset}, ' f'tool_opt={self.tool_opt}, ' f'file={self.file}' ')') @@ -521,9 +527,16 @@ def add_parser(cls, parser): parser.add_argument('--erase', '--no-erase', nargs=0, action=_ToggleAction, - help=("mass erase flash before loading, or don't" + help=("mass erase flash before loading, or don't. " + "Default action depends on each specific runner." if caps.erase else argparse.SUPPRESS)) + parser.add_argument('--reset', '--no-reset', nargs=0, + action=_ToggleAction, + help=("reset device after flashing, or don't. " + "Default action depends on each specific runner." + if caps.reset else argparse.SUPPRESS)) + parser.add_argument('-O', '--tool-opt', dest='tool_opt', default=[], action='append', help=(cls.tool_opt_help() if caps.tool_opt @@ -552,6 +565,8 @@ def create(cls, cfg: RunnerConfig, _missing_cap(cls, '--dt-flash') if args.erase and not caps.erase: _missing_cap(cls, '--erase') + if args.reset and not caps.reset: + _missing_cap(cls, '--reset') if args.tool_opt and not caps.tool_opt: _missing_cap(cls, '--tool-opt') if args.file and not caps.file: @@ -564,6 +579,8 @@ def create(cls, cfg: RunnerConfig, ret = cls.do_create(cfg, args) if args.erase: ret.logger.info('mass erase requested') + if args.reset: + ret.logger.info('reset after flashing requested') return ret @classmethod diff --git a/scripts/west_commands/runners/esp32.py b/scripts/west_commands/runners/esp32.py index d435014fc38..0ccf0c98d1f 100644 --- a/scripts/west_commands/runners/esp32.py +++ b/scripts/west_commands/runners/esp32.py @@ -16,13 +16,15 @@ class Esp32BinaryRunner(ZephyrBinaryRunner): '''Runner front-end for espidf.''' def __init__(self, cfg, device, boot_address, part_table_address, - app_address, erase=False, baud=921600, flash_size='detect', - flash_freq='40m', flash_mode='dio', espidf='espidf', - bootloader_bin=None, partition_table_bin=None, no_stub=False): + app_address, erase=False, reset=False, baud=921600, + flash_size='detect', flash_freq='40m', flash_mode='dio', + espidf='espidf', bootloader_bin=None, partition_table_bin=None, + no_stub=False): super().__init__(cfg) self.elf = cfg.elf_file self.app_bin = cfg.bin_file self.erase = bool(erase) + self.reset = bool(reset) self.device = device self.boot_address = boot_address self.part_table_address = part_table_address @@ -42,7 +44,7 @@ def name(cls): @classmethod def capabilities(cls): - return RunnerCaps(commands={'flash'}, erase=True) + return RunnerCaps(commands={'flash'}, erase=True, reset=True) @classmethod def do_add_parser(cls, parser): @@ -77,6 +79,8 @@ def do_add_parser(cls, parser): parser.add_argument('--esp-no-stub', default=False, action='store_true', help='Disable launching the flasher stub, only talk to ROM bootloader') + parser.set_defaults(reset=True) + @classmethod def do_create(cls, cfg, args): if args.esp_tool: @@ -88,7 +92,7 @@ def do_create(cls, cfg, args): return Esp32BinaryRunner( cfg, args.esp_device, boot_address=args.esp_boot_address, part_table_address=args.esp_partition_table_address, - app_address=args.esp_app_address, erase=args.erase, + app_address=args.esp_app_address, erase=args.erase, reset=args.reset, baud=args.esp_baud_rate, flash_size=args.esp_flash_size, flash_freq=args.esp_flash_freq, flash_mode=args.esp_flash_mode, espidf=espidf, bootloader_bin=args.esp_flash_bootloader, @@ -111,7 +115,8 @@ def do_run(self, command, **kwargs): cmd_flash.extend(['--port', self.device]) cmd_flash.extend(['--baud', self.baud]) cmd_flash.extend(['--before', 'default_reset']) - cmd_flash.extend(['--after', 'hard_reset', 'write_flash', '-u']) + if self.reset: + cmd_flash.extend(['--after', 'hard_reset', 'write_flash', '-u']) cmd_flash.extend(['--flash_mode', self.flash_mode]) cmd_flash.extend(['--flash_freq', self.flash_freq]) cmd_flash.extend(['--flash_size', self.flash_size]) diff --git a/scripts/west_commands/runners/ezflashcli.py b/scripts/west_commands/runners/ezflashcli.py index 4d9d3d3ae51..a3e1aea3d25 100644 --- a/scripts/west_commands/runners/ezflashcli.py +++ b/scripts/west_commands/runners/ezflashcli.py @@ -10,13 +10,14 @@ class EzFlashCliBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for ezFlashCLI''' - def __init__(self, cfg, tool, sn, erase=False): + def __init__(self, cfg, tool, sn, erase=False, reset=True): super().__init__(cfg) self.bin_ = cfg.bin_file self.tool = tool self.sn_arg = ['-j', f'{sn}'] if sn is not None else [] self.erase = bool(erase) + self.reset = bool(reset) @classmethod def name(cls): @@ -24,7 +25,7 @@ def name(cls): @classmethod def capabilities(cls): - return RunnerCaps(commands={'flash'}, erase=True) + return RunnerCaps(commands={'flash'}, erase=True, reset=True) @classmethod def do_add_parser(cls, parser): @@ -34,6 +35,8 @@ def do_add_parser(cls, parser): parser.add_argument('--sn', default=None, required=False, help='J-Link probe serial number') + parser.set_defaults(reset=True) + @classmethod def do_create(cls, cfg, args): return EzFlashCliBinaryRunner(cfg, tool=args.tool, sn=args.sn, @@ -64,7 +67,7 @@ def program_bin(self): load_offset = self.build_conf['CONFIG_FLASH_LOAD_OFFSET'] self.check_call([self.tool] + self.sn_arg + ["write_flash", f'0x{load_offset:x}', self.bin_]) - def reset(self): + def reset_device(self): self.logger.info("Resetting...") self.check_call([self.tool] + self.sn_arg + ["go"]) @@ -72,4 +75,5 @@ def do_run(self, command, **kwargs): self.require(self.tool) self.ensure_output('bin') self.program_bin() - self.reset() + if self.reset: + self.reset_device() diff --git a/scripts/west_commands/runners/jlink.py b/scripts/west_commands/runners/jlink.py index 80b7de2dffb..4fa71720673 100644 --- a/scripts/west_commands/runners/jlink.py +++ b/scripts/west_commands/runners/jlink.py @@ -35,7 +35,7 @@ class JLinkBinaryRunner(ZephyrBinaryRunner): def __init__(self, cfg, device, dev_id=None, commander=DEFAULT_JLINK_EXE, - dt_flash=True, erase=True, reset_after_load=False, + dt_flash=True, erase=True, reset=False, iface='swd', speed='auto', loader=None, gdbserver='JLinkGDBServer', @@ -54,7 +54,7 @@ def __init__(self, cfg, device, dev_id=None, self.commander = commander self.dt_flash = dt_flash self.erase = erase - self.reset_after_load = reset_after_load + self.reset = reset self.gdbserver = gdbserver self.iface = iface self.speed = speed @@ -74,7 +74,7 @@ def name(cls): @classmethod def capabilities(cls): return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach'}, - dev_id=True, flash_addr=True, erase=True, + dev_id=True, flash_addr=True, erase=True, reset=True, tool_opt=True, file=True) @classmethod @@ -114,11 +114,11 @@ def do_add_parser(cls, parser): help=f'''J-Link Commander, default is {DEFAULT_JLINK_EXE}''') parser.add_argument('--reset-after-load', '--no-reset-after-load', - dest='reset_after_load', nargs=0, + dest='reset', nargs=0, action=ToggleAction, - help='reset after loading? (default: no)') + help='obsolete synonym for --reset/--no-reset') - parser.set_defaults(reset_after_load=False) + parser.set_defaults(reset=False) @classmethod def do_create(cls, cfg, args): @@ -127,7 +127,7 @@ def do_create(cls, cfg, args): commander=args.commander, dt_flash=args.dt_flash, erase=args.erase, - reset_after_load=args.reset_after_load, + reset=args.reset, iface=args.iface, speed=args.speed, gdbserver=args.gdbserver, loader=args.loader, @@ -266,7 +266,7 @@ def do_run(self, command, **kwargs): client_cmd += ['-ex', 'monitor halt', '-ex', 'monitor reset', '-ex', 'load'] - if self.reset_after_load: + if self.reset: client_cmd += ['-ex', 'monitor reset'] if not self.gdb_host: self.require(self.gdbserver) @@ -326,7 +326,7 @@ def flash(self, **kwargs): # Flash the selected build artifact lines.append(flash_cmd) - if self.reset_after_load: + if self.reset: lines.append('r') # Reset and halt the target lines.append('g') # Start the CPU diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 1a66ed0bded..68540669868 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -28,7 +28,7 @@ class NrfBinaryRunner(ZephyrBinaryRunner): '''Runner front-end base class for nrf tools.''' def __init__(self, cfg, family, softreset, dev_id, erase=False, - tool_opt=[], force=False, recover=False): + reset=True, tool_opt=[], force=False, recover=False): super().__init__(cfg) self.hex_ = cfg.hex_file if family and not family.endswith('_FAMILY'): @@ -37,6 +37,7 @@ def __init__(self, cfg, family, softreset, dev_id, erase=False, self.softreset = softreset self.dev_id = dev_id self.erase = bool(erase) + self.reset = bool(reset) self.force = force self.recover = bool(recover) @@ -47,7 +48,7 @@ def __init__(self, cfg, family, softreset, dev_id, erase=False, @classmethod def capabilities(cls): return RunnerCaps(commands={'flash'}, dev_id=True, erase=True, - tool_opt=True) + reset=True, tool_opt=True) @classmethod def dev_id_help(cls) -> str: @@ -75,6 +76,8 @@ def do_add_parser(cls, parser): memory and disable read back protection before flashing (erases flash for both cores on nRF53)''') + parser.set_defaults(reset=True) + def ensure_snr(self): if not self.dev_id or "*" in self.dev_id: self.dev_id = self.get_board_snr(self.dev_id or "*") @@ -398,7 +401,8 @@ def do_run(self, command, **kwargs): if self.recover: self.recover_target() self.program_hex() - self.reset_target() + if self.reset: + self.reset_target() # All done, now flush any outstanding ops self.flush(force=True) diff --git a/scripts/west_commands/runners/nrfjprog.py b/scripts/west_commands/runners/nrfjprog.py index 9671def33c1..8762ce0e740 100644 --- a/scripts/west_commands/runners/nrfjprog.py +++ b/scripts/west_commands/runners/nrfjprog.py @@ -30,6 +30,7 @@ def tool_opt_help(cls) -> str: def do_create(cls, cfg, args): return NrfJprogBinaryRunner(cfg, args.nrf_family, args.softreset, args.dev_id, erase=args.erase, + reset=args.reset, tool_opt=args.tool_opt, force=args.force, recover=args.recover) diff --git a/scripts/west_commands/runners/nrfutil.py b/scripts/west_commands/runners/nrfutil.py index 9c92c07f07d..719e432a23b 100644 --- a/scripts/west_commands/runners/nrfutil.py +++ b/scripts/west_commands/runners/nrfutil.py @@ -16,9 +16,9 @@ class NrfUtilBinaryRunner(NrfBinaryRunner): '''Runner front-end for nrfutil.''' def __init__(self, cfg, family, softreset, dev_id, erase=False, - tool_opt=[], force=False, recover=False): + reset=True, tool_opt=[], force=False, recover=False): - super().__init__(cfg, family, softreset, dev_id, erase, + super().__init__(cfg, family, softreset, dev_id, erase, reset, tool_opt, force, recover) self._ops = [] self._op_id = 1 @@ -35,6 +35,7 @@ def tool_opt_help(cls) -> str: def do_create(cls, cfg, args): return NrfUtilBinaryRunner(cfg, args.nrf_family, args.softreset, args.dev_id, erase=args.erase, + reset=args.reset, tool_opt=args.tool_opt, force=args.force, recover=args.recover) diff --git a/scripts/west_commands/runners/stm32flash.py b/scripts/west_commands/runners/stm32flash.py index 052c45dbb49..5aa544d4b2a 100644 --- a/scripts/west_commands/runners/stm32flash.py +++ b/scripts/west_commands/runners/stm32flash.py @@ -37,7 +37,7 @@ def name(cls): @classmethod def capabilities(cls): - return RunnerCaps(commands={'flash'}) + return RunnerCaps(commands={'flash'}, reset=True) @classmethod def do_add_parser(cls, parser): @@ -72,12 +72,11 @@ def do_add_parser(cls, parser): parser.add_argument('--serial-mode', default='8e1', required=False, help='serial port mode, default \'8e1\'') - parser.add_argument('--reset', default=False, required=False, action='store_true', - help='reset device at exit, default False') - parser.add_argument('--verify', default=False, required=False, action='store_true', help='verify writes, default False') + parser.set_defaults(reset=False) + @classmethod def do_create(cls, cfg, args): return Stm32flashBinaryRunner(cfg, device=args.device, action=args.action, From 3a4a82bb58d125bff049f4c5f6319774a6a83e0e Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 28 Sep 2023 15:32:59 +0300 Subject: [PATCH 1335/4498] MAINTAINERS.yml: Add entry for bindesc Add a MAINTAINERS.yml entry for binary descriptors, with yonsch as maintainer. Signed-off-by: Yonatan Schachter --- MAINTAINERS.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index d05c2768577..f0c4f475bb1 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -193,6 +193,18 @@ Ambiq Platforms: labels: - "platform: Ambiq" +Binary Descriptors: + status: maintained + maintainers: + - yonsch + files: + - subsys/bindesc/ + - include/zephyr/bindesc.h + - samples/subsys/bindesc/ + - scripts/west_commands/bindesc.py + labels: + - "area: Binary Descriptors" + Bluetooth: status: maintained maintainers: From 0bc277b7a07b6a24124697be8371841625ba1547 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 28 Sep 2023 15:34:15 +0300 Subject: [PATCH 1336/4498] release-notes: Added binary descriptors Added binary descriptors to the release notes, under "Libraries / Subsystems". Signed-off-by: Yonatan Schachter --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b9d1d027ea5..b08e317db60 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -378,6 +378,10 @@ Libraries / Subsystems * Added the :ref:`blinfo_api` subsystem. +* Binary descriptors + + * Added the :ref:`binary_descriptors` (``bindesc``) subsystem. + HALs **** From f4e2a669eb6d7f49b9b8a50210d2d08ca6c77300 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 28 Sep 2023 15:35:13 +0300 Subject: [PATCH 1337/4498] samples: hello_bindesc: Improved README.md Improved the README.md of the hello_bindesc sample by adding a note about non existing bin files and referencing the relevant parts of the documentation. Signed-off-by: Yonatan Schachter --- samples/subsys/bindesc/hello_bindesc/README.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/samples/subsys/bindesc/hello_bindesc/README.rst b/samples/subsys/bindesc/hello_bindesc/README.rst index e72f6934608..5934b3f0ca6 100644 --- a/samples/subsys/bindesc/hello_bindesc/README.rst +++ b/samples/subsys/bindesc/hello_bindesc/README.rst @@ -11,7 +11,7 @@ A simple sample of binary descriptor definition and usage. Building and Running ******************** -Follow these steps to build the `hello_bindesc` sample application: +Follow these steps to build the ``hello_bindesc`` sample application: .. zephyr-app-commands:: :zephyr-app: samples/subsys/bindesc/hello_bindesc @@ -19,8 +19,13 @@ Follow these steps to build the `hello_bindesc` sample application: :goals: build :compact: -To see all binary descriptors, run: +To dump all binary descriptors in the image, run: .. code-block:: bash west bindesc dump build/zephyr/zephyr.bin + +(Note: you can also dump the contents of ``zephyr.elf``, if your build system +does not produce a ``*.bin`` file, e.g. compiling for ``native_posix``.) + +For more details see :ref:`binary_descriptors` and :ref:`west-bindesc`. From 66c4cef240a9ac037aa71ec668e1aaf683f26f94 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 28 Sep 2023 15:36:40 +0300 Subject: [PATCH 1338/4498] west_commands: bindesc: Fixed crash when no sub-command is given The west bindesc command currently crashes when no subcommand is given. This is because the subcommand was not marked as required. This commit fixes the issue. Signed-off-by: Yonatan Schachter --- scripts/west_commands/bindesc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/bindesc.py b/scripts/west_commands/bindesc.py index a4bc852bfab..c56555484e6 100644 --- a/scripts/west_commands/bindesc.py +++ b/scripts/west_commands/bindesc.py @@ -111,7 +111,7 @@ def do_add_parser(self, parser_adder): help=self.help, description=self.description) - subparsers = parser.add_subparsers(help='sub-command to run') + subparsers = parser.add_subparsers(help='sub-command to run', required=True) dump_parser = subparsers.add_parser('dump', help='Dump all binary descriptors in the image') dump_parser.add_argument('file', type=str, help='Executable file') From 79674debcbcab7f33f88fe093fb240b35a4a128f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 28 Sep 2023 14:20:15 +0200 Subject: [PATCH 1339/4498] samples: bindesc: doc: Describe sample using zephyr:code-sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the code sample using zephyr:code-sample directive to help with making it easier to find from API reference. Also cross-referenced main bindesc page from the sample. Signed-off-by: Benjamin Cabé --- samples/subsys/bindesc/hello_bindesc/README.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/samples/subsys/bindesc/hello_bindesc/README.rst b/samples/subsys/bindesc/hello_bindesc/README.rst index 5934b3f0ca6..f2cd9e2d16e 100644 --- a/samples/subsys/bindesc/hello_bindesc/README.rst +++ b/samples/subsys/bindesc/hello_bindesc/README.rst @@ -1,12 +1,13 @@ -.. _hello_bindesc-sample: +.. zephyr:code-sample:: hello-bindesc + :name: Binary descriptors "Hello World" + :relevant-api: bindesc_define -hello_bindesc Sample Application -################################ + Set and access binary descriptors for a basic Zephyr application. Overview ******** -A simple sample of binary descriptor definition and usage. +A simple sample of :ref:`binary descriptor ` definition and usage. Building and Running ******************** From 7fb10c82cc90aab470fc6c2b502d8ffa20962302 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 28 Sep 2023 15:54:47 +0200 Subject: [PATCH 1340/4498] tests: build_all: modem: Patch dependencies preventing build Some dependencies where missing from the build_all test for the modem_cellular.c driver. These have been added. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/build_all/modem/modem_cellular.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/drivers/build_all/modem/modem_cellular.conf b/tests/drivers/build_all/modem/modem_cellular.conf index e541af07e2d..3366fcf32d4 100644 --- a/tests/drivers/build_all/modem/modem_cellular.conf +++ b/tests/drivers/build_all/modem/modem_cellular.conf @@ -1,7 +1,10 @@ CONFIG_TEST=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_NETWORKING=y CONFIG_NET_L2_PPP=y CONFIG_MODEM=y +CONFIG_PM_DEVICE=y +CONFIG_MODEM_CELLULAR=y +CONFIG_UART_ASYNC_API=y +CONFIG_GPIO=y From ebd6681589711d1cc759ca3a90f5c54006a83b4d Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 28 Sep 2023 17:30:24 +0200 Subject: [PATCH 1341/4498] drivers: serial: serial_test: Patch irq_isr set to undefined This commit fixes an error where the irq_isr callback is set to an undefined variable instead of NULL. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/serial_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index 2ce4fb50f38..f18421b00e5 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -318,7 +318,7 @@ static int serial_vnd_callback_set(const struct device *dev, uart_callback_t cal } #if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_INTERRUPT_DRIVEN) - data->irq_isr = cb; + data->irq_isr = NULL; #endif if (callback == NULL && data->read_buf) { From d118d19293658eb64ca2a9a36a2d3c2bd36d0065 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 28 Sep 2023 15:57:49 +0200 Subject: [PATCH 1342/4498] drivers: serial: serial_test: Move ring buf dep to Kconfig This commit moves the dependency management between the RING_BUFFER and UART_ASYNC_API or UART_INTERRUPT_DRIVEN options to the Kconfig Kconfig.test. If either UART API options listed are selected, the RING_BUFFER option must be selected. This is now handled automatically by Kconfig instead of causing a build assert. The asserts where added with this PR #59880, and are removed in this commit. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/Kconfig.test | 1 + drivers/serial/serial_test.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/serial/Kconfig.test b/drivers/serial/Kconfig.test index 5e7353ba65a..e7f38edc591 100644 --- a/drivers/serial/Kconfig.test +++ b/drivers/serial/Kconfig.test @@ -8,3 +8,4 @@ config SERIAL_TEST select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select SERIAL_SUPPORT_ASYNC + select RING_BUFFER if (UART_INTERRUPT_DRIVEN || UART_ASYNC_API) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index f18421b00e5..b1661cdfeef 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -21,9 +21,6 @@ LOG_MODULE_REGISTER(mock_serial, CONFIG_LOG_DEFAULT_LEVEL); -BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN) || IS_ENABLED(CONFIG_RING_BUFFER)); -BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_ASYNC_API) || IS_ENABLED(CONFIG_RING_BUFFER)); - #define DT_DRV_COMPAT vnd_serial struct serial_vnd_data { #ifdef CONFIG_RING_BUFFER From b054d162f24f72c77ef14c6b52c6d40cceda801e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 28 Sep 2023 18:32:20 +0200 Subject: [PATCH 1343/4498] tests: drivers: modem: Specify targets for cellular Many boards do not build properly if UART_ASYNC_API is enabled, which is causing an overly large list of targets to exclude for the build_all.modem.modem_cellular.build test suite. This commit instead specifies 4 emulated boards, two of 32-bit, two of 64-bit instead. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/build_all/modem/testcase.yaml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 3614cb09655..8b42363b4ff 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -74,10 +74,9 @@ tests: - CONFIG_MODEM_IFACE_UART_ASYNC=y drivers.modem.modem_cellular.build: extra_args: CONF_FILE=modem_cellular.conf - platform_exclude: - - serpente - - particle_boron - - rak5010_nrf52840 - - litex_vexriscv - - ip_k66f + platform_allow: + - native_posix_64 + - native_posix + - qemu_x86 + - qemu_x86_64 min_ram: 36 From cc219c0132e31583ead7184c32d1af0283fb4637 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 28 Sep 2023 18:37:15 +0200 Subject: [PATCH 1344/4498] drivers: serial: serial_test.c: Patch 64-bit incompat The serial_test.c driver uses size_t to store read_size, which becomes a 64-bit type when built for 64-bit architectures. This is incompatible with the print format %d which is 32-bit. Updated to %zd Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/serial_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index b1661cdfeef..b1bb46228be 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -404,7 +404,7 @@ static int serial_vnd_rx_enable(const struct device *dev, uint8_t *read_buf, siz { struct serial_vnd_data *data = dev->data; - LOG_WRN("read_size %d", read_size); + LOG_WRN("read_size %zd", read_size); if (data == NULL) { return -ENOTSUP; From d47b1c05f31f8d56821f2ce3982c2f20299f9c02 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 27 Sep 2023 13:06:16 -0700 Subject: [PATCH 1345/4498] kernel: userspace: add k_object_is_valid() This adds a function k_object_is_valid() to check if a kernel object exists, of certain type, and has been initialized. This replaces the same (or very similar) code that has been copied from kernel into the network subsystem. Signed-off-by: Daniel Leung --- include/zephyr/sys/kobject.h | 22 ++++++++++++++++++ kernel/userspace_handler.c | 23 ++++++++++++++++--- subsys/net/ip/net_if.c | 8 +------ subsys/net/lib/sockets/sockets.c | 9 +------- .../mem_protect/mem_protect/src/kobject.c | 11 ++------- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/include/zephyr/sys/kobject.h b/include/zephyr/sys/kobject.h index 64db4d781c9..c423a7496ac 100644 --- a/include/zephyr/sys/kobject.h +++ b/include/zephyr/sys/kobject.h @@ -192,6 +192,19 @@ __syscall void k_object_release(const void *object); */ void k_object_access_all_grant(const void *object); +/** + * Check if a kernel object is of certain type and is valid. + * + * This checks if the kernel object exists, of certain type, + * and has been initialized. + * + * @param obj Address of the kernel object + * @param otype Object type (use K_OBJ_ANY for ignoring type checking) + * @return True if kernel object (@a obj) exists, of certain type, and + * has been initialized. False otherwise. + */ +bool k_object_is_valid(const void *obj, enum k_objects otype); + #else /* LCOV_EXCL_START */ #define K_THREAD_ACCESS_GRANT(thread, ...) @@ -236,6 +249,15 @@ static inline void k_object_access_all_grant(const void *object) { ARG_UNUSED(object); } + +static inline bool k_object_is_valid(const void *obj, enum k_objects otype) +{ + ARG_UNUSED(obj); + ARG_UNUSED(otype); + + return true; +} + /* LCOV_EXCL_STOP */ #endif /* !CONFIG_USERSPACE */ diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 80f9325b7de..5453bbcede4 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -7,8 +7,11 @@ #include #include #include +#include -static struct z_object *validate_any_object(const void *obj) +static struct z_object *validate_kernel_object(const void *obj, + enum k_objects otype, + enum _obj_init_check init) { struct z_object *ko; int ret; @@ -18,10 +21,10 @@ static struct z_object *validate_any_object(const void *obj) /* This can be any kernel object and it doesn't have to be * initialized */ - ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_ANY); + ret = z_object_validate(ko, otype, init); if (ret != 0) { #ifdef CONFIG_LOG - z_dump_object_error(ret, obj, ko, K_OBJ_ANY); + z_dump_object_error(ret, obj, ko, otype); #endif return NULL; } @@ -29,6 +32,20 @@ static struct z_object *validate_any_object(const void *obj) return ko; } +static ALWAYS_INLINE struct z_object *validate_any_object(const void *obj) +{ + return validate_kernel_object(obj, K_OBJ_ANY, _OBJ_INIT_ANY); +} + +bool k_object_is_valid(const void *obj, enum k_objects otype) +{ + struct z_object *ko; + + ko = validate_kernel_object(obj, otype, _OBJ_INIT_TRUE); + + return (ko != NULL); +} + /* Normally these would be included in userspace.c, but the way * syscall_dispatch.c declares weak handlers results in build errors if these * are located in userspace.c. Just put in a separate file. diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index f620dfeb4aa..bfa9c3cfdf7 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -152,19 +152,13 @@ struct net_if *z_impl_net_if_get_by_index(int index) struct net_if *z_vrfy_net_if_get_by_index(int index) { struct net_if *iface; - struct z_object *zo; - int ret; iface = net_if_get_by_index(index); if (!iface) { return NULL; } - zo = z_object_find(iface); - - ret = z_object_validate(zo, K_OBJ_NET_IF, _OBJ_INIT_TRUE); - if (ret != 0) { - z_dump_object_error(ret, iface, zo, K_OBJ_NET_IF); + if (!k_object_is_valid(iface, K_OBJ_NET_IF)) { return NULL; } diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 91cf6044c02..14d00581c97 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -78,14 +78,7 @@ static inline void *get_sock_vtable(int sock, #ifdef CONFIG_USERSPACE if (ctx != NULL && z_is_in_user_syscall()) { - struct z_object *zo; - int ret; - - zo = z_object_find(ctx); - ret = z_object_validate(zo, K_OBJ_NET_SOCKET, _OBJ_INIT_TRUE); - - if (ret != 0) { - z_dump_object_error(ret, ctx, zo, K_OBJ_NET_SOCKET); + if (!k_object_is_valid(ctx, K_OBJ_NET_SOCKET)) { /* Invalidate the context, the caller doesn't have * sufficient permission or there was some other * problem with the net socket object diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 122184160d4..589cbf52720 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -1034,18 +1034,11 @@ ZTEST(mem_protect_kobj, test_create_new_invalid_prio_thread_from_user) /* Function to init thread's stack objects */ static void thread_stack_init_objects(void *p1, void *p2, void *p3) { - int ret; - struct z_object *ko; - /* check that thread is initialized when running */ - ko = z_object_find(&child_thread); - ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_TRUE); - zassert_equal(ret, _OBJ_INIT_TRUE); + zassert_true(k_object_is_valid(&child_thread, K_OBJ_ANY)); /* check that stack is initialized when running */ - ko = z_object_find(child_stack); - ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_TRUE); - zassert_equal(ret, _OBJ_INIT_TRUE); + zassert_true(k_object_is_valid(child_stack, K_OBJ_ANY)); } /** From 6a3612666eb35223d2732d495e3f40e9e182535d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 28 Sep 2023 13:19:43 +0200 Subject: [PATCH 1346/4498] boards: mps2_an385: Exclude platform from networking tests The platform is known for having unstable system timer with networking enabled (see https://github.com/zephyrproject-rtos/zephyr/issues/48608) causing occasional failures of time-sensitive networking testsuties (TLS, now DHCPv6). Instead of excluding the platform on per-test basis, just exclude the platform from networking testing globally. Signed-off-by: Robert Lubos --- boards/arm/mps2_an385/mps2_an385.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arm/mps2_an385/mps2_an385.yaml b/boards/arm/mps2_an385/mps2_an385.yaml index 0236f2a137d..fec9dfc0fa8 100644 --- a/boards/arm/mps2_an385/mps2_an385.yaml +++ b/boards/arm/mps2_an385/mps2_an385.yaml @@ -13,4 +13,6 @@ supported: - gpio testing: default: true + ignore_tags: + - net vendor: arm From 815e7a1e3434dd3be8eba60f64dfaf512bd59fc9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 28 Sep 2023 13:45:39 +0200 Subject: [PATCH 1347/4498] samples: net: sockets: socketpair: Replace integration platform mps2_an385 was excluded from networking tests, therefore can no longer be used as an integration platform. Replace it with qemu_x86. Signed-off-by: Robert Lubos --- samples/net/sockets/socketpair/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/sockets/socketpair/sample.yaml b/samples/net/sockets/socketpair/sample.yaml index 2366392ed99..605668336d8 100644 --- a/samples/net/sockets/socketpair/sample.yaml +++ b/samples/net/sockets/socketpair/sample.yaml @@ -9,6 +9,6 @@ common: harness: net arch_exclude: posix integration_platforms: - - mps2_an385 + - qemu_x86 tests: sample.net.sockets.socketpair: {} From f5fbaa18a3e7d920d0ef4c5dc83e6932f0ee749d Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 21 Sep 2023 15:10:31 +0800 Subject: [PATCH 1348/4498] tests: build_all: plic: relocate and cleanup The test is for intc_plic only, so move them into the intc_plic folder. Also cleaned up the testcase.yaml a bit while I'm at it Signed-off-by: Yong Cong Sin --- .../boards/qemu_riscv64_trig.overlay | 3 --- .../{ => intc_plic}/CMakeLists.txt | 0 .../app.edge_interrupt.overlay} | 6 +++++- .../{ => intc_plic}/prj.conf | 0 .../{ => intc_plic}/src/main.c | 0 .../intc_plic/testcase.yaml | 17 ++++++++++++++++ .../interrupt_controller/testcase.yaml | 20 ------------------- 7 files changed, 22 insertions(+), 24 deletions(-) delete mode 100644 tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay rename tests/drivers/build_all/interrupt_controller/{ => intc_plic}/CMakeLists.txt (100%) rename tests/drivers/build_all/interrupt_controller/{boards/qemu_riscv32_trig.overlay => intc_plic/app.edge_interrupt.overlay} (58%) rename tests/drivers/build_all/interrupt_controller/{ => intc_plic}/prj.conf (100%) rename tests/drivers/build_all/interrupt_controller/{ => intc_plic}/src/main.c (100%) create mode 100644 tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml delete mode 100644 tests/drivers/build_all/interrupt_controller/testcase.yaml diff --git a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay b/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay deleted file mode 100644 index 5fe1ca0cf60..00000000000 --- a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv64_trig.overlay +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -#include "qemu_riscv32_trig.overlay" diff --git a/tests/drivers/build_all/interrupt_controller/CMakeLists.txt b/tests/drivers/build_all/interrupt_controller/intc_plic/CMakeLists.txt similarity index 100% rename from tests/drivers/build_all/interrupt_controller/CMakeLists.txt rename to tests/drivers/build_all/interrupt_controller/intc_plic/CMakeLists.txt diff --git a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay b/tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay similarity index 58% rename from tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay rename to tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay index 72b36e70091..e22118ecefe 100644 --- a/tests/drivers/build_all/interrupt_controller/boards/qemu_riscv32_trig.overlay +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay @@ -1,4 +1,8 @@ -// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ /{ soc { diff --git a/tests/drivers/build_all/interrupt_controller/prj.conf b/tests/drivers/build_all/interrupt_controller/intc_plic/prj.conf similarity index 100% rename from tests/drivers/build_all/interrupt_controller/prj.conf rename to tests/drivers/build_all/interrupt_controller/intc_plic/prj.conf diff --git a/tests/drivers/build_all/interrupt_controller/src/main.c b/tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c similarity index 100% rename from tests/drivers/build_all/interrupt_controller/src/main.c rename to tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml new file mode 100644 index 00000000000..ea549dc6f1c --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml @@ -0,0 +1,17 @@ +common: + build_only: true + filter: CONFIG_PLIC + platform_allow: + - qemu_riscv32 + - qemu_riscv64 + tags: + - drivers + - interrupt + - plic +tests: + drivers.interrupt_controller.intc_plic.build: {} + drivers.interrupt_controller.intc_plic.edge_interrupt.build: + extra_args: + DTC_OVERLAY_FILE="./app.edge_interrupt.overlay" + extra_configs: + - CONFIG_PLIC_SUPPORTS_EDGE_IRQ=y diff --git a/tests/drivers/build_all/interrupt_controller/testcase.yaml b/tests/drivers/build_all/interrupt_controller/testcase.yaml deleted file mode 100644 index 1ce419177c2..00000000000 --- a/tests/drivers/build_all/interrupt_controller/testcase.yaml +++ /dev/null @@ -1,20 +0,0 @@ -common: - build_only: true - tags: - - drivers - - interrupt -tests: - drivers.interrupt_controller.intc_plic.build: - platform_allow: - - qemu_riscv32 - - qemu_riscv64 - tags: plic - drivers.interrupt_controller.intc_plic.edge.build: - platform_allow: - - qemu_riscv32 - - qemu_riscv64 - extra_args: - DTC_OVERLAY_FILE="./boards/qemu_riscv32_trig.overlay;./boards/qemu_riscv64_trig.overlay" - extra_configs: - - CONFIG_PLIC_SUPPORTS_EDGE_IRQ=y - tags: plic From c7f85e6ee915c5dc165e9c2b90c98d0ec9ccca39 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 11 Sep 2023 17:22:40 +0200 Subject: [PATCH 1349/4498] native SOC: Add option to select the primary MCU Add a new kconfig option to select which is the preffered embedded MCU. Signed-off-by: Alberto Escolar Piedras --- soc/posix/inf_clock/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/soc/posix/inf_clock/Kconfig b/soc/posix/inf_clock/Kconfig index d66f09f1b92..9ebe7b73c37 100644 --- a/soc/posix/inf_clock/Kconfig +++ b/soc/posix/inf_clock/Kconfig @@ -10,3 +10,13 @@ config NATIVE_SIMULATOR_CPU_N Which native simulator embedded CPU number is this image targeting. This option is only applicable for targets which use the native simulator as their runner. + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int "Which CPU is the primary/preferred" + default 0 + depends on NATIVE_LIBRARY + help + On a multi MCU device, which MCU is the preferred one. + This MCU will for example have its tests command line parameters presented + without any prefix. Note that an MCU being primary does not imply it will be + the first one to boot. From dd29dffca4f9a0ca4638601a861311689c427b77 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 13 Sep 2023 15:44:17 +0200 Subject: [PATCH 1350/4498] native SOC: Add option to define how many MCUs a SOC has Add a new Kconfig option to define how many MCUs a SOC has Signed-off-by: Alberto Escolar Piedras --- boards/posix/common/natsim_config.cmake | 1 + soc/posix/inf_clock/Kconfig | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/boards/posix/common/natsim_config.cmake b/boards/posix/common/natsim_config.cmake index 30da901f535..205e0a21508 100644 --- a/boards/posix/common/natsim_config.cmake +++ b/boards/posix/common/natsim_config.cmake @@ -19,6 +19,7 @@ set(nsi_config_content "NSI_LINK_OPTIONS:=$,\ >" "NSI_EXTRA_LIBS:=$,\ >" "NSI_PATH:=${NSI_DIR}/" + "NSI_N_CPUS:=${CONFIG_NATIVE_SIMULATOR_NUMBER_MCUS}" ) string(REPLACE ";" "\n" nsi_config_content "${nsi_config_content}") diff --git a/soc/posix/inf_clock/Kconfig b/soc/posix/inf_clock/Kconfig index 9ebe7b73c37..10d74705874 100644 --- a/soc/posix/inf_clock/Kconfig +++ b/soc/posix/inf_clock/Kconfig @@ -11,6 +11,14 @@ config NATIVE_SIMULATOR_CPU_N This option is only applicable for targets which use the native simulator as their runner. +config NATIVE_SIMULATOR_NUMBER_MCUS + int "Total number of MCUs this target has" + range 1 16 + default 1 + depends on NATIVE_LIBRARY + help + How many AMP MCUs does this target have in total. + config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX int "Which CPU is the primary/preferred" default 0 From 9fea8f5f6b718e0b578cf96bae91e76ce18feb3b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 14 Sep 2023 17:36:24 +0200 Subject: [PATCH 1351/4498] native boards: AMP fix: localize the CONFIG_ symbols The Zephyr build leaves all kconfig options as absolute symbols in the image. This need to be localized, otherwise they will appear as duplicates with other Zephyr images. Signed-off-by: Alberto Escolar Piedras --- boards/posix/common/natsim_config.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/posix/common/natsim_config.cmake b/boards/posix/common/natsim_config.cmake index 205e0a21508..54b36be9d12 100644 --- a/boards/posix/common/natsim_config.cmake +++ b/boards/posix/common/natsim_config.cmake @@ -20,6 +20,7 @@ set(nsi_config_content "NSI_EXTRA_LIBS:=$,\ >" "NSI_PATH:=${NSI_DIR}/" "NSI_N_CPUS:=${CONFIG_NATIVE_SIMULATOR_NUMBER_MCUS}" + "NSI_LOCALIZE_OPTIONS:=--localize-symbol=CONFIG_*" ) string(REPLACE ";" "\n" nsi_config_content "${nsi_config_content}") From 536aee1e1a35075545432f725c5145e2f6ee16af Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 14 Sep 2023 15:46:42 +0200 Subject: [PATCH 1352/4498] native soc: Add option to pass extra images to native simulator build Add a new kconfig option to be able to pass extra images to the native simulator build. So one can, for ex., use one application build to produce one core image, and at the same time have it produce the final link with the native simulator runner and the other MCU images. Signed-off-by: Alberto Escolar Piedras --- boards/posix/common/natsim_config.cmake | 2 +- soc/posix/inf_clock/Kconfig | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/boards/posix/common/natsim_config.cmake b/boards/posix/common/natsim_config.cmake index 54b36be9d12..576e4b9b637 100644 --- a/boards/posix/common/natsim_config.cmake +++ b/boards/posix/common/natsim_config.cmake @@ -13,7 +13,7 @@ set(nsi_config_content "NSI_BUILD_PATH:=${zephyr_build_path}/NSI" "NSI_CC:=${CCACHE} ${CMAKE_C_COMPILER}" "NSI_OBJCOPY:=${CMAKE_OBJCOPY}" - "NSI_EMBEDDED_CPU_SW:=${zephyr_build_path}/${KERNEL_ELF_NAME}" + "NSI_EMBEDDED_CPU_SW:=${zephyr_build_path}/${KERNEL_ELF_NAME} ${CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS}" "NSI_EXE:=${zephyr_build_path}/${KERNEL_EXE_NAME}" "NSI_EXTRA_SRCS:=$,\ >" "NSI_LINK_OPTIONS:=$,\ >" diff --git a/soc/posix/inf_clock/Kconfig b/soc/posix/inf_clock/Kconfig index 10d74705874..3f42f7b23df 100644 --- a/soc/posix/inf_clock/Kconfig +++ b/soc/posix/inf_clock/Kconfig @@ -28,3 +28,12 @@ config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX This MCU will for example have its tests command line parameters presented without any prefix. Note that an MCU being primary does not imply it will be the first one to boot. + +config NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS + string "Other cores images to include" + depends on NATIVE_LIBRARY + help + This option can be used to provide the native simulator with other MCUs/Cores images which have + been produced by either other Zephyr builds or different OS builds. + So you can, for ex., use this application build produce one core image, and at the same time + have it produce the final link with the native simulator runner and the other MCU images. From 0a8500e79fb626bb75288032124a610c0628bdb8 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 28 Sep 2023 11:25:39 +0200 Subject: [PATCH 1353/4498] manifest: hal_nordic: Update to enable 15.4 on simulated nrf53 Take in a minor fix necessary to run 15.4 on the incoming simulated nrf53 targets. Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index c9398be0d5c..45bac43c958 100644 --- a/west.yml +++ b/west.yml @@ -189,7 +189,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 092eb78ed1b1551d8f480019b9c05d7371784578 + revision: d054a315eb888ba70e09e5f6decd4097b0276d1f path: modules/hal/nordic groups: - hal From d1ada164a41184756870d50aa1f487ca0fdf6ba7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 4 Sep 2023 13:04:03 +0200 Subject: [PATCH 1354/4498] nrf_hw_models: Update HW models to latest and align with them * In Zephyr: * The HW models now include N fake timers, and N bst timers. The embedded code needs to target the one for its CPU specifically. * Update the HW models module to f4595802d32d103718bf50b3d390b7a450895843 Including the following: * f459580 TEMP & ECB: Fix INTEN sideeffect prototypes * 50c2abe nrfx_common: Fix build error with clang * 5f0ae29 FICR: Add nrf53 variants * 82ee9bd DPPI: On initialization, set all registers to their reset value * 1472c34 NVMC & UICR: Readied for nrf53 * f425c08 NVMC & UICR: Refactor * 3a4cfc2 RADIO: Parametrize ED_RSSIOFFS * a20e9fc nrfx_get_irq_number() Add missing CCM peripheral for nrf5340net * c199715 DPPI: Bugfix * 93806ac Zephyr cmake: Align with nrf53 board rename * 51f26a3 VREQCTRL: Add register stub and definitions for nrf53 * 802e0cf RADIO: Switch to level interrupts, readied for nrf53 * 49bcea2 Templates: Added shortcut check & event signaling version for s * a880cd6 Template: Move static out of signal handler definition * 709f82b TEMP: Switched to level interrupts, readied for nrf53 * 6ef0069 AES_CCM: Switched to level interrupts, readied for nrf53 * eaa89da RNG: Use common templates * 75a6cb4 AAR: Switched to level interrupts, readied for nrf53 * fbf58f3 AES_ECB: Switched to level interrupts, readied for nrf53 * d084647 RNG: Bugfix in STOP subscription * 8007318 Templates: Added template code for the most common models logic * bab6a54 int ctrl: Added new API * daaaaa0 config: Fix nrf53 Net core EGU instance HAL mapping * 54570a0 nrf5340 RTC int mapping fix * 043af26 nrfx_common: Provide nrfx_get_irq_number() for 5340 cores * ecd7b9b SWI: Add SWI pseudo peripheral * a70c73b CLOCK: Add missing TASK sideeffecting prototypes, and fix typo * 56c7581 nrf5340: Split HAL files in net and app sets * 3892d3e Add API to get the MCUs/domains names * 8f485bc RADIO: Prevent clang build warning * 5aac1c2 hal: Build weak version of the HAL for the 53 series also * f18422d standalone nrfx_config: Provide needed definitions for nrf53 * 4015d5a nrfx_glue_bsim: Provide 2 trivial definitions for standalone bu * 4af80d5 cmsis stubs: Provide trivial macro to replace ISB * b6c2769 cmsis replacements: Fix for other Zephyr bsim targets * 8316930 zephyr CMakefile: Set HAL version based on Kconfig * 4404106 RNG: Rename functions to match new naming convention * a3dbb38 RTC: Rename functions to match new naming convention * 886dc73 CLOCK: Rename functions to match new naming convention * bcb2b99 EGU: Rename functions to match new naming convention * 50af67e TIMER: Rename functions to match new naming convention * 8120224 CLOCK/POWER/RESET: Add DPPI connections, generalize to N instan * 450337c RTC: Add DPPI connection, nrf53 support and new functionality * 2918ce6 DPPI common subscription: Minor API change * ec1c2a7 TIMER: Add DPPI connection, nrf53 support and functionality * e6f9860 EGU: Add DPPI connection, nrf53 support and generalize * c8a4368 bst_ticker: Generalize to N instances * 093deee fake timer: Generalize to N instances * 302da8d DPPI: Typo fix Signed-off-by: Alberto Escolar Piedras --- .../posix/nrf52_bsim/common/bstests_entry.c | 25 +++++++++++++++++++ boards/posix/nrf52_bsim/cpu_wait.c | 4 +-- boards/posix/nrf52_bsim/nsi_if.c | 7 ++++-- west.yml | 2 +- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/boards/posix/nrf52_bsim/common/bstests_entry.c b/boards/posix/nrf52_bsim/common/bstests_entry.c index 1f9afda15a6..5f2dcdd1fa8 100644 --- a/boards/posix/nrf52_bsim/common/bstests_entry.c +++ b/boards/posix/nrf52_bsim/common/bstests_entry.c @@ -244,3 +244,28 @@ uint8_t bst_delete(void) return bst_result; } + +#if defined(CONFIG_NATIVE_SIMULATOR_CPU_N) +#include "bstest_ticker.h" + +void bst_ticker_set_period(bs_time_t tick_period) +{ + bst_ticker_amp_set_period(CONFIG_NATIVE_SIMULATOR_CPU_N, tick_period); +} + +void bst_ticker_set_next_tick_absolute(bs_time_t time) +{ + bst_ticker_amp_set_next_tick_absolutelute(CONFIG_NATIVE_SIMULATOR_CPU_N, time); +} + +void bst_ticker_set_next_tick_delta(bs_time_t time) +{ + bst_ticker_amp_set_next_tick_delta(CONFIG_NATIVE_SIMULATOR_CPU_N, time); +} + +void bst_awake_cpu_asap(void) +{ + bst_ticker_amp_awake_cpu_asap(CONFIG_NATIVE_SIMULATOR_CPU_N); +} + +#endif /* defined(CONFIG_NATIVE_SIMULATOR_CPU_N) */ diff --git a/boards/posix/nrf52_bsim/cpu_wait.c b/boards/posix/nrf52_bsim/cpu_wait.c index dd443cfb362..a8695e64ed5 100644 --- a/boards/posix/nrf52_bsim/cpu_wait.c +++ b/boards/posix/nrf52_bsim/cpu_wait.c @@ -32,7 +32,7 @@ void arch_busy_wait(uint32_t usec_to_wait) * There may be wakes due to other interrupts or nested calls to * k_busy_wait in interrupt handlers */ - fake_timer_wake_in_time(time_end); + nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_CPU_N, time_end); posix_halt_cpu(); } } @@ -58,7 +58,7 @@ void posix_cpu_hold(uint32_t usec_to_waste) * cpu_hold in interrupt handlers */ time_start = nsi_hws_get_time(); - fake_timer_wake_in_time(time_start + to_wait); + nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_CPU_N, time_start + to_wait); posix_change_cpu_state_and_wait(true); to_wait -= nsi_hws_get_time() - time_start; diff --git a/boards/posix/nrf52_bsim/nsi_if.c b/boards/posix/nrf52_bsim/nsi_if.c index bb916c97466..4c2a411366a 100644 --- a/boards/posix/nrf52_bsim/nsi_if.c +++ b/boards/posix/nrf52_bsim/nsi_if.c @@ -12,6 +12,7 @@ #include "bstests.h" #include "bs_tracing.h" #include "phy_sync_ctrl.h" +#include "nsi_hw_scheduler.h" NATIVE_SIMULATOR_IF void nsif_cpu0_pre_cmdline_hooks(void) { @@ -89,9 +90,11 @@ NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised(void) posix_interrupt_raised(); } -NATIVE_SIMULATOR_IF void nsif_cpu0_bst_tick(uint64_t time) +NATIVE_SIMULATOR_IF int nsif_cpu0_test_hook(void *p) { - bst_tick(time); + (void) p; + bst_tick(nsi_hws_get_time()); + return 0; } NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised_from_sw(void) diff --git a/west.yml b/west.yml index 45bac43c958..4f4f04482e8 100644 --- a/west.yml +++ b/west.yml @@ -303,7 +303,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 57b61a9a2da75c860f15ca79522b24d57992df2c + revision: f4595802d32d103718bf50b3d390b7a450895843 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 From f39944933d8a3aa8761711e788cabfc07117377d Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 28 Sep 2023 15:56:08 +0200 Subject: [PATCH 1355/4498] dts: arm: nordic: Add support for ieee802154 in the nRF52820 radio The nRF52820 radio peripheral supports IEEE 802.15.4, add the required property and node to reflect this. See https://infocenter.nordicsemi.com/topic/ps_nrf52820/radio.html?cp=5_3_0_5_11 Signed-off-by: Carles Cufi --- dts/arm/nordic/nrf52820.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index 6d2f5eb02fe..c3d05fc6ec1 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -88,9 +88,15 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; dfe-supported; + ieee802154-supported; ble-2mbps-supported; ble-coded-phy-supported; tx-high-power-supported; + + ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; }; uart0: uart@40002000 { From 4c8866243d34c9f4ec5fd4c8d514141405fb3922 Mon Sep 17 00:00:00 2001 From: Armin Brauns Date: Thu, 28 Sep 2023 14:58:56 +0000 Subject: [PATCH 1356/4498] bluetooth: disable BT_ATT_ENFORCE_FLOW for BlueNRG devices The firmware on these devices seems to have a bug that can cause reordering of received packets. This can lead to new GATT requests being received before the acknowledgement of the previous GATT response, accompanied by log messages like the following: bt_att: bt_att_recv: Ignoring unexpected request Signed-off-by: Armin Brauns --- subsys/bluetooth/host/Kconfig.gatt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/Kconfig.gatt b/subsys/bluetooth/host/Kconfig.gatt index e405a56d147..9209368f943 100644 --- a/subsys/bluetooth/host/Kconfig.gatt +++ b/subsys/bluetooth/host/Kconfig.gatt @@ -7,7 +7,7 @@ menu "ATT and GATT Options" config BT_ATT_ENFORCE_FLOW bool "Enforce strict flow control semantics for incoming PDUs" - default y if !(BOARD_QEMU_CORTEX_M3 || BOARD_QEMU_X86 || ARCH_POSIX) + default y if !(BOARD_QEMU_CORTEX_M3 || BOARD_QEMU_X86 || ARCH_POSIX || BT_SPI_BLUENRG) help Enforce flow control rules on incoming PDUs, preventing a peer from sending new requests until a previous one has been responded From f19b8f2c1d073485a67b3f528c9888bc0c54589f Mon Sep 17 00:00:00 2001 From: Benjamin Perseghetti Date: Thu, 28 Sep 2023 17:43:01 -0400 Subject: [PATCH 1357/4498] soc: nxp_rt11xx: fix missing unique PWM name. Adds missing PWM unique device name. Signed-off-by: Benjamin Perseghetti --- dts/arm/nxp/nxp_rt11xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index ee61909255f..d3448a029b9 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -619,7 +619,7 @@ reg = <0x40194000 0x4000>; interrupts = <186 0>; - flexpwm3_pwm0: pwm0 { + flexpwm3_pwm0: flexpwm3_pwm0 { compatible = "nxp,imx-pwm"; index = <0>; interrupts = <182 0>; From 1c67228428732832e23d468b83eeddf772ad4fb4 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Tue, 26 Sep 2023 16:27:30 +0200 Subject: [PATCH 1358/4498] dts: stm32: stm32u5: Add sdmmc1 and sdmmc2 configuration Provide the soc configuration for sdmmc1 and sdmmc2 controllers. This includes registers address, clocks, resets and interrupt line details. Signed-off-by: Armando Visconti --- dts/arm/st/u5/stm32u5.dtsi | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 95bb4173c65..b7abd1dd17a 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -728,6 +728,35 @@ status = "disabled"; }; + /* + * The SDMMC domain clock can be chosen between ICLK and PLL1P. + * But ICLK is itself chosen among HSI48 (the default), PLL2Q, + * PLL1Q and MSIK. + * + * Currently, configuring ICLK is unsupported. When support for + * ICLK comes in the future, the clock source for sdmmc1 and + * sdmmc2 will have to be replaced with STM32_SRC_ICLK. + */ + sdmmc1: sdmmc@420c8000 { + compatible = "st,stm32-sdmmc"; + reg = <0x420c8000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x08000000>, + <&rcc STM32_SRC_HSI48 SDMMC_SEL(0)>; + resets = <&rctl STM32_RESET(AHB2L, 27U)>; + interrupts = <78 0>; + status = "disabled"; + }; + + sdmmc2: sdmmc@420c8c00 { + compatible = "st,stm32-sdmmc"; + reg = <0x420c8c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x10000000>, + <&rcc STM32_SRC_HSI48 SDMMC_SEL(0)>; + resets = <&rctl STM32_RESET(AHB2L, 28U)>; + interrupts = <79 0>; + status = "disabled"; + }; + dac1: dac@46021800 { compatible = "st,stm32-dac"; reg = <0x46021800 0x400>; From 8ab3fbf5709465b64eca8776fa73f67c1d18b63a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 28 Sep 2023 11:05:44 +0200 Subject: [PATCH 1359/4498] Bluetooth: Audio: Split bt_audio_codec_meta_get to cfg and cap Split the bt_audio_codec_meta_get functions to cfg and cap variants. This provides a more explicit API where users do not need to dereference their cfg/cap structs in order to use this functions. Furthermore this will also make the get functions more similar to the upcoming set functions, where the set functions will require the use of the cfg and cap structs. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 255 ++++++++++++++----- subsys/bluetooth/audio/codec.c | 329 ++++++++++++++++++++++--- tests/bluetooth/audio/codec/prj.conf | 2 + tests/bluetooth/audio/codec/src/main.c | 280 ++++++++++++++++----- 4 files changed, 704 insertions(+), 162 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index e09d7a18cf2..9ba245c7c9b 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -709,193 +709,168 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t *data, size_t data_len); -/** @} */ /* End of bt_audio_codec_cfg */ - -/** - * @brief Audio codec Config APIs - * @defgroup bt_audio_codec_meta Metadata parsing APIs - * - * Functions to parse LTV formatted metadata. - * - * @{ - */ - /** @brief Lookup a specific metadata value based on type * - * This works for metadata from both @ref bt_audio_codec_cfg meta and @ref bt_audio_codec_cap meta. - * * - * @param[in] meta The metadata to search in. - * @param[in] meta_len The length of @p meta. - * @param[in] type The type id to look for - * @param[out] data Pointer to the data-pointer to update when item is found + * + * @param[in] codec_cfg The codec data to search in. + * @param[in] type The type id to look for + * @param[out] data Pointer to the data-pointer to update when item is found * * @retval Length of found @p data (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, - const uint8_t **data); +int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t **data); /** @brief Extract preferred contexts * * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval The preferred context type if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len); +int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract stream contexts * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval The stream context type if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len); +int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract program info * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. * - * @param[in] meta The metadata to get the data from in. - * @param[in] meta_len The length of @p meta. + * @param[in] codec_cfg The codec data to search in. * @param[out] program_info Pointer to the UTF-8 formatted program info. * * @retval The length of the @p program_info (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, - const uint8_t **program_info); +int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **program_info); /** @brief Extract stream language * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval The stream language if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len); +int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract CCID list * * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. * - * @param[in] meta The metadata to get the data from in. - * @param[in] meta_len The length of @p meta. + * @param[in] codec_cfg The codec data to search in. * @param[out] ccid_list Pointer to the array containing 8-bit CCIDs. * * @retval The length of the @p ccid_list (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, - const uint8_t **ccid_list); +int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **ccid_list); /** @brief Extract parental rating * * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval The parental rating if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len); +int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract program info URI * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. * - * @param[in] meta The metadata to get the data from in. - * @param[in] meta_len The length of @p meta. + * @param[in] codec_cfg The codec data to search in. * @param[out] program_info_uri Pointer to the UTF-8 formatted program info URI. * * @retval The length of the @p ccid_list (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, - const uint8_t **program_info_uri); +int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **program_info_uri); /** @brief Extract audio active state * * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval The preferred context type if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len); +int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract broadcast audio immediate rendering flag * * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. * - * @param meta The metadata to get the data from in. - * @param meta_len The length of @p meta. + * @param codec_cfg The codec data to search in. * * @retval 0 if the flag was found * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not the flag was not found */ -int bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag(const uint8_t meta[], - size_t meta_len); +int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( + const struct bt_audio_codec_cfg *codec_cfg); /** @brief Extract extended metadata * * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. * - * @param[in] meta The metadata to get the data from in. - * @param[in] meta_len The length of @p meta. + * @param[in] codec_cfg The codec data to search in. * @param[out] extended_meta Pointer to the extended metadata. * * @retval The length of the @p ccid_list (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, - const uint8_t **extended_meta); +int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **extended_meta); /** @brief Extract vendor specific metadata * * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. * - * @param[in] meta The metadata to get the data from in. - * @param[in] meta_len The length of @p meta. + * @param[in] codec_cfg The codec data to search in. * @param[out] vendor_meta Pointer to the vendor specific metadata. * * @retval The length of the @p ccid_list (may be 0) * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found */ -int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, - const uint8_t **vendor_meta); - -/** @} */ /* End of bt_audio_codec_meta */ +int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **vendor_meta); +/** @} */ /* End of bt_audio_codec_cfg */ /** * @brief Audio codec capabilities APIs @@ -982,6 +957,166 @@ int bt_audio_codec_cap_get_octets_per_frame( */ int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap); +/** @brief Lookup a specific metadata value based on type + * + * @param[in] codec_cap The codec data to search in. + * @param[in] type The type id to look for + * @param[out] data Pointer to the data-pointer to update when item is found + * + * @retval Length of found @p data (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, + const uint8_t **data); + +/** @brief Extract preferred contexts + * + * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval The preferred context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract stream contexts + * + * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval The stream context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract program info + * + * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. + * + * @param[in] codec_cap The codec data to search in. + * @param[out] program_info Pointer to the UTF-8 formatted program info. + * + * @retval The length of the @p program_info (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **program_info); + +/** @brief Extract stream language + * + * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval The stream language if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract CCID list + * + * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. + * + * @param[in] codec_cap The codec data to search in. + * @param[out] ccid_list Pointer to the array containing 8-bit CCIDs. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **ccid_list); + +/** @brief Extract parental rating + * + * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval The parental rating if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract program info URI + * + * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. + * + * @param[in] codec_cap The codec data to search in. + * @param[out] program_info_uri Pointer to the UTF-8 formatted program info URI. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **program_info_uri); + +/** @brief Extract audio active state + * + * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval The preferred context type if positive or 0 + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size + */ +int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract broadcast audio immediate rendering flag + * + * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. + * + * @param codec_cap The codec data to search in. + * + * @retval 0 if the flag was found + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not the flag was not found + */ +int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( + const struct bt_audio_codec_cap *codec_cap); + +/** @brief Extract extended metadata + * + * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. + * + * @param[in] codec_cap The codec data to search in. + * @param[out] extended_meta Pointer to the extended metadata. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **extended_meta); + +/** @brief Extract vendor specific metadata + * + * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. + * + * @param[in] codec_cap The codec data to search in. + * @param[out] vendor_meta Pointer to the vendor specific metadata. + * + * @retval The length of the @p ccid_list (may be 0) + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + */ +int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **vendor_meta); /** @} */ /* End of bt_audio_codec_cap */ #ifdef __cplusplus diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index bdcf8978bd4..c9848c2ebf3 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -409,8 +409,8 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 -int bt_audio_codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, - const uint8_t **data) +static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, + const uint8_t **data) { struct search_type_param param = { .type = type, @@ -445,7 +445,7 @@ int bt_audio_codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t t return param.data_len; } -int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; int ret; @@ -455,8 +455,7 @@ int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, &data); if (data == NULL) { return -ENODATA; } @@ -468,7 +467,7 @@ int bt_audio_codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) return sys_get_le16(data); } -int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; int ret; @@ -478,8 +477,7 @@ int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, &data); if (data == NULL) { return -ENODATA; } @@ -491,8 +489,8 @@ int bt_audio_codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len return sys_get_le16(data); } -int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, - const uint8_t **program_info) +static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info) { const uint8_t *data; int ret; @@ -507,8 +505,7 @@ int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, &data); if (data == NULL) { return -ENODATA; } @@ -518,7 +515,7 @@ int bt_audio_codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, return ret; } -int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) { const uint8_t *data; int ret; @@ -528,8 +525,7 @@ int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_LANG, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_LANG, &data); if (data == NULL) { return -ENODATA; } @@ -541,8 +537,8 @@ int bt_audio_codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) return sys_get_le24(data); } -int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, - const uint8_t **ccid_list) +static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, + const uint8_t **ccid_list) { const uint8_t *data; int ret; @@ -557,7 +553,7 @@ int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_CCID_LIST, &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_CCID_LIST, &data); if (data == NULL) { return -ENODATA; } @@ -567,7 +563,7 @@ int bt_audio_codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, return ret; } -int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) { const uint8_t *data; int ret; @@ -577,8 +573,7 @@ int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_le return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, &data); if (data == NULL) { return -ENODATA; } @@ -590,8 +585,8 @@ int bt_audio_codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_le return data[0]; } -int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, - const uint8_t **program_info_uri) +static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, + const uint8_t **program_info_uri) { const uint8_t *data; int ret; @@ -606,8 +601,7 @@ int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_l return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, &data); if (data == NULL) { return -ENODATA; } @@ -617,7 +611,7 @@ int bt_audio_codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_l return ret; } -int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len) { const uint8_t *data; int ret; @@ -627,8 +621,7 @@ int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, - &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, &data); if (data == NULL) { return -ENODATA; } @@ -640,8 +633,7 @@ int bt_audio_codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta return data[0]; } -int bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag(const uint8_t meta[], - size_t meta_len) +static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -650,12 +642,12 @@ int bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag(const uint8 return -EINVAL; } - return bt_audio_codec_meta_get_val(meta, meta_len, - BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, &data); + return codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, + &data); } -int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, - const uint8_t **extended_meta) +static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len, + const uint8_t **extended_meta) { const uint8_t *data; int ret; @@ -670,7 +662,7 @@ int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_EXTENDED, &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_EXTENDED, &data); if (data == NULL) { return -ENODATA; } @@ -680,8 +672,7 @@ int bt_audio_codec_meta_get_extended(const uint8_t meta[], size_t meta_len, return ret; } -int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, - const uint8_t **vendor_meta) +static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta) { const uint8_t *data; int ret; @@ -696,7 +687,7 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, return -EINVAL; } - ret = bt_audio_codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_VENDOR, &data); + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_VENDOR, &data); if (data == NULL) { return -ENODATA; } @@ -705,6 +696,268 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, return ret; } + +#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 +int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t **data) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_val(codec_cfg->meta, codec_cfg->meta_len, type, data); +} + +int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_pref_context(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_stream_context(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **program_info) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_program_info(codec_cfg->meta, codec_cfg->meta_len, program_info); +} + +int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_stream_lang(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **ccid_list) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_ccid_list(codec_cfg->meta, codec_cfg->meta_len, ccid_list); +} + +int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_parental_rating(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **program_info_uri) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_program_info_uri(codec_cfg->meta, codec_cfg->meta_len, + program_info_uri); +} + +int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_audio_active_state(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( + const struct bt_audio_codec_cfg *codec_cfg) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + LOG_ERR("codec_cfg->meta_len %zu", codec_cfg->meta_len); + + return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len); +} + +int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **extended_meta) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_extended(codec_cfg->meta, codec_cfg->meta_len, extended_meta); +} + +int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **vendor_meta) +{ + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + return codec_meta_get_vendor(codec_cfg->meta, codec_cfg->meta_len, vendor_meta); +} +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ + +#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 +int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, + const uint8_t **data) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_val(codec_cap->meta, codec_cap->meta_len, type, data); +} + +int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_pref_context(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_stream_context(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **program_info) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_program_info(codec_cap->meta, codec_cap->meta_len, program_info); +} + +int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_stream_lang(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **ccid_list) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_ccid_list(codec_cap->meta, codec_cap->meta_len, ccid_list); +} + +int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_parental_rating(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **program_info_uri) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_program_info_uri(codec_cap->meta, codec_cap->meta_len, + program_info_uri); +} + +int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_audio_active_state(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( + const struct bt_audio_codec_cap *codec_cap) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len); +} + +int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **extended_meta) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_extended(codec_cap->meta, codec_cap->meta_len, extended_meta); +} + +int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **vendor_meta) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return codec_meta_get_vendor(codec_cap->meta, codec_cap->meta_len, vendor_meta); +} +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */ #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ */ diff --git a/tests/bluetooth/audio/codec/prj.conf b/tests/bluetooth/audio/codec/prj.conf index 5ac78f09abc..308958c0fe3 100644 --- a/tests/bluetooth/audio/codec/prj.conf +++ b/tests/bluetooth/audio/codec/prj.conf @@ -8,6 +8,8 @@ CONFIG_BT_BAP_UNICAST_SERVER=y CONFIG_LOG=y CONFIG_BT_AUDIO_LOG_LEVEL_DBG=y CONFIG_BT_AUDIO_CODEC_LOG_LEVEL_DBG=y +CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=15 +CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE=15 CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 28633716355..00226cd17f5 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -120,148 +120,151 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_blocks_per_sdu) zassert_equal(ret, 1u, "unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_pref_context) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_pref_context) { - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, - BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | - BT_AUDIO_CONTEXT_TYPE_MEDIA)), - }; + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); int ret; - ret = bt_audio_codec_meta_get_pref_context(metadata, ARRAY_SIZE(metadata)); + ret = bt_audio_codec_cfg_meta_get_pref_context(&codec_cfg); zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_stream_context) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_context) { - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, - BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | - BT_AUDIO_CONTEXT_TYPE_MEDIA)), - }; + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); int ret; - ret = bt_audio_codec_meta_get_stream_context(metadata, ARRAY_SIZE(metadata)); - zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + ret = bt_audio_codec_cfg_meta_get_stream_context(&codec_cfg); + zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_program_info) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info) { const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'I', 'n', 'f', 'o'}; - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, - 'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'I', 'n', 'f', 'o'), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + 'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', + 'I', 'n', 'f', 'o')}); const uint8_t *program_data; int ret; - ret = bt_audio_codec_meta_get_program_info(metadata, ARRAY_SIZE(metadata), &program_data); + ret = bt_audio_codec_cfg_meta_get_program_info(&codec_cfg, &program_data); zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_stream_lang) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_lang) { const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g'), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); int ret; - ret = bt_audio_codec_meta_get_stream_lang(metadata, ARRAY_SIZE(metadata)); + ret = bt_audio_codec_cfg_meta_get_stream_lang(&codec_cfg); zassert_equal(ret, expected_data, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_ccid_list) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); const uint8_t *ccid_list; int ret; - ret = bt_audio_codec_meta_get_ccid_list(metadata, ARRAY_SIZE(metadata), &ccid_list); + ret = bt_audio_codec_cfg_meta_get_ccid_list(&codec_cfg, &ccid_list); zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_parental_rating) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_parental_rating) { - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, - BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE), - }; + const struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); int ret; - ret = bt_audio_codec_meta_get_parental_rating(metadata, ARRAY_SIZE(metadata)); + ret = bt_audio_codec_cfg_meta_get_parental_rating(&codec_cfg); zassert_equal(ret, 0x07, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_program_info_uri) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info_uri) { const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, - 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm')}); const uint8_t *program_info_uri; int ret; - ret = bt_audio_codec_meta_get_program_info_uri(metadata, ARRAY_SIZE(metadata), - &program_info_uri); + ret = bt_audio_codec_cfg_meta_get_program_info_uri(&codec_cfg, &program_info_uri); zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_audio_active_state) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_audio_active_state) { - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, - BT_AUDIO_ACTIVE_STATE_ENABLED), - }; + const struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); int ret; - ret = bt_audio_codec_meta_get_audio_active_state(metadata, ARRAY_SIZE(metadata)); + ret = bt_audio_codec_cfg_meta_get_audio_active_state(&codec_cfg); zassert_equal(ret, 0x01, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag) { - const uint8_t metadata[] = {0x01, BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE}; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE)}); int ret; - ret = bt_audio_codec_meta_get_broadcast_audio_immediate_rendering_flag( - metadata, ARRAY_SIZE(metadata)); + ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(&codec_cfg); zassert_equal(ret, 0, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_extended) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); const uint8_t *extended_meta; int ret; - ret = bt_audio_codec_meta_get_extended(metadata, ARRAY_SIZE(metadata), &extended_meta); + ret = bt_audio_codec_cfg_meta_get_extended(&codec_cfg, &extended_meta); zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_meta_get_vendor) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_vendor) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; - const uint8_t metadata[] = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03), - }; + const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); const uint8_t *vendor_meta; int ret; - ret = bt_audio_codec_meta_get_vendor(metadata, ARRAY_SIZE(metadata), &vendor_meta); + ret = bt_audio_codec_cfg_meta_get_vendor(&codec_cfg, &vendor_meta); zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } @@ -339,3 +342,152 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_max_codec_frames_per_s ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(&codec_cap); zassert_equal(ret, 2, "Unexpected return value %d", ret); } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_pref_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_pref_context(&codec_cap); + zassert_equal(ret, 0x0005, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_context(&codec_cap); + zassert_equal(ret, 0x0005, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', + 'I', 'n', 'f', 'o'}; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + 'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', + 'I', 'n', 'f', 'o')}); + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info(&codec_cap, &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_lang(&codec_cap); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_cap_meta_get_ccid_list(&codec_cap, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_parental_rating) +{ + const struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_parental_rating(&codec_cap); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm')}); + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info_uri(&codec_cap, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_audio_active_state) +{ + const struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_audio_active_state(&codec_cap); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag) +{ + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_extended(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *vendor_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_vendor(&codec_cap, &vendor_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); +} From 8cd64fd791d767fae2f32c9fd45c603aa649da4a Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 27 Sep 2023 14:09:42 +0800 Subject: [PATCH 1360/4498] drivers: gpio: sifive: use Kconfig to convert between levels The number of IRQ first level bits is not necessarily 8 bits now, so use `CONFIG_1ST_LEVEL_INTERRUPT_BITS` instead of hardcoded value. Signed-off-by: Yong Cong Sin --- drivers/gpio/gpio_sifive.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_sifive.c b/drivers/gpio/gpio_sifive.c index a3b5292fe14..440ad3f78ab 100644 --- a/drivers/gpio/gpio_sifive.c +++ b/drivers/gpio/gpio_sifive.c @@ -77,7 +77,7 @@ static inline unsigned int gpio_sifive_pin_irq(unsigned int base_irq, int pin) if (level == 1) { pin_irq = base_irq + pin; } else if (level == 2) { - pin_irq = base_irq + (pin << 8); + pin_irq = base_irq + (pin << CONFIG_1ST_LEVEL_INTERRUPT_BITS); } return pin_irq; @@ -104,7 +104,8 @@ static void gpio_sifive_irq_handler(const struct device *dev) const struct gpio_sifive_config *cfg = DEV_GPIO_CFG(dev); /* Calculate pin and mask from base level 2 line */ - uint8_t pin = 1 + (riscv_plic_get_irq() - (uint8_t)(cfg->gpio_irq_base >> 8)); + uint8_t pin = 1 + (riscv_plic_get_irq() - + (uint8_t)(cfg->gpio_irq_base >> CONFIG_1ST_LEVEL_INTERRUPT_BITS)); /* This peripheral tracks each condition separately: a * transition from low to high will mark the pending bit for From 5656c23243dc4902ede13aa66000b42ba0b2862e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 27 Sep 2023 15:18:28 +0200 Subject: [PATCH 1361/4498] Bluetooth: Audio: Add codec_cfg_set_octets_per_frame Add the bt_audio_codec_cfg_set_octets_per_frame function to set or add the octets per frame field in the codec configuration. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 13 +++++++++++++ subsys/bluetooth/audio/codec.c | 12 ++++++++++++ tests/bluetooth/audio/codec/src/main.c | 16 ++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 9ba245c7c9b..00b2264a81e 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -660,6 +660,19 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * */ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the octets per codec frame of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param octets_per_frame The octets per codec frame to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg, + uint16_t octets_per_frame); + /** @brief Extract number of audio frame blockss in each SDU from BT codec config * * The overall SDU size will be octets_per_frame * frame_blocks_per_sdu * number-of-channels. diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index c9848c2ebf3..1fc704eeb95 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -377,6 +377,18 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod return sys_get_le16(data); } +int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg, + uint16_t octets_per_frame) +{ + uint16_t octets_per_frame_le16; + + octets_per_frame_le16 = sys_cpu_to_le16(octets_per_frame); + + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, + (uint8_t *)&octets_per_frame_le16, + sizeof(octets_per_frame_le16)); +} + int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default) { diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 00226cd17f5..8950a00186a 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -109,6 +109,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_octets_per_frame) zassert_equal(ret, 80u, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_octets_per_frame) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_32_2_2( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + int ret; + + ret = bt_audio_codec_cfg_get_octets_per_frame(&preset.codec_cfg); + zassert_equal(ret, 80, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_octets_per_frame(&preset.codec_cfg, 120); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_octets_per_frame(&preset.codec_cfg); + zassert_equal(ret, 120, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_blocks_per_sdu) { const struct bt_bap_lc3_preset preset = From e8e5d5554cd705d7e549aaeba646b7da8fb926cc Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Mon, 25 Sep 2023 16:51:30 +0200 Subject: [PATCH 1362/4498] drivers: adc: stm32: reset acquisition time between reads For all STM32 ADC that use common sampling times, there is a check made to ensure that all channels of a sequence use the same sampling time. The value was not reset between reads, resulting in error if two consecutive sequences used different values. This commit adds a reset of this value once read is done. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index ec73d80e239..b88c7870ffa 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -990,6 +990,11 @@ static void adc_context_on_complete(struct adc_context *ctx, int status) ARG_UNUSED(status); adc_stm32_disable(adc); + + /* Reset acquisition time used for the sequence */ + data->acq_time_index = -1; + + /* Reset internal channels */ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), LL_ADC_PATH_INTERNAL_NONE); @@ -1119,6 +1124,7 @@ static int adc_stm32_channel_setup(const struct device *dev, * identical acquisition time. */ if (acq_time_index != data->acq_time_index) { + LOG_ERR("Multiple sampling times not supported"); return -EINVAL; } } From ce42ffcce0c262c57aafa8b166e1d3fe43e04a31 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Mon, 25 Sep 2023 19:56:28 -0500 Subject: [PATCH 1363/4498] dts: boards: Use `ethernet-phy` devicetree node name consistently Some Ethernet PHYs used the devicetree node name `phy`, while others used `ethernet-phy`. Be consistent and use `ethernet-phy` throughout. Signed-off-by: Maureen Helm --- boards/arm/atsame54_xpro/atsame54_xpro.dts | 2 +- boards/arm/sam4e_xpro/sam4e_xpro.dts | 2 +- boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi | 2 +- boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi | 2 +- .../arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts | 2 +- boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts | 2 +- drivers/ethernet/eth_adin2111.c | 2 +- dts/arm64/fvp/fvp-aemv8r.dtsi | 2 +- dts/bindings/ethernet/adi,adin1110.yaml | 2 +- dts/bindings/ethernet/adi,adin2111.yaml | 4 ++-- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.dts b/boards/arm/atsame54_xpro/atsame54_xpro.dts index 135a53a6c09..0d0b6960ad1 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.dts +++ b/boards/arm/atsame54_xpro/atsame54_xpro.dts @@ -132,7 +132,7 @@ zephyr_udc0: &usb0 { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "okay"; address = <0>; diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.dts b/boards/arm/sam4e_xpro/sam4e_xpro.dts index eb4ff5fcecc..eba17bc297b 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.dts +++ b/boards/arm/sam4e_xpro/sam4e_xpro.dts @@ -198,7 +198,7 @@ pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "okay"; address = <0>; diff --git a/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi b/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi index 1b50d6494e0..6dbec1c2398 100644 --- a/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi +++ b/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi @@ -136,7 +136,7 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "okay"; address = <0>; diff --git a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi index 7aefd9cec86..1efd26bcc46 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi +++ b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi @@ -245,7 +245,7 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "okay"; address = <0>; diff --git a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts index 373c9b88fa2..693e26fd451 100644 --- a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts +++ b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts @@ -147,7 +147,7 @@ compatible = "smsc,lan91c111-mdio"; status = "disabled"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "disabled"; address = <0>; diff --git a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts index d0dbc4c62d7..e1de9c02c02 100644 --- a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts +++ b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts @@ -119,7 +119,7 @@ pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "disabled"; address = <1>; diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index 4d8c7053698..aa93d3ee7c4 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -938,7 +938,7 @@ static const struct ethernet_api adin2111_port_api = { #define ADIN2111_XSTR(x) ADIN2111_STR(x) #define ADIN2111_MDIO_PHY_BY_ADDR(adin_n, phy_addr) \ - DEVICE_DT_GET(DT_CHILD(DT_INST_CHILD(adin_n, mdio), phy_##phy_addr)) + DEVICE_DT_GET(DT_CHILD(DT_INST_CHILD(adin_n, mdio), ethernet_phy_##phy_addr)) #define ADIN2111_PORT_MAC(adin_n, port_n) \ DT_PROP(DT_CHILD(DT_DRV_INST(adin_n), port##port_n), local_mac_address) diff --git a/dts/arm64/fvp/fvp-aemv8r.dtsi b/dts/arm64/fvp/fvp-aemv8r.dtsi index 05ac898bf33..29f0b991ff5 100644 --- a/dts/arm64/fvp/fvp-aemv8r.dtsi +++ b/dts/arm64/fvp/fvp-aemv8r.dtsi @@ -119,7 +119,7 @@ compatible = "smsc,lan91c111-mdio"; status = "disabled"; - phy: phy { + phy: ethernet-phy { compatible = "ethernet-phy"; status = "disabled"; address = <0>; diff --git a/dts/bindings/ethernet/adi,adin1110.yaml b/dts/bindings/ethernet/adi,adin1110.yaml index 4f8bc6f8b25..8b94e1be839 100644 --- a/dts/bindings/ethernet/adi,adin1110.yaml +++ b/dts/bindings/ethernet/adi,adin1110.yaml @@ -20,7 +20,7 @@ description: | status = "okay"; #address-cells = <1>; #size-cells = <0>; - phy@1 { + ethernet-phy@1 { reg = <0x1>; compatible = "adi,adin2111-phy"; status = "okay"; diff --git a/dts/bindings/ethernet/adi,adin2111.yaml b/dts/bindings/ethernet/adi,adin2111.yaml index 8c0f9cb2025..f1b5c1b53c1 100644 --- a/dts/bindings/ethernet/adi,adin2111.yaml +++ b/dts/bindings/ethernet/adi,adin2111.yaml @@ -23,12 +23,12 @@ description: | status = "okay"; #address-cells = <1>; #size-cells = <0>; - phy@1 { + ethernet-phy@1 { reg = <0x1>; compatible = "adi,adin2111-phy"; status = "okay"; }; - phy@2 { + ethernet-phy@2 { reg = <0x2>; compatible = "adi,adin2111-phy"; status = "okay"; From d5287578fed820f29a7b0afd73838aa1c690f4ce Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Mon, 25 Sep 2023 20:19:28 -0500 Subject: [PATCH 1364/4498] dts: bindings: boards: Update Ethernet PHY to use `reg` property Updates Ethernet PHY devicetree bindings to be more consistent with Linux by using the standard `reg` property for the PHY address instead of a custom `address` property. As a result, MDIO controller bindings now require standard `#address-cells` and `#size-cells` properties. Signed-off-by: Maureen Helm --- boards/arm/atsame54_xpro/atsame54_xpro.dts | 4 ++-- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 4 ++-- boards/arm/sam4e_xpro/sam4e_xpro.dts | 4 ++-- .../sam_e70_xplained-common.dtsi | 4 ++-- .../arm/sam_v71_xult/sam_v71_xult-common.dtsi | 4 ++-- .../fvp_base_revc_2xaemv8a.dts | 6 ++++-- .../esp32_ethernet_kit/esp32_ethernet_kit.dts | 4 ++-- doc/releases/migration-guide-3.5.rst | 21 +++++++++++++++++++ drivers/ethernet/phy/phy_mii.c | 2 +- dts/arm/atmel/sam4e.dtsi | 2 ++ dts/arm/atmel/same5x.dtsi | 2 ++ dts/arm/atmel/same70.dtsi | 2 ++ dts/arm/nxp/nxp_s32z27x_r52.dtsi | 2 ++ dts/arm64/fvp/fvp-aemv8r.dtsi | 6 ++++-- dts/bindings/ethernet/ethernet-phy.yaml | 3 +-- dts/bindings/mdio/adi,adin2111-mdio.yaml | 9 -------- dts/bindings/mdio/mdio-controller.yaml | 9 ++++++++ dts/xtensa/espressif/esp32/esp32_common.dtsi | 2 ++ tests/drivers/build_all/mdio/app.overlay | 4 ++++ 19 files changed, 66 insertions(+), 28 deletions(-) diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.dts b/boards/arm/atsame54_xpro/atsame54_xpro.dts index 0d0b6960ad1..b5f9ab19b39 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.dts +++ b/boards/arm/atsame54_xpro/atsame54_xpro.dts @@ -132,9 +132,9 @@ zephyr_udc0: &usb0 { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "okay"; - address = <0>; + reg = <0>; }; }; diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 6bf924802ff..a31ee5f7506 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -31,9 +31,9 @@ pinctrl-names = "default"; status = "okay"; - phy0: ethernet-phy { + phy0: ethernet-phy@7 { compatible = "ethernet-phy"; - address = <0x7>; + reg = <0x7>; status = "okay"; }; }; diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.dts b/boards/arm/sam4e_xpro/sam4e_xpro.dts index eba17bc297b..ddd73d0faef 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.dts +++ b/boards/arm/sam4e_xpro/sam4e_xpro.dts @@ -198,10 +198,10 @@ pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "okay"; - address = <0>; + reg = <0>; }; }; diff --git a/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi b/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi index 6dbec1c2398..93dc9b1f356 100644 --- a/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi +++ b/boards/arm/sam_e70_xplained/sam_e70_xplained-common.dtsi @@ -136,10 +136,10 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "okay"; - address = <0>; + reg = <0>; }; }; diff --git a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi index 1efd26bcc46..9864c7ae50a 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi +++ b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi @@ -245,10 +245,10 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "okay"; - address = <0>; + reg = <0>; }; }; diff --git a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts index 693e26fd451..3a6ff898bf2 100644 --- a/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts +++ b/boards/arm64/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a.dts @@ -146,11 +146,13 @@ mdio: mdio { compatible = "smsc,lan91c111-mdio"; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "disabled"; - address = <0>; + reg = <0>; }; }; }; diff --git a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts index e1de9c02c02..3139e8beaa3 100644 --- a/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts +++ b/boards/xtensa/esp32_ethernet_kit/esp32_ethernet_kit.dts @@ -119,10 +119,10 @@ pinctrl-0 = <&mdio_default>; pinctrl-names = "default"; - phy: ethernet-phy { + phy: ethernet-phy@1 { compatible = "ethernet-phy"; status = "disabled"; - address = <1>; + reg = <1>; }; }; diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index ab891988aa9..220302e1203 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -118,6 +118,27 @@ Required changes :c:func:`can_set_bitrate` and :c:func:`can_set_bitrate_data` now also automatically calculate a suitable SJW, but their SJW cannot be overwritten by the caller. +* Ethernet PHY devicetree bindings were updated to use the standard ``reg`` + property for the PHY address instead of a custom ``address`` property. As a + result, MDIO controller nodes now require ``#address-cells`` and + ``#size-cells`` properties. Similarly, Ethernet PHY devicetree nodes and + corresponding driver were updated to consistently use the node name + ``ethernet-phy`` instead of ``phy``. Devicetrees and overlays must be updated + accordingly: + + .. code-block:: devicetree + + mdio { + compatible = "mdio-controller"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + }; + }; + Recommended Changes ******************* diff --git a/drivers/ethernet/phy/phy_mii.c b/drivers/ethernet/phy/phy_mii.c index fa703cc685e..4ad961089e6 100644 --- a/drivers/ethernet/phy/phy_mii.c +++ b/drivers/ethernet/phy/phy_mii.c @@ -477,7 +477,7 @@ static const struct ethphy_driver_api phy_mii_driver_api = { #define PHY_MII_CONFIG(n) \ static const struct phy_mii_dev_config phy_mii_dev_config_##n = { \ - .phy_addr = DT_INST_PROP(n, address), \ + .phy_addr = DT_INST_REG_ADDR(n), \ .fixed = IS_FIXED_LINK(n), \ .fixed_speed = DT_INST_ENUM_IDX_OR(n, fixed_link, 0), \ .mdio = UTIL_AND(UTIL_NOT(IS_FIXED_LINK(n)), \ diff --git a/dts/arm/atmel/sam4e.dtsi b/dts/arm/atmel/sam4e.dtsi index 6393de005f9..ede65163ed0 100644 --- a/dts/arm/atmel/sam4e.dtsi +++ b/dts/arm/atmel/sam4e.dtsi @@ -172,6 +172,8 @@ compatible = "atmel,sam-mdio"; reg = <0x40034000 0x4000>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; pinctrl: pinctrl@400e0e00 { diff --git a/dts/arm/atmel/same5x.dtsi b/dts/arm/atmel/same5x.dtsi index 341d6e9d1ad..1d11fa32c97 100644 --- a/dts/arm/atmel/same5x.dtsi +++ b/dts/arm/atmel/same5x.dtsi @@ -22,6 +22,8 @@ compatible = "atmel,sam-mdio"; reg = <0x42000800 0x400>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; }; }; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 7256a2bc0be..02fae555c25 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -334,6 +334,8 @@ compatible = "atmel,sam-mdio"; reg = <0x40050000 0x4000>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; tc0: tc@4000c000 { diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 691df7750f5..56677ed2865 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -637,6 +637,8 @@ compatible = "nxp,s32-netc-emdio"; reg = <0x74b60000 0x1c44>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; enetc_psi0: ethernet@74b00000 { diff --git a/dts/arm64/fvp/fvp-aemv8r.dtsi b/dts/arm64/fvp/fvp-aemv8r.dtsi index 29f0b991ff5..7b11948cfe1 100644 --- a/dts/arm64/fvp/fvp-aemv8r.dtsi +++ b/dts/arm64/fvp/fvp-aemv8r.dtsi @@ -118,11 +118,13 @@ mdio: mdio { compatible = "smsc,lan91c111-mdio"; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; - phy: ethernet-phy { + phy: ethernet-phy@0 { compatible = "ethernet-phy"; status = "disabled"; - address = <0>; + reg = <0>; }; }; }; diff --git a/dts/bindings/ethernet/ethernet-phy.yaml b/dts/bindings/ethernet/ethernet-phy.yaml index 9568c036d2e..77278c2ca40 100644 --- a/dts/bindings/ethernet/ethernet-phy.yaml +++ b/dts/bindings/ethernet/ethernet-phy.yaml @@ -10,8 +10,7 @@ compatible: "ethernet-phy" include: phy.yaml properties: - address: - type: int + reg: required: true description: PHY address no-reset: diff --git a/dts/bindings/mdio/adi,adin2111-mdio.yaml b/dts/bindings/mdio/adi,adin2111-mdio.yaml index ab20d5cb33d..a42a1f82113 100644 --- a/dts/bindings/mdio/adi,adin2111-mdio.yaml +++ b/dts/bindings/mdio/adi,adin2111-mdio.yaml @@ -8,12 +8,3 @@ compatible: "adi,adin2111-mdio" include: mdio-controller.yaml on-bus: adin2111 - -properties: - "#address-cells": - required: true - const: 1 - - "#size-cells": - required: true - const: 0 diff --git a/dts/bindings/mdio/mdio-controller.yaml b/dts/bindings/mdio/mdio-controller.yaml index b944d0a6ee8..9a2a6782d53 100644 --- a/dts/bindings/mdio/mdio-controller.yaml +++ b/dts/bindings/mdio/mdio-controller.yaml @@ -6,3 +6,12 @@ include: base.yaml bus: mdio + +properties: + "#address-cells": + required: true + const: 1 + + "#size-cells": + required: true + const: 0 diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index c7b735dd779..0f61150cead 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -71,6 +71,8 @@ compatible = "espressif,esp32-mdio"; clocks = <&rtc ESP32_EMAC_MODULE>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; pinctrl: pin-controller { diff --git a/tests/drivers/build_all/mdio/app.overlay b/tests/drivers/build_all/mdio/app.overlay index 82392465d23..e03c9e95065 100644 --- a/tests/drivers/build_all/mdio/app.overlay +++ b/tests/drivers/build_all/mdio/app.overlay @@ -29,6 +29,8 @@ mdc-gpios = <&test_gpio 0 0>; mdio-gpios = <&test_gpio 0 0>; status = "okay"; + #address-cells = <1>; + #size-cells = <0>; }; test_mdio1: mdio@33334444 { @@ -37,6 +39,8 @@ mdc-gpios = <&test_gpio 0 0>; mdio-gpios = <&test_gpio 0 0>; status = "okay"; + #address-cells = <1>; + #size-cells = <0>; }; }; }; From d212e50eafcf10e2d18ffe0bd13862d940bf9de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 20 Sep 2023 16:04:11 +0700 Subject: [PATCH 1365/4498] soc: nxp_s32: enable RTU.PIT timers for S32ZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each RTU includes one PIT instance that can be used by any of the cores. Signed-off-by: Manuel Argüelles --- dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi | 9 +++++++++ dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi | 9 +++++++++ soc/arm/nxp_s32/s32ze/Kconfig.series | 2 ++ west.yml | 2 +- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi index bc8ff76a850..6d3b7da45d2 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi @@ -83,5 +83,14 @@ clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; + + pit0: pit@76150000 { + compatible = "nxp,kinetis-pit"; + reg = <0x76150000 0x10000>; + interrupts = ; + clocks = <&clock NXP_S32_P0_REG_INTF_CLK>; + max-load-value = <0x00ffffff>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi index dd2e41d8464..ed3de4f2f16 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi @@ -83,5 +83,14 @@ clocks = <&clock NXP_S32_FIRC_CLK>; status = "disabled"; }; + + pit0: pit@76950000 { + compatible = "nxp,kinetis-pit"; + reg = <0x76950000 0x10000>; + interrupts = ; + clocks = <&clock NXP_S32_P1_REG_INTF_CLK>; + max-load-value = <0x00ffffff>; + status = "disabled"; + }; }; }; diff --git a/soc/arm/nxp_s32/s32ze/Kconfig.series b/soc/arm/nxp_s32/s32ze/Kconfig.series index ebeca180a1e..c1f2d3606ec 100644 --- a/soc/arm/nxp_s32/s32ze/Kconfig.series +++ b/soc/arm/nxp_s32/s32ze/Kconfig.series @@ -15,5 +15,7 @@ config SOC_SERIES_S32ZE_R52 select PLATFORM_SPECIFIC_INIT select SOC_FAMILY_NXP_S32 select CLOCK_CONTROL + select HAS_MCUX + select HAS_MCUX_PIT help Enable support for NXP S32Z/E MCUs family on Cortex-R52 cores. diff --git a/west.yml b/west.yml index 4f4f04482e8..4a86f7acb01 100644 --- a/west.yml +++ b/west.yml @@ -199,7 +199,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 6d91c1727dadb170facc48f5370358a12ae36677 + revision: b4a37865355a6d55cdcdc087b934017212fb0f54 path: modules/hal/nxp groups: - hal From fcdf31521f278c7989511efd85f8f1a2f04ac04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 20 Sep 2023 16:05:52 +0700 Subject: [PATCH 1366/4498] tests: counter: enable RTU.PIT tests for s32z270dc2_r52 boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable testing RTU.PIT on s32z270dc2_r52 boards. Signed-off-by: Manuel Argüelles --- .../counter_basic_api/boards/s32z270dc2_rtu0_r52.overlay | 8 +++++++- .../counter_basic_api/boards/s32z270dc2_rtu1_r52.overlay | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu0_r52.overlay b/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu0_r52.overlay index 32e77ec10fe..d35e70e8a12 100644 --- a/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu0_r52.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu0_r52.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,3 +23,9 @@ prescaler = <32>; status = "okay"; }; + +&pit0 { + pit-channel = <0>; + pit-period = <1000000>; + status = "okay"; +}; diff --git a/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu1_r52.overlay b/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu1_r52.overlay index 32e77ec10fe..d35e70e8a12 100644 --- a/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu1_r52.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/s32z270dc2_rtu1_r52.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,3 +23,9 @@ prescaler = <32>; status = "okay"; }; + +&pit0 { + pit-channel = <0>; + pit-period = <1000000>; + status = "okay"; +}; From 58ca047fa7c51015ad6a9dc98ea2fe864722fa26 Mon Sep 17 00:00:00 2001 From: Stefan Petersen Date: Mon, 11 Sep 2023 11:46:19 +0200 Subject: [PATCH 1367/4498] dts: stm32h7: flash-controller: Add default STM32 as compatible Add "st,stm32-flash-controller" as compatible for STM32H7 so that what is defined for STM32 in general is also defined for STM32H7. Already most of the other STM32 versions have this addition. Also removed the specific STM32H7 flag check in /flash/driver/Kconfig.stm32. Signed-off-by: Stefan Petersen --- drivers/flash/Kconfig.stm32 | 3 +-- dts/arm/st/h7/stm32h7.dtsi | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index 55aa1c7dcca..aa7d24cbd6d 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -8,8 +8,7 @@ config SOC_FLASH_STM32 bool "STM32 flash driver" - depends on DT_HAS_ST_STM32_FLASH_CONTROLLER_ENABLED || \ - DT_HAS_ST_STM32H7_FLASH_CONTROLLER_ENABLED + depends on DT_HAS_ST_STM32_FLASH_CONTROLLER_ENABLED select FLASH_HAS_DRIVER_ENABLED default y select FLASH_PAGE_LAYOUT diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index c835040b7e0..58a01b962b2 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -129,7 +129,7 @@ soc { flash: flash-controller@52002000 { - compatible = "st,stm32h7-flash-controller"; + compatible = "st,stm32-flash-controller", "st,stm32h7-flash-controller"; reg = <0x52002000 0x400>; interrupts = <4 0>; clocks = <&rcc STM32_CLOCK_BUS_AHB3 0x00000100>; From c67de647fbb6ed10a125f49bf0feea14e7ee002f Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Tue, 26 Sep 2023 13:05:42 +0700 Subject: [PATCH 1368/4498] boards: mr_canhubk3: configuring DMA for LPUART Assign DMA channels/sources for all LPUARTs exist on the board so that async APIs can be used for all instances when enabled. Because LPUART 1 & 9, LPUART 2 & 10 share the same DMA sources for TX and RX, be aware when using async APIs for those instances. Signed-off-by: Dat Nguyen Duy --- boards/arm/mr_canhubk3/mr_canhubk3.dts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index a89047e926e..bb9ff2b5055 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -197,38 +197,62 @@ &lpuart0 { pinctrl-0 = <&lpuart0_default>; pinctrl-names = "default"; + dmas = <&edma0 0 37>, <&edma0 1 38>; + dma-names = "tx", "rx"; }; &lpuart1 { pinctrl-0 = <&lpuart1_default>; pinctrl-names = "default"; + dmas = <&edma0 2 39>, <&edma0 3 40>; + dma-names = "tx", "rx"; }; &lpuart2 { pinctrl-0 = <&lpuart2_default>; pinctrl-names = "default"; current-speed = <115200>; + dmas = <&edma0 16 38>, <&edma0 17 39>; + dma-names = "tx", "rx"; status = "okay"; }; &lpuart9 { pinctrl-0 = <&lpuart9_default>; pinctrl-names = "default"; + /* + * LPUART 1 and 9 share the same DMA source for TX + * and RX, using UART async API for both instances + * should be careful. + */ + dmas = <&edma0 4 39>, <&edma0 5 40>; + dma-names = "tx", "rx"; }; &lpuart10 { pinctrl-0 = <&lpuart10_default>; pinctrl-names = "default"; + /* + * LPUART 2 and 10 share the same DMA source for TX + * and RX, using UART async API for both instances + * should be careful. + */ + dmas = <&edma0 18 38>, <&edma0 19 39>; + dma-names = "tx", "rx"; }; &lpuart13 { pinctrl-0 = <&lpuart13_default>; pinctrl-names = "default"; + dmas = <&edma0 20 44>, <&edma0 21 45>; + dma-names = "tx", "rx"; }; &lpuart14 { pinctrl-0 = <&lpuart14_default>; pinctrl-names = "default"; + dmas = <&edma0 22 46>, <&edma0 23 47>; + dma-names = "tx", "rx"; }; &qspi0 { From d4cab4474b194a014ec341a9b466ab154483369f Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 15 Jun 2023 14:27:07 +0700 Subject: [PATCH 1369/4498] tests: drivers: uart_async_api: enable test for mr_canhubk3 Run this test on lpuart10 with internal loopback enabled. Use DTCM region for this test because in some local variables are used for dma buffer which requires non-cacheable Signed-off-by: Dat Nguyen Duy --- .../uart_async_api/boards/mr_canhubk3.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/mr_canhubk3.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/mr_canhubk3.overlay b/tests/drivers/uart/uart_async_api/boards/mr_canhubk3.overlay new file mode 100644 index 00000000000..bf265a6a962 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/mr_canhubk3.overlay @@ -0,0 +1,16 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +/ { + chosen { + zephyr,sram = &dtcm; + }; +}; + +dut: &lpuart10 { + current-speed = <115200>; + nxp,loopback; + status = "okay"; +}; From f2ddadf3a06edb176e46c0d5edfd26d84c8bef9c Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 28 Sep 2023 08:38:12 +0700 Subject: [PATCH 1370/4498] boards: mr_canhubk3: enable dma for automation testing Enable dma for automation testing Signed-off-by: Dat Nguyen Duy --- boards/arm/mr_canhubk3/mr_canhubk3.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.yaml b/boards/arm/mr_canhubk3/mr_canhubk3.yaml index a9f5f68b720..227498e16a7 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.yaml +++ b/boards/arm/mr_canhubk3/mr_canhubk3.yaml @@ -19,4 +19,5 @@ supported: - watchdog - netif:eth - pwm + - dma vendor: nxp From 3bc531e9c6874eb04fea5c886dc725d75774e58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wouter=20Horr=C3=A9?= Date: Wed, 23 Aug 2023 15:13:40 +0200 Subject: [PATCH 1371/4498] drivers: i2c: stm32: Support wakeup from STOP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for wakeup from STOP mode when the i2c device is configured as a target. Signed-off-by: Wouter Horré --- drivers/i2c/i2c_ll_stm32_v2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index a05edd5c8cb..5d22380118b 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "i2c_ll_stm32.h" #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL @@ -227,6 +229,16 @@ int i2c_stm32_target_register(const struct device *dev, return ret; } +#if defined(CONFIG_PM_DEVICE_RUNTIME) + if (pm_device_wakeup_is_capable(dev)) { + /* Mark device as active */ + (void)pm_device_runtime_get(dev); + /* Enable wake-up from stop */ + LOG_DBG("i2c: enabling wakeup from stop"); + LL_I2C_EnableWakeUpFromStop(cfg->i2c); + } +#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */ + LL_I2C_Enable(i2c); if (!data->slave_cfg) { @@ -306,6 +318,16 @@ int i2c_stm32_target_unregister(const struct device *dev, LL_I2C_Disable(i2c); +#if defined(CONFIG_PM_DEVICE_RUNTIME) + if (pm_device_wakeup_is_capable(dev)) { + /* Disable wake-up from STOP */ + LOG_DBG("i2c: disabling wakeup from stop"); + LL_I2C_DisableWakeUpFromStop(i2c); + /* Release the device */ + (void)pm_device_runtime_put(dev); + } +#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */ + data->slave_attached = false; return 0; From 9727f61371bb7dce44d088f2a3c2b347815efedc Mon Sep 17 00:00:00 2001 From: Armin Brauns Date: Mon, 7 Aug 2023 09:21:05 +0000 Subject: [PATCH 1372/4498] logging: return actual filter level when runtime filter is disabled log_filter_set() is defined to return the actual level that was set by the call. In case runtime filtering is disabled, this is always the compiled-in log level, not the level passed by the user. Signed-off-by: Armin Brauns --- subsys/logging/log_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/logging/log_mgmt.c b/subsys/logging/log_mgmt.c index 1f3e3594760..08de43165bc 100644 --- a/subsys/logging/log_mgmt.c +++ b/subsys/logging/log_mgmt.c @@ -417,7 +417,7 @@ uint32_t z_impl_log_filter_set(struct log_backend const *const backend, uint32_t level) { if (!IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) { - return level; + return log_compiled_level_get(domain_id, source_id); } __ASSERT_NO_MSG(source_id < log_src_cnt_get(domain_id)); From a52e92a1485096f798c7e8abb95de253262c00bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 28 Sep 2023 08:56:53 +0200 Subject: [PATCH 1373/4498] Revert "logging: Fix case when LOG_LEVEL is 0" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit bd428663e9e98057f120cc4385e32c2cbe7e306d. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_core.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/logging/log_core.h b/include/zephyr/logging/log_core.h index 94fb92325f7..f1ec8345073 100644 --- a/include/zephyr/logging/log_core.h +++ b/include/zephyr/logging/log_core.h @@ -84,8 +84,6 @@ extern "C" { #define Z_LOG_EVAL1(_eval_level, _iftrue, _iffalse) \ __COND_CODE(_LOG_ZZZZ##_eval_level, _iftrue, _iffalse) -#define _LOG_ZZZZ0 _LOG_YYYY, -#define _LOG_ZZZZ0U _LOG_YYYY, #define _LOG_ZZZZ1 _LOG_YYYY, #define _LOG_ZZZZ1U _LOG_YYYY, #define _LOG_ZZZZ2 _LOG_YYYY, From 6b7c8ae1b3595656d7372fa4205420e7fc64103d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 28 Sep 2023 09:25:48 +0200 Subject: [PATCH 1374/4498] logging: log_output: Minor code cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Z_LOG_EVAL was used in place where COND_CODE_1 was a much better fit. Z_LOG_EVAL gave the same result but it was not intended to be used here. Signed-off-by: Krzysztof Chruściński --- subsys/logging/log_output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index ecfab72cac2..8a3fad06027 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -23,10 +23,10 @@ #define HEXDUMP_BYTES_IN_LINE 16 #define DROPPED_COLOR_PREFIX \ - Z_LOG_EVAL(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_RED), ()) + COND_CODE_1(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_RED), ()) #define DROPPED_COLOR_POSTFIX \ - Z_LOG_EVAL(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_DEFAULT), ()) + COND_CODE_1(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_DEFAULT), ()) static const char *const severity[] = { NULL, From 72ec6ce4db682c89bdcdd5688294ca075b8832a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 28 Sep 2023 09:29:26 +0200 Subject: [PATCH 1375/4498] logging: Fix _LOG_LEVEL_RESOLVE macro for LOG_LEVEL case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Z_LOG_EVAL returns 1 for non-zero log level so if LOG_LEVEL was 0 with intention to disable logs in the current module Z_LOG_EVAL was jumping to the second option and was applying default logging level. Since LOG_LEVEL set to 0 should also lead to evaluation of LOG_LEVEL COND_CODE_0 is added. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/logging/log.h b/include/zephyr/logging/log.h index 7b7dbb56b8a..e6db645c742 100644 --- a/include/zephyr/logging/log.h +++ b/include/zephyr/logging/log.h @@ -290,7 +290,7 @@ void z_log_vprintk(const char *fmt, va_list ap); #define _LOG_LEVEL_RESOLVE(...) LOG_LEVEL_NONE #else #define _LOG_LEVEL_RESOLVE(...) \ - Z_LOG_EVAL(LOG_LEVEL, \ + Z_LOG_EVAL(COND_CODE_0(LOG_LEVEL, (1), (LOG_LEVEL)), \ (GET_ARG_N(2, __VA_ARGS__, LOG_LEVEL)), \ (GET_ARG_N(2, __VA_ARGS__, CONFIG_LOG_DEFAULT_LEVEL))) #endif From 85fa6746de263bc13fecca4bb1ae2f4705a40438 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 28 Sep 2023 16:55:10 +0200 Subject: [PATCH 1376/4498] drivers: clock_control: stm32u5: enable backup access before enabling lsi LSI needs write access to backup domain to be enabled. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32_ll_u5.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index 52d6bd42d62..8fe0608d50c 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -770,10 +770,25 @@ static void set_up_fixed_clock_sources(void) } if (IS_ENABLED(STM32_LSI_ENABLED)) { + if (!LL_AHB3_GRP1_IsEnabledClock(LL_AHB3_GRP1_PERIPH_PWR)) { + /* Enable the power interface clock */ + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PWR); + } + + if (!LL_PWR_IsEnabledBkUpAccess()) { + /* Enable write access to Backup domain */ + LL_PWR_EnableBkUpAccess(); + while (!LL_PWR_IsEnabledBkUpAccess()) { + /* Wait for Backup domain access */ + } + } + /* Enable LSI oscillator */ LL_RCC_LSI_Enable(); while (LL_RCC_LSI_IsReady() != 1) { } + + LL_PWR_DisableBkUpAccess(); } if (IS_ENABLED(STM32_HSI48_ENABLED)) { From 6661f05dafade0024724b871ccf0355c8727aba3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 28 Sep 2023 14:17:04 +0300 Subject: [PATCH 1377/4498] net: ppp: Mark the PPP L2 as non-experimental The experimental status of the PPP L2 is long overdue so it can be removed as the component is working fine. Signed-off-by: Jukka Rissanen --- scripts/kconfig/hardened.csv | 1 - subsys/net/l2/ppp/Kconfig | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/kconfig/hardened.csv b/scripts/kconfig/hardened.csv index a09defdc756..ee95b54b3a7 100644 --- a/scripts/kconfig/hardened.csv +++ b/scripts/kconfig/hardened.csv @@ -100,7 +100,6 @@ NET_CONNECTION_MANAGER,n,experimental NET_GPTP,n,experimental NET_IPV4_AUTO,n,experimental NET_L2_IEEE802154_SECURITY,n,experimental -NET_L2_PPP,n,experimental NET_PROMISCUOUS_MODE,n,experimental NET_SOCKETS_CAN,n,experimental NET_SOCKETS_ENABLE_DTLS,n,experimental diff --git a/subsys/net/l2/ppp/Kconfig b/subsys/net/l2/ppp/Kconfig index 416fe9cf70d..db47968c512 100644 --- a/subsys/net/l2/ppp/Kconfig +++ b/subsys/net/l2/ppp/Kconfig @@ -2,8 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig NET_L2_PPP - bool "Point-to-point (PPP) support [EXPERIMENTAL]" - select EXPERIMENTAL + bool "Point-to-point (PPP) support" select NET_MGMT select NET_MGMT_EVENT help From 8fe6150e0ca022b9f10f70138219b15f704e6d1a Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 27 Sep 2023 16:36:18 +0100 Subject: [PATCH 1378/4498] arch: arm: cortex_m: restrict usage of atomic_operations_c for Cortex-m0/+ Armv8-m baseline support various instruction carrying exclusive-monitor and acquire-release semantic. By adding this guard we let armv8-m.baseline fall-back to arch defined or compiler built-in support for atomic operations. Signed-off-by: Wilfried Chauveau --- arch/arm/core/cortex_m/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/core/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig index 169d5bc838d..95e05604783 100644 --- a/arch/arm/core/cortex_m/Kconfig +++ b/arch/arm/core/cortex_m/Kconfig @@ -171,7 +171,7 @@ config CPU_CORTEX_M_HAS_CMSE config ARMV6_M_ARMV8_M_BASELINE bool - select ATOMIC_OPERATIONS_C + select ATOMIC_OPERATIONS_C if !ARMV8_M_BASELINE select ISA_THUMB2 help This option signifies the use of an ARMv6-M processor From 0781a868625cb390d34f7ee51206185b15cc3bbf Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 27 Sep 2023 16:44:09 +0100 Subject: [PATCH 1379/4498] arch: arm: cortex_m: enable armv8m.baseline to use BASEPRI based irq lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows for armv8m.baseline cores to rely on BASEPRI based interrupt masking and share the same code as v7m and v8m.mainline. Signed-off-by: Wilfried Chauveau --- include/zephyr/arch/arm/asm_inline_gcc.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/zephyr/arch/arm/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h index 7bb58d9897c..ee7a31debb5 100644 --- a/include/zephyr/arch/arm/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -43,13 +43,17 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) { unsigned int key; -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE) +#if CONFIG_MP_MAX_NUM_CPUS == 1 __asm__ volatile("mrs %0, PRIMASK;" "cpsid i" : "=r" (key) : : "memory"); -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) +#else +#error "Cortex-M0 and Cortex-M0+ require SoC specific support for cross core synchronisation." +#endif +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE) unsigned int tmp; __asm__ volatile( @@ -83,7 +87,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) { -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE) if (key != 0U) { return; } @@ -91,7 +95,7 @@ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) "cpsie i;" "isb" : : : "memory"); -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE) __asm__ volatile( "msr BASEPRI, %0;" "isb;" From 950fba73ee4b8f49a69fc238c9b090906c22e8b4 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 22 Sep 2023 14:57:47 +0200 Subject: [PATCH 1380/4498] dts: arm: st: u5: add missing compatibles for stm32u595 and u599 Add missing compatibles for STM32U595 and STM32U599. Signed-off-by: Guillaume Gautier --- dts/arm/st/u5/stm32u595.dtsi | 2 ++ dts/arm/st/u5/stm32u599.dtsi | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/dts/arm/st/u5/stm32u595.dtsi b/dts/arm/st/u5/stm32u595.dtsi index 2d7ffe1145d..401aa5ace79 100644 --- a/dts/arm/st/u5/stm32u595.dtsi +++ b/dts/arm/st/u5/stm32u595.dtsi @@ -9,6 +9,8 @@ / { soc { + compatible = "st,stm32u595", "st,stm32u5", "simple-bus"; + pinctrl: pin-controller@42020000 { compatible = "st,stm32-pinctrl"; #address-cells = <1>; diff --git a/dts/arm/st/u5/stm32u599.dtsi b/dts/arm/st/u5/stm32u599.dtsi index d3ecfb7c56a..f72d22c5f1a 100644 --- a/dts/arm/st/u5/stm32u599.dtsi +++ b/dts/arm/st/u5/stm32u599.dtsi @@ -5,3 +5,9 @@ */ #include + +/ { + soc { + compatible = "st,stm32u599", "st,stm32u5", "simple-bus"; + }; +}; From c2175e9ed55012ca2549f7e5265c8bb031aedda8 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 22 Sep 2023 14:59:57 +0200 Subject: [PATCH 1381/4498] dts: arm: st: u5: add stm32u5a5 dtsi Add STM32U5A5 dtsi. Signed-off-by: Guillaume Gautier --- dts/arm/st/u5/stm32u5a5.dtsi | 13 +++++++++++++ dts/arm/st/u5/stm32u5a5Xj.dtsi | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 dts/arm/st/u5/stm32u5a5.dtsi create mode 100644 dts/arm/st/u5/stm32u5a5Xj.dtsi diff --git a/dts/arm/st/u5/stm32u5a5.dtsi b/dts/arm/st/u5/stm32u5a5.dtsi new file mode 100644 index 00000000000..bc8ba619020 --- /dev/null +++ b/dts/arm/st/u5/stm32u5a5.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32u5a5", "st,stm32u5", "simple-bus"; + }; +}; diff --git a/dts/arm/st/u5/stm32u5a5Xj.dtsi b/dts/arm/st/u5/stm32u5a5Xj.dtsi new file mode 100644 index 00000000000..6719e89619d --- /dev/null +++ b/dts/arm/st/u5/stm32u5a5Xj.dtsi @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + /* SRAM1 + SRAM2 + SRAM3 + SRAM5 */ + reg = <0x20000000 DT_SIZE_K(2496)>; + }; + sram1: memory@28000000 { + /* SRAM4 */ + reg = <0x28000000 DT_SIZE_K(16)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(4)>; + }; + }; + }; +}; From 6f76e0dcf8a9b4a107971d3f2d00ef8a8009f298 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 22 Sep 2023 15:03:04 +0200 Subject: [PATCH 1382/4498] soc: arm: st_stm32: stm32u5: add stm32u5a5 soc Add STM32U5A5 SOC Signed-off-by: Guillaume Gautier --- .../st_stm32/stm32u5/Kconfig.defconfig.stm32u5a5xx | 14 ++++++++++++++ soc/arm/st_stm32/stm32u5/Kconfig.soc | 3 +++ 2 files changed, 17 insertions(+) create mode 100644 soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a5xx diff --git a/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a5xx b/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a5xx new file mode 100644 index 00000000000..1759406a580 --- /dev/null +++ b/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a5xx @@ -0,0 +1,14 @@ +# STMicroelectronics STM32U5A5XX MCU + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32U5A5XX + +config SOC + default "stm32u5a5xx" + +config NUM_IRQS + default 139 + +endif # SOC_STM32U5A5XX diff --git a/soc/arm/st_stm32/stm32u5/Kconfig.soc b/soc/arm/st_stm32/stm32u5/Kconfig.soc index cceb506f55e..8308c64372f 100644 --- a/soc/arm/st_stm32/stm32u5/Kconfig.soc +++ b/soc/arm/st_stm32/stm32u5/Kconfig.soc @@ -20,4 +20,7 @@ config SOC_STM32U595XX config SOC_STM32U599XX bool "STM32U599XX" +config SOC_STM32U5A5XX + bool "STM32U5A5XX" + endchoice From f2fa77a3e3ea5eb61d6f926ec819c78d786915b2 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 22 Sep 2023 15:12:36 +0200 Subject: [PATCH 1383/4498] boards: arm: nucleo_u5a5zj_q: add nucleo u5a5zj q board Add support for Nucleo U5A5ZJ Q board. Signed-off-by: Guillaume Gautier --- boards/arm/nucleo_u5a5zj_q/CMakeLists.txt | 14 + boards/arm/nucleo_u5a5zj_q/Kconfig.board | 8 + boards/arm/nucleo_u5a5zj_q/Kconfig.defconfig | 11 + .../nucleo_u5a5zj_q/arduino_r3_connector.dtsi | 40 ++ boards/arm/nucleo_u5a5zj_q/board.cmake | 14 + boards/arm/nucleo_u5a5zj_q/doc/index.rst | 377 ++++++++++++++++++ .../nucleo_u5a5zj_q-common.dtsi | 189 +++++++++ .../arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts | 76 ++++ .../arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml | 24 ++ .../nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig | 26 ++ .../arm/nucleo_u5a5zj_q/support/openocd.cfg | 44 ++ 11 files changed, 823 insertions(+) create mode 100644 boards/arm/nucleo_u5a5zj_q/CMakeLists.txt create mode 100644 boards/arm/nucleo_u5a5zj_q/Kconfig.board create mode 100644 boards/arm/nucleo_u5a5zj_q/Kconfig.defconfig create mode 100644 boards/arm/nucleo_u5a5zj_q/arduino_r3_connector.dtsi create mode 100644 boards/arm/nucleo_u5a5zj_q/board.cmake create mode 100644 boards/arm/nucleo_u5a5zj_q/doc/index.rst create mode 100644 boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi create mode 100644 boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts create mode 100644 boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml create mode 100644 boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig create mode 100644 boards/arm/nucleo_u5a5zj_q/support/openocd.cfg diff --git a/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt new file mode 100644 index 00000000000..c79a4b7b4e7 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr") + set(COMPILER_FULL_PATH ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc) +elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "gnuarmemb") + set(COMPILER_FULL_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc) +endif() + +if(CONFIG_BUILD_WITH_TFM) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + #Execute post build script postbuild.sh + COMMAND $/postbuild.sh ${COMPILER_FULL_PATH} + ) +endif() diff --git a/boards/arm/nucleo_u5a5zj_q/Kconfig.board b/boards/arm/nucleo_u5a5zj_q/Kconfig.board new file mode 100644 index 00000000000..2a1713e0b4f --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/Kconfig.board @@ -0,0 +1,8 @@ +# STM32U5A5ZJ Q Nucleo board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_U5A5ZJ_Q + bool "Nucleo U5A5ZJ Q Development Board" + depends on SOC_STM32U5A5XX diff --git a/boards/arm/nucleo_u5a5zj_q/Kconfig.defconfig b/boards/arm/nucleo_u5a5zj_q/Kconfig.defconfig new file mode 100644 index 00000000000..ab566327264 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/Kconfig.defconfig @@ -0,0 +1,11 @@ +# STM32U5A5ZJ Q Nucleo board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_U5A5ZJ_Q + +config BOARD + default "nucleo_u5a5zj_q" + +endif # BOARD_NUCLEO_U5A5ZJ_Q diff --git a/boards/arm/nucleo_u5a5zj_q/arduino_r3_connector.dtsi b/boards/arm/nucleo_u5a5zj_q/arduino_r3_connector.dtsi new file mode 100644 index 00000000000..be1a9c7abcc --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 3 0>, /* A0 */ + <1 0 &gpioa 2 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpiob 0 0>, /* A3 */ + <4 0 &gpioc 1 0>, /* A4 */ + <5 0 &gpioc 0 0>, /* A5 */ + <6 0 &gpiog 8 0>, /* D0 */ + <7 0 &gpiog 7 0>, /* D1 */ + <8 0 &gpiof 15 0>, /* D2 */ + <9 0 &gpioe 13 0>, /* D3 */ + <10 0 &gpiof 14 0>, /* D4 */ + <11 0 &gpioe 11 0>, /* D5 */ + <12 0 &gpioe 9 0>, /* D6 */ + <13 0 &gpiof 13 0>, /* D7 */ + <14 0 &gpiof 12 0>, /* D8 */ + <15 0 &gpiod 15 0>, /* D9 */ + <16 0 &gpiod 14 0>, /* D10 */ + <17 0 &gpioa 7 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; +arduino_serial: &lpuart1 {}; diff --git a/boards/arm/nucleo_u5a5zj_q/board.cmake b/boards/arm/nucleo_u5a5zj_q/board.cmake new file mode 100644 index 00000000000..55861552c8e --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/board.cmake @@ -0,0 +1,14 @@ +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") + +board_runner_args(openocd "--tcl-port=6666") +board_runner_args(openocd --cmd-pre-init "gdb_report_data_abort enable") +board_runner_args(openocd "--no-halt") + +board_runner_args(pyocd "--target=stm32u5a5zjtx") + +board_runner_args(jlink "--device=STM32U5A5ZJ" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nucleo_u5a5zj_q/doc/index.rst b/boards/arm/nucleo_u5a5zj_q/doc/index.rst new file mode 100644 index 00000000000..f877be5c168 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/doc/index.rst @@ -0,0 +1,377 @@ +.. _nucleo_u5a5zj_q_board: + +ST Nucleo U5A5ZJ Q +################## + +Overview +******** + +The Nucleo U5A5ZJ Q board, featuring an ARM Cortex-M33 based STM32U5A5ZJ MCU, +provides an affordable and flexible way for users to try out new concepts and +build prototypes by choosing from the various combinations of performance and +power consumption features. Here are some highlights of the Nucleo U5A5ZJ Q +board: + + +- STM32U5A5ZJ microcontroller in LQFP144 package +- Internal SMPS to generate V core logic supply +- Two types of extension resources: + + - Arduino Uno V3 connectivity + - ST morpho extension pin headers for full access to all STM32 I/Os + +- On-board ST-LINK/V3E debugger/programmer +- Flexible board power supply: + + - USB VBUS or external source(3.3V, 5V, 7 - 12V) + - ST-Link V3E + +- Three users LEDs +- Two push-buttons: USER and RESET +- USB Type-C ™ Sink device FS + +Hardware +******** + +The STM32U5A5xx devices are an ultra-low-power microcontrollers family (STM32U5 +Series) based on the high-performance Arm® Cortex®-M33 32-bit RISC core. +They operate at a frequency of up to 160 MHz. + +- Includes ST state-of-the-art patented technology +- Ultra-low-power with FlexPowerControl: + + - 1.71 V to 3.6 V power supply + - -40 °C to +85/125 °C temperature range + - Low-power background autonomous mode (LPBAM): autonomous peripherals with + DMA, functional down to Stop 2 mode + - VBAT mode: supply for RTC, 32 x 32-bit backup registers and 2-Kbyte backup SRAM + - 150 nA Shutdown mode (24 wake-up pins) + - 195 nA Standby mode (24 wake-up pins) + - 480 nA Standby mode with RTC + - 2 µA Stop 3 mode with 40-Kbyte SRAM + - 8.2 µA Stop 3 mode with 2.5-Mbyte SRAM + - 4.65 µA Stop 2 mode with 40-Kbyte SRAM + - 17.5 µA Stop 2 mode with 2.5-Mbyte SRAM + - 18.5 µA/MHz Run mode at 3.3 V + +- Core: + + - Arm® 32-bit Cortex®-M33 CPU with TrustZone®, MPU, DSP, + and FPU ART Accelerator + - 32-Kbyte ICACHE allowing 0-wait-state execution from flash and external + memories: frequency up to 160 MHz, 240 DMIPS + - 16-Kbyte DCACHE1 for external memories + +- Power management: + + - Embedded regulator (LDO) and SMPSstep-down converter supporting switch + on-the-fly and voltage scaling + +- Benchmarks: + + - 1.5 DMIPS/MHz (Drystone 2.1) + - 655 CoreMark® (4.09 CoreMark®/MHz) + - 369 ULPMark™-CP + - 89 ULPMark™-PP + - 47.2 ULPMark™-CM + - 120000 SecureMark™-TLS + +- Memories: + + - 4-Mbyte flash memory with ECC, 2 banks readwhile-write, including 512 Kbytes + with 100 kcycles + - With SRAM3 ECC off: 2514-Kbyte RAM including 66 Kbytes with ECC + - With SRAM3 ECC on: 2450-Kbyte RAMincluding 322 Kbytes with ECC + - External memory interface supporting SRAM,PSRAM, NOR, NAND, and FRAM memories + - 2 Octo-SPI memory interfaces + - 16-bit HSPI memory interface up to 160 MHz + +- Rich graphic features: + + - Neo-Chrom GPU (GPU2D) accelerating any angle rotation, scaling, and + perspective correct texture mapping + - 16-Kbyte DCACHE2 + - Chrom-ART Accelerator (DMA2D) for smoothmotion and transparency effects + - Chrom-GRC (GFXMMU) allowing up to 20 % of graphic resources optimization + - MIPI® DSI host controller with two DSI lanes running at up to 500 Mbit/s each + - LCD-TFT controller (LTDC) + - Digital camera interface + +- General-purpose input/outputs: + + - Up to 156 fast I/Os with interrupt capability most 5V-tolerant and + up to 14 I/Os with independent supply down to 1.08 V + +- Clock management: + + - 4 to 50 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC (± 1 %) + - Internal low-power 32 kHz RC (± 5 %) + - 2 internal multispeed 100 kHz to 48 MHz oscillators, including one + autotrimmed by LSE (better than ± 0.25 % accuracy) + - Internal 48 MHz + - 5 PLLs for system clock, USB, audio, ADC, DSI + +- Security and cryptography: + + - SESIP3 and PSA Level 3 Certified Assurance Target + - Arm® TrustZone® and securable I/Os, memories, and peripherals + - Flexible life cycle scheme with RDP andpassword-protected debug + - Root of trust thanks to unique boot entry and secure hide-protection area (HDP) + - Secure firmware installation (SFI) thanks to embedded root secure services (RSS) + - Secure data storage with hardware unique key (HUK) + - Secure firmware upgrade support with TF-M + - 2 AES coprocessors including one with DPA resistance + - Public key accelerator, DPA resistant + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - True random number generator, NIST SP800-90B compliant + - 96-bit unique ID + - 512-byte OTP (one-time programmable) + - Active tampers + +- Up to 17 timers, 2 watchdogs and RTC: + + - 19 timers: 2 16-bit advanced motor-control, 4 32-bit, 3 16-bit general + purpose, 2 16-bit basic, 4 low-power 16-bit (available in Stop mode), + 2 SysTick timers, and 2 watchdogs + - RTC with hardware calendar, alarms, and calibration + +- Up to 25 communication peripherals: + + - 1 USB Type-C®/USB power delivery controller + - 1 USB OTG high-speed with embedded PHY + - 2 SAIs (serial audio interface) + - 6 I2C FM+(1 Mbit/s), SMBus/PMBus™ + - 7 USARTs (ISO 7816, LIN, IrDA, modem) + - 3 SPIs (6x SPIs with OCTOSPI/HSPI) + - 1 CAN FD controller + - 2 SDMMC interfaces + - 1 multifunction digital filter (6 filters) + 1 audio digital filter + with sound-activity detection + - Parallel synchronous slave interface + +- Mathematical coprocessor: + + - CORDIC for trigonometric functions acceleration + - FMAC (filter mathematical accelerator) + +- Rich analog peripherals (independent supply): + + - 2 14-bit ADC 2.5-Msps with hardware oversampling + - 1 12-bit ADC 2.5-Msps, with hardware oversampling, autonomous in Stop 2 mode + - 12-bit DAC (2 channels), low-power sample, and hold, autonomous in Stop 2 mode + - 2 operational amplifiers with built-in PGA + - 2 ultra-low-power comparators + +- ECOPACK2 compliant packages + +More information about STM32U5A5ZJ can be found here: + +- `STM32U5A5ZJ on www.st.com`_ +- `STM32U5A5 reference manual`_ + +Supported Features +================== + +The Zephyr nucleo_u5a5zj_q board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| CAN/CANFD | on-chip | canbus | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| DAC | on-chip | DAC Controller | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| BKP SRAM | on-chip | Backup SRAM | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ + + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig file: +``boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig`` + + +Connections and IOs +=================== + +Nucleo U5A5ZJ Q Board has 10 GPIO controllers. These controllers are responsible +for pin muxing, input/output, pull-up, etc. + +For mode details please refer to `STM32 Nucleo-144 board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + + +- CAN/CANFD_TX: PD1 +- CAN/CANFD_RX: PD0 +- DAC1_OUT1 : PA4 +- I2C_1_SCL : PB8 +- I2C_1_SDA : PB9 +- I2C_2_SCL : PF1 +- I2C_2_SDA : PF0 +- LD1 : PC7 +- LD2 : PB7 +- LD3 : PG2 +- LPUART_1_TX : PG7 +- LPUART_1_RX : PG8 +- SPI_1_NSS : PA4 +- SPI_1_SCK : PA5 +- SPI_1_MISO : PA6 +- SPI_1_MOSI : PA7 +- UART_1_TX : PA9 +- UART_1_RX : PA10 +- UART_2_TX : PD5 +- UART_2_RX : PD6 +- USER_PB : PC13 + +System Clock +------------ + +Nucleo U5A5ZJ Q System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +160MHz, driven by 4MHz medium speed internal oscillator. + +Serial Port +----------- + +Nucleo U5A5ZJ Q board has 6 U(S)ARTs. The Zephyr console output is assigned to +USART1. Default settings are 115200 8N1. + + +Backup SRAM +----------- + +In order to test backup SRAM you may want to disconnect VBAT from VDD. You can +do it by removing ``SB50`` jumper on the back side of the board. + + +Programming and Debugging +************************* + +Nucleo U5A5ZJ-Q board includes an ST-LINK/V3 embedded debug tool interface. +This probe allows to flash the board using various tools. + +Flashing +======== + +Board is configured to be flashed using west STM32CubeProgrammer runner. +Installation of `STM32CubeProgrammer`_ is then required to flash the board. + +Alternatively, openocd (provided in Zephyr SDK), JLink and pyocd can also be +used to flash and debug the board if west is told to use it as runner, +which can be done by passing either ``-r openocd``, ``-r jlink`` or ``-r pyocd``. + +For pyocd additional target information needs to be installed. +This can be done by executing the following commands. + +.. code-block:: console + + $ pyocd pack --update + $ pyocd pack --install stm32u5 + + +Flashing an application to Nucleo U5A5ZJ Q +------------------------------------------ + +Connect the Nucleo U5A5ZJ Q to your host computer using the USB port. +Then build and flash an application. Here is an example for the +:ref:`hello_world` application. + +Run a serial host program to connect with your Nucleo board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then build and flash the application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_u5a5zj_q + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! arm + +Debugging +========= + +Default flasher for this board is openocd. It could be used in the usual way. +Here is an example for the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_u5a5zj_q + :goals: debug + +Building a secure/non-secure with Arm ® TrustZone ® +=========================================================== + +The TF-M applications can be run on this board, thanks to its Arm ® TrustZone ® +support. +In TF-M configuration, Zephyr is run on the non-secure domain. A non-secure image +can be generated using ``nucleo_u5a5zj_q_ns`` as build target. + +.. code-block:: bash + + $ west build -b nucleo_u5a5zj_q_ns path/to/source/directory + +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +is run automatically in a post-build step to make some required flash layout changes. + +Once the build is completed, run the following script to initialize the option bytes. + +.. code-block:: bash + + $ build/tfm/regression.sh + +Finally, to flash the board, run: + +.. code-block:: bash + + $ west flash + +Note: Check the ``build/tfm`` directory to ensure that the commands required by these scripts +(``readlink``, etc.) are available on your system. Please also check ``STM32_Programmer_CLI`` +(which is used for initialization) is available in the PATH. + +.. _STM32 Nucleo-144 board User Manual: + https://www.st.com/resource/en/user_manual/um2861-stm32u5-nucleo144-board-mb1549-stmicroelectronics.pdf + +.. _STM32U5A5ZJ on www.st.com: + https://www.st.com/en/microcontrollers/stm32u5a5zj.html + +.. _STM32U5A5 reference manual: + https://www.st.com/resource/en/reference_manual/rm0456-stm32u5-series-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _STMicroelectronics customized version of OpenOCD: + https://github.com/STMicroelectronics/OpenOCD diff --git a/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi new file mode 100644 index 00000000000..d0ba893c873 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + leds: leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + blue_led_1: led_2 { + gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + red_led_1: led_3 { + gpios = <&gpiog 2 GPIO_ACTIVE_HIGH>; + label = "User LD3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + + pwm_led_1: green_led_1 { + pwms = <&pwm3 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "green led"; + }; + + pwm_led_2: blue_led_1 { + pwms = <&pwm4 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "blue led"; + }; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_msis { + status = "okay"; + msi-range = <4>; + msi-pll-mode; +}; + +&pll1 { + div-m = <1>; + mul-n = <80>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_msis>; + status = "okay"; +}; + +&rcc { + clocks = <&pll1>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pf1 &i2c2_sda_pf0>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pe12 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&dac1 { + pinctrl-0 = <&dac1_out1_pa4>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pc0>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&adc4 { + pinctrl-0 = <&adc4_in18_pb0>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&timers3 { + st,prescaler = <10000>; + status = "okay"; + + pwm3: pwm { + pinctrl-0 = <&tim3_ch2_pc7>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&timers4 { + st,prescaler = <10000>; + status = "okay"; + + pwm4: pwm { + pinctrl-0 = <&tim4_ch2_pb7>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&iwdg { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&fdcan1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>, + <&rcc STM32_SRC_PLL1_Q FDCAN1_SEL(1)>; + pinctrl-0 = <&fdcan1_rx_pd0 &fdcan1_tx_pd1>; + pinctrl-names = "default"; + bus-speed = <125000>; + bus-speed-data = <1000000>; + status = "okay"; +}; + +&vref1 { + status = "okay"; +}; + +&vbat4 { + status = "okay"; +}; diff --git a/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts new file mode 100644 index 00000000000..c9296ccab97 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "nucleo_u5a5zj_q-common.dtsi" + +/ { + model = "STMicroelectronics STM32U5A5ZJ-NUCLEO-Q board"; + compatible = "st,stm32u5a5zj-nucleo-q"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,canbus = &fdcan1; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + led0 = &blue_led_1; + sw0 = &user_button; + pwm-led0 = &pwm_led_1; + pwm-led1 = &pwm_led_2; + watchdog0 = &iwdg; + volt-sensor0 = &vref1; + volt-sensor1 = &vbat4; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Following flash partition is dedicated to the use of nucleo_u5a5zj_q + * with TZEN=0 (so w/o TFM). + */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(1952)>; + }; + slot1_partition: partition@1f8000 { + label = "image-1"; + reg = <0x001f8000 DT_SIZE_K(1960)>; + }; + storage_partition: partition@3e2000 { + label = "storage"; + reg = <0x003f0000 DT_SIZE_K(120)>; + }; + + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&gpdma1 { + status = "okay"; +}; diff --git a/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml new file mode 100644 index 00000000000..4d74f6a13b8 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml @@ -0,0 +1,24 @@ +identifier: nucleo_u5a5zj_q +name: ST Nucleo U5A5ZJ Q +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - can + - adc + - dac + - gpio + - i2c + - spi + - usart + - watchdog + - backup_sram + - dma +ram: 2450 +flash: 4096 diff --git a/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig new file mode 100644 index 00000000000..3134af0b6a7 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/nucleo_u5a5zj_q_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32U5X=y +CONFIG_SOC_STM32U5A5XX=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable clock +CONFIG_CLOCK_CONTROL=y + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable pin controller +CONFIG_PINCTRL=y diff --git a/boards/arm/nucleo_u5a5zj_q/support/openocd.cfg b/boards/arm/nucleo_u5a5zj_q/support/openocd.cfg new file mode 100644 index 00000000000..ae4ce0a8816 --- /dev/null +++ b/boards/arm/nucleo_u5a5zj_q/support/openocd.cfg @@ -0,0 +1,44 @@ +source [find interface/stlink-dap.cfg] + +set WORKAREASIZE 0x8000 + +transport select "dapdirect_swd" + +set CHIPNAME STM32U5A5ZJTxQ +set BOARDNAME NUCLEO-U5A5ZJ-Q + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# STlink Debug clock frequency +set CLOCK_FREQ 8000 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +reset_config srst_only srst_nogate connect_assert_srst +set CONNECT_UNDER_RESET 1 +set CORE_RESET 0 + +# ACCESS PORT NUMBER +set AP_NUM 0 +# GDB PORT +set GDB_PORT 3333 + +# BCTM CPU variables + +source [find target/stm32u5x.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} From 504bf0760eca33ea067d75217496139e19187fc6 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 27 Sep 2023 13:31:01 +0200 Subject: [PATCH 1384/4498] tests: drivers: dac: dac_api: add nucleo u5a5zj-q board Add Nucleo U5A5ZJ-Q board to the list of supported boards. Signed-off-by: Guillaume Gautier --- tests/drivers/dac/dac_api/src/test_dac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/dac/dac_api/src/test_dac.c b/tests/drivers/dac/dac_api/src/test_dac.c index 71824f4fd9d..9c45ea041f6 100644 --- a/tests/drivers/dac/dac_api/src/test_dac.c +++ b/tests/drivers/dac/dac_api/src/test_dac.c @@ -27,6 +27,7 @@ defined(CONFIG_BOARD_STM32H573I_DK) || \ defined(CONFIG_BOARD_B_U585I_IOT02A) || \ defined(CONFIG_BOARD_NUCLEO_U575ZI_Q) || \ + defined(CONFIG_BOARD_NUCLEO_U5A5ZJ_Q) || \ defined(CONFIG_BOARD_NUCLEO_WL55JC) || \ defined(CONFIG_BOARD_RONOTH_LODEV) From 04de62d56d3691d3c600f152a281284623130cfa Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 27 Sep 2023 13:31:46 +0200 Subject: [PATCH 1385/4498] tests: drivers: adc: adc_api: add nucleo u5a5zj-q board Add Nucleo U5A5ZJ-Q board to the list of supported boards. Signed-off-by: Guillaume Gautier --- .../adc_api/boards/nucleo_u5a5zj_q.overlay | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/nucleo_u5a5zj_q.overlay diff --git a/tests/drivers/adc/adc_api/boards/nucleo_u5a5zj_q.overlay b/tests/drivers/adc/adc_api/boards/nucleo_u5a5zj_q.overlay new file mode 100644 index 00000000000..33fbcb51723 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/nucleo_u5a5zj_q.overlay @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 1>; + }; +}; + +&adc1 { + #address-cells = <1>; + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 9eac29d532274d41ac8f82a3dd8ab4eda9d9e0da Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Wed, 27 Sep 2023 14:50:36 +0200 Subject: [PATCH 1386/4498] drivers: sensor: npm1300_charger: Correct temperature order of magnitude Changes the interpreted unit of the threshold temperatures to match the description (millidegrees). Signed-off-by: Bernt Johan Damslora --- drivers/sensor/npm1300_charger/npm1300_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c index 3049e4d7844..43ac54e8ca8 100644 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -135,7 +135,7 @@ static void calc_temp(const struct npm1300_charger_config *const config, uint16_ static uint32_t calc_ntc_res(const struct npm1300_charger_config *const config, int32_t temp_mdegc) { float inv_t0 = 1.f / 298.15f; - float temp = (float)temp_mdegc / 1000000.f; + float temp = (float)temp_mdegc / 1000.f; float inv_temp_k = 1.f / (temp + 273.15f); From 8e1b9b38f229e9e46e1b8cc85585b3acddc04869 Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Thu, 28 Sep 2023 10:45:28 +0100 Subject: [PATCH 1387/4498] MAINTAINERS: Adding ithinuel as Arm collaborator Add myself as collaborator of Arm platforms Signed-off-by: Wilfried Chauveau --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f0c4f475bb1..33f5e72c9d7 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -138,6 +138,7 @@ ARM arch: - stephanosio - bbolen - povergoing + - ithinuel files: - arch/arm/ - arch/arm/core/offsets/ From a2f1e6222efdeed75805faab6e0a3d26fcb5f2af Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Fri, 29 Sep 2023 08:53:01 +0200 Subject: [PATCH 1388/4498] samples: led_ws2812: adjustable led update delay Add a Kconfig option to adjust update frequency of the LED strip. Signed-off-by: Jeppe Odgaard --- samples/drivers/led_ws2812/Kconfig | 10 ++++++++++ samples/drivers/led_ws2812/README.rst | 3 +++ samples/drivers/led_ws2812/src/main.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/samples/drivers/led_ws2812/Kconfig b/samples/drivers/led_ws2812/Kconfig index f5cfbc2cf73..2b60e294b7a 100644 --- a/samples/drivers/led_ws2812/Kconfig +++ b/samples/drivers/led_ws2812/Kconfig @@ -6,4 +6,14 @@ config SPI default y +menu "WS2812 Sample Configuration" + +config SAMPLE_LED_UPDATE_DELAY + int "Delay between LED updates in ms" + default 50 + help + Delay between LED updates in ms. + +endmenu + source "Kconfig.zephyr" diff --git a/samples/drivers/led_ws2812/README.rst b/samples/drivers/led_ws2812/README.rst index 6c1c26bd843..5529604b0a8 100644 --- a/samples/drivers/led_ws2812/README.rst +++ b/samples/drivers/led_ws2812/README.rst @@ -74,6 +74,9 @@ For example devicetree configurations for each compatible, see Some boards are already supported out of the box; see the :file:`boards` directory for this sample for details. +The sample updates the LED strip periodically. The update frequency can be +modified by changing the :kconfig:option:`CONFIG_SAMPLE_LED_UPDATE_DELAY`. + Then build and flash the application: .. zephyr-app-commands:: diff --git a/samples/drivers/led_ws2812/src/main.c b/samples/drivers/led_ws2812/src/main.c index ee7672b38c3..d26fe6a7e91 100644 --- a/samples/drivers/led_ws2812/src/main.c +++ b/samples/drivers/led_ws2812/src/main.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(main); #define STRIP_NODE DT_ALIAS(led_strip) #define STRIP_NUM_PIXELS DT_PROP(DT_ALIAS(led_strip), chain_length) -#define DELAY_TIME K_MSEC(50) +#define DELAY_TIME K_MSEC(CONFIG_SAMPLE_LED_UPDATE_DELAY) #define RGB(_r, _g, _b) { .r = (_r), .g = (_g), .b = (_b) } From c2de739f1f32f442ff93a03c1bb95bb4f6e49881 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Mon, 25 Sep 2023 13:45:58 +0100 Subject: [PATCH 1389/4498] twister: tests: handler: fix incorrect timeout mock There is clearly an issue with current timeout value timeout into mocked_instance as this value is used only once before this mock happen, so this mock is actually useless and we always use default value. Fix that. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- scripts/tests/twister/test_handlers.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py index ad08f56f112..253f573c4fd 100644 --- a/scripts/tests/twister/test_handlers.py +++ b/scripts/tests/twister/test_handlers.py @@ -1858,7 +1858,7 @@ def test_qemuhandler_thread_update_instance_info( ), ( '1\n2\n3\n4\n5\n'.encode('utf-8'), - 6, + 60, 1, [None] * 3 + ['success'] * 7, (n for n in [100, 100, 10000]), @@ -1900,14 +1900,12 @@ def mock_cputime(pid): else: raise ProcessLookupError() + type(mocked_instance.testsuite).timeout = mock.PropertyMock(return_value=timeout) handler = QEMUHandler(mocked_instance, 'build') handler.results = {} handler.ignore_unexpected_eof = False handler.pid_fn = 'pid_fn' handler.fifo_fn = 'fifo_fn' - type(mocked_instance.testsuite).timeout = mock.PropertyMock( - return_value=timeout - ) def mocked_open(filename, *args, **kwargs): if filename == handler.pid_fn: From 80d2872a41c92354f7b9bf5a17ceca90ef55ca6d Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Thu, 21 Sep 2023 18:06:17 +0100 Subject: [PATCH 1390/4498] twister: introduce twister-level timeout multiplier Twister allows us to control maximum execution time for each test with timeout value in test's .yaml configuration and platform level timeout multiplier which allows us to tweak timeout value for specific platform. However, sometimes we want to additionally adjust tests timeouts when running twister. This is especially useful in case of simulation platform as simulation time may depend on the host speed & load, we may select different (i.e. cycle accurate but slower one) simulation method, etc... Let's introduce global (twister-level) timeout multiplier option. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- .../pylib/twister/twisterlib/environment.py | 5 +++++ scripts/pylib/twister/twisterlib/handlers.py | 19 ++++++++++++------- scripts/tests/twister/test_handlers.py | 7 ++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 0517e8ce2b7..ecb5232364b 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -196,6 +196,11 @@ def add_parse_arguments(parser = None): help="""Only run device tests with current artifacts, do not build the code""") + parser.add_argument("--timeout-multiplier", type=float, default=1, + help="""Globally adjust tests timeouts by specified multiplier. The resulting test + timeout would be multiplication of test timeout value, board-level timeout multiplier + and global timeout multiplier (this parameter)""") + test_xor_subtest.add_argument( "-s", "--test", action="append", help="Run only the specified testsuite scenario. These are named by " diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 372a8b019dc..780b51cb7de 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -81,7 +81,6 @@ def __init__(self, instance, type_str="build"): self.name = instance.name self.instance = instance - self.timeout = math.ceil(instance.testsuite.timeout * instance.platform.timeout_multiplier) self.sourcedir = instance.testsuite.source_dir self.build_dir = instance.build_dir self.log = os.path.join(self.build_dir, "handler.log") @@ -94,6 +93,11 @@ def __init__(self, instance, type_str="build"): self.args = [] self.terminated = False + def get_test_timeout(self): + return math.ceil(self.instance.testsuite.timeout * + self.instance.platform.timeout_multiplier * + self.options.timeout_multiplier) + def record(self, harness): if harness.recording: filename = os.path.join(self.build_dir, "recording.csv") @@ -189,7 +193,7 @@ def _output_handler(self, proc, harness): with open(self.log, "wt") as log_out_fp: timeout_extended = False - timeout_time = time.time() + self.timeout + timeout_time = time.time() + self.get_test_timeout() while True: this_timeout = timeout_time - time.time() if this_timeout < 0: @@ -537,7 +541,8 @@ def _create_serial_connection(self, serial_device, hardware_baud, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, - timeout=max(flash_timeout, self.timeout) # the worst case of no serial input + # the worst case of no serial input + timeout=max(flash_timeout, self.get_test_timeout()) ) except serial.SerialException as e: self.instance.status = "failed" @@ -623,7 +628,7 @@ def handle(self, harness): flash_timeout = hardware.flash_timeout if hardware.flash_with_test: - flash_timeout += self.timeout + flash_timeout += self.get_test_timeout() try: ser = self._create_serial_connection( @@ -683,7 +688,7 @@ def handle(self, harness): if not flash_error: # Always wait at most the test timeout here after flashing. - t.join(self.timeout) + t.join(self.get_test_timeout()) else: # When the flash error is due exceptions, # twister tell the monitor serial thread @@ -966,7 +971,7 @@ def handle(self, harness): self._set_qemu_filenames(sysbuild_build_dir) self.thread = threading.Thread(name=self.name, target=QEMUHandler._thread, - args=(self, self.timeout, self.build_dir, + args=(self, self.get_test_timeout(), self.build_dir, self.log_fn, self.fifo_fn, self.pid_fn, self.results, harness, self.ignore_unexpected_eof)) @@ -986,7 +991,7 @@ def handle(self, harness): logger.debug("Spawning QEMUHandler Thread for %s" % self.name) try: - proc.wait(self.timeout) + proc.wait(self.get_test_timeout()) except subprocess.TimeoutExpired: # sometimes QEMU can't handle SIGTERM signal correctly # in that case kill -9 QEMU process directly and leave diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py index 253f573c4fd..6675c4ae451 100644 --- a/scripts/tests/twister/test_handlers.py +++ b/scripts/tests/twister/test_handlers.py @@ -420,6 +420,7 @@ def wait(self, *args, **kwargs): handler = BinaryHandler(mocked_instance, 'build') handler.terminate = mock.Mock() + handler.options = mock.Mock(timeout_multiplier=1) proc = MockProc(1, proc_stdout) @@ -1208,6 +1209,7 @@ def mock_serial(*args, **kwargs): handler.instance.add_missing_case_status = missing_mock available_mock = mock.Mock() handler.make_device_available = available_mock + handler.options = mock.Mock(timeout_multiplier=1) hardware_baud = 14400 flash_timeout = 60 @@ -1375,6 +1377,7 @@ def mock_popen(command, *args, **kwargs): handler = DeviceHandler(mocked_instance, 'build') handler.get_hardware = mock.Mock(return_value=hardware) handler.options = mock.Mock( + timeout_multiplier=1, west_flash=None, west_runner=None ) @@ -1906,6 +1909,7 @@ def mock_cputime(pid): handler.ignore_unexpected_eof = False handler.pid_fn = 'pid_fn' handler.fifo_fn = 'fifo_fn' + handler.options = mock.Mock(timeout_multiplier=1) def mocked_open(filename, *args, **kwargs): if filename == handler.pid_fn: @@ -1956,7 +1960,7 @@ def mocked_open(filename, *args, **kwargs): mock_thread_update_instance_info): QEMUHandler._thread( handler, - handler.timeout, + handler.get_test_timeout(), handler.build_dir, handler.log, handler.fifo_fn, @@ -2035,6 +2039,7 @@ def mock_filenames(sysbuild_build_dir): command = ['generator_cmd', '-C', os.path.join('cmd', 'path'), 'run'] handler.options = mock.Mock( + timeout_multiplier=1, west_flash=handler_options_west_flash, west_runner=None ) From 5133f62523e7895e3dde4ee228c28287bec7ace6 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Thu, 28 Sep 2023 00:28:26 +0100 Subject: [PATCH 1391/4498] doc: twister: add chapter about managing tests timeouts Document timeout_multiplier board.yaml option and --timeout-multiplier twister option. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- doc/develop/test/twister.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 5f61e6ec810..445fc020b9b 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -195,6 +195,14 @@ testing: only_tags: Only execute tests with this list of tags on a specific platform. + .. _twister_board_timeout_multiplier: + + timeout_multiplier: (default 1) + Multiply each test case timeout by specified ratio. This option allows to tune timeouts only + for required platform. It can be useful in case naturally slow platform I.e.: HW board with + power-efficient but slow CPU or simulation platform which can perform instruction accurate + simulation but does it slowly. + Test Cases ********** @@ -359,6 +367,8 @@ min_flash: minimum amount of ROM in KB needed for this test to build and run. This is compared with information provided by the board metadata. +.. _twister_test_case_timeout: + timeout: Length of time to run test before automatically killing it. Default to 60 seconds. @@ -660,6 +670,22 @@ line break instead of white spaces. Most everyday users will run with no arguments. +Managing tests timeouts +*********************** + +There are several parameters which control tests timeouts on various levels: + +* ``timeout`` option in each test case. See :ref:`here ` for more + details. +* ``timeout_multiplier`` option in board configuration. See + :ref:`here ` for more details. +* ``--timeout-multiplier`` twister option which can be used to adjust timeouts in exact twister run. + It can be useful in case of simulation platform as simulation time may depend on the host + speed & load or we may select different simulation method (i.e. cycle accurate but slower + one), etc... + +Overall test case timeout is a multiplication of these three parameters. + Running in Integration Mode *************************** From bc6962b7551df3e172c8e63f3fd7845f54202b01 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 19:38:56 +0200 Subject: [PATCH 1392/4498] tests: Bluetooth: Add inval testing of bt_bap_broadcast_source_delete Add invalid parameter and state testing of bt_bap_broadcast_source_delete Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index ee7c4989de1..b08705d51d7 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -743,3 +743,34 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval err = bt_bap_broadcast_source_reconfig(source, param); zassert_not_equal(0, err, "Did not fail with deleted broadcast source"); } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_delete_inval_source_null) +{ + int err; + + err = bt_bap_broadcast_source_delete(NULL); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_delete_inval_double_start) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source *source; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to start broadcast source: err %d", err); + + source = fixture->source; + /* Set to NULL to avoid deleting it in bap_broadcast_source_test_suite_after */ + fixture->source = NULL; + + err = bt_bap_broadcast_source_delete(source); + zassert_not_equal(0, err, "Did not fail with deleting already deleting source"); +} From 62787bd208e4254e6bbdc9a03463936229e16bf3 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 19:39:26 +0200 Subject: [PATCH 1393/4498] tests: bsim: Bluetooth: Remove broadcast_source_delete_inval Removed the tests for invalid bt_bap_broadcast_source_delete parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 138cd6e1bfc..5d226bfa5d4 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -839,30 +839,6 @@ static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source) } } -static void test_broadcast_source_delete_inval_state(struct bt_bap_broadcast_source *source) -{ - int err; - - printk("Test bt_bap_broadcast_source_delete in streaming state\n"); - err = bt_bap_broadcast_source_delete(NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_delete in streaming state not fail\n"); - return; - } -} - -static void test_broadcast_source_delete_inval(void) -{ - int err; - - printk("Test bt_bap_broadcast_source_delete with NULL source\n"); - err = bt_bap_broadcast_source_delete(NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_delete with NULL source did not fail\n"); - return; - } -} - static void test_broadcast_source_delete(struct bt_bap_broadcast_source *source) { int err; @@ -956,13 +932,10 @@ static void test_main(void) /* Keeping running for a little while */ k_sleep(K_SECONDS(5)); - test_broadcast_source_delete_inval_state(source); - test_broadcast_source_stop_inval(); test_broadcast_source_stop(source); test_broadcast_source_stop_inval_state(source); - test_broadcast_source_delete_inval(); test_broadcast_source_delete(source); source = NULL; From 638316cbb5c8e23b2db76d163178e5e764566e57 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 11:51:09 +0200 Subject: [PATCH 1394/4498] tests: Bluetooth: Add inval test of bt_bap_broadcast_source_create Add unit tests that tests invalid parameters for the bt_bap_broadcast_source_create function. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index b08705d51d7..5b7af42dfbc 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -224,6 +224,238 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_start_send fixture->source = NULL; } +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_param_null) +{ + int err; + + err = bt_bap_broadcast_source_create(NULL, &fixture->source); + zassert_not_equal(0, err, "Did not fail with null params"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_source_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + err = bt_bap_broadcast_source_create(create_param, NULL); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_subgroup_params_count_0) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + create_param->params_count = 0U; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with params_count %u", create_param->params_count); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_count_above_max) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + create_param->params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT + 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with params_count %u", create_param->params_count); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_subgroup_params_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + int err; + + create_param->params = NULL; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + create_param->params = subgroup_params; + zassert_not_equal(0, err, "Did not fail with NULL subgroup params"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_qos_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_audio_codec_qos *qos = create_param->qos; + int err; + + create_param->qos = NULL; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + create_param->qos = qos; + zassert_not_equal(0, err, "Did not fail with NULL qos"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_packing) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + create_param->packing = 0x02; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with packing %u", create_param->packing); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_params_count_0) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + int err; + + subgroup_params->params_count = 0U; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with %u stream params", + subgroup_params->params_count); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_params_count_above_max) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + int err; + + subgroup_params->params_count = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT + 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with %u stream params", + subgroup_params->params_count); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_stream_params_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + int err; + + subgroup_params->params = NULL; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + subgroup_params->params = stream_params; + zassert_not_equal(0, err, "Did not fail with NULL stream params"); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_codec_cfg_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + subgroup_params->codec_cfg = NULL; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + subgroup_params->codec_cfg = codec_cfg; + zassert_not_equal(0, err, "Did not fail with NULL codec_cfg"); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_codec_cfg_data_len) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + codec_cfg->data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with codec_cfg->data_len %zu", codec_cfg->data_len); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_codec_cfg_meta_len) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + codec_cfg->meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with codec_cfg->meta_len %zu", codec_cfg->meta_len); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_codec_cfg_cid) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + codec_cfg->id = BT_HCI_CODING_FORMAT_LC3; + codec_cfg->cid = 0x01; /* Shall be 0 if id == 0x06 (LC3)*/ + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with codec_cfg->cid %u", codec_cfg->cid); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_subgroup_params_codec_cfg_vid) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_audio_codec_cfg *codec_cfg = subgroup_params->codec_cfg; + int err; + + codec_cfg->id = BT_HCI_CODING_FORMAT_LC3; + codec_cfg->vid = 0x01; /* Shall be 0 if id == 0x06 (LC3)*/ + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with codec_cfg->vid %u", codec_cfg->vid); +} + +ZTEST_F(bap_broadcast_source_test_suite, + test_broadcast_source_create_inval_stream_params_stream_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + struct bt_bap_stream *stream = stream_params->stream; + int err; + + stream_params->stream = NULL; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + stream_params->stream = stream; + zassert_not_equal(0, err, "Did not fail with NULL stream_params->stream"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_stream_params_data_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + uint8_t *data = stream_params->data; + int err; + + stream_params->data = NULL; + stream_params->data_len = 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + /* Restore the params for the cleanup after function */ + stream_params->data = data; + zassert_not_equal( + 0, err, + "Did not fail with NULL stream_params->data and stream_params_>data_len %zu", + stream_params->data_len); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_inval_stream_params_data_len) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source_subgroup_param *subgroup_params = &create_param->params[0]; + struct bt_bap_broadcast_source_stream_param *stream_params = &subgroup_params->params[0]; + int err; + + stream_params->data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_not_equal(0, err, "Did not fail with stream_params_>data_len %zu", + stream_params->data_len); +} + ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_source_null) { struct bt_bap_broadcast_source_param *create_param = fixture->param; From 1442a6cf5bfe0fa3d486587c28af97f172649a6c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 13:24:45 +0200 Subject: [PATCH 1395/4498] tests: bsim: Bluetooth: Remove bsim testing of broadcast create inval Removing the babblesim testing of the invalid parameters for bt_bap_broadcast_source_create as they are now done in a unit test instead. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 440 ------------------ 1 file changed, 440 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 5d226bfa5d4..70e44d30f34 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -97,445 +97,6 @@ static struct bt_bap_stream_ops stream_ops = { .sent = sent_cb }; -static uint8_t valid_bis_codec_data[] = {BT_AUDIO_CODEC_DATA( - BT_AUDIO_CODEC_CONFIG_LC3_FREQ, BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ))}; - -static void -broadcast_source_inval_reset_param(struct bt_bap_broadcast_source_param *param, - struct bt_bap_broadcast_source_subgroup_param *subgroup_param, - struct bt_bap_broadcast_source_stream_param *stream_param) -{ - struct bt_bap_broadcast_source_stream_param valid_stream_param; - struct bt_bap_broadcast_source_subgroup_param valid_subgroup_param; - struct bt_bap_broadcast_source_param create_param; - - valid_stream_param.stream = &broadcast_source_streams[0]; - valid_stream_param.data_len = ARRAY_SIZE(valid_bis_codec_data); - valid_stream_param.data = valid_bis_codec_data; - - valid_subgroup_param.params_count = 1U; - valid_subgroup_param.params = &valid_stream_param; - valid_subgroup_param.codec_cfg = &preset_16_2_1.codec_cfg; - - create_param.params_count = 1U; - create_param.params = &valid_subgroup_param; - create_param.qos = &preset_16_2_1.qos; - create_param.packing = BT_ISO_PACKING_SEQUENTIAL; - create_param.encryption = false; - - memcpy(param, &create_param, sizeof(create_param)); - memcpy(subgroup_param, &valid_subgroup_param, sizeof(valid_subgroup_param)); - memcpy(stream_param, &valid_stream_param, sizeof(valid_stream_param)); - param->params = subgroup_param; - subgroup_param->params = stream_param; -} - -static void broadcast_source_create_inval_stream_param(void) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param create_param; - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_bap_broadcast_source *broadcast_source; - int err; - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Set data NULL while count is 1 */ - stream_param.data = NULL; - - printk("Test bt_bap_broadcast_source_create with NULL stream_param\n"); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL stream_param data did not " - "fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Initialize codec configuration data that is too large */ - stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_create with stream_param.data_len %zu\n", - stream_param.data_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with stream_param data len %u " - "did not fail\n", - stream_param.data_len); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Set stream to NULL */ - stream_param.stream = NULL; - - printk("Test bt_bap_broadcast_source_create with NULL stream_param.stream\n"); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL stream_param stream " - "did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { - uint8_t bis_codec_data[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1] = {0}; - - memcpy(bis_codec_data, valid_bis_codec_data, ARRAY_SIZE(valid_bis_codec_data)); - - /* Set LTV data to invalid size */ - stream_param.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - stream_param.data = bis_codec_data; - - printk("Test bt_bap_broadcast_source_create with CC LTV size %u\n", - stream_param.data_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with CC LTV size %u in stream_param " - "did not fail\n", - stream_param.data_len); - return; - } - } -} - -static void broadcast_source_create_inval_subgroup_codec_param(void) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param create_param; - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_bap_broadcast_source *broadcast_source; - struct bt_audio_codec_cfg codec_cfg; - int err; - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); - - codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_create with codec.data_len %zu\n", codec_cfg.data_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with codec data len %zu did not fail\n", - codec_cfg.data_len); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = - memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, sizeof(preset_16_2_1.codec_cfg)); - - codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_create with codec.meta_len %zu\n", codec_cfg.meta_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with codec meta len %zu did not fail\n", - codec_cfg.meta_len); - return; - } - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE < 255) { - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, - sizeof(preset_16_2_1.codec_cfg)); - - /* Set LTV data to invalid size */ - codec_cfg.data_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_create with CC LTV size %u\n", - codec_cfg.data_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with CC LTV size %zu in " - "subgroup_param did not fail\n", - codec_cfg.data_len); - return; - } - } - - if (CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE < 255) { - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - subgroup_param.codec_cfg = memcpy(&codec_cfg, &preset_16_2_1.codec_cfg, - sizeof(preset_16_2_1.codec_cfg)); - - /* Set LTV data to invalid size */ - codec_cfg.meta_len = CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE + 1; - - printk("Test bt_bap_broadcast_source_create with Meta LTV size %u\n", - codec_cfg.meta_len); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with meta LTV size %zu in " - "subgroup_param did not fail\n", - codec_cfg.meta_len); - return; - } - } -} - -static void broadcast_source_create_inval_subgroup_param(void) -{ - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param create_param; - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_bap_broadcast_source *broadcast_source; - int err; - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Set count to 0 */ - subgroup_param.params_count = 0; - - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with 0 stream_param count did not fail\n"); - return; - } - - /* Set count higher than max */ - subgroup_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT + 1; - - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with too high stream_param count did not " - "fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Set params to NULL */ - subgroup_param.params = NULL; - - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL stream_param did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - /* Set codec to NULL */ - subgroup_param.codec_cfg = NULL; - - err = bt_bap_broadcast_source_create(&create_param, &broadcast_source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL codec did not fail\n"); - return; - } - - /* Invalid codec values */ - broadcast_source_create_inval_subgroup_codec_param(); -} - -static void broadcast_source_create_inval(void) -{ - struct bt_bap_broadcast_source_stream_param stream_param; - struct bt_bap_broadcast_source_subgroup_param subgroup_param; - struct bt_bap_broadcast_source_param create_param; - struct bt_bap_broadcast_source *broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT + 1U]; - struct bt_audio_codec_qos qos; - int err; - - /* Test NULL parameters */ - printk("Test bt_bap_broadcast_source_create with NULL param\n"); - err = bt_bap_broadcast_source_create(NULL, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL param did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_create with NULL broadcast source\n"); - err = bt_bap_broadcast_source_create(&create_param, NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL broadcast source did not " - "fail\n"); - return; - } - - /* Test stream_param values */ - broadcast_source_create_inval_stream_param(); - - /* Test invalid subgroup_param values*/ - broadcast_source_create_inval_subgroup_param(); - - /* Invalid create_param values */ - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - create_param.params_count = 0; - - printk("Test bt_bap_broadcast_source_create with 0 params_count\n"); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with 0 params_count did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - create_param.params = NULL; - - printk("Test bt_bap_broadcast_source_create with NULL params\n"); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL params did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - create_param.packing = 0x35; - - printk("Test bt_bap_broadcast_source_create with packing 0x%02X\n", create_param.packing); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with invalid packing did not fail\n"); - return; - } - - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - create_param.qos = NULL; - - printk("Test bt_bap_broadcast_source_create with NULL qos\n"); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with NULL qos did not fail\n"); - return; - } - - /* Invalid QoS values */ - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - create_param.qos = memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - qos.phy = BT_AUDIO_CODEC_QOS_CODED + 1; - - printk("Test bt_bap_broadcast_source_create with qos.phy 0x%02X\n", qos.phy); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with invalid PHY did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.framing = BT_AUDIO_CODEC_QOS_FRAMING_FRAMED + 1; - - printk("Test bt_bap_broadcast_source_create with qos.framing 0x%02X\n", qos.framing); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with invalid framing did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.rtn = BT_ISO_BROADCAST_RTN_MAX + 1; - - printk("Test bt_bap_broadcast_source_create with qos.rtn 0x%02X\n", qos.rtn); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with invalid RTN did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.sdu = BT_ISO_MAX_SDU + 1; - - printk("Test bt_bap_broadcast_source_create with qos.sdu 0x%02X\n", qos.sdu); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with invalid SDU size did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.latency = BT_ISO_LATENCY_MIN - 1; - - printk("Test bt_bap_broadcast_source_create with qos.latency 0x%02X\n", qos.latency); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with too low latency did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.latency = BT_ISO_LATENCY_MAX + 1; - - printk("Test bt_bap_broadcast_source_create with qos.latency 0x%02X\n", qos.latency); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with too high latency did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.interval = BT_ISO_SDU_INTERVAL_MIN - 1; - - printk("Test bt_bap_broadcast_source_create with qos.interval 0x%02X\n", qos.interval); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with too low interval did not fail\n"); - return; - } - - memcpy(&qos, &preset_16_2_1.qos, sizeof(preset_16_2_1.qos)); - - qos.interval = BT_ISO_SDU_INTERVAL_MAX + 1; - - printk("Test bt_bap_broadcast_source_create with qos.interval 0x%02X\n", qos.interval); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with too high interval did not fail\n"); - return; - } - - /* Exceeding memory limits */ - broadcast_source_inval_reset_param(&create_param, &subgroup_param, &stream_param); - - printk("Test bt_bap_broadcast_source_create with %zu broadcast sources\n", - ARRAY_SIZE(broadcast_sources)); - for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources); i++) { - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[i]); - - if (i < CONFIG_BT_BAP_BROADCAST_SRC_COUNT) { - if (err != 0) { - FAIL("bt_bap_broadcast_source_create[%zu] failed: %d\n", i, err); - return; - } - } else { - if (err == 0) { - FAIL("bt_bap_broadcast_source_create[%zu] did not fail\n", i); - return; - } - } - } - - for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources) - 1; i++) { - err = bt_bap_broadcast_source_delete(broadcast_sources[i]); - if (err != 0) { - FAIL("bt_bap_broadcast_source_delete[%zu] failed: %d\n", i, err); - return; - } - broadcast_sources[i] = NULL; - } - - create_param.params_count = CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT + 1; - - printk("Test bt_bap_broadcast_source_create with %zu subgroups\n", - create_param.params_count); - err = bt_bap_broadcast_source_create(&create_param, &broadcast_sources[0]); - if (err == 0) { - FAIL("bt_bap_broadcast_source_create with %zu subgroups did not fail\n", - create_param.params_count); - return; - } -} - static int setup_broadcast_source(struct bt_bap_broadcast_source **source) { uint8_t bis_codec_data[] = { @@ -893,7 +454,6 @@ static void test_main(void) printk("Bluetooth initialized\n"); - broadcast_source_create_inval(); err = setup_broadcast_source(&source); if (err != 0) { FAIL("Unable to setup broadcast source: %d\n", err); From 711c17182f401101390ce30a132c531aade01bd9 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 28 Sep 2023 16:17:06 -0700 Subject: [PATCH 1396/4498] kernel: s/k_current_get/_current Running inside kernel we can use _current instead of k_current_get that can lead to additional function call checks. Signed-off-by: Flavio Ceolin --- kernel/fatal.c | 2 +- kernel/userspace.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/fatal.c b/kernel/fatal.c index a94aecd1cca..19c4de7e214 100644 --- a/kernel/fatal.c +++ b/kernel/fatal.c @@ -101,7 +101,7 @@ void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) */ unsigned int key = arch_irq_lock(); struct k_thread *thread = IS_ENABLED(CONFIG_MULTITHREADING) ? - k_current_get() : NULL; + _current : NULL; /* twister looks for the "ZEPHYR FATAL ERROR" string, don't * change it without also updating twister diff --git a/kernel/userspace.c b/kernel/userspace.c index 27988805b7d..ed36bec929c 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -785,7 +785,7 @@ void z_object_recycle(const void *obj) if (ko != NULL) { (void)memset(ko->perms, 0, sizeof(ko->perms)); - z_thread_perms_set(ko, k_current_get()); + z_thread_perms_set(ko, _current); ko->flags |= K_OBJ_FLAG_INITIALIZED; } } From 121d051c9a6b75e41c851103d973a37e8c7ae090 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 28 Sep 2023 16:21:06 -0700 Subject: [PATCH 1397/4498] kernel: fatal: Remove redundant function We don't need re-implement a function to get the current cpu. Simply use _current_cpu that even contains additional sanity checks. Signed-off-by: Flavio Ceolin --- kernel/fatal.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/kernel/fatal.c b/kernel/fatal.c index 19c4de7e214..7a3733cbfef 100644 --- a/kernel/fatal.c +++ b/kernel/fatal.c @@ -84,15 +84,6 @@ FUNC_NORETURN void k_fatal_halt(unsigned int reason) } /* LCOV_EXCL_STOP */ -static inline int get_cpu(void) -{ -#if defined(CONFIG_SMP) - return arch_curr_cpu()->id; -#else - return 0; -#endif -} - void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) { /* We can't allow this code to be preempted, but don't need to @@ -107,7 +98,7 @@ void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) * change it without also updating twister */ LOG_ERR(">>> ZEPHYR FATAL ERROR %d: %s on CPU %d", reason, - reason_to_str(reason), get_cpu()); + reason_to_str(reason), _current_cpu->id); /* FIXME: This doesn't seem to work as expected on all arches. * Need a reliable way to determine whether the fault happened when From 01757cfd32cd0215a52f0fcac4cc9c97b7cf8927 Mon Sep 17 00:00:00 2001 From: Henrik Lindblom Date: Sat, 4 Mar 2023 08:38:45 +0200 Subject: [PATCH 1398/4498] modbus: add support for defining custom functions Enables support for custom function codes. Modbus specification allows vendor specific function codes in the range 65-72 & 100-110 [1] and this feature allows users to implement custom logic for those codes. Additionally, since the Zephyr Modbus stack doesn't implement all defined Modbus fcs this feature allows users to add support for codes outside the basic register reading / writing functionality offered by Zephyr. Custom function codes can be added on a per-interface basis and the handler structures are allocated by the caller. [1]: https://modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf Signed-off-by: Henrik Lindblom --- include/zephyr/modbus/modbus.h | 87 ++++++++++++++++++++++++++++++++- subsys/modbus/modbus_core.c | 36 ++++++++++++++ subsys/modbus/modbus_internal.h | 14 +----- subsys/modbus/modbus_server.c | 38 ++++++++++++-- 4 files changed, 158 insertions(+), 17 deletions(-) diff --git a/include/zephyr/modbus/modbus.h b/include/zephyr/modbus/modbus.h index 45fc6fd0f21..1fba0ac669d 100644 --- a/include/zephyr/modbus/modbus.h +++ b/include/zephyr/modbus/modbus.h @@ -31,7 +31,7 @@ #define ZEPHYR_INCLUDE_MODBUS_H_ #include - +#include #ifdef __cplusplus extern "C" { #endif @@ -41,6 +41,22 @@ extern "C" { /** Length of MBAP Header plus function code */ #define MODBUS_MBAP_AND_FC_LENGTH (MODBUS_MBAP_LENGTH + 1) +/** @name Modbus exception codes + * @{ + */ +/* Modbus exception codes */ +#define MODBUS_EXC_NONE 0 +#define MODBUS_EXC_ILLEGAL_FC 1 +#define MODBUS_EXC_ILLEGAL_DATA_ADDR 2 +#define MODBUS_EXC_ILLEGAL_DATA_VAL 3 +#define MODBUS_EXC_SERVER_DEVICE_FAILURE 4 +#define MODBUS_EXC_ACK 5 +#define MODBUS_EXC_SERVER_DEVICE_BUSY 6 +#define MODBUS_EXC_MEM_PARITY_ERROR 8 +#define MODBUS_EXC_GW_PATH_UNAVAILABLE 10 +#define MODBUS_EXC_GW_TARGET_FAILED_TO_RESP 11 +/** @} */ + /** * @brief Frame struct used internally and for raw ADU support. */ @@ -384,6 +400,57 @@ int modbus_iface_get_by_name(const char *iface_name); typedef int (*modbus_raw_cb_t)(const int iface, const struct modbus_adu *adu, void *user_data); +/** + * @brief Custom function code handler function signature. + * + * Modbus allows user defined function codes which can be used to extend + * the base protocol. These callbacks can also be used to implement + * function codes currently not supported by Zephyr's Modbus subsystem. + * + * If an error occurs during the handling of the request, the handler should + * signal this by setting excep_code to a modbus exception code. + * + * User data pointer can be used to pass state between subsequent calls to + * the handler. + * + * @param iface Modbus interface index + * @param rx_adu Pointer to the received ADU struct + * @param tx_adu Pointer to the outgoing ADU struct + * @param excep_code Pointer to possible exception code + * @param user_data Pointer to user data + * + * @retval true If response should be sent, false otherwise + */ +typedef bool (*modbus_custom_cb_t)(const int iface, + const struct modbus_adu *const rx_adu, + struct modbus_adu *const tx_adu, + uint8_t *const excep_code, + void *const user_data); + +/** @cond INTERNAL_HIDDEN */ +/** + * @brief Custom function code definition. + */ +struct modbus_custom_fc { + sys_snode_t node; + modbus_custom_cb_t cb; + void *user_data; + uint8_t fc; + uint8_t excep_code; +}; +/** @endcond INTERNAL_HIDDEN */ + +/** + * @brief Helper macro for initializing custom function code structs + */ +#define MODBUS_CUSTOM_FC_DEFINE(name, user_cb, user_fc, userdata) \ + static struct modbus_custom_fc modbus_cfg_##name = { \ + .cb = user_cb, \ + .user_data = userdata, \ + .fc = user_fc, \ + .excep_code = MODBUS_EXC_NONE, \ + } + /** * @brief Modbus interface mode */ @@ -535,6 +602,24 @@ void modbus_raw_set_server_failure(struct modbus_adu *adu); */ int modbus_raw_backend_txn(const int iface, struct modbus_adu *adu); +/** + * @brief Register a user-defined function code handler. + * + * The Modbus specification allows users to define standard function codes + * missing from Zephyr's Modbus implementation as well as add non-standard + * function codes in the ranges 65 to 72 and 100 to 110 (decimal), as per + * specification. + * + * This function registers a new handler at runtime for the given + * function code. + * + * @param iface Modbus client interface index + * @param custom_fc User defined function code and callback pair + * + * @retval 0 on success + */ +int modbus_register_user_fc(const int iface, struct modbus_custom_fc *custom_fc); + #ifdef __cplusplus } #endif diff --git a/subsys/modbus/modbus_core.c b/subsys/modbus/modbus_core.c index 617f5833a40..777887f2275 100644 --- a/subsys/modbus/modbus_core.c +++ b/subsys/modbus/modbus_core.c @@ -211,6 +211,14 @@ static struct modbus_context *modbus_init_iface(const uint8_t iface) return ctx; } +static int modbus_user_fc_init(struct modbus_context *ctx, struct modbus_iface_param param) +{ + sys_slist_init(&ctx->user_defined_cbs); + LOG_DBG("Initializing user-defined function code support."); + + return 0; +} + int modbus_init_server(const int iface, struct modbus_iface_param param) { struct modbus_context *ctx = NULL; @@ -236,6 +244,12 @@ int modbus_init_server(const int iface, struct modbus_iface_param param) ctx->client = false; + if (modbus_user_fc_init(ctx, param) != 0) { + LOG_ERR("Failed to init MODBUS user defined function codes"); + rc = -EINVAL; + goto init_server_error; + } + switch (param.mode) { case MODBUS_MODE_RTU: case MODBUS_MODE_ASCII: @@ -278,6 +292,28 @@ int modbus_init_server(const int iface, struct modbus_iface_param param) return rc; } +int modbus_register_user_fc(const int iface, struct modbus_custom_fc *custom_fc) +{ + struct modbus_context *ctx = modbus_get_context(iface); + + if (!custom_fc) { + LOG_ERR("Provided function code handler was NULL"); + return -EINVAL; + } + + if (custom_fc->fc & BIT(7)) { + LOG_ERR("Function codes must have MSB of 0"); + return -EINVAL; + } + + custom_fc->excep_code = MODBUS_EXC_NONE; + + LOG_DBG("Registered new custom function code %d", custom_fc->fc); + sys_slist_append(&ctx->user_defined_cbs, &custom_fc->node); + + return 0; +} + int modbus_init_client(const int iface, struct modbus_iface_param param) { struct modbus_context *ctx = NULL; diff --git a/subsys/modbus/modbus_internal.h b/subsys/modbus/modbus_internal.h index f271e08941c..080da58ea09 100644 --- a/subsys/modbus/modbus_internal.h +++ b/subsys/modbus/modbus_internal.h @@ -55,18 +55,6 @@ #define MODBUS_FC08_SUBF_SERVER_MSG_CTR 14 #define MODBUS_FC08_SUBF_SERVER_NO_RESP_CTR 15 -/* Modbus exception codes */ -#define MODBUS_EXC_NONE 0 -#define MODBUS_EXC_ILLEGAL_FC 1 -#define MODBUS_EXC_ILLEGAL_DATA_ADDR 2 -#define MODBUS_EXC_ILLEGAL_DATA_VAL 3 -#define MODBUS_EXC_SERVER_DEVICE_FAILURE 4 -#define MODBUS_EXC_ACK 5 -#define MODBUS_EXC_SERVER_DEVICE_BUSY 6 -#define MODBUS_EXC_MEM_PARITY_ERROR 8 -#define MODBUS_EXC_GW_PATH_UNAVAILABLE 10 -#define MODBUS_EXC_GW_TARGET_FAILED_TO_RESP 11 - /* Modbus RTU (ASCII) constants */ #define MODBUS_COIL_OFF_CODE 0x0000 #define MODBUS_COIL_ON_CODE 0xFF00 @@ -142,6 +130,8 @@ struct modbus_context { uint16_t mbs_server_msg_ctr; uint16_t mbs_noresp_ctr; #endif + /* A linked list of function code, handler pairs */ + sys_slist_t user_defined_cbs; /* Unit ID */ uint8_t unit_id; diff --git a/subsys/modbus/modbus_server.c b/subsys/modbus/modbus_server.c index 58a783864c6..4805526b2d6 100644 --- a/subsys/modbus/modbus_server.c +++ b/subsys/modbus/modbus_server.c @@ -926,6 +926,38 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx) return true; } +static bool mbs_try_user_fc(struct modbus_context *ctx, uint8_t fc) +{ + struct modbus_custom_fc *p; + + LOG_DBG("Searching for custom Modbus handlers for code %u", fc); + + SYS_SLIST_FOR_EACH_CONTAINER(&ctx->user_defined_cbs, p, node) { + if (p->fc == fc) { + int iface = modbus_iface_get_by_ctx(ctx); + bool rval; + + LOG_DBG("Found custom handler"); + + p->excep_code = MODBUS_EXC_NONE; + rval = p->cb(iface, &ctx->rx_adu, &ctx->tx_adu, &p->excep_code, + p->user_data); + + if (p->excep_code != MODBUS_EXC_NONE) { + LOG_INF("Custom handler failed with code %d", p->excep_code); + mbs_exception_rsp(ctx, p->excep_code); + } + + return rval; + } + } + + LOG_ERR("Function code 0x%02x not implemented", fc); + mbs_exception_rsp(ctx, MODBUS_EXC_ILLEGAL_FC); + + return true; +} + bool modbus_server_handler(struct modbus_context *ctx) { bool send_reply = false; @@ -945,6 +977,7 @@ bool modbus_server_handler(struct modbus_context *ctx) } if (addr != 0 && addr != ctx->unit_id) { + LOG_DBG("Unit ID doesn't match %u != %u", addr, ctx->unit_id); update_noresp_ctr(ctx); return false; } @@ -995,10 +1028,7 @@ bool modbus_server_handler(struct modbus_context *ctx) break; default: - LOG_ERR("Function code 0x%02x not implemented", fc); - mbs_exception_rsp(ctx, MODBUS_EXC_ILLEGAL_FC); - send_reply = true; - break; + send_reply = mbs_try_user_fc(ctx, fc); } if (addr == 0) { From 1f65c9be8782ac77fc7aaaf6105e72b293803d09 Mon Sep 17 00:00:00 2001 From: Henrik Lindblom Date: Sun, 5 Mar 2023 09:48:48 +0200 Subject: [PATCH 1399/4498] samples: modbus: add user function code example Demonstrate user function codes with a simple example with a user defined fc that maps to a function that just increments a counter every time it's read. Signed-off-by: Henrik Lindblom --- samples/subsys/modbus/tcp_server/src/main.c | 46 ++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/samples/subsys/modbus/tcp_server/src/main.c b/samples/subsys/modbus/tcp_server/src/main.c index 15ca917a175..163fca98fc6 100644 --- a/samples/subsys/modbus/tcp_server/src/main.c +++ b/samples/subsys/modbus/tcp_server/src/main.c @@ -26,6 +26,43 @@ static const struct gpio_dt_spec led_dev[] = { GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios), }; +static int custom_read_count; + +static bool custom_handler(const int iface, + const struct modbus_adu *rx_adu, + struct modbus_adu *tx_adu, + uint8_t *const excep_code, + void *const user_data) +{ + const uint8_t request_len = 2; + const uint8_t response_len = 6; + int *read_counter = (int *)user_data; + uint8_t subfunc; + uint8_t data_len; + + LOG_INF("Custom Modbus handler called"); + + if (rx_adu->length != request_len) { + LOG_WRN("Custom request length doesn't match"); + *excep_code = MODBUS_EXC_ILLEGAL_DATA_VAL; + return true; + } + + subfunc = rx_adu->data[0]; + data_len = rx_adu->data[1]; + + LOG_INF("Custom function called with subfunc=%u, data_len=%u", subfunc, data_len); + (*read_counter)++; + sys_put_be16(0x5555, tx_adu->data); + sys_put_be16(0xAAAA, &tx_adu->data[2]); + sys_put_be16(*read_counter, &tx_adu->data[4]); + tx_adu->length = response_len; + + return true; +} + +MODBUS_CUSTOM_FC_DEFINE(custom, custom_handler, 101, &custom_read_count); + static int init_leds(void) { int err; @@ -155,6 +192,7 @@ const static struct modbus_iface_param server_param = { static int init_modbus_server(void) { char iface_name[] = "RAW_0"; + int err; server_iface = modbus_iface_get_by_name(iface_name); @@ -164,7 +202,13 @@ static int init_modbus_server(void) return -ENODEV; } - return modbus_init_server(server_iface, server_param); + err = modbus_init_server(server_iface, server_param); + + if (err < 0) { + return err; + } + + return modbus_register_user_fc(server_iface, &modbus_cfg_custom); } static int modbus_tcp_reply(int client, struct modbus_adu *adu) From 7bc93a62b8173b7fe5c27cc75f58a28547b82e45 Mon Sep 17 00:00:00 2001 From: Pawel Osypiuk Date: Wed, 22 Mar 2023 12:11:25 +0100 Subject: [PATCH 1400/4498] drivers: bluetooth: rpmsg: implement .close() Add .close() implementation for the HCI RPMsg driver. When running on the nRF5340 application core, it will power-cycle the network core. Signed-off-by: Pawel Osypiuk Signed-off-by: Jonathan Rico --- drivers/bluetooth/hci/CMakeLists.txt | 1 + drivers/bluetooth/hci/nrf53_support.c | 47 ++++++++++++++++ drivers/bluetooth/hci/rpmsg.c | 53 +++++++++++++++++++ include/zephyr/drivers/bluetooth/hci_driver.h | 13 +++++ 4 files changed, 114 insertions(+) create mode 100644 drivers/bluetooth/hci/nrf53_support.c diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index 8aca5f92a7f..5b09bbd81cc 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -11,3 +11,4 @@ zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c) zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c) zephyr_library_sources_ifdef(CONFIG_BT_SILABS_HCI slz_hci.c) zephyr_library_sources_ifdef(CONFIG_BT_PSOC6_BLESS hci_psoc6_bless.c) +zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP nrf53_support.c) diff --git a/drivers/bluetooth/hci/nrf53_support.c b/drivers/bluetooth/hci/nrf53_support.c new file mode 100644 index 00000000000..7fa91f4eb2f --- /dev/null +++ b/drivers/bluetooth/hci/nrf53_support.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Pawel Osypiuk + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) +#include <../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h> +#else +#define DEBUG_SETUP() +#endif /* defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) */ + +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_hci_nrf53_support); + +int bt_hci_transport_teardown(const struct device *dev) +{ + ARG_UNUSED(dev); + /* Put core into reset */ + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Hold; + LOG_DBG("Network MCU reseted."); + + return 0; +} + +int bt_hci_transport_setup(const struct device *dev) +{ + ARG_UNUSED(dev); +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) + /* Route Bluetooth Controller Debug Pins */ + DEBUG_SETUP(); +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) */ + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Retain nRF5340 Network MCU in Secure domain (bus + * accesses by Network MCU will have Secure attribute set). + */ + NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) */ + + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + + return 0; +} diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index 704508d5f32..e1fc5180df5 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -288,12 +288,30 @@ static struct ipc_ept_cfg hci_ept_cfg = { }, }; +int __weak bt_hci_transport_setup(const struct device *dev) +{ + ARG_UNUSED(dev); + return 0; +} + +int __weak bt_hci_transport_teardown(const struct device *dev) +{ + ARG_UNUSED(dev); + return 0; +} + static int bt_rpmsg_open(void) { int err; const struct device *hci_ipc_instance = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc)); + err = bt_hci_transport_setup(NULL); + if (err) { + LOG_ERR("HCI transport setup failed with: %d\n", err); + return err; + } + LOG_DBG(""); err = ipc_service_open_instance(hci_ipc_instance); @@ -317,9 +335,44 @@ static int bt_rpmsg_open(void) return 0; } +static int bt_rpmsg_close(void) +{ + int err; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL); + if (err) { + LOG_ERR("Sending reset command failed with: %d", err); + return err; + } + + err = ipc_service_deregister_endpoint(&hci_ept); + if (err) { + LOG_ERR("Deregistering HCI endpoint failed with: %d", err); + return err; + } + + const struct device *hci_ipc_instance = + DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc)); + + err = ipc_service_close_instance(hci_ipc_instance); + if (err) { + LOG_ERR("Closing IPC service failed with: %d", err); + return err; + } + + err = bt_hci_transport_teardown(NULL); + if (err) { + LOG_ERR("HCI transport teardown failed with: %d", err); + return err; + } + + return 0; +} + static const struct bt_hci_driver drv = { .name = "RPMsg", .open = bt_rpmsg_open, + .close = bt_rpmsg_close, .send = bt_rpmsg_send, .bus = BT_HCI_DRIVER_BUS_IPM, #if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE) diff --git a/include/zephyr/drivers/bluetooth/hci_driver.h b/include/zephyr/drivers/bluetooth/hci_driver.h index b0b310dc265..3774c8264ad 100644 --- a/include/zephyr/drivers/bluetooth/hci_driver.h +++ b/include/zephyr/drivers/bluetooth/hci_driver.h @@ -240,6 +240,19 @@ int bt_hci_driver_register(const struct bt_hci_driver *drv); */ int bt_hci_transport_setup(const struct device *dev); +/** + * @brief Teardown the HCI transport. + * + * @note A weak version of this function is included in the RPMSG driver, so + * defining it is optional. NRF5340 includes support to put network core + * in reset state. + * + * @param dev The device structure for the bus connecting to the IC + * + * @return 0 on success, negative error value on faulure + */ +int bt_hci_transport_teardown(const struct device *dev); + /** Allocate an HCI event buffer. * * This function allocates a new buffer for an HCI event. It is given the From 303ce143c2b8a097a6d0ae489f08ee9b7cea76cc Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 29 Sep 2023 13:27:51 +0200 Subject: [PATCH 1401/4498] Bluetooth: Controller: Fix regression in Adv PDU overflow calculation Fix regression in Adv PDU payload length overflow calculation. Regression in commit de8c19da5ebf ("Bluetooth: controller: Handle fragmented AD without chaining PDUs"). Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_adv_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 5349b21dd9f..302dc6da785 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -1804,7 +1804,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv, /* TODO: need aux_chain_ind support */ if ((sec_len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) { /* return excess length */ - *(uint8_t *)hdr_data = sec_len + ad_len - + *(uint8_t *)hdr_data = sec_len + ad_len + ad_fragment_len - PDU_AC_PAYLOAD_SIZE_MAX; if (pri_pdu == pri_pdu_prev) { @@ -2272,7 +2272,7 @@ uint8_t ull_adv_aux_pdu_set_clear(struct ll_adv_set *adv, /* Check AdvData overflow */ if ((len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) { /* return excess length */ - *(uint8_t *)hdr_data = len + ad_len - + *(uint8_t *)hdr_data = len + ad_len + ad_fragment_len - PDU_AC_PAYLOAD_SIZE_MAX; /* Will use packet too long error to determine fragmenting From 636c4ab796798e319ad66e44539ed3921669d332 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 28 Sep 2023 15:43:42 +0100 Subject: [PATCH 1402/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: bf8cf46b348eb8c8c10a1f1e4a7c24cdef52acf0 Brings following Zephyr relevant fixes: - 2929a975 bootutil: Show error if flash area open fails Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 4a86f7acb01..a8384e036c5 100644 --- a/west.yml +++ b/west.yml @@ -287,7 +287,7 @@ manifest: groups: - crypto - name: mcuboot - revision: ae2aeedfe8bb66f7fdddc25271689144d3579959 + revision: bf8cf46b348eb8c8c10a1f1e4a7c24cdef52acf0 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From 48f70eba2ba97cf9006bb7751eb35808f1bd2bfe Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 28 Sep 2023 14:00:12 +0200 Subject: [PATCH 1403/4498] Bluetooth: Controller: Fix clang warning on ull Fix a clang warning ull.c:1235: warning: use of bitwise '|' with boolean operands The result of ({1/0} &&(int)) is either true(1) or false(0), not the int and therefore bm is not a bitmask, but just true(1) or false(0) all together. Signed-off-by: Alberto Escolar Piedras --- subsys/bluetooth/controller/ll_sw/ull.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index f315fd2d337..d3321cb1b0b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -1232,10 +1232,8 @@ void ll_rx_dequeue(void) /* FIXME: use the correct adv and scan set to get * enabled status bitmask */ - bm = (IS_ENABLED(CONFIG_BT_OBSERVER) && - (ull_scan_is_enabled(0) << 1)) | - (IS_ENABLED(CONFIG_BT_BROADCASTER) && - ull_adv_is_enabled(0)); + bm = (IS_ENABLED(CONFIG_BT_OBSERVER)?(ull_scan_is_enabled(0) << 1):0) | + (IS_ENABLED(CONFIG_BT_BROADCASTER)?ull_adv_is_enabled(0):0); if (!bm) { ull_filter_adv_scan_state_cb(0); From 6e30d10c092d6a1fca3a1b73dadd25cc1a1f8948 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 11 Sep 2023 17:25:38 +0200 Subject: [PATCH 1404/4498] native SOC: Rename option NATIVE_SIMULATOR_CPU_N to MCU_N To be more accurate, as this option represents a microcontroller number, not a CPU number. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/Kconfig.defconfig | 2 +- .../posix/nrf52_bsim/common/bstests_entry.c | 12 ++++----- boards/posix/nrf52_bsim/common/cmsis/cmsis.c | 20 +++++++------- boards/posix/nrf52_bsim/cpu_wait.c | 4 +-- boards/posix/nrf52_bsim/irq_handler.c | 26 +++++++++---------- soc/posix/inf_clock/Kconfig | 4 +-- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/boards/posix/nrf52_bsim/Kconfig.defconfig b/boards/posix/nrf52_bsim/Kconfig.defconfig index 8fae1e9126e..28cf8d1eec2 100644 --- a/boards/posix/nrf52_bsim/Kconfig.defconfig +++ b/boards/posix/nrf52_bsim/Kconfig.defconfig @@ -14,7 +14,7 @@ config OUTPUT_PRINT_MEMORY_USAGE config BOARD default "nrf52_bsim" -config NATIVE_SIMULATOR_CPU_N +config NATIVE_SIMULATOR_MCU_N default 0 config SYS_CLOCK_HW_CYCLES_PER_SEC diff --git a/boards/posix/nrf52_bsim/common/bstests_entry.c b/boards/posix/nrf52_bsim/common/bstests_entry.c index 5f2dcdd1fa8..3e771195478 100644 --- a/boards/posix/nrf52_bsim/common/bstests_entry.c +++ b/boards/posix/nrf52_bsim/common/bstests_entry.c @@ -245,27 +245,27 @@ uint8_t bst_delete(void) return bst_result; } -#if defined(CONFIG_NATIVE_SIMULATOR_CPU_N) +#if defined(CONFIG_NATIVE_SIMULATOR_MCU_N) #include "bstest_ticker.h" void bst_ticker_set_period(bs_time_t tick_period) { - bst_ticker_amp_set_period(CONFIG_NATIVE_SIMULATOR_CPU_N, tick_period); + bst_ticker_amp_set_period(CONFIG_NATIVE_SIMULATOR_MCU_N, tick_period); } void bst_ticker_set_next_tick_absolute(bs_time_t time) { - bst_ticker_amp_set_next_tick_absolutelute(CONFIG_NATIVE_SIMULATOR_CPU_N, time); + bst_ticker_amp_set_next_tick_absolutelute(CONFIG_NATIVE_SIMULATOR_MCU_N, time); } void bst_ticker_set_next_tick_delta(bs_time_t time) { - bst_ticker_amp_set_next_tick_delta(CONFIG_NATIVE_SIMULATOR_CPU_N, time); + bst_ticker_amp_set_next_tick_delta(CONFIG_NATIVE_SIMULATOR_MCU_N, time); } void bst_awake_cpu_asap(void) { - bst_ticker_amp_awake_cpu_asap(CONFIG_NATIVE_SIMULATOR_CPU_N); + bst_ticker_amp_awake_cpu_asap(CONFIG_NATIVE_SIMULATOR_MCU_N); } -#endif /* defined(CONFIG_NATIVE_SIMULATOR_CPU_N) */ +#endif /* defined(CONFIG_NATIVE_SIMULATOR_MCU_N) */ diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis.c b/boards/posix/nrf52_bsim/common/cmsis/cmsis.c index c9deab58ee2..1694bc1da34 100644 --- a/boards/posix/nrf52_bsim/common/cmsis/cmsis.c +++ b/boards/posix/nrf52_bsim/common/cmsis/cmsis.c @@ -17,32 +17,32 @@ */ void NVIC_SetPendingIRQ(IRQn_Type IRQn) { - hw_irq_ctrl_raise_im_from_sw(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_raise_im_from_sw(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } void NVIC_ClearPendingIRQ(IRQn_Type IRQn) { - hw_irq_ctrl_clear_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_clear_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } void NVIC_DisableIRQ(IRQn_Type IRQn) { - hw_irq_ctrl_disable_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_disable_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } void NVIC_EnableIRQ(IRQn_Type IRQn) { - hw_irq_ctrl_enable_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_enable_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { - hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn, priority); + hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn, priority); } uint32_t NVIC_GetPriority(IRQn_Type IRQn) { - return hw_irq_ctrl_get_prio(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + return hw_irq_ctrl_get_prio(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } void NVIC_SystemReset(void) @@ -55,22 +55,22 @@ void NVIC_SystemReset(void) */ void __enable_irq(void) { - hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, false); + hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, false); } void __disable_irq(void) { - hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, true); + hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, true); } uint32_t __get_PRIMASK(void) { - return hw_irq_ctrl_get_current_lock(CONFIG_NATIVE_SIMULATOR_CPU_N); + return hw_irq_ctrl_get_current_lock(CONFIG_NATIVE_SIMULATOR_MCU_N); } void __set_PRIMASK(uint32_t primask) { - hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, primask != 0); + hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, primask != 0); } void __WFE(void) diff --git a/boards/posix/nrf52_bsim/cpu_wait.c b/boards/posix/nrf52_bsim/cpu_wait.c index a8695e64ed5..cedc71228a8 100644 --- a/boards/posix/nrf52_bsim/cpu_wait.c +++ b/boards/posix/nrf52_bsim/cpu_wait.c @@ -32,7 +32,7 @@ void arch_busy_wait(uint32_t usec_to_wait) * There may be wakes due to other interrupts or nested calls to * k_busy_wait in interrupt handlers */ - nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_CPU_N, time_end); + nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_MCU_N, time_end); posix_halt_cpu(); } } @@ -58,7 +58,7 @@ void posix_cpu_hold(uint32_t usec_to_waste) * cpu_hold in interrupt handlers */ time_start = nsi_hws_get_time(); - nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_CPU_N, time_start + to_wait); + nhw_fake_timer_wake_in_time(CONFIG_NATIVE_SIMULATOR_MCU_N, time_start + to_wait); posix_change_cpu_state_and_wait(true); to_wait -= nsi_hws_get_time() - time_start; diff --git a/boards/posix/nrf52_bsim/irq_handler.c b/boards/posix/nrf52_bsim/irq_handler.c index 0ba65fc4985..24c00a4f79c 100644 --- a/boards/posix/nrf52_bsim/irq_handler.c +++ b/boards/posix/nrf52_bsim/irq_handler.c @@ -43,7 +43,7 @@ static inline void vector_to_irq(int irq_nbr, int *may_swap) } bs_trace_raw_time(6, "Vectoring to irq %i (%s)\n", irq_nbr, - hw_irq_ctrl_get_name(CONFIG_NATIVE_SIMULATOR_CPU_N, irq_nbr)); + hw_irq_ctrl_get_name(CONFIG_NATIVE_SIMULATOR_MCU_N, irq_nbr)); sys_trace_isr_enter(); @@ -70,7 +70,7 @@ static inline void vector_to_irq(int irq_nbr, int *may_swap) sys_trace_isr_exit(); bs_trace_raw_time(7, "Irq %i (%s) ended\n", irq_nbr, - hw_irq_ctrl_get_name(CONFIG_NATIVE_SIMULATOR_CPU_N, irq_nbr)); + hw_irq_ctrl_get_name(CONFIG_NATIVE_SIMULATOR_MCU_N, irq_nbr)); } /** @@ -86,7 +86,7 @@ void posix_irq_handler(void) uint64_t irq_lock; int irq_nbr; static int may_swap; - const int cpu_n = CONFIG_NATIVE_SIMULATOR_CPU_N; + const int cpu_n = CONFIG_NATIVE_SIMULATOR_MCU_N; irq_lock = hw_irq_ctrl_get_current_lock(cpu_n); @@ -146,7 +146,7 @@ void posix_irq_handler_im_from_sw(void) * pending we go immediately into irq_handler() to vector into its * handler */ - if (hw_irq_ctrl_get_highest_prio_irq(CONFIG_NATIVE_SIMULATOR_CPU_N) != -1) { + if (hw_irq_ctrl_get_highest_prio_irq(CONFIG_NATIVE_SIMULATOR_MCU_N) != -1) { if (!posix_is_cpu_running()) { /* LCOV_EXCL_BR_LINE */ /* LCOV_EXCL_START */ posix_print_error_and_exit("programming error: %s " @@ -191,7 +191,7 @@ void posix_irq_handler_im_from_sw(void) */ unsigned int posix_irq_lock(void) { - return hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, true); + return hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, true); } /** @@ -205,27 +205,27 @@ unsigned int posix_irq_lock(void) */ void posix_irq_unlock(unsigned int key) { - hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, key); + hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, key); } void posix_irq_full_unlock(void) { - hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_CPU_N, false); + hw_irq_ctrl_change_lock(CONFIG_NATIVE_SIMULATOR_MCU_N, false); } void posix_irq_enable(unsigned int irq) { - hw_irq_ctrl_enable_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, irq); + hw_irq_ctrl_enable_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, irq); } void posix_irq_disable(unsigned int irq) { - hw_irq_ctrl_disable_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, irq); + hw_irq_ctrl_disable_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, irq); } int posix_irq_is_enabled(unsigned int irq) { - return hw_irq_ctrl_is_irq_enabled(CONFIG_NATIVE_SIMULATOR_CPU_N, irq); + return hw_irq_ctrl_is_irq_enabled(CONFIG_NATIVE_SIMULATOR_MCU_N, irq); } int posix_get_current_irq(void) @@ -266,7 +266,7 @@ void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), */ void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { - hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_CPU_N, irq, prio); + hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_MCU_N, irq, prio); } /** @@ -279,7 +279,7 @@ void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) */ void posix_sw_set_pending_IRQ(unsigned int IRQn) { - hw_irq_ctrl_raise_im_from_sw(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_raise_im_from_sw(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } /** @@ -288,7 +288,7 @@ void posix_sw_set_pending_IRQ(unsigned int IRQn) */ void posix_sw_clear_pending_IRQ(unsigned int IRQn) { - hw_irq_ctrl_clear_irq(CONFIG_NATIVE_SIMULATOR_CPU_N, IRQn); + hw_irq_ctrl_clear_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } #ifdef CONFIG_IRQ_OFFLOAD diff --git a/soc/posix/inf_clock/Kconfig b/soc/posix/inf_clock/Kconfig index 3f42f7b23df..d2f24b09a8a 100644 --- a/soc/posix/inf_clock/Kconfig +++ b/soc/posix/inf_clock/Kconfig @@ -1,13 +1,13 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config NATIVE_SIMULATOR_CPU_N +config NATIVE_SIMULATOR_MCU_N int "CPU Number this image targets" range 0 15 default 0 depends on NATIVE_LIBRARY help - Which native simulator embedded CPU number is this image targeting. + Which native simulator microcontroller/CPU number is this image targeting. This option is only applicable for targets which use the native simulator as their runner. From ddea15fbe1c6aa494f61253f087235dc6b7c155f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 11 Sep 2023 17:21:29 +0200 Subject: [PATCH 1405/4498] nrf52_bsim: Rename the native simulator hooks appropriately Each MCU hooks need to be named according to its MCU number. Rename the hooks appropriately. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/nsi_if.c | 38 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/boards/posix/nrf52_bsim/nsi_if.c b/boards/posix/nrf52_bsim/nsi_if.c index 4c2a411366a..ee36e507efe 100644 --- a/boards/posix/nrf52_bsim/nsi_if.c +++ b/boards/posix/nrf52_bsim/nsi_if.c @@ -14,7 +14,27 @@ #include "phy_sync_ctrl.h" #include "nsi_hw_scheduler.h" -NATIVE_SIMULATOR_IF void nsif_cpu0_pre_cmdline_hooks(void) +/* + * These hooks are to be named nsif_cpu_, for example nsif_cpu0_boot + */ +#define nsif_cpun_pre_cmdline_hooks _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _pre_cmdline_hooks) +#define nsif_cpun_save_test_arg _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _save_test_arg) +#define nsif_cpun_pre_hw_init_hooks _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _pre_hw_init_hooks) +#define nsif_cpun_boot _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _boot) +#define nsif_cpun_cleanup _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _cleanup) +#define nsif_cpun_irq_raised _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _irq_raised) +#define nsif_cpun_test_hook _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _test_hook) +#define nsif_cpun_irq_raised_from_sw _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\ + _irq_raised_from_sw) + +NATIVE_SIMULATOR_IF void nsif_cpun_pre_cmdline_hooks(void) { run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL); } @@ -27,7 +47,7 @@ static struct { int allocated_size; } test_args; -NATIVE_SIMULATOR_IF void nsif_cpu0_save_test_arg(char *argv) +NATIVE_SIMULATOR_IF void nsif_cpun_save_test_arg(char *argv) { if (test_args.test_case_argc >= test_args.allocated_size) { test_args.allocated_size += TESTCASAE_ARGV_ALLOCSIZE; @@ -53,7 +73,7 @@ static void test_args_free(void) NATIVE_TASK(test_args_free, ON_EXIT_PRE, 100); -NATIVE_SIMULATOR_IF void nsif_cpu0_pre_hw_init_hooks(void) +NATIVE_SIMULATOR_IF void nsif_cpun_pre_hw_init_hooks(void) { run_native_tasks(_NATIVE_PRE_BOOT_2_LEVEL); phy_sync_ctrl_connect_to_2G4_phy(); @@ -63,7 +83,7 @@ NATIVE_SIMULATOR_IF void nsif_cpu0_pre_hw_init_hooks(void) phy_sync_ctrl_pre_boot2(); } -NATIVE_SIMULATOR_IF void nsif_cpu0_boot(void) +NATIVE_SIMULATOR_IF void nsif_cpun_boot(void) { run_native_tasks(_NATIVE_PRE_BOOT_3_LEVEL); bst_pre_init(); @@ -73,11 +93,11 @@ NATIVE_SIMULATOR_IF void nsif_cpu0_boot(void) bst_post_init(); } -NATIVE_SIMULATOR_IF int nsif_cpu0_cleanup(void) +NATIVE_SIMULATOR_IF int nsif_cpun_cleanup(void) { /* * Note posix_soc_clean_up() may not return, but in that case, - * nsif_cpu0_cleanup() will be called again + * nsif_cpun_cleanup() will be called again */ posix_soc_clean_up(); @@ -85,19 +105,19 @@ NATIVE_SIMULATOR_IF int nsif_cpu0_cleanup(void) return bst_result; } -NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised(void) +NATIVE_SIMULATOR_IF void nsif_cpun_irq_raised(void) { posix_interrupt_raised(); } -NATIVE_SIMULATOR_IF int nsif_cpu0_test_hook(void *p) +NATIVE_SIMULATOR_IF int nsif_cpun_test_hook(void *p) { (void) p; bst_tick(nsi_hws_get_time()); return 0; } -NATIVE_SIMULATOR_IF void nsif_cpu0_irq_raised_from_sw(void) +NATIVE_SIMULATOR_IF void nsif_cpun_irq_raised_from_sw(void) { void posix_irq_handler_im_from_sw(void); posix_irq_handler_im_from_sw(); From f0a09a3f10168973ac20189b3dba3990967dfc7d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 11 Sep 2023 17:33:50 +0200 Subject: [PATCH 1406/4498] nrf52_bsim: bstest options: Prepend options with mcu number To allow knowing for which MCU are the options, prepend them with the MCU number. The primary/preferred MCU will also keep an alias to the old options (without the cpu_ prefix) Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf52_bsim/argparse.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/boards/posix/nrf52_bsim/argparse.c b/boards/posix/nrf52_bsim/argparse.c index df1a222fffb..594654899ef 100644 --- a/boards/posix/nrf52_bsim/argparse.c +++ b/boards/posix/nrf52_bsim/argparse.c @@ -14,7 +14,7 @@ #include "nsi_tracing.h" #include "nsi_main.h" -static const char exe_name[] = "nrf52_bsim options:"; +static const char exe_name[] = "nrf_bsim options:"; static char *testid; @@ -33,7 +33,7 @@ static void nrfbsim_register_args(void) { static bs_args_struct_t args_struct_toadd[] = { { - .option = "testid", + .option = "cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_testid", .name = "testid", .type = 's', .dest = (void *)&testid, @@ -42,11 +42,28 @@ static void nrfbsim_register_args(void) }, { .is_switch = true, - .option = "testslist", + .option = "cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_testslist", .type = 'b', .call_when_found = cmd_testlist_found, .descript = "Print information about the available bs application tests" }, +#if (CONFIG_NATIVE_SIMULATOR_MCU_N == CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX) + { + .option = "testid", + .name = "testid", + .type = 's', + .dest = (void *)&testid, + .call_when_found = cmd_testid_found, + .descript = "Alias of cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_testid" + }, + { + .is_switch = true, + .option = "testslist", + .type = 'b', + .call_when_found = cmd_testlist_found, + .descript = "Alias of cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_testslist" + }, +#endif ARG_TABLE_ENDMARKER }; From 4fd9ffb995236d7e7e13c6b6f319f251ed506e60 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 10:48:10 +0200 Subject: [PATCH 1407/4498] boards nrf52_bsim: Rename folder to nrf_bsim As we will now we having more nrf5*_bsim boards defined in this same folder, the old folder names became missleading. Signed-off-by: Alberto Escolar Piedras --- MAINTAINERS.yml | 6 +++--- boards/posix/{nrf52_bsim => nrf_bsim}/CMakeLists.txt | 0 boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig | 0 boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig.board | 0 boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig.defconfig | 0 boards/posix/{nrf52_bsim => nrf_bsim}/argparse.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/argparse.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/board.cmake | 0 boards/posix/{nrf52_bsim => nrf_bsim}/board_irq.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/board_soc.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/README.txt | 0 .../{nrf52_bsim => nrf_bsim}/common/bsim_args_runner.c | 0 .../{nrf52_bsim => nrf_bsim}/common/bsim_args_runner.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/bstests.h | 0 .../posix/{nrf52_bsim => nrf_bsim}/common/bstests_entry.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/cmdline.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis.h | 0 .../{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis_compiler.h | 0 .../{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis_instr.h | 0 .../posix/{nrf52_bsim => nrf_bsim}/common/phy_sync_ctrl.c | 0 .../posix/{nrf52_bsim => nrf_bsim}/common/phy_sync_ctrl.h | 0 .../posix/{nrf52_bsim => nrf_bsim}/common/posix_arch_if.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/runner_hooks.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/common/trace_hook.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/cpu_wait.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/doc/index.rst | 0 boards/posix/{nrf52_bsim => nrf_bsim}/irq_handler.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim.dts | 0 boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim.yaml | 0 boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim_defconfig | 0 boards/posix/{nrf52_bsim => nrf_bsim}/nsi_if.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/pre_dt_board.cmake | 0 boards/posix/{nrf52_bsim => nrf_bsim}/soc/nrfx_coredep.c | 0 boards/posix/{nrf52_bsim => nrf_bsim}/soc/soc_secure.h | 0 boards/posix/{nrf52_bsim => nrf_bsim}/time_machine.h | 0 36 files changed, 3 insertions(+), 3 deletions(-) rename boards/posix/{nrf52_bsim => nrf_bsim}/CMakeLists.txt (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig.board (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/Kconfig.defconfig (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/argparse.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/argparse.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/board.cmake (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/board_irq.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/board_soc.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/README.txt (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/bsim_args_runner.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/bsim_args_runner.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/bstests.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/bstests_entry.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/cmdline.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis_compiler.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/cmsis/cmsis_instr.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/phy_sync_ctrl.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/phy_sync_ctrl.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/posix_arch_if.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/runner_hooks.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/common/trace_hook.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/cpu_wait.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/doc/index.rst (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/irq_handler.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim.dts (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim.yaml (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/nrf52_bsim_defconfig (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/nsi_if.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/pre_dt_board.cmake (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/soc/nrfx_coredep.c (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/soc/soc_secure.h (100%) rename boards/posix/{nrf52_bsim => nrf_bsim}/time_machine.h (100%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 33f5e72c9d7..b86c89f44e4 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2070,18 +2070,18 @@ NIOS-2 arch: labels: - "area: NIOS2" -nRF52 BSIM: +nRF BSIM: status: maintained maintainers: - aescolar files: - - boards/posix/nrf52_bsim/ + - boards/posix/nrf_bsim/ - tests/boards/nrf52_bsim/ - tests/bsim/ files-exclude: - tests/bsim/*/ labels: - - "platform: nRF52 BSIM" + - "platform: nRF BSIM" POSIX API layer: status: maintained diff --git a/boards/posix/nrf52_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt similarity index 100% rename from boards/posix/nrf52_bsim/CMakeLists.txt rename to boards/posix/nrf_bsim/CMakeLists.txt diff --git a/boards/posix/nrf52_bsim/Kconfig b/boards/posix/nrf_bsim/Kconfig similarity index 100% rename from boards/posix/nrf52_bsim/Kconfig rename to boards/posix/nrf_bsim/Kconfig diff --git a/boards/posix/nrf52_bsim/Kconfig.board b/boards/posix/nrf_bsim/Kconfig.board similarity index 100% rename from boards/posix/nrf52_bsim/Kconfig.board rename to boards/posix/nrf_bsim/Kconfig.board diff --git a/boards/posix/nrf52_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig similarity index 100% rename from boards/posix/nrf52_bsim/Kconfig.defconfig rename to boards/posix/nrf_bsim/Kconfig.defconfig diff --git a/boards/posix/nrf52_bsim/argparse.c b/boards/posix/nrf_bsim/argparse.c similarity index 100% rename from boards/posix/nrf52_bsim/argparse.c rename to boards/posix/nrf_bsim/argparse.c diff --git a/boards/posix/nrf52_bsim/argparse.h b/boards/posix/nrf_bsim/argparse.h similarity index 100% rename from boards/posix/nrf52_bsim/argparse.h rename to boards/posix/nrf_bsim/argparse.h diff --git a/boards/posix/nrf52_bsim/board.cmake b/boards/posix/nrf_bsim/board.cmake similarity index 100% rename from boards/posix/nrf52_bsim/board.cmake rename to boards/posix/nrf_bsim/board.cmake diff --git a/boards/posix/nrf52_bsim/board_irq.h b/boards/posix/nrf_bsim/board_irq.h similarity index 100% rename from boards/posix/nrf52_bsim/board_irq.h rename to boards/posix/nrf_bsim/board_irq.h diff --git a/boards/posix/nrf52_bsim/board_soc.h b/boards/posix/nrf_bsim/board_soc.h similarity index 100% rename from boards/posix/nrf52_bsim/board_soc.h rename to boards/posix/nrf_bsim/board_soc.h diff --git a/boards/posix/nrf52_bsim/common/README.txt b/boards/posix/nrf_bsim/common/README.txt similarity index 100% rename from boards/posix/nrf52_bsim/common/README.txt rename to boards/posix/nrf_bsim/common/README.txt diff --git a/boards/posix/nrf52_bsim/common/bsim_args_runner.c b/boards/posix/nrf_bsim/common/bsim_args_runner.c similarity index 100% rename from boards/posix/nrf52_bsim/common/bsim_args_runner.c rename to boards/posix/nrf_bsim/common/bsim_args_runner.c diff --git a/boards/posix/nrf52_bsim/common/bsim_args_runner.h b/boards/posix/nrf_bsim/common/bsim_args_runner.h similarity index 100% rename from boards/posix/nrf52_bsim/common/bsim_args_runner.h rename to boards/posix/nrf_bsim/common/bsim_args_runner.h diff --git a/boards/posix/nrf52_bsim/common/bstests.h b/boards/posix/nrf_bsim/common/bstests.h similarity index 100% rename from boards/posix/nrf52_bsim/common/bstests.h rename to boards/posix/nrf_bsim/common/bstests.h diff --git a/boards/posix/nrf52_bsim/common/bstests_entry.c b/boards/posix/nrf_bsim/common/bstests_entry.c similarity index 100% rename from boards/posix/nrf52_bsim/common/bstests_entry.c rename to boards/posix/nrf_bsim/common/bstests_entry.c diff --git a/boards/posix/nrf52_bsim/common/cmdline.h b/boards/posix/nrf_bsim/common/cmdline.h similarity index 100% rename from boards/posix/nrf52_bsim/common/cmdline.h rename to boards/posix/nrf_bsim/common/cmdline.h diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis.c b/boards/posix/nrf_bsim/common/cmsis/cmsis.c similarity index 100% rename from boards/posix/nrf52_bsim/common/cmsis/cmsis.c rename to boards/posix/nrf_bsim/common/cmsis/cmsis.c diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis.h b/boards/posix/nrf_bsim/common/cmsis/cmsis.h similarity index 100% rename from boards/posix/nrf52_bsim/common/cmsis/cmsis.h rename to boards/posix/nrf_bsim/common/cmsis/cmsis.h diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis_compiler.h b/boards/posix/nrf_bsim/common/cmsis/cmsis_compiler.h similarity index 100% rename from boards/posix/nrf52_bsim/common/cmsis/cmsis_compiler.h rename to boards/posix/nrf_bsim/common/cmsis/cmsis_compiler.h diff --git a/boards/posix/nrf52_bsim/common/cmsis/cmsis_instr.h b/boards/posix/nrf_bsim/common/cmsis/cmsis_instr.h similarity index 100% rename from boards/posix/nrf52_bsim/common/cmsis/cmsis_instr.h rename to boards/posix/nrf_bsim/common/cmsis/cmsis_instr.h diff --git a/boards/posix/nrf52_bsim/common/phy_sync_ctrl.c b/boards/posix/nrf_bsim/common/phy_sync_ctrl.c similarity index 100% rename from boards/posix/nrf52_bsim/common/phy_sync_ctrl.c rename to boards/posix/nrf_bsim/common/phy_sync_ctrl.c diff --git a/boards/posix/nrf52_bsim/common/phy_sync_ctrl.h b/boards/posix/nrf_bsim/common/phy_sync_ctrl.h similarity index 100% rename from boards/posix/nrf52_bsim/common/phy_sync_ctrl.h rename to boards/posix/nrf_bsim/common/phy_sync_ctrl.h diff --git a/boards/posix/nrf52_bsim/common/posix_arch_if.c b/boards/posix/nrf_bsim/common/posix_arch_if.c similarity index 100% rename from boards/posix/nrf52_bsim/common/posix_arch_if.c rename to boards/posix/nrf_bsim/common/posix_arch_if.c diff --git a/boards/posix/nrf52_bsim/common/runner_hooks.c b/boards/posix/nrf_bsim/common/runner_hooks.c similarity index 100% rename from boards/posix/nrf52_bsim/common/runner_hooks.c rename to boards/posix/nrf_bsim/common/runner_hooks.c diff --git a/boards/posix/nrf52_bsim/common/trace_hook.c b/boards/posix/nrf_bsim/common/trace_hook.c similarity index 100% rename from boards/posix/nrf52_bsim/common/trace_hook.c rename to boards/posix/nrf_bsim/common/trace_hook.c diff --git a/boards/posix/nrf52_bsim/cpu_wait.c b/boards/posix/nrf_bsim/cpu_wait.c similarity index 100% rename from boards/posix/nrf52_bsim/cpu_wait.c rename to boards/posix/nrf_bsim/cpu_wait.c diff --git a/boards/posix/nrf52_bsim/doc/index.rst b/boards/posix/nrf_bsim/doc/index.rst similarity index 100% rename from boards/posix/nrf52_bsim/doc/index.rst rename to boards/posix/nrf_bsim/doc/index.rst diff --git a/boards/posix/nrf52_bsim/irq_handler.c b/boards/posix/nrf_bsim/irq_handler.c similarity index 100% rename from boards/posix/nrf52_bsim/irq_handler.c rename to boards/posix/nrf_bsim/irq_handler.c diff --git a/boards/posix/nrf52_bsim/nrf52_bsim.dts b/boards/posix/nrf_bsim/nrf52_bsim.dts similarity index 100% rename from boards/posix/nrf52_bsim/nrf52_bsim.dts rename to boards/posix/nrf_bsim/nrf52_bsim.dts diff --git a/boards/posix/nrf52_bsim/nrf52_bsim.yaml b/boards/posix/nrf_bsim/nrf52_bsim.yaml similarity index 100% rename from boards/posix/nrf52_bsim/nrf52_bsim.yaml rename to boards/posix/nrf_bsim/nrf52_bsim.yaml diff --git a/boards/posix/nrf52_bsim/nrf52_bsim_defconfig b/boards/posix/nrf_bsim/nrf52_bsim_defconfig similarity index 100% rename from boards/posix/nrf52_bsim/nrf52_bsim_defconfig rename to boards/posix/nrf_bsim/nrf52_bsim_defconfig diff --git a/boards/posix/nrf52_bsim/nsi_if.c b/boards/posix/nrf_bsim/nsi_if.c similarity index 100% rename from boards/posix/nrf52_bsim/nsi_if.c rename to boards/posix/nrf_bsim/nsi_if.c diff --git a/boards/posix/nrf52_bsim/pre_dt_board.cmake b/boards/posix/nrf_bsim/pre_dt_board.cmake similarity index 100% rename from boards/posix/nrf52_bsim/pre_dt_board.cmake rename to boards/posix/nrf_bsim/pre_dt_board.cmake diff --git a/boards/posix/nrf52_bsim/soc/nrfx_coredep.c b/boards/posix/nrf_bsim/soc/nrfx_coredep.c similarity index 100% rename from boards/posix/nrf52_bsim/soc/nrfx_coredep.c rename to boards/posix/nrf_bsim/soc/nrfx_coredep.c diff --git a/boards/posix/nrf52_bsim/soc/soc_secure.h b/boards/posix/nrf_bsim/soc/soc_secure.h similarity index 100% rename from boards/posix/nrf52_bsim/soc/soc_secure.h rename to boards/posix/nrf_bsim/soc/soc_secure.h diff --git a/boards/posix/nrf52_bsim/time_machine.h b/boards/posix/nrf_bsim/time_machine.h similarity index 100% rename from boards/posix/nrf52_bsim/time_machine.h rename to boards/posix/nrf_bsim/time_machine.h From af00bd8cb17b70c2e3b03b4ceb3fb138cf0417fc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 17:03:52 +0200 Subject: [PATCH 1408/4498] nrf_bsim: Handle test options for N MCUs Handle test options for N MCUs instead of just 1. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/CMakeLists.txt | 4 +++ .../posix/nrf_bsim/common/bsim_args_runner.c | 33 ++++++++++++++++--- .../nrf_bsim/common/bsim_extra_cpu_if_stubs.c | 27 +++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 boards/posix/nrf_bsim/common/bsim_extra_cpu_if_stubs.c diff --git a/boards/posix/nrf_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt index 9e70b603178..0a06623fe22 100644 --- a/boards/posix/nrf_bsim/CMakeLists.txt +++ b/boards/posix/nrf_bsim/CMakeLists.txt @@ -27,6 +27,7 @@ zephyr_library_sources( target_sources(native_simulator INTERFACE common/bsim_args_runner.c + common/bsim_extra_cpu_if_stubs.c common/phy_sync_ctrl.c common/runner_hooks.c common/posix_arch_if.c @@ -57,4 +58,7 @@ set_property(TARGET native_simulator APPEND PROPERTY RUNNER_LINK_LIBRARIES ${libpath}/libRandv2.32.a ) +target_compile_options(native_simulator INTERFACE + "-DNSI_PRIMARY_MCU_N=${CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}") + include(../common/natsim_config.cmake) diff --git a/boards/posix/nrf_bsim/common/bsim_args_runner.c b/boards/posix/nrf_bsim/common/bsim_args_runner.c index 6aed191793c..fe840ac4ad8 100644 --- a/boards/posix/nrf_bsim/common/bsim_args_runner.c +++ b/boards/posix/nrf_bsim/common/bsim_args_runner.c @@ -21,6 +21,7 @@ #include "bs_tracing.h" #include "bs_dump_files.h" #include "bs_rand_main.h" +#include "nsi_cpu_if.h" #include "nsi_tasks.h" #include "nsi_main.h" #include "NRF_HWLowL.h" @@ -86,8 +87,17 @@ static void bsim_register_basic_args(void) .name = "arg", .type = 'l', .descript = "The arguments that follow will be passed straight to the testcase " - "init function. (Note: If more than 1 MCU is present, argtest corresponds " - "to argtestmcu0)" + "init function (Note: If more than 1 MCU is present, argtest corresponds " + "to argstests" NSI_STRINGIFY(NSI_PRIMARY_MCU_N) " )" + }, + { + .manual = true, + .option = "argstest", + .name = "arg", + .type = 'l', + .descript = "The arguments that follow will be passed straight to cpu's " + "testcase init function), where 0 <= n < " NSI_STRINGIFY(NSI_N_CPUS) + " is the cpu number" }, { .manual = true, @@ -117,6 +127,17 @@ void bs_add_extra_dynargs(bs_args_struct_t *args_struct_toadd) bs_add_dynargs(&args_struct, args_struct_toadd); } +static void nsif_cpun_save_test_arg(int n, char *c) +{ + F_TRAMP_LIST(NATIVE_SIMULATOR_IF void nsif_cpu, _save_test_arg(char *argv)) + + void(*fptrs[])(char *) = { + F_TRAMP_TABLE(nsif_cpu, _save_test_arg) + }; + + fptrs[n](c); +} + /** * Check the arguments provided in the command line: set args based on it or * defaults, and check they are correct @@ -132,9 +153,14 @@ void nsi_handle_cmd_line(int argc, char *argv[]) static const char default_phy[] = "2G4"; enum {Main = 0, Test = 1} parsing = Main; + uint test_cpu_n; for (int i = 1; i < argc; i++) { if (bs_is_option(argv[i], "argstest", 0)) { + parsing = Test; + test_cpu_n = NSI_PRIMARY_MCU_N; + continue; + } else if (bs_is_multi_opt(argv[i], "argstest", &test_cpu_n, 0)) { parsing = Test; continue; } else if (bs_is_option(argv[i], "argsmain", 0)) { @@ -149,8 +175,7 @@ void nsi_handle_cmd_line(int argc, char *argv[]) argv[i]); } } else if (parsing == Test) { - void nsif_cpu0_save_test_arg(char *argv); - nsif_cpu0_save_test_arg(argv[i]); + nsif_cpun_save_test_arg(test_cpu_n, argv[i]); } else { bs_trace_error_line("Bad error\n"); } diff --git a/boards/posix/nrf_bsim/common/bsim_extra_cpu_if_stubs.c b/boards/posix/nrf_bsim/common/bsim_extra_cpu_if_stubs.c new file mode 100644 index 00000000000..bec831e3943 --- /dev/null +++ b/boards/posix/nrf_bsim/common/bsim_extra_cpu_if_stubs.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_tracing.h" +#include "nsi_cpu_if.h" + +/* + * Default (weak) implementation for nsif_cpu_save_test_arg() expected by the argument + * parsing defined in bsim_args_runner. + * Note that the real implementation is provided by the board code. + * This exists in case the total device image is assembled lacking some of the embedded MCU images + * or the user tries to target a non-existent MCU + */ + +static void save_test_arg_warn(const char *func, char *argv) +{ + bs_trace_warning("%s not defined. You may be passing a test argument to a CPU without" + " image or a non-existent CPU. Argument \"%s\" will be ignored\n", + func, argv); +} + +/* Define N instances of void nsif_cpu_save_test_arg */ +F_TRAMP_BODY_LIST(NATIVE_SIMULATOR_IF __attribute__((weak)) void nsif_cpu, + _save_test_arg(char *argv) { save_test_arg_warn(__func__, argv); }) From fa470ca57dac1ace611fffb9168c0a50cabac437 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 13 Sep 2023 16:18:36 +0200 Subject: [PATCH 1409/4498] native SOC: Add option to make a MCU to boot on its own As a development helper, add a kconfig option to automatically start the MCU this Zephyr image is built for during HW boot, even if in other circumstances this MCU would not start automatically (for ex. because another core is meant to release its reset). Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/nsi_if.c | 4 ++++ soc/posix/inf_clock/Kconfig | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/boards/posix/nrf_bsim/nsi_if.c b/boards/posix/nrf_bsim/nsi_if.c index ee36e507efe..d0f45597fa3 100644 --- a/boards/posix/nrf_bsim/nsi_if.c +++ b/boards/posix/nrf_bsim/nsi_if.c @@ -13,6 +13,7 @@ #include "bs_tracing.h" #include "phy_sync_ctrl.h" #include "nsi_hw_scheduler.h" +#include "nsi_cpu_ctrl.h" /* * These hooks are to be named nsif_cpu_, for example nsif_cpu0_boot @@ -37,6 +38,9 @@ NATIVE_SIMULATOR_IF void nsif_cpun_pre_cmdline_hooks(void) { run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL); +#if defined(CONFIG_NATIVE_SIMULATOR_AUTOSTART_MCU) + nsi_cpu_set_auto_start(CONFIG_NATIVE_SIMULATOR_MCU_N, true); +#endif } #define TESTCASAE_ARGV_ALLOCSIZE 128 diff --git a/soc/posix/inf_clock/Kconfig b/soc/posix/inf_clock/Kconfig index d2f24b09a8a..9e5f5ccc89f 100644 --- a/soc/posix/inf_clock/Kconfig +++ b/soc/posix/inf_clock/Kconfig @@ -27,7 +27,7 @@ config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX On a multi MCU device, which MCU is the preferred one. This MCU will for example have its tests command line parameters presented without any prefix. Note that an MCU being primary does not imply it will be - the first one to boot. + the first one to boot, or even that it will boot automatically. config NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS string "Other cores images to include" @@ -37,3 +37,13 @@ config NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS been produced by either other Zephyr builds or different OS builds. So you can, for ex., use this application build produce one core image, and at the same time have it produce the final link with the native simulator runner and the other MCU images. + +config NATIVE_SIMULATOR_AUTOSTART_MCU + bool "Auto-start this MCU" + depends on NATIVE_LIBRARY + help + Automatically start the MCU this Zephyr image is built for during HW boot, + even if in other circumstances this MCU would not start automatically (for ex. because + another core is meant to release its reset). + If that MCU was, by HW design, going to start at HW boot anyhow, this option does nothing. + This option is meant to facilitate development. From 27f32af8ecf5c41dfbceb872744ca73ffe784336 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 13 Sep 2023 17:07:10 +0200 Subject: [PATCH 1410/4498] nrf5x_bsim: Add command line options to control MCU boot Add options to force MCUs to boot/not boot, overriding of how they would behave otherwise, as well as an option to print info about the MCUs present in the platform. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/argparse.c | 15 +++++++++++++ .../posix/nrf_bsim/common/bsim_args_runner.c | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/boards/posix/nrf_bsim/argparse.c b/boards/posix/nrf_bsim/argparse.c index 594654899ef..69214ef5d7d 100644 --- a/boards/posix/nrf_bsim/argparse.c +++ b/boards/posix/nrf_bsim/argparse.c @@ -13,10 +13,12 @@ #include "posix_native_task.h" #include "nsi_tracing.h" #include "nsi_main.h" +#include "nsi_cpu_ctrl.h" static const char exe_name[] = "nrf_bsim options:"; static char *testid; +static bool cpu_autostart; static void cmd_testid_found(char *argv, int offset) { @@ -29,6 +31,11 @@ static void cmd_testlist_found(char *argv, int offset) nsi_exit(0); } +static void cmd_autostart_found(char *argv, int offset) +{ + nsi_cpu_set_auto_start(CONFIG_NATIVE_SIMULATOR_MCU_N, cpu_autostart); +} + static void nrfbsim_register_args(void) { static bs_args_struct_t args_struct_toadd[] = { @@ -64,6 +71,14 @@ static void nrfbsim_register_args(void) .descript = "Alias of cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_testslist" }, #endif + { + .option = "cpu" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) "_autostart", + .name = "autostart", + .type = 'b', + .dest = (void *)&cpu_autostart, + .call_when_found = cmd_autostart_found, + .descript = "Automatically start CPU" STRINGIFY(CONFIG_NATIVE_SIMULATOR_MCU_N) + }, ARG_TABLE_ENDMARKER }; diff --git a/boards/posix/nrf_bsim/common/bsim_args_runner.c b/boards/posix/nrf_bsim/common/bsim_args_runner.c index fe840ac4ad8..29e0d15dd2e 100644 --- a/boards/posix/nrf_bsim/common/bsim_args_runner.c +++ b/boards/posix/nrf_bsim/common/bsim_args_runner.c @@ -24,7 +24,9 @@ #include "nsi_cpu_if.h" #include "nsi_tasks.h" #include "nsi_main.h" +#include "nsi_cpu_ctrl.h" #include "NRF_HWLowL.h" +#include "NHW_misc.h" static bs_args_struct_t *args_struct; /* Direct use of this global is deprecated, use bsim_args_get_global_device_nbr() instead */ @@ -59,6 +61,18 @@ static void print_no_sim_warning(void) "and nosim\n"); } +static void print_mcus_info(char *argv, int offset) +{ + (void) argv; + (void) offset; + bs_trace_raw(0, "CPU #, Name , Autostart\n"); + bs_trace_raw(0, "-------------------------------\n"); + for (int i = 0; i < NSI_N_CPUS; i++) { + bs_trace_raw(0, "CPU %2i, %12s, %i\n", + i, nhw_get_core_name(i), nsi_cpu_get_auto_start(i)); + } +} + static void bsim_register_basic_args(void) { #define args (&global_args) @@ -106,6 +120,13 @@ static void bsim_register_basic_args(void) .type = 'l', .descript = "The arguments that follow will be passed to main (default)" }, + { + .is_switch = true, + .option = "cpu_print_info", + .call_when_found = print_mcus_info, + .type = 'b', + .descript = "Print information about each MCUs", + }, ARG_TABLE_ENDMARKER }; #undef args From d116a06a929f72d03e4eb88dd9cb498ee2e603db Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 14 Sep 2023 17:25:43 +0200 Subject: [PATCH 1411/4498] boards nrf_bsim: Add MCU number to traces When we have more than 1 MCU, add the MCU number to the traces so we can identify from which MCU they come from. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/CMakeLists.txt | 1 + boards/posix/nrf_bsim/common/trace_hook.c | 25 +++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/boards/posix/nrf_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt index 0a06623fe22..a9c8f684171 100644 --- a/boards/posix/nrf_bsim/CMakeLists.txt +++ b/boards/posix/nrf_bsim/CMakeLists.txt @@ -23,6 +23,7 @@ zephyr_library_sources( soc/nrfx_coredep.c common/bstests_entry.c common/cmsis/cmsis.c + common/trace_hook.c ) target_sources(native_simulator INTERFACE diff --git a/boards/posix/nrf_bsim/common/trace_hook.c b/boards/posix/nrf_bsim/common/trace_hook.c index 123eb4a22cc..55f491a2094 100644 --- a/boards/posix/nrf_bsim/common/trace_hook.c +++ b/boards/posix/nrf_bsim/common/trace_hook.c @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include "bs_tracing.h" @@ -14,21 +13,29 @@ * is down. */ +#if (CONFIG_NATIVE_SIMULATOR_NUMBER_MCUS > 1) +static const char *cpu_prefix = "CPU"; +static const unsigned int cpu_number = CONFIG_NATIVE_SIMULATOR_MCU_N; +#else +static const char *cpu_prefix; +static const unsigned int cpu_number; +#endif /* (CONFIG_NATIVE_SIMULATOR_NUMBER_MCUS > 1) */ + void posix_vprint_error_and_exit(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_ERROR, NULL, 0, 0, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_ERROR, cpu_prefix, cpu_number, 0, BS_TRACE_AUTOTIME, 0, format, vargs); } void posix_vprint_warning(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_WARNING, NULL, 0, 0, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_WARNING, cpu_prefix, cpu_number, 0, BS_TRACE_AUTOTIME, 0, format, vargs); } void posix_vprint_trace(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_RAW, NULL, 0, 2, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_RAW, cpu_prefix, cpu_number, 2, BS_TRACE_AUTOTIME, 0, format, vargs); } @@ -46,7 +53,7 @@ void posix_print_warning(const char *format, ...) va_list variable_argsp; va_start(variable_argsp, format); - bs_trace_vprint(BS_TRACE_WARNING, NULL, 0, 0, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_WARNING, cpu_prefix, cpu_number, 0, BS_TRACE_AUTOTIME, 0, format, variable_argsp); va_end(variable_argsp); } @@ -56,7 +63,7 @@ void posix_print_trace(const char *format, ...) va_list variable_argsp; va_start(variable_argsp, format); - bs_trace_vprint(BS_TRACE_RAW, NULL, 0, 2, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_RAW, cpu_prefix, cpu_number, 2, BS_TRACE_AUTOTIME, 0, format, variable_argsp); va_end(variable_argsp); } @@ -68,18 +75,18 @@ int posix_trace_over_tty(int file_number) void nsi_vprint_error_and_exit(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_ERROR, NULL, 0, 0, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_ERROR, cpu_prefix, cpu_number, 0, BS_TRACE_AUTOTIME, 0, format, vargs); } void nsi_vprint_warning(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_WARNING, NULL, 0, 0, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_WARNING, cpu_prefix, cpu_number, 0, BS_TRACE_AUTOTIME, 0, format, vargs); } void nsi_vprint_trace(const char *format, va_list vargs) { - bs_trace_vprint(BS_TRACE_RAW, NULL, 0, 2, BS_TRACE_AUTOTIME, 0, + bs_trace_vprint(BS_TRACE_RAW, cpu_prefix, cpu_number, 2, BS_TRACE_AUTOTIME, 0, format, vargs); } From b9f23b0c71a21d0fccf09bb28213ee2d2cc728ab Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 12 Sep 2023 10:26:24 +0200 Subject: [PATCH 1412/4498] nrf_bsim boards: Add new simulated nrf53 boards Add the first definition for the new simulated nrf5340 boards. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/Kconfig.board | 32 +++++ boards/posix/nrf_bsim/Kconfig.defconfig | 15 ++- boards/posix/nrf_bsim/board_soc.h | 12 +- .../nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts | 120 ++++++++++++++++++ .../nrf_bsim/nrf5340bsim_nrf5340_cpuapp.yaml | 14 ++ .../nrf5340bsim_nrf5340_cpuapp_defconfig | 6 + .../nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts | 77 +++++++++++ .../nrf_bsim/nrf5340bsim_nrf5340_cpunet.yaml | 14 ++ .../nrf5340bsim_nrf5340_cpunet_defconfig | 6 + 9 files changed, 289 insertions(+), 7 deletions(-) create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.yaml create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp_defconfig create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.yaml create mode 100644 boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet_defconfig diff --git a/boards/posix/nrf_bsim/Kconfig.board b/boards/posix/nrf_bsim/Kconfig.board index 8d0254b8fec..4a701c9acdc 100644 --- a/boards/posix/nrf_bsim/Kconfig.board +++ b/boards/posix/nrf_bsim/Kconfig.board @@ -15,3 +15,35 @@ config BOARD_NRF52_BSIM help Will produce a console Linux process which can be executed natively. It needs the BabbleSim simulator both in compile time and to execute + +config BOARD_NRF5340BSIM_NRF5340_CPUNET + bool "Simulated NRF53 Network core" + select SOC_SERIES_BSIM_NRFXX + select SOC_SERIES_BSIM_NRF53X + select SOC_COMPATIBLE_NRF + select SOC_COMPATIBLE_NRF53X + select SOC_COMPATIBLE_NRF5340_CPUNET + select NRF_RTC_TIMER + select CLOCK_CONTROL + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select NATIVE_LIBRARY + help + Will produce a console Linux process which can be executed natively. + It needs the BabbleSim simulator both in compile time and to execute + +config BOARD_NRF5340BSIM_NRF5340_CPUAPP + bool "Simulated NRF53 Application core" + select SOC_SERIES_BSIM_NRFXX + select SOC_SERIES_BSIM_NRF53X + select SOC_COMPATIBLE_NRF + select SOC_COMPATIBLE_NRF53X + select SOC_COMPATIBLE_NRF5340_CPUAPP + select NRF_RTC_TIMER + select CLOCK_CONTROL + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select NATIVE_LIBRARY + help + Will produce a console Linux process which can be executed natively. + It needs the BabbleSim simulator both in compile time and to execute diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 28cf8d1eec2..234e414158b 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -if BOARD_NRF52_BSIM +if SOC_SERIES_BSIM_NRFXX config BUILD_OUTPUT_BIN default n @@ -12,9 +12,16 @@ config OUTPUT_PRINT_MEMORY_USAGE default n config BOARD - default "nrf52_bsim" + default "nrf52_bsim" if BOARD_NRF52_BSIM + default "nrf5340bsim_nrf5340_cpunet" if BOARD_NRF5340BSIM_NRF5340_CPUNET + default "nrf5340bsim_nrf5340_cpuapp" if BOARD_NRF5340BSIM_NRF5340_CPUAPP + +config NATIVE_SIMULATOR_NUMBER_MCUS + default 2 if BOARD_NRF5340BSIM_NRF5340_CPUNET || BOARD_NRF5340BSIM_NRF5340_CPUAPP + default 1 config NATIVE_SIMULATOR_MCU_N + default 1 if BOARD_NRF5340BSIM_NRF5340_CPUNET default 0 config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -25,7 +32,7 @@ config SYS_CLOCK_TICKS_PER_SEC default 32768 config BT_CTLR - default y + default y if BOARD_NRF52_BSIM || BOARD_NRF5340BSIM_NRF5340_CPUNET depends on BT # The 15.4 driver Tx encryption is currently not functional with this @@ -54,4 +61,4 @@ config UART_CONSOLE endif # CONSOLE -endif # BOARD_NRF52_BSIM +endif # SOC_SERIES_BSIM_NRFXX diff --git a/boards/posix/nrf_bsim/board_soc.h b/boards/posix/nrf_bsim/board_soc.h index 7665d49993e..1b7e7a85c0c 100644 --- a/boards/posix/nrf_bsim/board_soc.h +++ b/boards/posix/nrf_bsim/board_soc.h @@ -16,8 +16,8 @@ * to define that kind of SOC related snippets */ -#ifndef _POSIX_NRF52_BOARD_SOC_H -#define _POSIX_NRF52_BOARD_SOC_H +#ifndef BOARDS_POSIX_NRF_BSIM_BOARD_SOC_H +#define BOARDS_POSIX_NRF_BSIM_BOARD_SOC_H #include #include @@ -30,7 +30,13 @@ #include #include "cmsis.h" +#if defined(CONFIG_BOARD_NRF52_BSIM) #define OFFLOAD_SW_IRQ SWI0_EGU0_IRQn +#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP) +#define OFFLOAD_SW_IRQ EGU0_IRQn +#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) +#define OFFLOAD_SW_IRQ SWI0_IRQn +#endif #define FLASH_PAGE_ERASE_MAX_TIME_US 89700UL #define FLASH_PAGE_MAX_CNT 256UL @@ -43,4 +49,4 @@ extern "C" { } #endif -#endif /* _POSIX_NRF52_BOARD_SOC_H */ +#endif /* BOARDS_POSIX_NRF_BSIM_BOARD_SOC_H */ diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts new file mode 100644 index 00000000000..b967c010653 --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Nordic NRF5340 BSIM NRF5340 Application"; + compatible = "bsim,nrf5340-bsim-nrf5340-cpuapp","bsim,nrf53"; + + /* We need to remove aliases to nodes we delete */ + aliases { + /delete-property/ sram-0; + /delete-property/ i2c-0; + /delete-property/ spi-0; + /delete-property/ uart-0; + /delete-property/ i2c-1; + /delete-property/ spi-1; + /delete-property/ uart-1; + /delete-property/ spi-4; + /delete-property/ i2c-2; + /delete-property/ spi-2; + /delete-property/ uart-2; + /delete-property/ i2c-3; + /delete-property/ spi-3; + /delete-property/ uart-3; + /delete-property/ wdt-0; + /delete-property/ wdt-1; + /delete-property/ pwm-0; + /delete-property/ pwm-1; + /delete-property/ pwm-2; + /delete-property/ pwm-3; + /delete-property/ pdm-0; + /delete-property/ i2s-0; + /delete-property/ qdec-0; + /delete-property/ qdec-1; + /delete-property/ gpio-0; + /delete-property/ gpio-1; + /delete-property/ gpiote-0; + }; + + chosen { + zephyr,flash = &flash0; + }; + + soc { + /delete-node/ memory@20000000; + peripheral@50000000 { + /delete-node/ dcnf@0; + /delete-node/ oscillator@4000; + /delete-node/ regulator@4000; + /delete-node/ ctrlap@6000; + /delete-node/ i2c@8000; + /delete-node/ spi@8000; + /delete-node/ uart@8000; + /delete-node/ i2c@9000; + /delete-node/ spi@9000; + /delete-node/ uart@9000; + /delete-node/ spi@a000; + /delete-node/ i2c@b000; + /delete-node/ spi@b000; + /delete-node/ uart@b000; + /delete-node/ i2c@c000; + /delete-node/ spi@c000; + /delete-node/ uart@c000; + /delete-node/ adc@e000; + /delete-node/ watchdog@18000; + /delete-node/ watchdog@19000; + /delete-node/ comparator@1a000; + /delete-node/ pwm@21000; + /delete-node/ pwm@22000; + /delete-node/ pwm@23000; + /delete-node/ pwm@24000; + /delete-node/ pdm@26000; + /delete-node/ i2s@28000; + /delete-node/ mbox@2a000; + /delete-node/ qspi@2b000; + /delete-node/ nfct@2d000; + /delete-node/ mutex@30000; + /delete-node/ qdec@33000; + /delete-node/ qdec@34000; + /delete-node/ usbd@36000; + /delete-node/ regulator@37000; + /delete-node/ kmu@39000; + /delete-node/ vmc@81000; + /delete-node/ gpio@842500; + /delete-node/ gpio@842800; + }; + /delete-node/ spu@50003000; + /delete-node/ gpiote@5000d000; + /delete-node/ crypto@50844000; + }; + + /delete-node/ cpus; + /delete-node/ ipc; + /delete-node/ sw-pwm; +}; + +&ieee802154 { + status = "okay"; +}; + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 DT_SIZE_K(1024)>; + }; + }; +}; diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.yaml b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.yaml new file mode 100644 index 00000000000..822368df0d3 --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.yaml @@ -0,0 +1,14 @@ +identifier: nrf5340bsim_nrf5340_cpuapp +name: NRF53 BabbleSim - Application Core target +type: native +arch: posix +simulation: native +env: + - BSIM_OUT_PATH +toolchain: + - zephyr +testing: + ignore_tags: + - gpio + - modem + - uart diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp_defconfig b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp_defconfig new file mode 100644 index 00000000000..fcf14c5b33a --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_POSIX=y +CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP=y +CONFIG_CONSOLE=y +CONFIG_NO_OPTIMIZATIONS=y diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts new file mode 100644 index 00000000000..138cde81ef1 --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Nordic NRF5340 BSIM NRF5340 Network"; + compatible = "bsim,nrf5340-bsim-nrf5340-cpunet","bsim,nrf53"; + + /* We need to remove aliases to nodes we delete */ + aliases { + /delete-property/ sram-0; + /delete-property/ sram-1; + /delete-property/ gpiote-0; + /delete-property/ wdt-0; + /delete-property/ i2c-0; + /delete-property/ spi-0; + /delete-property/ uart-0; + /delete-property/ gpio-0; + /delete-property/ gpio-1; + }; + + chosen { + zephyr,ieee802154 = &ieee802154; + /delete-property/ zephyr,flash-controller; + zephyr,flash = &flash1; + }; + + soc { + /delete-node/ memory@20000000; + /delete-node/ memory@21000000; + /delete-node/ gpiote@4100a000; + /delete-node/ watchdog@4100b000; + /delete-node/ mbox@41012000; + /delete-node/ i2c@41013000; + /delete-node/ spi@41013000; + /delete-node/ uart@41013000; + /delete-node/ acl@41080000; + /delete-node/ vmc@41081000; + /delete-node/ gpio@418c0500; + /delete-node/ gpio@418c0800; + }; + + /delete-node/ cpus; + /delete-node/ ipc; + /delete-node/ sw-pwm; +}; + +&radio { + /* These features are not yet supported by the RADIO model */ + /delete-property/ dfe-supported; + /delete-property/ ble-coded-phy-supported; +}; + +&ieee802154 { + status = "okay"; +}; + +&flash1 { + reg = <0x01000000 DT_SIZE_K(256)>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 DT_SIZE_K(256)>; + }; + }; +}; diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.yaml b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.yaml new file mode 100644 index 00000000000..4e305c095d3 --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.yaml @@ -0,0 +1,14 @@ +identifier: nrf5340bsim_nrf5340_cpunet +name: NRF53 Net Core BabbleSim board +type: native +arch: posix +simulation: native +env: + - BSIM_OUT_PATH +toolchain: + - zephyr +testing: + ignore_tags: + - gpio + - modem + - uart diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet_defconfig b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet_defconfig new file mode 100644 index 00000000000..5da7b71af05 --- /dev/null +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_POSIX=y +CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET=y +CONFIG_CONSOLE=y +CONFIG_NO_OPTIMIZATIONS=y From dd2eefb1cefb09b74271de24be1fbf253d7dbd09 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 18 Sep 2023 12:22:16 +0200 Subject: [PATCH 1413/4498] nrf_bsim: nrf53_bsim_cpunet: Automatically start CPU Automatically start the Network domain CPU during HW boot. In the real HW this CPU is held on reset until something else (Typically the application MCU) releases it. But doing so facilitates running tests in this MCU as there is no requirement for an image for the application core. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 234e414158b..6b44f44b07d 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -24,6 +24,9 @@ config NATIVE_SIMULATOR_MCU_N default 1 if BOARD_NRF5340BSIM_NRF5340_CPUNET default 0 +config NATIVE_SIMULATOR_AUTOSTART_MCU + default y if BOARD_NRF5340BSIM_NRF5340_CPUNET + config SYS_CLOCK_HW_CYCLES_PER_SEC default 32768 From 6ef42d0b809177ef8eaa5e8cc58f33d6b38bfb19 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 13:12:06 +0200 Subject: [PATCH 1414/4498] boards nrf53_bsim: Set net core as primary So it gets the command line arguments by default. This eases running the BT test which run on the nrf52_bsim. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/Kconfig.defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 6b44f44b07d..5dc75661117 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -27,6 +27,10 @@ config NATIVE_SIMULATOR_MCU_N config NATIVE_SIMULATOR_AUTOSTART_MCU default y if BOARD_NRF5340BSIM_NRF5340_CPUNET +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + default 1 if SOC_SERIES_BSIM_NRF53X + default 0 + config SYS_CLOCK_HW_CYCLES_PER_SEC default 32768 From 2243d7b717e090025c7915db23a7392f26d1b64f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Sep 2023 09:53:02 +0200 Subject: [PATCH 1415/4498] Bluetooth controller nrf: Provide radio hal header for simulated nrf5340 Provide a radio HAL header for the new nrf53 bsim target Signed-off-by: Alberto Escolar Piedras --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 2 + .../nordic/hal/nrf5/radio/radio_sim_nrf5340.h | 431 ++++++++++++++++++ 2 files changed, 433 insertions(+) create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 9e29ab5f70b..842b4189184 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -17,6 +17,8 @@ /* SoC specific defines */ #if defined(CONFIG_BOARD_NRF52_BSIM) #include "radio_sim_nrf52.h" +#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) +#include "radio_sim_nrf5340.h" #elif defined(CONFIG_SOC_SERIES_NRF51X) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h new file mode 100644 index 00000000000..c0cd88b30b0 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2019 Ioannis Glaropoulos + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* NRF Radio HW timing constants + * - provided in US and NS (for higher granularity) + * - based on the timings configured in the HW models, which are based + * on the product specification + * - Note that this timings are approx. the same as in the real HW, + * but tend to be rounded to the nearest microsecond + */ + +/* Override EVENT_TIMER_ID from 4 to 0, as nRF5340 does not have 4 timer + * instances. + */ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#undef EVENT_TIMER_ID +#define EVENT_TIMER_ID 0 + +#undef EVENT_TIMER +#define EVENT_TIMER _CONCAT(NRF_TIMER, EVENT_TIMER_ID) + +#undef SW_SWITCH_TIMER +#define SW_SWITCH_TIMER EVENT_TIMER +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS 41000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS 141000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode + * and no HW TIFS auto-switch) in microseconds for LE 1M PHY. + */ + /* 129.5 + 0.8 */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS 130000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS 40000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS 140000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS 129000 +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS 40000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS 140000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 1M PHY. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS 129000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS 40000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS 140000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS 129000 +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS) + +#define HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS 1000 +#define HAL_RADIO_NRF5340_TX_CHAIN_DELAY_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS) + +#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_US 9 +#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_NS 9000 +#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_US 5 +#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_NS 5000 + +#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS + +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS + +#else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ +#if defined(CONFIG_BT_CTLR_TIFS_HW) +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS + +#else /* !CONFIG_BT_CTLR_TIFS_HW */ +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS + +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ +#endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ + +/* nRF5340 supports +3dBm Tx Power using high voltage request, define +3dBm + * value for Controller use. + */ +#ifndef RADIO_TXPOWER_TXPOWER_Pos3dBm +#define RADIO_TXPOWER_TXPOWER_Pos3dBm (0x03UL) +#endif + +/* SoC specific NRF_RADIO power-on reset value. Refer to Product Specification, + * RADIO Registers section for the documented reset values. + * + * NOTE: Only implementation used values defined here. + * In the future if MDK or nRFx header include these, use them instead. + */ +#define HAL_RADIO_RESET_VALUE_DFEMODE 0x00000000UL +#define HAL_RADIO_RESET_VALUE_CTEINLINECONF 0x00002800UL + +static inline void hal_radio_tx_power_high_voltage_clear(void); + +static inline void hal_radio_reset(void) +{ +} + +static inline void hal_radio_stop(void) +{ + /* If +3dBm Tx power was used, then turn off high voltage when radio not + * used. + */ + hal_radio_tx_power_high_voltage_clear(); +} + +static inline void hal_radio_ram_prio_setup(void) +{ +} + +static inline uint32_t hal_radio_phy_mode_get(uint8_t phy, uint8_t flags) +{ + uint32_t mode; + + switch (phy) { + case BIT(0): + default: + mode = RADIO_MODE_MODE_Ble_1Mbit; + break; + + case BIT(1): + mode = RADIO_MODE_MODE_Ble_2Mbit; + break; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + mode = RADIO_MODE_MODE_Ble_LR125Kbit; + } else { + mode = RADIO_MODE_MODE_Ble_LR500Kbit; + } + break; +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } + + return mode; +} + +static inline uint32_t hal_radio_tx_power_max_get(void) +{ + return RADIO_TXPOWER_TXPOWER_0dBm; +} + +static inline uint32_t hal_radio_tx_power_min_get(void) +{ + return RADIO_TXPOWER_TXPOWER_Neg40dBm; +} + +static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) +{ + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { + return RADIO_TXPOWER_TXPOWER_0dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) { + return RADIO_TXPOWER_TXPOWER_Neg1dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) { + return RADIO_TXPOWER_TXPOWER_Neg2dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { + return RADIO_TXPOWER_TXPOWER_Neg3dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { + return RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm) { + return RADIO_TXPOWER_TXPOWER_Neg5dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm) { + return RADIO_TXPOWER_TXPOWER_Neg6dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm) { + return RADIO_TXPOWER_TXPOWER_Neg7dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { + return RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { + return RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { + return RADIO_TXPOWER_TXPOWER_Neg16dBm; + } + + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { + return RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + + /* Note: The -30 dBm power level is deprecated so ignore it! */ + return RADIO_TXPOWER_TXPOWER_Neg40dBm; +} + +static inline void hal_radio_tx_power_high_voltage_set(int8_t tx_power_lvl) +{ + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { + nrf_vreqctrl_radio_high_voltage_set(NRF_VREQCTRL, true); + } +} + +static inline void hal_radio_tx_power_high_voltage_clear(void) +{ + nrf_vreqctrl_radio_high_voltage_set(NRF_VREQCTRL, false); +} + +static inline uint32_t hal_radio_tx_ready_delay_us_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US; + case BIT(1): + return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US; + } +} + +static inline uint32_t hal_radio_rx_ready_delay_us_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US; + case BIT(1): + return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US; + } +} + +static inline uint32_t hal_radio_tx_chain_delay_us_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(phy); + ARG_UNUSED(flags); + + return HAL_RADIO_NRF5340_TX_CHAIN_DELAY_US; +} + +static inline uint32_t hal_radio_rx_chain_delay_us_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_US; + case BIT(1): + return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_US; + } +} + +static inline uint32_t hal_radio_tx_ready_delay_ns_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS; + } +} + +static inline uint32_t hal_radio_rx_ready_delay_ns_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS; + } +} + +static inline uint32_t hal_radio_tx_chain_delay_ns_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(phy); + ARG_UNUSED(flags); + + return HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS; +} + +static inline uint32_t hal_radio_rx_chain_delay_ns_get(uint8_t phy, uint8_t flags) +{ + ARG_UNUSED(flags); + + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_NS; + case BIT(1): + return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_NS; + + } +} From e021108ace8788c3a22ed833aef758823e2604b6 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Mon, 11 Sep 2023 11:35:38 +0700 Subject: [PATCH 1416/4498] misc: nxp_s32_emios: enable and declare interrupt handler This enables and declares interrupt handlers for eMIOS, the handlers defined and implemented at HAL, the driver takes the name for each id from interrupt-names devicetree Signed-off-by: Dat Nguyen Duy --- drivers/misc/nxp_s32_emios/nxp_s32_emios.c | 35 ++++++++++++++++++++++ dts/arm/nxp/nxp_s32k344_m7.dtsi | 6 ++++ dts/bindings/misc/nxp,s32-emios.yaml | 9 ++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/misc/nxp_s32_emios/nxp_s32_emios.c b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c index fd0a8c891ae..d22d94b3015 100644 --- a/drivers/misc/nxp_s32_emios/nxp_s32_emios.c +++ b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c @@ -12,12 +12,14 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_NXP_S32_EMIOS_LOG_LEVEL); #include +#include #define DT_DRV_COMPAT nxp_s32_emios struct nxp_s32_emios_config { uint8_t instance; Emios_Mcl_Ip_ConfigType *mcl_info; + void (*irq_config)(void); }; static int nxp_s32_emios_init(const struct device *dev) @@ -29,6 +31,8 @@ static int nxp_s32_emios_init(const struct device *dev) return -EINVAL; } + config->irq_config(); + return 0; } @@ -87,11 +91,42 @@ static int nxp_s32_emios_init(const struct device *dev) .masterBusConfig = &nxp_s32_emios_##n##_master_bus_config \ }; +#define EMIOS_INTERRUPT_NAME(name) DT_CAT3(EMIOS, name, _IRQ) + +/* + * The real interrupt handlers only defined in some circumstances, just add + * weak implementations to avoid populating so many preprocessor directives + */ +#define EMIOS_INTERRUPT_DEFINE(node_id, prop, idx) \ + __weak void EMIOS_INTERRUPT_NAME(DT_STRING_TOKEN_BY_IDX(node_id, prop, idx))(void) {} + +#define NXP_S32_EMIOS_INTERRUPT_DEFINE(n) \ + DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, EMIOS_INTERRUPT_DEFINE) + +#define EMIOS_INTERRUPT_CONFIG(node_id, prop, idx) \ + do { \ + IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \ + DT_IRQ_BY_IDX(node_id, idx, priority), \ + EMIOS_INTERRUPT_NAME(DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)),\ + DEVICE_DT_GET(node_id), \ + 0); \ + irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ + } while (false); + +#define NXP_S32_EMIOS_INTERRUPT_CONFIG(n) \ + static void nxp_s32_emios_##n##_interrupt_config(void) \ + { \ + DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, EMIOS_INTERRUPT_CONFIG) \ + } + #define NXP_S32_EMIOS_INIT_DEVICE(n) \ NXP_S32_EMIOS_GENERATE_CONFIG(n) \ + NXP_S32_EMIOS_INTERRUPT_DEFINE(n) \ + NXP_S32_EMIOS_INTERRUPT_CONFIG(n) \ const struct nxp_s32_emios_config nxp_s32_emios_##n##_config = { \ .instance = NXP_S32_EMIOS_GET_INSTANCE(n), \ .mcl_info = (Emios_Mcl_Ip_ConfigType *)&nxp_s32_emios_##n##_mcl_config, \ + .irq_config = nxp_s32_emios_##n##_interrupt_config, \ }; \ DEVICE_DT_INST_DEFINE(n, \ &nxp_s32_emios_init, \ diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index dbec883c7c2..05836148f56 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -624,6 +624,8 @@ clocks = <&clock NXP_S32_EMIOS0_CLK>; interrupts = <61 0>, <62 0>, <63 0>, <64 0>, <65 0>, <66 0>; + interrupt-names = "0_0", "0_1", "0_2", + "0_3", "0_4", "0_5"; status = "disabled"; master_bus { @@ -676,6 +678,8 @@ clocks = <&clock NXP_S32_EMIOS1_CLK>; interrupts = <69 0>, <70 0>, <71 0>, <72 0>, <73 0>, <74 0>; + interrupt-names = "1_0", "1_1", "1_2", + "1_3", "1_4", "1_5"; status = "disabled"; master_bus { @@ -728,6 +732,8 @@ clocks = <&clock NXP_S32_EMIOS2_CLK>; interrupts = <77 0>, <78 0>, <79 0>, <80 0>, <81 0>, <82 0>; + interrupt-names = "2_0", "2_1", "2_2", + "2_3", "2_4", "2_5"; status = "disabled"; master_bus { diff --git a/dts/bindings/misc/nxp,s32-emios.yaml b/dts/bindings/misc/nxp,s32-emios.yaml index b08c7f6596d..d6b86899ec0 100644 --- a/dts/bindings/misc/nxp,s32-emios.yaml +++ b/dts/bindings/misc/nxp,s32-emios.yaml @@ -15,6 +15,15 @@ properties: reg: required: true + interrupts: + required: true + + interrupt-names: + required: true + + clocks: + required: true + clock-divider: type: int required: true From 05fd40012fb19aeb1fa3830d55d4696e968e797a Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Sun, 24 Sep 2023 00:01:23 +0700 Subject: [PATCH 1417/4498] drivers: pwm_nxp_s32_emios: prepare for support pwm capture This prepares support pwm capture APIs by extended current pwm shim driver but use a differrence hal component: - Introduce a Kconfig options that will be set when PWM pulse generation API is used, it is also used to select the hal component. Guarding current code inside this Kconfig option - Increase #pwm-cells to 3, flags is supported for PWM capture - Do not require duty-cycle and polarity be set in dt, PWM capture doesn't need it. - Rename emum value for pwm-mode to keep only key information - Add preprocessor in case no channel is configured for generate PWM output, to avoid warning when build Signed-off-by: Dat Nguyen Duy --- boards/arm/mr_canhubk3/mr_canhubk3.dts | 28 ++--- drivers/pwm/pwm_nxp_s32_emios.c | 156 +++++++++++++++++------- dts/arm/nxp/nxp_s32k344_m7.dtsi | 6 +- dts/bindings/pwm/nxp,s32-emios-pwm.yaml | 20 +-- 4 files changed, 141 insertions(+), 69 deletions(-) diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index bb9ff2b5055..ec5eb1ece43 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -65,15 +65,15 @@ compatible = "pwm-leds"; user_led1_blue_pwm: user_led1_blue { - pwms = <&emios1_pwm 5 PWM_MSEC(20)>; + pwms = <&emios1_pwm 5 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; user_led1_green_pwm: user_led1_green { - pwms = <&emios1_pwm 10 PWM_MSEC(20)>; + pwms = <&emios1_pwm 10 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; user_led1_red_pwm: user_led1_red { - pwms = <&emios0_pwm 19 PWM_MSEC(20)>; + pwms = <&emios0_pwm 19 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; @@ -441,7 +441,7 @@ /* Default clock for internal counter for PWM channel 0-7 is 100Khz */ pwm_0 { channel = <0>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -450,7 +450,7 @@ pwm_1 { channel = <1>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -459,7 +459,7 @@ pwm_2 { channel = <2>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -468,7 +468,7 @@ pwm_3 { channel = <3>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -477,7 +477,7 @@ pwm_4 { channel = <4>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -486,7 +486,7 @@ pwm_5 { channel = <5>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -495,7 +495,7 @@ pwm_6 { channel = <6>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -504,7 +504,7 @@ pwm_7 { channel = <7>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; period = <65535>; duty-cycle = <0>; prescaler = <8>; @@ -515,7 +515,7 @@ channel = <19>; master-bus = <&emios0_bus_a>; duty-cycle = <0>; - pwm-mode = "MODE_OPWMB"; + pwm-mode = "OPWMB"; polarity = "ACTIVE_LOW"; }; }; @@ -554,7 +554,7 @@ channel = <10>; master-bus = <&emios1_bus_a>; duty-cycle = <0>; - pwm-mode = "MODE_OPWMB"; + pwm-mode = "OPWMB"; polarity = "ACTIVE_LOW"; }; @@ -562,7 +562,7 @@ channel = <5>; master-bus = <&emios1_bus_f>; duty-cycle = <0>; - pwm-mode = "MODE_OPWMB"; + pwm-mode = "OPWMB"; polarity = "ACTIVE_LOW"; }; }; diff --git a/drivers/pwm/pwm_nxp_s32_emios.c b/drivers/pwm/pwm_nxp_s32_emios.c index f090ba70e88..2d2fb1c75d1 100644 --- a/drivers/pwm/pwm_nxp_s32_emios.c +++ b/drivers/pwm/pwm_nxp_s32_emios.c @@ -8,6 +8,7 @@ #include #include #include + #include #include @@ -21,16 +22,23 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL); * Need to fill to this array at runtime, cannot do at build time like * the HAL over configuration tool due to limitation of the integration */ +#if EMIOS_PWM_IP_USED extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT]; +#endif struct pwm_nxp_s32_data { uint32_t emios_clk; +#if EMIOS_PWM_IP_USED + uint8_t start_pwm_ch; +#endif }; +#if EMIOS_PWM_IP_USED struct pwm_nxp_s32_pulse_info { uint8_t pwm_pulse_channels; Emios_Pwm_Ip_ChannelConfigType *pwm_info; }; +#endif struct pwm_nxp_s32_config { eMIOS_Type *base; @@ -38,9 +46,13 @@ struct pwm_nxp_s32_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; const struct pinctrl_dev_config *pincfg; + +#if EMIOS_PWM_IP_USED struct pwm_nxp_s32_pulse_info *pulse_info; +#endif }; +#if EMIOS_PWM_IP_USED #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED static int pwm_nxp_s32_set_cycles_internal_timebase(uint8_t instance, uint32_t channel, uint32_t period_cycles, uint32_t pulse_cycles) @@ -116,26 +128,31 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel, pwm_flags_t flags) { const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; - Emios_Pwm_Ip_PwmModeType mode; + Emios_Pwm_Ip_ChannelConfigType *pwm_info; + uint8_t logic_ch; if (channel >= EMIOS_PWM_IP_CHANNEL_COUNT) { LOG_ERR("invalid channel %d", channel); return -EINVAL; } - mode = Emios_Pwm_Ip_GetChannelMode(config->instance, channel); - if (mode == EMIOS_PWM_IP_MODE_NODEFINE) { + if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] >= + EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) { LOG_ERR("Channel %d is not configured for PWM", channel); return -EINVAL; } - if (flags) { + logic_ch = eMios_Pwm_Ip_IndexInChState[config->instance][channel] - data->start_pwm_ch; + pwm_info = &config->pulse_info->pwm_info[logic_ch]; + + if ((flags & PWM_POLARITY_MASK) == pwm_info->OutputPolarity) { LOG_ERR("Only support configuring output polarity at boot time"); return -ENOTSUP; } - switch (mode) { + switch (pwm_info->Mode) { #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED case EMIOS_PWM_IP_MODE_OPWFMB_FLAG: return pwm_nxp_s32_set_cycles_internal_timebase(config->instance, channel, @@ -174,6 +191,7 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel, return 0; } +#endif static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, uint32_t channel, @@ -182,14 +200,21 @@ static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, const struct pwm_nxp_s32_config *config = dev->config; struct pwm_nxp_s32_data *data = dev->data; - uint8_t internal_prescaler, global_prescaler, master_bus; + uint8_t master_bus = 0xFFU; + uint8_t internal_prescaler, global_prescaler; - if (Emios_Pwm_Ip_GetChannelMode(config->instance, channel) == EMIOS_PWM_IP_MODE_NODEFINE) { +#if EMIOS_PWM_IP_USED + if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] < + EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) { + master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel); + } +#endif + + if (master_bus == 0xFFU) { LOG_ERR("Channel %d is not configured for PWM", channel); return -EINVAL; } - master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel); internal_prescaler = (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCEXTPRE_MASK) >> eMIOS_C2_UCEXTPRE_SHIFT; @@ -205,17 +230,36 @@ static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, return 0; } -static int pwm_nxp_s32_init(const struct device *dev) +#if EMIOS_PWM_IP_USED +static int pwm_nxp_s32_pulse_gen_init(const struct device *dev) { const struct pwm_nxp_s32_config *config = dev->config; struct pwm_nxp_s32_data *data = dev->data; const Emios_Pwm_Ip_ChannelConfigType *pwm_info; - int err = 0; - uint8_t ch_id; + uint8_t ch_id; static uint8_t logic_ch; + data->start_pwm_ch = logic_ch; + + for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) { + pwm_info = &config->pulse_info->pwm_info[ch_id]; + eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++; + Emios_Pwm_Ip_InitChannel(config->instance, pwm_info); + } + + return 0; +} +#endif + +static int pwm_nxp_s32_init(const struct device *dev) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + int err = 0; + if (!device_is_ready(config->clock_dev)) { return -ENODEV; } @@ -230,11 +274,12 @@ static int pwm_nxp_s32_init(const struct device *dev) return err; } - for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) { - pwm_info = &config->pulse_info->pwm_info[ch_id]; - eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++; - Emios_Pwm_Ip_InitChannel(config->instance, pwm_info); +#if EMIOS_PWM_IP_USED + err = pwm_nxp_s32_pulse_gen_init(dev); + if (err < 0) { + return err; } +#endif return err; } @@ -244,18 +289,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .get_cycles_per_sec = pwm_nxp_s32_get_cycles_per_sec, }; -/* Macros used to glue devicetree with RTD's definition */ -#define BUS_A EMIOS_PWM_IP_BUS_A -#define BUS_B EMIOS_PWM_IP_BUS_BCDE -#define BUS_C EMIOS_PWM_IP_BUS_BCDE -#define BUS_D EMIOS_PWM_IP_BUS_BCDE -#define BUS_E EMIOS_PWM_IP_BUS_BCDE -#define BUS_F EMIOS_PWM_IP_BUS_F - -#define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_, mode, _FLAG) -#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode) -#define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode) - /* * If timebase is configured in MCB up/down count mode: pwm period = (2 * master bus's period - 2) */ @@ -265,24 +298,31 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { (DT_PROP_BY_PHANDLE(node_id, master_bus, period))) #define EMIOS_PWM_IS_MODE_OPWFMB(node_id) \ - DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWFMB) + DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWFMB) #define EMIOS_PWM_IS_MODE_OPWMCB(node_id) \ - UTIL_OR(DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_TRAIL_EDGE), \ - DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_LEAD_EDGE)) \ + UTIL_OR(DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMCB_TRAIL_EDGE), \ + DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMCB_LEAD_EDGE)) \ #define EMIOS_PWM_IS_MODE_OPWMB(node_id) \ - DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMB) + DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMB) + +#define EMIOS_PWM_LOG(node_id, msg) \ + DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \ #define EMIOS_PWM_VERIFY_MASTER_BUS(node_id) \ BUILD_ASSERT(BIT(DT_PROP(node_id, channel)) & \ DT_PROP_BY_PHANDLE(node_id, master_bus, channel_mask), \ - "Node "DT_NODE_PATH(node_id)": invalid master bus"); + EMIOS_PWM_LOG(node_id, "invalid master bus")); -#define EMIOS_PWM_LOG(node_id, msg) \ - DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \ +#define EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ + BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, duty_cycle), \ + EMIOS_PWM_LOG(node_id, "duty-cycle must be configured")); \ + BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, polarity), \ + EMIOS_PWM_LOG(node_id, "polarity must be configured")); #define EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id) \ + EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, period), \ EMIOS_PWM_LOG(node_id, "period must be configured")); \ BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), EMIOS_PWM_IP_MIN_CNT_VAL + 1, \ @@ -298,6 +338,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { EMIOS_PWM_LOG(node_id, "phase-shift must not be configured")); #define EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id) \ + EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, \ MCB_UP_DOWN_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up-down")); \ @@ -319,6 +360,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { " always use prescalered source")); \ #define EMIOS_PWM_VERIFY_MODE_OPWMB(node_id) \ + EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ @@ -335,7 +377,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \ " always use prescalered source")); \ -#define EMIOS_PWM_VERIFY_CONFIG(node_id) \ +#define _EMIOS_PWM_VERIFY_CONFIG(node_id) \ IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ (EMIOS_PWM_VERIFY_MASTER_BUS(node_id))) \ IF_ENABLED(EMIOS_PWM_IS_MODE_OPWFMB(node_id), \ @@ -345,15 +387,31 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { IF_ENABLED(EMIOS_PWM_IS_MODE_OPWMB(node_id), \ (EMIOS_PWM_VERIFY_MODE_OPWMB(node_id))) \ -#define EMIOS_PWM_CONFIG(node_id) \ +#if EMIOS_PWM_IP_USED +/* Macros used to glue devicetree with RTD's definition */ +#define EMIOS_PWM_BUS_A EMIOS_PWM_IP_BUS_A +#define EMIOS_PWM_BUS_B EMIOS_PWM_IP_BUS_BCDE +#define EMIOS_PWM_BUS_C EMIOS_PWM_IP_BUS_BCDE +#define EMIOS_PWM_BUS_D EMIOS_PWM_IP_BUS_BCDE +#define EMIOS_PWM_BUS_E EMIOS_PWM_IP_BUS_BCDE +#define EMIOS_PWM_BUS_F EMIOS_PWM_IP_BUS_F + +#define EMIOS_PWM_BUS(mode) DT_CAT(EMIOS_PWM_, mode) +#define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_MODE_, mode, _FLAG) +#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode) +#define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode) + +#define _EMIOS_PWM_PULSE_GEN_CONFIG(node_id) \ { \ .ChannelId = DT_PROP(node_id, channel), \ .Mode = EMIOS_PWM_MODE(DT_STRING_TOKEN(node_id, pwm_mode)), \ .InternalPsSrc = EMIOS_PWM_PS_SRC(DT_STRING_TOKEN(node_id, prescaler_src)), \ .InternalPs = DT_PROP_OR(node_id, prescaler, \ DT_PROP_BY_PHANDLE(node_id, master_bus, prescaler)) - 1,\ - .Timebase = DT_STRING_TOKEN_OR(DT_PHANDLE(node_id, master_bus), bus_type, \ - EMIOS_PWM_IP_BUS_INTERNAL), \ + .Timebase = COND_CODE_1(DT_NODE_HAS_PROP(node_id, master_bus), \ + (EMIOS_PWM_BUS(DT_STRING_TOKEN( \ + DT_PHANDLE(node_id, master_bus), bus_type))), \ + (EMIOS_PWM_IP_BUS_INTERNAL)), \ .PhaseShift = DT_PROP(node_id, phase_shift), \ .DeadTime = DT_PROP(node_id, dead_time), \ .OutputDisableSource = EMIOS_PWM_IP_OUTPUT_DISABLE_NONE, \ @@ -363,16 +421,25 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .DutyCycle = DT_PROP(node_id, duty_cycle), \ }, -#define EMIOS_PWM_GENERATE_CONFIG(n) \ - DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_VERIFY_CONFIG) \ +#define EMIOS_PWM_PULSE_GEN_CONFIG(n) \ const Emios_Pwm_Ip_ChannelConfigType emios_pwm_##n##_init[] = { \ - DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_CONFIG) \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _EMIOS_PWM_PULSE_GEN_CONFIG) \ }; \ const struct pwm_nxp_s32_pulse_info emios_pwm_##n##_info = { \ .pwm_pulse_channels = ARRAY_SIZE(emios_pwm_##n##_init), \ .pwm_info = (Emios_Pwm_Ip_ChannelConfigType *)emios_pwm_##n##_init, \ }; +#define EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) \ + .pulse_info = (struct pwm_nxp_s32_pulse_info *)&emios_pwm_##n##_info, +#else +#define EMIOS_PWM_PULSE_GEN_CONFIG(n) +#define EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) +#endif + +#define EMIOS_PWM_VERIFY_CONFIG(n) \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _EMIOS_PWM_VERIFY_CONFIG) + #define EMIOS_NXP_S32_INSTANCE_CHECK(idx, node_id) \ ((DT_REG_ADDR(node_id) == IP_EMIOS_##idx##_BASE) ? idx : 0) @@ -381,14 +448,15 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #define PWM_NXP_S32_INIT_DEVICE(n) \ PINCTRL_DT_INST_DEFINE(n); \ - EMIOS_PWM_GENERATE_CONFIG(n) \ + EMIOS_PWM_VERIFY_CONFIG(n) \ + EMIOS_PWM_PULSE_GEN_CONFIG(n) \ static const struct pwm_nxp_s32_config pwm_nxp_s32_config_##n = { \ .base = (eMIOS_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ .instance = EMIOS_NXP_S32_GET_INSTANCE(DT_INST_PARENT(n)), \ .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \ .clock_subsys = (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name),\ - .pulse_info = (struct pwm_nxp_s32_pulse_info *)&emios_pwm_##n##_info, \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n) \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) \ }; \ static struct pwm_nxp_s32_data pwm_nxp_s32_data_##n; \ DEVICE_DT_INST_DEFINE(n, \ diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 05836148f56..5b03cf84244 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -667,7 +667,7 @@ pwm { compatible = "nxp,s32-emios-pwm"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; }; @@ -721,7 +721,7 @@ pwm { compatible = "nxp,s32-emios-pwm"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; }; @@ -775,7 +775,7 @@ pwm { compatible = "nxp,s32-emios-pwm"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; }; diff --git a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml index 17ed23f9e46..bea525676a0 100644 --- a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml +++ b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml @@ -1,3 +1,6 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + description: | NXP S32 eMIOS PWM node for S32 SoCs. Each channel in eMIOS can be configured to use for PWM operation. There are several PWM modes supported by this module, @@ -9,7 +12,7 @@ description: | emios0_pwm: pwm { pwm_0 { channel = <0>; - pwm-mode = "MODE_OPWFMB"; + pwm-mode = "OPWFMB"; prescaler = <8>; period = <65534>; duty-cycle = <32768>; @@ -19,7 +22,7 @@ description: | pwm_1 { channel = <1>; master-bus = <&emios1_bus_a>; - pwm-mode = "MODE_OPWMB"; + pwm-mode = "OPWMB"; duty-cycle = <32768>; phase-shift = <100>; polarity = "ACTIVE_LOW"; @@ -28,7 +31,7 @@ description: | pwm_2 { channel = <2>; master-bus = <&emios1_bus_b>; - pwm-mode = "MODE_OPWMCB_LEAD_EDGE"; + pwm-mode = "OPWMCB_LEAD_EDGE"; duty-cycle = <32768>; dead-time = <100>; polarity = "ACTIVE_LOW"; @@ -53,12 +56,13 @@ properties: required: true "#pwm-cells": - const: 2 + const: 3 pwm-cells: - channel # Period in terms of nanoseconds - period + - flags child-binding: description: | @@ -97,10 +101,10 @@ child-binding: at runtime will impact to all channels share the same timebase, The new period and cycle take effect in next period boundary. enum: - - "MODE_OPWFMB" - - "MODE_OPWMB" - - "MODE_OPWMCB_TRAIL_EDGE" - - "MODE_OPWMCB_LEAD_EDGE" + - "OPWFMB" + - "OPWMB" + - "OPWMCB_TRAIL_EDGE" + - "OPWMCB_LEAD_EDGE" polarity: type: string From 0b0988db2de9ce779f29b8400748085681e1970e Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Sun, 24 Sep 2023 00:44:25 +0700 Subject: [PATCH 1418/4498] drivers: pwm_nxp_s32_emios: add support for pwm capture This introduces pwm capture shim driver for NXP S32 EMIOS, the driver uses SAIC mode that is supported for all channels, to capture the counter value on each edge for period/pulse measurement Signed-off-by: Dat Nguyen Duy --- drivers/pwm/pwm_nxp_s32_emios.c | 416 +++++++++++++++++++++++- dts/arm/nxp/nxp_s32k344_m7.dtsi | 3 + dts/bindings/misc/nxp,s32-emios.yaml | 6 + dts/bindings/pwm/nxp,s32-emios-pwm.yaml | 36 +- 4 files changed, 440 insertions(+), 21 deletions(-) diff --git a/drivers/pwm/pwm_nxp_s32_emios.c b/drivers/pwm/pwm_nxp_s32_emios.c index 2d2fb1c75d1..e5a0513fb2f 100644 --- a/drivers/pwm/pwm_nxp_s32_emios.c +++ b/drivers/pwm/pwm_nxp_s32_emios.c @@ -12,6 +12,10 @@ #include #include +#ifdef CONFIG_PWM_CAPTURE +#include +#endif + #define LOG_MODULE_NAME nxp_s32_emios_pwm #include LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL); @@ -26,11 +30,32 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL); extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT]; #endif +#ifdef CONFIG_PWM_CAPTURE +extern uint8 eMios_Icu_Ip_IndexInChState[EMIOS_ICU_IP_INSTANCE_COUNT][EMIOS_ICU_IP_NUM_OF_CHANNELS]; + +/* We need maximum three edges for measure both period and cycle */ +#define MAX_NUM_EDGE 3 + +struct pwm_nxp_s32_capture_data { + bool continuous; + bool inverted; + bool pulse_capture; + bool period_capture; + void *user_data; + pwm_capture_callback_handler_t callback; + eMios_Icu_ValueType edge_buff[MAX_NUM_EDGE]; +}; +#endif + struct pwm_nxp_s32_data { uint32_t emios_clk; #if EMIOS_PWM_IP_USED uint8_t start_pwm_ch; #endif + +#ifdef CONFIG_PWM_CAPTURE + struct pwm_nxp_s32_capture_data capture[EMIOS_ICU_IP_NUM_OF_CHANNELS]; +#endif }; #if EMIOS_PWM_IP_USED @@ -50,6 +75,10 @@ struct pwm_nxp_s32_config { #if EMIOS_PWM_IP_USED struct pwm_nxp_s32_pulse_info *pulse_info; #endif + +#ifdef CONFIG_PWM_CAPTURE + eMios_Icu_Ip_ConfigType * icu_cfg; +#endif }; #if EMIOS_PWM_IP_USED @@ -193,9 +222,178 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel, } #endif +#ifdef CONFIG_PWM_CAPTURE +static ALWAYS_INLINE eMios_Icu_ValueType pwm_nxp_s32_capture_calc(eMios_Icu_ValueType first_cnt, + eMios_Icu_ValueType second_cnt) +{ + if (first_cnt < second_cnt) { + return second_cnt - first_cnt; + } + + /* Counter top value is always 0xFFFF */ + return EMIOS_ICU_IP_COUNTER_MASK - first_cnt + second_cnt; +} + +static ALWAYS_INLINE eMios_Icu_ValueType pwm_nxp_s32_pulse_calc(bool inverted, + eMios_Icu_ValueType *edge_buff, + eMios_Icu_Ip_LevelType input_state) +{ + eMios_Icu_ValueType first_cnt, second_cnt; + + if (input_state ^ inverted) { + /* 3 edges captured is raise, fall, raise */ + first_cnt = edge_buff[0]; + second_cnt = edge_buff[1]; + } else { + /* 3 edges captured is fall, raise, fall */ + first_cnt = edge_buff[1]; + second_cnt = edge_buff[2]; + } + + return pwm_nxp_s32_capture_calc(first_cnt, second_cnt); +} + +static int pwm_nxp_s32_capture_configure(const struct device *dev, + uint32_t channel, + pwm_flags_t flags, + pwm_capture_callback_handler_t cb, + void *user_data) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + if (channel >= EMIOS_ICU_IP_NUM_OF_CHANNELS) { + LOG_ERR("Invalid channel %d", channel); + return -EINVAL; + } + + if (!flags) { + LOG_ERR("Invalid PWM capture flag"); + return -EINVAL; + } + + if (eMios_Icu_Ip_IndexInChState[config->instance][channel] >= + EMIOS_ICU_IP_NUM_OF_CHANNELS_USED) { + LOG_ERR("Channel %d is not configured for PWM", channel); + return -EINVAL; + } + + /* If interrupt is enabled --> channel is on-going */ + if (config->base->CH.UC[channel].C & eMIOS_C_FEN_MASK) { + LOG_ERR("Channel %d is busy", channel); + return -EBUSY; + } + + data->capture[channel].continuous = (flags & PWM_CAPTURE_MODE_MASK); + data->capture[channel].inverted = (flags & PWM_POLARITY_MASK); + data->capture[channel].pulse_capture = (flags & PWM_CAPTURE_TYPE_PULSE); + data->capture[channel].period_capture = (flags & PWM_CAPTURE_TYPE_PERIOD); + data->capture[channel].callback = cb; + data->capture[channel].user_data = user_data; + + return 0; +} + +static int pwm_nxp_s32_capture_enable(const struct device *dev, uint32_t channel) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + eMios_Icu_Ip_EdgeType edge; + uint8_t num_edge; + + if (channel >= EMIOS_ICU_IP_NUM_OF_CHANNELS) { + LOG_ERR("Invalid channel %d", channel); + return -EINVAL; + } + + if (eMios_Icu_Ip_IndexInChState[config->instance][channel] >= + EMIOS_ICU_IP_NUM_OF_CHANNELS_USED) { + LOG_ERR("Channel %d is not configured for PWM", channel); + return -EINVAL; + } + + if (!data->capture[channel].callback) { + LOG_ERR("Callback is not configured"); + return -EINVAL; + } + + /* If interrupt is enabled --> channel is on-going */ + if (config->base->CH.UC[channel].C & eMIOS_C_FEN_MASK) { + LOG_ERR("Channel %d is busy", channel); + return -EBUSY; + } + + /* If just measure period, we just need 2 edges */ + if (data->capture[channel].period_capture && !data->capture[channel].pulse_capture) { + num_edge = 2U; + edge = EMIOS_ICU_RISING_EDGE; + } else { + num_edge = 3U; + edge = EMIOS_ICU_BOTH_EDGES; + } + + Emios_Icu_Ip_SetActivation(config->instance, channel, edge); + + Emios_Icu_Ip_EnableNotification(config->instance, channel); + + Emios_Icu_Ip_StartTimestamp(config->instance, channel, + data->capture[channel].edge_buff, + MAX_NUM_EDGE, num_edge); + + return 0; +} + +static int pwm_nxp_s32_capture_disable(const struct device *dev, uint32_t channel) +{ + const struct pwm_nxp_s32_config *config = dev->config; + + if (channel >= EMIOS_ICU_IP_NUM_OF_CHANNELS) { + LOG_ERR("Invalid channel %d", channel); + return -EINVAL; + } + + if (eMios_Icu_Ip_IndexInChState[config->instance][channel] >= + EMIOS_ICU_IP_NUM_OF_CHANNELS_USED) { + LOG_ERR("Channel %d is not configured for PWM", channel); + return -EINVAL; + } + + Emios_Icu_Ip_StopTimestamp(config->instance, channel); + + return 0; +} + +static int pwm_nxp_s32_get_master_bus(const struct device *dev, uint32_t channel) +{ + const struct pwm_nxp_s32_config *config = dev->config; + uint8_t bus_select, master_bus; + + bus_select = (config->base->CH.UC[channel].C & eMIOS_C_BSL_MASK) >> eMIOS_C_BSL_SHIFT; + + switch (bus_select) { + case 0: + master_bus = 23U; + break; + case 1: + master_bus = (channel < 8U) ? 0U : ((channel < 16U) ? 8U : 16U); + break; + case 2: + master_bus = 22U; + break; + default: + /* Default is internal counter */ + master_bus = channel; + break; + } + + return master_bus; +} +#endif + static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, uint32_t channel, - uint64_t *cycles) + uint64_t *cycles) { const struct pwm_nxp_s32_config *config = dev->config; struct pwm_nxp_s32_data *data = dev->data; @@ -205,12 +403,19 @@ static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, #if EMIOS_PWM_IP_USED if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] < - EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) { + EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) { master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel); } #endif - if (master_bus == 0xFFU) { +#ifdef CONFIG_PWM_CAPTURE + if (eMios_Icu_Ip_IndexInChState[config->instance][channel] < + EMIOS_ICU_IP_NUM_OF_CHANNELS_USED) { + master_bus = pwm_nxp_s32_get_master_bus(dev, channel); + } +#endif + + if (master_bus == 0xFF) { LOG_ERR("Channel %d is not configured for PWM", channel); return -EINVAL; } @@ -253,6 +458,61 @@ static int pwm_nxp_s32_pulse_gen_init(const struct device *dev) } #endif +#ifdef CONFIG_PWM_CAPTURE +static int pwm_nxp_s32_pulse_capture_init(const struct device *dev) +{ + const struct pwm_nxp_s32_config *config = dev->config; + + const eMios_Icu_Ip_ChannelConfigType *icu_info; + + uint8_t ch_id; + static uint8_t logic_ch; + + for (ch_id = 0; ch_id < config->icu_cfg->nNumChannels; ch_id++) { + icu_info = &(*config->icu_cfg->pChannelsConfig)[ch_id]; + eMios_Icu_Ip_IndexInChState[config->instance][icu_info->hwChannel] = logic_ch++; + } + + if (Emios_Icu_Ip_Init(config->instance, config->icu_cfg)) { + return -EINVAL; + } + + return 0; +} + +static void pwm_nxp_s32_capture_callback(const struct device *dev, uint32_t channel) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + + uint32_t period = 0, pulse = 0; + + if (data->capture[channel].period_capture && !data->capture[channel].pulse_capture) { + period = pwm_nxp_s32_capture_calc(data->capture[channel].edge_buff[0], + data->capture[channel].edge_buff[1]); + } else { + if (data->capture[channel].pulse_capture) { + pulse = pwm_nxp_s32_pulse_calc(data->capture[channel].inverted, + data->capture[channel].edge_buff, + Emios_Icu_Ip_GetInputLevel(config->instance, + channel)); + } + + if (data->capture[channel].period_capture) { + period = pwm_nxp_s32_capture_calc(data->capture[channel].edge_buff[0], + data->capture[channel].edge_buff[2]); + } + } + + if (!data->capture[channel].continuous) { + Emios_Icu_Ip_StopTimestamp(config->instance, channel); + } + + data->capture[channel].callback(dev, channel, period, pulse, 0, + data->capture[channel].user_data); +} +#endif + static int pwm_nxp_s32_init(const struct device *dev) { const struct pwm_nxp_s32_config *config = dev->config; @@ -281,12 +541,24 @@ static int pwm_nxp_s32_init(const struct device *dev) } #endif +#ifdef CONFIG_PWM_CAPTURE + err = pwm_nxp_s32_pulse_capture_init(dev); + if (err < 0) { + return err; + } +#endif + return err; } static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .set_cycles = pwm_nxp_s32_set_cycles, .get_cycles_per_sec = pwm_nxp_s32_get_cycles_per_sec, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = pwm_nxp_s32_capture_configure, + .enable_capture = pwm_nxp_s32_capture_enable, + .disable_capture = pwm_nxp_s32_capture_disable, +#endif }; /* @@ -307,6 +579,12 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #define EMIOS_PWM_IS_MODE_OPWMB(node_id) \ DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMB) +#define EMIOS_PWM_IS_MODE_SAIC(node_id) \ + DT_ENUM_HAS_VALUE(node_id, pwm_mode, SAIC) + +#define EMIOS_PWM_IS_CAPTURE_MODE(node_id) \ + EMIOS_PWM_IS_MODE_SAIC(node_id) + #define EMIOS_PWM_LOG(node_id, msg) \ DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \ @@ -319,7 +597,9 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, duty_cycle), \ EMIOS_PWM_LOG(node_id, "duty-cycle must be configured")); \ BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, polarity), \ - EMIOS_PWM_LOG(node_id, "polarity must be configured")); + EMIOS_PWM_LOG(node_id, "polarity must be configured")); \ + BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, input_filter), \ + EMIOS_PWM_LOG(node_id, "input-filter is not used")); #define EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id) \ EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ @@ -333,9 +613,9 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, master_bus), \ EMIOS_PWM_LOG(node_id, "master-bus must not be configured")); \ BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ - EMIOS_PWM_LOG(node_id, "dead-time must not be configured")); \ + EMIOS_PWM_LOG(node_id, "dead-time is not used")); \ BUILD_ASSERT(DT_PROP(node_id, phase_shift) == 0, \ - EMIOS_PWM_LOG(node_id, "phase-shift must not be configured")); + EMIOS_PWM_LOG(node_id, "phase-shift is not used")); #define EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id) \ EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ @@ -348,15 +628,15 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { BUILD_ASSERT(DT_PROP(node_id, dead_time) <= DT_PROP(node_id, duty_cycle), \ EMIOS_PWM_LOG(node_id, "dead-time must <= duty-cycle")); \ BUILD_ASSERT(DT_PROP(node_id, phase_shift) == 0, \ - EMIOS_PWM_LOG(node_id, "phase-shift must not be configured")); \ + EMIOS_PWM_LOG(node_id, "phase-shift is not used")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period must not be configured," \ + EMIOS_PWM_LOG(node_id, "period is not used," \ " driver takes the value from master bus")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ - EMIOS_PWM_LOG(node_id, "prescaler must not be configured," \ + EMIOS_PWM_LOG(node_id, "prescaler is not used," \ " driver takes the value from master bus")); \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ - EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \ + EMIOS_PWM_LOG(node_id, "prescaler-src is not used," \ " always use prescalered source")); \ #define EMIOS_PWM_VERIFY_MODE_OPWMB(node_id) \ @@ -364,19 +644,46 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period must not be configured," \ + EMIOS_PWM_LOG(node_id, "period is not used," \ " driver takes the value from master bus")); \ BUILD_ASSERT((DT_PROP(node_id, duty_cycle) + DT_PROP(node_id, phase_shift)) <= \ EMIOS_PWM_PERIOD_TIME_BASE(node_id), \ EMIOS_PWM_LOG(node_id, "duty-cycle + phase-shift must <= period")); \ BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ - EMIOS_PWM_LOG(node_id, "dead-time must not be configured")); \ + EMIOS_PWM_LOG(node_id, "dead-time is not used")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ - EMIOS_PWM_LOG(node_id, "prescaler must not be configured")); \ + EMIOS_PWM_LOG(node_id, "prescaler is not used")); \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ - EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \ + EMIOS_PWM_LOG(node_id, "prescaler-src is not used," \ " always use prescalered source")); \ +#define EMIOS_PWM_VERIFY_MODE_SAIC(node_id) \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ + (BUILD_ASSERT( \ + DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ + EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up"));)) \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ + (BUILD_ASSERT(DT_PROP_BY_PHANDLE(node_id, master_bus, period) == 0xFFFF, \ + EMIOS_PWM_LOG(node_id, "master-bus period must be 0xFFFF"));)) \ + IF_ENABLED(UTIL_NOT(DT_NODE_HAS_PROP(node_id, master_bus)), \ + (BUILD_ASSERT( \ + BIT(DT_PROP(node_id, channel)) & DT_PROP(DT_GPARENT(node_id), internal_cnt),\ + EMIOS_PWM_LOG(node_id, "master-bus must be chosen," \ + " channel do not have has counter")))); \ + IF_ENABLED(UTIL_NOT(DT_NODE_HAS_PROP(node_id, master_bus)), \ + (BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, prescaler), \ + EMIOS_PWM_LOG(node_id, "if use internal counter, prescaler must" \ + " be configured")))); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, duty_cycle), \ + EMIOS_PWM_LOG(node_id, "duty-cycle is not used")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, polarity), \ + EMIOS_PWM_LOG(node_id, "polarity is not used")); \ + BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ + EMIOS_PWM_LOG(node_id, "period is not used")); \ + BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ + EMIOS_PWM_LOG(node_id, "prescaler-src is not used," \ + " always use prescalered source")); + #define _EMIOS_PWM_VERIFY_CONFIG(node_id) \ IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ (EMIOS_PWM_VERIFY_MASTER_BUS(node_id))) \ @@ -386,6 +693,8 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { (EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id))) \ IF_ENABLED(EMIOS_PWM_IS_MODE_OPWMB(node_id), \ (EMIOS_PWM_VERIFY_MODE_OPWMB(node_id))) \ + IF_ENABLED(EMIOS_PWM_IS_MODE_SAIC(node_id), \ + (EMIOS_PWM_VERIFY_MODE_SAIC(node_id))) #if EMIOS_PWM_IP_USED /* Macros used to glue devicetree with RTD's definition */ @@ -402,7 +711,8 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode) #define _EMIOS_PWM_PULSE_GEN_CONFIG(node_id) \ - { \ + IF_ENABLED(UTIL_NOT(EMIOS_PWM_IS_CAPTURE_MODE(node_id)), \ + ({ \ .ChannelId = DT_PROP(node_id, channel), \ .Mode = EMIOS_PWM_MODE(DT_STRING_TOKEN(node_id, pwm_mode)), \ .InternalPsSrc = EMIOS_PWM_PS_SRC(DT_STRING_TOKEN(node_id, prescaler_src)), \ @@ -419,7 +729,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .DebugMode = DT_PROP(node_id, freeze), \ .PeriodCount = DT_PROP_OR(node_id, period, EMIOS_PWM_PERIOD_TIME_BASE(node_id)),\ .DutyCycle = DT_PROP(node_id, duty_cycle), \ - }, + },)) #define EMIOS_PWM_PULSE_GEN_CONFIG(n) \ const Emios_Pwm_Ip_ChannelConfigType emios_pwm_##n##_init[] = { \ @@ -437,6 +747,78 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #define EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) #endif +#ifdef CONFIG_PWM_CAPTURE +/* Macros used to glue devicetree with RTD's definition */ +#define EMIOS_ICU_BUS_A EMIOS_ICU_BUS_A +#define EMIOS_ICU_BUS_B EMIOS_ICU_BUS_DIVERSE +#define EMIOS_ICU_BUS_C EMIOS_ICU_BUS_DIVERSE +#define EMIOS_ICU_BUS_D EMIOS_ICU_BUS_DIVERSE +#define EMIOS_ICU_BUS_E EMIOS_ICU_BUS_DIVERSE +#define EMIOS_ICU_BUS_F EMIOS_ICU_BUS_F + +#define DIGITAL_FILTER_0 EMIOS_DIGITAL_FILTER_BYPASSED +#define DIGITAL_FILTER_2 EMIOS_DIGITAL_FILTER_02 +#define DIGITAL_FILTER_4 EMIOS_DIGITAL_FILTER_04 +#define DIGITAL_FILTER_8 EMIOS_DIGITAL_FILTER_08 +#define DIGITAL_FILTER_16 EMIOS_DIGITAL_FILTER_16 + +#define EMIOS_PWM_CAPTURE_FILTER(filter) DT_CAT(DIGITAL_FILTER_, filter) +#define EMIOS_PWM_CAPTURE_MODE(mode) DT_CAT(EMIOS_ICU_, mode) +#define EMIOS_PWM_CAPTURE_BUS(mode) DT_CAT(EMIOS_ICU_, mode) + +#define EMIOS_PWM_CAPTURE_CB(n, ch) \ + DT_CAT5(pwm_nxp_s32_, n, _channel_, ch, _capture_callback) + +#define EMIOS_PWM_CALLBACK_DECLARE(node_id, n) \ + void EMIOS_PWM_CAPTURE_CB(n, DT_PROP(node_id, channel))(void) \ + { \ + pwm_nxp_s32_capture_callback(DEVICE_DT_INST_GET(n), DT_PROP(node_id, channel)); \ + } \ + +#define _EMIOS_PWM_PULSE_CAPTURE_CONFIG(node_id, n) \ + IF_ENABLED(EMIOS_PWM_IS_CAPTURE_MODE(node_id), \ + ({ \ + .hwChannel = DT_PROP(node_id, channel), \ + .ucMode = EMIOS_PWM_CAPTURE_MODE(DT_STRING_TOKEN(node_id, pwm_mode)), \ + .FreezeEn = DT_PROP(node_id, freeze), \ + .Prescaler = COND_CODE_1(DT_NODE_HAS_PROP(node_id, master_bus), \ + (DT_PROP_BY_PHANDLE(node_id, master_bus, prescaler)), \ + (DT_PROP(node_id, prescaler))) - 1, \ + .CntBus = COND_CODE_1(DT_NODE_HAS_PROP(node_id, master_bus), \ + (EMIOS_PWM_CAPTURE_BUS(DT_STRING_TOKEN( \ + DT_PHANDLE(node_id, master_bus), bus_type))),\ + (EMIOS_ICU_BUS_INTERNAL_COUNTER)), \ + .chMode = EMIOS_ICU_MODE_TIMESTAMP, \ + .chSubMode = EMIOS_ICU_MODE_WITHOUT_DMA, \ + .measurementMode = EMIOS_ICU_NO_MEASUREMENT, \ + .edgeAlignement = EMIOS_ICU_BOTH_EDGES, \ + .Filter = EMIOS_PWM_CAPTURE_FILTER(DT_PROP(node_id, input_filter)), \ + .callback = NULL_PTR, \ + .logicChStateCallback = NULL_PTR, \ + .callbackParams = 255U, \ + .bWithoutInterrupt = FALSE, \ + .timestampBufferType = EMIOS_ICU_CIRCULAR_BUFFER, \ + .eMiosChannelNotification = EMIOS_PWM_CAPTURE_CB(n, DT_PROP(node_id, channel)), \ + .eMiosOverflowNotification = NULL_PTR, \ + },)) + +#define EMIOS_PWM_PULSE_CAPTURE_CONFIG(n) \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, EMIOS_PWM_CALLBACK_DECLARE, n) \ + const eMios_Icu_Ip_ChannelConfigType emios_pwm_##n##_capture_init[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, _EMIOS_PWM_PULSE_CAPTURE_CONFIG, n) \ + }; \ + const eMios_Icu_Ip_ConfigType emios_pwm_##n##_capture_info = { \ + .nNumChannels = ARRAY_SIZE(emios_pwm_##n##_capture_init), \ + .pChannelsConfig = &emios_pwm_##n##_capture_init, \ + }; + +#define EMIOS_PWM_PULSE_CAPTURE_GET_CONFIG(n) \ + .icu_cfg = (eMios_Icu_Ip_ConfigType *)&emios_pwm_##n##_capture_info, +#else +#define EMIOS_PWM_PULSE_CAPTURE_CONFIG(n) +#define EMIOS_PWM_PULSE_CAPTURE_GET_CONFIG(n) +#endif + #define EMIOS_PWM_VERIFY_CONFIG(n) \ DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _EMIOS_PWM_VERIFY_CONFIG) @@ -450,6 +832,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { PINCTRL_DT_INST_DEFINE(n); \ EMIOS_PWM_VERIFY_CONFIG(n) \ EMIOS_PWM_PULSE_GEN_CONFIG(n) \ + EMIOS_PWM_PULSE_CAPTURE_CONFIG(n) \ static const struct pwm_nxp_s32_config pwm_nxp_s32_config_##n = { \ .base = (eMIOS_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ .instance = EMIOS_NXP_S32_GET_INSTANCE(DT_INST_PARENT(n)), \ @@ -457,6 +840,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .clock_subsys = (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name),\ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) \ + EMIOS_PWM_PULSE_CAPTURE_GET_CONFIG(n) \ }; \ static struct pwm_nxp_s32_data pwm_nxp_s32_data_##n; \ DEVICE_DT_INST_DEFINE(n, \ diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 5b03cf84244..91a4a2d989c 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -626,6 +626,7 @@ <64 0>, <65 0>, <66 0>; interrupt-names = "0_0", "0_1", "0_2", "0_3", "0_4", "0_5"; + internal-cnt = <0xC101FF>; status = "disabled"; master_bus { @@ -680,6 +681,7 @@ <72 0>, <73 0>, <74 0>; interrupt-names = "1_0", "1_1", "1_2", "1_3", "1_4", "1_5"; + internal-cnt = <0xC10101>; status = "disabled"; master_bus { @@ -734,6 +736,7 @@ <80 0>, <81 0>, <82 0>; interrupt-names = "2_0", "2_1", "2_2", "2_3", "2_4", "2_5"; + internal-cnt = <0xC10101>; status = "disabled"; master_bus { diff --git a/dts/bindings/misc/nxp,s32-emios.yaml b/dts/bindings/misc/nxp,s32-emios.yaml index d6b86899ec0..61c831a01a0 100644 --- a/dts/bindings/misc/nxp,s32-emios.yaml +++ b/dts/bindings/misc/nxp,s32-emios.yaml @@ -30,6 +30,12 @@ properties: description: | Clock divider value for the global prescaler. Could be in range [1 ... 256] + internal-cnt: + type: int + required: true + description: | + A mask for channels that have internal counter, lsb is channel 0. + child-binding: child-binding: description: | diff --git a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml index bea525676a0..37de69e39e1 100644 --- a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml +++ b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml @@ -7,8 +7,12 @@ description: | some modes only support on channels that have internal counter, some modes require to use a reference timebase from a master bus. - For example to configuring eMIOS instance 0 with channel 0 for mode OPWFMB, channel 1 - for mode OPWMB and channel 2 for mode OPWMCB with deadtime inserted at leading edge: + For example to configuring eMIOS instance 0 with: + - Channel 0 for mode OPWFMB + - Channel 1 for mode OPWMB + - Channel 2 for mode OPWMCB with deadtime inserted at leading edge + - Channel 3 for mode SAIC, use internal timebase with input filter = 2 eMIOS clock + emios0_pwm: pwm { pwm_0 { channel = <0>; @@ -36,6 +40,13 @@ description: | dead-time = <100>; polarity = "ACTIVE_LOW"; }; + + pwm_3 { + channel = <3>; + pwm-mode = "SAIC"; + prescaler = <8>; + input-filter = <2>; + }; }; OPWMB and OPWMCB modes use reference timebase, the master bus is chosen over @@ -79,7 +90,9 @@ child-binding: description: | A phandle to master-bus node that will be used as external timebase for current channel, this can be bypassed if internal counter is used - for PWM operation. + for PWM operation. A master bus must be used exclusively, such as if + is used as a timebase for a channel in SAIC mode, do not use that + master bus as a timebase for generate PWM pulse. pwm-mode: type: string @@ -100,15 +113,19 @@ child-binding: an external counter driven in MCB Up Down Mode. Changing PWM period at runtime will impact to all channels share the same timebase, The new period and cycle take effect in next period boundary. + + - SAIC: single action input capture mode, the eMIOS captures events as soon as + they occur. The value of latest captured event is stored and can be read + by software. enum: - "OPWFMB" - "OPWMB" - "OPWMCB_TRAIL_EDGE" - "OPWMCB_LEAD_EDGE" + - "SAIC" polarity: type: string - required: true description: | Output polarity for PWM channel. enum: @@ -117,7 +134,6 @@ child-binding: duty-cycle: type: int - required: true description: | Duty-cycle (in ticks) for PWM channel at boot time. @@ -157,3 +173,13 @@ child-binding: default: 0 description: | Phase Shift (in ticks) for PWM channel in OPWMB mode. + + input-filter: + type: int + default: 0 + enum: [0, 2, 4, 8, 16] + description: | + Select the minimim input pulse width, in filter clock cycles that can pass + through the input filter. The filter latency - the difference in time between + the input and the response is three clock edges. Default 0 means the filter + is bypassed. The clock source for programmable input filter is eMIOS clock. From 2aded4006f09735b37aa6e7ac1296bbf6edd715f Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Sat, 16 Sep 2023 10:06:04 +0700 Subject: [PATCH 1419/4498] tests: pwm_loopback: enable test for mr_canhubk3 Enable PWM loopback testing for mr_canhubk3 Signed-off-by: Dat Nguyen Duy --- .../pwm_loopback/boards/mr_canhubk3.overlay | 41 +++++++++++++++++++ west.yml | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/pwm/pwm_loopback/boards/mr_canhubk3.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/mr_canhubk3.overlay b/tests/drivers/pwm/pwm_loopback/boards/mr_canhubk3.overlay new file mode 100644 index 00000000000..898b6d938f7 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/mr_canhubk3.overlay @@ -0,0 +1,41 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + /* Connect P8A pin 3 and P8A pin 6 */ + pwms = <&emios0_pwm 0 0 PWM_POLARITY_NORMAL>, + <&emios0_pwm 1 0 PWM_POLARITY_NORMAL>; + }; +}; + +&pinctrl { + emios0_default { + group2 { + pinmux = ; + input-enable; + }; + }; +}; + +&emios0 { + emios0_pwm: pwm { + pinctrl-0 = <&emios0_default>; + pinctrl-names = "default"; + status = "okay"; + + pwm_1 { + /delete-property/ period; + /delete-property/ polarity; + /delete-property/ duty-cycle; + prescaler = <16>; + pwm-mode = "SAIC"; + }; + }; +}; diff --git a/west.yml b/west.yml index a8384e036c5..7d3eb0407fe 100644 --- a/west.yml +++ b/west.yml @@ -199,7 +199,7 @@ manifest: groups: - hal - name: hal_nxp - revision: b4a37865355a6d55cdcdc087b934017212fb0f54 + revision: ad142f5612d927e29b1f9606e8edade871b8a526 path: modules/hal/nxp groups: - hal From 4289359eb20db4a838fefe3648d441d13a6d7c0e Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Fri, 29 Sep 2023 11:55:01 +0300 Subject: [PATCH 1420/4498] modules: mcux: fix HAS_CMSIS_CORE selection Do not select HAS_CMSIS_CORE for SOC_FAMILY_NXP_ADSP. This soc family refers to the Audio DSP from i.MX MPU, which is a HiFi4 core, Xtensa arch. HAS_CMSIS_CORE is for ARM cores (A, M, R cores) - see modules/cmsis/Kconfig. Signed-off-by: Iuliana Prodan --- modules/Kconfig.mcux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index 67377adcbb3..4664b8c0423 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -5,7 +5,7 @@ config HAS_MCUX bool - select HAS_CMSIS_CORE + select HAS_CMSIS_CORE if !SOC_FAMILY_NXP_ADSP depends on SOC_FAMILY_KINETIS || SOC_FAMILY_IMX || SOC_FAMILY_LPC || \ SOC_FAMILY_NXP_ADSP || SOC_FAMILY_NXP_S32 From 2de7a8124af33e546a84666463143f99733facb5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Fri, 29 Sep 2023 09:40:17 +0200 Subject: [PATCH 1421/4498] dts: bindings: serial: nxp,kinetis-lpsci: do not re-specify pinctrl-0 Property type is already defined in pinctrl-device.yaml. Signed-off-by: Gerard Marull-Paretas --- dts/bindings/serial/nxp,kinetis-lpsci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/dts/bindings/serial/nxp,kinetis-lpsci.yaml b/dts/bindings/serial/nxp,kinetis-lpsci.yaml index 362038669cd..0934c02b3e1 100644 --- a/dts/bindings/serial/nxp,kinetis-lpsci.yaml +++ b/dts/bindings/serial/nxp,kinetis-lpsci.yaml @@ -12,5 +12,4 @@ properties: required: true pinctrl-0: - type: phandles required: true From 69fb18a19df1b1d895c79c67a1aa6330dd15b7da Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 20 Sep 2023 15:41:09 +0200 Subject: [PATCH 1422/4498] drivers: adc: stm32: ADC nocache buffers can be in CONFIG_NOCACHE_MEMORY CONFIG_NOCACHE_MEMORY is a valid way of declaring buffers in nocache regions. Consider them valid in the STM32 ADC driver nocache check. Copied from commit 818aa2d Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index b88c7870ffa..53562734bd0 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -43,7 +43,16 @@ LOG_MODULE_REGISTER(adc_stm32); #include #include #include + +#ifdef CONFIG_SOC_SERIES_STM32H7X #include +#endif + +#ifdef CONFIG_NOCACHE_MEMORY +#include +#elif defined(CONFIG_CACHE_MANAGEMENT) +#include +#endif /* CONFIG_NOCACHE_MEMORY */ #if defined(CONFIG_SOC_SERIES_STM32F3X) #if defined(ADC1_V2_5) @@ -285,13 +294,22 @@ static int adc_stm32_dma_start(const struct device *dev, * zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) | ... )>; * }; */ -static bool address_in_non_cacheable_sram(const uint16_t *buffer, const uint16_t size) +static bool buf_in_nocache(uintptr_t buf, size_t len_bytes) { - if (mem_attr_check_buf((void *) buffer, (size_t) size, DT_MEM_ARM_MPU_RAM_NOCACHE) == 0) { + bool buf_within_nocache = false; + +#ifdef CONFIG_NOCACHE_MEMORY + buf_within_nocache = (buf >= ((uintptr_t)_nocache_ram_start)) && + ((buf + len_bytes - 1) <= ((uintptr_t)_nocache_ram_end)); + if (buf_within_nocache) { return true; } +#endif /* CONFIG_NOCACHE_MEMORY */ + + buf_within_nocache = mem_attr_check_buf( + (void *)buf, len_bytes, DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE)) == 0; - return false; + return buf_within_nocache; } #endif /* defined(CONFIG_ADC_STM32_DMA) && defined(CONFIG_SOC_SERIES_STM32H7X) */ @@ -314,7 +332,7 @@ static int check_buffer(const struct adc_sequence *sequence, #if defined(CONFIG_ADC_STM32_DMA) && defined(CONFIG_SOC_SERIES_STM32H7X) /* Buffer is forced to be in non-cacheable SRAM region to avoid cache maintenance */ - if (!address_in_non_cacheable_sram(sequence->buffer, needed_buffer_size)) { + if (!buf_in_nocache((uintptr_t)sequence->buffer, needed_buffer_size)) { LOG_ERR("Supplied buffer is not in a non-cacheable region according to DTS."); return -EINVAL; } From 647fb4dc8f4f0cc09a38e223606dc239033ad8f5 Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Thu, 28 Sep 2023 17:19:45 +0300 Subject: [PATCH 1423/4498] net: lwm2m: RD client Deregister event indicate Added a new event for LWM2M_RD_CLIENT_EVENT_DEREGISTER for indicate LwM2M client dereistartion. Updated unit test and sample for new event type Signed-off-by: Juha Heiskanen --- doc/connectivity/networking/api/lwm2m.rst | 8 ++++++++ doc/releases/release-notes-3.5.rst | 1 + include/zephyr/net/lwm2m.h | 1 + samples/net/lwm2m_client/src/lwm2m-client.c | 3 +++ subsys/net/lib/lwm2m/lwm2m_rd_client.c | 2 ++ tests/net/lib/lwm2m/interop/src/lwm2m-client.c | 3 +++ tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c | 6 ++++++ 7 files changed, 24 insertions(+) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index eb699017f97..ce6cafd53a7 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -318,6 +318,14 @@ events, setup a callback function: LOG_DBG("Disconnected"); break; + case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: + LOG_DBG("Registration update"); + break; + + case LWM2M_RD_CLIENT_EVENT_DEREGISTER: + LOG_DBG("Deregistration client"); + break; + } } diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b08e317db60..7764e21a02a 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -305,6 +305,7 @@ Networking * Added support for tickless mode. This removes the 500 ms timeout from the socket loop so the engine does not constantly wake up the CPU. This can be enabled by :kconfig:option:`CONFIG_LWM2M_TICKLESS`. + * Added new :c:macro:`LWM2M_RD_CLIENT_EVENT_DEREGISTER` event. * Wi-Fi * Added Passive scan support. diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index e94297d3550..6262f6d103d 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -2073,6 +2073,7 @@ enum lwm2m_rd_client_event { LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED, LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, LWM2M_RD_CLIENT_EVENT_REG_UPDATE, + LWM2M_RD_CLIENT_EVENT_DEREGISTER, }; /** diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index e20008c2f66..748f654d9ee 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -231,6 +231,9 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_DBG("Registration update"); break; + case LWM2M_RD_CLIENT_EVENT_DEREGISTER: + LOG_DBG("Client De-register"); + break; } } diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index feebcaeea17..db8a84ce0b8 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -215,6 +215,8 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) } } else if (sm_state == ENGINE_UPDATE_REGISTRATION) { event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE; + } else if (sm_state == ENGINE_DEREGISTER) { + event = LWM2M_RD_CLIENT_EVENT_DEREGISTER; } if (sm_is_suspended()) { diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 1278d807b71..983fea79f3e 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -117,6 +117,9 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_DBG("Registration update"); break; + case LWM2M_RD_CLIENT_EVENT_DEREGISTER: + LOG_DBG("Deregistration client"); + break; } } diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 08c0820d5e9..03d0dce7f49 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -106,6 +106,9 @@ static void lwm2m_event_cb(struct lwm2m_ctx *client, enum lwm2m_rd_client_event case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_REG_UPDATE"); break; + case LWM2M_RD_CLIENT_EVENT_DEREGISTER: + LOG_INF("*** LWM2M_RD_CLIENT_EVENT_DEREGISTER"); + break; } show_lwm2m_event(client_event); @@ -211,6 +214,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); zassert_true(!lwm2m_rd_client_is_registred(&ctx), NULL); } @@ -425,6 +429,7 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) test_prepare_pending_message_cb(&message_reply_timeout_cb_default); zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE)); } @@ -529,6 +534,7 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) zassert_equal(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, false), 0); zassert_true(lwm2m_rd_client_resume() == 0, NULL); + zassert_false(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); } From 222593f8c45683c29341e153fe518ba7ea22498e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 28 Sep 2023 11:24:12 +0200 Subject: [PATCH 1424/4498] tests: kernel: timer: jitter_drift: Restore initial alignment to tick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 4cc21e2f4aea2e37f4fea1216fe92ded9ba6d755. That short sleeping before starting the test was removed together with accuracy improvements (specifically, with moving of the first readout of the cycle counter). Nevertheless, this tick alignment it still needed, as without it in specific conditions the test may undesirably fail. Signed-off-by: Andrzej Głąbek --- tests/kernel/timer/timer_behavior/src/jitter_drift.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/kernel/timer/timer_behavior/src/jitter_drift.c b/tests/kernel/timer/timer_behavior/src/jitter_drift.c index 666f916a1c9..d78adb40eaf 100644 --- a/tests/kernel/timer/timer_behavior/src/jitter_drift.c +++ b/tests/kernel/timer/timer_behavior/src/jitter_drift.c @@ -136,6 +136,17 @@ static void do_test_using(void (*sample_collection_fn)(void)) periodic_idx = 0; k_sem_init(&periodic_sem, 0, 1); + + /* Align to tick boundary. Otherwise the first handler execution + * might turn out to be significantly late and cause the test to + * fail. This can happen if k_timer_start() is called right before + * the upcoming tick boundary and in consequence the tick passes + * between the moment when the kernel decides what tick to use for + * the next timeout and the moment when the system timer actually + * sets up that timeout. + */ + k_sleep(K_TICKS(1)); + sample_collection_fn(); k_sem_take(&periodic_sem, K_FOREVER); From c8a79e1fc1b38e068633b3c7eadee26d16725890 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 27 Sep 2023 17:55:30 +0200 Subject: [PATCH 1425/4498] Bluetooth: Audio: Add codec_cfg_set_frame_blocks_per_sdu Add the bt_audio_codec_cfg_set_frame_blocks_per_sdu function to set or add the frame blocks per SDU field in the codec configuration. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 13 +++++++++++++ subsys/bluetooth/audio/codec.c | 7 +++++++ tests/bluetooth/audio/codec/src/main.c | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 00b2264a81e..c084c885068 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -697,6 +697,19 @@ int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default); +/** + * @brief Set the frame blocks per SDU of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param frame_blocks The frame blocks per SDU to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec_cfg, + uint8_t frame_blocks); + /** @brief Lookup a specific codec configuration value * * @param[in] codec_cfg The codec data to search in. diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 1fc704eeb95..59d2394b74e 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -416,6 +416,13 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg return data[0]; } + +int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec_cfg, + uint8_t frame_blocks) +{ + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU, + &frame_blocks, sizeof(frame_blocks)); +} #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 8950a00186a..05df015a876 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -136,6 +136,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_blocks_per_sdu) zassert_equal(ret, 1u, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_frame_blocks_per_sdu) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_32_2_2( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + int ret; + + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&preset.codec_cfg, true); + zassert_equal(ret, 1, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_frame_blocks_per_sdu(&preset.codec_cfg, 2U); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&preset.codec_cfg, true); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_pref_context) { const enum bt_audio_context ctx = From 6ef75a26eae2afb75062de1931affd8dce83afa9 Mon Sep 17 00:00:00 2001 From: Rahul Singh Date: Mon, 17 Jul 2023 09:45:39 +0100 Subject: [PATCH 1426/4498] net: zperf: Add support for bind to host option for tcp/udp download The current zperf tcp/udp download command doesn't provide the option to bind the server to a specific host address. If there is more than one interface, it will not be possible to test each interface with zperf tcp/udp download command without building the Zpehyr. This patch will add support for zperf tcp/udp download command to bind server to host interface address. Signed-off-by: Rahul Singh --- include/zephyr/net/zperf.h | 1 + subsys/net/lib/zperf/zperf_shell.c | 63 ++++++++++++++++++----- subsys/net/lib/zperf/zperf_tcp_receiver.c | 24 ++++++--- subsys/net/lib/zperf/zperf_udp_receiver.c | 16 +++++- 4 files changed, 84 insertions(+), 20 deletions(-) diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index cd86541721e..fc809ae9278 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -43,6 +43,7 @@ struct zperf_upload_params { struct zperf_download_params { uint16_t port; + struct sockaddr addr; }; struct zperf_results { diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 3f900fa6e8a..d2b2fb92f7c 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -178,6 +178,39 @@ static int parse_ipv4_addr(const struct shell *sh, char *host, char *port, return 0; } +static int zperf_bind_host(const struct shell *sh, + size_t argc, char *argv[], + struct zperf_download_params *param) +{ + int ret; + + /* Parse options */ + if (argc >= 2) { + param->port = strtoul(argv[1], NULL, 10); + } else { + param->port = DEF_PORT; + } + + if (argc >= 3) { + char *addr_str = argv[2]; + struct sockaddr addr; + + memset(&addr, 0, sizeof(addr)); + + ret = net_ipaddr_parse(addr_str, strlen(addr_str), &addr); + if (ret < 0) { + shell_fprintf(sh, SHELL_WARNING, + "Cannot parse address \"%s\"\n", + addr_str); + return ret; + } + + memcpy(¶m->addr, &addr, sizeof(struct sockaddr)); + } + + return 0; +} + static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) { int start = 0; @@ -333,10 +366,12 @@ static int cmd_udp_download(const struct shell *sh, size_t argc, struct zperf_download_params param = { 0 }; int ret; - if (argc >= 2) { - param.port = strtoul(argv[1], NULL, 10); - } else { - param.port = DEF_PORT; + ret = zperf_bind_host(sh, argc, argv, ¶m); + if (ret < 0) { + shell_fprintf(sh, SHELL_WARNING, + "Unable to bind host.\n"); + shell_help(sh); + return -ENOEXEC; } ret = zperf_udp_download(¶m, udp_session_cb, (void *)sh); @@ -1120,10 +1155,12 @@ static int cmd_tcp_download(const struct shell *sh, size_t argc, struct zperf_download_params param = { 0 }; int ret; - if (argc >= 2) { - param.port = strtoul(argv[1], NULL, 10); - } else { - param.port = DEF_PORT; + ret = zperf_bind_host(sh, argc, argv, ¶m); + if (ret < 0) { + shell_fprintf(sh, SHELL_WARNING, + "Unable to bind host.\n"); + shell_help(sh); + return -ENOEXEC; } ret = zperf_tcp_download(¶m, tcp_session_cb, (void *)sh); @@ -1254,8 +1291,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, , cmd_tcp_upload2), SHELL_CMD(download, &zperf_cmd_tcp_download, - "[]\n" - "Example: tcp download 5001\n", + "[]: Server port to listen on/connect to\n" + "[]: Bind to , an interface address\n" + "Example: tcp download 5001 192.168.0.1\n", cmd_tcp_download), SHELL_SUBCMD_SET_END ); @@ -1312,8 +1350,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, , cmd_udp_upload2), SHELL_CMD(download, &zperf_cmd_udp_download, - "[]\n" - "Example: udp download 5001\n", + "[]: Server port to listen on/connect to\n" + "[]: Bind to , an interface address\n" + "Example: udp download 5001 192.168.0.1\n", cmd_udp_download), SHELL_SUBCMD_SET_END ); diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index 25f9adc3494..614e1af6d03 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -46,6 +46,7 @@ static void *tcp_user_data; static bool tcp_server_running; static bool tcp_server_stop; static uint16_t tcp_server_port; +static struct sockaddr tcp_server_addr; static K_SEM_DEFINE(tcp_server_run, 0, 1); static void tcp_received(const struct sockaddr *addr, size_t datalen) @@ -150,6 +151,7 @@ static void tcp_server_session(void) if (IS_ENABLED(CONFIG_NET_IPV4)) { struct sockaddr_in *in4_addr = zperf_get_sin(); + const struct in_addr *addr = NULL; fds[SOCK_ID_IPV4_LISTEN].fd = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -158,7 +160,12 @@ static void tcp_server_session(void) goto error; } - if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + addr = &net_sin(&tcp_server_addr)->sin_addr; + + if (!net_ipv4_is_addr_unspecified(addr)) { + memcpy(&in4_addr->sin_addr, addr, + sizeof(struct in_addr)); + } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { /* Use Setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr->sin_addr); @@ -167,9 +174,8 @@ static void tcp_server_session(void) goto use_existing_ipv4; } } else { - /* Use existing IP */ - const struct in_addr *addr; use_existing_ipv4: + /* Use existing IP */ addr = zperf_get_default_if_in4_addr(); if (!addr) { NET_ERR("Unable to get IPv4 by default"); @@ -197,6 +203,7 @@ static void tcp_server_session(void) if (IS_ENABLED(CONFIG_NET_IPV6)) { struct sockaddr_in6 *in6_addr = zperf_get_sin6(); + const struct in6_addr *addr = NULL; fds[SOCK_ID_IPV6_LISTEN].fd = zsock_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); @@ -205,7 +212,12 @@ static void tcp_server_session(void) goto error; } - if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + addr = &net_sin6(&tcp_server_addr)->sin6_addr; + + if (!net_ipv6_is_addr_unspecified(addr)) { + memcpy(&in6_addr->sin6_addr, addr, + sizeof(struct in6_addr)); + } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { /* Use Setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, @@ -215,9 +227,8 @@ static void tcp_server_session(void) goto use_existing_ipv6; } } else { - /* Use existing IP */ - const struct in6_addr *addr; use_existing_ipv6: + /* Use existing IP */ addr = zperf_get_default_if_in6_addr(); if (!addr) { NET_ERR("Unable to get IPv6 by default"); @@ -387,6 +398,7 @@ int zperf_tcp_download(const struct zperf_download_params *param, tcp_server_port = param->port; tcp_server_running = true; tcp_server_stop = false; + memcpy(&tcp_server_addr, ¶m->addr, sizeof(struct sockaddr)); k_sem_give(&tcp_server_run); diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index f96acde6f49..cf29760e1c6 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -48,6 +48,7 @@ static void *udp_user_data; static bool udp_server_running; static bool udp_server_stop; static uint16_t udp_server_port; +static struct sockaddr udp_server_addr; static K_SEM_DEFINE(udp_server_run, 0, 1); static inline void build_reply(struct zperf_udp_datagram *hdr, @@ -251,7 +252,12 @@ static void udp_server_session(void) goto error; } - if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + in4_addr = &net_sin(&udp_server_addr)->sin_addr; + + if (!net_ipv4_is_addr_unspecified(in4_addr)) { + memcpy(&in4_addr_my->sin_addr, in4_addr, + sizeof(struct in_addr)); + } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { /* Use setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr_my->sin_addr); @@ -301,7 +307,12 @@ static void udp_server_session(void) goto error; } - if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + in6_addr = &net_sin6(&udp_server_addr)->sin6_addr; + + if (!net_ipv6_is_addr_unspecified(in6_addr)) { + memcpy(&in6_addr_my->sin6_addr, in6_addr, + sizeof(struct in6_addr)); + } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { /* Use setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, @@ -441,6 +452,7 @@ int zperf_udp_download(const struct zperf_download_params *param, udp_server_port = param->port; udp_server_running = true; udp_server_stop = false; + memcpy(&udp_server_addr, ¶m->addr, sizeof(struct sockaddr)); k_sem_give(&udp_server_run); From ae924b2afc359e9a4dff92d97a2250818346642d Mon Sep 17 00:00:00 2001 From: Manoel Brunnen Date: Thu, 21 Sep 2023 11:39:30 +0200 Subject: [PATCH 1427/4498] twister: Fix test-only tests with hardware map fixtures In test-only mode with a hardware map, all tests with fixtures were skipped, even when the hardware map has appropriate fixtures defined. TestPlan.load_from_file had the check for fixtures missing, but actually best is that the TestInstance checks the fixtures in the hardware map. Signed-off-by: Manoel Brunnen --- scripts/pylib/twister/twisterlib/testinstance.py | 9 ++++++++- scripts/pylib/twister/twisterlib/testplan.py | 11 ++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index ccfc3cd06d4..666a8d68d03 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -185,7 +185,7 @@ def setup_handler(self, env): self.handler = handler # Global testsuite parameters - def check_runnable(self, enable_slow=False, filter='buildable', fixtures=[]): + def check_runnable(self, enable_slow=False, filter='buildable', fixtures=[], hardware_map=None): # running on simulators is currently not supported on Windows if os.name == 'nt' and self.platform.simulation != 'na': @@ -218,6 +218,13 @@ def check_runnable(self, enable_slow=False, filter='buildable', fixtures=[]): testsuite_runnable = self.testsuite_runnable(self.testsuite, fixtures) + if hardware_map: + for h in hardware_map.duts: + if (h.platform == self.platform.name and + self.testsuite_runnable(self.testsuite, h.fixtures)): + testsuite_runnable = True + break + return testsuite_runnable and target_ready def create_overlay(self, platform, enable_asan=False, enable_ubsan=False, enable_coverage=False, coverage_platform=[]): diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index b6a590b752a..6275785bdcd 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -576,7 +576,8 @@ def load_from_file(self, file, filter_platform=[]): instance.run = instance.check_runnable( self.options.enable_slow, tfilter, - self.options.fixture + self.options.fixture, + self.hwm ) instance.metrics['handler_time'] = ts.get('execution_time', 0) @@ -726,13 +727,9 @@ def apply_filters(self, **kwargs): instance.run = instance.check_runnable( self.options.enable_slow, tfilter, - self.options.fixture + self.options.fixture, + self.hwm ) - if runnable and self.hwm.duts: - for h in self.hwm.duts: - if h.platform == plat.name: - if ts.harness_config.get('fixture') in h.fixtures: - instance.run = True if not force_platform and plat.name in exclude_platform: instance.add_filter("Platform is excluded on command line.", Filters.CMD_LINE) From 66730c961e87b6d00ab5b6cbea83df70c8eef35b Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Wed, 27 Sep 2023 15:43:31 +0200 Subject: [PATCH 1428/4498] scripts: tests: twister: Domain module testing Domain module was not yet covered by explicit unit tests. This commit adds a new test file to cover that gap. It achieves 100% coverage at the time of creation. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_domains.py | 219 ++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 scripts/tests/twister/test_domains.py diff --git a/scripts/tests/twister/test_domains.py b/scripts/tests/twister/test_domains.py new file mode 100644 index 00000000000..27b32ebbe15 --- /dev/null +++ b/scripts/tests/twister/test_domains.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for domains.py classes +""" + +import mock +import os +import pytest +import sys + +ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") +sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) + +import domains + +from contextlib import nullcontext + + +TESTDATA_1 = [ + ('', False, 1, ['domains.yaml file not found: domains.yaml']), + ( +""" +default: some default +build_dir: my/dir +domains: +- name: some default + build_dir: dir/2 +- name: another + build_dir: dir/3 +flash_order: I don\'t think this is correct +""", + True, 1, ['ERROR: Malformed yaml in file: domains.yaml'] + ), + ( +""" +default: None +build_dir: some/dir +""", + True, None, [] + ), +] + +@pytest.mark.parametrize( + 'f_contents, f_exists, exit_code, expected_logs', + TESTDATA_1, + ids=['no file', 'schema error', 'valid'] +) +def test_from_file(caplog, f_contents, f_exists, exit_code, expected_logs): + def mock_open(*args, **kwargs): + if f_exists: + return mock.mock_open(read_data=f_contents)(args, kwargs) + raise FileNotFoundError(f'domains.yaml not found.') + + init_mock = mock.Mock(return_value=None) + + with mock.patch('domains.Domains.__init__', init_mock), \ + mock.patch('builtins.open', mock_open), \ + pytest.raises(SystemExit) if exit_code else nullcontext() as s_exit: + result = domains.Domains.from_file('domains.yaml') + + if exit_code: + assert str(s_exit.value) == str(exit_code) + else: + init_mock.assert_called_once() + assert result is not None + + assert all([log in caplog.text for log in expected_logs]) + + +TESTDATA_2 = [ + ({'build_dir': None, 'default': None}, True, None, [], None, {}), + ( + { + 'build_dir': os.path.join('build', 'dir'), + 'domains': [ + { + 'name': 'a domain', + 'build_dir': os.path.join('dir', '1') + }, + { + 'name': 'default_domain', + 'build_dir': os.path.join('dir', '2') + } + ], + 'default': 'default_domain', + 'flash_order': ['default_domain', 'a domain'] + }, + False, + os.path.join('build', 'dir'), + [('default_domain', os.path.join('dir', '2')), + ('a domain', os.path.join('dir', '1'))], + ('default_domain', os.path.join('dir', '2')), + {'a domain': ('a domain', os.path.join('dir', '1')), + 'default_domain': ('default_domain', os.path.join('dir', '2'))} + ), +] + +@pytest.mark.parametrize( + 'data, expect_warning, expected_build_dir, expected_flash_order,' \ + ' expected_default, expected_domains', + TESTDATA_2, + ids=['required only', 'with default domain'] +) +def test_from_data( + caplog, + data, + expect_warning, + expected_build_dir, + expected_flash_order, + expected_default, + expected_domains +): + def mock_domain(name, build_dir, *args, **kwargs): + return name, build_dir + + warning_log = "no domains defined; this probably won't work" + + with mock.patch('domains.Domain', side_effect=mock_domain): + doms = domains.Domains.from_data(data) + + if expect_warning: + assert warning_log in caplog.text + else: + assert warning_log not in caplog.text + + assert doms.get_default_domain() == expected_default + assert doms.get_top_build_dir() == expected_build_dir + + assert doms._domains == expected_domains + + assert all([d in expected_flash_order for d in doms._flash_order]) + assert all([d in doms._flash_order for d in expected_flash_order]) + + +TESTDATA_3 = [ + ( + None, + True, + None, + [], + [('some', os.path.join('dir', '2')), + ('order', os.path.join('dir', '1'))] + ), + ( + None, + False, + None, + [], + [('order', os.path.join('dir', '1')), + ('some', os.path.join('dir', '2'))] + ), + ( + ['some', 'other'], + False, + 1, + ['domain other not found, valid domains are: order, some'], + [('some', os.path.join('dir', '2')), + ('order', os.path.join('dir', '1'))] + ), + ( + ['some'], + False, + None, + [], + [('some', os.path.join('dir', '2'))] + ), +] + +@pytest.mark.parametrize( + 'names, default_flash_order, exit_code, expected_logs, expected_result', + TESTDATA_3, + ids=['order only', 'no parameters', 'domain not found', 'valid'] +) +def test_get_domains( + caplog, + names, + default_flash_order, + exit_code, + expected_logs, + expected_result +): + doms = domains.Domains({'domains': [], 'default': None}) + doms._flash_order = [ + ('some', os.path.join('dir', '2')), + ('order', os.path.join('dir', '1')) + ] + doms._domains = { + 'order': ('order', os.path.join('dir', '1')), + 'some': ('some', os.path.join('dir', '2')) + } + + with pytest.raises(SystemExit) if exit_code else nullcontext() as s_exit: + result = doms.get_domains(names, default_flash_order) + + assert all([log in caplog.text for log in expected_logs]) + + if exit_code: + assert str(s_exit.value) == str(exit_code) + else: + assert result == expected_result + + +def test_domain(): + name = 'Domain Name' + build_dir = 'build/dir' + + domain = domains.Domain(name, build_dir) + + assert domain.name == name + assert domain.build_dir == build_dir + + domain.name = 'New Name' + domain.build_dir = 'new/dir' + + assert domain.name == 'New Name' + assert domain.build_dir == 'new/dir' From 90fac3045db59585f724fadc63adcaea9fcafd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Wed, 6 Sep 2023 18:57:08 +0200 Subject: [PATCH 1429/4498] tests: bluetooth: tester: add transfer ttl to mbt inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adding transfer ttl ixit value to be used as input for mbt test cases Signed-off-by: Alperen Şener --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 ++ tests/bluetooth/tester/src/btp_mesh.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index ea5d89de07a..6c4a5e90106 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -954,6 +954,7 @@ struct btp_mmdl_dfu_firmware_update_rp { struct btp_mmdl_blob_srv_recv_cmd { uint64_t id; uint16_t timeout; + uint8_t ttl; } __packed; #define BTP_MMDL_BLOB_TRANSFER_START 0x66 @@ -963,6 +964,7 @@ struct btp_mmdl_blob_transfer_start_cmd { uint8_t block_size; uint16_t chunk_size; uint16_t timeout; + uint8_t ttl; } __packed; #define BTP_MMDL_BLOB_TRANSFER_CANCEL 0x67 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index b9297474860..ffd4b69db84 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -4228,6 +4228,10 @@ static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len, blob_cli_xfer.inputs.timeout_base = cp->timeout; } + if (cp->ttl) { + blob_cli_xfer.inputs.ttl = cp->ttl; + } + err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs, &blob_cli_xfer.xfer, &dummy_blob_io); @@ -4311,13 +4315,15 @@ static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, uint16_t timeout_base; uint64_t id; + uint8_t ttl; LOG_DBG(""); id = cp->id; timeout_base = cp->timeout; + ttl = cp->ttl; - err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, BT_MESH_TTL_MAX, + err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, ttl, timeout_base); if (err) { From a54c18ad31943d113b10bdebfbee7e9928ae7862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Sat, 9 Sep 2023 19:41:26 +0200 Subject: [PATCH 1430/4498] tests: bluetooth: tester: fix improper large comp rsp struct init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Large composition data response struct should have a data buffer to store the reponse data to Signed-off-by: Alperen Şener --- tests/bluetooth/tester/src/btp_mesh.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index ffd4b69db84..f02d51c905a 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1761,7 +1761,12 @@ static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, struct btp_mesh_large_comp_data_get_rp *rp = rsp; int err; - struct bt_mesh_large_comp_data_rsp comp; + NET_BUF_SIMPLE_DEFINE(data, 500); + net_buf_simple_init(&data, 0); + + struct bt_mesh_large_comp_data_rsp comp = { + .data = &data, + }; err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->addr), cp->page, @@ -1785,7 +1790,12 @@ static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len, struct btp_mesh_models_metadata_get_rp *rp = rsp; int err; - struct bt_mesh_large_comp_data_rsp metadata; + NET_BUF_SIMPLE_DEFINE(data, 500); + net_buf_simple_init(&data, 0); + + struct bt_mesh_large_comp_data_rsp metadata = { + .data = &data, + }; err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->addr), cp->page, From 05e806d31d8ad7a37d20a07cdc32f7d68b044e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Thu, 28 Sep 2023 15:48:04 +0200 Subject: [PATCH 1431/4498] bluetooth: mesh: check upload slot before release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check if the slot is not reseved, NULL before try to releas it. Signed-off-by: Alperen Şener --- subsys/bluetooth/mesh/dfd_srv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 54de343c94a..59fe5b830d1 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -477,7 +477,9 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx /* This will be a no-op if the slot state isn't RESERVED, which is * what we want. */ - bt_mesh_dfu_slot_release(srv->upload.slot); + if (srv->upload.slot) { + bt_mesh_dfu_slot_release(srv->upload.slot); + } #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD srv->upload.is_oob = false; From 8a25b039e4ec687f89d19e2c388bddf2b8e84d31 Mon Sep 17 00:00:00 2001 From: David Corbeil Date: Thu, 28 Sep 2023 12:11:19 -0400 Subject: [PATCH 1432/4498] logging: net: changing syslog server address while running bug Fixed bug where changing the syslog network server's address while it's still running would fail most of the time Signed-off-by: David Corbeil --- subsys/logging/backends/log_backend_net.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/subsys/logging/backends/log_backend_net.c b/subsys/logging/backends/log_backend_net.c index c2236f98b66..0681e5901c7 100644 --- a/subsys/logging/backends/log_backend_net.c +++ b/subsys/logging/backends/log_backend_net.c @@ -199,18 +199,33 @@ static int format_set(const struct log_backend *const backend, uint32_t log_type bool log_backend_net_set_addr(const char *addr) { + bool ret = false; + if (net_init_done) { - const struct log_backend *backend = log_backend_net_get(); /* Release context so it can be recreated with the specified ip address * next time process() is called */ - net_context_put(backend->cb->ctx); - net_init_done = false; + int released = net_context_put(log_output_net.control_block->ctx); + + if (released < 0) { + LOG_ERR("Cannot release context (%d)", ret); + ret = false; + } else { + /* The context is successfully released so we flag it + * to be recreated with the new ip address + */ + net_init_done = false; + ret = true; + } + + if (!ret) { + return ret; + } } net_sin(&server_addr)->sin_port = htons(514); - bool ret = net_ipaddr_parse(addr, strlen(addr), &server_addr); + ret = net_ipaddr_parse(addr, strlen(addr), &server_addr); if (!ret) { LOG_ERR("Cannot parse syslog server address"); From 36402b6d2a79f17c27104c02aae0e1f00d411f23 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 25 Sep 2023 10:01:52 +0200 Subject: [PATCH 1433/4498] net: pkt: time: introduce ns timestamp helper A little refactoring that simplifies dealing with nanosecond timestamp values in packets and further decouples calling code from PTP: Benefits: - simplifies calling code by removing redundant conversions. - prepares for removing PTP dependencies from net_pkt. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_dw1000.c | 18 +++++------------ drivers/ieee802154/ieee802154_nrf5.c | 17 +++------------- include/zephyr/net/net_pkt.h | 28 ++++++++++++++++++++++++-- modules/openthread/platform/radio.c | 16 +++------------ subsys/net/ip/net_context.c | 5 +---- tests/net/socket/udp/src/main.c | 2 +- tests/subsys/openthread/radio_test.c | 3 +-- 7 files changed, 40 insertions(+), 49 deletions(-) diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index d48fd715ae1..730828d78ea 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -452,14 +452,11 @@ static inline void dwt_irq_handle_rx(const struct device *dev, uint32_t sys_stat if (IS_ENABLED(CONFIG_NET_PKT_TIMESTAMP)) { uint8_t ts_buf[sizeof(uint64_t)] = {0}; - struct net_ptp_time timestamp; - uint64_t ts_fsec; + uint64_t ts_nsec; memcpy(ts_buf, rx_inf_reg.rx_time, DWT_RX_TIME_RX_STAMP_LEN); - ts_fsec = sys_get_le64(ts_buf) * DWT_TS_TIME_UNITS_FS; - timestamp.second = (ts_fsec / 1000000) / NSEC_PER_SEC; - timestamp.nanosecond = (ts_fsec / 1000000) % NSEC_PER_SEC; - net_pkt_set_timestamp(pkt, ×tamp); + ts_nsec = (sys_get_le64(ts_buf) * DWT_TS_TIME_UNITS_FS) / 1000000U; + net_pkt_set_timestamp_ns(pkt, ts_nsec); } /* See 4.7.2 Estimating the receive signal power */ @@ -787,7 +784,6 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, struct dwt_context *ctx = dev->data; size_t len = frag->len; uint32_t tx_time = 0; - struct net_ptp_time *txts; uint64_t tmp_fs; uint32_t tx_fctrl; uint8_t sys_ctrl = DWT_SYS_CTRL_TXSTRT; @@ -808,8 +804,7 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, * tx_time is the high 32-bit of the 40-bit system * time value at which to send the message. */ - txts = net_pkt_timestamp(pkt); - tmp_fs = txts->second * NSEC_PER_SEC + txts->nanosecond; + tmp_fs = net_pkt_timestamp_ns(pkt); tmp_fs *= 1000U * 1000U; tx_time = (tmp_fs / DWT_TS_TIME_UNITS_FS) >> 8; @@ -866,7 +861,6 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, if (IS_ENABLED(CONFIG_NET_PKT_TIMESTAMP)) { uint8_t ts_buf[sizeof(uint64_t)] = {0}; - struct net_ptp_time timestamp; k_sem_take(&ctx->dev_lock, K_FOREVER); dwt_register_read(dev, DWT_TX_TIME_ID, @@ -879,9 +873,7 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, k_sem_give(&ctx->dev_lock); tmp_fs = sys_get_le64(ts_buf) * DWT_TS_TIME_UNITS_FS; - timestamp.second = (tmp_fs / 1000000) / NSEC_PER_SEC; - timestamp.nanosecond = (tmp_fs / 1000000) % NSEC_PER_SEC; - net_pkt_set_timestamp(pkt, ×tamp); + net_pkt_set_timestamp_ns(pkt, tmp_fs / 1000000U); } atomic_clear_bit(&ctx->state, DWT_STATE_TX); diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 3391add641a..f02ce5bda8f 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -178,13 +178,7 @@ static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3) net_pkt_set_ieee802154_ack_fpb(pkt, rx_frame->ack_fpb); #if defined(CONFIG_NET_PKT_TIMESTAMP) - struct net_ptp_time timestamp = { - .second = rx_frame->time / USEC_PER_SEC, - .nanosecond = - (rx_frame->time % USEC_PER_SEC) * NSEC_PER_USEC - }; - - net_pkt_set_timestamp(pkt, ×tamp); + net_pkt_set_timestamp_ns(pkt, rx_frame->time * NSEC_PER_USEC); #endif LOG_DBG("Caught a packet (%u) (LQI: %u)", @@ -407,12 +401,7 @@ static int handle_ack(struct nrf5_802154_data *nrf5_radio) net_pkt_set_ieee802154_rssi_dbm(ack_pkt, nrf5_radio->ack_frame.rssi); #if defined(CONFIG_NET_PKT_TIMESTAMP) - struct net_ptp_time timestamp = { - .second = nrf5_radio->ack_frame.time / USEC_PER_SEC, - .nanosecond = (nrf5_radio->ack_frame.time % USEC_PER_SEC) * NSEC_PER_USEC - }; - - net_pkt_set_timestamp(ack_pkt, ×tamp); + net_pkt_set_timestamp_ns(ack_pkt, nrf5_radio->ack_frame.time * NSEC_PER_USEC); #endif net_pkt_cursor_init(ack_pkt); @@ -531,7 +520,7 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, * expects a timestamp pointing to start of SHR. */ uint64_t tx_at = nrf_802154_timestamp_phr_to_shr_convert( - net_ptp_time_to_ns(net_pkt_timestamp(pkt)) / NSEC_PER_USEC); + net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC); return nrf_802154_transmit_raw_at(payload, tx_at, &metadata); } diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 219293dd647..4931f95009d 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -927,6 +927,16 @@ static inline void net_pkt_set_timestamp(struct net_pkt *pkt, pkt->timestamp.second = timestamp->second; pkt->timestamp.nanosecond = timestamp->nanosecond; } + +static inline net_time_t net_pkt_timestamp_ns(struct net_pkt *pkt) +{ + return net_ptp_time_to_ns(&pkt->timestamp); +} + +static inline void net_pkt_set_timestamp_ns(struct net_pkt *pkt, net_time_t timestamp) +{ + pkt->timestamp = ns_to_net_ptp_time(timestamp); +} #else static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt) { @@ -941,6 +951,19 @@ static inline void net_pkt_set_timestamp(struct net_pkt *pkt, ARG_UNUSED(pkt); ARG_UNUSED(timestamp); } + +static inline net_time_t net_pkt_timestamp_ns(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); + + return 0; +} + +static inline void net_pkt_set_timestamp_ns(struct net_pkt *pkt, net_time_t timestamp) +{ + ARG_UNUSED(pkt); + ARG_UNUSED(timestamp); +} #endif /* CONFIG_NET_PKT_TIMESTAMP || CONFIG_NET_PKT_TXTIME */ #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS) @@ -971,7 +994,7 @@ static inline void net_pkt_set_create_time(struct net_pkt *pkt, #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */ /** - * @deprecated Use @ref net_pkt_timestamp instead. + * @deprecated Use @ref net_pkt_timestamp or @ref net_pkt_timestamp_ns instead. */ static inline uint64_t net_pkt_txtime(struct net_pkt *pkt) { @@ -985,7 +1008,8 @@ static inline uint64_t net_pkt_txtime(struct net_pkt *pkt) } /** - * @deprecated Use @ref net_pkt_set_timestamp instead. + * @deprecated Use @ref net_pkt_set_timestamp or @ref net_pkt_set_timestamp_ns + * instead. */ static inline void net_pkt_set_txtime(struct net_pkt *pkt, uint64_t txtime) { diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 9d50e445714..17753ee852d 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -184,11 +184,7 @@ enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt ack_frame.mInfo.mRxInfo.mRssi = net_pkt_ieee802154_rssi_dbm(pkt); #if defined(CONFIG_NET_PKT_TIMESTAMP) - struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - - /* OpenThread expects the timestamp to point to the end of SFD */ - ack_frame.mInfo.mRxInfo.mTimestamp = pkt_time->second * USEC_PER_SEC + - pkt_time->nanosecond / NSEC_PER_USEC; + ack_frame.mInfo.mRxInfo.mTimestamp = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC; #endif return NET_OK; @@ -396,9 +392,7 @@ void transmit_message(struct k_work *tx_job) #if defined(CONFIG_NET_PKT_TXTIME) uint32_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + sTransmitFrame.mInfo.mTxInfo.mTxDelay; - struct net_ptp_time timestamp = - ns_to_net_ptp_time(convert_32bit_us_wrapped_to_64bit_ns(tx_at)); - net_pkt_set_timestamp(tx_pkt, ×tamp); + net_pkt_set_timestamp_ns(tx_pkt, convert_32bit_us_wrapped_to_64bit_ns(tx_at)); #endif tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_TXTIME_CCA, tx_pkt, tx_payload); @@ -476,11 +470,7 @@ static void openthread_handle_received_frame(otInstance *instance, recv_frame.mInfo.mRxInfo.mAckedWithFramePending = net_pkt_ieee802154_ack_fpb(pkt); #if defined(CONFIG_NET_PKT_TIMESTAMP) - struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - - /* OpenThread expects the timestamp to point to the end of SFD */ - recv_frame.mInfo.mRxInfo.mTimestamp = - pkt_time->second * USEC_PER_SEC + pkt_time->nanosecond / NSEC_PER_USEC; + recv_frame.mInfo.mRxInfo.mTimestamp = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC; #endif if (net_pkt_ieee802154_arb(pkt) && net_pkt_ieee802154_fv2015(pkt)) { diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 7875d6e3bc3..c611f48b3fa 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1656,10 +1656,7 @@ static void set_pkt_txtime(struct net_pkt *pkt, const struct msghdr *msghdr) if (cmsg->cmsg_len == CMSG_LEN(sizeof(uint64_t)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TXTIME) { - struct net_ptp_time txtime = - ns_to_net_ptp_time(*(net_time_t *)CMSG_DATA(cmsg)); - - net_pkt_set_timestamp(pkt, &txtime); + net_pkt_set_timestamp_ns(pkt, *(net_time_t *)CMSG_DATA(cmsg)); break; } } diff --git a/tests/net/socket/udp/src/main.c b/tests/net/socket/udp/src/main.c index 310f130d5d8..31c1fba43f5 100644 --- a/tests/net/socket/udp/src/main.c +++ b/tests/net/socket/udp/src/main.c @@ -974,7 +974,7 @@ static int eth_fake_send(const struct device *dev, struct net_pkt *pkt) return 0; } - txtime = net_ptp_time_to_ns(net_pkt_timestamp(pkt)); + txtime = net_pkt_timestamp_ns(pkt); if (txtime != TEST_TXTIME) { test_failed = true; } else { diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index ab251e6807f..a5b9014825c 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -320,8 +320,7 @@ ZTEST(openthread_radio, test_tx_test) zassert_equal(power, set_txpower_mock_fake.arg1_val); zassert_equal(1, tx_mock_fake.call_count); zassert_equal_ptr(frm->mPsdu, tx_mock_fake.arg3_val->data, NULL); - zassert_equal(expected_target_time, - net_ptp_time_to_ns(net_pkt_timestamp(tx_mock_fake.arg2_val))); + zassert_equal(expected_target_time, net_pkt_timestamp_ns(tx_mock_fake.arg2_val)); zassert_equal(IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? IEEE802154_TX_MODE_TXTIME_CCA : IEEE802154_TX_MODE_DIRECT, tx_mock_fake.arg1_val); From 203391a3785e05bd8f909d8a5cccddd57bcd3522 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 17 Aug 2023 18:39:57 +0200 Subject: [PATCH 1434/4498] net: l2: ieee802154: security config The "encryption only" security level was deprecated in IEEE 802.15.4-2015. This deprecation has already been introduced in the code but was overlooked in net config. Signed-off-by: Florian Grandel --- subsys/net/lib/config/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/config/Kconfig b/subsys/net/lib/config/Kconfig index 58895881ef4..c74193fec97 100644 --- a/subsys/net/lib/config/Kconfig +++ b/subsys/net/lib/config/Kconfig @@ -171,7 +171,7 @@ config NET_CONFIG_IEEE802154_SECURITY_LEVEL 1 authentication only with a 4 bytes length tag 2 authentication only with a 8 bytes length tag 3 authentication only with a 16 bytes length tag - 4 encryption only + 4 deprecated since IEEE 802.15.4-2015 5 encryption/authentication with a 4 bytes length tag 6 encryption/authentication with a 8 bytes length tag 7 encryption/authentication with a 16 bytes length tag From a5d46e7d660458ccc6f6179d3d0b0c47c8cf49fe Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 25 Sep 2023 10:19:57 +0200 Subject: [PATCH 1435/4498] net: l2: ieee802154: mgmt: NET_CONTINUE unless pkt is unrefed It is the general rule in Zephyr's network stack that methods that return NET_OK are expected to have "consumed" the packet, i.e. it should not be referenced any more. This change applies this rule to the methods in ieee802154_mgmt.* for improved consistency with the remainder of the network stack. Signed-off-by: Florian Grandel --- subsys/net/l2/ieee802154/ieee802154.c | 9 +++++---- subsys/net/l2/ieee802154/ieee802154_mgmt.c | 4 ++-- subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index 43a2d052daa..e3ef1cc3377 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -360,7 +360,7 @@ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_m static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pkt) { const struct ieee802154_radio_api *radio = net_if_get_device(iface)->api; - enum net_verdict verdict = NET_DROP; + enum net_verdict verdict = NET_CONTINUE; struct ieee802154_fcf_seq *fs; struct ieee802154_mpdu mpdu; bool is_broadcast; @@ -387,8 +387,9 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk if (fs->fc.frame_type == IEEE802154_FRAME_TYPE_BEACON) { verdict = ieee802154_handle_beacon(iface, &mpdu, net_pkt_ieee802154_lqi(pkt)); - if (verdict == NET_OK) { + if (verdict == NET_CONTINUE) { net_pkt_unref(pkt); + return NET_OK; } /* Beacons must not be acknowledged, see section 6.7.4.1. */ return verdict; @@ -400,7 +401,7 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk if (fs->fc.frame_type == IEEE802154_FRAME_TYPE_MAC_COMMAND) { verdict = ieee802154_handle_mac_command(iface, &mpdu); - if (verdict != NET_OK) { + if (verdict == NET_DROP) { return verdict; } } @@ -427,7 +428,7 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk if (fs->fc.frame_type == IEEE802154_FRAME_TYPE_MAC_COMMAND) { net_pkt_unref(pkt); - return verdict; + return NET_OK; } if (!ieee802154_decipher_data_frame(iface, pkt, &mpdu)) { diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index 30ac0f836cd..f9dd3dd5c6a 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -68,7 +68,7 @@ enum net_verdict ieee802154_handle_beacon(struct net_if *iface, k_sem_give(&ctx->scan_ctx_lock); - return NET_OK; + return NET_CONTINUE; } static int ieee802154_cancel_scan(uint32_t mgmt_request, struct net_if *iface, @@ -367,7 +367,7 @@ enum net_verdict ieee802154_handle_mac_command(struct net_if *iface, k_sem_give(&ctx->scan_ctx_lock); - return NET_OK; + return NET_CONTINUE; } if (mpdu->command->cfi == IEEE802154_CFI_DISASSOCIATION_NOTIFICATION) { diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h b/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h index 2e8b53693a4..acdd15a94fc 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h @@ -33,8 +33,8 @@ static inline void ieee802154_mgmt_init(struct net_if *iface) /** * Handles the given Beacon frame. * - * Returns NET_OK if successful. It's the caller's responsibility - * to release the corresponding package in that case. + * @retval NET_CONTINUE if successful. + * @retval NET_DROP error while parsing the beacon */ enum net_verdict ieee802154_handle_beacon(struct net_if *iface, struct ieee802154_mpdu *mpdu, @@ -43,8 +43,8 @@ enum net_verdict ieee802154_handle_beacon(struct net_if *iface, /** * Executes the given MAC command. * - * Returns NET_OK if successful. It's the caller's responsibility - * to release the corresponding package in that case. + * @retval NET_CONTINUE if successful. + * @retval NET_DROP error while parsing the mac command */ enum net_verdict ieee802154_handle_mac_command(struct net_if *iface, struct ieee802154_mpdu *mpdu); From 60ad26403ba1f2a7260405395710d8f43dccde9a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 25 Sep 2023 10:56:03 +0200 Subject: [PATCH 1436/4498] net: l2: ieee802154: only log fully assembled pkts As we already log fragmented packets there's no need to log them again unless they have been fully assembled and the result is to be logged. We also want to log the final packet in all cases (after mangling LL address) for the non-fragmented case. Signed-off-by: Florian Grandel --- subsys/net/l2/ieee802154/ieee802154.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index e3ef1cc3377..fc9c13c4f55 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -454,12 +454,13 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk #ifdef CONFIG_NET_6LO verdict = ieee802154_6lo_decode_pkt(iface, pkt); +#endif /* CONFIG_NET_6LO */ + + if (verdict == NET_CONTINUE) { + pkt_hexdump(RX_PKT_TITLE, pkt, true); + } - pkt_hexdump(RX_PKT_TITLE, pkt, true); return verdict; -#else - return NET_CONTINUE; -#endif /* CONFIG_NET_6LO */ /* At this point the call amounts to (part of) an * MCPS-DATA.indication primitive, see section 8.3.3. From 667c35a019979d53f64bde1f8f389e97db89ed24 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Wed, 28 Jun 2023 18:32:04 +0530 Subject: [PATCH 1437/4498] qinclude: zephyr: misc: Added timeaware gpio header file Added timeaware gpio interface. Signed-off-by: Anisetti Avinash Krishna --- drivers/misc/CMakeLists.txt | 1 + drivers/misc/Kconfig | 1 + drivers/misc/timeaware_gpio/CMakeLists.txt | 7 + drivers/misc/timeaware_gpio/Kconfig | 24 +++ .../timeaware_gpio/timeaware_gpio_handlers.c | 60 ++++++ .../misc/timeaware_gpio/timeaware_gpio.h | 193 ++++++++++++++++++ 6 files changed, 286 insertions(+) create mode 100644 drivers/misc/timeaware_gpio/CMakeLists.txt create mode 100644 drivers/misc/timeaware_gpio/Kconfig create mode 100644 drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c create mode 100644 include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index 62b53f4f1ce..863f839184e 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory_ifdef(CONFIG_FT800 ft8xx) add_subdirectory_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb) add_subdirectory_ifdef(CONFIG_PIO_RPI_PICO pio_rpi_pico) add_subdirectory_ifdef(CONFIG_NXP_S32_EMIOS nxp_s32_emios) +add_subdirectory_ifdef(CONFIG_TIMEAWARE_GPIO timeaware_gpio) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 342d9fb70f9..66d83fc693d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -9,5 +9,6 @@ source "drivers/misc/ft8xx/Kconfig" source "drivers/misc/grove_lcd_rgb/Kconfig" source "drivers/misc/pio_rpi_pico/Kconfig" source "drivers/misc/nxp_s32_emios/Kconfig" +source "drivers/misc/timeaware_gpio/Kconfig" endmenu diff --git a/drivers/misc/timeaware_gpio/CMakeLists.txt b/drivers/misc/timeaware_gpio/CMakeLists.txt new file mode 100644 index 00000000000..dd3ef4d4d5a --- /dev/null +++ b/drivers/misc/timeaware_gpio/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h) + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_USERSPACE timeaware_gpio_handlers.c) diff --git a/drivers/misc/timeaware_gpio/Kconfig b/drivers/misc/timeaware_gpio/Kconfig new file mode 100644 index 00000000000..987185a1863 --- /dev/null +++ b/drivers/misc/timeaware_gpio/Kconfig @@ -0,0 +1,24 @@ +# Timeaware gpio config options + +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + + +menuconfig TIMEAWARE_GPIO + bool "Timeaware GPIO driver" + help + Enable config options for timeaware GPIO driver. + +if TIMEAWARE_GPIO + +module = TIMEAWARE_GPIO +module-str = timeaware_gpio +source "subsys/logging/Kconfig.template.log_config" + +config TIMEAWARE_GPIO_INIT_PRIORITY + int "Timeaware GPIO initialization priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + System initialization priority for timeaware GPIO drivers. + +endif # TIMEAWARE_GPIO diff --git a/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c b/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c new file mode 100644 index 00000000000..e65dcb2a62c --- /dev/null +++ b/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +static inline int z_vrfy_tgpio_port_get_time(const struct device *port, uint64_t *current_time) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, get_time)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(current_time, sizeof(uint64_t))); + return z_impl_tgpio_port_get_time((const struct device *)port, (uint64_t *)current_time); +} +#include + +static inline int z_vrfy_tgpio_port_get_cycles_per_second(const struct device *port, + uint32_t *cycles) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, cyc_per_sec)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint32_t))); + return z_impl_tgpio_port_get_cycles_per_second((const struct device *)port, + (uint32_t *)cycles); +} +#include + +static inline int z_vrfy_tgpio_pin_periodic_output(const struct device *port, uint32_t pin, + uint64_t start_time, uint64_t repeat_interval, + bool periodic_enable) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, set_perout)); + return z_impl_tgpio_pin_periodic_output((const struct device *)port, pin, start_time, + repeat_interval, periodic_enable); +} +#include + +static inline int z_vrfy_tgpio_pin_disable(const struct device *port, uint32_t pin) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, pin_disable)); + return z_impl_tgpio_pin_disable((const struct device *)port, pin); +} +#include + +static inline int z_vrfy_tgpio_pin_config_ext_timestamp(const struct device *port, uint32_t pin, + uint32_t event_polarity) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, config_ext_ts)); + return z_impl_tgpio_pin_config_ext_timestamp((const struct device *)port, pin, + event_polarity); +} +#include + +static inline int z_vrfy_tgpio_pin_read_ts_ec(const struct device *port, uint32_t pin, + uint64_t *timestamp, uint64_t *event_count) +{ + Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, read_ts_ec)); + return z_impl_tgpio_pin_read_ts_ec((const struct device *)port, pin, (uint64_t *)timestamp, + (uint64_t *)event_count); +} +#include diff --git a/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h b/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h new file mode 100644 index 00000000000..68c305f9e18 --- /dev/null +++ b/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public APIs for Time-aware GPIO drivers + */ +#ifndef ZEPHYR_DRIVERS_MISC_TIMEAWARE_GPIO_TIMEAWARE_GPIO +#define ZEPHYR_DRIVERS_MISC_TIMEAWARE_GPIO_TIMEAWARE_GPIO + +/** + * @brief Time-aware GPIO Interface + * @defgroup tgpio_interface Time-aware GPIO Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Event polarity + */ +enum tgpio_pin_polarity { + TGPIO_RISING_EDGE = 0, + TGPIO_FALLING_EDGE, + TGPIO_TOGGLE_EDGE, +}; + +/** + * @cond INTERNAL_HIDDEN + * + * TGPIO driver API definition and system call entry points + * + * (Internal use only.) + */ + +__subsystem struct tgpio_driver_api { + int (*pin_disable)(const struct device *dev, uint32_t pin); + int (*get_time)(const struct device *dev, uint64_t *current_time); + int (*cyc_per_sec)(const struct device *dev, uint32_t *cycles); + int (*set_perout)(const struct device *dev, uint32_t pin, uint64_t start_time, + uint64_t repeat_interval, bool periodic_enable); + int (*config_ext_ts)(const struct device *dev, uint32_t pin, uint32_t event_polarity); + int (*read_ts_ec)(const struct device *dev, uint32_t pin, uint64_t *timestamp, + uint64_t *event_count); +}; + +/** + * @endcond + */ + +/** + * @brief Get time from ART timer + * + * @param dev TGPIO device + * @param current_time Pointer to store timer value in cycles + * + * @return 0 if successful + * @return negative errno code on failure. + */ +__syscall int tgpio_port_get_time(const struct device *dev, uint64_t *current_time); + +static inline int z_impl_tgpio_port_get_time(const struct device *dev, uint64_t *current_time) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->get_time(dev, current_time); +} + +/** + * @brief Get current running rate + * + * @param dev TGPIO device + * @param cycles pointer to store current running requency + * + * @return 0 if successful, negative errno code on failure. + */ +__syscall int tgpio_port_get_cycles_per_second(const struct device *dev, uint32_t *cycles); + +static inline int z_impl_tgpio_port_get_cycles_per_second(const struct device *dev, + uint32_t *cycles) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->cyc_per_sec(dev, cycles); +} + +/** + * @brief Disable operation on pin + * + * @param dev TGPIO device + * @param pin TGPIO pin + * + * @return 0 if successful, negative errno code on failure. + */ +__syscall int tgpio_pin_disable(const struct device *dev, uint32_t pin); + +static inline int z_impl_tgpio_pin_disable(const struct device *dev, uint32_t pin) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->pin_disable(dev, pin); +} + +/** + * @brief Enable/Continue operation on pin + * + * @param dev TGPIO device + * @param pin TGPIO pin + * @param event_polarity TGPIO pin event polarity + * + * @return 0 if successful, negative errno code on failure. + */ +__syscall int tgpio_pin_config_ext_timestamp(const struct device *dev, uint32_t pin, + uint32_t event_polarity); + +static inline int z_impl_tgpio_pin_config_ext_timestamp(const struct device *dev, uint32_t pin, + uint32_t event_polarity) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->config_ext_ts(dev, pin, event_polarity); +} + +/** + * @brief Enable periodic pulse generation on a pin + * + * @param dev TGPIO device + * @param pin TGPIO pin + * @param start_time start_time of first pulse in hw cycles + * @param repeat_interval repeat interval between two pulses in hw cycles + * @param periodic_enable enables periodic mode if 'true' is passed. + * + * @return 0 if successful, negative errno code on failure. + */ +__syscall int tgpio_pin_periodic_output(const struct device *dev, uint32_t pin, + uint64_t start_time, uint64_t repeat_interval, + bool periodic_enable); + +static inline int z_impl_tgpio_pin_periodic_output(const struct device *dev, uint32_t pin, + uint64_t start_time, uint64_t repeat_interval, + bool periodic_enable) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->set_perout(dev, pin, start_time, repeat_interval, periodic_enable); +} + +/** + * @brief Read timestamp and event counter from TGPIO + * + * @param dev TGPIO device + * @param pin TGPIO pin + * @param timestamp timestamp of the last pulse received + * @param event_count number of pulses received since the pin is enabled + * + * @return 0 if successful, negative errno code on failure. + */ +__syscall int tgpio_pin_read_ts_ec(const struct device *dev, uint32_t pin, uint64_t *timestamp, + uint64_t *event_count); + +static inline int z_impl_tgpio_pin_read_ts_ec(const struct device *dev, uint32_t pin, + uint64_t *timestamp, uint64_t *event_count) +{ + const struct tgpio_driver_api *api = (const struct tgpio_driver_api *)dev->api; + + return api->read_ts_ec(dev, pin, timestamp, event_count); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_DRIVERS_MISC_TIMEAWARE_GPIO_TIMEAWARE_GPIO */ From c45b719442b6f598bdf883e306c172d6c6f30e9a Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Wed, 28 Jun 2023 18:48:48 +0530 Subject: [PATCH 1438/4498] drivers: misc: timeaware_gpio: Added intel PCH driver Added intel PCH driver for timeaware GPIO. Signed-off-by: Anisetti Avinash Krishna --- drivers/misc/timeaware_gpio/CMakeLists.txt | 2 + drivers/misc/timeaware_gpio/Kconfig | 2 + .../Kconfig.timeaware_gpio_intel | 11 + .../timeaware_gpio/timeaware_gpio_intel.c | 231 ++++++++++++++++++ dts/bindings/misc/intel,timeaware-gpio.yaml | 22 ++ 5 files changed, 268 insertions(+) create mode 100644 drivers/misc/timeaware_gpio/Kconfig.timeaware_gpio_intel create mode 100644 drivers/misc/timeaware_gpio/timeaware_gpio_intel.c create mode 100644 dts/bindings/misc/intel,timeaware-gpio.yaml diff --git a/drivers/misc/timeaware_gpio/CMakeLists.txt b/drivers/misc/timeaware_gpio/CMakeLists.txt index dd3ef4d4d5a..a93054ff217 100644 --- a/drivers/misc/timeaware_gpio/CMakeLists.txt +++ b/drivers/misc/timeaware_gpio/CMakeLists.txt @@ -4,4 +4,6 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/misc/timeaware_gpio/ zephyr_library() +zephyr_library_sources_ifdef(CONFIG_TIMEAWARE_GPIO_INTEL timeaware_gpio_intel.c) + zephyr_library_sources_ifdef(CONFIG_USERSPACE timeaware_gpio_handlers.c) diff --git a/drivers/misc/timeaware_gpio/Kconfig b/drivers/misc/timeaware_gpio/Kconfig index 987185a1863..a6d7f4a2eb3 100644 --- a/drivers/misc/timeaware_gpio/Kconfig +++ b/drivers/misc/timeaware_gpio/Kconfig @@ -21,4 +21,6 @@ config TIMEAWARE_GPIO_INIT_PRIORITY help System initialization priority for timeaware GPIO drivers. +source "drivers/misc/timeaware_gpio/Kconfig.timeaware_gpio_intel" + endif # TIMEAWARE_GPIO diff --git a/drivers/misc/timeaware_gpio/Kconfig.timeaware_gpio_intel b/drivers/misc/timeaware_gpio/Kconfig.timeaware_gpio_intel new file mode 100644 index 00000000000..a62ee66dd25 --- /dev/null +++ b/drivers/misc/timeaware_gpio/Kconfig.timeaware_gpio_intel @@ -0,0 +1,11 @@ +# INTEL PMC TGPIO configuration options +# +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config TIMEAWARE_GPIO_INTEL + bool "Intel Time aware GPIO driver" + default y + depends on DT_HAS_INTEL_TIMEAWARE_GPIO_ENABLED + help + Intel time aware GPIO driver found on Intel PCH subsystem diff --git a/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c b/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c new file mode 100644 index 00000000000..5c193389552 --- /dev/null +++ b/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_timeaware_gpio + +#include +#include +#include +#include +#include +#include +#include + +/* TGPIO Register offsets */ +#define ART_L 0x00 /* ART lower 32 bit reg */ +#define ART_H 0x04 /* ART higher 32 bit reg */ +#define CTL 0x10 /* TGPIO control reg */ +#define COMPV31_0 0x20 /* Comparator lower 32 bit reg */ +#define COMPV63_32 0x24 /* Comparator higher 32 bit reg */ +#define PIV31_0 0x28 /* Periodic Interval lower 32 bit reg */ +#define PIV63_32 0x2c /* Periodic Interval higher 32 bit reg */ +#define TCV31_0 0x30 /* Time Capture lower 32 bit reg */ +#define TCV63_32 0x34 /* Time Capture higher 32 bit reg */ +#define ECCV31_0 0x38 /* Event Counter Capture lower 32 bit reg */ +#define ECCV63_32 0x3c /* Event Counter Capture higher 32 bit reg */ +#define EC31_0 0x40 /* Event Counter lower 32 bit reg */ +#define EC63_32 0x44 /* Event Counter higher 32 bit reg */ +#define REGSET_SIZE 0x100 /* Difference between 0 and 1 */ +#define UINT32_MASK 0xFFFFFFFF /* 32 bit Mask */ +#define UINT32_SIZE 32 + +/* Control Register */ +#define CTL_EN BIT(0) /* Control enable */ +#define CTL_DIR BIT(1) /* Control disable */ +#define CTL_EP GENMASK(3, 2) /* Recerved polarity */ +#define CTL_EP_RISING_EDGE (0 << 2) /* Rising edge */ +#define CTL_EP_FALLING_EDGE (1 << 2) /* Falling edge */ +#define CTL_EP_TOGGLE_EDGE (2 << 2) /* Toggle edge */ +#define CTL_PM BIT(4) /* Periodic mode */ + +/* Macro to get configuration data, required by DEVICE_MMIO_NAMED_* in init */ +#define DEV_CFG(_dev) \ + ((const struct tgpio_config *)(_dev)->config) +/* Macro to get runtime data, required by DEVICE_MMIO_NAMED_* in init */ +#define DEV_DATA(_dev) ((struct tgpio_runtime *)(_dev)->data) +/* Macro to individual pin regbase */ +#define pin_regs(addr, pin) (addr + (pin * REGSET_SIZE)) + +struct tgpio_config { + DEVICE_MMIO_NAMED_ROM(reg_base); + uint32_t max_pins; + uint32_t art_clock_freq; +}; + +struct tgpio_runtime { + DEVICE_MMIO_NAMED_RAM(reg_base); +}; + +static mm_reg_t regs(const struct device *dev) +{ + return DEVICE_MMIO_NAMED_GET(dev, reg_base); +} + +static int tgpio_intel_get_time(const struct device *dev, + uint64_t *current_time) +{ + *current_time = sys_read32(regs(dev) + ART_L); + *current_time += ((uint64_t)sys_read32(regs(dev) + ART_H) << UINT32_SIZE); + + return 0; +} + +static int tgpio_intel_cyc_per_sec(const struct device *dev, + uint32_t *cycles) +{ + *cycles = DEV_CFG(dev)->art_clock_freq; + + return 0; +} + +static int tgpio_intel_pin_disable(const struct device *dev, + uint32_t pin) +{ + mm_reg_t addr = regs(dev); + + if (pin >= DEV_CFG(dev)->max_pins) { + return -EINVAL; + } + + addr = pin_regs(addr, pin); + sys_write32(sys_read32(addr + CTL) & ~CTL_EN, addr + CTL); + + return 0; +} + +static int tgpio_intel_periodic_output(const struct device *dev, + uint32_t pin, + uint64_t start_time, + uint64_t repeat_interval, + bool periodic_enable) +{ + mm_reg_t addr = regs(dev); + uint32_t val; + + if (pin >= DEV_CFG(dev)->max_pins) { + return -EINVAL; + } + + addr = pin_regs(addr, pin); + tgpio_intel_pin_disable(dev, pin); + + /* Configure PIV */ + val = (repeat_interval >> UINT32_SIZE) & UINT32_MASK; + sys_write32(val, addr + PIV63_32); + val = repeat_interval & UINT32_MASK; + sys_write32(val, addr + PIV31_0); + + /* Configure COMPV */ + val = (start_time >> UINT32_SIZE) & UINT32_MASK; + sys_write32(val, addr + COMPV63_32); + val = start_time & UINT32_MASK; + sys_write32(val, addr + COMPV31_0); + + val = 0; + + /* Configure Periodic Mode */ + if (periodic_enable) { + val |= CTL_PM; + } + + /* Enable the pin */ + val |= CTL_EN; + sys_write32(val, addr + CTL); + + return 0; +} + +static int tgpio_intel_config_external_timestamp(const struct device *dev, + uint32_t pin, + uint32_t event_polarity) +{ + mm_reg_t addr = regs(dev); + uint32_t val; + + if (pin >= DEV_CFG(dev)->max_pins) { + return -EINVAL; + } + + addr = pin_regs(addr, pin); + tgpio_intel_pin_disable(dev, pin); + + /* Configure interrupt polarity */ + if (event_polarity == 0) { + val = CTL_EP_RISING_EDGE; + } else if (event_polarity == 1) { + val = CTL_EP_FALLING_EDGE; + } else { + val = CTL_EP_TOGGLE_EDGE; + } + + /* Configure direction = input */ + val |= CTL_DIR; + sys_write32(val, addr + CTL); + + /* Enable the pin */ + sys_write32(sys_read32(addr + CTL) | CTL_EN, addr + CTL); + + return 0; +} + +static int tgpio_intel_read_ts_ec(const struct device *dev, + uint32_t pin, + uint64_t *timestamp, + uint64_t *event_count) +{ + if (pin >= DEV_CFG(dev)->max_pins) { + return -EINVAL; + } + + *timestamp = sys_read32(regs(dev) + TCV31_0); + *timestamp += ((uint64_t)sys_read32(regs(dev) + TCV63_32) << UINT32_SIZE); + *event_count = sys_read32(regs(dev) + ECCV31_0); + *event_count += ((uint64_t)sys_read32(regs(dev) + ECCV63_32) << UINT32_SIZE); + + return 0; +} + +static const struct tgpio_driver_api api_funcs = { + .pin_disable = tgpio_intel_pin_disable, + .get_time = tgpio_intel_get_time, + .set_perout = tgpio_intel_periodic_output, + .config_ext_ts = tgpio_intel_config_external_timestamp, + .read_ts_ec = tgpio_intel_read_ts_ec, + .cyc_per_sec = tgpio_intel_cyc_per_sec, +}; + +static int tgpio_init(const struct device *dev) +{ + const struct tgpio_config *cfg = DEV_CFG(dev); + struct tgpio_runtime *rt = DEV_DATA(dev); + + device_map(&rt->reg_base, + cfg->reg_base.phys_addr & ~0xFFU, + cfg->reg_base.size, + K_MEM_CACHE_NONE); + + return 0; +} + +#define TGPIO_INTEL_DEV_CFG_DATA(n) \ + static const struct tgpio_config \ + tgpio_##n##_cfg = { \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ + .max_pins = DT_INST_PROP(n, max_pins), \ + .art_clock_freq = DT_INST_PROP(n, timer_clock), \ + }; \ + \ + static struct tgpio_runtime tgpio_##n##_runtime; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &tgpio_init, \ + NULL, \ + &tgpio_##n##_runtime, \ + &tgpio_##n##_cfg, \ + POST_KERNEL, CONFIG_TIMEAWARE_GPIO_INIT_PRIORITY,\ + &api_funcs); \ + +DT_INST_FOREACH_STATUS_OKAY(TGPIO_INTEL_DEV_CFG_DATA) diff --git a/dts/bindings/misc/intel,timeaware-gpio.yaml b/dts/bindings/misc/intel,timeaware-gpio.yaml new file mode 100644 index 00000000000..149e95bbb6a --- /dev/null +++ b/dts/bindings/misc/intel,timeaware-gpio.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Intel TGPIO node + +compatible: "intel,timeaware-gpio" + +include: [base.yaml] + +properties: + reg: + required: true + + timer-clock: + type: int + required: true + description: ART timer clock frequency + + max-pins: + type: int + required: true + description: Total number of available pins From ea2094e6362198aff92f55bd92b5da14ecdc3f89 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Wed, 28 Jun 2023 18:51:21 +0530 Subject: [PATCH 1439/4498] dts: x86: raptor_lake: Added timeaware gpio instance Added timeaware gpio instance in raptorlake dtsi Signed-off-by: Anisetti Avinash Krishna --- dts/x86/intel/raptor_lake.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index d7f9517dda9..c479d54dd9e 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -584,6 +584,14 @@ status = "okay"; }; + tgpio: tgpio@fe001200 { + compatible = "intel,timeaware-gpio"; + reg = <0xfe001200 0x100>; + timer-clock = <19200000>; + max-pins = <2>; + status = "okay"; + }; + hpet: hpet@fed00000 { compatible = "intel,hpet"; reg = <0xfed00000 0x400>; From 0ed8d9044426c98c96011f7421519e3c13955c03 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Mon, 31 Jul 2023 23:23:53 +0530 Subject: [PATCH 1440/4498] samples: drivers: misc: Added sample application for timeaware-gpio Added sample application for timeaware-gpio uasge. Signed-off-by: Anisetti Avinash Krishna --- .../misc/timeaware_gpio/CMakeLists.txt | 8 ++ .../drivers/misc/timeaware_gpio/README.rst | 52 +++++++++++++ samples/drivers/misc/timeaware_gpio/prj.conf | 2 + .../drivers/misc/timeaware_gpio/sample.yaml | 7 ++ .../drivers/misc/timeaware_gpio/src/main.c | 73 +++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 samples/drivers/misc/timeaware_gpio/CMakeLists.txt create mode 100644 samples/drivers/misc/timeaware_gpio/README.rst create mode 100644 samples/drivers/misc/timeaware_gpio/prj.conf create mode 100644 samples/drivers/misc/timeaware_gpio/sample.yaml create mode 100644 samples/drivers/misc/timeaware_gpio/src/main.c diff --git a/samples/drivers/misc/timeaware_gpio/CMakeLists.txt b/samples/drivers/misc/timeaware_gpio/CMakeLists.txt new file mode 100644 index 00000000000..2705cd84c08 --- /dev/null +++ b/samples/drivers/misc/timeaware_gpio/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(timeaware_gpio) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/misc/timeaware_gpio/README.rst b/samples/drivers/misc/timeaware_gpio/README.rst new file mode 100644 index 00000000000..fc242f9dba8 --- /dev/null +++ b/samples/drivers/misc/timeaware_gpio/README.rst @@ -0,0 +1,52 @@ +.. zephyr:code-sample:: timeaware-gpio + :name: Time-aware GPIO + :relevant-api: tgpio_interface + + Synchronize clocks. + +Overview +******** + +A sample application that can be used with any supported boards. eg. RPL. +prints configuration info to the console. Below functionalities are tested: + +1. Periodic pulse generation (an Oscilloscope or loopback may be required) +2. Input pulse timestamping (a pulse generator or loopback may be required) + +Building and Running +******************** + +This application can be built and executed as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/misc/timeaware_gpio + :board: intel_rpl_crb + :host-os: unix + :goals: build + + +To build for another supported board, change "intel_rpl_crb" to that board's +name (if supported). + +Sample Output +============= + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.4.0-4166-g52b34a310c67 *** + [TGPIO] Bind Success + [TGPIO] Time now: 00000001477ed72f + [TGPIO] Running rate: 19200000 + [TGPIO] Periodic pulses start at: 0000000148a3cf2f + [TGPIO] timestamp: 0000000000000000, event count: 0000000000000000 + [TGPIO] timestamp: 0000000148a3cf31, event count: 0000000000000001 + [TGPIO] timestamp: 0000000149c8c731, event count: 0000000000000002 + [TGPIO] timestamp: 000000014aedbf31, event count: 0000000000000003 + [TGPIO] timestamp: 000000014c12b731, event count: 0000000000000004 + [TGPIO] timestamp: 000000014d37af31, event count: 0000000000000005 + [TGPIO] timestamp: 000000014e5ca731, event count: 0000000000000006 + [TGPIO] timestamp: 000000014f819f31, event count: 0000000000000007 + [TGPIO] timestamp: 0000000150a69731, event count: 0000000000000008 + [TGPIO] timestamp: 0000000151cb8f31, event count: 0000000000000009 + [TGPIO] timestamp: 0000000152f08731, event count: 000000000000000a + [TGPIO] timestamp: 0000000154157f31, event count: 000000000000000b diff --git a/samples/drivers/misc/timeaware_gpio/prj.conf b/samples/drivers/misc/timeaware_gpio/prj.conf new file mode 100644 index 00000000000..5bc0e68bd3c --- /dev/null +++ b/samples/drivers/misc/timeaware_gpio/prj.conf @@ -0,0 +1,2 @@ +# nothing here +CONFIG_TIMEAWARE_GPIO=y diff --git a/samples/drivers/misc/timeaware_gpio/sample.yaml b/samples/drivers/misc/timeaware_gpio/sample.yaml new file mode 100644 index 00000000000..4af9b14640a --- /dev/null +++ b/samples/drivers/misc/timeaware_gpio/sample.yaml @@ -0,0 +1,7 @@ +sample: + name: timeaware_gpio +tests: + sample.drivers.misc.timeaware_gpio: + tags: + - drivers + filter: dt_compat_enabled("intel,timeaware-gpio") diff --git a/samples/drivers/misc/timeaware_gpio/src/main.c b/samples/drivers/misc/timeaware_gpio/src/main.c new file mode 100644 index 00000000000..f205368124a --- /dev/null +++ b/samples/drivers/misc/timeaware_gpio/src/main.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Sample application for timeaware GPIO. + * This example demonstrates the following + * a. How to generate pulses based on ART time on an output pin + * b. How to timestamp a pulse on an input pin + */ + +/* Local Includes */ +#include +#include +#include +#include +#include +#include + +#define TGPIO_LABEL DT_NODELABEL(tgpio) +#define TGPIO_PIN_IN 0 +#define TGPIO_PIN_OUT 1 + +int main(void) +{ + const struct device *tgpio_dev; + uint64_t tm, ts, ec, ret; + uint32_t cycles; + + /* Get the device handle for Timeaware-GPIO instance */ + tgpio_dev = DEVICE_DT_GET(TGPIO_LABEL); + if (!device_is_ready(tgpio_dev)) { + printk("[TGPIO] Bind failed\n"); + return -EINVAL; + } + + printk("[TGPIO] Bind Success\n"); + + tgpio_port_get_time(tgpio_dev, &tm); + printk("[TGPIO] Time now: %016llx\n", tm); + + tgpio_port_get_cycles_per_second(tgpio_dev, &cycles); + printk("[TGPIO] Running rate: %d\n", cycles); + + /* Configure start time of first pulse, time has to be in future */ + tm += cycles; + printk("[TGPIO] Periodic pulses start at: %016llx\n", tm); + + ret = tgpio_pin_periodic_output(tgpio_dev, TGPIO_PIN_OUT, + tm, cycles, true); + if (ret) { + printk("[TGPIO] periodic output configuration failed\n"); + return -EINVAL; + } + + /* Configure external timestamp for input pulses */ + ret = tgpio_pin_config_ext_timestamp(tgpio_dev, TGPIO_PIN_IN, 0); + if (ret) { + printk("[TGPIO] external timestamp configuration failed\n"); + return -EINVAL; + } + + while (1) { + /* Read timestamp and event counter values */ + tgpio_pin_read_ts_ec(tgpio_dev, TGPIO_PIN_IN, &ts, &ec); + printk("[TGPIO] timestamp: %016llx, event count: %016llx\n", ts, ec); + k_sleep(K_MSEC(500)); + } + return 0; +} From db70b8ed11e9492d743458c8c0f71997ee30f348 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Wed, 27 Sep 2023 17:43:04 +0530 Subject: [PATCH 1441/4498] doc: hardware: peripherals: Added tgpio.rst Added tgpio.rst file for documentation generation. Signed-off-by: Anisetti Avinash Krishna --- doc/hardware/peripherals/index.rst | 1 + doc/hardware/peripherals/tgpio.rst | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 doc/hardware/peripherals/tgpio.rst diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 6de39a8a7b2..48e8baa97b9 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -56,5 +56,6 @@ Peripherals uart.rst usbc_vbus.rst tcpc.rst + tgpio.rst video.rst watchdog.rst diff --git a/doc/hardware/peripherals/tgpio.rst b/doc/hardware/peripherals/tgpio.rst new file mode 100644 index 00000000000..460468693c5 --- /dev/null +++ b/doc/hardware/peripherals/tgpio.rst @@ -0,0 +1,20 @@ +.. _tgpio_api: + + +Time-aware General-Purpose Input/Output (TGPIO) +############################################### + +Overview +******** + +Configuration Options +********************* + +Related configuration options: + +* :kconfig:option:`CONFIG_TIMEAWARE_GPIO` + +API Reference +************* + +.. doxygengroup:: tgpio_interface From d2af54fc02b60e0f9a6ee8eef400ce1b04845410 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Wed, 27 Sep 2023 17:45:43 +0530 Subject: [PATCH 1442/4498] doc: devlop: api: Added TGPIO api overview Added TGPIO API overview as experimental. Signed-off-by: Anisetti Avinash Krishna --- doc/develop/api/overview.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 5e0ae969d87..3e64fd94016 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -329,6 +329,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Experimental - 3.1 + * - :ref:`tgpio_api` + - Experimental + - 3.5 + * - :ref:`uart_api` - Stable - 1.0 From 12fa5340899d139eac56d5cfeb080616837fff8c Mon Sep 17 00:00:00 2001 From: Kelly Helmut Lord Date: Wed, 19 Jul 2023 14:40:16 -0400 Subject: [PATCH 1443/4498] drivers: flash: shell: adjusted load command prompt Adjusted the prompt of the load command to make it more obvious that the user is being prompted for keyboard input. Signed-off-by: Kelly Helmut Lord --- drivers/flash/flash_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index e953b2edd1a..015bbbe9915 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -663,7 +663,7 @@ static int cmd_load(const struct shell *sh, size_t argc, char *argv[]) flash_load_boff = 0; flash_load_chunk = 0; - shell_print(sh, "Loading %d bytes starting at address %x", size, addr); + shell_print(sh, "Send %d bytes to complete flash load command", size); set_bypass(sh, bypass_cb); return 0; From c5094776e9ddbc0ca6bf966c732518ed0258563e Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Thu, 3 Aug 2023 14:36:14 +0530 Subject: [PATCH 1444/4498] sd: add check for maximum supported voltage by host controller add check for maximum voltage supported by hc before apply card voltage. Signed-off-by: Najumon B.A --- subsys/sd/sd.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/subsys/sd/sd.c b/subsys/sd/sd.c index ca00c8bcca4..87ec7a29910 100644 --- a/subsys/sd/sd.c +++ b/subsys/sd/sd.c @@ -117,7 +117,8 @@ static int sd_common_init(struct sd_card *card) static int sd_init_io(struct sd_card *card) { struct sdhc_io *bus_io = &card->bus_io; - int ret; + struct sdhc_host_props *host_props = &card->host_props; + int ret, voltage; /* SD clock should start gated */ bus_io->clock = 0; @@ -125,9 +126,22 @@ static int sd_init_io(struct sd_card *card) bus_io->bus_mode = SDHC_BUSMODE_PUSHPULL; bus_io->power_mode = SDHC_POWER_ON; bus_io->bus_width = SDHC_BUS_WIDTH1BIT; - /* Cards start with legacy timing and 3.3V signalling at power on */ + /* Cards start with legacy timing and Maximum voltage Host controller support */ bus_io->timing = SDHC_TIMING_LEGACY; - bus_io->signal_voltage = SD_VOL_3_3_V; + + if (host_props->host_caps.vol_330_support) { + LOG_DBG("Host controller support 3.3V max"); + voltage = SD_VOL_3_3_V; + } else if (host_props->host_caps.vol_300_support) { + LOG_DBG("Host controller support 3.0V max"); + voltage = SD_VOL_3_0_V; + } else { + LOG_DBG("Host controller support 1.8V max"); + voltage = SD_VOL_1_8_V; + } + + /* Set to maximum voltage support by Host controller */ + bus_io->signal_voltage = voltage; /* Toggle power to card to reset it */ LOG_DBG("Resetting power to card"); @@ -144,8 +158,8 @@ static int sd_init_io(struct sd_card *card) LOG_ERR("Could not disable card power via SDHC"); return ret; } - /* After reset or init, card voltage should be 3.3V */ - card->card_voltage = SD_VOL_3_3_V; + /* After reset or init, card voltage should be max HC support */ + card->card_voltage = voltage; /* Reset card flags */ card->flags = 0U; /* Delay so card can power up */ From a14bc241c07222204ef11be79a1a7c50a6aaa82d Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Thu, 3 Aug 2023 14:46:54 +0530 Subject: [PATCH 1445/4498] drivers: sdhc: add driver support for emmc host controller add host controller driver support for emmc version 5.1. The driver expose zephyr sdhc api interface for emmc host controller. Signed-off-by: Najumon B.A --- drivers/sdhc/CMakeLists.txt | 2 +- drivers/sdhc/Kconfig | 2 +- drivers/sdhc/Kconfig.intel | 58 + drivers/sdhc/intel_emmc_host.c | 1348 ++++++++++++++++++++++++ drivers/sdhc/intel_emmc_host.h | 303 ++++++ dts/bindings/sdhc/intel,emmc-host.yaml | 8 + 6 files changed, 1719 insertions(+), 2 deletions(-) create mode 100644 drivers/sdhc/Kconfig.intel create mode 100644 drivers/sdhc/intel_emmc_host.c create mode 100644 drivers/sdhc/intel_emmc_host.h create mode 100644 dts/bindings/sdhc/intel,emmc-host.yaml diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index b6563382a82..a43e3f54806 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -7,5 +7,5 @@ zephyr_library_sources_ifdef(CONFIG_IMX_USDHC imx_usdhc.c) zephyr_library_sources_ifdef(CONFIG_SPI_SDHC sdhc_spi.c) zephyr_library_sources_ifdef(CONFIG_MCUX_SDIF mcux_sdif.c) zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) - +zephyr_library_sources_ifdef(CONFIG_INTEL_EMMC_HOST intel_emmc_host.c) endif() diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index 5a1c7d6c95f..69a942238e4 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -12,6 +12,7 @@ source "drivers/sdhc/Kconfig.imx" source "drivers/sdhc/Kconfig.spi" source "drivers/sdhc/Kconfig.mcux_sdif" source "drivers/sdhc/Kconfig.sam_hsmci" +source "drivers/sdhc/Kconfig.intel" config SDHC_INIT_PRIORITY int "SDHC driver init priority" @@ -50,5 +51,4 @@ module = SDHC module-str = sdhc source "subsys/logging/Kconfig.template.log_config" - endif # SDHC diff --git a/drivers/sdhc/Kconfig.intel b/drivers/sdhc/Kconfig.intel new file mode 100644 index 00000000000..cebcfb066bf --- /dev/null +++ b/drivers/sdhc/Kconfig.intel @@ -0,0 +1,58 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config INTEL_EMMC_HOST + bool "EMMC driver" + select SDHC_SUPPORTS_NATIVE_MODE + select EVENTS + default y + depends on DT_HAS_INTEL_EMMC_HOST_ENABLED + help + EMMC driver support. Though this driver can be easily port to + any HW which is complaint to eMMC spec, currently it is only + validated using intel's EMMC host controller. + +if INTEL_EMMC_HOST +config INTEL_EMMC_HOST_INTR + bool "EMMC host controller interrupt mode" + default y + help + EMMC host controller interrupt mode support. + +config INTEL_EMMC_HOST_DMA + bool "EMMC host controller DMA mode" + select DCACHE + help + EMMC host controller DMA mode support. + +config INTEL_EMMC_HOST_ADMA + bool "EMMC host controller ADMA mode" + depends on INTEL_EMMC_HOST_DMA + help + EMMC host controller ADMA mode support. + +config INTEL_EMMC_HOST_ADMA_DESC_SIZE + int "EMMC host controller ADMA Descriptor size" + depends on INTEL_EMMC_HOST_ADMA + default 32 + help + EMMC host controller ADMA Descriptor size. + +config INTEL_EMMC_HOST_AUTO_STOP + bool "auto stop command mode" + default y + help + Auto stop command mode support. + +config INTEL_EMMC_HOST_BLOCK_GAP + bool "Block gap mode" + depends on INTEL_EMMC_HOST_DMA + help + Block gap mode support. + +config INTEL_EMMC_HOST_TUNING + bool "Host tuning" + help + Host tuning support. + +endif diff --git a/drivers/sdhc/intel_emmc_host.c b/drivers/sdhc/intel_emmc_host.c new file mode 100644 index 00000000000..ec5c7934be1 --- /dev/null +++ b/drivers/sdhc/intel_emmc_host.c @@ -0,0 +1,1348 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_emmc_host + +#include +#include +#include +#include +#include +#include "intel_emmc_host.h" +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) +BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "DT need CONFIG_PCIE"); +#include +#endif + +#include +LOG_MODULE_REGISTER(emmc_hc, CONFIG_SDHC_LOG_LEVEL); + +typedef void (*emmc_isr_cb_t)(const struct device *dev); + +#ifdef CONFIG_INTEL_EMMC_HOST_ADMA_DESC_SIZE +#define ADMA_DESC_SIZE CONFIG_INTEL_EMMC_HOST_ADMA_DESC_SIZE +#else +#define ADMA_DESC_SIZE 0 +#endif + +struct emmc_config { +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) + struct pcie_dev *pcie; +#else + DEVICE_MMIO_ROM; +#endif + emmc_isr_cb_t config_func; + uint32_t max_bus_freq; + uint32_t min_bus_freq; + uint32_t power_delay_ms; + uint8_t hs200_mode: 1; + uint8_t hs400_mode: 1; + uint8_t dw_4bit: 1; + uint8_t dw_8bit: 1; +}; + +struct emmc_data { + DEVICE_MMIO_RAM; + uint32_t rca; + struct sdhc_io host_io; + struct k_sem lock; + struct k_event irq_event; + uint64_t desc_table[ADMA_DESC_SIZE]; + struct sdhc_host_props props; + bool card_present; +}; + +static void enable_interrupts(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + regs->normal_int_stat_en = EMMC_HOST_NORMAL_INTR_MASK; + regs->err_int_stat_en = EMMC_HOST_ERROR_INTR_MASK; + regs->normal_int_signal_en = EMMC_HOST_NORMAL_INTR_MASK; + regs->err_int_signal_en = EMMC_HOST_ERROR_INTR_MASK; + regs->timeout_ctrl = EMMC_HOST_MAX_TIMEOUT; +} + +static void disable_interrupts(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + /* Keep enable interrupt status register to update */ + regs->normal_int_stat_en = EMMC_HOST_NORMAL_INTR_MASK; + regs->err_int_stat_en = EMMC_HOST_ERROR_INTR_MASK; + + /* Disable only interrupt generation */ + regs->normal_int_signal_en &= 0; + regs->err_int_signal_en &= 0; + regs->timeout_ctrl = EMMC_HOST_MAX_TIMEOUT; +} + +static void clear_interrupts(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + regs->normal_int_stat = EMMC_HOST_NORMAL_INTR_MASK_CLR; + regs->err_int_stat = EMMC_HOST_ERROR_INTR_MASK; +} + +static int emmc_set_voltage(const struct device *dev, enum sd_voltage signal_voltage) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + bool power_state = regs->power_ctrl & EMMC_HOST_POWER_CTRL_SD_BUS_POWER ? true : false; + int ret = 0; + + if (power_state) { + /* Turn OFF Bus Power before config clock */ + regs->power_ctrl &= ~EMMC_HOST_POWER_CTRL_SD_BUS_POWER; + } + + switch (signal_voltage) { + case SD_VOL_3_3_V: + if (regs->capabilities & EMMC_HOST_VOL_3_3_V_SUPPORT) { + regs->host_ctrl2 &= + ~(EMMC_HOST_CTRL2_1P8V_SIG_EN << EMMC_HOST_CTRL2_1P8V_SIG_LOC); + + /* 3.3v voltage select */ + regs->power_ctrl = EMMC_HOST_VOL_3_3_V_SELECT; + LOG_DBG("3.3V Selected for MMC Card"); + } else { + LOG_ERR("3.3V not supported by MMC Host"); + ret = -ENOTSUP; + } + break; + + case SD_VOL_3_0_V: + if (regs->capabilities & EMMC_HOST_VOL_3_0_V_SUPPORT) { + regs->host_ctrl2 &= + ~(EMMC_HOST_CTRL2_1P8V_SIG_EN << EMMC_HOST_CTRL2_1P8V_SIG_LOC); + + /* 3.0v voltage select */ + regs->power_ctrl = EMMC_HOST_VOL_3_0_V_SELECT; + LOG_DBG("3.0V Selected for MMC Card"); + } else { + LOG_ERR("3.0V not supported by MMC Host"); + ret = -ENOTSUP; + } + break; + + case SD_VOL_1_8_V: + if (regs->capabilities & EMMC_HOST_VOL_1_8_V_SUPPORT) { + regs->host_ctrl2 |= EMMC_HOST_CTRL2_1P8V_SIG_EN + << EMMC_HOST_CTRL2_1P8V_SIG_LOC; + + /* 1.8v voltage select */ + regs->power_ctrl = EMMC_HOST_VOL_1_8_V_SELECT; + LOG_DBG("1.8V Selected for MMC Card"); + } else { + LOG_ERR("1.8V not supported by MMC Host"); + ret = -ENOTSUP; + } + break; + + default: + ret = -EINVAL; + } + + if (power_state) { + /* Turn ON Bus Power */ + regs->power_ctrl |= EMMC_HOST_POWER_CTRL_SD_BUS_POWER; + } + + return ret; +} + +static int emmc_set_power(const struct device *dev, enum sdhc_power state) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + if (state == SDHC_POWER_ON) { + /* Turn ON Bus Power */ + regs->power_ctrl |= EMMC_HOST_POWER_CTRL_SD_BUS_POWER; + } else { + /* Turn OFF Bus Power */ + regs->power_ctrl &= ~EMMC_HOST_POWER_CTRL_SD_BUS_POWER; + } + + k_msleep(10u); + + return 0; +} + +static bool emmc_disable_clock(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + if (regs->present_state & EMMC_HOST_PSTATE_CMD_INHIBIT) { + LOG_ERR("present_state:%x", regs->present_state); + return false; + } + if (regs->present_state & EMMC_HOST_PSTATE_DAT_INHIBIT) { + LOG_ERR("present_state:%x", regs->present_state); + return false; + } + + regs->clock_ctrl &= ~EMMC_HOST_INTERNAL_CLOCK_EN; + regs->clock_ctrl &= ~EMMC_HOST_SD_CLOCK_EN; + + while ((regs->clock_ctrl & EMMC_HOST_SD_CLOCK_EN) != 0) { + ; + } + + return true; +} + +static bool emmc_enable_clock(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + regs->clock_ctrl |= EMMC_HOST_INTERNAL_CLOCK_EN; + /* Wait for the stable Internal Clock */ + while ((regs->clock_ctrl & EMMC_HOST_INTERNAL_CLOCK_STABLE) == 0) { + ; + } + + /* Enable SD Clock */ + regs->clock_ctrl |= EMMC_HOST_SD_CLOCK_EN; + while ((regs->clock_ctrl & EMMC_HOST_SD_CLOCK_EN) == 0) { + ; + } + + return true; +} + +static bool emmc_clock_set(const struct device *dev, enum sdhc_clock_speed speed) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint8_t base_freq; + uint32_t clock_divider; + float freq; + bool ret; + + switch (speed) { + case SDMMC_CLOCK_400KHZ: + freq = EMMC_HOST_CLK_FREQ_400K; + break; + + case SD_CLOCK_25MHZ: + case MMC_CLOCK_26MHZ: + freq = EMMC_HOST_CLK_FREQ_25M; + break; + + case SD_CLOCK_50MHZ: + case MMC_CLOCK_52MHZ: + freq = EMMC_HOST_CLK_FREQ_50M; + break; + + case SD_CLOCK_100MHZ: + freq = EMMC_HOST_CLK_FREQ_100M; + break; + + case MMC_CLOCK_HS200: + freq = EMMC_HOST_CLK_FREQ_200M; + break; + + case SD_CLOCK_208MHZ: + default: + return false; + } + + ret = emmc_disable_clock(dev); + if (!ret) { + return false; + } + + base_freq = regs->capabilities >> 8; + clock_divider = (int)(base_freq / (freq * 2)); + + LOG_DBG("Clock divider for MMC Clk: %d Hz is %d", speed, clock_divider); + + SET_BITS(regs->clock_ctrl, EMMC_HOST_CLK_SDCLCK_FREQ_SEL_LOC, + EMMC_HOST_CLK_SDCLCK_FREQ_SEL_MASK, clock_divider); + SET_BITS(regs->clock_ctrl, EMMC_HOST_CLK_SDCLCK_FREQ_SEL_UPPER_LOC, + EMMC_HOST_CLK_SDCLCK_FREQ_SEL_UPPER_MASK, clock_divider >> 8); + + emmc_enable_clock(dev); + + return true; +} + +static int set_timing(const struct device *dev, enum sdhc_timing_mode timing) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + int ret = 0; + uint8_t mode; + + LOG_DBG("UHS Mode: %d", timing); + + switch (timing) { + case SDHC_TIMING_LEGACY: + case SDHC_TIMING_HS: + case SDHC_TIMING_SDR12: + mode = EMMC_HOST_UHSMODE_SDR12; + break; + + case SDHC_TIMING_SDR25: + mode = EMMC_HOST_UHSMODE_SDR25; + break; + + case SDHC_TIMING_SDR50: + mode = EMMC_HOST_UHSMODE_SDR50; + break; + + case SDHC_TIMING_SDR104: + mode = EMMC_HOST_UHSMODE_SDR104; + break; + + case SDHC_TIMING_DDR50: + case SDHC_TIMING_DDR52: + mode = EMMC_HOST_UHSMODE_DDR50; + break; + + case SDHC_TIMING_HS400: + case SDHC_TIMING_HS200: + mode = EMMC_HOST_UHSMODE_HS400; + break; + + default: + ret = -ENOTSUP; + } + + if (!ret) { + if (!emmc_disable_clock(dev)) { + LOG_ERR("Disable clk failed"); + return -EIO; + } + regs->host_ctrl2 |= EMMC_HOST_CTRL2_1P8V_SIG_EN << EMMC_HOST_CTRL2_1P8V_SIG_LOC; + SET_BITS(regs->host_ctrl2, EMMC_HOST_CTRL2_UHS_MODE_SEL_LOC, + EMMC_HOST_CTRL2_UHS_MODE_SEL_MASK, mode); + + emmc_enable_clock(dev); + } + + return ret; +} + +static int wait_for_cmd_complete(struct emmc_data *emmc, uint32_t time_out) +{ + int ret; + k_timeout_t wait_time; + uint32_t events; + + if (time_out == SDHC_TIMEOUT_FOREVER) { + wait_time = K_FOREVER; + } else { + wait_time = K_MSEC(time_out); + } + + events = k_event_wait(&emmc->irq_event, + EMMC_HOST_CMD_COMPLETE | ERR_INTR_STATUS_EVENT(EMMC_HOST_ERR_STATUS), + false, wait_time); + + if (events & EMMC_HOST_CMD_COMPLETE) { + ret = 0; + } else if (events & ERR_INTR_STATUS_EVENT(EMMC_HOST_ERR_STATUS)) { + LOG_ERR("wait for cmd complete error: %x", events); + ret = -EIO; + } else { + LOG_ERR("wait for cmd complete timeout"); + ret = -EAGAIN; + } + + return ret; +} + +static int poll_cmd_complete(const struct device *dev, uint32_t time_out) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + int ret = -EAGAIN; + int32_t retry = time_out; + + while (retry > 0) { + if (regs->normal_int_stat & EMMC_HOST_CMD_COMPLETE) { + regs->normal_int_stat = EMMC_HOST_CMD_COMPLETE; + ret = 0; + break; + } + + k_busy_wait(1000u); + retry--; + } + + if (regs->err_int_stat) { + LOG_ERR("err_int_stat:%x", regs->err_int_stat); + regs->err_int_stat &= regs->err_int_stat; + ret = -EIO; + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_ADMA)) { + if (regs->adma_err_stat) { + LOG_ERR("adma error: %x", regs->adma_err_stat); + ret = -EIO; + } + } + return ret; +} + +void emmc_host_sw_reset(const struct device *dev, enum emmc_sw_reset reset) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + if (reset == EMMC_HOST_SW_RESET_DATA_LINE) { + regs->sw_reset = EMMC_HOST_SW_RESET_REG_DATA; + } else if (reset == EMMC_HOST_SW_RESET_CMD_LINE) { + regs->sw_reset = EMMC_HOST_SW_RESET_REG_CMD; + } else if (reset == EMMC_HOST_SW_RESET_ALL) { + regs->sw_reset = EMMC_HOST_SW_RESET_REG_ALL; + } + + while (regs->sw_reset != 0) { + ; + } + + k_sleep(K_MSEC(100u)); +} + +static int emmc_dma_init(const struct device *dev, struct sdhc_data *data, bool read) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + if (IS_ENABLED(CONFIG_DCACHE) && !read) { + sys_cache_data_flush_range(data->data, (data->blocks * data->block_size)); + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_ADMA)) { + uint8_t *buff = data->data; + + /* Setup DMA trasnfer using ADMA2 */ + memset(emmc->desc_table, 0, sizeof(emmc->desc_table)); + +#if defined(CONFIG_INTEL_EMMC_HOST_ADMA_DESC_SIZE) + __ASSERT_NO_MSG(data->blocks < CONFIG_INTEL_EMMC_HOST_ADMA_DESC_SIZE); +#endif + for (int i = 0; i < data->blocks; i++) { + emmc->desc_table[i] = ((uint64_t)buff) << EMMC_HOST_ADMA_BUFF_ADD_LOC; + emmc->desc_table[i] |= data->block_size << EMMC_HOST_ADMA_BUFF_LEN_LOC; + + if (i == (data->blocks - 1u)) { + emmc->desc_table[i] |= EMMC_HOST_ADMA_BUFF_LINK_LAST; + emmc->desc_table[i] |= EMMC_HOST_ADMA_INTR_EN; + emmc->desc_table[i] |= EMMC_HOST_ADMA_BUFF_LAST; + } else { + emmc->desc_table[i] |= EMMC_HOST_ADMA_BUFF_LINK_NEXT; + } + emmc->desc_table[i] |= EMMC_HOST_ADMA_BUFF_VALID; + buff += data->block_size; + LOG_DBG("desc_table:%llx", emmc->desc_table[i]); + } + + regs->adma_sys_addr1 = (uint32_t)((uintptr_t)emmc->desc_table & ADDRESS_32BIT_MASK); + regs->adma_sys_addr2 = + (uint32_t)(((uintptr_t)emmc->desc_table >> 32) & ADDRESS_32BIT_MASK); + + LOG_DBG("adma: %llx %x %p", emmc->desc_table[0], regs->adma_sys_addr1, + emmc->desc_table); + } else { + /* Setup DMA trasnfer using SDMA */ + regs->sdma_sysaddr = (uint32_t)((uintptr_t)data->data); + LOG_DBG("sdma_sysaddr: %x", regs->sdma_sysaddr); + } + return 0; +} + +static int emmc_init_xfr(const struct device *dev, struct sdhc_data *data, bool read) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint16_t multi_block = 0u; + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_DMA)) { + emmc_dma_init(dev, data, read); + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_ADMA)) { + SET_BITS(regs->host_ctrl1, EMMC_HOST_CTRL1_DMA_SEL_LOC, + EMMC_HOST_CTRL1_DMA_SEL_MASK, 2u); + } else { + SET_BITS(regs->host_ctrl1, EMMC_HOST_CTRL1_DMA_SEL_LOC, + EMMC_HOST_CTRL1_DMA_SEL_MASK, 0u); + } + + /* Set Block Size Register */ + SET_BITS(regs->block_size, EMMC_HOST_DMA_BUF_SIZE_LOC, EMMC_HOST_DMA_BUF_SIZE_MASK, + EMMC_HOST_SDMA_BOUNDARY); + SET_BITS(regs->block_size, EMMC_HOST_BLOCK_SIZE_LOC, EMMC_HOST_BLOCK_SIZE_MASK, + data->block_size); + if (data->blocks > 1) { + multi_block = 1u; + } + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_AUTO_STOP)) { + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_ADMA) && + emmc->host_io.timing == SDHC_TIMING_SDR104) { + /* Auto cmd23 only applicable for ADMA */ + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_AUTO_CMD_EN_LOC, + EMMC_HOST_XFER_AUTO_CMD_EN_MASK, multi_block ? 2 : 0); + } else { + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_AUTO_CMD_EN_LOC, + EMMC_HOST_XFER_AUTO_CMD_EN_MASK, multi_block ? 1 : 0); + } + } else { + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_AUTO_CMD_EN_LOC, + EMMC_HOST_XFER_AUTO_CMD_EN_MASK, 0); + } + + if (!IS_ENABLED(CONFIG_INTEL_EMMC_HOST_AUTO_STOP)) { + /* Set block count regitser to 0 for infinite transfer mode */ + regs->block_count = 0; + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_BLOCK_CNT_EN_LOC, + EMMC_HOST_XFER_BLOCK_CNT_EN_MASK, 0); + } else { + regs->block_count = (uint16_t)data->blocks; + /* Enable block count in transfer register */ + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_BLOCK_CNT_EN_LOC, + EMMC_HOST_XFER_BLOCK_CNT_EN_MASK, multi_block ? 1 : 0); + } + + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_MULTI_BLOCK_SEL_LOC, + EMMC_HOST_XFER_MULTI_BLOCK_SEL_MASK, multi_block); + + /* Set data transfer direction, Read = 1, Write = 0 */ + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_DATA_DIR_LOC, EMMC_HOST_XFER_DATA_DIR_MASK, + read ? 1u : 0u); + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_DMA)) { + /* Enable DMA or not */ + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_DMA_EN_LOC, EMMC_HOST_XFER_DMA_EN_MASK, + 1u); + } else { + SET_BITS(regs->transfer_mode, EMMC_HOST_XFER_DMA_EN_LOC, EMMC_HOST_XFER_DMA_EN_MASK, + 0u); + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_BLOCK_GAP)) { + /* Set an interrupt at the block gap */ + SET_BITS(regs->block_gap_ctrl, EMMC_HOST_BLOCK_GAP_LOC, EMMC_HOST_BLOCK_GAP_MASK, + 1u); + } else { + SET_BITS(regs->block_gap_ctrl, EMMC_HOST_BLOCK_GAP_LOC, EMMC_HOST_BLOCK_GAP_MASK, + 0u); + } + + /* Set data timeout time */ + regs->timeout_ctrl = data->timeout_ms; + + return 0; +} + +static int wait_xfr_intr_complete(const struct device *dev, uint32_t time_out) +{ + struct emmc_data *emmc = dev->data; + uint32_t events; + int ret; + k_timeout_t wait_time; + + LOG_DBG(""); + + if (time_out == SDHC_TIMEOUT_FOREVER) { + wait_time = K_FOREVER; + } else { + wait_time = K_MSEC(time_out); + } + + events = k_event_wait(&emmc->irq_event, + EMMC_HOST_XFER_COMPLETE | + ERR_INTR_STATUS_EVENT(EMMC_HOST_DMA_TXFR_ERR), + false, wait_time); + + if (events & EMMC_HOST_XFER_COMPLETE) { + ret = 0; + } else if (events & ERR_INTR_STATUS_EVENT(0xFFFF)) { + LOG_ERR("wait for xfer complete error: %x", events); + ret = -EIO; + } else { + LOG_ERR("wait for xfer complete timeout"); + ret = -EAGAIN; + } + + return ret; +} + +static int wait_xfr_poll_complete(const struct device *dev, uint32_t time_out) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + int ret = -EAGAIN; + int32_t retry = time_out; + + LOG_DBG(""); + + while (retry > 0) { + if (regs->normal_int_stat & EMMC_HOST_XFER_COMPLETE) { + regs->normal_int_stat |= EMMC_HOST_XFER_COMPLETE; + ret = 0; + break; + } + + k_busy_wait(EMMC_HOST_MSEC_DELAY); + retry--; + } + + return ret; +} + +static int wait_xfr_complete(const struct device *dev, uint32_t time_out) +{ + int ret; + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + ret = wait_xfr_intr_complete(dev, time_out); + } else { + ret = wait_xfr_poll_complete(dev, time_out); + } + return ret; +} + +static enum emmc_response_type emmc_decode_resp_type(enum sd_rsp_type type) +{ + enum emmc_response_type resp_type; + + switch (type & 0xF) { + case SD_RSP_TYPE_NONE: + resp_type = EMMC_HOST_RESP_NONE; + break; + case SD_RSP_TYPE_R1: + case SD_RSP_TYPE_R3: + case SD_RSP_TYPE_R4: + case SD_RSP_TYPE_R5: + resp_type = EMMC_HOST_RESP_LEN_48; + break; + case SD_RSP_TYPE_R1b: + resp_type = EMMC_HOST_RESP_LEN_48B; + break; + case SD_RSP_TYPE_R2: + resp_type = EMMC_HOST_RESP_LEN_136; + break; + + case SD_RSP_TYPE_R5b: + case SD_RSP_TYPE_R6: + case SD_RSP_TYPE_R7: + default: + resp_type = EMMC_HOST_INVAL_HOST_RESP_LEN; + } + + return resp_type; +} + +static void update_cmd_response(const struct device *dev, struct sdhc_command *sdhc_cmd) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint32_t resp0, resp1, resp2, resp3; + + if (sdhc_cmd->response_type == SD_RSP_TYPE_NONE) { + return; + } + + resp0 = regs->resp_01; + + if (sdhc_cmd->response_type == SD_RSP_TYPE_R2) { + resp1 = regs->resp_2 | (regs->resp_3 << 16u); + resp2 = regs->resp_4 | (regs->resp_5 << 16u); + resp3 = regs->resp_6 | (regs->resp_7 << 16u); + + LOG_DBG("cmd resp: %x %x %x %x", resp0, resp1, resp2, resp3); + + sdhc_cmd->response[0u] = resp3; + sdhc_cmd->response[1U] = resp2; + sdhc_cmd->response[2U] = resp1; + sdhc_cmd->response[3U] = resp0; + } else { + LOG_DBG("cmd resp: %x", resp0); + sdhc_cmd->response[0u] = resp0; + } +} + +static int emmc_host_send_cmd(const struct device *dev, const struct emmc_cmd_config *config) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + struct emmc_data *emmc = dev->data; + struct sdhc_command *sdhc_cmd = config->sdhc_cmd; + enum emmc_response_type resp_type = emmc_decode_resp_type(sdhc_cmd->response_type); + uint16_t cmd_reg; + int ret; + + LOG_DBG(""); + + /* Check if CMD line is available */ + if (regs->present_state & EMMC_HOST_PSTATE_CMD_INHIBIT) { + LOG_ERR("CMD line is not available"); + return -EBUSY; + } + + if (config->data_present && (regs->present_state & EMMC_HOST_PSTATE_DAT_INHIBIT)) { + LOG_ERR("Data line is not available"); + return -EBUSY; + } + + if (resp_type == EMMC_HOST_INVAL_HOST_RESP_LEN) { + LOG_ERR("Invalid eMMC resp type:%d", resp_type); + return -EINVAL; + } + + k_event_clear(&emmc->irq_event, EMMC_HOST_CMD_COMPLETE); + + regs->argument = sdhc_cmd->arg; + + cmd_reg = config->cmd_idx << EMMC_HOST_CMD_INDEX_LOC | + config->cmd_type << EMMC_HOST_CMD_TYPE_LOC | + config->data_present << EMMC_HOST_CMD_DATA_PRESENT_LOC | + config->idx_check_en << EMMC_HOST_CMD_IDX_CHECK_EN_LOC | + config->crc_check_en << EMMC_HOST_CMD_CRC_CHECK_EN_LOC | + resp_type << EMMC_HOST_CMD_RESP_TYPE_LOC; + regs->cmd = cmd_reg; + + LOG_DBG("CMD REG:%x %x", cmd_reg, regs->cmd); + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + ret = wait_for_cmd_complete(emmc, sdhc_cmd->timeout_ms); + } else { + ret = poll_cmd_complete(dev, sdhc_cmd->timeout_ms); + } + if (ret) { + LOG_ERR("Error on send cmd: %d, status:%d", config->cmd_idx, ret); + return ret; + } + + update_cmd_response(dev, sdhc_cmd); + + return 0; +} + +static int emmc_stop_transfer(const struct device *dev) +{ + struct emmc_data *emmc = dev->data; + struct sdhc_command hdc_cmd = {0}; + struct emmc_cmd_config cmd; + + hdc_cmd.arg = emmc->rca << EMMC_HOST_RCA_SHIFT; + hdc_cmd.response_type = SD_RSP_TYPE_R1; + hdc_cmd.timeout_ms = 1000; + + cmd.sdhc_cmd = &hdc_cmd; + cmd.cmd_idx = SD_STOP_TRANSMISSION; + cmd.cmd_type = EMMC_HOST_CMD_NORMAL; + cmd.data_present = false; + cmd.idx_check_en = false; + cmd.crc_check_en = false; + + return emmc_host_send_cmd(dev, &cmd); +} + +static int emmc_reset(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + LOG_DBG(""); + + if (!(regs->present_state & EMMC_HOST_PSTATE_CARD_INSERTED)) { + LOG_ERR("No EMMC card found"); + return -ENODEV; + } + + /* Reset device to idle state */ + emmc_host_sw_reset(dev, EMMC_HOST_SW_RESET_ALL); + + clear_interrupts(dev); + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + enable_interrupts(dev); + } else { + disable_interrupts(dev); + } + + return 0; +} + +static int read_data_port(const struct device *dev, struct sdhc_data *sdhc) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint32_t block_size = sdhc->block_size; + uint32_t i, block_cnt = sdhc->blocks; + uint32_t *data = (uint32_t *)sdhc->data; + k_timeout_t wait_time; + + if (sdhc->timeout_ms == SDHC_TIMEOUT_FOREVER) { + wait_time = K_FOREVER; + } else { + wait_time = K_MSEC(sdhc->timeout_ms); + } + + LOG_DBG(""); + + while (block_cnt--) { + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + uint32_t events; + + events = k_event_wait(&emmc->irq_event, EMMC_HOST_BUF_RD_READY, false, + wait_time); + k_event_clear(&emmc->irq_event, EMMC_HOST_BUF_RD_READY); + if (!(events & EMMC_HOST_BUF_RD_READY)) { + LOG_ERR("time out on EMMC_HOST_BUF_RD_READY:%d", + (sdhc->blocks - block_cnt)); + return -EIO; + } + } else { + while ((regs->present_state & EMMC_HOST_PSTATE_BUF_READ_EN) == 0) { + ; + } + } + + if (regs->present_state & EMMC_HOST_PSTATE_DAT_INHIBIT) { + for (i = block_size >> 2u; i != 0u; i--) { + *data = regs->data_port; + data++; + } + } + } + + return wait_xfr_complete(dev, sdhc->timeout_ms); +} + +static int write_data_port(const struct device *dev, struct sdhc_data *sdhc) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint32_t block_size = sdhc->block_size; + uint32_t i, block_cnt = sdhc->blocks; + uint32_t *data = (uint32_t *)sdhc->data; + k_timeout_t wait_time; + + if (sdhc->timeout_ms == SDHC_TIMEOUT_FOREVER) { + wait_time = K_FOREVER; + } else { + wait_time = K_MSEC(sdhc->timeout_ms); + } + + LOG_DBG(""); + + while ((regs->present_state & EMMC_HOST_PSTATE_BUF_WRITE_EN) == 0) { + ; + } + + while (1) { + uint32_t events; + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + k_event_clear(&emmc->irq_event, EMMC_HOST_BUF_WR_READY); + } + + if (regs->present_state & EMMC_HOST_PSTATE_DAT_INHIBIT) { + for (i = block_size >> 2u; i != 0u; i--) { + regs->data_port = *data; + data++; + } + } + + LOG_DBG("EMMC_HOST_BUF_WR_READY"); + + if (!(--block_cnt)) { + break; + } + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + events = k_event_wait(&emmc->irq_event, EMMC_HOST_BUF_WR_READY, false, + wait_time); + k_event_clear(&emmc->irq_event, EMMC_HOST_BUF_WR_READY); + + if (!(events & EMMC_HOST_BUF_WR_READY)) { + LOG_ERR("time out on EMMC_HOST_BUF_WR_READY"); + return -EIO; + } + } else { + while ((regs->present_state & EMMC_HOST_PSTATE_BUF_WRITE_EN) == 0) { + ; + } + } + } + + return wait_xfr_complete(dev, sdhc->timeout_ms); +} + +static int emmc_send_cmd_no_data(const struct device *dev, uint32_t cmd_idx, + struct sdhc_command *cmd) +{ + struct emmc_cmd_config emmc_cmd; + + emmc_cmd.sdhc_cmd = cmd; + emmc_cmd.cmd_idx = cmd_idx; + emmc_cmd.cmd_type = EMMC_HOST_CMD_NORMAL; + emmc_cmd.data_present = false; + emmc_cmd.idx_check_en = false; + emmc_cmd.crc_check_en = false; + + return emmc_host_send_cmd(dev, &emmc_cmd); +} + +static int emmc_send_cmd_data(const struct device *dev, uint32_t cmd_idx, + struct sdhc_command *cmd, struct sdhc_data *data, bool read) +{ + struct emmc_cmd_config emmc_cmd; + int ret; + + emmc_cmd.sdhc_cmd = cmd; + emmc_cmd.cmd_idx = cmd_idx; + emmc_cmd.cmd_type = EMMC_HOST_CMD_NORMAL; + emmc_cmd.data_present = true; + emmc_cmd.idx_check_en = true; + emmc_cmd.crc_check_en = true; + + ret = emmc_init_xfr(dev, data, read); + if (ret) { + LOG_ERR("Error on init xfr"); + return ret; + } + + ret = emmc_host_send_cmd(dev, &emmc_cmd); + if (ret) { + return ret; + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_DMA)) { + ret = wait_xfr_complete(dev, data->timeout_ms); + } else { + if (read) { + ret = read_data_port(dev, data); + } else { + ret = write_data_port(dev, data); + } + } + + return ret; +} + +static int emmc_xfr(const struct device *dev, struct sdhc_command *cmd, struct sdhc_data *data, + bool read) +{ + struct emmc_data *emmc = dev->data; + int ret; + struct emmc_cmd_config emmc_cmd; + + ret = emmc_init_xfr(dev, data, read); + if (ret) { + LOG_ERR("error emmc init xfr"); + return ret; + } + emmc_cmd.sdhc_cmd = cmd; + emmc_cmd.cmd_type = EMMC_HOST_CMD_NORMAL; + emmc_cmd.data_present = true; + emmc_cmd.idx_check_en = true; + emmc_cmd.crc_check_en = true; + + k_event_clear(&emmc->irq_event, EMMC_HOST_XFER_COMPLETE); + k_event_clear(&emmc->irq_event, read ? EMMC_HOST_BUF_RD_READY : EMMC_HOST_BUF_WR_READY); + + if (data->blocks > 1) { + emmc_cmd.cmd_idx = read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK; + ret = emmc_host_send_cmd(dev, &emmc_cmd); + } else { + emmc_cmd.cmd_idx = read ? SD_READ_SINGLE_BLOCK : SD_WRITE_SINGLE_BLOCK; + ret = emmc_host_send_cmd(dev, &emmc_cmd); + } + + if (ret) { + return ret; + } + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_DMA)) { + ret = wait_xfr_complete(dev, data->timeout_ms); + } else { + if (read) { + ret = read_data_port(dev, data); + } else { + ret = write_data_port(dev, data); + } + } + + if (!IS_ENABLED(CONFIG_INTEL_EMMC_HOST_AUTO_STOP)) { + emmc_stop_transfer(dev); + } + return ret; +} + +static int emmc_request(const struct device *dev, struct sdhc_command *cmd, struct sdhc_data *data) +{ + int ret; + + LOG_DBG(""); + + if (data) { + switch (cmd->opcode) { + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + LOG_DBG("SD_WRITE_SINGLE_BLOCK"); + ret = emmc_xfr(dev, cmd, data, false); + break; + + case SD_READ_SINGLE_BLOCK: + case SD_READ_MULTIPLE_BLOCK: + LOG_DBG("SD_READ_SINGLE_BLOCK"); + ret = emmc_xfr(dev, cmd, data, true); + break; + + case MMC_SEND_EXT_CSD: + LOG_DBG("EMMC_HOST_SEND_EXT_CSD"); + ret = emmc_send_cmd_data(dev, MMC_SEND_EXT_CSD, cmd, data, true); + break; + + default: + ret = emmc_send_cmd_data(dev, cmd->opcode, cmd, data, true); + } + } else { + ret = emmc_send_cmd_no_data(dev, cmd->opcode, cmd); + } + + return ret; +} + +static int emmc_set_io(const struct device *dev, struct sdhc_io *ios) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + struct sdhc_io *host_io = &emmc->host_io; + int ret; + + LOG_DBG("emmc I/O: DW %d, Clk %d Hz, card power state %s, voltage %s", ios->bus_width, + ios->clock, ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF", + ios->signal_voltage == SD_VOL_1_8_V ? "1.8V" : "3.3V"); + + if (ios->clock && (ios->clock > emmc->props.f_max || ios->clock < emmc->props.f_min)) { + LOG_ERR("Invalid argument for clock freq: %d Support max:%d and Min:%d", ios->clock, + emmc->props.f_max, emmc->props.f_min); + return -EINVAL; + } + + /* Set HC clock */ + if (host_io->clock != ios->clock) { + LOG_DBG("Clock: %d", host_io->clock); + if (ios->clock != 0) { + /* Enable clock */ + LOG_DBG("CLOCK: %d", ios->clock); + if (!emmc_clock_set(dev, ios->clock)) { + return -ENOTSUP; + } + } else { + emmc_disable_clock(dev); + } + host_io->clock = ios->clock; + } + + /* Set data width */ + if (host_io->bus_width != ios->bus_width) { + LOG_DBG("bus_width: %d", host_io->bus_width); + + if (ios->bus_width == SDHC_BUS_WIDTH4BIT) { + SET_BITS(regs->host_ctrl1, EMMC_HOST_CTRL1_EXT_DAT_WIDTH_LOC, + EMMC_HOST_CTRL1_EXT_DAT_WIDTH_MASK, + ios->bus_width == SDHC_BUS_WIDTH8BIT ? 1 : 0); + } else { + SET_BITS(regs->host_ctrl1, EMMC_HOST_CTRL1_DAT_WIDTH_LOC, + EMMC_HOST_CTRL1_DAT_WIDTH_MASK, + ios->bus_width == SDHC_BUS_WIDTH4BIT ? 1 : 0); + } + host_io->bus_width = ios->bus_width; + } + + /* Set HC signal voltage */ + if (ios->signal_voltage != host_io->signal_voltage) { + LOG_DBG("signal_voltage: %d", ios->signal_voltage); + ret = emmc_set_voltage(dev, ios->signal_voltage); + if (ret) { + LOG_ERR("Set signal volatge failed:%d", ret); + return ret; + } + host_io->signal_voltage = ios->signal_voltage; + } + + /* Set card power */ + if (host_io->power_mode != ios->power_mode) { + LOG_DBG("power_mode: %d", ios->power_mode); + + ret = emmc_set_power(dev, ios->power_mode); + if (ret) { + LOG_ERR("Set Bus power failed:%d", ret); + return ret; + } + host_io->power_mode = ios->power_mode; + } + + /* Set I/O timing */ + if (host_io->timing != ios->timing) { + LOG_DBG("timing: %d", ios->timing); + + ret = set_timing(dev, ios->timing); + if (ret) { + LOG_ERR("Set timing failed:%d", ret); + return ret; + } + host_io->timing = ios->timing; + } + + return ret; +} + +static int emmc_get_card_present(const struct device *dev) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + LOG_DBG(""); + + emmc->card_present = (bool)((regs->present_state >> 16u) & 1u); + + if (!emmc->card_present) { + LOG_ERR("No MMC device detected"); + } + + return ((int)emmc->card_present); +} + +static int emmc_execute_tuning(const struct device *dev) +{ + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_TUNING)) { + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + LOG_DBG("Tuning starting..."); + + regs->host_ctrl2 |= EMMC_HOST_START_TUNING; + while (!(regs->host_ctrl2 & EMMC_HOST_START_TUNING)) { + ; + } + + if (regs->host_ctrl2 & EMMC_HOST_TUNING_SUCCESS) { + LOG_DBG("Tuning Completed success"); + } else { + LOG_ERR("Tuning failed"); + return -EIO; + } + } + return 0; +} + +static int emmc_card_busy(const struct device *dev) +{ + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + LOG_DBG(""); + + if (regs->present_state & 7u) { + return 1; + } + + return 0; +} + +static int emmc_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + struct emmc_data *emmc = dev->data; + const struct emmc_config *config = dev->config; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + uint64_t cap = regs->capabilities; + + LOG_DBG(""); + + memset(props, 0, sizeof(struct sdhc_host_props)); + props->f_max = config->max_bus_freq; + props->f_min = config->min_bus_freq; + props->power_delay = config->power_delay_ms; + + props->host_caps.vol_180_support = (bool)(cap & BIT(26u)); + props->host_caps.vol_300_support = (bool)(cap & BIT(25u)); + props->host_caps.vol_330_support = (bool)(bool)(cap & BIT(24u)); + props->host_caps.suspend_res_support = false; + props->host_caps.sdma_support = (bool)(cap & BIT(22u)); + props->host_caps.high_spd_support = (bool)(cap & BIT(21u)); + props->host_caps.adma_2_support = (bool)(cap & BIT(19u)); + + props->host_caps.max_blk_len = (cap >> 16u) & 0x3u; + props->host_caps.ddr50_support = (bool)(cap & BIT(34u)); + props->host_caps.sdr104_support = (bool)(cap & BIT(33u)); + props->host_caps.sdr50_support = (bool)(cap & BIT(32u)); + props->host_caps.bus_8_bit_support = true; + props->host_caps.bus_4_bit_support = true; + props->host_caps.hs200_support = (bool)config->hs200_mode; + props->host_caps.hs400_support = (bool)config->hs400_mode; + + emmc->props = *props; + + return 0; +} + +static void emmc_isr(const struct device *dev) +{ + struct emmc_data *emmc = dev->data; + volatile struct emmc_reg *regs = (struct emmc_reg *)DEVICE_MMIO_GET(dev); + + if (regs->normal_int_stat & EMMC_HOST_CMD_COMPLETE) { + regs->normal_int_stat |= EMMC_HOST_CMD_COMPLETE; + k_event_post(&emmc->irq_event, EMMC_HOST_CMD_COMPLETE); + } + + if (regs->normal_int_stat & EMMC_HOST_XFER_COMPLETE) { + regs->normal_int_stat |= EMMC_HOST_XFER_COMPLETE; + k_event_post(&emmc->irq_event, EMMC_HOST_XFER_COMPLETE); + } + + if (regs->normal_int_stat & EMMC_HOST_DMA_INTR) { + regs->normal_int_stat |= EMMC_HOST_DMA_INTR; + k_event_post(&emmc->irq_event, EMMC_HOST_DMA_INTR); + } + + if (regs->normal_int_stat & EMMC_HOST_BUF_WR_READY) { + regs->normal_int_stat |= EMMC_HOST_BUF_WR_READY; + k_event_post(&emmc->irq_event, EMMC_HOST_BUF_WR_READY); + } + + if (regs->normal_int_stat & EMMC_HOST_BUF_RD_READY) { + regs->normal_int_stat |= EMMC_HOST_BUF_RD_READY; + k_event_post(&emmc->irq_event, EMMC_HOST_BUF_RD_READY); + } + + if (regs->err_int_stat) { + LOG_ERR("err int:%x", regs->err_int_stat); + k_event_post(&emmc->irq_event, ERR_INTR_STATUS_EVENT(regs->err_int_stat)); + if (regs->err_int_stat & EMMC_HOST_DMA_TXFR_ERR) { + regs->err_int_stat |= EMMC_HOST_DMA_TXFR_ERR; + } else { + regs->err_int_stat |= regs->err_int_stat; + } + } + + if (regs->normal_int_stat) { + k_event_post(&emmc->irq_event, regs->normal_int_stat); + regs->normal_int_stat |= regs->normal_int_stat; + } + + if (regs->adma_err_stat) { + LOG_ERR("adma err:%x", regs->adma_err_stat); + } +} + +static int emmc_init(const struct device *dev) +{ + struct emmc_data *emmc = dev->data; + const struct emmc_config *config = dev->config; + + k_sem_init(&emmc->lock, 1, 1); + k_event_init(&emmc->irq_event); + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) + if (config->pcie) { + struct pcie_bar mbar; + + if (config->pcie->bdf == PCIE_BDF_NONE) { + LOG_ERR("Cannot probe eMMC PCI device: %x", config->pcie->id); + return -ENODEV; + } + + if (!pcie_probe_mbar(config->pcie->bdf, 0, &mbar)) { + LOG_ERR("eMMC MBAR not found"); + return -EINVAL; + } + + pcie_get_mbar(config->pcie->bdf, 0, &mbar); + pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_MEM, true); + device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE); + pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_MASTER, true); + } else +#endif + { + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + } + + LOG_DBG("MMC Device MMIO: %p", (void *)(struct emmc_reg *)DEVICE_MMIO_GET(dev)); + + if (IS_ENABLED(CONFIG_INTEL_EMMC_HOST_INTR)) { + config->config_func(dev); + } + return emmc_reset(dev); +} + +static const struct sdhc_driver_api emmc_api = { + .reset = emmc_reset, + .request = emmc_request, + .set_io = emmc_set_io, + .get_card_present = emmc_get_card_present, + .execute_tuning = emmc_execute_tuning, + .card_busy = emmc_card_busy, + .get_host_props = emmc_get_host_props, +}; + +#define EMMC_HOST_IRQ_FLAGS_SENSE0(n) 0 +#define EMMC_HOST_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) +#define EMMC_HOST_IRQ_FLAGS(n)\ + _CONCAT(EMMC_HOST_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + +/* Not PCI(e) */ +#define EMMC_HOST_IRQ_CONFIG_PCIE0(n) \ + static void emmc_config_##n(const struct device *port) \ + { \ + ARG_UNUSED(port); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), emmc_isr, \ + DEVICE_DT_INST_GET(n), EMMC_HOST_IRQ_FLAGS(n)); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +/* PCI(e) with auto IRQ detection */ +#define EMMC_HOST_IRQ_CONFIG_PCIE1(n) \ + static void emmc_config_##n(const struct device *port) \ + { \ + BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \ + "Only runtime IRQ configuration is supported"); \ + BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), \ + "eMMC PCI device needs CONFIG_DYNAMIC_INTERRUPTS"); \ + const struct emmc_config *const dev_cfg = port->config; \ + unsigned int irq = pcie_alloc_irq(dev_cfg->pcie->bdf); \ + \ + if (irq == PCIE_CONF_INTR_IRQ_NONE) { \ + return; \ + } \ + pcie_connect_dynamic_irq(dev_cfg->pcie->bdf, irq, DT_INST_IRQ(n, priority), \ + (void (*)(const void *))emmc_isr, DEVICE_DT_INST_GET(n), \ + EMMC_HOST_IRQ_FLAGS(n)); \ + pcie_irq_enable(dev_cfg->pcie->bdf, irq); \ + } + +#define EMMC_HOST_IRQ_CONFIG(n) _CONCAT(EMMC_HOST_IRQ_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define INIT_PCIE0(n) +#define INIT_PCIE1(n) DEVICE_PCIE_INST_INIT(n, pcie), +#define INIT_PCIE(n) _CONCAT(INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define REG_INIT_PCIE0(n) DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), +#define REG_INIT_PCIE1(n) +#define REG_INIT(n) _CONCAT(REG_INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define DEFINE_PCIE0(n) +#define DEFINE_PCIE1(n) DEVICE_PCIE_INST_DECLARE(n) +#define EMMC_HOST_PCIE_DEFINE(n) _CONCAT(DEFINE_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define EMMC_HOST_DEV_CFG(n) \ + EMMC_HOST_PCIE_DEFINE(n); \ + EMMC_HOST_IRQ_CONFIG(n); \ + static const struct emmc_config emmc_config_data_##n = { \ + REG_INIT(n) INIT_PCIE(n).config_func = emmc_config_##n, \ + .hs200_mode = DT_INST_PROP_OR(n, mmc_hs200_1_8v, 0), \ + .hs400_mode = DT_INST_PROP_OR(n, mmc_hs400_1_8v, 0), \ + .dw_4bit = DT_INST_ENUM_HAS_VALUE(n, bus_width, 4), \ + .dw_8bit = DT_INST_ENUM_HAS_VALUE(n, bus_width, 8), \ + .max_bus_freq = DT_INST_PROP_OR(n, max_bus_freq, 40000), \ + .min_bus_freq = DT_INST_PROP_OR(n, min_bus_freq, 40000), \ + .power_delay_ms = DT_INST_PROP_OR(n, power_delay_ms, 500), \ + }; \ + \ + static struct emmc_data emmc_priv_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, emmc_init, NULL, &emmc_priv_data_##n, &emmc_config_data_##n, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &emmc_api); + +DT_INST_FOREACH_STATUS_OKAY(EMMC_HOST_DEV_CFG) diff --git a/drivers/sdhc/intel_emmc_host.h b/drivers/sdhc/intel_emmc_host.h new file mode 100644 index 00000000000..7ae87359594 --- /dev/null +++ b/drivers/sdhc/intel_emmc_host.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISK_EMMC_HOST_H_ +#define ZEPHYR_DRIVERS_DISK_EMMC_HOST_H_ + +/* Bit map for command Register */ +#define EMMC_HOST_CMD_RESP_TYPE_LOC 0 +#define EMMC_HOST_CMD_CRC_CHECK_EN_LOC 3 +#define EMMC_HOST_CMD_IDX_CHECK_EN_LOC 4 +#define EMMC_HOST_CMD_DATA_PRESENT_LOC 5 +#define EMMC_HOST_CMD_TYPE_LOC 6 +#define EMMC_HOST_CMD_INDEX_LOC 8 + +/* Bit map for Transfer Mode Register */ +#define EMMC_HOST_XFER_DMA_EN_LOC 0 +#define EMMC_HOST_XFER_BLOCK_CNT_EN_LOC 1 +#define EMMC_HOST_XFER_AUTO_CMD_EN_LOC 2 +#define EMMC_HOST_XFER_DATA_DIR_LOC 4 +#define EMMC_HOST_XFER_MULTI_BLOCK_SEL_LOC 5 + +#define EMMC_HOST_XFER_DMA_EN_MASK 0x01 +#define EMMC_HOST_XFER_BLOCK_CNT_EN_MASK 0x01 +#define EMMC_HOST_XFER_AUTO_CMD_EN_MASK 0x03 +#define EMMC_HOST_XFER_DATA_DIR_MASK 0x01 +#define EMMC_HOST_XFER_MULTI_BLOCK_SEL_MASK 0x01 + +/* Bit map for Block Size and GAP Register */ +#define EMMC_HOST_BLOCK_SIZE_LOC 0 +#define EMMC_HOST_BLOCK_SIZE_MASK 0xFFF +#define EMMC_HOST_DMA_BUF_SIZE_LOC 12 +#define EMMC_HOST_DMA_BUF_SIZE_MASK 0x07 +#define EMMC_HOST_BLOCK_GAP_LOC 3 +#define EMMC_HOST_BLOCK_GAP_MASK 0x01 + +#define EMMC_HOST_ADMA_BUFF_ADD_LOC 32 +#define EMMC_HOST_ADMA_BUFF_LEN_LOC 16 +#define EMMC_HOST_ADMA_BUFF_LINK_NEXT (0x3 << 4) +#define EMMC_HOST_ADMA_BUFF_LINK_LAST (0x2 << 4) +#define EMMC_HOST_ADMA_INTR_EN BIT(2) +#define EMMC_HOST_ADMA_BUFF_LAST BIT(1) +#define EMMC_HOST_ADMA_BUFF_VALID BIT(0) + +/* Bit Map and length details for Clock Control Register */ +#define EMMC_HOST_CLK_SDCLCK_FREQ_SEL_LOC 8 +#define EMMC_HOST_CLK_SDCLCK_FREQ_SEL_UPPER_LOC 6 + +#define EMMC_HOST_CLK_SDCLCK_FREQ_SEL_MASK 0xFF +#define EMMC_HOST_CLK_SDCLCK_FREQ_SEL_UPPER_MASK 0x03 + +/* Bit Map for Host Control 1 Register */ +#define EMMC_HOST_CTRL1_DAT_WIDTH_LOC 1 +#define EMMC_HOST_CTRL1_DMA_SEL_LOC 3 +#define EMMC_HOST_CTRL1_EXT_DAT_WIDTH_LOC 5 + +#define EMMC_HOST_CTRL1_DMA_SEL_MASK 0x03 +#define EMMC_HOST_CTRL1_EXT_DAT_WIDTH_MASK 0x01 +#define EMMC_HOST_CTRL1_DAT_WIDTH_MASK 0x01 + +/** Constants Software Reset register */ +#define EMMC_HOST_SW_RESET_REG_ALL BIT(0) +#define EMMC_HOST_SW_RESET_REG_CMD BIT(1) +#define EMMC_HOST_SW_RESET_REG_DATA BIT(2) + +#define EMMC_HOST_RESPONSE_SIZE 4 +#define EMMC_HOST_OCR_BUSY_BIT BIT(31) +#define EMMC_HOST_OCR_CAPACITY_MASK 0x40000000U +#define EMMC_HOST_DUAL_VOLTAGE_RANGE 0x40FF8080U +#define EMMC_HOST_BLOCK_SIZE 512 + +#define EMMC_HOST_RCA_SHIFT 16 +#define EMMC_HOST_EXTCSD_SEC_COUNT 53 +#define EMMC_HOST_EXTCSD_GENERIC_CMD6_TIME 62 +#define EMMC_HOST_EXTCSD_BUS_WIDTH_ADDR 0xB7 +#define EMMC_HOST_EXTCSD_HS_TIMING_ADDR 0xB9 +#define EMMC_HOST_BUS_SPEED_HIGHSPEED 1 + +#define EMMC_HOST_CMD_COMPLETE_RETRY 10000 +#define EMMC_HOST_XFR_COMPLETE_RETRY 2000000 + +#define EMMC_HOST_CMD1_RETRY_TIMEOUT 1000 +#define EMMC_HOST_CMD6_TIMEOUT_MULT 10 + +#define EMMC_HOST_NORMAL_INTR_MASK 0x3f +#define EMMC_HOST_ERROR_INTR_MASK 0x13ff +#define EMMC_HOST_NORMAL_INTR_MASK_CLR 0x60ff + +#define EMMC_HOST_POWER_CTRL_SD_BUS_POWER 0x1 +#define EMMC_HOST_POWER_CTRL_SD_BUS_VOLT_SEL 0x5 + +#define EMMC_HOST_UHSMODE_SDR12 0x0 +#define EMMC_HOST_UHSMODE_SDR25 0x1 +#define EMMC_HOST_UHSMODE_SDR50 0x2 +#define EMMC_HOST_UHSMODE_SDR104 0x3 +#define EMMC_HOST_UHSMODE_DDR50 0x4 +#define EMMC_HOST_UHSMODE_HS400 0x5 + +#define EMMC_HOST_CTRL2_1P8V_SIG_EN 1 +#define EMMC_HOST_CTRL2_1P8V_SIG_LOC 3 +#define EMMC_HOST_CTRL2_UHS_MODE_SEL_LOC 0 +#define EMMC_HOST_CTRL2_UHS_MODE_SEL_MASK 0x07 + +/* Event/command status */ +#define EMMC_HOST_CMD_COMPLETE BIT(0) +#define EMMC_HOST_XFER_COMPLETE BIT(1) +#define EMMC_HOST_BLOCK_GAP_INTR BIT(2) +#define EMMC_HOST_DMA_INTR BIT(3) +#define EMMC_HOST_BUF_WR_READY BIT(4) +#define EMMC_HOST_BUF_RD_READY BIT(5) + +#define EMMC_HOST_CMD_TIMEOUT_ERR BIT(0) +#define EMMC_HOST_CMD_CRC_ERR BIT(1) +#define EMMC_HOST_CMD_END_BIT_ERR BIT(2) +#define EMMC_HOST_CMD_IDX_ERR BIT(3) +#define EMMC_HOST_DATA_TIMEOUT_ERR BIT(4) +#define EMMC_HOST_DATA_CRC_ERR BIT(5) +#define EMMC_HOST_DATA_END_BIT_ERR BIT(6) +#define EMMC_HOST_CUR_LMT_ERR BIT(7) +#define EMMC_HOST_DMA_TXFR_ERR BIT(12) +#define EMMC_HOST_ERR_STATUS 0xFFF + +/** PState register bits */ +#define EMMC_HOST_PSTATE_CMD_INHIBIT BIT(0) +#define EMMC_HOST_PSTATE_DAT_INHIBIT BIT(1) +#define EMMC_HOST_PSTATE_DAT_LINE_ACTIVE BIT(2) + +#define EMMC_HOST_PSTATE_WR_DMA_ACTIVE BIT(8) +#define EMMC_HOST_PSTATE_RD_DMA_ACTIVE BIT(9) + +#define EMMC_HOST_PSTATE_BUF_READ_EN BIT(11) +#define EMMC_HOST_PSTATE_BUF_WRITE_EN BIT(10) + +#define EMMC_HOST_PSTATE_CARD_INSERTED BIT(16) + +#define EMMC_HOST_MAX_TIMEOUT 0xe +#define EMMC_HOST_MSEC_DELAY 1000 + +/** Constants for Clock Control register */ +#define EMMC_HOST_INTERNAL_CLOCK_EN BIT(0) +#define EMMC_HOST_INTERNAL_CLOCK_STABLE BIT(1) +#define EMMC_HOST_SD_CLOCK_EN BIT(2) + +/** Clock frequency */ +#define EMMC_HOST_CLK_FREQ_400K 0.4 +#define EMMC_HOST_CLK_FREQ_25M 25 +#define EMMC_HOST_CLK_FREQ_50M 50 +#define EMMC_HOST_CLK_FREQ_100M 100 +#define EMMC_HOST_CLK_FREQ_200M 200 + +#define EMMC_HOST_TUNING_SUCCESS BIT(7) +#define EMMC_HOST_START_TUNING BIT(6) + +#define EMMC_HOST_VOL_3_3_V_SUPPORT BIT(24) +#define EMMC_HOST_VOL_3_3_V_SELECT (7 << 1) +#define EMMC_HOST_VOL_3_0_V_SUPPORT BIT(25) +#define EMMC_HOST_VOL_3_0_V_SELECT (6 << 1) +#define EMMC_HOST_VOL_1_8_V_SUPPORT BIT(26) +#define EMMC_HOST_VOL_1_8_V_SELECT (5 << 1) + +#define EMMC_HOST_CMD_WAIT_TIMEOUT_US 3000 +#define EMMC_HOST_CMD_CMPLETE_TIMEOUT_US 9000 +#define EMMC_HOST_XFR_CMPLETE_TIMEOUT_US 1000 +#define EMMC_HOST_SDMA_BOUNDARY 0x0 +#define EMMC_HOST_RCA_ADDRESS 0x2 + +#define EMMC_HOST_RESP_MASK (0xFF000000U) + +#define EMMC_HOST_SET_RESP(resp0, resp1) (resp0 >> 1) | ((resp1 & 1) << 30) + +#define SET_BITS(reg, pos, bit_width, val) \ + reg &= ~(bit_width << pos); \ + reg |= ((val & bit_width) << pos) + +/* get value from certain bit + */ +#define GET_BITS(reg_name, start, width) ((reg_name) & (((1 << (width)) - 1) << (start))) + +#define ERR_INTR_STATUS_EVENT(reg_bits) reg_bits << 16 + +#define ADDRESS_32BIT_MASK 0xFFFFFFFF + +struct emmc_reg { + volatile uint32_t sdma_sysaddr; /**< SDMA System Address */ + volatile uint16_t block_size; /**< Block Size */ + volatile uint16_t block_count; /**< Block Count */ + volatile uint32_t argument; /**< Argument */ + volatile uint16_t transfer_mode; /**< Transfer Mode */ + volatile uint16_t cmd; /**< Command */ + + volatile uint32_t resp_01; /**< Response Register 0 & 1 */ + volatile uint16_t resp_2; /**< Response Register 2*/ + volatile uint16_t resp_3; /**< Response Register 3 */ + volatile uint16_t resp_4; /**< Response Register 4 */ + volatile uint16_t resp_5; /**< Response Register 5 */ + volatile uint16_t resp_6; /**< Response Register 6 */ + volatile uint16_t resp_7; /**< Response Register 7 */ + volatile uint32_t data_port; /**< Buffer Data Port */ + volatile uint32_t present_state; /**< Present State */ + volatile uint8_t host_ctrl1; /**< Host Control 1 */ + volatile uint8_t power_ctrl; /**< Power Control */ + volatile uint8_t block_gap_ctrl; /**< Block Gap Control */ + volatile uint8_t wake_up_ctrl; /**< Wakeup Control */ + volatile uint16_t clock_ctrl; /**< Clock Control */ + volatile uint8_t timeout_ctrl; /**< Timeout Control */ + volatile uint8_t sw_reset; /**< Software Reset */ + volatile uint16_t normal_int_stat; /**< Normal Interrupt Status */ + volatile uint16_t err_int_stat; /**< Error Interrupt Status */ + volatile uint16_t normal_int_stat_en; /**< Normal Interrupt Status Enable */ + volatile uint16_t err_int_stat_en; /**< Error Interrupt Status Enable */ + volatile uint16_t normal_int_signal_en; /**< Normal Interrupt Signal Enable */ + volatile uint16_t err_int_signal_en; /**< Error Interrupt Signal Enable */ + volatile uint16_t auto_cmd_err_stat; /**< Auto CMD Error Status */ + volatile uint16_t host_ctrl2; /**< Host Control 2 */ + volatile uint64_t capabilities; /**< Capabilities */ + + volatile uint64_t max_current_cap; /**< Max Current Capabilities */ + volatile uint16_t force_err_autocmd_stat; /**< Force Event for Auto CMD Error Status*/ + volatile uint16_t force_err_int_stat; /**< Force Event for Error Interrupt Status */ + volatile uint8_t adma_err_stat; /**< ADMA Error Status */ + volatile uint8_t reserved[3]; + volatile uint32_t adma_sys_addr1; /**< ADMA System Address1 */ + volatile uint32_t adma_sys_addr2; /**< ADMA System Address2 */ + volatile uint16_t preset_val_0; /**< Preset Value 0 */ + volatile uint16_t preset_val_1; /**< Preset Value 1 */ + volatile uint16_t preset_val_2; /**< Preset Value 2 */ + volatile uint16_t preset_val_3; /**< Preset Value 3 */ + volatile uint16_t preset_val_4; /**< Preset Value 4 */ + volatile uint16_t preset_val_5; /**< Preset Value 5 */ + volatile uint16_t preset_val_6; /**< Preset Value 6 */ + volatile uint16_t preset_val_7; /**< Preset Value 7 */ + volatile uint32_t boot_timeout; /**< Boot Timeout */ + volatile uint16_t preset_val_8; /**< Preset Value 8 */ + volatile uint16_t reserved3; + volatile uint16_t vendor_reg; /**< Vendor Enhanced strobe */ + volatile uint16_t reserved4[56]; + volatile uint32_t reserved5[4]; + volatile uint16_t slot_intr_stat; /**< Slot Interrupt Status */ + volatile uint16_t host_cntrl_version; /**< Host Controller Version */ + volatile uint32_t reserved6[64]; + volatile uint32_t cq_ver; /**< Command Queue Version */ + volatile uint32_t cq_cap; /**< Command Queue Capabilities */ + volatile uint32_t cq_cfg; /**< Command Queue Configuration */ + volatile uint32_t cq_ctrl; /**< Command Queue Control */ + volatile uint32_t cq_intr_stat; /**< Command Queue Interrupt Status */ + volatile uint32_t cq_intr_stat_en; /**< Command Queue Interrupt Status Enable */ + volatile uint32_t cq_intr_sig_en; /**< Command Queue Interrupt Signal Enable */ + volatile uint32_t cq_intr_coalesc; /**< Command Queue Interrupt Coalescing */ + volatile uint32_t cq_tdlba; /**< Command Queue Task Desc List Base Addr */ + volatile uint32_t cq_tdlba_upr; /**< Command Queue Task Desc List Base Addr Upr */ + volatile uint32_t cq_task_db; /**< Command Queue Task DoorBell */ + volatile uint32_t cq_task_db_notify; /**< Command Queue Task DoorBell Notify */ + volatile uint32_t cq_dev_qstat; /**< Command Queue Device queue status */ + volatile uint32_t cq_dev_pend_task; /**< Command Queue Device pending tasks */ + volatile uint32_t cq_task_clr; /**< Command Queue Task Clr */ + volatile uint32_t reserved7; + volatile uint32_t cq_ssc1; /**< Command Queue Send Status Configuration 1 */ + volatile uint32_t cq_ssc2; /**< Command Queue Send Status Configuration 2 */ + volatile uint32_t cq_crdct; /**< Command response for direct command */ + volatile uint32_t reserved8; + volatile uint32_t cq_rmem; /**< Command response mode error mask */ + volatile uint32_t cq_terri; /**< Command Queue Task Error Information */ + volatile uint32_t cq_cri; /**< Command Queue Command response index */ + volatile uint32_t cq_cra; /**< Command Queue Command response argument */ + volatile uint32_t reserved9[425]; +}; + +enum emmc_sw_reset { + EMMC_HOST_SW_RESET_DATA_LINE = 0, + EMMC_HOST_SW_RESET_CMD_LINE, + EMMC_HOST_SW_RESET_ALL +}; + +enum emmc_cmd_type { + EMMC_HOST_CMD_NORMAL = 0, + EMMC_HOST_CMD_SUSPEND, + EMMC_HOST_CMD_RESUME, + EMMC_HOST_CMD_ABORT, +}; + +enum emmc_response_type { + EMMC_HOST_RESP_NONE = 0, + EMMC_HOST_RESP_LEN_136, + EMMC_HOST_RESP_LEN_48, + EMMC_HOST_RESP_LEN_48B, + EMMC_HOST_INVAL_HOST_RESP_LEN, +}; + +struct emmc_cmd_config { + struct sdhc_command *sdhc_cmd; + uint32_t cmd_idx; + enum emmc_cmd_type cmd_type; + bool data_present; + bool idx_check_en; + bool crc_check_en; +}; + +struct resp { + uint64_t resp_48bit; +}; +#endif /* _EMMC_HOST_HC_H_ */ diff --git a/dts/bindings/sdhc/intel,emmc-host.yaml b/dts/bindings/sdhc/intel,emmc-host.yaml new file mode 100644 index 00000000000..5464b3d5ca1 --- /dev/null +++ b/dts/bindings/sdhc/intel,emmc-host.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: eMMC host controller + +compatible: "intel,emmc-host" + +include: [sdhc.yaml, pcie-device.yaml] From dfec79c948ff4f7e83721b70a32451759e070819 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Fri, 18 Aug 2023 19:24:42 +0530 Subject: [PATCH 1446/4498] boards: x86: add eMMC support for Intel Alder lake platform add DTS entry for enable eMMC support on Intel Alder lake platforms Signed-off-by: Najumon B.A --- boards/x86/intel_adl/intel_adl.dts | 1 + dts/x86/intel/alder_lake.dtsi | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/boards/x86/intel_adl/intel_adl.dts b/boards/x86/intel_adl/intel_adl.dts index 60f53a82f40..16dfb20a556 100644 --- a/boards/x86/intel_adl/intel_adl.dts +++ b/boards/x86/intel_adl/intel_adl.dts @@ -19,5 +19,6 @@ aliases { watchdog0 = &tco_wdt; + sdhc0 = &emmc; }; }; diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index 8c1c10bea6b..5856f008f4a 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -228,6 +228,28 @@ interrupt-parent = <&intc>; status = "disabled"; }; + + emmc: emmc0 { + compatible = "intel,emmc-host"; + vendor-id = <0x8086>; + device-id = <0x54C4>; + interrupts = ; + interrupt-parent = <&intc>; + + max-bus-freq = <200000000>; + min-bus-freq = <400000>; + power-delay-ms = <500>; + mmc-hs400-1_8v; + mmc-hs200-1_8v; + + mmc { + compatible = "zephyr,mmc-disk"; + bus-width = <8>; + status = "okay"; + }; + + status = "okay"; + }; }; soc { From 4e4b743fe12266135b9e808215bb415a059b06d9 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Wed, 6 Sep 2023 16:52:16 +0200 Subject: [PATCH 1447/4498] twister: Add "path" entry to json test report "Path" is a path (relative to zephyr) to a directory with test suite's definition. Such entry helps to locate a given test. Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/reports.py | 1 + scripts/pylib/twister/twisterlib/testsuite.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index bd005d4319a..0b34a5d309b 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -258,6 +258,7 @@ def json_report(self, filename, version="NA"): "name": instance.testsuite.name, "arch": instance.platform.arch, "platform": instance.platform.name, + "path": instance.testsuite.source_dir_rel } if instance.run_id: suite['run_id'] = instance.run_id diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index bdd681699ff..71dd9b493c9 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -395,6 +395,8 @@ def __init__(self, suite_root, suite_path, name, data=None): self.id = name self.source_dir = suite_path + self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), + start=canonical_zephyr_base) self.yamlfile = suite_path self.testcases = [] From 066cc2c9d2ee86c35cb10e38bc7ba152c1560602 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 21 Jul 2023 16:09:39 +0200 Subject: [PATCH 1448/4498] twister: Add options deciding if paths be included in tests' names Test suites names are not being handled uniformly for tests not in zephyr tree. Their names depend on -T arg used in twister's CLI. The newly added options allow to select if twister should add paths to suite names. This is needed if test plans are to be used for tests outside of zephyr tree. Signed-off-by: Maciej Perkowski --- .../pylib/twister/twisterlib/environment.py | 15 +++++++ scripts/pylib/twister/twisterlib/reports.py | 10 +++-- .../pylib/twister/twisterlib/testinstance.py | 7 +++- scripts/pylib/twister/twisterlib/testplan.py | 2 +- scripts/pylib/twister/twisterlib/testsuite.py | 16 +++++--- scripts/tests/twister/test_harness.py | 1 + scripts/tests/twister/test_testsuite.py | 40 +++++++++++++++++++ 7 files changed, 81 insertions(+), 10 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index ecb5232364b..9c676ceb733 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -442,6 +442,21 @@ def add_parse_arguments(parser = None): help="Re-use the outdir before building. Will result in " "faster compilation since builds will be incremental.") + parser.add_argument( + '--detailed-test-id', action='store_true', + help="Include paths to tests' locations in tests' names. Names will follow " + "PATH_TO_TEST/SCENARIO_NAME schema " + "e.g. samples/hello_world/sample.basic.helloworld") + + parser.add_argument( + "--no-detailed-test-id", dest='detailed_test_id', action="store_false", + help="Don't put paths into tests' names. " + "With this arg a test name will be a scenario name " + "e.g. sample.basic.helloworld.") + + # Include paths in names by default. + parser.set_defaults(detailed_test_id=True) + # To be removed in favor of --detailed-skipped-report parser.add_argument( "--no-skipped-report", action="store_true", diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index 0b34a5d309b..c1f160caad9 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -420,6 +420,7 @@ def footprint_reports(self, report, show_footprint, all_deltas, def synopsis(self): cnt = 0 example_instance = None + detailed_test_id = self.env.options.detailed_test_id for instance in self.instances.values(): if instance.status not in ["passed", "filtered", "skipped"]: cnt = cnt + 1 @@ -435,11 +436,14 @@ def synopsis(self): if cnt and example_instance: logger.info("") logger.info("To rerun the tests, call twister using the following commandline:") - logger.info("west twister -p -s , for example:") + extra_parameters = '' if detailed_test_id else ' --no-detailed-test-id' + logger.info(f"west twister -p -s {extra_parameters}, for example:") logger.info("") - logger.info(f"west twister -p {example_instance.platform.name} -s {example_instance.testsuite.name}") + logger.info(f"west twister -p {example_instance.platform.name} -s {example_instance.testsuite.name}" + f"{extra_parameters}") logger.info(f"or with west:") - logger.info(f"west build -p -b {example_instance.platform.name} -T {example_instance.testsuite.name}") + logger.info(f"west build -p -b {example_instance.platform.name} " + f"{example_instance.testsuite.source_dir_rel} -T {example_instance.testsuite.id}") logger.info("-+" * 40) def summary(self, results, unrecognized_sections, duration): diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index 666a8d68d03..958019b411a 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -55,7 +55,12 @@ def __init__(self, testsuite, platform, outdir): self.name = os.path.join(platform.name, testsuite.name) self.run_id = self._get_run_id() self.dut = None - self.build_dir = os.path.join(outdir, platform.name, testsuite.name) + if testsuite.detailed_test_id: + self.build_dir = os.path.join(outdir, platform.name, testsuite.name) + else: + # if suite is not in zephyr, keep only the part after ".." in reconstructed dir structure + source_dir_rel = testsuite.source_dir_rel.rsplit(os.pardir+os.path.sep, 1)[-1] + self.build_dir = os.path.join(outdir, platform.name, source_dir_rel, testsuite.name) self.domains = None diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 6275785bdcd..905da2bc42e 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -530,7 +530,7 @@ def add_testsuites(self, testsuite_filter=[]): for name in parsed_data.scenarios.keys(): suite_dict = parsed_data.get_scenario(name) - suite = TestSuite(root, suite_path, name, data=suite_dict) + suite = TestSuite(root, suite_path, name, data=suite_dict, detailed_test_id=self.options.detailed_test_id) suite.add_subcases(suite_dict, subcases, ztest_suite_names) if testsuite_filter: if suite.name and suite.name in testsuite_filter: diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index 71dd9b493c9..ecb7c8b4000 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -370,7 +370,7 @@ class TestSuite(DisablePyTestCollectionMixin): """Class representing a test application """ - def __init__(self, suite_root, suite_path, name, data=None): + def __init__(self, suite_root, suite_path, name, data=None, detailed_test_id=True): """TestSuite constructor. This gets called by TestPlan as it finds and reads test yaml files. @@ -391,12 +391,14 @@ def __init__(self, suite_root, suite_path, name, data=None): """ workdir = os.path.relpath(suite_path, suite_root) - self.name = self.get_unique(suite_root, workdir, name) + + assert self.check_suite_name(name, suite_root, workdir) + self.detailed_test_id = detailed_test_id + self.name = self.get_unique(suite_root, workdir, name) if self.detailed_test_id else name self.id = name self.source_dir = suite_path - self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), - start=canonical_zephyr_base) + self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), start=canonical_zephyr_base) self.yamlfile = suite_path self.testcases = [] @@ -449,10 +451,14 @@ def get_unique(testsuite_root, workdir, name): # workdir can be "." unique = os.path.normpath(os.path.join(relative_ts_root, workdir, name)) + return unique + + @staticmethod + def check_suite_name(name, testsuite_root, workdir): check = name.split(".") if len(check) < 2: raise TwisterException(f"""bad test name '{name}' in {testsuite_root}/{workdir}. \ Tests should reference the category and subsystem with a dot as a separator. """ ) - return unique + return True diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index a33d6431ab4..1da2aed3f46 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -40,6 +40,7 @@ def gtest(): mock_platform.name = "mock_platform" mock_testsuite = mock.Mock() mock_testsuite.name = "mock_testsuite" + mock_testsuite.detailed_test_id = True mock_testsuite.id = "id" mock_testsuite.testcases = [] instance = TestInstance(testsuite=mock_testsuite, platform=mock_platform, outdir="") diff --git a/scripts/tests/twister/test_testsuite.py b/scripts/tests/twister/test_testsuite.py index f72330ef897..74402561fc1 100644 --- a/scripts/tests/twister/test_testsuite.py +++ b/scripts/tests/twister/test_testsuite.py @@ -846,3 +846,43 @@ def test_testcase_dunders(): assert case_lesser < case_greater assert str(case_greater) == 'a greater name' assert repr(case_greater) == '' + + +TESTDATA_11 = [ + ( + ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites', + ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/tests/test_a', + 'test_a.check_1', + 'test_a.check_1' + ), + ( + ZEPHYR_BASE, + ZEPHYR_BASE, + 'test_a.check_1', + 'test_a.check_1' + ), + ( + ZEPHYR_BASE, + ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/test_b', + 'test_b.check_1', + 'test_b.check_1' + ), + ( + os.path.join(ZEPHYR_BASE, 'scripts/tests'), + os.path.join(ZEPHYR_BASE, 'scripts/tests'), + 'test_b.check_1', + 'test_b.check_1' + ), + ( + ZEPHYR_BASE, + ZEPHYR_BASE, + 'test_a.check_1.check_2', + 'test_a.check_1.check_2' + ), +] +@pytest.mark.parametrize("testsuite_root, suite_path, name, expected", TESTDATA_11) +def test_get_no_detailed_test_id(testsuite_root, suite_path, name, expected): + '''Test to check if the name without path is given for each testsuite''' + suite = TestSuite(testsuite_root, suite_path, name, detailed_test_id=False) + print(suite.name) + assert suite.name == expected From b38dab48c608040628a67c648a809986b59be1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 15 Sep 2023 16:25:28 +0700 Subject: [PATCH 1449/4498] counter: nxp_s32_sys_timer: use clock control APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use clock control API to retrieve the counter module's frequency and update the boards using it to provide the source clocks. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi | 16 ---------- drivers/counter/Kconfig.nxp_s32 | 3 +- drivers/counter/counter_nxp_s32_sys_timer.c | 29 +++++++++++++++++-- dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi | 4 +++ dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi | 4 +++ dts/bindings/timer/nxp,s32-sys-timer.yaml | 6 ++-- 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index a31ee5f7506..884f1d802bb 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -6,22 +6,6 @@ #include "s32z270dc2_r52-pinctrl-common.dtsi" -&stm0 { - clock-frequency = <133333333>; -}; - -&stm1 { - clock-frequency = <133333333>; -}; - -&stm2 { - clock-frequency = <133333333>; -}; - -&stm3 { - clock-frequency = <133333333>; -}; - &swt0 { status = "okay"; }; diff --git a/drivers/counter/Kconfig.nxp_s32 b/drivers/counter/Kconfig.nxp_s32 index 72274ee6269..ce4f3574abc 100644 --- a/drivers/counter/Kconfig.nxp_s32 +++ b/drivers/counter/Kconfig.nxp_s32 @@ -1,9 +1,10 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 config COUNTER_NXP_S32_SYS_TIMER bool "NXP S32 System Timer Module driver" default y depends on DT_HAS_NXP_S32_SYS_TIMER_ENABLED + select CLOCK_CONTROL help Enable support for NXP S32 System Timer Module (STM) driver. diff --git a/drivers/counter/counter_nxp_s32_sys_timer.c b/drivers/counter/counter_nxp_s32_sys_timer.c index bdaf62ad7bd..1c25039aab2 100644 --- a/drivers/counter/counter_nxp_s32_sys_timer.c +++ b/drivers/counter/counter_nxp_s32_sys_timer.c @@ -1,10 +1,11 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include #include @@ -35,6 +36,8 @@ struct nxp_s32_sys_timer_config { Stm_Ip_InstanceConfigType hw_cfg; Stm_Ip_ChannelConfigType ch_cfg[SYS_TIMER_NUM_CHANNELS]; uint8_t instance; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; }; static int nxp_s32_sys_timer_start(const struct device *dev) @@ -145,8 +148,14 @@ static uint32_t nxp_s32_sys_timer_get_top_value(const struct device *dev) static uint32_t nxp_s32_sys_timer_get_frequency(const struct device *dev) { const struct nxp_s32_sys_timer_config *config = dev->config; + uint32_t clock_rate; - return config->info.freq / (config->hw_cfg.clockPrescaler + 1U); + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_rate)) { + LOG_ERR("Failed to get clock frequency"); + return 0; + } + + return clock_rate / (config->hw_cfg.clockPrescaler + 1U); } static int nxp_s32_sys_timer_init(const struct device *dev) @@ -155,6 +164,18 @@ static int nxp_s32_sys_timer_init(const struct device *dev) struct nxp_s32_sys_timer_data *data = dev->data; struct nxp_s32_sys_timer_chan_data *ch_data; int i; + int err; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock control device not ready"); + return -ENODEV; + } + + err = clock_control_on(config->clock_dev, config->clock_subsys); + if (err) { + LOG_ERR("Failed to enable clock"); + return err; + } Stm_Ip_Init(config->instance, &config->hw_cfg); @@ -227,7 +248,6 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { static const struct nxp_s32_sys_timer_config nxp_s32_sys_timer_config_##n = { \ .info = { \ .max_top_value = SYS_TIMER_MAX_VALUE, \ - .freq = (DT_PROP(SYS_TIMER_NODE(n), clock_frequency)), \ .channels = SYS_TIMER_NUM_CHANNELS, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ }, \ @@ -239,6 +259,9 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { LISTIFY(SYS_TIMER_NUM_CHANNELS, SYS_TIMER_CHANNEL_CFG, (,), n) \ }, \ .instance = SYS_TIMER_INSTANCE_ID(n), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SYS_TIMER_NODE(n))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_CLOCKS_CELL(SYS_TIMER_NODE(n), name), \ }; \ \ DEVICE_DT_DEFINE(SYS_TIMER_NODE(n), \ diff --git a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi index 6d3b7da45d2..ec548c264cd 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu0_r52.dtsi @@ -20,6 +20,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76200000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU0_REG_INTF_CLK>; status = "disabled"; }; @@ -27,6 +28,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76210000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU0_REG_INTF_CLK>; status = "disabled"; }; @@ -34,6 +36,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76020000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU0_REG_INTF_CLK>; status = "disabled"; }; @@ -41,6 +44,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76030000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU0_REG_INTF_CLK>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi index ed3de4f2f16..f316ac86fd9 100644 --- a/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_rtu1_r52.dtsi @@ -20,6 +20,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76a00000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU1_REG_INTF_CLK>; status = "disabled"; }; @@ -27,6 +28,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76a10000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU1_REG_INTF_CLK>; status = "disabled"; }; @@ -34,6 +36,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76820000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU1_REG_INTF_CLK>; status = "disabled"; }; @@ -41,6 +44,7 @@ compatible = "nxp,s32-sys-timer"; reg = <0x76830000 0x10000>; interrupts = ; + clocks = <&clock NXP_S32_RTU1_REG_INTF_CLK>; status = "disabled"; }; diff --git a/dts/bindings/timer/nxp,s32-sys-timer.yaml b/dts/bindings/timer/nxp,s32-sys-timer.yaml index fbd8c8f3f70..54ac9d20d53 100644 --- a/dts/bindings/timer/nxp,s32-sys-timer.yaml +++ b/dts/bindings/timer/nxp,s32-sys-timer.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP S32 System Timer Module (STM) @@ -14,10 +14,8 @@ properties: interrupts: required: true - clock-frequency: - type: int + clocks: required: true - description: Module clock frequency in Hz. prescaler: type: int From 491901d605c84b04e431ca7e8c1343444056ae4c Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 27 Sep 2023 09:38:59 +0200 Subject: [PATCH 1450/4498] doc: board_porting: Move the board extensions section It was awkwardly placed in the middle of the "Write your devicetree" section, breaking up the flow of the guide. A more natural placement would be underneath "Contributing your board", considering that this feature deals with boards already submitted to Zephyr. Let's relocate this part and swap two of its paragraphs in the process, to motivate the feature before describing it. Signed-off-by: Grzegorz Swiderski --- doc/hardware/porting/board_porting.rst | 62 +++++++++++++------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index 8482eacc726..403c54a382d 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -242,37 +242,6 @@ followed by trial and error. If you want to understand details, you will need to read the rest of the devicetree documentation and the devicetree specification. -Board extensions -**************** - -Board extensions are board fragments that can be present in a board root -folder, under ``${BOARD_ROOT}/boards/extensions``. The extension folder must -follow the naming structure of the original board to extend. The board extension -directory may contain Kconfig fragments and/or devicetree overlays. Board -extensions are, by default, automatically loaded and applied on top of board -files, before anything else. There is no guarantee on which order extensions are -applied, in case multiple exist. This feature shall be disabled by passing -``-DBOARD_EXTENSIONS=OFF`` when building. - -Board extensions are designed for downstream users, for example, -``example-application`` or vendor SDKs. In some situations, certain hardware -description or `choices `_ can not be added in the -upstream Zephyr repository, but they can be in a downstream project, where -custom bindings or driver classes can also be created. This feature may also be -useful in development phases, when the board skeleton lives upstream, but other -features are developed in a downstream module. - -Note that board extensions need to follow the -:ref:`same guidelines ` as regular boards. For -example, it is wrong to enable extra peripherals or subsystems in a board -extension. - -.. warning:: - - Board extensions are not allowed in any module referenced in Zephyr's - ``west.yml`` manifest file. Any board changes are required to be submitted to - the main Zephyr repository. - .. _dt_k6x_example: Example: FRDM-K64F and Hexiwear K64 @@ -810,3 +779,34 @@ There are some extra things you'll need to do: #. Prepare a pull request adding your board which follows the :ref:`contribute_guidelines`. + +Board extensions +**************** + +Board extensions are designed for downstream users, for example, +``example-application`` or vendor SDKs. In some situations, certain hardware +description or `choices `_ can not be added in the +upstream Zephyr repository, but they can be in a downstream project, where +custom bindings or driver classes can also be created. This feature may also be +useful in development phases, when the board skeleton lives upstream, but other +features are developed in a downstream module. + +Board extensions are board fragments that can be present in a board root +folder, under ``${BOARD_ROOT}/boards/extensions``. The extension folder must +follow the naming structure of the original board to extend. The board extension +directory may contain Kconfig fragments and/or devicetree overlays. Board +extensions are, by default, automatically loaded and applied on top of board +files, before anything else. There is no guarantee on which order extensions are +applied, in case multiple exist. This feature shall be disabled by passing +``-DBOARD_EXTENSIONS=OFF`` when building. + +Note that board extensions need to follow the +:ref:`same guidelines ` as regular boards. For +example, it is wrong to enable extra peripherals or subsystems in a board +extension. + +.. warning:: + + Board extensions are not allowed in any module referenced in Zephyr's + ``west.yml`` manifest file. Any board changes are required to be submitted to + the main Zephyr repository. From f62c805a3de800c92bcd2652974a9de0fdcc3c23 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 27 Sep 2023 09:38:59 +0200 Subject: [PATCH 1451/4498] doc: board_porting: Extend the board extensions section Tweak a few sentences and add a basic example, to fit in with the overall document a little better. Also, fix an invalid cross-reference. Signed-off-by: Grzegorz Swiderski --- doc/hardware/porting/board_porting.rst | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index 403c54a382d..5b21cbf2b68 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -783,21 +783,31 @@ There are some extra things you'll need to do: Board extensions **************** -Board extensions are designed for downstream users, for example, +Boards already supported by Zephyr can be extended by downstream users, such as ``example-application`` or vendor SDKs. In some situations, certain hardware -description or `choices `_ can not be added in the +description or :ref:`choices ` can not be added in the upstream Zephyr repository, but they can be in a downstream project, where custom bindings or driver classes can also be created. This feature may also be useful in development phases, when the board skeleton lives upstream, but other features are developed in a downstream module. -Board extensions are board fragments that can be present in a board root -folder, under ``${BOARD_ROOT}/boards/extensions``. The extension folder must -follow the naming structure of the original board to extend. The board extension -directory may contain Kconfig fragments and/or devicetree overlays. Board -extensions are, by default, automatically loaded and applied on top of board +Board extensions are board fragments that can be present in an out-of-tree board +root folder, under ``${BOARD_ROOT}/boards/extensions``. Here is an example +structure of an extension for the ``plank`` board and its revisions: + +.. code-block:: none + + boards/extensions/plank + ├── plank.conf # optional + ├── plank_.conf # optional + ├── plank.overlay # optional + └── plank_.overlay # optional + +A board extension directory must follow the naming structure of the original +board it extends. It may contain Kconfig fragments and/or devicetree overlays. +Extensions are, by default, automatically loaded and applied on top of board files, before anything else. There is no guarantee on which order extensions are -applied, in case multiple exist. This feature shall be disabled by passing +applied, in case multiple exist. This feature can be disabled by passing ``-DBOARD_EXTENSIONS=OFF`` when building. Note that board extensions need to follow the From a35decaf90e620b6a9a64a0dc5bceebf2da9a04d Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 27 Sep 2023 12:53:39 +0200 Subject: [PATCH 1452/4498] doc: boards: Link to the board porting guide This is the more useful document to point newer Zephyr users to. The support documentation template is already mentioned in the guide (under "Contributing your board"), but leave the existing link to it for quick reference, just changing a few words. Signed-off-by: Grzegorz Swiderski --- boards/index.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/boards/index.rst b/boards/index.rst index 068388e28aa..9c843c9e95b 100644 --- a/boards/index.rst +++ b/boards/index.rst @@ -6,8 +6,11 @@ Supported Boards Zephyr project developers are continually adding board-specific support as documented below. -To add support documentation for a new board, please use the template available -under :zephyr_file:`doc/templates/board.tmpl` +If you are looking to add Zephyr support for a new board, please start with the +:ref:`board_porting_guide`. + +When adding support documentation for each board, remember to use the template +available under :zephyr_file:`doc/templates/board.tmpl`. .. toctree:: From f5dd62bbec03860ac46f9fe1fce41103a8579c4c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 27 Sep 2023 14:23:11 +0200 Subject: [PATCH 1453/4498] Bluetooth: Audio: Update codec_cfg_get_chan_allocation Update the function name from codec_cfg_get_chan_allocation_val to just codec_cfg_get_chan_allocation, and add codec_cfg_set_chan_allocation. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 17 ++++++++++-- samples/bluetooth/hap_ha/src/bap_unicast_sr.c | 2 +- .../tmap_peripheral/src/bap_unicast_sr.c | 2 +- .../bluetooth/unicast_audio_server/src/main.c | 2 +- subsys/bluetooth/audio/codec.c | 21 +++++++++++++-- tests/bluetooth/audio/codec/src/main.c | 27 +++++++++++++++++-- tests/bluetooth/tester/src/btp_bap.c | 4 +-- 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index c084c885068..5bf6fad74a6 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -637,8 +637,21 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg *codec_cfg, - enum bt_audio_location *chan_allocation); +int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_location *chan_allocation); + +/** + * @brief Set the channel allocation of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param chan_allocation The channel allocation to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_location chan_allocation); /** @brief Extract frame size in octets from BT codec config * diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index c185297ee20..5ed64e86202 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -89,7 +89,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); - if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index d05406dd1e9..ef78551efd1 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -78,7 +78,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); - if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index fd9415650ae..7c20ee34df8 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -149,7 +149,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frame Duration: %d us\n", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); - if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 59d2394b74e..c3dbfcf3ab8 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -322,8 +322,8 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co } } -int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg *codec_cfg, - enum bt_audio_location *chan_allocation) +int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_location *chan_allocation) { const uint8_t *data; uint8_t data_len; @@ -354,6 +354,23 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * return 0; } +int bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_location chan_allocation) +{ + uint32_t chan_allocation_u32; + + if ((chan_allocation & BT_AUDIO_LOCATION_ANY) != chan_allocation) { + LOG_DBG("Invalid chan_allocation value: 0x%08X", chan_allocation); + return -EINVAL; + } + + chan_allocation_u32 = sys_cpu_to_le32((uint32_t)chan_allocation); + + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, + (const uint8_t *)&chan_allocation_u32, + sizeof(chan_allocation_u32)); +} + int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg) { const uint8_t *data; diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 05df015a876..28dee9bdec1 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -84,7 +84,7 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_duration_us) zassert_equal(ret, 10000u, "unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation_val) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation) { const struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_8_1_1(BT_AUDIO_LOCATION_FRONT_LEFT, @@ -92,12 +92,35 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation_val) enum bt_audio_location chan_allocation = BT_AUDIO_LOCATION_FRONT_RIGHT; int err; - err = bt_audio_codec_cfg_get_chan_allocation_val(&preset.codec_cfg, &chan_allocation); + err = bt_audio_codec_cfg_get_chan_allocation(&preset.codec_cfg, &chan_allocation); zassert_false(err, "unexpected error %d", err); zassert_equal(chan_allocation, BT_AUDIO_LOCATION_FRONT_LEFT, "unexpected return value %d", chan_allocation); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_chan_allocation) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + enum bt_audio_location chan_allocation; + int err; + + err = bt_audio_codec_cfg_get_chan_allocation(&preset.codec_cfg, &chan_allocation); + zassert_equal(err, 0, "Unexpected return value %d", err); + zassert_equal(chan_allocation, 0x00000001, "Unexpected chan_allocation value %d", + chan_allocation); + + chan_allocation = BT_AUDIO_LOCATION_FRONT_RIGHT | BT_AUDIO_LOCATION_SIDE_RIGHT | + BT_AUDIO_LOCATION_TOP_SIDE_RIGHT | BT_AUDIO_LOCATION_RIGHT_SURROUND; + err = bt_audio_codec_cfg_set_chan_allocation(&preset.codec_cfg, chan_allocation); + zassert_true(err > 0, "Unexpected return value %d", err); + + err = bt_audio_codec_cfg_get_chan_allocation(&preset.codec_cfg, &chan_allocation); + zassert_equal(err, 0, "Unexpected return value %d", err); + zassert_equal(chan_allocation, 0x8080802, "Unexpected chan_allocation value %d", + chan_allocation); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_octets_per_frame) { const struct bt_bap_lc3_preset preset = diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 5fc38c81dbb..dda0dfc138b 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -150,7 +150,7 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) LOG_DBG(" Frame Duration: %d us", bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); - if (bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation) == 0) { + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { LOG_DBG(" Channel allocation: 0x%x", chan_allocation); } @@ -269,7 +269,7 @@ static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); chan_allocation_err = - bt_audio_codec_cfg_get_chan_allocation_val(codec_cfg, &chan_allocation); + bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); From 23ed21c0a028668ec89b5bdaa7a59bb6c1a53584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Thu, 28 Sep 2023 11:02:47 -0700 Subject: [PATCH 1454/4498] scripts: runners: rework RunnerCaps implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This provides miscellaneous quality of life improvements: - We couldn't use dataclasses when this class was originally written. We can now, so move to dataclass to avoid having to write __repr__(). - Add missing validation for the advertised commands - Add missing documentation for the 'file' capability Signed-off-by: Martí Bolívar --- scripts/west_commands/runners/core.py | 45 +++++++++++---------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index 68ad0eea024..c1f9eb7439f 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -22,6 +22,7 @@ import signal import subprocess import re +from dataclasses import dataclass, field from functools import partial from enum import Enum from inspect import isabstract @@ -199,6 +200,9 @@ def __init__(self, program): super().__init__(errno.ENOENT, os.strerror(errno.ENOENT), program) +_RUNNERCAPS_COMMANDS = {'flash', 'debug', 'debugserver', 'attach'} + +@dataclass class RunnerCaps: '''This class represents a runner class's capabilities. @@ -235,34 +239,23 @@ class RunnerCaps: - tool_opt: whether the runner supports a --tool-opt (-O) option, which can be given multiple times and is passed on to the underlying tool that the runner wraps. + + - file: whether the runner supports a --file option, which specifies + exactly the file that should be used to flash, overriding any default + discovered in the build directory. ''' - def __init__(self, - commands: Set[str] = {'flash', 'debug', - 'debugserver', 'attach'}, - dev_id: bool = False, - flash_addr: bool = False, - erase: bool = False, - reset: bool = False, - tool_opt: bool = False, - file: bool = False): - self.commands = commands - self.dev_id = dev_id - self.flash_addr = bool(flash_addr) - self.erase = bool(erase) - self.reset = bool(reset) - self.tool_opt = bool(tool_opt) - self.file = bool(file) - - def __str__(self): - return (f'RunnerCaps(commands={self.commands}, ' - f'dev_id={self.dev_id}, ' - f'flash_addr={self.flash_addr}, ' - f'erase={self.erase}, ' - f'reset={self.reset}, ' - f'tool_opt={self.tool_opt}, ' - f'file={self.file}' - ')') + commands: Set[str] = field(default_factory=lambda: set(_RUNNERCAPS_COMMANDS)) + dev_id: bool = False + flash_addr: bool = False + erase: bool = False + reset: bool = False + tool_opt: bool = False + file: bool = False + + def __post_init__(self): + if not self.commands.issubset(_RUNNERCAPS_COMMANDS): + raise ValueError(f'{self.commands=} contains invalid command') def _missing_cap(cls: Type['ZephyrBinaryRunner'], option: str) -> NoReturn: From d7aaf0daf75a0ac50d2924efd5dc12ff734ae803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 29 Sep 2023 12:27:08 +0200 Subject: [PATCH 1455/4498] doc: net: tftp: doxygen cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing docstrings for TFTP client error codes - Fix documentation for tftp_put() & tftp_get() - Fix rendering of notes for tftp_evt_type Signed-off-by: Benjamin Cabé --- include/zephyr/net/tftp.h | 44 +++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/include/zephyr/net/tftp.h b/include/zephyr/net/tftp.h index 648212a87cd..61db441e548 100644 --- a/include/zephyr/net/tftp.h +++ b/include/zephyr/net/tftp.h @@ -36,19 +36,19 @@ extern "C" { */ #define TFTP_HEADER_SIZE 4 -/* Maximum amount of data that can be sent or received */ +/** Maximum amount of data that can be sent or received */ #define TFTPC_MAX_BUF_SIZE (TFTP_BLOCK_SIZE + TFTP_HEADER_SIZE) /** * @name TFTP client error codes. * @{ */ -#define TFTPC_SUCCESS 0 -#define TFTPC_DUPLICATE_DATA -1 -#define TFTPC_BUFFER_OVERFLOW -2 -#define TFTPC_UNKNOWN_FAILURE -3 -#define TFTPC_REMOTE_ERROR -4 -#define TFTPC_RETRIES_EXHAUSTED -5 +#define TFTPC_SUCCESS 0 /**< Success. */ +#define TFTPC_DUPLICATE_DATA -1 /**< Duplicate data received. */ +#define TFTPC_BUFFER_OVERFLOW -2 /**< User buffer is too small. */ +#define TFTPC_UNKNOWN_FAILURE -3 /**< Unknown failure. */ +#define TFTPC_REMOTE_ERROR -4 /**< Remote server error. */ +#define TFTPC_RETRIES_EXHAUSTED -5 /**< Retries exhausted. */ /** * @} */ @@ -58,13 +58,15 @@ extern "C" { * through the callback registered by the application. */ enum tftp_evt_type { - /** DATA event when data is received from remote server. + /** + * DATA event when data is received from remote server. * * @note DATA event structure contains payload data and size. */ TFTP_EVT_DATA, - /** ERROR event when error is received from remote server. + /** + * ERROR event when error is received from remote server. * * @note ERROR event structure contains error code and message. */ @@ -132,17 +134,18 @@ struct tftpc { uint8_t tftp_buf[TFTPC_MAX_BUF_SIZE]; }; -/* @brief This function gets data from a "file" on the remote server. +/** + * @brief This function gets data from a "file" on the remote server. * * @param client Client information of type @ref tftpc. * @param remote_file Name of the remote file to get. * @param mode TFTP Client "mode" setting. * - * @return The size of data being received if the operation completed successfully. - * TFTPC_BUFFER_OVERFLOW if the file is larger than the user buffer. - * TFTPC_REMOTE_ERROR if the server failed to process our request. - * TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server. - * -EINVAL if `client` is NULL. + * @retval The size of data being received if the operation completed successfully. + * @retval TFTPC_BUFFER_OVERFLOW if the file is larger than the user buffer. + * @retval TFTPC_REMOTE_ERROR if the server failed to process our request. + * @retval TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server. + * @retval -EINVAL if `client` is NULL. * * @note This function blocks until the transfer is completed or network error happens. The * integrity of the `client` structure must be ensured until the function returns. @@ -150,7 +153,8 @@ struct tftpc { int tftp_get(struct tftpc *client, const char *remote_file, const char *mode); -/* @brief This function puts data to a "file" on the remote server. +/** + * @brief This function puts data to a "file" on the remote server. * * @param client Client information of type @ref tftpc. * @param remote_file Name of the remote file to put. @@ -158,10 +162,10 @@ int tftp_get(struct tftpc *client, * @param user_buf Data buffer containing the data to put. * @param user_buf_size Length of the data to put. * - * @return The size of data being sent if the operation completed successfully. - * TFTPC_REMOTE_ERROR if the server failed to process our request. - * TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server. - * -EINVAL if `client` or `user_buf` is NULL or if `user_buf_size` is zero. + * @retval The size of data being sent if the operation completed successfully. + * @retval TFTPC_REMOTE_ERROR if the server failed to process our request. + * @retval TFTPC_RETRIES_EXHAUSTED if the client timed out waiting for server. + * @retval -EINVAL if `client` or `user_buf` is NULL or if `user_buf_size` is zero. * * @note This function blocks until the transfer is completed or network error happens. The * integrity of the `client` structure must be ensured until the function returns. From 51d33410665496f8de8141f40de4942264b9d409 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 29 Sep 2023 14:16:37 +0200 Subject: [PATCH 1456/4498] net: icmp: Don't unref net_pkt from the registered handler A minor overlook from the recent ICMP rework, the registered handlers should no longer unref the processed packet as it's now the responsibility of the ICMP module. Signed-off-by: Robert Lubos --- subsys/net/ip/icmpv4.c | 2 -- subsys/net/ip/icmpv6.c | 2 -- subsys/net/ip/ipv6_mld.c | 2 -- subsys/net/ip/ipv6_nbr.c | 5 ----- subsys/net/ip/net_shell.c | 2 -- tests/net/icmp/src/main.c | 2 -- tests/net/icmpv4/src/main.c | 1 - tests/net/ipv6_fragment/src/main.c | 2 -- 8 files changed, 18 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index ea43f6052d0..7133ca16ee7 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -491,8 +491,6 @@ static int icmpv4_handle_echo_request(struct net_icmp_ctx *ctx, net_stats_update_icmp_sent(net_pkt_iface(reply)); - net_pkt_unref(pkt); - return 0; drop: if (reply) { diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index c19e3d5d1d3..ccd4c7f99ce 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -168,8 +168,6 @@ static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx, net_stats_update_icmp_sent(net_pkt_iface(reply)); - net_pkt_unref(pkt); - return 0; drop: diff --git a/subsys/net/ip/ipv6_mld.c b/subsys/net/ip/ipv6_mld.c index 43435b0b10f..e9eb82984f2 100644 --- a/subsys/net/ip/ipv6_mld.c +++ b/subsys/net/ip/ipv6_mld.c @@ -356,8 +356,6 @@ static int handle_mld_query(struct net_icmp_ctx *ctx, send_mld_report(net_pkt_iface(pkt)); - net_pkt_unref(pkt); - return 0; drop: diff --git a/subsys/net/ip/ipv6_nbr.c b/subsys/net/ip/ipv6_nbr.c index cca65d9fdc4..ebf8a6bc5b7 100644 --- a/subsys/net/ip/ipv6_nbr.c +++ b/subsys/net/ip/ipv6_nbr.c @@ -1383,7 +1383,6 @@ static int handle_ns_input(struct net_icmp_ctx *ctx, if (!net_ipv6_send_na(net_pkt_iface(pkt), na_src, na_dst, tgt, flags)) { - net_pkt_unref(pkt); return 0; } @@ -1822,8 +1821,6 @@ static int handle_na_input(struct net_icmp_ctx *ctx, goto drop; } - net_pkt_unref(pkt); - return 0; drop: @@ -2610,8 +2607,6 @@ static int handle_ra_input(struct net_icmp_ctx *ctx, /* Cancel the RS timer on iface */ net_if_stop_rs(net_pkt_iface(pkt)); - net_pkt_unref(pkt); - return 0; drop: diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 3a113778918..00e4fff57d6 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -4388,7 +4388,6 @@ static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, ping_done(&ping_ctx); } - net_pkt_unref(pkt); return 0; } #else @@ -4463,7 +4462,6 @@ static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, ping_done(&ping_ctx); } - net_pkt_unref(pkt); return 0; } #else diff --git a/tests/net/icmp/src/main.c b/tests/net/icmp/src/main.c index c2f97f93aa5..61a749c27ef 100644 --- a/tests/net/icmp/src/main.c +++ b/tests/net/icmp/src/main.c @@ -449,8 +449,6 @@ static int icmp_handler(struct net_icmp_ctx *ctx, test->req_received = true; k_sem_give(&test->tx_sem); - net_pkt_unref(pkt); - return 0; } diff --git a/tests/net/icmpv4/src/main.c b/tests/net/icmpv4/src/main.c index 7915e3fbfa7..c48e480a769 100644 --- a/tests/net/icmpv4/src/main.c +++ b/tests/net/icmpv4/src/main.c @@ -131,7 +131,6 @@ static int handle_reply_msg(struct net_icmp_ctx *ctx, return -ENOMSG; } - net_pkt_unref(pkt); return 0; } diff --git a/tests/net/ipv6_fragment/src/main.c b/tests/net/ipv6_fragment/src/main.c index 9eff54a1582..0d76f9cedf0 100644 --- a/tests/net/ipv6_fragment/src/main.c +++ b/tests/net/ipv6_fragment/src/main.c @@ -2282,8 +2282,6 @@ static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, i++; } - net_pkt_unref(pkt); - k_sem_give(&wait_data); return NET_OK; From e41f836c53b9a9daa6fcfca2109a484672b5a88a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 22 Sep 2023 11:02:48 +0200 Subject: [PATCH 1457/4498] tests nrf_rtc_timer: Allow on simulated nrf53 The simulated nrf53 bsim boards can run this test also just fine, so let's enable them. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/timer/nrf_rtc_timer/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/timer/nrf_rtc_timer/testcase.yaml b/tests/drivers/timer/nrf_rtc_timer/testcase.yaml index 8ebe05e8e96..9c3f9a94413 100644 --- a/tests/drivers/timer/nrf_rtc_timer/testcase.yaml +++ b/tests/drivers/timer/nrf_rtc_timer/testcase.yaml @@ -19,5 +19,7 @@ tests: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf52_bsim + - nrf5340bsim_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf52dk_nrf52832 From f1f066ec7d01889842263a853894afe3b694b7b9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 22 Sep 2023 11:03:24 +0200 Subject: [PATCH 1458/4498] test drivers.entropy.bt_hci: Allow on simulated nrf5340bsim_nrf5340_cpunet The simulated nrf5340bsim_nrf5340_cpunet board can run this test also just fine, so let's enable it. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/entropy/api/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/drivers/entropy/api/testcase.yaml b/tests/drivers/entropy/api/testcase.yaml index a2944f0230b..dfab54db635 100644 --- a/tests/drivers/entropy/api/testcase.yaml +++ b/tests/drivers/entropy/api/testcase.yaml @@ -5,7 +5,9 @@ tests: - drivers - entropy drivers.entropy.bt_hci: - platform_allow: nrf52_bsim + platform_allow: + - nrf52_bsim + - nrf5340bsim_nrf5340_cpunet extra_args: - DTC_OVERLAY_FILE=./entropy_bt_hci.overlay - OVERLAY_CONFIG=./entropy_bt_hci.conf From c883d397f62042042649689b00c8760099467e4c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 27 Sep 2023 16:16:41 +0200 Subject: [PATCH 1459/4498] tests/drivers/flash common: Allow on nrf53_bsim boards Add the new simulated nrf53 targets to this test, as they can run it without problems. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/flash/common/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index 6a06a61d011..844d5d1e556 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -42,6 +42,8 @@ tests: - mimxrt685_evk_cm33 - mimxrt595_evk_cm33 - nrf52_bsim + - nrf5340bsim_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpuapp drivers.flash.common.tfm_ns: build_only: true filter: (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE From a59b67c52114edef0c50611bad4374a2fcc4f97c Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 29 Sep 2023 16:50:04 +0300 Subject: [PATCH 1460/4498] samples: net: socket: echo_server: conn mgmt header file missing The conn_mgr_monitor.h was not included so the compilation gave warning for missing conn_mgr_ignore_iface() function. Signed-off-by: Jukka Rissanen --- samples/net/sockets/echo_server/src/tunnel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/sockets/echo_server/src/tunnel.c b/samples/net/sockets/echo_server/src/tunnel.c index 91d1aa7108d..77c85a7cd93 100644 --- a/samples/net/sockets/echo_server/src/tunnel.c +++ b/samples/net/sockets/echo_server/src/tunnel.c @@ -11,6 +11,7 @@ LOG_MODULE_DECLARE(net_echo_server_sample, LOG_LEVEL_DBG); #include #include +#include /* User data for the interface callback */ struct ud { From 639b11742ada0ad96ed60b49323660567050245f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 29 Sep 2023 14:39:50 +0200 Subject: [PATCH 1461/4498] doc: include: uart: cleanup doxygen documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a bunch of missing docstrings Properly document structs. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/uart.h | 64 ++++++++++++++++------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/include/zephyr/drivers/uart.h b/include/zephyr/drivers/uart.h index 8604d3fa543..6d68da64a58 100644 --- a/include/zephyr/drivers/uart.h +++ b/include/zephyr/drivers/uart.h @@ -31,11 +31,11 @@ extern "C" { /** @brief Line control signals. */ enum uart_line_ctrl { - UART_LINE_CTRL_BAUD_RATE = BIT(0), - UART_LINE_CTRL_RTS = BIT(1), - UART_LINE_CTRL_DTR = BIT(2), - UART_LINE_CTRL_DCD = BIT(3), - UART_LINE_CTRL_DSR = BIT(4), + UART_LINE_CTRL_BAUD_RATE = BIT(0), /**< Baud rate */ + UART_LINE_CTRL_RTS = BIT(1), /**< Request To Send (RTS) */ + UART_LINE_CTRL_DTR = BIT(2), /**< Data Terminal Ready (DTR) */ + UART_LINE_CTRL_DCD = BIT(3), /**< Data Carrier Detect (DCD) */ + UART_LINE_CTRL_DSR = BIT(4), /**< Data Set Ready (DSR) */ }; /** @@ -75,28 +75,28 @@ enum uart_rx_stop_reason { /** @brief Parity modes */ enum uart_config_parity { - UART_CFG_PARITY_NONE, - UART_CFG_PARITY_ODD, - UART_CFG_PARITY_EVEN, - UART_CFG_PARITY_MARK, - UART_CFG_PARITY_SPACE, + UART_CFG_PARITY_NONE, /**< No parity */ + UART_CFG_PARITY_ODD, /**< Odd parity */ + UART_CFG_PARITY_EVEN, /**< Even parity */ + UART_CFG_PARITY_MARK, /**< Mark parity */ + UART_CFG_PARITY_SPACE, /**< Space parity */ }; /** @brief Number of stop bits. */ enum uart_config_stop_bits { - UART_CFG_STOP_BITS_0_5, - UART_CFG_STOP_BITS_1, - UART_CFG_STOP_BITS_1_5, - UART_CFG_STOP_BITS_2, + UART_CFG_STOP_BITS_0_5, /**< 0.5 stop bit */ + UART_CFG_STOP_BITS_1, /**< 1 stop bit */ + UART_CFG_STOP_BITS_1_5, /**< 1.5 stop bits */ + UART_CFG_STOP_BITS_2, /**< 2 stop bits */ }; /** @brief Number of data bits. */ enum uart_config_data_bits { - UART_CFG_DATA_BITS_5, - UART_CFG_DATA_BITS_6, - UART_CFG_DATA_BITS_7, - UART_CFG_DATA_BITS_8, - UART_CFG_DATA_BITS_9, + UART_CFG_DATA_BITS_5, /**< 5 data bits */ + UART_CFG_DATA_BITS_6, /**< 6 data bits */ + UART_CFG_DATA_BITS_7, /**< 7 data bits */ + UART_CFG_DATA_BITS_8, /**< 8 data bits */ + UART_CFG_DATA_BITS_9, /**< 9 data bits */ }; /** @@ -107,27 +107,21 @@ enum uart_config_data_bits { * In other cases, flow control is managed by hardware/driver. */ enum uart_config_flow_control { - UART_CFG_FLOW_CTRL_NONE, - UART_CFG_FLOW_CTRL_RTS_CTS, - UART_CFG_FLOW_CTRL_DTR_DSR, - UART_CFG_FLOW_CTRL_RS485, + UART_CFG_FLOW_CTRL_NONE, /**< No flow control */ + UART_CFG_FLOW_CTRL_RTS_CTS, /**< RTS/CTS flow control */ + UART_CFG_FLOW_CTRL_DTR_DSR, /**< DTR/DSR flow control */ + UART_CFG_FLOW_CTRL_RS485, /**< RS485 flow control */ }; /** * @brief UART controller configuration structure - * - * @param baudrate Baudrate setting in bps - * @param parity Parity bit, use @ref uart_config_parity - * @param stop_bits Stop bits, use @ref uart_config_stop_bits - * @param data_bits Data bits, use @ref uart_config_data_bits - * @param flow_ctrl Flow control setting, use @ref uart_config_flow_control */ struct uart_config { - uint32_t baudrate; - uint8_t parity; - uint8_t stop_bits; - uint8_t data_bits; - uint8_t flow_ctrl; + uint32_t baudrate; /**< Baudrate setting in bps */ + uint8_t parity; /**< Parity bit, use @ref uart_config_parity */ + uint8_t stop_bits; /**< Stop bits, use @ref uart_config_stop_bits */ + uint8_t data_bits; /**< Data bits, use @ref uart_config_data_bits */ + uint8_t flow_ctrl; /**< Flow control setting, use @ref uart_config_flow_control */ }; /** @@ -285,7 +279,7 @@ struct uart_event_rx { /** @brief UART RX buffer released event data. */ struct uart_event_rx_buf { - /* @brief Pointer to buffer that is no longer in use. */ + /** @brief Pointer to buffer that is no longer in use. */ uint8_t *buf; }; From 3923cda6d865937c99c7f952a96ee2d09463b62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 29 Sep 2023 09:32:03 +0700 Subject: [PATCH 1462/4498] tests: kernel: syscalls: use default faulty address for s32z270dc2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before Picolibc was made default, this board needed a custom test faulty address. Now this address does not produce a fault anymore so switch back to the default faulty address. Fixes #63270 Signed-off-by: Manuel Argüelles --- tests/kernel/mem_protect/syscalls/src/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 20bc624b002..2e03c409065 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -25,8 +25,6 @@ #define FAULTY_ADDRESS 0x0FFFFFFF #elif defined(CONFIG_BOARD_QEMU_CORTEX_R5) #define FAULTY_ADDRESS 0xBFFFFFFF -#elif defined(CONFIG_SOC_SERIES_S32ZE_R52) -#define FAULTY_ADDRESS ((uintptr_t)(&_image_ram_end)) #elif CONFIG_MMU /* Just past the zephyr image mapping should be a non-present page */ #define FAULTY_ADDRESS Z_FREE_VM_START From 76e58af542b706f967e2e89ee2eb8b566dd1a860 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Sep 2023 15:22:32 +0100 Subject: [PATCH 1463/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 4fe28b3cf6d30c3e57d6a4f7ee3dba8617aa9a0a Brings following Zephyr relevant fixes: - 4fe28b3 Update zephyr version files for 2.0.0-rc1 - 6a6de4b scripts: imgtool: update to 2.0.0-rc1 release Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 7d3eb0407fe..3d74ecd4a0e 100644 --- a/west.yml +++ b/west.yml @@ -287,7 +287,7 @@ manifest: groups: - crypto - name: mcuboot - revision: bf8cf46b348eb8c8c10a1f1e4a7c24cdef52acf0 + revision: 4fe28b3cf6d30c3e57d6a4f7ee3dba8617aa9a0a path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From a6f8935e4fca606b90f3bdb05f8e2cf942732896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 14:57:46 +0200 Subject: [PATCH 1464/4498] doc: sphinx.util.progress_message is deprecated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of Sphinx 6.1, sphinx.util.progress_message is deprecated and sphinx.util.display.progress_message should be used instead. See https://www.sphinx-doc.org/en/master/changes.html#id165 Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/kconfig/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/kconfig/__init__.py b/doc/_extensions/zephyr/kconfig/__init__.py index e5992a15dde..c4042e298ad 100644 --- a/doc/_extensions/zephyr/kconfig/__init__.py +++ b/doc/_extensions/zephyr/kconfig/__init__.py @@ -44,7 +44,7 @@ from sphinx.environment import BuildEnvironment from sphinx.errors import ExtensionError from sphinx.roles import XRefRole -from sphinx.util import progress_message +from sphinx.util.display import progress_message from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_refnode From 34e16225ebe5cb3eccda55745cff93721bead4b3 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 29 Sep 2023 11:53:38 +0000 Subject: [PATCH 1465/4498] neural_net: remove unused experimental API Experimental API is not being used anymore, remove it. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 9 -- doc/develop/api/overview.rst | 4 - doc/hardware/peripherals/gna.rst | 15 -- doc/hardware/peripherals/index.rst | 1 - drivers/CMakeLists.txt | 1 - drivers/Kconfig | 1 - drivers/neural_net/CMakeLists.txt | 3 - drivers/neural_net/Kconfig | 17 --- include/zephyr/drivers/gna.h | 236 ----------------------------- tests/lib/cpp/cxx/src/main.cpp | 1 - 10 files changed, 288 deletions(-) delete mode 100644 doc/hardware/peripherals/gna.rst delete mode 100644 drivers/neural_net/CMakeLists.txt delete mode 100644 drivers/neural_net/Kconfig delete mode 100644 include/zephyr/drivers/gna.h diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b86c89f44e4..1f4afcf3e83 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1147,15 +1147,6 @@ Release Notes: labels: - "area: Modem" -"Drivers: Neural Networks": - status: odd fixes - collaborators: - - nashif - files: - - drivers/neural_net/ - labels: - - "area: Neural Networks" - "Drivers: Regulators": status: maintained maintainers: diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 3e64fd94016..33f0295d16a 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -137,10 +137,6 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Stable - 1.11 - * - :ref:`gna_api` - - Experimental - - 1.14 - * - :ref:`gpio_api` - Stable - 1.0 diff --git a/doc/hardware/peripherals/gna.rst b/doc/hardware/peripherals/gna.rst deleted file mode 100644 index b5fc8365752..00000000000 --- a/doc/hardware/peripherals/gna.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. _gna_api: - -Gaussian & Neural Accelerator (GNA) -################################### - -Overview -******** - -The GNA API provides access to Intel's Gaussian Mixture Model and Neural Network -Accelerator (GNA). - -API Reference -************* - -.. doxygengroup:: gna_interface diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 48e8baa97b9..ff80c0e9eb5 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -29,7 +29,6 @@ Peripherals edac/index.rst flash.rst fuel_gauge.rst - gna.rst gpio.rst hwinfo.rst i2c_eeprom_target.rst diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 891041f2ded..e9a1603f8cc 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -59,7 +59,6 @@ add_subdirectory_ifdef(CONFIG_MM_DRV mm) add_subdirectory_ifdef(CONFIG_MODEM modem) add_subdirectory_ifdef(CONFIG_NET_DRIVERS net) add_subdirectory_ifdef(CONFIG_NET_L2_ETHERNET ethernet) -add_subdirectory_ifdef(CONFIG_NEURAL_NET_ACCEL neural_net) add_subdirectory_ifdef(CONFIG_PECI peci) add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl) add_subdirectory_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops) diff --git a/drivers/Kconfig b/drivers/Kconfig index 2468fe77bd1..f486badbb38 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -55,7 +55,6 @@ source "drivers/misc/Kconfig" source "drivers/mm/Kconfig" source "drivers/modem/Kconfig" source "drivers/net/Kconfig" -source "drivers/neural_net/Kconfig" source "drivers/pcie/Kconfig" source "drivers/peci/Kconfig" source "drivers/pinctrl/Kconfig" diff --git a/drivers/neural_net/CMakeLists.txt b/drivers/neural_net/CMakeLists.txt deleted file mode 100644 index 28a0cecce8a..00000000000 --- a/drivers/neural_net/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() diff --git a/drivers/neural_net/Kconfig b/drivers/neural_net/Kconfig deleted file mode 100644 index 0aefae40d0a..00000000000 --- a/drivers/neural_net/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# Neural network accelerator driver configuration options - -# Copyright (c) 2018 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -menuconfig NEURAL_NET_ACCEL - bool "Neural Network Accelerator drivers" - help - Enable support for Neural Network Accelerators - -if NEURAL_NET_ACCEL - -module = NEURAL_NET -module-str = neural_net -source "subsys/logging/Kconfig.template.log_config" - -endif # NEURAL_NET diff --git a/include/zephyr/drivers/gna.h b/include/zephyr/drivers/gna.h deleted file mode 100644 index 6fc406507eb..00000000000 --- a/include/zephyr/drivers/gna.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation. - * - * Author: Sathish Kuttan - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Public API header file for Intel GNA driver - */ - -#ifndef __INCLUDE_GNA__ -#define __INCLUDE_GNA__ - -/** - * @defgroup gna_interface GNA Interface - * @ingroup io_interfaces - * @{ - * - * This file contains the driver APIs for Intel's - * Gaussian Mixture Model and Neural Network Accelerator (GNA) - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * GNA driver configuration structure. - * Currently empty. - */ -struct gna_config { -#ifdef __cplusplus - char no_empty_structs; /* technically a gcc C extension */ -#endif -}; - -/** - * GNA Neural Network model header - * Describes the key parameters of the neural network model - */ -struct gna_model_header { - uint32_t labase_offset; - uint32_t model_size; - uint32_t gna_mode; - uint32_t layer_count; - uint32_t bytes_per_input; - uint32_t bytes_per_output; - uint32_t num_input_nodes; - uint32_t num_output_nodes; - uint32_t input_ptr_offset; - uint32_t output_ptr_offset; - uint32_t rw_region_size; - uint32_t input_scaling_factor; - uint32_t output_scaling_factor; -}; - -/** - * GNA Neural Network model information to be provided by application - * during model registration - */ -struct gna_model_info { - struct gna_model_header *header; - void *rw_region; - void *ro_region; -}; - -/** - * Request to perform inference on the given neural network model - */ -struct gna_inference_req { - void *model_handle; - void *input; - void *output; - void *intermediate; -}; - -/** - * Statistics of the inference operation returned after completion - */ -struct gna_inference_stats { - uint32_t total_cycles; - uint32_t stall_cycles; - uint32_t cycles_per_sec; -}; - -/** - * Result of an inference operation - */ -enum gna_result { - GNA_RESULT_INFERENCE_COMPLETE, - GNA_RESULT_SATURATION_OCCURRED, - GNA_RESULT_OUTPUT_BUFFER_FULL_ERROR, - GNA_RESULT_PARAM_OUT_OF_RANGE_ERROR, - GNA_RESULT_GENERIC_ERROR, -}; - -/** - * Structure containing a response to the inference request - */ -struct gna_inference_resp { - enum gna_result result; - void *output; - size_t output_len; - struct gna_inference_stats stats; -}; - -/** - * @cond INTERNAL_HIDDEN - * - * Internal documentation. Skip in public documentation - */ -typedef int (*gna_callback)(struct gna_inference_resp *result); - -typedef int (*gna_api_config)(const struct device *dev, - struct gna_config *cfg); -typedef int (*gna_api_register)(const struct device *dev, - struct gna_model_info *model, - void **model_handle); -typedef int (*gna_api_deregister)(const struct device *dev, - void *model_handle); -typedef int (*gna_api_infer)(const struct device *dev, - struct gna_inference_req *req, - gna_callback callback); - -struct gna_driver_api { - gna_api_config configure; - gna_api_register register_model; - gna_api_deregister deregister_model; - gna_api_infer infer; -}; - -/** - * @endcond - */ - -/** - * @brief Configure the GNA device. - * - * Configure the GNA device. The GNA device must be configured before - * registering a model or performing inference - * - * @param dev Pointer to the device structure for the driver instance. - * @param cfg Device configuration information - * - * @retval 0 If the configuration is successful - * @retval A negative error code in case of a failure. - */ -static inline int gna_configure(const struct device *dev, - struct gna_config *cfg) -{ - const struct gna_driver_api *api = - (const struct gna_driver_api *)dev->api; - - return api->configure(dev, cfg); -} - -/** - * @brief Register a neural network model - * - * Register a neural network model with the GNA device - * A model needs to be registered before it can be used to perform inference - * - * @param dev Pointer to the device structure for the driver instance. - * @param model Information about the neural network model - * @param model_handle Handle to the registered model if registration succeeds - * - * @retval 0 If registration of the model is successful. - * @retval A negative error code in case of a failure. - */ -static inline int gna_register_model(const struct device *dev, - struct gna_model_info *model, - void **model_handle) -{ - const struct gna_driver_api *api = - (const struct gna_driver_api *)dev->api; - - return api->register_model(dev, model, model_handle); -} - -/** - * @brief De-register a previously registered neural network model - * - * De-register a previously registered neural network model from the GNA device - * De-registration may be done to free up memory for registering another model - * Once de-registered, the model can no longer be used to perform inference - * - * @param dev Pointer to the device structure for the driver instance. - * @param model Model handle output by gna_register_model API - * - * @retval 0 If de-registration of the model is successful. - * @retval A negative error code in case of a failure. - */ -static inline int gna_deregister_model(const struct device *dev, void *model) -{ - const struct gna_driver_api *api = - (const struct gna_driver_api *)dev->api; - - return api->deregister_model(dev, model); -} - -/** - * @brief Perform inference on a model with input vectors - * - * Make an inference request on a previously registered model with an of - * input data vector - * A callback is provided for notification of inference completion - * - * @param dev Pointer to the device structure for the driver instance. - * @param req Information required to perform inference on a neural network - * @param callback A callback function to notify inference completion - * - * @retval 0 If the request is accepted - * @retval A negative error code in case of a failure. - */ -static inline int gna_infer(const struct device *dev, - struct gna_inference_req *req, - gna_callback callback) -{ - const struct gna_driver_api *api = - (const struct gna_driver_api *)dev->api; - - return api->infer(dev, req, callback); -} - -#ifdef __cplusplus -} -#endif - -/** - * @} - */ - -#endif /* __INCLUDE_GNA__ */ diff --git a/tests/lib/cpp/cxx/src/main.cpp b/tests/lib/cpp/cxx/src/main.cpp index 02f7f767efe..43bc14f65ac 100644 --- a/tests/lib/cpp/cxx/src/main.cpp +++ b/tests/lib/cpp/cxx/src/main.cpp @@ -43,7 +43,6 @@ /* drivers/espi_saf.h requires SoC specific header */ #include #include -#include #include #include #include From 41e0a4a37141bad1c95cdd81653463032e4f05d7 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 27 Sep 2023 08:10:10 -0500 Subject: [PATCH 1466/4498] llext: Linkable loadable extensions Adds the linkable loadable extensions (llext) subsystem which provides functionality for reading, parsing, and linking ELF encoded executable code into a managed extension to the running elf base image. A loader interface, and default buffer loader implementation, make available to the llext subsystem the elf data. A simple management API provide the ability to load and unload extensions as needed. A shell interface for extension loading and unloading makes it easy to try. Adds initial support for armv7 thumb built elfs with very specific compiler flags. Signed-off-by: Tom Burdick Co-authored-by: Chen Peng1 Co-authored-by: Guennadi Liakhovetski --- arch/arm/core/CMakeLists.txt | 1 + arch/arm/core/elf.c | 37 + .../linker/common-rom/common-rom-misc.ld | 4 + include/zephyr/llext/buf_loader.h | 67 ++ include/zephyr/llext/elf.h | 484 +++++++++++ include/zephyr/llext/llext.h | 146 ++++ include/zephyr/llext/loader.h | 95 +++ include/zephyr/llext/symbol.h | 90 +++ lib/os/printk.c | 2 + subsys/CMakeLists.txt | 1 + subsys/Kconfig | 1 + subsys/llext/CMakeLists.txt | 6 + subsys/llext/Kconfig | 27 + subsys/llext/buf_loader.c | 31 + subsys/llext/llext.c | 757 ++++++++++++++++++ subsys/llext/shell.c | 178 ++++ 16 files changed, 1927 insertions(+) create mode 100644 arch/arm/core/elf.c create mode 100644 include/zephyr/llext/buf_loader.h create mode 100644 include/zephyr/llext/elf.h create mode 100644 include/zephyr/llext/llext.h create mode 100644 include/zephyr/llext/loader.h create mode 100644 include/zephyr/llext/symbol.h create mode 100644 subsys/llext/CMakeLists.txt create mode 100644 subsys/llext/Kconfig create mode 100644 subsys/llext/buf_loader.c create mode 100644 subsys/llext/llext.c create mode 100644 subsys/llext/shell.c diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 11f22942c11..1b4fa58eae5 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_ARM_ZIMAGE_HEADER header.S) +zephyr_library_sources_ifdef(CONFIG_LLEXT elf.c) add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M cortex_m) add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M_HAS_CMSE cortex_m/cmse) diff --git a/arch/arm/core/elf.c b/arch/arm/core/elf.c new file mode 100644 index 00000000000..b69a34086c8 --- /dev/null +++ b/arch/arm/core/elf.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +LOG_MODULE_DECLARE(elf); + +/** + * @brief Architecture specific function for relocating partially linked (static) elf + * + * Elf files contain a series of relocations described in a section. These relocation + * instructions are architecture specific and each architecture supporting modules + * must implement this. + * + * The relocation codes for arm are well documented + * https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#relocation + */ +void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval) +{ + elf_word reloc_type = ELF32_R_TYPE(rel->r_info); + + switch (reloc_type) { + case R_ARM_ABS32: + /* Update the absolute address of a load/store instruction */ + *((uint32_t *)opaddr) = (uint32_t)opval; + break; + default: + LOG_DBG("Unsupported ARM elf relocation type %d at address %lx", + reloc_type, opaddr); + break; + } +} diff --git a/include/zephyr/linker/common-rom/common-rom-misc.ld b/include/zephyr/linker/common-rom/common-rom-misc.ld index 74657c847a1..5da776a6aaf 100644 --- a/include/zephyr/linker/common-rom/common-rom-misc.ld +++ b/include/zephyr/linker/common-rom/common-rom-misc.ld @@ -39,6 +39,10 @@ ITERABLE_SECTION_ROM(zbus_channel_observation, 4) #endif /* CONFIG_ZBUS */ +#ifdef CONFIG_LLEXT + ITERABLE_SECTION_ROM(llext_const_symbol, 4) +#endif /* CONFIG_LLEXT */ + SECTION_DATA_PROLOGUE(symbol_to_keep,,) { __symbol_to_keep_start = .; diff --git a/include/zephyr/llext/buf_loader.h b/include/zephyr/llext/buf_loader.h new file mode 100644 index 00000000000..c75d20e4530 --- /dev/null +++ b/include/zephyr/llext/buf_loader.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LLEXT_BUF_LOADER_H +#define ZEPHYR_LLEXT_BUF_LOADER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LLEXT buffer loader + * @defgroup llext_buf_loader Linkable loadable extensions buffer loader + * @ingroup llext + * @{ + */ + +/** + * @brief An extension loader from a provided buffer containing an ELF + */ +struct llext_buf_loader { + /** Extension loader */ + struct llext_loader loader; + + /** @cond ignore */ + const uint8_t *buf; + size_t len; + size_t pos; + /** @endcond */ +}; + +/** @cond ignore */ +int llext_buf_read(struct llext_loader *ldr, void *buf, size_t len); +int llext_buf_seek(struct llext_loader *ldr, size_t pos); +/** @endcond */ + +/** + * @brief Initialize an extension buf loader + * + * @param _buf Buffer containing an ELF binary + * @param _buf_len Buffer length in bytes + */ +#define LLEXT_BUF_LOADER(_buf, _buf_len) \ + { \ + .loader = { \ + .read = llext_buf_read, \ + .seek = llext_buf_seek \ + }, \ + .buf = (_buf), \ + .len = (_buf_len), \ + .pos = 0 \ + } + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LLEXT_BUF_LOADER_H */ diff --git a/include/zephyr/llext/elf.h b/include/zephyr/llext/elf.h new file mode 100644 index 00000000000..1e83142dcd3 --- /dev/null +++ b/include/zephyr/llext/elf.h @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +#ifndef ZEPHYR_LLEXT_ELF_H +#define ZEPHYR_LLEXT_ELF_H + +#include + +/** + * @brief ELF types and parsing + * + * Reference documents can be found here https://refspecs.linuxfoundation.org/elf/ + * + * @defgroup elf ELF data types and defines + * @ingroup llext + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Unsigned program address */ +typedef uint32_t elf32_addr; +/** Unsigned medium integer */ +typedef uint16_t elf32_half; +/** Unsigned file offset */ +typedef uint32_t elf32_off; +/** Signed integer */ +typedef int32_t elf32_sword; +/** Unsigned integer */ +typedef uint32_t elf32_word; + +/** Unsigned program address */ +typedef uint64_t elf64_addr; +/** Unsigned medium integer */ +typedef uint16_t elf64_half; +/** Unsigned file offset */ +typedef uint64_t elf64_off; +/** Signed integer */ +typedef int32_t elf64_sword; +/** Unsigned integer */ +typedef uint32_t elf64_word; +/** Signed long integer */ +typedef int64_t elf64_sxword; +/** Unsigned long integer */ +typedef uint64_t elf64_xword; + + +/** + * @brief ELF identifier block + * + * 4 byte magic (.ELF) + * 1 byte class (Invalid, 32 bit, 64 bit) + * 1 byte endianness (Invalid, LSB, MSB) + * 1 byte version (1) + * 1 byte OS ABI (0 None, 1 HP-UX, 2 NetBSD, 3 Linux) + * 1 byte ABI (0) + * 7 bytes padding + */ +#define EI_NIDENT 16 + +/** + * @brief ELF Header(32-bit) + */ +struct elf32_ehdr { + /** Magic string identifying ELF binary */ + unsigned char e_ident[EI_NIDENT]; + /** Type of ELF */ + elf32_half e_type; + /** Machine type */ + elf32_half e_machine; + /** Object file version */ + elf32_word e_version; + /** Virtual address of entry */ + elf32_addr e_entry; + /** Program header table offset */ + elf32_off e_phoff; + /** Section header table offset */ + elf32_off e_shoff; + /** Processor specific flags */ + elf32_word e_flags; + /** ELF header size */ + elf32_half e_ehsize; + /** Program header count */ + elf32_half e_phentsize; + /** Program header count */ + elf32_half e_phnum; + /** Section header size */ + elf32_half e_shentsize; + /** Section header count */ + elf32_half e_shnum; + /** Section header containing section header string table */ + elf32_half e_shstrndx; +}; + +/** + * @brief ELF Header(64-bit) + */ +struct elf64_ehdr { + /** Magic string identifying ELF binary */ + unsigned char e_ident[EI_NIDENT]; + /** Type of ELF */ + elf64_half e_type; + /** Machine type */ + elf64_half e_machine; + /** Object file version */ + elf64_word e_version; + /** Virtual address of entry */ + elf64_addr e_entry; + /** Program header table offset */ + elf64_off e_phoff; + /** Section header table offset */ + elf64_off e_shoff; + /** Processor specific flags */ + elf64_word e_flags; + /** ELF header size */ + elf64_half e_ehsize; + /** Program header size */ + elf64_half e_phentsize; + /** Program header count */ + elf64_half e_phnum; + /** Section header size */ + elf64_half e_shentsize; + /** Section header count */ + elf64_half e_shnum; + /** Section header containing section header string table */ + elf64_half e_shstrndx; +}; + +/** Relocatable (unlinked) ELF */ +#define ET_REL 1 + +/** Executable (without PIC/PIE) ELF */ +#define ET_EXEC 2 + +/** Dynamic (executable with PIC/PIE or shared lib) ELF */ +#define ET_DYN 3 + +/** Core Dump */ +#define ET_CORE 4 + +/** + * @brief Section Header(32-bit) + */ +struct elf32_shdr { + /** Section header name index in section header string table */ + elf32_word sh_name; + /** Section type */ + elf32_word sh_type; + /** Section header attributes */ + elf32_word sh_flags; + /** Address of section in the image */ + elf32_addr sh_addr; + /** Location of section in the ELF binary in bytes */ + elf32_off sh_offset; + /** Section size in bytes */ + elf32_word sh_size; + /** Section header table link index, depends on section type */ + elf32_word sh_link; + /** Section info, depends on section type */ + elf32_word sh_info; + /** Section address alignment */ + elf32_word sh_addralign; + /** Section contains table of fixed size entries sh_entsize bytes large */ + elf32_word sh_entsize; +}; + +/** + * @brief Section Header(64-bit) + */ +struct elf64_shdr { + /** Section header name index in section header string table */ + elf64_word sh_name; + /** Section type */ + elf64_word sh_type; + /** Section header attributes */ + elf64_xword sh_flags; + /** Address of section in the image */ + elf64_addr sh_addr; + /** Location of section in the ELF binary in bytes */ + elf64_off sh_offset; + /** Section size in bytes */ + elf64_xword sh_size; + /** Section header table link index, depends on section type */ + elf64_word sh_link; + /** Section info, depends on section type */ + elf64_word sh_info; + /** Section address alignment */ + elf64_xword sh_addralign; + /** Section contains table of fixed size entries sh_entsize bytes large */ + elf64_xword sh_entsize; +}; + +#define SHT_PROGBITS 0x1 +#define SHT_SYMTAB 0x2 +#define SHT_STRTAB 0x3 +#define SHT_RELA 0x4 +#define SHT_NOBITS 0x8 +#define SHT_REL 0x9 +#define SHT_DYNSYM 0xB + +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 + +/** + * @brief Symbol table entry(32-bit) + */ +struct elf32_sym { + /** Name of the symbol as an index into the symbol string table */ + elf32_word st_name; + /** Value or location of the symbol */ + elf32_addr st_value; + /** Size of the symbol */ + elf32_word st_size; + /** Symbol binding and type information */ + unsigned char st_info; + /** Symbol visibility */ + unsigned char st_other; + /** Symbols related section given by section header index */ + elf32_half st_shndx; +}; + +/** + * @brief Symbol table entry(64-bit) + */ +struct elf64_sym { + /** Name of the symbol as an index into the symbol string table */ + elf64_word st_name; + /** Value or location of the symbol */ + elf64_addr st_value; + /** Size of the symbol */ + elf64_xword st_size; + /** Symbol binding and type information */ + unsigned char st_info; + /** Symbol visibility */ + unsigned char st_other; + /** Symbols related section given by section header index */ + elf64_half st_shndx; +}; + +#define SHN_UNDEF 0 +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_LOOS 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOOS 10 +#define STB_HIOS 12 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +/** + * @brief Symbol binding from 32bit st_info + * + * @param i Value of st_info + */ +#define ELF32_ST_BIND(i) ((i) >> 4) + +/** + * @brief Symbol type from 32bit st_info + * + * @param i Value of st_info + */ +#define ELF32_ST_TYPE(i) ((i) & 0xf) + +/** + * @brief Symbol binding from 32bit st_info + * + * @param i Value of st_info + */ +#define ELF64_ST_BIND(i) ((i) >> 4) + + +/** + * @brief Symbol type from 32bit st_info + * + * @param i Value of st_info + */ +#define ELF64_ST_TYPE(i) ((i) & 0xf) + +/** + * @brief Relocation entry for 32-bit ELFs + */ +struct elf32_rel { + /** Offset in the section to perform a relocation */ + elf32_addr r_offset; + + /** Information about the relocation, related symbol and type */ + elf32_word r_info; +}; + +/** + * @brief Relocation symbol index from r_info + * + * @param i Value of r_info + */ +#define ELF32_R_SYM(i) ((i) >> 8) + +/** + * @brief Relocation type from r_info + * + * @param i Value of r_info + */ +#define ELF32_R_TYPE(i) ((i) & 0xff) + +/** + * @brief Relocation entry for 64-bit ELFs + */ +struct elf64_rel { + /** Offset in section to perform a relocation */ + elf64_addr r_offset; + /** Information about relocation, related symbol and type */ + elf64_xword r_info; +}; + +/** @brief Relocation symbol from r_info + * + * @param i Value of r_info + */ +#define ELF64_R_SYM(i) ((i) >> 32) + +/** + * @brief Relocation type from r_info + * + * @param i Value of r_info + */ +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 + +#define R_ARM_NONE 0 +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_COPY 4 +#define R_ARM_CALL 28 +#define R_ARM_V4BX 40 + +#define R_XTENSA_NONE 0 +#define R_XTENSA_32 1 +#define R_XTENSA_SLOT0_OP 20 + +/** + * @brief Program header(32-bit) + */ +struct elf32_phdr { + elf32_word p_type; + elf32_off p_offset; + elf32_addr p_vaddr; + elf32_addr p_paddr; + elf32_word p_filesz; + elf32_word p_memsz; + elf32_word p_flags; + elf32_word p_align; +}; + +/** + * @brief Program header(64-bit) + */ +struct elf64_phdr { + elf64_word p_type; + elf64_off p_offset; + elf64_addr p_vaddr; + elf64_addr p_paddr; + elf64_xword p_filesz; + elf64_xword p_memsz; + elf64_word p_flags; + elf64_xword p_align; +}; + +/** + * @brief Program segment type + */ +#define PT_LOAD 1 + +/** + * @brief Dynamic section entry(32-bit) + */ +struct elf32_dyn { + elf32_sword d_tag; + union { + elf32_word d_val; + elf32_addr d_ptr; + } d_un; +}; + +/** + * @brief Dynamic section entry(64-bit) + */ +struct elf64_dyn { + elf64_sxword d_tag; + union { + elf64_xword d_val; + elf64_addr d_ptr; + } d_un; +}; + +#if defined(CONFIG_64BIT) || defined(__DOXYGEN__) +/** Machine sized elf header structure */ +typedef struct elf64_ehdr elf_ehdr_t; +/** Machine sized section header structure */ +typedef struct elf64_shdr elf_shdr_t; +/** Machine sized program header structure */ +typedef struct elf64_phdr elf_phdr_t; +/** Machine sized program address */ +typedef elf64_addr elf_addr; +/** Machine sized small integer */ +typedef elf64_half elf_half; +/** Machine sized integer */ +typedef elf64_xword elf_word; +/** Machine sized relocation struct */ +typedef struct elf64_rela elf_rel_t; +/** Machine sized symbol struct */ +typedef struct elf64_sym elf_sym_t; +/** Machine sized macro alias for obtaining a relocation symbol */ +#define ELF_R_SYM ELF64_R_SYM +/** Machine sized macro alias for obtaining a relocation type */ +#define ELF_R_TYPE ELF64_R_TYPE +/** Machine sized macro alias for obtaining a symbol bind */ +#define ELF_ST_BIND ELF64_ST_BIND +/** Machine sized macro alias for obtaining a symbol type */ +#define ELF_ST_TYPE ELF64_ST_TYPE +#else +/** Machine sized elf header structure */ +typedef struct elf32_ehdr elf_ehdr_t; +/** Machine sized section header structure */ +typedef struct elf32_shdr elf_shdr_t; +/** Machine sized program header structure */ +typedef struct elf32_phdr elf_phdr_t; +/** Machine sized program address */ +typedef elf32_addr elf_addr; +/** Machine sized small integer */ +typedef elf32_half elf_half; +/** Machine sized integer */ +typedef elf32_word elf_word; +/** Machine sized relocation struct */ +typedef struct elf32_rel elf_rel_t; +/** Machine sized symbol struct */ +typedef struct elf32_sym elf_sym_t; +/** Machine sized macro alias for obtaining a relocation symbol */ +#define ELF_R_SYM ELF32_R_SYM +/** Machine sized macro alias for obtaining a relocation type */ +#define ELF_R_TYPE ELF32_R_TYPE +/** Machine sized macro alias for obtaining a symbol bind */ +#define ELF_ST_BIND ELF32_ST_BIND +/** Machine sized macro alias for obtaining a symbol type */ +#define ELF_ST_TYPE ELF32_ST_TYPE +#endif + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_LLEXT_ELF_H */ diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h new file mode 100644 index 00000000000..13431954c48 --- /dev/null +++ b/include/zephyr/llext/llext.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LLEXT_H +#define ZEPHYR_LLEXT_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Linkable loadable extensions + * @defgroup llext Linkable loadable extensions + * @ingroup os_services + * @{ + */ + +/** + * @brief Enum of memory regions for lookup tables + */ +enum llext_mem { + LLEXT_MEM_TEXT, + LLEXT_MEM_DATA, + LLEXT_MEM_RODATA, + LLEXT_MEM_BSS, + + LLEXT_MEM_COUNT, +}; + +/** + * @brief Linkable loadable extension + */ +struct llext { + /** @cond ignore */ + sys_snode_t _llext_list; + /** @endcond */ + + /** Name of the llext */ + char name[16]; + + /** Lookup table of llext memory regions */ + void *mem[LLEXT_MEM_COUNT]; + + /** Total size of the llext memory usage */ + size_t mem_size; + + /** Exported symbols from the llext, may be linked against by other llext */ + struct llext_symtable sym_tab; +}; + +/** + * @brief List head of loaded extensions + */ +sys_slist_t *llext_list(void); + +/** + * @brief Find an llext by name + * + * @param[in] name String name of the llext + * @retval NULL if no llext not found + * @retval llext if llext found + */ +struct llext *llext_by_name(const char *name); + +/** + * @brief Load and link an extension + * + * Loads relevant ELF data into memory and provides a structure to work with it. + * + * Only relocatable ELF files are currently supported (partially linked). + * + * @param[in] loader An extension loader that provides input data and context + * @param[in] name A string identifier for the module + * @param[out] ext A pointer to a statically allocated llext struct + * + * @retval 0 Success + * @retval -ENOMEM Not enough memory + * @retval -EINVAL Invalid ELF stream + */ +int llext_load(struct llext_loader *loader, const char *name, struct llext **ext); + +/** + * @brief Unload an extension + * + * @param[in] ext Extension to unload + */ +void llext_unload(struct llext *ext); + +/** + * @brief Find the address for an arbitrary symbol name. + * + * @param[in] sym_table Symbol table to lookup symbol in, if NULL uses base table + * @param[in] sym_name Symbol name to find + * + * @retval NULL if no symbol found + * @retval addr Address of symbol in memory if found + */ +const void * const llext_find_sym(const struct llext_symtable *sym_table, const char *sym_name); + +/** + * @brief Call a function by name + * + * Expects a symbol representing a void fn(void) style function exists + * and may be called. + * + * @param[in] ext Extension to call function in + * @param[in] sym_name Function name (exported symbol) in the extension + * + * @retval 0 success + * @retval -EINVAL invalid symbol name + */ +int llext_call_fn(struct llext *ext, const char *sym_name); + +/** + * @brief Architecture specific function for updating op codes given a relocation + * + * Elf files contain a series of relocations described in a section. These relocation + * instructions are architecture specific and each architecture supporting extensions + * must implement this. They are instructions on how to rewrite opcodes given + * the actual placement of some symbolic data such as a section, function, + * or object. + * + * @param[in] rel Relocation data provided by elf + * @param[in] opaddr Address of operation to rewrite with relocation + * @param[in] opval Value of looked up symbol to relocate + */ +void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULE_H */ diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h new file mode 100644 index 00000000000..db4157168aa --- /dev/null +++ b/include/zephyr/llext/loader.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LLEXT_LOADER_H +#define ZEPHYR_LLEXT_LOADER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Loader context for llext + * @defgroup llext_loader Loader context for llext + * @ingroup llext + * @{ + */ + +/** + * @brief Enum of sections for lookup tables + */ +enum llext_section { + LLEXT_SECT_TEXT, + LLEXT_SECT_DATA, + LLEXT_SECT_RODATA, + LLEXT_SECT_BSS, + + LLEXT_SECT_REL_TEXT, + LLEXT_SECT_REL_DATA, + LLEXT_SECT_REL_RODATA, + LLEXT_SECT_REL_BSS, + + LLEXT_SECT_SYMTAB, + LLEXT_SECT_STRTAB, + LLEXT_SECT_SHSTRTAB, + + LLEXT_SECT_COUNT, +}; + +/** + * @brief Linkable loadable extension loader context + */ +struct llext_loader { + /** + * @brief Read (copy) from the loader + * + * Copies len bytes into buf from the current position of the + * loader. + * + * @param[in] ldr Loader + * @param[in] out Output location + * @param[in] len Length to copy into the output location + * + * @retval 0 Success + * @retval -errno Error reading (any errno) + */ + int (*read)(struct llext_loader *ldr, void *out, size_t len); + + /** + * @brief Seek to a new absolute location + * + * Changes the location of the loader position to a new absolute + * given position. + * + * @param[in] ldr Loader + * @param[in] pos Position in stream to move loader + * + * @retval 0 Success + * @retval -errno Error reading (any errno) + */ + int (*seek)(struct llext_loader *s, size_t pos); + + /** @cond ignore */ + elf_ehdr_t hdr; + elf_shdr_t sects[LLEXT_SECT_COUNT]; + uint32_t *sect_map; + uint32_t sect_cnt; + uint32_t sym_cnt; + /** @endcond */ +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LLEXT_LOADER_H */ diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h new file mode 100644 index 00000000000..f4b69ef5010 --- /dev/null +++ b/include/zephyr/llext/symbol.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LLEXT_SYMBOL_H +#define ZEPHYR_LLEXT_SYMBOL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief Linkable loadable extension symbol + * @defgroup llext_symbols LLEXT symbols + * @ingroup llext + * @{ + */ + +/** + * @brief Constant symbols are unchangeable named memory addresses + * + * Symbols may be named function or global objects that have been exported + * for linking. These constant symbols are useful in the base image + * as they may be placed in ROM. + */ +struct llext_const_symbol { + /** Name of symbol */ + const char *const name; + + /** Address of symbol */ + const void *const addr; +}; + +/** + * @brief Symbols are named memory addresses + * + * Symbols may be named function or global objects that have been exported + * for linking. These are mutable and should come from extensions where + * the location may need updating depending on where memory is placed. + */ +struct llext_symbol { + /** Name of symbol */ + char *name; + + /** Address of symbol */ + void *addr; +}; + + +/** + * @brief A symbol table + * + * An array of symbols + */ +struct llext_symtable { + /** Number of symbols in the table */ + size_t sym_cnt; + + /** Array of symbols */ + struct llext_symbol *syms; +}; + + +/** + * @brief Export a constant symbol to a table of symbols + * + * Takes a symbol (function or object) by symbolic name and adds the name + * and address of the symbol to a table of symbols that may be used for linking. + * + * @param x Symbol to export + */ +#define EXPORT_SYMBOL(x) \ + static const STRUCT_SECTION_ITERABLE(llext_const_symbol, x ## _sym) = { \ + .name = STRINGIFY(x), .addr = x, \ + } + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* ZEPHYR_LLEXT_SYMBOL_H */ diff --git a/lib/os/printk.c b/lib/os/printk.c index 466e8944b2e..0701f8a3a6f 100644 --- a/lib/os/printk.c +++ b/lib/os/printk.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* Option present only when CONFIG_USERSPACE enabled. */ @@ -210,6 +211,7 @@ void printk(const char *fmt, ...) va_end(ap); } +EXPORT_SYMBOL(printk); #endif /* defined(CONFIG_PRINTK) */ #ifndef CONFIG_PICOLIBC diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index d1d9147484a..bef01e0f24a 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory_ifdef(CONFIG_IMG_MANAGER dfu) add_subdirectory_ifdef(CONFIG_INPUT input) add_subdirectory_ifdef(CONFIG_JWT jwt) add_subdirectory_ifdef(CONFIG_MODEM_MODULES modem) +add_subdirectory_ifdef(CONFIG_LLEXT llext) add_subdirectory_ifdef(CONFIG_NET_BUF net) add_subdirectory_ifdef(CONFIG_RETENTION retention) add_subdirectory_ifdef(CONFIG_SENSING sensing) diff --git a/subsys/Kconfig b/subsys/Kconfig index e5a7e8af2b3..e4fa9212ab0 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -21,6 +21,7 @@ source "subsys/fs/Kconfig" source "subsys/input/Kconfig" source "subsys/ipc/Kconfig" source "subsys/jwt/Kconfig" +source "subsys/llext/Kconfig" source "subsys/logging/Kconfig" source "subsys/lorawan/Kconfig" source "subsys/mem_mgmt/Kconfig" diff --git a/subsys/llext/CMakeLists.txt b/subsys/llext/CMakeLists.txt new file mode 100644 index 00000000000..ac54f3172c3 --- /dev/null +++ b/subsys/llext/CMakeLists.txt @@ -0,0 +1,6 @@ +if(CONFIG_LLEXT) + zephyr_library() + zephyr_library_sources(llext.c) + zephyr_library_sources(buf_loader.c) + zephyr_library_sources_ifdef(CONFIG_LLEXT_SHELL shell.c) +endif() diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig new file mode 100644 index 00000000000..7f9f24dcb68 --- /dev/null +++ b/subsys/llext/Kconfig @@ -0,0 +1,27 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig LLEXT + bool "Linkable loadable extensions" + help + Enable the linkable loadable extension subsystem + +if LLEXT + +config LLEXT_HEAP_SIZE + int "llext heap memory size in kilobytes" + default 8 + help + Heap size in kilobytes available to llext for dynamic allocation + +config LLEXT_SHELL + bool "llext shell commands" + depends on SHELL + help + Manage llext with shell commands for loading, unloading, and introspection + +module = LLEXT +module-str = llext +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/subsys/llext/buf_loader.c b/subsys/llext/buf_loader.c new file mode 100644 index 00000000000..1b9fb576e7d --- /dev/null +++ b/subsys/llext/buf_loader.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include + +int llext_buf_read(struct llext_loader *l, void *buf, size_t len) +{ + struct llext_buf_loader *buf_l = CONTAINER_OF(l, struct llext_buf_loader, loader); + size_t end = MIN(buf_l->pos + len, buf_l->len); + size_t read_len = end - buf_l->pos; + + memcpy(buf, buf_l->buf + buf_l->pos, read_len); + buf_l->pos = end; + + return 0; +} + +int llext_buf_seek(struct llext_loader *l, size_t pos) +{ + struct llext_buf_loader *buf_l = CONTAINER_OF(l, struct llext_buf_loader, loader); + + buf_l->pos = MIN(pos, buf_l->len); + + return 0; +} diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c new file mode 100644 index 00000000000..1a4739564a3 --- /dev/null +++ b/subsys/llext/llext.c @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include "zephyr/sys/__assert.h" +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(llext, CONFIG_LLEXT_LOG_LEVEL); + +#include + +K_HEAP_DEFINE(llext_heap, CONFIG_LLEXT_HEAP_SIZE * 1024); + +static const char ELF_MAGIC[] = {0x7f, 'E', 'L', 'F'}; + +static inline int llext_read(struct llext_loader *l, void *buf, size_t len) +{ + return l->read(l, buf, len); +} + +static inline int llext_seek(struct llext_loader *l, size_t pos) +{ + return l->seek(l, pos); +} + +static sys_slist_t _llext_list = SYS_SLIST_STATIC_INIT(&_llext_list); + +sys_slist_t *llext_list(void) +{ + return &_llext_list; +} + +struct llext *llext_by_name(const char *name) +{ + sys_slist_t *mlist = llext_list(); + sys_snode_t *node = sys_slist_peek_head(mlist); + struct llext *ext = CONTAINER_OF(node, struct llext, _llext_list); + + while (node != NULL) { + if (strncmp(ext->name, name, sizeof(ext->name)) == 0) { + return ext; + } + node = sys_slist_peek_next(node); + ext = CONTAINER_OF(node, struct llext, _llext_list); + } + + return NULL; +} + +const void * const llext_find_sym(const struct llext_symtable *sym_table, const char *sym_name) +{ + if (sym_table == NULL) { + /* Buildin symbol table */ + STRUCT_SECTION_FOREACH(llext_const_symbol, sym) { + if (strcmp(sym->name, sym_name) == 0) { + return sym->addr; + } + } + } else { + /* find symbols in module */ + for (size_t i = 0; i < sym_table->sym_cnt; i++) { + if (strcmp(sym_table->syms[i].name, sym_name) == 0) { + return sym_table->syms[i].addr; + } + } + } + + return NULL; +} + +/* + * Find all relevant string and symbol tables + */ +static int llext_find_tables(struct llext_loader *ldr) +{ + int ret = 0; + size_t pos = ldr->hdr.e_shoff; + elf_shdr_t shdr; + + ldr->sects[LLEXT_SECT_SHSTRTAB] = + ldr->sects[LLEXT_SECT_STRTAB] = + ldr->sects[LLEXT_SECT_SYMTAB] = (elf_shdr_t){0}; + + /* Find symbol and string tables */ + for (int i = 0, str_cnt = 0; i < ldr->hdr.e_shnum && str_cnt < 3; i++) { + ret = llext_seek(ldr, pos); + if (ret != 0) { + LOG_ERR("failed seeking to position %u\n", pos); + goto out; + } + + ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); + if (ret != 0) { + LOG_ERR("failed reading section header at position %u\n", pos); + goto out; + } + + pos += ldr->hdr.e_shentsize; + + LOG_DBG("section %d at %x: name %d, type %d, flags %x, addr %x, size %d", + i, + ldr->hdr.e_shoff + i * ldr->hdr.e_shentsize, + shdr.sh_name, + shdr.sh_type, + shdr.sh_flags, + shdr.sh_addr, + shdr.sh_size); + + switch (shdr.sh_type) { + case SHT_SYMTAB: + case SHT_DYNSYM: + LOG_DBG("symtab at %d", i); + ldr->sects[LLEXT_SECT_SYMTAB] = shdr; + ldr->sect_map[i] = LLEXT_SECT_SYMTAB; + str_cnt++; + break; + case SHT_STRTAB: + if (ldr->hdr.e_shstrndx == i) { + LOG_DBG("shstrtab at %d", i); + ldr->sects[LLEXT_SECT_SHSTRTAB] = shdr; + ldr->sect_map[i] = LLEXT_SECT_SHSTRTAB; + } else { + LOG_DBG("strtab at %d", i); + ldr->sects[LLEXT_SECT_STRTAB] = shdr; + ldr->sect_map[i] = LLEXT_SECT_STRTAB; + } + str_cnt++; + break; + default: + break; + } + } + + if (!ldr->sects[LLEXT_SECT_SHSTRTAB].sh_type || + !ldr->sects[LLEXT_SECT_STRTAB].sh_type || + !ldr->sects[LLEXT_SECT_SYMTAB].sh_type) { + LOG_ERR("Some sections are missing or present multiple times!"); + ret = -ENOENT; + } + +out: + return ret; +} + +/* + * Maps the section indexes and copies special section headers for easier use + */ +static int llext_map_sections(struct llext_loader *ldr) +{ + int ret = 0; + size_t pos = ldr->hdr.e_shoff; + elf_shdr_t shdr; + char name[32]; + + for (int i = 0; i < ldr->hdr.e_shnum; i++) { + ret = llext_seek(ldr, pos); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); + if (ret != 0) { + goto out; + } + + pos += ldr->hdr.e_shentsize; + + elf_word str_idx = shdr.sh_name; + + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SHSTRTAB].sh_offset + str_idx); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, name, sizeof(name)); + if (ret != 0) { + goto out; + } + + name[sizeof(name) - 1] = '\0'; + + LOG_DBG("section %d name %s", i, name); + + enum llext_section sect_idx; + + if (strncmp(name, ".text", sizeof(name)) == 0) { + sect_idx = LLEXT_SECT_TEXT; + } else if (strncmp(name, ".data", sizeof(name)) == 0) { + sect_idx = LLEXT_SECT_DATA; + } else if (strncmp(name, ".rodata", sizeof(name)) == 0) { + sect_idx = LLEXT_SECT_RODATA; + } else if (strncmp(name, ".bss", sizeof(name)) == 0) { + sect_idx = LLEXT_SECT_BSS; + } else { + LOG_DBG("Not copied section %s", name); + continue; + } + + ldr->sects[sect_idx] = shdr; + ldr->sect_map[i] = sect_idx; + } + +out: + return ret; +} + +static inline enum llext_section llext_sect_from_mem(enum llext_mem m) +{ + enum llext_section s; + + switch (m) { + case LLEXT_MEM_BSS: + s = LLEXT_SECT_BSS; + break; + case LLEXT_MEM_DATA: + s = LLEXT_SECT_DATA; + break; + case LLEXT_MEM_RODATA: + s = LLEXT_SECT_RODATA; + break; + case LLEXT_MEM_TEXT: + s = LLEXT_SECT_TEXT; + break; + default: + CODE_UNREACHABLE; + } + + return s; +} + +static int llext_allocate_mem(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + enum llext_section sect_idx; + + for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { + sect_idx = llext_sect_from_mem(mem_idx); + + if (ldr->sects[sect_idx].sh_size > 0) { + ext->mem[mem_idx] = + k_heap_aligned_alloc(&llext_heap, sizeof(uintptr_t), + ldr->sects[sect_idx].sh_size, + K_NO_WAIT); + + if (ext->mem[mem_idx] == NULL) { + ret = -ENOMEM; + goto out; + } + } + } + +out: + return ret; +} + +static int llext_copy_sections(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + enum llext_section sect_idx; + + for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { + sect_idx = llext_sect_from_mem(mem_idx); + + if (ldr->sects[sect_idx].sh_size > 0) { + ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size); + if (ret != 0) { + goto out; + } + } + } + +out: + return ret; +} + +static int llext_count_export_syms(struct llext_loader *ldr) +{ + int ret = 0; + elf_sym_t sym; + size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; + size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; + size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; + size_t sym_cnt = syms_size / sizeof(elf_sym_t); + char name[32]; + + LOG_DBG("symbol count %u", sym_cnt); + + for (int i = 0; i < sym_cnt; i++) { + ret = llext_seek(ldr, pos); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &sym, ent_size); + if (ret != 0) { + goto out; + } + + pos += ent_size; + + uint32_t stt = ELF_ST_TYPE(sym.st_info); + uint32_t stb = ELF_ST_BIND(sym.st_info); + uint32_t sect = sym.st_shndx; + + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + sym.st_name); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, name, sizeof(name)); + if (ret != 0) { + goto out; + } + + name[sizeof(name) - 1] = '\0'; + + if (stt == STT_FUNC && stb == STB_GLOBAL) { + LOG_DBG("function symbol %d, name %s, type tag %d, bind %d, sect %d", + i, name, stt, stb, sect); + ldr->sym_cnt++; + } else { + LOG_DBG("unhandled symbol %d, name %s, type tag %d, bind %d, sect %d", + i, name, stt, stb, sect); + } + } + +out: + return ret; +} + +static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + + ext->sym_tab.syms = k_heap_alloc(&llext_heap, ldr->sym_cnt * sizeof(struct llext_symbol), + K_NO_WAIT); + ext->sym_tab.sym_cnt = ldr->sym_cnt; + memset(ext->sym_tab.syms, 0, ldr->sym_cnt * sizeof(struct llext_symbol)); + + return ret; +} + +static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + elf_sym_t sym; + size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; + size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; + size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; + size_t sym_cnt = syms_size / sizeof(elf_sym_t); + char name[32]; + int i, j = 0; + + for (i = 0; i < sym_cnt; i++) { + ret = llext_seek(ldr, pos); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &sym, ent_size); + if (ret != 0) { + goto out; + } + + pos += ent_size; + + uint32_t stt = ELF_ST_TYPE(sym.st_info); + uint32_t stb = ELF_ST_BIND(sym.st_info); + uint32_t sect = sym.st_shndx; + + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + sym.st_name); + if (ret != 0) { + goto out; + } + + llext_read(ldr, name, sizeof(name)); + if (ret != 0) { + goto out; + } + + if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) { + ext->sym_tab.syms[j].name = k_heap_alloc(&llext_heap, + sizeof(name), + K_NO_WAIT); + strcpy(ext->sym_tab.syms[j].name, name); + ext->sym_tab.syms[j].addr = + (void *)((uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]] + + sym.st_value); + LOG_DBG("function symbol %d name %s addr %p", + j, name, ext->sym_tab.syms[j].addr); + j++; + } + } + +out: + return ret; +} + +static int llext_link(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + uintptr_t loc = 0; + elf_shdr_t shdr; + elf_rel_t rel; + elf_sym_t sym; + size_t pos = ldr->hdr.e_shoff; + elf_word rel_cnt = 0; + char name[32]; + + for (int i = 0; i < ldr->hdr.e_shnum - 1; i++) { + ret = llext_seek(ldr, pos); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); + if (ret != 0) { + goto out; + } + + pos += ldr->hdr.e_shentsize; + + /* find relocation sections */ + if (shdr.sh_type != SHT_REL && shdr.sh_type != SHT_RELA) { + continue; + } + + rel_cnt = shdr.sh_size / sizeof(elf_rel_t); + + + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SHSTRTAB].sh_offset + shdr.sh_name); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, name, sizeof(name)); + if (ret != 0) { + goto out; + } + + if (strncmp(name, ".rel.text", sizeof(name)) == 0 || + strncmp(name, ".rela.text", sizeof(name)) == 0) { + loc = (uintptr_t)ext->mem[LLEXT_MEM_TEXT]; + } else if (strncmp(name, ".rel.bss", sizeof(name)) == 0) { + loc = (uintptr_t)ext->mem[LLEXT_MEM_BSS]; + } else if (strncmp(name, ".rel.rodata", sizeof(name)) == 0) { + loc = (uintptr_t)ext->mem[LLEXT_MEM_RODATA]; + } else if (strncmp(name, ".rel.data", sizeof(name)) == 0) { + loc = (uintptr_t)ext->mem[LLEXT_MEM_DATA]; + } + + LOG_DBG("relocation section %s (%d) linked to section %d has %d relocations", + name, i, shdr.sh_link, rel_cnt); + + for (int j = 0; j < rel_cnt; j++) { + /* get each relocation entry */ + ret = llext_seek(ldr, shdr.sh_offset + j * sizeof(elf_rel_t)); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &rel, sizeof(elf_rel_t)); + if (ret != 0) { + goto out; + } + + /* get corresponding symbol */ + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SYMTAB].sh_offset + + ELF_R_SYM(rel.r_info) * sizeof(elf_sym_t)); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, &sym, sizeof(elf_sym_t)); + if (ret != 0) { + goto out; + } + + ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + + sym.st_name); + if (ret != 0) { + goto out; + } + + ret = llext_read(ldr, name, sizeof(name)); + if (ret != 0) { + goto out; + } + + LOG_DBG("relocation %d:%d info %x (type %d, sym %d) offset %d sym_name " + "%s sym_type %d sym_bind %d sym_ndx %d", + i, j, rel.r_info, ELF_R_TYPE(rel.r_info), ELF_R_SYM(rel.r_info), + rel.r_offset, name, ELF_ST_TYPE(sym.st_info), + ELF_ST_BIND(sym.st_info), sym.st_shndx); + + uintptr_t link_addr, op_loc, op_code; + + /* If symbol is undefined, then we need to look it up */ + if (sym.st_shndx == SHN_UNDEF) { + link_addr = (uintptr_t)llext_find_sym(NULL, name); + + if (link_addr == 0) { + LOG_ERR("Undefined symbol with no entry in " + "symbol table %s, offset %d, link section %d", + name, rel.r_offset, shdr.sh_link); + ret = -ENODATA; + goto out; + } else { + op_code = (uintptr_t)(loc + rel.r_offset); + + LOG_INF("found symbol %s at 0x%lx, updating op code 0x%lx", + name, link_addr, op_code); + } + } else if (ELF_ST_TYPE(sym.st_info) == STT_SECTION) { + link_addr = (uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]]; + + LOG_INF("found section symbol %s addr 0x%lx", name, link_addr); + } else { + /* Nothing to relocate here */ + continue; + } + + op_loc = loc + rel.r_offset; + + LOG_INF("relocating (linking) symbol %s type %d binding %d ndx %d offset " + "%d link section %d", + name, ELF_ST_TYPE(sym.st_info), ELF_ST_BIND(sym.st_info), + sym.st_shndx, rel.r_offset, shdr.sh_link); + + LOG_INF("writing relocation symbol %s type %d sym %d at addr 0x%lx " + "addr 0x%lx", + name, ELF_R_TYPE(rel.r_info), ELF_R_SYM(rel.r_info), + op_loc, link_addr); + + /* relocation */ + arch_elf_relocate(&rel, op_loc, link_addr); + } + } + +out: + return ret; +} + +/* + * Load a valid ELF as an extension + */ +static int do_llext_load(struct llext_loader *ldr, struct llext *ext) +{ + int ret = 0; + + memset(ldr->sects, 0, sizeof(ldr->sects)); + ldr->sect_cnt = 0; + ldr->sym_cnt = 0; + + size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(uint32_t); + + ldr->sect_map = k_heap_alloc(&llext_heap, sect_map_sz, K_NO_WAIT); + if (!ldr->sect_map) { + LOG_ERR("Failed to allocate memory for section map, size %u", sect_map_sz); + ret = -ENOMEM; + goto out; + } + memset(ldr->sect_map, 0, ldr->hdr.e_shnum*sizeof(uint32_t)); + ldr->sect_cnt = ldr->hdr.e_shnum; + + LOG_DBG("Finding ELF tables..."); + ret = llext_find_tables(ldr); + if (ret != 0) { + LOG_ERR("Failed to find important ELF tables, ret %d", ret); + goto out; + } + + LOG_DBG("Mapping ELF sections..."); + ret = llext_map_sections(ldr); + if (ret != 0) { + LOG_ERR("Failed to map ELF sections, ret %d", ret); + goto out; + } + + LOG_DBG("Allocation memory for ELF sections..."); + ret = llext_allocate_mem(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to map memory for ELF sections, ret %d", ret); + goto out; + } + + LOG_DBG("Copying sections..."); + ret = llext_copy_sections(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to copy ELF sections, ret %d", ret); + goto out; + } + + LOG_DBG("Counting exported symbols..."); + ret = llext_count_export_syms(ldr); + if (ret != 0) { + LOG_ERR("Failed to count exported ELF symbols, ret %d", ret); + goto out; + } + + LOG_DBG("Allocating memory for symbol table..."); + ret = llext_allocate_symtab(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to allocate extension symbol table, ret %d", ret); + goto out; + } + + LOG_DBG("Copying symbols..."); + ret = llext_copy_symbols(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to copy symbols, ret %d", ret); + goto out; + } + + LOG_DBG("Linking ELF..."); + ret = llext_link(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to link, ret %d", ret); + goto out; + } + +out: + if (ldr->sect_map != NULL) { + k_heap_free(&llext_heap, ldr->sect_map); + } + + if (ret != 0) { + LOG_DBG("Failed to load extension, freeing memory..."); + for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { + if (ext->mem[mem_idx] != NULL) { + k_heap_free(&llext_heap, ext->mem[mem_idx]); + } + } + for (int i = 0; i < ext->sym_tab.sym_cnt; i++) { + if (ext->sym_tab.syms[i].name != NULL) { + k_heap_free(&llext_heap, ext->sym_tab.syms[i].name); + } + } + k_heap_free(&llext_heap, ext->sym_tab.syms); + } else { + LOG_DBG("loaded module, .text at %p, .rodata at %p", ext->mem[LLEXT_MEM_TEXT], + ext->mem[LLEXT_MEM_RODATA]); + } + + return ret; +} + +int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) +{ + int ret = 0; + elf_ehdr_t ehdr; + + ret = llext_seek(ldr, 0); + if (ret != 0) { + LOG_ERR("Failed to seek for ELF header"); + goto out; + } + + ret = llext_read(ldr, &ehdr, sizeof(ehdr)); + if (ret != 0) { + LOG_ERR("Failed to read ELF header"); + goto out; + } + + /* check whether this is an valid elf file */ + if (memcmp(ehdr.e_ident, ELF_MAGIC, sizeof(ELF_MAGIC)) != 0) { + LOG_HEXDUMP_ERR(ehdr.e_ident, 16, "Invalid ELF, magic does not match"); + ret = -EINVAL; + goto out; + } + + switch (ehdr.e_type) { + case ET_REL: + case ET_DYN: + LOG_DBG("Loading relocatable or shared elf"); + *ext = k_heap_alloc(&llext_heap, sizeof(struct llext), K_NO_WAIT); + if (*ext == NULL) { + LOG_ERR("Not enough memory for extension metadata"); + ret = -ENOMEM; + goto out; + } + memset(*ext, 0, sizeof(struct llext)); + + for (int i = 0; i < LLEXT_MEM_COUNT; i++) { + (*ext)->mem[i] = NULL; + } + + ldr->hdr = ehdr; + ret = do_llext_load(ldr, *ext); + break; + default: + LOG_ERR("Unsupported elf file type %x", ehdr.e_type); + *ext = NULL; + ret = -EINVAL; + goto out; + } + + if (ret == 0) { + strncpy((*ext)->name, name, sizeof((*ext)->name)); + (*ext)->name[sizeof((*ext)->name) - 1] = '\0'; + sys_slist_append(&_llext_list, &(*ext)->_llext_list); + LOG_INF("Loaded extension %s", (*ext)->name); + } + +out: + return ret; +} + +void llext_unload(struct llext *ext) +{ + __ASSERT(ext, "Expected non-null extension"); + + sys_slist_find_and_remove(&_llext_list, &ext->_llext_list); + + for (int i = 0; i < LLEXT_MEM_COUNT; i++) { + if (ext->mem[i] != NULL) { + LOG_DBG("freeing memory region %d", i); + k_heap_free(&llext_heap, ext->mem[i]); + ext->mem[i] = NULL; + } + } + + if (ext->sym_tab.syms != NULL) { + for (int i = 0; i < ext->sym_tab.sym_cnt; i++) { + k_heap_free(&llext_heap, ext->sym_tab.syms[i].name); + } + k_heap_free(&llext_heap, ext->sym_tab.syms); + } + + k_heap_free(&llext_heap, ext); +} + +int llext_call_fn(struct llext *ext, const char *sym_name) +{ + void (*fn)(void); + + fn = llext_find_sym(&ext->sym_tab, sym_name); + if (fn == NULL) { + return -EINVAL; + } + fn(); + + return 0; +} diff --git a/subsys/llext/shell.c b/subsys/llext/shell.c new file mode 100644 index 00000000000..fe50365431c --- /dev/null +++ b/subsys/llext/shell.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(llext_shell, CONFIG_LLEXT_LOG_LEVEL); + +#define LLEXT_LIST_HELP "List loaded extensions and their size in memory" + +#define LLEXT_LOAD_HEX_HELP \ + "Load an elf file encoded in hex directly from the shell input. Syntax:\n" \ + " " + +#define LLEXT_UNLOAD_HELP \ + "Unload an extension by name. Syntax:\n" \ + "" + +#define LLEXT_LIST_SYMBOLS_HELP \ + "List extension symbols. Syntax:\n" \ + "" + +#define LLEXT_CALL_FN_HELP \ + "Call extension function with prototype void fn(void). Syntax:\n" \ + " " + +static int cmd_llext_list_symbols(const struct shell *sh, size_t argc, char *argv[]) +{ + struct llext *m = llext_by_name(argv[1]); + + if (m == NULL) { + shell_print(sh, "No such llext %s", argv[1]); + return -EINVAL; + } + + shell_print(sh, "Extension: %s symbols", m->name); + shell_print(sh, "| Symbol | Address |\n"); + for (elf_word i = 0; i < m->sym_tab.sym_cnt; i++) { + shell_print(sh, "| %16s | %p |\n", m->sym_tab.syms[i].name, + m->sym_tab.syms[i].addr); + } + + return 0; +} + +static void llext_name_get(size_t idx, struct shell_static_entry *entry) +{ + sys_slist_t *ext_list = llext_list(); + sys_snode_t *node = sys_slist_peek_head(ext_list); + + entry->syntax = NULL; + + for (int i = 0; i < idx; i++) { + node = sys_slist_peek_next(node); + + if (node == NULL) { + goto out; + } + } + + struct llext *ext = CONTAINER_OF(node, struct llext, _llext_list); + + entry->syntax = ext->name; +out: + entry->syntax = NULL; + entry->help = NULL; + entry->subcmd = NULL; + +} + +SHELL_DYNAMIC_CMD_CREATE(msub_llext_name, llext_name_get); + +static int cmd_llext_list(const struct shell *sh, size_t argc, char *argv[]) +{ + sys_snode_t *node; + struct llext *ext; + + shell_print(sh, "| Name | Size |\n"); + SYS_SLIST_FOR_EACH_NODE(llext_list(), node) { + ext = CONTAINER_OF(node, struct llext, _llext_list); + shell_print(sh, "| %16s | %12d |\n", ext->name, ext->mem_size); + } + + return 0; +} + +#define LLEXT_MAX_SIZE 8192 +static uint8_t llext_buf[LLEXT_MAX_SIZE]; + +static int cmd_llext_load_hex(const struct shell *sh, size_t argc, char *argv[]) +{ + char name[16]; + size_t hex_len = strnlen(argv[2], LLEXT_MAX_SIZE*2+1); + size_t bin_len = hex_len/2; + + if (bin_len > LLEXT_MAX_SIZE) { + shell_print(sh, "Extension %d bytes too large to load, max %d bytes\n", hex_len/2, + LLEXT_MAX_SIZE); + return -ENOMEM; + } + + strncpy(name, argv[1], sizeof(name)); + + size_t llext_buf_len = hex2bin(argv[2], hex_len, llext_buf, LLEXT_MAX_SIZE); + struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(llext_buf, llext_buf_len); + struct llext_loader *ldr = &buf_loader.loader; + + LOG_DBG("hex2bin hex len %d, llext buf sz %d, read %d", + hex_len, LLEXT_MAX_SIZE, llext_buf_len); + LOG_HEXDUMP_DBG(llext_buf, 4, "4 byte MAGIC"); + + struct llext *ext; + int res = llext_load(ldr, name, &ext); + + if (res == 0) { + shell_print(sh, "Successfully loaded extension %s, addr %p\n", ext->name, ext); + } else { + shell_print(sh, "Failed to load extension %s, return code %d\n", name, res); + } + + return 0; +} + +static int cmd_llext_unload(const struct shell *sh, size_t argc, char *argv[]) +{ + struct llext *ext = llext_by_name(argv[1]); + + if (ext == NULL) { + shell_print(sh, "No such extension %s", argv[1]); + return -EINVAL; + } + + llext_unload(ext); + shell_print(sh, "Unloaded extension %s\n", argv[1]); + + return 0; +} + +static int cmd_llext_call_fn(const struct shell *sh, size_t argc, char *argv[]) +{ + struct llext *ext = llext_by_name(argv[1]); + + if (ext == NULL) { + shell_print(sh, "No such extension %s", argv[1]); + return -EINVAL; + } + + llext_call_fn(ext, argv[2]); + + return 0; +} + + +/* clang-format off */ +SHELL_STATIC_SUBCMD_SET_CREATE(sub_llext, + SHELL_CMD(list, NULL, LLEXT_LIST_HELP, cmd_llext_list), + SHELL_CMD_ARG(load_hex, NULL, LLEXT_LOAD_HEX_HELP, cmd_llext_load_hex, + 3, 0), + SHELL_CMD_ARG(unload, &msub_llext_name, LLEXT_UNLOAD_HELP, cmd_llext_unload, 2, 0), + SHELL_CMD_ARG(list_symbols, &msub_llext_name, LLEXT_LIST_SYMBOLS_HELP, + cmd_llext_list_symbols, 2, 0), + SHELL_CMD_ARG(call_fn, &msub_llext_name, LLEXT_CALL_FN_HELP, + cmd_llext_call_fn, 3, 0), + + SHELL_SUBCMD_SET_END + ); +/* clang-format on */ + +SHELL_CMD_REGISTER(llext, &sub_llext, "Loadable extension commands", NULL); From 09f38b5f2009944645c4bdea924e17f9f3752166 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 27 Sep 2023 08:12:45 -0500 Subject: [PATCH 1467/4498] docs: Add documentation for llext Adds a basic overview and API docs for llext. Signed-off-by: Tom Burdick --- doc/develop/api/overview.rst | 4 ++++ doc/services/index.rst | 1 + doc/services/llext/index.rst | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 doc/services/llext/index.rst diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 33f0295d16a..decb3e73972 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -201,6 +201,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Unstable - 1.9 + * - :ref:`llext` + - Experimental + - 3.5 + * - :ref:`logging_api` - Stable - 1.13 diff --git a/doc/services/index.rst b/doc/services/index.rst index 286d2d2c14b..87bebc24379 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -16,6 +16,7 @@ OS Services formatted_output.rst input/index.rst ipc/index.rst + llext/index.rst logging/index.rst tracing/index.rst resource_management/index.rst diff --git a/doc/services/llext/index.rst b/doc/services/llext/index.rst new file mode 100644 index 00000000000..d742f198530 --- /dev/null +++ b/doc/services/llext/index.rst @@ -0,0 +1,30 @@ +.. _llext: + +Linkable Loadable Extensions (LLEXT) +#################################### + +The llext subsystem provides a toolbox for extending the functionality of an +application at runtime with linkable loadable code. + +Extensions can be loaded from precompiled ELF formatted data which is +verified, loaded, and linked with other extensions. Extensions can be +manipulated and introspected to some degree, as well as unloaded when no longer +needed. + +An extension may be loaded using any implementation of a :c:struct:`llext_loader` +which has a set of function pointers that provide the necessary functionality +to read the ELF data. A loader also provides some minimal context (memory) +needed by the :c:func:`llext_load` function. An implementation over a buffer +containing an ELF in addressable memory in memory is available as +:c:struct:`llext_buf_loader`. + +API Reference +************* + +.. doxygengroup:: llext + +.. doxygengroup:: llext_symbols + +.. doxygengroup:: llext_loader + +.. doxygengroup:: llext_buf_loader From b7f3182f79561fb4b2ba113dc4f081d9b99b1405 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 27 Sep 2023 08:14:45 -0500 Subject: [PATCH 1468/4498] llext: Simple hello world test case Adds a very simple hello world test case for llext. The loadable extension is built and then included as a binary array into the test making it very easy to load, debug, and inspect. The extension is built using the same toolchain as the base image by default. Signed-off-by: Tom Burdick --- tests/subsys/llext/CMakeLists.txt | 26 ++++++++++ tests/subsys/llext/hello_world/CMakeLists.txt | 17 +++++++ tests/subsys/llext/hello_world/hello_world.c | 25 +++++++++ tests/subsys/llext/prj.conf | 8 +++ tests/subsys/llext/src/test_llext_simple.c | 51 +++++++++++++++++++ tests/subsys/llext/testcase.yaml | 11 ++++ 6 files changed, 138 insertions(+) create mode 100644 tests/subsys/llext/CMakeLists.txt create mode 100644 tests/subsys/llext/hello_world/CMakeLists.txt create mode 100644 tests/subsys/llext/hello_world/hello_world.c create mode 100644 tests/subsys/llext/prj.conf create mode 100644 tests/subsys/llext/src/test_llext_simple.c create mode 100644 tests/subsys/llext/testcase.yaml diff --git a/tests/subsys/llext/CMakeLists.txt b/tests/subsys/llext/CMakeLists.txt new file mode 100644 index 00000000000..adb199761dd --- /dev/null +++ b/tests/subsys/llext/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2023 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(llext_test) + +add_subdirectory(hello_world) + +target_sources(app PRIVATE src/test_llext_simple.c) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/include + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/${ARCH}/include + ) + +set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/) + +generate_inc_file_for_target( + app + ${HELLO_WORLD_LLEXT} + ${gen_dir}/hello_world.inc + ) + +add_dependencies(app hello_world) diff --git a/tests/subsys/llext/hello_world/CMakeLists.txt b/tests/subsys/llext/hello_world/CMakeLists.txt new file mode 100644 index 00000000000..1a16d4be26b --- /dev/null +++ b/tests/subsys/llext/hello_world/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(hello_world) + +# TODO check which architecture is being used +set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb") + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c -o ${PROJECT_BINARY_DIR}/hello_world.llext ${PROJECT_SOURCE_DIR}/hello_world.c +) + +set(HELLO_WORLD_LLEXT ${PROJECT_BINARY_DIR}/hello_world.llext PARENT_SCOPE) + +add_custom_target(hello_world DEPENDS ${PROJECT_BINARY_DIR}/hello_world.llext) diff --git a/tests/subsys/llext/hello_world/hello_world.c b/tests/subsys/llext/hello_world/hello_world.c new file mode 100644 index 00000000000..4f5c5eed526 --- /dev/null +++ b/tests/subsys/llext/hello_world/hello_world.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This very simple hello world C code can be used as a test case for building + * probably the simplest loadable extension. It requires a single symbol be + * linked, section relocation support, and the ability to export and call out to + * a function. + */ + +/* Various build options should be documented here to generate the test elf for + * each architecture. + * + * armv7-thumb: -mlong-call -mthumb -c -o hello_world_armv7_thumb.elf hello_world.c + */ + +extern void printk(char *fmt, ...); + +extern void hello_world(void) +{ + printk("hello world\n"); +} diff --git a/tests/subsys/llext/prj.conf b/tests/subsys/llext/prj.conf new file mode 100644 index 00000000000..e6f45708208 --- /dev/null +++ b/tests/subsys/llext/prj.conf @@ -0,0 +1,8 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=8192 +CONFIG_LOG=y +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_LLEXT=y +CONFIG_LLEXT_HEAP_SIZE=32 +CONFIG_LLEXT_LOG_LEVEL_DBG=y diff --git a/tests/subsys/llext/src/test_llext_simple.c b/tests/subsys/llext/src/test_llext_simple.c new file mode 100644 index 00000000000..ef0e62b93b5 --- /dev/null +++ b/tests/subsys/llext/src/test_llext_simple.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#ifdef CONFIG_ARM /* ARMV7 */ +const static uint8_t hello_world_elf[] __aligned(4) = { +#include "hello_world.inc" +}; +#endif + +/** + * Attempt to load, list, list symbols, call a fn, and unload a + * hello world extension for each supported architecture + * + * This requires a single linked symbol (printk) and a single + * exported symbol from the extension ( void hello_world(void)) + */ +ZTEST(llext, test_llext_simple) +{ + const char name[16] = {'h', 'e', 'l', 'l', 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + struct llext_buf_loader buf_loader = + LLEXT_BUF_LOADER(hello_world_elf, ARRAY_SIZE(hello_world_elf)); + struct llext_loader *loader = &buf_loader.loader; + struct llext *ext; + const void * const printk_fn = llext_find_sym(NULL, "printk"); + + zassert_equal(printk_fn, printk, "printk should be an exported symbol"); + + int res = llext_load(loader, name, &ext); + + zassert_ok(res, "load should succeed"); + + const void * const hello_world_fn = llext_find_sym(&ext->sym_tab, "hello_world"); + + zassert_not_null(hello_world_fn, "hello_world should be an exported symbol"); + + res = llext_call_fn(ext, "hello_world"); + + zassert_ok(res, "calling hello world should succeed"); + + llext_unload(ext); +} + +ZTEST_SUITE(llext, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml new file mode 100644 index 00000000000..6d493276b93 --- /dev/null +++ b/tests/subsys/llext/testcase.yaml @@ -0,0 +1,11 @@ +common: + tags: llext +tests: + llext.simple.arm: + filter: not CONFIG_CPU_HAS_MMU + arch_allow: arm + extra_configs: + - CONFIG_ARM_MPU=n + # Broken platforms + platform_exclude: + - nuvoton_pfm_m487 # See #63167 From 9c366973e410ea9fa6ecc0684d6af152fbc92638 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 27 Sep 2023 08:13:31 -0500 Subject: [PATCH 1469/4498] llext: Shell loader sample Adds a sample application that can be used for trying out llext with the shell. The docs cover how to load a hello world ELF on to the device, assuming its an arm v7 architecture. Signed-off-by: Tom Burdick --- samples/subsys/llext/llext.rst | 10 ++ .../subsys/llext/shell_loader/CMakeLists.txt | 9 ++ samples/subsys/llext/shell_loader/README.rst | 119 ++++++++++++++++++ samples/subsys/llext/shell_loader/prj.conf | 12 ++ samples/subsys/llext/shell_loader/sample.yaml | 14 +++ samples/subsys/llext/shell_loader/src/main.c | 15 +++ 6 files changed, 179 insertions(+) create mode 100644 samples/subsys/llext/llext.rst create mode 100644 samples/subsys/llext/shell_loader/CMakeLists.txt create mode 100644 samples/subsys/llext/shell_loader/README.rst create mode 100644 samples/subsys/llext/shell_loader/prj.conf create mode 100644 samples/subsys/llext/shell_loader/sample.yaml create mode 100644 samples/subsys/llext/shell_loader/src/main.c diff --git a/samples/subsys/llext/llext.rst b/samples/subsys/llext/llext.rst new file mode 100644 index 00000000000..f9001e2847b --- /dev/null +++ b/samples/subsys/llext/llext.rst @@ -0,0 +1,10 @@ +.. _llext-samples: + +Linkable Loadable Extension Samples +################################### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/samples/subsys/llext/shell_loader/CMakeLists.txt b/samples/subsys/llext/shell_loader/CMakeLists.txt new file mode 100644 index 00000000000..a9d5d832334 --- /dev/null +++ b/samples/subsys/llext/shell_loader/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(fs_shell) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/llext/shell_loader/README.rst b/samples/subsys/llext/shell_loader/README.rst new file mode 100644 index 00000000000..d24ff89478f --- /dev/null +++ b/samples/subsys/llext/shell_loader/README.rst @@ -0,0 +1,119 @@ +.. zephyr:code-sample:: llext-shell-loader + :name: Linkable loadable extensions shell module + :relevant-api: llext + + Manage loadable extensions using shell commands. + +Overview +******** + +This example provides shell access to the :ref:`llext` system and provides the +ability to manage loadable code extensions in the shell. + +Requirements +************ + +A board with shell capable console. + +Building +******** + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/llext/shell_loader + :goals: build + :compact: + +.. note:: You may need to disable memory protection for the sample to work (e.g. CONFIG_ARM_MPU=n). + +Running +******* + +Once the board has booted, you will be presented with a shell prompt. +All the llext system related commands are available as sub-commands of llext +which can be seen with llext help + +.. code-block:: console + + uart:~$ llext help + llext - Loadable extension commands + Subcommands: + list :List loaded extensions and their size in memory + load_hex :Load an elf file encoded in hex directly from the shell input. + Syntax: + + unload :Unload an extension by name. Syntax: + + list_symbols :List extension symbols. Syntax: + + call_fn :Call extension function with prototype void fn(void). Syntax: + + +A hello world C file can be found in tests/subsys/llext/hello_world/hello_world.c + +This can be built into a relocatable elf usable on arm v7 platforms. It can be +inspected with some binutils to see symbols, sections, and relocations. +Then using additional tools converted to a hex string usable by the llext +load_hex shell command. + +On a host machine with the zephyr sdk setup and the arm toolchain in PATH + +.. code-block:: console + + $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o hello_world.elf tests/subsys/llext/hello_world/hello_world.c + $ arm-zephyr-eabi-objdump -x -t hello_world.elf + + hello_world.elf: file format elf32-littlearm + hello_world.elf + architecture: armv4t, flags 0x00000011: + HAS_RELOC, HAS_SYMS + start address 0x00000000 + private flags = 0x5000000: [Version5 EABI] + + Sections: + Idx Name Size VMA LMA File off Algn + 0 .text 00000024 00000000 00000000 00000034 2**2 + CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE + 1 .data 00000000 00000000 00000000 00000058 2**0 + CONTENTS, ALLOC, LOAD, DATA + 2 .bss 00000000 00000000 00000000 00000058 2**0 + ALLOC + 3 .rodata 0000000d 00000000 00000000 00000058 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 4 .comment 00000021 00000000 00000000 00000065 2**0 + CONTENTS, READONLY + 5 .ARM.attributes 0000002a 00000000 00000000 00000086 2**0 + CONTENTS, READONLY + arm-zephyr-eabi-objdump: hello_world.elf: not a dynamic object + SYMBOL TABLE: + 00000000 l df *ABS* 00000000 hello_world.c + 00000000 l d .text 00000000 .text + 00000000 l d .data 00000000 .data + 00000000 l d .bss 00000000 .bss + 00000000 l d .rodata 00000000 .rodata + 00000000 l d .comment 00000000 .comment + 00000000 l d .ARM.attributes 00000000 .ARM.attributes + 00000000 g F .text 00000020 hello_world + 00000000 *UND* 00000000 printk + + + RELOCATION RECORDS FOR [.text]: + OFFSET TYPE VALUE + 00000018 R_ARM_ABS32 .rodata + 0000001c R_ARM_ABS32 printk + + $ xxd -p hello_world.elf | tr -d '\n' + + +The resulting hex string can be used to load the extension. + +.. code-block:: console + + uart:~$ llext load_hex hello_world 7f454c4601010100000000000000000001002800010000000000000000000000180200000000000534000000000028000b000a0080b500af044b1800044b00f009f8c046bd4680bc01bc004700000000000000001847c04668656c6c6f20776f726c640a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff00000000000000000000000003000100000000000000000000000000030003000000000000000000000000000300040000000000000000000000000003000500090000000000000000000000000005000c000000000000000000000000000100090000001800000000000000000001000c00000020000000000000000000010000000000000000000000000003000600000000000000000000000000030007000f0000000100000020000000120001001b0000000000000000000000100000000068656c6c6f2e630024640024740068656c6c6f5f776f726c64007072696e746b00000018000000020500001c000000020d0000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000024000000000000000000000004000000000000001b000000090000004000000000000000b40100001000000008000000010000000400000008000000250000000100000003000000000000005800000000000000000000000000000001000000000000002b00000008000000030000000000000058000000000000000000000000000000010000000000000030000000010000000200000000000000580000000d000000000000000000000004000000000000003800000001000000300000000000000065000000210000000000000000000000010000000100000041000000030000700000000000000000860000002a0000000000000000000000010000000000000001000000020000000000000000000000b0000000e0000000090000000c00000004000000100000000900000003000000000000000000000090010000220000000000000000000000010000000000000011000000030000000000000000000000c40100005100000000000000000000000100000000000000 + +This extension can then be seen in the list of loaded extensions (`list`), its symbols printed (`list_symbols`), and the hello_world +function which the extension exports can be called and run (`call_fn`). + +.. code-block:: console + + uart:~$ llext call_fn hello_world hello_world + hello world diff --git a/samples/subsys/llext/shell_loader/prj.conf b/samples/subsys/llext/shell_loader/prj.conf new file mode 100644 index 00000000000..678e5eb55ae --- /dev/null +++ b/samples/subsys/llext/shell_loader/prj.conf @@ -0,0 +1,12 @@ +CONFIG_LOG=y +CONFIG_LOG_MODE_IMMEDIATE=y + +CONFIG_SHELL=y +CONFIG_SHELL_CMD_BUFF_SIZE=32768 +CONFIG_SHELL_LOG_LEVEL_INF=y +CONFIG_SHELL_STACK_SIZE=8192 + +CONFIG_LLEXT=y +CONFIG_LLEXT_LOG_LEVEL_DBG=y +CONFIG_LLEXT_HEAP_SIZE=32 +CONFIG_LLEXT_SHELL=y diff --git a/samples/subsys/llext/shell_loader/sample.yaml b/samples/subsys/llext/shell_loader/sample.yaml new file mode 100644 index 00000000000..5ef2a080286 --- /dev/null +++ b/samples/subsys/llext/shell_loader/sample.yaml @@ -0,0 +1,14 @@ +sample: + description: Loadable extensions with shell sample + name: Extension loader shell +tests: + sample.llext.shell: + tags: shell llext + harness: keyboard + filter: not CONFIG_CPU_HAS_MMU + arch_allow: arm + extra_configs: + - CONFIG_ARM_MPU=n + # Broken platforms + platform_exclude: + - nuvoton_pfm_m487 # See #63167 diff --git a/samples/subsys/llext/shell_loader/src/main.c b/samples/subsys/llext/shell_loader/src/main.c new file mode 100644 index 00000000000..f22be157314 --- /dev/null +++ b/samples/subsys/llext/shell_loader/src/main.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#include +LOG_MODULE_REGISTER(app); + +int main(void) +{ + return 0; +} From 77e193eb03f4237e5c37d4905d703432e659085c Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 27 Sep 2023 09:51:38 -0500 Subject: [PATCH 1470/4498] llext: Maintainers file Adds to the maintainers file the llext subsystem making myself the maintainer and Guennadi Lyakh a collaborator. Signed-off-by: Tom Burdick --- MAINTAINERS.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1f4afcf3e83..a9f88ed9ccf 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3680,3 +3680,18 @@ zbus: - doc/services/zbus/ labels: - "area: zbus" + +"Linkable Loadable Extensions": + status: maintained + maintainers: + - teburd + collaborators: + - lyakh + files: + - samples/subsys/llext/ + - include/zephyr/llext/ + - tests/subsys/llext/ + - subsys/llext/ + - doc/services/llext/ + labels: + - "area: Linkable Loadable Extensions" From 2f003e59e40771f8205a708dc3c9e12118b468f3 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 11 May 2023 10:09:08 -0400 Subject: [PATCH 1471/4498] kernel: Re-factor k_mem_slab definition Rearranges the k_mem_slab fields so that information that describes how much of the memory slab is used is co-located. This will allow easier of its statistics into the object core statistics reporting framework. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 38 ++++++++++++---------- kernel/mem_slab.c | 36 +++++++++++--------- subsys/net/ip/net_shell.c | 16 ++++----- subsys/portability/cmsis_rtos_v2/mempool.c | 4 +-- tests/bluetooth/audio/mocks/src/mem_slab.c | 8 ++--- tests/net/bridge/src/main.c | 8 ++--- 6 files changed, 58 insertions(+), 52 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index c3f2562e567..17a364da900 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -4999,31 +4999,33 @@ __syscall void k_pipe_buffer_flush(struct k_pipe *pipe); * @cond INTERNAL_HIDDEN */ -struct k_mem_slab { - _wait_q_t wait_q; - struct k_spinlock lock; +struct k_mem_slab_info { uint32_t num_blocks; - size_t block_size; - char *buffer; - char *free_list; + size_t block_size; uint32_t num_used; #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION uint32_t max_used; #endif +}; + +struct k_mem_slab { + _wait_q_t wait_q; + struct k_spinlock lock; + char *buffer; + char *free_list; + struct k_mem_slab_info info; SYS_PORT_TRACING_TRACKING_FIELD(k_mem_slab) }; #define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \ - slab_num_blocks) \ - { \ - .wait_q = Z_WAIT_Q_INIT(&obj.wait_q), \ - .lock = {}, \ - .num_blocks = slab_num_blocks, \ - .block_size = slab_block_size, \ - .buffer = slab_buffer, \ - .free_list = NULL, \ - .num_used = 0, \ + slab_num_blocks) \ + { \ + .wait_q = Z_WAIT_Q_INIT(&obj.wait_q), \ + .lock = {}, \ + .buffer = slab_buffer, \ + .free_list = NULL, \ + .info = {slab_num_blocks, slab_block_size, 0} \ } @@ -5162,7 +5164,7 @@ extern void k_mem_slab_free(struct k_mem_slab *slab, void *mem); */ static inline uint32_t k_mem_slab_num_used_get(struct k_mem_slab *slab) { - return slab->num_used; + return slab->info.num_used; } /** @@ -5178,7 +5180,7 @@ static inline uint32_t k_mem_slab_num_used_get(struct k_mem_slab *slab) static inline uint32_t k_mem_slab_max_used_get(struct k_mem_slab *slab) { #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION - return slab->max_used; + return slab->info.max_used; #else ARG_UNUSED(slab); return 0; @@ -5197,7 +5199,7 @@ static inline uint32_t k_mem_slab_max_used_get(struct k_mem_slab *slab) */ static inline uint32_t k_mem_slab_num_free_get(struct k_mem_slab *slab) { - return slab->num_blocks - slab->num_used; + return slab->info.num_blocks - slab->info.num_used; } /** diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index 9c326536c38..aed02bd0f41 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -32,7 +32,7 @@ static int create_free_list(struct k_mem_slab *slab) char *p; /* blocks must be word aligned */ - CHECKIF(((slab->block_size | (uintptr_t)slab->buffer) & + CHECKIF(((slab->info.block_size | (uintptr_t)slab->buffer) & (sizeof(void *) - 1)) != 0U) { return -EINVAL; } @@ -40,10 +40,10 @@ static int create_free_list(struct k_mem_slab *slab) slab->free_list = NULL; p = slab->buffer; - for (j = 0U; j < slab->num_blocks; j++) { + for (j = 0U; j < slab->info.num_blocks; j++) { *(char **)p = slab->free_list; slab->free_list = p; - p += slab->block_size; + p += slab->info.block_size; } return 0; } @@ -79,14 +79,14 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, { int rc = 0; - slab->num_blocks = num_blocks; - slab->block_size = block_size; + slab->info.num_blocks = num_blocks; + slab->info.block_size = block_size; slab->buffer = buffer; - slab->num_used = 0U; + slab->info.num_used = 0U; slab->lock = (struct k_spinlock) {}; #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION - slab->max_used = 0U; + slab->info.max_used = 0U; #endif rc = create_free_list(slab); @@ -113,10 +113,11 @@ int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) /* take a free block */ *mem = slab->free_list; slab->free_list = *(char **)(slab->free_list); - slab->num_used++; + slab->info.num_used++; #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION - slab->max_used = MAX(slab->num_used, slab->max_used); + slab->info.max_used = MAX(slab->info.num_used, + slab->info.max_used); #endif result = 0; @@ -151,8 +152,9 @@ void k_mem_slab_free(struct k_mem_slab *slab, void *mem) k_spinlock_key_t key = k_spin_lock(&slab->lock); __ASSERT(((char *)mem >= slab->buffer) && - ((((char *)mem - slab->buffer) % slab->block_size) == 0) && - ((char *)mem <= (slab->buffer + (slab->block_size * (slab->num_blocks - 1)))), + ((((char *)mem - slab->buffer) % slab->info.block_size) == 0) && + ((char *)mem <= (slab->buffer + (slab->info.block_size * + (slab->info.num_blocks - 1)))), "Invalid memory pointer provided"); SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mem_slab, free, slab); @@ -170,7 +172,7 @@ void k_mem_slab_free(struct k_mem_slab *slab, void *mem) } *(char **) mem = slab->free_list; slab->free_list = (char *) mem; - slab->num_used--; + slab->info.num_used--; SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mem_slab, free, slab); @@ -185,10 +187,12 @@ int k_mem_slab_runtime_stats_get(struct k_mem_slab *slab, struct sys_memory_stat k_spinlock_key_t key = k_spin_lock(&slab->lock); - stats->allocated_bytes = slab->num_used * slab->block_size; - stats->free_bytes = (slab->num_blocks - slab->num_used) * slab->block_size; + stats->allocated_bytes = slab->info.num_used * slab->info.block_size; + stats->free_bytes = (slab->info.num_blocks - slab->info.num_used) * + slab->info.block_size; #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION - stats->max_allocated_bytes = slab->max_used * slab->block_size; + stats->max_allocated_bytes = slab->info.max_used * + slab->info.block_size; #else stats->max_allocated_bytes = 0; #endif @@ -207,7 +211,7 @@ int k_mem_slab_runtime_stats_reset_max(struct k_mem_slab *slab) k_spinlock_key_t key = k_spin_lock(&slab->lock); - slab->max_used = slab->num_used; + slab->info.max_used = slab->info.num_used; k_spin_unlock(&slab->lock, key); diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 00e4fff57d6..f00a83b7b64 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -4080,9 +4080,9 @@ static void context_info(struct net_context *context, void *user_data) #if defined(CONFIG_NET_BUF_POOL_USAGE) PR("%p\t%u\t%u\tETX\n", - slab, slab->num_blocks, k_mem_slab_num_free_get(slab)); + slab, slab->info.num_blocks, k_mem_slab_num_free_get(slab)); #else - PR("%p\t%d\tETX\n", slab, slab->num_blocks); + PR("%p\t%d\tETX\n", slab, slab->info.num_blocks); #endif info->are_external_pools = true; info->tx_slabs[info->pos] = slab; @@ -4133,10 +4133,10 @@ static int cmd_net_mem(const struct shell *sh, size_t argc, char *argv[]) PR("Address\t\tTotal\tAvail\tName\n"); PR("%p\t%d\t%u\tRX\n", - rx, rx->num_blocks, k_mem_slab_num_free_get(rx)); + rx, rx->info.num_blocks, k_mem_slab_num_free_get(rx)); PR("%p\t%d\t%u\tTX\n", - tx, tx->num_blocks, k_mem_slab_num_free_get(tx)); + tx, tx->info.num_blocks, k_mem_slab_num_free_get(tx)); PR("%p\t%d\t%ld\tRX DATA (%s)\n", rx_data, rx_data->buf_count, atomic_get(&rx_data->avail_count), rx_data->name); @@ -4146,8 +4146,8 @@ static int cmd_net_mem(const struct shell *sh, size_t argc, char *argv[]) #else PR("Address\t\tTotal\tName\n"); - PR("%p\t%d\tRX\n", rx, rx->num_blocks); - PR("%p\t%d\tTX\n", tx, tx->num_blocks); + PR("%p\t%d\tRX\n", rx, rx->info.num_blocks); + PR("%p\t%d\tTX\n", tx, tx->info.num_blocks); PR("%p\t%d\tRX DATA\n", rx_data, rx_data->buf_count); PR("%p\t%d\tTX DATA\n", tx_data, tx_data->buf_count); PR_INFO("Set %s to enable %s support.\n", @@ -4772,7 +4772,7 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) { - size_t last_offset = (slab->num_blocks - 1) * slab->block_size; + size_t last_offset = (slab->info.num_blocks - 1) * slab->info.block_size; size_t ptr_offset; /* Check if pointer fits into slab buffer area. */ @@ -4782,7 +4782,7 @@ static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) /* Check if pointer offset is correct. */ ptr_offset = ptr - slab->buffer; - if (ptr_offset % slab->block_size != 0) { + if (ptr_offset % slab->info.block_size != 0) { return false; } diff --git a/subsys/portability/cmsis_rtos_v2/mempool.c b/subsys/portability/cmsis_rtos_v2/mempool.c index 8ec08cbc752..183d3ac789a 100644 --- a/subsys/portability/cmsis_rtos_v2/mempool.c +++ b/subsys/portability/cmsis_rtos_v2/mempool.c @@ -172,7 +172,7 @@ uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) if (mslab == NULL) { return 0; } else { - return mslab->z_mslab.num_blocks; + return mslab->z_mslab.info.num_blocks; } } @@ -186,7 +186,7 @@ uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) if (mslab == NULL) { return 0; } else { - return mslab->z_mslab.block_size; + return mslab->z_mslab.info.block_size; } } diff --git a/tests/bluetooth/audio/mocks/src/mem_slab.c b/tests/bluetooth/audio/mocks/src/mem_slab.c index ec3ef196e5b..65209b848e5 100644 --- a/tests/bluetooth/audio/mocks/src/mem_slab.c +++ b/tests/bluetooth/audio/mocks/src/mem_slab.c @@ -9,20 +9,20 @@ int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) { - if (slab->num_used >= slab->num_blocks) { + if (slab->info.num_used >= slab->info.num_blocks) { *mem = NULL; return -ENOMEM; } - *mem = malloc(slab->block_size); + *mem = malloc(slab->info.block_size); zassert_not_null(*mem); - slab->num_used++; + slab->info.num_used++; return 0; } void k_mem_slab_free(struct k_mem_slab *slab, void *mem) { free(mem); - slab->num_used--; + slab->info.num_used--; } diff --git a/tests/net/bridge/src/main.c b/tests/net/bridge/src/main.c index 121c2683273..5bd533fe11b 100644 --- a/tests/net/bridge/src/main.c +++ b/tests/net/bridge/src/main.c @@ -183,8 +183,8 @@ static void get_free_packet_count(void) struct k_mem_slab *rx, *tx; net_pkt_get_info(&rx, &tx, NULL, NULL); - orig_rx_num_blocks = rx->num_blocks; - orig_tx_num_blocks = tx->num_blocks; + orig_rx_num_blocks = rx->info.num_blocks; + orig_tx_num_blocks = tx->info.num_blocks; } static void check_free_packet_count(void) @@ -192,8 +192,8 @@ static void check_free_packet_count(void) struct k_mem_slab *rx, *tx; net_pkt_get_info(&rx, &tx, NULL, NULL); - zassert_equal(rx->num_blocks, orig_rx_num_blocks, ""); - zassert_equal(tx->num_blocks, orig_tx_num_blocks, ""); + zassert_equal(rx->info.num_blocks, orig_rx_num_blocks, ""); + zassert_equal(tx->info.num_blocks, orig_tx_num_blocks, ""); } static void test_iface_setup(void) From baea37aeb431c87e947e02e5409b22fa4e918f20 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 12 May 2023 13:55:52 -0400 Subject: [PATCH 1472/4498] kernel: Re-factor sys_mem_blocks definition Rearranges the sys_mem_blocks fields so that information that describes how much of the memory block is used is co-located. This will allow easier of its statistics into the object core statistics reporting framework. Signed-off-by: Peter Mitsis --- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 2 +- include/zephyr/rtio/rtio.h | 13 ++- include/zephyr/sys/mem_blocks.h | 22 ++-- lib/os/mem_blocks.c | 103 ++++++++++-------- .../build_all/sensor/src/generic_test.c | 2 +- tests/lib/mem_blocks/src/main.c | 21 ++-- 6 files changed, 91 insertions(+), 72 deletions(-) diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index 899b75cefe4..55a9b1776a1 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -625,7 +625,7 @@ static int sys_mm_drv_mm_init(const struct device *dev) uint32_t avalible_memory_size = ace_hpsram_get_bank_count() * SRAM_BANK_SIZE; - L2_PHYS_SRAM_REGION.num_blocks = avalible_memory_size / CONFIG_MM_DRV_PAGE_SIZE; + L2_PHYS_SRAM_REGION.info.num_blocks = avalible_memory_size / CONFIG_MM_DRV_PAGE_SIZE; ret = calculate_memory_regions(UNUSED_L2_START_ALIGNED); CHECKIF(ret != 0) { diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 28481504962..ecbacb9a161 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -383,7 +383,7 @@ static inline size_t rtio_mempool_block_size(const struct rtio *r) if (r == NULL || r->block_pool == NULL) { return 0; } - return BIT(r->block_pool->blk_sz_shift); + return BIT(r->block_pool->info.blk_sz_shift); #endif } @@ -402,7 +402,7 @@ static inline uint16_t __rtio_compute_mempool_block_index(const struct rtio *r, uint32_t block_size = rtio_mempool_block_size(r); uintptr_t buff = (uintptr_t)mem_pool->buffer; - uint32_t buff_size = mem_pool->num_blocks * block_size; + uint32_t buff_size = mem_pool->info.num_blocks * block_size; if (addr < buff || addr >= buff + buff_size) { return UINT16_MAX; @@ -693,7 +693,7 @@ static inline int rtio_block_pool_alloc(struct rtio *r, size_t min_sz, static inline void rtio_block_pool_free(struct rtio *r, void *buf, uint32_t buf_len) { #ifdef CONFIG_RTIO_SYS_MEM_BLOCKS - size_t num_blks = buf_len >> r->block_pool->blk_sz_shift; + size_t num_blks = buf_len >> r->block_pool->info.blk_sz_shift; sys_mem_blocks_free_contiguous(r->block_pool, buf, num_blks); #endif @@ -1019,8 +1019,9 @@ static inline uint32_t rtio_cqe_compute_flags(struct rtio_iodev_sqe *iodev_sqe) if (iodev_sqe->sqe.op == RTIO_OP_RX && iodev_sqe->sqe.flags & RTIO_SQE_MEMPOOL_BUFFER) { struct rtio *r = iodev_sqe->r; struct sys_mem_blocks *mem_pool = r->block_pool; - int blk_index = (iodev_sqe->sqe.buf - mem_pool->buffer) >> mem_pool->blk_sz_shift; - int blk_count = iodev_sqe->sqe.buf_len >> mem_pool->blk_sz_shift; + int blk_index = (iodev_sqe->sqe.buf - mem_pool->buffer) >> + mem_pool->info.blk_sz_shift; + int blk_count = iodev_sqe->sqe.buf_len >> mem_pool->info.blk_sz_shift; flags = RTIO_CQE_FLAG_PREP_MEMPOOL(blk_index, blk_count); } @@ -1062,7 +1063,7 @@ static inline int z_impl_rtio_cqe_get_mempool_buffer(const struct rtio *r, struc *buff_len = blk_count * blk_size; __ASSERT_NO_MSG(*buff >= r->block_pool->buffer); __ASSERT_NO_MSG(*buff < - r->block_pool->buffer + blk_size * r->block_pool->num_blocks); + r->block_pool->buffer + blk_size * r->block_pool->info.num_blocks); return 0; } return -EINVAL; diff --git a/include/zephyr/sys/mem_blocks.h b/include/zephyr/sys/mem_blocks.h index 53f6cbf2bb2..77c37a75547 100644 --- a/include/zephyr/sys/mem_blocks.h +++ b/include/zephyr/sys/mem_blocks.h @@ -82,12 +82,17 @@ typedef sys_mem_blocks_t *(*sys_multi_mem_blocks_choice_fn_t) * @cond INTERNAL_HIDDEN */ -struct sys_mem_blocks { - /* Number of blocks */ - uint32_t num_blocks; +struct sys_mem_blocks_info { + uint32_t num_blocks; /* Total number of blocks */ + uint8_t blk_sz_shift; /* Bit shift for block size */ +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + uint32_t used_blocks; /* Current number of blocks in use */ + uint32_t max_used_blocks; /* Maximum number of blocks in use */ +#endif +}; - /* Bit shift for block size */ - uint8_t blk_sz_shift; +struct sys_mem_blocks { + struct sys_mem_blocks_info info; /* Memory block buffer */ uint8_t *buffer; @@ -98,11 +103,7 @@ struct sys_mem_blocks { #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS /* Spinlock guarding access to memory block internals */ struct k_spinlock lock; - - uint32_t used_blocks; - uint32_t max_used_blocks; #endif - }; struct sys_multi_mem_blocks { @@ -125,8 +126,7 @@ struct sys_multi_mem_blocks { _SYS_BITARRAY_DEFINE(_sys_mem_blocks_bitmap_##name, \ num_blks, mbmod); \ mbmod sys_mem_blocks_t name = { \ - .num_blocks = num_blks, \ - .blk_sz_shift = ilog2(blk_sz), \ + .info = {num_blks, ilog2(blk_sz)}, \ .buffer = buf, \ .bitmap = &_sys_mem_blocks_bitmap_##name, \ } diff --git a/lib/os/mem_blocks.c b/lib/os/mem_blocks.c index 3517a5705d9..e282a61108e 100644 --- a/lib/os/mem_blocks.c +++ b/lib/os/mem_blocks.c @@ -16,7 +16,6 @@ static void *alloc_blocks(sys_mem_blocks_t *mem_block, size_t num_blocks) size_t offset; int r; uint8_t *blk; - void *ret = NULL; #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS k_spinlock_key_t key = k_spin_lock(&mem_block->lock); @@ -24,29 +23,33 @@ static void *alloc_blocks(sys_mem_blocks_t *mem_block, size_t num_blocks) /* Find an unallocated block */ r = sys_bitarray_alloc(mem_block->bitmap, num_blocks, &offset); - if (r == 0) { - + if (r != 0) { #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS - mem_block->used_blocks += (uint32_t)num_blocks; - - if (mem_block->max_used_blocks < mem_block->used_blocks) { - mem_block->max_used_blocks = mem_block->used_blocks; - } - k_spin_unlock(&mem_block->lock, key); #endif + return NULL; + } - /* Calculate the start address of the newly allocated block */ - blk = mem_block->buffer + (offset << mem_block->blk_sz_shift); +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + mem_block->info.used_blocks += (uint32_t)num_blocks; - ret = blk; + if (mem_block->info.max_used_blocks < mem_block->info.used_blocks) { + mem_block->info.max_used_blocks = mem_block->info.used_blocks; } - return ret; + k_spin_unlock(&mem_block->lock, key); +#endif + + /* Calculate the start address of the newly allocated block */ + + blk = mem_block->buffer + (offset << mem_block->info.blk_sz_shift); + + return blk; } -static int free_blocks(sys_mem_blocks_t *mem_block, void *ptr, size_t num_blocks) +static int free_blocks(sys_mem_blocks_t *mem_block, void *ptr, + size_t num_blocks) { size_t offset; uint8_t *blk = ptr; @@ -58,8 +61,8 @@ static int free_blocks(sys_mem_blocks_t *mem_block, void *ptr, size_t num_blocks goto out; } - offset = (blk - mem_block->buffer) >> mem_block->blk_sz_shift; - if (offset >= mem_block->num_blocks) { + offset = (blk - mem_block->buffer) >> mem_block->info.blk_sz_shift; + if (offset >= mem_block->info.num_blocks) { ret = -EFAULT; goto out; } @@ -71,7 +74,7 @@ static int free_blocks(sys_mem_blocks_t *mem_block, void *ptr, size_t num_blocks #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS if (ret == 0) { - mem_block->used_blocks -= (uint32_t) num_blocks; + mem_block->info.used_blocks -= (uint32_t)num_blocks; } k_spin_unlock(&mem_block->lock, key); @@ -82,7 +85,7 @@ static int free_blocks(sys_mem_blocks_t *mem_block, void *ptr, size_t num_blocks } int sys_mem_blocks_alloc_contiguous(sys_mem_blocks_t *mem_block, size_t count, - void **out_block) + void **out_block) { int ret = 0; @@ -95,7 +98,7 @@ int sys_mem_blocks_alloc_contiguous(sys_mem_blocks_t *mem_block, size_t count, goto out; } - if (count > mem_block->num_blocks) { + if (count > mem_block->info.num_blocks) { /* Definitely not enough blocks to be allocated */ ret = -ENOMEM; goto out; @@ -111,11 +114,11 @@ int sys_mem_blocks_alloc_contiguous(sys_mem_blocks_t *mem_block, size_t count, *out_block = ptr; #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER heap_listener_notify_alloc(HEAP_ID_FROM_POINTER(mem_block), - ptr, count << mem_block->blk_sz_shift); + ptr, count << mem_block->info.blk_sz_shift); #endif out: - return ret; + return ret; } int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count, @@ -134,7 +137,7 @@ int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count, goto out; } - if (count > mem_block->num_blocks) { + if (count > mem_block->info.num_blocks) { /* Definitely not enough blocks to be allocated */ ret = -ENOMEM; goto out; @@ -151,7 +154,8 @@ int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count, #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER heap_listener_notify_alloc(HEAP_ID_FROM_POINTER(mem_block), - ptr, BIT(mem_block->blk_sz_shift)); + ptr, + BIT(mem_block->info.blk_sz_shift)); #endif } @@ -165,7 +169,8 @@ int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count, return ret; } -int sys_mem_blocks_is_region_free(sys_mem_blocks_t *mem_block, void *in_block, size_t count) +int sys_mem_blocks_is_region_free(sys_mem_blocks_t *mem_block, void *in_block, + size_t count) { bool result; size_t offset; @@ -174,11 +179,13 @@ int sys_mem_blocks_is_region_free(sys_mem_blocks_t *mem_block, void *in_block, s __ASSERT_NO_MSG(mem_block->bitmap != NULL); __ASSERT_NO_MSG(mem_block->buffer != NULL); - offset = ((uint8_t *)in_block - mem_block->buffer) >> mem_block->blk_sz_shift; + offset = ((uint8_t *)in_block - mem_block->buffer) >> + mem_block->info.blk_sz_shift; - __ASSERT_NO_MSG(offset + count <= mem_block->num_blocks); + __ASSERT_NO_MSG(offset + count <= mem_block->info.num_blocks); - result = sys_bitarray_is_region_cleared(mem_block->bitmap, count, offset); + result = sys_bitarray_is_region_cleared(mem_block->bitmap, count, + offset); return result; } @@ -196,9 +203,10 @@ int sys_mem_blocks_get(sys_mem_blocks_t *mem_block, void *in_block, size_t count goto out; } - offset = ((uint8_t *)in_block - mem_block->buffer) >> mem_block->blk_sz_shift; + offset = ((uint8_t *)in_block - mem_block->buffer) >> + mem_block->info.blk_sz_shift; - if (offset + count > mem_block->num_blocks) { + if (offset + count > mem_block->info.num_blocks) { /* Definitely not enough blocks to be allocated */ ret = -ENOMEM; goto out; @@ -208,7 +216,8 @@ int sys_mem_blocks_get(sys_mem_blocks_t *mem_block, void *in_block, size_t count k_spinlock_key_t key = k_spin_lock(&mem_block->lock); #endif - ret = sys_bitarray_test_and_set_region(mem_block->bitmap, count, offset, true); + ret = sys_bitarray_test_and_set_region(mem_block->bitmap, count, + offset, true); if (ret != 0) { #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS @@ -219,10 +228,10 @@ int sys_mem_blocks_get(sys_mem_blocks_t *mem_block, void *in_block, size_t count } #ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS - mem_block->used_blocks += (uint32_t)count; + mem_block->info.used_blocks += (uint32_t)count; - if (mem_block->max_used_blocks < mem_block->used_blocks) { - mem_block->max_used_blocks = mem_block->used_blocks; + if (mem_block->info.max_used_blocks < mem_block->info.used_blocks) { + mem_block->info.max_used_blocks = mem_block->info.used_blocks; } k_spin_unlock(&mem_block->lock, key); @@ -230,7 +239,7 @@ int sys_mem_blocks_get(sys_mem_blocks_t *mem_block, void *in_block, size_t count #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER heap_listener_notify_alloc(HEAP_ID_FROM_POINTER(mem_block), - in_block, count << mem_block->blk_sz_shift); + in_block, count << mem_block->info.blk_sz_shift); #endif out: @@ -254,7 +263,7 @@ int sys_mem_blocks_free(sys_mem_blocks_t *mem_block, size_t count, goto out; } - if (count > mem_block->num_blocks) { + if (count > mem_block->info.num_blocks) { ret = -EINVAL; goto out; } @@ -275,7 +284,7 @@ int sys_mem_blocks_free(sys_mem_blocks_t *mem_block, size_t count, * notifying at the end of function. */ heap_listener_notify_free(HEAP_ID_FROM_POINTER(mem_block), - ptr, BIT(mem_block->blk_sz_shift)); + ptr, BIT(mem_block->info.blk_sz_shift)); } #endif } @@ -297,7 +306,7 @@ int sys_mem_blocks_free_contiguous(sys_mem_blocks_t *mem_block, void *block, siz goto out; } - if (count > mem_block->num_blocks) { + if (count > mem_block->info.num_blocks) { ret = -EINVAL; goto out; } @@ -309,7 +318,7 @@ int sys_mem_blocks_free_contiguous(sys_mem_blocks_t *mem_block, void *block, siz } #ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER heap_listener_notify_free(HEAP_ID_FROM_POINTER(mem_block), - block, count << mem_block->blk_sz_shift); + block, count << mem_block->info.blk_sz_shift); #endif out: @@ -363,7 +372,7 @@ int sys_multi_mem_blocks_alloc(sys_multi_mem_blocks_t *group, ret = sys_mem_blocks_alloc(allocator, count, out_blocks); if ((ret == 0) && (blk_size != NULL)) { - *blk_size = BIT(allocator->blk_sz_shift); + *blk_size = BIT(allocator->info.blk_sz_shift); } out: @@ -395,7 +404,8 @@ int sys_multi_mem_blocks_free(sys_multi_mem_blocks_t *group, one_alloc = group->allocators[i]; start = one_alloc->buffer; - end = start + (BIT(one_alloc->blk_sz_shift) * one_alloc->num_blocks); + end = start + (BIT(one_alloc->info.blk_sz_shift) * + one_alloc->info.num_blocks); if (((uint8_t *)in_blocks[0] >= start) && ((uint8_t *)in_blocks[0] < end)) { @@ -422,12 +432,13 @@ int sys_mem_blocks_runtime_stats_get(sys_mem_blocks_t *mem_block, return -EINVAL; } - stats->allocated_bytes = mem_block->used_blocks << - mem_block->blk_sz_shift; - stats->free_bytes = (mem_block->num_blocks << mem_block->blk_sz_shift) - + stats->allocated_bytes = mem_block->info.used_blocks << + mem_block->info.blk_sz_shift; + stats->free_bytes = (mem_block->info.num_blocks << + mem_block->info.blk_sz_shift) - stats->allocated_bytes; - stats->max_allocated_bytes = mem_block->max_used_blocks << - mem_block->blk_sz_shift; + stats->max_allocated_bytes = mem_block->info.max_used_blocks << + mem_block->info.blk_sz_shift; return 0; } @@ -438,7 +449,7 @@ int sys_mem_blocks_runtime_stats_reset_max(sys_mem_blocks_t *mem_block) return -EINVAL; } - mem_block->max_used_blocks = mem_block->used_blocks; + mem_block->info.max_used_blocks = mem_block->info.used_blocks; return 0; } diff --git a/tests/drivers/build_all/sensor/src/generic_test.c b/tests/drivers/build_all/sensor/src/generic_test.c index 256a16cf3c6..42ac57e8f37 100644 --- a/tests/drivers/build_all/sensor/src/generic_test.c +++ b/tests/drivers/build_all/sensor/src/generic_test.c @@ -58,7 +58,7 @@ static void before(void *args) /* Wipe the mempool by marking every block free */ zassert_ok(sys_bitarray_clear_region(sensor_read_rtio_ctx.block_pool->bitmap, - sensor_read_rtio_ctx.block_pool->num_blocks, + sensor_read_rtio_ctx.block_pool->info.num_blocks, 0)); /* Flush the SQ and CQ */ diff --git a/tests/lib/mem_blocks/src/main.c b/tests/lib/mem_blocks/src/main.c index d7351a12058..4641a6db643 100644 --- a/tests/lib/mem_blocks/src/main.c +++ b/tests/lib/mem_blocks/src/main.c @@ -61,7 +61,8 @@ static bool check_buffer_bound(sys_mem_blocks_t *mem_block, void *ptr) uint8_t *start, *end, *ptr_u8; start = mem_block->buffer; - end = start + (BIT(mem_block->blk_sz_shift) * mem_block->num_blocks); + end = start + (BIT(mem_block->info.blk_sz_shift) * + mem_block->info.num_blocks); ptr_u8 = (uint8_t *)ptr; @@ -155,9 +156,11 @@ static void alloc_free(sys_mem_blocks_t *mem_block, zassert_equal(listener_mem[i], blocks[i][0], "Heap allocated pointer mismatched: %p != %p", listener_mem[i], blocks[i][0]); - zassert_equal(listener_size[i], BIT(mem_block->blk_sz_shift), + zassert_equal(listener_size[i], + BIT(mem_block->info.blk_sz_shift), "Heap allocated sized: %u != %u", - listener_size[i], BIT(mem_block->blk_sz_shift)); + listener_size[i], + BIT(mem_block->info.blk_sz_shift)); #endif } @@ -190,9 +193,11 @@ static void alloc_free(sys_mem_blocks_t *mem_block, zassert_equal(listener_mem[i], blocks[i][0], "Heap allocated pointer mismatched: %p != %p", listener_mem[i], blocks[i][0]); - zassert_equal(listener_size[i], BIT(mem_block->blk_sz_shift), + zassert_equal(listener_size[i], + BIT(mem_block->info.blk_sz_shift), "Heap allocated sized: %u != %u", - listener_size[i], BIT(mem_block->blk_sz_shift)); + listener_size[i], + BIT(mem_block->info.blk_sz_shift)); #endif } } @@ -701,7 +706,8 @@ ZTEST(lib_mem_block, test_mem_block_invalid_params) /* Fake a pointer */ blocks[0] = mem_block_01.buffer + - (BIT(mem_block_01.blk_sz_shift) * mem_block_01.num_blocks); + (BIT(mem_block_01.info.blk_sz_shift) * + mem_block_01.info.num_blocks); ret = sys_mem_blocks_free(&mem_block_01, 1, blocks); zassert_equal(ret, -EFAULT, "sys_mem_blocks_free should fail with -EFAULT but not"); @@ -791,7 +797,8 @@ ZTEST(lib_mem_block, test_multi_mem_block_invalid_params) /* Fake a pointer */ blocks[0] = mem_block_01.buffer + - (BIT(mem_block_01.blk_sz_shift) * mem_block_01.num_blocks); + (BIT(mem_block_01.info.blk_sz_shift) * + mem_block_01.info.num_blocks); ret = sys_multi_mem_blocks_free(&alloc_group, 1, blocks); zassert_equal(ret, -EINVAL, "sys_multi_mem_blocks_free should fail with -EINVAL but not"); From 9bedfd82a2ea8e9c8bdce625a58e18aa4df788d4 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 23 May 2023 18:36:04 -0400 Subject: [PATCH 1473/4498] kernel: Refactor CPU usage Refactors CPU usage (thread runtime stats) to make it easier to integrate with the object core statistics framework. Signed-off-by: Peter Mitsis --- include/zephyr/kernel_structs.h | 5 ++++- kernel/init.c | 3 ++- kernel/usage.c | 36 ++++++++++++++++----------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 728986686aa..4ead72479f8 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -141,7 +141,7 @@ struct _cpu { uint32_t usage0; #ifdef CONFIG_SCHED_THREAD_USAGE_ALL - struct k_cycle_stats usage; + struct k_cycle_stats *usage; #endif #endif @@ -183,6 +183,9 @@ struct z_kernel { #if defined(CONFIG_THREAD_MONITOR) struct k_thread *threads; /* singly linked list of ALL threads */ #endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + struct k_cycle_stats usage[CONFIG_MP_MAX_NUM_CPUS]; +#endif #if defined(CONFIG_SMP) && defined(CONFIG_SCHED_IPI_SUPPORTED) /* Need to signal an IPI at the next scheduling point */ diff --git a/kernel/init.c b/kernel/init.c index 3d5991f1fbe..dccbad6cb41 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -399,7 +399,8 @@ void z_init_cpu(int id) (Z_KERNEL_STACK_BUFFER(z_interrupt_stacks[id]) + K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[id])); #ifdef CONFIG_SCHED_THREAD_USAGE_ALL - _kernel.cpus[id].usage.track_usage = + _kernel.cpus[id].usage = &_kernel.usage[id]; + _kernel.cpus[id].usage->track_usage = CONFIG_SCHED_THREAD_USAGE_AUTO_ENABLE; #endif diff --git a/kernel/usage.c b/kernel/usage.c index a44c7552f5c..57a55a75759 100644 --- a/kernel/usage.c +++ b/kernel/usage.c @@ -35,22 +35,22 @@ static uint32_t usage_now(void) #ifdef CONFIG_SCHED_THREAD_USAGE_ALL static void sched_cpu_update_usage(struct _cpu *cpu, uint32_t cycles) { - if (!cpu->usage.track_usage) { + if (!cpu->usage->track_usage) { return; } if (cpu->current != cpu->idle_thread) { - cpu->usage.total += cycles; + cpu->usage->total += cycles; #ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS - cpu->usage.current += cycles; + cpu->usage->current += cycles; - if (cpu->usage.longest < cpu->usage.current) { - cpu->usage.longest = cpu->usage.current; + if (cpu->usage->longest < cpu->usage->current) { + cpu->usage->longest = cpu->usage->current; } } else { - cpu->usage.current = 0; - cpu->usage.num_windows++; + cpu->usage->current = 0; + cpu->usage->num_windows++; #endif } } @@ -148,16 +148,16 @@ void z_sched_cpu_usage(uint8_t cpu_id, struct k_thread_runtime_stats *stats) cpu->usage0 = now; } - stats->total_cycles = cpu->usage.total; + stats->total_cycles = cpu->usage->total; #ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS - stats->current_cycles = cpu->usage.current; - stats->peak_cycles = cpu->usage.longest; + stats->current_cycles = cpu->usage->current; + stats->peak_cycles = cpu->usage->longest; - if (cpu->usage.num_windows == 0) { + if (cpu->usage->num_windows == 0) { stats->average_cycles = 0; } else { stats->average_cycles = stats->total_cycles / - cpu->usage.num_windows; + cpu->usage->num_windows; } #endif @@ -282,7 +282,7 @@ void k_sys_runtime_stats_enable(void) key = k_spin_lock(&usage_lock); - if (_current_cpu->usage.track_usage) { + if (_current_cpu->usage->track_usage) { /* * Usage tracking is already enabled on the current CPU @@ -299,10 +299,10 @@ void k_sys_runtime_stats_enable(void) unsigned int num_cpus = arch_num_cpus(); for (uint8_t i = 0; i < num_cpus; i++) { - _kernel.cpus[i].usage.track_usage = true; + _kernel.cpus[i].usage->track_usage = true; #ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS - _kernel.cpus[i].usage.num_windows++; - _kernel.cpus[i].usage.current = 0; + _kernel.cpus[i].usage->num_windows++; + _kernel.cpus[i].usage->current = 0; #endif } @@ -316,7 +316,7 @@ void k_sys_runtime_stats_disable(void) key = k_spin_lock(&usage_lock); - if (!_current_cpu->usage.track_usage) { + if (!_current_cpu->usage->track_usage) { /* * Usage tracking is already disabled on the current CPU @@ -337,7 +337,7 @@ void k_sys_runtime_stats_disable(void) if (cpu->usage0 != 0) { sched_cpu_update_usage(cpu, now - cpu->usage0); } - cpu->usage.track_usage = false; + cpu->usage->track_usage = false; } k_spin_unlock(&usage_lock, key); From eb1e5a161d311ef3a79bb3b8cce8f0dbbe710d5a Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 31 May 2023 14:26:50 -0400 Subject: [PATCH 1474/4498] kernel: FIFO and LIFO have their own sections Instead of placing both FIFOs and LIFOs into a common k_queue type section, they are now placed into their own custom iterable secitons. This is necessary when employing object cores as FIFOs and LIFOs will be associated with different lists. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 4 ++-- include/zephyr/linker/common-ram.ld | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 17a364da900..f56a2ffeb98 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -2586,7 +2586,7 @@ struct k_fifo { * @param name Name of the FIFO queue. */ #define K_FIFO_DEFINE(name) \ - STRUCT_SECTION_ITERABLE_ALTERNATE(k_queue, k_fifo, name) = \ + STRUCT_SECTION_ITERABLE(k_fifo, name) = \ Z_FIFO_INITIALIZER(name) /** @} */ @@ -2706,7 +2706,7 @@ struct k_lifo { * @param name Name of the fifo. */ #define K_LIFO_DEFINE(name) \ - STRUCT_SECTION_ITERABLE_ALTERNATE(k_queue, k_lifo, name) = \ + STRUCT_SECTION_ITERABLE(k_lifo, name) = \ Z_LIFO_INITIALIZER(name) /** @} */ diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index b77e16a6182..9414941e9f0 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -84,6 +84,8 @@ ITERABLE_SECTION_RAM_GC_ALLOWED(k_sem, 4) ITERABLE_SECTION_RAM_GC_ALLOWED(k_event, 4) ITERABLE_SECTION_RAM_GC_ALLOWED(k_queue, 4) + ITERABLE_SECTION_RAM_GC_ALLOWED(k_fifo, 4) + ITERABLE_SECTION_RAM_GC_ALLOWED(k_lifo, 4) ITERABLE_SECTION_RAM_GC_ALLOWED(k_condvar, 4) ITERABLE_SECTION_RAM(net_buf_pool, 4) From 55db86e51272aeb07a66ae6d1263ac94a876bcad Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 9 May 2023 11:01:33 -0400 Subject: [PATCH 1475/4498] kernel: Add initial obj_core infrastructure Adds the initial object core infrastructure. Signed-off-by: Peter Mitsis --- include/zephyr/kernel/obj_core.h | 223 +++++++++++++++++++++++++++++++ include/zephyr/kernel_includes.h | 1 + kernel/CMakeLists.txt | 1 + kernel/Kconfig | 13 ++ kernel/obj_core.c | 119 +++++++++++++++++ 5 files changed, 357 insertions(+) create mode 100644 include/zephyr/kernel/obj_core.h create mode 100644 kernel/obj_core.c diff --git a/include/zephyr/kernel/obj_core.h b/include/zephyr/kernel/obj_core.h new file mode 100644 index 00000000000..2003f439e3f --- /dev/null +++ b/include/zephyr/kernel/obj_core.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __KERNEL_OBJ_CORE_H__ +#define __KERNEL_OBJ_CORE_H__ + +#include + +/** + * @defgroup obj_core_apis Object Core APIs + * @ingroup kernel_apis + * @{ + */ + +/** + * @brief Convert kernel object pointer into its object core pointer + */ +#define K_OBJ_CORE(kobj) (&((kobj)->obj_core)) + +/** + * @brief Generate new object type IDs based on a 4 letter string + */ +#define K_OBJ_TYPE_ID_GEN(s) ((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | (s[3])) + +/* Known kernel object types */ + +/** Condition variable object type */ +#define K_OBJ_TYPE_CONDVAR_ID K_OBJ_TYPE_ID_GEN("COND") +/** CPU object type */ +#define K_OBJ_TYPE_CPU_ID K_OBJ_TYPE_ID_GEN("CPU_") +/** Event object type */ +#define K_OBJ_TYPE_EVENT_ID K_OBJ_TYPE_ID_GEN("EVNT") +/** FIFO object type */ +#define K_OBJ_TYPE_FIFO_ID K_OBJ_TYPE_ID_GEN("FIFO") +/** Kernel object type */ +#define K_OBJ_TYPE_KERNEL_ID K_OBJ_TYPE_ID_GEN("KRNL") +/** LIFO object type */ +#define K_OBJ_TYPE_LIFO_ID K_OBJ_TYPE_ID_GEN("LIFO") +/** Memory block object type */ +#define K_OBJ_TYPE_MEM_BLOCK_ID K_OBJ_TYPE_ID_GEN("MBLK") +/** Mailbox object type */ +#define K_OBJ_TYPE_MBOX_ID K_OBJ_TYPE_ID_GEN("MBOX") +/** Memory slab object type */ +#define K_OBJ_TYPE_MEM_SLAB_ID K_OBJ_TYPE_ID_GEN("SLAB") +/** Message queue object type */ +#define K_OBJ_TYPE_MSGQ_ID K_OBJ_TYPE_ID_GEN("MSGQ") +/** Mutex object type */ +#define K_OBJ_TYPE_MUTEX_ID K_OBJ_TYPE_ID_GEN("MUTX") +/** Pipe object type */ +#define K_OBJ_TYPE_PIPE_ID K_OBJ_TYPE_ID_GEN("PIPE") +/** Semaphore object type */ +#define K_OBJ_TYPE_SEM_ID K_OBJ_TYPE_ID_GEN("SEM4") +/** Stack object type */ +#define K_OBJ_TYPE_STACK_ID K_OBJ_TYPE_ID_GEN("STCK") +/** Thread object type */ +#define K_OBJ_TYPE_THREAD_ID K_OBJ_TYPE_ID_GEN("THRD") +/** Timer object type */ +#define K_OBJ_TYPE_TIMER_ID K_OBJ_TYPE_ID_GEN("TIMR") + +struct k_obj_type; +struct k_obj_core; + +/** + * @cond INTERNAL_HIDDEN + */ + +#ifdef CONFIG_OBJ_CORE +#define K_OBJ_CORE_INIT(_objp, _obj_type) \ + extern struct k_obj_type _obj_type; \ + k_obj_core_init(_objp, &_obj_type) + +#define K_OBJ_CORE_LINK(objp) k_obj_core_link(objp) +#else +#define K_OBJ_CORE_INIT(objp, type) do { } while (0) +#define K_OBJ_CORE_LINK(objp) do { } while (0) +#endif + +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * Tools may use this list as an entry point to identify all registered + * object types and the object cores linked to them. + */ +extern sys_slist_t z_obj_type_list; + +/** Object type structure */ +struct k_obj_type { + sys_snode_t node; /**< Node within list of object types */ + sys_slist_t list; /**< List of objects of this object type */ + uint32_t id; /**< Unique type ID */ + size_t obj_core_offset; /**< Offset to obj_core field */ +}; + +/** Object core structure */ +struct k_obj_core { + sys_snode_t node; /**< Object node within object type's list */ + struct k_obj_type *type; /**< Object type to which object belongs */ +}; + +/** + * @brief Initialize a specific object type + * + * Initializes a specific object type and links it into the object core + * framework. + * + * @param type Pointer to the object type to initialize + * @param id A means to identify the object type + * @param off Offset of object core within the structure + * + * @retval Pointer to initialized object type + */ +struct k_obj_type *z_obj_type_init(struct k_obj_type *type, + uint32_t id, size_t off); + +/** + * @brief Find a specific object type by ID + * + * Given an object type ID, this function searches for the object type that + * is associated with the specified type ID @a type_id. + * + * @param type_id Type ID associated with object type + * + * @retval NULL if object type not found + * @retval Pointer to object type if found + */ +struct k_obj_type *k_obj_type_find(uint32_t type_id); + +/** + * @brief Walk the object type's list of object cores + * + * This function takes a global spinlock and walks the object type's list + * of object cores and invokes the callback function on each element while + * holding that lock. Although this will ensure that the list is not modified, + * one can expect a significant penalty in terms of performance and latency. + * + * The callback function shall either return non-zero to stop further walking, + * or it shall return 0 to continue walking. + * + * @param type Pointer to the object type + * @param func Callback to invoke on each object core of the object type + * @param data Custom data passed to the callback + * + * @retval non-zero if walk is terminated by the callback; otherwise 0 + */ +int k_obj_type_walk_locked(struct k_obj_type *type, + int (*func)(struct k_obj_core *, void *), + void *data); + +/** + * @brief Walk the object type's list of object cores + * + * This function is similar to k_obj_type_walk_locked() except that it walks + * the list without obtaining the global spinlock. No synchronization is + * provided here. Mutation of the list of objects while this function is in + * progress must be prevented at the application layer, otherwise + * undefined/unreliable behavior, corruption and/or crashes may result. + * + * The callback function shall either return non-zero to stop further walking, + * or it shall return 0 to continue walking. + * + * @param type Pointer to the object type + * @param func Callback to invoke on each object core of the object type + * @param data Custom data passed to the callback + * + * @retval non-zero if walk is terminated by the callback; otherwise 0 + */ +int k_obj_type_walk_unlocked(struct k_obj_type *type, + int (*func)(struct k_obj_core *, void *), + void *data); + +/** + * @brief Initialize the core of the kernel object + * + * Initializing the kernel object core associates it with the specified + * kernel object type. + * + * @param obj_core Pointer to the kernel object to initialize + * @param type Pointer to the kernel object type + */ +void k_obj_core_init(struct k_obj_core *obj_core, struct k_obj_type *type); + +/** + * @brief Link the kernel object to the kernel object type list + * + * A kernel object can be optionally linked into the kernel object type's + * list of objects. A kernel object must have been initialized before it + * can be linked. Linked kernel objects can be traversed and have information + * extracted from them by system tools. + * + * @param obj_core Pointer to the kernel object + */ +void k_obj_core_link(struct k_obj_core *obj_core); + +/** + * @brief Automatically link the kernel object after initializing it + * + * A useful wrapper to both initialize the core of the kernel object and + * automatically link it into the kernel object type's list of objects. + * + * @param obj_core Pointer to the kernel object to initialize + * @param type Pointer to the kernel object type + */ +void k_obj_core_init_and_link(struct k_obj_core *obj_core, + struct k_obj_type *type); + +/** + * @brief Unlink the kernel object from the kernel object type list + * + * Kernel objects can be unlinked from their respective kernel object type + * lists. If on a list, it must be done at the end of the kernel object's life + * cycle. + * + * @param obj_core Pointer to the kernel object + */ +void k_obj_core_unlink(struct k_obj_core *obj_core); + +/** @} */ +#endif /* __KERNEL_OBJ_CORE_H__ */ diff --git a/include/zephyr/kernel_includes.h b/include/zephyr/kernel_includes.h index f128fcc2c5c..31ea5fce751 100644 --- a/include/zephyr/kernel_includes.h +++ b/include/zephyr/kernel_includes.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 087e96b0812..e628cfec669 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -107,6 +107,7 @@ target_sources_ifdef(CONFIG_POLL kernel PRIVATE poll.c) target_sources_ifdef(CONFIG_EVENTS kernel PRIVATE events.c) target_sources_ifdef(CONFIG_PIPES kernel PRIVATE pipes.c) target_sources_ifdef(CONFIG_SCHED_THREAD_USAGE kernel PRIVATE usage.c) +target_sources_ifdef(CONFIG_OBJ_CORE kernel PRIVATE obj_core.c) if(${CONFIG_KERNEL_MEM_POOL}) target_sources(kernel PRIVATE mempool.c) diff --git a/kernel/Kconfig b/kernel/Kconfig index 7b4fd19c85f..5abbd158507 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -494,6 +494,19 @@ endif # THREAD_RUNTIME_STATS endmenu +menuconfig OBJ_CORE + bool "Object core framework" + default n + help + This option enables the object core framework. This will link + participating kernel objects and their respective types together + in a way that allows them to both have common information stored + together and for that information to be easily retrieved by + automated means. + +if OBJ_CORE +endif # OBJ_CORE + menu "Work Queue Options" config SYSTEM_WORKQUEUE_STACK_SIZE int "System workqueue stack size" diff --git a/kernel/obj_core.c b/kernel/obj_core.c new file mode 100644 index 00000000000..9f034868500 --- /dev/null +++ b/kernel/obj_core.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static struct k_spinlock lock; + +sys_slist_t z_obj_type_list = SYS_SLIST_STATIC_INIT(&z_obj_type_list); + +struct k_obj_type *z_obj_type_init(struct k_obj_type *type, + uint32_t id, size_t off) +{ + sys_slist_init(&type->list); + sys_slist_append(&z_obj_type_list, &type->node); + type->id = id; + type->obj_core_offset = off; + + return type; +} + +void k_obj_core_init(struct k_obj_core *obj_core, struct k_obj_type *type) +{ + obj_core->node.next = NULL; + obj_core->type = type; +} + +void k_obj_core_link(struct k_obj_core *obj_core) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + + sys_slist_append(&obj_core->type->list, &obj_core->node); + + k_spin_unlock(&lock, key); +} + +void k_obj_core_init_and_link(struct k_obj_core *obj_core, + struct k_obj_type *type) +{ + k_obj_core_init(obj_core, type); + k_obj_core_link(obj_core); +} + +void k_obj_core_unlink(struct k_obj_core *obj_core) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + + sys_slist_find_and_remove(&obj_core->type->list, &obj_core->node); + + k_spin_unlock(&lock, key); +} + +struct k_obj_type *k_obj_type_find(uint32_t type_id) +{ + struct k_obj_type *type; + struct k_obj_type *rv = NULL; + sys_snode_t *node; + + k_spinlock_key_t key = k_spin_lock(&lock); + + SYS_SLIST_FOR_EACH_NODE(&z_obj_type_list, node) { + type = CONTAINER_OF(node, struct k_obj_type, node); + if (type->id == type_id) { + rv = type; + break; + } + } + + k_spin_unlock(&lock, key); + + return rv; +} + +int k_obj_type_walk_locked(struct k_obj_type *type, + int (*func)(struct k_obj_core *, void *), + void *data) +{ + k_spinlock_key_t key; + struct k_obj_core *obj_core; + sys_snode_t *node; + int status = 0; + + key = k_spin_lock(&lock); + + SYS_SLIST_FOR_EACH_NODE(&type->list, node) { + obj_core = CONTAINER_OF(node, struct k_obj_core, node); + status = func(obj_core, data); + if (status != 0) { + break; + } + } + + k_spin_unlock(&lock, key); + + return status; +} + +int k_obj_type_walk_unlocked(struct k_obj_type *type, + int (*func)(struct k_obj_core *, void *), + void *data) +{ + struct k_obj_core *obj_core; + sys_snode_t *node; + sys_snode_t *next; + int status = 0; + + SYS_SLIST_FOR_EACH_NODE_SAFE(&type->list, node, next) { + obj_core = CONTAINER_OF(node, struct k_obj_core, node); + status = func(obj_core, data); + if (status != 0) { + break; + } + } + + return status; +} From 6df8efe3543230947ec38953b4496c2ea08f9e1c Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 11 May 2023 14:06:46 -0400 Subject: [PATCH 1476/4498] kernel: Integrate object cores into kernel Integrates object cores into the following kernel structures sys_mem_blocks, k_mem_slab _cpu, z_kernel k_thread, k_timer k_condvar, k_event, k_mutex, k_sem k_mbox, k_msgq, k_pipe, k_fifo, k_lifo, k_stack Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 82 ++++++++++++++++----- include/zephyr/kernel/thread.h | 4 ++ include/zephyr/kernel_structs.h | 9 +++ include/zephyr/linker/common-ram.ld | 1 + include/zephyr/sys/mem_blocks.h | 11 ++- kernel/Kconfig | 107 ++++++++++++++++++++++++++++ kernel/condvar.c | 31 ++++++++ kernel/events.c | 29 ++++++++ kernel/init.c | 39 +++++++++- kernel/mailbox.c | 30 ++++++++ kernel/mem_slab.c | 25 ++++++- kernel/msg_q.c | 30 ++++++++ kernel/mutex.c | 29 ++++++++ kernel/pipes.c | 29 ++++++++ kernel/queue.c | 46 ++++++++++++ kernel/sched.c | 4 ++ kernel/sem.c | 29 ++++++++ kernel/stack.c | 29 ++++++++ kernel/thread.c | 23 ++++++ kernel/timer.c | 28 ++++++++ lib/os/Kconfig.heap | 8 +++ lib/os/mem_blocks.c | 28 +++++++- 22 files changed, 629 insertions(+), 22 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index f56a2ffeb98..908bae10134 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1463,6 +1463,10 @@ struct k_timer { void *user_data; SYS_PORT_TRACING_TRACKING_FIELD(k_timer) + +#ifdef CONFIG_OBJ_CORE_TIMER + struct k_obj_core obj_core; +#endif }; #define Z_TIMER_INITIALIZER(obj, expiry, stop) \ @@ -2201,6 +2205,11 @@ struct k_event { struct k_spinlock lock; SYS_PORT_TRACING_TRACKING_FIELD(k_event) + +#ifdef CONFIG_OBJ_CORE_EVENT + struct k_obj_core obj_core; +#endif + }; #define Z_EVENT_INITIALIZER(obj) \ @@ -2359,6 +2368,9 @@ static inline uint32_t k_event_test(struct k_event *event, uint32_t events_mask) struct k_fifo { struct k_queue _queue; +#ifdef CONFIG_OBJ_CORE_FIFO + struct k_obj_core obj_core; +#endif }; /** @@ -2386,11 +2398,13 @@ struct k_fifo { * * @param fifo Address of the FIFO queue. */ -#define k_fifo_init(fifo) \ - ({ \ +#define k_fifo_init(fifo) \ + ({ \ SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_fifo, init, fifo); \ - k_queue_init(&(fifo)->_queue); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, init, fifo); \ + k_queue_init(&(fifo)->_queue); \ + K_OBJ_CORE_INIT(K_OBJ_CORE(fifo), _obj_type_fifo); \ + K_OBJ_CORE_LINK(K_OBJ_CORE(fifo)); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, init, fifo); \ }) /** @@ -2593,6 +2607,9 @@ struct k_fifo { struct k_lifo { struct k_queue _queue; +#ifdef CONFIG_OBJ_CORE_LIFO + struct k_obj_core obj_core; +#endif }; /** @@ -2621,11 +2638,13 @@ struct k_lifo { * * @param lifo Address of the LIFO queue. */ -#define k_lifo_init(lifo) \ - ({ \ +#define k_lifo_init(lifo) \ + ({ \ SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_lifo, init, lifo); \ - k_queue_init(&(lifo)->_queue); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, init, lifo); \ + k_queue_init(&(lifo)->_queue); \ + K_OBJ_CORE_INIT(K_OBJ_CORE(lifo), _obj_type_lifo); \ + K_OBJ_CORE_LINK(K_OBJ_CORE(lifo)); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, init, lifo); \ }) /** @@ -2726,6 +2745,10 @@ struct k_stack { uint8_t flags; SYS_PORT_TRACING_TRACKING_FIELD(k_stack) + +#ifdef CONFIG_OBJ_CORE_STACK + struct k_obj_core obj_core; +#endif }; #define Z_STACK_INITIALIZER(obj, stack_buffer, stack_num_entries) \ @@ -2882,6 +2905,10 @@ struct k_mutex { int owner_orig_prio; SYS_PORT_TRACING_TRACKING_FIELD(k_mutex) + +#ifdef CONFIG_OBJ_CORE_MUTEX + struct k_obj_core obj_core; +#endif }; /** @@ -2979,6 +3006,10 @@ __syscall int k_mutex_unlock(struct k_mutex *mutex); struct k_condvar { _wait_q_t wait_q; + +#ifdef CONFIG_OBJ_CORE_CONDVAR + struct k_obj_core obj_core; +#endif }; #define Z_CONDVAR_INITIALIZER(obj) \ @@ -3067,6 +3098,9 @@ struct k_sem { SYS_PORT_TRACING_TRACKING_FIELD(k_sem) +#ifdef CONFIG_OBJ_CORE_SEM + struct k_obj_core obj_core; +#endif }; #define Z_SEM_INITIALIZER(obj, initial_count, count_limit) \ @@ -4379,6 +4413,10 @@ struct k_msgq { uint8_t flags; SYS_PORT_TRACING_TRACKING_FIELD(k_msgq) + +#ifdef CONFIG_OBJ_CORE_MSGQ + struct k_obj_core obj_core; +#endif }; /** * @cond INTERNAL_HIDDEN @@ -4677,6 +4715,10 @@ struct k_mbox { struct k_spinlock lock; SYS_PORT_TRACING_TRACKING_FIELD(k_mbox) + +#ifdef CONFIG_OBJ_CORE_MAILBOX + struct k_obj_core obj_core; +#endif }; /** * @cond INTERNAL_HIDDEN @@ -4814,6 +4856,10 @@ struct k_pipe { uint8_t flags; /**< Flags */ SYS_PORT_TRACING_TRACKING_FIELD(k_pipe) + +#ifdef CONFIG_OBJ_CORE_PIPE + struct k_obj_core obj_core; +#endif }; /** @@ -5016,16 +5062,20 @@ struct k_mem_slab { struct k_mem_slab_info info; SYS_PORT_TRACING_TRACKING_FIELD(k_mem_slab) + +#ifdef CONFIG_OBJ_CORE_MEM_SLAB + struct k_obj_core obj_core; +#endif }; -#define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \ - slab_num_blocks) \ - { \ - .wait_q = Z_WAIT_Q_INIT(&obj.wait_q), \ - .lock = {}, \ - .buffer = slab_buffer, \ - .free_list = NULL, \ - .info = {slab_num_blocks, slab_block_size, 0} \ +#define Z_MEM_SLAB_INITIALIZER(_slab, _slab_buffer, _slab_block_size, \ + _slab_num_blocks) \ + { \ + .wait_q = Z_WAIT_Q_INIT(&(_slab).wait_q), \ + .lock = {}, \ + .buffer = _slab_buffer, \ + .free_list = NULL, \ + .info = {_slab_num_blocks, _slab_block_size, 0} \ } diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 3394a65bae2..e6bdd423bec 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -347,6 +347,10 @@ struct k_thread { struct _pipe_desc pipe_desc; #endif +#ifdef CONFIG_OBJ_CORE_THREAD + struct k_obj_core obj_core; +#endif + /** arch-specifics: must always be at the end */ struct _thread_arch arch; }; diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 4ead72479f8..6d0c8cc4967 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -29,6 +29,7 @@ #include #include #include +#include #endif #ifdef __cplusplus @@ -145,6 +146,10 @@ struct _cpu { #endif #endif +#ifdef CONFIG_OBJ_CORE_SYSTEM + struct k_obj_core obj_core; +#endif + /* Per CPU architecture specifics */ struct _cpu_arch arch; }; @@ -187,6 +192,10 @@ struct z_kernel { struct k_cycle_stats usage[CONFIG_MP_MAX_NUM_CPUS]; #endif +#ifdef CONFIG_OBJ_CORE_SYSTEM + struct k_obj_core obj_core; +#endif + #if defined(CONFIG_SMP) && defined(CONFIG_SCHED_IPI_SUPPORTED) /* Need to signal an IPI at the next scheduling point */ bool pending_ipi; diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index 9414941e9f0..d2d1a5ca7f1 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -87,6 +87,7 @@ ITERABLE_SECTION_RAM_GC_ALLOWED(k_fifo, 4) ITERABLE_SECTION_RAM_GC_ALLOWED(k_lifo, 4) ITERABLE_SECTION_RAM_GC_ALLOWED(k_condvar, 4) + ITERABLE_SECTION_RAM_GC_ALLOWED(sys_mem_blocks_ptr, 4) ITERABLE_SECTION_RAM(net_buf_pool, 4) diff --git a/include/zephyr/sys/mem_blocks.h b/include/zephyr/sys/mem_blocks.h index 77c37a75547..fe1565e3a8c 100644 --- a/include/zephyr/sys/mem_blocks.h +++ b/include/zephyr/sys/mem_blocks.h @@ -104,6 +104,9 @@ struct sys_mem_blocks { /* Spinlock guarding access to memory block internals */ struct k_spinlock lock; #endif +#ifdef CONFIG_OBJ_CORE_SYS_MEM_BLOCKS + struct k_obj_core obj_core; +#endif }; struct sys_multi_mem_blocks { @@ -125,11 +128,15 @@ struct sys_multi_mem_blocks { #define _SYS_MEM_BLOCKS_DEFINE_WITH_EXT_BUF(name, blk_sz, num_blks, buf, mbmod) \ _SYS_BITARRAY_DEFINE(_sys_mem_blocks_bitmap_##name, \ num_blks, mbmod); \ - mbmod sys_mem_blocks_t name = { \ + mbmod struct sys_mem_blocks name = { \ .info = {num_blks, ilog2(blk_sz)}, \ .buffer = buf, \ .bitmap = &_sys_mem_blocks_bitmap_##name, \ - } + }; \ + STRUCT_SECTION_ITERABLE_ALTERNATE(sys_mem_blocks_ptr, \ + sys_mem_blocks *, \ + __##name##_ptr) = &name; \ + LINKER_KEEP(__##name##_ptr); /** * @brief Create a memory block object with a new backing buffer. diff --git a/kernel/Kconfig b/kernel/Kconfig index 5abbd158507..663a5a3ed36 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -505,6 +505,113 @@ menuconfig OBJ_CORE automated means. if OBJ_CORE +config OBJ_CORE_CONDVAR + bool "Integrate condition variables into object core framework" + default y + help + When enabled, this option integrates condition variables into the + object core framework. + +config OBJ_CORE_EVENT + bool "Integrate events into object core framework" + default y if EVENTS + help + When enabled, this option integrate kernel events into the object + core framework. + +config OBJ_CORE_FIFO + bool "Integrate FIFOs into object core framework" + default y + help + When enabled, this option integrates FIFOs into the object core + framework. + +config OBJ_CORE_LIFO + bool "Integrate LIFOs into object core framework" + default y + help + When enabled, this option integrates LIFOs into the object core + framework. + +config OBJ_CORE_MAILBOX + bool "Integrate mailboxes into object core framework" + default y + help + When enabled, this option integrates mailboxes into the object core + framework. + +config OBJ_CORE_MEM_SLAB + bool "Integrate memory slabs into object core framework" + default y + help + When enabled, this option integrates memory slabs into the object + core framework. + +config OBJ_CORE_MUTEX + bool "Integrate mutexes into object core framework" + default y + help + When enabled, this option integrates mutexes into the object core + framework. + +config OBJ_CORE_MSGQ + bool "Integrate message queues into object core framework" + default y + help + When enabled, this option integrates message queues into the object + core framework. + +config OBJ_CORE_SEM + bool "Integrate semaphores into object core framework" + default y + help + When enabled, this option integrates semaphores into the object core + framework. + +config OBJ_CORE_PIPE + bool "Integrate pipe into object core framework" + default y if PIPES + help + When enabled, this option integrates pipes into the object core + framework. + +config OBJ_CORE_SEM + bool "Integrate semaphores into object core framework" + default y + help + When enabled, this option integrates semaphores into the object core + framework. + +config OBJ_CORE_STACK + bool "Integrate stacks into object core framework" + default y + help + When enabled, this option integrates stacks into the object core + framework. + +config OBJ_CORE_THREAD + bool "Integrate threads into object core framework" + default y + help + When enabled, this option integrates threads into the object core + framework. + +config OBJ_CORE_TIMER + bool "Integrate timers into object core framework" + default y + help + When enabled, this option integrates timers into the object core + framework. + +config OBJ_CORE_SYSTEM + bool + default y + help + When enabled, this option integrates the internal CPU and kernel + system objects into the object core framework. As these are internal + structures, this option is hidden by default and only available to + advanced users. + endif # OBJ_CORE menu "Work Queue Options" diff --git a/kernel/condvar.c b/kernel/condvar.c index 27fb0ec8a02..21f538c1996 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -10,6 +10,11 @@ #include #include #include +#include + +#ifdef CONFIG_OBJ_CORE_CONDVAR +static struct k_obj_type obj_type_condvar; +#endif static struct k_spinlock lock; @@ -18,6 +23,10 @@ int z_impl_k_condvar_init(struct k_condvar *condvar) z_waitq_init(&condvar->wait_q); z_object_init(condvar); +#ifdef CONFIG_OBJ_CORE_CONDVAR + k_obj_core_init_and_link(K_OBJ_CORE(condvar), &obj_type_condvar); +#endif + SYS_PORT_TRACING_OBJ_INIT(k_condvar, condvar, 0); return 0; @@ -125,3 +134,25 @@ int z_vrfy_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, } #include #endif + +#ifdef CONFIG_OBJ_CORE_CONDVAR +static int init_condvar_obj_core_list(void) +{ + /* Initialize condvar object type */ + + z_obj_type_init(&obj_type_condvar, K_OBJ_TYPE_CONDVAR_ID, + offsetof(struct k_condvar, obj_core)); + + /* Initialize and link statically defined condvars */ + + STRUCT_SECTION_FOREACH(k_condvar, condvar) { + k_obj_core_init_and_link(K_OBJ_CORE(condvar), + &obj_type_condvar); + } + + return 0; +} + +SYS_INIT(init_condvar_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/events.c b/kernel/events.c index a4fcf1710d0..654978650bc 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -45,6 +45,10 @@ struct event_walk_data { uint32_t events; }; +#ifdef CONFIG_OBJ_CORE_EVENT +static struct k_obj_type obj_type_event; +#endif + void z_impl_k_event_init(struct k_event *event) { event->events = 0; @@ -55,6 +59,10 @@ void z_impl_k_event_init(struct k_event *event) z_waitq_init(&event->wait_q); z_object_init(event); + +#ifdef CONFIG_OBJ_CORE_EVENT + k_obj_core_init_and_link(K_OBJ_CORE(event), &obj_type_event); +#endif } #ifdef CONFIG_USERSPACE @@ -336,3 +344,24 @@ uint32_t z_vrfy_k_event_wait_all(struct k_event *event, uint32_t events, } #include #endif + +#ifdef CONFIG_OBJ_CORE_EVENT +static int init_event_obj_core_list(void) +{ + /* Initialize condvar object type */ + + z_obj_type_init(&obj_type_event, K_OBJ_TYPE_EVENT_ID, + offsetof(struct k_event, obj_core)); + + /* Initialize and link statically defined condvars */ + + STRUCT_SECTION_FOREACH(k_event, event) { + k_obj_core_init_and_link(K_OBJ_CORE(event), &obj_type_event); + } + + return 0; +} + +SYS_INIT(init_event_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/init.c b/kernel/init.c index dccbad6cb41..b803f4c2067 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -37,7 +37,6 @@ #include LOG_MODULE_REGISTER(os, CONFIG_KERNEL_LOG_LEVEL); - BUILD_ASSERT(CONFIG_MP_NUM_CPUS == CONFIG_MP_MAX_NUM_CPUS, "CONFIG_MP_NUM_CPUS and CONFIG_MP_MAX_NUM_CPUS need to be set the same"); @@ -98,6 +97,10 @@ K_KERNEL_PINNED_STACK_ARRAY_DEFINE(z_interrupt_stacks, extern void idle(void *unused1, void *unused2, void *unused3); +#ifdef CONFIG_OBJ_CORE_SYSTEM +static struct k_obj_type obj_type_cpu; +static struct k_obj_type obj_type_kernel; +#endif /* LCOV_EXCL_START * @@ -409,6 +412,10 @@ void z_init_cpu(int id) * will keep track of this from here. */ atomic_inc(&_cpus_active); + +#ifdef CONFIG_OBJ_CORE_SYSTEM + k_obj_core_init_and_link(K_OBJ_CORE(&_kernel.cpus[id]), &obj_type_cpu); +#endif } /** @@ -598,3 +605,33 @@ FUNC_NORETURN void z_cstart(void) CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } + +#ifdef CONFIG_OBJ_CORE_SYSTEM +static int init_cpu_obj_core_list(void) +{ + /* Initialize CPU object type */ + + z_obj_type_init(&obj_type_cpu, K_OBJ_TYPE_CPU_ID, + offsetof(struct _cpu, obj_core)); + + return 0; +} + +static int init_kernel_obj_core_list(void) +{ + /* Initialize kernel object type */ + + z_obj_type_init(&obj_type_kernel, K_OBJ_TYPE_KERNEL_ID, + offsetof(struct z_kernel, obj_core)); + + k_obj_core_init_and_link(K_OBJ_CORE(&_kernel), &obj_type_kernel); + + return 0; +} + +SYS_INIT(init_cpu_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); + +SYS_INIT(init_kernel_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/mailbox.c b/kernel/mailbox.c index e72023846df..50c23345684 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -20,6 +20,10 @@ #include #include +#ifdef CONFIG_OBJ_CORE_MAILBOX +static struct k_obj_type obj_type_mailbox; +#endif + #if (CONFIG_NUM_MBOX_ASYNC_MSGS > 0) /* asynchronous message descriptor type */ @@ -91,6 +95,10 @@ void k_mbox_init(struct k_mbox *mbox) z_waitq_init(&mbox->rx_msg_queue); mbox->lock = (struct k_spinlock) {}; +#ifdef CONFIG_OBJ_CORE_MAILBOX + k_obj_core_init_and_link(K_OBJ_CORE(mbox), &obj_type_mailbox); +#endif + SYS_PORT_TRACING_OBJ_INIT(k_mbox, mbox); } @@ -447,3 +455,25 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer, return result; } + +#ifdef CONFIG_OBJ_CORE_MAILBOX + +static int init_mailbox_obj_core_list(void) +{ + /* Initialize mailbox object type */ + + z_obj_type_init(&obj_type_mailbox, K_OBJ_TYPE_MBOX_ID, + offsetof(struct k_mbox, obj_core)); + + /* Initialize and link satically defined mailboxes */ + + STRUCT_SECTION_FOREACH(k_mbox, mbox) { + k_obj_core_init_and_link(K_OBJ_CORE(mbox), &obj_type_mailbox); + } + + return 0; +} + +SYS_INIT(init_mailbox_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index aed02bd0f41..ff2e05b5e03 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -17,6 +17,10 @@ #include #include +#ifdef CONFIG_OBJ_CORE_MEM_SLAB +static struct k_obj_type obj_type_mem_slab; +#endif + /** * @brief Initialize kernel memory slab subsystem. * @@ -55,23 +59,36 @@ static int create_free_list(struct k_mem_slab *slab) * * @return 0 on success, fails otherwise. */ -static int init_mem_slab_module(void) +static int init_mem_slab_obj_core_list(void) { int rc = 0; + /* Initialize mem_slab object type */ + +#ifdef CONFIG_OBJ_CORE_MEM_SLAB + z_obj_type_init(&obj_type_mem_slab, K_OBJ_TYPE_MEM_SLAB_ID, + offsetof(struct k_mem_slab, obj_core)); +#endif + + /* Initialize statically defined mem_slabs */ + STRUCT_SECTION_FOREACH(k_mem_slab, slab) { rc = create_free_list(slab); if (rc < 0) { goto out; } z_object_init(slab); + +#ifdef CONFIG_OBJ_CORE_MEM_SLAB + k_obj_core_init_and_link(K_OBJ_CORE(slab), &obj_type_mem_slab); +#endif } out: return rc; } -SYS_INIT(init_mem_slab_module, PRE_KERNEL_1, +SYS_INIT(init_mem_slab_obj_core_list, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, @@ -94,6 +111,10 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, goto out; } +#ifdef CONFIG_OBJ_CORE_MEM_SLAB + k_obj_core_init_and_link(K_OBJ_CORE(slab), &obj_type_mem_slab); +#endif + z_waitq_init(&slab->wait_q); z_object_init(slab); out: diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 82566115a67..5b0f7cb83bd 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_OBJ_CORE_MSGQ +static struct k_obj_type obj_type_msgq; +#endif + #ifdef CONFIG_POLL static inline void handle_poll_events(struct k_msgq *msgq, uint32_t state) { @@ -49,6 +53,10 @@ void k_msgq_init(struct k_msgq *msgq, char *buffer, size_t msg_size, sys_dlist_init(&msgq->poll_events); #endif /* CONFIG_POLL */ +#ifdef CONFIG_OBJ_CORE_MSGQ + k_obj_core_init_and_link(K_OBJ_CORE(msgq), &obj_type_msgq); +#endif + SYS_PORT_TRACING_OBJ_INIT(k_msgq, msgq); z_object_init(msgq); @@ -409,3 +417,25 @@ static inline uint32_t z_vrfy_k_msgq_num_used_get(struct k_msgq *msgq) #include #endif + +#ifdef CONFIG_OBJ_CORE_MSGQ +static int init_msgq_obj_core_list(void) +{ + /* Initialize msgq object type */ + + z_obj_type_init(&obj_type_msgq, K_OBJ_TYPE_MSGQ_ID, + offsetof(struct k_msgq, obj_core)); + + /* Initialize and link statically defined message queues */ + + STRUCT_SECTION_FOREACH(k_msgq, msgq) { + k_obj_core_init_and_link(K_OBJ_CORE(msgq), &obj_type_msgq); + } + + return 0; +}; + +SYS_INIT(init_msgq_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); + +#endif diff --git a/kernel/mutex.c b/kernel/mutex.c index 44e0d316dab..94084bdcce9 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -46,6 +46,10 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); */ static struct k_spinlock lock; +#ifdef CONFIG_OBJ_CORE_MUTEX +static struct k_obj_type obj_type_mutex; +#endif + int z_impl_k_mutex_init(struct k_mutex *mutex) { mutex->owner = NULL; @@ -55,6 +59,10 @@ int z_impl_k_mutex_init(struct k_mutex *mutex) z_object_init(mutex); +#ifdef CONFIG_OBJ_CORE_MUTEX + k_obj_core_init_and_link(K_OBJ_CORE(mutex), &obj_type_mutex); +#endif + SYS_PORT_TRACING_OBJ_INIT(k_mutex, mutex, 0); return 0; @@ -281,3 +289,24 @@ static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) } #include #endif + +#ifdef CONFIG_OBJ_CORE_MUTEX +static int init_mutex_obj_core_list(void) +{ + /* Initialize mutex object type */ + + z_obj_type_init(&obj_type_mutex, K_OBJ_TYPE_MUTEX_ID, + offsetof(struct k_mutex, obj_core)); + + /* Initialize and link statically defined mutexs */ + + STRUCT_SECTION_FOREACH(k_mutex, mutex) { + k_obj_core_init_and_link(K_OBJ_CORE(mutex), &obj_type_mutex); + } + + return 0; +} + +SYS_INIT(init_mutex_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/pipes.c b/kernel/pipes.c index 68cf39d9a27..e4bb0227901 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -31,6 +31,10 @@ static int pipe_get_internal(k_spinlock_key_t key, struct k_pipe *pipe, void *data, size_t bytes_to_read, size_t *bytes_read, size_t min_xfer, k_timeout_t timeout); +#ifdef CONFIG_OBJ_CORE_PIPE +static struct k_obj_type obj_type_pipe; +#endif + void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) { @@ -50,6 +54,10 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) sys_dlist_init(&pipe->poll_events); #endif z_object_init(pipe); + +#ifdef CONFIG_OBJ_CORE_PIPE + k_obj_core_init_and_link(K_OBJ_CORE(pipe), &obj_type_pipe); +#endif } int z_impl_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) @@ -801,3 +809,24 @@ size_t z_vrfy_k_pipe_write_avail(struct k_pipe *pipe) } #include #endif + +#ifdef CONFIG_OBJ_CORE_PIPE +static int init_pipe_obj_core_list(void) +{ + /* Initialize pipe object type */ + + z_obj_type_init(&obj_type_pipe, K_OBJ_TYPE_PIPE_ID, + offsetof(struct k_pipe, obj_core)); + + /* Initialize and link statically defined pipes */ + + STRUCT_SECTION_FOREACH(k_pipe, pipe) { + k_obj_core_init_and_link(K_OBJ_CORE(pipe), &obj_type_pipe); + } + + return 0; +} + +SYS_INIT(init_pipe_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/queue.c b/kernel/queue.c index 7e6102ee4de..2625b9aba5b 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -432,3 +432,49 @@ static inline void *z_vrfy_k_queue_peek_tail(struct k_queue *queue) #include #endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_OBJ_CORE_FIFO +struct k_obj_type _obj_type_fifo; + +static int init_fifo_obj_core_list(void) +{ + /* Initialize fifo object type */ + + z_obj_type_init(&_obj_type_fifo, K_OBJ_TYPE_FIFO_ID, + offsetof(struct k_fifo, obj_core)); + + /* Initialize and link statically defined fifos */ + + STRUCT_SECTION_FOREACH(k_fifo, fifo) { + k_obj_core_init_and_link(K_OBJ_CORE(fifo), &_obj_type_fifo); + } + + return 0; +} + +SYS_INIT(init_fifo_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif + +#ifdef CONFIG_OBJ_CORE_LIFO +struct k_obj_type _obj_type_lifo; + +static int init_lifo_obj_core_list(void) +{ + /* Initialize lifo object type */ + + z_obj_type_init(&_obj_type_lifo, K_OBJ_TYPE_LIFO_ID, + offsetof(struct k_lifo, obj_core)); + + /* Initialize and link statically defined lifo */ + + STRUCT_SECTION_FOREACH(k_lifo, lifo) { + k_obj_core_init_and_link(K_OBJ_CORE(lifo), &_obj_type_lifo); + } + + return 0; +} + +SYS_INIT(init_lifo_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/sched.c b/kernel/sched.c index fa641179880..1aa13c327f3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1742,6 +1742,10 @@ static void end_thread(struct k_thread *thread) z_thread_cmsis_status_mask_clear(thread); #endif +#ifdef CONFIG_OBJ_CORE_THREAD + k_obj_core_unlink(K_OBJ_CORE(thread)); +#endif + #ifdef CONFIG_USERSPACE z_mem_domain_exit_thread(thread); z_thread_perms_all_clear(thread); diff --git a/kernel/sem.c b/kernel/sem.c index 26e4597911b..3b8bcb12808 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -38,6 +38,10 @@ */ static struct k_spinlock lock; +#ifdef CONFIG_OBJ_CORE_SEM +static struct k_obj_type obj_type_sem; +#endif + int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { @@ -61,6 +65,10 @@ int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, #endif z_object_init(sem); +#ifdef CONFIG_OBJ_CORE_SEM + k_obj_core_init_and_link(K_OBJ_CORE(sem), &obj_type_sem); +#endif + return 0; } @@ -200,3 +208,24 @@ static inline unsigned int z_vrfy_k_sem_count_get(struct k_sem *sem) #include #endif + +#ifdef CONFIG_OBJ_CORE_SEM +static int init_sem_obj_core_list(void) +{ + /* Initialize semaphore object type */ + + z_obj_type_init(&obj_type_sem, K_OBJ_TYPE_SEM_ID, + offsetof(struct k_sem, obj_core)); + + /* Initialize and link statically defined semaphores */ + + STRUCT_SECTION_FOREACH(k_sem, sem) { + k_obj_core_init_and_link(K_OBJ_CORE(sem), &obj_type_sem); + } + + return 0; +} + +SYS_INIT(init_sem_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/stack.c b/kernel/stack.c index 27038ce133e..0362ece76b5 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -19,6 +19,10 @@ #include #include +#ifdef CONFIG_OBJ_CORE_STACK +static struct k_obj_type obj_type_stack; +#endif + void k_stack_init(struct k_stack *stack, stack_data_t *buffer, uint32_t num_entries) { @@ -29,6 +33,10 @@ void k_stack_init(struct k_stack *stack, stack_data_t *buffer, SYS_PORT_TRACING_OBJ_INIT(k_stack, stack); z_object_init(stack); + +#ifdef CONFIG_OBJ_CORE_STACK + k_obj_core_init_and_link(K_OBJ_CORE(stack), &obj_type_stack); +#endif } int32_t z_impl_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) @@ -185,3 +193,24 @@ static inline int z_vrfy_k_stack_pop(struct k_stack *stack, } #include #endif + +#ifdef CONFIG_OBJ_CORE_STACK +static int init_stack_obj_core_list(void) +{ + /* Initialize stack object type */ + + z_obj_type_init(&obj_type_stack, K_OBJ_TYPE_STACK_ID, + offsetof(struct k_stack, obj_core)); + + /* Initialize and link statically defined stacks */ + + STRUCT_SECTION_FOREACH(k_stack, stack) { + k_obj_core_init_and_link(K_OBJ_CORE(stack), &obj_type_stack); + } + + return 0; +} + +SYS_INIT(init_stack_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/kernel/thread.c b/kernel/thread.c index 2b0b5ce0aac..c3cac10f579 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -33,6 +33,25 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); +#ifdef CONFIG_OBJ_CORE_THREAD +static struct k_obj_type obj_type_thread; + +static int init_thread_obj_core_list(void) +{ + /* Initialize mem_slab object type */ + +#ifdef CONFIG_OBJ_CORE_THREAD + z_obj_type_init(&obj_type_thread, K_OBJ_TYPE_THREAD_ID, + offsetof(struct k_thread, obj_core)); +#endif + + return 0; +} + +SYS_INIT(init_thread_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif + #ifdef CONFIG_THREAD_MONITOR /* This lock protects the linked list of active threads; i.e. the * initial _kernel.threads pointer and the linked list made up of @@ -543,6 +562,10 @@ char *z_setup_new_thread(struct k_thread *new_thread, Z_ASSERT_VALID_PRIO(prio, entry); +#ifdef CONFIG_OBJ_CORE_THREAD + k_obj_core_init_and_link(K_OBJ_CORE(new_thread), &obj_type_thread); +#endif + #ifdef CONFIG_USERSPACE __ASSERT((options & K_USER) == 0U || z_stack_is_user_capable(stack), "user thread %p with kernel-only stack %p", diff --git a/kernel/timer.c b/kernel/timer.c index 0186b42c922..24fe71c7f67 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -15,6 +15,10 @@ static struct k_spinlock lock; +#ifdef CONFIG_OBJ_CORE_TIMER +static struct k_obj_type obj_type_timer; +#endif + /** * @brief Handle expiration of a kernel timer object. * @@ -125,6 +129,10 @@ void k_timer_init(struct k_timer *timer, timer->user_data = NULL; z_object_init(timer); + +#ifdef CONFIG_OBJ_CORE_TIMER + k_obj_core_init_and_link(K_OBJ_CORE(timer), &obj_type_timer); +#endif } @@ -325,3 +333,23 @@ static inline void z_vrfy_k_timer_user_data_set(struct k_timer *timer, #include #endif + +#ifdef CONFIG_OBJ_CORE_TIMER +static int init_timer_obj_core_list(void) +{ + /* Initialize timer object type */ + + z_obj_type_init(&obj_type_timer, K_OBJ_TYPE_TIMER_ID, + offsetof(struct k_timer, obj_core)); + + /* Initialize and link statically defined timers */ + + STRUCT_SECTION_FOREACH(k_timer, timer) { + k_obj_core_init_and_link(K_OBJ_CORE(timer), &obj_type_timer); + } + + return 0; +} +SYS_INIT(init_timer_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif diff --git a/lib/os/Kconfig.heap b/lib/os/Kconfig.heap index 14fba87470b..9871de87004 100644 --- a/lib/os/Kconfig.heap +++ b/lib/os/Kconfig.heap @@ -133,4 +133,12 @@ config SYS_MEM_BLOCKS_RUNTIME_STATS blocks statistics related to the current and maximum number of allocations in a given memory block. +config OBJ_CORE_SYS_MEM_BLOCKS + bool "Kernel object for memory blocks" + depends on SYS_MEM_BLOCKS && OBJ_CORE + default y if SYS_MEM_BLOCKS && OBJ_CORE + help + This option allows object cores to be integrated into memory block + objects. + endmenu diff --git a/lib/os/mem_blocks.c b/lib/os/mem_blocks.c index e282a61108e..c3366c36702 100644 --- a/lib/os/mem_blocks.c +++ b/lib/os/mem_blocks.c @@ -10,6 +10,7 @@ #include #include #include +#include static void *alloc_blocks(sys_mem_blocks_t *mem_block, size_t num_blocks) { @@ -364,7 +365,7 @@ int sys_multi_mem_blocks_alloc(sys_multi_mem_blocks_t *group, goto out; } - if (count > allocator->num_blocks) { + if (count > allocator->info.num_blocks) { ret = -ENOMEM; goto out; } @@ -454,3 +455,28 @@ int sys_mem_blocks_runtime_stats_reset_max(sys_mem_blocks_t *mem_block) return 0; } #endif + +#ifdef CONFIG_OBJ_CORE_SYS_MEM_BLOCKS +static struct k_obj_type obj_type_sys_mem_blocks; + +static int init_sys_mem_blocks_obj_core_list(void) +{ + /* Initialize the sys_mem_blocks object type */ + + z_obj_type_init(&obj_type_sys_mem_blocks, K_OBJ_TYPE_MEM_BLOCK_ID, + offsetof(struct sys_mem_blocks, obj_core)); + + /* Initialize statically defined sys_mem_blocks */ + + STRUCT_SECTION_FOREACH_ALTERNATE(sys_mem_blocks_ptr, + sys_mem_blocks *, block_pp) { + k_obj_core_init_and_link(K_OBJ_CORE(*block_pp), + &obj_type_sys_mem_blocks); + } + + return 0; +} + +SYS_INIT(init_sys_mem_blocks_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif From 1d5d674e0d8b405d6b8fff075d1ca741d27c4b9e Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 9 Jun 2023 14:23:25 -0400 Subject: [PATCH 1477/4498] kernel: Add initial k_obj_core_stats infrastructure Adds the infrastructure to integrate statistics into the object core. Signed-off-by: Peter Mitsis --- include/zephyr/kernel/obj_core.h | 171 ++++++++++++++++++++++ kernel/Kconfig | 10 ++ kernel/obj_core.c | 236 +++++++++++++++++++++++++++++++ 3 files changed, 417 insertions(+) diff --git a/include/zephyr/kernel/obj_core.h b/include/zephyr/kernel/obj_core.h index 2003f439e3f..1dedccbfc4f 100644 --- a/include/zephyr/kernel/obj_core.h +++ b/include/zephyr/kernel/obj_core.h @@ -88,18 +88,42 @@ struct k_obj_core; */ extern sys_slist_t z_obj_type_list; +/** Object core statistics descriptor */ +struct k_obj_core_stats_desc { + size_t raw_size; /**< Internal representation stats buffer size */ + size_t query_size; /**< Stats buffer size used for reporting */ + + /** Function pointer to retrieve internal representation of stats */ + int (*raw)(struct k_obj_core *obj_core, void *stats); + /** Function pointer to retrieve reported statistics */ + int (*query)(struct k_obj_core *obj_core, void *stats); + /** Function pointer to reset object's statistics */ + int (*reset)(struct k_obj_core *obj_core); + /** Function pointer to disable object's statistics gathering */ + int (*disable)(struct k_obj_core *obj_core); + /** Function pointer to enable object's statistics gathering */ + int (*enable)(struct k_obj_core *obj_core); +}; + /** Object type structure */ struct k_obj_type { sys_snode_t node; /**< Node within list of object types */ sys_slist_t list; /**< List of objects of this object type */ uint32_t id; /**< Unique type ID */ size_t obj_core_offset; /**< Offset to obj_core field */ +#ifdef CONFIG_OBJ_CORE_STATS + /** Pointer to object core statistics descriptor */ + struct k_obj_core_stats_desc *stats_desc; +#endif }; /** Object core structure */ struct k_obj_core { sys_snode_t node; /**< Object node within object type's list */ struct k_obj_type *type; /**< Object type to which object belongs */ +#ifdef CONFIG_OBJ_CORE_STATS + void *stats; /**< Pointer to kernel object's stats */ +#endif }; /** @@ -219,5 +243,152 @@ void k_obj_core_init_and_link(struct k_obj_core *obj_core, */ void k_obj_core_unlink(struct k_obj_core *obj_core); +/** @} */ + +/** + * @defgroup obj_core_stats_apis Object Core Statistics APIs + * @ingroup kernel_apis + * @{ + */ + +#ifdef CONFIG_OBJ_CORE_STATS +/** + * @brief Initialize the object type's stats descriptor + * + * This routine initializes the object type's stats descriptor. + * + * @param type Pointer to the object type + * @param stats_desc Pointer to the object core statistics descriptor + */ +static inline void k_obj_type_stats_init(struct k_obj_type *type, + struct k_obj_core_stats_desc *stats_desc) +{ + type->stats_desc = stats_desc; +} + +/** + * @brief Initialize the object core for statistics + * + * This routine initializes the object core to operate within the object core + * statistics framework. + * + * @param obj_core Pointer to the object core + * @param stats Pointer to the object's raw statistics + */ +static inline void k_obj_core_stats_init(struct k_obj_core *obj_core, + void *stats) +{ + obj_core->stats = stats; +} +#endif + +/** + * @brief Register kernel object for gathering statistics + * + * Before a kernel object can gather statistics, it must be registered to do + * so. Registering will also automatically enable the kernel object to gather + * its statistics. + * + * @param obj_core Pointer to kernel object core + * @param stats Pointer to raw kernel statistics + * @param stats_len Size of raw kernel statistics buffer + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, + size_t stats_len); + +/** + * @brief Deregister kernel object from gathering statistics + * + * Deregistering a kernel object core from gathering statistics prevents it + * from gathering any more statistics. It is expected to be invoked at the end + * of a kernel object's life cycle. + * + * @param obj_core Pointer to kernel object core + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_deregister(struct k_obj_core *obj_core); + +/** + * @brief Retrieve the raw statistics associated with the kernel object + * + * This function copies the raw statistics associated with the kernel object + * core specified by @a obj_core into the buffer @a stats. Note that the size + * of the buffer (@a stats_len) must match the size specified by the kernel + * object type's statistics descriptor. + * + * @param obj_core Pointer to kernel object core + * @param stats Pointer to memory buffer into which to copy raw stats + * @param stats_len Length of the memory buffer + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_raw(struct k_obj_core *obj_core, void *stats, + size_t stats_len); + +/** + * @brief Retrieve the statistics associated with the kernel object + * + * This function copies the statistics associated with the kernel object core + * specified by @a obj_core into the buffer @a stats. Unlike the raw statistics + * this may report calculated values such as averages. Note that the size of + * the buffer (@a stats_len) must match the size specified by the kernel object + * type's statistics descriptor. + * + * @param obj_core Pointer to kernel object core + * @param stats Pointer to memory buffer into which to copy the queried stats + * @param stats_len Length of the memory buffer + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_query(struct k_obj_core *obj_core, void *stats, + size_t stats_len); + +/** + * @brief Reset the stats associated with the kernel object + * + * This function resets the statistics associated with the kernel object core + * specified by @a obj_core. + * + * @param obj_core Pointer to kernel object core + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_reset(struct k_obj_core *obj_core); + +/** + * @brief Stop gathering the stats associated with the kernel object + * + * This function temporarily stops the gathering of statistics associated with + * the kernel object core specified by @a obj_core. The gathering of statistics + * can be resumed by invoking :c:func :`k_obj_core_stats_enable`. + * + * @param obj_core Pointer to kernel object core + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_disable(struct k_obj_core *obj_core); + +/** + * @brief Reset the stats associated with the kernel object + * + * This function resumes the gathering of statistics associated with the kernel + * object core specified by @a obj_core. + * + * @param obj_core Pointer to kernel object core + * + * @retval 0 on success + * @retval -errno on failure + */ +int k_obj_core_stats_enable(struct k_obj_core *obj_core); + /** @} */ #endif /* __KERNEL_OBJ_CORE_H__ */ diff --git a/kernel/Kconfig b/kernel/Kconfig index 663a5a3ed36..8c436f3b43f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -612,6 +612,16 @@ config OBJ_CORE_SYSTEM structures, this option is hidden by default and only available to advanced users. +menuconfig OBJ_CORE_STATS + bool "Object core statistics" + default n + help + This option integrates statistics gathering into the object core + framework. + +if OBJ_CORE_STATS +endif # OBJ_CORE_STATS + endif # OBJ_CORE menu "Work Queue Options" diff --git a/kernel/obj_core.c b/kernel/obj_core.c index 9f034868500..b8f262232b6 100644 --- a/kernel/obj_core.c +++ b/kernel/obj_core.c @@ -26,6 +26,9 @@ void k_obj_core_init(struct k_obj_core *obj_core, struct k_obj_type *type) { obj_core->node.next = NULL; obj_core->type = type; +#ifdef CONFIG_OBJ_CORE_STATS + obj_core->stats = NULL; +#endif } void k_obj_core_link(struct k_obj_core *obj_core) @@ -117,3 +120,236 @@ int k_obj_type_walk_unlocked(struct k_obj_type *type, return status; } + +#ifdef CONFIG_OBJ_CORE_STATS +int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, + size_t stats_len) +{ + __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + if (obj_core->type->stats_desc == NULL) { + + /* Object type not configured for statistics. */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if (obj_core->type->stats_desc->raw_size != stats_len) { + + /* Buffer size mismatch */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + obj_core->stats = stats; + k_spin_unlock(&lock, key); + + return 0; +} + +int k_obj_core_stats_deregister(struct k_obj_core *obj_core) +{ + __ASSERT((obj_core != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + if (obj_core->type->stats_desc == NULL) { + + /* Object type not configured for statistics. */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + obj_core->stats = NULL; + k_spin_unlock(&lock, key); + + return 0; +} + +int k_obj_core_stats_raw(struct k_obj_core *obj_core, void *stats, + size_t stats_len) +{ + int rv; + struct k_obj_core_stats_desc *desc; + + __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + desc = obj_core->type->stats_desc; + if ((desc == NULL) || (desc->raw == NULL)) { + + /* The object type is not configured for this operation */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if ((desc->raw_size != stats_len) || (obj_core->stats == NULL)) { + + /* + * Either the size of the stats buffer is wrong or + * the kernel object was not registered for statistics. + */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + rv = desc->raw(obj_core, stats); + k_spin_unlock(&lock, key); + + return rv; +} + +int k_obj_core_stats_query(struct k_obj_core *obj_core, void *stats, + size_t stats_len) +{ + int rv; + struct k_obj_core_stats_desc *desc; + + __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + desc = obj_core->type->stats_desc; + if ((desc == NULL) || (desc->query == NULL)) { + + /* The object type is not configured for this operation */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if ((desc->query_size != stats_len) || (obj_core->stats == NULL)) { + + /* + * Either the size of the stats buffer is wrong or + * the kernel object was not registered for statistics. + */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + rv = desc->query(obj_core, stats); + k_spin_unlock(&lock, key); + + return rv; +} + +int k_obj_core_stats_reset(struct k_obj_core *obj_core) +{ + int rv; + struct k_obj_core_stats_desc *desc; + + __ASSERT((obj_core != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + desc = obj_core->type->stats_desc; + if ((desc == NULL) || (desc->reset == NULL)) { + + /* The object type is not configured for this operation */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if (obj_core->stats == NULL) { + + /* This kernel object is not configured for statistics */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + rv = desc->reset(obj_core); + k_spin_unlock(&lock, key); + + return rv; +} + +int k_obj_core_stats_disable(struct k_obj_core *obj_core) +{ + int rv; + struct k_obj_core_stats_desc *desc; + + __ASSERT((obj_core != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + desc = obj_core->type->stats_desc; + if ((desc == NULL) || (desc->disable == NULL)) { + + /* The object type is not configured for this operation */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if (obj_core->stats == NULL) { + + /* This kernel object is not configured for statistics */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + rv = desc->disable(obj_core); + k_spin_unlock(&lock, key); + + return rv; +} + +int k_obj_core_stats_enable(struct k_obj_core *obj_core) +{ + int rv; + struct k_obj_core_stats_desc *desc; + + __ASSERT((obj_core != NULL), "NULL parameter"); + + k_spinlock_key_t key = k_spin_lock(&lock); + + __ASSERT(obj_core->type != NULL, "Object core not initialized"); + + desc = obj_core->type->stats_desc; + if ((desc == NULL) || (desc->enable == NULL)) { + + /* The object type is not configured for this operation */ + + k_spin_unlock(&lock, key); + return -ENOTSUP; + } + + if (obj_core->stats == NULL) { + + /* This kernel object is not configured for statistics */ + + k_spin_unlock(&lock, key); + return -EINVAL; + } + + rv = desc->enable(obj_core); + k_spin_unlock(&lock, key); + + return rv; +} +#endif From e6f10905539c1a83d28a199af240cc67307921e6 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 1 Jun 2023 12:16:40 -0400 Subject: [PATCH 1478/4498] kernel: Integrate object core statistics Integrates object core statistics framework into the following kernel objects: sys_mem_blocks, k_mem_slab threads, _cpu, z_kernel Signed-off-by: Peter Mitsis --- kernel/Kconfig | 23 +++++ kernel/include/kernel_internal.h | 16 ++++ kernel/init.c | 39 +++++++++ kernel/mem_slab.c | 82 ++++++++++++++++++ kernel/obj_core.c | 28 ------ kernel/sched.c | 3 + kernel/thread.c | 21 +++++ kernel/usage.c | 141 +++++++++++++++++++++++++++++++ lib/os/Kconfig.heap | 9 ++ lib/os/mem_blocks.c | 77 +++++++++++++++++ 10 files changed, 411 insertions(+), 28 deletions(-) diff --git a/kernel/Kconfig b/kernel/Kconfig index 8c436f3b43f..556bb69531e 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -620,6 +620,29 @@ menuconfig OBJ_CORE_STATS framework. if OBJ_CORE_STATS +config OBJ_CORE_STATS_MEM_SLAB + bool "Object core statistics for memory slabs" + default y if OBJ_CORE_MEM_SLAB + help + When enabled, this allows memory slab statistics to be integrated + into kernel objects. + +config OBJ_CORE_STATS_THREAD + bool "Object core statistics for threads" + default y if OBJ_CORE_THREAD + select THREAD_RUNTIME_STATS + help + When enabled, this integrates thread runtime statistics into the + object core statistics framework. + +config OBJ_CORE_STATS_SYSTEM + bool "Object core statistics for system level objects" + default y if OBJ_CORE_SYSTEM + select SCHED_THREAD_USAGE_ALL + help + When enabled, this integrates thread runtime statistics at the + CPU and system level into the object core statistics framework. + endif # OBJ_CORE_STATS endif # OBJ_CORE diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index 576996cc9f6..cd5b1220aae 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -289,6 +289,22 @@ void z_paging_histogram_inc(struct k_mem_paging_histogram_t *hist, uint32_t cycles); #endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ +#ifdef CONFIG_OBJ_CORE_STATS_THREAD +int z_thread_stats_raw(struct k_obj_core *obj_core, void *stats); +int z_thread_stats_query(struct k_obj_core *obj_core, void *stats); +int z_thread_stats_reset(struct k_obj_core *obj_core); +int z_thread_stats_disable(struct k_obj_core *obj_core); +int z_thread_stats_enable(struct k_obj_core *obj_core); +#endif + +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM +int z_cpu_stats_raw(struct k_obj_core *obj_core, void *stats); +int z_cpu_stats_query(struct k_obj_core *obj_core, void *stats); + +int z_kernel_stats_raw(struct k_obj_core *obj_core, void *stats); +int z_kernel_stats_query(struct k_obj_core *obj_core, void *stats); +#endif + #ifdef __cplusplus } #endif diff --git a/kernel/init.c b/kernel/init.c index b803f4c2067..cd4b0e748fa 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -100,6 +100,28 @@ extern void idle(void *unused1, void *unused2, void *unused3); #ifdef CONFIG_OBJ_CORE_SYSTEM static struct k_obj_type obj_type_cpu; static struct k_obj_type obj_type_kernel; + +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM +static struct k_obj_core_stats_desc cpu_stats_desc = { + .raw_size = sizeof(struct k_cycle_stats), + .query_size = sizeof(struct k_thread_runtime_stats), + .raw = z_cpu_stats_raw, + .query = z_cpu_stats_query, + .reset = NULL, + .disable = NULL, + .enable = NULL, +}; + +static struct k_obj_core_stats_desc kernel_stats_desc = { + .raw_size = sizeof(struct k_cycle_stats) * CONFIG_MP_MAX_NUM_CPUS, + .query_size = sizeof(struct k_thread_runtime_stats), + .raw = z_kernel_stats_raw, + .query = z_kernel_stats_query, + .reset = NULL, + .disable = NULL, + .enable = NULL, +}; +#endif #endif /* LCOV_EXCL_START @@ -415,6 +437,11 @@ void z_init_cpu(int id) #ifdef CONFIG_OBJ_CORE_SYSTEM k_obj_core_init_and_link(K_OBJ_CORE(&_kernel.cpus[id]), &obj_type_cpu); +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM + k_obj_core_stats_register(K_OBJ_CORE(&_kernel.cpus[id]), + _kernel.cpus[id].usage, + sizeof(struct k_cycle_stats)); +#endif #endif } @@ -614,6 +641,10 @@ static int init_cpu_obj_core_list(void) z_obj_type_init(&obj_type_cpu, K_OBJ_TYPE_CPU_ID, offsetof(struct _cpu, obj_core)); +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM + k_obj_type_stats_init(&obj_type_cpu, &cpu_stats_desc); +#endif + return 0; } @@ -624,7 +655,15 @@ static int init_kernel_obj_core_list(void) z_obj_type_init(&obj_type_kernel, K_OBJ_TYPE_KERNEL_ID, offsetof(struct z_kernel, obj_core)); +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM + k_obj_type_stats_init(&obj_type_kernel, &kernel_stats_desc); +#endif + k_obj_core_init_and_link(K_OBJ_CORE(&_kernel), &obj_type_kernel); +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM + k_obj_core_stats_register(K_OBJ_CORE(&_kernel), _kernel.usage, + sizeof(_kernel.usage)); +#endif return 0; } diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index ff2e05b5e03..7f7853213b9 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -13,12 +13,83 @@ #include #include #include +#include /* private kernel APIs */ #include #include #ifdef CONFIG_OBJ_CORE_MEM_SLAB static struct k_obj_type obj_type_mem_slab; + +#ifdef CONFIG_OBJ_CORE_STATS_MEM_SLAB + +static int k_mem_slab_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); + + struct k_mem_slab *slab; + k_spinlock_key_t key; + + slab = CONTAINER_OF(obj_core, struct k_mem_slab, obj_core); + key = k_spin_lock(&slab->lock); + memcpy(stats, &slab->info, sizeof(slab->info)); + k_spin_unlock(&slab->lock, key); + + return 0; +} + +static int k_mem_slab_stats_query(struct k_obj_core *obj_core, void *stats) +{ + __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); + + struct k_mem_slab *slab; + k_spinlock_key_t key; + struct sys_memory_stats *ptr = stats; + + slab = CONTAINER_OF(obj_core, struct k_mem_slab, obj_core); + key = k_spin_lock(&slab->lock); + ptr->free_bytes = (slab->info.num_blocks - slab->info.num_used) * + slab->info.block_size; + ptr->allocated_bytes = slab->info.num_used * slab->info.block_size; +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + ptr->max_allocated_bytes = slab->info.max_used * slab->info.block_size; +#else + ptr->max_allocated_bytes = 0; +#endif + k_spin_unlock(&slab->lock, key); + + return 0; +} + +static int k_mem_slab_stats_reset(struct k_obj_core *obj_core) +{ + __ASSERT(obj_core != NULL, "NULL parameter"); + + struct k_mem_slab *slab; + k_spinlock_key_t key; + + slab = CONTAINER_OF(obj_core, struct k_mem_slab, obj_core); + key = k_spin_lock(&slab->lock); + +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + slab->info.max_used = slab->info.num_used; +#endif + + k_spin_unlock(&slab->lock, key); + + return 0; +} + +static struct k_obj_core_stats_desc mem_slab_stats_desc = { + .raw_size = sizeof(struct k_mem_slab_info), + .query_size = sizeof(struct sys_memory_stats), + .raw = k_mem_slab_stats_raw, + .query = k_mem_slab_stats_query, + .reset = k_mem_slab_stats_reset, + .disable = NULL, + .enable = NULL, +}; +#endif #endif /** @@ -68,6 +139,9 @@ static int init_mem_slab_obj_core_list(void) #ifdef CONFIG_OBJ_CORE_MEM_SLAB z_obj_type_init(&obj_type_mem_slab, K_OBJ_TYPE_MEM_SLAB_ID, offsetof(struct k_mem_slab, obj_core)); +#ifdef CONFIG_OBJ_CORE_STATS_MEM_SLAB + k_obj_type_stats_init(&obj_type_mem_slab, &mem_slab_stats_desc); +#endif #endif /* Initialize statically defined mem_slabs */ @@ -81,6 +155,10 @@ static int init_mem_slab_obj_core_list(void) #ifdef CONFIG_OBJ_CORE_MEM_SLAB k_obj_core_init_and_link(K_OBJ_CORE(slab), &obj_type_mem_slab); +#ifdef CONFIG_OBJ_CORE_STATS_MEM_SLAB + k_obj_core_stats_register(K_OBJ_CORE(slab), &slab->info, + sizeof(struct k_mem_slab_info)); +#endif #endif } @@ -114,6 +192,10 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, #ifdef CONFIG_OBJ_CORE_MEM_SLAB k_obj_core_init_and_link(K_OBJ_CORE(slab), &obj_type_mem_slab); #endif +#ifdef CONFIG_OBJ_CORE_STATS_MEM_SLAB + k_obj_core_stats_register(K_OBJ_CORE(slab), &slab->info, + sizeof(struct k_mem_slab_info)); +#endif z_waitq_init(&slab->wait_q); z_object_init(slab); diff --git a/kernel/obj_core.c b/kernel/obj_core.c index b8f262232b6..8ac4f737d2d 100644 --- a/kernel/obj_core.c +++ b/kernel/obj_core.c @@ -125,12 +125,8 @@ int k_obj_type_walk_unlocked(struct k_obj_type *type, int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, size_t stats_len) { - __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - if (obj_core->type->stats_desc == NULL) { /* Object type not configured for statistics. */ @@ -155,12 +151,8 @@ int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, int k_obj_core_stats_deregister(struct k_obj_core *obj_core) { - __ASSERT((obj_core != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - if (obj_core->type->stats_desc == NULL) { /* Object type not configured for statistics. */ @@ -181,12 +173,8 @@ int k_obj_core_stats_raw(struct k_obj_core *obj_core, void *stats, int rv; struct k_obj_core_stats_desc *desc; - __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - desc = obj_core->type->stats_desc; if ((desc == NULL) || (desc->raw == NULL)) { @@ -219,12 +207,8 @@ int k_obj_core_stats_query(struct k_obj_core *obj_core, void *stats, int rv; struct k_obj_core_stats_desc *desc; - __ASSERT((obj_core != NULL) && (stats != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - desc = obj_core->type->stats_desc; if ((desc == NULL) || (desc->query == NULL)) { @@ -256,12 +240,8 @@ int k_obj_core_stats_reset(struct k_obj_core *obj_core) int rv; struct k_obj_core_stats_desc *desc; - __ASSERT((obj_core != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - desc = obj_core->type->stats_desc; if ((desc == NULL) || (desc->reset == NULL)) { @@ -290,12 +270,8 @@ int k_obj_core_stats_disable(struct k_obj_core *obj_core) int rv; struct k_obj_core_stats_desc *desc; - __ASSERT((obj_core != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - desc = obj_core->type->stats_desc; if ((desc == NULL) || (desc->disable == NULL)) { @@ -324,12 +300,8 @@ int k_obj_core_stats_enable(struct k_obj_core *obj_core) int rv; struct k_obj_core_stats_desc *desc; - __ASSERT((obj_core != NULL), "NULL parameter"); - k_spinlock_key_t key = k_spin_lock(&lock); - __ASSERT(obj_core->type != NULL, "Object core not initialized"); - desc = obj_core->type->stats_desc; if ((desc == NULL) || (desc->enable == NULL)) { diff --git a/kernel/sched.c b/kernel/sched.c index 1aa13c327f3..db6742e841e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1743,6 +1743,9 @@ static void end_thread(struct k_thread *thread) #endif #ifdef CONFIG_OBJ_CORE_THREAD +#ifdef CONFIG_OBJ_CORE_STATS_THREAD + k_obj_core_stats_deregister(K_OBJ_CORE(thread)); +#endif k_obj_core_unlink(K_OBJ_CORE(thread)); #endif diff --git a/kernel/thread.c b/kernel/thread.c index c3cac10f579..75ca7864772 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -36,6 +36,18 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #ifdef CONFIG_OBJ_CORE_THREAD static struct k_obj_type obj_type_thread; +#ifdef CONFIG_OBJ_CORE_STATS_THREAD +static struct k_obj_core_stats_desc thread_stats_desc = { + .raw_size = sizeof(struct k_cycle_stats), + .query_size = sizeof(struct k_thread_runtime_stats), + .raw = z_thread_stats_raw, + .query = z_thread_stats_query, + .reset = z_thread_stats_reset, + .disable = z_thread_stats_disable, + .enable = z_thread_stats_enable, +}; +#endif + static int init_thread_obj_core_list(void) { /* Initialize mem_slab object type */ @@ -45,6 +57,10 @@ static int init_thread_obj_core_list(void) offsetof(struct k_thread, obj_core)); #endif +#ifdef CONFIG_OBJ_CORE_STATS_THREAD + k_obj_type_stats_init(&obj_type_thread, &thread_stats_desc); +#endif + return 0; } @@ -564,6 +580,11 @@ char *z_setup_new_thread(struct k_thread *new_thread, #ifdef CONFIG_OBJ_CORE_THREAD k_obj_core_init_and_link(K_OBJ_CORE(new_thread), &obj_type_thread); +#ifdef CONFIG_OBJ_CORE_STATS_THREAD + k_obj_core_stats_register(K_OBJ_CORE(new_thread), + &new_thread->base.usage, + sizeof(new_thread->base.usage)); +#endif #endif #ifdef CONFIG_USERSPACE diff --git a/kernel/usage.c b/kernel/usage.c index 57a55a75759..de497e2879c 100644 --- a/kernel/usage.c +++ b/kernel/usage.c @@ -343,3 +343,144 @@ void k_sys_runtime_stats_disable(void) k_spin_unlock(&usage_lock, key); } #endif + +#ifdef CONFIG_OBJ_CORE_STATS_THREAD +int z_thread_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&usage_lock); + memcpy(stats, obj_core->stats, sizeof(struct k_cycle_stats)); + k_spin_unlock(&usage_lock, key); + + return 0; +} + +int z_thread_stats_query(struct k_obj_core *obj_core, void *stats) +{ + struct k_thread *thread; + + thread = CONTAINER_OF(obj_core, struct k_thread, obj_core); + + z_sched_thread_usage(thread, stats); + + return 0; +} + +int z_thread_stats_reset(struct k_obj_core *obj_core) +{ + k_spinlock_key_t key; + struct k_cycle_stats *stats; + struct k_thread *thread; + + thread = CONTAINER_OF(obj_core, struct k_thread, obj_core); + key = k_spin_lock(&usage_lock); + stats = obj_core->stats; + + stats->total = 0ULL; +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + stats->current = 0ULL; + stats->longest = 0ULL; + stats->num_windows = (thread->base.usage.track_usage) ? 1U : 0U; +#endif + + if (thread != _current_cpu->current) { + + /* + * If the thread is not running, there is nothing else to do. + * If the thread is running on another core, then it is not + * safe to do anything else but unlock and return (and pretend + * that its stats were reset at the start of its execution + * window. + */ + + k_spin_unlock(&usage_lock, key); + + return 0; + } + + /* Update the current CPU stats. */ + + uint32_t now = usage_now(); + uint32_t cycles = now - _current_cpu->usage0; + + sched_cpu_update_usage(_current_cpu, cycles); + + _current_cpu->usage0 = now; + + k_spin_unlock(&usage_lock, key); + + return 0; +} + +int z_thread_stats_disable(struct k_obj_core *obj_core) +{ +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + struct k_thread *thread; + + thread = CONTAINER_OF(obj_core, struct k_thread, obj_core); + + return k_thread_runtime_stats_disable(thread); +#else + return -ENOTSUP; +#endif +} + +int z_thread_stats_enable(struct k_obj_core *obj_core) +{ +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + struct k_thread *thread; + + thread = CONTAINER_OF(obj_core, struct k_thread, obj_core); + + return k_thread_runtime_stats_enable(thread); +#else + return -ENOTSUP; +#endif +} +#endif + +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM +int z_cpu_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&usage_lock); + memcpy(stats, obj_core->stats, sizeof(struct k_cycle_stats)); + k_spin_unlock(&usage_lock, key); + + return 0; +} + +int z_cpu_stats_query(struct k_obj_core *obj_core, void *stats) +{ + struct _cpu *cpu; + + cpu = CONTAINER_OF(obj_core, struct _cpu, obj_core); + + z_sched_cpu_usage(cpu->id, stats); + + return 0; +} +#endif + +#ifdef CONFIG_OBJ_CORE_STATS_SYSTEM +int z_kernel_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&usage_lock); + memcpy(stats, obj_core->stats, + CONFIG_MP_MAX_NUM_CPUS * sizeof(struct k_cycle_stats)); + k_spin_unlock(&usage_lock, key); + + return 0; +} + +int z_kernel_stats_query(struct k_obj_core *obj_core, void *stats) +{ + ARG_UNUSED(obj_core); + + return k_thread_runtime_stats_all_get(stats); +} +#endif diff --git a/lib/os/Kconfig.heap b/lib/os/Kconfig.heap index 9871de87004..b913d6100dc 100644 --- a/lib/os/Kconfig.heap +++ b/lib/os/Kconfig.heap @@ -141,4 +141,13 @@ config OBJ_CORE_SYS_MEM_BLOCKS This option allows object cores to be integrated into memory block objects. +config OBJ_CORE_STATS_SYS_MEM_BLOCKS + bool "Object core statistics for memory blocks" + depends on SYS_MEM_BLOCKS && OBJ_CORE_STATS + default y if SYS_MEM_BLOCKS && OBJ_CORE_STATS + select SYS_MEM_BLOCKS_RUNTIME_STATS + help + This option integrates the object core statistics framework into + the memory blocks. + endmenu diff --git a/lib/os/mem_blocks.c b/lib/os/mem_blocks.c index c3366c36702..84d3d81638a 100644 --- a/lib/os/mem_blocks.c +++ b/lib/os/mem_blocks.c @@ -11,6 +11,7 @@ #include #include #include +#include static void *alloc_blocks(sys_mem_blocks_t *mem_block, size_t num_blocks) { @@ -456,6 +457,72 @@ int sys_mem_blocks_runtime_stats_reset_max(sys_mem_blocks_t *mem_block) } #endif +#ifdef CONFIG_OBJ_CORE_STATS_SYS_MEM_BLOCKS +static int sys_mem_blocks_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + struct sys_mem_blocks *block; + k_spinlock_key_t key; + + block = CONTAINER_OF(obj_core, struct sys_mem_blocks, obj_core); + + key = k_spin_lock(&block->lock); + + memcpy(stats, &block->info, sizeof(block->info)); + + k_spin_unlock(&block->lock, key); + + return 0; +} + +static int sys_mem_blocks_stats_query(struct k_obj_core *obj_core, void *stats) +{ + struct sys_mem_blocks *block; + k_spinlock_key_t key; + struct sys_memory_stats *ptr = stats; + + block = CONTAINER_OF(obj_core, struct sys_mem_blocks, obj_core); + + key = k_spin_lock(&block->lock); + + ptr->free_bytes = (block->info.num_blocks - block->info.used_blocks) << + block->info.blk_sz_shift; + ptr->allocated_bytes = block->info.used_blocks << + block->info.blk_sz_shift; + ptr->max_allocated_bytes = block->info.max_used_blocks << + block->info.blk_sz_shift; + + k_spin_unlock(&block->lock, key); + + return 0; +} + +static int sys_mem_blocks_stats_reset(struct k_obj_core *obj_core) +{ + struct sys_mem_blocks *block; + k_spinlock_key_t key; + + block = CONTAINER_OF(obj_core, struct sys_mem_blocks, obj_core); + + key = k_spin_lock(&block->lock); + block->info.max_used_blocks = block->info.used_blocks; + k_spin_unlock(&block->lock, key); + + return 0; +} + +static struct k_obj_type obj_type_sys_mem_blocks; + +static struct k_obj_core_stats_desc sys_mem_blocks_stats_desc = { + .raw_size = sizeof(struct sys_mem_blocks_info), + .query_size = sizeof(struct sys_memory_stats), + .raw = sys_mem_blocks_stats_raw, + .query = sys_mem_blocks_stats_query, + .reset = sys_mem_blocks_stats_reset, + .disable = NULL, + .enable = NULL, +}; +#endif + #ifdef CONFIG_OBJ_CORE_SYS_MEM_BLOCKS static struct k_obj_type obj_type_sys_mem_blocks; @@ -466,12 +533,22 @@ static int init_sys_mem_blocks_obj_core_list(void) z_obj_type_init(&obj_type_sys_mem_blocks, K_OBJ_TYPE_MEM_BLOCK_ID, offsetof(struct sys_mem_blocks, obj_core)); +#ifdef CONFIG_OBJ_CORE_STATS_SYS_MEM_BLOCKS + k_obj_type_stats_init(&obj_type_sys_mem_blocks, + &sys_mem_blocks_stats_desc); +#endif + /* Initialize statically defined sys_mem_blocks */ STRUCT_SECTION_FOREACH_ALTERNATE(sys_mem_blocks_ptr, sys_mem_blocks *, block_pp) { k_obj_core_init_and_link(K_OBJ_CORE(*block_pp), &obj_type_sys_mem_blocks); +#ifdef CONFIG_OBJ_CORE_STATS_SYS_MEM_BLOCKS + k_obj_core_stats_register(K_OBJ_CORE(*block_pp), + &(*block_pp)->info, + sizeof(struct sys_mem_blocks_info)); +#endif } return 0; From 5594de49ea0b0207308bd9e432a9fe87bc2828cf Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 30 May 2023 13:51:32 -0400 Subject: [PATCH 1479/4498] test: Implement object core test Creates a test to verify that kernel objects can be found within the object core framework. Signed-off-by: Peter Mitsis --- tests/kernel/obj_core/obj_core/CMakeLists.txt | 8 + tests/kernel/obj_core/obj_core/prj.conf | 6 + tests/kernel/obj_core/obj_core/src/main.c | 286 ++++++++++++++++++ tests/kernel/obj_core/obj_core/testcase.yaml | 9 + 4 files changed, 309 insertions(+) create mode 100644 tests/kernel/obj_core/obj_core/CMakeLists.txt create mode 100644 tests/kernel/obj_core/obj_core/prj.conf create mode 100644 tests/kernel/obj_core/obj_core/src/main.c create mode 100644 tests/kernel/obj_core/obj_core/testcase.yaml diff --git a/tests/kernel/obj_core/obj_core/CMakeLists.txt b/tests/kernel/obj_core/obj_core/CMakeLists.txt new file mode 100644 index 00000000000..a9c26c7493c --- /dev/null +++ b/tests/kernel/obj_core/obj_core/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(obj_core) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/obj_core/obj_core/prj.conf b/tests/kernel/obj_core/obj_core/prj.conf new file mode 100644 index 00000000000..59e79100e29 --- /dev/null +++ b/tests/kernel/obj_core/obj_core/prj.conf @@ -0,0 +1,6 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_OBJ_CORE=y +CONFIG_EVENTS=y +CONFIG_PIPES=y +CONFIG_SYS_MEM_BLOCKS=y diff --git a/tests/kernel/obj_core/obj_core/src/main.c b/tests/kernel/obj_core/obj_core/src/main.c new file mode 100644 index 00000000000..94f4e9fa648 --- /dev/null +++ b/tests/kernel/obj_core/obj_core/src/main.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +SYS_MEM_BLOCKS_DEFINE(block1, 32, 4, 16); + +K_MEM_SLAB_DEFINE(slab1, 32, 4, 16); +static char slab2_buffer[256] __aligned(8); +struct k_mem_slab slab2; + +K_TIMER_DEFINE(timer1, NULL, NULL); +struct k_timer timer2; + +K_STACK_DEFINE(stack1, 8); +static struct k_stack stack2; +stack_data_t stack2_buffer[8]; + +static K_FIFO_DEFINE(fifo1); +static struct k_fifo fifo2; + +static K_LIFO_DEFINE(lifo1); +static struct k_lifo lifo2; + +K_PIPE_DEFINE(pipe1, 16, 8); +static struct k_pipe pipe2; +static char pipe2_buffer[16]; + +K_MSGQ_DEFINE(msgq1, 16, 4, 8); +static struct k_msgq msgq2; +static char msgq2_buffer[16]; + +static K_MBOX_DEFINE(mbox1); +static struct k_mbox mbox2; + +static K_CONDVAR_DEFINE(condvar1); +static struct k_condvar condvar2; + +static K_EVENT_DEFINE(event1); +static struct k_event event2; + +static K_MUTEX_DEFINE(mutex1); +static struct k_mutex mutex2; + +static K_SEM_DEFINE(sem1, 0, 1); +static struct k_sem sem2; + +static void thread_entry(void *, void *, void *); +K_THREAD_DEFINE(thread1, 512, thread_entry, NULL, NULL, NULL, + K_HIGHEST_THREAD_PRIO, 0, 0); +static struct k_thread thread2; +K_THREAD_STACK_DEFINE(thread2_stack, 512); + +struct obj_core_find_data { + struct k_obj_core *obj_core; /* Object core to search for */ +}; + +static void thread_entry(void *p1, void *p2, void *p3) +{ + k_sem_take(&sem1, K_FOREVER); +} + +static int obj_core_find_op(struct k_obj_core *obj_core, void *data) +{ + struct obj_core_find_data *find_data = data; + + if (find_data->obj_core == obj_core) { + + /* Object core found. Abort the search. */ + + return 1; + } + + /* Object core not found--continue searching. */ + + return 0; +} + +static void common_obj_core_test(uint32_t type_id, const char *str, + struct k_obj_core *static_obj_core, + struct k_obj_core *dyn_obj_core) +{ + struct k_obj_type *obj_type; + struct obj_core_find_data walk_data; + int status; + + obj_type = k_obj_type_find(type_id); + + zassert_not_null(obj_type, "%s object type not found\n", str); + + /* Search for statically initialized object */ + + if (static_obj_core != NULL) { + walk_data.obj_core = static_obj_core; + status = k_obj_type_walk_locked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 1, + "static %s not found with locked walk\n", str); + + status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 1, + "static %s not found with unlocked walk\n", str); + } + + /* Search for dynamically initialized object */ + + if (dyn_obj_core != NULL) { + walk_data.obj_core = dyn_obj_core; + status = k_obj_type_walk_locked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 1, + "dynamic %s not found with locked walk\n", str); + + status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 1, + "dynamic %s not found with unlocked walk\n", str); + } +} + +ZTEST(obj_core, test_obj_core_thread) +{ + k_thread_create(&thread2, thread2_stack, + K_THREAD_STACK_SIZEOF(thread2_stack), thread_entry, + NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); + + common_obj_core_test(K_OBJ_TYPE_THREAD_ID, "thread", + K_OBJ_CORE(thread1), K_OBJ_CORE(&thread2)); + + /* Terminate both thread1 and thread 2 */ + + k_thread_abort(thread1); + k_thread_abort(&thread2); + + /* + * Neither thread1 nor thread2 should be in the thread object type's + * list of threads anymore. Verify this. + */ + + struct k_obj_type *obj_type; + struct obj_core_find_data walk_data; + int status; + + obj_type = k_obj_type_find(K_OBJ_TYPE_THREAD_ID); + + zassert_not_null(obj_type, "thread object type not found\n"); + + /* Search for statically initialized object */ + + walk_data.obj_core = K_OBJ_CORE(thread1); + status = k_obj_type_walk_locked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 0, "static thread found with locked walk\n"); + + status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 0, "static thread found with unlocked walk\n"); + + walk_data.obj_core = K_OBJ_CORE(&thread2); + status = k_obj_type_walk_locked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 0, "dynamic thread found with locked walk\n"); + + status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op, + &walk_data); + zassert_equal(status, 0, "dynamic thread found with unlocked walk\n"); +} + +ZTEST(obj_core, test_obj_core_system) +{ + int i; + char cpu_str[16]; + + /* + * Use the existing object cores in the _cpu and z_kerenl structures + * as we should not be creating new ones. + */ + + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + sprintf(cpu_str, "CPU%d", i); + common_obj_core_test(K_OBJ_TYPE_CPU_ID, cpu_str, + K_OBJ_CORE(&_kernel.cpus[i]), NULL); + } + + common_obj_core_test(K_OBJ_TYPE_KERNEL_ID, "_kernel", + K_OBJ_CORE(&_kernel), NULL); +} + +ZTEST(obj_core, test_obj_core_sys_mem_block) +{ + common_obj_core_test(K_OBJ_TYPE_MEM_BLOCK_ID, "memory block", + K_OBJ_CORE(&block1), NULL); +} + +ZTEST(obj_core, test_obj_core_mem_slab) +{ + k_mem_slab_init(&slab2, slab2_buffer, 32, 8); + common_obj_core_test(K_OBJ_TYPE_MEM_SLAB_ID, "memory slab", + K_OBJ_CORE(&slab1), K_OBJ_CORE(&slab2)); +} + +ZTEST(obj_core, test_obj_core_timer) +{ + k_timer_init(&timer2, NULL, NULL); + common_obj_core_test(K_OBJ_TYPE_TIMER_ID, "timer", + K_OBJ_CORE(&timer1), K_OBJ_CORE(&timer2)); +} + +ZTEST(obj_core, test_obj_core_stack) +{ + k_stack_init(&stack2, stack2_buffer, 8); + common_obj_core_test(K_OBJ_TYPE_STACK_ID, "stack", + K_OBJ_CORE(&stack1), K_OBJ_CORE(&stack2)); +} + +ZTEST(obj_core, test_obj_core_fifo) +{ + k_fifo_init(&fifo2); + common_obj_core_test(K_OBJ_TYPE_FIFO_ID, "FIFO", + K_OBJ_CORE(&fifo1), K_OBJ_CORE(&fifo2)); +} + +ZTEST(obj_core, test_obj_core_lifo) +{ + k_lifo_init(&lifo2); + common_obj_core_test(K_OBJ_TYPE_LIFO_ID, "LIFO", + K_OBJ_CORE(&lifo1), K_OBJ_CORE(&lifo2)); +} + +ZTEST(obj_core, test_obj_core_pipe) +{ + k_pipe_init(&pipe2, pipe2_buffer, sizeof(pipe2_buffer)); + common_obj_core_test(K_OBJ_TYPE_PIPE_ID, "pipe", + K_OBJ_CORE(&pipe1), K_OBJ_CORE(&pipe2)); +} + +ZTEST(obj_core, test_obj_core_msgq) +{ + k_msgq_init(&msgq2, msgq2_buffer, 4, 4); + common_obj_core_test(K_OBJ_TYPE_MSGQ_ID, "message queue", + K_OBJ_CORE(&msgq1), K_OBJ_CORE(&msgq2)); +} + +ZTEST(obj_core, test_obj_core_mbox) +{ + k_mbox_init(&mbox2); + common_obj_core_test(K_OBJ_TYPE_MBOX_ID, "mailbox", + K_OBJ_CORE(&mbox1), K_OBJ_CORE(&mbox2)); +} + +ZTEST(obj_core, test_obj_core_condvar) +{ + k_condvar_init(&condvar2); + common_obj_core_test(K_OBJ_TYPE_CONDVAR_ID, "condition variable", + K_OBJ_CORE(&condvar1), K_OBJ_CORE(&condvar2)); +} + +ZTEST(obj_core, test_obj_core_event) +{ + k_event_init(&event2); + common_obj_core_test(K_OBJ_TYPE_EVENT_ID, "event", + K_OBJ_CORE(&event1), K_OBJ_CORE(&event2)); +} + +ZTEST(obj_core, test_obj_core_mutex) +{ + k_mutex_init(&mutex2); + common_obj_core_test(K_OBJ_TYPE_MUTEX_ID, "mutex", + K_OBJ_CORE(&mutex1), K_OBJ_CORE(&mutex2)); +} + +ZTEST(obj_core, test_obj_core_sem) +{ + k_sem_init(&sem2, 0, 1); + + common_obj_core_test(K_OBJ_TYPE_SEM_ID, "semaphore", + K_OBJ_CORE(&sem1), K_OBJ_CORE(&sem2)); +} + +ZTEST_SUITE(obj_core, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); diff --git a/tests/kernel/obj_core/obj_core/testcase.yaml b/tests/kernel/obj_core/obj_core/testcase.yaml new file mode 100644 index 00000000000..e6bcafafc56 --- /dev/null +++ b/tests/kernel/obj_core/obj_core/testcase.yaml @@ -0,0 +1,9 @@ +tests: + kernel.obj_core: + tags: kernel + ignore_faults: true + integration_platforms: + - qemu_x86 + platform_exclude: + - qemu_x86_tiny + - qemu_x86_tiny@768 From d709182ba5d56e398bf8e8801bcecbb6e17a7357 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 2 Jun 2023 11:26:34 -0400 Subject: [PATCH 1480/4498] test: Implement object core stats API test Creates a set of tests to verify that the top-level k_obj_core_stats_xxx() routines behave as expected. Note that this test is not meant to test the details of the object core statistics operator function pointers. Signed-off-by: Peter Mitsis --- .../obj_core_stats_api/CMakeLists.txt | 8 + .../obj_core/obj_core_stats_api/prj.conf | 7 + .../obj_core/obj_core_stats_api/src/main.c | 325 ++++++++++++++++++ .../obj_core/obj_core_stats_api/testcase.yaml | 9 + 4 files changed, 349 insertions(+) create mode 100644 tests/kernel/obj_core/obj_core_stats_api/CMakeLists.txt create mode 100644 tests/kernel/obj_core/obj_core_stats_api/prj.conf create mode 100644 tests/kernel/obj_core/obj_core_stats_api/src/main.c create mode 100644 tests/kernel/obj_core/obj_core_stats_api/testcase.yaml diff --git a/tests/kernel/obj_core/obj_core_stats_api/CMakeLists.txt b/tests/kernel/obj_core/obj_core_stats_api/CMakeLists.txt new file mode 100644 index 00000000000..a9c26c7493c --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats_api/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(obj_core) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/obj_core/obj_core_stats_api/prj.conf b/tests/kernel/obj_core/obj_core_stats_api/prj.conf new file mode 100644 index 00000000000..c6a53340e13 --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats_api/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_OBJ_CORE=y +CONFIG_OBJ_CORE_STATS=y +CONFIG_PIPES=y +CONFIG_SCHED_THREAD_USAGE=y +CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y diff --git a/tests/kernel/obj_core/obj_core_stats_api/src/main.c b/tests/kernel/obj_core/obj_core_stats_api/src/main.c new file mode 100644 index 00000000000..c6638e28a31 --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats_api/src/main.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +K_SEM_DEFINE(test_sem, 0, 1); + +static void test_thread_entry(void *, void *, void *); +K_THREAD_DEFINE(test_thread, 512, test_thread_entry, NULL, NULL, NULL, + K_HIGHEST_THREAD_PRIO, 0, 0); + +/* + * As the test mucks about with the set of object core statistics operators + * for the test_thread, we want to ensure that no other test mucks with it + * at an inopportune time. This could also be done by setting the CPU count + * in the prj.conf to 1. However, for this test to allow it to be run on both + * UP and SMP systems the mutex is being used. + */ + +K_MUTEX_DEFINE(test_mutex); + +static void test_thread_entry(void *p1, void *p2, void *p3) +{ + k_sem_take(&test_sem, K_FOREVER); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_enable) +{ + int status; + int (*saved_enable)(struct k_obj_core *obj_core); + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to enable stats for an object core that is not enabled + * for statistics (semaphores). + */ + + status = k_obj_core_stats_enable(K_OBJ_CORE(&test_sem)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + saved_enable = K_OBJ_CORE(test_thread)->type->stats_desc->enable; + K_OBJ_CORE(test_thread)->type->stats_desc->enable = NULL; + status = k_obj_core_stats_enable(K_OBJ_CORE(test_thread)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + K_OBJ_CORE(test_thread)->type->stats_desc->enable = saved_enable; + + /* + * Note: Testing the stats enable function pointer is done in another + * set of tests. + */ + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_disable) +{ + int status; + int (*saved_disable)(struct k_obj_core *obj_core); + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to disable stats for an object core that is not enabled + * for statistics (semaphores). + */ + + status = k_obj_core_stats_disable(K_OBJ_CORE(&test_sem)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + saved_disable = K_OBJ_CORE(test_thread)->type->stats_desc->disable; + K_OBJ_CORE(test_thread)->type->stats_desc->disable = NULL; + status = k_obj_core_stats_disable(K_OBJ_CORE(test_thread)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + K_OBJ_CORE(test_thread)->type->stats_desc->disable = saved_disable; + + /* + * Note: Testing the stats disable function pointer is done in + * another set of tests. + */ + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_reset) +{ + int status; + int (*saved_reset)(struct k_obj_core *obj_core); + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to reset stats for an object core that is not enabled + * for statistics (semaphores). + */ + + status = k_obj_core_stats_reset(K_OBJ_CORE(&test_sem)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + saved_reset = K_OBJ_CORE(test_thread)->type->stats_desc->reset; + K_OBJ_CORE(test_thread)->type->stats_desc->reset = NULL; + status = k_obj_core_stats_reset(K_OBJ_CORE(test_thread)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + K_OBJ_CORE(test_thread)->type->stats_desc->reset = saved_reset; + + /* + * Note: Testing the stats reset function pointer is done in + * another set of tests. + */ + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_query) +{ + int status; + struct k_thread_runtime_stats query; + int (*saved_query)(struct k_obj_core *obj_core, void *stats); + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to query stats for an object core that is not enabled + * for statistics (semaphores). + */ + + status = k_obj_core_stats_query(K_OBJ_CORE(&test_sem), &query, + sizeof(struct k_thread_runtime_stats)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + saved_query = K_OBJ_CORE(test_thread)->type->stats_desc->query; + K_OBJ_CORE(test_thread)->type->stats_desc->query = NULL; + status = k_obj_core_stats_query(K_OBJ_CORE(test_thread), + &query, sizeof(query)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + K_OBJ_CORE(test_thread)->type->stats_desc->query = saved_query; + + /* + * Note: Testing the stats query function pointer is done in + * another set of tests. + */ + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_raw) +{ + int status; + char buffer[sizeof(struct k_cycle_stats)]; + int (*saved_raw)(struct k_obj_core *obj_core, void *stats); + void *saved_stats; + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to get raw stats for an object core that is not enabled + * for statistics (semaphores). + */ + + status = k_obj_core_stats_raw(K_OBJ_CORE(&test_sem), + buffer, sizeof(buffer)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + /* Force there to be no means to obtain raw data */ + + saved_raw = K_OBJ_CORE(test_thread)->type->stats_desc->raw; + K_OBJ_CORE(test_thread)->type->stats_desc->raw = NULL; + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), + buffer, sizeof(buffer)); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n", -ENOTSUP, status); + + K_OBJ_CORE(test_thread)->type->stats_desc->raw = saved_raw; + + /* + * Verify that passing a buffer with unexpected length + * returns the expected error (-EINVAL). + */ + + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), + buffer, 0); + zassert_equal(status, -EINVAL, + "Expected %d, got %d\n", -EINVAL, status); + + /* + * Verify that if the object core's pointer to raw stats data + * is NULL, we get the expected error (-EINVAL). + */ + + saved_stats = K_OBJ_CORE(test_thread)->stats; + K_OBJ_CORE(test_thread)->stats = NULL; + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), + buffer, sizeof(buffer)); + zassert_equal(status, -EINVAL, + "Expected %d, got %d\n", -EINVAL, status); + K_OBJ_CORE(test_thread)->stats = saved_stats; + + /* + * Note: Further testing the stats query function pointer is done in + * another set of tests. + */ + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_deregister) +{ + int status; + char buffer[sizeof(struct k_cycle_stats)]; + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to de-register stats for an object core that does + * not have them enabled (semaphores). + */ + + status = k_obj_core_stats_deregister(K_OBJ_CORE(&test_sem)); + zassert_equal(status, -ENOTSUP, "Expected %d, got %d\n", 0, -ENOTSUP); + + /* De-register stats for the test thread. */ + + status = k_obj_core_stats_deregister(K_OBJ_CORE(test_thread)); + zassert_equal(status, 0, "Expected %d, got %d\n", 0, status); + + /* Attempt to get raw stats for the de-registered thread */ + + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), + buffer, sizeof(buffer)); + zassert_equal(status, -EINVAL, + "Expected %d, got %d\n", -EINVAL, status); + + /* Restore the raw stats */ + + status = k_obj_core_stats_register(K_OBJ_CORE(test_thread), + &test_thread->base.usage, + sizeof(struct k_cycle_stats)); + + k_mutex_unlock(&test_mutex); +} + +ZTEST(obj_core_stats_api, test_obj_core_stats_register) +{ + int status; + char buffer[sizeof(struct k_cycle_stats)]; + char data[sizeof(struct k_cycle_stats)]; + + /* + * Ensure only one thread is mucking around with test_thread + * at a time. + */ + + k_mutex_lock(&test_mutex, K_FOREVER); + + /* + * Attempt to register stats for a semaphore + * (which does not currently exist). + */ + + status = k_obj_core_stats_register(K_OBJ_CORE(&test_sem), + (void *)0xBAD0BAD1, + 42); + + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d\n" + "--Were semaphore stats recently implemented?\n", + -ENOTSUP, status); + /* + * Attempt to register stats for a thread with the wrong buffer + * size. + */ + + status = k_obj_core_stats_register(K_OBJ_CORE(test_thread), + buffer, sizeof(buffer) + 42); + + zassert_equal(status, -EINVAL, + "Expected %d, got %d\n", -EINVAL, status); + + /* + * Attempt to register stats for a thread with the right buffer + * size. + */ + + status = k_obj_core_stats_register(K_OBJ_CORE(test_thread), + buffer, sizeof(buffer)); + + zassert_equal(status, 0, + "Failed to change raw buffer pointer (%d)\n", status); + + memset(buffer, 0xaa, sizeof(buffer)); + memset(data, 0x00, sizeof(data)); + + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), + data, sizeof(data)); + zassert_equal(status, 0, "Expected %d, got %d\n", 0, status); + + zassert_mem_equal(buffer, data, sizeof(buffer), + "Test thread raw stats buffer was not changed\n"); + + /* Restore the test thread's raw stats buffer */ + + status = k_obj_core_stats_register(K_OBJ_CORE(test_thread), + &test_thread->base.usage, + sizeof(test_thread->base.usage)); + zassert_equal(status, 0, + "Expected %d, got %d\n", 0, status); + + k_mutex_unlock(&test_mutex); +} + +ZTEST_SUITE(obj_core_stats_api, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); diff --git a/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml b/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml new file mode 100644 index 00000000000..6ac7bfe663b --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml @@ -0,0 +1,9 @@ +tests: + kernel.obj_core_stats_api: + tags: kernel + ignore_faults: true + integration_platforms: + - qemu_x86 + platform_exclude: + - qemu_x86_tiny + - qemu_x86_tiny@768 From eb86a0cca51a44799abdf29261700b457249d540 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 5 Jun 2023 10:29:57 -0400 Subject: [PATCH 1481/4498] test: Implement obj core stats test Adds a test to test the objects integrated into the object core statistics framework. Signed-off-by: Peter Mitsis --- .../obj_core/obj_core_stats/CMakeLists.txt | 8 + tests/kernel/obj_core/obj_core_stats/prj.conf | 8 + .../kernel/obj_core/obj_core_stats/src/main.c | 704 ++++++++++++++++++ .../obj_core/obj_core_stats/testcase.yaml | 9 + 4 files changed, 729 insertions(+) create mode 100644 tests/kernel/obj_core/obj_core_stats/CMakeLists.txt create mode 100644 tests/kernel/obj_core/obj_core_stats/prj.conf create mode 100644 tests/kernel/obj_core/obj_core_stats/src/main.c create mode 100644 tests/kernel/obj_core/obj_core_stats/testcase.yaml diff --git a/tests/kernel/obj_core/obj_core_stats/CMakeLists.txt b/tests/kernel/obj_core/obj_core_stats/CMakeLists.txt new file mode 100644 index 00000000000..a9c26c7493c --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(obj_core) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/obj_core/obj_core_stats/prj.conf b/tests/kernel/obj_core/obj_core_stats/prj.conf new file mode 100644 index 00000000000..47b02f61737 --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats/prj.conf @@ -0,0 +1,8 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_OBJ_CORE=y +CONFIG_OBJ_CORE_STATS=y +CONFIG_SCHED_THREAD_USAGE=y +CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y +CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION=y +CONFIG_SYS_MEM_BLOCKS=y diff --git a/tests/kernel/obj_core/obj_core_stats/src/main.c b/tests/kernel/obj_core/obj_core_stats/src/main.c new file mode 100644 index 00000000000..24d649e363a --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats/src/main.c @@ -0,0 +1,704 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +SYS_MEM_BLOCKS_DEFINE(mem_block, 32, 4, 16); /* Four 32 byte blocks */ + +K_MEM_SLAB_DEFINE(mem_slab, 32, 4, 16); /* Four 32 byte blocks */ + +#if !defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_SPARC) && !defined(CONFIG_MIPS) +static void test_thread_entry(void *, void *, void *); +K_THREAD_DEFINE(test_thread, 1024, test_thread_entry, NULL, NULL, NULL, + K_HIGHEST_THREAD_PRIO, 0, 0); + +K_SEM_DEFINE(wake_main_thread, 0, 1); +K_SEM_DEFINE(wake_test_thread, 0, 1); +#endif /* !CONFIG_ARCH_POSIX && !CONFIG_SPARC && !CONFIG_MIPS */ + +#if CONFIG_MP_MAX_NUM_CPUS > 1 +K_THREAD_STACK_ARRAY_DEFINE(busy_thread_stack, CONFIG_MP_MAX_NUM_CPUS - 1, 512); + +struct k_thread busy_thread[CONFIG_MP_MAX_NUM_CPUS - 1]; + +void busy_thread_entry(void *p1, void *p2, void *p3) +{ + while (1) { + /* Busy loop to prevent CPU from entering idle */ + } +} + +#endif + +/***************** SYSTEM (CPUs and KERNEL) ******************/ + +/* + * As the k_obj_core_stats_xxx() APIs are essentially wrappers to the + * thread runtime stats APIs, limit this test to the same architectures as + * that thread runtime stats test. + */ + +#if !defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_SPARC) && !defined(CONFIG_MIPS) +ZTEST(obj_core_stats_system, test_obj_core_stats_system) +{ + int status; + struct k_cycle_stats kernel_raw[CONFIG_MP_MAX_NUM_CPUS]; + struct k_cycle_stats cpu_raw; + struct k_thread_runtime_stats kernel_query; + struct k_thread_runtime_stats cpu_query; + struct k_thread_runtime_stats sum_query; + unsigned int i; + +#if CONFIG_MP_MAX_NUM_CPUS > 1 + + /* Create 1 busy thread for each core except the current */ + + int prio; + + prio = k_thread_priority_get(k_current_get()); + + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS - 1; i++) { + k_thread_create(&busy_thread[i], busy_thread_stack[i], + K_THREAD_STACK_SIZEOF(busy_thread_stack[i]), + busy_thread_entry, NULL, NULL, NULL, + prio + 10, 0, K_NO_WAIT); + } +#endif + + status = k_obj_core_stats_raw(K_OBJ_CORE(&_kernel), kernel_raw, + sizeof(kernel_raw)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + /* + * Not much can be predicted for the raw stats aside from the + * the contents of the CPU sampling to be at least as large as + * kernel sampling. The same goes for the query stats. + */ + + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + status = k_obj_core_stats_raw(K_OBJ_CORE(&_kernel.cpus[i]), + &cpu_raw, sizeof(cpu_raw)); + zassert_equal(status, 0, "Expected 0, got %d on CPU %u\n", + status, i); + + zassert_true(cpu_raw.total >= kernel_raw[i].total); +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + zassert_true(cpu_raw.current >= kernel_raw[i].current); + zassert_true(cpu_raw.longest >= kernel_raw[i].longest); + zassert_true(cpu_raw.num_windows >= kernel_raw[i].num_windows); +#endif + zassert_true(cpu_raw.track_usage == kernel_raw[i].track_usage); + } + + status = k_obj_core_stats_query(K_OBJ_CORE(&_kernel), &kernel_query, + sizeof(kernel_query)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + sum_query = (struct k_thread_runtime_stats){}; + + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + status = k_obj_core_stats_query(K_OBJ_CORE(&_kernel.cpus[i]), + &cpu_query, sizeof(cpu_query)); + zassert_equal(status, 0, "Expected 0, got %d on CPU %u\n", + status, i); + +#ifdef CONFIG_SCHED_THREAD_USAGE + sum_query.execution_cycles += cpu_query.execution_cycles; + sum_query.total_cycles += cpu_query.total_cycles; +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + sum_query.current_cycles += cpu_query.current_cycles; + sum_query.peak_cycles += cpu_query.peak_cycles; + sum_query.average_cycles += cpu_query.average_cycles; +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + sum_query.idle_cycles += cpu_query.idle_cycles; +#endif + } + +#ifdef CONFIG_SCHED_THREAD_USAGE + zassert_true(sum_query.execution_cycles >= kernel_query.execution_cycles); + zassert_true(sum_query.total_cycles >= kernel_query.total_cycles); +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + zassert_true(sum_query.current_cycles >= kernel_query.current_cycles); + zassert_true(sum_query.peak_cycles >= kernel_query.peak_cycles); + zassert_true(sum_query.average_cycles >= kernel_query.average_cycles); +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + zassert_true(sum_query.idle_cycles >= kernel_query.idle_cycles); +#endif +} +#endif /* !CONFIG_ARCH_POSIX && !CONFIG_SPARC && !CONFIG_MIPS */ + +ZTEST(obj_core_stats_system, test_obj_core_stats_cpu_reset) +{ + int status; + + for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + status = k_obj_core_stats_reset(K_OBJ_CORE(&_kernel.cpus[i])); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d on CPU%d\n", + -ENOTSUP, status, i); + } +} + +ZTEST(obj_core_stats_system, test_obj_core_stats_cpu_disable) +{ + int status; + + for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + status = k_obj_core_stats_disable(K_OBJ_CORE(&_kernel.cpus[i])); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d on CPU%d\n", + -ENOTSUP, status, i); + } +} + +ZTEST(obj_core_stats_system, test_obj_core_stats_cpu_enable) +{ + int status; + + for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + status = k_obj_core_stats_enable(K_OBJ_CORE(&_kernel.cpus[i])); + zassert_equal(status, -ENOTSUP, + "Expected %d, got %d on CPU%d\n", + -ENOTSUP, status, i); + } +} + +ZTEST(obj_core_stats_system, test_obj_core_stats_kernel_reset) +{ + int status; + + status = k_obj_core_stats_reset(K_OBJ_CORE(&_kernel)); + zassert_equal(status, -ENOTSUP, "Expected %d, got %d\n", + -ENOTSUP, status); +} + +ZTEST(obj_core_stats_system, test_obj_core_stats_kernel_disable) +{ + int status; + + status = k_obj_core_stats_disable(K_OBJ_CORE(&_kernel)); + zassert_equal(status, -ENOTSUP, "Expected %d, got %d\n", + -ENOTSUP, status); +} + +ZTEST(obj_core_stats_system, test_obj_core_stats_kernel_enable) +{ + int status; + + status = k_obj_core_stats_enable(K_OBJ_CORE(&_kernel)); + zassert_equal(status, -ENOTSUP, "Expected %d, got %d\n", + -ENOTSUP, status); +} + +/***************** THREADS ******************/ + +#if !defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_SPARC) && !defined(CONFIG_MIPS) +/* + * As the k_obj_core_stats_xxx() APIs are essentially wrappers to the + * thread runtime stats APIs, limit this test to the same architectures as + * that thread runtime stats test. + */ +void test_thread_entry(void *p1, void *p2, void *p3) +{ + while (1) { + k_busy_wait(10000); + + k_sem_give(&wake_main_thread); + k_sem_take(&wake_test_thread, K_FOREVER); + } +} + +ZTEST(obj_core_stats_thread, test_obj_core_stats_thread_test) +{ + struct k_cycle_stats raw1; + struct k_cycle_stats raw2; + struct k_thread_runtime_stats query1; + struct k_thread_runtime_stats query2; + struct k_thread_runtime_stats query3; + int status; + + k_sem_take(&wake_main_thread, K_FOREVER); + k_busy_wait(10000); + + /* test_thread should now be blocked on wake_test_thread */ + + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), &raw1, + sizeof(raw1)); + zassert_equal(status, 0, "Expected 0, got %d", status); + + status = k_obj_core_stats_query(K_OBJ_CORE(test_thread), &query1, + sizeof(query1)); + zassert_equal(status, 0, "Expected 0, got %d", status); + + /* + * Busy wait for 10 msec. As test_thread should still be blocked, + * its stats data should not change. + */ + + k_busy_wait(10000); + + status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread), &raw2, + sizeof(raw2)); + zassert_equal(status, 0, "Expected 0, got %d", status); + + status = k_obj_core_stats_query(K_OBJ_CORE(test_thread), &query2, + sizeof(query2)); + zassert_equal(status, 0, "Expected 0, got %d", status); + + zassert_mem_equal(&raw1, &raw2, sizeof(raw1), + "Thread raw stats changed while blocked\n"); + zassert_mem_equal(&query1, &query2, sizeof(query1), + "Thread query stats changed while blocked\n"); + + /* + * Let test_thread execute for a short bit and then re-sample the + * stats. As the k_obj_core_stats_query() backend is identical to + * that of k_thread_runtime_stats_get(), their queries should be + * identical (and different from the previous sample). + */ + + k_sem_give(&wake_test_thread); + k_sem_take(&wake_main_thread, K_FOREVER); + k_busy_wait(10000); + + /* test_thread should now be blocked. */ + + status = k_obj_core_stats_query(K_OBJ_CORE(test_thread), &query2, + sizeof(query3)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + status = k_thread_runtime_stats_get(test_thread, &query3); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + zassert_mem_equal(&query2, &query3, sizeof(query2), + "Queries not equal!\n"); + +#ifdef CONFIG_SCHED_THREAD_USAGE + zassert_true(query2.execution_cycles > query1.execution_cycles, + "Execution cycles did not increase\n"); + zassert_true(query2.total_cycles > query1.total_cycles, + "Total cycles did not increase\n"); +#endif + +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + + /* + * [current_cycles], [peak_cycles] and [average_cycles] can not be + * predicted by this test. + */ + +#endif + +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + zassert_equal(query2.idle_cycles, 0, + "Expected 0, got %llu\n", query2.idle_cycles); +#endif + + /* Reset the stats */ + + status = k_obj_core_stats_reset(K_OBJ_CORE(test_thread)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + status = k_obj_core_stats_query(K_OBJ_CORE(test_thread), + &query3, sizeof(query3)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + +#ifdef CONFIG_SCHED_THREAD_USAGE + zassert_equal(query3.execution_cycles, 0, + "Expected 0, got %llu\n", query3.execution_cycles); + zassert_equal(query3.total_cycles, 0, + "Expected 0, got %llu\n", query3.total_cycles); +#endif + +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + zassert_equal(query3.current_cycles, 0, + "Expected 0, got %llu\n", query3.current_cycles); + zassert_equal(query3.peak_cycles, 0, + "Expected 0, got %llu\n", query3.peak_cycles); + zassert_equal(query3.average_cycles, 0, + "Expected 0, got %llu\n", query3.average_cycles); +#endif + +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + zassert_equal(query3.idle_cycles, 0, + "Expected 0, got %llu\n", query3.idle_cycles); +#endif + + /* Disable the stats (re-using query2 and query3) */ + + status = k_obj_core_stats_disable(K_OBJ_CORE(test_thread)); + zassert_equal(status, 0, "Expected 0, got %llu\n", status); + + k_sem_give(&wake_test_thread); + k_sem_take(&wake_main_thread, K_FOREVER); + k_busy_wait(10000); + + k_obj_core_stats_query(K_OBJ_CORE(test_thread), + &query2, sizeof(query2)); + + zassert_mem_equal(&query2, &query3, sizeof(query2), + "Stats changed while disabled!\n"); + + /* Enable the stats */ + + status = k_obj_core_stats_enable(K_OBJ_CORE(test_thread)); + zassert_equal(status, 0, "Expected 0, got %llu\n", status); + + k_sem_give(&wake_test_thread); + k_sem_take(&wake_main_thread, K_FOREVER); + k_busy_wait(10000); + + k_obj_core_stats_query(K_OBJ_CORE(test_thread), + &query3, sizeof(query3)); + + /* We can not predict the stats, but they should be non-zero. */ + +#ifdef CONFIG_SCHED_THREAD_USAGE + zassert_true(query3.execution_cycles > 0); + zassert_true(query3.total_cycles > 0); +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE + zassert_true(query3.current_cycles > 0); + zassert_true(query3.peak_cycles > 0); + zassert_true(query3.average_cycles > 0); +#endif +#ifdef CONFIG_SCHED_THREAD_USAGE_ALL + zassert_true(query3.idle_cycles == 0); +#endif + + k_thread_abort(test_thread); +} +#endif /* !CONFIG_ARCH_POSIX && !CONFIG_SPARC && !CONFIG_MIPS */ + +/***************** SYSTEM MEMORY BLOCKS *********************/ + +ZTEST(obj_core_stats_mem_block, test_sys_mem_block_enable) +{ + int status; + + status = k_obj_core_stats_enable(K_OBJ_CORE(&mem_block)); + zassert_equal(status, -ENOTSUP, + "Not supposed to be supported. Got %d, not %d\n", + status, -ENOTSUP); +} + +ZTEST(obj_core_stats_mem_block, test_sys_mem_block_disable) +{ + int status; + + status = k_obj_core_stats_disable(K_OBJ_CORE(&mem_block)); + zassert_equal(status, -ENOTSUP, + "Not supposed to be supported. Got %d, not %d\n", + status, -ENOTSUP); +} + +static void test_mem_block_raw(const char *str, + struct sys_mem_blocks_info *expected) +{ + int status; + struct sys_mem_blocks_info raw; + + status = k_obj_core_stats_raw(K_OBJ_CORE(&mem_block), &raw, + sizeof(raw)); + zassert_equal(status, 0, + "%s: Failed to get raw stats (%d)\n", str, status); + + zassert_equal(raw.num_blocks, expected->num_blocks, + "%s: Expected %u blocks, got %u\n", + str, expected->num_blocks, raw.num_blocks); + zassert_equal(raw.blk_sz_shift, expected->blk_sz_shift, + "%s: Expected blk_sz_shift=%u, got %u\n", + str, expected->blk_sz_shift, raw.blk_sz_shift); +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + zassert_equal(raw.used_blocks, expected->used_blocks, + "%s: Expected %u used, got %d\n", + str, expected->used_blocks, raw.used_blocks); + zassert_equal(raw.max_used_blocks, expected->max_used_blocks, + "%s: Expected max %u used, got %d\n", + str, expected->max_used_blocks, raw.max_used_blocks); +#endif +} + +static void test_mem_block_query(const char *str, + struct sys_memory_stats *expected) +{ + struct sys_memory_stats query; + int status; + + status = k_obj_core_stats_query(K_OBJ_CORE(&mem_block), &query, + sizeof(query)); + zassert_equal(status, 0, + "%s: Failed to get query stats (%d)\n", str, status); + + zassert_equal(query.free_bytes, expected->free_bytes, + "%s: Expected %u free bytes, got %u\n", + str, expected->free_bytes, query.free_bytes); +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + zassert_equal(query.allocated_bytes, expected->allocated_bytes, + "%s: Expected %u allocated bytes, got %u\n", + str, expected->allocated_bytes, query.allocated_bytes); + zassert_equal(query.max_allocated_bytes, expected->max_allocated_bytes, + "%s: Expected %u max_allocated bytes, got %d\n", + str, expected->max_allocated_bytes, + query.max_allocated_bytes); +#endif +} + +ZTEST(obj_core_stats_mem_block, test_obj_core_stats_mem_block) +{ + struct sys_mem_blocks_info raw = { + .num_blocks = 4, .blk_sz_shift = 5, +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + .used_blocks = 0, .max_used_blocks = 0 +#endif + }; + struct sys_memory_stats query = { + .free_bytes = 128, + .allocated_bytes = 0, + .max_allocated_bytes = 0 + }; + void *mem1; + void *mem2; + int status; + + /* + * As the ordering of the "raw", "query" and "reset" tests matter, + * they have been grouped together here. As they are for the most + * wrappers for the runtime stats routines, minimal testing is + * being done. + */ + + /* Initial checks */ + + test_mem_block_raw("Initial", &raw); + test_mem_block_query("Initial", &query); + + /* Allocate 1st block */ + + status = sys_mem_blocks_alloc(&mem_block, 1, &mem1); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + query.free_bytes -= 32; + query.allocated_bytes += 32; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + raw.used_blocks++; + raw.max_used_blocks++; + query.max_allocated_bytes += 32; +#endif + test_mem_block_raw("1st Alloc", &raw); + test_mem_block_query("1st Alloc", &query); + + /* Allocate 2nd block */ + + status = sys_mem_blocks_alloc(&mem_block, 1, &mem2); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + query.free_bytes -= 32; + query.allocated_bytes += 32; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + raw.used_blocks++; + raw.max_used_blocks++; + query.max_allocated_bytes += 32; +#endif + test_mem_block_raw("2nd Alloc", &raw); + test_mem_block_query("2nd Alloc", &query); + + /* Free 1st block */ + + sys_mem_blocks_free(&mem_block, 1, &mem1); + + query.free_bytes += 32; + query.allocated_bytes -= 32; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + raw.used_blocks--; +#endif + test_mem_block_raw("Free 1st", &raw); + test_mem_block_query("Free 1st", &query); + + /* Reset the mem block stats */ + + status = k_obj_core_stats_reset(K_OBJ_CORE(&mem_block)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + raw.max_used_blocks = raw.used_blocks; + query.max_allocated_bytes = query.allocated_bytes; +#endif + test_mem_block_raw("Reset", &raw); + test_mem_block_query("Reset", &query); + + /* Cleanup - Free 2nd block */ + sys_mem_blocks_free(&mem_block, 1, &mem2); +} + +/***************** MEMORY SLABS *********************/ + +ZTEST(obj_core_stats_mem_slab, test_mem_slab_enable) +{ + int status; + + status = k_obj_core_stats_disable(K_OBJ_CORE(&mem_slab)); + zassert_equal(status, -ENOTSUP, + "Not supposed to be supported. Got %d, not %d\n", + status, -ENOTSUP); +} + +ZTEST(obj_core_stats_mem_slab, test_mem_slab_disable) +{ + int status; + + status = k_obj_core_stats_disable(K_OBJ_CORE(&mem_slab)); + zassert_equal(status, -ENOTSUP, + "Not supposed to be supported. Got %d, not %d\n", + status, -ENOTSUP); +} + +static void test_mem_slab_raw(const char *str, struct k_mem_slab_info *expected) +{ + int status; + struct k_mem_slab_info raw; + + status = k_obj_core_stats_raw(K_OBJ_CORE(&mem_slab), &raw, + sizeof(raw)); + zassert_equal(status, 0, + "%s: Failed to get raw stats (%d)\n", str, status); + + zassert_equal(raw.num_blocks, expected->num_blocks, + "%s: Expected %u blocks, got %u\n", + str, expected->num_blocks, raw.num_blocks); + zassert_equal(raw.block_size, expected->block_size, + "%s: Expected block size=%u blocks, got %u\n", + str, expected->block_size, raw.block_size); + zassert_equal(raw.num_used, expected->num_used, + "%s: Expected %u used, got %d\n", + str, expected->num_used, raw.num_used); +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + zassert_equal(raw.max_used, expected->max_used, + "%s: Expected max %u used, got %d\n", + str, expected->max_used, raw.max_used); +#endif +} + +static void test_mem_slab_query(const char *str, + struct sys_memory_stats *expected) +{ + struct sys_memory_stats query; + int status; + + status = k_obj_core_stats_query(K_OBJ_CORE(&mem_slab), &query, + sizeof(query)); + zassert_equal(status, 0, + "%s: Failed to get query stats (%d)\n", str, status); + + zassert_equal(query.free_bytes, expected->free_bytes, + "%s: Expected %u free bytes, got %u\n", + str, expected->free_bytes, query.free_bytes); + zassert_equal(query.allocated_bytes, expected->allocated_bytes, + "%s: Expected %u allocated bytes, got %u\n", + str, expected->allocated_bytes, query.allocated_bytes); + zassert_equal(query.max_allocated_bytes, expected->max_allocated_bytes, + "%s: Expected %u max_allocated bytes, got %d\n", + str, expected->max_allocated_bytes, + query.max_allocated_bytes); +} + +ZTEST(obj_core_stats_mem_slab, test_obj_core_stats_mem_slab) +{ + struct k_mem_slab_info raw = { + .num_blocks = 4, .block_size = 32, .num_used = 0, +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + .max_used = 0 +#endif + }; + struct sys_memory_stats query = { + .free_bytes = 128, + .allocated_bytes = 0, + .max_allocated_bytes = 0 + }; + void *mem1; + void *mem2; + int status; + + /* + * As the ordering of the "raw", "query" and "reset" tests matter, + * they have been grouped together here. As they are for the most + * wrappers for the runtime stats routines, minimal testing is + * being done. + */ + + + /* Initial checks */ + + test_mem_slab_raw("Initial", &raw); + test_mem_slab_query("Initial", &query); + + /* Allocate 1st block */ + + status = k_mem_slab_alloc(&mem_slab, &mem1, K_FOREVER); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + raw.num_used++; + query.free_bytes -= 32; + query.allocated_bytes += 32; +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + raw.max_used++; + query.max_allocated_bytes += 32; +#endif + test_mem_slab_raw("1st Alloc", &raw); + test_mem_slab_query("1st Alloc", &query); + + /* Allocate 2nd block */ + + status = k_mem_slab_alloc(&mem_slab, &mem2, K_FOREVER); + zassert_equal(status, 0, "Expected 0, got %d\n", status); + + raw.num_used++; + query.free_bytes -= 32; + query.allocated_bytes += 32; +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + raw.max_used++; + query.max_allocated_bytes += 32; +#endif + test_mem_slab_raw("2nd Alloc", &raw); + test_mem_slab_query("2nd Alloc", &query); + + /* Free 1st block */ + k_mem_slab_free(&mem_slab, mem1); + + raw.num_used--; + query.free_bytes += 32; + query.allocated_bytes -= 32; + test_mem_slab_raw("Free 1st", &raw); + test_mem_slab_query("Free 1st", &query); + + /* Reset the mem slab stats */ + status = k_obj_core_stats_reset(K_OBJ_CORE(&mem_slab)); + zassert_equal(status, 0, "Expected 0, got %d\n", status); +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + raw.max_used = raw.num_used; + query.max_allocated_bytes = query.allocated_bytes; +#endif + test_mem_slab_raw("Reset", &raw); + test_mem_slab_query("Reset", &query); + + /* Cleanup - Free 2nd block */ + k_mem_slab_free(&mem_slab, mem2); +} + +ZTEST_SUITE(obj_core_stats_system, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); + +ZTEST_SUITE(obj_core_stats_thread, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); + +ZTEST_SUITE(obj_core_stats_mem_block, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); + +ZTEST_SUITE(obj_core_stats_mem_slab, NULL, NULL, + ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); diff --git a/tests/kernel/obj_core/obj_core_stats/testcase.yaml b/tests/kernel/obj_core/obj_core_stats/testcase.yaml new file mode 100644 index 00000000000..e2276a001b8 --- /dev/null +++ b/tests/kernel/obj_core/obj_core_stats/testcase.yaml @@ -0,0 +1,9 @@ +tests: + kernel.obj_core_stats: + tags: kernel + ignore_faults: true + integration_platforms: + - qemu_x86 + platform_exclude: + - qemu_x86_tiny + - qemu_x86_tiny@768 From 1afc32e762ded12d0c26c1b24fcd982ea5371855 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Sun, 11 Jun 2023 16:50:52 -0400 Subject: [PATCH 1482/4498] doc: Add object core documentation Adds documentation for both object cores and object core statistics. Signed-off-by: Peter Mitsis --- doc/kernel/index.rst | 1 + doc/kernel/object_cores/index.rst | 233 ++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 doc/kernel/object_cores/index.rst diff --git a/doc/kernel/index.rst b/doc/kernel/index.rst index b8cf4bd38eb..90f82b5b53c 100644 --- a/doc/kernel/index.rst +++ b/doc/kernel/index.rst @@ -12,6 +12,7 @@ Kernel memory_management/index.rst data_structures/index.rst timing_functions/index.rst + object_cores/index.rst timeutil.rst util/index.rst iterable_sections/index.rst diff --git a/doc/kernel/object_cores/index.rst b/doc/kernel/object_cores/index.rst new file mode 100644 index 00000000000..6ccd41df7ad --- /dev/null +++ b/doc/kernel/object_cores/index.rst @@ -0,0 +1,233 @@ +.. _object_cores_api: + +Object Cores +############ + +Object cores are a kernel debugging tool that can be used to both identify and +perform operations on registered objects. + +.. contents:: + :local: + :depth: 2 + +Object Core Concepts +******************** + +Each instance of an object embeds an object core field named `obj_core`. +Objects of the same type are linked together via their respective object +cores to form a singly linked list. Each object core also links to the their +respective object type. Each object type contains a singly linked list +linking together all the object cores of that type. Object types are also +linked together via a singly linked list. Together, this can allow debugging +tools to traverse all the objects in the system. + +Object cores have been integrated into following kernel objects: + * :ref:`Condition Variables ` + * :ref:`Events ` + * :ref:`FIFOs ` and :ref:`LIFOs ` + * :ref:`Mailboxes ` + * :ref:`Memory Slabs ` + * :ref:`Message Queues ` + * :ref:`Mutexes ` + * :ref:`Pipes ` + * :ref:`Semaphores ` + * :ref:`Timers ` + * :ref:`System Memory Blocks ` + +Developers are free to integrate them if desired into other objects within +their projects. + +Object Core Statistics Concepts +******************************* +A variety of kernel objects allow for the gathering and reporting of statistics. +Object cores provide a uniform means to retrieve that information via object +core statistics. When enabled, the object type contains a pointer to a +statistics descriptor that defines the various operations that have been +enabled for interfacing with the object's statistics. Additionally, the object +core contains a pointer to the "raw" statistical information associated with +that object. Raw data is the raw, unmanipulated data associated with the +statistics. Queried data may be "raw", but it may also have been manipulated in +some way by calculation (such as determining an average). + +The following table indicates both what objects have been integrated into the +object core statistics as well as the structures used for both "raw" and +"queried" data. + +===================== ============================== ============================== +Object Raw Data Type Query Data Type +===================== ============================== ============================== +struct mem_slab struct mem_slab_info struct sys_memory_stats +struct sys_mem_blocks struct sys_mem_blocks_info struct sys_memory_stats +struct k_thread struct k_cycle_stats struct k_thread_runtime_stats +struct _cpu struct k_cycle_stats struct k_thread_runtime_stats +struct z_kernel struct k_cycle_stats[num CPUs] struct k_thread_runtime_stats +===================== ============================== ============================== + +Implementation +************** + +Defining a New Object Type +========================== + +An object type is defined using a global variable of type +:c:struct:`k_obj_type`. It must be initialized before any objects of that type +are initialized. The following code shows how a new object type can be +initialized for use with object cores and object core statistics. + +.. code-block:: c + + /* Unique object type ID */ + + #define K_OBJ_TYPE_MY_NEW_TYPE K_OBJ_TYPE_ID_GEN("UNIQ") + struct k_obj_type my_obj_type; + + struct my_obj_type_raw_info { + ... + }; + + struct my_obj_type_query_stats { + ... + }; + + struct my_new_obj { + ... + struct k_obj_core obj_core; + struct my_obj_type_raw_info info; + }; + + struct k_obj_core_stats_desc my_obj_type_stats_desc = { + .raw_size = sizeof(struct my_obj_type_raw_stats), + .query_size = sizeof(struct my_obj_type_query_stats), + .raw = my_obj_type_stats_raw, + .query = my_obj_type_stats_query, + .reset = my_obj_type_stats_reset, + .disable = NULL, /* Stats gathering is always on */ + .enable = NULL, /* Stats gathering is always on */ + }; + + void my_obj_type_init(void) + { + z_obj_type_init(&my_obj_type, K_OBJ_TYPE_MY_NEW_TYPE, + offsetof(struct my_new_obj, obj_core); + k_obj_type_stats_init(&my_obj_type, &my_obj_type_stats_desc); + } + +Initializing a New Object Core +============================== + +Kernel objects that have already been integrated into the object core framework +automatically have their object cores initialized when the object is +initialized. However, developers that wish to add their own objects into the +framework need to both initialize the object core and link it. The following +code builds on the example above and initializes the object core. + +.. code-block:: c + + void my_new_obj_init(struct my_new_obj *new_obj) + { + ... + k_obj_core_init(K_OBJ_CORE(new_obj), &my_obj_type); + k_obj_core_link(K_OBJ_CORE(new_obj)); + k_obj_core_stats_register(K_OBJ_CORE(new_obj), &new_obj->raw_stats, + sizeof(struct my_obj_type_raw_info)); + } + +Walking a List of Object Cores +============================== + +Two routines exist for walking the list of object cores linked to an object +type. These are :c:func:`k_obj_type_walk_locked` and +:c:func:`k_obj_type_walk_unlocked`. The following code builds upon the example +above and prints the addresses of all the objects of that new object type. + +.. code-block:: c + + int walk_op(struct k_obj_core *obj_core, void *data) + { + uint8_t *ptr; + + ptr = obj_core; + ptr -= obj_core->type->obj_core_offset; + + printk("%p\n", ptr); + + return 0; + } + + void print_object_addresses(void) + { + struct k_obj_type *obj_type; + + /* Find the object type */ + + obj_type = k_obj_type_find(K_OBJ_TYPE_MY_NEW_TYPE); + + /* Walk the list of objects */ + + k_obj_type_walk_unlocked(obj_type, walk_op, NULL); + } + +Object Core Statistics Querying +=============================== + +The following code builds on the examples above and shows how an object +integrated into the object core statistics framework can both retrieve queried +data and reset the stats associated with the object. + +.. code-block:: c + + struct my_new_obj my_obj; + + ... + + void my_func(void) + { + struct my_obj_type_query_stats my_stats; + int status; + + my_obj_type_init(&my_obj); + + ... + + status = k_obj_core_stats_query(K_OBJ_CORE(&my_obj), + &my_stats, sizeof(my_stats)); + if (status != 0) { + /* Failed to get stats */ + ... + } else { + k_obj_core_stats_reset(K_OBJ_CORE(&my_obj)); + } + + ... + } + +Configuration Options +********************* + +Related configuration options: + +* :kconfig:option:`CONFIG_OBJ_CORE` +* :kconfig:option:`CONFIG_OBJ_CORE_CONDVAR` +* :kconfig:option:`CONFIG_OBJ_CORE_EVENT` +* :kconfig:option:`CONFIG_OBJ_CORE_FIFO` +* :kconfig:option:`CONFIG_OBJ_CORE_LIFO` +* :kconfig:option:`CONFIG_OBJ_CORE_MAILBOX` +* :kconfig:option:`CONFIG_OBJ_CORE_MEM_SLAB` +* :kconfig:option:`CONFIG_OBJ_CORE_MSGQ` +* :kconfig:option:`CONFIG_OBJ_CORE_MUTEX` +* :kconfig:option:`CONFIG_OBJ_CORE_PIPE` +* :kconfig:option:`CONFIG_OBJ_CORE_SEM` +* :kconfig:option:`CONFIG_OBJ_CORE_STACK` +* :kconfig:option:`CONFIG_OBJ_CORE_TIMER` +* :kconfig:option:`CONFIG_OBJ_CORE_SYS_MEM_BLOCKS` +* :kconfig:option:`CONFIG_OBJ_CORE_STATS` +* :kconfig:option:`CONFIG_OBJ_CORE_STATS_MEM_SLAB` +* :kconfig:option:`CONFIG_OBJ_CORE_STATS_THREAD` +* :kconfig:option:`CONFIG_OBJ_CORE_STATS_SYSTEM` +* :kconfig:option:`CONFIG_OBJ_CORE_STATS_SYS_MEM_BLOCKS` + +API Reference +************* + +.. doxygengroup:: obj_core_apis +.. doxygengroup:: obj_core_stats_apis From 13712dbea2d53ce02be79bcfba54a4d477b26f84 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 14 Aug 2023 15:36:57 -0400 Subject: [PATCH 1483/4498] test: Shorten object core API stats test name Changing the name of the routine test_obj_core_stats_deregister() to something shorter (test_obj_core_stats_dereg) has been found to be a workaround to the issue identified in #61087. Signed-off-by: Peter Mitsis --- tests/kernel/obj_core/obj_core_stats_api/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kernel/obj_core/obj_core_stats_api/src/main.c b/tests/kernel/obj_core/obj_core_stats_api/src/main.c index c6638e28a31..253ebdd7302 100644 --- a/tests/kernel/obj_core/obj_core_stats_api/src/main.c +++ b/tests/kernel/obj_core/obj_core_stats_api/src/main.c @@ -216,7 +216,7 @@ ZTEST(obj_core_stats_api, test_obj_core_stats_raw) k_mutex_unlock(&test_mutex); } -ZTEST(obj_core_stats_api, test_obj_core_stats_deregister) +ZTEST(obj_core_stats_api, test_obj_core_stats_dereg) { int status; char buffer[sizeof(struct k_cycle_stats)]; From a956f7aef10b0028453efe1f428cb9c52445fbb7 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 29 Sep 2023 11:34:39 -0400 Subject: [PATCH 1484/4498] west.yml: Pull in latest percepio updates Pulls in the latest percepio module updates that alter how it accesses the k_mem_slab structure (due to changes from this PR). Signed-off-by: Peter Mitsis --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3d74ecd4a0e..fe1460492d2 100644 --- a/west.yml +++ b/west.yml @@ -313,7 +313,7 @@ manifest: path: modules/lib/openthread - name: percepio path: modules/debug/percepio - revision: 7ba53eb1c22d14a49fa51f4b57fc0614a893fdd7 + revision: 722448367cf6c4b877eb7999c90ee52226379acc groups: - debug - name: picolibc From f0c7fbf0f1d3f057ff1494db6471c7f866d413ee Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 08:34:26 -0400 Subject: [PATCH 1485/4498] kernel: move sched_priq.h to internal/ folder This header is internal to the kernel and shall not be included directly. Signed-off-by: Anas Nashif --- include/zephyr/kernel/{ => internal}/sched_priq.h | 0 include/zephyr/kernel_includes.h | 2 +- include/zephyr/kernel_structs.h | 2 +- kernel/include/wait_q.h | 2 +- kernel/sched.c | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename include/zephyr/kernel/{ => internal}/sched_priq.h (100%) diff --git a/include/zephyr/kernel/sched_priq.h b/include/zephyr/kernel/internal/sched_priq.h similarity index 100% rename from include/zephyr/kernel/sched_priq.h rename to include/zephyr/kernel/internal/sched_priq.h diff --git a/include/zephyr/kernel_includes.h b/include/zephyr/kernel_includes.h index 31ea5fce751..df10bbd8446 100644 --- a/include/zephyr/kernel_includes.h +++ b/include/zephyr/kernel_includes.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 6d0c8cc4967..d066db620ce 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -23,7 +23,7 @@ #if !defined(_ASMLANGUAGE) #include #include -#include +#include #include #include #include diff --git a/kernel/include/wait_q.h b/kernel/include/wait_q.h index 2c8eeefbf25..0c44a89eb66 100644 --- a/kernel/include/wait_q.h +++ b/kernel/include/wait_q.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #ifdef __cplusplus diff --git a/kernel/sched.c b/kernel/sched.c index db6742e841e..66b10c3b04f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include From e19f21cb27ea18ffaa4c4d80c44256068c412ff9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 10:28:13 -0400 Subject: [PATCH 1486/4498] kernel: move z_is_thread_essential out of public kernel header This is a private API to the kernel, so move out of kernel.h Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 2 -- kernel/include/ksched.h | 2 ++ tests/kernel/mem_protect/userspace/src/main.c | 2 +- tests/kernel/threads/thread_apis/src/test_essential_thread.c | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 908bae10134..4fcb14353bd 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5950,8 +5950,6 @@ extern void z_init_static_threads(void); /** * @internal */ -extern bool z_is_thread_essential(void); - #ifdef CONFIG_SMP void z_smp_thread_init(void *arg, struct k_thread *thread); void z_smp_thread_swap(void); diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index 9d0ef300376..a6898a8bdf4 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -13,6 +13,8 @@ #include #include +bool z_is_thread_essential(void); + BUILD_ASSERT(K_LOWEST_APPLICATION_THREAD_PRIO >= K_HIGHEST_APPLICATION_THREAD_PRIO); diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 6e996e9e605..8d5cf9ec4bc 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -327,7 +327,7 @@ ZTEST_USER(userspace, test_write_kerntext) /* Try to write to kernel text. */ set_fault(K_ERR_CPU_EXCEPTION); - memset(&z_is_thread_essential, 0, 4); + memset(&k_current_get, 0, 4); zassert_unreachable("Write to kernel text did not fault"); } diff --git a/tests/kernel/threads/thread_apis/src/test_essential_thread.c b/tests/kernel/threads/thread_apis/src/test_essential_thread.c index 7f62296f396..9dae2829549 100644 --- a/tests/kernel/threads/thread_apis/src/test_essential_thread.c +++ b/tests/kernel/threads/thread_apis/src/test_essential_thread.c @@ -6,7 +6,10 @@ #include #include #include + +/* Internal APIs */ #include +#include struct k_thread kthread_thread; struct k_thread kthread_thread1; From 209ff606bef127cbc0891a47d68d2045b85664bf Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 11:34:06 -0400 Subject: [PATCH 1487/4498] kernel: move internal smp calls to a internal header Those APIs are internal and should not be part of the main public API header. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 8 -------- include/zephyr/kernel/internal/smp.h | 19 +++++++++++++++++++ include/zephyr/kernel_includes.h | 2 ++ 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 include/zephyr/kernel/internal/smp.h diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 4fcb14353bd..f20219cf0f0 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5947,14 +5947,6 @@ extern void z_init_static_threads(void); #define z_init_static_threads() do { } while (false) #endif -/** - * @internal - */ -#ifdef CONFIG_SMP -void z_smp_thread_init(void *arg, struct k_thread *thread); -void z_smp_thread_swap(void); -#endif - /** * @internal */ diff --git a/include/zephyr/kernel/internal/smp.h b/include/zephyr/kernel/internal/smp.h new file mode 100644 index 00000000000..06336bb7104 --- /dev/null +++ b/include/zephyr/kernel/internal/smp.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_KERNEL_INTERNAL_SMP_H_ +#define ZEPHYR_INCLUDE_KERNEL_INTERNAL_SMP_H_ + +struct k_thread; + +/** + * @internal + */ +#ifdef CONFIG_SOF +void z_smp_thread_init(void *arg, struct k_thread *thread); +void z_smp_thread_swap(void); +#endif + +#endif diff --git a/include/zephyr/kernel_includes.h b/include/zephyr/kernel_includes.h index df10bbd8446..31c6da3d617 100644 --- a/include/zephyr/kernel_includes.h +++ b/include/zephyr/kernel_includes.h @@ -45,5 +45,7 @@ #include #include #include +/* FIXME This needs to be removed. Exposes some private APIs to SOF */ +#include #endif /* ZEPHYR_INCLUDE_KERNEL_INCLUDES_H_ */ From a1c7bfbc63e1b3a07277e85e7503b118fa8f712c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 18 Sep 2023 12:52:08 -0400 Subject: [PATCH 1488/4498] kernel: remove unused z_init_thread_base from kernel.h This API is internal and not used in any way in kernel.h, so move it back to where it is needed. Signed-off-by: Anas Nashif --- include/zephyr/kernel.h | 4 ---- kernel/include/kernel_internal.h | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index f20219cf0f0..be1e7d65b7e 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5931,10 +5931,6 @@ static inline void k_cpu_atomic_idle(unsigned int key) /** * @internal */ -extern void z_init_thread_base(struct _thread_base *thread_base, - int priority, uint32_t initial_state, - unsigned int options); - #ifdef CONFIG_MULTITHREADING /** * @internal diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index cd5b1220aae..3c379559f72 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -24,8 +24,11 @@ extern "C" { #endif -/* Early boot functions */ +/* Initialize a thread */ +void z_init_thread_base(struct _thread_base *thread_base, int priority, + uint32_t initial_state, unsigned int options); +/* Early boot functions */ void z_early_memset(void *dst, int c, size_t n); void z_early_memcpy(void *dst, const void *src, size_t n); From cc2a558707758992f0b3f11cbcceb8c507262172 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 19 Sep 2023 10:59:34 +0000 Subject: [PATCH 1489/4498] kernel: move more internal smp calls into internal domain Move 3 more internal APIs into internal area as the first step for cleanup. Having them in kernel.h is just an invitation for them to be used by someone. Signed-off-by: Anas Nashif --- include/zephyr/kernel/internal/smp.h | 4 ++++ include/zephyr/kernel/thread.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/kernel/internal/smp.h b/include/zephyr/kernel/internal/smp.h index 06336bb7104..d4f70d3c07b 100644 --- a/include/zephyr/kernel/internal/smp.h +++ b/include/zephyr/kernel/internal/smp.h @@ -16,4 +16,8 @@ void z_smp_thread_init(void *arg, struct k_thread *thread); void z_smp_thread_swap(void); #endif +void z_init_cpu(int id); +void z_sched_ipi(void); +void z_smp_start_cpu(int id); + #endif diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index e6bdd423bec..7a231196cb4 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -358,8 +358,4 @@ struct k_thread { typedef struct k_thread _thread_t; typedef struct k_thread *k_tid_t; -void z_init_cpu(int id); -void z_sched_ipi(void); -void z_smp_start_cpu(int id); - #endif From b9f8b91692121ae86308ddacfdb5e15c03f4ee73 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 28 Sep 2023 01:43:48 +0000 Subject: [PATCH 1490/4498] kernel: sys_clock: remove stray z_enable_sys_clock prototype The implementation was removed, but we still have the prototype. Signed-off-by: Anas Nashif --- include/zephyr/sys_clock.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/zephyr/sys_clock.h b/include/zephyr/sys_clock.h index 039c6b49744..8211b68203e 100644 --- a/include/zephyr/sys_clock.h +++ b/include/zephyr/sys_clock.h @@ -113,10 +113,6 @@ typedef struct { /** @} */ -#ifdef CONFIG_TICKLESS_KERNEL -extern void z_enable_sys_clock(void); -#endif - #if defined(CONFIG_SYS_CLOCK_EXISTS) && \ (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0) #error "SYS_CLOCK_HW_CYCLES_PER_SEC must be non-zero!" From c910dc81a614dead8d0b45a8a06da0ccf7bdec9d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 28 Sep 2023 15:31:47 +0000 Subject: [PATCH 1491/4498] sys_clock: header: minor cleanup and doxygenization Minor cleanup and doxygen related changes adding missing coverage. Signed-off-by: Anas Nashif --- include/zephyr/sys_clock.h | 72 +++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/include/zephyr/sys_clock.h b/include/zephyr/sys_clock.h index 8211b68203e..e43b539fb8f 100644 --- a/include/zephyr/sys_clock.h +++ b/include/zephyr/sys_clock.h @@ -79,6 +79,36 @@ typedef struct { */ #define K_TIMEOUT_EQ(a, b) ((a).ticks == (b).ticks) +/** number of nanoseconds per micorsecond */ +#define NSEC_PER_USEC 1000U + +/** number of nanoseconds per millisecond */ +#define NSEC_PER_MSEC 1000000U + +/** number of microseconds per millisecond */ +#define USEC_PER_MSEC 1000U + +/** number of milliseconds per second */ +#define MSEC_PER_SEC 1000U + +/** number of seconds per minute */ +#define SEC_PER_MIN 60U + +/** number of minutes per hour */ +#define MIN_PER_HOUR 60U + +/** number of hours per day */ +#define HOUR_PER_DAY 24U + +/** number of microseconds per second */ +#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC)) + +/** number of nanoseconds per second */ +#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC)) + +/** @} */ + +/** @cond INTERNAL_HIDDEN */ #define Z_TIMEOUT_NO_WAIT ((k_timeout_t) {0}) #if defined(__cplusplus) && ((__cplusplus - 0) < 202002L) #define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { (t) }) @@ -111,40 +141,16 @@ typedef struct { */ #define Z_TICK_ABS(t) (K_TICKS_FOREVER - 1 - (t)) -/** @} */ +/* added tick needed to account for tick in progress */ +#define _TICK_ALIGN 1 + +/** @endcond */ #if defined(CONFIG_SYS_CLOCK_EXISTS) && \ (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0) #error "SYS_CLOCK_HW_CYCLES_PER_SEC must be non-zero!" #endif -/* number of nsec per usec */ -#define NSEC_PER_USEC 1000U - -/* number of nsec per msec */ -#define NSEC_PER_MSEC 1000000U - -/* number of microseconds per millisecond */ -#define USEC_PER_MSEC 1000U - -/* number of milliseconds per second */ -#define MSEC_PER_SEC 1000U - -/* number of seconds per minute */ -#define SEC_PER_MIN 60U - -/* number of minutes per hour */ -#define MIN_PER_HOUR 60U - -/* number of hours per day */ -#define HOUR_PER_DAY 24U - -/* number of microseconds per second */ -#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC)) - -/* number of nanoseconds per second */ -#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC)) - /* kernel clocks */ @@ -153,6 +159,10 @@ typedef struct { * but if the HW timer cycles/sec, ticks/sec and ms/sec are all known * to be nicely related, then we can cheat with 32 bits instead. */ +/** + * @addtogroup clock_apis + * @{ + */ #ifdef CONFIG_SYS_CLOCK_EXISTS @@ -164,10 +174,7 @@ typedef struct { #endif -/* added tick needed to account for tick in progress */ -#define _TICK_ALIGN 1 - -/* +/** * SYS_CLOCK_HW_CYCLES_TO_NS_AVG converts CPU clock cycles to nanoseconds * and calculates the average cycle time */ @@ -322,6 +329,7 @@ static inline bool sys_timepoint_expired(k_timepoint_t timepoint) return K_TIMEOUT_EQ(sys_timepoint_timeout(timepoint), Z_TIMEOUT_NO_WAIT); } +/** @} */ #ifdef __cplusplus } From 9d1b7086d70d6ce6775a1393d53118819df17628 Mon Sep 17 00:00:00 2001 From: Daniel Fladerer Date: Fri, 29 Sep 2023 15:48:01 +0200 Subject: [PATCH 1492/4498] drivers: serial: uart_mcux_iuart: Add parity bit handling Adding parity bit handling according to uart_mcux.c Signed-off-by: Daniel Fladerer --- drivers/serial/uart_mcux_iuart.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/serial/uart_mcux_iuart.c b/drivers/serial/uart_mcux_iuart.c index 09ae22c906e..9a1f73f2a21 100644 --- a/drivers/serial/uart_mcux_iuart.c +++ b/drivers/serial/uart_mcux_iuart.c @@ -19,6 +19,8 @@ struct mcux_iuart_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; uint32_t baud_rate; + /* initial parity, 0 for none, 1 for odd, 2 for even */ + uint8_t parity; const struct pinctrl_dev_config *pincfg; #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(const struct device *dev); @@ -242,6 +244,20 @@ static int mcux_iuart_init(const struct device *dev) uart_config.baudRate_Bps = config->baud_rate; clock_control_on(config->clock_dev, config->clock_subsys); + switch (config->parity) { + case UART_CFG_PARITY_NONE: + uart_config.parityMode = kUART_ParityDisabled; + break; + case UART_CFG_PARITY_EVEN: + uart_config.parityMode = kUART_ParityEven; + break; + case UART_CFG_PARITY_ODD: + uart_config.parityMode = kUART_ParityOdd; + break; + default: + return -ENOTSUP; + } + UART_Init(config->base, &uart_config, clock_freq); err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); @@ -313,6 +329,7 @@ static const struct mcux_iuart_config mcux_iuart_##n##_config = { \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ .baud_rate = DT_INST_PROP(n, current_speed), \ + .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ IRQ_FUNC_INIT \ } From d6a96a4b24f55d4b3c4400a6b389e1b129913578 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 29 Sep 2023 12:26:48 +0200 Subject: [PATCH 1493/4498] net: l2: ppp: Don't attempt reestablish PPP if carrier is down This commit adds a check to prevent attempting to reestablish the PPP session if the carrier is down. Without this check, the PPP FSM attempts and fails to establish a PPP session twice before giving up. The behavior is not breaking anything, but it is not desired. Signed-off-by: Bjarki Arge Andreasen --- subsys/net/l2/ppp/lcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/l2/ppp/lcp.c b/subsys/net/l2/ppp/lcp.c index 0d46b5b66fa..9e54f631f48 100644 --- a/subsys/net/l2/ppp/lcp.c +++ b/subsys/net/l2/ppp/lcp.c @@ -179,6 +179,10 @@ static void lcp_down(struct ppp_fsm *fsm) ppp_link_down(ctx); + if (!net_if_is_carrier_ok(ctx->iface)) { + return; + } + ppp_change_phase(ctx, PPP_ESTABLISH); } From 74b2c8c123173721939151c36ee3eb4429a4fd54 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 29 Sep 2023 17:03:53 +0200 Subject: [PATCH 1494/4498] net: ppp: Remove unused flag from struct ppp_context Remove unused flag from ppp_context struct. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/net/ppp.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/zephyr/net/ppp.h b/include/zephyr/net/ppp.h index 4067d37f4cc..a72d4f1feac 100644 --- a/include/zephyr/net/ppp.h +++ b/include/zephyr/net/ppp.h @@ -483,9 +483,6 @@ struct ppp_context { /** This tells how many network protocols are up */ int network_protos_up; - /** Is network carrier up */ - uint16_t is_net_carrier_up : 1; - /** Is PPP ready to receive packets */ uint16_t is_ready_to_serve : 1; From 9ad403e9cae5b9dc6e37365a9096dfe4877ab0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 29 Sep 2023 13:04:09 +0200 Subject: [PATCH 1495/4498] doc: pm: policy: Hide internal/private fields. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use INTERNAL_HIDDEN to hide private fields from public documentation. Signed-off-by: Benjamin Cabé --- include/zephyr/pm/policy.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/zephyr/pm/policy.h b/include/zephyr/pm/policy.h index b2e648b5ba6..e77004bbbe8 100644 --- a/include/zephyr/pm/policy.h +++ b/include/zephyr/pm/policy.h @@ -40,8 +40,10 @@ typedef void (*pm_policy_latency_changed_cb_t)(int32_t latency); * @note All fields in this structure are meant for private usage. */ struct pm_policy_latency_subscription { + /** @cond INTERNAL_HIDDEN */ sys_snode_t node; pm_policy_latency_changed_cb_t cb; + /** @endcond */ }; /** @@ -50,8 +52,10 @@ struct pm_policy_latency_subscription { * @note All fields in this structure are meant for private usage. */ struct pm_policy_latency_request { + /** @cond INTERNAL_HIDDEN */ sys_snode_t node; uint32_t value_us; + /** @endcond */ }; /** @@ -60,8 +64,10 @@ struct pm_policy_latency_request { * @note All fields in this structure are meant for private usage. */ struct pm_policy_event { + /** @cond INTERNAL_HIDDEN */ sys_snode_t node; uint32_t value_cyc; + /** @endcond */ }; /** @cond INTERNAL_HIDDEN */ From 48a069204cf0a749b4cd5ecd5e3da6df0c84f462 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 29 Sep 2023 11:35:39 +0200 Subject: [PATCH 1496/4498] modem: modem_pipe: Avoid inconsequential open/close calls This PR adds a mechanism to avoid calling open() or close() on pipes which are already opened or closed respectively. This optimization can help simplify backends implementing the modem_pipe API by avoiding duplicated boilerplate code. The TTY backend test suite has been updated to match the new behavior. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_pipe.c | 29 +++++++++++++++++++++- tests/subsys/modem/backends/tty/src/main.c | 8 +++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/subsys/modem/modem_pipe.c b/subsys/modem/modem_pipe.c index 5240c5ebc27..01bdac50d3a 100644 --- a/subsys/modem/modem_pipe.c +++ b/subsys/modem/modem_pipe.c @@ -31,8 +31,12 @@ int modem_pipe_open(struct modem_pipe *pipe) int ret; k_mutex_lock(&pipe->lock, K_FOREVER); - ret = pipe->api->open(pipe->data); + if (pipe->state == MODEM_PIPE_STATE_OPEN) { + k_mutex_unlock(&pipe->lock); + return 0; + } + ret = pipe->api->open(pipe->data); if (ret < 0) { k_mutex_unlock(&pipe->lock); return ret; @@ -54,6 +58,15 @@ int modem_pipe_open_async(struct modem_pipe *pipe) int ret; k_mutex_lock(&pipe->lock, K_FOREVER); + if (pipe->state == MODEM_PIPE_STATE_OPEN) { + if (pipe->callback != NULL) { + pipe->callback(pipe, MODEM_PIPE_EVENT_OPENED, pipe->user_data); + } + + k_mutex_unlock(&pipe->lock); + return 0; + } + ret = pipe->api->open(pipe->data); k_mutex_unlock(&pipe->lock); return ret; @@ -118,6 +131,11 @@ int modem_pipe_close(struct modem_pipe *pipe) int ret; k_mutex_lock(&pipe->lock, K_FOREVER); + if (pipe->state == MODEM_PIPE_STATE_CLOSED) { + k_mutex_unlock(&pipe->lock); + return 0; + } + ret = pipe->api->close(pipe->data); if (ret < 0) { k_mutex_unlock(&pipe->lock); @@ -140,6 +158,15 @@ int modem_pipe_close_async(struct modem_pipe *pipe) int ret; k_mutex_lock(&pipe->lock, K_FOREVER); + if (pipe->state == MODEM_PIPE_STATE_CLOSED) { + if (pipe->callback != NULL) { + pipe->callback(pipe, MODEM_PIPE_EVENT_CLOSED, pipe->user_data); + } + + k_mutex_unlock(&pipe->lock); + return 0; + } + ret = pipe->api->close(pipe->data); k_mutex_unlock(&pipe->lock); return ret; diff --git a/tests/subsys/modem/backends/tty/src/main.c b/tests/subsys/modem/backends/tty/src/main.c index bd9f7494eed..49a1841486a 100644 --- a/tests/subsys/modem/backends/tty/src/main.c +++ b/tests/subsys/modem/backends/tty/src/main.c @@ -122,10 +122,10 @@ static void test_modem_backend_tty_teardown(void *f) /*************************************************************************************************/ ZTEST(modem_backend_tty_suite, test_close_open) { - zassert_true(modem_pipe_close(tty_pipe) == 0, "Failed to close pipe"); - zassert_true(modem_pipe_close(tty_pipe) == -EALREADY, "Pipe should already be closed"); - zassert_true(modem_pipe_open(tty_pipe) == 0, "Failed to open pipe"); - zassert_true(modem_pipe_open(tty_pipe) == -EALREADY, "Pipe should already be open"); + zassert_ok(modem_pipe_close(tty_pipe), "Failed to close pipe"); + zassert_ok(modem_pipe_close(tty_pipe), "Pipe should already be closed"); + zassert_ok(modem_pipe_open(tty_pipe), "Failed to open pipe"); + zassert_ok(modem_pipe_open(tty_pipe), "Pipe should already be open"); } ZTEST(modem_backend_tty_suite, test_receive_ready_event_not_raised) From da9c821ce0862cfb0f9a0b3e7edd2ec30fc176c2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 29 Sep 2023 11:47:52 +0200 Subject: [PATCH 1497/4498] modem: modem_pipe: Update documentation This commit improves the documentation in the header for the modem_pipe to include return value descriptions and notes regarding when specific events are invoked resulting from calls to the modem_pipe API. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/pipe.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/zephyr/modem/pipe.h b/include/zephyr/modem/pipe.h index 945cace6bb8..124af5d4269 100644 --- a/include/zephyr/modem/pipe.h +++ b/include/zephyr/modem/pipe.h @@ -69,6 +69,9 @@ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api * @brief Open pipe * * @param pipe Pipe instance + * + * @retval 0 if pipe was successfully opened or was already open + * @retval -errno code otherwise */ int modem_pipe_open(struct modem_pipe *pipe); @@ -76,6 +79,12 @@ int modem_pipe_open(struct modem_pipe *pipe); * @brief Open pipe asynchronously * * @param pipe Pipe instance + * + * @note The MODEM_PIPE_EVENT_OPENED event is invoked immediately if pipe is + * already opened. + * + * @retval 0 if pipe open was called successfully or pipe was already open + * @retval -errno code otherwise */ int modem_pipe_open_async(struct modem_pipe *pipe); @@ -85,6 +94,9 @@ int modem_pipe_open_async(struct modem_pipe *pipe); * @param pipe Pipe instance * @param callback Callback called when pipe event occurs * @param user_data Free to use user data passed with callback + * + * @note The MODEM_PIPE_EVENT_RECEIVE_READY event is invoked immediately if pipe has pending + * data ready to receive. */ void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback, void *user_data); @@ -127,6 +139,9 @@ void modem_pipe_release(struct modem_pipe *pipe); * @brief Close pipe * * @param pipe Pipe instance + * + * @retval 0 if pipe open was called closed or pipe was already closed + * @retval -errno code otherwise */ int modem_pipe_close(struct modem_pipe *pipe); @@ -134,6 +149,12 @@ int modem_pipe_close(struct modem_pipe *pipe); * @brief Close pipe asynchronously * * @param pipe Pipe instance + * + * @note The MODEM_PIPE_EVENT_CLOSED event is invoked immediately if pipe is + * already closed. + * + * @retval 0 if pipe close was called successfully or pipe was already closed + * @retval -errno code otherwise */ int modem_pipe_close_async(struct modem_pipe *pipe); From 56627e40cb465dabfbe5c80bae257062ecb79e20 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 28 Sep 2023 09:20:00 -0700 Subject: [PATCH 1498/4498] net: wifi_utils: Fix wifi_utils_parse_scan_ssids doc Function recently changed its behavior, just changing the documentation to reflect that. Signed-off-by: Flavio Ceolin --- include/zephyr/net/wifi_utils.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index c9ef9979f91..c16eef0e5b2 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -57,12 +57,9 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); /** - * @brief Convert a string containing a list of SSIDs to an array of SSID strings. + * @brief Append a string containing an SSID to an array of SSID strings. * - * @details The function will parse a string which specifies Wi-Fi SSIDs - * as a comma separated string and convert it to an array. - * - * @param scan_ssids_str List of SSIDs expressed as a comma separated list. + * @param scan_ssids_str string to be appended in the list of scanned SSIDs. * @param ssids Pointer to an array where the SSIDs pointers are to be stored. * @param num_ssids Maximum number of SSIDs that can be stored. * From 27b4b9f4c8f2ee61dff937cc146939aae171c9cf Mon Sep 17 00:00:00 2001 From: Chandler Keep Date: Thu, 28 Sep 2023 10:00:55 +0100 Subject: [PATCH 1499/4498] mgmt/MCUmgr/mgmt: Support for finding registered command groups This commit adds support for finding registered mcumgr command groups. By default, supported command groups are local to the namespace where they're registered. This api addition allows applications to get reference to these supported command groups to deregister & re-register them. This adds scope for applications to support multiple implementations of a command group alongside the default. Signed-off-by: Chandler Keep --- include/zephyr/mgmt/mcumgr/mgmt/mgmt.h | 10 ++++++++++ subsys/mgmt/mcumgr/mgmt/src/mgmt.c | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h index ec09bb03467..ed84b037633 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h @@ -123,6 +123,16 @@ void mgmt_unregister_group(struct mgmt_group *group); */ const struct mgmt_handler *mgmt_find_handler(uint16_t group_id, uint16_t command_id); +/** + * @brief Finds a registered command group. + * + * @param group_id The command group id to find. + * + * @return The requested command group on success; + * NULL on failure. + */ +const struct mgmt_group *mgmt_find_group(uint16_t group_id); + #if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) /** * @brief Finds a registered error translation function for converting from SMP diff --git a/subsys/mgmt/mcumgr/mgmt/src/mgmt.c b/subsys/mgmt/mcumgr/mgmt/src/mgmt.c index 4121a6f9262..56dcbb0254d 100644 --- a/subsys/mgmt/mcumgr/mgmt/src/mgmt.c +++ b/subsys/mgmt/mcumgr/mgmt/src/mgmt.c @@ -69,6 +69,29 @@ mgmt_find_handler(uint16_t group_id, uint16_t command_id) return &group->mg_handlers[command_id]; } +const struct mgmt_group * +mgmt_find_group(uint16_t group_id) +{ + struct mgmt_group *group = NULL; + sys_snode_t *snp, *sns; + + /* + * Find the group with the specified group id + * from the registered group list, if one exists + * return the matching mgmt group pointer, otherwise return NULL + */ + SYS_SLIST_FOR_EACH_NODE_SAFE(&mgmt_group_list, snp, sns) { + struct mgmt_group *loop_group = + CONTAINER_OF(snp, struct mgmt_group, node); + if (loop_group->mg_group_id == group_id) { + group = loop_group; + break; + } + } + + return group; +} + #if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL) smp_translate_error_fn mgmt_find_error_translation_function(uint16_t group_id) { From 31eaffdf0552ee967b371644869223d9e901de00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 23 Jun 2023 09:06:51 +0200 Subject: [PATCH 1500/4498] nrf53: Add RTC pretick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add RTC pretick option that triggers HW activity one tick before and RTC event that leads to the interrupt. Option is active only on nrf53 network core. Signed-off-by: Krzysztof Chruściński --- drivers/timer/nrf_rtc_timer.c | 17 ++- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 21 ++++ soc/arm/nordic_nrf/nrf53/soc.c | 164 +++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 1 deletion(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index 4410529608b..e8ba5bd42a5 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -25,6 +25,11 @@ #define RTC_LABEL rtc1 #define RTC_CH_COUNT RTC1_CC_NUM +#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ + IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) + +BUILD_ASSERT(!RTC_PRETICK || !(RTC_PRETICK && (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT > 0)), + "Cannot use user channels when RTC pretick is used"); BUILD_ASSERT(CHAN_COUNT <= RTC_CH_COUNT, "Not enough compare channels"); /* Ensure that counter driver for RTC1 is not enabled. */ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), @@ -44,6 +49,9 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), #define ANCHOR_RANGE_END (7 * COUNTER_SPAN / 8) #define TARGET_TIME_INVALID (UINT64_MAX) +extern void rtc_pretick_rtc1_cc0_set_hook(uint32_t val); +extern void rtc_pretick_rtc1_isr_hook(void); + static volatile uint32_t overflow_cnt; static volatile uint64_t anchor; static uint64_t last_count; @@ -260,7 +268,7 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) * This never happens when the written value is N+3. Use 3 cycles as * the nearest possible scheduling then. */ - enum { MIN_CYCLES_FROM_NOW = 3 }; + enum { MIN_CYCLES_FROM_NOW = RTC_PRETICK ? 4 : 3 }; uint32_t cc_val = req_cc; uint32_t cc_inc = MIN_CYCLES_FROM_NOW; @@ -277,6 +285,9 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) for (;;) { uint32_t now; + if (RTC_PRETICK) { + rtc_pretick_rtc1_cc0_set_hook(cc_val); + } set_comparator(chan, cc_val); /* Enable event routing after the required CC value was set. * Even though the above operation may get repeated (see below), @@ -559,6 +570,10 @@ void rtc_nrf_isr(const void *arg) { ARG_UNUSED(arg); + if (RTC_PRETICK) { + rtc_pretick_rtc1_isr_hook(); + } + if (nrf_rtc_int_enable_check(RTC, NRF_RTC_INT_OVERFLOW_MASK) && nrf_rtc_event_check(RTC, NRF_RTC_EVENT_OVERFLOW)) { nrf_rtc_event_clear(RTC, NRF_RTC_EVENT_OVERFLOW); diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 632b754bdc1..15dcf41f46e 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -11,12 +11,14 @@ config SOC_NRF5340_CPUAPP select ARMV8_M_DSP select HAS_POWEROFF select SOC_COMPATIBLE_NRF5340_CPUAPP + imply SOC_NRF53_RTC_PRETICK config SOC_NRF5340_CPUNET bool select ARM_ON_EXIT_CPU_IDLE select SOC_COMPATIBLE_NRF5340_CPUNET imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED + imply SOC_NRF53_RTC_PRETICK choice prompt "nRF53x MCU Selection" @@ -49,6 +51,25 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND depends on SYS_CLOCK_EXISTS select ARM_ON_ENTER_CPU_IDLE_HOOK +config SOC_NRF53_RTC_PRETICK + bool + depends on !NRF_802154_RADIO_DRIVER + select NRFX_DPPI + +if SOC_NRF53_RTC_PRETICK + +config SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET + int "IPC 0 channel for RTC pretick" + range 0 15 + default 10 + +config SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET + int "IPC 1 channel for RTC pretick" + range 0 15 + default 11 + +endif + if SOC_NRF5340_CPUAPP config SOC_DCDC_NRF53X_APP diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 6552f9d4bb1..50f00932be9 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #if defined(CONFIG_SOC_NRF5340_CPUAPP) #include #include @@ -31,6 +33,8 @@ #if defined(CONFIG_PM_S2RAM) #include #endif +#include +#include #include #include @@ -38,6 +42,9 @@ #define PIN_XL1 0 #define PIN_XL2 1 +#define RTC1_PRETICK_CC_CHAN 1 +#define RTC1_PRETICK_OVERFLOW_CHAN 2 + #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) #define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ NRF_DT_GPIOS_TO_PSEL_BY_IDX(node_id, prop, idx), @@ -137,11 +144,164 @@ bool z_arm_on_enter_cpu_idle(void) suppress_message = true; } #endif +#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) + if (ok_to_sleep) { + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] |= + IPC_PUBLISH_RECEIVE_EN_Msk; + if (!nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) && + !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) && + !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { + NRF_WDT->TASKS_STOP = 1; + /* Check if any event did not occur after we checked for + * stopping condition. If yes, we might have stopped WDT + * when it should be running. Restart it. + */ + if (nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) || + nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) || + nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { + NRF_WDT->TASKS_START = 1; + } + } + } +#endif return ok_to_sleep; } #endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ +#if CONFIG_SOC_NRF53_RTC_PRETICK +#ifdef CONFIG_SOC_NRF5340_CPUAPP +/* RTC pretick - application core part. */ +static int rtc_pretick_cpuapp_init(void) +{ + uint8_t ch; + nrfx_err_t err; + nrf_ipc_event_t ipc_event = + nrf_ipc_receive_event_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET); + nrf_ipc_task_t ipc_task = + nrf_ipc_send_task_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET); + uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); + uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); + + err = nrfx_gppi_channel_alloc(&ch); + if (err != NRFX_SUCCESS) { + return -ENOMEM; + } + + nrf_ipc_receive_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET, + BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET)); + nrf_ipc_send_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET, + BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET)); + + nrfx_gppi_task_endpoint_setup(ch, task_ipc); + nrfx_gppi_event_endpoint_setup(ch, evt_ipc); + nrfx_gppi_channels_enable(BIT(ch)); + + return 0; +} +#else /* CONFIG_SOC_NRF5340_CPUNET */ + +static void rtc_pretick_rtc_isr_hook(void) +{ + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= + ~IPC_PUBLISH_RECEIVE_EN_Msk; +} + +void rtc_pretick_rtc0_isr_hook(void) +{ + rtc_pretick_rtc_isr_hook(); +} + +void rtc_pretick_rtc1_cc0_set_hook(uint32_t val) +{ + nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, val - 1); +} + +void rtc_pretick_rtc1_isr_hook(void) +{ + rtc_pretick_rtc_isr_hook(); + + if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW)) { + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); + } + } + if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_COMPARE_0)) { + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + } + } +} + +static int rtc_pretick_cpunet_init(void) +{ + uint8_t ppi_ch; + nrf_ipc_task_t ipc_task = + nrf_ipc_send_task_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET); + nrf_ipc_event_t ipc_event = + nrf_ipc_receive_event_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET); + uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); + uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); + uint32_t task_wdt = nrf_wdt_task_address_get(NRF_WDT, NRF_WDT_TASK_START); + uint32_t evt_mpsl_cc = nrf_rtc_event_address_get(NRF_RTC0, NRF_RTC_EVENT_COMPARE_3); + uint32_t evt_cc = nrf_rtc_event_address_get(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + uint32_t evt_overflow = nrf_rtc_event_address_get(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); + + /* Configure Watchdog to allow stopping. */ + nrf_wdt_behaviour_set(NRF_WDT, WDT_CONFIG_STOPEN_Msk | BIT(4)); + *((volatile uint32_t *)0x41203120) = 0x14; + + /* Configure IPC */ + nrf_ipc_receive_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET, + BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET)); + nrf_ipc_send_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET, + BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET)); + + /* Allocate PPI channel for RTC Compare event publishers that starts WDT. */ + nrfx_err_t err = nrfx_gppi_channel_alloc(&ppi_ch); + + if (err != NRFX_SUCCESS) { + return -ENOMEM; + } + + /* Setup a PPI connection between RTC "pretick" events and IPC task. */ + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE)) { + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_mpsl_cc); + } + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_cc); + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_overflow); + nrfx_gppi_task_endpoint_setup(ppi_ch, task_ipc); + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_ipc); + nrfx_gppi_task_endpoint_setup(ppi_ch, task_wdt); + nrfx_gppi_channels_enable(BIT(ppi_ch)); + + nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_CC_CHAN)); + nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_OVERFLOW_CHAN)); + + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); + /* Set event 1 tick before overflow. */ + nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_OVERFLOW_CHAN, 0x00FFFFFF); + + return 0; +} +#endif /* CONFIG_SOC_NRF5340_CPUNET */ + +static int rtc_pretick_init(void) +{ + ARG_UNUSED(unused); +#ifdef CONFIG_SOC_NRF5340_CPUAPP + return rtc_pretick_cpuapp_init(); +#else + return rtc_pretick_cpunet_init(); +#endif +} +#endif /* CONFIG_SOC_NRF53_RTC_PRETICK */ + + static int nordicsemi_nrf53_init(void) { #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF_ENABLE_CACHE) @@ -242,3 +402,7 @@ void arch_busy_wait(uint32_t time_us) } SYS_INIT(nordicsemi_nrf53_init, PRE_KERNEL_1, 0); + +#ifdef CONFIG_SOC_NRF53_RTC_PRETICK +SYS_INIT(rtc_pretick_init, POST_KERNEL, 0); +#endif From 3d89d58cb87843470a6b57b5a5b56b7e29b0d84f Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 26 Sep 2023 14:28:36 +0200 Subject: [PATCH 1501/4498] arch: arm: aarch32: Introduce z_arm_on_enter_cpu_idle_prepare() hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce an optional hook to be called when the CPU is made idle. If needed, this hook can be used to prepare data for upcoming call to z_arm_on_enter_cpu_idle(). The main difference is that z_arm_on_enter_cpu_idle_prepare() hook is called before interrupts are disabled. Signed-off-by: Andrzej Kuroś --- arch/arm/Kconfig | 10 ++++++++++ arch/arm/core/cortex_m/cpu_idle.S | 25 ++++++++++++++++++++----- include/zephyr/arch/arm/misc.h | 9 +++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index da1878c740c..3f775e4d638 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -53,6 +53,16 @@ config ARM_ON_ENTER_CPU_IDLE_HOOK If needed, this hook can be used to prevent the CPU from actually entering sleep by skipping the WFE/WFI instruction. +config ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK + bool + help + Enables a hook (z_arm_on_enter_cpu_idle_prepare()) that is called when + the CPU is made idle (by k_cpu_idle() or k_cpu_atomic_idle()). + If needed, this hook can prepare data to upcoming call to + z_arm_on_enter_cpu_idle(). The z_arm_on_enter_cpu_idle_prepare differs + from z_arm_on_enter_cpu_idle because it is called before interrupts are + disabled. + config ARM_ON_EXIT_CPU_IDLE bool help diff --git a/arch/arm/core/cortex_m/cpu_idle.S b/arch/arm/core/cortex_m/cpu_idle.S index d79ea4f0c16..8acae5ddb13 100644 --- a/arch/arm/core/cortex_m/cpu_idle.S +++ b/arch/arm/core/cortex_m/cpu_idle.S @@ -81,16 +81,24 @@ SECTION_FUNC(TEXT, z_arm_cpu_idle_init) bx lr SECTION_FUNC(TEXT, arch_cpu_idle) -#ifdef CONFIG_TRACING +#if defined(CONFIG_TRACING) || \ + defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) push {r0, lr} + +#ifdef CONFIG_TRACING bl sys_trace_idle +#endif +#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK + bl z_arm_on_enter_cpu_idle_prepare +#endif + #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 #else pop {r0, lr} #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#endif /* CONFIG_TRACING */ +#endif #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* @@ -134,17 +142,24 @@ SECTION_FUNC(TEXT, arch_cpu_idle) bx lr SECTION_FUNC(TEXT, arch_cpu_atomic_idle) -#ifdef CONFIG_TRACING +#if defined(CONFIG_TRACING) || \ + defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) push {r0, lr} + +#ifdef CONFIG_TRACING bl sys_trace_idle +#endif +#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK + bl z_arm_on_enter_cpu_idle_prepare +#endif + #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 #else pop {r0, lr} #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#endif /* CONFIG_TRACING */ - +#endif /* * Lock PRIMASK while sleeping: wfe will still get interrupted by * incoming interrupts but the CPU will not service them right away. diff --git a/include/zephyr/arch/arm/misc.h b/include/zephyr/arch/arm/misc.h index 24ed69f663c..ab67a35e94c 100644 --- a/include/zephyr/arch/arm/misc.h +++ b/include/zephyr/arch/arm/misc.h @@ -51,6 +51,15 @@ extern bool z_arm_thread_is_in_user_mode(void); bool z_arm_on_enter_cpu_idle(void); #endif +#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) +/* Prototype of a hook that can be enabled to be called every time the CPU is + * made idle (the calls will be done from k_cpu_idle() and k_cpu_atomic_idle()). + * The function is called before interrupts are disabled and can prepare to + * upcoming call to z_arm_on_enter_cpu_idle. + */ +void z_arm_on_enter_cpu_idle_prepare(void); +#endif + #endif #ifdef __cplusplus From e03d5d4c6dd5d08b0126153203b6dd0331f47507 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Mon, 18 Sep 2023 10:06:22 +0200 Subject: [PATCH 1502/4498] nrf53: RTC pretick allows user channels and require just one CC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nrf53 pretick can be used with non-zero `NRF_RTC_TIMER_USER_CHAN_COUNT` Kconfig option. The nrf53 pretick requires just one RTC1 CC channel. The nrf53 pretick handles also RTC1 and RTC0 both CCs and OVERFLOW events by examination of events scheduled on them. The pretick is set based on number of ticks to the closest event scheduled that can trigger an interrupt. Because the operation in `z_arm_on_enter_cpu_idle` hook would take too much time with interrupts disabled, the `z_arm_on_enter_cpu_idle_prepare` hook enabled by Kconfig option `ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK` is used. It performs RTC0 and RTC1 examination, and sets pretick without interrupts being blocked. The LDREX/STREX are leveraged to detect if exception took place between start of `z_arm_on_enter_cpu_idle_prepare` and `z_arm_on_enter_cpu_idle`. If exception has not been taken, the pretick calculation can be trusted because source data could not changed and too much time could not pass. Otherwise the sleep attempt is disallowed, the idle will loop again and try later. Prompt for `SOC_NRF53_RTC_PRETICK` Kconfig option allows to control this option by an user and turn the feature off if necessary. Signed-off-by: Andrzej Kuroś --- drivers/timer/nrf_rtc_timer.c | 18 +- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 9 +- soc/arm/nordic_nrf/nrf53/soc.c | 274 ++++++++++++++++++++++----- 3 files changed, 239 insertions(+), 62 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index e8ba5bd42a5..9241c5b7a10 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -17,20 +17,18 @@ #include #include +#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ + IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) + #define EXT_CHAN_COUNT CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT #define CHAN_COUNT (EXT_CHAN_COUNT + 1) #define RTC NRF_RTC1 #define RTC_IRQn NRFX_IRQ_NUMBER_GET(RTC) #define RTC_LABEL rtc1 -#define RTC_CH_COUNT RTC1_CC_NUM +#define CHAN_COUNT_MAX (RTC1_CC_NUM - (RTC_PRETICK ? 1 : 0)) -#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ - IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) - -BUILD_ASSERT(!RTC_PRETICK || !(RTC_PRETICK && (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT > 0)), - "Cannot use user channels when RTC pretick is used"); -BUILD_ASSERT(CHAN_COUNT <= RTC_CH_COUNT, "Not enough compare channels"); +BUILD_ASSERT(CHAN_COUNT <= CHAN_COUNT_MAX, "Not enough compare channels"); /* Ensure that counter driver for RTC1 is not enabled. */ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), "Counter for RTC1 must be disabled"); @@ -49,7 +47,6 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), #define ANCHOR_RANGE_END (7 * COUNTER_SPAN / 8) #define TARGET_TIME_INVALID (UINT64_MAX) -extern void rtc_pretick_rtc1_cc0_set_hook(uint32_t val); extern void rtc_pretick_rtc1_isr_hook(void); static volatile uint32_t overflow_cnt; @@ -268,7 +265,7 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) * This never happens when the written value is N+3. Use 3 cycles as * the nearest possible scheduling then. */ - enum { MIN_CYCLES_FROM_NOW = RTC_PRETICK ? 4 : 3 }; + enum { MIN_CYCLES_FROM_NOW = 3 }; uint32_t cc_val = req_cc; uint32_t cc_inc = MIN_CYCLES_FROM_NOW; @@ -285,9 +282,6 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) for (;;) { uint32_t now; - if (RTC_PRETICK) { - rtc_pretick_rtc1_cc0_set_hook(cc_val); - } set_comparator(chan, cc_val); /* Enable event routing after the required CC value was set. * Even though the above operation may get repeated (see below), diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 15dcf41f46e..59ff2eb2c6f 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -18,7 +18,7 @@ config SOC_NRF5340_CPUNET select ARM_ON_EXIT_CPU_IDLE select SOC_COMPATIBLE_NRF5340_CPUNET imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED - imply SOC_NRF53_RTC_PRETICK + imply SOC_NRF53_RTC_PRETICK if !WDT_NRFX choice prompt "nRF53x MCU Selection" @@ -52,9 +52,14 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND select ARM_ON_ENTER_CPU_IDLE_HOOK config SOC_NRF53_RTC_PRETICK - bool + bool "Pre-tick workaround for nRF5340 anomaly 165" depends on !NRF_802154_RADIO_DRIVER select NRFX_DPPI + select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET + select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET + help + Indicates that the pre-tick workaround for the anomaly 165 that affects + the nRF5340 SoC should be applied. if SOC_NRF53_RTC_PRETICK diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 50f00932be9..aa93dfd4b54 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -42,8 +43,11 @@ #define PIN_XL1 0 #define PIN_XL2 1 -#define RTC1_PRETICK_CC_CHAN 1 -#define RTC1_PRETICK_OVERFLOW_CHAN 2 +#define RTC1_PRETICK_CC_CHAN (RTC1_CC_NUM - 1) + +/* Mask of CC channels capable of generating interrupts, see nrf_rtc_timer.c */ +#define RTC1_PRETICK_SELECTED_CC_MASK BIT_MASK(CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT + 1U) +#define RTC0_PRETICK_SELECTED_CC_MASK BIT_MASK(NRF_RTC_CC_COUNT_MAX) #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) #define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ @@ -130,39 +134,240 @@ static bool nrf53_anomaly_160_check(void) return true; } -bool z_arm_on_enter_cpu_idle(void) +#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) + +BUILD_ASSERT(!IS_ENABLED(CONFIG_WDT_NRFX), + "For CONFIG_SOC_NRF53_RTC_PRETICK watchdog is used internally for the pre-tick workaround on nRF5340 cpunet. Application cannot use the watchdog."); + +static inline uint32_t rtc_counter_sub(uint32_t a, uint32_t b) { - bool ok_to_sleep = nrf53_anomaly_160_check(); + return (a - b) & NRF_RTC_COUNTER_MAX; +} -#if (LOG_LEVEL >= LOG_LEVEL_DBG) - static bool suppress_message; +static bool rtc_ticks_to_next_event_get(NRF_RTC_Type *rtc, uint32_t selected_cc_mask, uint32_t cntr, + uint32_t *ticks_to_next_event) +{ + bool result = false; - if (ok_to_sleep) { - suppress_message = false; - } else if (!suppress_message) { - LOG_DBG("Anomaly 160 trigger conditions detected."); - suppress_message = true; + /* Let's preload register to speed-up. */ + uint32_t reg_intenset = rtc->INTENSET; + + /* Note: TICK event not handled. */ + + if (reg_intenset & NRF_RTC_INT_OVERFLOW_MASK) { + /* Overflow can generate an interrupt. */ + *ticks_to_next_event = NRF_RTC_COUNTER_MAX + 1U - cntr; + result = true; } -#endif -#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) + + for (uint32_t chan = 0; chan < NRF_RTC_CC_COUNT_MAX; chan++) { + if ((selected_cc_mask & (1U << chan)) && + (reg_intenset & NRF_RTC_CHANNEL_INT_MASK(chan))) { + /* The CC is in selected mask and is can generate an interrupt. */ + uint32_t cc = nrf_rtc_cc_get(rtc, chan); + uint32_t ticks_to_fire = rtc_counter_sub(cc, cntr); + + if (ticks_to_fire == 0U) { + /* When ticks_to_fire == 0, the event should have been just + * generated the interrupt can be already handled or be pending. + * However the next event is expected to be after counter wraps. + */ + ticks_to_fire = NRF_RTC_COUNTER_MAX + 1U; + } + + if (!result) { + *ticks_to_next_event = ticks_to_fire; + result = true; + } else if (ticks_to_fire < *ticks_to_next_event) { + *ticks_to_next_event = ticks_to_fire; + result = true; + } else { + /* CC that fires no earlier than already found. */ + } + } + } + + return result; +} + +static void rtc_counter_synchronized_get(NRF_RTC_Type *rtc_a, NRF_RTC_Type *rtc_b, + uint32_t *counter_a, uint32_t *counter_b) +{ + do { + *counter_a = nrf_rtc_counter_get(rtc_a); + barrier_dmem_fence_full(); + *counter_b = nrf_rtc_counter_get(rtc_b); + barrier_dmem_fence_full(); + } while (*counter_a != nrf_rtc_counter_get(rtc_a)); +} + +static uint8_t cpu_idle_prepare_monitor_dummy; +static bool cpu_idle_prepare_allows_sleep; + +static void cpu_idle_prepare_monitor_begin(void) +{ + __LDREXB(&cpu_idle_prepare_monitor_dummy); +} + +/* Returns 0 if no exception preempted since the last call to cpu_idle_prepare_monitor_begin. */ +static bool cpu_idle_prepare_monitor_end(void) +{ + /* The value stored is irrelevant. If any exception took place after + * cpu_idle_prepare_monitor_begin, the the local monitor is cleared and + * the store fails returning 1. + * See Arm v8-M Architecture Reference Manual: + * Chapter B9.2 The local monitors + * Chapter B9.4 Exclusive access instructions and the monitors + * See Arm Cortex-M33 Processor Technical Reference Manual + * Chapter 3.5 Exclusive monitor + */ + return __STREXB(0U, &cpu_idle_prepare_monitor_dummy); +} + +void z_arm_on_enter_cpu_idle_prepare(void) +{ + bool ok_to_sleep = true; + + cpu_idle_prepare_monitor_begin(); + + uint32_t rtc_counter = 0U; + uint32_t rtc_ticks_to_next_event = 0U; + uint32_t rtc0_counter = 0U; + uint32_t rtc0_ticks_to_next_event = 0U; + + rtc_counter_synchronized_get(NRF_RTC1, NRF_RTC0, &rtc_counter, &rtc0_counter); + + bool rtc_scheduled = rtc_ticks_to_next_event_get(NRF_RTC1, RTC1_PRETICK_SELECTED_CC_MASK, + rtc_counter, &rtc_ticks_to_next_event); + + if (rtc_ticks_to_next_event_get(NRF_RTC0, RTC0_PRETICK_SELECTED_CC_MASK, rtc0_counter, + &rtc0_ticks_to_next_event)) { + /* An event is scheduled on RTC0. */ + if (!rtc_scheduled) { + rtc_ticks_to_next_event = rtc0_ticks_to_next_event; + rtc_scheduled = true; + } else if (rtc0_ticks_to_next_event < rtc_ticks_to_next_event) { + rtc_ticks_to_next_event = rtc0_ticks_to_next_event; + } else { + /* Event on RTC0 will not happen earlier than already found. */ + } + } + + if (rtc_scheduled) { + static bool rtc_pretick_cc_set_on_time; + /* The pretick should happen 1 tick before the earliest scheduled event + * that can trigger an interrupt. + */ + uint32_t rtc_pretick_cc_val = (rtc_counter + rtc_ticks_to_next_event - 1U) + & NRF_RTC_COUNTER_MAX; + + if (rtc_pretick_cc_val != nrf_rtc_cc_get(NRF_RTC1, RTC1_PRETICK_CC_CHAN)) { + /* The CC for pretick needs to be updated. */ + nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, rtc_pretick_cc_val); + + if (rtc_ticks_to_next_event >= NRF_RTC_COUNTER_MAX/2) { + /* Pretick is scheduled so far in the future, assumed on time. */ + rtc_pretick_cc_set_on_time = true; + } else { + /* Let's check if we updated CC on time, so that the CC can + * take effect. + */ + barrier_dmem_fence_full(); + rtc_counter = nrf_rtc_counter_get(NRF_RTC1); + uint32_t pretick_cc_to_counter = + rtc_counter_sub(rtc_pretick_cc_val, rtc_counter); + + if ((pretick_cc_to_counter < 3) || + (pretick_cc_to_counter >= NRF_RTC_COUNTER_MAX/2)) { + /* The COUNTER value is close enough to the expected + * pretick CC or has just expired, so the pretick event + * generation is not guaranteed. + */ + rtc_pretick_cc_set_on_time = false; + } else { + /* The written rtc_pretick_cc is guaranteed to to trigger + * compare event. + */ + rtc_pretick_cc_set_on_time = true; + } + } + } else { + /* The CC for pretick doesn't need to be updated, however + * rtc_pretick_cc_set_on_time still holds if we managed to set it on time. + */ + } + + /* If the CC for pretick is set on time, so the pretick CC event can be reliably + * generated then allow to sleep. Otherwise (the CC for pretick cannot be reliably + * generated, because CC was set very short to it's fire time) sleep not at all. + */ + ok_to_sleep = rtc_pretick_cc_set_on_time; + } else { + /* No events on any RTC timers are scheduled. */ + } + if (ok_to_sleep) { NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] |= IPC_PUBLISH_RECEIVE_EN_Msk; - if (!nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) && - !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) && - !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { + if (!nrf_rtc_event_check(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN))) { NRF_WDT->TASKS_STOP = 1; /* Check if any event did not occur after we checked for * stopping condition. If yes, we might have stopped WDT * when it should be running. Restart it. */ - if (nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) || - nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) || - nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { + if (nrf_rtc_event_check(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN))) { NRF_WDT->TASKS_START = 1; } } } + + cpu_idle_prepare_allows_sleep = ok_to_sleep; +} +#endif /* CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET */ + +bool z_arm_on_enter_cpu_idle(void) +{ + bool ok_to_sleep = true; + +#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) + if (cpu_idle_prepare_monitor_end() == 0) { + /* No exception happened since cpu_idle_prepare_monitor_begin. + * We can trust the outcome of. z_arm_on_enter_cpu_idle_prepare + */ + ok_to_sleep = cpu_idle_prepare_allows_sleep; + } else { + /* Exception happened since cpu_idle_prepare_monitor_begin. + * The values which z_arm_on_enter_cpu_idle_prepare could be changed + * by the exception, so we can not trust to it's outcome. + * Do not sleep at all, let's try in the next iteration of idle loop. + */ + ok_to_sleep = false; + } +#endif + + if (ok_to_sleep) { + ok_to_sleep = nrf53_anomaly_160_check(); + +#if (LOG_LEVEL >= LOG_LEVEL_DBG) + static bool suppress_message; + + if (ok_to_sleep) { + suppress_message = false; + } else if (!suppress_message) { + LOG_DBG("Anomaly 160 trigger conditions detected."); + suppress_message = true; + } +#endif + } + +#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) + if (!ok_to_sleep) { + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= + ~IPC_PUBLISH_RECEIVE_EN_Msk; + NRF_WDT->TASKS_STOP = 1; + } #endif return ok_to_sleep; @@ -212,25 +417,12 @@ void rtc_pretick_rtc0_isr_hook(void) rtc_pretick_rtc_isr_hook(); } -void rtc_pretick_rtc1_cc0_set_hook(uint32_t val) -{ - nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, val - 1); -} - void rtc_pretick_rtc1_isr_hook(void) { rtc_pretick_rtc_isr_hook(); - if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW)) { - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); - } - } - if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_COMPARE_0)) { - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - } + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); } } @@ -244,11 +436,8 @@ static int rtc_pretick_cpunet_init(void) uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); uint32_t task_wdt = nrf_wdt_task_address_get(NRF_WDT, NRF_WDT_TASK_START); - uint32_t evt_mpsl_cc = nrf_rtc_event_address_get(NRF_RTC0, NRF_RTC_EVENT_COMPARE_3); uint32_t evt_cc = nrf_rtc_event_address_get(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - uint32_t evt_overflow = nrf_rtc_event_address_get(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); /* Configure Watchdog to allow stopping. */ nrf_wdt_behaviour_set(NRF_WDT, WDT_CONFIG_STOPEN_Msk | BIT(4)); @@ -267,24 +456,14 @@ static int rtc_pretick_cpunet_init(void) return -ENOMEM; } - /* Setup a PPI connection between RTC "pretick" events and IPC task. */ - if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE)) { - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_mpsl_cc); - } nrfx_gppi_event_endpoint_setup(ppi_ch, evt_cc); - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_overflow); nrfx_gppi_task_endpoint_setup(ppi_ch, task_ipc); nrfx_gppi_event_endpoint_setup(ppi_ch, evt_ipc); nrfx_gppi_task_endpoint_setup(ppi_ch, task_wdt); nrfx_gppi_channels_enable(BIT(ppi_ch)); nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_CC_CHAN)); - nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_OVERFLOW_CHAN)); - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); - /* Set event 1 tick before overflow. */ - nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_OVERFLOW_CHAN, 0x00FFFFFF); return 0; } @@ -292,7 +471,6 @@ static int rtc_pretick_cpunet_init(void) static int rtc_pretick_init(void) { - ARG_UNUSED(unused); #ifdef CONFIG_SOC_NRF5340_CPUAPP return rtc_pretick_cpuapp_init(); #else From d44e96e486ae442d523c3b88ba1ec39b6d5891bd Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Mon, 25 Sep 2023 11:51:15 +0200 Subject: [PATCH 1503/4498] nrf53: pretick with NRF_802154_RADIO_DRIVER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `SOC_NRF53_RTC_PRETICK` option is now allowed to be used with `NRF_802154_RADIO_DRIVER`. Signed-off-by: Andrzej Kuroś --- drivers/timer/Kconfig.nrf_rtc | 1 + soc/arm/nordic_nrf/nrf53/Kconfig.soc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index cda05d4dabe..acb6f123afe 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -19,6 +19,7 @@ if NRF_RTC_TIMER config NRF_RTC_TIMER_USER_CHAN_COUNT int "Additional channels that can be used" + default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 0 help diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 59ff2eb2c6f..87d8a6d0c7a 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -53,7 +53,6 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND config SOC_NRF53_RTC_PRETICK bool "Pre-tick workaround for nRF5340 anomaly 165" - depends on !NRF_802154_RADIO_DRIVER select NRFX_DPPI select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET @@ -204,6 +203,7 @@ config NRF53_SYNC_RTC_INIT_PRIORITY nRF53 Synchronized RTC initialization priority. config NRF_RTC_TIMER_USER_CHAN_COUNT + default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 1 From 33277f9b48fc5898b6608763aa4fe4f480a1a6a6 Mon Sep 17 00:00:00 2001 From: Abram Early Date: Tue, 12 Jan 2021 13:15:00 -0700 Subject: [PATCH 1504/4498] drivers: can: Implement MCP25xxFD driver Implementation for Microchip MCP2517FD/MCP2518FD SPI based CAN-FD controller. Signed-off-by: Abram Early --- drivers/can/CMakeLists.txt | 1 + drivers/can/Kconfig | 1 + drivers/can/Kconfig.mcp25xxfd | 56 ++ drivers/can/can_mcp25xxfd.c | 1088 +++++++++++++++++++++ drivers/can/can_mcp25xxfd.h | 537 ++++++++++ dts/bindings/can/microchip,mcp25xxfd.yaml | 40 + 6 files changed, 1723 insertions(+) create mode 100644 drivers/can/Kconfig.mcp25xxfd create mode 100644 drivers/can/can_mcp25xxfd.c create mode 100644 drivers/can/can_mcp25xxfd.h create mode 100644 dts/bindings/can/microchip,mcp25xxfd.yaml diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index df2a013c8aa..5a83bb63486 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_FAKE can_fake.c) zephyr_library_sources_ifdef(CONFIG_CAN_LOOPBACK can_loopback.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCAN can_mcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCP2515 can_mcp2515.c) +zephyr_library_sources_ifdef(CONFIG_CAN_MCP25XXFD can_mcp25xxfd.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_FLEXCAN can_mcux_flexcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM can_sam.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM0 can_sam0.c) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index 352192ba63f..90e17889129 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -100,6 +100,7 @@ source "drivers/can/Kconfig.kvaser" source "drivers/can/Kconfig.fake" source "drivers/can/Kconfig.nxp_s32" source "drivers/can/Kconfig.tcan4x5x" +source "drivers/can/Kconfig.mcp25xxfd" source "drivers/can/transceiver/Kconfig" diff --git a/drivers/can/Kconfig.mcp25xxfd b/drivers/can/Kconfig.mcp25xxfd new file mode 100644 index 00000000000..21cdb032f95 --- /dev/null +++ b/drivers/can/Kconfig.mcp25xxfd @@ -0,0 +1,56 @@ +# MCP25XXFD CAN configuration options + +# Copyright (c) 2020 Abram Early +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_MICROCHIP_MCP25XXFD_CAN := microchip,mcp25xxfd + +config CAN_MCP25XXFD + bool "MCP25XXFD CAN Driver" + default $(dt_compat_enabled,$(DT_COMPAT_MICROCHIP_MCP25XXFD_CAN)) + depends on SPI + select CAN_AUTO_BUS_OFF_RECOVERY + select CAN_HAS_CANFD + select CAN_HAS_RX_TIMESTAMP + help + Enable MCP25XXFD CAN Driver + +if CAN_MCP25XXFD + +config CAN_MCP25XXFD_MAX_TX_QUEUE + int "Maximum number of queued messages" + default 4 + range 1 31 + help + Defines the array size of transmit callback pointers and semaphores, + as well as the number of TX FIFOs allocated on the MCP25XXFD. + +config CAN_MCP25XXFD_INT_THREAD_STACK_SIZE + int "Stack size for interrupt handler" + default 768 + help + Size of the stack used for internal thread which is ran for + interrupt handling and incoming packets. + +config CAN_MCP25XXFD_INT_THREAD_PRIO + int "Priority for interrupt handler" + default 2 + help + Priority level of the internal thread which is ran for + interrupt handling and incoming packets. + +config CAN_MAX_FILTER + int "Maximum number of concurrent active filters" + default 5 + range 1 31 + help + Defines the array size of the callback/msgq pointers. + Must be at least the size of concurrent reads. + +config CAN_MCP25XXFD_INIT_PRIORITY + int "Init priority" + default 80 + help + MCP25XXFD driver initialization priority, must be higher than SPI. + +endif # CAN_MCP25XXFD diff --git a/drivers/can/can_mcp25xxfd.c b/drivers/can/can_mcp25xxfd.c new file mode 100644 index 00000000000..30b48495e62 --- /dev/null +++ b/drivers/can/can_mcp25xxfd.c @@ -0,0 +1,1088 @@ +/* + * Copyright (c) 2020 Abram Early + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_mcp25xxfd + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_CAN_LOG_LEVEL +#include +LOG_MODULE_REGISTER(mcp25xxfd_can); + +#include "can_mcp25xxfd.h" + +#define SP_IS_SET(inst) DT_INST_NODE_HAS_PROP(inst, sample_point) || + +/* Macro to exclude the sample point algorithm from compilation if not used + * Without the macro, the algorithm would always waste ROM + */ +#define USE_SP_ALGO (DT_INST_FOREACH_STATUS_OKAY(SP_IS_SET) 0) + +static int mcp25xxfd_reset(const struct device *dev) +{ + uint8_t cmd_buf[] = { 0x00, 0x00 }; + const struct spi_buf tx_buf = { + .buf = cmd_buf, + .len = sizeof(cmd_buf), + }; + const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1U }; + + return spi_write(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, &tx); +} + +static int mcp25xxfd_read(const struct device *dev, uint16_t address, void *rxd, + uint8_t rx_len) +{ + __ASSERT(address < 0x400 || address >= 0xC00 || + (address % 4 == 0 && rx_len % 4 == 0), + "Address and Length must be word aligned in RAM"); + uint8_t cmd_buf[2 + rx_len]; + + cmd_buf[0] = (MCP25XXFD_OPCODE_READ << 4) + ((address >> 8) & 0x0F); + cmd_buf[1] = address & 0xFF; + const struct spi_buf tx_buf[] = { + { .buf = cmd_buf, .len = sizeof(cmd_buf) }, + }; + const struct spi_buf rx_buf[] = { + { .buf = cmd_buf, .len = sizeof(cmd_buf) }, + }; + const struct spi_buf_set tx = { .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf) }; + const struct spi_buf_set rx = { .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf) }; + int ret; + + ret = spi_transceive(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, + &tx, &rx); + memcpy(rxd, &cmd_buf[2], rx_len); + if (ret < 0) { + LOG_ERR("Failed to read %d bytes from 0x%03x", rx_len, address); + } + return ret; +} + +static int mcp25xxfd_write(const struct device *dev, uint16_t address, + void *txd, uint8_t tx_len) +{ + __ASSERT(address < 0x400 || address >= 0xC00 || + (address % 4 == 0 && tx_len % 4 == 0), + "Address and Length must be word aligned in RAM"); + uint8_t cmd_buf[2 + tx_len]; + + cmd_buf[0] = (MCP25XXFD_OPCODE_WRITE << 4) + + ((address >> 8) & 0xF); + cmd_buf[1] = address & 0xFF; + const struct spi_buf tx_buf[] = { + { .buf = cmd_buf, .len = sizeof(cmd_buf) }, + }; + const struct spi_buf_set tx = { .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf) }; + int ret; + + memcpy(&cmd_buf[2], txd, tx_len); + ret = spi_write(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, &tx); + if (ret < 0) { + LOG_ERR("Failed to write %d bytes to 0x%03x", tx_len, address); + } + return ret; +} + +static inline int mcp25xxfd_readb(const struct device *dev, uint16_t address, + void *rxd) +{ + return mcp25xxfd_read(dev, address, rxd, 1); +} + +static inline int mcp25xxfd_writeb(const struct device *dev, uint16_t address, + void *txd) +{ + return mcp25xxfd_write(dev, address, txd, 1); +} + +static inline int mcp25xxfd_readw(const struct device *dev, uint16_t address, + void *rxd) +{ + return mcp25xxfd_read(dev, address, rxd, 4); +} + +static inline int mcp25xxfd_writew(const struct device *dev, uint16_t address, + void *txd) +{ + return mcp25xxfd_write(dev, address, txd, 4); +} + +static int mcp25xxfd_fifo_read(const struct device *dev, uint16_t fifo_address, + void *rxd, uint8_t rx_len) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_fifo fiforegs; + int ret; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp25xxfd_read(dev, fifo_address, &fiforegs, sizeof(fiforegs)); + if (ret < 0) { + goto done; + } + + if (!fiforegs.sta.FNEIF) { + ret = -ENODATA; + goto done; + } + + ret = mcp25xxfd_read(dev, 0x400 + fiforegs.ua, rxd, rx_len); + if (ret < 0) { + goto done; + } + + fiforegs.con.UINC = 1; + ret = mcp25xxfd_writeb(dev, fifo_address + 1, &fiforegs.con.bytes[1]); + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static int mcp25xxfd_fifo_write(const struct device *dev, uint16_t fifo_address, + void *txd, uint8_t tx_len) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_fifo fiforegs; + int ret; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp25xxfd_read(dev, fifo_address, &fiforegs, sizeof(fiforegs)); + if (ret < 0) { + goto done; + } + + if (!fiforegs.sta.FNEIF) { + ret = -ENOMEM; + goto done; + } + + ret = mcp25xxfd_write(dev, 0x400 + fiforegs.ua, txd, tx_len); + if (ret < 0) { + goto done; + } + + fiforegs.con.UINC = 1; + fiforegs.con.TXREQ = 1; + ret = mcp25xxfd_writeb(dev, fifo_address + 1, &fiforegs.con.bytes[1]); + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static void mcp25xxfd_zcanframe_to_txobj(const struct zcan_frame *src, + struct mcp25xxfd_txobj *dst) +{ + memset(dst, 0, offsetof(struct mcp25xxfd_txobj, DATA)); + + if (src->id_type == CAN_STANDARD_IDENTIFIER) { + dst->SID = src->id; + } else { + dst->SID = src->id >> 18; + dst->EID = src->id; + dst->IDE = 1; + } + dst->BRS = src->brs; + dst->RTR = src->rtr == CAN_REMOTEREQUEST; + dst->DLC = src->dlc; +#if defined(CONFIG_CAN_FD_MODE) + dst->FDF = src->fd; +#endif + + memcpy(dst->DATA, src->data, MIN(can_dlc_to_bytes(src->dlc), CAN_MAX_DLEN)); +} + +static void mcp25xxfd_rxobj_to_zcanframe(const struct mcp25xxfd_rxobj *src, + struct zcan_frame *dst) +{ + memset(dst, 0, offsetof(struct zcan_frame, data)); + + if (src->IDE) { + dst->id = src->EID | (src->SID << 18); + dst->id_type = CAN_EXTENDED_IDENTIFIER; + } else { + dst->id = src->SID; + dst->id_type = CAN_STANDARD_IDENTIFIER; + } + dst->brs = src->BRS; + dst->rtr = src->RTR; + dst->dlc = src->DLC; +#if defined(CONFIG_CAN_FD_MODE) + dst->fd = src->FDF; +#endif +#if defined(CONFIG_CAN_RX_TIMESTAMP) + dst->timestamp = src->RXMSGTS; +#endif + + memcpy(dst->data, src->DATA, MIN(can_dlc_to_bytes(src->DLC), CAN_MAX_DLEN)); +} + +static int mcp25xxfd_get_raw_mode(const struct device *dev, uint8_t *mode) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_con con; + int ret; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + ret = mcp25xxfd_readb(dev, MCP25XXFD_REG_CON + 2, &con.byte[2]); + k_mutex_unlock(&dev_data->mutex); + *mode = con.OPMOD; + return ret; +} + +static int mcp25xxfd_set_raw_mode(const struct device *dev, uint8_t mode) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_con con; + int ret; + + while (true) { + k_mutex_lock(&dev_data->mutex, K_FOREVER); + ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_CON, &con); + if (ret < 0 || con.OPMOD == mode) { + k_mutex_unlock(&dev_data->mutex); + break; + } + + if (con.OPMOD == MCP25XXFD_OPMODE_CONFIGURATION) { + /* Configuration mode can be switched to any other mode */ + con.REQMOD = mode; + } else if (con.OPMOD == MCP25XXFD_OPMODE_NORMAL_CANFD || + con.OPMOD == MCP25XXFD_OPMODE_NORMAL_CAN2) { + /* Normal modes can only be directly switched to Sleep, Restricted, or Listen-Only modes */ + if (mode == MCP25XXFD_OPMODE_SLEEP || + mode == MCP25XXFD_OPMODE_RESTRICTED || + mode == MCP25XXFD_OPMODE_LISTEN_ONLY) { + con.REQMOD = mode; + } else { + con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; + } + } else if (con.OPMOD == MCP25XXFD_OPMODE_LISTEN_ONLY) { + /* Listen-Only mode can be directly switched back to normal modes */ + if (mode == MCP25XXFD_OPMODE_NORMAL_CANFD || + mode == MCP25XXFD_OPMODE_NORMAL_CAN2) { + con.REQMOD = mode; + } else { + con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; + } + } else { + /* Otherwise, the device must be put into configuration mode first */ + con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; + } + + LOG_DBG("OPMOD: #%d, REQMOD #%d", con.OPMOD, con.REQMOD); + ret = mcp25xxfd_writeb(dev, MCP25XXFD_REG_CON + 3, + &con.byte[3]); + k_mutex_unlock(&dev_data->mutex); + if (ret < 0) { + break; + } + + ret = k_sem_take(&dev_data->mode_sem, K_MSEC(2)); + if (ret == -EAGAIN) { + return CAN_TIMEOUT; + } + } + return ret; +} + +static int mcp25xxfd_set_mode(const struct device *dev, enum can_mode mode) +{ + switch (mode) { + case CAN_NORMAL_MODE: +#if defined(CONFIG_CAN_FD_MODE) + return mcp25xxfd_set_raw_mode(dev, + MCP25XXFD_OPMODE_NORMAL_CANFD); +#else + return mcp25xxfd_set_raw_mode(dev, + MCP25XXFD_OPMODE_NORMAL_CAN2); +#endif + case CAN_LOOPBACK_MODE: + return mcp25xxfd_set_raw_mode(dev, + MCP25XXFD_OPMODE_EXT_LOOPBACK); + default: + LOG_ERR("Unsupported CAN Mode %u", mode); + case CAN_SILENT_MODE: + return mcp25xxfd_set_raw_mode(dev, + MCP25XXFD_OPMODE_LISTEN_ONLY); + } +} + +static int mcp25xxfd_set_timing(const struct device *dev, + const struct can_timing *timing, + const struct can_timing *timing_data) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + uint8_t mode; + int ret; + +#if defined(CONFIG_CAN_FD_MODE) + if (!timing || !timing_data) { +#else + if (!timing) { +#endif + return -EINVAL; + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp25xxfd_get_raw_mode(dev, &mode); + if (ret < 0) { + goto done; + } + ret = mcp25xxfd_set_raw_mode(dev, MCP25XXFD_OPMODE_CONFIGURATION); + if (ret < 0) { + goto done; + } + + union mcp25xxfd_nbtcfg nbtcfg = { + .BRP = timing->prescaler - 1, + .TSEG1 = (timing->prop_seg + timing->phase_seg1) - 1, + .TSEG2 = timing->phase_seg2 - 1, + .SJW = timing->sjw - 1, + }; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_NBTCFG, nbtcfg.byte); + if (ret < 0) { + LOG_ERR("Failed to write device configuration [%d]", ret); + goto done; + } + +#if defined(CONFIG_CAN_FD_MODE) + union mcp25xxfd_dbtcfg ndtcfg = { + .BRP = timing_data->prescaler - 1, + .TSEG1 = (timing_data->prop_seg + timing_data->phase_seg1) - 1, + .TSEG2 = timing_data->phase_seg2 - 1, + .SJW = timing_data->sjw - 1, + }; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_DBTCFG, ndtcfg.byte); + if (ret < 0) { + LOG_ERR("Failed to write device configuration [%d]", ret); + goto done; + } +#endif + + union mcp25xxfd_tdc tdc = { + .EDGFLTEN = 0, + .SID11EN = 0, +#if defined(CONFIG_CAN_FD_MODE) + .TDCMOD = MCP25XXFD_TDCMOD_AUTO, + .TDCO = timing_data->prescaler * + (timing_data->prop_seg + timing_data->phase_seg1), +#else + .TDCMOD = MCP25XXFD_TDCMOD_DISABLED, +#endif + }; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TDC, &tdc); + if (ret < 0) { + LOG_ERR("Failed to write device configuration [%d]", ret); + goto done; + } + +#if defined(CONFIG_CAN_RX_TIMESTAMP) + union mcp25xxfd_tscon tscon = { + .TBCEN = 1, + .TSRES = 0, + .TSEOF = 0, + .TBCPRE = timing->prescaler - 1, + }; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TSCON, &tscon); + if (ret < 0) { + LOG_ERR("Failed to write device configuration [%d]", ret); + goto done; + } +#endif + + ret = mcp25xxfd_set_raw_mode(dev, mode); + if (ret < 0) { + goto done; + } + +done: + k_mutex_unlock(&dev_data->mutex); + + return ret; +} + +static int mcp25xxfd_send(const struct device *dev, + const struct zcan_frame *msg, k_timeout_t timeout, + can_tx_callback_t callback, void *callback_arg) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + struct mcp25xxfd_txobj tx_frame; + uint8_t mailbox_idx = 0; + int ret; + + LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s", + can_dlc_to_bytes(msg->dlc), msg->id, + msg->id_type == CAN_STANDARD_IDENTIFIER ? + "standard" : "extended", + msg->rtr == CAN_DATAFRAME ? "" : "RTR", + msg->fd == CAN_DATAFRAME ? "" : "FD frame", + msg->brs == CAN_DATAFRAME ? "" : "BRS"); + + if (msg->fd != 1 && msg->dlc > CAN_MAX_DLC) { + LOG_ERR("DLC of %d without fd flag set.", msg->dlc); + return CAN_TX_EINVAL; + } + + if (k_sem_take(&dev_data->tx_sem, timeout) != 0) { + return CAN_TIMEOUT; + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + for (; mailbox_idx < MCP25XXFD_TXFIFOS; mailbox_idx++) { + if ((BIT(mailbox_idx) & dev_data->mailbox_usage) == 0) { + dev_data->mailbox_usage |= BIT(mailbox_idx); + break; + } + } + k_mutex_unlock(&dev_data->mutex); + + if (mailbox_idx >= MCP25XXFD_TXFIFOS) { + k_sem_give(&dev_data->tx_sem); + return CAN_TX_ERR; + } + + dev_data->mailbox[mailbox_idx].cb = callback; + dev_data->mailbox[mailbox_idx].cb_arg = callback_arg; + + mcp25xxfd_zcanframe_to_txobj(msg, &tx_frame); + tx_frame.SEQ = mailbox_idx; + ret = mcp25xxfd_fifo_write(dev, MCP25XXFD_REG_FIFOCON(mailbox_idx), &tx_frame, + offsetof(struct mcp25xxfd_txobj, DATA) + ROUND_UP(can_dlc_to_bytes(msg->dlc), 4)); + + if (ret >= 0) { + if (callback == NULL) { + k_sem_take(&dev_data->mailbox[mailbox_idx].tx_sem, + timeout); + } + } else { + k_mutex_lock(&dev_data->mutex, K_FOREVER); + dev_data->mailbox_usage &= ~BIT(mailbox_idx); + k_mutex_unlock(&dev_data->mutex); + k_sem_give(&dev_data->tx_sem); + } + + return ret; +} + +static int mcp25xxfd_attach_isr(const struct device *dev, + can_rx_callback_t rx_cb, void *cb_arg, + const struct zcan_filter *filter) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_fltcon fltcon; + union mcp25xxfd_fltobj fltobj = { .word = 0 }; + union mcp25xxfd_mask mask = { .word = 0 }; + int filter_idx = 0; + int ret; + + __ASSERT(rx_cb != NULL, "rx_cb can not be null"); + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + while ((BIT(filter_idx) & dev_data->filter_usage) && + (filter_idx < CONFIG_CAN_MAX_FILTER)) { + filter_idx++; + } + + if (filter_idx < CONFIG_CAN_MAX_FILTER) { + if (filter->id_type == CAN_STANDARD_IDENTIFIER) { + fltobj.SID = filter->id; + mask.MSID = filter->id_mask; + } else { + fltobj.SID = filter->id >> 18; + mask.MSID = filter->id_mask >> 18; + fltobj.EID = filter->id; + mask.MEID = filter->id_mask; + fltobj.EXIDE = 1; + } + mask.MIDE = 1; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FLTOBJ(filter_idx), + &fltobj); + if (ret < 0) { + LOG_ERR("Failed to write register [%d]", ret); + goto done; + } + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_MASK(filter_idx), + &mask); + if (ret < 0) { + LOG_ERR("Failed to write register [%d]", ret); + goto done; + } + + fltcon.FLTEN = 1; + fltcon.FLTBP = MCP25XXFD_RXFIFO_IDX; + ret = mcp25xxfd_writeb(dev, MCP21518FD_REG_FLTCON(filter_idx), + fltcon.byte); + if (ret < 0) { + LOG_ERR("Failed to write register [%d]", ret); + goto done; + } + + dev_data->filter_usage |= BIT(filter_idx); + dev_data->filter[filter_idx] = *filter; + dev_data->rx_cb[filter_idx] = rx_cb; + dev_data->cb_arg[filter_idx] = cb_arg; + } else { + filter_idx = CAN_NO_FREE_FILTER; + } +done: + k_mutex_unlock(&dev_data->mutex); + + return filter_idx; +} + +static void mcp25xxfd_detach(const struct device *dev, int filter_nr) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_fltcon fltcon; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + dev_data->filter_usage &= ~BIT(filter_nr); + fltcon.FLTEN = 0; + mcp25xxfd_writeb(dev, MCP21518FD_REG_FLTCON(filter_nr), &fltcon); + + k_mutex_unlock(&dev_data->mutex); +} + +static void mcp25xxfd_register_state_change_isr(const struct device *dev, + can_state_change_isr_t isr) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + + dev_data->state_change_isr = isr; +} + +static enum can_state mcp25xxfd_get_state(const struct device *dev, + struct can_bus_err_cnt *err_cnt) +{ + return DEV_DATA(dev)->state; +} + +static int mcp25xxfd_get_core_clock(const struct device *dev, uint32_t *rate) +{ + const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); + + *rate = dev_cfg->osc_freq; + return 0; +} + +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY +static void mcp25xxfd_recover(const struct device *dev, k_timeout_t timeout) +{ + ARG_UNUSED(dev); + ARG_UNUSED(timeout); +} +#endif + +static void mcp25xxfd_rx(const struct device *dev, int fifo_idx) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + struct mcp25xxfd_rxobj rx_frame; + struct zcan_frame msg; + + while (mcp25xxfd_fifo_read(dev, MCP25XXFD_REG_FIFOCON(fifo_idx), &rx_frame, + sizeof(rx_frame)) >= 0) { + mcp25xxfd_rxobj_to_zcanframe(&rx_frame, &msg); + if (dev_data->filter_usage & BIT(rx_frame.FILHIT)) { + dev_data->rx_cb[rx_frame.FILHIT]( + &msg, dev_data->cb_arg[rx_frame.FILHIT]); + } + } +} + +static void mcp25xxfd_tx_done(const struct device *dev) +{ + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + struct mcp25xxfd_tefobj tefobj; + uint8_t mailbox_idx; + + while (mcp25xxfd_fifo_read(dev, MCP25XXFD_REG_TEFCON, &tefobj, + sizeof(tefobj)) >= 0) { + mailbox_idx = tefobj.SEQ; + if (dev_data->mailbox[mailbox_idx].cb == NULL) { + k_sem_give(&dev_data->mailbox[mailbox_idx].tx_sem); + } else { + dev_data->mailbox[mailbox_idx].cb( + 0, dev_data->mailbox[mailbox_idx].cb_arg); + } + k_mutex_lock(&dev_data->mutex, K_FOREVER); + dev_data->mailbox_usage &= ~BIT(mailbox_idx); + k_mutex_unlock(&dev_data->mutex); + k_sem_give(&dev_data->tx_sem); + } +} + +static void mcp25xxfd_int_thread(const struct device *dev) +{ + const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + union mcp25xxfd_intregs intregs; + union mcp25xxfd_trec trec; + uint32_t ints_before; + int ret; + + while (1) { + k_sem_take(&dev_data->int_sem, K_FOREVER); + + while (1) { + ret = mcp25xxfd_read(dev, MCP25XXFD_REG_INTREGS, + &intregs, sizeof(intregs)); + if (ret < 0) { + continue; + } + ints_before = intregs.ints.word; + + if (intregs.ints.RXIF) { + mcp25xxfd_rx(dev, MCP25XXFD_RXFIFO_IDX); + } + + if (intregs.ints.TEFIF) { + mcp25xxfd_tx_done(dev); + } + + if (intregs.ints.MODIF) { + k_sem_give(&dev_data->mode_sem); + intregs.ints.MODIF = 0; + } + + if (intregs.ints.CERRIF) { + ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_TREC, + &trec); + if (ret >= 0) { + enum can_state new_state; + + if (trec.TXBO) { + new_state = CAN_BUS_OFF; + + /* Upon entering bus-off, all the fifos are reset. */ + LOG_DBG("All FIFOs Reset"); + k_mutex_lock(&dev_data->mutex, K_FOREVER); + for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { + if (!(dev_data->mailbox_usage & BIT(i))) { + continue; + } + if (dev_data->mailbox[i].cb == NULL) { + k_sem_give(&dev_data->mailbox[i].tx_sem); + } else { + dev_data->mailbox[i].cb( + CAN_TX_BUS_OFF, dev_data->mailbox[i].cb_arg); + } + dev_data->mailbox_usage &= ~BIT(i); + k_sem_give(&dev_data->tx_sem); + } + k_mutex_unlock(&dev_data->mutex); + } else if (trec.TXBP || trec.RXBP) { + new_state = CAN_ERROR_PASSIVE; + } else { + new_state = CAN_ERROR_ACTIVE; + } + if (dev_data->state != new_state) { + LOG_DBG("State %d -> %d (tx: %d, rx: %d)", dev_data->state, new_state, trec.TEC, trec.REC); + dev_data->state = new_state; + if (dev_data->state_change_isr) { + struct can_bus_err_cnt + err_cnt; + err_cnt.rx_err_cnt = + trec.REC; + err_cnt.tx_err_cnt = + trec.TEC; + dev_data->state_change_isr( + new_state, + err_cnt); + } + } + + intregs.ints.CERRIF = 0; + } + } + + if (ints_before != intregs.ints.word) { + mcp25xxfd_writew(dev, MCP25XXFD_REG_INT, &intregs.ints); + } + + /* Break from loop if INT pin is inactive */ + ret = gpio_pin_get(dev_data->int_gpio, + dev_cfg->int_pin); + if (ret <= 0) { + /* All interrupt flags handled, but we'll abort if + * an error occurs to avoid deadlock. */ + break; + } + } + + /* Re-enable pin interrupts */ + if (gpio_pin_interrupt_configure(dev_data->int_gpio, dev_cfg->int_pin, + GPIO_INT_LEVEL_ACTIVE)) { + LOG_ERR("Couldn't enable pin interrupt"); + k_oops(); + } + } +} + +static void mcp25xxfd_int_gpio_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + struct mcp25xxfd_data *dev_data = + CONTAINER_OF(cb, struct mcp25xxfd_data, int_gpio_cb); + + /* Disable pin interrupts */ + if (gpio_pin_interrupt_configure(dev, dev_data->int_pin, GPIO_INT_DISABLE)) { + LOG_ERR("Couldn't disable pin interrupt"); + k_oops(); + } + + k_sem_give(&dev_data->int_sem); +} + +static const struct can_driver_api can_api_funcs = { + .set_mode = mcp25xxfd_set_mode, + .set_timing = mcp25xxfd_set_timing, + .send = mcp25xxfd_send, + .attach_isr = mcp25xxfd_attach_isr, + .detach = mcp25xxfd_detach, +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY + .recover = mcp25xxfd_recover, +#endif + .get_state = mcp25xxfd_get_state, + .register_state_change_isr = mcp25xxfd_register_state_change_isr, + .get_core_clock = mcp25xxfd_get_core_clock, + .timing_min = { .sjw = 1, + .prop_seg = 0x0, + .phase_seg1 = 2, + .phase_seg2 = 1, + .prescaler = 1 }, + .timing_max = { .sjw = 128, + .prop_seg = 0x0, + .phase_seg1 = 256, + .phase_seg2 = 128, + .prescaler = 256 }, +#if defined(CONFIG_CAN_FD_MODE) + .timing_min_data = { .sjw = 1, + .prop_seg = 0x0, + .phase_seg1 = 1, + .phase_seg2 = 1, + .prescaler = 1 }, + .timing_max_data = { .sjw = 16, + .prop_seg = 0x0, + .phase_seg1 = 32, + .phase_seg2 = 16, + .prescaler = 256 } +#endif +}; + +static int mcp25xxfd_init(const struct device *dev) +{ + const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); + struct mcp25xxfd_data *dev_data = DEV_DATA(dev); + int ret; + struct can_timing timing; + +#if defined(CONFIG_CAN_FD_MODE) + struct can_timing timing_data; +#endif + + k_sem_init(&dev_data->int_sem, 0, 1); + k_sem_init(&dev_data->mode_sem, 0, 1); + k_sem_init(&dev_data->tx_sem, MCP25XXFD_TXFIFOS, + MCP25XXFD_TXFIFOS); + for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { + k_sem_init(&dev_data->mailbox[i].tx_sem, 0, 1); + } + k_mutex_init(&dev_data->mutex); + + /* SPI Init */ + dev_data->spi_cfg.operation = SPI_WORD_SET(8); + dev_data->spi_cfg.frequency = dev_cfg->spi_freq; + dev_data->spi_cfg.slave = dev_cfg->spi_slave; + dev_data->spi = device_get_binding(dev_cfg->spi_port); + if (!dev_data->spi) { + LOG_ERR("SPI master port %s not found", dev_cfg->spi_port); + return -EINVAL; + } + +#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) + dev_data->spi_cs_ctrl.gpio_dev = + device_get_binding(dev_cfg->spi_cs_port); + if (!dev_data->spi_cs_ctrl.gpio_dev) { + LOG_ERR("Unable to get GPIO SPI CS device"); + return -ENODEV; + } + + dev_data->spi_cs_ctrl.gpio_pin = dev_cfg->spi_cs_pin; + dev_data->spi_cs_ctrl.gpio_dt_flags = dev_cfg->spi_cs_flags; + dev_data->spi_cs_ctrl.delay = 0U; + + dev_data->spi_cfg.cs = &dev_data->spi_cs_ctrl; +#else + dev_data->spi_cfg.cs = NULL; +#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ + + ret = mcp25xxfd_reset(dev); + if (ret < 0) { + LOG_ERR("Failed to reset the device [%d]", ret); + return -EIO; + } + + dev_data->int_gpio = device_get_binding(dev_cfg->int_port); + if (dev_data->int_gpio == NULL) { + LOG_ERR("GPIO port %s not found", dev_cfg->int_port); + return -EINVAL; + } + + if (gpio_pin_configure(dev_data->int_gpio, dev_cfg->int_pin, + (GPIO_INPUT | + DT_INST_GPIO_FLAGS(0, int_gpios)))) { + LOG_ERR("Unable to configure GPIO pin %u", dev_cfg->int_pin); + return -EINVAL; + } + + gpio_init_callback(&(dev_data->int_gpio_cb), + mcp25xxfd_int_gpio_callback, BIT(dev_cfg->int_pin)); + dev_data->int_pin = dev_cfg->int_pin; + + if (gpio_add_callback(dev_data->int_gpio, &(dev_data->int_gpio_cb))) { + return -EINVAL; + } + + if (gpio_pin_interrupt_configure(dev_data->int_gpio, dev_cfg->int_pin, + GPIO_INT_LEVEL_ACTIVE)) { + return -EINVAL; + } + + k_thread_create(&dev_data->int_thread, dev_data->int_thread_stack, + dev_cfg->int_thread_stack_size, + (k_thread_entry_t)mcp25xxfd_int_thread, (void *)dev, + NULL, NULL, K_PRIO_COOP(dev_cfg->int_thread_priority), + 0, K_NO_WAIT); + + timing.sjw = dev_cfg->tq_sjw; + if (dev_cfg->sample_point && USE_SP_ALGO) { + ret = can_calc_timing(dev, &timing, dev_cfg->bus_speed, + dev_cfg->sample_point); + if (ret == -EINVAL) { + LOG_ERR("Can't find timing for given param"); + return -EIO; + } + LOG_DBG("Presc: %d, BS1: %d, BS2: %d", timing.prescaler, + timing.phase_seg1, timing.phase_seg2); + LOG_DBG("Sample-point err : %d", ret); + } else { + timing.prop_seg = dev_cfg->tq_prop; + timing.phase_seg1 = dev_cfg->tq_bs1; + timing.phase_seg2 = dev_cfg->tq_bs2; + ret = can_calc_prescaler(dev, &timing, dev_cfg->bus_speed); + if (ret) { + LOG_WRN("Bitrate error: %d", ret); + } + } + +#if defined(CONFIG_CAN_FD_MODE) + timing_data.sjw = dev_cfg->tq_sjw_data; + if (dev_cfg->sample_point && USE_SP_ALGO) { + ret = can_calc_timing(dev, &timing_data, + dev_cfg->bus_speed_data, + dev_cfg->sample_point_data); + if (ret == -EINVAL) { + LOG_ERR("Can't find timing for given param"); + return -EIO; + } + LOG_DBG("Presc: %d, BS1: %d, BS2: %d", timing.prescaler, + timing.phase_seg1, timing.phase_seg2); + LOG_DBG("Sample-point err : %d", ret); + } else { + timing_data.prop_seg = dev_cfg->tq_prop_data; + timing_data.phase_seg1 = dev_cfg->tq_bs1_data; + timing_data.phase_seg2 = dev_cfg->tq_bs2_data; + ret = can_calc_prescaler(dev, &timing_data, + dev_cfg->bus_speed_data); + if (ret) { + LOG_WRN("Bitrate error: %d", ret); + } + } +#endif + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + union mcp25xxfd_con con; + union mcp25xxfd_int regint = { .word = 0x00000000 }; + union mcp25xxfd_iocon iocon; + union mcp25xxfd_osc osc; + union mcp25xxfd_fifocon tefcon = { .word = 0x00000400 }; + union mcp25xxfd_fifocon txfifocon = { .word = 0x00600400 }; + union mcp25xxfd_fifocon fifocon = { .word = 0x00600400 }; + + ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_CON, &con); + if (ret < 0) { + goto done; + } else if (con.OPMOD != MCP25XXFD_OPMODE_CONFIGURATION) { + LOG_ERR("Device did not reset into configuration mode [%d]", + con.OPMOD); + ret = -EIO; + goto done; + } + con.TXBWS = 0; + con.ABAT = 0; + con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; + con.TXQEN = 1; + con.STEF = 1; + con.SERR2LOM = 0; + con.ESIGM = 0; + con.RTXAT = 0; + con.BRSDIS = 0; + con.BUSY = 0; + con.WFT = MCP25XXFD_WFT_T11FILTER; + con.WAKFIL = 1; + con.PXEDIS = 0; + con.ISOCRCEN = 1; + con.DNCNT = 0; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_CON, con.byte); + if (ret < 0) { + goto done; + } + + osc.PLLEN = 0; + osc.OSCDIS = 0; + osc.LPMEN = 0; + osc.SCLKDIV = 0; + osc.CLKODIV = dev_cfg->clko_div; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_OSC, &osc.word); + if (ret < 0) { + goto done; + } + + iocon.TRIS0 = 1; + iocon.TRIS1 = 1; + iocon.XSTBYEN = 0; + iocon.LAT0 = 0; + iocon.LAT1 = 0; + iocon.PM0 = 1; + iocon.PM1 = 1; + iocon.TXCANOD = 0; + iocon.SOF = dev_cfg->sof_on_clko ? 1 : 0; + iocon.INTOD = 0; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_IOCON, &iocon.word); + if (ret < 0) { + goto done; + } + + regint.RXIE = 1; + regint.MODIE = 1; + regint.TEFIE = 1; + regint.CERRIE = 1; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_INT, ®int); + if (ret < 0) { + goto done; + } + + tefcon.FSIZE = MCP25XXFD_TXFIFOS - 1; + tefcon.FNEIE = 1; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TEFCON, &tefcon); + if (ret < 0) { + goto done; + } + + txfifocon.PLSIZE = can_bytes_to_dlc(MCP25XXFD_PAYLOAD_SIZE) - 8; + txfifocon.FSIZE = 0; + txfifocon.TXPRI = 0; + txfifocon.TXEN = 1; + for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FIFOCON(i), &txfifocon); + if (ret < 0) { + goto done; + } + } + + fifocon.PLSIZE = can_bytes_to_dlc(MCP25XXFD_PAYLOAD_SIZE) - 8; + fifocon.FSIZE = MCP25XXFD_RXFIFO_LENGTH - 1; +#if defined(CONFIG_CAN_RX_TIMESTAMP) + fifocon.TSEN = 1; +#endif + fifocon.FNEIE = 1; + ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FIFOCON(MCP25XXFD_RXFIFO_IDX), &fifocon); + if (ret < 0) { + goto done; + } + + LOG_DBG("%d TX FIFOS: 1 element", MCP25XXFD_TXFIFOS); + LOG_DBG("1 RX FIFO: %ld elements", MCP25XXFD_RXFIFO_LENGTH); + LOG_DBG("%ldb of %db RAM Allocated", MCP25XXFD_TEF_SIZE + MCP25XXFD_TXFIFOS_SIZE + MCP25XXFD_RXFIFO_SIZE, MCP25XXFD_RAM_SIZE); + +done: + k_mutex_unlock(&dev_data->mutex); + +#if defined(CONFIG_CAN_FD_MODE) + ret = can_set_timing(dev, &timing, &timing_data); +#else + ret = can_set_timing(dev, &timing, NULL); +#endif + if (ret < 0) { + return ret; + } + + ret = can_set_mode(dev, CAN_NORMAL_MODE); + + return ret; +} + +#if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) + +static K_KERNEL_STACK_DEFINE(mcp25xxfd_int_stack_0, + CONFIG_CAN_MCP25XXFD_INT_THREAD_STACK_SIZE); +static struct mcp25xxfd_data mcp25xxfd_data_0 = { + .int_thread_stack = mcp25xxfd_int_stack_0 +}; +static const struct mcp25xxfd_config mcp25xxfd_config_0 = { + .spi_port = DT_INST_BUS_LABEL(0), + .spi_freq = DT_INST_PROP(0, spi_max_frequency), + .spi_slave = DT_INST_REG_ADDR(0), +#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) + .spi_cs_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0), + .spi_cs_port = DT_INST_SPI_DEV_CS_GPIOS_LABEL(0), + .spi_cs_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0), +#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ + + .int_pin = DT_INST_GPIO_PIN(0, int_gpios), + .int_port = DT_INST_GPIO_LABEL(0, int_gpios), + .int_thread_stack_size = CONFIG_CAN_MCP25XXFD_INT_THREAD_STACK_SIZE, + .int_thread_priority = CONFIG_CAN_MCP25XXFD_INT_THREAD_PRIO, + + .sof_on_clko = DT_INST_PROP(0, sof_on_clko), + .clko_div = DT_ENUM_IDX(DT_DRV_INST(0), clko_div), + + .osc_freq = DT_INST_PROP(0, osc_freq), + .tq_sjw = DT_INST_PROP(0, sjw), + .tq_prop = DT_INST_PROP_OR(0, prop_seg, 0), + .tq_bs1 = DT_INST_PROP_OR(0, phase_seg1, 0), + .tq_bs2 = DT_INST_PROP_OR(0, phase_seg2, 0), + .bus_speed = DT_INST_PROP(0, bus_speed), + .sample_point = DT_INST_PROP_OR(0, sample_point, 0), + +#if defined(CONFIG_CAN_FD_MODE) + .tq_sjw_data = DT_INST_PROP(0, sjw_data), + .tq_prop_data = DT_INST_PROP_OR(0, prop_seg_data, 0), + .tq_bs1_data = DT_INST_PROP_OR(0, phase_seg1_data, 0), + .tq_bs2_data = DT_INST_PROP_OR(0, phase_seg2_data, 0), + .bus_speed_data = DT_INST_PROP(0, bus_speed_data), + .sample_point_data = DT_INST_PROP_OR(0, sample_point_data, 0) +#endif +}; + +DEVICE_DT_INST_DEFINE(0, &mcp25xxfd_init, NULL, + &mcp25xxfd_data_0, &mcp25xxfd_config_0, POST_KERNEL, + CONFIG_CAN_MCP25XXFD_INIT_PRIORITY, &can_api_funcs); + +#endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) */ diff --git a/drivers/can/can_mcp25xxfd.h b/drivers/can/can_mcp25xxfd.h new file mode 100644 index 00000000000..4d9cb448f97 --- /dev/null +++ b/drivers/can/can_mcp25xxfd.h @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2020 Abram Early + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ +#define ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ + +#include + +#define DEV_CFG(dev) ((const struct mcp25xxfd_config *const)(dev)->config) +#define DEV_DATA(dev) ((struct mcp25xxfd_data *const)(dev)->data) + +#define MCP25XXFD_RAM_SIZE 2048 +#define MCP25XXFD_PAYLOAD_SIZE CLAMP(ROUND_UP(CAN_MAX_DLEN, 4), 8, 64) +#if defined(CONFIG_CAN_TX_TIMESTAMP) +/* Note: This will be implemented with a future can_send overhaul */ +#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (4 + 8)) +#else +#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (0 + 8)) +#endif +#define MCP25XXFD_TXFIFOS_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (8 + MCP25XXFD_PAYLOAD_SIZE)) +#define MCP25XXFD_RXFIFO_MAX \ + ((MCP25XXFD_RAM_SIZE - (MCP25XXFD_TEF_SIZE + MCP25XXFD_TXFIFOS_SIZE))) +#if defined(CONFIG_CAN_RX_TIMESTAMP) +#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (4 + 8 + MCP25XXFD_PAYLOAD_SIZE) +#else +#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (0 + 8 + MCP25XXFD_PAYLOAD_SIZE) +#endif +#define MCP25XXFD_RXFIFO_LENGTH \ + MIN(MCP25XXFD_RXFIFO_MAX / MCP25XXFD_RXFIFO_ELEMENT_SIZE, 32) +#define MCP25XXFD_RXFIFO_SIZE (MCP25XXFD_RXFIFO_LENGTH * MCP25XXFD_RXFIFO_ELEMENT_SIZE) +#define MCP25XXFD_TXFIFOS CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE +#define MCP25XXFD_RXFIFO_IDX CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE +BUILD_ASSERT(MCP25XXFD_RXFIFO_LENGTH >= 1, + "Cannot fit RX FIFO into MCP25xxFD RAM"); + +struct mcp25xxfd_mailbox { + can_tx_callback_t cb; + void *cb_arg; + struct k_sem tx_sem; +}; + +struct mcp25xxfd_data { + /* SPI Data */ + const struct device *spi; + struct spi_config spi_cfg; +#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) + struct spi_cs_control spi_cs_ctrl; +#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ + + /* Interrupt Data */ + const struct device *int_gpio; + struct gpio_callback int_gpio_cb; + struct k_thread int_thread; + k_thread_stack_t *int_thread_stack; + struct k_sem int_sem; + uint8_t int_pin; + + /* General */ + enum can_state state; + can_state_change_isr_t state_change_isr; + struct k_mutex mutex; + struct k_sem mode_sem; + + /* TX Callback */ + struct k_sem tx_sem; + uint32_t mailbox_usage; + struct mcp25xxfd_mailbox mailbox[CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE]; + + /* Filter Data */ + uint64_t filter_usage; + struct zcan_filter filter[CONFIG_CAN_MAX_FILTER]; + can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; + void *cb_arg[CONFIG_CAN_MAX_FILTER]; +}; + +struct mcp25xxfd_config { + /* SPI Config */ + const char *spi_port; + uint32_t spi_freq; + uint8_t spi_slave; + uint8_t spi_cs_pin; + uint8_t spi_cs_flags; + const char *spi_cs_port; + + /* Interrupt Config */ + uint8_t int_pin; + const char *int_port; + size_t int_thread_stack_size; + int int_thread_priority; + uint32_t osc_freq; + + /* CAN Timing */ + uint8_t tq_sjw; + uint8_t tq_prop; + uint8_t tq_bs1; + uint8_t tq_bs2; + uint32_t bus_speed; + uint16_t sample_point; + + /* IO Config */ + bool sof_on_clko; + uint8_t clko_div; + +#if defined(CONFIG_CAN_FD_MODE) + /* CAN-FD Timing */ + uint8_t tq_sjw_data; + uint8_t tq_prop_data; + uint8_t tq_bs1_data; + uint8_t tq_bs2_data; + uint32_t bus_speed_data; + uint16_t sample_point_data; +#endif +}; + +/* MCP25XXFD Opcodes */ +#define MCP25XXFD_OPCODE_RESET 0x00 +#define MCP25XXFD_OPCODE_WRITE 0x02 +#define MCP25XXFD_OPCODE_READ 0x03 + +/* MCP25XXFD Operation Modes */ +#define MCP25XXFD_OPMODE_NORMAL_CANFD 0b000 +#define MCP25XXFD_OPMODE_SLEEP 0b001 +#define MCP25XXFD_OPMODE_INT_LOOPBACK 0b010 +#define MCP25XXFD_OPMODE_LISTEN_ONLY 0b011 +#define MCP25XXFD_OPMODE_CONFIGURATION 0b100 +#define MCP25XXFD_OPMODE_EXT_LOOPBACK 0b101 +#define MCP25XXFD_OPMODE_NORMAL_CAN2 0b110 +#define MCP25XXFD_OPMODE_RESTRICTED 0b110 + +#define MCP25XXFD_WFT_T00FILTER 0b00 +#define MCP25XXFD_WFT_T01FILTER 0b01 +#define MCP25XXFD_WFT_T10FILTER 0b10 +#define MCP25XXFD_WFT_T11FILTER 0b11 + +#define MCP25XXFD_TDCMOD_AUTO 0b10 +#define MCP25XXFD_TDCMOD_MANUAL 0b01 +#define MCP25XXFD_TDCMOD_DISABLED 0b00 + +/* MCP25XXFD Registers */ + +#define MCP25XXFD_REG_CON 0x000 +union mcp25xxfd_con { + struct { + uint32_t DNCNT : 5; /* Device Net Filter Bit Number */ + uint32_t ISOCRCEN : 1; /* Enable ISO CRC in CAN FD Frames */ + uint32_t PXEDIS : 1; /* Protocol Exception Event Detection Disabled */ + uint32_t res0 : 1; + uint32_t WAKFIL : 1; /* Enable CAN Bus Line Wake-up Filter */ + uint32_t WFT : 2; /* Selectable Wake-up Filter Time */ + uint32_t BUSY : 1; /* CAN Module is Busy */ + uint32_t BRSDIS : 1; /* Bit Rate Switching Disable */ + uint32_t res1 : 3; + uint32_t RTXAT : 1; /* Restrict Retransmission Attempts */ + uint32_t ESIGM : 1; /* Transmit ESI in Gateway Mode */ + uint32_t SERR2LOM : 1; /* Transition to Listen Only Mode on System Error */ + uint32_t STEF : 1; /* Store in Transmit Event FIFO */ + uint32_t TXQEN : 1; /* Enable Transmit Queue */ + uint32_t OPMOD : 3; /* Operation Mode Status */ + uint32_t REQMOD : 3; /* Request Operation Mode */ + uint32_t ABAT : 1; /* Abort All Pending Transmissions */ + uint32_t TXBWS : 4; /* Transmit Bandwidth Sharing */ + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_NBTCFG 0x004 +union mcp25xxfd_nbtcfg { + struct { + uint32_t SJW : 7; /* Synchronization Jump Width */ + uint32_t res0 : 1; + uint32_t TSEG2 : 7; /* Time Segment 2 (Phase Segment 2) */ + uint32_t res1 : 1; + uint32_t TSEG1 : 8; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */ + uint32_t BRP : 8; /* Baud Rate Prescaler */ + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_DBTCFG 0x008 +union mcp25xxfd_dbtcfg { + struct { + uint32_t SJW : 4; /* Synchronization Jump Width */ + uint32_t res0 : 4; + uint32_t TSEG2 : 4; /* Time Segment 2 (Phase Segment 2) */ + uint32_t res1 : 4; + uint32_t TSEG1 : 5; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */ + uint32_t res2 : 3; + uint32_t BRP : 8; /* Baud Rate Prescaler */ + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_TDC 0x00C +union mcp25xxfd_tdc { + struct { + uint32_t TDCV : 6; /* Transmitter Delay Compensation Value */ + uint32_t res0 : 2; + uint32_t TDCO : 7; /* Transmitter Delay Compensation Offset */ + uint32_t res1 : 1; + uint32_t TDCMOD : 2; /* Transmitter Delay Compensation Mode */ + uint32_t res2 : 6; + uint32_t SID11EN : 1; /* Enable 12-Bit SID in CAN FD Base Format Messages */ + uint32_t EDGFLTEN : 1; /* Enable Edge Filtering during Bus Integration state */ + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_TSCON 0x014 +union mcp25xxfd_tscon { + struct { + uint32_t TBCPRE : 10; /* Time Base Counter Prescaler */ + uint32_t res0 : 6; + uint32_t TBCEN : 1; /* Time Base Counter Enable */ + uint32_t TSEOF : 1; /* 0: Beginning (See TSREF) / 1: Frame is considered valid */ + uint32_t TSRES : 1; /* Timestamp Sample Point Bit (0: SP of SOF / 1: SP of bit following FDF on FD frames) */ + uint32_t res1 : 13; + }; + uint32_t word; + uint8_t bytes[4]; +}; + +#define MCP25XXFD_REG_VEC 0x018 +union mcp25xxfd_vec { + struct { + uint32_t ICODE : 7; /* Interrupt Flag Code */ + uint32_t res0 : 1; + uint32_t FILHIT : 5; /* Filter Hit Number */ + uint32_t res1 : 3; + uint32_t TXCODE : 7; /* Transmit Interrupt Flag Code */ + uint32_t res2 : 1; + uint32_t RXCODE : 7; /* Receive Interrupt Flag Code */ + uint32_t res3 : 1; + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_INT 0x01C +union mcp25xxfd_int { + struct { + uint32_t TXIF : 1; /* Transmit FIFO Interrupt Flag */ + uint32_t RXIF : 1; /* Receive FIFO Interrupt Flag */ + uint32_t TCBIF : 1; /* Time Base Counter Interrupt Flag */ + uint32_t MODIF : 1; /* Mode Change Interrupt Flag */ + uint32_t TEFIF : 1; /* Transmit Event FIFO Interrupt Flag */ + uint32_t res0 : 3; + uint32_t ECCIF : 1; /* ECC Error Interrupt Flag */ + uint32_t SPICRCIF : 1; /* SPI CRC Error Interrupt Flag */ + uint32_t TXATIF : 1; /* Transmit Attempt Interrupt Flag */ + uint32_t RXOVIF : 1; /* Receive FIFO Overflow Interrupt Flag */ + uint32_t SERRIF : 1; /* System Error Interrupt Flag */ + uint32_t CERRIF : 1; /* CAN Bus Error Interrupt Flag */ + uint32_t WAKIF : 1; /* Bus Wake Up Interrupt Flag */ + uint32_t IVMIF : 1; /* Invalid Message Interrupt Flag */ + uint32_t TXIE : 1; /* Transmit FIFO Interrupt Enable */ + uint32_t RXIE : 1; /* Receive FIFO Interrupt Enable */ + uint32_t TBCIE : 1; /* Time Base Counter Interrupt Enable */ + uint32_t MODIE : 1; /* Mode Change Interrupt Enable */ + uint32_t TEFIE : 1; /* Transmit Event FIFO Interrupt Enable */ + uint32_t res1 : 3; + uint32_t ECCIE : 1; /* ECC Error Interrupt Enable */ + uint32_t SPICRCIE : 1; /* SPI CRC Error Interrupt Enable */ + uint32_t TXATIE : 1; /* Transmit Attempt Interrupt Enable */ + uint32_t RXOVIE : 1; /* Receive FIFO Overflow Interrupt Enable */ + uint32_t SERRIE : 1; /* System Error Interrupt Enable */ + uint32_t CERRIE : 1; /* CAN Bus Error Interrupt Enable */ + uint32_t WAKIE : 1; /* Bus Wake Up Interrupt Enable */ + uint32_t IVMIE : 1; /* Invalid Message Interrupt Enable */ + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_INTREGS MCP25XXFD_REG_VEC +union mcp25xxfd_intregs { + struct { + union mcp25xxfd_vec vec; /* Interrupt Vector Codes */ + union mcp25xxfd_int ints; /* Interrupt Enables/Flags */ + uint32_t rxif; /* FIFO RXIF Interrupt Flags */ + uint32_t txif; /* FIFO TXIF Interrupt Flags */ + uint32_t rxovif; /* FIFO RXOVIF Interrupt Flags */ + uint32_t txatif; /* FIFO TXATIF Interrupt Flags */ + }; + uint32_t words[6]; +}; + +#define MCP25XXFD_REG_TREC 0x034 + +union mcp25xxfd_trec { + struct { + uint32_t REC : 8; /* Receive Error Counter */ + uint32_t TEC : 8; /* Transmit Error Counter */ + uint32_t EWARN : 1; /* Transmitter or Receiver is in Error Warning State */ + uint32_t RXWARN : 1; /* Receiver is in Error Warning State */ + uint32_t TXWARN : 1; /* Transmitter is in Error Warning State */ + uint32_t RXBP : 1; /* Receiver in Error Passive State */ + uint32_t TXBP : 1; /* Transmitter in Error Passive State bit */ + uint32_t TXBO : 1; /* Transmitter in Bus Off State */ + uint32_t res0 : 10; + }; + uint32_t word; + uint8_t bytes[4]; +}; + +#define MCP25XXFD_REG_BDIAG1 0x3C +union mcp25xxfd_bdiag1 { + struct { + uint32_t EFMSGCNT : 16; + uint32_t NBIT0ERR : 1; + uint32_t NBIT1ERR : 1; + uint32_t NACKERR : 1; + uint32_t NFORMERR : 1; + uint32_t NSTUFERR : 1; + uint32_t NCRCERR : 1; + uint32_t res0 : 1; + uint32_t TXBOERR : 1; + uint32_t DBIT0ERR : 1; + uint32_t DBIT1ERR : 1; + uint32_t res1 : 1; + uint32_t DFORMERR : 1; + uint32_t DSTUFERR : 1; + uint32_t DCRCERR : 1; + uint32_t ESI : 1; + uint32_t DLCMM : 1; + }; + uint32_t word; + uint8_t byte[4]; +}; + +/* The FIFOCON, FIFOSTA, and FIFOUA registers are almost identical to their TEF and TXQ counterparts. */ + +#define MCP25XXFD_REG_TEFCON 0x040 +#define MCP25XXFD_REG_TXQCON 0x050 +#define MCP25XXFD_REG_FIFOCON(m) (MCP25XXFD_REG_TXQCON + (m) * 0xC) + +union mcp25xxfd_fifocon { + struct { + uint32_t FNEIE : 1; /* FIFO Not Full/Not Empty Interrupt Enable */ + uint32_t FHIE : 1; /* FIFO Half Empty/Full Interrupt Enable */ + uint32_t FFIE : 1; /* FIFO Empty/Full Interrupt Enable */ + uint32_t OVIE : 1; /* FIFO Overflow Interrupt Enable */ + uint32_t TXATIE : 1; /* FIFO TX Attempts Exhuasted Interrupt Enable */ + uint32_t TSEN : 1; /* FIFO Timestamp Enable */ + uint32_t RTREN : 1; /* FIFO Auto RTR Enable */ + uint32_t TXEN : 1; /* FIFO Transmit Enable */ + uint32_t UINC : 1; /* FIFO Increment Head */ + uint32_t TXREQ : 1; /* FIFO Message Send Request */ + uint32_t FRESET : 1; /* FIFO Reset */ + uint32_t res0 : 5; + uint32_t TXPRI : 5; /* Transmit Priority */ + uint32_t TXAT : 2; /* Retransmission Attempts */ + uint32_t res1 : 1; + uint32_t FSIZE : 5; /* FIFO Size */ + uint32_t PLSIZE : 3; /* Payload Size */ + }; + uint32_t word; + uint8_t bytes[4]; +}; + +#define MCP25XXFD_REG_TEFSTA 0x044 +#define MCP25XXFD_REG_TXQSTA 0x054 +#define MCP25XXFD_REG_FIFOSTA(m) (MCP25XXFD_REG_TXQSTA + (m) * 0xC) + +union mcp25xxfd_fifosta { + struct { + uint32_t FNEIF : 1; /* FIFO Not Full/Not Empty Interrupt Flag */ + uint32_t FHIF : 1; /* FIFO Half Empty/Full Interrupt Flag */ + uint32_t FFIF : 1; /* FIFO Empty/Full Interrupt Flag */ + uint32_t OVIF : 1; /* FIFO Overflow Interrupt Flag */ + uint32_t TXATIF : 1; /* FIFO TX Attempts Exhuasted Interrupt Flag */ + uint32_t TXERR : 1; /* Transmission Error Status */ + uint32_t TXLARB : 1; /* Message Lost Arbitration Status */ + uint32_t TXABT : 1; /* Message Aborted Status */ + uint32_t FIFOCI : 5; /* FIFO Message Index */ + }; + uint32_t word; + uint8_t bytes[4]; +}; + +#define MCP25XXFD_REG_TEFUA 0x048 +#define MCP25XXFD_REG_TXQUA 0x058 +#define MCP25XXFD_REG_FIFOUA(m) (MCP25XXFD_REG_TXQUA + (m) * 0xC) + +union mcp25xxfd_fifo { + struct { + union mcp25xxfd_fifocon con; /* FIFO Control Register */ + union mcp25xxfd_fifosta sta; /* FIFO Status Register */ + uint32_t ua; /* FIFO User Address Register */ + }; + uint32_t words[3]; +}; + +#define MCP21518FD_REG_FLTCON(m) (0x1D0 + m) +union mcp25xxfd_fltcon { + struct { + uint32_t FLTBP : 5; + uint32_t res : 2; + uint32_t FLTEN : 1; + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_FLTOBJ(m) (0x1F0 + ((m) * 8)) +union mcp25xxfd_fltobj { + struct { + uint32_t SID : 11; + uint32_t EID : 18; + uint32_t SID11 : 1; + uint32_t EXIDE : 1; + uint32_t res0 : 1; + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_MASK(m) (0x1F4 + ((m) * 8)) +union mcp25xxfd_mask { + struct { + uint32_t MSID : 11; + uint32_t MEID : 18; + uint32_t MSID11 : 1; + uint32_t MIDE : 1; + uint32_t res0 : 1; + }; + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_OSC 0xE00 +union mcp25xxfd_osc { + struct { + uint32_t PLLEN : 1; /* PLL Enable (0: Clock from XTAL, 1: Clock from 10x PLL) */ + uint32_t res0 : 1; + uint32_t OSCDIS : 1; /* Clock (Oscillator) Disable */ + uint32_t LPMEN : 1; /* Low Power Mode (LPM) Enable */ + uint32_t SCLKDIV : 1; /* System Clock Divisor (0: 1/1, 1: 1/2) */ + uint32_t CLKODIV : 2; /* Clock Output Divisor (0: 1/1, 1: 1/2, 2: 1/4, 3: 1/10) */ + uint32_t res1 : 1; + uint32_t PLLRDY : 1; /* PLL Ready (0: Not Ready, 1: Locked) */ + uint32_t res2 : 1; + uint32_t OSCRDY : 1; /* Clock Ready (0: Not Ready/Off, 1: Running/Stable) */ + uint32_t res3 : 1; + uint32_t SCLKRDY : 1; /* Synchronized SCLKDIV Bit (0: SCLKDIV 0, 1: SCLKDIV 1) */ + uint32_t res4 : 19; + }; + + uint32_t word; + uint8_t byte[4]; +}; + +#define MCP25XXFD_REG_IOCON 0xE04 +union mcp25xxfd_iocon { + struct { + uint32_t TRIS0 : 1; /* GPIO0 Data Direction (0: Output, 1: Input) */ + uint32_t TRIS1 : 1; /* GPIO1 Data Direction (0: Output, 1: Input) */ + uint32_t res0 : 4; + uint32_t XSTBYEN : 1; /* Enable Transiever Standby Pin Control */ + uint32_t res1 : 1; + uint32_t LAT0 : 1; /* GPIO0 Latch (0: Low, 1: High) */ + uint32_t LAT1 : 1; /* GPIO1 Latch (0: Low, 1: High) */ + uint32_t res2 : 6; + uint32_t GPIO0 : 1; /* GPIO0 Status (0: < VIL, 1: > VIH) */ + uint32_t GPIO1 : 1; /* GPIO1 Status (0: < VIL, 1: > VIH) */ + uint32_t res3 : 6; + uint32_t PM0 : 1; /* GPIO0 Pin Mode (0: INT0, 1: GPIO0) */ + uint32_t PM1 : 1; /* GPIO1 Pin Mode (0: INT1, 1: GPIO1) */ + uint32_t res4 : 2; + uint32_t TXCANOD : 1; /* TXCAN Drive Mode (0: Push/Pull, 1: Open Drain) */ + uint32_t SOF : 1; /* Start-Of-Frame Signal (0: Clock on CLKO, 1: SOF on CLKO) */ + uint32_t INTOD : 1; /* Interrupt Pins Drive Mode (0: Push/Pull, 1: Open Drain) */ + uint32_t res5 : 1; + }; + + uint32_t word; + uint8_t byte[4]; +}; + +/* MCP25XXFD Objects */ + +struct mcp25xxfd_txobj { + uint32_t SID : 11; + uint32_t EID : 18; + uint32_t SID11 : 1; + uint32_t res0 : 2; + uint32_t DLC : 4; /* Data Length Code */ + uint32_t IDE : 1; /* Indentifier Extension Flag */ + uint32_t RTR : 1; /* Remote Transmission Request */ + uint32_t BRS : 1; /* Bit Rate Switch Enable */ + uint32_t FDF : 1; /* FD Frame */ + uint32_t ESI : 1; /* Error Status Indicator */ + uint32_t SEQ : 23; + uint8_t DATA[CAN_MAX_DLEN]; +}; + +struct mcp25xxfd_rxobj { + uint32_t SID : 11; + uint32_t EID : 18; + uint32_t SID11 : 1; + uint32_t res0 : 2; + uint32_t DLC : 4; /* Data Length Code */ + uint32_t IDE : 1; /* Indentifier Extension Flag */ + uint32_t RTR : 1; /* Remote Transmission Request */ + uint32_t BRS : 1; /* Bit Rate Switch Enable */ + uint32_t FDF : 1; /* FD Frame */ + uint32_t ESI : 1; /* Error Status Indicator */ + uint32_t res1 : 2; + uint32_t FILHIT : 5; + uint32_t res2 : 16; +#if defined(CONFIG_CAN_RX_TIMESTAMP) + uint32_t RXMSGTS : 32; +#endif + uint8_t DATA[CAN_MAX_DLEN]; +}; + +struct mcp25xxfd_tefobj { + uint32_t SID : 11; + uint32_t EID : 18; + uint32_t SID11 : 1; + uint32_t res0 : 2; + uint32_t DLC : 4; /* Data Length Code */ + uint32_t IDE : 1; /* Indentifier Extension Flag */ + uint32_t RTR : 1; /* Remote Transmission Request */ + uint32_t BRS : 1; /* Bit Rate Switch Enable */ + uint32_t FDF : 1; /* FD Frame */ + uint32_t ESI : 1; /* Error Status Indicator */ + uint32_t SEQ : 23; +}; + +#endif /* ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ */ diff --git a/dts/bindings/can/microchip,mcp25xxfd.yaml b/dts/bindings/can/microchip,mcp25xxfd.yaml new file mode 100644 index 00000000000..037bf32d405 --- /dev/null +++ b/dts/bindings/can/microchip,mcp25xxfd.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2020 Abram Early +# SPDX-License-Identifier: Apache-2.0 + +description: MCP25XXFD SPI CAN-FD controller + +compatible: "microchip,mcp25xxfd" + +include: [spi-device.yaml, can-fd-controller.yaml] + +properties: + osc-freq: + type: int + required: true + description: Frequency of the external oscillator + int-gpios: + type: phandle-array + required: true + description: > + Interrupt pin. + + This pin signals active low when produced by the controller. The + property value should ensure the flags properly describe the signal + that is presented to the driver. + reg: + type: array + required: true + sof-on-clko: + type: boolean + required: false + description: Output SOF signal on CLKO pin + clko-div: + type: int + required: false + description: The factor to divide the system clock for CLKO + default: 10 + enum: + - 1 + - 2 + - 4 + - 10 \ No newline at end of file From 31bef358975a9224dad2c0aea35ef37d99173644 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Sun, 2 Jul 2023 14:22:50 -0400 Subject: [PATCH 1505/4498] drivers: can: mcp251xfd: Add driver This continue PR #31270. The updated changes are: - Updated to work with latest zephyr - Inplace reads/writes of registers - Batch read of RX messages when multiple messages can be read - FIFO abstraction of RX/TEF queues - Handle ivmif errors - Use READ_CRC for register reads - Use bitmasks instead of bitfield members - Rename mcp25xxfd to mcp251xfd - General cleanups Signed-off-by: Andriy Gelman --- drivers/can/CMakeLists.txt | 2 +- drivers/can/Kconfig | 2 +- drivers/can/Kconfig.mcp251xfd | 61 + drivers/can/Kconfig.mcp25xxfd | 56 - drivers/can/can_mcp251xfd.c | 1786 +++++++++++++++++++++ drivers/can/can_mcp251xfd.h | 557 +++++++ drivers/can/can_mcp25xxfd.c | 1088 ------------- drivers/can/can_mcp25xxfd.h | 537 ------- dts/bindings/can/microchip,mcp251xfd.yaml | 80 + dts/bindings/can/microchip,mcp25xxfd.yaml | 40 - 10 files changed, 2486 insertions(+), 1723 deletions(-) create mode 100644 drivers/can/Kconfig.mcp251xfd delete mode 100644 drivers/can/Kconfig.mcp25xxfd create mode 100644 drivers/can/can_mcp251xfd.c create mode 100644 drivers/can/can_mcp251xfd.h delete mode 100644 drivers/can/can_mcp25xxfd.c delete mode 100644 drivers/can/can_mcp25xxfd.h create mode 100644 dts/bindings/can/microchip,mcp251xfd.yaml delete mode 100644 dts/bindings/can/microchip,mcp25xxfd.yaml diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 5a83bb63486..e0420efe784 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -10,7 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_FAKE can_fake.c) zephyr_library_sources_ifdef(CONFIG_CAN_LOOPBACK can_loopback.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCAN can_mcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCP2515 can_mcp2515.c) -zephyr_library_sources_ifdef(CONFIG_CAN_MCP25XXFD can_mcp25xxfd.c) +zephyr_library_sources_ifdef(CONFIG_CAN_MCP251XFD can_mcp251xfd.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_FLEXCAN can_mcux_flexcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM can_sam.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM0 can_sam0.c) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index 90e17889129..30381b09780 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -100,7 +100,7 @@ source "drivers/can/Kconfig.kvaser" source "drivers/can/Kconfig.fake" source "drivers/can/Kconfig.nxp_s32" source "drivers/can/Kconfig.tcan4x5x" -source "drivers/can/Kconfig.mcp25xxfd" +source "drivers/can/Kconfig.mcp251xfd" source "drivers/can/transceiver/Kconfig" diff --git a/drivers/can/Kconfig.mcp251xfd b/drivers/can/Kconfig.mcp251xfd new file mode 100644 index 00000000000..8e6cb5ad91c --- /dev/null +++ b/drivers/can/Kconfig.mcp251xfd @@ -0,0 +1,61 @@ +# MCP25XXFD CAN configuration options + +# Copyright (c) 2020 Abram Early +# Copyright (c) 2023 Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +config CAN_MCP251XFD + bool "MCP25XXFD CAN Driver" + default y + depends on DT_HAS_MICROCHIP_MCP251XFD_ENABLED + select CRC + select SPI + help + Enable MCP25XXFD CAN Driver + +if CAN_MCP251XFD + +config CAN_MCP251XFD_MAX_TX_QUEUE + int "Maximum number of queued messages" + default 8 + range 1 32 + help + Defines the array size of transmit callback pointers and semaphores, + as well as the number of messages in the TX queue. + +config CAN_MCP251XFD_RX_FIFO_ITEMS + int "Number of CAN messages in the RX fifo" + default 16 + range 1 32 + help + Defines the number of CAN messages in the RX fifo. + +config CAN_MCP251XFD_INT_THREAD_STACK_SIZE + int "Stack size for interrupt handler" + default 768 + help + Size of the stack used for internal thread which is ran for + interrupt handling and incoming packets. + +config CAN_MCP251XFD_INT_THREAD_PRIO + int "Priority for interrupt handler" + default 2 + help + Thread priority of the interrupt handler. A higher number implies a + higher priority. The thread is cooperative and will not be interrupted by + another thread until execution is released. + +config CAN_MCP251XFD_READ_CRC_RETRIES + int "Number of retries during SFR register read" + default 5 + help + Number of retries during SFR register read if CRC fails. + +config CAN_MAX_FILTER + int "Maximum number of concurrent active filters" + default 5 + range 1 31 + help + Maximum number of filters supported by the can_add_rx_callback() API call. + +endif # CAN_MCP251XFD diff --git a/drivers/can/Kconfig.mcp25xxfd b/drivers/can/Kconfig.mcp25xxfd deleted file mode 100644 index 21cdb032f95..00000000000 --- a/drivers/can/Kconfig.mcp25xxfd +++ /dev/null @@ -1,56 +0,0 @@ -# MCP25XXFD CAN configuration options - -# Copyright (c) 2020 Abram Early -# SPDX-License-Identifier: Apache-2.0 - -DT_COMPAT_MICROCHIP_MCP25XXFD_CAN := microchip,mcp25xxfd - -config CAN_MCP25XXFD - bool "MCP25XXFD CAN Driver" - default $(dt_compat_enabled,$(DT_COMPAT_MICROCHIP_MCP25XXFD_CAN)) - depends on SPI - select CAN_AUTO_BUS_OFF_RECOVERY - select CAN_HAS_CANFD - select CAN_HAS_RX_TIMESTAMP - help - Enable MCP25XXFD CAN Driver - -if CAN_MCP25XXFD - -config CAN_MCP25XXFD_MAX_TX_QUEUE - int "Maximum number of queued messages" - default 4 - range 1 31 - help - Defines the array size of transmit callback pointers and semaphores, - as well as the number of TX FIFOs allocated on the MCP25XXFD. - -config CAN_MCP25XXFD_INT_THREAD_STACK_SIZE - int "Stack size for interrupt handler" - default 768 - help - Size of the stack used for internal thread which is ran for - interrupt handling and incoming packets. - -config CAN_MCP25XXFD_INT_THREAD_PRIO - int "Priority for interrupt handler" - default 2 - help - Priority level of the internal thread which is ran for - interrupt handling and incoming packets. - -config CAN_MAX_FILTER - int "Maximum number of concurrent active filters" - default 5 - range 1 31 - help - Defines the array size of the callback/msgq pointers. - Must be at least the size of concurrent reads. - -config CAN_MCP25XXFD_INIT_PRIORITY - int "Init priority" - default 80 - help - MCP25XXFD driver initialization priority, must be higher than SPI. - -endif # CAN_MCP25XXFD diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c new file mode 100644 index 00000000000..83b35f38102 --- /dev/null +++ b/drivers/can/can_mcp251xfd.c @@ -0,0 +1,1786 @@ +/* + * Copyright (c) 2020 Abram Early + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_mcp251xfd + +#include "can_mcp251xfd.h" + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(can_mcp251xfd, CONFIG_CAN_LOG_LEVEL); + +#define SP_IS_SET(inst) DT_INST_NODE_HAS_PROP(inst, sample_point) || + +/* + * Macro to exclude the sample point algorithm from compilation if not used + * Without the macro, the algorithm would always waste ROM + */ +#define USE_SP_ALGO (DT_INST_FOREACH_STATUS_OKAY(SP_IS_SET) 0) + +static void mcp251xfd_canframe_to_txobj(const struct can_frame *src, int mailbox_idx, + struct mcp251xfd_txobj *dst) +{ + dst->flags = 0; + + if ((src->flags & CAN_FRAME_IDE) != 0) { + dst->id = FIELD_PREP(MCP251XFD_OBJ_ID_SID_MASK, src->id >> 18); + dst->id |= FIELD_PREP(MCP251XFD_OBJ_ID_EID_MASK, src->id); + + dst->flags |= MCP251XFD_OBJ_FLAGS_IDE; + } else { + dst->id = FIELD_PREP(MCP251XFD_OBJ_ID_SID_MASK, src->id); + } + + if ((src->flags & CAN_FRAME_BRS) != 0) { + dst->flags |= MCP251XFD_OBJ_FLAGS_BRS; + } + + if ((src->flags & CAN_FRAME_RTR) != 0) { + dst->flags |= MCP251XFD_OBJ_FLAGS_RTR; + } + + dst->flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_DLC_MASK, src->dlc); +#if defined(CONFIG_CAN_FD_MODE) + if ((src->flags & CAN_FRAME_FDF) != 0) { + dst->flags |= MCP251XFD_OBJ_FLAGS_FDF; + } +#endif + dst->flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_SEQ_MASK, mailbox_idx); + + dst->id = sys_cpu_to_le32(dst->id); + dst->flags = sys_cpu_to_le32(dst->flags); + + memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(src->dlc), CAN_MAX_DLEN)); +} + +static void *mcp251xfd_read_reg(const struct device *dev, uint16_t addr, int len) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + struct mcp251xfd_spi_data *spi_data = &dev_data->spi_data; + uint16_t spi_cmd; + int ret; + + spi_cmd = sys_cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ | addr); + memcpy(&spi_data->header[1], &spi_cmd, sizeof(spi_cmd)); + + struct spi_buf tx_buf = {.buf = &spi_data->header[1], .len = MCP251XFD_SPI_CMD_LEN + len}; + struct spi_buf rx_buf = {.buf = &spi_data->header[1], .len = MCP251XFD_SPI_CMD_LEN + len}; + + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; + + ret = spi_transceive_dt(&dev_cfg->bus, &tx, &rx); + if (ret < 0) { + return NULL; + } + + return &spi_data->buf[0]; +} + +static void *mcp251xfd_read_crc(const struct device *dev, uint16_t addr, int len) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + struct mcp251xfd_spi_data *spi_data = &dev_data->spi_data; + int num_retries = CONFIG_CAN_MCP251XFD_READ_CRC_RETRIES + 1; + int ret; + + while (num_retries-- > 0) { + uint16_t crc_in, crc, spi_cmd; + + struct spi_buf tx_buf = {.buf = &spi_data->header[0], + .len = MCP251XFD_SPI_CMD_LEN + + MCP251XFD_SPI_LEN_FIELD_LEN + len + + MCP251XFD_SPI_CRC_LEN}; + + struct spi_buf rx_buf = {.buf = &spi_data->header[0], + .len = MCP251XFD_SPI_CMD_LEN + + MCP251XFD_SPI_LEN_FIELD_LEN + len + + MCP251XFD_SPI_CRC_LEN}; + + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; + + spi_cmd = sys_cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ_CRC | addr); + memcpy(&spi_data->header[0], &spi_cmd, sizeof(spi_cmd)); + spi_data->header[2] = len; + + /* + * Evaluate initial crc over spi_cmd and length as these value will change after + * spi transaction is finished. + */ + crc_in = crc16(MCP251XFD_CRC_POLY, MCP251XFD_CRC_SEED, + (uint8_t *)(&spi_data->header[0]), + MCP251XFD_SPI_CMD_LEN + MCP251XFD_SPI_LEN_FIELD_LEN); + + ret = spi_transceive_dt(&dev_cfg->bus, &tx, &rx); + if (ret < 0) { + continue; + } + + /* Continue crc calculation over the data field and the crc field */ + crc = crc16(MCP251XFD_CRC_POLY, crc_in, &spi_data->buf[0], + len + MCP251XFD_SPI_CRC_LEN); + if (crc == 0) { + return &spi_data->buf[0]; + } + } + + return NULL; +} + +static inline void *mcp251xfd_get_spi_buf_ptr(const struct device *dev) +{ + struct mcp251xfd_data *dev_data = dev->data; + struct mcp251xfd_spi_data *spi_data = &dev_data->spi_data; + + return &spi_data->buf[0]; +} + +static int mcp251xfd_write(const struct device *dev, uint16_t addr, int len) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + struct mcp251xfd_spi_data *spi_data = &dev_data->spi_data; + uint16_t spi_cmd; + + struct spi_buf tx_buf = {.buf = &spi_data->header[1], .len = MCP251XFD_SPI_CMD_LEN + len}; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + + spi_cmd = sys_cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE | addr); + memcpy(&spi_data->header[1], &spi_cmd, sizeof(spi_cmd)); + + return spi_write_dt(&dev_cfg->bus, &tx); +} + +static int mcp251xfd_fifo_write(const struct device *dev, int mailbox_idx, + const struct can_frame *msg) +{ + uint32_t *regs; + struct mcp251xfd_txobj *txobj; + uint8_t *reg_byte; + uint16_t address; + int tx_len; + int ret; + + /* read fifosta and ua at the same time */ + regs = mcp251xfd_read_crc(dev, MCP251XFD_REG_TXQSTA, MCP251XFD_REG_SIZE * 2); + if (!regs) { + LOG_ERR("Failed to read 8 bytes from REG_TXQSTA"); + return -EINVAL; + } + + /* check if fifo is full */ + if (!(regs[0] & MCP251XFD_REG_TXQSTA_TXQNIF)) { + return -ENOMEM; + } + + address = MCP251XFD_RAM_START_ADDR + regs[1]; + + txobj = mcp251xfd_get_spi_buf_ptr(dev); + mcp251xfd_canframe_to_txobj(msg, mailbox_idx, txobj); + + tx_len = MCP251XFD_OBJ_HEADER_SIZE + + ROUND_UP(can_dlc_to_bytes(msg->dlc), MCP251XFD_RAM_ALIGNMENT); + + ret = mcp251xfd_write(dev, address, tx_len); + if (ret < 0) { + return ret; + } + + reg_byte = mcp251xfd_get_spi_buf_ptr(dev); + *reg_byte = MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(MCP251XFD_REG_TXQCON_UINC | + MCP251XFD_REG_TXQCON_TXREQ); + + return mcp251xfd_write(dev, MCP251XFD_REG_TXQCON + 1, 1); +} + +static void mcp251xfd_rxobj_to_canframe(struct mcp251xfd_rxobj *src, struct can_frame *dst) +{ + memset(dst, 0, offsetof(struct can_frame, data)); + + src->id = sys_le32_to_cpu(src->id); + src->flags = sys_le32_to_cpu(src->flags); + + if ((src->flags & MCP251XFD_OBJ_FLAGS_IDE) != 0) { + dst->id = FIELD_GET(MCP251XFD_OBJ_ID_EID_MASK, src->id); + dst->id |= FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK, src->id) << 18; + dst->flags |= CAN_FRAME_IDE; + } else { + dst->id = FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK, src->id); + } + + if ((src->flags & MCP251XFD_OBJ_FLAGS_BRS) != 0) { + dst->flags |= CAN_FRAME_BRS; + } + + if ((src->flags & MCP251XFD_OBJ_FLAGS_RTR) != 0) { + dst->flags |= CAN_FRAME_RTR; + } + +#if defined(CONFIG_CAN_FD_MODE) + if ((src->flags & MCP251XFD_OBJ_FLAGS_FDF) != 0) { + dst->flags |= CAN_FRAME_FDF; + } +#endif + + dst->dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC_MASK, src->flags); + +#if defined(CONFIG_CAN_RX_TIMESTAMP) + dst->timestamp = sys_le32_to_cpu(src->timestamp); +#endif + + memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(dst->dlc), CAN_MAX_DLEN)); +} + +static int mcp251xfd_get_mode_internal(const struct device *dev, uint8_t *mode) +{ + uint8_t *reg_byte; + uint32_t mask = MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(MCP251XFD_REG_CON_OPMOD_MASK); + + reg_byte = mcp251xfd_read_crc(dev, MCP251XFD_REG_CON_B2, 1); + if (!reg_byte) { + return -EINVAL; + } + + *mode = FIELD_GET(mask, *reg_byte); + + return 0; +} + +static int mcp251xfd_reg_check_value_wtimeout(const struct device *dev, uint16_t addr, + uint32_t value, uint32_t mask, + uint32_t timeout_usec, int retries, bool allow_yield) +{ + uint32_t *reg; + uint32_t delay = timeout_usec / retries; + + for (;;) { + reg = mcp251xfd_read_crc(dev, addr, MCP251XFD_REG_SIZE); + if (!reg) { + return -EINVAL; + } + + *reg = sys_le32_to_cpu(*reg); + + if ((*reg & mask) == value) { + return 0; + } + + if (--retries < 0) { + LOG_ERR("Timeout validing 0x%x", addr); + return -EIO; + } + + if (allow_yield) { + k_sleep(K_USEC(delay)); + } else { + k_busy_wait(delay); + } + } + return 0; +} + +static int mcp251xfd_set_tdc(const struct device *dev, bool is_enabled, int tdc_offset) +{ + uint32_t *reg; + + if (is_enabled && + (tdc_offset < MCP251XFD_REG_TDC_TDCO_MIN || tdc_offset > MCP251XFD_REG_TDC_TDCO_MAX)) { + return -EINVAL; + } + + reg = mcp251xfd_get_spi_buf_ptr(dev); + + if (is_enabled) { + *reg = FIELD_PREP(MCP251XFD_REG_TDC_TDCMOD_MASK, MCP251XFD_REG_TDC_TDCMOD_AUTO); + *reg |= FIELD_PREP(MCP251XFD_REG_TDC_TDCO_MASK, tdc_offset); + } else { + *reg = FIELD_PREP(MCP251XFD_REG_TDC_TDCMOD_MASK, MCP251XFD_REG_TDC_TDCMOD_DISABLED); + } + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_TDC, MCP251XFD_REG_SIZE); +} + +static int mcp251xfd_set_mode_internal(const struct device *dev, uint8_t requested_mode) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + uint32_t opmod, reg_con; + int ret = 0; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg = mcp251xfd_read_crc(dev, MCP251XFD_REG_CON, MCP251XFD_REG_SIZE); + if (!reg) { + ret = -EINVAL; + goto done; + } + + reg_con = sys_le32_to_cpu(*reg); + + opmod = FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, reg_con); + if (opmod == requested_mode) { + goto done; + } + +#if defined(CONFIG_CAN_FD_MODE) + if (dev_data->current_mcp251xfd_mode == MCP251XFD_REG_CON_MODE_CONFIG) { + if (requested_mode == MCP251XFD_REG_CON_MODE_CAN2_0 || + requested_mode == MCP251XFD_REG_CON_MODE_EXT_LOOPBACK || + requested_mode == MCP251XFD_REG_CON_MODE_INT_LOOPBACK) { + ret = mcp251xfd_set_tdc(dev, false, 0); + } else if (requested_mode == MCP251XFD_REG_CON_MODE_MIXED) { + ret = mcp251xfd_set_tdc(dev, true, dev_data->tdco); + } + + if (ret < 0) { + goto done; + } + } +#endif + + reg_con &= ~MCP251XFD_REG_CON_REQOP_MASK; + reg_con |= FIELD_PREP(MCP251XFD_REG_CON_REQOP_MASK, requested_mode); + + *reg = sys_cpu_to_le32(reg_con); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_CON, MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write REG_CON register [%d]", MCP251XFD_REG_CON); + goto done; + } + + ret = mcp251xfd_reg_check_value_wtimeout( + dev, MCP251XFD_REG_CON, FIELD_PREP(MCP251XFD_REG_CON_OPMOD_MASK, requested_mode), + MCP251XFD_REG_CON_OPMOD_MASK, MCP251XFD_MODE_CHANGE_TIMEOUT_USEC, + MCP251XFD_MODE_CHANGE_RETRIES, true); +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static int mcp251xfd_set_mode(const struct device *dev, can_mode_t mode) +{ + struct mcp251xfd_data *dev_data = dev->data; + + if (dev_data->started) { + return -EBUSY; + } + + /* todo: Add CAN_MODE_ONE_SHOT support */ + if ((mode & (CAN_MODE_3_SAMPLES | CAN_MODE_ONE_SHOT)) != 0) { + return -ENOTSUP; + } + + if (mode == CAN_MODE_NORMAL) { + dev_data->next_mcp251xfd_mode = MCP251XFD_REG_CON_MODE_CAN2_0; + } + + if ((mode & CAN_MODE_FD) != 0) { +#if defined(CONFIG_CAN_FD_MODE) + dev_data->next_mcp251xfd_mode = MCP251XFD_REG_CON_MODE_MIXED; +#else + return -ENOTSUP; +#endif + } + + if ((mode & CAN_MODE_LISTENONLY) != 0) { + dev_data->next_mcp251xfd_mode = MCP251XFD_REG_CON_MODE_LISTENONLY; + } + + if ((mode & CAN_MODE_LOOPBACK) != 0) { + dev_data->next_mcp251xfd_mode = MCP251XFD_REG_CON_MODE_EXT_LOOPBACK; + } + + dev_data->mode = mode; + + return 0; +} + +static int mcp251xfd_set_timing(const struct device *dev, const struct can_timing *timing) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + int ret; + + if (!timing) { + return -EINVAL; + } + + if (dev_data->started) { + return -EBUSY; + } + + __ASSERT_NO_MSG(timing->prop_seg == 0); + __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 128); + __ASSERT_NO_MSG(timing->phase_seg1 >= 2 && timing->phase_seg1 <= 256); + __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 128); + __ASSERT_NO_MSG(timing->prescaler >= 1 && timing->prescaler <= 256); + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg = mcp251xfd_get_spi_buf_ptr(dev); + *reg = FIELD_PREP(MCP251XFD_REG_NBTCFG_BRP_MASK, timing->prescaler - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_NBTCFG_TSEG1_MASK, + timing->prop_seg + timing->phase_seg1 - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_NBTCFG_TSEG2_MASK, timing->phase_seg2 - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_NBTCFG_SJW_MASK, timing->sjw - 1); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_NBTCFG, MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write NBTCFG register [%d]", ret); + } + + k_mutex_unlock(&dev_data->mutex); + + return ret; +} + + +#if defined(CONFIG_CAN_FD_MODE) +static int mcp251xfd_set_timing_data(const struct device *dev, const struct can_timing *timing) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + int ret; + + if (!timing) { + return -EINVAL; + } + + if (dev_data->started) { + return -EBUSY; + } + + __ASSERT_NO_MSG(timing->prop_seg == 0); + __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 16); + __ASSERT_NO_MSG(timing->phase_seg1 >= 1 && timing->phase_seg1 <= 32); + __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 16); + __ASSERT_NO_MSG(timing->prescaler >= 1 && timing->prescaler <= 256); + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg = mcp251xfd_get_spi_buf_ptr(dev); + + *reg = FIELD_PREP(MCP251XFD_REG_DBTCFG_BRP_MASK, timing->prescaler - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_DBTCFG_TSEG1_MASK, + timing->prop_seg + timing->phase_seg1 - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_DBTCFG_TSEG2_MASK, timing->phase_seg2 - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_DBTCFG_SJW_MASK, timing->sjw - 1); + + *reg = sys_cpu_to_le32(*reg); + + dev_data->tdco = timing->prescaler * (timing->prop_seg + timing->phase_seg1); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_DBTCFG, MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write DBTCFG register [%d]", ret); + } + + k_mutex_unlock(&dev_data->mutex); + + return ret; +} +#endif + +static int mcp251xfd_send(const struct device *dev, const struct can_frame *msg, + k_timeout_t timeout, can_tx_callback_t callback, void *callback_arg) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint8_t mailbox_idx; + int ret = 0; + + LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s", can_dlc_to_bytes(msg->dlc), + msg->id, msg->flags & CAN_FRAME_IDE ? "extended" : "standard", + msg->flags & CAN_FRAME_RTR ? "RTR" : "", + msg->flags & CAN_FRAME_FDF ? "FD frame" : "", + msg->flags & CAN_FRAME_BRS ? "BRS" : ""); + + __ASSERT_NO_MSG(callback != NULL); + + if (!dev_data->started) { + return -ENETDOWN; + } + + if (dev_data->state == CAN_STATE_BUS_OFF) { + return -ENETUNREACH; + } + + if ((msg->flags & CAN_FRAME_FDF) == 0 && msg->dlc > CAN_MAX_DLC) { + LOG_ERR("DLC of %d without fd flag set.", msg->dlc); + return -EINVAL; + } + + if ((msg->flags & CAN_FRAME_FDF) && !(dev_data->mode & CAN_MODE_FD)) { + return -ENOTSUP; + } + + if (k_sem_take(&dev_data->tx_sem, timeout) != 0) { + return -EAGAIN; + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + for (mailbox_idx = 0; mailbox_idx < MCP251XFD_TX_QUEUE_ITEMS; mailbox_idx++) { + if ((BIT(mailbox_idx) & dev_data->mailbox_usage) == 0) { + dev_data->mailbox_usage |= BIT(mailbox_idx); + break; + } + } + + if (mailbox_idx >= MCP251XFD_TX_QUEUE_ITEMS) { + k_sem_give(&dev_data->tx_sem); + ret = -EIO; + goto done; + } + + dev_data->mailbox[mailbox_idx].cb = callback; + dev_data->mailbox[mailbox_idx].cb_arg = callback_arg; + + ret = mcp251xfd_fifo_write(dev, mailbox_idx, msg); + + if (ret < 0) { + dev_data->mailbox_usage &= ~BIT(mailbox_idx); + dev_data->mailbox[mailbox_idx].cb = NULL; + k_sem_give(&dev_data->tx_sem); + } + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static int mcp251xfd_add_rx_filter(const struct device *dev, can_rx_callback_t rx_cb, void *cb_arg, + const struct can_filter *filter) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + uint8_t *reg_byte; + int filter_idx; + int ret; + + __ASSERT(rx_cb != NULL, "rx_cb can not be null"); + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + for (filter_idx = 0; filter_idx < CONFIG_CAN_MAX_FILTER ; filter_idx++) { + if ((BIT(filter_idx) & dev_data->filter_usage) == 0) { + break; + } + } + + if (filter_idx >= CONFIG_CAN_MAX_FILTER) { + filter_idx = -ENOSPC; + goto done; + } + + if ((filter->flags & CAN_FILTER_RTR) != 0) { + filter_idx = -ENOTSUP; + goto done; + } + + reg = mcp251xfd_get_spi_buf_ptr(dev); + + if ((filter->flags & CAN_FILTER_IDE) != 0) { + *reg = FIELD_PREP(MCP251XFD_REG_FLTOBJ_SID_MASK, filter->id >> 18); + *reg |= FIELD_PREP(MCP251XFD_REG_FLTOBJ_EID_MASK, filter->id); + *reg |= MCP251XFD_REG_FLTOBJ_EXIDE; + } else { + *reg = FIELD_PREP(MCP251XFD_REG_FLTOBJ_SID_MASK, filter->id); + } + + *reg = sys_cpu_to_le32(*reg); + ret = mcp251xfd_write(dev, MCP251XFD_REG_FLTOBJ(filter_idx), MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write FLTOBJ register [%d]", ret); + goto done; + } + + reg = mcp251xfd_get_spi_buf_ptr(dev); + if ((filter->flags & CAN_FILTER_IDE) != 0) { + *reg = FIELD_PREP(MCP251XFD_REG_MASK_MSID_MASK, filter->mask >> 18); + *reg |= FIELD_PREP(MCP251XFD_REG_MASK_MEID_MASK, filter->mask); + } else { + *reg = FIELD_PREP(MCP251XFD_REG_MASK_MSID_MASK, filter->mask); + } + *reg |= MCP251XFD_REG_MASK_MIDE; + + *reg = sys_cpu_to_le32(*reg); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_FLTMASK(filter_idx), MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write FLTMASK register [%d]", ret); + goto done; + } + + reg_byte = mcp251xfd_get_spi_buf_ptr(dev); + *reg_byte = MCP251XFD_REG_BYTE_FLTCON_FLTEN; + *reg_byte |= FIELD_PREP(MCP251XFD_REG_BYTE_FLTCON_FBP_MASK, MCP251XFD_RX_FIFO_IDX); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_BYTE_FLTCON(filter_idx), 1); + if (ret < 0) { + LOG_ERR("Failed to write FLTCON register [%d]", ret); + goto done; + } + + dev_data->filter_usage |= BIT(filter_idx); + dev_data->filter[filter_idx] = *filter; + dev_data->rx_cb[filter_idx] = rx_cb; + dev_data->cb_arg[filter_idx] = cb_arg; + +done: + k_mutex_unlock(&dev_data->mutex); + + return filter_idx; +} + +static void mcp251xfd_remove_rx_filter(const struct device *dev, int filter_idx) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint8_t *reg_byte; + uint32_t *reg; + int ret; + + if (filter_idx < 0 || filter_idx >= CONFIG_CAN_MAX_FILTER) { + LOG_ERR("Filter ID %d out of bounds", filter_idx); + return; + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg_byte = mcp251xfd_get_spi_buf_ptr(dev); + *reg_byte = 0; + + ret = mcp251xfd_write(dev, MCP251XFD_REG_BYTE_FLTCON(filter_idx), 1); + if (ret < 0) { + LOG_ERR("Failed to write FLTCON register [%d]", ret); + goto done; + } + + dev_data->filter_usage &= ~BIT(filter_idx); + + reg = mcp251xfd_get_spi_buf_ptr(dev); + reg[0] = 0; + + ret = mcp251xfd_write(dev, MCP251XFD_REG_FLTCON(filter_idx), MCP251XFD_REG_SIZE); + if (ret < 0) { + LOG_ERR("Failed to write FLTCON register [%d]", ret); + } + +done: + k_mutex_unlock(&dev_data->mutex); +} + +static void mcp251xfd_set_state_change_callback(const struct device *dev, + can_state_change_callback_t cb, void *user_data) +{ + struct mcp251xfd_data *dev_data = dev->data; + + dev_data->state_change_cb = cb; + dev_data->state_change_cb_data = user_data; +} + +static int mcp251xfd_get_state(const struct device *dev, enum can_state *state, + struct can_bus_err_cnt *err_cnt) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + int ret = 0; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg = mcp251xfd_read_crc(dev, MCP251XFD_REG_TREC, MCP251XFD_REG_SIZE); + if (!reg) { + ret = -EINVAL; + goto done; + } + + *reg = sys_le32_to_cpu(*reg); + + if (err_cnt != NULL) { + err_cnt->tx_err_cnt = FIELD_GET(MCP251XFD_REG_TREC_TEC_MASK, *reg); + err_cnt->rx_err_cnt = FIELD_GET(MCP251XFD_REG_TREC_REC_MASK, *reg); + } + + if (state == NULL) { + goto done; + } + + if (!dev_data->started) { + *state = CAN_STATE_STOPPED; + goto done; + } + + if ((*reg & MCP251XFD_REG_TREC_TXBO) != 0) { + *state = CAN_STATE_BUS_OFF; + } else if ((*reg & MCP251XFD_REG_TREC_TXBP) != 0) { + *state = CAN_STATE_ERROR_PASSIVE; + } else if ((*reg & MCP251XFD_REG_TREC_RXBP) != 0) { + *state = CAN_STATE_ERROR_PASSIVE; + } else if ((*reg & MCP251XFD_REG_TREC_TXWARN) != 0) { + *state = CAN_STATE_ERROR_WARNING; + } else if ((*reg & MCP251XFD_REG_TREC_RXWARN) != 0) { + *state = CAN_STATE_ERROR_WARNING; + } else { + *state = CAN_STATE_ERROR_ACTIVE; + } + +done: + k_mutex_unlock(&dev_data->mutex); + return 0; +} + +static int mcp251xfd_get_core_clock(const struct device *dev, uint32_t *rate) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + + *rate = dev_cfg->osc_freq; + return 0; +} + +static int mcp251xfd_get_max_filters(const struct device *dev, bool ide) +{ + ARG_UNUSED(ide); + + return CONFIG_CAN_MAX_FILTER; +} + +static int mcp251xfd_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + + *max_bitrate = dev_cfg->max_bitrate; + + return 0; +} + +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY +static int mcp251xfd_recover(const struct device *dev, k_timeout_t timeout) +{ + struct mcp251xfd_data *dev_data = dev->data; + + ARG_UNUSED(timeout); + + if (!dev_data->started) { + return -ENETDOWN; + } + + return -ENOTSUP; +} +#endif + +static int mcp251xfd_handle_fifo_read(const struct device *dev, const struct mcp251xfd_fifo *fifo, + uint8_t fifo_type) +{ + int ret = 0; + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *regs, fifosta, ua; + uint8_t *reg_byte; + + int len; + int fetch_total = 0; + int ui_inc = 0; + uint32_t fifo_tail_index, fifo_tail_addr; + uint8_t fifo_head_index; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + /* read in FIFOSTA and FIFOUA at the same time */ + regs = mcp251xfd_read_crc(dev, MCP251XFD_REG_FIFOCON_TO_STA(fifo->reg_fifocon_addr), + 2 * MCP251XFD_REG_SIZE); + if (!regs) { + ret = -EINVAL; + goto done; + } + fifosta = sys_le32_to_cpu(regs[0]); + ua = sys_le32_to_cpu(regs[1]); + + /* is there any data in the fifo? */ + if (!(fifosta & MCP251XFD_REG_FIFOSTA_TFNRFNIF)) { + goto done; + } + + fifo_tail_addr = ua; + fifo_tail_index = (fifo_tail_addr - fifo->ram_start_addr) / fifo->item_size; + + if (fifo_type == MCP251XFD_FIFO_TYPE_RX) { + /* + * fifo_head_index points where the next message will be written. + * It points to one past the end of the fifo. + */ + fifo_head_index = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifosta); + if (fifo_head_index == 0) { + fifo_head_index = fifo->capacity - 1; + } else { + fifo_head_index -= 1; + } + + if (fifo_tail_index > fifo_head_index) { + /* fetch to the end of the memory and then wrap to the start */ + fetch_total = fifo->capacity - 1 - fifo_tail_index + 1; + fetch_total += fifo_head_index + 1; + } else { + fetch_total = fifo_head_index - fifo_tail_index + 1; + } + } else if (fifo_type == MCP251XFD_FIFO_TYPE_TEF) { + /* FIFOCI doesn't exist for TEF queues, so fetch one message at a time */ + fifo_head_index = fifo_tail_index; + fetch_total = 1; + } else { + ret = -EINVAL; + goto done; + } + + while (fetch_total > 0) { + uint16_t memory_addr; + uint8_t *data; + + if (fifo_tail_index > fifo_head_index) { + len = fifo->capacity - 1 - fifo_tail_index + 1; + } else { + len = fifo_head_index - fifo_tail_index + 1; + } + + memory_addr = MCP251XFD_RAM_START_ADDR + fifo->ram_start_addr + + fifo_tail_index * fifo->item_size; + + data = mcp251xfd_read_reg(dev, memory_addr, len * fifo->item_size); + if (!data) { + LOG_ERR("Error fetching batch message"); + ret = -EINVAL; + goto done; + } + + for (int i = 0; i < len; i++) { + fifo->msg_handler(dev, (void *)(&data[i * fifo->item_size])); + } + + fifo_tail_index = (fifo_tail_index + len) % fifo->capacity; + fetch_total -= len; + ui_inc += len; + } + + reg_byte = mcp251xfd_get_spi_buf_ptr(dev); + *reg_byte = MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(MCP251XFD_REG_FIFOCON_UINC); + + for (int i = 0; i < ui_inc; i++) { + ret = mcp251xfd_write(dev, fifo->reg_fifocon_addr + 1, 1); + if (ret < 0) { + LOG_ERR("Failed to increment pointer"); + goto done; + } + } + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static void mcp251xfd_reset_tx_fifos(const struct device *dev, int status) +{ + struct mcp251xfd_data *dev_data = dev->data; + + LOG_INF("All FIFOs Reset"); + k_mutex_lock(&dev_data->mutex, K_FOREVER); + for (int i = 0; i < MCP251XFD_TX_QUEUE_ITEMS; i++) { + can_tx_callback_t callback; + + if (!(dev_data->mailbox_usage & BIT(i))) { + continue; + } + + callback = dev_data->mailbox[i].cb; + if (callback) { + callback(dev, status, dev_data->mailbox[i].cb_arg); + } + + dev_data->mailbox_usage &= ~BIT(i); + dev_data->mailbox[i].cb = NULL; + k_sem_give(&dev_data->tx_sem); + } + k_mutex_unlock(&dev_data->mutex); +} + +/* + * CERRIF will be set each time a threshold in the TEC/REC counter is crossed by the following + * conditions: + * • TEC or REC exceeds the Error Warning state threshold + * • The transmitter or receiver transitions to Error Passive state + * • The transmitter transitions to Bus Off state + * • The transmitter or receiver transitions from Error Passive to Error Active state + * • The module transitions from Bus Off to Error Active state, after the bus off recovery + * sequence + * When the user clears CERRIF, it will remain clear until a new counter crossing occurs. + */ +static int mcp251xfd_handle_cerrif(const struct device *dev) +{ + enum can_state new_state; + struct mcp251xfd_data *dev_data = dev->data; + struct can_bus_err_cnt err_cnt; + int ret = 0; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp251xfd_get_state(dev, &new_state, &err_cnt); + if (ret < 0) { + goto done; + } + + if (new_state == dev_data->state) { + goto done; + } + + LOG_INF("State %d -> %d (tx: %d, rx: %d)", dev_data->state, new_state, err_cnt.tx_err_cnt, + err_cnt.rx_err_cnt); + + /* Upon entering bus-off, all the fifos are reset. */ + dev_data->state = new_state; + if (new_state == CAN_STATE_BUS_OFF) { + mcp251xfd_reset_tx_fifos(dev, -ENETDOWN); + } + + if (dev_data->state_change_cb) { + dev_data->state_change_cb(dev, new_state, err_cnt, dev_data->state_change_cb_data); + } + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static int mcp251xfd_handle_modif(const struct device *dev) +{ + struct mcp251xfd_data *dev_data = dev->data; + uint8_t mode; + int ret; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp251xfd_get_mode_internal(dev, &mode); + if (ret < 0) { + goto finish; + } + + dev_data->current_mcp251xfd_mode = mode; + + LOG_INF("Switched to mode %d", mode); + + if (mode == dev_data->next_mcp251xfd_mode) { + ret = 0; + goto finish; + } + + /* try to transition back into our target mode */ + if (dev_data->started) { + LOG_INF("Switching back into mode %d", dev_data->next_mcp251xfd_mode); + ret = mcp251xfd_set_mode_internal(dev, dev_data->next_mcp251xfd_mode); + } + +finish: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static int mcp251xfd_handle_ivmif(const struct device *dev) +{ + uint32_t *reg; + struct mcp251xfd_data *dev_data = dev->data; + int ret; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + reg = mcp251xfd_read_crc(dev, MCP251XFD_REG_BDIAG1, MCP251XFD_REG_SIZE); + if (!reg) { + ret = -EINVAL; + goto done; + } + + *reg = sys_le32_to_cpu(*reg); + + if ((*reg & MCP251XFD_REG_BDIAG1_TXBOERR) != 0) { + LOG_INF("ivmif bus-off error"); + mcp251xfd_reset_tx_fifos(dev, -ENETDOWN); + } + + /* Clear the values in diag */ + reg = mcp251xfd_get_spi_buf_ptr(dev); + reg[0] = 0; + ret = mcp251xfd_write(dev, MCP251XFD_REG_BDIAG1, MCP251XFD_REG_SIZE); + +done: + k_mutex_unlock(&dev_data->mutex); + return ret; +} + +static void mcp251xfd_handle_interrupts(const struct device *dev) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + uint16_t *reg_int_hw; + uint32_t reg_int; + int ret; + uint8_t consecutive_calls = 0; + + while (1) { + k_mutex_lock(&dev_data->mutex, K_FOREVER); + reg_int_hw = mcp251xfd_read_crc(dev, MCP251XFD_REG_INT, sizeof(*reg_int_hw)); + + if (!reg_int_hw) { + k_mutex_unlock(&dev_data->mutex); + continue; + } + + *reg_int_hw = sys_le16_to_cpu(*reg_int_hw); + + reg_int = *reg_int_hw; + + /* these interrupt flags need to be explicitly cleared */ + if (*reg_int_hw & MCP251XFD_REG_INT_IF_CLEARABLE_MASK) { + + *reg_int_hw &= ~MCP251XFD_REG_INT_IF_CLEARABLE_MASK; + + *reg_int_hw = sys_cpu_to_le16(*reg_int_hw); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_INT, sizeof(*reg_int_hw)); + if (ret) { + LOG_ERR("Error clearing REG_INT interrupts [%d]", ret); + } + } + + k_mutex_unlock(&dev_data->mutex); + + if ((reg_int & MCP251XFD_REG_INT_RXIF) != 0) { + ret = mcp251xfd_handle_fifo_read(dev, &dev_cfg->rx_fifo, + MCP251XFD_FIFO_TYPE_RX); + if (ret < 0) { + LOG_ERR("Error handling RXIF [%d]", ret); + } + } + + if ((reg_int & MCP251XFD_REG_INT_TEFIF) != 0) { + ret = mcp251xfd_handle_fifo_read(dev, &dev_cfg->tef_fifo, + MCP251XFD_FIFO_TYPE_TEF); + if (ret < 0) { + LOG_ERR("Error handling TEFIF [%d]", ret); + } + } + + if ((reg_int & MCP251XFD_REG_INT_IVMIF) != 0) { + ret = mcp251xfd_handle_ivmif(dev); + if (ret < 0) { + LOG_ERR("Error handling IVMIF [%d]", ret); + } + } + + if ((reg_int & MCP251XFD_REG_INT_MODIF) != 0) { + ret = mcp251xfd_handle_modif(dev); + if (ret < 0) { + LOG_ERR("Error handling MODIF [%d]", ret); + } + } + + /* + * From Linux mcp251xfd driver + * On the MCP2527FD and MCP2518FD, we don't get a CERRIF IRQ on the transition + * TX ERROR_WARNING -> TX ERROR_ACTIVE. + */ + if ((reg_int & MCP251XFD_REG_INT_CERRIF) || + dev_data->state > CAN_STATE_ERROR_ACTIVE) { + ret = mcp251xfd_handle_cerrif(dev); + if (ret < 0) { + LOG_ERR("Error handling CERRIF [%d]", ret); + } + } + + /* Break from loop if INT pin is inactive */ + consecutive_calls++; + ret = gpio_pin_get_dt(&dev_cfg->int_gpio_dt); + if (ret < 0) { + LOG_ERR("Couldn't read INT pin [%d]", ret); + } else if (ret == 0) { + /* All interrupt flags handled */ + break; + } else if (consecutive_calls % MCP251XFD_MAX_INT_HANDLER_CALLS == 0) { + /* If there are clock problems, then MODIF cannot be cleared. */ + /* This is detected if there are too many consecutive calls. */ + /* Sleep this thread if this happens. */ + k_sleep(K_USEC(MCP251XFD_INT_HANDLER_SLEEP_USEC)); + } + } +} + +static void mcp251xfd_int_thread(const struct device *dev) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + + while (1) { + int ret; + + k_sem_take(&dev_data->int_sem, K_FOREVER); + mcp251xfd_handle_interrupts(dev); + + /* Re-enable pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(&dev_cfg->int_gpio_dt, GPIO_INT_LEVEL_ACTIVE); + if (ret < 0) { + LOG_ERR("Couldn't enable pin interrupt [%d]", ret); + k_oops(); + } + } +} + +static void mcp251xfd_int_gpio_callback(const struct device *dev_gpio, struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(dev_gpio); + struct mcp251xfd_data *dev_data = CONTAINER_OF(cb, struct mcp251xfd_data, int_gpio_cb); + const struct device *dev = dev_data->dev; + const struct mcp251xfd_config *dev_cfg = dev->config; + int ret; + + /* Disable pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(&dev_cfg->int_gpio_dt, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Couldn't disable pin interrupt [%d]", ret); + k_oops(); + } + + k_sem_give(&dev_data->int_sem); +} + +static int mcp251xfd_get_capabilities(const struct device *dev, can_mode_t *cap) +{ + ARG_UNUSED(dev); + + *cap = CAN_MODE_NORMAL | CAN_MODE_LISTENONLY | CAN_MODE_LOOPBACK; + +#if defined(CONFIG_CAN_FD_MODE) + *cap |= CAN_MODE_FD; +#endif + + return 0; +} + +static int mcp251xfd_start(const struct device *dev) +{ + struct mcp251xfd_data *dev_data = dev->data; + const struct mcp251xfd_config *dev_cfg = dev->config; + int ret; + + if (dev_data->started) { + return -EALREADY; + } + + /* in case of a race between mcp251xfd_send() and mcp251xfd_stop() */ + mcp251xfd_reset_tx_fifos(dev, -ENETDOWN); + + if (dev_cfg->phy != NULL) { + ret = can_transceiver_enable(dev_cfg->phy); + if (ret < 0) { + LOG_ERR("Failed to enable CAN transceiver [%d]", ret); + return ret; + } + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + ret = mcp251xfd_set_mode_internal(dev, dev_data->next_mcp251xfd_mode); + if (ret < 0) { + LOG_ERR("Failed to set the mode [%d]", ret); + if (dev_cfg->phy != NULL) { + /* Attempt to disable the CAN transceiver in case of error */ + (void)can_transceiver_disable(dev_cfg->phy); + } + } else { + dev_data->started = true; + } + + k_mutex_unlock(&dev_data->mutex); + + return ret; +} + +static int mcp251xfd_stop(const struct device *dev) +{ + struct mcp251xfd_data *dev_data = dev->data; + const struct mcp251xfd_config *dev_cfg = dev->config; + uint8_t *reg_byte; + int ret; + + if (!dev_data->started) { + return -EALREADY; + } + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + + /* abort all transmissions */ + reg_byte = mcp251xfd_get_spi_buf_ptr(dev); + *reg_byte = MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(MCP251XFD_REG_CON_ABAT); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_CON_B3, 1); + if (ret < 0) { + k_mutex_unlock(&dev_data->mutex); + return ret; + } + + /* wait for all the messages to be aborted */ + while (1) { + reg_byte = mcp251xfd_read_crc(dev, MCP251XFD_REG_CON_B3, 1); + + if (!reg_byte || + (*reg_byte & MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(MCP251XFD_REG_CON_ABAT)) == 0) { + break; + } + } + + mcp251xfd_reset_tx_fifos(dev, -ENETDOWN); + + ret = mcp251xfd_set_mode_internal(dev, MCP251XFD_REG_CON_MODE_CONFIG); + if (ret < 0) { + k_mutex_unlock(&dev_data->mutex); + return ret; + } + + dev_data->started = false; + k_mutex_unlock(&dev_data->mutex); + + if (dev_cfg->phy != NULL) { + ret = can_transceiver_disable(dev_cfg->phy); + if (ret < 0) { + LOG_ERR("Failed to disable CAN transceiver [%d]", ret); + return ret; + } + } + + return 0; +} + +static void mcp251xfd_rx_fifo_handler(const struct device *dev, void *data) +{ + struct can_frame dst; + struct mcp251xfd_data *dev_data = dev->data; + struct mcp251xfd_rxobj *rxobj = data; + uint32_t filhit; + + mcp251xfd_rxobj_to_canframe(rxobj, &dst); + + filhit = FIELD_GET(MCP251XFD_OBJ_FILHIT_MASK, rxobj->flags); + if ((dev_data->filter_usage & BIT(filhit)) != 0) { + LOG_DBG("Received msg CAN id: 0x%x", dst.id); + dev_data->rx_cb[filhit](dev, &dst, dev_data->cb_arg[filhit]); + } +} + +static void mcp251xfd_tef_fifo_handler(const struct device *dev, void *data) +{ + struct mcp251xfd_data *dev_data = dev->data; + can_tx_callback_t callback; + struct mcp251xfd_tefobj *tefobj = data; + uint8_t mailbox_idx; + + mailbox_idx = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MASK, tefobj->flags); + if (mailbox_idx >= MCP251XFD_TX_QUEUE_ITEMS) { + mcp251xfd_reset_tx_fifos(dev, -EIO); + LOG_ERR("Invalid mailbox index"); + return; + } + + callback = dev_data->mailbox[mailbox_idx].cb; + if (callback != NULL) { + callback(dev, 0, dev_data->mailbox[mailbox_idx].cb_arg); + } + + dev_data->mailbox_usage &= ~BIT(mailbox_idx); + dev_data->mailbox[mailbox_idx].cb = NULL; + k_sem_give(&dev_data->tx_sem); +} + +static int mcp251xfd_init_timing_struct(struct can_timing *timing, + const struct device *dev, + const struct mcp251xfd_timing_params *timing_params, + bool is_nominal) +{ + int ret; + + if (USE_SP_ALGO && timing_params->sample_point > 0) { + if (is_nominal) { + ret = can_calc_timing(dev, timing, timing_params->bus_speed, + timing_params->sample_point); + } else { + ret = can_calc_timing_data(dev, timing, timing_params->bus_speed, + timing_params->sample_point); + } + if (ret < 0) { + return ret; + } + LOG_DBG("Presc: %d, BS1: %d, BS2: %d", timing->prescaler, timing->phase_seg1, + timing->phase_seg2); + LOG_DBG("Sample-point err : %d", ret); + } else { + timing->sjw = timing_params->sjw; + timing->prop_seg = timing_params->prop_seg; + timing->phase_seg1 = timing_params->phase_seg1; + timing->phase_seg2 = timing_params->phase_seg2; + ret = can_calc_prescaler(dev, timing, timing_params->bus_speed); + if (ret > 0) { + LOG_WRN("Bitrate error: %d", ret); + } + } + + return ret; +} + +static inline int mcp251xfd_init_con_reg(const struct device *dev) +{ + uint32_t *reg; + + reg = mcp251xfd_get_spi_buf_ptr(dev); + *reg = MCP251XFD_REG_CON_ISOCRCEN | MCP251XFD_REG_CON_WAKFIL | MCP251XFD_REG_CON_TXQEN | + MCP251XFD_REG_CON_STEF; + *reg |= FIELD_PREP(MCP251XFD_REG_CON_WFT_MASK, MCP251XFD_REG_CON_WFT_T11FILTER) | + FIELD_PREP(MCP251XFD_REG_CON_REQOP_MASK, MCP251XFD_REG_CON_MODE_CONFIG); + + return mcp251xfd_write(dev, MCP251XFD_REG_CON, MCP251XFD_REG_SIZE); +} + +static inline int mcp251xfd_init_osc_reg(const struct device *dev) +{ + int ret; + const struct mcp251xfd_config *dev_cfg = dev->config; + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + uint32_t reg_value = MCP251XFD_REG_OSC_OSCRDY; + + *reg = FIELD_PREP(MCP251XFD_REG_OSC_CLKODIV_MASK, dev_cfg->clko_div); + if (dev_cfg->pll_enable) { + *reg |= MCP251XFD_REG_OSC_PLLEN; + reg_value |= MCP251XFD_REG_OSC_PLLRDY; + } + + *reg = sys_cpu_to_le32(*reg); + + ret = mcp251xfd_write(dev, MCP251XFD_REG_OSC, MCP251XFD_REG_SIZE); + if (ret < 0) { + return ret; + } + + return mcp251xfd_reg_check_value_wtimeout(dev, MCP251XFD_REG_OSC, reg_value, reg_value, + MCP251XFD_PLLRDY_TIMEOUT_USEC, + MCP251XFD_PLLRDY_RETRIES, false); +} + +static inline int mcp251xfd_init_iocon_reg(const struct device *dev) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + +/* + * MCP2518FD Errata: DS80000789 + * Writing Byte 2/3 of the IOCON register using single SPI write cleat LAT0 and LAT1. + * This has no effect in the current version since LAT0/1 are set to zero anyway. + * However, it needs to be properly handled if other values are needed. Errata suggests + * to do single byte writes instead. + */ + + *reg = MCP251XFD_REG_IOCON_TRIS0 | MCP251XFD_REG_IOCON_TRIS1 | MCP251XFD_REG_IOCON_PM0 | + MCP251XFD_REG_IOCON_PM1; + + if (dev_cfg->sof_on_clko) { + *reg |= MCP251XFD_REG_IOCON_SOF; + } + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_IOCON, MCP251XFD_REG_SIZE); +} + +static inline int mcp251xfd_init_int_reg(const struct device *dev) +{ + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + + *reg = MCP251XFD_REG_INT_RXIE | MCP251XFD_REG_INT_MODIE | MCP251XFD_REG_INT_TEFIE | + MCP251XFD_REG_INT_CERRIE; + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_INT, MCP251XFD_REG_SIZE); +} + +static inline int mcp251xfd_init_tef_fifo(const struct device *dev) +{ + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + + *reg = MCP251XFD_REG_TEFCON_TEFNEIE | MCP251XFD_REG_TEFCON_FRESET; + *reg |= FIELD_PREP(MCP251XFD_REG_TEFCON_FSIZE_MASK, MCP251XFD_TX_QUEUE_ITEMS - 1); + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_TEFCON, MCP251XFD_REG_SIZE); +} + +static inline int mcp251xfd_init_tx_queue(const struct device *dev) +{ + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + + *reg = MCP251XFD_REG_TXQCON_TXEN | MCP251XFD_REG_TXQCON_FRESET; + *reg |= FIELD_PREP(MCP251XFD_REG_TXQCON_TXAT_MASK, MCP251XFD_REG_TXQCON_TXAT_UNLIMITED); + *reg |= FIELD_PREP(MCP251XFD_REG_TXQCON_FSIZE_MASK, MCP251XFD_TX_QUEUE_ITEMS - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_TXQCON_PLSIZE_MASK, + can_bytes_to_dlc(MCP251XFD_PAYLOAD_SIZE) - 8); + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_TXQCON, MCP251XFD_REG_SIZE); +} + +static inline int mcp251xfd_init_rx_fifo(const struct device *dev) +{ + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + + *reg = MCP251XFD_REG_FIFOCON_TFNRFNIE | MCP251XFD_REG_FIFOCON_FRESET; + *reg |= FIELD_PREP(MCP251XFD_REG_FIFOCON_FSIZE_MASK, MCP251XFD_RX_FIFO_ITEMS - 1); + *reg |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, + can_bytes_to_dlc(MCP251XFD_PAYLOAD_SIZE) - 8); +#if defined(CONFIG_CAN_RX_TIMESTAMP) + *reg |= MCP251XFD_REG_FIFOCON_RXTSEN; +#endif + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_FIFOCON(MCP251XFD_RX_FIFO_IDX), + MCP251XFD_REG_SIZE); +} + +#if defined(CONFIG_CAN_RX_TIMESTAMP) +static int mcp251xfd_init_tscon(const struct device *dev) +{ + uint32_t *reg = mcp251xfd_get_spi_buf_ptr(dev); + const struct mcp251xfd_config *dev_cfg = dev->config; + + *reg = MCP251XFD_REG_TSCON_TBCEN; + *reg |= FIELD_PREP(MCP251XFD_REG_TSCON_TBCPRE_MASK, + dev_cfg->timestamp_prescaler - 1); + + *reg = sys_cpu_to_le32(*reg); + + return mcp251xfd_write(dev, MCP251XFD_REG_TSCON, MCP251XFD_REG_SIZE); +} +#endif + +static int mcp251xfd_reset(const struct device *dev) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + uint16_t cmd = sys_cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_RESET); + const struct spi_buf tx_buf = {.buf = &cmd, .len = sizeof(cmd),}; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + int ret; + + /* device can only be reset when in configuration mode */ + ret = mcp251xfd_set_mode_internal(dev, MCP251XFD_REG_CON_MODE_CONFIG); + if (ret < 0) { + return ret; + } + + return spi_write_dt(&dev_cfg->bus, &tx); +} + +static int mcp251xfd_init(const struct device *dev) +{ + const struct mcp251xfd_config *dev_cfg = dev->config; + struct mcp251xfd_data *dev_data = dev->data; + uint32_t *reg; + uint8_t opmod; + int ret; + struct can_timing timing = { 0 }; +#if defined(CONFIG_CAN_FD_MODE) + struct can_timing timing_data = { 0 }; +#endif + + dev_data->dev = dev; + + if (dev_cfg->clk_dev != NULL) { + uint32_t clk_id = dev_cfg->clk_id; + + if (!device_is_ready(dev_cfg->clk_dev)) { + LOG_ERR("Clock controller not ready"); + return -ENODEV; + } + + ret = clock_control_on(dev_cfg->clk_dev, (clock_control_subsys_t)clk_id); + if (ret < 0) { + LOG_ERR("Failed to enable clock [%d]", ret); + return ret; + } + } + + k_sem_init(&dev_data->int_sem, 0, 1); + k_sem_init(&dev_data->tx_sem, MCP251XFD_TX_QUEUE_ITEMS, MCP251XFD_TX_QUEUE_ITEMS); + + k_mutex_init(&dev_data->mutex); + + if (!spi_is_ready_dt(&dev_cfg->bus)) { + LOG_ERR("SPI bus %s not ready", dev_cfg->bus.bus->name); + return -ENODEV; + } + + if (!gpio_is_ready_dt(&dev_cfg->int_gpio_dt)) { + LOG_ERR("GPIO port not ready"); + return -ENODEV; + } + + if (gpio_pin_configure_dt(&dev_cfg->int_gpio_dt, GPIO_INPUT) < 0) { + LOG_ERR("Unable to configure GPIO pin"); + return -EINVAL; + } + + gpio_init_callback(&dev_data->int_gpio_cb, mcp251xfd_int_gpio_callback, + BIT(dev_cfg->int_gpio_dt.pin)); + + if (gpio_add_callback_dt(&dev_cfg->int_gpio_dt, &dev_data->int_gpio_cb) < 0) { + return -EINVAL; + } + + if (gpio_pin_interrupt_configure_dt(&dev_cfg->int_gpio_dt, GPIO_INT_LEVEL_ACTIVE) < 0) { + return -EINVAL; + } + + k_thread_create(&dev_data->int_thread, dev_data->int_thread_stack, + CONFIG_CAN_MCP251XFD_INT_THREAD_STACK_SIZE, + (k_thread_entry_t)mcp251xfd_int_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_CAN_MCP251XFD_INT_THREAD_PRIO), 0, K_NO_WAIT); + + (void)k_thread_name_set(&dev_data->int_thread, "MCP251XFD interrupt thread"); + + ret = mcp251xfd_reset(dev); + if (ret < 0) { + LOG_ERR("Failed to reset the device [%d]", ret); + goto done; + } + + ret = mcp251xfd_init_timing_struct(&timing, dev, &dev_cfg->timing_params, true); + if (ret < 0) { + LOG_ERR("Can't find timing for given param"); + goto done; + } + +#if defined(CONFIG_CAN_FD_MODE) + ret = mcp251xfd_init_timing_struct(&timing_data, dev, &dev_cfg->timing_params_data, false); + if (ret < 0) { + LOG_ERR("Can't find timing for given param"); + goto done; + } +#endif + + reg = mcp251xfd_read_crc(dev, MCP251XFD_REG_CON, MCP251XFD_REG_SIZE); + if (!reg) { + ret = -EINVAL; + goto done; + } + + *reg = sys_le32_to_cpu(*reg); + + opmod = FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, *reg); + + if (opmod != MCP251XFD_REG_CON_MODE_CONFIG) { + LOG_ERR("Device did not reset into configuration mode [%d]", opmod); + ret = -EIO; + goto done; + } + + dev_data->current_mcp251xfd_mode = MCP251XFD_REG_CON_MODE_CONFIG; + + ret = mcp251xfd_init_con_reg(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_init_osc_reg(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_init_iocon_reg(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_init_int_reg(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_set_tdc(dev, false, 0); + if (ret < 0) { + goto done; + } + +#if defined(CONFIG_CAN_RX_TIMESTAMP) + ret = mcp251xfd_init_tscon(dev); + if (ret < 0) { + goto done; + } +#endif + + ret = mcp251xfd_init_tef_fifo(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_init_tx_queue(dev); + if (ret < 0) { + goto done; + } + + ret = mcp251xfd_init_rx_fifo(dev); + if (ret < 0) { + goto done; + } + + LOG_DBG("%d TX FIFOS: 1 element", MCP251XFD_TX_QUEUE_ITEMS); + LOG_DBG("1 RX FIFO: %d elements", MCP251XFD_RX_FIFO_ITEMS); + LOG_DBG("%db of %db RAM Allocated", + MCP251XFD_TEF_FIFO_SIZE + MCP251XFD_TX_QUEUE_SIZE + MCP251XFD_RX_FIFO_SIZE, + MCP251XFD_RAM_SIZE); + +done: + ret = can_set_timing(dev, &timing); + if (ret < 0) { + return ret; + } + +#if defined(CONFIG_CAN_FD_MODE) + ret = can_set_timing_data(dev, &timing_data); + if (ret < 0) { + return ret; + } +#endif + + return ret; +} + +static const struct can_driver_api mcp251xfd_api_funcs = { + .get_capabilities = mcp251xfd_get_capabilities, + .set_mode = mcp251xfd_set_mode, + .set_timing = mcp251xfd_set_timing, +#if defined(CONFIG_CAN_FD_MODE) + .set_timing_data = mcp251xfd_set_timing_data, +#endif + .start = mcp251xfd_start, + .stop = mcp251xfd_stop, + .send = mcp251xfd_send, + .add_rx_filter = mcp251xfd_add_rx_filter, + .remove_rx_filter = mcp251xfd_remove_rx_filter, +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY + .recover = mcp251xfd_recover, +#endif + .get_state = mcp251xfd_get_state, + .set_state_change_callback = mcp251xfd_set_state_change_callback, + .get_core_clock = mcp251xfd_get_core_clock, + .get_max_filters = mcp251xfd_get_max_filters, + .get_max_bitrate = mcp251xfd_get_max_bitrate, + .timing_min = { + .sjw = 1, + .prop_seg = 0, + .phase_seg1 = 2, + .phase_seg2 = 1, + .prescaler = 1, + }, + .timing_max = { + .sjw = 128, + .prop_seg = 0, + .phase_seg1 = 256, + .phase_seg2 = 128, + .prescaler = 256, + }, +#if defined(CONFIG_CAN_FD_MODE) + .timing_data_min = { + .sjw = 1, + .prop_seg = 0, + .phase_seg1 = 1, + .phase_seg2 = 1, + .prescaler = 1, + }, + .timing_data_max = { + .sjw = 16, + .prop_seg = 0, + .phase_seg1 = 32, + .phase_seg2 = 16, + .prescaler = 256, + }, +#endif +}; + +#define MCP251XFD_SET_TIMING_MACRO(inst, type) \ + .timing_params##type = { \ + .sjw = DT_INST_PROP(inst, sjw##type), \ + .prop_seg = DT_INST_PROP_OR(inst, prop_seg##type, 0), \ + .phase_seg1 = DT_INST_PROP_OR(inst, phase_seg1##type, 0), \ + .phase_seg2 = DT_INST_PROP_OR(inst, phase_seg2##type, 0), \ + .bus_speed = DT_INST_PROP(inst, bus_speed##type), \ + .sample_point = DT_INST_PROP_OR(inst, sample_point##type, 0), \ + } + +#if defined(CONFIG_CAN_FD_MODE) +#define MCP251XFD_SET_TIMING(inst) \ + MCP251XFD_SET_TIMING_MACRO(inst,), \ + MCP251XFD_SET_TIMING_MACRO(inst, _data) +#else +#define MCP251XFD_SET_TIMING(inst) \ + MCP251XFD_SET_TIMING_MACRO(inst,) +#endif + +#define MCP251XFD_SET_CLOCK(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, clocks), \ + (.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clk_id = DT_INST_CLOCKS_CELL(inst, id)), \ + ()) + +#define MCP251XFD_INIT(inst) \ + static K_KERNEL_STACK_DEFINE(mcp251xfd_int_stack_##inst, \ + CONFIG_CAN_MCP251XFD_INT_THREAD_STACK_SIZE); \ + \ + static struct mcp251xfd_data mcp251xfd_data_##inst = { \ + .int_thread_stack = mcp251xfd_int_stack_##inst, \ + }; \ + static const struct mcp251xfd_config mcp251xfd_config_##inst = { \ + .bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ + .int_gpio_dt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + \ + .sof_on_clko = DT_INST_PROP(inst, sof_on_clko), \ + .clko_div = DT_INST_ENUM_IDX(inst, clko_div), \ + .pll_enable = DT_INST_PROP(inst, pll_enable), \ + .timestamp_prescaler = DT_INST_PROP(inst, timestamp_prescaler), \ + \ + .osc_freq = DT_INST_PROP(inst, osc_freq), \ + MCP251XFD_SET_TIMING(inst), \ + .phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, phys)), \ + .max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(inst, 8000000), \ + .rx_fifo = {.ram_start_addr = MCP251XFD_RX_FIFO_START_ADDR, \ + .reg_fifocon_addr = MCP251XFD_REG_FIFOCON(MCP251XFD_RX_FIFO_IDX), \ + .capacity = MCP251XFD_RX_FIFO_ITEMS, \ + .item_size = MCP251XFD_RX_FIFO_ITEM_SIZE, \ + .msg_handler = mcp251xfd_rx_fifo_handler}, \ + .tef_fifo = {.ram_start_addr = MCP251XFD_TEF_FIFO_START_ADDR, \ + .reg_fifocon_addr = MCP251XFD_REG_TEFCON, \ + .capacity = MCP251XFD_TEF_FIFO_ITEMS, \ + .item_size = MCP251XFD_TEF_FIFO_ITEM_SIZE, \ + .msg_handler = mcp251xfd_tef_fifo_handler}, \ + MCP251XFD_SET_CLOCK(inst) \ + }; \ + \ + CAN_DEVICE_DT_INST_DEFINE(inst, &mcp251xfd_init, NULL, &mcp251xfd_data_##inst, \ + &mcp251xfd_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &mcp251xfd_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(MCP251XFD_INIT) diff --git a/drivers/can/can_mcp251xfd.h b/drivers/can/can_mcp251xfd.h new file mode 100644 index 00000000000..f0414103bed --- /dev/null +++ b/drivers/can/can_mcp251xfd.h @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2020 Abram Early + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP251XFD_H_ +#define ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP251XFD_H_ + +#include + +#include +#include +#include + +#define MCP251XFD_UINT32_FLAG_TO_BYTE_MASK(flag_u32) \ + ((flag_u32) >> ROUND_DOWN(LOG2((flag_u32)), 8)) + +#define MCP251XFD_RAM_START_ADDR 0x400 +#define MCP251XFD_RAM_SIZE 2048 +#define MCP251XFD_RAM_ALIGNMENT 4 +#define MCP251XFD_PAYLOAD_SIZE CAN_MAX_DLEN + +#define MCP251XFD_FIFO_TYPE_TEF 0 +#define MCP251XFD_FIFO_TYPE_RX 1 + +#define MCP251XFD_TEF_FIFO_ITEM_SIZE 8 +#define MCP251XFD_TX_QUEUE_ITEM_SIZE (8 + MCP251XFD_PAYLOAD_SIZE) + +#if defined(CONFIG_CAN_RX_TIMESTAMP) +#define MCP251XFD_RX_FIFO_ITEM_SIZE (4 + 8 + MCP251XFD_PAYLOAD_SIZE) +#else +#define MCP251XFD_RX_FIFO_ITEM_SIZE (8 + MCP251XFD_PAYLOAD_SIZE) +#endif + +#define MCP251XFD_TEF_FIFO_START_ADDR 0 +#define MCP251XFD_TEF_FIFO_ITEMS CONFIG_CAN_MCP251XFD_MAX_TX_QUEUE +#define MCP251XFD_TEF_FIFO_SIZE (MCP251XFD_TEF_FIFO_ITEMS * MCP251XFD_TEF_FIFO_ITEM_SIZE) + +#define MCP251XFD_TX_QUEUE_START_ADDR MCP251XFD_TEF_FIFO_SIZE +#define MCP251XFD_TX_QUEUE_ITEMS CONFIG_CAN_MCP251XFD_MAX_TX_QUEUE +#define MCP251XFD_TX_QUEUE_SIZE (MCP251XFD_TX_QUEUE_ITEMS * MCP251XFD_TX_QUEUE_ITEM_SIZE) + +#define MCP251XFD_RX_FIFO_START_ADDR (MCP251XFD_TX_QUEUE_START_ADDR + MCP251XFD_TX_QUEUE_SIZE) +#define MCP251XFD_RX_FIFO_SIZE_MAX (MCP251XFD_RAM_SIZE - MCP251XFD_RX_FIFO_START_ADDR) +#define MCP251XFD_RX_FIFO_ITEMS_MAX (MCP251XFD_RX_FIFO_SIZE_MAX / MCP251XFD_RX_FIFO_ITEM_SIZE) + +#define MCP251XFD_RX_FIFO_ITEMS CONFIG_CAN_MCP251XFD_RX_FIFO_ITEMS +#define MCP251XFD_RX_FIFO_SIZE (MCP251XFD_RX_FIFO_ITEMS * MCP251XFD_RX_FIFO_ITEM_SIZE) + +#define MCP251XFD_RX_FIFO_IDX 1 +#define MCP251XFD_REG_SIZE 4 + +#define MCP251XFD_CRC_POLY 0x8005 +#define MCP251XFD_CRC_SEED 0xffff + +BUILD_ASSERT(MCP251XFD_TEF_FIFO_SIZE + MCP251XFD_TX_QUEUE_SIZE + + MCP251XFD_RX_FIFO_SIZE <= MCP251XFD_RAM_SIZE, + "Cannot fit FIFOs into RAM"); + +/* Timeout for changing mode */ +#define MCP251XFD_MODE_CHANGE_TIMEOUT_USEC 200000U +#define MCP251XFD_MODE_CHANGE_RETRIES 100 + +#define MCP251XFD_PLLRDY_TIMEOUT_USEC 100000 +#define MCP251XFD_PLLRDY_RETRIES 100 + +#define MCP251XFD_MAX_INT_HANDLER_CALLS 10 +#define MCP251XFD_INT_HANDLER_SLEEP_USEC 10000 + + +struct mcp251xfd_mailbox { + can_tx_callback_t cb; + void *cb_arg; +}; + +#define MCP251XFD_SPI_CMD_LEN 2 +#define MCP251XFD_SPI_LEN_FIELD_LEN 1 +#define MCP251XFD_SPI_CRC_LEN 2 + +/* MPC251x registers - mostly copied from Linux kernel implementation of driver */ + +/* CAN FD Controller Module SFR */ +#define MCP251XFD_REG_CON 0x00 +#define MCP251XFD_REG_CON_TXBWS_MASK GENMASK(31, 28) +#define MCP251XFD_REG_CON_ABAT BIT(27) +#define MCP251XFD_REG_CON_REQOP_MASK GENMASK(26, 24) +#define MCP251XFD_REG_CON_MODE_MIXED 0 +#define MCP251XFD_REG_CON_MODE_SLEEP 1 +#define MCP251XFD_REG_CON_MODE_INT_LOOPBACK 2 +#define MCP251XFD_REG_CON_MODE_LISTENONLY 3 +#define MCP251XFD_REG_CON_MODE_CONFIG 4 +#define MCP251XFD_REG_CON_MODE_EXT_LOOPBACK 5 +#define MCP251XFD_REG_CON_MODE_CAN2_0 6 +#define MCP251XFD_REG_CON_MODE_RESTRICTED 7 +#define MCP251XFD_REG_CON_OPMOD_MASK GENMASK(23, 21) +#define MCP251XFD_REG_CON_TXQEN BIT(20) +#define MCP251XFD_REG_CON_STEF BIT(19) +#define MCP251XFD_REG_CON_SERR2LOM BIT(18) +#define MCP251XFD_REG_CON_ESIGM BIT(17) +#define MCP251XFD_REG_CON_RTXAT BIT(16) +#define MCP251XFD_REG_CON_BRSDIS BIT(12) +#define MCP251XFD_REG_CON_BUSY BIT(11) +#define MCP251XFD_REG_CON_WFT_MASK GENMASK(10, 9) +#define MCP251XFD_REG_CON_WFT_T00FILTER 0x0 +#define MCP251XFD_REG_CON_WFT_T01FILTER 0x1 +#define MCP251XFD_REG_CON_WFT_T10FILTER 0x2 +#define MCP251XFD_REG_CON_WFT_T11FILTER 0x3 +#define MCP251XFD_REG_CON_WAKFIL BIT(8) +#define MCP251XFD_REG_CON_PXEDIS BIT(6) +#define MCP251XFD_REG_CON_ISOCRCEN BIT(5) +#define MCP251XFD_REG_CON_DNCNT_MASK GENMASK(4, 0) + +#define MCP251XFD_REG_CON_B2 (MCP251XFD_REG_CON + 2) +#define MCP251XFD_REG_CON_B3 (MCP251XFD_REG_CON + 3) + +#define MCP251XFD_REG_NBTCFG 0x04 +#define MCP251XFD_REG_NBTCFG_BRP_MASK GENMASK(31, 24) +#define MCP251XFD_REG_NBTCFG_TSEG1_MASK GENMASK(23, 16) +#define MCP251XFD_REG_NBTCFG_TSEG2_MASK GENMASK(14, 8) +#define MCP251XFD_REG_NBTCFG_SJW_MASK GENMASK(6, 0) + +#define MCP251XFD_REG_DBTCFG 0x08 +#define MCP251XFD_REG_DBTCFG_BRP_MASK GENMASK(31, 24) +#define MCP251XFD_REG_DBTCFG_TSEG1_MASK GENMASK(20, 16) +#define MCP251XFD_REG_DBTCFG_TSEG2_MASK GENMASK(11, 8) +#define MCP251XFD_REG_DBTCFG_SJW_MASK GENMASK(3, 0) + +#define MCP251XFD_REG_TDC 0x0c +#define MCP251XFD_REG_TDC_EDGFLTEN BIT(25) +#define MCP251XFD_REG_TDC_SID11EN BIT(24) +#define MCP251XFD_REG_TDC_TDCMOD_MASK GENMASK(17, 16) +#define MCP251XFD_REG_TDC_TDCMOD_AUTO 2 +#define MCP251XFD_REG_TDC_TDCMOD_MANUAL 1 +#define MCP251XFD_REG_TDC_TDCMOD_DISABLED 0 +#define MCP251XFD_REG_TDC_TDCO_MASK GENMASK(14, 8) +#define MCP251XFD_REG_TDC_TDCV_MASK GENMASK(5, 0) +#define MCP251XFD_REG_TDC_TDCO_MIN -64 +#define MCP251XFD_REG_TDC_TDCO_MAX 63 + +#define MCP251XFD_REG_TBC 0x10 + +#define MCP251XFD_REG_TSCON 0x14 +#define MCP251XFD_REG_TSCON_TSRES BIT(18) +#define MCP251XFD_REG_TSCON_TSEOF BIT(17) +#define MCP251XFD_REG_TSCON_TBCEN BIT(16) +#define MCP251XFD_REG_TSCON_TBCPRE_MASK GENMASK(9, 0) + +#define MCP251XFD_REG_VEC 0x18 +#define MCP251XFD_REG_VEC_RXCODE_MASK GENMASK(30, 24) +#define MCP251XFD_REG_VEC_TXCODE_MASK GENMASK(22, 16) +#define MCP251XFD_REG_VEC_FILHIT_MASK GENMASK(12, 8) +#define MCP251XFD_REG_VEC_ICODE_MASK GENMASK(6, 0) + +#define MCP251XFD_REG_INT 0x1c +#define MCP251XFD_REG_INT_IF_MASK GENMASK(15, 0) +#define MCP251XFD_REG_INT_IE_MASK GENMASK(31, 16) +#define MCP251XFD_REG_INT_IVMIE BIT(31) +#define MCP251XFD_REG_INT_WAKIE BIT(30) +#define MCP251XFD_REG_INT_CERRIE BIT(29) +#define MCP251XFD_REG_INT_SERRIE BIT(28) +#define MCP251XFD_REG_INT_RXOVIE BIT(27) +#define MCP251XFD_REG_INT_TXATIE BIT(26) +#define MCP251XFD_REG_INT_SPICRCIE BIT(25) +#define MCP251XFD_REG_INT_ECCIE BIT(24) +#define MCP251XFD_REG_INT_TEFIE BIT(20) +#define MCP251XFD_REG_INT_MODIE BIT(19) +#define MCP251XFD_REG_INT_TBCIE BIT(18) +#define MCP251XFD_REG_INT_RXIE BIT(17) +#define MCP251XFD_REG_INT_TXIE BIT(16) +#define MCP251XFD_REG_INT_IVMIF BIT(15) +#define MCP251XFD_REG_INT_WAKIF BIT(14) +#define MCP251XFD_REG_INT_CERRIF BIT(13) +#define MCP251XFD_REG_INT_SERRIF BIT(12) +#define MCP251XFD_REG_INT_RXOVIF BIT(11) +#define MCP251XFD_REG_INT_TXATIF BIT(10) +#define MCP251XFD_REG_INT_SPICRCIF BIT(9) +#define MCP251XFD_REG_INT_ECCIF BIT(8) +#define MCP251XFD_REG_INT_TEFIF BIT(4) +#define MCP251XFD_REG_INT_MODIF BIT(3) +#define MCP251XFD_REG_INT_TBCIF BIT(2) +#define MCP251XFD_REG_INT_RXIF BIT(1) +#define MCP251XFD_REG_INT_TXIF BIT(0) + +/* These IRQ flags must be cleared by SW in the CAN_INT register */ +#define MCP251XFD_REG_INT_IF_CLEARABLE_MASK \ + (MCP251XFD_REG_INT_IVMIF | MCP251XFD_REG_INT_WAKIF | MCP251XFD_REG_INT_CERRIF | \ + MCP251XFD_REG_INT_SERRIF | MCP251XFD_REG_INT_MODIF) + +#define MCP251XFD_REG_RXIF 0x20 +#define MCP251XFD_REG_TXIF 0x24 +#define MCP251XFD_REG_RXOVIF 0x28 +#define MCP251XFD_REG_TXATIF 0x2c +#define MCP251XFD_REG_TXREQ 0x30 + +#define MCP251XFD_REG_TREC 0x34 +#define MCP251XFD_REG_TREC_TXBO BIT(21) +#define MCP251XFD_REG_TREC_TXBP BIT(20) +#define MCP251XFD_REG_TREC_RXBP BIT(19) +#define MCP251XFD_REG_TREC_TXWARN BIT(18) +#define MCP251XFD_REG_TREC_RXWARN BIT(17) +#define MCP251XFD_REG_TREC_EWARN BIT(16) +#define MCP251XFD_REG_TREC_TEC_MASK GENMASK(15, 8) +#define MCP251XFD_REG_TREC_REC_MASK GENMASK(7, 0) + +#define MCP251XFD_REG_BDIAG0 0x38 +#define MCP251XFD_REG_BDIAG0_DTERRCNT_MASK GENMASK(31, 24) +#define MCP251XFD_REG_BDIAG0_DRERRCNT_MASK GENMASK(23, 16) +#define MCP251XFD_REG_BDIAG0_NTERRCNT_MASK GENMASK(15, 8) +#define MCP251XFD_REG_BDIAG0_NRERRCNT_MASK GENMASK(7, 0) + +#define MCP251XFD_REG_BDIAG1 0x3c +#define MCP251XFD_REG_BDIAG1_DLCMM BIT(31) +#define MCP251XFD_REG_BDIAG1_ESI BIT(30) +#define MCP251XFD_REG_BDIAG1_DCRCERR BIT(29) +#define MCP251XFD_REG_BDIAG1_DSTUFERR BIT(28) +#define MCP251XFD_REG_BDIAG1_DFORMERR BIT(27) +#define MCP251XFD_REG_BDIAG1_DBIT1ERR BIT(25) +#define MCP251XFD_REG_BDIAG1_DBIT0ERR BIT(24) +#define MCP251XFD_REG_BDIAG1_TXBOERR BIT(23) +#define MCP251XFD_REG_BDIAG1_NCRCERR BIT(21) +#define MCP251XFD_REG_BDIAG1_NSTUFERR BIT(20) +#define MCP251XFD_REG_BDIAG1_NFORMERR BIT(19) +#define MCP251XFD_REG_BDIAG1_NACKERR BIT(18) +#define MCP251XFD_REG_BDIAG1_NBIT1ERR BIT(17) +#define MCP251XFD_REG_BDIAG1_NBIT0ERR BIT(16) +#define MCP251XFD_REG_BDIAG1_BERR_MASK \ + (MCP251XFD_REG_BDIAG1_DLCMM | MCP251XFD_REG_BDIAG1_ESI | MCP251XFD_REG_BDIAG1_DCRCERR | \ + MCP251XFD_REG_BDIAG1_DSTUFERR | MCP251XFD_REG_BDIAG1_DFORMERR | \ + MCP251XFD_REG_BDIAG1_DBIT1ERR | MCP251XFD_REG_BDIAG1_DBIT0ERR | \ + MCP251XFD_REG_BDIAG1_TXBOERR | MCP251XFD_REG_BDIAG1_NCRCERR | \ + MCP251XFD_REG_BDIAG1_NSTUFERR | MCP251XFD_REG_BDIAG1_NFORMERR | \ + MCP251XFD_REG_BDIAG1_NACKERR | MCP251XFD_REG_BDIAG1_NBIT1ERR | \ + MCP251XFD_REG_BDIAG1_NBIT0ERR) +#define MCP251XFD_REG_BDIAG1_EFMSGCNT_MASK GENMASK(15, 0) + +#define MCP251XFD_REG_TEFCON 0x40 +#define MCP251XFD_REG_TEFCON_FSIZE_MASK GENMASK(28, 24) +#define MCP251XFD_REG_TEFCON_FRESET BIT(10) +#define MCP251XFD_REG_TEFCON_UINC BIT(8) +#define MCP251XFD_REG_TEFCON_TEFTSEN BIT(5) +#define MCP251XFD_REG_TEFCON_TEFOVIE BIT(3) +#define MCP251XFD_REG_TEFCON_TEFFIE BIT(2) +#define MCP251XFD_REG_TEFCON_TEFHIE BIT(1) +#define MCP251XFD_REG_TEFCON_TEFNEIE BIT(0) + +#define MCP251XFD_REG_TEFSTA 0x44 +#define MCP251XFD_REG_TEFSTA_TEFOVIF BIT(3) +#define MCP251XFD_REG_TEFSTA_TEFFIF BIT(2) +#define MCP251XFD_REG_TEFSTA_TEFHIF BIT(1) +#define MCP251XFD_REG_TEFSTA_TEFNEIF BIT(0) + +#define MCP251XFD_REG_TEFUA 0x48 + +#define MCP251XFD_REG_TXQCON 0x50 +#define MCP251XFD_REG_TXQCON_PLSIZE_MASK GENMASK(31, 29) +#define MCP251XFD_REG_TXQCON_PLSIZE_8 0 +#define MCP251XFD_REG_TXQCON_PLSIZE_12 1 +#define MCP251XFD_REG_TXQCON_PLSIZE_16 2 +#define MCP251XFD_REG_TXQCON_PLSIZE_20 3 +#define MCP251XFD_REG_TXQCON_PLSIZE_24 4 +#define MCP251XFD_REG_TXQCON_PLSIZE_32 5 +#define MCP251XFD_REG_TXQCON_PLSIZE_48 6 +#define MCP251XFD_REG_TXQCON_PLSIZE_64 7 +#define MCP251XFD_REG_TXQCON_FSIZE_MASK GENMASK(28, 24) +#define MCP251XFD_REG_TXQCON_TXAT_UNLIMITED 3 +#define MCP251XFD_REG_TXQCON_TXAT_THREE_SHOT 1 +#define MCP251XFD_REG_TXQCON_TXAT_ONE_SHOT 0 +#define MCP251XFD_REG_TXQCON_TXAT_MASK GENMASK(22, 21) +#define MCP251XFD_REG_TXQCON_TXPRI_MASK GENMASK(20, 16) +#define MCP251XFD_REG_TXQCON_FRESET BIT(10) +#define MCP251XFD_REG_TXQCON_TXREQ BIT(9) +#define MCP251XFD_REG_TXQCON_UINC BIT(8) +#define MCP251XFD_REG_TXQCON_TXEN BIT(7) +#define MCP251XFD_REG_TXQCON_TXATIE BIT(4) +#define MCP251XFD_REG_TXQCON_TXQEIE BIT(2) +#define MCP251XFD_REG_TXQCON_TXQNIE BIT(0) + +#define MCP251XFD_REG_TXQSTA 0x54 +#define MCP251XFD_REG_TXQSTA_TXQCI_MASK GENMASK(12, 8) +#define MCP251XFD_REG_TXQSTA_TXABT BIT(7) +#define MCP251XFD_REG_TXQSTA_TXLARB BIT(6) +#define MCP251XFD_REG_TXQSTA_TXERR BIT(5) +#define MCP251XFD_REG_TXQSTA_TXATIF BIT(4) +#define MCP251XFD_REG_TXQSTA_TXQEIF BIT(2) +#define MCP251XFD_REG_TXQSTA_TXQNIF BIT(0) + +#define MCP251XFD_REG_TXQUA 0x58 + +#define MCP251XFD_REG_FIFOCON(x) (0x50 + 0xc * (x)) +#define MCP251XFD_REG_FIFOCON_PLSIZE_MASK GENMASK(31, 29) +#define MCP251XFD_REG_FIFOCON_PLSIZE_8 0 +#define MCP251XFD_REG_FIFOCON_PLSIZE_12 1 +#define MCP251XFD_REG_FIFOCON_PLSIZE_16 2 +#define MCP251XFD_REG_FIFOCON_PLSIZE_20 3 +#define MCP251XFD_REG_FIFOCON_PLSIZE_24 4 +#define MCP251XFD_REG_FIFOCON_PLSIZE_32 5 +#define MCP251XFD_REG_FIFOCON_PLSIZE_48 6 +#define MCP251XFD_REG_FIFOCON_PLSIZE_64 7 +#define MCP251XFD_REG_FIFOCON_FSIZE_MASK GENMASK(28, 24) +#define MCP251XFD_REG_FIFOCON_TXAT_MASK GENMASK(22, 21) +#define MCP251XFD_REG_FIFOCON_TXAT_ONE_SHOT 0 +#define MCP251XFD_REG_FIFOCON_TXAT_THREE_SHOT 1 +#define MCP251XFD_REG_FIFOCON_TXAT_UNLIMITED 3 +#define MCP251XFD_REG_FIFOCON_TXPRI_MASK GENMASK(20, 16) +#define MCP251XFD_REG_FIFOCON_FRESET BIT(10) +#define MCP251XFD_REG_FIFOCON_TXREQ BIT(9) +#define MCP251XFD_REG_FIFOCON_UINC BIT(8) +#define MCP251XFD_REG_FIFOCON_TXEN BIT(7) +#define MCP251XFD_REG_FIFOCON_RTREN BIT(6) +#define MCP251XFD_REG_FIFOCON_RXTSEN BIT(5) +#define MCP251XFD_REG_FIFOCON_TXATIE BIT(4) +#define MCP251XFD_REG_FIFOCON_RXOVIE BIT(3) +#define MCP251XFD_REG_FIFOCON_TFERFFIE BIT(2) +#define MCP251XFD_REG_FIFOCON_TFHRFHIE BIT(1) +#define MCP251XFD_REG_FIFOCON_TFNRFNIE BIT(0) + +#define MCP251XFD_REG_FIFOSTA(x) (0x54 + 0xc * (x)) +#define MCP251XFD_REG_FIFOSTA_FIFOCI_MASK GENMASK(12, 8) +#define MCP251XFD_REG_FIFOSTA_TXABT BIT(7) +#define MCP251XFD_REG_FIFOSTA_TXLARB BIT(6) +#define MCP251XFD_REG_FIFOSTA_TXERR BIT(5) +#define MCP251XFD_REG_FIFOSTA_TXATIF BIT(4) +#define MCP251XFD_REG_FIFOSTA_RXOVIF BIT(3) +#define MCP251XFD_REG_FIFOSTA_TFERFFIF BIT(2) +#define MCP251XFD_REG_FIFOSTA_TFHRFHIF BIT(1) +#define MCP251XFD_REG_FIFOSTA_TFNRFNIF BIT(0) + +#define MCP251XFD_REG_FIFOUA(x) (0x58 + 0xc * (x)) + +#define MCP251XFD_REG_BYTE_FLTCON(m) (0x1d0 + m) +#define MCP251XFD_REG_BYTE_FLTCON_FBP_MASK GENMASK(4, 0) +#define MCP251XFD_REG_BYTE_FLTCON_FLTEN BIT(7) + +#define MCP251XFD_REG_FLTOBJ(x) (0x1f0 + 0x8 * (x)) +#define MCP251XFD_REG_FLTOBJ_EXIDE BIT(30) +#define MCP251XFD_REG_FLTOBJ_SID11 BIT(29) +#define MCP251XFD_REG_FLTOBJ_EID_MASK GENMASK(28, 11) +#define MCP251XFD_REG_FLTOBJ_SID_MASK GENMASK(10, 0) + +#define MCP251XFD_REG_FLTMASK(x) (0x1f4 + 0x8 * (x)) +#define MCP251XFD_REG_MASK_MIDE BIT(30) +#define MCP251XFD_REG_MASK_MSID11 BIT(29) +#define MCP251XFD_REG_MASK_MEID_MASK GENMASK(28, 11) +#define MCP251XFD_REG_MASK_MSID_MASK GENMASK(10, 0) + +/* Message Object */ +#define MCP251XFD_OBJ_ID_SID11 BIT(29) +#define MCP251XFD_OBJ_ID_EID_MASK GENMASK(28, 11) +#define MCP251XFD_OBJ_ID_SID_MASK GENMASK(10, 0) +#define MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK GENMASK(31, 9) +#define MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK GENMASK(15, 9) +#define MCP251XFD_OBJ_FLAGS_SEQ_MASK MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK +#define MCP251XFD_OBJ_FLAGS_ESI BIT(8) +#define MCP251XFD_OBJ_FLAGS_FDF BIT(7) +#define MCP251XFD_OBJ_FLAGS_BRS BIT(6) +#define MCP251XFD_OBJ_FLAGS_RTR BIT(5) +#define MCP251XFD_OBJ_FLAGS_IDE BIT(4) +#define MCP251XFD_OBJ_FLAGS_DLC_MASK GENMASK(3, 0) +#define MCP251XFD_OBJ_FILHIT_MASK GENMASK(15, 11) + +#define MCP251XFD_OBJ_DATA_OFFSET 2 /* offset to the data in sizeof(uint32_t) */ +#define MCP251XFD_OBJ_HEADER_SIZE (MCP251XFD_OBJ_DATA_OFFSET * MCP251XFD_REG_SIZE) + +#define MCP251XFD_REG_FRAME_EFF_SID_MASK GENMASK(28, 18) +#define MCP251XFD_REG_FRAME_EFF_EID_MASK GENMASK(17, 0) + +/* MCP2517/18FD SFR */ +#define MCP251XFD_REG_OSC 0xe00 +#define MCP251XFD_REG_OSC_SCLKRDY BIT(12) +#define MCP251XFD_REG_OSC_OSCRDY BIT(10) +#define MCP251XFD_REG_OSC_PLLRDY BIT(8) +#define MCP251XFD_REG_OSC_CLKODIV_10 3 +#define MCP251XFD_REG_OSC_CLKODIV_4 2 +#define MCP251XFD_REG_OSC_CLKODIV_2 1 +#define MCP251XFD_REG_OSC_CLKODIV_1 0 +#define MCP251XFD_REG_OSC_CLKODIV_MASK GENMASK(6, 5) +#define MCP251XFD_REG_OSC_SCLKDIV BIT(4) +#define MCP251XFD_REG_OSC_LPMEN BIT(3) /* MCP2518FD only */ +#define MCP251XFD_REG_OSC_OSCDIS BIT(2) +#define MCP251XFD_REG_OSC_PLLEN BIT(0) + +#define MCP251XFD_REG_IOCON 0xe04 +#define MCP251XFD_REG_IOCON_INTOD BIT(30) +#define MCP251XFD_REG_IOCON_SOF BIT(29) +#define MCP251XFD_REG_IOCON_TXCANOD BIT(28) +#define MCP251XFD_REG_IOCON_PM1 BIT(25) +#define MCP251XFD_REG_IOCON_PM0 BIT(24) +#define MCP251XFD_REG_IOCON_GPIO1 BIT(17) +#define MCP251XFD_REG_IOCON_GPIO0 BIT(16) +#define MCP251XFD_REG_IOCON_LAT1 BIT(9) +#define MCP251XFD_REG_IOCON_LAT0 BIT(8) +#define MCP251XFD_REG_IOCON_XSTBYEN BIT(6) +#define MCP251XFD_REG_IOCON_TRIS1 BIT(1) +#define MCP251XFD_REG_IOCON_TRIS0 BIT(0) + +#define MCP251XFD_REG_CRC 0xe08 +#define MCP251XFD_REG_CRC_FERRIE BIT(25) +#define MCP251XFD_REG_CRC_CRCERRIE BIT(24) +#define MCP251XFD_REG_CRC_FERRIF BIT(17) +#define MCP251XFD_REG_CRC_CRCERRIF BIT(16) +#define MCP251XFD_REG_CRC_IF_MASK GENMASK(17, 16) +#define MCP251XFD_REG_CRC_MASK GENMASK(15, 0) + +#define MCP251XFD_REG_ECCCON 0xe0c +#define MCP251XFD_REG_ECCCON_PARITY_MASK GENMASK(14, 8) +#define MCP251XFD_REG_ECCCON_DEDIE BIT(2) +#define MCP251XFD_REG_ECCCON_SECIE BIT(1) +#define MCP251XFD_REG_ECCCON_ECCEN BIT(0) + +#define MCP251XFD_REG_ECCSTAT 0xe10 +#define MCP251XFD_REG_ECCSTAT_ERRADDR_MASK GENMASK(27, 16) +#define MCP251XFD_REG_ECCSTAT_IF_MASK GENMASK(2, 1) +#define MCP251XFD_REG_ECCSTAT_DEDIF BIT(2) +#define MCP251XFD_REG_ECCSTAT_SECIF BIT(1) + +#define MCP251XFD_REG_DEVID 0xe14 /* MCP2518FD only */ +#define MCP251XFD_REG_DEVID_ID_MASK GENMASK(7, 4) +#define MCP251XFD_REG_DEVID_REV_MASK GENMASK(3, 0) + +/* SPI commands */ +#define MCP251XFD_SPI_INSTRUCTION_RESET 0x0000 +#define MCP251XFD_SPI_INSTRUCTION_WRITE 0x2000 +#define MCP251XFD_SPI_INSTRUCTION_READ 0x3000 +#define MCP251XFD_SPI_INSTRUCTION_WRITE_CRC 0xa000 +#define MCP251XFD_SPI_INSTRUCTION_READ_CRC 0xb000 +#define MCP251XFD_SPI_INSTRUCTION_WRITE_CRC_SAFE 0xc000 +#define MCP251XFD_SPI_ADDRESS_MASK GENMASK(11, 0) + +#define MCP251XFD_REG_FIFOCON_TO_STA(addr) (addr + 0x4) + +#define MCP251XFD_REG_FLTCON(m) (0x1d0 + m) + +struct mcp251xfd_txobj { + uint32_t id; + uint32_t flags; + uint8_t data[CAN_MAX_DLEN]; +} __packed; + +struct mcp251xfd_rxobj { + uint32_t id; + uint32_t flags; +#if defined(CONFIG_CAN_RX_TIMESTAMP) + uint32_t timestamp; +#endif + uint8_t data[CAN_MAX_DLEN]; +} __packed; + +struct mcp251xfd_tefobj { + uint32_t id; + uint32_t flags; +} __packed; + +#define MCP251XFD_MAX_READ_FIFO_BUF_SIZE \ + MAX((MCP251XFD_RX_FIFO_ITEM_SIZE * MCP251XFD_RX_FIFO_ITEMS), \ + (MCP251XFD_TEF_FIFO_ITEM_SIZE * MCP251XFD_TEF_FIFO_ITEMS)) + +#define MCP251XFD_MAX_READ_CRC_BUF_SIZE \ + (MCP251XFD_SPI_CRC_LEN + 2 * MCP251XFD_REG_SIZE) + +#define MCP251XFD_SPI_BUF_SIZE \ + MAX(MCP251XFD_MAX_READ_FIFO_BUF_SIZE, MCP251XFD_MAX_READ_CRC_BUF_SIZE) +#define MCP251XFD_SPI_HEADER_LEN (MCP251XFD_SPI_CMD_LEN + MCP251XFD_SPI_LEN_FIELD_LEN) + +struct mcp251xfd_spi_data { + uint8_t _unused[4 - (MCP251XFD_SPI_HEADER_LEN % 4)]; /* so that buf is 4-byte aligned */ + uint8_t header[MCP251XFD_SPI_HEADER_LEN]; /* contains spi_cmd and length field (if used) */ + uint8_t buf[MCP251XFD_SPI_BUF_SIZE]; +} __packed __aligned(4); + +struct mcp251xfd_fifo { + uint32_t ram_start_addr; + uint16_t reg_fifocon_addr; + uint8_t capacity; + uint8_t item_size; + void (*msg_handler)(const struct device *dev, void *data); +}; + +struct mcp251xfd_data { + /* Interrupt Data */ + struct gpio_callback int_gpio_cb; + struct k_thread int_thread; + k_thread_stack_t *int_thread_stack; + struct k_sem int_sem; + + /* General */ + enum can_state state; + can_state_change_callback_t state_change_cb; + void *state_change_cb_data; + struct k_mutex mutex; + + /* TX Callback */ + struct k_sem tx_sem; + uint32_t mailbox_usage; + struct mcp251xfd_mailbox mailbox[CONFIG_CAN_MCP251XFD_MAX_TX_QUEUE]; + + /* Filter Data */ + uint64_t filter_usage; + struct can_filter filter[CONFIG_CAN_MAX_FILTER]; + can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; + void *cb_arg[CONFIG_CAN_MAX_FILTER]; + + const struct device *dev; + + bool started; + uint8_t next_mcp251xfd_mode; + uint8_t current_mcp251xfd_mode; + int tdco; + + can_mode_t mode; + + struct mcp251xfd_spi_data spi_data; + +}; + +struct mcp251xfd_timing_params { + uint8_t sjw; + uint8_t prop_seg; + uint8_t phase_seg1; + uint8_t phase_seg2; + uint32_t bus_speed; + uint16_t sample_point; +}; + +struct mcp251xfd_config { + /* spi configuration */ + struct spi_dt_spec bus; + struct gpio_dt_spec int_gpio_dt; + + uint32_t osc_freq; + + /* IO Config */ + bool sof_on_clko; + bool pll_enable; + uint8_t clko_div; + + uint16_t timestamp_prescaler; + + /* CAN Timing */ + struct mcp251xfd_timing_params timing_params; +#if defined(CONFIG_CAN_FD_MODE) + struct mcp251xfd_timing_params timing_params_data; +#endif + + /* CAN transceiver */ + const struct device *phy; + uint32_t max_bitrate; + + const struct device *clk_dev; + uint8_t clk_id; + + struct mcp251xfd_fifo rx_fifo; + struct mcp251xfd_fifo tef_fifo; +}; + +#endif /* ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP251XFD_H_ */ diff --git a/drivers/can/can_mcp25xxfd.c b/drivers/can/can_mcp25xxfd.c deleted file mode 100644 index 30b48495e62..00000000000 --- a/drivers/can/can_mcp25xxfd.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * Copyright (c) 2020 Abram Early - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT microchip_mcp25xxfd - -#include -#include -#include -#include - -#define LOG_LEVEL CONFIG_CAN_LOG_LEVEL -#include -LOG_MODULE_REGISTER(mcp25xxfd_can); - -#include "can_mcp25xxfd.h" - -#define SP_IS_SET(inst) DT_INST_NODE_HAS_PROP(inst, sample_point) || - -/* Macro to exclude the sample point algorithm from compilation if not used - * Without the macro, the algorithm would always waste ROM - */ -#define USE_SP_ALGO (DT_INST_FOREACH_STATUS_OKAY(SP_IS_SET) 0) - -static int mcp25xxfd_reset(const struct device *dev) -{ - uint8_t cmd_buf[] = { 0x00, 0x00 }; - const struct spi_buf tx_buf = { - .buf = cmd_buf, - .len = sizeof(cmd_buf), - }; - const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1U }; - - return spi_write(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, &tx); -} - -static int mcp25xxfd_read(const struct device *dev, uint16_t address, void *rxd, - uint8_t rx_len) -{ - __ASSERT(address < 0x400 || address >= 0xC00 || - (address % 4 == 0 && rx_len % 4 == 0), - "Address and Length must be word aligned in RAM"); - uint8_t cmd_buf[2 + rx_len]; - - cmd_buf[0] = (MCP25XXFD_OPCODE_READ << 4) + ((address >> 8) & 0x0F); - cmd_buf[1] = address & 0xFF; - const struct spi_buf tx_buf[] = { - { .buf = cmd_buf, .len = sizeof(cmd_buf) }, - }; - const struct spi_buf rx_buf[] = { - { .buf = cmd_buf, .len = sizeof(cmd_buf) }, - }; - const struct spi_buf_set tx = { .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf) }; - const struct spi_buf_set rx = { .buffers = rx_buf, - .count = ARRAY_SIZE(rx_buf) }; - int ret; - - ret = spi_transceive(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, - &tx, &rx); - memcpy(rxd, &cmd_buf[2], rx_len); - if (ret < 0) { - LOG_ERR("Failed to read %d bytes from 0x%03x", rx_len, address); - } - return ret; -} - -static int mcp25xxfd_write(const struct device *dev, uint16_t address, - void *txd, uint8_t tx_len) -{ - __ASSERT(address < 0x400 || address >= 0xC00 || - (address % 4 == 0 && tx_len % 4 == 0), - "Address and Length must be word aligned in RAM"); - uint8_t cmd_buf[2 + tx_len]; - - cmd_buf[0] = (MCP25XXFD_OPCODE_WRITE << 4) + - ((address >> 8) & 0xF); - cmd_buf[1] = address & 0xFF; - const struct spi_buf tx_buf[] = { - { .buf = cmd_buf, .len = sizeof(cmd_buf) }, - }; - const struct spi_buf_set tx = { .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf) }; - int ret; - - memcpy(&cmd_buf[2], txd, tx_len); - ret = spi_write(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg, &tx); - if (ret < 0) { - LOG_ERR("Failed to write %d bytes to 0x%03x", tx_len, address); - } - return ret; -} - -static inline int mcp25xxfd_readb(const struct device *dev, uint16_t address, - void *rxd) -{ - return mcp25xxfd_read(dev, address, rxd, 1); -} - -static inline int mcp25xxfd_writeb(const struct device *dev, uint16_t address, - void *txd) -{ - return mcp25xxfd_write(dev, address, txd, 1); -} - -static inline int mcp25xxfd_readw(const struct device *dev, uint16_t address, - void *rxd) -{ - return mcp25xxfd_read(dev, address, rxd, 4); -} - -static inline int mcp25xxfd_writew(const struct device *dev, uint16_t address, - void *txd) -{ - return mcp25xxfd_write(dev, address, txd, 4); -} - -static int mcp25xxfd_fifo_read(const struct device *dev, uint16_t fifo_address, - void *rxd, uint8_t rx_len) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_fifo fiforegs; - int ret; - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - ret = mcp25xxfd_read(dev, fifo_address, &fiforegs, sizeof(fiforegs)); - if (ret < 0) { - goto done; - } - - if (!fiforegs.sta.FNEIF) { - ret = -ENODATA; - goto done; - } - - ret = mcp25xxfd_read(dev, 0x400 + fiforegs.ua, rxd, rx_len); - if (ret < 0) { - goto done; - } - - fiforegs.con.UINC = 1; - ret = mcp25xxfd_writeb(dev, fifo_address + 1, &fiforegs.con.bytes[1]); - -done: - k_mutex_unlock(&dev_data->mutex); - return ret; -} - -static int mcp25xxfd_fifo_write(const struct device *dev, uint16_t fifo_address, - void *txd, uint8_t tx_len) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_fifo fiforegs; - int ret; - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - ret = mcp25xxfd_read(dev, fifo_address, &fiforegs, sizeof(fiforegs)); - if (ret < 0) { - goto done; - } - - if (!fiforegs.sta.FNEIF) { - ret = -ENOMEM; - goto done; - } - - ret = mcp25xxfd_write(dev, 0x400 + fiforegs.ua, txd, tx_len); - if (ret < 0) { - goto done; - } - - fiforegs.con.UINC = 1; - fiforegs.con.TXREQ = 1; - ret = mcp25xxfd_writeb(dev, fifo_address + 1, &fiforegs.con.bytes[1]); - -done: - k_mutex_unlock(&dev_data->mutex); - return ret; -} - -static void mcp25xxfd_zcanframe_to_txobj(const struct zcan_frame *src, - struct mcp25xxfd_txobj *dst) -{ - memset(dst, 0, offsetof(struct mcp25xxfd_txobj, DATA)); - - if (src->id_type == CAN_STANDARD_IDENTIFIER) { - dst->SID = src->id; - } else { - dst->SID = src->id >> 18; - dst->EID = src->id; - dst->IDE = 1; - } - dst->BRS = src->brs; - dst->RTR = src->rtr == CAN_REMOTEREQUEST; - dst->DLC = src->dlc; -#if defined(CONFIG_CAN_FD_MODE) - dst->FDF = src->fd; -#endif - - memcpy(dst->DATA, src->data, MIN(can_dlc_to_bytes(src->dlc), CAN_MAX_DLEN)); -} - -static void mcp25xxfd_rxobj_to_zcanframe(const struct mcp25xxfd_rxobj *src, - struct zcan_frame *dst) -{ - memset(dst, 0, offsetof(struct zcan_frame, data)); - - if (src->IDE) { - dst->id = src->EID | (src->SID << 18); - dst->id_type = CAN_EXTENDED_IDENTIFIER; - } else { - dst->id = src->SID; - dst->id_type = CAN_STANDARD_IDENTIFIER; - } - dst->brs = src->BRS; - dst->rtr = src->RTR; - dst->dlc = src->DLC; -#if defined(CONFIG_CAN_FD_MODE) - dst->fd = src->FDF; -#endif -#if defined(CONFIG_CAN_RX_TIMESTAMP) - dst->timestamp = src->RXMSGTS; -#endif - - memcpy(dst->data, src->DATA, MIN(can_dlc_to_bytes(src->DLC), CAN_MAX_DLEN)); -} - -static int mcp25xxfd_get_raw_mode(const struct device *dev, uint8_t *mode) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_con con; - int ret; - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - ret = mcp25xxfd_readb(dev, MCP25XXFD_REG_CON + 2, &con.byte[2]); - k_mutex_unlock(&dev_data->mutex); - *mode = con.OPMOD; - return ret; -} - -static int mcp25xxfd_set_raw_mode(const struct device *dev, uint8_t mode) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_con con; - int ret; - - while (true) { - k_mutex_lock(&dev_data->mutex, K_FOREVER); - ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_CON, &con); - if (ret < 0 || con.OPMOD == mode) { - k_mutex_unlock(&dev_data->mutex); - break; - } - - if (con.OPMOD == MCP25XXFD_OPMODE_CONFIGURATION) { - /* Configuration mode can be switched to any other mode */ - con.REQMOD = mode; - } else if (con.OPMOD == MCP25XXFD_OPMODE_NORMAL_CANFD || - con.OPMOD == MCP25XXFD_OPMODE_NORMAL_CAN2) { - /* Normal modes can only be directly switched to Sleep, Restricted, or Listen-Only modes */ - if (mode == MCP25XXFD_OPMODE_SLEEP || - mode == MCP25XXFD_OPMODE_RESTRICTED || - mode == MCP25XXFD_OPMODE_LISTEN_ONLY) { - con.REQMOD = mode; - } else { - con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; - } - } else if (con.OPMOD == MCP25XXFD_OPMODE_LISTEN_ONLY) { - /* Listen-Only mode can be directly switched back to normal modes */ - if (mode == MCP25XXFD_OPMODE_NORMAL_CANFD || - mode == MCP25XXFD_OPMODE_NORMAL_CAN2) { - con.REQMOD = mode; - } else { - con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; - } - } else { - /* Otherwise, the device must be put into configuration mode first */ - con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; - } - - LOG_DBG("OPMOD: #%d, REQMOD #%d", con.OPMOD, con.REQMOD); - ret = mcp25xxfd_writeb(dev, MCP25XXFD_REG_CON + 3, - &con.byte[3]); - k_mutex_unlock(&dev_data->mutex); - if (ret < 0) { - break; - } - - ret = k_sem_take(&dev_data->mode_sem, K_MSEC(2)); - if (ret == -EAGAIN) { - return CAN_TIMEOUT; - } - } - return ret; -} - -static int mcp25xxfd_set_mode(const struct device *dev, enum can_mode mode) -{ - switch (mode) { - case CAN_NORMAL_MODE: -#if defined(CONFIG_CAN_FD_MODE) - return mcp25xxfd_set_raw_mode(dev, - MCP25XXFD_OPMODE_NORMAL_CANFD); -#else - return mcp25xxfd_set_raw_mode(dev, - MCP25XXFD_OPMODE_NORMAL_CAN2); -#endif - case CAN_LOOPBACK_MODE: - return mcp25xxfd_set_raw_mode(dev, - MCP25XXFD_OPMODE_EXT_LOOPBACK); - default: - LOG_ERR("Unsupported CAN Mode %u", mode); - case CAN_SILENT_MODE: - return mcp25xxfd_set_raw_mode(dev, - MCP25XXFD_OPMODE_LISTEN_ONLY); - } -} - -static int mcp25xxfd_set_timing(const struct device *dev, - const struct can_timing *timing, - const struct can_timing *timing_data) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - uint8_t mode; - int ret; - -#if defined(CONFIG_CAN_FD_MODE) - if (!timing || !timing_data) { -#else - if (!timing) { -#endif - return -EINVAL; - } - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - ret = mcp25xxfd_get_raw_mode(dev, &mode); - if (ret < 0) { - goto done; - } - ret = mcp25xxfd_set_raw_mode(dev, MCP25XXFD_OPMODE_CONFIGURATION); - if (ret < 0) { - goto done; - } - - union mcp25xxfd_nbtcfg nbtcfg = { - .BRP = timing->prescaler - 1, - .TSEG1 = (timing->prop_seg + timing->phase_seg1) - 1, - .TSEG2 = timing->phase_seg2 - 1, - .SJW = timing->sjw - 1, - }; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_NBTCFG, nbtcfg.byte); - if (ret < 0) { - LOG_ERR("Failed to write device configuration [%d]", ret); - goto done; - } - -#if defined(CONFIG_CAN_FD_MODE) - union mcp25xxfd_dbtcfg ndtcfg = { - .BRP = timing_data->prescaler - 1, - .TSEG1 = (timing_data->prop_seg + timing_data->phase_seg1) - 1, - .TSEG2 = timing_data->phase_seg2 - 1, - .SJW = timing_data->sjw - 1, - }; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_DBTCFG, ndtcfg.byte); - if (ret < 0) { - LOG_ERR("Failed to write device configuration [%d]", ret); - goto done; - } -#endif - - union mcp25xxfd_tdc tdc = { - .EDGFLTEN = 0, - .SID11EN = 0, -#if defined(CONFIG_CAN_FD_MODE) - .TDCMOD = MCP25XXFD_TDCMOD_AUTO, - .TDCO = timing_data->prescaler * - (timing_data->prop_seg + timing_data->phase_seg1), -#else - .TDCMOD = MCP25XXFD_TDCMOD_DISABLED, -#endif - }; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TDC, &tdc); - if (ret < 0) { - LOG_ERR("Failed to write device configuration [%d]", ret); - goto done; - } - -#if defined(CONFIG_CAN_RX_TIMESTAMP) - union mcp25xxfd_tscon tscon = { - .TBCEN = 1, - .TSRES = 0, - .TSEOF = 0, - .TBCPRE = timing->prescaler - 1, - }; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TSCON, &tscon); - if (ret < 0) { - LOG_ERR("Failed to write device configuration [%d]", ret); - goto done; - } -#endif - - ret = mcp25xxfd_set_raw_mode(dev, mode); - if (ret < 0) { - goto done; - } - -done: - k_mutex_unlock(&dev_data->mutex); - - return ret; -} - -static int mcp25xxfd_send(const struct device *dev, - const struct zcan_frame *msg, k_timeout_t timeout, - can_tx_callback_t callback, void *callback_arg) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - struct mcp25xxfd_txobj tx_frame; - uint8_t mailbox_idx = 0; - int ret; - - LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s", - can_dlc_to_bytes(msg->dlc), msg->id, - msg->id_type == CAN_STANDARD_IDENTIFIER ? - "standard" : "extended", - msg->rtr == CAN_DATAFRAME ? "" : "RTR", - msg->fd == CAN_DATAFRAME ? "" : "FD frame", - msg->brs == CAN_DATAFRAME ? "" : "BRS"); - - if (msg->fd != 1 && msg->dlc > CAN_MAX_DLC) { - LOG_ERR("DLC of %d without fd flag set.", msg->dlc); - return CAN_TX_EINVAL; - } - - if (k_sem_take(&dev_data->tx_sem, timeout) != 0) { - return CAN_TIMEOUT; - } - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - for (; mailbox_idx < MCP25XXFD_TXFIFOS; mailbox_idx++) { - if ((BIT(mailbox_idx) & dev_data->mailbox_usage) == 0) { - dev_data->mailbox_usage |= BIT(mailbox_idx); - break; - } - } - k_mutex_unlock(&dev_data->mutex); - - if (mailbox_idx >= MCP25XXFD_TXFIFOS) { - k_sem_give(&dev_data->tx_sem); - return CAN_TX_ERR; - } - - dev_data->mailbox[mailbox_idx].cb = callback; - dev_data->mailbox[mailbox_idx].cb_arg = callback_arg; - - mcp25xxfd_zcanframe_to_txobj(msg, &tx_frame); - tx_frame.SEQ = mailbox_idx; - ret = mcp25xxfd_fifo_write(dev, MCP25XXFD_REG_FIFOCON(mailbox_idx), &tx_frame, - offsetof(struct mcp25xxfd_txobj, DATA) + ROUND_UP(can_dlc_to_bytes(msg->dlc), 4)); - - if (ret >= 0) { - if (callback == NULL) { - k_sem_take(&dev_data->mailbox[mailbox_idx].tx_sem, - timeout); - } - } else { - k_mutex_lock(&dev_data->mutex, K_FOREVER); - dev_data->mailbox_usage &= ~BIT(mailbox_idx); - k_mutex_unlock(&dev_data->mutex); - k_sem_give(&dev_data->tx_sem); - } - - return ret; -} - -static int mcp25xxfd_attach_isr(const struct device *dev, - can_rx_callback_t rx_cb, void *cb_arg, - const struct zcan_filter *filter) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_fltcon fltcon; - union mcp25xxfd_fltobj fltobj = { .word = 0 }; - union mcp25xxfd_mask mask = { .word = 0 }; - int filter_idx = 0; - int ret; - - __ASSERT(rx_cb != NULL, "rx_cb can not be null"); - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - while ((BIT(filter_idx) & dev_data->filter_usage) && - (filter_idx < CONFIG_CAN_MAX_FILTER)) { - filter_idx++; - } - - if (filter_idx < CONFIG_CAN_MAX_FILTER) { - if (filter->id_type == CAN_STANDARD_IDENTIFIER) { - fltobj.SID = filter->id; - mask.MSID = filter->id_mask; - } else { - fltobj.SID = filter->id >> 18; - mask.MSID = filter->id_mask >> 18; - fltobj.EID = filter->id; - mask.MEID = filter->id_mask; - fltobj.EXIDE = 1; - } - mask.MIDE = 1; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FLTOBJ(filter_idx), - &fltobj); - if (ret < 0) { - LOG_ERR("Failed to write register [%d]", ret); - goto done; - } - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_MASK(filter_idx), - &mask); - if (ret < 0) { - LOG_ERR("Failed to write register [%d]", ret); - goto done; - } - - fltcon.FLTEN = 1; - fltcon.FLTBP = MCP25XXFD_RXFIFO_IDX; - ret = mcp25xxfd_writeb(dev, MCP21518FD_REG_FLTCON(filter_idx), - fltcon.byte); - if (ret < 0) { - LOG_ERR("Failed to write register [%d]", ret); - goto done; - } - - dev_data->filter_usage |= BIT(filter_idx); - dev_data->filter[filter_idx] = *filter; - dev_data->rx_cb[filter_idx] = rx_cb; - dev_data->cb_arg[filter_idx] = cb_arg; - } else { - filter_idx = CAN_NO_FREE_FILTER; - } -done: - k_mutex_unlock(&dev_data->mutex); - - return filter_idx; -} - -static void mcp25xxfd_detach(const struct device *dev, int filter_nr) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_fltcon fltcon; - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - dev_data->filter_usage &= ~BIT(filter_nr); - fltcon.FLTEN = 0; - mcp25xxfd_writeb(dev, MCP21518FD_REG_FLTCON(filter_nr), &fltcon); - - k_mutex_unlock(&dev_data->mutex); -} - -static void mcp25xxfd_register_state_change_isr(const struct device *dev, - can_state_change_isr_t isr) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - - dev_data->state_change_isr = isr; -} - -static enum can_state mcp25xxfd_get_state(const struct device *dev, - struct can_bus_err_cnt *err_cnt) -{ - return DEV_DATA(dev)->state; -} - -static int mcp25xxfd_get_core_clock(const struct device *dev, uint32_t *rate) -{ - const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); - - *rate = dev_cfg->osc_freq; - return 0; -} - -#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY -static void mcp25xxfd_recover(const struct device *dev, k_timeout_t timeout) -{ - ARG_UNUSED(dev); - ARG_UNUSED(timeout); -} -#endif - -static void mcp25xxfd_rx(const struct device *dev, int fifo_idx) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - struct mcp25xxfd_rxobj rx_frame; - struct zcan_frame msg; - - while (mcp25xxfd_fifo_read(dev, MCP25XXFD_REG_FIFOCON(fifo_idx), &rx_frame, - sizeof(rx_frame)) >= 0) { - mcp25xxfd_rxobj_to_zcanframe(&rx_frame, &msg); - if (dev_data->filter_usage & BIT(rx_frame.FILHIT)) { - dev_data->rx_cb[rx_frame.FILHIT]( - &msg, dev_data->cb_arg[rx_frame.FILHIT]); - } - } -} - -static void mcp25xxfd_tx_done(const struct device *dev) -{ - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - struct mcp25xxfd_tefobj tefobj; - uint8_t mailbox_idx; - - while (mcp25xxfd_fifo_read(dev, MCP25XXFD_REG_TEFCON, &tefobj, - sizeof(tefobj)) >= 0) { - mailbox_idx = tefobj.SEQ; - if (dev_data->mailbox[mailbox_idx].cb == NULL) { - k_sem_give(&dev_data->mailbox[mailbox_idx].tx_sem); - } else { - dev_data->mailbox[mailbox_idx].cb( - 0, dev_data->mailbox[mailbox_idx].cb_arg); - } - k_mutex_lock(&dev_data->mutex, K_FOREVER); - dev_data->mailbox_usage &= ~BIT(mailbox_idx); - k_mutex_unlock(&dev_data->mutex); - k_sem_give(&dev_data->tx_sem); - } -} - -static void mcp25xxfd_int_thread(const struct device *dev) -{ - const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - union mcp25xxfd_intregs intregs; - union mcp25xxfd_trec trec; - uint32_t ints_before; - int ret; - - while (1) { - k_sem_take(&dev_data->int_sem, K_FOREVER); - - while (1) { - ret = mcp25xxfd_read(dev, MCP25XXFD_REG_INTREGS, - &intregs, sizeof(intregs)); - if (ret < 0) { - continue; - } - ints_before = intregs.ints.word; - - if (intregs.ints.RXIF) { - mcp25xxfd_rx(dev, MCP25XXFD_RXFIFO_IDX); - } - - if (intregs.ints.TEFIF) { - mcp25xxfd_tx_done(dev); - } - - if (intregs.ints.MODIF) { - k_sem_give(&dev_data->mode_sem); - intregs.ints.MODIF = 0; - } - - if (intregs.ints.CERRIF) { - ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_TREC, - &trec); - if (ret >= 0) { - enum can_state new_state; - - if (trec.TXBO) { - new_state = CAN_BUS_OFF; - - /* Upon entering bus-off, all the fifos are reset. */ - LOG_DBG("All FIFOs Reset"); - k_mutex_lock(&dev_data->mutex, K_FOREVER); - for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { - if (!(dev_data->mailbox_usage & BIT(i))) { - continue; - } - if (dev_data->mailbox[i].cb == NULL) { - k_sem_give(&dev_data->mailbox[i].tx_sem); - } else { - dev_data->mailbox[i].cb( - CAN_TX_BUS_OFF, dev_data->mailbox[i].cb_arg); - } - dev_data->mailbox_usage &= ~BIT(i); - k_sem_give(&dev_data->tx_sem); - } - k_mutex_unlock(&dev_data->mutex); - } else if (trec.TXBP || trec.RXBP) { - new_state = CAN_ERROR_PASSIVE; - } else { - new_state = CAN_ERROR_ACTIVE; - } - if (dev_data->state != new_state) { - LOG_DBG("State %d -> %d (tx: %d, rx: %d)", dev_data->state, new_state, trec.TEC, trec.REC); - dev_data->state = new_state; - if (dev_data->state_change_isr) { - struct can_bus_err_cnt - err_cnt; - err_cnt.rx_err_cnt = - trec.REC; - err_cnt.tx_err_cnt = - trec.TEC; - dev_data->state_change_isr( - new_state, - err_cnt); - } - } - - intregs.ints.CERRIF = 0; - } - } - - if (ints_before != intregs.ints.word) { - mcp25xxfd_writew(dev, MCP25XXFD_REG_INT, &intregs.ints); - } - - /* Break from loop if INT pin is inactive */ - ret = gpio_pin_get(dev_data->int_gpio, - dev_cfg->int_pin); - if (ret <= 0) { - /* All interrupt flags handled, but we'll abort if - * an error occurs to avoid deadlock. */ - break; - } - } - - /* Re-enable pin interrupts */ - if (gpio_pin_interrupt_configure(dev_data->int_gpio, dev_cfg->int_pin, - GPIO_INT_LEVEL_ACTIVE)) { - LOG_ERR("Couldn't enable pin interrupt"); - k_oops(); - } - } -} - -static void mcp25xxfd_int_gpio_callback(const struct device *dev, - struct gpio_callback *cb, uint32_t pins) -{ - struct mcp25xxfd_data *dev_data = - CONTAINER_OF(cb, struct mcp25xxfd_data, int_gpio_cb); - - /* Disable pin interrupts */ - if (gpio_pin_interrupt_configure(dev, dev_data->int_pin, GPIO_INT_DISABLE)) { - LOG_ERR("Couldn't disable pin interrupt"); - k_oops(); - } - - k_sem_give(&dev_data->int_sem); -} - -static const struct can_driver_api can_api_funcs = { - .set_mode = mcp25xxfd_set_mode, - .set_timing = mcp25xxfd_set_timing, - .send = mcp25xxfd_send, - .attach_isr = mcp25xxfd_attach_isr, - .detach = mcp25xxfd_detach, -#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY - .recover = mcp25xxfd_recover, -#endif - .get_state = mcp25xxfd_get_state, - .register_state_change_isr = mcp25xxfd_register_state_change_isr, - .get_core_clock = mcp25xxfd_get_core_clock, - .timing_min = { .sjw = 1, - .prop_seg = 0x0, - .phase_seg1 = 2, - .phase_seg2 = 1, - .prescaler = 1 }, - .timing_max = { .sjw = 128, - .prop_seg = 0x0, - .phase_seg1 = 256, - .phase_seg2 = 128, - .prescaler = 256 }, -#if defined(CONFIG_CAN_FD_MODE) - .timing_min_data = { .sjw = 1, - .prop_seg = 0x0, - .phase_seg1 = 1, - .phase_seg2 = 1, - .prescaler = 1 }, - .timing_max_data = { .sjw = 16, - .prop_seg = 0x0, - .phase_seg1 = 32, - .phase_seg2 = 16, - .prescaler = 256 } -#endif -}; - -static int mcp25xxfd_init(const struct device *dev) -{ - const struct mcp25xxfd_config *dev_cfg = DEV_CFG(dev); - struct mcp25xxfd_data *dev_data = DEV_DATA(dev); - int ret; - struct can_timing timing; - -#if defined(CONFIG_CAN_FD_MODE) - struct can_timing timing_data; -#endif - - k_sem_init(&dev_data->int_sem, 0, 1); - k_sem_init(&dev_data->mode_sem, 0, 1); - k_sem_init(&dev_data->tx_sem, MCP25XXFD_TXFIFOS, - MCP25XXFD_TXFIFOS); - for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { - k_sem_init(&dev_data->mailbox[i].tx_sem, 0, 1); - } - k_mutex_init(&dev_data->mutex); - - /* SPI Init */ - dev_data->spi_cfg.operation = SPI_WORD_SET(8); - dev_data->spi_cfg.frequency = dev_cfg->spi_freq; - dev_data->spi_cfg.slave = dev_cfg->spi_slave; - dev_data->spi = device_get_binding(dev_cfg->spi_port); - if (!dev_data->spi) { - LOG_ERR("SPI master port %s not found", dev_cfg->spi_port); - return -EINVAL; - } - -#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) - dev_data->spi_cs_ctrl.gpio_dev = - device_get_binding(dev_cfg->spi_cs_port); - if (!dev_data->spi_cs_ctrl.gpio_dev) { - LOG_ERR("Unable to get GPIO SPI CS device"); - return -ENODEV; - } - - dev_data->spi_cs_ctrl.gpio_pin = dev_cfg->spi_cs_pin; - dev_data->spi_cs_ctrl.gpio_dt_flags = dev_cfg->spi_cs_flags; - dev_data->spi_cs_ctrl.delay = 0U; - - dev_data->spi_cfg.cs = &dev_data->spi_cs_ctrl; -#else - dev_data->spi_cfg.cs = NULL; -#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ - - ret = mcp25xxfd_reset(dev); - if (ret < 0) { - LOG_ERR("Failed to reset the device [%d]", ret); - return -EIO; - } - - dev_data->int_gpio = device_get_binding(dev_cfg->int_port); - if (dev_data->int_gpio == NULL) { - LOG_ERR("GPIO port %s not found", dev_cfg->int_port); - return -EINVAL; - } - - if (gpio_pin_configure(dev_data->int_gpio, dev_cfg->int_pin, - (GPIO_INPUT | - DT_INST_GPIO_FLAGS(0, int_gpios)))) { - LOG_ERR("Unable to configure GPIO pin %u", dev_cfg->int_pin); - return -EINVAL; - } - - gpio_init_callback(&(dev_data->int_gpio_cb), - mcp25xxfd_int_gpio_callback, BIT(dev_cfg->int_pin)); - dev_data->int_pin = dev_cfg->int_pin; - - if (gpio_add_callback(dev_data->int_gpio, &(dev_data->int_gpio_cb))) { - return -EINVAL; - } - - if (gpio_pin_interrupt_configure(dev_data->int_gpio, dev_cfg->int_pin, - GPIO_INT_LEVEL_ACTIVE)) { - return -EINVAL; - } - - k_thread_create(&dev_data->int_thread, dev_data->int_thread_stack, - dev_cfg->int_thread_stack_size, - (k_thread_entry_t)mcp25xxfd_int_thread, (void *)dev, - NULL, NULL, K_PRIO_COOP(dev_cfg->int_thread_priority), - 0, K_NO_WAIT); - - timing.sjw = dev_cfg->tq_sjw; - if (dev_cfg->sample_point && USE_SP_ALGO) { - ret = can_calc_timing(dev, &timing, dev_cfg->bus_speed, - dev_cfg->sample_point); - if (ret == -EINVAL) { - LOG_ERR("Can't find timing for given param"); - return -EIO; - } - LOG_DBG("Presc: %d, BS1: %d, BS2: %d", timing.prescaler, - timing.phase_seg1, timing.phase_seg2); - LOG_DBG("Sample-point err : %d", ret); - } else { - timing.prop_seg = dev_cfg->tq_prop; - timing.phase_seg1 = dev_cfg->tq_bs1; - timing.phase_seg2 = dev_cfg->tq_bs2; - ret = can_calc_prescaler(dev, &timing, dev_cfg->bus_speed); - if (ret) { - LOG_WRN("Bitrate error: %d", ret); - } - } - -#if defined(CONFIG_CAN_FD_MODE) - timing_data.sjw = dev_cfg->tq_sjw_data; - if (dev_cfg->sample_point && USE_SP_ALGO) { - ret = can_calc_timing(dev, &timing_data, - dev_cfg->bus_speed_data, - dev_cfg->sample_point_data); - if (ret == -EINVAL) { - LOG_ERR("Can't find timing for given param"); - return -EIO; - } - LOG_DBG("Presc: %d, BS1: %d, BS2: %d", timing.prescaler, - timing.phase_seg1, timing.phase_seg2); - LOG_DBG("Sample-point err : %d", ret); - } else { - timing_data.prop_seg = dev_cfg->tq_prop_data; - timing_data.phase_seg1 = dev_cfg->tq_bs1_data; - timing_data.phase_seg2 = dev_cfg->tq_bs2_data; - ret = can_calc_prescaler(dev, &timing_data, - dev_cfg->bus_speed_data); - if (ret) { - LOG_WRN("Bitrate error: %d", ret); - } - } -#endif - - k_mutex_lock(&dev_data->mutex, K_FOREVER); - - union mcp25xxfd_con con; - union mcp25xxfd_int regint = { .word = 0x00000000 }; - union mcp25xxfd_iocon iocon; - union mcp25xxfd_osc osc; - union mcp25xxfd_fifocon tefcon = { .word = 0x00000400 }; - union mcp25xxfd_fifocon txfifocon = { .word = 0x00600400 }; - union mcp25xxfd_fifocon fifocon = { .word = 0x00600400 }; - - ret = mcp25xxfd_readw(dev, MCP25XXFD_REG_CON, &con); - if (ret < 0) { - goto done; - } else if (con.OPMOD != MCP25XXFD_OPMODE_CONFIGURATION) { - LOG_ERR("Device did not reset into configuration mode [%d]", - con.OPMOD); - ret = -EIO; - goto done; - } - con.TXBWS = 0; - con.ABAT = 0; - con.REQMOD = MCP25XXFD_OPMODE_CONFIGURATION; - con.TXQEN = 1; - con.STEF = 1; - con.SERR2LOM = 0; - con.ESIGM = 0; - con.RTXAT = 0; - con.BRSDIS = 0; - con.BUSY = 0; - con.WFT = MCP25XXFD_WFT_T11FILTER; - con.WAKFIL = 1; - con.PXEDIS = 0; - con.ISOCRCEN = 1; - con.DNCNT = 0; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_CON, con.byte); - if (ret < 0) { - goto done; - } - - osc.PLLEN = 0; - osc.OSCDIS = 0; - osc.LPMEN = 0; - osc.SCLKDIV = 0; - osc.CLKODIV = dev_cfg->clko_div; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_OSC, &osc.word); - if (ret < 0) { - goto done; - } - - iocon.TRIS0 = 1; - iocon.TRIS1 = 1; - iocon.XSTBYEN = 0; - iocon.LAT0 = 0; - iocon.LAT1 = 0; - iocon.PM0 = 1; - iocon.PM1 = 1; - iocon.TXCANOD = 0; - iocon.SOF = dev_cfg->sof_on_clko ? 1 : 0; - iocon.INTOD = 0; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_IOCON, &iocon.word); - if (ret < 0) { - goto done; - } - - regint.RXIE = 1; - regint.MODIE = 1; - regint.TEFIE = 1; - regint.CERRIE = 1; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_INT, ®int); - if (ret < 0) { - goto done; - } - - tefcon.FSIZE = MCP25XXFD_TXFIFOS - 1; - tefcon.FNEIE = 1; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_TEFCON, &tefcon); - if (ret < 0) { - goto done; - } - - txfifocon.PLSIZE = can_bytes_to_dlc(MCP25XXFD_PAYLOAD_SIZE) - 8; - txfifocon.FSIZE = 0; - txfifocon.TXPRI = 0; - txfifocon.TXEN = 1; - for (int i = 0; i < MCP25XXFD_TXFIFOS; i++) { - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FIFOCON(i), &txfifocon); - if (ret < 0) { - goto done; - } - } - - fifocon.PLSIZE = can_bytes_to_dlc(MCP25XXFD_PAYLOAD_SIZE) - 8; - fifocon.FSIZE = MCP25XXFD_RXFIFO_LENGTH - 1; -#if defined(CONFIG_CAN_RX_TIMESTAMP) - fifocon.TSEN = 1; -#endif - fifocon.FNEIE = 1; - ret = mcp25xxfd_writew(dev, MCP25XXFD_REG_FIFOCON(MCP25XXFD_RXFIFO_IDX), &fifocon); - if (ret < 0) { - goto done; - } - - LOG_DBG("%d TX FIFOS: 1 element", MCP25XXFD_TXFIFOS); - LOG_DBG("1 RX FIFO: %ld elements", MCP25XXFD_RXFIFO_LENGTH); - LOG_DBG("%ldb of %db RAM Allocated", MCP25XXFD_TEF_SIZE + MCP25XXFD_TXFIFOS_SIZE + MCP25XXFD_RXFIFO_SIZE, MCP25XXFD_RAM_SIZE); - -done: - k_mutex_unlock(&dev_data->mutex); - -#if defined(CONFIG_CAN_FD_MODE) - ret = can_set_timing(dev, &timing, &timing_data); -#else - ret = can_set_timing(dev, &timing, NULL); -#endif - if (ret < 0) { - return ret; - } - - ret = can_set_mode(dev, CAN_NORMAL_MODE); - - return ret; -} - -#if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) - -static K_KERNEL_STACK_DEFINE(mcp25xxfd_int_stack_0, - CONFIG_CAN_MCP25XXFD_INT_THREAD_STACK_SIZE); -static struct mcp25xxfd_data mcp25xxfd_data_0 = { - .int_thread_stack = mcp25xxfd_int_stack_0 -}; -static const struct mcp25xxfd_config mcp25xxfd_config_0 = { - .spi_port = DT_INST_BUS_LABEL(0), - .spi_freq = DT_INST_PROP(0, spi_max_frequency), - .spi_slave = DT_INST_REG_ADDR(0), -#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) - .spi_cs_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0), - .spi_cs_port = DT_INST_SPI_DEV_CS_GPIOS_LABEL(0), - .spi_cs_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0), -#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ - - .int_pin = DT_INST_GPIO_PIN(0, int_gpios), - .int_port = DT_INST_GPIO_LABEL(0, int_gpios), - .int_thread_stack_size = CONFIG_CAN_MCP25XXFD_INT_THREAD_STACK_SIZE, - .int_thread_priority = CONFIG_CAN_MCP25XXFD_INT_THREAD_PRIO, - - .sof_on_clko = DT_INST_PROP(0, sof_on_clko), - .clko_div = DT_ENUM_IDX(DT_DRV_INST(0), clko_div), - - .osc_freq = DT_INST_PROP(0, osc_freq), - .tq_sjw = DT_INST_PROP(0, sjw), - .tq_prop = DT_INST_PROP_OR(0, prop_seg, 0), - .tq_bs1 = DT_INST_PROP_OR(0, phase_seg1, 0), - .tq_bs2 = DT_INST_PROP_OR(0, phase_seg2, 0), - .bus_speed = DT_INST_PROP(0, bus_speed), - .sample_point = DT_INST_PROP_OR(0, sample_point, 0), - -#if defined(CONFIG_CAN_FD_MODE) - .tq_sjw_data = DT_INST_PROP(0, sjw_data), - .tq_prop_data = DT_INST_PROP_OR(0, prop_seg_data, 0), - .tq_bs1_data = DT_INST_PROP_OR(0, phase_seg1_data, 0), - .tq_bs2_data = DT_INST_PROP_OR(0, phase_seg2_data, 0), - .bus_speed_data = DT_INST_PROP(0, bus_speed_data), - .sample_point_data = DT_INST_PROP_OR(0, sample_point_data, 0) -#endif -}; - -DEVICE_DT_INST_DEFINE(0, &mcp25xxfd_init, NULL, - &mcp25xxfd_data_0, &mcp25xxfd_config_0, POST_KERNEL, - CONFIG_CAN_MCP25XXFD_INIT_PRIORITY, &can_api_funcs); - -#endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) */ diff --git a/drivers/can/can_mcp25xxfd.h b/drivers/can/can_mcp25xxfd.h deleted file mode 100644 index 4d9cb448f97..00000000000 --- a/drivers/can/can_mcp25xxfd.h +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2020 Abram Early - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ -#define ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ - -#include - -#define DEV_CFG(dev) ((const struct mcp25xxfd_config *const)(dev)->config) -#define DEV_DATA(dev) ((struct mcp25xxfd_data *const)(dev)->data) - -#define MCP25XXFD_RAM_SIZE 2048 -#define MCP25XXFD_PAYLOAD_SIZE CLAMP(ROUND_UP(CAN_MAX_DLEN, 4), 8, 64) -#if defined(CONFIG_CAN_TX_TIMESTAMP) -/* Note: This will be implemented with a future can_send overhaul */ -#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (4 + 8)) -#else -#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (0 + 8)) -#endif -#define MCP25XXFD_TXFIFOS_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (8 + MCP25XXFD_PAYLOAD_SIZE)) -#define MCP25XXFD_RXFIFO_MAX \ - ((MCP25XXFD_RAM_SIZE - (MCP25XXFD_TEF_SIZE + MCP25XXFD_TXFIFOS_SIZE))) -#if defined(CONFIG_CAN_RX_TIMESTAMP) -#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (4 + 8 + MCP25XXFD_PAYLOAD_SIZE) -#else -#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (0 + 8 + MCP25XXFD_PAYLOAD_SIZE) -#endif -#define MCP25XXFD_RXFIFO_LENGTH \ - MIN(MCP25XXFD_RXFIFO_MAX / MCP25XXFD_RXFIFO_ELEMENT_SIZE, 32) -#define MCP25XXFD_RXFIFO_SIZE (MCP25XXFD_RXFIFO_LENGTH * MCP25XXFD_RXFIFO_ELEMENT_SIZE) -#define MCP25XXFD_TXFIFOS CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE -#define MCP25XXFD_RXFIFO_IDX CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE -BUILD_ASSERT(MCP25XXFD_RXFIFO_LENGTH >= 1, - "Cannot fit RX FIFO into MCP25xxFD RAM"); - -struct mcp25xxfd_mailbox { - can_tx_callback_t cb; - void *cb_arg; - struct k_sem tx_sem; -}; - -struct mcp25xxfd_data { - /* SPI Data */ - const struct device *spi; - struct spi_config spi_cfg; -#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) - struct spi_cs_control spi_cs_ctrl; -#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */ - - /* Interrupt Data */ - const struct device *int_gpio; - struct gpio_callback int_gpio_cb; - struct k_thread int_thread; - k_thread_stack_t *int_thread_stack; - struct k_sem int_sem; - uint8_t int_pin; - - /* General */ - enum can_state state; - can_state_change_isr_t state_change_isr; - struct k_mutex mutex; - struct k_sem mode_sem; - - /* TX Callback */ - struct k_sem tx_sem; - uint32_t mailbox_usage; - struct mcp25xxfd_mailbox mailbox[CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE]; - - /* Filter Data */ - uint64_t filter_usage; - struct zcan_filter filter[CONFIG_CAN_MAX_FILTER]; - can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; - void *cb_arg[CONFIG_CAN_MAX_FILTER]; -}; - -struct mcp25xxfd_config { - /* SPI Config */ - const char *spi_port; - uint32_t spi_freq; - uint8_t spi_slave; - uint8_t spi_cs_pin; - uint8_t spi_cs_flags; - const char *spi_cs_port; - - /* Interrupt Config */ - uint8_t int_pin; - const char *int_port; - size_t int_thread_stack_size; - int int_thread_priority; - uint32_t osc_freq; - - /* CAN Timing */ - uint8_t tq_sjw; - uint8_t tq_prop; - uint8_t tq_bs1; - uint8_t tq_bs2; - uint32_t bus_speed; - uint16_t sample_point; - - /* IO Config */ - bool sof_on_clko; - uint8_t clko_div; - -#if defined(CONFIG_CAN_FD_MODE) - /* CAN-FD Timing */ - uint8_t tq_sjw_data; - uint8_t tq_prop_data; - uint8_t tq_bs1_data; - uint8_t tq_bs2_data; - uint32_t bus_speed_data; - uint16_t sample_point_data; -#endif -}; - -/* MCP25XXFD Opcodes */ -#define MCP25XXFD_OPCODE_RESET 0x00 -#define MCP25XXFD_OPCODE_WRITE 0x02 -#define MCP25XXFD_OPCODE_READ 0x03 - -/* MCP25XXFD Operation Modes */ -#define MCP25XXFD_OPMODE_NORMAL_CANFD 0b000 -#define MCP25XXFD_OPMODE_SLEEP 0b001 -#define MCP25XXFD_OPMODE_INT_LOOPBACK 0b010 -#define MCP25XXFD_OPMODE_LISTEN_ONLY 0b011 -#define MCP25XXFD_OPMODE_CONFIGURATION 0b100 -#define MCP25XXFD_OPMODE_EXT_LOOPBACK 0b101 -#define MCP25XXFD_OPMODE_NORMAL_CAN2 0b110 -#define MCP25XXFD_OPMODE_RESTRICTED 0b110 - -#define MCP25XXFD_WFT_T00FILTER 0b00 -#define MCP25XXFD_WFT_T01FILTER 0b01 -#define MCP25XXFD_WFT_T10FILTER 0b10 -#define MCP25XXFD_WFT_T11FILTER 0b11 - -#define MCP25XXFD_TDCMOD_AUTO 0b10 -#define MCP25XXFD_TDCMOD_MANUAL 0b01 -#define MCP25XXFD_TDCMOD_DISABLED 0b00 - -/* MCP25XXFD Registers */ - -#define MCP25XXFD_REG_CON 0x000 -union mcp25xxfd_con { - struct { - uint32_t DNCNT : 5; /* Device Net Filter Bit Number */ - uint32_t ISOCRCEN : 1; /* Enable ISO CRC in CAN FD Frames */ - uint32_t PXEDIS : 1; /* Protocol Exception Event Detection Disabled */ - uint32_t res0 : 1; - uint32_t WAKFIL : 1; /* Enable CAN Bus Line Wake-up Filter */ - uint32_t WFT : 2; /* Selectable Wake-up Filter Time */ - uint32_t BUSY : 1; /* CAN Module is Busy */ - uint32_t BRSDIS : 1; /* Bit Rate Switching Disable */ - uint32_t res1 : 3; - uint32_t RTXAT : 1; /* Restrict Retransmission Attempts */ - uint32_t ESIGM : 1; /* Transmit ESI in Gateway Mode */ - uint32_t SERR2LOM : 1; /* Transition to Listen Only Mode on System Error */ - uint32_t STEF : 1; /* Store in Transmit Event FIFO */ - uint32_t TXQEN : 1; /* Enable Transmit Queue */ - uint32_t OPMOD : 3; /* Operation Mode Status */ - uint32_t REQMOD : 3; /* Request Operation Mode */ - uint32_t ABAT : 1; /* Abort All Pending Transmissions */ - uint32_t TXBWS : 4; /* Transmit Bandwidth Sharing */ - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_NBTCFG 0x004 -union mcp25xxfd_nbtcfg { - struct { - uint32_t SJW : 7; /* Synchronization Jump Width */ - uint32_t res0 : 1; - uint32_t TSEG2 : 7; /* Time Segment 2 (Phase Segment 2) */ - uint32_t res1 : 1; - uint32_t TSEG1 : 8; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */ - uint32_t BRP : 8; /* Baud Rate Prescaler */ - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_DBTCFG 0x008 -union mcp25xxfd_dbtcfg { - struct { - uint32_t SJW : 4; /* Synchronization Jump Width */ - uint32_t res0 : 4; - uint32_t TSEG2 : 4; /* Time Segment 2 (Phase Segment 2) */ - uint32_t res1 : 4; - uint32_t TSEG1 : 5; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */ - uint32_t res2 : 3; - uint32_t BRP : 8; /* Baud Rate Prescaler */ - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_TDC 0x00C -union mcp25xxfd_tdc { - struct { - uint32_t TDCV : 6; /* Transmitter Delay Compensation Value */ - uint32_t res0 : 2; - uint32_t TDCO : 7; /* Transmitter Delay Compensation Offset */ - uint32_t res1 : 1; - uint32_t TDCMOD : 2; /* Transmitter Delay Compensation Mode */ - uint32_t res2 : 6; - uint32_t SID11EN : 1; /* Enable 12-Bit SID in CAN FD Base Format Messages */ - uint32_t EDGFLTEN : 1; /* Enable Edge Filtering during Bus Integration state */ - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_TSCON 0x014 -union mcp25xxfd_tscon { - struct { - uint32_t TBCPRE : 10; /* Time Base Counter Prescaler */ - uint32_t res0 : 6; - uint32_t TBCEN : 1; /* Time Base Counter Enable */ - uint32_t TSEOF : 1; /* 0: Beginning (See TSREF) / 1: Frame is considered valid */ - uint32_t TSRES : 1; /* Timestamp Sample Point Bit (0: SP of SOF / 1: SP of bit following FDF on FD frames) */ - uint32_t res1 : 13; - }; - uint32_t word; - uint8_t bytes[4]; -}; - -#define MCP25XXFD_REG_VEC 0x018 -union mcp25xxfd_vec { - struct { - uint32_t ICODE : 7; /* Interrupt Flag Code */ - uint32_t res0 : 1; - uint32_t FILHIT : 5; /* Filter Hit Number */ - uint32_t res1 : 3; - uint32_t TXCODE : 7; /* Transmit Interrupt Flag Code */ - uint32_t res2 : 1; - uint32_t RXCODE : 7; /* Receive Interrupt Flag Code */ - uint32_t res3 : 1; - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_INT 0x01C -union mcp25xxfd_int { - struct { - uint32_t TXIF : 1; /* Transmit FIFO Interrupt Flag */ - uint32_t RXIF : 1; /* Receive FIFO Interrupt Flag */ - uint32_t TCBIF : 1; /* Time Base Counter Interrupt Flag */ - uint32_t MODIF : 1; /* Mode Change Interrupt Flag */ - uint32_t TEFIF : 1; /* Transmit Event FIFO Interrupt Flag */ - uint32_t res0 : 3; - uint32_t ECCIF : 1; /* ECC Error Interrupt Flag */ - uint32_t SPICRCIF : 1; /* SPI CRC Error Interrupt Flag */ - uint32_t TXATIF : 1; /* Transmit Attempt Interrupt Flag */ - uint32_t RXOVIF : 1; /* Receive FIFO Overflow Interrupt Flag */ - uint32_t SERRIF : 1; /* System Error Interrupt Flag */ - uint32_t CERRIF : 1; /* CAN Bus Error Interrupt Flag */ - uint32_t WAKIF : 1; /* Bus Wake Up Interrupt Flag */ - uint32_t IVMIF : 1; /* Invalid Message Interrupt Flag */ - uint32_t TXIE : 1; /* Transmit FIFO Interrupt Enable */ - uint32_t RXIE : 1; /* Receive FIFO Interrupt Enable */ - uint32_t TBCIE : 1; /* Time Base Counter Interrupt Enable */ - uint32_t MODIE : 1; /* Mode Change Interrupt Enable */ - uint32_t TEFIE : 1; /* Transmit Event FIFO Interrupt Enable */ - uint32_t res1 : 3; - uint32_t ECCIE : 1; /* ECC Error Interrupt Enable */ - uint32_t SPICRCIE : 1; /* SPI CRC Error Interrupt Enable */ - uint32_t TXATIE : 1; /* Transmit Attempt Interrupt Enable */ - uint32_t RXOVIE : 1; /* Receive FIFO Overflow Interrupt Enable */ - uint32_t SERRIE : 1; /* System Error Interrupt Enable */ - uint32_t CERRIE : 1; /* CAN Bus Error Interrupt Enable */ - uint32_t WAKIE : 1; /* Bus Wake Up Interrupt Enable */ - uint32_t IVMIE : 1; /* Invalid Message Interrupt Enable */ - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_INTREGS MCP25XXFD_REG_VEC -union mcp25xxfd_intregs { - struct { - union mcp25xxfd_vec vec; /* Interrupt Vector Codes */ - union mcp25xxfd_int ints; /* Interrupt Enables/Flags */ - uint32_t rxif; /* FIFO RXIF Interrupt Flags */ - uint32_t txif; /* FIFO TXIF Interrupt Flags */ - uint32_t rxovif; /* FIFO RXOVIF Interrupt Flags */ - uint32_t txatif; /* FIFO TXATIF Interrupt Flags */ - }; - uint32_t words[6]; -}; - -#define MCP25XXFD_REG_TREC 0x034 - -union mcp25xxfd_trec { - struct { - uint32_t REC : 8; /* Receive Error Counter */ - uint32_t TEC : 8; /* Transmit Error Counter */ - uint32_t EWARN : 1; /* Transmitter or Receiver is in Error Warning State */ - uint32_t RXWARN : 1; /* Receiver is in Error Warning State */ - uint32_t TXWARN : 1; /* Transmitter is in Error Warning State */ - uint32_t RXBP : 1; /* Receiver in Error Passive State */ - uint32_t TXBP : 1; /* Transmitter in Error Passive State bit */ - uint32_t TXBO : 1; /* Transmitter in Bus Off State */ - uint32_t res0 : 10; - }; - uint32_t word; - uint8_t bytes[4]; -}; - -#define MCP25XXFD_REG_BDIAG1 0x3C -union mcp25xxfd_bdiag1 { - struct { - uint32_t EFMSGCNT : 16; - uint32_t NBIT0ERR : 1; - uint32_t NBIT1ERR : 1; - uint32_t NACKERR : 1; - uint32_t NFORMERR : 1; - uint32_t NSTUFERR : 1; - uint32_t NCRCERR : 1; - uint32_t res0 : 1; - uint32_t TXBOERR : 1; - uint32_t DBIT0ERR : 1; - uint32_t DBIT1ERR : 1; - uint32_t res1 : 1; - uint32_t DFORMERR : 1; - uint32_t DSTUFERR : 1; - uint32_t DCRCERR : 1; - uint32_t ESI : 1; - uint32_t DLCMM : 1; - }; - uint32_t word; - uint8_t byte[4]; -}; - -/* The FIFOCON, FIFOSTA, and FIFOUA registers are almost identical to their TEF and TXQ counterparts. */ - -#define MCP25XXFD_REG_TEFCON 0x040 -#define MCP25XXFD_REG_TXQCON 0x050 -#define MCP25XXFD_REG_FIFOCON(m) (MCP25XXFD_REG_TXQCON + (m) * 0xC) - -union mcp25xxfd_fifocon { - struct { - uint32_t FNEIE : 1; /* FIFO Not Full/Not Empty Interrupt Enable */ - uint32_t FHIE : 1; /* FIFO Half Empty/Full Interrupt Enable */ - uint32_t FFIE : 1; /* FIFO Empty/Full Interrupt Enable */ - uint32_t OVIE : 1; /* FIFO Overflow Interrupt Enable */ - uint32_t TXATIE : 1; /* FIFO TX Attempts Exhuasted Interrupt Enable */ - uint32_t TSEN : 1; /* FIFO Timestamp Enable */ - uint32_t RTREN : 1; /* FIFO Auto RTR Enable */ - uint32_t TXEN : 1; /* FIFO Transmit Enable */ - uint32_t UINC : 1; /* FIFO Increment Head */ - uint32_t TXREQ : 1; /* FIFO Message Send Request */ - uint32_t FRESET : 1; /* FIFO Reset */ - uint32_t res0 : 5; - uint32_t TXPRI : 5; /* Transmit Priority */ - uint32_t TXAT : 2; /* Retransmission Attempts */ - uint32_t res1 : 1; - uint32_t FSIZE : 5; /* FIFO Size */ - uint32_t PLSIZE : 3; /* Payload Size */ - }; - uint32_t word; - uint8_t bytes[4]; -}; - -#define MCP25XXFD_REG_TEFSTA 0x044 -#define MCP25XXFD_REG_TXQSTA 0x054 -#define MCP25XXFD_REG_FIFOSTA(m) (MCP25XXFD_REG_TXQSTA + (m) * 0xC) - -union mcp25xxfd_fifosta { - struct { - uint32_t FNEIF : 1; /* FIFO Not Full/Not Empty Interrupt Flag */ - uint32_t FHIF : 1; /* FIFO Half Empty/Full Interrupt Flag */ - uint32_t FFIF : 1; /* FIFO Empty/Full Interrupt Flag */ - uint32_t OVIF : 1; /* FIFO Overflow Interrupt Flag */ - uint32_t TXATIF : 1; /* FIFO TX Attempts Exhuasted Interrupt Flag */ - uint32_t TXERR : 1; /* Transmission Error Status */ - uint32_t TXLARB : 1; /* Message Lost Arbitration Status */ - uint32_t TXABT : 1; /* Message Aborted Status */ - uint32_t FIFOCI : 5; /* FIFO Message Index */ - }; - uint32_t word; - uint8_t bytes[4]; -}; - -#define MCP25XXFD_REG_TEFUA 0x048 -#define MCP25XXFD_REG_TXQUA 0x058 -#define MCP25XXFD_REG_FIFOUA(m) (MCP25XXFD_REG_TXQUA + (m) * 0xC) - -union mcp25xxfd_fifo { - struct { - union mcp25xxfd_fifocon con; /* FIFO Control Register */ - union mcp25xxfd_fifosta sta; /* FIFO Status Register */ - uint32_t ua; /* FIFO User Address Register */ - }; - uint32_t words[3]; -}; - -#define MCP21518FD_REG_FLTCON(m) (0x1D0 + m) -union mcp25xxfd_fltcon { - struct { - uint32_t FLTBP : 5; - uint32_t res : 2; - uint32_t FLTEN : 1; - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_FLTOBJ(m) (0x1F0 + ((m) * 8)) -union mcp25xxfd_fltobj { - struct { - uint32_t SID : 11; - uint32_t EID : 18; - uint32_t SID11 : 1; - uint32_t EXIDE : 1; - uint32_t res0 : 1; - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_MASK(m) (0x1F4 + ((m) * 8)) -union mcp25xxfd_mask { - struct { - uint32_t MSID : 11; - uint32_t MEID : 18; - uint32_t MSID11 : 1; - uint32_t MIDE : 1; - uint32_t res0 : 1; - }; - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_OSC 0xE00 -union mcp25xxfd_osc { - struct { - uint32_t PLLEN : 1; /* PLL Enable (0: Clock from XTAL, 1: Clock from 10x PLL) */ - uint32_t res0 : 1; - uint32_t OSCDIS : 1; /* Clock (Oscillator) Disable */ - uint32_t LPMEN : 1; /* Low Power Mode (LPM) Enable */ - uint32_t SCLKDIV : 1; /* System Clock Divisor (0: 1/1, 1: 1/2) */ - uint32_t CLKODIV : 2; /* Clock Output Divisor (0: 1/1, 1: 1/2, 2: 1/4, 3: 1/10) */ - uint32_t res1 : 1; - uint32_t PLLRDY : 1; /* PLL Ready (0: Not Ready, 1: Locked) */ - uint32_t res2 : 1; - uint32_t OSCRDY : 1; /* Clock Ready (0: Not Ready/Off, 1: Running/Stable) */ - uint32_t res3 : 1; - uint32_t SCLKRDY : 1; /* Synchronized SCLKDIV Bit (0: SCLKDIV 0, 1: SCLKDIV 1) */ - uint32_t res4 : 19; - }; - - uint32_t word; - uint8_t byte[4]; -}; - -#define MCP25XXFD_REG_IOCON 0xE04 -union mcp25xxfd_iocon { - struct { - uint32_t TRIS0 : 1; /* GPIO0 Data Direction (0: Output, 1: Input) */ - uint32_t TRIS1 : 1; /* GPIO1 Data Direction (0: Output, 1: Input) */ - uint32_t res0 : 4; - uint32_t XSTBYEN : 1; /* Enable Transiever Standby Pin Control */ - uint32_t res1 : 1; - uint32_t LAT0 : 1; /* GPIO0 Latch (0: Low, 1: High) */ - uint32_t LAT1 : 1; /* GPIO1 Latch (0: Low, 1: High) */ - uint32_t res2 : 6; - uint32_t GPIO0 : 1; /* GPIO0 Status (0: < VIL, 1: > VIH) */ - uint32_t GPIO1 : 1; /* GPIO1 Status (0: < VIL, 1: > VIH) */ - uint32_t res3 : 6; - uint32_t PM0 : 1; /* GPIO0 Pin Mode (0: INT0, 1: GPIO0) */ - uint32_t PM1 : 1; /* GPIO1 Pin Mode (0: INT1, 1: GPIO1) */ - uint32_t res4 : 2; - uint32_t TXCANOD : 1; /* TXCAN Drive Mode (0: Push/Pull, 1: Open Drain) */ - uint32_t SOF : 1; /* Start-Of-Frame Signal (0: Clock on CLKO, 1: SOF on CLKO) */ - uint32_t INTOD : 1; /* Interrupt Pins Drive Mode (0: Push/Pull, 1: Open Drain) */ - uint32_t res5 : 1; - }; - - uint32_t word; - uint8_t byte[4]; -}; - -/* MCP25XXFD Objects */ - -struct mcp25xxfd_txobj { - uint32_t SID : 11; - uint32_t EID : 18; - uint32_t SID11 : 1; - uint32_t res0 : 2; - uint32_t DLC : 4; /* Data Length Code */ - uint32_t IDE : 1; /* Indentifier Extension Flag */ - uint32_t RTR : 1; /* Remote Transmission Request */ - uint32_t BRS : 1; /* Bit Rate Switch Enable */ - uint32_t FDF : 1; /* FD Frame */ - uint32_t ESI : 1; /* Error Status Indicator */ - uint32_t SEQ : 23; - uint8_t DATA[CAN_MAX_DLEN]; -}; - -struct mcp25xxfd_rxobj { - uint32_t SID : 11; - uint32_t EID : 18; - uint32_t SID11 : 1; - uint32_t res0 : 2; - uint32_t DLC : 4; /* Data Length Code */ - uint32_t IDE : 1; /* Indentifier Extension Flag */ - uint32_t RTR : 1; /* Remote Transmission Request */ - uint32_t BRS : 1; /* Bit Rate Switch Enable */ - uint32_t FDF : 1; /* FD Frame */ - uint32_t ESI : 1; /* Error Status Indicator */ - uint32_t res1 : 2; - uint32_t FILHIT : 5; - uint32_t res2 : 16; -#if defined(CONFIG_CAN_RX_TIMESTAMP) - uint32_t RXMSGTS : 32; -#endif - uint8_t DATA[CAN_MAX_DLEN]; -}; - -struct mcp25xxfd_tefobj { - uint32_t SID : 11; - uint32_t EID : 18; - uint32_t SID11 : 1; - uint32_t res0 : 2; - uint32_t DLC : 4; /* Data Length Code */ - uint32_t IDE : 1; /* Indentifier Extension Flag */ - uint32_t RTR : 1; /* Remote Transmission Request */ - uint32_t BRS : 1; /* Bit Rate Switch Enable */ - uint32_t FDF : 1; /* FD Frame */ - uint32_t ESI : 1; /* Error Status Indicator */ - uint32_t SEQ : 23; -}; - -#endif /* ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ */ diff --git a/dts/bindings/can/microchip,mcp251xfd.yaml b/dts/bindings/can/microchip,mcp251xfd.yaml new file mode 100644 index 00000000000..3338f82e02a --- /dev/null +++ b/dts/bindings/can/microchip,mcp251xfd.yaml @@ -0,0 +1,80 @@ +# Copyright (c) 2020 Abram Early +# SPDX-License-Identifier: Apache-2.0 + +description: | + Microchip MCP251XFD SPI CAN-FD controller + + The MCP251XFD node is defined on an SPI bus. An example + configuration is: + + &mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + + bus-speed = <125000>; + sample-point = <875>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + }; + }; + +compatible: "microchip,mcp251xfd" + +include: [spi-device.yaml, can-fd-controller.yaml] + +properties: + osc-freq: + type: int + required: true + description: Frequency of the external oscillator in Hz. + + int-gpios: + type: phandle-array + required: true + description: | + The interrupt signal from the controller is active low in push-pull mode. + The property value should ensure the flags properly describe the signal + that is presented to the driver. + + pll-enable: + type: boolean + description: | + Enables controller PLL, which multiples input clock frequency x10. + This parameter also implicity sets whether the clock is from the PLL + output or directly from the oscillator. + If this option is enabled the clock source is the PLL, otherwise its + the oscillator. + + timestamp-prescaler: + type: int + default: 1 + description: | + Prescaler value for computing the timestamps of received messages. + The timestamp counter is derived from the internal clock divided by this value. + Valid range is [1, 1024]. + + sof-on-clko: + type: boolean + description: | + Output start-of-frame (SOF) signal on the CLKO pin every time + a Start bit of a CAN message is transmitted or received. If this option + is not set, then an internal clock (typically 40MHz or 20MHz) will be + output on CLKO pin instead. + + clko-div: + type: int + description: The factor to divide the system clock for CLKO pin. + default: 10 + enum: + - 1 + - 2 + - 4 + - 10 diff --git a/dts/bindings/can/microchip,mcp25xxfd.yaml b/dts/bindings/can/microchip,mcp25xxfd.yaml deleted file mode 100644 index 037bf32d405..00000000000 --- a/dts/bindings/can/microchip,mcp25xxfd.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2020 Abram Early -# SPDX-License-Identifier: Apache-2.0 - -description: MCP25XXFD SPI CAN-FD controller - -compatible: "microchip,mcp25xxfd" - -include: [spi-device.yaml, can-fd-controller.yaml] - -properties: - osc-freq: - type: int - required: true - description: Frequency of the external oscillator - int-gpios: - type: phandle-array - required: true - description: > - Interrupt pin. - - This pin signals active low when produced by the controller. The - property value should ensure the flags properly describe the signal - that is presented to the driver. - reg: - type: array - required: true - sof-on-clko: - type: boolean - required: false - description: Output SOF signal on CLKO pin - clko-div: - type: int - required: false - description: The factor to divide the system clock for CLKO - default: 10 - enum: - - 1 - - 2 - - 4 - - 10 \ No newline at end of file From 4cbb727e39590d88b25dc73036fc4eb172dd8132 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Sun, 2 Jul 2023 17:22:32 -0400 Subject: [PATCH 1506/4498] shields: Add CAN-FD MikroElektronika mcp2518fd click shield Adds MikroElektronica click shield for the Microchip MCP2518FD CAN-FD controller. Signed-off-by: Andriy Gelman --- .../mikroe_mcp2518fd_click/Kconfig.shield | 5 +++ .../mikroe_mcp2518fd_click/doc/index.rst | 41 +++++++++++++++++++ .../mikroe_mcp2518fd_click.overlay | 24 +++++++++++ 3 files changed, 70 insertions(+) create mode 100644 boards/shields/mikroe_mcp2518fd_click/Kconfig.shield create mode 100644 boards/shields/mikroe_mcp2518fd_click/doc/index.rst create mode 100644 boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay diff --git a/boards/shields/mikroe_mcp2518fd_click/Kconfig.shield b/boards/shields/mikroe_mcp2518fd_click/Kconfig.shield new file mode 100644 index 00000000000..5db87f809c7 --- /dev/null +++ b/boards/shields/mikroe_mcp2518fd_click/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_MIKROE_MCP2518FD_CLICK + def_bool $(shields_list_contains,mikroe_mcp2518fd_click) diff --git a/boards/shields/mikroe_mcp2518fd_click/doc/index.rst b/boards/shields/mikroe_mcp2518fd_click/doc/index.rst new file mode 100644 index 00000000000..00bc60190f8 --- /dev/null +++ b/boards/shields/mikroe_mcp2518fd_click/doc/index.rst @@ -0,0 +1,41 @@ +.. _mikroe_mcp2518fd_click_shield: + +MikroElektronika MCP2518FD Click shield (CAN-FD) +################################################ + +Overview +-------- + +MCP2518FD Click shield has a MCP2518FD CAN-FD controller via a SPI +interface and a high-speed ATA6563 CAN transceiver. + +More information about the shield can be found at +`Mikroe MCP2518FD click`_. + +Requirements +************ + +The shield uses a mikroBUS interface. The target board must define +a `mikrobus_spi` and `mikrobus_header` node labels +(see :ref:`shields` for more details). The target board must also +support level triggered interrupts. + +Programming +*********** + +Set ``-DSHIELD=mikroe_mcp2518fd_click`` when you invoke ``west build``, +for example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/can/counter + :board: lpcxpresso55s28 + :shield: mikroe_mcp2518fd_click + :goals: build flash + +References +********** + +.. target-notes:: + +.. _Mikroe MCP2518FD click: + https://www.mikroe.com/mcp2518fd-click diff --git a/boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay b/boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay new file mode 100644 index 00000000000..afd647b760a --- /dev/null +++ b/boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay @@ -0,0 +1,24 @@ +&mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + + bus-speed = <125000>; + sample-point = <875>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + }; +}; + +/ { + chosen { + zephyr,canbus = &mcp2518fd_mikroe_mcp2518fd_click; + }; +}; From 1211d778ac5066adf369828f29549e06eded9bc6 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Sun, 16 Jul 2023 19:27:00 -0400 Subject: [PATCH 1507/4498] tests: drivers: build_all: can: Add mcp251xfd test case Adds build test case for mcp25xxfd with arduino_uno_click and mikroe_mcp2518fd_click shield. Signed-off-by: Andriy Gelman --- tests/drivers/build_all/can/testcase.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/drivers/build_all/can/testcase.yaml b/tests/drivers/build_all/can/testcase.yaml index 4894e9cf3f1..749da969f76 100644 --- a/tests/drivers/build_all/can/testcase.yaml +++ b/tests/drivers/build_all/can/testcase.yaml @@ -16,3 +16,6 @@ tests: - arduino_gpio extra_args: SHIELD=tcan4550evm platform_allow: frdm_k64f + drivers.build_all.can.mcp251xfd: + extra_args: SHIELD=mikroe_mcp2518fd_click + platform_allow: lpcxpresso55s28 From f30f08a3ce75ae7d7384a7608b7e3dcef804661a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 15 Aug 2023 13:04:54 +0000 Subject: [PATCH 1508/4498] manifest: move optional modules to a submanifest and make them optional Move optional modules to a submanifest and make them optional by default. This is just a POC, might require some more thought. The idea is to look at the optional manifest as an area for modules that work with Zephyr, but not needed directly by zephyr. This could be documented somewhere for discovery purposes allowing users to enable such modules in their downstream if desired. See #54276 Signed-off-by: Anas Nashif --- submanifests/optional.yaml | 60 ++++++++++++++++++++++++++++++++++++++ west.yml | 33 +-------------------- 2 files changed, 61 insertions(+), 32 deletions(-) create mode 100644 submanifests/optional.yaml diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml new file mode 100644 index 00000000000..ef40d0201fb --- /dev/null +++ b/submanifests/optional.yaml @@ -0,0 +1,60 @@ +manifest: + remotes: + - name: upstream + url-base: https://github.com/zephyrproject-rtos + projects: + - name: chre + revision: b7955c27e50485b7dafdc3888d7d6afdc2ac6d96 + path: modules/lib/chre + remote: upstream + groups: + - optional + - name: lz4 + revision: 8e303c264fc21c2116dc612658003a22e933124d + path: modules/lib/lz4 + remote: upstream + groups: + - optional + - name: nanopb + revision: 42fa8b211e946b90b9d968523fce7b1cfe27617e + path: modules/lib/nanopb + remote: upstream + groups: + - optional + - name: psa-arch-tests + revision: 6a17330e0dfb5f319730f974d5b05f7b7f04757b + path: modules/tee/tf-m/psa-arch-tests + remote: upstream + groups: + - optional + - name: sof + revision: c0f20b69daa44e3563f970b366e49ccfcfa1b71c + path: modules/audio/sof + remote: upstream + groups: + - optional + - name: tf-m-tests + revision: a878426da78fbd1486dfc29d6c6b82be4ee79e72 + path: modules/tee/tf-m/tf-m-tests + remote: upstream + groups: + - optional + - name: tflite-micro + revision: 1a34dcab41e7e0e667db72d6a40999c1ec9c510c + path: optional/modules/lib/tflite-micro + repo-path: tflite-micro + remote: upstream + groups: + - optional + - name: thrift + path: optional/modules/lib/thrift + revision: 10023645a0e6cb7ce23fcd7fd3dbac9f18df6234 + remote: upstream + groups: + - optional + - name: zscilib + path: modules/lib/zscilib + revision: 34c3432e81085bb717e4871d21ca419ae0058ec5 + remote: upstream + groups: + - optional diff --git a/west.yml b/west.yml index fe1460492d2..b09d2a9d005 100644 --- a/west.yml +++ b/west.yml @@ -24,7 +24,7 @@ manifest: - name: babblesim url-base: https://github.com/BabbleSim - group-filter: [-babblesim] + group-filter: [-babblesim, -optional] # # Please add items below based on alphabetical order @@ -118,9 +118,6 @@ manifest: - name: canopennode revision: dec12fa3f0d790cafa8414a4c2930ea71ab72ffd path: modules/lib/canopennode - - name: chre - revision: b7955c27e50485b7dafdc3888d7d6afdc2ac6d96 - path: modules/lib/chre - name: cmsis revision: 5a00331455dd74e31e80efa383a489faea0590e3 path: modules/hal/cmsis @@ -278,9 +275,6 @@ manifest: - name: lvgl revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd path: modules/lib/gui/lvgl - - name: lz4 - revision: 8e303c264fc21c2116dc612658003a22e933124d - path: modules/lib/lz4 - name: mbedtls revision: c38dc78d9a8dcbe43b898cc1171ab33ba3e6fc26 path: modules/crypto/mbedtls @@ -294,9 +288,6 @@ manifest: groups: - debug revision: a819419603a2dfcb47f7f39092e1bc112e45d1ef - - name: nanopb - revision: 42fa8b211e946b90b9d968523fce7b1cfe27617e - path: modules/lib/nanopb - name: net-tools revision: e0828aa9629b533644dc96ff6d1295c939bd713c path: tools/net-tools @@ -324,12 +315,6 @@ manifest: path: modules/debug/segger groups: - debug - - name: sof - revision: c0f20b69daa44e3563f970b366e49ccfcfa1b71c - path: modules/audio/sof - - name: tflite-micro - revision: 1a34dcab41e7e0e667db72d6a40999c1ec9c510c - path: modules/lib/tflite-micro - name: tinycrypt revision: 3e9a49d2672ec01435ffbf0d788db6d95ef28de0 path: modules/crypto/tinycrypt @@ -345,28 +330,12 @@ manifest: path: modules/tee/tf-a/trusted-firmware-a groups: - tee - - name: tf-m-tests - revision: a878426da78fbd1486dfc29d6c6b82be4ee79e72 - path: modules/tee/tf-m/tf-m-tests - groups: - - tee - - name: psa-arch-tests - revision: 6a17330e0dfb5f319730f974d5b05f7b7f04757b - path: modules/tee/tf-m/psa-arch-tests - groups: - - tee - name: uoscore-uedhoc revision: 5fe2cb613bd7e4590bd1b00c2adf181ac0229379 path: modules/lib/uoscore-uedhoc - name: zcbor revision: 67fd8bb88d3136738661fa8bb5f9989103f4599e path: modules/lib/zcbor - - name: zscilib - path: modules/lib/zscilib - revision: 34c3432e81085bb717e4871d21ca419ae0058ec5 - - name: thrift - path: modules/lib/thrift - revision: 10023645a0e6cb7ce23fcd7fd3dbac9f18df6234 self: path: zephyr From f00b4a8a1590e51f0e747de0caf35e2fd08d10c8 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 1 Sep 2023 10:09:19 +0000 Subject: [PATCH 1509/4498] doc: modules: integration modes Document integration modes of modules. Signed-off-by: Anas Nashif --- doc/contribute/external.rst | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/doc/contribute/external.rst b/doc/contribute/external.rst index 2ce1b392edd..e602c94df09 100644 --- a/doc/contribute/external.rst +++ b/doc/contribute/external.rst @@ -103,6 +103,47 @@ With this approach the code is considered as being developed externally, and thus it is not automatically subject to the requirements of the previous section. +Integration in main manifest file (west.yaml) ++++++++++++++++++++++++++++++++++++++++++++++ + +Integrating external code into the main :file:`west.yml` manifest file is +limited to code that is used by a Zephyr subsystem (libraries), by a platform, +drivers (HAL) or tooling needed to test or build Zephyr components. + +The integration of modules in this group is validated by the Zephyr project CI, +and verified to be working with each Zephyr release. + +Integrated modules will not be removed from the tree without a detailed +migration plan. + +Integration as optional modules ++++++++++++++++++++++++++++++++ + +Standalone or loose integration of modules/projects without any incoming +dependencies shall be made optional and shall be kept standalone. Optional +projects that provide value to users directly and through a Zephyr subsystem or +platform shall be added to an optional manifest file that is filtered by +default. (:file:`submanifests/optional.yml`). + +Such optional projects might include samples and tests in their own repositories. + +There shall not be any direct dependency added in the Zephyr code tree (Git +repository) and all sample or test code shall be maintained as part of the module. + +.. note:: + + This is valid for all new optional modules. Existing optional modules with + samples and test code in the Zephyr Git repository will be transitioned out + over time. + +Integration as external modules ++++++++++++++++++++++++++++++++ + +Similar to optional modules, but added to the Zephyr project as an entry in the +documentation using a pre-defined template. This type of modules exists outside the +Zephyr project manifest with documentation instructing users and developers how +to integrate the functionality. + Ongoing maintenance =================== From 9d9f3b5c67a74bdead9dbbac794793dfeffe273b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 1 Sep 2023 11:07:21 +0000 Subject: [PATCH 1510/4498] twister: do not error on module filters If a module is not available, then it is optional, so do not error in --integration mode. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/testplan.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 905da2bc42e..042dcebb737 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -64,6 +64,8 @@ class Filters: SKIP = 'Skip filter' # in case of incompatibility between selected and allowed toolchains. TOOLCHAIN = 'Toolchain filter' + # in case an optional module is not available + MODULE = 'Module filter' class TestLevel: @@ -740,7 +742,7 @@ def apply_filters(self, **kwargs): if ts.modules and self.modules: if not set(ts.modules).issubset(set(self.modules)): - instance.add_filter(f"one or more required modules not available: {','.join(ts.modules)}", Filters.TESTSUITE) + instance.add_filter(f"one or more required modules not available: {','.join(ts.modules)}", Filters.MODULE) if self.options.level: tl = self.get_level(self.options.level) @@ -1035,7 +1037,7 @@ def change_skip_to_error_if_integration(options, instance): # Do not treat this as error if filter type is command line filters = {t['type'] for t in instance.filters} ignore_filters ={Filters.CMD_LINE, Filters.SKIP, Filters.PLATFORM_KEY, - Filters.TOOLCHAIN} + Filters.TOOLCHAIN, Filters.MODULE} if filters.intersection(ignore_filters): return instance.status = "error" From f669e156d4a7d1f8cea6448896aa4b0226a891ce Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 12 Sep 2023 07:05:46 -0400 Subject: [PATCH 1511/4498] ci: pull optional modules for now While we cleanup, pull optional modules as before to keep CI happy. Signed-off-by: Anas Nashif --- .github/workflows/clang.yaml | 1 + .github/workflows/compliance.yml | 1 + .github/workflows/twister.yaml | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 6b0762547cc..0aa8d5cd690 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -58,6 +58,7 @@ jobs: git log --pretty=oneline | head -n 10 west init -l . || true west config --global update.narrow true + west config manifest.group-filter -- +ci,+optional # In some cases modules are left in a state where they can't be # updated (i.e. when we cancel a job and the builder is killed), # So first retry to update, if that does not work, remove all modules diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index f84faff3e4a..59cfc40c264 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -44,6 +44,7 @@ jobs: # debug git log --pretty=oneline | head -n 10 west init -l . || true + west config manifest.group-filter -- +ci,+optional west update 2>&1 1> west.update.log || west update 2>&1 1> west.update2.log - name: Run Compliance Tests diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index f77980a349d..23174d7ab7c 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -75,7 +75,7 @@ jobs: git rebase origin/${BASE_REF} git log --pretty=oneline | head -n 10 west init -l . || true - west config manifest.group-filter -- +ci + west config manifest.group-filter -- +ci,+optional west config --global update.narrow true west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/zephyrproject) west forall -c 'git reset --hard HEAD' @@ -174,6 +174,7 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH west init -l . || true + west config manifest.group-filter -- +ci,+optional west config --global update.narrow true west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/zephyrproject) west forall -c 'git reset --hard HEAD' From dd7532dcf9abd40450c6ac0d66e6252877c4b2ac Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 31 Aug 2023 12:59:14 +0000 Subject: [PATCH 1512/4498] doc: add manifest extension Generate index of west projects and information about them. Based on an extension from sdk-nrf repo. Signed-off-by: Anas Nashif --- .../zephyr/manifest_projects_table.py | 141 ++++++++++++++++++ doc/conf.py | 3 + doc/develop/manifest/index.rst | 58 +++++++ 3 files changed, 202 insertions(+) create mode 100644 doc/_extensions/zephyr/manifest_projects_table.py create mode 100644 doc/develop/manifest/index.rst diff --git a/doc/_extensions/zephyr/manifest_projects_table.py b/doc/_extensions/zephyr/manifest_projects_table.py new file mode 100644 index 00000000000..0eaa06d45cf --- /dev/null +++ b/doc/_extensions/zephyr/manifest_projects_table.py @@ -0,0 +1,141 @@ +""" +Manifest Revisions Table +======================== + +This extension allows to render a table containing the revisions of the projects +present in a manifest file. + +Usage +***** + +This extension introduces a new directive: ``manifest-projects-table``. It can +be used in the code as:: + + .. manifest-projects-table:: + :filter: active + +where the ``:filter:`` option can have the following values: active, inactive, all. + +Options +******* + +- ``manifest_projects_table_manifest``: Path to the manifest file. + +Copyright (c) Nordic Semiconductor ASA 2022 +Copyright (c) Intel Corp 2023 +SPDX-License-Identifier: Apache-2.0 +""" + +import re +from typing import Any, Dict, List + +from docutils import nodes +from docutils.parsers.rst import directives +from sphinx.application import Sphinx +from sphinx.util.docutils import SphinxDirective +from west.manifest import Manifest + + +__version__ = "0.1.0" + + +class ManifestProjectsTable(SphinxDirective): + """Manifest revisions table.""" + + option_spec = { + "filter": directives.unchanged, + } + + @staticmethod + def rev_url(base_url: str, rev: str) -> str: + """Return URL for a revision. + + Notes: + Revision format is assumed to be a git hash or a tag. URL is + formatted assuming a GitHub base URL. + + Args: + base_url: Base URL of the repository. + rev: Revision. + + Returns: + URL for the revision. + """ + + if re.match(r"^[0-9a-f]{40}$", rev): + return f"{base_url}/commit/{rev}" + + return f"{base_url}/releases/tag/{rev}" + + def run(self) -> List[nodes.Element]: + active_filter = self.options.get("filter", None) + + manifest = Manifest.from_file(self.env.config.manifest_projects_table_manifest) + projects = [] + for project in manifest.projects: + if project.name == "manifest": + continue + if active_filter == 'active' and manifest.is_active(project): + projects.append(project) + elif active_filter == 'inactive' and not manifest.is_active(project): + projects.append(project) + elif active_filter == 'all' or active_filter is None: + projects.append(project) + + # build table + table = nodes.table() + + tgroup = nodes.tgroup(cols=2) + tgroup += nodes.colspec(colwidth=1) + tgroup += nodes.colspec(colwidth=1) + table += tgroup + + thead = nodes.thead() + tgroup += thead + + row = nodes.row() + thead.append(row) + + entry = nodes.entry() + entry += nodes.paragraph(text="Project") + row += entry + entry = nodes.entry() + entry += nodes.paragraph(text="Revision") + row += entry + + rows = [] + for project in projects: + row = nodes.row() + rows.append(row) + + entry = nodes.entry() + entry += nodes.paragraph(text=project.name) + row += entry + entry = nodes.entry() + par = nodes.paragraph() + par += nodes.reference( + project.revision, + project.revision, + internal=False, + refuri=ManifestProjectsTable.rev_url(project.url, project.revision), + ) + entry += par + row += entry + + tbody = nodes.tbody() + tbody.extend(rows) + tgroup += tbody + + return [table] + + +def setup(app: Sphinx) -> Dict[str, Any]: + app.add_config_value("manifest_projects_table_manifest", None, "env") + + directives.register_directive("manifest-projects-table", ManifestProjectsTable) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/doc/conf.py b/doc/conf.py index 592e3d19def..e250c494fde 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -82,6 +82,7 @@ "zephyr.warnings_filter", "zephyr.doxyrunner", "zephyr.vcs_link", + "zephyr.manifest_projects_table", "notfound.extension", "sphinx_copybutton", "sphinx_togglebutton", @@ -171,6 +172,7 @@ "API": f"{reference_prefix}/doxygen/html/index.html", "Kconfig Options": f"{reference_prefix}/kconfig.html", "Devicetree Bindings": f"{reference_prefix}/build/dts/api/bindings.html", + "West Projects": f"{reference_prefix}/develop/projects/index.html", } } @@ -292,6 +294,7 @@ ] external_content_keep = [ "reference/kconfig/*", + "develop/manifest/index.rst", "build/dts/api/bindings.rst", "build/dts/api/bindings/**/*", "build/dts/api/compatibles/**/*", diff --git a/doc/develop/manifest/index.rst b/doc/develop/manifest/index.rst new file mode 100644 index 00000000000..2dba5d817dc --- /dev/null +++ b/doc/develop/manifest/index.rst @@ -0,0 +1,58 @@ +:orphan: + +.. _west_projects_index: + +West Projects index +################### + +See :ref:`external-contributions` for more information about +this contributing and review process for imported components. + +Active Projects/Modules ++++++++++++++++++++++++ + +The projects below are enabled by default and will be downloaded when you +call `west update`. Many of the projects or modules listed below are +essential for building generic Zephyr application and include among others +hardware support for many of the platforms available in Zephyr. + +To disable any of the active modules, for example a specific HAL, use the +following commands:: + + west config manifest.project-filter -- -hal_FOO + west update + +.. manifest-projects-table:: + :filter: active + +Inactive and Optional Projects/Modules +++++++++++++++++++++++++++++++++++++++ + + +The projects below are optional and will not be downloaded when you +call `west update`. You can add any of the the projects or modules listed below +and use them to write application code and extend your workspace with the added +functionality. + +To enable any of the modules below, use the following commands:: + + west config manifest.project-filter -- +nanopb + west update + +.. manifest-projects-table:: + :filter: inactive + +External Projects/Modules +++++++++++++++++++++++++++ + + +The projects listed below are external and are not directly imported into the +default manifest. +To use any of the projects below, you will need to define your own manifest +file which includes them. See :ref:`west-manifest-import` for information on +recommended ways to do this while still inheriting the mandatory modules from +Zephyr's :file:`west.yml`. + +.. rst-class:: rst-columns + +- TBD From a0005188ceb1d0a78e6472fcc973db6408f03139 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 12 Sep 2023 19:53:28 +0000 Subject: [PATCH 1513/4498] samples: compression: add dependency on lz4 module This sample depends on lz4. Signed-off-by: Anas Nashif --- samples/compression/lz4/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/compression/lz4/sample.yaml b/samples/compression/lz4/sample.yaml index 442845e199d..733646979d5 100644 --- a/samples/compression/lz4/sample.yaml +++ b/samples/compression/lz4/sample.yaml @@ -12,6 +12,8 @@ common: type: one_line regex: - "Validation done. (.*)" + modules: + - lz4 tests: sample.compression.lz4: integration_platforms: From 2ed4cf0fde26049eefb94bcad57486e4c20169d9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 12 Sep 2023 19:54:12 +0000 Subject: [PATCH 1514/4498] samples: tflite-micro: depend on module The sample depends on on the tflite-micro module. Signed-off-by: Anas Nashif --- samples/modules/tflite-micro/tflm_ethosu/sample.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/modules/tflite-micro/tflm_ethosu/sample.yaml b/samples/modules/tflite-micro/tflm_ethosu/sample.yaml index d900f9dbe78..e1ff20cbd0f 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/sample.yaml +++ b/samples/modules/tflite-micro/tflm_ethosu/sample.yaml @@ -3,7 +3,10 @@ sample: name: Arm Ethos-U NPU sample tests: sample.drivers.tflm_ethosu: - tags: NPU + tags: + - NPU + modules: + - tflite-micro filter: dt_compat_enabled("arm,ethos-u") build_only: true integration_platforms: From a3eff88792caf97f507bc238ea76d4a5272169d8 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 12 Sep 2023 19:55:23 +0000 Subject: [PATCH 1515/4498] samples: tfm: depend on psa-arch-tests Those samples/tests depend on psa-arch-tests module. Signed-off-by: Anas Nashif --- samples/tfm_integration/tfm_psa_test/sample.yaml | 3 +++ samples/tfm_integration/tfm_regression_test/sample.yaml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index 6eea76dc157..df8ae92a372 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -8,6 +8,9 @@ common: - nrf9160dk_nrf9160_ns - nrf9161dk_nrf9161_ns - v2m_musca_s1_ns + modules: + - psa-arch-tests + - tf-m-tests integration_platforms: - mps2_an521_ns harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index 12e0810fb96..e5612d909c8 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -2,8 +2,9 @@ common: tags: - trusted-firmware-m - mcuboot + modules: + - psa-arch-tests platform_allow: - - nrf5340dk_nrf5340_cpuapp_ns - nrf9160dk_nrf9160_ns - nrf9161dk_nrf9161_ns From 1369a1d152841fd50c4e82a59714c388ed295693 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Sat, 30 Sep 2023 08:01:50 -0500 Subject: [PATCH 1516/4498] llext: Cleanups noted in initial PR There were a few small nits that were pointed out in the initial PR. Fixes the LOG_ macro in the arm elf implementation, replaces a few stray mentions of modules in llext.h with extensions. Signed-off-by: Tom Burdick --- arch/arm/core/elf.c | 4 ++-- include/zephyr/llext/llext.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/elf.c b/arch/arm/core/elf.c index b69a34086c8..0a7aa654479 100644 --- a/arch/arm/core/elf.c +++ b/arch/arm/core/elf.c @@ -8,13 +8,13 @@ #include #include -LOG_MODULE_DECLARE(elf); +LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL); /** * @brief Architecture specific function for relocating partially linked (static) elf * * Elf files contain a series of relocations described in a section. These relocation - * instructions are architecture specific and each architecture supporting modules + * instructions are architecture specific and each architecture supporting extensions * must implement this. * * The relocation codes for arm are well documented diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 13431954c48..56ad0eefea5 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -79,7 +79,7 @@ struct llext *llext_by_name(const char *name); * Only relocatable ELF files are currently supported (partially linked). * * @param[in] loader An extension loader that provides input data and context - * @param[in] name A string identifier for the module + * @param[in] name A string identifier for the extension * @param[out] ext A pointer to a statically allocated llext struct * * @retval 0 Success @@ -143,4 +143,4 @@ void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval); } #endif -#endif /* ZEPHYR_MODULE_H */ +#endif /* ZEPHYR_LLEXT_H */ From ef72f73945039fd6b6ad66119343e86e58dbe717 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 25 Aug 2023 01:12:07 +0200 Subject: [PATCH 1517/4498] usb: device_next: loopback: fixup left over from early state Class instance must not call usbd_ep_ctrl_enqueue(). Signed-off-by: Johann Fischer --- subsys/usb/device_next/class/loopback.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/subsys/usb/device_next/class/loopback.c b/subsys/usb/device_next/class/loopback.c index bdd20717e74..d6d60243ab2 100644 --- a/subsys/usb/device_next/class/loopback.c +++ b/subsys/usb/device_next/class/loopback.c @@ -216,8 +216,6 @@ static int lb_control_to_host(struct usbd_class_node *c_nd, const struct usb_setup_packet *const setup, struct net_buf *const buf) { - struct usbd_contex *uds_ctx = c_nd->data->uds_ctx; - if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) { errno = -ENOTSUP; return 0; @@ -226,7 +224,6 @@ static int lb_control_to_host(struct usbd_class_node *c_nd, if (setup->bRequest == LB_VENDOR_REQ_IN) { net_buf_add_mem(buf, lb_buf, MIN(sizeof(lb_buf), setup->wLength)); - usbd_ep_ctrl_enqueue(uds_ctx, buf); LOG_WRN("Device-to-Host, wLength %u | %zu", setup->wLength, MIN(sizeof(lb_buf), setup->wLength)); From bb3193a9f0b0dbb72dcaef1874634da5b8d0d293 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 11 Jan 2023 09:33:23 +0100 Subject: [PATCH 1518/4498] include: usbh: remove usbh_peripheral and rename class_code Rename usbh_class_code to usbh_code_triple and remove reserved member to bettter reflect the purpose of this structure. Remove unused struct usbh_peripheral. Signed-off-by: Johann Fischer --- include/zephyr/usb/usbh.h | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/include/zephyr/usb/usbh.h b/include/zephyr/usb/usbh.h index 022a4d64653..66ba43072c4 100644 --- a/include/zephyr/usb/usbh.h +++ b/include/zephyr/usb/usbh.h @@ -54,29 +54,15 @@ struct usbh_contex { } /** - * @brief USB host peripheral structure + * @brief USB Class Code triple */ -struct usbh_peripheral { - /** Peripheral dlist node */ - sys_dnode_t node; - /** Peripheral address */ - uint8_t addr; - /** Detected speed (TBD) */ - uint8_t speed; -}; - -/** - * @brief Class Code - */ -struct usbh_class_code { +struct usbh_code_triple { /** Device Class Code */ uint8_t dclass; /** Class Subclass Code */ uint8_t sub; /** Class Protocol Code */ uint8_t proto; - /** Reserved */ - uint8_t reserved; }; /** @@ -84,7 +70,7 @@ struct usbh_class_code { */ struct usbh_class_data { /** Class code supported by this instance */ - struct usbh_class_code code; + struct usbh_code_triple code; /** Initialization of the class implementation */ /* int (*init)(struct usbh_contex *const uhs_ctx); */ From 960e758e6b9eefe8a12d8246ddf5a9482913e39f Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 18 Aug 2023 14:08:35 +0200 Subject: [PATCH 1519/4498] drivers: uhc: move transfer status to transfer structure Aling with the changes in UDC done in the commit ad81b3b79747 ("drivers: udc: move transfer status to buffer info structure") This allows us to get the result of synchronous transfer and simplify uhc_submit_event(). Signed-off-by: Johann Fischer --- drivers/usb/uhc/uhc_common.c | 15 +++++++++++---- drivers/usb/uhc/uhc_common.h | 4 +--- drivers/usb/uhc/uhc_max3421e.c | 18 +++++++++--------- drivers/usb/uhc/uhc_virtual.c | 4 ++-- include/zephyr/drivers/usb/uhc.h | 8 ++++---- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 659be150117..98e1b196e97 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -21,13 +21,11 @@ NET_BUF_POOL_VAR_DEFINE(uhc_ep_pool, int uhc_submit_event(const struct device *dev, const enum uhc_event_type type, - const int status, - struct uhc_transfer *const xfer) + const int status) { struct uhc_data *data = dev->data; struct uhc_event drv_evt = { .type = type, - .xfer = xfer, .status = status, .dev = dev, }; @@ -43,10 +41,19 @@ void uhc_xfer_return(const struct device *dev, struct uhc_transfer *const xfer, const int err) { + struct uhc_data *data = dev->data; + struct uhc_event drv_evt = { + .type = UHC_EVT_EP_REQUEST, + .xfer = xfer, + .dev = dev, + }; + sys_dlist_remove(&xfer->node); xfer->queued = 0; xfer->claimed = 0; - uhc_submit_event(dev, UHC_EVT_EP_REQUEST, err, xfer); + xfer->err = err; + + data->event_cb(dev, &drv_evt); } struct uhc_transfer *uhc_xfer_get_next(const struct device *dev) diff --git a/drivers/usb/uhc/uhc_common.h b/drivers/usb/uhc/uhc_common.h index f6c487b0dc8..fa48bf2636a 100644 --- a/drivers/usb/uhc/uhc_common.h +++ b/drivers/usb/uhc/uhc_common.h @@ -173,14 +173,12 @@ int uhc_xfer_append(const struct device *dev, * @param[in] dev Pointer to device struct of the driver instance * @param[in] type Event type * @param[in] status Event status - * @param[in] xfer Pointer to UHC transfer * * @return 0 on success, all other values should be treated as error. * @retval -EPERM controller is not initialized */ int uhc_submit_event(const struct device *dev, const enum uhc_event_type type, - const int status, - struct uhc_transfer *const xfer); + const int status); #endif /* ZEPHYR_INCLUDE_UHC_COMMON_H */ diff --git a/drivers/usb/uhc/uhc_max3421e.c b/drivers/usb/uhc/uhc_max3421e.c index 0ab41d0ea9a..f51a4d96667 100644 --- a/drivers/usb/uhc/uhc_max3421e.c +++ b/drivers/usb/uhc/uhc_max3421e.c @@ -607,7 +607,7 @@ static void max3421e_handle_condet(const struct device *dev) type = UHC_EVT_DEV_CONNECTED_LS; } - uhc_submit_event(dev, type, 0, NULL); + uhc_submit_event(dev, type, 0); } static void max3421e_bus_event(const struct device *dev) @@ -617,13 +617,13 @@ static void max3421e_bus_event(const struct device *dev) if (atomic_test_and_clear_bit(&priv->state, MAX3421E_STATE_BUS_RESUME)) { /* Resume operation done event */ - uhc_submit_event(dev, UHC_EVT_RESUMED, 0, NULL); + uhc_submit_event(dev, UHC_EVT_RESUMED, 0); } if (atomic_test_and_clear_bit(&priv->state, MAX3421E_STATE_BUS_RESET)) { /* Reset operation done event */ - uhc_submit_event(dev, UHC_EVT_RESETED, 0, NULL); + uhc_submit_event(dev, UHC_EVT_RESETED, 0); } } @@ -654,7 +654,7 @@ static int max3421e_handle_bus_irq(const struct device *dev) /* Suspend operation Done Interrupt (bus suspended) */ if (hirq & MAX3421E_SUSDN) { ret = max3421e_hien_disable(dev, MAX3421E_SUSDN); - uhc_submit_event(dev, UHC_EVT_SUSPENDED, 0, NULL); + uhc_submit_event(dev, UHC_EVT_SUSPENDED, 0); } /* Peripheral Connect/Disconnect Interrupt */ @@ -664,7 +664,7 @@ static int max3421e_handle_bus_irq(const struct device *dev) /* Remote Wakeup Interrupt */ if (hirq & MAX3421E_RWU) { - uhc_submit_event(dev, UHC_EVT_RWUP, 0, NULL); + uhc_submit_event(dev, UHC_EVT_RWUP, 0); } /* Bus Reset or Bus Resume event */ @@ -695,7 +695,7 @@ static void uhc_max3421e_thread(const struct device *dev) */ err = max3421e_update_hrsl_hirq(dev); if (unlikely(err)) { - uhc_submit_event(dev, UHC_EVT_ERROR, err, NULL); + uhc_submit_event(dev, UHC_EVT_ERROR, err); } /* Host Transfer Done Interrupt */ @@ -713,20 +713,20 @@ static void uhc_max3421e_thread(const struct device *dev) if (priv->hirq & ~(MAX3421E_FRAME | MAX3421E_HXFRDN)) { err = max3421e_handle_bus_irq(dev); if (unlikely(err)) { - uhc_submit_event(dev, UHC_EVT_ERROR, err, NULL); + uhc_submit_event(dev, UHC_EVT_ERROR, err); } } /* Clear interrupts and schedule new bus transfer */ err = max3421e_clear_hirq(dev, priv->hirq); if (unlikely(err)) { - uhc_submit_event(dev, UHC_EVT_ERROR, err, NULL); + uhc_submit_event(dev, UHC_EVT_ERROR, err); } if (schedule) { err = max3421e_schedule_xfer(dev); if (unlikely(err)) { - uhc_submit_event(dev, UHC_EVT_ERROR, err, NULL); + uhc_submit_event(dev, UHC_EVT_ERROR, err); } } diff --git a/drivers/usb/uhc/uhc_virtual.c b/drivers/usb/uhc/uhc_virtual.c index b6b044353d9..810e2922236 100644 --- a/drivers/usb/uhc/uhc_virtual.c +++ b/drivers/usb/uhc/uhc_virtual.c @@ -374,7 +374,7 @@ static void xfer_work_handler(struct k_work *work) if (schedule && !priv->busy) { err = vrt_schedule_xfer(dev); if (unlikely(err)) { - uhc_submit_event(dev, UHC_EVT_ERROR, err, NULL); + uhc_submit_event(dev, UHC_EVT_ERROR, err); } } @@ -411,7 +411,7 @@ static void vrt_device_act(const struct device *dev, type = UHC_EVT_ERROR; } - uhc_submit_event(dev, type, 0, NULL); + uhc_submit_event(dev, type, 0); } static void uhc_vrt_uvb_cb(const void *const vrt_priv, diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index aff6b27bc74..9aefee569de 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -60,6 +60,8 @@ struct uhc_transfer { unsigned int setup : 1; /** Transfer owner */ void *owner; + /** Transfer result, 0 on success, other values on error */ + int err; }; /** @@ -105,13 +107,11 @@ struct uhc_event { /** Event type */ enum uhc_event_type type; union { - /** Event value */ - uint32_t value; + /** Event status value, if any */ + int status; /** Pointer to request used only for UHC_EVT_EP_REQUEST */ struct uhc_transfer *xfer; }; - /** Event status, 0 on success, other (transfer) values on error */ - int status; /** Pointer to controller's device struct */ const struct device *dev; }; From 9cb777b95e510529da0c682fb9679946d95a4b86 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 23 Aug 2023 11:40:44 +0200 Subject: [PATCH 1520/4498] drivers: uhc: rework transfer buffer handling The current approach is a bit impractical in the upper layer. This patch removes the two fifos that hold the transfer buffers and replaces them with a byte array for the setup packet and a pointer to a data buffer. The data buffer is mandatory for all types of transfers except control without a data stage. The waste of eight unused bytes for non-control transfers should be insignificant, since an additional pointer would be at least half of it, and then there would be the overhead of handling it. This patch also clean up the transfer flags, rename owner to callback as it reflects the upper layer use case, and add an additional member to hold the pointer to the USB device (peripheral on the bus). Signed-off-by: Johann Fischer --- drivers/usb/uhc/uhc_common.c | 118 +++++++++++++------------- drivers/usb/uhc/uhc_common.h | 71 ---------------- drivers/usb/uhc/uhc_max3421e.c | 123 +++++++++++---------------- drivers/usb/uhc/uhc_virtual.c | 139 +++++++++++++------------------ include/zephyr/drivers/usb/uhc.h | 88 ++++++++++++++----- subsys/usb/host/usbh_ch9.c | 21 ++--- subsys/usb/host/usbh_core.c | 11 +-- subsys/usb/host/usbh_shell.c | 41 +++++---- 8 files changed, 262 insertions(+), 350 deletions(-) diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 98e1b196e97..15377500a66 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -50,7 +50,6 @@ void uhc_xfer_return(const struct device *dev, sys_dlist_remove(&xfer->node); xfer->queued = 0; - xfer->claimed = 0; xfer->err = err; data->event_cb(dev, &drv_evt); @@ -81,13 +80,25 @@ int uhc_xfer_append(const struct device *dev, return 0; } +struct net_buf *uhc_xfer_buf_alloc(const struct device *dev, + const size_t size) +{ + return net_buf_alloc_len(&uhc_ep_pool, size, K_NO_WAIT); +} + +void uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf) +{ + net_buf_unref(buf); +} + struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, const uint8_t addr, const uint8_t ep, const uint8_t attrib, const uint16_t mps, const uint16_t timeout, - void *const owner) + void *const udev, + void *const cb) { const struct uhc_api *api = dev->api; struct uhc_transfer *xfer = NULL; @@ -98,8 +109,8 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, goto xfer_alloc_error; } - LOG_DBG("Allocate xfer, ep 0x%02x attrib 0x%02x owner %p", - ep, attrib, owner); + LOG_DBG("Allocate xfer, ep 0x%02x attrib 0x%02x cb %p", + ep, attrib, cb); if (k_mem_slab_alloc(&uhc_xfer_pool, (void **)&xfer, K_NO_WAIT)) { LOG_ERR("Failed to allocate transfer"); @@ -107,14 +118,13 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, } memset(xfer, 0, sizeof(struct uhc_transfer)); - k_fifo_init(&xfer->queue); - k_fifo_init(&xfer->done); xfer->addr = addr; xfer->ep = ep; xfer->attrib = attrib; xfer->mps = mps; xfer->timeout = timeout; - xfer->owner = owner; + xfer->udev = udev; + xfer->cb = cb; xfer_alloc_error: api->unlock(dev); @@ -122,84 +132,70 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, return xfer; } -int uhc_xfer_free(const struct device *dev, struct uhc_transfer *const xfer) +struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, + const uint8_t addr, + const uint8_t ep, + const uint8_t attrib, + const uint16_t mps, + const uint16_t timeout, + void *const udev, + void *const cb, + size_t size) { - const struct uhc_api *api = dev->api; + struct uhc_transfer *xfer; struct net_buf *buf; - int ret = 0; - api->lock(dev); - - if (xfer->queued || xfer->claimed) { - ret = -EBUSY; - LOG_ERR("Transfer is still claimed"); - goto xfer_free_error; - } - - while (!k_fifo_is_empty(&xfer->queue)) { - buf = net_buf_get(&xfer->queue, K_NO_WAIT); - uhc_xfer_buf_free(dev, buf); + buf = uhc_xfer_buf_alloc(dev, size); + if (buf == NULL) { + return NULL; } - while (!k_fifo_is_empty(&xfer->done)) { - buf = net_buf_get(&xfer->done, K_NO_WAIT); - uhc_xfer_buf_free(dev, buf); + xfer = uhc_xfer_alloc(dev, addr, ep, attrib, mps, timeout, udev, cb); + if (xfer == NULL) { + net_buf_unref(buf); + return NULL; } - k_mem_slab_free(&uhc_xfer_pool, (void *)xfer); - -xfer_free_error: - api->unlock(dev); + xfer->buf = buf; - return ret; + return xfer; } -struct net_buf *uhc_xfer_buf_alloc(const struct device *dev, - struct uhc_transfer *const xfer, - const size_t size) +int uhc_xfer_free(const struct device *dev, struct uhc_transfer *const xfer) { const struct uhc_api *api = dev->api; - struct net_buf *buf = NULL; + int ret = 0; api->lock(dev); - if (!uhc_is_initialized(dev)) { - goto buf_alloc_error; - } - - if (xfer->queued || xfer->claimed) { - goto buf_alloc_error; - } - - LOG_DBG("Allocate net_buf, ep 0x%02x, size %zd", xfer->ep, size); - buf = net_buf_alloc_len(&uhc_ep_pool, size, K_NO_WAIT); - if (!buf) { - LOG_ERR("Failed to allocate net_buf"); - goto buf_alloc_error; - } - - if (buf->size < size) { - LOG_ERR("Buffer is smaller than requested"); - net_buf_unref(buf); - buf = NULL; - goto buf_alloc_error; + if (xfer->queued) { + ret = -EBUSY; + LOG_ERR("Transfer is still queued"); + goto xfer_free_error; } - k_fifo_put(&xfer->queue, &buf->node); + k_mem_slab_free(&uhc_xfer_pool, (void *)xfer); -buf_alloc_error: +xfer_free_error: api->unlock(dev); - return buf; + return ret; } -int uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf) +int uhc_xfer_buf_add(const struct device *dev, + struct uhc_transfer *const xfer, + struct net_buf *buf) { const struct uhc_api *api = dev->api; int ret = 0; api->lock(dev); - net_buf_unref(buf); + if (xfer->queued) { + ret = -EBUSY; + } else { + xfer->buf = buf; + } + api->unlock(dev); return ret; @@ -217,12 +213,13 @@ int uhc_ep_enqueue(const struct device *dev, struct uhc_transfer *const xfer) goto ep_enqueue_error; } - xfer->claimed = 1; + xfer->queued = 1; ret = api->ep_enqueue(dev, xfer); if (ret) { - xfer->claimed = 0; + xfer->queued = 0; } + ep_enqueue_error: api->unlock(dev); @@ -242,6 +239,7 @@ int uhc_ep_dequeue(const struct device *dev, struct uhc_transfer *const xfer) } ret = api->ep_dequeue(dev, xfer); + xfer->queued = 0; ep_dequeue_error: api->unlock(dev); diff --git a/drivers/usb/uhc/uhc_common.h b/drivers/usb/uhc/uhc_common.h index fa48bf2636a..e8b276cf239 100644 --- a/drivers/usb/uhc/uhc_common.h +++ b/drivers/usb/uhc/uhc_common.h @@ -58,54 +58,6 @@ static inline int uhc_unlock_internal(const struct device *dev) return k_mutex_unlock(&data->mutex); } -/** - * @brief Checks if the transfer is queued. - * - * @param[in] xfer Pointer to UHC transfer - * - * @return true if transfer is queued, false otherwise - */ -static inline bool uhc_xfer_is_queued(struct uhc_transfer *xfer) -{ - return xfer->queued; -} - -/** - * @brief Helper function to set queued flag - * - * This function can be used by the driver to set queued flag - * - * @param[in] xfer Pointer to UHC transfer - */ -static inline void uhc_xfer_queued(struct uhc_transfer *xfer) -{ - xfer->queued = true; -} - -/** - * @brief Checks if the setup flag is set. - * - * @param[in] xfer Pointer to UHC transfer - * - * @return true if setup flagh is set, false otherwise - */ -static inline bool uhc_xfer_is_setup(struct uhc_transfer *xfer) -{ - return xfer->setup; -} - -/** - * @brief Helper function to set setup flag - * - * This function can be used by the driver to set setup flag - * - * @param[in] xfer Pointer to UHC transfer - */ -static inline void uhc_xfer_setup(struct uhc_transfer *xfer) -{ - xfer->setup = true; -} - /** * @brief Helper function to return UHC transfer to a higher level. * @@ -119,29 +71,6 @@ void uhc_xfer_return(const struct device *dev, struct uhc_transfer *const xfer, const int err); -/** - * @brief Helper to move current buffer in the done-FIFO. - * - * Helper to move current buffer (probably completed) in the - * designated done-FIFO. - * - * @param[in] xfer Pointer to UHC transfer - * - * @return 0 on success, all other values should be treated as error. - * @retval -ENOMEM if there is no buffer in the queue - */ -static inline int uhc_xfer_done(struct uhc_transfer *xfer) -{ - struct net_buf *buf; - - buf = k_fifo_get(&xfer->queue, K_NO_WAIT); - if (buf) { - k_fifo_put(&xfer->done, &buf->node); - } - - return buf == NULL ? -ENOMEM : 0; -} - /** * @brief Helper to get next transfer to process. * diff --git a/drivers/usb/uhc/uhc_max3421e.c b/drivers/usb/uhc/uhc_max3421e.c index f51a4d96667..a7955631fb9 100644 --- a/drivers/usb/uhc/uhc_max3421e.c +++ b/drivers/usb/uhc/uhc_max3421e.c @@ -310,28 +310,19 @@ static int max3421e_xfer_control(const struct device *dev, const uint8_t hrsl) { struct max3421e_data *priv = uhc_get_private(dev); - struct net_buf *buf; + struct net_buf *buf = xfer->buf; int ret; /* Just restart if device NAKed packet */ - if (uhc_xfer_is_queued(xfer) && HRSLT_IS_NAK(hrsl)) { + if (HRSLT_IS_NAK(hrsl)) { return max3421e_hxfr_start(dev, priv->hxfr); } - buf = k_fifo_peek_head(&xfer->queue); - if (buf == NULL) { - LOG_ERR("No buffers to handle"); - return -ENODATA; - } - if (!uhc_xfer_is_queued(xfer) && xfer->setup) { - return -EINVAL; - } - - if (!xfer->setup) { - /* Handle SETUP stage */ + if (xfer->stage == UHC_CONTROL_STAGE_SETUP) { + LOG_DBG("Handle SETUP stage"); ret = max3421e_write(dev, MAX3421E_REG_SUDFIFO, - buf->data, MIN(buf->len, 8)); + xfer->setup_pkt, sizeof(xfer->setup_pkt)); if (ret) { return ret; } @@ -341,25 +332,26 @@ static int max3421e_xfer_control(const struct device *dev, return ret; } - uhc_xfer_setup(xfer); - uhc_xfer_queued(xfer); - return 0; } - if (buf->size != 0) { - /* handle DATA stage */ - ret = max3421e_xfer_data(dev, buf, xfer->ep); - } else { - /* handle ACK stage */ + if (buf != NULL && xfer->stage == UHC_CONTROL_STAGE_DATA) { + LOG_DBG("Handle DATA stage"); + return max3421e_xfer_data(dev, buf, xfer->ep); + } + + if (xfer->stage == UHC_CONTROL_STAGE_STATUS) { + LOG_DBG("Handle STATUS stage"); if (USB_EP_DIR_IS_IN(xfer->ep)) { ret = max3421e_hxfr_start(dev, MAX3421E_HXFR_HSOUT(0)); } else { ret = max3421e_hxfr_start(dev, MAX3421E_HXFR_HSIN(0)); } + + return ret; } - return ret; + return -EINVAL; } static int max3421e_xfer_bulk(const struct device *dev, @@ -367,26 +359,19 @@ static int max3421e_xfer_bulk(const struct device *dev, const uint8_t hrsl) { struct max3421e_data *priv = uhc_get_private(dev); - struct net_buf *buf; - int ret; + struct net_buf *buf = xfer->buf; /* Just restart if device NAKed packet */ - if (uhc_xfer_is_queued(xfer) && HRSLT_IS_NAK(hrsl)) { + if (HRSLT_IS_NAK(hrsl)) { return max3421e_hxfr_start(dev, priv->hxfr); } - buf = k_fifo_peek_head(&xfer->queue); if (buf == NULL) { - LOG_ERR("No buffers to handle"); + LOG_ERR("No buffer to handle"); return -ENODATA; } - ret = max3421e_xfer_data(dev, buf, xfer->ep); - if (!ret) { - uhc_xfer_queued(xfer); - } - - return ret; + return max3421e_xfer_data(dev, buf, xfer->ep); } static int max3421e_schedule_xfer(const struct device *dev) @@ -444,27 +429,27 @@ static int max3421e_hrslt_success(const struct device *dev) { struct max3421e_data *priv = uhc_get_private(dev); struct uhc_transfer *const xfer = priv->last_xfer; - struct net_buf *buf; + struct net_buf *buf = xfer->buf; + bool finished = false; int err = 0; size_t len; uint8_t bc; - buf = k_fifo_peek_head(&xfer->queue); - if (buf == NULL) { - return -ENODATA; - } - switch (MAX3421E_HXFR_TYPE(priv->hxfr)) { case MAX3421E_HXFR_TYPE_SETUP: - err = uhc_xfer_done(xfer); + if (xfer->buf != NULL) { + xfer->stage = UHC_CONTROL_STAGE_DATA; + } else { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } break; case MAX3421E_HXFR_TYPE_HSOUT: LOG_DBG("HSOUT"); - err = uhc_xfer_done(xfer); + finished = true; break; case MAX3421E_HXFR_TYPE_HSIN: LOG_DBG("HSIN"); - err = uhc_xfer_done(xfer); + finished = true; break; case MAX3421E_HXFR_TYPE_ISOOUT: LOG_ERR("ISO OUT is not implemented"); @@ -477,7 +462,11 @@ static int max3421e_hrslt_success(const struct device *dev) case MAX3421E_HXFR_TYPE_BULKOUT: if (buf->len == 0) { LOG_INF("hrslt bulk out %u", buf->len); - err = uhc_xfer_done(xfer); + if (xfer->ep == USB_CONTROL_EP_OUT) { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } else { + finished = true; + } } break; case MAX3421E_HXFR_TYPE_BULKIN: @@ -502,11 +491,25 @@ static int max3421e_hrslt_success(const struct device *dev) if (bc < MAX3421E_MAX_EP_SIZE || !net_buf_tailroom(buf)) { LOG_INF("hrslt bulk in %u, %u", bc, len); - err = uhc_xfer_done(xfer); + if (xfer->ep == USB_CONTROL_EP_IN) { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } else { + finished = true; + } } break; } + if (finished) { + LOG_DBG("Transfer finished"); + uhc_xfer_return(dev, xfer, 0); + priv->last_xfer = NULL; + } + + if (err) { + max3421e_xfer_drop_active(dev, err); + } + return err; } @@ -515,27 +518,13 @@ static int max3421e_handle_hxfrdn(const struct device *dev) struct max3421e_data *priv = uhc_get_private(dev); struct uhc_transfer *const xfer = priv->last_xfer; const uint8_t hrsl = priv->hrsl; - int ret; + int ret = 0; if (xfer == NULL) { LOG_ERR("No transfers to handle"); return -ENODATA; } - /* If an active xfer is not marked then something has gone wrong */ - if (!uhc_xfer_is_queued(xfer)) { - LOG_ERR("Active transfer not queued"); - max3421e_xfer_drop_active(dev, -EINVAL); - return -EINVAL; - } - - /* There should always be a buffer in the fifo when a xfer is active */ - if (k_fifo_is_empty(&xfer->queue)) { - LOG_ERR("No buffers to handle"); - max3421e_xfer_drop_active(dev, -ENODATA); - return -ENODATA; - } - switch (MAX3421E_HRSLT(hrsl)) { case MAX3421E_HR_NAK: /* @@ -549,27 +538,15 @@ static int max3421e_handle_hxfrdn(const struct device *dev) max3421e_xfer_drop_active(dev, -ETIMEDOUT); } - ret = 0; break; case MAX3421E_HR_STALL: max3421e_xfer_drop_active(dev, -EPIPE); - ret = 0; break; case MAX3421E_HR_TOGERR: LOG_WRN("Toggle error"); - ret = 0; break; case MAX3421E_HR_SUCCESS: ret = max3421e_hrslt_success(dev); - if (ret) { - max3421e_xfer_drop_active(dev, ret); - } else { - if (k_fifo_is_empty(&xfer->queue)) { - uhc_xfer_return(dev, xfer, 0); - priv->last_xfer = NULL; - } - } - break; default: /* TODO: Handle all reasonalbe result codes */ @@ -578,7 +555,7 @@ static int max3421e_handle_hxfrdn(const struct device *dev) break; } - return 0; + return ret; } static void max3421e_handle_condet(const struct device *dev) diff --git a/drivers/usb/uhc/uhc_virtual.c b/drivers/usb/uhc/uhc_virtual.c index 810e2922236..9e33f755573 100644 --- a/drivers/usb/uhc/uhc_virtual.c +++ b/drivers/usb/uhc/uhc_virtual.c @@ -78,24 +78,16 @@ static int vrt_xfer_control(const struct device *dev, struct uhc_transfer *const xfer) { struct uhc_vrt_data *priv = uhc_get_private(dev); + struct net_buf *buf = xfer->buf; struct uvb_packet *uvb_pkt; - struct net_buf *buf; + uint8_t *data = NULL; + size_t length = 0; - buf = k_fifo_peek_head(&xfer->queue); - if (buf == NULL) { - LOG_ERR("No buffers to handle"); - return -ENODATA; - } - - if (!uhc_xfer_is_queued(xfer) && xfer->setup) { - return -EINVAL; - } - - if (!xfer->setup) { + if (xfer->stage == UHC_CONTROL_STAGE_SETUP) { LOG_DBG("Handle SETUP stage"); uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_SETUP, xfer->addr, USB_CONTROL_EP_OUT, - buf->data, buf->len); + xfer->setup_pkt, sizeof(xfer->setup_pkt)); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); return -ENOMEM; @@ -103,17 +95,11 @@ static int vrt_xfer_control(const struct device *dev, priv->req = UVB_REQUEST_SETUP; priv->busy = true; - uhc_xfer_setup(xfer); - uhc_xfer_queued(xfer); return uvb_advert_pkt(priv->host_node, uvb_pkt); } - if (buf->size != 0) { - uint8_t *data; - size_t length; - - LOG_DBG("Handle DATA stage"); + if (buf != NULL && xfer->stage == UHC_CONTROL_STAGE_DATA) { if (USB_EP_DIR_IS_IN(xfer->ep)) { length = MIN(net_buf_tailroom(buf), xfer->mps); data = net_buf_tail(buf); @@ -122,6 +108,7 @@ static int vrt_xfer_control(const struct device *dev, data = buf->data; } + LOG_DBG("Handle DATA stage"); uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, xfer->addr, xfer->ep, data, length); @@ -132,7 +119,11 @@ static int vrt_xfer_control(const struct device *dev, priv->req = UVB_REQUEST_DATA; priv->busy = true; - } else { + + return uvb_advert_pkt(priv->host_node, uvb_pkt); + } + + if (xfer->stage == UHC_CONTROL_STAGE_STATUS) { uint8_t ep; LOG_DBG("Handle STATUS stage"); @@ -144,7 +135,7 @@ static int vrt_xfer_control(const struct device *dev, uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, xfer->addr, ep, - buf->data, 0); + NULL, 0); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); return -ENOMEM; @@ -152,26 +143,21 @@ static int vrt_xfer_control(const struct device *dev, priv->req = UVB_REQUEST_DATA; priv->busy = true; + + return uvb_advert_pkt(priv->host_node, uvb_pkt); } - return uvb_advert_pkt(priv->host_node, uvb_pkt); + return -EINVAL; } static int vrt_xfer_bulk(const struct device *dev, struct uhc_transfer *const xfer) { struct uhc_vrt_data *priv = uhc_get_private(dev); + struct net_buf *buf = xfer->buf; struct uvb_packet *uvb_pkt; - struct net_buf *buf; uint8_t *data; size_t length; - int ret; - - buf = k_fifo_peek_head(&xfer->queue); - if (buf == NULL) { - LOG_ERR("No buffers to handle"); - return -ENODATA; - } if (USB_EP_DIR_IS_IN(xfer->ep)) { length = MIN(net_buf_tailroom(buf), xfer->mps); @@ -188,12 +174,7 @@ static int vrt_xfer_bulk(const struct device *dev, return -ENOMEM; } - ret = uvb_advert_pkt(priv->host_node, uvb_pkt); - if (!ret) { - uhc_xfer_queued(xfer); - } - - return ret; + return uvb_advert_pkt(priv->host_node, uvb_pkt); } static int vrt_schedule_xfer(const struct device *dev) @@ -218,31 +199,41 @@ static int vrt_schedule_xfer(const struct device *dev) return vrt_xfer_bulk(dev, priv->last_xfer); } -static int vrt_hrslt_success(const struct device *dev, - struct uvb_packet *const pkt) +static void vrt_hrslt_success(const struct device *dev, + struct uvb_packet *const pkt) { struct uhc_vrt_data *priv = uhc_get_private(dev); struct uhc_transfer *const xfer = priv->last_xfer; - struct net_buf *buf; + struct net_buf *buf = xfer->buf; + bool finished = false; size_t length; - int err = 0; - - buf = k_fifo_peek_head(&xfer->queue); - if (buf == NULL) { - return -ENODATA; - } switch (pkt->request) { case UVB_REQUEST_SETUP: - err = uhc_xfer_done(xfer); + if (xfer->buf != NULL) { + xfer->stage = UHC_CONTROL_STAGE_DATA; + } else { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } + break; case UVB_REQUEST_DATA: + if (xfer->stage == UHC_CONTROL_STAGE_STATUS) { + LOG_DBG("Status stage finished"); + finished = true; + break; + } + if (USB_EP_DIR_IS_OUT(pkt->ep)) { length = MIN(buf->len, xfer->mps); net_buf_pull(buf, length); LOG_DBG("OUT chunk %zu out of %u", length, buf->len); if (buf->len == 0) { - err = uhc_xfer_done(xfer); + if (pkt->ep == USB_CONTROL_EP_OUT) { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } else { + finished = true; + } } } else { length = MIN(net_buf_tailroom(buf), pkt->length); @@ -254,13 +245,21 @@ static int vrt_hrslt_success(const struct device *dev, LOG_DBG("IN chunk %zu out of %zu", length, net_buf_tailroom(buf)); if (pkt->length < xfer->mps || !net_buf_tailroom(buf)) { - err = uhc_xfer_done(xfer); + if (pkt->ep == USB_CONTROL_EP_IN) { + xfer->stage = UHC_CONTROL_STAGE_STATUS; + } else { + finished = true; + } } } break; } - return err; + if (finished) { + LOG_DBG("Transfer finished"); + uhc_xfer_return(dev, xfer, 0); + priv->last_xfer = NULL; + } } static void vrt_xfer_drop_active(const struct device *dev, int err) @@ -278,7 +277,7 @@ static int vrt_handle_reply(const struct device *dev, { struct uhc_vrt_data *priv = uhc_get_private(dev); struct uhc_transfer *const xfer = priv->last_xfer; - int ret; + int ret = 0; if (xfer == NULL) { LOG_ERR("No transfers to handle"); @@ -286,47 +285,19 @@ static int vrt_handle_reply(const struct device *dev, goto handle_reply_err; } - /* If an active xfer is not marked then something has gone wrong */ - if (!uhc_xfer_is_queued(xfer)) { - LOG_ERR("Active transfer not queued"); - vrt_xfer_drop_active(dev, -EINVAL); - ret = -EINVAL; - goto handle_reply_err; - } - - /* There should always be a buffer in the fifo when a xfer is active */ - if (k_fifo_is_empty(&xfer->queue)) { - LOG_ERR("No buffers to handle"); - vrt_xfer_drop_active(dev, -ENODATA); - ret = -ENODATA; - goto handle_reply_err; - } + priv->busy = false; switch (pkt->reply) { case UVB_REPLY_NACK: /* Restart last transaction */ - priv->busy = false; break; case UVB_REPLY_STALL: vrt_xfer_drop_active(dev, -EPIPE); - priv->busy = false; break; case UVB_REPLY_ACK: - ret = vrt_hrslt_success(dev, pkt); - priv->busy = false; - if (ret) { - vrt_xfer_drop_active(dev, ret); - } else { - if (k_fifo_is_empty(&xfer->queue)) { - LOG_DBG("Transfer done"); - uhc_xfer_return(dev, xfer, 0); - priv->last_xfer = NULL; - } - } - + vrt_hrslt_success(dev, pkt); break; default: - priv->busy = false; vrt_xfer_drop_active(dev, -EINVAL); ret = -EINVAL; break; @@ -349,7 +320,11 @@ static void xfer_work_handler(struct k_work *work) switch (ev->type) { case UHC_VRT_EVT_REPLY: - vrt_handle_reply(dev, ev->pkt); + err = vrt_handle_reply(dev, ev->pkt); + if (unlikely(err)) { + uhc_submit_event(dev, UHC_EVT_ERROR, err); + } + schedule = true; break; case UHC_VRT_EVT_XFER: diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index 9aefee569de..5f499af6c1d 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -25,6 +25,15 @@ * @{ */ +/** + * @brief USB control transfer stage + */ +enum uhc_control_stage { + UHC_CONTROL_STAGE_SETUP = 0, + UHC_CONTROL_STAGE_DATA, + UHC_CONTROL_STAGE_STATUS, +}; + /** * UHC endpoint buffer info * @@ -38,10 +47,10 @@ struct uhc_transfer { /** dlist node */ sys_dnode_t node; - /** FIFO requests to process */ - struct k_fifo queue; - /** FIFO to keep completed requests */ - struct k_fifo done; + /** Control transfer setup packet */ + uint8_t setup_pkt[8]; + /** Transfer data buffer */ + struct net_buf *buf; /** Device (peripheral) address */ uint8_t addr; /** Endpoint to which request is associated */ @@ -52,14 +61,14 @@ struct uhc_transfer { uint16_t mps; /** Timeout in number of frames */ uint16_t timeout; - /** Flag marks request buffer claimed by the controller */ - unsigned int claimed : 1; /** Flag marks request buffer is queued */ unsigned int queued : 1; - /** Flag marks setup stage of transfer */ - unsigned int setup : 1; - /** Transfer owner */ - void *owner; + /** Control stage status, up to the driver to use it or not */ + unsigned int stage : 2; + /** Pointer to USB device (opaque for the UHC) */ + void *udev; + /** Pointer to transfer completion callback (opaque for the UHC) */ + void *cb; /** Transfer result, 0 on success, other values on error */ int err; }; @@ -321,8 +330,8 @@ static inline int uhc_bus_resume(const struct device *dev) * @brief Allocate UHC transfer * * Allocate a new transfer from common transfer pool. - * Transfer has no buffers after allocation, these can be - * requested and assigned separately. + * Transfer has no buffer after allocation, but can be allocated + * and added from different pools. * * @param[in] dev Pointer to device struct of the driver instance * @param[in] addr Device (peripheral) address @@ -330,7 +339,8 @@ static inline int uhc_bus_resume(const struct device *dev) * @param[in] attrib Endpoint attributes * @param[in] mps Maximum packet size of the endpoint * @param[in] timeout Timeout in number of frames - * @param[in] owner Transfer owner + * @param[in] udev Opaque pointer to USB device + * @param[in] cb Transfer completion callback * * @return pointer to allocated transfer or NULL on error. */ @@ -340,7 +350,35 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, const uint8_t attrib, const uint16_t mps, const uint16_t timeout, - void *const owner); + void *const udev, + void *const cb); + +/** + * @brief Allocate UHC transfer with buffer + * + * Allocate a new transfer from common transfer pool with buffer. + * + * @param[in] dev Pointer to device struct of the driver instance + * @param[in] addr Device (peripheral) address + * @param[in] ep Endpoint address + * @param[in] attrib Endpoint attributes + * @param[in] mps Maximum packet size of the endpoint + * @param[in] timeout Timeout in number of frames + * @param[in] udev Opaque pointer to USB device + * @param[in] cb Transfer completion callback + * @param[in] size Size of the buffer + * + * @return pointer to allocated transfer or NULL on error. + */ +struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, + const uint8_t addr, + const uint8_t ep, + const uint8_t attrib, + const uint16_t mps, + const uint16_t timeout, + void *const udev, + void *const cb, + size_t size); /** * @brief Free UHC transfer and any buffers @@ -355,20 +393,32 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, int uhc_xfer_free(const struct device *dev, struct uhc_transfer *const xfer); +/** + * @brief Add UHC transfer buffer + * + * Add a previously allocated buffer to the transfer. + * + * @param[in] dev Pointer to device struct of the driver instance + * @param[in] xfer Pointer to UHC transfer + * @param[in] buf Pointer to UHC request buffer + * + * @return pointer to allocated request or NULL on error. + */ +int uhc_xfer_buf_add(const struct device *dev, + struct uhc_transfer *const xfer, + struct net_buf *buf); /** * @brief Allocate UHC transfer buffer * * Allocate a new buffer from common request buffer pool and - * assign it to the transfer. + * assign it to the transfer if the xfer parameter is not NULL. * * @param[in] dev Pointer to device struct of the driver instance - * @param[in] xfer Pointer to UHC transfer * @param[in] size Size of the request buffer * * @return pointer to allocated request or NULL on error. */ struct net_buf *uhc_xfer_buf_alloc(const struct device *dev, - struct uhc_transfer *const xfer, const size_t size); /** @@ -378,10 +428,8 @@ struct net_buf *uhc_xfer_buf_alloc(const struct device *dev, * * @param[in] dev Pointer to device struct of the driver instance * @param[in] buf Pointer to UHC request buffer - * - * @return 0 on success, all other values should be treated as error. */ -int uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf); +void uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf); /** * @brief Queue USB host controller transfer diff --git a/subsys/usb/host/usbh_ch9.c b/subsys/usb/host/usbh_ch9.c index d442f540e2d..ec55c0b3824 100644 --- a/subsys/usb/host/usbh_ch9.c +++ b/subsys/usb/host/usbh_ch9.c @@ -37,21 +37,15 @@ int usbh_req_setup(const struct device *dev, uint8_t ep = usb_reqtype_is_to_device(&req) ? 0x00 : 0x80; int ret; - xfer = uhc_xfer_alloc(dev, addr, ep, 0, 64, SETUP_REQ_TIMEOUT, NULL); + xfer = uhc_xfer_alloc(dev, addr, ep, 0, 64, SETUP_REQ_TIMEOUT, NULL, NULL); if (!xfer) { return -ENOMEM; } - buf = uhc_xfer_buf_alloc(dev, xfer, sizeof(req)); - if (!buf) { - ret = -ENOMEM; - goto buf_alloc_err; - } - - net_buf_add_mem(buf, &req, sizeof(req)); + memcpy(xfer->setup_pkt, &req, sizeof(req)); if (wLength) { - buf = uhc_xfer_buf_alloc(dev, xfer, wLength); + buf = uhc_xfer_buf_alloc(dev, wLength); if (!buf) { ret = -ENOMEM; goto buf_alloc_err; @@ -60,12 +54,11 @@ int usbh_req_setup(const struct device *dev, if (usb_reqtype_is_to_device(&req) && data != NULL) { net_buf_add_mem(buf, data, wLength); } - } - buf = uhc_xfer_buf_alloc(dev, xfer, 0); - if (!buf) { - ret = -ENOMEM; - goto buf_alloc_err; + ret = uhc_xfer_buf_add(dev, xfer, buf); + if (ret) { + goto buf_alloc_err; + } } return uhc_ep_enqueue(dev, xfer); diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index dc0f1a1da87..903d3f18a3d 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -39,14 +39,9 @@ static int event_ep_request(struct usbh_contex *const ctx, return class_data->request(ctx, event->xfer, event->status); } - while (!k_fifo_is_empty(&xfer->done)) { - struct net_buf *buf; - - buf = net_buf_get(&xfer->done, K_NO_WAIT); - if (buf) { - LOG_HEXDUMP_INF(buf->data, buf->len, "buf"); - uhc_xfer_buf_free(dev, buf); - } + if (xfer->buf) { + LOG_HEXDUMP_INF(xfer->buf->data, xfer->buf->len, "buf"); + uhc_xfer_buf_free(dev, xfer->buf); } return uhc_xfer_free(dev, xfer); diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index 6742e2ca5a0..d8e3488c079 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -107,27 +107,22 @@ static int bazfoo_request(struct usbh_contex *const ctx, shell_info(ctx_shell, "host: transfer finished %p, err %d", xfer, err); - while (!k_fifo_is_empty(&xfer->done)) { - struct net_buf *buf; - - buf = net_buf_get(&xfer->done, K_NO_WAIT); - if (buf) { - /* - * FIXME: We don not distinguish the context - * of the request and always try to print it - * as descriptor first. If it is not a known descriptor, - * we show a hexdump in any case. - * This is just simple enough for first steps and will - * be revised with coming peripheral device management. - */ - if (xfer->ep == USB_CONTROL_EP_IN) { - print_desc(ctx_shell, buf); - } else { - shell_hexdump(ctx_shell, buf->data, buf->len); - } - - uhc_xfer_buf_free(dev, buf); + if (xfer->buf) { + /* + * FIXME: We don not distinguish the context + * of the request and always try to print it + * as descriptor first. If it is not a known descriptor, + * we show a hexdump in any case. + * This is just simple enough for first steps and will + * be revised with coming peripheral device management. + */ + if (xfer->ep == USB_CONTROL_EP_IN) { + print_desc(ctx_shell, xfer->buf); + } else { + shell_hexdump(ctx_shell, xfer->buf->data, xfer->buf->len); } + + uhc_xfer_buf_free(dev, xfer->buf); } return uhc_xfer_free(dev, xfer); @@ -191,12 +186,12 @@ static int cmd_bulk(const struct shell *sh, size_t argc, char **argv) ep = strtol(argv[2], NULL, 16); len = MIN(sizeof(vreq_test_buf), strtol(argv[3], NULL, 10)); - xfer = uhc_xfer_alloc(uhs_ctx.dev, addr, ep, 0, 512, 10, NULL); + xfer = uhc_xfer_alloc(uhs_ctx.dev, addr, ep, 0, 512, 10, NULL, NULL); if (!xfer) { return -ENOMEM; } - buf = uhc_xfer_buf_alloc(uhs_ctx.dev, xfer, len); + buf = uhc_xfer_buf_alloc(uhs_ctx.dev, len); if (!buf) { return -ENOMEM; } @@ -205,6 +200,8 @@ static int cmd_bulk(const struct shell *sh, size_t argc, char **argv) net_buf_add_mem(buf, vreq_test_buf, len); } + uhc_xfer_buf_add(uhs_ctx.dev, xfer, buf); + return uhc_ep_enqueue(uhs_ctx.dev, xfer); } From aced8f528e9c397d8147efa22452e7564cddf9a6 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 25 Aug 2023 15:49:42 +0200 Subject: [PATCH 1521/4498] usb: host: cleanup UHC event processing Remove ugly hack to call class driver ops. This is preparation for later changes where we will change parts to work on structure that represents USB device and not on glue UHC functions. Signed-off-by: Johann Fischer --- subsys/usb/host/usbh_core.c | 47 +++++++++---------------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index 903d3f18a3d..9626f50be40 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -17,9 +17,6 @@ LOG_MODULE_REGISTER(uhs, CONFIG_USBH_LOG_LEVEL); static K_KERNEL_STACK_DEFINE(usbh_stack, CONFIG_USBH_STACK_SIZE); static struct k_thread usbh_thread_data; -/* TODO */ -static struct usbh_class_data *class_data; - K_MSGQ_DEFINE(usbh_msgq, sizeof(struct uhc_event), CONFIG_USBH_MAX_UHC_MSG, sizeof(uint32_t)); @@ -29,16 +26,11 @@ static int usbh_event_carrier(const struct device *dev, return k_msgq_put(&usbh_msgq, event, K_NO_WAIT); } -static int event_ep_request(struct usbh_contex *const ctx, - struct uhc_event *const event) +static int discard_ep_request(struct usbh_contex *const ctx, + struct uhc_transfer *const xfer) { - struct uhc_transfer *xfer = event->xfer; const struct device *dev = ctx->dev; - if (class_data && class_data->request) { - return class_data->request(ctx, event->xfer, event->status); - } - if (xfer->buf) { LOG_HEXDUMP_INF(xfer->buf->data, xfer->buf->len, "buf"); uhc_xfer_buf_free(dev, xfer->buf); @@ -52,51 +44,33 @@ static ALWAYS_INLINE int usbh_event_handler(struct usbh_contex *const ctx, { int ret = 0; + if (event->type == UHC_EVT_EP_REQUEST) { + return discard_ep_request(ctx, event->xfer); + } + switch (event->type) { case UHC_EVT_DEV_CONNECTED_LS: case UHC_EVT_DEV_CONNECTED_FS: case UHC_EVT_DEV_CONNECTED_HS: LOG_DBG("Device connected event"); - if (class_data && class_data->connected) { - ret = class_data->connected(ctx); - } break; case UHC_EVT_DEV_REMOVED: LOG_DBG("Device removed event"); - if (class_data && class_data->removed) { - ret = class_data->removed(ctx); - } break; case UHC_EVT_RESETED: LOG_DBG("Bus reset"); - /* TODO */ - if (class_data && class_data->removed) { - ret = class_data->removed(ctx); - } break; case UHC_EVT_SUSPENDED: LOG_DBG("Bus suspended"); - if (class_data && class_data->suspended) { - ret = class_data->suspended(ctx); - } break; case UHC_EVT_RESUMED: LOG_DBG("Bus resumed"); - if (class_data && class_data->resumed) { - ret = class_data->resumed(ctx); - } break; case UHC_EVT_RWUP: LOG_DBG("RWUP event"); - if (class_data && class_data->rwup) { - ret = class_data->rwup(ctx); - } - break; - case UHC_EVT_EP_REQUEST: - event_ep_request(ctx, event); break; case UHC_EVT_ERROR: - LOG_DBG("Error event"); + LOG_DBG("Error event %d", event->status); break; default: break; @@ -131,9 +105,10 @@ int usbh_init_device_intl(struct usbh_contex *const uhs_ctx) } STRUCT_SECTION_FOREACH(usbh_class_data, cdata) { - LOG_DBG("class data %p", cdata); - /* TODO */ - class_data = cdata; + /* + * For now, we have not implemented any class drivers, + * so just keep it as placeholder. + */ break; } From c3bcf314816e606428128f542f66c83e07e61b36 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 29 Sep 2022 11:13:53 +0200 Subject: [PATCH 1522/4498] usb: host: add a structure to represent a USB device. Add a structure to represent a USB device and wrappers to avoid glue UHC calls when operating on devices. Although there is a long road to device configuration and management, we can start with the tools that can also be used for USB device support testing. Signed-off-by: Johann Fischer --- subsys/usb/host/CMakeLists.txt | 1 + subsys/usb/host/usbh_device.c | 19 +++++++ subsys/usb/host/usbh_device.h | 95 ++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 subsys/usb/host/usbh_device.c create mode 100644 subsys/usb/host/usbh_device.h diff --git a/subsys/usb/host/CMakeLists.txt b/subsys/usb/host/CMakeLists.txt index 94fc529f533..1f29b2c7af2 100644 --- a/subsys/usb/host/CMakeLists.txt +++ b/subsys/usb/host/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_library_sources( usbh_ch9.c usbh_core.c usbh_api.c + usbh_device.c ) zephyr_library_sources_ifdef( diff --git a/subsys/usb/host/usbh_device.c b/subsys/usb/host/usbh_device.c new file mode 100644 index 00000000000..cfc4cc5998d --- /dev/null +++ b/subsys/usb/host/usbh_device.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "usbh_device.h" + +#define USBH_USB_DEVICE_COUNT 1 + +static struct usb_device udevs[USBH_USB_DEVICE_COUNT]; + +struct usb_device *usbh_device_get_any(struct usbh_contex *const ctx) +{ + udevs->ctx = ctx; + + return udevs; +} diff --git a/subsys/usb/host/usbh_device.h b/subsys/usb/host/usbh_device.h new file mode 100644 index 00000000000..742c6a71803 --- /dev/null +++ b/subsys/usb/host/usbh_device.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_USBH_DEVICE_H +#define ZEPHYR_INCLUDE_USBH_DEVICE_H + +#include +#include +#include + +/* USB device state */ +enum usb_device_state { + USB_STATE_NOTCONNECTED, + USB_STATE_DEFAULT, + USB_STATE_ADDRESSED, + USB_STATE_CONFIGURED, +}; + +/* Host support view of a USB device */ +struct usb_device { + struct usbh_contex *ctx; + struct usb_device_descriptor dev_desc; + enum usb_device_state state; + uint8_t actual_cfg; + uint8_t addr; +}; + +/* Callback type to be used for e.g. synchronous requests */ +typedef int (*usbh_udev_cb_t)(struct usb_device *const udev, + struct uhc_transfer *const xfer); + +/* + * Get a device to work on, there will only be one for the first time + * until we implement USB device configuration/management. + */ +struct usb_device *usbh_device_get_any(struct usbh_contex *const ctx); + +/* Wrappers around to avoid glue UHC calls. */ +static inline struct uhc_transfer *usbh_xfer_alloc(struct usb_device *udev, + const uint8_t ep, + const uint8_t attrib, + const uint16_t mps, + const uint16_t timeout, + usbh_udev_cb_t *const cb) +{ + struct usbh_contex *const ctx = udev->ctx; + + return uhc_xfer_alloc(ctx->dev, udev->addr, ep, attrib, mps, timeout, udev, cb); +} + +static inline int usbh_xfer_buf_add(const struct usb_device *udev, + struct uhc_transfer *const xfer, + struct net_buf *buf) +{ + struct usbh_contex *const ctx = udev->ctx; + + return uhc_xfer_buf_add(ctx->dev, xfer, buf); +} + +static inline struct net_buf *usbh_xfer_buf_alloc(struct usb_device *udev, + const size_t size) +{ + struct usbh_contex *const ctx = udev->ctx; + + return uhc_xfer_buf_alloc(ctx->dev, size); +} + +static inline int usbh_xfer_free(const struct usb_device *udev, + struct uhc_transfer *const xfer) +{ + struct usbh_contex *const ctx = udev->ctx; + + return uhc_xfer_free(ctx->dev, xfer); +} + +static inline void usbh_xfer_buf_free(const struct usb_device *udev, + struct net_buf *const buf) +{ + struct usbh_contex *const ctx = udev->ctx; + + uhc_xfer_buf_free(ctx->dev, buf); +} + +static inline int usbh_xfer_enqueue(const struct usb_device *udev, + struct uhc_transfer *const xfer) +{ + struct usbh_contex *const ctx = udev->ctx; + + return uhc_ep_enqueue(ctx->dev, xfer); +} + +#endif /* ZEPHYR_INCLUDE_USBH_DEVICE_H */ From c1065e0e19cd9fa8c95330b4e98df643ae6d62d5 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 25 Aug 2023 19:00:28 +0200 Subject: [PATCH 1523/4498] usb: host: rework ch9 tools to work on USB device Use the USB device structure and wrappers introduced earlier. With this patch, users of ch9 requests do not need to work directly with the UHC API. The requests are now blocked until there is a response from the UHC. Callers finally have access to the data buffer and request status. Signed-off-by: Johann Fischer --- subsys/usb/host/usbh_ch9.c | 188 +++++++++++++++++++++---------- subsys/usb/host/usbh_ch9.h | 49 ++++---- subsys/usb/host/usbh_core.c | 15 ++- subsys/usb/host/usbh_shell.c | 213 ++++++++++++++++++----------------- 4 files changed, 272 insertions(+), 193 deletions(-) diff --git a/subsys/usb/host/usbh_ch9.c b/subsys/usb/host/usbh_ch9.c index ec55c0b3824..55bc5a97bc5 100644 --- a/subsys/usb/host/usbh_ch9.c +++ b/subsys/usb/host/usbh_ch9.c @@ -4,26 +4,43 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include + +#include +#include #include #include #include +#include "usbh_device.h" + #include LOG_MODULE_REGISTER(usbh_ch9, CONFIG_USBH_LOG_LEVEL); -#define SETUP_REQ_TIMEOUT 1000U +/* + * For now we set it to the upper limit defined in Chapter + * "9.2.6.4 Standard Device Requests" + * This will need to be revised and set depending on the request. + */ +#define SETUP_REQ_TIMEOUT 5000U + +K_SEM_DEFINE(ch9_req_sync, 0, 1); -int usbh_req_setup(const struct device *dev, - const uint8_t addr, +static int ch9_req_cb(struct usb_device *const udev, struct uhc_transfer *const xfer) +{ + LOG_DBG("Request finished %p, err %d", xfer, xfer->err); + k_sem_give(&ch9_req_sync); + + return 0; +} + +int usbh_req_setup(struct usb_device *const udev, const uint8_t bmRequestType, const uint8_t bRequest, const uint16_t wValue, const uint16_t wIndex, const uint16_t wLength, - uint8_t *const data) + struct net_buf *const buf) { struct usb_setup_packet req = { .bmRequestType = bmRequestType, @@ -33,101 +50,152 @@ int usbh_req_setup(const struct device *dev, .wLength = sys_cpu_to_le16(wLength), }; struct uhc_transfer *xfer; - struct net_buf *buf; uint8_t ep = usb_reqtype_is_to_device(&req) ? 0x00 : 0x80; int ret; - xfer = uhc_xfer_alloc(dev, addr, ep, 0, 64, SETUP_REQ_TIMEOUT, NULL, NULL); + xfer = usbh_xfer_alloc(udev, ep, 0, 64, SETUP_REQ_TIMEOUT, (void *)ch9_req_cb); if (!xfer) { return -ENOMEM; } memcpy(xfer->setup_pkt, &req, sizeof(req)); - if (wLength) { - buf = uhc_xfer_buf_alloc(dev, wLength); - if (!buf) { - ret = -ENOMEM; - goto buf_alloc_err; - } - - if (usb_reqtype_is_to_device(&req) && data != NULL) { - net_buf_add_mem(buf, data, wLength); - } - - ret = uhc_xfer_buf_add(dev, xfer, buf); + if (wLength && buf != NULL) { + ret = usbh_xfer_buf_add(udev, xfer, buf); if (ret) { goto buf_alloc_err; } } - return uhc_ep_enqueue(dev, xfer); + ret = usbh_xfer_enqueue(udev, xfer); + if (ret) { + goto buf_alloc_err; + } + + k_sem_take(&ch9_req_sync, K_MSEC(SETUP_REQ_TIMEOUT)); + ret = xfer->err; buf_alloc_err: - uhc_xfer_free(dev, xfer); + usbh_xfer_free(udev, xfer); return ret; } -int usbh_req_desc(const struct device *dev, - const uint8_t addr, +int usbh_req_desc(struct usb_device *const udev, const uint8_t type, const uint8_t index, const uint8_t id, - const uint16_t len) + const uint16_t len, + struct net_buf *const buf) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_HOST << 7; const uint8_t bRequest = USB_SREQ_GET_DESCRIPTOR; const uint16_t wValue = (type << 8) | index; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, id, len, - NULL); + buf); } -int usbh_req_desc_dev(const struct device *dev, - const uint8_t addr) +int usbh_req_desc_dev(struct usb_device *const udev, + struct usb_device_descriptor *const desc) { const uint8_t type = USB_DESC_DEVICE; - const uint16_t wLength = 18; + const uint16_t wLength = sizeof(struct usb_device_descriptor); + struct net_buf *buf; + int ret; + + buf = usbh_xfer_buf_alloc(udev, wLength); + if (!buf) { + return -ENOMEM; + } + + ret = usbh_req_desc(udev, type, 0, 0, wLength, buf); + if (ret == 0 && buf->len == wLength) { + memcpy(desc, buf->data, wLength); + desc->bcdUSB = sys_le16_to_cpu(desc->bcdUSB); + desc->idVendor = sys_le16_to_cpu(desc->idVendor); + desc->idProduct = sys_le16_to_cpu(desc->idProduct); + desc->bcdDevice = sys_le16_to_cpu(desc->bcdDevice); + } - return usbh_req_desc(dev, addr, type, 0, 0, wLength); + usbh_xfer_buf_free(udev, buf); + + return ret; } -int usbh_req_desc_cfg(const struct device *dev, - const uint8_t addr, +int usbh_req_desc_cfg(struct usb_device *const udev, const uint8_t index, - const uint16_t len) + const uint16_t len, + struct usb_cfg_descriptor *const desc) { const uint8_t type = USB_DESC_CONFIGURATION; + const uint16_t wLength = len; + struct net_buf *buf; + int ret; + + buf = usbh_xfer_buf_alloc(udev, len); + if (!buf) { + return -ENOMEM; + } - return usbh_req_desc(dev, addr, type, index, 0, len); + ret = usbh_req_desc(udev, type, index, 0, wLength, buf); + if (ret == 0) { + memcpy(desc, buf->data, len); + desc->wTotalLength = sys_le16_to_cpu(desc->wTotalLength); + } + + usbh_xfer_buf_free(udev, buf); + + return ret; } -int usbh_req_set_address(const struct device *dev, - const uint8_t addr, const uint8_t new) +int usbh_req_set_address(struct usb_device *const udev, + const uint8_t addr) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7; const uint8_t bRequest = USB_SREQ_SET_ADDRESS; + int ret; - return usbh_req_setup(dev, addr, - bmRequestType, bRequest, new, 0, 0, - NULL); + ret = usbh_req_setup(udev, bmRequestType, bRequest, addr, 0, 0, NULL); + if (ret == 0) { + udev->addr = addr; + if (addr == 0) { + udev->state = USB_STATE_DEFAULT; + } + + if (addr != 0 && udev->state == USB_STATE_DEFAULT) { + udev->state = USB_STATE_ADDRESSED; + } + } + + return ret; } -int usbh_req_set_cfg(const struct device *dev, - const uint8_t addr, const uint8_t new) +int usbh_req_set_cfg(struct usb_device *const udev, + const uint8_t cfg) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7; const uint8_t bRequest = USB_SREQ_SET_CONFIGURATION; + int ret; - return usbh_req_setup(dev, addr, - bmRequestType, bRequest, new, 0, 0, - NULL); + /* Ignore the required state change condition for now. */ + ret = usbh_req_setup(udev, bmRequestType, bRequest, cfg, 0, 0, NULL); + if (ret == 0) { + udev->actual_cfg = cfg; + if (cfg == 0) { + udev->state = USB_STATE_ADDRESSED; + } + + if (cfg != 0 && udev->state == USB_STATE_ADDRESSED) { + udev->state = USB_STATE_CONFIGURED; + } + } + + return ret; } -int usbh_req_set_alt(const struct device *dev, - const uint8_t addr, const uint8_t iface, - const uint8_t alt) +int usbh_req_set_alt(struct usb_device *const udev, + const uint8_t iface, const uint8_t alt) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 | USB_REQTYPE_RECIPIENT_INTERFACE; @@ -135,37 +203,35 @@ int usbh_req_set_alt(const struct device *dev, const uint16_t wValue = alt; const uint16_t wIndex = iface; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, wIndex, 0, NULL); } -int usbh_req_set_sfs_rwup(const struct device *dev, - const uint8_t addr) +int usbh_req_set_sfs_rwup(struct usb_device *const udev) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7; const uint8_t bRequest = USB_SREQ_SET_FEATURE; const uint16_t wValue = USB_SFS_REMOTE_WAKEUP; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, 0, 0, NULL); } -int usbh_req_clear_sfs_rwup(const struct device *dev, - const uint8_t addr) +int usbh_req_clear_sfs_rwup(struct usb_device *const udev) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7; const uint8_t bRequest = USB_SREQ_CLEAR_FEATURE; const uint16_t wValue = USB_SFS_REMOTE_WAKEUP; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, 0, 0, NULL); } -int usbh_req_set_hcfs_ppwr(const struct device *dev, - const uint8_t addr, const uint8_t port) +int usbh_req_set_hcfs_ppwr(struct usb_device *const udev, + const uint8_t port) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 | USB_REQTYPE_TYPE_CLASS << 5 | @@ -174,13 +240,13 @@ int usbh_req_set_hcfs_ppwr(const struct device *dev, const uint16_t wValue = USB_HCFS_PORT_POWER; const uint16_t wIndex = port; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, wIndex, 0, NULL); } -int usbh_req_set_hcfs_prst(const struct device *dev, - const uint8_t addr, const uint8_t port) +int usbh_req_set_hcfs_prst(struct usb_device *const udev, + const uint8_t port) { const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 | USB_REQTYPE_TYPE_CLASS << 5 | @@ -189,7 +255,7 @@ int usbh_req_set_hcfs_prst(const struct device *dev, const uint16_t wValue = USB_HCFS_PORT_RESET; const uint16_t wIndex = port; - return usbh_req_setup(dev, addr, + return usbh_req_setup(udev, bmRequestType, bRequest, wValue, wIndex, 0, NULL); } diff --git a/subsys/usb/host/usbh_ch9.h b/subsys/usb/host/usbh_ch9.h index c5a932fdec6..a07ca7bd8a1 100644 --- a/subsys/usb/host/usbh_ch9.h +++ b/subsys/usb/host/usbh_ch9.h @@ -10,49 +10,48 @@ #include #include -int usbh_req_setup(const struct device *dev, - const uint8_t addr, +#include "usbh_device.h" + +int usbh_req_setup(struct usb_device *const udev, const uint8_t bmRequestType, const uint8_t bRequest, const uint16_t wValue, const uint16_t wIndex, const uint16_t wLength, - uint8_t *const data); + struct net_buf *const data); -int usbh_req_desc(const struct device *dev, - const uint8_t addr, +int usbh_req_desc(struct usb_device *const udev, const uint8_t type, const uint8_t index, const uint8_t id, - const uint16_t len); + const uint16_t len, + struct net_buf *const data); -int usbh_req_desc_dev(const struct device *dev, - const uint8_t addr); +int usbh_req_desc_dev(struct usb_device *const udev, + struct usb_device_descriptor *const dev); -int usbh_req_desc_cfg(const struct device *dev, - const uint8_t addr, +int usbh_req_desc_cfg(struct usb_device *const udev, const uint8_t index, - const uint16_t len); + const uint16_t len, + struct usb_cfg_descriptor *const desc); -int usbh_req_set_alt(const struct device *dev, - const uint8_t addr, const uint8_t iface, +int usbh_req_set_alt(struct usb_device *const udev, + const uint8_t iface, const uint8_t alt); -int usbh_req_set_address(const struct device *dev, - const uint8_t addr, const uint8_t new); +int usbh_req_set_address(struct usb_device *const udev, + const uint8_t addr); -int usbh_req_set_cfg(const struct device *dev, - const uint8_t addr, const uint8_t new); +int usbh_req_set_cfg(struct usb_device *const udev, + const uint8_t cfg); -int usbh_req_set_sfs_rwup(const struct device *dev, - const uint8_t addr); +int usbh_req_set_sfs_rwup(struct usb_device *const udev); -int usbh_req_clear_sfs_rwup(const struct device *dev, - const uint8_t addr); +int usbh_req_clear_sfs_rwup(struct usb_device *const udev); -int usbh_req_set_hcfs_ppwr(const struct device *dev, - const uint8_t addr, const uint8_t port); +int usbh_req_set_hcfs_ppwr(const struct usb_device *udev, + const uint8_t port); -int usbh_req_set_hcfs_prst(const struct device *dev, - const uint8_t addr, const uint8_t port); +int usbh_req_set_hcfs_prst(const struct usb_device *udev, + const uint8_t port); #endif /* ZEPHYR_INCLUDE_USBH_CH9_H */ diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index 9626f50be40..ac4976b6556 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -9,8 +9,11 @@ #include #include #include -#include "usbh_internal.h" #include + +#include "usbh_internal.h" +#include "usbh_device.h" + #include LOG_MODULE_REGISTER(uhs, CONFIG_USBH_LOG_LEVEL); @@ -45,7 +48,15 @@ static ALWAYS_INLINE int usbh_event_handler(struct usbh_contex *const ctx, int ret = 0; if (event->type == UHC_EVT_EP_REQUEST) { - return discard_ep_request(ctx, event->xfer); + struct usb_device *const udev = event->xfer->udev; + usbh_udev_cb_t cb = event->xfer->cb; + + if (event->xfer->cb) { + ret = cb(udev, event->xfer); + } else { + ret = discard_ep_request(ctx, event->xfer); + } + return ret; } switch (event->type) { diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index d8e3488c079..dc7c8863435 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -12,7 +12,7 @@ #include #include -#include "usbh_internal.h" +#include "usbh_device.h" #include "usbh_ch9.h" #include @@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(usbh_shell, CONFIG_USBH_LOG_LEVEL); #define FOOBAZ_VREQ_IN 0x5c USBH_CONTROLLER_DEFINE(uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0))); - +static struct usb_device *udev; const static struct shell *ctx_shell; static void print_dev_desc(const struct shell *sh, @@ -178,30 +178,27 @@ static int cmd_bulk(const struct shell *sh, size_t argc, char **argv) { struct uhc_transfer *xfer; struct net_buf *buf; - uint8_t addr; uint8_t ep; size_t len; - addr = strtol(argv[1], NULL, 10); - ep = strtol(argv[2], NULL, 16); - len = MIN(sizeof(vreq_test_buf), strtol(argv[3], NULL, 10)); + ep = strtol(argv[1], NULL, 16); + len = MIN(sizeof(vreq_test_buf), strtol(argv[2], NULL, 10)); - xfer = uhc_xfer_alloc(uhs_ctx.dev, addr, ep, 0, 512, 10, NULL, NULL); + xfer = usbh_xfer_alloc(udev, ep, 0, 512, 10, NULL); if (!xfer) { return -ENOMEM; } - buf = uhc_xfer_buf_alloc(uhs_ctx.dev, len); + buf = usbh_xfer_buf_alloc(udev, len); if (!buf) { return -ENOMEM; } + xfer->buf = buf; if (USB_EP_DIR_IS_OUT(ep)) { net_buf_add_mem(buf, vreq_test_buf, len); } - uhc_xfer_buf_add(uhs_ctx.dev, xfer, buf); - return uhc_ep_enqueue(uhs_ctx.dev, xfer); } @@ -212,15 +209,25 @@ static int cmd_vendor_in(const struct shell *sh, (USB_REQTYPE_TYPE_VENDOR << 5); const uint8_t bRequest = FOOBAZ_VREQ_IN; const uint16_t wValue = 0x0000; + struct net_buf *buf; uint16_t wLength; - uint8_t addr; + int ret; - addr = strtol(argv[1], NULL, 10); - wLength = MIN(sizeof(vreq_test_buf), strtol(argv[2], NULL, 10)); + wLength = MIN(sizeof(vreq_test_buf), strtol(argv[1], NULL, 10)); + buf = usbh_xfer_buf_alloc(udev, wLength); + if (!buf) { + shell_print(sh, "host: Failed to allocate buffer"); + return -ENOMEM; + } - return usbh_req_setup(uhs_ctx.dev, addr, - bmRequestType, bRequest, wValue, 0, wLength, - NULL); + ret = usbh_req_setup(udev, bmRequestType, bRequest, wValue, 0, wLength, buf); + if (ret == 0) { + memcpy(vreq_test_buf, buf->data, MIN(buf->len, wLength)); + } + + usbh_xfer_buf_free(udev, buf); + + return ret; } static int cmd_vendor_out(const struct shell *sh, @@ -230,32 +237,35 @@ static int cmd_vendor_out(const struct shell *sh, (USB_REQTYPE_TYPE_VENDOR << 5); const uint8_t bRequest = FOOBAZ_VREQ_OUT; const uint16_t wValue = 0x0000; + struct net_buf *buf; uint16_t wLength; - uint8_t addr; - - addr = strtol(argv[1], NULL, 10); - wLength = MIN(sizeof(vreq_test_buf), strtol(argv[2], NULL, 10)); + int ret; - for (int i = 0; i < wLength; i++) { - vreq_test_buf[i] = i; + wLength = MIN(sizeof(vreq_test_buf), strtol(argv[1], NULL, 10)); + buf = usbh_xfer_buf_alloc(udev, wLength); + if (!buf) { + shell_print(sh, "host: Failed to allocate buffer"); + return -ENOMEM; } - return usbh_req_setup(uhs_ctx.dev, addr, - bmRequestType, bRequest, wValue, 0, wLength, - vreq_test_buf); + net_buf_add_mem(buf, &vreq_test_buf, wLength); + ret = usbh_req_setup(udev, bmRequestType, bRequest, wValue, 0, wLength, buf); + usbh_xfer_buf_free(udev, buf); + + return ret; } static int cmd_desc_device(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; + struct usb_device_descriptor desc; int err; - addr = strtol(argv[1], NULL, 10); - - err = usbh_req_desc_dev(uhs_ctx.dev, addr); + err = usbh_req_desc_dev(udev, &desc); if (err) { shell_print(sh, "host: Failed to request device descriptor"); + } else { + print_dev_desc(sh, &desc); } return err; @@ -264,17 +274,17 @@ static int cmd_desc_device(const struct shell *sh, static int cmd_desc_config(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; + struct usb_cfg_descriptor desc; uint8_t cfg; int err; - addr = strtol(argv[1], NULL, 10); - cfg = strtol(argv[2], NULL, 10); + cfg = strtol(argv[1], NULL, 10); - /* TODO: cfg is ignored, add to usbh_req_desc_cfg */ - err = usbh_req_desc_cfg(uhs_ctx.dev, addr, cfg, 128); + err = usbh_req_desc_cfg(udev, cfg, sizeof(desc), &desc); if (err) { shell_print(sh, "host: Failed to request configuration descriptor"); + } else { + print_cfg_desc(sh, &desc); } return err; @@ -284,40 +294,46 @@ static int cmd_desc_string(const struct shell *sh, size_t argc, char **argv) { const uint8_t type = USB_DESC_STRING; - uint8_t addr; + struct net_buf *buf; uint8_t id; uint8_t idx; int err; - addr = strtol(argv[1], NULL, 10); - id = strtol(argv[2], NULL, 10); - idx = strtol(argv[3], NULL, 10); + id = strtol(argv[1], NULL, 10); + idx = strtol(argv[2], NULL, 10); + + buf = usbh_xfer_buf_alloc(udev, 128); + if (!buf) { + return -ENOMEM; + } - err = usbh_req_desc(uhs_ctx.dev, addr, type, idx, id, 128); + err = usbh_req_desc(udev, type, idx, id, 128, buf); if (err) { shell_print(sh, "host: Failed to request configuration descriptor"); + } else { + shell_hexdump(ctx_shell, buf->data, buf->len); } + usbh_xfer_buf_free(udev, buf); + return err; } static int cmd_feature_set_halt(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; uint8_t ep; int err; - addr = strtol(argv[1], NULL, 10); - ep = strtol(argv[2], NULL, 16); + ep = strtol(argv[1], NULL, 16); - /* TODO: add usbh_req_set_sfs_halt(uhs_ctx.dev, 0); */ - err = usbh_req_set_sfs_rwup(uhs_ctx.dev, addr); + /* TODO: add usbh_req_set_sfs_halt(&uhs_ctx, NULL, 0); */ + err = usbh_req_set_sfs_rwup(udev); if (err) { shell_error(sh, "host: Failed to set halt feature"); } else { shell_print(sh, "host: Device 0x%02x, ep 0x%02x halt feature set", - addr, ep); + udev->addr, ep); } return err; @@ -326,16 +342,13 @@ static int cmd_feature_set_halt(const struct shell *sh, static int cmd_feature_clear_rwup(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; int err; - addr = strtol(argv[1], NULL, 10); - - err = usbh_req_clear_sfs_rwup(uhs_ctx.dev, addr); + err = usbh_req_clear_sfs_rwup(udev); if (err) { shell_error(sh, "host: Failed to clear rwup feature"); } else { - shell_print(sh, "host: Device 0x%02x, rwup feature cleared", addr); + shell_print(sh, "host: Device 0x%02x, rwup feature cleared", udev->addr); } return err; @@ -344,16 +357,13 @@ static int cmd_feature_clear_rwup(const struct shell *sh, static int cmd_feature_set_rwup(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; int err; - addr = strtol(argv[1], NULL, 10); - - err = usbh_req_set_sfs_rwup(uhs_ctx.dev, addr); + err = usbh_req_set_sfs_rwup(udev); if (err) { shell_error(sh, "host: Failed to set rwup feature"); } else { - shell_print(sh, "host: Device 0x%02x, rwup feature set", addr); + shell_print(sh, "host: Device 0x%02x, rwup feature set", udev->addr); } return err; @@ -362,19 +372,17 @@ static int cmd_feature_set_rwup(const struct shell *sh, static int cmd_feature_set_ppwr(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; uint8_t port; int err; - addr = strtol(argv[1], NULL, 10); - port = strtol(argv[2], NULL, 10); + port = strtol(argv[1], NULL, 10); - err = usbh_req_set_hcfs_ppwr(uhs_ctx.dev, addr, port); + err = usbh_req_set_hcfs_ppwr(udev, port); if (err) { shell_error(sh, "host: Failed to set ppwr feature"); } else { shell_print(sh, "host: Device 0x%02x, port %d, ppwr feature set", - addr, port); + udev->addr, port); } return err; @@ -383,19 +391,17 @@ static int cmd_feature_set_ppwr(const struct shell *sh, static int cmd_feature_set_prst(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; uint8_t port; int err; - addr = strtol(argv[1], NULL, 10); - port = strtol(argv[2], NULL, 10); + port = strtol(argv[1], NULL, 10); - err = usbh_req_set_hcfs_prst(uhs_ctx.dev, addr, port); + err = usbh_req_set_hcfs_prst(udev, port); if (err) { shell_error(sh, "host: Failed to set prst feature"); } else { shell_print(sh, "host: Device 0x%02x, port %d, prst feature set", - addr, port); + udev->addr, port); } return err; @@ -404,19 +410,17 @@ static int cmd_feature_set_prst(const struct shell *sh, static int cmd_device_config(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; uint8_t cfg; int err; - addr = strtol(argv[1], NULL, 10); - cfg = strtol(argv[2], NULL, 10); + cfg = strtol(argv[1], NULL, 10); - err = usbh_req_set_cfg(uhs_ctx.dev, addr, cfg); + err = usbh_req_set_cfg(udev, cfg); if (err) { shell_error(sh, "host: Failed to set configuration"); } else { shell_print(sh, "host: Device 0x%02x, new configuration %u", - addr, cfg); + udev->addr, cfg); } return err; @@ -425,21 +429,19 @@ static int cmd_device_config(const struct shell *sh, static int cmd_device_interface(const struct shell *sh, size_t argc, char **argv) { - uint8_t addr; uint8_t iface; uint8_t alt; int err; - addr = strtol(argv[1], NULL, 10); - iface = strtol(argv[2], NULL, 10); - alt = strtol(argv[3], NULL, 10); + iface = strtol(argv[1], NULL, 10); + alt = strtol(argv[2], NULL, 10); - err = usbh_req_set_alt(uhs_ctx.dev, addr, iface, alt); + err = usbh_req_set_alt(udev, iface, alt); if (err) { shell_error(sh, "host: Failed to set interface alternate"); } else { shell_print(sh, "host: Device 0x%02x, new %u alternate %u", - addr, iface, alt); + udev->addr, iface, alt); } return err; @@ -453,7 +455,7 @@ static int cmd_device_address(const struct shell *sh, addr = strtol(argv[1], NULL, 10); - err = usbh_req_set_address(uhs_ctx.dev, 0, addr); + err = usbh_req_set_address(udev, addr); if (err) { shell_error(sh, "host: Failed to set address"); } else { @@ -524,6 +526,7 @@ static int cmd_usbh_init(const struct shell *sh, int err; ctx_shell = sh; + udev = usbh_device_get_any(&uhs_ctx); err = usbh_init(&uhs_ctx); if (err == -EALREADY) { @@ -568,54 +571,54 @@ static int cmd_usbh_disable(const struct shell *sh, } SHELL_STATIC_SUBCMD_SET_CREATE(desc_cmds, - SHELL_CMD_ARG(device, NULL, "

", - cmd_desc_device, 2, 0), - SHELL_CMD_ARG(configuration, NULL, "
", - cmd_desc_config, 3, 0), - SHELL_CMD_ARG(string, NULL, "
", - cmd_desc_string, 4, 0), + SHELL_CMD_ARG(device, NULL, NULL, + cmd_desc_device, 1, 0), + SHELL_CMD_ARG(configuration, NULL, "", + cmd_desc_config, 2, 0), + SHELL_CMD_ARG(string, NULL, " ", + cmd_desc_string, 3, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(feature_set_cmds, - SHELL_CMD_ARG(rwup, NULL, "
", - cmd_feature_set_rwup, 2, 0), - SHELL_CMD_ARG(ppwr, NULL, "
", - cmd_feature_set_ppwr, 3, 0), - SHELL_CMD_ARG(prst, NULL, "
", - cmd_feature_set_prst, 3, 0), - SHELL_CMD_ARG(halt, NULL, "
", - cmd_feature_set_halt, 3, 0), + SHELL_CMD_ARG(rwup, NULL, NULL, + cmd_feature_set_rwup, 1, 0), + SHELL_CMD_ARG(ppwr, NULL, "", + cmd_feature_set_ppwr, 2, 0), + SHELL_CMD_ARG(prst, NULL, "", + cmd_feature_set_prst, 2, 0), + SHELL_CMD_ARG(halt, NULL, "", + cmd_feature_set_halt, 2, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(feature_clear_cmds, - SHELL_CMD_ARG(rwup, NULL, "
", - cmd_feature_clear_rwup, 2, 0), - SHELL_CMD_ARG(halt, NULL, "
", - cmd_feature_set_halt, 3, 0), + SHELL_CMD_ARG(rwup, NULL, NULL, + cmd_feature_clear_rwup, 1, 0), + SHELL_CMD_ARG(halt, NULL, "", + cmd_feature_set_halt, 2, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(device_cmds, SHELL_CMD_ARG(address, NULL, "
", cmd_device_address, 2, 0), - SHELL_CMD_ARG(config, NULL, "
", - cmd_device_config, 3, 0), - SHELL_CMD_ARG(interface, NULL, "
", - cmd_device_interface, 4, 0), + SHELL_CMD_ARG(config, NULL, "", + cmd_device_config, 2, 0), + SHELL_CMD_ARG(interface, NULL, " ", + cmd_device_interface, 3, 0), SHELL_CMD_ARG(descriptor, &desc_cmds, "descriptor request", NULL, 1, 0), SHELL_CMD_ARG(feature-set, &feature_set_cmds, "feature selector", NULL, 1, 0), SHELL_CMD_ARG(feature-clear, &feature_clear_cmds, "feature selector", NULL, 1, 0), - SHELL_CMD_ARG(vendor_in, NULL, "
", - cmd_vendor_in, 3, 0), - SHELL_CMD_ARG(vendor_out, NULL, "
", - cmd_vendor_out, 3, 0), - SHELL_CMD_ARG(bulk, NULL, "
", - cmd_bulk, 4, 0), + SHELL_CMD_ARG(vendor_in, NULL, "", + cmd_vendor_in, 2, 0), + SHELL_CMD_ARG(vendor_out, NULL, "", + cmd_vendor_out, 2, 0), + SHELL_CMD_ARG(bulk, NULL, " ", + cmd_bulk, 3, 0), SHELL_SUBCMD_SET_END ); From 2cea6e091b5eb42291390751df6abc221bf510cd Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 25 Aug 2023 19:10:52 +0200 Subject: [PATCH 1524/4498] usb: host: remove unused USBH_DEFINE_CLASS(bazfoo) from the shell With the latest change, there is no need for this structure to be used as a completion handler. Signed-off-by: Johann Fischer --- subsys/usb/host/usbh_shell.c | 118 +---------------------------------- 1 file changed, 1 insertion(+), 117 deletions(-) diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index dc7c8863435..0f5f7792bc8 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -24,6 +24,7 @@ LOG_MODULE_REGISTER(usbh_shell, CONFIG_USBH_LOG_LEVEL); USBH_CONTROLLER_DEFINE(uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0))); static struct usb_device *udev; const static struct shell *ctx_shell; +static uint8_t vreq_test_buf[1024]; static void print_dev_desc(const struct shell *sh, const struct usb_device_descriptor *const desc) @@ -57,123 +58,6 @@ static void print_cfg_desc(const struct shell *sh, shell_print(sh, "bMaxPower\t\t%u mA", desc->bMaxPower * 2); } -static void print_desc(const struct shell *sh, const struct net_buf *const buf) -{ - struct usb_desc_header *head = (void *)buf->data; - - if (buf->len < sizeof(struct usb_desc_header)) { - return; - } - - switch (head->bDescriptorType) { - case USB_DESC_DEVICE: { - struct usb_device_descriptor *desc = (void *)buf->data; - - if (buf->len < sizeof(struct usb_device_descriptor)) { - shell_hexdump(ctx_shell, buf->data, buf->len); - break; - } - - desc->bcdUSB = sys_le16_to_cpu(desc->bcdUSB); - desc->idVendor = sys_le16_to_cpu(desc->idVendor); - desc->idProduct = sys_le16_to_cpu(desc->idProduct); - desc->bcdDevice = sys_le16_to_cpu(desc->bcdDevice); - print_dev_desc(sh, desc); - break; - } - case USB_DESC_CONFIGURATION: { - struct usb_cfg_descriptor *desc = (void *)buf->data; - - if (buf->len < sizeof(struct usb_cfg_descriptor)) { - shell_hexdump(ctx_shell, buf->data, buf->len); - break; - } - - desc->wTotalLength = sys_le16_to_cpu(desc->wTotalLength); - print_cfg_desc(sh, desc); - break; - } - default: - shell_hexdump(ctx_shell, buf->data, buf->len); - break; - } -} - -static int bazfoo_request(struct usbh_contex *const ctx, - struct uhc_transfer *const xfer, - int err) -{ - const struct device *dev = ctx->dev; - - shell_info(ctx_shell, "host: transfer finished %p, err %d", xfer, err); - - if (xfer->buf) { - /* - * FIXME: We don not distinguish the context - * of the request and always try to print it - * as descriptor first. If it is not a known descriptor, - * we show a hexdump in any case. - * This is just simple enough for first steps and will - * be revised with coming peripheral device management. - */ - if (xfer->ep == USB_CONTROL_EP_IN) { - print_desc(ctx_shell, xfer->buf); - } else { - shell_hexdump(ctx_shell, xfer->buf->data, xfer->buf->len); - } - - uhc_xfer_buf_free(dev, xfer->buf); - } - - return uhc_xfer_free(dev, xfer); -} - -static int bazfoo_connected(struct usbh_contex *const ctx) -{ - shell_info(ctx_shell, "host: USB device connected"); - - return 0; -} - -static int bazfoo_removed(struct usbh_contex *const ctx) -{ - shell_info(ctx_shell, "host: USB device removed"); - - return 0; -} - -static int bazfoo_rwup(struct usbh_contex *const ctx) -{ - shell_info(ctx_shell, "host: Bus remote wakeup event"); - - return 0; -} - -static int bazfoo_suspended(struct usbh_contex *const ctx) -{ - shell_info(ctx_shell, "host: Bus suspended"); - - return 0; -} - -static int bazfoo_resumed(struct usbh_contex *const ctx) -{ - shell_info(ctx_shell, "host: Bus resumed"); - - return 0; -} - -USBH_DEFINE_CLASS(bazfoo) = { - .request = bazfoo_request, - .connected = bazfoo_connected, - .removed = bazfoo_removed, - .rwup = bazfoo_rwup, - .suspended = bazfoo_suspended, - .resumed = bazfoo_resumed, -}; - -static uint8_t vreq_test_buf[1024]; - static int cmd_bulk(const struct shell *sh, size_t argc, char **argv) { struct uhc_transfer *xfer; From dd43679fdfdb617ef435c945912d10683f296489 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 25 Aug 2023 19:36:34 +0200 Subject: [PATCH 1525/4498] usb: host: add command to get the current device configuration Add command to get the current device configuration. Revise the shell part to have a set|get configuration subcommands. Signed-off-by: Johann Fischer --- subsys/usb/host/usbh_ch9.c | 24 ++++++++++++++++++++++++ subsys/usb/host/usbh_ch9.h | 3 +++ subsys/usb/host/usbh_shell.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/subsys/usb/host/usbh_ch9.c b/subsys/usb/host/usbh_ch9.c index 55bc5a97bc5..37c5a13ec67 100644 --- a/subsys/usb/host/usbh_ch9.c +++ b/subsys/usb/host/usbh_ch9.c @@ -194,6 +194,30 @@ int usbh_req_set_cfg(struct usb_device *const udev, return ret; } +int usbh_req_get_cfg(struct usb_device *const udev, + uint8_t *const cfg) +{ + const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_HOST << 7; + const uint8_t bRequest = USB_SREQ_GET_CONFIGURATION; + const uint16_t wLength = 1; + struct net_buf *buf; + int ret; + + buf = usbh_xfer_buf_alloc(udev, wLength); + if (!buf) { + return -ENOMEM; + } + + ret = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf); + if (ret == 0 && buf->len == wLength) { + *cfg = buf->data[0]; + } + + usbh_xfer_buf_free(udev, buf); + + return ret; +} + int usbh_req_set_alt(struct usb_device *const udev, const uint8_t iface, const uint8_t alt) { diff --git a/subsys/usb/host/usbh_ch9.h b/subsys/usb/host/usbh_ch9.h index a07ca7bd8a1..26c21c83715 100644 --- a/subsys/usb/host/usbh_ch9.h +++ b/subsys/usb/host/usbh_ch9.h @@ -44,6 +44,9 @@ int usbh_req_set_address(struct usb_device *const udev, int usbh_req_set_cfg(struct usb_device *const udev, const uint8_t cfg); +int usbh_req_get_cfg(struct usb_device *const udev, + uint8_t *const cfg); + int usbh_req_set_sfs_rwup(struct usb_device *const udev); int usbh_req_clear_sfs_rwup(struct usb_device *const udev); diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index 0f5f7792bc8..0525bdeccef 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -291,8 +291,8 @@ static int cmd_feature_set_prst(const struct shell *sh, return err; } -static int cmd_device_config(const struct shell *sh, - size_t argc, char **argv) +static int cmd_config_set(const struct shell *sh, + size_t argc, char **argv) { uint8_t cfg; int err; @@ -310,6 +310,23 @@ static int cmd_device_config(const struct shell *sh, return err; } +static int cmd_config_get(const struct shell *sh, + size_t argc, char **argv) +{ + uint8_t cfg; + int err; + + err = usbh_req_get_cfg(udev, &cfg); + if (err) { + shell_error(sh, "host: Failed to set configuration"); + } else { + shell_print(sh, "host: Device 0x%02x, current configuration %u", + udev->addr, cfg); + } + + return err; +} + static int cmd_device_interface(const struct shell *sh, size_t argc, char **argv) { @@ -484,11 +501,19 @@ SHELL_STATIC_SUBCMD_SET_CREATE(feature_clear_cmds, SHELL_SUBCMD_SET_END ); +SHELL_STATIC_SUBCMD_SET_CREATE(config_cmds, + SHELL_CMD_ARG(get, NULL, NULL, + cmd_config_get, 1, 0), + SHELL_CMD_ARG(set, NULL, "", + cmd_config_set, 2, 0), + SHELL_SUBCMD_SET_END +); + SHELL_STATIC_SUBCMD_SET_CREATE(device_cmds, SHELL_CMD_ARG(address, NULL, "
", cmd_device_address, 2, 0), - SHELL_CMD_ARG(config, NULL, "", - cmd_device_config, 2, 0), + SHELL_CMD_ARG(config, &config_cmds, "get|set configuration", + NULL, 1, 0), SHELL_CMD_ARG(interface, NULL, " ", cmd_device_interface, 3, 0), SHELL_CMD_ARG(descriptor, &desc_cmds, "descriptor request", From d18cb6c189382ff85c0f75557c71fb5f18a71d01 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 29 Sep 2023 11:54:09 +0200 Subject: [PATCH 1526/4498] usb: host: usbh_ch9: add ASSERT for unresolved data stage conditions Do not explicitly check buf parameter in usbh_req_setup() but add ASSERT to check unresolved data stage conditions. Signed-off-by: Johann Fischer --- subsys/usb/host/usbh_ch9.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/usb/host/usbh_ch9.c b/subsys/usb/host/usbh_ch9.c index 37c5a13ec67..f8f587a43c3 100644 --- a/subsys/usb/host/usbh_ch9.c +++ b/subsys/usb/host/usbh_ch9.c @@ -60,7 +60,9 @@ int usbh_req_setup(struct usb_device *const udev, memcpy(xfer->setup_pkt, &req, sizeof(req)); - if (wLength && buf != NULL) { + __ASSERT((buf != NULL && wLength) || (buf == NULL && !wLength), + "Unresolved conditions for data stage"); + if (wLength) { ret = usbh_xfer_buf_add(udev, xfer, buf); if (ret) { goto buf_alloc_err; From ed7d56f04ee280867d4ef344f1922231679545ed Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 16 Sep 2022 11:46:24 +0200 Subject: [PATCH 1527/4498] tests: usb: add test for new USB device support This is initial patch to add tests for new USB device support. The test uses USB host support and virtual USB bus by default, but should work on real hardware as well. For now, only the Get Configuration and Set Interface requests are tested by default. More tests will follow. Signed-off-by: Johann Fischer --- tests/subsys/usb/device_next/CMakeLists.txt | 11 ++ .../device_next/boards/native_posix.overlay | 19 +++ .../device_next/boards/qemu_cortex_m3.overlay | 17 ++ tests/subsys/usb/device_next/prj.conf | 12 ++ tests/subsys/usb/device_next/src/main.c | 160 ++++++++++++++++++ tests/subsys/usb/device_next/testcase.yaml | 9 + 6 files changed, 228 insertions(+) create mode 100644 tests/subsys/usb/device_next/CMakeLists.txt create mode 100644 tests/subsys/usb/device_next/boards/native_posix.overlay create mode 100644 tests/subsys/usb/device_next/boards/qemu_cortex_m3.overlay create mode 100644 tests/subsys/usb/device_next/prj.conf create mode 100644 tests/subsys/usb/device_next/src/main.c create mode 100644 tests/subsys/usb/device_next/testcase.yaml diff --git a/tests/subsys/usb/device_next/CMakeLists.txt b/tests/subsys/usb/device_next/CMakeLists.txt new file mode 100644 index 00000000000..b9e9a6b4ea3 --- /dev/null +++ b/tests/subsys/usb/device_next/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_usb_device_next) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/usb/host) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/usb/device_next/boards/native_posix.overlay b/tests/subsys/usb/device_next/boards/native_posix.overlay new file mode 100644 index 00000000000..d352f555c8c --- /dev/null +++ b/tests/subsys/usb/device_next/boards/native_posix.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &zephyr_udc0; + +/ { + zephyr_uhc0: uhc_vrt0 { + compatible = "zephyr,uhc-virtual"; + + zephyr_udc0: udc_vrt0 { + compatible = "zephyr,udc-virtual"; + num-bidir-endpoints = <8>; + maximum-speed = "high-speed"; + }; + }; +}; diff --git a/tests/subsys/usb/device_next/boards/qemu_cortex_m3.overlay b/tests/subsys/usb/device_next/boards/qemu_cortex_m3.overlay new file mode 100644 index 00000000000..4dd05c0fe99 --- /dev/null +++ b/tests/subsys/usb/device_next/boards/qemu_cortex_m3.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr_uhc0: uhc_vrt0 { + compatible = "zephyr,uhc-virtual"; + + zephyr_udc0: udc_vrt0 { + compatible = "zephyr,udc-virtual"; + num-bidir-endpoints = <8>; + maximum-speed = "high-speed"; + }; + }; +}; diff --git a/tests/subsys/usb/device_next/prj.conf b/tests/subsys/usb/device_next/prj.conf new file mode 100644 index 00000000000..6025cf69cd5 --- /dev/null +++ b/tests/subsys/usb/device_next/prj.conf @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=y +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_USBD_LOOPBACK_CLASS=y + +CONFIG_UHC_DRIVER=y +CONFIG_USB_HOST_STACK=y diff --git a/tests/subsys/usb/device_next/src/main.c b/tests/subsys/usb/device_next/src/main.c new file mode 100644 index 00000000000..50c20c2fbf3 --- /dev/null +++ b/tests/subsys/usb/device_next/src/main.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "usbh_ch9.h" +#include "usbh_device.h" + +#include +LOG_MODULE_REGISTER(usb_test, LOG_LEVEL_INF); + +#define TEST_DEFAULT_INTERFACE 0 +#define TEST_DEFAULT_ALTERNATE 1 + +USBD_CONFIGURATION_DEFINE(test_config, + USB_SCD_SELF_POWERED | USB_SCD_REMOTE_WAKEUP, + 200); + +USBD_DESC_LANG_DEFINE(test_lang); +USBD_DESC_STRING_DEFINE(test_mfg, "ZEPHYR", 1); +USBD_DESC_STRING_DEFINE(test_product, "Zephyr USB Test", 2); +USBD_DESC_STRING_DEFINE(test_sn, "0123456789ABCDEF", 3); + +USBD_DEVICE_DEFINE(test_usbd, + DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), + 0x2fe3, 0xffff); + +USBH_CONTROLLER_DEFINE(uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0))); + +/* Get Configuration request test */ +ZTEST(device_next, test_get_configuration) +{ + struct usb_device *udev; + uint8_t cfg = 0; + int err; + + udev = usbh_device_get_any(&uhs_ctx); + err = usbh_req_get_cfg(udev, &cfg); + + switch (udev->state) { + case USB_STATE_DEFAULT: + /* Not specified, expect protocol error */ + zassert_equal(err, -EPIPE, "Transfer status is not a protocol error"); + break; + case USB_STATE_ADDRESSED: + /* TODO: Expect zero value */ + zassert_equal(err, 0, "Transfer status is an error"); + zassert_equal(cfg, 0, "Device not in address state"); + break; + case USB_STATE_CONFIGURED: + /* TODO: Expect non-zero valid configuration value */ + zassert_equal(err, 0, "Transfer status is an error"); + zassert_not_equal(cfg, 0, "Device not in configured state"); + break; + default: + break; + } +} + +/* Set Interface request test */ +ZTEST(device_next, test_set_interface) +{ + struct usb_device *udev; + int err; + + udev = usbh_device_get_any(&uhs_ctx); + err = usbh_req_set_alt(udev, TEST_DEFAULT_INTERFACE, + TEST_DEFAULT_ALTERNATE); + + switch (udev->state) { + case USB_STATE_DEFAULT: + /* Not specified, expect protocol error */ + case USB_STATE_ADDRESSED: + /* Expect protocol error */ + zassert_equal(err, -EPIPE, "Transfer status is not a protocol error"); + break; + case USB_STATE_CONFIGURED: + /* TODO */ + default: + break; + } +} + +static void *usb_test_enable(void) +{ + struct usb_device *udev; + int err; + + err = usbh_init(&uhs_ctx); + zassert_equal(err, 0, "Failed to initialize USB host"); + + err = usbh_enable(&uhs_ctx); + zassert_equal(err, 0, "Failed to enable USB host"); + + err = uhc_bus_reset(uhs_ctx.dev); + zassert_equal(err, 0, "Failed to signal bus reset"); + + err = uhc_bus_resume(uhs_ctx.dev); + zassert_equal(err, 0, "Failed to signal bus resume"); + + err = uhc_sof_enable(uhs_ctx.dev); + zassert_equal(err, 0, "Failed to enable SoF generator"); + + LOG_INF("Host controller enabled"); + + err = usbd_add_descriptor(&test_usbd, &test_lang); + zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err); + + err = usbd_add_descriptor(&test_usbd, &test_mfg); + zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err); + + err = usbd_add_descriptor(&test_usbd, &test_product); + zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err); + + err = usbd_add_descriptor(&test_usbd, &test_sn); + zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err); + + err = usbd_add_configuration(&test_usbd, &test_config); + zassert_equal(err, 0, "Failed to add configuration (%d)"); + + err = usbd_register_class(&test_usbd, "loopback_0", 1); + zassert_equal(err, 0, "Failed to register loopback_0 class (%d)"); + + err = usbd_init(&test_usbd); + zassert_equal(err, 0, "Failed to initialize device support"); + + err = usbd_enable(&test_usbd); + zassert_equal(err, 0, "Failed to enable device support"); + + LOG_INF("Device support enabled"); + udev = usbh_device_get_any(&uhs_ctx); + udev->state = USB_STATE_DEFAULT; + + return NULL; +} + +static void usb_test_shutdown(void *f) +{ + int err; + + err = usbd_disable(&test_usbd); + zassert_equal(err, 0, "Failed to enable device support"); + + err = usbd_shutdown(&test_usbd); + zassert_equal(err, 0, "Failed to shutdown device support"); + + LOG_INF("Device support disabled"); + + err = usbh_disable(&uhs_ctx); + zassert_equal(err, 0, "Failed to disable USB host"); + + LOG_INF("Host controller disabled"); +} + +ZTEST_SUITE(device_next, NULL, usb_test_enable, NULL, NULL, usb_test_shutdown); diff --git a/tests/subsys/usb/device_next/testcase.yaml b/tests/subsys/usb/device_next/testcase.yaml new file mode 100644 index 00000000000..47e6aa3a0a1 --- /dev/null +++ b/tests/subsys/usb/device_next/testcase.yaml @@ -0,0 +1,9 @@ +tests: + usb.device_next: + depends_on: usb_device + tags: usb + platform_allow: + - native_posix + - qemu_cortex_m3 + integration_platforms: + - native_posix From 29521a4bdd4e3917ea0f3e2f12371cd9a8607911 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 1 Oct 2023 10:22:53 +0300 Subject: [PATCH 1528/4498] posix: Fix release name length in struct utsname The release name length forgot to take into account the optional EXTRAVERSION string (e.g. rc1). Signed-off-by: Johan Hedberg --- include/zephyr/posix/sys/utsname.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/posix/sys/utsname.h b/include/zephyr/posix/sys/utsname.h index f00497f17f3..32046f431d8 100644 --- a/include/zephyr/posix/sys/utsname.h +++ b/include/zephyr/posix/sys/utsname.h @@ -13,7 +13,7 @@ extern "C" { struct utsname { char sysname[sizeof("Zephyr")]; char nodename[CONFIG_POSIX_UNAME_NODENAME_LEN + 1]; - char release[sizeof("99.99.99")]; + char release[sizeof("99.99.99-rc1")]; char version[CONFIG_POSIX_UNAME_VERSION_LEN + 1]; char machine[sizeof(CONFIG_ARCH)]; }; From 021003c5c08a7277aef0c84876c8041dd46f392a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 1 Oct 2023 19:31:02 +0300 Subject: [PATCH 1529/4498] samples: tracing: Skip broken percepio test case The percepio build seems to have a bug and fail whenever the major, minor or patchlevel numeric value is 0: Invalid version specified: major: 3, minor: 5, patchlevel: 0 Disable the sample until a proper fix is available. Signed-off-by: Johan Hedberg --- samples/subsys/tracing/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index dda98638a58..973188add69 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -66,6 +66,7 @@ tests: platform_allow: native_posix extra_args: CONF_FILE="prj_native_posix_ctf.conf" sample.tracing.percepio: + skip: true platform_allow: frdm_k64f extra_args: CONF_FILE="prj_percepio.conf" modules: From 1fc16e65656e742fbe0adc89e0fdf685c51525a5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 1 Oct 2023 09:39:49 +0300 Subject: [PATCH 1530/4498] release: Zephyr 3.5.0-rc1 Bump the version to 3.5.0-rc1. Signed-off-by: Johan Hedberg --- VERSION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 2d7dfb83b49..091da5fcbd2 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 3 -VERSION_MINOR = 4 -PATCHLEVEL = 99 +VERSION_MINOR = 5 +PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = +EXTRAVERSION = rc1 From d044dfe7e9a2198534ca7b233b814f277f6b64c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Fri, 29 Sep 2023 09:06:27 +0700 Subject: [PATCH 1531/4498] tests: error_hook: skip test_catch_fatal_error for Armv8-R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip `test_catch_fatal_error` test case for Armv8-R because divide by zero trapping is not supported on this architecture. Fixes #63268 Signed-off-by: Manuel Argüelles --- tests/ztest/error_hook/src/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ztest/error_hook/src/main.c b/tests/ztest/error_hook/src/main.c index 7940f3c9009..cde770e5f9f 100644 --- a/tests/ztest/error_hook/src/main.c +++ b/tests/ztest/error_hook/src/main.c @@ -115,14 +115,16 @@ __no_optimization static void trigger_fault_divide_zero(void) * For the Cortex-M0, M0+, M23 (CONFIG_ARMV6_M_ARMV8_M_BASELINE) * which does not include a divide instruction, the test is skipped, * and there will be no hardware exception for that. + * For ARMv8-R, divide by zero trapping is not supported in hardware. */ #if (defined(CONFIG_SOC_SERIES_MPS2) && defined(CONFIG_QEMU_TARGET)) || \ (defined(CONFIG_SOC_SERIES_MPS3) && defined(CONFIG_QEMU_TARGET)) || \ defined(CONFIG_BOARD_QEMU_CORTEX_A53) || defined(CONFIG_SOC_QEMU_ARC) || \ defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) || \ defined(CONFIG_BOARD_QEMU_CORTEX_R5) || \ - defined(CONFIG_BOARD_FVP_BASER_AEMV8R) || defined(CONFIG_BOARD_FVP_BASE_REVC_2XAEMV8A) || \ - defined(CONFIG_BOARD_FVP_BASER_AEMV8R_AARCH32) || defined(CONFIG_SOC_NSIM_EM11D) + defined(CONFIG_ARMV8_R) || defined(CONFIG_AARCH32_ARMV8_R) || \ + defined(CONFIG_BOARD_FVP_BASE_REVC_2XAEMV8A) || \ + defined(CONFIG_SOC_NSIM_EM11D) ztest_test_skip(); #endif } From 7a14830d85587d22bcf812f1ec6931c3c35ce02f Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 22 Jun 2023 22:49:14 +0530 Subject: [PATCH 1532/4498] Bluetooth: Controller: Remove HCI ISO data with invalid status Remove incorrect implementation of HCI ISO data with invalid status. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/lll/lll_central_iso.c | 97 ++----------------- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 43 -------- 2 files changed, 8 insertions(+), 132 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 46360ef88d7..936087369f1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -845,7 +845,6 @@ static void isr_rx(void *param) struct lll_conn_iso_group *cig_lll; struct lll_conn *next_conn_lll; uint8_t phy; - uint8_t bn; /* Fetch next CIS */ /* TODO: Use a new ull_conn_iso_lll_stream_get_active_by_group() @@ -861,18 +860,6 @@ static void isr_rx(void *param) goto isr_rx_done; } - /* Adjust sn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } - /* Get reference to ACL context */ next_conn_lll = ull_conn_lll_get(next_cis_lll->acl_handle); @@ -940,45 +927,17 @@ static void isr_rx(void *param) cis_lll = old_cis_lll; } - /* Generate ISO Data Invalid Status */ - bn = cis_lll->rx.bn_curr; - while (bn <= cis_lll->rx.bn) { - struct node_rx_iso_meta *iso_meta; - struct node_rx_pdu *status_node_rx; - - /* Ensure there is always one free for reception - * of ISO PDU by the radio h/w DMA, hence peek - * for two available ISO PDU when using one for - * generating invalid ISO data. - */ - status_node_rx = ull_iso_pdu_rx_alloc_peek(2U); - if (!status_node_rx) { - break; - } - - status_node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; - status_node_rx->hdr.handle = cis_lll->handle; - iso_meta = &status_node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = (cis_lll->event_count * - cis_lll->rx.bn) + (bn - 1U); - iso_meta->timestamp = - HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + - radio_tmr_ready_restore(); - iso_meta->timestamp %= - HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); - iso_meta->status = 1U; - - ull_iso_pdu_rx_alloc(); - iso_rx_put(status_node_rx->hdr.link, status_node_rx); - - bn++; + /* Adjust sn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); } -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) - if (bn != cis_lll->rx.bn_curr) { - iso_rx_sched(); + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); } -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ /* Reset indices for the next CIS */ se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */ @@ -1176,7 +1135,6 @@ static void isr_done(void *param) { struct lll_conn_iso_stream *cis_lll; struct event_done_extra *e; - uint8_t bn; lll_isr_status_reset(); @@ -1195,45 +1153,6 @@ static void isr_done(void *param) lll_flush_rx(cis_lll); } - /* Generate ISO Data Invalid Status */ - bn = cis_lll->rx.bn_curr; - while (bn <= cis_lll->rx.bn) { - struct node_rx_iso_meta *iso_meta; - struct node_rx_pdu *node_rx; - - /* Ensure there is always one free for reception of ISO PDU by - * the radio h/w DMA, hence peek for two available ISO PDU when - * using one for generating invalid ISO data. - */ - node_rx = ull_iso_pdu_rx_alloc_peek(2U); - if (!node_rx) { - break; - } - - node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; - node_rx->hdr.handle = cis_lll->handle; - iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = (cis_lll->event_count * - cis_lll->rx.bn) + (bn - 1U); - iso_meta->timestamp = - HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + - radio_tmr_ready_restore(); - iso_meta->timestamp %= - HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); - iso_meta->status = 1U; - - ull_iso_pdu_rx_alloc(); - iso_rx_put(node_rx->hdr.link, node_rx); - - bn++; - } - -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) - if (bn != cis_lll->rx.bn_curr) { - iso_rx_sched(); - } -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ - e = ull_event_done_extra_get(); LL_ASSERT(e); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 13238c081cf..3bbdb5fbf90 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -1229,7 +1229,6 @@ static void isr_done(void *param) { struct lll_conn_iso_stream *cis_lll; struct event_done_extra *e; - uint8_t bn; lll_isr_status_reset(); @@ -1242,48 +1241,6 @@ static void isr_done(void *param) lll_flush_rx(cis_lll); } - /* Generate ISO Data Invalid Status */ - bn = cis_lll->rx.bn_curr; - while (bn <= cis_lll->rx.bn) { - struct node_rx_iso_meta *iso_meta; - struct node_rx_pdu *node_rx; - - node_rx = ull_iso_pdu_rx_alloc_peek(2U); - if (!node_rx) { - break; - } - - node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; - node_rx->hdr.handle = cis_lll->handle; - iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = (cis_lll->event_count * - cis_lll->rx.bn) + (bn - 1U); - if (trx_performed_bitmask) { - iso_meta->timestamp = cis_lll->offset + - HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + - radio_tmr_aa_restore() - cis_offset_first - - addr_us_get(cis_lll->rx.phy); - } else { - iso_meta->timestamp = cis_lll->offset + - HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + - radio_tmr_ready_restore() - cis_offset_first; - } - iso_meta->timestamp %= - HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); - iso_meta->status = 1U; - - ull_iso_pdu_rx_alloc(); - iso_rx_put(node_rx->hdr.link, node_rx); - - bn++; - } - -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) - if (bn != cis_lll->rx.bn_curr) { - iso_rx_sched(); - } -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ - e = ull_event_done_extra_get(); LL_ASSERT(e); From 7fa77a67fc1c924899982bbcde3d87c80b3e13cb Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 17 Jun 2023 05:05:42 +0530 Subject: [PATCH 1533/4498] Bluetooth: Controller: Use of payload_count for Flush Timeout Use of payload_count for supporting flush timeout in Central and Peripheral ISO Lower Link Layer. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/ll_sw/lll_conn_iso.h | 3 +- .../ll_sw/nordic/lll/lll_central_iso.c | 379 ++++++++++------ .../ll_sw/nordic/lll/lll_peripheral_iso.c | 405 +++++++++++------- 3 files changed, 503 insertions(+), 284 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 7fdf6bf48d5..9822066f513 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -16,8 +16,7 @@ struct lll_conn_iso_stream_rxtx { uint64_t bn:4; /* Burst number (BN) */ uint64_t phy:3; /* PHY */ uint64_t rfu:1; - uint8_t bn_curr:4; /* Current burst number */ - + uint8_t bn_curr:4; /* Current burst number */ #if defined(CONFIG_BT_CTLR_LE_ENC) struct ccm ccm; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 936087369f1..d4f4c8c3262 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -40,14 +40,15 @@ #include "hal/debug.h" static int init_reset(void); -static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll); -static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll); static int prepare_cb(struct lll_prepare_param *p); static void abort_cb(struct lll_prepare_param *prepare_param, void *param); static void isr_tx(void *param); static void isr_rx(void *param); static void isr_prepare_subevent(void *param); static void isr_done(void *param); +static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); +static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll); +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); static uint16_t next_cis_chan_remap_idx; static uint16_t next_cis_chan_prn_s; @@ -118,24 +119,6 @@ static int init_reset(void) return 0; } -static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll) -{ - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - uint8_t sn_update = cis_lll->tx.bn + 1U - cis_lll->tx.bn_curr; - - /* we'll re-use sn_update when implementing flush timeout */ - cis_lll->sn += sn_update; -} - -static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll) -{ - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - uint8_t nesn_update = cis_lll->rx.bn + 1U - cis_lll->rx.bn_curr; - - /* we'll re-use sn_update when implementing flush timeout */ - cis_lll->nesn += nesn_update; -} - static int prepare_cb(struct lll_prepare_param *p) { struct lll_conn_iso_group *cig_lll = p->param; @@ -197,24 +180,10 @@ static int prepare_cb(struct lll_prepare_param *p) /* Reset accumulated latencies */ cig_lll->latency_prepare = 0U; - /* Adjust the SN and NESN for skipped CIG events */ - if (cis_lll->event_count) { - uint16_t cis_lazy; - - if (lazy > cis_lll->event_count) { - cis_lazy = lazy - cis_lll->event_count; - } else { - cis_lazy = lazy; - } - - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn += cis_lll->tx.bn * cis_lazy; - cis_lll->nesn += cis_lll->rx.bn * cis_lazy; - } - se_curr = 1U; - cis_lll->tx.bn_curr = 1U; - cis_lll->rx.bn_curr = 1U; + + /* Adjust the SN and NESN for skipped CIG events */ + payload_count_lazy(cis_lll, lazy); /* Start setting up of Radio h/w */ radio_reset(); @@ -248,7 +217,8 @@ static int prepare_cb(struct lll_prepare_param *p) struct node_tx_iso *node_tx; memq_link_t *link; - payload_count = cis_lll->event_count * cis_lll->tx.bn; + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; do { link = memq_peek(cis_lll->memq_tx.head, @@ -399,33 +369,12 @@ static int prepare_cb(struct lll_prepare_param *p) do { cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { - if (cis_lll->event_count) { - uint16_t cis_lazy; - - if (lazy > cis_lll->event_count) { - cis_lazy = lazy - cis_lll->event_count; - } else { - cis_lazy = lazy; - } + /* Adjust sn and nesn for skipped CIG events */ + payload_count_lazy(cis_lll, lazy); - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn += cis_lll->tx.bn * cis_lazy; - cis_lll->nesn += cis_lll->rx.bn * cis_lazy; - - /* Adjust sn and nesn for canceled events */ - if (err) { - /* Adjust sn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } - } + /* Adjust sn and nesn for canceled events */ + if (err) { + payload_count_flush_or_inc_on_close(cis_lll); } } } while (cis_lll); @@ -450,9 +399,21 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) /* NOTE: This is not a prepare being cancelled */ if (!prepare_param) { + struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; + struct lll_conn_iso_group *cig_lll; cis_lll = ull_conn_iso_lll_stream_get(cis_handle_curr); + cig_lll = param; + + /* Adjust the SN, NESN and payload_count on abort for CISes */ + do { + next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, + &cis_handle_curr); + if (next_cis_lll && next_cis_lll->active) { + payload_count_flush_or_inc_on_close(next_cis_lll); + } + } while (next_cis_lll); /* Perform event abort here. * After event has been cleanly aborted, clean up resources @@ -508,8 +469,8 @@ static void isr_tx(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = (cis_lll->event_count * cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + payload_count = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; cis_lll->rx.ccm.counter = payload_count; @@ -652,7 +613,9 @@ static void isr_tx(void *param) cis_lll = next_cis_lll; /* Tx Ack stale ISO Data */ - payload_count = cis_lll->event_count * cis_lll->tx.bn; + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; + do { link = memq_peek(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, @@ -687,8 +650,6 @@ static void isr_tx(void *param) static void isr_rx(void *param) { struct lll_conn_iso_stream *cis_lll; - struct node_rx_pdu *node_rx; - struct pdu_cis *pdu_rx; uint8_t ack_pending; uint8_t trx_done; uint8_t crc_ok; @@ -714,6 +675,8 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done) { + payload_count_flush(cis_lll); + goto isr_rx_next_subevent; } @@ -723,23 +686,23 @@ static void isr_rx(void *param) /* Set the bit corresponding to CIS index */ trx_performed_bitmask |= (1U << LL_CIS_IDX_FROM_HANDLE(cis_lll->handle)); - /* Get reference to received PDU */ - node_rx = ull_iso_pdu_rx_alloc_peek(1U); - LL_ASSERT(node_rx); + if (crc_ok) { + struct node_rx_pdu *node_rx; + struct pdu_cis *pdu_rx; - pdu_rx = (void *)node_rx->pdu; + /* Get reference to received PDU */ + node_rx = ull_iso_pdu_rx_alloc_peek(1U); + LL_ASSERT(node_rx); + pdu_rx = (void *)node_rx->pdu; - if (crc_ok) { /* Tx ACK */ - if (pdu_rx->nesn != cis_lll->sn) { - /* Increment sequence number */ + if ((pdu_rx->nesn != cis_lll->sn) && (cis_lll->tx.bn_curr <= cis_lll->tx.bn)) { cis_lll->sn++; - - /* Increment burst number */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - - cis_lll->tx.bn_curr++; - + cis_lll->tx.bn_curr++; + if ((cis_lll->tx.bn_curr > cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; } /* TODO: Implement early Tx Ack. Currently Tx Ack @@ -755,7 +718,6 @@ static void isr_rx(void *param) ull_iso_pdu_rx_alloc_peek(2U)) { struct node_rx_iso_meta *iso_meta; - /* Increment next expected sequence number */ cis_lll->nesn++; #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -786,9 +748,8 @@ static void isr_rx(void *param) node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; node_rx->hdr.handle = cis_lll->handle; iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = (cis_lll->event_count * - cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + iso_meta->payload_number = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_ready_restore(); @@ -803,36 +764,23 @@ static void isr_rx(void *param) iso_rx_sched(); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ - /* Increment burst number */ cis_lll->rx.bn_curr++; + if ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } /* Need to be acked */ ack_pending = 1U; - - /* Handle NULL PDU indication received */ - } else if (pdu_rx->npi) { - /* Source could not send ISO data, increment NESN as if - * we received and expect to receive the next PDU in the - * burst. - */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - /* Increment next expected serial number */ - cis_lll->nesn++; - - /* Increment burst number */ - cis_lll->rx.bn_curr++; - } - - /* Not NPI, or more than the BN, or no free Rx ISO PDU buffers. - */ - } else { - /* Do nothing, ignore the Rx buffer */ } /* Close Isochronous Event */ cie = cie || pdu_rx->cie; } + payload_count_flush(cis_lll); + /* Close Isochronous Event */ cie = cie || ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && (cis_lll->tx.bn_curr > cis_lll->tx.bn) && @@ -893,7 +841,8 @@ static void isr_rx(void *param) old_cis_lll = cis_lll; cis_lll = next_cis_lll; - payload_count = cis_lll->event_count * cis_lll->tx.bn; + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; do { link = memq_peek(cis_lll->memq_tx.head, @@ -927,22 +876,10 @@ static void isr_rx(void *param) cis_lll = old_cis_lll; } - /* Adjust sn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } + payload_count_flush_or_inc_on_close(cis_lll); /* Reset indices for the next CIS */ se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */ - next_cis_lll->tx.bn_curr = 1U; - next_cis_lll->rx.bn_curr = 1U; #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) radio_tx_power_set(next_conn_lll->tx_pwr_lvl); @@ -1001,8 +938,7 @@ static void isr_prepare_subevent(void *param) memq_link_t *link; payload_index = cis_lll->tx.bn_curr - 1U; - payload_count = cis_lll->event_count * cis_lll->tx.bn + - payload_index; + payload_count = cis_lll->tx.payload_count + payload_index; link = memq_peek_n(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, payload_index, (void **)&node_tx); @@ -1141,17 +1077,7 @@ static void isr_done(void *param) /* Get reference to CIS LLL context */ cis_lll = param; - /* Adjust sn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } + payload_count_flush_or_inc_on_close(cis_lll); e = ull_event_done_extra_get(); LL_ASSERT(e); @@ -1166,3 +1092,190 @@ static void isr_done(void *param) lll_isr_cleanup(param); } + +static void payload_count_flush(struct lll_conn_iso_stream *cis_lll) +{ + if (cis_lll->tx.bn) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + if ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == + (cis_lll->event_count + 1U)) && (u <= se_curr) && + (((cis_lll->tx.bn_curr < cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) <= cis_lll->event_count)) || + ((cis_lll->tx.bn_curr == cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn++; + cis_lll->tx.bn_curr++; + if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + } + } + + if (cis_lll->rx.bn) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + if ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == + (cis_lll->event_count + 1U)) && (u <= se_curr) && + (((cis_lll->rx.bn_curr < cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) <= cis_lll->event_count)) || + ((cis_lll->rx.bn_curr == cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + } + } +} + +static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll) +{ + if (cis_lll->tx.bn) { + uint64_t payload_count; + uint8_t u; + + if (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.bn_curr) > + (cis_lll->event_count + cis_lll->tx.bn)) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + + goto payload_count_flush_or_inc_on_close_rx; + } + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + while ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == + (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn++; + cis_lll->tx.bn_curr++; + if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + } + } + +payload_count_flush_or_inc_on_close_rx: + if (cis_lll->rx.bn) { + uint64_t payload_count; + uint8_t u; + + if (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.bn_curr) > + (cis_lll->event_count + cis_lll->rx.bn)) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + + return; + } + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + while ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == + (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + } + } +} + +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) +{ + if (cis_lll->tx.bn) { + uint16_t tx_lazy; + + tx_lazy = lazy; + while (tx_lazy--) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + while (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < + (cis_lll->event_count + 1U)) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn++; + cis_lll->tx.bn_curr++; + if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + } + } + } + + if (cis_lll->rx.bn) { + while (lazy--) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + while (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < + (cis_lll->event_count + 1U)) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + + payload_count = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + } + } + } +} diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 3bbdb5fbf90..75af765f9d0 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -49,8 +49,9 @@ static void isr_prepare_subevent(void *param); static void isr_prepare_subevent_next_cis(void *param); static void isr_prepare_subevent_common(void *param); static void isr_done(void *param); -static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll); -static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll); +static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); +static void payload_count_rx_flush_or_txrx_inc(struct lll_conn_iso_stream *cis_lll); +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); static uint8_t next_chan_use; static uint16_t data_chan_id; @@ -61,7 +62,6 @@ static uint32_t trx_performed_bitmask; static uint16_t cis_offset_first; static uint16_t cis_handle_curr; static uint8_t se_curr; -static uint8_t has_tx; #if defined(CONFIG_BT_CTLR_LE_ENC) static uint8_t mic_state; @@ -135,24 +135,6 @@ static int init_reset(void) return 0; } -static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll) -{ - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - uint8_t sn_update = cis_lll->tx.bn + 1U - cis_lll->tx.bn_curr; - - /* TODO we'll re-use sn_update when implementing flush timeout */ - cis_lll->sn += sn_update; -} - -static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll) -{ - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - uint8_t nesn_update = cis_lll->rx.bn + 1U - cis_lll->rx.bn_curr; - - /* TODO we'll re-use nesn_update when implementing flush timeout */ - cis_lll->nesn += nesn_update; -} - static int prepare_cb(struct lll_prepare_param *p) { struct lll_conn_iso_group *cig_lll = p->param; @@ -225,14 +207,10 @@ static int prepare_cb(struct lll_prepare_param *p) EVENT_US_TO_US_FRAC(cig_lll->window_widening_max_us); } - /* Adjust sn and nesn for skipped CIG events */ - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn += (cis_lll->tx.bn * lazy); - cis_lll->nesn += cis_lll->rx.bn * lazy; - se_curr = 1U; - cis_lll->rx.bn_curr = 1U; - has_tx = 0U; + + /* Adjust sn and nesn for skipped CIG events */ + payload_count_lazy(cis_lll, lazy); /* Start setting up of Radio h/w */ radio_reset(); @@ -260,8 +238,9 @@ static int prepare_cb(struct lll_prepare_param *p) uint64_t payload_cnt; uint8_t pkt_flags; - payload_cnt = (cis_lll->event_count * cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + payload_cnt = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; + cis_lll->rx.ccm.counter = payload_cnt; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -372,9 +351,10 @@ static int prepare_cb(struct lll_prepare_param *p) /* Adjust the SN and NESN for skipped CIG events */ uint16_t cis_handle = cis_handle_curr; - while (true) { - /* FIXME: Update below implementation when supporting Flush Timeout */ - payload_count = cis_lll->event_count * cis_lll->tx.bn; + do { + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; + do { link = memq_peek(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, (void **)&tx); @@ -392,26 +372,22 @@ static int prepare_cb(struct lll_prepare_param *p) } } while (link); - cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + do { + cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + } while (cis_lll && !cis_lll->active); + if (!cis_lll) { break; } - if (cis_lll->active) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn += cis_lll->tx.bn * lazy; - cis_lll->nesn += cis_lll->rx.bn * lazy; - - /* Adjust sn and nesn for canceled events */ - if (err) { - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } - } + /* Adjust sn and nesn for skipped CIG events */ + payload_count_lazy(cis_lll, lazy); + + /* Adjust sn and nesn for canceled events */ + if (err) { + payload_count_rx_flush_or_txrx_inc(cis_lll); } - }; + } while (cis_lll); /* Return if prepare callback cancelled */ if (err) { @@ -433,24 +409,21 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) /* NOTE: This is not a prepare being cancelled */ if (!prepare_param) { - struct lll_conn_iso_group *cig_lll = param; + struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; + struct lll_conn_iso_group *cig_lll; - cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, NULL); - - /* FIXME: Consider Flush Timeout when resetting current burst number */ - if (!has_tx) { - has_tx = 1U; + cis_lll = ull_conn_iso_lll_stream_get(cis_handle_curr); + cig_lll = param; - /* Adjust nesn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); + /* Adjust the SN, NESN and payload_count on abort for CISes */ + do { + next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, + &cis_handle_curr); + if (next_cis_lll && next_cis_lll->active) { + payload_count_rx_flush_or_txrx_inc(next_cis_lll); } - - /* Set to last burst number in previous event */ - cis_lll->tx.bn_curr = cis_lll->tx.bn; - } + } while (next_cis_lll); /* Perform event abort here. * After event has been cleanly aborted, clean up resources @@ -500,20 +473,9 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done) { - /* FIXME: Consider Flush Timeout when resetting current burst number */ - if (!has_tx) { - has_tx = 1U; - - /* Adjust nesn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Start transmitting new burst */ - cis_lll->tx.bn_curr = cis_lll->tx.bn; - } + payload_count_flush(cis_lll); + /* Next subevent or next CIS */ if (se_curr < cis_lll->nse) { radio_isr_set(isr_prepare_subevent, param); } else { @@ -562,17 +524,20 @@ static void isr_rx(void *param) pdu_rx = (void *)node_rx->pdu; /* Tx ACK */ - if (pdu_rx->nesn != cis_lll->sn) { - /* Increment sequence number */ + if ((pdu_rx->nesn != cis_lll->sn) && (cis_lll->tx.bn_curr <= cis_lll->tx.bn)) { cis_lll->sn++; - - /* Increment burst number */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - cis_lll->tx.bn_curr++; + cis_lll->tx.bn_curr++; + if ((cis_lll->tx.bn_curr > cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) < + cis_lll->event_count)) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; } - /* TODO: Tx Ack */ - + /* TODO: Implement early Tx Ack. Currently Tx Ack + * generated as stale Tx Ack when payload count + * has elapsed. + */ } /* Handle valid ISO data Rx */ @@ -582,7 +547,6 @@ static void isr_rx(void *param) ull_iso_pdu_rx_alloc_peek(2U)) { struct node_rx_iso_meta *iso_meta; - /* Increment next expected sequence number */ cis_lll->nesn++; #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -614,9 +578,8 @@ static void isr_rx(void *param) node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; node_rx->hdr.handle = cis_lll->handle; iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = (cis_lll->event_count * - cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + iso_meta->payload_number = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; iso_meta->timestamp = cis_lll->offset + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_aa_restore() - cis_offset_first - @@ -632,46 +595,19 @@ static void isr_rx(void *param) iso_rx_sched(); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ - /* Increment burst number */ cis_lll->rx.bn_curr++; - - /* Handle NULL PDU indication received */ - } else if (pdu_rx->npi) { - /* Source could not send ISO data, increment NESN as if - * we received and expect to receive the next PDU in the - * burst. - */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - /* Increment next expected serial number */ - cis_lll->nesn++; - - /* Increment burst number */ - cis_lll->rx.bn_curr++; + if ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; } - - /* Not NPI, or more than the BN, or no free Rx ISO PDU buffers. - */ - } else { - /* Do nothing, ignore the Rx buffer */ } /* Close Isochronous Event */ cie = cie || pdu_rx->cie; } - /* FIXME: Consider Flush Timeout when resetting current burst number */ - if (!has_tx) { - has_tx = 1U; - - /* Adjust nesn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); - } - - /* Start transmitting new burst */ - cis_lll->tx.bn_curr = 1U; - } + payload_count_flush(cis_lll); /* Close Isochronous Event */ cie = cie || ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && @@ -696,8 +632,7 @@ static void isr_rx(void *param) memq_link_t *link; payload_index = cis_lll->tx.bn_curr - 1U; - payload_count = cis_lll->event_count * cis_lll->tx.bn + - payload_index; + payload_count = cis_lll->tx.payload_count + payload_index; link = memq_peek_n(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, payload_index, (void **)&tx); @@ -801,6 +736,7 @@ static void isr_rx(void *param) &data_chan_prn_s, &data_chan_remap_idx); } else { + struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_group *cig_lll; uint16_t event_counter; uint16_t cis_handle; @@ -809,34 +745,34 @@ static void isr_rx(void *param) cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); cis_handle = cis_handle_curr; do { - cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); - } while (cis_lll && !cis_lll->active); + next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + } while (next_cis_lll && !next_cis_lll->active); - if (!cis_lll) { + if (!next_cis_lll) { /* ISO Event Done */ radio_isr_set(isr_done, param); return; } + payload_count_rx_flush_or_txrx_inc(cis_lll); + cis_handle_curr = cis_handle; /* Event counter value, 0-15 bit of cisEventCounter */ - event_counter = cis_lll->event_count; + event_counter = next_cis_lll->event_count; /* Calculate the radio channel to use for next CIS ISO event */ - data_chan_id = lll_chan_id(cis_lll->access_addr); + data_chan_id = lll_chan_id(next_cis_lll->access_addr); next_chan_use = lll_chan_iso_event(event_counter, data_chan_id, conn_lll->data_chan_map, conn_lll->data_chan_count, &data_chan_prn_s, &data_chan_remap_idx); - /* Reset indices for the next CIS */ - se_curr = 0U; /* isr_tx() will increase se_curr */ - cis_lll->tx.bn_curr = 1U; /* FIXME: may be this should be previous event value? */ - cis_lll->rx.bn_curr = 1U; - has_tx = 0U; + /* Next CIS, se_curr is incremented in isr_tx() */ + cis_lll = next_cis_lll; + se_curr = 0U; } /* Schedule next subevent reception */ @@ -894,8 +830,9 @@ static void isr_tx(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = (cis_lll->event_count * cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + payload_count = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; + cis_lll->rx.ccm.counter = payload_count; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -996,6 +933,7 @@ static void isr_tx(void *param) static void next_cis_prepare(void *param) { + struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; struct lll_conn_iso_group *cig_lll; uint16_t cis_handle; @@ -1005,12 +943,13 @@ static void next_cis_prepare(void *param) /* Check for next active CIS */ cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); + next_cis_lll = cis_lll; cis_handle = cis_handle_curr; do { - cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); - } while (cis_lll && !cis_lll->active); + next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + } while (next_cis_lll && !next_cis_lll->active); - if (!cis_lll) { + if (!next_cis_lll) { /* ISO Event Done */ radio_isr_set(isr_done, param); @@ -1019,7 +958,7 @@ static void next_cis_prepare(void *param) cis_handle_curr = cis_handle; - radio_isr_set(isr_prepare_subevent_next_cis, cis_lll); + radio_isr_set(isr_prepare_subevent_next_cis, next_cis_lll); } static void isr_prepare_subevent(void *param) @@ -1071,11 +1010,8 @@ static void isr_prepare_subevent_next_cis(void *param) &data_chan_prn_s, &data_chan_remap_idx); - /* Reset indices for the next CIS */ - se_curr = 0U; /* isr_prepare_subevent_common() will increase se_curr */ - cis_lll->tx.bn_curr = 1U; /* FIXME: may be this should be previous event value? */ - cis_lll->rx.bn_curr = 1U; - has_tx = 0U; + /* se_curr is incremented in isr_prepare_subevent_common() */ + se_curr = 0U; isr_prepare_subevent_common(param); } @@ -1111,8 +1047,9 @@ static void isr_prepare_subevent_common(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = (cis_lll->event_count * cis_lll->rx.bn) + - (cis_lll->rx.bn_curr - 1U); + payload_count = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; + cis_lll->rx.ccm.counter = payload_count; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -1235,11 +1172,7 @@ static void isr_done(void *param) /* Get reference to CIS LLL context */ cis_lll = param; - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); - } + payload_count_rx_flush_or_txrx_inc(cis_lll); e = ull_event_done_extra_get(); LL_ASSERT(e); @@ -1275,3 +1208,177 @@ static void isr_done(void *param) lll_isr_cleanup(param); } + +static void payload_count_flush(struct lll_conn_iso_stream *cis_lll) +{ + if (cis_lll->tx.bn) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + while (((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == + (cis_lll->event_count + 1U)) && (u < se_curr))) && + (((cis_lll->tx.bn_curr < cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) <= cis_lll->event_count)) || + ((cis_lll->tx.bn_curr == cis_lll->tx.bn) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn++; + cis_lll->tx.bn_curr++; + if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + } + } + + if (cis_lll->rx.bn) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + if ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == + (cis_lll->event_count + 1U)) && (u <= se_curr) && + (((cis_lll->rx.bn_curr < cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) <= cis_lll->event_count)) || + ((cis_lll->rx.bn_curr == cis_lll->rx.bn) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + } + } +} + +static void payload_count_rx_flush_or_txrx_inc(struct lll_conn_iso_stream *cis_lll) +{ + if (cis_lll->tx.bn) { + if (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.bn_curr) > + (cis_lll->event_count + cis_lll->tx.bn)) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + } + + if (cis_lll->rx.bn) { + uint64_t payload_count; + uint8_t u; + + if (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.bn_curr) > + (cis_lll->event_count + cis_lll->rx.bn)) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + + return; + } + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + while ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == + (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + } + } +} + +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) +{ + if (cis_lll->tx.bn && lazy) { + uint16_t tx_lazy; + + tx_lazy = lazy; + while (tx_lazy--) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + while (((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == + (cis_lll->event_count + 1U)) && (u < (cis_lll->nse + 1U)))) && + ((cis_lll->tx.payload_count / cis_lll->tx.bn) < + cis_lll->event_count)) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn++; + cis_lll->tx.bn_curr++; + if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { + cis_lll->tx.payload_count += cis_lll->tx.bn; + cis_lll->tx.bn_curr = 1U; + } + + payload_count = cis_lll->tx.payload_count + + cis_lll->tx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * + (cis_lll->tx.bn - 1U - + (payload_count % cis_lll->tx.bn))); + } + } + } + + if (cis_lll->rx.bn) { + while (lazy--) { + uint64_t payload_count; + uint8_t u; + + payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + while (((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < + (cis_lll->event_count + 1U)) || + ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == + (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) && + ((cis_lll->rx.payload_count / cis_lll->rx.bn) < + cis_lll->event_count)) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->nesn++; + cis_lll->rx.bn_curr++; + if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { + cis_lll->rx.payload_count += cis_lll->rx.bn; + cis_lll->rx.bn_curr = 1U; + } + + payload_count = cis_lll->rx.payload_count + + cis_lll->rx.bn_curr - 1U; + u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * + (cis_lll->rx.bn - 1U - + (payload_count % cis_lll->rx.bn))); + } + } + } +} From e3ecab3142031383783764fbb9d9016931127e4a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 22 Jun 2023 22:36:05 +0530 Subject: [PATCH 1534/4498] Bluetooth: Controller: Fix ISO Data timestamp when FT > 1 Fix ISO data timestamp to reflect the SDU reference point and not the ISO event anchor point when PDUs received after retransmissions. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/lll_conn_iso.h | 3 +++ .../controller/ll_sw/nordic/lll/lll_central_iso.c | 7 ++++++- .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 5 +++++ subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 1 + subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 9822066f513..0321b96f638 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -77,6 +77,9 @@ struct lll_conn_iso_group { uint8_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ uint8_t paused:1; /* 1: CIG is paused */ + /* ISO interval to calculate timestamp under FT > 1 */ + uint32_t iso_interval_us; + /* Accumulates LLL prepare callback latencies */ uint16_t latency_prepare; uint16_t latency_event; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index d4f4c8c3262..4bf44a42cd9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -716,6 +716,7 @@ static void isr_rx(void *param) (cis_lll->rx.bn_curr <= cis_lll->rx.bn) && (pdu_rx->sn == cis_lll->nesn) && ull_iso_pdu_rx_alloc_peek(2U)) { + struct lll_conn_iso_group *cig_lll; struct node_rx_iso_meta *iso_meta; cis_lll->nesn++; @@ -753,6 +754,10 @@ static void isr_rx(void *param) iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_ready_restore(); + cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); + iso_meta->timestamp -= (cis_lll->event_count - + (cis_lll->rx.payload_count / cis_lll->rx.bn)) * + cig_lll->iso_interval_us; iso_meta->timestamp %= HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); iso_meta->status = 0U; @@ -788,8 +793,8 @@ static void isr_rx(void *param) isr_rx_next_subevent: if (cie || (se_curr == cis_lll->nse)) { - struct lll_conn_iso_stream *old_cis_lll; struct lll_conn_iso_stream *next_cis_lll; + struct lll_conn_iso_stream *old_cis_lll; struct lll_conn_iso_group *cig_lll; struct lll_conn *next_conn_lll; uint8_t phy; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 75af765f9d0..25401f5564e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -545,6 +545,7 @@ static void isr_rx(void *param) (cis_lll->rx.bn_curr <= cis_lll->rx.bn) && (pdu_rx->sn == cis_lll->nesn) && ull_iso_pdu_rx_alloc_peek(2U)) { + struct lll_conn_iso_group *cig_lll; struct node_rx_iso_meta *iso_meta; cis_lll->nesn++; @@ -584,6 +585,10 @@ static void isr_rx(void *param) HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_aa_restore() - cis_offset_first - addr_us_get(cis_lll->rx.phy); + cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); + iso_meta->timestamp -= (cis_lll->event_count - + (cis_lll->rx.payload_count / cis_lll->rx.bn)) * + cig_lll->iso_interval_us; iso_meta->timestamp %= HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); iso_meta->status = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 8c516826e06..62a684bbfa9 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -254,6 +254,7 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) } iso_interval_us = cig->iso_interval * ISO_INT_UNIT_US; + cig->lll.iso_interval_us = iso_interval_us; lll_hdr_init(&cig->lll, cig); max_se_length = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index eeef778734b..a707341f41c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -191,6 +191,7 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cig->iso_interval = sys_le16_to_cpu(req->iso_interval); iso_interval_us = cig->iso_interval * CONN_INT_UNIT_US; + cig->lll.iso_interval_us = iso_interval_us; cig->cig_id = req->cig_id; cig->lll.handle = LLL_HANDLE_INVALID; From 61d00467b469e816dfd6933bfef038422ddf36c7 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 8 Jun 2023 10:17:33 +0530 Subject: [PATCH 1535/4498] Bluetooth: Controller: Option to ignore Tx ISO Data Packet Seq Num Kconfig option to turn off ISO Data Packet Sequence Number use to place the ISO Data in the correct radio event, instead simply buffer it to next radio event. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 9 +- subsys/bluetooth/controller/hci/hci.c | 108 +++++++++++++++--- .../controller/ll_sw/ull_central_iso.c | 3 + .../controller/ll_sw/ull_conn_iso_types.h | 4 + .../controller/ll_sw/ull_peripheral_iso.c | 3 + 5 files changed, 111 insertions(+), 16 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 3f6f3c10382..a7dade7a1db 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -499,7 +499,8 @@ config BT_CTLR_SCAN_ENABLE_STRICT config BT_CTLR_ISOAL_SN_STRICT bool "Enforce Strict Tx ISO Data Sequence Number use" - depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO + depends on !BT_CTLR_ISOAL_PSN_IGNORE && (BT_CTLR_ADV_ISO || \ + BT_CTLR_CONN_ISO) default y help Enforce strict sequencing of released payloads based on the TX SDU's @@ -517,6 +518,12 @@ config BT_CTLR_ISOAL_SN_STRICT dropped. This will result in better delivery of data to the receiver but at the cost of creating skews in the received stream of SDUs. +config BT_CTLR_ISOAL_PSN_IGNORE + bool "Ignore Tx ISO Data Packet Sequence Number use" + depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO + help + Ignore the use of Tx ISO Data Packet Sequence Number. + config BT_CTLR_ZLI bool "Use Zero Latency IRQs" depends on ZERO_LATENCY_IRQS diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 0adbf5ff70c..b2c95271b2c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5657,8 +5657,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) struct bt_hci_iso_data_hdr *iso_data_hdr; struct isoal_sdu_tx sdu_frag_tx; struct bt_hci_iso_hdr *iso_hdr; - struct ll_iso_datapath *dp_in; - struct ll_iso_stream_hdr *hdr; uint32_t *time_stamp; uint16_t handle; uint8_t pb_flag; @@ -5668,8 +5666,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) iso_data_hdr = NULL; *evt = NULL; - hdr = NULL; - dp_in = NULL; if (buf->len < sizeof(*iso_hdr)) { LOG_ERR("No HCI ISO header"); @@ -5747,16 +5743,49 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * data path */ } else if (IS_CIS_HANDLE(handle)) { - struct ll_conn_iso_stream *cis = - ll_iso_stream_connected_get(handle); + struct ll_conn_iso_stream *cis; + struct ll_conn_iso_group *cig; + struct ll_iso_stream_hdr *hdr; + struct ll_iso_datapath *dp_in; + + cis = ll_iso_stream_connected_get(handle); if (!cis) { return -EINVAL; } - struct ll_conn_iso_group *cig = cis->group; - uint8_t event_offset; + cig = cis->group; - hdr = &(cis->hdr); +#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) + uint64_t event_count; + uint64_t pkt_seq_num; + + /* Catch up local pkt_seq_num with internal pkt_seq_num */ + event_count = cis->lll.event_count; + pkt_seq_num = event_count + 1U; + if (!(pb_flag & 0x01) && + (((pkt_seq_num - cis->pkt_seq_num) & + BIT64_MASK(39)) <= BIT64_MASK(38))) { + cis->pkt_seq_num = pkt_seq_num; + } else { + pkt_seq_num = cis->pkt_seq_num; + } + + /* Pre-increment, for next ISO data packet seq num comparison */ + if (pb_flag & 0x10) { + cis->pkt_seq_num++; + } + + /* Target next event to avoid overlapping with current event */ + pkt_seq_num++; + sdu_frag_tx.target_event = pkt_seq_num; + sdu_frag_tx.grp_ref_point = + isoal_get_wrapped_time_us(cig->cig_ref_point, + ((pkt_seq_num - event_count) * + cig->iso_interval * + ISO_INT_UNIT_US)); + +#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + uint8_t event_offset; /* We must ensure sufficient time for ISO-AL to fragment SDU and * deliver PDUs to the TX queue. By checking ull_ref_get, we @@ -5780,11 +5809,15 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) } sdu_frag_tx.target_event = cis->lll.event_count + event_offset; - sdu_frag_tx.grp_ref_point = isoal_get_wrapped_time_us(cig->cig_ref_point, - (event_offset * cig->iso_interval * - ISO_INT_UNIT_US)); + sdu_frag_tx.grp_ref_point = + isoal_get_wrapped_time_us(cig->cig_ref_point, + (event_offset * + cig->iso_interval * + ISO_INT_UNIT_US)); +#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ /* Get controller's input data path for CIS */ + hdr = &(cis->hdr); dp_in = hdr->datapath_in; if (!dp_in || dp_in->path_id != BT_HCI_DATAPATH_ID_HCI) { LOG_ERR("Input data path not set for HCI"); @@ -5817,8 +5850,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) struct ll_adv_iso_set *adv_iso; struct lll_adv_iso *lll_iso; uint16_t stream_handle; - uint8_t target_event; - uint8_t event_offset; uint16_t slen; /* FIXME: Code only expects header present */ @@ -5844,6 +5875,53 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) return -EINVAL; } + lll_iso = &adv_iso->lll; + +#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) + uint64_t event_count; + uint64_t pkt_seq_num; + + /* Catch up local pkt_seq_num with internal pkt_seq_num */ + event_count = lll_iso->payload_count / lll_iso->bn; + pkt_seq_num = event_count; + if (!(pb_flag & 0x01) && + (((pkt_seq_num - stream->pkt_seq_num) & + BIT64_MASK(39)) <= BIT64_MASK(38))) { + stream->pkt_seq_num = pkt_seq_num; + } else { + pkt_seq_num = stream->pkt_seq_num; + } + + /* Pre-increment, for next ISO data packet seq num comparison */ + if (pb_flag & 0x10) { + stream->pkt_seq_num++; + } + + /* Target next event to avoid overlapping with current event */ + /* FIXME: Implement ISO Tx ack generation early in done compared + * to currently only in prepare. I.e. to ensure upper + * layer has the number of completed packet before the + * next BIG event, so as to supply new ISO data packets. + * Without which upper layers need extra buffers to + * buffer next ISO data packet. + * + * Enable below increment once early Tx ack is + * implemented. + * + * pkt_seq_num++; + */ + sdu_frag_tx.target_event = pkt_seq_num; + sdu_frag_tx.grp_ref_point = + isoal_get_wrapped_time_us(adv_iso->big_ref_point, + (((pkt_seq_num + 1U) - + event_count) * + lll_iso->iso_interval * + ISO_INT_UNIT_US)); + +#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + uint8_t target_event; + uint8_t event_offset; + /* Determine the target event and the first event offset after * datapath setup. * event_offset mitigates the possibility of first SDU being @@ -5861,7 +5939,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * BIG event by incrementing the previous elapsed big_ref_point * by one additional ISO interval. */ - lll_iso = &adv_iso->lll; target_event = lll_iso->payload_count / lll_iso->bn; event_offset = ull_ref_get(&adv_iso->ull) ? 0U : 1U; event_offset += lll_iso->latency_prepare; @@ -5872,6 +5949,7 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) ((event_offset + 1U) * lll_iso->iso_interval * ISO_INT_UNIT_US)); +#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ /* Start Fragmentation */ /* FIXME: need to ensure ISO-AL returns proper isoal_status. diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 62a684bbfa9..474b8d0dbe9 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -883,6 +883,9 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ cis->central.instant = instant; +#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) + cis->pkt_seq_num = 0U; +#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h index e8ca29da7af..39cee21d0b1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h @@ -48,6 +48,10 @@ struct ll_conn_iso_stream { */ uint8_t terminate_reason; uint8_t cis_id; + +#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) + uint64_t pkt_seq_num:39; +#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ }; struct ll_conn_iso_group { diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index a707341f41c..843bf877935 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -326,6 +326,9 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, cis->sync_delay = sys_get_le24(ind->cis_sync_delay); cis->offset = cis_offset; memcpy(cis->lll.access_addr, ind->aa, sizeof(ind->aa)); +#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) + cis->pkt_seq_num = 0U; +#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; From 2935d3b731d551230c0dcdf13afed61f0716d601 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Aug 2023 14:04:35 +0530 Subject: [PATCH 1536/4498] tests: bsim: Bluetooth: Test RTN=2, FT=2, Per skip 2 SE in Controller Test RTN=2, FT=2 in Controller with 2 subevents dropped by peripheral. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 9 +++++- tests/bsim/bluetooth/ll/cis/Kconfig | 19 +++++++++++++ .../overlay-acl_first_ft_per_skip_2_se.conf | 9 ++++++ tests/bsim/bluetooth/ll/cis/prj.conf | 1 + tests/bsim/bluetooth/ll/cis/src/main.c | 28 ++++++++++++++----- ...onnected_iso_acl_first_ft_per_skip_2_se.sh | 24 ++++++++++++++++ tests/bsim/bluetooth/ll/compile.sh | 1 + 7 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf create mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 25401f5564e..c33c82d4c70 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -472,7 +472,14 @@ static void isr_rx(void *param) cis_lll = param; /* No Rx */ - if (!trx_done) { + if (!trx_done || +#if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) + ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT) && + ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || + (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT + 1U)) && + ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || +#endif + false) { payload_count_flush(cis_lll); /* Next subevent or next CIS */ diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig b/tests/bsim/bluetooth/ll/cis/Kconfig index b59a46be4fc..532a26f5d52 100644 --- a/tests/bsim/bluetooth/ll/cis/Kconfig +++ b/tests/bsim/bluetooth/ll/cis/Kconfig @@ -16,6 +16,25 @@ config TEST_MULTIPLE_PERIPERAL_CIS help Multiple Peripheral CIS establishment. +config TEST_FT_SKIP_SUBEVENTS + bool + help + Skip central and/or peripheral subevent reception to test flush + timeout implementation. + +config TEST_FT_PER_SKIP_SUBEVENTS + bool "Skip peripheral role subevents to test Flush Timeout" + select TEST_FT_SKIP_SUBEVENTS + help + Skip peripheral role subevent reception to test flush timeout + implementation. + +config TEST_FT_PER_SKIP_EVENTS_COUNT + int "Skip peripheral ISO events count, all subevents in them" + depends on TEST_FT_PER_SKIP_SUBEVENTS + help + Skip peripheral ISO events count where all subevents are skipped. + config BT_CTLR_SCAN_UNRESERVED default y if TEST_CONNECT_ACL_FIRST help diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf new file mode 100644 index 00000000000..bfbe36115f5 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf @@ -0,0 +1,9 @@ +CONFIG_TEST_USE_LEGACY_ADVERTISING=n +CONFIG_TEST_CONNECT_ACL_FIRST=y +CONFIG_TEST_FT_PER_SKIP_SUBEVENTS=y +CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT=1 +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_ISO_MAX_CHAN=1 +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/prj.conf b/tests/bsim/bluetooth/ll/cis/prj.conf index 0b6b764393b..a4d3c3e8c5f 100644 --- a/tests/bsim/bluetooth/ll/cis/prj.conf +++ b/tests/bsim/bluetooth/ll/cis/prj.conf @@ -13,6 +13,7 @@ CONFIG_BT_MAX_CONN=9 CONFIG_BT_ISO_MAX_CHAN=9 CONFIG_BT_ISO_TX_BUF_COUNT=18 CONFIG_BT_ISO_TX_MTU=120 +CONFIG_BT_ISO_RX_MTU=120 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_RX_SIZE=255 diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index a9538e3e9c6..720adc16ef9 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -53,6 +53,7 @@ static bt_addr_le_t peer_addr; #define ISO_INTERVAL_US 10000U #define ISO_LATENCY_MS DIV_ROUND_UP(ISO_INTERVAL_US, USEC_PER_MSEC) +#define ISO_LATENCY_FT_MS 20U #define BT_CONN_US_TO_INTERVAL(t) ((uint16_t)((t) * 4U / 5U / USEC_PER_MSEC)) @@ -103,7 +104,7 @@ static bt_addr_le_t peer_addr; #define NAME_LEN 30 -#define BUF_ALLOC_TIMEOUT (30) /* milliseconds */ +#define BUF_ALLOC_TIMEOUT (40) /* milliseconds */ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL); @@ -300,8 +301,11 @@ static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *in expected_seq_num[index] = seq_num; } - expected_seq_num[index]++; + expected_seq_num[index] += 1U; +#if defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) + expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U); +#endif } else if (expected_seq_num[index] && expected_seq_num[index] < SEQ_NUM_MAX) { FAIL("%s: Invalid ISO data after valid ISO data reception.\n" @@ -361,7 +365,11 @@ static void test_cis_central(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx[i].phy = BT_GAP_LE_PHY_2M; - iso_tx[i].rtn = 0U; + if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { + iso_tx[i].rtn = 2U; + } else { + iso_tx[i].rtn = 0U; + } iso_tx[i].path = NULL; iso_qos[i].tx = &iso_tx[i]; @@ -381,7 +389,11 @@ static void test_cis_central(void) cig_param.sca = BT_GAP_SCA_UNKNOWN; cig_param.packing = 0U; cig_param.framing = 0U; - cig_param.latency = ISO_LATENCY_MS; + if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { + cig_param.latency = ISO_LATENCY_FT_MS; + } else { + cig_param.latency = ISO_LATENCY_MS; + } cig_param.interval = ISO_INTERVAL_US; printk("Create CIG..."); @@ -404,7 +416,7 @@ static void test_cis_central(void) uint8_t conn_index; uint8_t chan; - printk("Start scanning..."); + printk("Start scanning (%d)...", i); err = bt_le_scan_start(BT_LE_SCAN_CUSTOM, NULL); if (err) { FAIL("Could not start scan: %d\n", err); @@ -510,7 +522,7 @@ static void test_cis_central(void) ret = bt_iso_chan_send(&iso_chan[chan], buf, seq_num, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { - FAIL("Unable to broadcast data on channel %u" + FAIL("Unable to send data on channel %u" " : %d\n", chan, ret); net_buf_unref(buf); return; @@ -522,7 +534,7 @@ static void test_cis_central(void) } } - k_sleep(K_MSEC(100)); + k_sleep(K_MSEC(1000)); for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { printk("ISO disconnect channel %u...", chan); @@ -587,6 +599,8 @@ static int iso_accept(const struct bt_iso_accept_info *info, *chan = &iso_chan_p[chan_count]; chan_count++; + printk("Accepted on channel %p\n", *chan); + return 0; } diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh new file mode 100755 index 00000000000..307d865a117 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, +# FT=2, skips 2 subevents in the peripheral +simulation_id="connected_iso_acl_first_ft_per_skip_2_se" +verbosity_level=2 +EXECUTE_TIMEOUT=60 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_2_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_2_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 2369192e0cc..28ca40b322c 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -39,6 +39,7 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-legacy_adv_acl_first.conf c app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group_acl_first.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From a7d2fdd02bc54872c2803416d33f48bf6837afc6 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Aug 2023 14:04:35 +0530 Subject: [PATCH 1537/4498] tests: bsim: Bluetooth: Test RTN=2, FT=2, Per skip 4 SE in Controller Test RTN=2, FT=2 in Controller with 4 subevents dropped by peripheral. Signed-off-by: Vinayak Kariappa Chettimada --- .../overlay-acl_first_ft_per_skip_4_se.conf | 9 +++++++ ...onnected_iso_acl_first_ft_per_skip_4_se.sh | 24 +++++++++++++++++++ tests/bsim/bluetooth/ll/compile.sh | 1 + 3 files changed, 34 insertions(+) create mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_4_se.conf create mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_4_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_4_se.conf new file mode 100644 index 00000000000..f1c78198c87 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_4_se.conf @@ -0,0 +1,9 @@ +CONFIG_TEST_USE_LEGACY_ADVERTISING=n +CONFIG_TEST_CONNECT_ACL_FIRST=y +CONFIG_TEST_FT_PER_SKIP_SUBEVENTS=y +CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT=2 +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_ISO_MAX_CHAN=1 +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh new file mode 100755 index 00000000000..2bb7eeb4f31 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, +# FT=2, skips 4 subevents in the peripheral +simulation_id="connected_iso_acl_first_ft_per_skip_4_se" +verbosity_level=2 +EXECUTE_TIMEOUT=60 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_4_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_4_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 28ca40b322c..9a8d66a17f2 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -40,6 +40,7 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group_acl_first.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_4_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From 291cd03818e909c20fed720c4773c82c2eabbd71 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Aug 2023 14:04:35 +0530 Subject: [PATCH 1538/4498] tests: bsim: Bluetooth: Test RTN=2, FT=2, Cen skip 2 SE in Controller Test RTN=2, FT=2 in Controller with 2 subevents dropped by central. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/lll/lll_central_iso.c | 9 +- tests/bsim/bluetooth/ll/cis/Kconfig | 13 ++ .../overlay-acl_first_ft_cen_skip_2_se.conf | 9 ++ tests/bsim/bluetooth/ll/cis/src/main.c | 114 +++++++++++++++++- ...onnected_iso_acl_first_ft_cen_skip_2_se.sh | 24 ++++ tests/bsim/bluetooth/ll/compile.sh | 1 + 6 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf create mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 4bf44a42cd9..9c2184b9942 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -674,7 +674,14 @@ static void isr_rx(void *param) cis_lll = param; /* No Rx */ - if (!trx_done) { + if (!trx_done || +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT) && + ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || + (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT + 1U)) && + ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || +#endif + false) { payload_count_flush(cis_lll); goto isr_rx_next_subevent; diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig b/tests/bsim/bluetooth/ll/cis/Kconfig index 532a26f5d52..6076f88ae3c 100644 --- a/tests/bsim/bluetooth/ll/cis/Kconfig +++ b/tests/bsim/bluetooth/ll/cis/Kconfig @@ -35,6 +35,19 @@ config TEST_FT_PER_SKIP_EVENTS_COUNT help Skip peripheral ISO events count where all subevents are skipped. +config TEST_FT_CEN_SKIP_SUBEVENTS + bool "Skip central role subevents to test Flush Timeout" + select TEST_FT_SKIP_SUBEVENTS + help + Skip central role subevent reception to test flush timeout + implementation. + +config TEST_FT_CEN_SKIP_EVENTS_COUNT + int "Skip central ISO events count, all subevents in them" + depends on TEST_FT_CEN_SKIP_SUBEVENTS + help + Skip central ISO events count where all subevents are skipped. + config BT_CTLR_SCAN_UNRESERVED default y if TEST_CONNECT_ACL_FIRST help diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf new file mode 100644 index 00000000000..194a23ffec6 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf @@ -0,0 +1,9 @@ +CONFIG_TEST_USE_LEGACY_ADVERTISING=n +CONFIG_TEST_CONNECT_ACL_FIRST=y +CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS=y +CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT=1 +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_ISO_MAX_CHAN=1 +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index 720adc16ef9..15e102981d6 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -296,15 +296,19 @@ static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *in seq_num = sys_get_le32(buf->data); if (info->flags & BT_ISO_FLAGS_VALID) { if (seq_num != expected_seq_num[index]) { - FAIL("ISO data miss match, expected %u actual %u\n", - expected_seq_num[index], seq_num); + if (expected_seq_num[index]) { + FAIL("ISO data miss match, expected %u actual %u\n", + expected_seq_num[index], seq_num); + } expected_seq_num[index] = seq_num; } expected_seq_num[index] += 1U; -#if defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) +#if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U); +#elif defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + expected_seq_num[index] += ((CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U); #endif } else if (expected_seq_num[index] && expected_seq_num[index] < SEQ_NUM_MAX) { @@ -342,6 +346,7 @@ static struct bt_iso_chan_ops iso_ops = { static void test_cis_central(void) { struct bt_iso_chan_io_qos iso_tx[CONFIG_BT_ISO_MAX_CHAN]; + struct bt_iso_chan_io_qos iso_rx[CONFIG_BT_ISO_MAX_CHAN]; struct bt_iso_chan_qos iso_qos[CONFIG_BT_ISO_MAX_CHAN]; struct bt_iso_chan *channels[CONFIG_BT_ISO_MAX_CHAN]; struct bt_conn *conn_list[CONFIG_BT_MAX_CONN]; @@ -372,8 +377,27 @@ static void test_cis_central(void) } iso_tx[i].path = NULL; - iso_qos[i].tx = &iso_tx[i]; - iso_qos[i].rx = NULL; + if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || + IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { + iso_qos[i].tx = &iso_tx[i]; + } else { + iso_qos[i].tx = NULL; + } + + iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU; + iso_rx[i].phy = BT_GAP_LE_PHY_2M; + if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { + iso_rx[i].rtn = 2U; + } else { + iso_rx[i].rtn = 0U; + } + iso_rx[i].path = NULL; + + if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { + iso_qos[i].rx = &iso_rx[i]; + } else { + iso_qos[i].rx = NULL; + } iso_chan[i].ops = &iso_ops; iso_chan[i].qos = &iso_qos[i]; @@ -406,6 +430,12 @@ static void test_cis_central(void) conn_count = 0U; +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U; + } +#endif + #if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) { #else @@ -493,6 +523,7 @@ static void test_cis_central(void) printk("connected to peer %d ISO channel.\n", chan); } +#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { @@ -535,6 +566,9 @@ static void test_cis_central(void) } k_sleep(K_MSEC(1000)); +#else + k_sleep(K_SECONDS(11)); +#endif for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { printk("ISO disconnect channel %u...", chan); @@ -573,6 +607,16 @@ static void test_cis_central(void) } #endif +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + if (expected_seq_num[chan] < SEQ_NUM_MAX) { + FAIL("ISO Data reception incomplete %u (%u).\n", + expected_seq_num[chan], SEQ_NUM_MAX); + return; + } + } +#endif + PASS("Central ISO tests Passed\n"); } @@ -613,6 +657,7 @@ static struct bt_iso_server iso_server = { static void test_cis_peripheral(void) { + struct bt_iso_chan_io_qos iso_tx_p[CONFIG_BT_ISO_MAX_CHAN]; int err; printk("Bluetooth initializing..."); @@ -624,7 +669,18 @@ static void test_cis_peripheral(void) printk("success.\n"); for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { - iso_rx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; + iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; + iso_tx_p[i].phy = BT_GAP_LE_PHY_2M; + if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { + iso_tx_p[i].rtn = 2U; + } else { + iso_tx_p[i].rtn = 0U; + } + iso_tx_p[i].path = NULL; + + iso_qos_p[i].tx = &iso_tx_p[i]; + + iso_rx_p[i].sdu = CONFIG_BT_ISO_RX_MTU; iso_qos_p[i].rx = &iso_rx_p[i]; @@ -698,7 +754,51 @@ static void test_cis_peripheral(void) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) } +#endif + +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; + struct net_buf *buf; + int ret; + buf = net_buf_alloc(&tx_pool, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (!buf) { + FAIL("Data buffer allocate timeout on channel" + " %u\n", chan); + return; + } + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + sys_put_le32(seq_num, iso_data); + net_buf_add_mem(buf, iso_data, sizeof(iso_data)); + + ret = k_sem_take(&sem_iso_data, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (ret) { + FAIL("k_sem_take for ISO data sent failed.\n"); + return; + } + + printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); + ret = bt_iso_chan_send(&iso_chan_p[chan], buf, + seq_num, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + FAIL("Unable to send data on channel %u" + " : %d\n", chan, ret); + net_buf_unref(buf); + return; + } + } + + if ((seq_num % 100) == 0) { + printk("Sending value %u\n", seq_num); + } + } +#endif + +#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif @@ -722,6 +822,7 @@ static void test_cis_peripheral(void) } printk("disconnected from peer device.\n"); +#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #else @@ -734,6 +835,7 @@ static void test_cis_peripheral(void) } #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) } +#endif #endif PASS("Peripheral ISO tests Passed\n"); diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh new file mode 100755 index 00000000000..04ce474e812 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, +# FT=2, skips 2 subevents in the central +simulation_id="connected_iso_acl_first_ft_cen_skip_2_se" +verbosity_level=2 +EXECUTE_TIMEOUT=60 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_2_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_2_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 9a8d66a17f2..6d530d05d72 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -41,6 +41,7 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group_acl_first.conf co app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_4_se.conf compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_cen_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From 27c92fe23828017161e3f35a2bb0f1c670be2ebd Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Aug 2023 14:04:35 +0530 Subject: [PATCH 1539/4498] tests: bsim: Bluetooth: Test RTN=2, FT=2, Cen skip 4 SE in Controller Test RTN=2, FT=2 in Controller with 4 subevents dropped by central. Signed-off-by: Vinayak Kariappa Chettimada --- .../overlay-acl_first_ft_cen_skip_4_se.conf | 9 +++++++ tests/bsim/bluetooth/ll/cis/src/main.c | 2 +- ...onnected_iso_acl_first_ft_cen_skip_4_se.sh | 24 +++++++++++++++++++ tests/bsim/bluetooth/ll/compile.sh | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_4_se.conf create mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_4_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_4_se.conf new file mode 100644 index 00000000000..e3a02840dba --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_4_se.conf @@ -0,0 +1,9 @@ +CONFIG_TEST_USE_LEGACY_ADVERTISING=n +CONFIG_TEST_CONNECT_ACL_FIRST=y +CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS=y +CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT=2 +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_ISO_MAX_CHAN=1 +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index 15e102981d6..6411115f1e8 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -104,7 +104,7 @@ static bt_addr_le_t peer_addr; #define NAME_LEN 30 -#define BUF_ALLOC_TIMEOUT (40) /* milliseconds */ +#define BUF_ALLOC_TIMEOUT (50) /* milliseconds */ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL); diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh new file mode 100755 index 00000000000..a5b3f169f4c --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, +# FT=2, skips 4 subevents in the central +simulation_id="connected_iso_acl_first_ft_cen_skip_4_se" +verbosity_level=2 +EXECUTE_TIMEOUT=60 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_4_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_4_se_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 6d530d05d72..d16e17ed8ea 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -42,6 +42,7 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_4_se.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_cen_skip_2_se.conf compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_cen_skip_4_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From a178aa9855bd9f9f33d822f95d0eb0c3a35ab26c Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 27 Sep 2023 11:21:26 +0200 Subject: [PATCH 1540/4498] Bluetooth: Controller: Review rework flush timeout support Review rework changed related to flush timeout support. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/hci/hci.c | 44 +++- .../bluetooth/controller/ll_sw/lll_conn_iso.h | 28 ++- .../ll_sw/nordic/lll/lll_central_iso.c | 19 +- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 8 + tests/bsim/bluetooth/ll/cis/src/main.c | 206 +++++++++--------- ...onnected_iso_acl_first_ft_cen_skip_2_se.sh | 2 +- ...onnected_iso_acl_first_ft_cen_skip_4_se.sh | 2 +- ...onnected_iso_acl_first_ft_per_skip_2_se.sh | 2 +- ...onnected_iso_acl_first_ft_per_skip_4_se.sh | 2 +- 9 files changed, 183 insertions(+), 130 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index b2c95271b2c..c3dd070720b 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5762,6 +5762,18 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) /* Catch up local pkt_seq_num with internal pkt_seq_num */ event_count = cis->lll.event_count; pkt_seq_num = event_count + 1U; + /* If pb_flag is BT_ISO_START (0b00) or BT_ISO_SINGLE (0b10) + * then we simply check that the pb_flag is an even value, and + * then pkt_seq_num is a future sequence number value compare + * to last recorded number in cis->pkt_seq_num. + * + * When (pkt_seq_num - stream->pkt_seq_num) is negative then + * BIT64(39) will be set (2's compliment value). The diff value + * less than or equal to BIT64_MASK(38) means the diff value is + * positive and hence pkt_seq_num is greater than + * stream->pkt_seq_num. This calculation is valid for when value + * rollover too. + */ if (!(pb_flag & 0x01) && (((pkt_seq_num - cis->pkt_seq_num) & BIT64_MASK(39)) <= BIT64_MASK(38))) { @@ -5770,12 +5782,17 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) pkt_seq_num = cis->pkt_seq_num; } - /* Pre-increment, for next ISO data packet seq num comparison */ + /* Pre-increment, when pg_flag is BT_ISO_SINGLE (0b10) or + * BT_ISO_END (0b11) then we simple check if pb_flag has bit 1 + * is set, for next ISO data packet seq num comparison. + */ if (pb_flag & 0x10) { cis->pkt_seq_num++; } - /* Target next event to avoid overlapping with current event */ + /* Target next ISO event to avoid overlapping with, if any, + * current ISO event + */ pkt_seq_num++; sdu_frag_tx.target_event = pkt_seq_num; sdu_frag_tx.grp_ref_point = @@ -5817,7 +5834,7 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) #endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ /* Get controller's input data path for CIS */ - hdr = &(cis->hdr); + hdr = &cis->hdr; dp_in = hdr->datapath_in; if (!dp_in || dp_in->path_id != BT_HCI_DATAPATH_ID_HCI) { LOG_ERR("Input data path not set for HCI"); @@ -5884,6 +5901,18 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) /* Catch up local pkt_seq_num with internal pkt_seq_num */ event_count = lll_iso->payload_count / lll_iso->bn; pkt_seq_num = event_count; + /* If pb_flag is BT_ISO_START (0b00) or BT_ISO_SINGLE (0b10) + * then we simply check that the pb_flag is an even value, and + * then pkt_seq_num is a future sequence number value compare + * to last recorded number in cis->pkt_seq_num. + * + * When (pkt_seq_num - stream->pkt_seq_num) is negative then + * BIT64(39) will be set (2's compliment value). The diff value + * less than or equal to BIT64_MASK(38) means the diff value is + * positive and hence pkt_seq_num is greater than + * stream->pkt_seq_num. This calculation is valid for when value + * rollover too. + */ if (!(pb_flag & 0x01) && (((pkt_seq_num - stream->pkt_seq_num) & BIT64_MASK(39)) <= BIT64_MASK(38))) { @@ -5892,12 +5921,17 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) pkt_seq_num = stream->pkt_seq_num; } - /* Pre-increment, for next ISO data packet seq num comparison */ + /* Pre-increment, when pg_flag is BT_ISO_SINGLE (0b10) or + * BT_ISO_END (0b11) then we simple check if pb_flag has bit 1 + * is set, for next ISO data packet seq num comparison. + */ if (pb_flag & 0x10) { stream->pkt_seq_num++; } - /* Target next event to avoid overlapping with current event */ + /* Target next ISO event to avoid overlapping with, if any, + * current ISO event + */ /* FIXME: Implement ISO Tx ack generation early in done compared * to currently only in prepare. I.e. to ensure upper * layer has the number of completed packet before the diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 0321b96f638..8a85ca7c6c9 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -15,8 +15,10 @@ struct lll_conn_iso_stream_rxtx { uint64_t ft:8; /* Flush timeout (FT) */ uint64_t bn:4; /* Burst number (BN) */ uint64_t phy:3; /* PHY */ - uint64_t rfu:1; - uint8_t bn_curr:4; /* Current burst number */ + uint64_t rfu0:1; + + uint8_t bn_curr:4; /* Current burst number */ + uint8_t rfu1:4; #if defined(CONFIG_BT_CTLR_LE_ENC) struct ccm ccm; @@ -73,20 +75,26 @@ struct lll_conn_iso_group { struct lll_hdr hdr; uint16_t handle; /* CIG handle (internal) */ - uint8_t num_cis:5; /* Number of CISes in this CIG */ - uint8_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ - uint8_t paused:1; /* 1: CIG is paused */ - /* ISO interval to calculate timestamp under FT > 1 */ - uint32_t iso_interval_us; + /* Resumption information */ + uint16_t resume_cis; /* CIS handle to schedule at resume */ + + /* ISO group information */ + uint32_t num_cis:5; /* Number of CISes in this CIG */ + uint32_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ + uint32_t paused:1; /* 1: CIG is paused */ + uint32_t rfu0:1; + + /* ISO interval to calculate timestamp under FT > 1, + * maximum ISO interval of 4 seconds can be represented in 22-bits. + */ + uint32_t iso_interval_us:22; + uint32_t rfu1:2; /* Accumulates LLL prepare callback latencies */ uint16_t latency_prepare; uint16_t latency_event; - /* Resumption information */ - uint16_t resume_cis; /* CIS handle to schedule at resume */ - #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) /* Window widening. Relies on vendor specific conversion macros, e.g. * EVENT_US_FRAC_TO_TICKS(). diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 9c2184b9942..751c3915fc2 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -48,7 +48,7 @@ static void isr_prepare_subevent(void *param); static void isr_done(void *param); static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll); -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); +static void payload_count_lazy_update(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); static uint16_t next_cis_chan_remap_idx; static uint16_t next_cis_chan_prn_s; @@ -183,7 +183,7 @@ static int prepare_cb(struct lll_prepare_param *p) se_curr = 1U; /* Adjust the SN and NESN for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); + payload_count_lazy_update(cis_lll, lazy); /* Start setting up of Radio h/w */ radio_reset(); @@ -370,7 +370,7 @@ static int prepare_cb(struct lll_prepare_param *p) cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); + payload_count_lazy_update(cis_lll, lazy); /* Adjust sn and nesn for canceled events */ if (err) { @@ -676,11 +676,20 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done || #if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + /* Used by test code, + * to skip a number of events in every 3 event count when current subevent is less than + * or equal to 2 or when current subevent has completed all its NSE number of subevents. + * OR + * to skip a (number + 1) of events in every 3 event count when current subevent is less + * than or equal to 1 or when current subevent has completed all its NSE number of + * subevents. + */ ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT) && ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || + (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT + 1U)) && ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || -#endif +#endif /* CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS */ false) { payload_count_flush(cis_lll); @@ -1230,7 +1239,7 @@ static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_ } } -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) +static void payload_count_lazy_update(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) { if (cis_lll->tx.bn) { uint16_t tx_lazy; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index c33c82d4c70..27ed4d1e42c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -474,6 +474,14 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done || #if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) + /* Used by test code, + * to skip a number of events in every 3 event count when current subevent is less than + * or equal to 2 or when current subevent has completed all its NSE number of subevents. + * OR + * to skip a (number + 1) of events in every 3 event count when current subevent is less + * than or equal to 1 or when current subevent has completed all its NSE number of + * subevents. + */ ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT) && ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT + 1U)) && diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index 6411115f1e8..dc4f455df8c 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -352,7 +352,7 @@ static void test_cis_central(void) struct bt_conn *conn_list[CONFIG_BT_MAX_CONN]; struct bt_iso_cig_param cig_param; struct bt_iso_cig *cig; - uint8_t conn_count; + int conn_count; int err; printk("Bluetooth initializing..."); @@ -370,12 +370,12 @@ static void test_cis_central(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx[i].phy = BT_GAP_LE_PHY_2M; + iso_tx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_tx[i].rtn = 2U; } else { iso_tx[i].rtn = 0U; } - iso_tx[i].path = NULL; if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { @@ -386,12 +386,12 @@ static void test_cis_central(void) iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU; iso_rx[i].phy = BT_GAP_LE_PHY_2M; + iso_rx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_rx[i].rtn = 2U; } else { iso_rx[i].rtn = 0U; } - iso_rx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { iso_qos[i].rx = &iso_rx[i]; @@ -413,12 +413,12 @@ static void test_cis_central(void) cig_param.sca = BT_GAP_SCA_UNKNOWN; cig_param.packing = 0U; cig_param.framing = 0U; + cig_param.interval = ISO_INTERVAL_US; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { cig_param.latency = ISO_LATENCY_FT_MS; } else { cig_param.latency = ISO_LATENCY_MS; } - cig_param.interval = ISO_INTERVAL_US; printk("Create CIG..."); err = bt_iso_cig_create(&cig_param, &cig); @@ -428,10 +428,10 @@ static void test_cis_central(void) } printk("success.\n"); - conn_count = 0U; + conn_count = 0; #if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U; } #endif @@ -443,8 +443,8 @@ static void test_cis_central(void) #endif struct bt_conn *conn; - uint8_t conn_index; - uint8_t chan; + int conn_index; + int chan; printk("Start scanning (%d)...", i); err = bt_le_scan_start(BT_LE_SCAN_CUSTOM, NULL); @@ -494,12 +494,12 @@ static void test_cis_central(void) #if defined(CONFIG_TEST_CONNECT_ACL_FIRST) } - for (uint8_t chan = 0U, conn_index = 0U; + for (int chan = 0, conn_index = 0; (conn_index < conn_count) && (chan < CONFIG_BT_ISO_MAX_CHAN); conn_index++, chan++) { #elif defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (uint8_t chan = 0U, conn_index = 0U; + for (int chan = 0, conn_index = 0; (chan < CONFIG_BT_ISO_MAX_CHAN); chan++) { #endif @@ -523,70 +523,67 @@ static void test_cis_central(void) printk("connected to peer %d ISO channel.\n", chan); } -#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) - for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { - - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; - struct net_buf *buf; - int ret; - - buf = net_buf_alloc(&tx_pool, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (!buf) { - FAIL("Data buffer allocate timeout on channel" - " %u\n", chan); - return; - } - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - sys_put_le32(seq_num, iso_data); - net_buf_add_mem(buf, iso_data, sizeof(iso_data)); - - ret = k_sem_take(&sem_iso_data, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (ret) { - FAIL("k_sem_take for ISO data sent failed.\n"); - return; + if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || + IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { + for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { + + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; + struct net_buf *buf; + int ret; + + buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT)); + if (!buf) { + FAIL("Data buffer allocate timeout on channel %d\n", chan); + return; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + sys_put_le16(seq_num, iso_data); + net_buf_add_mem(buf, iso_data, sizeof(iso_data)); + + ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT)); + if (ret) { + FAIL("k_sem_take for ISO data sent failed.\n"); + return; + } + + printk("ISO send: seq_num %u, chan %d\n", seq_num, chan); + ret = bt_iso_chan_send(&iso_chan[chan], buf, + seq_num, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + FAIL("Unable to send data on channel %d : %d\n", chan, ret); + net_buf_unref(buf); + return; + } } - printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); - ret = bt_iso_chan_send(&iso_chan[chan], buf, - seq_num, BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - FAIL("Unable to send data on channel %u" - " : %d\n", chan, ret); - net_buf_unref(buf); - return; + if ((seq_num % 100) == 0) { + printk("Sending value %u\n", seq_num); } } - if ((seq_num % 100) == 0) { - printk("Sending value %u\n", seq_num); - } + k_sleep(K_MSEC(1000)); + } else { + k_sleep(K_SECONDS(11)); } - k_sleep(K_MSEC(1000)); -#else - k_sleep(K_SECONDS(11)); -#endif - - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - printk("ISO disconnect channel %u...", chan); + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + printk("ISO disconnect channel %d...", chan); err = bt_iso_chan_disconnect(&iso_chan[chan]); if (err) { - FAIL("Failed to disconnect channel %u (%d)\n", - chan, err); + FAIL("Failed to disconnect channel %d (%d)\n", chan, err); return; } printk("success\n"); - printk("Waiting for ISO channel disconnect %u...", chan); + printk("Waiting for ISO channel disconnect %d...", chan); err = k_sem_take(&sem_iso_disc, K_FOREVER); if (err) { FAIL("failed (err %d)\n", err); return; } - printk("disconnected to peer %u ISO channel.\n", chan); + printk("disconnected to peer %d ISO channel.\n", chan); } bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL); @@ -607,15 +604,15 @@ static void test_cis_central(void) } #endif -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - if (expected_seq_num[chan] < SEQ_NUM_MAX) { - FAIL("ISO Data reception incomplete %u (%u).\n", - expected_seq_num[chan], SEQ_NUM_MAX); - return; + if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + if (expected_seq_num[chan] < SEQ_NUM_MAX) { + FAIL("ISO Data reception incomplete %u (%u).\n", + expected_seq_num[chan], SEQ_NUM_MAX); + return; + } } } -#endif PASS("Central ISO tests Passed\n"); } @@ -671,12 +668,12 @@ static void test_cis_peripheral(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx_p[i].phy = BT_GAP_LE_PHY_2M; + iso_tx_p[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_tx_p[i].rtn = 2U; } else { iso_tx_p[i].rtn = 0U; } - iso_tx_p[i].path = NULL; iso_qos_p[i].tx = &iso_tx_p[i]; @@ -741,7 +738,7 @@ static void test_cis_peripheral(void) printk("connected to peer central.\n"); #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif printk("Waiting for ISO channel connection..."); @@ -756,50 +753,47 @@ static void test_cis_peripheral(void) } #endif -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; - struct net_buf *buf; - int ret; - - buf = net_buf_alloc(&tx_pool, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (!buf) { - FAIL("Data buffer allocate timeout on channel" - " %u\n", chan); - return; - } - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - sys_put_le32(seq_num, iso_data); - net_buf_add_mem(buf, iso_data, sizeof(iso_data)); - - ret = k_sem_take(&sem_iso_data, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (ret) { - FAIL("k_sem_take for ISO data sent failed.\n"); - return; + if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { + for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; + struct net_buf *buf; + int ret; + + buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT)); + if (!buf) { + FAIL("Data buffer allocate timeout on channel %d\n", chan); + return; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + sys_put_le16(seq_num, iso_data); + net_buf_add_mem(buf, iso_data, sizeof(iso_data)); + + ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT)); + if (ret) { + FAIL("k_sem_take for ISO data sent failed.\n"); + return; + } + + printk("ISO send: seq_num %u, chan %d\n", seq_num, chan); + ret = bt_iso_chan_send(&iso_chan_p[chan], buf, seq_num, + BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + FAIL("Unable to send data on channel %d : %d\n", chan, ret); + net_buf_unref(buf); + return; + } } - printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); - ret = bt_iso_chan_send(&iso_chan_p[chan], buf, - seq_num, BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - FAIL("Unable to send data on channel %u" - " : %d\n", chan, ret); - net_buf_unref(buf); - return; + if ((seq_num % 100) == 0) { + printk("Sending value %u\n", seq_num); } } - - if ((seq_num % 100) == 0) { - printk("Sending value %u\n", seq_num); - } } -#endif #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif printk("Waiting for ISO channel disconnect..."); @@ -824,13 +818,13 @@ static void test_cis_peripheral(void) #if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #else - uint8_t chan = 0U; + int chan = 0; #endif if (expected_seq_num[chan] < SEQ_NUM_MAX) { - FAIL("ISO Data reception incomplete %u (%u).\n", - expected_seq_num[chan], SEQ_NUM_MAX); + FAIL("ISO Data reception incomplete %u (%u).\n", expected_seq_num[chan], + SEQ_NUM_MAX); return; } #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh index 04ce474e812..bb08f582574 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA +# Copyright 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh index a5b3f169f4c..f75790e3fcf 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_4_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA +# Copyright 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh index 307d865a117..84d3c5c4ed3 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA +# Copyright 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh index 2bb7eeb4f31..8fd00d9a057 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_4_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA +# Copyright 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source From 48c83a1f4268e539afa03abe2ecaed43a0650b7e Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 29 Sep 2023 19:07:12 +0200 Subject: [PATCH 1541/4498] Bluetooth: Controller: Fix num cmplt for BIS HCI ISO Data fragments Fix number of completed packets generated when BIS HCI ISO Data packets sent to Controller are in fragments. Use the ISOAL stored sdu_fragment count to generate the number of completed packets count. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index d3321cb1b0b..3130978df4e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2572,18 +2572,10 @@ static uint8_t tx_cmplt_get(uint16_t *handle, uint8_t *first, uint8_t last) /* We must count each SDU HCI fragment */ tx_node = tx->node; if (IS_NODE_TX_PTR(tx_node)) { - if (IS_ADV_ISO_HANDLE(tx->handle)) { - /* FIXME: ADV_ISO shall be updated to - * use ISOAL for TX. Until then, assume - * 1 node equals 1 fragment. - */ - sdu_fragments = 1U; - } else { - /* We count each SDU fragment completed - * by this PDU. - */ - sdu_fragments = tx_node->sdu_fragments; - } + /* We count each SDU fragment completed + * by this PDU. + */ + sdu_fragments = tx_node->sdu_fragments; /* Replace node reference with fragments * count From 2c6fd67d5906630b1e26ae33e82c6341302a5b4f Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 21 Sep 2023 14:19:54 +0200 Subject: [PATCH 1542/4498] manifest: hal_renesas: Update hal with runtime crash fixes hal has to simple corrections: - One of the asserts were obviously checking wrong condition. It resulted in crash when asserts were enabled - pdc module was using calloc in PRE_KERNEL_1 stage which is not allowed. Latest Zephyr changes of default c library triggered crash. Before calloc returned NULL and that was handled, but now it simple returns some random data. Now static buffers are utilized instead. Signed-off-by: Jerzy Kasenberg --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b09d2a9d005..55a7cd46437 100644 --- a/west.yml +++ b/west.yml @@ -213,7 +213,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 61ea3505a470b4e739cad4359ec1401cc4b85805 + revision: a6cf2af9140e014fbbc48d2b6deb802231dd369f groups: - hal - name: hal_rpi_pico From 113600eb4bd773fcd1b9da91dfbf461e7202fe39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Mon, 2 Oct 2023 13:29:54 +0200 Subject: [PATCH 1543/4498] drivers: i2s: use new k_mem_slab definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 2f003e59e407 ("kernel: Re-factor k_mem_slab definition") moved block_size into from k_mem_slab to k_mem_slab_info without updating i2s handlers. Use the new member to fix build failures. Fixes: #63363 Signed-off-by: Tomasz Moń --- drivers/i2s/i2s_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index c454f8374b1..e556d708616 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -33,7 +33,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, /* Ensure that the k_mem_slab's slabs are large enough for the * specified block size */ - if (config.block_size > config.mem_slab->block_size) { + if (config.block_size > config.mem_slab->info.block_size) { goto out; } From 8c4eec7ac6e37be89af89e021c6f5c96e1ac1e0a Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Mon, 2 Oct 2023 14:17:12 +0300 Subject: [PATCH 1544/4498] intel_adsp: boot_complete must be done PRE_KERNEL_1 Commit 759e07bebe20 ("intel_adsp: move memory window setup to PRE_KERNEL_1") moved memory window setup from EARLY to PRE_KERNEL_1. Similar change must be done to boot_complete, or otherwise boot-up sequence will not be completed correctly on all platforms. Suggested-by: Anas Nashif Signed-off-by: Kai Vehmanen --- soc/xtensa/intel_adsp/common/boot_complete.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/common/boot_complete.c b/soc/xtensa/intel_adsp/common/boot_complete.c index 791590e1273..445fd57b064 100644 --- a/soc/xtensa/intel_adsp/common/boot_complete.c +++ b/soc/xtensa/intel_adsp/common/boot_complete.c @@ -29,4 +29,4 @@ int boot_complete(void) return 0; } -SYS_INIT(boot_complete, EARLY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +SYS_INIT(boot_complete, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); From ebc8fdac4fe84586b7083ff35873010b0f86e185 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 2 Oct 2023 11:48:32 +0000 Subject: [PATCH 1545/4498] doc: fix link to manifest listing and documentation Point to the correct page referencing manifest entries. Signed-off-by: Anas Nashif --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index e250c494fde..2785ec5438b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -172,7 +172,7 @@ "API": f"{reference_prefix}/doxygen/html/index.html", "Kconfig Options": f"{reference_prefix}/kconfig.html", "Devicetree Bindings": f"{reference_prefix}/build/dts/api/bindings.html", - "West Projects": f"{reference_prefix}/develop/projects/index.html", + "West Projects": f"{reference_prefix}/develop/manifest/index.html", } } From 55940f701c2f30412bbf1fe7a3d1fea1f901c539 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Sat, 30 Sep 2023 10:37:11 +0200 Subject: [PATCH 1546/4498] tests bsim: Limit parallel build The compile script had been modified to fully parallelize all images builds in 1de363d9d5279e2c3d6021fecad41ffca96e09f1 And has been kept building everything in parallel since then. Over time we have seen an increase in the number of hangs for this job in CI. This is understood as being the result of the number of images having increased, leading to a too high load on the worker machines which cause them to timeout their connection to the github CI scheduler. In b83a82882559f0c4a6bc0a64f83be06cdbdf79c1 these jobs priority was lowered to aleviate this issue, but again we see an increased number of CI runner disconnects. Let's parallelize this compile jobs a bit less. With this change, we do not build anymore the sets of host ll and mesh test images in parallel but sequencially. On a local test this reduces peak load from ~1700 to ~700, and eliminates issues with system unresponsiveness; while there is no statistically measurable increase in overall build time. Note that the single audio image is still built in parallel to the other 3 sets, as this was seen to improve total build time by 2 seconds out of 1m51s. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/compile.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/bsim/bluetooth/compile.sh b/tests/bsim/bluetooth/compile.sh index df5c85489c3..016437aed73 100755 --- a/tests/bsim/bluetooth/compile.sh +++ b/tests/bsim/bluetooth/compile.sh @@ -18,9 +18,14 @@ mkdir -p ${WORK_DIR} source ${ZEPHYR_BASE}/tests/bsim/sh_common.source +# Note: We do not parallelize the call into the build of the host, ll and mesh images as those +# are already building many images in parallel in themselves, and otherwise we would be +# launching too many parallel builds which can lead to a too high system load. +# On the other hand the audio compile script, only builds one image. So we parallelize it with +# the rest to save a couple of seconds. run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio/compile.sh -run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/compile.sh -run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/ll/compile.sh -run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/mesh/compile.sh +${ZEPHYR_BASE}/tests/bsim/bluetooth/host/compile.sh +${ZEPHYR_BASE}/tests/bsim/bluetooth/ll/compile.sh +${ZEPHYR_BASE}/tests/bsim/bluetooth/mesh/compile.sh wait_for_background_jobs From dee64613c2046fb25b2b546338bcdd83f052f6ec Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 2 Oct 2023 10:41:40 +0300 Subject: [PATCH 1547/4498] samples: tracing: Reenable the percepio test case Update to a fixed percepio tree, which allows the build to pass for valid version numbers with 0 being one of the version number components. Signed-off-by: Johan Hedberg --- samples/subsys/tracing/sample.yaml | 1 - west.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index 973188add69..dda98638a58 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -66,7 +66,6 @@ tests: platform_allow: native_posix extra_args: CONF_FILE="prj_native_posix_ctf.conf" sample.tracing.percepio: - skip: true platform_allow: frdm_k64f extra_args: CONF_FILE="prj_percepio.conf" modules: diff --git a/west.yml b/west.yml index 55a7cd46437..4556e0dcaa7 100644 --- a/west.yml +++ b/west.yml @@ -304,7 +304,7 @@ manifest: path: modules/lib/openthread - name: percepio path: modules/debug/percepio - revision: 722448367cf6c4b877eb7999c90ee52226379acc + revision: 79d586d592fca3e9fecd8886af6acd8c7bb66314 groups: - debug - name: picolibc From 6de57d0985577def3aabc05b3d2d645ba882fe26 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Thu, 14 Sep 2023 15:24:29 +0000 Subject: [PATCH 1548/4498] Bluetooth: Host: Document required changes for L2CAP accept() callback Add a required change in the migration guide to document the changes to the accept() callback in struct bt_l2cap_server. Signed-off-by: Donatien Garnier --- doc/releases/migration-guide-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 220302e1203..017297a8967 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -139,6 +139,12 @@ Required changes }; }; +* The ``accept()`` callback's signature in :c:struct:`bt_l2cap_server` has + changed to ``int (*accept)(struct bt_conn *conn, struct bt_l2cap_server + *server, struct bt_l2cap_chan **chan)``, + adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` + structure instance the callback relates to. :github:`60536` + Recommended Changes ******************* From 0badef8091d737e465f75c8a1c011c9bb996bf77 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 2 Oct 2023 16:12:54 +0200 Subject: [PATCH 1549/4498] twister: Fix missing timeout in handler class In PR #62947 a timeout variable was replaced with a method, but this timeout was used in another place to start pytest subprogram. This commit provides a fix. Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index ef41084cdd4..fbffa817bb2 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1052,7 +1052,7 @@ def run(self): harness = HarnessImporter.get_harness(instance.testsuite.harness.capitalize()) harness.configure(instance) if isinstance(harness, Pytest): - harness.pytest_run(instance.handler.timeout) + harness.pytest_run(instance.handler.get_test_timeout()) else: instance.handler.handle(harness) From b7fbec7920c6bbeca36fb186239d3266e4fddb7e Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 26 Sep 2023 15:42:39 -0300 Subject: [PATCH 1550/4498] drivers: i2c: esp32: check busy line before transfer I2C scan might fail as peripheral is still busy completing last operation. This makes sure transfer call waits for free line. Signed-off-by: Sylvio Alves --- drivers/i2c/i2c_esp32.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/i2c_esp32.c b/drivers/i2c/i2c_esp32.c index 18a38b02a28..60af4648949 100644 --- a/drivers/i2c/i2c_esp32.c +++ b/drivers/i2c/i2c_esp32.c @@ -560,12 +560,20 @@ static int IRAM_ATTR i2c_esp32_transfer(const struct device *dev, struct i2c_msg { struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data; struct i2c_msg *current, *next; + uint32_t timeout = I2C_TRANSFER_TIMEOUT_MSEC * USEC_PER_MSEC; int ret = 0; if (!num_msgs) { return 0; } + while (i2c_hal_is_bus_busy(&data->hal)) { + k_busy_wait(1); + if (timeout-- == 0) { + return -EBUSY; + } + } + /* Check for validity of all messages before transfer */ current = msgs; From 390fcd9adfae0d390b1754dd9c50e8848681824f Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 27 Sep 2023 10:42:58 -0700 Subject: [PATCH 1551/4498] doc: vuln: Add information about CVE-2023-5184 Information about CVE-2023-5184 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index fa12af7e9a7..92a0a23c48c 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1372,3 +1372,17 @@ This has been fixed in main for v3.4.0 `_ - `PR 59018 fix for main `_ + +CVE-2023-5184 +------------- + +Potential signed to unsigned conversion errors and buffer overflow +vulnerabilities in the Zephyr IPM driver + +- `Zephyr project bug tracker GHSA-8x3p-q3r5-xh9g + `_ + +This has been fixed in main for v3.5.0 + +- `PR 63069 fix for main + `_ From 3d91b927c2e6481969d05fd38addee08b8ea24cc Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 27 Sep 2023 10:37:26 -0700 Subject: [PATCH 1552/4498] doc: release: 3.5: Add info about CVE-2023-5184 Add CVE-2023-5184 to 3.5 release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7764e21a02a..7d0d6ad8de6 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -21,6 +21,8 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ +* CVE-2023-5184 `Zephyr project bug tracker GHSA-8x3p-q3r5-xh9g + `_ Kernel ****** From fea507faee78a3927d45a700370db5c1fed19ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 24 Aug 2023 15:25:34 +0200 Subject: [PATCH 1553/4498] net: coap: Capitalize and document COAP_MAKE_RESPONSE_CODE macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Capitalize COAP_MAKE_RESPONSE_CODE macro to align better with coding style - Added missing Doxygen comments Signed-off-by: Benjamin Cabé --- include/zephyr/net/coap.h | 62 +++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 55776bfc6d8..5952cf77d83 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -115,7 +115,13 @@ enum coap_msgtype { COAP_TYPE_RESET = 3 }; -#define coap_make_response_code(class, det) ((class << 5) | (det)) +/** + * Utility macro to create a CoAP response code. + * @param class Class of the response code (ex. 2, 4, 5, ...) + * @param det Detail of the response code + * @return Response code literal +*/ +#define COAP_MAKE_RESPONSE_CODE(class, det) ((class << 5) | (det)) /** * @brief Set of response codes available for a response packet. @@ -123,35 +129,35 @@ enum coap_msgtype { * To be used when creating a response. */ enum coap_response_code { - COAP_RESPONSE_CODE_OK = coap_make_response_code(2, 0), - COAP_RESPONSE_CODE_CREATED = coap_make_response_code(2, 1), - COAP_RESPONSE_CODE_DELETED = coap_make_response_code(2, 2), - COAP_RESPONSE_CODE_VALID = coap_make_response_code(2, 3), - COAP_RESPONSE_CODE_CHANGED = coap_make_response_code(2, 4), - COAP_RESPONSE_CODE_CONTENT = coap_make_response_code(2, 5), - COAP_RESPONSE_CODE_CONTINUE = coap_make_response_code(2, 31), - COAP_RESPONSE_CODE_BAD_REQUEST = coap_make_response_code(4, 0), - COAP_RESPONSE_CODE_UNAUTHORIZED = coap_make_response_code(4, 1), - COAP_RESPONSE_CODE_BAD_OPTION = coap_make_response_code(4, 2), - COAP_RESPONSE_CODE_FORBIDDEN = coap_make_response_code(4, 3), - COAP_RESPONSE_CODE_NOT_FOUND = coap_make_response_code(4, 4), - COAP_RESPONSE_CODE_NOT_ALLOWED = coap_make_response_code(4, 5), - COAP_RESPONSE_CODE_NOT_ACCEPTABLE = coap_make_response_code(4, 6), - COAP_RESPONSE_CODE_INCOMPLETE = coap_make_response_code(4, 8), - COAP_RESPONSE_CODE_CONFLICT = coap_make_response_code(4, 9), - COAP_RESPONSE_CODE_PRECONDITION_FAILED = coap_make_response_code(4, 12), - COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = coap_make_response_code(4, 13), + COAP_RESPONSE_CODE_OK = COAP_MAKE_RESPONSE_CODE(2, 0), + COAP_RESPONSE_CODE_CREATED = COAP_MAKE_RESPONSE_CODE(2, 1), + COAP_RESPONSE_CODE_DELETED = COAP_MAKE_RESPONSE_CODE(2, 2), + COAP_RESPONSE_CODE_VALID = COAP_MAKE_RESPONSE_CODE(2, 3), + COAP_RESPONSE_CODE_CHANGED = COAP_MAKE_RESPONSE_CODE(2, 4), + COAP_RESPONSE_CODE_CONTENT = COAP_MAKE_RESPONSE_CODE(2, 5), + COAP_RESPONSE_CODE_CONTINUE = COAP_MAKE_RESPONSE_CODE(2, 31), + COAP_RESPONSE_CODE_BAD_REQUEST = COAP_MAKE_RESPONSE_CODE(4, 0), + COAP_RESPONSE_CODE_UNAUTHORIZED = COAP_MAKE_RESPONSE_CODE(4, 1), + COAP_RESPONSE_CODE_BAD_OPTION = COAP_MAKE_RESPONSE_CODE(4, 2), + COAP_RESPONSE_CODE_FORBIDDEN = COAP_MAKE_RESPONSE_CODE(4, 3), + COAP_RESPONSE_CODE_NOT_FOUND = COAP_MAKE_RESPONSE_CODE(4, 4), + COAP_RESPONSE_CODE_NOT_ALLOWED = COAP_MAKE_RESPONSE_CODE(4, 5), + COAP_RESPONSE_CODE_NOT_ACCEPTABLE = COAP_MAKE_RESPONSE_CODE(4, 6), + COAP_RESPONSE_CODE_INCOMPLETE = COAP_MAKE_RESPONSE_CODE(4, 8), + COAP_RESPONSE_CODE_CONFLICT = COAP_MAKE_RESPONSE_CODE(4, 9), + COAP_RESPONSE_CODE_PRECONDITION_FAILED = COAP_MAKE_RESPONSE_CODE(4, 12), + COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = COAP_MAKE_RESPONSE_CODE(4, 13), COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = - coap_make_response_code(4, 15), - COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = coap_make_response_code(4, 22), - COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = coap_make_response_code(4, 29), - COAP_RESPONSE_CODE_INTERNAL_ERROR = coap_make_response_code(5, 0), - COAP_RESPONSE_CODE_NOT_IMPLEMENTED = coap_make_response_code(5, 1), - COAP_RESPONSE_CODE_BAD_GATEWAY = coap_make_response_code(5, 2), - COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = coap_make_response_code(5, 3), - COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = coap_make_response_code(5, 4), + COAP_MAKE_RESPONSE_CODE(4, 15), + COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = COAP_MAKE_RESPONSE_CODE(4, 22), + COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = COAP_MAKE_RESPONSE_CODE(4, 29), + COAP_RESPONSE_CODE_INTERNAL_ERROR = COAP_MAKE_RESPONSE_CODE(5, 0), + COAP_RESPONSE_CODE_NOT_IMPLEMENTED = COAP_MAKE_RESPONSE_CODE(5, 1), + COAP_RESPONSE_CODE_BAD_GATEWAY = COAP_MAKE_RESPONSE_CODE(5, 2), + COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = COAP_MAKE_RESPONSE_CODE(5, 3), + COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = COAP_MAKE_RESPONSE_CODE(5, 4), COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED = - coap_make_response_code(5, 5) + COAP_MAKE_RESPONSE_CODE(5, 5) }; #define COAP_CODE_EMPTY (0) From 9c7672bfbc4688b933420264170235d491c28b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 24 Aug 2023 15:35:22 +0200 Subject: [PATCH 1554/4498] net: coap: Improve CoAP Doxygen comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the Doxygen comments for coap.h by adding missing documentation for most of the compilation units. Signed-off-by: Benjamin Cabé --- include/zephyr/net/coap.h | 156 +++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 61 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 5952cf77d83..6fc21a6280b 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -42,25 +42,25 @@ extern "C" { * Refer to RFC 7252, section 12.2 for more information. */ enum coap_option_num { - COAP_OPTION_IF_MATCH = 1, - COAP_OPTION_URI_HOST = 3, - COAP_OPTION_ETAG = 4, - COAP_OPTION_IF_NONE_MATCH = 5, - COAP_OPTION_OBSERVE = 6, - COAP_OPTION_URI_PORT = 7, - COAP_OPTION_LOCATION_PATH = 8, - COAP_OPTION_URI_PATH = 11, - COAP_OPTION_CONTENT_FORMAT = 12, - COAP_OPTION_MAX_AGE = 14, - COAP_OPTION_URI_QUERY = 15, - COAP_OPTION_ACCEPT = 17, - COAP_OPTION_LOCATION_QUERY = 20, - COAP_OPTION_BLOCK2 = 23, - COAP_OPTION_BLOCK1 = 27, - COAP_OPTION_SIZE2 = 28, - COAP_OPTION_PROXY_URI = 35, - COAP_OPTION_PROXY_SCHEME = 39, - COAP_OPTION_SIZE1 = 60, + COAP_OPTION_IF_MATCH = 1, /**< If-Match */ + COAP_OPTION_URI_HOST = 3, /**< Uri-Host */ + COAP_OPTION_ETAG = 4, /**< ETag */ + COAP_OPTION_IF_NONE_MATCH = 5, /**< If-None-Match */ + COAP_OPTION_OBSERVE = 6, /**< Observe (RFC 7641) */ + COAP_OPTION_URI_PORT = 7, /**< Uri-Port */ + COAP_OPTION_LOCATION_PATH = 8, /**< Location-Path */ + COAP_OPTION_URI_PATH = 11, /**< Uri-Path */ + COAP_OPTION_CONTENT_FORMAT = 12, /**< Content-Format */ + COAP_OPTION_MAX_AGE = 14, /**< Max-Age */ + COAP_OPTION_URI_QUERY = 15, /**< Uri-Query */ + COAP_OPTION_ACCEPT = 17, /**< Accept */ + COAP_OPTION_LOCATION_QUERY = 20, /**< Location-Query */ + COAP_OPTION_BLOCK2 = 23, /**< Block2 (RFC 7959) */ + COAP_OPTION_BLOCK1 = 27, /**< Block1 (RFC 7959) */ + COAP_OPTION_SIZE2 = 28, /**< Size2 (RFC 7959) */ + COAP_OPTION_PROXY_URI = 35, /**< Proxy-Uri */ + COAP_OPTION_PROXY_SCHEME = 39, /**< Proxy-Scheme */ + COAP_OPTION_SIZE1 = 60 /**< Size1 */ }; /** @@ -69,13 +69,13 @@ enum coap_option_num { * To be used when creating a request or a response. */ enum coap_method { - COAP_METHOD_GET = 1, - COAP_METHOD_POST = 2, - COAP_METHOD_PUT = 3, - COAP_METHOD_DELETE = 4, - COAP_METHOD_FETCH = 5, - COAP_METHOD_PATCH = 6, - COAP_METHOD_IPATCH = 7, + COAP_METHOD_GET = 1, /**< GET */ + COAP_METHOD_POST = 2, /**< POST */ + COAP_METHOD_PUT = 3, /**< PUT */ + COAP_METHOD_DELETE = 4, /**< DELETE */ + COAP_METHOD_FETCH = 5, /**< FETCH */ + COAP_METHOD_PATCH = 6, /**< PATCH */ + COAP_METHOD_IPATCH = 7, /**< IPATCH */ }; #define COAP_REQUEST_MASK 0x07 @@ -120,7 +120,7 @@ enum coap_msgtype { * @param class Class of the response code (ex. 2, 4, 5, ...) * @param det Detail of the response code * @return Response code literal -*/ + */ #define COAP_MAKE_RESPONSE_CODE(class, det) ((class << 5) | (det)) /** @@ -129,33 +129,60 @@ enum coap_msgtype { * To be used when creating a response. */ enum coap_response_code { + /** 2.00 - OK */ COAP_RESPONSE_CODE_OK = COAP_MAKE_RESPONSE_CODE(2, 0), + /** 2.01 - Created */ COAP_RESPONSE_CODE_CREATED = COAP_MAKE_RESPONSE_CODE(2, 1), + /** 2.02 - Deleted */ COAP_RESPONSE_CODE_DELETED = COAP_MAKE_RESPONSE_CODE(2, 2), + /** 2.03 - Valid */ COAP_RESPONSE_CODE_VALID = COAP_MAKE_RESPONSE_CODE(2, 3), + /** 2.04 - Changed */ COAP_RESPONSE_CODE_CHANGED = COAP_MAKE_RESPONSE_CODE(2, 4), + /** 2.05 - Content */ COAP_RESPONSE_CODE_CONTENT = COAP_MAKE_RESPONSE_CODE(2, 5), + /** 2.31 - Continue */ COAP_RESPONSE_CODE_CONTINUE = COAP_MAKE_RESPONSE_CODE(2, 31), + /** 4.00 - Bad Request */ COAP_RESPONSE_CODE_BAD_REQUEST = COAP_MAKE_RESPONSE_CODE(4, 0), + /** 4.01 - Unauthorized */ COAP_RESPONSE_CODE_UNAUTHORIZED = COAP_MAKE_RESPONSE_CODE(4, 1), + /** 4.02 - Bad Option */ COAP_RESPONSE_CODE_BAD_OPTION = COAP_MAKE_RESPONSE_CODE(4, 2), + /** 4.03 - Forbidden */ COAP_RESPONSE_CODE_FORBIDDEN = COAP_MAKE_RESPONSE_CODE(4, 3), + /** 4.04 - Not Found */ COAP_RESPONSE_CODE_NOT_FOUND = COAP_MAKE_RESPONSE_CODE(4, 4), + /** 4.05 - Method Not Allowed */ COAP_RESPONSE_CODE_NOT_ALLOWED = COAP_MAKE_RESPONSE_CODE(4, 5), + /** 4.06 - Not Acceptable */ COAP_RESPONSE_CODE_NOT_ACCEPTABLE = COAP_MAKE_RESPONSE_CODE(4, 6), + /** 4.08 - Request Entity Incomplete */ COAP_RESPONSE_CODE_INCOMPLETE = COAP_MAKE_RESPONSE_CODE(4, 8), + /** 4.12 - Precondition Failed */ COAP_RESPONSE_CODE_CONFLICT = COAP_MAKE_RESPONSE_CODE(4, 9), + /** 4.12 - Precondition Failed */ COAP_RESPONSE_CODE_PRECONDITION_FAILED = COAP_MAKE_RESPONSE_CODE(4, 12), + /** 4.13 - Request Entity Too Large */ COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = COAP_MAKE_RESPONSE_CODE(4, 13), + /** 4.15 - Unsupported Content-Format */ COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = COAP_MAKE_RESPONSE_CODE(4, 15), + /** 4.22 - Unprocessable Entity */ COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = COAP_MAKE_RESPONSE_CODE(4, 22), + /** 4.29 - Too Many Requests */ COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = COAP_MAKE_RESPONSE_CODE(4, 29), + /** 5.00 - Internal Server Error */ COAP_RESPONSE_CODE_INTERNAL_ERROR = COAP_MAKE_RESPONSE_CODE(5, 0), + /** 5.01 - Not Implemented */ COAP_RESPONSE_CODE_NOT_IMPLEMENTED = COAP_MAKE_RESPONSE_CODE(5, 1), + /** 5.02 - Bad Gateway */ COAP_RESPONSE_CODE_BAD_GATEWAY = COAP_MAKE_RESPONSE_CODE(5, 2), + /** 5.03 - Service Unavailable */ COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = COAP_MAKE_RESPONSE_CODE(5, 3), + /** 5.04 - Gateway Timeout */ COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = COAP_MAKE_RESPONSE_CODE(5, 4), + /** 5.05 - Proxying Not Supported */ COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED = COAP_MAKE_RESPONSE_CODE(5, 5) }; @@ -170,15 +197,15 @@ enum coap_response_code { * To be used when encoding or decoding a Content-Format option. */ enum coap_content_format { - COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /* charset=urf-8 */ - COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40, - COAP_CONTENT_FORMAT_APP_XML = 41, - COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42, - COAP_CONTENT_FORMAT_APP_EXI = 47, - COAP_CONTENT_FORMAT_APP_JSON = 50, - COAP_CONTENT_FORMAT_APP_JSON_PATCH_JSON = 51, - COAP_CONTENT_FORMAT_APP_MERGE_PATCH_JSON = 52, - COAP_CONTENT_FORMAT_APP_CBOR = 60, + COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /**< text/plain;charset=utf-8 */ + COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40, /**< application/link-format */ + COAP_CONTENT_FORMAT_APP_XML = 41, /**< application/xml */ + COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42, /**< application/octet-stream */ + COAP_CONTENT_FORMAT_APP_EXI = 47, /**< application/exi */ + COAP_CONTENT_FORMAT_APP_JSON = 50, /**< application/json */ + COAP_CONTENT_FORMAT_APP_JSON_PATCH_JSON = 51, /**< application/json-patch+json */ + COAP_CONTENT_FORMAT_APP_MERGE_PATCH_JSON = 52, /**< application/merge-patch+json */ + COAP_CONTENT_FORMAT_APP_CBOR = 60 /**< application/cbor */ }; /* block option helper */ @@ -239,25 +266,32 @@ struct coap_observer { * @brief Representation of a CoAP Packet. */ struct coap_packet { - uint8_t *data; /* User allocated buffer */ - uint16_t offset; /* CoAP lib maintains offset while adding data */ - uint16_t max_len; /* Max CoAP packet data length */ - uint8_t hdr_len; /* CoAP header length */ - uint16_t opt_len; /* Total options length (delta + len + value) */ - uint16_t delta; /* Used for delta calculation in CoAP packet */ -#if defined(CONFIG_COAP_KEEP_USER_DATA) - void *user_data; /* Application specific user data */ + uint8_t *data; /**< User allocated buffer */ + uint16_t offset; /**< CoAP lib maintains offset while adding data */ + uint16_t max_len; /**< Max CoAP packet data length */ + uint8_t hdr_len; /**< CoAP header length */ + uint16_t opt_len; /**< Total options length (delta + len + value) */ + uint16_t delta; /**< Used for delta calculation in CoAP packet */ +#if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(DOXGEN) + /** + * Application specific user data. + * Only available when @kconfig{CONFIG_COAP_KEEP_USER_DATA} is enabled. + */ + void *user_data; #endif }; +/** + * @brief Representation of a CoAP option. + */ struct coap_option { - uint16_t delta; + uint16_t delta; /**< Option delta */ #if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN) uint16_t len; uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE]; #else - uint8_t len; - uint8_t value[12]; + uint8_t len; /**< Option length */ + uint8_t value[12]; /**< Option value */ #endif }; @@ -277,13 +311,13 @@ typedef int (*coap_reply_t)(const struct coap_packet *response, * @brief Represents a request awaiting for an acknowledgment (ACK). */ struct coap_pending { - struct sockaddr addr; - int64_t t0; - uint32_t timeout; - uint16_t id; - uint8_t *data; - uint16_t len; - uint8_t retries; + struct sockaddr addr; /**< Remote address */ + int64_t t0; /**< Time when the request was sent */ + uint32_t timeout; /**< Timeout in ms */ + uint16_t id; /**< Message id */ + uint8_t *data; /**< User allocated buffer */ + uint16_t len; /**< Length of the CoAP packet */ + uint8_t retries; /**< Number of times the request has been sent */ }; /** @@ -563,13 +597,13 @@ int coap_handle_request(struct coap_packet *cpkt, * https://tools.ietf.org/html/rfc7959 */ enum coap_block_size { - COAP_BLOCK_16, - COAP_BLOCK_32, - COAP_BLOCK_64, - COAP_BLOCK_128, - COAP_BLOCK_256, - COAP_BLOCK_512, - COAP_BLOCK_1024, + COAP_BLOCK_16, /**< 16-byte block size */ + COAP_BLOCK_32, /**< 32-byte block size */ + COAP_BLOCK_64, /**< 64-byte block size */ + COAP_BLOCK_128, /**< 128-byte block size */ + COAP_BLOCK_256, /**< 256-byte block size */ + COAP_BLOCK_512, /**< 512-byte block size */ + COAP_BLOCK_1024, /**< 1024-byte block size */ }; /** From 9bf17f9276cd91d04fb066fc6a1e976e7c3e8f6a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 1 Oct 2023 13:44:46 +0200 Subject: [PATCH 1555/4498] drivers: can: remove unnecessary asserts in timing callbacks Remove unnecessary calls to __ASSERT_NO_MSG() in CAN controller driver timing setter callbacks. The CAN API functions can_set_timing and can_set_timing_data() already provide run-time timing parameter validation. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_esp32_twai.c | 6 ------ drivers/can/can_mcan.c | 12 ------------ drivers/can/can_mcp2515.c | 11 ----------- drivers/can/can_mcp251xfd.c | 12 ------------ drivers/can/can_sja1000.c | 6 ------ 5 files changed, 47 deletions(-) diff --git a/drivers/can/can_esp32_twai.c b/drivers/can/can_esp32_twai.c index 6bec2638ae4..2fd379d0049 100644 --- a/drivers/can/can_esp32_twai.c +++ b/drivers/can/can_esp32_twai.c @@ -119,12 +119,6 @@ static int can_esp32_twai_set_timing(const struct device *dev, const struct can_ uint8_t btr0; uint8_t btr1; - __ASSERT_NO_MSG(timing->sjw >= 0x1 && timing->sjw <= 0x4); - __ASSERT_NO_MSG(timing->prop_seg == 0); - __ASSERT_NO_MSG(timing->phase_seg1 >= 0x1 && timing->phase_seg1 <= 0x10); - __ASSERT_NO_MSG(timing->phase_seg2 >= 0x1 && timing->phase_seg2 <= 0x8); - __ASSERT_NO_MSG(timing->prescaler >= 0x1 && timing->prescaler <= 0x2000); - if (data->started) { return -EBUSY; } diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index e83ee991c23..b49f6c7c5ed 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -204,12 +204,6 @@ int can_mcan_set_timing(const struct device *dev, const struct can_timing *timin return -EBUSY; } - __ASSERT_NO_MSG(timing->prop_seg == 0U); - __ASSERT_NO_MSG(timing->phase_seg1 <= 0x100 && timing->phase_seg1 > 1U); - __ASSERT_NO_MSG(timing->phase_seg2 <= 0x80 && timing->phase_seg2 > 1U); - __ASSERT_NO_MSG(timing->prescaler <= 0x200 && timing->prescaler > 0U); - __ASSERT_NO_MSG(timing->sjw <= 0x80 && timing->sjw > 0U); - k_mutex_lock(&data->lock, K_FOREVER); nbtp |= FIELD_PREP(CAN_MCAN_NBTP_NSJW, timing->sjw - 1UL) | @@ -239,12 +233,6 @@ int can_mcan_set_timing_data(const struct device *dev, const struct can_timing * return -EBUSY; } - __ASSERT_NO_MSG(timing_data->prop_seg == 0U); - __ASSERT_NO_MSG(timing_data->phase_seg1 <= 0x20 && timing_data->phase_seg1 > 0U); - __ASSERT_NO_MSG(timing_data->phase_seg2 <= 0x10 && timing_data->phase_seg2 > 0U); - __ASSERT_NO_MSG(timing_data->prescaler <= 0x20 && timing_data->prescaler > 0U); - __ASSERT_NO_MSG(timing_data->sjw <= 0x10 && timing_data->sjw > 0U); - k_mutex_lock(&data->lock, K_FOREVER); dbtp |= FIELD_PREP(CAN_MCAN_DBTP_DSJW, timing_data->sjw - 1UL) | diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 8a1b40d0a7b..e6092d0ce92 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -389,17 +389,6 @@ static int mcp2515_set_timing(const struct device *dev, const uint8_t rx0_ctrl = BIT(6) | BIT(5) | BIT(2); const uint8_t rx1_ctrl = BIT(6) | BIT(5); - __ASSERT(timing->sjw <= 4, "1 <= SJW <= 4"); - __ASSERT((timing->prop_seg >= 1) && (timing->prop_seg <= 8), - "1 <= PROP <= 8"); - __ASSERT((timing->phase_seg1 >= 1) && (timing->phase_seg1 <= 8), - "1 <= BS1 <= 8"); - __ASSERT((timing->phase_seg2 >= 2) && (timing->phase_seg2 <= 8), - "2 <= BS2 <= 8"); - __ASSERT(timing->prop_seg + timing->phase_seg1 >= timing->phase_seg2, - "PROP + BS1 >= BS2"); - __ASSERT(timing->phase_seg2 > timing->sjw, "BS2 > SJW"); - config_buf[0] = cnf3; config_buf[1] = cnf2; config_buf[2] = cnf1; diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c index 83b35f38102..055fc454ef3 100644 --- a/drivers/can/can_mcp251xfd.c +++ b/drivers/can/can_mcp251xfd.c @@ -425,12 +425,6 @@ static int mcp251xfd_set_timing(const struct device *dev, const struct can_timin return -EBUSY; } - __ASSERT_NO_MSG(timing->prop_seg == 0); - __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 128); - __ASSERT_NO_MSG(timing->phase_seg1 >= 2 && timing->phase_seg1 <= 256); - __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 128); - __ASSERT_NO_MSG(timing->prescaler >= 1 && timing->prescaler <= 256); - k_mutex_lock(&dev_data->mutex, K_FOREVER); reg = mcp251xfd_get_spi_buf_ptr(dev); @@ -466,12 +460,6 @@ static int mcp251xfd_set_timing_data(const struct device *dev, const struct can_ return -EBUSY; } - __ASSERT_NO_MSG(timing->prop_seg == 0); - __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 16); - __ASSERT_NO_MSG(timing->phase_seg1 >= 1 && timing->phase_seg1 <= 32); - __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 16); - __ASSERT_NO_MSG(timing->prescaler >= 1 && timing->prescaler <= 256); - k_mutex_lock(&dev_data->mutex, K_FOREVER); reg = mcp251xfd_get_spi_buf_ptr(dev); diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index 4c38ae196a1..815f9d43488 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -108,12 +108,6 @@ int can_sja1000_set_timing(const struct device *dev, const struct can_timing *ti uint8_t btr0; uint8_t btr1; - __ASSERT_NO_MSG(timing->sjw >= 1 && timing->sjw <= 4); - __ASSERT_NO_MSG(timing->prop_seg == 0); - __ASSERT_NO_MSG(timing->phase_seg1 >= 1 && timing->phase_seg1 <= 16); - __ASSERT_NO_MSG(timing->phase_seg2 >= 1 && timing->phase_seg2 <= 8); - __ASSERT_NO_MSG(timing->prescaler >= 1 && timing->prescaler <= 64); - if (data->started) { return -EBUSY; } From 2aafc0d4d7a3645918769e187129164573fa2968 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 08:06:08 +0100 Subject: [PATCH 1556/4498] doc: release: 3.5: Correct word in MCUmgr update Changes wrong word transport to group Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7d0d6ad8de6..b9bde4cfaab 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -334,7 +334,7 @@ Libraries / Subsystems * MCUmgr SMP version 2 error translation (to legacy MCUmgr error code) is now supported in function handlers by setting ``mg_translate_error`` of - :c:struct:`mgmt_group` when registering a transport. See + :c:struct:`mgmt_group` when registering a group. See :c:type:`smp_translate_error_fn` for function details. * Fixed an issue with MCUmgr img_mgmt group whereby the size of the upload in From 7e37df33deaa41018aaefdd214cc86cc23d55709 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 08:06:55 +0100 Subject: [PATCH 1557/4498] doc: migration-guide: 3.5: Add note on SMP version 2 error handlers Adds a note about required changed for Zephyr 3.4 SMP version 2 error translation handlers in Zephyr 3.5 (or newer) Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 017297a8967..6a517ce8737 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -34,6 +34,13 @@ Required changes SMP version 2 error code defines for in-tree modules have been updated to replace the ``*_RET_RC_*`` parts with ``*_ERR_*``. +* MCUmgr SMP version 2 error translation (to legacy MCUmgr error code) is now + handled in function handlers by setting the ``mg_translate_error`` function + pointer of :c:struct:`mgmt_group` when registering a group. See + :c:type:`smp_translate_error_fn` for function details. Any SMP version 2 + handlers made for Zephyr 3.4 need to be updated to include these translation + functions when the groups are registered. + * ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` and its type moved from 'enum' to 'int'. To have a seamless conversion this is the required change in the DT: From c80750ec9c3a54d43d7ea07cc12410891816447a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 08:18:59 +0100 Subject: [PATCH 1558/4498] doc: release: 3.5: Add MCUboot release notes Adds the changes in MCUboot to this release Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b9bde4cfaab..89e0d01d422 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -405,6 +405,63 @@ MCUboot the primary slot with secondary slot contents, without saving the original image in primary slot. + * Fixed issue with serial recovery not showing image details for decrypted images. + + * Fixed issue with serial recovery in single slot mode wrongly iterating over 2 image slots. + + * Fixed an issue with boot_serial repeats not being processed when output was sent, this would + lead to a divergence of commands whereby later commands being sent would have the previous + command output sent instead. + + * Fixed an issue with the boot_serial zcbor setup encoder function wrongly including the buffer + address in the size which caused serial recovery to fail on some platforms. + + * Fixed wrongly building in optimize for debug mode by default, this saves a significant amount + of flash space. + + * Fixed issue with serial recovery use of MBEDTLS having undefined operations which led to usage + faults when the secondary slot image was encrypted. + + * Added error output when flash device fails to open and asserts are disabled, which will now + panic the bootloader. + + * Added currently running slot ID and maximum application size to shared data function + definition. + + * Added P384 and SHA384 support to imgtool. + + * Added optional serial recovery image state and image set state commands. + + * Added ``dumpinfo`` command for signed image parsing in imgtool. + + * Added ``getpubhash`` command to dump the sha256 hash of the public key in imgtool. + + * Added support for ``getpub`` to print the output to a file in imgtool. + + * Added support for dumping the raw versions of the public keys in imgtool. + + * Added support for sharing boot information with application via retention subsystem. + + * Added support for serial recovery to read and handle encrypted seondary slot partitions. + + * Removed ECDSA P224 support. + + * Removed custom image list boot serial extension support. + + * Reworked boot serial extensions so that they can be used by modules or from user repositories + by switching to iterable sections. + + * Reworked image encryption support for Zephyr, static dummy key files are no longer in the code, + a pem file must be supplied to extract the private and public keys. The Kconfig menu has + changed to only show a single option for enabling encryption and selecting the key file. + + * Reworked the ECDSA256 TLV curve agnostic and renamed it to ``ECDSA_SIG``. + + * CDDL auto-generated function code has been replaced with zcbor function calls, this now allows + the parameters to be supplied in any order. + + * The MCUboot version in this release is version ``2.0.0+0-rc1``. + Storage ******* From 12639b6860fe7b63b6fdbb6787ca4d1a743ddf9d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 09:24:06 +0100 Subject: [PATCH 1559/4498] doc: release: 3.5: Add additional MCUmgr changes Adds some additional notes on changes to MCUmgr in 3.5 Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 89e0d01d422..c92361a34e0 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -369,6 +369,15 @@ Libraries / Subsystems * Added ``user_data`` as an optional field to :c:struct:`mgmt_handler` when :kconfig:option:`CONFIG_MCUMGR_MGMT_HANDLER_USER_DATA` is enabled. + * Added optional ``force`` parameter to os mgmt reset command, this can be checked in the + :c:enum:`MGMT_EVT_OP_OS_MGMT_RESET` notification callback whose data structure is + :c:struct:`os_mgmt_reset_data`. + + * Added configurable number of SMP encoding levels via + :kconfig:option:`CONFIG_MCUMGR_SMP_CBOR_MIN_ENCODING_LEVELS`, which automatically increments + minimum encoding levels for in-tree groups if :kconfig:option:`CONFIG_ZCBOR_CANONICAL` is + enabled. + * File systems * Added support for ext2 file system. From d0b1031593789ed44d4105da7c07ec665ffdfede Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 09:24:53 +0100 Subject: [PATCH 1560/4498] doc: release: 3.5: Add retained memory changes Adds notes on changes to retained memory Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c92361a34e0..68404b42798 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -251,6 +251,13 @@ Drivers and Sensors * Added support for Nuvoton NuMaker M46x +* Retained memory + + * Added support for allowing mutex support to be forcibly disabled with + :kconfig:option:`CONFIG_RETAINED_MEM_MUTEX_FORCE_DISABLE`. + + * Fixed issue with user mode support not working. + * SDHC * Sensor From ea4a463cc00d37058cabc84e22c030eafc10a19d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Oct 2023 09:25:22 +0100 Subject: [PATCH 1561/4498] doc: release: 3.5: Add additional retention change note Adds a note on the change to disable retention system mutex support Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 68404b42798..3aa025327d5 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -397,6 +397,9 @@ Libraries / Subsystems * Added the :ref:`blinfo_api` subsystem. + * Added support for allowing mutex support to be forcibly disabled with + :kconfig:option:`CONFIG_RETENTION_MUTEX_FORCE_DISABLE`. + * Binary descriptors * Added the :ref:`binary_descriptors` (``bindesc``) subsystem. From 58444cc23bf9b5ba35b0c58864e351621c35f217 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Wed, 27 Sep 2023 23:29:51 -0400 Subject: [PATCH 1562/4498] boards: riscv: qemu: enable coverage support for all targets Support code coverage on all RISC-V qemu targets. Additional boards may choose to enable coveage support as well. Tested by following the procedure documented at https://docs.zephyrproject.org/latest/develop/test/coverage.html with the qemu_riscv64 target. Signed-off-by: Christopher Friedt --- boards/riscv/qemu_riscv32/Kconfig.board | 3 +++ boards/riscv/qemu_riscv32e/Kconfig.board | 1 + boards/riscv/qemu_riscv64/Kconfig.board | 2 ++ 3 files changed, 6 insertions(+) diff --git a/boards/riscv/qemu_riscv32/Kconfig.board b/boards/riscv/qemu_riscv32/Kconfig.board index 3277f94129a..989fa13b453 100644 --- a/boards/riscv/qemu_riscv32/Kconfig.board +++ b/boards/riscv/qemu_riscv32/Kconfig.board @@ -4,6 +4,7 @@ config BOARD_QEMU_RISCV32 bool "QEMU RISCV32 target" depends on SOC_RISCV_VIRT select QEMU_TARGET + select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU select RISCV_ISA_RV32I select RISCV_ISA_EXT_ZICSR @@ -13,6 +14,7 @@ config BOARD_QEMU_RISCV32_SMP bool "QEMU RISCV32 SMP target" depends on SOC_RISCV_VIRT select QEMU_TARGET + select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU select RISCV_ISA_RV32I select RISCV_ISA_EXT_ZICSR @@ -22,6 +24,7 @@ config BOARD_QEMU_RISCV32_XIP bool "QEMU RISCV32 XIP target" depends on SOC_RISCV_SIFIVE_FREEDOM select QEMU_TARGET + select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU select RISCV_ISA_RV32I select RISCV_ISA_EXT_ZICSR diff --git a/boards/riscv/qemu_riscv32e/Kconfig.board b/boards/riscv/qemu_riscv32e/Kconfig.board index 043be02bfbd..ace6a7322dd 100644 --- a/boards/riscv/qemu_riscv32e/Kconfig.board +++ b/boards/riscv/qemu_riscv32e/Kconfig.board @@ -5,6 +5,7 @@ config BOARD_QEMU_RISCV32E bool "QEMU RISCV32E target" depends on SOC_RISCV_VIRT select QEMU_TARGET + select HAS_COVERAGE_SUPPORT select RISCV_ISA_RV32E select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI diff --git a/boards/riscv/qemu_riscv64/Kconfig.board b/boards/riscv/qemu_riscv64/Kconfig.board index eb92cfef930..f75ba14b7a4 100644 --- a/boards/riscv/qemu_riscv64/Kconfig.board +++ b/boards/riscv/qemu_riscv64/Kconfig.board @@ -6,6 +6,7 @@ config BOARD_QEMU_RISCV64 depends on SOC_RISCV_VIRT select QEMU_TARGET select 64BIT + select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU_DOUBLE_PRECISION select RISCV_ISA_RV64I select RISCV_ISA_EXT_ZICSR @@ -16,6 +17,7 @@ config BOARD_QEMU_RISCV64_SMP depends on SOC_RISCV_VIRT select QEMU_TARGET select 64BIT + select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU_DOUBLE_PRECISION select RISCV_ISA_RV64I select RISCV_ISA_EXT_ZICSR From feb3896e668d92bea974b5e50e6be6cd7f2757ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Sep 2023 15:08:57 +0200 Subject: [PATCH 1563/4498] boards: doc: cypress: Update all cypress.com links to use HTTPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While recent browsers seem to transparently try to use https when hitting http://www.cypress.com/... URLs, they are effectively not working anymore, so use https://www.cypress.com/... URLs instead. And it's a good practice anyway to promote secure links vs. plain http :) curl http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 -v -m 5 * Trying [2a02:26f0:2b00:1a::212:b1ac]:80... * Connected to www.cypress.com (2a02:26f0:2b00:1a::212:b1ac) port 80 (#0) > GET /products/32-bit-arm-cortex-m4-psoc-6 HTTP/1.1 Host: > www.cypress.com User-Agent: curl/8.1.2 Accept: */* > * Operation timed out after 5004 milliseconds with 0 bytes received * Closing connection 0 curl: (28) Operation timed out after 5004 milliseconds with 0 bytes received Signed-off-by: Benjamin Cabé --- boards/arm/cy8ckit_062_wifi_bt/doc/index.rst | 14 +++++++------- boards/arm/cy8cproto_062_4343w/doc/index.rst | 8 ++++---- boards/arm/cy8cproto_063_ble/doc/index.rst | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst b/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst index 87cb1283246..e1d6d16ef0a 100644 --- a/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst +++ b/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst @@ -187,22 +187,22 @@ References ********** .. _PSoC 62 MCU SoC Website: - http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 + https://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 .. _PSoC 62 MCU Datasheet: - http://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary + https://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary .. _PSoC 62 MCU Architecture Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual .. _PSoC 62 MCU Register Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm .. _CY8CKIT-062-WiFi-BT Website: - http://www.cypress.com/documentation/development-kitsboards/psoc-6-wifi-bt-pioneer-kit + https://www.cypress.com/documentation/development-kitsboards/psoc-6-wifi-bt-pioneer-kit .. _CY8CKIT-062-WiFi-BT User Guide: - http://www.cypress.com/file/407731/download + https://www.cypress.com/file/407731/download .. _CY8CKIT-062-WiFi-BT Schematics: - http://www.cypress.com/file/420846/download + https://www.cypress.com/file/420846/download diff --git a/boards/arm/cy8cproto_062_4343w/doc/index.rst b/boards/arm/cy8cproto_062_4343w/doc/index.rst index 2b04a8f3688..9cf9c942591 100644 --- a/boards/arm/cy8cproto_062_4343w/doc/index.rst +++ b/boards/arm/cy8cproto_062_4343w/doc/index.rst @@ -160,16 +160,16 @@ Errata +------------------------------------------------+----------------------------------------+ .. _PSoC 62 MCU SoC Website: - http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 + https://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 .. _PSoC 62 MCU Datasheet: - http://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary + https://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary .. _PSoC 62 MCU Architecture Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual .. _PSoC 62 MCU Register Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm .. _CY8CPROTO-062-4343W PSoC 6 Wi-Fi BT Website: https://www.infineon.com/cms/en/product/evaluation-boards/cy8cproto-062-4343w/ diff --git a/boards/arm/cy8cproto_063_ble/doc/index.rst b/boards/arm/cy8cproto_063_ble/doc/index.rst index 9757a2d7cc4..58ac2a98183 100644 --- a/boards/arm/cy8cproto_063_ble/doc/index.rst +++ b/boards/arm/cy8cproto_063_ble/doc/index.rst @@ -121,7 +121,7 @@ References ********** .. _PSoC 63 BLE MCU SoC Website: - http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 + https://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 .. _PSoC 63 BLE MCU Datasheet: https://www.infineon.com/dgdl/Infineon-PSoC_6_MCU_PSoC_63_with_BLE_Datasheet_Programmable_System-on-Chip_(PSoC)-DataSheet-v16_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0ee4efe46c37&utm_source=cypress&utm_medium=referral&utm_campaign=202110_globe_en_all_integration-files From 7ac34d095790155d5769f7a22c0c6280fc465707 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 18:51:52 +0200 Subject: [PATCH 1564/4498] drivers: ieee802154: cc13xx_cc26xx_subg: fix timing regression Fixes a timing regression introduced by commit a12a6ab5b94a0aa4cc53c4b507bd8c5085a30910. This caused a massively increased package error rate. Fixes: #63324. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 1b1891bc14e..c8d71e58bf3 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -595,8 +595,12 @@ static int ieee802154_cc13xx_cc26xx_subg_attr_get(const struct device *dev, { ARG_UNUSED(dev); + /* We claim channel page nine with channel page zero channel range to + * ensure SUN-FSK timing, see the TODO in + * ieee802154_cc13xx_cc26xx_subg_channel_to_frequency(). + */ return ieee802154_attr_get_channel_page_and_range( - attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_NINE_SUN_PREDEFINED, &drv_attr.phy_supported_channels, value); } @@ -896,7 +900,9 @@ static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_d /* see IEEE 802.15.4, section 11.3, table 11-1 and section 10.2.8 */ .csEndTime = RF_convertUsToRatTicks( IEEE802154_PHY_A_CCA_TIME * - IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS), + (IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_NS / + NSEC_PER_USEC) + ), }, .cmd_prop_tx_adv = { From 4f5323a1cf5eab0182166ece2079ad8f0bb94efd Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Thu, 28 Sep 2023 16:21:14 +0200 Subject: [PATCH 1565/4498] Bluetooth: fix HCI ISO Data packets fragmentation this commit partially reverts e460847b6083c0bc57bd63f63bc13c756207c2c9 According to Core Spec 5.4, Vol. 4, Part E, 5.4.5, Data_Total_Length field contains length of the whole packet including optional fields of SDU (Time_Stamp, Packet_Sequence_Number, ISO_SDU_Length, RFU and Packet_Status_Flag). In Zephyr Host, Data_Total_Length value is stored in bt_dev.le.iso_mtu field. Therefore, there is no need to calculate iso_hdr_len(), this length is already taken into account in conn_mtu(conn). This commits removes iso_hdr_len() function and fixes calculation of HCI ISO Data packet length calculations. Signed-off-by: Ivan Iushkov --- subsys/bluetooth/host/conn.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 93cd6a47d95..390aafdf465 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -656,21 +656,6 @@ static int do_send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags return err; } -static size_t iso_hdr_len(struct net_buf *buf, struct bt_conn *conn) -{ -#if defined(CONFIG_BT_ISO) - if (conn->type == BT_CONN_TYPE_ISO) { - if (tx_data(buf)->iso_has_ts) { - return BT_HCI_ISO_TS_DATA_HDR_SIZE; - } else { - return BT_HCI_ISO_DATA_HDR_SIZE; - } - } -#endif - - return 0; -} - static int send_frag(struct bt_conn *conn, struct net_buf *buf, struct net_buf *frag, uint8_t flags) @@ -683,9 +668,7 @@ static int send_frag(struct bt_conn *conn, /* Add the data to the buffer */ if (frag) { - size_t iso_hdr = flags == FRAG_START ? iso_hdr_len(buf, conn) : 0; - uint16_t frag_len = MIN(conn_mtu(conn) + iso_hdr, - net_buf_tailroom(frag)); + uint16_t frag_len = MIN(conn_mtu(conn), net_buf_tailroom(frag)); net_buf_add_mem(frag, buf->data, frag_len); net_buf_pull(buf, frag_len); @@ -733,11 +716,6 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) return frag; } -static bool fits_single_ctlr_buf(struct net_buf *buf, struct bt_conn *conn) -{ - return buf->len - iso_hdr_len(buf, conn) <= conn_mtu(conn); -} - static int send_buf(struct bt_conn *conn, struct net_buf *buf) { struct net_buf *frag; @@ -747,7 +725,7 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf) LOG_DBG("conn %p buf %p len %u", conn, buf, buf->len); /* Send directly if the packet fits the ACL MTU */ - if (fits_single_ctlr_buf(buf, conn) && !tx_data(buf)->is_cont) { + if (buf->len <= conn_mtu(conn) && !tx_data(buf)->is_cont) { LOG_DBG("send single"); return send_frag(conn, buf, NULL, FRAG_SINGLE); } From a4a196f0027b11a5debd9025fb0ba8099ea6a3c0 Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Thu, 28 Sep 2023 16:34:46 +0200 Subject: [PATCH 1566/4498] Bluetooth: fix iso_has_ts field for SDU fragmented to multiple HCI packets iso_has_ts wasn't set correcrly for fragments of HCI ISO Data packets, now it is set depending on timestamp provided in the original buffer provided by host user Signed-off-by: Ivan Iushkov --- subsys/bluetooth/host/conn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 390aafdf465..7670834d3e2 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -712,6 +712,7 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) /* Fragments never have a TX completion callback */ tx_data(frag)->tx = NULL; tx_data(frag)->is_cont = false; + tx_data(frag)->iso_has_ts = tx_data(buf)->iso_has_ts; return frag; } From c650f6aea0bc5e6c4fcacb521435b1673553f221 Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Fri, 29 Sep 2023 12:08:10 +0200 Subject: [PATCH 1567/4498] Bluetooth: documentation change of kconfig.iso configs Added comment to KConfig.iso file to make description of BT_ISO_TX_MTU and BT_ISO_RX_MTU more clear Signed-off-by: Ivan Iushkov --- subsys/bluetooth/Kconfig.iso | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/bluetooth/Kconfig.iso b/subsys/bluetooth/Kconfig.iso index 553ff3a7fb4..304c408f42f 100644 --- a/subsys/bluetooth/Kconfig.iso +++ b/subsys/bluetooth/Kconfig.iso @@ -99,6 +99,10 @@ config BT_ISO_TX_MTU range 1 4095 help Maximum MTU for Isochronous channels TX buffers. + This is the actual data payload. It doesn't include the optional + HCI ISO Data packet fields (e.g. `struct bt_hci_iso_ts_data_hdr`). + Set this value to 247 to fit 247 bytes of data within a single + HCI ISO Data packet with a size of 255, without utilizing timestamps. config BT_ISO_RX_BUF_COUNT int "Number of Isochronous RX buffers" @@ -113,6 +117,8 @@ config BT_ISO_RX_MTU range 23 4095 help Maximum MTU for Isochronous channels RX buffers. + This is the actual data payload. It doesn't include the optional + HCI ISO Data packet fields (e.g. `struct bt_hci_iso_ts_data_hdr`) config BT_ISO_ADVANCED bool "Advanced ISO parameters" From c6c97002b52998c3509ef5e806654a90173cb4aa Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Mon, 2 Oct 2023 13:39:52 -0400 Subject: [PATCH 1568/4498] tests: subsys: zbus: do not use verbose logging This change fixes a regression on `qemu_riscv64_smp` and `qemu_riscv32_smp` that arose because debug logging was enabled. My guess is that subtle races exist and that debug logging exacerbates the condidtions for those races. Signed-off-by: Christopher Friedt --- tests/subsys/zbus/integration/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/subsys/zbus/integration/prj.conf b/tests/subsys/zbus/integration/prj.conf index 2735cb28b7c..72f1d956e1e 100644 --- a/tests/subsys/zbus/integration/prj.conf +++ b/tests/subsys/zbus/integration/prj.conf @@ -3,7 +3,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=n CONFIG_LOG=y CONFIG_ZBUS=y -CONFIG_ZBUS_LOG_LEVEL_DBG=y CONFIG_ZBUS_CHANNEL_NAME=y CONFIG_ZBUS_MSG_SUBSCRIBER=y CONFIG_HEAP_MEM_POOL_SIZE=1024 From 08a0bd65dabc559f608c750c52d64b15f39d7298 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Thu, 28 Sep 2023 10:49:22 +0200 Subject: [PATCH 1569/4498] MAINTAINERS: Add domains.py under West area This small library is shared by both west and twister, where it's used to parse the `domains.yaml` files generated by sysbuild. It also defines the schema that sysbuild itself must adhere to when generating the file. `domains.py` used to be located in `scripts/west_commands/`, which means that it once belonged under "West". Having one file appear in multiple areas is discouraged, so let's just move it back to "West". Signed-off-by: Grzegorz Swiderski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a9f88ed9ccf..78183be61bb 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2908,6 +2908,7 @@ West: - scripts/west-commands.yml - scripts/west_commands/ - doc/develop/west/ + - scripts/pylib/build_helpers/domains.py labels: - "area: West" From 4b179076216f337b57f127f6a7e72c1b01c703d4 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Thu, 28 Sep 2023 21:08:52 -0700 Subject: [PATCH 1570/4498] intel_ish: Enable ISH boards for coverage. When build ISH project in Chromium repo, the coverage report error: zmake build --coverage rex-ish lcov: ERROR: no valid records found in tracefile. To fix this, enable coverage config to link ISH boards with coverage library. Signed-off-by: Li Feng --- soc/x86/intel_ish/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/x86/intel_ish/Kconfig b/soc/x86/intel_ish/Kconfig index 590c26a55fb..b3865915a2a 100644 --- a/soc/x86/intel_ish/Kconfig +++ b/soc/x86/intel_ish/Kconfig @@ -13,3 +13,4 @@ config SOC_FAMILY_INTEL_ISH select CPU_HAS_FPU select INTEL_HAL select HAS_PM + select HAS_COVERAGE_SUPPORT From baec80fe415fe7d61c71cb506afb4f9e46584cf2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 28 Sep 2023 10:31:40 +0200 Subject: [PATCH 1571/4498] CI bsim workflow: Also run controller tests on nrf5340bsim_nrf5340_cpunet Run all bsim bluetooth controller tests also on a nrf5340bsim_nrf5340_cpunet, as the controller runs in a quite different mode. Signed-off-by: Alberto Escolar Piedras --- .github/workflows/bsim-tests.yaml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 37a8234a9a2..a8a49be7670 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -40,8 +40,9 @@ jobs: BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components EDTT_PATH: ../tools/edtt - bsim_bluetooth_test_results_file: ./bsim_bluetooth/bsim_results.xml - bsim_networking_test_results_file: ./bsim_net/bsim_results.xml + bsim_bt_52_test_results_file: ./bsim_bt/52_bsim_results.xml + bsim_bt_53_test_results_file: ./bsim_bt/53_bsim_results.xml + bsim_net_52_test_results_file: ./bsim_net/52_bsim_results.xml steps: - name: Apply container owner mismatch workaround run: | @@ -133,16 +134,22 @@ jobs: if: steps.check-bluetooth-files.outputs.any_changed == 'true' || steps.check-common-files.outputs.any_changed == 'true' run: | export ZEPHYR_BASE=${PWD} - WORK_DIR=${ZEPHYR_BASE}/bsim_bluetooth nice tests/bsim/bluetooth/compile.sh - RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bluetooth_test_results_file} \ + WORK_DIR=${ZEPHYR_BASE}/bsim_bt nice tests/bsim/bluetooth/compile.sh + RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bt_52_test_results_file} \ SEARCH_PATH=tests/bsim/bluetooth/ tests/bsim/run_parallel.sh + # Run the BT controller tests also for the nrf5340 + BOARD=nrf5340bsim_nrf5340_cpunet \ + WORK_DIR=${ZEPHYR_BASE}/bsim_bt nice tests/bsim/bluetooth/ll/compile.sh + BOARD=nrf5340bsim_nrf5340_cpunet \ + RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bt_53_test_results_file} \ + SEARCH_PATH=tests/bsim/bluetooth/ll/ tests/bsim/run_parallel.sh - name: Run Networking Tests with BSIM if: steps.check-networking-files.outputs.any_changed == 'true' || steps.check-common-files.outputs.any_changed == 'true' run: | export ZEPHYR_BASE=${PWD} WORK_DIR=${ZEPHYR_BASE}/bsim_net nice tests/bsim/net/compile.sh - RESULTS_FILE=${ZEPHYR_BASE}/${bsim_networking_test_results_file} \ + RESULTS_FILE=${ZEPHYR_BASE}/${bsim_net_52_test_results_file} \ SEARCH_PATH=tests/bsim/net/ tests/bsim/run_parallel.sh - name: Upload Test Results @@ -151,8 +158,9 @@ jobs: with: name: bsim-test-results path: | - ./bsim_bluetooth/bsim_results.xml - ./bsim_net/bsim_results.xml + ./bsim_bt/52_bsim_results.xml + ./bsim_bt/53_bsim_results.xml + ./bsim_net/52_bsim_results.xml ${{ github.event_path }} if-no-files-found: warn From 224839432730a2fe1694f39291398de5fe08eba3 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 2 Oct 2023 15:17:53 +0200 Subject: [PATCH 1572/4498] Bluetooth: Audio: Fix issues when setting new cfg values Fix issues when setting new values in cfg that modify the length of the codec configuration LTV value. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/audio.c | 6 +++-- subsys/bluetooth/audio/codec.c | 40 ++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/audio/audio.c b/subsys/bluetooth/audio/audio.c index b927b928590..31e8548376e 100644 --- a/subsys/bluetooth/audio/audio.c +++ b/subsys/bluetooth/audio/audio.c @@ -34,15 +34,17 @@ int bt_audio_data_parse(const uint8_t ltv[], size_t size, } for (size_t i = 0; i < size;) { - const uint8_t len = ltv[i++]; + const uint8_t len = ltv[i]; struct bt_data data; if (i + len > size || len < sizeof(data.type)) { - LOG_DBG("Invalid len %u at i = %zu", len, i - 1); + LOG_DBG("Invalid len %u at i = %zu", len, i); return -EINVAL; } + i++; /* Increment as we have parsed the len field */ + data.type = ltv[i++]; data.data_len = len - sizeof(data.type); diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index c3dbfcf3ab8..8a9826f8633 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -177,9 +177,9 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ } for (uint16_t i = 0U; i < codec_cfg->data_len;) { - const uint8_t len = codec_cfg->data[i++]; + uint8_t *len = &codec_cfg->data[i++]; const uint8_t data_type = codec_cfg->data[i++]; - const uint8_t value_len = len - sizeof(data_type); + const uint8_t value_len = *len - sizeof(data_type); if (data_type == type) { uint8_t *value = &codec_cfg->data[i]; @@ -187,12 +187,20 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ if (data_len == value_len) { memcpy(value, data, data_len); } else { - const uint8_t *old_next_data_start = value + value_len + 1; - const uint8_t data_len_to_move = - codec_cfg->data_len - - (old_next_data_start - codec_cfg->data); - uint8_t *new_next_data_start = value + data_len + 1; const int16_t diff = data_len - value_len; + uint8_t *old_next_data_start; + uint8_t *new_next_data_start; + uint8_t data_len_to_move; + + /* Check if this is the last value in the buffer */ + if (value + value_len == codec_cfg->data + codec_cfg->data_len) { + data_len_to_move = 0U; + } else { + old_next_data_start = value + value_len + 1; + new_next_data_start = value + data_len + 1; + data_len_to_move = codec_cfg->data_len - + (old_next_data_start - codec_cfg->data); + } if (diff < 0) { /* In this case we need to move memory around after the copy @@ -200,8 +208,10 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ */ memcpy(value, data, data_len); - memmove(new_next_data_start, old_next_data_start, - data_len_to_move); + if (data_len_to_move > 0U) { + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + } } else { /* In this case we need to move memory around before * the copy to fit the new longer data @@ -215,12 +225,16 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ return -ENOMEM; } - memmove(new_next_data_start, old_next_data_start, - data_len_to_move); + if (data_len_to_move > 0) { + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + } + memcpy(value, data, data_len); } codec_cfg->data_len += diff; + *len += diff; } return codec_cfg->data_len; @@ -237,7 +251,9 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ net_buf_simple_add_u8(&buf, data_len + sizeof(type)); net_buf_simple_add_u8(&buf, type); - net_buf_simple_add_mem(&buf, data, data_len); + if (data_len > 0) { + net_buf_simple_add_mem(&buf, data, data_len); + } codec_cfg->data_len = buf.len; } else { LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len, From ca1de2fc3961147269cc189c65e99f6f23fee3ce Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 2 Oct 2023 18:52:30 +0300 Subject: [PATCH 1573/4498] tests: btp_mesh: Check correct error code Check actual error code. Signed-off-by: Andrei Emeltchenko --- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index f02d51c905a..1d94eb43cb5 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -3801,7 +3801,7 @@ static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len, return; } - bt_mesh_dfu_slot_commit(slot); + err = bt_mesh_dfu_slot_commit(slot); if (err) { LOG_ERR("Failed to commit slot: %d", err); return; From b0c96580298ac47715fdb1d1ba5ede766676d643 Mon Sep 17 00:00:00 2001 From: Vivekananda Uppunda Date: Mon, 2 Oct 2023 07:19:05 +0530 Subject: [PATCH 1574/4498] net: l2: wifi: Fix Wi-Fi mode get command bug The mode command operation has to be set to WIFI_MGMT_GET when the option -g is provided. It was mistakenly set to true. Correcting the same This PR fixes #63424 and sets the proper value for the get command Signed-off-by: Vivekananda Uppunda --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a39f75919f5..7d03fb0c217 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1306,7 +1306,7 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, mode->mode |= WIFI_SOFTAP_MODE; break; case 'g': - mode->oper = true; + mode->oper = WIFI_MGMT_GET; break; case 'i': mode->if_index = (uint8_t)atoi(optarg); From 026dbdf5392ea0cb96ff8a9a204a2d239de096a5 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 2 Oct 2023 16:59:49 +0200 Subject: [PATCH 1575/4498] cmake: LLVM LLD minimum version 14.0.0 Fixes: #35671 Add minimal version required for LLVM LLD linker. Linking fails with older LLVM LLD, such as v10.0.0. LLVM v14.0.0 was released in 2022, and latest LLVM is v17.0.1. Zephyr currently doesn't have a strict minimum version of LLVM specified, but based on LLVM development and known issues on older releases, then a minimum version of v14.0.0 has been chosen in this commit. Signed-off-by: Torsten Rasmussen --- cmake/linker/lld/target.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/linker/lld/target.cmake b/cmake/linker/lld/target.cmake index 0daf19a7c76..77ebf8d3121 100644 --- a/cmake/linker/lld/target.cmake +++ b/cmake/linker/lld/target.cmake @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") -find_package(LlvmLld REQUIRED) +find_package(LlvmLld 14.0.0 REQUIRED) set(CMAKE_LINKER ${LLVMLLD_LINKER}) set_ifndef(LINKERFLAGPREFIX -Wl) From 8f5b3334ed336f7d24f5414f0d6175c851f192d4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 2 Oct 2023 16:54:23 +0200 Subject: [PATCH 1576/4498] doc: release: 3.5: native boards updates Release notes content related to the POSIX arch and native boards. Signed-off-by: Alberto Escolar Piedras --- doc/releases/release-notes-3.5.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 3aa025327d5..27a12ba7921 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -9,6 +9,8 @@ We are pleased to announce the release of Zephyr version 3.5.0. Major enhancements with this release include: +* Added native_sim (successor to native_posix) + The following sections provide detailed lists of changes by component. Security Vulnerability Related @@ -45,6 +47,16 @@ Architectures * Xtensa +* POSIX + + * Has been reworked to use the native simulator. + * New boards have been added. + * For the new boards, embedded C libraries can be used, and conflicts with the host symbols + and libraries avoided. + * The :ref:`POSIX OS abstraction` is supported in these new boards. + * AMP targets are now supported. + * Added support for LLVM source profiling/coverage. + Bluetooth ********* @@ -91,6 +103,12 @@ Boards & SoC Support * Added support for these Xtensa boards: +* Added support for these POSIX boards: + + * :ref:`native_sim(_64) ` + * nrf5340bsim_nrf5340_cpu(net|app). A simulated nrf5340 SOC, which uses Babblesim for its radio + traffic. + * Made these changes for ARC boards: * Made these changes for ARM boards: @@ -103,6 +121,13 @@ Boards & SoC Support * Made these changes for Xtensa boards: +* Made these changes for POSIX boards: + + * nrf52_bsim: + + * Has been reworked to use the native simulator as its runner. + * Multiple HW models improvements and fixes. GPIO & GPIOTE peripherals added. + * Removed support for these ARC boards: * Removed support for these ARM boards: From 6c12ed18ad793700f1b1c5a4277a74ce3f0ca5dd Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 16:02:17 +0200 Subject: [PATCH 1577/4498] tests: Bluetooth: Add inval testing of bt_bap_broadcast_source_stop Add invalid parameter and state testing of bt_bap_broadcast_source_stop Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index 5b7af42dfbc..a41fd8f219b 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -976,6 +976,48 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_inval zassert_not_equal(0, err, "Did not fail with deleted broadcast source"); } +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_stop_inval_source_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_le_ext_adv ext_adv = {0}; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); + zassert_equal(0, err, "Unable to start broadcast source: err %d", err); + + err = bt_bap_broadcast_source_stop(NULL); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_stop_inval_state) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_le_ext_adv ext_adv = {0}; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_start(fixture->source, &ext_adv); + zassert_equal(0, err, "Unable to start broadcast source: err %d", err); + + err = bt_bap_broadcast_source_stop(fixture->source); + zassert_equal(0, err, "Unable to stop broadcast source: err %d", err); + + err = bt_bap_broadcast_source_stop(NULL); + zassert_not_equal(0, err, "Did not fail with stopping already stopped source"); +} + + ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_delete_inval_source_null) { int err; From e67d6c2fa45be3e1d5b4d3037f057e1ae1f0eecf Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 6 Sep 2023 16:02:52 +0200 Subject: [PATCH 1578/4498] tests: bsim: Bluetooth: Remove broadcast_source_stop_inval Removed the tests for invalid bt_bap_broadcast_source_stop parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 70e44d30f34..b606f5d6fda 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -356,30 +356,6 @@ static void test_broadcast_source_start(struct bt_bap_broadcast_source *source, } } -static void test_broadcast_source_stop_inval_state(struct bt_bap_broadcast_source *source) -{ - int err; - - printk("Test bt_bap_broadcast_source_stop in stopped state\n"); - err = bt_bap_broadcast_source_stop(source); - if (err == 0) { - FAIL("bt_bap_broadcast_source_stop in stopped state did not fail\n"); - return; - } -} - -static void test_broadcast_source_stop_inval(void) -{ - int err; - - printk("Test bt_bap_broadcast_source_stop with NULL source\n"); - err = bt_bap_broadcast_source_stop(NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_stop with NULL source did not fail\n"); - return; - } -} - static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source) { int err; @@ -492,9 +468,7 @@ static void test_main(void) /* Keeping running for a little while */ k_sleep(K_SECONDS(5)); - test_broadcast_source_stop_inval(); test_broadcast_source_stop(source); - test_broadcast_source_stop_inval_state(source); test_broadcast_source_delete(source); source = NULL; From 9dc12095a07264aec27aae48f41851769c581013 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Sep 2023 11:20:08 +0200 Subject: [PATCH 1579/4498] samples: usb: mass: update build instruction using RAM disk Follow up on commit f67dd39bb290 ("drivers: ramdisk: use devicetree to instantiate RAM disk"). Unfortunately, the additional argument must be passed for the default build. Using app.overlay would not always help since the sample has few board-specific overlays. Signed-off-by: Johann Fischer --- samples/subsys/usb/mass/README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/subsys/usb/mass/README.rst b/samples/subsys/usb/mass/README.rst index 4d400e942c9..1c2011f363f 100644 --- a/samples/subsys/usb/mass/README.rst +++ b/samples/subsys/usb/mass/README.rst @@ -15,8 +15,7 @@ into an USB disk. This sample can be found under Requirements ************ -This project requires a USB device driver, and either 32KiB (96KiB optional) -of RAM or a FLASH device. +This project requires a USB device driver, and either 96KiB of RAM or a FLASH device. Building and Running ******************** @@ -30,12 +29,13 @@ RAM-disk Example without any file system ======================================== The default configurations selects RAM-based disk without any file system. -This example only needs additional 32KiB RAM for the RAM-disk and is intended +This example only needs additional 96KiB RAM for the RAM-disk and is intended for testing USB mass storage class implementation. .. zephyr-app-commands:: :zephyr-app: samples/subsys/usb/mass :board: reel_board + :gen-args: -DEXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" :goals: build :compact: @@ -50,7 +50,7 @@ In this example we will build the sample with a RAM-based disk: .. zephyr-app-commands:: :zephyr-app: samples/subsys/usb/mass :board: reel_board - :gen-args: -DCONFIG_APP_MSC_STORAGE_RAM=y + :gen-args: -DEXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" -DCONFIG_APP_MSC_STORAGE_RAM=y :goals: build :compact: From a2a21e6dcf9019cb3cd347d52fc0f02d231aa4b3 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Sep 2023 12:07:41 +0200 Subject: [PATCH 1580/4498] doc: release: add migration guide for RAM disk driver Add migration guide and devicetree example for RAM disk driver. Signed-off-by: Johann Fischer --- doc/releases/migration-guide-3.5.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 6a517ce8737..2f5e66c341d 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -152,6 +152,24 @@ Required changes adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` structure instance the callback relates to. :github:`60536` +* The RAM disk driver has been changed to support multiple instances and instantiation + using devicetree. As a result, Kconfig option :kconfig:option:`CONFIG_DISK_RAM_VOLUME_SIZE` + and Kconfig option :kconfig:option:`CONFIG_DISK_RAM_VOLUME_NAME` are removed, + and the application using the RAM disk must instantiate it using devicetree, + as in the following example: + + .. code-block:: devicetree + + / { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <192>; + }; + }; + + Recommended Changes ******************* From cdebe6ef711ffbd08b5faad48b955fdd077e00fc Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Thu, 21 Sep 2023 23:29:48 -0700 Subject: [PATCH 1581/4498] boards: arm: npcx: update flashing information Update flashing information for npcx7m6fb_evb and npcx9m6f_evb since current OpenOCD in zephyr-sdk has supported them. Signed-off-by: Mulin Chao --- boards/arm/npcx7m6fb_evb/doc/index.rst | 14 ++++++++++++-- boards/arm/npcx9m6f_evb/doc/index.rst | 25 +++++++------------------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/boards/arm/npcx7m6fb_evb/doc/index.rst b/boards/arm/npcx7m6fb_evb/doc/index.rst index e3e855254d6..7222aac1ebb 100644 --- a/boards/arm/npcx7m6fb_evb/doc/index.rst +++ b/boards/arm/npcx7m6fb_evb/doc/index.rst @@ -79,10 +79,20 @@ JTAG only sessions. Flashing ======== -Build application as usual for the ``npcx7m6fb_evb`` board, and flash -using Servo V2, μServo, or Servo V4 (CCD). See the +If the correct IDC headers are installed, this board supports both J-TAG and +also the ChromiumOS servo. + +To flash using Servo V2, μServo, or Servo V4 (CCD), see the `Chromium EC Flashing Documentation`_ for more information. +To flash with J-TAG, install the drivers for your programmer, for example: +SEGGER J-link's drivers are at https://www.segger.com/downloads/jlink/ + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: npcx7m6fb_evb + :maybe-skip-config: + :goals: build flash Debugging ========= diff --git a/boards/arm/npcx9m6f_evb/doc/index.rst b/boards/arm/npcx9m6f_evb/doc/index.rst index e74685c965e..898f3051220 100644 --- a/boards/arm/npcx9m6f_evb/doc/index.rst +++ b/boards/arm/npcx9m6f_evb/doc/index.rst @@ -93,8 +93,8 @@ JTAG-only sessions. Flashing ======== -If the correct headers are installed, this board supports both J-TAG and also -the ChromiumOS servo. +If the correct IDC headers are installed, this board supports both J-TAG and +also the ChromiumOS servo. To flash using Servo V2, μServo, or Servo V4 (CCD), see the `Chromium EC Flashing Documentation`_ for more information. @@ -102,22 +102,11 @@ To flash using Servo V2, μServo, or Servo V4 (CCD), see the To flash with J-TAG, install the drivers for your programmer, for example: SEGGER J-link's drivers are at https://www.segger.com/downloads/jlink/ -The openocd from Zephyr SDK 0.14.2 doesn't include npcx support, so build openocd from source.:: - - sudo apt-get install libftdi-dev libusb-1.0.0-dev - git clone https://git.code.sf.net/p/openocd/code ~/openocd - cd ~/openocd - ./bootstrap - ./configure --enable-jlink --enable-ftdi - make clean - make - sudo make install - -Build and flash the blinky sample.:: - - west build -t clean && \ - west build -c -p auto -b npcx9m6f_evb samples/basic/blinky && \ - west flash --openocd /usr/local/bin/openocd +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: npcx9m6f_evb + :maybe-skip-config: + :goals: build flash Debugging ========= From e503ec4064d4e4ac828bfaf4810f35f1301ca96b Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Fri, 22 Sep 2023 14:54:40 -0500 Subject: [PATCH 1582/4498] drivers: ethernet: Fix adin2111 multiple compatibles support The adin2111 ethernet driver supports both adi,adin2111 and adi,adin1110 devicetree compatibles, however it failed to build when both compatibles existed in the same devicetree. This may be an unusual configuration for real systems, but was found when extending tests/drivers/build_all/ethernet to cover both compatibles. Signed-off-by: Maureen Helm --- drivers/ethernet/eth_adin2111.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index aa93d3ee7c4..f2ebb24a680 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -943,57 +943,57 @@ static const struct ethernet_api adin2111_port_api = { #define ADIN2111_PORT_MAC(adin_n, port_n) \ DT_PROP(DT_CHILD(DT_DRV_INST(adin_n), port##port_n), local_mac_address) -#define ADIN2111_PORT_DEVICE_INIT_INSTANCE(parent_n, port_n, phy_n) \ - static struct adin2111_port_data adin2111_port_data_##port_n = { \ +#define ADIN2111_PORT_DEVICE_INIT_INSTANCE(parent_n, port_n, phy_n, name) \ + static struct adin2111_port_data name##_port_data_##port_n = { \ .mac_addr = ADIN2111_PORT_MAC(parent_n, phy_n), \ }; \ - static const struct adin2111_port_config adin2111_port_config_##port_n = { \ + static const struct adin2111_port_config name##_port_config_##port_n = { \ .adin = DEVICE_DT_INST_GET(parent_n), \ .phy = ADIN2111_MDIO_PHY_BY_ADDR(parent_n, phy_n), \ .port_idx = port_n, \ .phy_addr = phy_n, \ }; \ - NET_DEVICE_INIT_INSTANCE(adin2111_port_##port_n, "port_" ADIN2111_XSTR(port_n), port_n, \ - NULL, NULL, &adin2111_port_data_##port_n, \ - &adin2111_port_config_##port_n, CONFIG_ETH_INIT_PRIORITY, \ + NET_DEVICE_INIT_INSTANCE(name##_port_##port_n, "port_" ADIN2111_XSTR(port_n), port_n, \ + NULL, NULL, &name##_port_data_##port_n, \ + &name##_port_config_##port_n, CONFIG_ETH_INIT_PRIORITY, \ &adin2111_port_api, ETHERNET_L2, \ NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU); #define ADIN2111_SPI_OPERATION ((uint16_t)(SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8))) -#define ADIN2111_MAC_INITIALIZE(inst, dev_id, ifaces) \ - static uint8_t __aligned(4) adin2111_buffer_##inst[CONFIG_ETH_ADIN2111_BUFFER_SIZE]; \ - static const struct adin2111_config adin2111_config_##inst = { \ +#define ADIN2111_MAC_INITIALIZE(inst, dev_id, ifaces, name) \ + static uint8_t __aligned(4) name##_buffer_##inst[CONFIG_ETH_ADIN2111_BUFFER_SIZE]; \ + static const struct adin2111_config name##_config_##inst = { \ .id = dev_id, \ .spi = SPI_DT_SPEC_INST_GET(inst, ADIN2111_SPI_OPERATION, 1), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, { 0 }), \ }; \ - static struct adin2111_data adin2111_data_##inst = { \ + static struct adin2111_data name##_data_##inst = { \ .ifaces_left_to_init = ifaces, \ .port = {}, \ .offload_sem = Z_SEM_INITIALIZER(adin2111_data_##inst.offload_sem, 0, 1), \ .lock = Z_MUTEX_INITIALIZER(adin2111_data_##inst.lock), \ - .buf = adin2111_buffer_##inst, \ + .buf = name##_buffer_##inst, \ }; \ /* adin */ \ DEVICE_DT_DEFINE(DT_DRV_INST(inst), adin2111_init, NULL, \ - &adin2111_data_##inst, &adin2111_config_##inst, \ + &name##_data_##inst, &name##_config_##inst, \ POST_KERNEL, CONFIG_ETH_ADIN2111_INIT_PRIORITY, \ NULL); -#define ADIN2111_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2) \ +#define ADIN2111_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2, adin2111) \ /* ports */ \ - ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1) \ - ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2) + ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin2111) \ + ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2, adin2111) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT adi_adin2111 DT_INST_FOREACH_STATUS_OKAY(ADIN2111_MAC_INIT) -#define ADIN1110_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN1110_MAC, 1) \ +#define ADIN1110_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN1110_MAC, 1, adin1110) \ /* ports */ \ - ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1) + ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin1110) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT adi_adin1110 From 66a03e6a38e7cd29dd41816bb76b4ac651153515 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Mon, 25 Sep 2023 14:54:59 -0500 Subject: [PATCH 1583/4498] drivers: ethernet: Remove CONFIG_ETH_ADIN2111_INIT_PRIORITY Simplifies the adin2111 ethernet driver to use the generic driver class initialization priority instead of a driver-specific priority. Suggested-by: Georgij Cernysiov Signed-off-by: Maureen Helm --- drivers/ethernet/Kconfig.adin2111 | 10 ---------- drivers/ethernet/eth_adin2111.c | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/ethernet/Kconfig.adin2111 b/drivers/ethernet/Kconfig.adin2111 index 11914519667..2e1cbd8a0af 100644 --- a/drivers/ethernet/Kconfig.adin2111 +++ b/drivers/ethernet/Kconfig.adin2111 @@ -20,16 +20,6 @@ menuconfig ETH_ADIN2111 if ETH_ADIN2111 -config ETH_ADIN2111_INIT_PRIORITY - int "ADIN2111 driver init priority" - default 72 - help - ADIN2111 device driver initialization priority. - Must be initialized after SPI, but before MDIO - and ports. - - Both ports use ETH_INIT_PRIORITY initialization priority. - config ETH_ADIN2111_IRQ_THREAD_STACK_SIZE int "Stack size for a thread that processes ADIN IRQ" default 2048 diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index f2ebb24a680..c26671b0e3f 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -979,7 +979,7 @@ static const struct ethernet_api adin2111_port_api = { /* adin */ \ DEVICE_DT_DEFINE(DT_DRV_INST(inst), adin2111_init, NULL, \ &name##_data_##inst, &name##_config_##inst, \ - POST_KERNEL, CONFIG_ETH_ADIN2111_INIT_PRIORITY, \ + POST_KERNEL, CONFIG_ETH_INIT_PRIORITY, \ NULL); #define ADIN2111_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2, adin2111) \ From aab537c8e2cf3bcca9b092c8c26cc8bdf7754663 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Mon, 25 Sep 2023 14:31:15 -0500 Subject: [PATCH 1584/4498] drivers: ethernet: Decouple generic MII PHY and adin2111 driver Kconfigs Decouples the generic MII PHY driver from the adin2111 driver by making it depend on an ethernet-phy compatible devicetree node rather than the adin2111 driver not being enabled. This makes it possible to add the adin2111 driver to tests/drivers/build_all/ethernet Signed-off-by: Maureen Helm --- drivers/ethernet/phy/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index bd5d9fb48ed..ae1229de1fc 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -23,7 +23,8 @@ config PHY_INIT_PRIORITY config PHY_GENERIC_MII bool "Generic MII PHY Driver" - default y if !ETH_ADIN2111 + default y + depends on DT_HAS_ETHERNET_PHY_ENABLED depends on MDIO help This is a generic MII PHY interface that communicates with the From 00d03fe942c08c2444636d24266333cfcaea5fcb Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Fri, 22 Sep 2023 15:14:26 -0500 Subject: [PATCH 1585/4498] tests: drivers: build_all: Add adin2111 to ethernet driver build test Ensures that the eth_adin2111 driver builds for both of its supported devicetree compatibles by adding adi,adin2111 and adi,adin1110 compatible nodes to the ethernet driver build test. Sets relevant device device driver initialization priorities to be equal, allowing devicetree dependency ordinals to determine the initialization sequence. Signed-off-by: Maureen Helm --- tests/drivers/build_all/ethernet/app.overlay | 60 ++++++++++++++++++++ tests/drivers/build_all/ethernet/prj.conf | 5 ++ 2 files changed, 65 insertions(+) diff --git a/tests/drivers/build_all/ethernet/app.overlay b/tests/drivers/build_all/ethernet/app.overlay index 5f1d7fb2f45..a80c949e036 100644 --- a/tests/drivers/build_all/ethernet/app.overlay +++ b/tests/drivers/build_all/ethernet/app.overlay @@ -33,6 +33,8 @@ /* one entry for every devices at spi.dtsi */ cs-gpios = <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>; @@ -60,6 +62,64 @@ int-gpios = <&test_gpio 0 0>; reset-gpios = <&test_gpio 0 0>; }; + + test_spi_adin1110: adin1110@3 { + compatible = "adi,adin1110"; + reg = <0x3>; + spi-max-frequency = <25000000>; + int-gpios = <&test_gpio 0 0>; + reset-gpios = <&test_gpio 0 0>; + + port1 { + local-mac-address = [ CA 2F B7 10 23 63 ]; + }; + + mdio { + compatible = "adi,adin2111-mdio"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@1 { + reg = <0x1>; + compatible = "adi,adin2111-phy"; + status = "okay"; + }; + }; + }; + + test_spi_adin2111: adin2111@4 { + compatible = "adi,adin2111"; + reg = <0x4>; + spi-max-frequency = <0>; + int-gpios = <&test_gpio 0 0>; + reset-gpios = <&test_gpio 0 0>; + + port1 { + local-mac-address = [ CA 2F B7 10 23 63 ]; + }; + port2 { + local-mac-address = [ 3C 82 D4 A2 29 8E ]; + }; + + mdio { + compatible = "adi,adin2111-mdio"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@1 { + reg = <0x1>; + compatible = "adi,adin2111-phy"; + status = "okay"; + }; + ethernet-phy@2 { + reg = <0x2>; + compatible = "adi,adin2111-phy"; + status = "okay"; + }; + }; + }; }; }; }; diff --git a/tests/drivers/build_all/ethernet/prj.conf b/tests/drivers/build_all/ethernet/prj.conf index de2c010c47f..f20cbb1d088 100644 --- a/tests/drivers/build_all/ethernet/prj.conf +++ b/tests/drivers/build_all/ethernet/prj.conf @@ -7,3 +7,8 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_TEST_USERSPACE=y CONFIG_GPIO=y + +CONFIG_SPI_INIT_PRIORITY=50 +CONFIG_ETH_INIT_PRIORITY=50 +CONFIG_MDIO_INIT_PRIORITY=50 +CONFIG_PHY_INIT_PRIORITY=50 From edb9aa308bd3b58761a78ecc46415f327c5456e8 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 12:43:49 +0200 Subject: [PATCH 1586/4498] doc: ieee802154: fixes L2 docs Fixes several minor doc glitches that were overlooked in the previous major doc update: - Fixes some minor formatting issues. - Fixes wording and typos in some instances. - Adds at least a one-sentence definition to all concepts that previously only had a spec pointer. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154.h | 97 ++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index bb400cbbd6d..e4ef8bba6f8 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -97,8 +97,23 @@ extern "C" { * @{ */ -#define IEEE802154_MAX_PHY_PACKET_SIZE 127 /**< see section 11.3, aMaxPhyPacketSize */ -#define IEEE802154_FCS_LENGTH 2 /**< see section 7.2.1.1 */ +/** + * @brief Represents the PHY constant aMaxPhyPacketSize, see section 11.3. + * + * @note Currently only 127 byte sized packets are supported although some PHYs + * (e.g. SUN, MSK, LECIM, ...) support larger packet sizes. Needs to be changed + * once those PHYs should be fully supported. + */ +#define IEEE802154_MAX_PHY_PACKET_SIZE 127 + +/** + * @brief Represents the frame check sequence length, see section 7.2.1.1. + * + * @note Currently only a 2 byte FCS is supported although some PHYs (e.g. SUN, + * TVWS, ...) optionally support a 4 byte FCS. Needs to be changed once those + * PHYs should be fully supported. + */ +#define IEEE802154_FCS_LENGTH 2 /** * @brief IEEE 802.15.4 "hardware" MTU (not to be confused with L3/IP MTU), i.e. @@ -110,9 +125,9 @@ extern "C" { * concept in Linux and Zephyr's L3. It is not a concept from the IEEE 802.15.4 * standard. * - * @note Currently we only support the original frame size from the 2006 - * standard version and earlier. The 2015+ standard introduced PHYs with larger - * PHY payload. These are not (yet) supported in Zephyr. + * @note Currently only the original frame size from the 2006 standard version + * and earlier is supported. The 2015+ standard introduced PHYs with larger PHY + * payload. These are not (yet) supported in Zephyr. */ #define IEEE802154_MTU (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_FCS_LENGTH) @@ -134,23 +149,42 @@ extern "C" { #define IEEE802154_NO_CHANNEL USHRT_MAX /** - * @{ - * See sections 6.1 and 7.3.5 + * Represents the IEEE 802.15.4 broadcast short address, see sections 6.1 and + * 8.4.3, table 8-94, macShortAddress. */ #define IEEE802154_BROADCAST_ADDRESS 0xffff + +/** + * Represents a special IEEE 802.15.4 short address that indicates that a device + * has been associated with a coordinator but did not receive a short address, + * see sections 6.4.1 and 8.4.3, table 8-94, macShortAddress. + */ #define IEEE802154_NO_SHORT_ADDRESS_ASSIGNED 0xfffe -/** @} */ -/* See section 6.1 */ +/** Represents the IEEE 802.15.4 broadcast PAN ID, see section 6.1. */ #define IEEE802154_BROADCAST_PAN_ID 0xffff -/* See section 7.3.5 */ +/** + * Represents a special value of the macShortAddress MAC PIB attribute, while the + * device is not associated, see section 8.4.3, table 8-94. + */ #define IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED IEEE802154_BROADCAST_ADDRESS + +/** + * Represents a special value of the macPanId MAC PIB attribute, while the + * device is not associated, see section 8.4.3, table 8-94. + */ #define IEEE802154_PAN_ID_NOT_ASSOCIATED IEEE802154_BROADCAST_PAN_ID -/** interface-level security attributes, see section 9.5. */ +/** Interface-level security attributes, see section 9.5. */ struct ieee802154_security_ctx { - /** section 9.5, secFrameCounter */ + /** + * Interface-level outgoing frame counter, section 9.5, table 9-8, + * secFrameCounter. + * + * Only used when the driver does not implement key-specific frame + * counters. + */ uint32_t frame_counter; /** @cond INTERNAL_HIDDEN */ @@ -159,41 +193,40 @@ struct ieee802154_security_ctx { /** INTERNAL_HIDDEN @endcond */ /** - * @brief frame-level security key material + * @brief Interface-level frame encryption security key material * * @details Currently native L2 only supports a single secKeySource, see * section 9.5, table 9-9, in combination with secKeyMode zero (implicit * key mode), see section 9.4.2.3, table 9-7. * - * @warning This is no longer in accordance with the current version of + * @warning This is no longer in accordance with the 2015+ versions of * the standard and needs to be extended in the future for full security * procedure compliance. */ uint8_t key[16]; - /** frame-level security key material */ + /** Length in bytes of the interface-level security key material. */ uint8_t key_len; /** - * @brief security level - * - * @details Currently native L2 supports a single security level for all - * frame types, commands and information elements, see section 9.4.2.2, - * table 9-6 and ieee802154_security_level. + * @brief Frame security level, possible values are defined in section + * 9.4.2.2, table 9-6. * - * @warning This is no longer in accordance with the current version of - * the standard and needs to be extended in the future for full security - * procedure compliance. + * @warning Currently native L2 allows to configure one common security + * level for all frame types, commands and information elements. This is + * no longer in accordance with the 2015+ versions of the standard and + * needs to be extended in the future for full security procedure + * compliance. */ uint8_t level : 3; /** - * @brief key_mode + * @brief Frame security key mode * * @details Currently only implicit key mode is partially supported, see * section 9.4.2.3, table 9-7, secKeyMode. * - * @warning This is no longer in accordance with the current version of + * @warning This is no longer in accordance with the 2015+ versions of * the standard and needs to be extended in the future for full security * procedure compliance. */ @@ -305,14 +338,14 @@ struct ieee802154_context { uint16_t coord_short_addr; #endif - /** transmission power */ + /** Transmission power in dBm. */ int16_t tx_power; /** L2 flags */ enum net_l2_flags flags; /** - * @brief DSN + * @brief Data sequence number * * @details The sequence number added to the transmitted Data frame or * MAC command, see section 8.4.3.1, table 8-94, macDsn. @@ -322,8 +355,10 @@ struct ieee802154_context { /** * @brief Device Role * - * @details See section 6.1: A device may be operating as end device (0 - * - default), coordinator (1), or PAN coordinator (2). + * @details See section 6.1: A device may be operating as end device + * (0), coordinator (1), or PAN coordinator (2). If no device role is + * explicitly configured then the device will be treated as an end + * device. * * A value of 3 is undefined. * @@ -349,8 +384,8 @@ struct ieee802154_context { /** * @brief Context lock * - * @details guards all mutable context attributes unless otherwise - * mentioned on attribute level + * @details This lock guards all mutable context attributes unless + * otherwise mentioned on attribute level. */ struct k_sem ctx_lock; }; From f3556f3f8c1c9ca3a521ee92bb3c34b7f842868a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 12:45:39 +0200 Subject: [PATCH 1587/4498] doc: ieee802154: fix driver API Fixes a few minor documentation issues that slipped through in the recent large documentation update: - Fixes the ordering of sections to follow the ordering of the correspondig sections in the IEEE 802.15.4 standard. - Fixes a few note/detail sections that were not recognized as such. - Removes internal TODO markers from the publicly visible docs. - Fixes wording and typos in a few instances. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154_radio.h | 416 ++++++++++++++------------ 1 file changed, 220 insertions(+), 196 deletions(-) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index c837a2991bd..f4d8ff6d318 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -61,7 +61,7 @@ extern "C" { */ /** - * @name MAC functional description (section 6) + * @name IEEE 802.15.4-2020, Section 6: MAC functional description * @{ */ @@ -84,7 +84,7 @@ extern "C" { /** - * @name MAC services (section 8) + * @name IEEE 802.15.4-2020, Section 8: MAC services * @{ */ @@ -125,7 +125,7 @@ extern "C" { /** - * @name General PHY requirements (section 10) + * @name IEEE 802.15.4-2020, Section 10: General PHY requirements * @{ */ @@ -142,7 +142,7 @@ extern "C" { * PIB attribute that represented channel page/number combinations as a * bitmap. This attribute was removed in later versions of the standard as the * number of channels increased beyond what could be represented by a bit map. - * That's the reason why we chose to represent supported channels as a + * That's the reason why it was decided to represent supported channels as a * combination of channel pages and ranges instead. * - In the 2020 version of the standard, 13 channel pages are explicitly * defined, but up to 32 pages could in principle be supported. This was a @@ -153,8 +153,8 @@ extern "C" { * - ASK PHY (channel page one) was deprecated in the 2015 version of the * standard. The 2020 version of the standard is a bit ambivalent whether * channel page one disappeared as well or should be interpreted as O-QPSK now - * (see section 10.1.3.3). We resolve this ambivalence by deprecating channel - * page one. + * (see section 10.1.3.3). In Zephyr this ambivalence is resolved by + * deprecating channel page one. * - For some PHYs the standard doesn't clearly specify a channel page, namely * the GFSK, RS-GFSK, CMB and TASK PHYs. These are all rather new and left out * in our list as long as no driver wants to implement them. @@ -242,8 +242,8 @@ struct ieee802154_phy_supported_channels { /** * @brief Pointer to an array of channel range structures. * - * @warning The pointer must be stable and valid throughout the life of - * the interface. + * @warning The pointer must be valid and constant throughout the life + * of the interface. */ const struct ieee802154_phy_channel_range *const ranges; @@ -293,7 +293,7 @@ struct ieee802154_phy_supported_channels { /** - * @name PHY services (section 11) + * @name IEEE 802.15.4-2020, Section 11: PHY services * @{ */ @@ -321,7 +321,7 @@ struct ieee802154_phy_supported_channels { /** - * @name O-QPSK PHY (section 12) + * @name IEEE 802.15.4-2020, Section 12: O-QPSK PHY * @{ */ @@ -338,7 +338,7 @@ struct ieee802154_phy_supported_channels { /** - * @name BPSK PHY (section 13) + * @name IEEE 802.15.4-2020, Section 13: BPSK PHY * @{ */ @@ -352,7 +352,7 @@ struct ieee802154_phy_supported_channels { /** - * @name HRP UWB PHY (section 15) + * @name IEEE 802.15.4-2020, Section 15: HRP UWB PHY * * @details For HRP UWB the symbol period is derived from the preamble symbol period * (T_psym), see section 11.3, table 11-1 and section 15.2.5, table 15-4 @@ -406,7 +406,7 @@ enum ieee802154_phy_hrp_uwb_nominal_prf { /** - * @name SUN FSK PHY (section 19) + * @name IEEE 802.15.4-2020, Section 19: SUN FSK PHY * @{ */ @@ -419,7 +419,7 @@ enum ieee802154_phy_hrp_uwb_nominal_prf { /** @} */ /** - * @name IEEE 802.15.4 driver + * @name IEEE 802.15.4 Driver API * @{ */ @@ -517,7 +517,8 @@ enum ieee802154_event { IEEE802154_EVENT_TX_STARTED, /** Data reception failed */ IEEE802154_EVENT_RX_FAILED, - /** An RX slot ended, requires @ref IEEE802154_HW_RXTIME + /** + * An RX slot ended, requires @ref IEEE802154_HW_RXTIME. * * @note This event SHALL not be triggered by drivers when RX is * synchronously switched of due to a call to `stop()` or an RX slot @@ -620,194 +621,208 @@ enum ieee802154_fpb_mode { /** IEEE 802.15.4 driver configuration types. */ enum ieee802154_config_type { - /** Indicates how the driver should set the Frame Pending bit in ACK - * responses for Data Requests. If enabled, the driver should determine - * whether to set the bit or not based on the information provided with - * @ref IEEE802154_CONFIG_ACK_FPB config and FPB address matching mode - * specified. Otherwise, Frame Pending bit should be set to ``1`` (see - * section 6.7.3). - * - * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is - * available in any interface operational state. + /** + * Indicates how the driver should set the Frame Pending bit in ACK + * responses for Data Requests. If enabled, the driver should determine + * whether to set the bit or not based on the information provided with + * @ref IEEE802154_CONFIG_ACK_FPB config and FPB address matching mode + * specified. Otherwise, Frame Pending bit should be set to ``1`` (see + * section 6.7.3). + * + * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is + * available in any interface operational state. */ IEEE802154_CONFIG_AUTO_ACK_FPB, - /** Indicates whether to set ACK Frame Pending bit for specific address - * or not. Disabling the Frame Pending bit with no address provided - * (NULL pointer) should disable it for all enabled addresses. + /** + * Indicates whether to set ACK Frame Pending bit for specific address + * or not. Disabling the Frame Pending bit with no address provided + * (NULL pointer) should disable it for all enabled addresses. * - * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is - * available in any interface operational state. + * @note requires @ref IEEE802154_HW_TX_RX_ACK capability and is + * available in any interface operational state. */ IEEE802154_CONFIG_ACK_FPB, - /** Indicates whether the device is a PAN coordinator. This influences - * packet filtering. + /** + * Indicates whether the device is a PAN coordinator. This influences + * packet filtering. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. */ IEEE802154_CONFIG_PAN_COORDINATOR, - /** Enable/disable promiscuous mode. + /** + * Enable/disable promiscuous mode. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. */ IEEE802154_CONFIG_PROMISCUOUS, - /** Specifies new IEEE 802.15.4 driver event handler. Specifying NULL as - * a handler will disable events notification. + /** + * Specifies new IEEE 802.15.4 driver event handler. Specifying NULL as + * a handler will disable events notification. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. */ IEEE802154_CONFIG_EVENT_HANDLER, - /** Updates MAC keys, key index and the per-key frame counter for drivers - * supporting transmit security offloading, see section 9.5, tables 9-9 - * and 9-10. The key configuration SHALL NOT be accepted if the frame - * counter (in case frame counter per key is true) is not strictly - * larger than the current frame counter associated with the same key, - * see sections 8.2.2, 9.2.4 g/h) and 9.4.3. - * - * @note Available in any interface operational state. + /** + * Updates MAC keys, key index and the per-key frame counter for drivers + * supporting transmit security offloading, see section 9.5, tables 9-9 + * and 9-10. The key configuration SHALL NOT be accepted if the frame + * counter (in case frame counter per key is true) is not strictly + * larger than the current frame counter associated with the same key, + * see sections 8.2.2, 9.2.4 g/h) and 9.4.3. + * + * @note Available in any interface operational state. */ IEEE802154_CONFIG_MAC_KEYS, - /** Sets the current MAC frame counter value associated with the - * interface for drivers supporting transmit security offloading, see - * section 9.5, table 9-8, secFrameCounter. - * - * @warning The frame counter MUST NOT be accepted if it is not - * strictly greater than the current frame counter associated with the - * interface, see sections 8.2.2, 9.2.4 g/h) and 9.4.3. Otherwise the - * replay protection provided by the frame counter may be compromised. - * Drivers SHALL return -EINVAL in case the configured frame counter - * does not conform to this requirement. - * - * @note Available in any interface operational state. + /** + * Sets the current MAC frame counter value associated with the + * interface for drivers supporting transmit security offloading, see + * section 9.5, table 9-8, secFrameCounter. + * + * @warning The frame counter MUST NOT be accepted if it is not + * strictly greater than the current frame counter associated with the + * interface, see sections 8.2.2, 9.2.4 g/h) and 9.4.3. Otherwise the + * replay protection provided by the frame counter may be compromised. + * Drivers SHALL return -EINVAL in case the configured frame counter + * does not conform to this requirement. + * + * @note Available in any interface operational state. */ IEEE802154_CONFIG_FRAME_COUNTER, - /** Sets the current MAC frame counter value if the provided value is greater than - * the current one. + /** + * Sets the current MAC frame counter value if the provided value is greater than + * the current one. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. * - * @note This configuration option does not conform to the requirements - * specified in #61227 as it is redundant with @ref - * IEEE802154_CONFIG_FRAME_COUNTER, and will therefore be deprecated in - * the future. + * @warning This configuration option does not conform to the + * requirements specified in #61227 as it is redundant with @ref + * IEEE802154_CONFIG_FRAME_COUNTER, and will therefore be deprecated in + * the future. */ IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER, - /** Set or unset a radio reception window (RX slot). This can be used for - * any scheduled reception, e.g.: Zigbee GP device, CSL, TSCH, etc. - * - * @details The start and duration parameters of the RX slot are - * relative to the network subsystem's local clock. If the start - * parameter of the RX slot is -1 then any previously configured RX - * slot SHALL be canceled immediately. If the start parameter is any - * value in the past (including 0) or the duration parameter is zero - * then the receiver SHALL remain off forever until the RX slot has - * either been removed or re-configured to point to a future start - * time. If an RX slot is configured while the previous RX slot is - * still scheduled, then the previous slot SHALL be cancelled and the - * new slot scheduled instead. - * - * RX slots MAY be programmed while the driver is "DOWN". If any past - * or future RX slot is configured when calling `start()` then the - * interface SHALL be placed in "UP" state but the receiver SHALL not - * be started. - * - * The driver SHALL take care to start/stop the receiver autonomously, - * asynchronously and automatically around the RX slot. The driver - * SHALL resume power just before the RX slot and suspend it again - * after the slot unless another programmed event forces the driver not - * to suspend. The driver SHALL switch to the programmed channel - * before the RX slot and back to the channel set with set_channel() - * after the RX slot. If the driver interface is "DOWN" when the start - * time of an RX slot arrives, then the RX slot SHALL not be observed - * and the receiver SHALL remain off. - * - * If the driver is "UP" while configuring an RX slot, the driver SHALL - * turn off the receiver immediately and (possibly asynchronously) put - * the driver into the lowest possible power saving mode until the - * start of the RX slot. If the driver is "UP" while the RX slot is - * deleted, then the driver SHALL enable the receiver immediately. The - * receiver MUST be ready to receive packets before returning from the - * `configure()` operation in this case. - * - * This behavior means that setting an RX slot implicitly sets the MAC - * PIB attribute macRxOnWhenIdle (see section 8.4.3.1, table 8-94) to - * "true" while deleting the RX slot implicitly sets macRxOnWhenIdle to - * "false". - * - * @note requires @ref IEEE802154_HW_RXTIME capability and is available - * in any interface operational state. + /** + * Set or unset a radio reception window (RX slot). This can be used for + * any scheduled reception, e.g.: Zigbee GP device, CSL, TSCH, etc. + * + * @details The start and duration parameters of the RX slot are + * relative to the network subsystem's local clock. If the start + * parameter of the RX slot is -1 then any previously configured RX + * slot SHALL be canceled immediately. If the start parameter is any + * value in the past (including 0) or the duration parameter is zero + * then the receiver SHALL remain off forever until the RX slot has + * either been removed or re-configured to point to a future start + * time. If an RX slot is configured while the previous RX slot is + * still scheduled, then the previous slot SHALL be cancelled and the + * new slot scheduled instead. + * + * RX slots MAY be programmed while the driver is "DOWN". If any past + * or future RX slot is configured when calling `start()` then the + * interface SHALL be placed in "UP" state but the receiver SHALL not + * be started. + * + * The driver SHALL take care to start/stop the receiver autonomously, + * asynchronously and automatically around the RX slot. The driver + * SHALL resume power just before the RX slot and suspend it again + * after the slot unless another programmed event forces the driver not + * to suspend. The driver SHALL switch to the programmed channel + * before the RX slot and back to the channel set with set_channel() + * after the RX slot. If the driver interface is "DOWN" when the start + * time of an RX slot arrives, then the RX slot SHALL not be observed + * and the receiver SHALL remain off. + * + * If the driver is "UP" while configuring an RX slot, the driver SHALL + * turn off the receiver immediately and (possibly asynchronously) put + * the driver into the lowest possible power saving mode until the + * start of the RX slot. If the driver is "UP" while the RX slot is + * deleted, then the driver SHALL enable the receiver immediately. The + * receiver MUST be ready to receive packets before returning from the + * `configure()` operation in this case. + * + * This behavior means that setting an RX slot implicitly sets the MAC + * PIB attribute macRxOnWhenIdle (see section 8.4.3.1, table 8-94) to + * "false" while deleting the RX slot implicitly sets macRxOnWhenIdle to + * "true". + * + * @note requires @ref IEEE802154_HW_RXTIME capability and is available + * in any interface operational state. */ IEEE802154_CONFIG_RX_SLOT, - /** Configure CSL receiver (Endpoint) period - * - * @details In order to configure a CSL receiver the upper layer should combine several - * configuration options in the following way: - * 1. Use @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE once to inform the driver of the - * short and extended addresses of the peer to which it should inject CSL IEs. - * 2. Use @ref IEEE802154_CONFIG_CSL_RX_TIME periodically, before each use of - * @ref IEEE802154_CONFIG_CSL_PERIOD setting parameters of the nearest CSL RX window, - * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not - * the nearest one) CSL RX window, to allow the driver to calculate the proper - * CSL Phase to the nearest CSL window to inject in the CSL IEs for both transmitted - * data and ACK frames. - * 3. Use @ref IEEE802154_CONFIG_CSL_PERIOD on each value change to update the current - * CSL period value which will be injected in the CSL IEs together with the CSL Phase - * based on @ref IEEE802154_CONFIG_CSL_RX_TIME. - * 4. Use @ref IEEE802154_CONFIG_RX_SLOT periodically to schedule the immediate receive - * window early enough before the expected window start time, taking into account - * possible clock drifts and scheduling uncertainties. - * - * This diagram shows the usage of the four options over time: - * Start CSL Schedule CSL window - * - * ENH_ACK_HEADER_IE CSL_RX_TIME (following window) - * | | - * | CSL_RX_TIME (nearest window) | RX_SLOT (nearest window) - * | | | | - * | | CSL_PERIOD | | - * | | | | | - * v v v v v - * ----------------------------------------------------------[ CSL window ]-----+ - * ^ | - * | | - * +--------------------- loop ---------+ - * - * @note Available in any interface operational state. - * - * @note This configuration option does not conform to the requirements - * specified in #61227 as it is incompatible with standard primitives - * and may therefore be deprecated in the future. + /** + * Configure CSL receiver (Endpoint) period. + * + * @details In order to configure a CSL receiver the upper layer should combine several + * configuration options in the following way: + * 1. Use @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE once to inform the driver of the + * short and extended addresses of the peer to which it should inject CSL IEs. + * 2. Use @ref IEEE802154_CONFIG_CSL_RX_TIME periodically, before each use of + * @ref IEEE802154_CONFIG_CSL_PERIOD setting parameters of the nearest CSL RX window, + * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not + * the nearest one) CSL RX window, to allow the driver to calculate the proper + * CSL phase to the nearest CSL window to inject in the CSL IEs for both transmitted + * data and ACK frames. + * 3. Use @ref IEEE802154_CONFIG_CSL_PERIOD on each value change to update the current + * CSL period value which will be injected in the CSL IEs together with the CSL phase + * based on @ref IEEE802154_CONFIG_CSL_RX_TIME. + * 4. Use @ref IEEE802154_CONFIG_RX_SLOT periodically to schedule the immediate receive + * window early enough before the expected window start time, taking into account + * possible clock drifts and scheduling uncertainties. + * + * This diagram shows the usage of the four options over time: + * + * Start CSL Schedule CSL window + * + * ENH_ACK_HEADER_IE CSL_RX_TIME (following window) + * | | + * | CSL_RX_TIME (nearest window) | RX_SLOT (nearest window) + * | | | | + * | | CSL_PERIOD | | + * | | | | | + * v v v v v + * ----------------------------------------------------------[ CSL window ]-----+ + * ^ | + * | | + * +--------------------- loop ---------+ + * + * @note Available in any interface operational state. + * + * @warning This configuration option does not conform to the + * requirements specified in #61227 as it is incompatible with standard + * primitives and may therefore be deprecated in the future. */ IEEE802154_CONFIG_CSL_PERIOD, - /** Configure the next CSL receive window (i.e. "channel sample") center, - * in units of nanoseconds relative to the network subsystem's local clock. + /** + * @brief Configure the next CSL receive window (i.e. "channel sample") + * center, in units of nanoseconds relative to the network subsystem's + * local clock. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. * - * @note This configuration option does not conform to the requirements - * specified in #61227 as it is incompatible with standard primitives - * and may therefore be deprecated in the future. + * @warning This configuration option does not conform to the + * requirements specified in #61227 as it is incompatible with standard + * primitives and may therefore be deprecated in the future. */ IEEE802154_CONFIG_CSL_RX_TIME, - /** Indicates whether to inject IE into ENH ACK Frame for specific address - * or not. Disabling the ENH ACK with no address provided (NULL pointer) - * should disable it for all enabled addresses. + /** + * Indicates whether to inject IE into ENH ACK Frame for specific address + * or not. Disabling the ENH ACK with no address provided (NULL pointer) + * should disable it for all enabled addresses. * - * @note Available in any interface operational state. + * @note Available in any interface operational state. * - * @note This configuration option does not conform to the requirements - * specified in #61227 as it is incompatible with standard primitives - * and may therefore be modified in the future. + * @warning This configuration option does not conform to the + * requirements specified in #61227 as it is incompatible with standard + * primitives and may therefore be modified in the future. */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, @@ -860,16 +875,19 @@ struct ieee802154_config { /** see @ref IEEE802154_CONFIG_EVENT_HANDLER */ ieee802154_event_cb_t event_handler; - /** see @ref IEEE802154_CONFIG_MAC_KEYS - * Pointer to an array containing a list of keys used - * for MAC encryption. Refer to secKeyIdLookupDescriptor and - * secKeyDescriptor in IEEE 802.15.4 + /** + * @brief see @ref IEEE802154_CONFIG_MAC_KEYS + * + * @details Pointer to an array containing a list of keys used + * for MAC encryption. Refer to secKeyIdLookupDescriptor and + * secKeyDescriptor in IEEE 802.15.4 * - * key_value field points to a buffer containing the 16 byte - * key. The buffer is copied by the callee. + * The key_value field points to a buffer containing the 16 byte + * key. The buffer SHALL be copied by the driver before + * returning from the call. * - * The variable length array is terminated by key_value field - * set to NULL. + * The variable length array is terminated by key_value field + * set to NULL. */ struct ieee802154_key *mac_keys; @@ -929,7 +947,7 @@ struct ieee802154_config { /** see @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE */ struct { /** - * header IEs to be added to the Enh-Ack frame + * Header IEs to be added to the Enh-Ack frame. * * in little endian */ @@ -1005,28 +1023,29 @@ enum ieee802154_attr { * configuration data that originate from L2. * * @note To keep this union reasonably small, any attribute requiring a large - * memory area, SHALL be provided pointing to stable memory allocated by the - * driver. + * memory area, SHALL be provided pointing to static memory allocated by the + * driver and valid throughout the lifetime of the driver instance. */ struct ieee802154_attr_value { union { + /* TODO: Implement configuration of phyCurrentPage once drivers + * need to support channel page switching at runtime. + */ /** * @brief A bit field that represents the supported channel * pages, see @ref ieee802154_phy_channel_page. * * @note To keep the API extensible as required by the standard, - * we model supported pages as a bitmap to support drivers that - * implement runtime switching between multiple channel pages. + * supported pages are modeled as a bitmap to support drivers + * that implement runtime switching between multiple channel + * pages. * * @note Currently none of the Zephyr drivers implements more * than one channel page at runtime, therefore only one bit will - * be set and we consider the current channel page (see the PHY - * PIB attribute phyCurrentPage, section 11.3, table 11-2) to be - * read-only, fixed and "well known" via the supported channel - * pages attribute. - * - * TODO: Implement configuration of phyCurrentPage once drivers - * need to support channel page switching at runtime. + * be set and the current channel page (see the PHY PIB + * attribute phyCurrentPage, section 11.3, table 11-2) is + * considered to be read-only, fixed and "well known" via the + * supported channel pages attribute. */ uint32_t phy_supported_channel_pages; @@ -1034,8 +1053,8 @@ struct ieee802154_attr_value { * @brief Pointer to a structure representing channel ranges * currently available on the selected channel page. * - * @warning The pointer must be stable and valid throughout the - * life of the interface. + * @warning The pointer must be valid and constant throughout + * the life of the interface. * * @details The selected channel page corresponds to the * phyCurrentPage PHY PIB attribute, see the description of @@ -1067,6 +1086,9 @@ struct ieee802154_attr_value { */ const struct ieee802154_phy_supported_channels *phy_supported_channels; + /* TODO: Allow the PRF to be configured for each TX call once + * drivers need to support PRF switching at runtime. + */ /** * @brief A bit field representing supported HRP UWB pulse * repetition frequencies (PRF), see enum @@ -1074,20 +1096,16 @@ struct ieee802154_attr_value { * * @note Currently none of the Zephyr HRP UWB drivers implements * more than one nominal PRF at runtime, therefore only one bit - * will be set and we consider the current PRF (UwbPrf, - * MCPS-DATA.request, section 8.3.2, table 8-88) to be - * read-only, fixed and "well known" via the supported PRF - * attribute. - * - * TODO: Allow the PRF to be configured for each TX call once - * drivers need to support PRF switching at runtime. + * will be set and the current PRF (UwbPrf, MCPS-DATA.request, + * section 8.3.2, table 8-88) is considered to be read-only, + * fixed and "well known" via the supported PRF attribute. */ uint32_t phy_hrp_uwb_supported_nominal_prfs; }; }; /** - * @brief Helper function to handle channel page and rank to be called from + * @brief Helper function to handle channel page and range to be called from * drivers' attr_get() implementation. This only applies to drivers with a * single channel page. * @@ -1603,7 +1621,8 @@ BUILD_ASSERT(offsetof(struct ieee802154_radio_api, iface_api) == 0); /** INTERNAL_HIDDEN @endcond */ /** - * @brief Check if AR flag is set on the frame inside given net_pkt + * @brief Check if the AR flag is set on the frame inside the given @ref + * net_pkt. * * @param frag A valid pointer on a net_buf structure, must not be NULL, * and its length should be at least 1 byte (ImmAck frames are the @@ -1616,10 +1635,16 @@ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) return (*frag->data & IEEE802154_AR_FLAG_SET); } +/** @} */ + /** - * IEEE 802.15.4 driver callbacks + * @name IEEE 802.15.4 driver callbacks + * @{ */ +/* TODO: Fix drivers to either unref the packet before they return NET_OK or to + * return NET_CONTINUE instead. See note below. + */ /** * @brief IEEE 802.15.4 driver ACK handling callback into L2 that drivers must * call when receiving an ACK package. @@ -1638,10 +1663,9 @@ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) * * @return NET_OK if L2 handles the ACK package, NET_CONTINUE or NET_DROP otherwise. * - * Note: Deviating from other functions in the net stack returning net_verdict, - * this function will not unref the package even if it returns NET_OK. - * - * TODO: Fix this deviating behavior. + * @warning Deviating from other functions in the net stack returning + * net_verdict, this function will not unref the package even if it returns + * NET_OK. */ extern enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt); From d68db1ecfa512bc416bfa906d74f441cba2ab8fb Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 2 Oct 2023 18:22:29 +0300 Subject: [PATCH 1588/4498] net: dhcpv6: Fix params check Fix params check. Signed-off-by: Andrei Emeltchenko --- subsys/net/ip/dhcpv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index 6fae4f320bf..fdfef3c5147 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -2100,7 +2100,7 @@ void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) goto out; } - if (!params->request_addr && !params->request_addr) { + if (!params->request_addr && !params->request_prefix) { NET_ERR("Information Request not supported yet"); goto out; } From a714b420807d09d9c073bc9fc608235cd6dcb435 Mon Sep 17 00:00:00 2001 From: Kieran Tyrrell Date: Mon, 2 Oct 2023 18:13:34 +0100 Subject: [PATCH 1589/4498] net: ip: fix promiscuous mode altering packets Always clone net_pkt to pass to promiscuous queue. Previously, net_pkt was passed to L2 before conditionally cloning. But L2 would in some cases strip ethernet headers, so cloned net_pkt received through promiscuous interface would be missing headers. Signed-off-by: Kieran Tyrrell --- subsys/net/ip/net_if.c | 38 +++----------------------------- tests/net/promiscuous/src/main.c | 20 +++++++++++++++-- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index bfa9c3cfdf7..2b084de071f 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4120,45 +4120,13 @@ enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt) { if (IS_ENABLED(CONFIG_NET_PROMISCUOUS_MODE) && net_if_is_promisc(iface)) { - /* If the packet is not for us and the promiscuous - * mode is enabled, then increase the ref count so - * that net_core.c:processing_data() will not free it. - * The promiscuous mode handler must free the packet - * after it has finished working with it. - * - * If packet is for us, then NET_CONTINUE is returned. - * In this case we must clone the packet, as the packet - * could be manipulated by other part of the stack. - */ - enum net_verdict verdict; struct net_pkt *new_pkt; - /* This protects pkt so that it will not be freed by L2 recv() - */ - net_pkt_ref(pkt); + new_pkt = net_pkt_clone(pkt, K_NO_WAIT); - verdict = net_if_l2(iface)->recv(iface, pkt); - if (verdict == NET_CONTINUE) { - new_pkt = net_pkt_clone(pkt, K_NO_WAIT); - } else { - new_pkt = net_pkt_ref(pkt); + if (net_promisc_mode_input(new_pkt) == NET_DROP) { + net_pkt_unref(new_pkt); } - - /* L2 has modified the buffer starting point, it is easier - * to re-initialize the cursor rather than updating it. - */ - if (new_pkt) { - net_pkt_cursor_init(new_pkt); - - if (net_promisc_mode_input(new_pkt) == NET_DROP) { - net_pkt_unref(new_pkt); - } - } else { - NET_WARN("promiscuous packet dropped, unable to clone packet"); - } - net_pkt_unref(pkt); - - return verdict; } return net_if_l2(iface)->recv(iface, pkt); diff --git a/tests/net/promiscuous/src/main.c b/tests/net/promiscuous/src/main.c index 0b6e6a47957..9bedd9773b9 100644 --- a/tests/net/promiscuous/src/main.c +++ b/tests/net/promiscuous/src/main.c @@ -352,6 +352,8 @@ static void _recv_data(struct net_if *iface, struct net_pkt **pkt) *pkt = net_pkt_rx_alloc_with_buffer(iface, sizeof(data), AF_UNSPEC, 0, K_FOREVER); + net_pkt_ref(*pkt); + net_pkt_write(*pkt, data, sizeof(data)); ret = net_recv_data(iface, *pkt); @@ -372,11 +374,25 @@ static void test_verify_data(void) struct net_pkt *pkt; pkt = net_promisc_mode_wait_data(K_SECONDS(1)); - zassert_equal_ptr(pkt, pkt1, "pkt %p != %p", pkt, pkt1); + zassert_not_null(pkt, "pkt"); + zassert_not_null(pkt->buffer, "pkt->buffer"); + zassert_not_null(pkt1, "pkt1"); + zassert_not_null(pkt1->buffer, "pkt1->buffer"); + zassert_equal(pkt->buffer->len, pkt1->buffer->len, "packet length differs"); + zassert_not_null(pkt->buffer->data, "pkt->buffer->data"); + zassert_not_null(pkt1->buffer->data, "pkt1->buffer->data"); + zassert_mem_equal(pkt->buffer->data, pkt1->buffer->data, pkt1->buffer->len); net_pkt_unref(pkt); pkt = net_promisc_mode_wait_data(K_SECONDS(1)); - zassert_equal_ptr(pkt, pkt2, "pkt %p != %p", pkt, pkt2); + zassert_not_null(pkt, "pkt"); + zassert_not_null(pkt->buffer, "pkt->buffer"); + zassert_not_null(pkt2, "pkt2"); + zassert_not_null(pkt2->buffer, "pkt2->buffer"); + zassert_equal(pkt->buffer->len, pkt2->buffer->len, "packet length differs"); + zassert_not_null(pkt->buffer->data, "pkt->buffer->data"); + zassert_not_null(pkt2->buffer->data, "pkt2->buffer->data"); + zassert_mem_equal(pkt->buffer->data, pkt2->buffer->data, pkt2->buffer->len); net_pkt_unref(pkt); } From 2332a1db39d32e1f96cd8f27ec9d96f0ece2f5da Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 3 Oct 2023 14:03:56 +0200 Subject: [PATCH 1590/4498] west: runners: nrf: Document why the network core is recovered first The network core needs to be recovered first due to the fact that recovering it erases both the network and application cores' flash memory. This means that the little flash image that is programmed during the recover operation would be lost for the app core if we inverted the order. Signed-off-by: Carles Cufi --- scripts/west_commands/runners/nrf_common.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 68540669868..2ff51d7e85d 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -227,6 +227,11 @@ def recover_target(self): else: self.logger.info('Recovering and erasing all flash memory.') + # The network core needs to be recovered first due to the fact that + # recovering it erases the flash of *both* cores. Since a recover + # operation unlocks the core and then flashes a small image that keeps + # the debug access port open, recovering the network core last would + # result in that small image being deleted from the app core. if self.family == 'NRF53_FAMILY': self.exec_op('recover', core='NRFDL_DEVICE_CORE_NETWORK') From 7cac905e576214ed162705f4214eb4181dbdff63 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 2 Oct 2023 18:34:28 +0200 Subject: [PATCH 1591/4498] drivers: modem: modem_cellular: extend CMUX timeout This commit adds a timeout of 300ms to the generic (gsm_ppp) init chat script. This delay is required for some modems (discovered on a Telit ME910G1-WW) to allow it to enter CMUX mode. Without this delay, the modem simply refuses to respond to any CMUX commands. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/modem_cellular.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 9d13b65dedc..9a6e91e99be 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1323,8 +1323,14 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), + /* The 300ms delay after sending the AT+CMUX command is required + * for some modems to ensure they get enough time to enter CMUX + * mode before sending the first CMUX command. If this delay is + * too short, modems have been observed to simply deadlock, + * refusing to respond to any CMUX command. + */ MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 0)); + 300)); MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_init_chat_script, zephyr_gsm_ppp_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); From 8130435c2a36ea3cca007862ba4a90c747066466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 15:47:17 +0200 Subject: [PATCH 1592/4498] mgmt: mcumgr: grp: os_mgmt: Add SPARC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the preprocessor symbol PROCESSOR_NAME for SPARC to avoid a preprocessor warning. Signed-off-by: Martin Åberg --- subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h b/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h index ccb384f6e9d..9e6fa763790 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h @@ -132,6 +132,8 @@ extern "C" { #define PROCESSOR_NAME "riscv" #elif defined(CONFIG_XTENSA) #define PROCESSOR_NAME "xtensa" +#elif defined(CONFIG_SPARC) +#define PROCESSOR_NAME "sparc" #endif #ifndef PROCESSOR_NAME From 0edfd664af45760be3cc3cabb5345334accd8fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 15:50:17 +0200 Subject: [PATCH 1593/4498] tests: mcumgr: smp_version: Enable for SPARC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has been tested on the following boards. The result is PASS on all. - qemu_leon3 - generic_leon3 - gr716a_mini Signed-off-by: Martin Åberg --- tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml b/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml index 57ba9712512..20e6b7f4fef 100644 --- a/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml +++ b/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml @@ -11,7 +11,6 @@ tests: # FIXME: Exclude systems whereby the processor type is not known and emits a warning arch_exclude: - nios2 - - sparc - mips - posix platform_exclude: @@ -25,7 +24,6 @@ tests: # FIXME: Exclude systems whereby the processor type is not known and emits a warning arch_exclude: - nios2 - - sparc - mips - posix platform_exclude: From 33494d4ea2de8633dfe2a0b14716bca688a72306 Mon Sep 17 00:00:00 2001 From: Kai Meinhard Date: Mon, 2 Oct 2023 14:40:38 +0200 Subject: [PATCH 1594/4498] LLEXT: Make max size in shell configurable The maximum size of an extension accept by the shell was previously a define and is now made configurable through Kconfig. Signed-off-by: Kai Meinhard --- subsys/llext/Kconfig | 7 +++++++ subsys/llext/shell.c | 13 ++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index 7f9f24dcb68..9fec16cb230 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -20,6 +20,13 @@ config LLEXT_SHELL help Manage llext with shell commands for loading, unloading, and introspection +config LLEXT_SHELL_MAX_SIZE + int "Maximum size of llext in bytes" + depends on LLEXT_SHELL + default 8192 + help + When loading llext with shell it is stored in a temporary buffer of this size + module = LLEXT module-str = llext source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/llext/shell.c b/subsys/llext/shell.c index fe50365431c..370fd83405f 100644 --- a/subsys/llext/shell.c +++ b/subsys/llext/shell.c @@ -93,29 +93,28 @@ static int cmd_llext_list(const struct shell *sh, size_t argc, char *argv[]) return 0; } -#define LLEXT_MAX_SIZE 8192 -static uint8_t llext_buf[LLEXT_MAX_SIZE]; +static uint8_t llext_buf[CONFIG_LLEXT_SHELL_MAX_SIZE]; static int cmd_llext_load_hex(const struct shell *sh, size_t argc, char *argv[]) { char name[16]; - size_t hex_len = strnlen(argv[2], LLEXT_MAX_SIZE*2+1); + size_t hex_len = strnlen(argv[2], CONFIG_LLEXT_SHELL_MAX_SIZE*2+1); size_t bin_len = hex_len/2; - if (bin_len > LLEXT_MAX_SIZE) { + if (bin_len > CONFIG_LLEXT_SHELL_MAX_SIZE) { shell_print(sh, "Extension %d bytes too large to load, max %d bytes\n", hex_len/2, - LLEXT_MAX_SIZE); + CONFIG_LLEXT_SHELL_MAX_SIZE); return -ENOMEM; } strncpy(name, argv[1], sizeof(name)); - size_t llext_buf_len = hex2bin(argv[2], hex_len, llext_buf, LLEXT_MAX_SIZE); + size_t llext_buf_len = hex2bin(argv[2], hex_len, llext_buf, CONFIG_LLEXT_SHELL_MAX_SIZE); struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(llext_buf, llext_buf_len); struct llext_loader *ldr = &buf_loader.loader; LOG_DBG("hex2bin hex len %d, llext buf sz %d, read %d", - hex_len, LLEXT_MAX_SIZE, llext_buf_len); + hex_len, CONFIG_LLEXT_SHELL_MAX_SIZE, llext_buf_len); LOG_HEXDUMP_DBG(llext_buf, 4, "4 byte MAGIC"); struct llext *ext; From b99651df24fde4f7013d243e52bf0842a2ce1691 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 2 Oct 2023 09:37:29 +0200 Subject: [PATCH 1595/4498] drivers: clock_control: stm32: Set flash latency before increasing clocks Latency should be set before HCLK clock increase. Not doing so can result in broken behavior. For instance, at startup, MSI is @4MHz on L4 series. If MSI is required to be configured at 48 MHz for future use a USB clock, this will be done in set_up_fixed_clock_sources(). If flash latency is not correctly set at this point fetching flash will fail.. Move flash latency configuration before setting up fixed clocks. Signed-off-by: Erwan Gouriou --- drivers/clock_control/clock_stm32_ll_common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 40a2bf28ce3..1c916139358 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -723,12 +723,6 @@ int stm32_clock_control_init(const struct device *dev) /* Some clocks would be activated by default */ config_enable_default_clocks(); - /* Set up indiviual enabled clocks */ - set_up_fixed_clock_sources(); - - /* Set up PLLs */ - set_up_plls(); - #if defined(FLASH_ACR_LATENCY) uint32_t old_flash_freq; uint32_t new_flash_freq; @@ -739,12 +733,18 @@ int stm32_clock_control_init(const struct device *dev) new_flash_freq = RCC_CALC_FLASH_FREQ(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, STM32_FLASH_PRESCALER); - /* If freq increases, set flash latency before any clock setting */ + /* If HCLK increases, set flash latency before any clock setting */ if (old_flash_freq < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); } #endif /* FLASH_ACR_LATENCY */ + /* Set up indiviual enabled clocks */ + set_up_fixed_clock_sources(); + + /* Set up PLLs */ + set_up_plls(); + if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) { @@ -779,7 +779,7 @@ int stm32_clock_control_init(const struct device *dev) } #if defined(FLASH_ACR_LATENCY) - /* If freq not increased, set flash latency after all clock setting */ + /* If HCLK not increased, set flash latency after all clock setting */ if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); } From c5408ab51c3ee0ec7b0cb3d2419b8d998d735e66 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 2 Oct 2023 09:45:30 +0200 Subject: [PATCH 1596/4498] drivers: clock_control: stm32: Use hclk freq for flash latency computation Flash is clocked with HCLK, while CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC reflects SYSCLK. HCLK = SYCLK / AHB prescaler. When dealing with flash latency, use HCLK instead of SYSCLK. This changes reverts a abusive change done in an old commit (efd8ee465c72) Signed-off-by: Erwan Gouriou --- drivers/clock_control/clock_stm32_ll_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 1c916139358..ba5ba2e4673 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -734,8 +734,8 @@ int stm32_clock_control_init(const struct device *dev) STM32_FLASH_PRESCALER); /* If HCLK increases, set flash latency before any clock setting */ - if (old_flash_freq < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { - LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + if (old_flash_freq < new_flash_freq) { + LL_SetFlashLatency(new_flash_freq); } #endif /* FLASH_ACR_LATENCY */ @@ -780,8 +780,8 @@ int stm32_clock_control_init(const struct device *dev) #if defined(FLASH_ACR_LATENCY) /* If HCLK not increased, set flash latency after all clock setting */ - if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { - LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + if (old_flash_freq >= new_flash_freq) { + LL_SetFlashLatency(new_flash_freq); } #endif /* FLASH_ACR_LATENCY */ From 630bfff65f6d0a61eee76f3ff5082354408fe63a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 19:57:11 +0200 Subject: [PATCH 1597/4498] net: lib: zperf: fix compiler warning The compiler emits a "null where non-null expected" warning unless the argument of strlen is non-null at compile time. Signed-off-by: Florian Grandel --- subsys/net/lib/zperf/zperf_tcp_receiver.c | 4 ++-- subsys/net/lib/zperf/zperf_udp_receiver.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index 614e1af6d03..cd0add89cd9 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -165,7 +165,7 @@ static void tcp_server_session(void) if (!net_ipv4_is_addr_unspecified(addr)) { memcpy(&in4_addr->sin_addr, addr, sizeof(struct in_addr)); - } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + } else if (strlen(MY_IP4ADDR ? MY_IP4ADDR : "")) { /* Use Setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr->sin_addr); @@ -217,7 +217,7 @@ static void tcp_server_session(void) if (!net_ipv6_is_addr_unspecified(addr)) { memcpy(&in6_addr->sin6_addr, addr, sizeof(struct in6_addr)); - } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + } else if (strlen(MY_IP6ADDR ? MY_IP6ADDR : "")) { /* Use Setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index cf29760e1c6..0b6997e401e 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -257,7 +257,7 @@ static void udp_server_session(void) if (!net_ipv4_is_addr_unspecified(in4_addr)) { memcpy(&in4_addr_my->sin_addr, in4_addr, sizeof(struct in_addr)); - } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + } else if (strlen(MY_IP4ADDR ? MY_IP4ADDR : "")) { /* Use setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr_my->sin_addr); @@ -312,7 +312,7 @@ static void udp_server_session(void) if (!net_ipv6_is_addr_unspecified(in6_addr)) { memcpy(&in6_addr_my->sin6_addr, in6_addr, sizeof(struct in6_addr)); - } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + } else if (strlen(MY_IP6ADDR ? MY_IP6ADDR : "")) { /* Use setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, From b892a4bc499bb44421c4f792444acfc32a42d39f Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Fri, 29 Sep 2023 13:44:41 +0200 Subject: [PATCH 1598/4498] scripts: tests: twister: Add log_helper tests Log helper is a small module that this commit covers with an explicit test. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_log_helper.py | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 scripts/tests/twister/test_log_helper.py diff --git a/scripts/tests/twister/test_log_helper.py b/scripts/tests/twister/test_log_helper.py new file mode 100644 index 00000000000..9373be5da2f --- /dev/null +++ b/scripts/tests/twister/test_log_helper.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for log_helper.py functions +""" + +import logging +import mock +import pytest + +from importlib import reload + +import twisterlib.log_helper + + +TESTDATA = [ + ('Windows', 'dummy message: [\'dummy\', \'command\', \'-flag\']'), + ('Linux', 'dummy message: dummy command -flag'), +] + +@pytest.mark.parametrize( + 'system, expected_log', + TESTDATA, + ids=['Windows', 'Linux'] +) +def test_log_command(caplog, system, expected_log): + caplog.set_level(logging.DEBUG) + + logger = logging.getLogger('dummy') + message = 'dummy message' + args = ['dummy', 'command', '-flag'] + + with mock.patch('platform.system', return_value=system): + reload(twisterlib.log_helper) + twisterlib.log_helper.log_command(logger, message, args) + + reload(twisterlib.log_helper) + + assert expected_log in caplog.text From 3d82fbe35766ee7e3a082f7e5312f801dcdefebc Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Sat, 23 Sep 2023 16:18:24 +0300 Subject: [PATCH 1599/4498] posix: pthread: Remove dead code warning It is better to put LOG_ERR() before K_SPINLOCK_BREAK(). Signed-off-by: Andrei Emeltchenko --- lib/posix/pthread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index f3ca678ac4d..7435ae8db2a 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -667,15 +667,15 @@ int pthread_join(pthread_t pthread, void **status) { if (t->detachstate != PTHREAD_CREATE_JOINABLE) { ret = EINVAL; - K_SPINLOCK_BREAK; LOG_ERR("Pthread %p is not a joinable", &t->thread); + K_SPINLOCK_BREAK; } if (t->qid == POSIX_THREAD_READY_Q) { /* in case thread has moved to ready_q between to_posix_thread() and here */ ret = ESRCH; - K_SPINLOCK_BREAK; LOG_ERR("Pthread %p has already been joined", &t->thread); + K_SPINLOCK_BREAK; } /* From 0ee03806438a94c7285d7a8df248f2d7e8f6e2cd Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 25 Sep 2023 17:06:12 +0300 Subject: [PATCH 1600/4498] posix: pthread: Move logging out of spinlock area Move LOG_ERR() outside of K_SPINLOCK(). Signed-off-by: Andrei Emeltchenko --- lib/posix/pthread.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 7435ae8db2a..3e00af2d4cf 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -667,14 +667,12 @@ int pthread_join(pthread_t pthread, void **status) { if (t->detachstate != PTHREAD_CREATE_JOINABLE) { ret = EINVAL; - LOG_ERR("Pthread %p is not a joinable", &t->thread); K_SPINLOCK_BREAK; } if (t->qid == POSIX_THREAD_READY_Q) { /* in case thread has moved to ready_q between to_posix_thread() and here */ ret = ESRCH; - LOG_ERR("Pthread %p has already been joined", &t->thread); K_SPINLOCK_BREAK; } @@ -685,8 +683,15 @@ int pthread_join(pthread_t pthread, void **status) t->detachstate = PTHREAD_CREATE_DETACHED; } - if (ret != 0) { + switch (ret) { + case ESRCH: + LOG_ERR("Pthread %p has already been joined", &t->thread); return ret; + case EINVAL: + LOG_ERR("Pthread %p is not a joinable", &t->thread); + return ret; + case 0: + break; } err = k_thread_join(&t->thread, K_FOREVER); From 06e8e9f5f5df55c0fe471c074f42910a178a4ebd Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 25 Sep 2023 17:15:53 +0300 Subject: [PATCH 1601/4498] posix: pthread: Reuse variable for return code No need to have different variables for different function's return codes. Signed-off-by: Andrei Emeltchenko --- lib/posix/pthread.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 3e00af2d4cf..7377f2b133d 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -646,9 +646,8 @@ void pthread_exit(void *retval) */ int pthread_join(pthread_t pthread, void **status) { - int err; - int ret; struct posix_thread *t; + int ret; if (pthread == pthread_self()) { LOG_ERR("Pthread attempted to join itself (%x)", pthread); @@ -694,9 +693,9 @@ int pthread_join(pthread_t pthread, void **status) break; } - err = k_thread_join(&t->thread, K_FOREVER); + ret = k_thread_join(&t->thread, K_FOREVER); /* other possibilities? */ - __ASSERT_NO_MSG(err == 0); + __ASSERT_NO_MSG(ret == 0); LOG_DBG("Joined pthread %p", &t->thread); From 4e7d1b0f7430d030f15dd27b5b83087e72582609 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Wed, 6 Sep 2023 23:05:45 +0800 Subject: [PATCH 1602/4498] drivers: spi: Fix Ambiq apollo4p SPI mode configuration. The commit fixes the SPI mode improper configuration. Otherwise the MODE_3 and MODE_0 cases would never be entered as expected. Signed-off-by: Aaron Ye --- drivers/spi/spi_ambiq.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi_ambiq.c b/drivers/spi/spi_ambiq.c index facfc09b035..e0b8a488dda 100644 --- a/drivers/spi/spi_ambiq.c +++ b/drivers/spi/spi_ambiq.c @@ -76,12 +76,14 @@ static int spi_config(const struct device *dev, const struct spi_config *config) return -ENOTSUP; } - if (config->operation & (SPI_MODE_CPOL | SPI_MODE_CPHA)) { - if (config->operation & (SPI_MODE_CPOL && SPI_MODE_CPHA)) { + if (config->operation & SPI_MODE_CPOL) { + if (config->operation & SPI_MODE_CPHA) { data->iom_cfg.eSpiMode = AM_HAL_IOM_SPI_MODE_3; - } else if (config->operation & SPI_MODE_CPOL) { + } else { data->iom_cfg.eSpiMode = AM_HAL_IOM_SPI_MODE_2; - } else if (config->operation & SPI_MODE_CPHA) { + } + } else { + if (config->operation & SPI_MODE_CPHA) { data->iom_cfg.eSpiMode = AM_HAL_IOM_SPI_MODE_1; } else { data->iom_cfg.eSpiMode = AM_HAL_IOM_SPI_MODE_0; From 7cf21d10806a25f6ddd937862e902a04ec5c79b6 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Wed, 6 Sep 2023 23:07:17 +0800 Subject: [PATCH 1603/4498] drivers: spi: Fix Ambiq apollo4p SPI reconfiguration. The configured SPI should not be configured again. Otherwise it would cause SPI transmission failure. Signed-off-by: Aaron Ye --- drivers/spi/spi_ambiq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/spi/spi_ambiq.c b/drivers/spi/spi_ambiq.c index e0b8a488dda..d9a0a098aae 100644 --- a/drivers/spi/spi_ambiq.c +++ b/drivers/spi/spi_ambiq.c @@ -46,11 +46,17 @@ static int spi_config(const struct device *dev, const struct spi_config *config) { struct spi_ambiq_data *data = dev->data; const struct spi_ambiq_config *cfg = dev->config; + struct spi_context *ctx = &(data->ctx); data->iom_cfg.eInterfaceMode = AM_HAL_IOM_SPI_MODE; int ret = 0; + if (spi_context_configured(ctx, config)) { + /* Already configured. No need to do it again. */ + return 0; + } + if (config->operation & SPI_HALF_DUPLEX) { LOG_ERR("Half-duplex not supported"); return -ENOTSUP; @@ -105,6 +111,7 @@ static int spi_config(const struct device *dev, const struct spi_config *config) } data->iom_cfg.ui32ClockFreq = cfg->clock_freq; + ctx->config = config; /* Disable IOM instance as it cannot be configured when enabled*/ ret = am_hal_iom_disable(data->IOMHandle); From a94422f686fbeff317f0aed518ed11ce94d224ce Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Wed, 6 Sep 2023 23:17:59 +0800 Subject: [PATCH 1604/4498] drivers: spi: Fix the Ambiq apollo4p SPI transmission failure. The instruction length can only be 0~5. Use am_hal_iom_blocking_transfer and specify clearly the TX/RX direction. Hold CS to continue to RX expected response after instruction transmission. Signed-off-by: Aaron Ye --- drivers/spi/spi_ambiq.c | 66 ++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi_ambiq.c b/drivers/spi/spi_ambiq.c index d9a0a098aae..16614798e32 100644 --- a/drivers/spi/spi_ambiq.c +++ b/drivers/spi/spi_ambiq.c @@ -130,33 +130,51 @@ static int spi_ambiq_xfer(const struct device *dev, const struct spi_config *con int ret = 0; am_hal_iom_transfer_t trans = {0}; - uint8_t *buf3; - trans.eDirection = AM_HAL_IOM_FULLDUPLEX; - - uint16_t cmd = *ctx->tx_buf; - - trans.ui32InstrLen = ctx->tx_len; - spi_context_update_tx(ctx, 1, 1); - cmd = __bswap_16(cmd | *ctx->tx_buf << 8); - trans.ui64Instr = cmd; + if (ctx->tx_len) { + trans.ui64Instr = *ctx->tx_buf; + trans.ui32InstrLen = 1; + spi_context_update_tx(ctx, 1, 1); - if (ctx->rx_buf != NULL) { - trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; - spi_context_update_rx(ctx, 1, ctx->rx_len); - buf3 = (uint8_t *)malloc(sizeof(uint8_t) * ctx->rx_len); + if (ctx->rx_buf != NULL) { + if (ctx->tx_len > 0) { + /* The instruction length can only be 0~5. */ + if (ctx->tx_len > 4) { + spi_context_complete(ctx, dev, 0); + return -ENOTSUP; + } + + /* Put the remaining TX data in instruction. */ + trans.ui32InstrLen += ctx->tx_len; + for (int i = 0; i < trans.ui32InstrLen - 1; i++) { + trans.ui64Instr = (trans.ui64Instr << 8) | (*ctx->tx_buf); + spi_context_update_tx(ctx, 1, 1); + } + } + + /* Set RX direction and hold CS to continue to receive data. */ + trans.eDirection = AM_HAL_IOM_RX; + trans.bContinue = true; + trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; + trans.ui32NumBytes = ctx->rx_len; + ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); + } else if (ctx->tx_buf != NULL) { + /* Set TX direction to send data and release CS after transmission. */ + trans.eDirection = AM_HAL_IOM_TX; + trans.bContinue = false; + trans.ui32NumBytes = ctx->tx_len; + trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; + ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); + } + } else { + /* Set RX direction to receive data and release CS after transmission. */ + trans.ui64Instr = 0; + trans.ui32InstrLen = 0; + trans.eDirection = AM_HAL_IOM_RX; + trans.bContinue = false; + trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; trans.ui32NumBytes = ctx->rx_len; - trans.pui32RxBuffer = (uint32_t *)&buf3; - ret = am_hal_iom_spi_blocking_fullduplex(data->IOMHandle, &trans); - - memcpy(ctx->rx_buf, &buf3, (ctx->rx_len * sizeof(uint8_t))); - - } else if (ctx->tx_buf != NULL) { - spi_context_update_tx(ctx, 1, 1); - trans.ui32NumBytes = ctx->tx_len; - trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; - trans.pui32RxBuffer = (uint32_t *)ctx->tx_buf; - ret = am_hal_iom_spi_blocking_fullduplex(data->IOMHandle, &trans); + ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); } spi_context_complete(ctx, dev, 0); From e3dc860429b40947d729346232e7e267cbe217ef Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 26 Sep 2023 11:25:58 -0700 Subject: [PATCH 1605/4498] doc: vuln: Add information about CVE-2023-4262 Information about CVE-2023-4262 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 92a0a23c48c..b7529a73d5e 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1358,6 +1358,16 @@ This has been fixed in main for v3.5.0 - `PR 60079 fix for 3.3 `_ +CVE-2023-4262 +------------- + +Potential buffer overflow vulnerabilities in the Zephyr Mgmt subsystem + +- `Zephyr project bug tracker GHSA-56p9-5p3v-hhrc + `_ + +- This issue has not been fixed. + CVE-2023-4265 ------------- From 3f39f70799fd0e2e8ad3bff26d3693d29420da9f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 28 Sep 2023 15:56:27 +0200 Subject: [PATCH 1606/4498] doc: api: Update link for connection manager Update link for connection manager in API overview page. Signed-off-by: Robert Lubos --- doc/develop/api/overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index decb3e73972..9295ee57b5f 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -53,7 +53,7 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Unstable - 1.10 - * - ``conn_mgr`` + * - :ref:`conn_mgr_docs` - Experimental - 3.4.0 From e11bc94a44adabc6e29c74e2c903083e42bf0991 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 3 Oct 2023 10:53:57 +0200 Subject: [PATCH 1607/4498] cmake run_native: Fix target dependency The run_native (and therefore run) targets did not depend on the proper thing for native_simulator based targets Fix it. Signed-off-by: Alberto Escolar Piedras --- cmake/emu/native.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/emu/native.cmake b/cmake/emu/native.cmake index 12cdd3112b7..3578f47bfc4 100644 --- a/cmake/emu/native.cmake +++ b/cmake/emu/native.cmake @@ -3,7 +3,9 @@ add_custom_target(run_native COMMAND ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_EXE_NAME} - DEPENDS ${logical_target_for_zephyr_elf} + DEPENDS + ${logical_target_for_zephyr_elf} + $<$:native_runner_executable> WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} USES_TERMINAL ) From fea8cacceaa9fbc80cd7dd0e3a9993ababed2645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8nningstad?= Date: Thu, 7 Sep 2023 13:07:17 +0200 Subject: [PATCH 1608/4498] twister: Make string stripping consistent across handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All handlers except QEMU were right-stripping console lines before checking them. In certain cases where the regex is expecting the whitespace, this could make the test fail on qemu when it is passing on something else. Change QEMUHandler to us .rstrip instead of .strip() Signed-off-by: Øyvind Rønningstad --- scripts/pylib/twister/twisterlib/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 780b51cb7de..e4a0d9f5a1a 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -887,7 +887,7 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, # line contains a full line of data output from QEMU log_out_fp.write(line) log_out_fp.flush() - line = line.strip() + line = line.rstrip() logger.debug(f"QEMU ({pid}): {line}") harness.handle(line) From 496faf8677ae03941639eaa887e03aa710f156ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 27 Sep 2023 12:32:54 +0200 Subject: [PATCH 1609/4498] samples: tfm: fix 404 link to tfm docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix HTTP 404 in link to "Adding Secure Partition" external doc page. Signed-off-by: Benjamin Cabé --- samples/tfm_integration/tfm_secure_partition/README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/tfm_integration/tfm_secure_partition/README.rst b/samples/tfm_integration/tfm_secure_partition/README.rst index 2faa4d25419..14db40bb5dd 100644 --- a/samples/tfm_integration/tfm_secure_partition/README.rst +++ b/samples/tfm_integration/tfm_secure_partition/README.rst @@ -17,7 +17,7 @@ This dummy partition has a single secure service, which can index one of 5 dummy The partition is located in the ``dummy_partition`` directory. It contains the partition sources, build files and build configuration files. The partition is built by the TF-M build system, refer to :ref:`tfm_build_system` for more details. -For more information on how to add custom secure partitions refer to TF-M's guide: https://tf-m-user-guide.trustedfirmware.org/docs/integration_guide/services/tfm_secure_partition_addition.html +For more information on how to add custom secure partitions refer to TF-M's guide: https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_secure_partition_addition.html When adapting this partition for your own purposes, please change all occurrences of "dummy_partition", "DUMMY_PARTITION", "dp", and "DP" to your own partition name. Also, look through both the secure and non-secure CMakeLists.txt file and make relevant changes, as well as the yaml files inside "partition". @@ -32,8 +32,8 @@ On Target Refer to :ref:`tfm_ipc` for detailed instructions. -On QEMU: -======== +On QEMU +======= Refer to :ref:`tfm_ipc` for detailed instructions. From d24de87aed9088656c179359d950a8384ac5004a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 27 Sep 2023 12:34:28 +0200 Subject: [PATCH 1610/4498] samples: tfm: wrap lines at 100 characters. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run formatter to wrap lines at 100 characters. Signed-off-by: Benjamin Cabé --- .../tfm_secure_partition/README.rst | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/samples/tfm_integration/tfm_secure_partition/README.rst b/samples/tfm_integration/tfm_secure_partition/README.rst index 14db40bb5dd..94158ef06d8 100644 --- a/samples/tfm_integration/tfm_secure_partition/README.rst +++ b/samples/tfm_integration/tfm_secure_partition/README.rst @@ -6,21 +6,29 @@ TF-M Secure Partition Sample Overview ******** -A Secure Partition is an isolated module that resides in TF-M. It exposes a number of functions or "secure services" to other partitions and/or to the non-secure firmware. -TF-M already contains standard partitions such as crypto, protected_storage, or firmware_update, but it's also possible to create your own partitions. +A Secure Partition is an isolated module that resides in TF-M. It exposes a number of functions or +"secure services" to other partitions and/or to the non-secure firmware. TF-M already contains +standard partitions such as crypto, protected_storage, or firmware_update, but it's also possible to +create your own partitions. -This sample creates a dummy secure partition and secure service for TF-M and instructs the TF-M build system to build it into the secure firmware. -The dummy secure service is then called in the main file (in the non-secure firmware). +This sample creates a dummy secure partition and secure service for TF-M and instructs the TF-M +build system to build it into the secure firmware. The dummy secure service is then called in the +main file (in the non-secure firmware). -This dummy partition has a single secure service, which can index one of 5 dummy secrets inside the partition, and retrieve a hash of the secret. +This dummy partition has a single secure service, which can index one of 5 dummy secrets inside the +partition, and retrieve a hash of the secret. -The partition is located in the ``dummy_partition`` directory. It contains the partition sources, build files and build configuration files. -The partition is built by the TF-M build system, refer to :ref:`tfm_build_system` for more details. +The partition is located in the ``dummy_partition`` directory. It contains the partition sources, +build files and build configuration files. The partition is built by the TF-M build system, refer to +:ref:`tfm_build_system` for more details. -For more information on how to add custom secure partitions refer to TF-M's guide: https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_secure_partition_addition.html +For more information on how to add custom secure partitions refer to TF-M's guide: +https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_secure_partition_addition.html -When adapting this partition for your own purposes, please change all occurrences of "dummy_partition", "DUMMY_PARTITION", "dp", and "DP" to your own partition name. -Also, look through both the secure and non-secure CMakeLists.txt file and make relevant changes, as well as the yaml files inside "partition". +When adapting this partition for your own purposes, please change all occurrences of +"dummy_partition", "DUMMY_PARTITION", "dp", and "DP" to your own partition name. Also, look through +both the secure and non-secure CMakeLists.txt file and make relevant changes, as well as the yaml +files inside "partition". Building and Running ******************** From 15aa3acaf6a7f5fc296d709bc5f3c7cebe461d49 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 20 Jul 2023 12:34:23 -0700 Subject: [PATCH 1611/4498] kconfig: Remove MP_NUM_CPUS usage Zephyr's code base uses MP_MAX_NUM_CPUS to know how many cores exists in the target. It is also expected that both symbols MP_MAX_NUM_CPUS and MP_NUM_CPUS have the same value, so lets just use MP_MAX_NUM_CPUS and simplify it. Signed-off-by: Flavio Ceolin --- boards/x86/acrn/doc/index.rst | 2 +- doc/kernel/services/smp/smp.rst | 2 +- drivers/mbox/mbox_andes_plic_sw.c | 2 +- kernel/Kconfig | 4 ++-- lib/os/Kconfig | 2 +- subsys/debug/Kconfig | 2 +- tests/posix/pthread_pressure/Kconfig | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/boards/x86/acrn/doc/index.rst b/boards/x86/acrn/doc/index.rst index bd22b8b5e60..2bdaa96a817 100644 --- a/boards/x86/acrn/doc/index.rst +++ b/boards/x86/acrn/doc/index.rst @@ -125,7 +125,7 @@ Configure Zephyr CPUs Now you need to configure the CPU environment ACRN presents to the guest. By default Zephyr builds in SMP mode, but ACRN's default configuration gives it only one CPU. Find the value of -``CONFIG_MP_NUM_CPUS`` in the Zephyr .config file give the guest that +``CONFIG_MP_MAX_NUM_CPUS`` in the Zephyr .config file give the guest that many CPUs in the ```` tag. For example: .. code-block:: xml diff --git a/doc/kernel/services/smp/smp.rst b/doc/kernel/services/smp/smp.rst index 395d1874f58..0f1e29c9f12 100644 --- a/doc/kernel/services/smp/smp.rst +++ b/doc/kernel/services/smp/smp.rst @@ -18,7 +18,7 @@ variable. This must be set to "y" to enable SMP features, otherwise a uniprocessor kernel will be built. In general the platform default will have enabled this anywhere it's supported. When enabled, the number of physical CPUs available is visible at build time as -:kconfig:option:`CONFIG_MP_NUM_CPUS`. Likewise, the default for this will be the +:kconfig:option:`CONFIG_MP_MAX_NUM_CPUS`. Likewise, the default for this will be the number of available CPUs on the platform and it is not expected that typical apps will change it. But it is legal and supported to set this to a smaller (but obviously not larger) number for special diff --git a/drivers/mbox/mbox_andes_plic_sw.c b/drivers/mbox/mbox_andes_plic_sw.c index 13254c464af..bc01da73a30 100644 --- a/drivers/mbox/mbox_andes_plic_sw.c +++ b/drivers/mbox/mbox_andes_plic_sw.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(mbox_andes_plic_sw); static struct mbox_andes_data { mbox_callback_t cb[IPI_NUM]; void *user_data[IPI_NUM]; - uint32_t enabled_channel[CONFIG_MP_NUM_CPUS]; + uint32_t enabled_channel[CONFIG_MP_MAX_NUM_CPUS]; #ifdef CONFIG_SCHED_IPI_SUPPORTED uint32_t reg_cb_channel; uint32_t ipi_channel; diff --git a/kernel/Kconfig b/kernel/Kconfig index 556bb69531e..5cb5937f2e6 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1173,12 +1173,12 @@ config TRACE_SCHED_IPI to check if schedule IPI has called or not, for testing purpose. depends on SCHED_IPI_SUPPORTED - depends on MP_NUM_CPUS>1 + depends on MP_MAX_NUM_CPUS>1 config KERNEL_COHERENCE bool "Place all shared data into coherent memory" depends on ARCH_HAS_COHERENCE - default y if SMP && MP_NUM_CPUS > 1 + default y if SMP && MP_MAX_NUM_CPUS > 1 select THREAD_STACK_INFO help When available and selected, the kernel will build in a mode diff --git a/lib/os/Kconfig b/lib/os/Kconfig index f7ad7385df7..e6b25ade5a5 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -35,7 +35,7 @@ config BASE64 config PRINTK_SYNC bool "Serialize printk() calls" - default y if SMP && MP_NUM_CPUS > 1 && !(EFI_CONSOLE && LOG) + default y if SMP && MP_MAX_NUM_CPUS > 1 && !(EFI_CONSOLE && LOG) help When true, a spinlock will be taken around the output from a single printk() call, preventing the output data from diff --git a/subsys/debug/Kconfig b/subsys/debug/Kconfig index 47b03f25325..f9468ff5e0c 100644 --- a/subsys/debug/Kconfig +++ b/subsys/debug/Kconfig @@ -257,7 +257,7 @@ config ASSERT_LEVEL config SPIN_VALIDATE bool "Spinlock validation" depends on MULTITHREADING - depends on MP_NUM_CPUS <= 4 + depends on MP_MAX_NUM_CPUS <= 4 default y if !FLASH || FLASH_SIZE > 32 help There's a spinlock validation framework available when asserts are diff --git a/tests/posix/pthread_pressure/Kconfig b/tests/posix/pthread_pressure/Kconfig index 70154447d7b..e861f0a5be7 100644 --- a/tests/posix/pthread_pressure/Kconfig +++ b/tests/posix/pthread_pressure/Kconfig @@ -6,8 +6,8 @@ source "Kconfig.zephyr" config TEST_NUM_CPUS int "Number of CPUs to use in parallel" - range 1 MP_NUM_CPUS - default MP_NUM_CPUS + range 1 MP_MAX_NUM_CPUS + default MP_MAX_NUM_CPUS help The number of parallel threads to run during the test. From fee22dae4014b02a1f968c993f4dc3666bdbdb1f Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 28 Sep 2023 14:04:43 -0700 Subject: [PATCH 1612/4498] kconfig: Deprecate CONFIG_MP_NUM_CPUS Mark CONFIG_MP_NUM_CPUS deprecated and point to CONFIG_MP_MAX_NUM_CPUS. Signed-off-by: Flavio Ceolin --- kernel/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/Kconfig b/kernel/Kconfig index 5cb5937f2e6..b2dde710121 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1140,12 +1140,11 @@ config SMP_BOOT_DELAY secondary CPUs at a later time. config MP_NUM_CPUS - int "Number of CPUs/cores" + int "Number of CPUs/cores [DEPRECATED]" default MP_MAX_NUM_CPUS range 1 12 help - Number of multiprocessing-capable cores available to the - multicpu API and SMP features. + This is deprecated, please use MP_MAX_NUM_CPUS instead. config MP_MAX_NUM_CPUS int "Maximum number of CPUs/cores" From f91bfae0a776443b02615e4880c59825254d3686 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 29 Sep 2023 14:19:35 +0200 Subject: [PATCH 1613/4498] drivers: can: mcux: flexcan: validate initial timing parameters Validate the initial timing parameters set via devicetree. Fixes: #61909 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcux_flexcan.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 44355a480e4..5b4e557a931 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -1205,6 +1205,13 @@ static int mcux_flexcan_init(const struct device *dev) } } + /* Validate initial timing parameters */ + err = can_set_timing(dev, &data->timing); + if (err != 0) { + LOG_ERR("failed to set timing (err %d)", err); + return -ENODEV; + } + #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD if (config->flexcan_fd) { data->timing_data.sjw = config->sjw_data; @@ -1230,6 +1237,14 @@ static int mcux_flexcan_init(const struct device *dev) } } } + + /* Validate initial data phase timing parameters */ + err = can_set_timing_data(dev, &data->timing_data); + if (err != 0) { + LOG_ERR("failed to set data phase timing (err %d)", err); + return -ENODEV; + } + #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); From 5b76d95a735dd47550eb76acc9816d85c654908b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Oct 2023 08:51:31 -0700 Subject: [PATCH 1614/4498] kernel: Re-order _static_thread_data initializer to match type C++ compilers complain if the order of designated initializers doesn't match the order of the members in the type. Re-order the initializers for the _static_thread_data struct to match the new order of the type. Signed-off-by: Keith Packard --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index be1e7d65b7e..386c5369326 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -707,8 +707,8 @@ struct _static_thread_data { .init_p3 = (void *)p3, \ .init_prio = (prio), \ .init_options = (options), \ - .init_delay = SYS_TIMEOUT_MS(delay), \ .init_name = STRINGIFY(tname), \ + .init_delay = SYS_TIMEOUT_MS(delay), \ } /* From 6552e05100aaa84652e16edd1cae720f35134a09 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 25 Sep 2023 10:17:38 +0800 Subject: [PATCH 1615/4498] ITE: dts: it8xxx2: Correct the clock frequency of baud rate The baud rate clock frequency is 1.8432MHz. Signed-off-by: Tim Lin --- boards/riscv/it82xx2_evb/it82xx2_evb.dts | 4 ++-- boards/riscv/it8xxx2_evb/it8xxx2_evb.dts | 4 ++-- dts/riscv/ite/it8xxx2.dtsi | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.dts b/boards/riscv/it82xx2_evb/it82xx2_evb.dts index 2938fb7ebd5..fa8f3090973 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb.dts +++ b/boards/riscv/it82xx2_evb/it82xx2_evb.dts @@ -108,13 +108,13 @@ &uart1 { status = "okay"; current-speed = <115200>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; }; &uart2 { status = "okay"; current-speed = <460800>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; }; &ite_uart1_wrapper { diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index 1b127e4bc0e..ffac4a2ed99 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -99,12 +99,12 @@ &uart1 { status = "okay"; current-speed = <115200>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; }; &uart2 { status = "okay"; current-speed = <460800>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; }; &ite_uart1_wrapper { status = "okay"; diff --git a/dts/riscv/ite/it8xxx2.dtsi b/dts/riscv/ite/it8xxx2.dtsi index 84f551a5015..62734db2675 100644 --- a/dts/riscv/ite/it8xxx2.dtsi +++ b/dts/riscv/ite/it8xxx2.dtsi @@ -107,7 +107,7 @@ reg = <0x00f02700 0x0020>; status = "disabled"; current-speed = <115200>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; interrupts = <38 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&intc>; reg-shift = <0>; @@ -117,7 +117,7 @@ reg = <0x00f02800 0x0020>; status = "disabled"; current-speed = <460800>; - clock-frequency = <1804800>; + clock-frequency = <1843200>; interrupts = <39 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&intc>; reg-shift = <0>; From 9d79728c48fb1a4b0dae9d3de36a343d135d0a83 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Mon, 2 Oct 2023 14:31:48 -0400 Subject: [PATCH 1616/4498] drivers: serial: uart_emul: support interrupt-driven receive Previously, the uart_emul device did not support interrupt-driven receive, which is an unwritten requirement for hooking up a uart to the Zephyr console driver. The console is a fairly high-traffic subsystem, and we should be able to perform more extensive testing on it, aside from maching twister output against a regular expression. With this change, we can use the emulation uart within the body of a ZTest. Testing Done: ```shell west build -p auto -b qemu_riscv64 -t run tests/drivers/console_switching ... *** Booting Zephyr OS build zephyr-v3.4.0-4277-gae0d63471be1 *** Running TESTSUITE console_switching =================================================================== START - test_read read "Hello, uart_emul0!" from uart_emul0 read "Hello, uart_emul1!" from uart_emul1 read "Hello, uart_emul0!" from uart_emul0 read "Hello, uart_emul1!" from uart_emul1 PASS - test_read in 0.005 seconds =================================================================== START - test_write wrote "Hello, uart_emul0!" to uart_emul0 wrote "Hello, uart_emul1!" to uart_emul1 wrote "Hello, uart_emul0!" to uart_emul0 wrote "Hello, uart_emul1!" to uart_emul1 PASS - test_write in 0.003 seconds =================================================================== TESTSUITE console_switching succeeded ------ TESTSUITE SUMMARY START ------ SUITE PASS - 100.00% [console_switching]: pass = 2, fail = 0, skip = 0... - PASS - [console_switching.test_read] duration = 0.005 seconds - PASS - [console_switching.test_write] duration = 0.003 seconds ------ TESTSUITE SUMMARY END ------ =================================================================== PROJECT EXECUTION SUCCESSFUL ``` Signed-off-by: Christopher Friedt --- drivers/serial/Kconfig.emul | 1 + drivers/serial/uart_emul.c | 174 ++++++++++++++++++++++++++++++++++-- 2 files changed, 166 insertions(+), 9 deletions(-) diff --git a/drivers/serial/Kconfig.emul b/drivers/serial/Kconfig.emul index 67134b9485c..2b48335b757 100644 --- a/drivers/serial/Kconfig.emul +++ b/drivers/serial/Kconfig.emul @@ -7,6 +7,7 @@ config UART_EMUL bool "Emulated UART driver [EXPERIMENTAL]" default y depends on DT_HAS_ZEPHYR_UART_EMUL_ENABLED + select SERIAL_SUPPORT_INTERRUPT select RING_BUFFER select EXPERIMENTAL help diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 4cb50731f9c..e4ea6357ea9 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -6,19 +6,26 @@ #define DT_DRV_COMPAT zephyr_uart_emul -#include -#include -#include -#include #include +#include +#include +#include #include +#include +#include + LOG_MODULE_REGISTER(uart_emul, CONFIG_UART_LOG_LEVEL); struct uart_emul_config { bool loopback; }; +struct uart_emul_work { + struct k_work work; + const struct device *dev; +}; + /* Device run time data */ struct uart_emul_data { struct uart_config cfg; @@ -31,6 +38,13 @@ struct uart_emul_data { struct ring_buf *tx_rb; struct k_spinlock tx_lock; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + bool rx_irq_en; + struct uart_emul_work irq_work; + uart_irq_callback_user_data_t irq_cb; + void *irq_cb_udata; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; int uart_emul_poll_in(const struct device *dev, unsigned char *p_char) @@ -99,6 +113,123 @@ int uart_emul_config_get(const struct device *dev, struct uart_config *cfg) } #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static int uart_emul_fifo_read(const struct device *dev, uint8_t *rx_data, int size) +{ + int ret; + struct uart_emul_data *data = dev->data; + + K_SPINLOCK(&data->rx_lock) { + ret = MIN(size, ring_buf_size_get(data->rx_rb)); + size = ret; + + for (int n = 0; size > 0; size -= n, rx_data += n) { + n = ring_buf_get(data->rx_rb, rx_data, size); + } + } + + return ret; +} + +static int uart_emul_irq_rx_ready(const struct device *dev) +{ + bool ready = false; + struct uart_emul_data *data = dev->data; + + K_SPINLOCK(&data->rx_lock) { + if (!data->rx_irq_en) { + K_SPINLOCK_BREAK; + } + + ready = !ring_buf_is_empty(data->rx_rb); + } + + return ready; +} + +static void uart_emul_irq_handler(struct k_work *work) +{ + struct uart_emul_work *uwork = CONTAINER_OF(work, struct uart_emul_work, work); + const struct device *dev = uwork->dev; + struct uart_emul_data *data = dev->data; + uart_irq_callback_user_data_t cb = data->irq_cb; + void *udata = data->irq_cb_udata; + + if (cb == NULL) { + LOG_DBG("No IRQ callback configured for uart_emul device %p", dev); + return; + } + + while (true) { + bool have_work = false; + + K_SPINLOCK(&data->rx_lock) { + if (!data->rx_irq_en) { + K_SPINLOCK_BREAK; + } + + have_work = have_work || !ring_buf_is_empty(data->rx_rb); + } + + if (!have_work) { + break; + } + + cb(dev, udata); + } +} + +static int uart_emul_irq_is_pending(const struct device *dev) +{ + bool rx_pending; + struct uart_emul_data *const data = dev->data; + + K_SPINLOCK(&data->rx_lock) { + rx_pending = !ring_buf_is_empty(data->rx_rb); + } + + return rx_pending; +} + +static void uart_emul_irq_rx_enable(const struct device *dev) +{ + bool submit_irq_work; + struct uart_emul_data *const data = dev->data; + + K_SPINLOCK(&data->rx_lock) { + data->rx_irq_en = true; + submit_irq_work = !ring_buf_is_empty(data->rx_rb); + } + + if (submit_irq_work) { + (void)k_work_submit(&data->irq_work.work); + } +} + +static void uart_emul_irq_rx_disable(const struct device *dev) +{ + struct uart_emul_data *const data = dev->data; + + K_SPINLOCK(&data->rx_lock) { + data->rx_irq_en = false; + } +} + +static void uart_emul_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_emul_data *const data = dev->data; + + data->irq_cb = cb; + data->irq_cb_udata = user_data; +} + +static int uart_emul_irq_update(const struct device *dev) +{ + return 1; +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + static const struct uart_driver_api uart_emul_api = { .poll_in = uart_emul_poll_in, .poll_out = uart_emul_poll_out, @@ -106,7 +237,16 @@ static const struct uart_driver_api uart_emul_api = { .config_get = uart_emul_config_get, .configure = uart_emul_configure, #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ - .err_check = uart_emul_err_check + .err_check = uart_emul_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_read = uart_emul_fifo_read, + .irq_rx_enable = uart_emul_irq_rx_enable, + .irq_rx_disable = uart_emul_irq_rx_disable, + .irq_rx_ready = uart_emul_irq_rx_ready, + .irq_callback_set = uart_emul_irq_callback_set, + .irq_update = uart_emul_irq_update, + .irq_is_pending = uart_emul_irq_is_pending, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; void uart_emul_callback_tx_data_ready_set(const struct device *dev, @@ -121,12 +261,22 @@ void uart_emul_callback_tx_data_ready_set(const struct device *dev, uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t size) { struct uart_emul_data *drv_data = dev->data; - k_spinlock_key_t key; uint32_t count; + __unused bool empty; + __unused bool irq_en; + + K_SPINLOCK(&drv_data->rx_lock) { + count = ring_buf_put(drv_data->rx_rb, data, size); + empty = ring_buf_is_empty(drv_data->rx_rb); + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (irq_en = drv_data->rx_irq_en;)); + } + + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( + if (count > 0 && irq_en && !empty) { + (void)k_work_submit(&drv_data->irq_work.work); + } + )) - key = k_spin_lock(&drv_data->rx_lock); - count = ring_buf_put(drv_data->rx_rb, data, size); - k_spin_unlock(&drv_data->rx_lock, key); return count; } @@ -171,6 +321,11 @@ uint32_t uart_emul_flush_tx_data(const struct device *dev) #define UART_EMUL_RX_FIFO_SIZE(inst) (DT_INST_PROP(inst, rx_fifo_size)) #define UART_EMUL_TX_FIFO_SIZE(inst) (DT_INST_PROP(inst, tx_fifo_size)) +#define UART_EMUL_IRQ_WORK_INIT(inst) \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (.irq_work = {.dev = DEVICE_DT_INST_GET(inst), \ + .work = Z_WORK_INITIALIZER(uart_emul_irq_handler)},)) + #define DEFINE_UART_EMUL(inst) \ \ RING_BUF_DECLARE(uart_emul_##inst##_rx_rb, UART_EMUL_RX_FIFO_SIZE(inst)); \ @@ -182,6 +337,7 @@ uint32_t uart_emul_flush_tx_data(const struct device *dev) static struct uart_emul_data uart_emul_data_##inst = { \ .rx_rb = &uart_emul_##inst##_rx_rb, \ .tx_rb = &uart_emul_##inst##_tx_rb, \ + UART_EMUL_IRQ_WORK_INIT(inst) \ }; \ \ DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &uart_emul_data_##inst, &uart_emul_cfg_##inst, \ From 99ab1ab06cda167a633c4047d327141a19cbafaa Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Mon, 2 Oct 2023 16:33:26 -0400 Subject: [PATCH 1617/4498] drivers: serial: uart_emul: make api implementation static Keep uart API implementation of the uart_emul driver "private" by adding the static keyword. Signed-off-by: Christopher Friedt --- drivers/serial/uart_emul.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index e4ea6357ea9..55c726f96b0 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -47,7 +47,7 @@ struct uart_emul_data { #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; -int uart_emul_poll_in(const struct device *dev, unsigned char *p_char) +static int uart_emul_poll_in(const struct device *dev, unsigned char *p_char) { struct uart_emul_data *drv_data = dev->data; k_spinlock_key_t key; @@ -65,7 +65,7 @@ int uart_emul_poll_in(const struct device *dev, unsigned char *p_char) return 0; } -void uart_emul_poll_out(const struct device *dev, unsigned char out_char) +static void uart_emul_poll_out(const struct device *dev, unsigned char out_char) { struct uart_emul_data *drv_data = dev->data; const struct uart_emul_config *drv_cfg = dev->config; @@ -90,13 +90,13 @@ void uart_emul_poll_out(const struct device *dev, unsigned char out_char) } } -int uart_emul_err_check(const struct device *dev) +static int uart_emul_err_check(const struct device *dev) { return 0; } #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE -int uart_emul_configure(const struct device *dev, const struct uart_config *cfg) +static int uart_emul_configure(const struct device *dev, const struct uart_config *cfg) { struct uart_emul_data *drv_data = dev->data; @@ -104,7 +104,7 @@ int uart_emul_configure(const struct device *dev, const struct uart_config *cfg) return 0; } -int uart_emul_config_get(const struct device *dev, struct uart_config *cfg) +static int uart_emul_config_get(const struct device *dev, struct uart_config *cfg) { const struct uart_emul_data *drv_data = dev->data; From d489ec087ed5a0b4a8c104e2f5fb9a302419d96b Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Tue, 18 Jul 2023 23:49:55 +0800 Subject: [PATCH 1618/4498] lib: posix: mutex: to_posix_mutex should be spinlocked to_posix_mutex allocates a mutex which will race to change the value of the lock, thus to_posix_mutex should be performed under the spinlock to prevent the racy issue. Signed-off-by: Jaxson Han --- lib/posix/mutex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/posix/mutex.c b/lib/posix/mutex.c index 3c8dde8d52d..5aef2c0bc0e 100644 --- a/lib/posix/mutex.c +++ b/lib/posix/mutex.c @@ -112,8 +112,11 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) struct k_mutex *m; k_spinlock_key_t key; + key = k_spin_lock(&pthread_mutex_spinlock); + m = to_posix_mutex(mu); if (m == NULL) { + k_spin_unlock(&pthread_mutex_spinlock, key); return EINVAL; } @@ -122,7 +125,6 @@ static int acquire_mutex(pthread_mutex_t *mu, k_timeout_t timeout) bit = posix_mutex_to_offset(m); type = posix_mutex_type[bit]; - key = k_spin_lock(&pthread_mutex_spinlock); if (m->owner == k_current_get()) { switch (type) { case PTHREAD_MUTEX_NORMAL: From b375092441473ebc2fabac4ca33eb432ac823d16 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Sep 2023 10:23:58 +0100 Subject: [PATCH 1619/4498] doc: services: device_mgmt: smp_group_0: Tidy documentation Minor doc changes Signed-off-by: Jamie McCrae --- doc/services/device_mgmt/smp_groups/smp_group_0.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index c77c212c512..ba15ac22a1d 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -985,7 +985,7 @@ where: Bootloader Information: MCUboot =============================== -In case when MCUboot is application bootloader empty request will +In case when MCUboot is application bootloader, empty request will be responded with: .. code-block:: none @@ -1034,8 +1034,8 @@ where "mode" is one of: | 6 | MCUboot is in RAM loader mode. | +-----+-----------------------------------------------------+ -The "no-downgrade" is a flag, which is always sent when true, indicating that -mode has downgrade prevention enabled; downgrade prevention means that -if uploaded image has lower version than running, it will notbe taken -for exectuion by MCUboot. -MCUmgr may reject image with lower version in that MCUboot configuration. +The ``no-downgrade`` field is a flag, which is always sent when true, indicating that MCUboot has +downgrade prevention enabled; downgrade prevention means that if the uploaded image has a lower +version than the currently running application, it will not be used for an update by MCUboot. + +MCUmgr may reject images with a lower version in this configuration. From 5adc6d520372a5fe31b2ddbd32288282bb0ad085 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Wed, 20 Sep 2023 00:26:28 +0300 Subject: [PATCH 1620/4498] dts: silabs: Added pinctrl nodes for Silabs devices Added pinctrl nodes for Silabs SoCs where they were missing: efm32pg, efm32hg, efm32wg, efr32mg21. Signed-off-by: Yonatan Schachter --- dts/arm/silabs/efm32hg.dtsi | 8 ++++++++ dts/arm/silabs/efm32wg.dtsi | 8 ++++++++ dts/arm/silabs/efr32mg21.dtsi | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/dts/arm/silabs/efm32hg.dtsi b/dts/arm/silabs/efm32hg.dtsi index bf63ebdd6ad..e3854d6067a 100644 --- a/dts/arm/silabs/efm32hg.dtsi +++ b/dts/arm/silabs/efm32hg.dtsi @@ -140,6 +140,14 @@ status = "disabled"; }; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; diff --git a/dts/arm/silabs/efm32wg.dtsi b/dts/arm/silabs/efm32wg.dtsi index a12715acdf5..19182ebfbfe 100644 --- a/dts/arm/silabs/efm32wg.dtsi +++ b/dts/arm/silabs/efm32wg.dtsi @@ -185,6 +185,14 @@ status = "disabled"; }; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; diff --git a/dts/arm/silabs/efr32mg21.dtsi b/dts/arm/silabs/efr32mg21.dtsi index 369a1f436f2..4ada3f6ff60 100644 --- a/dts/arm/silabs/efr32mg21.dtsi +++ b/dts/arm/silabs/efr32mg21.dtsi @@ -182,6 +182,14 @@ interrupts = <44 0>; status = "disabled"; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; From c461441cc5aac2738de17ff89e46214eb2ae5750 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Wed, 20 Sep 2023 00:28:02 +0300 Subject: [PATCH 1621/4498] soc: silabs: Added Kconfig to indicate the existence of a radio PHY Added SOC_GECKO_HAS_RADIO symbol, to indicate that a SoC has a radio phy, so that radio related code would only apply to devices with radio. Signed-off-by: Yonatan Schachter --- soc/arm/silabs_exx32/Kconfig | 7 +++++++ soc/arm/silabs_exx32/efr32bg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg22/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg27/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg1p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg12p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg21/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg24/Kconfig.series | 1 + 9 files changed, 15 insertions(+) diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index cdd96703850..d0bbf68c885 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -8,6 +8,7 @@ config SOC_FAMILY_EXX32 select BUILD_OUTPUT_HEX if SOC_FAMILY_EXX32 + config SOC_FAMILY string default "silabs_exx32" @@ -326,8 +327,14 @@ config SOC_GECKO_HAS_HFRCO_FREQRANGE If disabled, indicates that configuration of HFRCO frequency for corresponding SOC is not supported via this field. This is the case for e.g. efm32hg, efm32wg series. +config SOC_GECKO_HAS_RADIO + bool + help + If enabled, indicates that the SoC has a Radio PHY. + config SOC_GECKO_USE_RAIL bool "Use RAIL (Radio Abstraction Interface Layer)" + depends on SOC_GECKO_HAS_RADIO help RAIL (Radio Abstraction Interface Layer) is a library needed to use the EFR radio hardware. This option enable the proper set of features to allow to properly compile diff --git a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series index aae28d74a45..f48d53d861e 100644 --- a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_EFR32BG13P select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select HAS_SILABS_GECKO select HAS_SWO select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series index 992e3be97ba..278f702ebac 100644 --- a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series @@ -15,6 +15,7 @@ config SOC_SERIES_EFR32BG22 select HAS_SILABS_GECKO select HAS_SWO select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 select SOC_GECKO_GPIO select SOC_GECKO_CMU diff --git a/soc/arm/silabs_exx32/efr32bg27/Kconfig.series b/soc/arm/silabs_exx32/efr32bg27/Kconfig.series index 572e6107f4e..d826c4d121c 100644 --- a/soc/arm/silabs_exx32/efr32bg27/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg27/Kconfig.series @@ -15,6 +15,7 @@ config SOC_SERIES_EFR32BG27 select HAS_SILABS_GECKO select HAS_SWO select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 select SOC_GECKO_CMU select SOC_GECKO_CORE diff --git a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series index 6feb9f9cc22..11074d6f586 100644 --- a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_EFR32FG13P select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE select SOC_GECKO_CMU diff --git a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series index 8e57722a566..8d453472de4 100644 --- a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_EFR32FG1P select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE select SOC_GECKO_CMU diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series index 00bdfc643b5..23426e8ce20 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_EFR32MG12P select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select HAS_SILABS_GECKO select HAS_SWO select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION diff --git a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series index c22cb8376ee..146493469e8 100644 --- a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series @@ -12,6 +12,7 @@ config SOC_SERIES_EFR32MG21 select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 select HAS_SILABS_GECKO select HAS_SWO diff --git a/soc/arm/silabs_exx32/efr32mg24/Kconfig.series b/soc/arm/silabs_exx32/efr32mg24/Kconfig.series index 064db296cd8..a57d2237b3d 100644 --- a/soc/arm/silabs_exx32/efr32mg24/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg24/Kconfig.series @@ -14,6 +14,7 @@ config SOC_SERIES_EFR32MG24 select ARMV8_M_DSP select ARM_TRUSTZONE_M select SOC_FAMILY_EXX32 + select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 select HAS_SILABS_GECKO select HAS_SWO From fc13204937ede1117940db9fd504a67ef719885f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 3 Oct 2023 13:45:22 +0200 Subject: [PATCH 1622/4498] sensors: mpu6050: samples: fix wrong channel fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MPU6050 does not have SENSOR_CHAN_AMBIENT_TEMP. It should be SENSOR_CHAN_DIE_TEMP. Signed-off-by: Benjamin Cabé --- samples/sensor/mpu6050/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sensor/mpu6050/src/main.c b/samples/sensor/mpu6050/src/main.c index c3151ee91ff..531a7cca873 100644 --- a/samples/sensor/mpu6050/src/main.c +++ b/samples/sensor/mpu6050/src/main.c @@ -46,7 +46,7 @@ static int process_mpu6050(const struct device *dev) gyro); } if (rc == 0) { - rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, + rc = sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &temperature); } if (rc == 0) { From ba1af3f36bfaf7916d5b635484f8f05300bbe65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 3 Oct 2023 13:46:27 +0200 Subject: [PATCH 1623/4498] sensors: mpu6050: add missing break statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing break statement so that SENSOR_CHAN_DIE_TEMP is properly supported. Signed-off-by: Benjamin Cabé --- drivers/sensor/mpu6050/mpu6050.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sensor/mpu6050/mpu6050.c b/drivers/sensor/mpu6050/mpu6050.c index 9476b420bce..34ce2d7d260 100644 --- a/drivers/sensor/mpu6050/mpu6050.c +++ b/drivers/sensor/mpu6050/mpu6050.c @@ -104,6 +104,7 @@ static int mpu6050_channel_get(const struct device *dev, break; case SENSOR_CHAN_DIE_TEMP: mpu6050_convert_temp(val, drv_data->temp); + break; default: return -ENOTSUP; } From fe6fb0f467c4b47cc33e1ffdd99ea976850d02a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Mon, 2 Oct 2023 01:14:16 +0200 Subject: [PATCH 1624/4498] bluetooth: mesh: fix static oob auth padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The remaining bit should be zero if auth is shorter than PROV_AUTH_MAX_LEN and it should be trimmed by removing octets with indexes higher than PROV_AUTH_MAX_LEN. Signed-off-by: Alperen Şener --- subsys/bluetooth/mesh/prov_device.c | 18 ++++++++++-------- subsys/bluetooth/mesh/provisioner.c | 13 ++++++++----- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 0184463568f..992bf656202 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -192,14 +192,16 @@ static void prov_start(const uint8_t *data) } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { - - uint8_t tail_size = bt_mesh_prov->static_val_len < auth_size - ? auth_size - bt_mesh_prov->static_val_len - : 0; - - memcpy(bt_mesh_prov_link.auth + tail_size, bt_mesh_prov->static_val, - tail_size ? bt_mesh_prov->static_val_len : auth_size); - memset(bt_mesh_prov_link.auth, 0, tail_size); + /* Trim the Auth if it is longer than required length */ + memcpy(bt_mesh_prov_link.auth, bt_mesh_prov->static_val, + bt_mesh_prov->static_val_len > auth_size ? auth_size + : bt_mesh_prov->static_val_len); + + /* Padd with zeros if the Auth is shorter the required length*/ + if (bt_mesh_prov->static_val_len < auth_size) { + memset(bt_mesh_prov_link.auth + bt_mesh_prov->static_val_len, 0, + auth_size - bt_mesh_prov->static_val_len); + } } } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 673e14578d2..361f373cb7b 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -751,17 +751,20 @@ int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size) int bt_mesh_auth_method_set_static(const uint8_t *static_val, uint8_t size) { - uint8_t tail_size = size < PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN - size : 0; - if (!size || !static_val) { return -EINVAL; } prov_set_method(AUTH_METHOD_STATIC, 0, 0); - memcpy(bt_mesh_prov_link.auth + tail_size, static_val, - tail_size ? size : PROV_AUTH_MAX_LEN); - memset(bt_mesh_prov_link.auth, 0, tail_size); + /* Trim the Auth if it is longer than required length */ + memcpy(bt_mesh_prov_link.auth, static_val, + size > PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN : size); + + /* Padd with zeros if the Auth is shorter the required length*/ + if (size < PROV_AUTH_MAX_LEN) { + memset(bt_mesh_prov_link.auth + size, 0, PROV_AUTH_MAX_LEN - size); + } return 0; } From 89db200117aa4d0604060d65318dcc0ab30b073d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 3 Oct 2023 16:23:00 +0200 Subject: [PATCH 1625/4498] Bluetooth: Controller: Remove unused terminate_ack Remove the terminate_ack from struct ll_conn since it is not used anywhere, and results in dead code. Signed-off-by: Emil Gydesen --- subsys/bluetooth/controller/ll_sw/ull_central.c | 2 -- subsys/bluetooth/controller/ll_sw/ull_conn.c | 6 ------ subsys/bluetooth/controller/ll_sw/ull_conn_types.h | 1 - 3 files changed, 9 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index b189c65fa21..7ea3c600ea6 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -291,8 +291,6 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, /* Setup the PRT reload */ ull_cp_prt_reload_set(conn, conn_interval_us); - conn->central.terminate_ack = 0U; - conn->llcp_terminate.reason_final = 0U; /* NOTE: use allocated link for generating dedicated * terminate ind rx node diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 9d78af7acc1..1640c00e87e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1044,12 +1044,6 @@ void ull_conn_done(struct node_rx_event_done *done) lll->latency_event = lll->latency; } #endif /* CONFIG_BT_PERIPHERAL */ - -#if defined(CONFIG_BT_CENTRAL) - } else if (reason_final) { - conn->central.terminate_ack = 1; -#endif /* CONFIG_BT_CENTRAL */ - } /* Reset connection failed to establish countdown */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index 12e16488f38..8fabab03378 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -202,7 +202,6 @@ struct ll_conn { #if defined(CONFIG_BT_CTLR_CONN_META) uint8_t is_must_expire:1; #endif /* CONFIG_BT_CTLR_CONN_META */ - uint8_t terminate_ack:1; } central; #endif /* CONFIG_BT_CENTRAL */ }; From d79ba86c04922d9ac139ac6c47ee3547f1ff891e Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Mon, 2 Oct 2023 20:19:55 +0100 Subject: [PATCH 1626/4498] lib: libc: armstdc: add missing retarget of fputc to _stdout_hook Fixes #62677 where printf defaults to using armclang's semihosting backed implementation of printf. Signed-off-by: Wilfried Chauveau --- lib/libc/armstdc/src/libc-hooks.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/libc/armstdc/src/libc-hooks.c b/lib/libc/armstdc/src/libc-hooks.c index 4884c391465..afce534eddf 100644 --- a/lib/libc/armstdc/src/libc-hooks.c +++ b/lib/libc/armstdc/src/libc-hooks.c @@ -25,3 +25,8 @@ volatile int *__aeabi_errno_addr(void) { return &_current->errno_var; } + +int fputc(int c, FILE *f) +{ + return (_stdout_hook)(c); +} From 1b21109c2cc618bd4dcc3ea2c5658337f9b92db5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 3 Oct 2023 15:35:24 +0200 Subject: [PATCH 1627/4498] net: lwm2m: Reset ongoing notification in case token changes In case observation token changes (the LwM2M server re-sends observation request to the client), the LwM2M engine should cancel any ongoing notifications based on the old token. Otherwise, it will be impossible to match the pending notification reply (ACK) with the observer context anymore, causing new notifications for this observation to stall. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_engine.c | 2 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 6 +++--- subsys/net/lib/lwm2m/lwm2m_observation.c | 14 +++++++++++++- subsys/net/lib/lwm2m/lwm2m_observation.h | 14 +++++++------- tests/net/lib/lwm2m/lwm2m_engine/src/main.c | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 651baa30ff6..d4ebf2d62a2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -592,7 +592,7 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) continue; } /* Check That There is not pending process*/ - if (obs->active_tx_operation) { + if (obs->active_notify != NULL) { continue; } diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 678f358d1ee..2733f6ed4a8 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2823,7 +2823,7 @@ static void notify_message_timeout_cb(struct lwm2m_message *msg) msg->token, msg->tkl); if (obs) { - obs->active_tx_operation = false; + obs->active_notify = NULL; if (client_ctx->observe_cb) { client_ctx->observe_cb(LWM2M_OBSERVE_EVENT_NOTIFY_TIMEOUT, &msg->path, msg->reply->user_data); @@ -2895,7 +2895,7 @@ static int notify_message_reply_cb(const struct coap_packet *response, struct co reply->token, reply->tkl); if (obs) { - obs->active_tx_operation = false; + obs->active_notify = NULL; if (msg->ctx->observe_cb) { msg->ctx->observe_cb(LWM2M_OBSERVE_EVENT_NOTIFY_ACK, lwm2m_read_first_path_ptr(&obs->path_list), @@ -3068,7 +3068,7 @@ int generate_notify_message(struct lwm2m_ctx *ctx, struct observe_node *obs, voi goto cleanup; } - obs->active_tx_operation = true; + obs->active_notify = msg; obs->resource_update = false; lwm2m_information_interface_send(msg); #if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT) diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 91ab9c1709a..7933ebd8fd3 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -438,7 +438,7 @@ static void engine_observe_node_init(struct observe_node *obs, const uint8_t *to obs->event_timestamp = 0; } obs->resource_update = false; - obs->active_tx_operation = false; + obs->active_notify = NULL; obs->format = format; obs->counter = OBSERVE_COUNTER_START; sys_slist_append(&ctx->observer, &obs->node); @@ -596,6 +596,12 @@ static int engine_add_observer(struct lwm2m_message *msg, const uint8_t *token, memcpy(obs->token, token, tkl); obs->tkl = tkl; + /* Cancel ongoing notification */ + if (obs->active_notify != NULL) { + lwm2m_reset_message(obs->active_notify, true); + obs->active_notify = NULL; + } + LOG_DBG("OBSERVER DUPLICATE %u/%u/%u(%u) [%s]", msg->path.obj_id, msg->path.obj_inst_id, msg->path.res_id, msg->path.level, lwm2m_sprint_ip_addr(&msg->ctx->remote_addr)); @@ -679,6 +685,12 @@ static int engine_add_composite_observer(struct lwm2m_message *msg, const uint8_ memcpy(obs->token, token, tkl); obs->tkl = tkl; + /* Cancel ongoing notification */ + if (obs->active_notify != NULL) { + lwm2m_reset_message(obs->active_notify, true); + obs->active_notify = NULL; + } + LOG_DBG("OBSERVER Composite DUPLICATE [%s]", lwm2m_sprint_ip_addr(&msg->ctx->remote_addr)); diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.h b/subsys/net/lib/lwm2m/lwm2m_observation.h index 95e60ab0a19..d74df74aab4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.h +++ b/subsys/net/lib/lwm2m/lwm2m_observation.h @@ -14,16 +14,16 @@ int lwm2m_notify_observer_path(const struct lwm2m_obj_path *path); struct observe_node { sys_snode_t node; - sys_slist_t path_list; /* List of Observation path */ - uint8_t token[MAX_TOKEN_LEN]; /* Observation Token */ - int64_t event_timestamp; /* Timestamp for trig next Notify */ - int64_t last_timestamp; /* Timestamp from last Notify */ + sys_slist_t path_list; /* List of Observation path */ + uint8_t token[MAX_TOKEN_LEN]; /* Observation Token */ + int64_t event_timestamp; /* Timestamp for trig next Notify */ + int64_t last_timestamp; /* Timestamp from last Notify */ + struct lwm2m_message *active_notify; /* Currently active notification */ uint32_t counter; uint16_t format; uint8_t tkl; - bool resource_update : 1; /* Resource is updated */ - bool composite : 1; /* Composite Observation */ - bool active_tx_operation : 1; /* Active Notification process ongoing */ + bool resource_update : 1; /* Resource is updated */ + bool composite : 1; /* Composite Observation */ }; /* Attribute handling. */ diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c index bd1d21983dd..ed26380eccd 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c @@ -238,7 +238,7 @@ ZTEST(lwm2m_engine, test_check_notifications) obs.last_timestamp = k_uptime_get(); obs.event_timestamp = k_uptime_get() + 1000U; obs.resource_update = false; - obs.active_tx_operation = false; + obs.active_notify = NULL; sys_slist_append(&ctx.observer, &obs.node); From 22f09e9fa03fcf88fcc0832857a4d77f8ea0db8c Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Mon, 2 Oct 2023 14:53:41 +0300 Subject: [PATCH 1628/4498] net: coap: release non-confirmable messages Only confirmable messages need pending tracking. Non-confirmable messages are released after sending. Match incoming packets with token, not message ID. Ignore responses with non-matching tokens. Remove unused function send_reset(). Signed-off-by: Juha Ylinen --- subsys/net/lib/coap/coap_client.c | 79 +++++++++------------------- tests/net/lib/coap_client/src/main.c | 4 +- 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index d096e39c62f..e78aafd6829 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -308,12 +308,6 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr reset_internal_request(internal_req); - if (retries == -1) { - internal_req->retry_count = DEFAULT_RETRY_AMOUNT; - } else { - internal_req->retry_count = retries; - } - if (k_mutex_lock(&client->send_mutex, K_NO_WAIT)) { return -EAGAIN; } @@ -332,16 +326,25 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr goto out; } - ret = coap_pending_init(&internal_req->pending, &internal_req->request, &client->address, - internal_req->retry_count); + /* only TYPE_CON messages need pending tracking */ + if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { + if (retries == -1) { + internal_req->retry_count = DEFAULT_RETRY_AMOUNT; + } else { + internal_req->retry_count = retries; + } - if (ret < 0) { - LOG_ERR("Failed to initialize pending struct"); - k_mutex_unlock(&client->send_mutex); - goto out; - } + ret = coap_pending_init(&internal_req->pending, &internal_req->request, + &client->address, internal_req->retry_count); + + if (ret < 0) { + LOG_ERR("Failed to initialize pending struct"); + k_mutex_unlock(&client->send_mutex); + goto out; + } - coap_pending_cycle(&internal_req->pending); + coap_pending_cycle(&internal_req->pending); + } ret = send_request(sock, internal_req->request.data, internal_req->request.offset, 0, &client->address, client->socklen); @@ -368,6 +371,10 @@ static void report_callback_error(struct coap_client_internal_request *internal_ static bool timeout_expired(struct coap_client_internal_request *internal_req) { + if (internal_req->pending.timeout == 0) { + return false; + } + return (internal_req->request_ongoing && internal_req->pending.timeout <= (k_uptime_get() - internal_req->pending.t0)); } @@ -547,35 +554,6 @@ static int send_ack(struct coap_client *client, const struct coap_packet *req, return 0; } -static int send_reset(struct coap_client *client, const struct coap_packet *req, - uint8_t response_code) -{ - int ret; - uint16_t id; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t tkl; - struct coap_packet reset; - - id = coap_header_get_id(req); - tkl = response_code ? coap_header_get_token(req, token) : 0; - ret = coap_packet_init(&reset, client->send_buf, MAX_COAP_MSG_LEN, COAP_VERSION, - COAP_TYPE_RESET, tkl, token, response_code, id); - - if (ret < 0) { - LOG_ERR("Error creating CoAP reset message"); - return ret; - } - - ret = send_request(client->fd, reset.data, reset.offset, 0, - &client->address, client->socklen); - if (ret < 0) { - LOG_ERR("Error sending CoAP reset message"); - return ret; - } - - return 0; -} - struct coap_client_internal_request *get_request_with_id(struct coap_client *client, uint16_t message_id) { @@ -631,7 +609,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet */ response_type = coap_header_get_type(response); - internal_req = get_request_with_id(client, coap_header_get_id(response)); + internal_req = get_request_with_token(client, response); /* Reset and Ack need to match the message ID with request */ if ((response_type == COAP_TYPE_ACK || response_type == COAP_TYPE_RESET) && internal_req == NULL) { @@ -655,17 +633,8 @@ static int handle_response(struct coap_client *client, const struct coap_packet return 1; } - /* Check for tokens - * Separate response doesn't match with message ID, - * check if there is a separate request waiting with matching token - */ - if (internal_req == NULL) { - internal_req = get_request_with_token(client, response); - } - if (internal_req == NULL || !token_compare(internal_req, response)) { - LOG_ERR("Not matching tokens, respond with reset"); - ret = send_reset(client, response, COAP_RESPONSE_CODE_NOT_FOUND); + LOG_WRN("Not matching tokens"); return 1; } @@ -795,7 +764,7 @@ void coap_client_recv(void *coap_cl, void *a, void *b) ret = handle_response(clients[i], &response); if (ret < 0) { - LOG_ERR("Error handling respnse"); + LOG_ERR("Error handling response"); } clients[i]->response_ready = false; diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index a3862852c21..bb9d9fc38c5 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -392,7 +392,5 @@ ZTEST(coap_client, test_unmatching_tokens) k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1)); clear_socket_events(); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_NOT_FOUND, "Unexpected response %d", - last_response_code); - k_sleep(K_MSEC(1)); + k_sleep(K_MSEC(1000)); } From ecefcd7f87d73bbd7d472399127421639d5bc2c2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 21 Sep 2023 10:21:14 +0000 Subject: [PATCH 1629/4498] misc: check_init_priorities: drop CONFIG_DEVICE_DEPS=y This runs fine without CONFIG_DEVICE_DEPS, let's drop it from here. Signed-off-by: Fabio Baltieri --- tests/misc/check_init_priorities/prj.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/misc/check_init_priorities/prj.conf b/tests/misc/check_init_priorities/prj.conf index bad7dc092f3..6709862e8d4 100644 --- a/tests/misc/check_init_priorities/prj.conf +++ b/tests/misc/check_init_priorities/prj.conf @@ -1,4 +1 @@ -# Required to force 2 stage linking -CONFIG_DEVICE_DEPS=y - CONFIG_CHECK_INIT_PRIORITIES=n From 8db1a5add221b5e47ad4e01dfcb3b4064a8299f4 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 21 Sep 2023 15:20:49 +0800 Subject: [PATCH 1630/4498] drivers: intc: plic: support trigger type by default and hardcode offset Removing the edge-trigger Kconfig as it is supported by default in the RISCV PLIC specifications. Define the edge-trigger register offset in the driver instead of retrieving the value from devicetree as it is not something configurable. The value 0x1080 is defined in Andes & Telink datasheets. Updated build_all testcase. Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/Kconfig.plic | 6 ------ drivers/interrupt_controller/intc_plic.c | 19 ++++++++++++------- .../sifive,plic-1.0.0.yaml | 4 ---- .../intc_plic/app.edge_interrupt.overlay | 13 ------------- .../interrupt_controller/intc_plic/src/main.c | 10 ---------- .../intc_plic/testcase.yaml | 5 ----- 6 files changed, 12 insertions(+), 45 deletions(-) delete mode 100644 tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay diff --git a/drivers/interrupt_controller/Kconfig.plic b/drivers/interrupt_controller/Kconfig.plic index fd5f3b95de4..c1e16c7c1c5 100644 --- a/drivers/interrupt_controller/Kconfig.plic +++ b/drivers/interrupt_controller/Kconfig.plic @@ -10,9 +10,3 @@ config PLIC help Platform Level Interrupt Controller provides support for external interrupt lines defined by the RISC-V SoC. - -config PLIC_SUPPORTS_EDGE_IRQ - bool "The given interrupt controller supports edge interrupts" - help - The given interrupt controller supports edge triggered - interrupts. diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index bbab421d253..34c62e2b14a 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -21,6 +21,14 @@ #include #include +#define PLIC_BASE_ADDR(n) DT_INST_REG_ADDR(n) +/* + * Trigger type is mentioned, but not defined in the RISCV PLIC specs. + * However, it is defined and supported by at least the Andes & Telink datasheet, and supported + * in Linux's SiFive PLIC driver + */ +#define PLIC_REG_TRIG_TYPE_OFFSET 0x1080 + #define PLIC_MAX_PRIO DT_INST_PROP(0, riscv_max_priority) #define PLIC_PRIO DT_INST_REG_ADDR_BY_NAME_U64(0, prio) #define PLIC_IRQ_EN DT_INST_REG_ADDR_BY_NAME_U64(0, irq_en) @@ -29,7 +37,7 @@ #define PLIC_IRQS (CONFIG_NUM_IRQS - CONFIG_2ND_LVL_ISR_TBL_OFFSET) #define PLIC_EN_SIZE ((PLIC_IRQS >> 5) + 1) -#define PLIC_EDGE_TRIG_TYPE (DT_INST_REG_ADDR(0) + DT_INST_PROP(0, riscv_trigger_reg_offset)) +#define PLIC_EDGE_TRIG_TYPE (PLIC_BASE_ADDR(0) + PLIC_REG_TRIG_TYPE_OFFSET) #define PLIC_EDGE_TRIG_SHIFT 5 struct plic_regs_t { @@ -52,13 +60,10 @@ static int save_irq; */ static int riscv_plic_is_edge_irq(uint32_t irq) { - if (IS_ENABLED(CONFIG_PLIC_SUPPORTS_EDGE_IRQ)) { - volatile uint32_t *trig = (volatile uint32_t *)PLIC_EDGE_TRIG_TYPE; + volatile uint32_t *trig = (volatile uint32_t *)PLIC_EDGE_TRIG_TYPE; - trig += (irq >> PLIC_EDGE_TRIG_SHIFT); - return *trig & BIT(irq); - } - return 0; + trig += (irq >> PLIC_EDGE_TRIG_SHIFT); + return *trig & BIT(irq); } /** diff --git a/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml index 839506f33ea..4698d7f8515 100644 --- a/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml +++ b/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml @@ -12,7 +12,3 @@ properties: type: int description: Number of external interrupts supported required: true - riscv,trigger-reg-offset: - type: int - default: 4224 - description: Offset of the trigger type register if supported diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay b/tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay deleted file mode 100644 index e22118ecefe..00000000000 --- a/tests/drivers/build_all/interrupt_controller/intc_plic/app.edge_interrupt.overlay +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2023 Meta - * - * SPDX-License-Identifier: Apache-2.0 - */ - - /{ - soc { - plic: interrupt-controller@c000000 { - riscv,trigger-reg-offset = < 0x00001080 >; - }; - }; -}; diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c b/tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c index 82860397c3f..06e02aa86d1 100644 --- a/tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/src/main.c @@ -4,16 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#ifdef CONFIG_PLIC_SUPPORTS_EDGE_IRQ -BUILD_ASSERT(DT_PROP(DT_NODELABEL(plic), riscv_trigger_reg_offset) == 0x00001080, - "the offset should be the value defined in the board dt overlay"); -#else -BUILD_ASSERT(DT_PROP(DT_NODELABEL(plic), riscv_trigger_reg_offset) == 4224, - "the offset should be the binding default value"); -#endif /* CONFIG_PLIC_SUPPORTS_EDGE_IRQ */ - int main(void) { return 0; diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml index ea549dc6f1c..6d6164a3bed 100644 --- a/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml @@ -10,8 +10,3 @@ common: - plic tests: drivers.interrupt_controller.intc_plic.build: {} - drivers.interrupt_controller.intc_plic.edge_interrupt.build: - extra_args: - DTC_OVERLAY_FILE="./app.edge_interrupt.overlay" - extra_configs: - - CONFIG_PLIC_SUPPORTS_EDGE_IRQ=y From 39433f0669f1fd620f36605d1c3df61a6cf97ae2 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 21 Sep 2023 15:40:10 +0800 Subject: [PATCH 1631/4498] drivers: intc: plic: define all registers' offset in the driver Define all the register offset directly in the driver according to the RISCV PLIC specification as they are not configurable, see: https://github.com/riscv/riscv-plic-spec. Updated devicetrees that has PLIC accordingly. Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/intc_plic.c | 13 ++++++++++--- dts/riscv/andes/andes_v5_ae350.dtsi | 5 +---- dts/riscv/efinix/sapphire_soc.dtsi | 5 +---- dts/riscv/lowrisc/opentitan_earlgrey.dtsi | 5 +---- dts/riscv/microchip/microchip-miv.dtsi | 5 +---- dts/riscv/microchip/mpfs-icicle.dtsi | 5 +---- dts/riscv/sifive/riscv32-fe310.dtsi | 5 +---- dts/riscv/sifive/riscv64-fu540.dtsi | 5 +---- dts/riscv/sifive/riscv64-fu740.dtsi | 5 +---- dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi | 5 +---- dts/riscv/telink/telink_b91.dtsi | 5 +---- dts/riscv/virt.dtsi | 5 +---- 12 files changed, 21 insertions(+), 47 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 34c62e2b14a..42f6cbc1f06 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -22,6 +22,13 @@ #include #define PLIC_BASE_ADDR(n) DT_INST_REG_ADDR(n) +/* + * These registers' offset are defined in the RISCV PLIC specs, see: + * https://github.com/riscv/riscv-plic-spec + */ +#define PLIC_REG_PRIO_OFFSET 0x0 +#define PLIC_REG_IRQ_EN_OFFSET 0x2000 +#define PLIC_REG_REGS_OFFSET 0x200000 /* * Trigger type is mentioned, but not defined in the RISCV PLIC specs. * However, it is defined and supported by at least the Andes & Telink datasheet, and supported @@ -30,9 +37,9 @@ #define PLIC_REG_TRIG_TYPE_OFFSET 0x1080 #define PLIC_MAX_PRIO DT_INST_PROP(0, riscv_max_priority) -#define PLIC_PRIO DT_INST_REG_ADDR_BY_NAME_U64(0, prio) -#define PLIC_IRQ_EN DT_INST_REG_ADDR_BY_NAME_U64(0, irq_en) -#define PLIC_REG DT_INST_REG_ADDR_BY_NAME_U64(0, reg) +#define PLIC_PRIO (PLIC_BASE_ADDR(0) + PLIC_REG_PRIO_OFFSET) +#define PLIC_IRQ_EN (PLIC_BASE_ADDR(0) + PLIC_REG_IRQ_EN_OFFSET) +#define PLIC_REG (PLIC_BASE_ADDR(0) + PLIC_REG_REGS_OFFSET) #define PLIC_IRQS (CONFIG_NUM_IRQS - CONFIG_2ND_LVL_ISR_TBL_OFFSET) #define PLIC_EN_SIZE ((PLIC_IRQS >> 5) + 1) diff --git a/dts/riscv/andes/andes_v5_ae350.dtsi b/dts/riscv/andes/andes_v5_ae350.dtsi index c102e3b6118..1b5abf0ee8c 100644 --- a/dts/riscv/andes/andes_v5_ae350.dtsi +++ b/dts/riscv/andes/andes_v5_ae350.dtsi @@ -171,10 +171,7 @@ #address-cells = <1>; #interrupt-cells = <2>; interrupt-controller; - reg = < 0xe4000000 0x00001000 - 0xe4002000 0x00000800 - 0xe4200000 0x00010000 >; - reg-names = "prio", "irq_en", "reg"; + reg = <0xe4000000 0x04000000>; riscv,max-priority = <255>; riscv,ndev = <1023>; interrupts-extended = <&CPU0_intc 11 &CPU1_intc 11 diff --git a/dts/riscv/efinix/sapphire_soc.dtsi b/dts/riscv/efinix/sapphire_soc.dtsi index e6b2a98254b..75043c9dfbb 100644 --- a/dts/riscv/efinix/sapphire_soc.dtsi +++ b/dts/riscv/efinix/sapphire_soc.dtsi @@ -55,10 +55,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = < 0xf8c00000 0x00001000 - 0xf8c02000 0x00000800 - 0xf8e00000 0x00010000 >; - reg-names = "prio", "irq_en", "reg"; + reg = <0xf8c00000 0x04000000>; riscv,max-priority = <3>; riscv,ndev = <32>; }; diff --git a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi index 1b86ed2af62..2df96d71eeb 100644 --- a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi +++ b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi @@ -75,10 +75,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0x48000000 0x00001000 - 0x48002000 0x00001000 - 0x48200000 0x00000008>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x48000000 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <184>; status = "okay"; diff --git a/dts/riscv/microchip/microchip-miv.dtsi b/dts/riscv/microchip/microchip-miv.dtsi index 56060baa8f2..305145b7e44 100644 --- a/dts/riscv/microchip/microchip-miv.dtsi +++ b/dts/riscv/microchip/microchip-miv.dtsi @@ -54,10 +54,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0x40000000 0x2000 - 0x40002000 0x1fe000 - 0x40200000 0x2000000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x40000000 0x04000000>; riscv,max-priority = <1>; riscv,ndev = <31>; }; diff --git a/dts/riscv/microchip/mpfs-icicle.dtsi b/dts/riscv/microchip/mpfs-icicle.dtsi index 76b0320c55e..4ed4d45e305 100644 --- a/dts/riscv/microchip/mpfs-icicle.dtsi +++ b/dts/riscv/microchip/mpfs-icicle.dtsi @@ -121,10 +121,7 @@ interrupt-controller; interrupts-extended = <&hlic0 11 &hlic1 11>; - reg = <0x0c000000 0x00002000 - 0x0c002000 0x001fe000 - 0x0c200000 0x3e000000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0c000000 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <187>; }; diff --git a/dts/riscv/sifive/riscv32-fe310.dtsi b/dts/riscv/sifive/riscv32-fe310.dtsi index 2a4f9424e81..c028db37c4e 100644 --- a/dts/riscv/sifive/riscv32-fe310.dtsi +++ b/dts/riscv/sifive/riscv32-fe310.dtsi @@ -123,10 +123,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0x0c000000 0x00002000 - 0x0c002000 0x001fe000 - 0x0c200000 0x03e00000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0c000000 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <52>; }; diff --git a/dts/riscv/sifive/riscv64-fu540.dtsi b/dts/riscv/sifive/riscv64-fu540.dtsi index a71a68fdb17..ed56401d462 100644 --- a/dts/riscv/sifive/riscv64-fu540.dtsi +++ b/dts/riscv/sifive/riscv64-fu540.dtsi @@ -120,10 +120,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0x0c000000 0x00002000 - 0x0c002000 0x001fe000 - 0x0c200000 0x03e00000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0c000000 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <52>; }; diff --git a/dts/riscv/sifive/riscv64-fu740.dtsi b/dts/riscv/sifive/riscv64-fu740.dtsi index 9a2c5b62ffd..bbe45b98aab 100644 --- a/dts/riscv/sifive/riscv64-fu740.dtsi +++ b/dts/riscv/sifive/riscv64-fu740.dtsi @@ -142,10 +142,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts-extended = <&hlic 11>; - reg = <0x0 0x0c000000 0x0 0x00002000 - 0x0 0x0c002000 0x0 0x001fe000 - 0x0 0x0c200000 0x0 0x03e00000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0 0x0c000000 0x0 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <52>; }; diff --git a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi index 445a1534c5b..c355ac89a5f 100644 --- a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi +++ b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi @@ -129,10 +129,7 @@ interrupt-controller; interrupts-extended = <&cpu0intctrl 11 &cpu0intctrl 9 &cpu1intctrl 11 &cpu1intctrl 9 >; - reg = <0x0 0x0c000000 0x0 0x00002000 - 0x0 0x0c002000 0x0 0x001fe000 - 0x0 0x0c200000 0x0 0x03e00000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0 0x0c000000 0x0 0x04000000>; riscv,max-priority = <7>; riscv,ndev = <127>; }; diff --git a/dts/riscv/telink/telink_b91.dtsi b/dts/riscv/telink/telink_b91.dtsi index 2a6acfd5fd2..a75929f2814 100644 --- a/dts/riscv/telink/telink_b91.dtsi +++ b/dts/riscv/telink/telink_b91.dtsi @@ -132,10 +132,7 @@ interrupt-controller; interrupts-extended = <&hlic 11>; interrupt-parent = <&cpu0>; - reg = < 0xe4000000 0x00001000 - 0xe4002000 0x00000800 - 0xe4200000 0x00010000 >; - reg-names = "prio", "irq_en", "reg"; + reg = <0xe4000000 0x00210000>; riscv,max-priority = <3>; riscv,ndev = <63>; }; diff --git a/dts/riscv/virt.dtsi b/dts/riscv/virt.dtsi index 6119c6112db..45e4a7559a5 100644 --- a/dts/riscv/virt.dtsi +++ b/dts/riscv/virt.dtsi @@ -165,10 +165,7 @@ plic: interrupt-controller@c000000 { riscv,max-priority = <7>; riscv,ndev = < 0x35 >; - reg = <0x0c000000 0x00002000 - 0x0c002000 0x001fe000 - 0x0c200000 0x03e00000>; - reg-names = "prio", "irq_en", "reg"; + reg = <0x0c000000 0x04000000>; interrupts-extended = < &hlic0 0x0b &hlic0 0x09 &hlic1 0x0b &hlic1 0x09 From 0e6bef270e4a0d735d8e7b40362b54ec5a92c031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 29 Sep 2023 12:15:52 +0200 Subject: [PATCH 1632/4498] doc: drivers: counter: cleanup Doxygen docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly document structs and convert some @defgroups to @name'd headings that are more appropriate. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/counter.h | 102 ++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 36 deletions(-) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index 2fd86d5d989..5da1a257d21 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -32,8 +32,11 @@ extern "C" { #endif -/**@defgroup COUNTER_FLAGS Counter device capabilities - * @{ */ +/** + * @anchor COUNTER_FLAGS + * @name Counter device capabilities + * @{ + */ /** * @brief Counter count up flag. @@ -42,7 +45,9 @@ extern "C" { /**@} */ -/**@defgroup COUNTER_TOP_FLAGS Flags used by @ref counter_top_cfg. +/** + * @anchor COUNTER_TOP_FLAGS + * @name Flags used by counter_top_cfg. * @{ */ @@ -64,7 +69,9 @@ extern "C" { /**@} */ -/**@defgroup COUNTER_ALARM_FLAGS Alarm configuration flags +/** + * @anchor COUNTER_ALARM_FLAGS + * @name Alarm configuration flags * * @brief Used in alarm configuration structure (@ref counter_alarm_cfg). * @{ */ @@ -87,7 +94,9 @@ extern "C" { /**@} */ -/**@defgroup COUNTER_GUARD_PERIOD_FLAGS Counter guard period flags +/** + * @anchor COUNTER_GUARD_PERIOD_FLAGS + * @name Counter guard period flags * * @brief Used by @ref counter_set_guard_period and * @ref counter_get_guard_period. @@ -113,27 +122,36 @@ typedef void (*counter_alarm_callback_t)(const struct device *dev, void *user_data); /** @brief Alarm callback structure. - * - * @param callback Callback called on alarm (cannot be NULL). - * @param ticks Number of ticks that triggers the alarm. It can be relative (to - * now) or an absolute value (see @ref COUNTER_ALARM_CFG_ABSOLUTE). - * Both, relative and absolute, alarm values can be any value - * between zero and the current top value (see @ref counter_get_top_value). - * When setting an absolute alarm value close to the current counter - * value there is a risk that the counter will have counted past the - * given absolute value before the driver manages to activate the alarm. - * Therefore a guard period can be defined that lets the driver decide - * unambiguously whether it is late or not (see @ref counter_set_guard_period). - * If the counter is clock driven then ticks can be converted to - * microseconds (see @ref counter_ticks_to_us). Alternatively, - * the counter implementation may count asynchronous events. - * @param user_data User data returned in callback. - * @param flags Alarm flags. See @ref COUNTER_ALARM_FLAGS. */ struct counter_alarm_cfg { + /** + * Callback called on alarm (cannot be NULL). + */ counter_alarm_callback_t callback; + /** + * Number of ticks that triggers the alarm. + * + * It can be relative (to now) or an absolute value (see @ref + * COUNTER_ALARM_CFG_ABSOLUTE). Both, relative and absolute, alarm + * values can be any value between zero and the current top value (see + * @ref counter_get_top_value). When setting an absolute alarm value + * close to the current counter value there is a risk that the counter + * will have counted past the given absolute value before the driver + * manages to activate the alarm. Therefore a guard period can be + * defined that lets the driver decide unambiguously whether it is late + * or not (see @ref counter_set_guard_period). If the counter is clock + * driven then ticks can be converted to microseconds (see @ref + * counter_ticks_to_us). Alternatively, the counter implementation may + * count asynchronous events. + */ uint32_t ticks; + /** + * User data returned in callback. + */ void *user_data; + /** + * Alarm flags (see @ref COUNTER_ALARM_FLAGS). + */ uint32_t flags; }; @@ -146,34 +164,46 @@ typedef void (*counter_top_callback_t)(const struct device *dev, void *user_data); /** @brief Top value configuration structure. - * - * @param ticks Top value. - * @param callback Callback function. Can be NULL. - * @param user_data User data passed to callback function. Not valid if - * callback is NULL. - * @param flags Flags. See @ref COUNTER_TOP_FLAGS. */ struct counter_top_cfg { + /** + * Top value. + */ uint32_t ticks; + /** + * Callback function (can be NULL). + */ counter_top_callback_t callback; + /** + * User data passed to callback function (not valid if callback is NULL). + */ void *user_data; + /** + * Flags (see @ref COUNTER_TOP_FLAGS). + */ uint32_t flags; }; /** @brief Structure with generic counter features. - * - * @param max_top_value Maximal (default) top value on which counter is reset - * (cleared or reloaded). - * @param freq Frequency of the source clock if synchronous events are - * counted. - * @param flags Flags. See @ref COUNTER_FLAGS. - * @param channels Number of channels that can be used for setting alarm, - * see @ref counter_set_channel_alarm. */ struct counter_config_info { + /** + * Maximal (default) top value on which counter is reset (cleared or reloaded). + */ uint32_t max_top_value; + /** + * Frequency of the source clock if synchronous events are counted. + */ uint32_t freq; + /** + * Flags (see @ref COUNTER_FLAGS). + */ uint8_t flags; + /** + * Number of channels that can be used for setting alarm. + * + * @see counter_set_channel_alarm + */ uint8_t channels; }; @@ -618,7 +648,7 @@ static inline int z_impl_counter_set_guard_period(const struct device *dev, /** * @brief Return guard period. * - * See @ref counter_set_guard_period. + * @see counter_set_guard_period. * * @param dev Pointer to the device structure for the driver instance. * @param flags See @ref COUNTER_GUARD_PERIOD_FLAGS. From fd6f3c5a2ac99291ba10b274ecfd7fc9505112ce Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 29 Sep 2023 10:48:50 +0200 Subject: [PATCH 1633/4498] twister: Fix quarantine performance issue When using a quarantine file with more than 512 unique entries, than time of matching quarantine increases significantly. This is because regexp cache size is 512. Add precompiled regexp entries to the quarantine as a fix. Signed-off-by: Grzegorz Chwierut --- .../pylib/twister/twisterlib/quarantine.py | 22 ++++++++++++++----- scripts/tests/twister/test_quarantine.py | 5 ++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/quarantine.py b/scripts/pylib/twister/twisterlib/quarantine.py index cb05a920ca6..e4baa52781e 100644 --- a/scripts/pylib/twister/twisterlib/quarantine.py +++ b/scripts/pylib/twister/twisterlib/quarantine.py @@ -41,6 +41,10 @@ class QuarantineElement: architectures: list[str] = field(default_factory=list) simulations: list[str] = field(default_factory=list) comment: str = 'NA' + re_scenarios: list = field(default_factory=list) + re_platforms: list = field(default_factory=list) + re_architectures: list = field(default_factory=list) + re_simulations: list = field(default_factory=list) def __post_init__(self): # If there is no entry in filters then take all possible values. @@ -53,6 +57,12 @@ def __post_init__(self): self.architectures = [] if 'all' in self.simulations: self.simulations = [] + # keep precompiled regexp entiries to speed-up matching + self.re_scenarios = [re.compile(pat) for pat in self.scenarios] + self.re_platforms = [re.compile(pat) for pat in self.platforms] + self.re_architectures = [re.compile(pat) for pat in self.architectures] + self.re_simulations = [re.compile(pat) for pat in self.simulations] + # However, at least one of the filters ('scenarios', platforms' ...) # must be given (there is no sense to put all possible configuration # into quarantine) @@ -101,16 +111,16 @@ def get_matched_quarantine(self, for qelem in self.qlist: matched: bool = False if (qelem.scenarios - and (matched := _is_element_matched(scenario, qelem.scenarios)) is False): + and (matched := _is_element_matched(scenario, qelem.re_scenarios)) is False): continue if (qelem.platforms - and (matched := _is_element_matched(platform, qelem.platforms)) is False): + and (matched := _is_element_matched(platform, qelem.re_platforms)) is False): continue if (qelem.architectures - and (matched := _is_element_matched(architecture, qelem.architectures)) is False): + and (matched := _is_element_matched(architecture, qelem.re_architectures)) is False): continue if (qelem.simulations - and (matched := _is_element_matched(simulation, qelem.simulations)) is False): + and (matched := _is_element_matched(simulation, qelem.re_simulations)) is False): continue if matched: @@ -118,9 +128,9 @@ def get_matched_quarantine(self, return None -def _is_element_matched(element: str, list_of_elements: list) -> bool: +def _is_element_matched(element: str, list_of_elements: list[re.Pattern]) -> bool: """Return True if given element is matching to any of elements from the list""" for pattern in list_of_elements: - if re.fullmatch(pattern, element): + if pattern.fullmatch(element): return True return False diff --git a/scripts/tests/twister/test_quarantine.py b/scripts/tests/twister/test_quarantine.py index 8988d7978ca..1e4b7d2f405 100644 --- a/scripts/tests/twister/test_quarantine.py +++ b/scripts/tests/twister/test_quarantine.py @@ -104,10 +104,9 @@ def test_quarantinedata_post_init(): quarantine_element = QuarantineElement( platforms=['dummy platform'], - architectures=[] + architectures=[], + simulations=['dummy simulation', 'another simulation'] ) - quarantine_element.scenarios = [] - quarantine_element.simulations = ['dummy simulation', 'another simulation'] quarantine_data_qlist = [quarantine_element, quarantine_element_dict] From 6c2da47e4c918dca6b9a78d0af0de04d857c69f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rait=20R=C3=A4=C3=A4k?= Date: Wed, 4 Oct 2023 20:29:11 +1100 Subject: [PATCH 1634/4498] bluetooth: conn: Fix forced pairing request handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BT_SECURITY_FORCE_PAIR option gets overridden when CONFIG_BT_SMP_SC_ONLY or CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY is defined. Cache the bit value before overrides. Add explicit forced pair handling to existing security level check. Functionality did not change as this was done implicitly due to integer comparison for enums. Add extra clarification to the method doc. Signed-off-by: Rait Rääk --- include/zephyr/bluetooth/conn.h | 3 +++ subsys/bluetooth/host/conn.c | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 9fd78b6a89b..09b8321d685 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -813,6 +813,9 @@ int bt_le_set_auto_conn(const bt_addr_le_t *addr, * @note When @kconfig{CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY} is enabled then the * security level will always be level 3. * + * @note When @ref BT_SECURITY_FORCE_PAIR within @p sec is enabled then the pairing + * procedure will always be initiated. + * * @param conn Connection object. * @param sec Requested security level. * diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 7670834d3e2..cc0e8bc6b33 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2285,12 +2285,16 @@ static int start_security(struct bt_conn *conn) int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec) { + bool force_pair; int err; if (conn->state != BT_CONN_CONNECTED) { return -ENOTCONN; } + force_pair = sec & BT_SECURITY_FORCE_PAIR; + sec &= ~BT_SECURITY_FORCE_PAIR; + if (IS_ENABLED(CONFIG_BT_SMP_SC_ONLY)) { sec = BT_SECURITY_L4; } @@ -2300,13 +2304,12 @@ int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec) } /* nothing to do */ - if (conn->sec_level >= sec || conn->required_sec_level >= sec) { + if (!force_pair && (conn->sec_level >= sec || conn->required_sec_level >= sec)) { return 0; } - atomic_set_bit_to(conn->flags, BT_CONN_FORCE_PAIR, - sec & BT_SECURITY_FORCE_PAIR); - conn->required_sec_level = sec & ~BT_SECURITY_FORCE_PAIR; + atomic_set_bit_to(conn->flags, BT_CONN_FORCE_PAIR, force_pair); + conn->required_sec_level = sec; err = start_security(conn); From 1234b4919d33e90f6dfc86c77edcc5c65ebbf1e3 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Tue, 3 Oct 2023 16:39:33 +0100 Subject: [PATCH 1635/4498] Revert "boards/arc/qemu_arc: Disable use of branch delay slots" This reverts commit 8084ea55b787790e656b78d94bc2433bb47d8deb. The rootcause is fixed in the ARC QEMU which is in SDK 0.16.3. As we've updated SDK in upstream CI we can revert this workaround. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/qemu_arc/qemu_arc_em_defconfig | 1 - boards/arc/qemu_arc/qemu_arc_hs5x_defconfig | 1 - boards/arc/qemu_arc/qemu_arc_hs6x_defconfig | 1 - boards/arc/qemu_arc/qemu_arc_hs_defconfig | 1 - boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig | 1 - 5 files changed, 5 deletions(-) diff --git a/boards/arc/qemu_arc/qemu_arc_em_defconfig b/boards/arc/qemu_arc/qemu_arc_em_defconfig index b713b193bc0..0d6f4052e64 100644 --- a/boards/arc/qemu_arc/qemu_arc_em_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_em_defconfig @@ -10,4 +10,3 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y -CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig b/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig index 9459d6f70bb..f8e50bcf3f8 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs5x_defconfig @@ -10,4 +10,3 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 -CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig b/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig index 3d2804c33f7..8ab0d4ae0f0 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs6x_defconfig @@ -10,4 +10,3 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 -CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs_defconfig b/boards/arc/qemu_arc/qemu_arc_hs_defconfig index 5ff910926f8..911702aab21 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs_defconfig @@ -10,4 +10,3 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y -CONFIG_COMPILER_OPT="-fno-delayed-branch" diff --git a/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig b/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig index b072c7692b6..bec83e7c5ae 100644 --- a/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig +++ b/boards/arc/qemu_arc/qemu_arc_hs_xip_defconfig @@ -10,4 +10,3 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_QEMU_ICOUNT_SHIFT=6 CONFIG_ARC_MPU_ENABLE=y -CONFIG_COMPILER_OPT="-fno-delayed-branch" From 93beac7a69c1da8a5910809ba0da7b1172e830fe Mon Sep 17 00:00:00 2001 From: Nicola Guerrera Date: Tue, 3 Oct 2023 21:02:47 +0200 Subject: [PATCH 1636/4498] docs: update sha256 for SDK Update sha256.sum urls to 0.16.3 in index.rst and installation_linux.rst. Signed-off-by: Nicola Guerrera --- doc/develop/getting_started/index.rst | 4 ++-- doc/develop/getting_started/installation_linux.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 636eec29788..38320e541f6 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -503,7 +503,7 @@ that are used to emulate, flash and debug Zephyr applications. cd ~ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM Linux SDK. @@ -560,7 +560,7 @@ that are used to emulate, flash and debug Zephyr applications. cd ~ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. diff --git a/doc/develop/getting_started/installation_linux.rst b/doc/develop/getting_started/installation_linux.rst index a7b71317fed..d9598f4170d 100644 --- a/doc/develop/getting_started/installation_linux.rst +++ b/doc/develop/getting_started/installation_linux.rst @@ -233,9 +233,9 @@ Follow these steps to install the Zephyr SDK: .. code-block:: bash wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing - You can change ``0.16.1`` to another version if needed; the `Zephyr SDK + You can change ``0.16.3`` to another version if needed; the `Zephyr SDK Releases`_ page contains all available SDK releases. If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace From dbdbc64d94d017a2c3077d7836804bed56e5d493 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 3 Oct 2023 17:33:36 +0000 Subject: [PATCH 1637/4498] tests: drivers: regulator: clean up testcase.yaml for voltage test Clean up testcase definition for voltage test, by moving the LPCXpresso55s36 board overlay file into the boards/ folder of the test, as well as adding a fixture to the testcase so that it will only be executed on properly configured boards. Fixes #62884 Signed-off-by: Daniel DeGrasse --- .../voltage/{ => boards}/lpcxpresso55s36.overlay | 0 tests/drivers/regulator/voltage/testcase.yaml | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) rename tests/drivers/regulator/voltage/{ => boards}/lpcxpresso55s36.overlay (100%) diff --git a/tests/drivers/regulator/voltage/lpcxpresso55s36.overlay b/tests/drivers/regulator/voltage/boards/lpcxpresso55s36.overlay similarity index 100% rename from tests/drivers/regulator/voltage/lpcxpresso55s36.overlay rename to tests/drivers/regulator/voltage/boards/lpcxpresso55s36.overlay diff --git a/tests/drivers/regulator/voltage/testcase.yaml b/tests/drivers/regulator/voltage/testcase.yaml index 71c94e59c82..04b83333079 100644 --- a/tests/drivers/regulator/voltage/testcase.yaml +++ b/tests/drivers/regulator/voltage/testcase.yaml @@ -15,8 +15,12 @@ tests: - SHIELD=npm6001_ek harness_config: fixture: npm6001_ek_to_adc - drivers.regulator.voltage.mimxrt685_evk_cm33: - platform_allow: mimxrt685_evk_cm33 + drivers.regulator.voltage.nxp: + platform_allow: + - mimxrt685_evk_cm33 + - lpcxpresso55s36 + harness_config: + fixture: gpio_loopback drivers.regulator.voltage.rpi_pico_vreg: platform_allow: rpi_pico harness_config: From c6cecef12058b96ce9fe62b549e407c6b7c20949 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 3 Oct 2023 23:42:09 +0200 Subject: [PATCH 1638/4498] Bluetooth: Controll: Fix dead code in ll_setup_iso_path In ll_setup_iso_path cis is only ever set if CONFIG_BT_CTLR_CONN_ISO is enabled, and similarly adv_stream is only ever set if CONFIG_BT_CTLR_ADV_ISO is enabled. The two assignments were reported as dead code by Coverity due to this, which has been fixed by guarding the code with the respective Kconfigs. Signed-off-by: Emil Gydesen --- subsys/bluetooth/controller/ll_sw/ull_iso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index 70d018e7e0c..b21a9d20721 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -491,11 +491,11 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, pdu_release, &source_handle); if (!err) { - if (cis) { + if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && cis != NULL) { cis->hdr.datapath_in = dp; } - if (adv_stream) { + if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO) && adv_stream != NULL) { adv_stream->dp = dp; } From 7a1b194a97e697578e459535752e6c3b1a75bdd9 Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Wed, 4 Oct 2023 11:58:46 +0200 Subject: [PATCH 1639/4498] bluetooth: host: smp: Add runtime check for central-specific path Added run-time BT_CENTRAL role check for the path that was central specific and did not have such check. When multi-role BT device tried to pair without bonding (peripheral role) while already previously bonded with the same device on another Bluetooth identity, pairing failed. It executed central-specific code, which should not be executed in case when the device acts as peripheral (as it is even opt-out from code when CONFIG_BT_CENTRAL is not enabled). Signed-off-by: Mateusz Kapala --- subsys/bluetooth/host/smp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index cccf95adf8e..2c110dc43a3 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -4706,6 +4706,7 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan, */ if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY) && + conn->role == BT_HCI_ROLE_CENTRAL && !(smp->remote_dist & BT_SMP_DIST_ID_KEY)) { uint8_t smp_err; From 3c0c6343407106e6ff4705a464bc93912ca37929 Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Wed, 4 Oct 2023 11:59:06 +0200 Subject: [PATCH 1640/4498] bluetooth: tests: Improve bondable_per_connection bsim test Added fail on pairing_failed callback for both central and peripheral. Added pairing status checks in peripheral. It has been done to test the case when multi-role BT device tried to pair without bonding (peripheral role) while already previously bonded with the same device on another Bluetooth identity as it seems that there was an issue with it previously. Signed-off-by: Mateusz Kapala --- .../host/security/bond_per_connection/src/bs_bt_utils.c | 6 ++++++ .../host/security/bond_per_connection/src/peripheral.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c index 1523e10d8a5..94b27a50b33 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c @@ -88,6 +88,11 @@ DEFINE_FLAG(flag_pairing_complete); DEFINE_FLAG(flag_bonded); DEFINE_FLAG(flag_not_bonded); +static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) +{ + FAIL("Pairing failed (unexpected): reason %u\n", reason); +} + static void pairing_complete(struct bt_conn *conn, bool bonded) { SET_FLAG(flag_pairing_complete); @@ -100,6 +105,7 @@ static void pairing_complete(struct bt_conn *conn, bool bonded) } static struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { + .pairing_failed = pairing_failed, .pairing_complete = pairing_complete, }; diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c index 9b368cce26e..04fc3cdd8f2 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c @@ -33,6 +33,8 @@ void peripheral(void) wait_connected(); /* Central should bond here and trigger a disconnect. */ wait_disconnected(); + TAKE_FLAG(flag_pairing_complete); + TAKE_FLAG(flag_bonded); unpair(id_a); clear_g_conn(); @@ -43,6 +45,8 @@ void peripheral(void) wait_connected(); /* Central should bond here and trigger a disconnect. */ wait_disconnected(); + TAKE_FLAG(flag_pairing_complete); + TAKE_FLAG(flag_bonded); clear_g_conn(); printk("== Bonding id b - bond per-connection false ==\n"); @@ -51,6 +55,8 @@ void peripheral(void) wait_connected(); /* Central should pair without bond here and trigger a disconnect. */ wait_disconnected(); + TAKE_FLAG(flag_pairing_complete); + TAKE_FLAG(flag_not_bonded); PASS("PASS\n"); } From df156d7fafd00ebe1afb97f0ae045f919fb91bfe Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 4 Oct 2023 14:32:14 +0200 Subject: [PATCH 1641/4498] dts: bindings: can: reword the CAN controller bindings descriptions Reword the descriptions for the bus-speed, sample-point, bus-speed-data, and sample-point-data CAN controller devicetree properties. Signed-off-by: Henrik Brix Andersen --- dts/bindings/can/can-controller.yaml | 18 +++++++++++------- dts/bindings/can/can-fd-controller.yaml | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/dts/bindings/can/can-controller.yaml b/dts/bindings/can/can-controller.yaml index a0e31045c70..b2502dce1c3 100644 --- a/dts/bindings/can/can-controller.yaml +++ b/dts/bindings/can/can-controller.yaml @@ -6,7 +6,17 @@ properties: bus-speed: type: int required: true - description: bus speed in Baud/s + description: | + Initial bitrate in bit/s. + sample-point: + type: int + description: | + Initial sample point in per mille (e.g. 875 equals 87.5%). + + This property is required unless the timing is specified using time quanta based properties + (`sjw`, `prop-seg`, `phase-seg1`, and `phase-seg2`). + + If this property is present, the time quanta based timing properties are ignored. sjw: type: int deprecated: true @@ -37,12 +47,6 @@ properties: description: | Initial time quanta of phase buffer 2 segment (ISO 11898-1). Deprecated in favor of setting advanced timing parameters from the application. - sample-point: - type: int - description: > - Sample point in permille. - This param is required if segments are not given. - If the sample point is given, the segments are ignored. phys: type: phandle description: | diff --git a/dts/bindings/can/can-fd-controller.yaml b/dts/bindings/can/can-fd-controller.yaml index e6842403ac6..beb9da9f736 100644 --- a/dts/bindings/can/can-fd-controller.yaml +++ b/dts/bindings/can/can-fd-controller.yaml @@ -6,7 +6,17 @@ properties: bus-speed-data: type: int required: true - description: data phase bus speed in Baud/s + description: | + Initial data phase bitrate in bit/s. + sample-point-data: + type: int + description: | + Initial data phase sample point in per mille (e.g. 875 equals 87.5%). + + This property is required unless the timing is specified using time quanta based properties + (`sjw-data`, `prop-seg-data`, `phase-seg1-data`, and `phase-seg2-data`). + + If this property is present, the time quanta based timing properties are ignored. sjw-data: type: int deprecated: true @@ -37,12 +47,6 @@ properties: description: | Initial time quanta of phase buffer 2 segment for the data phase (ISO11898-1:2015). Deprecated in favor of setting advanced timing parameters from the application. - sample-point-data: - type: int - description: > - Sample point in permille for the data phase. - This param is required if segments are not given. - If the sample point is given, the segments are ignored. tx-delay-comp-offset: type: int default: 0 From ce15b5af0cf91bdcf8e73ed4aa2ebca3a71a76da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 4 Oct 2023 12:26:38 +0200 Subject: [PATCH 1642/4498] doc: gsg: remove unused numbered steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There used to be a dedicated style to number headings in a .rst document but there is currently no actual stylesheet for it, and the added value is somewhat limited: dropping the associated directive from the GSG. Signed-off-by: Benjamin Cabé --- doc/develop/getting_started/index.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 38320e541f6..59f41a503d6 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -13,8 +13,6 @@ Follow this guide to: .. _host_setup: -.. rst-class:: numbered-step - Select and Update OS ******************** @@ -46,8 +44,6 @@ Click the operating system you are using. .. _install-required-tools: -.. rst-class:: numbered-step - Install dependencies ******************** @@ -178,8 +174,6 @@ The current minimum required version for the main dependencies are: .. _install_py_requirements: .. _gs_python_deps: -.. rst-class:: numbered-step - Get Zephyr and install Python dependencies ****************************************** @@ -476,8 +470,6 @@ additional Python dependencies. pip3 install -r %HOMEPATH%\zephyrproject\zephyr\scripts\requirements.txt -.. rst-class:: numbered-step - Install Zephyr SDK ****************** @@ -643,8 +635,6 @@ that are used to emulate, flash and debug Zephyr applications. .. _getting_started_run_sample: -.. rst-class:: numbered-step - Build the Blinky Sample *********************** @@ -688,8 +678,6 @@ users. Users may also use the ``-p auto`` option, which will use heuristics to determine if a pristine build is required, such as when building another sample. -.. rst-class:: numbered-step - Flash the Sample **************** From f7f8acaf035b7c1c3a783326f03a2f050d0ab14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 4 Oct 2023 12:28:59 +0200 Subject: [PATCH 1643/4498] doc: remove instructions regarding numbered steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Numbered steps" were dropped a long time ago in a previous revamp of the stylesheet, so dropping instructions related to them in the documentation guidelines. Also remove unecessary mention to "how to build the doc" as it's already mentioned as a note at the top of the document. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/guidelines.rst | 26 --------------------- 1 file changed, 26 deletions(-) diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index fbbc6feb00c..20ca94e2948 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -580,29 +580,3 @@ in the Zephyr setup. Within a tab, you can have most any content *other than a heading* (code-blocks, ordered and unordered lists, pictures, paragraphs, and such). You can read more about sphinx-tabs from the link above. - -Instruction Steps -***************** - -Also introduced in the :ref:`getting_started` is a style that makes it -easy to create tutorial guides with clearly identified steps. Add -the ``.. rst-class:: numbered-step`` directive immediately before a -second-level heading (by project convention, a heading underlined with -asterisks ``******``, and it will be displayed as a numbered step, -sequentially numbered within the document. For example:: - - .. rst-class:: numbered-step - - Put your right hand in - ********************** - -.. rst-class:: numbered-step - -Put your right hand in -********************** - -See the :zephyr_raw:`doc/develop/getting_started/index.rst` source file and -compare with the :ref:`getting_started` to see a full example. As implemented, -only one set of numbered steps is intended per document. - -For instructions on building the documentation, see :ref:`zephyr_doc`. From 099d67902edb4a5c82253cb93c64c12fdf7b0bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20St=C3=B6tter?= Date: Sun, 1 Oct 2023 11:02:15 +0200 Subject: [PATCH 1644/4498] bluetooth: audio: add support for cpp in bap.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Small patch adding extern "C" Signed-off-by: Moritz Stötter --- include/zephyr/bluetooth/audio/bap.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 52a9c0d477d..db5737f2152 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -20,6 +20,12 @@ #include #include + +#ifdef __cplusplus +extern "C" { +#endif + + #if defined(CONFIG_BT_BAP_SCAN_DELEGATOR) #define BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN #define BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS @@ -2079,4 +2085,8 @@ int bt_bap_broadcast_assistant_read_recv_state(struct bt_conn *conn, /** @} */ /* end of bt_bap */ +#ifdef __cplusplus +} +#endif + #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BAP_ */ From 8b78eecfd6b99d69b7092b52cbee944a7c9f2f1d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 2 Oct 2023 11:48:38 +0200 Subject: [PATCH 1645/4498] boards posix: Fix in POSIX arch common description Minor updates as now we have also native_sim, so we should not only refer to native_posix. Signed-off-by: Alberto Escolar Piedras --- boards/posix/doc/arch_soc.rst | 6 +++--- boards/posix/doc/layering.svg | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/posix/doc/arch_soc.rst b/boards/posix/doc/arch_soc.rst index 3cd72e080e7..cac21706293 100644 --- a/boards/posix/doc/arch_soc.rst +++ b/boards/posix/doc/arch_soc.rst @@ -33,9 +33,9 @@ target hardware in the early phases of development. Types of POSIX arch based boards ================================ -Today there are two types of POSIX boards: The :ref:`native_posix` -board and the :ref:`bsim boards`. -While they share the main objectives and principles, the first is intended as +Today there are two types of POSIX boards: The native boards, :ref:`native_posix` +and :ref:`native_sim`, and the :ref:`bsim boards`. +While they share the main objectives and principles, the first are intended as a HW agnostic test platform which in some cases utilizes the host OS peripherals, while the second intend to simulate a particular HW platform, with focus on their radio (e.g. BT LE) and utilize the `BabbleSim`_ physical layer diff --git a/boards/posix/doc/layering.svg b/boards/posix/doc/layering.svg index af432d2894e..c85357d0132 100644 --- a/boards/posix/doc/layering.svg +++ b/boards/posix/doc/layering.svg @@ -129,11 +129,11 @@ x="42.81" dy="1.2em" class="st4">layering Sheet.14 - Native_posix & _bsim boards Zephyr layering + native_posix/sim & _bsim boards Zephyr layering - Native_posix native_posix/sim & _bsim boards Zephyr layering From 84f76e42daa507601329033bba68fd7ed6902a52 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 2 Oct 2023 15:47:02 +0200 Subject: [PATCH 1646/4498] boards nrf_bsim docs: Add documentation for nrf5340bsim Add documentation for the newly introduced nrf5340bsim boards. And rename the nrf52bsim documentation file as it is not the only one anymore. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_sim/doc/index.rst | 2 + .../doc/{index.rst => nrf52_bsim.rst} | 0 boards/posix/nrf_bsim/doc/nrf5340bsim.rst | 124 ++++++++++++++++++ 3 files changed, 126 insertions(+) rename boards/posix/nrf_bsim/doc/{index.rst => nrf52_bsim.rst} (100%) create mode 100644 boards/posix/nrf_bsim/doc/nrf5340bsim.rst diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index ea521b0f5e2..5286de1b425 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -65,6 +65,8 @@ The 64 bit version, ``native_sim_64``, compiles your code targeting the LP64 ABI (x86-64 in x86 systems), where pointers and longs are 64 bits. You can use this target if you cannot compile or run 32 bit binaries. +.. _native_sim_Clib_choice: + C library choice **************** diff --git a/boards/posix/nrf_bsim/doc/index.rst b/boards/posix/nrf_bsim/doc/nrf52_bsim.rst similarity index 100% rename from boards/posix/nrf_bsim/doc/index.rst rename to boards/posix/nrf_bsim/doc/nrf52_bsim.rst diff --git a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst new file mode 100644 index 00000000000..5364cd0a307 --- /dev/null +++ b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst @@ -0,0 +1,124 @@ +.. _nrf5340bsim: + +NRF5340 simulated boards (BabbleSim) +#################################### + +.. contents:: + :depth: 1 + :backlinks: entry + :local: + + +Overview +******** + +To allow simulating nrf5340 SOCs two Zephyr target boards are provided: the +``nrf5340bsim_nrf5340_cpuapp`` and ``nrf5340bsim_nrf5340_cpunet``. + +These use `BabbleSim`_ to simulate the radio activity, and the +:ref:`POSIX architecture` and the `native simulator`_ to +run applications natively on the development system. This has the benefit of +providing native code execution performance and easy debugging using +native tools, but inherits :ref:`its limitations `. + +Just like for the nrf5340dk targets, +the nrf5340bsim_nrf5340_cpuapp build target provides support for the application core, +and the nrf5340bsim_nrf5340_cpunet build target provides support for the network +core on the simulated nRF5340 SOC. + +These boards include models of some of the nRF5340 SOC peripherals: + +* Radio +* Timers +* AAR (Accelerated Address Resolver) +* AES CCM & AES ECB encryption HW +* CLOCK (Clock control) +* DPPI (Distributed Programmable Peripheral Interconnect) +* EGU (Event Generator Unit) +* FICR (Factory Information Configuration Registers) +* NVMC (Non-Volatile Memory Controller / Flash) +* RNG (Random Number Generator) +* RTC (Real Time Counter) +* TEMP (Temperature sensor) +* UICR (User Information Configuration Registers) + +and will use the same drivers as the nrf5340dk targets for these. +For more information on what is modelled to which level of detail, +check the `HW models implementation status`_. + +.. note:: + + The IPC and MUTEX peripherals are not yet present in these models. Therefore communication + between the cores using Zephyr's IPC driver is not yet possible. + +Note that unlike a real nrf5340 device, the nrf5340bsim boards have unlimited RAM and flash for +code. + +.. _BabbleSim: + https://BabbleSim.github.io + +.. _native simulator: + https://github.com/BabbleSim/native_simulator/blob/main/docs/README.md + +.. _HW models implementation status: + https://github.com/BabbleSim/ext_nRF_hw_models/blob/main/docs/README_impl_status.md + + +Building for, and using these boards +************************************ + +If you are interested in developing on only one of the MCUs in this SOC, you +can use the corresponding simulated target, nrf5340bsim_nrf5340_cpuapp or nrf5340bsim_nrf5340_cpunet +following the instructions from the :ref:`nrf52_bsim board `. +Simply change the board/target appropriately when building. + + +.. note:: + + Unlike in real HW, the net core MCU is set-up to automatically boot at start, to facilitate + developing without an image in the application core. You can control + this with either :kconfig:option:`CONFIG_NATIVE_SIMULATOR_AUTOSTART_MCU`, or the command line + option ``--cpu1_autostart``. + + If an MCU is booted without any image, it will automatically set itself to sleep. + + +Assembling both MCUs images into a single executable +**************************************************** + +By default, when you build targeting either nrf5340bsim_nrf5340_cpuapp or +nrf5340bsim_nrf5340_cpunet you will end up with a library (``zephyr/zephyr.elf``) that corresponds +to that MCU code image, and an executable (``zephyr/zephyr.exe``) that includes the native simulator +runner, SOC HW models, that image, and an empty image for the other MCU. + +If you want to assemble an executable including a previously built image for the other MCU, +built with either Zephyr's build system or another native simulator compatible build system, +you can provide that image to the Zephyr build of the second image using +:kconfig:option:`CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS`. + + +.. note:: + + These libraries/images are **not** embedded images. You cannot use them for embedded devices, + and cannot use an embedded image to assemble a native executable. + +.. note:: + + OpenAMP is not yet supported in these boards. + +TrustZone, TF-M and other security considerations +************************************************* + +ARM's TrustZone is not modelled in these boards. This means that: + +* There is no differentiation between secure and non secure execution states or bus accesses. +* All RAM, flash and peripherals are in principle accessible from all SW. Peripherals with their + own interconnect master ports can, in principle, access any other peripheral or RAM area. +* There is no nrf5340bsim_nrf5340_cpuapp_ns board/build target, or posibility of mixing secure + and non-secure images. +* Currently there is no model of the SPU, and therefore neither flash, RAM areas or peripherals + can be labelled as restricted for secure or non secure access. +* TF-M cannot be used. + +Note that the ARM cryptocell-312 peripheral is not modelled. The mbedTLS library can still be used +but with a SW crypto backend instead of the cryptocell HW acceleration. From d12fac706d3f61257551c1eb0927a74650422291 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 2 Oct 2023 15:48:02 +0200 Subject: [PATCH 1647/4498] boards nrf_bsim docs: Update common documentation Update the documentation describing the bsim boards overall to match the current reality. Signed-off-by: Alberto Escolar Piedras --- boards/posix/doc/bsim_boards_design.rst | 47 +++++++++++++++++-------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/boards/posix/doc/bsim_boards_design.rst b/boards/posix/doc/bsim_boards_design.rst index 3c12f0e6acb..f69a27a5761 100644 --- a/boards/posix/doc/bsim_boards_design.rst +++ b/boards/posix/doc/bsim_boards_design.rst @@ -4,12 +4,15 @@ Bsim boards ########### This page covers the design, architecture and rationale, of the -:ref:`nrf52_bsim` board and other similar bsim boards. -Particular details on the nRF52 simulation board, including how to use it, -can be found in that :ref:`board documentation`. +:ref:`nrf52_bsim`, :ref:`nrf5340bsim` and other similar bsim boards. +Particular details on the nRF52 and nRF5340 simulation boards, including how to use them, +can be found in their respective documentation. These boards are postfixed with `_bsim` as they use BabbleSim_ (shortened bsim). +These boards use the `native simulator`_ and the :ref:`POSIX architecture` to build +and execute the embedded code natively on Linux. + .. contents:: :depth: 2 :backlinks: entry @@ -24,10 +27,20 @@ These boards are postfixed with `_bsim` as they use BabbleSim_ .. _Architecture of HW models used for FW development and testing: https://babblesim.github.io/arch_hw_models.html +.. _native simulator: + https://github.com/BabbleSim/native_simulator/blob/main/docs/README.md + +.. _native simulator design documentation: + https://github.com/BabbleSim/native_simulator/blob/main/docs/Design.md + +.. _nRF HW models design documentation: + https://github.com/BabbleSim/ext_nRF_hw_models/blob/main/docs/README_HW_models.md + + Overall objective ***************** -Bsim boards main purpose is to be test-benches for +The main purpose of these bsim boards is to be test-benches for integration testing of embedded code on workstation/simulation. Integration testing in the sense that the code under test will, at the very least, run with the Zephyr RTOS just like for any other @@ -125,10 +138,11 @@ The basic architecture layering of these boards is as follows: Note that in a normal Zephyr target interrupt handling and a custom busy wait would be provided by the SOC layer, but abusing Zephyr's layering, and for the soc_inf layer to be generic, these were delegated to the board. - The board layer also provides the :c:func:`main` entry point for the linux - program, command line argument handling, the overall time scheduling of - the simulated device, and other test specific functionality like bs_tests - hooks, trace control, etc. + The board layer provides other test specific + functionality like bs_tests hooks, trace control, etc, and + by means of the native simulator, provides the :c:func:`main` entry point for the linux + program, command line argument handling, and the overall time scheduling of + the simulated device. Note that the POSIX arch and soc_inf expect a set of APIs being provided by the board. This includes the busy wait API, a basic tracing API, the interrupt controller and interrupt handling APIs, :c:func:`posix_exit`, @@ -156,12 +170,15 @@ Threading and overall scheduling of CPU and HW models The threading description, as well as the general SOC and board architecture introduced in -:ref:`POSIX arch architecture` -apply to the bsim boards. +:ref:`POSIX arch architecture` and on the +`native simulator design documentation`_ apply to the bsim boards. Moreover in `Architecture of HW models used for FW development and testing`_ -more details on the HW models and their scheduling are provided. +a general introduction to the babblesim HW models and their scheduling are provided. + +In case of the nRF bsim boards, more information can be found in the +`nRF HW models design documentation`_. Time and the time_machine ========================= @@ -178,7 +195,7 @@ and the simulation results will not be affected in any way by the load of the simulation host or by the process execution being "paused" in a debugger or similar. -The time_machine component provides the overall HW event time loop +The native simulator HW scheduler provides the overall HW event time loop required by the HW models, which consists of a very simple "search for next event", "advance time to next event and execute it" loop, together with an API for components that use it to inform about their events @@ -204,7 +221,7 @@ below represents this communication: Communication between a Zephyr device and other simulated devices Test code may also communicate with other devices' test code using the bsim -backchannels. These provide a direct, reliable pipe between devices' test code +backchannels. These provide a direct, reliable pipe between devices which test code can use to exchange data. @@ -289,8 +306,8 @@ arguments: - The HW models command line arguments: The HW models will expose which arguments they need to have processed, but the bsim board as actual integrating program ensures they are handled. -- Test (bs_tests) control: To select a test, print which are available, and - pass arguments to the tests themselves. +- Test (bs_tests) control: To select a test for each embedded CPU, + print which are available, and pass arguments to the tests themselves. Command line argument parsing is handled by using the bs_cmd_line component from Babblesim's base/libUtilv1 library. And basic arguments definitions that From e851725e62e1f302e437b1bd59cf9ea9e36f40c9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 2 Oct 2023 15:38:24 +0200 Subject: [PATCH 1648/4498] boards nrf52_bsim docs: Minor updates Minor updates both to make it more consistent with the nrf53bsim documentation, and include more links and a small section about the C library choice. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/doc/nrf52_bsim.rst | 52 +++++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/boards/posix/nrf_bsim/doc/nrf52_bsim.rst b/boards/posix/nrf_bsim/doc/nrf52_bsim.rst index a954217e21a..f8b7cad6628 100644 --- a/boards/posix/nrf_bsim/doc/nrf52_bsim.rst +++ b/boards/posix/nrf_bsim/doc/nrf52_bsim.rst @@ -12,38 +12,51 @@ NRF52 simulated board (BabbleSim) Overview ******** -This is a :ref:`POSIX architecture` -based simulated NRF52 board which uses `BabbleSim`_ to simulate the radio -activity. -This board models some of the NRF52 SOC peripherals: +To allow simulating a nRF52833 SOC a Zephyr target boards is provided: the +nrf52_bsim. + +This uses `BabbleSim`_ to simulate the radio activity, and the +:ref:`POSIX architecture` and the `native simulator`_ to +run applications natively on the development system. This has the benefit of +providing native code execution performance and easy debugging using +native tools, but inherits :ref:`its limitations `. + +This board includes models of some of the nRF52 SOC peripherals: * Radio * Timers -* RTC (Real Time Counter) -* RNG (Random Number Generator) -* AES CCM & AES ECB encryption HW * AAR (Accelerated Address Resolver) +* AES CCM & AES ECB encryption HW * CLOCK (Clock control) -* PPI (Programmable Peripheral Interconnect) * EGU (Event Generator Unit) +* FICR (Factory Information Configuration Registers) * GPIO & GPIOTE +* NVMC (Non-Volatile Memory Controller / Flash) +* PPI (Programmable Peripheral Interconnect) +* RNG (Random Number Generator) +* RTC (Real Time Counter) * TEMP (Temperature sensor) * UICR (User Information Configuration Registers) -* FICR (Factory Information Configuration Registers) -* NVMC (Non-Volatile Memory Controller) -The nrf52_bsim board definition uses the POSIX architecture and the native simulator to -run applications natively on the development system, this has the benefit of -providing native code execution performance and easy debugging using -native tools, but inherits :ref:`its limitations `. +and will use the same drivers as the nrf52 dk targets for these. +For more information on what is modelled to which level of detail, +check the `HW models implementation status`_. + +Note that unlike a real nrf52 device, the nrf52_bsim has unlimited RAM and flash for code. .. _BabbleSim: https://BabbleSim.github.io +.. _native simulator: + https://github.com/BabbleSim/native_simulator/blob/main/docs/README.md + +.. _HW models implementation status: + https://github.com/BabbleSim/ext_nRF_hw_models/blob/main/docs/README_impl_status.md + .. _nrf52bsim_build_and_run: Building and running -********************** +******************** This board requires the host 32 bit C library. See :ref:`POSIX Arch dependencies`. @@ -157,6 +170,15 @@ Run them with ``-help`` for more information. You can find more information about how to run BabbleSim simulations in `this BabbleSim example `_. + +C library choice +**************** + +These nRF bsim boards use the `native simulator`_ at their core, so you can chose with which +C library you want to build your embedded code. +Check the :ref:`native simulator C library choice section` for more info. + + Debugging, coverage and address sanitizer ***************************************** From e2d7ba093e9115c6c94e225fc820cdfcc1215550 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Tue, 3 Oct 2023 15:48:18 +0200 Subject: [PATCH 1649/4498] boards: doc: Add serial programming for mimx8mq_evk Extend the programming section with serial programming using `screen` and `xmodem`. Signed-off-by: Jeppe Odgaard --- boards/arm/mimx8mq_evk/doc/index.rst | 39 +++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/boards/arm/mimx8mq_evk/doc/index.rst b/boards/arm/mimx8mq_evk/doc/index.rst index 892c6c6422c..4cdc9233b4d 100644 --- a/boards/arm/mimx8mq_evk/doc/index.rst +++ b/boards/arm/mimx8mq_evk/doc/index.rst @@ -138,9 +138,13 @@ The available configurations are: - &ocram_sys - &ocram_s_sys -Load and run Zephyr on M4 from A53 using u-boot by copying the compiled -``zephyr.bin`` to the first FAT partition of the SD card and plug the SD -card into the board. Power it up and stop the u-boot execution at prompt. +Load and run Zephyr on M4 from A53 using u-boot. + +From an SD card: + +Copy the compiled ``zephyr.bin`` to the first FAT partition of the +SD card and plug the SD card into the board. Power it up and stop the u-boot +execution at prompt. Load the M4 binary onto the desired memory and start its execution using: @@ -150,6 +154,35 @@ Load the M4 binary onto the desired memory and start its execution using: cp.b 0x40480000 0x7e0000 0x8000 bootaux 0x7e0000 +From serial: + +This procedure requires `screen` and `lrzsz` to be installed. + +Start ``screen``, power up the board, and stop the u-boot execution at prompt: + +.. code-block:: console + + screen 115200 + +Start ``loadx`` with offset ``7e0000``: + +.. code-block:: console + + loadx 7e0000 115200 + +Send the compiled ``zephyr.bin`` with ``sx`` by pressing Ctrl-a followed by ':' +and write: + +.. code-block:: console + + exec !! sx + +Start execution: + +.. code-block:: console + + bootaux 0x7e0000 + Debugging ========= From 591c1bb867d189ea917fcd85479cac76ff768da1 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 10:37:01 +0000 Subject: [PATCH 1650/4498] bindings: move cst816s and cap1203 to input These two have been converted from kscan to input already, move the bindings over to match the change. Signed-off-by: Fabio Baltieri --- dts/bindings/{kscan => input}/hynitron,cst816s.yaml | 0 dts/bindings/{kscan => input}/microchip,cap1203.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename dts/bindings/{kscan => input}/hynitron,cst816s.yaml (100%) rename dts/bindings/{kscan => input}/microchip,cap1203.yaml (100%) diff --git a/dts/bindings/kscan/hynitron,cst816s.yaml b/dts/bindings/input/hynitron,cst816s.yaml similarity index 100% rename from dts/bindings/kscan/hynitron,cst816s.yaml rename to dts/bindings/input/hynitron,cst816s.yaml diff --git a/dts/bindings/kscan/microchip,cap1203.yaml b/dts/bindings/input/microchip,cap1203.yaml similarity index 100% rename from dts/bindings/kscan/microchip,cap1203.yaml rename to dts/bindings/input/microchip,cap1203.yaml From 6f0a5961e300034f438449e64cbe753fad089c66 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 22 Sep 2023 19:00:08 +0100 Subject: [PATCH 1651/4498] drivers: i2c: i2c_nrfx_twim: fail gracefully on dma max size Different nRF52 devices have different maximum TWI DMA transfer size, and it's easy to hit the limit with i2c displays on nrf52832 (8 bit) and nrf52810 (10 bit). Currently neither the driver or the hal validate the limit, leading to random NACK errors when trying to transfer more data. Add a check on the driver to fail gracefully when going over the limit. Signed-off-by: Fabio Baltieri --- drivers/i2c/i2c_nrfx_twim.c | 11 +++++++++++ dts/arm/nordic/nrf51822.dtsi | 2 ++ dts/arm/nordic/nrf52805.dtsi | 1 + dts/arm/nordic/nrf52810.dtsi | 1 + dts/arm/nordic/nrf52811.dtsi | 1 + dts/arm/nordic/nrf52820.dtsi | 2 ++ dts/arm/nordic/nrf52832.dtsi | 2 ++ dts/arm/nordic/nrf52833.dtsi | 2 ++ dts/arm/nordic/nrf52840.dtsi | 2 ++ dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi | 4 ++++ dts/arm/nordic/nrf91_peripherals.dtsi | 4 ++++ dts/bindings/i2c/nordic,nrf-twi-common.yaml | 7 +++++++ 12 files changed, 39 insertions(+) diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index a282a60746f..13df5051ac7 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -38,6 +38,7 @@ struct i2c_nrfx_twim_config { uint16_t msg_buf_size; void (*irq_connect)(void); const struct pinctrl_dev_config *pcfg; + uint16_t max_transfer_size; }; static int i2c_nrfx_twim_recover_bus(const struct device *dev); @@ -124,6 +125,14 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, cur_xfer.type = (msgs[i].flags & I2C_MSG_READ) ? NRFX_TWIM_XFER_RX : NRFX_TWIM_XFER_TX; + if (cur_xfer.primary_length > dev_config->max_transfer_size) { + LOG_ERR("Trying to transfer more than the maximum size " + "for this device: %d > %d", + cur_xfer.primary_length, + dev_config->max_transfer_size); + return -ENOSPC; + } + nrfx_err_t res = nrfx_twim_xfer(&dev_config->twim, &cur_xfer, (msgs[i].flags & I2C_MSG_STOP) ? @@ -412,6 +421,8 @@ static int i2c_nrfx_twim_init(const struct device *dev) .msg_buf_size = MSG_BUF_SIZE(idx), \ .irq_connect = irq_connect##idx, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ + .max_transfer_size = BIT_MASK( \ + DT_PROP(I2C(idx), easydma_maxcnt_bits)), \ }; \ PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \ I2C_DEVICE_DT_DEFINE(I2C(idx), \ diff --git a/dts/arm/nordic/nrf51822.dtsi b/dts/arm/nordic/nrf51822.dtsi index c55b94cc660..222ccd4854c 100644 --- a/dts/arm/nordic/nrf51822.dtsi +++ b/dts/arm/nordic/nrf51822.dtsi @@ -99,6 +99,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <8>; status = "disabled"; }; @@ -126,6 +127,7 @@ reg = <0x40004000 0x1000>; clock-frequency = ; interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <8>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index 212100d90e5..dd7845588e7 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -110,6 +110,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <14>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 36bfda18511..82f5afb99f6 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -114,6 +114,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <10>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 815bf16d6c1..9e03d5edb32 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -126,6 +126,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <14>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index c3d05fc6ec1..71ff85afbeb 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -122,6 +122,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; status = "disabled"; }; @@ -157,6 +158,7 @@ reg = <0x40004000 0x1000>; clock-frequency = ; interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index 929e5ffcee4..69de3aa591a 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -114,6 +114,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <8>; status = "disabled"; }; @@ -149,6 +150,7 @@ reg = <0x40004000 0x1000>; clock-frequency = ; interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <8>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index 08c806cc99b..8003649385c 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -121,6 +121,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -156,6 +157,7 @@ reg = <0x40004000 0x1000>; clock-frequency = ; interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index f35778a9d48..24710e8e0ff 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -116,6 +116,7 @@ reg = <0x40003000 0x1000>; clock-frequency = ; interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -151,6 +152,7 @@ reg = <0x40004000 0x1000>; clock-frequency = ; interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi index 30e9b47bd82..e7aa0309f70 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi @@ -78,6 +78,7 @@ i2c0: i2c@8000 { reg = <0x8000 0x1000>; clock-frequency = ; interrupts = <8 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -118,6 +119,7 @@ i2c1: i2c@9000 { reg = <0x9000 0x1000>; clock-frequency = ; interrupts = <9 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -171,6 +173,7 @@ i2c2: i2c@b000 { reg = <0xb000 0x1000>; clock-frequency = ; interrupts = <11 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -211,6 +214,7 @@ i2c3: i2c@c000 { reg = <0xc000 0x1000>; clock-frequency = ; interrupts = <12 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; diff --git a/dts/arm/nordic/nrf91_peripherals.dtsi b/dts/arm/nordic/nrf91_peripherals.dtsi index bb456bc6349..2e437eb082d 100644 --- a/dts/arm/nordic/nrf91_peripherals.dtsi +++ b/dts/arm/nordic/nrf91_peripherals.dtsi @@ -158,6 +158,7 @@ i2c0: i2c@8000 { reg = <0x8000 0x1000>; clock-frequency = ; interrupts = <8 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <13>; status = "disabled"; }; @@ -173,6 +174,7 @@ i2c1: i2c@9000 { reg = <0x9000 0x1000>; clock-frequency = ; interrupts = <9 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <13>; status = "disabled"; }; @@ -188,6 +190,7 @@ i2c2: i2c@a000 { reg = <0xa000 0x1000>; clock-frequency = ; interrupts = <10 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <13>; status = "disabled"; }; @@ -203,6 +206,7 @@ i2c3: i2c@b000 { reg = <0xb000 0x1000>; clock-frequency = ; interrupts = <11 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <13>; status = "disabled"; }; diff --git a/dts/bindings/i2c/nordic,nrf-twi-common.yaml b/dts/bindings/i2c/nordic,nrf-twi-common.yaml index 621d45d0f4b..a2052e360d1 100644 --- a/dts/bindings/i2c/nordic,nrf-twi-common.yaml +++ b/dts/bindings/i2c/nordic,nrf-twi-common.yaml @@ -15,3 +15,10 @@ properties: pinctrl-0: required: true + + easydma-maxcnt-bits: + type: int + required: true + description: | + Maximum number of bits available in the EasyDMA MAXCNT register. This + property must be set at SoC level DTS files. From a51593b8fab49f8dc988bfc2e99c9bec903e6413 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 11:11:55 +0000 Subject: [PATCH 1652/4498] doc: release: add 3.5 input notes and migration guide Add 3.6 release notes and migration guide for various changes in the input subsystem. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.5.rst | 8 ++++++++ doc/releases/release-notes-3.5.rst | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 2f5e66c341d..d0db13e6fc4 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -169,6 +169,14 @@ Required changes }; }; +* The :dtcompatible:`goodix,gt911`, :dtcompatible:`xptek,xpt2046` and + :dtcompatible:`hynitron,cst816s` drivers have been converted from Kscan to + Input, they can still be used with Kscan applications by adding a + :dtcompatible:`zephyr,kscan-input` node. + +* The ``zephyr,gpio-keys`` binding has been merged into + :dtcompatible:`gpio-keys` and the callback definition has been renamed from + ``INPUT_LISTENER_CB_DEFINE`` to :c:macro:`INPUT_CALLBACK_DEFINE`. Recommended Changes ******************* diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 27a12ba7921..67c64654afb 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -248,6 +248,24 @@ Drivers and Sensors * GIC: Architecture version selection is now based on the device tree +* Input + + * New drivers: :dtcompatible:`gpio-qdec`, :dtcompatible:`st,stmpe811`. + + * Drivers converted from Kscan to Input: :dtcompatible:`goodix,gt911` + :dtcompatible:`xptek,xpt2046` :dtcompatible:`hynitron,cst816s` + :dtcompatible:`microchip,cap1203`. + + * Added a Kconfig option for dumping all events to the console + :kconfig:option:`CONFIG_INPUT_EVENT_DUMP` and new shell commands + :kconfig:option:`CONFIG_INPUT_SHELL`. + + * Merged ``zephyr,gpio-keys`` into :dtcompatible:`gpio-keys` and added + ``zephyr,code`` codes to all in-tree board ``gpio-keys`` nodes. + + * Renamed the callback definition macro from ``INPUT_LISTENER_CB_DEFINE`` to + :c:macro:`INPUT_CALLBACK_DEFINE`. + * IPM * KSCAN From 9eaa6a27989269c22f9cec88e7ab70ca93101411 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 11:15:04 +0000 Subject: [PATCH 1653/4498] doc: release: add 3.5 migration notes about CONTAINER_OF Add a migration note entry about CONTAINER_OF type checking for the k_work use case. This was common enough that it's probably worth a note pointing at the conversion function. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index d0db13e6fc4..2a5285c459b 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -178,6 +178,12 @@ Required changes :dtcompatible:`gpio-keys` and the callback definition has been renamed from ``INPUT_LISTENER_CB_DEFINE`` to :c:macro:`INPUT_CALLBACK_DEFINE`. +* :c:macro:`CONTAINER_OF` now performs type checking, this was very commonly + misused to obtain user structure from :c:struct:`k_work` pointers without + passing from :c:struct:`k_work_delayable`. This would now result in a build + error and have to be done correctly using + :c:func:`k_work_delayable_from_work`. + Recommended Changes ******************* From 761dac4fa7b169f5809b69c529d70e658308bada Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 11:16:15 +0000 Subject: [PATCH 1654/4498] doc: release: add 3.5 add build time checking release notes Add few notes about the change in build time priority cheking and the new initlevels target. Signed-off-by: Fabio Baltieri --- doc/releases/release-notes-3.5.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 67c64654afb..7a5782c8701 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -163,6 +163,14 @@ Build system and infrastructure propagated to the bootloader and target images to automatically create encrypted updates. +* Build time priority checking: enable build time priority checking by default. + This fails the build if the initialization sequence in the final ELF file + does not match the devicetree hierarchy. It can be turned off by disabling + the :kconfig:option:`COFNIG_CHECK_INIT_PRIORITIES` option. + +* Added a new ``initlevels`` target for printing the final device and + :c:macro:`SYS_INIT` initialization sequence from the final ELF file. + Drivers and Sensors ******************* From 2f64ac9ab6d44f910bcd81df0a6ac27599bed148 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 11:16:49 +0000 Subject: [PATCH 1655/4498] doc: release: add 3.5 change and release notes about bq274xx Few channels of this driver were using the wrong units, add a note pointing out that this needs a matching change in any application using them. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.5.rst | 5 +++++ doc/releases/release-notes-3.5.rst | 3 +++ 2 files changed, 8 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 2a5285c459b..a605fbefe59 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -184,6 +184,11 @@ Required changes error and have to be done correctly using :c:func:`k_work_delayable_from_work`. +* The :dtcompatible:`ti,bq274xx` driver was using incorrect units for capacity + and power channels, these have been fixed and scaled by x1000 factor from the + previous implementation, any application using them has to be changed + accordingly. + Recommended Changes ******************* diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7a5782c8701..2e39fb89cf1 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -313,6 +313,9 @@ Drivers and Sensors * Sensor + * Reworked the :dtcompatible:`ti,bq274xx` to add ``BQ27427`` support, fixed + units for capacity and power channels. + * Serial * Added support for Nuvoton NuMaker M46x From f82e2ef043ea40c648094955b4a0c54c42a98d5a Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Thu, 28 Sep 2023 09:36:01 +0200 Subject: [PATCH 1656/4498] scripts: domains: Tighten up initialization Do extra checks to reject inconsistent `domains.yaml` contents early: default: app build_dir: /path/to/build domains: - name: image_1 build_dir: /path/to/build/image_1 - name: image_2 build_dir: /path/to/build/image_2 flash_order: - image_1 - image_2 - unknown This example lists "image_1" and "image_2" as known domains, but an entry for the default "app" is missing, which should never be allowed. A valid `domains.yaml` file shall also not contain extra domains under `flash_order`, such as "unknown", which doesn't appear under `domains`. Either of these cases can now be caught while initializing an instance of the Domains class. It follows that a valid `domains.yaml` file must always contain a list of domains with at least one entry - the default image. Since `default` is a required key in the YAML schema, `domains` should be required too. Thus, empty lists will be rejected by pykwalify, so the questionable warning for "no domains defined; this probably won't work" can be axed. Fixes #63166 Signed-off-by: Grzegorz Swiderski --- scripts/pylib/build_helpers/domains.py | 39 ++++++++++++-------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 8cacac7b4e8..f4c2f085fd2 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -27,7 +27,7 @@ required: true type: str domains: - required: false + required: true type: seq sequence: - type: map @@ -57,19 +57,18 @@ class Domains: def __init__(self, data): - self._build_dir = data.get('build_dir') - domain_list = data.get('domains') or [] - if not domain_list: - logger.warning("no domains defined; this probably won't work") - + self._build_dir = data['build_dir'] self._domains = { d['name']: Domain(d['name'], d['build_dir']) - for d in domain_list + for d in data['domains'] } - self._default_domain = self._domains.get(data['default']) - domains_flash_order = data.get('flash_order') or [] - self._flash_order = list(map(self._domains.get, domains_flash_order)) + # In the YAML data, the values for "default" and "flash_order" + # must not name any domains that aren't listed under "domains". + # Now that self._domains has been initialized, we can leverage + # the common checks in self.get_domain to verify this. + self._default_domain = self.get_domain(data['default']) + self._flash_order = self.get_domains(data['flash_order'] or []) @staticmethod def from_file(domains_file): @@ -101,21 +100,19 @@ def from_data(domains_data): return Domains(domains_data) def get_domains(self, names=None, default_flash_order=False): - ret = [] - - if not names: + if names is None: if default_flash_order: return self._flash_order return list(self._domains.values()) + return list(map(self.get_domain, names)) - for n in names: - found = self._domains.get(n) - if not found: - logger.critical(f'domain {n} not found, ' - f'valid domains are: {", ".join(self._domains)}') - exit(1) - ret.append(found) - return ret + def get_domain(self, name): + found = self._domains.get(name) + if not found: + logger.critical(f'domain "{name}" not found, ' + f'valid domains are: {", ".join(self._domains)}') + exit(1) + return found def get_default_domain(self): return self._default_domain From 652b0a8a985481cb40d680a4864599d9294a296c Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Thu, 28 Sep 2023 09:36:18 +0200 Subject: [PATCH 1657/4498] scripts: domains: Support initialization only from YAML By requiring a full-on YAML fragment, the Domains class can rely on pykwalify to do the heavy lifting with validating types and structure. Remove support for loading domains from a dictionary, so that we don't ever have to replicate the same checks on the input, and we can instead have a single entry point. Signed-off-by: Grzegorz Swiderski --- scripts/pylib/build_helpers/domains.py | 32 ++++++++++++-------------- scripts/west_commands/build_helpers.py | 13 +++++++---- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index f4c2f085fd2..475844e9a61 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -56,7 +56,15 @@ class Domains: - def __init__(self, data): + def __init__(self, domains_yaml): + try: + data = yaml.safe_load(domains_yaml) + pykwalify.core.Core(source_data=data, + schema_data=schema).validate() + except (yaml.YAMLError, pykwalify.errors.SchemaError): + logger.critical(f'malformed domains.yaml') + exit(1) + self._build_dir = data['build_dir'] self._domains = { d['name']: Domain(d['name'], d['build_dir']) @@ -72,32 +80,22 @@ def __init__(self, data): @staticmethod def from_file(domains_file): - '''Load domains from domains.yaml. - - Exception raised: - - ``FileNotFoundError`` if the domains file is not found. + '''Load domains from a domains.yaml file. ''' try: with open(domains_file, 'r') as f: - domains = yaml.safe_load(f.read()) + domains_yaml = f.read() except FileNotFoundError: logger.critical(f'domains.yaml file not found: {domains_file}') exit(1) - try: - pykwalify.core.Core(source_data=domains, schema_data=schema)\ - .validate() - except pykwalify.errors.SchemaError: - logger.critical(f'ERROR: Malformed yaml in file: {domains_file}') - exit(1) - - return Domains(domains) + return Domains(domains_yaml) @staticmethod - def from_data(domains_data): - '''Load domains from domains dictionary. + def from_yaml(domains_yaml): + '''Load domains from a string with YAML contents. ''' - return Domains(domains_data) + return Domains(domains_yaml) def get_domains(self, names=None, default_flash_order=False): if names is None: diff --git a/scripts/west_commands/build_helpers.py b/scripts/west_commands/build_helpers.py index 88845e50f4b..ca6845f01da 100644 --- a/scripts/west_commands/build_helpers.py +++ b/scripts/west_commands/build_helpers.py @@ -151,9 +151,14 @@ def load_domains(path): domains_file = Path(path) / 'domains.yaml' if not domains_file.is_file(): - return Domains.from_data({'default': 'app', - 'build_dir': path, - 'domains': [{'name': 'app', 'build_dir': path}], - 'flash_order': ['app']}) + return Domains.from_yaml(f'''\ +default: app +build_dir: {path} +domains: + - name: app + build_dir: {path} +flash_order: + - app +''') return Domains.from_file(domains_file) From 9bbf7e5a4806c158e0d5c19b816379ef02e0f3e3 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Thu, 28 Sep 2023 09:36:36 +0200 Subject: [PATCH 1658/4498] scripts: domains: Convert Domain to a dataclass For conciseness. Signed-off-by: Grzegorz Swiderski --- scripts/pylib/build_helpers/domains.py | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 475844e9a61..978569d9547 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -8,6 +8,8 @@ Domain class. ''' +from dataclasses import dataclass + import yaml import pykwalify.core import logging @@ -119,24 +121,8 @@ def get_top_build_dir(self): return self._build_dir +@dataclass class Domain: - def __init__(self, name, build_dir): - self.name = name - self.build_dir = build_dir - - @property - def name(self): - return self._name - - @name.setter - def name(self, value): - self._name = value - - @property - def build_dir(self): - return self._build_dir - - @build_dir.setter - def build_dir(self, value): - self._build_dir = value + name: str + build_dir: str From d487794dd683b7d6e7dc298d9dca7a70ab6d04cd Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 4 Oct 2023 13:25:11 +0000 Subject: [PATCH 1659/4498] drivers: i2s: i2s_mcux_sai: fix logging statements for k_mem_slab Since 2f003e59 reworked the structure of k_mem_slab information fields, we need to update the logging statements in the i2s_mcux_sai driver to access these fields correctly. Fixes #63527 Signed-off-by: Daniel DeGrasse --- drivers/i2s/i2s_mcux_sai.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index ebb9b9f00d5..3e4f6f19f84 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -660,9 +660,9 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, LOG_DBG("tx slab free_list = 0x%x", (uint32_t)i2s_cfg->mem_slab->free_list); LOG_DBG("tx slab num_blocks = %d", - (uint32_t)i2s_cfg->mem_slab->num_blocks); + (uint32_t)i2s_cfg->mem_slab->info.num_blocks); LOG_DBG("tx slab block_size = %d", - (uint32_t)i2s_cfg->mem_slab->block_size); + (uint32_t)i2s_cfg->mem_slab->info.block_size); LOG_DBG("tx slab buffer = 0x%x", (uint32_t)i2s_cfg->mem_slab->buffer); @@ -693,9 +693,9 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, LOG_DBG("rx slab free_list = 0x%x", (uint32_t)i2s_cfg->mem_slab->free_list); LOG_DBG("rx slab num_blocks = %d", - (uint32_t)i2s_cfg->mem_slab->num_blocks); + (uint32_t)i2s_cfg->mem_slab->info.num_blocks); LOG_DBG("rx slab block_size = %d", - (uint32_t)i2s_cfg->mem_slab->block_size); + (uint32_t)i2s_cfg->mem_slab->info.block_size); LOG_DBG("rx slab buffer = 0x%x", (uint32_t)i2s_cfg->mem_slab->buffer); From 01bdd845db4f945afff82a38cf14ccaa7b875d81 Mon Sep 17 00:00:00 2001 From: Mario Jaun Date: Tue, 3 Oct 2023 10:24:51 +0200 Subject: [PATCH 1660/4498] drivers: i2c: stm32: disable reload mode at the end of a transfer Fixes an issue that reload mode is not disabled in case of an error. From this case the driver could not recover because in msg_init() no new transfer could be initialized. Signed-off-by: Mario Jaun --- drivers/i2c/i2c_ll_stm32_v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index 5d22380118b..c75d68e4f19 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -103,6 +103,10 @@ static void stm32_i2c_master_mode_end(const struct device *dev) stm32_i2c_disable_transfer_interrupts(dev); + if (LL_I2C_IsEnabledReloadMode(i2c)) { + LL_I2C_DisableReloadMode(i2c); + } + #if defined(CONFIG_I2C_TARGET) data->master_active = false; if (!data->slave_attached) { From dcf6327d6ad75208b15be47758411a7f9b820afd Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Wed, 4 Oct 2023 13:46:17 +0200 Subject: [PATCH 1661/4498] net: context: set context->local for offloaded iface Currently context->local is not set for offloaded interface. This change move net_offload_bind call after set of context->local. Signed-off-by: Wojciech Slenska --- subsys/net/ip/net_context.c | 38 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index c611f48b3fa..9de988e54f8 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -709,24 +709,19 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, return -EADDRNOTAVAIL; } - if (IS_ENABLED(CONFIG_NET_OFFLOAD) && - net_if_is_ip_offloaded(iface)) { - net_context_set_iface(context, iface); - - return net_offload_bind(iface, - context, - addr, - addrlen); - } - k_mutex_lock(&context->lock, K_FOREVER); - ret = 0; - net_context_set_iface(context, iface); net_sin6_ptr(&context->local)->sin6_family = AF_INET6; net_sin6_ptr(&context->local)->sin6_addr = ptr; + + if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) { + k_mutex_unlock(&context->lock); + return net_offload_bind(iface, context, addr, addrlen); + } + + ret = 0; if (addr6->sin6_port) { ret = check_used_port(context->proto, addr6->sin6_port, @@ -811,24 +806,19 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, return -EADDRNOTAVAIL; } - if (IS_ENABLED(CONFIG_NET_OFFLOAD) && - net_if_is_ip_offloaded(iface)) { - net_context_set_iface(context, iface); - - return net_offload_bind(iface, - context, - addr, - addrlen); - } - k_mutex_lock(&context->lock, K_FOREVER); - ret = 0; - net_context_set_iface(context, iface); net_sin_ptr(&context->local)->sin_family = AF_INET; net_sin_ptr(&context->local)->sin_addr = ptr; + + if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(iface)) { + k_mutex_unlock(&context->lock); + return net_offload_bind(iface, context, addr, addrlen); + } + + ret = 0; if (addr4->sin_port) { ret = check_used_port(context->proto, addr4->sin_port, From e9e698e4f15e9e7255f9a8c2e6681b95f19bedd9 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 26 Sep 2023 11:38:02 -0700 Subject: [PATCH 1662/4498] doc: release: 3.5 Add info about CVE-2023-4264 Add CVE-2023-4264 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 2e39fb89cf1..c7c146e52f8 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -23,6 +23,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ +* CVE-2023-4264 `Zephyr project bug tracker GHSA-rgx6-3w4j-gf5j + `_ + * CVE-2023-5184 `Zephyr project bug tracker GHSA-8x3p-q3r5-xh9g `_ From 078967671c9038367edeb60818c0e69015320e32 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 26 Sep 2023 11:42:57 -0700 Subject: [PATCH 1663/4498] doc: vuln: Add information about CVE-2023-4264 Information about CVE-2023-4264 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index b7529a73d5e..af9b5971979 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1368,6 +1368,28 @@ Potential buffer overflow vulnerabilities in the Zephyr Mgmt subsystem - This issue has not been fixed. +CVE-2023-4264 +------------- + +Potential buffer overflow vulnerabilities in the Zephyr Bluetooth subsystem + +- `Zephyr project bug tracker GHSA-rgx6-3w4j-gf5j + `_ + +This has been fixed in main for v3.5.0 + +- `PR 58834 fix for main + `_ + +- `PR 60465 fix for main + `_ + +- `PR 61845 fix for main + `_ + +- `PR 61385 fix for 3.4 + `_ + CVE-2023-4265 ------------- From e962fda0ee66900a15705c0a5e58fea4adf8035b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 4 Oct 2023 17:29:33 +0200 Subject: [PATCH 1664/4498] Bluetooth: Audio: Fix BAP Broadcast source reconfig param count The check for number of streams in a subgroup was reversed, so it would never allow for correct values. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_source.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index c52c31c005a..bc5c2b8908d 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -770,10 +770,10 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, ¶m->params[subgroup_cnt]; const size_t subgroup_stream_param_cnt = subgroup_param->params_count; struct bt_bap_stream *stream; - size_t stream_cnt = 0U; + size_t subgroup_stream_cnt = 0U; SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) { - stream_cnt++; + subgroup_stream_cnt++; } /* Verify that the param stream is in the subgroup */ @@ -799,10 +799,10 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, } } - if (subgroup_stream_param_cnt < stream_cnt) { + if (subgroup_stream_cnt < subgroup_stream_param_cnt) { LOG_DBG("Invalid param->params[%zu]->params_count: %zu " "(only %zu streams in subgroup)", - subgroup_cnt, subgroup_stream_param_cnt, stream_cnt); + subgroup_cnt, subgroup_stream_param_cnt, subgroup_stream_cnt); return -EINVAL; } From 85fa4122014d867b290b9fe5bc569b8b1c3b0da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Fri, 29 Sep 2023 15:10:10 +0200 Subject: [PATCH 1665/4498] bluetooth: tester: add support for variable static oob size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding variable static auth size support to be compatible both mesh 1.0.1 and mesh 1.1. Signed-off-by: Alperen Şener --- tests/bluetooth/tester/src/btp/btp_mesh.h | 8 +++----- tests/bluetooth/tester/src/btp_mesh.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 6c4a5e90106..826f0fd0408 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -30,15 +30,12 @@ struct btp_mesh_read_supported_commands_rp { #define BTP_MESH_CONFIG_PROVISIONING 0x02 -#if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) -#define BTP_MESH_PROV_AUTH_MAX_LEN 32 -#else -#define BTP_MESH_PROV_AUTH_MAX_LEN 16 -#endif +#define BTP_MESH_PROV_AUTH_MAX_LEN 32 struct btp_mesh_config_provisioning_cmd { uint8_t uuid[16]; uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; + uint8_t static_auth_size; uint8_t out_size; uint16_t out_actions; uint8_t in_size; @@ -48,6 +45,7 @@ struct btp_mesh_config_provisioning_cmd { struct btp_mesh_config_provisioning_cmd_v2 { uint8_t uuid[16]; uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; + uint8_t static_auth_size; uint8_t out_size; uint16_t out_actions; uint8_t in_size; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 1d94eb43cb5..44ace086c69 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -50,6 +50,7 @@ static uint8_t priv_key[32]; /* Configured provisioning data */ static uint8_t dev_uuid[16]; static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; +static uint8_t static_auth_size; /* Vendor Model data */ #define VND_MODEL_ID_1 0x1234 @@ -1127,13 +1128,21 @@ static uint8_t config_prov(const void *cmd, uint16_t cmd_len, /* TODO consider fix BTP commands to avoid this */ if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) { + LOG_DBG("wrong cmd size"); return BTP_STATUS_FAILED; } LOG_DBG(""); + static_auth_size = cp->static_auth_size; + + if (static_auth_size > BTP_MESH_PROV_AUTH_MAX_LEN || static_auth_size == 0) { + LOG_DBG("wrong static auth length"); + return BTP_STATUS_FAILED; + } + memcpy(dev_uuid, cp->uuid, sizeof(dev_uuid)); - memcpy(static_auth, cp->static_auth, sizeof(static_auth)); + memcpy(static_auth, cp->static_auth, cp->static_auth_size); prov.output_size = cp->out_size; prov.output_actions = sys_le16_to_cpu(cp->out_actions); @@ -1152,7 +1161,7 @@ static uint8_t config_prov(const void *cmd, uint16_t cmd_len, } else if (cp->auth_method == AUTH_METHOD_INPUT) { err = bt_mesh_auth_method_set_input(prov.input_actions, prov.input_size); } else if (cp->auth_method == AUTH_METHOD_STATIC) { - err = bt_mesh_auth_method_set_static(static_auth, sizeof(static_auth)); + err = bt_mesh_auth_method_set_static(static_auth, static_auth_size); } if (err) { From 6d56851eb50e27608d9d7e6227916dc6144cf158 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 4 Oct 2023 13:53:12 +0200 Subject: [PATCH 1666/4498] boards: frdm_k64f: Add uart-mcumgr chosen Since frdm_k64f is used as example in mcumgr sample with serial transport, make it ready for compilation. Fixes #63520 Signed-off-by: Erwan Gouriou --- boards/arm/frdm_k64f/frdm_k64f.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/frdm_k64f/frdm_k64f.dts b/boards/arm/frdm_k64f/frdm_k64f.dts index ec6a0fdf84e..5b0e26fb039 100644 --- a/boards/arm/frdm_k64f/frdm_k64f.dts +++ b/boards/arm/frdm_k64f/frdm_k64f.dts @@ -28,6 +28,7 @@ zephyr,shell-uart = &uart0; zephyr,uart-pipe = &uart0; zephyr,canbus = &flexcan0; + zephyr,uart-mcumgr = &uart0; }; leds { From 78f24b0a278c446c580678fba551da4b222f9632 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 4 Oct 2023 22:14:21 +0000 Subject: [PATCH 1667/4498] doc: release: 3.5 Add CVEs under embargo Add CVEs fixed that are under embargo. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c7c146e52f8..3e72a039516 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -20,15 +20,24 @@ The following CVEs are addressed by this release: More detailed information can be found in: https://docs.zephyrproject.org/latest/security/vulnerabilities.html +* CVE-2023-4257: Under embargo until 2023-10-12 + * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ * CVE-2023-4264 `Zephyr project bug tracker GHSA-rgx6-3w4j-gf5j `_ +* CVE-2023-4424: Under embargo until 2023-11-01 + +* CVE-2023-5055: Under embargo until 2023-11-01 + +* CVE-2023-5139: Under embargo until 2023-10-25 + * CVE-2023-5184 `Zephyr project bug tracker GHSA-8x3p-q3r5-xh9g `_ + Kernel ****** From 66d76d4afa5430357a14262ebb0e0af14cf6ff65 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 4 Oct 2023 22:15:32 +0000 Subject: [PATCH 1668/4498] doc: vuln: Add CVEs under embargo Add placeholders for CVEs under embargo. Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index af9b5971979..41d3f0235e1 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1339,6 +1339,11 @@ This has been fixed in main for v3.4.0 - `PR 56709 fix for main `_ +CVE-2023-4257 +------------- + +Under embargo until 2023/10/12 + CVE-2023-4258 ------------- @@ -1405,6 +1410,21 @@ This has been fixed in main for v3.4.0 - `PR 59018 fix for main `_ +CVE-2023-4424 +------------- + +Under embargo until 2023/11/01 + +CVE-2023-5055 +------------- + +Under embargo until 2023/11/01 + +CVE-2023-5139 +------------- + +Under embargo until 2023/10/25 + CVE-2023-5184 ------------- From db8855aaa3f32d3ba1f4e4e9066eb953c4406e25 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Wed, 4 Oct 2023 13:22:41 +0800 Subject: [PATCH 1669/4498] driver: crypto: SHA: npcx: change to support npcx4 The pre-alloacted size of the buffer for the SHA ROM API code increases in npcx4 chip. This commit adds a new property context-buffer-size to sha0 DT node in npcx9 and npcx4 separately. The driver can pre-allocate buffer with the correct size based on the property. Signed-off-by: Jun Lin --- drivers/crypto/crypto_npcx_sha.c | 2 +- dts/arm/nuvoton/npcx/npcx4.dtsi | 1 + dts/arm/nuvoton/npcx/npcx9.dtsi | 1 + dts/bindings/crypto/nuvoton,npcx-sha.yaml | 7 +++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/crypto_npcx_sha.c b/drivers/crypto/crypto_npcx_sha.c index e2420134cfa..26403599360 100644 --- a/drivers/crypto/crypto_npcx_sha.c +++ b/drivers/crypto/crypto_npcx_sha.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(sha_npcx, CONFIG_CRYPTO_LOG_LEVEL); #define NPCX_HASH_CAPS_SUPPORT (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS) -#define NPCX_SHA256_HANDLE_SIZE 212 +#define NPCX_SHA256_HANDLE_SIZE DT_INST_PROP(0, context_buffer_size) #define NPCX_SHA_MAX_SESSION 1 /* The status code returns from Nuvoton Cryptographic Library ROM APIs */ diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index 56adb416d01..54616fbeed4 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -292,6 +292,7 @@ sha0: sha@13c { compatible = "nuvoton,npcx-sha"; reg = <0x13c 0x3c>; + context-buffer-size = <228>; status = "disabled"; }; }; diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi index 18a1278de57..4d0cb7dc69e 100644 --- a/dts/arm/nuvoton/npcx/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9.dtsi @@ -269,6 +269,7 @@ sha0: sha@13c { compatible = "nuvoton,npcx-sha"; reg = <0x13c 0x3c>; + context-buffer-size = <212>; status = "disabled"; }; }; diff --git a/dts/bindings/crypto/nuvoton,npcx-sha.yaml b/dts/bindings/crypto/nuvoton,npcx-sha.yaml index 2670855d45b..237490840ad 100644 --- a/dts/bindings/crypto/nuvoton,npcx-sha.yaml +++ b/dts/bindings/crypto/nuvoton,npcx-sha.yaml @@ -10,3 +10,10 @@ include: base.yaml properties: reg: required: true + + context-buffer-size: + type: int + required: true + description: | + Size of the pre-allocated buffer for the SHA ROM API to store the + intermdiate computation result and final digest. From ccbbb493da9dfb4846672a870e51be933b4404b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 17:05:49 +0200 Subject: [PATCH 1670/4498] tests: kernel: Add qemu_leon3 to no-multithreading tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add qemu_leon3 target to the tests that list below. These set CONFIG_MULTITHREADING=n. - tests/kernel/mem_heap/mheap_api_concept - tests/kernel/mem_slab/mslab_api - tests/kernel/threads/no-multithreading - tests/kernel/timer/timer_api Signed-off-by: Martin Åberg --- tests/kernel/mem_heap/mheap_api_concept/testcase.yaml | 1 + tests/kernel/mem_slab/mslab_api/testcase.yaml | 1 + tests/kernel/threads/no-multithreading/testcase.yaml | 1 + tests/kernel/timer/timer_api/testcase.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/tests/kernel/mem_heap/mheap_api_concept/testcase.yaml b/tests/kernel/mem_heap/mheap_api_concept/testcase.yaml index 897aca938e9..380c9a0726f 100644 --- a/tests/kernel/mem_heap/mheap_api_concept/testcase.yaml +++ b/tests/kernel/mem_heap/mheap_api_concept/testcase.yaml @@ -24,6 +24,7 @@ tests: - qemu_riscv32 - qemu_riscv32e - qemu_riscv64 + - qemu_leon3 integration_platforms: - qemu_cortex_m3 extra_configs: diff --git a/tests/kernel/mem_slab/mslab_api/testcase.yaml b/tests/kernel/mem_slab/mslab_api/testcase.yaml index fbfdffda5fa..3f067a1529f 100644 --- a/tests/kernel/mem_slab/mslab_api/testcase.yaml +++ b/tests/kernel/mem_slab/mslab_api/testcase.yaml @@ -22,6 +22,7 @@ tests: - qemu_riscv32 - qemu_riscv32e - qemu_riscv64 + - qemu_leon3 integration_platforms: - qemu_cortex_m3 - qemu_arc_hs diff --git a/tests/kernel/threads/no-multithreading/testcase.yaml b/tests/kernel/threads/no-multithreading/testcase.yaml index 990965d459f..d29165f683c 100644 --- a/tests/kernel/threads/no-multithreading/testcase.yaml +++ b/tests/kernel/threads/no-multithreading/testcase.yaml @@ -22,5 +22,6 @@ tests: - qemu_riscv32 - qemu_riscv32e - qemu_riscv64 + - qemu_leon3 integration_platforms: - qemu_cortex_m0 diff --git a/tests/kernel/timer/timer_api/testcase.yaml b/tests/kernel/timer/timer_api/testcase.yaml index 1847499e49f..82919939e43 100644 --- a/tests/kernel/timer/timer_api/testcase.yaml +++ b/tests/kernel/timer/timer_api/testcase.yaml @@ -34,6 +34,7 @@ tests: - qemu_arc_em - qemu_arc_hs - qemu_arc_hs6x + - qemu_leon3 integration_platforms: - qemu_cortex_m3 - nsim_em From 14d88c6dc8bf9e990ab00eb07ba660b645a1dc13 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 3 Oct 2023 22:16:18 +0000 Subject: [PATCH 1671/4498] tests: drivers: flash: remove platform_allow filter Prior to commit 903a79431, drivers.flash.common.default would have executed on any platform that passed the filter condition. With the addition of the platform_allow filter, this is no longer the case, and is masking issues such as those seen in #62963. Remove the platform_allow filter to return this test to the previous behavior. Signed-off-by: Daniel DeGrasse --- tests/drivers/flash/common/testcase.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index 844d5d1e556..d9cf78ebcab 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -35,15 +35,6 @@ tests: integration_platforms: - qemu_x86 - mimxrt1060_evk - platform_allow: - - qemu_x86 - - mimxrt1060_evk - - it8xxx2_evb - - mimxrt685_evk_cm33 - - mimxrt595_evk_cm33 - - nrf52_bsim - - nrf5340bsim_nrf5340_cpunet - - nrf5340bsim_nrf5340_cpuapp drivers.flash.common.tfm_ns: build_only: true filter: (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE From 3521c95c2fb6b9befc1ae782ef9e9eb47ca31dae Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 23:19:13 -0700 Subject: [PATCH 1672/4498] fs: fuse: Fix possible buffer overflow Ensure that the path in fuse_fs_access_readdir does not overflow the local buffer. Signed-off-by: Flavio Ceolin --- subsys/fs/fuse_fs_access.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/subsys/fs/fuse_fs_access.c b/subsys/fs/fuse_fs_access.c index 8453c6544e8..11e8f0225d9 100644 --- a/subsys/fs/fuse_fs_access.c +++ b/subsys/fs/fuse_fs_access.c @@ -176,9 +176,15 @@ static int fuse_fs_access_readdir(const char *path, void *buf, * directory but FUSE strips the trailing slashes from * directory names so add it back. */ - char mount_path[PATH_MAX]; + char mount_path[PATH_MAX] = {0}; + size_t len = strlen(path); - sprintf(mount_path, "%s/", path); + if (len >= (PATH_MAX - 2)) { + return -ENOMEM; + } + + memcpy(mount_path, path, len) + mount_path[len] = '/'; err = fs_opendir(&dir, mount_path); } else { err = fs_opendir(&dir, path); From c7779bec8ca238e73649f9721f0f71129867e52b Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 2 Oct 2023 13:00:06 +0200 Subject: [PATCH 1673/4498] cmake: stub zephyr_set(... SCOPE ...) function in package helper Fixes: #63011 Custom targets are not available in script mode, which cause snippet loading to fail when using package helper. Lookup of snippets is supported by package helper, thus allowing twister to filter test cases based on snippets. However, loading of snippets itself is not supported as snippets make use of Zephyr scoping, which uses custom targets, something that is not available in script mode. Therefore overload the `zephyr_set()` function, so that CMake package helper can be used together with snippets. Signed-off-by: Torsten Rasmussen --- cmake/package_helper.cmake | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/package_helper.cmake b/cmake/package_helper.cmake index d33b1cf6ddf..55412b94110 100644 --- a/cmake/package_helper.cmake +++ b/cmake/package_helper.cmake @@ -111,5 +111,16 @@ if(NOT DEFINED MODULES) ) endif() +# Loading Zephyr CMake extension commands, which allows us to overload Zephyr +# scoping rules. +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS extensions) + +# Zephyr scoping creates custom targets for handling of properties. +# However, custom targets cannot be used in CMake script mode. +# Therefore disable zephyr_set(... SCOPE ...) in package helper as it is not needed. +function(zephyr_set variable) + # This silence the error: zephyr_set(... SCOPE ) doesn't exists. +endfunction() + string(REPLACE ";" "," MODULES "${MODULES}") find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS zephyr_default:${MODULES}) From 0ba6e80a12b94aa09d47889e3cb0b08024a9cde6 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Wed, 4 Oct 2023 16:41:39 +0200 Subject: [PATCH 1674/4498] Bluetooth: Mesh: fix settings work queue size for rpr If RPR server is used then Mesh settings work queue requires more size during provisioning procedure. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 6bc4c8b5673..a2f5ffc1097 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1718,6 +1718,7 @@ config BT_MESH_SETTINGS_WORKQ_PRIO config BT_MESH_SETTINGS_WORKQ_STACK_SIZE int "Stack size of the settings workq" + default 1200 if BT_MESH_RPR_SRV default 880 help Size of the settings workqueue stack. From c81c38114a345651420451cfc1c6d114eef5c36d Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Sat, 12 Aug 2023 13:32:53 +0200 Subject: [PATCH 1675/4498] drivers: ieee802154: cc13xx_cc26xx_subg: minor cleanup Cleans up includes and a few other minor non-functional errors in the CC13/26xx driver. Signed-off-by: Florian Grandel --- .../ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index c8d71e58bf3..c2ae3b2ea43 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -10,16 +10,17 @@ #include LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx_subg); -#include #include -#include -#include +#include + +#include #include +#include #include #include -#include -#include +#include #include +#include #include #include @@ -348,7 +349,7 @@ static void client_error_callback(RF_Handle h, RF_CmdHandle ch, { ARG_UNUSED(h); ARG_UNUSED(ch); - LOG_DBG("e: 0x%" PRIx64, e); + LOG_ERR("client error: 0x%" PRIx64, e); } static void client_event_callback(RF_Handle h, RF_ClientEvent event, @@ -821,8 +822,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) return -EIO; } - /* - * Run CMD_FS with frequency 0 to ensure RF_currClient is not NULL. + /* Run CMD_FS with frequency 0 to ensure RF_currClient is not NULL. * RF_currClient is a static variable in the TI RF Driver library. * If this is not done, then even CMD_ABORT fails. */ From 128354ae17fb95ec6c61d73b9060f1a274715464 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 08:40:37 +0200 Subject: [PATCH 1676/4498] drivers: ieee802154: cc13xx_cc26xx_subg: simplify static funcs Restructuring and renaming of driver-internal functions for improved readability and maintainability: - distinguish between externally exposed API methods (cc13xx_cc26xx_sub_* prefix) and internal helper methods (drv_* prefix). - extract a few functions to reduce complexity and improve re-use Also removes unnecessary initial runtime blanking of static (.bss) data in the newly introduced extracted buffer initialization functions. Signed-off-by: Florian Grandel --- .../ieee802154_cc13xx_cc26xx_subg.c | 158 +++++++++++------- .../ieee802154_cc13xx_cc26xx_subg.h | 2 + 2 files changed, 99 insertions(+), 61 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index c2ae3b2ea43..de5beb1ebea 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -33,18 +33,9 @@ LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx_subg); #include "ieee802154_cc13xx_cc26xx_subg.h" -static void ieee802154_cc13xx_cc26xx_subg_rx_done( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data); -static void ieee802154_cc13xx_cc26xx_subg_data_init( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data); -static int ieee802154_cc13xx_cc26xx_subg_stop( - const struct device *dev); -static int ieee802154_cc13xx_cc26xx_subg_stop_if( - const struct device *dev); -static int ieee802154_cc13xx_cc26xx_subg_rx( - const struct device *dev); -static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data); +static int drv_start_rx(const struct device *dev); +static int drv_stop_rx(const struct device *dev); +static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data); #ifndef CMD_PROP_RADIO_DIV_SETUP_PA /* workaround for older HAL TI SDK (less than 4.40) */ @@ -257,9 +248,7 @@ static RF_Mode rf_mode = { .cpePatchFxn = &rf_patch_cpe_multi_protocol, }; - -static inline int ieee802154_cc13xx_cc26xx_subg_channel_to_frequency( - uint16_t channel, uint16_t *frequency, uint16_t *fractFreq) +static inline int drv_channel_frequency(uint16_t channel, uint16_t *frequency, uint16_t *fractFreq) { __ASSERT_NO_MSG(frequency != NULL); __ASSERT_NO_MSG(fractFreq != NULL); @@ -310,6 +299,15 @@ static inline int ieee802154_cc13xx_cc26xx_subg_channel_to_frequency( return 0; } +static inline int drv_power_down(const struct device *const dev) +{ + struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + + (void)RF_yield(drv_data->rf_handle); + + return 0; +} + static void cmd_prop_tx_adv_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { @@ -332,7 +330,7 @@ static void cmd_prop_rx_adv_callback(RF_Handle h, RF_CmdHandle ch, op->commandNo, op->status, e); if (e & RF_EventRxEntryDone) { - ieee802154_cc13xx_cc26xx_subg_rx_done(drv_data); + drv_rx_done(drv_data); } if (op->status == PROP_ERROR_RXBUF @@ -340,7 +338,7 @@ static void cmd_prop_rx_adv_callback(RF_Handle h, RF_CmdHandle ch, || op->status == PROP_ERROR_RXOVF) { LOG_DBG("RX Error %x", op->status); /* Restart RX */ - (void)ieee802154_cc13xx_cc26xx_subg_rx(dev); + (void)drv_start_rx(dev); } } @@ -378,11 +376,12 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) drv_data->cmd_prop_cs.condition.rule = COND_NEVER; was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; - - ret = ieee802154_cc13xx_cc26xx_subg_stop(dev); - if (ret < 0) { - ret = -EIO; - goto out; + if (was_rx_on) { + ret = drv_stop_rx(dev); + if (ret < 0) { + ret = -EIO; + goto out; + } } events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_prop_cs, RF_PriorityNormal, @@ -416,18 +415,25 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) * the meantime. */ if (was_rx_on) { - ieee802154_cc13xx_cc26xx_subg_rx(dev); + drv_start_rx(dev); } return ret; } -static int ieee802154_cc13xx_cc26xx_subg_rx(const struct device *dev) +static int drv_start_rx(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_CmdHandle cmd_handle; - /* Set all RX entries to empty */ - ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers(drv_data); +#ifdef CONFIG_ASSERT + if (CONFIG_ASSERT_LEVEL > 0) { + /* ensure that all RX buffers are initialized and pending. */ + for (int i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; i++) { + __ASSERT_NO_MSG(drv_data->rx_entry[i].pNextEntry != NULL); + __ASSERT_NO_MSG(drv_data->rx_entry[i].status == DATA_ENTRY_PENDING); + } + } +#endif drv_data->cmd_prop_rx_adv.status = IDLE; cmd_handle = RF_postCmd(drv_data->rf_handle, @@ -438,9 +444,31 @@ static int ieee802154_cc13xx_cc26xx_subg_rx(const struct device *dev) return -EIO; } + drv_data->rx_cmd_handle = cmd_handle; + return 0; } +static int drv_stop_rx(const struct device *dev) +{ + struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + RF_Stat status; + + if (drv_data->cmd_prop_rx_adv.status != ACTIVE) { + return -EALREADY; + } + + /* Stop RX without aborting ongoing reception of packets. */ + status = RF_cancelCmd(drv_data->rf_handle, drv_data->rx_cmd_handle, RF_ABORT_GRACEFULLY); + switch (status) { + case RF_StatSuccess: + case RF_StatCmdEnded: + return 0; + default: + return -EIO; + } +} + static int ieee802154_cc13xx_cc26xx_subg_set_channel( const struct device *dev, uint16_t channel) { @@ -450,18 +478,19 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( bool was_rx_on; int ret; - ret = ieee802154_cc13xx_cc26xx_subg_channel_to_frequency(channel, &freq, &fract); + ret = drv_channel_frequency(channel, &freq, &fract); if (ret < 0) { return ret; } - was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; - /* Abort FG and BG processes */ - ret = ieee802154_cc13xx_cc26xx_subg_stop(dev); - if (ret) { - ret = -EIO; - goto out; + was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; + if (was_rx_on) { + ret = drv_stop_rx(dev); + if (ret) { + ret = -EIO; + goto out; + } } /* Block TX while changing channel */ @@ -483,7 +512,7 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( out: /* Re-enable RX if we found it on initially. */ if (was_rx_on) { - ieee802154_cc13xx_cc26xx_subg_rx(dev); + (void)drv_start_rx(dev); } return ret; } @@ -531,7 +560,7 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_EventMask events; - int ret; + int ret = 0; if (mode != IEEE802154_TX_MODE_DIRECT) { /* For backwards compatibility we only log an error but do not bail. */ @@ -561,10 +590,12 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, drv_data->cmd_prop_tx_adv.pNextOp = NULL; /* Abort FG and BG processes */ - ret = ieee802154_cc13xx_cc26xx_subg_stop(dev); - if (ret < 0) { - ret = -EIO; - goto out; + if (drv_data->cmd_prop_rx_adv.status == ACTIVE) { + ret = drv_stop_rx(dev); + if (ret < 0) { + ret = -EIO; + goto out; + } } events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_prop_tx_adv, @@ -582,7 +613,7 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, } out: - (void)ieee802154_cc13xx_cc26xx_subg_rx(dev); + (void)drv_start_rx(dev); k_mutex_unlock(&drv_data->tx_mutex); return ret; } @@ -605,8 +636,7 @@ static int ieee802154_cc13xx_cc26xx_subg_attr_get(const struct device *dev, &drv_attr.phy_supported_channels, value); } -static void ieee802154_cc13xx_cc26xx_subg_rx_done( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) +static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { struct net_pkt *pkt; uint8_t len; @@ -675,14 +705,11 @@ static void ieee802154_cc13xx_cc26xx_subg_rx_done( static int ieee802154_cc13xx_cc26xx_subg_start(const struct device *dev) { - /* Start RX */ - return ieee802154_cc13xx_cc26xx_subg_rx(dev); + return drv_start_rx(dev); } -/** - * Flushes / stops all radio commands in RF queue. - */ -static int ieee802154_cc13xx_cc26xx_subg_stop(const struct device *dev) +/* Aborts all radio commands in the RF queue. */ +static int drv_abort_commands(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_Stat status; @@ -705,17 +732,14 @@ static int ieee802154_cc13xx_cc26xx_subg_stop(const struct device *dev) */ static int ieee802154_cc13xx_cc26xx_subg_stop_if(const struct device *dev) { - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; int ret; - ret = ieee802154_cc13xx_cc26xx_subg_stop(dev); + ret = drv_abort_commands(dev); if (ret < 0) { return ret; } - /* power down radio */ - RF_yield(drv_data->rf_handle); - return 0; + return drv_power_down(dev); } static int @@ -726,12 +750,11 @@ ieee802154_cc13xx_cc26xx_subg_configure(const struct device *dev, return -ENOTSUP; } -static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) +static void drv_setup_rx_buffers(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { - for (size_t i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; ++i) { - memset(&drv_data->rx_entry[i], 0, sizeof(drv_data->rx_entry[i])); + /* No need to zero buffers as they are zeroed on initialization. */ + for (size_t i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; ++i) { if (i < CC13XX_CC26XX_NUM_RX_BUF - 1) { drv_data->rx_entry[i].pNextEntry = (uint8_t *) &drv_data->rx_entry[i + 1]; @@ -750,8 +773,18 @@ static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers( drv_data->rx_queue.pLastEntry = NULL; } -static void ieee802154_cc13xx_cc26xx_subg_data_init( - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) +static void drv_setup_tx_buffer(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) +{ + /* No need to zero buffers as they are zeroed on initialization. */ + + /* Part of the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ + drv_data->tx_data[1] = BIT(3) | /* FCS Type: 2-octet FCS */ + BIT(4); /* DW: Enable Data Whitening */ + + drv_data->cmd_prop_tx_adv.pPkt = drv_data->tx_data; +} + +static void drv_data_init(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { uint8_t *mac; @@ -766,7 +799,10 @@ static void ieee802154_cc13xx_cc26xx_subg_data_init( sys_memcpy_swap(&drv_data->mac, mac, sizeof(drv_data->mac)); /* Setup circular RX queue (TRM 25.3.2.7) */ - ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers(drv_data); + drv_setup_rx_buffers(drv_data); + + /* Setup TX buffer (TRM 25.10.2.1.1, table 25-171) */ + drv_setup_tx_buffer(drv_data); k_mutex_init(&drv_data->tx_mutex); } @@ -807,7 +843,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; /* Initialize driver data */ - ieee802154_cc13xx_cc26xx_subg_data_init(drv_data); + drv_data_init(drv_data); /* Setup radio */ RF_Params_init(&rf_params); diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h index 2c150b4ebdb..8ca1949044f 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h @@ -53,6 +53,8 @@ struct ieee802154_cc13xx_cc26xx_subg_data { volatile rfc_CMD_PROP_TX_ADV_t cmd_prop_tx_adv; volatile rfc_propRxOutput_t cmd_prop_rx_adv_output; volatile rfc_CMD_PROP_CS_t cmd_prop_cs; + + RF_CmdHandle rx_cmd_handle; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_CC13XX_CC26XX_SUBG_H_ */ From 35cfe00e91f0409550b5793a88466f30c16db4cf Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 08:54:16 +0200 Subject: [PATCH 1677/4498] drivers: ieee802154: cc13xx_cc26xx_subg: remove redundant code Removes redunant reset statements that update immutable data. Signed-off-by: Florian Grandel --- .../ieee802154_cc13xx_cc26xx_subg.c | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index de5beb1ebea..c3c1753b8dc 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -372,8 +372,6 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) int ret; drv_data->cmd_prop_cs.status = IDLE; - drv_data->cmd_prop_cs.pNextOp = NULL; - drv_data->cmd_prop_cs.condition.rule = COND_NEVER; was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; if (was_rx_on) { @@ -569,25 +567,16 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, k_mutex_lock(&drv_data->tx_mutex, K_FOREVER); - /* Prepend data with the SUN FSK PHY header, - * see IEEE 802.15.4, section 19.2.4. - */ + /* Complete the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ drv_data->tx_data[0] = buf->len + IEEE802154_FCS_LENGTH; - drv_data->tx_data[1] = 0; - drv_data->tx_data[1] |= BIT(3); /* FCS Type: 2-octet FCS */ - drv_data->tx_data[1] |= BIT(4); /* DW: Enable Data Whitening */ - /* TODO: Zero-copy TX, see discussion in #49775. */ + /* Set TX data */ __ASSERT_NO_MSG(buf->len + IEEE802154_PHY_SUN_FSK_PHR_LEN <= CC13XX_CC26XX_TX_BUF_SIZE); + /* TODO: Zero-copy TX, see discussion in #49775. */ memcpy(&drv_data->tx_data[IEEE802154_PHY_SUN_FSK_PHR_LEN], buf->data, buf->len); - - /* Set TX data */ drv_data->cmd_prop_tx_adv.pktLen = buf->len + IEEE802154_PHY_SUN_FSK_PHR_LEN; - drv_data->cmd_prop_tx_adv.pPkt = drv_data->tx_data; - /* Reset command status */ drv_data->cmd_prop_tx_adv.status = IDLE; - drv_data->cmd_prop_tx_adv.pNextOp = NULL; /* Abort FG and BG processes */ if (drv_data->cmd_prop_rx_adv.status == ACTIVE) { @@ -863,12 +852,6 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) * If this is not done, then even CMD_ABORT fails. */ drv_data->cmd_fs.status = IDLE; - drv_data->cmd_fs.pNextOp = NULL; - drv_data->cmd_fs.condition.rule = COND_NEVER; - drv_data->cmd_fs.synthConf.bTxMode = false; - drv_data->cmd_fs.frequency = 0; - drv_data->cmd_fs.fractFreq = 0; - events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs, RF_PriorityNormal, NULL, 0); if (events != RF_EventLastCmdDone) { @@ -919,12 +902,13 @@ static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_d .cmd_prop_rx_adv_output, }, - /* TODO: Support correlation CCA modes, see section 10.2.8. */ .cmd_prop_cs = { .commandNo = CMD_PROP_CS, .condition.rule = COND_NEVER, .csConf = { - /* CCA Mode 1: Energy above threshold, see section 10.2.8. */ + /* CCA Mode 1: Energy above threshold, see section 10.2.8. + * CC13/26xx SubG does not support correlation mode. + */ .bEnaRssi = true, /* Abort as soon as any energy above the ED threshold is detected. */ .busyOp = true, @@ -949,7 +933,8 @@ static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_d .pktConf.bUseCrc = true, /* PHR field format, see IEEE 802.15.4, section 19.2.4 */ .numHdrBits = 16, - .preTrigger.triggerType = TRIG_REL_START, + .preTrigger.triggerType = + TRIG_REL_START, /* workaround for CC13_RF_ROM_FW_CPE--BUG00016 */ .preTrigger.pastTrig = true, /* Last preamble byte and SFD for uncoded 2-FSK SUN PHY, phySunFskSfd = 0, * see IEEE 802.15.4, section 19.2.3.2, table 19-2. From 26a0ef15c41430446221596c14b7946c94e30806 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 09:01:58 +0200 Subject: [PATCH 1678/4498] drivers: ieee802154: cc13xx_cc26xx_subg: check for RX up Checks whether the receiver is already on before trying to switch it on. This also closes a gap wrt the driver API specification. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index c3c1753b8dc..0d0f091e181 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -423,6 +423,10 @@ static int drv_start_rx(const struct device *dev) struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_CmdHandle cmd_handle; + if (drv_data->cmd_prop_rx_adv.status == ACTIVE) { + return -EALREADY; + } + #ifdef CONFIG_ASSERT if (CONFIG_ASSERT_LEVEL > 0) { /* ensure that all RX buffers are initialized and pending. */ From 016d3bed5c054de7e34cd834be0999ca159b84e3 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 09:14:00 +0200 Subject: [PATCH 1679/4498] drivers: ieee802154: cc13xx_cc26xx_subg: improve locking Replaces the mutex by a semaphore for ISR readiness as requested by the driver API specification. Signed-off-by: Florian Grandel --- .../ieee802154_cc13xx_cc26xx_subg.c | 61 ++++++++++++++----- .../ieee802154_cc13xx_cc26xx_subg.h | 5 +- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 0d0f091e181..59d57ec9905 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -242,6 +242,8 @@ static const RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[] = { }; #endif /* CONFIG_SOC_CC1352x power table */ +#define LOCK_TIMEOUT (k_is_in_isr() ? K_NO_WAIT : K_FOREVER) + /** RF patches to use (note: RF core keeps a pointer to this, so no stack). */ static RF_Mode rf_mode = { .rfMode = RF_MODE_MULTIPLE, @@ -315,6 +317,7 @@ static void cmd_prop_tx_adv_callback(RF_Handle h, RF_CmdHandle ch, struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_Op *op = RF_getCmdOp(h, ch); + /* No need for locking as the RX status is volatile and there's no race. */ LOG_DBG("ch: %u cmd: %04x cs st: %04x tx st: %04x e: 0x%" PRIx64, ch, op->commandNo, op->status, drv_data->cmd_prop_tx_adv.status, e); } @@ -337,8 +340,14 @@ static void cmd_prop_rx_adv_callback(RF_Handle h, RF_CmdHandle ch, || op->status == PROP_ERROR_RXFULL || op->status == PROP_ERROR_RXOVF) { LOG_DBG("RX Error %x", op->status); + /* Restart RX */ + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return; + } + (void)drv_start_rx(dev); + k_sem_give(&drv_data->lock); } } @@ -371,6 +380,10 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) bool was_rx_on; int ret; + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return -EWOULDBLOCK; + } + drv_data->cmd_prop_cs.status = IDLE; was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; @@ -396,7 +409,8 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) * this usually means we want to TX directly after * and cannot afford any extra latency. */ - return 0; + ret = 0; + break; case PROP_DONE_BUSY: case PROP_DONE_BUSYTIMEOUT: ret = -EBUSY; @@ -412,12 +426,15 @@ static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) * and want to be able to receive packets in * the meantime. */ - if (was_rx_on) { + if (ret && was_rx_on) { drv_start_rx(dev); } + + k_sem_give(&drv_data->lock); return ret; } +/* This method must be called with the lock held. */ static int drv_start_rx(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; @@ -451,6 +468,7 @@ static int drv_start_rx(const struct device *dev) return 0; } +/* This method must be called with the lock held. */ static int drv_stop_rx(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; @@ -485,6 +503,10 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( return ret; } + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return -EWOULDBLOCK; + } + /* Abort FG and BG processes */ was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; if (was_rx_on) { @@ -495,9 +517,6 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( } } - /* Block TX while changing channel */ - k_mutex_lock(&drv_data->tx_mutex, K_FOREVER); - /* Set the frequency */ drv_data->cmd_fs.status = IDLE; drv_data->cmd_fs.frequency = freq; @@ -509,13 +528,14 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( ret = -EIO; } - k_mutex_unlock(&drv_data->tx_mutex); - out: /* Re-enable RX if we found it on initially. */ if (was_rx_on) { (void)drv_start_rx(dev); } + + k_sem_give(&drv_data->lock); + return ret; } @@ -545,6 +565,7 @@ static int ieee802154_cc13xx_cc26xx_subg_set_txpower( return -EINVAL; } + /* No need for locking: rf_handle is immutable after initialization. */ status = RF_setTxPower(drv_data->rf_handle, power_table_value); if (status != RF_StatSuccess) { LOG_DBG("RF_setTxPower() failed: %d", status); @@ -569,7 +590,9 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, NET_ERR("TX mode %d not supported - sending directly instead.", mode); } - k_mutex_lock(&drv_data->tx_mutex, K_FOREVER); + if (k_sem_take(&drv_data->lock, K_FOREVER)) { + return -EIO; + } /* Complete the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ drv_data->tx_data[0] = buf->len + IEEE802154_FCS_LENGTH; @@ -602,12 +625,11 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, if (drv_data->cmd_prop_tx_adv.status != PROP_DONE_OK) { LOG_DBG("Transmit failed (0x%x)", drv_data->cmd_prop_tx_adv.status); ret = -EIO; - goto out; } out: (void)drv_start_rx(dev); - k_mutex_unlock(&drv_data->tx_mutex); + k_sem_give(&drv_data->lock); return ret; } @@ -636,6 +658,11 @@ static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) int8_t rssi, status; uint8_t *sdu; + /* No need for locking as only immutable data is accessed from drv_data. + * The rx queue itself (entries and data) are managed and protected + * internally by TI's RF driver. + */ + for (int i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; i++) { if (drv_data->rx_entry[i].status == DATA_ENTRY_FINISHED) { len = drv_data->rx_data[i][0]; @@ -701,7 +728,7 @@ static int ieee802154_cc13xx_cc26xx_subg_start(const struct device *dev) return drv_start_rx(dev); } -/* Aborts all radio commands in the RF queue. */ +/* Aborts all radio commands in the RF queue. Requires the lock to be held. */ static int drv_abort_commands(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; @@ -745,7 +772,9 @@ ieee802154_cc13xx_cc26xx_subg_configure(const struct device *dev, static void drv_setup_rx_buffers(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { - /* No need to zero buffers as they are zeroed on initialization. */ + /* No need to zero buffers as they are zeroed on initialization and no + * need for locking as initialization is done with exclusive access. + */ for (size_t i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; ++i) { if (i < CC13XX_CC26XX_NUM_RX_BUF - 1) { @@ -768,7 +797,9 @@ static void drv_setup_rx_buffers(struct ieee802154_cc13xx_cc26xx_subg_data *drv_ static void drv_setup_tx_buffer(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { - /* No need to zero buffers as they are zeroed on initialization. */ + /* No need to zero buffers as they are zeroed on initialization and no + * need for locking as initialization is done with exclusive access. + */ /* Part of the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ drv_data->tx_data[1] = BIT(3) | /* FCS Type: 2-octet FCS */ @@ -797,7 +828,7 @@ static void drv_data_init(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) /* Setup TX buffer (TRM 25.10.2.1.1, table 25-171) */ drv_setup_tx_buffer(drv_data); - k_mutex_init(&drv_data->tx_mutex); + k_sem_init(&drv_data->lock, 1, 1); } static void ieee802154_cc13xx_cc26xx_subg_iface_init(struct net_if *iface) @@ -835,6 +866,8 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) RF_EventMask events; struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + /* No need for locking - initialization is exclusive. */ + /* Initialize driver data */ drv_data_init(drv_data); diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h index 8ca1949044f..d2fb68832d1 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h @@ -32,14 +32,15 @@ #define CC13XX_CC26XX_INVALID_RSSI INT8_MIN struct ieee802154_cc13xx_cc26xx_subg_data { + /* protects writable data and serializes access to the API */ + struct k_sem lock; + RF_Handle rf_handle; RF_Object rf_object; struct net_if *iface; uint8_t mac[8]; /* in big endian */ - struct k_mutex tx_mutex; - dataQueue_t rx_queue; rfc_dataEntryPointer_t rx_entry[CC13XX_CC26XX_NUM_RX_BUF]; uint8_t rx_data[CC13XX_CC26XX_NUM_RX_BUF][CC13XX_CC26XX_RX_BUF_SIZE]; From fce4788415666a038f3c32ab55df215a4f71f20f Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 29 Sep 2023 09:17:00 +0200 Subject: [PATCH 1680/4498] drivers: ieee802154: cc13xx_cc26xx_subg: fix oper. state The driver API now distinguishes between operational UP/DOWN states as required by Zephyr's network API and receiver on/off states as an internal driver state for improved standard conformance. This change closes the gap between the driver API requirements and the implementation in this respect. Signed-off-by: Florian Grandel --- .../ieee802154_cc13xx_cc26xx_subg.c | 111 ++++++++++++++---- .../ieee802154_cc13xx_cc26xx_subg.h | 2 + 2 files changed, 88 insertions(+), 25 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 59d57ec9905..e123c9649ac 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -376,20 +376,25 @@ ieee802154_cc13xx_cc26xx_subg_get_capabilities(const struct device *dev) static int ieee802154_cc13xx_cc26xx_subg_cca(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + bool was_rx_on = false; RF_EventMask events; - bool was_rx_on; int ret; if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { return -EWOULDBLOCK; } + if (!drv_data->is_up) { + ret = -ENETDOWN; + goto out; + } + drv_data->cmd_prop_cs.status = IDLE; was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; if (was_rx_on) { ret = drv_stop_rx(dev); - if (ret < 0) { + if (ret) { ret = -EIO; goto out; } @@ -493,8 +498,8 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( const struct device *dev, uint16_t channel) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; - RF_EventMask events; uint16_t freq, fract; + RF_EventMask events; bool was_rx_on; int ret; @@ -507,7 +512,6 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( return -EWOULDBLOCK; } - /* Abort FG and BG processes */ was_rx_on = drv_data->cmd_prop_rx_adv.status == ACTIVE; if (was_rx_on) { ret = drv_stop_rx(dev); @@ -529,9 +533,11 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( } out: - /* Re-enable RX if we found it on initially. */ if (was_rx_on) { + /* Re-enable RX if we found it on initially. */ (void)drv_start_rx(dev); + } else if (!drv_data->is_up) { + ret = drv_power_down(dev); } k_sem_give(&drv_data->lock); @@ -555,11 +561,12 @@ static int ieee802154_cc13xx_cc26xx_subg_set_txpower( const struct device *dev, int16_t dbm) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + RF_TxPowerTable_Value power_table_value; RF_Stat status; + int ret = 0; - RF_TxPowerTable_Value power_table_value = RF_TxPowerTable_findValue( + power_table_value = RF_TxPowerTable_findValue( (RF_TxPowerTable_Entry *)ieee802154_cc13xx_subg_power_table, dbm); - if (power_table_value.rawValue == RF_TxPowerTable_INVALID_VALUE) { LOG_DBG("RF_TxPowerTable_findValue() failed"); return -EINVAL; @@ -572,7 +579,17 @@ static int ieee802154_cc13xx_cc26xx_subg_set_txpower( return -EIO; } - return 0; + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return -EWOULDBLOCK; + } + + if (!drv_data->is_up) { + ret = drv_power_down(dev); + } + + k_sem_give(&drv_data->lock); + + return ret; } /* See IEEE 802.15.4 section 6.7.1 and TRM section 25.5.4.3 */ @@ -594,6 +611,19 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, return -EIO; } + if (!drv_data->is_up) { + ret = -ENETDOWN; + goto out; + } + + if (drv_data->cmd_prop_rx_adv.status == ACTIVE) { + ret = drv_stop_rx(dev); + if (ret) { + ret = -EIO; + goto out; + } + } + /* Complete the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ drv_data->tx_data[0] = buf->len + IEEE802154_FCS_LENGTH; @@ -604,16 +634,6 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, drv_data->cmd_prop_tx_adv.pktLen = buf->len + IEEE802154_PHY_SUN_FSK_PHR_LEN; drv_data->cmd_prop_tx_adv.status = IDLE; - - /* Abort FG and BG processes */ - if (drv_data->cmd_prop_rx_adv.status == ACTIVE) { - ret = drv_stop_rx(dev); - if (ret < 0) { - ret = -EIO; - goto out; - } - } - events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_prop_tx_adv, RF_PriorityNormal, cmd_prop_tx_adv_callback, RF_EventLastCmdDone); if ((events & RF_EventLastCmdDone) == 0) { @@ -629,6 +649,7 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, out: (void)drv_start_rx(dev); + k_sem_give(&drv_data->lock); return ret; } @@ -653,9 +674,9 @@ static int ieee802154_cc13xx_cc26xx_subg_attr_get(const struct device *dev, static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) { + int8_t rssi, status; struct net_pkt *pkt; uint8_t len; - int8_t rssi, status; uint8_t *sdu; /* No need for locking as only immutable data is accessed from drv_data. @@ -725,7 +746,28 @@ static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) static int ieee802154_cc13xx_cc26xx_subg_start(const struct device *dev) { - return drv_start_rx(dev); + struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + int ret; + + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return -EIO; + } + + if (drv_data->is_up) { + ret = -EALREADY; + goto out; + } + + ret = drv_start_rx(dev); + if (ret) { + goto out; + } + + drv_data->is_up = true; + +out: + k_sem_give(&drv_data->lock); + return ret; } /* Aborts all radio commands in the RF queue. Requires the lock to be held. */ @@ -752,14 +794,33 @@ static int drv_abort_commands(const struct device *dev) */ static int ieee802154_cc13xx_cc26xx_subg_stop_if(const struct device *dev) { + struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; int ret; + if (k_sem_take(&drv_data->lock, LOCK_TIMEOUT)) { + return -EIO; + } + + if (!drv_data->is_up) { + ret = -EALREADY; + goto out; + } + ret = drv_abort_commands(dev); - if (ret < 0) { - return ret; + if (ret) { + goto out; } - return drv_power_down(dev); + ret = drv_power_down(dev); + if (ret) { + goto out; + } + + drv_data->is_up = false; + + out: + k_sem_give(&drv_data->lock); + return ret; } static int @@ -862,9 +923,9 @@ static struct ieee802154_radio_api static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) { + struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; RF_Params rf_params; RF_EventMask events; - struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; /* No need for locking - initialization is exclusive. */ @@ -896,7 +957,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) return -EIO; } - return 0; + return drv_power_down(dev); } static struct ieee802154_cc13xx_cc26xx_subg_data ieee802154_cc13xx_cc26xx_subg_data = { diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h index d2fb68832d1..bae259b1983 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.h @@ -41,6 +41,8 @@ struct ieee802154_cc13xx_cc26xx_subg_data { struct net_if *iface; uint8_t mac[8]; /* in big endian */ + bool is_up; + dataQueue_t rx_queue; rfc_dataEntryPointer_t rx_entry[CC13XX_CC26XX_NUM_RX_BUF]; uint8_t rx_data[CC13XX_CC26XX_NUM_RX_BUF][CC13XX_CC26XX_RX_BUF_SIZE]; From 0c1c443fc619d3a1e12918e210bbb8ecda09cc82 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 7 Sep 2023 13:30:24 +0200 Subject: [PATCH 1681/4498] drivers: ieee802154: cc13xx_cc26xx_subg: improve readability Moves the RX callback closer to where it's actually being used also removing the necessity to declare a function prototype. Signed-off-by: Florian Grandel --- .../ieee802154_cc13xx_cc26xx_subg.c | 145 +++++++++--------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index e123c9649ac..6e10a630019 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -35,7 +35,6 @@ LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx_subg); static int drv_start_rx(const struct device *dev); static int drv_stop_rx(const struct device *dev); -static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data); #ifndef CMD_PROP_RADIO_DIV_SETUP_PA /* workaround for older HAL TI SDK (less than 4.40) */ @@ -322,6 +321,78 @@ static void cmd_prop_tx_adv_callback(RF_Handle h, RF_CmdHandle ch, op->commandNo, op->status, drv_data->cmd_prop_tx_adv.status, e); } +static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) +{ + int8_t rssi, status; + struct net_pkt *pkt; + uint8_t len; + uint8_t *sdu; + + /* No need for locking as only immutable data is accessed from drv_data. + * The rx queue itself (entries and data) are managed and protected + * internally by TI's RF driver. + */ + + for (int i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; i++) { + if (drv_data->rx_entry[i].status == DATA_ENTRY_FINISHED) { + len = drv_data->rx_data[i][0]; + sdu = drv_data->rx_data[i] + 1; + status = drv_data->rx_data[i][len--]; + rssi = drv_data->rx_data[i][len--]; + + /* TODO: Configure firmware to include CRC in raw mode. */ + if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && len > 0) { + /* append CRC-16/CCITT */ + uint16_t crc = 0; + + crc = crc16_ccitt(0, sdu, len); + sdu[len++] = crc; + sdu[len++] = crc >> 8; + } + + LOG_DBG("Received: len = %u, rssi = %d status = %u", + len, rssi, status); + + pkt = net_pkt_rx_alloc_with_buffer( + drv_data->iface, len, AF_UNSPEC, 0, K_NO_WAIT); + if (!pkt) { + LOG_WRN("Cannot allocate packet"); + continue; + } + + if (net_pkt_write(pkt, sdu, len)) { + LOG_WRN("Cannot write packet"); + net_pkt_unref(pkt); + continue; + } + + drv_data->rx_entry[i].status = DATA_ENTRY_PENDING; + + /* TODO: Determine LQI in PROP mode. */ + net_pkt_set_ieee802154_lqi(pkt, 0xff); + net_pkt_set_ieee802154_rssi_dbm(pkt, + rssi == CC13XX_CC26XX_INVALID_RSSI + ? IEEE802154_MAC_RSSI_DBM_UNDEFINED + : rssi); + + if (ieee802154_handle_ack(drv_data->iface, pkt) == NET_OK) { + net_pkt_unref(pkt); + continue; + } + + if (net_recv_data(drv_data->iface, pkt)) { + LOG_WRN("Packet dropped"); + net_pkt_unref(pkt); + } + + } else if (drv_data->rx_entry[i].status == + DATA_ENTRY_UNFINISHED) { + LOG_WRN("Frame not finished"); + drv_data->rx_entry[i].status = DATA_ENTRY_PENDING; + } + } +} + static void cmd_prop_rx_adv_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { @@ -672,78 +743,6 @@ static int ieee802154_cc13xx_cc26xx_subg_attr_get(const struct device *dev, &drv_attr.phy_supported_channels, value); } -static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) -{ - int8_t rssi, status; - struct net_pkt *pkt; - uint8_t len; - uint8_t *sdu; - - /* No need for locking as only immutable data is accessed from drv_data. - * The rx queue itself (entries and data) are managed and protected - * internally by TI's RF driver. - */ - - for (int i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; i++) { - if (drv_data->rx_entry[i].status == DATA_ENTRY_FINISHED) { - len = drv_data->rx_data[i][0]; - sdu = drv_data->rx_data[i] + 1; - status = drv_data->rx_data[i][len--]; - rssi = drv_data->rx_data[i][len--]; - - /* TODO: Configure firmware to include CRC in raw mode. */ - if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && len > 0) { - /* append CRC-16/CCITT */ - uint16_t crc = 0; - - crc = crc16_ccitt(0, sdu, len); - sdu[len++] = crc; - sdu[len++] = crc >> 8; - } - - LOG_DBG("Received: len = %u, rssi = %d status = %u", - len, rssi, status); - - pkt = net_pkt_rx_alloc_with_buffer( - drv_data->iface, len, AF_UNSPEC, 0, K_NO_WAIT); - if (!pkt) { - LOG_WRN("Cannot allocate packet"); - continue; - } - - if (net_pkt_write(pkt, sdu, len)) { - LOG_WRN("Cannot write packet"); - net_pkt_unref(pkt); - continue; - } - - drv_data->rx_entry[i].status = DATA_ENTRY_PENDING; - - /* TODO: Determine LQI in PROP mode. */ - net_pkt_set_ieee802154_lqi(pkt, 0xff); - net_pkt_set_ieee802154_rssi_dbm(pkt, - rssi == CC13XX_CC26XX_INVALID_RSSI - ? IEEE802154_MAC_RSSI_DBM_UNDEFINED - : rssi); - - if (ieee802154_handle_ack(drv_data->iface, pkt) == NET_OK) { - net_pkt_unref(pkt); - continue; - } - - if (net_recv_data(drv_data->iface, pkt)) { - LOG_WRN("Packet dropped"); - net_pkt_unref(pkt); - } - - } else if (drv_data->rx_entry[i].status == - DATA_ENTRY_UNFINISHED) { - LOG_WRN("Frame not finished"); - drv_data->rx_entry[i].status = DATA_ENTRY_PENDING; - } - } -} - static int ieee802154_cc13xx_cc26xx_subg_start(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; From f2979edd5c2bb5c61b5f7911b13e7c5aed9ac9c4 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 7 Sep 2023 13:56:32 +0200 Subject: [PATCH 1682/4498] drivers: ieee802154: cc13xx_cc26xx_subg: fix initial CMD_FS The frequency synchronization command requires a proper frequency to be set in order to be successfully executed. The command not being executed leads to unnecessary internal error handling wrt command scheduling. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 6e10a630019..35255fcbb85 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -923,6 +923,7 @@ static struct ieee802154_radio_api static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) { struct ieee802154_cc13xx_cc26xx_subg_data *drv_data = dev->data; + uint16_t freq, fract; RF_Params rf_params; RF_EventMask events; @@ -944,11 +945,13 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) return -EIO; } - /* Run CMD_FS with frequency 0 to ensure RF_currClient is not NULL. - * RF_currClient is a static variable in the TI RF Driver library. - * If this is not done, then even CMD_ABORT fails. + /* Run CMD_FS for channel 0 to place a valid CMD_FS command in the + * driver's internal state which it requires for proper operation. */ + (void)drv_channel_frequency(0, &freq, &fract); drv_data->cmd_fs.status = IDLE; + drv_data->cmd_fs.frequency = freq; + drv_data->cmd_fs.fractFreq = fract; events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs, RF_PriorityNormal, NULL, 0); if (events != RF_EventLastCmdDone) { From 4b0e730fb17a33b5cbb0b29f2d201eafb3a484bd Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 7 Sep 2023 13:54:42 +0200 Subject: [PATCH 1683/4498] drivers: ieee802154: cc13xx_cc26xx_subg: check radio op status Not only the return code of TI's RF command queueing mechanism but also the command status need to be checked to assert that a command was executed successfully. This change introduces additional checking of the command status. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 35255fcbb85..9aba1a35166 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -598,7 +598,7 @@ static int ieee802154_cc13xx_cc26xx_subg_set_channel( drv_data->cmd_fs.fractFreq = fract; events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs, RF_PriorityNormal, NULL, 0); - if (events != RF_EventLastCmdDone) { + if (events != RF_EventLastCmdDone || drv_data->cmd_fs.status != DONE_OK) { LOG_DBG("Failed to set frequency: 0x%" PRIx64, events); ret = -EIO; } @@ -954,7 +954,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) drv_data->cmd_fs.fractFreq = fract; events = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs, RF_PriorityNormal, NULL, 0); - if (events != RF_EventLastCmdDone) { + if (events != RF_EventLastCmdDone || drv_data->cmd_fs.status != DONE_OK) { LOG_ERR("Failed to set frequency: 0x%" PRIx64, events); return -EIO; } From 2445e55cd4ddaa2b3863bdedb4dca520a93e1b93 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 4 Oct 2023 15:29:10 +0200 Subject: [PATCH 1684/4498] tests: bluetooth: tester: Move bt_mesh_init call to BTP_MESH_INIT cmd In some RPR tests we need to pass alternative composition data when testing CDP128. When bt_mesh_init is called from mesh service registration callback, we can't pass any arguments. Therefore we need to move bt_mesh_init call out from mesh service registration to BTP_MESH_INIT command. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp/btp_mesh.h | 4 +++ tests/bluetooth/tester/src/btp_mesh.c | 32 ++++++++++++----------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 826f0fd0408..bb26524246e 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -77,6 +77,10 @@ struct btp_mesh_provision_node_cmd_v2 { } __packed; #define BTP_MESH_INIT 0x04 +struct btp_mesh_init_cmd { + bool comp_alt; +} __packed; + #define BTP_MESH_RESET 0x05 #define BTP_MESH_INPUT_NUMBER 0x06 struct btp_mesh_input_number_cmd { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 44ace086c69..6a180fcb6d1 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1242,8 +1242,24 @@ static uint8_t provision_adv(const void *cmd, uint16_t cmd_len, static uint8_t init(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { + const struct btp_mesh_init_cmd *cp = cmd; int err; + if (!cp->comp_alt) { + LOG_WRN("Loading default comp data"); + err = bt_mesh_init(&prov, &comp); + } else { + LOG_WRN("Loading alternative comp data"); +#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV + health_srv.metadata = health_srv_meta_alt; +#endif + err = bt_mesh_init(&prov, &comp_alt); + } + + if (err) { + return BTP_STATUS_FAILED; + } + LOG_DBG(""); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { @@ -4403,7 +4419,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_INIT, - .expect_len = 0, + .expect_len = sizeof(struct btp_mesh_init_cmd), .func = init, }, { @@ -5208,26 +5224,12 @@ BT_MESH_LPN_CB_DEFINE(lpn_cb) = { uint8_t tester_init_mesh(void) { - int err; - if (IS_ENABLED(CONFIG_BT_TESTING)) { bt_test_cb_register(&bt_test_cb); } tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); - if (default_comp) { - err = bt_mesh_init(&prov, &comp); - } else { -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV - health_srv.metadata = health_srv_meta_alt; -#endif - err = bt_mesh_init(&prov, &comp_alt); - } - - if (err) { - return BTP_STATUS_FAILED; - } return BTP_STATUS_SUCCESS; } From bd82ff245a92ea15a4d938621c4c977d11c07177 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 4 Oct 2023 15:32:28 +0200 Subject: [PATCH 1685/4498] tests: bluetooth: tester: Remove comp_alt_set command Remove this command as composition can only be set in bt_mesh_init call which is called before settings are loaded. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 - tests/bluetooth/tester/src/btp_mesh.c | 48 ----------------------- 2 files changed, 50 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bb26524246e..6b58d1515dc 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -849,8 +849,6 @@ struct btp_mesh_opcodes_aggregator_init_cmd { #define BTP_MESH_COMP_CHANGE_PREPARE 0x57 -#define BTP_MESH_SET_COMP_ALT 0x58 - #define BTP_MESH_RPR_SCAN_START 0x59 struct btp_rpr_scan_start_cmd { uint16_t dst; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 6a180fcb6d1..083d2987150 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -318,8 +318,6 @@ static struct { .dst = BT_MESH_ADDR_UNASSIGNED, }; -static bool default_comp = true; - static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1889,47 +1887,6 @@ static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#if IS_ENABLED(CONFIG_BT_SETTINGS) -static int comp_alt_set(const char *name, size_t len_rd, - settings_read_cb read_cb, void *store) -{ - ssize_t len; - bool alt_comp_value; - - if (len_rd == 0) { - LOG_DBG("Default composition"); - } - - len = read_cb(store, &alt_comp_value, sizeof(alt_comp_value)); - if (len < 0 || len != len_rd) { - LOG_ERR("Failed to read value (err %zd)", len); - return len; - } - - if (alt_comp_value) { - default_comp = false; - } - - return 0; -} - -SETTINGS_STATIC_HANDLER_DEFINE(tester_comp_alt, "tester/comp_alt", NULL, comp_alt_set, NULL, NULL); -#endif - -static uint8_t set_comp_alt(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ -#if !IS_ENABLED(CONFIG_BT_SETTINGS) - return BTP_STATUS_FAILED; -#else - bool comp_alt_val = true; - - settings_save_one("tester/comp_alt", &comp_alt_val, sizeof(comp_alt_val)); - - return BTP_STATUS_SUCCESS; -#endif -} - static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -4847,11 +4804,6 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = change_prepare }, - { - .opcode = BTP_MESH_SET_COMP_ALT, - .expect_len = 0, - .func = set_comp_alt - }, #if defined(CONFIG_BT_MESH_RPR_CLI) { .opcode = BTP_MESH_RPR_SCAN_START, From 2a2d032341376312fd0ffc99cd0fc0f673f38a05 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 8 Aug 2023 21:52:54 -0700 Subject: [PATCH 1686/4498] modules: hal_ethos_u: ethosu_log depends on stdout console ethosu_log.h uses the stdout as it's stream for printf. This could cause an issue where if CONFIG_LOG=n and CONFIG_CONSOLE=y then there would be no way to control the log level and it would default to debug level. There is no NONE option as with the way the ethos-u hal is set up with no way to go below the err level. Signed-off-by: Ryan McClelland --- modules/hal_ethos_u/Kconfig | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/modules/hal_ethos_u/Kconfig b/modules/hal_ethos_u/Kconfig index 4a270cabbdc..bfed9b94d82 100644 --- a/modules/hal_ethos_u/Kconfig +++ b/modules/hal_ethos_u/Kconfig @@ -40,6 +40,32 @@ config ARM_ETHOS_U_NPU_NAME help Name of the used Arm NPU -module = ARM_ETHOS_U -module-str = arm_ethos_u -source "subsys/logging/Kconfig.template.log_config" +choice "ARM_ETHOS_U_LOG_LEVEL_CHOICE" + prompt "Max compiled-in log level for arm_ethos_u" + default ARM_ETHOS_U_LOG_LEVEL_WRN + depends on STDOUT_CONSOLE + +config ARM_ETHOS_U_LOG_LEVEL_ERR + bool "Error" + +config ARM_ETHOS_U_LOG_LEVEL_WRN + bool "Warning" + +config ARM_ETHOS_U_LOG_LEVEL_INF + bool "Info" + +config ARM_ETHOS_U_LOG_LEVEL_DBG + bool "Debug" + +config ARM_ETHOS_U_LOG_LEVEL_DEFAULT + bool "Default" + +endchoice + +config ARM_ETHOS_U_LOG_LEVEL + int + depends on STDOUT_CONSOLE + default 1 if ARM_ETHOS_U_LOG_LEVEL_ERR + default 2 if ARM_ETHOS_U_LOG_LEVEL_WRN + default 3 if ARM_ETHOS_U_LOG_LEVEL_INF + default 4 if ARM_ETHOS_U_LOG_LEVEL_DBG From deac568b188a0bc193c2d62f8d2aba29b27571e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stasys=20Au=C5=BEbikas?= Date: Wed, 4 Oct 2023 21:45:56 +0300 Subject: [PATCH 1687/4498] mgmt: mcumgr: transport: dummy: Fix truncating uint16_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `smp_send_pos` is 16 bits wide but it was being passed as uint8_t, thus truncating. This made it impossible to receive packets larger than 256 bytes. Signed-off-by: Stasys Aužbikas --- subsys/mgmt/mcumgr/transport/src/smp_dummy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/mgmt/mcumgr/transport/src/smp_dummy.c b/subsys/mgmt/mcumgr/transport/src/smp_dummy.c index fc34fb05939..e0033cc0d2c 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_dummy.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_dummy.c @@ -65,7 +65,7 @@ static struct net_buf *mcumgr_dummy_process_frag( static struct net_buf *mcumgr_dummy_process_frag_outgoing( struct mcumgr_serial_rx_ctxt *tx_ctxt, - const uint8_t *frag, int frag_len); + const uint8_t *frag, uint16_t frag_len); static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb); @@ -113,7 +113,7 @@ static void smp_dummy_process_frag(struct uart_mcumgr_rx_buf *rx_buf) * used in tests */ static struct net_buf *smp_dummy_process_frag_outgoing(uint8_t *buffer, - uint8_t buffer_size) + uint16_t buffer_size) { struct net_buf *nb; @@ -441,7 +441,7 @@ static struct net_buf *mcumgr_dummy_process_frag( */ static struct net_buf *mcumgr_dummy_process_frag_outgoing( struct mcumgr_serial_rx_ctxt *tx_ctxt, - const uint8_t *frag, int frag_len) + const uint8_t *frag, uint16_t frag_len) { struct net_buf *nb; uint16_t crc; From 0722c621c85565797242fbd3685f4d5cf51ecaff Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 4 Oct 2023 15:05:58 +0800 Subject: [PATCH 1688/4498] util: increase several macros limit from 255 to 4095 Currently, the following macros will only work for 0 - 255: - `IS_EQ` - `UTIL_X2` - `UTIL_INC` - `UTIL_DEC` - `LISTIFY` This patch increases their limit to 4095. Signed-off-by: Yong Cong Sin --- include/zephyr/sys/util_internal.h | 1033 +- include/zephyr/sys/util_internal_is_eq.h | 4114 +++++ include/zephyr/sys/util_internal_util_dec.h | 4122 +++++ include/zephyr/sys/util_internal_util_inc.h | 4122 +++++ include/zephyr/sys/util_internal_util_x2.h | 4121 +++++ include/zephyr/sys/util_listify.h | 16400 ++++++++++++++++++ include/zephyr/sys/util_loops.h | 1025 +- include/zephyr/sys/util_macro.h | 16 +- scripts/utils/gen_util_macros.py | 163 + 9 files changed, 33059 insertions(+), 2057 deletions(-) create mode 100644 include/zephyr/sys/util_internal_is_eq.h create mode 100644 include/zephyr/sys/util_internal_util_dec.h create mode 100644 include/zephyr/sys/util_internal_util_inc.h create mode 100644 include/zephyr/sys/util_internal_util_x2.h create mode 100644 include/zephyr/sys/util_listify.h create mode 100644 scripts/utils/gen_util_macros.py diff --git a/include/zephyr/sys/util_internal.h b/include/zephyr/sys/util_internal.h index 7850886b54b..2cde08332e2 100644 --- a/include/zephyr/sys/util_internal.h +++ b/include/zephyr/sys/util_internal.h @@ -50,7 +50,7 @@ #define Z_IS_ENABLED3(ignore_this, val, ...) val /* Implementation of IS_EQ(). Returns 1 if _0 and _1 are the same integer from - * 0 to 255, 0 otherwise. + * 0 to 4095, 0 otherwise. */ #define Z_IS_EQ(_0, _1) Z_HAS_COMMA(Z_CAT4(Z_IS_, _0, _EQ_, _1)()) @@ -150,262 +150,7 @@ #define MACRO_MC_15(m, a, ...) UTIL_CAT(m(a), MACRO_MC_14(m, __VA_ARGS__,)) /* Used by Z_IS_EQ */ -#define Z_IS_0_EQ_0(...) \, -#define Z_IS_1_EQ_1(...) \, -#define Z_IS_2_EQ_2(...) \, -#define Z_IS_3_EQ_3(...) \, -#define Z_IS_4_EQ_4(...) \, -#define Z_IS_5_EQ_5(...) \, -#define Z_IS_6_EQ_6(...) \, -#define Z_IS_7_EQ_7(...) \, -#define Z_IS_8_EQ_8(...) \, -#define Z_IS_9_EQ_9(...) \, -#define Z_IS_10_EQ_10(...) \, -#define Z_IS_11_EQ_11(...) \, -#define Z_IS_12_EQ_12(...) \, -#define Z_IS_13_EQ_13(...) \, -#define Z_IS_14_EQ_14(...) \, -#define Z_IS_15_EQ_15(...) \, -#define Z_IS_16_EQ_16(...) \, -#define Z_IS_17_EQ_17(...) \, -#define Z_IS_18_EQ_18(...) \, -#define Z_IS_19_EQ_19(...) \, -#define Z_IS_20_EQ_20(...) \, -#define Z_IS_21_EQ_21(...) \, -#define Z_IS_22_EQ_22(...) \, -#define Z_IS_23_EQ_23(...) \, -#define Z_IS_24_EQ_24(...) \, -#define Z_IS_25_EQ_25(...) \, -#define Z_IS_26_EQ_26(...) \, -#define Z_IS_27_EQ_27(...) \, -#define Z_IS_28_EQ_28(...) \, -#define Z_IS_29_EQ_29(...) \, -#define Z_IS_30_EQ_30(...) \, -#define Z_IS_31_EQ_31(...) \, -#define Z_IS_32_EQ_32(...) \, -#define Z_IS_33_EQ_33(...) \, -#define Z_IS_34_EQ_34(...) \, -#define Z_IS_35_EQ_35(...) \, -#define Z_IS_36_EQ_36(...) \, -#define Z_IS_37_EQ_37(...) \, -#define Z_IS_38_EQ_38(...) \, -#define Z_IS_39_EQ_39(...) \, -#define Z_IS_40_EQ_40(...) \, -#define Z_IS_41_EQ_41(...) \, -#define Z_IS_42_EQ_42(...) \, -#define Z_IS_43_EQ_43(...) \, -#define Z_IS_44_EQ_44(...) \, -#define Z_IS_45_EQ_45(...) \, -#define Z_IS_46_EQ_46(...) \, -#define Z_IS_47_EQ_47(...) \, -#define Z_IS_48_EQ_48(...) \, -#define Z_IS_49_EQ_49(...) \, -#define Z_IS_50_EQ_50(...) \, -#define Z_IS_51_EQ_51(...) \, -#define Z_IS_52_EQ_52(...) \, -#define Z_IS_53_EQ_53(...) \, -#define Z_IS_54_EQ_54(...) \, -#define Z_IS_55_EQ_55(...) \, -#define Z_IS_56_EQ_56(...) \, -#define Z_IS_57_EQ_57(...) \, -#define Z_IS_58_EQ_58(...) \, -#define Z_IS_59_EQ_59(...) \, -#define Z_IS_60_EQ_60(...) \, -#define Z_IS_61_EQ_61(...) \, -#define Z_IS_62_EQ_62(...) \, -#define Z_IS_63_EQ_63(...) \, -#define Z_IS_64_EQ_64(...) \, -#define Z_IS_65_EQ_65(...) \, -#define Z_IS_66_EQ_66(...) \, -#define Z_IS_67_EQ_67(...) \, -#define Z_IS_68_EQ_68(...) \, -#define Z_IS_69_EQ_69(...) \, -#define Z_IS_70_EQ_70(...) \, -#define Z_IS_71_EQ_71(...) \, -#define Z_IS_72_EQ_72(...) \, -#define Z_IS_73_EQ_73(...) \, -#define Z_IS_74_EQ_74(...) \, -#define Z_IS_75_EQ_75(...) \, -#define Z_IS_76_EQ_76(...) \, -#define Z_IS_77_EQ_77(...) \, -#define Z_IS_78_EQ_78(...) \, -#define Z_IS_79_EQ_79(...) \, -#define Z_IS_80_EQ_80(...) \, -#define Z_IS_81_EQ_81(...) \, -#define Z_IS_82_EQ_82(...) \, -#define Z_IS_83_EQ_83(...) \, -#define Z_IS_84_EQ_84(...) \, -#define Z_IS_85_EQ_85(...) \, -#define Z_IS_86_EQ_86(...) \, -#define Z_IS_87_EQ_87(...) \, -#define Z_IS_88_EQ_88(...) \, -#define Z_IS_89_EQ_89(...) \, -#define Z_IS_90_EQ_90(...) \, -#define Z_IS_91_EQ_91(...) \, -#define Z_IS_92_EQ_92(...) \, -#define Z_IS_93_EQ_93(...) \, -#define Z_IS_94_EQ_94(...) \, -#define Z_IS_95_EQ_95(...) \, -#define Z_IS_96_EQ_96(...) \, -#define Z_IS_97_EQ_97(...) \, -#define Z_IS_98_EQ_98(...) \, -#define Z_IS_99_EQ_99(...) \, -#define Z_IS_100_EQ_100(...) \, -#define Z_IS_101_EQ_101(...) \, -#define Z_IS_102_EQ_102(...) \, -#define Z_IS_103_EQ_103(...) \, -#define Z_IS_104_EQ_104(...) \, -#define Z_IS_105_EQ_105(...) \, -#define Z_IS_106_EQ_106(...) \, -#define Z_IS_107_EQ_107(...) \, -#define Z_IS_108_EQ_108(...) \, -#define Z_IS_109_EQ_109(...) \, -#define Z_IS_110_EQ_110(...) \, -#define Z_IS_111_EQ_111(...) \, -#define Z_IS_112_EQ_112(...) \, -#define Z_IS_113_EQ_113(...) \, -#define Z_IS_114_EQ_114(...) \, -#define Z_IS_115_EQ_115(...) \, -#define Z_IS_116_EQ_116(...) \, -#define Z_IS_117_EQ_117(...) \, -#define Z_IS_118_EQ_118(...) \, -#define Z_IS_119_EQ_119(...) \, -#define Z_IS_120_EQ_120(...) \, -#define Z_IS_121_EQ_121(...) \, -#define Z_IS_122_EQ_122(...) \, -#define Z_IS_123_EQ_123(...) \, -#define Z_IS_124_EQ_124(...) \, -#define Z_IS_125_EQ_125(...) \, -#define Z_IS_126_EQ_126(...) \, -#define Z_IS_127_EQ_127(...) \, -#define Z_IS_128_EQ_128(...) \, -#define Z_IS_129_EQ_129(...) \, -#define Z_IS_130_EQ_130(...) \, -#define Z_IS_131_EQ_131(...) \, -#define Z_IS_132_EQ_132(...) \, -#define Z_IS_133_EQ_133(...) \, -#define Z_IS_134_EQ_134(...) \, -#define Z_IS_135_EQ_135(...) \, -#define Z_IS_136_EQ_136(...) \, -#define Z_IS_137_EQ_137(...) \, -#define Z_IS_138_EQ_138(...) \, -#define Z_IS_139_EQ_139(...) \, -#define Z_IS_140_EQ_140(...) \, -#define Z_IS_141_EQ_141(...) \, -#define Z_IS_142_EQ_142(...) \, -#define Z_IS_143_EQ_143(...) \, -#define Z_IS_144_EQ_144(...) \, -#define Z_IS_145_EQ_145(...) \, -#define Z_IS_146_EQ_146(...) \, -#define Z_IS_147_EQ_147(...) \, -#define Z_IS_148_EQ_148(...) \, -#define Z_IS_149_EQ_149(...) \, -#define Z_IS_150_EQ_150(...) \, -#define Z_IS_151_EQ_151(...) \, -#define Z_IS_152_EQ_152(...) \, -#define Z_IS_153_EQ_153(...) \, -#define Z_IS_154_EQ_154(...) \, -#define Z_IS_155_EQ_155(...) \, -#define Z_IS_156_EQ_156(...) \, -#define Z_IS_157_EQ_157(...) \, -#define Z_IS_158_EQ_158(...) \, -#define Z_IS_159_EQ_159(...) \, -#define Z_IS_160_EQ_160(...) \, -#define Z_IS_161_EQ_161(...) \, -#define Z_IS_162_EQ_162(...) \, -#define Z_IS_163_EQ_163(...) \, -#define Z_IS_164_EQ_164(...) \, -#define Z_IS_165_EQ_165(...) \, -#define Z_IS_166_EQ_166(...) \, -#define Z_IS_167_EQ_167(...) \, -#define Z_IS_168_EQ_168(...) \, -#define Z_IS_169_EQ_169(...) \, -#define Z_IS_170_EQ_170(...) \, -#define Z_IS_171_EQ_171(...) \, -#define Z_IS_172_EQ_172(...) \, -#define Z_IS_173_EQ_173(...) \, -#define Z_IS_174_EQ_174(...) \, -#define Z_IS_175_EQ_175(...) \, -#define Z_IS_176_EQ_176(...) \, -#define Z_IS_177_EQ_177(...) \, -#define Z_IS_178_EQ_178(...) \, -#define Z_IS_179_EQ_179(...) \, -#define Z_IS_180_EQ_180(...) \, -#define Z_IS_181_EQ_181(...) \, -#define Z_IS_182_EQ_182(...) \, -#define Z_IS_183_EQ_183(...) \, -#define Z_IS_184_EQ_184(...) \, -#define Z_IS_185_EQ_185(...) \, -#define Z_IS_186_EQ_186(...) \, -#define Z_IS_187_EQ_187(...) \, -#define Z_IS_188_EQ_188(...) \, -#define Z_IS_189_EQ_189(...) \, -#define Z_IS_190_EQ_190(...) \, -#define Z_IS_191_EQ_191(...) \, -#define Z_IS_192_EQ_192(...) \, -#define Z_IS_193_EQ_193(...) \, -#define Z_IS_194_EQ_194(...) \, -#define Z_IS_195_EQ_195(...) \, -#define Z_IS_196_EQ_196(...) \, -#define Z_IS_197_EQ_197(...) \, -#define Z_IS_198_EQ_198(...) \, -#define Z_IS_199_EQ_199(...) \, -#define Z_IS_200_EQ_200(...) \, -#define Z_IS_201_EQ_201(...) \, -#define Z_IS_202_EQ_202(...) \, -#define Z_IS_203_EQ_203(...) \, -#define Z_IS_204_EQ_204(...) \, -#define Z_IS_205_EQ_205(...) \, -#define Z_IS_206_EQ_206(...) \, -#define Z_IS_207_EQ_207(...) \, -#define Z_IS_208_EQ_208(...) \, -#define Z_IS_209_EQ_209(...) \, -#define Z_IS_210_EQ_210(...) \, -#define Z_IS_211_EQ_211(...) \, -#define Z_IS_212_EQ_212(...) \, -#define Z_IS_213_EQ_213(...) \, -#define Z_IS_214_EQ_214(...) \, -#define Z_IS_215_EQ_215(...) \, -#define Z_IS_216_EQ_216(...) \, -#define Z_IS_217_EQ_217(...) \, -#define Z_IS_218_EQ_218(...) \, -#define Z_IS_219_EQ_219(...) \, -#define Z_IS_220_EQ_220(...) \, -#define Z_IS_221_EQ_221(...) \, -#define Z_IS_222_EQ_222(...) \, -#define Z_IS_223_EQ_223(...) \, -#define Z_IS_224_EQ_224(...) \, -#define Z_IS_225_EQ_225(...) \, -#define Z_IS_226_EQ_226(...) \, -#define Z_IS_227_EQ_227(...) \, -#define Z_IS_228_EQ_228(...) \, -#define Z_IS_229_EQ_229(...) \, -#define Z_IS_230_EQ_230(...) \, -#define Z_IS_231_EQ_231(...) \, -#define Z_IS_232_EQ_232(...) \, -#define Z_IS_233_EQ_233(...) \, -#define Z_IS_234_EQ_234(...) \, -#define Z_IS_235_EQ_235(...) \, -#define Z_IS_236_EQ_236(...) \, -#define Z_IS_237_EQ_237(...) \, -#define Z_IS_238_EQ_238(...) \, -#define Z_IS_239_EQ_239(...) \, -#define Z_IS_240_EQ_240(...) \, -#define Z_IS_241_EQ_241(...) \, -#define Z_IS_242_EQ_242(...) \, -#define Z_IS_243_EQ_243(...) \, -#define Z_IS_244_EQ_244(...) \, -#define Z_IS_245_EQ_245(...) \, -#define Z_IS_246_EQ_246(...) \, -#define Z_IS_247_EQ_247(...) \, -#define Z_IS_248_EQ_248(...) \, -#define Z_IS_249_EQ_249(...) \, -#define Z_IS_250_EQ_250(...) \, -#define Z_IS_251_EQ_251(...) \, -#define Z_IS_252_EQ_252(...) \, -#define Z_IS_253_EQ_253(...) \, -#define Z_IS_254_EQ_254(...) \, -#define Z_IS_255_EQ_255(...) \, +#include "util_internal_is_eq.h" /* * Generic sparse list of odd numbers (check the implementation of @@ -435,775 +180,13 @@ 48, EMPTY, 50, EMPTY, 52, EMPTY, 54, EMPTY, \ 56, EMPTY, 58, EMPTY, 60, EMPTY, 62, EMPTY -#define UTIL_INC_0 1 -#define UTIL_INC_1 2 -#define UTIL_INC_2 3 -#define UTIL_INC_3 4 -#define UTIL_INC_4 5 -#define UTIL_INC_5 6 -#define UTIL_INC_6 7 -#define UTIL_INC_7 8 -#define UTIL_INC_8 9 -#define UTIL_INC_9 10 -#define UTIL_INC_10 11 -#define UTIL_INC_11 12 -#define UTIL_INC_12 13 -#define UTIL_INC_13 14 -#define UTIL_INC_14 15 -#define UTIL_INC_15 16 -#define UTIL_INC_16 17 -#define UTIL_INC_17 18 -#define UTIL_INC_18 19 -#define UTIL_INC_19 20 -#define UTIL_INC_20 21 -#define UTIL_INC_21 22 -#define UTIL_INC_22 23 -#define UTIL_INC_23 24 -#define UTIL_INC_24 25 -#define UTIL_INC_25 26 -#define UTIL_INC_26 27 -#define UTIL_INC_27 28 -#define UTIL_INC_28 29 -#define UTIL_INC_29 30 -#define UTIL_INC_30 31 -#define UTIL_INC_31 32 -#define UTIL_INC_32 33 -#define UTIL_INC_33 34 -#define UTIL_INC_34 35 -#define UTIL_INC_35 36 -#define UTIL_INC_36 37 -#define UTIL_INC_37 38 -#define UTIL_INC_38 39 -#define UTIL_INC_39 40 -#define UTIL_INC_40 41 -#define UTIL_INC_41 42 -#define UTIL_INC_42 43 -#define UTIL_INC_43 44 -#define UTIL_INC_44 45 -#define UTIL_INC_45 46 -#define UTIL_INC_46 47 -#define UTIL_INC_47 48 -#define UTIL_INC_48 49 -#define UTIL_INC_49 50 -#define UTIL_INC_50 51 -#define UTIL_INC_51 52 -#define UTIL_INC_52 53 -#define UTIL_INC_53 54 -#define UTIL_INC_54 55 -#define UTIL_INC_55 56 -#define UTIL_INC_56 57 -#define UTIL_INC_57 58 -#define UTIL_INC_58 59 -#define UTIL_INC_59 60 -#define UTIL_INC_60 61 -#define UTIL_INC_61 62 -#define UTIL_INC_62 63 -#define UTIL_INC_63 64 -#define UTIL_INC_64 65 -#define UTIL_INC_65 66 -#define UTIL_INC_66 67 -#define UTIL_INC_67 68 -#define UTIL_INC_68 69 -#define UTIL_INC_69 70 -#define UTIL_INC_70 71 -#define UTIL_INC_71 72 -#define UTIL_INC_72 73 -#define UTIL_INC_73 74 -#define UTIL_INC_74 75 -#define UTIL_INC_75 76 -#define UTIL_INC_76 77 -#define UTIL_INC_77 78 -#define UTIL_INC_78 79 -#define UTIL_INC_79 80 -#define UTIL_INC_80 81 -#define UTIL_INC_81 82 -#define UTIL_INC_82 83 -#define UTIL_INC_83 84 -#define UTIL_INC_84 85 -#define UTIL_INC_85 86 -#define UTIL_INC_86 87 -#define UTIL_INC_87 88 -#define UTIL_INC_88 89 -#define UTIL_INC_89 90 -#define UTIL_INC_90 91 -#define UTIL_INC_91 92 -#define UTIL_INC_92 93 -#define UTIL_INC_93 94 -#define UTIL_INC_94 95 -#define UTIL_INC_95 96 -#define UTIL_INC_96 97 -#define UTIL_INC_97 98 -#define UTIL_INC_98 99 -#define UTIL_INC_99 100 -#define UTIL_INC_100 101 -#define UTIL_INC_101 102 -#define UTIL_INC_102 103 -#define UTIL_INC_103 104 -#define UTIL_INC_104 105 -#define UTIL_INC_105 106 -#define UTIL_INC_106 107 -#define UTIL_INC_107 108 -#define UTIL_INC_108 109 -#define UTIL_INC_109 110 -#define UTIL_INC_110 111 -#define UTIL_INC_111 112 -#define UTIL_INC_112 113 -#define UTIL_INC_113 114 -#define UTIL_INC_114 115 -#define UTIL_INC_115 116 -#define UTIL_INC_116 117 -#define UTIL_INC_117 118 -#define UTIL_INC_118 119 -#define UTIL_INC_119 120 -#define UTIL_INC_120 121 -#define UTIL_INC_121 122 -#define UTIL_INC_122 123 -#define UTIL_INC_123 124 -#define UTIL_INC_124 125 -#define UTIL_INC_125 126 -#define UTIL_INC_126 127 -#define UTIL_INC_127 128 -#define UTIL_INC_128 129 -#define UTIL_INC_129 130 -#define UTIL_INC_130 131 -#define UTIL_INC_131 132 -#define UTIL_INC_132 133 -#define UTIL_INC_133 134 -#define UTIL_INC_134 135 -#define UTIL_INC_135 136 -#define UTIL_INC_136 137 -#define UTIL_INC_137 138 -#define UTIL_INC_138 139 -#define UTIL_INC_139 140 -#define UTIL_INC_140 141 -#define UTIL_INC_141 142 -#define UTIL_INC_142 143 -#define UTIL_INC_143 144 -#define UTIL_INC_144 145 -#define UTIL_INC_145 146 -#define UTIL_INC_146 147 -#define UTIL_INC_147 148 -#define UTIL_INC_148 149 -#define UTIL_INC_149 150 -#define UTIL_INC_150 151 -#define UTIL_INC_151 152 -#define UTIL_INC_152 153 -#define UTIL_INC_153 154 -#define UTIL_INC_154 155 -#define UTIL_INC_155 156 -#define UTIL_INC_156 157 -#define UTIL_INC_157 158 -#define UTIL_INC_158 159 -#define UTIL_INC_159 160 -#define UTIL_INC_160 161 -#define UTIL_INC_161 162 -#define UTIL_INC_162 163 -#define UTIL_INC_163 164 -#define UTIL_INC_164 165 -#define UTIL_INC_165 166 -#define UTIL_INC_166 167 -#define UTIL_INC_167 168 -#define UTIL_INC_168 169 -#define UTIL_INC_169 170 -#define UTIL_INC_170 171 -#define UTIL_INC_171 172 -#define UTIL_INC_172 173 -#define UTIL_INC_173 174 -#define UTIL_INC_174 175 -#define UTIL_INC_175 176 -#define UTIL_INC_176 177 -#define UTIL_INC_177 178 -#define UTIL_INC_178 179 -#define UTIL_INC_179 180 -#define UTIL_INC_180 181 -#define UTIL_INC_181 182 -#define UTIL_INC_182 183 -#define UTIL_INC_183 184 -#define UTIL_INC_184 185 -#define UTIL_INC_185 186 -#define UTIL_INC_186 187 -#define UTIL_INC_187 188 -#define UTIL_INC_188 189 -#define UTIL_INC_189 190 -#define UTIL_INC_190 191 -#define UTIL_INC_191 192 -#define UTIL_INC_192 193 -#define UTIL_INC_193 194 -#define UTIL_INC_194 195 -#define UTIL_INC_195 196 -#define UTIL_INC_196 197 -#define UTIL_INC_197 198 -#define UTIL_INC_198 199 -#define UTIL_INC_199 200 -#define UTIL_INC_200 201 -#define UTIL_INC_201 202 -#define UTIL_INC_202 203 -#define UTIL_INC_203 204 -#define UTIL_INC_204 205 -#define UTIL_INC_205 206 -#define UTIL_INC_206 207 -#define UTIL_INC_207 208 -#define UTIL_INC_208 209 -#define UTIL_INC_209 210 -#define UTIL_INC_210 211 -#define UTIL_INC_211 212 -#define UTIL_INC_212 213 -#define UTIL_INC_213 214 -#define UTIL_INC_214 215 -#define UTIL_INC_215 216 -#define UTIL_INC_216 217 -#define UTIL_INC_217 218 -#define UTIL_INC_218 219 -#define UTIL_INC_219 220 -#define UTIL_INC_220 221 -#define UTIL_INC_221 222 -#define UTIL_INC_222 223 -#define UTIL_INC_223 224 -#define UTIL_INC_224 225 -#define UTIL_INC_225 226 -#define UTIL_INC_226 227 -#define UTIL_INC_227 228 -#define UTIL_INC_228 229 -#define UTIL_INC_229 230 -#define UTIL_INC_230 231 -#define UTIL_INC_231 232 -#define UTIL_INC_232 233 -#define UTIL_INC_233 234 -#define UTIL_INC_234 235 -#define UTIL_INC_235 236 -#define UTIL_INC_236 237 -#define UTIL_INC_237 238 -#define UTIL_INC_238 239 -#define UTIL_INC_239 240 -#define UTIL_INC_240 241 -#define UTIL_INC_241 242 -#define UTIL_INC_242 243 -#define UTIL_INC_243 244 -#define UTIL_INC_244 245 -#define UTIL_INC_245 246 -#define UTIL_INC_246 247 -#define UTIL_INC_247 248 -#define UTIL_INC_248 249 -#define UTIL_INC_249 250 -#define UTIL_INC_250 251 -#define UTIL_INC_251 252 -#define UTIL_INC_252 253 -#define UTIL_INC_253 254 -#define UTIL_INC_254 255 -#define UTIL_INC_255 256 +/* Used by UTIL_INC */ +#include "util_internal_util_inc.h" -#define UTIL_DEC_0 0 -#define UTIL_DEC_1 0 -#define UTIL_DEC_2 1 -#define UTIL_DEC_3 2 -#define UTIL_DEC_4 3 -#define UTIL_DEC_5 4 -#define UTIL_DEC_6 5 -#define UTIL_DEC_7 6 -#define UTIL_DEC_8 7 -#define UTIL_DEC_9 8 -#define UTIL_DEC_10 9 -#define UTIL_DEC_11 10 -#define UTIL_DEC_12 11 -#define UTIL_DEC_13 12 -#define UTIL_DEC_14 13 -#define UTIL_DEC_15 14 -#define UTIL_DEC_16 15 -#define UTIL_DEC_17 16 -#define UTIL_DEC_18 17 -#define UTIL_DEC_19 18 -#define UTIL_DEC_20 19 -#define UTIL_DEC_21 20 -#define UTIL_DEC_22 21 -#define UTIL_DEC_23 22 -#define UTIL_DEC_24 23 -#define UTIL_DEC_25 24 -#define UTIL_DEC_26 25 -#define UTIL_DEC_27 26 -#define UTIL_DEC_28 27 -#define UTIL_DEC_29 28 -#define UTIL_DEC_30 29 -#define UTIL_DEC_31 30 -#define UTIL_DEC_32 31 -#define UTIL_DEC_33 32 -#define UTIL_DEC_34 33 -#define UTIL_DEC_35 34 -#define UTIL_DEC_36 35 -#define UTIL_DEC_37 36 -#define UTIL_DEC_38 37 -#define UTIL_DEC_39 38 -#define UTIL_DEC_40 39 -#define UTIL_DEC_41 40 -#define UTIL_DEC_42 41 -#define UTIL_DEC_43 42 -#define UTIL_DEC_44 43 -#define UTIL_DEC_45 44 -#define UTIL_DEC_46 45 -#define UTIL_DEC_47 46 -#define UTIL_DEC_48 47 -#define UTIL_DEC_49 48 -#define UTIL_DEC_50 49 -#define UTIL_DEC_51 50 -#define UTIL_DEC_52 51 -#define UTIL_DEC_53 52 -#define UTIL_DEC_54 53 -#define UTIL_DEC_55 54 -#define UTIL_DEC_56 55 -#define UTIL_DEC_57 56 -#define UTIL_DEC_58 57 -#define UTIL_DEC_59 58 -#define UTIL_DEC_60 59 -#define UTIL_DEC_61 60 -#define UTIL_DEC_62 61 -#define UTIL_DEC_63 62 -#define UTIL_DEC_64 63 -#define UTIL_DEC_65 64 -#define UTIL_DEC_66 65 -#define UTIL_DEC_67 66 -#define UTIL_DEC_68 67 -#define UTIL_DEC_69 68 -#define UTIL_DEC_70 69 -#define UTIL_DEC_71 70 -#define UTIL_DEC_72 71 -#define UTIL_DEC_73 72 -#define UTIL_DEC_74 73 -#define UTIL_DEC_75 74 -#define UTIL_DEC_76 75 -#define UTIL_DEC_77 76 -#define UTIL_DEC_78 77 -#define UTIL_DEC_79 78 -#define UTIL_DEC_80 79 -#define UTIL_DEC_81 80 -#define UTIL_DEC_82 81 -#define UTIL_DEC_83 82 -#define UTIL_DEC_84 83 -#define UTIL_DEC_85 84 -#define UTIL_DEC_86 85 -#define UTIL_DEC_87 86 -#define UTIL_DEC_88 87 -#define UTIL_DEC_89 88 -#define UTIL_DEC_90 89 -#define UTIL_DEC_91 90 -#define UTIL_DEC_92 91 -#define UTIL_DEC_93 92 -#define UTIL_DEC_94 93 -#define UTIL_DEC_95 94 -#define UTIL_DEC_96 95 -#define UTIL_DEC_97 96 -#define UTIL_DEC_98 97 -#define UTIL_DEC_99 98 -#define UTIL_DEC_100 99 -#define UTIL_DEC_101 100 -#define UTIL_DEC_102 101 -#define UTIL_DEC_103 102 -#define UTIL_DEC_104 103 -#define UTIL_DEC_105 104 -#define UTIL_DEC_106 105 -#define UTIL_DEC_107 106 -#define UTIL_DEC_108 107 -#define UTIL_DEC_109 108 -#define UTIL_DEC_110 109 -#define UTIL_DEC_111 110 -#define UTIL_DEC_112 111 -#define UTIL_DEC_113 112 -#define UTIL_DEC_114 113 -#define UTIL_DEC_115 114 -#define UTIL_DEC_116 115 -#define UTIL_DEC_117 116 -#define UTIL_DEC_118 117 -#define UTIL_DEC_119 118 -#define UTIL_DEC_120 119 -#define UTIL_DEC_121 120 -#define UTIL_DEC_122 121 -#define UTIL_DEC_123 122 -#define UTIL_DEC_124 123 -#define UTIL_DEC_125 124 -#define UTIL_DEC_126 125 -#define UTIL_DEC_127 126 -#define UTIL_DEC_128 127 -#define UTIL_DEC_129 128 -#define UTIL_DEC_130 129 -#define UTIL_DEC_131 130 -#define UTIL_DEC_132 131 -#define UTIL_DEC_133 132 -#define UTIL_DEC_134 133 -#define UTIL_DEC_135 134 -#define UTIL_DEC_136 135 -#define UTIL_DEC_137 136 -#define UTIL_DEC_138 137 -#define UTIL_DEC_139 138 -#define UTIL_DEC_140 139 -#define UTIL_DEC_141 140 -#define UTIL_DEC_142 141 -#define UTIL_DEC_143 142 -#define UTIL_DEC_144 143 -#define UTIL_DEC_145 144 -#define UTIL_DEC_146 145 -#define UTIL_DEC_147 146 -#define UTIL_DEC_148 147 -#define UTIL_DEC_149 148 -#define UTIL_DEC_150 149 -#define UTIL_DEC_151 150 -#define UTIL_DEC_152 151 -#define UTIL_DEC_153 152 -#define UTIL_DEC_154 153 -#define UTIL_DEC_155 154 -#define UTIL_DEC_156 155 -#define UTIL_DEC_157 156 -#define UTIL_DEC_158 157 -#define UTIL_DEC_159 158 -#define UTIL_DEC_160 159 -#define UTIL_DEC_161 160 -#define UTIL_DEC_162 161 -#define UTIL_DEC_163 162 -#define UTIL_DEC_164 163 -#define UTIL_DEC_165 164 -#define UTIL_DEC_166 165 -#define UTIL_DEC_167 166 -#define UTIL_DEC_168 167 -#define UTIL_DEC_169 168 -#define UTIL_DEC_170 169 -#define UTIL_DEC_171 170 -#define UTIL_DEC_172 171 -#define UTIL_DEC_173 172 -#define UTIL_DEC_174 173 -#define UTIL_DEC_175 174 -#define UTIL_DEC_176 175 -#define UTIL_DEC_177 176 -#define UTIL_DEC_178 177 -#define UTIL_DEC_179 178 -#define UTIL_DEC_180 179 -#define UTIL_DEC_181 180 -#define UTIL_DEC_182 181 -#define UTIL_DEC_183 182 -#define UTIL_DEC_184 183 -#define UTIL_DEC_185 184 -#define UTIL_DEC_186 185 -#define UTIL_DEC_187 186 -#define UTIL_DEC_188 187 -#define UTIL_DEC_189 188 -#define UTIL_DEC_190 189 -#define UTIL_DEC_191 190 -#define UTIL_DEC_192 191 -#define UTIL_DEC_193 192 -#define UTIL_DEC_194 193 -#define UTIL_DEC_195 194 -#define UTIL_DEC_196 195 -#define UTIL_DEC_197 196 -#define UTIL_DEC_198 197 -#define UTIL_DEC_199 198 -#define UTIL_DEC_200 199 -#define UTIL_DEC_201 200 -#define UTIL_DEC_202 201 -#define UTIL_DEC_203 202 -#define UTIL_DEC_204 203 -#define UTIL_DEC_205 204 -#define UTIL_DEC_206 205 -#define UTIL_DEC_207 206 -#define UTIL_DEC_208 207 -#define UTIL_DEC_209 208 -#define UTIL_DEC_210 209 -#define UTIL_DEC_211 210 -#define UTIL_DEC_212 211 -#define UTIL_DEC_213 212 -#define UTIL_DEC_214 213 -#define UTIL_DEC_215 214 -#define UTIL_DEC_216 215 -#define UTIL_DEC_217 216 -#define UTIL_DEC_218 217 -#define UTIL_DEC_219 218 -#define UTIL_DEC_220 219 -#define UTIL_DEC_221 220 -#define UTIL_DEC_222 221 -#define UTIL_DEC_223 222 -#define UTIL_DEC_224 223 -#define UTIL_DEC_225 224 -#define UTIL_DEC_226 225 -#define UTIL_DEC_227 226 -#define UTIL_DEC_228 227 -#define UTIL_DEC_229 228 -#define UTIL_DEC_230 229 -#define UTIL_DEC_231 230 -#define UTIL_DEC_232 231 -#define UTIL_DEC_233 232 -#define UTIL_DEC_234 233 -#define UTIL_DEC_235 234 -#define UTIL_DEC_236 235 -#define UTIL_DEC_237 236 -#define UTIL_DEC_238 237 -#define UTIL_DEC_239 238 -#define UTIL_DEC_240 239 -#define UTIL_DEC_241 240 -#define UTIL_DEC_242 241 -#define UTIL_DEC_243 242 -#define UTIL_DEC_244 243 -#define UTIL_DEC_245 244 -#define UTIL_DEC_246 245 -#define UTIL_DEC_247 246 -#define UTIL_DEC_248 247 -#define UTIL_DEC_249 248 -#define UTIL_DEC_250 249 -#define UTIL_DEC_251 250 -#define UTIL_DEC_252 251 -#define UTIL_DEC_253 252 -#define UTIL_DEC_254 253 -#define UTIL_DEC_255 254 +/* Used by UTIL_DEC */ +#include "util_internal_util_dec.h" -#define UTIL_X2_0 0 -#define UTIL_X2_1 2 -#define UTIL_X2_2 4 -#define UTIL_X2_3 6 -#define UTIL_X2_4 8 -#define UTIL_X2_5 10 -#define UTIL_X2_6 12 -#define UTIL_X2_7 14 -#define UTIL_X2_8 16 -#define UTIL_X2_9 18 -#define UTIL_X2_10 20 -#define UTIL_X2_11 22 -#define UTIL_X2_12 24 -#define UTIL_X2_13 26 -#define UTIL_X2_14 28 -#define UTIL_X2_15 30 -#define UTIL_X2_16 32 -#define UTIL_X2_17 34 -#define UTIL_X2_18 36 -#define UTIL_X2_19 38 -#define UTIL_X2_20 40 -#define UTIL_X2_21 42 -#define UTIL_X2_22 44 -#define UTIL_X2_23 46 -#define UTIL_X2_24 48 -#define UTIL_X2_25 50 -#define UTIL_X2_26 52 -#define UTIL_X2_27 54 -#define UTIL_X2_28 56 -#define UTIL_X2_29 58 -#define UTIL_X2_30 60 -#define UTIL_X2_31 62 -#define UTIL_X2_32 64 -#define UTIL_X2_33 66 -#define UTIL_X2_34 68 -#define UTIL_X2_35 70 -#define UTIL_X2_36 72 -#define UTIL_X2_37 74 -#define UTIL_X2_38 76 -#define UTIL_X2_39 78 -#define UTIL_X2_40 80 -#define UTIL_X2_41 82 -#define UTIL_X2_42 84 -#define UTIL_X2_43 86 -#define UTIL_X2_44 88 -#define UTIL_X2_45 90 -#define UTIL_X2_46 92 -#define UTIL_X2_47 94 -#define UTIL_X2_48 96 -#define UTIL_X2_49 98 -#define UTIL_X2_50 100 -#define UTIL_X2_51 102 -#define UTIL_X2_52 104 -#define UTIL_X2_53 106 -#define UTIL_X2_54 108 -#define UTIL_X2_55 110 -#define UTIL_X2_56 112 -#define UTIL_X2_57 114 -#define UTIL_X2_58 116 -#define UTIL_X2_59 118 -#define UTIL_X2_60 120 -#define UTIL_X2_61 122 -#define UTIL_X2_62 124 -#define UTIL_X2_63 126 -#define UTIL_X2_64 128 -#define UTIL_X2_65 130 -#define UTIL_X2_66 132 -#define UTIL_X2_67 134 -#define UTIL_X2_68 136 -#define UTIL_X2_69 138 -#define UTIL_X2_70 140 -#define UTIL_X2_71 142 -#define UTIL_X2_72 144 -#define UTIL_X2_73 146 -#define UTIL_X2_74 148 -#define UTIL_X2_75 150 -#define UTIL_X2_76 152 -#define UTIL_X2_77 154 -#define UTIL_X2_78 156 -#define UTIL_X2_79 158 -#define UTIL_X2_80 160 -#define UTIL_X2_81 162 -#define UTIL_X2_82 164 -#define UTIL_X2_83 166 -#define UTIL_X2_84 168 -#define UTIL_X2_85 170 -#define UTIL_X2_86 172 -#define UTIL_X2_87 174 -#define UTIL_X2_88 176 -#define UTIL_X2_89 178 -#define UTIL_X2_90 180 -#define UTIL_X2_91 182 -#define UTIL_X2_92 184 -#define UTIL_X2_93 186 -#define UTIL_X2_94 188 -#define UTIL_X2_95 190 -#define UTIL_X2_96 192 -#define UTIL_X2_97 194 -#define UTIL_X2_98 196 -#define UTIL_X2_99 198 -#define UTIL_X2_100 200 -#define UTIL_X2_101 202 -#define UTIL_X2_102 204 -#define UTIL_X2_103 206 -#define UTIL_X2_104 208 -#define UTIL_X2_105 210 -#define UTIL_X2_106 212 -#define UTIL_X2_107 214 -#define UTIL_X2_108 216 -#define UTIL_X2_109 218 -#define UTIL_X2_110 220 -#define UTIL_X2_111 222 -#define UTIL_X2_112 224 -#define UTIL_X2_113 226 -#define UTIL_X2_114 228 -#define UTIL_X2_115 230 -#define UTIL_X2_116 232 -#define UTIL_X2_117 234 -#define UTIL_X2_118 236 -#define UTIL_X2_119 238 -#define UTIL_X2_120 240 -#define UTIL_X2_121 242 -#define UTIL_X2_122 244 -#define UTIL_X2_123 246 -#define UTIL_X2_124 248 -#define UTIL_X2_125 250 -#define UTIL_X2_126 252 -#define UTIL_X2_127 254 -#define UTIL_X2_128 256 -#define UTIL_X2_129 258 -#define UTIL_X2_130 260 -#define UTIL_X2_131 262 -#define UTIL_X2_132 264 -#define UTIL_X2_133 266 -#define UTIL_X2_134 268 -#define UTIL_X2_135 270 -#define UTIL_X2_136 272 -#define UTIL_X2_137 274 -#define UTIL_X2_138 276 -#define UTIL_X2_139 278 -#define UTIL_X2_140 280 -#define UTIL_X2_141 282 -#define UTIL_X2_142 284 -#define UTIL_X2_143 286 -#define UTIL_X2_144 288 -#define UTIL_X2_145 290 -#define UTIL_X2_146 292 -#define UTIL_X2_147 294 -#define UTIL_X2_148 296 -#define UTIL_X2_149 298 -#define UTIL_X2_150 300 -#define UTIL_X2_151 302 -#define UTIL_X2_152 304 -#define UTIL_X2_153 306 -#define UTIL_X2_154 308 -#define UTIL_X2_155 310 -#define UTIL_X2_156 312 -#define UTIL_X2_157 314 -#define UTIL_X2_158 316 -#define UTIL_X2_159 318 -#define UTIL_X2_160 320 -#define UTIL_X2_161 322 -#define UTIL_X2_162 324 -#define UTIL_X2_163 326 -#define UTIL_X2_164 328 -#define UTIL_X2_165 330 -#define UTIL_X2_166 332 -#define UTIL_X2_167 334 -#define UTIL_X2_168 336 -#define UTIL_X2_169 338 -#define UTIL_X2_170 340 -#define UTIL_X2_171 342 -#define UTIL_X2_172 344 -#define UTIL_X2_173 346 -#define UTIL_X2_174 348 -#define UTIL_X2_175 350 -#define UTIL_X2_176 352 -#define UTIL_X2_177 354 -#define UTIL_X2_178 356 -#define UTIL_X2_179 358 -#define UTIL_X2_180 360 -#define UTIL_X2_181 362 -#define UTIL_X2_182 364 -#define UTIL_X2_183 366 -#define UTIL_X2_184 368 -#define UTIL_X2_185 370 -#define UTIL_X2_186 372 -#define UTIL_X2_187 374 -#define UTIL_X2_188 376 -#define UTIL_X2_189 378 -#define UTIL_X2_190 380 -#define UTIL_X2_191 382 -#define UTIL_X2_192 384 -#define UTIL_X2_193 386 -#define UTIL_X2_194 388 -#define UTIL_X2_195 390 -#define UTIL_X2_196 392 -#define UTIL_X2_197 394 -#define UTIL_X2_198 396 -#define UTIL_X2_199 398 -#define UTIL_X2_200 400 -#define UTIL_X2_201 402 -#define UTIL_X2_202 404 -#define UTIL_X2_203 406 -#define UTIL_X2_204 408 -#define UTIL_X2_205 410 -#define UTIL_X2_206 412 -#define UTIL_X2_207 414 -#define UTIL_X2_208 416 -#define UTIL_X2_209 418 -#define UTIL_X2_210 420 -#define UTIL_X2_211 422 -#define UTIL_X2_212 424 -#define UTIL_X2_213 426 -#define UTIL_X2_214 428 -#define UTIL_X2_215 430 -#define UTIL_X2_216 432 -#define UTIL_X2_217 434 -#define UTIL_X2_218 436 -#define UTIL_X2_219 438 -#define UTIL_X2_220 440 -#define UTIL_X2_221 442 -#define UTIL_X2_222 444 -#define UTIL_X2_223 446 -#define UTIL_X2_224 448 -#define UTIL_X2_225 450 -#define UTIL_X2_226 452 -#define UTIL_X2_227 454 -#define UTIL_X2_228 456 -#define UTIL_X2_229 458 -#define UTIL_X2_230 460 -#define UTIL_X2_231 462 -#define UTIL_X2_232 464 -#define UTIL_X2_233 466 -#define UTIL_X2_234 468 -#define UTIL_X2_235 470 -#define UTIL_X2_236 472 -#define UTIL_X2_237 474 -#define UTIL_X2_238 476 -#define UTIL_X2_239 478 -#define UTIL_X2_240 480 -#define UTIL_X2_241 482 -#define UTIL_X2_242 484 -#define UTIL_X2_243 486 -#define UTIL_X2_244 488 -#define UTIL_X2_245 490 -#define UTIL_X2_246 492 -#define UTIL_X2_247 494 -#define UTIL_X2_248 496 -#define UTIL_X2_249 498 -#define UTIL_X2_250 500 -#define UTIL_X2_251 502 -#define UTIL_X2_252 504 -#define UTIL_X2_253 506 -#define UTIL_X2_254 508 -#define UTIL_X2_255 510 +/* Used by UTIL_X2 */ +#include "util_internal_util_x2.h" #endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ diff --git a/include/zephyr/sys/util_internal_is_eq.h b/include/zephyr/sys/util_internal_is_eq.h new file mode 100644 index 00000000000..0734cf3506a --- /dev/null +++ b/include/zephyr/sys/util_internal_is_eq.h @@ -0,0 +1,4114 @@ +/* + * Copyright (c) 2011-2014, Wind River Systems, Inc. + * Copyright (c) 2020, Nordic Semiconductor ASA + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ +#error "This header should not be used directly, please include util_internal.h instead" +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ +#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ + +#define Z_IS_0_EQ_0(...) \, +#define Z_IS_1_EQ_1(...) \, +#define Z_IS_2_EQ_2(...) \, +#define Z_IS_3_EQ_3(...) \, +#define Z_IS_4_EQ_4(...) \, +#define Z_IS_5_EQ_5(...) \, +#define Z_IS_6_EQ_6(...) \, +#define Z_IS_7_EQ_7(...) \, +#define Z_IS_8_EQ_8(...) \, +#define Z_IS_9_EQ_9(...) \, +#define Z_IS_10_EQ_10(...) \, +#define Z_IS_11_EQ_11(...) \, +#define Z_IS_12_EQ_12(...) \, +#define Z_IS_13_EQ_13(...) \, +#define Z_IS_14_EQ_14(...) \, +#define Z_IS_15_EQ_15(...) \, +#define Z_IS_16_EQ_16(...) \, +#define Z_IS_17_EQ_17(...) \, +#define Z_IS_18_EQ_18(...) \, +#define Z_IS_19_EQ_19(...) \, +#define Z_IS_20_EQ_20(...) \, +#define Z_IS_21_EQ_21(...) \, +#define Z_IS_22_EQ_22(...) \, +#define Z_IS_23_EQ_23(...) \, +#define Z_IS_24_EQ_24(...) \, +#define Z_IS_25_EQ_25(...) \, +#define Z_IS_26_EQ_26(...) \, +#define Z_IS_27_EQ_27(...) \, +#define Z_IS_28_EQ_28(...) \, +#define Z_IS_29_EQ_29(...) \, +#define Z_IS_30_EQ_30(...) \, +#define Z_IS_31_EQ_31(...) \, +#define Z_IS_32_EQ_32(...) \, +#define Z_IS_33_EQ_33(...) \, +#define Z_IS_34_EQ_34(...) \, +#define Z_IS_35_EQ_35(...) \, +#define Z_IS_36_EQ_36(...) \, +#define Z_IS_37_EQ_37(...) \, +#define Z_IS_38_EQ_38(...) \, +#define Z_IS_39_EQ_39(...) \, +#define Z_IS_40_EQ_40(...) \, +#define Z_IS_41_EQ_41(...) \, +#define Z_IS_42_EQ_42(...) \, +#define Z_IS_43_EQ_43(...) \, +#define Z_IS_44_EQ_44(...) \, +#define Z_IS_45_EQ_45(...) \, +#define Z_IS_46_EQ_46(...) \, +#define Z_IS_47_EQ_47(...) \, +#define Z_IS_48_EQ_48(...) \, +#define Z_IS_49_EQ_49(...) \, +#define Z_IS_50_EQ_50(...) \, +#define Z_IS_51_EQ_51(...) \, +#define Z_IS_52_EQ_52(...) \, +#define Z_IS_53_EQ_53(...) \, +#define Z_IS_54_EQ_54(...) \, +#define Z_IS_55_EQ_55(...) \, +#define Z_IS_56_EQ_56(...) \, +#define Z_IS_57_EQ_57(...) \, +#define Z_IS_58_EQ_58(...) \, +#define Z_IS_59_EQ_59(...) \, +#define Z_IS_60_EQ_60(...) \, +#define Z_IS_61_EQ_61(...) \, +#define Z_IS_62_EQ_62(...) \, +#define Z_IS_63_EQ_63(...) \, +#define Z_IS_64_EQ_64(...) \, +#define Z_IS_65_EQ_65(...) \, +#define Z_IS_66_EQ_66(...) \, +#define Z_IS_67_EQ_67(...) \, +#define Z_IS_68_EQ_68(...) \, +#define Z_IS_69_EQ_69(...) \, +#define Z_IS_70_EQ_70(...) \, +#define Z_IS_71_EQ_71(...) \, +#define Z_IS_72_EQ_72(...) \, +#define Z_IS_73_EQ_73(...) \, +#define Z_IS_74_EQ_74(...) \, +#define Z_IS_75_EQ_75(...) \, +#define Z_IS_76_EQ_76(...) \, +#define Z_IS_77_EQ_77(...) \, +#define Z_IS_78_EQ_78(...) \, +#define Z_IS_79_EQ_79(...) \, +#define Z_IS_80_EQ_80(...) \, +#define Z_IS_81_EQ_81(...) \, +#define Z_IS_82_EQ_82(...) \, +#define Z_IS_83_EQ_83(...) \, +#define Z_IS_84_EQ_84(...) \, +#define Z_IS_85_EQ_85(...) \, +#define Z_IS_86_EQ_86(...) \, +#define Z_IS_87_EQ_87(...) \, +#define Z_IS_88_EQ_88(...) \, +#define Z_IS_89_EQ_89(...) \, +#define Z_IS_90_EQ_90(...) \, +#define Z_IS_91_EQ_91(...) \, +#define Z_IS_92_EQ_92(...) \, +#define Z_IS_93_EQ_93(...) \, +#define Z_IS_94_EQ_94(...) \, +#define Z_IS_95_EQ_95(...) \, +#define Z_IS_96_EQ_96(...) \, +#define Z_IS_97_EQ_97(...) \, +#define Z_IS_98_EQ_98(...) \, +#define Z_IS_99_EQ_99(...) \, +#define Z_IS_100_EQ_100(...) \, +#define Z_IS_101_EQ_101(...) \, +#define Z_IS_102_EQ_102(...) \, +#define Z_IS_103_EQ_103(...) \, +#define Z_IS_104_EQ_104(...) \, +#define Z_IS_105_EQ_105(...) \, +#define Z_IS_106_EQ_106(...) \, +#define Z_IS_107_EQ_107(...) \, +#define Z_IS_108_EQ_108(...) \, +#define Z_IS_109_EQ_109(...) \, +#define Z_IS_110_EQ_110(...) \, +#define Z_IS_111_EQ_111(...) \, +#define Z_IS_112_EQ_112(...) \, +#define Z_IS_113_EQ_113(...) \, +#define Z_IS_114_EQ_114(...) \, +#define Z_IS_115_EQ_115(...) \, +#define Z_IS_116_EQ_116(...) \, +#define Z_IS_117_EQ_117(...) \, +#define Z_IS_118_EQ_118(...) \, +#define Z_IS_119_EQ_119(...) \, +#define Z_IS_120_EQ_120(...) \, +#define Z_IS_121_EQ_121(...) \, +#define Z_IS_122_EQ_122(...) \, +#define Z_IS_123_EQ_123(...) \, +#define Z_IS_124_EQ_124(...) \, +#define Z_IS_125_EQ_125(...) \, +#define Z_IS_126_EQ_126(...) \, +#define Z_IS_127_EQ_127(...) \, +#define Z_IS_128_EQ_128(...) \, +#define Z_IS_129_EQ_129(...) \, +#define Z_IS_130_EQ_130(...) \, +#define Z_IS_131_EQ_131(...) \, +#define Z_IS_132_EQ_132(...) \, +#define Z_IS_133_EQ_133(...) \, +#define Z_IS_134_EQ_134(...) \, +#define Z_IS_135_EQ_135(...) \, +#define Z_IS_136_EQ_136(...) \, +#define Z_IS_137_EQ_137(...) \, +#define Z_IS_138_EQ_138(...) \, +#define Z_IS_139_EQ_139(...) \, +#define Z_IS_140_EQ_140(...) \, +#define Z_IS_141_EQ_141(...) \, +#define Z_IS_142_EQ_142(...) \, +#define Z_IS_143_EQ_143(...) \, +#define Z_IS_144_EQ_144(...) \, +#define Z_IS_145_EQ_145(...) \, +#define Z_IS_146_EQ_146(...) \, +#define Z_IS_147_EQ_147(...) \, +#define Z_IS_148_EQ_148(...) \, +#define Z_IS_149_EQ_149(...) \, +#define Z_IS_150_EQ_150(...) \, +#define Z_IS_151_EQ_151(...) \, +#define Z_IS_152_EQ_152(...) \, +#define Z_IS_153_EQ_153(...) \, +#define Z_IS_154_EQ_154(...) \, +#define Z_IS_155_EQ_155(...) \, +#define Z_IS_156_EQ_156(...) \, +#define Z_IS_157_EQ_157(...) \, +#define Z_IS_158_EQ_158(...) \, +#define Z_IS_159_EQ_159(...) \, +#define Z_IS_160_EQ_160(...) \, +#define Z_IS_161_EQ_161(...) \, +#define Z_IS_162_EQ_162(...) \, +#define Z_IS_163_EQ_163(...) \, +#define Z_IS_164_EQ_164(...) \, +#define Z_IS_165_EQ_165(...) \, +#define Z_IS_166_EQ_166(...) \, +#define Z_IS_167_EQ_167(...) \, +#define Z_IS_168_EQ_168(...) \, +#define Z_IS_169_EQ_169(...) \, +#define Z_IS_170_EQ_170(...) \, +#define Z_IS_171_EQ_171(...) \, +#define Z_IS_172_EQ_172(...) \, +#define Z_IS_173_EQ_173(...) \, +#define Z_IS_174_EQ_174(...) \, +#define Z_IS_175_EQ_175(...) \, +#define Z_IS_176_EQ_176(...) \, +#define Z_IS_177_EQ_177(...) \, +#define Z_IS_178_EQ_178(...) \, +#define Z_IS_179_EQ_179(...) \, +#define Z_IS_180_EQ_180(...) \, +#define Z_IS_181_EQ_181(...) \, +#define Z_IS_182_EQ_182(...) \, +#define Z_IS_183_EQ_183(...) \, +#define Z_IS_184_EQ_184(...) \, +#define Z_IS_185_EQ_185(...) \, +#define Z_IS_186_EQ_186(...) \, +#define Z_IS_187_EQ_187(...) \, +#define Z_IS_188_EQ_188(...) \, +#define Z_IS_189_EQ_189(...) \, +#define Z_IS_190_EQ_190(...) \, +#define Z_IS_191_EQ_191(...) \, +#define Z_IS_192_EQ_192(...) \, +#define Z_IS_193_EQ_193(...) \, +#define Z_IS_194_EQ_194(...) \, +#define Z_IS_195_EQ_195(...) \, +#define Z_IS_196_EQ_196(...) \, +#define Z_IS_197_EQ_197(...) \, +#define Z_IS_198_EQ_198(...) \, +#define Z_IS_199_EQ_199(...) \, +#define Z_IS_200_EQ_200(...) \, +#define Z_IS_201_EQ_201(...) \, +#define Z_IS_202_EQ_202(...) \, +#define Z_IS_203_EQ_203(...) \, +#define Z_IS_204_EQ_204(...) \, +#define Z_IS_205_EQ_205(...) \, +#define Z_IS_206_EQ_206(...) \, +#define Z_IS_207_EQ_207(...) \, +#define Z_IS_208_EQ_208(...) \, +#define Z_IS_209_EQ_209(...) \, +#define Z_IS_210_EQ_210(...) \, +#define Z_IS_211_EQ_211(...) \, +#define Z_IS_212_EQ_212(...) \, +#define Z_IS_213_EQ_213(...) \, +#define Z_IS_214_EQ_214(...) \, +#define Z_IS_215_EQ_215(...) \, +#define Z_IS_216_EQ_216(...) \, +#define Z_IS_217_EQ_217(...) \, +#define Z_IS_218_EQ_218(...) \, +#define Z_IS_219_EQ_219(...) \, +#define Z_IS_220_EQ_220(...) \, +#define Z_IS_221_EQ_221(...) \, +#define Z_IS_222_EQ_222(...) \, +#define Z_IS_223_EQ_223(...) \, +#define Z_IS_224_EQ_224(...) \, +#define Z_IS_225_EQ_225(...) \, +#define Z_IS_226_EQ_226(...) \, +#define Z_IS_227_EQ_227(...) \, +#define Z_IS_228_EQ_228(...) \, +#define Z_IS_229_EQ_229(...) \, +#define Z_IS_230_EQ_230(...) \, +#define Z_IS_231_EQ_231(...) \, +#define Z_IS_232_EQ_232(...) \, +#define Z_IS_233_EQ_233(...) \, +#define Z_IS_234_EQ_234(...) \, +#define Z_IS_235_EQ_235(...) \, +#define Z_IS_236_EQ_236(...) \, +#define Z_IS_237_EQ_237(...) \, +#define Z_IS_238_EQ_238(...) \, +#define Z_IS_239_EQ_239(...) \, +#define Z_IS_240_EQ_240(...) \, +#define Z_IS_241_EQ_241(...) \, +#define Z_IS_242_EQ_242(...) \, +#define Z_IS_243_EQ_243(...) \, +#define Z_IS_244_EQ_244(...) \, +#define Z_IS_245_EQ_245(...) \, +#define Z_IS_246_EQ_246(...) \, +#define Z_IS_247_EQ_247(...) \, +#define Z_IS_248_EQ_248(...) \, +#define Z_IS_249_EQ_249(...) \, +#define Z_IS_250_EQ_250(...) \, +#define Z_IS_251_EQ_251(...) \, +#define Z_IS_252_EQ_252(...) \, +#define Z_IS_253_EQ_253(...) \, +#define Z_IS_254_EQ_254(...) \, +#define Z_IS_255_EQ_255(...) \, +#define Z_IS_256_EQ_256(...) \, +#define Z_IS_257_EQ_257(...) \, +#define Z_IS_258_EQ_258(...) \, +#define Z_IS_259_EQ_259(...) \, +#define Z_IS_260_EQ_260(...) \, +#define Z_IS_261_EQ_261(...) \, +#define Z_IS_262_EQ_262(...) \, +#define Z_IS_263_EQ_263(...) \, +#define Z_IS_264_EQ_264(...) \, +#define Z_IS_265_EQ_265(...) \, +#define Z_IS_266_EQ_266(...) \, +#define Z_IS_267_EQ_267(...) \, +#define Z_IS_268_EQ_268(...) \, +#define Z_IS_269_EQ_269(...) \, +#define Z_IS_270_EQ_270(...) \, +#define Z_IS_271_EQ_271(...) \, +#define Z_IS_272_EQ_272(...) \, +#define Z_IS_273_EQ_273(...) \, +#define Z_IS_274_EQ_274(...) \, +#define Z_IS_275_EQ_275(...) \, +#define Z_IS_276_EQ_276(...) \, +#define Z_IS_277_EQ_277(...) \, +#define Z_IS_278_EQ_278(...) \, +#define Z_IS_279_EQ_279(...) \, +#define Z_IS_280_EQ_280(...) \, +#define Z_IS_281_EQ_281(...) \, +#define Z_IS_282_EQ_282(...) \, +#define Z_IS_283_EQ_283(...) \, +#define Z_IS_284_EQ_284(...) \, +#define Z_IS_285_EQ_285(...) \, +#define Z_IS_286_EQ_286(...) \, +#define Z_IS_287_EQ_287(...) \, +#define Z_IS_288_EQ_288(...) \, +#define Z_IS_289_EQ_289(...) \, +#define Z_IS_290_EQ_290(...) \, +#define Z_IS_291_EQ_291(...) \, +#define Z_IS_292_EQ_292(...) \, +#define Z_IS_293_EQ_293(...) \, +#define Z_IS_294_EQ_294(...) \, +#define Z_IS_295_EQ_295(...) \, +#define Z_IS_296_EQ_296(...) \, +#define Z_IS_297_EQ_297(...) \, +#define Z_IS_298_EQ_298(...) \, +#define Z_IS_299_EQ_299(...) \, +#define Z_IS_300_EQ_300(...) \, +#define Z_IS_301_EQ_301(...) \, +#define Z_IS_302_EQ_302(...) \, +#define Z_IS_303_EQ_303(...) \, +#define Z_IS_304_EQ_304(...) \, +#define Z_IS_305_EQ_305(...) \, +#define Z_IS_306_EQ_306(...) \, +#define Z_IS_307_EQ_307(...) \, +#define Z_IS_308_EQ_308(...) \, +#define Z_IS_309_EQ_309(...) \, +#define Z_IS_310_EQ_310(...) \, +#define Z_IS_311_EQ_311(...) \, +#define Z_IS_312_EQ_312(...) \, +#define Z_IS_313_EQ_313(...) \, +#define Z_IS_314_EQ_314(...) \, +#define Z_IS_315_EQ_315(...) \, +#define Z_IS_316_EQ_316(...) \, +#define Z_IS_317_EQ_317(...) \, +#define Z_IS_318_EQ_318(...) \, +#define Z_IS_319_EQ_319(...) \, +#define Z_IS_320_EQ_320(...) \, +#define Z_IS_321_EQ_321(...) \, +#define Z_IS_322_EQ_322(...) \, +#define Z_IS_323_EQ_323(...) \, +#define Z_IS_324_EQ_324(...) \, +#define Z_IS_325_EQ_325(...) \, +#define Z_IS_326_EQ_326(...) \, +#define Z_IS_327_EQ_327(...) \, +#define Z_IS_328_EQ_328(...) \, +#define Z_IS_329_EQ_329(...) \, +#define Z_IS_330_EQ_330(...) \, +#define Z_IS_331_EQ_331(...) \, +#define Z_IS_332_EQ_332(...) \, +#define Z_IS_333_EQ_333(...) \, +#define Z_IS_334_EQ_334(...) \, +#define Z_IS_335_EQ_335(...) \, +#define Z_IS_336_EQ_336(...) \, +#define Z_IS_337_EQ_337(...) \, +#define Z_IS_338_EQ_338(...) \, +#define Z_IS_339_EQ_339(...) \, +#define Z_IS_340_EQ_340(...) \, +#define Z_IS_341_EQ_341(...) \, +#define Z_IS_342_EQ_342(...) \, +#define Z_IS_343_EQ_343(...) \, +#define Z_IS_344_EQ_344(...) \, +#define Z_IS_345_EQ_345(...) \, +#define Z_IS_346_EQ_346(...) \, +#define Z_IS_347_EQ_347(...) \, +#define Z_IS_348_EQ_348(...) \, +#define Z_IS_349_EQ_349(...) \, +#define Z_IS_350_EQ_350(...) \, +#define Z_IS_351_EQ_351(...) \, +#define Z_IS_352_EQ_352(...) \, +#define Z_IS_353_EQ_353(...) \, +#define Z_IS_354_EQ_354(...) \, +#define Z_IS_355_EQ_355(...) \, +#define Z_IS_356_EQ_356(...) \, +#define Z_IS_357_EQ_357(...) \, +#define Z_IS_358_EQ_358(...) \, +#define Z_IS_359_EQ_359(...) \, +#define Z_IS_360_EQ_360(...) \, +#define Z_IS_361_EQ_361(...) \, +#define Z_IS_362_EQ_362(...) \, +#define Z_IS_363_EQ_363(...) \, +#define Z_IS_364_EQ_364(...) \, +#define Z_IS_365_EQ_365(...) \, +#define Z_IS_366_EQ_366(...) \, +#define Z_IS_367_EQ_367(...) \, +#define Z_IS_368_EQ_368(...) \, +#define Z_IS_369_EQ_369(...) \, +#define Z_IS_370_EQ_370(...) \, +#define Z_IS_371_EQ_371(...) \, +#define Z_IS_372_EQ_372(...) \, +#define Z_IS_373_EQ_373(...) \, +#define Z_IS_374_EQ_374(...) \, +#define Z_IS_375_EQ_375(...) \, +#define Z_IS_376_EQ_376(...) \, +#define Z_IS_377_EQ_377(...) \, +#define Z_IS_378_EQ_378(...) \, +#define Z_IS_379_EQ_379(...) \, +#define Z_IS_380_EQ_380(...) \, +#define Z_IS_381_EQ_381(...) \, +#define Z_IS_382_EQ_382(...) \, +#define Z_IS_383_EQ_383(...) \, +#define Z_IS_384_EQ_384(...) \, +#define Z_IS_385_EQ_385(...) \, +#define Z_IS_386_EQ_386(...) \, +#define Z_IS_387_EQ_387(...) \, +#define Z_IS_388_EQ_388(...) \, +#define Z_IS_389_EQ_389(...) \, +#define Z_IS_390_EQ_390(...) \, +#define Z_IS_391_EQ_391(...) \, +#define Z_IS_392_EQ_392(...) \, +#define Z_IS_393_EQ_393(...) \, +#define Z_IS_394_EQ_394(...) \, +#define Z_IS_395_EQ_395(...) \, +#define Z_IS_396_EQ_396(...) \, +#define Z_IS_397_EQ_397(...) \, +#define Z_IS_398_EQ_398(...) \, +#define Z_IS_399_EQ_399(...) \, +#define Z_IS_400_EQ_400(...) \, +#define Z_IS_401_EQ_401(...) \, +#define Z_IS_402_EQ_402(...) \, +#define Z_IS_403_EQ_403(...) \, +#define Z_IS_404_EQ_404(...) \, +#define Z_IS_405_EQ_405(...) \, +#define Z_IS_406_EQ_406(...) \, +#define Z_IS_407_EQ_407(...) \, +#define Z_IS_408_EQ_408(...) \, +#define Z_IS_409_EQ_409(...) \, +#define Z_IS_410_EQ_410(...) \, +#define Z_IS_411_EQ_411(...) \, +#define Z_IS_412_EQ_412(...) \, +#define Z_IS_413_EQ_413(...) \, +#define Z_IS_414_EQ_414(...) \, +#define Z_IS_415_EQ_415(...) \, +#define Z_IS_416_EQ_416(...) \, +#define Z_IS_417_EQ_417(...) \, +#define Z_IS_418_EQ_418(...) \, +#define Z_IS_419_EQ_419(...) \, +#define Z_IS_420_EQ_420(...) \, +#define Z_IS_421_EQ_421(...) \, +#define Z_IS_422_EQ_422(...) \, +#define Z_IS_423_EQ_423(...) \, +#define Z_IS_424_EQ_424(...) \, +#define Z_IS_425_EQ_425(...) \, +#define Z_IS_426_EQ_426(...) \, +#define Z_IS_427_EQ_427(...) \, +#define Z_IS_428_EQ_428(...) \, +#define Z_IS_429_EQ_429(...) \, +#define Z_IS_430_EQ_430(...) \, +#define Z_IS_431_EQ_431(...) \, +#define Z_IS_432_EQ_432(...) \, +#define Z_IS_433_EQ_433(...) \, +#define Z_IS_434_EQ_434(...) \, +#define Z_IS_435_EQ_435(...) \, +#define Z_IS_436_EQ_436(...) \, +#define Z_IS_437_EQ_437(...) \, +#define Z_IS_438_EQ_438(...) \, +#define Z_IS_439_EQ_439(...) \, +#define Z_IS_440_EQ_440(...) \, +#define Z_IS_441_EQ_441(...) \, +#define Z_IS_442_EQ_442(...) \, +#define Z_IS_443_EQ_443(...) \, +#define Z_IS_444_EQ_444(...) \, +#define Z_IS_445_EQ_445(...) \, +#define Z_IS_446_EQ_446(...) \, +#define Z_IS_447_EQ_447(...) \, +#define Z_IS_448_EQ_448(...) \, +#define Z_IS_449_EQ_449(...) \, +#define Z_IS_450_EQ_450(...) \, +#define Z_IS_451_EQ_451(...) \, +#define Z_IS_452_EQ_452(...) \, +#define Z_IS_453_EQ_453(...) \, +#define Z_IS_454_EQ_454(...) \, +#define Z_IS_455_EQ_455(...) \, +#define Z_IS_456_EQ_456(...) \, +#define Z_IS_457_EQ_457(...) \, +#define Z_IS_458_EQ_458(...) \, +#define Z_IS_459_EQ_459(...) \, +#define Z_IS_460_EQ_460(...) \, +#define Z_IS_461_EQ_461(...) \, +#define Z_IS_462_EQ_462(...) \, +#define Z_IS_463_EQ_463(...) \, +#define Z_IS_464_EQ_464(...) \, +#define Z_IS_465_EQ_465(...) \, +#define Z_IS_466_EQ_466(...) \, +#define Z_IS_467_EQ_467(...) \, +#define Z_IS_468_EQ_468(...) \, +#define Z_IS_469_EQ_469(...) \, +#define Z_IS_470_EQ_470(...) \, +#define Z_IS_471_EQ_471(...) \, +#define Z_IS_472_EQ_472(...) \, +#define Z_IS_473_EQ_473(...) \, +#define Z_IS_474_EQ_474(...) \, +#define Z_IS_475_EQ_475(...) \, +#define Z_IS_476_EQ_476(...) \, +#define Z_IS_477_EQ_477(...) \, +#define Z_IS_478_EQ_478(...) \, +#define Z_IS_479_EQ_479(...) \, +#define Z_IS_480_EQ_480(...) \, +#define Z_IS_481_EQ_481(...) \, +#define Z_IS_482_EQ_482(...) \, +#define Z_IS_483_EQ_483(...) \, +#define Z_IS_484_EQ_484(...) \, +#define Z_IS_485_EQ_485(...) \, +#define Z_IS_486_EQ_486(...) \, +#define Z_IS_487_EQ_487(...) \, +#define Z_IS_488_EQ_488(...) \, +#define Z_IS_489_EQ_489(...) \, +#define Z_IS_490_EQ_490(...) \, +#define Z_IS_491_EQ_491(...) \, +#define Z_IS_492_EQ_492(...) \, +#define Z_IS_493_EQ_493(...) \, +#define Z_IS_494_EQ_494(...) \, +#define Z_IS_495_EQ_495(...) \, +#define Z_IS_496_EQ_496(...) \, +#define Z_IS_497_EQ_497(...) \, +#define Z_IS_498_EQ_498(...) \, +#define Z_IS_499_EQ_499(...) \, +#define Z_IS_500_EQ_500(...) \, +#define Z_IS_501_EQ_501(...) \, +#define Z_IS_502_EQ_502(...) \, +#define Z_IS_503_EQ_503(...) \, +#define Z_IS_504_EQ_504(...) \, +#define Z_IS_505_EQ_505(...) \, +#define Z_IS_506_EQ_506(...) \, +#define Z_IS_507_EQ_507(...) \, +#define Z_IS_508_EQ_508(...) \, +#define Z_IS_509_EQ_509(...) \, +#define Z_IS_510_EQ_510(...) \, +#define Z_IS_511_EQ_511(...) \, +#define Z_IS_512_EQ_512(...) \, +#define Z_IS_513_EQ_513(...) \, +#define Z_IS_514_EQ_514(...) \, +#define Z_IS_515_EQ_515(...) \, +#define Z_IS_516_EQ_516(...) \, +#define Z_IS_517_EQ_517(...) \, +#define Z_IS_518_EQ_518(...) \, +#define Z_IS_519_EQ_519(...) \, +#define Z_IS_520_EQ_520(...) \, +#define Z_IS_521_EQ_521(...) \, +#define Z_IS_522_EQ_522(...) \, +#define Z_IS_523_EQ_523(...) \, +#define Z_IS_524_EQ_524(...) \, +#define Z_IS_525_EQ_525(...) \, +#define Z_IS_526_EQ_526(...) \, +#define Z_IS_527_EQ_527(...) \, +#define Z_IS_528_EQ_528(...) \, +#define Z_IS_529_EQ_529(...) \, +#define Z_IS_530_EQ_530(...) \, +#define Z_IS_531_EQ_531(...) \, +#define Z_IS_532_EQ_532(...) \, +#define Z_IS_533_EQ_533(...) \, +#define Z_IS_534_EQ_534(...) \, +#define Z_IS_535_EQ_535(...) \, +#define Z_IS_536_EQ_536(...) \, +#define Z_IS_537_EQ_537(...) \, +#define Z_IS_538_EQ_538(...) \, +#define Z_IS_539_EQ_539(...) \, +#define Z_IS_540_EQ_540(...) \, +#define Z_IS_541_EQ_541(...) \, +#define Z_IS_542_EQ_542(...) \, +#define Z_IS_543_EQ_543(...) \, +#define Z_IS_544_EQ_544(...) \, +#define Z_IS_545_EQ_545(...) \, +#define Z_IS_546_EQ_546(...) \, +#define Z_IS_547_EQ_547(...) \, +#define Z_IS_548_EQ_548(...) \, +#define Z_IS_549_EQ_549(...) \, +#define Z_IS_550_EQ_550(...) \, +#define Z_IS_551_EQ_551(...) \, +#define Z_IS_552_EQ_552(...) \, +#define Z_IS_553_EQ_553(...) \, +#define Z_IS_554_EQ_554(...) \, +#define Z_IS_555_EQ_555(...) \, +#define Z_IS_556_EQ_556(...) \, +#define Z_IS_557_EQ_557(...) \, +#define Z_IS_558_EQ_558(...) \, +#define Z_IS_559_EQ_559(...) \, +#define Z_IS_560_EQ_560(...) \, +#define Z_IS_561_EQ_561(...) \, +#define Z_IS_562_EQ_562(...) \, +#define Z_IS_563_EQ_563(...) \, +#define Z_IS_564_EQ_564(...) \, +#define Z_IS_565_EQ_565(...) \, +#define Z_IS_566_EQ_566(...) \, +#define Z_IS_567_EQ_567(...) \, +#define Z_IS_568_EQ_568(...) \, +#define Z_IS_569_EQ_569(...) \, +#define Z_IS_570_EQ_570(...) \, +#define Z_IS_571_EQ_571(...) \, +#define Z_IS_572_EQ_572(...) \, +#define Z_IS_573_EQ_573(...) \, +#define Z_IS_574_EQ_574(...) \, +#define Z_IS_575_EQ_575(...) \, +#define Z_IS_576_EQ_576(...) \, +#define Z_IS_577_EQ_577(...) \, +#define Z_IS_578_EQ_578(...) \, +#define Z_IS_579_EQ_579(...) \, +#define Z_IS_580_EQ_580(...) \, +#define Z_IS_581_EQ_581(...) \, +#define Z_IS_582_EQ_582(...) \, +#define Z_IS_583_EQ_583(...) \, +#define Z_IS_584_EQ_584(...) \, +#define Z_IS_585_EQ_585(...) \, +#define Z_IS_586_EQ_586(...) \, +#define Z_IS_587_EQ_587(...) \, +#define Z_IS_588_EQ_588(...) \, +#define Z_IS_589_EQ_589(...) \, +#define Z_IS_590_EQ_590(...) \, +#define Z_IS_591_EQ_591(...) \, +#define Z_IS_592_EQ_592(...) \, +#define Z_IS_593_EQ_593(...) \, +#define Z_IS_594_EQ_594(...) \, +#define Z_IS_595_EQ_595(...) \, +#define Z_IS_596_EQ_596(...) \, +#define Z_IS_597_EQ_597(...) \, +#define Z_IS_598_EQ_598(...) \, +#define Z_IS_599_EQ_599(...) \, +#define Z_IS_600_EQ_600(...) \, +#define Z_IS_601_EQ_601(...) \, +#define Z_IS_602_EQ_602(...) \, +#define Z_IS_603_EQ_603(...) \, +#define Z_IS_604_EQ_604(...) \, +#define Z_IS_605_EQ_605(...) \, +#define Z_IS_606_EQ_606(...) \, +#define Z_IS_607_EQ_607(...) \, +#define Z_IS_608_EQ_608(...) \, +#define Z_IS_609_EQ_609(...) \, +#define Z_IS_610_EQ_610(...) \, +#define Z_IS_611_EQ_611(...) \, +#define Z_IS_612_EQ_612(...) \, +#define Z_IS_613_EQ_613(...) \, +#define Z_IS_614_EQ_614(...) \, +#define Z_IS_615_EQ_615(...) \, +#define Z_IS_616_EQ_616(...) \, +#define Z_IS_617_EQ_617(...) \, +#define Z_IS_618_EQ_618(...) \, +#define Z_IS_619_EQ_619(...) \, +#define Z_IS_620_EQ_620(...) \, +#define Z_IS_621_EQ_621(...) \, +#define Z_IS_622_EQ_622(...) \, +#define Z_IS_623_EQ_623(...) \, +#define Z_IS_624_EQ_624(...) \, +#define Z_IS_625_EQ_625(...) \, +#define Z_IS_626_EQ_626(...) \, +#define Z_IS_627_EQ_627(...) \, +#define Z_IS_628_EQ_628(...) \, +#define Z_IS_629_EQ_629(...) \, +#define Z_IS_630_EQ_630(...) \, +#define Z_IS_631_EQ_631(...) \, +#define Z_IS_632_EQ_632(...) \, +#define Z_IS_633_EQ_633(...) \, +#define Z_IS_634_EQ_634(...) \, +#define Z_IS_635_EQ_635(...) \, +#define Z_IS_636_EQ_636(...) \, +#define Z_IS_637_EQ_637(...) \, +#define Z_IS_638_EQ_638(...) \, +#define Z_IS_639_EQ_639(...) \, +#define Z_IS_640_EQ_640(...) \, +#define Z_IS_641_EQ_641(...) \, +#define Z_IS_642_EQ_642(...) \, +#define Z_IS_643_EQ_643(...) \, +#define Z_IS_644_EQ_644(...) \, +#define Z_IS_645_EQ_645(...) \, +#define Z_IS_646_EQ_646(...) \, +#define Z_IS_647_EQ_647(...) \, +#define Z_IS_648_EQ_648(...) \, +#define Z_IS_649_EQ_649(...) \, +#define Z_IS_650_EQ_650(...) \, +#define Z_IS_651_EQ_651(...) \, +#define Z_IS_652_EQ_652(...) \, +#define Z_IS_653_EQ_653(...) \, +#define Z_IS_654_EQ_654(...) \, +#define Z_IS_655_EQ_655(...) \, +#define Z_IS_656_EQ_656(...) \, +#define Z_IS_657_EQ_657(...) \, +#define Z_IS_658_EQ_658(...) \, +#define Z_IS_659_EQ_659(...) \, +#define Z_IS_660_EQ_660(...) \, +#define Z_IS_661_EQ_661(...) \, +#define Z_IS_662_EQ_662(...) \, +#define Z_IS_663_EQ_663(...) \, +#define Z_IS_664_EQ_664(...) \, +#define Z_IS_665_EQ_665(...) \, +#define Z_IS_666_EQ_666(...) \, +#define Z_IS_667_EQ_667(...) \, +#define Z_IS_668_EQ_668(...) \, +#define Z_IS_669_EQ_669(...) \, +#define Z_IS_670_EQ_670(...) \, +#define Z_IS_671_EQ_671(...) \, +#define Z_IS_672_EQ_672(...) \, +#define Z_IS_673_EQ_673(...) \, +#define Z_IS_674_EQ_674(...) \, +#define Z_IS_675_EQ_675(...) \, +#define Z_IS_676_EQ_676(...) \, +#define Z_IS_677_EQ_677(...) \, +#define Z_IS_678_EQ_678(...) \, +#define Z_IS_679_EQ_679(...) \, +#define Z_IS_680_EQ_680(...) \, +#define Z_IS_681_EQ_681(...) \, +#define Z_IS_682_EQ_682(...) \, +#define Z_IS_683_EQ_683(...) \, +#define Z_IS_684_EQ_684(...) \, +#define Z_IS_685_EQ_685(...) \, +#define Z_IS_686_EQ_686(...) \, +#define Z_IS_687_EQ_687(...) \, +#define Z_IS_688_EQ_688(...) \, +#define Z_IS_689_EQ_689(...) \, +#define Z_IS_690_EQ_690(...) \, +#define Z_IS_691_EQ_691(...) \, +#define Z_IS_692_EQ_692(...) \, +#define Z_IS_693_EQ_693(...) \, +#define Z_IS_694_EQ_694(...) \, +#define Z_IS_695_EQ_695(...) \, +#define Z_IS_696_EQ_696(...) \, +#define Z_IS_697_EQ_697(...) \, +#define Z_IS_698_EQ_698(...) \, +#define Z_IS_699_EQ_699(...) \, +#define Z_IS_700_EQ_700(...) \, +#define Z_IS_701_EQ_701(...) \, +#define Z_IS_702_EQ_702(...) \, +#define Z_IS_703_EQ_703(...) \, +#define Z_IS_704_EQ_704(...) \, +#define Z_IS_705_EQ_705(...) \, +#define Z_IS_706_EQ_706(...) \, +#define Z_IS_707_EQ_707(...) \, +#define Z_IS_708_EQ_708(...) \, +#define Z_IS_709_EQ_709(...) \, +#define Z_IS_710_EQ_710(...) \, +#define Z_IS_711_EQ_711(...) \, +#define Z_IS_712_EQ_712(...) \, +#define Z_IS_713_EQ_713(...) \, +#define Z_IS_714_EQ_714(...) \, +#define Z_IS_715_EQ_715(...) \, +#define Z_IS_716_EQ_716(...) \, +#define Z_IS_717_EQ_717(...) \, +#define Z_IS_718_EQ_718(...) \, +#define Z_IS_719_EQ_719(...) \, +#define Z_IS_720_EQ_720(...) \, +#define Z_IS_721_EQ_721(...) \, +#define Z_IS_722_EQ_722(...) \, +#define Z_IS_723_EQ_723(...) \, +#define Z_IS_724_EQ_724(...) \, +#define Z_IS_725_EQ_725(...) \, +#define Z_IS_726_EQ_726(...) \, +#define Z_IS_727_EQ_727(...) \, +#define Z_IS_728_EQ_728(...) \, +#define Z_IS_729_EQ_729(...) \, +#define Z_IS_730_EQ_730(...) \, +#define Z_IS_731_EQ_731(...) \, +#define Z_IS_732_EQ_732(...) \, +#define Z_IS_733_EQ_733(...) \, +#define Z_IS_734_EQ_734(...) \, +#define Z_IS_735_EQ_735(...) \, +#define Z_IS_736_EQ_736(...) \, +#define Z_IS_737_EQ_737(...) \, +#define Z_IS_738_EQ_738(...) \, +#define Z_IS_739_EQ_739(...) \, +#define Z_IS_740_EQ_740(...) \, +#define Z_IS_741_EQ_741(...) \, +#define Z_IS_742_EQ_742(...) \, +#define Z_IS_743_EQ_743(...) \, +#define Z_IS_744_EQ_744(...) \, +#define Z_IS_745_EQ_745(...) \, +#define Z_IS_746_EQ_746(...) \, +#define Z_IS_747_EQ_747(...) \, +#define Z_IS_748_EQ_748(...) \, +#define Z_IS_749_EQ_749(...) \, +#define Z_IS_750_EQ_750(...) \, +#define Z_IS_751_EQ_751(...) \, +#define Z_IS_752_EQ_752(...) \, +#define Z_IS_753_EQ_753(...) \, +#define Z_IS_754_EQ_754(...) \, +#define Z_IS_755_EQ_755(...) \, +#define Z_IS_756_EQ_756(...) \, +#define Z_IS_757_EQ_757(...) \, +#define Z_IS_758_EQ_758(...) \, +#define Z_IS_759_EQ_759(...) \, +#define Z_IS_760_EQ_760(...) \, +#define Z_IS_761_EQ_761(...) \, +#define Z_IS_762_EQ_762(...) \, +#define Z_IS_763_EQ_763(...) \, +#define Z_IS_764_EQ_764(...) \, +#define Z_IS_765_EQ_765(...) \, +#define Z_IS_766_EQ_766(...) \, +#define Z_IS_767_EQ_767(...) \, +#define Z_IS_768_EQ_768(...) \, +#define Z_IS_769_EQ_769(...) \, +#define Z_IS_770_EQ_770(...) \, +#define Z_IS_771_EQ_771(...) \, +#define Z_IS_772_EQ_772(...) \, +#define Z_IS_773_EQ_773(...) \, +#define Z_IS_774_EQ_774(...) \, +#define Z_IS_775_EQ_775(...) \, +#define Z_IS_776_EQ_776(...) \, +#define Z_IS_777_EQ_777(...) \, +#define Z_IS_778_EQ_778(...) \, +#define Z_IS_779_EQ_779(...) \, +#define Z_IS_780_EQ_780(...) \, +#define Z_IS_781_EQ_781(...) \, +#define Z_IS_782_EQ_782(...) \, +#define Z_IS_783_EQ_783(...) \, +#define Z_IS_784_EQ_784(...) \, +#define Z_IS_785_EQ_785(...) \, +#define Z_IS_786_EQ_786(...) \, +#define Z_IS_787_EQ_787(...) \, +#define Z_IS_788_EQ_788(...) \, +#define Z_IS_789_EQ_789(...) \, +#define Z_IS_790_EQ_790(...) \, +#define Z_IS_791_EQ_791(...) \, +#define Z_IS_792_EQ_792(...) \, +#define Z_IS_793_EQ_793(...) \, +#define Z_IS_794_EQ_794(...) \, +#define Z_IS_795_EQ_795(...) \, +#define Z_IS_796_EQ_796(...) \, +#define Z_IS_797_EQ_797(...) \, +#define Z_IS_798_EQ_798(...) \, +#define Z_IS_799_EQ_799(...) \, +#define Z_IS_800_EQ_800(...) \, +#define Z_IS_801_EQ_801(...) \, +#define Z_IS_802_EQ_802(...) \, +#define Z_IS_803_EQ_803(...) \, +#define Z_IS_804_EQ_804(...) \, +#define Z_IS_805_EQ_805(...) \, +#define Z_IS_806_EQ_806(...) \, +#define Z_IS_807_EQ_807(...) \, +#define Z_IS_808_EQ_808(...) \, +#define Z_IS_809_EQ_809(...) \, +#define Z_IS_810_EQ_810(...) \, +#define Z_IS_811_EQ_811(...) \, +#define Z_IS_812_EQ_812(...) \, +#define Z_IS_813_EQ_813(...) \, +#define Z_IS_814_EQ_814(...) \, +#define Z_IS_815_EQ_815(...) \, +#define Z_IS_816_EQ_816(...) \, +#define Z_IS_817_EQ_817(...) \, +#define Z_IS_818_EQ_818(...) \, +#define Z_IS_819_EQ_819(...) \, +#define Z_IS_820_EQ_820(...) \, +#define Z_IS_821_EQ_821(...) \, +#define Z_IS_822_EQ_822(...) \, +#define Z_IS_823_EQ_823(...) \, +#define Z_IS_824_EQ_824(...) \, +#define Z_IS_825_EQ_825(...) \, +#define Z_IS_826_EQ_826(...) \, +#define Z_IS_827_EQ_827(...) \, +#define Z_IS_828_EQ_828(...) \, +#define Z_IS_829_EQ_829(...) \, +#define Z_IS_830_EQ_830(...) \, +#define Z_IS_831_EQ_831(...) \, +#define Z_IS_832_EQ_832(...) \, +#define Z_IS_833_EQ_833(...) \, +#define Z_IS_834_EQ_834(...) \, +#define Z_IS_835_EQ_835(...) \, +#define Z_IS_836_EQ_836(...) \, +#define Z_IS_837_EQ_837(...) \, +#define Z_IS_838_EQ_838(...) \, +#define Z_IS_839_EQ_839(...) \, +#define Z_IS_840_EQ_840(...) \, +#define Z_IS_841_EQ_841(...) \, +#define Z_IS_842_EQ_842(...) \, +#define Z_IS_843_EQ_843(...) \, +#define Z_IS_844_EQ_844(...) \, +#define Z_IS_845_EQ_845(...) \, +#define Z_IS_846_EQ_846(...) \, +#define Z_IS_847_EQ_847(...) \, +#define Z_IS_848_EQ_848(...) \, +#define Z_IS_849_EQ_849(...) \, +#define Z_IS_850_EQ_850(...) \, +#define Z_IS_851_EQ_851(...) \, +#define Z_IS_852_EQ_852(...) \, +#define Z_IS_853_EQ_853(...) \, +#define Z_IS_854_EQ_854(...) \, +#define Z_IS_855_EQ_855(...) \, +#define Z_IS_856_EQ_856(...) \, +#define Z_IS_857_EQ_857(...) \, +#define Z_IS_858_EQ_858(...) \, +#define Z_IS_859_EQ_859(...) \, +#define Z_IS_860_EQ_860(...) \, +#define Z_IS_861_EQ_861(...) \, +#define Z_IS_862_EQ_862(...) \, +#define Z_IS_863_EQ_863(...) \, +#define Z_IS_864_EQ_864(...) \, +#define Z_IS_865_EQ_865(...) \, +#define Z_IS_866_EQ_866(...) \, +#define Z_IS_867_EQ_867(...) \, +#define Z_IS_868_EQ_868(...) \, +#define Z_IS_869_EQ_869(...) \, +#define Z_IS_870_EQ_870(...) \, +#define Z_IS_871_EQ_871(...) \, +#define Z_IS_872_EQ_872(...) \, +#define Z_IS_873_EQ_873(...) \, +#define Z_IS_874_EQ_874(...) \, +#define Z_IS_875_EQ_875(...) \, +#define Z_IS_876_EQ_876(...) \, +#define Z_IS_877_EQ_877(...) \, +#define Z_IS_878_EQ_878(...) \, +#define Z_IS_879_EQ_879(...) \, +#define Z_IS_880_EQ_880(...) \, +#define Z_IS_881_EQ_881(...) \, +#define Z_IS_882_EQ_882(...) \, +#define Z_IS_883_EQ_883(...) \, +#define Z_IS_884_EQ_884(...) \, +#define Z_IS_885_EQ_885(...) \, +#define Z_IS_886_EQ_886(...) \, +#define Z_IS_887_EQ_887(...) \, +#define Z_IS_888_EQ_888(...) \, +#define Z_IS_889_EQ_889(...) \, +#define Z_IS_890_EQ_890(...) \, +#define Z_IS_891_EQ_891(...) \, +#define Z_IS_892_EQ_892(...) \, +#define Z_IS_893_EQ_893(...) \, +#define Z_IS_894_EQ_894(...) \, +#define Z_IS_895_EQ_895(...) \, +#define Z_IS_896_EQ_896(...) \, +#define Z_IS_897_EQ_897(...) \, +#define Z_IS_898_EQ_898(...) \, +#define Z_IS_899_EQ_899(...) \, +#define Z_IS_900_EQ_900(...) \, +#define Z_IS_901_EQ_901(...) \, +#define Z_IS_902_EQ_902(...) \, +#define Z_IS_903_EQ_903(...) \, +#define Z_IS_904_EQ_904(...) \, +#define Z_IS_905_EQ_905(...) \, +#define Z_IS_906_EQ_906(...) \, +#define Z_IS_907_EQ_907(...) \, +#define Z_IS_908_EQ_908(...) \, +#define Z_IS_909_EQ_909(...) \, +#define Z_IS_910_EQ_910(...) \, +#define Z_IS_911_EQ_911(...) \, +#define Z_IS_912_EQ_912(...) \, +#define Z_IS_913_EQ_913(...) \, +#define Z_IS_914_EQ_914(...) \, +#define Z_IS_915_EQ_915(...) \, +#define Z_IS_916_EQ_916(...) \, +#define Z_IS_917_EQ_917(...) \, +#define Z_IS_918_EQ_918(...) \, +#define Z_IS_919_EQ_919(...) \, +#define Z_IS_920_EQ_920(...) \, +#define Z_IS_921_EQ_921(...) \, +#define Z_IS_922_EQ_922(...) \, +#define Z_IS_923_EQ_923(...) \, +#define Z_IS_924_EQ_924(...) \, +#define Z_IS_925_EQ_925(...) \, +#define Z_IS_926_EQ_926(...) \, +#define Z_IS_927_EQ_927(...) \, +#define Z_IS_928_EQ_928(...) \, +#define Z_IS_929_EQ_929(...) \, +#define Z_IS_930_EQ_930(...) \, +#define Z_IS_931_EQ_931(...) \, +#define Z_IS_932_EQ_932(...) \, +#define Z_IS_933_EQ_933(...) \, +#define Z_IS_934_EQ_934(...) \, +#define Z_IS_935_EQ_935(...) \, +#define Z_IS_936_EQ_936(...) \, +#define Z_IS_937_EQ_937(...) \, +#define Z_IS_938_EQ_938(...) \, +#define Z_IS_939_EQ_939(...) \, +#define Z_IS_940_EQ_940(...) \, +#define Z_IS_941_EQ_941(...) \, +#define Z_IS_942_EQ_942(...) \, +#define Z_IS_943_EQ_943(...) \, +#define Z_IS_944_EQ_944(...) \, +#define Z_IS_945_EQ_945(...) \, +#define Z_IS_946_EQ_946(...) \, +#define Z_IS_947_EQ_947(...) \, +#define Z_IS_948_EQ_948(...) \, +#define Z_IS_949_EQ_949(...) \, +#define Z_IS_950_EQ_950(...) \, +#define Z_IS_951_EQ_951(...) \, +#define Z_IS_952_EQ_952(...) \, +#define Z_IS_953_EQ_953(...) \, +#define Z_IS_954_EQ_954(...) \, +#define Z_IS_955_EQ_955(...) \, +#define Z_IS_956_EQ_956(...) \, +#define Z_IS_957_EQ_957(...) \, +#define Z_IS_958_EQ_958(...) \, +#define Z_IS_959_EQ_959(...) \, +#define Z_IS_960_EQ_960(...) \, +#define Z_IS_961_EQ_961(...) \, +#define Z_IS_962_EQ_962(...) \, +#define Z_IS_963_EQ_963(...) \, +#define Z_IS_964_EQ_964(...) \, +#define Z_IS_965_EQ_965(...) \, +#define Z_IS_966_EQ_966(...) \, +#define Z_IS_967_EQ_967(...) \, +#define Z_IS_968_EQ_968(...) \, +#define Z_IS_969_EQ_969(...) \, +#define Z_IS_970_EQ_970(...) \, +#define Z_IS_971_EQ_971(...) \, +#define Z_IS_972_EQ_972(...) \, +#define Z_IS_973_EQ_973(...) \, +#define Z_IS_974_EQ_974(...) \, +#define Z_IS_975_EQ_975(...) \, +#define Z_IS_976_EQ_976(...) \, +#define Z_IS_977_EQ_977(...) \, +#define Z_IS_978_EQ_978(...) \, +#define Z_IS_979_EQ_979(...) \, +#define Z_IS_980_EQ_980(...) \, +#define Z_IS_981_EQ_981(...) \, +#define Z_IS_982_EQ_982(...) \, +#define Z_IS_983_EQ_983(...) \, +#define Z_IS_984_EQ_984(...) \, +#define Z_IS_985_EQ_985(...) \, +#define Z_IS_986_EQ_986(...) \, +#define Z_IS_987_EQ_987(...) \, +#define Z_IS_988_EQ_988(...) \, +#define Z_IS_989_EQ_989(...) \, +#define Z_IS_990_EQ_990(...) \, +#define Z_IS_991_EQ_991(...) \, +#define Z_IS_992_EQ_992(...) \, +#define Z_IS_993_EQ_993(...) \, +#define Z_IS_994_EQ_994(...) \, +#define Z_IS_995_EQ_995(...) \, +#define Z_IS_996_EQ_996(...) \, +#define Z_IS_997_EQ_997(...) \, +#define Z_IS_998_EQ_998(...) \, +#define Z_IS_999_EQ_999(...) \, +#define Z_IS_1000_EQ_1000(...) \, +#define Z_IS_1001_EQ_1001(...) \, +#define Z_IS_1002_EQ_1002(...) \, +#define Z_IS_1003_EQ_1003(...) \, +#define Z_IS_1004_EQ_1004(...) \, +#define Z_IS_1005_EQ_1005(...) \, +#define Z_IS_1006_EQ_1006(...) \, +#define Z_IS_1007_EQ_1007(...) \, +#define Z_IS_1008_EQ_1008(...) \, +#define Z_IS_1009_EQ_1009(...) \, +#define Z_IS_1010_EQ_1010(...) \, +#define Z_IS_1011_EQ_1011(...) \, +#define Z_IS_1012_EQ_1012(...) \, +#define Z_IS_1013_EQ_1013(...) \, +#define Z_IS_1014_EQ_1014(...) \, +#define Z_IS_1015_EQ_1015(...) \, +#define Z_IS_1016_EQ_1016(...) \, +#define Z_IS_1017_EQ_1017(...) \, +#define Z_IS_1018_EQ_1018(...) \, +#define Z_IS_1019_EQ_1019(...) \, +#define Z_IS_1020_EQ_1020(...) \, +#define Z_IS_1021_EQ_1021(...) \, +#define Z_IS_1022_EQ_1022(...) \, +#define Z_IS_1023_EQ_1023(...) \, +#define Z_IS_1024_EQ_1024(...) \, +#define Z_IS_1025_EQ_1025(...) \, +#define Z_IS_1026_EQ_1026(...) \, +#define Z_IS_1027_EQ_1027(...) \, +#define Z_IS_1028_EQ_1028(...) \, +#define Z_IS_1029_EQ_1029(...) \, +#define Z_IS_1030_EQ_1030(...) \, +#define Z_IS_1031_EQ_1031(...) \, +#define Z_IS_1032_EQ_1032(...) \, +#define Z_IS_1033_EQ_1033(...) \, +#define Z_IS_1034_EQ_1034(...) \, +#define Z_IS_1035_EQ_1035(...) \, +#define Z_IS_1036_EQ_1036(...) \, +#define Z_IS_1037_EQ_1037(...) \, +#define Z_IS_1038_EQ_1038(...) \, +#define Z_IS_1039_EQ_1039(...) \, +#define Z_IS_1040_EQ_1040(...) \, +#define Z_IS_1041_EQ_1041(...) \, +#define Z_IS_1042_EQ_1042(...) \, +#define Z_IS_1043_EQ_1043(...) \, +#define Z_IS_1044_EQ_1044(...) \, +#define Z_IS_1045_EQ_1045(...) \, +#define Z_IS_1046_EQ_1046(...) \, +#define Z_IS_1047_EQ_1047(...) \, +#define Z_IS_1048_EQ_1048(...) \, +#define Z_IS_1049_EQ_1049(...) \, +#define Z_IS_1050_EQ_1050(...) \, +#define Z_IS_1051_EQ_1051(...) \, +#define Z_IS_1052_EQ_1052(...) \, +#define Z_IS_1053_EQ_1053(...) \, +#define Z_IS_1054_EQ_1054(...) \, +#define Z_IS_1055_EQ_1055(...) \, +#define Z_IS_1056_EQ_1056(...) \, +#define Z_IS_1057_EQ_1057(...) \, +#define Z_IS_1058_EQ_1058(...) \, +#define Z_IS_1059_EQ_1059(...) \, +#define Z_IS_1060_EQ_1060(...) \, +#define Z_IS_1061_EQ_1061(...) \, +#define Z_IS_1062_EQ_1062(...) \, +#define Z_IS_1063_EQ_1063(...) \, +#define Z_IS_1064_EQ_1064(...) \, +#define Z_IS_1065_EQ_1065(...) \, +#define Z_IS_1066_EQ_1066(...) \, +#define Z_IS_1067_EQ_1067(...) \, +#define Z_IS_1068_EQ_1068(...) \, +#define Z_IS_1069_EQ_1069(...) \, +#define Z_IS_1070_EQ_1070(...) \, +#define Z_IS_1071_EQ_1071(...) \, +#define Z_IS_1072_EQ_1072(...) \, +#define Z_IS_1073_EQ_1073(...) \, +#define Z_IS_1074_EQ_1074(...) \, +#define Z_IS_1075_EQ_1075(...) \, +#define Z_IS_1076_EQ_1076(...) \, +#define Z_IS_1077_EQ_1077(...) \, +#define Z_IS_1078_EQ_1078(...) \, +#define Z_IS_1079_EQ_1079(...) \, +#define Z_IS_1080_EQ_1080(...) \, +#define Z_IS_1081_EQ_1081(...) \, +#define Z_IS_1082_EQ_1082(...) \, +#define Z_IS_1083_EQ_1083(...) \, +#define Z_IS_1084_EQ_1084(...) \, +#define Z_IS_1085_EQ_1085(...) \, +#define Z_IS_1086_EQ_1086(...) \, +#define Z_IS_1087_EQ_1087(...) \, +#define Z_IS_1088_EQ_1088(...) \, +#define Z_IS_1089_EQ_1089(...) \, +#define Z_IS_1090_EQ_1090(...) \, +#define Z_IS_1091_EQ_1091(...) \, +#define Z_IS_1092_EQ_1092(...) \, +#define Z_IS_1093_EQ_1093(...) \, +#define Z_IS_1094_EQ_1094(...) \, +#define Z_IS_1095_EQ_1095(...) \, +#define Z_IS_1096_EQ_1096(...) \, +#define Z_IS_1097_EQ_1097(...) \, +#define Z_IS_1098_EQ_1098(...) \, +#define Z_IS_1099_EQ_1099(...) \, +#define Z_IS_1100_EQ_1100(...) \, +#define Z_IS_1101_EQ_1101(...) \, +#define Z_IS_1102_EQ_1102(...) \, +#define Z_IS_1103_EQ_1103(...) \, +#define Z_IS_1104_EQ_1104(...) \, +#define Z_IS_1105_EQ_1105(...) \, +#define Z_IS_1106_EQ_1106(...) \, +#define Z_IS_1107_EQ_1107(...) \, +#define Z_IS_1108_EQ_1108(...) \, +#define Z_IS_1109_EQ_1109(...) \, +#define Z_IS_1110_EQ_1110(...) \, +#define Z_IS_1111_EQ_1111(...) \, +#define Z_IS_1112_EQ_1112(...) \, +#define Z_IS_1113_EQ_1113(...) \, +#define Z_IS_1114_EQ_1114(...) \, +#define Z_IS_1115_EQ_1115(...) \, +#define Z_IS_1116_EQ_1116(...) \, +#define Z_IS_1117_EQ_1117(...) \, +#define Z_IS_1118_EQ_1118(...) \, +#define Z_IS_1119_EQ_1119(...) \, +#define Z_IS_1120_EQ_1120(...) \, +#define Z_IS_1121_EQ_1121(...) \, +#define Z_IS_1122_EQ_1122(...) \, +#define Z_IS_1123_EQ_1123(...) \, +#define Z_IS_1124_EQ_1124(...) \, +#define Z_IS_1125_EQ_1125(...) \, +#define Z_IS_1126_EQ_1126(...) \, +#define Z_IS_1127_EQ_1127(...) \, +#define Z_IS_1128_EQ_1128(...) \, +#define Z_IS_1129_EQ_1129(...) \, +#define Z_IS_1130_EQ_1130(...) \, +#define Z_IS_1131_EQ_1131(...) \, +#define Z_IS_1132_EQ_1132(...) \, +#define Z_IS_1133_EQ_1133(...) \, +#define Z_IS_1134_EQ_1134(...) \, +#define Z_IS_1135_EQ_1135(...) \, +#define Z_IS_1136_EQ_1136(...) \, +#define Z_IS_1137_EQ_1137(...) \, +#define Z_IS_1138_EQ_1138(...) \, +#define Z_IS_1139_EQ_1139(...) \, +#define Z_IS_1140_EQ_1140(...) \, +#define Z_IS_1141_EQ_1141(...) \, +#define Z_IS_1142_EQ_1142(...) \, +#define Z_IS_1143_EQ_1143(...) \, +#define Z_IS_1144_EQ_1144(...) \, +#define Z_IS_1145_EQ_1145(...) \, +#define Z_IS_1146_EQ_1146(...) \, +#define Z_IS_1147_EQ_1147(...) \, +#define Z_IS_1148_EQ_1148(...) \, +#define Z_IS_1149_EQ_1149(...) \, +#define Z_IS_1150_EQ_1150(...) \, +#define Z_IS_1151_EQ_1151(...) \, +#define Z_IS_1152_EQ_1152(...) \, +#define Z_IS_1153_EQ_1153(...) \, +#define Z_IS_1154_EQ_1154(...) \, +#define Z_IS_1155_EQ_1155(...) \, +#define Z_IS_1156_EQ_1156(...) \, +#define Z_IS_1157_EQ_1157(...) \, +#define Z_IS_1158_EQ_1158(...) \, +#define Z_IS_1159_EQ_1159(...) \, +#define Z_IS_1160_EQ_1160(...) \, +#define Z_IS_1161_EQ_1161(...) \, +#define Z_IS_1162_EQ_1162(...) \, +#define Z_IS_1163_EQ_1163(...) \, +#define Z_IS_1164_EQ_1164(...) \, +#define Z_IS_1165_EQ_1165(...) \, +#define Z_IS_1166_EQ_1166(...) \, +#define Z_IS_1167_EQ_1167(...) \, +#define Z_IS_1168_EQ_1168(...) \, +#define Z_IS_1169_EQ_1169(...) \, +#define Z_IS_1170_EQ_1170(...) \, +#define Z_IS_1171_EQ_1171(...) \, +#define Z_IS_1172_EQ_1172(...) \, +#define Z_IS_1173_EQ_1173(...) \, +#define Z_IS_1174_EQ_1174(...) \, +#define Z_IS_1175_EQ_1175(...) \, +#define Z_IS_1176_EQ_1176(...) \, +#define Z_IS_1177_EQ_1177(...) \, +#define Z_IS_1178_EQ_1178(...) \, +#define Z_IS_1179_EQ_1179(...) \, +#define Z_IS_1180_EQ_1180(...) \, +#define Z_IS_1181_EQ_1181(...) \, +#define Z_IS_1182_EQ_1182(...) \, +#define Z_IS_1183_EQ_1183(...) \, +#define Z_IS_1184_EQ_1184(...) \, +#define Z_IS_1185_EQ_1185(...) \, +#define Z_IS_1186_EQ_1186(...) \, +#define Z_IS_1187_EQ_1187(...) \, +#define Z_IS_1188_EQ_1188(...) \, +#define Z_IS_1189_EQ_1189(...) \, +#define Z_IS_1190_EQ_1190(...) \, +#define Z_IS_1191_EQ_1191(...) \, +#define Z_IS_1192_EQ_1192(...) \, +#define Z_IS_1193_EQ_1193(...) \, +#define Z_IS_1194_EQ_1194(...) \, +#define Z_IS_1195_EQ_1195(...) \, +#define Z_IS_1196_EQ_1196(...) \, +#define Z_IS_1197_EQ_1197(...) \, +#define Z_IS_1198_EQ_1198(...) \, +#define Z_IS_1199_EQ_1199(...) \, +#define Z_IS_1200_EQ_1200(...) \, +#define Z_IS_1201_EQ_1201(...) \, +#define Z_IS_1202_EQ_1202(...) \, +#define Z_IS_1203_EQ_1203(...) \, +#define Z_IS_1204_EQ_1204(...) \, +#define Z_IS_1205_EQ_1205(...) \, +#define Z_IS_1206_EQ_1206(...) \, +#define Z_IS_1207_EQ_1207(...) \, +#define Z_IS_1208_EQ_1208(...) \, +#define Z_IS_1209_EQ_1209(...) \, +#define Z_IS_1210_EQ_1210(...) \, +#define Z_IS_1211_EQ_1211(...) \, +#define Z_IS_1212_EQ_1212(...) \, +#define Z_IS_1213_EQ_1213(...) \, +#define Z_IS_1214_EQ_1214(...) \, +#define Z_IS_1215_EQ_1215(...) \, +#define Z_IS_1216_EQ_1216(...) \, +#define Z_IS_1217_EQ_1217(...) \, +#define Z_IS_1218_EQ_1218(...) \, +#define Z_IS_1219_EQ_1219(...) \, +#define Z_IS_1220_EQ_1220(...) \, +#define Z_IS_1221_EQ_1221(...) \, +#define Z_IS_1222_EQ_1222(...) \, +#define Z_IS_1223_EQ_1223(...) \, +#define Z_IS_1224_EQ_1224(...) \, +#define Z_IS_1225_EQ_1225(...) \, +#define Z_IS_1226_EQ_1226(...) \, +#define Z_IS_1227_EQ_1227(...) \, +#define Z_IS_1228_EQ_1228(...) \, +#define Z_IS_1229_EQ_1229(...) \, +#define Z_IS_1230_EQ_1230(...) \, +#define Z_IS_1231_EQ_1231(...) \, +#define Z_IS_1232_EQ_1232(...) \, +#define Z_IS_1233_EQ_1233(...) \, +#define Z_IS_1234_EQ_1234(...) \, +#define Z_IS_1235_EQ_1235(...) \, +#define Z_IS_1236_EQ_1236(...) \, +#define Z_IS_1237_EQ_1237(...) \, +#define Z_IS_1238_EQ_1238(...) \, +#define Z_IS_1239_EQ_1239(...) \, +#define Z_IS_1240_EQ_1240(...) \, +#define Z_IS_1241_EQ_1241(...) \, +#define Z_IS_1242_EQ_1242(...) \, +#define Z_IS_1243_EQ_1243(...) \, +#define Z_IS_1244_EQ_1244(...) \, +#define Z_IS_1245_EQ_1245(...) \, +#define Z_IS_1246_EQ_1246(...) \, +#define Z_IS_1247_EQ_1247(...) \, +#define Z_IS_1248_EQ_1248(...) \, +#define Z_IS_1249_EQ_1249(...) \, +#define Z_IS_1250_EQ_1250(...) \, +#define Z_IS_1251_EQ_1251(...) \, +#define Z_IS_1252_EQ_1252(...) \, +#define Z_IS_1253_EQ_1253(...) \, +#define Z_IS_1254_EQ_1254(...) \, +#define Z_IS_1255_EQ_1255(...) \, +#define Z_IS_1256_EQ_1256(...) \, +#define Z_IS_1257_EQ_1257(...) \, +#define Z_IS_1258_EQ_1258(...) \, +#define Z_IS_1259_EQ_1259(...) \, +#define Z_IS_1260_EQ_1260(...) \, +#define Z_IS_1261_EQ_1261(...) \, +#define Z_IS_1262_EQ_1262(...) \, +#define Z_IS_1263_EQ_1263(...) \, +#define Z_IS_1264_EQ_1264(...) \, +#define Z_IS_1265_EQ_1265(...) \, +#define Z_IS_1266_EQ_1266(...) \, +#define Z_IS_1267_EQ_1267(...) \, +#define Z_IS_1268_EQ_1268(...) \, +#define Z_IS_1269_EQ_1269(...) \, +#define Z_IS_1270_EQ_1270(...) \, +#define Z_IS_1271_EQ_1271(...) \, +#define Z_IS_1272_EQ_1272(...) \, +#define Z_IS_1273_EQ_1273(...) \, +#define Z_IS_1274_EQ_1274(...) \, +#define Z_IS_1275_EQ_1275(...) \, +#define Z_IS_1276_EQ_1276(...) \, +#define Z_IS_1277_EQ_1277(...) \, +#define Z_IS_1278_EQ_1278(...) \, +#define Z_IS_1279_EQ_1279(...) \, +#define Z_IS_1280_EQ_1280(...) \, +#define Z_IS_1281_EQ_1281(...) \, +#define Z_IS_1282_EQ_1282(...) \, +#define Z_IS_1283_EQ_1283(...) \, +#define Z_IS_1284_EQ_1284(...) \, +#define Z_IS_1285_EQ_1285(...) \, +#define Z_IS_1286_EQ_1286(...) \, +#define Z_IS_1287_EQ_1287(...) \, +#define Z_IS_1288_EQ_1288(...) \, +#define Z_IS_1289_EQ_1289(...) \, +#define Z_IS_1290_EQ_1290(...) \, +#define Z_IS_1291_EQ_1291(...) \, +#define Z_IS_1292_EQ_1292(...) \, +#define Z_IS_1293_EQ_1293(...) \, +#define Z_IS_1294_EQ_1294(...) \, +#define Z_IS_1295_EQ_1295(...) \, +#define Z_IS_1296_EQ_1296(...) \, +#define Z_IS_1297_EQ_1297(...) \, +#define Z_IS_1298_EQ_1298(...) \, +#define Z_IS_1299_EQ_1299(...) \, +#define Z_IS_1300_EQ_1300(...) \, +#define Z_IS_1301_EQ_1301(...) \, +#define Z_IS_1302_EQ_1302(...) \, +#define Z_IS_1303_EQ_1303(...) \, +#define Z_IS_1304_EQ_1304(...) \, +#define Z_IS_1305_EQ_1305(...) \, +#define Z_IS_1306_EQ_1306(...) \, +#define Z_IS_1307_EQ_1307(...) \, +#define Z_IS_1308_EQ_1308(...) \, +#define Z_IS_1309_EQ_1309(...) \, +#define Z_IS_1310_EQ_1310(...) \, +#define Z_IS_1311_EQ_1311(...) \, +#define Z_IS_1312_EQ_1312(...) \, +#define Z_IS_1313_EQ_1313(...) \, +#define Z_IS_1314_EQ_1314(...) \, +#define Z_IS_1315_EQ_1315(...) \, +#define Z_IS_1316_EQ_1316(...) \, +#define Z_IS_1317_EQ_1317(...) \, +#define Z_IS_1318_EQ_1318(...) \, +#define Z_IS_1319_EQ_1319(...) \, +#define Z_IS_1320_EQ_1320(...) \, +#define Z_IS_1321_EQ_1321(...) \, +#define Z_IS_1322_EQ_1322(...) \, +#define Z_IS_1323_EQ_1323(...) \, +#define Z_IS_1324_EQ_1324(...) \, +#define Z_IS_1325_EQ_1325(...) \, +#define Z_IS_1326_EQ_1326(...) \, +#define Z_IS_1327_EQ_1327(...) \, +#define Z_IS_1328_EQ_1328(...) \, +#define Z_IS_1329_EQ_1329(...) \, +#define Z_IS_1330_EQ_1330(...) \, +#define Z_IS_1331_EQ_1331(...) \, +#define Z_IS_1332_EQ_1332(...) \, +#define Z_IS_1333_EQ_1333(...) \, +#define Z_IS_1334_EQ_1334(...) \, +#define Z_IS_1335_EQ_1335(...) \, +#define Z_IS_1336_EQ_1336(...) \, +#define Z_IS_1337_EQ_1337(...) \, +#define Z_IS_1338_EQ_1338(...) \, +#define Z_IS_1339_EQ_1339(...) \, +#define Z_IS_1340_EQ_1340(...) \, +#define Z_IS_1341_EQ_1341(...) \, +#define Z_IS_1342_EQ_1342(...) \, +#define Z_IS_1343_EQ_1343(...) \, +#define Z_IS_1344_EQ_1344(...) \, +#define Z_IS_1345_EQ_1345(...) \, +#define Z_IS_1346_EQ_1346(...) \, +#define Z_IS_1347_EQ_1347(...) \, +#define Z_IS_1348_EQ_1348(...) \, +#define Z_IS_1349_EQ_1349(...) \, +#define Z_IS_1350_EQ_1350(...) \, +#define Z_IS_1351_EQ_1351(...) \, +#define Z_IS_1352_EQ_1352(...) \, +#define Z_IS_1353_EQ_1353(...) \, +#define Z_IS_1354_EQ_1354(...) \, +#define Z_IS_1355_EQ_1355(...) \, +#define Z_IS_1356_EQ_1356(...) \, +#define Z_IS_1357_EQ_1357(...) \, +#define Z_IS_1358_EQ_1358(...) \, +#define Z_IS_1359_EQ_1359(...) \, +#define Z_IS_1360_EQ_1360(...) \, +#define Z_IS_1361_EQ_1361(...) \, +#define Z_IS_1362_EQ_1362(...) \, +#define Z_IS_1363_EQ_1363(...) \, +#define Z_IS_1364_EQ_1364(...) \, +#define Z_IS_1365_EQ_1365(...) \, +#define Z_IS_1366_EQ_1366(...) \, +#define Z_IS_1367_EQ_1367(...) \, +#define Z_IS_1368_EQ_1368(...) \, +#define Z_IS_1369_EQ_1369(...) \, +#define Z_IS_1370_EQ_1370(...) \, +#define Z_IS_1371_EQ_1371(...) \, +#define Z_IS_1372_EQ_1372(...) \, +#define Z_IS_1373_EQ_1373(...) \, +#define Z_IS_1374_EQ_1374(...) \, +#define Z_IS_1375_EQ_1375(...) \, +#define Z_IS_1376_EQ_1376(...) \, +#define Z_IS_1377_EQ_1377(...) \, +#define Z_IS_1378_EQ_1378(...) \, +#define Z_IS_1379_EQ_1379(...) \, +#define Z_IS_1380_EQ_1380(...) \, +#define Z_IS_1381_EQ_1381(...) \, +#define Z_IS_1382_EQ_1382(...) \, +#define Z_IS_1383_EQ_1383(...) \, +#define Z_IS_1384_EQ_1384(...) \, +#define Z_IS_1385_EQ_1385(...) \, +#define Z_IS_1386_EQ_1386(...) \, +#define Z_IS_1387_EQ_1387(...) \, +#define Z_IS_1388_EQ_1388(...) \, +#define Z_IS_1389_EQ_1389(...) \, +#define Z_IS_1390_EQ_1390(...) \, +#define Z_IS_1391_EQ_1391(...) \, +#define Z_IS_1392_EQ_1392(...) \, +#define Z_IS_1393_EQ_1393(...) \, +#define Z_IS_1394_EQ_1394(...) \, +#define Z_IS_1395_EQ_1395(...) \, +#define Z_IS_1396_EQ_1396(...) \, +#define Z_IS_1397_EQ_1397(...) \, +#define Z_IS_1398_EQ_1398(...) \, +#define Z_IS_1399_EQ_1399(...) \, +#define Z_IS_1400_EQ_1400(...) \, +#define Z_IS_1401_EQ_1401(...) \, +#define Z_IS_1402_EQ_1402(...) \, +#define Z_IS_1403_EQ_1403(...) \, +#define Z_IS_1404_EQ_1404(...) \, +#define Z_IS_1405_EQ_1405(...) \, +#define Z_IS_1406_EQ_1406(...) \, +#define Z_IS_1407_EQ_1407(...) \, +#define Z_IS_1408_EQ_1408(...) \, +#define Z_IS_1409_EQ_1409(...) \, +#define Z_IS_1410_EQ_1410(...) \, +#define Z_IS_1411_EQ_1411(...) \, +#define Z_IS_1412_EQ_1412(...) \, +#define Z_IS_1413_EQ_1413(...) \, +#define Z_IS_1414_EQ_1414(...) \, +#define Z_IS_1415_EQ_1415(...) \, +#define Z_IS_1416_EQ_1416(...) \, +#define Z_IS_1417_EQ_1417(...) \, +#define Z_IS_1418_EQ_1418(...) \, +#define Z_IS_1419_EQ_1419(...) \, +#define Z_IS_1420_EQ_1420(...) \, +#define Z_IS_1421_EQ_1421(...) \, +#define Z_IS_1422_EQ_1422(...) \, +#define Z_IS_1423_EQ_1423(...) \, +#define Z_IS_1424_EQ_1424(...) \, +#define Z_IS_1425_EQ_1425(...) \, +#define Z_IS_1426_EQ_1426(...) \, +#define Z_IS_1427_EQ_1427(...) \, +#define Z_IS_1428_EQ_1428(...) \, +#define Z_IS_1429_EQ_1429(...) \, +#define Z_IS_1430_EQ_1430(...) \, +#define Z_IS_1431_EQ_1431(...) \, +#define Z_IS_1432_EQ_1432(...) \, +#define Z_IS_1433_EQ_1433(...) \, +#define Z_IS_1434_EQ_1434(...) \, +#define Z_IS_1435_EQ_1435(...) \, +#define Z_IS_1436_EQ_1436(...) \, +#define Z_IS_1437_EQ_1437(...) \, +#define Z_IS_1438_EQ_1438(...) \, +#define Z_IS_1439_EQ_1439(...) \, +#define Z_IS_1440_EQ_1440(...) \, +#define Z_IS_1441_EQ_1441(...) \, +#define Z_IS_1442_EQ_1442(...) \, +#define Z_IS_1443_EQ_1443(...) \, +#define Z_IS_1444_EQ_1444(...) \, +#define Z_IS_1445_EQ_1445(...) \, +#define Z_IS_1446_EQ_1446(...) \, +#define Z_IS_1447_EQ_1447(...) \, +#define Z_IS_1448_EQ_1448(...) \, +#define Z_IS_1449_EQ_1449(...) \, +#define Z_IS_1450_EQ_1450(...) \, +#define Z_IS_1451_EQ_1451(...) \, +#define Z_IS_1452_EQ_1452(...) \, +#define Z_IS_1453_EQ_1453(...) \, +#define Z_IS_1454_EQ_1454(...) \, +#define Z_IS_1455_EQ_1455(...) \, +#define Z_IS_1456_EQ_1456(...) \, +#define Z_IS_1457_EQ_1457(...) \, +#define Z_IS_1458_EQ_1458(...) \, +#define Z_IS_1459_EQ_1459(...) \, +#define Z_IS_1460_EQ_1460(...) \, +#define Z_IS_1461_EQ_1461(...) \, +#define Z_IS_1462_EQ_1462(...) \, +#define Z_IS_1463_EQ_1463(...) \, +#define Z_IS_1464_EQ_1464(...) \, +#define Z_IS_1465_EQ_1465(...) \, +#define Z_IS_1466_EQ_1466(...) \, +#define Z_IS_1467_EQ_1467(...) \, +#define Z_IS_1468_EQ_1468(...) \, +#define Z_IS_1469_EQ_1469(...) \, +#define Z_IS_1470_EQ_1470(...) \, +#define Z_IS_1471_EQ_1471(...) \, +#define Z_IS_1472_EQ_1472(...) \, +#define Z_IS_1473_EQ_1473(...) \, +#define Z_IS_1474_EQ_1474(...) \, +#define Z_IS_1475_EQ_1475(...) \, +#define Z_IS_1476_EQ_1476(...) \, +#define Z_IS_1477_EQ_1477(...) \, +#define Z_IS_1478_EQ_1478(...) \, +#define Z_IS_1479_EQ_1479(...) \, +#define Z_IS_1480_EQ_1480(...) \, +#define Z_IS_1481_EQ_1481(...) \, +#define Z_IS_1482_EQ_1482(...) \, +#define Z_IS_1483_EQ_1483(...) \, +#define Z_IS_1484_EQ_1484(...) \, +#define Z_IS_1485_EQ_1485(...) \, +#define Z_IS_1486_EQ_1486(...) \, +#define Z_IS_1487_EQ_1487(...) \, +#define Z_IS_1488_EQ_1488(...) \, +#define Z_IS_1489_EQ_1489(...) \, +#define Z_IS_1490_EQ_1490(...) \, +#define Z_IS_1491_EQ_1491(...) \, +#define Z_IS_1492_EQ_1492(...) \, +#define Z_IS_1493_EQ_1493(...) \, +#define Z_IS_1494_EQ_1494(...) \, +#define Z_IS_1495_EQ_1495(...) \, +#define Z_IS_1496_EQ_1496(...) \, +#define Z_IS_1497_EQ_1497(...) \, +#define Z_IS_1498_EQ_1498(...) \, +#define Z_IS_1499_EQ_1499(...) \, +#define Z_IS_1500_EQ_1500(...) \, +#define Z_IS_1501_EQ_1501(...) \, +#define Z_IS_1502_EQ_1502(...) \, +#define Z_IS_1503_EQ_1503(...) \, +#define Z_IS_1504_EQ_1504(...) \, +#define Z_IS_1505_EQ_1505(...) \, +#define Z_IS_1506_EQ_1506(...) \, +#define Z_IS_1507_EQ_1507(...) \, +#define Z_IS_1508_EQ_1508(...) \, +#define Z_IS_1509_EQ_1509(...) \, +#define Z_IS_1510_EQ_1510(...) \, +#define Z_IS_1511_EQ_1511(...) \, +#define Z_IS_1512_EQ_1512(...) \, +#define Z_IS_1513_EQ_1513(...) \, +#define Z_IS_1514_EQ_1514(...) \, +#define Z_IS_1515_EQ_1515(...) \, +#define Z_IS_1516_EQ_1516(...) \, +#define Z_IS_1517_EQ_1517(...) \, +#define Z_IS_1518_EQ_1518(...) \, +#define Z_IS_1519_EQ_1519(...) \, +#define Z_IS_1520_EQ_1520(...) \, +#define Z_IS_1521_EQ_1521(...) \, +#define Z_IS_1522_EQ_1522(...) \, +#define Z_IS_1523_EQ_1523(...) \, +#define Z_IS_1524_EQ_1524(...) \, +#define Z_IS_1525_EQ_1525(...) \, +#define Z_IS_1526_EQ_1526(...) \, +#define Z_IS_1527_EQ_1527(...) \, +#define Z_IS_1528_EQ_1528(...) \, +#define Z_IS_1529_EQ_1529(...) \, +#define Z_IS_1530_EQ_1530(...) \, +#define Z_IS_1531_EQ_1531(...) \, +#define Z_IS_1532_EQ_1532(...) \, +#define Z_IS_1533_EQ_1533(...) \, +#define Z_IS_1534_EQ_1534(...) \, +#define Z_IS_1535_EQ_1535(...) \, +#define Z_IS_1536_EQ_1536(...) \, +#define Z_IS_1537_EQ_1537(...) \, +#define Z_IS_1538_EQ_1538(...) \, +#define Z_IS_1539_EQ_1539(...) \, +#define Z_IS_1540_EQ_1540(...) \, +#define Z_IS_1541_EQ_1541(...) \, +#define Z_IS_1542_EQ_1542(...) \, +#define Z_IS_1543_EQ_1543(...) \, +#define Z_IS_1544_EQ_1544(...) \, +#define Z_IS_1545_EQ_1545(...) \, +#define Z_IS_1546_EQ_1546(...) \, +#define Z_IS_1547_EQ_1547(...) \, +#define Z_IS_1548_EQ_1548(...) \, +#define Z_IS_1549_EQ_1549(...) \, +#define Z_IS_1550_EQ_1550(...) \, +#define Z_IS_1551_EQ_1551(...) \, +#define Z_IS_1552_EQ_1552(...) \, +#define Z_IS_1553_EQ_1553(...) \, +#define Z_IS_1554_EQ_1554(...) \, +#define Z_IS_1555_EQ_1555(...) \, +#define Z_IS_1556_EQ_1556(...) \, +#define Z_IS_1557_EQ_1557(...) \, +#define Z_IS_1558_EQ_1558(...) \, +#define Z_IS_1559_EQ_1559(...) \, +#define Z_IS_1560_EQ_1560(...) \, +#define Z_IS_1561_EQ_1561(...) \, +#define Z_IS_1562_EQ_1562(...) \, +#define Z_IS_1563_EQ_1563(...) \, +#define Z_IS_1564_EQ_1564(...) \, +#define Z_IS_1565_EQ_1565(...) \, +#define Z_IS_1566_EQ_1566(...) \, +#define Z_IS_1567_EQ_1567(...) \, +#define Z_IS_1568_EQ_1568(...) \, +#define Z_IS_1569_EQ_1569(...) \, +#define Z_IS_1570_EQ_1570(...) \, +#define Z_IS_1571_EQ_1571(...) \, +#define Z_IS_1572_EQ_1572(...) \, +#define Z_IS_1573_EQ_1573(...) \, +#define Z_IS_1574_EQ_1574(...) \, +#define Z_IS_1575_EQ_1575(...) \, +#define Z_IS_1576_EQ_1576(...) \, +#define Z_IS_1577_EQ_1577(...) \, +#define Z_IS_1578_EQ_1578(...) \, +#define Z_IS_1579_EQ_1579(...) \, +#define Z_IS_1580_EQ_1580(...) \, +#define Z_IS_1581_EQ_1581(...) \, +#define Z_IS_1582_EQ_1582(...) \, +#define Z_IS_1583_EQ_1583(...) \, +#define Z_IS_1584_EQ_1584(...) \, +#define Z_IS_1585_EQ_1585(...) \, +#define Z_IS_1586_EQ_1586(...) \, +#define Z_IS_1587_EQ_1587(...) \, +#define Z_IS_1588_EQ_1588(...) \, +#define Z_IS_1589_EQ_1589(...) \, +#define Z_IS_1590_EQ_1590(...) \, +#define Z_IS_1591_EQ_1591(...) \, +#define Z_IS_1592_EQ_1592(...) \, +#define Z_IS_1593_EQ_1593(...) \, +#define Z_IS_1594_EQ_1594(...) \, +#define Z_IS_1595_EQ_1595(...) \, +#define Z_IS_1596_EQ_1596(...) \, +#define Z_IS_1597_EQ_1597(...) \, +#define Z_IS_1598_EQ_1598(...) \, +#define Z_IS_1599_EQ_1599(...) \, +#define Z_IS_1600_EQ_1600(...) \, +#define Z_IS_1601_EQ_1601(...) \, +#define Z_IS_1602_EQ_1602(...) \, +#define Z_IS_1603_EQ_1603(...) \, +#define Z_IS_1604_EQ_1604(...) \, +#define Z_IS_1605_EQ_1605(...) \, +#define Z_IS_1606_EQ_1606(...) \, +#define Z_IS_1607_EQ_1607(...) \, +#define Z_IS_1608_EQ_1608(...) \, +#define Z_IS_1609_EQ_1609(...) \, +#define Z_IS_1610_EQ_1610(...) \, +#define Z_IS_1611_EQ_1611(...) \, +#define Z_IS_1612_EQ_1612(...) \, +#define Z_IS_1613_EQ_1613(...) \, +#define Z_IS_1614_EQ_1614(...) \, +#define Z_IS_1615_EQ_1615(...) \, +#define Z_IS_1616_EQ_1616(...) \, +#define Z_IS_1617_EQ_1617(...) \, +#define Z_IS_1618_EQ_1618(...) \, +#define Z_IS_1619_EQ_1619(...) \, +#define Z_IS_1620_EQ_1620(...) \, +#define Z_IS_1621_EQ_1621(...) \, +#define Z_IS_1622_EQ_1622(...) \, +#define Z_IS_1623_EQ_1623(...) \, +#define Z_IS_1624_EQ_1624(...) \, +#define Z_IS_1625_EQ_1625(...) \, +#define Z_IS_1626_EQ_1626(...) \, +#define Z_IS_1627_EQ_1627(...) \, +#define Z_IS_1628_EQ_1628(...) \, +#define Z_IS_1629_EQ_1629(...) \, +#define Z_IS_1630_EQ_1630(...) \, +#define Z_IS_1631_EQ_1631(...) \, +#define Z_IS_1632_EQ_1632(...) \, +#define Z_IS_1633_EQ_1633(...) \, +#define Z_IS_1634_EQ_1634(...) \, +#define Z_IS_1635_EQ_1635(...) \, +#define Z_IS_1636_EQ_1636(...) \, +#define Z_IS_1637_EQ_1637(...) \, +#define Z_IS_1638_EQ_1638(...) \, +#define Z_IS_1639_EQ_1639(...) \, +#define Z_IS_1640_EQ_1640(...) \, +#define Z_IS_1641_EQ_1641(...) \, +#define Z_IS_1642_EQ_1642(...) \, +#define Z_IS_1643_EQ_1643(...) \, +#define Z_IS_1644_EQ_1644(...) \, +#define Z_IS_1645_EQ_1645(...) \, +#define Z_IS_1646_EQ_1646(...) \, +#define Z_IS_1647_EQ_1647(...) \, +#define Z_IS_1648_EQ_1648(...) \, +#define Z_IS_1649_EQ_1649(...) \, +#define Z_IS_1650_EQ_1650(...) \, +#define Z_IS_1651_EQ_1651(...) \, +#define Z_IS_1652_EQ_1652(...) \, +#define Z_IS_1653_EQ_1653(...) \, +#define Z_IS_1654_EQ_1654(...) \, +#define Z_IS_1655_EQ_1655(...) \, +#define Z_IS_1656_EQ_1656(...) \, +#define Z_IS_1657_EQ_1657(...) \, +#define Z_IS_1658_EQ_1658(...) \, +#define Z_IS_1659_EQ_1659(...) \, +#define Z_IS_1660_EQ_1660(...) \, +#define Z_IS_1661_EQ_1661(...) \, +#define Z_IS_1662_EQ_1662(...) \, +#define Z_IS_1663_EQ_1663(...) \, +#define Z_IS_1664_EQ_1664(...) \, +#define Z_IS_1665_EQ_1665(...) \, +#define Z_IS_1666_EQ_1666(...) \, +#define Z_IS_1667_EQ_1667(...) \, +#define Z_IS_1668_EQ_1668(...) \, +#define Z_IS_1669_EQ_1669(...) \, +#define Z_IS_1670_EQ_1670(...) \, +#define Z_IS_1671_EQ_1671(...) \, +#define Z_IS_1672_EQ_1672(...) \, +#define Z_IS_1673_EQ_1673(...) \, +#define Z_IS_1674_EQ_1674(...) \, +#define Z_IS_1675_EQ_1675(...) \, +#define Z_IS_1676_EQ_1676(...) \, +#define Z_IS_1677_EQ_1677(...) \, +#define Z_IS_1678_EQ_1678(...) \, +#define Z_IS_1679_EQ_1679(...) \, +#define Z_IS_1680_EQ_1680(...) \, +#define Z_IS_1681_EQ_1681(...) \, +#define Z_IS_1682_EQ_1682(...) \, +#define Z_IS_1683_EQ_1683(...) \, +#define Z_IS_1684_EQ_1684(...) \, +#define Z_IS_1685_EQ_1685(...) \, +#define Z_IS_1686_EQ_1686(...) \, +#define Z_IS_1687_EQ_1687(...) \, +#define Z_IS_1688_EQ_1688(...) \, +#define Z_IS_1689_EQ_1689(...) \, +#define Z_IS_1690_EQ_1690(...) \, +#define Z_IS_1691_EQ_1691(...) \, +#define Z_IS_1692_EQ_1692(...) \, +#define Z_IS_1693_EQ_1693(...) \, +#define Z_IS_1694_EQ_1694(...) \, +#define Z_IS_1695_EQ_1695(...) \, +#define Z_IS_1696_EQ_1696(...) \, +#define Z_IS_1697_EQ_1697(...) \, +#define Z_IS_1698_EQ_1698(...) \, +#define Z_IS_1699_EQ_1699(...) \, +#define Z_IS_1700_EQ_1700(...) \, +#define Z_IS_1701_EQ_1701(...) \, +#define Z_IS_1702_EQ_1702(...) \, +#define Z_IS_1703_EQ_1703(...) \, +#define Z_IS_1704_EQ_1704(...) \, +#define Z_IS_1705_EQ_1705(...) \, +#define Z_IS_1706_EQ_1706(...) \, +#define Z_IS_1707_EQ_1707(...) \, +#define Z_IS_1708_EQ_1708(...) \, +#define Z_IS_1709_EQ_1709(...) \, +#define Z_IS_1710_EQ_1710(...) \, +#define Z_IS_1711_EQ_1711(...) \, +#define Z_IS_1712_EQ_1712(...) \, +#define Z_IS_1713_EQ_1713(...) \, +#define Z_IS_1714_EQ_1714(...) \, +#define Z_IS_1715_EQ_1715(...) \, +#define Z_IS_1716_EQ_1716(...) \, +#define Z_IS_1717_EQ_1717(...) \, +#define Z_IS_1718_EQ_1718(...) \, +#define Z_IS_1719_EQ_1719(...) \, +#define Z_IS_1720_EQ_1720(...) \, +#define Z_IS_1721_EQ_1721(...) \, +#define Z_IS_1722_EQ_1722(...) \, +#define Z_IS_1723_EQ_1723(...) \, +#define Z_IS_1724_EQ_1724(...) \, +#define Z_IS_1725_EQ_1725(...) \, +#define Z_IS_1726_EQ_1726(...) \, +#define Z_IS_1727_EQ_1727(...) \, +#define Z_IS_1728_EQ_1728(...) \, +#define Z_IS_1729_EQ_1729(...) \, +#define Z_IS_1730_EQ_1730(...) \, +#define Z_IS_1731_EQ_1731(...) \, +#define Z_IS_1732_EQ_1732(...) \, +#define Z_IS_1733_EQ_1733(...) \, +#define Z_IS_1734_EQ_1734(...) \, +#define Z_IS_1735_EQ_1735(...) \, +#define Z_IS_1736_EQ_1736(...) \, +#define Z_IS_1737_EQ_1737(...) \, +#define Z_IS_1738_EQ_1738(...) \, +#define Z_IS_1739_EQ_1739(...) \, +#define Z_IS_1740_EQ_1740(...) \, +#define Z_IS_1741_EQ_1741(...) \, +#define Z_IS_1742_EQ_1742(...) \, +#define Z_IS_1743_EQ_1743(...) \, +#define Z_IS_1744_EQ_1744(...) \, +#define Z_IS_1745_EQ_1745(...) \, +#define Z_IS_1746_EQ_1746(...) \, +#define Z_IS_1747_EQ_1747(...) \, +#define Z_IS_1748_EQ_1748(...) \, +#define Z_IS_1749_EQ_1749(...) \, +#define Z_IS_1750_EQ_1750(...) \, +#define Z_IS_1751_EQ_1751(...) \, +#define Z_IS_1752_EQ_1752(...) \, +#define Z_IS_1753_EQ_1753(...) \, +#define Z_IS_1754_EQ_1754(...) \, +#define Z_IS_1755_EQ_1755(...) \, +#define Z_IS_1756_EQ_1756(...) \, +#define Z_IS_1757_EQ_1757(...) \, +#define Z_IS_1758_EQ_1758(...) \, +#define Z_IS_1759_EQ_1759(...) \, +#define Z_IS_1760_EQ_1760(...) \, +#define Z_IS_1761_EQ_1761(...) \, +#define Z_IS_1762_EQ_1762(...) \, +#define Z_IS_1763_EQ_1763(...) \, +#define Z_IS_1764_EQ_1764(...) \, +#define Z_IS_1765_EQ_1765(...) \, +#define Z_IS_1766_EQ_1766(...) \, +#define Z_IS_1767_EQ_1767(...) \, +#define Z_IS_1768_EQ_1768(...) \, +#define Z_IS_1769_EQ_1769(...) \, +#define Z_IS_1770_EQ_1770(...) \, +#define Z_IS_1771_EQ_1771(...) \, +#define Z_IS_1772_EQ_1772(...) \, +#define Z_IS_1773_EQ_1773(...) \, +#define Z_IS_1774_EQ_1774(...) \, +#define Z_IS_1775_EQ_1775(...) \, +#define Z_IS_1776_EQ_1776(...) \, +#define Z_IS_1777_EQ_1777(...) \, +#define Z_IS_1778_EQ_1778(...) \, +#define Z_IS_1779_EQ_1779(...) \, +#define Z_IS_1780_EQ_1780(...) \, +#define Z_IS_1781_EQ_1781(...) \, +#define Z_IS_1782_EQ_1782(...) \, +#define Z_IS_1783_EQ_1783(...) \, +#define Z_IS_1784_EQ_1784(...) \, +#define Z_IS_1785_EQ_1785(...) \, +#define Z_IS_1786_EQ_1786(...) \, +#define Z_IS_1787_EQ_1787(...) \, +#define Z_IS_1788_EQ_1788(...) \, +#define Z_IS_1789_EQ_1789(...) \, +#define Z_IS_1790_EQ_1790(...) \, +#define Z_IS_1791_EQ_1791(...) \, +#define Z_IS_1792_EQ_1792(...) \, +#define Z_IS_1793_EQ_1793(...) \, +#define Z_IS_1794_EQ_1794(...) \, +#define Z_IS_1795_EQ_1795(...) \, +#define Z_IS_1796_EQ_1796(...) \, +#define Z_IS_1797_EQ_1797(...) \, +#define Z_IS_1798_EQ_1798(...) \, +#define Z_IS_1799_EQ_1799(...) \, +#define Z_IS_1800_EQ_1800(...) \, +#define Z_IS_1801_EQ_1801(...) \, +#define Z_IS_1802_EQ_1802(...) \, +#define Z_IS_1803_EQ_1803(...) \, +#define Z_IS_1804_EQ_1804(...) \, +#define Z_IS_1805_EQ_1805(...) \, +#define Z_IS_1806_EQ_1806(...) \, +#define Z_IS_1807_EQ_1807(...) \, +#define Z_IS_1808_EQ_1808(...) \, +#define Z_IS_1809_EQ_1809(...) \, +#define Z_IS_1810_EQ_1810(...) \, +#define Z_IS_1811_EQ_1811(...) \, +#define Z_IS_1812_EQ_1812(...) \, +#define Z_IS_1813_EQ_1813(...) \, +#define Z_IS_1814_EQ_1814(...) \, +#define Z_IS_1815_EQ_1815(...) \, +#define Z_IS_1816_EQ_1816(...) \, +#define Z_IS_1817_EQ_1817(...) \, +#define Z_IS_1818_EQ_1818(...) \, +#define Z_IS_1819_EQ_1819(...) \, +#define Z_IS_1820_EQ_1820(...) \, +#define Z_IS_1821_EQ_1821(...) \, +#define Z_IS_1822_EQ_1822(...) \, +#define Z_IS_1823_EQ_1823(...) \, +#define Z_IS_1824_EQ_1824(...) \, +#define Z_IS_1825_EQ_1825(...) \, +#define Z_IS_1826_EQ_1826(...) \, +#define Z_IS_1827_EQ_1827(...) \, +#define Z_IS_1828_EQ_1828(...) \, +#define Z_IS_1829_EQ_1829(...) \, +#define Z_IS_1830_EQ_1830(...) \, +#define Z_IS_1831_EQ_1831(...) \, +#define Z_IS_1832_EQ_1832(...) \, +#define Z_IS_1833_EQ_1833(...) \, +#define Z_IS_1834_EQ_1834(...) \, +#define Z_IS_1835_EQ_1835(...) \, +#define Z_IS_1836_EQ_1836(...) \, +#define Z_IS_1837_EQ_1837(...) \, +#define Z_IS_1838_EQ_1838(...) \, +#define Z_IS_1839_EQ_1839(...) \, +#define Z_IS_1840_EQ_1840(...) \, +#define Z_IS_1841_EQ_1841(...) \, +#define Z_IS_1842_EQ_1842(...) \, +#define Z_IS_1843_EQ_1843(...) \, +#define Z_IS_1844_EQ_1844(...) \, +#define Z_IS_1845_EQ_1845(...) \, +#define Z_IS_1846_EQ_1846(...) \, +#define Z_IS_1847_EQ_1847(...) \, +#define Z_IS_1848_EQ_1848(...) \, +#define Z_IS_1849_EQ_1849(...) \, +#define Z_IS_1850_EQ_1850(...) \, +#define Z_IS_1851_EQ_1851(...) \, +#define Z_IS_1852_EQ_1852(...) \, +#define Z_IS_1853_EQ_1853(...) \, +#define Z_IS_1854_EQ_1854(...) \, +#define Z_IS_1855_EQ_1855(...) \, +#define Z_IS_1856_EQ_1856(...) \, +#define Z_IS_1857_EQ_1857(...) \, +#define Z_IS_1858_EQ_1858(...) \, +#define Z_IS_1859_EQ_1859(...) \, +#define Z_IS_1860_EQ_1860(...) \, +#define Z_IS_1861_EQ_1861(...) \, +#define Z_IS_1862_EQ_1862(...) \, +#define Z_IS_1863_EQ_1863(...) \, +#define Z_IS_1864_EQ_1864(...) \, +#define Z_IS_1865_EQ_1865(...) \, +#define Z_IS_1866_EQ_1866(...) \, +#define Z_IS_1867_EQ_1867(...) \, +#define Z_IS_1868_EQ_1868(...) \, +#define Z_IS_1869_EQ_1869(...) \, +#define Z_IS_1870_EQ_1870(...) \, +#define Z_IS_1871_EQ_1871(...) \, +#define Z_IS_1872_EQ_1872(...) \, +#define Z_IS_1873_EQ_1873(...) \, +#define Z_IS_1874_EQ_1874(...) \, +#define Z_IS_1875_EQ_1875(...) \, +#define Z_IS_1876_EQ_1876(...) \, +#define Z_IS_1877_EQ_1877(...) \, +#define Z_IS_1878_EQ_1878(...) \, +#define Z_IS_1879_EQ_1879(...) \, +#define Z_IS_1880_EQ_1880(...) \, +#define Z_IS_1881_EQ_1881(...) \, +#define Z_IS_1882_EQ_1882(...) \, +#define Z_IS_1883_EQ_1883(...) \, +#define Z_IS_1884_EQ_1884(...) \, +#define Z_IS_1885_EQ_1885(...) \, +#define Z_IS_1886_EQ_1886(...) \, +#define Z_IS_1887_EQ_1887(...) \, +#define Z_IS_1888_EQ_1888(...) \, +#define Z_IS_1889_EQ_1889(...) \, +#define Z_IS_1890_EQ_1890(...) \, +#define Z_IS_1891_EQ_1891(...) \, +#define Z_IS_1892_EQ_1892(...) \, +#define Z_IS_1893_EQ_1893(...) \, +#define Z_IS_1894_EQ_1894(...) \, +#define Z_IS_1895_EQ_1895(...) \, +#define Z_IS_1896_EQ_1896(...) \, +#define Z_IS_1897_EQ_1897(...) \, +#define Z_IS_1898_EQ_1898(...) \, +#define Z_IS_1899_EQ_1899(...) \, +#define Z_IS_1900_EQ_1900(...) \, +#define Z_IS_1901_EQ_1901(...) \, +#define Z_IS_1902_EQ_1902(...) \, +#define Z_IS_1903_EQ_1903(...) \, +#define Z_IS_1904_EQ_1904(...) \, +#define Z_IS_1905_EQ_1905(...) \, +#define Z_IS_1906_EQ_1906(...) \, +#define Z_IS_1907_EQ_1907(...) \, +#define Z_IS_1908_EQ_1908(...) \, +#define Z_IS_1909_EQ_1909(...) \, +#define Z_IS_1910_EQ_1910(...) \, +#define Z_IS_1911_EQ_1911(...) \, +#define Z_IS_1912_EQ_1912(...) \, +#define Z_IS_1913_EQ_1913(...) \, +#define Z_IS_1914_EQ_1914(...) \, +#define Z_IS_1915_EQ_1915(...) \, +#define Z_IS_1916_EQ_1916(...) \, +#define Z_IS_1917_EQ_1917(...) \, +#define Z_IS_1918_EQ_1918(...) \, +#define Z_IS_1919_EQ_1919(...) \, +#define Z_IS_1920_EQ_1920(...) \, +#define Z_IS_1921_EQ_1921(...) \, +#define Z_IS_1922_EQ_1922(...) \, +#define Z_IS_1923_EQ_1923(...) \, +#define Z_IS_1924_EQ_1924(...) \, +#define Z_IS_1925_EQ_1925(...) \, +#define Z_IS_1926_EQ_1926(...) \, +#define Z_IS_1927_EQ_1927(...) \, +#define Z_IS_1928_EQ_1928(...) \, +#define Z_IS_1929_EQ_1929(...) \, +#define Z_IS_1930_EQ_1930(...) \, +#define Z_IS_1931_EQ_1931(...) \, +#define Z_IS_1932_EQ_1932(...) \, +#define Z_IS_1933_EQ_1933(...) \, +#define Z_IS_1934_EQ_1934(...) \, +#define Z_IS_1935_EQ_1935(...) \, +#define Z_IS_1936_EQ_1936(...) \, +#define Z_IS_1937_EQ_1937(...) \, +#define Z_IS_1938_EQ_1938(...) \, +#define Z_IS_1939_EQ_1939(...) \, +#define Z_IS_1940_EQ_1940(...) \, +#define Z_IS_1941_EQ_1941(...) \, +#define Z_IS_1942_EQ_1942(...) \, +#define Z_IS_1943_EQ_1943(...) \, +#define Z_IS_1944_EQ_1944(...) \, +#define Z_IS_1945_EQ_1945(...) \, +#define Z_IS_1946_EQ_1946(...) \, +#define Z_IS_1947_EQ_1947(...) \, +#define Z_IS_1948_EQ_1948(...) \, +#define Z_IS_1949_EQ_1949(...) \, +#define Z_IS_1950_EQ_1950(...) \, +#define Z_IS_1951_EQ_1951(...) \, +#define Z_IS_1952_EQ_1952(...) \, +#define Z_IS_1953_EQ_1953(...) \, +#define Z_IS_1954_EQ_1954(...) \, +#define Z_IS_1955_EQ_1955(...) \, +#define Z_IS_1956_EQ_1956(...) \, +#define Z_IS_1957_EQ_1957(...) \, +#define Z_IS_1958_EQ_1958(...) \, +#define Z_IS_1959_EQ_1959(...) \, +#define Z_IS_1960_EQ_1960(...) \, +#define Z_IS_1961_EQ_1961(...) \, +#define Z_IS_1962_EQ_1962(...) \, +#define Z_IS_1963_EQ_1963(...) \, +#define Z_IS_1964_EQ_1964(...) \, +#define Z_IS_1965_EQ_1965(...) \, +#define Z_IS_1966_EQ_1966(...) \, +#define Z_IS_1967_EQ_1967(...) \, +#define Z_IS_1968_EQ_1968(...) \, +#define Z_IS_1969_EQ_1969(...) \, +#define Z_IS_1970_EQ_1970(...) \, +#define Z_IS_1971_EQ_1971(...) \, +#define Z_IS_1972_EQ_1972(...) \, +#define Z_IS_1973_EQ_1973(...) \, +#define Z_IS_1974_EQ_1974(...) \, +#define Z_IS_1975_EQ_1975(...) \, +#define Z_IS_1976_EQ_1976(...) \, +#define Z_IS_1977_EQ_1977(...) \, +#define Z_IS_1978_EQ_1978(...) \, +#define Z_IS_1979_EQ_1979(...) \, +#define Z_IS_1980_EQ_1980(...) \, +#define Z_IS_1981_EQ_1981(...) \, +#define Z_IS_1982_EQ_1982(...) \, +#define Z_IS_1983_EQ_1983(...) \, +#define Z_IS_1984_EQ_1984(...) \, +#define Z_IS_1985_EQ_1985(...) \, +#define Z_IS_1986_EQ_1986(...) \, +#define Z_IS_1987_EQ_1987(...) \, +#define Z_IS_1988_EQ_1988(...) \, +#define Z_IS_1989_EQ_1989(...) \, +#define Z_IS_1990_EQ_1990(...) \, +#define Z_IS_1991_EQ_1991(...) \, +#define Z_IS_1992_EQ_1992(...) \, +#define Z_IS_1993_EQ_1993(...) \, +#define Z_IS_1994_EQ_1994(...) \, +#define Z_IS_1995_EQ_1995(...) \, +#define Z_IS_1996_EQ_1996(...) \, +#define Z_IS_1997_EQ_1997(...) \, +#define Z_IS_1998_EQ_1998(...) \, +#define Z_IS_1999_EQ_1999(...) \, +#define Z_IS_2000_EQ_2000(...) \, +#define Z_IS_2001_EQ_2001(...) \, +#define Z_IS_2002_EQ_2002(...) \, +#define Z_IS_2003_EQ_2003(...) \, +#define Z_IS_2004_EQ_2004(...) \, +#define Z_IS_2005_EQ_2005(...) \, +#define Z_IS_2006_EQ_2006(...) \, +#define Z_IS_2007_EQ_2007(...) \, +#define Z_IS_2008_EQ_2008(...) \, +#define Z_IS_2009_EQ_2009(...) \, +#define Z_IS_2010_EQ_2010(...) \, +#define Z_IS_2011_EQ_2011(...) \, +#define Z_IS_2012_EQ_2012(...) \, +#define Z_IS_2013_EQ_2013(...) \, +#define Z_IS_2014_EQ_2014(...) \, +#define Z_IS_2015_EQ_2015(...) \, +#define Z_IS_2016_EQ_2016(...) \, +#define Z_IS_2017_EQ_2017(...) \, +#define Z_IS_2018_EQ_2018(...) \, +#define Z_IS_2019_EQ_2019(...) \, +#define Z_IS_2020_EQ_2020(...) \, +#define Z_IS_2021_EQ_2021(...) \, +#define Z_IS_2022_EQ_2022(...) \, +#define Z_IS_2023_EQ_2023(...) \, +#define Z_IS_2024_EQ_2024(...) \, +#define Z_IS_2025_EQ_2025(...) \, +#define Z_IS_2026_EQ_2026(...) \, +#define Z_IS_2027_EQ_2027(...) \, +#define Z_IS_2028_EQ_2028(...) \, +#define Z_IS_2029_EQ_2029(...) \, +#define Z_IS_2030_EQ_2030(...) \, +#define Z_IS_2031_EQ_2031(...) \, +#define Z_IS_2032_EQ_2032(...) \, +#define Z_IS_2033_EQ_2033(...) \, +#define Z_IS_2034_EQ_2034(...) \, +#define Z_IS_2035_EQ_2035(...) \, +#define Z_IS_2036_EQ_2036(...) \, +#define Z_IS_2037_EQ_2037(...) \, +#define Z_IS_2038_EQ_2038(...) \, +#define Z_IS_2039_EQ_2039(...) \, +#define Z_IS_2040_EQ_2040(...) \, +#define Z_IS_2041_EQ_2041(...) \, +#define Z_IS_2042_EQ_2042(...) \, +#define Z_IS_2043_EQ_2043(...) \, +#define Z_IS_2044_EQ_2044(...) \, +#define Z_IS_2045_EQ_2045(...) \, +#define Z_IS_2046_EQ_2046(...) \, +#define Z_IS_2047_EQ_2047(...) \, +#define Z_IS_2048_EQ_2048(...) \, +#define Z_IS_2049_EQ_2049(...) \, +#define Z_IS_2050_EQ_2050(...) \, +#define Z_IS_2051_EQ_2051(...) \, +#define Z_IS_2052_EQ_2052(...) \, +#define Z_IS_2053_EQ_2053(...) \, +#define Z_IS_2054_EQ_2054(...) \, +#define Z_IS_2055_EQ_2055(...) \, +#define Z_IS_2056_EQ_2056(...) \, +#define Z_IS_2057_EQ_2057(...) \, +#define Z_IS_2058_EQ_2058(...) \, +#define Z_IS_2059_EQ_2059(...) \, +#define Z_IS_2060_EQ_2060(...) \, +#define Z_IS_2061_EQ_2061(...) \, +#define Z_IS_2062_EQ_2062(...) \, +#define Z_IS_2063_EQ_2063(...) \, +#define Z_IS_2064_EQ_2064(...) \, +#define Z_IS_2065_EQ_2065(...) \, +#define Z_IS_2066_EQ_2066(...) \, +#define Z_IS_2067_EQ_2067(...) \, +#define Z_IS_2068_EQ_2068(...) \, +#define Z_IS_2069_EQ_2069(...) \, +#define Z_IS_2070_EQ_2070(...) \, +#define Z_IS_2071_EQ_2071(...) \, +#define Z_IS_2072_EQ_2072(...) \, +#define Z_IS_2073_EQ_2073(...) \, +#define Z_IS_2074_EQ_2074(...) \, +#define Z_IS_2075_EQ_2075(...) \, +#define Z_IS_2076_EQ_2076(...) \, +#define Z_IS_2077_EQ_2077(...) \, +#define Z_IS_2078_EQ_2078(...) \, +#define Z_IS_2079_EQ_2079(...) \, +#define Z_IS_2080_EQ_2080(...) \, +#define Z_IS_2081_EQ_2081(...) \, +#define Z_IS_2082_EQ_2082(...) \, +#define Z_IS_2083_EQ_2083(...) \, +#define Z_IS_2084_EQ_2084(...) \, +#define Z_IS_2085_EQ_2085(...) \, +#define Z_IS_2086_EQ_2086(...) \, +#define Z_IS_2087_EQ_2087(...) \, +#define Z_IS_2088_EQ_2088(...) \, +#define Z_IS_2089_EQ_2089(...) \, +#define Z_IS_2090_EQ_2090(...) \, +#define Z_IS_2091_EQ_2091(...) \, +#define Z_IS_2092_EQ_2092(...) \, +#define Z_IS_2093_EQ_2093(...) \, +#define Z_IS_2094_EQ_2094(...) \, +#define Z_IS_2095_EQ_2095(...) \, +#define Z_IS_2096_EQ_2096(...) \, +#define Z_IS_2097_EQ_2097(...) \, +#define Z_IS_2098_EQ_2098(...) \, +#define Z_IS_2099_EQ_2099(...) \, +#define Z_IS_2100_EQ_2100(...) \, +#define Z_IS_2101_EQ_2101(...) \, +#define Z_IS_2102_EQ_2102(...) \, +#define Z_IS_2103_EQ_2103(...) \, +#define Z_IS_2104_EQ_2104(...) \, +#define Z_IS_2105_EQ_2105(...) \, +#define Z_IS_2106_EQ_2106(...) \, +#define Z_IS_2107_EQ_2107(...) \, +#define Z_IS_2108_EQ_2108(...) \, +#define Z_IS_2109_EQ_2109(...) \, +#define Z_IS_2110_EQ_2110(...) \, +#define Z_IS_2111_EQ_2111(...) \, +#define Z_IS_2112_EQ_2112(...) \, +#define Z_IS_2113_EQ_2113(...) \, +#define Z_IS_2114_EQ_2114(...) \, +#define Z_IS_2115_EQ_2115(...) \, +#define Z_IS_2116_EQ_2116(...) \, +#define Z_IS_2117_EQ_2117(...) \, +#define Z_IS_2118_EQ_2118(...) \, +#define Z_IS_2119_EQ_2119(...) \, +#define Z_IS_2120_EQ_2120(...) \, +#define Z_IS_2121_EQ_2121(...) \, +#define Z_IS_2122_EQ_2122(...) \, +#define Z_IS_2123_EQ_2123(...) \, +#define Z_IS_2124_EQ_2124(...) \, +#define Z_IS_2125_EQ_2125(...) \, +#define Z_IS_2126_EQ_2126(...) \, +#define Z_IS_2127_EQ_2127(...) \, +#define Z_IS_2128_EQ_2128(...) \, +#define Z_IS_2129_EQ_2129(...) \, +#define Z_IS_2130_EQ_2130(...) \, +#define Z_IS_2131_EQ_2131(...) \, +#define Z_IS_2132_EQ_2132(...) \, +#define Z_IS_2133_EQ_2133(...) \, +#define Z_IS_2134_EQ_2134(...) \, +#define Z_IS_2135_EQ_2135(...) \, +#define Z_IS_2136_EQ_2136(...) \, +#define Z_IS_2137_EQ_2137(...) \, +#define Z_IS_2138_EQ_2138(...) \, +#define Z_IS_2139_EQ_2139(...) \, +#define Z_IS_2140_EQ_2140(...) \, +#define Z_IS_2141_EQ_2141(...) \, +#define Z_IS_2142_EQ_2142(...) \, +#define Z_IS_2143_EQ_2143(...) \, +#define Z_IS_2144_EQ_2144(...) \, +#define Z_IS_2145_EQ_2145(...) \, +#define Z_IS_2146_EQ_2146(...) \, +#define Z_IS_2147_EQ_2147(...) \, +#define Z_IS_2148_EQ_2148(...) \, +#define Z_IS_2149_EQ_2149(...) \, +#define Z_IS_2150_EQ_2150(...) \, +#define Z_IS_2151_EQ_2151(...) \, +#define Z_IS_2152_EQ_2152(...) \, +#define Z_IS_2153_EQ_2153(...) \, +#define Z_IS_2154_EQ_2154(...) \, +#define Z_IS_2155_EQ_2155(...) \, +#define Z_IS_2156_EQ_2156(...) \, +#define Z_IS_2157_EQ_2157(...) \, +#define Z_IS_2158_EQ_2158(...) \, +#define Z_IS_2159_EQ_2159(...) \, +#define Z_IS_2160_EQ_2160(...) \, +#define Z_IS_2161_EQ_2161(...) \, +#define Z_IS_2162_EQ_2162(...) \, +#define Z_IS_2163_EQ_2163(...) \, +#define Z_IS_2164_EQ_2164(...) \, +#define Z_IS_2165_EQ_2165(...) \, +#define Z_IS_2166_EQ_2166(...) \, +#define Z_IS_2167_EQ_2167(...) \, +#define Z_IS_2168_EQ_2168(...) \, +#define Z_IS_2169_EQ_2169(...) \, +#define Z_IS_2170_EQ_2170(...) \, +#define Z_IS_2171_EQ_2171(...) \, +#define Z_IS_2172_EQ_2172(...) \, +#define Z_IS_2173_EQ_2173(...) \, +#define Z_IS_2174_EQ_2174(...) \, +#define Z_IS_2175_EQ_2175(...) \, +#define Z_IS_2176_EQ_2176(...) \, +#define Z_IS_2177_EQ_2177(...) \, +#define Z_IS_2178_EQ_2178(...) \, +#define Z_IS_2179_EQ_2179(...) \, +#define Z_IS_2180_EQ_2180(...) \, +#define Z_IS_2181_EQ_2181(...) \, +#define Z_IS_2182_EQ_2182(...) \, +#define Z_IS_2183_EQ_2183(...) \, +#define Z_IS_2184_EQ_2184(...) \, +#define Z_IS_2185_EQ_2185(...) \, +#define Z_IS_2186_EQ_2186(...) \, +#define Z_IS_2187_EQ_2187(...) \, +#define Z_IS_2188_EQ_2188(...) \, +#define Z_IS_2189_EQ_2189(...) \, +#define Z_IS_2190_EQ_2190(...) \, +#define Z_IS_2191_EQ_2191(...) \, +#define Z_IS_2192_EQ_2192(...) \, +#define Z_IS_2193_EQ_2193(...) \, +#define Z_IS_2194_EQ_2194(...) \, +#define Z_IS_2195_EQ_2195(...) \, +#define Z_IS_2196_EQ_2196(...) \, +#define Z_IS_2197_EQ_2197(...) \, +#define Z_IS_2198_EQ_2198(...) \, +#define Z_IS_2199_EQ_2199(...) \, +#define Z_IS_2200_EQ_2200(...) \, +#define Z_IS_2201_EQ_2201(...) \, +#define Z_IS_2202_EQ_2202(...) \, +#define Z_IS_2203_EQ_2203(...) \, +#define Z_IS_2204_EQ_2204(...) \, +#define Z_IS_2205_EQ_2205(...) \, +#define Z_IS_2206_EQ_2206(...) \, +#define Z_IS_2207_EQ_2207(...) \, +#define Z_IS_2208_EQ_2208(...) \, +#define Z_IS_2209_EQ_2209(...) \, +#define Z_IS_2210_EQ_2210(...) \, +#define Z_IS_2211_EQ_2211(...) \, +#define Z_IS_2212_EQ_2212(...) \, +#define Z_IS_2213_EQ_2213(...) \, +#define Z_IS_2214_EQ_2214(...) \, +#define Z_IS_2215_EQ_2215(...) \, +#define Z_IS_2216_EQ_2216(...) \, +#define Z_IS_2217_EQ_2217(...) \, +#define Z_IS_2218_EQ_2218(...) \, +#define Z_IS_2219_EQ_2219(...) \, +#define Z_IS_2220_EQ_2220(...) \, +#define Z_IS_2221_EQ_2221(...) \, +#define Z_IS_2222_EQ_2222(...) \, +#define Z_IS_2223_EQ_2223(...) \, +#define Z_IS_2224_EQ_2224(...) \, +#define Z_IS_2225_EQ_2225(...) \, +#define Z_IS_2226_EQ_2226(...) \, +#define Z_IS_2227_EQ_2227(...) \, +#define Z_IS_2228_EQ_2228(...) \, +#define Z_IS_2229_EQ_2229(...) \, +#define Z_IS_2230_EQ_2230(...) \, +#define Z_IS_2231_EQ_2231(...) \, +#define Z_IS_2232_EQ_2232(...) \, +#define Z_IS_2233_EQ_2233(...) \, +#define Z_IS_2234_EQ_2234(...) \, +#define Z_IS_2235_EQ_2235(...) \, +#define Z_IS_2236_EQ_2236(...) \, +#define Z_IS_2237_EQ_2237(...) \, +#define Z_IS_2238_EQ_2238(...) \, +#define Z_IS_2239_EQ_2239(...) \, +#define Z_IS_2240_EQ_2240(...) \, +#define Z_IS_2241_EQ_2241(...) \, +#define Z_IS_2242_EQ_2242(...) \, +#define Z_IS_2243_EQ_2243(...) \, +#define Z_IS_2244_EQ_2244(...) \, +#define Z_IS_2245_EQ_2245(...) \, +#define Z_IS_2246_EQ_2246(...) \, +#define Z_IS_2247_EQ_2247(...) \, +#define Z_IS_2248_EQ_2248(...) \, +#define Z_IS_2249_EQ_2249(...) \, +#define Z_IS_2250_EQ_2250(...) \, +#define Z_IS_2251_EQ_2251(...) \, +#define Z_IS_2252_EQ_2252(...) \, +#define Z_IS_2253_EQ_2253(...) \, +#define Z_IS_2254_EQ_2254(...) \, +#define Z_IS_2255_EQ_2255(...) \, +#define Z_IS_2256_EQ_2256(...) \, +#define Z_IS_2257_EQ_2257(...) \, +#define Z_IS_2258_EQ_2258(...) \, +#define Z_IS_2259_EQ_2259(...) \, +#define Z_IS_2260_EQ_2260(...) \, +#define Z_IS_2261_EQ_2261(...) \, +#define Z_IS_2262_EQ_2262(...) \, +#define Z_IS_2263_EQ_2263(...) \, +#define Z_IS_2264_EQ_2264(...) \, +#define Z_IS_2265_EQ_2265(...) \, +#define Z_IS_2266_EQ_2266(...) \, +#define Z_IS_2267_EQ_2267(...) \, +#define Z_IS_2268_EQ_2268(...) \, +#define Z_IS_2269_EQ_2269(...) \, +#define Z_IS_2270_EQ_2270(...) \, +#define Z_IS_2271_EQ_2271(...) \, +#define Z_IS_2272_EQ_2272(...) \, +#define Z_IS_2273_EQ_2273(...) \, +#define Z_IS_2274_EQ_2274(...) \, +#define Z_IS_2275_EQ_2275(...) \, +#define Z_IS_2276_EQ_2276(...) \, +#define Z_IS_2277_EQ_2277(...) \, +#define Z_IS_2278_EQ_2278(...) \, +#define Z_IS_2279_EQ_2279(...) \, +#define Z_IS_2280_EQ_2280(...) \, +#define Z_IS_2281_EQ_2281(...) \, +#define Z_IS_2282_EQ_2282(...) \, +#define Z_IS_2283_EQ_2283(...) \, +#define Z_IS_2284_EQ_2284(...) \, +#define Z_IS_2285_EQ_2285(...) \, +#define Z_IS_2286_EQ_2286(...) \, +#define Z_IS_2287_EQ_2287(...) \, +#define Z_IS_2288_EQ_2288(...) \, +#define Z_IS_2289_EQ_2289(...) \, +#define Z_IS_2290_EQ_2290(...) \, +#define Z_IS_2291_EQ_2291(...) \, +#define Z_IS_2292_EQ_2292(...) \, +#define Z_IS_2293_EQ_2293(...) \, +#define Z_IS_2294_EQ_2294(...) \, +#define Z_IS_2295_EQ_2295(...) \, +#define Z_IS_2296_EQ_2296(...) \, +#define Z_IS_2297_EQ_2297(...) \, +#define Z_IS_2298_EQ_2298(...) \, +#define Z_IS_2299_EQ_2299(...) \, +#define Z_IS_2300_EQ_2300(...) \, +#define Z_IS_2301_EQ_2301(...) \, +#define Z_IS_2302_EQ_2302(...) \, +#define Z_IS_2303_EQ_2303(...) \, +#define Z_IS_2304_EQ_2304(...) \, +#define Z_IS_2305_EQ_2305(...) \, +#define Z_IS_2306_EQ_2306(...) \, +#define Z_IS_2307_EQ_2307(...) \, +#define Z_IS_2308_EQ_2308(...) \, +#define Z_IS_2309_EQ_2309(...) \, +#define Z_IS_2310_EQ_2310(...) \, +#define Z_IS_2311_EQ_2311(...) \, +#define Z_IS_2312_EQ_2312(...) \, +#define Z_IS_2313_EQ_2313(...) \, +#define Z_IS_2314_EQ_2314(...) \, +#define Z_IS_2315_EQ_2315(...) \, +#define Z_IS_2316_EQ_2316(...) \, +#define Z_IS_2317_EQ_2317(...) \, +#define Z_IS_2318_EQ_2318(...) \, +#define Z_IS_2319_EQ_2319(...) \, +#define Z_IS_2320_EQ_2320(...) \, +#define Z_IS_2321_EQ_2321(...) \, +#define Z_IS_2322_EQ_2322(...) \, +#define Z_IS_2323_EQ_2323(...) \, +#define Z_IS_2324_EQ_2324(...) \, +#define Z_IS_2325_EQ_2325(...) \, +#define Z_IS_2326_EQ_2326(...) \, +#define Z_IS_2327_EQ_2327(...) \, +#define Z_IS_2328_EQ_2328(...) \, +#define Z_IS_2329_EQ_2329(...) \, +#define Z_IS_2330_EQ_2330(...) \, +#define Z_IS_2331_EQ_2331(...) \, +#define Z_IS_2332_EQ_2332(...) \, +#define Z_IS_2333_EQ_2333(...) \, +#define Z_IS_2334_EQ_2334(...) \, +#define Z_IS_2335_EQ_2335(...) \, +#define Z_IS_2336_EQ_2336(...) \, +#define Z_IS_2337_EQ_2337(...) \, +#define Z_IS_2338_EQ_2338(...) \, +#define Z_IS_2339_EQ_2339(...) \, +#define Z_IS_2340_EQ_2340(...) \, +#define Z_IS_2341_EQ_2341(...) \, +#define Z_IS_2342_EQ_2342(...) \, +#define Z_IS_2343_EQ_2343(...) \, +#define Z_IS_2344_EQ_2344(...) \, +#define Z_IS_2345_EQ_2345(...) \, +#define Z_IS_2346_EQ_2346(...) \, +#define Z_IS_2347_EQ_2347(...) \, +#define Z_IS_2348_EQ_2348(...) \, +#define Z_IS_2349_EQ_2349(...) \, +#define Z_IS_2350_EQ_2350(...) \, +#define Z_IS_2351_EQ_2351(...) \, +#define Z_IS_2352_EQ_2352(...) \, +#define Z_IS_2353_EQ_2353(...) \, +#define Z_IS_2354_EQ_2354(...) \, +#define Z_IS_2355_EQ_2355(...) \, +#define Z_IS_2356_EQ_2356(...) \, +#define Z_IS_2357_EQ_2357(...) \, +#define Z_IS_2358_EQ_2358(...) \, +#define Z_IS_2359_EQ_2359(...) \, +#define Z_IS_2360_EQ_2360(...) \, +#define Z_IS_2361_EQ_2361(...) \, +#define Z_IS_2362_EQ_2362(...) \, +#define Z_IS_2363_EQ_2363(...) \, +#define Z_IS_2364_EQ_2364(...) \, +#define Z_IS_2365_EQ_2365(...) \, +#define Z_IS_2366_EQ_2366(...) \, +#define Z_IS_2367_EQ_2367(...) \, +#define Z_IS_2368_EQ_2368(...) \, +#define Z_IS_2369_EQ_2369(...) \, +#define Z_IS_2370_EQ_2370(...) \, +#define Z_IS_2371_EQ_2371(...) \, +#define Z_IS_2372_EQ_2372(...) \, +#define Z_IS_2373_EQ_2373(...) \, +#define Z_IS_2374_EQ_2374(...) \, +#define Z_IS_2375_EQ_2375(...) \, +#define Z_IS_2376_EQ_2376(...) \, +#define Z_IS_2377_EQ_2377(...) \, +#define Z_IS_2378_EQ_2378(...) \, +#define Z_IS_2379_EQ_2379(...) \, +#define Z_IS_2380_EQ_2380(...) \, +#define Z_IS_2381_EQ_2381(...) \, +#define Z_IS_2382_EQ_2382(...) \, +#define Z_IS_2383_EQ_2383(...) \, +#define Z_IS_2384_EQ_2384(...) \, +#define Z_IS_2385_EQ_2385(...) \, +#define Z_IS_2386_EQ_2386(...) \, +#define Z_IS_2387_EQ_2387(...) \, +#define Z_IS_2388_EQ_2388(...) \, +#define Z_IS_2389_EQ_2389(...) \, +#define Z_IS_2390_EQ_2390(...) \, +#define Z_IS_2391_EQ_2391(...) \, +#define Z_IS_2392_EQ_2392(...) \, +#define Z_IS_2393_EQ_2393(...) \, +#define Z_IS_2394_EQ_2394(...) \, +#define Z_IS_2395_EQ_2395(...) \, +#define Z_IS_2396_EQ_2396(...) \, +#define Z_IS_2397_EQ_2397(...) \, +#define Z_IS_2398_EQ_2398(...) \, +#define Z_IS_2399_EQ_2399(...) \, +#define Z_IS_2400_EQ_2400(...) \, +#define Z_IS_2401_EQ_2401(...) \, +#define Z_IS_2402_EQ_2402(...) \, +#define Z_IS_2403_EQ_2403(...) \, +#define Z_IS_2404_EQ_2404(...) \, +#define Z_IS_2405_EQ_2405(...) \, +#define Z_IS_2406_EQ_2406(...) \, +#define Z_IS_2407_EQ_2407(...) \, +#define Z_IS_2408_EQ_2408(...) \, +#define Z_IS_2409_EQ_2409(...) \, +#define Z_IS_2410_EQ_2410(...) \, +#define Z_IS_2411_EQ_2411(...) \, +#define Z_IS_2412_EQ_2412(...) \, +#define Z_IS_2413_EQ_2413(...) \, +#define Z_IS_2414_EQ_2414(...) \, +#define Z_IS_2415_EQ_2415(...) \, +#define Z_IS_2416_EQ_2416(...) \, +#define Z_IS_2417_EQ_2417(...) \, +#define Z_IS_2418_EQ_2418(...) \, +#define Z_IS_2419_EQ_2419(...) \, +#define Z_IS_2420_EQ_2420(...) \, +#define Z_IS_2421_EQ_2421(...) \, +#define Z_IS_2422_EQ_2422(...) \, +#define Z_IS_2423_EQ_2423(...) \, +#define Z_IS_2424_EQ_2424(...) \, +#define Z_IS_2425_EQ_2425(...) \, +#define Z_IS_2426_EQ_2426(...) \, +#define Z_IS_2427_EQ_2427(...) \, +#define Z_IS_2428_EQ_2428(...) \, +#define Z_IS_2429_EQ_2429(...) \, +#define Z_IS_2430_EQ_2430(...) \, +#define Z_IS_2431_EQ_2431(...) \, +#define Z_IS_2432_EQ_2432(...) \, +#define Z_IS_2433_EQ_2433(...) \, +#define Z_IS_2434_EQ_2434(...) \, +#define Z_IS_2435_EQ_2435(...) \, +#define Z_IS_2436_EQ_2436(...) \, +#define Z_IS_2437_EQ_2437(...) \, +#define Z_IS_2438_EQ_2438(...) \, +#define Z_IS_2439_EQ_2439(...) \, +#define Z_IS_2440_EQ_2440(...) \, +#define Z_IS_2441_EQ_2441(...) \, +#define Z_IS_2442_EQ_2442(...) \, +#define Z_IS_2443_EQ_2443(...) \, +#define Z_IS_2444_EQ_2444(...) \, +#define Z_IS_2445_EQ_2445(...) \, +#define Z_IS_2446_EQ_2446(...) \, +#define Z_IS_2447_EQ_2447(...) \, +#define Z_IS_2448_EQ_2448(...) \, +#define Z_IS_2449_EQ_2449(...) \, +#define Z_IS_2450_EQ_2450(...) \, +#define Z_IS_2451_EQ_2451(...) \, +#define Z_IS_2452_EQ_2452(...) \, +#define Z_IS_2453_EQ_2453(...) \, +#define Z_IS_2454_EQ_2454(...) \, +#define Z_IS_2455_EQ_2455(...) \, +#define Z_IS_2456_EQ_2456(...) \, +#define Z_IS_2457_EQ_2457(...) \, +#define Z_IS_2458_EQ_2458(...) \, +#define Z_IS_2459_EQ_2459(...) \, +#define Z_IS_2460_EQ_2460(...) \, +#define Z_IS_2461_EQ_2461(...) \, +#define Z_IS_2462_EQ_2462(...) \, +#define Z_IS_2463_EQ_2463(...) \, +#define Z_IS_2464_EQ_2464(...) \, +#define Z_IS_2465_EQ_2465(...) \, +#define Z_IS_2466_EQ_2466(...) \, +#define Z_IS_2467_EQ_2467(...) \, +#define Z_IS_2468_EQ_2468(...) \, +#define Z_IS_2469_EQ_2469(...) \, +#define Z_IS_2470_EQ_2470(...) \, +#define Z_IS_2471_EQ_2471(...) \, +#define Z_IS_2472_EQ_2472(...) \, +#define Z_IS_2473_EQ_2473(...) \, +#define Z_IS_2474_EQ_2474(...) \, +#define Z_IS_2475_EQ_2475(...) \, +#define Z_IS_2476_EQ_2476(...) \, +#define Z_IS_2477_EQ_2477(...) \, +#define Z_IS_2478_EQ_2478(...) \, +#define Z_IS_2479_EQ_2479(...) \, +#define Z_IS_2480_EQ_2480(...) \, +#define Z_IS_2481_EQ_2481(...) \, +#define Z_IS_2482_EQ_2482(...) \, +#define Z_IS_2483_EQ_2483(...) \, +#define Z_IS_2484_EQ_2484(...) \, +#define Z_IS_2485_EQ_2485(...) \, +#define Z_IS_2486_EQ_2486(...) \, +#define Z_IS_2487_EQ_2487(...) \, +#define Z_IS_2488_EQ_2488(...) \, +#define Z_IS_2489_EQ_2489(...) \, +#define Z_IS_2490_EQ_2490(...) \, +#define Z_IS_2491_EQ_2491(...) \, +#define Z_IS_2492_EQ_2492(...) \, +#define Z_IS_2493_EQ_2493(...) \, +#define Z_IS_2494_EQ_2494(...) \, +#define Z_IS_2495_EQ_2495(...) \, +#define Z_IS_2496_EQ_2496(...) \, +#define Z_IS_2497_EQ_2497(...) \, +#define Z_IS_2498_EQ_2498(...) \, +#define Z_IS_2499_EQ_2499(...) \, +#define Z_IS_2500_EQ_2500(...) \, +#define Z_IS_2501_EQ_2501(...) \, +#define Z_IS_2502_EQ_2502(...) \, +#define Z_IS_2503_EQ_2503(...) \, +#define Z_IS_2504_EQ_2504(...) \, +#define Z_IS_2505_EQ_2505(...) \, +#define Z_IS_2506_EQ_2506(...) \, +#define Z_IS_2507_EQ_2507(...) \, +#define Z_IS_2508_EQ_2508(...) \, +#define Z_IS_2509_EQ_2509(...) \, +#define Z_IS_2510_EQ_2510(...) \, +#define Z_IS_2511_EQ_2511(...) \, +#define Z_IS_2512_EQ_2512(...) \, +#define Z_IS_2513_EQ_2513(...) \, +#define Z_IS_2514_EQ_2514(...) \, +#define Z_IS_2515_EQ_2515(...) \, +#define Z_IS_2516_EQ_2516(...) \, +#define Z_IS_2517_EQ_2517(...) \, +#define Z_IS_2518_EQ_2518(...) \, +#define Z_IS_2519_EQ_2519(...) \, +#define Z_IS_2520_EQ_2520(...) \, +#define Z_IS_2521_EQ_2521(...) \, +#define Z_IS_2522_EQ_2522(...) \, +#define Z_IS_2523_EQ_2523(...) \, +#define Z_IS_2524_EQ_2524(...) \, +#define Z_IS_2525_EQ_2525(...) \, +#define Z_IS_2526_EQ_2526(...) \, +#define Z_IS_2527_EQ_2527(...) \, +#define Z_IS_2528_EQ_2528(...) \, +#define Z_IS_2529_EQ_2529(...) \, +#define Z_IS_2530_EQ_2530(...) \, +#define Z_IS_2531_EQ_2531(...) \, +#define Z_IS_2532_EQ_2532(...) \, +#define Z_IS_2533_EQ_2533(...) \, +#define Z_IS_2534_EQ_2534(...) \, +#define Z_IS_2535_EQ_2535(...) \, +#define Z_IS_2536_EQ_2536(...) \, +#define Z_IS_2537_EQ_2537(...) \, +#define Z_IS_2538_EQ_2538(...) \, +#define Z_IS_2539_EQ_2539(...) \, +#define Z_IS_2540_EQ_2540(...) \, +#define Z_IS_2541_EQ_2541(...) \, +#define Z_IS_2542_EQ_2542(...) \, +#define Z_IS_2543_EQ_2543(...) \, +#define Z_IS_2544_EQ_2544(...) \, +#define Z_IS_2545_EQ_2545(...) \, +#define Z_IS_2546_EQ_2546(...) \, +#define Z_IS_2547_EQ_2547(...) \, +#define Z_IS_2548_EQ_2548(...) \, +#define Z_IS_2549_EQ_2549(...) \, +#define Z_IS_2550_EQ_2550(...) \, +#define Z_IS_2551_EQ_2551(...) \, +#define Z_IS_2552_EQ_2552(...) \, +#define Z_IS_2553_EQ_2553(...) \, +#define Z_IS_2554_EQ_2554(...) \, +#define Z_IS_2555_EQ_2555(...) \, +#define Z_IS_2556_EQ_2556(...) \, +#define Z_IS_2557_EQ_2557(...) \, +#define Z_IS_2558_EQ_2558(...) \, +#define Z_IS_2559_EQ_2559(...) \, +#define Z_IS_2560_EQ_2560(...) \, +#define Z_IS_2561_EQ_2561(...) \, +#define Z_IS_2562_EQ_2562(...) \, +#define Z_IS_2563_EQ_2563(...) \, +#define Z_IS_2564_EQ_2564(...) \, +#define Z_IS_2565_EQ_2565(...) \, +#define Z_IS_2566_EQ_2566(...) \, +#define Z_IS_2567_EQ_2567(...) \, +#define Z_IS_2568_EQ_2568(...) \, +#define Z_IS_2569_EQ_2569(...) \, +#define Z_IS_2570_EQ_2570(...) \, +#define Z_IS_2571_EQ_2571(...) \, +#define Z_IS_2572_EQ_2572(...) \, +#define Z_IS_2573_EQ_2573(...) \, +#define Z_IS_2574_EQ_2574(...) \, +#define Z_IS_2575_EQ_2575(...) \, +#define Z_IS_2576_EQ_2576(...) \, +#define Z_IS_2577_EQ_2577(...) \, +#define Z_IS_2578_EQ_2578(...) \, +#define Z_IS_2579_EQ_2579(...) \, +#define Z_IS_2580_EQ_2580(...) \, +#define Z_IS_2581_EQ_2581(...) \, +#define Z_IS_2582_EQ_2582(...) \, +#define Z_IS_2583_EQ_2583(...) \, +#define Z_IS_2584_EQ_2584(...) \, +#define Z_IS_2585_EQ_2585(...) \, +#define Z_IS_2586_EQ_2586(...) \, +#define Z_IS_2587_EQ_2587(...) \, +#define Z_IS_2588_EQ_2588(...) \, +#define Z_IS_2589_EQ_2589(...) \, +#define Z_IS_2590_EQ_2590(...) \, +#define Z_IS_2591_EQ_2591(...) \, +#define Z_IS_2592_EQ_2592(...) \, +#define Z_IS_2593_EQ_2593(...) \, +#define Z_IS_2594_EQ_2594(...) \, +#define Z_IS_2595_EQ_2595(...) \, +#define Z_IS_2596_EQ_2596(...) \, +#define Z_IS_2597_EQ_2597(...) \, +#define Z_IS_2598_EQ_2598(...) \, +#define Z_IS_2599_EQ_2599(...) \, +#define Z_IS_2600_EQ_2600(...) \, +#define Z_IS_2601_EQ_2601(...) \, +#define Z_IS_2602_EQ_2602(...) \, +#define Z_IS_2603_EQ_2603(...) \, +#define Z_IS_2604_EQ_2604(...) \, +#define Z_IS_2605_EQ_2605(...) \, +#define Z_IS_2606_EQ_2606(...) \, +#define Z_IS_2607_EQ_2607(...) \, +#define Z_IS_2608_EQ_2608(...) \, +#define Z_IS_2609_EQ_2609(...) \, +#define Z_IS_2610_EQ_2610(...) \, +#define Z_IS_2611_EQ_2611(...) \, +#define Z_IS_2612_EQ_2612(...) \, +#define Z_IS_2613_EQ_2613(...) \, +#define Z_IS_2614_EQ_2614(...) \, +#define Z_IS_2615_EQ_2615(...) \, +#define Z_IS_2616_EQ_2616(...) \, +#define Z_IS_2617_EQ_2617(...) \, +#define Z_IS_2618_EQ_2618(...) \, +#define Z_IS_2619_EQ_2619(...) \, +#define Z_IS_2620_EQ_2620(...) \, +#define Z_IS_2621_EQ_2621(...) \, +#define Z_IS_2622_EQ_2622(...) \, +#define Z_IS_2623_EQ_2623(...) \, +#define Z_IS_2624_EQ_2624(...) \, +#define Z_IS_2625_EQ_2625(...) \, +#define Z_IS_2626_EQ_2626(...) \, +#define Z_IS_2627_EQ_2627(...) \, +#define Z_IS_2628_EQ_2628(...) \, +#define Z_IS_2629_EQ_2629(...) \, +#define Z_IS_2630_EQ_2630(...) \, +#define Z_IS_2631_EQ_2631(...) \, +#define Z_IS_2632_EQ_2632(...) \, +#define Z_IS_2633_EQ_2633(...) \, +#define Z_IS_2634_EQ_2634(...) \, +#define Z_IS_2635_EQ_2635(...) \, +#define Z_IS_2636_EQ_2636(...) \, +#define Z_IS_2637_EQ_2637(...) \, +#define Z_IS_2638_EQ_2638(...) \, +#define Z_IS_2639_EQ_2639(...) \, +#define Z_IS_2640_EQ_2640(...) \, +#define Z_IS_2641_EQ_2641(...) \, +#define Z_IS_2642_EQ_2642(...) \, +#define Z_IS_2643_EQ_2643(...) \, +#define Z_IS_2644_EQ_2644(...) \, +#define Z_IS_2645_EQ_2645(...) \, +#define Z_IS_2646_EQ_2646(...) \, +#define Z_IS_2647_EQ_2647(...) \, +#define Z_IS_2648_EQ_2648(...) \, +#define Z_IS_2649_EQ_2649(...) \, +#define Z_IS_2650_EQ_2650(...) \, +#define Z_IS_2651_EQ_2651(...) \, +#define Z_IS_2652_EQ_2652(...) \, +#define Z_IS_2653_EQ_2653(...) \, +#define Z_IS_2654_EQ_2654(...) \, +#define Z_IS_2655_EQ_2655(...) \, +#define Z_IS_2656_EQ_2656(...) \, +#define Z_IS_2657_EQ_2657(...) \, +#define Z_IS_2658_EQ_2658(...) \, +#define Z_IS_2659_EQ_2659(...) \, +#define Z_IS_2660_EQ_2660(...) \, +#define Z_IS_2661_EQ_2661(...) \, +#define Z_IS_2662_EQ_2662(...) \, +#define Z_IS_2663_EQ_2663(...) \, +#define Z_IS_2664_EQ_2664(...) \, +#define Z_IS_2665_EQ_2665(...) \, +#define Z_IS_2666_EQ_2666(...) \, +#define Z_IS_2667_EQ_2667(...) \, +#define Z_IS_2668_EQ_2668(...) \, +#define Z_IS_2669_EQ_2669(...) \, +#define Z_IS_2670_EQ_2670(...) \, +#define Z_IS_2671_EQ_2671(...) \, +#define Z_IS_2672_EQ_2672(...) \, +#define Z_IS_2673_EQ_2673(...) \, +#define Z_IS_2674_EQ_2674(...) \, +#define Z_IS_2675_EQ_2675(...) \, +#define Z_IS_2676_EQ_2676(...) \, +#define Z_IS_2677_EQ_2677(...) \, +#define Z_IS_2678_EQ_2678(...) \, +#define Z_IS_2679_EQ_2679(...) \, +#define Z_IS_2680_EQ_2680(...) \, +#define Z_IS_2681_EQ_2681(...) \, +#define Z_IS_2682_EQ_2682(...) \, +#define Z_IS_2683_EQ_2683(...) \, +#define Z_IS_2684_EQ_2684(...) \, +#define Z_IS_2685_EQ_2685(...) \, +#define Z_IS_2686_EQ_2686(...) \, +#define Z_IS_2687_EQ_2687(...) \, +#define Z_IS_2688_EQ_2688(...) \, +#define Z_IS_2689_EQ_2689(...) \, +#define Z_IS_2690_EQ_2690(...) \, +#define Z_IS_2691_EQ_2691(...) \, +#define Z_IS_2692_EQ_2692(...) \, +#define Z_IS_2693_EQ_2693(...) \, +#define Z_IS_2694_EQ_2694(...) \, +#define Z_IS_2695_EQ_2695(...) \, +#define Z_IS_2696_EQ_2696(...) \, +#define Z_IS_2697_EQ_2697(...) \, +#define Z_IS_2698_EQ_2698(...) \, +#define Z_IS_2699_EQ_2699(...) \, +#define Z_IS_2700_EQ_2700(...) \, +#define Z_IS_2701_EQ_2701(...) \, +#define Z_IS_2702_EQ_2702(...) \, +#define Z_IS_2703_EQ_2703(...) \, +#define Z_IS_2704_EQ_2704(...) \, +#define Z_IS_2705_EQ_2705(...) \, +#define Z_IS_2706_EQ_2706(...) \, +#define Z_IS_2707_EQ_2707(...) \, +#define Z_IS_2708_EQ_2708(...) \, +#define Z_IS_2709_EQ_2709(...) \, +#define Z_IS_2710_EQ_2710(...) \, +#define Z_IS_2711_EQ_2711(...) \, +#define Z_IS_2712_EQ_2712(...) \, +#define Z_IS_2713_EQ_2713(...) \, +#define Z_IS_2714_EQ_2714(...) \, +#define Z_IS_2715_EQ_2715(...) \, +#define Z_IS_2716_EQ_2716(...) \, +#define Z_IS_2717_EQ_2717(...) \, +#define Z_IS_2718_EQ_2718(...) \, +#define Z_IS_2719_EQ_2719(...) \, +#define Z_IS_2720_EQ_2720(...) \, +#define Z_IS_2721_EQ_2721(...) \, +#define Z_IS_2722_EQ_2722(...) \, +#define Z_IS_2723_EQ_2723(...) \, +#define Z_IS_2724_EQ_2724(...) \, +#define Z_IS_2725_EQ_2725(...) \, +#define Z_IS_2726_EQ_2726(...) \, +#define Z_IS_2727_EQ_2727(...) \, +#define Z_IS_2728_EQ_2728(...) \, +#define Z_IS_2729_EQ_2729(...) \, +#define Z_IS_2730_EQ_2730(...) \, +#define Z_IS_2731_EQ_2731(...) \, +#define Z_IS_2732_EQ_2732(...) \, +#define Z_IS_2733_EQ_2733(...) \, +#define Z_IS_2734_EQ_2734(...) \, +#define Z_IS_2735_EQ_2735(...) \, +#define Z_IS_2736_EQ_2736(...) \, +#define Z_IS_2737_EQ_2737(...) \, +#define Z_IS_2738_EQ_2738(...) \, +#define Z_IS_2739_EQ_2739(...) \, +#define Z_IS_2740_EQ_2740(...) \, +#define Z_IS_2741_EQ_2741(...) \, +#define Z_IS_2742_EQ_2742(...) \, +#define Z_IS_2743_EQ_2743(...) \, +#define Z_IS_2744_EQ_2744(...) \, +#define Z_IS_2745_EQ_2745(...) \, +#define Z_IS_2746_EQ_2746(...) \, +#define Z_IS_2747_EQ_2747(...) \, +#define Z_IS_2748_EQ_2748(...) \, +#define Z_IS_2749_EQ_2749(...) \, +#define Z_IS_2750_EQ_2750(...) \, +#define Z_IS_2751_EQ_2751(...) \, +#define Z_IS_2752_EQ_2752(...) \, +#define Z_IS_2753_EQ_2753(...) \, +#define Z_IS_2754_EQ_2754(...) \, +#define Z_IS_2755_EQ_2755(...) \, +#define Z_IS_2756_EQ_2756(...) \, +#define Z_IS_2757_EQ_2757(...) \, +#define Z_IS_2758_EQ_2758(...) \, +#define Z_IS_2759_EQ_2759(...) \, +#define Z_IS_2760_EQ_2760(...) \, +#define Z_IS_2761_EQ_2761(...) \, +#define Z_IS_2762_EQ_2762(...) \, +#define Z_IS_2763_EQ_2763(...) \, +#define Z_IS_2764_EQ_2764(...) \, +#define Z_IS_2765_EQ_2765(...) \, +#define Z_IS_2766_EQ_2766(...) \, +#define Z_IS_2767_EQ_2767(...) \, +#define Z_IS_2768_EQ_2768(...) \, +#define Z_IS_2769_EQ_2769(...) \, +#define Z_IS_2770_EQ_2770(...) \, +#define Z_IS_2771_EQ_2771(...) \, +#define Z_IS_2772_EQ_2772(...) \, +#define Z_IS_2773_EQ_2773(...) \, +#define Z_IS_2774_EQ_2774(...) \, +#define Z_IS_2775_EQ_2775(...) \, +#define Z_IS_2776_EQ_2776(...) \, +#define Z_IS_2777_EQ_2777(...) \, +#define Z_IS_2778_EQ_2778(...) \, +#define Z_IS_2779_EQ_2779(...) \, +#define Z_IS_2780_EQ_2780(...) \, +#define Z_IS_2781_EQ_2781(...) \, +#define Z_IS_2782_EQ_2782(...) \, +#define Z_IS_2783_EQ_2783(...) \, +#define Z_IS_2784_EQ_2784(...) \, +#define Z_IS_2785_EQ_2785(...) \, +#define Z_IS_2786_EQ_2786(...) \, +#define Z_IS_2787_EQ_2787(...) \, +#define Z_IS_2788_EQ_2788(...) \, +#define Z_IS_2789_EQ_2789(...) \, +#define Z_IS_2790_EQ_2790(...) \, +#define Z_IS_2791_EQ_2791(...) \, +#define Z_IS_2792_EQ_2792(...) \, +#define Z_IS_2793_EQ_2793(...) \, +#define Z_IS_2794_EQ_2794(...) \, +#define Z_IS_2795_EQ_2795(...) \, +#define Z_IS_2796_EQ_2796(...) \, +#define Z_IS_2797_EQ_2797(...) \, +#define Z_IS_2798_EQ_2798(...) \, +#define Z_IS_2799_EQ_2799(...) \, +#define Z_IS_2800_EQ_2800(...) \, +#define Z_IS_2801_EQ_2801(...) \, +#define Z_IS_2802_EQ_2802(...) \, +#define Z_IS_2803_EQ_2803(...) \, +#define Z_IS_2804_EQ_2804(...) \, +#define Z_IS_2805_EQ_2805(...) \, +#define Z_IS_2806_EQ_2806(...) \, +#define Z_IS_2807_EQ_2807(...) \, +#define Z_IS_2808_EQ_2808(...) \, +#define Z_IS_2809_EQ_2809(...) \, +#define Z_IS_2810_EQ_2810(...) \, +#define Z_IS_2811_EQ_2811(...) \, +#define Z_IS_2812_EQ_2812(...) \, +#define Z_IS_2813_EQ_2813(...) \, +#define Z_IS_2814_EQ_2814(...) \, +#define Z_IS_2815_EQ_2815(...) \, +#define Z_IS_2816_EQ_2816(...) \, +#define Z_IS_2817_EQ_2817(...) \, +#define Z_IS_2818_EQ_2818(...) \, +#define Z_IS_2819_EQ_2819(...) \, +#define Z_IS_2820_EQ_2820(...) \, +#define Z_IS_2821_EQ_2821(...) \, +#define Z_IS_2822_EQ_2822(...) \, +#define Z_IS_2823_EQ_2823(...) \, +#define Z_IS_2824_EQ_2824(...) \, +#define Z_IS_2825_EQ_2825(...) \, +#define Z_IS_2826_EQ_2826(...) \, +#define Z_IS_2827_EQ_2827(...) \, +#define Z_IS_2828_EQ_2828(...) \, +#define Z_IS_2829_EQ_2829(...) \, +#define Z_IS_2830_EQ_2830(...) \, +#define Z_IS_2831_EQ_2831(...) \, +#define Z_IS_2832_EQ_2832(...) \, +#define Z_IS_2833_EQ_2833(...) \, +#define Z_IS_2834_EQ_2834(...) \, +#define Z_IS_2835_EQ_2835(...) \, +#define Z_IS_2836_EQ_2836(...) \, +#define Z_IS_2837_EQ_2837(...) \, +#define Z_IS_2838_EQ_2838(...) \, +#define Z_IS_2839_EQ_2839(...) \, +#define Z_IS_2840_EQ_2840(...) \, +#define Z_IS_2841_EQ_2841(...) \, +#define Z_IS_2842_EQ_2842(...) \, +#define Z_IS_2843_EQ_2843(...) \, +#define Z_IS_2844_EQ_2844(...) \, +#define Z_IS_2845_EQ_2845(...) \, +#define Z_IS_2846_EQ_2846(...) \, +#define Z_IS_2847_EQ_2847(...) \, +#define Z_IS_2848_EQ_2848(...) \, +#define Z_IS_2849_EQ_2849(...) \, +#define Z_IS_2850_EQ_2850(...) \, +#define Z_IS_2851_EQ_2851(...) \, +#define Z_IS_2852_EQ_2852(...) \, +#define Z_IS_2853_EQ_2853(...) \, +#define Z_IS_2854_EQ_2854(...) \, +#define Z_IS_2855_EQ_2855(...) \, +#define Z_IS_2856_EQ_2856(...) \, +#define Z_IS_2857_EQ_2857(...) \, +#define Z_IS_2858_EQ_2858(...) \, +#define Z_IS_2859_EQ_2859(...) \, +#define Z_IS_2860_EQ_2860(...) \, +#define Z_IS_2861_EQ_2861(...) \, +#define Z_IS_2862_EQ_2862(...) \, +#define Z_IS_2863_EQ_2863(...) \, +#define Z_IS_2864_EQ_2864(...) \, +#define Z_IS_2865_EQ_2865(...) \, +#define Z_IS_2866_EQ_2866(...) \, +#define Z_IS_2867_EQ_2867(...) \, +#define Z_IS_2868_EQ_2868(...) \, +#define Z_IS_2869_EQ_2869(...) \, +#define Z_IS_2870_EQ_2870(...) \, +#define Z_IS_2871_EQ_2871(...) \, +#define Z_IS_2872_EQ_2872(...) \, +#define Z_IS_2873_EQ_2873(...) \, +#define Z_IS_2874_EQ_2874(...) \, +#define Z_IS_2875_EQ_2875(...) \, +#define Z_IS_2876_EQ_2876(...) \, +#define Z_IS_2877_EQ_2877(...) \, +#define Z_IS_2878_EQ_2878(...) \, +#define Z_IS_2879_EQ_2879(...) \, +#define Z_IS_2880_EQ_2880(...) \, +#define Z_IS_2881_EQ_2881(...) \, +#define Z_IS_2882_EQ_2882(...) \, +#define Z_IS_2883_EQ_2883(...) \, +#define Z_IS_2884_EQ_2884(...) \, +#define Z_IS_2885_EQ_2885(...) \, +#define Z_IS_2886_EQ_2886(...) \, +#define Z_IS_2887_EQ_2887(...) \, +#define Z_IS_2888_EQ_2888(...) \, +#define Z_IS_2889_EQ_2889(...) \, +#define Z_IS_2890_EQ_2890(...) \, +#define Z_IS_2891_EQ_2891(...) \, +#define Z_IS_2892_EQ_2892(...) \, +#define Z_IS_2893_EQ_2893(...) \, +#define Z_IS_2894_EQ_2894(...) \, +#define Z_IS_2895_EQ_2895(...) \, +#define Z_IS_2896_EQ_2896(...) \, +#define Z_IS_2897_EQ_2897(...) \, +#define Z_IS_2898_EQ_2898(...) \, +#define Z_IS_2899_EQ_2899(...) \, +#define Z_IS_2900_EQ_2900(...) \, +#define Z_IS_2901_EQ_2901(...) \, +#define Z_IS_2902_EQ_2902(...) \, +#define Z_IS_2903_EQ_2903(...) \, +#define Z_IS_2904_EQ_2904(...) \, +#define Z_IS_2905_EQ_2905(...) \, +#define Z_IS_2906_EQ_2906(...) \, +#define Z_IS_2907_EQ_2907(...) \, +#define Z_IS_2908_EQ_2908(...) \, +#define Z_IS_2909_EQ_2909(...) \, +#define Z_IS_2910_EQ_2910(...) \, +#define Z_IS_2911_EQ_2911(...) \, +#define Z_IS_2912_EQ_2912(...) \, +#define Z_IS_2913_EQ_2913(...) \, +#define Z_IS_2914_EQ_2914(...) \, +#define Z_IS_2915_EQ_2915(...) \, +#define Z_IS_2916_EQ_2916(...) \, +#define Z_IS_2917_EQ_2917(...) \, +#define Z_IS_2918_EQ_2918(...) \, +#define Z_IS_2919_EQ_2919(...) \, +#define Z_IS_2920_EQ_2920(...) \, +#define Z_IS_2921_EQ_2921(...) \, +#define Z_IS_2922_EQ_2922(...) \, +#define Z_IS_2923_EQ_2923(...) \, +#define Z_IS_2924_EQ_2924(...) \, +#define Z_IS_2925_EQ_2925(...) \, +#define Z_IS_2926_EQ_2926(...) \, +#define Z_IS_2927_EQ_2927(...) \, +#define Z_IS_2928_EQ_2928(...) \, +#define Z_IS_2929_EQ_2929(...) \, +#define Z_IS_2930_EQ_2930(...) \, +#define Z_IS_2931_EQ_2931(...) \, +#define Z_IS_2932_EQ_2932(...) \, +#define Z_IS_2933_EQ_2933(...) \, +#define Z_IS_2934_EQ_2934(...) \, +#define Z_IS_2935_EQ_2935(...) \, +#define Z_IS_2936_EQ_2936(...) \, +#define Z_IS_2937_EQ_2937(...) \, +#define Z_IS_2938_EQ_2938(...) \, +#define Z_IS_2939_EQ_2939(...) \, +#define Z_IS_2940_EQ_2940(...) \, +#define Z_IS_2941_EQ_2941(...) \, +#define Z_IS_2942_EQ_2942(...) \, +#define Z_IS_2943_EQ_2943(...) \, +#define Z_IS_2944_EQ_2944(...) \, +#define Z_IS_2945_EQ_2945(...) \, +#define Z_IS_2946_EQ_2946(...) \, +#define Z_IS_2947_EQ_2947(...) \, +#define Z_IS_2948_EQ_2948(...) \, +#define Z_IS_2949_EQ_2949(...) \, +#define Z_IS_2950_EQ_2950(...) \, +#define Z_IS_2951_EQ_2951(...) \, +#define Z_IS_2952_EQ_2952(...) \, +#define Z_IS_2953_EQ_2953(...) \, +#define Z_IS_2954_EQ_2954(...) \, +#define Z_IS_2955_EQ_2955(...) \, +#define Z_IS_2956_EQ_2956(...) \, +#define Z_IS_2957_EQ_2957(...) \, +#define Z_IS_2958_EQ_2958(...) \, +#define Z_IS_2959_EQ_2959(...) \, +#define Z_IS_2960_EQ_2960(...) \, +#define Z_IS_2961_EQ_2961(...) \, +#define Z_IS_2962_EQ_2962(...) \, +#define Z_IS_2963_EQ_2963(...) \, +#define Z_IS_2964_EQ_2964(...) \, +#define Z_IS_2965_EQ_2965(...) \, +#define Z_IS_2966_EQ_2966(...) \, +#define Z_IS_2967_EQ_2967(...) \, +#define Z_IS_2968_EQ_2968(...) \, +#define Z_IS_2969_EQ_2969(...) \, +#define Z_IS_2970_EQ_2970(...) \, +#define Z_IS_2971_EQ_2971(...) \, +#define Z_IS_2972_EQ_2972(...) \, +#define Z_IS_2973_EQ_2973(...) \, +#define Z_IS_2974_EQ_2974(...) \, +#define Z_IS_2975_EQ_2975(...) \, +#define Z_IS_2976_EQ_2976(...) \, +#define Z_IS_2977_EQ_2977(...) \, +#define Z_IS_2978_EQ_2978(...) \, +#define Z_IS_2979_EQ_2979(...) \, +#define Z_IS_2980_EQ_2980(...) \, +#define Z_IS_2981_EQ_2981(...) \, +#define Z_IS_2982_EQ_2982(...) \, +#define Z_IS_2983_EQ_2983(...) \, +#define Z_IS_2984_EQ_2984(...) \, +#define Z_IS_2985_EQ_2985(...) \, +#define Z_IS_2986_EQ_2986(...) \, +#define Z_IS_2987_EQ_2987(...) \, +#define Z_IS_2988_EQ_2988(...) \, +#define Z_IS_2989_EQ_2989(...) \, +#define Z_IS_2990_EQ_2990(...) \, +#define Z_IS_2991_EQ_2991(...) \, +#define Z_IS_2992_EQ_2992(...) \, +#define Z_IS_2993_EQ_2993(...) \, +#define Z_IS_2994_EQ_2994(...) \, +#define Z_IS_2995_EQ_2995(...) \, +#define Z_IS_2996_EQ_2996(...) \, +#define Z_IS_2997_EQ_2997(...) \, +#define Z_IS_2998_EQ_2998(...) \, +#define Z_IS_2999_EQ_2999(...) \, +#define Z_IS_3000_EQ_3000(...) \, +#define Z_IS_3001_EQ_3001(...) \, +#define Z_IS_3002_EQ_3002(...) \, +#define Z_IS_3003_EQ_3003(...) \, +#define Z_IS_3004_EQ_3004(...) \, +#define Z_IS_3005_EQ_3005(...) \, +#define Z_IS_3006_EQ_3006(...) \, +#define Z_IS_3007_EQ_3007(...) \, +#define Z_IS_3008_EQ_3008(...) \, +#define Z_IS_3009_EQ_3009(...) \, +#define Z_IS_3010_EQ_3010(...) \, +#define Z_IS_3011_EQ_3011(...) \, +#define Z_IS_3012_EQ_3012(...) \, +#define Z_IS_3013_EQ_3013(...) \, +#define Z_IS_3014_EQ_3014(...) \, +#define Z_IS_3015_EQ_3015(...) \, +#define Z_IS_3016_EQ_3016(...) \, +#define Z_IS_3017_EQ_3017(...) \, +#define Z_IS_3018_EQ_3018(...) \, +#define Z_IS_3019_EQ_3019(...) \, +#define Z_IS_3020_EQ_3020(...) \, +#define Z_IS_3021_EQ_3021(...) \, +#define Z_IS_3022_EQ_3022(...) \, +#define Z_IS_3023_EQ_3023(...) \, +#define Z_IS_3024_EQ_3024(...) \, +#define Z_IS_3025_EQ_3025(...) \, +#define Z_IS_3026_EQ_3026(...) \, +#define Z_IS_3027_EQ_3027(...) \, +#define Z_IS_3028_EQ_3028(...) \, +#define Z_IS_3029_EQ_3029(...) \, +#define Z_IS_3030_EQ_3030(...) \, +#define Z_IS_3031_EQ_3031(...) \, +#define Z_IS_3032_EQ_3032(...) \, +#define Z_IS_3033_EQ_3033(...) \, +#define Z_IS_3034_EQ_3034(...) \, +#define Z_IS_3035_EQ_3035(...) \, +#define Z_IS_3036_EQ_3036(...) \, +#define Z_IS_3037_EQ_3037(...) \, +#define Z_IS_3038_EQ_3038(...) \, +#define Z_IS_3039_EQ_3039(...) \, +#define Z_IS_3040_EQ_3040(...) \, +#define Z_IS_3041_EQ_3041(...) \, +#define Z_IS_3042_EQ_3042(...) \, +#define Z_IS_3043_EQ_3043(...) \, +#define Z_IS_3044_EQ_3044(...) \, +#define Z_IS_3045_EQ_3045(...) \, +#define Z_IS_3046_EQ_3046(...) \, +#define Z_IS_3047_EQ_3047(...) \, +#define Z_IS_3048_EQ_3048(...) \, +#define Z_IS_3049_EQ_3049(...) \, +#define Z_IS_3050_EQ_3050(...) \, +#define Z_IS_3051_EQ_3051(...) \, +#define Z_IS_3052_EQ_3052(...) \, +#define Z_IS_3053_EQ_3053(...) \, +#define Z_IS_3054_EQ_3054(...) \, +#define Z_IS_3055_EQ_3055(...) \, +#define Z_IS_3056_EQ_3056(...) \, +#define Z_IS_3057_EQ_3057(...) \, +#define Z_IS_3058_EQ_3058(...) \, +#define Z_IS_3059_EQ_3059(...) \, +#define Z_IS_3060_EQ_3060(...) \, +#define Z_IS_3061_EQ_3061(...) \, +#define Z_IS_3062_EQ_3062(...) \, +#define Z_IS_3063_EQ_3063(...) \, +#define Z_IS_3064_EQ_3064(...) \, +#define Z_IS_3065_EQ_3065(...) \, +#define Z_IS_3066_EQ_3066(...) \, +#define Z_IS_3067_EQ_3067(...) \, +#define Z_IS_3068_EQ_3068(...) \, +#define Z_IS_3069_EQ_3069(...) \, +#define Z_IS_3070_EQ_3070(...) \, +#define Z_IS_3071_EQ_3071(...) \, +#define Z_IS_3072_EQ_3072(...) \, +#define Z_IS_3073_EQ_3073(...) \, +#define Z_IS_3074_EQ_3074(...) \, +#define Z_IS_3075_EQ_3075(...) \, +#define Z_IS_3076_EQ_3076(...) \, +#define Z_IS_3077_EQ_3077(...) \, +#define Z_IS_3078_EQ_3078(...) \, +#define Z_IS_3079_EQ_3079(...) \, +#define Z_IS_3080_EQ_3080(...) \, +#define Z_IS_3081_EQ_3081(...) \, +#define Z_IS_3082_EQ_3082(...) \, +#define Z_IS_3083_EQ_3083(...) \, +#define Z_IS_3084_EQ_3084(...) \, +#define Z_IS_3085_EQ_3085(...) \, +#define Z_IS_3086_EQ_3086(...) \, +#define Z_IS_3087_EQ_3087(...) \, +#define Z_IS_3088_EQ_3088(...) \, +#define Z_IS_3089_EQ_3089(...) \, +#define Z_IS_3090_EQ_3090(...) \, +#define Z_IS_3091_EQ_3091(...) \, +#define Z_IS_3092_EQ_3092(...) \, +#define Z_IS_3093_EQ_3093(...) \, +#define Z_IS_3094_EQ_3094(...) \, +#define Z_IS_3095_EQ_3095(...) \, +#define Z_IS_3096_EQ_3096(...) \, +#define Z_IS_3097_EQ_3097(...) \, +#define Z_IS_3098_EQ_3098(...) \, +#define Z_IS_3099_EQ_3099(...) \, +#define Z_IS_3100_EQ_3100(...) \, +#define Z_IS_3101_EQ_3101(...) \, +#define Z_IS_3102_EQ_3102(...) \, +#define Z_IS_3103_EQ_3103(...) \, +#define Z_IS_3104_EQ_3104(...) \, +#define Z_IS_3105_EQ_3105(...) \, +#define Z_IS_3106_EQ_3106(...) \, +#define Z_IS_3107_EQ_3107(...) \, +#define Z_IS_3108_EQ_3108(...) \, +#define Z_IS_3109_EQ_3109(...) \, +#define Z_IS_3110_EQ_3110(...) \, +#define Z_IS_3111_EQ_3111(...) \, +#define Z_IS_3112_EQ_3112(...) \, +#define Z_IS_3113_EQ_3113(...) \, +#define Z_IS_3114_EQ_3114(...) \, +#define Z_IS_3115_EQ_3115(...) \, +#define Z_IS_3116_EQ_3116(...) \, +#define Z_IS_3117_EQ_3117(...) \, +#define Z_IS_3118_EQ_3118(...) \, +#define Z_IS_3119_EQ_3119(...) \, +#define Z_IS_3120_EQ_3120(...) \, +#define Z_IS_3121_EQ_3121(...) \, +#define Z_IS_3122_EQ_3122(...) \, +#define Z_IS_3123_EQ_3123(...) \, +#define Z_IS_3124_EQ_3124(...) \, +#define Z_IS_3125_EQ_3125(...) \, +#define Z_IS_3126_EQ_3126(...) \, +#define Z_IS_3127_EQ_3127(...) \, +#define Z_IS_3128_EQ_3128(...) \, +#define Z_IS_3129_EQ_3129(...) \, +#define Z_IS_3130_EQ_3130(...) \, +#define Z_IS_3131_EQ_3131(...) \, +#define Z_IS_3132_EQ_3132(...) \, +#define Z_IS_3133_EQ_3133(...) \, +#define Z_IS_3134_EQ_3134(...) \, +#define Z_IS_3135_EQ_3135(...) \, +#define Z_IS_3136_EQ_3136(...) \, +#define Z_IS_3137_EQ_3137(...) \, +#define Z_IS_3138_EQ_3138(...) \, +#define Z_IS_3139_EQ_3139(...) \, +#define Z_IS_3140_EQ_3140(...) \, +#define Z_IS_3141_EQ_3141(...) \, +#define Z_IS_3142_EQ_3142(...) \, +#define Z_IS_3143_EQ_3143(...) \, +#define Z_IS_3144_EQ_3144(...) \, +#define Z_IS_3145_EQ_3145(...) \, +#define Z_IS_3146_EQ_3146(...) \, +#define Z_IS_3147_EQ_3147(...) \, +#define Z_IS_3148_EQ_3148(...) \, +#define Z_IS_3149_EQ_3149(...) \, +#define Z_IS_3150_EQ_3150(...) \, +#define Z_IS_3151_EQ_3151(...) \, +#define Z_IS_3152_EQ_3152(...) \, +#define Z_IS_3153_EQ_3153(...) \, +#define Z_IS_3154_EQ_3154(...) \, +#define Z_IS_3155_EQ_3155(...) \, +#define Z_IS_3156_EQ_3156(...) \, +#define Z_IS_3157_EQ_3157(...) \, +#define Z_IS_3158_EQ_3158(...) \, +#define Z_IS_3159_EQ_3159(...) \, +#define Z_IS_3160_EQ_3160(...) \, +#define Z_IS_3161_EQ_3161(...) \, +#define Z_IS_3162_EQ_3162(...) \, +#define Z_IS_3163_EQ_3163(...) \, +#define Z_IS_3164_EQ_3164(...) \, +#define Z_IS_3165_EQ_3165(...) \, +#define Z_IS_3166_EQ_3166(...) \, +#define Z_IS_3167_EQ_3167(...) \, +#define Z_IS_3168_EQ_3168(...) \, +#define Z_IS_3169_EQ_3169(...) \, +#define Z_IS_3170_EQ_3170(...) \, +#define Z_IS_3171_EQ_3171(...) \, +#define Z_IS_3172_EQ_3172(...) \, +#define Z_IS_3173_EQ_3173(...) \, +#define Z_IS_3174_EQ_3174(...) \, +#define Z_IS_3175_EQ_3175(...) \, +#define Z_IS_3176_EQ_3176(...) \, +#define Z_IS_3177_EQ_3177(...) \, +#define Z_IS_3178_EQ_3178(...) \, +#define Z_IS_3179_EQ_3179(...) \, +#define Z_IS_3180_EQ_3180(...) \, +#define Z_IS_3181_EQ_3181(...) \, +#define Z_IS_3182_EQ_3182(...) \, +#define Z_IS_3183_EQ_3183(...) \, +#define Z_IS_3184_EQ_3184(...) \, +#define Z_IS_3185_EQ_3185(...) \, +#define Z_IS_3186_EQ_3186(...) \, +#define Z_IS_3187_EQ_3187(...) \, +#define Z_IS_3188_EQ_3188(...) \, +#define Z_IS_3189_EQ_3189(...) \, +#define Z_IS_3190_EQ_3190(...) \, +#define Z_IS_3191_EQ_3191(...) \, +#define Z_IS_3192_EQ_3192(...) \, +#define Z_IS_3193_EQ_3193(...) \, +#define Z_IS_3194_EQ_3194(...) \, +#define Z_IS_3195_EQ_3195(...) \, +#define Z_IS_3196_EQ_3196(...) \, +#define Z_IS_3197_EQ_3197(...) \, +#define Z_IS_3198_EQ_3198(...) \, +#define Z_IS_3199_EQ_3199(...) \, +#define Z_IS_3200_EQ_3200(...) \, +#define Z_IS_3201_EQ_3201(...) \, +#define Z_IS_3202_EQ_3202(...) \, +#define Z_IS_3203_EQ_3203(...) \, +#define Z_IS_3204_EQ_3204(...) \, +#define Z_IS_3205_EQ_3205(...) \, +#define Z_IS_3206_EQ_3206(...) \, +#define Z_IS_3207_EQ_3207(...) \, +#define Z_IS_3208_EQ_3208(...) \, +#define Z_IS_3209_EQ_3209(...) \, +#define Z_IS_3210_EQ_3210(...) \, +#define Z_IS_3211_EQ_3211(...) \, +#define Z_IS_3212_EQ_3212(...) \, +#define Z_IS_3213_EQ_3213(...) \, +#define Z_IS_3214_EQ_3214(...) \, +#define Z_IS_3215_EQ_3215(...) \, +#define Z_IS_3216_EQ_3216(...) \, +#define Z_IS_3217_EQ_3217(...) \, +#define Z_IS_3218_EQ_3218(...) \, +#define Z_IS_3219_EQ_3219(...) \, +#define Z_IS_3220_EQ_3220(...) \, +#define Z_IS_3221_EQ_3221(...) \, +#define Z_IS_3222_EQ_3222(...) \, +#define Z_IS_3223_EQ_3223(...) \, +#define Z_IS_3224_EQ_3224(...) \, +#define Z_IS_3225_EQ_3225(...) \, +#define Z_IS_3226_EQ_3226(...) \, +#define Z_IS_3227_EQ_3227(...) \, +#define Z_IS_3228_EQ_3228(...) \, +#define Z_IS_3229_EQ_3229(...) \, +#define Z_IS_3230_EQ_3230(...) \, +#define Z_IS_3231_EQ_3231(...) \, +#define Z_IS_3232_EQ_3232(...) \, +#define Z_IS_3233_EQ_3233(...) \, +#define Z_IS_3234_EQ_3234(...) \, +#define Z_IS_3235_EQ_3235(...) \, +#define Z_IS_3236_EQ_3236(...) \, +#define Z_IS_3237_EQ_3237(...) \, +#define Z_IS_3238_EQ_3238(...) \, +#define Z_IS_3239_EQ_3239(...) \, +#define Z_IS_3240_EQ_3240(...) \, +#define Z_IS_3241_EQ_3241(...) \, +#define Z_IS_3242_EQ_3242(...) \, +#define Z_IS_3243_EQ_3243(...) \, +#define Z_IS_3244_EQ_3244(...) \, +#define Z_IS_3245_EQ_3245(...) \, +#define Z_IS_3246_EQ_3246(...) \, +#define Z_IS_3247_EQ_3247(...) \, +#define Z_IS_3248_EQ_3248(...) \, +#define Z_IS_3249_EQ_3249(...) \, +#define Z_IS_3250_EQ_3250(...) \, +#define Z_IS_3251_EQ_3251(...) \, +#define Z_IS_3252_EQ_3252(...) \, +#define Z_IS_3253_EQ_3253(...) \, +#define Z_IS_3254_EQ_3254(...) \, +#define Z_IS_3255_EQ_3255(...) \, +#define Z_IS_3256_EQ_3256(...) \, +#define Z_IS_3257_EQ_3257(...) \, +#define Z_IS_3258_EQ_3258(...) \, +#define Z_IS_3259_EQ_3259(...) \, +#define Z_IS_3260_EQ_3260(...) \, +#define Z_IS_3261_EQ_3261(...) \, +#define Z_IS_3262_EQ_3262(...) \, +#define Z_IS_3263_EQ_3263(...) \, +#define Z_IS_3264_EQ_3264(...) \, +#define Z_IS_3265_EQ_3265(...) \, +#define Z_IS_3266_EQ_3266(...) \, +#define Z_IS_3267_EQ_3267(...) \, +#define Z_IS_3268_EQ_3268(...) \, +#define Z_IS_3269_EQ_3269(...) \, +#define Z_IS_3270_EQ_3270(...) \, +#define Z_IS_3271_EQ_3271(...) \, +#define Z_IS_3272_EQ_3272(...) \, +#define Z_IS_3273_EQ_3273(...) \, +#define Z_IS_3274_EQ_3274(...) \, +#define Z_IS_3275_EQ_3275(...) \, +#define Z_IS_3276_EQ_3276(...) \, +#define Z_IS_3277_EQ_3277(...) \, +#define Z_IS_3278_EQ_3278(...) \, +#define Z_IS_3279_EQ_3279(...) \, +#define Z_IS_3280_EQ_3280(...) \, +#define Z_IS_3281_EQ_3281(...) \, +#define Z_IS_3282_EQ_3282(...) \, +#define Z_IS_3283_EQ_3283(...) \, +#define Z_IS_3284_EQ_3284(...) \, +#define Z_IS_3285_EQ_3285(...) \, +#define Z_IS_3286_EQ_3286(...) \, +#define Z_IS_3287_EQ_3287(...) \, +#define Z_IS_3288_EQ_3288(...) \, +#define Z_IS_3289_EQ_3289(...) \, +#define Z_IS_3290_EQ_3290(...) \, +#define Z_IS_3291_EQ_3291(...) \, +#define Z_IS_3292_EQ_3292(...) \, +#define Z_IS_3293_EQ_3293(...) \, +#define Z_IS_3294_EQ_3294(...) \, +#define Z_IS_3295_EQ_3295(...) \, +#define Z_IS_3296_EQ_3296(...) \, +#define Z_IS_3297_EQ_3297(...) \, +#define Z_IS_3298_EQ_3298(...) \, +#define Z_IS_3299_EQ_3299(...) \, +#define Z_IS_3300_EQ_3300(...) \, +#define Z_IS_3301_EQ_3301(...) \, +#define Z_IS_3302_EQ_3302(...) \, +#define Z_IS_3303_EQ_3303(...) \, +#define Z_IS_3304_EQ_3304(...) \, +#define Z_IS_3305_EQ_3305(...) \, +#define Z_IS_3306_EQ_3306(...) \, +#define Z_IS_3307_EQ_3307(...) \, +#define Z_IS_3308_EQ_3308(...) \, +#define Z_IS_3309_EQ_3309(...) \, +#define Z_IS_3310_EQ_3310(...) \, +#define Z_IS_3311_EQ_3311(...) \, +#define Z_IS_3312_EQ_3312(...) \, +#define Z_IS_3313_EQ_3313(...) \, +#define Z_IS_3314_EQ_3314(...) \, +#define Z_IS_3315_EQ_3315(...) \, +#define Z_IS_3316_EQ_3316(...) \, +#define Z_IS_3317_EQ_3317(...) \, +#define Z_IS_3318_EQ_3318(...) \, +#define Z_IS_3319_EQ_3319(...) \, +#define Z_IS_3320_EQ_3320(...) \, +#define Z_IS_3321_EQ_3321(...) \, +#define Z_IS_3322_EQ_3322(...) \, +#define Z_IS_3323_EQ_3323(...) \, +#define Z_IS_3324_EQ_3324(...) \, +#define Z_IS_3325_EQ_3325(...) \, +#define Z_IS_3326_EQ_3326(...) \, +#define Z_IS_3327_EQ_3327(...) \, +#define Z_IS_3328_EQ_3328(...) \, +#define Z_IS_3329_EQ_3329(...) \, +#define Z_IS_3330_EQ_3330(...) \, +#define Z_IS_3331_EQ_3331(...) \, +#define Z_IS_3332_EQ_3332(...) \, +#define Z_IS_3333_EQ_3333(...) \, +#define Z_IS_3334_EQ_3334(...) \, +#define Z_IS_3335_EQ_3335(...) \, +#define Z_IS_3336_EQ_3336(...) \, +#define Z_IS_3337_EQ_3337(...) \, +#define Z_IS_3338_EQ_3338(...) \, +#define Z_IS_3339_EQ_3339(...) \, +#define Z_IS_3340_EQ_3340(...) \, +#define Z_IS_3341_EQ_3341(...) \, +#define Z_IS_3342_EQ_3342(...) \, +#define Z_IS_3343_EQ_3343(...) \, +#define Z_IS_3344_EQ_3344(...) \, +#define Z_IS_3345_EQ_3345(...) \, +#define Z_IS_3346_EQ_3346(...) \, +#define Z_IS_3347_EQ_3347(...) \, +#define Z_IS_3348_EQ_3348(...) \, +#define Z_IS_3349_EQ_3349(...) \, +#define Z_IS_3350_EQ_3350(...) \, +#define Z_IS_3351_EQ_3351(...) \, +#define Z_IS_3352_EQ_3352(...) \, +#define Z_IS_3353_EQ_3353(...) \, +#define Z_IS_3354_EQ_3354(...) \, +#define Z_IS_3355_EQ_3355(...) \, +#define Z_IS_3356_EQ_3356(...) \, +#define Z_IS_3357_EQ_3357(...) \, +#define Z_IS_3358_EQ_3358(...) \, +#define Z_IS_3359_EQ_3359(...) \, +#define Z_IS_3360_EQ_3360(...) \, +#define Z_IS_3361_EQ_3361(...) \, +#define Z_IS_3362_EQ_3362(...) \, +#define Z_IS_3363_EQ_3363(...) \, +#define Z_IS_3364_EQ_3364(...) \, +#define Z_IS_3365_EQ_3365(...) \, +#define Z_IS_3366_EQ_3366(...) \, +#define Z_IS_3367_EQ_3367(...) \, +#define Z_IS_3368_EQ_3368(...) \, +#define Z_IS_3369_EQ_3369(...) \, +#define Z_IS_3370_EQ_3370(...) \, +#define Z_IS_3371_EQ_3371(...) \, +#define Z_IS_3372_EQ_3372(...) \, +#define Z_IS_3373_EQ_3373(...) \, +#define Z_IS_3374_EQ_3374(...) \, +#define Z_IS_3375_EQ_3375(...) \, +#define Z_IS_3376_EQ_3376(...) \, +#define Z_IS_3377_EQ_3377(...) \, +#define Z_IS_3378_EQ_3378(...) \, +#define Z_IS_3379_EQ_3379(...) \, +#define Z_IS_3380_EQ_3380(...) \, +#define Z_IS_3381_EQ_3381(...) \, +#define Z_IS_3382_EQ_3382(...) \, +#define Z_IS_3383_EQ_3383(...) \, +#define Z_IS_3384_EQ_3384(...) \, +#define Z_IS_3385_EQ_3385(...) \, +#define Z_IS_3386_EQ_3386(...) \, +#define Z_IS_3387_EQ_3387(...) \, +#define Z_IS_3388_EQ_3388(...) \, +#define Z_IS_3389_EQ_3389(...) \, +#define Z_IS_3390_EQ_3390(...) \, +#define Z_IS_3391_EQ_3391(...) \, +#define Z_IS_3392_EQ_3392(...) \, +#define Z_IS_3393_EQ_3393(...) \, +#define Z_IS_3394_EQ_3394(...) \, +#define Z_IS_3395_EQ_3395(...) \, +#define Z_IS_3396_EQ_3396(...) \, +#define Z_IS_3397_EQ_3397(...) \, +#define Z_IS_3398_EQ_3398(...) \, +#define Z_IS_3399_EQ_3399(...) \, +#define Z_IS_3400_EQ_3400(...) \, +#define Z_IS_3401_EQ_3401(...) \, +#define Z_IS_3402_EQ_3402(...) \, +#define Z_IS_3403_EQ_3403(...) \, +#define Z_IS_3404_EQ_3404(...) \, +#define Z_IS_3405_EQ_3405(...) \, +#define Z_IS_3406_EQ_3406(...) \, +#define Z_IS_3407_EQ_3407(...) \, +#define Z_IS_3408_EQ_3408(...) \, +#define Z_IS_3409_EQ_3409(...) \, +#define Z_IS_3410_EQ_3410(...) \, +#define Z_IS_3411_EQ_3411(...) \, +#define Z_IS_3412_EQ_3412(...) \, +#define Z_IS_3413_EQ_3413(...) \, +#define Z_IS_3414_EQ_3414(...) \, +#define Z_IS_3415_EQ_3415(...) \, +#define Z_IS_3416_EQ_3416(...) \, +#define Z_IS_3417_EQ_3417(...) \, +#define Z_IS_3418_EQ_3418(...) \, +#define Z_IS_3419_EQ_3419(...) \, +#define Z_IS_3420_EQ_3420(...) \, +#define Z_IS_3421_EQ_3421(...) \, +#define Z_IS_3422_EQ_3422(...) \, +#define Z_IS_3423_EQ_3423(...) \, +#define Z_IS_3424_EQ_3424(...) \, +#define Z_IS_3425_EQ_3425(...) \, +#define Z_IS_3426_EQ_3426(...) \, +#define Z_IS_3427_EQ_3427(...) \, +#define Z_IS_3428_EQ_3428(...) \, +#define Z_IS_3429_EQ_3429(...) \, +#define Z_IS_3430_EQ_3430(...) \, +#define Z_IS_3431_EQ_3431(...) \, +#define Z_IS_3432_EQ_3432(...) \, +#define Z_IS_3433_EQ_3433(...) \, +#define Z_IS_3434_EQ_3434(...) \, +#define Z_IS_3435_EQ_3435(...) \, +#define Z_IS_3436_EQ_3436(...) \, +#define Z_IS_3437_EQ_3437(...) \, +#define Z_IS_3438_EQ_3438(...) \, +#define Z_IS_3439_EQ_3439(...) \, +#define Z_IS_3440_EQ_3440(...) \, +#define Z_IS_3441_EQ_3441(...) \, +#define Z_IS_3442_EQ_3442(...) \, +#define Z_IS_3443_EQ_3443(...) \, +#define Z_IS_3444_EQ_3444(...) \, +#define Z_IS_3445_EQ_3445(...) \, +#define Z_IS_3446_EQ_3446(...) \, +#define Z_IS_3447_EQ_3447(...) \, +#define Z_IS_3448_EQ_3448(...) \, +#define Z_IS_3449_EQ_3449(...) \, +#define Z_IS_3450_EQ_3450(...) \, +#define Z_IS_3451_EQ_3451(...) \, +#define Z_IS_3452_EQ_3452(...) \, +#define Z_IS_3453_EQ_3453(...) \, +#define Z_IS_3454_EQ_3454(...) \, +#define Z_IS_3455_EQ_3455(...) \, +#define Z_IS_3456_EQ_3456(...) \, +#define Z_IS_3457_EQ_3457(...) \, +#define Z_IS_3458_EQ_3458(...) \, +#define Z_IS_3459_EQ_3459(...) \, +#define Z_IS_3460_EQ_3460(...) \, +#define Z_IS_3461_EQ_3461(...) \, +#define Z_IS_3462_EQ_3462(...) \, +#define Z_IS_3463_EQ_3463(...) \, +#define Z_IS_3464_EQ_3464(...) \, +#define Z_IS_3465_EQ_3465(...) \, +#define Z_IS_3466_EQ_3466(...) \, +#define Z_IS_3467_EQ_3467(...) \, +#define Z_IS_3468_EQ_3468(...) \, +#define Z_IS_3469_EQ_3469(...) \, +#define Z_IS_3470_EQ_3470(...) \, +#define Z_IS_3471_EQ_3471(...) \, +#define Z_IS_3472_EQ_3472(...) \, +#define Z_IS_3473_EQ_3473(...) \, +#define Z_IS_3474_EQ_3474(...) \, +#define Z_IS_3475_EQ_3475(...) \, +#define Z_IS_3476_EQ_3476(...) \, +#define Z_IS_3477_EQ_3477(...) \, +#define Z_IS_3478_EQ_3478(...) \, +#define Z_IS_3479_EQ_3479(...) \, +#define Z_IS_3480_EQ_3480(...) \, +#define Z_IS_3481_EQ_3481(...) \, +#define Z_IS_3482_EQ_3482(...) \, +#define Z_IS_3483_EQ_3483(...) \, +#define Z_IS_3484_EQ_3484(...) \, +#define Z_IS_3485_EQ_3485(...) \, +#define Z_IS_3486_EQ_3486(...) \, +#define Z_IS_3487_EQ_3487(...) \, +#define Z_IS_3488_EQ_3488(...) \, +#define Z_IS_3489_EQ_3489(...) \, +#define Z_IS_3490_EQ_3490(...) \, +#define Z_IS_3491_EQ_3491(...) \, +#define Z_IS_3492_EQ_3492(...) \, +#define Z_IS_3493_EQ_3493(...) \, +#define Z_IS_3494_EQ_3494(...) \, +#define Z_IS_3495_EQ_3495(...) \, +#define Z_IS_3496_EQ_3496(...) \, +#define Z_IS_3497_EQ_3497(...) \, +#define Z_IS_3498_EQ_3498(...) \, +#define Z_IS_3499_EQ_3499(...) \, +#define Z_IS_3500_EQ_3500(...) \, +#define Z_IS_3501_EQ_3501(...) \, +#define Z_IS_3502_EQ_3502(...) \, +#define Z_IS_3503_EQ_3503(...) \, +#define Z_IS_3504_EQ_3504(...) \, +#define Z_IS_3505_EQ_3505(...) \, +#define Z_IS_3506_EQ_3506(...) \, +#define Z_IS_3507_EQ_3507(...) \, +#define Z_IS_3508_EQ_3508(...) \, +#define Z_IS_3509_EQ_3509(...) \, +#define Z_IS_3510_EQ_3510(...) \, +#define Z_IS_3511_EQ_3511(...) \, +#define Z_IS_3512_EQ_3512(...) \, +#define Z_IS_3513_EQ_3513(...) \, +#define Z_IS_3514_EQ_3514(...) \, +#define Z_IS_3515_EQ_3515(...) \, +#define Z_IS_3516_EQ_3516(...) \, +#define Z_IS_3517_EQ_3517(...) \, +#define Z_IS_3518_EQ_3518(...) \, +#define Z_IS_3519_EQ_3519(...) \, +#define Z_IS_3520_EQ_3520(...) \, +#define Z_IS_3521_EQ_3521(...) \, +#define Z_IS_3522_EQ_3522(...) \, +#define Z_IS_3523_EQ_3523(...) \, +#define Z_IS_3524_EQ_3524(...) \, +#define Z_IS_3525_EQ_3525(...) \, +#define Z_IS_3526_EQ_3526(...) \, +#define Z_IS_3527_EQ_3527(...) \, +#define Z_IS_3528_EQ_3528(...) \, +#define Z_IS_3529_EQ_3529(...) \, +#define Z_IS_3530_EQ_3530(...) \, +#define Z_IS_3531_EQ_3531(...) \, +#define Z_IS_3532_EQ_3532(...) \, +#define Z_IS_3533_EQ_3533(...) \, +#define Z_IS_3534_EQ_3534(...) \, +#define Z_IS_3535_EQ_3535(...) \, +#define Z_IS_3536_EQ_3536(...) \, +#define Z_IS_3537_EQ_3537(...) \, +#define Z_IS_3538_EQ_3538(...) \, +#define Z_IS_3539_EQ_3539(...) \, +#define Z_IS_3540_EQ_3540(...) \, +#define Z_IS_3541_EQ_3541(...) \, +#define Z_IS_3542_EQ_3542(...) \, +#define Z_IS_3543_EQ_3543(...) \, +#define Z_IS_3544_EQ_3544(...) \, +#define Z_IS_3545_EQ_3545(...) \, +#define Z_IS_3546_EQ_3546(...) \, +#define Z_IS_3547_EQ_3547(...) \, +#define Z_IS_3548_EQ_3548(...) \, +#define Z_IS_3549_EQ_3549(...) \, +#define Z_IS_3550_EQ_3550(...) \, +#define Z_IS_3551_EQ_3551(...) \, +#define Z_IS_3552_EQ_3552(...) \, +#define Z_IS_3553_EQ_3553(...) \, +#define Z_IS_3554_EQ_3554(...) \, +#define Z_IS_3555_EQ_3555(...) \, +#define Z_IS_3556_EQ_3556(...) \, +#define Z_IS_3557_EQ_3557(...) \, +#define Z_IS_3558_EQ_3558(...) \, +#define Z_IS_3559_EQ_3559(...) \, +#define Z_IS_3560_EQ_3560(...) \, +#define Z_IS_3561_EQ_3561(...) \, +#define Z_IS_3562_EQ_3562(...) \, +#define Z_IS_3563_EQ_3563(...) \, +#define Z_IS_3564_EQ_3564(...) \, +#define Z_IS_3565_EQ_3565(...) \, +#define Z_IS_3566_EQ_3566(...) \, +#define Z_IS_3567_EQ_3567(...) \, +#define Z_IS_3568_EQ_3568(...) \, +#define Z_IS_3569_EQ_3569(...) \, +#define Z_IS_3570_EQ_3570(...) \, +#define Z_IS_3571_EQ_3571(...) \, +#define Z_IS_3572_EQ_3572(...) \, +#define Z_IS_3573_EQ_3573(...) \, +#define Z_IS_3574_EQ_3574(...) \, +#define Z_IS_3575_EQ_3575(...) \, +#define Z_IS_3576_EQ_3576(...) \, +#define Z_IS_3577_EQ_3577(...) \, +#define Z_IS_3578_EQ_3578(...) \, +#define Z_IS_3579_EQ_3579(...) \, +#define Z_IS_3580_EQ_3580(...) \, +#define Z_IS_3581_EQ_3581(...) \, +#define Z_IS_3582_EQ_3582(...) \, +#define Z_IS_3583_EQ_3583(...) \, +#define Z_IS_3584_EQ_3584(...) \, +#define Z_IS_3585_EQ_3585(...) \, +#define Z_IS_3586_EQ_3586(...) \, +#define Z_IS_3587_EQ_3587(...) \, +#define Z_IS_3588_EQ_3588(...) \, +#define Z_IS_3589_EQ_3589(...) \, +#define Z_IS_3590_EQ_3590(...) \, +#define Z_IS_3591_EQ_3591(...) \, +#define Z_IS_3592_EQ_3592(...) \, +#define Z_IS_3593_EQ_3593(...) \, +#define Z_IS_3594_EQ_3594(...) \, +#define Z_IS_3595_EQ_3595(...) \, +#define Z_IS_3596_EQ_3596(...) \, +#define Z_IS_3597_EQ_3597(...) \, +#define Z_IS_3598_EQ_3598(...) \, +#define Z_IS_3599_EQ_3599(...) \, +#define Z_IS_3600_EQ_3600(...) \, +#define Z_IS_3601_EQ_3601(...) \, +#define Z_IS_3602_EQ_3602(...) \, +#define Z_IS_3603_EQ_3603(...) \, +#define Z_IS_3604_EQ_3604(...) \, +#define Z_IS_3605_EQ_3605(...) \, +#define Z_IS_3606_EQ_3606(...) \, +#define Z_IS_3607_EQ_3607(...) \, +#define Z_IS_3608_EQ_3608(...) \, +#define Z_IS_3609_EQ_3609(...) \, +#define Z_IS_3610_EQ_3610(...) \, +#define Z_IS_3611_EQ_3611(...) \, +#define Z_IS_3612_EQ_3612(...) \, +#define Z_IS_3613_EQ_3613(...) \, +#define Z_IS_3614_EQ_3614(...) \, +#define Z_IS_3615_EQ_3615(...) \, +#define Z_IS_3616_EQ_3616(...) \, +#define Z_IS_3617_EQ_3617(...) \, +#define Z_IS_3618_EQ_3618(...) \, +#define Z_IS_3619_EQ_3619(...) \, +#define Z_IS_3620_EQ_3620(...) \, +#define Z_IS_3621_EQ_3621(...) \, +#define Z_IS_3622_EQ_3622(...) \, +#define Z_IS_3623_EQ_3623(...) \, +#define Z_IS_3624_EQ_3624(...) \, +#define Z_IS_3625_EQ_3625(...) \, +#define Z_IS_3626_EQ_3626(...) \, +#define Z_IS_3627_EQ_3627(...) \, +#define Z_IS_3628_EQ_3628(...) \, +#define Z_IS_3629_EQ_3629(...) \, +#define Z_IS_3630_EQ_3630(...) \, +#define Z_IS_3631_EQ_3631(...) \, +#define Z_IS_3632_EQ_3632(...) \, +#define Z_IS_3633_EQ_3633(...) \, +#define Z_IS_3634_EQ_3634(...) \, +#define Z_IS_3635_EQ_3635(...) \, +#define Z_IS_3636_EQ_3636(...) \, +#define Z_IS_3637_EQ_3637(...) \, +#define Z_IS_3638_EQ_3638(...) \, +#define Z_IS_3639_EQ_3639(...) \, +#define Z_IS_3640_EQ_3640(...) \, +#define Z_IS_3641_EQ_3641(...) \, +#define Z_IS_3642_EQ_3642(...) \, +#define Z_IS_3643_EQ_3643(...) \, +#define Z_IS_3644_EQ_3644(...) \, +#define Z_IS_3645_EQ_3645(...) \, +#define Z_IS_3646_EQ_3646(...) \, +#define Z_IS_3647_EQ_3647(...) \, +#define Z_IS_3648_EQ_3648(...) \, +#define Z_IS_3649_EQ_3649(...) \, +#define Z_IS_3650_EQ_3650(...) \, +#define Z_IS_3651_EQ_3651(...) \, +#define Z_IS_3652_EQ_3652(...) \, +#define Z_IS_3653_EQ_3653(...) \, +#define Z_IS_3654_EQ_3654(...) \, +#define Z_IS_3655_EQ_3655(...) \, +#define Z_IS_3656_EQ_3656(...) \, +#define Z_IS_3657_EQ_3657(...) \, +#define Z_IS_3658_EQ_3658(...) \, +#define Z_IS_3659_EQ_3659(...) \, +#define Z_IS_3660_EQ_3660(...) \, +#define Z_IS_3661_EQ_3661(...) \, +#define Z_IS_3662_EQ_3662(...) \, +#define Z_IS_3663_EQ_3663(...) \, +#define Z_IS_3664_EQ_3664(...) \, +#define Z_IS_3665_EQ_3665(...) \, +#define Z_IS_3666_EQ_3666(...) \, +#define Z_IS_3667_EQ_3667(...) \, +#define Z_IS_3668_EQ_3668(...) \, +#define Z_IS_3669_EQ_3669(...) \, +#define Z_IS_3670_EQ_3670(...) \, +#define Z_IS_3671_EQ_3671(...) \, +#define Z_IS_3672_EQ_3672(...) \, +#define Z_IS_3673_EQ_3673(...) \, +#define Z_IS_3674_EQ_3674(...) \, +#define Z_IS_3675_EQ_3675(...) \, +#define Z_IS_3676_EQ_3676(...) \, +#define Z_IS_3677_EQ_3677(...) \, +#define Z_IS_3678_EQ_3678(...) \, +#define Z_IS_3679_EQ_3679(...) \, +#define Z_IS_3680_EQ_3680(...) \, +#define Z_IS_3681_EQ_3681(...) \, +#define Z_IS_3682_EQ_3682(...) \, +#define Z_IS_3683_EQ_3683(...) \, +#define Z_IS_3684_EQ_3684(...) \, +#define Z_IS_3685_EQ_3685(...) \, +#define Z_IS_3686_EQ_3686(...) \, +#define Z_IS_3687_EQ_3687(...) \, +#define Z_IS_3688_EQ_3688(...) \, +#define Z_IS_3689_EQ_3689(...) \, +#define Z_IS_3690_EQ_3690(...) \, +#define Z_IS_3691_EQ_3691(...) \, +#define Z_IS_3692_EQ_3692(...) \, +#define Z_IS_3693_EQ_3693(...) \, +#define Z_IS_3694_EQ_3694(...) \, +#define Z_IS_3695_EQ_3695(...) \, +#define Z_IS_3696_EQ_3696(...) \, +#define Z_IS_3697_EQ_3697(...) \, +#define Z_IS_3698_EQ_3698(...) \, +#define Z_IS_3699_EQ_3699(...) \, +#define Z_IS_3700_EQ_3700(...) \, +#define Z_IS_3701_EQ_3701(...) \, +#define Z_IS_3702_EQ_3702(...) \, +#define Z_IS_3703_EQ_3703(...) \, +#define Z_IS_3704_EQ_3704(...) \, +#define Z_IS_3705_EQ_3705(...) \, +#define Z_IS_3706_EQ_3706(...) \, +#define Z_IS_3707_EQ_3707(...) \, +#define Z_IS_3708_EQ_3708(...) \, +#define Z_IS_3709_EQ_3709(...) \, +#define Z_IS_3710_EQ_3710(...) \, +#define Z_IS_3711_EQ_3711(...) \, +#define Z_IS_3712_EQ_3712(...) \, +#define Z_IS_3713_EQ_3713(...) \, +#define Z_IS_3714_EQ_3714(...) \, +#define Z_IS_3715_EQ_3715(...) \, +#define Z_IS_3716_EQ_3716(...) \, +#define Z_IS_3717_EQ_3717(...) \, +#define Z_IS_3718_EQ_3718(...) \, +#define Z_IS_3719_EQ_3719(...) \, +#define Z_IS_3720_EQ_3720(...) \, +#define Z_IS_3721_EQ_3721(...) \, +#define Z_IS_3722_EQ_3722(...) \, +#define Z_IS_3723_EQ_3723(...) \, +#define Z_IS_3724_EQ_3724(...) \, +#define Z_IS_3725_EQ_3725(...) \, +#define Z_IS_3726_EQ_3726(...) \, +#define Z_IS_3727_EQ_3727(...) \, +#define Z_IS_3728_EQ_3728(...) \, +#define Z_IS_3729_EQ_3729(...) \, +#define Z_IS_3730_EQ_3730(...) \, +#define Z_IS_3731_EQ_3731(...) \, +#define Z_IS_3732_EQ_3732(...) \, +#define Z_IS_3733_EQ_3733(...) \, +#define Z_IS_3734_EQ_3734(...) \, +#define Z_IS_3735_EQ_3735(...) \, +#define Z_IS_3736_EQ_3736(...) \, +#define Z_IS_3737_EQ_3737(...) \, +#define Z_IS_3738_EQ_3738(...) \, +#define Z_IS_3739_EQ_3739(...) \, +#define Z_IS_3740_EQ_3740(...) \, +#define Z_IS_3741_EQ_3741(...) \, +#define Z_IS_3742_EQ_3742(...) \, +#define Z_IS_3743_EQ_3743(...) \, +#define Z_IS_3744_EQ_3744(...) \, +#define Z_IS_3745_EQ_3745(...) \, +#define Z_IS_3746_EQ_3746(...) \, +#define Z_IS_3747_EQ_3747(...) \, +#define Z_IS_3748_EQ_3748(...) \, +#define Z_IS_3749_EQ_3749(...) \, +#define Z_IS_3750_EQ_3750(...) \, +#define Z_IS_3751_EQ_3751(...) \, +#define Z_IS_3752_EQ_3752(...) \, +#define Z_IS_3753_EQ_3753(...) \, +#define Z_IS_3754_EQ_3754(...) \, +#define Z_IS_3755_EQ_3755(...) \, +#define Z_IS_3756_EQ_3756(...) \, +#define Z_IS_3757_EQ_3757(...) \, +#define Z_IS_3758_EQ_3758(...) \, +#define Z_IS_3759_EQ_3759(...) \, +#define Z_IS_3760_EQ_3760(...) \, +#define Z_IS_3761_EQ_3761(...) \, +#define Z_IS_3762_EQ_3762(...) \, +#define Z_IS_3763_EQ_3763(...) \, +#define Z_IS_3764_EQ_3764(...) \, +#define Z_IS_3765_EQ_3765(...) \, +#define Z_IS_3766_EQ_3766(...) \, +#define Z_IS_3767_EQ_3767(...) \, +#define Z_IS_3768_EQ_3768(...) \, +#define Z_IS_3769_EQ_3769(...) \, +#define Z_IS_3770_EQ_3770(...) \, +#define Z_IS_3771_EQ_3771(...) \, +#define Z_IS_3772_EQ_3772(...) \, +#define Z_IS_3773_EQ_3773(...) \, +#define Z_IS_3774_EQ_3774(...) \, +#define Z_IS_3775_EQ_3775(...) \, +#define Z_IS_3776_EQ_3776(...) \, +#define Z_IS_3777_EQ_3777(...) \, +#define Z_IS_3778_EQ_3778(...) \, +#define Z_IS_3779_EQ_3779(...) \, +#define Z_IS_3780_EQ_3780(...) \, +#define Z_IS_3781_EQ_3781(...) \, +#define Z_IS_3782_EQ_3782(...) \, +#define Z_IS_3783_EQ_3783(...) \, +#define Z_IS_3784_EQ_3784(...) \, +#define Z_IS_3785_EQ_3785(...) \, +#define Z_IS_3786_EQ_3786(...) \, +#define Z_IS_3787_EQ_3787(...) \, +#define Z_IS_3788_EQ_3788(...) \, +#define Z_IS_3789_EQ_3789(...) \, +#define Z_IS_3790_EQ_3790(...) \, +#define Z_IS_3791_EQ_3791(...) \, +#define Z_IS_3792_EQ_3792(...) \, +#define Z_IS_3793_EQ_3793(...) \, +#define Z_IS_3794_EQ_3794(...) \, +#define Z_IS_3795_EQ_3795(...) \, +#define Z_IS_3796_EQ_3796(...) \, +#define Z_IS_3797_EQ_3797(...) \, +#define Z_IS_3798_EQ_3798(...) \, +#define Z_IS_3799_EQ_3799(...) \, +#define Z_IS_3800_EQ_3800(...) \, +#define Z_IS_3801_EQ_3801(...) \, +#define Z_IS_3802_EQ_3802(...) \, +#define Z_IS_3803_EQ_3803(...) \, +#define Z_IS_3804_EQ_3804(...) \, +#define Z_IS_3805_EQ_3805(...) \, +#define Z_IS_3806_EQ_3806(...) \, +#define Z_IS_3807_EQ_3807(...) \, +#define Z_IS_3808_EQ_3808(...) \, +#define Z_IS_3809_EQ_3809(...) \, +#define Z_IS_3810_EQ_3810(...) \, +#define Z_IS_3811_EQ_3811(...) \, +#define Z_IS_3812_EQ_3812(...) \, +#define Z_IS_3813_EQ_3813(...) \, +#define Z_IS_3814_EQ_3814(...) \, +#define Z_IS_3815_EQ_3815(...) \, +#define Z_IS_3816_EQ_3816(...) \, +#define Z_IS_3817_EQ_3817(...) \, +#define Z_IS_3818_EQ_3818(...) \, +#define Z_IS_3819_EQ_3819(...) \, +#define Z_IS_3820_EQ_3820(...) \, +#define Z_IS_3821_EQ_3821(...) \, +#define Z_IS_3822_EQ_3822(...) \, +#define Z_IS_3823_EQ_3823(...) \, +#define Z_IS_3824_EQ_3824(...) \, +#define Z_IS_3825_EQ_3825(...) \, +#define Z_IS_3826_EQ_3826(...) \, +#define Z_IS_3827_EQ_3827(...) \, +#define Z_IS_3828_EQ_3828(...) \, +#define Z_IS_3829_EQ_3829(...) \, +#define Z_IS_3830_EQ_3830(...) \, +#define Z_IS_3831_EQ_3831(...) \, +#define Z_IS_3832_EQ_3832(...) \, +#define Z_IS_3833_EQ_3833(...) \, +#define Z_IS_3834_EQ_3834(...) \, +#define Z_IS_3835_EQ_3835(...) \, +#define Z_IS_3836_EQ_3836(...) \, +#define Z_IS_3837_EQ_3837(...) \, +#define Z_IS_3838_EQ_3838(...) \, +#define Z_IS_3839_EQ_3839(...) \, +#define Z_IS_3840_EQ_3840(...) \, +#define Z_IS_3841_EQ_3841(...) \, +#define Z_IS_3842_EQ_3842(...) \, +#define Z_IS_3843_EQ_3843(...) \, +#define Z_IS_3844_EQ_3844(...) \, +#define Z_IS_3845_EQ_3845(...) \, +#define Z_IS_3846_EQ_3846(...) \, +#define Z_IS_3847_EQ_3847(...) \, +#define Z_IS_3848_EQ_3848(...) \, +#define Z_IS_3849_EQ_3849(...) \, +#define Z_IS_3850_EQ_3850(...) \, +#define Z_IS_3851_EQ_3851(...) \, +#define Z_IS_3852_EQ_3852(...) \, +#define Z_IS_3853_EQ_3853(...) \, +#define Z_IS_3854_EQ_3854(...) \, +#define Z_IS_3855_EQ_3855(...) \, +#define Z_IS_3856_EQ_3856(...) \, +#define Z_IS_3857_EQ_3857(...) \, +#define Z_IS_3858_EQ_3858(...) \, +#define Z_IS_3859_EQ_3859(...) \, +#define Z_IS_3860_EQ_3860(...) \, +#define Z_IS_3861_EQ_3861(...) \, +#define Z_IS_3862_EQ_3862(...) \, +#define Z_IS_3863_EQ_3863(...) \, +#define Z_IS_3864_EQ_3864(...) \, +#define Z_IS_3865_EQ_3865(...) \, +#define Z_IS_3866_EQ_3866(...) \, +#define Z_IS_3867_EQ_3867(...) \, +#define Z_IS_3868_EQ_3868(...) \, +#define Z_IS_3869_EQ_3869(...) \, +#define Z_IS_3870_EQ_3870(...) \, +#define Z_IS_3871_EQ_3871(...) \, +#define Z_IS_3872_EQ_3872(...) \, +#define Z_IS_3873_EQ_3873(...) \, +#define Z_IS_3874_EQ_3874(...) \, +#define Z_IS_3875_EQ_3875(...) \, +#define Z_IS_3876_EQ_3876(...) \, +#define Z_IS_3877_EQ_3877(...) \, +#define Z_IS_3878_EQ_3878(...) \, +#define Z_IS_3879_EQ_3879(...) \, +#define Z_IS_3880_EQ_3880(...) \, +#define Z_IS_3881_EQ_3881(...) \, +#define Z_IS_3882_EQ_3882(...) \, +#define Z_IS_3883_EQ_3883(...) \, +#define Z_IS_3884_EQ_3884(...) \, +#define Z_IS_3885_EQ_3885(...) \, +#define Z_IS_3886_EQ_3886(...) \, +#define Z_IS_3887_EQ_3887(...) \, +#define Z_IS_3888_EQ_3888(...) \, +#define Z_IS_3889_EQ_3889(...) \, +#define Z_IS_3890_EQ_3890(...) \, +#define Z_IS_3891_EQ_3891(...) \, +#define Z_IS_3892_EQ_3892(...) \, +#define Z_IS_3893_EQ_3893(...) \, +#define Z_IS_3894_EQ_3894(...) \, +#define Z_IS_3895_EQ_3895(...) \, +#define Z_IS_3896_EQ_3896(...) \, +#define Z_IS_3897_EQ_3897(...) \, +#define Z_IS_3898_EQ_3898(...) \, +#define Z_IS_3899_EQ_3899(...) \, +#define Z_IS_3900_EQ_3900(...) \, +#define Z_IS_3901_EQ_3901(...) \, +#define Z_IS_3902_EQ_3902(...) \, +#define Z_IS_3903_EQ_3903(...) \, +#define Z_IS_3904_EQ_3904(...) \, +#define Z_IS_3905_EQ_3905(...) \, +#define Z_IS_3906_EQ_3906(...) \, +#define Z_IS_3907_EQ_3907(...) \, +#define Z_IS_3908_EQ_3908(...) \, +#define Z_IS_3909_EQ_3909(...) \, +#define Z_IS_3910_EQ_3910(...) \, +#define Z_IS_3911_EQ_3911(...) \, +#define Z_IS_3912_EQ_3912(...) \, +#define Z_IS_3913_EQ_3913(...) \, +#define Z_IS_3914_EQ_3914(...) \, +#define Z_IS_3915_EQ_3915(...) \, +#define Z_IS_3916_EQ_3916(...) \, +#define Z_IS_3917_EQ_3917(...) \, +#define Z_IS_3918_EQ_3918(...) \, +#define Z_IS_3919_EQ_3919(...) \, +#define Z_IS_3920_EQ_3920(...) \, +#define Z_IS_3921_EQ_3921(...) \, +#define Z_IS_3922_EQ_3922(...) \, +#define Z_IS_3923_EQ_3923(...) \, +#define Z_IS_3924_EQ_3924(...) \, +#define Z_IS_3925_EQ_3925(...) \, +#define Z_IS_3926_EQ_3926(...) \, +#define Z_IS_3927_EQ_3927(...) \, +#define Z_IS_3928_EQ_3928(...) \, +#define Z_IS_3929_EQ_3929(...) \, +#define Z_IS_3930_EQ_3930(...) \, +#define Z_IS_3931_EQ_3931(...) \, +#define Z_IS_3932_EQ_3932(...) \, +#define Z_IS_3933_EQ_3933(...) \, +#define Z_IS_3934_EQ_3934(...) \, +#define Z_IS_3935_EQ_3935(...) \, +#define Z_IS_3936_EQ_3936(...) \, +#define Z_IS_3937_EQ_3937(...) \, +#define Z_IS_3938_EQ_3938(...) \, +#define Z_IS_3939_EQ_3939(...) \, +#define Z_IS_3940_EQ_3940(...) \, +#define Z_IS_3941_EQ_3941(...) \, +#define Z_IS_3942_EQ_3942(...) \, +#define Z_IS_3943_EQ_3943(...) \, +#define Z_IS_3944_EQ_3944(...) \, +#define Z_IS_3945_EQ_3945(...) \, +#define Z_IS_3946_EQ_3946(...) \, +#define Z_IS_3947_EQ_3947(...) \, +#define Z_IS_3948_EQ_3948(...) \, +#define Z_IS_3949_EQ_3949(...) \, +#define Z_IS_3950_EQ_3950(...) \, +#define Z_IS_3951_EQ_3951(...) \, +#define Z_IS_3952_EQ_3952(...) \, +#define Z_IS_3953_EQ_3953(...) \, +#define Z_IS_3954_EQ_3954(...) \, +#define Z_IS_3955_EQ_3955(...) \, +#define Z_IS_3956_EQ_3956(...) \, +#define Z_IS_3957_EQ_3957(...) \, +#define Z_IS_3958_EQ_3958(...) \, +#define Z_IS_3959_EQ_3959(...) \, +#define Z_IS_3960_EQ_3960(...) \, +#define Z_IS_3961_EQ_3961(...) \, +#define Z_IS_3962_EQ_3962(...) \, +#define Z_IS_3963_EQ_3963(...) \, +#define Z_IS_3964_EQ_3964(...) \, +#define Z_IS_3965_EQ_3965(...) \, +#define Z_IS_3966_EQ_3966(...) \, +#define Z_IS_3967_EQ_3967(...) \, +#define Z_IS_3968_EQ_3968(...) \, +#define Z_IS_3969_EQ_3969(...) \, +#define Z_IS_3970_EQ_3970(...) \, +#define Z_IS_3971_EQ_3971(...) \, +#define Z_IS_3972_EQ_3972(...) \, +#define Z_IS_3973_EQ_3973(...) \, +#define Z_IS_3974_EQ_3974(...) \, +#define Z_IS_3975_EQ_3975(...) \, +#define Z_IS_3976_EQ_3976(...) \, +#define Z_IS_3977_EQ_3977(...) \, +#define Z_IS_3978_EQ_3978(...) \, +#define Z_IS_3979_EQ_3979(...) \, +#define Z_IS_3980_EQ_3980(...) \, +#define Z_IS_3981_EQ_3981(...) \, +#define Z_IS_3982_EQ_3982(...) \, +#define Z_IS_3983_EQ_3983(...) \, +#define Z_IS_3984_EQ_3984(...) \, +#define Z_IS_3985_EQ_3985(...) \, +#define Z_IS_3986_EQ_3986(...) \, +#define Z_IS_3987_EQ_3987(...) \, +#define Z_IS_3988_EQ_3988(...) \, +#define Z_IS_3989_EQ_3989(...) \, +#define Z_IS_3990_EQ_3990(...) \, +#define Z_IS_3991_EQ_3991(...) \, +#define Z_IS_3992_EQ_3992(...) \, +#define Z_IS_3993_EQ_3993(...) \, +#define Z_IS_3994_EQ_3994(...) \, +#define Z_IS_3995_EQ_3995(...) \, +#define Z_IS_3996_EQ_3996(...) \, +#define Z_IS_3997_EQ_3997(...) \, +#define Z_IS_3998_EQ_3998(...) \, +#define Z_IS_3999_EQ_3999(...) \, +#define Z_IS_4000_EQ_4000(...) \, +#define Z_IS_4001_EQ_4001(...) \, +#define Z_IS_4002_EQ_4002(...) \, +#define Z_IS_4003_EQ_4003(...) \, +#define Z_IS_4004_EQ_4004(...) \, +#define Z_IS_4005_EQ_4005(...) \, +#define Z_IS_4006_EQ_4006(...) \, +#define Z_IS_4007_EQ_4007(...) \, +#define Z_IS_4008_EQ_4008(...) \, +#define Z_IS_4009_EQ_4009(...) \, +#define Z_IS_4010_EQ_4010(...) \, +#define Z_IS_4011_EQ_4011(...) \, +#define Z_IS_4012_EQ_4012(...) \, +#define Z_IS_4013_EQ_4013(...) \, +#define Z_IS_4014_EQ_4014(...) \, +#define Z_IS_4015_EQ_4015(...) \, +#define Z_IS_4016_EQ_4016(...) \, +#define Z_IS_4017_EQ_4017(...) \, +#define Z_IS_4018_EQ_4018(...) \, +#define Z_IS_4019_EQ_4019(...) \, +#define Z_IS_4020_EQ_4020(...) \, +#define Z_IS_4021_EQ_4021(...) \, +#define Z_IS_4022_EQ_4022(...) \, +#define Z_IS_4023_EQ_4023(...) \, +#define Z_IS_4024_EQ_4024(...) \, +#define Z_IS_4025_EQ_4025(...) \, +#define Z_IS_4026_EQ_4026(...) \, +#define Z_IS_4027_EQ_4027(...) \, +#define Z_IS_4028_EQ_4028(...) \, +#define Z_IS_4029_EQ_4029(...) \, +#define Z_IS_4030_EQ_4030(...) \, +#define Z_IS_4031_EQ_4031(...) \, +#define Z_IS_4032_EQ_4032(...) \, +#define Z_IS_4033_EQ_4033(...) \, +#define Z_IS_4034_EQ_4034(...) \, +#define Z_IS_4035_EQ_4035(...) \, +#define Z_IS_4036_EQ_4036(...) \, +#define Z_IS_4037_EQ_4037(...) \, +#define Z_IS_4038_EQ_4038(...) \, +#define Z_IS_4039_EQ_4039(...) \, +#define Z_IS_4040_EQ_4040(...) \, +#define Z_IS_4041_EQ_4041(...) \, +#define Z_IS_4042_EQ_4042(...) \, +#define Z_IS_4043_EQ_4043(...) \, +#define Z_IS_4044_EQ_4044(...) \, +#define Z_IS_4045_EQ_4045(...) \, +#define Z_IS_4046_EQ_4046(...) \, +#define Z_IS_4047_EQ_4047(...) \, +#define Z_IS_4048_EQ_4048(...) \, +#define Z_IS_4049_EQ_4049(...) \, +#define Z_IS_4050_EQ_4050(...) \, +#define Z_IS_4051_EQ_4051(...) \, +#define Z_IS_4052_EQ_4052(...) \, +#define Z_IS_4053_EQ_4053(...) \, +#define Z_IS_4054_EQ_4054(...) \, +#define Z_IS_4055_EQ_4055(...) \, +#define Z_IS_4056_EQ_4056(...) \, +#define Z_IS_4057_EQ_4057(...) \, +#define Z_IS_4058_EQ_4058(...) \, +#define Z_IS_4059_EQ_4059(...) \, +#define Z_IS_4060_EQ_4060(...) \, +#define Z_IS_4061_EQ_4061(...) \, +#define Z_IS_4062_EQ_4062(...) \, +#define Z_IS_4063_EQ_4063(...) \, +#define Z_IS_4064_EQ_4064(...) \, +#define Z_IS_4065_EQ_4065(...) \, +#define Z_IS_4066_EQ_4066(...) \, +#define Z_IS_4067_EQ_4067(...) \, +#define Z_IS_4068_EQ_4068(...) \, +#define Z_IS_4069_EQ_4069(...) \, +#define Z_IS_4070_EQ_4070(...) \, +#define Z_IS_4071_EQ_4071(...) \, +#define Z_IS_4072_EQ_4072(...) \, +#define Z_IS_4073_EQ_4073(...) \, +#define Z_IS_4074_EQ_4074(...) \, +#define Z_IS_4075_EQ_4075(...) \, +#define Z_IS_4076_EQ_4076(...) \, +#define Z_IS_4077_EQ_4077(...) \, +#define Z_IS_4078_EQ_4078(...) \, +#define Z_IS_4079_EQ_4079(...) \, +#define Z_IS_4080_EQ_4080(...) \, +#define Z_IS_4081_EQ_4081(...) \, +#define Z_IS_4082_EQ_4082(...) \, +#define Z_IS_4083_EQ_4083(...) \, +#define Z_IS_4084_EQ_4084(...) \, +#define Z_IS_4085_EQ_4085(...) \, +#define Z_IS_4086_EQ_4086(...) \, +#define Z_IS_4087_EQ_4087(...) \, +#define Z_IS_4088_EQ_4088(...) \, +#define Z_IS_4089_EQ_4089(...) \, +#define Z_IS_4090_EQ_4090(...) \, +#define Z_IS_4091_EQ_4091(...) \, +#define Z_IS_4092_EQ_4092(...) \, +#define Z_IS_4093_EQ_4093(...) \, +#define Z_IS_4094_EQ_4094(...) \, +#define Z_IS_4095_EQ_4095(...) \, +#define Z_IS_4096_EQ_4096(...) \, + +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ */ diff --git a/include/zephyr/sys/util_internal_util_dec.h b/include/zephyr/sys/util_internal_util_dec.h new file mode 100644 index 00000000000..c66718996dd --- /dev/null +++ b/include/zephyr/sys/util_internal_util_dec.h @@ -0,0 +1,4122 @@ +/* + * Copyright (c) 2011-2014, Wind River Systems, Inc. + * Copyright (c) 2020, Nordic Semiconductor ASA + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @cond INTERNAL_HIDDEN + */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ +#error "This header should not be used directly, please include util_internal.h instead" +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_ +#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_ + +#define Z_UTIL_DEC_0 0 +#define Z_UTIL_DEC_1 0 +#define Z_UTIL_DEC_2 1 +#define Z_UTIL_DEC_3 2 +#define Z_UTIL_DEC_4 3 +#define Z_UTIL_DEC_5 4 +#define Z_UTIL_DEC_6 5 +#define Z_UTIL_DEC_7 6 +#define Z_UTIL_DEC_8 7 +#define Z_UTIL_DEC_9 8 +#define Z_UTIL_DEC_10 9 +#define Z_UTIL_DEC_11 10 +#define Z_UTIL_DEC_12 11 +#define Z_UTIL_DEC_13 12 +#define Z_UTIL_DEC_14 13 +#define Z_UTIL_DEC_15 14 +#define Z_UTIL_DEC_16 15 +#define Z_UTIL_DEC_17 16 +#define Z_UTIL_DEC_18 17 +#define Z_UTIL_DEC_19 18 +#define Z_UTIL_DEC_20 19 +#define Z_UTIL_DEC_21 20 +#define Z_UTIL_DEC_22 21 +#define Z_UTIL_DEC_23 22 +#define Z_UTIL_DEC_24 23 +#define Z_UTIL_DEC_25 24 +#define Z_UTIL_DEC_26 25 +#define Z_UTIL_DEC_27 26 +#define Z_UTIL_DEC_28 27 +#define Z_UTIL_DEC_29 28 +#define Z_UTIL_DEC_30 29 +#define Z_UTIL_DEC_31 30 +#define Z_UTIL_DEC_32 31 +#define Z_UTIL_DEC_33 32 +#define Z_UTIL_DEC_34 33 +#define Z_UTIL_DEC_35 34 +#define Z_UTIL_DEC_36 35 +#define Z_UTIL_DEC_37 36 +#define Z_UTIL_DEC_38 37 +#define Z_UTIL_DEC_39 38 +#define Z_UTIL_DEC_40 39 +#define Z_UTIL_DEC_41 40 +#define Z_UTIL_DEC_42 41 +#define Z_UTIL_DEC_43 42 +#define Z_UTIL_DEC_44 43 +#define Z_UTIL_DEC_45 44 +#define Z_UTIL_DEC_46 45 +#define Z_UTIL_DEC_47 46 +#define Z_UTIL_DEC_48 47 +#define Z_UTIL_DEC_49 48 +#define Z_UTIL_DEC_50 49 +#define Z_UTIL_DEC_51 50 +#define Z_UTIL_DEC_52 51 +#define Z_UTIL_DEC_53 52 +#define Z_UTIL_DEC_54 53 +#define Z_UTIL_DEC_55 54 +#define Z_UTIL_DEC_56 55 +#define Z_UTIL_DEC_57 56 +#define Z_UTIL_DEC_58 57 +#define Z_UTIL_DEC_59 58 +#define Z_UTIL_DEC_60 59 +#define Z_UTIL_DEC_61 60 +#define Z_UTIL_DEC_62 61 +#define Z_UTIL_DEC_63 62 +#define Z_UTIL_DEC_64 63 +#define Z_UTIL_DEC_65 64 +#define Z_UTIL_DEC_66 65 +#define Z_UTIL_DEC_67 66 +#define Z_UTIL_DEC_68 67 +#define Z_UTIL_DEC_69 68 +#define Z_UTIL_DEC_70 69 +#define Z_UTIL_DEC_71 70 +#define Z_UTIL_DEC_72 71 +#define Z_UTIL_DEC_73 72 +#define Z_UTIL_DEC_74 73 +#define Z_UTIL_DEC_75 74 +#define Z_UTIL_DEC_76 75 +#define Z_UTIL_DEC_77 76 +#define Z_UTIL_DEC_78 77 +#define Z_UTIL_DEC_79 78 +#define Z_UTIL_DEC_80 79 +#define Z_UTIL_DEC_81 80 +#define Z_UTIL_DEC_82 81 +#define Z_UTIL_DEC_83 82 +#define Z_UTIL_DEC_84 83 +#define Z_UTIL_DEC_85 84 +#define Z_UTIL_DEC_86 85 +#define Z_UTIL_DEC_87 86 +#define Z_UTIL_DEC_88 87 +#define Z_UTIL_DEC_89 88 +#define Z_UTIL_DEC_90 89 +#define Z_UTIL_DEC_91 90 +#define Z_UTIL_DEC_92 91 +#define Z_UTIL_DEC_93 92 +#define Z_UTIL_DEC_94 93 +#define Z_UTIL_DEC_95 94 +#define Z_UTIL_DEC_96 95 +#define Z_UTIL_DEC_97 96 +#define Z_UTIL_DEC_98 97 +#define Z_UTIL_DEC_99 98 +#define Z_UTIL_DEC_100 99 +#define Z_UTIL_DEC_101 100 +#define Z_UTIL_DEC_102 101 +#define Z_UTIL_DEC_103 102 +#define Z_UTIL_DEC_104 103 +#define Z_UTIL_DEC_105 104 +#define Z_UTIL_DEC_106 105 +#define Z_UTIL_DEC_107 106 +#define Z_UTIL_DEC_108 107 +#define Z_UTIL_DEC_109 108 +#define Z_UTIL_DEC_110 109 +#define Z_UTIL_DEC_111 110 +#define Z_UTIL_DEC_112 111 +#define Z_UTIL_DEC_113 112 +#define Z_UTIL_DEC_114 113 +#define Z_UTIL_DEC_115 114 +#define Z_UTIL_DEC_116 115 +#define Z_UTIL_DEC_117 116 +#define Z_UTIL_DEC_118 117 +#define Z_UTIL_DEC_119 118 +#define Z_UTIL_DEC_120 119 +#define Z_UTIL_DEC_121 120 +#define Z_UTIL_DEC_122 121 +#define Z_UTIL_DEC_123 122 +#define Z_UTIL_DEC_124 123 +#define Z_UTIL_DEC_125 124 +#define Z_UTIL_DEC_126 125 +#define Z_UTIL_DEC_127 126 +#define Z_UTIL_DEC_128 127 +#define Z_UTIL_DEC_129 128 +#define Z_UTIL_DEC_130 129 +#define Z_UTIL_DEC_131 130 +#define Z_UTIL_DEC_132 131 +#define Z_UTIL_DEC_133 132 +#define Z_UTIL_DEC_134 133 +#define Z_UTIL_DEC_135 134 +#define Z_UTIL_DEC_136 135 +#define Z_UTIL_DEC_137 136 +#define Z_UTIL_DEC_138 137 +#define Z_UTIL_DEC_139 138 +#define Z_UTIL_DEC_140 139 +#define Z_UTIL_DEC_141 140 +#define Z_UTIL_DEC_142 141 +#define Z_UTIL_DEC_143 142 +#define Z_UTIL_DEC_144 143 +#define Z_UTIL_DEC_145 144 +#define Z_UTIL_DEC_146 145 +#define Z_UTIL_DEC_147 146 +#define Z_UTIL_DEC_148 147 +#define Z_UTIL_DEC_149 148 +#define Z_UTIL_DEC_150 149 +#define Z_UTIL_DEC_151 150 +#define Z_UTIL_DEC_152 151 +#define Z_UTIL_DEC_153 152 +#define Z_UTIL_DEC_154 153 +#define Z_UTIL_DEC_155 154 +#define Z_UTIL_DEC_156 155 +#define Z_UTIL_DEC_157 156 +#define Z_UTIL_DEC_158 157 +#define Z_UTIL_DEC_159 158 +#define Z_UTIL_DEC_160 159 +#define Z_UTIL_DEC_161 160 +#define Z_UTIL_DEC_162 161 +#define Z_UTIL_DEC_163 162 +#define Z_UTIL_DEC_164 163 +#define Z_UTIL_DEC_165 164 +#define Z_UTIL_DEC_166 165 +#define Z_UTIL_DEC_167 166 +#define Z_UTIL_DEC_168 167 +#define Z_UTIL_DEC_169 168 +#define Z_UTIL_DEC_170 169 +#define Z_UTIL_DEC_171 170 +#define Z_UTIL_DEC_172 171 +#define Z_UTIL_DEC_173 172 +#define Z_UTIL_DEC_174 173 +#define Z_UTIL_DEC_175 174 +#define Z_UTIL_DEC_176 175 +#define Z_UTIL_DEC_177 176 +#define Z_UTIL_DEC_178 177 +#define Z_UTIL_DEC_179 178 +#define Z_UTIL_DEC_180 179 +#define Z_UTIL_DEC_181 180 +#define Z_UTIL_DEC_182 181 +#define Z_UTIL_DEC_183 182 +#define Z_UTIL_DEC_184 183 +#define Z_UTIL_DEC_185 184 +#define Z_UTIL_DEC_186 185 +#define Z_UTIL_DEC_187 186 +#define Z_UTIL_DEC_188 187 +#define Z_UTIL_DEC_189 188 +#define Z_UTIL_DEC_190 189 +#define Z_UTIL_DEC_191 190 +#define Z_UTIL_DEC_192 191 +#define Z_UTIL_DEC_193 192 +#define Z_UTIL_DEC_194 193 +#define Z_UTIL_DEC_195 194 +#define Z_UTIL_DEC_196 195 +#define Z_UTIL_DEC_197 196 +#define Z_UTIL_DEC_198 197 +#define Z_UTIL_DEC_199 198 +#define Z_UTIL_DEC_200 199 +#define Z_UTIL_DEC_201 200 +#define Z_UTIL_DEC_202 201 +#define Z_UTIL_DEC_203 202 +#define Z_UTIL_DEC_204 203 +#define Z_UTIL_DEC_205 204 +#define Z_UTIL_DEC_206 205 +#define Z_UTIL_DEC_207 206 +#define Z_UTIL_DEC_208 207 +#define Z_UTIL_DEC_209 208 +#define Z_UTIL_DEC_210 209 +#define Z_UTIL_DEC_211 210 +#define Z_UTIL_DEC_212 211 +#define Z_UTIL_DEC_213 212 +#define Z_UTIL_DEC_214 213 +#define Z_UTIL_DEC_215 214 +#define Z_UTIL_DEC_216 215 +#define Z_UTIL_DEC_217 216 +#define Z_UTIL_DEC_218 217 +#define Z_UTIL_DEC_219 218 +#define Z_UTIL_DEC_220 219 +#define Z_UTIL_DEC_221 220 +#define Z_UTIL_DEC_222 221 +#define Z_UTIL_DEC_223 222 +#define Z_UTIL_DEC_224 223 +#define Z_UTIL_DEC_225 224 +#define Z_UTIL_DEC_226 225 +#define Z_UTIL_DEC_227 226 +#define Z_UTIL_DEC_228 227 +#define Z_UTIL_DEC_229 228 +#define Z_UTIL_DEC_230 229 +#define Z_UTIL_DEC_231 230 +#define Z_UTIL_DEC_232 231 +#define Z_UTIL_DEC_233 232 +#define Z_UTIL_DEC_234 233 +#define Z_UTIL_DEC_235 234 +#define Z_UTIL_DEC_236 235 +#define Z_UTIL_DEC_237 236 +#define Z_UTIL_DEC_238 237 +#define Z_UTIL_DEC_239 238 +#define Z_UTIL_DEC_240 239 +#define Z_UTIL_DEC_241 240 +#define Z_UTIL_DEC_242 241 +#define Z_UTIL_DEC_243 242 +#define Z_UTIL_DEC_244 243 +#define Z_UTIL_DEC_245 244 +#define Z_UTIL_DEC_246 245 +#define Z_UTIL_DEC_247 246 +#define Z_UTIL_DEC_248 247 +#define Z_UTIL_DEC_249 248 +#define Z_UTIL_DEC_250 249 +#define Z_UTIL_DEC_251 250 +#define Z_UTIL_DEC_252 251 +#define Z_UTIL_DEC_253 252 +#define Z_UTIL_DEC_254 253 +#define Z_UTIL_DEC_255 254 +#define Z_UTIL_DEC_256 255 +#define Z_UTIL_DEC_257 256 +#define Z_UTIL_DEC_258 257 +#define Z_UTIL_DEC_259 258 +#define Z_UTIL_DEC_260 259 +#define Z_UTIL_DEC_261 260 +#define Z_UTIL_DEC_262 261 +#define Z_UTIL_DEC_263 262 +#define Z_UTIL_DEC_264 263 +#define Z_UTIL_DEC_265 264 +#define Z_UTIL_DEC_266 265 +#define Z_UTIL_DEC_267 266 +#define Z_UTIL_DEC_268 267 +#define Z_UTIL_DEC_269 268 +#define Z_UTIL_DEC_270 269 +#define Z_UTIL_DEC_271 270 +#define Z_UTIL_DEC_272 271 +#define Z_UTIL_DEC_273 272 +#define Z_UTIL_DEC_274 273 +#define Z_UTIL_DEC_275 274 +#define Z_UTIL_DEC_276 275 +#define Z_UTIL_DEC_277 276 +#define Z_UTIL_DEC_278 277 +#define Z_UTIL_DEC_279 278 +#define Z_UTIL_DEC_280 279 +#define Z_UTIL_DEC_281 280 +#define Z_UTIL_DEC_282 281 +#define Z_UTIL_DEC_283 282 +#define Z_UTIL_DEC_284 283 +#define Z_UTIL_DEC_285 284 +#define Z_UTIL_DEC_286 285 +#define Z_UTIL_DEC_287 286 +#define Z_UTIL_DEC_288 287 +#define Z_UTIL_DEC_289 288 +#define Z_UTIL_DEC_290 289 +#define Z_UTIL_DEC_291 290 +#define Z_UTIL_DEC_292 291 +#define Z_UTIL_DEC_293 292 +#define Z_UTIL_DEC_294 293 +#define Z_UTIL_DEC_295 294 +#define Z_UTIL_DEC_296 295 +#define Z_UTIL_DEC_297 296 +#define Z_UTIL_DEC_298 297 +#define Z_UTIL_DEC_299 298 +#define Z_UTIL_DEC_300 299 +#define Z_UTIL_DEC_301 300 +#define Z_UTIL_DEC_302 301 +#define Z_UTIL_DEC_303 302 +#define Z_UTIL_DEC_304 303 +#define Z_UTIL_DEC_305 304 +#define Z_UTIL_DEC_306 305 +#define Z_UTIL_DEC_307 306 +#define Z_UTIL_DEC_308 307 +#define Z_UTIL_DEC_309 308 +#define Z_UTIL_DEC_310 309 +#define Z_UTIL_DEC_311 310 +#define Z_UTIL_DEC_312 311 +#define Z_UTIL_DEC_313 312 +#define Z_UTIL_DEC_314 313 +#define Z_UTIL_DEC_315 314 +#define Z_UTIL_DEC_316 315 +#define Z_UTIL_DEC_317 316 +#define Z_UTIL_DEC_318 317 +#define Z_UTIL_DEC_319 318 +#define Z_UTIL_DEC_320 319 +#define Z_UTIL_DEC_321 320 +#define Z_UTIL_DEC_322 321 +#define Z_UTIL_DEC_323 322 +#define Z_UTIL_DEC_324 323 +#define Z_UTIL_DEC_325 324 +#define Z_UTIL_DEC_326 325 +#define Z_UTIL_DEC_327 326 +#define Z_UTIL_DEC_328 327 +#define Z_UTIL_DEC_329 328 +#define Z_UTIL_DEC_330 329 +#define Z_UTIL_DEC_331 330 +#define Z_UTIL_DEC_332 331 +#define Z_UTIL_DEC_333 332 +#define Z_UTIL_DEC_334 333 +#define Z_UTIL_DEC_335 334 +#define Z_UTIL_DEC_336 335 +#define Z_UTIL_DEC_337 336 +#define Z_UTIL_DEC_338 337 +#define Z_UTIL_DEC_339 338 +#define Z_UTIL_DEC_340 339 +#define Z_UTIL_DEC_341 340 +#define Z_UTIL_DEC_342 341 +#define Z_UTIL_DEC_343 342 +#define Z_UTIL_DEC_344 343 +#define Z_UTIL_DEC_345 344 +#define Z_UTIL_DEC_346 345 +#define Z_UTIL_DEC_347 346 +#define Z_UTIL_DEC_348 347 +#define Z_UTIL_DEC_349 348 +#define Z_UTIL_DEC_350 349 +#define Z_UTIL_DEC_351 350 +#define Z_UTIL_DEC_352 351 +#define Z_UTIL_DEC_353 352 +#define Z_UTIL_DEC_354 353 +#define Z_UTIL_DEC_355 354 +#define Z_UTIL_DEC_356 355 +#define Z_UTIL_DEC_357 356 +#define Z_UTIL_DEC_358 357 +#define Z_UTIL_DEC_359 358 +#define Z_UTIL_DEC_360 359 +#define Z_UTIL_DEC_361 360 +#define Z_UTIL_DEC_362 361 +#define Z_UTIL_DEC_363 362 +#define Z_UTIL_DEC_364 363 +#define Z_UTIL_DEC_365 364 +#define Z_UTIL_DEC_366 365 +#define Z_UTIL_DEC_367 366 +#define Z_UTIL_DEC_368 367 +#define Z_UTIL_DEC_369 368 +#define Z_UTIL_DEC_370 369 +#define Z_UTIL_DEC_371 370 +#define Z_UTIL_DEC_372 371 +#define Z_UTIL_DEC_373 372 +#define Z_UTIL_DEC_374 373 +#define Z_UTIL_DEC_375 374 +#define Z_UTIL_DEC_376 375 +#define Z_UTIL_DEC_377 376 +#define Z_UTIL_DEC_378 377 +#define Z_UTIL_DEC_379 378 +#define Z_UTIL_DEC_380 379 +#define Z_UTIL_DEC_381 380 +#define Z_UTIL_DEC_382 381 +#define Z_UTIL_DEC_383 382 +#define Z_UTIL_DEC_384 383 +#define Z_UTIL_DEC_385 384 +#define Z_UTIL_DEC_386 385 +#define Z_UTIL_DEC_387 386 +#define Z_UTIL_DEC_388 387 +#define Z_UTIL_DEC_389 388 +#define Z_UTIL_DEC_390 389 +#define Z_UTIL_DEC_391 390 +#define Z_UTIL_DEC_392 391 +#define Z_UTIL_DEC_393 392 +#define Z_UTIL_DEC_394 393 +#define Z_UTIL_DEC_395 394 +#define Z_UTIL_DEC_396 395 +#define Z_UTIL_DEC_397 396 +#define Z_UTIL_DEC_398 397 +#define Z_UTIL_DEC_399 398 +#define Z_UTIL_DEC_400 399 +#define Z_UTIL_DEC_401 400 +#define Z_UTIL_DEC_402 401 +#define Z_UTIL_DEC_403 402 +#define Z_UTIL_DEC_404 403 +#define Z_UTIL_DEC_405 404 +#define Z_UTIL_DEC_406 405 +#define Z_UTIL_DEC_407 406 +#define Z_UTIL_DEC_408 407 +#define Z_UTIL_DEC_409 408 +#define Z_UTIL_DEC_410 409 +#define Z_UTIL_DEC_411 410 +#define Z_UTIL_DEC_412 411 +#define Z_UTIL_DEC_413 412 +#define Z_UTIL_DEC_414 413 +#define Z_UTIL_DEC_415 414 +#define Z_UTIL_DEC_416 415 +#define Z_UTIL_DEC_417 416 +#define Z_UTIL_DEC_418 417 +#define Z_UTIL_DEC_419 418 +#define Z_UTIL_DEC_420 419 +#define Z_UTIL_DEC_421 420 +#define Z_UTIL_DEC_422 421 +#define Z_UTIL_DEC_423 422 +#define Z_UTIL_DEC_424 423 +#define Z_UTIL_DEC_425 424 +#define Z_UTIL_DEC_426 425 +#define Z_UTIL_DEC_427 426 +#define Z_UTIL_DEC_428 427 +#define Z_UTIL_DEC_429 428 +#define Z_UTIL_DEC_430 429 +#define Z_UTIL_DEC_431 430 +#define Z_UTIL_DEC_432 431 +#define Z_UTIL_DEC_433 432 +#define Z_UTIL_DEC_434 433 +#define Z_UTIL_DEC_435 434 +#define Z_UTIL_DEC_436 435 +#define Z_UTIL_DEC_437 436 +#define Z_UTIL_DEC_438 437 +#define Z_UTIL_DEC_439 438 +#define Z_UTIL_DEC_440 439 +#define Z_UTIL_DEC_441 440 +#define Z_UTIL_DEC_442 441 +#define Z_UTIL_DEC_443 442 +#define Z_UTIL_DEC_444 443 +#define Z_UTIL_DEC_445 444 +#define Z_UTIL_DEC_446 445 +#define Z_UTIL_DEC_447 446 +#define Z_UTIL_DEC_448 447 +#define Z_UTIL_DEC_449 448 +#define Z_UTIL_DEC_450 449 +#define Z_UTIL_DEC_451 450 +#define Z_UTIL_DEC_452 451 +#define Z_UTIL_DEC_453 452 +#define Z_UTIL_DEC_454 453 +#define Z_UTIL_DEC_455 454 +#define Z_UTIL_DEC_456 455 +#define Z_UTIL_DEC_457 456 +#define Z_UTIL_DEC_458 457 +#define Z_UTIL_DEC_459 458 +#define Z_UTIL_DEC_460 459 +#define Z_UTIL_DEC_461 460 +#define Z_UTIL_DEC_462 461 +#define Z_UTIL_DEC_463 462 +#define Z_UTIL_DEC_464 463 +#define Z_UTIL_DEC_465 464 +#define Z_UTIL_DEC_466 465 +#define Z_UTIL_DEC_467 466 +#define Z_UTIL_DEC_468 467 +#define Z_UTIL_DEC_469 468 +#define Z_UTIL_DEC_470 469 +#define Z_UTIL_DEC_471 470 +#define Z_UTIL_DEC_472 471 +#define Z_UTIL_DEC_473 472 +#define Z_UTIL_DEC_474 473 +#define Z_UTIL_DEC_475 474 +#define Z_UTIL_DEC_476 475 +#define Z_UTIL_DEC_477 476 +#define Z_UTIL_DEC_478 477 +#define Z_UTIL_DEC_479 478 +#define Z_UTIL_DEC_480 479 +#define Z_UTIL_DEC_481 480 +#define Z_UTIL_DEC_482 481 +#define Z_UTIL_DEC_483 482 +#define Z_UTIL_DEC_484 483 +#define Z_UTIL_DEC_485 484 +#define Z_UTIL_DEC_486 485 +#define Z_UTIL_DEC_487 486 +#define Z_UTIL_DEC_488 487 +#define Z_UTIL_DEC_489 488 +#define Z_UTIL_DEC_490 489 +#define Z_UTIL_DEC_491 490 +#define Z_UTIL_DEC_492 491 +#define Z_UTIL_DEC_493 492 +#define Z_UTIL_DEC_494 493 +#define Z_UTIL_DEC_495 494 +#define Z_UTIL_DEC_496 495 +#define Z_UTIL_DEC_497 496 +#define Z_UTIL_DEC_498 497 +#define Z_UTIL_DEC_499 498 +#define Z_UTIL_DEC_500 499 +#define Z_UTIL_DEC_501 500 +#define Z_UTIL_DEC_502 501 +#define Z_UTIL_DEC_503 502 +#define Z_UTIL_DEC_504 503 +#define Z_UTIL_DEC_505 504 +#define Z_UTIL_DEC_506 505 +#define Z_UTIL_DEC_507 506 +#define Z_UTIL_DEC_508 507 +#define Z_UTIL_DEC_509 508 +#define Z_UTIL_DEC_510 509 +#define Z_UTIL_DEC_511 510 +#define Z_UTIL_DEC_512 511 +#define Z_UTIL_DEC_513 512 +#define Z_UTIL_DEC_514 513 +#define Z_UTIL_DEC_515 514 +#define Z_UTIL_DEC_516 515 +#define Z_UTIL_DEC_517 516 +#define Z_UTIL_DEC_518 517 +#define Z_UTIL_DEC_519 518 +#define Z_UTIL_DEC_520 519 +#define Z_UTIL_DEC_521 520 +#define Z_UTIL_DEC_522 521 +#define Z_UTIL_DEC_523 522 +#define Z_UTIL_DEC_524 523 +#define Z_UTIL_DEC_525 524 +#define Z_UTIL_DEC_526 525 +#define Z_UTIL_DEC_527 526 +#define Z_UTIL_DEC_528 527 +#define Z_UTIL_DEC_529 528 +#define Z_UTIL_DEC_530 529 +#define Z_UTIL_DEC_531 530 +#define Z_UTIL_DEC_532 531 +#define Z_UTIL_DEC_533 532 +#define Z_UTIL_DEC_534 533 +#define Z_UTIL_DEC_535 534 +#define Z_UTIL_DEC_536 535 +#define Z_UTIL_DEC_537 536 +#define Z_UTIL_DEC_538 537 +#define Z_UTIL_DEC_539 538 +#define Z_UTIL_DEC_540 539 +#define Z_UTIL_DEC_541 540 +#define Z_UTIL_DEC_542 541 +#define Z_UTIL_DEC_543 542 +#define Z_UTIL_DEC_544 543 +#define Z_UTIL_DEC_545 544 +#define Z_UTIL_DEC_546 545 +#define Z_UTIL_DEC_547 546 +#define Z_UTIL_DEC_548 547 +#define Z_UTIL_DEC_549 548 +#define Z_UTIL_DEC_550 549 +#define Z_UTIL_DEC_551 550 +#define Z_UTIL_DEC_552 551 +#define Z_UTIL_DEC_553 552 +#define Z_UTIL_DEC_554 553 +#define Z_UTIL_DEC_555 554 +#define Z_UTIL_DEC_556 555 +#define Z_UTIL_DEC_557 556 +#define Z_UTIL_DEC_558 557 +#define Z_UTIL_DEC_559 558 +#define Z_UTIL_DEC_560 559 +#define Z_UTIL_DEC_561 560 +#define Z_UTIL_DEC_562 561 +#define Z_UTIL_DEC_563 562 +#define Z_UTIL_DEC_564 563 +#define Z_UTIL_DEC_565 564 +#define Z_UTIL_DEC_566 565 +#define Z_UTIL_DEC_567 566 +#define Z_UTIL_DEC_568 567 +#define Z_UTIL_DEC_569 568 +#define Z_UTIL_DEC_570 569 +#define Z_UTIL_DEC_571 570 +#define Z_UTIL_DEC_572 571 +#define Z_UTIL_DEC_573 572 +#define Z_UTIL_DEC_574 573 +#define Z_UTIL_DEC_575 574 +#define Z_UTIL_DEC_576 575 +#define Z_UTIL_DEC_577 576 +#define Z_UTIL_DEC_578 577 +#define Z_UTIL_DEC_579 578 +#define Z_UTIL_DEC_580 579 +#define Z_UTIL_DEC_581 580 +#define Z_UTIL_DEC_582 581 +#define Z_UTIL_DEC_583 582 +#define Z_UTIL_DEC_584 583 +#define Z_UTIL_DEC_585 584 +#define Z_UTIL_DEC_586 585 +#define Z_UTIL_DEC_587 586 +#define Z_UTIL_DEC_588 587 +#define Z_UTIL_DEC_589 588 +#define Z_UTIL_DEC_590 589 +#define Z_UTIL_DEC_591 590 +#define Z_UTIL_DEC_592 591 +#define Z_UTIL_DEC_593 592 +#define Z_UTIL_DEC_594 593 +#define Z_UTIL_DEC_595 594 +#define Z_UTIL_DEC_596 595 +#define Z_UTIL_DEC_597 596 +#define Z_UTIL_DEC_598 597 +#define Z_UTIL_DEC_599 598 +#define Z_UTIL_DEC_600 599 +#define Z_UTIL_DEC_601 600 +#define Z_UTIL_DEC_602 601 +#define Z_UTIL_DEC_603 602 +#define Z_UTIL_DEC_604 603 +#define Z_UTIL_DEC_605 604 +#define Z_UTIL_DEC_606 605 +#define Z_UTIL_DEC_607 606 +#define Z_UTIL_DEC_608 607 +#define Z_UTIL_DEC_609 608 +#define Z_UTIL_DEC_610 609 +#define Z_UTIL_DEC_611 610 +#define Z_UTIL_DEC_612 611 +#define Z_UTIL_DEC_613 612 +#define Z_UTIL_DEC_614 613 +#define Z_UTIL_DEC_615 614 +#define Z_UTIL_DEC_616 615 +#define Z_UTIL_DEC_617 616 +#define Z_UTIL_DEC_618 617 +#define Z_UTIL_DEC_619 618 +#define Z_UTIL_DEC_620 619 +#define Z_UTIL_DEC_621 620 +#define Z_UTIL_DEC_622 621 +#define Z_UTIL_DEC_623 622 +#define Z_UTIL_DEC_624 623 +#define Z_UTIL_DEC_625 624 +#define Z_UTIL_DEC_626 625 +#define Z_UTIL_DEC_627 626 +#define Z_UTIL_DEC_628 627 +#define Z_UTIL_DEC_629 628 +#define Z_UTIL_DEC_630 629 +#define Z_UTIL_DEC_631 630 +#define Z_UTIL_DEC_632 631 +#define Z_UTIL_DEC_633 632 +#define Z_UTIL_DEC_634 633 +#define Z_UTIL_DEC_635 634 +#define Z_UTIL_DEC_636 635 +#define Z_UTIL_DEC_637 636 +#define Z_UTIL_DEC_638 637 +#define Z_UTIL_DEC_639 638 +#define Z_UTIL_DEC_640 639 +#define Z_UTIL_DEC_641 640 +#define Z_UTIL_DEC_642 641 +#define Z_UTIL_DEC_643 642 +#define Z_UTIL_DEC_644 643 +#define Z_UTIL_DEC_645 644 +#define Z_UTIL_DEC_646 645 +#define Z_UTIL_DEC_647 646 +#define Z_UTIL_DEC_648 647 +#define Z_UTIL_DEC_649 648 +#define Z_UTIL_DEC_650 649 +#define Z_UTIL_DEC_651 650 +#define Z_UTIL_DEC_652 651 +#define Z_UTIL_DEC_653 652 +#define Z_UTIL_DEC_654 653 +#define Z_UTIL_DEC_655 654 +#define Z_UTIL_DEC_656 655 +#define Z_UTIL_DEC_657 656 +#define Z_UTIL_DEC_658 657 +#define Z_UTIL_DEC_659 658 +#define Z_UTIL_DEC_660 659 +#define Z_UTIL_DEC_661 660 +#define Z_UTIL_DEC_662 661 +#define Z_UTIL_DEC_663 662 +#define Z_UTIL_DEC_664 663 +#define Z_UTIL_DEC_665 664 +#define Z_UTIL_DEC_666 665 +#define Z_UTIL_DEC_667 666 +#define Z_UTIL_DEC_668 667 +#define Z_UTIL_DEC_669 668 +#define Z_UTIL_DEC_670 669 +#define Z_UTIL_DEC_671 670 +#define Z_UTIL_DEC_672 671 +#define Z_UTIL_DEC_673 672 +#define Z_UTIL_DEC_674 673 +#define Z_UTIL_DEC_675 674 +#define Z_UTIL_DEC_676 675 +#define Z_UTIL_DEC_677 676 +#define Z_UTIL_DEC_678 677 +#define Z_UTIL_DEC_679 678 +#define Z_UTIL_DEC_680 679 +#define Z_UTIL_DEC_681 680 +#define Z_UTIL_DEC_682 681 +#define Z_UTIL_DEC_683 682 +#define Z_UTIL_DEC_684 683 +#define Z_UTIL_DEC_685 684 +#define Z_UTIL_DEC_686 685 +#define Z_UTIL_DEC_687 686 +#define Z_UTIL_DEC_688 687 +#define Z_UTIL_DEC_689 688 +#define Z_UTIL_DEC_690 689 +#define Z_UTIL_DEC_691 690 +#define Z_UTIL_DEC_692 691 +#define Z_UTIL_DEC_693 692 +#define Z_UTIL_DEC_694 693 +#define Z_UTIL_DEC_695 694 +#define Z_UTIL_DEC_696 695 +#define Z_UTIL_DEC_697 696 +#define Z_UTIL_DEC_698 697 +#define Z_UTIL_DEC_699 698 +#define Z_UTIL_DEC_700 699 +#define Z_UTIL_DEC_701 700 +#define Z_UTIL_DEC_702 701 +#define Z_UTIL_DEC_703 702 +#define Z_UTIL_DEC_704 703 +#define Z_UTIL_DEC_705 704 +#define Z_UTIL_DEC_706 705 +#define Z_UTIL_DEC_707 706 +#define Z_UTIL_DEC_708 707 +#define Z_UTIL_DEC_709 708 +#define Z_UTIL_DEC_710 709 +#define Z_UTIL_DEC_711 710 +#define Z_UTIL_DEC_712 711 +#define Z_UTIL_DEC_713 712 +#define Z_UTIL_DEC_714 713 +#define Z_UTIL_DEC_715 714 +#define Z_UTIL_DEC_716 715 +#define Z_UTIL_DEC_717 716 +#define Z_UTIL_DEC_718 717 +#define Z_UTIL_DEC_719 718 +#define Z_UTIL_DEC_720 719 +#define Z_UTIL_DEC_721 720 +#define Z_UTIL_DEC_722 721 +#define Z_UTIL_DEC_723 722 +#define Z_UTIL_DEC_724 723 +#define Z_UTIL_DEC_725 724 +#define Z_UTIL_DEC_726 725 +#define Z_UTIL_DEC_727 726 +#define Z_UTIL_DEC_728 727 +#define Z_UTIL_DEC_729 728 +#define Z_UTIL_DEC_730 729 +#define Z_UTIL_DEC_731 730 +#define Z_UTIL_DEC_732 731 +#define Z_UTIL_DEC_733 732 +#define Z_UTIL_DEC_734 733 +#define Z_UTIL_DEC_735 734 +#define Z_UTIL_DEC_736 735 +#define Z_UTIL_DEC_737 736 +#define Z_UTIL_DEC_738 737 +#define Z_UTIL_DEC_739 738 +#define Z_UTIL_DEC_740 739 +#define Z_UTIL_DEC_741 740 +#define Z_UTIL_DEC_742 741 +#define Z_UTIL_DEC_743 742 +#define Z_UTIL_DEC_744 743 +#define Z_UTIL_DEC_745 744 +#define Z_UTIL_DEC_746 745 +#define Z_UTIL_DEC_747 746 +#define Z_UTIL_DEC_748 747 +#define Z_UTIL_DEC_749 748 +#define Z_UTIL_DEC_750 749 +#define Z_UTIL_DEC_751 750 +#define Z_UTIL_DEC_752 751 +#define Z_UTIL_DEC_753 752 +#define Z_UTIL_DEC_754 753 +#define Z_UTIL_DEC_755 754 +#define Z_UTIL_DEC_756 755 +#define Z_UTIL_DEC_757 756 +#define Z_UTIL_DEC_758 757 +#define Z_UTIL_DEC_759 758 +#define Z_UTIL_DEC_760 759 +#define Z_UTIL_DEC_761 760 +#define Z_UTIL_DEC_762 761 +#define Z_UTIL_DEC_763 762 +#define Z_UTIL_DEC_764 763 +#define Z_UTIL_DEC_765 764 +#define Z_UTIL_DEC_766 765 +#define Z_UTIL_DEC_767 766 +#define Z_UTIL_DEC_768 767 +#define Z_UTIL_DEC_769 768 +#define Z_UTIL_DEC_770 769 +#define Z_UTIL_DEC_771 770 +#define Z_UTIL_DEC_772 771 +#define Z_UTIL_DEC_773 772 +#define Z_UTIL_DEC_774 773 +#define Z_UTIL_DEC_775 774 +#define Z_UTIL_DEC_776 775 +#define Z_UTIL_DEC_777 776 +#define Z_UTIL_DEC_778 777 +#define Z_UTIL_DEC_779 778 +#define Z_UTIL_DEC_780 779 +#define Z_UTIL_DEC_781 780 +#define Z_UTIL_DEC_782 781 +#define Z_UTIL_DEC_783 782 +#define Z_UTIL_DEC_784 783 +#define Z_UTIL_DEC_785 784 +#define Z_UTIL_DEC_786 785 +#define Z_UTIL_DEC_787 786 +#define Z_UTIL_DEC_788 787 +#define Z_UTIL_DEC_789 788 +#define Z_UTIL_DEC_790 789 +#define Z_UTIL_DEC_791 790 +#define Z_UTIL_DEC_792 791 +#define Z_UTIL_DEC_793 792 +#define Z_UTIL_DEC_794 793 +#define Z_UTIL_DEC_795 794 +#define Z_UTIL_DEC_796 795 +#define Z_UTIL_DEC_797 796 +#define Z_UTIL_DEC_798 797 +#define Z_UTIL_DEC_799 798 +#define Z_UTIL_DEC_800 799 +#define Z_UTIL_DEC_801 800 +#define Z_UTIL_DEC_802 801 +#define Z_UTIL_DEC_803 802 +#define Z_UTIL_DEC_804 803 +#define Z_UTIL_DEC_805 804 +#define Z_UTIL_DEC_806 805 +#define Z_UTIL_DEC_807 806 +#define Z_UTIL_DEC_808 807 +#define Z_UTIL_DEC_809 808 +#define Z_UTIL_DEC_810 809 +#define Z_UTIL_DEC_811 810 +#define Z_UTIL_DEC_812 811 +#define Z_UTIL_DEC_813 812 +#define Z_UTIL_DEC_814 813 +#define Z_UTIL_DEC_815 814 +#define Z_UTIL_DEC_816 815 +#define Z_UTIL_DEC_817 816 +#define Z_UTIL_DEC_818 817 +#define Z_UTIL_DEC_819 818 +#define Z_UTIL_DEC_820 819 +#define Z_UTIL_DEC_821 820 +#define Z_UTIL_DEC_822 821 +#define Z_UTIL_DEC_823 822 +#define Z_UTIL_DEC_824 823 +#define Z_UTIL_DEC_825 824 +#define Z_UTIL_DEC_826 825 +#define Z_UTIL_DEC_827 826 +#define Z_UTIL_DEC_828 827 +#define Z_UTIL_DEC_829 828 +#define Z_UTIL_DEC_830 829 +#define Z_UTIL_DEC_831 830 +#define Z_UTIL_DEC_832 831 +#define Z_UTIL_DEC_833 832 +#define Z_UTIL_DEC_834 833 +#define Z_UTIL_DEC_835 834 +#define Z_UTIL_DEC_836 835 +#define Z_UTIL_DEC_837 836 +#define Z_UTIL_DEC_838 837 +#define Z_UTIL_DEC_839 838 +#define Z_UTIL_DEC_840 839 +#define Z_UTIL_DEC_841 840 +#define Z_UTIL_DEC_842 841 +#define Z_UTIL_DEC_843 842 +#define Z_UTIL_DEC_844 843 +#define Z_UTIL_DEC_845 844 +#define Z_UTIL_DEC_846 845 +#define Z_UTIL_DEC_847 846 +#define Z_UTIL_DEC_848 847 +#define Z_UTIL_DEC_849 848 +#define Z_UTIL_DEC_850 849 +#define Z_UTIL_DEC_851 850 +#define Z_UTIL_DEC_852 851 +#define Z_UTIL_DEC_853 852 +#define Z_UTIL_DEC_854 853 +#define Z_UTIL_DEC_855 854 +#define Z_UTIL_DEC_856 855 +#define Z_UTIL_DEC_857 856 +#define Z_UTIL_DEC_858 857 +#define Z_UTIL_DEC_859 858 +#define Z_UTIL_DEC_860 859 +#define Z_UTIL_DEC_861 860 +#define Z_UTIL_DEC_862 861 +#define Z_UTIL_DEC_863 862 +#define Z_UTIL_DEC_864 863 +#define Z_UTIL_DEC_865 864 +#define Z_UTIL_DEC_866 865 +#define Z_UTIL_DEC_867 866 +#define Z_UTIL_DEC_868 867 +#define Z_UTIL_DEC_869 868 +#define Z_UTIL_DEC_870 869 +#define Z_UTIL_DEC_871 870 +#define Z_UTIL_DEC_872 871 +#define Z_UTIL_DEC_873 872 +#define Z_UTIL_DEC_874 873 +#define Z_UTIL_DEC_875 874 +#define Z_UTIL_DEC_876 875 +#define Z_UTIL_DEC_877 876 +#define Z_UTIL_DEC_878 877 +#define Z_UTIL_DEC_879 878 +#define Z_UTIL_DEC_880 879 +#define Z_UTIL_DEC_881 880 +#define Z_UTIL_DEC_882 881 +#define Z_UTIL_DEC_883 882 +#define Z_UTIL_DEC_884 883 +#define Z_UTIL_DEC_885 884 +#define Z_UTIL_DEC_886 885 +#define Z_UTIL_DEC_887 886 +#define Z_UTIL_DEC_888 887 +#define Z_UTIL_DEC_889 888 +#define Z_UTIL_DEC_890 889 +#define Z_UTIL_DEC_891 890 +#define Z_UTIL_DEC_892 891 +#define Z_UTIL_DEC_893 892 +#define Z_UTIL_DEC_894 893 +#define Z_UTIL_DEC_895 894 +#define Z_UTIL_DEC_896 895 +#define Z_UTIL_DEC_897 896 +#define Z_UTIL_DEC_898 897 +#define Z_UTIL_DEC_899 898 +#define Z_UTIL_DEC_900 899 +#define Z_UTIL_DEC_901 900 +#define Z_UTIL_DEC_902 901 +#define Z_UTIL_DEC_903 902 +#define Z_UTIL_DEC_904 903 +#define Z_UTIL_DEC_905 904 +#define Z_UTIL_DEC_906 905 +#define Z_UTIL_DEC_907 906 +#define Z_UTIL_DEC_908 907 +#define Z_UTIL_DEC_909 908 +#define Z_UTIL_DEC_910 909 +#define Z_UTIL_DEC_911 910 +#define Z_UTIL_DEC_912 911 +#define Z_UTIL_DEC_913 912 +#define Z_UTIL_DEC_914 913 +#define Z_UTIL_DEC_915 914 +#define Z_UTIL_DEC_916 915 +#define Z_UTIL_DEC_917 916 +#define Z_UTIL_DEC_918 917 +#define Z_UTIL_DEC_919 918 +#define Z_UTIL_DEC_920 919 +#define Z_UTIL_DEC_921 920 +#define Z_UTIL_DEC_922 921 +#define Z_UTIL_DEC_923 922 +#define Z_UTIL_DEC_924 923 +#define Z_UTIL_DEC_925 924 +#define Z_UTIL_DEC_926 925 +#define Z_UTIL_DEC_927 926 +#define Z_UTIL_DEC_928 927 +#define Z_UTIL_DEC_929 928 +#define Z_UTIL_DEC_930 929 +#define Z_UTIL_DEC_931 930 +#define Z_UTIL_DEC_932 931 +#define Z_UTIL_DEC_933 932 +#define Z_UTIL_DEC_934 933 +#define Z_UTIL_DEC_935 934 +#define Z_UTIL_DEC_936 935 +#define Z_UTIL_DEC_937 936 +#define Z_UTIL_DEC_938 937 +#define Z_UTIL_DEC_939 938 +#define Z_UTIL_DEC_940 939 +#define Z_UTIL_DEC_941 940 +#define Z_UTIL_DEC_942 941 +#define Z_UTIL_DEC_943 942 +#define Z_UTIL_DEC_944 943 +#define Z_UTIL_DEC_945 944 +#define Z_UTIL_DEC_946 945 +#define Z_UTIL_DEC_947 946 +#define Z_UTIL_DEC_948 947 +#define Z_UTIL_DEC_949 948 +#define Z_UTIL_DEC_950 949 +#define Z_UTIL_DEC_951 950 +#define Z_UTIL_DEC_952 951 +#define Z_UTIL_DEC_953 952 +#define Z_UTIL_DEC_954 953 +#define Z_UTIL_DEC_955 954 +#define Z_UTIL_DEC_956 955 +#define Z_UTIL_DEC_957 956 +#define Z_UTIL_DEC_958 957 +#define Z_UTIL_DEC_959 958 +#define Z_UTIL_DEC_960 959 +#define Z_UTIL_DEC_961 960 +#define Z_UTIL_DEC_962 961 +#define Z_UTIL_DEC_963 962 +#define Z_UTIL_DEC_964 963 +#define Z_UTIL_DEC_965 964 +#define Z_UTIL_DEC_966 965 +#define Z_UTIL_DEC_967 966 +#define Z_UTIL_DEC_968 967 +#define Z_UTIL_DEC_969 968 +#define Z_UTIL_DEC_970 969 +#define Z_UTIL_DEC_971 970 +#define Z_UTIL_DEC_972 971 +#define Z_UTIL_DEC_973 972 +#define Z_UTIL_DEC_974 973 +#define Z_UTIL_DEC_975 974 +#define Z_UTIL_DEC_976 975 +#define Z_UTIL_DEC_977 976 +#define Z_UTIL_DEC_978 977 +#define Z_UTIL_DEC_979 978 +#define Z_UTIL_DEC_980 979 +#define Z_UTIL_DEC_981 980 +#define Z_UTIL_DEC_982 981 +#define Z_UTIL_DEC_983 982 +#define Z_UTIL_DEC_984 983 +#define Z_UTIL_DEC_985 984 +#define Z_UTIL_DEC_986 985 +#define Z_UTIL_DEC_987 986 +#define Z_UTIL_DEC_988 987 +#define Z_UTIL_DEC_989 988 +#define Z_UTIL_DEC_990 989 +#define Z_UTIL_DEC_991 990 +#define Z_UTIL_DEC_992 991 +#define Z_UTIL_DEC_993 992 +#define Z_UTIL_DEC_994 993 +#define Z_UTIL_DEC_995 994 +#define Z_UTIL_DEC_996 995 +#define Z_UTIL_DEC_997 996 +#define Z_UTIL_DEC_998 997 +#define Z_UTIL_DEC_999 998 +#define Z_UTIL_DEC_1000 999 +#define Z_UTIL_DEC_1001 1000 +#define Z_UTIL_DEC_1002 1001 +#define Z_UTIL_DEC_1003 1002 +#define Z_UTIL_DEC_1004 1003 +#define Z_UTIL_DEC_1005 1004 +#define Z_UTIL_DEC_1006 1005 +#define Z_UTIL_DEC_1007 1006 +#define Z_UTIL_DEC_1008 1007 +#define Z_UTIL_DEC_1009 1008 +#define Z_UTIL_DEC_1010 1009 +#define Z_UTIL_DEC_1011 1010 +#define Z_UTIL_DEC_1012 1011 +#define Z_UTIL_DEC_1013 1012 +#define Z_UTIL_DEC_1014 1013 +#define Z_UTIL_DEC_1015 1014 +#define Z_UTIL_DEC_1016 1015 +#define Z_UTIL_DEC_1017 1016 +#define Z_UTIL_DEC_1018 1017 +#define Z_UTIL_DEC_1019 1018 +#define Z_UTIL_DEC_1020 1019 +#define Z_UTIL_DEC_1021 1020 +#define Z_UTIL_DEC_1022 1021 +#define Z_UTIL_DEC_1023 1022 +#define Z_UTIL_DEC_1024 1023 +#define Z_UTIL_DEC_1025 1024 +#define Z_UTIL_DEC_1026 1025 +#define Z_UTIL_DEC_1027 1026 +#define Z_UTIL_DEC_1028 1027 +#define Z_UTIL_DEC_1029 1028 +#define Z_UTIL_DEC_1030 1029 +#define Z_UTIL_DEC_1031 1030 +#define Z_UTIL_DEC_1032 1031 +#define Z_UTIL_DEC_1033 1032 +#define Z_UTIL_DEC_1034 1033 +#define Z_UTIL_DEC_1035 1034 +#define Z_UTIL_DEC_1036 1035 +#define Z_UTIL_DEC_1037 1036 +#define Z_UTIL_DEC_1038 1037 +#define Z_UTIL_DEC_1039 1038 +#define Z_UTIL_DEC_1040 1039 +#define Z_UTIL_DEC_1041 1040 +#define Z_UTIL_DEC_1042 1041 +#define Z_UTIL_DEC_1043 1042 +#define Z_UTIL_DEC_1044 1043 +#define Z_UTIL_DEC_1045 1044 +#define Z_UTIL_DEC_1046 1045 +#define Z_UTIL_DEC_1047 1046 +#define Z_UTIL_DEC_1048 1047 +#define Z_UTIL_DEC_1049 1048 +#define Z_UTIL_DEC_1050 1049 +#define Z_UTIL_DEC_1051 1050 +#define Z_UTIL_DEC_1052 1051 +#define Z_UTIL_DEC_1053 1052 +#define Z_UTIL_DEC_1054 1053 +#define Z_UTIL_DEC_1055 1054 +#define Z_UTIL_DEC_1056 1055 +#define Z_UTIL_DEC_1057 1056 +#define Z_UTIL_DEC_1058 1057 +#define Z_UTIL_DEC_1059 1058 +#define Z_UTIL_DEC_1060 1059 +#define Z_UTIL_DEC_1061 1060 +#define Z_UTIL_DEC_1062 1061 +#define Z_UTIL_DEC_1063 1062 +#define Z_UTIL_DEC_1064 1063 +#define Z_UTIL_DEC_1065 1064 +#define Z_UTIL_DEC_1066 1065 +#define Z_UTIL_DEC_1067 1066 +#define Z_UTIL_DEC_1068 1067 +#define Z_UTIL_DEC_1069 1068 +#define Z_UTIL_DEC_1070 1069 +#define Z_UTIL_DEC_1071 1070 +#define Z_UTIL_DEC_1072 1071 +#define Z_UTIL_DEC_1073 1072 +#define Z_UTIL_DEC_1074 1073 +#define Z_UTIL_DEC_1075 1074 +#define Z_UTIL_DEC_1076 1075 +#define Z_UTIL_DEC_1077 1076 +#define Z_UTIL_DEC_1078 1077 +#define Z_UTIL_DEC_1079 1078 +#define Z_UTIL_DEC_1080 1079 +#define Z_UTIL_DEC_1081 1080 +#define Z_UTIL_DEC_1082 1081 +#define Z_UTIL_DEC_1083 1082 +#define Z_UTIL_DEC_1084 1083 +#define Z_UTIL_DEC_1085 1084 +#define Z_UTIL_DEC_1086 1085 +#define Z_UTIL_DEC_1087 1086 +#define Z_UTIL_DEC_1088 1087 +#define Z_UTIL_DEC_1089 1088 +#define Z_UTIL_DEC_1090 1089 +#define Z_UTIL_DEC_1091 1090 +#define Z_UTIL_DEC_1092 1091 +#define Z_UTIL_DEC_1093 1092 +#define Z_UTIL_DEC_1094 1093 +#define Z_UTIL_DEC_1095 1094 +#define Z_UTIL_DEC_1096 1095 +#define Z_UTIL_DEC_1097 1096 +#define Z_UTIL_DEC_1098 1097 +#define Z_UTIL_DEC_1099 1098 +#define Z_UTIL_DEC_1100 1099 +#define Z_UTIL_DEC_1101 1100 +#define Z_UTIL_DEC_1102 1101 +#define Z_UTIL_DEC_1103 1102 +#define Z_UTIL_DEC_1104 1103 +#define Z_UTIL_DEC_1105 1104 +#define Z_UTIL_DEC_1106 1105 +#define Z_UTIL_DEC_1107 1106 +#define Z_UTIL_DEC_1108 1107 +#define Z_UTIL_DEC_1109 1108 +#define Z_UTIL_DEC_1110 1109 +#define Z_UTIL_DEC_1111 1110 +#define Z_UTIL_DEC_1112 1111 +#define Z_UTIL_DEC_1113 1112 +#define Z_UTIL_DEC_1114 1113 +#define Z_UTIL_DEC_1115 1114 +#define Z_UTIL_DEC_1116 1115 +#define Z_UTIL_DEC_1117 1116 +#define Z_UTIL_DEC_1118 1117 +#define Z_UTIL_DEC_1119 1118 +#define Z_UTIL_DEC_1120 1119 +#define Z_UTIL_DEC_1121 1120 +#define Z_UTIL_DEC_1122 1121 +#define Z_UTIL_DEC_1123 1122 +#define Z_UTIL_DEC_1124 1123 +#define Z_UTIL_DEC_1125 1124 +#define Z_UTIL_DEC_1126 1125 +#define Z_UTIL_DEC_1127 1126 +#define Z_UTIL_DEC_1128 1127 +#define Z_UTIL_DEC_1129 1128 +#define Z_UTIL_DEC_1130 1129 +#define Z_UTIL_DEC_1131 1130 +#define Z_UTIL_DEC_1132 1131 +#define Z_UTIL_DEC_1133 1132 +#define Z_UTIL_DEC_1134 1133 +#define Z_UTIL_DEC_1135 1134 +#define Z_UTIL_DEC_1136 1135 +#define Z_UTIL_DEC_1137 1136 +#define Z_UTIL_DEC_1138 1137 +#define Z_UTIL_DEC_1139 1138 +#define Z_UTIL_DEC_1140 1139 +#define Z_UTIL_DEC_1141 1140 +#define Z_UTIL_DEC_1142 1141 +#define Z_UTIL_DEC_1143 1142 +#define Z_UTIL_DEC_1144 1143 +#define Z_UTIL_DEC_1145 1144 +#define Z_UTIL_DEC_1146 1145 +#define Z_UTIL_DEC_1147 1146 +#define Z_UTIL_DEC_1148 1147 +#define Z_UTIL_DEC_1149 1148 +#define Z_UTIL_DEC_1150 1149 +#define Z_UTIL_DEC_1151 1150 +#define Z_UTIL_DEC_1152 1151 +#define Z_UTIL_DEC_1153 1152 +#define Z_UTIL_DEC_1154 1153 +#define Z_UTIL_DEC_1155 1154 +#define Z_UTIL_DEC_1156 1155 +#define Z_UTIL_DEC_1157 1156 +#define Z_UTIL_DEC_1158 1157 +#define Z_UTIL_DEC_1159 1158 +#define Z_UTIL_DEC_1160 1159 +#define Z_UTIL_DEC_1161 1160 +#define Z_UTIL_DEC_1162 1161 +#define Z_UTIL_DEC_1163 1162 +#define Z_UTIL_DEC_1164 1163 +#define Z_UTIL_DEC_1165 1164 +#define Z_UTIL_DEC_1166 1165 +#define Z_UTIL_DEC_1167 1166 +#define Z_UTIL_DEC_1168 1167 +#define Z_UTIL_DEC_1169 1168 +#define Z_UTIL_DEC_1170 1169 +#define Z_UTIL_DEC_1171 1170 +#define Z_UTIL_DEC_1172 1171 +#define Z_UTIL_DEC_1173 1172 +#define Z_UTIL_DEC_1174 1173 +#define Z_UTIL_DEC_1175 1174 +#define Z_UTIL_DEC_1176 1175 +#define Z_UTIL_DEC_1177 1176 +#define Z_UTIL_DEC_1178 1177 +#define Z_UTIL_DEC_1179 1178 +#define Z_UTIL_DEC_1180 1179 +#define Z_UTIL_DEC_1181 1180 +#define Z_UTIL_DEC_1182 1181 +#define Z_UTIL_DEC_1183 1182 +#define Z_UTIL_DEC_1184 1183 +#define Z_UTIL_DEC_1185 1184 +#define Z_UTIL_DEC_1186 1185 +#define Z_UTIL_DEC_1187 1186 +#define Z_UTIL_DEC_1188 1187 +#define Z_UTIL_DEC_1189 1188 +#define Z_UTIL_DEC_1190 1189 +#define Z_UTIL_DEC_1191 1190 +#define Z_UTIL_DEC_1192 1191 +#define Z_UTIL_DEC_1193 1192 +#define Z_UTIL_DEC_1194 1193 +#define Z_UTIL_DEC_1195 1194 +#define Z_UTIL_DEC_1196 1195 +#define Z_UTIL_DEC_1197 1196 +#define Z_UTIL_DEC_1198 1197 +#define Z_UTIL_DEC_1199 1198 +#define Z_UTIL_DEC_1200 1199 +#define Z_UTIL_DEC_1201 1200 +#define Z_UTIL_DEC_1202 1201 +#define Z_UTIL_DEC_1203 1202 +#define Z_UTIL_DEC_1204 1203 +#define Z_UTIL_DEC_1205 1204 +#define Z_UTIL_DEC_1206 1205 +#define Z_UTIL_DEC_1207 1206 +#define Z_UTIL_DEC_1208 1207 +#define Z_UTIL_DEC_1209 1208 +#define Z_UTIL_DEC_1210 1209 +#define Z_UTIL_DEC_1211 1210 +#define Z_UTIL_DEC_1212 1211 +#define Z_UTIL_DEC_1213 1212 +#define Z_UTIL_DEC_1214 1213 +#define Z_UTIL_DEC_1215 1214 +#define Z_UTIL_DEC_1216 1215 +#define Z_UTIL_DEC_1217 1216 +#define Z_UTIL_DEC_1218 1217 +#define Z_UTIL_DEC_1219 1218 +#define Z_UTIL_DEC_1220 1219 +#define Z_UTIL_DEC_1221 1220 +#define Z_UTIL_DEC_1222 1221 +#define Z_UTIL_DEC_1223 1222 +#define Z_UTIL_DEC_1224 1223 +#define Z_UTIL_DEC_1225 1224 +#define Z_UTIL_DEC_1226 1225 +#define Z_UTIL_DEC_1227 1226 +#define Z_UTIL_DEC_1228 1227 +#define Z_UTIL_DEC_1229 1228 +#define Z_UTIL_DEC_1230 1229 +#define Z_UTIL_DEC_1231 1230 +#define Z_UTIL_DEC_1232 1231 +#define Z_UTIL_DEC_1233 1232 +#define Z_UTIL_DEC_1234 1233 +#define Z_UTIL_DEC_1235 1234 +#define Z_UTIL_DEC_1236 1235 +#define Z_UTIL_DEC_1237 1236 +#define Z_UTIL_DEC_1238 1237 +#define Z_UTIL_DEC_1239 1238 +#define Z_UTIL_DEC_1240 1239 +#define Z_UTIL_DEC_1241 1240 +#define Z_UTIL_DEC_1242 1241 +#define Z_UTIL_DEC_1243 1242 +#define Z_UTIL_DEC_1244 1243 +#define Z_UTIL_DEC_1245 1244 +#define Z_UTIL_DEC_1246 1245 +#define Z_UTIL_DEC_1247 1246 +#define Z_UTIL_DEC_1248 1247 +#define Z_UTIL_DEC_1249 1248 +#define Z_UTIL_DEC_1250 1249 +#define Z_UTIL_DEC_1251 1250 +#define Z_UTIL_DEC_1252 1251 +#define Z_UTIL_DEC_1253 1252 +#define Z_UTIL_DEC_1254 1253 +#define Z_UTIL_DEC_1255 1254 +#define Z_UTIL_DEC_1256 1255 +#define Z_UTIL_DEC_1257 1256 +#define Z_UTIL_DEC_1258 1257 +#define Z_UTIL_DEC_1259 1258 +#define Z_UTIL_DEC_1260 1259 +#define Z_UTIL_DEC_1261 1260 +#define Z_UTIL_DEC_1262 1261 +#define Z_UTIL_DEC_1263 1262 +#define Z_UTIL_DEC_1264 1263 +#define Z_UTIL_DEC_1265 1264 +#define Z_UTIL_DEC_1266 1265 +#define Z_UTIL_DEC_1267 1266 +#define Z_UTIL_DEC_1268 1267 +#define Z_UTIL_DEC_1269 1268 +#define Z_UTIL_DEC_1270 1269 +#define Z_UTIL_DEC_1271 1270 +#define Z_UTIL_DEC_1272 1271 +#define Z_UTIL_DEC_1273 1272 +#define Z_UTIL_DEC_1274 1273 +#define Z_UTIL_DEC_1275 1274 +#define Z_UTIL_DEC_1276 1275 +#define Z_UTIL_DEC_1277 1276 +#define Z_UTIL_DEC_1278 1277 +#define Z_UTIL_DEC_1279 1278 +#define Z_UTIL_DEC_1280 1279 +#define Z_UTIL_DEC_1281 1280 +#define Z_UTIL_DEC_1282 1281 +#define Z_UTIL_DEC_1283 1282 +#define Z_UTIL_DEC_1284 1283 +#define Z_UTIL_DEC_1285 1284 +#define Z_UTIL_DEC_1286 1285 +#define Z_UTIL_DEC_1287 1286 +#define Z_UTIL_DEC_1288 1287 +#define Z_UTIL_DEC_1289 1288 +#define Z_UTIL_DEC_1290 1289 +#define Z_UTIL_DEC_1291 1290 +#define Z_UTIL_DEC_1292 1291 +#define Z_UTIL_DEC_1293 1292 +#define Z_UTIL_DEC_1294 1293 +#define Z_UTIL_DEC_1295 1294 +#define Z_UTIL_DEC_1296 1295 +#define Z_UTIL_DEC_1297 1296 +#define Z_UTIL_DEC_1298 1297 +#define Z_UTIL_DEC_1299 1298 +#define Z_UTIL_DEC_1300 1299 +#define Z_UTIL_DEC_1301 1300 +#define Z_UTIL_DEC_1302 1301 +#define Z_UTIL_DEC_1303 1302 +#define Z_UTIL_DEC_1304 1303 +#define Z_UTIL_DEC_1305 1304 +#define Z_UTIL_DEC_1306 1305 +#define Z_UTIL_DEC_1307 1306 +#define Z_UTIL_DEC_1308 1307 +#define Z_UTIL_DEC_1309 1308 +#define Z_UTIL_DEC_1310 1309 +#define Z_UTIL_DEC_1311 1310 +#define Z_UTIL_DEC_1312 1311 +#define Z_UTIL_DEC_1313 1312 +#define Z_UTIL_DEC_1314 1313 +#define Z_UTIL_DEC_1315 1314 +#define Z_UTIL_DEC_1316 1315 +#define Z_UTIL_DEC_1317 1316 +#define Z_UTIL_DEC_1318 1317 +#define Z_UTIL_DEC_1319 1318 +#define Z_UTIL_DEC_1320 1319 +#define Z_UTIL_DEC_1321 1320 +#define Z_UTIL_DEC_1322 1321 +#define Z_UTIL_DEC_1323 1322 +#define Z_UTIL_DEC_1324 1323 +#define Z_UTIL_DEC_1325 1324 +#define Z_UTIL_DEC_1326 1325 +#define Z_UTIL_DEC_1327 1326 +#define Z_UTIL_DEC_1328 1327 +#define Z_UTIL_DEC_1329 1328 +#define Z_UTIL_DEC_1330 1329 +#define Z_UTIL_DEC_1331 1330 +#define Z_UTIL_DEC_1332 1331 +#define Z_UTIL_DEC_1333 1332 +#define Z_UTIL_DEC_1334 1333 +#define Z_UTIL_DEC_1335 1334 +#define Z_UTIL_DEC_1336 1335 +#define Z_UTIL_DEC_1337 1336 +#define Z_UTIL_DEC_1338 1337 +#define Z_UTIL_DEC_1339 1338 +#define Z_UTIL_DEC_1340 1339 +#define Z_UTIL_DEC_1341 1340 +#define Z_UTIL_DEC_1342 1341 +#define Z_UTIL_DEC_1343 1342 +#define Z_UTIL_DEC_1344 1343 +#define Z_UTIL_DEC_1345 1344 +#define Z_UTIL_DEC_1346 1345 +#define Z_UTIL_DEC_1347 1346 +#define Z_UTIL_DEC_1348 1347 +#define Z_UTIL_DEC_1349 1348 +#define Z_UTIL_DEC_1350 1349 +#define Z_UTIL_DEC_1351 1350 +#define Z_UTIL_DEC_1352 1351 +#define Z_UTIL_DEC_1353 1352 +#define Z_UTIL_DEC_1354 1353 +#define Z_UTIL_DEC_1355 1354 +#define Z_UTIL_DEC_1356 1355 +#define Z_UTIL_DEC_1357 1356 +#define Z_UTIL_DEC_1358 1357 +#define Z_UTIL_DEC_1359 1358 +#define Z_UTIL_DEC_1360 1359 +#define Z_UTIL_DEC_1361 1360 +#define Z_UTIL_DEC_1362 1361 +#define Z_UTIL_DEC_1363 1362 +#define Z_UTIL_DEC_1364 1363 +#define Z_UTIL_DEC_1365 1364 +#define Z_UTIL_DEC_1366 1365 +#define Z_UTIL_DEC_1367 1366 +#define Z_UTIL_DEC_1368 1367 +#define Z_UTIL_DEC_1369 1368 +#define Z_UTIL_DEC_1370 1369 +#define Z_UTIL_DEC_1371 1370 +#define Z_UTIL_DEC_1372 1371 +#define Z_UTIL_DEC_1373 1372 +#define Z_UTIL_DEC_1374 1373 +#define Z_UTIL_DEC_1375 1374 +#define Z_UTIL_DEC_1376 1375 +#define Z_UTIL_DEC_1377 1376 +#define Z_UTIL_DEC_1378 1377 +#define Z_UTIL_DEC_1379 1378 +#define Z_UTIL_DEC_1380 1379 +#define Z_UTIL_DEC_1381 1380 +#define Z_UTIL_DEC_1382 1381 +#define Z_UTIL_DEC_1383 1382 +#define Z_UTIL_DEC_1384 1383 +#define Z_UTIL_DEC_1385 1384 +#define Z_UTIL_DEC_1386 1385 +#define Z_UTIL_DEC_1387 1386 +#define Z_UTIL_DEC_1388 1387 +#define Z_UTIL_DEC_1389 1388 +#define Z_UTIL_DEC_1390 1389 +#define Z_UTIL_DEC_1391 1390 +#define Z_UTIL_DEC_1392 1391 +#define Z_UTIL_DEC_1393 1392 +#define Z_UTIL_DEC_1394 1393 +#define Z_UTIL_DEC_1395 1394 +#define Z_UTIL_DEC_1396 1395 +#define Z_UTIL_DEC_1397 1396 +#define Z_UTIL_DEC_1398 1397 +#define Z_UTIL_DEC_1399 1398 +#define Z_UTIL_DEC_1400 1399 +#define Z_UTIL_DEC_1401 1400 +#define Z_UTIL_DEC_1402 1401 +#define Z_UTIL_DEC_1403 1402 +#define Z_UTIL_DEC_1404 1403 +#define Z_UTIL_DEC_1405 1404 +#define Z_UTIL_DEC_1406 1405 +#define Z_UTIL_DEC_1407 1406 +#define Z_UTIL_DEC_1408 1407 +#define Z_UTIL_DEC_1409 1408 +#define Z_UTIL_DEC_1410 1409 +#define Z_UTIL_DEC_1411 1410 +#define Z_UTIL_DEC_1412 1411 +#define Z_UTIL_DEC_1413 1412 +#define Z_UTIL_DEC_1414 1413 +#define Z_UTIL_DEC_1415 1414 +#define Z_UTIL_DEC_1416 1415 +#define Z_UTIL_DEC_1417 1416 +#define Z_UTIL_DEC_1418 1417 +#define Z_UTIL_DEC_1419 1418 +#define Z_UTIL_DEC_1420 1419 +#define Z_UTIL_DEC_1421 1420 +#define Z_UTIL_DEC_1422 1421 +#define Z_UTIL_DEC_1423 1422 +#define Z_UTIL_DEC_1424 1423 +#define Z_UTIL_DEC_1425 1424 +#define Z_UTIL_DEC_1426 1425 +#define Z_UTIL_DEC_1427 1426 +#define Z_UTIL_DEC_1428 1427 +#define Z_UTIL_DEC_1429 1428 +#define Z_UTIL_DEC_1430 1429 +#define Z_UTIL_DEC_1431 1430 +#define Z_UTIL_DEC_1432 1431 +#define Z_UTIL_DEC_1433 1432 +#define Z_UTIL_DEC_1434 1433 +#define Z_UTIL_DEC_1435 1434 +#define Z_UTIL_DEC_1436 1435 +#define Z_UTIL_DEC_1437 1436 +#define Z_UTIL_DEC_1438 1437 +#define Z_UTIL_DEC_1439 1438 +#define Z_UTIL_DEC_1440 1439 +#define Z_UTIL_DEC_1441 1440 +#define Z_UTIL_DEC_1442 1441 +#define Z_UTIL_DEC_1443 1442 +#define Z_UTIL_DEC_1444 1443 +#define Z_UTIL_DEC_1445 1444 +#define Z_UTIL_DEC_1446 1445 +#define Z_UTIL_DEC_1447 1446 +#define Z_UTIL_DEC_1448 1447 +#define Z_UTIL_DEC_1449 1448 +#define Z_UTIL_DEC_1450 1449 +#define Z_UTIL_DEC_1451 1450 +#define Z_UTIL_DEC_1452 1451 +#define Z_UTIL_DEC_1453 1452 +#define Z_UTIL_DEC_1454 1453 +#define Z_UTIL_DEC_1455 1454 +#define Z_UTIL_DEC_1456 1455 +#define Z_UTIL_DEC_1457 1456 +#define Z_UTIL_DEC_1458 1457 +#define Z_UTIL_DEC_1459 1458 +#define Z_UTIL_DEC_1460 1459 +#define Z_UTIL_DEC_1461 1460 +#define Z_UTIL_DEC_1462 1461 +#define Z_UTIL_DEC_1463 1462 +#define Z_UTIL_DEC_1464 1463 +#define Z_UTIL_DEC_1465 1464 +#define Z_UTIL_DEC_1466 1465 +#define Z_UTIL_DEC_1467 1466 +#define Z_UTIL_DEC_1468 1467 +#define Z_UTIL_DEC_1469 1468 +#define Z_UTIL_DEC_1470 1469 +#define Z_UTIL_DEC_1471 1470 +#define Z_UTIL_DEC_1472 1471 +#define Z_UTIL_DEC_1473 1472 +#define Z_UTIL_DEC_1474 1473 +#define Z_UTIL_DEC_1475 1474 +#define Z_UTIL_DEC_1476 1475 +#define Z_UTIL_DEC_1477 1476 +#define Z_UTIL_DEC_1478 1477 +#define Z_UTIL_DEC_1479 1478 +#define Z_UTIL_DEC_1480 1479 +#define Z_UTIL_DEC_1481 1480 +#define Z_UTIL_DEC_1482 1481 +#define Z_UTIL_DEC_1483 1482 +#define Z_UTIL_DEC_1484 1483 +#define Z_UTIL_DEC_1485 1484 +#define Z_UTIL_DEC_1486 1485 +#define Z_UTIL_DEC_1487 1486 +#define Z_UTIL_DEC_1488 1487 +#define Z_UTIL_DEC_1489 1488 +#define Z_UTIL_DEC_1490 1489 +#define Z_UTIL_DEC_1491 1490 +#define Z_UTIL_DEC_1492 1491 +#define Z_UTIL_DEC_1493 1492 +#define Z_UTIL_DEC_1494 1493 +#define Z_UTIL_DEC_1495 1494 +#define Z_UTIL_DEC_1496 1495 +#define Z_UTIL_DEC_1497 1496 +#define Z_UTIL_DEC_1498 1497 +#define Z_UTIL_DEC_1499 1498 +#define Z_UTIL_DEC_1500 1499 +#define Z_UTIL_DEC_1501 1500 +#define Z_UTIL_DEC_1502 1501 +#define Z_UTIL_DEC_1503 1502 +#define Z_UTIL_DEC_1504 1503 +#define Z_UTIL_DEC_1505 1504 +#define Z_UTIL_DEC_1506 1505 +#define Z_UTIL_DEC_1507 1506 +#define Z_UTIL_DEC_1508 1507 +#define Z_UTIL_DEC_1509 1508 +#define Z_UTIL_DEC_1510 1509 +#define Z_UTIL_DEC_1511 1510 +#define Z_UTIL_DEC_1512 1511 +#define Z_UTIL_DEC_1513 1512 +#define Z_UTIL_DEC_1514 1513 +#define Z_UTIL_DEC_1515 1514 +#define Z_UTIL_DEC_1516 1515 +#define Z_UTIL_DEC_1517 1516 +#define Z_UTIL_DEC_1518 1517 +#define Z_UTIL_DEC_1519 1518 +#define Z_UTIL_DEC_1520 1519 +#define Z_UTIL_DEC_1521 1520 +#define Z_UTIL_DEC_1522 1521 +#define Z_UTIL_DEC_1523 1522 +#define Z_UTIL_DEC_1524 1523 +#define Z_UTIL_DEC_1525 1524 +#define Z_UTIL_DEC_1526 1525 +#define Z_UTIL_DEC_1527 1526 +#define Z_UTIL_DEC_1528 1527 +#define Z_UTIL_DEC_1529 1528 +#define Z_UTIL_DEC_1530 1529 +#define Z_UTIL_DEC_1531 1530 +#define Z_UTIL_DEC_1532 1531 +#define Z_UTIL_DEC_1533 1532 +#define Z_UTIL_DEC_1534 1533 +#define Z_UTIL_DEC_1535 1534 +#define Z_UTIL_DEC_1536 1535 +#define Z_UTIL_DEC_1537 1536 +#define Z_UTIL_DEC_1538 1537 +#define Z_UTIL_DEC_1539 1538 +#define Z_UTIL_DEC_1540 1539 +#define Z_UTIL_DEC_1541 1540 +#define Z_UTIL_DEC_1542 1541 +#define Z_UTIL_DEC_1543 1542 +#define Z_UTIL_DEC_1544 1543 +#define Z_UTIL_DEC_1545 1544 +#define Z_UTIL_DEC_1546 1545 +#define Z_UTIL_DEC_1547 1546 +#define Z_UTIL_DEC_1548 1547 +#define Z_UTIL_DEC_1549 1548 +#define Z_UTIL_DEC_1550 1549 +#define Z_UTIL_DEC_1551 1550 +#define Z_UTIL_DEC_1552 1551 +#define Z_UTIL_DEC_1553 1552 +#define Z_UTIL_DEC_1554 1553 +#define Z_UTIL_DEC_1555 1554 +#define Z_UTIL_DEC_1556 1555 +#define Z_UTIL_DEC_1557 1556 +#define Z_UTIL_DEC_1558 1557 +#define Z_UTIL_DEC_1559 1558 +#define Z_UTIL_DEC_1560 1559 +#define Z_UTIL_DEC_1561 1560 +#define Z_UTIL_DEC_1562 1561 +#define Z_UTIL_DEC_1563 1562 +#define Z_UTIL_DEC_1564 1563 +#define Z_UTIL_DEC_1565 1564 +#define Z_UTIL_DEC_1566 1565 +#define Z_UTIL_DEC_1567 1566 +#define Z_UTIL_DEC_1568 1567 +#define Z_UTIL_DEC_1569 1568 +#define Z_UTIL_DEC_1570 1569 +#define Z_UTIL_DEC_1571 1570 +#define Z_UTIL_DEC_1572 1571 +#define Z_UTIL_DEC_1573 1572 +#define Z_UTIL_DEC_1574 1573 +#define Z_UTIL_DEC_1575 1574 +#define Z_UTIL_DEC_1576 1575 +#define Z_UTIL_DEC_1577 1576 +#define Z_UTIL_DEC_1578 1577 +#define Z_UTIL_DEC_1579 1578 +#define Z_UTIL_DEC_1580 1579 +#define Z_UTIL_DEC_1581 1580 +#define Z_UTIL_DEC_1582 1581 +#define Z_UTIL_DEC_1583 1582 +#define Z_UTIL_DEC_1584 1583 +#define Z_UTIL_DEC_1585 1584 +#define Z_UTIL_DEC_1586 1585 +#define Z_UTIL_DEC_1587 1586 +#define Z_UTIL_DEC_1588 1587 +#define Z_UTIL_DEC_1589 1588 +#define Z_UTIL_DEC_1590 1589 +#define Z_UTIL_DEC_1591 1590 +#define Z_UTIL_DEC_1592 1591 +#define Z_UTIL_DEC_1593 1592 +#define Z_UTIL_DEC_1594 1593 +#define Z_UTIL_DEC_1595 1594 +#define Z_UTIL_DEC_1596 1595 +#define Z_UTIL_DEC_1597 1596 +#define Z_UTIL_DEC_1598 1597 +#define Z_UTIL_DEC_1599 1598 +#define Z_UTIL_DEC_1600 1599 +#define Z_UTIL_DEC_1601 1600 +#define Z_UTIL_DEC_1602 1601 +#define Z_UTIL_DEC_1603 1602 +#define Z_UTIL_DEC_1604 1603 +#define Z_UTIL_DEC_1605 1604 +#define Z_UTIL_DEC_1606 1605 +#define Z_UTIL_DEC_1607 1606 +#define Z_UTIL_DEC_1608 1607 +#define Z_UTIL_DEC_1609 1608 +#define Z_UTIL_DEC_1610 1609 +#define Z_UTIL_DEC_1611 1610 +#define Z_UTIL_DEC_1612 1611 +#define Z_UTIL_DEC_1613 1612 +#define Z_UTIL_DEC_1614 1613 +#define Z_UTIL_DEC_1615 1614 +#define Z_UTIL_DEC_1616 1615 +#define Z_UTIL_DEC_1617 1616 +#define Z_UTIL_DEC_1618 1617 +#define Z_UTIL_DEC_1619 1618 +#define Z_UTIL_DEC_1620 1619 +#define Z_UTIL_DEC_1621 1620 +#define Z_UTIL_DEC_1622 1621 +#define Z_UTIL_DEC_1623 1622 +#define Z_UTIL_DEC_1624 1623 +#define Z_UTIL_DEC_1625 1624 +#define Z_UTIL_DEC_1626 1625 +#define Z_UTIL_DEC_1627 1626 +#define Z_UTIL_DEC_1628 1627 +#define Z_UTIL_DEC_1629 1628 +#define Z_UTIL_DEC_1630 1629 +#define Z_UTIL_DEC_1631 1630 +#define Z_UTIL_DEC_1632 1631 +#define Z_UTIL_DEC_1633 1632 +#define Z_UTIL_DEC_1634 1633 +#define Z_UTIL_DEC_1635 1634 +#define Z_UTIL_DEC_1636 1635 +#define Z_UTIL_DEC_1637 1636 +#define Z_UTIL_DEC_1638 1637 +#define Z_UTIL_DEC_1639 1638 +#define Z_UTIL_DEC_1640 1639 +#define Z_UTIL_DEC_1641 1640 +#define Z_UTIL_DEC_1642 1641 +#define Z_UTIL_DEC_1643 1642 +#define Z_UTIL_DEC_1644 1643 +#define Z_UTIL_DEC_1645 1644 +#define Z_UTIL_DEC_1646 1645 +#define Z_UTIL_DEC_1647 1646 +#define Z_UTIL_DEC_1648 1647 +#define Z_UTIL_DEC_1649 1648 +#define Z_UTIL_DEC_1650 1649 +#define Z_UTIL_DEC_1651 1650 +#define Z_UTIL_DEC_1652 1651 +#define Z_UTIL_DEC_1653 1652 +#define Z_UTIL_DEC_1654 1653 +#define Z_UTIL_DEC_1655 1654 +#define Z_UTIL_DEC_1656 1655 +#define Z_UTIL_DEC_1657 1656 +#define Z_UTIL_DEC_1658 1657 +#define Z_UTIL_DEC_1659 1658 +#define Z_UTIL_DEC_1660 1659 +#define Z_UTIL_DEC_1661 1660 +#define Z_UTIL_DEC_1662 1661 +#define Z_UTIL_DEC_1663 1662 +#define Z_UTIL_DEC_1664 1663 +#define Z_UTIL_DEC_1665 1664 +#define Z_UTIL_DEC_1666 1665 +#define Z_UTIL_DEC_1667 1666 +#define Z_UTIL_DEC_1668 1667 +#define Z_UTIL_DEC_1669 1668 +#define Z_UTIL_DEC_1670 1669 +#define Z_UTIL_DEC_1671 1670 +#define Z_UTIL_DEC_1672 1671 +#define Z_UTIL_DEC_1673 1672 +#define Z_UTIL_DEC_1674 1673 +#define Z_UTIL_DEC_1675 1674 +#define Z_UTIL_DEC_1676 1675 +#define Z_UTIL_DEC_1677 1676 +#define Z_UTIL_DEC_1678 1677 +#define Z_UTIL_DEC_1679 1678 +#define Z_UTIL_DEC_1680 1679 +#define Z_UTIL_DEC_1681 1680 +#define Z_UTIL_DEC_1682 1681 +#define Z_UTIL_DEC_1683 1682 +#define Z_UTIL_DEC_1684 1683 +#define Z_UTIL_DEC_1685 1684 +#define Z_UTIL_DEC_1686 1685 +#define Z_UTIL_DEC_1687 1686 +#define Z_UTIL_DEC_1688 1687 +#define Z_UTIL_DEC_1689 1688 +#define Z_UTIL_DEC_1690 1689 +#define Z_UTIL_DEC_1691 1690 +#define Z_UTIL_DEC_1692 1691 +#define Z_UTIL_DEC_1693 1692 +#define Z_UTIL_DEC_1694 1693 +#define Z_UTIL_DEC_1695 1694 +#define Z_UTIL_DEC_1696 1695 +#define Z_UTIL_DEC_1697 1696 +#define Z_UTIL_DEC_1698 1697 +#define Z_UTIL_DEC_1699 1698 +#define Z_UTIL_DEC_1700 1699 +#define Z_UTIL_DEC_1701 1700 +#define Z_UTIL_DEC_1702 1701 +#define Z_UTIL_DEC_1703 1702 +#define Z_UTIL_DEC_1704 1703 +#define Z_UTIL_DEC_1705 1704 +#define Z_UTIL_DEC_1706 1705 +#define Z_UTIL_DEC_1707 1706 +#define Z_UTIL_DEC_1708 1707 +#define Z_UTIL_DEC_1709 1708 +#define Z_UTIL_DEC_1710 1709 +#define Z_UTIL_DEC_1711 1710 +#define Z_UTIL_DEC_1712 1711 +#define Z_UTIL_DEC_1713 1712 +#define Z_UTIL_DEC_1714 1713 +#define Z_UTIL_DEC_1715 1714 +#define Z_UTIL_DEC_1716 1715 +#define Z_UTIL_DEC_1717 1716 +#define Z_UTIL_DEC_1718 1717 +#define Z_UTIL_DEC_1719 1718 +#define Z_UTIL_DEC_1720 1719 +#define Z_UTIL_DEC_1721 1720 +#define Z_UTIL_DEC_1722 1721 +#define Z_UTIL_DEC_1723 1722 +#define Z_UTIL_DEC_1724 1723 +#define Z_UTIL_DEC_1725 1724 +#define Z_UTIL_DEC_1726 1725 +#define Z_UTIL_DEC_1727 1726 +#define Z_UTIL_DEC_1728 1727 +#define Z_UTIL_DEC_1729 1728 +#define Z_UTIL_DEC_1730 1729 +#define Z_UTIL_DEC_1731 1730 +#define Z_UTIL_DEC_1732 1731 +#define Z_UTIL_DEC_1733 1732 +#define Z_UTIL_DEC_1734 1733 +#define Z_UTIL_DEC_1735 1734 +#define Z_UTIL_DEC_1736 1735 +#define Z_UTIL_DEC_1737 1736 +#define Z_UTIL_DEC_1738 1737 +#define Z_UTIL_DEC_1739 1738 +#define Z_UTIL_DEC_1740 1739 +#define Z_UTIL_DEC_1741 1740 +#define Z_UTIL_DEC_1742 1741 +#define Z_UTIL_DEC_1743 1742 +#define Z_UTIL_DEC_1744 1743 +#define Z_UTIL_DEC_1745 1744 +#define Z_UTIL_DEC_1746 1745 +#define Z_UTIL_DEC_1747 1746 +#define Z_UTIL_DEC_1748 1747 +#define Z_UTIL_DEC_1749 1748 +#define Z_UTIL_DEC_1750 1749 +#define Z_UTIL_DEC_1751 1750 +#define Z_UTIL_DEC_1752 1751 +#define Z_UTIL_DEC_1753 1752 +#define Z_UTIL_DEC_1754 1753 +#define Z_UTIL_DEC_1755 1754 +#define Z_UTIL_DEC_1756 1755 +#define Z_UTIL_DEC_1757 1756 +#define Z_UTIL_DEC_1758 1757 +#define Z_UTIL_DEC_1759 1758 +#define Z_UTIL_DEC_1760 1759 +#define Z_UTIL_DEC_1761 1760 +#define Z_UTIL_DEC_1762 1761 +#define Z_UTIL_DEC_1763 1762 +#define Z_UTIL_DEC_1764 1763 +#define Z_UTIL_DEC_1765 1764 +#define Z_UTIL_DEC_1766 1765 +#define Z_UTIL_DEC_1767 1766 +#define Z_UTIL_DEC_1768 1767 +#define Z_UTIL_DEC_1769 1768 +#define Z_UTIL_DEC_1770 1769 +#define Z_UTIL_DEC_1771 1770 +#define Z_UTIL_DEC_1772 1771 +#define Z_UTIL_DEC_1773 1772 +#define Z_UTIL_DEC_1774 1773 +#define Z_UTIL_DEC_1775 1774 +#define Z_UTIL_DEC_1776 1775 +#define Z_UTIL_DEC_1777 1776 +#define Z_UTIL_DEC_1778 1777 +#define Z_UTIL_DEC_1779 1778 +#define Z_UTIL_DEC_1780 1779 +#define Z_UTIL_DEC_1781 1780 +#define Z_UTIL_DEC_1782 1781 +#define Z_UTIL_DEC_1783 1782 +#define Z_UTIL_DEC_1784 1783 +#define Z_UTIL_DEC_1785 1784 +#define Z_UTIL_DEC_1786 1785 +#define Z_UTIL_DEC_1787 1786 +#define Z_UTIL_DEC_1788 1787 +#define Z_UTIL_DEC_1789 1788 +#define Z_UTIL_DEC_1790 1789 +#define Z_UTIL_DEC_1791 1790 +#define Z_UTIL_DEC_1792 1791 +#define Z_UTIL_DEC_1793 1792 +#define Z_UTIL_DEC_1794 1793 +#define Z_UTIL_DEC_1795 1794 +#define Z_UTIL_DEC_1796 1795 +#define Z_UTIL_DEC_1797 1796 +#define Z_UTIL_DEC_1798 1797 +#define Z_UTIL_DEC_1799 1798 +#define Z_UTIL_DEC_1800 1799 +#define Z_UTIL_DEC_1801 1800 +#define Z_UTIL_DEC_1802 1801 +#define Z_UTIL_DEC_1803 1802 +#define Z_UTIL_DEC_1804 1803 +#define Z_UTIL_DEC_1805 1804 +#define Z_UTIL_DEC_1806 1805 +#define Z_UTIL_DEC_1807 1806 +#define Z_UTIL_DEC_1808 1807 +#define Z_UTIL_DEC_1809 1808 +#define Z_UTIL_DEC_1810 1809 +#define Z_UTIL_DEC_1811 1810 +#define Z_UTIL_DEC_1812 1811 +#define Z_UTIL_DEC_1813 1812 +#define Z_UTIL_DEC_1814 1813 +#define Z_UTIL_DEC_1815 1814 +#define Z_UTIL_DEC_1816 1815 +#define Z_UTIL_DEC_1817 1816 +#define Z_UTIL_DEC_1818 1817 +#define Z_UTIL_DEC_1819 1818 +#define Z_UTIL_DEC_1820 1819 +#define Z_UTIL_DEC_1821 1820 +#define Z_UTIL_DEC_1822 1821 +#define Z_UTIL_DEC_1823 1822 +#define Z_UTIL_DEC_1824 1823 +#define Z_UTIL_DEC_1825 1824 +#define Z_UTIL_DEC_1826 1825 +#define Z_UTIL_DEC_1827 1826 +#define Z_UTIL_DEC_1828 1827 +#define Z_UTIL_DEC_1829 1828 +#define Z_UTIL_DEC_1830 1829 +#define Z_UTIL_DEC_1831 1830 +#define Z_UTIL_DEC_1832 1831 +#define Z_UTIL_DEC_1833 1832 +#define Z_UTIL_DEC_1834 1833 +#define Z_UTIL_DEC_1835 1834 +#define Z_UTIL_DEC_1836 1835 +#define Z_UTIL_DEC_1837 1836 +#define Z_UTIL_DEC_1838 1837 +#define Z_UTIL_DEC_1839 1838 +#define Z_UTIL_DEC_1840 1839 +#define Z_UTIL_DEC_1841 1840 +#define Z_UTIL_DEC_1842 1841 +#define Z_UTIL_DEC_1843 1842 +#define Z_UTIL_DEC_1844 1843 +#define Z_UTIL_DEC_1845 1844 +#define Z_UTIL_DEC_1846 1845 +#define Z_UTIL_DEC_1847 1846 +#define Z_UTIL_DEC_1848 1847 +#define Z_UTIL_DEC_1849 1848 +#define Z_UTIL_DEC_1850 1849 +#define Z_UTIL_DEC_1851 1850 +#define Z_UTIL_DEC_1852 1851 +#define Z_UTIL_DEC_1853 1852 +#define Z_UTIL_DEC_1854 1853 +#define Z_UTIL_DEC_1855 1854 +#define Z_UTIL_DEC_1856 1855 +#define Z_UTIL_DEC_1857 1856 +#define Z_UTIL_DEC_1858 1857 +#define Z_UTIL_DEC_1859 1858 +#define Z_UTIL_DEC_1860 1859 +#define Z_UTIL_DEC_1861 1860 +#define Z_UTIL_DEC_1862 1861 +#define Z_UTIL_DEC_1863 1862 +#define Z_UTIL_DEC_1864 1863 +#define Z_UTIL_DEC_1865 1864 +#define Z_UTIL_DEC_1866 1865 +#define Z_UTIL_DEC_1867 1866 +#define Z_UTIL_DEC_1868 1867 +#define Z_UTIL_DEC_1869 1868 +#define Z_UTIL_DEC_1870 1869 +#define Z_UTIL_DEC_1871 1870 +#define Z_UTIL_DEC_1872 1871 +#define Z_UTIL_DEC_1873 1872 +#define Z_UTIL_DEC_1874 1873 +#define Z_UTIL_DEC_1875 1874 +#define Z_UTIL_DEC_1876 1875 +#define Z_UTIL_DEC_1877 1876 +#define Z_UTIL_DEC_1878 1877 +#define Z_UTIL_DEC_1879 1878 +#define Z_UTIL_DEC_1880 1879 +#define Z_UTIL_DEC_1881 1880 +#define Z_UTIL_DEC_1882 1881 +#define Z_UTIL_DEC_1883 1882 +#define Z_UTIL_DEC_1884 1883 +#define Z_UTIL_DEC_1885 1884 +#define Z_UTIL_DEC_1886 1885 +#define Z_UTIL_DEC_1887 1886 +#define Z_UTIL_DEC_1888 1887 +#define Z_UTIL_DEC_1889 1888 +#define Z_UTIL_DEC_1890 1889 +#define Z_UTIL_DEC_1891 1890 +#define Z_UTIL_DEC_1892 1891 +#define Z_UTIL_DEC_1893 1892 +#define Z_UTIL_DEC_1894 1893 +#define Z_UTIL_DEC_1895 1894 +#define Z_UTIL_DEC_1896 1895 +#define Z_UTIL_DEC_1897 1896 +#define Z_UTIL_DEC_1898 1897 +#define Z_UTIL_DEC_1899 1898 +#define Z_UTIL_DEC_1900 1899 +#define Z_UTIL_DEC_1901 1900 +#define Z_UTIL_DEC_1902 1901 +#define Z_UTIL_DEC_1903 1902 +#define Z_UTIL_DEC_1904 1903 +#define Z_UTIL_DEC_1905 1904 +#define Z_UTIL_DEC_1906 1905 +#define Z_UTIL_DEC_1907 1906 +#define Z_UTIL_DEC_1908 1907 +#define Z_UTIL_DEC_1909 1908 +#define Z_UTIL_DEC_1910 1909 +#define Z_UTIL_DEC_1911 1910 +#define Z_UTIL_DEC_1912 1911 +#define Z_UTIL_DEC_1913 1912 +#define Z_UTIL_DEC_1914 1913 +#define Z_UTIL_DEC_1915 1914 +#define Z_UTIL_DEC_1916 1915 +#define Z_UTIL_DEC_1917 1916 +#define Z_UTIL_DEC_1918 1917 +#define Z_UTIL_DEC_1919 1918 +#define Z_UTIL_DEC_1920 1919 +#define Z_UTIL_DEC_1921 1920 +#define Z_UTIL_DEC_1922 1921 +#define Z_UTIL_DEC_1923 1922 +#define Z_UTIL_DEC_1924 1923 +#define Z_UTIL_DEC_1925 1924 +#define Z_UTIL_DEC_1926 1925 +#define Z_UTIL_DEC_1927 1926 +#define Z_UTIL_DEC_1928 1927 +#define Z_UTIL_DEC_1929 1928 +#define Z_UTIL_DEC_1930 1929 +#define Z_UTIL_DEC_1931 1930 +#define Z_UTIL_DEC_1932 1931 +#define Z_UTIL_DEC_1933 1932 +#define Z_UTIL_DEC_1934 1933 +#define Z_UTIL_DEC_1935 1934 +#define Z_UTIL_DEC_1936 1935 +#define Z_UTIL_DEC_1937 1936 +#define Z_UTIL_DEC_1938 1937 +#define Z_UTIL_DEC_1939 1938 +#define Z_UTIL_DEC_1940 1939 +#define Z_UTIL_DEC_1941 1940 +#define Z_UTIL_DEC_1942 1941 +#define Z_UTIL_DEC_1943 1942 +#define Z_UTIL_DEC_1944 1943 +#define Z_UTIL_DEC_1945 1944 +#define Z_UTIL_DEC_1946 1945 +#define Z_UTIL_DEC_1947 1946 +#define Z_UTIL_DEC_1948 1947 +#define Z_UTIL_DEC_1949 1948 +#define Z_UTIL_DEC_1950 1949 +#define Z_UTIL_DEC_1951 1950 +#define Z_UTIL_DEC_1952 1951 +#define Z_UTIL_DEC_1953 1952 +#define Z_UTIL_DEC_1954 1953 +#define Z_UTIL_DEC_1955 1954 +#define Z_UTIL_DEC_1956 1955 +#define Z_UTIL_DEC_1957 1956 +#define Z_UTIL_DEC_1958 1957 +#define Z_UTIL_DEC_1959 1958 +#define Z_UTIL_DEC_1960 1959 +#define Z_UTIL_DEC_1961 1960 +#define Z_UTIL_DEC_1962 1961 +#define Z_UTIL_DEC_1963 1962 +#define Z_UTIL_DEC_1964 1963 +#define Z_UTIL_DEC_1965 1964 +#define Z_UTIL_DEC_1966 1965 +#define Z_UTIL_DEC_1967 1966 +#define Z_UTIL_DEC_1968 1967 +#define Z_UTIL_DEC_1969 1968 +#define Z_UTIL_DEC_1970 1969 +#define Z_UTIL_DEC_1971 1970 +#define Z_UTIL_DEC_1972 1971 +#define Z_UTIL_DEC_1973 1972 +#define Z_UTIL_DEC_1974 1973 +#define Z_UTIL_DEC_1975 1974 +#define Z_UTIL_DEC_1976 1975 +#define Z_UTIL_DEC_1977 1976 +#define Z_UTIL_DEC_1978 1977 +#define Z_UTIL_DEC_1979 1978 +#define Z_UTIL_DEC_1980 1979 +#define Z_UTIL_DEC_1981 1980 +#define Z_UTIL_DEC_1982 1981 +#define Z_UTIL_DEC_1983 1982 +#define Z_UTIL_DEC_1984 1983 +#define Z_UTIL_DEC_1985 1984 +#define Z_UTIL_DEC_1986 1985 +#define Z_UTIL_DEC_1987 1986 +#define Z_UTIL_DEC_1988 1987 +#define Z_UTIL_DEC_1989 1988 +#define Z_UTIL_DEC_1990 1989 +#define Z_UTIL_DEC_1991 1990 +#define Z_UTIL_DEC_1992 1991 +#define Z_UTIL_DEC_1993 1992 +#define Z_UTIL_DEC_1994 1993 +#define Z_UTIL_DEC_1995 1994 +#define Z_UTIL_DEC_1996 1995 +#define Z_UTIL_DEC_1997 1996 +#define Z_UTIL_DEC_1998 1997 +#define Z_UTIL_DEC_1999 1998 +#define Z_UTIL_DEC_2000 1999 +#define Z_UTIL_DEC_2001 2000 +#define Z_UTIL_DEC_2002 2001 +#define Z_UTIL_DEC_2003 2002 +#define Z_UTIL_DEC_2004 2003 +#define Z_UTIL_DEC_2005 2004 +#define Z_UTIL_DEC_2006 2005 +#define Z_UTIL_DEC_2007 2006 +#define Z_UTIL_DEC_2008 2007 +#define Z_UTIL_DEC_2009 2008 +#define Z_UTIL_DEC_2010 2009 +#define Z_UTIL_DEC_2011 2010 +#define Z_UTIL_DEC_2012 2011 +#define Z_UTIL_DEC_2013 2012 +#define Z_UTIL_DEC_2014 2013 +#define Z_UTIL_DEC_2015 2014 +#define Z_UTIL_DEC_2016 2015 +#define Z_UTIL_DEC_2017 2016 +#define Z_UTIL_DEC_2018 2017 +#define Z_UTIL_DEC_2019 2018 +#define Z_UTIL_DEC_2020 2019 +#define Z_UTIL_DEC_2021 2020 +#define Z_UTIL_DEC_2022 2021 +#define Z_UTIL_DEC_2023 2022 +#define Z_UTIL_DEC_2024 2023 +#define Z_UTIL_DEC_2025 2024 +#define Z_UTIL_DEC_2026 2025 +#define Z_UTIL_DEC_2027 2026 +#define Z_UTIL_DEC_2028 2027 +#define Z_UTIL_DEC_2029 2028 +#define Z_UTIL_DEC_2030 2029 +#define Z_UTIL_DEC_2031 2030 +#define Z_UTIL_DEC_2032 2031 +#define Z_UTIL_DEC_2033 2032 +#define Z_UTIL_DEC_2034 2033 +#define Z_UTIL_DEC_2035 2034 +#define Z_UTIL_DEC_2036 2035 +#define Z_UTIL_DEC_2037 2036 +#define Z_UTIL_DEC_2038 2037 +#define Z_UTIL_DEC_2039 2038 +#define Z_UTIL_DEC_2040 2039 +#define Z_UTIL_DEC_2041 2040 +#define Z_UTIL_DEC_2042 2041 +#define Z_UTIL_DEC_2043 2042 +#define Z_UTIL_DEC_2044 2043 +#define Z_UTIL_DEC_2045 2044 +#define Z_UTIL_DEC_2046 2045 +#define Z_UTIL_DEC_2047 2046 +#define Z_UTIL_DEC_2048 2047 +#define Z_UTIL_DEC_2049 2048 +#define Z_UTIL_DEC_2050 2049 +#define Z_UTIL_DEC_2051 2050 +#define Z_UTIL_DEC_2052 2051 +#define Z_UTIL_DEC_2053 2052 +#define Z_UTIL_DEC_2054 2053 +#define Z_UTIL_DEC_2055 2054 +#define Z_UTIL_DEC_2056 2055 +#define Z_UTIL_DEC_2057 2056 +#define Z_UTIL_DEC_2058 2057 +#define Z_UTIL_DEC_2059 2058 +#define Z_UTIL_DEC_2060 2059 +#define Z_UTIL_DEC_2061 2060 +#define Z_UTIL_DEC_2062 2061 +#define Z_UTIL_DEC_2063 2062 +#define Z_UTIL_DEC_2064 2063 +#define Z_UTIL_DEC_2065 2064 +#define Z_UTIL_DEC_2066 2065 +#define Z_UTIL_DEC_2067 2066 +#define Z_UTIL_DEC_2068 2067 +#define Z_UTIL_DEC_2069 2068 +#define Z_UTIL_DEC_2070 2069 +#define Z_UTIL_DEC_2071 2070 +#define Z_UTIL_DEC_2072 2071 +#define Z_UTIL_DEC_2073 2072 +#define Z_UTIL_DEC_2074 2073 +#define Z_UTIL_DEC_2075 2074 +#define Z_UTIL_DEC_2076 2075 +#define Z_UTIL_DEC_2077 2076 +#define Z_UTIL_DEC_2078 2077 +#define Z_UTIL_DEC_2079 2078 +#define Z_UTIL_DEC_2080 2079 +#define Z_UTIL_DEC_2081 2080 +#define Z_UTIL_DEC_2082 2081 +#define Z_UTIL_DEC_2083 2082 +#define Z_UTIL_DEC_2084 2083 +#define Z_UTIL_DEC_2085 2084 +#define Z_UTIL_DEC_2086 2085 +#define Z_UTIL_DEC_2087 2086 +#define Z_UTIL_DEC_2088 2087 +#define Z_UTIL_DEC_2089 2088 +#define Z_UTIL_DEC_2090 2089 +#define Z_UTIL_DEC_2091 2090 +#define Z_UTIL_DEC_2092 2091 +#define Z_UTIL_DEC_2093 2092 +#define Z_UTIL_DEC_2094 2093 +#define Z_UTIL_DEC_2095 2094 +#define Z_UTIL_DEC_2096 2095 +#define Z_UTIL_DEC_2097 2096 +#define Z_UTIL_DEC_2098 2097 +#define Z_UTIL_DEC_2099 2098 +#define Z_UTIL_DEC_2100 2099 +#define Z_UTIL_DEC_2101 2100 +#define Z_UTIL_DEC_2102 2101 +#define Z_UTIL_DEC_2103 2102 +#define Z_UTIL_DEC_2104 2103 +#define Z_UTIL_DEC_2105 2104 +#define Z_UTIL_DEC_2106 2105 +#define Z_UTIL_DEC_2107 2106 +#define Z_UTIL_DEC_2108 2107 +#define Z_UTIL_DEC_2109 2108 +#define Z_UTIL_DEC_2110 2109 +#define Z_UTIL_DEC_2111 2110 +#define Z_UTIL_DEC_2112 2111 +#define Z_UTIL_DEC_2113 2112 +#define Z_UTIL_DEC_2114 2113 +#define Z_UTIL_DEC_2115 2114 +#define Z_UTIL_DEC_2116 2115 +#define Z_UTIL_DEC_2117 2116 +#define Z_UTIL_DEC_2118 2117 +#define Z_UTIL_DEC_2119 2118 +#define Z_UTIL_DEC_2120 2119 +#define Z_UTIL_DEC_2121 2120 +#define Z_UTIL_DEC_2122 2121 +#define Z_UTIL_DEC_2123 2122 +#define Z_UTIL_DEC_2124 2123 +#define Z_UTIL_DEC_2125 2124 +#define Z_UTIL_DEC_2126 2125 +#define Z_UTIL_DEC_2127 2126 +#define Z_UTIL_DEC_2128 2127 +#define Z_UTIL_DEC_2129 2128 +#define Z_UTIL_DEC_2130 2129 +#define Z_UTIL_DEC_2131 2130 +#define Z_UTIL_DEC_2132 2131 +#define Z_UTIL_DEC_2133 2132 +#define Z_UTIL_DEC_2134 2133 +#define Z_UTIL_DEC_2135 2134 +#define Z_UTIL_DEC_2136 2135 +#define Z_UTIL_DEC_2137 2136 +#define Z_UTIL_DEC_2138 2137 +#define Z_UTIL_DEC_2139 2138 +#define Z_UTIL_DEC_2140 2139 +#define Z_UTIL_DEC_2141 2140 +#define Z_UTIL_DEC_2142 2141 +#define Z_UTIL_DEC_2143 2142 +#define Z_UTIL_DEC_2144 2143 +#define Z_UTIL_DEC_2145 2144 +#define Z_UTIL_DEC_2146 2145 +#define Z_UTIL_DEC_2147 2146 +#define Z_UTIL_DEC_2148 2147 +#define Z_UTIL_DEC_2149 2148 +#define Z_UTIL_DEC_2150 2149 +#define Z_UTIL_DEC_2151 2150 +#define Z_UTIL_DEC_2152 2151 +#define Z_UTIL_DEC_2153 2152 +#define Z_UTIL_DEC_2154 2153 +#define Z_UTIL_DEC_2155 2154 +#define Z_UTIL_DEC_2156 2155 +#define Z_UTIL_DEC_2157 2156 +#define Z_UTIL_DEC_2158 2157 +#define Z_UTIL_DEC_2159 2158 +#define Z_UTIL_DEC_2160 2159 +#define Z_UTIL_DEC_2161 2160 +#define Z_UTIL_DEC_2162 2161 +#define Z_UTIL_DEC_2163 2162 +#define Z_UTIL_DEC_2164 2163 +#define Z_UTIL_DEC_2165 2164 +#define Z_UTIL_DEC_2166 2165 +#define Z_UTIL_DEC_2167 2166 +#define Z_UTIL_DEC_2168 2167 +#define Z_UTIL_DEC_2169 2168 +#define Z_UTIL_DEC_2170 2169 +#define Z_UTIL_DEC_2171 2170 +#define Z_UTIL_DEC_2172 2171 +#define Z_UTIL_DEC_2173 2172 +#define Z_UTIL_DEC_2174 2173 +#define Z_UTIL_DEC_2175 2174 +#define Z_UTIL_DEC_2176 2175 +#define Z_UTIL_DEC_2177 2176 +#define Z_UTIL_DEC_2178 2177 +#define Z_UTIL_DEC_2179 2178 +#define Z_UTIL_DEC_2180 2179 +#define Z_UTIL_DEC_2181 2180 +#define Z_UTIL_DEC_2182 2181 +#define Z_UTIL_DEC_2183 2182 +#define Z_UTIL_DEC_2184 2183 +#define Z_UTIL_DEC_2185 2184 +#define Z_UTIL_DEC_2186 2185 +#define Z_UTIL_DEC_2187 2186 +#define Z_UTIL_DEC_2188 2187 +#define Z_UTIL_DEC_2189 2188 +#define Z_UTIL_DEC_2190 2189 +#define Z_UTIL_DEC_2191 2190 +#define Z_UTIL_DEC_2192 2191 +#define Z_UTIL_DEC_2193 2192 +#define Z_UTIL_DEC_2194 2193 +#define Z_UTIL_DEC_2195 2194 +#define Z_UTIL_DEC_2196 2195 +#define Z_UTIL_DEC_2197 2196 +#define Z_UTIL_DEC_2198 2197 +#define Z_UTIL_DEC_2199 2198 +#define Z_UTIL_DEC_2200 2199 +#define Z_UTIL_DEC_2201 2200 +#define Z_UTIL_DEC_2202 2201 +#define Z_UTIL_DEC_2203 2202 +#define Z_UTIL_DEC_2204 2203 +#define Z_UTIL_DEC_2205 2204 +#define Z_UTIL_DEC_2206 2205 +#define Z_UTIL_DEC_2207 2206 +#define Z_UTIL_DEC_2208 2207 +#define Z_UTIL_DEC_2209 2208 +#define Z_UTIL_DEC_2210 2209 +#define Z_UTIL_DEC_2211 2210 +#define Z_UTIL_DEC_2212 2211 +#define Z_UTIL_DEC_2213 2212 +#define Z_UTIL_DEC_2214 2213 +#define Z_UTIL_DEC_2215 2214 +#define Z_UTIL_DEC_2216 2215 +#define Z_UTIL_DEC_2217 2216 +#define Z_UTIL_DEC_2218 2217 +#define Z_UTIL_DEC_2219 2218 +#define Z_UTIL_DEC_2220 2219 +#define Z_UTIL_DEC_2221 2220 +#define Z_UTIL_DEC_2222 2221 +#define Z_UTIL_DEC_2223 2222 +#define Z_UTIL_DEC_2224 2223 +#define Z_UTIL_DEC_2225 2224 +#define Z_UTIL_DEC_2226 2225 +#define Z_UTIL_DEC_2227 2226 +#define Z_UTIL_DEC_2228 2227 +#define Z_UTIL_DEC_2229 2228 +#define Z_UTIL_DEC_2230 2229 +#define Z_UTIL_DEC_2231 2230 +#define Z_UTIL_DEC_2232 2231 +#define Z_UTIL_DEC_2233 2232 +#define Z_UTIL_DEC_2234 2233 +#define Z_UTIL_DEC_2235 2234 +#define Z_UTIL_DEC_2236 2235 +#define Z_UTIL_DEC_2237 2236 +#define Z_UTIL_DEC_2238 2237 +#define Z_UTIL_DEC_2239 2238 +#define Z_UTIL_DEC_2240 2239 +#define Z_UTIL_DEC_2241 2240 +#define Z_UTIL_DEC_2242 2241 +#define Z_UTIL_DEC_2243 2242 +#define Z_UTIL_DEC_2244 2243 +#define Z_UTIL_DEC_2245 2244 +#define Z_UTIL_DEC_2246 2245 +#define Z_UTIL_DEC_2247 2246 +#define Z_UTIL_DEC_2248 2247 +#define Z_UTIL_DEC_2249 2248 +#define Z_UTIL_DEC_2250 2249 +#define Z_UTIL_DEC_2251 2250 +#define Z_UTIL_DEC_2252 2251 +#define Z_UTIL_DEC_2253 2252 +#define Z_UTIL_DEC_2254 2253 +#define Z_UTIL_DEC_2255 2254 +#define Z_UTIL_DEC_2256 2255 +#define Z_UTIL_DEC_2257 2256 +#define Z_UTIL_DEC_2258 2257 +#define Z_UTIL_DEC_2259 2258 +#define Z_UTIL_DEC_2260 2259 +#define Z_UTIL_DEC_2261 2260 +#define Z_UTIL_DEC_2262 2261 +#define Z_UTIL_DEC_2263 2262 +#define Z_UTIL_DEC_2264 2263 +#define Z_UTIL_DEC_2265 2264 +#define Z_UTIL_DEC_2266 2265 +#define Z_UTIL_DEC_2267 2266 +#define Z_UTIL_DEC_2268 2267 +#define Z_UTIL_DEC_2269 2268 +#define Z_UTIL_DEC_2270 2269 +#define Z_UTIL_DEC_2271 2270 +#define Z_UTIL_DEC_2272 2271 +#define Z_UTIL_DEC_2273 2272 +#define Z_UTIL_DEC_2274 2273 +#define Z_UTIL_DEC_2275 2274 +#define Z_UTIL_DEC_2276 2275 +#define Z_UTIL_DEC_2277 2276 +#define Z_UTIL_DEC_2278 2277 +#define Z_UTIL_DEC_2279 2278 +#define Z_UTIL_DEC_2280 2279 +#define Z_UTIL_DEC_2281 2280 +#define Z_UTIL_DEC_2282 2281 +#define Z_UTIL_DEC_2283 2282 +#define Z_UTIL_DEC_2284 2283 +#define Z_UTIL_DEC_2285 2284 +#define Z_UTIL_DEC_2286 2285 +#define Z_UTIL_DEC_2287 2286 +#define Z_UTIL_DEC_2288 2287 +#define Z_UTIL_DEC_2289 2288 +#define Z_UTIL_DEC_2290 2289 +#define Z_UTIL_DEC_2291 2290 +#define Z_UTIL_DEC_2292 2291 +#define Z_UTIL_DEC_2293 2292 +#define Z_UTIL_DEC_2294 2293 +#define Z_UTIL_DEC_2295 2294 +#define Z_UTIL_DEC_2296 2295 +#define Z_UTIL_DEC_2297 2296 +#define Z_UTIL_DEC_2298 2297 +#define Z_UTIL_DEC_2299 2298 +#define Z_UTIL_DEC_2300 2299 +#define Z_UTIL_DEC_2301 2300 +#define Z_UTIL_DEC_2302 2301 +#define Z_UTIL_DEC_2303 2302 +#define Z_UTIL_DEC_2304 2303 +#define Z_UTIL_DEC_2305 2304 +#define Z_UTIL_DEC_2306 2305 +#define Z_UTIL_DEC_2307 2306 +#define Z_UTIL_DEC_2308 2307 +#define Z_UTIL_DEC_2309 2308 +#define Z_UTIL_DEC_2310 2309 +#define Z_UTIL_DEC_2311 2310 +#define Z_UTIL_DEC_2312 2311 +#define Z_UTIL_DEC_2313 2312 +#define Z_UTIL_DEC_2314 2313 +#define Z_UTIL_DEC_2315 2314 +#define Z_UTIL_DEC_2316 2315 +#define Z_UTIL_DEC_2317 2316 +#define Z_UTIL_DEC_2318 2317 +#define Z_UTIL_DEC_2319 2318 +#define Z_UTIL_DEC_2320 2319 +#define Z_UTIL_DEC_2321 2320 +#define Z_UTIL_DEC_2322 2321 +#define Z_UTIL_DEC_2323 2322 +#define Z_UTIL_DEC_2324 2323 +#define Z_UTIL_DEC_2325 2324 +#define Z_UTIL_DEC_2326 2325 +#define Z_UTIL_DEC_2327 2326 +#define Z_UTIL_DEC_2328 2327 +#define Z_UTIL_DEC_2329 2328 +#define Z_UTIL_DEC_2330 2329 +#define Z_UTIL_DEC_2331 2330 +#define Z_UTIL_DEC_2332 2331 +#define Z_UTIL_DEC_2333 2332 +#define Z_UTIL_DEC_2334 2333 +#define Z_UTIL_DEC_2335 2334 +#define Z_UTIL_DEC_2336 2335 +#define Z_UTIL_DEC_2337 2336 +#define Z_UTIL_DEC_2338 2337 +#define Z_UTIL_DEC_2339 2338 +#define Z_UTIL_DEC_2340 2339 +#define Z_UTIL_DEC_2341 2340 +#define Z_UTIL_DEC_2342 2341 +#define Z_UTIL_DEC_2343 2342 +#define Z_UTIL_DEC_2344 2343 +#define Z_UTIL_DEC_2345 2344 +#define Z_UTIL_DEC_2346 2345 +#define Z_UTIL_DEC_2347 2346 +#define Z_UTIL_DEC_2348 2347 +#define Z_UTIL_DEC_2349 2348 +#define Z_UTIL_DEC_2350 2349 +#define Z_UTIL_DEC_2351 2350 +#define Z_UTIL_DEC_2352 2351 +#define Z_UTIL_DEC_2353 2352 +#define Z_UTIL_DEC_2354 2353 +#define Z_UTIL_DEC_2355 2354 +#define Z_UTIL_DEC_2356 2355 +#define Z_UTIL_DEC_2357 2356 +#define Z_UTIL_DEC_2358 2357 +#define Z_UTIL_DEC_2359 2358 +#define Z_UTIL_DEC_2360 2359 +#define Z_UTIL_DEC_2361 2360 +#define Z_UTIL_DEC_2362 2361 +#define Z_UTIL_DEC_2363 2362 +#define Z_UTIL_DEC_2364 2363 +#define Z_UTIL_DEC_2365 2364 +#define Z_UTIL_DEC_2366 2365 +#define Z_UTIL_DEC_2367 2366 +#define Z_UTIL_DEC_2368 2367 +#define Z_UTIL_DEC_2369 2368 +#define Z_UTIL_DEC_2370 2369 +#define Z_UTIL_DEC_2371 2370 +#define Z_UTIL_DEC_2372 2371 +#define Z_UTIL_DEC_2373 2372 +#define Z_UTIL_DEC_2374 2373 +#define Z_UTIL_DEC_2375 2374 +#define Z_UTIL_DEC_2376 2375 +#define Z_UTIL_DEC_2377 2376 +#define Z_UTIL_DEC_2378 2377 +#define Z_UTIL_DEC_2379 2378 +#define Z_UTIL_DEC_2380 2379 +#define Z_UTIL_DEC_2381 2380 +#define Z_UTIL_DEC_2382 2381 +#define Z_UTIL_DEC_2383 2382 +#define Z_UTIL_DEC_2384 2383 +#define Z_UTIL_DEC_2385 2384 +#define Z_UTIL_DEC_2386 2385 +#define Z_UTIL_DEC_2387 2386 +#define Z_UTIL_DEC_2388 2387 +#define Z_UTIL_DEC_2389 2388 +#define Z_UTIL_DEC_2390 2389 +#define Z_UTIL_DEC_2391 2390 +#define Z_UTIL_DEC_2392 2391 +#define Z_UTIL_DEC_2393 2392 +#define Z_UTIL_DEC_2394 2393 +#define Z_UTIL_DEC_2395 2394 +#define Z_UTIL_DEC_2396 2395 +#define Z_UTIL_DEC_2397 2396 +#define Z_UTIL_DEC_2398 2397 +#define Z_UTIL_DEC_2399 2398 +#define Z_UTIL_DEC_2400 2399 +#define Z_UTIL_DEC_2401 2400 +#define Z_UTIL_DEC_2402 2401 +#define Z_UTIL_DEC_2403 2402 +#define Z_UTIL_DEC_2404 2403 +#define Z_UTIL_DEC_2405 2404 +#define Z_UTIL_DEC_2406 2405 +#define Z_UTIL_DEC_2407 2406 +#define Z_UTIL_DEC_2408 2407 +#define Z_UTIL_DEC_2409 2408 +#define Z_UTIL_DEC_2410 2409 +#define Z_UTIL_DEC_2411 2410 +#define Z_UTIL_DEC_2412 2411 +#define Z_UTIL_DEC_2413 2412 +#define Z_UTIL_DEC_2414 2413 +#define Z_UTIL_DEC_2415 2414 +#define Z_UTIL_DEC_2416 2415 +#define Z_UTIL_DEC_2417 2416 +#define Z_UTIL_DEC_2418 2417 +#define Z_UTIL_DEC_2419 2418 +#define Z_UTIL_DEC_2420 2419 +#define Z_UTIL_DEC_2421 2420 +#define Z_UTIL_DEC_2422 2421 +#define Z_UTIL_DEC_2423 2422 +#define Z_UTIL_DEC_2424 2423 +#define Z_UTIL_DEC_2425 2424 +#define Z_UTIL_DEC_2426 2425 +#define Z_UTIL_DEC_2427 2426 +#define Z_UTIL_DEC_2428 2427 +#define Z_UTIL_DEC_2429 2428 +#define Z_UTIL_DEC_2430 2429 +#define Z_UTIL_DEC_2431 2430 +#define Z_UTIL_DEC_2432 2431 +#define Z_UTIL_DEC_2433 2432 +#define Z_UTIL_DEC_2434 2433 +#define Z_UTIL_DEC_2435 2434 +#define Z_UTIL_DEC_2436 2435 +#define Z_UTIL_DEC_2437 2436 +#define Z_UTIL_DEC_2438 2437 +#define Z_UTIL_DEC_2439 2438 +#define Z_UTIL_DEC_2440 2439 +#define Z_UTIL_DEC_2441 2440 +#define Z_UTIL_DEC_2442 2441 +#define Z_UTIL_DEC_2443 2442 +#define Z_UTIL_DEC_2444 2443 +#define Z_UTIL_DEC_2445 2444 +#define Z_UTIL_DEC_2446 2445 +#define Z_UTIL_DEC_2447 2446 +#define Z_UTIL_DEC_2448 2447 +#define Z_UTIL_DEC_2449 2448 +#define Z_UTIL_DEC_2450 2449 +#define Z_UTIL_DEC_2451 2450 +#define Z_UTIL_DEC_2452 2451 +#define Z_UTIL_DEC_2453 2452 +#define Z_UTIL_DEC_2454 2453 +#define Z_UTIL_DEC_2455 2454 +#define Z_UTIL_DEC_2456 2455 +#define Z_UTIL_DEC_2457 2456 +#define Z_UTIL_DEC_2458 2457 +#define Z_UTIL_DEC_2459 2458 +#define Z_UTIL_DEC_2460 2459 +#define Z_UTIL_DEC_2461 2460 +#define Z_UTIL_DEC_2462 2461 +#define Z_UTIL_DEC_2463 2462 +#define Z_UTIL_DEC_2464 2463 +#define Z_UTIL_DEC_2465 2464 +#define Z_UTIL_DEC_2466 2465 +#define Z_UTIL_DEC_2467 2466 +#define Z_UTIL_DEC_2468 2467 +#define Z_UTIL_DEC_2469 2468 +#define Z_UTIL_DEC_2470 2469 +#define Z_UTIL_DEC_2471 2470 +#define Z_UTIL_DEC_2472 2471 +#define Z_UTIL_DEC_2473 2472 +#define Z_UTIL_DEC_2474 2473 +#define Z_UTIL_DEC_2475 2474 +#define Z_UTIL_DEC_2476 2475 +#define Z_UTIL_DEC_2477 2476 +#define Z_UTIL_DEC_2478 2477 +#define Z_UTIL_DEC_2479 2478 +#define Z_UTIL_DEC_2480 2479 +#define Z_UTIL_DEC_2481 2480 +#define Z_UTIL_DEC_2482 2481 +#define Z_UTIL_DEC_2483 2482 +#define Z_UTIL_DEC_2484 2483 +#define Z_UTIL_DEC_2485 2484 +#define Z_UTIL_DEC_2486 2485 +#define Z_UTIL_DEC_2487 2486 +#define Z_UTIL_DEC_2488 2487 +#define Z_UTIL_DEC_2489 2488 +#define Z_UTIL_DEC_2490 2489 +#define Z_UTIL_DEC_2491 2490 +#define Z_UTIL_DEC_2492 2491 +#define Z_UTIL_DEC_2493 2492 +#define Z_UTIL_DEC_2494 2493 +#define Z_UTIL_DEC_2495 2494 +#define Z_UTIL_DEC_2496 2495 +#define Z_UTIL_DEC_2497 2496 +#define Z_UTIL_DEC_2498 2497 +#define Z_UTIL_DEC_2499 2498 +#define Z_UTIL_DEC_2500 2499 +#define Z_UTIL_DEC_2501 2500 +#define Z_UTIL_DEC_2502 2501 +#define Z_UTIL_DEC_2503 2502 +#define Z_UTIL_DEC_2504 2503 +#define Z_UTIL_DEC_2505 2504 +#define Z_UTIL_DEC_2506 2505 +#define Z_UTIL_DEC_2507 2506 +#define Z_UTIL_DEC_2508 2507 +#define Z_UTIL_DEC_2509 2508 +#define Z_UTIL_DEC_2510 2509 +#define Z_UTIL_DEC_2511 2510 +#define Z_UTIL_DEC_2512 2511 +#define Z_UTIL_DEC_2513 2512 +#define Z_UTIL_DEC_2514 2513 +#define Z_UTIL_DEC_2515 2514 +#define Z_UTIL_DEC_2516 2515 +#define Z_UTIL_DEC_2517 2516 +#define Z_UTIL_DEC_2518 2517 +#define Z_UTIL_DEC_2519 2518 +#define Z_UTIL_DEC_2520 2519 +#define Z_UTIL_DEC_2521 2520 +#define Z_UTIL_DEC_2522 2521 +#define Z_UTIL_DEC_2523 2522 +#define Z_UTIL_DEC_2524 2523 +#define Z_UTIL_DEC_2525 2524 +#define Z_UTIL_DEC_2526 2525 +#define Z_UTIL_DEC_2527 2526 +#define Z_UTIL_DEC_2528 2527 +#define Z_UTIL_DEC_2529 2528 +#define Z_UTIL_DEC_2530 2529 +#define Z_UTIL_DEC_2531 2530 +#define Z_UTIL_DEC_2532 2531 +#define Z_UTIL_DEC_2533 2532 +#define Z_UTIL_DEC_2534 2533 +#define Z_UTIL_DEC_2535 2534 +#define Z_UTIL_DEC_2536 2535 +#define Z_UTIL_DEC_2537 2536 +#define Z_UTIL_DEC_2538 2537 +#define Z_UTIL_DEC_2539 2538 +#define Z_UTIL_DEC_2540 2539 +#define Z_UTIL_DEC_2541 2540 +#define Z_UTIL_DEC_2542 2541 +#define Z_UTIL_DEC_2543 2542 +#define Z_UTIL_DEC_2544 2543 +#define Z_UTIL_DEC_2545 2544 +#define Z_UTIL_DEC_2546 2545 +#define Z_UTIL_DEC_2547 2546 +#define Z_UTIL_DEC_2548 2547 +#define Z_UTIL_DEC_2549 2548 +#define Z_UTIL_DEC_2550 2549 +#define Z_UTIL_DEC_2551 2550 +#define Z_UTIL_DEC_2552 2551 +#define Z_UTIL_DEC_2553 2552 +#define Z_UTIL_DEC_2554 2553 +#define Z_UTIL_DEC_2555 2554 +#define Z_UTIL_DEC_2556 2555 +#define Z_UTIL_DEC_2557 2556 +#define Z_UTIL_DEC_2558 2557 +#define Z_UTIL_DEC_2559 2558 +#define Z_UTIL_DEC_2560 2559 +#define Z_UTIL_DEC_2561 2560 +#define Z_UTIL_DEC_2562 2561 +#define Z_UTIL_DEC_2563 2562 +#define Z_UTIL_DEC_2564 2563 +#define Z_UTIL_DEC_2565 2564 +#define Z_UTIL_DEC_2566 2565 +#define Z_UTIL_DEC_2567 2566 +#define Z_UTIL_DEC_2568 2567 +#define Z_UTIL_DEC_2569 2568 +#define Z_UTIL_DEC_2570 2569 +#define Z_UTIL_DEC_2571 2570 +#define Z_UTIL_DEC_2572 2571 +#define Z_UTIL_DEC_2573 2572 +#define Z_UTIL_DEC_2574 2573 +#define Z_UTIL_DEC_2575 2574 +#define Z_UTIL_DEC_2576 2575 +#define Z_UTIL_DEC_2577 2576 +#define Z_UTIL_DEC_2578 2577 +#define Z_UTIL_DEC_2579 2578 +#define Z_UTIL_DEC_2580 2579 +#define Z_UTIL_DEC_2581 2580 +#define Z_UTIL_DEC_2582 2581 +#define Z_UTIL_DEC_2583 2582 +#define Z_UTIL_DEC_2584 2583 +#define Z_UTIL_DEC_2585 2584 +#define Z_UTIL_DEC_2586 2585 +#define Z_UTIL_DEC_2587 2586 +#define Z_UTIL_DEC_2588 2587 +#define Z_UTIL_DEC_2589 2588 +#define Z_UTIL_DEC_2590 2589 +#define Z_UTIL_DEC_2591 2590 +#define Z_UTIL_DEC_2592 2591 +#define Z_UTIL_DEC_2593 2592 +#define Z_UTIL_DEC_2594 2593 +#define Z_UTIL_DEC_2595 2594 +#define Z_UTIL_DEC_2596 2595 +#define Z_UTIL_DEC_2597 2596 +#define Z_UTIL_DEC_2598 2597 +#define Z_UTIL_DEC_2599 2598 +#define Z_UTIL_DEC_2600 2599 +#define Z_UTIL_DEC_2601 2600 +#define Z_UTIL_DEC_2602 2601 +#define Z_UTIL_DEC_2603 2602 +#define Z_UTIL_DEC_2604 2603 +#define Z_UTIL_DEC_2605 2604 +#define Z_UTIL_DEC_2606 2605 +#define Z_UTIL_DEC_2607 2606 +#define Z_UTIL_DEC_2608 2607 +#define Z_UTIL_DEC_2609 2608 +#define Z_UTIL_DEC_2610 2609 +#define Z_UTIL_DEC_2611 2610 +#define Z_UTIL_DEC_2612 2611 +#define Z_UTIL_DEC_2613 2612 +#define Z_UTIL_DEC_2614 2613 +#define Z_UTIL_DEC_2615 2614 +#define Z_UTIL_DEC_2616 2615 +#define Z_UTIL_DEC_2617 2616 +#define Z_UTIL_DEC_2618 2617 +#define Z_UTIL_DEC_2619 2618 +#define Z_UTIL_DEC_2620 2619 +#define Z_UTIL_DEC_2621 2620 +#define Z_UTIL_DEC_2622 2621 +#define Z_UTIL_DEC_2623 2622 +#define Z_UTIL_DEC_2624 2623 +#define Z_UTIL_DEC_2625 2624 +#define Z_UTIL_DEC_2626 2625 +#define Z_UTIL_DEC_2627 2626 +#define Z_UTIL_DEC_2628 2627 +#define Z_UTIL_DEC_2629 2628 +#define Z_UTIL_DEC_2630 2629 +#define Z_UTIL_DEC_2631 2630 +#define Z_UTIL_DEC_2632 2631 +#define Z_UTIL_DEC_2633 2632 +#define Z_UTIL_DEC_2634 2633 +#define Z_UTIL_DEC_2635 2634 +#define Z_UTIL_DEC_2636 2635 +#define Z_UTIL_DEC_2637 2636 +#define Z_UTIL_DEC_2638 2637 +#define Z_UTIL_DEC_2639 2638 +#define Z_UTIL_DEC_2640 2639 +#define Z_UTIL_DEC_2641 2640 +#define Z_UTIL_DEC_2642 2641 +#define Z_UTIL_DEC_2643 2642 +#define Z_UTIL_DEC_2644 2643 +#define Z_UTIL_DEC_2645 2644 +#define Z_UTIL_DEC_2646 2645 +#define Z_UTIL_DEC_2647 2646 +#define Z_UTIL_DEC_2648 2647 +#define Z_UTIL_DEC_2649 2648 +#define Z_UTIL_DEC_2650 2649 +#define Z_UTIL_DEC_2651 2650 +#define Z_UTIL_DEC_2652 2651 +#define Z_UTIL_DEC_2653 2652 +#define Z_UTIL_DEC_2654 2653 +#define Z_UTIL_DEC_2655 2654 +#define Z_UTIL_DEC_2656 2655 +#define Z_UTIL_DEC_2657 2656 +#define Z_UTIL_DEC_2658 2657 +#define Z_UTIL_DEC_2659 2658 +#define Z_UTIL_DEC_2660 2659 +#define Z_UTIL_DEC_2661 2660 +#define Z_UTIL_DEC_2662 2661 +#define Z_UTIL_DEC_2663 2662 +#define Z_UTIL_DEC_2664 2663 +#define Z_UTIL_DEC_2665 2664 +#define Z_UTIL_DEC_2666 2665 +#define Z_UTIL_DEC_2667 2666 +#define Z_UTIL_DEC_2668 2667 +#define Z_UTIL_DEC_2669 2668 +#define Z_UTIL_DEC_2670 2669 +#define Z_UTIL_DEC_2671 2670 +#define Z_UTIL_DEC_2672 2671 +#define Z_UTIL_DEC_2673 2672 +#define Z_UTIL_DEC_2674 2673 +#define Z_UTIL_DEC_2675 2674 +#define Z_UTIL_DEC_2676 2675 +#define Z_UTIL_DEC_2677 2676 +#define Z_UTIL_DEC_2678 2677 +#define Z_UTIL_DEC_2679 2678 +#define Z_UTIL_DEC_2680 2679 +#define Z_UTIL_DEC_2681 2680 +#define Z_UTIL_DEC_2682 2681 +#define Z_UTIL_DEC_2683 2682 +#define Z_UTIL_DEC_2684 2683 +#define Z_UTIL_DEC_2685 2684 +#define Z_UTIL_DEC_2686 2685 +#define Z_UTIL_DEC_2687 2686 +#define Z_UTIL_DEC_2688 2687 +#define Z_UTIL_DEC_2689 2688 +#define Z_UTIL_DEC_2690 2689 +#define Z_UTIL_DEC_2691 2690 +#define Z_UTIL_DEC_2692 2691 +#define Z_UTIL_DEC_2693 2692 +#define Z_UTIL_DEC_2694 2693 +#define Z_UTIL_DEC_2695 2694 +#define Z_UTIL_DEC_2696 2695 +#define Z_UTIL_DEC_2697 2696 +#define Z_UTIL_DEC_2698 2697 +#define Z_UTIL_DEC_2699 2698 +#define Z_UTIL_DEC_2700 2699 +#define Z_UTIL_DEC_2701 2700 +#define Z_UTIL_DEC_2702 2701 +#define Z_UTIL_DEC_2703 2702 +#define Z_UTIL_DEC_2704 2703 +#define Z_UTIL_DEC_2705 2704 +#define Z_UTIL_DEC_2706 2705 +#define Z_UTIL_DEC_2707 2706 +#define Z_UTIL_DEC_2708 2707 +#define Z_UTIL_DEC_2709 2708 +#define Z_UTIL_DEC_2710 2709 +#define Z_UTIL_DEC_2711 2710 +#define Z_UTIL_DEC_2712 2711 +#define Z_UTIL_DEC_2713 2712 +#define Z_UTIL_DEC_2714 2713 +#define Z_UTIL_DEC_2715 2714 +#define Z_UTIL_DEC_2716 2715 +#define Z_UTIL_DEC_2717 2716 +#define Z_UTIL_DEC_2718 2717 +#define Z_UTIL_DEC_2719 2718 +#define Z_UTIL_DEC_2720 2719 +#define Z_UTIL_DEC_2721 2720 +#define Z_UTIL_DEC_2722 2721 +#define Z_UTIL_DEC_2723 2722 +#define Z_UTIL_DEC_2724 2723 +#define Z_UTIL_DEC_2725 2724 +#define Z_UTIL_DEC_2726 2725 +#define Z_UTIL_DEC_2727 2726 +#define Z_UTIL_DEC_2728 2727 +#define Z_UTIL_DEC_2729 2728 +#define Z_UTIL_DEC_2730 2729 +#define Z_UTIL_DEC_2731 2730 +#define Z_UTIL_DEC_2732 2731 +#define Z_UTIL_DEC_2733 2732 +#define Z_UTIL_DEC_2734 2733 +#define Z_UTIL_DEC_2735 2734 +#define Z_UTIL_DEC_2736 2735 +#define Z_UTIL_DEC_2737 2736 +#define Z_UTIL_DEC_2738 2737 +#define Z_UTIL_DEC_2739 2738 +#define Z_UTIL_DEC_2740 2739 +#define Z_UTIL_DEC_2741 2740 +#define Z_UTIL_DEC_2742 2741 +#define Z_UTIL_DEC_2743 2742 +#define Z_UTIL_DEC_2744 2743 +#define Z_UTIL_DEC_2745 2744 +#define Z_UTIL_DEC_2746 2745 +#define Z_UTIL_DEC_2747 2746 +#define Z_UTIL_DEC_2748 2747 +#define Z_UTIL_DEC_2749 2748 +#define Z_UTIL_DEC_2750 2749 +#define Z_UTIL_DEC_2751 2750 +#define Z_UTIL_DEC_2752 2751 +#define Z_UTIL_DEC_2753 2752 +#define Z_UTIL_DEC_2754 2753 +#define Z_UTIL_DEC_2755 2754 +#define Z_UTIL_DEC_2756 2755 +#define Z_UTIL_DEC_2757 2756 +#define Z_UTIL_DEC_2758 2757 +#define Z_UTIL_DEC_2759 2758 +#define Z_UTIL_DEC_2760 2759 +#define Z_UTIL_DEC_2761 2760 +#define Z_UTIL_DEC_2762 2761 +#define Z_UTIL_DEC_2763 2762 +#define Z_UTIL_DEC_2764 2763 +#define Z_UTIL_DEC_2765 2764 +#define Z_UTIL_DEC_2766 2765 +#define Z_UTIL_DEC_2767 2766 +#define Z_UTIL_DEC_2768 2767 +#define Z_UTIL_DEC_2769 2768 +#define Z_UTIL_DEC_2770 2769 +#define Z_UTIL_DEC_2771 2770 +#define Z_UTIL_DEC_2772 2771 +#define Z_UTIL_DEC_2773 2772 +#define Z_UTIL_DEC_2774 2773 +#define Z_UTIL_DEC_2775 2774 +#define Z_UTIL_DEC_2776 2775 +#define Z_UTIL_DEC_2777 2776 +#define Z_UTIL_DEC_2778 2777 +#define Z_UTIL_DEC_2779 2778 +#define Z_UTIL_DEC_2780 2779 +#define Z_UTIL_DEC_2781 2780 +#define Z_UTIL_DEC_2782 2781 +#define Z_UTIL_DEC_2783 2782 +#define Z_UTIL_DEC_2784 2783 +#define Z_UTIL_DEC_2785 2784 +#define Z_UTIL_DEC_2786 2785 +#define Z_UTIL_DEC_2787 2786 +#define Z_UTIL_DEC_2788 2787 +#define Z_UTIL_DEC_2789 2788 +#define Z_UTIL_DEC_2790 2789 +#define Z_UTIL_DEC_2791 2790 +#define Z_UTIL_DEC_2792 2791 +#define Z_UTIL_DEC_2793 2792 +#define Z_UTIL_DEC_2794 2793 +#define Z_UTIL_DEC_2795 2794 +#define Z_UTIL_DEC_2796 2795 +#define Z_UTIL_DEC_2797 2796 +#define Z_UTIL_DEC_2798 2797 +#define Z_UTIL_DEC_2799 2798 +#define Z_UTIL_DEC_2800 2799 +#define Z_UTIL_DEC_2801 2800 +#define Z_UTIL_DEC_2802 2801 +#define Z_UTIL_DEC_2803 2802 +#define Z_UTIL_DEC_2804 2803 +#define Z_UTIL_DEC_2805 2804 +#define Z_UTIL_DEC_2806 2805 +#define Z_UTIL_DEC_2807 2806 +#define Z_UTIL_DEC_2808 2807 +#define Z_UTIL_DEC_2809 2808 +#define Z_UTIL_DEC_2810 2809 +#define Z_UTIL_DEC_2811 2810 +#define Z_UTIL_DEC_2812 2811 +#define Z_UTIL_DEC_2813 2812 +#define Z_UTIL_DEC_2814 2813 +#define Z_UTIL_DEC_2815 2814 +#define Z_UTIL_DEC_2816 2815 +#define Z_UTIL_DEC_2817 2816 +#define Z_UTIL_DEC_2818 2817 +#define Z_UTIL_DEC_2819 2818 +#define Z_UTIL_DEC_2820 2819 +#define Z_UTIL_DEC_2821 2820 +#define Z_UTIL_DEC_2822 2821 +#define Z_UTIL_DEC_2823 2822 +#define Z_UTIL_DEC_2824 2823 +#define Z_UTIL_DEC_2825 2824 +#define Z_UTIL_DEC_2826 2825 +#define Z_UTIL_DEC_2827 2826 +#define Z_UTIL_DEC_2828 2827 +#define Z_UTIL_DEC_2829 2828 +#define Z_UTIL_DEC_2830 2829 +#define Z_UTIL_DEC_2831 2830 +#define Z_UTIL_DEC_2832 2831 +#define Z_UTIL_DEC_2833 2832 +#define Z_UTIL_DEC_2834 2833 +#define Z_UTIL_DEC_2835 2834 +#define Z_UTIL_DEC_2836 2835 +#define Z_UTIL_DEC_2837 2836 +#define Z_UTIL_DEC_2838 2837 +#define Z_UTIL_DEC_2839 2838 +#define Z_UTIL_DEC_2840 2839 +#define Z_UTIL_DEC_2841 2840 +#define Z_UTIL_DEC_2842 2841 +#define Z_UTIL_DEC_2843 2842 +#define Z_UTIL_DEC_2844 2843 +#define Z_UTIL_DEC_2845 2844 +#define Z_UTIL_DEC_2846 2845 +#define Z_UTIL_DEC_2847 2846 +#define Z_UTIL_DEC_2848 2847 +#define Z_UTIL_DEC_2849 2848 +#define Z_UTIL_DEC_2850 2849 +#define Z_UTIL_DEC_2851 2850 +#define Z_UTIL_DEC_2852 2851 +#define Z_UTIL_DEC_2853 2852 +#define Z_UTIL_DEC_2854 2853 +#define Z_UTIL_DEC_2855 2854 +#define Z_UTIL_DEC_2856 2855 +#define Z_UTIL_DEC_2857 2856 +#define Z_UTIL_DEC_2858 2857 +#define Z_UTIL_DEC_2859 2858 +#define Z_UTIL_DEC_2860 2859 +#define Z_UTIL_DEC_2861 2860 +#define Z_UTIL_DEC_2862 2861 +#define Z_UTIL_DEC_2863 2862 +#define Z_UTIL_DEC_2864 2863 +#define Z_UTIL_DEC_2865 2864 +#define Z_UTIL_DEC_2866 2865 +#define Z_UTIL_DEC_2867 2866 +#define Z_UTIL_DEC_2868 2867 +#define Z_UTIL_DEC_2869 2868 +#define Z_UTIL_DEC_2870 2869 +#define Z_UTIL_DEC_2871 2870 +#define Z_UTIL_DEC_2872 2871 +#define Z_UTIL_DEC_2873 2872 +#define Z_UTIL_DEC_2874 2873 +#define Z_UTIL_DEC_2875 2874 +#define Z_UTIL_DEC_2876 2875 +#define Z_UTIL_DEC_2877 2876 +#define Z_UTIL_DEC_2878 2877 +#define Z_UTIL_DEC_2879 2878 +#define Z_UTIL_DEC_2880 2879 +#define Z_UTIL_DEC_2881 2880 +#define Z_UTIL_DEC_2882 2881 +#define Z_UTIL_DEC_2883 2882 +#define Z_UTIL_DEC_2884 2883 +#define Z_UTIL_DEC_2885 2884 +#define Z_UTIL_DEC_2886 2885 +#define Z_UTIL_DEC_2887 2886 +#define Z_UTIL_DEC_2888 2887 +#define Z_UTIL_DEC_2889 2888 +#define Z_UTIL_DEC_2890 2889 +#define Z_UTIL_DEC_2891 2890 +#define Z_UTIL_DEC_2892 2891 +#define Z_UTIL_DEC_2893 2892 +#define Z_UTIL_DEC_2894 2893 +#define Z_UTIL_DEC_2895 2894 +#define Z_UTIL_DEC_2896 2895 +#define Z_UTIL_DEC_2897 2896 +#define Z_UTIL_DEC_2898 2897 +#define Z_UTIL_DEC_2899 2898 +#define Z_UTIL_DEC_2900 2899 +#define Z_UTIL_DEC_2901 2900 +#define Z_UTIL_DEC_2902 2901 +#define Z_UTIL_DEC_2903 2902 +#define Z_UTIL_DEC_2904 2903 +#define Z_UTIL_DEC_2905 2904 +#define Z_UTIL_DEC_2906 2905 +#define Z_UTIL_DEC_2907 2906 +#define Z_UTIL_DEC_2908 2907 +#define Z_UTIL_DEC_2909 2908 +#define Z_UTIL_DEC_2910 2909 +#define Z_UTIL_DEC_2911 2910 +#define Z_UTIL_DEC_2912 2911 +#define Z_UTIL_DEC_2913 2912 +#define Z_UTIL_DEC_2914 2913 +#define Z_UTIL_DEC_2915 2914 +#define Z_UTIL_DEC_2916 2915 +#define Z_UTIL_DEC_2917 2916 +#define Z_UTIL_DEC_2918 2917 +#define Z_UTIL_DEC_2919 2918 +#define Z_UTIL_DEC_2920 2919 +#define Z_UTIL_DEC_2921 2920 +#define Z_UTIL_DEC_2922 2921 +#define Z_UTIL_DEC_2923 2922 +#define Z_UTIL_DEC_2924 2923 +#define Z_UTIL_DEC_2925 2924 +#define Z_UTIL_DEC_2926 2925 +#define Z_UTIL_DEC_2927 2926 +#define Z_UTIL_DEC_2928 2927 +#define Z_UTIL_DEC_2929 2928 +#define Z_UTIL_DEC_2930 2929 +#define Z_UTIL_DEC_2931 2930 +#define Z_UTIL_DEC_2932 2931 +#define Z_UTIL_DEC_2933 2932 +#define Z_UTIL_DEC_2934 2933 +#define Z_UTIL_DEC_2935 2934 +#define Z_UTIL_DEC_2936 2935 +#define Z_UTIL_DEC_2937 2936 +#define Z_UTIL_DEC_2938 2937 +#define Z_UTIL_DEC_2939 2938 +#define Z_UTIL_DEC_2940 2939 +#define Z_UTIL_DEC_2941 2940 +#define Z_UTIL_DEC_2942 2941 +#define Z_UTIL_DEC_2943 2942 +#define Z_UTIL_DEC_2944 2943 +#define Z_UTIL_DEC_2945 2944 +#define Z_UTIL_DEC_2946 2945 +#define Z_UTIL_DEC_2947 2946 +#define Z_UTIL_DEC_2948 2947 +#define Z_UTIL_DEC_2949 2948 +#define Z_UTIL_DEC_2950 2949 +#define Z_UTIL_DEC_2951 2950 +#define Z_UTIL_DEC_2952 2951 +#define Z_UTIL_DEC_2953 2952 +#define Z_UTIL_DEC_2954 2953 +#define Z_UTIL_DEC_2955 2954 +#define Z_UTIL_DEC_2956 2955 +#define Z_UTIL_DEC_2957 2956 +#define Z_UTIL_DEC_2958 2957 +#define Z_UTIL_DEC_2959 2958 +#define Z_UTIL_DEC_2960 2959 +#define Z_UTIL_DEC_2961 2960 +#define Z_UTIL_DEC_2962 2961 +#define Z_UTIL_DEC_2963 2962 +#define Z_UTIL_DEC_2964 2963 +#define Z_UTIL_DEC_2965 2964 +#define Z_UTIL_DEC_2966 2965 +#define Z_UTIL_DEC_2967 2966 +#define Z_UTIL_DEC_2968 2967 +#define Z_UTIL_DEC_2969 2968 +#define Z_UTIL_DEC_2970 2969 +#define Z_UTIL_DEC_2971 2970 +#define Z_UTIL_DEC_2972 2971 +#define Z_UTIL_DEC_2973 2972 +#define Z_UTIL_DEC_2974 2973 +#define Z_UTIL_DEC_2975 2974 +#define Z_UTIL_DEC_2976 2975 +#define Z_UTIL_DEC_2977 2976 +#define Z_UTIL_DEC_2978 2977 +#define Z_UTIL_DEC_2979 2978 +#define Z_UTIL_DEC_2980 2979 +#define Z_UTIL_DEC_2981 2980 +#define Z_UTIL_DEC_2982 2981 +#define Z_UTIL_DEC_2983 2982 +#define Z_UTIL_DEC_2984 2983 +#define Z_UTIL_DEC_2985 2984 +#define Z_UTIL_DEC_2986 2985 +#define Z_UTIL_DEC_2987 2986 +#define Z_UTIL_DEC_2988 2987 +#define Z_UTIL_DEC_2989 2988 +#define Z_UTIL_DEC_2990 2989 +#define Z_UTIL_DEC_2991 2990 +#define Z_UTIL_DEC_2992 2991 +#define Z_UTIL_DEC_2993 2992 +#define Z_UTIL_DEC_2994 2993 +#define Z_UTIL_DEC_2995 2994 +#define Z_UTIL_DEC_2996 2995 +#define Z_UTIL_DEC_2997 2996 +#define Z_UTIL_DEC_2998 2997 +#define Z_UTIL_DEC_2999 2998 +#define Z_UTIL_DEC_3000 2999 +#define Z_UTIL_DEC_3001 3000 +#define Z_UTIL_DEC_3002 3001 +#define Z_UTIL_DEC_3003 3002 +#define Z_UTIL_DEC_3004 3003 +#define Z_UTIL_DEC_3005 3004 +#define Z_UTIL_DEC_3006 3005 +#define Z_UTIL_DEC_3007 3006 +#define Z_UTIL_DEC_3008 3007 +#define Z_UTIL_DEC_3009 3008 +#define Z_UTIL_DEC_3010 3009 +#define Z_UTIL_DEC_3011 3010 +#define Z_UTIL_DEC_3012 3011 +#define Z_UTIL_DEC_3013 3012 +#define Z_UTIL_DEC_3014 3013 +#define Z_UTIL_DEC_3015 3014 +#define Z_UTIL_DEC_3016 3015 +#define Z_UTIL_DEC_3017 3016 +#define Z_UTIL_DEC_3018 3017 +#define Z_UTIL_DEC_3019 3018 +#define Z_UTIL_DEC_3020 3019 +#define Z_UTIL_DEC_3021 3020 +#define Z_UTIL_DEC_3022 3021 +#define Z_UTIL_DEC_3023 3022 +#define Z_UTIL_DEC_3024 3023 +#define Z_UTIL_DEC_3025 3024 +#define Z_UTIL_DEC_3026 3025 +#define Z_UTIL_DEC_3027 3026 +#define Z_UTIL_DEC_3028 3027 +#define Z_UTIL_DEC_3029 3028 +#define Z_UTIL_DEC_3030 3029 +#define Z_UTIL_DEC_3031 3030 +#define Z_UTIL_DEC_3032 3031 +#define Z_UTIL_DEC_3033 3032 +#define Z_UTIL_DEC_3034 3033 +#define Z_UTIL_DEC_3035 3034 +#define Z_UTIL_DEC_3036 3035 +#define Z_UTIL_DEC_3037 3036 +#define Z_UTIL_DEC_3038 3037 +#define Z_UTIL_DEC_3039 3038 +#define Z_UTIL_DEC_3040 3039 +#define Z_UTIL_DEC_3041 3040 +#define Z_UTIL_DEC_3042 3041 +#define Z_UTIL_DEC_3043 3042 +#define Z_UTIL_DEC_3044 3043 +#define Z_UTIL_DEC_3045 3044 +#define Z_UTIL_DEC_3046 3045 +#define Z_UTIL_DEC_3047 3046 +#define Z_UTIL_DEC_3048 3047 +#define Z_UTIL_DEC_3049 3048 +#define Z_UTIL_DEC_3050 3049 +#define Z_UTIL_DEC_3051 3050 +#define Z_UTIL_DEC_3052 3051 +#define Z_UTIL_DEC_3053 3052 +#define Z_UTIL_DEC_3054 3053 +#define Z_UTIL_DEC_3055 3054 +#define Z_UTIL_DEC_3056 3055 +#define Z_UTIL_DEC_3057 3056 +#define Z_UTIL_DEC_3058 3057 +#define Z_UTIL_DEC_3059 3058 +#define Z_UTIL_DEC_3060 3059 +#define Z_UTIL_DEC_3061 3060 +#define Z_UTIL_DEC_3062 3061 +#define Z_UTIL_DEC_3063 3062 +#define Z_UTIL_DEC_3064 3063 +#define Z_UTIL_DEC_3065 3064 +#define Z_UTIL_DEC_3066 3065 +#define Z_UTIL_DEC_3067 3066 +#define Z_UTIL_DEC_3068 3067 +#define Z_UTIL_DEC_3069 3068 +#define Z_UTIL_DEC_3070 3069 +#define Z_UTIL_DEC_3071 3070 +#define Z_UTIL_DEC_3072 3071 +#define Z_UTIL_DEC_3073 3072 +#define Z_UTIL_DEC_3074 3073 +#define Z_UTIL_DEC_3075 3074 +#define Z_UTIL_DEC_3076 3075 +#define Z_UTIL_DEC_3077 3076 +#define Z_UTIL_DEC_3078 3077 +#define Z_UTIL_DEC_3079 3078 +#define Z_UTIL_DEC_3080 3079 +#define Z_UTIL_DEC_3081 3080 +#define Z_UTIL_DEC_3082 3081 +#define Z_UTIL_DEC_3083 3082 +#define Z_UTIL_DEC_3084 3083 +#define Z_UTIL_DEC_3085 3084 +#define Z_UTIL_DEC_3086 3085 +#define Z_UTIL_DEC_3087 3086 +#define Z_UTIL_DEC_3088 3087 +#define Z_UTIL_DEC_3089 3088 +#define Z_UTIL_DEC_3090 3089 +#define Z_UTIL_DEC_3091 3090 +#define Z_UTIL_DEC_3092 3091 +#define Z_UTIL_DEC_3093 3092 +#define Z_UTIL_DEC_3094 3093 +#define Z_UTIL_DEC_3095 3094 +#define Z_UTIL_DEC_3096 3095 +#define Z_UTIL_DEC_3097 3096 +#define Z_UTIL_DEC_3098 3097 +#define Z_UTIL_DEC_3099 3098 +#define Z_UTIL_DEC_3100 3099 +#define Z_UTIL_DEC_3101 3100 +#define Z_UTIL_DEC_3102 3101 +#define Z_UTIL_DEC_3103 3102 +#define Z_UTIL_DEC_3104 3103 +#define Z_UTIL_DEC_3105 3104 +#define Z_UTIL_DEC_3106 3105 +#define Z_UTIL_DEC_3107 3106 +#define Z_UTIL_DEC_3108 3107 +#define Z_UTIL_DEC_3109 3108 +#define Z_UTIL_DEC_3110 3109 +#define Z_UTIL_DEC_3111 3110 +#define Z_UTIL_DEC_3112 3111 +#define Z_UTIL_DEC_3113 3112 +#define Z_UTIL_DEC_3114 3113 +#define Z_UTIL_DEC_3115 3114 +#define Z_UTIL_DEC_3116 3115 +#define Z_UTIL_DEC_3117 3116 +#define Z_UTIL_DEC_3118 3117 +#define Z_UTIL_DEC_3119 3118 +#define Z_UTIL_DEC_3120 3119 +#define Z_UTIL_DEC_3121 3120 +#define Z_UTIL_DEC_3122 3121 +#define Z_UTIL_DEC_3123 3122 +#define Z_UTIL_DEC_3124 3123 +#define Z_UTIL_DEC_3125 3124 +#define Z_UTIL_DEC_3126 3125 +#define Z_UTIL_DEC_3127 3126 +#define Z_UTIL_DEC_3128 3127 +#define Z_UTIL_DEC_3129 3128 +#define Z_UTIL_DEC_3130 3129 +#define Z_UTIL_DEC_3131 3130 +#define Z_UTIL_DEC_3132 3131 +#define Z_UTIL_DEC_3133 3132 +#define Z_UTIL_DEC_3134 3133 +#define Z_UTIL_DEC_3135 3134 +#define Z_UTIL_DEC_3136 3135 +#define Z_UTIL_DEC_3137 3136 +#define Z_UTIL_DEC_3138 3137 +#define Z_UTIL_DEC_3139 3138 +#define Z_UTIL_DEC_3140 3139 +#define Z_UTIL_DEC_3141 3140 +#define Z_UTIL_DEC_3142 3141 +#define Z_UTIL_DEC_3143 3142 +#define Z_UTIL_DEC_3144 3143 +#define Z_UTIL_DEC_3145 3144 +#define Z_UTIL_DEC_3146 3145 +#define Z_UTIL_DEC_3147 3146 +#define Z_UTIL_DEC_3148 3147 +#define Z_UTIL_DEC_3149 3148 +#define Z_UTIL_DEC_3150 3149 +#define Z_UTIL_DEC_3151 3150 +#define Z_UTIL_DEC_3152 3151 +#define Z_UTIL_DEC_3153 3152 +#define Z_UTIL_DEC_3154 3153 +#define Z_UTIL_DEC_3155 3154 +#define Z_UTIL_DEC_3156 3155 +#define Z_UTIL_DEC_3157 3156 +#define Z_UTIL_DEC_3158 3157 +#define Z_UTIL_DEC_3159 3158 +#define Z_UTIL_DEC_3160 3159 +#define Z_UTIL_DEC_3161 3160 +#define Z_UTIL_DEC_3162 3161 +#define Z_UTIL_DEC_3163 3162 +#define Z_UTIL_DEC_3164 3163 +#define Z_UTIL_DEC_3165 3164 +#define Z_UTIL_DEC_3166 3165 +#define Z_UTIL_DEC_3167 3166 +#define Z_UTIL_DEC_3168 3167 +#define Z_UTIL_DEC_3169 3168 +#define Z_UTIL_DEC_3170 3169 +#define Z_UTIL_DEC_3171 3170 +#define Z_UTIL_DEC_3172 3171 +#define Z_UTIL_DEC_3173 3172 +#define Z_UTIL_DEC_3174 3173 +#define Z_UTIL_DEC_3175 3174 +#define Z_UTIL_DEC_3176 3175 +#define Z_UTIL_DEC_3177 3176 +#define Z_UTIL_DEC_3178 3177 +#define Z_UTIL_DEC_3179 3178 +#define Z_UTIL_DEC_3180 3179 +#define Z_UTIL_DEC_3181 3180 +#define Z_UTIL_DEC_3182 3181 +#define Z_UTIL_DEC_3183 3182 +#define Z_UTIL_DEC_3184 3183 +#define Z_UTIL_DEC_3185 3184 +#define Z_UTIL_DEC_3186 3185 +#define Z_UTIL_DEC_3187 3186 +#define Z_UTIL_DEC_3188 3187 +#define Z_UTIL_DEC_3189 3188 +#define Z_UTIL_DEC_3190 3189 +#define Z_UTIL_DEC_3191 3190 +#define Z_UTIL_DEC_3192 3191 +#define Z_UTIL_DEC_3193 3192 +#define Z_UTIL_DEC_3194 3193 +#define Z_UTIL_DEC_3195 3194 +#define Z_UTIL_DEC_3196 3195 +#define Z_UTIL_DEC_3197 3196 +#define Z_UTIL_DEC_3198 3197 +#define Z_UTIL_DEC_3199 3198 +#define Z_UTIL_DEC_3200 3199 +#define Z_UTIL_DEC_3201 3200 +#define Z_UTIL_DEC_3202 3201 +#define Z_UTIL_DEC_3203 3202 +#define Z_UTIL_DEC_3204 3203 +#define Z_UTIL_DEC_3205 3204 +#define Z_UTIL_DEC_3206 3205 +#define Z_UTIL_DEC_3207 3206 +#define Z_UTIL_DEC_3208 3207 +#define Z_UTIL_DEC_3209 3208 +#define Z_UTIL_DEC_3210 3209 +#define Z_UTIL_DEC_3211 3210 +#define Z_UTIL_DEC_3212 3211 +#define Z_UTIL_DEC_3213 3212 +#define Z_UTIL_DEC_3214 3213 +#define Z_UTIL_DEC_3215 3214 +#define Z_UTIL_DEC_3216 3215 +#define Z_UTIL_DEC_3217 3216 +#define Z_UTIL_DEC_3218 3217 +#define Z_UTIL_DEC_3219 3218 +#define Z_UTIL_DEC_3220 3219 +#define Z_UTIL_DEC_3221 3220 +#define Z_UTIL_DEC_3222 3221 +#define Z_UTIL_DEC_3223 3222 +#define Z_UTIL_DEC_3224 3223 +#define Z_UTIL_DEC_3225 3224 +#define Z_UTIL_DEC_3226 3225 +#define Z_UTIL_DEC_3227 3226 +#define Z_UTIL_DEC_3228 3227 +#define Z_UTIL_DEC_3229 3228 +#define Z_UTIL_DEC_3230 3229 +#define Z_UTIL_DEC_3231 3230 +#define Z_UTIL_DEC_3232 3231 +#define Z_UTIL_DEC_3233 3232 +#define Z_UTIL_DEC_3234 3233 +#define Z_UTIL_DEC_3235 3234 +#define Z_UTIL_DEC_3236 3235 +#define Z_UTIL_DEC_3237 3236 +#define Z_UTIL_DEC_3238 3237 +#define Z_UTIL_DEC_3239 3238 +#define Z_UTIL_DEC_3240 3239 +#define Z_UTIL_DEC_3241 3240 +#define Z_UTIL_DEC_3242 3241 +#define Z_UTIL_DEC_3243 3242 +#define Z_UTIL_DEC_3244 3243 +#define Z_UTIL_DEC_3245 3244 +#define Z_UTIL_DEC_3246 3245 +#define Z_UTIL_DEC_3247 3246 +#define Z_UTIL_DEC_3248 3247 +#define Z_UTIL_DEC_3249 3248 +#define Z_UTIL_DEC_3250 3249 +#define Z_UTIL_DEC_3251 3250 +#define Z_UTIL_DEC_3252 3251 +#define Z_UTIL_DEC_3253 3252 +#define Z_UTIL_DEC_3254 3253 +#define Z_UTIL_DEC_3255 3254 +#define Z_UTIL_DEC_3256 3255 +#define Z_UTIL_DEC_3257 3256 +#define Z_UTIL_DEC_3258 3257 +#define Z_UTIL_DEC_3259 3258 +#define Z_UTIL_DEC_3260 3259 +#define Z_UTIL_DEC_3261 3260 +#define Z_UTIL_DEC_3262 3261 +#define Z_UTIL_DEC_3263 3262 +#define Z_UTIL_DEC_3264 3263 +#define Z_UTIL_DEC_3265 3264 +#define Z_UTIL_DEC_3266 3265 +#define Z_UTIL_DEC_3267 3266 +#define Z_UTIL_DEC_3268 3267 +#define Z_UTIL_DEC_3269 3268 +#define Z_UTIL_DEC_3270 3269 +#define Z_UTIL_DEC_3271 3270 +#define Z_UTIL_DEC_3272 3271 +#define Z_UTIL_DEC_3273 3272 +#define Z_UTIL_DEC_3274 3273 +#define Z_UTIL_DEC_3275 3274 +#define Z_UTIL_DEC_3276 3275 +#define Z_UTIL_DEC_3277 3276 +#define Z_UTIL_DEC_3278 3277 +#define Z_UTIL_DEC_3279 3278 +#define Z_UTIL_DEC_3280 3279 +#define Z_UTIL_DEC_3281 3280 +#define Z_UTIL_DEC_3282 3281 +#define Z_UTIL_DEC_3283 3282 +#define Z_UTIL_DEC_3284 3283 +#define Z_UTIL_DEC_3285 3284 +#define Z_UTIL_DEC_3286 3285 +#define Z_UTIL_DEC_3287 3286 +#define Z_UTIL_DEC_3288 3287 +#define Z_UTIL_DEC_3289 3288 +#define Z_UTIL_DEC_3290 3289 +#define Z_UTIL_DEC_3291 3290 +#define Z_UTIL_DEC_3292 3291 +#define Z_UTIL_DEC_3293 3292 +#define Z_UTIL_DEC_3294 3293 +#define Z_UTIL_DEC_3295 3294 +#define Z_UTIL_DEC_3296 3295 +#define Z_UTIL_DEC_3297 3296 +#define Z_UTIL_DEC_3298 3297 +#define Z_UTIL_DEC_3299 3298 +#define Z_UTIL_DEC_3300 3299 +#define Z_UTIL_DEC_3301 3300 +#define Z_UTIL_DEC_3302 3301 +#define Z_UTIL_DEC_3303 3302 +#define Z_UTIL_DEC_3304 3303 +#define Z_UTIL_DEC_3305 3304 +#define Z_UTIL_DEC_3306 3305 +#define Z_UTIL_DEC_3307 3306 +#define Z_UTIL_DEC_3308 3307 +#define Z_UTIL_DEC_3309 3308 +#define Z_UTIL_DEC_3310 3309 +#define Z_UTIL_DEC_3311 3310 +#define Z_UTIL_DEC_3312 3311 +#define Z_UTIL_DEC_3313 3312 +#define Z_UTIL_DEC_3314 3313 +#define Z_UTIL_DEC_3315 3314 +#define Z_UTIL_DEC_3316 3315 +#define Z_UTIL_DEC_3317 3316 +#define Z_UTIL_DEC_3318 3317 +#define Z_UTIL_DEC_3319 3318 +#define Z_UTIL_DEC_3320 3319 +#define Z_UTIL_DEC_3321 3320 +#define Z_UTIL_DEC_3322 3321 +#define Z_UTIL_DEC_3323 3322 +#define Z_UTIL_DEC_3324 3323 +#define Z_UTIL_DEC_3325 3324 +#define Z_UTIL_DEC_3326 3325 +#define Z_UTIL_DEC_3327 3326 +#define Z_UTIL_DEC_3328 3327 +#define Z_UTIL_DEC_3329 3328 +#define Z_UTIL_DEC_3330 3329 +#define Z_UTIL_DEC_3331 3330 +#define Z_UTIL_DEC_3332 3331 +#define Z_UTIL_DEC_3333 3332 +#define Z_UTIL_DEC_3334 3333 +#define Z_UTIL_DEC_3335 3334 +#define Z_UTIL_DEC_3336 3335 +#define Z_UTIL_DEC_3337 3336 +#define Z_UTIL_DEC_3338 3337 +#define Z_UTIL_DEC_3339 3338 +#define Z_UTIL_DEC_3340 3339 +#define Z_UTIL_DEC_3341 3340 +#define Z_UTIL_DEC_3342 3341 +#define Z_UTIL_DEC_3343 3342 +#define Z_UTIL_DEC_3344 3343 +#define Z_UTIL_DEC_3345 3344 +#define Z_UTIL_DEC_3346 3345 +#define Z_UTIL_DEC_3347 3346 +#define Z_UTIL_DEC_3348 3347 +#define Z_UTIL_DEC_3349 3348 +#define Z_UTIL_DEC_3350 3349 +#define Z_UTIL_DEC_3351 3350 +#define Z_UTIL_DEC_3352 3351 +#define Z_UTIL_DEC_3353 3352 +#define Z_UTIL_DEC_3354 3353 +#define Z_UTIL_DEC_3355 3354 +#define Z_UTIL_DEC_3356 3355 +#define Z_UTIL_DEC_3357 3356 +#define Z_UTIL_DEC_3358 3357 +#define Z_UTIL_DEC_3359 3358 +#define Z_UTIL_DEC_3360 3359 +#define Z_UTIL_DEC_3361 3360 +#define Z_UTIL_DEC_3362 3361 +#define Z_UTIL_DEC_3363 3362 +#define Z_UTIL_DEC_3364 3363 +#define Z_UTIL_DEC_3365 3364 +#define Z_UTIL_DEC_3366 3365 +#define Z_UTIL_DEC_3367 3366 +#define Z_UTIL_DEC_3368 3367 +#define Z_UTIL_DEC_3369 3368 +#define Z_UTIL_DEC_3370 3369 +#define Z_UTIL_DEC_3371 3370 +#define Z_UTIL_DEC_3372 3371 +#define Z_UTIL_DEC_3373 3372 +#define Z_UTIL_DEC_3374 3373 +#define Z_UTIL_DEC_3375 3374 +#define Z_UTIL_DEC_3376 3375 +#define Z_UTIL_DEC_3377 3376 +#define Z_UTIL_DEC_3378 3377 +#define Z_UTIL_DEC_3379 3378 +#define Z_UTIL_DEC_3380 3379 +#define Z_UTIL_DEC_3381 3380 +#define Z_UTIL_DEC_3382 3381 +#define Z_UTIL_DEC_3383 3382 +#define Z_UTIL_DEC_3384 3383 +#define Z_UTIL_DEC_3385 3384 +#define Z_UTIL_DEC_3386 3385 +#define Z_UTIL_DEC_3387 3386 +#define Z_UTIL_DEC_3388 3387 +#define Z_UTIL_DEC_3389 3388 +#define Z_UTIL_DEC_3390 3389 +#define Z_UTIL_DEC_3391 3390 +#define Z_UTIL_DEC_3392 3391 +#define Z_UTIL_DEC_3393 3392 +#define Z_UTIL_DEC_3394 3393 +#define Z_UTIL_DEC_3395 3394 +#define Z_UTIL_DEC_3396 3395 +#define Z_UTIL_DEC_3397 3396 +#define Z_UTIL_DEC_3398 3397 +#define Z_UTIL_DEC_3399 3398 +#define Z_UTIL_DEC_3400 3399 +#define Z_UTIL_DEC_3401 3400 +#define Z_UTIL_DEC_3402 3401 +#define Z_UTIL_DEC_3403 3402 +#define Z_UTIL_DEC_3404 3403 +#define Z_UTIL_DEC_3405 3404 +#define Z_UTIL_DEC_3406 3405 +#define Z_UTIL_DEC_3407 3406 +#define Z_UTIL_DEC_3408 3407 +#define Z_UTIL_DEC_3409 3408 +#define Z_UTIL_DEC_3410 3409 +#define Z_UTIL_DEC_3411 3410 +#define Z_UTIL_DEC_3412 3411 +#define Z_UTIL_DEC_3413 3412 +#define Z_UTIL_DEC_3414 3413 +#define Z_UTIL_DEC_3415 3414 +#define Z_UTIL_DEC_3416 3415 +#define Z_UTIL_DEC_3417 3416 +#define Z_UTIL_DEC_3418 3417 +#define Z_UTIL_DEC_3419 3418 +#define Z_UTIL_DEC_3420 3419 +#define Z_UTIL_DEC_3421 3420 +#define Z_UTIL_DEC_3422 3421 +#define Z_UTIL_DEC_3423 3422 +#define Z_UTIL_DEC_3424 3423 +#define Z_UTIL_DEC_3425 3424 +#define Z_UTIL_DEC_3426 3425 +#define Z_UTIL_DEC_3427 3426 +#define Z_UTIL_DEC_3428 3427 +#define Z_UTIL_DEC_3429 3428 +#define Z_UTIL_DEC_3430 3429 +#define Z_UTIL_DEC_3431 3430 +#define Z_UTIL_DEC_3432 3431 +#define Z_UTIL_DEC_3433 3432 +#define Z_UTIL_DEC_3434 3433 +#define Z_UTIL_DEC_3435 3434 +#define Z_UTIL_DEC_3436 3435 +#define Z_UTIL_DEC_3437 3436 +#define Z_UTIL_DEC_3438 3437 +#define Z_UTIL_DEC_3439 3438 +#define Z_UTIL_DEC_3440 3439 +#define Z_UTIL_DEC_3441 3440 +#define Z_UTIL_DEC_3442 3441 +#define Z_UTIL_DEC_3443 3442 +#define Z_UTIL_DEC_3444 3443 +#define Z_UTIL_DEC_3445 3444 +#define Z_UTIL_DEC_3446 3445 +#define Z_UTIL_DEC_3447 3446 +#define Z_UTIL_DEC_3448 3447 +#define Z_UTIL_DEC_3449 3448 +#define Z_UTIL_DEC_3450 3449 +#define Z_UTIL_DEC_3451 3450 +#define Z_UTIL_DEC_3452 3451 +#define Z_UTIL_DEC_3453 3452 +#define Z_UTIL_DEC_3454 3453 +#define Z_UTIL_DEC_3455 3454 +#define Z_UTIL_DEC_3456 3455 +#define Z_UTIL_DEC_3457 3456 +#define Z_UTIL_DEC_3458 3457 +#define Z_UTIL_DEC_3459 3458 +#define Z_UTIL_DEC_3460 3459 +#define Z_UTIL_DEC_3461 3460 +#define Z_UTIL_DEC_3462 3461 +#define Z_UTIL_DEC_3463 3462 +#define Z_UTIL_DEC_3464 3463 +#define Z_UTIL_DEC_3465 3464 +#define Z_UTIL_DEC_3466 3465 +#define Z_UTIL_DEC_3467 3466 +#define Z_UTIL_DEC_3468 3467 +#define Z_UTIL_DEC_3469 3468 +#define Z_UTIL_DEC_3470 3469 +#define Z_UTIL_DEC_3471 3470 +#define Z_UTIL_DEC_3472 3471 +#define Z_UTIL_DEC_3473 3472 +#define Z_UTIL_DEC_3474 3473 +#define Z_UTIL_DEC_3475 3474 +#define Z_UTIL_DEC_3476 3475 +#define Z_UTIL_DEC_3477 3476 +#define Z_UTIL_DEC_3478 3477 +#define Z_UTIL_DEC_3479 3478 +#define Z_UTIL_DEC_3480 3479 +#define Z_UTIL_DEC_3481 3480 +#define Z_UTIL_DEC_3482 3481 +#define Z_UTIL_DEC_3483 3482 +#define Z_UTIL_DEC_3484 3483 +#define Z_UTIL_DEC_3485 3484 +#define Z_UTIL_DEC_3486 3485 +#define Z_UTIL_DEC_3487 3486 +#define Z_UTIL_DEC_3488 3487 +#define Z_UTIL_DEC_3489 3488 +#define Z_UTIL_DEC_3490 3489 +#define Z_UTIL_DEC_3491 3490 +#define Z_UTIL_DEC_3492 3491 +#define Z_UTIL_DEC_3493 3492 +#define Z_UTIL_DEC_3494 3493 +#define Z_UTIL_DEC_3495 3494 +#define Z_UTIL_DEC_3496 3495 +#define Z_UTIL_DEC_3497 3496 +#define Z_UTIL_DEC_3498 3497 +#define Z_UTIL_DEC_3499 3498 +#define Z_UTIL_DEC_3500 3499 +#define Z_UTIL_DEC_3501 3500 +#define Z_UTIL_DEC_3502 3501 +#define Z_UTIL_DEC_3503 3502 +#define Z_UTIL_DEC_3504 3503 +#define Z_UTIL_DEC_3505 3504 +#define Z_UTIL_DEC_3506 3505 +#define Z_UTIL_DEC_3507 3506 +#define Z_UTIL_DEC_3508 3507 +#define Z_UTIL_DEC_3509 3508 +#define Z_UTIL_DEC_3510 3509 +#define Z_UTIL_DEC_3511 3510 +#define Z_UTIL_DEC_3512 3511 +#define Z_UTIL_DEC_3513 3512 +#define Z_UTIL_DEC_3514 3513 +#define Z_UTIL_DEC_3515 3514 +#define Z_UTIL_DEC_3516 3515 +#define Z_UTIL_DEC_3517 3516 +#define Z_UTIL_DEC_3518 3517 +#define Z_UTIL_DEC_3519 3518 +#define Z_UTIL_DEC_3520 3519 +#define Z_UTIL_DEC_3521 3520 +#define Z_UTIL_DEC_3522 3521 +#define Z_UTIL_DEC_3523 3522 +#define Z_UTIL_DEC_3524 3523 +#define Z_UTIL_DEC_3525 3524 +#define Z_UTIL_DEC_3526 3525 +#define Z_UTIL_DEC_3527 3526 +#define Z_UTIL_DEC_3528 3527 +#define Z_UTIL_DEC_3529 3528 +#define Z_UTIL_DEC_3530 3529 +#define Z_UTIL_DEC_3531 3530 +#define Z_UTIL_DEC_3532 3531 +#define Z_UTIL_DEC_3533 3532 +#define Z_UTIL_DEC_3534 3533 +#define Z_UTIL_DEC_3535 3534 +#define Z_UTIL_DEC_3536 3535 +#define Z_UTIL_DEC_3537 3536 +#define Z_UTIL_DEC_3538 3537 +#define Z_UTIL_DEC_3539 3538 +#define Z_UTIL_DEC_3540 3539 +#define Z_UTIL_DEC_3541 3540 +#define Z_UTIL_DEC_3542 3541 +#define Z_UTIL_DEC_3543 3542 +#define Z_UTIL_DEC_3544 3543 +#define Z_UTIL_DEC_3545 3544 +#define Z_UTIL_DEC_3546 3545 +#define Z_UTIL_DEC_3547 3546 +#define Z_UTIL_DEC_3548 3547 +#define Z_UTIL_DEC_3549 3548 +#define Z_UTIL_DEC_3550 3549 +#define Z_UTIL_DEC_3551 3550 +#define Z_UTIL_DEC_3552 3551 +#define Z_UTIL_DEC_3553 3552 +#define Z_UTIL_DEC_3554 3553 +#define Z_UTIL_DEC_3555 3554 +#define Z_UTIL_DEC_3556 3555 +#define Z_UTIL_DEC_3557 3556 +#define Z_UTIL_DEC_3558 3557 +#define Z_UTIL_DEC_3559 3558 +#define Z_UTIL_DEC_3560 3559 +#define Z_UTIL_DEC_3561 3560 +#define Z_UTIL_DEC_3562 3561 +#define Z_UTIL_DEC_3563 3562 +#define Z_UTIL_DEC_3564 3563 +#define Z_UTIL_DEC_3565 3564 +#define Z_UTIL_DEC_3566 3565 +#define Z_UTIL_DEC_3567 3566 +#define Z_UTIL_DEC_3568 3567 +#define Z_UTIL_DEC_3569 3568 +#define Z_UTIL_DEC_3570 3569 +#define Z_UTIL_DEC_3571 3570 +#define Z_UTIL_DEC_3572 3571 +#define Z_UTIL_DEC_3573 3572 +#define Z_UTIL_DEC_3574 3573 +#define Z_UTIL_DEC_3575 3574 +#define Z_UTIL_DEC_3576 3575 +#define Z_UTIL_DEC_3577 3576 +#define Z_UTIL_DEC_3578 3577 +#define Z_UTIL_DEC_3579 3578 +#define Z_UTIL_DEC_3580 3579 +#define Z_UTIL_DEC_3581 3580 +#define Z_UTIL_DEC_3582 3581 +#define Z_UTIL_DEC_3583 3582 +#define Z_UTIL_DEC_3584 3583 +#define Z_UTIL_DEC_3585 3584 +#define Z_UTIL_DEC_3586 3585 +#define Z_UTIL_DEC_3587 3586 +#define Z_UTIL_DEC_3588 3587 +#define Z_UTIL_DEC_3589 3588 +#define Z_UTIL_DEC_3590 3589 +#define Z_UTIL_DEC_3591 3590 +#define Z_UTIL_DEC_3592 3591 +#define Z_UTIL_DEC_3593 3592 +#define Z_UTIL_DEC_3594 3593 +#define Z_UTIL_DEC_3595 3594 +#define Z_UTIL_DEC_3596 3595 +#define Z_UTIL_DEC_3597 3596 +#define Z_UTIL_DEC_3598 3597 +#define Z_UTIL_DEC_3599 3598 +#define Z_UTIL_DEC_3600 3599 +#define Z_UTIL_DEC_3601 3600 +#define Z_UTIL_DEC_3602 3601 +#define Z_UTIL_DEC_3603 3602 +#define Z_UTIL_DEC_3604 3603 +#define Z_UTIL_DEC_3605 3604 +#define Z_UTIL_DEC_3606 3605 +#define Z_UTIL_DEC_3607 3606 +#define Z_UTIL_DEC_3608 3607 +#define Z_UTIL_DEC_3609 3608 +#define Z_UTIL_DEC_3610 3609 +#define Z_UTIL_DEC_3611 3610 +#define Z_UTIL_DEC_3612 3611 +#define Z_UTIL_DEC_3613 3612 +#define Z_UTIL_DEC_3614 3613 +#define Z_UTIL_DEC_3615 3614 +#define Z_UTIL_DEC_3616 3615 +#define Z_UTIL_DEC_3617 3616 +#define Z_UTIL_DEC_3618 3617 +#define Z_UTIL_DEC_3619 3618 +#define Z_UTIL_DEC_3620 3619 +#define Z_UTIL_DEC_3621 3620 +#define Z_UTIL_DEC_3622 3621 +#define Z_UTIL_DEC_3623 3622 +#define Z_UTIL_DEC_3624 3623 +#define Z_UTIL_DEC_3625 3624 +#define Z_UTIL_DEC_3626 3625 +#define Z_UTIL_DEC_3627 3626 +#define Z_UTIL_DEC_3628 3627 +#define Z_UTIL_DEC_3629 3628 +#define Z_UTIL_DEC_3630 3629 +#define Z_UTIL_DEC_3631 3630 +#define Z_UTIL_DEC_3632 3631 +#define Z_UTIL_DEC_3633 3632 +#define Z_UTIL_DEC_3634 3633 +#define Z_UTIL_DEC_3635 3634 +#define Z_UTIL_DEC_3636 3635 +#define Z_UTIL_DEC_3637 3636 +#define Z_UTIL_DEC_3638 3637 +#define Z_UTIL_DEC_3639 3638 +#define Z_UTIL_DEC_3640 3639 +#define Z_UTIL_DEC_3641 3640 +#define Z_UTIL_DEC_3642 3641 +#define Z_UTIL_DEC_3643 3642 +#define Z_UTIL_DEC_3644 3643 +#define Z_UTIL_DEC_3645 3644 +#define Z_UTIL_DEC_3646 3645 +#define Z_UTIL_DEC_3647 3646 +#define Z_UTIL_DEC_3648 3647 +#define Z_UTIL_DEC_3649 3648 +#define Z_UTIL_DEC_3650 3649 +#define Z_UTIL_DEC_3651 3650 +#define Z_UTIL_DEC_3652 3651 +#define Z_UTIL_DEC_3653 3652 +#define Z_UTIL_DEC_3654 3653 +#define Z_UTIL_DEC_3655 3654 +#define Z_UTIL_DEC_3656 3655 +#define Z_UTIL_DEC_3657 3656 +#define Z_UTIL_DEC_3658 3657 +#define Z_UTIL_DEC_3659 3658 +#define Z_UTIL_DEC_3660 3659 +#define Z_UTIL_DEC_3661 3660 +#define Z_UTIL_DEC_3662 3661 +#define Z_UTIL_DEC_3663 3662 +#define Z_UTIL_DEC_3664 3663 +#define Z_UTIL_DEC_3665 3664 +#define Z_UTIL_DEC_3666 3665 +#define Z_UTIL_DEC_3667 3666 +#define Z_UTIL_DEC_3668 3667 +#define Z_UTIL_DEC_3669 3668 +#define Z_UTIL_DEC_3670 3669 +#define Z_UTIL_DEC_3671 3670 +#define Z_UTIL_DEC_3672 3671 +#define Z_UTIL_DEC_3673 3672 +#define Z_UTIL_DEC_3674 3673 +#define Z_UTIL_DEC_3675 3674 +#define Z_UTIL_DEC_3676 3675 +#define Z_UTIL_DEC_3677 3676 +#define Z_UTIL_DEC_3678 3677 +#define Z_UTIL_DEC_3679 3678 +#define Z_UTIL_DEC_3680 3679 +#define Z_UTIL_DEC_3681 3680 +#define Z_UTIL_DEC_3682 3681 +#define Z_UTIL_DEC_3683 3682 +#define Z_UTIL_DEC_3684 3683 +#define Z_UTIL_DEC_3685 3684 +#define Z_UTIL_DEC_3686 3685 +#define Z_UTIL_DEC_3687 3686 +#define Z_UTIL_DEC_3688 3687 +#define Z_UTIL_DEC_3689 3688 +#define Z_UTIL_DEC_3690 3689 +#define Z_UTIL_DEC_3691 3690 +#define Z_UTIL_DEC_3692 3691 +#define Z_UTIL_DEC_3693 3692 +#define Z_UTIL_DEC_3694 3693 +#define Z_UTIL_DEC_3695 3694 +#define Z_UTIL_DEC_3696 3695 +#define Z_UTIL_DEC_3697 3696 +#define Z_UTIL_DEC_3698 3697 +#define Z_UTIL_DEC_3699 3698 +#define Z_UTIL_DEC_3700 3699 +#define Z_UTIL_DEC_3701 3700 +#define Z_UTIL_DEC_3702 3701 +#define Z_UTIL_DEC_3703 3702 +#define Z_UTIL_DEC_3704 3703 +#define Z_UTIL_DEC_3705 3704 +#define Z_UTIL_DEC_3706 3705 +#define Z_UTIL_DEC_3707 3706 +#define Z_UTIL_DEC_3708 3707 +#define Z_UTIL_DEC_3709 3708 +#define Z_UTIL_DEC_3710 3709 +#define Z_UTIL_DEC_3711 3710 +#define Z_UTIL_DEC_3712 3711 +#define Z_UTIL_DEC_3713 3712 +#define Z_UTIL_DEC_3714 3713 +#define Z_UTIL_DEC_3715 3714 +#define Z_UTIL_DEC_3716 3715 +#define Z_UTIL_DEC_3717 3716 +#define Z_UTIL_DEC_3718 3717 +#define Z_UTIL_DEC_3719 3718 +#define Z_UTIL_DEC_3720 3719 +#define Z_UTIL_DEC_3721 3720 +#define Z_UTIL_DEC_3722 3721 +#define Z_UTIL_DEC_3723 3722 +#define Z_UTIL_DEC_3724 3723 +#define Z_UTIL_DEC_3725 3724 +#define Z_UTIL_DEC_3726 3725 +#define Z_UTIL_DEC_3727 3726 +#define Z_UTIL_DEC_3728 3727 +#define Z_UTIL_DEC_3729 3728 +#define Z_UTIL_DEC_3730 3729 +#define Z_UTIL_DEC_3731 3730 +#define Z_UTIL_DEC_3732 3731 +#define Z_UTIL_DEC_3733 3732 +#define Z_UTIL_DEC_3734 3733 +#define Z_UTIL_DEC_3735 3734 +#define Z_UTIL_DEC_3736 3735 +#define Z_UTIL_DEC_3737 3736 +#define Z_UTIL_DEC_3738 3737 +#define Z_UTIL_DEC_3739 3738 +#define Z_UTIL_DEC_3740 3739 +#define Z_UTIL_DEC_3741 3740 +#define Z_UTIL_DEC_3742 3741 +#define Z_UTIL_DEC_3743 3742 +#define Z_UTIL_DEC_3744 3743 +#define Z_UTIL_DEC_3745 3744 +#define Z_UTIL_DEC_3746 3745 +#define Z_UTIL_DEC_3747 3746 +#define Z_UTIL_DEC_3748 3747 +#define Z_UTIL_DEC_3749 3748 +#define Z_UTIL_DEC_3750 3749 +#define Z_UTIL_DEC_3751 3750 +#define Z_UTIL_DEC_3752 3751 +#define Z_UTIL_DEC_3753 3752 +#define Z_UTIL_DEC_3754 3753 +#define Z_UTIL_DEC_3755 3754 +#define Z_UTIL_DEC_3756 3755 +#define Z_UTIL_DEC_3757 3756 +#define Z_UTIL_DEC_3758 3757 +#define Z_UTIL_DEC_3759 3758 +#define Z_UTIL_DEC_3760 3759 +#define Z_UTIL_DEC_3761 3760 +#define Z_UTIL_DEC_3762 3761 +#define Z_UTIL_DEC_3763 3762 +#define Z_UTIL_DEC_3764 3763 +#define Z_UTIL_DEC_3765 3764 +#define Z_UTIL_DEC_3766 3765 +#define Z_UTIL_DEC_3767 3766 +#define Z_UTIL_DEC_3768 3767 +#define Z_UTIL_DEC_3769 3768 +#define Z_UTIL_DEC_3770 3769 +#define Z_UTIL_DEC_3771 3770 +#define Z_UTIL_DEC_3772 3771 +#define Z_UTIL_DEC_3773 3772 +#define Z_UTIL_DEC_3774 3773 +#define Z_UTIL_DEC_3775 3774 +#define Z_UTIL_DEC_3776 3775 +#define Z_UTIL_DEC_3777 3776 +#define Z_UTIL_DEC_3778 3777 +#define Z_UTIL_DEC_3779 3778 +#define Z_UTIL_DEC_3780 3779 +#define Z_UTIL_DEC_3781 3780 +#define Z_UTIL_DEC_3782 3781 +#define Z_UTIL_DEC_3783 3782 +#define Z_UTIL_DEC_3784 3783 +#define Z_UTIL_DEC_3785 3784 +#define Z_UTIL_DEC_3786 3785 +#define Z_UTIL_DEC_3787 3786 +#define Z_UTIL_DEC_3788 3787 +#define Z_UTIL_DEC_3789 3788 +#define Z_UTIL_DEC_3790 3789 +#define Z_UTIL_DEC_3791 3790 +#define Z_UTIL_DEC_3792 3791 +#define Z_UTIL_DEC_3793 3792 +#define Z_UTIL_DEC_3794 3793 +#define Z_UTIL_DEC_3795 3794 +#define Z_UTIL_DEC_3796 3795 +#define Z_UTIL_DEC_3797 3796 +#define Z_UTIL_DEC_3798 3797 +#define Z_UTIL_DEC_3799 3798 +#define Z_UTIL_DEC_3800 3799 +#define Z_UTIL_DEC_3801 3800 +#define Z_UTIL_DEC_3802 3801 +#define Z_UTIL_DEC_3803 3802 +#define Z_UTIL_DEC_3804 3803 +#define Z_UTIL_DEC_3805 3804 +#define Z_UTIL_DEC_3806 3805 +#define Z_UTIL_DEC_3807 3806 +#define Z_UTIL_DEC_3808 3807 +#define Z_UTIL_DEC_3809 3808 +#define Z_UTIL_DEC_3810 3809 +#define Z_UTIL_DEC_3811 3810 +#define Z_UTIL_DEC_3812 3811 +#define Z_UTIL_DEC_3813 3812 +#define Z_UTIL_DEC_3814 3813 +#define Z_UTIL_DEC_3815 3814 +#define Z_UTIL_DEC_3816 3815 +#define Z_UTIL_DEC_3817 3816 +#define Z_UTIL_DEC_3818 3817 +#define Z_UTIL_DEC_3819 3818 +#define Z_UTIL_DEC_3820 3819 +#define Z_UTIL_DEC_3821 3820 +#define Z_UTIL_DEC_3822 3821 +#define Z_UTIL_DEC_3823 3822 +#define Z_UTIL_DEC_3824 3823 +#define Z_UTIL_DEC_3825 3824 +#define Z_UTIL_DEC_3826 3825 +#define Z_UTIL_DEC_3827 3826 +#define Z_UTIL_DEC_3828 3827 +#define Z_UTIL_DEC_3829 3828 +#define Z_UTIL_DEC_3830 3829 +#define Z_UTIL_DEC_3831 3830 +#define Z_UTIL_DEC_3832 3831 +#define Z_UTIL_DEC_3833 3832 +#define Z_UTIL_DEC_3834 3833 +#define Z_UTIL_DEC_3835 3834 +#define Z_UTIL_DEC_3836 3835 +#define Z_UTIL_DEC_3837 3836 +#define Z_UTIL_DEC_3838 3837 +#define Z_UTIL_DEC_3839 3838 +#define Z_UTIL_DEC_3840 3839 +#define Z_UTIL_DEC_3841 3840 +#define Z_UTIL_DEC_3842 3841 +#define Z_UTIL_DEC_3843 3842 +#define Z_UTIL_DEC_3844 3843 +#define Z_UTIL_DEC_3845 3844 +#define Z_UTIL_DEC_3846 3845 +#define Z_UTIL_DEC_3847 3846 +#define Z_UTIL_DEC_3848 3847 +#define Z_UTIL_DEC_3849 3848 +#define Z_UTIL_DEC_3850 3849 +#define Z_UTIL_DEC_3851 3850 +#define Z_UTIL_DEC_3852 3851 +#define Z_UTIL_DEC_3853 3852 +#define Z_UTIL_DEC_3854 3853 +#define Z_UTIL_DEC_3855 3854 +#define Z_UTIL_DEC_3856 3855 +#define Z_UTIL_DEC_3857 3856 +#define Z_UTIL_DEC_3858 3857 +#define Z_UTIL_DEC_3859 3858 +#define Z_UTIL_DEC_3860 3859 +#define Z_UTIL_DEC_3861 3860 +#define Z_UTIL_DEC_3862 3861 +#define Z_UTIL_DEC_3863 3862 +#define Z_UTIL_DEC_3864 3863 +#define Z_UTIL_DEC_3865 3864 +#define Z_UTIL_DEC_3866 3865 +#define Z_UTIL_DEC_3867 3866 +#define Z_UTIL_DEC_3868 3867 +#define Z_UTIL_DEC_3869 3868 +#define Z_UTIL_DEC_3870 3869 +#define Z_UTIL_DEC_3871 3870 +#define Z_UTIL_DEC_3872 3871 +#define Z_UTIL_DEC_3873 3872 +#define Z_UTIL_DEC_3874 3873 +#define Z_UTIL_DEC_3875 3874 +#define Z_UTIL_DEC_3876 3875 +#define Z_UTIL_DEC_3877 3876 +#define Z_UTIL_DEC_3878 3877 +#define Z_UTIL_DEC_3879 3878 +#define Z_UTIL_DEC_3880 3879 +#define Z_UTIL_DEC_3881 3880 +#define Z_UTIL_DEC_3882 3881 +#define Z_UTIL_DEC_3883 3882 +#define Z_UTIL_DEC_3884 3883 +#define Z_UTIL_DEC_3885 3884 +#define Z_UTIL_DEC_3886 3885 +#define Z_UTIL_DEC_3887 3886 +#define Z_UTIL_DEC_3888 3887 +#define Z_UTIL_DEC_3889 3888 +#define Z_UTIL_DEC_3890 3889 +#define Z_UTIL_DEC_3891 3890 +#define Z_UTIL_DEC_3892 3891 +#define Z_UTIL_DEC_3893 3892 +#define Z_UTIL_DEC_3894 3893 +#define Z_UTIL_DEC_3895 3894 +#define Z_UTIL_DEC_3896 3895 +#define Z_UTIL_DEC_3897 3896 +#define Z_UTIL_DEC_3898 3897 +#define Z_UTIL_DEC_3899 3898 +#define Z_UTIL_DEC_3900 3899 +#define Z_UTIL_DEC_3901 3900 +#define Z_UTIL_DEC_3902 3901 +#define Z_UTIL_DEC_3903 3902 +#define Z_UTIL_DEC_3904 3903 +#define Z_UTIL_DEC_3905 3904 +#define Z_UTIL_DEC_3906 3905 +#define Z_UTIL_DEC_3907 3906 +#define Z_UTIL_DEC_3908 3907 +#define Z_UTIL_DEC_3909 3908 +#define Z_UTIL_DEC_3910 3909 +#define Z_UTIL_DEC_3911 3910 +#define Z_UTIL_DEC_3912 3911 +#define Z_UTIL_DEC_3913 3912 +#define Z_UTIL_DEC_3914 3913 +#define Z_UTIL_DEC_3915 3914 +#define Z_UTIL_DEC_3916 3915 +#define Z_UTIL_DEC_3917 3916 +#define Z_UTIL_DEC_3918 3917 +#define Z_UTIL_DEC_3919 3918 +#define Z_UTIL_DEC_3920 3919 +#define Z_UTIL_DEC_3921 3920 +#define Z_UTIL_DEC_3922 3921 +#define Z_UTIL_DEC_3923 3922 +#define Z_UTIL_DEC_3924 3923 +#define Z_UTIL_DEC_3925 3924 +#define Z_UTIL_DEC_3926 3925 +#define Z_UTIL_DEC_3927 3926 +#define Z_UTIL_DEC_3928 3927 +#define Z_UTIL_DEC_3929 3928 +#define Z_UTIL_DEC_3930 3929 +#define Z_UTIL_DEC_3931 3930 +#define Z_UTIL_DEC_3932 3931 +#define Z_UTIL_DEC_3933 3932 +#define Z_UTIL_DEC_3934 3933 +#define Z_UTIL_DEC_3935 3934 +#define Z_UTIL_DEC_3936 3935 +#define Z_UTIL_DEC_3937 3936 +#define Z_UTIL_DEC_3938 3937 +#define Z_UTIL_DEC_3939 3938 +#define Z_UTIL_DEC_3940 3939 +#define Z_UTIL_DEC_3941 3940 +#define Z_UTIL_DEC_3942 3941 +#define Z_UTIL_DEC_3943 3942 +#define Z_UTIL_DEC_3944 3943 +#define Z_UTIL_DEC_3945 3944 +#define Z_UTIL_DEC_3946 3945 +#define Z_UTIL_DEC_3947 3946 +#define Z_UTIL_DEC_3948 3947 +#define Z_UTIL_DEC_3949 3948 +#define Z_UTIL_DEC_3950 3949 +#define Z_UTIL_DEC_3951 3950 +#define Z_UTIL_DEC_3952 3951 +#define Z_UTIL_DEC_3953 3952 +#define Z_UTIL_DEC_3954 3953 +#define Z_UTIL_DEC_3955 3954 +#define Z_UTIL_DEC_3956 3955 +#define Z_UTIL_DEC_3957 3956 +#define Z_UTIL_DEC_3958 3957 +#define Z_UTIL_DEC_3959 3958 +#define Z_UTIL_DEC_3960 3959 +#define Z_UTIL_DEC_3961 3960 +#define Z_UTIL_DEC_3962 3961 +#define Z_UTIL_DEC_3963 3962 +#define Z_UTIL_DEC_3964 3963 +#define Z_UTIL_DEC_3965 3964 +#define Z_UTIL_DEC_3966 3965 +#define Z_UTIL_DEC_3967 3966 +#define Z_UTIL_DEC_3968 3967 +#define Z_UTIL_DEC_3969 3968 +#define Z_UTIL_DEC_3970 3969 +#define Z_UTIL_DEC_3971 3970 +#define Z_UTIL_DEC_3972 3971 +#define Z_UTIL_DEC_3973 3972 +#define Z_UTIL_DEC_3974 3973 +#define Z_UTIL_DEC_3975 3974 +#define Z_UTIL_DEC_3976 3975 +#define Z_UTIL_DEC_3977 3976 +#define Z_UTIL_DEC_3978 3977 +#define Z_UTIL_DEC_3979 3978 +#define Z_UTIL_DEC_3980 3979 +#define Z_UTIL_DEC_3981 3980 +#define Z_UTIL_DEC_3982 3981 +#define Z_UTIL_DEC_3983 3982 +#define Z_UTIL_DEC_3984 3983 +#define Z_UTIL_DEC_3985 3984 +#define Z_UTIL_DEC_3986 3985 +#define Z_UTIL_DEC_3987 3986 +#define Z_UTIL_DEC_3988 3987 +#define Z_UTIL_DEC_3989 3988 +#define Z_UTIL_DEC_3990 3989 +#define Z_UTIL_DEC_3991 3990 +#define Z_UTIL_DEC_3992 3991 +#define Z_UTIL_DEC_3993 3992 +#define Z_UTIL_DEC_3994 3993 +#define Z_UTIL_DEC_3995 3994 +#define Z_UTIL_DEC_3996 3995 +#define Z_UTIL_DEC_3997 3996 +#define Z_UTIL_DEC_3998 3997 +#define Z_UTIL_DEC_3999 3998 +#define Z_UTIL_DEC_4000 3999 +#define Z_UTIL_DEC_4001 4000 +#define Z_UTIL_DEC_4002 4001 +#define Z_UTIL_DEC_4003 4002 +#define Z_UTIL_DEC_4004 4003 +#define Z_UTIL_DEC_4005 4004 +#define Z_UTIL_DEC_4006 4005 +#define Z_UTIL_DEC_4007 4006 +#define Z_UTIL_DEC_4008 4007 +#define Z_UTIL_DEC_4009 4008 +#define Z_UTIL_DEC_4010 4009 +#define Z_UTIL_DEC_4011 4010 +#define Z_UTIL_DEC_4012 4011 +#define Z_UTIL_DEC_4013 4012 +#define Z_UTIL_DEC_4014 4013 +#define Z_UTIL_DEC_4015 4014 +#define Z_UTIL_DEC_4016 4015 +#define Z_UTIL_DEC_4017 4016 +#define Z_UTIL_DEC_4018 4017 +#define Z_UTIL_DEC_4019 4018 +#define Z_UTIL_DEC_4020 4019 +#define Z_UTIL_DEC_4021 4020 +#define Z_UTIL_DEC_4022 4021 +#define Z_UTIL_DEC_4023 4022 +#define Z_UTIL_DEC_4024 4023 +#define Z_UTIL_DEC_4025 4024 +#define Z_UTIL_DEC_4026 4025 +#define Z_UTIL_DEC_4027 4026 +#define Z_UTIL_DEC_4028 4027 +#define Z_UTIL_DEC_4029 4028 +#define Z_UTIL_DEC_4030 4029 +#define Z_UTIL_DEC_4031 4030 +#define Z_UTIL_DEC_4032 4031 +#define Z_UTIL_DEC_4033 4032 +#define Z_UTIL_DEC_4034 4033 +#define Z_UTIL_DEC_4035 4034 +#define Z_UTIL_DEC_4036 4035 +#define Z_UTIL_DEC_4037 4036 +#define Z_UTIL_DEC_4038 4037 +#define Z_UTIL_DEC_4039 4038 +#define Z_UTIL_DEC_4040 4039 +#define Z_UTIL_DEC_4041 4040 +#define Z_UTIL_DEC_4042 4041 +#define Z_UTIL_DEC_4043 4042 +#define Z_UTIL_DEC_4044 4043 +#define Z_UTIL_DEC_4045 4044 +#define Z_UTIL_DEC_4046 4045 +#define Z_UTIL_DEC_4047 4046 +#define Z_UTIL_DEC_4048 4047 +#define Z_UTIL_DEC_4049 4048 +#define Z_UTIL_DEC_4050 4049 +#define Z_UTIL_DEC_4051 4050 +#define Z_UTIL_DEC_4052 4051 +#define Z_UTIL_DEC_4053 4052 +#define Z_UTIL_DEC_4054 4053 +#define Z_UTIL_DEC_4055 4054 +#define Z_UTIL_DEC_4056 4055 +#define Z_UTIL_DEC_4057 4056 +#define Z_UTIL_DEC_4058 4057 +#define Z_UTIL_DEC_4059 4058 +#define Z_UTIL_DEC_4060 4059 +#define Z_UTIL_DEC_4061 4060 +#define Z_UTIL_DEC_4062 4061 +#define Z_UTIL_DEC_4063 4062 +#define Z_UTIL_DEC_4064 4063 +#define Z_UTIL_DEC_4065 4064 +#define Z_UTIL_DEC_4066 4065 +#define Z_UTIL_DEC_4067 4066 +#define Z_UTIL_DEC_4068 4067 +#define Z_UTIL_DEC_4069 4068 +#define Z_UTIL_DEC_4070 4069 +#define Z_UTIL_DEC_4071 4070 +#define Z_UTIL_DEC_4072 4071 +#define Z_UTIL_DEC_4073 4072 +#define Z_UTIL_DEC_4074 4073 +#define Z_UTIL_DEC_4075 4074 +#define Z_UTIL_DEC_4076 4075 +#define Z_UTIL_DEC_4077 4076 +#define Z_UTIL_DEC_4078 4077 +#define Z_UTIL_DEC_4079 4078 +#define Z_UTIL_DEC_4080 4079 +#define Z_UTIL_DEC_4081 4080 +#define Z_UTIL_DEC_4082 4081 +#define Z_UTIL_DEC_4083 4082 +#define Z_UTIL_DEC_4084 4083 +#define Z_UTIL_DEC_4085 4084 +#define Z_UTIL_DEC_4086 4085 +#define Z_UTIL_DEC_4087 4086 +#define Z_UTIL_DEC_4088 4087 +#define Z_UTIL_DEC_4089 4088 +#define Z_UTIL_DEC_4090 4089 +#define Z_UTIL_DEC_4091 4090 +#define Z_UTIL_DEC_4092 4091 +#define Z_UTIL_DEC_4093 4092 +#define Z_UTIL_DEC_4094 4093 +#define Z_UTIL_DEC_4095 4094 +#define Z_UTIL_DEC_4096 4095 + +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_ */ + +/** + * INTERNAL_HIDDEN @endcond + */ diff --git a/include/zephyr/sys/util_internal_util_inc.h b/include/zephyr/sys/util_internal_util_inc.h new file mode 100644 index 00000000000..dbff47383c9 --- /dev/null +++ b/include/zephyr/sys/util_internal_util_inc.h @@ -0,0 +1,4122 @@ +/* + * Copyright (c) 2011-2014, Wind River Systems, Inc. + * Copyright (c) 2020, Nordic Semiconductor ASA + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @cond INTERNAL_HIDDEN + */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ +#error "This header should not be used directly, please include util_internal.h instead" +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_ +#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_ + +#define Z_UTIL_INC_0 1 +#define Z_UTIL_INC_1 2 +#define Z_UTIL_INC_2 3 +#define Z_UTIL_INC_3 4 +#define Z_UTIL_INC_4 5 +#define Z_UTIL_INC_5 6 +#define Z_UTIL_INC_6 7 +#define Z_UTIL_INC_7 8 +#define Z_UTIL_INC_8 9 +#define Z_UTIL_INC_9 10 +#define Z_UTIL_INC_10 11 +#define Z_UTIL_INC_11 12 +#define Z_UTIL_INC_12 13 +#define Z_UTIL_INC_13 14 +#define Z_UTIL_INC_14 15 +#define Z_UTIL_INC_15 16 +#define Z_UTIL_INC_16 17 +#define Z_UTIL_INC_17 18 +#define Z_UTIL_INC_18 19 +#define Z_UTIL_INC_19 20 +#define Z_UTIL_INC_20 21 +#define Z_UTIL_INC_21 22 +#define Z_UTIL_INC_22 23 +#define Z_UTIL_INC_23 24 +#define Z_UTIL_INC_24 25 +#define Z_UTIL_INC_25 26 +#define Z_UTIL_INC_26 27 +#define Z_UTIL_INC_27 28 +#define Z_UTIL_INC_28 29 +#define Z_UTIL_INC_29 30 +#define Z_UTIL_INC_30 31 +#define Z_UTIL_INC_31 32 +#define Z_UTIL_INC_32 33 +#define Z_UTIL_INC_33 34 +#define Z_UTIL_INC_34 35 +#define Z_UTIL_INC_35 36 +#define Z_UTIL_INC_36 37 +#define Z_UTIL_INC_37 38 +#define Z_UTIL_INC_38 39 +#define Z_UTIL_INC_39 40 +#define Z_UTIL_INC_40 41 +#define Z_UTIL_INC_41 42 +#define Z_UTIL_INC_42 43 +#define Z_UTIL_INC_43 44 +#define Z_UTIL_INC_44 45 +#define Z_UTIL_INC_45 46 +#define Z_UTIL_INC_46 47 +#define Z_UTIL_INC_47 48 +#define Z_UTIL_INC_48 49 +#define Z_UTIL_INC_49 50 +#define Z_UTIL_INC_50 51 +#define Z_UTIL_INC_51 52 +#define Z_UTIL_INC_52 53 +#define Z_UTIL_INC_53 54 +#define Z_UTIL_INC_54 55 +#define Z_UTIL_INC_55 56 +#define Z_UTIL_INC_56 57 +#define Z_UTIL_INC_57 58 +#define Z_UTIL_INC_58 59 +#define Z_UTIL_INC_59 60 +#define Z_UTIL_INC_60 61 +#define Z_UTIL_INC_61 62 +#define Z_UTIL_INC_62 63 +#define Z_UTIL_INC_63 64 +#define Z_UTIL_INC_64 65 +#define Z_UTIL_INC_65 66 +#define Z_UTIL_INC_66 67 +#define Z_UTIL_INC_67 68 +#define Z_UTIL_INC_68 69 +#define Z_UTIL_INC_69 70 +#define Z_UTIL_INC_70 71 +#define Z_UTIL_INC_71 72 +#define Z_UTIL_INC_72 73 +#define Z_UTIL_INC_73 74 +#define Z_UTIL_INC_74 75 +#define Z_UTIL_INC_75 76 +#define Z_UTIL_INC_76 77 +#define Z_UTIL_INC_77 78 +#define Z_UTIL_INC_78 79 +#define Z_UTIL_INC_79 80 +#define Z_UTIL_INC_80 81 +#define Z_UTIL_INC_81 82 +#define Z_UTIL_INC_82 83 +#define Z_UTIL_INC_83 84 +#define Z_UTIL_INC_84 85 +#define Z_UTIL_INC_85 86 +#define Z_UTIL_INC_86 87 +#define Z_UTIL_INC_87 88 +#define Z_UTIL_INC_88 89 +#define Z_UTIL_INC_89 90 +#define Z_UTIL_INC_90 91 +#define Z_UTIL_INC_91 92 +#define Z_UTIL_INC_92 93 +#define Z_UTIL_INC_93 94 +#define Z_UTIL_INC_94 95 +#define Z_UTIL_INC_95 96 +#define Z_UTIL_INC_96 97 +#define Z_UTIL_INC_97 98 +#define Z_UTIL_INC_98 99 +#define Z_UTIL_INC_99 100 +#define Z_UTIL_INC_100 101 +#define Z_UTIL_INC_101 102 +#define Z_UTIL_INC_102 103 +#define Z_UTIL_INC_103 104 +#define Z_UTIL_INC_104 105 +#define Z_UTIL_INC_105 106 +#define Z_UTIL_INC_106 107 +#define Z_UTIL_INC_107 108 +#define Z_UTIL_INC_108 109 +#define Z_UTIL_INC_109 110 +#define Z_UTIL_INC_110 111 +#define Z_UTIL_INC_111 112 +#define Z_UTIL_INC_112 113 +#define Z_UTIL_INC_113 114 +#define Z_UTIL_INC_114 115 +#define Z_UTIL_INC_115 116 +#define Z_UTIL_INC_116 117 +#define Z_UTIL_INC_117 118 +#define Z_UTIL_INC_118 119 +#define Z_UTIL_INC_119 120 +#define Z_UTIL_INC_120 121 +#define Z_UTIL_INC_121 122 +#define Z_UTIL_INC_122 123 +#define Z_UTIL_INC_123 124 +#define Z_UTIL_INC_124 125 +#define Z_UTIL_INC_125 126 +#define Z_UTIL_INC_126 127 +#define Z_UTIL_INC_127 128 +#define Z_UTIL_INC_128 129 +#define Z_UTIL_INC_129 130 +#define Z_UTIL_INC_130 131 +#define Z_UTIL_INC_131 132 +#define Z_UTIL_INC_132 133 +#define Z_UTIL_INC_133 134 +#define Z_UTIL_INC_134 135 +#define Z_UTIL_INC_135 136 +#define Z_UTIL_INC_136 137 +#define Z_UTIL_INC_137 138 +#define Z_UTIL_INC_138 139 +#define Z_UTIL_INC_139 140 +#define Z_UTIL_INC_140 141 +#define Z_UTIL_INC_141 142 +#define Z_UTIL_INC_142 143 +#define Z_UTIL_INC_143 144 +#define Z_UTIL_INC_144 145 +#define Z_UTIL_INC_145 146 +#define Z_UTIL_INC_146 147 +#define Z_UTIL_INC_147 148 +#define Z_UTIL_INC_148 149 +#define Z_UTIL_INC_149 150 +#define Z_UTIL_INC_150 151 +#define Z_UTIL_INC_151 152 +#define Z_UTIL_INC_152 153 +#define Z_UTIL_INC_153 154 +#define Z_UTIL_INC_154 155 +#define Z_UTIL_INC_155 156 +#define Z_UTIL_INC_156 157 +#define Z_UTIL_INC_157 158 +#define Z_UTIL_INC_158 159 +#define Z_UTIL_INC_159 160 +#define Z_UTIL_INC_160 161 +#define Z_UTIL_INC_161 162 +#define Z_UTIL_INC_162 163 +#define Z_UTIL_INC_163 164 +#define Z_UTIL_INC_164 165 +#define Z_UTIL_INC_165 166 +#define Z_UTIL_INC_166 167 +#define Z_UTIL_INC_167 168 +#define Z_UTIL_INC_168 169 +#define Z_UTIL_INC_169 170 +#define Z_UTIL_INC_170 171 +#define Z_UTIL_INC_171 172 +#define Z_UTIL_INC_172 173 +#define Z_UTIL_INC_173 174 +#define Z_UTIL_INC_174 175 +#define Z_UTIL_INC_175 176 +#define Z_UTIL_INC_176 177 +#define Z_UTIL_INC_177 178 +#define Z_UTIL_INC_178 179 +#define Z_UTIL_INC_179 180 +#define Z_UTIL_INC_180 181 +#define Z_UTIL_INC_181 182 +#define Z_UTIL_INC_182 183 +#define Z_UTIL_INC_183 184 +#define Z_UTIL_INC_184 185 +#define Z_UTIL_INC_185 186 +#define Z_UTIL_INC_186 187 +#define Z_UTIL_INC_187 188 +#define Z_UTIL_INC_188 189 +#define Z_UTIL_INC_189 190 +#define Z_UTIL_INC_190 191 +#define Z_UTIL_INC_191 192 +#define Z_UTIL_INC_192 193 +#define Z_UTIL_INC_193 194 +#define Z_UTIL_INC_194 195 +#define Z_UTIL_INC_195 196 +#define Z_UTIL_INC_196 197 +#define Z_UTIL_INC_197 198 +#define Z_UTIL_INC_198 199 +#define Z_UTIL_INC_199 200 +#define Z_UTIL_INC_200 201 +#define Z_UTIL_INC_201 202 +#define Z_UTIL_INC_202 203 +#define Z_UTIL_INC_203 204 +#define Z_UTIL_INC_204 205 +#define Z_UTIL_INC_205 206 +#define Z_UTIL_INC_206 207 +#define Z_UTIL_INC_207 208 +#define Z_UTIL_INC_208 209 +#define Z_UTIL_INC_209 210 +#define Z_UTIL_INC_210 211 +#define Z_UTIL_INC_211 212 +#define Z_UTIL_INC_212 213 +#define Z_UTIL_INC_213 214 +#define Z_UTIL_INC_214 215 +#define Z_UTIL_INC_215 216 +#define Z_UTIL_INC_216 217 +#define Z_UTIL_INC_217 218 +#define Z_UTIL_INC_218 219 +#define Z_UTIL_INC_219 220 +#define Z_UTIL_INC_220 221 +#define Z_UTIL_INC_221 222 +#define Z_UTIL_INC_222 223 +#define Z_UTIL_INC_223 224 +#define Z_UTIL_INC_224 225 +#define Z_UTIL_INC_225 226 +#define Z_UTIL_INC_226 227 +#define Z_UTIL_INC_227 228 +#define Z_UTIL_INC_228 229 +#define Z_UTIL_INC_229 230 +#define Z_UTIL_INC_230 231 +#define Z_UTIL_INC_231 232 +#define Z_UTIL_INC_232 233 +#define Z_UTIL_INC_233 234 +#define Z_UTIL_INC_234 235 +#define Z_UTIL_INC_235 236 +#define Z_UTIL_INC_236 237 +#define Z_UTIL_INC_237 238 +#define Z_UTIL_INC_238 239 +#define Z_UTIL_INC_239 240 +#define Z_UTIL_INC_240 241 +#define Z_UTIL_INC_241 242 +#define Z_UTIL_INC_242 243 +#define Z_UTIL_INC_243 244 +#define Z_UTIL_INC_244 245 +#define Z_UTIL_INC_245 246 +#define Z_UTIL_INC_246 247 +#define Z_UTIL_INC_247 248 +#define Z_UTIL_INC_248 249 +#define Z_UTIL_INC_249 250 +#define Z_UTIL_INC_250 251 +#define Z_UTIL_INC_251 252 +#define Z_UTIL_INC_252 253 +#define Z_UTIL_INC_253 254 +#define Z_UTIL_INC_254 255 +#define Z_UTIL_INC_255 256 +#define Z_UTIL_INC_256 257 +#define Z_UTIL_INC_257 258 +#define Z_UTIL_INC_258 259 +#define Z_UTIL_INC_259 260 +#define Z_UTIL_INC_260 261 +#define Z_UTIL_INC_261 262 +#define Z_UTIL_INC_262 263 +#define Z_UTIL_INC_263 264 +#define Z_UTIL_INC_264 265 +#define Z_UTIL_INC_265 266 +#define Z_UTIL_INC_266 267 +#define Z_UTIL_INC_267 268 +#define Z_UTIL_INC_268 269 +#define Z_UTIL_INC_269 270 +#define Z_UTIL_INC_270 271 +#define Z_UTIL_INC_271 272 +#define Z_UTIL_INC_272 273 +#define Z_UTIL_INC_273 274 +#define Z_UTIL_INC_274 275 +#define Z_UTIL_INC_275 276 +#define Z_UTIL_INC_276 277 +#define Z_UTIL_INC_277 278 +#define Z_UTIL_INC_278 279 +#define Z_UTIL_INC_279 280 +#define Z_UTIL_INC_280 281 +#define Z_UTIL_INC_281 282 +#define Z_UTIL_INC_282 283 +#define Z_UTIL_INC_283 284 +#define Z_UTIL_INC_284 285 +#define Z_UTIL_INC_285 286 +#define Z_UTIL_INC_286 287 +#define Z_UTIL_INC_287 288 +#define Z_UTIL_INC_288 289 +#define Z_UTIL_INC_289 290 +#define Z_UTIL_INC_290 291 +#define Z_UTIL_INC_291 292 +#define Z_UTIL_INC_292 293 +#define Z_UTIL_INC_293 294 +#define Z_UTIL_INC_294 295 +#define Z_UTIL_INC_295 296 +#define Z_UTIL_INC_296 297 +#define Z_UTIL_INC_297 298 +#define Z_UTIL_INC_298 299 +#define Z_UTIL_INC_299 300 +#define Z_UTIL_INC_300 301 +#define Z_UTIL_INC_301 302 +#define Z_UTIL_INC_302 303 +#define Z_UTIL_INC_303 304 +#define Z_UTIL_INC_304 305 +#define Z_UTIL_INC_305 306 +#define Z_UTIL_INC_306 307 +#define Z_UTIL_INC_307 308 +#define Z_UTIL_INC_308 309 +#define Z_UTIL_INC_309 310 +#define Z_UTIL_INC_310 311 +#define Z_UTIL_INC_311 312 +#define Z_UTIL_INC_312 313 +#define Z_UTIL_INC_313 314 +#define Z_UTIL_INC_314 315 +#define Z_UTIL_INC_315 316 +#define Z_UTIL_INC_316 317 +#define Z_UTIL_INC_317 318 +#define Z_UTIL_INC_318 319 +#define Z_UTIL_INC_319 320 +#define Z_UTIL_INC_320 321 +#define Z_UTIL_INC_321 322 +#define Z_UTIL_INC_322 323 +#define Z_UTIL_INC_323 324 +#define Z_UTIL_INC_324 325 +#define Z_UTIL_INC_325 326 +#define Z_UTIL_INC_326 327 +#define Z_UTIL_INC_327 328 +#define Z_UTIL_INC_328 329 +#define Z_UTIL_INC_329 330 +#define Z_UTIL_INC_330 331 +#define Z_UTIL_INC_331 332 +#define Z_UTIL_INC_332 333 +#define Z_UTIL_INC_333 334 +#define Z_UTIL_INC_334 335 +#define Z_UTIL_INC_335 336 +#define Z_UTIL_INC_336 337 +#define Z_UTIL_INC_337 338 +#define Z_UTIL_INC_338 339 +#define Z_UTIL_INC_339 340 +#define Z_UTIL_INC_340 341 +#define Z_UTIL_INC_341 342 +#define Z_UTIL_INC_342 343 +#define Z_UTIL_INC_343 344 +#define Z_UTIL_INC_344 345 +#define Z_UTIL_INC_345 346 +#define Z_UTIL_INC_346 347 +#define Z_UTIL_INC_347 348 +#define Z_UTIL_INC_348 349 +#define Z_UTIL_INC_349 350 +#define Z_UTIL_INC_350 351 +#define Z_UTIL_INC_351 352 +#define Z_UTIL_INC_352 353 +#define Z_UTIL_INC_353 354 +#define Z_UTIL_INC_354 355 +#define Z_UTIL_INC_355 356 +#define Z_UTIL_INC_356 357 +#define Z_UTIL_INC_357 358 +#define Z_UTIL_INC_358 359 +#define Z_UTIL_INC_359 360 +#define Z_UTIL_INC_360 361 +#define Z_UTIL_INC_361 362 +#define Z_UTIL_INC_362 363 +#define Z_UTIL_INC_363 364 +#define Z_UTIL_INC_364 365 +#define Z_UTIL_INC_365 366 +#define Z_UTIL_INC_366 367 +#define Z_UTIL_INC_367 368 +#define Z_UTIL_INC_368 369 +#define Z_UTIL_INC_369 370 +#define Z_UTIL_INC_370 371 +#define Z_UTIL_INC_371 372 +#define Z_UTIL_INC_372 373 +#define Z_UTIL_INC_373 374 +#define Z_UTIL_INC_374 375 +#define Z_UTIL_INC_375 376 +#define Z_UTIL_INC_376 377 +#define Z_UTIL_INC_377 378 +#define Z_UTIL_INC_378 379 +#define Z_UTIL_INC_379 380 +#define Z_UTIL_INC_380 381 +#define Z_UTIL_INC_381 382 +#define Z_UTIL_INC_382 383 +#define Z_UTIL_INC_383 384 +#define Z_UTIL_INC_384 385 +#define Z_UTIL_INC_385 386 +#define Z_UTIL_INC_386 387 +#define Z_UTIL_INC_387 388 +#define Z_UTIL_INC_388 389 +#define Z_UTIL_INC_389 390 +#define Z_UTIL_INC_390 391 +#define Z_UTIL_INC_391 392 +#define Z_UTIL_INC_392 393 +#define Z_UTIL_INC_393 394 +#define Z_UTIL_INC_394 395 +#define Z_UTIL_INC_395 396 +#define Z_UTIL_INC_396 397 +#define Z_UTIL_INC_397 398 +#define Z_UTIL_INC_398 399 +#define Z_UTIL_INC_399 400 +#define Z_UTIL_INC_400 401 +#define Z_UTIL_INC_401 402 +#define Z_UTIL_INC_402 403 +#define Z_UTIL_INC_403 404 +#define Z_UTIL_INC_404 405 +#define Z_UTIL_INC_405 406 +#define Z_UTIL_INC_406 407 +#define Z_UTIL_INC_407 408 +#define Z_UTIL_INC_408 409 +#define Z_UTIL_INC_409 410 +#define Z_UTIL_INC_410 411 +#define Z_UTIL_INC_411 412 +#define Z_UTIL_INC_412 413 +#define Z_UTIL_INC_413 414 +#define Z_UTIL_INC_414 415 +#define Z_UTIL_INC_415 416 +#define Z_UTIL_INC_416 417 +#define Z_UTIL_INC_417 418 +#define Z_UTIL_INC_418 419 +#define Z_UTIL_INC_419 420 +#define Z_UTIL_INC_420 421 +#define Z_UTIL_INC_421 422 +#define Z_UTIL_INC_422 423 +#define Z_UTIL_INC_423 424 +#define Z_UTIL_INC_424 425 +#define Z_UTIL_INC_425 426 +#define Z_UTIL_INC_426 427 +#define Z_UTIL_INC_427 428 +#define Z_UTIL_INC_428 429 +#define Z_UTIL_INC_429 430 +#define Z_UTIL_INC_430 431 +#define Z_UTIL_INC_431 432 +#define Z_UTIL_INC_432 433 +#define Z_UTIL_INC_433 434 +#define Z_UTIL_INC_434 435 +#define Z_UTIL_INC_435 436 +#define Z_UTIL_INC_436 437 +#define Z_UTIL_INC_437 438 +#define Z_UTIL_INC_438 439 +#define Z_UTIL_INC_439 440 +#define Z_UTIL_INC_440 441 +#define Z_UTIL_INC_441 442 +#define Z_UTIL_INC_442 443 +#define Z_UTIL_INC_443 444 +#define Z_UTIL_INC_444 445 +#define Z_UTIL_INC_445 446 +#define Z_UTIL_INC_446 447 +#define Z_UTIL_INC_447 448 +#define Z_UTIL_INC_448 449 +#define Z_UTIL_INC_449 450 +#define Z_UTIL_INC_450 451 +#define Z_UTIL_INC_451 452 +#define Z_UTIL_INC_452 453 +#define Z_UTIL_INC_453 454 +#define Z_UTIL_INC_454 455 +#define Z_UTIL_INC_455 456 +#define Z_UTIL_INC_456 457 +#define Z_UTIL_INC_457 458 +#define Z_UTIL_INC_458 459 +#define Z_UTIL_INC_459 460 +#define Z_UTIL_INC_460 461 +#define Z_UTIL_INC_461 462 +#define Z_UTIL_INC_462 463 +#define Z_UTIL_INC_463 464 +#define Z_UTIL_INC_464 465 +#define Z_UTIL_INC_465 466 +#define Z_UTIL_INC_466 467 +#define Z_UTIL_INC_467 468 +#define Z_UTIL_INC_468 469 +#define Z_UTIL_INC_469 470 +#define Z_UTIL_INC_470 471 +#define Z_UTIL_INC_471 472 +#define Z_UTIL_INC_472 473 +#define Z_UTIL_INC_473 474 +#define Z_UTIL_INC_474 475 +#define Z_UTIL_INC_475 476 +#define Z_UTIL_INC_476 477 +#define Z_UTIL_INC_477 478 +#define Z_UTIL_INC_478 479 +#define Z_UTIL_INC_479 480 +#define Z_UTIL_INC_480 481 +#define Z_UTIL_INC_481 482 +#define Z_UTIL_INC_482 483 +#define Z_UTIL_INC_483 484 +#define Z_UTIL_INC_484 485 +#define Z_UTIL_INC_485 486 +#define Z_UTIL_INC_486 487 +#define Z_UTIL_INC_487 488 +#define Z_UTIL_INC_488 489 +#define Z_UTIL_INC_489 490 +#define Z_UTIL_INC_490 491 +#define Z_UTIL_INC_491 492 +#define Z_UTIL_INC_492 493 +#define Z_UTIL_INC_493 494 +#define Z_UTIL_INC_494 495 +#define Z_UTIL_INC_495 496 +#define Z_UTIL_INC_496 497 +#define Z_UTIL_INC_497 498 +#define Z_UTIL_INC_498 499 +#define Z_UTIL_INC_499 500 +#define Z_UTIL_INC_500 501 +#define Z_UTIL_INC_501 502 +#define Z_UTIL_INC_502 503 +#define Z_UTIL_INC_503 504 +#define Z_UTIL_INC_504 505 +#define Z_UTIL_INC_505 506 +#define Z_UTIL_INC_506 507 +#define Z_UTIL_INC_507 508 +#define Z_UTIL_INC_508 509 +#define Z_UTIL_INC_509 510 +#define Z_UTIL_INC_510 511 +#define Z_UTIL_INC_511 512 +#define Z_UTIL_INC_512 513 +#define Z_UTIL_INC_513 514 +#define Z_UTIL_INC_514 515 +#define Z_UTIL_INC_515 516 +#define Z_UTIL_INC_516 517 +#define Z_UTIL_INC_517 518 +#define Z_UTIL_INC_518 519 +#define Z_UTIL_INC_519 520 +#define Z_UTIL_INC_520 521 +#define Z_UTIL_INC_521 522 +#define Z_UTIL_INC_522 523 +#define Z_UTIL_INC_523 524 +#define Z_UTIL_INC_524 525 +#define Z_UTIL_INC_525 526 +#define Z_UTIL_INC_526 527 +#define Z_UTIL_INC_527 528 +#define Z_UTIL_INC_528 529 +#define Z_UTIL_INC_529 530 +#define Z_UTIL_INC_530 531 +#define Z_UTIL_INC_531 532 +#define Z_UTIL_INC_532 533 +#define Z_UTIL_INC_533 534 +#define Z_UTIL_INC_534 535 +#define Z_UTIL_INC_535 536 +#define Z_UTIL_INC_536 537 +#define Z_UTIL_INC_537 538 +#define Z_UTIL_INC_538 539 +#define Z_UTIL_INC_539 540 +#define Z_UTIL_INC_540 541 +#define Z_UTIL_INC_541 542 +#define Z_UTIL_INC_542 543 +#define Z_UTIL_INC_543 544 +#define Z_UTIL_INC_544 545 +#define Z_UTIL_INC_545 546 +#define Z_UTIL_INC_546 547 +#define Z_UTIL_INC_547 548 +#define Z_UTIL_INC_548 549 +#define Z_UTIL_INC_549 550 +#define Z_UTIL_INC_550 551 +#define Z_UTIL_INC_551 552 +#define Z_UTIL_INC_552 553 +#define Z_UTIL_INC_553 554 +#define Z_UTIL_INC_554 555 +#define Z_UTIL_INC_555 556 +#define Z_UTIL_INC_556 557 +#define Z_UTIL_INC_557 558 +#define Z_UTIL_INC_558 559 +#define Z_UTIL_INC_559 560 +#define Z_UTIL_INC_560 561 +#define Z_UTIL_INC_561 562 +#define Z_UTIL_INC_562 563 +#define Z_UTIL_INC_563 564 +#define Z_UTIL_INC_564 565 +#define Z_UTIL_INC_565 566 +#define Z_UTIL_INC_566 567 +#define Z_UTIL_INC_567 568 +#define Z_UTIL_INC_568 569 +#define Z_UTIL_INC_569 570 +#define Z_UTIL_INC_570 571 +#define Z_UTIL_INC_571 572 +#define Z_UTIL_INC_572 573 +#define Z_UTIL_INC_573 574 +#define Z_UTIL_INC_574 575 +#define Z_UTIL_INC_575 576 +#define Z_UTIL_INC_576 577 +#define Z_UTIL_INC_577 578 +#define Z_UTIL_INC_578 579 +#define Z_UTIL_INC_579 580 +#define Z_UTIL_INC_580 581 +#define Z_UTIL_INC_581 582 +#define Z_UTIL_INC_582 583 +#define Z_UTIL_INC_583 584 +#define Z_UTIL_INC_584 585 +#define Z_UTIL_INC_585 586 +#define Z_UTIL_INC_586 587 +#define Z_UTIL_INC_587 588 +#define Z_UTIL_INC_588 589 +#define Z_UTIL_INC_589 590 +#define Z_UTIL_INC_590 591 +#define Z_UTIL_INC_591 592 +#define Z_UTIL_INC_592 593 +#define Z_UTIL_INC_593 594 +#define Z_UTIL_INC_594 595 +#define Z_UTIL_INC_595 596 +#define Z_UTIL_INC_596 597 +#define Z_UTIL_INC_597 598 +#define Z_UTIL_INC_598 599 +#define Z_UTIL_INC_599 600 +#define Z_UTIL_INC_600 601 +#define Z_UTIL_INC_601 602 +#define Z_UTIL_INC_602 603 +#define Z_UTIL_INC_603 604 +#define Z_UTIL_INC_604 605 +#define Z_UTIL_INC_605 606 +#define Z_UTIL_INC_606 607 +#define Z_UTIL_INC_607 608 +#define Z_UTIL_INC_608 609 +#define Z_UTIL_INC_609 610 +#define Z_UTIL_INC_610 611 +#define Z_UTIL_INC_611 612 +#define Z_UTIL_INC_612 613 +#define Z_UTIL_INC_613 614 +#define Z_UTIL_INC_614 615 +#define Z_UTIL_INC_615 616 +#define Z_UTIL_INC_616 617 +#define Z_UTIL_INC_617 618 +#define Z_UTIL_INC_618 619 +#define Z_UTIL_INC_619 620 +#define Z_UTIL_INC_620 621 +#define Z_UTIL_INC_621 622 +#define Z_UTIL_INC_622 623 +#define Z_UTIL_INC_623 624 +#define Z_UTIL_INC_624 625 +#define Z_UTIL_INC_625 626 +#define Z_UTIL_INC_626 627 +#define Z_UTIL_INC_627 628 +#define Z_UTIL_INC_628 629 +#define Z_UTIL_INC_629 630 +#define Z_UTIL_INC_630 631 +#define Z_UTIL_INC_631 632 +#define Z_UTIL_INC_632 633 +#define Z_UTIL_INC_633 634 +#define Z_UTIL_INC_634 635 +#define Z_UTIL_INC_635 636 +#define Z_UTIL_INC_636 637 +#define Z_UTIL_INC_637 638 +#define Z_UTIL_INC_638 639 +#define Z_UTIL_INC_639 640 +#define Z_UTIL_INC_640 641 +#define Z_UTIL_INC_641 642 +#define Z_UTIL_INC_642 643 +#define Z_UTIL_INC_643 644 +#define Z_UTIL_INC_644 645 +#define Z_UTIL_INC_645 646 +#define Z_UTIL_INC_646 647 +#define Z_UTIL_INC_647 648 +#define Z_UTIL_INC_648 649 +#define Z_UTIL_INC_649 650 +#define Z_UTIL_INC_650 651 +#define Z_UTIL_INC_651 652 +#define Z_UTIL_INC_652 653 +#define Z_UTIL_INC_653 654 +#define Z_UTIL_INC_654 655 +#define Z_UTIL_INC_655 656 +#define Z_UTIL_INC_656 657 +#define Z_UTIL_INC_657 658 +#define Z_UTIL_INC_658 659 +#define Z_UTIL_INC_659 660 +#define Z_UTIL_INC_660 661 +#define Z_UTIL_INC_661 662 +#define Z_UTIL_INC_662 663 +#define Z_UTIL_INC_663 664 +#define Z_UTIL_INC_664 665 +#define Z_UTIL_INC_665 666 +#define Z_UTIL_INC_666 667 +#define Z_UTIL_INC_667 668 +#define Z_UTIL_INC_668 669 +#define Z_UTIL_INC_669 670 +#define Z_UTIL_INC_670 671 +#define Z_UTIL_INC_671 672 +#define Z_UTIL_INC_672 673 +#define Z_UTIL_INC_673 674 +#define Z_UTIL_INC_674 675 +#define Z_UTIL_INC_675 676 +#define Z_UTIL_INC_676 677 +#define Z_UTIL_INC_677 678 +#define Z_UTIL_INC_678 679 +#define Z_UTIL_INC_679 680 +#define Z_UTIL_INC_680 681 +#define Z_UTIL_INC_681 682 +#define Z_UTIL_INC_682 683 +#define Z_UTIL_INC_683 684 +#define Z_UTIL_INC_684 685 +#define Z_UTIL_INC_685 686 +#define Z_UTIL_INC_686 687 +#define Z_UTIL_INC_687 688 +#define Z_UTIL_INC_688 689 +#define Z_UTIL_INC_689 690 +#define Z_UTIL_INC_690 691 +#define Z_UTIL_INC_691 692 +#define Z_UTIL_INC_692 693 +#define Z_UTIL_INC_693 694 +#define Z_UTIL_INC_694 695 +#define Z_UTIL_INC_695 696 +#define Z_UTIL_INC_696 697 +#define Z_UTIL_INC_697 698 +#define Z_UTIL_INC_698 699 +#define Z_UTIL_INC_699 700 +#define Z_UTIL_INC_700 701 +#define Z_UTIL_INC_701 702 +#define Z_UTIL_INC_702 703 +#define Z_UTIL_INC_703 704 +#define Z_UTIL_INC_704 705 +#define Z_UTIL_INC_705 706 +#define Z_UTIL_INC_706 707 +#define Z_UTIL_INC_707 708 +#define Z_UTIL_INC_708 709 +#define Z_UTIL_INC_709 710 +#define Z_UTIL_INC_710 711 +#define Z_UTIL_INC_711 712 +#define Z_UTIL_INC_712 713 +#define Z_UTIL_INC_713 714 +#define Z_UTIL_INC_714 715 +#define Z_UTIL_INC_715 716 +#define Z_UTIL_INC_716 717 +#define Z_UTIL_INC_717 718 +#define Z_UTIL_INC_718 719 +#define Z_UTIL_INC_719 720 +#define Z_UTIL_INC_720 721 +#define Z_UTIL_INC_721 722 +#define Z_UTIL_INC_722 723 +#define Z_UTIL_INC_723 724 +#define Z_UTIL_INC_724 725 +#define Z_UTIL_INC_725 726 +#define Z_UTIL_INC_726 727 +#define Z_UTIL_INC_727 728 +#define Z_UTIL_INC_728 729 +#define Z_UTIL_INC_729 730 +#define Z_UTIL_INC_730 731 +#define Z_UTIL_INC_731 732 +#define Z_UTIL_INC_732 733 +#define Z_UTIL_INC_733 734 +#define Z_UTIL_INC_734 735 +#define Z_UTIL_INC_735 736 +#define Z_UTIL_INC_736 737 +#define Z_UTIL_INC_737 738 +#define Z_UTIL_INC_738 739 +#define Z_UTIL_INC_739 740 +#define Z_UTIL_INC_740 741 +#define Z_UTIL_INC_741 742 +#define Z_UTIL_INC_742 743 +#define Z_UTIL_INC_743 744 +#define Z_UTIL_INC_744 745 +#define Z_UTIL_INC_745 746 +#define Z_UTIL_INC_746 747 +#define Z_UTIL_INC_747 748 +#define Z_UTIL_INC_748 749 +#define Z_UTIL_INC_749 750 +#define Z_UTIL_INC_750 751 +#define Z_UTIL_INC_751 752 +#define Z_UTIL_INC_752 753 +#define Z_UTIL_INC_753 754 +#define Z_UTIL_INC_754 755 +#define Z_UTIL_INC_755 756 +#define Z_UTIL_INC_756 757 +#define Z_UTIL_INC_757 758 +#define Z_UTIL_INC_758 759 +#define Z_UTIL_INC_759 760 +#define Z_UTIL_INC_760 761 +#define Z_UTIL_INC_761 762 +#define Z_UTIL_INC_762 763 +#define Z_UTIL_INC_763 764 +#define Z_UTIL_INC_764 765 +#define Z_UTIL_INC_765 766 +#define Z_UTIL_INC_766 767 +#define Z_UTIL_INC_767 768 +#define Z_UTIL_INC_768 769 +#define Z_UTIL_INC_769 770 +#define Z_UTIL_INC_770 771 +#define Z_UTIL_INC_771 772 +#define Z_UTIL_INC_772 773 +#define Z_UTIL_INC_773 774 +#define Z_UTIL_INC_774 775 +#define Z_UTIL_INC_775 776 +#define Z_UTIL_INC_776 777 +#define Z_UTIL_INC_777 778 +#define Z_UTIL_INC_778 779 +#define Z_UTIL_INC_779 780 +#define Z_UTIL_INC_780 781 +#define Z_UTIL_INC_781 782 +#define Z_UTIL_INC_782 783 +#define Z_UTIL_INC_783 784 +#define Z_UTIL_INC_784 785 +#define Z_UTIL_INC_785 786 +#define Z_UTIL_INC_786 787 +#define Z_UTIL_INC_787 788 +#define Z_UTIL_INC_788 789 +#define Z_UTIL_INC_789 790 +#define Z_UTIL_INC_790 791 +#define Z_UTIL_INC_791 792 +#define Z_UTIL_INC_792 793 +#define Z_UTIL_INC_793 794 +#define Z_UTIL_INC_794 795 +#define Z_UTIL_INC_795 796 +#define Z_UTIL_INC_796 797 +#define Z_UTIL_INC_797 798 +#define Z_UTIL_INC_798 799 +#define Z_UTIL_INC_799 800 +#define Z_UTIL_INC_800 801 +#define Z_UTIL_INC_801 802 +#define Z_UTIL_INC_802 803 +#define Z_UTIL_INC_803 804 +#define Z_UTIL_INC_804 805 +#define Z_UTIL_INC_805 806 +#define Z_UTIL_INC_806 807 +#define Z_UTIL_INC_807 808 +#define Z_UTIL_INC_808 809 +#define Z_UTIL_INC_809 810 +#define Z_UTIL_INC_810 811 +#define Z_UTIL_INC_811 812 +#define Z_UTIL_INC_812 813 +#define Z_UTIL_INC_813 814 +#define Z_UTIL_INC_814 815 +#define Z_UTIL_INC_815 816 +#define Z_UTIL_INC_816 817 +#define Z_UTIL_INC_817 818 +#define Z_UTIL_INC_818 819 +#define Z_UTIL_INC_819 820 +#define Z_UTIL_INC_820 821 +#define Z_UTIL_INC_821 822 +#define Z_UTIL_INC_822 823 +#define Z_UTIL_INC_823 824 +#define Z_UTIL_INC_824 825 +#define Z_UTIL_INC_825 826 +#define Z_UTIL_INC_826 827 +#define Z_UTIL_INC_827 828 +#define Z_UTIL_INC_828 829 +#define Z_UTIL_INC_829 830 +#define Z_UTIL_INC_830 831 +#define Z_UTIL_INC_831 832 +#define Z_UTIL_INC_832 833 +#define Z_UTIL_INC_833 834 +#define Z_UTIL_INC_834 835 +#define Z_UTIL_INC_835 836 +#define Z_UTIL_INC_836 837 +#define Z_UTIL_INC_837 838 +#define Z_UTIL_INC_838 839 +#define Z_UTIL_INC_839 840 +#define Z_UTIL_INC_840 841 +#define Z_UTIL_INC_841 842 +#define Z_UTIL_INC_842 843 +#define Z_UTIL_INC_843 844 +#define Z_UTIL_INC_844 845 +#define Z_UTIL_INC_845 846 +#define Z_UTIL_INC_846 847 +#define Z_UTIL_INC_847 848 +#define Z_UTIL_INC_848 849 +#define Z_UTIL_INC_849 850 +#define Z_UTIL_INC_850 851 +#define Z_UTIL_INC_851 852 +#define Z_UTIL_INC_852 853 +#define Z_UTIL_INC_853 854 +#define Z_UTIL_INC_854 855 +#define Z_UTIL_INC_855 856 +#define Z_UTIL_INC_856 857 +#define Z_UTIL_INC_857 858 +#define Z_UTIL_INC_858 859 +#define Z_UTIL_INC_859 860 +#define Z_UTIL_INC_860 861 +#define Z_UTIL_INC_861 862 +#define Z_UTIL_INC_862 863 +#define Z_UTIL_INC_863 864 +#define Z_UTIL_INC_864 865 +#define Z_UTIL_INC_865 866 +#define Z_UTIL_INC_866 867 +#define Z_UTIL_INC_867 868 +#define Z_UTIL_INC_868 869 +#define Z_UTIL_INC_869 870 +#define Z_UTIL_INC_870 871 +#define Z_UTIL_INC_871 872 +#define Z_UTIL_INC_872 873 +#define Z_UTIL_INC_873 874 +#define Z_UTIL_INC_874 875 +#define Z_UTIL_INC_875 876 +#define Z_UTIL_INC_876 877 +#define Z_UTIL_INC_877 878 +#define Z_UTIL_INC_878 879 +#define Z_UTIL_INC_879 880 +#define Z_UTIL_INC_880 881 +#define Z_UTIL_INC_881 882 +#define Z_UTIL_INC_882 883 +#define Z_UTIL_INC_883 884 +#define Z_UTIL_INC_884 885 +#define Z_UTIL_INC_885 886 +#define Z_UTIL_INC_886 887 +#define Z_UTIL_INC_887 888 +#define Z_UTIL_INC_888 889 +#define Z_UTIL_INC_889 890 +#define Z_UTIL_INC_890 891 +#define Z_UTIL_INC_891 892 +#define Z_UTIL_INC_892 893 +#define Z_UTIL_INC_893 894 +#define Z_UTIL_INC_894 895 +#define Z_UTIL_INC_895 896 +#define Z_UTIL_INC_896 897 +#define Z_UTIL_INC_897 898 +#define Z_UTIL_INC_898 899 +#define Z_UTIL_INC_899 900 +#define Z_UTIL_INC_900 901 +#define Z_UTIL_INC_901 902 +#define Z_UTIL_INC_902 903 +#define Z_UTIL_INC_903 904 +#define Z_UTIL_INC_904 905 +#define Z_UTIL_INC_905 906 +#define Z_UTIL_INC_906 907 +#define Z_UTIL_INC_907 908 +#define Z_UTIL_INC_908 909 +#define Z_UTIL_INC_909 910 +#define Z_UTIL_INC_910 911 +#define Z_UTIL_INC_911 912 +#define Z_UTIL_INC_912 913 +#define Z_UTIL_INC_913 914 +#define Z_UTIL_INC_914 915 +#define Z_UTIL_INC_915 916 +#define Z_UTIL_INC_916 917 +#define Z_UTIL_INC_917 918 +#define Z_UTIL_INC_918 919 +#define Z_UTIL_INC_919 920 +#define Z_UTIL_INC_920 921 +#define Z_UTIL_INC_921 922 +#define Z_UTIL_INC_922 923 +#define Z_UTIL_INC_923 924 +#define Z_UTIL_INC_924 925 +#define Z_UTIL_INC_925 926 +#define Z_UTIL_INC_926 927 +#define Z_UTIL_INC_927 928 +#define Z_UTIL_INC_928 929 +#define Z_UTIL_INC_929 930 +#define Z_UTIL_INC_930 931 +#define Z_UTIL_INC_931 932 +#define Z_UTIL_INC_932 933 +#define Z_UTIL_INC_933 934 +#define Z_UTIL_INC_934 935 +#define Z_UTIL_INC_935 936 +#define Z_UTIL_INC_936 937 +#define Z_UTIL_INC_937 938 +#define Z_UTIL_INC_938 939 +#define Z_UTIL_INC_939 940 +#define Z_UTIL_INC_940 941 +#define Z_UTIL_INC_941 942 +#define Z_UTIL_INC_942 943 +#define Z_UTIL_INC_943 944 +#define Z_UTIL_INC_944 945 +#define Z_UTIL_INC_945 946 +#define Z_UTIL_INC_946 947 +#define Z_UTIL_INC_947 948 +#define Z_UTIL_INC_948 949 +#define Z_UTIL_INC_949 950 +#define Z_UTIL_INC_950 951 +#define Z_UTIL_INC_951 952 +#define Z_UTIL_INC_952 953 +#define Z_UTIL_INC_953 954 +#define Z_UTIL_INC_954 955 +#define Z_UTIL_INC_955 956 +#define Z_UTIL_INC_956 957 +#define Z_UTIL_INC_957 958 +#define Z_UTIL_INC_958 959 +#define Z_UTIL_INC_959 960 +#define Z_UTIL_INC_960 961 +#define Z_UTIL_INC_961 962 +#define Z_UTIL_INC_962 963 +#define Z_UTIL_INC_963 964 +#define Z_UTIL_INC_964 965 +#define Z_UTIL_INC_965 966 +#define Z_UTIL_INC_966 967 +#define Z_UTIL_INC_967 968 +#define Z_UTIL_INC_968 969 +#define Z_UTIL_INC_969 970 +#define Z_UTIL_INC_970 971 +#define Z_UTIL_INC_971 972 +#define Z_UTIL_INC_972 973 +#define Z_UTIL_INC_973 974 +#define Z_UTIL_INC_974 975 +#define Z_UTIL_INC_975 976 +#define Z_UTIL_INC_976 977 +#define Z_UTIL_INC_977 978 +#define Z_UTIL_INC_978 979 +#define Z_UTIL_INC_979 980 +#define Z_UTIL_INC_980 981 +#define Z_UTIL_INC_981 982 +#define Z_UTIL_INC_982 983 +#define Z_UTIL_INC_983 984 +#define Z_UTIL_INC_984 985 +#define Z_UTIL_INC_985 986 +#define Z_UTIL_INC_986 987 +#define Z_UTIL_INC_987 988 +#define Z_UTIL_INC_988 989 +#define Z_UTIL_INC_989 990 +#define Z_UTIL_INC_990 991 +#define Z_UTIL_INC_991 992 +#define Z_UTIL_INC_992 993 +#define Z_UTIL_INC_993 994 +#define Z_UTIL_INC_994 995 +#define Z_UTIL_INC_995 996 +#define Z_UTIL_INC_996 997 +#define Z_UTIL_INC_997 998 +#define Z_UTIL_INC_998 999 +#define Z_UTIL_INC_999 1000 +#define Z_UTIL_INC_1000 1001 +#define Z_UTIL_INC_1001 1002 +#define Z_UTIL_INC_1002 1003 +#define Z_UTIL_INC_1003 1004 +#define Z_UTIL_INC_1004 1005 +#define Z_UTIL_INC_1005 1006 +#define Z_UTIL_INC_1006 1007 +#define Z_UTIL_INC_1007 1008 +#define Z_UTIL_INC_1008 1009 +#define Z_UTIL_INC_1009 1010 +#define Z_UTIL_INC_1010 1011 +#define Z_UTIL_INC_1011 1012 +#define Z_UTIL_INC_1012 1013 +#define Z_UTIL_INC_1013 1014 +#define Z_UTIL_INC_1014 1015 +#define Z_UTIL_INC_1015 1016 +#define Z_UTIL_INC_1016 1017 +#define Z_UTIL_INC_1017 1018 +#define Z_UTIL_INC_1018 1019 +#define Z_UTIL_INC_1019 1020 +#define Z_UTIL_INC_1020 1021 +#define Z_UTIL_INC_1021 1022 +#define Z_UTIL_INC_1022 1023 +#define Z_UTIL_INC_1023 1024 +#define Z_UTIL_INC_1024 1025 +#define Z_UTIL_INC_1025 1026 +#define Z_UTIL_INC_1026 1027 +#define Z_UTIL_INC_1027 1028 +#define Z_UTIL_INC_1028 1029 +#define Z_UTIL_INC_1029 1030 +#define Z_UTIL_INC_1030 1031 +#define Z_UTIL_INC_1031 1032 +#define Z_UTIL_INC_1032 1033 +#define Z_UTIL_INC_1033 1034 +#define Z_UTIL_INC_1034 1035 +#define Z_UTIL_INC_1035 1036 +#define Z_UTIL_INC_1036 1037 +#define Z_UTIL_INC_1037 1038 +#define Z_UTIL_INC_1038 1039 +#define Z_UTIL_INC_1039 1040 +#define Z_UTIL_INC_1040 1041 +#define Z_UTIL_INC_1041 1042 +#define Z_UTIL_INC_1042 1043 +#define Z_UTIL_INC_1043 1044 +#define Z_UTIL_INC_1044 1045 +#define Z_UTIL_INC_1045 1046 +#define Z_UTIL_INC_1046 1047 +#define Z_UTIL_INC_1047 1048 +#define Z_UTIL_INC_1048 1049 +#define Z_UTIL_INC_1049 1050 +#define Z_UTIL_INC_1050 1051 +#define Z_UTIL_INC_1051 1052 +#define Z_UTIL_INC_1052 1053 +#define Z_UTIL_INC_1053 1054 +#define Z_UTIL_INC_1054 1055 +#define Z_UTIL_INC_1055 1056 +#define Z_UTIL_INC_1056 1057 +#define Z_UTIL_INC_1057 1058 +#define Z_UTIL_INC_1058 1059 +#define Z_UTIL_INC_1059 1060 +#define Z_UTIL_INC_1060 1061 +#define Z_UTIL_INC_1061 1062 +#define Z_UTIL_INC_1062 1063 +#define Z_UTIL_INC_1063 1064 +#define Z_UTIL_INC_1064 1065 +#define Z_UTIL_INC_1065 1066 +#define Z_UTIL_INC_1066 1067 +#define Z_UTIL_INC_1067 1068 +#define Z_UTIL_INC_1068 1069 +#define Z_UTIL_INC_1069 1070 +#define Z_UTIL_INC_1070 1071 +#define Z_UTIL_INC_1071 1072 +#define Z_UTIL_INC_1072 1073 +#define Z_UTIL_INC_1073 1074 +#define Z_UTIL_INC_1074 1075 +#define Z_UTIL_INC_1075 1076 +#define Z_UTIL_INC_1076 1077 +#define Z_UTIL_INC_1077 1078 +#define Z_UTIL_INC_1078 1079 +#define Z_UTIL_INC_1079 1080 +#define Z_UTIL_INC_1080 1081 +#define Z_UTIL_INC_1081 1082 +#define Z_UTIL_INC_1082 1083 +#define Z_UTIL_INC_1083 1084 +#define Z_UTIL_INC_1084 1085 +#define Z_UTIL_INC_1085 1086 +#define Z_UTIL_INC_1086 1087 +#define Z_UTIL_INC_1087 1088 +#define Z_UTIL_INC_1088 1089 +#define Z_UTIL_INC_1089 1090 +#define Z_UTIL_INC_1090 1091 +#define Z_UTIL_INC_1091 1092 +#define Z_UTIL_INC_1092 1093 +#define Z_UTIL_INC_1093 1094 +#define Z_UTIL_INC_1094 1095 +#define Z_UTIL_INC_1095 1096 +#define Z_UTIL_INC_1096 1097 +#define Z_UTIL_INC_1097 1098 +#define Z_UTIL_INC_1098 1099 +#define Z_UTIL_INC_1099 1100 +#define Z_UTIL_INC_1100 1101 +#define Z_UTIL_INC_1101 1102 +#define Z_UTIL_INC_1102 1103 +#define Z_UTIL_INC_1103 1104 +#define Z_UTIL_INC_1104 1105 +#define Z_UTIL_INC_1105 1106 +#define Z_UTIL_INC_1106 1107 +#define Z_UTIL_INC_1107 1108 +#define Z_UTIL_INC_1108 1109 +#define Z_UTIL_INC_1109 1110 +#define Z_UTIL_INC_1110 1111 +#define Z_UTIL_INC_1111 1112 +#define Z_UTIL_INC_1112 1113 +#define Z_UTIL_INC_1113 1114 +#define Z_UTIL_INC_1114 1115 +#define Z_UTIL_INC_1115 1116 +#define Z_UTIL_INC_1116 1117 +#define Z_UTIL_INC_1117 1118 +#define Z_UTIL_INC_1118 1119 +#define Z_UTIL_INC_1119 1120 +#define Z_UTIL_INC_1120 1121 +#define Z_UTIL_INC_1121 1122 +#define Z_UTIL_INC_1122 1123 +#define Z_UTIL_INC_1123 1124 +#define Z_UTIL_INC_1124 1125 +#define Z_UTIL_INC_1125 1126 +#define Z_UTIL_INC_1126 1127 +#define Z_UTIL_INC_1127 1128 +#define Z_UTIL_INC_1128 1129 +#define Z_UTIL_INC_1129 1130 +#define Z_UTIL_INC_1130 1131 +#define Z_UTIL_INC_1131 1132 +#define Z_UTIL_INC_1132 1133 +#define Z_UTIL_INC_1133 1134 +#define Z_UTIL_INC_1134 1135 +#define Z_UTIL_INC_1135 1136 +#define Z_UTIL_INC_1136 1137 +#define Z_UTIL_INC_1137 1138 +#define Z_UTIL_INC_1138 1139 +#define Z_UTIL_INC_1139 1140 +#define Z_UTIL_INC_1140 1141 +#define Z_UTIL_INC_1141 1142 +#define Z_UTIL_INC_1142 1143 +#define Z_UTIL_INC_1143 1144 +#define Z_UTIL_INC_1144 1145 +#define Z_UTIL_INC_1145 1146 +#define Z_UTIL_INC_1146 1147 +#define Z_UTIL_INC_1147 1148 +#define Z_UTIL_INC_1148 1149 +#define Z_UTIL_INC_1149 1150 +#define Z_UTIL_INC_1150 1151 +#define Z_UTIL_INC_1151 1152 +#define Z_UTIL_INC_1152 1153 +#define Z_UTIL_INC_1153 1154 +#define Z_UTIL_INC_1154 1155 +#define Z_UTIL_INC_1155 1156 +#define Z_UTIL_INC_1156 1157 +#define Z_UTIL_INC_1157 1158 +#define Z_UTIL_INC_1158 1159 +#define Z_UTIL_INC_1159 1160 +#define Z_UTIL_INC_1160 1161 +#define Z_UTIL_INC_1161 1162 +#define Z_UTIL_INC_1162 1163 +#define Z_UTIL_INC_1163 1164 +#define Z_UTIL_INC_1164 1165 +#define Z_UTIL_INC_1165 1166 +#define Z_UTIL_INC_1166 1167 +#define Z_UTIL_INC_1167 1168 +#define Z_UTIL_INC_1168 1169 +#define Z_UTIL_INC_1169 1170 +#define Z_UTIL_INC_1170 1171 +#define Z_UTIL_INC_1171 1172 +#define Z_UTIL_INC_1172 1173 +#define Z_UTIL_INC_1173 1174 +#define Z_UTIL_INC_1174 1175 +#define Z_UTIL_INC_1175 1176 +#define Z_UTIL_INC_1176 1177 +#define Z_UTIL_INC_1177 1178 +#define Z_UTIL_INC_1178 1179 +#define Z_UTIL_INC_1179 1180 +#define Z_UTIL_INC_1180 1181 +#define Z_UTIL_INC_1181 1182 +#define Z_UTIL_INC_1182 1183 +#define Z_UTIL_INC_1183 1184 +#define Z_UTIL_INC_1184 1185 +#define Z_UTIL_INC_1185 1186 +#define Z_UTIL_INC_1186 1187 +#define Z_UTIL_INC_1187 1188 +#define Z_UTIL_INC_1188 1189 +#define Z_UTIL_INC_1189 1190 +#define Z_UTIL_INC_1190 1191 +#define Z_UTIL_INC_1191 1192 +#define Z_UTIL_INC_1192 1193 +#define Z_UTIL_INC_1193 1194 +#define Z_UTIL_INC_1194 1195 +#define Z_UTIL_INC_1195 1196 +#define Z_UTIL_INC_1196 1197 +#define Z_UTIL_INC_1197 1198 +#define Z_UTIL_INC_1198 1199 +#define Z_UTIL_INC_1199 1200 +#define Z_UTIL_INC_1200 1201 +#define Z_UTIL_INC_1201 1202 +#define Z_UTIL_INC_1202 1203 +#define Z_UTIL_INC_1203 1204 +#define Z_UTIL_INC_1204 1205 +#define Z_UTIL_INC_1205 1206 +#define Z_UTIL_INC_1206 1207 +#define Z_UTIL_INC_1207 1208 +#define Z_UTIL_INC_1208 1209 +#define Z_UTIL_INC_1209 1210 +#define Z_UTIL_INC_1210 1211 +#define Z_UTIL_INC_1211 1212 +#define Z_UTIL_INC_1212 1213 +#define Z_UTIL_INC_1213 1214 +#define Z_UTIL_INC_1214 1215 +#define Z_UTIL_INC_1215 1216 +#define Z_UTIL_INC_1216 1217 +#define Z_UTIL_INC_1217 1218 +#define Z_UTIL_INC_1218 1219 +#define Z_UTIL_INC_1219 1220 +#define Z_UTIL_INC_1220 1221 +#define Z_UTIL_INC_1221 1222 +#define Z_UTIL_INC_1222 1223 +#define Z_UTIL_INC_1223 1224 +#define Z_UTIL_INC_1224 1225 +#define Z_UTIL_INC_1225 1226 +#define Z_UTIL_INC_1226 1227 +#define Z_UTIL_INC_1227 1228 +#define Z_UTIL_INC_1228 1229 +#define Z_UTIL_INC_1229 1230 +#define Z_UTIL_INC_1230 1231 +#define Z_UTIL_INC_1231 1232 +#define Z_UTIL_INC_1232 1233 +#define Z_UTIL_INC_1233 1234 +#define Z_UTIL_INC_1234 1235 +#define Z_UTIL_INC_1235 1236 +#define Z_UTIL_INC_1236 1237 +#define Z_UTIL_INC_1237 1238 +#define Z_UTIL_INC_1238 1239 +#define Z_UTIL_INC_1239 1240 +#define Z_UTIL_INC_1240 1241 +#define Z_UTIL_INC_1241 1242 +#define Z_UTIL_INC_1242 1243 +#define Z_UTIL_INC_1243 1244 +#define Z_UTIL_INC_1244 1245 +#define Z_UTIL_INC_1245 1246 +#define Z_UTIL_INC_1246 1247 +#define Z_UTIL_INC_1247 1248 +#define Z_UTIL_INC_1248 1249 +#define Z_UTIL_INC_1249 1250 +#define Z_UTIL_INC_1250 1251 +#define Z_UTIL_INC_1251 1252 +#define Z_UTIL_INC_1252 1253 +#define Z_UTIL_INC_1253 1254 +#define Z_UTIL_INC_1254 1255 +#define Z_UTIL_INC_1255 1256 +#define Z_UTIL_INC_1256 1257 +#define Z_UTIL_INC_1257 1258 +#define Z_UTIL_INC_1258 1259 +#define Z_UTIL_INC_1259 1260 +#define Z_UTIL_INC_1260 1261 +#define Z_UTIL_INC_1261 1262 +#define Z_UTIL_INC_1262 1263 +#define Z_UTIL_INC_1263 1264 +#define Z_UTIL_INC_1264 1265 +#define Z_UTIL_INC_1265 1266 +#define Z_UTIL_INC_1266 1267 +#define Z_UTIL_INC_1267 1268 +#define Z_UTIL_INC_1268 1269 +#define Z_UTIL_INC_1269 1270 +#define Z_UTIL_INC_1270 1271 +#define Z_UTIL_INC_1271 1272 +#define Z_UTIL_INC_1272 1273 +#define Z_UTIL_INC_1273 1274 +#define Z_UTIL_INC_1274 1275 +#define Z_UTIL_INC_1275 1276 +#define Z_UTIL_INC_1276 1277 +#define Z_UTIL_INC_1277 1278 +#define Z_UTIL_INC_1278 1279 +#define Z_UTIL_INC_1279 1280 +#define Z_UTIL_INC_1280 1281 +#define Z_UTIL_INC_1281 1282 +#define Z_UTIL_INC_1282 1283 +#define Z_UTIL_INC_1283 1284 +#define Z_UTIL_INC_1284 1285 +#define Z_UTIL_INC_1285 1286 +#define Z_UTIL_INC_1286 1287 +#define Z_UTIL_INC_1287 1288 +#define Z_UTIL_INC_1288 1289 +#define Z_UTIL_INC_1289 1290 +#define Z_UTIL_INC_1290 1291 +#define Z_UTIL_INC_1291 1292 +#define Z_UTIL_INC_1292 1293 +#define Z_UTIL_INC_1293 1294 +#define Z_UTIL_INC_1294 1295 +#define Z_UTIL_INC_1295 1296 +#define Z_UTIL_INC_1296 1297 +#define Z_UTIL_INC_1297 1298 +#define Z_UTIL_INC_1298 1299 +#define Z_UTIL_INC_1299 1300 +#define Z_UTIL_INC_1300 1301 +#define Z_UTIL_INC_1301 1302 +#define Z_UTIL_INC_1302 1303 +#define Z_UTIL_INC_1303 1304 +#define Z_UTIL_INC_1304 1305 +#define Z_UTIL_INC_1305 1306 +#define Z_UTIL_INC_1306 1307 +#define Z_UTIL_INC_1307 1308 +#define Z_UTIL_INC_1308 1309 +#define Z_UTIL_INC_1309 1310 +#define Z_UTIL_INC_1310 1311 +#define Z_UTIL_INC_1311 1312 +#define Z_UTIL_INC_1312 1313 +#define Z_UTIL_INC_1313 1314 +#define Z_UTIL_INC_1314 1315 +#define Z_UTIL_INC_1315 1316 +#define Z_UTIL_INC_1316 1317 +#define Z_UTIL_INC_1317 1318 +#define Z_UTIL_INC_1318 1319 +#define Z_UTIL_INC_1319 1320 +#define Z_UTIL_INC_1320 1321 +#define Z_UTIL_INC_1321 1322 +#define Z_UTIL_INC_1322 1323 +#define Z_UTIL_INC_1323 1324 +#define Z_UTIL_INC_1324 1325 +#define Z_UTIL_INC_1325 1326 +#define Z_UTIL_INC_1326 1327 +#define Z_UTIL_INC_1327 1328 +#define Z_UTIL_INC_1328 1329 +#define Z_UTIL_INC_1329 1330 +#define Z_UTIL_INC_1330 1331 +#define Z_UTIL_INC_1331 1332 +#define Z_UTIL_INC_1332 1333 +#define Z_UTIL_INC_1333 1334 +#define Z_UTIL_INC_1334 1335 +#define Z_UTIL_INC_1335 1336 +#define Z_UTIL_INC_1336 1337 +#define Z_UTIL_INC_1337 1338 +#define Z_UTIL_INC_1338 1339 +#define Z_UTIL_INC_1339 1340 +#define Z_UTIL_INC_1340 1341 +#define Z_UTIL_INC_1341 1342 +#define Z_UTIL_INC_1342 1343 +#define Z_UTIL_INC_1343 1344 +#define Z_UTIL_INC_1344 1345 +#define Z_UTIL_INC_1345 1346 +#define Z_UTIL_INC_1346 1347 +#define Z_UTIL_INC_1347 1348 +#define Z_UTIL_INC_1348 1349 +#define Z_UTIL_INC_1349 1350 +#define Z_UTIL_INC_1350 1351 +#define Z_UTIL_INC_1351 1352 +#define Z_UTIL_INC_1352 1353 +#define Z_UTIL_INC_1353 1354 +#define Z_UTIL_INC_1354 1355 +#define Z_UTIL_INC_1355 1356 +#define Z_UTIL_INC_1356 1357 +#define Z_UTIL_INC_1357 1358 +#define Z_UTIL_INC_1358 1359 +#define Z_UTIL_INC_1359 1360 +#define Z_UTIL_INC_1360 1361 +#define Z_UTIL_INC_1361 1362 +#define Z_UTIL_INC_1362 1363 +#define Z_UTIL_INC_1363 1364 +#define Z_UTIL_INC_1364 1365 +#define Z_UTIL_INC_1365 1366 +#define Z_UTIL_INC_1366 1367 +#define Z_UTIL_INC_1367 1368 +#define Z_UTIL_INC_1368 1369 +#define Z_UTIL_INC_1369 1370 +#define Z_UTIL_INC_1370 1371 +#define Z_UTIL_INC_1371 1372 +#define Z_UTIL_INC_1372 1373 +#define Z_UTIL_INC_1373 1374 +#define Z_UTIL_INC_1374 1375 +#define Z_UTIL_INC_1375 1376 +#define Z_UTIL_INC_1376 1377 +#define Z_UTIL_INC_1377 1378 +#define Z_UTIL_INC_1378 1379 +#define Z_UTIL_INC_1379 1380 +#define Z_UTIL_INC_1380 1381 +#define Z_UTIL_INC_1381 1382 +#define Z_UTIL_INC_1382 1383 +#define Z_UTIL_INC_1383 1384 +#define Z_UTIL_INC_1384 1385 +#define Z_UTIL_INC_1385 1386 +#define Z_UTIL_INC_1386 1387 +#define Z_UTIL_INC_1387 1388 +#define Z_UTIL_INC_1388 1389 +#define Z_UTIL_INC_1389 1390 +#define Z_UTIL_INC_1390 1391 +#define Z_UTIL_INC_1391 1392 +#define Z_UTIL_INC_1392 1393 +#define Z_UTIL_INC_1393 1394 +#define Z_UTIL_INC_1394 1395 +#define Z_UTIL_INC_1395 1396 +#define Z_UTIL_INC_1396 1397 +#define Z_UTIL_INC_1397 1398 +#define Z_UTIL_INC_1398 1399 +#define Z_UTIL_INC_1399 1400 +#define Z_UTIL_INC_1400 1401 +#define Z_UTIL_INC_1401 1402 +#define Z_UTIL_INC_1402 1403 +#define Z_UTIL_INC_1403 1404 +#define Z_UTIL_INC_1404 1405 +#define Z_UTIL_INC_1405 1406 +#define Z_UTIL_INC_1406 1407 +#define Z_UTIL_INC_1407 1408 +#define Z_UTIL_INC_1408 1409 +#define Z_UTIL_INC_1409 1410 +#define Z_UTIL_INC_1410 1411 +#define Z_UTIL_INC_1411 1412 +#define Z_UTIL_INC_1412 1413 +#define Z_UTIL_INC_1413 1414 +#define Z_UTIL_INC_1414 1415 +#define Z_UTIL_INC_1415 1416 +#define Z_UTIL_INC_1416 1417 +#define Z_UTIL_INC_1417 1418 +#define Z_UTIL_INC_1418 1419 +#define Z_UTIL_INC_1419 1420 +#define Z_UTIL_INC_1420 1421 +#define Z_UTIL_INC_1421 1422 +#define Z_UTIL_INC_1422 1423 +#define Z_UTIL_INC_1423 1424 +#define Z_UTIL_INC_1424 1425 +#define Z_UTIL_INC_1425 1426 +#define Z_UTIL_INC_1426 1427 +#define Z_UTIL_INC_1427 1428 +#define Z_UTIL_INC_1428 1429 +#define Z_UTIL_INC_1429 1430 +#define Z_UTIL_INC_1430 1431 +#define Z_UTIL_INC_1431 1432 +#define Z_UTIL_INC_1432 1433 +#define Z_UTIL_INC_1433 1434 +#define Z_UTIL_INC_1434 1435 +#define Z_UTIL_INC_1435 1436 +#define Z_UTIL_INC_1436 1437 +#define Z_UTIL_INC_1437 1438 +#define Z_UTIL_INC_1438 1439 +#define Z_UTIL_INC_1439 1440 +#define Z_UTIL_INC_1440 1441 +#define Z_UTIL_INC_1441 1442 +#define Z_UTIL_INC_1442 1443 +#define Z_UTIL_INC_1443 1444 +#define Z_UTIL_INC_1444 1445 +#define Z_UTIL_INC_1445 1446 +#define Z_UTIL_INC_1446 1447 +#define Z_UTIL_INC_1447 1448 +#define Z_UTIL_INC_1448 1449 +#define Z_UTIL_INC_1449 1450 +#define Z_UTIL_INC_1450 1451 +#define Z_UTIL_INC_1451 1452 +#define Z_UTIL_INC_1452 1453 +#define Z_UTIL_INC_1453 1454 +#define Z_UTIL_INC_1454 1455 +#define Z_UTIL_INC_1455 1456 +#define Z_UTIL_INC_1456 1457 +#define Z_UTIL_INC_1457 1458 +#define Z_UTIL_INC_1458 1459 +#define Z_UTIL_INC_1459 1460 +#define Z_UTIL_INC_1460 1461 +#define Z_UTIL_INC_1461 1462 +#define Z_UTIL_INC_1462 1463 +#define Z_UTIL_INC_1463 1464 +#define Z_UTIL_INC_1464 1465 +#define Z_UTIL_INC_1465 1466 +#define Z_UTIL_INC_1466 1467 +#define Z_UTIL_INC_1467 1468 +#define Z_UTIL_INC_1468 1469 +#define Z_UTIL_INC_1469 1470 +#define Z_UTIL_INC_1470 1471 +#define Z_UTIL_INC_1471 1472 +#define Z_UTIL_INC_1472 1473 +#define Z_UTIL_INC_1473 1474 +#define Z_UTIL_INC_1474 1475 +#define Z_UTIL_INC_1475 1476 +#define Z_UTIL_INC_1476 1477 +#define Z_UTIL_INC_1477 1478 +#define Z_UTIL_INC_1478 1479 +#define Z_UTIL_INC_1479 1480 +#define Z_UTIL_INC_1480 1481 +#define Z_UTIL_INC_1481 1482 +#define Z_UTIL_INC_1482 1483 +#define Z_UTIL_INC_1483 1484 +#define Z_UTIL_INC_1484 1485 +#define Z_UTIL_INC_1485 1486 +#define Z_UTIL_INC_1486 1487 +#define Z_UTIL_INC_1487 1488 +#define Z_UTIL_INC_1488 1489 +#define Z_UTIL_INC_1489 1490 +#define Z_UTIL_INC_1490 1491 +#define Z_UTIL_INC_1491 1492 +#define Z_UTIL_INC_1492 1493 +#define Z_UTIL_INC_1493 1494 +#define Z_UTIL_INC_1494 1495 +#define Z_UTIL_INC_1495 1496 +#define Z_UTIL_INC_1496 1497 +#define Z_UTIL_INC_1497 1498 +#define Z_UTIL_INC_1498 1499 +#define Z_UTIL_INC_1499 1500 +#define Z_UTIL_INC_1500 1501 +#define Z_UTIL_INC_1501 1502 +#define Z_UTIL_INC_1502 1503 +#define Z_UTIL_INC_1503 1504 +#define Z_UTIL_INC_1504 1505 +#define Z_UTIL_INC_1505 1506 +#define Z_UTIL_INC_1506 1507 +#define Z_UTIL_INC_1507 1508 +#define Z_UTIL_INC_1508 1509 +#define Z_UTIL_INC_1509 1510 +#define Z_UTIL_INC_1510 1511 +#define Z_UTIL_INC_1511 1512 +#define Z_UTIL_INC_1512 1513 +#define Z_UTIL_INC_1513 1514 +#define Z_UTIL_INC_1514 1515 +#define Z_UTIL_INC_1515 1516 +#define Z_UTIL_INC_1516 1517 +#define Z_UTIL_INC_1517 1518 +#define Z_UTIL_INC_1518 1519 +#define Z_UTIL_INC_1519 1520 +#define Z_UTIL_INC_1520 1521 +#define Z_UTIL_INC_1521 1522 +#define Z_UTIL_INC_1522 1523 +#define Z_UTIL_INC_1523 1524 +#define Z_UTIL_INC_1524 1525 +#define Z_UTIL_INC_1525 1526 +#define Z_UTIL_INC_1526 1527 +#define Z_UTIL_INC_1527 1528 +#define Z_UTIL_INC_1528 1529 +#define Z_UTIL_INC_1529 1530 +#define Z_UTIL_INC_1530 1531 +#define Z_UTIL_INC_1531 1532 +#define Z_UTIL_INC_1532 1533 +#define Z_UTIL_INC_1533 1534 +#define Z_UTIL_INC_1534 1535 +#define Z_UTIL_INC_1535 1536 +#define Z_UTIL_INC_1536 1537 +#define Z_UTIL_INC_1537 1538 +#define Z_UTIL_INC_1538 1539 +#define Z_UTIL_INC_1539 1540 +#define Z_UTIL_INC_1540 1541 +#define Z_UTIL_INC_1541 1542 +#define Z_UTIL_INC_1542 1543 +#define Z_UTIL_INC_1543 1544 +#define Z_UTIL_INC_1544 1545 +#define Z_UTIL_INC_1545 1546 +#define Z_UTIL_INC_1546 1547 +#define Z_UTIL_INC_1547 1548 +#define Z_UTIL_INC_1548 1549 +#define Z_UTIL_INC_1549 1550 +#define Z_UTIL_INC_1550 1551 +#define Z_UTIL_INC_1551 1552 +#define Z_UTIL_INC_1552 1553 +#define Z_UTIL_INC_1553 1554 +#define Z_UTIL_INC_1554 1555 +#define Z_UTIL_INC_1555 1556 +#define Z_UTIL_INC_1556 1557 +#define Z_UTIL_INC_1557 1558 +#define Z_UTIL_INC_1558 1559 +#define Z_UTIL_INC_1559 1560 +#define Z_UTIL_INC_1560 1561 +#define Z_UTIL_INC_1561 1562 +#define Z_UTIL_INC_1562 1563 +#define Z_UTIL_INC_1563 1564 +#define Z_UTIL_INC_1564 1565 +#define Z_UTIL_INC_1565 1566 +#define Z_UTIL_INC_1566 1567 +#define Z_UTIL_INC_1567 1568 +#define Z_UTIL_INC_1568 1569 +#define Z_UTIL_INC_1569 1570 +#define Z_UTIL_INC_1570 1571 +#define Z_UTIL_INC_1571 1572 +#define Z_UTIL_INC_1572 1573 +#define Z_UTIL_INC_1573 1574 +#define Z_UTIL_INC_1574 1575 +#define Z_UTIL_INC_1575 1576 +#define Z_UTIL_INC_1576 1577 +#define Z_UTIL_INC_1577 1578 +#define Z_UTIL_INC_1578 1579 +#define Z_UTIL_INC_1579 1580 +#define Z_UTIL_INC_1580 1581 +#define Z_UTIL_INC_1581 1582 +#define Z_UTIL_INC_1582 1583 +#define Z_UTIL_INC_1583 1584 +#define Z_UTIL_INC_1584 1585 +#define Z_UTIL_INC_1585 1586 +#define Z_UTIL_INC_1586 1587 +#define Z_UTIL_INC_1587 1588 +#define Z_UTIL_INC_1588 1589 +#define Z_UTIL_INC_1589 1590 +#define Z_UTIL_INC_1590 1591 +#define Z_UTIL_INC_1591 1592 +#define Z_UTIL_INC_1592 1593 +#define Z_UTIL_INC_1593 1594 +#define Z_UTIL_INC_1594 1595 +#define Z_UTIL_INC_1595 1596 +#define Z_UTIL_INC_1596 1597 +#define Z_UTIL_INC_1597 1598 +#define Z_UTIL_INC_1598 1599 +#define Z_UTIL_INC_1599 1600 +#define Z_UTIL_INC_1600 1601 +#define Z_UTIL_INC_1601 1602 +#define Z_UTIL_INC_1602 1603 +#define Z_UTIL_INC_1603 1604 +#define Z_UTIL_INC_1604 1605 +#define Z_UTIL_INC_1605 1606 +#define Z_UTIL_INC_1606 1607 +#define Z_UTIL_INC_1607 1608 +#define Z_UTIL_INC_1608 1609 +#define Z_UTIL_INC_1609 1610 +#define Z_UTIL_INC_1610 1611 +#define Z_UTIL_INC_1611 1612 +#define Z_UTIL_INC_1612 1613 +#define Z_UTIL_INC_1613 1614 +#define Z_UTIL_INC_1614 1615 +#define Z_UTIL_INC_1615 1616 +#define Z_UTIL_INC_1616 1617 +#define Z_UTIL_INC_1617 1618 +#define Z_UTIL_INC_1618 1619 +#define Z_UTIL_INC_1619 1620 +#define Z_UTIL_INC_1620 1621 +#define Z_UTIL_INC_1621 1622 +#define Z_UTIL_INC_1622 1623 +#define Z_UTIL_INC_1623 1624 +#define Z_UTIL_INC_1624 1625 +#define Z_UTIL_INC_1625 1626 +#define Z_UTIL_INC_1626 1627 +#define Z_UTIL_INC_1627 1628 +#define Z_UTIL_INC_1628 1629 +#define Z_UTIL_INC_1629 1630 +#define Z_UTIL_INC_1630 1631 +#define Z_UTIL_INC_1631 1632 +#define Z_UTIL_INC_1632 1633 +#define Z_UTIL_INC_1633 1634 +#define Z_UTIL_INC_1634 1635 +#define Z_UTIL_INC_1635 1636 +#define Z_UTIL_INC_1636 1637 +#define Z_UTIL_INC_1637 1638 +#define Z_UTIL_INC_1638 1639 +#define Z_UTIL_INC_1639 1640 +#define Z_UTIL_INC_1640 1641 +#define Z_UTIL_INC_1641 1642 +#define Z_UTIL_INC_1642 1643 +#define Z_UTIL_INC_1643 1644 +#define Z_UTIL_INC_1644 1645 +#define Z_UTIL_INC_1645 1646 +#define Z_UTIL_INC_1646 1647 +#define Z_UTIL_INC_1647 1648 +#define Z_UTIL_INC_1648 1649 +#define Z_UTIL_INC_1649 1650 +#define Z_UTIL_INC_1650 1651 +#define Z_UTIL_INC_1651 1652 +#define Z_UTIL_INC_1652 1653 +#define Z_UTIL_INC_1653 1654 +#define Z_UTIL_INC_1654 1655 +#define Z_UTIL_INC_1655 1656 +#define Z_UTIL_INC_1656 1657 +#define Z_UTIL_INC_1657 1658 +#define Z_UTIL_INC_1658 1659 +#define Z_UTIL_INC_1659 1660 +#define Z_UTIL_INC_1660 1661 +#define Z_UTIL_INC_1661 1662 +#define Z_UTIL_INC_1662 1663 +#define Z_UTIL_INC_1663 1664 +#define Z_UTIL_INC_1664 1665 +#define Z_UTIL_INC_1665 1666 +#define Z_UTIL_INC_1666 1667 +#define Z_UTIL_INC_1667 1668 +#define Z_UTIL_INC_1668 1669 +#define Z_UTIL_INC_1669 1670 +#define Z_UTIL_INC_1670 1671 +#define Z_UTIL_INC_1671 1672 +#define Z_UTIL_INC_1672 1673 +#define Z_UTIL_INC_1673 1674 +#define Z_UTIL_INC_1674 1675 +#define Z_UTIL_INC_1675 1676 +#define Z_UTIL_INC_1676 1677 +#define Z_UTIL_INC_1677 1678 +#define Z_UTIL_INC_1678 1679 +#define Z_UTIL_INC_1679 1680 +#define Z_UTIL_INC_1680 1681 +#define Z_UTIL_INC_1681 1682 +#define Z_UTIL_INC_1682 1683 +#define Z_UTIL_INC_1683 1684 +#define Z_UTIL_INC_1684 1685 +#define Z_UTIL_INC_1685 1686 +#define Z_UTIL_INC_1686 1687 +#define Z_UTIL_INC_1687 1688 +#define Z_UTIL_INC_1688 1689 +#define Z_UTIL_INC_1689 1690 +#define Z_UTIL_INC_1690 1691 +#define Z_UTIL_INC_1691 1692 +#define Z_UTIL_INC_1692 1693 +#define Z_UTIL_INC_1693 1694 +#define Z_UTIL_INC_1694 1695 +#define Z_UTIL_INC_1695 1696 +#define Z_UTIL_INC_1696 1697 +#define Z_UTIL_INC_1697 1698 +#define Z_UTIL_INC_1698 1699 +#define Z_UTIL_INC_1699 1700 +#define Z_UTIL_INC_1700 1701 +#define Z_UTIL_INC_1701 1702 +#define Z_UTIL_INC_1702 1703 +#define Z_UTIL_INC_1703 1704 +#define Z_UTIL_INC_1704 1705 +#define Z_UTIL_INC_1705 1706 +#define Z_UTIL_INC_1706 1707 +#define Z_UTIL_INC_1707 1708 +#define Z_UTIL_INC_1708 1709 +#define Z_UTIL_INC_1709 1710 +#define Z_UTIL_INC_1710 1711 +#define Z_UTIL_INC_1711 1712 +#define Z_UTIL_INC_1712 1713 +#define Z_UTIL_INC_1713 1714 +#define Z_UTIL_INC_1714 1715 +#define Z_UTIL_INC_1715 1716 +#define Z_UTIL_INC_1716 1717 +#define Z_UTIL_INC_1717 1718 +#define Z_UTIL_INC_1718 1719 +#define Z_UTIL_INC_1719 1720 +#define Z_UTIL_INC_1720 1721 +#define Z_UTIL_INC_1721 1722 +#define Z_UTIL_INC_1722 1723 +#define Z_UTIL_INC_1723 1724 +#define Z_UTIL_INC_1724 1725 +#define Z_UTIL_INC_1725 1726 +#define Z_UTIL_INC_1726 1727 +#define Z_UTIL_INC_1727 1728 +#define Z_UTIL_INC_1728 1729 +#define Z_UTIL_INC_1729 1730 +#define Z_UTIL_INC_1730 1731 +#define Z_UTIL_INC_1731 1732 +#define Z_UTIL_INC_1732 1733 +#define Z_UTIL_INC_1733 1734 +#define Z_UTIL_INC_1734 1735 +#define Z_UTIL_INC_1735 1736 +#define Z_UTIL_INC_1736 1737 +#define Z_UTIL_INC_1737 1738 +#define Z_UTIL_INC_1738 1739 +#define Z_UTIL_INC_1739 1740 +#define Z_UTIL_INC_1740 1741 +#define Z_UTIL_INC_1741 1742 +#define Z_UTIL_INC_1742 1743 +#define Z_UTIL_INC_1743 1744 +#define Z_UTIL_INC_1744 1745 +#define Z_UTIL_INC_1745 1746 +#define Z_UTIL_INC_1746 1747 +#define Z_UTIL_INC_1747 1748 +#define Z_UTIL_INC_1748 1749 +#define Z_UTIL_INC_1749 1750 +#define Z_UTIL_INC_1750 1751 +#define Z_UTIL_INC_1751 1752 +#define Z_UTIL_INC_1752 1753 +#define Z_UTIL_INC_1753 1754 +#define Z_UTIL_INC_1754 1755 +#define Z_UTIL_INC_1755 1756 +#define Z_UTIL_INC_1756 1757 +#define Z_UTIL_INC_1757 1758 +#define Z_UTIL_INC_1758 1759 +#define Z_UTIL_INC_1759 1760 +#define Z_UTIL_INC_1760 1761 +#define Z_UTIL_INC_1761 1762 +#define Z_UTIL_INC_1762 1763 +#define Z_UTIL_INC_1763 1764 +#define Z_UTIL_INC_1764 1765 +#define Z_UTIL_INC_1765 1766 +#define Z_UTIL_INC_1766 1767 +#define Z_UTIL_INC_1767 1768 +#define Z_UTIL_INC_1768 1769 +#define Z_UTIL_INC_1769 1770 +#define Z_UTIL_INC_1770 1771 +#define Z_UTIL_INC_1771 1772 +#define Z_UTIL_INC_1772 1773 +#define Z_UTIL_INC_1773 1774 +#define Z_UTIL_INC_1774 1775 +#define Z_UTIL_INC_1775 1776 +#define Z_UTIL_INC_1776 1777 +#define Z_UTIL_INC_1777 1778 +#define Z_UTIL_INC_1778 1779 +#define Z_UTIL_INC_1779 1780 +#define Z_UTIL_INC_1780 1781 +#define Z_UTIL_INC_1781 1782 +#define Z_UTIL_INC_1782 1783 +#define Z_UTIL_INC_1783 1784 +#define Z_UTIL_INC_1784 1785 +#define Z_UTIL_INC_1785 1786 +#define Z_UTIL_INC_1786 1787 +#define Z_UTIL_INC_1787 1788 +#define Z_UTIL_INC_1788 1789 +#define Z_UTIL_INC_1789 1790 +#define Z_UTIL_INC_1790 1791 +#define Z_UTIL_INC_1791 1792 +#define Z_UTIL_INC_1792 1793 +#define Z_UTIL_INC_1793 1794 +#define Z_UTIL_INC_1794 1795 +#define Z_UTIL_INC_1795 1796 +#define Z_UTIL_INC_1796 1797 +#define Z_UTIL_INC_1797 1798 +#define Z_UTIL_INC_1798 1799 +#define Z_UTIL_INC_1799 1800 +#define Z_UTIL_INC_1800 1801 +#define Z_UTIL_INC_1801 1802 +#define Z_UTIL_INC_1802 1803 +#define Z_UTIL_INC_1803 1804 +#define Z_UTIL_INC_1804 1805 +#define Z_UTIL_INC_1805 1806 +#define Z_UTIL_INC_1806 1807 +#define Z_UTIL_INC_1807 1808 +#define Z_UTIL_INC_1808 1809 +#define Z_UTIL_INC_1809 1810 +#define Z_UTIL_INC_1810 1811 +#define Z_UTIL_INC_1811 1812 +#define Z_UTIL_INC_1812 1813 +#define Z_UTIL_INC_1813 1814 +#define Z_UTIL_INC_1814 1815 +#define Z_UTIL_INC_1815 1816 +#define Z_UTIL_INC_1816 1817 +#define Z_UTIL_INC_1817 1818 +#define Z_UTIL_INC_1818 1819 +#define Z_UTIL_INC_1819 1820 +#define Z_UTIL_INC_1820 1821 +#define Z_UTIL_INC_1821 1822 +#define Z_UTIL_INC_1822 1823 +#define Z_UTIL_INC_1823 1824 +#define Z_UTIL_INC_1824 1825 +#define Z_UTIL_INC_1825 1826 +#define Z_UTIL_INC_1826 1827 +#define Z_UTIL_INC_1827 1828 +#define Z_UTIL_INC_1828 1829 +#define Z_UTIL_INC_1829 1830 +#define Z_UTIL_INC_1830 1831 +#define Z_UTIL_INC_1831 1832 +#define Z_UTIL_INC_1832 1833 +#define Z_UTIL_INC_1833 1834 +#define Z_UTIL_INC_1834 1835 +#define Z_UTIL_INC_1835 1836 +#define Z_UTIL_INC_1836 1837 +#define Z_UTIL_INC_1837 1838 +#define Z_UTIL_INC_1838 1839 +#define Z_UTIL_INC_1839 1840 +#define Z_UTIL_INC_1840 1841 +#define Z_UTIL_INC_1841 1842 +#define Z_UTIL_INC_1842 1843 +#define Z_UTIL_INC_1843 1844 +#define Z_UTIL_INC_1844 1845 +#define Z_UTIL_INC_1845 1846 +#define Z_UTIL_INC_1846 1847 +#define Z_UTIL_INC_1847 1848 +#define Z_UTIL_INC_1848 1849 +#define Z_UTIL_INC_1849 1850 +#define Z_UTIL_INC_1850 1851 +#define Z_UTIL_INC_1851 1852 +#define Z_UTIL_INC_1852 1853 +#define Z_UTIL_INC_1853 1854 +#define Z_UTIL_INC_1854 1855 +#define Z_UTIL_INC_1855 1856 +#define Z_UTIL_INC_1856 1857 +#define Z_UTIL_INC_1857 1858 +#define Z_UTIL_INC_1858 1859 +#define Z_UTIL_INC_1859 1860 +#define Z_UTIL_INC_1860 1861 +#define Z_UTIL_INC_1861 1862 +#define Z_UTIL_INC_1862 1863 +#define Z_UTIL_INC_1863 1864 +#define Z_UTIL_INC_1864 1865 +#define Z_UTIL_INC_1865 1866 +#define Z_UTIL_INC_1866 1867 +#define Z_UTIL_INC_1867 1868 +#define Z_UTIL_INC_1868 1869 +#define Z_UTIL_INC_1869 1870 +#define Z_UTIL_INC_1870 1871 +#define Z_UTIL_INC_1871 1872 +#define Z_UTIL_INC_1872 1873 +#define Z_UTIL_INC_1873 1874 +#define Z_UTIL_INC_1874 1875 +#define Z_UTIL_INC_1875 1876 +#define Z_UTIL_INC_1876 1877 +#define Z_UTIL_INC_1877 1878 +#define Z_UTIL_INC_1878 1879 +#define Z_UTIL_INC_1879 1880 +#define Z_UTIL_INC_1880 1881 +#define Z_UTIL_INC_1881 1882 +#define Z_UTIL_INC_1882 1883 +#define Z_UTIL_INC_1883 1884 +#define Z_UTIL_INC_1884 1885 +#define Z_UTIL_INC_1885 1886 +#define Z_UTIL_INC_1886 1887 +#define Z_UTIL_INC_1887 1888 +#define Z_UTIL_INC_1888 1889 +#define Z_UTIL_INC_1889 1890 +#define Z_UTIL_INC_1890 1891 +#define Z_UTIL_INC_1891 1892 +#define Z_UTIL_INC_1892 1893 +#define Z_UTIL_INC_1893 1894 +#define Z_UTIL_INC_1894 1895 +#define Z_UTIL_INC_1895 1896 +#define Z_UTIL_INC_1896 1897 +#define Z_UTIL_INC_1897 1898 +#define Z_UTIL_INC_1898 1899 +#define Z_UTIL_INC_1899 1900 +#define Z_UTIL_INC_1900 1901 +#define Z_UTIL_INC_1901 1902 +#define Z_UTIL_INC_1902 1903 +#define Z_UTIL_INC_1903 1904 +#define Z_UTIL_INC_1904 1905 +#define Z_UTIL_INC_1905 1906 +#define Z_UTIL_INC_1906 1907 +#define Z_UTIL_INC_1907 1908 +#define Z_UTIL_INC_1908 1909 +#define Z_UTIL_INC_1909 1910 +#define Z_UTIL_INC_1910 1911 +#define Z_UTIL_INC_1911 1912 +#define Z_UTIL_INC_1912 1913 +#define Z_UTIL_INC_1913 1914 +#define Z_UTIL_INC_1914 1915 +#define Z_UTIL_INC_1915 1916 +#define Z_UTIL_INC_1916 1917 +#define Z_UTIL_INC_1917 1918 +#define Z_UTIL_INC_1918 1919 +#define Z_UTIL_INC_1919 1920 +#define Z_UTIL_INC_1920 1921 +#define Z_UTIL_INC_1921 1922 +#define Z_UTIL_INC_1922 1923 +#define Z_UTIL_INC_1923 1924 +#define Z_UTIL_INC_1924 1925 +#define Z_UTIL_INC_1925 1926 +#define Z_UTIL_INC_1926 1927 +#define Z_UTIL_INC_1927 1928 +#define Z_UTIL_INC_1928 1929 +#define Z_UTIL_INC_1929 1930 +#define Z_UTIL_INC_1930 1931 +#define Z_UTIL_INC_1931 1932 +#define Z_UTIL_INC_1932 1933 +#define Z_UTIL_INC_1933 1934 +#define Z_UTIL_INC_1934 1935 +#define Z_UTIL_INC_1935 1936 +#define Z_UTIL_INC_1936 1937 +#define Z_UTIL_INC_1937 1938 +#define Z_UTIL_INC_1938 1939 +#define Z_UTIL_INC_1939 1940 +#define Z_UTIL_INC_1940 1941 +#define Z_UTIL_INC_1941 1942 +#define Z_UTIL_INC_1942 1943 +#define Z_UTIL_INC_1943 1944 +#define Z_UTIL_INC_1944 1945 +#define Z_UTIL_INC_1945 1946 +#define Z_UTIL_INC_1946 1947 +#define Z_UTIL_INC_1947 1948 +#define Z_UTIL_INC_1948 1949 +#define Z_UTIL_INC_1949 1950 +#define Z_UTIL_INC_1950 1951 +#define Z_UTIL_INC_1951 1952 +#define Z_UTIL_INC_1952 1953 +#define Z_UTIL_INC_1953 1954 +#define Z_UTIL_INC_1954 1955 +#define Z_UTIL_INC_1955 1956 +#define Z_UTIL_INC_1956 1957 +#define Z_UTIL_INC_1957 1958 +#define Z_UTIL_INC_1958 1959 +#define Z_UTIL_INC_1959 1960 +#define Z_UTIL_INC_1960 1961 +#define Z_UTIL_INC_1961 1962 +#define Z_UTIL_INC_1962 1963 +#define Z_UTIL_INC_1963 1964 +#define Z_UTIL_INC_1964 1965 +#define Z_UTIL_INC_1965 1966 +#define Z_UTIL_INC_1966 1967 +#define Z_UTIL_INC_1967 1968 +#define Z_UTIL_INC_1968 1969 +#define Z_UTIL_INC_1969 1970 +#define Z_UTIL_INC_1970 1971 +#define Z_UTIL_INC_1971 1972 +#define Z_UTIL_INC_1972 1973 +#define Z_UTIL_INC_1973 1974 +#define Z_UTIL_INC_1974 1975 +#define Z_UTIL_INC_1975 1976 +#define Z_UTIL_INC_1976 1977 +#define Z_UTIL_INC_1977 1978 +#define Z_UTIL_INC_1978 1979 +#define Z_UTIL_INC_1979 1980 +#define Z_UTIL_INC_1980 1981 +#define Z_UTIL_INC_1981 1982 +#define Z_UTIL_INC_1982 1983 +#define Z_UTIL_INC_1983 1984 +#define Z_UTIL_INC_1984 1985 +#define Z_UTIL_INC_1985 1986 +#define Z_UTIL_INC_1986 1987 +#define Z_UTIL_INC_1987 1988 +#define Z_UTIL_INC_1988 1989 +#define Z_UTIL_INC_1989 1990 +#define Z_UTIL_INC_1990 1991 +#define Z_UTIL_INC_1991 1992 +#define Z_UTIL_INC_1992 1993 +#define Z_UTIL_INC_1993 1994 +#define Z_UTIL_INC_1994 1995 +#define Z_UTIL_INC_1995 1996 +#define Z_UTIL_INC_1996 1997 +#define Z_UTIL_INC_1997 1998 +#define Z_UTIL_INC_1998 1999 +#define Z_UTIL_INC_1999 2000 +#define Z_UTIL_INC_2000 2001 +#define Z_UTIL_INC_2001 2002 +#define Z_UTIL_INC_2002 2003 +#define Z_UTIL_INC_2003 2004 +#define Z_UTIL_INC_2004 2005 +#define Z_UTIL_INC_2005 2006 +#define Z_UTIL_INC_2006 2007 +#define Z_UTIL_INC_2007 2008 +#define Z_UTIL_INC_2008 2009 +#define Z_UTIL_INC_2009 2010 +#define Z_UTIL_INC_2010 2011 +#define Z_UTIL_INC_2011 2012 +#define Z_UTIL_INC_2012 2013 +#define Z_UTIL_INC_2013 2014 +#define Z_UTIL_INC_2014 2015 +#define Z_UTIL_INC_2015 2016 +#define Z_UTIL_INC_2016 2017 +#define Z_UTIL_INC_2017 2018 +#define Z_UTIL_INC_2018 2019 +#define Z_UTIL_INC_2019 2020 +#define Z_UTIL_INC_2020 2021 +#define Z_UTIL_INC_2021 2022 +#define Z_UTIL_INC_2022 2023 +#define Z_UTIL_INC_2023 2024 +#define Z_UTIL_INC_2024 2025 +#define Z_UTIL_INC_2025 2026 +#define Z_UTIL_INC_2026 2027 +#define Z_UTIL_INC_2027 2028 +#define Z_UTIL_INC_2028 2029 +#define Z_UTIL_INC_2029 2030 +#define Z_UTIL_INC_2030 2031 +#define Z_UTIL_INC_2031 2032 +#define Z_UTIL_INC_2032 2033 +#define Z_UTIL_INC_2033 2034 +#define Z_UTIL_INC_2034 2035 +#define Z_UTIL_INC_2035 2036 +#define Z_UTIL_INC_2036 2037 +#define Z_UTIL_INC_2037 2038 +#define Z_UTIL_INC_2038 2039 +#define Z_UTIL_INC_2039 2040 +#define Z_UTIL_INC_2040 2041 +#define Z_UTIL_INC_2041 2042 +#define Z_UTIL_INC_2042 2043 +#define Z_UTIL_INC_2043 2044 +#define Z_UTIL_INC_2044 2045 +#define Z_UTIL_INC_2045 2046 +#define Z_UTIL_INC_2046 2047 +#define Z_UTIL_INC_2047 2048 +#define Z_UTIL_INC_2048 2049 +#define Z_UTIL_INC_2049 2050 +#define Z_UTIL_INC_2050 2051 +#define Z_UTIL_INC_2051 2052 +#define Z_UTIL_INC_2052 2053 +#define Z_UTIL_INC_2053 2054 +#define Z_UTIL_INC_2054 2055 +#define Z_UTIL_INC_2055 2056 +#define Z_UTIL_INC_2056 2057 +#define Z_UTIL_INC_2057 2058 +#define Z_UTIL_INC_2058 2059 +#define Z_UTIL_INC_2059 2060 +#define Z_UTIL_INC_2060 2061 +#define Z_UTIL_INC_2061 2062 +#define Z_UTIL_INC_2062 2063 +#define Z_UTIL_INC_2063 2064 +#define Z_UTIL_INC_2064 2065 +#define Z_UTIL_INC_2065 2066 +#define Z_UTIL_INC_2066 2067 +#define Z_UTIL_INC_2067 2068 +#define Z_UTIL_INC_2068 2069 +#define Z_UTIL_INC_2069 2070 +#define Z_UTIL_INC_2070 2071 +#define Z_UTIL_INC_2071 2072 +#define Z_UTIL_INC_2072 2073 +#define Z_UTIL_INC_2073 2074 +#define Z_UTIL_INC_2074 2075 +#define Z_UTIL_INC_2075 2076 +#define Z_UTIL_INC_2076 2077 +#define Z_UTIL_INC_2077 2078 +#define Z_UTIL_INC_2078 2079 +#define Z_UTIL_INC_2079 2080 +#define Z_UTIL_INC_2080 2081 +#define Z_UTIL_INC_2081 2082 +#define Z_UTIL_INC_2082 2083 +#define Z_UTIL_INC_2083 2084 +#define Z_UTIL_INC_2084 2085 +#define Z_UTIL_INC_2085 2086 +#define Z_UTIL_INC_2086 2087 +#define Z_UTIL_INC_2087 2088 +#define Z_UTIL_INC_2088 2089 +#define Z_UTIL_INC_2089 2090 +#define Z_UTIL_INC_2090 2091 +#define Z_UTIL_INC_2091 2092 +#define Z_UTIL_INC_2092 2093 +#define Z_UTIL_INC_2093 2094 +#define Z_UTIL_INC_2094 2095 +#define Z_UTIL_INC_2095 2096 +#define Z_UTIL_INC_2096 2097 +#define Z_UTIL_INC_2097 2098 +#define Z_UTIL_INC_2098 2099 +#define Z_UTIL_INC_2099 2100 +#define Z_UTIL_INC_2100 2101 +#define Z_UTIL_INC_2101 2102 +#define Z_UTIL_INC_2102 2103 +#define Z_UTIL_INC_2103 2104 +#define Z_UTIL_INC_2104 2105 +#define Z_UTIL_INC_2105 2106 +#define Z_UTIL_INC_2106 2107 +#define Z_UTIL_INC_2107 2108 +#define Z_UTIL_INC_2108 2109 +#define Z_UTIL_INC_2109 2110 +#define Z_UTIL_INC_2110 2111 +#define Z_UTIL_INC_2111 2112 +#define Z_UTIL_INC_2112 2113 +#define Z_UTIL_INC_2113 2114 +#define Z_UTIL_INC_2114 2115 +#define Z_UTIL_INC_2115 2116 +#define Z_UTIL_INC_2116 2117 +#define Z_UTIL_INC_2117 2118 +#define Z_UTIL_INC_2118 2119 +#define Z_UTIL_INC_2119 2120 +#define Z_UTIL_INC_2120 2121 +#define Z_UTIL_INC_2121 2122 +#define Z_UTIL_INC_2122 2123 +#define Z_UTIL_INC_2123 2124 +#define Z_UTIL_INC_2124 2125 +#define Z_UTIL_INC_2125 2126 +#define Z_UTIL_INC_2126 2127 +#define Z_UTIL_INC_2127 2128 +#define Z_UTIL_INC_2128 2129 +#define Z_UTIL_INC_2129 2130 +#define Z_UTIL_INC_2130 2131 +#define Z_UTIL_INC_2131 2132 +#define Z_UTIL_INC_2132 2133 +#define Z_UTIL_INC_2133 2134 +#define Z_UTIL_INC_2134 2135 +#define Z_UTIL_INC_2135 2136 +#define Z_UTIL_INC_2136 2137 +#define Z_UTIL_INC_2137 2138 +#define Z_UTIL_INC_2138 2139 +#define Z_UTIL_INC_2139 2140 +#define Z_UTIL_INC_2140 2141 +#define Z_UTIL_INC_2141 2142 +#define Z_UTIL_INC_2142 2143 +#define Z_UTIL_INC_2143 2144 +#define Z_UTIL_INC_2144 2145 +#define Z_UTIL_INC_2145 2146 +#define Z_UTIL_INC_2146 2147 +#define Z_UTIL_INC_2147 2148 +#define Z_UTIL_INC_2148 2149 +#define Z_UTIL_INC_2149 2150 +#define Z_UTIL_INC_2150 2151 +#define Z_UTIL_INC_2151 2152 +#define Z_UTIL_INC_2152 2153 +#define Z_UTIL_INC_2153 2154 +#define Z_UTIL_INC_2154 2155 +#define Z_UTIL_INC_2155 2156 +#define Z_UTIL_INC_2156 2157 +#define Z_UTIL_INC_2157 2158 +#define Z_UTIL_INC_2158 2159 +#define Z_UTIL_INC_2159 2160 +#define Z_UTIL_INC_2160 2161 +#define Z_UTIL_INC_2161 2162 +#define Z_UTIL_INC_2162 2163 +#define Z_UTIL_INC_2163 2164 +#define Z_UTIL_INC_2164 2165 +#define Z_UTIL_INC_2165 2166 +#define Z_UTIL_INC_2166 2167 +#define Z_UTIL_INC_2167 2168 +#define Z_UTIL_INC_2168 2169 +#define Z_UTIL_INC_2169 2170 +#define Z_UTIL_INC_2170 2171 +#define Z_UTIL_INC_2171 2172 +#define Z_UTIL_INC_2172 2173 +#define Z_UTIL_INC_2173 2174 +#define Z_UTIL_INC_2174 2175 +#define Z_UTIL_INC_2175 2176 +#define Z_UTIL_INC_2176 2177 +#define Z_UTIL_INC_2177 2178 +#define Z_UTIL_INC_2178 2179 +#define Z_UTIL_INC_2179 2180 +#define Z_UTIL_INC_2180 2181 +#define Z_UTIL_INC_2181 2182 +#define Z_UTIL_INC_2182 2183 +#define Z_UTIL_INC_2183 2184 +#define Z_UTIL_INC_2184 2185 +#define Z_UTIL_INC_2185 2186 +#define Z_UTIL_INC_2186 2187 +#define Z_UTIL_INC_2187 2188 +#define Z_UTIL_INC_2188 2189 +#define Z_UTIL_INC_2189 2190 +#define Z_UTIL_INC_2190 2191 +#define Z_UTIL_INC_2191 2192 +#define Z_UTIL_INC_2192 2193 +#define Z_UTIL_INC_2193 2194 +#define Z_UTIL_INC_2194 2195 +#define Z_UTIL_INC_2195 2196 +#define Z_UTIL_INC_2196 2197 +#define Z_UTIL_INC_2197 2198 +#define Z_UTIL_INC_2198 2199 +#define Z_UTIL_INC_2199 2200 +#define Z_UTIL_INC_2200 2201 +#define Z_UTIL_INC_2201 2202 +#define Z_UTIL_INC_2202 2203 +#define Z_UTIL_INC_2203 2204 +#define Z_UTIL_INC_2204 2205 +#define Z_UTIL_INC_2205 2206 +#define Z_UTIL_INC_2206 2207 +#define Z_UTIL_INC_2207 2208 +#define Z_UTIL_INC_2208 2209 +#define Z_UTIL_INC_2209 2210 +#define Z_UTIL_INC_2210 2211 +#define Z_UTIL_INC_2211 2212 +#define Z_UTIL_INC_2212 2213 +#define Z_UTIL_INC_2213 2214 +#define Z_UTIL_INC_2214 2215 +#define Z_UTIL_INC_2215 2216 +#define Z_UTIL_INC_2216 2217 +#define Z_UTIL_INC_2217 2218 +#define Z_UTIL_INC_2218 2219 +#define Z_UTIL_INC_2219 2220 +#define Z_UTIL_INC_2220 2221 +#define Z_UTIL_INC_2221 2222 +#define Z_UTIL_INC_2222 2223 +#define Z_UTIL_INC_2223 2224 +#define Z_UTIL_INC_2224 2225 +#define Z_UTIL_INC_2225 2226 +#define Z_UTIL_INC_2226 2227 +#define Z_UTIL_INC_2227 2228 +#define Z_UTIL_INC_2228 2229 +#define Z_UTIL_INC_2229 2230 +#define Z_UTIL_INC_2230 2231 +#define Z_UTIL_INC_2231 2232 +#define Z_UTIL_INC_2232 2233 +#define Z_UTIL_INC_2233 2234 +#define Z_UTIL_INC_2234 2235 +#define Z_UTIL_INC_2235 2236 +#define Z_UTIL_INC_2236 2237 +#define Z_UTIL_INC_2237 2238 +#define Z_UTIL_INC_2238 2239 +#define Z_UTIL_INC_2239 2240 +#define Z_UTIL_INC_2240 2241 +#define Z_UTIL_INC_2241 2242 +#define Z_UTIL_INC_2242 2243 +#define Z_UTIL_INC_2243 2244 +#define Z_UTIL_INC_2244 2245 +#define Z_UTIL_INC_2245 2246 +#define Z_UTIL_INC_2246 2247 +#define Z_UTIL_INC_2247 2248 +#define Z_UTIL_INC_2248 2249 +#define Z_UTIL_INC_2249 2250 +#define Z_UTIL_INC_2250 2251 +#define Z_UTIL_INC_2251 2252 +#define Z_UTIL_INC_2252 2253 +#define Z_UTIL_INC_2253 2254 +#define Z_UTIL_INC_2254 2255 +#define Z_UTIL_INC_2255 2256 +#define Z_UTIL_INC_2256 2257 +#define Z_UTIL_INC_2257 2258 +#define Z_UTIL_INC_2258 2259 +#define Z_UTIL_INC_2259 2260 +#define Z_UTIL_INC_2260 2261 +#define Z_UTIL_INC_2261 2262 +#define Z_UTIL_INC_2262 2263 +#define Z_UTIL_INC_2263 2264 +#define Z_UTIL_INC_2264 2265 +#define Z_UTIL_INC_2265 2266 +#define Z_UTIL_INC_2266 2267 +#define Z_UTIL_INC_2267 2268 +#define Z_UTIL_INC_2268 2269 +#define Z_UTIL_INC_2269 2270 +#define Z_UTIL_INC_2270 2271 +#define Z_UTIL_INC_2271 2272 +#define Z_UTIL_INC_2272 2273 +#define Z_UTIL_INC_2273 2274 +#define Z_UTIL_INC_2274 2275 +#define Z_UTIL_INC_2275 2276 +#define Z_UTIL_INC_2276 2277 +#define Z_UTIL_INC_2277 2278 +#define Z_UTIL_INC_2278 2279 +#define Z_UTIL_INC_2279 2280 +#define Z_UTIL_INC_2280 2281 +#define Z_UTIL_INC_2281 2282 +#define Z_UTIL_INC_2282 2283 +#define Z_UTIL_INC_2283 2284 +#define Z_UTIL_INC_2284 2285 +#define Z_UTIL_INC_2285 2286 +#define Z_UTIL_INC_2286 2287 +#define Z_UTIL_INC_2287 2288 +#define Z_UTIL_INC_2288 2289 +#define Z_UTIL_INC_2289 2290 +#define Z_UTIL_INC_2290 2291 +#define Z_UTIL_INC_2291 2292 +#define Z_UTIL_INC_2292 2293 +#define Z_UTIL_INC_2293 2294 +#define Z_UTIL_INC_2294 2295 +#define Z_UTIL_INC_2295 2296 +#define Z_UTIL_INC_2296 2297 +#define Z_UTIL_INC_2297 2298 +#define Z_UTIL_INC_2298 2299 +#define Z_UTIL_INC_2299 2300 +#define Z_UTIL_INC_2300 2301 +#define Z_UTIL_INC_2301 2302 +#define Z_UTIL_INC_2302 2303 +#define Z_UTIL_INC_2303 2304 +#define Z_UTIL_INC_2304 2305 +#define Z_UTIL_INC_2305 2306 +#define Z_UTIL_INC_2306 2307 +#define Z_UTIL_INC_2307 2308 +#define Z_UTIL_INC_2308 2309 +#define Z_UTIL_INC_2309 2310 +#define Z_UTIL_INC_2310 2311 +#define Z_UTIL_INC_2311 2312 +#define Z_UTIL_INC_2312 2313 +#define Z_UTIL_INC_2313 2314 +#define Z_UTIL_INC_2314 2315 +#define Z_UTIL_INC_2315 2316 +#define Z_UTIL_INC_2316 2317 +#define Z_UTIL_INC_2317 2318 +#define Z_UTIL_INC_2318 2319 +#define Z_UTIL_INC_2319 2320 +#define Z_UTIL_INC_2320 2321 +#define Z_UTIL_INC_2321 2322 +#define Z_UTIL_INC_2322 2323 +#define Z_UTIL_INC_2323 2324 +#define Z_UTIL_INC_2324 2325 +#define Z_UTIL_INC_2325 2326 +#define Z_UTIL_INC_2326 2327 +#define Z_UTIL_INC_2327 2328 +#define Z_UTIL_INC_2328 2329 +#define Z_UTIL_INC_2329 2330 +#define Z_UTIL_INC_2330 2331 +#define Z_UTIL_INC_2331 2332 +#define Z_UTIL_INC_2332 2333 +#define Z_UTIL_INC_2333 2334 +#define Z_UTIL_INC_2334 2335 +#define Z_UTIL_INC_2335 2336 +#define Z_UTIL_INC_2336 2337 +#define Z_UTIL_INC_2337 2338 +#define Z_UTIL_INC_2338 2339 +#define Z_UTIL_INC_2339 2340 +#define Z_UTIL_INC_2340 2341 +#define Z_UTIL_INC_2341 2342 +#define Z_UTIL_INC_2342 2343 +#define Z_UTIL_INC_2343 2344 +#define Z_UTIL_INC_2344 2345 +#define Z_UTIL_INC_2345 2346 +#define Z_UTIL_INC_2346 2347 +#define Z_UTIL_INC_2347 2348 +#define Z_UTIL_INC_2348 2349 +#define Z_UTIL_INC_2349 2350 +#define Z_UTIL_INC_2350 2351 +#define Z_UTIL_INC_2351 2352 +#define Z_UTIL_INC_2352 2353 +#define Z_UTIL_INC_2353 2354 +#define Z_UTIL_INC_2354 2355 +#define Z_UTIL_INC_2355 2356 +#define Z_UTIL_INC_2356 2357 +#define Z_UTIL_INC_2357 2358 +#define Z_UTIL_INC_2358 2359 +#define Z_UTIL_INC_2359 2360 +#define Z_UTIL_INC_2360 2361 +#define Z_UTIL_INC_2361 2362 +#define Z_UTIL_INC_2362 2363 +#define Z_UTIL_INC_2363 2364 +#define Z_UTIL_INC_2364 2365 +#define Z_UTIL_INC_2365 2366 +#define Z_UTIL_INC_2366 2367 +#define Z_UTIL_INC_2367 2368 +#define Z_UTIL_INC_2368 2369 +#define Z_UTIL_INC_2369 2370 +#define Z_UTIL_INC_2370 2371 +#define Z_UTIL_INC_2371 2372 +#define Z_UTIL_INC_2372 2373 +#define Z_UTIL_INC_2373 2374 +#define Z_UTIL_INC_2374 2375 +#define Z_UTIL_INC_2375 2376 +#define Z_UTIL_INC_2376 2377 +#define Z_UTIL_INC_2377 2378 +#define Z_UTIL_INC_2378 2379 +#define Z_UTIL_INC_2379 2380 +#define Z_UTIL_INC_2380 2381 +#define Z_UTIL_INC_2381 2382 +#define Z_UTIL_INC_2382 2383 +#define Z_UTIL_INC_2383 2384 +#define Z_UTIL_INC_2384 2385 +#define Z_UTIL_INC_2385 2386 +#define Z_UTIL_INC_2386 2387 +#define Z_UTIL_INC_2387 2388 +#define Z_UTIL_INC_2388 2389 +#define Z_UTIL_INC_2389 2390 +#define Z_UTIL_INC_2390 2391 +#define Z_UTIL_INC_2391 2392 +#define Z_UTIL_INC_2392 2393 +#define Z_UTIL_INC_2393 2394 +#define Z_UTIL_INC_2394 2395 +#define Z_UTIL_INC_2395 2396 +#define Z_UTIL_INC_2396 2397 +#define Z_UTIL_INC_2397 2398 +#define Z_UTIL_INC_2398 2399 +#define Z_UTIL_INC_2399 2400 +#define Z_UTIL_INC_2400 2401 +#define Z_UTIL_INC_2401 2402 +#define Z_UTIL_INC_2402 2403 +#define Z_UTIL_INC_2403 2404 +#define Z_UTIL_INC_2404 2405 +#define Z_UTIL_INC_2405 2406 +#define Z_UTIL_INC_2406 2407 +#define Z_UTIL_INC_2407 2408 +#define Z_UTIL_INC_2408 2409 +#define Z_UTIL_INC_2409 2410 +#define Z_UTIL_INC_2410 2411 +#define Z_UTIL_INC_2411 2412 +#define Z_UTIL_INC_2412 2413 +#define Z_UTIL_INC_2413 2414 +#define Z_UTIL_INC_2414 2415 +#define Z_UTIL_INC_2415 2416 +#define Z_UTIL_INC_2416 2417 +#define Z_UTIL_INC_2417 2418 +#define Z_UTIL_INC_2418 2419 +#define Z_UTIL_INC_2419 2420 +#define Z_UTIL_INC_2420 2421 +#define Z_UTIL_INC_2421 2422 +#define Z_UTIL_INC_2422 2423 +#define Z_UTIL_INC_2423 2424 +#define Z_UTIL_INC_2424 2425 +#define Z_UTIL_INC_2425 2426 +#define Z_UTIL_INC_2426 2427 +#define Z_UTIL_INC_2427 2428 +#define Z_UTIL_INC_2428 2429 +#define Z_UTIL_INC_2429 2430 +#define Z_UTIL_INC_2430 2431 +#define Z_UTIL_INC_2431 2432 +#define Z_UTIL_INC_2432 2433 +#define Z_UTIL_INC_2433 2434 +#define Z_UTIL_INC_2434 2435 +#define Z_UTIL_INC_2435 2436 +#define Z_UTIL_INC_2436 2437 +#define Z_UTIL_INC_2437 2438 +#define Z_UTIL_INC_2438 2439 +#define Z_UTIL_INC_2439 2440 +#define Z_UTIL_INC_2440 2441 +#define Z_UTIL_INC_2441 2442 +#define Z_UTIL_INC_2442 2443 +#define Z_UTIL_INC_2443 2444 +#define Z_UTIL_INC_2444 2445 +#define Z_UTIL_INC_2445 2446 +#define Z_UTIL_INC_2446 2447 +#define Z_UTIL_INC_2447 2448 +#define Z_UTIL_INC_2448 2449 +#define Z_UTIL_INC_2449 2450 +#define Z_UTIL_INC_2450 2451 +#define Z_UTIL_INC_2451 2452 +#define Z_UTIL_INC_2452 2453 +#define Z_UTIL_INC_2453 2454 +#define Z_UTIL_INC_2454 2455 +#define Z_UTIL_INC_2455 2456 +#define Z_UTIL_INC_2456 2457 +#define Z_UTIL_INC_2457 2458 +#define Z_UTIL_INC_2458 2459 +#define Z_UTIL_INC_2459 2460 +#define Z_UTIL_INC_2460 2461 +#define Z_UTIL_INC_2461 2462 +#define Z_UTIL_INC_2462 2463 +#define Z_UTIL_INC_2463 2464 +#define Z_UTIL_INC_2464 2465 +#define Z_UTIL_INC_2465 2466 +#define Z_UTIL_INC_2466 2467 +#define Z_UTIL_INC_2467 2468 +#define Z_UTIL_INC_2468 2469 +#define Z_UTIL_INC_2469 2470 +#define Z_UTIL_INC_2470 2471 +#define Z_UTIL_INC_2471 2472 +#define Z_UTIL_INC_2472 2473 +#define Z_UTIL_INC_2473 2474 +#define Z_UTIL_INC_2474 2475 +#define Z_UTIL_INC_2475 2476 +#define Z_UTIL_INC_2476 2477 +#define Z_UTIL_INC_2477 2478 +#define Z_UTIL_INC_2478 2479 +#define Z_UTIL_INC_2479 2480 +#define Z_UTIL_INC_2480 2481 +#define Z_UTIL_INC_2481 2482 +#define Z_UTIL_INC_2482 2483 +#define Z_UTIL_INC_2483 2484 +#define Z_UTIL_INC_2484 2485 +#define Z_UTIL_INC_2485 2486 +#define Z_UTIL_INC_2486 2487 +#define Z_UTIL_INC_2487 2488 +#define Z_UTIL_INC_2488 2489 +#define Z_UTIL_INC_2489 2490 +#define Z_UTIL_INC_2490 2491 +#define Z_UTIL_INC_2491 2492 +#define Z_UTIL_INC_2492 2493 +#define Z_UTIL_INC_2493 2494 +#define Z_UTIL_INC_2494 2495 +#define Z_UTIL_INC_2495 2496 +#define Z_UTIL_INC_2496 2497 +#define Z_UTIL_INC_2497 2498 +#define Z_UTIL_INC_2498 2499 +#define Z_UTIL_INC_2499 2500 +#define Z_UTIL_INC_2500 2501 +#define Z_UTIL_INC_2501 2502 +#define Z_UTIL_INC_2502 2503 +#define Z_UTIL_INC_2503 2504 +#define Z_UTIL_INC_2504 2505 +#define Z_UTIL_INC_2505 2506 +#define Z_UTIL_INC_2506 2507 +#define Z_UTIL_INC_2507 2508 +#define Z_UTIL_INC_2508 2509 +#define Z_UTIL_INC_2509 2510 +#define Z_UTIL_INC_2510 2511 +#define Z_UTIL_INC_2511 2512 +#define Z_UTIL_INC_2512 2513 +#define Z_UTIL_INC_2513 2514 +#define Z_UTIL_INC_2514 2515 +#define Z_UTIL_INC_2515 2516 +#define Z_UTIL_INC_2516 2517 +#define Z_UTIL_INC_2517 2518 +#define Z_UTIL_INC_2518 2519 +#define Z_UTIL_INC_2519 2520 +#define Z_UTIL_INC_2520 2521 +#define Z_UTIL_INC_2521 2522 +#define Z_UTIL_INC_2522 2523 +#define Z_UTIL_INC_2523 2524 +#define Z_UTIL_INC_2524 2525 +#define Z_UTIL_INC_2525 2526 +#define Z_UTIL_INC_2526 2527 +#define Z_UTIL_INC_2527 2528 +#define Z_UTIL_INC_2528 2529 +#define Z_UTIL_INC_2529 2530 +#define Z_UTIL_INC_2530 2531 +#define Z_UTIL_INC_2531 2532 +#define Z_UTIL_INC_2532 2533 +#define Z_UTIL_INC_2533 2534 +#define Z_UTIL_INC_2534 2535 +#define Z_UTIL_INC_2535 2536 +#define Z_UTIL_INC_2536 2537 +#define Z_UTIL_INC_2537 2538 +#define Z_UTIL_INC_2538 2539 +#define Z_UTIL_INC_2539 2540 +#define Z_UTIL_INC_2540 2541 +#define Z_UTIL_INC_2541 2542 +#define Z_UTIL_INC_2542 2543 +#define Z_UTIL_INC_2543 2544 +#define Z_UTIL_INC_2544 2545 +#define Z_UTIL_INC_2545 2546 +#define Z_UTIL_INC_2546 2547 +#define Z_UTIL_INC_2547 2548 +#define Z_UTIL_INC_2548 2549 +#define Z_UTIL_INC_2549 2550 +#define Z_UTIL_INC_2550 2551 +#define Z_UTIL_INC_2551 2552 +#define Z_UTIL_INC_2552 2553 +#define Z_UTIL_INC_2553 2554 +#define Z_UTIL_INC_2554 2555 +#define Z_UTIL_INC_2555 2556 +#define Z_UTIL_INC_2556 2557 +#define Z_UTIL_INC_2557 2558 +#define Z_UTIL_INC_2558 2559 +#define Z_UTIL_INC_2559 2560 +#define Z_UTIL_INC_2560 2561 +#define Z_UTIL_INC_2561 2562 +#define Z_UTIL_INC_2562 2563 +#define Z_UTIL_INC_2563 2564 +#define Z_UTIL_INC_2564 2565 +#define Z_UTIL_INC_2565 2566 +#define Z_UTIL_INC_2566 2567 +#define Z_UTIL_INC_2567 2568 +#define Z_UTIL_INC_2568 2569 +#define Z_UTIL_INC_2569 2570 +#define Z_UTIL_INC_2570 2571 +#define Z_UTIL_INC_2571 2572 +#define Z_UTIL_INC_2572 2573 +#define Z_UTIL_INC_2573 2574 +#define Z_UTIL_INC_2574 2575 +#define Z_UTIL_INC_2575 2576 +#define Z_UTIL_INC_2576 2577 +#define Z_UTIL_INC_2577 2578 +#define Z_UTIL_INC_2578 2579 +#define Z_UTIL_INC_2579 2580 +#define Z_UTIL_INC_2580 2581 +#define Z_UTIL_INC_2581 2582 +#define Z_UTIL_INC_2582 2583 +#define Z_UTIL_INC_2583 2584 +#define Z_UTIL_INC_2584 2585 +#define Z_UTIL_INC_2585 2586 +#define Z_UTIL_INC_2586 2587 +#define Z_UTIL_INC_2587 2588 +#define Z_UTIL_INC_2588 2589 +#define Z_UTIL_INC_2589 2590 +#define Z_UTIL_INC_2590 2591 +#define Z_UTIL_INC_2591 2592 +#define Z_UTIL_INC_2592 2593 +#define Z_UTIL_INC_2593 2594 +#define Z_UTIL_INC_2594 2595 +#define Z_UTIL_INC_2595 2596 +#define Z_UTIL_INC_2596 2597 +#define Z_UTIL_INC_2597 2598 +#define Z_UTIL_INC_2598 2599 +#define Z_UTIL_INC_2599 2600 +#define Z_UTIL_INC_2600 2601 +#define Z_UTIL_INC_2601 2602 +#define Z_UTIL_INC_2602 2603 +#define Z_UTIL_INC_2603 2604 +#define Z_UTIL_INC_2604 2605 +#define Z_UTIL_INC_2605 2606 +#define Z_UTIL_INC_2606 2607 +#define Z_UTIL_INC_2607 2608 +#define Z_UTIL_INC_2608 2609 +#define Z_UTIL_INC_2609 2610 +#define Z_UTIL_INC_2610 2611 +#define Z_UTIL_INC_2611 2612 +#define Z_UTIL_INC_2612 2613 +#define Z_UTIL_INC_2613 2614 +#define Z_UTIL_INC_2614 2615 +#define Z_UTIL_INC_2615 2616 +#define Z_UTIL_INC_2616 2617 +#define Z_UTIL_INC_2617 2618 +#define Z_UTIL_INC_2618 2619 +#define Z_UTIL_INC_2619 2620 +#define Z_UTIL_INC_2620 2621 +#define Z_UTIL_INC_2621 2622 +#define Z_UTIL_INC_2622 2623 +#define Z_UTIL_INC_2623 2624 +#define Z_UTIL_INC_2624 2625 +#define Z_UTIL_INC_2625 2626 +#define Z_UTIL_INC_2626 2627 +#define Z_UTIL_INC_2627 2628 +#define Z_UTIL_INC_2628 2629 +#define Z_UTIL_INC_2629 2630 +#define Z_UTIL_INC_2630 2631 +#define Z_UTIL_INC_2631 2632 +#define Z_UTIL_INC_2632 2633 +#define Z_UTIL_INC_2633 2634 +#define Z_UTIL_INC_2634 2635 +#define Z_UTIL_INC_2635 2636 +#define Z_UTIL_INC_2636 2637 +#define Z_UTIL_INC_2637 2638 +#define Z_UTIL_INC_2638 2639 +#define Z_UTIL_INC_2639 2640 +#define Z_UTIL_INC_2640 2641 +#define Z_UTIL_INC_2641 2642 +#define Z_UTIL_INC_2642 2643 +#define Z_UTIL_INC_2643 2644 +#define Z_UTIL_INC_2644 2645 +#define Z_UTIL_INC_2645 2646 +#define Z_UTIL_INC_2646 2647 +#define Z_UTIL_INC_2647 2648 +#define Z_UTIL_INC_2648 2649 +#define Z_UTIL_INC_2649 2650 +#define Z_UTIL_INC_2650 2651 +#define Z_UTIL_INC_2651 2652 +#define Z_UTIL_INC_2652 2653 +#define Z_UTIL_INC_2653 2654 +#define Z_UTIL_INC_2654 2655 +#define Z_UTIL_INC_2655 2656 +#define Z_UTIL_INC_2656 2657 +#define Z_UTIL_INC_2657 2658 +#define Z_UTIL_INC_2658 2659 +#define Z_UTIL_INC_2659 2660 +#define Z_UTIL_INC_2660 2661 +#define Z_UTIL_INC_2661 2662 +#define Z_UTIL_INC_2662 2663 +#define Z_UTIL_INC_2663 2664 +#define Z_UTIL_INC_2664 2665 +#define Z_UTIL_INC_2665 2666 +#define Z_UTIL_INC_2666 2667 +#define Z_UTIL_INC_2667 2668 +#define Z_UTIL_INC_2668 2669 +#define Z_UTIL_INC_2669 2670 +#define Z_UTIL_INC_2670 2671 +#define Z_UTIL_INC_2671 2672 +#define Z_UTIL_INC_2672 2673 +#define Z_UTIL_INC_2673 2674 +#define Z_UTIL_INC_2674 2675 +#define Z_UTIL_INC_2675 2676 +#define Z_UTIL_INC_2676 2677 +#define Z_UTIL_INC_2677 2678 +#define Z_UTIL_INC_2678 2679 +#define Z_UTIL_INC_2679 2680 +#define Z_UTIL_INC_2680 2681 +#define Z_UTIL_INC_2681 2682 +#define Z_UTIL_INC_2682 2683 +#define Z_UTIL_INC_2683 2684 +#define Z_UTIL_INC_2684 2685 +#define Z_UTIL_INC_2685 2686 +#define Z_UTIL_INC_2686 2687 +#define Z_UTIL_INC_2687 2688 +#define Z_UTIL_INC_2688 2689 +#define Z_UTIL_INC_2689 2690 +#define Z_UTIL_INC_2690 2691 +#define Z_UTIL_INC_2691 2692 +#define Z_UTIL_INC_2692 2693 +#define Z_UTIL_INC_2693 2694 +#define Z_UTIL_INC_2694 2695 +#define Z_UTIL_INC_2695 2696 +#define Z_UTIL_INC_2696 2697 +#define Z_UTIL_INC_2697 2698 +#define Z_UTIL_INC_2698 2699 +#define Z_UTIL_INC_2699 2700 +#define Z_UTIL_INC_2700 2701 +#define Z_UTIL_INC_2701 2702 +#define Z_UTIL_INC_2702 2703 +#define Z_UTIL_INC_2703 2704 +#define Z_UTIL_INC_2704 2705 +#define Z_UTIL_INC_2705 2706 +#define Z_UTIL_INC_2706 2707 +#define Z_UTIL_INC_2707 2708 +#define Z_UTIL_INC_2708 2709 +#define Z_UTIL_INC_2709 2710 +#define Z_UTIL_INC_2710 2711 +#define Z_UTIL_INC_2711 2712 +#define Z_UTIL_INC_2712 2713 +#define Z_UTIL_INC_2713 2714 +#define Z_UTIL_INC_2714 2715 +#define Z_UTIL_INC_2715 2716 +#define Z_UTIL_INC_2716 2717 +#define Z_UTIL_INC_2717 2718 +#define Z_UTIL_INC_2718 2719 +#define Z_UTIL_INC_2719 2720 +#define Z_UTIL_INC_2720 2721 +#define Z_UTIL_INC_2721 2722 +#define Z_UTIL_INC_2722 2723 +#define Z_UTIL_INC_2723 2724 +#define Z_UTIL_INC_2724 2725 +#define Z_UTIL_INC_2725 2726 +#define Z_UTIL_INC_2726 2727 +#define Z_UTIL_INC_2727 2728 +#define Z_UTIL_INC_2728 2729 +#define Z_UTIL_INC_2729 2730 +#define Z_UTIL_INC_2730 2731 +#define Z_UTIL_INC_2731 2732 +#define Z_UTIL_INC_2732 2733 +#define Z_UTIL_INC_2733 2734 +#define Z_UTIL_INC_2734 2735 +#define Z_UTIL_INC_2735 2736 +#define Z_UTIL_INC_2736 2737 +#define Z_UTIL_INC_2737 2738 +#define Z_UTIL_INC_2738 2739 +#define Z_UTIL_INC_2739 2740 +#define Z_UTIL_INC_2740 2741 +#define Z_UTIL_INC_2741 2742 +#define Z_UTIL_INC_2742 2743 +#define Z_UTIL_INC_2743 2744 +#define Z_UTIL_INC_2744 2745 +#define Z_UTIL_INC_2745 2746 +#define Z_UTIL_INC_2746 2747 +#define Z_UTIL_INC_2747 2748 +#define Z_UTIL_INC_2748 2749 +#define Z_UTIL_INC_2749 2750 +#define Z_UTIL_INC_2750 2751 +#define Z_UTIL_INC_2751 2752 +#define Z_UTIL_INC_2752 2753 +#define Z_UTIL_INC_2753 2754 +#define Z_UTIL_INC_2754 2755 +#define Z_UTIL_INC_2755 2756 +#define Z_UTIL_INC_2756 2757 +#define Z_UTIL_INC_2757 2758 +#define Z_UTIL_INC_2758 2759 +#define Z_UTIL_INC_2759 2760 +#define Z_UTIL_INC_2760 2761 +#define Z_UTIL_INC_2761 2762 +#define Z_UTIL_INC_2762 2763 +#define Z_UTIL_INC_2763 2764 +#define Z_UTIL_INC_2764 2765 +#define Z_UTIL_INC_2765 2766 +#define Z_UTIL_INC_2766 2767 +#define Z_UTIL_INC_2767 2768 +#define Z_UTIL_INC_2768 2769 +#define Z_UTIL_INC_2769 2770 +#define Z_UTIL_INC_2770 2771 +#define Z_UTIL_INC_2771 2772 +#define Z_UTIL_INC_2772 2773 +#define Z_UTIL_INC_2773 2774 +#define Z_UTIL_INC_2774 2775 +#define Z_UTIL_INC_2775 2776 +#define Z_UTIL_INC_2776 2777 +#define Z_UTIL_INC_2777 2778 +#define Z_UTIL_INC_2778 2779 +#define Z_UTIL_INC_2779 2780 +#define Z_UTIL_INC_2780 2781 +#define Z_UTIL_INC_2781 2782 +#define Z_UTIL_INC_2782 2783 +#define Z_UTIL_INC_2783 2784 +#define Z_UTIL_INC_2784 2785 +#define Z_UTIL_INC_2785 2786 +#define Z_UTIL_INC_2786 2787 +#define Z_UTIL_INC_2787 2788 +#define Z_UTIL_INC_2788 2789 +#define Z_UTIL_INC_2789 2790 +#define Z_UTIL_INC_2790 2791 +#define Z_UTIL_INC_2791 2792 +#define Z_UTIL_INC_2792 2793 +#define Z_UTIL_INC_2793 2794 +#define Z_UTIL_INC_2794 2795 +#define Z_UTIL_INC_2795 2796 +#define Z_UTIL_INC_2796 2797 +#define Z_UTIL_INC_2797 2798 +#define Z_UTIL_INC_2798 2799 +#define Z_UTIL_INC_2799 2800 +#define Z_UTIL_INC_2800 2801 +#define Z_UTIL_INC_2801 2802 +#define Z_UTIL_INC_2802 2803 +#define Z_UTIL_INC_2803 2804 +#define Z_UTIL_INC_2804 2805 +#define Z_UTIL_INC_2805 2806 +#define Z_UTIL_INC_2806 2807 +#define Z_UTIL_INC_2807 2808 +#define Z_UTIL_INC_2808 2809 +#define Z_UTIL_INC_2809 2810 +#define Z_UTIL_INC_2810 2811 +#define Z_UTIL_INC_2811 2812 +#define Z_UTIL_INC_2812 2813 +#define Z_UTIL_INC_2813 2814 +#define Z_UTIL_INC_2814 2815 +#define Z_UTIL_INC_2815 2816 +#define Z_UTIL_INC_2816 2817 +#define Z_UTIL_INC_2817 2818 +#define Z_UTIL_INC_2818 2819 +#define Z_UTIL_INC_2819 2820 +#define Z_UTIL_INC_2820 2821 +#define Z_UTIL_INC_2821 2822 +#define Z_UTIL_INC_2822 2823 +#define Z_UTIL_INC_2823 2824 +#define Z_UTIL_INC_2824 2825 +#define Z_UTIL_INC_2825 2826 +#define Z_UTIL_INC_2826 2827 +#define Z_UTIL_INC_2827 2828 +#define Z_UTIL_INC_2828 2829 +#define Z_UTIL_INC_2829 2830 +#define Z_UTIL_INC_2830 2831 +#define Z_UTIL_INC_2831 2832 +#define Z_UTIL_INC_2832 2833 +#define Z_UTIL_INC_2833 2834 +#define Z_UTIL_INC_2834 2835 +#define Z_UTIL_INC_2835 2836 +#define Z_UTIL_INC_2836 2837 +#define Z_UTIL_INC_2837 2838 +#define Z_UTIL_INC_2838 2839 +#define Z_UTIL_INC_2839 2840 +#define Z_UTIL_INC_2840 2841 +#define Z_UTIL_INC_2841 2842 +#define Z_UTIL_INC_2842 2843 +#define Z_UTIL_INC_2843 2844 +#define Z_UTIL_INC_2844 2845 +#define Z_UTIL_INC_2845 2846 +#define Z_UTIL_INC_2846 2847 +#define Z_UTIL_INC_2847 2848 +#define Z_UTIL_INC_2848 2849 +#define Z_UTIL_INC_2849 2850 +#define Z_UTIL_INC_2850 2851 +#define Z_UTIL_INC_2851 2852 +#define Z_UTIL_INC_2852 2853 +#define Z_UTIL_INC_2853 2854 +#define Z_UTIL_INC_2854 2855 +#define Z_UTIL_INC_2855 2856 +#define Z_UTIL_INC_2856 2857 +#define Z_UTIL_INC_2857 2858 +#define Z_UTIL_INC_2858 2859 +#define Z_UTIL_INC_2859 2860 +#define Z_UTIL_INC_2860 2861 +#define Z_UTIL_INC_2861 2862 +#define Z_UTIL_INC_2862 2863 +#define Z_UTIL_INC_2863 2864 +#define Z_UTIL_INC_2864 2865 +#define Z_UTIL_INC_2865 2866 +#define Z_UTIL_INC_2866 2867 +#define Z_UTIL_INC_2867 2868 +#define Z_UTIL_INC_2868 2869 +#define Z_UTIL_INC_2869 2870 +#define Z_UTIL_INC_2870 2871 +#define Z_UTIL_INC_2871 2872 +#define Z_UTIL_INC_2872 2873 +#define Z_UTIL_INC_2873 2874 +#define Z_UTIL_INC_2874 2875 +#define Z_UTIL_INC_2875 2876 +#define Z_UTIL_INC_2876 2877 +#define Z_UTIL_INC_2877 2878 +#define Z_UTIL_INC_2878 2879 +#define Z_UTIL_INC_2879 2880 +#define Z_UTIL_INC_2880 2881 +#define Z_UTIL_INC_2881 2882 +#define Z_UTIL_INC_2882 2883 +#define Z_UTIL_INC_2883 2884 +#define Z_UTIL_INC_2884 2885 +#define Z_UTIL_INC_2885 2886 +#define Z_UTIL_INC_2886 2887 +#define Z_UTIL_INC_2887 2888 +#define Z_UTIL_INC_2888 2889 +#define Z_UTIL_INC_2889 2890 +#define Z_UTIL_INC_2890 2891 +#define Z_UTIL_INC_2891 2892 +#define Z_UTIL_INC_2892 2893 +#define Z_UTIL_INC_2893 2894 +#define Z_UTIL_INC_2894 2895 +#define Z_UTIL_INC_2895 2896 +#define Z_UTIL_INC_2896 2897 +#define Z_UTIL_INC_2897 2898 +#define Z_UTIL_INC_2898 2899 +#define Z_UTIL_INC_2899 2900 +#define Z_UTIL_INC_2900 2901 +#define Z_UTIL_INC_2901 2902 +#define Z_UTIL_INC_2902 2903 +#define Z_UTIL_INC_2903 2904 +#define Z_UTIL_INC_2904 2905 +#define Z_UTIL_INC_2905 2906 +#define Z_UTIL_INC_2906 2907 +#define Z_UTIL_INC_2907 2908 +#define Z_UTIL_INC_2908 2909 +#define Z_UTIL_INC_2909 2910 +#define Z_UTIL_INC_2910 2911 +#define Z_UTIL_INC_2911 2912 +#define Z_UTIL_INC_2912 2913 +#define Z_UTIL_INC_2913 2914 +#define Z_UTIL_INC_2914 2915 +#define Z_UTIL_INC_2915 2916 +#define Z_UTIL_INC_2916 2917 +#define Z_UTIL_INC_2917 2918 +#define Z_UTIL_INC_2918 2919 +#define Z_UTIL_INC_2919 2920 +#define Z_UTIL_INC_2920 2921 +#define Z_UTIL_INC_2921 2922 +#define Z_UTIL_INC_2922 2923 +#define Z_UTIL_INC_2923 2924 +#define Z_UTIL_INC_2924 2925 +#define Z_UTIL_INC_2925 2926 +#define Z_UTIL_INC_2926 2927 +#define Z_UTIL_INC_2927 2928 +#define Z_UTIL_INC_2928 2929 +#define Z_UTIL_INC_2929 2930 +#define Z_UTIL_INC_2930 2931 +#define Z_UTIL_INC_2931 2932 +#define Z_UTIL_INC_2932 2933 +#define Z_UTIL_INC_2933 2934 +#define Z_UTIL_INC_2934 2935 +#define Z_UTIL_INC_2935 2936 +#define Z_UTIL_INC_2936 2937 +#define Z_UTIL_INC_2937 2938 +#define Z_UTIL_INC_2938 2939 +#define Z_UTIL_INC_2939 2940 +#define Z_UTIL_INC_2940 2941 +#define Z_UTIL_INC_2941 2942 +#define Z_UTIL_INC_2942 2943 +#define Z_UTIL_INC_2943 2944 +#define Z_UTIL_INC_2944 2945 +#define Z_UTIL_INC_2945 2946 +#define Z_UTIL_INC_2946 2947 +#define Z_UTIL_INC_2947 2948 +#define Z_UTIL_INC_2948 2949 +#define Z_UTIL_INC_2949 2950 +#define Z_UTIL_INC_2950 2951 +#define Z_UTIL_INC_2951 2952 +#define Z_UTIL_INC_2952 2953 +#define Z_UTIL_INC_2953 2954 +#define Z_UTIL_INC_2954 2955 +#define Z_UTIL_INC_2955 2956 +#define Z_UTIL_INC_2956 2957 +#define Z_UTIL_INC_2957 2958 +#define Z_UTIL_INC_2958 2959 +#define Z_UTIL_INC_2959 2960 +#define Z_UTIL_INC_2960 2961 +#define Z_UTIL_INC_2961 2962 +#define Z_UTIL_INC_2962 2963 +#define Z_UTIL_INC_2963 2964 +#define Z_UTIL_INC_2964 2965 +#define Z_UTIL_INC_2965 2966 +#define Z_UTIL_INC_2966 2967 +#define Z_UTIL_INC_2967 2968 +#define Z_UTIL_INC_2968 2969 +#define Z_UTIL_INC_2969 2970 +#define Z_UTIL_INC_2970 2971 +#define Z_UTIL_INC_2971 2972 +#define Z_UTIL_INC_2972 2973 +#define Z_UTIL_INC_2973 2974 +#define Z_UTIL_INC_2974 2975 +#define Z_UTIL_INC_2975 2976 +#define Z_UTIL_INC_2976 2977 +#define Z_UTIL_INC_2977 2978 +#define Z_UTIL_INC_2978 2979 +#define Z_UTIL_INC_2979 2980 +#define Z_UTIL_INC_2980 2981 +#define Z_UTIL_INC_2981 2982 +#define Z_UTIL_INC_2982 2983 +#define Z_UTIL_INC_2983 2984 +#define Z_UTIL_INC_2984 2985 +#define Z_UTIL_INC_2985 2986 +#define Z_UTIL_INC_2986 2987 +#define Z_UTIL_INC_2987 2988 +#define Z_UTIL_INC_2988 2989 +#define Z_UTIL_INC_2989 2990 +#define Z_UTIL_INC_2990 2991 +#define Z_UTIL_INC_2991 2992 +#define Z_UTIL_INC_2992 2993 +#define Z_UTIL_INC_2993 2994 +#define Z_UTIL_INC_2994 2995 +#define Z_UTIL_INC_2995 2996 +#define Z_UTIL_INC_2996 2997 +#define Z_UTIL_INC_2997 2998 +#define Z_UTIL_INC_2998 2999 +#define Z_UTIL_INC_2999 3000 +#define Z_UTIL_INC_3000 3001 +#define Z_UTIL_INC_3001 3002 +#define Z_UTIL_INC_3002 3003 +#define Z_UTIL_INC_3003 3004 +#define Z_UTIL_INC_3004 3005 +#define Z_UTIL_INC_3005 3006 +#define Z_UTIL_INC_3006 3007 +#define Z_UTIL_INC_3007 3008 +#define Z_UTIL_INC_3008 3009 +#define Z_UTIL_INC_3009 3010 +#define Z_UTIL_INC_3010 3011 +#define Z_UTIL_INC_3011 3012 +#define Z_UTIL_INC_3012 3013 +#define Z_UTIL_INC_3013 3014 +#define Z_UTIL_INC_3014 3015 +#define Z_UTIL_INC_3015 3016 +#define Z_UTIL_INC_3016 3017 +#define Z_UTIL_INC_3017 3018 +#define Z_UTIL_INC_3018 3019 +#define Z_UTIL_INC_3019 3020 +#define Z_UTIL_INC_3020 3021 +#define Z_UTIL_INC_3021 3022 +#define Z_UTIL_INC_3022 3023 +#define Z_UTIL_INC_3023 3024 +#define Z_UTIL_INC_3024 3025 +#define Z_UTIL_INC_3025 3026 +#define Z_UTIL_INC_3026 3027 +#define Z_UTIL_INC_3027 3028 +#define Z_UTIL_INC_3028 3029 +#define Z_UTIL_INC_3029 3030 +#define Z_UTIL_INC_3030 3031 +#define Z_UTIL_INC_3031 3032 +#define Z_UTIL_INC_3032 3033 +#define Z_UTIL_INC_3033 3034 +#define Z_UTIL_INC_3034 3035 +#define Z_UTIL_INC_3035 3036 +#define Z_UTIL_INC_3036 3037 +#define Z_UTIL_INC_3037 3038 +#define Z_UTIL_INC_3038 3039 +#define Z_UTIL_INC_3039 3040 +#define Z_UTIL_INC_3040 3041 +#define Z_UTIL_INC_3041 3042 +#define Z_UTIL_INC_3042 3043 +#define Z_UTIL_INC_3043 3044 +#define Z_UTIL_INC_3044 3045 +#define Z_UTIL_INC_3045 3046 +#define Z_UTIL_INC_3046 3047 +#define Z_UTIL_INC_3047 3048 +#define Z_UTIL_INC_3048 3049 +#define Z_UTIL_INC_3049 3050 +#define Z_UTIL_INC_3050 3051 +#define Z_UTIL_INC_3051 3052 +#define Z_UTIL_INC_3052 3053 +#define Z_UTIL_INC_3053 3054 +#define Z_UTIL_INC_3054 3055 +#define Z_UTIL_INC_3055 3056 +#define Z_UTIL_INC_3056 3057 +#define Z_UTIL_INC_3057 3058 +#define Z_UTIL_INC_3058 3059 +#define Z_UTIL_INC_3059 3060 +#define Z_UTIL_INC_3060 3061 +#define Z_UTIL_INC_3061 3062 +#define Z_UTIL_INC_3062 3063 +#define Z_UTIL_INC_3063 3064 +#define Z_UTIL_INC_3064 3065 +#define Z_UTIL_INC_3065 3066 +#define Z_UTIL_INC_3066 3067 +#define Z_UTIL_INC_3067 3068 +#define Z_UTIL_INC_3068 3069 +#define Z_UTIL_INC_3069 3070 +#define Z_UTIL_INC_3070 3071 +#define Z_UTIL_INC_3071 3072 +#define Z_UTIL_INC_3072 3073 +#define Z_UTIL_INC_3073 3074 +#define Z_UTIL_INC_3074 3075 +#define Z_UTIL_INC_3075 3076 +#define Z_UTIL_INC_3076 3077 +#define Z_UTIL_INC_3077 3078 +#define Z_UTIL_INC_3078 3079 +#define Z_UTIL_INC_3079 3080 +#define Z_UTIL_INC_3080 3081 +#define Z_UTIL_INC_3081 3082 +#define Z_UTIL_INC_3082 3083 +#define Z_UTIL_INC_3083 3084 +#define Z_UTIL_INC_3084 3085 +#define Z_UTIL_INC_3085 3086 +#define Z_UTIL_INC_3086 3087 +#define Z_UTIL_INC_3087 3088 +#define Z_UTIL_INC_3088 3089 +#define Z_UTIL_INC_3089 3090 +#define Z_UTIL_INC_3090 3091 +#define Z_UTIL_INC_3091 3092 +#define Z_UTIL_INC_3092 3093 +#define Z_UTIL_INC_3093 3094 +#define Z_UTIL_INC_3094 3095 +#define Z_UTIL_INC_3095 3096 +#define Z_UTIL_INC_3096 3097 +#define Z_UTIL_INC_3097 3098 +#define Z_UTIL_INC_3098 3099 +#define Z_UTIL_INC_3099 3100 +#define Z_UTIL_INC_3100 3101 +#define Z_UTIL_INC_3101 3102 +#define Z_UTIL_INC_3102 3103 +#define Z_UTIL_INC_3103 3104 +#define Z_UTIL_INC_3104 3105 +#define Z_UTIL_INC_3105 3106 +#define Z_UTIL_INC_3106 3107 +#define Z_UTIL_INC_3107 3108 +#define Z_UTIL_INC_3108 3109 +#define Z_UTIL_INC_3109 3110 +#define Z_UTIL_INC_3110 3111 +#define Z_UTIL_INC_3111 3112 +#define Z_UTIL_INC_3112 3113 +#define Z_UTIL_INC_3113 3114 +#define Z_UTIL_INC_3114 3115 +#define Z_UTIL_INC_3115 3116 +#define Z_UTIL_INC_3116 3117 +#define Z_UTIL_INC_3117 3118 +#define Z_UTIL_INC_3118 3119 +#define Z_UTIL_INC_3119 3120 +#define Z_UTIL_INC_3120 3121 +#define Z_UTIL_INC_3121 3122 +#define Z_UTIL_INC_3122 3123 +#define Z_UTIL_INC_3123 3124 +#define Z_UTIL_INC_3124 3125 +#define Z_UTIL_INC_3125 3126 +#define Z_UTIL_INC_3126 3127 +#define Z_UTIL_INC_3127 3128 +#define Z_UTIL_INC_3128 3129 +#define Z_UTIL_INC_3129 3130 +#define Z_UTIL_INC_3130 3131 +#define Z_UTIL_INC_3131 3132 +#define Z_UTIL_INC_3132 3133 +#define Z_UTIL_INC_3133 3134 +#define Z_UTIL_INC_3134 3135 +#define Z_UTIL_INC_3135 3136 +#define Z_UTIL_INC_3136 3137 +#define Z_UTIL_INC_3137 3138 +#define Z_UTIL_INC_3138 3139 +#define Z_UTIL_INC_3139 3140 +#define Z_UTIL_INC_3140 3141 +#define Z_UTIL_INC_3141 3142 +#define Z_UTIL_INC_3142 3143 +#define Z_UTIL_INC_3143 3144 +#define Z_UTIL_INC_3144 3145 +#define Z_UTIL_INC_3145 3146 +#define Z_UTIL_INC_3146 3147 +#define Z_UTIL_INC_3147 3148 +#define Z_UTIL_INC_3148 3149 +#define Z_UTIL_INC_3149 3150 +#define Z_UTIL_INC_3150 3151 +#define Z_UTIL_INC_3151 3152 +#define Z_UTIL_INC_3152 3153 +#define Z_UTIL_INC_3153 3154 +#define Z_UTIL_INC_3154 3155 +#define Z_UTIL_INC_3155 3156 +#define Z_UTIL_INC_3156 3157 +#define Z_UTIL_INC_3157 3158 +#define Z_UTIL_INC_3158 3159 +#define Z_UTIL_INC_3159 3160 +#define Z_UTIL_INC_3160 3161 +#define Z_UTIL_INC_3161 3162 +#define Z_UTIL_INC_3162 3163 +#define Z_UTIL_INC_3163 3164 +#define Z_UTIL_INC_3164 3165 +#define Z_UTIL_INC_3165 3166 +#define Z_UTIL_INC_3166 3167 +#define Z_UTIL_INC_3167 3168 +#define Z_UTIL_INC_3168 3169 +#define Z_UTIL_INC_3169 3170 +#define Z_UTIL_INC_3170 3171 +#define Z_UTIL_INC_3171 3172 +#define Z_UTIL_INC_3172 3173 +#define Z_UTIL_INC_3173 3174 +#define Z_UTIL_INC_3174 3175 +#define Z_UTIL_INC_3175 3176 +#define Z_UTIL_INC_3176 3177 +#define Z_UTIL_INC_3177 3178 +#define Z_UTIL_INC_3178 3179 +#define Z_UTIL_INC_3179 3180 +#define Z_UTIL_INC_3180 3181 +#define Z_UTIL_INC_3181 3182 +#define Z_UTIL_INC_3182 3183 +#define Z_UTIL_INC_3183 3184 +#define Z_UTIL_INC_3184 3185 +#define Z_UTIL_INC_3185 3186 +#define Z_UTIL_INC_3186 3187 +#define Z_UTIL_INC_3187 3188 +#define Z_UTIL_INC_3188 3189 +#define Z_UTIL_INC_3189 3190 +#define Z_UTIL_INC_3190 3191 +#define Z_UTIL_INC_3191 3192 +#define Z_UTIL_INC_3192 3193 +#define Z_UTIL_INC_3193 3194 +#define Z_UTIL_INC_3194 3195 +#define Z_UTIL_INC_3195 3196 +#define Z_UTIL_INC_3196 3197 +#define Z_UTIL_INC_3197 3198 +#define Z_UTIL_INC_3198 3199 +#define Z_UTIL_INC_3199 3200 +#define Z_UTIL_INC_3200 3201 +#define Z_UTIL_INC_3201 3202 +#define Z_UTIL_INC_3202 3203 +#define Z_UTIL_INC_3203 3204 +#define Z_UTIL_INC_3204 3205 +#define Z_UTIL_INC_3205 3206 +#define Z_UTIL_INC_3206 3207 +#define Z_UTIL_INC_3207 3208 +#define Z_UTIL_INC_3208 3209 +#define Z_UTIL_INC_3209 3210 +#define Z_UTIL_INC_3210 3211 +#define Z_UTIL_INC_3211 3212 +#define Z_UTIL_INC_3212 3213 +#define Z_UTIL_INC_3213 3214 +#define Z_UTIL_INC_3214 3215 +#define Z_UTIL_INC_3215 3216 +#define Z_UTIL_INC_3216 3217 +#define Z_UTIL_INC_3217 3218 +#define Z_UTIL_INC_3218 3219 +#define Z_UTIL_INC_3219 3220 +#define Z_UTIL_INC_3220 3221 +#define Z_UTIL_INC_3221 3222 +#define Z_UTIL_INC_3222 3223 +#define Z_UTIL_INC_3223 3224 +#define Z_UTIL_INC_3224 3225 +#define Z_UTIL_INC_3225 3226 +#define Z_UTIL_INC_3226 3227 +#define Z_UTIL_INC_3227 3228 +#define Z_UTIL_INC_3228 3229 +#define Z_UTIL_INC_3229 3230 +#define Z_UTIL_INC_3230 3231 +#define Z_UTIL_INC_3231 3232 +#define Z_UTIL_INC_3232 3233 +#define Z_UTIL_INC_3233 3234 +#define Z_UTIL_INC_3234 3235 +#define Z_UTIL_INC_3235 3236 +#define Z_UTIL_INC_3236 3237 +#define Z_UTIL_INC_3237 3238 +#define Z_UTIL_INC_3238 3239 +#define Z_UTIL_INC_3239 3240 +#define Z_UTIL_INC_3240 3241 +#define Z_UTIL_INC_3241 3242 +#define Z_UTIL_INC_3242 3243 +#define Z_UTIL_INC_3243 3244 +#define Z_UTIL_INC_3244 3245 +#define Z_UTIL_INC_3245 3246 +#define Z_UTIL_INC_3246 3247 +#define Z_UTIL_INC_3247 3248 +#define Z_UTIL_INC_3248 3249 +#define Z_UTIL_INC_3249 3250 +#define Z_UTIL_INC_3250 3251 +#define Z_UTIL_INC_3251 3252 +#define Z_UTIL_INC_3252 3253 +#define Z_UTIL_INC_3253 3254 +#define Z_UTIL_INC_3254 3255 +#define Z_UTIL_INC_3255 3256 +#define Z_UTIL_INC_3256 3257 +#define Z_UTIL_INC_3257 3258 +#define Z_UTIL_INC_3258 3259 +#define Z_UTIL_INC_3259 3260 +#define Z_UTIL_INC_3260 3261 +#define Z_UTIL_INC_3261 3262 +#define Z_UTIL_INC_3262 3263 +#define Z_UTIL_INC_3263 3264 +#define Z_UTIL_INC_3264 3265 +#define Z_UTIL_INC_3265 3266 +#define Z_UTIL_INC_3266 3267 +#define Z_UTIL_INC_3267 3268 +#define Z_UTIL_INC_3268 3269 +#define Z_UTIL_INC_3269 3270 +#define Z_UTIL_INC_3270 3271 +#define Z_UTIL_INC_3271 3272 +#define Z_UTIL_INC_3272 3273 +#define Z_UTIL_INC_3273 3274 +#define Z_UTIL_INC_3274 3275 +#define Z_UTIL_INC_3275 3276 +#define Z_UTIL_INC_3276 3277 +#define Z_UTIL_INC_3277 3278 +#define Z_UTIL_INC_3278 3279 +#define Z_UTIL_INC_3279 3280 +#define Z_UTIL_INC_3280 3281 +#define Z_UTIL_INC_3281 3282 +#define Z_UTIL_INC_3282 3283 +#define Z_UTIL_INC_3283 3284 +#define Z_UTIL_INC_3284 3285 +#define Z_UTIL_INC_3285 3286 +#define Z_UTIL_INC_3286 3287 +#define Z_UTIL_INC_3287 3288 +#define Z_UTIL_INC_3288 3289 +#define Z_UTIL_INC_3289 3290 +#define Z_UTIL_INC_3290 3291 +#define Z_UTIL_INC_3291 3292 +#define Z_UTIL_INC_3292 3293 +#define Z_UTIL_INC_3293 3294 +#define Z_UTIL_INC_3294 3295 +#define Z_UTIL_INC_3295 3296 +#define Z_UTIL_INC_3296 3297 +#define Z_UTIL_INC_3297 3298 +#define Z_UTIL_INC_3298 3299 +#define Z_UTIL_INC_3299 3300 +#define Z_UTIL_INC_3300 3301 +#define Z_UTIL_INC_3301 3302 +#define Z_UTIL_INC_3302 3303 +#define Z_UTIL_INC_3303 3304 +#define Z_UTIL_INC_3304 3305 +#define Z_UTIL_INC_3305 3306 +#define Z_UTIL_INC_3306 3307 +#define Z_UTIL_INC_3307 3308 +#define Z_UTIL_INC_3308 3309 +#define Z_UTIL_INC_3309 3310 +#define Z_UTIL_INC_3310 3311 +#define Z_UTIL_INC_3311 3312 +#define Z_UTIL_INC_3312 3313 +#define Z_UTIL_INC_3313 3314 +#define Z_UTIL_INC_3314 3315 +#define Z_UTIL_INC_3315 3316 +#define Z_UTIL_INC_3316 3317 +#define Z_UTIL_INC_3317 3318 +#define Z_UTIL_INC_3318 3319 +#define Z_UTIL_INC_3319 3320 +#define Z_UTIL_INC_3320 3321 +#define Z_UTIL_INC_3321 3322 +#define Z_UTIL_INC_3322 3323 +#define Z_UTIL_INC_3323 3324 +#define Z_UTIL_INC_3324 3325 +#define Z_UTIL_INC_3325 3326 +#define Z_UTIL_INC_3326 3327 +#define Z_UTIL_INC_3327 3328 +#define Z_UTIL_INC_3328 3329 +#define Z_UTIL_INC_3329 3330 +#define Z_UTIL_INC_3330 3331 +#define Z_UTIL_INC_3331 3332 +#define Z_UTIL_INC_3332 3333 +#define Z_UTIL_INC_3333 3334 +#define Z_UTIL_INC_3334 3335 +#define Z_UTIL_INC_3335 3336 +#define Z_UTIL_INC_3336 3337 +#define Z_UTIL_INC_3337 3338 +#define Z_UTIL_INC_3338 3339 +#define Z_UTIL_INC_3339 3340 +#define Z_UTIL_INC_3340 3341 +#define Z_UTIL_INC_3341 3342 +#define Z_UTIL_INC_3342 3343 +#define Z_UTIL_INC_3343 3344 +#define Z_UTIL_INC_3344 3345 +#define Z_UTIL_INC_3345 3346 +#define Z_UTIL_INC_3346 3347 +#define Z_UTIL_INC_3347 3348 +#define Z_UTIL_INC_3348 3349 +#define Z_UTIL_INC_3349 3350 +#define Z_UTIL_INC_3350 3351 +#define Z_UTIL_INC_3351 3352 +#define Z_UTIL_INC_3352 3353 +#define Z_UTIL_INC_3353 3354 +#define Z_UTIL_INC_3354 3355 +#define Z_UTIL_INC_3355 3356 +#define Z_UTIL_INC_3356 3357 +#define Z_UTIL_INC_3357 3358 +#define Z_UTIL_INC_3358 3359 +#define Z_UTIL_INC_3359 3360 +#define Z_UTIL_INC_3360 3361 +#define Z_UTIL_INC_3361 3362 +#define Z_UTIL_INC_3362 3363 +#define Z_UTIL_INC_3363 3364 +#define Z_UTIL_INC_3364 3365 +#define Z_UTIL_INC_3365 3366 +#define Z_UTIL_INC_3366 3367 +#define Z_UTIL_INC_3367 3368 +#define Z_UTIL_INC_3368 3369 +#define Z_UTIL_INC_3369 3370 +#define Z_UTIL_INC_3370 3371 +#define Z_UTIL_INC_3371 3372 +#define Z_UTIL_INC_3372 3373 +#define Z_UTIL_INC_3373 3374 +#define Z_UTIL_INC_3374 3375 +#define Z_UTIL_INC_3375 3376 +#define Z_UTIL_INC_3376 3377 +#define Z_UTIL_INC_3377 3378 +#define Z_UTIL_INC_3378 3379 +#define Z_UTIL_INC_3379 3380 +#define Z_UTIL_INC_3380 3381 +#define Z_UTIL_INC_3381 3382 +#define Z_UTIL_INC_3382 3383 +#define Z_UTIL_INC_3383 3384 +#define Z_UTIL_INC_3384 3385 +#define Z_UTIL_INC_3385 3386 +#define Z_UTIL_INC_3386 3387 +#define Z_UTIL_INC_3387 3388 +#define Z_UTIL_INC_3388 3389 +#define Z_UTIL_INC_3389 3390 +#define Z_UTIL_INC_3390 3391 +#define Z_UTIL_INC_3391 3392 +#define Z_UTIL_INC_3392 3393 +#define Z_UTIL_INC_3393 3394 +#define Z_UTIL_INC_3394 3395 +#define Z_UTIL_INC_3395 3396 +#define Z_UTIL_INC_3396 3397 +#define Z_UTIL_INC_3397 3398 +#define Z_UTIL_INC_3398 3399 +#define Z_UTIL_INC_3399 3400 +#define Z_UTIL_INC_3400 3401 +#define Z_UTIL_INC_3401 3402 +#define Z_UTIL_INC_3402 3403 +#define Z_UTIL_INC_3403 3404 +#define Z_UTIL_INC_3404 3405 +#define Z_UTIL_INC_3405 3406 +#define Z_UTIL_INC_3406 3407 +#define Z_UTIL_INC_3407 3408 +#define Z_UTIL_INC_3408 3409 +#define Z_UTIL_INC_3409 3410 +#define Z_UTIL_INC_3410 3411 +#define Z_UTIL_INC_3411 3412 +#define Z_UTIL_INC_3412 3413 +#define Z_UTIL_INC_3413 3414 +#define Z_UTIL_INC_3414 3415 +#define Z_UTIL_INC_3415 3416 +#define Z_UTIL_INC_3416 3417 +#define Z_UTIL_INC_3417 3418 +#define Z_UTIL_INC_3418 3419 +#define Z_UTIL_INC_3419 3420 +#define Z_UTIL_INC_3420 3421 +#define Z_UTIL_INC_3421 3422 +#define Z_UTIL_INC_3422 3423 +#define Z_UTIL_INC_3423 3424 +#define Z_UTIL_INC_3424 3425 +#define Z_UTIL_INC_3425 3426 +#define Z_UTIL_INC_3426 3427 +#define Z_UTIL_INC_3427 3428 +#define Z_UTIL_INC_3428 3429 +#define Z_UTIL_INC_3429 3430 +#define Z_UTIL_INC_3430 3431 +#define Z_UTIL_INC_3431 3432 +#define Z_UTIL_INC_3432 3433 +#define Z_UTIL_INC_3433 3434 +#define Z_UTIL_INC_3434 3435 +#define Z_UTIL_INC_3435 3436 +#define Z_UTIL_INC_3436 3437 +#define Z_UTIL_INC_3437 3438 +#define Z_UTIL_INC_3438 3439 +#define Z_UTIL_INC_3439 3440 +#define Z_UTIL_INC_3440 3441 +#define Z_UTIL_INC_3441 3442 +#define Z_UTIL_INC_3442 3443 +#define Z_UTIL_INC_3443 3444 +#define Z_UTIL_INC_3444 3445 +#define Z_UTIL_INC_3445 3446 +#define Z_UTIL_INC_3446 3447 +#define Z_UTIL_INC_3447 3448 +#define Z_UTIL_INC_3448 3449 +#define Z_UTIL_INC_3449 3450 +#define Z_UTIL_INC_3450 3451 +#define Z_UTIL_INC_3451 3452 +#define Z_UTIL_INC_3452 3453 +#define Z_UTIL_INC_3453 3454 +#define Z_UTIL_INC_3454 3455 +#define Z_UTIL_INC_3455 3456 +#define Z_UTIL_INC_3456 3457 +#define Z_UTIL_INC_3457 3458 +#define Z_UTIL_INC_3458 3459 +#define Z_UTIL_INC_3459 3460 +#define Z_UTIL_INC_3460 3461 +#define Z_UTIL_INC_3461 3462 +#define Z_UTIL_INC_3462 3463 +#define Z_UTIL_INC_3463 3464 +#define Z_UTIL_INC_3464 3465 +#define Z_UTIL_INC_3465 3466 +#define Z_UTIL_INC_3466 3467 +#define Z_UTIL_INC_3467 3468 +#define Z_UTIL_INC_3468 3469 +#define Z_UTIL_INC_3469 3470 +#define Z_UTIL_INC_3470 3471 +#define Z_UTIL_INC_3471 3472 +#define Z_UTIL_INC_3472 3473 +#define Z_UTIL_INC_3473 3474 +#define Z_UTIL_INC_3474 3475 +#define Z_UTIL_INC_3475 3476 +#define Z_UTIL_INC_3476 3477 +#define Z_UTIL_INC_3477 3478 +#define Z_UTIL_INC_3478 3479 +#define Z_UTIL_INC_3479 3480 +#define Z_UTIL_INC_3480 3481 +#define Z_UTIL_INC_3481 3482 +#define Z_UTIL_INC_3482 3483 +#define Z_UTIL_INC_3483 3484 +#define Z_UTIL_INC_3484 3485 +#define Z_UTIL_INC_3485 3486 +#define Z_UTIL_INC_3486 3487 +#define Z_UTIL_INC_3487 3488 +#define Z_UTIL_INC_3488 3489 +#define Z_UTIL_INC_3489 3490 +#define Z_UTIL_INC_3490 3491 +#define Z_UTIL_INC_3491 3492 +#define Z_UTIL_INC_3492 3493 +#define Z_UTIL_INC_3493 3494 +#define Z_UTIL_INC_3494 3495 +#define Z_UTIL_INC_3495 3496 +#define Z_UTIL_INC_3496 3497 +#define Z_UTIL_INC_3497 3498 +#define Z_UTIL_INC_3498 3499 +#define Z_UTIL_INC_3499 3500 +#define Z_UTIL_INC_3500 3501 +#define Z_UTIL_INC_3501 3502 +#define Z_UTIL_INC_3502 3503 +#define Z_UTIL_INC_3503 3504 +#define Z_UTIL_INC_3504 3505 +#define Z_UTIL_INC_3505 3506 +#define Z_UTIL_INC_3506 3507 +#define Z_UTIL_INC_3507 3508 +#define Z_UTIL_INC_3508 3509 +#define Z_UTIL_INC_3509 3510 +#define Z_UTIL_INC_3510 3511 +#define Z_UTIL_INC_3511 3512 +#define Z_UTIL_INC_3512 3513 +#define Z_UTIL_INC_3513 3514 +#define Z_UTIL_INC_3514 3515 +#define Z_UTIL_INC_3515 3516 +#define Z_UTIL_INC_3516 3517 +#define Z_UTIL_INC_3517 3518 +#define Z_UTIL_INC_3518 3519 +#define Z_UTIL_INC_3519 3520 +#define Z_UTIL_INC_3520 3521 +#define Z_UTIL_INC_3521 3522 +#define Z_UTIL_INC_3522 3523 +#define Z_UTIL_INC_3523 3524 +#define Z_UTIL_INC_3524 3525 +#define Z_UTIL_INC_3525 3526 +#define Z_UTIL_INC_3526 3527 +#define Z_UTIL_INC_3527 3528 +#define Z_UTIL_INC_3528 3529 +#define Z_UTIL_INC_3529 3530 +#define Z_UTIL_INC_3530 3531 +#define Z_UTIL_INC_3531 3532 +#define Z_UTIL_INC_3532 3533 +#define Z_UTIL_INC_3533 3534 +#define Z_UTIL_INC_3534 3535 +#define Z_UTIL_INC_3535 3536 +#define Z_UTIL_INC_3536 3537 +#define Z_UTIL_INC_3537 3538 +#define Z_UTIL_INC_3538 3539 +#define Z_UTIL_INC_3539 3540 +#define Z_UTIL_INC_3540 3541 +#define Z_UTIL_INC_3541 3542 +#define Z_UTIL_INC_3542 3543 +#define Z_UTIL_INC_3543 3544 +#define Z_UTIL_INC_3544 3545 +#define Z_UTIL_INC_3545 3546 +#define Z_UTIL_INC_3546 3547 +#define Z_UTIL_INC_3547 3548 +#define Z_UTIL_INC_3548 3549 +#define Z_UTIL_INC_3549 3550 +#define Z_UTIL_INC_3550 3551 +#define Z_UTIL_INC_3551 3552 +#define Z_UTIL_INC_3552 3553 +#define Z_UTIL_INC_3553 3554 +#define Z_UTIL_INC_3554 3555 +#define Z_UTIL_INC_3555 3556 +#define Z_UTIL_INC_3556 3557 +#define Z_UTIL_INC_3557 3558 +#define Z_UTIL_INC_3558 3559 +#define Z_UTIL_INC_3559 3560 +#define Z_UTIL_INC_3560 3561 +#define Z_UTIL_INC_3561 3562 +#define Z_UTIL_INC_3562 3563 +#define Z_UTIL_INC_3563 3564 +#define Z_UTIL_INC_3564 3565 +#define Z_UTIL_INC_3565 3566 +#define Z_UTIL_INC_3566 3567 +#define Z_UTIL_INC_3567 3568 +#define Z_UTIL_INC_3568 3569 +#define Z_UTIL_INC_3569 3570 +#define Z_UTIL_INC_3570 3571 +#define Z_UTIL_INC_3571 3572 +#define Z_UTIL_INC_3572 3573 +#define Z_UTIL_INC_3573 3574 +#define Z_UTIL_INC_3574 3575 +#define Z_UTIL_INC_3575 3576 +#define Z_UTIL_INC_3576 3577 +#define Z_UTIL_INC_3577 3578 +#define Z_UTIL_INC_3578 3579 +#define Z_UTIL_INC_3579 3580 +#define Z_UTIL_INC_3580 3581 +#define Z_UTIL_INC_3581 3582 +#define Z_UTIL_INC_3582 3583 +#define Z_UTIL_INC_3583 3584 +#define Z_UTIL_INC_3584 3585 +#define Z_UTIL_INC_3585 3586 +#define Z_UTIL_INC_3586 3587 +#define Z_UTIL_INC_3587 3588 +#define Z_UTIL_INC_3588 3589 +#define Z_UTIL_INC_3589 3590 +#define Z_UTIL_INC_3590 3591 +#define Z_UTIL_INC_3591 3592 +#define Z_UTIL_INC_3592 3593 +#define Z_UTIL_INC_3593 3594 +#define Z_UTIL_INC_3594 3595 +#define Z_UTIL_INC_3595 3596 +#define Z_UTIL_INC_3596 3597 +#define Z_UTIL_INC_3597 3598 +#define Z_UTIL_INC_3598 3599 +#define Z_UTIL_INC_3599 3600 +#define Z_UTIL_INC_3600 3601 +#define Z_UTIL_INC_3601 3602 +#define Z_UTIL_INC_3602 3603 +#define Z_UTIL_INC_3603 3604 +#define Z_UTIL_INC_3604 3605 +#define Z_UTIL_INC_3605 3606 +#define Z_UTIL_INC_3606 3607 +#define Z_UTIL_INC_3607 3608 +#define Z_UTIL_INC_3608 3609 +#define Z_UTIL_INC_3609 3610 +#define Z_UTIL_INC_3610 3611 +#define Z_UTIL_INC_3611 3612 +#define Z_UTIL_INC_3612 3613 +#define Z_UTIL_INC_3613 3614 +#define Z_UTIL_INC_3614 3615 +#define Z_UTIL_INC_3615 3616 +#define Z_UTIL_INC_3616 3617 +#define Z_UTIL_INC_3617 3618 +#define Z_UTIL_INC_3618 3619 +#define Z_UTIL_INC_3619 3620 +#define Z_UTIL_INC_3620 3621 +#define Z_UTIL_INC_3621 3622 +#define Z_UTIL_INC_3622 3623 +#define Z_UTIL_INC_3623 3624 +#define Z_UTIL_INC_3624 3625 +#define Z_UTIL_INC_3625 3626 +#define Z_UTIL_INC_3626 3627 +#define Z_UTIL_INC_3627 3628 +#define Z_UTIL_INC_3628 3629 +#define Z_UTIL_INC_3629 3630 +#define Z_UTIL_INC_3630 3631 +#define Z_UTIL_INC_3631 3632 +#define Z_UTIL_INC_3632 3633 +#define Z_UTIL_INC_3633 3634 +#define Z_UTIL_INC_3634 3635 +#define Z_UTIL_INC_3635 3636 +#define Z_UTIL_INC_3636 3637 +#define Z_UTIL_INC_3637 3638 +#define Z_UTIL_INC_3638 3639 +#define Z_UTIL_INC_3639 3640 +#define Z_UTIL_INC_3640 3641 +#define Z_UTIL_INC_3641 3642 +#define Z_UTIL_INC_3642 3643 +#define Z_UTIL_INC_3643 3644 +#define Z_UTIL_INC_3644 3645 +#define Z_UTIL_INC_3645 3646 +#define Z_UTIL_INC_3646 3647 +#define Z_UTIL_INC_3647 3648 +#define Z_UTIL_INC_3648 3649 +#define Z_UTIL_INC_3649 3650 +#define Z_UTIL_INC_3650 3651 +#define Z_UTIL_INC_3651 3652 +#define Z_UTIL_INC_3652 3653 +#define Z_UTIL_INC_3653 3654 +#define Z_UTIL_INC_3654 3655 +#define Z_UTIL_INC_3655 3656 +#define Z_UTIL_INC_3656 3657 +#define Z_UTIL_INC_3657 3658 +#define Z_UTIL_INC_3658 3659 +#define Z_UTIL_INC_3659 3660 +#define Z_UTIL_INC_3660 3661 +#define Z_UTIL_INC_3661 3662 +#define Z_UTIL_INC_3662 3663 +#define Z_UTIL_INC_3663 3664 +#define Z_UTIL_INC_3664 3665 +#define Z_UTIL_INC_3665 3666 +#define Z_UTIL_INC_3666 3667 +#define Z_UTIL_INC_3667 3668 +#define Z_UTIL_INC_3668 3669 +#define Z_UTIL_INC_3669 3670 +#define Z_UTIL_INC_3670 3671 +#define Z_UTIL_INC_3671 3672 +#define Z_UTIL_INC_3672 3673 +#define Z_UTIL_INC_3673 3674 +#define Z_UTIL_INC_3674 3675 +#define Z_UTIL_INC_3675 3676 +#define Z_UTIL_INC_3676 3677 +#define Z_UTIL_INC_3677 3678 +#define Z_UTIL_INC_3678 3679 +#define Z_UTIL_INC_3679 3680 +#define Z_UTIL_INC_3680 3681 +#define Z_UTIL_INC_3681 3682 +#define Z_UTIL_INC_3682 3683 +#define Z_UTIL_INC_3683 3684 +#define Z_UTIL_INC_3684 3685 +#define Z_UTIL_INC_3685 3686 +#define Z_UTIL_INC_3686 3687 +#define Z_UTIL_INC_3687 3688 +#define Z_UTIL_INC_3688 3689 +#define Z_UTIL_INC_3689 3690 +#define Z_UTIL_INC_3690 3691 +#define Z_UTIL_INC_3691 3692 +#define Z_UTIL_INC_3692 3693 +#define Z_UTIL_INC_3693 3694 +#define Z_UTIL_INC_3694 3695 +#define Z_UTIL_INC_3695 3696 +#define Z_UTIL_INC_3696 3697 +#define Z_UTIL_INC_3697 3698 +#define Z_UTIL_INC_3698 3699 +#define Z_UTIL_INC_3699 3700 +#define Z_UTIL_INC_3700 3701 +#define Z_UTIL_INC_3701 3702 +#define Z_UTIL_INC_3702 3703 +#define Z_UTIL_INC_3703 3704 +#define Z_UTIL_INC_3704 3705 +#define Z_UTIL_INC_3705 3706 +#define Z_UTIL_INC_3706 3707 +#define Z_UTIL_INC_3707 3708 +#define Z_UTIL_INC_3708 3709 +#define Z_UTIL_INC_3709 3710 +#define Z_UTIL_INC_3710 3711 +#define Z_UTIL_INC_3711 3712 +#define Z_UTIL_INC_3712 3713 +#define Z_UTIL_INC_3713 3714 +#define Z_UTIL_INC_3714 3715 +#define Z_UTIL_INC_3715 3716 +#define Z_UTIL_INC_3716 3717 +#define Z_UTIL_INC_3717 3718 +#define Z_UTIL_INC_3718 3719 +#define Z_UTIL_INC_3719 3720 +#define Z_UTIL_INC_3720 3721 +#define Z_UTIL_INC_3721 3722 +#define Z_UTIL_INC_3722 3723 +#define Z_UTIL_INC_3723 3724 +#define Z_UTIL_INC_3724 3725 +#define Z_UTIL_INC_3725 3726 +#define Z_UTIL_INC_3726 3727 +#define Z_UTIL_INC_3727 3728 +#define Z_UTIL_INC_3728 3729 +#define Z_UTIL_INC_3729 3730 +#define Z_UTIL_INC_3730 3731 +#define Z_UTIL_INC_3731 3732 +#define Z_UTIL_INC_3732 3733 +#define Z_UTIL_INC_3733 3734 +#define Z_UTIL_INC_3734 3735 +#define Z_UTIL_INC_3735 3736 +#define Z_UTIL_INC_3736 3737 +#define Z_UTIL_INC_3737 3738 +#define Z_UTIL_INC_3738 3739 +#define Z_UTIL_INC_3739 3740 +#define Z_UTIL_INC_3740 3741 +#define Z_UTIL_INC_3741 3742 +#define Z_UTIL_INC_3742 3743 +#define Z_UTIL_INC_3743 3744 +#define Z_UTIL_INC_3744 3745 +#define Z_UTIL_INC_3745 3746 +#define Z_UTIL_INC_3746 3747 +#define Z_UTIL_INC_3747 3748 +#define Z_UTIL_INC_3748 3749 +#define Z_UTIL_INC_3749 3750 +#define Z_UTIL_INC_3750 3751 +#define Z_UTIL_INC_3751 3752 +#define Z_UTIL_INC_3752 3753 +#define Z_UTIL_INC_3753 3754 +#define Z_UTIL_INC_3754 3755 +#define Z_UTIL_INC_3755 3756 +#define Z_UTIL_INC_3756 3757 +#define Z_UTIL_INC_3757 3758 +#define Z_UTIL_INC_3758 3759 +#define Z_UTIL_INC_3759 3760 +#define Z_UTIL_INC_3760 3761 +#define Z_UTIL_INC_3761 3762 +#define Z_UTIL_INC_3762 3763 +#define Z_UTIL_INC_3763 3764 +#define Z_UTIL_INC_3764 3765 +#define Z_UTIL_INC_3765 3766 +#define Z_UTIL_INC_3766 3767 +#define Z_UTIL_INC_3767 3768 +#define Z_UTIL_INC_3768 3769 +#define Z_UTIL_INC_3769 3770 +#define Z_UTIL_INC_3770 3771 +#define Z_UTIL_INC_3771 3772 +#define Z_UTIL_INC_3772 3773 +#define Z_UTIL_INC_3773 3774 +#define Z_UTIL_INC_3774 3775 +#define Z_UTIL_INC_3775 3776 +#define Z_UTIL_INC_3776 3777 +#define Z_UTIL_INC_3777 3778 +#define Z_UTIL_INC_3778 3779 +#define Z_UTIL_INC_3779 3780 +#define Z_UTIL_INC_3780 3781 +#define Z_UTIL_INC_3781 3782 +#define Z_UTIL_INC_3782 3783 +#define Z_UTIL_INC_3783 3784 +#define Z_UTIL_INC_3784 3785 +#define Z_UTIL_INC_3785 3786 +#define Z_UTIL_INC_3786 3787 +#define Z_UTIL_INC_3787 3788 +#define Z_UTIL_INC_3788 3789 +#define Z_UTIL_INC_3789 3790 +#define Z_UTIL_INC_3790 3791 +#define Z_UTIL_INC_3791 3792 +#define Z_UTIL_INC_3792 3793 +#define Z_UTIL_INC_3793 3794 +#define Z_UTIL_INC_3794 3795 +#define Z_UTIL_INC_3795 3796 +#define Z_UTIL_INC_3796 3797 +#define Z_UTIL_INC_3797 3798 +#define Z_UTIL_INC_3798 3799 +#define Z_UTIL_INC_3799 3800 +#define Z_UTIL_INC_3800 3801 +#define Z_UTIL_INC_3801 3802 +#define Z_UTIL_INC_3802 3803 +#define Z_UTIL_INC_3803 3804 +#define Z_UTIL_INC_3804 3805 +#define Z_UTIL_INC_3805 3806 +#define Z_UTIL_INC_3806 3807 +#define Z_UTIL_INC_3807 3808 +#define Z_UTIL_INC_3808 3809 +#define Z_UTIL_INC_3809 3810 +#define Z_UTIL_INC_3810 3811 +#define Z_UTIL_INC_3811 3812 +#define Z_UTIL_INC_3812 3813 +#define Z_UTIL_INC_3813 3814 +#define Z_UTIL_INC_3814 3815 +#define Z_UTIL_INC_3815 3816 +#define Z_UTIL_INC_3816 3817 +#define Z_UTIL_INC_3817 3818 +#define Z_UTIL_INC_3818 3819 +#define Z_UTIL_INC_3819 3820 +#define Z_UTIL_INC_3820 3821 +#define Z_UTIL_INC_3821 3822 +#define Z_UTIL_INC_3822 3823 +#define Z_UTIL_INC_3823 3824 +#define Z_UTIL_INC_3824 3825 +#define Z_UTIL_INC_3825 3826 +#define Z_UTIL_INC_3826 3827 +#define Z_UTIL_INC_3827 3828 +#define Z_UTIL_INC_3828 3829 +#define Z_UTIL_INC_3829 3830 +#define Z_UTIL_INC_3830 3831 +#define Z_UTIL_INC_3831 3832 +#define Z_UTIL_INC_3832 3833 +#define Z_UTIL_INC_3833 3834 +#define Z_UTIL_INC_3834 3835 +#define Z_UTIL_INC_3835 3836 +#define Z_UTIL_INC_3836 3837 +#define Z_UTIL_INC_3837 3838 +#define Z_UTIL_INC_3838 3839 +#define Z_UTIL_INC_3839 3840 +#define Z_UTIL_INC_3840 3841 +#define Z_UTIL_INC_3841 3842 +#define Z_UTIL_INC_3842 3843 +#define Z_UTIL_INC_3843 3844 +#define Z_UTIL_INC_3844 3845 +#define Z_UTIL_INC_3845 3846 +#define Z_UTIL_INC_3846 3847 +#define Z_UTIL_INC_3847 3848 +#define Z_UTIL_INC_3848 3849 +#define Z_UTIL_INC_3849 3850 +#define Z_UTIL_INC_3850 3851 +#define Z_UTIL_INC_3851 3852 +#define Z_UTIL_INC_3852 3853 +#define Z_UTIL_INC_3853 3854 +#define Z_UTIL_INC_3854 3855 +#define Z_UTIL_INC_3855 3856 +#define Z_UTIL_INC_3856 3857 +#define Z_UTIL_INC_3857 3858 +#define Z_UTIL_INC_3858 3859 +#define Z_UTIL_INC_3859 3860 +#define Z_UTIL_INC_3860 3861 +#define Z_UTIL_INC_3861 3862 +#define Z_UTIL_INC_3862 3863 +#define Z_UTIL_INC_3863 3864 +#define Z_UTIL_INC_3864 3865 +#define Z_UTIL_INC_3865 3866 +#define Z_UTIL_INC_3866 3867 +#define Z_UTIL_INC_3867 3868 +#define Z_UTIL_INC_3868 3869 +#define Z_UTIL_INC_3869 3870 +#define Z_UTIL_INC_3870 3871 +#define Z_UTIL_INC_3871 3872 +#define Z_UTIL_INC_3872 3873 +#define Z_UTIL_INC_3873 3874 +#define Z_UTIL_INC_3874 3875 +#define Z_UTIL_INC_3875 3876 +#define Z_UTIL_INC_3876 3877 +#define Z_UTIL_INC_3877 3878 +#define Z_UTIL_INC_3878 3879 +#define Z_UTIL_INC_3879 3880 +#define Z_UTIL_INC_3880 3881 +#define Z_UTIL_INC_3881 3882 +#define Z_UTIL_INC_3882 3883 +#define Z_UTIL_INC_3883 3884 +#define Z_UTIL_INC_3884 3885 +#define Z_UTIL_INC_3885 3886 +#define Z_UTIL_INC_3886 3887 +#define Z_UTIL_INC_3887 3888 +#define Z_UTIL_INC_3888 3889 +#define Z_UTIL_INC_3889 3890 +#define Z_UTIL_INC_3890 3891 +#define Z_UTIL_INC_3891 3892 +#define Z_UTIL_INC_3892 3893 +#define Z_UTIL_INC_3893 3894 +#define Z_UTIL_INC_3894 3895 +#define Z_UTIL_INC_3895 3896 +#define Z_UTIL_INC_3896 3897 +#define Z_UTIL_INC_3897 3898 +#define Z_UTIL_INC_3898 3899 +#define Z_UTIL_INC_3899 3900 +#define Z_UTIL_INC_3900 3901 +#define Z_UTIL_INC_3901 3902 +#define Z_UTIL_INC_3902 3903 +#define Z_UTIL_INC_3903 3904 +#define Z_UTIL_INC_3904 3905 +#define Z_UTIL_INC_3905 3906 +#define Z_UTIL_INC_3906 3907 +#define Z_UTIL_INC_3907 3908 +#define Z_UTIL_INC_3908 3909 +#define Z_UTIL_INC_3909 3910 +#define Z_UTIL_INC_3910 3911 +#define Z_UTIL_INC_3911 3912 +#define Z_UTIL_INC_3912 3913 +#define Z_UTIL_INC_3913 3914 +#define Z_UTIL_INC_3914 3915 +#define Z_UTIL_INC_3915 3916 +#define Z_UTIL_INC_3916 3917 +#define Z_UTIL_INC_3917 3918 +#define Z_UTIL_INC_3918 3919 +#define Z_UTIL_INC_3919 3920 +#define Z_UTIL_INC_3920 3921 +#define Z_UTIL_INC_3921 3922 +#define Z_UTIL_INC_3922 3923 +#define Z_UTIL_INC_3923 3924 +#define Z_UTIL_INC_3924 3925 +#define Z_UTIL_INC_3925 3926 +#define Z_UTIL_INC_3926 3927 +#define Z_UTIL_INC_3927 3928 +#define Z_UTIL_INC_3928 3929 +#define Z_UTIL_INC_3929 3930 +#define Z_UTIL_INC_3930 3931 +#define Z_UTIL_INC_3931 3932 +#define Z_UTIL_INC_3932 3933 +#define Z_UTIL_INC_3933 3934 +#define Z_UTIL_INC_3934 3935 +#define Z_UTIL_INC_3935 3936 +#define Z_UTIL_INC_3936 3937 +#define Z_UTIL_INC_3937 3938 +#define Z_UTIL_INC_3938 3939 +#define Z_UTIL_INC_3939 3940 +#define Z_UTIL_INC_3940 3941 +#define Z_UTIL_INC_3941 3942 +#define Z_UTIL_INC_3942 3943 +#define Z_UTIL_INC_3943 3944 +#define Z_UTIL_INC_3944 3945 +#define Z_UTIL_INC_3945 3946 +#define Z_UTIL_INC_3946 3947 +#define Z_UTIL_INC_3947 3948 +#define Z_UTIL_INC_3948 3949 +#define Z_UTIL_INC_3949 3950 +#define Z_UTIL_INC_3950 3951 +#define Z_UTIL_INC_3951 3952 +#define Z_UTIL_INC_3952 3953 +#define Z_UTIL_INC_3953 3954 +#define Z_UTIL_INC_3954 3955 +#define Z_UTIL_INC_3955 3956 +#define Z_UTIL_INC_3956 3957 +#define Z_UTIL_INC_3957 3958 +#define Z_UTIL_INC_3958 3959 +#define Z_UTIL_INC_3959 3960 +#define Z_UTIL_INC_3960 3961 +#define Z_UTIL_INC_3961 3962 +#define Z_UTIL_INC_3962 3963 +#define Z_UTIL_INC_3963 3964 +#define Z_UTIL_INC_3964 3965 +#define Z_UTIL_INC_3965 3966 +#define Z_UTIL_INC_3966 3967 +#define Z_UTIL_INC_3967 3968 +#define Z_UTIL_INC_3968 3969 +#define Z_UTIL_INC_3969 3970 +#define Z_UTIL_INC_3970 3971 +#define Z_UTIL_INC_3971 3972 +#define Z_UTIL_INC_3972 3973 +#define Z_UTIL_INC_3973 3974 +#define Z_UTIL_INC_3974 3975 +#define Z_UTIL_INC_3975 3976 +#define Z_UTIL_INC_3976 3977 +#define Z_UTIL_INC_3977 3978 +#define Z_UTIL_INC_3978 3979 +#define Z_UTIL_INC_3979 3980 +#define Z_UTIL_INC_3980 3981 +#define Z_UTIL_INC_3981 3982 +#define Z_UTIL_INC_3982 3983 +#define Z_UTIL_INC_3983 3984 +#define Z_UTIL_INC_3984 3985 +#define Z_UTIL_INC_3985 3986 +#define Z_UTIL_INC_3986 3987 +#define Z_UTIL_INC_3987 3988 +#define Z_UTIL_INC_3988 3989 +#define Z_UTIL_INC_3989 3990 +#define Z_UTIL_INC_3990 3991 +#define Z_UTIL_INC_3991 3992 +#define Z_UTIL_INC_3992 3993 +#define Z_UTIL_INC_3993 3994 +#define Z_UTIL_INC_3994 3995 +#define Z_UTIL_INC_3995 3996 +#define Z_UTIL_INC_3996 3997 +#define Z_UTIL_INC_3997 3998 +#define Z_UTIL_INC_3998 3999 +#define Z_UTIL_INC_3999 4000 +#define Z_UTIL_INC_4000 4001 +#define Z_UTIL_INC_4001 4002 +#define Z_UTIL_INC_4002 4003 +#define Z_UTIL_INC_4003 4004 +#define Z_UTIL_INC_4004 4005 +#define Z_UTIL_INC_4005 4006 +#define Z_UTIL_INC_4006 4007 +#define Z_UTIL_INC_4007 4008 +#define Z_UTIL_INC_4008 4009 +#define Z_UTIL_INC_4009 4010 +#define Z_UTIL_INC_4010 4011 +#define Z_UTIL_INC_4011 4012 +#define Z_UTIL_INC_4012 4013 +#define Z_UTIL_INC_4013 4014 +#define Z_UTIL_INC_4014 4015 +#define Z_UTIL_INC_4015 4016 +#define Z_UTIL_INC_4016 4017 +#define Z_UTIL_INC_4017 4018 +#define Z_UTIL_INC_4018 4019 +#define Z_UTIL_INC_4019 4020 +#define Z_UTIL_INC_4020 4021 +#define Z_UTIL_INC_4021 4022 +#define Z_UTIL_INC_4022 4023 +#define Z_UTIL_INC_4023 4024 +#define Z_UTIL_INC_4024 4025 +#define Z_UTIL_INC_4025 4026 +#define Z_UTIL_INC_4026 4027 +#define Z_UTIL_INC_4027 4028 +#define Z_UTIL_INC_4028 4029 +#define Z_UTIL_INC_4029 4030 +#define Z_UTIL_INC_4030 4031 +#define Z_UTIL_INC_4031 4032 +#define Z_UTIL_INC_4032 4033 +#define Z_UTIL_INC_4033 4034 +#define Z_UTIL_INC_4034 4035 +#define Z_UTIL_INC_4035 4036 +#define Z_UTIL_INC_4036 4037 +#define Z_UTIL_INC_4037 4038 +#define Z_UTIL_INC_4038 4039 +#define Z_UTIL_INC_4039 4040 +#define Z_UTIL_INC_4040 4041 +#define Z_UTIL_INC_4041 4042 +#define Z_UTIL_INC_4042 4043 +#define Z_UTIL_INC_4043 4044 +#define Z_UTIL_INC_4044 4045 +#define Z_UTIL_INC_4045 4046 +#define Z_UTIL_INC_4046 4047 +#define Z_UTIL_INC_4047 4048 +#define Z_UTIL_INC_4048 4049 +#define Z_UTIL_INC_4049 4050 +#define Z_UTIL_INC_4050 4051 +#define Z_UTIL_INC_4051 4052 +#define Z_UTIL_INC_4052 4053 +#define Z_UTIL_INC_4053 4054 +#define Z_UTIL_INC_4054 4055 +#define Z_UTIL_INC_4055 4056 +#define Z_UTIL_INC_4056 4057 +#define Z_UTIL_INC_4057 4058 +#define Z_UTIL_INC_4058 4059 +#define Z_UTIL_INC_4059 4060 +#define Z_UTIL_INC_4060 4061 +#define Z_UTIL_INC_4061 4062 +#define Z_UTIL_INC_4062 4063 +#define Z_UTIL_INC_4063 4064 +#define Z_UTIL_INC_4064 4065 +#define Z_UTIL_INC_4065 4066 +#define Z_UTIL_INC_4066 4067 +#define Z_UTIL_INC_4067 4068 +#define Z_UTIL_INC_4068 4069 +#define Z_UTIL_INC_4069 4070 +#define Z_UTIL_INC_4070 4071 +#define Z_UTIL_INC_4071 4072 +#define Z_UTIL_INC_4072 4073 +#define Z_UTIL_INC_4073 4074 +#define Z_UTIL_INC_4074 4075 +#define Z_UTIL_INC_4075 4076 +#define Z_UTIL_INC_4076 4077 +#define Z_UTIL_INC_4077 4078 +#define Z_UTIL_INC_4078 4079 +#define Z_UTIL_INC_4079 4080 +#define Z_UTIL_INC_4080 4081 +#define Z_UTIL_INC_4081 4082 +#define Z_UTIL_INC_4082 4083 +#define Z_UTIL_INC_4083 4084 +#define Z_UTIL_INC_4084 4085 +#define Z_UTIL_INC_4085 4086 +#define Z_UTIL_INC_4086 4087 +#define Z_UTIL_INC_4087 4088 +#define Z_UTIL_INC_4088 4089 +#define Z_UTIL_INC_4089 4090 +#define Z_UTIL_INC_4090 4091 +#define Z_UTIL_INC_4091 4092 +#define Z_UTIL_INC_4092 4093 +#define Z_UTIL_INC_4093 4094 +#define Z_UTIL_INC_4094 4095 +#define Z_UTIL_INC_4095 4096 +#define Z_UTIL_INC_4096 4097 + +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_ */ + +/** + * INTERNAL_HIDDEN @endcond + */ diff --git a/include/zephyr/sys/util_internal_util_x2.h b/include/zephyr/sys/util_internal_util_x2.h new file mode 100644 index 00000000000..f2452822cf8 --- /dev/null +++ b/include/zephyr/sys/util_internal_util_x2.h @@ -0,0 +1,4121 @@ +/* + * Copyright (c) 2011-2014, Wind River Systems, Inc. + * Copyright (c) 2020, Nordic Semiconductor ASA + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @cond INTERNAL_HIDDEN + */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ +#error "This header should not be used directly, please include util_internal.h instead" +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_ +#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_ + +#define Z_UTIL_X2_0 0 +#define Z_UTIL_X2_1 2 +#define Z_UTIL_X2_2 4 +#define Z_UTIL_X2_3 6 +#define Z_UTIL_X2_4 8 +#define Z_UTIL_X2_5 10 +#define Z_UTIL_X2_6 12 +#define Z_UTIL_X2_7 14 +#define Z_UTIL_X2_8 16 +#define Z_UTIL_X2_9 18 +#define Z_UTIL_X2_10 20 +#define Z_UTIL_X2_11 22 +#define Z_UTIL_X2_12 24 +#define Z_UTIL_X2_13 26 +#define Z_UTIL_X2_14 28 +#define Z_UTIL_X2_15 30 +#define Z_UTIL_X2_16 32 +#define Z_UTIL_X2_17 34 +#define Z_UTIL_X2_18 36 +#define Z_UTIL_X2_19 38 +#define Z_UTIL_X2_20 40 +#define Z_UTIL_X2_21 42 +#define Z_UTIL_X2_22 44 +#define Z_UTIL_X2_23 46 +#define Z_UTIL_X2_24 48 +#define Z_UTIL_X2_25 50 +#define Z_UTIL_X2_26 52 +#define Z_UTIL_X2_27 54 +#define Z_UTIL_X2_28 56 +#define Z_UTIL_X2_29 58 +#define Z_UTIL_X2_30 60 +#define Z_UTIL_X2_31 62 +#define Z_UTIL_X2_32 64 +#define Z_UTIL_X2_33 66 +#define Z_UTIL_X2_34 68 +#define Z_UTIL_X2_35 70 +#define Z_UTIL_X2_36 72 +#define Z_UTIL_X2_37 74 +#define Z_UTIL_X2_38 76 +#define Z_UTIL_X2_39 78 +#define Z_UTIL_X2_40 80 +#define Z_UTIL_X2_41 82 +#define Z_UTIL_X2_42 84 +#define Z_UTIL_X2_43 86 +#define Z_UTIL_X2_44 88 +#define Z_UTIL_X2_45 90 +#define Z_UTIL_X2_46 92 +#define Z_UTIL_X2_47 94 +#define Z_UTIL_X2_48 96 +#define Z_UTIL_X2_49 98 +#define Z_UTIL_X2_50 100 +#define Z_UTIL_X2_51 102 +#define Z_UTIL_X2_52 104 +#define Z_UTIL_X2_53 106 +#define Z_UTIL_X2_54 108 +#define Z_UTIL_X2_55 110 +#define Z_UTIL_X2_56 112 +#define Z_UTIL_X2_57 114 +#define Z_UTIL_X2_58 116 +#define Z_UTIL_X2_59 118 +#define Z_UTIL_X2_60 120 +#define Z_UTIL_X2_61 122 +#define Z_UTIL_X2_62 124 +#define Z_UTIL_X2_63 126 +#define Z_UTIL_X2_64 128 +#define Z_UTIL_X2_65 130 +#define Z_UTIL_X2_66 132 +#define Z_UTIL_X2_67 134 +#define Z_UTIL_X2_68 136 +#define Z_UTIL_X2_69 138 +#define Z_UTIL_X2_70 140 +#define Z_UTIL_X2_71 142 +#define Z_UTIL_X2_72 144 +#define Z_UTIL_X2_73 146 +#define Z_UTIL_X2_74 148 +#define Z_UTIL_X2_75 150 +#define Z_UTIL_X2_76 152 +#define Z_UTIL_X2_77 154 +#define Z_UTIL_X2_78 156 +#define Z_UTIL_X2_79 158 +#define Z_UTIL_X2_80 160 +#define Z_UTIL_X2_81 162 +#define Z_UTIL_X2_82 164 +#define Z_UTIL_X2_83 166 +#define Z_UTIL_X2_84 168 +#define Z_UTIL_X2_85 170 +#define Z_UTIL_X2_86 172 +#define Z_UTIL_X2_87 174 +#define Z_UTIL_X2_88 176 +#define Z_UTIL_X2_89 178 +#define Z_UTIL_X2_90 180 +#define Z_UTIL_X2_91 182 +#define Z_UTIL_X2_92 184 +#define Z_UTIL_X2_93 186 +#define Z_UTIL_X2_94 188 +#define Z_UTIL_X2_95 190 +#define Z_UTIL_X2_96 192 +#define Z_UTIL_X2_97 194 +#define Z_UTIL_X2_98 196 +#define Z_UTIL_X2_99 198 +#define Z_UTIL_X2_100 200 +#define Z_UTIL_X2_101 202 +#define Z_UTIL_X2_102 204 +#define Z_UTIL_X2_103 206 +#define Z_UTIL_X2_104 208 +#define Z_UTIL_X2_105 210 +#define Z_UTIL_X2_106 212 +#define Z_UTIL_X2_107 214 +#define Z_UTIL_X2_108 216 +#define Z_UTIL_X2_109 218 +#define Z_UTIL_X2_110 220 +#define Z_UTIL_X2_111 222 +#define Z_UTIL_X2_112 224 +#define Z_UTIL_X2_113 226 +#define Z_UTIL_X2_114 228 +#define Z_UTIL_X2_115 230 +#define Z_UTIL_X2_116 232 +#define Z_UTIL_X2_117 234 +#define Z_UTIL_X2_118 236 +#define Z_UTIL_X2_119 238 +#define Z_UTIL_X2_120 240 +#define Z_UTIL_X2_121 242 +#define Z_UTIL_X2_122 244 +#define Z_UTIL_X2_123 246 +#define Z_UTIL_X2_124 248 +#define Z_UTIL_X2_125 250 +#define Z_UTIL_X2_126 252 +#define Z_UTIL_X2_127 254 +#define Z_UTIL_X2_128 256 +#define Z_UTIL_X2_129 258 +#define Z_UTIL_X2_130 260 +#define Z_UTIL_X2_131 262 +#define Z_UTIL_X2_132 264 +#define Z_UTIL_X2_133 266 +#define Z_UTIL_X2_134 268 +#define Z_UTIL_X2_135 270 +#define Z_UTIL_X2_136 272 +#define Z_UTIL_X2_137 274 +#define Z_UTIL_X2_138 276 +#define Z_UTIL_X2_139 278 +#define Z_UTIL_X2_140 280 +#define Z_UTIL_X2_141 282 +#define Z_UTIL_X2_142 284 +#define Z_UTIL_X2_143 286 +#define Z_UTIL_X2_144 288 +#define Z_UTIL_X2_145 290 +#define Z_UTIL_X2_146 292 +#define Z_UTIL_X2_147 294 +#define Z_UTIL_X2_148 296 +#define Z_UTIL_X2_149 298 +#define Z_UTIL_X2_150 300 +#define Z_UTIL_X2_151 302 +#define Z_UTIL_X2_152 304 +#define Z_UTIL_X2_153 306 +#define Z_UTIL_X2_154 308 +#define Z_UTIL_X2_155 310 +#define Z_UTIL_X2_156 312 +#define Z_UTIL_X2_157 314 +#define Z_UTIL_X2_158 316 +#define Z_UTIL_X2_159 318 +#define Z_UTIL_X2_160 320 +#define Z_UTIL_X2_161 322 +#define Z_UTIL_X2_162 324 +#define Z_UTIL_X2_163 326 +#define Z_UTIL_X2_164 328 +#define Z_UTIL_X2_165 330 +#define Z_UTIL_X2_166 332 +#define Z_UTIL_X2_167 334 +#define Z_UTIL_X2_168 336 +#define Z_UTIL_X2_169 338 +#define Z_UTIL_X2_170 340 +#define Z_UTIL_X2_171 342 +#define Z_UTIL_X2_172 344 +#define Z_UTIL_X2_173 346 +#define Z_UTIL_X2_174 348 +#define Z_UTIL_X2_175 350 +#define Z_UTIL_X2_176 352 +#define Z_UTIL_X2_177 354 +#define Z_UTIL_X2_178 356 +#define Z_UTIL_X2_179 358 +#define Z_UTIL_X2_180 360 +#define Z_UTIL_X2_181 362 +#define Z_UTIL_X2_182 364 +#define Z_UTIL_X2_183 366 +#define Z_UTIL_X2_184 368 +#define Z_UTIL_X2_185 370 +#define Z_UTIL_X2_186 372 +#define Z_UTIL_X2_187 374 +#define Z_UTIL_X2_188 376 +#define Z_UTIL_X2_189 378 +#define Z_UTIL_X2_190 380 +#define Z_UTIL_X2_191 382 +#define Z_UTIL_X2_192 384 +#define Z_UTIL_X2_193 386 +#define Z_UTIL_X2_194 388 +#define Z_UTIL_X2_195 390 +#define Z_UTIL_X2_196 392 +#define Z_UTIL_X2_197 394 +#define Z_UTIL_X2_198 396 +#define Z_UTIL_X2_199 398 +#define Z_UTIL_X2_200 400 +#define Z_UTIL_X2_201 402 +#define Z_UTIL_X2_202 404 +#define Z_UTIL_X2_203 406 +#define Z_UTIL_X2_204 408 +#define Z_UTIL_X2_205 410 +#define Z_UTIL_X2_206 412 +#define Z_UTIL_X2_207 414 +#define Z_UTIL_X2_208 416 +#define Z_UTIL_X2_209 418 +#define Z_UTIL_X2_210 420 +#define Z_UTIL_X2_211 422 +#define Z_UTIL_X2_212 424 +#define Z_UTIL_X2_213 426 +#define Z_UTIL_X2_214 428 +#define Z_UTIL_X2_215 430 +#define Z_UTIL_X2_216 432 +#define Z_UTIL_X2_217 434 +#define Z_UTIL_X2_218 436 +#define Z_UTIL_X2_219 438 +#define Z_UTIL_X2_220 440 +#define Z_UTIL_X2_221 442 +#define Z_UTIL_X2_222 444 +#define Z_UTIL_X2_223 446 +#define Z_UTIL_X2_224 448 +#define Z_UTIL_X2_225 450 +#define Z_UTIL_X2_226 452 +#define Z_UTIL_X2_227 454 +#define Z_UTIL_X2_228 456 +#define Z_UTIL_X2_229 458 +#define Z_UTIL_X2_230 460 +#define Z_UTIL_X2_231 462 +#define Z_UTIL_X2_232 464 +#define Z_UTIL_X2_233 466 +#define Z_UTIL_X2_234 468 +#define Z_UTIL_X2_235 470 +#define Z_UTIL_X2_236 472 +#define Z_UTIL_X2_237 474 +#define Z_UTIL_X2_238 476 +#define Z_UTIL_X2_239 478 +#define Z_UTIL_X2_240 480 +#define Z_UTIL_X2_241 482 +#define Z_UTIL_X2_242 484 +#define Z_UTIL_X2_243 486 +#define Z_UTIL_X2_244 488 +#define Z_UTIL_X2_245 490 +#define Z_UTIL_X2_246 492 +#define Z_UTIL_X2_247 494 +#define Z_UTIL_X2_248 496 +#define Z_UTIL_X2_249 498 +#define Z_UTIL_X2_250 500 +#define Z_UTIL_X2_251 502 +#define Z_UTIL_X2_252 504 +#define Z_UTIL_X2_253 506 +#define Z_UTIL_X2_254 508 +#define Z_UTIL_X2_255 510 +#define Z_UTIL_X2_256 512 +#define Z_UTIL_X2_257 514 +#define Z_UTIL_X2_258 516 +#define Z_UTIL_X2_259 518 +#define Z_UTIL_X2_260 520 +#define Z_UTIL_X2_261 522 +#define Z_UTIL_X2_262 524 +#define Z_UTIL_X2_263 526 +#define Z_UTIL_X2_264 528 +#define Z_UTIL_X2_265 530 +#define Z_UTIL_X2_266 532 +#define Z_UTIL_X2_267 534 +#define Z_UTIL_X2_268 536 +#define Z_UTIL_X2_269 538 +#define Z_UTIL_X2_270 540 +#define Z_UTIL_X2_271 542 +#define Z_UTIL_X2_272 544 +#define Z_UTIL_X2_273 546 +#define Z_UTIL_X2_274 548 +#define Z_UTIL_X2_275 550 +#define Z_UTIL_X2_276 552 +#define Z_UTIL_X2_277 554 +#define Z_UTIL_X2_278 556 +#define Z_UTIL_X2_279 558 +#define Z_UTIL_X2_280 560 +#define Z_UTIL_X2_281 562 +#define Z_UTIL_X2_282 564 +#define Z_UTIL_X2_283 566 +#define Z_UTIL_X2_284 568 +#define Z_UTIL_X2_285 570 +#define Z_UTIL_X2_286 572 +#define Z_UTIL_X2_287 574 +#define Z_UTIL_X2_288 576 +#define Z_UTIL_X2_289 578 +#define Z_UTIL_X2_290 580 +#define Z_UTIL_X2_291 582 +#define Z_UTIL_X2_292 584 +#define Z_UTIL_X2_293 586 +#define Z_UTIL_X2_294 588 +#define Z_UTIL_X2_295 590 +#define Z_UTIL_X2_296 592 +#define Z_UTIL_X2_297 594 +#define Z_UTIL_X2_298 596 +#define Z_UTIL_X2_299 598 +#define Z_UTIL_X2_300 600 +#define Z_UTIL_X2_301 602 +#define Z_UTIL_X2_302 604 +#define Z_UTIL_X2_303 606 +#define Z_UTIL_X2_304 608 +#define Z_UTIL_X2_305 610 +#define Z_UTIL_X2_306 612 +#define Z_UTIL_X2_307 614 +#define Z_UTIL_X2_308 616 +#define Z_UTIL_X2_309 618 +#define Z_UTIL_X2_310 620 +#define Z_UTIL_X2_311 622 +#define Z_UTIL_X2_312 624 +#define Z_UTIL_X2_313 626 +#define Z_UTIL_X2_314 628 +#define Z_UTIL_X2_315 630 +#define Z_UTIL_X2_316 632 +#define Z_UTIL_X2_317 634 +#define Z_UTIL_X2_318 636 +#define Z_UTIL_X2_319 638 +#define Z_UTIL_X2_320 640 +#define Z_UTIL_X2_321 642 +#define Z_UTIL_X2_322 644 +#define Z_UTIL_X2_323 646 +#define Z_UTIL_X2_324 648 +#define Z_UTIL_X2_325 650 +#define Z_UTIL_X2_326 652 +#define Z_UTIL_X2_327 654 +#define Z_UTIL_X2_328 656 +#define Z_UTIL_X2_329 658 +#define Z_UTIL_X2_330 660 +#define Z_UTIL_X2_331 662 +#define Z_UTIL_X2_332 664 +#define Z_UTIL_X2_333 666 +#define Z_UTIL_X2_334 668 +#define Z_UTIL_X2_335 670 +#define Z_UTIL_X2_336 672 +#define Z_UTIL_X2_337 674 +#define Z_UTIL_X2_338 676 +#define Z_UTIL_X2_339 678 +#define Z_UTIL_X2_340 680 +#define Z_UTIL_X2_341 682 +#define Z_UTIL_X2_342 684 +#define Z_UTIL_X2_343 686 +#define Z_UTIL_X2_344 688 +#define Z_UTIL_X2_345 690 +#define Z_UTIL_X2_346 692 +#define Z_UTIL_X2_347 694 +#define Z_UTIL_X2_348 696 +#define Z_UTIL_X2_349 698 +#define Z_UTIL_X2_350 700 +#define Z_UTIL_X2_351 702 +#define Z_UTIL_X2_352 704 +#define Z_UTIL_X2_353 706 +#define Z_UTIL_X2_354 708 +#define Z_UTIL_X2_355 710 +#define Z_UTIL_X2_356 712 +#define Z_UTIL_X2_357 714 +#define Z_UTIL_X2_358 716 +#define Z_UTIL_X2_359 718 +#define Z_UTIL_X2_360 720 +#define Z_UTIL_X2_361 722 +#define Z_UTIL_X2_362 724 +#define Z_UTIL_X2_363 726 +#define Z_UTIL_X2_364 728 +#define Z_UTIL_X2_365 730 +#define Z_UTIL_X2_366 732 +#define Z_UTIL_X2_367 734 +#define Z_UTIL_X2_368 736 +#define Z_UTIL_X2_369 738 +#define Z_UTIL_X2_370 740 +#define Z_UTIL_X2_371 742 +#define Z_UTIL_X2_372 744 +#define Z_UTIL_X2_373 746 +#define Z_UTIL_X2_374 748 +#define Z_UTIL_X2_375 750 +#define Z_UTIL_X2_376 752 +#define Z_UTIL_X2_377 754 +#define Z_UTIL_X2_378 756 +#define Z_UTIL_X2_379 758 +#define Z_UTIL_X2_380 760 +#define Z_UTIL_X2_381 762 +#define Z_UTIL_X2_382 764 +#define Z_UTIL_X2_383 766 +#define Z_UTIL_X2_384 768 +#define Z_UTIL_X2_385 770 +#define Z_UTIL_X2_386 772 +#define Z_UTIL_X2_387 774 +#define Z_UTIL_X2_388 776 +#define Z_UTIL_X2_389 778 +#define Z_UTIL_X2_390 780 +#define Z_UTIL_X2_391 782 +#define Z_UTIL_X2_392 784 +#define Z_UTIL_X2_393 786 +#define Z_UTIL_X2_394 788 +#define Z_UTIL_X2_395 790 +#define Z_UTIL_X2_396 792 +#define Z_UTIL_X2_397 794 +#define Z_UTIL_X2_398 796 +#define Z_UTIL_X2_399 798 +#define Z_UTIL_X2_400 800 +#define Z_UTIL_X2_401 802 +#define Z_UTIL_X2_402 804 +#define Z_UTIL_X2_403 806 +#define Z_UTIL_X2_404 808 +#define Z_UTIL_X2_405 810 +#define Z_UTIL_X2_406 812 +#define Z_UTIL_X2_407 814 +#define Z_UTIL_X2_408 816 +#define Z_UTIL_X2_409 818 +#define Z_UTIL_X2_410 820 +#define Z_UTIL_X2_411 822 +#define Z_UTIL_X2_412 824 +#define Z_UTIL_X2_413 826 +#define Z_UTIL_X2_414 828 +#define Z_UTIL_X2_415 830 +#define Z_UTIL_X2_416 832 +#define Z_UTIL_X2_417 834 +#define Z_UTIL_X2_418 836 +#define Z_UTIL_X2_419 838 +#define Z_UTIL_X2_420 840 +#define Z_UTIL_X2_421 842 +#define Z_UTIL_X2_422 844 +#define Z_UTIL_X2_423 846 +#define Z_UTIL_X2_424 848 +#define Z_UTIL_X2_425 850 +#define Z_UTIL_X2_426 852 +#define Z_UTIL_X2_427 854 +#define Z_UTIL_X2_428 856 +#define Z_UTIL_X2_429 858 +#define Z_UTIL_X2_430 860 +#define Z_UTIL_X2_431 862 +#define Z_UTIL_X2_432 864 +#define Z_UTIL_X2_433 866 +#define Z_UTIL_X2_434 868 +#define Z_UTIL_X2_435 870 +#define Z_UTIL_X2_436 872 +#define Z_UTIL_X2_437 874 +#define Z_UTIL_X2_438 876 +#define Z_UTIL_X2_439 878 +#define Z_UTIL_X2_440 880 +#define Z_UTIL_X2_441 882 +#define Z_UTIL_X2_442 884 +#define Z_UTIL_X2_443 886 +#define Z_UTIL_X2_444 888 +#define Z_UTIL_X2_445 890 +#define Z_UTIL_X2_446 892 +#define Z_UTIL_X2_447 894 +#define Z_UTIL_X2_448 896 +#define Z_UTIL_X2_449 898 +#define Z_UTIL_X2_450 900 +#define Z_UTIL_X2_451 902 +#define Z_UTIL_X2_452 904 +#define Z_UTIL_X2_453 906 +#define Z_UTIL_X2_454 908 +#define Z_UTIL_X2_455 910 +#define Z_UTIL_X2_456 912 +#define Z_UTIL_X2_457 914 +#define Z_UTIL_X2_458 916 +#define Z_UTIL_X2_459 918 +#define Z_UTIL_X2_460 920 +#define Z_UTIL_X2_461 922 +#define Z_UTIL_X2_462 924 +#define Z_UTIL_X2_463 926 +#define Z_UTIL_X2_464 928 +#define Z_UTIL_X2_465 930 +#define Z_UTIL_X2_466 932 +#define Z_UTIL_X2_467 934 +#define Z_UTIL_X2_468 936 +#define Z_UTIL_X2_469 938 +#define Z_UTIL_X2_470 940 +#define Z_UTIL_X2_471 942 +#define Z_UTIL_X2_472 944 +#define Z_UTIL_X2_473 946 +#define Z_UTIL_X2_474 948 +#define Z_UTIL_X2_475 950 +#define Z_UTIL_X2_476 952 +#define Z_UTIL_X2_477 954 +#define Z_UTIL_X2_478 956 +#define Z_UTIL_X2_479 958 +#define Z_UTIL_X2_480 960 +#define Z_UTIL_X2_481 962 +#define Z_UTIL_X2_482 964 +#define Z_UTIL_X2_483 966 +#define Z_UTIL_X2_484 968 +#define Z_UTIL_X2_485 970 +#define Z_UTIL_X2_486 972 +#define Z_UTIL_X2_487 974 +#define Z_UTIL_X2_488 976 +#define Z_UTIL_X2_489 978 +#define Z_UTIL_X2_490 980 +#define Z_UTIL_X2_491 982 +#define Z_UTIL_X2_492 984 +#define Z_UTIL_X2_493 986 +#define Z_UTIL_X2_494 988 +#define Z_UTIL_X2_495 990 +#define Z_UTIL_X2_496 992 +#define Z_UTIL_X2_497 994 +#define Z_UTIL_X2_498 996 +#define Z_UTIL_X2_499 998 +#define Z_UTIL_X2_500 1000 +#define Z_UTIL_X2_501 1002 +#define Z_UTIL_X2_502 1004 +#define Z_UTIL_X2_503 1006 +#define Z_UTIL_X2_504 1008 +#define Z_UTIL_X2_505 1010 +#define Z_UTIL_X2_506 1012 +#define Z_UTIL_X2_507 1014 +#define Z_UTIL_X2_508 1016 +#define Z_UTIL_X2_509 1018 +#define Z_UTIL_X2_510 1020 +#define Z_UTIL_X2_511 1022 +#define Z_UTIL_X2_512 1024 +#define Z_UTIL_X2_513 1026 +#define Z_UTIL_X2_514 1028 +#define Z_UTIL_X2_515 1030 +#define Z_UTIL_X2_516 1032 +#define Z_UTIL_X2_517 1034 +#define Z_UTIL_X2_518 1036 +#define Z_UTIL_X2_519 1038 +#define Z_UTIL_X2_520 1040 +#define Z_UTIL_X2_521 1042 +#define Z_UTIL_X2_522 1044 +#define Z_UTIL_X2_523 1046 +#define Z_UTIL_X2_524 1048 +#define Z_UTIL_X2_525 1050 +#define Z_UTIL_X2_526 1052 +#define Z_UTIL_X2_527 1054 +#define Z_UTIL_X2_528 1056 +#define Z_UTIL_X2_529 1058 +#define Z_UTIL_X2_530 1060 +#define Z_UTIL_X2_531 1062 +#define Z_UTIL_X2_532 1064 +#define Z_UTIL_X2_533 1066 +#define Z_UTIL_X2_534 1068 +#define Z_UTIL_X2_535 1070 +#define Z_UTIL_X2_536 1072 +#define Z_UTIL_X2_537 1074 +#define Z_UTIL_X2_538 1076 +#define Z_UTIL_X2_539 1078 +#define Z_UTIL_X2_540 1080 +#define Z_UTIL_X2_541 1082 +#define Z_UTIL_X2_542 1084 +#define Z_UTIL_X2_543 1086 +#define Z_UTIL_X2_544 1088 +#define Z_UTIL_X2_545 1090 +#define Z_UTIL_X2_546 1092 +#define Z_UTIL_X2_547 1094 +#define Z_UTIL_X2_548 1096 +#define Z_UTIL_X2_549 1098 +#define Z_UTIL_X2_550 1100 +#define Z_UTIL_X2_551 1102 +#define Z_UTIL_X2_552 1104 +#define Z_UTIL_X2_553 1106 +#define Z_UTIL_X2_554 1108 +#define Z_UTIL_X2_555 1110 +#define Z_UTIL_X2_556 1112 +#define Z_UTIL_X2_557 1114 +#define Z_UTIL_X2_558 1116 +#define Z_UTIL_X2_559 1118 +#define Z_UTIL_X2_560 1120 +#define Z_UTIL_X2_561 1122 +#define Z_UTIL_X2_562 1124 +#define Z_UTIL_X2_563 1126 +#define Z_UTIL_X2_564 1128 +#define Z_UTIL_X2_565 1130 +#define Z_UTIL_X2_566 1132 +#define Z_UTIL_X2_567 1134 +#define Z_UTIL_X2_568 1136 +#define Z_UTIL_X2_569 1138 +#define Z_UTIL_X2_570 1140 +#define Z_UTIL_X2_571 1142 +#define Z_UTIL_X2_572 1144 +#define Z_UTIL_X2_573 1146 +#define Z_UTIL_X2_574 1148 +#define Z_UTIL_X2_575 1150 +#define Z_UTIL_X2_576 1152 +#define Z_UTIL_X2_577 1154 +#define Z_UTIL_X2_578 1156 +#define Z_UTIL_X2_579 1158 +#define Z_UTIL_X2_580 1160 +#define Z_UTIL_X2_581 1162 +#define Z_UTIL_X2_582 1164 +#define Z_UTIL_X2_583 1166 +#define Z_UTIL_X2_584 1168 +#define Z_UTIL_X2_585 1170 +#define Z_UTIL_X2_586 1172 +#define Z_UTIL_X2_587 1174 +#define Z_UTIL_X2_588 1176 +#define Z_UTIL_X2_589 1178 +#define Z_UTIL_X2_590 1180 +#define Z_UTIL_X2_591 1182 +#define Z_UTIL_X2_592 1184 +#define Z_UTIL_X2_593 1186 +#define Z_UTIL_X2_594 1188 +#define Z_UTIL_X2_595 1190 +#define Z_UTIL_X2_596 1192 +#define Z_UTIL_X2_597 1194 +#define Z_UTIL_X2_598 1196 +#define Z_UTIL_X2_599 1198 +#define Z_UTIL_X2_600 1200 +#define Z_UTIL_X2_601 1202 +#define Z_UTIL_X2_602 1204 +#define Z_UTIL_X2_603 1206 +#define Z_UTIL_X2_604 1208 +#define Z_UTIL_X2_605 1210 +#define Z_UTIL_X2_606 1212 +#define Z_UTIL_X2_607 1214 +#define Z_UTIL_X2_608 1216 +#define Z_UTIL_X2_609 1218 +#define Z_UTIL_X2_610 1220 +#define Z_UTIL_X2_611 1222 +#define Z_UTIL_X2_612 1224 +#define Z_UTIL_X2_613 1226 +#define Z_UTIL_X2_614 1228 +#define Z_UTIL_X2_615 1230 +#define Z_UTIL_X2_616 1232 +#define Z_UTIL_X2_617 1234 +#define Z_UTIL_X2_618 1236 +#define Z_UTIL_X2_619 1238 +#define Z_UTIL_X2_620 1240 +#define Z_UTIL_X2_621 1242 +#define Z_UTIL_X2_622 1244 +#define Z_UTIL_X2_623 1246 +#define Z_UTIL_X2_624 1248 +#define Z_UTIL_X2_625 1250 +#define Z_UTIL_X2_626 1252 +#define Z_UTIL_X2_627 1254 +#define Z_UTIL_X2_628 1256 +#define Z_UTIL_X2_629 1258 +#define Z_UTIL_X2_630 1260 +#define Z_UTIL_X2_631 1262 +#define Z_UTIL_X2_632 1264 +#define Z_UTIL_X2_633 1266 +#define Z_UTIL_X2_634 1268 +#define Z_UTIL_X2_635 1270 +#define Z_UTIL_X2_636 1272 +#define Z_UTIL_X2_637 1274 +#define Z_UTIL_X2_638 1276 +#define Z_UTIL_X2_639 1278 +#define Z_UTIL_X2_640 1280 +#define Z_UTIL_X2_641 1282 +#define Z_UTIL_X2_642 1284 +#define Z_UTIL_X2_643 1286 +#define Z_UTIL_X2_644 1288 +#define Z_UTIL_X2_645 1290 +#define Z_UTIL_X2_646 1292 +#define Z_UTIL_X2_647 1294 +#define Z_UTIL_X2_648 1296 +#define Z_UTIL_X2_649 1298 +#define Z_UTIL_X2_650 1300 +#define Z_UTIL_X2_651 1302 +#define Z_UTIL_X2_652 1304 +#define Z_UTIL_X2_653 1306 +#define Z_UTIL_X2_654 1308 +#define Z_UTIL_X2_655 1310 +#define Z_UTIL_X2_656 1312 +#define Z_UTIL_X2_657 1314 +#define Z_UTIL_X2_658 1316 +#define Z_UTIL_X2_659 1318 +#define Z_UTIL_X2_660 1320 +#define Z_UTIL_X2_661 1322 +#define Z_UTIL_X2_662 1324 +#define Z_UTIL_X2_663 1326 +#define Z_UTIL_X2_664 1328 +#define Z_UTIL_X2_665 1330 +#define Z_UTIL_X2_666 1332 +#define Z_UTIL_X2_667 1334 +#define Z_UTIL_X2_668 1336 +#define Z_UTIL_X2_669 1338 +#define Z_UTIL_X2_670 1340 +#define Z_UTIL_X2_671 1342 +#define Z_UTIL_X2_672 1344 +#define Z_UTIL_X2_673 1346 +#define Z_UTIL_X2_674 1348 +#define Z_UTIL_X2_675 1350 +#define Z_UTIL_X2_676 1352 +#define Z_UTIL_X2_677 1354 +#define Z_UTIL_X2_678 1356 +#define Z_UTIL_X2_679 1358 +#define Z_UTIL_X2_680 1360 +#define Z_UTIL_X2_681 1362 +#define Z_UTIL_X2_682 1364 +#define Z_UTIL_X2_683 1366 +#define Z_UTIL_X2_684 1368 +#define Z_UTIL_X2_685 1370 +#define Z_UTIL_X2_686 1372 +#define Z_UTIL_X2_687 1374 +#define Z_UTIL_X2_688 1376 +#define Z_UTIL_X2_689 1378 +#define Z_UTIL_X2_690 1380 +#define Z_UTIL_X2_691 1382 +#define Z_UTIL_X2_692 1384 +#define Z_UTIL_X2_693 1386 +#define Z_UTIL_X2_694 1388 +#define Z_UTIL_X2_695 1390 +#define Z_UTIL_X2_696 1392 +#define Z_UTIL_X2_697 1394 +#define Z_UTIL_X2_698 1396 +#define Z_UTIL_X2_699 1398 +#define Z_UTIL_X2_700 1400 +#define Z_UTIL_X2_701 1402 +#define Z_UTIL_X2_702 1404 +#define Z_UTIL_X2_703 1406 +#define Z_UTIL_X2_704 1408 +#define Z_UTIL_X2_705 1410 +#define Z_UTIL_X2_706 1412 +#define Z_UTIL_X2_707 1414 +#define Z_UTIL_X2_708 1416 +#define Z_UTIL_X2_709 1418 +#define Z_UTIL_X2_710 1420 +#define Z_UTIL_X2_711 1422 +#define Z_UTIL_X2_712 1424 +#define Z_UTIL_X2_713 1426 +#define Z_UTIL_X2_714 1428 +#define Z_UTIL_X2_715 1430 +#define Z_UTIL_X2_716 1432 +#define Z_UTIL_X2_717 1434 +#define Z_UTIL_X2_718 1436 +#define Z_UTIL_X2_719 1438 +#define Z_UTIL_X2_720 1440 +#define Z_UTIL_X2_721 1442 +#define Z_UTIL_X2_722 1444 +#define Z_UTIL_X2_723 1446 +#define Z_UTIL_X2_724 1448 +#define Z_UTIL_X2_725 1450 +#define Z_UTIL_X2_726 1452 +#define Z_UTIL_X2_727 1454 +#define Z_UTIL_X2_728 1456 +#define Z_UTIL_X2_729 1458 +#define Z_UTIL_X2_730 1460 +#define Z_UTIL_X2_731 1462 +#define Z_UTIL_X2_732 1464 +#define Z_UTIL_X2_733 1466 +#define Z_UTIL_X2_734 1468 +#define Z_UTIL_X2_735 1470 +#define Z_UTIL_X2_736 1472 +#define Z_UTIL_X2_737 1474 +#define Z_UTIL_X2_738 1476 +#define Z_UTIL_X2_739 1478 +#define Z_UTIL_X2_740 1480 +#define Z_UTIL_X2_741 1482 +#define Z_UTIL_X2_742 1484 +#define Z_UTIL_X2_743 1486 +#define Z_UTIL_X2_744 1488 +#define Z_UTIL_X2_745 1490 +#define Z_UTIL_X2_746 1492 +#define Z_UTIL_X2_747 1494 +#define Z_UTIL_X2_748 1496 +#define Z_UTIL_X2_749 1498 +#define Z_UTIL_X2_750 1500 +#define Z_UTIL_X2_751 1502 +#define Z_UTIL_X2_752 1504 +#define Z_UTIL_X2_753 1506 +#define Z_UTIL_X2_754 1508 +#define Z_UTIL_X2_755 1510 +#define Z_UTIL_X2_756 1512 +#define Z_UTIL_X2_757 1514 +#define Z_UTIL_X2_758 1516 +#define Z_UTIL_X2_759 1518 +#define Z_UTIL_X2_760 1520 +#define Z_UTIL_X2_761 1522 +#define Z_UTIL_X2_762 1524 +#define Z_UTIL_X2_763 1526 +#define Z_UTIL_X2_764 1528 +#define Z_UTIL_X2_765 1530 +#define Z_UTIL_X2_766 1532 +#define Z_UTIL_X2_767 1534 +#define Z_UTIL_X2_768 1536 +#define Z_UTIL_X2_769 1538 +#define Z_UTIL_X2_770 1540 +#define Z_UTIL_X2_771 1542 +#define Z_UTIL_X2_772 1544 +#define Z_UTIL_X2_773 1546 +#define Z_UTIL_X2_774 1548 +#define Z_UTIL_X2_775 1550 +#define Z_UTIL_X2_776 1552 +#define Z_UTIL_X2_777 1554 +#define Z_UTIL_X2_778 1556 +#define Z_UTIL_X2_779 1558 +#define Z_UTIL_X2_780 1560 +#define Z_UTIL_X2_781 1562 +#define Z_UTIL_X2_782 1564 +#define Z_UTIL_X2_783 1566 +#define Z_UTIL_X2_784 1568 +#define Z_UTIL_X2_785 1570 +#define Z_UTIL_X2_786 1572 +#define Z_UTIL_X2_787 1574 +#define Z_UTIL_X2_788 1576 +#define Z_UTIL_X2_789 1578 +#define Z_UTIL_X2_790 1580 +#define Z_UTIL_X2_791 1582 +#define Z_UTIL_X2_792 1584 +#define Z_UTIL_X2_793 1586 +#define Z_UTIL_X2_794 1588 +#define Z_UTIL_X2_795 1590 +#define Z_UTIL_X2_796 1592 +#define Z_UTIL_X2_797 1594 +#define Z_UTIL_X2_798 1596 +#define Z_UTIL_X2_799 1598 +#define Z_UTIL_X2_800 1600 +#define Z_UTIL_X2_801 1602 +#define Z_UTIL_X2_802 1604 +#define Z_UTIL_X2_803 1606 +#define Z_UTIL_X2_804 1608 +#define Z_UTIL_X2_805 1610 +#define Z_UTIL_X2_806 1612 +#define Z_UTIL_X2_807 1614 +#define Z_UTIL_X2_808 1616 +#define Z_UTIL_X2_809 1618 +#define Z_UTIL_X2_810 1620 +#define Z_UTIL_X2_811 1622 +#define Z_UTIL_X2_812 1624 +#define Z_UTIL_X2_813 1626 +#define Z_UTIL_X2_814 1628 +#define Z_UTIL_X2_815 1630 +#define Z_UTIL_X2_816 1632 +#define Z_UTIL_X2_817 1634 +#define Z_UTIL_X2_818 1636 +#define Z_UTIL_X2_819 1638 +#define Z_UTIL_X2_820 1640 +#define Z_UTIL_X2_821 1642 +#define Z_UTIL_X2_822 1644 +#define Z_UTIL_X2_823 1646 +#define Z_UTIL_X2_824 1648 +#define Z_UTIL_X2_825 1650 +#define Z_UTIL_X2_826 1652 +#define Z_UTIL_X2_827 1654 +#define Z_UTIL_X2_828 1656 +#define Z_UTIL_X2_829 1658 +#define Z_UTIL_X2_830 1660 +#define Z_UTIL_X2_831 1662 +#define Z_UTIL_X2_832 1664 +#define Z_UTIL_X2_833 1666 +#define Z_UTIL_X2_834 1668 +#define Z_UTIL_X2_835 1670 +#define Z_UTIL_X2_836 1672 +#define Z_UTIL_X2_837 1674 +#define Z_UTIL_X2_838 1676 +#define Z_UTIL_X2_839 1678 +#define Z_UTIL_X2_840 1680 +#define Z_UTIL_X2_841 1682 +#define Z_UTIL_X2_842 1684 +#define Z_UTIL_X2_843 1686 +#define Z_UTIL_X2_844 1688 +#define Z_UTIL_X2_845 1690 +#define Z_UTIL_X2_846 1692 +#define Z_UTIL_X2_847 1694 +#define Z_UTIL_X2_848 1696 +#define Z_UTIL_X2_849 1698 +#define Z_UTIL_X2_850 1700 +#define Z_UTIL_X2_851 1702 +#define Z_UTIL_X2_852 1704 +#define Z_UTIL_X2_853 1706 +#define Z_UTIL_X2_854 1708 +#define Z_UTIL_X2_855 1710 +#define Z_UTIL_X2_856 1712 +#define Z_UTIL_X2_857 1714 +#define Z_UTIL_X2_858 1716 +#define Z_UTIL_X2_859 1718 +#define Z_UTIL_X2_860 1720 +#define Z_UTIL_X2_861 1722 +#define Z_UTIL_X2_862 1724 +#define Z_UTIL_X2_863 1726 +#define Z_UTIL_X2_864 1728 +#define Z_UTIL_X2_865 1730 +#define Z_UTIL_X2_866 1732 +#define Z_UTIL_X2_867 1734 +#define Z_UTIL_X2_868 1736 +#define Z_UTIL_X2_869 1738 +#define Z_UTIL_X2_870 1740 +#define Z_UTIL_X2_871 1742 +#define Z_UTIL_X2_872 1744 +#define Z_UTIL_X2_873 1746 +#define Z_UTIL_X2_874 1748 +#define Z_UTIL_X2_875 1750 +#define Z_UTIL_X2_876 1752 +#define Z_UTIL_X2_877 1754 +#define Z_UTIL_X2_878 1756 +#define Z_UTIL_X2_879 1758 +#define Z_UTIL_X2_880 1760 +#define Z_UTIL_X2_881 1762 +#define Z_UTIL_X2_882 1764 +#define Z_UTIL_X2_883 1766 +#define Z_UTIL_X2_884 1768 +#define Z_UTIL_X2_885 1770 +#define Z_UTIL_X2_886 1772 +#define Z_UTIL_X2_887 1774 +#define Z_UTIL_X2_888 1776 +#define Z_UTIL_X2_889 1778 +#define Z_UTIL_X2_890 1780 +#define Z_UTIL_X2_891 1782 +#define Z_UTIL_X2_892 1784 +#define Z_UTIL_X2_893 1786 +#define Z_UTIL_X2_894 1788 +#define Z_UTIL_X2_895 1790 +#define Z_UTIL_X2_896 1792 +#define Z_UTIL_X2_897 1794 +#define Z_UTIL_X2_898 1796 +#define Z_UTIL_X2_899 1798 +#define Z_UTIL_X2_900 1800 +#define Z_UTIL_X2_901 1802 +#define Z_UTIL_X2_902 1804 +#define Z_UTIL_X2_903 1806 +#define Z_UTIL_X2_904 1808 +#define Z_UTIL_X2_905 1810 +#define Z_UTIL_X2_906 1812 +#define Z_UTIL_X2_907 1814 +#define Z_UTIL_X2_908 1816 +#define Z_UTIL_X2_909 1818 +#define Z_UTIL_X2_910 1820 +#define Z_UTIL_X2_911 1822 +#define Z_UTIL_X2_912 1824 +#define Z_UTIL_X2_913 1826 +#define Z_UTIL_X2_914 1828 +#define Z_UTIL_X2_915 1830 +#define Z_UTIL_X2_916 1832 +#define Z_UTIL_X2_917 1834 +#define Z_UTIL_X2_918 1836 +#define Z_UTIL_X2_919 1838 +#define Z_UTIL_X2_920 1840 +#define Z_UTIL_X2_921 1842 +#define Z_UTIL_X2_922 1844 +#define Z_UTIL_X2_923 1846 +#define Z_UTIL_X2_924 1848 +#define Z_UTIL_X2_925 1850 +#define Z_UTIL_X2_926 1852 +#define Z_UTIL_X2_927 1854 +#define Z_UTIL_X2_928 1856 +#define Z_UTIL_X2_929 1858 +#define Z_UTIL_X2_930 1860 +#define Z_UTIL_X2_931 1862 +#define Z_UTIL_X2_932 1864 +#define Z_UTIL_X2_933 1866 +#define Z_UTIL_X2_934 1868 +#define Z_UTIL_X2_935 1870 +#define Z_UTIL_X2_936 1872 +#define Z_UTIL_X2_937 1874 +#define Z_UTIL_X2_938 1876 +#define Z_UTIL_X2_939 1878 +#define Z_UTIL_X2_940 1880 +#define Z_UTIL_X2_941 1882 +#define Z_UTIL_X2_942 1884 +#define Z_UTIL_X2_943 1886 +#define Z_UTIL_X2_944 1888 +#define Z_UTIL_X2_945 1890 +#define Z_UTIL_X2_946 1892 +#define Z_UTIL_X2_947 1894 +#define Z_UTIL_X2_948 1896 +#define Z_UTIL_X2_949 1898 +#define Z_UTIL_X2_950 1900 +#define Z_UTIL_X2_951 1902 +#define Z_UTIL_X2_952 1904 +#define Z_UTIL_X2_953 1906 +#define Z_UTIL_X2_954 1908 +#define Z_UTIL_X2_955 1910 +#define Z_UTIL_X2_956 1912 +#define Z_UTIL_X2_957 1914 +#define Z_UTIL_X2_958 1916 +#define Z_UTIL_X2_959 1918 +#define Z_UTIL_X2_960 1920 +#define Z_UTIL_X2_961 1922 +#define Z_UTIL_X2_962 1924 +#define Z_UTIL_X2_963 1926 +#define Z_UTIL_X2_964 1928 +#define Z_UTIL_X2_965 1930 +#define Z_UTIL_X2_966 1932 +#define Z_UTIL_X2_967 1934 +#define Z_UTIL_X2_968 1936 +#define Z_UTIL_X2_969 1938 +#define Z_UTIL_X2_970 1940 +#define Z_UTIL_X2_971 1942 +#define Z_UTIL_X2_972 1944 +#define Z_UTIL_X2_973 1946 +#define Z_UTIL_X2_974 1948 +#define Z_UTIL_X2_975 1950 +#define Z_UTIL_X2_976 1952 +#define Z_UTIL_X2_977 1954 +#define Z_UTIL_X2_978 1956 +#define Z_UTIL_X2_979 1958 +#define Z_UTIL_X2_980 1960 +#define Z_UTIL_X2_981 1962 +#define Z_UTIL_X2_982 1964 +#define Z_UTIL_X2_983 1966 +#define Z_UTIL_X2_984 1968 +#define Z_UTIL_X2_985 1970 +#define Z_UTIL_X2_986 1972 +#define Z_UTIL_X2_987 1974 +#define Z_UTIL_X2_988 1976 +#define Z_UTIL_X2_989 1978 +#define Z_UTIL_X2_990 1980 +#define Z_UTIL_X2_991 1982 +#define Z_UTIL_X2_992 1984 +#define Z_UTIL_X2_993 1986 +#define Z_UTIL_X2_994 1988 +#define Z_UTIL_X2_995 1990 +#define Z_UTIL_X2_996 1992 +#define Z_UTIL_X2_997 1994 +#define Z_UTIL_X2_998 1996 +#define Z_UTIL_X2_999 1998 +#define Z_UTIL_X2_1000 2000 +#define Z_UTIL_X2_1001 2002 +#define Z_UTIL_X2_1002 2004 +#define Z_UTIL_X2_1003 2006 +#define Z_UTIL_X2_1004 2008 +#define Z_UTIL_X2_1005 2010 +#define Z_UTIL_X2_1006 2012 +#define Z_UTIL_X2_1007 2014 +#define Z_UTIL_X2_1008 2016 +#define Z_UTIL_X2_1009 2018 +#define Z_UTIL_X2_1010 2020 +#define Z_UTIL_X2_1011 2022 +#define Z_UTIL_X2_1012 2024 +#define Z_UTIL_X2_1013 2026 +#define Z_UTIL_X2_1014 2028 +#define Z_UTIL_X2_1015 2030 +#define Z_UTIL_X2_1016 2032 +#define Z_UTIL_X2_1017 2034 +#define Z_UTIL_X2_1018 2036 +#define Z_UTIL_X2_1019 2038 +#define Z_UTIL_X2_1020 2040 +#define Z_UTIL_X2_1021 2042 +#define Z_UTIL_X2_1022 2044 +#define Z_UTIL_X2_1023 2046 +#define Z_UTIL_X2_1024 2048 +#define Z_UTIL_X2_1025 2050 +#define Z_UTIL_X2_1026 2052 +#define Z_UTIL_X2_1027 2054 +#define Z_UTIL_X2_1028 2056 +#define Z_UTIL_X2_1029 2058 +#define Z_UTIL_X2_1030 2060 +#define Z_UTIL_X2_1031 2062 +#define Z_UTIL_X2_1032 2064 +#define Z_UTIL_X2_1033 2066 +#define Z_UTIL_X2_1034 2068 +#define Z_UTIL_X2_1035 2070 +#define Z_UTIL_X2_1036 2072 +#define Z_UTIL_X2_1037 2074 +#define Z_UTIL_X2_1038 2076 +#define Z_UTIL_X2_1039 2078 +#define Z_UTIL_X2_1040 2080 +#define Z_UTIL_X2_1041 2082 +#define Z_UTIL_X2_1042 2084 +#define Z_UTIL_X2_1043 2086 +#define Z_UTIL_X2_1044 2088 +#define Z_UTIL_X2_1045 2090 +#define Z_UTIL_X2_1046 2092 +#define Z_UTIL_X2_1047 2094 +#define Z_UTIL_X2_1048 2096 +#define Z_UTIL_X2_1049 2098 +#define Z_UTIL_X2_1050 2100 +#define Z_UTIL_X2_1051 2102 +#define Z_UTIL_X2_1052 2104 +#define Z_UTIL_X2_1053 2106 +#define Z_UTIL_X2_1054 2108 +#define Z_UTIL_X2_1055 2110 +#define Z_UTIL_X2_1056 2112 +#define Z_UTIL_X2_1057 2114 +#define Z_UTIL_X2_1058 2116 +#define Z_UTIL_X2_1059 2118 +#define Z_UTIL_X2_1060 2120 +#define Z_UTIL_X2_1061 2122 +#define Z_UTIL_X2_1062 2124 +#define Z_UTIL_X2_1063 2126 +#define Z_UTIL_X2_1064 2128 +#define Z_UTIL_X2_1065 2130 +#define Z_UTIL_X2_1066 2132 +#define Z_UTIL_X2_1067 2134 +#define Z_UTIL_X2_1068 2136 +#define Z_UTIL_X2_1069 2138 +#define Z_UTIL_X2_1070 2140 +#define Z_UTIL_X2_1071 2142 +#define Z_UTIL_X2_1072 2144 +#define Z_UTIL_X2_1073 2146 +#define Z_UTIL_X2_1074 2148 +#define Z_UTIL_X2_1075 2150 +#define Z_UTIL_X2_1076 2152 +#define Z_UTIL_X2_1077 2154 +#define Z_UTIL_X2_1078 2156 +#define Z_UTIL_X2_1079 2158 +#define Z_UTIL_X2_1080 2160 +#define Z_UTIL_X2_1081 2162 +#define Z_UTIL_X2_1082 2164 +#define Z_UTIL_X2_1083 2166 +#define Z_UTIL_X2_1084 2168 +#define Z_UTIL_X2_1085 2170 +#define Z_UTIL_X2_1086 2172 +#define Z_UTIL_X2_1087 2174 +#define Z_UTIL_X2_1088 2176 +#define Z_UTIL_X2_1089 2178 +#define Z_UTIL_X2_1090 2180 +#define Z_UTIL_X2_1091 2182 +#define Z_UTIL_X2_1092 2184 +#define Z_UTIL_X2_1093 2186 +#define Z_UTIL_X2_1094 2188 +#define Z_UTIL_X2_1095 2190 +#define Z_UTIL_X2_1096 2192 +#define Z_UTIL_X2_1097 2194 +#define Z_UTIL_X2_1098 2196 +#define Z_UTIL_X2_1099 2198 +#define Z_UTIL_X2_1100 2200 +#define Z_UTIL_X2_1101 2202 +#define Z_UTIL_X2_1102 2204 +#define Z_UTIL_X2_1103 2206 +#define Z_UTIL_X2_1104 2208 +#define Z_UTIL_X2_1105 2210 +#define Z_UTIL_X2_1106 2212 +#define Z_UTIL_X2_1107 2214 +#define Z_UTIL_X2_1108 2216 +#define Z_UTIL_X2_1109 2218 +#define Z_UTIL_X2_1110 2220 +#define Z_UTIL_X2_1111 2222 +#define Z_UTIL_X2_1112 2224 +#define Z_UTIL_X2_1113 2226 +#define Z_UTIL_X2_1114 2228 +#define Z_UTIL_X2_1115 2230 +#define Z_UTIL_X2_1116 2232 +#define Z_UTIL_X2_1117 2234 +#define Z_UTIL_X2_1118 2236 +#define Z_UTIL_X2_1119 2238 +#define Z_UTIL_X2_1120 2240 +#define Z_UTIL_X2_1121 2242 +#define Z_UTIL_X2_1122 2244 +#define Z_UTIL_X2_1123 2246 +#define Z_UTIL_X2_1124 2248 +#define Z_UTIL_X2_1125 2250 +#define Z_UTIL_X2_1126 2252 +#define Z_UTIL_X2_1127 2254 +#define Z_UTIL_X2_1128 2256 +#define Z_UTIL_X2_1129 2258 +#define Z_UTIL_X2_1130 2260 +#define Z_UTIL_X2_1131 2262 +#define Z_UTIL_X2_1132 2264 +#define Z_UTIL_X2_1133 2266 +#define Z_UTIL_X2_1134 2268 +#define Z_UTIL_X2_1135 2270 +#define Z_UTIL_X2_1136 2272 +#define Z_UTIL_X2_1137 2274 +#define Z_UTIL_X2_1138 2276 +#define Z_UTIL_X2_1139 2278 +#define Z_UTIL_X2_1140 2280 +#define Z_UTIL_X2_1141 2282 +#define Z_UTIL_X2_1142 2284 +#define Z_UTIL_X2_1143 2286 +#define Z_UTIL_X2_1144 2288 +#define Z_UTIL_X2_1145 2290 +#define Z_UTIL_X2_1146 2292 +#define Z_UTIL_X2_1147 2294 +#define Z_UTIL_X2_1148 2296 +#define Z_UTIL_X2_1149 2298 +#define Z_UTIL_X2_1150 2300 +#define Z_UTIL_X2_1151 2302 +#define Z_UTIL_X2_1152 2304 +#define Z_UTIL_X2_1153 2306 +#define Z_UTIL_X2_1154 2308 +#define Z_UTIL_X2_1155 2310 +#define Z_UTIL_X2_1156 2312 +#define Z_UTIL_X2_1157 2314 +#define Z_UTIL_X2_1158 2316 +#define Z_UTIL_X2_1159 2318 +#define Z_UTIL_X2_1160 2320 +#define Z_UTIL_X2_1161 2322 +#define Z_UTIL_X2_1162 2324 +#define Z_UTIL_X2_1163 2326 +#define Z_UTIL_X2_1164 2328 +#define Z_UTIL_X2_1165 2330 +#define Z_UTIL_X2_1166 2332 +#define Z_UTIL_X2_1167 2334 +#define Z_UTIL_X2_1168 2336 +#define Z_UTIL_X2_1169 2338 +#define Z_UTIL_X2_1170 2340 +#define Z_UTIL_X2_1171 2342 +#define Z_UTIL_X2_1172 2344 +#define Z_UTIL_X2_1173 2346 +#define Z_UTIL_X2_1174 2348 +#define Z_UTIL_X2_1175 2350 +#define Z_UTIL_X2_1176 2352 +#define Z_UTIL_X2_1177 2354 +#define Z_UTIL_X2_1178 2356 +#define Z_UTIL_X2_1179 2358 +#define Z_UTIL_X2_1180 2360 +#define Z_UTIL_X2_1181 2362 +#define Z_UTIL_X2_1182 2364 +#define Z_UTIL_X2_1183 2366 +#define Z_UTIL_X2_1184 2368 +#define Z_UTIL_X2_1185 2370 +#define Z_UTIL_X2_1186 2372 +#define Z_UTIL_X2_1187 2374 +#define Z_UTIL_X2_1188 2376 +#define Z_UTIL_X2_1189 2378 +#define Z_UTIL_X2_1190 2380 +#define Z_UTIL_X2_1191 2382 +#define Z_UTIL_X2_1192 2384 +#define Z_UTIL_X2_1193 2386 +#define Z_UTIL_X2_1194 2388 +#define Z_UTIL_X2_1195 2390 +#define Z_UTIL_X2_1196 2392 +#define Z_UTIL_X2_1197 2394 +#define Z_UTIL_X2_1198 2396 +#define Z_UTIL_X2_1199 2398 +#define Z_UTIL_X2_1200 2400 +#define Z_UTIL_X2_1201 2402 +#define Z_UTIL_X2_1202 2404 +#define Z_UTIL_X2_1203 2406 +#define Z_UTIL_X2_1204 2408 +#define Z_UTIL_X2_1205 2410 +#define Z_UTIL_X2_1206 2412 +#define Z_UTIL_X2_1207 2414 +#define Z_UTIL_X2_1208 2416 +#define Z_UTIL_X2_1209 2418 +#define Z_UTIL_X2_1210 2420 +#define Z_UTIL_X2_1211 2422 +#define Z_UTIL_X2_1212 2424 +#define Z_UTIL_X2_1213 2426 +#define Z_UTIL_X2_1214 2428 +#define Z_UTIL_X2_1215 2430 +#define Z_UTIL_X2_1216 2432 +#define Z_UTIL_X2_1217 2434 +#define Z_UTIL_X2_1218 2436 +#define Z_UTIL_X2_1219 2438 +#define Z_UTIL_X2_1220 2440 +#define Z_UTIL_X2_1221 2442 +#define Z_UTIL_X2_1222 2444 +#define Z_UTIL_X2_1223 2446 +#define Z_UTIL_X2_1224 2448 +#define Z_UTIL_X2_1225 2450 +#define Z_UTIL_X2_1226 2452 +#define Z_UTIL_X2_1227 2454 +#define Z_UTIL_X2_1228 2456 +#define Z_UTIL_X2_1229 2458 +#define Z_UTIL_X2_1230 2460 +#define Z_UTIL_X2_1231 2462 +#define Z_UTIL_X2_1232 2464 +#define Z_UTIL_X2_1233 2466 +#define Z_UTIL_X2_1234 2468 +#define Z_UTIL_X2_1235 2470 +#define Z_UTIL_X2_1236 2472 +#define Z_UTIL_X2_1237 2474 +#define Z_UTIL_X2_1238 2476 +#define Z_UTIL_X2_1239 2478 +#define Z_UTIL_X2_1240 2480 +#define Z_UTIL_X2_1241 2482 +#define Z_UTIL_X2_1242 2484 +#define Z_UTIL_X2_1243 2486 +#define Z_UTIL_X2_1244 2488 +#define Z_UTIL_X2_1245 2490 +#define Z_UTIL_X2_1246 2492 +#define Z_UTIL_X2_1247 2494 +#define Z_UTIL_X2_1248 2496 +#define Z_UTIL_X2_1249 2498 +#define Z_UTIL_X2_1250 2500 +#define Z_UTIL_X2_1251 2502 +#define Z_UTIL_X2_1252 2504 +#define Z_UTIL_X2_1253 2506 +#define Z_UTIL_X2_1254 2508 +#define Z_UTIL_X2_1255 2510 +#define Z_UTIL_X2_1256 2512 +#define Z_UTIL_X2_1257 2514 +#define Z_UTIL_X2_1258 2516 +#define Z_UTIL_X2_1259 2518 +#define Z_UTIL_X2_1260 2520 +#define Z_UTIL_X2_1261 2522 +#define Z_UTIL_X2_1262 2524 +#define Z_UTIL_X2_1263 2526 +#define Z_UTIL_X2_1264 2528 +#define Z_UTIL_X2_1265 2530 +#define Z_UTIL_X2_1266 2532 +#define Z_UTIL_X2_1267 2534 +#define Z_UTIL_X2_1268 2536 +#define Z_UTIL_X2_1269 2538 +#define Z_UTIL_X2_1270 2540 +#define Z_UTIL_X2_1271 2542 +#define Z_UTIL_X2_1272 2544 +#define Z_UTIL_X2_1273 2546 +#define Z_UTIL_X2_1274 2548 +#define Z_UTIL_X2_1275 2550 +#define Z_UTIL_X2_1276 2552 +#define Z_UTIL_X2_1277 2554 +#define Z_UTIL_X2_1278 2556 +#define Z_UTIL_X2_1279 2558 +#define Z_UTIL_X2_1280 2560 +#define Z_UTIL_X2_1281 2562 +#define Z_UTIL_X2_1282 2564 +#define Z_UTIL_X2_1283 2566 +#define Z_UTIL_X2_1284 2568 +#define Z_UTIL_X2_1285 2570 +#define Z_UTIL_X2_1286 2572 +#define Z_UTIL_X2_1287 2574 +#define Z_UTIL_X2_1288 2576 +#define Z_UTIL_X2_1289 2578 +#define Z_UTIL_X2_1290 2580 +#define Z_UTIL_X2_1291 2582 +#define Z_UTIL_X2_1292 2584 +#define Z_UTIL_X2_1293 2586 +#define Z_UTIL_X2_1294 2588 +#define Z_UTIL_X2_1295 2590 +#define Z_UTIL_X2_1296 2592 +#define Z_UTIL_X2_1297 2594 +#define Z_UTIL_X2_1298 2596 +#define Z_UTIL_X2_1299 2598 +#define Z_UTIL_X2_1300 2600 +#define Z_UTIL_X2_1301 2602 +#define Z_UTIL_X2_1302 2604 +#define Z_UTIL_X2_1303 2606 +#define Z_UTIL_X2_1304 2608 +#define Z_UTIL_X2_1305 2610 +#define Z_UTIL_X2_1306 2612 +#define Z_UTIL_X2_1307 2614 +#define Z_UTIL_X2_1308 2616 +#define Z_UTIL_X2_1309 2618 +#define Z_UTIL_X2_1310 2620 +#define Z_UTIL_X2_1311 2622 +#define Z_UTIL_X2_1312 2624 +#define Z_UTIL_X2_1313 2626 +#define Z_UTIL_X2_1314 2628 +#define Z_UTIL_X2_1315 2630 +#define Z_UTIL_X2_1316 2632 +#define Z_UTIL_X2_1317 2634 +#define Z_UTIL_X2_1318 2636 +#define Z_UTIL_X2_1319 2638 +#define Z_UTIL_X2_1320 2640 +#define Z_UTIL_X2_1321 2642 +#define Z_UTIL_X2_1322 2644 +#define Z_UTIL_X2_1323 2646 +#define Z_UTIL_X2_1324 2648 +#define Z_UTIL_X2_1325 2650 +#define Z_UTIL_X2_1326 2652 +#define Z_UTIL_X2_1327 2654 +#define Z_UTIL_X2_1328 2656 +#define Z_UTIL_X2_1329 2658 +#define Z_UTIL_X2_1330 2660 +#define Z_UTIL_X2_1331 2662 +#define Z_UTIL_X2_1332 2664 +#define Z_UTIL_X2_1333 2666 +#define Z_UTIL_X2_1334 2668 +#define Z_UTIL_X2_1335 2670 +#define Z_UTIL_X2_1336 2672 +#define Z_UTIL_X2_1337 2674 +#define Z_UTIL_X2_1338 2676 +#define Z_UTIL_X2_1339 2678 +#define Z_UTIL_X2_1340 2680 +#define Z_UTIL_X2_1341 2682 +#define Z_UTIL_X2_1342 2684 +#define Z_UTIL_X2_1343 2686 +#define Z_UTIL_X2_1344 2688 +#define Z_UTIL_X2_1345 2690 +#define Z_UTIL_X2_1346 2692 +#define Z_UTIL_X2_1347 2694 +#define Z_UTIL_X2_1348 2696 +#define Z_UTIL_X2_1349 2698 +#define Z_UTIL_X2_1350 2700 +#define Z_UTIL_X2_1351 2702 +#define Z_UTIL_X2_1352 2704 +#define Z_UTIL_X2_1353 2706 +#define Z_UTIL_X2_1354 2708 +#define Z_UTIL_X2_1355 2710 +#define Z_UTIL_X2_1356 2712 +#define Z_UTIL_X2_1357 2714 +#define Z_UTIL_X2_1358 2716 +#define Z_UTIL_X2_1359 2718 +#define Z_UTIL_X2_1360 2720 +#define Z_UTIL_X2_1361 2722 +#define Z_UTIL_X2_1362 2724 +#define Z_UTIL_X2_1363 2726 +#define Z_UTIL_X2_1364 2728 +#define Z_UTIL_X2_1365 2730 +#define Z_UTIL_X2_1366 2732 +#define Z_UTIL_X2_1367 2734 +#define Z_UTIL_X2_1368 2736 +#define Z_UTIL_X2_1369 2738 +#define Z_UTIL_X2_1370 2740 +#define Z_UTIL_X2_1371 2742 +#define Z_UTIL_X2_1372 2744 +#define Z_UTIL_X2_1373 2746 +#define Z_UTIL_X2_1374 2748 +#define Z_UTIL_X2_1375 2750 +#define Z_UTIL_X2_1376 2752 +#define Z_UTIL_X2_1377 2754 +#define Z_UTIL_X2_1378 2756 +#define Z_UTIL_X2_1379 2758 +#define Z_UTIL_X2_1380 2760 +#define Z_UTIL_X2_1381 2762 +#define Z_UTIL_X2_1382 2764 +#define Z_UTIL_X2_1383 2766 +#define Z_UTIL_X2_1384 2768 +#define Z_UTIL_X2_1385 2770 +#define Z_UTIL_X2_1386 2772 +#define Z_UTIL_X2_1387 2774 +#define Z_UTIL_X2_1388 2776 +#define Z_UTIL_X2_1389 2778 +#define Z_UTIL_X2_1390 2780 +#define Z_UTIL_X2_1391 2782 +#define Z_UTIL_X2_1392 2784 +#define Z_UTIL_X2_1393 2786 +#define Z_UTIL_X2_1394 2788 +#define Z_UTIL_X2_1395 2790 +#define Z_UTIL_X2_1396 2792 +#define Z_UTIL_X2_1397 2794 +#define Z_UTIL_X2_1398 2796 +#define Z_UTIL_X2_1399 2798 +#define Z_UTIL_X2_1400 2800 +#define Z_UTIL_X2_1401 2802 +#define Z_UTIL_X2_1402 2804 +#define Z_UTIL_X2_1403 2806 +#define Z_UTIL_X2_1404 2808 +#define Z_UTIL_X2_1405 2810 +#define Z_UTIL_X2_1406 2812 +#define Z_UTIL_X2_1407 2814 +#define Z_UTIL_X2_1408 2816 +#define Z_UTIL_X2_1409 2818 +#define Z_UTIL_X2_1410 2820 +#define Z_UTIL_X2_1411 2822 +#define Z_UTIL_X2_1412 2824 +#define Z_UTIL_X2_1413 2826 +#define Z_UTIL_X2_1414 2828 +#define Z_UTIL_X2_1415 2830 +#define Z_UTIL_X2_1416 2832 +#define Z_UTIL_X2_1417 2834 +#define Z_UTIL_X2_1418 2836 +#define Z_UTIL_X2_1419 2838 +#define Z_UTIL_X2_1420 2840 +#define Z_UTIL_X2_1421 2842 +#define Z_UTIL_X2_1422 2844 +#define Z_UTIL_X2_1423 2846 +#define Z_UTIL_X2_1424 2848 +#define Z_UTIL_X2_1425 2850 +#define Z_UTIL_X2_1426 2852 +#define Z_UTIL_X2_1427 2854 +#define Z_UTIL_X2_1428 2856 +#define Z_UTIL_X2_1429 2858 +#define Z_UTIL_X2_1430 2860 +#define Z_UTIL_X2_1431 2862 +#define Z_UTIL_X2_1432 2864 +#define Z_UTIL_X2_1433 2866 +#define Z_UTIL_X2_1434 2868 +#define Z_UTIL_X2_1435 2870 +#define Z_UTIL_X2_1436 2872 +#define Z_UTIL_X2_1437 2874 +#define Z_UTIL_X2_1438 2876 +#define Z_UTIL_X2_1439 2878 +#define Z_UTIL_X2_1440 2880 +#define Z_UTIL_X2_1441 2882 +#define Z_UTIL_X2_1442 2884 +#define Z_UTIL_X2_1443 2886 +#define Z_UTIL_X2_1444 2888 +#define Z_UTIL_X2_1445 2890 +#define Z_UTIL_X2_1446 2892 +#define Z_UTIL_X2_1447 2894 +#define Z_UTIL_X2_1448 2896 +#define Z_UTIL_X2_1449 2898 +#define Z_UTIL_X2_1450 2900 +#define Z_UTIL_X2_1451 2902 +#define Z_UTIL_X2_1452 2904 +#define Z_UTIL_X2_1453 2906 +#define Z_UTIL_X2_1454 2908 +#define Z_UTIL_X2_1455 2910 +#define Z_UTIL_X2_1456 2912 +#define Z_UTIL_X2_1457 2914 +#define Z_UTIL_X2_1458 2916 +#define Z_UTIL_X2_1459 2918 +#define Z_UTIL_X2_1460 2920 +#define Z_UTIL_X2_1461 2922 +#define Z_UTIL_X2_1462 2924 +#define Z_UTIL_X2_1463 2926 +#define Z_UTIL_X2_1464 2928 +#define Z_UTIL_X2_1465 2930 +#define Z_UTIL_X2_1466 2932 +#define Z_UTIL_X2_1467 2934 +#define Z_UTIL_X2_1468 2936 +#define Z_UTIL_X2_1469 2938 +#define Z_UTIL_X2_1470 2940 +#define Z_UTIL_X2_1471 2942 +#define Z_UTIL_X2_1472 2944 +#define Z_UTIL_X2_1473 2946 +#define Z_UTIL_X2_1474 2948 +#define Z_UTIL_X2_1475 2950 +#define Z_UTIL_X2_1476 2952 +#define Z_UTIL_X2_1477 2954 +#define Z_UTIL_X2_1478 2956 +#define Z_UTIL_X2_1479 2958 +#define Z_UTIL_X2_1480 2960 +#define Z_UTIL_X2_1481 2962 +#define Z_UTIL_X2_1482 2964 +#define Z_UTIL_X2_1483 2966 +#define Z_UTIL_X2_1484 2968 +#define Z_UTIL_X2_1485 2970 +#define Z_UTIL_X2_1486 2972 +#define Z_UTIL_X2_1487 2974 +#define Z_UTIL_X2_1488 2976 +#define Z_UTIL_X2_1489 2978 +#define Z_UTIL_X2_1490 2980 +#define Z_UTIL_X2_1491 2982 +#define Z_UTIL_X2_1492 2984 +#define Z_UTIL_X2_1493 2986 +#define Z_UTIL_X2_1494 2988 +#define Z_UTIL_X2_1495 2990 +#define Z_UTIL_X2_1496 2992 +#define Z_UTIL_X2_1497 2994 +#define Z_UTIL_X2_1498 2996 +#define Z_UTIL_X2_1499 2998 +#define Z_UTIL_X2_1500 3000 +#define Z_UTIL_X2_1501 3002 +#define Z_UTIL_X2_1502 3004 +#define Z_UTIL_X2_1503 3006 +#define Z_UTIL_X2_1504 3008 +#define Z_UTIL_X2_1505 3010 +#define Z_UTIL_X2_1506 3012 +#define Z_UTIL_X2_1507 3014 +#define Z_UTIL_X2_1508 3016 +#define Z_UTIL_X2_1509 3018 +#define Z_UTIL_X2_1510 3020 +#define Z_UTIL_X2_1511 3022 +#define Z_UTIL_X2_1512 3024 +#define Z_UTIL_X2_1513 3026 +#define Z_UTIL_X2_1514 3028 +#define Z_UTIL_X2_1515 3030 +#define Z_UTIL_X2_1516 3032 +#define Z_UTIL_X2_1517 3034 +#define Z_UTIL_X2_1518 3036 +#define Z_UTIL_X2_1519 3038 +#define Z_UTIL_X2_1520 3040 +#define Z_UTIL_X2_1521 3042 +#define Z_UTIL_X2_1522 3044 +#define Z_UTIL_X2_1523 3046 +#define Z_UTIL_X2_1524 3048 +#define Z_UTIL_X2_1525 3050 +#define Z_UTIL_X2_1526 3052 +#define Z_UTIL_X2_1527 3054 +#define Z_UTIL_X2_1528 3056 +#define Z_UTIL_X2_1529 3058 +#define Z_UTIL_X2_1530 3060 +#define Z_UTIL_X2_1531 3062 +#define Z_UTIL_X2_1532 3064 +#define Z_UTIL_X2_1533 3066 +#define Z_UTIL_X2_1534 3068 +#define Z_UTIL_X2_1535 3070 +#define Z_UTIL_X2_1536 3072 +#define Z_UTIL_X2_1537 3074 +#define Z_UTIL_X2_1538 3076 +#define Z_UTIL_X2_1539 3078 +#define Z_UTIL_X2_1540 3080 +#define Z_UTIL_X2_1541 3082 +#define Z_UTIL_X2_1542 3084 +#define Z_UTIL_X2_1543 3086 +#define Z_UTIL_X2_1544 3088 +#define Z_UTIL_X2_1545 3090 +#define Z_UTIL_X2_1546 3092 +#define Z_UTIL_X2_1547 3094 +#define Z_UTIL_X2_1548 3096 +#define Z_UTIL_X2_1549 3098 +#define Z_UTIL_X2_1550 3100 +#define Z_UTIL_X2_1551 3102 +#define Z_UTIL_X2_1552 3104 +#define Z_UTIL_X2_1553 3106 +#define Z_UTIL_X2_1554 3108 +#define Z_UTIL_X2_1555 3110 +#define Z_UTIL_X2_1556 3112 +#define Z_UTIL_X2_1557 3114 +#define Z_UTIL_X2_1558 3116 +#define Z_UTIL_X2_1559 3118 +#define Z_UTIL_X2_1560 3120 +#define Z_UTIL_X2_1561 3122 +#define Z_UTIL_X2_1562 3124 +#define Z_UTIL_X2_1563 3126 +#define Z_UTIL_X2_1564 3128 +#define Z_UTIL_X2_1565 3130 +#define Z_UTIL_X2_1566 3132 +#define Z_UTIL_X2_1567 3134 +#define Z_UTIL_X2_1568 3136 +#define Z_UTIL_X2_1569 3138 +#define Z_UTIL_X2_1570 3140 +#define Z_UTIL_X2_1571 3142 +#define Z_UTIL_X2_1572 3144 +#define Z_UTIL_X2_1573 3146 +#define Z_UTIL_X2_1574 3148 +#define Z_UTIL_X2_1575 3150 +#define Z_UTIL_X2_1576 3152 +#define Z_UTIL_X2_1577 3154 +#define Z_UTIL_X2_1578 3156 +#define Z_UTIL_X2_1579 3158 +#define Z_UTIL_X2_1580 3160 +#define Z_UTIL_X2_1581 3162 +#define Z_UTIL_X2_1582 3164 +#define Z_UTIL_X2_1583 3166 +#define Z_UTIL_X2_1584 3168 +#define Z_UTIL_X2_1585 3170 +#define Z_UTIL_X2_1586 3172 +#define Z_UTIL_X2_1587 3174 +#define Z_UTIL_X2_1588 3176 +#define Z_UTIL_X2_1589 3178 +#define Z_UTIL_X2_1590 3180 +#define Z_UTIL_X2_1591 3182 +#define Z_UTIL_X2_1592 3184 +#define Z_UTIL_X2_1593 3186 +#define Z_UTIL_X2_1594 3188 +#define Z_UTIL_X2_1595 3190 +#define Z_UTIL_X2_1596 3192 +#define Z_UTIL_X2_1597 3194 +#define Z_UTIL_X2_1598 3196 +#define Z_UTIL_X2_1599 3198 +#define Z_UTIL_X2_1600 3200 +#define Z_UTIL_X2_1601 3202 +#define Z_UTIL_X2_1602 3204 +#define Z_UTIL_X2_1603 3206 +#define Z_UTIL_X2_1604 3208 +#define Z_UTIL_X2_1605 3210 +#define Z_UTIL_X2_1606 3212 +#define Z_UTIL_X2_1607 3214 +#define Z_UTIL_X2_1608 3216 +#define Z_UTIL_X2_1609 3218 +#define Z_UTIL_X2_1610 3220 +#define Z_UTIL_X2_1611 3222 +#define Z_UTIL_X2_1612 3224 +#define Z_UTIL_X2_1613 3226 +#define Z_UTIL_X2_1614 3228 +#define Z_UTIL_X2_1615 3230 +#define Z_UTIL_X2_1616 3232 +#define Z_UTIL_X2_1617 3234 +#define Z_UTIL_X2_1618 3236 +#define Z_UTIL_X2_1619 3238 +#define Z_UTIL_X2_1620 3240 +#define Z_UTIL_X2_1621 3242 +#define Z_UTIL_X2_1622 3244 +#define Z_UTIL_X2_1623 3246 +#define Z_UTIL_X2_1624 3248 +#define Z_UTIL_X2_1625 3250 +#define Z_UTIL_X2_1626 3252 +#define Z_UTIL_X2_1627 3254 +#define Z_UTIL_X2_1628 3256 +#define Z_UTIL_X2_1629 3258 +#define Z_UTIL_X2_1630 3260 +#define Z_UTIL_X2_1631 3262 +#define Z_UTIL_X2_1632 3264 +#define Z_UTIL_X2_1633 3266 +#define Z_UTIL_X2_1634 3268 +#define Z_UTIL_X2_1635 3270 +#define Z_UTIL_X2_1636 3272 +#define Z_UTIL_X2_1637 3274 +#define Z_UTIL_X2_1638 3276 +#define Z_UTIL_X2_1639 3278 +#define Z_UTIL_X2_1640 3280 +#define Z_UTIL_X2_1641 3282 +#define Z_UTIL_X2_1642 3284 +#define Z_UTIL_X2_1643 3286 +#define Z_UTIL_X2_1644 3288 +#define Z_UTIL_X2_1645 3290 +#define Z_UTIL_X2_1646 3292 +#define Z_UTIL_X2_1647 3294 +#define Z_UTIL_X2_1648 3296 +#define Z_UTIL_X2_1649 3298 +#define Z_UTIL_X2_1650 3300 +#define Z_UTIL_X2_1651 3302 +#define Z_UTIL_X2_1652 3304 +#define Z_UTIL_X2_1653 3306 +#define Z_UTIL_X2_1654 3308 +#define Z_UTIL_X2_1655 3310 +#define Z_UTIL_X2_1656 3312 +#define Z_UTIL_X2_1657 3314 +#define Z_UTIL_X2_1658 3316 +#define Z_UTIL_X2_1659 3318 +#define Z_UTIL_X2_1660 3320 +#define Z_UTIL_X2_1661 3322 +#define Z_UTIL_X2_1662 3324 +#define Z_UTIL_X2_1663 3326 +#define Z_UTIL_X2_1664 3328 +#define Z_UTIL_X2_1665 3330 +#define Z_UTIL_X2_1666 3332 +#define Z_UTIL_X2_1667 3334 +#define Z_UTIL_X2_1668 3336 +#define Z_UTIL_X2_1669 3338 +#define Z_UTIL_X2_1670 3340 +#define Z_UTIL_X2_1671 3342 +#define Z_UTIL_X2_1672 3344 +#define Z_UTIL_X2_1673 3346 +#define Z_UTIL_X2_1674 3348 +#define Z_UTIL_X2_1675 3350 +#define Z_UTIL_X2_1676 3352 +#define Z_UTIL_X2_1677 3354 +#define Z_UTIL_X2_1678 3356 +#define Z_UTIL_X2_1679 3358 +#define Z_UTIL_X2_1680 3360 +#define Z_UTIL_X2_1681 3362 +#define Z_UTIL_X2_1682 3364 +#define Z_UTIL_X2_1683 3366 +#define Z_UTIL_X2_1684 3368 +#define Z_UTIL_X2_1685 3370 +#define Z_UTIL_X2_1686 3372 +#define Z_UTIL_X2_1687 3374 +#define Z_UTIL_X2_1688 3376 +#define Z_UTIL_X2_1689 3378 +#define Z_UTIL_X2_1690 3380 +#define Z_UTIL_X2_1691 3382 +#define Z_UTIL_X2_1692 3384 +#define Z_UTIL_X2_1693 3386 +#define Z_UTIL_X2_1694 3388 +#define Z_UTIL_X2_1695 3390 +#define Z_UTIL_X2_1696 3392 +#define Z_UTIL_X2_1697 3394 +#define Z_UTIL_X2_1698 3396 +#define Z_UTIL_X2_1699 3398 +#define Z_UTIL_X2_1700 3400 +#define Z_UTIL_X2_1701 3402 +#define Z_UTIL_X2_1702 3404 +#define Z_UTIL_X2_1703 3406 +#define Z_UTIL_X2_1704 3408 +#define Z_UTIL_X2_1705 3410 +#define Z_UTIL_X2_1706 3412 +#define Z_UTIL_X2_1707 3414 +#define Z_UTIL_X2_1708 3416 +#define Z_UTIL_X2_1709 3418 +#define Z_UTIL_X2_1710 3420 +#define Z_UTIL_X2_1711 3422 +#define Z_UTIL_X2_1712 3424 +#define Z_UTIL_X2_1713 3426 +#define Z_UTIL_X2_1714 3428 +#define Z_UTIL_X2_1715 3430 +#define Z_UTIL_X2_1716 3432 +#define Z_UTIL_X2_1717 3434 +#define Z_UTIL_X2_1718 3436 +#define Z_UTIL_X2_1719 3438 +#define Z_UTIL_X2_1720 3440 +#define Z_UTIL_X2_1721 3442 +#define Z_UTIL_X2_1722 3444 +#define Z_UTIL_X2_1723 3446 +#define Z_UTIL_X2_1724 3448 +#define Z_UTIL_X2_1725 3450 +#define Z_UTIL_X2_1726 3452 +#define Z_UTIL_X2_1727 3454 +#define Z_UTIL_X2_1728 3456 +#define Z_UTIL_X2_1729 3458 +#define Z_UTIL_X2_1730 3460 +#define Z_UTIL_X2_1731 3462 +#define Z_UTIL_X2_1732 3464 +#define Z_UTIL_X2_1733 3466 +#define Z_UTIL_X2_1734 3468 +#define Z_UTIL_X2_1735 3470 +#define Z_UTIL_X2_1736 3472 +#define Z_UTIL_X2_1737 3474 +#define Z_UTIL_X2_1738 3476 +#define Z_UTIL_X2_1739 3478 +#define Z_UTIL_X2_1740 3480 +#define Z_UTIL_X2_1741 3482 +#define Z_UTIL_X2_1742 3484 +#define Z_UTIL_X2_1743 3486 +#define Z_UTIL_X2_1744 3488 +#define Z_UTIL_X2_1745 3490 +#define Z_UTIL_X2_1746 3492 +#define Z_UTIL_X2_1747 3494 +#define Z_UTIL_X2_1748 3496 +#define Z_UTIL_X2_1749 3498 +#define Z_UTIL_X2_1750 3500 +#define Z_UTIL_X2_1751 3502 +#define Z_UTIL_X2_1752 3504 +#define Z_UTIL_X2_1753 3506 +#define Z_UTIL_X2_1754 3508 +#define Z_UTIL_X2_1755 3510 +#define Z_UTIL_X2_1756 3512 +#define Z_UTIL_X2_1757 3514 +#define Z_UTIL_X2_1758 3516 +#define Z_UTIL_X2_1759 3518 +#define Z_UTIL_X2_1760 3520 +#define Z_UTIL_X2_1761 3522 +#define Z_UTIL_X2_1762 3524 +#define Z_UTIL_X2_1763 3526 +#define Z_UTIL_X2_1764 3528 +#define Z_UTIL_X2_1765 3530 +#define Z_UTIL_X2_1766 3532 +#define Z_UTIL_X2_1767 3534 +#define Z_UTIL_X2_1768 3536 +#define Z_UTIL_X2_1769 3538 +#define Z_UTIL_X2_1770 3540 +#define Z_UTIL_X2_1771 3542 +#define Z_UTIL_X2_1772 3544 +#define Z_UTIL_X2_1773 3546 +#define Z_UTIL_X2_1774 3548 +#define Z_UTIL_X2_1775 3550 +#define Z_UTIL_X2_1776 3552 +#define Z_UTIL_X2_1777 3554 +#define Z_UTIL_X2_1778 3556 +#define Z_UTIL_X2_1779 3558 +#define Z_UTIL_X2_1780 3560 +#define Z_UTIL_X2_1781 3562 +#define Z_UTIL_X2_1782 3564 +#define Z_UTIL_X2_1783 3566 +#define Z_UTIL_X2_1784 3568 +#define Z_UTIL_X2_1785 3570 +#define Z_UTIL_X2_1786 3572 +#define Z_UTIL_X2_1787 3574 +#define Z_UTIL_X2_1788 3576 +#define Z_UTIL_X2_1789 3578 +#define Z_UTIL_X2_1790 3580 +#define Z_UTIL_X2_1791 3582 +#define Z_UTIL_X2_1792 3584 +#define Z_UTIL_X2_1793 3586 +#define Z_UTIL_X2_1794 3588 +#define Z_UTIL_X2_1795 3590 +#define Z_UTIL_X2_1796 3592 +#define Z_UTIL_X2_1797 3594 +#define Z_UTIL_X2_1798 3596 +#define Z_UTIL_X2_1799 3598 +#define Z_UTIL_X2_1800 3600 +#define Z_UTIL_X2_1801 3602 +#define Z_UTIL_X2_1802 3604 +#define Z_UTIL_X2_1803 3606 +#define Z_UTIL_X2_1804 3608 +#define Z_UTIL_X2_1805 3610 +#define Z_UTIL_X2_1806 3612 +#define Z_UTIL_X2_1807 3614 +#define Z_UTIL_X2_1808 3616 +#define Z_UTIL_X2_1809 3618 +#define Z_UTIL_X2_1810 3620 +#define Z_UTIL_X2_1811 3622 +#define Z_UTIL_X2_1812 3624 +#define Z_UTIL_X2_1813 3626 +#define Z_UTIL_X2_1814 3628 +#define Z_UTIL_X2_1815 3630 +#define Z_UTIL_X2_1816 3632 +#define Z_UTIL_X2_1817 3634 +#define Z_UTIL_X2_1818 3636 +#define Z_UTIL_X2_1819 3638 +#define Z_UTIL_X2_1820 3640 +#define Z_UTIL_X2_1821 3642 +#define Z_UTIL_X2_1822 3644 +#define Z_UTIL_X2_1823 3646 +#define Z_UTIL_X2_1824 3648 +#define Z_UTIL_X2_1825 3650 +#define Z_UTIL_X2_1826 3652 +#define Z_UTIL_X2_1827 3654 +#define Z_UTIL_X2_1828 3656 +#define Z_UTIL_X2_1829 3658 +#define Z_UTIL_X2_1830 3660 +#define Z_UTIL_X2_1831 3662 +#define Z_UTIL_X2_1832 3664 +#define Z_UTIL_X2_1833 3666 +#define Z_UTIL_X2_1834 3668 +#define Z_UTIL_X2_1835 3670 +#define Z_UTIL_X2_1836 3672 +#define Z_UTIL_X2_1837 3674 +#define Z_UTIL_X2_1838 3676 +#define Z_UTIL_X2_1839 3678 +#define Z_UTIL_X2_1840 3680 +#define Z_UTIL_X2_1841 3682 +#define Z_UTIL_X2_1842 3684 +#define Z_UTIL_X2_1843 3686 +#define Z_UTIL_X2_1844 3688 +#define Z_UTIL_X2_1845 3690 +#define Z_UTIL_X2_1846 3692 +#define Z_UTIL_X2_1847 3694 +#define Z_UTIL_X2_1848 3696 +#define Z_UTIL_X2_1849 3698 +#define Z_UTIL_X2_1850 3700 +#define Z_UTIL_X2_1851 3702 +#define Z_UTIL_X2_1852 3704 +#define Z_UTIL_X2_1853 3706 +#define Z_UTIL_X2_1854 3708 +#define Z_UTIL_X2_1855 3710 +#define Z_UTIL_X2_1856 3712 +#define Z_UTIL_X2_1857 3714 +#define Z_UTIL_X2_1858 3716 +#define Z_UTIL_X2_1859 3718 +#define Z_UTIL_X2_1860 3720 +#define Z_UTIL_X2_1861 3722 +#define Z_UTIL_X2_1862 3724 +#define Z_UTIL_X2_1863 3726 +#define Z_UTIL_X2_1864 3728 +#define Z_UTIL_X2_1865 3730 +#define Z_UTIL_X2_1866 3732 +#define Z_UTIL_X2_1867 3734 +#define Z_UTIL_X2_1868 3736 +#define Z_UTIL_X2_1869 3738 +#define Z_UTIL_X2_1870 3740 +#define Z_UTIL_X2_1871 3742 +#define Z_UTIL_X2_1872 3744 +#define Z_UTIL_X2_1873 3746 +#define Z_UTIL_X2_1874 3748 +#define Z_UTIL_X2_1875 3750 +#define Z_UTIL_X2_1876 3752 +#define Z_UTIL_X2_1877 3754 +#define Z_UTIL_X2_1878 3756 +#define Z_UTIL_X2_1879 3758 +#define Z_UTIL_X2_1880 3760 +#define Z_UTIL_X2_1881 3762 +#define Z_UTIL_X2_1882 3764 +#define Z_UTIL_X2_1883 3766 +#define Z_UTIL_X2_1884 3768 +#define Z_UTIL_X2_1885 3770 +#define Z_UTIL_X2_1886 3772 +#define Z_UTIL_X2_1887 3774 +#define Z_UTIL_X2_1888 3776 +#define Z_UTIL_X2_1889 3778 +#define Z_UTIL_X2_1890 3780 +#define Z_UTIL_X2_1891 3782 +#define Z_UTIL_X2_1892 3784 +#define Z_UTIL_X2_1893 3786 +#define Z_UTIL_X2_1894 3788 +#define Z_UTIL_X2_1895 3790 +#define Z_UTIL_X2_1896 3792 +#define Z_UTIL_X2_1897 3794 +#define Z_UTIL_X2_1898 3796 +#define Z_UTIL_X2_1899 3798 +#define Z_UTIL_X2_1900 3800 +#define Z_UTIL_X2_1901 3802 +#define Z_UTIL_X2_1902 3804 +#define Z_UTIL_X2_1903 3806 +#define Z_UTIL_X2_1904 3808 +#define Z_UTIL_X2_1905 3810 +#define Z_UTIL_X2_1906 3812 +#define Z_UTIL_X2_1907 3814 +#define Z_UTIL_X2_1908 3816 +#define Z_UTIL_X2_1909 3818 +#define Z_UTIL_X2_1910 3820 +#define Z_UTIL_X2_1911 3822 +#define Z_UTIL_X2_1912 3824 +#define Z_UTIL_X2_1913 3826 +#define Z_UTIL_X2_1914 3828 +#define Z_UTIL_X2_1915 3830 +#define Z_UTIL_X2_1916 3832 +#define Z_UTIL_X2_1917 3834 +#define Z_UTIL_X2_1918 3836 +#define Z_UTIL_X2_1919 3838 +#define Z_UTIL_X2_1920 3840 +#define Z_UTIL_X2_1921 3842 +#define Z_UTIL_X2_1922 3844 +#define Z_UTIL_X2_1923 3846 +#define Z_UTIL_X2_1924 3848 +#define Z_UTIL_X2_1925 3850 +#define Z_UTIL_X2_1926 3852 +#define Z_UTIL_X2_1927 3854 +#define Z_UTIL_X2_1928 3856 +#define Z_UTIL_X2_1929 3858 +#define Z_UTIL_X2_1930 3860 +#define Z_UTIL_X2_1931 3862 +#define Z_UTIL_X2_1932 3864 +#define Z_UTIL_X2_1933 3866 +#define Z_UTIL_X2_1934 3868 +#define Z_UTIL_X2_1935 3870 +#define Z_UTIL_X2_1936 3872 +#define Z_UTIL_X2_1937 3874 +#define Z_UTIL_X2_1938 3876 +#define Z_UTIL_X2_1939 3878 +#define Z_UTIL_X2_1940 3880 +#define Z_UTIL_X2_1941 3882 +#define Z_UTIL_X2_1942 3884 +#define Z_UTIL_X2_1943 3886 +#define Z_UTIL_X2_1944 3888 +#define Z_UTIL_X2_1945 3890 +#define Z_UTIL_X2_1946 3892 +#define Z_UTIL_X2_1947 3894 +#define Z_UTIL_X2_1948 3896 +#define Z_UTIL_X2_1949 3898 +#define Z_UTIL_X2_1950 3900 +#define Z_UTIL_X2_1951 3902 +#define Z_UTIL_X2_1952 3904 +#define Z_UTIL_X2_1953 3906 +#define Z_UTIL_X2_1954 3908 +#define Z_UTIL_X2_1955 3910 +#define Z_UTIL_X2_1956 3912 +#define Z_UTIL_X2_1957 3914 +#define Z_UTIL_X2_1958 3916 +#define Z_UTIL_X2_1959 3918 +#define Z_UTIL_X2_1960 3920 +#define Z_UTIL_X2_1961 3922 +#define Z_UTIL_X2_1962 3924 +#define Z_UTIL_X2_1963 3926 +#define Z_UTIL_X2_1964 3928 +#define Z_UTIL_X2_1965 3930 +#define Z_UTIL_X2_1966 3932 +#define Z_UTIL_X2_1967 3934 +#define Z_UTIL_X2_1968 3936 +#define Z_UTIL_X2_1969 3938 +#define Z_UTIL_X2_1970 3940 +#define Z_UTIL_X2_1971 3942 +#define Z_UTIL_X2_1972 3944 +#define Z_UTIL_X2_1973 3946 +#define Z_UTIL_X2_1974 3948 +#define Z_UTIL_X2_1975 3950 +#define Z_UTIL_X2_1976 3952 +#define Z_UTIL_X2_1977 3954 +#define Z_UTIL_X2_1978 3956 +#define Z_UTIL_X2_1979 3958 +#define Z_UTIL_X2_1980 3960 +#define Z_UTIL_X2_1981 3962 +#define Z_UTIL_X2_1982 3964 +#define Z_UTIL_X2_1983 3966 +#define Z_UTIL_X2_1984 3968 +#define Z_UTIL_X2_1985 3970 +#define Z_UTIL_X2_1986 3972 +#define Z_UTIL_X2_1987 3974 +#define Z_UTIL_X2_1988 3976 +#define Z_UTIL_X2_1989 3978 +#define Z_UTIL_X2_1990 3980 +#define Z_UTIL_X2_1991 3982 +#define Z_UTIL_X2_1992 3984 +#define Z_UTIL_X2_1993 3986 +#define Z_UTIL_X2_1994 3988 +#define Z_UTIL_X2_1995 3990 +#define Z_UTIL_X2_1996 3992 +#define Z_UTIL_X2_1997 3994 +#define Z_UTIL_X2_1998 3996 +#define Z_UTIL_X2_1999 3998 +#define Z_UTIL_X2_2000 4000 +#define Z_UTIL_X2_2001 4002 +#define Z_UTIL_X2_2002 4004 +#define Z_UTIL_X2_2003 4006 +#define Z_UTIL_X2_2004 4008 +#define Z_UTIL_X2_2005 4010 +#define Z_UTIL_X2_2006 4012 +#define Z_UTIL_X2_2007 4014 +#define Z_UTIL_X2_2008 4016 +#define Z_UTIL_X2_2009 4018 +#define Z_UTIL_X2_2010 4020 +#define Z_UTIL_X2_2011 4022 +#define Z_UTIL_X2_2012 4024 +#define Z_UTIL_X2_2013 4026 +#define Z_UTIL_X2_2014 4028 +#define Z_UTIL_X2_2015 4030 +#define Z_UTIL_X2_2016 4032 +#define Z_UTIL_X2_2017 4034 +#define Z_UTIL_X2_2018 4036 +#define Z_UTIL_X2_2019 4038 +#define Z_UTIL_X2_2020 4040 +#define Z_UTIL_X2_2021 4042 +#define Z_UTIL_X2_2022 4044 +#define Z_UTIL_X2_2023 4046 +#define Z_UTIL_X2_2024 4048 +#define Z_UTIL_X2_2025 4050 +#define Z_UTIL_X2_2026 4052 +#define Z_UTIL_X2_2027 4054 +#define Z_UTIL_X2_2028 4056 +#define Z_UTIL_X2_2029 4058 +#define Z_UTIL_X2_2030 4060 +#define Z_UTIL_X2_2031 4062 +#define Z_UTIL_X2_2032 4064 +#define Z_UTIL_X2_2033 4066 +#define Z_UTIL_X2_2034 4068 +#define Z_UTIL_X2_2035 4070 +#define Z_UTIL_X2_2036 4072 +#define Z_UTIL_X2_2037 4074 +#define Z_UTIL_X2_2038 4076 +#define Z_UTIL_X2_2039 4078 +#define Z_UTIL_X2_2040 4080 +#define Z_UTIL_X2_2041 4082 +#define Z_UTIL_X2_2042 4084 +#define Z_UTIL_X2_2043 4086 +#define Z_UTIL_X2_2044 4088 +#define Z_UTIL_X2_2045 4090 +#define Z_UTIL_X2_2046 4092 +#define Z_UTIL_X2_2047 4094 +#define Z_UTIL_X2_2048 4096 +#define Z_UTIL_X2_2049 4098 +#define Z_UTIL_X2_2050 4100 +#define Z_UTIL_X2_2051 4102 +#define Z_UTIL_X2_2052 4104 +#define Z_UTIL_X2_2053 4106 +#define Z_UTIL_X2_2054 4108 +#define Z_UTIL_X2_2055 4110 +#define Z_UTIL_X2_2056 4112 +#define Z_UTIL_X2_2057 4114 +#define Z_UTIL_X2_2058 4116 +#define Z_UTIL_X2_2059 4118 +#define Z_UTIL_X2_2060 4120 +#define Z_UTIL_X2_2061 4122 +#define Z_UTIL_X2_2062 4124 +#define Z_UTIL_X2_2063 4126 +#define Z_UTIL_X2_2064 4128 +#define Z_UTIL_X2_2065 4130 +#define Z_UTIL_X2_2066 4132 +#define Z_UTIL_X2_2067 4134 +#define Z_UTIL_X2_2068 4136 +#define Z_UTIL_X2_2069 4138 +#define Z_UTIL_X2_2070 4140 +#define Z_UTIL_X2_2071 4142 +#define Z_UTIL_X2_2072 4144 +#define Z_UTIL_X2_2073 4146 +#define Z_UTIL_X2_2074 4148 +#define Z_UTIL_X2_2075 4150 +#define Z_UTIL_X2_2076 4152 +#define Z_UTIL_X2_2077 4154 +#define Z_UTIL_X2_2078 4156 +#define Z_UTIL_X2_2079 4158 +#define Z_UTIL_X2_2080 4160 +#define Z_UTIL_X2_2081 4162 +#define Z_UTIL_X2_2082 4164 +#define Z_UTIL_X2_2083 4166 +#define Z_UTIL_X2_2084 4168 +#define Z_UTIL_X2_2085 4170 +#define Z_UTIL_X2_2086 4172 +#define Z_UTIL_X2_2087 4174 +#define Z_UTIL_X2_2088 4176 +#define Z_UTIL_X2_2089 4178 +#define Z_UTIL_X2_2090 4180 +#define Z_UTIL_X2_2091 4182 +#define Z_UTIL_X2_2092 4184 +#define Z_UTIL_X2_2093 4186 +#define Z_UTIL_X2_2094 4188 +#define Z_UTIL_X2_2095 4190 +#define Z_UTIL_X2_2096 4192 +#define Z_UTIL_X2_2097 4194 +#define Z_UTIL_X2_2098 4196 +#define Z_UTIL_X2_2099 4198 +#define Z_UTIL_X2_2100 4200 +#define Z_UTIL_X2_2101 4202 +#define Z_UTIL_X2_2102 4204 +#define Z_UTIL_X2_2103 4206 +#define Z_UTIL_X2_2104 4208 +#define Z_UTIL_X2_2105 4210 +#define Z_UTIL_X2_2106 4212 +#define Z_UTIL_X2_2107 4214 +#define Z_UTIL_X2_2108 4216 +#define Z_UTIL_X2_2109 4218 +#define Z_UTIL_X2_2110 4220 +#define Z_UTIL_X2_2111 4222 +#define Z_UTIL_X2_2112 4224 +#define Z_UTIL_X2_2113 4226 +#define Z_UTIL_X2_2114 4228 +#define Z_UTIL_X2_2115 4230 +#define Z_UTIL_X2_2116 4232 +#define Z_UTIL_X2_2117 4234 +#define Z_UTIL_X2_2118 4236 +#define Z_UTIL_X2_2119 4238 +#define Z_UTIL_X2_2120 4240 +#define Z_UTIL_X2_2121 4242 +#define Z_UTIL_X2_2122 4244 +#define Z_UTIL_X2_2123 4246 +#define Z_UTIL_X2_2124 4248 +#define Z_UTIL_X2_2125 4250 +#define Z_UTIL_X2_2126 4252 +#define Z_UTIL_X2_2127 4254 +#define Z_UTIL_X2_2128 4256 +#define Z_UTIL_X2_2129 4258 +#define Z_UTIL_X2_2130 4260 +#define Z_UTIL_X2_2131 4262 +#define Z_UTIL_X2_2132 4264 +#define Z_UTIL_X2_2133 4266 +#define Z_UTIL_X2_2134 4268 +#define Z_UTIL_X2_2135 4270 +#define Z_UTIL_X2_2136 4272 +#define Z_UTIL_X2_2137 4274 +#define Z_UTIL_X2_2138 4276 +#define Z_UTIL_X2_2139 4278 +#define Z_UTIL_X2_2140 4280 +#define Z_UTIL_X2_2141 4282 +#define Z_UTIL_X2_2142 4284 +#define Z_UTIL_X2_2143 4286 +#define Z_UTIL_X2_2144 4288 +#define Z_UTIL_X2_2145 4290 +#define Z_UTIL_X2_2146 4292 +#define Z_UTIL_X2_2147 4294 +#define Z_UTIL_X2_2148 4296 +#define Z_UTIL_X2_2149 4298 +#define Z_UTIL_X2_2150 4300 +#define Z_UTIL_X2_2151 4302 +#define Z_UTIL_X2_2152 4304 +#define Z_UTIL_X2_2153 4306 +#define Z_UTIL_X2_2154 4308 +#define Z_UTIL_X2_2155 4310 +#define Z_UTIL_X2_2156 4312 +#define Z_UTIL_X2_2157 4314 +#define Z_UTIL_X2_2158 4316 +#define Z_UTIL_X2_2159 4318 +#define Z_UTIL_X2_2160 4320 +#define Z_UTIL_X2_2161 4322 +#define Z_UTIL_X2_2162 4324 +#define Z_UTIL_X2_2163 4326 +#define Z_UTIL_X2_2164 4328 +#define Z_UTIL_X2_2165 4330 +#define Z_UTIL_X2_2166 4332 +#define Z_UTIL_X2_2167 4334 +#define Z_UTIL_X2_2168 4336 +#define Z_UTIL_X2_2169 4338 +#define Z_UTIL_X2_2170 4340 +#define Z_UTIL_X2_2171 4342 +#define Z_UTIL_X2_2172 4344 +#define Z_UTIL_X2_2173 4346 +#define Z_UTIL_X2_2174 4348 +#define Z_UTIL_X2_2175 4350 +#define Z_UTIL_X2_2176 4352 +#define Z_UTIL_X2_2177 4354 +#define Z_UTIL_X2_2178 4356 +#define Z_UTIL_X2_2179 4358 +#define Z_UTIL_X2_2180 4360 +#define Z_UTIL_X2_2181 4362 +#define Z_UTIL_X2_2182 4364 +#define Z_UTIL_X2_2183 4366 +#define Z_UTIL_X2_2184 4368 +#define Z_UTIL_X2_2185 4370 +#define Z_UTIL_X2_2186 4372 +#define Z_UTIL_X2_2187 4374 +#define Z_UTIL_X2_2188 4376 +#define Z_UTIL_X2_2189 4378 +#define Z_UTIL_X2_2190 4380 +#define Z_UTIL_X2_2191 4382 +#define Z_UTIL_X2_2192 4384 +#define Z_UTIL_X2_2193 4386 +#define Z_UTIL_X2_2194 4388 +#define Z_UTIL_X2_2195 4390 +#define Z_UTIL_X2_2196 4392 +#define Z_UTIL_X2_2197 4394 +#define Z_UTIL_X2_2198 4396 +#define Z_UTIL_X2_2199 4398 +#define Z_UTIL_X2_2200 4400 +#define Z_UTIL_X2_2201 4402 +#define Z_UTIL_X2_2202 4404 +#define Z_UTIL_X2_2203 4406 +#define Z_UTIL_X2_2204 4408 +#define Z_UTIL_X2_2205 4410 +#define Z_UTIL_X2_2206 4412 +#define Z_UTIL_X2_2207 4414 +#define Z_UTIL_X2_2208 4416 +#define Z_UTIL_X2_2209 4418 +#define Z_UTIL_X2_2210 4420 +#define Z_UTIL_X2_2211 4422 +#define Z_UTIL_X2_2212 4424 +#define Z_UTIL_X2_2213 4426 +#define Z_UTIL_X2_2214 4428 +#define Z_UTIL_X2_2215 4430 +#define Z_UTIL_X2_2216 4432 +#define Z_UTIL_X2_2217 4434 +#define Z_UTIL_X2_2218 4436 +#define Z_UTIL_X2_2219 4438 +#define Z_UTIL_X2_2220 4440 +#define Z_UTIL_X2_2221 4442 +#define Z_UTIL_X2_2222 4444 +#define Z_UTIL_X2_2223 4446 +#define Z_UTIL_X2_2224 4448 +#define Z_UTIL_X2_2225 4450 +#define Z_UTIL_X2_2226 4452 +#define Z_UTIL_X2_2227 4454 +#define Z_UTIL_X2_2228 4456 +#define Z_UTIL_X2_2229 4458 +#define Z_UTIL_X2_2230 4460 +#define Z_UTIL_X2_2231 4462 +#define Z_UTIL_X2_2232 4464 +#define Z_UTIL_X2_2233 4466 +#define Z_UTIL_X2_2234 4468 +#define Z_UTIL_X2_2235 4470 +#define Z_UTIL_X2_2236 4472 +#define Z_UTIL_X2_2237 4474 +#define Z_UTIL_X2_2238 4476 +#define Z_UTIL_X2_2239 4478 +#define Z_UTIL_X2_2240 4480 +#define Z_UTIL_X2_2241 4482 +#define Z_UTIL_X2_2242 4484 +#define Z_UTIL_X2_2243 4486 +#define Z_UTIL_X2_2244 4488 +#define Z_UTIL_X2_2245 4490 +#define Z_UTIL_X2_2246 4492 +#define Z_UTIL_X2_2247 4494 +#define Z_UTIL_X2_2248 4496 +#define Z_UTIL_X2_2249 4498 +#define Z_UTIL_X2_2250 4500 +#define Z_UTIL_X2_2251 4502 +#define Z_UTIL_X2_2252 4504 +#define Z_UTIL_X2_2253 4506 +#define Z_UTIL_X2_2254 4508 +#define Z_UTIL_X2_2255 4510 +#define Z_UTIL_X2_2256 4512 +#define Z_UTIL_X2_2257 4514 +#define Z_UTIL_X2_2258 4516 +#define Z_UTIL_X2_2259 4518 +#define Z_UTIL_X2_2260 4520 +#define Z_UTIL_X2_2261 4522 +#define Z_UTIL_X2_2262 4524 +#define Z_UTIL_X2_2263 4526 +#define Z_UTIL_X2_2264 4528 +#define Z_UTIL_X2_2265 4530 +#define Z_UTIL_X2_2266 4532 +#define Z_UTIL_X2_2267 4534 +#define Z_UTIL_X2_2268 4536 +#define Z_UTIL_X2_2269 4538 +#define Z_UTIL_X2_2270 4540 +#define Z_UTIL_X2_2271 4542 +#define Z_UTIL_X2_2272 4544 +#define Z_UTIL_X2_2273 4546 +#define Z_UTIL_X2_2274 4548 +#define Z_UTIL_X2_2275 4550 +#define Z_UTIL_X2_2276 4552 +#define Z_UTIL_X2_2277 4554 +#define Z_UTIL_X2_2278 4556 +#define Z_UTIL_X2_2279 4558 +#define Z_UTIL_X2_2280 4560 +#define Z_UTIL_X2_2281 4562 +#define Z_UTIL_X2_2282 4564 +#define Z_UTIL_X2_2283 4566 +#define Z_UTIL_X2_2284 4568 +#define Z_UTIL_X2_2285 4570 +#define Z_UTIL_X2_2286 4572 +#define Z_UTIL_X2_2287 4574 +#define Z_UTIL_X2_2288 4576 +#define Z_UTIL_X2_2289 4578 +#define Z_UTIL_X2_2290 4580 +#define Z_UTIL_X2_2291 4582 +#define Z_UTIL_X2_2292 4584 +#define Z_UTIL_X2_2293 4586 +#define Z_UTIL_X2_2294 4588 +#define Z_UTIL_X2_2295 4590 +#define Z_UTIL_X2_2296 4592 +#define Z_UTIL_X2_2297 4594 +#define Z_UTIL_X2_2298 4596 +#define Z_UTIL_X2_2299 4598 +#define Z_UTIL_X2_2300 4600 +#define Z_UTIL_X2_2301 4602 +#define Z_UTIL_X2_2302 4604 +#define Z_UTIL_X2_2303 4606 +#define Z_UTIL_X2_2304 4608 +#define Z_UTIL_X2_2305 4610 +#define Z_UTIL_X2_2306 4612 +#define Z_UTIL_X2_2307 4614 +#define Z_UTIL_X2_2308 4616 +#define Z_UTIL_X2_2309 4618 +#define Z_UTIL_X2_2310 4620 +#define Z_UTIL_X2_2311 4622 +#define Z_UTIL_X2_2312 4624 +#define Z_UTIL_X2_2313 4626 +#define Z_UTIL_X2_2314 4628 +#define Z_UTIL_X2_2315 4630 +#define Z_UTIL_X2_2316 4632 +#define Z_UTIL_X2_2317 4634 +#define Z_UTIL_X2_2318 4636 +#define Z_UTIL_X2_2319 4638 +#define Z_UTIL_X2_2320 4640 +#define Z_UTIL_X2_2321 4642 +#define Z_UTIL_X2_2322 4644 +#define Z_UTIL_X2_2323 4646 +#define Z_UTIL_X2_2324 4648 +#define Z_UTIL_X2_2325 4650 +#define Z_UTIL_X2_2326 4652 +#define Z_UTIL_X2_2327 4654 +#define Z_UTIL_X2_2328 4656 +#define Z_UTIL_X2_2329 4658 +#define Z_UTIL_X2_2330 4660 +#define Z_UTIL_X2_2331 4662 +#define Z_UTIL_X2_2332 4664 +#define Z_UTIL_X2_2333 4666 +#define Z_UTIL_X2_2334 4668 +#define Z_UTIL_X2_2335 4670 +#define Z_UTIL_X2_2336 4672 +#define Z_UTIL_X2_2337 4674 +#define Z_UTIL_X2_2338 4676 +#define Z_UTIL_X2_2339 4678 +#define Z_UTIL_X2_2340 4680 +#define Z_UTIL_X2_2341 4682 +#define Z_UTIL_X2_2342 4684 +#define Z_UTIL_X2_2343 4686 +#define Z_UTIL_X2_2344 4688 +#define Z_UTIL_X2_2345 4690 +#define Z_UTIL_X2_2346 4692 +#define Z_UTIL_X2_2347 4694 +#define Z_UTIL_X2_2348 4696 +#define Z_UTIL_X2_2349 4698 +#define Z_UTIL_X2_2350 4700 +#define Z_UTIL_X2_2351 4702 +#define Z_UTIL_X2_2352 4704 +#define Z_UTIL_X2_2353 4706 +#define Z_UTIL_X2_2354 4708 +#define Z_UTIL_X2_2355 4710 +#define Z_UTIL_X2_2356 4712 +#define Z_UTIL_X2_2357 4714 +#define Z_UTIL_X2_2358 4716 +#define Z_UTIL_X2_2359 4718 +#define Z_UTIL_X2_2360 4720 +#define Z_UTIL_X2_2361 4722 +#define Z_UTIL_X2_2362 4724 +#define Z_UTIL_X2_2363 4726 +#define Z_UTIL_X2_2364 4728 +#define Z_UTIL_X2_2365 4730 +#define Z_UTIL_X2_2366 4732 +#define Z_UTIL_X2_2367 4734 +#define Z_UTIL_X2_2368 4736 +#define Z_UTIL_X2_2369 4738 +#define Z_UTIL_X2_2370 4740 +#define Z_UTIL_X2_2371 4742 +#define Z_UTIL_X2_2372 4744 +#define Z_UTIL_X2_2373 4746 +#define Z_UTIL_X2_2374 4748 +#define Z_UTIL_X2_2375 4750 +#define Z_UTIL_X2_2376 4752 +#define Z_UTIL_X2_2377 4754 +#define Z_UTIL_X2_2378 4756 +#define Z_UTIL_X2_2379 4758 +#define Z_UTIL_X2_2380 4760 +#define Z_UTIL_X2_2381 4762 +#define Z_UTIL_X2_2382 4764 +#define Z_UTIL_X2_2383 4766 +#define Z_UTIL_X2_2384 4768 +#define Z_UTIL_X2_2385 4770 +#define Z_UTIL_X2_2386 4772 +#define Z_UTIL_X2_2387 4774 +#define Z_UTIL_X2_2388 4776 +#define Z_UTIL_X2_2389 4778 +#define Z_UTIL_X2_2390 4780 +#define Z_UTIL_X2_2391 4782 +#define Z_UTIL_X2_2392 4784 +#define Z_UTIL_X2_2393 4786 +#define Z_UTIL_X2_2394 4788 +#define Z_UTIL_X2_2395 4790 +#define Z_UTIL_X2_2396 4792 +#define Z_UTIL_X2_2397 4794 +#define Z_UTIL_X2_2398 4796 +#define Z_UTIL_X2_2399 4798 +#define Z_UTIL_X2_2400 4800 +#define Z_UTIL_X2_2401 4802 +#define Z_UTIL_X2_2402 4804 +#define Z_UTIL_X2_2403 4806 +#define Z_UTIL_X2_2404 4808 +#define Z_UTIL_X2_2405 4810 +#define Z_UTIL_X2_2406 4812 +#define Z_UTIL_X2_2407 4814 +#define Z_UTIL_X2_2408 4816 +#define Z_UTIL_X2_2409 4818 +#define Z_UTIL_X2_2410 4820 +#define Z_UTIL_X2_2411 4822 +#define Z_UTIL_X2_2412 4824 +#define Z_UTIL_X2_2413 4826 +#define Z_UTIL_X2_2414 4828 +#define Z_UTIL_X2_2415 4830 +#define Z_UTIL_X2_2416 4832 +#define Z_UTIL_X2_2417 4834 +#define Z_UTIL_X2_2418 4836 +#define Z_UTIL_X2_2419 4838 +#define Z_UTIL_X2_2420 4840 +#define Z_UTIL_X2_2421 4842 +#define Z_UTIL_X2_2422 4844 +#define Z_UTIL_X2_2423 4846 +#define Z_UTIL_X2_2424 4848 +#define Z_UTIL_X2_2425 4850 +#define Z_UTIL_X2_2426 4852 +#define Z_UTIL_X2_2427 4854 +#define Z_UTIL_X2_2428 4856 +#define Z_UTIL_X2_2429 4858 +#define Z_UTIL_X2_2430 4860 +#define Z_UTIL_X2_2431 4862 +#define Z_UTIL_X2_2432 4864 +#define Z_UTIL_X2_2433 4866 +#define Z_UTIL_X2_2434 4868 +#define Z_UTIL_X2_2435 4870 +#define Z_UTIL_X2_2436 4872 +#define Z_UTIL_X2_2437 4874 +#define Z_UTIL_X2_2438 4876 +#define Z_UTIL_X2_2439 4878 +#define Z_UTIL_X2_2440 4880 +#define Z_UTIL_X2_2441 4882 +#define Z_UTIL_X2_2442 4884 +#define Z_UTIL_X2_2443 4886 +#define Z_UTIL_X2_2444 4888 +#define Z_UTIL_X2_2445 4890 +#define Z_UTIL_X2_2446 4892 +#define Z_UTIL_X2_2447 4894 +#define Z_UTIL_X2_2448 4896 +#define Z_UTIL_X2_2449 4898 +#define Z_UTIL_X2_2450 4900 +#define Z_UTIL_X2_2451 4902 +#define Z_UTIL_X2_2452 4904 +#define Z_UTIL_X2_2453 4906 +#define Z_UTIL_X2_2454 4908 +#define Z_UTIL_X2_2455 4910 +#define Z_UTIL_X2_2456 4912 +#define Z_UTIL_X2_2457 4914 +#define Z_UTIL_X2_2458 4916 +#define Z_UTIL_X2_2459 4918 +#define Z_UTIL_X2_2460 4920 +#define Z_UTIL_X2_2461 4922 +#define Z_UTIL_X2_2462 4924 +#define Z_UTIL_X2_2463 4926 +#define Z_UTIL_X2_2464 4928 +#define Z_UTIL_X2_2465 4930 +#define Z_UTIL_X2_2466 4932 +#define Z_UTIL_X2_2467 4934 +#define Z_UTIL_X2_2468 4936 +#define Z_UTIL_X2_2469 4938 +#define Z_UTIL_X2_2470 4940 +#define Z_UTIL_X2_2471 4942 +#define Z_UTIL_X2_2472 4944 +#define Z_UTIL_X2_2473 4946 +#define Z_UTIL_X2_2474 4948 +#define Z_UTIL_X2_2475 4950 +#define Z_UTIL_X2_2476 4952 +#define Z_UTIL_X2_2477 4954 +#define Z_UTIL_X2_2478 4956 +#define Z_UTIL_X2_2479 4958 +#define Z_UTIL_X2_2480 4960 +#define Z_UTIL_X2_2481 4962 +#define Z_UTIL_X2_2482 4964 +#define Z_UTIL_X2_2483 4966 +#define Z_UTIL_X2_2484 4968 +#define Z_UTIL_X2_2485 4970 +#define Z_UTIL_X2_2486 4972 +#define Z_UTIL_X2_2487 4974 +#define Z_UTIL_X2_2488 4976 +#define Z_UTIL_X2_2489 4978 +#define Z_UTIL_X2_2490 4980 +#define Z_UTIL_X2_2491 4982 +#define Z_UTIL_X2_2492 4984 +#define Z_UTIL_X2_2493 4986 +#define Z_UTIL_X2_2494 4988 +#define Z_UTIL_X2_2495 4990 +#define Z_UTIL_X2_2496 4992 +#define Z_UTIL_X2_2497 4994 +#define Z_UTIL_X2_2498 4996 +#define Z_UTIL_X2_2499 4998 +#define Z_UTIL_X2_2500 5000 +#define Z_UTIL_X2_2501 5002 +#define Z_UTIL_X2_2502 5004 +#define Z_UTIL_X2_2503 5006 +#define Z_UTIL_X2_2504 5008 +#define Z_UTIL_X2_2505 5010 +#define Z_UTIL_X2_2506 5012 +#define Z_UTIL_X2_2507 5014 +#define Z_UTIL_X2_2508 5016 +#define Z_UTIL_X2_2509 5018 +#define Z_UTIL_X2_2510 5020 +#define Z_UTIL_X2_2511 5022 +#define Z_UTIL_X2_2512 5024 +#define Z_UTIL_X2_2513 5026 +#define Z_UTIL_X2_2514 5028 +#define Z_UTIL_X2_2515 5030 +#define Z_UTIL_X2_2516 5032 +#define Z_UTIL_X2_2517 5034 +#define Z_UTIL_X2_2518 5036 +#define Z_UTIL_X2_2519 5038 +#define Z_UTIL_X2_2520 5040 +#define Z_UTIL_X2_2521 5042 +#define Z_UTIL_X2_2522 5044 +#define Z_UTIL_X2_2523 5046 +#define Z_UTIL_X2_2524 5048 +#define Z_UTIL_X2_2525 5050 +#define Z_UTIL_X2_2526 5052 +#define Z_UTIL_X2_2527 5054 +#define Z_UTIL_X2_2528 5056 +#define Z_UTIL_X2_2529 5058 +#define Z_UTIL_X2_2530 5060 +#define Z_UTIL_X2_2531 5062 +#define Z_UTIL_X2_2532 5064 +#define Z_UTIL_X2_2533 5066 +#define Z_UTIL_X2_2534 5068 +#define Z_UTIL_X2_2535 5070 +#define Z_UTIL_X2_2536 5072 +#define Z_UTIL_X2_2537 5074 +#define Z_UTIL_X2_2538 5076 +#define Z_UTIL_X2_2539 5078 +#define Z_UTIL_X2_2540 5080 +#define Z_UTIL_X2_2541 5082 +#define Z_UTIL_X2_2542 5084 +#define Z_UTIL_X2_2543 5086 +#define Z_UTIL_X2_2544 5088 +#define Z_UTIL_X2_2545 5090 +#define Z_UTIL_X2_2546 5092 +#define Z_UTIL_X2_2547 5094 +#define Z_UTIL_X2_2548 5096 +#define Z_UTIL_X2_2549 5098 +#define Z_UTIL_X2_2550 5100 +#define Z_UTIL_X2_2551 5102 +#define Z_UTIL_X2_2552 5104 +#define Z_UTIL_X2_2553 5106 +#define Z_UTIL_X2_2554 5108 +#define Z_UTIL_X2_2555 5110 +#define Z_UTIL_X2_2556 5112 +#define Z_UTIL_X2_2557 5114 +#define Z_UTIL_X2_2558 5116 +#define Z_UTIL_X2_2559 5118 +#define Z_UTIL_X2_2560 5120 +#define Z_UTIL_X2_2561 5122 +#define Z_UTIL_X2_2562 5124 +#define Z_UTIL_X2_2563 5126 +#define Z_UTIL_X2_2564 5128 +#define Z_UTIL_X2_2565 5130 +#define Z_UTIL_X2_2566 5132 +#define Z_UTIL_X2_2567 5134 +#define Z_UTIL_X2_2568 5136 +#define Z_UTIL_X2_2569 5138 +#define Z_UTIL_X2_2570 5140 +#define Z_UTIL_X2_2571 5142 +#define Z_UTIL_X2_2572 5144 +#define Z_UTIL_X2_2573 5146 +#define Z_UTIL_X2_2574 5148 +#define Z_UTIL_X2_2575 5150 +#define Z_UTIL_X2_2576 5152 +#define Z_UTIL_X2_2577 5154 +#define Z_UTIL_X2_2578 5156 +#define Z_UTIL_X2_2579 5158 +#define Z_UTIL_X2_2580 5160 +#define Z_UTIL_X2_2581 5162 +#define Z_UTIL_X2_2582 5164 +#define Z_UTIL_X2_2583 5166 +#define Z_UTIL_X2_2584 5168 +#define Z_UTIL_X2_2585 5170 +#define Z_UTIL_X2_2586 5172 +#define Z_UTIL_X2_2587 5174 +#define Z_UTIL_X2_2588 5176 +#define Z_UTIL_X2_2589 5178 +#define Z_UTIL_X2_2590 5180 +#define Z_UTIL_X2_2591 5182 +#define Z_UTIL_X2_2592 5184 +#define Z_UTIL_X2_2593 5186 +#define Z_UTIL_X2_2594 5188 +#define Z_UTIL_X2_2595 5190 +#define Z_UTIL_X2_2596 5192 +#define Z_UTIL_X2_2597 5194 +#define Z_UTIL_X2_2598 5196 +#define Z_UTIL_X2_2599 5198 +#define Z_UTIL_X2_2600 5200 +#define Z_UTIL_X2_2601 5202 +#define Z_UTIL_X2_2602 5204 +#define Z_UTIL_X2_2603 5206 +#define Z_UTIL_X2_2604 5208 +#define Z_UTIL_X2_2605 5210 +#define Z_UTIL_X2_2606 5212 +#define Z_UTIL_X2_2607 5214 +#define Z_UTIL_X2_2608 5216 +#define Z_UTIL_X2_2609 5218 +#define Z_UTIL_X2_2610 5220 +#define Z_UTIL_X2_2611 5222 +#define Z_UTIL_X2_2612 5224 +#define Z_UTIL_X2_2613 5226 +#define Z_UTIL_X2_2614 5228 +#define Z_UTIL_X2_2615 5230 +#define Z_UTIL_X2_2616 5232 +#define Z_UTIL_X2_2617 5234 +#define Z_UTIL_X2_2618 5236 +#define Z_UTIL_X2_2619 5238 +#define Z_UTIL_X2_2620 5240 +#define Z_UTIL_X2_2621 5242 +#define Z_UTIL_X2_2622 5244 +#define Z_UTIL_X2_2623 5246 +#define Z_UTIL_X2_2624 5248 +#define Z_UTIL_X2_2625 5250 +#define Z_UTIL_X2_2626 5252 +#define Z_UTIL_X2_2627 5254 +#define Z_UTIL_X2_2628 5256 +#define Z_UTIL_X2_2629 5258 +#define Z_UTIL_X2_2630 5260 +#define Z_UTIL_X2_2631 5262 +#define Z_UTIL_X2_2632 5264 +#define Z_UTIL_X2_2633 5266 +#define Z_UTIL_X2_2634 5268 +#define Z_UTIL_X2_2635 5270 +#define Z_UTIL_X2_2636 5272 +#define Z_UTIL_X2_2637 5274 +#define Z_UTIL_X2_2638 5276 +#define Z_UTIL_X2_2639 5278 +#define Z_UTIL_X2_2640 5280 +#define Z_UTIL_X2_2641 5282 +#define Z_UTIL_X2_2642 5284 +#define Z_UTIL_X2_2643 5286 +#define Z_UTIL_X2_2644 5288 +#define Z_UTIL_X2_2645 5290 +#define Z_UTIL_X2_2646 5292 +#define Z_UTIL_X2_2647 5294 +#define Z_UTIL_X2_2648 5296 +#define Z_UTIL_X2_2649 5298 +#define Z_UTIL_X2_2650 5300 +#define Z_UTIL_X2_2651 5302 +#define Z_UTIL_X2_2652 5304 +#define Z_UTIL_X2_2653 5306 +#define Z_UTIL_X2_2654 5308 +#define Z_UTIL_X2_2655 5310 +#define Z_UTIL_X2_2656 5312 +#define Z_UTIL_X2_2657 5314 +#define Z_UTIL_X2_2658 5316 +#define Z_UTIL_X2_2659 5318 +#define Z_UTIL_X2_2660 5320 +#define Z_UTIL_X2_2661 5322 +#define Z_UTIL_X2_2662 5324 +#define Z_UTIL_X2_2663 5326 +#define Z_UTIL_X2_2664 5328 +#define Z_UTIL_X2_2665 5330 +#define Z_UTIL_X2_2666 5332 +#define Z_UTIL_X2_2667 5334 +#define Z_UTIL_X2_2668 5336 +#define Z_UTIL_X2_2669 5338 +#define Z_UTIL_X2_2670 5340 +#define Z_UTIL_X2_2671 5342 +#define Z_UTIL_X2_2672 5344 +#define Z_UTIL_X2_2673 5346 +#define Z_UTIL_X2_2674 5348 +#define Z_UTIL_X2_2675 5350 +#define Z_UTIL_X2_2676 5352 +#define Z_UTIL_X2_2677 5354 +#define Z_UTIL_X2_2678 5356 +#define Z_UTIL_X2_2679 5358 +#define Z_UTIL_X2_2680 5360 +#define Z_UTIL_X2_2681 5362 +#define Z_UTIL_X2_2682 5364 +#define Z_UTIL_X2_2683 5366 +#define Z_UTIL_X2_2684 5368 +#define Z_UTIL_X2_2685 5370 +#define Z_UTIL_X2_2686 5372 +#define Z_UTIL_X2_2687 5374 +#define Z_UTIL_X2_2688 5376 +#define Z_UTIL_X2_2689 5378 +#define Z_UTIL_X2_2690 5380 +#define Z_UTIL_X2_2691 5382 +#define Z_UTIL_X2_2692 5384 +#define Z_UTIL_X2_2693 5386 +#define Z_UTIL_X2_2694 5388 +#define Z_UTIL_X2_2695 5390 +#define Z_UTIL_X2_2696 5392 +#define Z_UTIL_X2_2697 5394 +#define Z_UTIL_X2_2698 5396 +#define Z_UTIL_X2_2699 5398 +#define Z_UTIL_X2_2700 5400 +#define Z_UTIL_X2_2701 5402 +#define Z_UTIL_X2_2702 5404 +#define Z_UTIL_X2_2703 5406 +#define Z_UTIL_X2_2704 5408 +#define Z_UTIL_X2_2705 5410 +#define Z_UTIL_X2_2706 5412 +#define Z_UTIL_X2_2707 5414 +#define Z_UTIL_X2_2708 5416 +#define Z_UTIL_X2_2709 5418 +#define Z_UTIL_X2_2710 5420 +#define Z_UTIL_X2_2711 5422 +#define Z_UTIL_X2_2712 5424 +#define Z_UTIL_X2_2713 5426 +#define Z_UTIL_X2_2714 5428 +#define Z_UTIL_X2_2715 5430 +#define Z_UTIL_X2_2716 5432 +#define Z_UTIL_X2_2717 5434 +#define Z_UTIL_X2_2718 5436 +#define Z_UTIL_X2_2719 5438 +#define Z_UTIL_X2_2720 5440 +#define Z_UTIL_X2_2721 5442 +#define Z_UTIL_X2_2722 5444 +#define Z_UTIL_X2_2723 5446 +#define Z_UTIL_X2_2724 5448 +#define Z_UTIL_X2_2725 5450 +#define Z_UTIL_X2_2726 5452 +#define Z_UTIL_X2_2727 5454 +#define Z_UTIL_X2_2728 5456 +#define Z_UTIL_X2_2729 5458 +#define Z_UTIL_X2_2730 5460 +#define Z_UTIL_X2_2731 5462 +#define Z_UTIL_X2_2732 5464 +#define Z_UTIL_X2_2733 5466 +#define Z_UTIL_X2_2734 5468 +#define Z_UTIL_X2_2735 5470 +#define Z_UTIL_X2_2736 5472 +#define Z_UTIL_X2_2737 5474 +#define Z_UTIL_X2_2738 5476 +#define Z_UTIL_X2_2739 5478 +#define Z_UTIL_X2_2740 5480 +#define Z_UTIL_X2_2741 5482 +#define Z_UTIL_X2_2742 5484 +#define Z_UTIL_X2_2743 5486 +#define Z_UTIL_X2_2744 5488 +#define Z_UTIL_X2_2745 5490 +#define Z_UTIL_X2_2746 5492 +#define Z_UTIL_X2_2747 5494 +#define Z_UTIL_X2_2748 5496 +#define Z_UTIL_X2_2749 5498 +#define Z_UTIL_X2_2750 5500 +#define Z_UTIL_X2_2751 5502 +#define Z_UTIL_X2_2752 5504 +#define Z_UTIL_X2_2753 5506 +#define Z_UTIL_X2_2754 5508 +#define Z_UTIL_X2_2755 5510 +#define Z_UTIL_X2_2756 5512 +#define Z_UTIL_X2_2757 5514 +#define Z_UTIL_X2_2758 5516 +#define Z_UTIL_X2_2759 5518 +#define Z_UTIL_X2_2760 5520 +#define Z_UTIL_X2_2761 5522 +#define Z_UTIL_X2_2762 5524 +#define Z_UTIL_X2_2763 5526 +#define Z_UTIL_X2_2764 5528 +#define Z_UTIL_X2_2765 5530 +#define Z_UTIL_X2_2766 5532 +#define Z_UTIL_X2_2767 5534 +#define Z_UTIL_X2_2768 5536 +#define Z_UTIL_X2_2769 5538 +#define Z_UTIL_X2_2770 5540 +#define Z_UTIL_X2_2771 5542 +#define Z_UTIL_X2_2772 5544 +#define Z_UTIL_X2_2773 5546 +#define Z_UTIL_X2_2774 5548 +#define Z_UTIL_X2_2775 5550 +#define Z_UTIL_X2_2776 5552 +#define Z_UTIL_X2_2777 5554 +#define Z_UTIL_X2_2778 5556 +#define Z_UTIL_X2_2779 5558 +#define Z_UTIL_X2_2780 5560 +#define Z_UTIL_X2_2781 5562 +#define Z_UTIL_X2_2782 5564 +#define Z_UTIL_X2_2783 5566 +#define Z_UTIL_X2_2784 5568 +#define Z_UTIL_X2_2785 5570 +#define Z_UTIL_X2_2786 5572 +#define Z_UTIL_X2_2787 5574 +#define Z_UTIL_X2_2788 5576 +#define Z_UTIL_X2_2789 5578 +#define Z_UTIL_X2_2790 5580 +#define Z_UTIL_X2_2791 5582 +#define Z_UTIL_X2_2792 5584 +#define Z_UTIL_X2_2793 5586 +#define Z_UTIL_X2_2794 5588 +#define Z_UTIL_X2_2795 5590 +#define Z_UTIL_X2_2796 5592 +#define Z_UTIL_X2_2797 5594 +#define Z_UTIL_X2_2798 5596 +#define Z_UTIL_X2_2799 5598 +#define Z_UTIL_X2_2800 5600 +#define Z_UTIL_X2_2801 5602 +#define Z_UTIL_X2_2802 5604 +#define Z_UTIL_X2_2803 5606 +#define Z_UTIL_X2_2804 5608 +#define Z_UTIL_X2_2805 5610 +#define Z_UTIL_X2_2806 5612 +#define Z_UTIL_X2_2807 5614 +#define Z_UTIL_X2_2808 5616 +#define Z_UTIL_X2_2809 5618 +#define Z_UTIL_X2_2810 5620 +#define Z_UTIL_X2_2811 5622 +#define Z_UTIL_X2_2812 5624 +#define Z_UTIL_X2_2813 5626 +#define Z_UTIL_X2_2814 5628 +#define Z_UTIL_X2_2815 5630 +#define Z_UTIL_X2_2816 5632 +#define Z_UTIL_X2_2817 5634 +#define Z_UTIL_X2_2818 5636 +#define Z_UTIL_X2_2819 5638 +#define Z_UTIL_X2_2820 5640 +#define Z_UTIL_X2_2821 5642 +#define Z_UTIL_X2_2822 5644 +#define Z_UTIL_X2_2823 5646 +#define Z_UTIL_X2_2824 5648 +#define Z_UTIL_X2_2825 5650 +#define Z_UTIL_X2_2826 5652 +#define Z_UTIL_X2_2827 5654 +#define Z_UTIL_X2_2828 5656 +#define Z_UTIL_X2_2829 5658 +#define Z_UTIL_X2_2830 5660 +#define Z_UTIL_X2_2831 5662 +#define Z_UTIL_X2_2832 5664 +#define Z_UTIL_X2_2833 5666 +#define Z_UTIL_X2_2834 5668 +#define Z_UTIL_X2_2835 5670 +#define Z_UTIL_X2_2836 5672 +#define Z_UTIL_X2_2837 5674 +#define Z_UTIL_X2_2838 5676 +#define Z_UTIL_X2_2839 5678 +#define Z_UTIL_X2_2840 5680 +#define Z_UTIL_X2_2841 5682 +#define Z_UTIL_X2_2842 5684 +#define Z_UTIL_X2_2843 5686 +#define Z_UTIL_X2_2844 5688 +#define Z_UTIL_X2_2845 5690 +#define Z_UTIL_X2_2846 5692 +#define Z_UTIL_X2_2847 5694 +#define Z_UTIL_X2_2848 5696 +#define Z_UTIL_X2_2849 5698 +#define Z_UTIL_X2_2850 5700 +#define Z_UTIL_X2_2851 5702 +#define Z_UTIL_X2_2852 5704 +#define Z_UTIL_X2_2853 5706 +#define Z_UTIL_X2_2854 5708 +#define Z_UTIL_X2_2855 5710 +#define Z_UTIL_X2_2856 5712 +#define Z_UTIL_X2_2857 5714 +#define Z_UTIL_X2_2858 5716 +#define Z_UTIL_X2_2859 5718 +#define Z_UTIL_X2_2860 5720 +#define Z_UTIL_X2_2861 5722 +#define Z_UTIL_X2_2862 5724 +#define Z_UTIL_X2_2863 5726 +#define Z_UTIL_X2_2864 5728 +#define Z_UTIL_X2_2865 5730 +#define Z_UTIL_X2_2866 5732 +#define Z_UTIL_X2_2867 5734 +#define Z_UTIL_X2_2868 5736 +#define Z_UTIL_X2_2869 5738 +#define Z_UTIL_X2_2870 5740 +#define Z_UTIL_X2_2871 5742 +#define Z_UTIL_X2_2872 5744 +#define Z_UTIL_X2_2873 5746 +#define Z_UTIL_X2_2874 5748 +#define Z_UTIL_X2_2875 5750 +#define Z_UTIL_X2_2876 5752 +#define Z_UTIL_X2_2877 5754 +#define Z_UTIL_X2_2878 5756 +#define Z_UTIL_X2_2879 5758 +#define Z_UTIL_X2_2880 5760 +#define Z_UTIL_X2_2881 5762 +#define Z_UTIL_X2_2882 5764 +#define Z_UTIL_X2_2883 5766 +#define Z_UTIL_X2_2884 5768 +#define Z_UTIL_X2_2885 5770 +#define Z_UTIL_X2_2886 5772 +#define Z_UTIL_X2_2887 5774 +#define Z_UTIL_X2_2888 5776 +#define Z_UTIL_X2_2889 5778 +#define Z_UTIL_X2_2890 5780 +#define Z_UTIL_X2_2891 5782 +#define Z_UTIL_X2_2892 5784 +#define Z_UTIL_X2_2893 5786 +#define Z_UTIL_X2_2894 5788 +#define Z_UTIL_X2_2895 5790 +#define Z_UTIL_X2_2896 5792 +#define Z_UTIL_X2_2897 5794 +#define Z_UTIL_X2_2898 5796 +#define Z_UTIL_X2_2899 5798 +#define Z_UTIL_X2_2900 5800 +#define Z_UTIL_X2_2901 5802 +#define Z_UTIL_X2_2902 5804 +#define Z_UTIL_X2_2903 5806 +#define Z_UTIL_X2_2904 5808 +#define Z_UTIL_X2_2905 5810 +#define Z_UTIL_X2_2906 5812 +#define Z_UTIL_X2_2907 5814 +#define Z_UTIL_X2_2908 5816 +#define Z_UTIL_X2_2909 5818 +#define Z_UTIL_X2_2910 5820 +#define Z_UTIL_X2_2911 5822 +#define Z_UTIL_X2_2912 5824 +#define Z_UTIL_X2_2913 5826 +#define Z_UTIL_X2_2914 5828 +#define Z_UTIL_X2_2915 5830 +#define Z_UTIL_X2_2916 5832 +#define Z_UTIL_X2_2917 5834 +#define Z_UTIL_X2_2918 5836 +#define Z_UTIL_X2_2919 5838 +#define Z_UTIL_X2_2920 5840 +#define Z_UTIL_X2_2921 5842 +#define Z_UTIL_X2_2922 5844 +#define Z_UTIL_X2_2923 5846 +#define Z_UTIL_X2_2924 5848 +#define Z_UTIL_X2_2925 5850 +#define Z_UTIL_X2_2926 5852 +#define Z_UTIL_X2_2927 5854 +#define Z_UTIL_X2_2928 5856 +#define Z_UTIL_X2_2929 5858 +#define Z_UTIL_X2_2930 5860 +#define Z_UTIL_X2_2931 5862 +#define Z_UTIL_X2_2932 5864 +#define Z_UTIL_X2_2933 5866 +#define Z_UTIL_X2_2934 5868 +#define Z_UTIL_X2_2935 5870 +#define Z_UTIL_X2_2936 5872 +#define Z_UTIL_X2_2937 5874 +#define Z_UTIL_X2_2938 5876 +#define Z_UTIL_X2_2939 5878 +#define Z_UTIL_X2_2940 5880 +#define Z_UTIL_X2_2941 5882 +#define Z_UTIL_X2_2942 5884 +#define Z_UTIL_X2_2943 5886 +#define Z_UTIL_X2_2944 5888 +#define Z_UTIL_X2_2945 5890 +#define Z_UTIL_X2_2946 5892 +#define Z_UTIL_X2_2947 5894 +#define Z_UTIL_X2_2948 5896 +#define Z_UTIL_X2_2949 5898 +#define Z_UTIL_X2_2950 5900 +#define Z_UTIL_X2_2951 5902 +#define Z_UTIL_X2_2952 5904 +#define Z_UTIL_X2_2953 5906 +#define Z_UTIL_X2_2954 5908 +#define Z_UTIL_X2_2955 5910 +#define Z_UTIL_X2_2956 5912 +#define Z_UTIL_X2_2957 5914 +#define Z_UTIL_X2_2958 5916 +#define Z_UTIL_X2_2959 5918 +#define Z_UTIL_X2_2960 5920 +#define Z_UTIL_X2_2961 5922 +#define Z_UTIL_X2_2962 5924 +#define Z_UTIL_X2_2963 5926 +#define Z_UTIL_X2_2964 5928 +#define Z_UTIL_X2_2965 5930 +#define Z_UTIL_X2_2966 5932 +#define Z_UTIL_X2_2967 5934 +#define Z_UTIL_X2_2968 5936 +#define Z_UTIL_X2_2969 5938 +#define Z_UTIL_X2_2970 5940 +#define Z_UTIL_X2_2971 5942 +#define Z_UTIL_X2_2972 5944 +#define Z_UTIL_X2_2973 5946 +#define Z_UTIL_X2_2974 5948 +#define Z_UTIL_X2_2975 5950 +#define Z_UTIL_X2_2976 5952 +#define Z_UTIL_X2_2977 5954 +#define Z_UTIL_X2_2978 5956 +#define Z_UTIL_X2_2979 5958 +#define Z_UTIL_X2_2980 5960 +#define Z_UTIL_X2_2981 5962 +#define Z_UTIL_X2_2982 5964 +#define Z_UTIL_X2_2983 5966 +#define Z_UTIL_X2_2984 5968 +#define Z_UTIL_X2_2985 5970 +#define Z_UTIL_X2_2986 5972 +#define Z_UTIL_X2_2987 5974 +#define Z_UTIL_X2_2988 5976 +#define Z_UTIL_X2_2989 5978 +#define Z_UTIL_X2_2990 5980 +#define Z_UTIL_X2_2991 5982 +#define Z_UTIL_X2_2992 5984 +#define Z_UTIL_X2_2993 5986 +#define Z_UTIL_X2_2994 5988 +#define Z_UTIL_X2_2995 5990 +#define Z_UTIL_X2_2996 5992 +#define Z_UTIL_X2_2997 5994 +#define Z_UTIL_X2_2998 5996 +#define Z_UTIL_X2_2999 5998 +#define Z_UTIL_X2_3000 6000 +#define Z_UTIL_X2_3001 6002 +#define Z_UTIL_X2_3002 6004 +#define Z_UTIL_X2_3003 6006 +#define Z_UTIL_X2_3004 6008 +#define Z_UTIL_X2_3005 6010 +#define Z_UTIL_X2_3006 6012 +#define Z_UTIL_X2_3007 6014 +#define Z_UTIL_X2_3008 6016 +#define Z_UTIL_X2_3009 6018 +#define Z_UTIL_X2_3010 6020 +#define Z_UTIL_X2_3011 6022 +#define Z_UTIL_X2_3012 6024 +#define Z_UTIL_X2_3013 6026 +#define Z_UTIL_X2_3014 6028 +#define Z_UTIL_X2_3015 6030 +#define Z_UTIL_X2_3016 6032 +#define Z_UTIL_X2_3017 6034 +#define Z_UTIL_X2_3018 6036 +#define Z_UTIL_X2_3019 6038 +#define Z_UTIL_X2_3020 6040 +#define Z_UTIL_X2_3021 6042 +#define Z_UTIL_X2_3022 6044 +#define Z_UTIL_X2_3023 6046 +#define Z_UTIL_X2_3024 6048 +#define Z_UTIL_X2_3025 6050 +#define Z_UTIL_X2_3026 6052 +#define Z_UTIL_X2_3027 6054 +#define Z_UTIL_X2_3028 6056 +#define Z_UTIL_X2_3029 6058 +#define Z_UTIL_X2_3030 6060 +#define Z_UTIL_X2_3031 6062 +#define Z_UTIL_X2_3032 6064 +#define Z_UTIL_X2_3033 6066 +#define Z_UTIL_X2_3034 6068 +#define Z_UTIL_X2_3035 6070 +#define Z_UTIL_X2_3036 6072 +#define Z_UTIL_X2_3037 6074 +#define Z_UTIL_X2_3038 6076 +#define Z_UTIL_X2_3039 6078 +#define Z_UTIL_X2_3040 6080 +#define Z_UTIL_X2_3041 6082 +#define Z_UTIL_X2_3042 6084 +#define Z_UTIL_X2_3043 6086 +#define Z_UTIL_X2_3044 6088 +#define Z_UTIL_X2_3045 6090 +#define Z_UTIL_X2_3046 6092 +#define Z_UTIL_X2_3047 6094 +#define Z_UTIL_X2_3048 6096 +#define Z_UTIL_X2_3049 6098 +#define Z_UTIL_X2_3050 6100 +#define Z_UTIL_X2_3051 6102 +#define Z_UTIL_X2_3052 6104 +#define Z_UTIL_X2_3053 6106 +#define Z_UTIL_X2_3054 6108 +#define Z_UTIL_X2_3055 6110 +#define Z_UTIL_X2_3056 6112 +#define Z_UTIL_X2_3057 6114 +#define Z_UTIL_X2_3058 6116 +#define Z_UTIL_X2_3059 6118 +#define Z_UTIL_X2_3060 6120 +#define Z_UTIL_X2_3061 6122 +#define Z_UTIL_X2_3062 6124 +#define Z_UTIL_X2_3063 6126 +#define Z_UTIL_X2_3064 6128 +#define Z_UTIL_X2_3065 6130 +#define Z_UTIL_X2_3066 6132 +#define Z_UTIL_X2_3067 6134 +#define Z_UTIL_X2_3068 6136 +#define Z_UTIL_X2_3069 6138 +#define Z_UTIL_X2_3070 6140 +#define Z_UTIL_X2_3071 6142 +#define Z_UTIL_X2_3072 6144 +#define Z_UTIL_X2_3073 6146 +#define Z_UTIL_X2_3074 6148 +#define Z_UTIL_X2_3075 6150 +#define Z_UTIL_X2_3076 6152 +#define Z_UTIL_X2_3077 6154 +#define Z_UTIL_X2_3078 6156 +#define Z_UTIL_X2_3079 6158 +#define Z_UTIL_X2_3080 6160 +#define Z_UTIL_X2_3081 6162 +#define Z_UTIL_X2_3082 6164 +#define Z_UTIL_X2_3083 6166 +#define Z_UTIL_X2_3084 6168 +#define Z_UTIL_X2_3085 6170 +#define Z_UTIL_X2_3086 6172 +#define Z_UTIL_X2_3087 6174 +#define Z_UTIL_X2_3088 6176 +#define Z_UTIL_X2_3089 6178 +#define Z_UTIL_X2_3090 6180 +#define Z_UTIL_X2_3091 6182 +#define Z_UTIL_X2_3092 6184 +#define Z_UTIL_X2_3093 6186 +#define Z_UTIL_X2_3094 6188 +#define Z_UTIL_X2_3095 6190 +#define Z_UTIL_X2_3096 6192 +#define Z_UTIL_X2_3097 6194 +#define Z_UTIL_X2_3098 6196 +#define Z_UTIL_X2_3099 6198 +#define Z_UTIL_X2_3100 6200 +#define Z_UTIL_X2_3101 6202 +#define Z_UTIL_X2_3102 6204 +#define Z_UTIL_X2_3103 6206 +#define Z_UTIL_X2_3104 6208 +#define Z_UTIL_X2_3105 6210 +#define Z_UTIL_X2_3106 6212 +#define Z_UTIL_X2_3107 6214 +#define Z_UTIL_X2_3108 6216 +#define Z_UTIL_X2_3109 6218 +#define Z_UTIL_X2_3110 6220 +#define Z_UTIL_X2_3111 6222 +#define Z_UTIL_X2_3112 6224 +#define Z_UTIL_X2_3113 6226 +#define Z_UTIL_X2_3114 6228 +#define Z_UTIL_X2_3115 6230 +#define Z_UTIL_X2_3116 6232 +#define Z_UTIL_X2_3117 6234 +#define Z_UTIL_X2_3118 6236 +#define Z_UTIL_X2_3119 6238 +#define Z_UTIL_X2_3120 6240 +#define Z_UTIL_X2_3121 6242 +#define Z_UTIL_X2_3122 6244 +#define Z_UTIL_X2_3123 6246 +#define Z_UTIL_X2_3124 6248 +#define Z_UTIL_X2_3125 6250 +#define Z_UTIL_X2_3126 6252 +#define Z_UTIL_X2_3127 6254 +#define Z_UTIL_X2_3128 6256 +#define Z_UTIL_X2_3129 6258 +#define Z_UTIL_X2_3130 6260 +#define Z_UTIL_X2_3131 6262 +#define Z_UTIL_X2_3132 6264 +#define Z_UTIL_X2_3133 6266 +#define Z_UTIL_X2_3134 6268 +#define Z_UTIL_X2_3135 6270 +#define Z_UTIL_X2_3136 6272 +#define Z_UTIL_X2_3137 6274 +#define Z_UTIL_X2_3138 6276 +#define Z_UTIL_X2_3139 6278 +#define Z_UTIL_X2_3140 6280 +#define Z_UTIL_X2_3141 6282 +#define Z_UTIL_X2_3142 6284 +#define Z_UTIL_X2_3143 6286 +#define Z_UTIL_X2_3144 6288 +#define Z_UTIL_X2_3145 6290 +#define Z_UTIL_X2_3146 6292 +#define Z_UTIL_X2_3147 6294 +#define Z_UTIL_X2_3148 6296 +#define Z_UTIL_X2_3149 6298 +#define Z_UTIL_X2_3150 6300 +#define Z_UTIL_X2_3151 6302 +#define Z_UTIL_X2_3152 6304 +#define Z_UTIL_X2_3153 6306 +#define Z_UTIL_X2_3154 6308 +#define Z_UTIL_X2_3155 6310 +#define Z_UTIL_X2_3156 6312 +#define Z_UTIL_X2_3157 6314 +#define Z_UTIL_X2_3158 6316 +#define Z_UTIL_X2_3159 6318 +#define Z_UTIL_X2_3160 6320 +#define Z_UTIL_X2_3161 6322 +#define Z_UTIL_X2_3162 6324 +#define Z_UTIL_X2_3163 6326 +#define Z_UTIL_X2_3164 6328 +#define Z_UTIL_X2_3165 6330 +#define Z_UTIL_X2_3166 6332 +#define Z_UTIL_X2_3167 6334 +#define Z_UTIL_X2_3168 6336 +#define Z_UTIL_X2_3169 6338 +#define Z_UTIL_X2_3170 6340 +#define Z_UTIL_X2_3171 6342 +#define Z_UTIL_X2_3172 6344 +#define Z_UTIL_X2_3173 6346 +#define Z_UTIL_X2_3174 6348 +#define Z_UTIL_X2_3175 6350 +#define Z_UTIL_X2_3176 6352 +#define Z_UTIL_X2_3177 6354 +#define Z_UTIL_X2_3178 6356 +#define Z_UTIL_X2_3179 6358 +#define Z_UTIL_X2_3180 6360 +#define Z_UTIL_X2_3181 6362 +#define Z_UTIL_X2_3182 6364 +#define Z_UTIL_X2_3183 6366 +#define Z_UTIL_X2_3184 6368 +#define Z_UTIL_X2_3185 6370 +#define Z_UTIL_X2_3186 6372 +#define Z_UTIL_X2_3187 6374 +#define Z_UTIL_X2_3188 6376 +#define Z_UTIL_X2_3189 6378 +#define Z_UTIL_X2_3190 6380 +#define Z_UTIL_X2_3191 6382 +#define Z_UTIL_X2_3192 6384 +#define Z_UTIL_X2_3193 6386 +#define Z_UTIL_X2_3194 6388 +#define Z_UTIL_X2_3195 6390 +#define Z_UTIL_X2_3196 6392 +#define Z_UTIL_X2_3197 6394 +#define Z_UTIL_X2_3198 6396 +#define Z_UTIL_X2_3199 6398 +#define Z_UTIL_X2_3200 6400 +#define Z_UTIL_X2_3201 6402 +#define Z_UTIL_X2_3202 6404 +#define Z_UTIL_X2_3203 6406 +#define Z_UTIL_X2_3204 6408 +#define Z_UTIL_X2_3205 6410 +#define Z_UTIL_X2_3206 6412 +#define Z_UTIL_X2_3207 6414 +#define Z_UTIL_X2_3208 6416 +#define Z_UTIL_X2_3209 6418 +#define Z_UTIL_X2_3210 6420 +#define Z_UTIL_X2_3211 6422 +#define Z_UTIL_X2_3212 6424 +#define Z_UTIL_X2_3213 6426 +#define Z_UTIL_X2_3214 6428 +#define Z_UTIL_X2_3215 6430 +#define Z_UTIL_X2_3216 6432 +#define Z_UTIL_X2_3217 6434 +#define Z_UTIL_X2_3218 6436 +#define Z_UTIL_X2_3219 6438 +#define Z_UTIL_X2_3220 6440 +#define Z_UTIL_X2_3221 6442 +#define Z_UTIL_X2_3222 6444 +#define Z_UTIL_X2_3223 6446 +#define Z_UTIL_X2_3224 6448 +#define Z_UTIL_X2_3225 6450 +#define Z_UTIL_X2_3226 6452 +#define Z_UTIL_X2_3227 6454 +#define Z_UTIL_X2_3228 6456 +#define Z_UTIL_X2_3229 6458 +#define Z_UTIL_X2_3230 6460 +#define Z_UTIL_X2_3231 6462 +#define Z_UTIL_X2_3232 6464 +#define Z_UTIL_X2_3233 6466 +#define Z_UTIL_X2_3234 6468 +#define Z_UTIL_X2_3235 6470 +#define Z_UTIL_X2_3236 6472 +#define Z_UTIL_X2_3237 6474 +#define Z_UTIL_X2_3238 6476 +#define Z_UTIL_X2_3239 6478 +#define Z_UTIL_X2_3240 6480 +#define Z_UTIL_X2_3241 6482 +#define Z_UTIL_X2_3242 6484 +#define Z_UTIL_X2_3243 6486 +#define Z_UTIL_X2_3244 6488 +#define Z_UTIL_X2_3245 6490 +#define Z_UTIL_X2_3246 6492 +#define Z_UTIL_X2_3247 6494 +#define Z_UTIL_X2_3248 6496 +#define Z_UTIL_X2_3249 6498 +#define Z_UTIL_X2_3250 6500 +#define Z_UTIL_X2_3251 6502 +#define Z_UTIL_X2_3252 6504 +#define Z_UTIL_X2_3253 6506 +#define Z_UTIL_X2_3254 6508 +#define Z_UTIL_X2_3255 6510 +#define Z_UTIL_X2_3256 6512 +#define Z_UTIL_X2_3257 6514 +#define Z_UTIL_X2_3258 6516 +#define Z_UTIL_X2_3259 6518 +#define Z_UTIL_X2_3260 6520 +#define Z_UTIL_X2_3261 6522 +#define Z_UTIL_X2_3262 6524 +#define Z_UTIL_X2_3263 6526 +#define Z_UTIL_X2_3264 6528 +#define Z_UTIL_X2_3265 6530 +#define Z_UTIL_X2_3266 6532 +#define Z_UTIL_X2_3267 6534 +#define Z_UTIL_X2_3268 6536 +#define Z_UTIL_X2_3269 6538 +#define Z_UTIL_X2_3270 6540 +#define Z_UTIL_X2_3271 6542 +#define Z_UTIL_X2_3272 6544 +#define Z_UTIL_X2_3273 6546 +#define Z_UTIL_X2_3274 6548 +#define Z_UTIL_X2_3275 6550 +#define Z_UTIL_X2_3276 6552 +#define Z_UTIL_X2_3277 6554 +#define Z_UTIL_X2_3278 6556 +#define Z_UTIL_X2_3279 6558 +#define Z_UTIL_X2_3280 6560 +#define Z_UTIL_X2_3281 6562 +#define Z_UTIL_X2_3282 6564 +#define Z_UTIL_X2_3283 6566 +#define Z_UTIL_X2_3284 6568 +#define Z_UTIL_X2_3285 6570 +#define Z_UTIL_X2_3286 6572 +#define Z_UTIL_X2_3287 6574 +#define Z_UTIL_X2_3288 6576 +#define Z_UTIL_X2_3289 6578 +#define Z_UTIL_X2_3290 6580 +#define Z_UTIL_X2_3291 6582 +#define Z_UTIL_X2_3292 6584 +#define Z_UTIL_X2_3293 6586 +#define Z_UTIL_X2_3294 6588 +#define Z_UTIL_X2_3295 6590 +#define Z_UTIL_X2_3296 6592 +#define Z_UTIL_X2_3297 6594 +#define Z_UTIL_X2_3298 6596 +#define Z_UTIL_X2_3299 6598 +#define Z_UTIL_X2_3300 6600 +#define Z_UTIL_X2_3301 6602 +#define Z_UTIL_X2_3302 6604 +#define Z_UTIL_X2_3303 6606 +#define Z_UTIL_X2_3304 6608 +#define Z_UTIL_X2_3305 6610 +#define Z_UTIL_X2_3306 6612 +#define Z_UTIL_X2_3307 6614 +#define Z_UTIL_X2_3308 6616 +#define Z_UTIL_X2_3309 6618 +#define Z_UTIL_X2_3310 6620 +#define Z_UTIL_X2_3311 6622 +#define Z_UTIL_X2_3312 6624 +#define Z_UTIL_X2_3313 6626 +#define Z_UTIL_X2_3314 6628 +#define Z_UTIL_X2_3315 6630 +#define Z_UTIL_X2_3316 6632 +#define Z_UTIL_X2_3317 6634 +#define Z_UTIL_X2_3318 6636 +#define Z_UTIL_X2_3319 6638 +#define Z_UTIL_X2_3320 6640 +#define Z_UTIL_X2_3321 6642 +#define Z_UTIL_X2_3322 6644 +#define Z_UTIL_X2_3323 6646 +#define Z_UTIL_X2_3324 6648 +#define Z_UTIL_X2_3325 6650 +#define Z_UTIL_X2_3326 6652 +#define Z_UTIL_X2_3327 6654 +#define Z_UTIL_X2_3328 6656 +#define Z_UTIL_X2_3329 6658 +#define Z_UTIL_X2_3330 6660 +#define Z_UTIL_X2_3331 6662 +#define Z_UTIL_X2_3332 6664 +#define Z_UTIL_X2_3333 6666 +#define Z_UTIL_X2_3334 6668 +#define Z_UTIL_X2_3335 6670 +#define Z_UTIL_X2_3336 6672 +#define Z_UTIL_X2_3337 6674 +#define Z_UTIL_X2_3338 6676 +#define Z_UTIL_X2_3339 6678 +#define Z_UTIL_X2_3340 6680 +#define Z_UTIL_X2_3341 6682 +#define Z_UTIL_X2_3342 6684 +#define Z_UTIL_X2_3343 6686 +#define Z_UTIL_X2_3344 6688 +#define Z_UTIL_X2_3345 6690 +#define Z_UTIL_X2_3346 6692 +#define Z_UTIL_X2_3347 6694 +#define Z_UTIL_X2_3348 6696 +#define Z_UTIL_X2_3349 6698 +#define Z_UTIL_X2_3350 6700 +#define Z_UTIL_X2_3351 6702 +#define Z_UTIL_X2_3352 6704 +#define Z_UTIL_X2_3353 6706 +#define Z_UTIL_X2_3354 6708 +#define Z_UTIL_X2_3355 6710 +#define Z_UTIL_X2_3356 6712 +#define Z_UTIL_X2_3357 6714 +#define Z_UTIL_X2_3358 6716 +#define Z_UTIL_X2_3359 6718 +#define Z_UTIL_X2_3360 6720 +#define Z_UTIL_X2_3361 6722 +#define Z_UTIL_X2_3362 6724 +#define Z_UTIL_X2_3363 6726 +#define Z_UTIL_X2_3364 6728 +#define Z_UTIL_X2_3365 6730 +#define Z_UTIL_X2_3366 6732 +#define Z_UTIL_X2_3367 6734 +#define Z_UTIL_X2_3368 6736 +#define Z_UTIL_X2_3369 6738 +#define Z_UTIL_X2_3370 6740 +#define Z_UTIL_X2_3371 6742 +#define Z_UTIL_X2_3372 6744 +#define Z_UTIL_X2_3373 6746 +#define Z_UTIL_X2_3374 6748 +#define Z_UTIL_X2_3375 6750 +#define Z_UTIL_X2_3376 6752 +#define Z_UTIL_X2_3377 6754 +#define Z_UTIL_X2_3378 6756 +#define Z_UTIL_X2_3379 6758 +#define Z_UTIL_X2_3380 6760 +#define Z_UTIL_X2_3381 6762 +#define Z_UTIL_X2_3382 6764 +#define Z_UTIL_X2_3383 6766 +#define Z_UTIL_X2_3384 6768 +#define Z_UTIL_X2_3385 6770 +#define Z_UTIL_X2_3386 6772 +#define Z_UTIL_X2_3387 6774 +#define Z_UTIL_X2_3388 6776 +#define Z_UTIL_X2_3389 6778 +#define Z_UTIL_X2_3390 6780 +#define Z_UTIL_X2_3391 6782 +#define Z_UTIL_X2_3392 6784 +#define Z_UTIL_X2_3393 6786 +#define Z_UTIL_X2_3394 6788 +#define Z_UTIL_X2_3395 6790 +#define Z_UTIL_X2_3396 6792 +#define Z_UTIL_X2_3397 6794 +#define Z_UTIL_X2_3398 6796 +#define Z_UTIL_X2_3399 6798 +#define Z_UTIL_X2_3400 6800 +#define Z_UTIL_X2_3401 6802 +#define Z_UTIL_X2_3402 6804 +#define Z_UTIL_X2_3403 6806 +#define Z_UTIL_X2_3404 6808 +#define Z_UTIL_X2_3405 6810 +#define Z_UTIL_X2_3406 6812 +#define Z_UTIL_X2_3407 6814 +#define Z_UTIL_X2_3408 6816 +#define Z_UTIL_X2_3409 6818 +#define Z_UTIL_X2_3410 6820 +#define Z_UTIL_X2_3411 6822 +#define Z_UTIL_X2_3412 6824 +#define Z_UTIL_X2_3413 6826 +#define Z_UTIL_X2_3414 6828 +#define Z_UTIL_X2_3415 6830 +#define Z_UTIL_X2_3416 6832 +#define Z_UTIL_X2_3417 6834 +#define Z_UTIL_X2_3418 6836 +#define Z_UTIL_X2_3419 6838 +#define Z_UTIL_X2_3420 6840 +#define Z_UTIL_X2_3421 6842 +#define Z_UTIL_X2_3422 6844 +#define Z_UTIL_X2_3423 6846 +#define Z_UTIL_X2_3424 6848 +#define Z_UTIL_X2_3425 6850 +#define Z_UTIL_X2_3426 6852 +#define Z_UTIL_X2_3427 6854 +#define Z_UTIL_X2_3428 6856 +#define Z_UTIL_X2_3429 6858 +#define Z_UTIL_X2_3430 6860 +#define Z_UTIL_X2_3431 6862 +#define Z_UTIL_X2_3432 6864 +#define Z_UTIL_X2_3433 6866 +#define Z_UTIL_X2_3434 6868 +#define Z_UTIL_X2_3435 6870 +#define Z_UTIL_X2_3436 6872 +#define Z_UTIL_X2_3437 6874 +#define Z_UTIL_X2_3438 6876 +#define Z_UTIL_X2_3439 6878 +#define Z_UTIL_X2_3440 6880 +#define Z_UTIL_X2_3441 6882 +#define Z_UTIL_X2_3442 6884 +#define Z_UTIL_X2_3443 6886 +#define Z_UTIL_X2_3444 6888 +#define Z_UTIL_X2_3445 6890 +#define Z_UTIL_X2_3446 6892 +#define Z_UTIL_X2_3447 6894 +#define Z_UTIL_X2_3448 6896 +#define Z_UTIL_X2_3449 6898 +#define Z_UTIL_X2_3450 6900 +#define Z_UTIL_X2_3451 6902 +#define Z_UTIL_X2_3452 6904 +#define Z_UTIL_X2_3453 6906 +#define Z_UTIL_X2_3454 6908 +#define Z_UTIL_X2_3455 6910 +#define Z_UTIL_X2_3456 6912 +#define Z_UTIL_X2_3457 6914 +#define Z_UTIL_X2_3458 6916 +#define Z_UTIL_X2_3459 6918 +#define Z_UTIL_X2_3460 6920 +#define Z_UTIL_X2_3461 6922 +#define Z_UTIL_X2_3462 6924 +#define Z_UTIL_X2_3463 6926 +#define Z_UTIL_X2_3464 6928 +#define Z_UTIL_X2_3465 6930 +#define Z_UTIL_X2_3466 6932 +#define Z_UTIL_X2_3467 6934 +#define Z_UTIL_X2_3468 6936 +#define Z_UTIL_X2_3469 6938 +#define Z_UTIL_X2_3470 6940 +#define Z_UTIL_X2_3471 6942 +#define Z_UTIL_X2_3472 6944 +#define Z_UTIL_X2_3473 6946 +#define Z_UTIL_X2_3474 6948 +#define Z_UTIL_X2_3475 6950 +#define Z_UTIL_X2_3476 6952 +#define Z_UTIL_X2_3477 6954 +#define Z_UTIL_X2_3478 6956 +#define Z_UTIL_X2_3479 6958 +#define Z_UTIL_X2_3480 6960 +#define Z_UTIL_X2_3481 6962 +#define Z_UTIL_X2_3482 6964 +#define Z_UTIL_X2_3483 6966 +#define Z_UTIL_X2_3484 6968 +#define Z_UTIL_X2_3485 6970 +#define Z_UTIL_X2_3486 6972 +#define Z_UTIL_X2_3487 6974 +#define Z_UTIL_X2_3488 6976 +#define Z_UTIL_X2_3489 6978 +#define Z_UTIL_X2_3490 6980 +#define Z_UTIL_X2_3491 6982 +#define Z_UTIL_X2_3492 6984 +#define Z_UTIL_X2_3493 6986 +#define Z_UTIL_X2_3494 6988 +#define Z_UTIL_X2_3495 6990 +#define Z_UTIL_X2_3496 6992 +#define Z_UTIL_X2_3497 6994 +#define Z_UTIL_X2_3498 6996 +#define Z_UTIL_X2_3499 6998 +#define Z_UTIL_X2_3500 7000 +#define Z_UTIL_X2_3501 7002 +#define Z_UTIL_X2_3502 7004 +#define Z_UTIL_X2_3503 7006 +#define Z_UTIL_X2_3504 7008 +#define Z_UTIL_X2_3505 7010 +#define Z_UTIL_X2_3506 7012 +#define Z_UTIL_X2_3507 7014 +#define Z_UTIL_X2_3508 7016 +#define Z_UTIL_X2_3509 7018 +#define Z_UTIL_X2_3510 7020 +#define Z_UTIL_X2_3511 7022 +#define Z_UTIL_X2_3512 7024 +#define Z_UTIL_X2_3513 7026 +#define Z_UTIL_X2_3514 7028 +#define Z_UTIL_X2_3515 7030 +#define Z_UTIL_X2_3516 7032 +#define Z_UTIL_X2_3517 7034 +#define Z_UTIL_X2_3518 7036 +#define Z_UTIL_X2_3519 7038 +#define Z_UTIL_X2_3520 7040 +#define Z_UTIL_X2_3521 7042 +#define Z_UTIL_X2_3522 7044 +#define Z_UTIL_X2_3523 7046 +#define Z_UTIL_X2_3524 7048 +#define Z_UTIL_X2_3525 7050 +#define Z_UTIL_X2_3526 7052 +#define Z_UTIL_X2_3527 7054 +#define Z_UTIL_X2_3528 7056 +#define Z_UTIL_X2_3529 7058 +#define Z_UTIL_X2_3530 7060 +#define Z_UTIL_X2_3531 7062 +#define Z_UTIL_X2_3532 7064 +#define Z_UTIL_X2_3533 7066 +#define Z_UTIL_X2_3534 7068 +#define Z_UTIL_X2_3535 7070 +#define Z_UTIL_X2_3536 7072 +#define Z_UTIL_X2_3537 7074 +#define Z_UTIL_X2_3538 7076 +#define Z_UTIL_X2_3539 7078 +#define Z_UTIL_X2_3540 7080 +#define Z_UTIL_X2_3541 7082 +#define Z_UTIL_X2_3542 7084 +#define Z_UTIL_X2_3543 7086 +#define Z_UTIL_X2_3544 7088 +#define Z_UTIL_X2_3545 7090 +#define Z_UTIL_X2_3546 7092 +#define Z_UTIL_X2_3547 7094 +#define Z_UTIL_X2_3548 7096 +#define Z_UTIL_X2_3549 7098 +#define Z_UTIL_X2_3550 7100 +#define Z_UTIL_X2_3551 7102 +#define Z_UTIL_X2_3552 7104 +#define Z_UTIL_X2_3553 7106 +#define Z_UTIL_X2_3554 7108 +#define Z_UTIL_X2_3555 7110 +#define Z_UTIL_X2_3556 7112 +#define Z_UTIL_X2_3557 7114 +#define Z_UTIL_X2_3558 7116 +#define Z_UTIL_X2_3559 7118 +#define Z_UTIL_X2_3560 7120 +#define Z_UTIL_X2_3561 7122 +#define Z_UTIL_X2_3562 7124 +#define Z_UTIL_X2_3563 7126 +#define Z_UTIL_X2_3564 7128 +#define Z_UTIL_X2_3565 7130 +#define Z_UTIL_X2_3566 7132 +#define Z_UTIL_X2_3567 7134 +#define Z_UTIL_X2_3568 7136 +#define Z_UTIL_X2_3569 7138 +#define Z_UTIL_X2_3570 7140 +#define Z_UTIL_X2_3571 7142 +#define Z_UTIL_X2_3572 7144 +#define Z_UTIL_X2_3573 7146 +#define Z_UTIL_X2_3574 7148 +#define Z_UTIL_X2_3575 7150 +#define Z_UTIL_X2_3576 7152 +#define Z_UTIL_X2_3577 7154 +#define Z_UTIL_X2_3578 7156 +#define Z_UTIL_X2_3579 7158 +#define Z_UTIL_X2_3580 7160 +#define Z_UTIL_X2_3581 7162 +#define Z_UTIL_X2_3582 7164 +#define Z_UTIL_X2_3583 7166 +#define Z_UTIL_X2_3584 7168 +#define Z_UTIL_X2_3585 7170 +#define Z_UTIL_X2_3586 7172 +#define Z_UTIL_X2_3587 7174 +#define Z_UTIL_X2_3588 7176 +#define Z_UTIL_X2_3589 7178 +#define Z_UTIL_X2_3590 7180 +#define Z_UTIL_X2_3591 7182 +#define Z_UTIL_X2_3592 7184 +#define Z_UTIL_X2_3593 7186 +#define Z_UTIL_X2_3594 7188 +#define Z_UTIL_X2_3595 7190 +#define Z_UTIL_X2_3596 7192 +#define Z_UTIL_X2_3597 7194 +#define Z_UTIL_X2_3598 7196 +#define Z_UTIL_X2_3599 7198 +#define Z_UTIL_X2_3600 7200 +#define Z_UTIL_X2_3601 7202 +#define Z_UTIL_X2_3602 7204 +#define Z_UTIL_X2_3603 7206 +#define Z_UTIL_X2_3604 7208 +#define Z_UTIL_X2_3605 7210 +#define Z_UTIL_X2_3606 7212 +#define Z_UTIL_X2_3607 7214 +#define Z_UTIL_X2_3608 7216 +#define Z_UTIL_X2_3609 7218 +#define Z_UTIL_X2_3610 7220 +#define Z_UTIL_X2_3611 7222 +#define Z_UTIL_X2_3612 7224 +#define Z_UTIL_X2_3613 7226 +#define Z_UTIL_X2_3614 7228 +#define Z_UTIL_X2_3615 7230 +#define Z_UTIL_X2_3616 7232 +#define Z_UTIL_X2_3617 7234 +#define Z_UTIL_X2_3618 7236 +#define Z_UTIL_X2_3619 7238 +#define Z_UTIL_X2_3620 7240 +#define Z_UTIL_X2_3621 7242 +#define Z_UTIL_X2_3622 7244 +#define Z_UTIL_X2_3623 7246 +#define Z_UTIL_X2_3624 7248 +#define Z_UTIL_X2_3625 7250 +#define Z_UTIL_X2_3626 7252 +#define Z_UTIL_X2_3627 7254 +#define Z_UTIL_X2_3628 7256 +#define Z_UTIL_X2_3629 7258 +#define Z_UTIL_X2_3630 7260 +#define Z_UTIL_X2_3631 7262 +#define Z_UTIL_X2_3632 7264 +#define Z_UTIL_X2_3633 7266 +#define Z_UTIL_X2_3634 7268 +#define Z_UTIL_X2_3635 7270 +#define Z_UTIL_X2_3636 7272 +#define Z_UTIL_X2_3637 7274 +#define Z_UTIL_X2_3638 7276 +#define Z_UTIL_X2_3639 7278 +#define Z_UTIL_X2_3640 7280 +#define Z_UTIL_X2_3641 7282 +#define Z_UTIL_X2_3642 7284 +#define Z_UTIL_X2_3643 7286 +#define Z_UTIL_X2_3644 7288 +#define Z_UTIL_X2_3645 7290 +#define Z_UTIL_X2_3646 7292 +#define Z_UTIL_X2_3647 7294 +#define Z_UTIL_X2_3648 7296 +#define Z_UTIL_X2_3649 7298 +#define Z_UTIL_X2_3650 7300 +#define Z_UTIL_X2_3651 7302 +#define Z_UTIL_X2_3652 7304 +#define Z_UTIL_X2_3653 7306 +#define Z_UTIL_X2_3654 7308 +#define Z_UTIL_X2_3655 7310 +#define Z_UTIL_X2_3656 7312 +#define Z_UTIL_X2_3657 7314 +#define Z_UTIL_X2_3658 7316 +#define Z_UTIL_X2_3659 7318 +#define Z_UTIL_X2_3660 7320 +#define Z_UTIL_X2_3661 7322 +#define Z_UTIL_X2_3662 7324 +#define Z_UTIL_X2_3663 7326 +#define Z_UTIL_X2_3664 7328 +#define Z_UTIL_X2_3665 7330 +#define Z_UTIL_X2_3666 7332 +#define Z_UTIL_X2_3667 7334 +#define Z_UTIL_X2_3668 7336 +#define Z_UTIL_X2_3669 7338 +#define Z_UTIL_X2_3670 7340 +#define Z_UTIL_X2_3671 7342 +#define Z_UTIL_X2_3672 7344 +#define Z_UTIL_X2_3673 7346 +#define Z_UTIL_X2_3674 7348 +#define Z_UTIL_X2_3675 7350 +#define Z_UTIL_X2_3676 7352 +#define Z_UTIL_X2_3677 7354 +#define Z_UTIL_X2_3678 7356 +#define Z_UTIL_X2_3679 7358 +#define Z_UTIL_X2_3680 7360 +#define Z_UTIL_X2_3681 7362 +#define Z_UTIL_X2_3682 7364 +#define Z_UTIL_X2_3683 7366 +#define Z_UTIL_X2_3684 7368 +#define Z_UTIL_X2_3685 7370 +#define Z_UTIL_X2_3686 7372 +#define Z_UTIL_X2_3687 7374 +#define Z_UTIL_X2_3688 7376 +#define Z_UTIL_X2_3689 7378 +#define Z_UTIL_X2_3690 7380 +#define Z_UTIL_X2_3691 7382 +#define Z_UTIL_X2_3692 7384 +#define Z_UTIL_X2_3693 7386 +#define Z_UTIL_X2_3694 7388 +#define Z_UTIL_X2_3695 7390 +#define Z_UTIL_X2_3696 7392 +#define Z_UTIL_X2_3697 7394 +#define Z_UTIL_X2_3698 7396 +#define Z_UTIL_X2_3699 7398 +#define Z_UTIL_X2_3700 7400 +#define Z_UTIL_X2_3701 7402 +#define Z_UTIL_X2_3702 7404 +#define Z_UTIL_X2_3703 7406 +#define Z_UTIL_X2_3704 7408 +#define Z_UTIL_X2_3705 7410 +#define Z_UTIL_X2_3706 7412 +#define Z_UTIL_X2_3707 7414 +#define Z_UTIL_X2_3708 7416 +#define Z_UTIL_X2_3709 7418 +#define Z_UTIL_X2_3710 7420 +#define Z_UTIL_X2_3711 7422 +#define Z_UTIL_X2_3712 7424 +#define Z_UTIL_X2_3713 7426 +#define Z_UTIL_X2_3714 7428 +#define Z_UTIL_X2_3715 7430 +#define Z_UTIL_X2_3716 7432 +#define Z_UTIL_X2_3717 7434 +#define Z_UTIL_X2_3718 7436 +#define Z_UTIL_X2_3719 7438 +#define Z_UTIL_X2_3720 7440 +#define Z_UTIL_X2_3721 7442 +#define Z_UTIL_X2_3722 7444 +#define Z_UTIL_X2_3723 7446 +#define Z_UTIL_X2_3724 7448 +#define Z_UTIL_X2_3725 7450 +#define Z_UTIL_X2_3726 7452 +#define Z_UTIL_X2_3727 7454 +#define Z_UTIL_X2_3728 7456 +#define Z_UTIL_X2_3729 7458 +#define Z_UTIL_X2_3730 7460 +#define Z_UTIL_X2_3731 7462 +#define Z_UTIL_X2_3732 7464 +#define Z_UTIL_X2_3733 7466 +#define Z_UTIL_X2_3734 7468 +#define Z_UTIL_X2_3735 7470 +#define Z_UTIL_X2_3736 7472 +#define Z_UTIL_X2_3737 7474 +#define Z_UTIL_X2_3738 7476 +#define Z_UTIL_X2_3739 7478 +#define Z_UTIL_X2_3740 7480 +#define Z_UTIL_X2_3741 7482 +#define Z_UTIL_X2_3742 7484 +#define Z_UTIL_X2_3743 7486 +#define Z_UTIL_X2_3744 7488 +#define Z_UTIL_X2_3745 7490 +#define Z_UTIL_X2_3746 7492 +#define Z_UTIL_X2_3747 7494 +#define Z_UTIL_X2_3748 7496 +#define Z_UTIL_X2_3749 7498 +#define Z_UTIL_X2_3750 7500 +#define Z_UTIL_X2_3751 7502 +#define Z_UTIL_X2_3752 7504 +#define Z_UTIL_X2_3753 7506 +#define Z_UTIL_X2_3754 7508 +#define Z_UTIL_X2_3755 7510 +#define Z_UTIL_X2_3756 7512 +#define Z_UTIL_X2_3757 7514 +#define Z_UTIL_X2_3758 7516 +#define Z_UTIL_X2_3759 7518 +#define Z_UTIL_X2_3760 7520 +#define Z_UTIL_X2_3761 7522 +#define Z_UTIL_X2_3762 7524 +#define Z_UTIL_X2_3763 7526 +#define Z_UTIL_X2_3764 7528 +#define Z_UTIL_X2_3765 7530 +#define Z_UTIL_X2_3766 7532 +#define Z_UTIL_X2_3767 7534 +#define Z_UTIL_X2_3768 7536 +#define Z_UTIL_X2_3769 7538 +#define Z_UTIL_X2_3770 7540 +#define Z_UTIL_X2_3771 7542 +#define Z_UTIL_X2_3772 7544 +#define Z_UTIL_X2_3773 7546 +#define Z_UTIL_X2_3774 7548 +#define Z_UTIL_X2_3775 7550 +#define Z_UTIL_X2_3776 7552 +#define Z_UTIL_X2_3777 7554 +#define Z_UTIL_X2_3778 7556 +#define Z_UTIL_X2_3779 7558 +#define Z_UTIL_X2_3780 7560 +#define Z_UTIL_X2_3781 7562 +#define Z_UTIL_X2_3782 7564 +#define Z_UTIL_X2_3783 7566 +#define Z_UTIL_X2_3784 7568 +#define Z_UTIL_X2_3785 7570 +#define Z_UTIL_X2_3786 7572 +#define Z_UTIL_X2_3787 7574 +#define Z_UTIL_X2_3788 7576 +#define Z_UTIL_X2_3789 7578 +#define Z_UTIL_X2_3790 7580 +#define Z_UTIL_X2_3791 7582 +#define Z_UTIL_X2_3792 7584 +#define Z_UTIL_X2_3793 7586 +#define Z_UTIL_X2_3794 7588 +#define Z_UTIL_X2_3795 7590 +#define Z_UTIL_X2_3796 7592 +#define Z_UTIL_X2_3797 7594 +#define Z_UTIL_X2_3798 7596 +#define Z_UTIL_X2_3799 7598 +#define Z_UTIL_X2_3800 7600 +#define Z_UTIL_X2_3801 7602 +#define Z_UTIL_X2_3802 7604 +#define Z_UTIL_X2_3803 7606 +#define Z_UTIL_X2_3804 7608 +#define Z_UTIL_X2_3805 7610 +#define Z_UTIL_X2_3806 7612 +#define Z_UTIL_X2_3807 7614 +#define Z_UTIL_X2_3808 7616 +#define Z_UTIL_X2_3809 7618 +#define Z_UTIL_X2_3810 7620 +#define Z_UTIL_X2_3811 7622 +#define Z_UTIL_X2_3812 7624 +#define Z_UTIL_X2_3813 7626 +#define Z_UTIL_X2_3814 7628 +#define Z_UTIL_X2_3815 7630 +#define Z_UTIL_X2_3816 7632 +#define Z_UTIL_X2_3817 7634 +#define Z_UTIL_X2_3818 7636 +#define Z_UTIL_X2_3819 7638 +#define Z_UTIL_X2_3820 7640 +#define Z_UTIL_X2_3821 7642 +#define Z_UTIL_X2_3822 7644 +#define Z_UTIL_X2_3823 7646 +#define Z_UTIL_X2_3824 7648 +#define Z_UTIL_X2_3825 7650 +#define Z_UTIL_X2_3826 7652 +#define Z_UTIL_X2_3827 7654 +#define Z_UTIL_X2_3828 7656 +#define Z_UTIL_X2_3829 7658 +#define Z_UTIL_X2_3830 7660 +#define Z_UTIL_X2_3831 7662 +#define Z_UTIL_X2_3832 7664 +#define Z_UTIL_X2_3833 7666 +#define Z_UTIL_X2_3834 7668 +#define Z_UTIL_X2_3835 7670 +#define Z_UTIL_X2_3836 7672 +#define Z_UTIL_X2_3837 7674 +#define Z_UTIL_X2_3838 7676 +#define Z_UTIL_X2_3839 7678 +#define Z_UTIL_X2_3840 7680 +#define Z_UTIL_X2_3841 7682 +#define Z_UTIL_X2_3842 7684 +#define Z_UTIL_X2_3843 7686 +#define Z_UTIL_X2_3844 7688 +#define Z_UTIL_X2_3845 7690 +#define Z_UTIL_X2_3846 7692 +#define Z_UTIL_X2_3847 7694 +#define Z_UTIL_X2_3848 7696 +#define Z_UTIL_X2_3849 7698 +#define Z_UTIL_X2_3850 7700 +#define Z_UTIL_X2_3851 7702 +#define Z_UTIL_X2_3852 7704 +#define Z_UTIL_X2_3853 7706 +#define Z_UTIL_X2_3854 7708 +#define Z_UTIL_X2_3855 7710 +#define Z_UTIL_X2_3856 7712 +#define Z_UTIL_X2_3857 7714 +#define Z_UTIL_X2_3858 7716 +#define Z_UTIL_X2_3859 7718 +#define Z_UTIL_X2_3860 7720 +#define Z_UTIL_X2_3861 7722 +#define Z_UTIL_X2_3862 7724 +#define Z_UTIL_X2_3863 7726 +#define Z_UTIL_X2_3864 7728 +#define Z_UTIL_X2_3865 7730 +#define Z_UTIL_X2_3866 7732 +#define Z_UTIL_X2_3867 7734 +#define Z_UTIL_X2_3868 7736 +#define Z_UTIL_X2_3869 7738 +#define Z_UTIL_X2_3870 7740 +#define Z_UTIL_X2_3871 7742 +#define Z_UTIL_X2_3872 7744 +#define Z_UTIL_X2_3873 7746 +#define Z_UTIL_X2_3874 7748 +#define Z_UTIL_X2_3875 7750 +#define Z_UTIL_X2_3876 7752 +#define Z_UTIL_X2_3877 7754 +#define Z_UTIL_X2_3878 7756 +#define Z_UTIL_X2_3879 7758 +#define Z_UTIL_X2_3880 7760 +#define Z_UTIL_X2_3881 7762 +#define Z_UTIL_X2_3882 7764 +#define Z_UTIL_X2_3883 7766 +#define Z_UTIL_X2_3884 7768 +#define Z_UTIL_X2_3885 7770 +#define Z_UTIL_X2_3886 7772 +#define Z_UTIL_X2_3887 7774 +#define Z_UTIL_X2_3888 7776 +#define Z_UTIL_X2_3889 7778 +#define Z_UTIL_X2_3890 7780 +#define Z_UTIL_X2_3891 7782 +#define Z_UTIL_X2_3892 7784 +#define Z_UTIL_X2_3893 7786 +#define Z_UTIL_X2_3894 7788 +#define Z_UTIL_X2_3895 7790 +#define Z_UTIL_X2_3896 7792 +#define Z_UTIL_X2_3897 7794 +#define Z_UTIL_X2_3898 7796 +#define Z_UTIL_X2_3899 7798 +#define Z_UTIL_X2_3900 7800 +#define Z_UTIL_X2_3901 7802 +#define Z_UTIL_X2_3902 7804 +#define Z_UTIL_X2_3903 7806 +#define Z_UTIL_X2_3904 7808 +#define Z_UTIL_X2_3905 7810 +#define Z_UTIL_X2_3906 7812 +#define Z_UTIL_X2_3907 7814 +#define Z_UTIL_X2_3908 7816 +#define Z_UTIL_X2_3909 7818 +#define Z_UTIL_X2_3910 7820 +#define Z_UTIL_X2_3911 7822 +#define Z_UTIL_X2_3912 7824 +#define Z_UTIL_X2_3913 7826 +#define Z_UTIL_X2_3914 7828 +#define Z_UTIL_X2_3915 7830 +#define Z_UTIL_X2_3916 7832 +#define Z_UTIL_X2_3917 7834 +#define Z_UTIL_X2_3918 7836 +#define Z_UTIL_X2_3919 7838 +#define Z_UTIL_X2_3920 7840 +#define Z_UTIL_X2_3921 7842 +#define Z_UTIL_X2_3922 7844 +#define Z_UTIL_X2_3923 7846 +#define Z_UTIL_X2_3924 7848 +#define Z_UTIL_X2_3925 7850 +#define Z_UTIL_X2_3926 7852 +#define Z_UTIL_X2_3927 7854 +#define Z_UTIL_X2_3928 7856 +#define Z_UTIL_X2_3929 7858 +#define Z_UTIL_X2_3930 7860 +#define Z_UTIL_X2_3931 7862 +#define Z_UTIL_X2_3932 7864 +#define Z_UTIL_X2_3933 7866 +#define Z_UTIL_X2_3934 7868 +#define Z_UTIL_X2_3935 7870 +#define Z_UTIL_X2_3936 7872 +#define Z_UTIL_X2_3937 7874 +#define Z_UTIL_X2_3938 7876 +#define Z_UTIL_X2_3939 7878 +#define Z_UTIL_X2_3940 7880 +#define Z_UTIL_X2_3941 7882 +#define Z_UTIL_X2_3942 7884 +#define Z_UTIL_X2_3943 7886 +#define Z_UTIL_X2_3944 7888 +#define Z_UTIL_X2_3945 7890 +#define Z_UTIL_X2_3946 7892 +#define Z_UTIL_X2_3947 7894 +#define Z_UTIL_X2_3948 7896 +#define Z_UTIL_X2_3949 7898 +#define Z_UTIL_X2_3950 7900 +#define Z_UTIL_X2_3951 7902 +#define Z_UTIL_X2_3952 7904 +#define Z_UTIL_X2_3953 7906 +#define Z_UTIL_X2_3954 7908 +#define Z_UTIL_X2_3955 7910 +#define Z_UTIL_X2_3956 7912 +#define Z_UTIL_X2_3957 7914 +#define Z_UTIL_X2_3958 7916 +#define Z_UTIL_X2_3959 7918 +#define Z_UTIL_X2_3960 7920 +#define Z_UTIL_X2_3961 7922 +#define Z_UTIL_X2_3962 7924 +#define Z_UTIL_X2_3963 7926 +#define Z_UTIL_X2_3964 7928 +#define Z_UTIL_X2_3965 7930 +#define Z_UTIL_X2_3966 7932 +#define Z_UTIL_X2_3967 7934 +#define Z_UTIL_X2_3968 7936 +#define Z_UTIL_X2_3969 7938 +#define Z_UTIL_X2_3970 7940 +#define Z_UTIL_X2_3971 7942 +#define Z_UTIL_X2_3972 7944 +#define Z_UTIL_X2_3973 7946 +#define Z_UTIL_X2_3974 7948 +#define Z_UTIL_X2_3975 7950 +#define Z_UTIL_X2_3976 7952 +#define Z_UTIL_X2_3977 7954 +#define Z_UTIL_X2_3978 7956 +#define Z_UTIL_X2_3979 7958 +#define Z_UTIL_X2_3980 7960 +#define Z_UTIL_X2_3981 7962 +#define Z_UTIL_X2_3982 7964 +#define Z_UTIL_X2_3983 7966 +#define Z_UTIL_X2_3984 7968 +#define Z_UTIL_X2_3985 7970 +#define Z_UTIL_X2_3986 7972 +#define Z_UTIL_X2_3987 7974 +#define Z_UTIL_X2_3988 7976 +#define Z_UTIL_X2_3989 7978 +#define Z_UTIL_X2_3990 7980 +#define Z_UTIL_X2_3991 7982 +#define Z_UTIL_X2_3992 7984 +#define Z_UTIL_X2_3993 7986 +#define Z_UTIL_X2_3994 7988 +#define Z_UTIL_X2_3995 7990 +#define Z_UTIL_X2_3996 7992 +#define Z_UTIL_X2_3997 7994 +#define Z_UTIL_X2_3998 7996 +#define Z_UTIL_X2_3999 7998 +#define Z_UTIL_X2_4000 8000 +#define Z_UTIL_X2_4001 8002 +#define Z_UTIL_X2_4002 8004 +#define Z_UTIL_X2_4003 8006 +#define Z_UTIL_X2_4004 8008 +#define Z_UTIL_X2_4005 8010 +#define Z_UTIL_X2_4006 8012 +#define Z_UTIL_X2_4007 8014 +#define Z_UTIL_X2_4008 8016 +#define Z_UTIL_X2_4009 8018 +#define Z_UTIL_X2_4010 8020 +#define Z_UTIL_X2_4011 8022 +#define Z_UTIL_X2_4012 8024 +#define Z_UTIL_X2_4013 8026 +#define Z_UTIL_X2_4014 8028 +#define Z_UTIL_X2_4015 8030 +#define Z_UTIL_X2_4016 8032 +#define Z_UTIL_X2_4017 8034 +#define Z_UTIL_X2_4018 8036 +#define Z_UTIL_X2_4019 8038 +#define Z_UTIL_X2_4020 8040 +#define Z_UTIL_X2_4021 8042 +#define Z_UTIL_X2_4022 8044 +#define Z_UTIL_X2_4023 8046 +#define Z_UTIL_X2_4024 8048 +#define Z_UTIL_X2_4025 8050 +#define Z_UTIL_X2_4026 8052 +#define Z_UTIL_X2_4027 8054 +#define Z_UTIL_X2_4028 8056 +#define Z_UTIL_X2_4029 8058 +#define Z_UTIL_X2_4030 8060 +#define Z_UTIL_X2_4031 8062 +#define Z_UTIL_X2_4032 8064 +#define Z_UTIL_X2_4033 8066 +#define Z_UTIL_X2_4034 8068 +#define Z_UTIL_X2_4035 8070 +#define Z_UTIL_X2_4036 8072 +#define Z_UTIL_X2_4037 8074 +#define Z_UTIL_X2_4038 8076 +#define Z_UTIL_X2_4039 8078 +#define Z_UTIL_X2_4040 8080 +#define Z_UTIL_X2_4041 8082 +#define Z_UTIL_X2_4042 8084 +#define Z_UTIL_X2_4043 8086 +#define Z_UTIL_X2_4044 8088 +#define Z_UTIL_X2_4045 8090 +#define Z_UTIL_X2_4046 8092 +#define Z_UTIL_X2_4047 8094 +#define Z_UTIL_X2_4048 8096 +#define Z_UTIL_X2_4049 8098 +#define Z_UTIL_X2_4050 8100 +#define Z_UTIL_X2_4051 8102 +#define Z_UTIL_X2_4052 8104 +#define Z_UTIL_X2_4053 8106 +#define Z_UTIL_X2_4054 8108 +#define Z_UTIL_X2_4055 8110 +#define Z_UTIL_X2_4056 8112 +#define Z_UTIL_X2_4057 8114 +#define Z_UTIL_X2_4058 8116 +#define Z_UTIL_X2_4059 8118 +#define Z_UTIL_X2_4060 8120 +#define Z_UTIL_X2_4061 8122 +#define Z_UTIL_X2_4062 8124 +#define Z_UTIL_X2_4063 8126 +#define Z_UTIL_X2_4064 8128 +#define Z_UTIL_X2_4065 8130 +#define Z_UTIL_X2_4066 8132 +#define Z_UTIL_X2_4067 8134 +#define Z_UTIL_X2_4068 8136 +#define Z_UTIL_X2_4069 8138 +#define Z_UTIL_X2_4070 8140 +#define Z_UTIL_X2_4071 8142 +#define Z_UTIL_X2_4072 8144 +#define Z_UTIL_X2_4073 8146 +#define Z_UTIL_X2_4074 8148 +#define Z_UTIL_X2_4075 8150 +#define Z_UTIL_X2_4076 8152 +#define Z_UTIL_X2_4077 8154 +#define Z_UTIL_X2_4078 8156 +#define Z_UTIL_X2_4079 8158 +#define Z_UTIL_X2_4080 8160 +#define Z_UTIL_X2_4081 8162 +#define Z_UTIL_X2_4082 8164 +#define Z_UTIL_X2_4083 8166 +#define Z_UTIL_X2_4084 8168 +#define Z_UTIL_X2_4085 8170 +#define Z_UTIL_X2_4086 8172 +#define Z_UTIL_X2_4087 8174 +#define Z_UTIL_X2_4088 8176 +#define Z_UTIL_X2_4089 8178 +#define Z_UTIL_X2_4090 8180 +#define Z_UTIL_X2_4091 8182 +#define Z_UTIL_X2_4092 8184 +#define Z_UTIL_X2_4093 8186 +#define Z_UTIL_X2_4094 8188 +#define Z_UTIL_X2_4095 8190 + +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_ */ + +/** + * INTERNAL_HIDDEN @endcond + */ diff --git a/include/zephyr/sys/util_listify.h b/include/zephyr/sys/util_listify.h new file mode 100644 index 00000000000..3b755231290 --- /dev/null +++ b/include/zephyr/sys/util_listify.h @@ -0,0 +1,16400 @@ +/* + * Copyright (c) 2021, Nordic Semiconductor ASA + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_ +#error "This header should not be used directly, please include util_loops.h instead" +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_ */ + +#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_ +#define ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_ + +#define Z_UTIL_LISTIFY_0(F, sep, ...) + +#define Z_UTIL_LISTIFY_1(F, sep, ...) \ + F(0, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2(F, sep, ...) \ + Z_UTIL_LISTIFY_1(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3(F, sep, ...) \ + Z_UTIL_LISTIFY_2(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4(F, sep, ...) \ + Z_UTIL_LISTIFY_3(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_5(F, sep, ...) \ + Z_UTIL_LISTIFY_4(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_6(F, sep, ...) \ + Z_UTIL_LISTIFY_5(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(5, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_7(F, sep, ...) \ + Z_UTIL_LISTIFY_6(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(6, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_8(F, sep, ...) \ + Z_UTIL_LISTIFY_7(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(7, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_9(F, sep, ...) \ + Z_UTIL_LISTIFY_8(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(8, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_10(F, sep, ...) \ + Z_UTIL_LISTIFY_9(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(9, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_11(F, sep, ...) \ + Z_UTIL_LISTIFY_10(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(10, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_12(F, sep, ...) \ + Z_UTIL_LISTIFY_11(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(11, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_13(F, sep, ...) \ + Z_UTIL_LISTIFY_12(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(12, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_14(F, sep, ...) \ + Z_UTIL_LISTIFY_13(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(13, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_15(F, sep, ...) \ + Z_UTIL_LISTIFY_14(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(14, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_16(F, sep, ...) \ + Z_UTIL_LISTIFY_15(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(15, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_17(F, sep, ...) \ + Z_UTIL_LISTIFY_16(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(16, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_18(F, sep, ...) \ + Z_UTIL_LISTIFY_17(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(17, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_19(F, sep, ...) \ + Z_UTIL_LISTIFY_18(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(18, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_20(F, sep, ...) \ + Z_UTIL_LISTIFY_19(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(19, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_21(F, sep, ...) \ + Z_UTIL_LISTIFY_20(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(20, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_22(F, sep, ...) \ + Z_UTIL_LISTIFY_21(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(21, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_23(F, sep, ...) \ + Z_UTIL_LISTIFY_22(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(22, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_24(F, sep, ...) \ + Z_UTIL_LISTIFY_23(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(23, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_25(F, sep, ...) \ + Z_UTIL_LISTIFY_24(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(24, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_26(F, sep, ...) \ + Z_UTIL_LISTIFY_25(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(25, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_27(F, sep, ...) \ + Z_UTIL_LISTIFY_26(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(26, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_28(F, sep, ...) \ + Z_UTIL_LISTIFY_27(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(27, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_29(F, sep, ...) \ + Z_UTIL_LISTIFY_28(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(28, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_30(F, sep, ...) \ + Z_UTIL_LISTIFY_29(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(29, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_31(F, sep, ...) \ + Z_UTIL_LISTIFY_30(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(30, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_32(F, sep, ...) \ + Z_UTIL_LISTIFY_31(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(31, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_33(F, sep, ...) \ + Z_UTIL_LISTIFY_32(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(32, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_34(F, sep, ...) \ + Z_UTIL_LISTIFY_33(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(33, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_35(F, sep, ...) \ + Z_UTIL_LISTIFY_34(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(34, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_36(F, sep, ...) \ + Z_UTIL_LISTIFY_35(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(35, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_37(F, sep, ...) \ + Z_UTIL_LISTIFY_36(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(36, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_38(F, sep, ...) \ + Z_UTIL_LISTIFY_37(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(37, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_39(F, sep, ...) \ + Z_UTIL_LISTIFY_38(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(38, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_40(F, sep, ...) \ + Z_UTIL_LISTIFY_39(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(39, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_41(F, sep, ...) \ + Z_UTIL_LISTIFY_40(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(40, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_42(F, sep, ...) \ + Z_UTIL_LISTIFY_41(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(41, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_43(F, sep, ...) \ + Z_UTIL_LISTIFY_42(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(42, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_44(F, sep, ...) \ + Z_UTIL_LISTIFY_43(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(43, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_45(F, sep, ...) \ + Z_UTIL_LISTIFY_44(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(44, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_46(F, sep, ...) \ + Z_UTIL_LISTIFY_45(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(45, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_47(F, sep, ...) \ + Z_UTIL_LISTIFY_46(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(46, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_48(F, sep, ...) \ + Z_UTIL_LISTIFY_47(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(47, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_49(F, sep, ...) \ + Z_UTIL_LISTIFY_48(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(48, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_50(F, sep, ...) \ + Z_UTIL_LISTIFY_49(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(49, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_51(F, sep, ...) \ + Z_UTIL_LISTIFY_50(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(50, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_52(F, sep, ...) \ + Z_UTIL_LISTIFY_51(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(51, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_53(F, sep, ...) \ + Z_UTIL_LISTIFY_52(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(52, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_54(F, sep, ...) \ + Z_UTIL_LISTIFY_53(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(53, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_55(F, sep, ...) \ + Z_UTIL_LISTIFY_54(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(54, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_56(F, sep, ...) \ + Z_UTIL_LISTIFY_55(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(55, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_57(F, sep, ...) \ + Z_UTIL_LISTIFY_56(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(56, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_58(F, sep, ...) \ + Z_UTIL_LISTIFY_57(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(57, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_59(F, sep, ...) \ + Z_UTIL_LISTIFY_58(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(58, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_60(F, sep, ...) \ + Z_UTIL_LISTIFY_59(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(59, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_61(F, sep, ...) \ + Z_UTIL_LISTIFY_60(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(60, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_62(F, sep, ...) \ + Z_UTIL_LISTIFY_61(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(61, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_63(F, sep, ...) \ + Z_UTIL_LISTIFY_62(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(62, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_64(F, sep, ...) \ + Z_UTIL_LISTIFY_63(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(63, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_65(F, sep, ...) \ + Z_UTIL_LISTIFY_64(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(64, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_66(F, sep, ...) \ + Z_UTIL_LISTIFY_65(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(65, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_67(F, sep, ...) \ + Z_UTIL_LISTIFY_66(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(66, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_68(F, sep, ...) \ + Z_UTIL_LISTIFY_67(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(67, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_69(F, sep, ...) \ + Z_UTIL_LISTIFY_68(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(68, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_70(F, sep, ...) \ + Z_UTIL_LISTIFY_69(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(69, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_71(F, sep, ...) \ + Z_UTIL_LISTIFY_70(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(70, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_72(F, sep, ...) \ + Z_UTIL_LISTIFY_71(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(71, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_73(F, sep, ...) \ + Z_UTIL_LISTIFY_72(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(72, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_74(F, sep, ...) \ + Z_UTIL_LISTIFY_73(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(73, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_75(F, sep, ...) \ + Z_UTIL_LISTIFY_74(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(74, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_76(F, sep, ...) \ + Z_UTIL_LISTIFY_75(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(75, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_77(F, sep, ...) \ + Z_UTIL_LISTIFY_76(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(76, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_78(F, sep, ...) \ + Z_UTIL_LISTIFY_77(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(77, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_79(F, sep, ...) \ + Z_UTIL_LISTIFY_78(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(78, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_80(F, sep, ...) \ + Z_UTIL_LISTIFY_79(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(79, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_81(F, sep, ...) \ + Z_UTIL_LISTIFY_80(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(80, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_82(F, sep, ...) \ + Z_UTIL_LISTIFY_81(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(81, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_83(F, sep, ...) \ + Z_UTIL_LISTIFY_82(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(82, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_84(F, sep, ...) \ + Z_UTIL_LISTIFY_83(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(83, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_85(F, sep, ...) \ + Z_UTIL_LISTIFY_84(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(84, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_86(F, sep, ...) \ + Z_UTIL_LISTIFY_85(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(85, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_87(F, sep, ...) \ + Z_UTIL_LISTIFY_86(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(86, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_88(F, sep, ...) \ + Z_UTIL_LISTIFY_87(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(87, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_89(F, sep, ...) \ + Z_UTIL_LISTIFY_88(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(88, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_90(F, sep, ...) \ + Z_UTIL_LISTIFY_89(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(89, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_91(F, sep, ...) \ + Z_UTIL_LISTIFY_90(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(90, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_92(F, sep, ...) \ + Z_UTIL_LISTIFY_91(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(91, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_93(F, sep, ...) \ + Z_UTIL_LISTIFY_92(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(92, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_94(F, sep, ...) \ + Z_UTIL_LISTIFY_93(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(93, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_95(F, sep, ...) \ + Z_UTIL_LISTIFY_94(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(94, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_96(F, sep, ...) \ + Z_UTIL_LISTIFY_95(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(95, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_97(F, sep, ...) \ + Z_UTIL_LISTIFY_96(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(96, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_98(F, sep, ...) \ + Z_UTIL_LISTIFY_97(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(97, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_99(F, sep, ...) \ + Z_UTIL_LISTIFY_98(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(98, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_100(F, sep, ...) \ + Z_UTIL_LISTIFY_99(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(99, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_101(F, sep, ...) \ + Z_UTIL_LISTIFY_100(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(100, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_102(F, sep, ...) \ + Z_UTIL_LISTIFY_101(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(101, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_103(F, sep, ...) \ + Z_UTIL_LISTIFY_102(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(102, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_104(F, sep, ...) \ + Z_UTIL_LISTIFY_103(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(103, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_105(F, sep, ...) \ + Z_UTIL_LISTIFY_104(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(104, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_106(F, sep, ...) \ + Z_UTIL_LISTIFY_105(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(105, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_107(F, sep, ...) \ + Z_UTIL_LISTIFY_106(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(106, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_108(F, sep, ...) \ + Z_UTIL_LISTIFY_107(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(107, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_109(F, sep, ...) \ + Z_UTIL_LISTIFY_108(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(108, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_110(F, sep, ...) \ + Z_UTIL_LISTIFY_109(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(109, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_111(F, sep, ...) \ + Z_UTIL_LISTIFY_110(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(110, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_112(F, sep, ...) \ + Z_UTIL_LISTIFY_111(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(111, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_113(F, sep, ...) \ + Z_UTIL_LISTIFY_112(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(112, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_114(F, sep, ...) \ + Z_UTIL_LISTIFY_113(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(113, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_115(F, sep, ...) \ + Z_UTIL_LISTIFY_114(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(114, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_116(F, sep, ...) \ + Z_UTIL_LISTIFY_115(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(115, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_117(F, sep, ...) \ + Z_UTIL_LISTIFY_116(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(116, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_118(F, sep, ...) \ + Z_UTIL_LISTIFY_117(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(117, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_119(F, sep, ...) \ + Z_UTIL_LISTIFY_118(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(118, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_120(F, sep, ...) \ + Z_UTIL_LISTIFY_119(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(119, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_121(F, sep, ...) \ + Z_UTIL_LISTIFY_120(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(120, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_122(F, sep, ...) \ + Z_UTIL_LISTIFY_121(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(121, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_123(F, sep, ...) \ + Z_UTIL_LISTIFY_122(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(122, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_124(F, sep, ...) \ + Z_UTIL_LISTIFY_123(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(123, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_125(F, sep, ...) \ + Z_UTIL_LISTIFY_124(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(124, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_126(F, sep, ...) \ + Z_UTIL_LISTIFY_125(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(125, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_127(F, sep, ...) \ + Z_UTIL_LISTIFY_126(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(126, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_128(F, sep, ...) \ + Z_UTIL_LISTIFY_127(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(127, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_129(F, sep, ...) \ + Z_UTIL_LISTIFY_128(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(128, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_130(F, sep, ...) \ + Z_UTIL_LISTIFY_129(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(129, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_131(F, sep, ...) \ + Z_UTIL_LISTIFY_130(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(130, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_132(F, sep, ...) \ + Z_UTIL_LISTIFY_131(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(131, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_133(F, sep, ...) \ + Z_UTIL_LISTIFY_132(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(132, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_134(F, sep, ...) \ + Z_UTIL_LISTIFY_133(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(133, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_135(F, sep, ...) \ + Z_UTIL_LISTIFY_134(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(134, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_136(F, sep, ...) \ + Z_UTIL_LISTIFY_135(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(135, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_137(F, sep, ...) \ + Z_UTIL_LISTIFY_136(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(136, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_138(F, sep, ...) \ + Z_UTIL_LISTIFY_137(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(137, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_139(F, sep, ...) \ + Z_UTIL_LISTIFY_138(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(138, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_140(F, sep, ...) \ + Z_UTIL_LISTIFY_139(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(139, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_141(F, sep, ...) \ + Z_UTIL_LISTIFY_140(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(140, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_142(F, sep, ...) \ + Z_UTIL_LISTIFY_141(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(141, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_143(F, sep, ...) \ + Z_UTIL_LISTIFY_142(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(142, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_144(F, sep, ...) \ + Z_UTIL_LISTIFY_143(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(143, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_145(F, sep, ...) \ + Z_UTIL_LISTIFY_144(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(144, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_146(F, sep, ...) \ + Z_UTIL_LISTIFY_145(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(145, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_147(F, sep, ...) \ + Z_UTIL_LISTIFY_146(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(146, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_148(F, sep, ...) \ + Z_UTIL_LISTIFY_147(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(147, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_149(F, sep, ...) \ + Z_UTIL_LISTIFY_148(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(148, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_150(F, sep, ...) \ + Z_UTIL_LISTIFY_149(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(149, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_151(F, sep, ...) \ + Z_UTIL_LISTIFY_150(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(150, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_152(F, sep, ...) \ + Z_UTIL_LISTIFY_151(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(151, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_153(F, sep, ...) \ + Z_UTIL_LISTIFY_152(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(152, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_154(F, sep, ...) \ + Z_UTIL_LISTIFY_153(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(153, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_155(F, sep, ...) \ + Z_UTIL_LISTIFY_154(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(154, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_156(F, sep, ...) \ + Z_UTIL_LISTIFY_155(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(155, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_157(F, sep, ...) \ + Z_UTIL_LISTIFY_156(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(156, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_158(F, sep, ...) \ + Z_UTIL_LISTIFY_157(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(157, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_159(F, sep, ...) \ + Z_UTIL_LISTIFY_158(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(158, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_160(F, sep, ...) \ + Z_UTIL_LISTIFY_159(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(159, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_161(F, sep, ...) \ + Z_UTIL_LISTIFY_160(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(160, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_162(F, sep, ...) \ + Z_UTIL_LISTIFY_161(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(161, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_163(F, sep, ...) \ + Z_UTIL_LISTIFY_162(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(162, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_164(F, sep, ...) \ + Z_UTIL_LISTIFY_163(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(163, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_165(F, sep, ...) \ + Z_UTIL_LISTIFY_164(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(164, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_166(F, sep, ...) \ + Z_UTIL_LISTIFY_165(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(165, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_167(F, sep, ...) \ + Z_UTIL_LISTIFY_166(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(166, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_168(F, sep, ...) \ + Z_UTIL_LISTIFY_167(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(167, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_169(F, sep, ...) \ + Z_UTIL_LISTIFY_168(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(168, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_170(F, sep, ...) \ + Z_UTIL_LISTIFY_169(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(169, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_171(F, sep, ...) \ + Z_UTIL_LISTIFY_170(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(170, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_172(F, sep, ...) \ + Z_UTIL_LISTIFY_171(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(171, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_173(F, sep, ...) \ + Z_UTIL_LISTIFY_172(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(172, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_174(F, sep, ...) \ + Z_UTIL_LISTIFY_173(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(173, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_175(F, sep, ...) \ + Z_UTIL_LISTIFY_174(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(174, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_176(F, sep, ...) \ + Z_UTIL_LISTIFY_175(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(175, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_177(F, sep, ...) \ + Z_UTIL_LISTIFY_176(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(176, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_178(F, sep, ...) \ + Z_UTIL_LISTIFY_177(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(177, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_179(F, sep, ...) \ + Z_UTIL_LISTIFY_178(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(178, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_180(F, sep, ...) \ + Z_UTIL_LISTIFY_179(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(179, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_181(F, sep, ...) \ + Z_UTIL_LISTIFY_180(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(180, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_182(F, sep, ...) \ + Z_UTIL_LISTIFY_181(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(181, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_183(F, sep, ...) \ + Z_UTIL_LISTIFY_182(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(182, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_184(F, sep, ...) \ + Z_UTIL_LISTIFY_183(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(183, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_185(F, sep, ...) \ + Z_UTIL_LISTIFY_184(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(184, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_186(F, sep, ...) \ + Z_UTIL_LISTIFY_185(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(185, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_187(F, sep, ...) \ + Z_UTIL_LISTIFY_186(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(186, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_188(F, sep, ...) \ + Z_UTIL_LISTIFY_187(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(187, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_189(F, sep, ...) \ + Z_UTIL_LISTIFY_188(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(188, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_190(F, sep, ...) \ + Z_UTIL_LISTIFY_189(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(189, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_191(F, sep, ...) \ + Z_UTIL_LISTIFY_190(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(190, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_192(F, sep, ...) \ + Z_UTIL_LISTIFY_191(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(191, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_193(F, sep, ...) \ + Z_UTIL_LISTIFY_192(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(192, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_194(F, sep, ...) \ + Z_UTIL_LISTIFY_193(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(193, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_195(F, sep, ...) \ + Z_UTIL_LISTIFY_194(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(194, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_196(F, sep, ...) \ + Z_UTIL_LISTIFY_195(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(195, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_197(F, sep, ...) \ + Z_UTIL_LISTIFY_196(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(196, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_198(F, sep, ...) \ + Z_UTIL_LISTIFY_197(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(197, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_199(F, sep, ...) \ + Z_UTIL_LISTIFY_198(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(198, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_200(F, sep, ...) \ + Z_UTIL_LISTIFY_199(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(199, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_201(F, sep, ...) \ + Z_UTIL_LISTIFY_200(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(200, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_202(F, sep, ...) \ + Z_UTIL_LISTIFY_201(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(201, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_203(F, sep, ...) \ + Z_UTIL_LISTIFY_202(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(202, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_204(F, sep, ...) \ + Z_UTIL_LISTIFY_203(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(203, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_205(F, sep, ...) \ + Z_UTIL_LISTIFY_204(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(204, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_206(F, sep, ...) \ + Z_UTIL_LISTIFY_205(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(205, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_207(F, sep, ...) \ + Z_UTIL_LISTIFY_206(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(206, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_208(F, sep, ...) \ + Z_UTIL_LISTIFY_207(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(207, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_209(F, sep, ...) \ + Z_UTIL_LISTIFY_208(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(208, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_210(F, sep, ...) \ + Z_UTIL_LISTIFY_209(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(209, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_211(F, sep, ...) \ + Z_UTIL_LISTIFY_210(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(210, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_212(F, sep, ...) \ + Z_UTIL_LISTIFY_211(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(211, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_213(F, sep, ...) \ + Z_UTIL_LISTIFY_212(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(212, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_214(F, sep, ...) \ + Z_UTIL_LISTIFY_213(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(213, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_215(F, sep, ...) \ + Z_UTIL_LISTIFY_214(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(214, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_216(F, sep, ...) \ + Z_UTIL_LISTIFY_215(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(215, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_217(F, sep, ...) \ + Z_UTIL_LISTIFY_216(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(216, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_218(F, sep, ...) \ + Z_UTIL_LISTIFY_217(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(217, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_219(F, sep, ...) \ + Z_UTIL_LISTIFY_218(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(218, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_220(F, sep, ...) \ + Z_UTIL_LISTIFY_219(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(219, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_221(F, sep, ...) \ + Z_UTIL_LISTIFY_220(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(220, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_222(F, sep, ...) \ + Z_UTIL_LISTIFY_221(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(221, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_223(F, sep, ...) \ + Z_UTIL_LISTIFY_222(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(222, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_224(F, sep, ...) \ + Z_UTIL_LISTIFY_223(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(223, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_225(F, sep, ...) \ + Z_UTIL_LISTIFY_224(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(224, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_226(F, sep, ...) \ + Z_UTIL_LISTIFY_225(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(225, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_227(F, sep, ...) \ + Z_UTIL_LISTIFY_226(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(226, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_228(F, sep, ...) \ + Z_UTIL_LISTIFY_227(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(227, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_229(F, sep, ...) \ + Z_UTIL_LISTIFY_228(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(228, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_230(F, sep, ...) \ + Z_UTIL_LISTIFY_229(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(229, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_231(F, sep, ...) \ + Z_UTIL_LISTIFY_230(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(230, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_232(F, sep, ...) \ + Z_UTIL_LISTIFY_231(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(231, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_233(F, sep, ...) \ + Z_UTIL_LISTIFY_232(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(232, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_234(F, sep, ...) \ + Z_UTIL_LISTIFY_233(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(233, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_235(F, sep, ...) \ + Z_UTIL_LISTIFY_234(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(234, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_236(F, sep, ...) \ + Z_UTIL_LISTIFY_235(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(235, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_237(F, sep, ...) \ + Z_UTIL_LISTIFY_236(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(236, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_238(F, sep, ...) \ + Z_UTIL_LISTIFY_237(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(237, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_239(F, sep, ...) \ + Z_UTIL_LISTIFY_238(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(238, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_240(F, sep, ...) \ + Z_UTIL_LISTIFY_239(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(239, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_241(F, sep, ...) \ + Z_UTIL_LISTIFY_240(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(240, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_242(F, sep, ...) \ + Z_UTIL_LISTIFY_241(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(241, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_243(F, sep, ...) \ + Z_UTIL_LISTIFY_242(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(242, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_244(F, sep, ...) \ + Z_UTIL_LISTIFY_243(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(243, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_245(F, sep, ...) \ + Z_UTIL_LISTIFY_244(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(244, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_246(F, sep, ...) \ + Z_UTIL_LISTIFY_245(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(245, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_247(F, sep, ...) \ + Z_UTIL_LISTIFY_246(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(246, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_248(F, sep, ...) \ + Z_UTIL_LISTIFY_247(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(247, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_249(F, sep, ...) \ + Z_UTIL_LISTIFY_248(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(248, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_250(F, sep, ...) \ + Z_UTIL_LISTIFY_249(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(249, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_251(F, sep, ...) \ + Z_UTIL_LISTIFY_250(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(250, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_252(F, sep, ...) \ + Z_UTIL_LISTIFY_251(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(251, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_253(F, sep, ...) \ + Z_UTIL_LISTIFY_252(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(252, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_254(F, sep, ...) \ + Z_UTIL_LISTIFY_253(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(253, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_255(F, sep, ...) \ + Z_UTIL_LISTIFY_254(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(254, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_256(F, sep, ...) \ + Z_UTIL_LISTIFY_255(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(255, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_257(F, sep, ...) \ + Z_UTIL_LISTIFY_256(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(256, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_258(F, sep, ...) \ + Z_UTIL_LISTIFY_257(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(257, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_259(F, sep, ...) \ + Z_UTIL_LISTIFY_258(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(258, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_260(F, sep, ...) \ + Z_UTIL_LISTIFY_259(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(259, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_261(F, sep, ...) \ + Z_UTIL_LISTIFY_260(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(260, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_262(F, sep, ...) \ + Z_UTIL_LISTIFY_261(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(261, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_263(F, sep, ...) \ + Z_UTIL_LISTIFY_262(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(262, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_264(F, sep, ...) \ + Z_UTIL_LISTIFY_263(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(263, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_265(F, sep, ...) \ + Z_UTIL_LISTIFY_264(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(264, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_266(F, sep, ...) \ + Z_UTIL_LISTIFY_265(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(265, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_267(F, sep, ...) \ + Z_UTIL_LISTIFY_266(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(266, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_268(F, sep, ...) \ + Z_UTIL_LISTIFY_267(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(267, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_269(F, sep, ...) \ + Z_UTIL_LISTIFY_268(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(268, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_270(F, sep, ...) \ + Z_UTIL_LISTIFY_269(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(269, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_271(F, sep, ...) \ + Z_UTIL_LISTIFY_270(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(270, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_272(F, sep, ...) \ + Z_UTIL_LISTIFY_271(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(271, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_273(F, sep, ...) \ + Z_UTIL_LISTIFY_272(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(272, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_274(F, sep, ...) \ + Z_UTIL_LISTIFY_273(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(273, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_275(F, sep, ...) \ + Z_UTIL_LISTIFY_274(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(274, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_276(F, sep, ...) \ + Z_UTIL_LISTIFY_275(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(275, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_277(F, sep, ...) \ + Z_UTIL_LISTIFY_276(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(276, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_278(F, sep, ...) \ + Z_UTIL_LISTIFY_277(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(277, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_279(F, sep, ...) \ + Z_UTIL_LISTIFY_278(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(278, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_280(F, sep, ...) \ + Z_UTIL_LISTIFY_279(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(279, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_281(F, sep, ...) \ + Z_UTIL_LISTIFY_280(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(280, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_282(F, sep, ...) \ + Z_UTIL_LISTIFY_281(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(281, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_283(F, sep, ...) \ + Z_UTIL_LISTIFY_282(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(282, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_284(F, sep, ...) \ + Z_UTIL_LISTIFY_283(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(283, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_285(F, sep, ...) \ + Z_UTIL_LISTIFY_284(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(284, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_286(F, sep, ...) \ + Z_UTIL_LISTIFY_285(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(285, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_287(F, sep, ...) \ + Z_UTIL_LISTIFY_286(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(286, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_288(F, sep, ...) \ + Z_UTIL_LISTIFY_287(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(287, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_289(F, sep, ...) \ + Z_UTIL_LISTIFY_288(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(288, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_290(F, sep, ...) \ + Z_UTIL_LISTIFY_289(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(289, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_291(F, sep, ...) \ + Z_UTIL_LISTIFY_290(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(290, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_292(F, sep, ...) \ + Z_UTIL_LISTIFY_291(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(291, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_293(F, sep, ...) \ + Z_UTIL_LISTIFY_292(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(292, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_294(F, sep, ...) \ + Z_UTIL_LISTIFY_293(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(293, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_295(F, sep, ...) \ + Z_UTIL_LISTIFY_294(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(294, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_296(F, sep, ...) \ + Z_UTIL_LISTIFY_295(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(295, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_297(F, sep, ...) \ + Z_UTIL_LISTIFY_296(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(296, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_298(F, sep, ...) \ + Z_UTIL_LISTIFY_297(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(297, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_299(F, sep, ...) \ + Z_UTIL_LISTIFY_298(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(298, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_300(F, sep, ...) \ + Z_UTIL_LISTIFY_299(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(299, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_301(F, sep, ...) \ + Z_UTIL_LISTIFY_300(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(300, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_302(F, sep, ...) \ + Z_UTIL_LISTIFY_301(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(301, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_303(F, sep, ...) \ + Z_UTIL_LISTIFY_302(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(302, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_304(F, sep, ...) \ + Z_UTIL_LISTIFY_303(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(303, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_305(F, sep, ...) \ + Z_UTIL_LISTIFY_304(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(304, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_306(F, sep, ...) \ + Z_UTIL_LISTIFY_305(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(305, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_307(F, sep, ...) \ + Z_UTIL_LISTIFY_306(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(306, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_308(F, sep, ...) \ + Z_UTIL_LISTIFY_307(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(307, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_309(F, sep, ...) \ + Z_UTIL_LISTIFY_308(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(308, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_310(F, sep, ...) \ + Z_UTIL_LISTIFY_309(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(309, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_311(F, sep, ...) \ + Z_UTIL_LISTIFY_310(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(310, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_312(F, sep, ...) \ + Z_UTIL_LISTIFY_311(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(311, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_313(F, sep, ...) \ + Z_UTIL_LISTIFY_312(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(312, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_314(F, sep, ...) \ + Z_UTIL_LISTIFY_313(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(313, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_315(F, sep, ...) \ + Z_UTIL_LISTIFY_314(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(314, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_316(F, sep, ...) \ + Z_UTIL_LISTIFY_315(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(315, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_317(F, sep, ...) \ + Z_UTIL_LISTIFY_316(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(316, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_318(F, sep, ...) \ + Z_UTIL_LISTIFY_317(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(317, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_319(F, sep, ...) \ + Z_UTIL_LISTIFY_318(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(318, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_320(F, sep, ...) \ + Z_UTIL_LISTIFY_319(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(319, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_321(F, sep, ...) \ + Z_UTIL_LISTIFY_320(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(320, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_322(F, sep, ...) \ + Z_UTIL_LISTIFY_321(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(321, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_323(F, sep, ...) \ + Z_UTIL_LISTIFY_322(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(322, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_324(F, sep, ...) \ + Z_UTIL_LISTIFY_323(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(323, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_325(F, sep, ...) \ + Z_UTIL_LISTIFY_324(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(324, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_326(F, sep, ...) \ + Z_UTIL_LISTIFY_325(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(325, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_327(F, sep, ...) \ + Z_UTIL_LISTIFY_326(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(326, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_328(F, sep, ...) \ + Z_UTIL_LISTIFY_327(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(327, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_329(F, sep, ...) \ + Z_UTIL_LISTIFY_328(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(328, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_330(F, sep, ...) \ + Z_UTIL_LISTIFY_329(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(329, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_331(F, sep, ...) \ + Z_UTIL_LISTIFY_330(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(330, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_332(F, sep, ...) \ + Z_UTIL_LISTIFY_331(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(331, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_333(F, sep, ...) \ + Z_UTIL_LISTIFY_332(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(332, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_334(F, sep, ...) \ + Z_UTIL_LISTIFY_333(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(333, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_335(F, sep, ...) \ + Z_UTIL_LISTIFY_334(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(334, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_336(F, sep, ...) \ + Z_UTIL_LISTIFY_335(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(335, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_337(F, sep, ...) \ + Z_UTIL_LISTIFY_336(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(336, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_338(F, sep, ...) \ + Z_UTIL_LISTIFY_337(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(337, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_339(F, sep, ...) \ + Z_UTIL_LISTIFY_338(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(338, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_340(F, sep, ...) \ + Z_UTIL_LISTIFY_339(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(339, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_341(F, sep, ...) \ + Z_UTIL_LISTIFY_340(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(340, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_342(F, sep, ...) \ + Z_UTIL_LISTIFY_341(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(341, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_343(F, sep, ...) \ + Z_UTIL_LISTIFY_342(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(342, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_344(F, sep, ...) \ + Z_UTIL_LISTIFY_343(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(343, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_345(F, sep, ...) \ + Z_UTIL_LISTIFY_344(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(344, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_346(F, sep, ...) \ + Z_UTIL_LISTIFY_345(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(345, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_347(F, sep, ...) \ + Z_UTIL_LISTIFY_346(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(346, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_348(F, sep, ...) \ + Z_UTIL_LISTIFY_347(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(347, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_349(F, sep, ...) \ + Z_UTIL_LISTIFY_348(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(348, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_350(F, sep, ...) \ + Z_UTIL_LISTIFY_349(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(349, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_351(F, sep, ...) \ + Z_UTIL_LISTIFY_350(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(350, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_352(F, sep, ...) \ + Z_UTIL_LISTIFY_351(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(351, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_353(F, sep, ...) \ + Z_UTIL_LISTIFY_352(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(352, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_354(F, sep, ...) \ + Z_UTIL_LISTIFY_353(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(353, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_355(F, sep, ...) \ + Z_UTIL_LISTIFY_354(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(354, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_356(F, sep, ...) \ + Z_UTIL_LISTIFY_355(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(355, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_357(F, sep, ...) \ + Z_UTIL_LISTIFY_356(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(356, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_358(F, sep, ...) \ + Z_UTIL_LISTIFY_357(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(357, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_359(F, sep, ...) \ + Z_UTIL_LISTIFY_358(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(358, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_360(F, sep, ...) \ + Z_UTIL_LISTIFY_359(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(359, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_361(F, sep, ...) \ + Z_UTIL_LISTIFY_360(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(360, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_362(F, sep, ...) \ + Z_UTIL_LISTIFY_361(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(361, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_363(F, sep, ...) \ + Z_UTIL_LISTIFY_362(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(362, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_364(F, sep, ...) \ + Z_UTIL_LISTIFY_363(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(363, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_365(F, sep, ...) \ + Z_UTIL_LISTIFY_364(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(364, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_366(F, sep, ...) \ + Z_UTIL_LISTIFY_365(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(365, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_367(F, sep, ...) \ + Z_UTIL_LISTIFY_366(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(366, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_368(F, sep, ...) \ + Z_UTIL_LISTIFY_367(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(367, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_369(F, sep, ...) \ + Z_UTIL_LISTIFY_368(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(368, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_370(F, sep, ...) \ + Z_UTIL_LISTIFY_369(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(369, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_371(F, sep, ...) \ + Z_UTIL_LISTIFY_370(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(370, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_372(F, sep, ...) \ + Z_UTIL_LISTIFY_371(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(371, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_373(F, sep, ...) \ + Z_UTIL_LISTIFY_372(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(372, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_374(F, sep, ...) \ + Z_UTIL_LISTIFY_373(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(373, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_375(F, sep, ...) \ + Z_UTIL_LISTIFY_374(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(374, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_376(F, sep, ...) \ + Z_UTIL_LISTIFY_375(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(375, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_377(F, sep, ...) \ + Z_UTIL_LISTIFY_376(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(376, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_378(F, sep, ...) \ + Z_UTIL_LISTIFY_377(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(377, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_379(F, sep, ...) \ + Z_UTIL_LISTIFY_378(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(378, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_380(F, sep, ...) \ + Z_UTIL_LISTIFY_379(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(379, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_381(F, sep, ...) \ + Z_UTIL_LISTIFY_380(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(380, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_382(F, sep, ...) \ + Z_UTIL_LISTIFY_381(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(381, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_383(F, sep, ...) \ + Z_UTIL_LISTIFY_382(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(382, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_384(F, sep, ...) \ + Z_UTIL_LISTIFY_383(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(383, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_385(F, sep, ...) \ + Z_UTIL_LISTIFY_384(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(384, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_386(F, sep, ...) \ + Z_UTIL_LISTIFY_385(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(385, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_387(F, sep, ...) \ + Z_UTIL_LISTIFY_386(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(386, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_388(F, sep, ...) \ + Z_UTIL_LISTIFY_387(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(387, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_389(F, sep, ...) \ + Z_UTIL_LISTIFY_388(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(388, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_390(F, sep, ...) \ + Z_UTIL_LISTIFY_389(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(389, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_391(F, sep, ...) \ + Z_UTIL_LISTIFY_390(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(390, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_392(F, sep, ...) \ + Z_UTIL_LISTIFY_391(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(391, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_393(F, sep, ...) \ + Z_UTIL_LISTIFY_392(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(392, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_394(F, sep, ...) \ + Z_UTIL_LISTIFY_393(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(393, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_395(F, sep, ...) \ + Z_UTIL_LISTIFY_394(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(394, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_396(F, sep, ...) \ + Z_UTIL_LISTIFY_395(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(395, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_397(F, sep, ...) \ + Z_UTIL_LISTIFY_396(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(396, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_398(F, sep, ...) \ + Z_UTIL_LISTIFY_397(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(397, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_399(F, sep, ...) \ + Z_UTIL_LISTIFY_398(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(398, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_400(F, sep, ...) \ + Z_UTIL_LISTIFY_399(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(399, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_401(F, sep, ...) \ + Z_UTIL_LISTIFY_400(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(400, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_402(F, sep, ...) \ + Z_UTIL_LISTIFY_401(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(401, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_403(F, sep, ...) \ + Z_UTIL_LISTIFY_402(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(402, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_404(F, sep, ...) \ + Z_UTIL_LISTIFY_403(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(403, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_405(F, sep, ...) \ + Z_UTIL_LISTIFY_404(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(404, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_406(F, sep, ...) \ + Z_UTIL_LISTIFY_405(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(405, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_407(F, sep, ...) \ + Z_UTIL_LISTIFY_406(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(406, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_408(F, sep, ...) \ + Z_UTIL_LISTIFY_407(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(407, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_409(F, sep, ...) \ + Z_UTIL_LISTIFY_408(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(408, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_410(F, sep, ...) \ + Z_UTIL_LISTIFY_409(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(409, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_411(F, sep, ...) \ + Z_UTIL_LISTIFY_410(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(410, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_412(F, sep, ...) \ + Z_UTIL_LISTIFY_411(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(411, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_413(F, sep, ...) \ + Z_UTIL_LISTIFY_412(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(412, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_414(F, sep, ...) \ + Z_UTIL_LISTIFY_413(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(413, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_415(F, sep, ...) \ + Z_UTIL_LISTIFY_414(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(414, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_416(F, sep, ...) \ + Z_UTIL_LISTIFY_415(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(415, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_417(F, sep, ...) \ + Z_UTIL_LISTIFY_416(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(416, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_418(F, sep, ...) \ + Z_UTIL_LISTIFY_417(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(417, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_419(F, sep, ...) \ + Z_UTIL_LISTIFY_418(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(418, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_420(F, sep, ...) \ + Z_UTIL_LISTIFY_419(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(419, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_421(F, sep, ...) \ + Z_UTIL_LISTIFY_420(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(420, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_422(F, sep, ...) \ + Z_UTIL_LISTIFY_421(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(421, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_423(F, sep, ...) \ + Z_UTIL_LISTIFY_422(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(422, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_424(F, sep, ...) \ + Z_UTIL_LISTIFY_423(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(423, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_425(F, sep, ...) \ + Z_UTIL_LISTIFY_424(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(424, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_426(F, sep, ...) \ + Z_UTIL_LISTIFY_425(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(425, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_427(F, sep, ...) \ + Z_UTIL_LISTIFY_426(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(426, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_428(F, sep, ...) \ + Z_UTIL_LISTIFY_427(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(427, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_429(F, sep, ...) \ + Z_UTIL_LISTIFY_428(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(428, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_430(F, sep, ...) \ + Z_UTIL_LISTIFY_429(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(429, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_431(F, sep, ...) \ + Z_UTIL_LISTIFY_430(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(430, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_432(F, sep, ...) \ + Z_UTIL_LISTIFY_431(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(431, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_433(F, sep, ...) \ + Z_UTIL_LISTIFY_432(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(432, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_434(F, sep, ...) \ + Z_UTIL_LISTIFY_433(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(433, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_435(F, sep, ...) \ + Z_UTIL_LISTIFY_434(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(434, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_436(F, sep, ...) \ + Z_UTIL_LISTIFY_435(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(435, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_437(F, sep, ...) \ + Z_UTIL_LISTIFY_436(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(436, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_438(F, sep, ...) \ + Z_UTIL_LISTIFY_437(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(437, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_439(F, sep, ...) \ + Z_UTIL_LISTIFY_438(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(438, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_440(F, sep, ...) \ + Z_UTIL_LISTIFY_439(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(439, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_441(F, sep, ...) \ + Z_UTIL_LISTIFY_440(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(440, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_442(F, sep, ...) \ + Z_UTIL_LISTIFY_441(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(441, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_443(F, sep, ...) \ + Z_UTIL_LISTIFY_442(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(442, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_444(F, sep, ...) \ + Z_UTIL_LISTIFY_443(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(443, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_445(F, sep, ...) \ + Z_UTIL_LISTIFY_444(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(444, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_446(F, sep, ...) \ + Z_UTIL_LISTIFY_445(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(445, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_447(F, sep, ...) \ + Z_UTIL_LISTIFY_446(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(446, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_448(F, sep, ...) \ + Z_UTIL_LISTIFY_447(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(447, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_449(F, sep, ...) \ + Z_UTIL_LISTIFY_448(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(448, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_450(F, sep, ...) \ + Z_UTIL_LISTIFY_449(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(449, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_451(F, sep, ...) \ + Z_UTIL_LISTIFY_450(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(450, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_452(F, sep, ...) \ + Z_UTIL_LISTIFY_451(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(451, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_453(F, sep, ...) \ + Z_UTIL_LISTIFY_452(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(452, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_454(F, sep, ...) \ + Z_UTIL_LISTIFY_453(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(453, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_455(F, sep, ...) \ + Z_UTIL_LISTIFY_454(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(454, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_456(F, sep, ...) \ + Z_UTIL_LISTIFY_455(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(455, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_457(F, sep, ...) \ + Z_UTIL_LISTIFY_456(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(456, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_458(F, sep, ...) \ + Z_UTIL_LISTIFY_457(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(457, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_459(F, sep, ...) \ + Z_UTIL_LISTIFY_458(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(458, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_460(F, sep, ...) \ + Z_UTIL_LISTIFY_459(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(459, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_461(F, sep, ...) \ + Z_UTIL_LISTIFY_460(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(460, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_462(F, sep, ...) \ + Z_UTIL_LISTIFY_461(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(461, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_463(F, sep, ...) \ + Z_UTIL_LISTIFY_462(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(462, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_464(F, sep, ...) \ + Z_UTIL_LISTIFY_463(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(463, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_465(F, sep, ...) \ + Z_UTIL_LISTIFY_464(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(464, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_466(F, sep, ...) \ + Z_UTIL_LISTIFY_465(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(465, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_467(F, sep, ...) \ + Z_UTIL_LISTIFY_466(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(466, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_468(F, sep, ...) \ + Z_UTIL_LISTIFY_467(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(467, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_469(F, sep, ...) \ + Z_UTIL_LISTIFY_468(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(468, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_470(F, sep, ...) \ + Z_UTIL_LISTIFY_469(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(469, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_471(F, sep, ...) \ + Z_UTIL_LISTIFY_470(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(470, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_472(F, sep, ...) \ + Z_UTIL_LISTIFY_471(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(471, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_473(F, sep, ...) \ + Z_UTIL_LISTIFY_472(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(472, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_474(F, sep, ...) \ + Z_UTIL_LISTIFY_473(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(473, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_475(F, sep, ...) \ + Z_UTIL_LISTIFY_474(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(474, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_476(F, sep, ...) \ + Z_UTIL_LISTIFY_475(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(475, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_477(F, sep, ...) \ + Z_UTIL_LISTIFY_476(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(476, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_478(F, sep, ...) \ + Z_UTIL_LISTIFY_477(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(477, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_479(F, sep, ...) \ + Z_UTIL_LISTIFY_478(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(478, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_480(F, sep, ...) \ + Z_UTIL_LISTIFY_479(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(479, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_481(F, sep, ...) \ + Z_UTIL_LISTIFY_480(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(480, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_482(F, sep, ...) \ + Z_UTIL_LISTIFY_481(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(481, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_483(F, sep, ...) \ + Z_UTIL_LISTIFY_482(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(482, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_484(F, sep, ...) \ + Z_UTIL_LISTIFY_483(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(483, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_485(F, sep, ...) \ + Z_UTIL_LISTIFY_484(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(484, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_486(F, sep, ...) \ + Z_UTIL_LISTIFY_485(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(485, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_487(F, sep, ...) \ + Z_UTIL_LISTIFY_486(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(486, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_488(F, sep, ...) \ + Z_UTIL_LISTIFY_487(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(487, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_489(F, sep, ...) \ + Z_UTIL_LISTIFY_488(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(488, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_490(F, sep, ...) \ + Z_UTIL_LISTIFY_489(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(489, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_491(F, sep, ...) \ + Z_UTIL_LISTIFY_490(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(490, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_492(F, sep, ...) \ + Z_UTIL_LISTIFY_491(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(491, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_493(F, sep, ...) \ + Z_UTIL_LISTIFY_492(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(492, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_494(F, sep, ...) \ + Z_UTIL_LISTIFY_493(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(493, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_495(F, sep, ...) \ + Z_UTIL_LISTIFY_494(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(494, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_496(F, sep, ...) \ + Z_UTIL_LISTIFY_495(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(495, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_497(F, sep, ...) \ + Z_UTIL_LISTIFY_496(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(496, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_498(F, sep, ...) \ + Z_UTIL_LISTIFY_497(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(497, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_499(F, sep, ...) \ + Z_UTIL_LISTIFY_498(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(498, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_500(F, sep, ...) \ + Z_UTIL_LISTIFY_499(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(499, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_501(F, sep, ...) \ + Z_UTIL_LISTIFY_500(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(500, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_502(F, sep, ...) \ + Z_UTIL_LISTIFY_501(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(501, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_503(F, sep, ...) \ + Z_UTIL_LISTIFY_502(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(502, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_504(F, sep, ...) \ + Z_UTIL_LISTIFY_503(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(503, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_505(F, sep, ...) \ + Z_UTIL_LISTIFY_504(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(504, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_506(F, sep, ...) \ + Z_UTIL_LISTIFY_505(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(505, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_507(F, sep, ...) \ + Z_UTIL_LISTIFY_506(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(506, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_508(F, sep, ...) \ + Z_UTIL_LISTIFY_507(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(507, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_509(F, sep, ...) \ + Z_UTIL_LISTIFY_508(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(508, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_510(F, sep, ...) \ + Z_UTIL_LISTIFY_509(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(509, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_511(F, sep, ...) \ + Z_UTIL_LISTIFY_510(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(510, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_512(F, sep, ...) \ + Z_UTIL_LISTIFY_511(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(511, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_513(F, sep, ...) \ + Z_UTIL_LISTIFY_512(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(512, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_514(F, sep, ...) \ + Z_UTIL_LISTIFY_513(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(513, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_515(F, sep, ...) \ + Z_UTIL_LISTIFY_514(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(514, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_516(F, sep, ...) \ + Z_UTIL_LISTIFY_515(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(515, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_517(F, sep, ...) \ + Z_UTIL_LISTIFY_516(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(516, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_518(F, sep, ...) \ + Z_UTIL_LISTIFY_517(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(517, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_519(F, sep, ...) \ + Z_UTIL_LISTIFY_518(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(518, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_520(F, sep, ...) \ + Z_UTIL_LISTIFY_519(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(519, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_521(F, sep, ...) \ + Z_UTIL_LISTIFY_520(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(520, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_522(F, sep, ...) \ + Z_UTIL_LISTIFY_521(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(521, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_523(F, sep, ...) \ + Z_UTIL_LISTIFY_522(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(522, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_524(F, sep, ...) \ + Z_UTIL_LISTIFY_523(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(523, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_525(F, sep, ...) \ + Z_UTIL_LISTIFY_524(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(524, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_526(F, sep, ...) \ + Z_UTIL_LISTIFY_525(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(525, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_527(F, sep, ...) \ + Z_UTIL_LISTIFY_526(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(526, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_528(F, sep, ...) \ + Z_UTIL_LISTIFY_527(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(527, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_529(F, sep, ...) \ + Z_UTIL_LISTIFY_528(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(528, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_530(F, sep, ...) \ + Z_UTIL_LISTIFY_529(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(529, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_531(F, sep, ...) \ + Z_UTIL_LISTIFY_530(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(530, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_532(F, sep, ...) \ + Z_UTIL_LISTIFY_531(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(531, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_533(F, sep, ...) \ + Z_UTIL_LISTIFY_532(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(532, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_534(F, sep, ...) \ + Z_UTIL_LISTIFY_533(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(533, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_535(F, sep, ...) \ + Z_UTIL_LISTIFY_534(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(534, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_536(F, sep, ...) \ + Z_UTIL_LISTIFY_535(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(535, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_537(F, sep, ...) \ + Z_UTIL_LISTIFY_536(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(536, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_538(F, sep, ...) \ + Z_UTIL_LISTIFY_537(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(537, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_539(F, sep, ...) \ + Z_UTIL_LISTIFY_538(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(538, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_540(F, sep, ...) \ + Z_UTIL_LISTIFY_539(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(539, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_541(F, sep, ...) \ + Z_UTIL_LISTIFY_540(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(540, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_542(F, sep, ...) \ + Z_UTIL_LISTIFY_541(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(541, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_543(F, sep, ...) \ + Z_UTIL_LISTIFY_542(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(542, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_544(F, sep, ...) \ + Z_UTIL_LISTIFY_543(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(543, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_545(F, sep, ...) \ + Z_UTIL_LISTIFY_544(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(544, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_546(F, sep, ...) \ + Z_UTIL_LISTIFY_545(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(545, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_547(F, sep, ...) \ + Z_UTIL_LISTIFY_546(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(546, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_548(F, sep, ...) \ + Z_UTIL_LISTIFY_547(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(547, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_549(F, sep, ...) \ + Z_UTIL_LISTIFY_548(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(548, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_550(F, sep, ...) \ + Z_UTIL_LISTIFY_549(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(549, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_551(F, sep, ...) \ + Z_UTIL_LISTIFY_550(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(550, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_552(F, sep, ...) \ + Z_UTIL_LISTIFY_551(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(551, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_553(F, sep, ...) \ + Z_UTIL_LISTIFY_552(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(552, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_554(F, sep, ...) \ + Z_UTIL_LISTIFY_553(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(553, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_555(F, sep, ...) \ + Z_UTIL_LISTIFY_554(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(554, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_556(F, sep, ...) \ + Z_UTIL_LISTIFY_555(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(555, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_557(F, sep, ...) \ + Z_UTIL_LISTIFY_556(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(556, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_558(F, sep, ...) \ + Z_UTIL_LISTIFY_557(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(557, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_559(F, sep, ...) \ + Z_UTIL_LISTIFY_558(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(558, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_560(F, sep, ...) \ + Z_UTIL_LISTIFY_559(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(559, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_561(F, sep, ...) \ + Z_UTIL_LISTIFY_560(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(560, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_562(F, sep, ...) \ + Z_UTIL_LISTIFY_561(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(561, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_563(F, sep, ...) \ + Z_UTIL_LISTIFY_562(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(562, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_564(F, sep, ...) \ + Z_UTIL_LISTIFY_563(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(563, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_565(F, sep, ...) \ + Z_UTIL_LISTIFY_564(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(564, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_566(F, sep, ...) \ + Z_UTIL_LISTIFY_565(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(565, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_567(F, sep, ...) \ + Z_UTIL_LISTIFY_566(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(566, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_568(F, sep, ...) \ + Z_UTIL_LISTIFY_567(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(567, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_569(F, sep, ...) \ + Z_UTIL_LISTIFY_568(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(568, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_570(F, sep, ...) \ + Z_UTIL_LISTIFY_569(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(569, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_571(F, sep, ...) \ + Z_UTIL_LISTIFY_570(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(570, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_572(F, sep, ...) \ + Z_UTIL_LISTIFY_571(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(571, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_573(F, sep, ...) \ + Z_UTIL_LISTIFY_572(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(572, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_574(F, sep, ...) \ + Z_UTIL_LISTIFY_573(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(573, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_575(F, sep, ...) \ + Z_UTIL_LISTIFY_574(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(574, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_576(F, sep, ...) \ + Z_UTIL_LISTIFY_575(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(575, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_577(F, sep, ...) \ + Z_UTIL_LISTIFY_576(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(576, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_578(F, sep, ...) \ + Z_UTIL_LISTIFY_577(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(577, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_579(F, sep, ...) \ + Z_UTIL_LISTIFY_578(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(578, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_580(F, sep, ...) \ + Z_UTIL_LISTIFY_579(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(579, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_581(F, sep, ...) \ + Z_UTIL_LISTIFY_580(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(580, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_582(F, sep, ...) \ + Z_UTIL_LISTIFY_581(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(581, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_583(F, sep, ...) \ + Z_UTIL_LISTIFY_582(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(582, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_584(F, sep, ...) \ + Z_UTIL_LISTIFY_583(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(583, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_585(F, sep, ...) \ + Z_UTIL_LISTIFY_584(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(584, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_586(F, sep, ...) \ + Z_UTIL_LISTIFY_585(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(585, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_587(F, sep, ...) \ + Z_UTIL_LISTIFY_586(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(586, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_588(F, sep, ...) \ + Z_UTIL_LISTIFY_587(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(587, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_589(F, sep, ...) \ + Z_UTIL_LISTIFY_588(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(588, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_590(F, sep, ...) \ + Z_UTIL_LISTIFY_589(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(589, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_591(F, sep, ...) \ + Z_UTIL_LISTIFY_590(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(590, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_592(F, sep, ...) \ + Z_UTIL_LISTIFY_591(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(591, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_593(F, sep, ...) \ + Z_UTIL_LISTIFY_592(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(592, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_594(F, sep, ...) \ + Z_UTIL_LISTIFY_593(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(593, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_595(F, sep, ...) \ + Z_UTIL_LISTIFY_594(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(594, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_596(F, sep, ...) \ + Z_UTIL_LISTIFY_595(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(595, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_597(F, sep, ...) \ + Z_UTIL_LISTIFY_596(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(596, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_598(F, sep, ...) \ + Z_UTIL_LISTIFY_597(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(597, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_599(F, sep, ...) \ + Z_UTIL_LISTIFY_598(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(598, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_600(F, sep, ...) \ + Z_UTIL_LISTIFY_599(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(599, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_601(F, sep, ...) \ + Z_UTIL_LISTIFY_600(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(600, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_602(F, sep, ...) \ + Z_UTIL_LISTIFY_601(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(601, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_603(F, sep, ...) \ + Z_UTIL_LISTIFY_602(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(602, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_604(F, sep, ...) \ + Z_UTIL_LISTIFY_603(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(603, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_605(F, sep, ...) \ + Z_UTIL_LISTIFY_604(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(604, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_606(F, sep, ...) \ + Z_UTIL_LISTIFY_605(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(605, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_607(F, sep, ...) \ + Z_UTIL_LISTIFY_606(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(606, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_608(F, sep, ...) \ + Z_UTIL_LISTIFY_607(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(607, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_609(F, sep, ...) \ + Z_UTIL_LISTIFY_608(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(608, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_610(F, sep, ...) \ + Z_UTIL_LISTIFY_609(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(609, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_611(F, sep, ...) \ + Z_UTIL_LISTIFY_610(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(610, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_612(F, sep, ...) \ + Z_UTIL_LISTIFY_611(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(611, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_613(F, sep, ...) \ + Z_UTIL_LISTIFY_612(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(612, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_614(F, sep, ...) \ + Z_UTIL_LISTIFY_613(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(613, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_615(F, sep, ...) \ + Z_UTIL_LISTIFY_614(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(614, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_616(F, sep, ...) \ + Z_UTIL_LISTIFY_615(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(615, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_617(F, sep, ...) \ + Z_UTIL_LISTIFY_616(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(616, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_618(F, sep, ...) \ + Z_UTIL_LISTIFY_617(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(617, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_619(F, sep, ...) \ + Z_UTIL_LISTIFY_618(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(618, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_620(F, sep, ...) \ + Z_UTIL_LISTIFY_619(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(619, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_621(F, sep, ...) \ + Z_UTIL_LISTIFY_620(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(620, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_622(F, sep, ...) \ + Z_UTIL_LISTIFY_621(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(621, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_623(F, sep, ...) \ + Z_UTIL_LISTIFY_622(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(622, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_624(F, sep, ...) \ + Z_UTIL_LISTIFY_623(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(623, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_625(F, sep, ...) \ + Z_UTIL_LISTIFY_624(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(624, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_626(F, sep, ...) \ + Z_UTIL_LISTIFY_625(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(625, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_627(F, sep, ...) \ + Z_UTIL_LISTIFY_626(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(626, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_628(F, sep, ...) \ + Z_UTIL_LISTIFY_627(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(627, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_629(F, sep, ...) \ + Z_UTIL_LISTIFY_628(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(628, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_630(F, sep, ...) \ + Z_UTIL_LISTIFY_629(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(629, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_631(F, sep, ...) \ + Z_UTIL_LISTIFY_630(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(630, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_632(F, sep, ...) \ + Z_UTIL_LISTIFY_631(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(631, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_633(F, sep, ...) \ + Z_UTIL_LISTIFY_632(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(632, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_634(F, sep, ...) \ + Z_UTIL_LISTIFY_633(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(633, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_635(F, sep, ...) \ + Z_UTIL_LISTIFY_634(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(634, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_636(F, sep, ...) \ + Z_UTIL_LISTIFY_635(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(635, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_637(F, sep, ...) \ + Z_UTIL_LISTIFY_636(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(636, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_638(F, sep, ...) \ + Z_UTIL_LISTIFY_637(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(637, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_639(F, sep, ...) \ + Z_UTIL_LISTIFY_638(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(638, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_640(F, sep, ...) \ + Z_UTIL_LISTIFY_639(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(639, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_641(F, sep, ...) \ + Z_UTIL_LISTIFY_640(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(640, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_642(F, sep, ...) \ + Z_UTIL_LISTIFY_641(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(641, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_643(F, sep, ...) \ + Z_UTIL_LISTIFY_642(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(642, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_644(F, sep, ...) \ + Z_UTIL_LISTIFY_643(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(643, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_645(F, sep, ...) \ + Z_UTIL_LISTIFY_644(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(644, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_646(F, sep, ...) \ + Z_UTIL_LISTIFY_645(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(645, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_647(F, sep, ...) \ + Z_UTIL_LISTIFY_646(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(646, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_648(F, sep, ...) \ + Z_UTIL_LISTIFY_647(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(647, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_649(F, sep, ...) \ + Z_UTIL_LISTIFY_648(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(648, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_650(F, sep, ...) \ + Z_UTIL_LISTIFY_649(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(649, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_651(F, sep, ...) \ + Z_UTIL_LISTIFY_650(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(650, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_652(F, sep, ...) \ + Z_UTIL_LISTIFY_651(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(651, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_653(F, sep, ...) \ + Z_UTIL_LISTIFY_652(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(652, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_654(F, sep, ...) \ + Z_UTIL_LISTIFY_653(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(653, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_655(F, sep, ...) \ + Z_UTIL_LISTIFY_654(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(654, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_656(F, sep, ...) \ + Z_UTIL_LISTIFY_655(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(655, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_657(F, sep, ...) \ + Z_UTIL_LISTIFY_656(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(656, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_658(F, sep, ...) \ + Z_UTIL_LISTIFY_657(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(657, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_659(F, sep, ...) \ + Z_UTIL_LISTIFY_658(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(658, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_660(F, sep, ...) \ + Z_UTIL_LISTIFY_659(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(659, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_661(F, sep, ...) \ + Z_UTIL_LISTIFY_660(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(660, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_662(F, sep, ...) \ + Z_UTIL_LISTIFY_661(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(661, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_663(F, sep, ...) \ + Z_UTIL_LISTIFY_662(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(662, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_664(F, sep, ...) \ + Z_UTIL_LISTIFY_663(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(663, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_665(F, sep, ...) \ + Z_UTIL_LISTIFY_664(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(664, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_666(F, sep, ...) \ + Z_UTIL_LISTIFY_665(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(665, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_667(F, sep, ...) \ + Z_UTIL_LISTIFY_666(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(666, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_668(F, sep, ...) \ + Z_UTIL_LISTIFY_667(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(667, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_669(F, sep, ...) \ + Z_UTIL_LISTIFY_668(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(668, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_670(F, sep, ...) \ + Z_UTIL_LISTIFY_669(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(669, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_671(F, sep, ...) \ + Z_UTIL_LISTIFY_670(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(670, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_672(F, sep, ...) \ + Z_UTIL_LISTIFY_671(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(671, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_673(F, sep, ...) \ + Z_UTIL_LISTIFY_672(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(672, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_674(F, sep, ...) \ + Z_UTIL_LISTIFY_673(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(673, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_675(F, sep, ...) \ + Z_UTIL_LISTIFY_674(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(674, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_676(F, sep, ...) \ + Z_UTIL_LISTIFY_675(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(675, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_677(F, sep, ...) \ + Z_UTIL_LISTIFY_676(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(676, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_678(F, sep, ...) \ + Z_UTIL_LISTIFY_677(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(677, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_679(F, sep, ...) \ + Z_UTIL_LISTIFY_678(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(678, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_680(F, sep, ...) \ + Z_UTIL_LISTIFY_679(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(679, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_681(F, sep, ...) \ + Z_UTIL_LISTIFY_680(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(680, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_682(F, sep, ...) \ + Z_UTIL_LISTIFY_681(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(681, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_683(F, sep, ...) \ + Z_UTIL_LISTIFY_682(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(682, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_684(F, sep, ...) \ + Z_UTIL_LISTIFY_683(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(683, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_685(F, sep, ...) \ + Z_UTIL_LISTIFY_684(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(684, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_686(F, sep, ...) \ + Z_UTIL_LISTIFY_685(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(685, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_687(F, sep, ...) \ + Z_UTIL_LISTIFY_686(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(686, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_688(F, sep, ...) \ + Z_UTIL_LISTIFY_687(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(687, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_689(F, sep, ...) \ + Z_UTIL_LISTIFY_688(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(688, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_690(F, sep, ...) \ + Z_UTIL_LISTIFY_689(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(689, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_691(F, sep, ...) \ + Z_UTIL_LISTIFY_690(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(690, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_692(F, sep, ...) \ + Z_UTIL_LISTIFY_691(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(691, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_693(F, sep, ...) \ + Z_UTIL_LISTIFY_692(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(692, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_694(F, sep, ...) \ + Z_UTIL_LISTIFY_693(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(693, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_695(F, sep, ...) \ + Z_UTIL_LISTIFY_694(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(694, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_696(F, sep, ...) \ + Z_UTIL_LISTIFY_695(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(695, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_697(F, sep, ...) \ + Z_UTIL_LISTIFY_696(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(696, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_698(F, sep, ...) \ + Z_UTIL_LISTIFY_697(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(697, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_699(F, sep, ...) \ + Z_UTIL_LISTIFY_698(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(698, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_700(F, sep, ...) \ + Z_UTIL_LISTIFY_699(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(699, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_701(F, sep, ...) \ + Z_UTIL_LISTIFY_700(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(700, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_702(F, sep, ...) \ + Z_UTIL_LISTIFY_701(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(701, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_703(F, sep, ...) \ + Z_UTIL_LISTIFY_702(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(702, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_704(F, sep, ...) \ + Z_UTIL_LISTIFY_703(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(703, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_705(F, sep, ...) \ + Z_UTIL_LISTIFY_704(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(704, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_706(F, sep, ...) \ + Z_UTIL_LISTIFY_705(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(705, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_707(F, sep, ...) \ + Z_UTIL_LISTIFY_706(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(706, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_708(F, sep, ...) \ + Z_UTIL_LISTIFY_707(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(707, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_709(F, sep, ...) \ + Z_UTIL_LISTIFY_708(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(708, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_710(F, sep, ...) \ + Z_UTIL_LISTIFY_709(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(709, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_711(F, sep, ...) \ + Z_UTIL_LISTIFY_710(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(710, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_712(F, sep, ...) \ + Z_UTIL_LISTIFY_711(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(711, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_713(F, sep, ...) \ + Z_UTIL_LISTIFY_712(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(712, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_714(F, sep, ...) \ + Z_UTIL_LISTIFY_713(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(713, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_715(F, sep, ...) \ + Z_UTIL_LISTIFY_714(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(714, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_716(F, sep, ...) \ + Z_UTIL_LISTIFY_715(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(715, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_717(F, sep, ...) \ + Z_UTIL_LISTIFY_716(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(716, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_718(F, sep, ...) \ + Z_UTIL_LISTIFY_717(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(717, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_719(F, sep, ...) \ + Z_UTIL_LISTIFY_718(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(718, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_720(F, sep, ...) \ + Z_UTIL_LISTIFY_719(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(719, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_721(F, sep, ...) \ + Z_UTIL_LISTIFY_720(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(720, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_722(F, sep, ...) \ + Z_UTIL_LISTIFY_721(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(721, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_723(F, sep, ...) \ + Z_UTIL_LISTIFY_722(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(722, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_724(F, sep, ...) \ + Z_UTIL_LISTIFY_723(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(723, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_725(F, sep, ...) \ + Z_UTIL_LISTIFY_724(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(724, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_726(F, sep, ...) \ + Z_UTIL_LISTIFY_725(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(725, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_727(F, sep, ...) \ + Z_UTIL_LISTIFY_726(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(726, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_728(F, sep, ...) \ + Z_UTIL_LISTIFY_727(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(727, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_729(F, sep, ...) \ + Z_UTIL_LISTIFY_728(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(728, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_730(F, sep, ...) \ + Z_UTIL_LISTIFY_729(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(729, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_731(F, sep, ...) \ + Z_UTIL_LISTIFY_730(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(730, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_732(F, sep, ...) \ + Z_UTIL_LISTIFY_731(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(731, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_733(F, sep, ...) \ + Z_UTIL_LISTIFY_732(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(732, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_734(F, sep, ...) \ + Z_UTIL_LISTIFY_733(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(733, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_735(F, sep, ...) \ + Z_UTIL_LISTIFY_734(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(734, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_736(F, sep, ...) \ + Z_UTIL_LISTIFY_735(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(735, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_737(F, sep, ...) \ + Z_UTIL_LISTIFY_736(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(736, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_738(F, sep, ...) \ + Z_UTIL_LISTIFY_737(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(737, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_739(F, sep, ...) \ + Z_UTIL_LISTIFY_738(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(738, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_740(F, sep, ...) \ + Z_UTIL_LISTIFY_739(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(739, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_741(F, sep, ...) \ + Z_UTIL_LISTIFY_740(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(740, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_742(F, sep, ...) \ + Z_UTIL_LISTIFY_741(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(741, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_743(F, sep, ...) \ + Z_UTIL_LISTIFY_742(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(742, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_744(F, sep, ...) \ + Z_UTIL_LISTIFY_743(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(743, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_745(F, sep, ...) \ + Z_UTIL_LISTIFY_744(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(744, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_746(F, sep, ...) \ + Z_UTIL_LISTIFY_745(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(745, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_747(F, sep, ...) \ + Z_UTIL_LISTIFY_746(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(746, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_748(F, sep, ...) \ + Z_UTIL_LISTIFY_747(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(747, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_749(F, sep, ...) \ + Z_UTIL_LISTIFY_748(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(748, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_750(F, sep, ...) \ + Z_UTIL_LISTIFY_749(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(749, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_751(F, sep, ...) \ + Z_UTIL_LISTIFY_750(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(750, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_752(F, sep, ...) \ + Z_UTIL_LISTIFY_751(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(751, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_753(F, sep, ...) \ + Z_UTIL_LISTIFY_752(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(752, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_754(F, sep, ...) \ + Z_UTIL_LISTIFY_753(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(753, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_755(F, sep, ...) \ + Z_UTIL_LISTIFY_754(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(754, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_756(F, sep, ...) \ + Z_UTIL_LISTIFY_755(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(755, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_757(F, sep, ...) \ + Z_UTIL_LISTIFY_756(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(756, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_758(F, sep, ...) \ + Z_UTIL_LISTIFY_757(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(757, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_759(F, sep, ...) \ + Z_UTIL_LISTIFY_758(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(758, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_760(F, sep, ...) \ + Z_UTIL_LISTIFY_759(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(759, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_761(F, sep, ...) \ + Z_UTIL_LISTIFY_760(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(760, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_762(F, sep, ...) \ + Z_UTIL_LISTIFY_761(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(761, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_763(F, sep, ...) \ + Z_UTIL_LISTIFY_762(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(762, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_764(F, sep, ...) \ + Z_UTIL_LISTIFY_763(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(763, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_765(F, sep, ...) \ + Z_UTIL_LISTIFY_764(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(764, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_766(F, sep, ...) \ + Z_UTIL_LISTIFY_765(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(765, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_767(F, sep, ...) \ + Z_UTIL_LISTIFY_766(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(766, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_768(F, sep, ...) \ + Z_UTIL_LISTIFY_767(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(767, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_769(F, sep, ...) \ + Z_UTIL_LISTIFY_768(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(768, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_770(F, sep, ...) \ + Z_UTIL_LISTIFY_769(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(769, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_771(F, sep, ...) \ + Z_UTIL_LISTIFY_770(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(770, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_772(F, sep, ...) \ + Z_UTIL_LISTIFY_771(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(771, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_773(F, sep, ...) \ + Z_UTIL_LISTIFY_772(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(772, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_774(F, sep, ...) \ + Z_UTIL_LISTIFY_773(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(773, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_775(F, sep, ...) \ + Z_UTIL_LISTIFY_774(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(774, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_776(F, sep, ...) \ + Z_UTIL_LISTIFY_775(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(775, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_777(F, sep, ...) \ + Z_UTIL_LISTIFY_776(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(776, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_778(F, sep, ...) \ + Z_UTIL_LISTIFY_777(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(777, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_779(F, sep, ...) \ + Z_UTIL_LISTIFY_778(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(778, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_780(F, sep, ...) \ + Z_UTIL_LISTIFY_779(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(779, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_781(F, sep, ...) \ + Z_UTIL_LISTIFY_780(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(780, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_782(F, sep, ...) \ + Z_UTIL_LISTIFY_781(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(781, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_783(F, sep, ...) \ + Z_UTIL_LISTIFY_782(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(782, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_784(F, sep, ...) \ + Z_UTIL_LISTIFY_783(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(783, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_785(F, sep, ...) \ + Z_UTIL_LISTIFY_784(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(784, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_786(F, sep, ...) \ + Z_UTIL_LISTIFY_785(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(785, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_787(F, sep, ...) \ + Z_UTIL_LISTIFY_786(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(786, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_788(F, sep, ...) \ + Z_UTIL_LISTIFY_787(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(787, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_789(F, sep, ...) \ + Z_UTIL_LISTIFY_788(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(788, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_790(F, sep, ...) \ + Z_UTIL_LISTIFY_789(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(789, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_791(F, sep, ...) \ + Z_UTIL_LISTIFY_790(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(790, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_792(F, sep, ...) \ + Z_UTIL_LISTIFY_791(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(791, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_793(F, sep, ...) \ + Z_UTIL_LISTIFY_792(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(792, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_794(F, sep, ...) \ + Z_UTIL_LISTIFY_793(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(793, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_795(F, sep, ...) \ + Z_UTIL_LISTIFY_794(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(794, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_796(F, sep, ...) \ + Z_UTIL_LISTIFY_795(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(795, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_797(F, sep, ...) \ + Z_UTIL_LISTIFY_796(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(796, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_798(F, sep, ...) \ + Z_UTIL_LISTIFY_797(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(797, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_799(F, sep, ...) \ + Z_UTIL_LISTIFY_798(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(798, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_800(F, sep, ...) \ + Z_UTIL_LISTIFY_799(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(799, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_801(F, sep, ...) \ + Z_UTIL_LISTIFY_800(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(800, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_802(F, sep, ...) \ + Z_UTIL_LISTIFY_801(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(801, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_803(F, sep, ...) \ + Z_UTIL_LISTIFY_802(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(802, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_804(F, sep, ...) \ + Z_UTIL_LISTIFY_803(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(803, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_805(F, sep, ...) \ + Z_UTIL_LISTIFY_804(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(804, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_806(F, sep, ...) \ + Z_UTIL_LISTIFY_805(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(805, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_807(F, sep, ...) \ + Z_UTIL_LISTIFY_806(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(806, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_808(F, sep, ...) \ + Z_UTIL_LISTIFY_807(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(807, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_809(F, sep, ...) \ + Z_UTIL_LISTIFY_808(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(808, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_810(F, sep, ...) \ + Z_UTIL_LISTIFY_809(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(809, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_811(F, sep, ...) \ + Z_UTIL_LISTIFY_810(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(810, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_812(F, sep, ...) \ + Z_UTIL_LISTIFY_811(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(811, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_813(F, sep, ...) \ + Z_UTIL_LISTIFY_812(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(812, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_814(F, sep, ...) \ + Z_UTIL_LISTIFY_813(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(813, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_815(F, sep, ...) \ + Z_UTIL_LISTIFY_814(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(814, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_816(F, sep, ...) \ + Z_UTIL_LISTIFY_815(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(815, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_817(F, sep, ...) \ + Z_UTIL_LISTIFY_816(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(816, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_818(F, sep, ...) \ + Z_UTIL_LISTIFY_817(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(817, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_819(F, sep, ...) \ + Z_UTIL_LISTIFY_818(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(818, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_820(F, sep, ...) \ + Z_UTIL_LISTIFY_819(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(819, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_821(F, sep, ...) \ + Z_UTIL_LISTIFY_820(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(820, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_822(F, sep, ...) \ + Z_UTIL_LISTIFY_821(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(821, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_823(F, sep, ...) \ + Z_UTIL_LISTIFY_822(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(822, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_824(F, sep, ...) \ + Z_UTIL_LISTIFY_823(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(823, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_825(F, sep, ...) \ + Z_UTIL_LISTIFY_824(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(824, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_826(F, sep, ...) \ + Z_UTIL_LISTIFY_825(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(825, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_827(F, sep, ...) \ + Z_UTIL_LISTIFY_826(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(826, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_828(F, sep, ...) \ + Z_UTIL_LISTIFY_827(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(827, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_829(F, sep, ...) \ + Z_UTIL_LISTIFY_828(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(828, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_830(F, sep, ...) \ + Z_UTIL_LISTIFY_829(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(829, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_831(F, sep, ...) \ + Z_UTIL_LISTIFY_830(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(830, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_832(F, sep, ...) \ + Z_UTIL_LISTIFY_831(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(831, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_833(F, sep, ...) \ + Z_UTIL_LISTIFY_832(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(832, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_834(F, sep, ...) \ + Z_UTIL_LISTIFY_833(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(833, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_835(F, sep, ...) \ + Z_UTIL_LISTIFY_834(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(834, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_836(F, sep, ...) \ + Z_UTIL_LISTIFY_835(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(835, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_837(F, sep, ...) \ + Z_UTIL_LISTIFY_836(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(836, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_838(F, sep, ...) \ + Z_UTIL_LISTIFY_837(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(837, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_839(F, sep, ...) \ + Z_UTIL_LISTIFY_838(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(838, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_840(F, sep, ...) \ + Z_UTIL_LISTIFY_839(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(839, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_841(F, sep, ...) \ + Z_UTIL_LISTIFY_840(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(840, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_842(F, sep, ...) \ + Z_UTIL_LISTIFY_841(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(841, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_843(F, sep, ...) \ + Z_UTIL_LISTIFY_842(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(842, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_844(F, sep, ...) \ + Z_UTIL_LISTIFY_843(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(843, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_845(F, sep, ...) \ + Z_UTIL_LISTIFY_844(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(844, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_846(F, sep, ...) \ + Z_UTIL_LISTIFY_845(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(845, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_847(F, sep, ...) \ + Z_UTIL_LISTIFY_846(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(846, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_848(F, sep, ...) \ + Z_UTIL_LISTIFY_847(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(847, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_849(F, sep, ...) \ + Z_UTIL_LISTIFY_848(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(848, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_850(F, sep, ...) \ + Z_UTIL_LISTIFY_849(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(849, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_851(F, sep, ...) \ + Z_UTIL_LISTIFY_850(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(850, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_852(F, sep, ...) \ + Z_UTIL_LISTIFY_851(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(851, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_853(F, sep, ...) \ + Z_UTIL_LISTIFY_852(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(852, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_854(F, sep, ...) \ + Z_UTIL_LISTIFY_853(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(853, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_855(F, sep, ...) \ + Z_UTIL_LISTIFY_854(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(854, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_856(F, sep, ...) \ + Z_UTIL_LISTIFY_855(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(855, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_857(F, sep, ...) \ + Z_UTIL_LISTIFY_856(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(856, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_858(F, sep, ...) \ + Z_UTIL_LISTIFY_857(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(857, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_859(F, sep, ...) \ + Z_UTIL_LISTIFY_858(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(858, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_860(F, sep, ...) \ + Z_UTIL_LISTIFY_859(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(859, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_861(F, sep, ...) \ + Z_UTIL_LISTIFY_860(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(860, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_862(F, sep, ...) \ + Z_UTIL_LISTIFY_861(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(861, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_863(F, sep, ...) \ + Z_UTIL_LISTIFY_862(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(862, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_864(F, sep, ...) \ + Z_UTIL_LISTIFY_863(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(863, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_865(F, sep, ...) \ + Z_UTIL_LISTIFY_864(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(864, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_866(F, sep, ...) \ + Z_UTIL_LISTIFY_865(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(865, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_867(F, sep, ...) \ + Z_UTIL_LISTIFY_866(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(866, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_868(F, sep, ...) \ + Z_UTIL_LISTIFY_867(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(867, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_869(F, sep, ...) \ + Z_UTIL_LISTIFY_868(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(868, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_870(F, sep, ...) \ + Z_UTIL_LISTIFY_869(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(869, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_871(F, sep, ...) \ + Z_UTIL_LISTIFY_870(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(870, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_872(F, sep, ...) \ + Z_UTIL_LISTIFY_871(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(871, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_873(F, sep, ...) \ + Z_UTIL_LISTIFY_872(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(872, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_874(F, sep, ...) \ + Z_UTIL_LISTIFY_873(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(873, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_875(F, sep, ...) \ + Z_UTIL_LISTIFY_874(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(874, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_876(F, sep, ...) \ + Z_UTIL_LISTIFY_875(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(875, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_877(F, sep, ...) \ + Z_UTIL_LISTIFY_876(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(876, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_878(F, sep, ...) \ + Z_UTIL_LISTIFY_877(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(877, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_879(F, sep, ...) \ + Z_UTIL_LISTIFY_878(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(878, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_880(F, sep, ...) \ + Z_UTIL_LISTIFY_879(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(879, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_881(F, sep, ...) \ + Z_UTIL_LISTIFY_880(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(880, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_882(F, sep, ...) \ + Z_UTIL_LISTIFY_881(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(881, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_883(F, sep, ...) \ + Z_UTIL_LISTIFY_882(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(882, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_884(F, sep, ...) \ + Z_UTIL_LISTIFY_883(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(883, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_885(F, sep, ...) \ + Z_UTIL_LISTIFY_884(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(884, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_886(F, sep, ...) \ + Z_UTIL_LISTIFY_885(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(885, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_887(F, sep, ...) \ + Z_UTIL_LISTIFY_886(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(886, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_888(F, sep, ...) \ + Z_UTIL_LISTIFY_887(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(887, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_889(F, sep, ...) \ + Z_UTIL_LISTIFY_888(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(888, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_890(F, sep, ...) \ + Z_UTIL_LISTIFY_889(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(889, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_891(F, sep, ...) \ + Z_UTIL_LISTIFY_890(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(890, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_892(F, sep, ...) \ + Z_UTIL_LISTIFY_891(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(891, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_893(F, sep, ...) \ + Z_UTIL_LISTIFY_892(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(892, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_894(F, sep, ...) \ + Z_UTIL_LISTIFY_893(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(893, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_895(F, sep, ...) \ + Z_UTIL_LISTIFY_894(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(894, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_896(F, sep, ...) \ + Z_UTIL_LISTIFY_895(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(895, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_897(F, sep, ...) \ + Z_UTIL_LISTIFY_896(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(896, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_898(F, sep, ...) \ + Z_UTIL_LISTIFY_897(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(897, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_899(F, sep, ...) \ + Z_UTIL_LISTIFY_898(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(898, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_900(F, sep, ...) \ + Z_UTIL_LISTIFY_899(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(899, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_901(F, sep, ...) \ + Z_UTIL_LISTIFY_900(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(900, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_902(F, sep, ...) \ + Z_UTIL_LISTIFY_901(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(901, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_903(F, sep, ...) \ + Z_UTIL_LISTIFY_902(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(902, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_904(F, sep, ...) \ + Z_UTIL_LISTIFY_903(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(903, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_905(F, sep, ...) \ + Z_UTIL_LISTIFY_904(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(904, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_906(F, sep, ...) \ + Z_UTIL_LISTIFY_905(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(905, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_907(F, sep, ...) \ + Z_UTIL_LISTIFY_906(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(906, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_908(F, sep, ...) \ + Z_UTIL_LISTIFY_907(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(907, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_909(F, sep, ...) \ + Z_UTIL_LISTIFY_908(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(908, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_910(F, sep, ...) \ + Z_UTIL_LISTIFY_909(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(909, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_911(F, sep, ...) \ + Z_UTIL_LISTIFY_910(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(910, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_912(F, sep, ...) \ + Z_UTIL_LISTIFY_911(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(911, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_913(F, sep, ...) \ + Z_UTIL_LISTIFY_912(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(912, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_914(F, sep, ...) \ + Z_UTIL_LISTIFY_913(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(913, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_915(F, sep, ...) \ + Z_UTIL_LISTIFY_914(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(914, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_916(F, sep, ...) \ + Z_UTIL_LISTIFY_915(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(915, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_917(F, sep, ...) \ + Z_UTIL_LISTIFY_916(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(916, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_918(F, sep, ...) \ + Z_UTIL_LISTIFY_917(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(917, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_919(F, sep, ...) \ + Z_UTIL_LISTIFY_918(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(918, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_920(F, sep, ...) \ + Z_UTIL_LISTIFY_919(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(919, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_921(F, sep, ...) \ + Z_UTIL_LISTIFY_920(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(920, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_922(F, sep, ...) \ + Z_UTIL_LISTIFY_921(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(921, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_923(F, sep, ...) \ + Z_UTIL_LISTIFY_922(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(922, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_924(F, sep, ...) \ + Z_UTIL_LISTIFY_923(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(923, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_925(F, sep, ...) \ + Z_UTIL_LISTIFY_924(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(924, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_926(F, sep, ...) \ + Z_UTIL_LISTIFY_925(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(925, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_927(F, sep, ...) \ + Z_UTIL_LISTIFY_926(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(926, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_928(F, sep, ...) \ + Z_UTIL_LISTIFY_927(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(927, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_929(F, sep, ...) \ + Z_UTIL_LISTIFY_928(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(928, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_930(F, sep, ...) \ + Z_UTIL_LISTIFY_929(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(929, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_931(F, sep, ...) \ + Z_UTIL_LISTIFY_930(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(930, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_932(F, sep, ...) \ + Z_UTIL_LISTIFY_931(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(931, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_933(F, sep, ...) \ + Z_UTIL_LISTIFY_932(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(932, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_934(F, sep, ...) \ + Z_UTIL_LISTIFY_933(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(933, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_935(F, sep, ...) \ + Z_UTIL_LISTIFY_934(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(934, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_936(F, sep, ...) \ + Z_UTIL_LISTIFY_935(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(935, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_937(F, sep, ...) \ + Z_UTIL_LISTIFY_936(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(936, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_938(F, sep, ...) \ + Z_UTIL_LISTIFY_937(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(937, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_939(F, sep, ...) \ + Z_UTIL_LISTIFY_938(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(938, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_940(F, sep, ...) \ + Z_UTIL_LISTIFY_939(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(939, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_941(F, sep, ...) \ + Z_UTIL_LISTIFY_940(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(940, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_942(F, sep, ...) \ + Z_UTIL_LISTIFY_941(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(941, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_943(F, sep, ...) \ + Z_UTIL_LISTIFY_942(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(942, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_944(F, sep, ...) \ + Z_UTIL_LISTIFY_943(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(943, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_945(F, sep, ...) \ + Z_UTIL_LISTIFY_944(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(944, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_946(F, sep, ...) \ + Z_UTIL_LISTIFY_945(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(945, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_947(F, sep, ...) \ + Z_UTIL_LISTIFY_946(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(946, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_948(F, sep, ...) \ + Z_UTIL_LISTIFY_947(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(947, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_949(F, sep, ...) \ + Z_UTIL_LISTIFY_948(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(948, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_950(F, sep, ...) \ + Z_UTIL_LISTIFY_949(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(949, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_951(F, sep, ...) \ + Z_UTIL_LISTIFY_950(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(950, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_952(F, sep, ...) \ + Z_UTIL_LISTIFY_951(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(951, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_953(F, sep, ...) \ + Z_UTIL_LISTIFY_952(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(952, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_954(F, sep, ...) \ + Z_UTIL_LISTIFY_953(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(953, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_955(F, sep, ...) \ + Z_UTIL_LISTIFY_954(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(954, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_956(F, sep, ...) \ + Z_UTIL_LISTIFY_955(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(955, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_957(F, sep, ...) \ + Z_UTIL_LISTIFY_956(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(956, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_958(F, sep, ...) \ + Z_UTIL_LISTIFY_957(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(957, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_959(F, sep, ...) \ + Z_UTIL_LISTIFY_958(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(958, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_960(F, sep, ...) \ + Z_UTIL_LISTIFY_959(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(959, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_961(F, sep, ...) \ + Z_UTIL_LISTIFY_960(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(960, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_962(F, sep, ...) \ + Z_UTIL_LISTIFY_961(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(961, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_963(F, sep, ...) \ + Z_UTIL_LISTIFY_962(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(962, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_964(F, sep, ...) \ + Z_UTIL_LISTIFY_963(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(963, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_965(F, sep, ...) \ + Z_UTIL_LISTIFY_964(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(964, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_966(F, sep, ...) \ + Z_UTIL_LISTIFY_965(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(965, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_967(F, sep, ...) \ + Z_UTIL_LISTIFY_966(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(966, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_968(F, sep, ...) \ + Z_UTIL_LISTIFY_967(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(967, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_969(F, sep, ...) \ + Z_UTIL_LISTIFY_968(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(968, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_970(F, sep, ...) \ + Z_UTIL_LISTIFY_969(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(969, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_971(F, sep, ...) \ + Z_UTIL_LISTIFY_970(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(970, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_972(F, sep, ...) \ + Z_UTIL_LISTIFY_971(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(971, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_973(F, sep, ...) \ + Z_UTIL_LISTIFY_972(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(972, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_974(F, sep, ...) \ + Z_UTIL_LISTIFY_973(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(973, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_975(F, sep, ...) \ + Z_UTIL_LISTIFY_974(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(974, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_976(F, sep, ...) \ + Z_UTIL_LISTIFY_975(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(975, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_977(F, sep, ...) \ + Z_UTIL_LISTIFY_976(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(976, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_978(F, sep, ...) \ + Z_UTIL_LISTIFY_977(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(977, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_979(F, sep, ...) \ + Z_UTIL_LISTIFY_978(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(978, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_980(F, sep, ...) \ + Z_UTIL_LISTIFY_979(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(979, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_981(F, sep, ...) \ + Z_UTIL_LISTIFY_980(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(980, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_982(F, sep, ...) \ + Z_UTIL_LISTIFY_981(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(981, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_983(F, sep, ...) \ + Z_UTIL_LISTIFY_982(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(982, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_984(F, sep, ...) \ + Z_UTIL_LISTIFY_983(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(983, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_985(F, sep, ...) \ + Z_UTIL_LISTIFY_984(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(984, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_986(F, sep, ...) \ + Z_UTIL_LISTIFY_985(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(985, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_987(F, sep, ...) \ + Z_UTIL_LISTIFY_986(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(986, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_988(F, sep, ...) \ + Z_UTIL_LISTIFY_987(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(987, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_989(F, sep, ...) \ + Z_UTIL_LISTIFY_988(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(988, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_990(F, sep, ...) \ + Z_UTIL_LISTIFY_989(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(989, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_991(F, sep, ...) \ + Z_UTIL_LISTIFY_990(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(990, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_992(F, sep, ...) \ + Z_UTIL_LISTIFY_991(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(991, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_993(F, sep, ...) \ + Z_UTIL_LISTIFY_992(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(992, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_994(F, sep, ...) \ + Z_UTIL_LISTIFY_993(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(993, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_995(F, sep, ...) \ + Z_UTIL_LISTIFY_994(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(994, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_996(F, sep, ...) \ + Z_UTIL_LISTIFY_995(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(995, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_997(F, sep, ...) \ + Z_UTIL_LISTIFY_996(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(996, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_998(F, sep, ...) \ + Z_UTIL_LISTIFY_997(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(997, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_999(F, sep, ...) \ + Z_UTIL_LISTIFY_998(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(998, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1000(F, sep, ...) \ + Z_UTIL_LISTIFY_999(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(999, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1001(F, sep, ...) \ + Z_UTIL_LISTIFY_1000(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1000, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1002(F, sep, ...) \ + Z_UTIL_LISTIFY_1001(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1001, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1003(F, sep, ...) \ + Z_UTIL_LISTIFY_1002(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1002, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1004(F, sep, ...) \ + Z_UTIL_LISTIFY_1003(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1003, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1005(F, sep, ...) \ + Z_UTIL_LISTIFY_1004(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1004, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1006(F, sep, ...) \ + Z_UTIL_LISTIFY_1005(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1005, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1007(F, sep, ...) \ + Z_UTIL_LISTIFY_1006(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1006, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1008(F, sep, ...) \ + Z_UTIL_LISTIFY_1007(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1007, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1009(F, sep, ...) \ + Z_UTIL_LISTIFY_1008(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1008, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1010(F, sep, ...) \ + Z_UTIL_LISTIFY_1009(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1009, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1011(F, sep, ...) \ + Z_UTIL_LISTIFY_1010(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1010, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1012(F, sep, ...) \ + Z_UTIL_LISTIFY_1011(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1011, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1013(F, sep, ...) \ + Z_UTIL_LISTIFY_1012(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1012, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1014(F, sep, ...) \ + Z_UTIL_LISTIFY_1013(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1013, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1015(F, sep, ...) \ + Z_UTIL_LISTIFY_1014(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1014, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1016(F, sep, ...) \ + Z_UTIL_LISTIFY_1015(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1015, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1017(F, sep, ...) \ + Z_UTIL_LISTIFY_1016(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1016, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1018(F, sep, ...) \ + Z_UTIL_LISTIFY_1017(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1017, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1019(F, sep, ...) \ + Z_UTIL_LISTIFY_1018(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1018, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1020(F, sep, ...) \ + Z_UTIL_LISTIFY_1019(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1019, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1021(F, sep, ...) \ + Z_UTIL_LISTIFY_1020(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1020, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1022(F, sep, ...) \ + Z_UTIL_LISTIFY_1021(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1021, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1023(F, sep, ...) \ + Z_UTIL_LISTIFY_1022(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1022, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1024(F, sep, ...) \ + Z_UTIL_LISTIFY_1023(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1023, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1025(F, sep, ...) \ + Z_UTIL_LISTIFY_1024(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1024, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1026(F, sep, ...) \ + Z_UTIL_LISTIFY_1025(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1025, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1027(F, sep, ...) \ + Z_UTIL_LISTIFY_1026(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1026, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1028(F, sep, ...) \ + Z_UTIL_LISTIFY_1027(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1027, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1029(F, sep, ...) \ + Z_UTIL_LISTIFY_1028(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1028, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1030(F, sep, ...) \ + Z_UTIL_LISTIFY_1029(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1029, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1031(F, sep, ...) \ + Z_UTIL_LISTIFY_1030(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1030, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1032(F, sep, ...) \ + Z_UTIL_LISTIFY_1031(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1031, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1033(F, sep, ...) \ + Z_UTIL_LISTIFY_1032(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1032, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1034(F, sep, ...) \ + Z_UTIL_LISTIFY_1033(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1033, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1035(F, sep, ...) \ + Z_UTIL_LISTIFY_1034(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1034, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1036(F, sep, ...) \ + Z_UTIL_LISTIFY_1035(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1035, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1037(F, sep, ...) \ + Z_UTIL_LISTIFY_1036(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1036, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1038(F, sep, ...) \ + Z_UTIL_LISTIFY_1037(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1037, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1039(F, sep, ...) \ + Z_UTIL_LISTIFY_1038(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1038, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1040(F, sep, ...) \ + Z_UTIL_LISTIFY_1039(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1039, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1041(F, sep, ...) \ + Z_UTIL_LISTIFY_1040(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1040, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1042(F, sep, ...) \ + Z_UTIL_LISTIFY_1041(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1041, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1043(F, sep, ...) \ + Z_UTIL_LISTIFY_1042(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1042, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1044(F, sep, ...) \ + Z_UTIL_LISTIFY_1043(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1043, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1045(F, sep, ...) \ + Z_UTIL_LISTIFY_1044(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1044, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1046(F, sep, ...) \ + Z_UTIL_LISTIFY_1045(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1045, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1047(F, sep, ...) \ + Z_UTIL_LISTIFY_1046(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1046, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1048(F, sep, ...) \ + Z_UTIL_LISTIFY_1047(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1047, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1049(F, sep, ...) \ + Z_UTIL_LISTIFY_1048(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1048, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1050(F, sep, ...) \ + Z_UTIL_LISTIFY_1049(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1049, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1051(F, sep, ...) \ + Z_UTIL_LISTIFY_1050(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1050, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1052(F, sep, ...) \ + Z_UTIL_LISTIFY_1051(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1051, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1053(F, sep, ...) \ + Z_UTIL_LISTIFY_1052(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1052, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1054(F, sep, ...) \ + Z_UTIL_LISTIFY_1053(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1053, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1055(F, sep, ...) \ + Z_UTIL_LISTIFY_1054(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1054, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1056(F, sep, ...) \ + Z_UTIL_LISTIFY_1055(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1055, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1057(F, sep, ...) \ + Z_UTIL_LISTIFY_1056(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1056, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1058(F, sep, ...) \ + Z_UTIL_LISTIFY_1057(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1057, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1059(F, sep, ...) \ + Z_UTIL_LISTIFY_1058(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1058, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1060(F, sep, ...) \ + Z_UTIL_LISTIFY_1059(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1059, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1061(F, sep, ...) \ + Z_UTIL_LISTIFY_1060(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1060, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1062(F, sep, ...) \ + Z_UTIL_LISTIFY_1061(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1061, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1063(F, sep, ...) \ + Z_UTIL_LISTIFY_1062(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1062, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1064(F, sep, ...) \ + Z_UTIL_LISTIFY_1063(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1063, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1065(F, sep, ...) \ + Z_UTIL_LISTIFY_1064(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1064, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1066(F, sep, ...) \ + Z_UTIL_LISTIFY_1065(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1065, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1067(F, sep, ...) \ + Z_UTIL_LISTIFY_1066(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1066, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1068(F, sep, ...) \ + Z_UTIL_LISTIFY_1067(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1067, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1069(F, sep, ...) \ + Z_UTIL_LISTIFY_1068(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1068, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1070(F, sep, ...) \ + Z_UTIL_LISTIFY_1069(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1069, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1071(F, sep, ...) \ + Z_UTIL_LISTIFY_1070(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1070, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1072(F, sep, ...) \ + Z_UTIL_LISTIFY_1071(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1071, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1073(F, sep, ...) \ + Z_UTIL_LISTIFY_1072(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1072, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1074(F, sep, ...) \ + Z_UTIL_LISTIFY_1073(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1073, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1075(F, sep, ...) \ + Z_UTIL_LISTIFY_1074(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1074, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1076(F, sep, ...) \ + Z_UTIL_LISTIFY_1075(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1075, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1077(F, sep, ...) \ + Z_UTIL_LISTIFY_1076(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1076, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1078(F, sep, ...) \ + Z_UTIL_LISTIFY_1077(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1077, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1079(F, sep, ...) \ + Z_UTIL_LISTIFY_1078(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1078, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1080(F, sep, ...) \ + Z_UTIL_LISTIFY_1079(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1079, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1081(F, sep, ...) \ + Z_UTIL_LISTIFY_1080(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1080, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1082(F, sep, ...) \ + Z_UTIL_LISTIFY_1081(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1081, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1083(F, sep, ...) \ + Z_UTIL_LISTIFY_1082(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1082, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1084(F, sep, ...) \ + Z_UTIL_LISTIFY_1083(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1083, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1085(F, sep, ...) \ + Z_UTIL_LISTIFY_1084(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1084, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1086(F, sep, ...) \ + Z_UTIL_LISTIFY_1085(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1085, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1087(F, sep, ...) \ + Z_UTIL_LISTIFY_1086(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1086, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1088(F, sep, ...) \ + Z_UTIL_LISTIFY_1087(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1087, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1089(F, sep, ...) \ + Z_UTIL_LISTIFY_1088(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1088, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1090(F, sep, ...) \ + Z_UTIL_LISTIFY_1089(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1089, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1091(F, sep, ...) \ + Z_UTIL_LISTIFY_1090(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1090, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1092(F, sep, ...) \ + Z_UTIL_LISTIFY_1091(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1091, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1093(F, sep, ...) \ + Z_UTIL_LISTIFY_1092(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1092, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1094(F, sep, ...) \ + Z_UTIL_LISTIFY_1093(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1093, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1095(F, sep, ...) \ + Z_UTIL_LISTIFY_1094(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1094, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1096(F, sep, ...) \ + Z_UTIL_LISTIFY_1095(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1095, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1097(F, sep, ...) \ + Z_UTIL_LISTIFY_1096(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1096, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1098(F, sep, ...) \ + Z_UTIL_LISTIFY_1097(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1097, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1099(F, sep, ...) \ + Z_UTIL_LISTIFY_1098(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1098, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1100(F, sep, ...) \ + Z_UTIL_LISTIFY_1099(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1099, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1101(F, sep, ...) \ + Z_UTIL_LISTIFY_1100(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1100, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1102(F, sep, ...) \ + Z_UTIL_LISTIFY_1101(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1101, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1103(F, sep, ...) \ + Z_UTIL_LISTIFY_1102(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1102, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1104(F, sep, ...) \ + Z_UTIL_LISTIFY_1103(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1103, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1105(F, sep, ...) \ + Z_UTIL_LISTIFY_1104(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1104, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1106(F, sep, ...) \ + Z_UTIL_LISTIFY_1105(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1105, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1107(F, sep, ...) \ + Z_UTIL_LISTIFY_1106(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1106, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1108(F, sep, ...) \ + Z_UTIL_LISTIFY_1107(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1107, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1109(F, sep, ...) \ + Z_UTIL_LISTIFY_1108(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1108, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1110(F, sep, ...) \ + Z_UTIL_LISTIFY_1109(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1109, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1111(F, sep, ...) \ + Z_UTIL_LISTIFY_1110(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1110, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1112(F, sep, ...) \ + Z_UTIL_LISTIFY_1111(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1111, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1113(F, sep, ...) \ + Z_UTIL_LISTIFY_1112(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1112, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1114(F, sep, ...) \ + Z_UTIL_LISTIFY_1113(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1113, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1115(F, sep, ...) \ + Z_UTIL_LISTIFY_1114(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1114, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1116(F, sep, ...) \ + Z_UTIL_LISTIFY_1115(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1115, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1117(F, sep, ...) \ + Z_UTIL_LISTIFY_1116(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1116, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1118(F, sep, ...) \ + Z_UTIL_LISTIFY_1117(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1117, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1119(F, sep, ...) \ + Z_UTIL_LISTIFY_1118(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1118, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1120(F, sep, ...) \ + Z_UTIL_LISTIFY_1119(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1119, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1121(F, sep, ...) \ + Z_UTIL_LISTIFY_1120(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1120, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1122(F, sep, ...) \ + Z_UTIL_LISTIFY_1121(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1121, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1123(F, sep, ...) \ + Z_UTIL_LISTIFY_1122(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1122, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1124(F, sep, ...) \ + Z_UTIL_LISTIFY_1123(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1123, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1125(F, sep, ...) \ + Z_UTIL_LISTIFY_1124(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1124, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1126(F, sep, ...) \ + Z_UTIL_LISTIFY_1125(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1125, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1127(F, sep, ...) \ + Z_UTIL_LISTIFY_1126(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1126, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1128(F, sep, ...) \ + Z_UTIL_LISTIFY_1127(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1127, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1129(F, sep, ...) \ + Z_UTIL_LISTIFY_1128(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1128, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1130(F, sep, ...) \ + Z_UTIL_LISTIFY_1129(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1129, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1131(F, sep, ...) \ + Z_UTIL_LISTIFY_1130(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1130, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1132(F, sep, ...) \ + Z_UTIL_LISTIFY_1131(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1131, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1133(F, sep, ...) \ + Z_UTIL_LISTIFY_1132(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1132, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1134(F, sep, ...) \ + Z_UTIL_LISTIFY_1133(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1133, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1135(F, sep, ...) \ + Z_UTIL_LISTIFY_1134(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1134, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1136(F, sep, ...) \ + Z_UTIL_LISTIFY_1135(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1135, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1137(F, sep, ...) \ + Z_UTIL_LISTIFY_1136(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1136, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1138(F, sep, ...) \ + Z_UTIL_LISTIFY_1137(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1137, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1139(F, sep, ...) \ + Z_UTIL_LISTIFY_1138(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1138, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1140(F, sep, ...) \ + Z_UTIL_LISTIFY_1139(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1139, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1141(F, sep, ...) \ + Z_UTIL_LISTIFY_1140(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1140, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1142(F, sep, ...) \ + Z_UTIL_LISTIFY_1141(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1141, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1143(F, sep, ...) \ + Z_UTIL_LISTIFY_1142(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1142, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1144(F, sep, ...) \ + Z_UTIL_LISTIFY_1143(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1143, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1145(F, sep, ...) \ + Z_UTIL_LISTIFY_1144(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1144, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1146(F, sep, ...) \ + Z_UTIL_LISTIFY_1145(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1145, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1147(F, sep, ...) \ + Z_UTIL_LISTIFY_1146(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1146, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1148(F, sep, ...) \ + Z_UTIL_LISTIFY_1147(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1147, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1149(F, sep, ...) \ + Z_UTIL_LISTIFY_1148(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1148, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1150(F, sep, ...) \ + Z_UTIL_LISTIFY_1149(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1149, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1151(F, sep, ...) \ + Z_UTIL_LISTIFY_1150(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1150, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1152(F, sep, ...) \ + Z_UTIL_LISTIFY_1151(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1151, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1153(F, sep, ...) \ + Z_UTIL_LISTIFY_1152(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1152, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1154(F, sep, ...) \ + Z_UTIL_LISTIFY_1153(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1153, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1155(F, sep, ...) \ + Z_UTIL_LISTIFY_1154(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1154, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1156(F, sep, ...) \ + Z_UTIL_LISTIFY_1155(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1155, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1157(F, sep, ...) \ + Z_UTIL_LISTIFY_1156(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1156, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1158(F, sep, ...) \ + Z_UTIL_LISTIFY_1157(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1157, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1159(F, sep, ...) \ + Z_UTIL_LISTIFY_1158(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1158, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1160(F, sep, ...) \ + Z_UTIL_LISTIFY_1159(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1159, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1161(F, sep, ...) \ + Z_UTIL_LISTIFY_1160(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1160, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1162(F, sep, ...) \ + Z_UTIL_LISTIFY_1161(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1161, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1163(F, sep, ...) \ + Z_UTIL_LISTIFY_1162(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1162, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1164(F, sep, ...) \ + Z_UTIL_LISTIFY_1163(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1163, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1165(F, sep, ...) \ + Z_UTIL_LISTIFY_1164(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1164, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1166(F, sep, ...) \ + Z_UTIL_LISTIFY_1165(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1165, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1167(F, sep, ...) \ + Z_UTIL_LISTIFY_1166(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1166, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1168(F, sep, ...) \ + Z_UTIL_LISTIFY_1167(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1167, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1169(F, sep, ...) \ + Z_UTIL_LISTIFY_1168(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1168, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1170(F, sep, ...) \ + Z_UTIL_LISTIFY_1169(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1169, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1171(F, sep, ...) \ + Z_UTIL_LISTIFY_1170(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1170, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1172(F, sep, ...) \ + Z_UTIL_LISTIFY_1171(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1171, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1173(F, sep, ...) \ + Z_UTIL_LISTIFY_1172(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1172, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1174(F, sep, ...) \ + Z_UTIL_LISTIFY_1173(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1173, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1175(F, sep, ...) \ + Z_UTIL_LISTIFY_1174(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1174, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1176(F, sep, ...) \ + Z_UTIL_LISTIFY_1175(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1175, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1177(F, sep, ...) \ + Z_UTIL_LISTIFY_1176(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1176, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1178(F, sep, ...) \ + Z_UTIL_LISTIFY_1177(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1177, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1179(F, sep, ...) \ + Z_UTIL_LISTIFY_1178(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1178, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1180(F, sep, ...) \ + Z_UTIL_LISTIFY_1179(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1179, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1181(F, sep, ...) \ + Z_UTIL_LISTIFY_1180(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1180, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1182(F, sep, ...) \ + Z_UTIL_LISTIFY_1181(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1181, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1183(F, sep, ...) \ + Z_UTIL_LISTIFY_1182(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1182, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1184(F, sep, ...) \ + Z_UTIL_LISTIFY_1183(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1183, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1185(F, sep, ...) \ + Z_UTIL_LISTIFY_1184(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1184, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1186(F, sep, ...) \ + Z_UTIL_LISTIFY_1185(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1185, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1187(F, sep, ...) \ + Z_UTIL_LISTIFY_1186(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1186, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1188(F, sep, ...) \ + Z_UTIL_LISTIFY_1187(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1187, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1189(F, sep, ...) \ + Z_UTIL_LISTIFY_1188(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1188, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1190(F, sep, ...) \ + Z_UTIL_LISTIFY_1189(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1189, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1191(F, sep, ...) \ + Z_UTIL_LISTIFY_1190(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1190, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1192(F, sep, ...) \ + Z_UTIL_LISTIFY_1191(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1191, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1193(F, sep, ...) \ + Z_UTIL_LISTIFY_1192(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1192, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1194(F, sep, ...) \ + Z_UTIL_LISTIFY_1193(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1193, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1195(F, sep, ...) \ + Z_UTIL_LISTIFY_1194(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1194, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1196(F, sep, ...) \ + Z_UTIL_LISTIFY_1195(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1195, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1197(F, sep, ...) \ + Z_UTIL_LISTIFY_1196(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1196, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1198(F, sep, ...) \ + Z_UTIL_LISTIFY_1197(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1197, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1199(F, sep, ...) \ + Z_UTIL_LISTIFY_1198(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1198, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1200(F, sep, ...) \ + Z_UTIL_LISTIFY_1199(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1199, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1201(F, sep, ...) \ + Z_UTIL_LISTIFY_1200(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1200, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1202(F, sep, ...) \ + Z_UTIL_LISTIFY_1201(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1201, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1203(F, sep, ...) \ + Z_UTIL_LISTIFY_1202(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1202, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1204(F, sep, ...) \ + Z_UTIL_LISTIFY_1203(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1203, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1205(F, sep, ...) \ + Z_UTIL_LISTIFY_1204(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1204, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1206(F, sep, ...) \ + Z_UTIL_LISTIFY_1205(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1205, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1207(F, sep, ...) \ + Z_UTIL_LISTIFY_1206(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1206, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1208(F, sep, ...) \ + Z_UTIL_LISTIFY_1207(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1207, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1209(F, sep, ...) \ + Z_UTIL_LISTIFY_1208(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1208, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1210(F, sep, ...) \ + Z_UTIL_LISTIFY_1209(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1209, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1211(F, sep, ...) \ + Z_UTIL_LISTIFY_1210(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1210, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1212(F, sep, ...) \ + Z_UTIL_LISTIFY_1211(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1211, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1213(F, sep, ...) \ + Z_UTIL_LISTIFY_1212(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1212, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1214(F, sep, ...) \ + Z_UTIL_LISTIFY_1213(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1213, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1215(F, sep, ...) \ + Z_UTIL_LISTIFY_1214(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1214, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1216(F, sep, ...) \ + Z_UTIL_LISTIFY_1215(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1215, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1217(F, sep, ...) \ + Z_UTIL_LISTIFY_1216(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1216, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1218(F, sep, ...) \ + Z_UTIL_LISTIFY_1217(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1217, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1219(F, sep, ...) \ + Z_UTIL_LISTIFY_1218(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1218, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1220(F, sep, ...) \ + Z_UTIL_LISTIFY_1219(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1219, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1221(F, sep, ...) \ + Z_UTIL_LISTIFY_1220(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1220, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1222(F, sep, ...) \ + Z_UTIL_LISTIFY_1221(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1221, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1223(F, sep, ...) \ + Z_UTIL_LISTIFY_1222(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1222, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1224(F, sep, ...) \ + Z_UTIL_LISTIFY_1223(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1223, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1225(F, sep, ...) \ + Z_UTIL_LISTIFY_1224(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1224, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1226(F, sep, ...) \ + Z_UTIL_LISTIFY_1225(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1225, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1227(F, sep, ...) \ + Z_UTIL_LISTIFY_1226(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1226, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1228(F, sep, ...) \ + Z_UTIL_LISTIFY_1227(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1227, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1229(F, sep, ...) \ + Z_UTIL_LISTIFY_1228(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1228, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1230(F, sep, ...) \ + Z_UTIL_LISTIFY_1229(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1229, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1231(F, sep, ...) \ + Z_UTIL_LISTIFY_1230(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1230, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1232(F, sep, ...) \ + Z_UTIL_LISTIFY_1231(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1231, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1233(F, sep, ...) \ + Z_UTIL_LISTIFY_1232(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1232, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1234(F, sep, ...) \ + Z_UTIL_LISTIFY_1233(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1233, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1235(F, sep, ...) \ + Z_UTIL_LISTIFY_1234(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1234, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1236(F, sep, ...) \ + Z_UTIL_LISTIFY_1235(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1235, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1237(F, sep, ...) \ + Z_UTIL_LISTIFY_1236(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1236, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1238(F, sep, ...) \ + Z_UTIL_LISTIFY_1237(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1237, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1239(F, sep, ...) \ + Z_UTIL_LISTIFY_1238(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1238, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1240(F, sep, ...) \ + Z_UTIL_LISTIFY_1239(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1239, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1241(F, sep, ...) \ + Z_UTIL_LISTIFY_1240(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1240, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1242(F, sep, ...) \ + Z_UTIL_LISTIFY_1241(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1241, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1243(F, sep, ...) \ + Z_UTIL_LISTIFY_1242(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1242, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1244(F, sep, ...) \ + Z_UTIL_LISTIFY_1243(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1243, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1245(F, sep, ...) \ + Z_UTIL_LISTIFY_1244(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1244, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1246(F, sep, ...) \ + Z_UTIL_LISTIFY_1245(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1245, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1247(F, sep, ...) \ + Z_UTIL_LISTIFY_1246(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1246, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1248(F, sep, ...) \ + Z_UTIL_LISTIFY_1247(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1247, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1249(F, sep, ...) \ + Z_UTIL_LISTIFY_1248(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1248, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1250(F, sep, ...) \ + Z_UTIL_LISTIFY_1249(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1249, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1251(F, sep, ...) \ + Z_UTIL_LISTIFY_1250(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1250, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1252(F, sep, ...) \ + Z_UTIL_LISTIFY_1251(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1251, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1253(F, sep, ...) \ + Z_UTIL_LISTIFY_1252(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1252, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1254(F, sep, ...) \ + Z_UTIL_LISTIFY_1253(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1253, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1255(F, sep, ...) \ + Z_UTIL_LISTIFY_1254(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1254, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1256(F, sep, ...) \ + Z_UTIL_LISTIFY_1255(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1255, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1257(F, sep, ...) \ + Z_UTIL_LISTIFY_1256(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1256, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1258(F, sep, ...) \ + Z_UTIL_LISTIFY_1257(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1257, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1259(F, sep, ...) \ + Z_UTIL_LISTIFY_1258(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1258, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1260(F, sep, ...) \ + Z_UTIL_LISTIFY_1259(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1259, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1261(F, sep, ...) \ + Z_UTIL_LISTIFY_1260(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1260, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1262(F, sep, ...) \ + Z_UTIL_LISTIFY_1261(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1261, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1263(F, sep, ...) \ + Z_UTIL_LISTIFY_1262(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1262, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1264(F, sep, ...) \ + Z_UTIL_LISTIFY_1263(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1263, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1265(F, sep, ...) \ + Z_UTIL_LISTIFY_1264(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1264, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1266(F, sep, ...) \ + Z_UTIL_LISTIFY_1265(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1265, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1267(F, sep, ...) \ + Z_UTIL_LISTIFY_1266(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1266, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1268(F, sep, ...) \ + Z_UTIL_LISTIFY_1267(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1267, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1269(F, sep, ...) \ + Z_UTIL_LISTIFY_1268(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1268, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1270(F, sep, ...) \ + Z_UTIL_LISTIFY_1269(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1269, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1271(F, sep, ...) \ + Z_UTIL_LISTIFY_1270(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1270, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1272(F, sep, ...) \ + Z_UTIL_LISTIFY_1271(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1271, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1273(F, sep, ...) \ + Z_UTIL_LISTIFY_1272(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1272, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1274(F, sep, ...) \ + Z_UTIL_LISTIFY_1273(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1273, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1275(F, sep, ...) \ + Z_UTIL_LISTIFY_1274(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1274, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1276(F, sep, ...) \ + Z_UTIL_LISTIFY_1275(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1275, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1277(F, sep, ...) \ + Z_UTIL_LISTIFY_1276(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1276, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1278(F, sep, ...) \ + Z_UTIL_LISTIFY_1277(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1277, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1279(F, sep, ...) \ + Z_UTIL_LISTIFY_1278(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1278, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1280(F, sep, ...) \ + Z_UTIL_LISTIFY_1279(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1279, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1281(F, sep, ...) \ + Z_UTIL_LISTIFY_1280(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1280, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1282(F, sep, ...) \ + Z_UTIL_LISTIFY_1281(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1281, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1283(F, sep, ...) \ + Z_UTIL_LISTIFY_1282(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1282, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1284(F, sep, ...) \ + Z_UTIL_LISTIFY_1283(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1283, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1285(F, sep, ...) \ + Z_UTIL_LISTIFY_1284(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1284, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1286(F, sep, ...) \ + Z_UTIL_LISTIFY_1285(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1285, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1287(F, sep, ...) \ + Z_UTIL_LISTIFY_1286(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1286, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1288(F, sep, ...) \ + Z_UTIL_LISTIFY_1287(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1287, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1289(F, sep, ...) \ + Z_UTIL_LISTIFY_1288(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1288, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1290(F, sep, ...) \ + Z_UTIL_LISTIFY_1289(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1289, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1291(F, sep, ...) \ + Z_UTIL_LISTIFY_1290(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1290, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1292(F, sep, ...) \ + Z_UTIL_LISTIFY_1291(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1291, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1293(F, sep, ...) \ + Z_UTIL_LISTIFY_1292(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1292, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1294(F, sep, ...) \ + Z_UTIL_LISTIFY_1293(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1293, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1295(F, sep, ...) \ + Z_UTIL_LISTIFY_1294(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1294, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1296(F, sep, ...) \ + Z_UTIL_LISTIFY_1295(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1295, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1297(F, sep, ...) \ + Z_UTIL_LISTIFY_1296(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1296, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1298(F, sep, ...) \ + Z_UTIL_LISTIFY_1297(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1297, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1299(F, sep, ...) \ + Z_UTIL_LISTIFY_1298(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1298, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1300(F, sep, ...) \ + Z_UTIL_LISTIFY_1299(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1299, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1301(F, sep, ...) \ + Z_UTIL_LISTIFY_1300(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1300, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1302(F, sep, ...) \ + Z_UTIL_LISTIFY_1301(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1301, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1303(F, sep, ...) \ + Z_UTIL_LISTIFY_1302(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1302, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1304(F, sep, ...) \ + Z_UTIL_LISTIFY_1303(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1303, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1305(F, sep, ...) \ + Z_UTIL_LISTIFY_1304(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1304, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1306(F, sep, ...) \ + Z_UTIL_LISTIFY_1305(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1305, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1307(F, sep, ...) \ + Z_UTIL_LISTIFY_1306(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1306, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1308(F, sep, ...) \ + Z_UTIL_LISTIFY_1307(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1307, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1309(F, sep, ...) \ + Z_UTIL_LISTIFY_1308(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1308, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1310(F, sep, ...) \ + Z_UTIL_LISTIFY_1309(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1309, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1311(F, sep, ...) \ + Z_UTIL_LISTIFY_1310(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1310, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1312(F, sep, ...) \ + Z_UTIL_LISTIFY_1311(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1311, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1313(F, sep, ...) \ + Z_UTIL_LISTIFY_1312(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1312, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1314(F, sep, ...) \ + Z_UTIL_LISTIFY_1313(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1313, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1315(F, sep, ...) \ + Z_UTIL_LISTIFY_1314(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1314, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1316(F, sep, ...) \ + Z_UTIL_LISTIFY_1315(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1315, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1317(F, sep, ...) \ + Z_UTIL_LISTIFY_1316(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1316, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1318(F, sep, ...) \ + Z_UTIL_LISTIFY_1317(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1317, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1319(F, sep, ...) \ + Z_UTIL_LISTIFY_1318(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1318, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1320(F, sep, ...) \ + Z_UTIL_LISTIFY_1319(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1319, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1321(F, sep, ...) \ + Z_UTIL_LISTIFY_1320(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1320, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1322(F, sep, ...) \ + Z_UTIL_LISTIFY_1321(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1321, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1323(F, sep, ...) \ + Z_UTIL_LISTIFY_1322(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1322, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1324(F, sep, ...) \ + Z_UTIL_LISTIFY_1323(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1323, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1325(F, sep, ...) \ + Z_UTIL_LISTIFY_1324(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1324, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1326(F, sep, ...) \ + Z_UTIL_LISTIFY_1325(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1325, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1327(F, sep, ...) \ + Z_UTIL_LISTIFY_1326(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1326, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1328(F, sep, ...) \ + Z_UTIL_LISTIFY_1327(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1327, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1329(F, sep, ...) \ + Z_UTIL_LISTIFY_1328(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1328, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1330(F, sep, ...) \ + Z_UTIL_LISTIFY_1329(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1329, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1331(F, sep, ...) \ + Z_UTIL_LISTIFY_1330(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1330, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1332(F, sep, ...) \ + Z_UTIL_LISTIFY_1331(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1331, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1333(F, sep, ...) \ + Z_UTIL_LISTIFY_1332(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1332, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1334(F, sep, ...) \ + Z_UTIL_LISTIFY_1333(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1333, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1335(F, sep, ...) \ + Z_UTIL_LISTIFY_1334(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1334, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1336(F, sep, ...) \ + Z_UTIL_LISTIFY_1335(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1335, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1337(F, sep, ...) \ + Z_UTIL_LISTIFY_1336(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1336, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1338(F, sep, ...) \ + Z_UTIL_LISTIFY_1337(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1337, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1339(F, sep, ...) \ + Z_UTIL_LISTIFY_1338(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1338, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1340(F, sep, ...) \ + Z_UTIL_LISTIFY_1339(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1339, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1341(F, sep, ...) \ + Z_UTIL_LISTIFY_1340(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1340, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1342(F, sep, ...) \ + Z_UTIL_LISTIFY_1341(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1341, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1343(F, sep, ...) \ + Z_UTIL_LISTIFY_1342(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1342, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1344(F, sep, ...) \ + Z_UTIL_LISTIFY_1343(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1343, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1345(F, sep, ...) \ + Z_UTIL_LISTIFY_1344(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1344, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1346(F, sep, ...) \ + Z_UTIL_LISTIFY_1345(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1345, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1347(F, sep, ...) \ + Z_UTIL_LISTIFY_1346(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1346, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1348(F, sep, ...) \ + Z_UTIL_LISTIFY_1347(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1347, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1349(F, sep, ...) \ + Z_UTIL_LISTIFY_1348(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1348, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1350(F, sep, ...) \ + Z_UTIL_LISTIFY_1349(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1349, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1351(F, sep, ...) \ + Z_UTIL_LISTIFY_1350(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1350, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1352(F, sep, ...) \ + Z_UTIL_LISTIFY_1351(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1351, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1353(F, sep, ...) \ + Z_UTIL_LISTIFY_1352(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1352, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1354(F, sep, ...) \ + Z_UTIL_LISTIFY_1353(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1353, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1355(F, sep, ...) \ + Z_UTIL_LISTIFY_1354(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1354, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1356(F, sep, ...) \ + Z_UTIL_LISTIFY_1355(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1355, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1357(F, sep, ...) \ + Z_UTIL_LISTIFY_1356(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1356, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1358(F, sep, ...) \ + Z_UTIL_LISTIFY_1357(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1357, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1359(F, sep, ...) \ + Z_UTIL_LISTIFY_1358(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1358, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1360(F, sep, ...) \ + Z_UTIL_LISTIFY_1359(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1359, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1361(F, sep, ...) \ + Z_UTIL_LISTIFY_1360(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1360, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1362(F, sep, ...) \ + Z_UTIL_LISTIFY_1361(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1361, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1363(F, sep, ...) \ + Z_UTIL_LISTIFY_1362(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1362, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1364(F, sep, ...) \ + Z_UTIL_LISTIFY_1363(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1363, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1365(F, sep, ...) \ + Z_UTIL_LISTIFY_1364(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1364, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1366(F, sep, ...) \ + Z_UTIL_LISTIFY_1365(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1365, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1367(F, sep, ...) \ + Z_UTIL_LISTIFY_1366(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1366, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1368(F, sep, ...) \ + Z_UTIL_LISTIFY_1367(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1367, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1369(F, sep, ...) \ + Z_UTIL_LISTIFY_1368(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1368, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1370(F, sep, ...) \ + Z_UTIL_LISTIFY_1369(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1369, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1371(F, sep, ...) \ + Z_UTIL_LISTIFY_1370(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1370, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1372(F, sep, ...) \ + Z_UTIL_LISTIFY_1371(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1371, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1373(F, sep, ...) \ + Z_UTIL_LISTIFY_1372(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1372, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1374(F, sep, ...) \ + Z_UTIL_LISTIFY_1373(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1373, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1375(F, sep, ...) \ + Z_UTIL_LISTIFY_1374(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1374, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1376(F, sep, ...) \ + Z_UTIL_LISTIFY_1375(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1375, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1377(F, sep, ...) \ + Z_UTIL_LISTIFY_1376(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1376, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1378(F, sep, ...) \ + Z_UTIL_LISTIFY_1377(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1377, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1379(F, sep, ...) \ + Z_UTIL_LISTIFY_1378(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1378, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1380(F, sep, ...) \ + Z_UTIL_LISTIFY_1379(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1379, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1381(F, sep, ...) \ + Z_UTIL_LISTIFY_1380(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1380, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1382(F, sep, ...) \ + Z_UTIL_LISTIFY_1381(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1381, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1383(F, sep, ...) \ + Z_UTIL_LISTIFY_1382(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1382, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1384(F, sep, ...) \ + Z_UTIL_LISTIFY_1383(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1383, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1385(F, sep, ...) \ + Z_UTIL_LISTIFY_1384(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1384, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1386(F, sep, ...) \ + Z_UTIL_LISTIFY_1385(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1385, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1387(F, sep, ...) \ + Z_UTIL_LISTIFY_1386(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1386, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1388(F, sep, ...) \ + Z_UTIL_LISTIFY_1387(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1387, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1389(F, sep, ...) \ + Z_UTIL_LISTIFY_1388(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1388, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1390(F, sep, ...) \ + Z_UTIL_LISTIFY_1389(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1389, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1391(F, sep, ...) \ + Z_UTIL_LISTIFY_1390(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1390, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1392(F, sep, ...) \ + Z_UTIL_LISTIFY_1391(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1391, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1393(F, sep, ...) \ + Z_UTIL_LISTIFY_1392(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1392, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1394(F, sep, ...) \ + Z_UTIL_LISTIFY_1393(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1393, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1395(F, sep, ...) \ + Z_UTIL_LISTIFY_1394(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1394, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1396(F, sep, ...) \ + Z_UTIL_LISTIFY_1395(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1395, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1397(F, sep, ...) \ + Z_UTIL_LISTIFY_1396(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1396, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1398(F, sep, ...) \ + Z_UTIL_LISTIFY_1397(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1397, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1399(F, sep, ...) \ + Z_UTIL_LISTIFY_1398(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1398, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1400(F, sep, ...) \ + Z_UTIL_LISTIFY_1399(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1399, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1401(F, sep, ...) \ + Z_UTIL_LISTIFY_1400(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1400, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1402(F, sep, ...) \ + Z_UTIL_LISTIFY_1401(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1401, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1403(F, sep, ...) \ + Z_UTIL_LISTIFY_1402(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1402, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1404(F, sep, ...) \ + Z_UTIL_LISTIFY_1403(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1403, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1405(F, sep, ...) \ + Z_UTIL_LISTIFY_1404(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1404, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1406(F, sep, ...) \ + Z_UTIL_LISTIFY_1405(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1405, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1407(F, sep, ...) \ + Z_UTIL_LISTIFY_1406(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1406, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1408(F, sep, ...) \ + Z_UTIL_LISTIFY_1407(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1407, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1409(F, sep, ...) \ + Z_UTIL_LISTIFY_1408(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1408, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1410(F, sep, ...) \ + Z_UTIL_LISTIFY_1409(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1409, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1411(F, sep, ...) \ + Z_UTIL_LISTIFY_1410(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1410, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1412(F, sep, ...) \ + Z_UTIL_LISTIFY_1411(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1411, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1413(F, sep, ...) \ + Z_UTIL_LISTIFY_1412(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1412, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1414(F, sep, ...) \ + Z_UTIL_LISTIFY_1413(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1413, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1415(F, sep, ...) \ + Z_UTIL_LISTIFY_1414(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1414, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1416(F, sep, ...) \ + Z_UTIL_LISTIFY_1415(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1415, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1417(F, sep, ...) \ + Z_UTIL_LISTIFY_1416(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1416, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1418(F, sep, ...) \ + Z_UTIL_LISTIFY_1417(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1417, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1419(F, sep, ...) \ + Z_UTIL_LISTIFY_1418(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1418, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1420(F, sep, ...) \ + Z_UTIL_LISTIFY_1419(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1419, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1421(F, sep, ...) \ + Z_UTIL_LISTIFY_1420(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1420, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1422(F, sep, ...) \ + Z_UTIL_LISTIFY_1421(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1421, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1423(F, sep, ...) \ + Z_UTIL_LISTIFY_1422(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1422, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1424(F, sep, ...) \ + Z_UTIL_LISTIFY_1423(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1423, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1425(F, sep, ...) \ + Z_UTIL_LISTIFY_1424(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1424, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1426(F, sep, ...) \ + Z_UTIL_LISTIFY_1425(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1425, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1427(F, sep, ...) \ + Z_UTIL_LISTIFY_1426(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1426, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1428(F, sep, ...) \ + Z_UTIL_LISTIFY_1427(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1427, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1429(F, sep, ...) \ + Z_UTIL_LISTIFY_1428(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1428, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1430(F, sep, ...) \ + Z_UTIL_LISTIFY_1429(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1429, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1431(F, sep, ...) \ + Z_UTIL_LISTIFY_1430(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1430, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1432(F, sep, ...) \ + Z_UTIL_LISTIFY_1431(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1431, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1433(F, sep, ...) \ + Z_UTIL_LISTIFY_1432(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1432, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1434(F, sep, ...) \ + Z_UTIL_LISTIFY_1433(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1433, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1435(F, sep, ...) \ + Z_UTIL_LISTIFY_1434(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1434, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1436(F, sep, ...) \ + Z_UTIL_LISTIFY_1435(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1435, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1437(F, sep, ...) \ + Z_UTIL_LISTIFY_1436(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1436, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1438(F, sep, ...) \ + Z_UTIL_LISTIFY_1437(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1437, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1439(F, sep, ...) \ + Z_UTIL_LISTIFY_1438(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1438, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1440(F, sep, ...) \ + Z_UTIL_LISTIFY_1439(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1439, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1441(F, sep, ...) \ + Z_UTIL_LISTIFY_1440(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1440, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1442(F, sep, ...) \ + Z_UTIL_LISTIFY_1441(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1441, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1443(F, sep, ...) \ + Z_UTIL_LISTIFY_1442(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1442, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1444(F, sep, ...) \ + Z_UTIL_LISTIFY_1443(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1443, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1445(F, sep, ...) \ + Z_UTIL_LISTIFY_1444(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1444, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1446(F, sep, ...) \ + Z_UTIL_LISTIFY_1445(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1445, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1447(F, sep, ...) \ + Z_UTIL_LISTIFY_1446(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1446, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1448(F, sep, ...) \ + Z_UTIL_LISTIFY_1447(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1447, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1449(F, sep, ...) \ + Z_UTIL_LISTIFY_1448(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1448, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1450(F, sep, ...) \ + Z_UTIL_LISTIFY_1449(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1449, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1451(F, sep, ...) \ + Z_UTIL_LISTIFY_1450(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1450, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1452(F, sep, ...) \ + Z_UTIL_LISTIFY_1451(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1451, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1453(F, sep, ...) \ + Z_UTIL_LISTIFY_1452(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1452, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1454(F, sep, ...) \ + Z_UTIL_LISTIFY_1453(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1453, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1455(F, sep, ...) \ + Z_UTIL_LISTIFY_1454(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1454, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1456(F, sep, ...) \ + Z_UTIL_LISTIFY_1455(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1455, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1457(F, sep, ...) \ + Z_UTIL_LISTIFY_1456(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1456, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1458(F, sep, ...) \ + Z_UTIL_LISTIFY_1457(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1457, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1459(F, sep, ...) \ + Z_UTIL_LISTIFY_1458(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1458, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1460(F, sep, ...) \ + Z_UTIL_LISTIFY_1459(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1459, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1461(F, sep, ...) \ + Z_UTIL_LISTIFY_1460(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1460, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1462(F, sep, ...) \ + Z_UTIL_LISTIFY_1461(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1461, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1463(F, sep, ...) \ + Z_UTIL_LISTIFY_1462(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1462, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1464(F, sep, ...) \ + Z_UTIL_LISTIFY_1463(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1463, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1465(F, sep, ...) \ + Z_UTIL_LISTIFY_1464(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1464, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1466(F, sep, ...) \ + Z_UTIL_LISTIFY_1465(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1465, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1467(F, sep, ...) \ + Z_UTIL_LISTIFY_1466(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1466, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1468(F, sep, ...) \ + Z_UTIL_LISTIFY_1467(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1467, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1469(F, sep, ...) \ + Z_UTIL_LISTIFY_1468(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1468, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1470(F, sep, ...) \ + Z_UTIL_LISTIFY_1469(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1469, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1471(F, sep, ...) \ + Z_UTIL_LISTIFY_1470(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1470, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1472(F, sep, ...) \ + Z_UTIL_LISTIFY_1471(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1471, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1473(F, sep, ...) \ + Z_UTIL_LISTIFY_1472(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1472, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1474(F, sep, ...) \ + Z_UTIL_LISTIFY_1473(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1473, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1475(F, sep, ...) \ + Z_UTIL_LISTIFY_1474(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1474, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1476(F, sep, ...) \ + Z_UTIL_LISTIFY_1475(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1475, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1477(F, sep, ...) \ + Z_UTIL_LISTIFY_1476(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1476, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1478(F, sep, ...) \ + Z_UTIL_LISTIFY_1477(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1477, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1479(F, sep, ...) \ + Z_UTIL_LISTIFY_1478(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1478, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1480(F, sep, ...) \ + Z_UTIL_LISTIFY_1479(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1479, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1481(F, sep, ...) \ + Z_UTIL_LISTIFY_1480(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1480, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1482(F, sep, ...) \ + Z_UTIL_LISTIFY_1481(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1481, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1483(F, sep, ...) \ + Z_UTIL_LISTIFY_1482(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1482, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1484(F, sep, ...) \ + Z_UTIL_LISTIFY_1483(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1483, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1485(F, sep, ...) \ + Z_UTIL_LISTIFY_1484(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1484, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1486(F, sep, ...) \ + Z_UTIL_LISTIFY_1485(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1485, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1487(F, sep, ...) \ + Z_UTIL_LISTIFY_1486(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1486, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1488(F, sep, ...) \ + Z_UTIL_LISTIFY_1487(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1487, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1489(F, sep, ...) \ + Z_UTIL_LISTIFY_1488(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1488, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1490(F, sep, ...) \ + Z_UTIL_LISTIFY_1489(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1489, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1491(F, sep, ...) \ + Z_UTIL_LISTIFY_1490(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1490, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1492(F, sep, ...) \ + Z_UTIL_LISTIFY_1491(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1491, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1493(F, sep, ...) \ + Z_UTIL_LISTIFY_1492(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1492, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1494(F, sep, ...) \ + Z_UTIL_LISTIFY_1493(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1493, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1495(F, sep, ...) \ + Z_UTIL_LISTIFY_1494(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1494, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1496(F, sep, ...) \ + Z_UTIL_LISTIFY_1495(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1495, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1497(F, sep, ...) \ + Z_UTIL_LISTIFY_1496(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1496, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1498(F, sep, ...) \ + Z_UTIL_LISTIFY_1497(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1497, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1499(F, sep, ...) \ + Z_UTIL_LISTIFY_1498(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1498, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1500(F, sep, ...) \ + Z_UTIL_LISTIFY_1499(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1499, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1501(F, sep, ...) \ + Z_UTIL_LISTIFY_1500(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1500, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1502(F, sep, ...) \ + Z_UTIL_LISTIFY_1501(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1501, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1503(F, sep, ...) \ + Z_UTIL_LISTIFY_1502(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1502, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1504(F, sep, ...) \ + Z_UTIL_LISTIFY_1503(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1503, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1505(F, sep, ...) \ + Z_UTIL_LISTIFY_1504(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1504, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1506(F, sep, ...) \ + Z_UTIL_LISTIFY_1505(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1505, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1507(F, sep, ...) \ + Z_UTIL_LISTIFY_1506(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1506, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1508(F, sep, ...) \ + Z_UTIL_LISTIFY_1507(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1507, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1509(F, sep, ...) \ + Z_UTIL_LISTIFY_1508(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1508, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1510(F, sep, ...) \ + Z_UTIL_LISTIFY_1509(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1509, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1511(F, sep, ...) \ + Z_UTIL_LISTIFY_1510(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1510, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1512(F, sep, ...) \ + Z_UTIL_LISTIFY_1511(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1511, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1513(F, sep, ...) \ + Z_UTIL_LISTIFY_1512(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1512, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1514(F, sep, ...) \ + Z_UTIL_LISTIFY_1513(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1513, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1515(F, sep, ...) \ + Z_UTIL_LISTIFY_1514(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1514, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1516(F, sep, ...) \ + Z_UTIL_LISTIFY_1515(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1515, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1517(F, sep, ...) \ + Z_UTIL_LISTIFY_1516(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1516, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1518(F, sep, ...) \ + Z_UTIL_LISTIFY_1517(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1517, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1519(F, sep, ...) \ + Z_UTIL_LISTIFY_1518(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1518, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1520(F, sep, ...) \ + Z_UTIL_LISTIFY_1519(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1519, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1521(F, sep, ...) \ + Z_UTIL_LISTIFY_1520(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1520, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1522(F, sep, ...) \ + Z_UTIL_LISTIFY_1521(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1521, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1523(F, sep, ...) \ + Z_UTIL_LISTIFY_1522(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1522, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1524(F, sep, ...) \ + Z_UTIL_LISTIFY_1523(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1523, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1525(F, sep, ...) \ + Z_UTIL_LISTIFY_1524(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1524, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1526(F, sep, ...) \ + Z_UTIL_LISTIFY_1525(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1525, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1527(F, sep, ...) \ + Z_UTIL_LISTIFY_1526(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1526, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1528(F, sep, ...) \ + Z_UTIL_LISTIFY_1527(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1527, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1529(F, sep, ...) \ + Z_UTIL_LISTIFY_1528(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1528, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1530(F, sep, ...) \ + Z_UTIL_LISTIFY_1529(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1529, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1531(F, sep, ...) \ + Z_UTIL_LISTIFY_1530(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1530, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1532(F, sep, ...) \ + Z_UTIL_LISTIFY_1531(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1531, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1533(F, sep, ...) \ + Z_UTIL_LISTIFY_1532(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1532, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1534(F, sep, ...) \ + Z_UTIL_LISTIFY_1533(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1533, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1535(F, sep, ...) \ + Z_UTIL_LISTIFY_1534(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1534, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1536(F, sep, ...) \ + Z_UTIL_LISTIFY_1535(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1535, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1537(F, sep, ...) \ + Z_UTIL_LISTIFY_1536(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1536, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1538(F, sep, ...) \ + Z_UTIL_LISTIFY_1537(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1537, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1539(F, sep, ...) \ + Z_UTIL_LISTIFY_1538(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1538, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1540(F, sep, ...) \ + Z_UTIL_LISTIFY_1539(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1539, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1541(F, sep, ...) \ + Z_UTIL_LISTIFY_1540(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1540, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1542(F, sep, ...) \ + Z_UTIL_LISTIFY_1541(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1541, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1543(F, sep, ...) \ + Z_UTIL_LISTIFY_1542(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1542, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1544(F, sep, ...) \ + Z_UTIL_LISTIFY_1543(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1543, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1545(F, sep, ...) \ + Z_UTIL_LISTIFY_1544(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1544, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1546(F, sep, ...) \ + Z_UTIL_LISTIFY_1545(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1545, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1547(F, sep, ...) \ + Z_UTIL_LISTIFY_1546(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1546, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1548(F, sep, ...) \ + Z_UTIL_LISTIFY_1547(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1547, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1549(F, sep, ...) \ + Z_UTIL_LISTIFY_1548(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1548, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1550(F, sep, ...) \ + Z_UTIL_LISTIFY_1549(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1549, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1551(F, sep, ...) \ + Z_UTIL_LISTIFY_1550(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1550, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1552(F, sep, ...) \ + Z_UTIL_LISTIFY_1551(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1551, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1553(F, sep, ...) \ + Z_UTIL_LISTIFY_1552(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1552, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1554(F, sep, ...) \ + Z_UTIL_LISTIFY_1553(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1553, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1555(F, sep, ...) \ + Z_UTIL_LISTIFY_1554(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1554, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1556(F, sep, ...) \ + Z_UTIL_LISTIFY_1555(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1555, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1557(F, sep, ...) \ + Z_UTIL_LISTIFY_1556(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1556, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1558(F, sep, ...) \ + Z_UTIL_LISTIFY_1557(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1557, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1559(F, sep, ...) \ + Z_UTIL_LISTIFY_1558(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1558, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1560(F, sep, ...) \ + Z_UTIL_LISTIFY_1559(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1559, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1561(F, sep, ...) \ + Z_UTIL_LISTIFY_1560(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1560, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1562(F, sep, ...) \ + Z_UTIL_LISTIFY_1561(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1561, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1563(F, sep, ...) \ + Z_UTIL_LISTIFY_1562(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1562, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1564(F, sep, ...) \ + Z_UTIL_LISTIFY_1563(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1563, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1565(F, sep, ...) \ + Z_UTIL_LISTIFY_1564(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1564, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1566(F, sep, ...) \ + Z_UTIL_LISTIFY_1565(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1565, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1567(F, sep, ...) \ + Z_UTIL_LISTIFY_1566(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1566, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1568(F, sep, ...) \ + Z_UTIL_LISTIFY_1567(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1567, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1569(F, sep, ...) \ + Z_UTIL_LISTIFY_1568(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1568, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1570(F, sep, ...) \ + Z_UTIL_LISTIFY_1569(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1569, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1571(F, sep, ...) \ + Z_UTIL_LISTIFY_1570(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1570, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1572(F, sep, ...) \ + Z_UTIL_LISTIFY_1571(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1571, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1573(F, sep, ...) \ + Z_UTIL_LISTIFY_1572(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1572, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1574(F, sep, ...) \ + Z_UTIL_LISTIFY_1573(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1573, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1575(F, sep, ...) \ + Z_UTIL_LISTIFY_1574(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1574, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1576(F, sep, ...) \ + Z_UTIL_LISTIFY_1575(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1575, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1577(F, sep, ...) \ + Z_UTIL_LISTIFY_1576(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1576, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1578(F, sep, ...) \ + Z_UTIL_LISTIFY_1577(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1577, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1579(F, sep, ...) \ + Z_UTIL_LISTIFY_1578(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1578, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1580(F, sep, ...) \ + Z_UTIL_LISTIFY_1579(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1579, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1581(F, sep, ...) \ + Z_UTIL_LISTIFY_1580(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1580, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1582(F, sep, ...) \ + Z_UTIL_LISTIFY_1581(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1581, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1583(F, sep, ...) \ + Z_UTIL_LISTIFY_1582(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1582, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1584(F, sep, ...) \ + Z_UTIL_LISTIFY_1583(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1583, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1585(F, sep, ...) \ + Z_UTIL_LISTIFY_1584(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1584, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1586(F, sep, ...) \ + Z_UTIL_LISTIFY_1585(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1585, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1587(F, sep, ...) \ + Z_UTIL_LISTIFY_1586(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1586, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1588(F, sep, ...) \ + Z_UTIL_LISTIFY_1587(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1587, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1589(F, sep, ...) \ + Z_UTIL_LISTIFY_1588(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1588, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1590(F, sep, ...) \ + Z_UTIL_LISTIFY_1589(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1589, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1591(F, sep, ...) \ + Z_UTIL_LISTIFY_1590(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1590, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1592(F, sep, ...) \ + Z_UTIL_LISTIFY_1591(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1591, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1593(F, sep, ...) \ + Z_UTIL_LISTIFY_1592(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1592, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1594(F, sep, ...) \ + Z_UTIL_LISTIFY_1593(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1593, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1595(F, sep, ...) \ + Z_UTIL_LISTIFY_1594(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1594, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1596(F, sep, ...) \ + Z_UTIL_LISTIFY_1595(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1595, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1597(F, sep, ...) \ + Z_UTIL_LISTIFY_1596(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1596, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1598(F, sep, ...) \ + Z_UTIL_LISTIFY_1597(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1597, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1599(F, sep, ...) \ + Z_UTIL_LISTIFY_1598(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1598, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1600(F, sep, ...) \ + Z_UTIL_LISTIFY_1599(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1599, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1601(F, sep, ...) \ + Z_UTIL_LISTIFY_1600(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1600, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1602(F, sep, ...) \ + Z_UTIL_LISTIFY_1601(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1601, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1603(F, sep, ...) \ + Z_UTIL_LISTIFY_1602(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1602, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1604(F, sep, ...) \ + Z_UTIL_LISTIFY_1603(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1603, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1605(F, sep, ...) \ + Z_UTIL_LISTIFY_1604(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1604, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1606(F, sep, ...) \ + Z_UTIL_LISTIFY_1605(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1605, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1607(F, sep, ...) \ + Z_UTIL_LISTIFY_1606(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1606, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1608(F, sep, ...) \ + Z_UTIL_LISTIFY_1607(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1607, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1609(F, sep, ...) \ + Z_UTIL_LISTIFY_1608(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1608, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1610(F, sep, ...) \ + Z_UTIL_LISTIFY_1609(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1609, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1611(F, sep, ...) \ + Z_UTIL_LISTIFY_1610(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1610, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1612(F, sep, ...) \ + Z_UTIL_LISTIFY_1611(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1611, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1613(F, sep, ...) \ + Z_UTIL_LISTIFY_1612(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1612, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1614(F, sep, ...) \ + Z_UTIL_LISTIFY_1613(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1613, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1615(F, sep, ...) \ + Z_UTIL_LISTIFY_1614(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1614, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1616(F, sep, ...) \ + Z_UTIL_LISTIFY_1615(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1615, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1617(F, sep, ...) \ + Z_UTIL_LISTIFY_1616(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1616, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1618(F, sep, ...) \ + Z_UTIL_LISTIFY_1617(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1617, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1619(F, sep, ...) \ + Z_UTIL_LISTIFY_1618(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1618, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1620(F, sep, ...) \ + Z_UTIL_LISTIFY_1619(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1619, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1621(F, sep, ...) \ + Z_UTIL_LISTIFY_1620(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1620, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1622(F, sep, ...) \ + Z_UTIL_LISTIFY_1621(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1621, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1623(F, sep, ...) \ + Z_UTIL_LISTIFY_1622(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1622, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1624(F, sep, ...) \ + Z_UTIL_LISTIFY_1623(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1623, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1625(F, sep, ...) \ + Z_UTIL_LISTIFY_1624(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1624, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1626(F, sep, ...) \ + Z_UTIL_LISTIFY_1625(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1625, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1627(F, sep, ...) \ + Z_UTIL_LISTIFY_1626(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1626, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1628(F, sep, ...) \ + Z_UTIL_LISTIFY_1627(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1627, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1629(F, sep, ...) \ + Z_UTIL_LISTIFY_1628(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1628, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1630(F, sep, ...) \ + Z_UTIL_LISTIFY_1629(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1629, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1631(F, sep, ...) \ + Z_UTIL_LISTIFY_1630(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1630, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1632(F, sep, ...) \ + Z_UTIL_LISTIFY_1631(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1631, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1633(F, sep, ...) \ + Z_UTIL_LISTIFY_1632(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1632, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1634(F, sep, ...) \ + Z_UTIL_LISTIFY_1633(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1633, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1635(F, sep, ...) \ + Z_UTIL_LISTIFY_1634(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1634, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1636(F, sep, ...) \ + Z_UTIL_LISTIFY_1635(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1635, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1637(F, sep, ...) \ + Z_UTIL_LISTIFY_1636(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1636, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1638(F, sep, ...) \ + Z_UTIL_LISTIFY_1637(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1637, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1639(F, sep, ...) \ + Z_UTIL_LISTIFY_1638(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1638, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1640(F, sep, ...) \ + Z_UTIL_LISTIFY_1639(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1639, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1641(F, sep, ...) \ + Z_UTIL_LISTIFY_1640(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1640, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1642(F, sep, ...) \ + Z_UTIL_LISTIFY_1641(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1641, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1643(F, sep, ...) \ + Z_UTIL_LISTIFY_1642(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1642, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1644(F, sep, ...) \ + Z_UTIL_LISTIFY_1643(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1643, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1645(F, sep, ...) \ + Z_UTIL_LISTIFY_1644(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1644, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1646(F, sep, ...) \ + Z_UTIL_LISTIFY_1645(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1645, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1647(F, sep, ...) \ + Z_UTIL_LISTIFY_1646(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1646, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1648(F, sep, ...) \ + Z_UTIL_LISTIFY_1647(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1647, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1649(F, sep, ...) \ + Z_UTIL_LISTIFY_1648(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1648, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1650(F, sep, ...) \ + Z_UTIL_LISTIFY_1649(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1649, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1651(F, sep, ...) \ + Z_UTIL_LISTIFY_1650(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1650, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1652(F, sep, ...) \ + Z_UTIL_LISTIFY_1651(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1651, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1653(F, sep, ...) \ + Z_UTIL_LISTIFY_1652(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1652, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1654(F, sep, ...) \ + Z_UTIL_LISTIFY_1653(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1653, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1655(F, sep, ...) \ + Z_UTIL_LISTIFY_1654(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1654, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1656(F, sep, ...) \ + Z_UTIL_LISTIFY_1655(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1655, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1657(F, sep, ...) \ + Z_UTIL_LISTIFY_1656(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1656, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1658(F, sep, ...) \ + Z_UTIL_LISTIFY_1657(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1657, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1659(F, sep, ...) \ + Z_UTIL_LISTIFY_1658(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1658, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1660(F, sep, ...) \ + Z_UTIL_LISTIFY_1659(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1659, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1661(F, sep, ...) \ + Z_UTIL_LISTIFY_1660(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1660, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1662(F, sep, ...) \ + Z_UTIL_LISTIFY_1661(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1661, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1663(F, sep, ...) \ + Z_UTIL_LISTIFY_1662(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1662, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1664(F, sep, ...) \ + Z_UTIL_LISTIFY_1663(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1663, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1665(F, sep, ...) \ + Z_UTIL_LISTIFY_1664(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1664, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1666(F, sep, ...) \ + Z_UTIL_LISTIFY_1665(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1665, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1667(F, sep, ...) \ + Z_UTIL_LISTIFY_1666(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1666, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1668(F, sep, ...) \ + Z_UTIL_LISTIFY_1667(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1667, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1669(F, sep, ...) \ + Z_UTIL_LISTIFY_1668(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1668, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1670(F, sep, ...) \ + Z_UTIL_LISTIFY_1669(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1669, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1671(F, sep, ...) \ + Z_UTIL_LISTIFY_1670(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1670, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1672(F, sep, ...) \ + Z_UTIL_LISTIFY_1671(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1671, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1673(F, sep, ...) \ + Z_UTIL_LISTIFY_1672(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1672, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1674(F, sep, ...) \ + Z_UTIL_LISTIFY_1673(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1673, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1675(F, sep, ...) \ + Z_UTIL_LISTIFY_1674(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1674, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1676(F, sep, ...) \ + Z_UTIL_LISTIFY_1675(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1675, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1677(F, sep, ...) \ + Z_UTIL_LISTIFY_1676(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1676, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1678(F, sep, ...) \ + Z_UTIL_LISTIFY_1677(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1677, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1679(F, sep, ...) \ + Z_UTIL_LISTIFY_1678(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1678, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1680(F, sep, ...) \ + Z_UTIL_LISTIFY_1679(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1679, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1681(F, sep, ...) \ + Z_UTIL_LISTIFY_1680(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1680, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1682(F, sep, ...) \ + Z_UTIL_LISTIFY_1681(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1681, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1683(F, sep, ...) \ + Z_UTIL_LISTIFY_1682(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1682, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1684(F, sep, ...) \ + Z_UTIL_LISTIFY_1683(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1683, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1685(F, sep, ...) \ + Z_UTIL_LISTIFY_1684(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1684, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1686(F, sep, ...) \ + Z_UTIL_LISTIFY_1685(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1685, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1687(F, sep, ...) \ + Z_UTIL_LISTIFY_1686(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1686, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1688(F, sep, ...) \ + Z_UTIL_LISTIFY_1687(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1687, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1689(F, sep, ...) \ + Z_UTIL_LISTIFY_1688(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1688, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1690(F, sep, ...) \ + Z_UTIL_LISTIFY_1689(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1689, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1691(F, sep, ...) \ + Z_UTIL_LISTIFY_1690(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1690, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1692(F, sep, ...) \ + Z_UTIL_LISTIFY_1691(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1691, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1693(F, sep, ...) \ + Z_UTIL_LISTIFY_1692(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1692, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1694(F, sep, ...) \ + Z_UTIL_LISTIFY_1693(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1693, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1695(F, sep, ...) \ + Z_UTIL_LISTIFY_1694(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1694, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1696(F, sep, ...) \ + Z_UTIL_LISTIFY_1695(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1695, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1697(F, sep, ...) \ + Z_UTIL_LISTIFY_1696(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1696, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1698(F, sep, ...) \ + Z_UTIL_LISTIFY_1697(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1697, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1699(F, sep, ...) \ + Z_UTIL_LISTIFY_1698(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1698, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1700(F, sep, ...) \ + Z_UTIL_LISTIFY_1699(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1699, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1701(F, sep, ...) \ + Z_UTIL_LISTIFY_1700(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1700, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1702(F, sep, ...) \ + Z_UTIL_LISTIFY_1701(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1701, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1703(F, sep, ...) \ + Z_UTIL_LISTIFY_1702(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1702, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1704(F, sep, ...) \ + Z_UTIL_LISTIFY_1703(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1703, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1705(F, sep, ...) \ + Z_UTIL_LISTIFY_1704(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1704, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1706(F, sep, ...) \ + Z_UTIL_LISTIFY_1705(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1705, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1707(F, sep, ...) \ + Z_UTIL_LISTIFY_1706(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1706, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1708(F, sep, ...) \ + Z_UTIL_LISTIFY_1707(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1707, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1709(F, sep, ...) \ + Z_UTIL_LISTIFY_1708(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1708, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1710(F, sep, ...) \ + Z_UTIL_LISTIFY_1709(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1709, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1711(F, sep, ...) \ + Z_UTIL_LISTIFY_1710(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1710, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1712(F, sep, ...) \ + Z_UTIL_LISTIFY_1711(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1711, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1713(F, sep, ...) \ + Z_UTIL_LISTIFY_1712(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1712, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1714(F, sep, ...) \ + Z_UTIL_LISTIFY_1713(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1713, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1715(F, sep, ...) \ + Z_UTIL_LISTIFY_1714(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1714, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1716(F, sep, ...) \ + Z_UTIL_LISTIFY_1715(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1715, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1717(F, sep, ...) \ + Z_UTIL_LISTIFY_1716(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1716, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1718(F, sep, ...) \ + Z_UTIL_LISTIFY_1717(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1717, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1719(F, sep, ...) \ + Z_UTIL_LISTIFY_1718(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1718, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1720(F, sep, ...) \ + Z_UTIL_LISTIFY_1719(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1719, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1721(F, sep, ...) \ + Z_UTIL_LISTIFY_1720(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1720, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1722(F, sep, ...) \ + Z_UTIL_LISTIFY_1721(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1721, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1723(F, sep, ...) \ + Z_UTIL_LISTIFY_1722(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1722, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1724(F, sep, ...) \ + Z_UTIL_LISTIFY_1723(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1723, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1725(F, sep, ...) \ + Z_UTIL_LISTIFY_1724(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1724, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1726(F, sep, ...) \ + Z_UTIL_LISTIFY_1725(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1725, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1727(F, sep, ...) \ + Z_UTIL_LISTIFY_1726(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1726, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1728(F, sep, ...) \ + Z_UTIL_LISTIFY_1727(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1727, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1729(F, sep, ...) \ + Z_UTIL_LISTIFY_1728(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1728, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1730(F, sep, ...) \ + Z_UTIL_LISTIFY_1729(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1729, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1731(F, sep, ...) \ + Z_UTIL_LISTIFY_1730(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1730, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1732(F, sep, ...) \ + Z_UTIL_LISTIFY_1731(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1731, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1733(F, sep, ...) \ + Z_UTIL_LISTIFY_1732(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1732, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1734(F, sep, ...) \ + Z_UTIL_LISTIFY_1733(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1733, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1735(F, sep, ...) \ + Z_UTIL_LISTIFY_1734(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1734, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1736(F, sep, ...) \ + Z_UTIL_LISTIFY_1735(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1735, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1737(F, sep, ...) \ + Z_UTIL_LISTIFY_1736(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1736, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1738(F, sep, ...) \ + Z_UTIL_LISTIFY_1737(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1737, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1739(F, sep, ...) \ + Z_UTIL_LISTIFY_1738(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1738, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1740(F, sep, ...) \ + Z_UTIL_LISTIFY_1739(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1739, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1741(F, sep, ...) \ + Z_UTIL_LISTIFY_1740(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1740, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1742(F, sep, ...) \ + Z_UTIL_LISTIFY_1741(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1741, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1743(F, sep, ...) \ + Z_UTIL_LISTIFY_1742(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1742, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1744(F, sep, ...) \ + Z_UTIL_LISTIFY_1743(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1743, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1745(F, sep, ...) \ + Z_UTIL_LISTIFY_1744(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1744, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1746(F, sep, ...) \ + Z_UTIL_LISTIFY_1745(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1745, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1747(F, sep, ...) \ + Z_UTIL_LISTIFY_1746(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1746, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1748(F, sep, ...) \ + Z_UTIL_LISTIFY_1747(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1747, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1749(F, sep, ...) \ + Z_UTIL_LISTIFY_1748(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1748, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1750(F, sep, ...) \ + Z_UTIL_LISTIFY_1749(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1749, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1751(F, sep, ...) \ + Z_UTIL_LISTIFY_1750(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1750, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1752(F, sep, ...) \ + Z_UTIL_LISTIFY_1751(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1751, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1753(F, sep, ...) \ + Z_UTIL_LISTIFY_1752(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1752, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1754(F, sep, ...) \ + Z_UTIL_LISTIFY_1753(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1753, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1755(F, sep, ...) \ + Z_UTIL_LISTIFY_1754(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1754, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1756(F, sep, ...) \ + Z_UTIL_LISTIFY_1755(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1755, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1757(F, sep, ...) \ + Z_UTIL_LISTIFY_1756(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1756, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1758(F, sep, ...) \ + Z_UTIL_LISTIFY_1757(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1757, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1759(F, sep, ...) \ + Z_UTIL_LISTIFY_1758(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1758, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1760(F, sep, ...) \ + Z_UTIL_LISTIFY_1759(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1759, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1761(F, sep, ...) \ + Z_UTIL_LISTIFY_1760(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1760, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1762(F, sep, ...) \ + Z_UTIL_LISTIFY_1761(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1761, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1763(F, sep, ...) \ + Z_UTIL_LISTIFY_1762(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1762, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1764(F, sep, ...) \ + Z_UTIL_LISTIFY_1763(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1763, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1765(F, sep, ...) \ + Z_UTIL_LISTIFY_1764(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1764, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1766(F, sep, ...) \ + Z_UTIL_LISTIFY_1765(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1765, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1767(F, sep, ...) \ + Z_UTIL_LISTIFY_1766(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1766, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1768(F, sep, ...) \ + Z_UTIL_LISTIFY_1767(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1767, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1769(F, sep, ...) \ + Z_UTIL_LISTIFY_1768(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1768, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1770(F, sep, ...) \ + Z_UTIL_LISTIFY_1769(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1769, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1771(F, sep, ...) \ + Z_UTIL_LISTIFY_1770(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1770, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1772(F, sep, ...) \ + Z_UTIL_LISTIFY_1771(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1771, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1773(F, sep, ...) \ + Z_UTIL_LISTIFY_1772(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1772, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1774(F, sep, ...) \ + Z_UTIL_LISTIFY_1773(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1773, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1775(F, sep, ...) \ + Z_UTIL_LISTIFY_1774(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1774, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1776(F, sep, ...) \ + Z_UTIL_LISTIFY_1775(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1775, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1777(F, sep, ...) \ + Z_UTIL_LISTIFY_1776(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1776, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1778(F, sep, ...) \ + Z_UTIL_LISTIFY_1777(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1777, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1779(F, sep, ...) \ + Z_UTIL_LISTIFY_1778(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1778, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1780(F, sep, ...) \ + Z_UTIL_LISTIFY_1779(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1779, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1781(F, sep, ...) \ + Z_UTIL_LISTIFY_1780(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1780, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1782(F, sep, ...) \ + Z_UTIL_LISTIFY_1781(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1781, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1783(F, sep, ...) \ + Z_UTIL_LISTIFY_1782(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1782, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1784(F, sep, ...) \ + Z_UTIL_LISTIFY_1783(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1783, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1785(F, sep, ...) \ + Z_UTIL_LISTIFY_1784(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1784, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1786(F, sep, ...) \ + Z_UTIL_LISTIFY_1785(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1785, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1787(F, sep, ...) \ + Z_UTIL_LISTIFY_1786(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1786, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1788(F, sep, ...) \ + Z_UTIL_LISTIFY_1787(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1787, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1789(F, sep, ...) \ + Z_UTIL_LISTIFY_1788(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1788, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1790(F, sep, ...) \ + Z_UTIL_LISTIFY_1789(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1789, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1791(F, sep, ...) \ + Z_UTIL_LISTIFY_1790(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1790, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1792(F, sep, ...) \ + Z_UTIL_LISTIFY_1791(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1791, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1793(F, sep, ...) \ + Z_UTIL_LISTIFY_1792(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1792, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1794(F, sep, ...) \ + Z_UTIL_LISTIFY_1793(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1793, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1795(F, sep, ...) \ + Z_UTIL_LISTIFY_1794(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1794, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1796(F, sep, ...) \ + Z_UTIL_LISTIFY_1795(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1795, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1797(F, sep, ...) \ + Z_UTIL_LISTIFY_1796(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1796, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1798(F, sep, ...) \ + Z_UTIL_LISTIFY_1797(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1797, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1799(F, sep, ...) \ + Z_UTIL_LISTIFY_1798(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1798, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1800(F, sep, ...) \ + Z_UTIL_LISTIFY_1799(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1799, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1801(F, sep, ...) \ + Z_UTIL_LISTIFY_1800(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1800, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1802(F, sep, ...) \ + Z_UTIL_LISTIFY_1801(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1801, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1803(F, sep, ...) \ + Z_UTIL_LISTIFY_1802(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1802, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1804(F, sep, ...) \ + Z_UTIL_LISTIFY_1803(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1803, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1805(F, sep, ...) \ + Z_UTIL_LISTIFY_1804(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1804, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1806(F, sep, ...) \ + Z_UTIL_LISTIFY_1805(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1805, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1807(F, sep, ...) \ + Z_UTIL_LISTIFY_1806(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1806, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1808(F, sep, ...) \ + Z_UTIL_LISTIFY_1807(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1807, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1809(F, sep, ...) \ + Z_UTIL_LISTIFY_1808(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1808, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1810(F, sep, ...) \ + Z_UTIL_LISTIFY_1809(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1809, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1811(F, sep, ...) \ + Z_UTIL_LISTIFY_1810(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1810, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1812(F, sep, ...) \ + Z_UTIL_LISTIFY_1811(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1811, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1813(F, sep, ...) \ + Z_UTIL_LISTIFY_1812(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1812, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1814(F, sep, ...) \ + Z_UTIL_LISTIFY_1813(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1813, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1815(F, sep, ...) \ + Z_UTIL_LISTIFY_1814(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1814, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1816(F, sep, ...) \ + Z_UTIL_LISTIFY_1815(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1815, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1817(F, sep, ...) \ + Z_UTIL_LISTIFY_1816(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1816, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1818(F, sep, ...) \ + Z_UTIL_LISTIFY_1817(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1817, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1819(F, sep, ...) \ + Z_UTIL_LISTIFY_1818(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1818, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1820(F, sep, ...) \ + Z_UTIL_LISTIFY_1819(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1819, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1821(F, sep, ...) \ + Z_UTIL_LISTIFY_1820(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1820, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1822(F, sep, ...) \ + Z_UTIL_LISTIFY_1821(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1821, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1823(F, sep, ...) \ + Z_UTIL_LISTIFY_1822(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1822, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1824(F, sep, ...) \ + Z_UTIL_LISTIFY_1823(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1823, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1825(F, sep, ...) \ + Z_UTIL_LISTIFY_1824(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1824, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1826(F, sep, ...) \ + Z_UTIL_LISTIFY_1825(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1825, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1827(F, sep, ...) \ + Z_UTIL_LISTIFY_1826(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1826, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1828(F, sep, ...) \ + Z_UTIL_LISTIFY_1827(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1827, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1829(F, sep, ...) \ + Z_UTIL_LISTIFY_1828(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1828, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1830(F, sep, ...) \ + Z_UTIL_LISTIFY_1829(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1829, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1831(F, sep, ...) \ + Z_UTIL_LISTIFY_1830(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1830, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1832(F, sep, ...) \ + Z_UTIL_LISTIFY_1831(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1831, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1833(F, sep, ...) \ + Z_UTIL_LISTIFY_1832(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1832, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1834(F, sep, ...) \ + Z_UTIL_LISTIFY_1833(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1833, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1835(F, sep, ...) \ + Z_UTIL_LISTIFY_1834(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1834, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1836(F, sep, ...) \ + Z_UTIL_LISTIFY_1835(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1835, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1837(F, sep, ...) \ + Z_UTIL_LISTIFY_1836(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1836, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1838(F, sep, ...) \ + Z_UTIL_LISTIFY_1837(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1837, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1839(F, sep, ...) \ + Z_UTIL_LISTIFY_1838(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1838, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1840(F, sep, ...) \ + Z_UTIL_LISTIFY_1839(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1839, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1841(F, sep, ...) \ + Z_UTIL_LISTIFY_1840(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1840, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1842(F, sep, ...) \ + Z_UTIL_LISTIFY_1841(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1841, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1843(F, sep, ...) \ + Z_UTIL_LISTIFY_1842(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1842, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1844(F, sep, ...) \ + Z_UTIL_LISTIFY_1843(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1843, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1845(F, sep, ...) \ + Z_UTIL_LISTIFY_1844(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1844, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1846(F, sep, ...) \ + Z_UTIL_LISTIFY_1845(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1845, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1847(F, sep, ...) \ + Z_UTIL_LISTIFY_1846(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1846, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1848(F, sep, ...) \ + Z_UTIL_LISTIFY_1847(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1847, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1849(F, sep, ...) \ + Z_UTIL_LISTIFY_1848(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1848, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1850(F, sep, ...) \ + Z_UTIL_LISTIFY_1849(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1849, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1851(F, sep, ...) \ + Z_UTIL_LISTIFY_1850(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1850, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1852(F, sep, ...) \ + Z_UTIL_LISTIFY_1851(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1851, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1853(F, sep, ...) \ + Z_UTIL_LISTIFY_1852(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1852, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1854(F, sep, ...) \ + Z_UTIL_LISTIFY_1853(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1853, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1855(F, sep, ...) \ + Z_UTIL_LISTIFY_1854(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1854, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1856(F, sep, ...) \ + Z_UTIL_LISTIFY_1855(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1855, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1857(F, sep, ...) \ + Z_UTIL_LISTIFY_1856(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1856, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1858(F, sep, ...) \ + Z_UTIL_LISTIFY_1857(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1857, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1859(F, sep, ...) \ + Z_UTIL_LISTIFY_1858(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1858, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1860(F, sep, ...) \ + Z_UTIL_LISTIFY_1859(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1859, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1861(F, sep, ...) \ + Z_UTIL_LISTIFY_1860(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1860, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1862(F, sep, ...) \ + Z_UTIL_LISTIFY_1861(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1861, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1863(F, sep, ...) \ + Z_UTIL_LISTIFY_1862(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1862, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1864(F, sep, ...) \ + Z_UTIL_LISTIFY_1863(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1863, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1865(F, sep, ...) \ + Z_UTIL_LISTIFY_1864(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1864, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1866(F, sep, ...) \ + Z_UTIL_LISTIFY_1865(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1865, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1867(F, sep, ...) \ + Z_UTIL_LISTIFY_1866(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1866, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1868(F, sep, ...) \ + Z_UTIL_LISTIFY_1867(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1867, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1869(F, sep, ...) \ + Z_UTIL_LISTIFY_1868(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1868, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1870(F, sep, ...) \ + Z_UTIL_LISTIFY_1869(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1869, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1871(F, sep, ...) \ + Z_UTIL_LISTIFY_1870(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1870, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1872(F, sep, ...) \ + Z_UTIL_LISTIFY_1871(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1871, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1873(F, sep, ...) \ + Z_UTIL_LISTIFY_1872(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1872, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1874(F, sep, ...) \ + Z_UTIL_LISTIFY_1873(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1873, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1875(F, sep, ...) \ + Z_UTIL_LISTIFY_1874(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1874, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1876(F, sep, ...) \ + Z_UTIL_LISTIFY_1875(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1875, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1877(F, sep, ...) \ + Z_UTIL_LISTIFY_1876(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1876, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1878(F, sep, ...) \ + Z_UTIL_LISTIFY_1877(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1877, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1879(F, sep, ...) \ + Z_UTIL_LISTIFY_1878(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1878, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1880(F, sep, ...) \ + Z_UTIL_LISTIFY_1879(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1879, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1881(F, sep, ...) \ + Z_UTIL_LISTIFY_1880(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1880, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1882(F, sep, ...) \ + Z_UTIL_LISTIFY_1881(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1881, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1883(F, sep, ...) \ + Z_UTIL_LISTIFY_1882(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1882, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1884(F, sep, ...) \ + Z_UTIL_LISTIFY_1883(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1883, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1885(F, sep, ...) \ + Z_UTIL_LISTIFY_1884(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1884, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1886(F, sep, ...) \ + Z_UTIL_LISTIFY_1885(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1885, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1887(F, sep, ...) \ + Z_UTIL_LISTIFY_1886(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1886, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1888(F, sep, ...) \ + Z_UTIL_LISTIFY_1887(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1887, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1889(F, sep, ...) \ + Z_UTIL_LISTIFY_1888(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1888, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1890(F, sep, ...) \ + Z_UTIL_LISTIFY_1889(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1889, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1891(F, sep, ...) \ + Z_UTIL_LISTIFY_1890(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1890, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1892(F, sep, ...) \ + Z_UTIL_LISTIFY_1891(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1891, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1893(F, sep, ...) \ + Z_UTIL_LISTIFY_1892(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1892, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1894(F, sep, ...) \ + Z_UTIL_LISTIFY_1893(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1893, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1895(F, sep, ...) \ + Z_UTIL_LISTIFY_1894(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1894, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1896(F, sep, ...) \ + Z_UTIL_LISTIFY_1895(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1895, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1897(F, sep, ...) \ + Z_UTIL_LISTIFY_1896(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1896, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1898(F, sep, ...) \ + Z_UTIL_LISTIFY_1897(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1897, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1899(F, sep, ...) \ + Z_UTIL_LISTIFY_1898(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1898, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1900(F, sep, ...) \ + Z_UTIL_LISTIFY_1899(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1899, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1901(F, sep, ...) \ + Z_UTIL_LISTIFY_1900(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1900, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1902(F, sep, ...) \ + Z_UTIL_LISTIFY_1901(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1901, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1903(F, sep, ...) \ + Z_UTIL_LISTIFY_1902(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1902, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1904(F, sep, ...) \ + Z_UTIL_LISTIFY_1903(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1903, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1905(F, sep, ...) \ + Z_UTIL_LISTIFY_1904(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1904, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1906(F, sep, ...) \ + Z_UTIL_LISTIFY_1905(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1905, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1907(F, sep, ...) \ + Z_UTIL_LISTIFY_1906(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1906, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1908(F, sep, ...) \ + Z_UTIL_LISTIFY_1907(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1907, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1909(F, sep, ...) \ + Z_UTIL_LISTIFY_1908(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1908, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1910(F, sep, ...) \ + Z_UTIL_LISTIFY_1909(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1909, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1911(F, sep, ...) \ + Z_UTIL_LISTIFY_1910(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1910, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1912(F, sep, ...) \ + Z_UTIL_LISTIFY_1911(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1911, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1913(F, sep, ...) \ + Z_UTIL_LISTIFY_1912(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1912, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1914(F, sep, ...) \ + Z_UTIL_LISTIFY_1913(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1913, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1915(F, sep, ...) \ + Z_UTIL_LISTIFY_1914(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1914, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1916(F, sep, ...) \ + Z_UTIL_LISTIFY_1915(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1915, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1917(F, sep, ...) \ + Z_UTIL_LISTIFY_1916(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1916, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1918(F, sep, ...) \ + Z_UTIL_LISTIFY_1917(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1917, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1919(F, sep, ...) \ + Z_UTIL_LISTIFY_1918(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1918, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1920(F, sep, ...) \ + Z_UTIL_LISTIFY_1919(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1919, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1921(F, sep, ...) \ + Z_UTIL_LISTIFY_1920(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1920, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1922(F, sep, ...) \ + Z_UTIL_LISTIFY_1921(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1921, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1923(F, sep, ...) \ + Z_UTIL_LISTIFY_1922(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1922, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1924(F, sep, ...) \ + Z_UTIL_LISTIFY_1923(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1923, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1925(F, sep, ...) \ + Z_UTIL_LISTIFY_1924(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1924, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1926(F, sep, ...) \ + Z_UTIL_LISTIFY_1925(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1925, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1927(F, sep, ...) \ + Z_UTIL_LISTIFY_1926(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1926, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1928(F, sep, ...) \ + Z_UTIL_LISTIFY_1927(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1927, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1929(F, sep, ...) \ + Z_UTIL_LISTIFY_1928(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1928, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1930(F, sep, ...) \ + Z_UTIL_LISTIFY_1929(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1929, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1931(F, sep, ...) \ + Z_UTIL_LISTIFY_1930(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1930, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1932(F, sep, ...) \ + Z_UTIL_LISTIFY_1931(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1931, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1933(F, sep, ...) \ + Z_UTIL_LISTIFY_1932(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1932, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1934(F, sep, ...) \ + Z_UTIL_LISTIFY_1933(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1933, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1935(F, sep, ...) \ + Z_UTIL_LISTIFY_1934(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1934, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1936(F, sep, ...) \ + Z_UTIL_LISTIFY_1935(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1935, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1937(F, sep, ...) \ + Z_UTIL_LISTIFY_1936(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1936, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1938(F, sep, ...) \ + Z_UTIL_LISTIFY_1937(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1937, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1939(F, sep, ...) \ + Z_UTIL_LISTIFY_1938(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1938, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1940(F, sep, ...) \ + Z_UTIL_LISTIFY_1939(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1939, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1941(F, sep, ...) \ + Z_UTIL_LISTIFY_1940(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1940, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1942(F, sep, ...) \ + Z_UTIL_LISTIFY_1941(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1941, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1943(F, sep, ...) \ + Z_UTIL_LISTIFY_1942(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1942, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1944(F, sep, ...) \ + Z_UTIL_LISTIFY_1943(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1943, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1945(F, sep, ...) \ + Z_UTIL_LISTIFY_1944(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1944, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1946(F, sep, ...) \ + Z_UTIL_LISTIFY_1945(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1945, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1947(F, sep, ...) \ + Z_UTIL_LISTIFY_1946(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1946, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1948(F, sep, ...) \ + Z_UTIL_LISTIFY_1947(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1947, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1949(F, sep, ...) \ + Z_UTIL_LISTIFY_1948(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1948, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1950(F, sep, ...) \ + Z_UTIL_LISTIFY_1949(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1949, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1951(F, sep, ...) \ + Z_UTIL_LISTIFY_1950(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1950, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1952(F, sep, ...) \ + Z_UTIL_LISTIFY_1951(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1951, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1953(F, sep, ...) \ + Z_UTIL_LISTIFY_1952(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1952, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1954(F, sep, ...) \ + Z_UTIL_LISTIFY_1953(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1953, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1955(F, sep, ...) \ + Z_UTIL_LISTIFY_1954(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1954, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1956(F, sep, ...) \ + Z_UTIL_LISTIFY_1955(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1955, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1957(F, sep, ...) \ + Z_UTIL_LISTIFY_1956(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1956, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1958(F, sep, ...) \ + Z_UTIL_LISTIFY_1957(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1957, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1959(F, sep, ...) \ + Z_UTIL_LISTIFY_1958(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1958, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1960(F, sep, ...) \ + Z_UTIL_LISTIFY_1959(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1959, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1961(F, sep, ...) \ + Z_UTIL_LISTIFY_1960(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1960, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1962(F, sep, ...) \ + Z_UTIL_LISTIFY_1961(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1961, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1963(F, sep, ...) \ + Z_UTIL_LISTIFY_1962(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1962, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1964(F, sep, ...) \ + Z_UTIL_LISTIFY_1963(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1963, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1965(F, sep, ...) \ + Z_UTIL_LISTIFY_1964(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1964, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1966(F, sep, ...) \ + Z_UTIL_LISTIFY_1965(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1965, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1967(F, sep, ...) \ + Z_UTIL_LISTIFY_1966(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1966, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1968(F, sep, ...) \ + Z_UTIL_LISTIFY_1967(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1967, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1969(F, sep, ...) \ + Z_UTIL_LISTIFY_1968(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1968, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1970(F, sep, ...) \ + Z_UTIL_LISTIFY_1969(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1969, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1971(F, sep, ...) \ + Z_UTIL_LISTIFY_1970(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1970, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1972(F, sep, ...) \ + Z_UTIL_LISTIFY_1971(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1971, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1973(F, sep, ...) \ + Z_UTIL_LISTIFY_1972(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1972, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1974(F, sep, ...) \ + Z_UTIL_LISTIFY_1973(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1973, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1975(F, sep, ...) \ + Z_UTIL_LISTIFY_1974(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1974, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1976(F, sep, ...) \ + Z_UTIL_LISTIFY_1975(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1975, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1977(F, sep, ...) \ + Z_UTIL_LISTIFY_1976(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1976, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1978(F, sep, ...) \ + Z_UTIL_LISTIFY_1977(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1977, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1979(F, sep, ...) \ + Z_UTIL_LISTIFY_1978(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1978, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1980(F, sep, ...) \ + Z_UTIL_LISTIFY_1979(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1979, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1981(F, sep, ...) \ + Z_UTIL_LISTIFY_1980(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1980, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1982(F, sep, ...) \ + Z_UTIL_LISTIFY_1981(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1981, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1983(F, sep, ...) \ + Z_UTIL_LISTIFY_1982(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1982, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1984(F, sep, ...) \ + Z_UTIL_LISTIFY_1983(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1983, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1985(F, sep, ...) \ + Z_UTIL_LISTIFY_1984(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1984, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1986(F, sep, ...) \ + Z_UTIL_LISTIFY_1985(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1985, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1987(F, sep, ...) \ + Z_UTIL_LISTIFY_1986(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1986, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1988(F, sep, ...) \ + Z_UTIL_LISTIFY_1987(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1987, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1989(F, sep, ...) \ + Z_UTIL_LISTIFY_1988(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1988, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1990(F, sep, ...) \ + Z_UTIL_LISTIFY_1989(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1989, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1991(F, sep, ...) \ + Z_UTIL_LISTIFY_1990(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1990, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1992(F, sep, ...) \ + Z_UTIL_LISTIFY_1991(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1991, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1993(F, sep, ...) \ + Z_UTIL_LISTIFY_1992(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1992, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1994(F, sep, ...) \ + Z_UTIL_LISTIFY_1993(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1993, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1995(F, sep, ...) \ + Z_UTIL_LISTIFY_1994(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1994, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1996(F, sep, ...) \ + Z_UTIL_LISTIFY_1995(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1995, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1997(F, sep, ...) \ + Z_UTIL_LISTIFY_1996(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1996, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1998(F, sep, ...) \ + Z_UTIL_LISTIFY_1997(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1997, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_1999(F, sep, ...) \ + Z_UTIL_LISTIFY_1998(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1998, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2000(F, sep, ...) \ + Z_UTIL_LISTIFY_1999(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1999, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2001(F, sep, ...) \ + Z_UTIL_LISTIFY_2000(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2000, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2002(F, sep, ...) \ + Z_UTIL_LISTIFY_2001(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2001, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2003(F, sep, ...) \ + Z_UTIL_LISTIFY_2002(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2002, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2004(F, sep, ...) \ + Z_UTIL_LISTIFY_2003(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2003, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2005(F, sep, ...) \ + Z_UTIL_LISTIFY_2004(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2004, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2006(F, sep, ...) \ + Z_UTIL_LISTIFY_2005(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2005, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2007(F, sep, ...) \ + Z_UTIL_LISTIFY_2006(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2006, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2008(F, sep, ...) \ + Z_UTIL_LISTIFY_2007(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2007, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2009(F, sep, ...) \ + Z_UTIL_LISTIFY_2008(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2008, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2010(F, sep, ...) \ + Z_UTIL_LISTIFY_2009(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2009, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2011(F, sep, ...) \ + Z_UTIL_LISTIFY_2010(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2010, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2012(F, sep, ...) \ + Z_UTIL_LISTIFY_2011(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2011, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2013(F, sep, ...) \ + Z_UTIL_LISTIFY_2012(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2012, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2014(F, sep, ...) \ + Z_UTIL_LISTIFY_2013(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2013, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2015(F, sep, ...) \ + Z_UTIL_LISTIFY_2014(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2014, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2016(F, sep, ...) \ + Z_UTIL_LISTIFY_2015(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2015, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2017(F, sep, ...) \ + Z_UTIL_LISTIFY_2016(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2016, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2018(F, sep, ...) \ + Z_UTIL_LISTIFY_2017(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2017, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2019(F, sep, ...) \ + Z_UTIL_LISTIFY_2018(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2018, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2020(F, sep, ...) \ + Z_UTIL_LISTIFY_2019(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2019, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2021(F, sep, ...) \ + Z_UTIL_LISTIFY_2020(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2020, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2022(F, sep, ...) \ + Z_UTIL_LISTIFY_2021(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2021, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2023(F, sep, ...) \ + Z_UTIL_LISTIFY_2022(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2022, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2024(F, sep, ...) \ + Z_UTIL_LISTIFY_2023(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2023, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2025(F, sep, ...) \ + Z_UTIL_LISTIFY_2024(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2024, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2026(F, sep, ...) \ + Z_UTIL_LISTIFY_2025(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2025, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2027(F, sep, ...) \ + Z_UTIL_LISTIFY_2026(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2026, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2028(F, sep, ...) \ + Z_UTIL_LISTIFY_2027(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2027, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2029(F, sep, ...) \ + Z_UTIL_LISTIFY_2028(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2028, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2030(F, sep, ...) \ + Z_UTIL_LISTIFY_2029(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2029, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2031(F, sep, ...) \ + Z_UTIL_LISTIFY_2030(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2030, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2032(F, sep, ...) \ + Z_UTIL_LISTIFY_2031(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2031, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2033(F, sep, ...) \ + Z_UTIL_LISTIFY_2032(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2032, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2034(F, sep, ...) \ + Z_UTIL_LISTIFY_2033(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2033, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2035(F, sep, ...) \ + Z_UTIL_LISTIFY_2034(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2034, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2036(F, sep, ...) \ + Z_UTIL_LISTIFY_2035(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2035, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2037(F, sep, ...) \ + Z_UTIL_LISTIFY_2036(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2036, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2038(F, sep, ...) \ + Z_UTIL_LISTIFY_2037(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2037, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2039(F, sep, ...) \ + Z_UTIL_LISTIFY_2038(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2038, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2040(F, sep, ...) \ + Z_UTIL_LISTIFY_2039(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2039, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2041(F, sep, ...) \ + Z_UTIL_LISTIFY_2040(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2040, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2042(F, sep, ...) \ + Z_UTIL_LISTIFY_2041(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2041, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2043(F, sep, ...) \ + Z_UTIL_LISTIFY_2042(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2042, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2044(F, sep, ...) \ + Z_UTIL_LISTIFY_2043(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2043, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2045(F, sep, ...) \ + Z_UTIL_LISTIFY_2044(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2044, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2046(F, sep, ...) \ + Z_UTIL_LISTIFY_2045(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2045, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2047(F, sep, ...) \ + Z_UTIL_LISTIFY_2046(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2046, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2048(F, sep, ...) \ + Z_UTIL_LISTIFY_2047(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2047, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2049(F, sep, ...) \ + Z_UTIL_LISTIFY_2048(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2048, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2050(F, sep, ...) \ + Z_UTIL_LISTIFY_2049(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2049, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2051(F, sep, ...) \ + Z_UTIL_LISTIFY_2050(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2050, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2052(F, sep, ...) \ + Z_UTIL_LISTIFY_2051(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2051, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2053(F, sep, ...) \ + Z_UTIL_LISTIFY_2052(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2052, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2054(F, sep, ...) \ + Z_UTIL_LISTIFY_2053(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2053, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2055(F, sep, ...) \ + Z_UTIL_LISTIFY_2054(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2054, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2056(F, sep, ...) \ + Z_UTIL_LISTIFY_2055(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2055, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2057(F, sep, ...) \ + Z_UTIL_LISTIFY_2056(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2056, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2058(F, sep, ...) \ + Z_UTIL_LISTIFY_2057(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2057, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2059(F, sep, ...) \ + Z_UTIL_LISTIFY_2058(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2058, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2060(F, sep, ...) \ + Z_UTIL_LISTIFY_2059(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2059, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2061(F, sep, ...) \ + Z_UTIL_LISTIFY_2060(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2060, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2062(F, sep, ...) \ + Z_UTIL_LISTIFY_2061(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2061, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2063(F, sep, ...) \ + Z_UTIL_LISTIFY_2062(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2062, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2064(F, sep, ...) \ + Z_UTIL_LISTIFY_2063(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2063, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2065(F, sep, ...) \ + Z_UTIL_LISTIFY_2064(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2064, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2066(F, sep, ...) \ + Z_UTIL_LISTIFY_2065(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2065, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2067(F, sep, ...) \ + Z_UTIL_LISTIFY_2066(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2066, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2068(F, sep, ...) \ + Z_UTIL_LISTIFY_2067(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2067, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2069(F, sep, ...) \ + Z_UTIL_LISTIFY_2068(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2068, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2070(F, sep, ...) \ + Z_UTIL_LISTIFY_2069(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2069, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2071(F, sep, ...) \ + Z_UTIL_LISTIFY_2070(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2070, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2072(F, sep, ...) \ + Z_UTIL_LISTIFY_2071(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2071, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2073(F, sep, ...) \ + Z_UTIL_LISTIFY_2072(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2072, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2074(F, sep, ...) \ + Z_UTIL_LISTIFY_2073(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2073, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2075(F, sep, ...) \ + Z_UTIL_LISTIFY_2074(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2074, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2076(F, sep, ...) \ + Z_UTIL_LISTIFY_2075(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2075, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2077(F, sep, ...) \ + Z_UTIL_LISTIFY_2076(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2076, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2078(F, sep, ...) \ + Z_UTIL_LISTIFY_2077(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2077, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2079(F, sep, ...) \ + Z_UTIL_LISTIFY_2078(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2078, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2080(F, sep, ...) \ + Z_UTIL_LISTIFY_2079(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2079, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2081(F, sep, ...) \ + Z_UTIL_LISTIFY_2080(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2080, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2082(F, sep, ...) \ + Z_UTIL_LISTIFY_2081(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2081, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2083(F, sep, ...) \ + Z_UTIL_LISTIFY_2082(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2082, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2084(F, sep, ...) \ + Z_UTIL_LISTIFY_2083(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2083, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2085(F, sep, ...) \ + Z_UTIL_LISTIFY_2084(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2084, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2086(F, sep, ...) \ + Z_UTIL_LISTIFY_2085(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2085, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2087(F, sep, ...) \ + Z_UTIL_LISTIFY_2086(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2086, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2088(F, sep, ...) \ + Z_UTIL_LISTIFY_2087(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2087, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2089(F, sep, ...) \ + Z_UTIL_LISTIFY_2088(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2088, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2090(F, sep, ...) \ + Z_UTIL_LISTIFY_2089(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2089, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2091(F, sep, ...) \ + Z_UTIL_LISTIFY_2090(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2090, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2092(F, sep, ...) \ + Z_UTIL_LISTIFY_2091(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2091, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2093(F, sep, ...) \ + Z_UTIL_LISTIFY_2092(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2092, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2094(F, sep, ...) \ + Z_UTIL_LISTIFY_2093(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2093, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2095(F, sep, ...) \ + Z_UTIL_LISTIFY_2094(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2094, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2096(F, sep, ...) \ + Z_UTIL_LISTIFY_2095(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2095, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2097(F, sep, ...) \ + Z_UTIL_LISTIFY_2096(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2096, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2098(F, sep, ...) \ + Z_UTIL_LISTIFY_2097(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2097, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2099(F, sep, ...) \ + Z_UTIL_LISTIFY_2098(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2098, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2100(F, sep, ...) \ + Z_UTIL_LISTIFY_2099(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2099, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2101(F, sep, ...) \ + Z_UTIL_LISTIFY_2100(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2100, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2102(F, sep, ...) \ + Z_UTIL_LISTIFY_2101(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2101, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2103(F, sep, ...) \ + Z_UTIL_LISTIFY_2102(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2102, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2104(F, sep, ...) \ + Z_UTIL_LISTIFY_2103(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2103, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2105(F, sep, ...) \ + Z_UTIL_LISTIFY_2104(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2104, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2106(F, sep, ...) \ + Z_UTIL_LISTIFY_2105(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2105, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2107(F, sep, ...) \ + Z_UTIL_LISTIFY_2106(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2106, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2108(F, sep, ...) \ + Z_UTIL_LISTIFY_2107(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2107, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2109(F, sep, ...) \ + Z_UTIL_LISTIFY_2108(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2108, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2110(F, sep, ...) \ + Z_UTIL_LISTIFY_2109(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2109, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2111(F, sep, ...) \ + Z_UTIL_LISTIFY_2110(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2110, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2112(F, sep, ...) \ + Z_UTIL_LISTIFY_2111(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2111, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2113(F, sep, ...) \ + Z_UTIL_LISTIFY_2112(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2112, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2114(F, sep, ...) \ + Z_UTIL_LISTIFY_2113(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2113, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2115(F, sep, ...) \ + Z_UTIL_LISTIFY_2114(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2114, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2116(F, sep, ...) \ + Z_UTIL_LISTIFY_2115(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2115, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2117(F, sep, ...) \ + Z_UTIL_LISTIFY_2116(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2116, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2118(F, sep, ...) \ + Z_UTIL_LISTIFY_2117(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2117, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2119(F, sep, ...) \ + Z_UTIL_LISTIFY_2118(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2118, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2120(F, sep, ...) \ + Z_UTIL_LISTIFY_2119(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2119, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2121(F, sep, ...) \ + Z_UTIL_LISTIFY_2120(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2120, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2122(F, sep, ...) \ + Z_UTIL_LISTIFY_2121(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2121, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2123(F, sep, ...) \ + Z_UTIL_LISTIFY_2122(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2122, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2124(F, sep, ...) \ + Z_UTIL_LISTIFY_2123(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2123, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2125(F, sep, ...) \ + Z_UTIL_LISTIFY_2124(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2124, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2126(F, sep, ...) \ + Z_UTIL_LISTIFY_2125(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2125, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2127(F, sep, ...) \ + Z_UTIL_LISTIFY_2126(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2126, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2128(F, sep, ...) \ + Z_UTIL_LISTIFY_2127(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2127, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2129(F, sep, ...) \ + Z_UTIL_LISTIFY_2128(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2128, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2130(F, sep, ...) \ + Z_UTIL_LISTIFY_2129(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2129, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2131(F, sep, ...) \ + Z_UTIL_LISTIFY_2130(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2130, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2132(F, sep, ...) \ + Z_UTIL_LISTIFY_2131(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2131, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2133(F, sep, ...) \ + Z_UTIL_LISTIFY_2132(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2132, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2134(F, sep, ...) \ + Z_UTIL_LISTIFY_2133(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2133, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2135(F, sep, ...) \ + Z_UTIL_LISTIFY_2134(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2134, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2136(F, sep, ...) \ + Z_UTIL_LISTIFY_2135(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2135, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2137(F, sep, ...) \ + Z_UTIL_LISTIFY_2136(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2136, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2138(F, sep, ...) \ + Z_UTIL_LISTIFY_2137(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2137, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2139(F, sep, ...) \ + Z_UTIL_LISTIFY_2138(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2138, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2140(F, sep, ...) \ + Z_UTIL_LISTIFY_2139(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2139, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2141(F, sep, ...) \ + Z_UTIL_LISTIFY_2140(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2140, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2142(F, sep, ...) \ + Z_UTIL_LISTIFY_2141(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2141, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2143(F, sep, ...) \ + Z_UTIL_LISTIFY_2142(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2142, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2144(F, sep, ...) \ + Z_UTIL_LISTIFY_2143(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2143, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2145(F, sep, ...) \ + Z_UTIL_LISTIFY_2144(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2144, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2146(F, sep, ...) \ + Z_UTIL_LISTIFY_2145(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2145, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2147(F, sep, ...) \ + Z_UTIL_LISTIFY_2146(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2146, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2148(F, sep, ...) \ + Z_UTIL_LISTIFY_2147(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2147, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2149(F, sep, ...) \ + Z_UTIL_LISTIFY_2148(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2148, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2150(F, sep, ...) \ + Z_UTIL_LISTIFY_2149(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2149, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2151(F, sep, ...) \ + Z_UTIL_LISTIFY_2150(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2150, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2152(F, sep, ...) \ + Z_UTIL_LISTIFY_2151(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2151, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2153(F, sep, ...) \ + Z_UTIL_LISTIFY_2152(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2152, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2154(F, sep, ...) \ + Z_UTIL_LISTIFY_2153(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2153, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2155(F, sep, ...) \ + Z_UTIL_LISTIFY_2154(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2154, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2156(F, sep, ...) \ + Z_UTIL_LISTIFY_2155(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2155, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2157(F, sep, ...) \ + Z_UTIL_LISTIFY_2156(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2156, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2158(F, sep, ...) \ + Z_UTIL_LISTIFY_2157(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2157, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2159(F, sep, ...) \ + Z_UTIL_LISTIFY_2158(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2158, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2160(F, sep, ...) \ + Z_UTIL_LISTIFY_2159(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2159, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2161(F, sep, ...) \ + Z_UTIL_LISTIFY_2160(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2160, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2162(F, sep, ...) \ + Z_UTIL_LISTIFY_2161(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2161, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2163(F, sep, ...) \ + Z_UTIL_LISTIFY_2162(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2162, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2164(F, sep, ...) \ + Z_UTIL_LISTIFY_2163(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2163, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2165(F, sep, ...) \ + Z_UTIL_LISTIFY_2164(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2164, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2166(F, sep, ...) \ + Z_UTIL_LISTIFY_2165(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2165, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2167(F, sep, ...) \ + Z_UTIL_LISTIFY_2166(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2166, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2168(F, sep, ...) \ + Z_UTIL_LISTIFY_2167(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2167, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2169(F, sep, ...) \ + Z_UTIL_LISTIFY_2168(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2168, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2170(F, sep, ...) \ + Z_UTIL_LISTIFY_2169(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2169, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2171(F, sep, ...) \ + Z_UTIL_LISTIFY_2170(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2170, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2172(F, sep, ...) \ + Z_UTIL_LISTIFY_2171(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2171, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2173(F, sep, ...) \ + Z_UTIL_LISTIFY_2172(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2172, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2174(F, sep, ...) \ + Z_UTIL_LISTIFY_2173(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2173, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2175(F, sep, ...) \ + Z_UTIL_LISTIFY_2174(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2174, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2176(F, sep, ...) \ + Z_UTIL_LISTIFY_2175(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2175, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2177(F, sep, ...) \ + Z_UTIL_LISTIFY_2176(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2176, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2178(F, sep, ...) \ + Z_UTIL_LISTIFY_2177(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2177, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2179(F, sep, ...) \ + Z_UTIL_LISTIFY_2178(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2178, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2180(F, sep, ...) \ + Z_UTIL_LISTIFY_2179(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2179, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2181(F, sep, ...) \ + Z_UTIL_LISTIFY_2180(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2180, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2182(F, sep, ...) \ + Z_UTIL_LISTIFY_2181(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2181, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2183(F, sep, ...) \ + Z_UTIL_LISTIFY_2182(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2182, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2184(F, sep, ...) \ + Z_UTIL_LISTIFY_2183(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2183, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2185(F, sep, ...) \ + Z_UTIL_LISTIFY_2184(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2184, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2186(F, sep, ...) \ + Z_UTIL_LISTIFY_2185(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2185, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2187(F, sep, ...) \ + Z_UTIL_LISTIFY_2186(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2186, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2188(F, sep, ...) \ + Z_UTIL_LISTIFY_2187(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2187, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2189(F, sep, ...) \ + Z_UTIL_LISTIFY_2188(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2188, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2190(F, sep, ...) \ + Z_UTIL_LISTIFY_2189(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2189, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2191(F, sep, ...) \ + Z_UTIL_LISTIFY_2190(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2190, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2192(F, sep, ...) \ + Z_UTIL_LISTIFY_2191(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2191, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2193(F, sep, ...) \ + Z_UTIL_LISTIFY_2192(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2192, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2194(F, sep, ...) \ + Z_UTIL_LISTIFY_2193(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2193, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2195(F, sep, ...) \ + Z_UTIL_LISTIFY_2194(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2194, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2196(F, sep, ...) \ + Z_UTIL_LISTIFY_2195(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2195, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2197(F, sep, ...) \ + Z_UTIL_LISTIFY_2196(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2196, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2198(F, sep, ...) \ + Z_UTIL_LISTIFY_2197(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2197, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2199(F, sep, ...) \ + Z_UTIL_LISTIFY_2198(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2198, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2200(F, sep, ...) \ + Z_UTIL_LISTIFY_2199(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2199, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2201(F, sep, ...) \ + Z_UTIL_LISTIFY_2200(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2200, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2202(F, sep, ...) \ + Z_UTIL_LISTIFY_2201(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2201, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2203(F, sep, ...) \ + Z_UTIL_LISTIFY_2202(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2202, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2204(F, sep, ...) \ + Z_UTIL_LISTIFY_2203(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2203, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2205(F, sep, ...) \ + Z_UTIL_LISTIFY_2204(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2204, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2206(F, sep, ...) \ + Z_UTIL_LISTIFY_2205(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2205, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2207(F, sep, ...) \ + Z_UTIL_LISTIFY_2206(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2206, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2208(F, sep, ...) \ + Z_UTIL_LISTIFY_2207(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2207, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2209(F, sep, ...) \ + Z_UTIL_LISTIFY_2208(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2208, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2210(F, sep, ...) \ + Z_UTIL_LISTIFY_2209(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2209, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2211(F, sep, ...) \ + Z_UTIL_LISTIFY_2210(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2210, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2212(F, sep, ...) \ + Z_UTIL_LISTIFY_2211(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2211, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2213(F, sep, ...) \ + Z_UTIL_LISTIFY_2212(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2212, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2214(F, sep, ...) \ + Z_UTIL_LISTIFY_2213(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2213, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2215(F, sep, ...) \ + Z_UTIL_LISTIFY_2214(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2214, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2216(F, sep, ...) \ + Z_UTIL_LISTIFY_2215(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2215, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2217(F, sep, ...) \ + Z_UTIL_LISTIFY_2216(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2216, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2218(F, sep, ...) \ + Z_UTIL_LISTIFY_2217(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2217, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2219(F, sep, ...) \ + Z_UTIL_LISTIFY_2218(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2218, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2220(F, sep, ...) \ + Z_UTIL_LISTIFY_2219(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2219, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2221(F, sep, ...) \ + Z_UTIL_LISTIFY_2220(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2220, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2222(F, sep, ...) \ + Z_UTIL_LISTIFY_2221(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2221, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2223(F, sep, ...) \ + Z_UTIL_LISTIFY_2222(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2222, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2224(F, sep, ...) \ + Z_UTIL_LISTIFY_2223(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2223, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2225(F, sep, ...) \ + Z_UTIL_LISTIFY_2224(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2224, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2226(F, sep, ...) \ + Z_UTIL_LISTIFY_2225(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2225, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2227(F, sep, ...) \ + Z_UTIL_LISTIFY_2226(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2226, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2228(F, sep, ...) \ + Z_UTIL_LISTIFY_2227(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2227, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2229(F, sep, ...) \ + Z_UTIL_LISTIFY_2228(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2228, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2230(F, sep, ...) \ + Z_UTIL_LISTIFY_2229(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2229, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2231(F, sep, ...) \ + Z_UTIL_LISTIFY_2230(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2230, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2232(F, sep, ...) \ + Z_UTIL_LISTIFY_2231(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2231, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2233(F, sep, ...) \ + Z_UTIL_LISTIFY_2232(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2232, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2234(F, sep, ...) \ + Z_UTIL_LISTIFY_2233(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2233, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2235(F, sep, ...) \ + Z_UTIL_LISTIFY_2234(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2234, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2236(F, sep, ...) \ + Z_UTIL_LISTIFY_2235(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2235, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2237(F, sep, ...) \ + Z_UTIL_LISTIFY_2236(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2236, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2238(F, sep, ...) \ + Z_UTIL_LISTIFY_2237(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2237, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2239(F, sep, ...) \ + Z_UTIL_LISTIFY_2238(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2238, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2240(F, sep, ...) \ + Z_UTIL_LISTIFY_2239(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2239, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2241(F, sep, ...) \ + Z_UTIL_LISTIFY_2240(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2240, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2242(F, sep, ...) \ + Z_UTIL_LISTIFY_2241(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2241, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2243(F, sep, ...) \ + Z_UTIL_LISTIFY_2242(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2242, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2244(F, sep, ...) \ + Z_UTIL_LISTIFY_2243(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2243, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2245(F, sep, ...) \ + Z_UTIL_LISTIFY_2244(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2244, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2246(F, sep, ...) \ + Z_UTIL_LISTIFY_2245(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2245, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2247(F, sep, ...) \ + Z_UTIL_LISTIFY_2246(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2246, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2248(F, sep, ...) \ + Z_UTIL_LISTIFY_2247(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2247, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2249(F, sep, ...) \ + Z_UTIL_LISTIFY_2248(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2248, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2250(F, sep, ...) \ + Z_UTIL_LISTIFY_2249(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2249, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2251(F, sep, ...) \ + Z_UTIL_LISTIFY_2250(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2250, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2252(F, sep, ...) \ + Z_UTIL_LISTIFY_2251(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2251, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2253(F, sep, ...) \ + Z_UTIL_LISTIFY_2252(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2252, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2254(F, sep, ...) \ + Z_UTIL_LISTIFY_2253(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2253, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2255(F, sep, ...) \ + Z_UTIL_LISTIFY_2254(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2254, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2256(F, sep, ...) \ + Z_UTIL_LISTIFY_2255(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2255, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2257(F, sep, ...) \ + Z_UTIL_LISTIFY_2256(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2256, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2258(F, sep, ...) \ + Z_UTIL_LISTIFY_2257(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2257, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2259(F, sep, ...) \ + Z_UTIL_LISTIFY_2258(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2258, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2260(F, sep, ...) \ + Z_UTIL_LISTIFY_2259(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2259, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2261(F, sep, ...) \ + Z_UTIL_LISTIFY_2260(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2260, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2262(F, sep, ...) \ + Z_UTIL_LISTIFY_2261(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2261, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2263(F, sep, ...) \ + Z_UTIL_LISTIFY_2262(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2262, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2264(F, sep, ...) \ + Z_UTIL_LISTIFY_2263(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2263, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2265(F, sep, ...) \ + Z_UTIL_LISTIFY_2264(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2264, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2266(F, sep, ...) \ + Z_UTIL_LISTIFY_2265(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2265, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2267(F, sep, ...) \ + Z_UTIL_LISTIFY_2266(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2266, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2268(F, sep, ...) \ + Z_UTIL_LISTIFY_2267(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2267, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2269(F, sep, ...) \ + Z_UTIL_LISTIFY_2268(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2268, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2270(F, sep, ...) \ + Z_UTIL_LISTIFY_2269(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2269, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2271(F, sep, ...) \ + Z_UTIL_LISTIFY_2270(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2270, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2272(F, sep, ...) \ + Z_UTIL_LISTIFY_2271(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2271, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2273(F, sep, ...) \ + Z_UTIL_LISTIFY_2272(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2272, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2274(F, sep, ...) \ + Z_UTIL_LISTIFY_2273(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2273, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2275(F, sep, ...) \ + Z_UTIL_LISTIFY_2274(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2274, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2276(F, sep, ...) \ + Z_UTIL_LISTIFY_2275(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2275, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2277(F, sep, ...) \ + Z_UTIL_LISTIFY_2276(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2276, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2278(F, sep, ...) \ + Z_UTIL_LISTIFY_2277(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2277, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2279(F, sep, ...) \ + Z_UTIL_LISTIFY_2278(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2278, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2280(F, sep, ...) \ + Z_UTIL_LISTIFY_2279(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2279, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2281(F, sep, ...) \ + Z_UTIL_LISTIFY_2280(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2280, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2282(F, sep, ...) \ + Z_UTIL_LISTIFY_2281(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2281, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2283(F, sep, ...) \ + Z_UTIL_LISTIFY_2282(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2282, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2284(F, sep, ...) \ + Z_UTIL_LISTIFY_2283(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2283, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2285(F, sep, ...) \ + Z_UTIL_LISTIFY_2284(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2284, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2286(F, sep, ...) \ + Z_UTIL_LISTIFY_2285(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2285, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2287(F, sep, ...) \ + Z_UTIL_LISTIFY_2286(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2286, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2288(F, sep, ...) \ + Z_UTIL_LISTIFY_2287(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2287, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2289(F, sep, ...) \ + Z_UTIL_LISTIFY_2288(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2288, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2290(F, sep, ...) \ + Z_UTIL_LISTIFY_2289(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2289, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2291(F, sep, ...) \ + Z_UTIL_LISTIFY_2290(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2290, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2292(F, sep, ...) \ + Z_UTIL_LISTIFY_2291(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2291, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2293(F, sep, ...) \ + Z_UTIL_LISTIFY_2292(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2292, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2294(F, sep, ...) \ + Z_UTIL_LISTIFY_2293(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2293, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2295(F, sep, ...) \ + Z_UTIL_LISTIFY_2294(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2294, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2296(F, sep, ...) \ + Z_UTIL_LISTIFY_2295(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2295, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2297(F, sep, ...) \ + Z_UTIL_LISTIFY_2296(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2296, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2298(F, sep, ...) \ + Z_UTIL_LISTIFY_2297(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2297, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2299(F, sep, ...) \ + Z_UTIL_LISTIFY_2298(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2298, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2300(F, sep, ...) \ + Z_UTIL_LISTIFY_2299(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2299, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2301(F, sep, ...) \ + Z_UTIL_LISTIFY_2300(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2300, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2302(F, sep, ...) \ + Z_UTIL_LISTIFY_2301(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2301, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2303(F, sep, ...) \ + Z_UTIL_LISTIFY_2302(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2302, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2304(F, sep, ...) \ + Z_UTIL_LISTIFY_2303(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2303, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2305(F, sep, ...) \ + Z_UTIL_LISTIFY_2304(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2304, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2306(F, sep, ...) \ + Z_UTIL_LISTIFY_2305(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2305, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2307(F, sep, ...) \ + Z_UTIL_LISTIFY_2306(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2306, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2308(F, sep, ...) \ + Z_UTIL_LISTIFY_2307(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2307, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2309(F, sep, ...) \ + Z_UTIL_LISTIFY_2308(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2308, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2310(F, sep, ...) \ + Z_UTIL_LISTIFY_2309(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2309, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2311(F, sep, ...) \ + Z_UTIL_LISTIFY_2310(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2310, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2312(F, sep, ...) \ + Z_UTIL_LISTIFY_2311(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2311, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2313(F, sep, ...) \ + Z_UTIL_LISTIFY_2312(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2312, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2314(F, sep, ...) \ + Z_UTIL_LISTIFY_2313(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2313, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2315(F, sep, ...) \ + Z_UTIL_LISTIFY_2314(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2314, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2316(F, sep, ...) \ + Z_UTIL_LISTIFY_2315(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2315, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2317(F, sep, ...) \ + Z_UTIL_LISTIFY_2316(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2316, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2318(F, sep, ...) \ + Z_UTIL_LISTIFY_2317(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2317, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2319(F, sep, ...) \ + Z_UTIL_LISTIFY_2318(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2318, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2320(F, sep, ...) \ + Z_UTIL_LISTIFY_2319(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2319, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2321(F, sep, ...) \ + Z_UTIL_LISTIFY_2320(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2320, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2322(F, sep, ...) \ + Z_UTIL_LISTIFY_2321(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2321, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2323(F, sep, ...) \ + Z_UTIL_LISTIFY_2322(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2322, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2324(F, sep, ...) \ + Z_UTIL_LISTIFY_2323(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2323, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2325(F, sep, ...) \ + Z_UTIL_LISTIFY_2324(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2324, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2326(F, sep, ...) \ + Z_UTIL_LISTIFY_2325(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2325, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2327(F, sep, ...) \ + Z_UTIL_LISTIFY_2326(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2326, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2328(F, sep, ...) \ + Z_UTIL_LISTIFY_2327(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2327, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2329(F, sep, ...) \ + Z_UTIL_LISTIFY_2328(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2328, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2330(F, sep, ...) \ + Z_UTIL_LISTIFY_2329(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2329, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2331(F, sep, ...) \ + Z_UTIL_LISTIFY_2330(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2330, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2332(F, sep, ...) \ + Z_UTIL_LISTIFY_2331(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2331, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2333(F, sep, ...) \ + Z_UTIL_LISTIFY_2332(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2332, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2334(F, sep, ...) \ + Z_UTIL_LISTIFY_2333(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2333, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2335(F, sep, ...) \ + Z_UTIL_LISTIFY_2334(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2334, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2336(F, sep, ...) \ + Z_UTIL_LISTIFY_2335(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2335, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2337(F, sep, ...) \ + Z_UTIL_LISTIFY_2336(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2336, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2338(F, sep, ...) \ + Z_UTIL_LISTIFY_2337(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2337, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2339(F, sep, ...) \ + Z_UTIL_LISTIFY_2338(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2338, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2340(F, sep, ...) \ + Z_UTIL_LISTIFY_2339(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2339, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2341(F, sep, ...) \ + Z_UTIL_LISTIFY_2340(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2340, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2342(F, sep, ...) \ + Z_UTIL_LISTIFY_2341(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2341, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2343(F, sep, ...) \ + Z_UTIL_LISTIFY_2342(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2342, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2344(F, sep, ...) \ + Z_UTIL_LISTIFY_2343(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2343, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2345(F, sep, ...) \ + Z_UTIL_LISTIFY_2344(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2344, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2346(F, sep, ...) \ + Z_UTIL_LISTIFY_2345(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2345, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2347(F, sep, ...) \ + Z_UTIL_LISTIFY_2346(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2346, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2348(F, sep, ...) \ + Z_UTIL_LISTIFY_2347(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2347, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2349(F, sep, ...) \ + Z_UTIL_LISTIFY_2348(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2348, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2350(F, sep, ...) \ + Z_UTIL_LISTIFY_2349(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2349, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2351(F, sep, ...) \ + Z_UTIL_LISTIFY_2350(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2350, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2352(F, sep, ...) \ + Z_UTIL_LISTIFY_2351(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2351, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2353(F, sep, ...) \ + Z_UTIL_LISTIFY_2352(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2352, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2354(F, sep, ...) \ + Z_UTIL_LISTIFY_2353(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2353, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2355(F, sep, ...) \ + Z_UTIL_LISTIFY_2354(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2354, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2356(F, sep, ...) \ + Z_UTIL_LISTIFY_2355(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2355, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2357(F, sep, ...) \ + Z_UTIL_LISTIFY_2356(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2356, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2358(F, sep, ...) \ + Z_UTIL_LISTIFY_2357(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2357, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2359(F, sep, ...) \ + Z_UTIL_LISTIFY_2358(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2358, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2360(F, sep, ...) \ + Z_UTIL_LISTIFY_2359(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2359, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2361(F, sep, ...) \ + Z_UTIL_LISTIFY_2360(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2360, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2362(F, sep, ...) \ + Z_UTIL_LISTIFY_2361(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2361, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2363(F, sep, ...) \ + Z_UTIL_LISTIFY_2362(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2362, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2364(F, sep, ...) \ + Z_UTIL_LISTIFY_2363(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2363, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2365(F, sep, ...) \ + Z_UTIL_LISTIFY_2364(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2364, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2366(F, sep, ...) \ + Z_UTIL_LISTIFY_2365(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2365, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2367(F, sep, ...) \ + Z_UTIL_LISTIFY_2366(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2366, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2368(F, sep, ...) \ + Z_UTIL_LISTIFY_2367(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2367, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2369(F, sep, ...) \ + Z_UTIL_LISTIFY_2368(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2368, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2370(F, sep, ...) \ + Z_UTIL_LISTIFY_2369(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2369, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2371(F, sep, ...) \ + Z_UTIL_LISTIFY_2370(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2370, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2372(F, sep, ...) \ + Z_UTIL_LISTIFY_2371(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2371, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2373(F, sep, ...) \ + Z_UTIL_LISTIFY_2372(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2372, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2374(F, sep, ...) \ + Z_UTIL_LISTIFY_2373(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2373, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2375(F, sep, ...) \ + Z_UTIL_LISTIFY_2374(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2374, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2376(F, sep, ...) \ + Z_UTIL_LISTIFY_2375(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2375, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2377(F, sep, ...) \ + Z_UTIL_LISTIFY_2376(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2376, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2378(F, sep, ...) \ + Z_UTIL_LISTIFY_2377(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2377, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2379(F, sep, ...) \ + Z_UTIL_LISTIFY_2378(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2378, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2380(F, sep, ...) \ + Z_UTIL_LISTIFY_2379(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2379, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2381(F, sep, ...) \ + Z_UTIL_LISTIFY_2380(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2380, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2382(F, sep, ...) \ + Z_UTIL_LISTIFY_2381(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2381, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2383(F, sep, ...) \ + Z_UTIL_LISTIFY_2382(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2382, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2384(F, sep, ...) \ + Z_UTIL_LISTIFY_2383(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2383, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2385(F, sep, ...) \ + Z_UTIL_LISTIFY_2384(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2384, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2386(F, sep, ...) \ + Z_UTIL_LISTIFY_2385(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2385, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2387(F, sep, ...) \ + Z_UTIL_LISTIFY_2386(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2386, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2388(F, sep, ...) \ + Z_UTIL_LISTIFY_2387(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2387, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2389(F, sep, ...) \ + Z_UTIL_LISTIFY_2388(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2388, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2390(F, sep, ...) \ + Z_UTIL_LISTIFY_2389(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2389, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2391(F, sep, ...) \ + Z_UTIL_LISTIFY_2390(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2390, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2392(F, sep, ...) \ + Z_UTIL_LISTIFY_2391(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2391, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2393(F, sep, ...) \ + Z_UTIL_LISTIFY_2392(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2392, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2394(F, sep, ...) \ + Z_UTIL_LISTIFY_2393(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2393, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2395(F, sep, ...) \ + Z_UTIL_LISTIFY_2394(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2394, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2396(F, sep, ...) \ + Z_UTIL_LISTIFY_2395(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2395, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2397(F, sep, ...) \ + Z_UTIL_LISTIFY_2396(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2396, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2398(F, sep, ...) \ + Z_UTIL_LISTIFY_2397(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2397, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2399(F, sep, ...) \ + Z_UTIL_LISTIFY_2398(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2398, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2400(F, sep, ...) \ + Z_UTIL_LISTIFY_2399(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2399, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2401(F, sep, ...) \ + Z_UTIL_LISTIFY_2400(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2400, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2402(F, sep, ...) \ + Z_UTIL_LISTIFY_2401(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2401, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2403(F, sep, ...) \ + Z_UTIL_LISTIFY_2402(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2402, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2404(F, sep, ...) \ + Z_UTIL_LISTIFY_2403(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2403, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2405(F, sep, ...) \ + Z_UTIL_LISTIFY_2404(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2404, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2406(F, sep, ...) \ + Z_UTIL_LISTIFY_2405(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2405, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2407(F, sep, ...) \ + Z_UTIL_LISTIFY_2406(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2406, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2408(F, sep, ...) \ + Z_UTIL_LISTIFY_2407(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2407, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2409(F, sep, ...) \ + Z_UTIL_LISTIFY_2408(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2408, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2410(F, sep, ...) \ + Z_UTIL_LISTIFY_2409(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2409, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2411(F, sep, ...) \ + Z_UTIL_LISTIFY_2410(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2410, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2412(F, sep, ...) \ + Z_UTIL_LISTIFY_2411(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2411, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2413(F, sep, ...) \ + Z_UTIL_LISTIFY_2412(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2412, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2414(F, sep, ...) \ + Z_UTIL_LISTIFY_2413(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2413, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2415(F, sep, ...) \ + Z_UTIL_LISTIFY_2414(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2414, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2416(F, sep, ...) \ + Z_UTIL_LISTIFY_2415(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2415, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2417(F, sep, ...) \ + Z_UTIL_LISTIFY_2416(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2416, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2418(F, sep, ...) \ + Z_UTIL_LISTIFY_2417(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2417, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2419(F, sep, ...) \ + Z_UTIL_LISTIFY_2418(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2418, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2420(F, sep, ...) \ + Z_UTIL_LISTIFY_2419(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2419, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2421(F, sep, ...) \ + Z_UTIL_LISTIFY_2420(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2420, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2422(F, sep, ...) \ + Z_UTIL_LISTIFY_2421(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2421, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2423(F, sep, ...) \ + Z_UTIL_LISTIFY_2422(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2422, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2424(F, sep, ...) \ + Z_UTIL_LISTIFY_2423(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2423, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2425(F, sep, ...) \ + Z_UTIL_LISTIFY_2424(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2424, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2426(F, sep, ...) \ + Z_UTIL_LISTIFY_2425(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2425, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2427(F, sep, ...) \ + Z_UTIL_LISTIFY_2426(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2426, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2428(F, sep, ...) \ + Z_UTIL_LISTIFY_2427(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2427, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2429(F, sep, ...) \ + Z_UTIL_LISTIFY_2428(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2428, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2430(F, sep, ...) \ + Z_UTIL_LISTIFY_2429(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2429, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2431(F, sep, ...) \ + Z_UTIL_LISTIFY_2430(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2430, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2432(F, sep, ...) \ + Z_UTIL_LISTIFY_2431(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2431, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2433(F, sep, ...) \ + Z_UTIL_LISTIFY_2432(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2432, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2434(F, sep, ...) \ + Z_UTIL_LISTIFY_2433(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2433, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2435(F, sep, ...) \ + Z_UTIL_LISTIFY_2434(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2434, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2436(F, sep, ...) \ + Z_UTIL_LISTIFY_2435(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2435, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2437(F, sep, ...) \ + Z_UTIL_LISTIFY_2436(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2436, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2438(F, sep, ...) \ + Z_UTIL_LISTIFY_2437(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2437, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2439(F, sep, ...) \ + Z_UTIL_LISTIFY_2438(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2438, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2440(F, sep, ...) \ + Z_UTIL_LISTIFY_2439(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2439, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2441(F, sep, ...) \ + Z_UTIL_LISTIFY_2440(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2440, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2442(F, sep, ...) \ + Z_UTIL_LISTIFY_2441(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2441, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2443(F, sep, ...) \ + Z_UTIL_LISTIFY_2442(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2442, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2444(F, sep, ...) \ + Z_UTIL_LISTIFY_2443(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2443, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2445(F, sep, ...) \ + Z_UTIL_LISTIFY_2444(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2444, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2446(F, sep, ...) \ + Z_UTIL_LISTIFY_2445(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2445, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2447(F, sep, ...) \ + Z_UTIL_LISTIFY_2446(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2446, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2448(F, sep, ...) \ + Z_UTIL_LISTIFY_2447(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2447, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2449(F, sep, ...) \ + Z_UTIL_LISTIFY_2448(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2448, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2450(F, sep, ...) \ + Z_UTIL_LISTIFY_2449(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2449, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2451(F, sep, ...) \ + Z_UTIL_LISTIFY_2450(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2450, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2452(F, sep, ...) \ + Z_UTIL_LISTIFY_2451(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2451, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2453(F, sep, ...) \ + Z_UTIL_LISTIFY_2452(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2452, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2454(F, sep, ...) \ + Z_UTIL_LISTIFY_2453(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2453, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2455(F, sep, ...) \ + Z_UTIL_LISTIFY_2454(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2454, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2456(F, sep, ...) \ + Z_UTIL_LISTIFY_2455(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2455, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2457(F, sep, ...) \ + Z_UTIL_LISTIFY_2456(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2456, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2458(F, sep, ...) \ + Z_UTIL_LISTIFY_2457(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2457, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2459(F, sep, ...) \ + Z_UTIL_LISTIFY_2458(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2458, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2460(F, sep, ...) \ + Z_UTIL_LISTIFY_2459(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2459, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2461(F, sep, ...) \ + Z_UTIL_LISTIFY_2460(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2460, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2462(F, sep, ...) \ + Z_UTIL_LISTIFY_2461(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2461, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2463(F, sep, ...) \ + Z_UTIL_LISTIFY_2462(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2462, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2464(F, sep, ...) \ + Z_UTIL_LISTIFY_2463(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2463, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2465(F, sep, ...) \ + Z_UTIL_LISTIFY_2464(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2464, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2466(F, sep, ...) \ + Z_UTIL_LISTIFY_2465(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2465, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2467(F, sep, ...) \ + Z_UTIL_LISTIFY_2466(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2466, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2468(F, sep, ...) \ + Z_UTIL_LISTIFY_2467(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2467, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2469(F, sep, ...) \ + Z_UTIL_LISTIFY_2468(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2468, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2470(F, sep, ...) \ + Z_UTIL_LISTIFY_2469(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2469, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2471(F, sep, ...) \ + Z_UTIL_LISTIFY_2470(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2470, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2472(F, sep, ...) \ + Z_UTIL_LISTIFY_2471(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2471, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2473(F, sep, ...) \ + Z_UTIL_LISTIFY_2472(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2472, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2474(F, sep, ...) \ + Z_UTIL_LISTIFY_2473(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2473, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2475(F, sep, ...) \ + Z_UTIL_LISTIFY_2474(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2474, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2476(F, sep, ...) \ + Z_UTIL_LISTIFY_2475(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2475, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2477(F, sep, ...) \ + Z_UTIL_LISTIFY_2476(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2476, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2478(F, sep, ...) \ + Z_UTIL_LISTIFY_2477(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2477, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2479(F, sep, ...) \ + Z_UTIL_LISTIFY_2478(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2478, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2480(F, sep, ...) \ + Z_UTIL_LISTIFY_2479(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2479, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2481(F, sep, ...) \ + Z_UTIL_LISTIFY_2480(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2480, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2482(F, sep, ...) \ + Z_UTIL_LISTIFY_2481(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2481, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2483(F, sep, ...) \ + Z_UTIL_LISTIFY_2482(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2482, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2484(F, sep, ...) \ + Z_UTIL_LISTIFY_2483(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2483, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2485(F, sep, ...) \ + Z_UTIL_LISTIFY_2484(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2484, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2486(F, sep, ...) \ + Z_UTIL_LISTIFY_2485(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2485, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2487(F, sep, ...) \ + Z_UTIL_LISTIFY_2486(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2486, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2488(F, sep, ...) \ + Z_UTIL_LISTIFY_2487(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2487, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2489(F, sep, ...) \ + Z_UTIL_LISTIFY_2488(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2488, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2490(F, sep, ...) \ + Z_UTIL_LISTIFY_2489(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2489, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2491(F, sep, ...) \ + Z_UTIL_LISTIFY_2490(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2490, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2492(F, sep, ...) \ + Z_UTIL_LISTIFY_2491(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2491, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2493(F, sep, ...) \ + Z_UTIL_LISTIFY_2492(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2492, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2494(F, sep, ...) \ + Z_UTIL_LISTIFY_2493(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2493, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2495(F, sep, ...) \ + Z_UTIL_LISTIFY_2494(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2494, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2496(F, sep, ...) \ + Z_UTIL_LISTIFY_2495(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2495, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2497(F, sep, ...) \ + Z_UTIL_LISTIFY_2496(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2496, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2498(F, sep, ...) \ + Z_UTIL_LISTIFY_2497(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2497, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2499(F, sep, ...) \ + Z_UTIL_LISTIFY_2498(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2498, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2500(F, sep, ...) \ + Z_UTIL_LISTIFY_2499(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2499, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2501(F, sep, ...) \ + Z_UTIL_LISTIFY_2500(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2500, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2502(F, sep, ...) \ + Z_UTIL_LISTIFY_2501(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2501, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2503(F, sep, ...) \ + Z_UTIL_LISTIFY_2502(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2502, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2504(F, sep, ...) \ + Z_UTIL_LISTIFY_2503(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2503, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2505(F, sep, ...) \ + Z_UTIL_LISTIFY_2504(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2504, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2506(F, sep, ...) \ + Z_UTIL_LISTIFY_2505(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2505, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2507(F, sep, ...) \ + Z_UTIL_LISTIFY_2506(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2506, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2508(F, sep, ...) \ + Z_UTIL_LISTIFY_2507(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2507, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2509(F, sep, ...) \ + Z_UTIL_LISTIFY_2508(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2508, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2510(F, sep, ...) \ + Z_UTIL_LISTIFY_2509(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2509, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2511(F, sep, ...) \ + Z_UTIL_LISTIFY_2510(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2510, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2512(F, sep, ...) \ + Z_UTIL_LISTIFY_2511(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2511, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2513(F, sep, ...) \ + Z_UTIL_LISTIFY_2512(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2512, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2514(F, sep, ...) \ + Z_UTIL_LISTIFY_2513(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2513, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2515(F, sep, ...) \ + Z_UTIL_LISTIFY_2514(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2514, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2516(F, sep, ...) \ + Z_UTIL_LISTIFY_2515(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2515, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2517(F, sep, ...) \ + Z_UTIL_LISTIFY_2516(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2516, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2518(F, sep, ...) \ + Z_UTIL_LISTIFY_2517(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2517, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2519(F, sep, ...) \ + Z_UTIL_LISTIFY_2518(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2518, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2520(F, sep, ...) \ + Z_UTIL_LISTIFY_2519(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2519, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2521(F, sep, ...) \ + Z_UTIL_LISTIFY_2520(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2520, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2522(F, sep, ...) \ + Z_UTIL_LISTIFY_2521(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2521, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2523(F, sep, ...) \ + Z_UTIL_LISTIFY_2522(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2522, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2524(F, sep, ...) \ + Z_UTIL_LISTIFY_2523(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2523, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2525(F, sep, ...) \ + Z_UTIL_LISTIFY_2524(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2524, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2526(F, sep, ...) \ + Z_UTIL_LISTIFY_2525(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2525, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2527(F, sep, ...) \ + Z_UTIL_LISTIFY_2526(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2526, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2528(F, sep, ...) \ + Z_UTIL_LISTIFY_2527(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2527, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2529(F, sep, ...) \ + Z_UTIL_LISTIFY_2528(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2528, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2530(F, sep, ...) \ + Z_UTIL_LISTIFY_2529(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2529, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2531(F, sep, ...) \ + Z_UTIL_LISTIFY_2530(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2530, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2532(F, sep, ...) \ + Z_UTIL_LISTIFY_2531(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2531, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2533(F, sep, ...) \ + Z_UTIL_LISTIFY_2532(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2532, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2534(F, sep, ...) \ + Z_UTIL_LISTIFY_2533(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2533, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2535(F, sep, ...) \ + Z_UTIL_LISTIFY_2534(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2534, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2536(F, sep, ...) \ + Z_UTIL_LISTIFY_2535(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2535, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2537(F, sep, ...) \ + Z_UTIL_LISTIFY_2536(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2536, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2538(F, sep, ...) \ + Z_UTIL_LISTIFY_2537(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2537, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2539(F, sep, ...) \ + Z_UTIL_LISTIFY_2538(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2538, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2540(F, sep, ...) \ + Z_UTIL_LISTIFY_2539(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2539, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2541(F, sep, ...) \ + Z_UTIL_LISTIFY_2540(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2540, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2542(F, sep, ...) \ + Z_UTIL_LISTIFY_2541(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2541, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2543(F, sep, ...) \ + Z_UTIL_LISTIFY_2542(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2542, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2544(F, sep, ...) \ + Z_UTIL_LISTIFY_2543(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2543, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2545(F, sep, ...) \ + Z_UTIL_LISTIFY_2544(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2544, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2546(F, sep, ...) \ + Z_UTIL_LISTIFY_2545(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2545, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2547(F, sep, ...) \ + Z_UTIL_LISTIFY_2546(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2546, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2548(F, sep, ...) \ + Z_UTIL_LISTIFY_2547(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2547, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2549(F, sep, ...) \ + Z_UTIL_LISTIFY_2548(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2548, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2550(F, sep, ...) \ + Z_UTIL_LISTIFY_2549(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2549, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2551(F, sep, ...) \ + Z_UTIL_LISTIFY_2550(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2550, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2552(F, sep, ...) \ + Z_UTIL_LISTIFY_2551(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2551, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2553(F, sep, ...) \ + Z_UTIL_LISTIFY_2552(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2552, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2554(F, sep, ...) \ + Z_UTIL_LISTIFY_2553(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2553, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2555(F, sep, ...) \ + Z_UTIL_LISTIFY_2554(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2554, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2556(F, sep, ...) \ + Z_UTIL_LISTIFY_2555(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2555, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2557(F, sep, ...) \ + Z_UTIL_LISTIFY_2556(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2556, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2558(F, sep, ...) \ + Z_UTIL_LISTIFY_2557(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2557, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2559(F, sep, ...) \ + Z_UTIL_LISTIFY_2558(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2558, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2560(F, sep, ...) \ + Z_UTIL_LISTIFY_2559(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2559, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2561(F, sep, ...) \ + Z_UTIL_LISTIFY_2560(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2560, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2562(F, sep, ...) \ + Z_UTIL_LISTIFY_2561(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2561, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2563(F, sep, ...) \ + Z_UTIL_LISTIFY_2562(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2562, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2564(F, sep, ...) \ + Z_UTIL_LISTIFY_2563(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2563, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2565(F, sep, ...) \ + Z_UTIL_LISTIFY_2564(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2564, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2566(F, sep, ...) \ + Z_UTIL_LISTIFY_2565(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2565, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2567(F, sep, ...) \ + Z_UTIL_LISTIFY_2566(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2566, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2568(F, sep, ...) \ + Z_UTIL_LISTIFY_2567(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2567, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2569(F, sep, ...) \ + Z_UTIL_LISTIFY_2568(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2568, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2570(F, sep, ...) \ + Z_UTIL_LISTIFY_2569(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2569, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2571(F, sep, ...) \ + Z_UTIL_LISTIFY_2570(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2570, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2572(F, sep, ...) \ + Z_UTIL_LISTIFY_2571(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2571, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2573(F, sep, ...) \ + Z_UTIL_LISTIFY_2572(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2572, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2574(F, sep, ...) \ + Z_UTIL_LISTIFY_2573(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2573, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2575(F, sep, ...) \ + Z_UTIL_LISTIFY_2574(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2574, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2576(F, sep, ...) \ + Z_UTIL_LISTIFY_2575(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2575, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2577(F, sep, ...) \ + Z_UTIL_LISTIFY_2576(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2576, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2578(F, sep, ...) \ + Z_UTIL_LISTIFY_2577(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2577, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2579(F, sep, ...) \ + Z_UTIL_LISTIFY_2578(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2578, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2580(F, sep, ...) \ + Z_UTIL_LISTIFY_2579(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2579, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2581(F, sep, ...) \ + Z_UTIL_LISTIFY_2580(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2580, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2582(F, sep, ...) \ + Z_UTIL_LISTIFY_2581(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2581, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2583(F, sep, ...) \ + Z_UTIL_LISTIFY_2582(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2582, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2584(F, sep, ...) \ + Z_UTIL_LISTIFY_2583(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2583, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2585(F, sep, ...) \ + Z_UTIL_LISTIFY_2584(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2584, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2586(F, sep, ...) \ + Z_UTIL_LISTIFY_2585(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2585, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2587(F, sep, ...) \ + Z_UTIL_LISTIFY_2586(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2586, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2588(F, sep, ...) \ + Z_UTIL_LISTIFY_2587(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2587, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2589(F, sep, ...) \ + Z_UTIL_LISTIFY_2588(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2588, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2590(F, sep, ...) \ + Z_UTIL_LISTIFY_2589(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2589, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2591(F, sep, ...) \ + Z_UTIL_LISTIFY_2590(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2590, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2592(F, sep, ...) \ + Z_UTIL_LISTIFY_2591(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2591, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2593(F, sep, ...) \ + Z_UTIL_LISTIFY_2592(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2592, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2594(F, sep, ...) \ + Z_UTIL_LISTIFY_2593(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2593, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2595(F, sep, ...) \ + Z_UTIL_LISTIFY_2594(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2594, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2596(F, sep, ...) \ + Z_UTIL_LISTIFY_2595(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2595, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2597(F, sep, ...) \ + Z_UTIL_LISTIFY_2596(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2596, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2598(F, sep, ...) \ + Z_UTIL_LISTIFY_2597(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2597, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2599(F, sep, ...) \ + Z_UTIL_LISTIFY_2598(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2598, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2600(F, sep, ...) \ + Z_UTIL_LISTIFY_2599(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2599, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2601(F, sep, ...) \ + Z_UTIL_LISTIFY_2600(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2600, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2602(F, sep, ...) \ + Z_UTIL_LISTIFY_2601(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2601, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2603(F, sep, ...) \ + Z_UTIL_LISTIFY_2602(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2602, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2604(F, sep, ...) \ + Z_UTIL_LISTIFY_2603(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2603, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2605(F, sep, ...) \ + Z_UTIL_LISTIFY_2604(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2604, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2606(F, sep, ...) \ + Z_UTIL_LISTIFY_2605(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2605, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2607(F, sep, ...) \ + Z_UTIL_LISTIFY_2606(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2606, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2608(F, sep, ...) \ + Z_UTIL_LISTIFY_2607(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2607, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2609(F, sep, ...) \ + Z_UTIL_LISTIFY_2608(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2608, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2610(F, sep, ...) \ + Z_UTIL_LISTIFY_2609(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2609, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2611(F, sep, ...) \ + Z_UTIL_LISTIFY_2610(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2610, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2612(F, sep, ...) \ + Z_UTIL_LISTIFY_2611(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2611, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2613(F, sep, ...) \ + Z_UTIL_LISTIFY_2612(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2612, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2614(F, sep, ...) \ + Z_UTIL_LISTIFY_2613(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2613, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2615(F, sep, ...) \ + Z_UTIL_LISTIFY_2614(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2614, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2616(F, sep, ...) \ + Z_UTIL_LISTIFY_2615(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2615, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2617(F, sep, ...) \ + Z_UTIL_LISTIFY_2616(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2616, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2618(F, sep, ...) \ + Z_UTIL_LISTIFY_2617(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2617, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2619(F, sep, ...) \ + Z_UTIL_LISTIFY_2618(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2618, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2620(F, sep, ...) \ + Z_UTIL_LISTIFY_2619(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2619, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2621(F, sep, ...) \ + Z_UTIL_LISTIFY_2620(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2620, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2622(F, sep, ...) \ + Z_UTIL_LISTIFY_2621(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2621, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2623(F, sep, ...) \ + Z_UTIL_LISTIFY_2622(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2622, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2624(F, sep, ...) \ + Z_UTIL_LISTIFY_2623(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2623, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2625(F, sep, ...) \ + Z_UTIL_LISTIFY_2624(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2624, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2626(F, sep, ...) \ + Z_UTIL_LISTIFY_2625(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2625, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2627(F, sep, ...) \ + Z_UTIL_LISTIFY_2626(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2626, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2628(F, sep, ...) \ + Z_UTIL_LISTIFY_2627(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2627, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2629(F, sep, ...) \ + Z_UTIL_LISTIFY_2628(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2628, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2630(F, sep, ...) \ + Z_UTIL_LISTIFY_2629(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2629, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2631(F, sep, ...) \ + Z_UTIL_LISTIFY_2630(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2630, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2632(F, sep, ...) \ + Z_UTIL_LISTIFY_2631(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2631, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2633(F, sep, ...) \ + Z_UTIL_LISTIFY_2632(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2632, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2634(F, sep, ...) \ + Z_UTIL_LISTIFY_2633(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2633, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2635(F, sep, ...) \ + Z_UTIL_LISTIFY_2634(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2634, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2636(F, sep, ...) \ + Z_UTIL_LISTIFY_2635(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2635, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2637(F, sep, ...) \ + Z_UTIL_LISTIFY_2636(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2636, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2638(F, sep, ...) \ + Z_UTIL_LISTIFY_2637(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2637, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2639(F, sep, ...) \ + Z_UTIL_LISTIFY_2638(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2638, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2640(F, sep, ...) \ + Z_UTIL_LISTIFY_2639(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2639, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2641(F, sep, ...) \ + Z_UTIL_LISTIFY_2640(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2640, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2642(F, sep, ...) \ + Z_UTIL_LISTIFY_2641(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2641, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2643(F, sep, ...) \ + Z_UTIL_LISTIFY_2642(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2642, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2644(F, sep, ...) \ + Z_UTIL_LISTIFY_2643(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2643, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2645(F, sep, ...) \ + Z_UTIL_LISTIFY_2644(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2644, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2646(F, sep, ...) \ + Z_UTIL_LISTIFY_2645(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2645, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2647(F, sep, ...) \ + Z_UTIL_LISTIFY_2646(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2646, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2648(F, sep, ...) \ + Z_UTIL_LISTIFY_2647(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2647, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2649(F, sep, ...) \ + Z_UTIL_LISTIFY_2648(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2648, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2650(F, sep, ...) \ + Z_UTIL_LISTIFY_2649(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2649, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2651(F, sep, ...) \ + Z_UTIL_LISTIFY_2650(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2650, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2652(F, sep, ...) \ + Z_UTIL_LISTIFY_2651(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2651, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2653(F, sep, ...) \ + Z_UTIL_LISTIFY_2652(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2652, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2654(F, sep, ...) \ + Z_UTIL_LISTIFY_2653(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2653, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2655(F, sep, ...) \ + Z_UTIL_LISTIFY_2654(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2654, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2656(F, sep, ...) \ + Z_UTIL_LISTIFY_2655(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2655, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2657(F, sep, ...) \ + Z_UTIL_LISTIFY_2656(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2656, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2658(F, sep, ...) \ + Z_UTIL_LISTIFY_2657(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2657, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2659(F, sep, ...) \ + Z_UTIL_LISTIFY_2658(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2658, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2660(F, sep, ...) \ + Z_UTIL_LISTIFY_2659(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2659, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2661(F, sep, ...) \ + Z_UTIL_LISTIFY_2660(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2660, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2662(F, sep, ...) \ + Z_UTIL_LISTIFY_2661(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2661, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2663(F, sep, ...) \ + Z_UTIL_LISTIFY_2662(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2662, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2664(F, sep, ...) \ + Z_UTIL_LISTIFY_2663(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2663, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2665(F, sep, ...) \ + Z_UTIL_LISTIFY_2664(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2664, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2666(F, sep, ...) \ + Z_UTIL_LISTIFY_2665(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2665, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2667(F, sep, ...) \ + Z_UTIL_LISTIFY_2666(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2666, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2668(F, sep, ...) \ + Z_UTIL_LISTIFY_2667(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2667, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2669(F, sep, ...) \ + Z_UTIL_LISTIFY_2668(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2668, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2670(F, sep, ...) \ + Z_UTIL_LISTIFY_2669(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2669, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2671(F, sep, ...) \ + Z_UTIL_LISTIFY_2670(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2670, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2672(F, sep, ...) \ + Z_UTIL_LISTIFY_2671(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2671, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2673(F, sep, ...) \ + Z_UTIL_LISTIFY_2672(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2672, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2674(F, sep, ...) \ + Z_UTIL_LISTIFY_2673(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2673, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2675(F, sep, ...) \ + Z_UTIL_LISTIFY_2674(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2674, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2676(F, sep, ...) \ + Z_UTIL_LISTIFY_2675(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2675, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2677(F, sep, ...) \ + Z_UTIL_LISTIFY_2676(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2676, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2678(F, sep, ...) \ + Z_UTIL_LISTIFY_2677(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2677, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2679(F, sep, ...) \ + Z_UTIL_LISTIFY_2678(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2678, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2680(F, sep, ...) \ + Z_UTIL_LISTIFY_2679(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2679, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2681(F, sep, ...) \ + Z_UTIL_LISTIFY_2680(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2680, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2682(F, sep, ...) \ + Z_UTIL_LISTIFY_2681(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2681, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2683(F, sep, ...) \ + Z_UTIL_LISTIFY_2682(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2682, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2684(F, sep, ...) \ + Z_UTIL_LISTIFY_2683(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2683, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2685(F, sep, ...) \ + Z_UTIL_LISTIFY_2684(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2684, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2686(F, sep, ...) \ + Z_UTIL_LISTIFY_2685(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2685, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2687(F, sep, ...) \ + Z_UTIL_LISTIFY_2686(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2686, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2688(F, sep, ...) \ + Z_UTIL_LISTIFY_2687(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2687, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2689(F, sep, ...) \ + Z_UTIL_LISTIFY_2688(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2688, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2690(F, sep, ...) \ + Z_UTIL_LISTIFY_2689(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2689, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2691(F, sep, ...) \ + Z_UTIL_LISTIFY_2690(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2690, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2692(F, sep, ...) \ + Z_UTIL_LISTIFY_2691(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2691, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2693(F, sep, ...) \ + Z_UTIL_LISTIFY_2692(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2692, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2694(F, sep, ...) \ + Z_UTIL_LISTIFY_2693(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2693, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2695(F, sep, ...) \ + Z_UTIL_LISTIFY_2694(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2694, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2696(F, sep, ...) \ + Z_UTIL_LISTIFY_2695(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2695, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2697(F, sep, ...) \ + Z_UTIL_LISTIFY_2696(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2696, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2698(F, sep, ...) \ + Z_UTIL_LISTIFY_2697(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2697, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2699(F, sep, ...) \ + Z_UTIL_LISTIFY_2698(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2698, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2700(F, sep, ...) \ + Z_UTIL_LISTIFY_2699(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2699, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2701(F, sep, ...) \ + Z_UTIL_LISTIFY_2700(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2700, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2702(F, sep, ...) \ + Z_UTIL_LISTIFY_2701(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2701, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2703(F, sep, ...) \ + Z_UTIL_LISTIFY_2702(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2702, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2704(F, sep, ...) \ + Z_UTIL_LISTIFY_2703(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2703, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2705(F, sep, ...) \ + Z_UTIL_LISTIFY_2704(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2704, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2706(F, sep, ...) \ + Z_UTIL_LISTIFY_2705(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2705, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2707(F, sep, ...) \ + Z_UTIL_LISTIFY_2706(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2706, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2708(F, sep, ...) \ + Z_UTIL_LISTIFY_2707(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2707, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2709(F, sep, ...) \ + Z_UTIL_LISTIFY_2708(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2708, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2710(F, sep, ...) \ + Z_UTIL_LISTIFY_2709(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2709, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2711(F, sep, ...) \ + Z_UTIL_LISTIFY_2710(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2710, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2712(F, sep, ...) \ + Z_UTIL_LISTIFY_2711(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2711, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2713(F, sep, ...) \ + Z_UTIL_LISTIFY_2712(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2712, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2714(F, sep, ...) \ + Z_UTIL_LISTIFY_2713(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2713, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2715(F, sep, ...) \ + Z_UTIL_LISTIFY_2714(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2714, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2716(F, sep, ...) \ + Z_UTIL_LISTIFY_2715(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2715, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2717(F, sep, ...) \ + Z_UTIL_LISTIFY_2716(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2716, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2718(F, sep, ...) \ + Z_UTIL_LISTIFY_2717(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2717, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2719(F, sep, ...) \ + Z_UTIL_LISTIFY_2718(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2718, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2720(F, sep, ...) \ + Z_UTIL_LISTIFY_2719(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2719, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2721(F, sep, ...) \ + Z_UTIL_LISTIFY_2720(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2720, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2722(F, sep, ...) \ + Z_UTIL_LISTIFY_2721(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2721, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2723(F, sep, ...) \ + Z_UTIL_LISTIFY_2722(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2722, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2724(F, sep, ...) \ + Z_UTIL_LISTIFY_2723(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2723, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2725(F, sep, ...) \ + Z_UTIL_LISTIFY_2724(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2724, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2726(F, sep, ...) \ + Z_UTIL_LISTIFY_2725(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2725, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2727(F, sep, ...) \ + Z_UTIL_LISTIFY_2726(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2726, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2728(F, sep, ...) \ + Z_UTIL_LISTIFY_2727(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2727, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2729(F, sep, ...) \ + Z_UTIL_LISTIFY_2728(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2728, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2730(F, sep, ...) \ + Z_UTIL_LISTIFY_2729(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2729, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2731(F, sep, ...) \ + Z_UTIL_LISTIFY_2730(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2730, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2732(F, sep, ...) \ + Z_UTIL_LISTIFY_2731(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2731, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2733(F, sep, ...) \ + Z_UTIL_LISTIFY_2732(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2732, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2734(F, sep, ...) \ + Z_UTIL_LISTIFY_2733(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2733, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2735(F, sep, ...) \ + Z_UTIL_LISTIFY_2734(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2734, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2736(F, sep, ...) \ + Z_UTIL_LISTIFY_2735(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2735, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2737(F, sep, ...) \ + Z_UTIL_LISTIFY_2736(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2736, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2738(F, sep, ...) \ + Z_UTIL_LISTIFY_2737(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2737, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2739(F, sep, ...) \ + Z_UTIL_LISTIFY_2738(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2738, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2740(F, sep, ...) \ + Z_UTIL_LISTIFY_2739(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2739, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2741(F, sep, ...) \ + Z_UTIL_LISTIFY_2740(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2740, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2742(F, sep, ...) \ + Z_UTIL_LISTIFY_2741(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2741, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2743(F, sep, ...) \ + Z_UTIL_LISTIFY_2742(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2742, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2744(F, sep, ...) \ + Z_UTIL_LISTIFY_2743(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2743, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2745(F, sep, ...) \ + Z_UTIL_LISTIFY_2744(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2744, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2746(F, sep, ...) \ + Z_UTIL_LISTIFY_2745(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2745, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2747(F, sep, ...) \ + Z_UTIL_LISTIFY_2746(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2746, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2748(F, sep, ...) \ + Z_UTIL_LISTIFY_2747(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2747, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2749(F, sep, ...) \ + Z_UTIL_LISTIFY_2748(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2748, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2750(F, sep, ...) \ + Z_UTIL_LISTIFY_2749(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2749, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2751(F, sep, ...) \ + Z_UTIL_LISTIFY_2750(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2750, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2752(F, sep, ...) \ + Z_UTIL_LISTIFY_2751(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2751, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2753(F, sep, ...) \ + Z_UTIL_LISTIFY_2752(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2752, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2754(F, sep, ...) \ + Z_UTIL_LISTIFY_2753(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2753, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2755(F, sep, ...) \ + Z_UTIL_LISTIFY_2754(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2754, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2756(F, sep, ...) \ + Z_UTIL_LISTIFY_2755(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2755, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2757(F, sep, ...) \ + Z_UTIL_LISTIFY_2756(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2756, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2758(F, sep, ...) \ + Z_UTIL_LISTIFY_2757(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2757, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2759(F, sep, ...) \ + Z_UTIL_LISTIFY_2758(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2758, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2760(F, sep, ...) \ + Z_UTIL_LISTIFY_2759(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2759, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2761(F, sep, ...) \ + Z_UTIL_LISTIFY_2760(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2760, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2762(F, sep, ...) \ + Z_UTIL_LISTIFY_2761(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2761, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2763(F, sep, ...) \ + Z_UTIL_LISTIFY_2762(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2762, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2764(F, sep, ...) \ + Z_UTIL_LISTIFY_2763(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2763, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2765(F, sep, ...) \ + Z_UTIL_LISTIFY_2764(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2764, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2766(F, sep, ...) \ + Z_UTIL_LISTIFY_2765(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2765, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2767(F, sep, ...) \ + Z_UTIL_LISTIFY_2766(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2766, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2768(F, sep, ...) \ + Z_UTIL_LISTIFY_2767(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2767, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2769(F, sep, ...) \ + Z_UTIL_LISTIFY_2768(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2768, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2770(F, sep, ...) \ + Z_UTIL_LISTIFY_2769(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2769, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2771(F, sep, ...) \ + Z_UTIL_LISTIFY_2770(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2770, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2772(F, sep, ...) \ + Z_UTIL_LISTIFY_2771(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2771, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2773(F, sep, ...) \ + Z_UTIL_LISTIFY_2772(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2772, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2774(F, sep, ...) \ + Z_UTIL_LISTIFY_2773(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2773, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2775(F, sep, ...) \ + Z_UTIL_LISTIFY_2774(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2774, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2776(F, sep, ...) \ + Z_UTIL_LISTIFY_2775(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2775, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2777(F, sep, ...) \ + Z_UTIL_LISTIFY_2776(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2776, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2778(F, sep, ...) \ + Z_UTIL_LISTIFY_2777(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2777, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2779(F, sep, ...) \ + Z_UTIL_LISTIFY_2778(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2778, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2780(F, sep, ...) \ + Z_UTIL_LISTIFY_2779(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2779, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2781(F, sep, ...) \ + Z_UTIL_LISTIFY_2780(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2780, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2782(F, sep, ...) \ + Z_UTIL_LISTIFY_2781(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2781, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2783(F, sep, ...) \ + Z_UTIL_LISTIFY_2782(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2782, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2784(F, sep, ...) \ + Z_UTIL_LISTIFY_2783(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2783, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2785(F, sep, ...) \ + Z_UTIL_LISTIFY_2784(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2784, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2786(F, sep, ...) \ + Z_UTIL_LISTIFY_2785(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2785, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2787(F, sep, ...) \ + Z_UTIL_LISTIFY_2786(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2786, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2788(F, sep, ...) \ + Z_UTIL_LISTIFY_2787(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2787, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2789(F, sep, ...) \ + Z_UTIL_LISTIFY_2788(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2788, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2790(F, sep, ...) \ + Z_UTIL_LISTIFY_2789(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2789, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2791(F, sep, ...) \ + Z_UTIL_LISTIFY_2790(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2790, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2792(F, sep, ...) \ + Z_UTIL_LISTIFY_2791(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2791, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2793(F, sep, ...) \ + Z_UTIL_LISTIFY_2792(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2792, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2794(F, sep, ...) \ + Z_UTIL_LISTIFY_2793(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2793, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2795(F, sep, ...) \ + Z_UTIL_LISTIFY_2794(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2794, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2796(F, sep, ...) \ + Z_UTIL_LISTIFY_2795(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2795, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2797(F, sep, ...) \ + Z_UTIL_LISTIFY_2796(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2796, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2798(F, sep, ...) \ + Z_UTIL_LISTIFY_2797(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2797, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2799(F, sep, ...) \ + Z_UTIL_LISTIFY_2798(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2798, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2800(F, sep, ...) \ + Z_UTIL_LISTIFY_2799(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2799, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2801(F, sep, ...) \ + Z_UTIL_LISTIFY_2800(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2800, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2802(F, sep, ...) \ + Z_UTIL_LISTIFY_2801(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2801, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2803(F, sep, ...) \ + Z_UTIL_LISTIFY_2802(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2802, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2804(F, sep, ...) \ + Z_UTIL_LISTIFY_2803(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2803, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2805(F, sep, ...) \ + Z_UTIL_LISTIFY_2804(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2804, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2806(F, sep, ...) \ + Z_UTIL_LISTIFY_2805(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2805, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2807(F, sep, ...) \ + Z_UTIL_LISTIFY_2806(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2806, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2808(F, sep, ...) \ + Z_UTIL_LISTIFY_2807(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2807, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2809(F, sep, ...) \ + Z_UTIL_LISTIFY_2808(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2808, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2810(F, sep, ...) \ + Z_UTIL_LISTIFY_2809(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2809, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2811(F, sep, ...) \ + Z_UTIL_LISTIFY_2810(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2810, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2812(F, sep, ...) \ + Z_UTIL_LISTIFY_2811(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2811, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2813(F, sep, ...) \ + Z_UTIL_LISTIFY_2812(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2812, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2814(F, sep, ...) \ + Z_UTIL_LISTIFY_2813(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2813, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2815(F, sep, ...) \ + Z_UTIL_LISTIFY_2814(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2814, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2816(F, sep, ...) \ + Z_UTIL_LISTIFY_2815(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2815, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2817(F, sep, ...) \ + Z_UTIL_LISTIFY_2816(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2816, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2818(F, sep, ...) \ + Z_UTIL_LISTIFY_2817(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2817, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2819(F, sep, ...) \ + Z_UTIL_LISTIFY_2818(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2818, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2820(F, sep, ...) \ + Z_UTIL_LISTIFY_2819(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2819, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2821(F, sep, ...) \ + Z_UTIL_LISTIFY_2820(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2820, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2822(F, sep, ...) \ + Z_UTIL_LISTIFY_2821(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2821, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2823(F, sep, ...) \ + Z_UTIL_LISTIFY_2822(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2822, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2824(F, sep, ...) \ + Z_UTIL_LISTIFY_2823(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2823, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2825(F, sep, ...) \ + Z_UTIL_LISTIFY_2824(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2824, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2826(F, sep, ...) \ + Z_UTIL_LISTIFY_2825(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2825, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2827(F, sep, ...) \ + Z_UTIL_LISTIFY_2826(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2826, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2828(F, sep, ...) \ + Z_UTIL_LISTIFY_2827(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2827, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2829(F, sep, ...) \ + Z_UTIL_LISTIFY_2828(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2828, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2830(F, sep, ...) \ + Z_UTIL_LISTIFY_2829(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2829, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2831(F, sep, ...) \ + Z_UTIL_LISTIFY_2830(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2830, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2832(F, sep, ...) \ + Z_UTIL_LISTIFY_2831(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2831, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2833(F, sep, ...) \ + Z_UTIL_LISTIFY_2832(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2832, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2834(F, sep, ...) \ + Z_UTIL_LISTIFY_2833(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2833, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2835(F, sep, ...) \ + Z_UTIL_LISTIFY_2834(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2834, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2836(F, sep, ...) \ + Z_UTIL_LISTIFY_2835(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2835, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2837(F, sep, ...) \ + Z_UTIL_LISTIFY_2836(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2836, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2838(F, sep, ...) \ + Z_UTIL_LISTIFY_2837(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2837, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2839(F, sep, ...) \ + Z_UTIL_LISTIFY_2838(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2838, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2840(F, sep, ...) \ + Z_UTIL_LISTIFY_2839(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2839, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2841(F, sep, ...) \ + Z_UTIL_LISTIFY_2840(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2840, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2842(F, sep, ...) \ + Z_UTIL_LISTIFY_2841(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2841, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2843(F, sep, ...) \ + Z_UTIL_LISTIFY_2842(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2842, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2844(F, sep, ...) \ + Z_UTIL_LISTIFY_2843(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2843, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2845(F, sep, ...) \ + Z_UTIL_LISTIFY_2844(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2844, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2846(F, sep, ...) \ + Z_UTIL_LISTIFY_2845(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2845, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2847(F, sep, ...) \ + Z_UTIL_LISTIFY_2846(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2846, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2848(F, sep, ...) \ + Z_UTIL_LISTIFY_2847(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2847, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2849(F, sep, ...) \ + Z_UTIL_LISTIFY_2848(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2848, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2850(F, sep, ...) \ + Z_UTIL_LISTIFY_2849(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2849, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2851(F, sep, ...) \ + Z_UTIL_LISTIFY_2850(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2850, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2852(F, sep, ...) \ + Z_UTIL_LISTIFY_2851(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2851, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2853(F, sep, ...) \ + Z_UTIL_LISTIFY_2852(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2852, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2854(F, sep, ...) \ + Z_UTIL_LISTIFY_2853(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2853, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2855(F, sep, ...) \ + Z_UTIL_LISTIFY_2854(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2854, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2856(F, sep, ...) \ + Z_UTIL_LISTIFY_2855(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2855, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2857(F, sep, ...) \ + Z_UTIL_LISTIFY_2856(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2856, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2858(F, sep, ...) \ + Z_UTIL_LISTIFY_2857(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2857, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2859(F, sep, ...) \ + Z_UTIL_LISTIFY_2858(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2858, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2860(F, sep, ...) \ + Z_UTIL_LISTIFY_2859(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2859, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2861(F, sep, ...) \ + Z_UTIL_LISTIFY_2860(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2860, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2862(F, sep, ...) \ + Z_UTIL_LISTIFY_2861(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2861, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2863(F, sep, ...) \ + Z_UTIL_LISTIFY_2862(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2862, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2864(F, sep, ...) \ + Z_UTIL_LISTIFY_2863(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2863, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2865(F, sep, ...) \ + Z_UTIL_LISTIFY_2864(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2864, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2866(F, sep, ...) \ + Z_UTIL_LISTIFY_2865(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2865, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2867(F, sep, ...) \ + Z_UTIL_LISTIFY_2866(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2866, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2868(F, sep, ...) \ + Z_UTIL_LISTIFY_2867(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2867, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2869(F, sep, ...) \ + Z_UTIL_LISTIFY_2868(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2868, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2870(F, sep, ...) \ + Z_UTIL_LISTIFY_2869(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2869, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2871(F, sep, ...) \ + Z_UTIL_LISTIFY_2870(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2870, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2872(F, sep, ...) \ + Z_UTIL_LISTIFY_2871(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2871, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2873(F, sep, ...) \ + Z_UTIL_LISTIFY_2872(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2872, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2874(F, sep, ...) \ + Z_UTIL_LISTIFY_2873(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2873, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2875(F, sep, ...) \ + Z_UTIL_LISTIFY_2874(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2874, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2876(F, sep, ...) \ + Z_UTIL_LISTIFY_2875(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2875, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2877(F, sep, ...) \ + Z_UTIL_LISTIFY_2876(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2876, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2878(F, sep, ...) \ + Z_UTIL_LISTIFY_2877(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2877, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2879(F, sep, ...) \ + Z_UTIL_LISTIFY_2878(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2878, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2880(F, sep, ...) \ + Z_UTIL_LISTIFY_2879(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2879, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2881(F, sep, ...) \ + Z_UTIL_LISTIFY_2880(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2880, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2882(F, sep, ...) \ + Z_UTIL_LISTIFY_2881(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2881, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2883(F, sep, ...) \ + Z_UTIL_LISTIFY_2882(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2882, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2884(F, sep, ...) \ + Z_UTIL_LISTIFY_2883(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2883, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2885(F, sep, ...) \ + Z_UTIL_LISTIFY_2884(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2884, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2886(F, sep, ...) \ + Z_UTIL_LISTIFY_2885(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2885, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2887(F, sep, ...) \ + Z_UTIL_LISTIFY_2886(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2886, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2888(F, sep, ...) \ + Z_UTIL_LISTIFY_2887(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2887, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2889(F, sep, ...) \ + Z_UTIL_LISTIFY_2888(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2888, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2890(F, sep, ...) \ + Z_UTIL_LISTIFY_2889(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2889, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2891(F, sep, ...) \ + Z_UTIL_LISTIFY_2890(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2890, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2892(F, sep, ...) \ + Z_UTIL_LISTIFY_2891(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2891, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2893(F, sep, ...) \ + Z_UTIL_LISTIFY_2892(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2892, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2894(F, sep, ...) \ + Z_UTIL_LISTIFY_2893(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2893, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2895(F, sep, ...) \ + Z_UTIL_LISTIFY_2894(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2894, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2896(F, sep, ...) \ + Z_UTIL_LISTIFY_2895(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2895, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2897(F, sep, ...) \ + Z_UTIL_LISTIFY_2896(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2896, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2898(F, sep, ...) \ + Z_UTIL_LISTIFY_2897(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2897, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2899(F, sep, ...) \ + Z_UTIL_LISTIFY_2898(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2898, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2900(F, sep, ...) \ + Z_UTIL_LISTIFY_2899(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2899, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2901(F, sep, ...) \ + Z_UTIL_LISTIFY_2900(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2900, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2902(F, sep, ...) \ + Z_UTIL_LISTIFY_2901(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2901, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2903(F, sep, ...) \ + Z_UTIL_LISTIFY_2902(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2902, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2904(F, sep, ...) \ + Z_UTIL_LISTIFY_2903(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2903, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2905(F, sep, ...) \ + Z_UTIL_LISTIFY_2904(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2904, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2906(F, sep, ...) \ + Z_UTIL_LISTIFY_2905(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2905, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2907(F, sep, ...) \ + Z_UTIL_LISTIFY_2906(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2906, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2908(F, sep, ...) \ + Z_UTIL_LISTIFY_2907(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2907, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2909(F, sep, ...) \ + Z_UTIL_LISTIFY_2908(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2908, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2910(F, sep, ...) \ + Z_UTIL_LISTIFY_2909(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2909, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2911(F, sep, ...) \ + Z_UTIL_LISTIFY_2910(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2910, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2912(F, sep, ...) \ + Z_UTIL_LISTIFY_2911(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2911, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2913(F, sep, ...) \ + Z_UTIL_LISTIFY_2912(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2912, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2914(F, sep, ...) \ + Z_UTIL_LISTIFY_2913(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2913, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2915(F, sep, ...) \ + Z_UTIL_LISTIFY_2914(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2914, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2916(F, sep, ...) \ + Z_UTIL_LISTIFY_2915(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2915, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2917(F, sep, ...) \ + Z_UTIL_LISTIFY_2916(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2916, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2918(F, sep, ...) \ + Z_UTIL_LISTIFY_2917(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2917, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2919(F, sep, ...) \ + Z_UTIL_LISTIFY_2918(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2918, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2920(F, sep, ...) \ + Z_UTIL_LISTIFY_2919(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2919, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2921(F, sep, ...) \ + Z_UTIL_LISTIFY_2920(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2920, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2922(F, sep, ...) \ + Z_UTIL_LISTIFY_2921(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2921, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2923(F, sep, ...) \ + Z_UTIL_LISTIFY_2922(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2922, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2924(F, sep, ...) \ + Z_UTIL_LISTIFY_2923(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2923, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2925(F, sep, ...) \ + Z_UTIL_LISTIFY_2924(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2924, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2926(F, sep, ...) \ + Z_UTIL_LISTIFY_2925(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2925, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2927(F, sep, ...) \ + Z_UTIL_LISTIFY_2926(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2926, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2928(F, sep, ...) \ + Z_UTIL_LISTIFY_2927(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2927, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2929(F, sep, ...) \ + Z_UTIL_LISTIFY_2928(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2928, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2930(F, sep, ...) \ + Z_UTIL_LISTIFY_2929(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2929, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2931(F, sep, ...) \ + Z_UTIL_LISTIFY_2930(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2930, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2932(F, sep, ...) \ + Z_UTIL_LISTIFY_2931(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2931, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2933(F, sep, ...) \ + Z_UTIL_LISTIFY_2932(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2932, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2934(F, sep, ...) \ + Z_UTIL_LISTIFY_2933(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2933, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2935(F, sep, ...) \ + Z_UTIL_LISTIFY_2934(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2934, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2936(F, sep, ...) \ + Z_UTIL_LISTIFY_2935(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2935, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2937(F, sep, ...) \ + Z_UTIL_LISTIFY_2936(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2936, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2938(F, sep, ...) \ + Z_UTIL_LISTIFY_2937(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2937, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2939(F, sep, ...) \ + Z_UTIL_LISTIFY_2938(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2938, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2940(F, sep, ...) \ + Z_UTIL_LISTIFY_2939(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2939, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2941(F, sep, ...) \ + Z_UTIL_LISTIFY_2940(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2940, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2942(F, sep, ...) \ + Z_UTIL_LISTIFY_2941(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2941, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2943(F, sep, ...) \ + Z_UTIL_LISTIFY_2942(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2942, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2944(F, sep, ...) \ + Z_UTIL_LISTIFY_2943(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2943, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2945(F, sep, ...) \ + Z_UTIL_LISTIFY_2944(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2944, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2946(F, sep, ...) \ + Z_UTIL_LISTIFY_2945(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2945, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2947(F, sep, ...) \ + Z_UTIL_LISTIFY_2946(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2946, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2948(F, sep, ...) \ + Z_UTIL_LISTIFY_2947(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2947, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2949(F, sep, ...) \ + Z_UTIL_LISTIFY_2948(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2948, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2950(F, sep, ...) \ + Z_UTIL_LISTIFY_2949(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2949, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2951(F, sep, ...) \ + Z_UTIL_LISTIFY_2950(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2950, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2952(F, sep, ...) \ + Z_UTIL_LISTIFY_2951(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2951, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2953(F, sep, ...) \ + Z_UTIL_LISTIFY_2952(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2952, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2954(F, sep, ...) \ + Z_UTIL_LISTIFY_2953(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2953, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2955(F, sep, ...) \ + Z_UTIL_LISTIFY_2954(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2954, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2956(F, sep, ...) \ + Z_UTIL_LISTIFY_2955(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2955, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2957(F, sep, ...) \ + Z_UTIL_LISTIFY_2956(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2956, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2958(F, sep, ...) \ + Z_UTIL_LISTIFY_2957(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2957, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2959(F, sep, ...) \ + Z_UTIL_LISTIFY_2958(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2958, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2960(F, sep, ...) \ + Z_UTIL_LISTIFY_2959(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2959, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2961(F, sep, ...) \ + Z_UTIL_LISTIFY_2960(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2960, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2962(F, sep, ...) \ + Z_UTIL_LISTIFY_2961(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2961, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2963(F, sep, ...) \ + Z_UTIL_LISTIFY_2962(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2962, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2964(F, sep, ...) \ + Z_UTIL_LISTIFY_2963(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2963, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2965(F, sep, ...) \ + Z_UTIL_LISTIFY_2964(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2964, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2966(F, sep, ...) \ + Z_UTIL_LISTIFY_2965(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2965, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2967(F, sep, ...) \ + Z_UTIL_LISTIFY_2966(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2966, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2968(F, sep, ...) \ + Z_UTIL_LISTIFY_2967(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2967, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2969(F, sep, ...) \ + Z_UTIL_LISTIFY_2968(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2968, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2970(F, sep, ...) \ + Z_UTIL_LISTIFY_2969(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2969, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2971(F, sep, ...) \ + Z_UTIL_LISTIFY_2970(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2970, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2972(F, sep, ...) \ + Z_UTIL_LISTIFY_2971(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2971, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2973(F, sep, ...) \ + Z_UTIL_LISTIFY_2972(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2972, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2974(F, sep, ...) \ + Z_UTIL_LISTIFY_2973(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2973, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2975(F, sep, ...) \ + Z_UTIL_LISTIFY_2974(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2974, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2976(F, sep, ...) \ + Z_UTIL_LISTIFY_2975(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2975, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2977(F, sep, ...) \ + Z_UTIL_LISTIFY_2976(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2976, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2978(F, sep, ...) \ + Z_UTIL_LISTIFY_2977(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2977, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2979(F, sep, ...) \ + Z_UTIL_LISTIFY_2978(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2978, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2980(F, sep, ...) \ + Z_UTIL_LISTIFY_2979(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2979, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2981(F, sep, ...) \ + Z_UTIL_LISTIFY_2980(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2980, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2982(F, sep, ...) \ + Z_UTIL_LISTIFY_2981(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2981, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2983(F, sep, ...) \ + Z_UTIL_LISTIFY_2982(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2982, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2984(F, sep, ...) \ + Z_UTIL_LISTIFY_2983(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2983, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2985(F, sep, ...) \ + Z_UTIL_LISTIFY_2984(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2984, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2986(F, sep, ...) \ + Z_UTIL_LISTIFY_2985(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2985, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2987(F, sep, ...) \ + Z_UTIL_LISTIFY_2986(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2986, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2988(F, sep, ...) \ + Z_UTIL_LISTIFY_2987(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2987, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2989(F, sep, ...) \ + Z_UTIL_LISTIFY_2988(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2988, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2990(F, sep, ...) \ + Z_UTIL_LISTIFY_2989(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2989, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2991(F, sep, ...) \ + Z_UTIL_LISTIFY_2990(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2990, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2992(F, sep, ...) \ + Z_UTIL_LISTIFY_2991(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2991, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2993(F, sep, ...) \ + Z_UTIL_LISTIFY_2992(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2992, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2994(F, sep, ...) \ + Z_UTIL_LISTIFY_2993(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2993, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2995(F, sep, ...) \ + Z_UTIL_LISTIFY_2994(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2994, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2996(F, sep, ...) \ + Z_UTIL_LISTIFY_2995(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2995, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2997(F, sep, ...) \ + Z_UTIL_LISTIFY_2996(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2996, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2998(F, sep, ...) \ + Z_UTIL_LISTIFY_2997(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2997, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2999(F, sep, ...) \ + Z_UTIL_LISTIFY_2998(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2998, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3000(F, sep, ...) \ + Z_UTIL_LISTIFY_2999(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2999, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3001(F, sep, ...) \ + Z_UTIL_LISTIFY_3000(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3000, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3002(F, sep, ...) \ + Z_UTIL_LISTIFY_3001(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3001, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3003(F, sep, ...) \ + Z_UTIL_LISTIFY_3002(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3002, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3004(F, sep, ...) \ + Z_UTIL_LISTIFY_3003(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3003, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3005(F, sep, ...) \ + Z_UTIL_LISTIFY_3004(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3004, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3006(F, sep, ...) \ + Z_UTIL_LISTIFY_3005(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3005, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3007(F, sep, ...) \ + Z_UTIL_LISTIFY_3006(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3006, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3008(F, sep, ...) \ + Z_UTIL_LISTIFY_3007(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3007, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3009(F, sep, ...) \ + Z_UTIL_LISTIFY_3008(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3008, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3010(F, sep, ...) \ + Z_UTIL_LISTIFY_3009(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3009, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3011(F, sep, ...) \ + Z_UTIL_LISTIFY_3010(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3010, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3012(F, sep, ...) \ + Z_UTIL_LISTIFY_3011(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3011, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3013(F, sep, ...) \ + Z_UTIL_LISTIFY_3012(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3012, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3014(F, sep, ...) \ + Z_UTIL_LISTIFY_3013(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3013, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3015(F, sep, ...) \ + Z_UTIL_LISTIFY_3014(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3014, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3016(F, sep, ...) \ + Z_UTIL_LISTIFY_3015(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3015, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3017(F, sep, ...) \ + Z_UTIL_LISTIFY_3016(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3016, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3018(F, sep, ...) \ + Z_UTIL_LISTIFY_3017(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3017, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3019(F, sep, ...) \ + Z_UTIL_LISTIFY_3018(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3018, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3020(F, sep, ...) \ + Z_UTIL_LISTIFY_3019(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3019, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3021(F, sep, ...) \ + Z_UTIL_LISTIFY_3020(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3020, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3022(F, sep, ...) \ + Z_UTIL_LISTIFY_3021(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3021, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3023(F, sep, ...) \ + Z_UTIL_LISTIFY_3022(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3022, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3024(F, sep, ...) \ + Z_UTIL_LISTIFY_3023(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3023, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3025(F, sep, ...) \ + Z_UTIL_LISTIFY_3024(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3024, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3026(F, sep, ...) \ + Z_UTIL_LISTIFY_3025(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3025, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3027(F, sep, ...) \ + Z_UTIL_LISTIFY_3026(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3026, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3028(F, sep, ...) \ + Z_UTIL_LISTIFY_3027(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3027, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3029(F, sep, ...) \ + Z_UTIL_LISTIFY_3028(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3028, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3030(F, sep, ...) \ + Z_UTIL_LISTIFY_3029(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3029, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3031(F, sep, ...) \ + Z_UTIL_LISTIFY_3030(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3030, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3032(F, sep, ...) \ + Z_UTIL_LISTIFY_3031(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3031, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3033(F, sep, ...) \ + Z_UTIL_LISTIFY_3032(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3032, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3034(F, sep, ...) \ + Z_UTIL_LISTIFY_3033(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3033, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3035(F, sep, ...) \ + Z_UTIL_LISTIFY_3034(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3034, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3036(F, sep, ...) \ + Z_UTIL_LISTIFY_3035(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3035, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3037(F, sep, ...) \ + Z_UTIL_LISTIFY_3036(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3036, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3038(F, sep, ...) \ + Z_UTIL_LISTIFY_3037(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3037, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3039(F, sep, ...) \ + Z_UTIL_LISTIFY_3038(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3038, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3040(F, sep, ...) \ + Z_UTIL_LISTIFY_3039(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3039, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3041(F, sep, ...) \ + Z_UTIL_LISTIFY_3040(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3040, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3042(F, sep, ...) \ + Z_UTIL_LISTIFY_3041(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3041, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3043(F, sep, ...) \ + Z_UTIL_LISTIFY_3042(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3042, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3044(F, sep, ...) \ + Z_UTIL_LISTIFY_3043(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3043, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3045(F, sep, ...) \ + Z_UTIL_LISTIFY_3044(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3044, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3046(F, sep, ...) \ + Z_UTIL_LISTIFY_3045(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3045, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3047(F, sep, ...) \ + Z_UTIL_LISTIFY_3046(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3046, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3048(F, sep, ...) \ + Z_UTIL_LISTIFY_3047(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3047, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3049(F, sep, ...) \ + Z_UTIL_LISTIFY_3048(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3048, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3050(F, sep, ...) \ + Z_UTIL_LISTIFY_3049(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3049, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3051(F, sep, ...) \ + Z_UTIL_LISTIFY_3050(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3050, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3052(F, sep, ...) \ + Z_UTIL_LISTIFY_3051(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3051, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3053(F, sep, ...) \ + Z_UTIL_LISTIFY_3052(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3052, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3054(F, sep, ...) \ + Z_UTIL_LISTIFY_3053(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3053, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3055(F, sep, ...) \ + Z_UTIL_LISTIFY_3054(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3054, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3056(F, sep, ...) \ + Z_UTIL_LISTIFY_3055(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3055, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3057(F, sep, ...) \ + Z_UTIL_LISTIFY_3056(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3056, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3058(F, sep, ...) \ + Z_UTIL_LISTIFY_3057(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3057, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3059(F, sep, ...) \ + Z_UTIL_LISTIFY_3058(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3058, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3060(F, sep, ...) \ + Z_UTIL_LISTIFY_3059(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3059, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3061(F, sep, ...) \ + Z_UTIL_LISTIFY_3060(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3060, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3062(F, sep, ...) \ + Z_UTIL_LISTIFY_3061(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3061, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3063(F, sep, ...) \ + Z_UTIL_LISTIFY_3062(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3062, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3064(F, sep, ...) \ + Z_UTIL_LISTIFY_3063(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3063, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3065(F, sep, ...) \ + Z_UTIL_LISTIFY_3064(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3064, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3066(F, sep, ...) \ + Z_UTIL_LISTIFY_3065(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3065, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3067(F, sep, ...) \ + Z_UTIL_LISTIFY_3066(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3066, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3068(F, sep, ...) \ + Z_UTIL_LISTIFY_3067(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3067, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3069(F, sep, ...) \ + Z_UTIL_LISTIFY_3068(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3068, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3070(F, sep, ...) \ + Z_UTIL_LISTIFY_3069(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3069, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3071(F, sep, ...) \ + Z_UTIL_LISTIFY_3070(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3070, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3072(F, sep, ...) \ + Z_UTIL_LISTIFY_3071(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3071, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3073(F, sep, ...) \ + Z_UTIL_LISTIFY_3072(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3072, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3074(F, sep, ...) \ + Z_UTIL_LISTIFY_3073(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3073, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3075(F, sep, ...) \ + Z_UTIL_LISTIFY_3074(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3074, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3076(F, sep, ...) \ + Z_UTIL_LISTIFY_3075(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3075, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3077(F, sep, ...) \ + Z_UTIL_LISTIFY_3076(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3076, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3078(F, sep, ...) \ + Z_UTIL_LISTIFY_3077(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3077, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3079(F, sep, ...) \ + Z_UTIL_LISTIFY_3078(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3078, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3080(F, sep, ...) \ + Z_UTIL_LISTIFY_3079(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3079, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3081(F, sep, ...) \ + Z_UTIL_LISTIFY_3080(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3080, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3082(F, sep, ...) \ + Z_UTIL_LISTIFY_3081(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3081, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3083(F, sep, ...) \ + Z_UTIL_LISTIFY_3082(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3082, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3084(F, sep, ...) \ + Z_UTIL_LISTIFY_3083(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3083, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3085(F, sep, ...) \ + Z_UTIL_LISTIFY_3084(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3084, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3086(F, sep, ...) \ + Z_UTIL_LISTIFY_3085(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3085, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3087(F, sep, ...) \ + Z_UTIL_LISTIFY_3086(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3086, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3088(F, sep, ...) \ + Z_UTIL_LISTIFY_3087(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3087, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3089(F, sep, ...) \ + Z_UTIL_LISTIFY_3088(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3088, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3090(F, sep, ...) \ + Z_UTIL_LISTIFY_3089(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3089, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3091(F, sep, ...) \ + Z_UTIL_LISTIFY_3090(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3090, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3092(F, sep, ...) \ + Z_UTIL_LISTIFY_3091(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3091, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3093(F, sep, ...) \ + Z_UTIL_LISTIFY_3092(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3092, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3094(F, sep, ...) \ + Z_UTIL_LISTIFY_3093(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3093, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3095(F, sep, ...) \ + Z_UTIL_LISTIFY_3094(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3094, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3096(F, sep, ...) \ + Z_UTIL_LISTIFY_3095(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3095, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3097(F, sep, ...) \ + Z_UTIL_LISTIFY_3096(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3096, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3098(F, sep, ...) \ + Z_UTIL_LISTIFY_3097(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3097, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3099(F, sep, ...) \ + Z_UTIL_LISTIFY_3098(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3098, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3100(F, sep, ...) \ + Z_UTIL_LISTIFY_3099(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3099, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3101(F, sep, ...) \ + Z_UTIL_LISTIFY_3100(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3100, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3102(F, sep, ...) \ + Z_UTIL_LISTIFY_3101(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3101, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3103(F, sep, ...) \ + Z_UTIL_LISTIFY_3102(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3102, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3104(F, sep, ...) \ + Z_UTIL_LISTIFY_3103(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3103, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3105(F, sep, ...) \ + Z_UTIL_LISTIFY_3104(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3104, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3106(F, sep, ...) \ + Z_UTIL_LISTIFY_3105(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3105, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3107(F, sep, ...) \ + Z_UTIL_LISTIFY_3106(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3106, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3108(F, sep, ...) \ + Z_UTIL_LISTIFY_3107(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3107, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3109(F, sep, ...) \ + Z_UTIL_LISTIFY_3108(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3108, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3110(F, sep, ...) \ + Z_UTIL_LISTIFY_3109(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3109, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3111(F, sep, ...) \ + Z_UTIL_LISTIFY_3110(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3110, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3112(F, sep, ...) \ + Z_UTIL_LISTIFY_3111(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3111, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3113(F, sep, ...) \ + Z_UTIL_LISTIFY_3112(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3112, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3114(F, sep, ...) \ + Z_UTIL_LISTIFY_3113(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3113, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3115(F, sep, ...) \ + Z_UTIL_LISTIFY_3114(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3114, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3116(F, sep, ...) \ + Z_UTIL_LISTIFY_3115(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3115, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3117(F, sep, ...) \ + Z_UTIL_LISTIFY_3116(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3116, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3118(F, sep, ...) \ + Z_UTIL_LISTIFY_3117(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3117, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3119(F, sep, ...) \ + Z_UTIL_LISTIFY_3118(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3118, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3120(F, sep, ...) \ + Z_UTIL_LISTIFY_3119(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3119, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3121(F, sep, ...) \ + Z_UTIL_LISTIFY_3120(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3120, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3122(F, sep, ...) \ + Z_UTIL_LISTIFY_3121(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3121, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3123(F, sep, ...) \ + Z_UTIL_LISTIFY_3122(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3122, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3124(F, sep, ...) \ + Z_UTIL_LISTIFY_3123(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3123, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3125(F, sep, ...) \ + Z_UTIL_LISTIFY_3124(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3124, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3126(F, sep, ...) \ + Z_UTIL_LISTIFY_3125(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3125, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3127(F, sep, ...) \ + Z_UTIL_LISTIFY_3126(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3126, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3128(F, sep, ...) \ + Z_UTIL_LISTIFY_3127(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3127, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3129(F, sep, ...) \ + Z_UTIL_LISTIFY_3128(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3128, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3130(F, sep, ...) \ + Z_UTIL_LISTIFY_3129(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3129, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3131(F, sep, ...) \ + Z_UTIL_LISTIFY_3130(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3130, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3132(F, sep, ...) \ + Z_UTIL_LISTIFY_3131(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3131, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3133(F, sep, ...) \ + Z_UTIL_LISTIFY_3132(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3132, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3134(F, sep, ...) \ + Z_UTIL_LISTIFY_3133(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3133, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3135(F, sep, ...) \ + Z_UTIL_LISTIFY_3134(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3134, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3136(F, sep, ...) \ + Z_UTIL_LISTIFY_3135(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3135, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3137(F, sep, ...) \ + Z_UTIL_LISTIFY_3136(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3136, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3138(F, sep, ...) \ + Z_UTIL_LISTIFY_3137(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3137, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3139(F, sep, ...) \ + Z_UTIL_LISTIFY_3138(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3138, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3140(F, sep, ...) \ + Z_UTIL_LISTIFY_3139(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3139, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3141(F, sep, ...) \ + Z_UTIL_LISTIFY_3140(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3140, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3142(F, sep, ...) \ + Z_UTIL_LISTIFY_3141(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3141, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3143(F, sep, ...) \ + Z_UTIL_LISTIFY_3142(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3142, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3144(F, sep, ...) \ + Z_UTIL_LISTIFY_3143(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3143, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3145(F, sep, ...) \ + Z_UTIL_LISTIFY_3144(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3144, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3146(F, sep, ...) \ + Z_UTIL_LISTIFY_3145(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3145, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3147(F, sep, ...) \ + Z_UTIL_LISTIFY_3146(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3146, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3148(F, sep, ...) \ + Z_UTIL_LISTIFY_3147(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3147, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3149(F, sep, ...) \ + Z_UTIL_LISTIFY_3148(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3148, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3150(F, sep, ...) \ + Z_UTIL_LISTIFY_3149(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3149, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3151(F, sep, ...) \ + Z_UTIL_LISTIFY_3150(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3150, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3152(F, sep, ...) \ + Z_UTIL_LISTIFY_3151(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3151, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3153(F, sep, ...) \ + Z_UTIL_LISTIFY_3152(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3152, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3154(F, sep, ...) \ + Z_UTIL_LISTIFY_3153(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3153, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3155(F, sep, ...) \ + Z_UTIL_LISTIFY_3154(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3154, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3156(F, sep, ...) \ + Z_UTIL_LISTIFY_3155(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3155, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3157(F, sep, ...) \ + Z_UTIL_LISTIFY_3156(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3156, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3158(F, sep, ...) \ + Z_UTIL_LISTIFY_3157(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3157, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3159(F, sep, ...) \ + Z_UTIL_LISTIFY_3158(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3158, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3160(F, sep, ...) \ + Z_UTIL_LISTIFY_3159(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3159, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3161(F, sep, ...) \ + Z_UTIL_LISTIFY_3160(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3160, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3162(F, sep, ...) \ + Z_UTIL_LISTIFY_3161(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3161, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3163(F, sep, ...) \ + Z_UTIL_LISTIFY_3162(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3162, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3164(F, sep, ...) \ + Z_UTIL_LISTIFY_3163(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3163, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3165(F, sep, ...) \ + Z_UTIL_LISTIFY_3164(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3164, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3166(F, sep, ...) \ + Z_UTIL_LISTIFY_3165(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3165, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3167(F, sep, ...) \ + Z_UTIL_LISTIFY_3166(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3166, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3168(F, sep, ...) \ + Z_UTIL_LISTIFY_3167(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3167, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3169(F, sep, ...) \ + Z_UTIL_LISTIFY_3168(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3168, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3170(F, sep, ...) \ + Z_UTIL_LISTIFY_3169(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3169, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3171(F, sep, ...) \ + Z_UTIL_LISTIFY_3170(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3170, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3172(F, sep, ...) \ + Z_UTIL_LISTIFY_3171(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3171, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3173(F, sep, ...) \ + Z_UTIL_LISTIFY_3172(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3172, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3174(F, sep, ...) \ + Z_UTIL_LISTIFY_3173(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3173, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3175(F, sep, ...) \ + Z_UTIL_LISTIFY_3174(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3174, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3176(F, sep, ...) \ + Z_UTIL_LISTIFY_3175(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3175, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3177(F, sep, ...) \ + Z_UTIL_LISTIFY_3176(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3176, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3178(F, sep, ...) \ + Z_UTIL_LISTIFY_3177(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3177, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3179(F, sep, ...) \ + Z_UTIL_LISTIFY_3178(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3178, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3180(F, sep, ...) \ + Z_UTIL_LISTIFY_3179(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3179, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3181(F, sep, ...) \ + Z_UTIL_LISTIFY_3180(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3180, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3182(F, sep, ...) \ + Z_UTIL_LISTIFY_3181(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3181, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3183(F, sep, ...) \ + Z_UTIL_LISTIFY_3182(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3182, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3184(F, sep, ...) \ + Z_UTIL_LISTIFY_3183(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3183, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3185(F, sep, ...) \ + Z_UTIL_LISTIFY_3184(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3184, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3186(F, sep, ...) \ + Z_UTIL_LISTIFY_3185(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3185, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3187(F, sep, ...) \ + Z_UTIL_LISTIFY_3186(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3186, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3188(F, sep, ...) \ + Z_UTIL_LISTIFY_3187(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3187, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3189(F, sep, ...) \ + Z_UTIL_LISTIFY_3188(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3188, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3190(F, sep, ...) \ + Z_UTIL_LISTIFY_3189(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3189, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3191(F, sep, ...) \ + Z_UTIL_LISTIFY_3190(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3190, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3192(F, sep, ...) \ + Z_UTIL_LISTIFY_3191(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3191, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3193(F, sep, ...) \ + Z_UTIL_LISTIFY_3192(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3192, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3194(F, sep, ...) \ + Z_UTIL_LISTIFY_3193(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3193, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3195(F, sep, ...) \ + Z_UTIL_LISTIFY_3194(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3194, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3196(F, sep, ...) \ + Z_UTIL_LISTIFY_3195(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3195, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3197(F, sep, ...) \ + Z_UTIL_LISTIFY_3196(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3196, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3198(F, sep, ...) \ + Z_UTIL_LISTIFY_3197(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3197, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3199(F, sep, ...) \ + Z_UTIL_LISTIFY_3198(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3198, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3200(F, sep, ...) \ + Z_UTIL_LISTIFY_3199(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3199, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3201(F, sep, ...) \ + Z_UTIL_LISTIFY_3200(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3200, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3202(F, sep, ...) \ + Z_UTIL_LISTIFY_3201(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3201, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3203(F, sep, ...) \ + Z_UTIL_LISTIFY_3202(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3202, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3204(F, sep, ...) \ + Z_UTIL_LISTIFY_3203(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3203, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3205(F, sep, ...) \ + Z_UTIL_LISTIFY_3204(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3204, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3206(F, sep, ...) \ + Z_UTIL_LISTIFY_3205(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3205, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3207(F, sep, ...) \ + Z_UTIL_LISTIFY_3206(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3206, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3208(F, sep, ...) \ + Z_UTIL_LISTIFY_3207(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3207, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3209(F, sep, ...) \ + Z_UTIL_LISTIFY_3208(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3208, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3210(F, sep, ...) \ + Z_UTIL_LISTIFY_3209(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3209, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3211(F, sep, ...) \ + Z_UTIL_LISTIFY_3210(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3210, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3212(F, sep, ...) \ + Z_UTIL_LISTIFY_3211(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3211, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3213(F, sep, ...) \ + Z_UTIL_LISTIFY_3212(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3212, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3214(F, sep, ...) \ + Z_UTIL_LISTIFY_3213(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3213, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3215(F, sep, ...) \ + Z_UTIL_LISTIFY_3214(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3214, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3216(F, sep, ...) \ + Z_UTIL_LISTIFY_3215(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3215, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3217(F, sep, ...) \ + Z_UTIL_LISTIFY_3216(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3216, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3218(F, sep, ...) \ + Z_UTIL_LISTIFY_3217(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3217, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3219(F, sep, ...) \ + Z_UTIL_LISTIFY_3218(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3218, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3220(F, sep, ...) \ + Z_UTIL_LISTIFY_3219(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3219, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3221(F, sep, ...) \ + Z_UTIL_LISTIFY_3220(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3220, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3222(F, sep, ...) \ + Z_UTIL_LISTIFY_3221(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3221, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3223(F, sep, ...) \ + Z_UTIL_LISTIFY_3222(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3222, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3224(F, sep, ...) \ + Z_UTIL_LISTIFY_3223(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3223, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3225(F, sep, ...) \ + Z_UTIL_LISTIFY_3224(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3224, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3226(F, sep, ...) \ + Z_UTIL_LISTIFY_3225(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3225, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3227(F, sep, ...) \ + Z_UTIL_LISTIFY_3226(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3226, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3228(F, sep, ...) \ + Z_UTIL_LISTIFY_3227(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3227, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3229(F, sep, ...) \ + Z_UTIL_LISTIFY_3228(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3228, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3230(F, sep, ...) \ + Z_UTIL_LISTIFY_3229(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3229, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3231(F, sep, ...) \ + Z_UTIL_LISTIFY_3230(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3230, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3232(F, sep, ...) \ + Z_UTIL_LISTIFY_3231(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3231, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3233(F, sep, ...) \ + Z_UTIL_LISTIFY_3232(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3232, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3234(F, sep, ...) \ + Z_UTIL_LISTIFY_3233(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3233, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3235(F, sep, ...) \ + Z_UTIL_LISTIFY_3234(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3234, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3236(F, sep, ...) \ + Z_UTIL_LISTIFY_3235(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3235, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3237(F, sep, ...) \ + Z_UTIL_LISTIFY_3236(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3236, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3238(F, sep, ...) \ + Z_UTIL_LISTIFY_3237(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3237, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3239(F, sep, ...) \ + Z_UTIL_LISTIFY_3238(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3238, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3240(F, sep, ...) \ + Z_UTIL_LISTIFY_3239(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3239, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3241(F, sep, ...) \ + Z_UTIL_LISTIFY_3240(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3240, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3242(F, sep, ...) \ + Z_UTIL_LISTIFY_3241(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3241, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3243(F, sep, ...) \ + Z_UTIL_LISTIFY_3242(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3242, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3244(F, sep, ...) \ + Z_UTIL_LISTIFY_3243(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3243, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3245(F, sep, ...) \ + Z_UTIL_LISTIFY_3244(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3244, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3246(F, sep, ...) \ + Z_UTIL_LISTIFY_3245(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3245, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3247(F, sep, ...) \ + Z_UTIL_LISTIFY_3246(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3246, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3248(F, sep, ...) \ + Z_UTIL_LISTIFY_3247(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3247, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3249(F, sep, ...) \ + Z_UTIL_LISTIFY_3248(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3248, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3250(F, sep, ...) \ + Z_UTIL_LISTIFY_3249(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3249, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3251(F, sep, ...) \ + Z_UTIL_LISTIFY_3250(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3250, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3252(F, sep, ...) \ + Z_UTIL_LISTIFY_3251(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3251, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3253(F, sep, ...) \ + Z_UTIL_LISTIFY_3252(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3252, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3254(F, sep, ...) \ + Z_UTIL_LISTIFY_3253(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3253, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3255(F, sep, ...) \ + Z_UTIL_LISTIFY_3254(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3254, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3256(F, sep, ...) \ + Z_UTIL_LISTIFY_3255(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3255, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3257(F, sep, ...) \ + Z_UTIL_LISTIFY_3256(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3256, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3258(F, sep, ...) \ + Z_UTIL_LISTIFY_3257(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3257, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3259(F, sep, ...) \ + Z_UTIL_LISTIFY_3258(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3258, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3260(F, sep, ...) \ + Z_UTIL_LISTIFY_3259(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3259, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3261(F, sep, ...) \ + Z_UTIL_LISTIFY_3260(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3260, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3262(F, sep, ...) \ + Z_UTIL_LISTIFY_3261(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3261, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3263(F, sep, ...) \ + Z_UTIL_LISTIFY_3262(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3262, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3264(F, sep, ...) \ + Z_UTIL_LISTIFY_3263(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3263, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3265(F, sep, ...) \ + Z_UTIL_LISTIFY_3264(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3264, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3266(F, sep, ...) \ + Z_UTIL_LISTIFY_3265(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3265, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3267(F, sep, ...) \ + Z_UTIL_LISTIFY_3266(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3266, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3268(F, sep, ...) \ + Z_UTIL_LISTIFY_3267(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3267, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3269(F, sep, ...) \ + Z_UTIL_LISTIFY_3268(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3268, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3270(F, sep, ...) \ + Z_UTIL_LISTIFY_3269(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3269, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3271(F, sep, ...) \ + Z_UTIL_LISTIFY_3270(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3270, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3272(F, sep, ...) \ + Z_UTIL_LISTIFY_3271(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3271, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3273(F, sep, ...) \ + Z_UTIL_LISTIFY_3272(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3272, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3274(F, sep, ...) \ + Z_UTIL_LISTIFY_3273(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3273, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3275(F, sep, ...) \ + Z_UTIL_LISTIFY_3274(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3274, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3276(F, sep, ...) \ + Z_UTIL_LISTIFY_3275(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3275, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3277(F, sep, ...) \ + Z_UTIL_LISTIFY_3276(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3276, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3278(F, sep, ...) \ + Z_UTIL_LISTIFY_3277(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3277, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3279(F, sep, ...) \ + Z_UTIL_LISTIFY_3278(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3278, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3280(F, sep, ...) \ + Z_UTIL_LISTIFY_3279(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3279, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3281(F, sep, ...) \ + Z_UTIL_LISTIFY_3280(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3280, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3282(F, sep, ...) \ + Z_UTIL_LISTIFY_3281(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3281, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3283(F, sep, ...) \ + Z_UTIL_LISTIFY_3282(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3282, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3284(F, sep, ...) \ + Z_UTIL_LISTIFY_3283(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3283, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3285(F, sep, ...) \ + Z_UTIL_LISTIFY_3284(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3284, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3286(F, sep, ...) \ + Z_UTIL_LISTIFY_3285(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3285, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3287(F, sep, ...) \ + Z_UTIL_LISTIFY_3286(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3286, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3288(F, sep, ...) \ + Z_UTIL_LISTIFY_3287(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3287, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3289(F, sep, ...) \ + Z_UTIL_LISTIFY_3288(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3288, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3290(F, sep, ...) \ + Z_UTIL_LISTIFY_3289(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3289, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3291(F, sep, ...) \ + Z_UTIL_LISTIFY_3290(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3290, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3292(F, sep, ...) \ + Z_UTIL_LISTIFY_3291(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3291, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3293(F, sep, ...) \ + Z_UTIL_LISTIFY_3292(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3292, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3294(F, sep, ...) \ + Z_UTIL_LISTIFY_3293(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3293, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3295(F, sep, ...) \ + Z_UTIL_LISTIFY_3294(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3294, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3296(F, sep, ...) \ + Z_UTIL_LISTIFY_3295(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3295, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3297(F, sep, ...) \ + Z_UTIL_LISTIFY_3296(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3296, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3298(F, sep, ...) \ + Z_UTIL_LISTIFY_3297(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3297, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3299(F, sep, ...) \ + Z_UTIL_LISTIFY_3298(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3298, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3300(F, sep, ...) \ + Z_UTIL_LISTIFY_3299(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3299, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3301(F, sep, ...) \ + Z_UTIL_LISTIFY_3300(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3300, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3302(F, sep, ...) \ + Z_UTIL_LISTIFY_3301(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3301, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3303(F, sep, ...) \ + Z_UTIL_LISTIFY_3302(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3302, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3304(F, sep, ...) \ + Z_UTIL_LISTIFY_3303(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3303, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3305(F, sep, ...) \ + Z_UTIL_LISTIFY_3304(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3304, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3306(F, sep, ...) \ + Z_UTIL_LISTIFY_3305(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3305, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3307(F, sep, ...) \ + Z_UTIL_LISTIFY_3306(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3306, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3308(F, sep, ...) \ + Z_UTIL_LISTIFY_3307(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3307, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3309(F, sep, ...) \ + Z_UTIL_LISTIFY_3308(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3308, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3310(F, sep, ...) \ + Z_UTIL_LISTIFY_3309(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3309, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3311(F, sep, ...) \ + Z_UTIL_LISTIFY_3310(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3310, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3312(F, sep, ...) \ + Z_UTIL_LISTIFY_3311(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3311, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3313(F, sep, ...) \ + Z_UTIL_LISTIFY_3312(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3312, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3314(F, sep, ...) \ + Z_UTIL_LISTIFY_3313(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3313, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3315(F, sep, ...) \ + Z_UTIL_LISTIFY_3314(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3314, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3316(F, sep, ...) \ + Z_UTIL_LISTIFY_3315(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3315, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3317(F, sep, ...) \ + Z_UTIL_LISTIFY_3316(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3316, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3318(F, sep, ...) \ + Z_UTIL_LISTIFY_3317(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3317, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3319(F, sep, ...) \ + Z_UTIL_LISTIFY_3318(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3318, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3320(F, sep, ...) \ + Z_UTIL_LISTIFY_3319(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3319, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3321(F, sep, ...) \ + Z_UTIL_LISTIFY_3320(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3320, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3322(F, sep, ...) \ + Z_UTIL_LISTIFY_3321(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3321, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3323(F, sep, ...) \ + Z_UTIL_LISTIFY_3322(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3322, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3324(F, sep, ...) \ + Z_UTIL_LISTIFY_3323(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3323, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3325(F, sep, ...) \ + Z_UTIL_LISTIFY_3324(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3324, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3326(F, sep, ...) \ + Z_UTIL_LISTIFY_3325(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3325, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3327(F, sep, ...) \ + Z_UTIL_LISTIFY_3326(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3326, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3328(F, sep, ...) \ + Z_UTIL_LISTIFY_3327(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3327, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3329(F, sep, ...) \ + Z_UTIL_LISTIFY_3328(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3328, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3330(F, sep, ...) \ + Z_UTIL_LISTIFY_3329(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3329, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3331(F, sep, ...) \ + Z_UTIL_LISTIFY_3330(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3330, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3332(F, sep, ...) \ + Z_UTIL_LISTIFY_3331(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3331, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3333(F, sep, ...) \ + Z_UTIL_LISTIFY_3332(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3332, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3334(F, sep, ...) \ + Z_UTIL_LISTIFY_3333(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3333, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3335(F, sep, ...) \ + Z_UTIL_LISTIFY_3334(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3334, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3336(F, sep, ...) \ + Z_UTIL_LISTIFY_3335(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3335, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3337(F, sep, ...) \ + Z_UTIL_LISTIFY_3336(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3336, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3338(F, sep, ...) \ + Z_UTIL_LISTIFY_3337(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3337, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3339(F, sep, ...) \ + Z_UTIL_LISTIFY_3338(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3338, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3340(F, sep, ...) \ + Z_UTIL_LISTIFY_3339(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3339, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3341(F, sep, ...) \ + Z_UTIL_LISTIFY_3340(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3340, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3342(F, sep, ...) \ + Z_UTIL_LISTIFY_3341(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3341, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3343(F, sep, ...) \ + Z_UTIL_LISTIFY_3342(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3342, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3344(F, sep, ...) \ + Z_UTIL_LISTIFY_3343(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3343, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3345(F, sep, ...) \ + Z_UTIL_LISTIFY_3344(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3344, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3346(F, sep, ...) \ + Z_UTIL_LISTIFY_3345(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3345, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3347(F, sep, ...) \ + Z_UTIL_LISTIFY_3346(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3346, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3348(F, sep, ...) \ + Z_UTIL_LISTIFY_3347(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3347, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3349(F, sep, ...) \ + Z_UTIL_LISTIFY_3348(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3348, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3350(F, sep, ...) \ + Z_UTIL_LISTIFY_3349(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3349, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3351(F, sep, ...) \ + Z_UTIL_LISTIFY_3350(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3350, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3352(F, sep, ...) \ + Z_UTIL_LISTIFY_3351(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3351, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3353(F, sep, ...) \ + Z_UTIL_LISTIFY_3352(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3352, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3354(F, sep, ...) \ + Z_UTIL_LISTIFY_3353(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3353, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3355(F, sep, ...) \ + Z_UTIL_LISTIFY_3354(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3354, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3356(F, sep, ...) \ + Z_UTIL_LISTIFY_3355(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3355, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3357(F, sep, ...) \ + Z_UTIL_LISTIFY_3356(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3356, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3358(F, sep, ...) \ + Z_UTIL_LISTIFY_3357(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3357, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3359(F, sep, ...) \ + Z_UTIL_LISTIFY_3358(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3358, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3360(F, sep, ...) \ + Z_UTIL_LISTIFY_3359(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3359, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3361(F, sep, ...) \ + Z_UTIL_LISTIFY_3360(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3360, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3362(F, sep, ...) \ + Z_UTIL_LISTIFY_3361(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3361, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3363(F, sep, ...) \ + Z_UTIL_LISTIFY_3362(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3362, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3364(F, sep, ...) \ + Z_UTIL_LISTIFY_3363(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3363, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3365(F, sep, ...) \ + Z_UTIL_LISTIFY_3364(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3364, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3366(F, sep, ...) \ + Z_UTIL_LISTIFY_3365(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3365, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3367(F, sep, ...) \ + Z_UTIL_LISTIFY_3366(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3366, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3368(F, sep, ...) \ + Z_UTIL_LISTIFY_3367(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3367, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3369(F, sep, ...) \ + Z_UTIL_LISTIFY_3368(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3368, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3370(F, sep, ...) \ + Z_UTIL_LISTIFY_3369(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3369, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3371(F, sep, ...) \ + Z_UTIL_LISTIFY_3370(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3370, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3372(F, sep, ...) \ + Z_UTIL_LISTIFY_3371(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3371, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3373(F, sep, ...) \ + Z_UTIL_LISTIFY_3372(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3372, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3374(F, sep, ...) \ + Z_UTIL_LISTIFY_3373(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3373, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3375(F, sep, ...) \ + Z_UTIL_LISTIFY_3374(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3374, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3376(F, sep, ...) \ + Z_UTIL_LISTIFY_3375(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3375, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3377(F, sep, ...) \ + Z_UTIL_LISTIFY_3376(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3376, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3378(F, sep, ...) \ + Z_UTIL_LISTIFY_3377(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3377, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3379(F, sep, ...) \ + Z_UTIL_LISTIFY_3378(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3378, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3380(F, sep, ...) \ + Z_UTIL_LISTIFY_3379(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3379, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3381(F, sep, ...) \ + Z_UTIL_LISTIFY_3380(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3380, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3382(F, sep, ...) \ + Z_UTIL_LISTIFY_3381(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3381, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3383(F, sep, ...) \ + Z_UTIL_LISTIFY_3382(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3382, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3384(F, sep, ...) \ + Z_UTIL_LISTIFY_3383(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3383, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3385(F, sep, ...) \ + Z_UTIL_LISTIFY_3384(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3384, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3386(F, sep, ...) \ + Z_UTIL_LISTIFY_3385(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3385, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3387(F, sep, ...) \ + Z_UTIL_LISTIFY_3386(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3386, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3388(F, sep, ...) \ + Z_UTIL_LISTIFY_3387(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3387, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3389(F, sep, ...) \ + Z_UTIL_LISTIFY_3388(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3388, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3390(F, sep, ...) \ + Z_UTIL_LISTIFY_3389(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3389, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3391(F, sep, ...) \ + Z_UTIL_LISTIFY_3390(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3390, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3392(F, sep, ...) \ + Z_UTIL_LISTIFY_3391(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3391, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3393(F, sep, ...) \ + Z_UTIL_LISTIFY_3392(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3392, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3394(F, sep, ...) \ + Z_UTIL_LISTIFY_3393(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3393, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3395(F, sep, ...) \ + Z_UTIL_LISTIFY_3394(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3394, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3396(F, sep, ...) \ + Z_UTIL_LISTIFY_3395(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3395, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3397(F, sep, ...) \ + Z_UTIL_LISTIFY_3396(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3396, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3398(F, sep, ...) \ + Z_UTIL_LISTIFY_3397(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3397, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3399(F, sep, ...) \ + Z_UTIL_LISTIFY_3398(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3398, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3400(F, sep, ...) \ + Z_UTIL_LISTIFY_3399(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3399, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3401(F, sep, ...) \ + Z_UTIL_LISTIFY_3400(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3400, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3402(F, sep, ...) \ + Z_UTIL_LISTIFY_3401(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3401, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3403(F, sep, ...) \ + Z_UTIL_LISTIFY_3402(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3402, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3404(F, sep, ...) \ + Z_UTIL_LISTIFY_3403(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3403, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3405(F, sep, ...) \ + Z_UTIL_LISTIFY_3404(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3404, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3406(F, sep, ...) \ + Z_UTIL_LISTIFY_3405(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3405, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3407(F, sep, ...) \ + Z_UTIL_LISTIFY_3406(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3406, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3408(F, sep, ...) \ + Z_UTIL_LISTIFY_3407(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3407, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3409(F, sep, ...) \ + Z_UTIL_LISTIFY_3408(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3408, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3410(F, sep, ...) \ + Z_UTIL_LISTIFY_3409(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3409, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3411(F, sep, ...) \ + Z_UTIL_LISTIFY_3410(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3410, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3412(F, sep, ...) \ + Z_UTIL_LISTIFY_3411(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3411, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3413(F, sep, ...) \ + Z_UTIL_LISTIFY_3412(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3412, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3414(F, sep, ...) \ + Z_UTIL_LISTIFY_3413(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3413, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3415(F, sep, ...) \ + Z_UTIL_LISTIFY_3414(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3414, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3416(F, sep, ...) \ + Z_UTIL_LISTIFY_3415(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3415, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3417(F, sep, ...) \ + Z_UTIL_LISTIFY_3416(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3416, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3418(F, sep, ...) \ + Z_UTIL_LISTIFY_3417(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3417, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3419(F, sep, ...) \ + Z_UTIL_LISTIFY_3418(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3418, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3420(F, sep, ...) \ + Z_UTIL_LISTIFY_3419(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3419, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3421(F, sep, ...) \ + Z_UTIL_LISTIFY_3420(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3420, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3422(F, sep, ...) \ + Z_UTIL_LISTIFY_3421(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3421, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3423(F, sep, ...) \ + Z_UTIL_LISTIFY_3422(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3422, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3424(F, sep, ...) \ + Z_UTIL_LISTIFY_3423(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3423, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3425(F, sep, ...) \ + Z_UTIL_LISTIFY_3424(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3424, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3426(F, sep, ...) \ + Z_UTIL_LISTIFY_3425(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3425, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3427(F, sep, ...) \ + Z_UTIL_LISTIFY_3426(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3426, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3428(F, sep, ...) \ + Z_UTIL_LISTIFY_3427(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3427, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3429(F, sep, ...) \ + Z_UTIL_LISTIFY_3428(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3428, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3430(F, sep, ...) \ + Z_UTIL_LISTIFY_3429(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3429, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3431(F, sep, ...) \ + Z_UTIL_LISTIFY_3430(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3430, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3432(F, sep, ...) \ + Z_UTIL_LISTIFY_3431(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3431, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3433(F, sep, ...) \ + Z_UTIL_LISTIFY_3432(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3432, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3434(F, sep, ...) \ + Z_UTIL_LISTIFY_3433(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3433, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3435(F, sep, ...) \ + Z_UTIL_LISTIFY_3434(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3434, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3436(F, sep, ...) \ + Z_UTIL_LISTIFY_3435(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3435, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3437(F, sep, ...) \ + Z_UTIL_LISTIFY_3436(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3436, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3438(F, sep, ...) \ + Z_UTIL_LISTIFY_3437(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3437, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3439(F, sep, ...) \ + Z_UTIL_LISTIFY_3438(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3438, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3440(F, sep, ...) \ + Z_UTIL_LISTIFY_3439(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3439, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3441(F, sep, ...) \ + Z_UTIL_LISTIFY_3440(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3440, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3442(F, sep, ...) \ + Z_UTIL_LISTIFY_3441(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3441, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3443(F, sep, ...) \ + Z_UTIL_LISTIFY_3442(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3442, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3444(F, sep, ...) \ + Z_UTIL_LISTIFY_3443(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3443, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3445(F, sep, ...) \ + Z_UTIL_LISTIFY_3444(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3444, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3446(F, sep, ...) \ + Z_UTIL_LISTIFY_3445(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3445, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3447(F, sep, ...) \ + Z_UTIL_LISTIFY_3446(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3446, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3448(F, sep, ...) \ + Z_UTIL_LISTIFY_3447(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3447, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3449(F, sep, ...) \ + Z_UTIL_LISTIFY_3448(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3448, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3450(F, sep, ...) \ + Z_UTIL_LISTIFY_3449(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3449, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3451(F, sep, ...) \ + Z_UTIL_LISTIFY_3450(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3450, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3452(F, sep, ...) \ + Z_UTIL_LISTIFY_3451(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3451, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3453(F, sep, ...) \ + Z_UTIL_LISTIFY_3452(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3452, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3454(F, sep, ...) \ + Z_UTIL_LISTIFY_3453(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3453, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3455(F, sep, ...) \ + Z_UTIL_LISTIFY_3454(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3454, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3456(F, sep, ...) \ + Z_UTIL_LISTIFY_3455(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3455, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3457(F, sep, ...) \ + Z_UTIL_LISTIFY_3456(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3456, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3458(F, sep, ...) \ + Z_UTIL_LISTIFY_3457(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3457, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3459(F, sep, ...) \ + Z_UTIL_LISTIFY_3458(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3458, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3460(F, sep, ...) \ + Z_UTIL_LISTIFY_3459(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3459, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3461(F, sep, ...) \ + Z_UTIL_LISTIFY_3460(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3460, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3462(F, sep, ...) \ + Z_UTIL_LISTIFY_3461(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3461, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3463(F, sep, ...) \ + Z_UTIL_LISTIFY_3462(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3462, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3464(F, sep, ...) \ + Z_UTIL_LISTIFY_3463(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3463, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3465(F, sep, ...) \ + Z_UTIL_LISTIFY_3464(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3464, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3466(F, sep, ...) \ + Z_UTIL_LISTIFY_3465(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3465, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3467(F, sep, ...) \ + Z_UTIL_LISTIFY_3466(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3466, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3468(F, sep, ...) \ + Z_UTIL_LISTIFY_3467(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3467, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3469(F, sep, ...) \ + Z_UTIL_LISTIFY_3468(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3468, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3470(F, sep, ...) \ + Z_UTIL_LISTIFY_3469(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3469, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3471(F, sep, ...) \ + Z_UTIL_LISTIFY_3470(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3470, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3472(F, sep, ...) \ + Z_UTIL_LISTIFY_3471(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3471, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3473(F, sep, ...) \ + Z_UTIL_LISTIFY_3472(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3472, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3474(F, sep, ...) \ + Z_UTIL_LISTIFY_3473(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3473, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3475(F, sep, ...) \ + Z_UTIL_LISTIFY_3474(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3474, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3476(F, sep, ...) \ + Z_UTIL_LISTIFY_3475(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3475, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3477(F, sep, ...) \ + Z_UTIL_LISTIFY_3476(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3476, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3478(F, sep, ...) \ + Z_UTIL_LISTIFY_3477(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3477, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3479(F, sep, ...) \ + Z_UTIL_LISTIFY_3478(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3478, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3480(F, sep, ...) \ + Z_UTIL_LISTIFY_3479(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3479, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3481(F, sep, ...) \ + Z_UTIL_LISTIFY_3480(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3480, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3482(F, sep, ...) \ + Z_UTIL_LISTIFY_3481(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3481, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3483(F, sep, ...) \ + Z_UTIL_LISTIFY_3482(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3482, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3484(F, sep, ...) \ + Z_UTIL_LISTIFY_3483(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3483, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3485(F, sep, ...) \ + Z_UTIL_LISTIFY_3484(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3484, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3486(F, sep, ...) \ + Z_UTIL_LISTIFY_3485(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3485, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3487(F, sep, ...) \ + Z_UTIL_LISTIFY_3486(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3486, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3488(F, sep, ...) \ + Z_UTIL_LISTIFY_3487(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3487, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3489(F, sep, ...) \ + Z_UTIL_LISTIFY_3488(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3488, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3490(F, sep, ...) \ + Z_UTIL_LISTIFY_3489(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3489, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3491(F, sep, ...) \ + Z_UTIL_LISTIFY_3490(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3490, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3492(F, sep, ...) \ + Z_UTIL_LISTIFY_3491(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3491, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3493(F, sep, ...) \ + Z_UTIL_LISTIFY_3492(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3492, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3494(F, sep, ...) \ + Z_UTIL_LISTIFY_3493(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3493, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3495(F, sep, ...) \ + Z_UTIL_LISTIFY_3494(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3494, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3496(F, sep, ...) \ + Z_UTIL_LISTIFY_3495(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3495, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3497(F, sep, ...) \ + Z_UTIL_LISTIFY_3496(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3496, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3498(F, sep, ...) \ + Z_UTIL_LISTIFY_3497(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3497, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3499(F, sep, ...) \ + Z_UTIL_LISTIFY_3498(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3498, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3500(F, sep, ...) \ + Z_UTIL_LISTIFY_3499(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3499, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3501(F, sep, ...) \ + Z_UTIL_LISTIFY_3500(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3500, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3502(F, sep, ...) \ + Z_UTIL_LISTIFY_3501(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3501, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3503(F, sep, ...) \ + Z_UTIL_LISTIFY_3502(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3502, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3504(F, sep, ...) \ + Z_UTIL_LISTIFY_3503(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3503, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3505(F, sep, ...) \ + Z_UTIL_LISTIFY_3504(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3504, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3506(F, sep, ...) \ + Z_UTIL_LISTIFY_3505(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3505, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3507(F, sep, ...) \ + Z_UTIL_LISTIFY_3506(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3506, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3508(F, sep, ...) \ + Z_UTIL_LISTIFY_3507(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3507, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3509(F, sep, ...) \ + Z_UTIL_LISTIFY_3508(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3508, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3510(F, sep, ...) \ + Z_UTIL_LISTIFY_3509(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3509, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3511(F, sep, ...) \ + Z_UTIL_LISTIFY_3510(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3510, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3512(F, sep, ...) \ + Z_UTIL_LISTIFY_3511(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3511, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3513(F, sep, ...) \ + Z_UTIL_LISTIFY_3512(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3512, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3514(F, sep, ...) \ + Z_UTIL_LISTIFY_3513(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3513, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3515(F, sep, ...) \ + Z_UTIL_LISTIFY_3514(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3514, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3516(F, sep, ...) \ + Z_UTIL_LISTIFY_3515(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3515, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3517(F, sep, ...) \ + Z_UTIL_LISTIFY_3516(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3516, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3518(F, sep, ...) \ + Z_UTIL_LISTIFY_3517(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3517, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3519(F, sep, ...) \ + Z_UTIL_LISTIFY_3518(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3518, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3520(F, sep, ...) \ + Z_UTIL_LISTIFY_3519(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3519, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3521(F, sep, ...) \ + Z_UTIL_LISTIFY_3520(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3520, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3522(F, sep, ...) \ + Z_UTIL_LISTIFY_3521(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3521, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3523(F, sep, ...) \ + Z_UTIL_LISTIFY_3522(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3522, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3524(F, sep, ...) \ + Z_UTIL_LISTIFY_3523(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3523, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3525(F, sep, ...) \ + Z_UTIL_LISTIFY_3524(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3524, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3526(F, sep, ...) \ + Z_UTIL_LISTIFY_3525(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3525, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3527(F, sep, ...) \ + Z_UTIL_LISTIFY_3526(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3526, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3528(F, sep, ...) \ + Z_UTIL_LISTIFY_3527(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3527, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3529(F, sep, ...) \ + Z_UTIL_LISTIFY_3528(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3528, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3530(F, sep, ...) \ + Z_UTIL_LISTIFY_3529(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3529, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3531(F, sep, ...) \ + Z_UTIL_LISTIFY_3530(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3530, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3532(F, sep, ...) \ + Z_UTIL_LISTIFY_3531(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3531, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3533(F, sep, ...) \ + Z_UTIL_LISTIFY_3532(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3532, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3534(F, sep, ...) \ + Z_UTIL_LISTIFY_3533(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3533, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3535(F, sep, ...) \ + Z_UTIL_LISTIFY_3534(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3534, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3536(F, sep, ...) \ + Z_UTIL_LISTIFY_3535(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3535, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3537(F, sep, ...) \ + Z_UTIL_LISTIFY_3536(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3536, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3538(F, sep, ...) \ + Z_UTIL_LISTIFY_3537(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3537, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3539(F, sep, ...) \ + Z_UTIL_LISTIFY_3538(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3538, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3540(F, sep, ...) \ + Z_UTIL_LISTIFY_3539(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3539, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3541(F, sep, ...) \ + Z_UTIL_LISTIFY_3540(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3540, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3542(F, sep, ...) \ + Z_UTIL_LISTIFY_3541(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3541, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3543(F, sep, ...) \ + Z_UTIL_LISTIFY_3542(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3542, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3544(F, sep, ...) \ + Z_UTIL_LISTIFY_3543(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3543, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3545(F, sep, ...) \ + Z_UTIL_LISTIFY_3544(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3544, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3546(F, sep, ...) \ + Z_UTIL_LISTIFY_3545(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3545, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3547(F, sep, ...) \ + Z_UTIL_LISTIFY_3546(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3546, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3548(F, sep, ...) \ + Z_UTIL_LISTIFY_3547(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3547, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3549(F, sep, ...) \ + Z_UTIL_LISTIFY_3548(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3548, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3550(F, sep, ...) \ + Z_UTIL_LISTIFY_3549(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3549, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3551(F, sep, ...) \ + Z_UTIL_LISTIFY_3550(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3550, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3552(F, sep, ...) \ + Z_UTIL_LISTIFY_3551(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3551, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3553(F, sep, ...) \ + Z_UTIL_LISTIFY_3552(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3552, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3554(F, sep, ...) \ + Z_UTIL_LISTIFY_3553(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3553, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3555(F, sep, ...) \ + Z_UTIL_LISTIFY_3554(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3554, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3556(F, sep, ...) \ + Z_UTIL_LISTIFY_3555(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3555, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3557(F, sep, ...) \ + Z_UTIL_LISTIFY_3556(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3556, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3558(F, sep, ...) \ + Z_UTIL_LISTIFY_3557(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3557, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3559(F, sep, ...) \ + Z_UTIL_LISTIFY_3558(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3558, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3560(F, sep, ...) \ + Z_UTIL_LISTIFY_3559(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3559, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3561(F, sep, ...) \ + Z_UTIL_LISTIFY_3560(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3560, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3562(F, sep, ...) \ + Z_UTIL_LISTIFY_3561(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3561, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3563(F, sep, ...) \ + Z_UTIL_LISTIFY_3562(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3562, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3564(F, sep, ...) \ + Z_UTIL_LISTIFY_3563(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3563, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3565(F, sep, ...) \ + Z_UTIL_LISTIFY_3564(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3564, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3566(F, sep, ...) \ + Z_UTIL_LISTIFY_3565(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3565, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3567(F, sep, ...) \ + Z_UTIL_LISTIFY_3566(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3566, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3568(F, sep, ...) \ + Z_UTIL_LISTIFY_3567(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3567, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3569(F, sep, ...) \ + Z_UTIL_LISTIFY_3568(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3568, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3570(F, sep, ...) \ + Z_UTIL_LISTIFY_3569(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3569, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3571(F, sep, ...) \ + Z_UTIL_LISTIFY_3570(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3570, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3572(F, sep, ...) \ + Z_UTIL_LISTIFY_3571(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3571, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3573(F, sep, ...) \ + Z_UTIL_LISTIFY_3572(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3572, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3574(F, sep, ...) \ + Z_UTIL_LISTIFY_3573(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3573, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3575(F, sep, ...) \ + Z_UTIL_LISTIFY_3574(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3574, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3576(F, sep, ...) \ + Z_UTIL_LISTIFY_3575(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3575, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3577(F, sep, ...) \ + Z_UTIL_LISTIFY_3576(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3576, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3578(F, sep, ...) \ + Z_UTIL_LISTIFY_3577(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3577, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3579(F, sep, ...) \ + Z_UTIL_LISTIFY_3578(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3578, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3580(F, sep, ...) \ + Z_UTIL_LISTIFY_3579(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3579, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3581(F, sep, ...) \ + Z_UTIL_LISTIFY_3580(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3580, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3582(F, sep, ...) \ + Z_UTIL_LISTIFY_3581(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3581, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3583(F, sep, ...) \ + Z_UTIL_LISTIFY_3582(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3582, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3584(F, sep, ...) \ + Z_UTIL_LISTIFY_3583(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3583, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3585(F, sep, ...) \ + Z_UTIL_LISTIFY_3584(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3584, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3586(F, sep, ...) \ + Z_UTIL_LISTIFY_3585(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3585, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3587(F, sep, ...) \ + Z_UTIL_LISTIFY_3586(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3586, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3588(F, sep, ...) \ + Z_UTIL_LISTIFY_3587(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3587, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3589(F, sep, ...) \ + Z_UTIL_LISTIFY_3588(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3588, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3590(F, sep, ...) \ + Z_UTIL_LISTIFY_3589(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3589, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3591(F, sep, ...) \ + Z_UTIL_LISTIFY_3590(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3590, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3592(F, sep, ...) \ + Z_UTIL_LISTIFY_3591(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3591, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3593(F, sep, ...) \ + Z_UTIL_LISTIFY_3592(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3592, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3594(F, sep, ...) \ + Z_UTIL_LISTIFY_3593(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3593, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3595(F, sep, ...) \ + Z_UTIL_LISTIFY_3594(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3594, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3596(F, sep, ...) \ + Z_UTIL_LISTIFY_3595(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3595, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3597(F, sep, ...) \ + Z_UTIL_LISTIFY_3596(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3596, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3598(F, sep, ...) \ + Z_UTIL_LISTIFY_3597(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3597, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3599(F, sep, ...) \ + Z_UTIL_LISTIFY_3598(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3598, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3600(F, sep, ...) \ + Z_UTIL_LISTIFY_3599(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3599, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3601(F, sep, ...) \ + Z_UTIL_LISTIFY_3600(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3600, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3602(F, sep, ...) \ + Z_UTIL_LISTIFY_3601(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3601, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3603(F, sep, ...) \ + Z_UTIL_LISTIFY_3602(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3602, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3604(F, sep, ...) \ + Z_UTIL_LISTIFY_3603(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3603, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3605(F, sep, ...) \ + Z_UTIL_LISTIFY_3604(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3604, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3606(F, sep, ...) \ + Z_UTIL_LISTIFY_3605(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3605, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3607(F, sep, ...) \ + Z_UTIL_LISTIFY_3606(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3606, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3608(F, sep, ...) \ + Z_UTIL_LISTIFY_3607(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3607, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3609(F, sep, ...) \ + Z_UTIL_LISTIFY_3608(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3608, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3610(F, sep, ...) \ + Z_UTIL_LISTIFY_3609(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3609, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3611(F, sep, ...) \ + Z_UTIL_LISTIFY_3610(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3610, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3612(F, sep, ...) \ + Z_UTIL_LISTIFY_3611(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3611, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3613(F, sep, ...) \ + Z_UTIL_LISTIFY_3612(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3612, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3614(F, sep, ...) \ + Z_UTIL_LISTIFY_3613(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3613, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3615(F, sep, ...) \ + Z_UTIL_LISTIFY_3614(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3614, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3616(F, sep, ...) \ + Z_UTIL_LISTIFY_3615(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3615, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3617(F, sep, ...) \ + Z_UTIL_LISTIFY_3616(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3616, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3618(F, sep, ...) \ + Z_UTIL_LISTIFY_3617(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3617, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3619(F, sep, ...) \ + Z_UTIL_LISTIFY_3618(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3618, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3620(F, sep, ...) \ + Z_UTIL_LISTIFY_3619(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3619, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3621(F, sep, ...) \ + Z_UTIL_LISTIFY_3620(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3620, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3622(F, sep, ...) \ + Z_UTIL_LISTIFY_3621(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3621, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3623(F, sep, ...) \ + Z_UTIL_LISTIFY_3622(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3622, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3624(F, sep, ...) \ + Z_UTIL_LISTIFY_3623(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3623, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3625(F, sep, ...) \ + Z_UTIL_LISTIFY_3624(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3624, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3626(F, sep, ...) \ + Z_UTIL_LISTIFY_3625(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3625, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3627(F, sep, ...) \ + Z_UTIL_LISTIFY_3626(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3626, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3628(F, sep, ...) \ + Z_UTIL_LISTIFY_3627(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3627, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3629(F, sep, ...) \ + Z_UTIL_LISTIFY_3628(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3628, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3630(F, sep, ...) \ + Z_UTIL_LISTIFY_3629(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3629, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3631(F, sep, ...) \ + Z_UTIL_LISTIFY_3630(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3630, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3632(F, sep, ...) \ + Z_UTIL_LISTIFY_3631(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3631, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3633(F, sep, ...) \ + Z_UTIL_LISTIFY_3632(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3632, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3634(F, sep, ...) \ + Z_UTIL_LISTIFY_3633(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3633, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3635(F, sep, ...) \ + Z_UTIL_LISTIFY_3634(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3634, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3636(F, sep, ...) \ + Z_UTIL_LISTIFY_3635(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3635, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3637(F, sep, ...) \ + Z_UTIL_LISTIFY_3636(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3636, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3638(F, sep, ...) \ + Z_UTIL_LISTIFY_3637(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3637, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3639(F, sep, ...) \ + Z_UTIL_LISTIFY_3638(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3638, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3640(F, sep, ...) \ + Z_UTIL_LISTIFY_3639(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3639, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3641(F, sep, ...) \ + Z_UTIL_LISTIFY_3640(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3640, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3642(F, sep, ...) \ + Z_UTIL_LISTIFY_3641(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3641, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3643(F, sep, ...) \ + Z_UTIL_LISTIFY_3642(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3642, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3644(F, sep, ...) \ + Z_UTIL_LISTIFY_3643(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3643, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3645(F, sep, ...) \ + Z_UTIL_LISTIFY_3644(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3644, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3646(F, sep, ...) \ + Z_UTIL_LISTIFY_3645(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3645, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3647(F, sep, ...) \ + Z_UTIL_LISTIFY_3646(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3646, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3648(F, sep, ...) \ + Z_UTIL_LISTIFY_3647(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3647, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3649(F, sep, ...) \ + Z_UTIL_LISTIFY_3648(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3648, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3650(F, sep, ...) \ + Z_UTIL_LISTIFY_3649(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3649, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3651(F, sep, ...) \ + Z_UTIL_LISTIFY_3650(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3650, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3652(F, sep, ...) \ + Z_UTIL_LISTIFY_3651(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3651, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3653(F, sep, ...) \ + Z_UTIL_LISTIFY_3652(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3652, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3654(F, sep, ...) \ + Z_UTIL_LISTIFY_3653(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3653, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3655(F, sep, ...) \ + Z_UTIL_LISTIFY_3654(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3654, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3656(F, sep, ...) \ + Z_UTIL_LISTIFY_3655(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3655, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3657(F, sep, ...) \ + Z_UTIL_LISTIFY_3656(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3656, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3658(F, sep, ...) \ + Z_UTIL_LISTIFY_3657(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3657, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3659(F, sep, ...) \ + Z_UTIL_LISTIFY_3658(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3658, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3660(F, sep, ...) \ + Z_UTIL_LISTIFY_3659(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3659, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3661(F, sep, ...) \ + Z_UTIL_LISTIFY_3660(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3660, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3662(F, sep, ...) \ + Z_UTIL_LISTIFY_3661(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3661, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3663(F, sep, ...) \ + Z_UTIL_LISTIFY_3662(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3662, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3664(F, sep, ...) \ + Z_UTIL_LISTIFY_3663(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3663, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3665(F, sep, ...) \ + Z_UTIL_LISTIFY_3664(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3664, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3666(F, sep, ...) \ + Z_UTIL_LISTIFY_3665(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3665, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3667(F, sep, ...) \ + Z_UTIL_LISTIFY_3666(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3666, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3668(F, sep, ...) \ + Z_UTIL_LISTIFY_3667(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3667, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3669(F, sep, ...) \ + Z_UTIL_LISTIFY_3668(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3668, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3670(F, sep, ...) \ + Z_UTIL_LISTIFY_3669(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3669, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3671(F, sep, ...) \ + Z_UTIL_LISTIFY_3670(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3670, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3672(F, sep, ...) \ + Z_UTIL_LISTIFY_3671(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3671, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3673(F, sep, ...) \ + Z_UTIL_LISTIFY_3672(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3672, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3674(F, sep, ...) \ + Z_UTIL_LISTIFY_3673(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3673, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3675(F, sep, ...) \ + Z_UTIL_LISTIFY_3674(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3674, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3676(F, sep, ...) \ + Z_UTIL_LISTIFY_3675(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3675, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3677(F, sep, ...) \ + Z_UTIL_LISTIFY_3676(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3676, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3678(F, sep, ...) \ + Z_UTIL_LISTIFY_3677(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3677, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3679(F, sep, ...) \ + Z_UTIL_LISTIFY_3678(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3678, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3680(F, sep, ...) \ + Z_UTIL_LISTIFY_3679(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3679, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3681(F, sep, ...) \ + Z_UTIL_LISTIFY_3680(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3680, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3682(F, sep, ...) \ + Z_UTIL_LISTIFY_3681(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3681, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3683(F, sep, ...) \ + Z_UTIL_LISTIFY_3682(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3682, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3684(F, sep, ...) \ + Z_UTIL_LISTIFY_3683(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3683, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3685(F, sep, ...) \ + Z_UTIL_LISTIFY_3684(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3684, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3686(F, sep, ...) \ + Z_UTIL_LISTIFY_3685(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3685, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3687(F, sep, ...) \ + Z_UTIL_LISTIFY_3686(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3686, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3688(F, sep, ...) \ + Z_UTIL_LISTIFY_3687(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3687, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3689(F, sep, ...) \ + Z_UTIL_LISTIFY_3688(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3688, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3690(F, sep, ...) \ + Z_UTIL_LISTIFY_3689(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3689, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3691(F, sep, ...) \ + Z_UTIL_LISTIFY_3690(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3690, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3692(F, sep, ...) \ + Z_UTIL_LISTIFY_3691(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3691, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3693(F, sep, ...) \ + Z_UTIL_LISTIFY_3692(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3692, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3694(F, sep, ...) \ + Z_UTIL_LISTIFY_3693(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3693, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3695(F, sep, ...) \ + Z_UTIL_LISTIFY_3694(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3694, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3696(F, sep, ...) \ + Z_UTIL_LISTIFY_3695(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3695, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3697(F, sep, ...) \ + Z_UTIL_LISTIFY_3696(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3696, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3698(F, sep, ...) \ + Z_UTIL_LISTIFY_3697(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3697, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3699(F, sep, ...) \ + Z_UTIL_LISTIFY_3698(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3698, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3700(F, sep, ...) \ + Z_UTIL_LISTIFY_3699(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3699, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3701(F, sep, ...) \ + Z_UTIL_LISTIFY_3700(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3700, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3702(F, sep, ...) \ + Z_UTIL_LISTIFY_3701(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3701, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3703(F, sep, ...) \ + Z_UTIL_LISTIFY_3702(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3702, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3704(F, sep, ...) \ + Z_UTIL_LISTIFY_3703(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3703, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3705(F, sep, ...) \ + Z_UTIL_LISTIFY_3704(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3704, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3706(F, sep, ...) \ + Z_UTIL_LISTIFY_3705(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3705, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3707(F, sep, ...) \ + Z_UTIL_LISTIFY_3706(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3706, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3708(F, sep, ...) \ + Z_UTIL_LISTIFY_3707(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3707, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3709(F, sep, ...) \ + Z_UTIL_LISTIFY_3708(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3708, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3710(F, sep, ...) \ + Z_UTIL_LISTIFY_3709(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3709, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3711(F, sep, ...) \ + Z_UTIL_LISTIFY_3710(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3710, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3712(F, sep, ...) \ + Z_UTIL_LISTIFY_3711(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3711, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3713(F, sep, ...) \ + Z_UTIL_LISTIFY_3712(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3712, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3714(F, sep, ...) \ + Z_UTIL_LISTIFY_3713(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3713, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3715(F, sep, ...) \ + Z_UTIL_LISTIFY_3714(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3714, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3716(F, sep, ...) \ + Z_UTIL_LISTIFY_3715(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3715, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3717(F, sep, ...) \ + Z_UTIL_LISTIFY_3716(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3716, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3718(F, sep, ...) \ + Z_UTIL_LISTIFY_3717(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3717, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3719(F, sep, ...) \ + Z_UTIL_LISTIFY_3718(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3718, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3720(F, sep, ...) \ + Z_UTIL_LISTIFY_3719(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3719, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3721(F, sep, ...) \ + Z_UTIL_LISTIFY_3720(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3720, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3722(F, sep, ...) \ + Z_UTIL_LISTIFY_3721(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3721, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3723(F, sep, ...) \ + Z_UTIL_LISTIFY_3722(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3722, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3724(F, sep, ...) \ + Z_UTIL_LISTIFY_3723(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3723, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3725(F, sep, ...) \ + Z_UTIL_LISTIFY_3724(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3724, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3726(F, sep, ...) \ + Z_UTIL_LISTIFY_3725(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3725, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3727(F, sep, ...) \ + Z_UTIL_LISTIFY_3726(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3726, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3728(F, sep, ...) \ + Z_UTIL_LISTIFY_3727(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3727, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3729(F, sep, ...) \ + Z_UTIL_LISTIFY_3728(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3728, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3730(F, sep, ...) \ + Z_UTIL_LISTIFY_3729(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3729, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3731(F, sep, ...) \ + Z_UTIL_LISTIFY_3730(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3730, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3732(F, sep, ...) \ + Z_UTIL_LISTIFY_3731(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3731, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3733(F, sep, ...) \ + Z_UTIL_LISTIFY_3732(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3732, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3734(F, sep, ...) \ + Z_UTIL_LISTIFY_3733(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3733, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3735(F, sep, ...) \ + Z_UTIL_LISTIFY_3734(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3734, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3736(F, sep, ...) \ + Z_UTIL_LISTIFY_3735(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3735, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3737(F, sep, ...) \ + Z_UTIL_LISTIFY_3736(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3736, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3738(F, sep, ...) \ + Z_UTIL_LISTIFY_3737(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3737, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3739(F, sep, ...) \ + Z_UTIL_LISTIFY_3738(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3738, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3740(F, sep, ...) \ + Z_UTIL_LISTIFY_3739(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3739, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3741(F, sep, ...) \ + Z_UTIL_LISTIFY_3740(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3740, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3742(F, sep, ...) \ + Z_UTIL_LISTIFY_3741(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3741, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3743(F, sep, ...) \ + Z_UTIL_LISTIFY_3742(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3742, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3744(F, sep, ...) \ + Z_UTIL_LISTIFY_3743(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3743, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3745(F, sep, ...) \ + Z_UTIL_LISTIFY_3744(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3744, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3746(F, sep, ...) \ + Z_UTIL_LISTIFY_3745(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3745, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3747(F, sep, ...) \ + Z_UTIL_LISTIFY_3746(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3746, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3748(F, sep, ...) \ + Z_UTIL_LISTIFY_3747(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3747, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3749(F, sep, ...) \ + Z_UTIL_LISTIFY_3748(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3748, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3750(F, sep, ...) \ + Z_UTIL_LISTIFY_3749(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3749, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3751(F, sep, ...) \ + Z_UTIL_LISTIFY_3750(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3750, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3752(F, sep, ...) \ + Z_UTIL_LISTIFY_3751(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3751, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3753(F, sep, ...) \ + Z_UTIL_LISTIFY_3752(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3752, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3754(F, sep, ...) \ + Z_UTIL_LISTIFY_3753(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3753, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3755(F, sep, ...) \ + Z_UTIL_LISTIFY_3754(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3754, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3756(F, sep, ...) \ + Z_UTIL_LISTIFY_3755(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3755, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3757(F, sep, ...) \ + Z_UTIL_LISTIFY_3756(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3756, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3758(F, sep, ...) \ + Z_UTIL_LISTIFY_3757(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3757, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3759(F, sep, ...) \ + Z_UTIL_LISTIFY_3758(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3758, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3760(F, sep, ...) \ + Z_UTIL_LISTIFY_3759(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3759, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3761(F, sep, ...) \ + Z_UTIL_LISTIFY_3760(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3760, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3762(F, sep, ...) \ + Z_UTIL_LISTIFY_3761(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3761, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3763(F, sep, ...) \ + Z_UTIL_LISTIFY_3762(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3762, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3764(F, sep, ...) \ + Z_UTIL_LISTIFY_3763(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3763, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3765(F, sep, ...) \ + Z_UTIL_LISTIFY_3764(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3764, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3766(F, sep, ...) \ + Z_UTIL_LISTIFY_3765(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3765, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3767(F, sep, ...) \ + Z_UTIL_LISTIFY_3766(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3766, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3768(F, sep, ...) \ + Z_UTIL_LISTIFY_3767(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3767, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3769(F, sep, ...) \ + Z_UTIL_LISTIFY_3768(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3768, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3770(F, sep, ...) \ + Z_UTIL_LISTIFY_3769(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3769, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3771(F, sep, ...) \ + Z_UTIL_LISTIFY_3770(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3770, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3772(F, sep, ...) \ + Z_UTIL_LISTIFY_3771(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3771, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3773(F, sep, ...) \ + Z_UTIL_LISTIFY_3772(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3772, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3774(F, sep, ...) \ + Z_UTIL_LISTIFY_3773(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3773, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3775(F, sep, ...) \ + Z_UTIL_LISTIFY_3774(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3774, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3776(F, sep, ...) \ + Z_UTIL_LISTIFY_3775(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3775, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3777(F, sep, ...) \ + Z_UTIL_LISTIFY_3776(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3776, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3778(F, sep, ...) \ + Z_UTIL_LISTIFY_3777(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3777, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3779(F, sep, ...) \ + Z_UTIL_LISTIFY_3778(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3778, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3780(F, sep, ...) \ + Z_UTIL_LISTIFY_3779(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3779, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3781(F, sep, ...) \ + Z_UTIL_LISTIFY_3780(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3780, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3782(F, sep, ...) \ + Z_UTIL_LISTIFY_3781(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3781, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3783(F, sep, ...) \ + Z_UTIL_LISTIFY_3782(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3782, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3784(F, sep, ...) \ + Z_UTIL_LISTIFY_3783(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3783, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3785(F, sep, ...) \ + Z_UTIL_LISTIFY_3784(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3784, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3786(F, sep, ...) \ + Z_UTIL_LISTIFY_3785(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3785, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3787(F, sep, ...) \ + Z_UTIL_LISTIFY_3786(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3786, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3788(F, sep, ...) \ + Z_UTIL_LISTIFY_3787(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3787, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3789(F, sep, ...) \ + Z_UTIL_LISTIFY_3788(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3788, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3790(F, sep, ...) \ + Z_UTIL_LISTIFY_3789(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3789, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3791(F, sep, ...) \ + Z_UTIL_LISTIFY_3790(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3790, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3792(F, sep, ...) \ + Z_UTIL_LISTIFY_3791(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3791, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3793(F, sep, ...) \ + Z_UTIL_LISTIFY_3792(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3792, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3794(F, sep, ...) \ + Z_UTIL_LISTIFY_3793(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3793, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3795(F, sep, ...) \ + Z_UTIL_LISTIFY_3794(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3794, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3796(F, sep, ...) \ + Z_UTIL_LISTIFY_3795(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3795, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3797(F, sep, ...) \ + Z_UTIL_LISTIFY_3796(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3796, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3798(F, sep, ...) \ + Z_UTIL_LISTIFY_3797(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3797, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3799(F, sep, ...) \ + Z_UTIL_LISTIFY_3798(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3798, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3800(F, sep, ...) \ + Z_UTIL_LISTIFY_3799(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3799, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3801(F, sep, ...) \ + Z_UTIL_LISTIFY_3800(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3800, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3802(F, sep, ...) \ + Z_UTIL_LISTIFY_3801(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3801, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3803(F, sep, ...) \ + Z_UTIL_LISTIFY_3802(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3802, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3804(F, sep, ...) \ + Z_UTIL_LISTIFY_3803(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3803, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3805(F, sep, ...) \ + Z_UTIL_LISTIFY_3804(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3804, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3806(F, sep, ...) \ + Z_UTIL_LISTIFY_3805(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3805, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3807(F, sep, ...) \ + Z_UTIL_LISTIFY_3806(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3806, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3808(F, sep, ...) \ + Z_UTIL_LISTIFY_3807(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3807, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3809(F, sep, ...) \ + Z_UTIL_LISTIFY_3808(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3808, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3810(F, sep, ...) \ + Z_UTIL_LISTIFY_3809(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3809, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3811(F, sep, ...) \ + Z_UTIL_LISTIFY_3810(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3810, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3812(F, sep, ...) \ + Z_UTIL_LISTIFY_3811(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3811, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3813(F, sep, ...) \ + Z_UTIL_LISTIFY_3812(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3812, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3814(F, sep, ...) \ + Z_UTIL_LISTIFY_3813(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3813, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3815(F, sep, ...) \ + Z_UTIL_LISTIFY_3814(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3814, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3816(F, sep, ...) \ + Z_UTIL_LISTIFY_3815(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3815, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3817(F, sep, ...) \ + Z_UTIL_LISTIFY_3816(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3816, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3818(F, sep, ...) \ + Z_UTIL_LISTIFY_3817(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3817, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3819(F, sep, ...) \ + Z_UTIL_LISTIFY_3818(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3818, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3820(F, sep, ...) \ + Z_UTIL_LISTIFY_3819(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3819, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3821(F, sep, ...) \ + Z_UTIL_LISTIFY_3820(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3820, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3822(F, sep, ...) \ + Z_UTIL_LISTIFY_3821(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3821, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3823(F, sep, ...) \ + Z_UTIL_LISTIFY_3822(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3822, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3824(F, sep, ...) \ + Z_UTIL_LISTIFY_3823(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3823, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3825(F, sep, ...) \ + Z_UTIL_LISTIFY_3824(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3824, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3826(F, sep, ...) \ + Z_UTIL_LISTIFY_3825(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3825, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3827(F, sep, ...) \ + Z_UTIL_LISTIFY_3826(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3826, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3828(F, sep, ...) \ + Z_UTIL_LISTIFY_3827(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3827, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3829(F, sep, ...) \ + Z_UTIL_LISTIFY_3828(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3828, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3830(F, sep, ...) \ + Z_UTIL_LISTIFY_3829(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3829, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3831(F, sep, ...) \ + Z_UTIL_LISTIFY_3830(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3830, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3832(F, sep, ...) \ + Z_UTIL_LISTIFY_3831(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3831, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3833(F, sep, ...) \ + Z_UTIL_LISTIFY_3832(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3832, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3834(F, sep, ...) \ + Z_UTIL_LISTIFY_3833(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3833, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3835(F, sep, ...) \ + Z_UTIL_LISTIFY_3834(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3834, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3836(F, sep, ...) \ + Z_UTIL_LISTIFY_3835(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3835, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3837(F, sep, ...) \ + Z_UTIL_LISTIFY_3836(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3836, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3838(F, sep, ...) \ + Z_UTIL_LISTIFY_3837(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3837, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3839(F, sep, ...) \ + Z_UTIL_LISTIFY_3838(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3838, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3840(F, sep, ...) \ + Z_UTIL_LISTIFY_3839(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3839, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3841(F, sep, ...) \ + Z_UTIL_LISTIFY_3840(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3840, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3842(F, sep, ...) \ + Z_UTIL_LISTIFY_3841(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3841, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3843(F, sep, ...) \ + Z_UTIL_LISTIFY_3842(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3842, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3844(F, sep, ...) \ + Z_UTIL_LISTIFY_3843(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3843, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3845(F, sep, ...) \ + Z_UTIL_LISTIFY_3844(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3844, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3846(F, sep, ...) \ + Z_UTIL_LISTIFY_3845(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3845, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3847(F, sep, ...) \ + Z_UTIL_LISTIFY_3846(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3846, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3848(F, sep, ...) \ + Z_UTIL_LISTIFY_3847(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3847, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3849(F, sep, ...) \ + Z_UTIL_LISTIFY_3848(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3848, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3850(F, sep, ...) \ + Z_UTIL_LISTIFY_3849(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3849, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3851(F, sep, ...) \ + Z_UTIL_LISTIFY_3850(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3850, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3852(F, sep, ...) \ + Z_UTIL_LISTIFY_3851(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3851, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3853(F, sep, ...) \ + Z_UTIL_LISTIFY_3852(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3852, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3854(F, sep, ...) \ + Z_UTIL_LISTIFY_3853(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3853, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3855(F, sep, ...) \ + Z_UTIL_LISTIFY_3854(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3854, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3856(F, sep, ...) \ + Z_UTIL_LISTIFY_3855(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3855, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3857(F, sep, ...) \ + Z_UTIL_LISTIFY_3856(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3856, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3858(F, sep, ...) \ + Z_UTIL_LISTIFY_3857(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3857, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3859(F, sep, ...) \ + Z_UTIL_LISTIFY_3858(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3858, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3860(F, sep, ...) \ + Z_UTIL_LISTIFY_3859(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3859, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3861(F, sep, ...) \ + Z_UTIL_LISTIFY_3860(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3860, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3862(F, sep, ...) \ + Z_UTIL_LISTIFY_3861(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3861, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3863(F, sep, ...) \ + Z_UTIL_LISTIFY_3862(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3862, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3864(F, sep, ...) \ + Z_UTIL_LISTIFY_3863(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3863, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3865(F, sep, ...) \ + Z_UTIL_LISTIFY_3864(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3864, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3866(F, sep, ...) \ + Z_UTIL_LISTIFY_3865(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3865, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3867(F, sep, ...) \ + Z_UTIL_LISTIFY_3866(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3866, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3868(F, sep, ...) \ + Z_UTIL_LISTIFY_3867(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3867, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3869(F, sep, ...) \ + Z_UTIL_LISTIFY_3868(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3868, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3870(F, sep, ...) \ + Z_UTIL_LISTIFY_3869(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3869, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3871(F, sep, ...) \ + Z_UTIL_LISTIFY_3870(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3870, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3872(F, sep, ...) \ + Z_UTIL_LISTIFY_3871(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3871, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3873(F, sep, ...) \ + Z_UTIL_LISTIFY_3872(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3872, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3874(F, sep, ...) \ + Z_UTIL_LISTIFY_3873(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3873, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3875(F, sep, ...) \ + Z_UTIL_LISTIFY_3874(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3874, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3876(F, sep, ...) \ + Z_UTIL_LISTIFY_3875(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3875, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3877(F, sep, ...) \ + Z_UTIL_LISTIFY_3876(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3876, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3878(F, sep, ...) \ + Z_UTIL_LISTIFY_3877(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3877, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3879(F, sep, ...) \ + Z_UTIL_LISTIFY_3878(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3878, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3880(F, sep, ...) \ + Z_UTIL_LISTIFY_3879(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3879, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3881(F, sep, ...) \ + Z_UTIL_LISTIFY_3880(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3880, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3882(F, sep, ...) \ + Z_UTIL_LISTIFY_3881(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3881, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3883(F, sep, ...) \ + Z_UTIL_LISTIFY_3882(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3882, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3884(F, sep, ...) \ + Z_UTIL_LISTIFY_3883(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3883, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3885(F, sep, ...) \ + Z_UTIL_LISTIFY_3884(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3884, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3886(F, sep, ...) \ + Z_UTIL_LISTIFY_3885(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3885, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3887(F, sep, ...) \ + Z_UTIL_LISTIFY_3886(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3886, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3888(F, sep, ...) \ + Z_UTIL_LISTIFY_3887(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3887, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3889(F, sep, ...) \ + Z_UTIL_LISTIFY_3888(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3888, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3890(F, sep, ...) \ + Z_UTIL_LISTIFY_3889(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3889, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3891(F, sep, ...) \ + Z_UTIL_LISTIFY_3890(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3890, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3892(F, sep, ...) \ + Z_UTIL_LISTIFY_3891(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3891, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3893(F, sep, ...) \ + Z_UTIL_LISTIFY_3892(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3892, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3894(F, sep, ...) \ + Z_UTIL_LISTIFY_3893(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3893, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3895(F, sep, ...) \ + Z_UTIL_LISTIFY_3894(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3894, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3896(F, sep, ...) \ + Z_UTIL_LISTIFY_3895(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3895, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3897(F, sep, ...) \ + Z_UTIL_LISTIFY_3896(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3896, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3898(F, sep, ...) \ + Z_UTIL_LISTIFY_3897(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3897, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3899(F, sep, ...) \ + Z_UTIL_LISTIFY_3898(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3898, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3900(F, sep, ...) \ + Z_UTIL_LISTIFY_3899(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3899, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3901(F, sep, ...) \ + Z_UTIL_LISTIFY_3900(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3900, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3902(F, sep, ...) \ + Z_UTIL_LISTIFY_3901(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3901, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3903(F, sep, ...) \ + Z_UTIL_LISTIFY_3902(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3902, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3904(F, sep, ...) \ + Z_UTIL_LISTIFY_3903(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3903, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3905(F, sep, ...) \ + Z_UTIL_LISTIFY_3904(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3904, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3906(F, sep, ...) \ + Z_UTIL_LISTIFY_3905(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3905, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3907(F, sep, ...) \ + Z_UTIL_LISTIFY_3906(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3906, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3908(F, sep, ...) \ + Z_UTIL_LISTIFY_3907(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3907, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3909(F, sep, ...) \ + Z_UTIL_LISTIFY_3908(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3908, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3910(F, sep, ...) \ + Z_UTIL_LISTIFY_3909(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3909, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3911(F, sep, ...) \ + Z_UTIL_LISTIFY_3910(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3910, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3912(F, sep, ...) \ + Z_UTIL_LISTIFY_3911(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3911, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3913(F, sep, ...) \ + Z_UTIL_LISTIFY_3912(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3912, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3914(F, sep, ...) \ + Z_UTIL_LISTIFY_3913(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3913, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3915(F, sep, ...) \ + Z_UTIL_LISTIFY_3914(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3914, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3916(F, sep, ...) \ + Z_UTIL_LISTIFY_3915(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3915, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3917(F, sep, ...) \ + Z_UTIL_LISTIFY_3916(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3916, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3918(F, sep, ...) \ + Z_UTIL_LISTIFY_3917(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3917, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3919(F, sep, ...) \ + Z_UTIL_LISTIFY_3918(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3918, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3920(F, sep, ...) \ + Z_UTIL_LISTIFY_3919(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3919, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3921(F, sep, ...) \ + Z_UTIL_LISTIFY_3920(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3920, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3922(F, sep, ...) \ + Z_UTIL_LISTIFY_3921(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3921, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3923(F, sep, ...) \ + Z_UTIL_LISTIFY_3922(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3922, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3924(F, sep, ...) \ + Z_UTIL_LISTIFY_3923(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3923, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3925(F, sep, ...) \ + Z_UTIL_LISTIFY_3924(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3924, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3926(F, sep, ...) \ + Z_UTIL_LISTIFY_3925(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3925, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3927(F, sep, ...) \ + Z_UTIL_LISTIFY_3926(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3926, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3928(F, sep, ...) \ + Z_UTIL_LISTIFY_3927(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3927, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3929(F, sep, ...) \ + Z_UTIL_LISTIFY_3928(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3928, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3930(F, sep, ...) \ + Z_UTIL_LISTIFY_3929(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3929, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3931(F, sep, ...) \ + Z_UTIL_LISTIFY_3930(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3930, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3932(F, sep, ...) \ + Z_UTIL_LISTIFY_3931(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3931, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3933(F, sep, ...) \ + Z_UTIL_LISTIFY_3932(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3932, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3934(F, sep, ...) \ + Z_UTIL_LISTIFY_3933(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3933, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3935(F, sep, ...) \ + Z_UTIL_LISTIFY_3934(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3934, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3936(F, sep, ...) \ + Z_UTIL_LISTIFY_3935(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3935, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3937(F, sep, ...) \ + Z_UTIL_LISTIFY_3936(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3936, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3938(F, sep, ...) \ + Z_UTIL_LISTIFY_3937(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3937, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3939(F, sep, ...) \ + Z_UTIL_LISTIFY_3938(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3938, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3940(F, sep, ...) \ + Z_UTIL_LISTIFY_3939(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3939, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3941(F, sep, ...) \ + Z_UTIL_LISTIFY_3940(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3940, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3942(F, sep, ...) \ + Z_UTIL_LISTIFY_3941(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3941, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3943(F, sep, ...) \ + Z_UTIL_LISTIFY_3942(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3942, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3944(F, sep, ...) \ + Z_UTIL_LISTIFY_3943(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3943, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3945(F, sep, ...) \ + Z_UTIL_LISTIFY_3944(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3944, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3946(F, sep, ...) \ + Z_UTIL_LISTIFY_3945(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3945, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3947(F, sep, ...) \ + Z_UTIL_LISTIFY_3946(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3946, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3948(F, sep, ...) \ + Z_UTIL_LISTIFY_3947(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3947, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3949(F, sep, ...) \ + Z_UTIL_LISTIFY_3948(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3948, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3950(F, sep, ...) \ + Z_UTIL_LISTIFY_3949(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3949, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3951(F, sep, ...) \ + Z_UTIL_LISTIFY_3950(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3950, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3952(F, sep, ...) \ + Z_UTIL_LISTIFY_3951(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3951, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3953(F, sep, ...) \ + Z_UTIL_LISTIFY_3952(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3952, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3954(F, sep, ...) \ + Z_UTIL_LISTIFY_3953(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3953, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3955(F, sep, ...) \ + Z_UTIL_LISTIFY_3954(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3954, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3956(F, sep, ...) \ + Z_UTIL_LISTIFY_3955(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3955, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3957(F, sep, ...) \ + Z_UTIL_LISTIFY_3956(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3956, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3958(F, sep, ...) \ + Z_UTIL_LISTIFY_3957(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3957, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3959(F, sep, ...) \ + Z_UTIL_LISTIFY_3958(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3958, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3960(F, sep, ...) \ + Z_UTIL_LISTIFY_3959(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3959, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3961(F, sep, ...) \ + Z_UTIL_LISTIFY_3960(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3960, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3962(F, sep, ...) \ + Z_UTIL_LISTIFY_3961(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3961, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3963(F, sep, ...) \ + Z_UTIL_LISTIFY_3962(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3962, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3964(F, sep, ...) \ + Z_UTIL_LISTIFY_3963(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3963, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3965(F, sep, ...) \ + Z_UTIL_LISTIFY_3964(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3964, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3966(F, sep, ...) \ + Z_UTIL_LISTIFY_3965(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3965, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3967(F, sep, ...) \ + Z_UTIL_LISTIFY_3966(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3966, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3968(F, sep, ...) \ + Z_UTIL_LISTIFY_3967(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3967, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3969(F, sep, ...) \ + Z_UTIL_LISTIFY_3968(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3968, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3970(F, sep, ...) \ + Z_UTIL_LISTIFY_3969(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3969, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3971(F, sep, ...) \ + Z_UTIL_LISTIFY_3970(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3970, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3972(F, sep, ...) \ + Z_UTIL_LISTIFY_3971(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3971, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3973(F, sep, ...) \ + Z_UTIL_LISTIFY_3972(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3972, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3974(F, sep, ...) \ + Z_UTIL_LISTIFY_3973(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3973, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3975(F, sep, ...) \ + Z_UTIL_LISTIFY_3974(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3974, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3976(F, sep, ...) \ + Z_UTIL_LISTIFY_3975(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3975, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3977(F, sep, ...) \ + Z_UTIL_LISTIFY_3976(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3976, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3978(F, sep, ...) \ + Z_UTIL_LISTIFY_3977(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3977, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3979(F, sep, ...) \ + Z_UTIL_LISTIFY_3978(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3978, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3980(F, sep, ...) \ + Z_UTIL_LISTIFY_3979(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3979, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3981(F, sep, ...) \ + Z_UTIL_LISTIFY_3980(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3980, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3982(F, sep, ...) \ + Z_UTIL_LISTIFY_3981(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3981, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3983(F, sep, ...) \ + Z_UTIL_LISTIFY_3982(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3982, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3984(F, sep, ...) \ + Z_UTIL_LISTIFY_3983(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3983, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3985(F, sep, ...) \ + Z_UTIL_LISTIFY_3984(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3984, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3986(F, sep, ...) \ + Z_UTIL_LISTIFY_3985(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3985, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3987(F, sep, ...) \ + Z_UTIL_LISTIFY_3986(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3986, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3988(F, sep, ...) \ + Z_UTIL_LISTIFY_3987(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3987, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3989(F, sep, ...) \ + Z_UTIL_LISTIFY_3988(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3988, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3990(F, sep, ...) \ + Z_UTIL_LISTIFY_3989(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3989, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3991(F, sep, ...) \ + Z_UTIL_LISTIFY_3990(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3990, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3992(F, sep, ...) \ + Z_UTIL_LISTIFY_3991(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3991, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3993(F, sep, ...) \ + Z_UTIL_LISTIFY_3992(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3992, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3994(F, sep, ...) \ + Z_UTIL_LISTIFY_3993(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3993, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3995(F, sep, ...) \ + Z_UTIL_LISTIFY_3994(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3994, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3996(F, sep, ...) \ + Z_UTIL_LISTIFY_3995(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3995, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3997(F, sep, ...) \ + Z_UTIL_LISTIFY_3996(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3996, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3998(F, sep, ...) \ + Z_UTIL_LISTIFY_3997(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3997, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3999(F, sep, ...) \ + Z_UTIL_LISTIFY_3998(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3998, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4000(F, sep, ...) \ + Z_UTIL_LISTIFY_3999(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3999, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4001(F, sep, ...) \ + Z_UTIL_LISTIFY_4000(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4000, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4002(F, sep, ...) \ + Z_UTIL_LISTIFY_4001(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4001, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4003(F, sep, ...) \ + Z_UTIL_LISTIFY_4002(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4002, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4004(F, sep, ...) \ + Z_UTIL_LISTIFY_4003(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4003, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4005(F, sep, ...) \ + Z_UTIL_LISTIFY_4004(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4004, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4006(F, sep, ...) \ + Z_UTIL_LISTIFY_4005(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4005, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4007(F, sep, ...) \ + Z_UTIL_LISTIFY_4006(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4006, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4008(F, sep, ...) \ + Z_UTIL_LISTIFY_4007(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4007, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4009(F, sep, ...) \ + Z_UTIL_LISTIFY_4008(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4008, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4010(F, sep, ...) \ + Z_UTIL_LISTIFY_4009(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4009, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4011(F, sep, ...) \ + Z_UTIL_LISTIFY_4010(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4010, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4012(F, sep, ...) \ + Z_UTIL_LISTIFY_4011(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4011, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4013(F, sep, ...) \ + Z_UTIL_LISTIFY_4012(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4012, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4014(F, sep, ...) \ + Z_UTIL_LISTIFY_4013(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4013, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4015(F, sep, ...) \ + Z_UTIL_LISTIFY_4014(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4014, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4016(F, sep, ...) \ + Z_UTIL_LISTIFY_4015(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4015, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4017(F, sep, ...) \ + Z_UTIL_LISTIFY_4016(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4016, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4018(F, sep, ...) \ + Z_UTIL_LISTIFY_4017(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4017, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4019(F, sep, ...) \ + Z_UTIL_LISTIFY_4018(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4018, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4020(F, sep, ...) \ + Z_UTIL_LISTIFY_4019(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4019, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4021(F, sep, ...) \ + Z_UTIL_LISTIFY_4020(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4020, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4022(F, sep, ...) \ + Z_UTIL_LISTIFY_4021(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4021, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4023(F, sep, ...) \ + Z_UTIL_LISTIFY_4022(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4022, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4024(F, sep, ...) \ + Z_UTIL_LISTIFY_4023(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4023, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4025(F, sep, ...) \ + Z_UTIL_LISTIFY_4024(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4024, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4026(F, sep, ...) \ + Z_UTIL_LISTIFY_4025(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4025, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4027(F, sep, ...) \ + Z_UTIL_LISTIFY_4026(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4026, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4028(F, sep, ...) \ + Z_UTIL_LISTIFY_4027(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4027, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4029(F, sep, ...) \ + Z_UTIL_LISTIFY_4028(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4028, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4030(F, sep, ...) \ + Z_UTIL_LISTIFY_4029(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4029, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4031(F, sep, ...) \ + Z_UTIL_LISTIFY_4030(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4030, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4032(F, sep, ...) \ + Z_UTIL_LISTIFY_4031(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4031, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4033(F, sep, ...) \ + Z_UTIL_LISTIFY_4032(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4032, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4034(F, sep, ...) \ + Z_UTIL_LISTIFY_4033(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4033, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4035(F, sep, ...) \ + Z_UTIL_LISTIFY_4034(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4034, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4036(F, sep, ...) \ + Z_UTIL_LISTIFY_4035(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4035, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4037(F, sep, ...) \ + Z_UTIL_LISTIFY_4036(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4036, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4038(F, sep, ...) \ + Z_UTIL_LISTIFY_4037(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4037, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4039(F, sep, ...) \ + Z_UTIL_LISTIFY_4038(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4038, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4040(F, sep, ...) \ + Z_UTIL_LISTIFY_4039(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4039, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4041(F, sep, ...) \ + Z_UTIL_LISTIFY_4040(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4040, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4042(F, sep, ...) \ + Z_UTIL_LISTIFY_4041(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4041, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4043(F, sep, ...) \ + Z_UTIL_LISTIFY_4042(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4042, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4044(F, sep, ...) \ + Z_UTIL_LISTIFY_4043(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4043, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4045(F, sep, ...) \ + Z_UTIL_LISTIFY_4044(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4044, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4046(F, sep, ...) \ + Z_UTIL_LISTIFY_4045(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4045, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4047(F, sep, ...) \ + Z_UTIL_LISTIFY_4046(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4046, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4048(F, sep, ...) \ + Z_UTIL_LISTIFY_4047(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4047, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4049(F, sep, ...) \ + Z_UTIL_LISTIFY_4048(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4048, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4050(F, sep, ...) \ + Z_UTIL_LISTIFY_4049(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4049, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4051(F, sep, ...) \ + Z_UTIL_LISTIFY_4050(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4050, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4052(F, sep, ...) \ + Z_UTIL_LISTIFY_4051(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4051, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4053(F, sep, ...) \ + Z_UTIL_LISTIFY_4052(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4052, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4054(F, sep, ...) \ + Z_UTIL_LISTIFY_4053(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4053, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4055(F, sep, ...) \ + Z_UTIL_LISTIFY_4054(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4054, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4056(F, sep, ...) \ + Z_UTIL_LISTIFY_4055(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4055, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4057(F, sep, ...) \ + Z_UTIL_LISTIFY_4056(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4056, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4058(F, sep, ...) \ + Z_UTIL_LISTIFY_4057(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4057, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4059(F, sep, ...) \ + Z_UTIL_LISTIFY_4058(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4058, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4060(F, sep, ...) \ + Z_UTIL_LISTIFY_4059(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4059, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4061(F, sep, ...) \ + Z_UTIL_LISTIFY_4060(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4060, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4062(F, sep, ...) \ + Z_UTIL_LISTIFY_4061(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4061, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4063(F, sep, ...) \ + Z_UTIL_LISTIFY_4062(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4062, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4064(F, sep, ...) \ + Z_UTIL_LISTIFY_4063(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4063, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4065(F, sep, ...) \ + Z_UTIL_LISTIFY_4064(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4064, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4066(F, sep, ...) \ + Z_UTIL_LISTIFY_4065(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4065, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4067(F, sep, ...) \ + Z_UTIL_LISTIFY_4066(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4066, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4068(F, sep, ...) \ + Z_UTIL_LISTIFY_4067(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4067, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4069(F, sep, ...) \ + Z_UTIL_LISTIFY_4068(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4068, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4070(F, sep, ...) \ + Z_UTIL_LISTIFY_4069(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4069, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4071(F, sep, ...) \ + Z_UTIL_LISTIFY_4070(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4070, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4072(F, sep, ...) \ + Z_UTIL_LISTIFY_4071(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4071, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4073(F, sep, ...) \ + Z_UTIL_LISTIFY_4072(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4072, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4074(F, sep, ...) \ + Z_UTIL_LISTIFY_4073(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4073, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4075(F, sep, ...) \ + Z_UTIL_LISTIFY_4074(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4074, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4076(F, sep, ...) \ + Z_UTIL_LISTIFY_4075(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4075, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4077(F, sep, ...) \ + Z_UTIL_LISTIFY_4076(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4076, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4078(F, sep, ...) \ + Z_UTIL_LISTIFY_4077(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4077, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4079(F, sep, ...) \ + Z_UTIL_LISTIFY_4078(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4078, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4080(F, sep, ...) \ + Z_UTIL_LISTIFY_4079(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4079, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4081(F, sep, ...) \ + Z_UTIL_LISTIFY_4080(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4080, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4082(F, sep, ...) \ + Z_UTIL_LISTIFY_4081(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4081, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4083(F, sep, ...) \ + Z_UTIL_LISTIFY_4082(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4082, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4084(F, sep, ...) \ + Z_UTIL_LISTIFY_4083(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4083, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4085(F, sep, ...) \ + Z_UTIL_LISTIFY_4084(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4084, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4086(F, sep, ...) \ + Z_UTIL_LISTIFY_4085(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4085, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4087(F, sep, ...) \ + Z_UTIL_LISTIFY_4086(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4086, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4088(F, sep, ...) \ + Z_UTIL_LISTIFY_4087(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4087, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4089(F, sep, ...) \ + Z_UTIL_LISTIFY_4088(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4088, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4090(F, sep, ...) \ + Z_UTIL_LISTIFY_4089(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4089, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4091(F, sep, ...) \ + Z_UTIL_LISTIFY_4090(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4090, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4092(F, sep, ...) \ + Z_UTIL_LISTIFY_4091(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4091, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4093(F, sep, ...) \ + Z_UTIL_LISTIFY_4092(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4092, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4094(F, sep, ...) \ + Z_UTIL_LISTIFY_4093(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4093, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4095(F, sep, ...) \ + Z_UTIL_LISTIFY_4094(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4094, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4096(F, sep, ...) \ + Z_UTIL_LISTIFY_4095(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4095, __VA_ARGS__) + +#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_ */ diff --git a/include/zephyr/sys/util_loops.h b/include/zephyr/sys/util_loops.h index 979a508a63c..ff64e7b1ef9 100644 --- a/include/zephyr/sys/util_loops.h +++ b/include/zephyr/sys/util_loops.h @@ -1080,1029 +1080,6 @@ #define Z_BYPASS(x) x /* Set of UTIL_LISTIFY particles */ -#define Z_UTIL_LISTIFY_0(F, sep, ...) - -#define Z_UTIL_LISTIFY_1(F, sep, ...) \ - F(0, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_2(F, sep, ...) \ - Z_UTIL_LISTIFY_1(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(1, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_3(F, sep, ...) \ - Z_UTIL_LISTIFY_2(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(2, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_4(F, sep, ...) \ - Z_UTIL_LISTIFY_3(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(3, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_5(F, sep, ...) \ - Z_UTIL_LISTIFY_4(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(4, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_6(F, sep, ...) \ - Z_UTIL_LISTIFY_5(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(5, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_7(F, sep, ...) \ - Z_UTIL_LISTIFY_6(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(6, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_8(F, sep, ...) \ - Z_UTIL_LISTIFY_7(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(7, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_9(F, sep, ...) \ - Z_UTIL_LISTIFY_8(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(8, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_10(F, sep, ...) \ - Z_UTIL_LISTIFY_9(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(9, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_11(F, sep, ...) \ - Z_UTIL_LISTIFY_10(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(10, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_12(F, sep, ...) \ - Z_UTIL_LISTIFY_11(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(11, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_13(F, sep, ...) \ - Z_UTIL_LISTIFY_12(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(12, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_14(F, sep, ...) \ - Z_UTIL_LISTIFY_13(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(13, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_15(F, sep, ...) \ - Z_UTIL_LISTIFY_14(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(14, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_16(F, sep, ...) \ - Z_UTIL_LISTIFY_15(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(15, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_17(F, sep, ...) \ - Z_UTIL_LISTIFY_16(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(16, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_18(F, sep, ...) \ - Z_UTIL_LISTIFY_17(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(17, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_19(F, sep, ...) \ - Z_UTIL_LISTIFY_18(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(18, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_20(F, sep, ...) \ - Z_UTIL_LISTIFY_19(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(19, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_21(F, sep, ...) \ - Z_UTIL_LISTIFY_20(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(20, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_22(F, sep, ...) \ - Z_UTIL_LISTIFY_21(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(21, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_23(F, sep, ...) \ - Z_UTIL_LISTIFY_22(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(22, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_24(F, sep, ...) \ - Z_UTIL_LISTIFY_23(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(23, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_25(F, sep, ...) \ - Z_UTIL_LISTIFY_24(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(24, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_26(F, sep, ...) \ - Z_UTIL_LISTIFY_25(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(25, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_27(F, sep, ...) \ - Z_UTIL_LISTIFY_26(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(26, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_28(F, sep, ...) \ - Z_UTIL_LISTIFY_27(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(27, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_29(F, sep, ...) \ - Z_UTIL_LISTIFY_28(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(28, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_30(F, sep, ...) \ - Z_UTIL_LISTIFY_29(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(29, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_31(F, sep, ...) \ - Z_UTIL_LISTIFY_30(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(30, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_32(F, sep, ...) \ - Z_UTIL_LISTIFY_31(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(31, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_33(F, sep, ...) \ - Z_UTIL_LISTIFY_32(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(32, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_34(F, sep, ...) \ - Z_UTIL_LISTIFY_33(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(33, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_35(F, sep, ...) \ - Z_UTIL_LISTIFY_34(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(34, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_36(F, sep, ...) \ - Z_UTIL_LISTIFY_35(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(35, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_37(F, sep, ...) \ - Z_UTIL_LISTIFY_36(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(36, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_38(F, sep, ...) \ - Z_UTIL_LISTIFY_37(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(37, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_39(F, sep, ...) \ - Z_UTIL_LISTIFY_38(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(38, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_40(F, sep, ...) \ - Z_UTIL_LISTIFY_39(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(39, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_41(F, sep, ...) \ - Z_UTIL_LISTIFY_40(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(40, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_42(F, sep, ...) \ - Z_UTIL_LISTIFY_41(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(41, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_43(F, sep, ...) \ - Z_UTIL_LISTIFY_42(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(42, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_44(F, sep, ...) \ - Z_UTIL_LISTIFY_43(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(43, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_45(F, sep, ...) \ - Z_UTIL_LISTIFY_44(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(44, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_46(F, sep, ...) \ - Z_UTIL_LISTIFY_45(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(45, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_47(F, sep, ...) \ - Z_UTIL_LISTIFY_46(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(46, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_48(F, sep, ...) \ - Z_UTIL_LISTIFY_47(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(47, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_49(F, sep, ...) \ - Z_UTIL_LISTIFY_48(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(48, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_50(F, sep, ...) \ - Z_UTIL_LISTIFY_49(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(49, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_51(F, sep, ...) \ - Z_UTIL_LISTIFY_50(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(50, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_52(F, sep, ...) \ - Z_UTIL_LISTIFY_51(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(51, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_53(F, sep, ...) \ - Z_UTIL_LISTIFY_52(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(52, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_54(F, sep, ...) \ - Z_UTIL_LISTIFY_53(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(53, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_55(F, sep, ...) \ - Z_UTIL_LISTIFY_54(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(54, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_56(F, sep, ...) \ - Z_UTIL_LISTIFY_55(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(55, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_57(F, sep, ...) \ - Z_UTIL_LISTIFY_56(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(56, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_58(F, sep, ...) \ - Z_UTIL_LISTIFY_57(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(57, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_59(F, sep, ...) \ - Z_UTIL_LISTIFY_58(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(58, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_60(F, sep, ...) \ - Z_UTIL_LISTIFY_59(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(59, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_61(F, sep, ...) \ - Z_UTIL_LISTIFY_60(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(60, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_62(F, sep, ...) \ - Z_UTIL_LISTIFY_61(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(61, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_63(F, sep, ...) \ - Z_UTIL_LISTIFY_62(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(62, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_64(F, sep, ...) \ - Z_UTIL_LISTIFY_63(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(63, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_65(F, sep, ...) \ - Z_UTIL_LISTIFY_64(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(64, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_66(F, sep, ...) \ - Z_UTIL_LISTIFY_65(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(65, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_67(F, sep, ...) \ - Z_UTIL_LISTIFY_66(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(66, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_68(F, sep, ...) \ - Z_UTIL_LISTIFY_67(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(67, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_69(F, sep, ...) \ - Z_UTIL_LISTIFY_68(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(68, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_70(F, sep, ...) \ - Z_UTIL_LISTIFY_69(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(69, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_71(F, sep, ...) \ - Z_UTIL_LISTIFY_70(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(70, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_72(F, sep, ...) \ - Z_UTIL_LISTIFY_71(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(71, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_73(F, sep, ...) \ - Z_UTIL_LISTIFY_72(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(72, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_74(F, sep, ...) \ - Z_UTIL_LISTIFY_73(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(73, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_75(F, sep, ...) \ - Z_UTIL_LISTIFY_74(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(74, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_76(F, sep, ...) \ - Z_UTIL_LISTIFY_75(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(75, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_77(F, sep, ...) \ - Z_UTIL_LISTIFY_76(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(76, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_78(F, sep, ...) \ - Z_UTIL_LISTIFY_77(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(77, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_79(F, sep, ...) \ - Z_UTIL_LISTIFY_78(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(78, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_80(F, sep, ...) \ - Z_UTIL_LISTIFY_79(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(79, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_81(F, sep, ...) \ - Z_UTIL_LISTIFY_80(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(80, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_82(F, sep, ...) \ - Z_UTIL_LISTIFY_81(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(81, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_83(F, sep, ...) \ - Z_UTIL_LISTIFY_82(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(82, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_84(F, sep, ...) \ - Z_UTIL_LISTIFY_83(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(83, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_85(F, sep, ...) \ - Z_UTIL_LISTIFY_84(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(84, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_86(F, sep, ...) \ - Z_UTIL_LISTIFY_85(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(85, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_87(F, sep, ...) \ - Z_UTIL_LISTIFY_86(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(86, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_88(F, sep, ...) \ - Z_UTIL_LISTIFY_87(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(87, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_89(F, sep, ...) \ - Z_UTIL_LISTIFY_88(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(88, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_90(F, sep, ...) \ - Z_UTIL_LISTIFY_89(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(89, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_91(F, sep, ...) \ - Z_UTIL_LISTIFY_90(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(90, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_92(F, sep, ...) \ - Z_UTIL_LISTIFY_91(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(91, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_93(F, sep, ...) \ - Z_UTIL_LISTIFY_92(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(92, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_94(F, sep, ...) \ - Z_UTIL_LISTIFY_93(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(93, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_95(F, sep, ...) \ - Z_UTIL_LISTIFY_94(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(94, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_96(F, sep, ...) \ - Z_UTIL_LISTIFY_95(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(95, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_97(F, sep, ...) \ - Z_UTIL_LISTIFY_96(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(96, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_98(F, sep, ...) \ - Z_UTIL_LISTIFY_97(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(97, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_99(F, sep, ...) \ - Z_UTIL_LISTIFY_98(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(98, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_100(F, sep, ...) \ - Z_UTIL_LISTIFY_99(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(99, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_101(F, sep, ...) \ - Z_UTIL_LISTIFY_100(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(100, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_102(F, sep, ...) \ - Z_UTIL_LISTIFY_101(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(101, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_103(F, sep, ...) \ - Z_UTIL_LISTIFY_102(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(102, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_104(F, sep, ...) \ - Z_UTIL_LISTIFY_103(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(103, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_105(F, sep, ...) \ - Z_UTIL_LISTIFY_104(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(104, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_106(F, sep, ...) \ - Z_UTIL_LISTIFY_105(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(105, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_107(F, sep, ...) \ - Z_UTIL_LISTIFY_106(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(106, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_108(F, sep, ...) \ - Z_UTIL_LISTIFY_107(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(107, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_109(F, sep, ...) \ - Z_UTIL_LISTIFY_108(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(108, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_110(F, sep, ...) \ - Z_UTIL_LISTIFY_109(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(109, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_111(F, sep, ...) \ - Z_UTIL_LISTIFY_110(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(110, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_112(F, sep, ...) \ - Z_UTIL_LISTIFY_111(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(111, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_113(F, sep, ...) \ - Z_UTIL_LISTIFY_112(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(112, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_114(F, sep, ...) \ - Z_UTIL_LISTIFY_113(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(113, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_115(F, sep, ...) \ - Z_UTIL_LISTIFY_114(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(114, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_116(F, sep, ...) \ - Z_UTIL_LISTIFY_115(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(115, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_117(F, sep, ...) \ - Z_UTIL_LISTIFY_116(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(116, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_118(F, sep, ...) \ - Z_UTIL_LISTIFY_117(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(117, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_119(F, sep, ...) \ - Z_UTIL_LISTIFY_118(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(118, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_120(F, sep, ...) \ - Z_UTIL_LISTIFY_119(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(119, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_121(F, sep, ...) \ - Z_UTIL_LISTIFY_120(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(120, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_122(F, sep, ...) \ - Z_UTIL_LISTIFY_121(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(121, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_123(F, sep, ...) \ - Z_UTIL_LISTIFY_122(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(122, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_124(F, sep, ...) \ - Z_UTIL_LISTIFY_123(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(123, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_125(F, sep, ...) \ - Z_UTIL_LISTIFY_124(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(124, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_126(F, sep, ...) \ - Z_UTIL_LISTIFY_125(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(125, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_127(F, sep, ...) \ - Z_UTIL_LISTIFY_126(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(126, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_128(F, sep, ...) \ - Z_UTIL_LISTIFY_127(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(127, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_129(F, sep, ...) \ - Z_UTIL_LISTIFY_128(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(128, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_130(F, sep, ...) \ - Z_UTIL_LISTIFY_129(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(129, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_131(F, sep, ...) \ - Z_UTIL_LISTIFY_130(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(130, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_132(F, sep, ...) \ - Z_UTIL_LISTIFY_131(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(131, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_133(F, sep, ...) \ - Z_UTIL_LISTIFY_132(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(132, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_134(F, sep, ...) \ - Z_UTIL_LISTIFY_133(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(133, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_135(F, sep, ...) \ - Z_UTIL_LISTIFY_134(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(134, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_136(F, sep, ...) \ - Z_UTIL_LISTIFY_135(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(135, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_137(F, sep, ...) \ - Z_UTIL_LISTIFY_136(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(136, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_138(F, sep, ...) \ - Z_UTIL_LISTIFY_137(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(137, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_139(F, sep, ...) \ - Z_UTIL_LISTIFY_138(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(138, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_140(F, sep, ...) \ - Z_UTIL_LISTIFY_139(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(139, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_141(F, sep, ...) \ - Z_UTIL_LISTIFY_140(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(140, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_142(F, sep, ...) \ - Z_UTIL_LISTIFY_141(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(141, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_143(F, sep, ...) \ - Z_UTIL_LISTIFY_142(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(142, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_144(F, sep, ...) \ - Z_UTIL_LISTIFY_143(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(143, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_145(F, sep, ...) \ - Z_UTIL_LISTIFY_144(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(144, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_146(F, sep, ...) \ - Z_UTIL_LISTIFY_145(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(145, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_147(F, sep, ...) \ - Z_UTIL_LISTIFY_146(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(146, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_148(F, sep, ...) \ - Z_UTIL_LISTIFY_147(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(147, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_149(F, sep, ...) \ - Z_UTIL_LISTIFY_148(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(148, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_150(F, sep, ...) \ - Z_UTIL_LISTIFY_149(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(149, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_151(F, sep, ...) \ - Z_UTIL_LISTIFY_150(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(150, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_152(F, sep, ...) \ - Z_UTIL_LISTIFY_151(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(151, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_153(F, sep, ...) \ - Z_UTIL_LISTIFY_152(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(152, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_154(F, sep, ...) \ - Z_UTIL_LISTIFY_153(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(153, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_155(F, sep, ...) \ - Z_UTIL_LISTIFY_154(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(154, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_156(F, sep, ...) \ - Z_UTIL_LISTIFY_155(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(155, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_157(F, sep, ...) \ - Z_UTIL_LISTIFY_156(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(156, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_158(F, sep, ...) \ - Z_UTIL_LISTIFY_157(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(157, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_159(F, sep, ...) \ - Z_UTIL_LISTIFY_158(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(158, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_160(F, sep, ...) \ - Z_UTIL_LISTIFY_159(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(159, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_161(F, sep, ...) \ - Z_UTIL_LISTIFY_160(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(160, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_162(F, sep, ...) \ - Z_UTIL_LISTIFY_161(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(161, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_163(F, sep, ...) \ - Z_UTIL_LISTIFY_162(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(162, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_164(F, sep, ...) \ - Z_UTIL_LISTIFY_163(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(163, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_165(F, sep, ...) \ - Z_UTIL_LISTIFY_164(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(164, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_166(F, sep, ...) \ - Z_UTIL_LISTIFY_165(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(165, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_167(F, sep, ...) \ - Z_UTIL_LISTIFY_166(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(166, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_168(F, sep, ...) \ - Z_UTIL_LISTIFY_167(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(167, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_169(F, sep, ...) \ - Z_UTIL_LISTIFY_168(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(168, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_170(F, sep, ...) \ - Z_UTIL_LISTIFY_169(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(169, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_171(F, sep, ...) \ - Z_UTIL_LISTIFY_170(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(170, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_172(F, sep, ...) \ - Z_UTIL_LISTIFY_171(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(171, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_173(F, sep, ...) \ - Z_UTIL_LISTIFY_172(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(172, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_174(F, sep, ...) \ - Z_UTIL_LISTIFY_173(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(173, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_175(F, sep, ...) \ - Z_UTIL_LISTIFY_174(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(174, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_176(F, sep, ...) \ - Z_UTIL_LISTIFY_175(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(175, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_177(F, sep, ...) \ - Z_UTIL_LISTIFY_176(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(176, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_178(F, sep, ...) \ - Z_UTIL_LISTIFY_177(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(177, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_179(F, sep, ...) \ - Z_UTIL_LISTIFY_178(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(178, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_180(F, sep, ...) \ - Z_UTIL_LISTIFY_179(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(179, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_181(F, sep, ...) \ - Z_UTIL_LISTIFY_180(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(180, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_182(F, sep, ...) \ - Z_UTIL_LISTIFY_181(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(181, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_183(F, sep, ...) \ - Z_UTIL_LISTIFY_182(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(182, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_184(F, sep, ...) \ - Z_UTIL_LISTIFY_183(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(183, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_185(F, sep, ...) \ - Z_UTIL_LISTIFY_184(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(184, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_186(F, sep, ...) \ - Z_UTIL_LISTIFY_185(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(185, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_187(F, sep, ...) \ - Z_UTIL_LISTIFY_186(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(186, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_188(F, sep, ...) \ - Z_UTIL_LISTIFY_187(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(187, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_189(F, sep, ...) \ - Z_UTIL_LISTIFY_188(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(188, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_190(F, sep, ...) \ - Z_UTIL_LISTIFY_189(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(189, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_191(F, sep, ...) \ - Z_UTIL_LISTIFY_190(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(190, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_192(F, sep, ...) \ - Z_UTIL_LISTIFY_191(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(191, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_193(F, sep, ...) \ - Z_UTIL_LISTIFY_192(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(192, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_194(F, sep, ...) \ - Z_UTIL_LISTIFY_193(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(193, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_195(F, sep, ...) \ - Z_UTIL_LISTIFY_194(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(194, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_196(F, sep, ...) \ - Z_UTIL_LISTIFY_195(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(195, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_197(F, sep, ...) \ - Z_UTIL_LISTIFY_196(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(196, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_198(F, sep, ...) \ - Z_UTIL_LISTIFY_197(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(197, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_199(F, sep, ...) \ - Z_UTIL_LISTIFY_198(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(198, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_200(F, sep, ...) \ - Z_UTIL_LISTIFY_199(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(199, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_201(F, sep, ...) \ - Z_UTIL_LISTIFY_200(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(200, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_202(F, sep, ...) \ - Z_UTIL_LISTIFY_201(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(201, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_203(F, sep, ...) \ - Z_UTIL_LISTIFY_202(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(202, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_204(F, sep, ...) \ - Z_UTIL_LISTIFY_203(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(203, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_205(F, sep, ...) \ - Z_UTIL_LISTIFY_204(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(204, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_206(F, sep, ...) \ - Z_UTIL_LISTIFY_205(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(205, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_207(F, sep, ...) \ - Z_UTIL_LISTIFY_206(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(206, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_208(F, sep, ...) \ - Z_UTIL_LISTIFY_207(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(207, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_209(F, sep, ...) \ - Z_UTIL_LISTIFY_208(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(208, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_210(F, sep, ...) \ - Z_UTIL_LISTIFY_209(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(209, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_211(F, sep, ...) \ - Z_UTIL_LISTIFY_210(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(210, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_212(F, sep, ...) \ - Z_UTIL_LISTIFY_211(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(211, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_213(F, sep, ...) \ - Z_UTIL_LISTIFY_212(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(212, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_214(F, sep, ...) \ - Z_UTIL_LISTIFY_213(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(213, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_215(F, sep, ...) \ - Z_UTIL_LISTIFY_214(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(214, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_216(F, sep, ...) \ - Z_UTIL_LISTIFY_215(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(215, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_217(F, sep, ...) \ - Z_UTIL_LISTIFY_216(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(216, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_218(F, sep, ...) \ - Z_UTIL_LISTIFY_217(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(217, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_219(F, sep, ...) \ - Z_UTIL_LISTIFY_218(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(218, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_220(F, sep, ...) \ - Z_UTIL_LISTIFY_219(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(219, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_221(F, sep, ...) \ - Z_UTIL_LISTIFY_220(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(220, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_222(F, sep, ...) \ - Z_UTIL_LISTIFY_221(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(221, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_223(F, sep, ...) \ - Z_UTIL_LISTIFY_222(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(222, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_224(F, sep, ...) \ - Z_UTIL_LISTIFY_223(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(223, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_225(F, sep, ...) \ - Z_UTIL_LISTIFY_224(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(224, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_226(F, sep, ...) \ - Z_UTIL_LISTIFY_225(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(225, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_227(F, sep, ...) \ - Z_UTIL_LISTIFY_226(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(226, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_228(F, sep, ...) \ - Z_UTIL_LISTIFY_227(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(227, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_229(F, sep, ...) \ - Z_UTIL_LISTIFY_228(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(228, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_230(F, sep, ...) \ - Z_UTIL_LISTIFY_229(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(229, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_231(F, sep, ...) \ - Z_UTIL_LISTIFY_230(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(230, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_232(F, sep, ...) \ - Z_UTIL_LISTIFY_231(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(231, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_233(F, sep, ...) \ - Z_UTIL_LISTIFY_232(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(232, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_234(F, sep, ...) \ - Z_UTIL_LISTIFY_233(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(233, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_235(F, sep, ...) \ - Z_UTIL_LISTIFY_234(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(234, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_236(F, sep, ...) \ - Z_UTIL_LISTIFY_235(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(235, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_237(F, sep, ...) \ - Z_UTIL_LISTIFY_236(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(236, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_238(F, sep, ...) \ - Z_UTIL_LISTIFY_237(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(237, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_239(F, sep, ...) \ - Z_UTIL_LISTIFY_238(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(238, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_240(F, sep, ...) \ - Z_UTIL_LISTIFY_239(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(239, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_241(F, sep, ...) \ - Z_UTIL_LISTIFY_240(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(240, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_242(F, sep, ...) \ - Z_UTIL_LISTIFY_241(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(241, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_243(F, sep, ...) \ - Z_UTIL_LISTIFY_242(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(242, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_244(F, sep, ...) \ - Z_UTIL_LISTIFY_243(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(243, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_245(F, sep, ...) \ - Z_UTIL_LISTIFY_244(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(244, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_246(F, sep, ...) \ - Z_UTIL_LISTIFY_245(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(245, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_247(F, sep, ...) \ - Z_UTIL_LISTIFY_246(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(246, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_248(F, sep, ...) \ - Z_UTIL_LISTIFY_247(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(247, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_249(F, sep, ...) \ - Z_UTIL_LISTIFY_248(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(248, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_250(F, sep, ...) \ - Z_UTIL_LISTIFY_249(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(249, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_251(F, sep, ...) \ - Z_UTIL_LISTIFY_250(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(250, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_252(F, sep, ...) \ - Z_UTIL_LISTIFY_251(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(251, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_253(F, sep, ...) \ - Z_UTIL_LISTIFY_252(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(252, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_254(F, sep, ...) \ - Z_UTIL_LISTIFY_253(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(253, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_255(F, sep, ...) \ - Z_UTIL_LISTIFY_254(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(254, __VA_ARGS__) - -#define Z_UTIL_LISTIFY_256(F, sep, ...) \ - Z_UTIL_LISTIFY_255(F, sep, __VA_ARGS__) __DEBRACKET sep \ - F(255, __VA_ARGS__) +#include "util_listify.h" #endif /* ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_ */ diff --git a/include/zephyr/sys/util_macro.h b/include/zephyr/sys/util_macro.h index 1fbc3944be8..02d0e9885a6 100644 --- a/include/zephyr/sys/util_macro.h +++ b/include/zephyr/sys/util_macro.h @@ -256,7 +256,7 @@ extern "C" { * @brief Like a == b, but does evaluation and * short-circuiting at C preprocessor time. * - * This however only works for integer literal from 0 to 255. + * This however only works for integer literal from 0 to 4095. * */ #define IS_EQ(a, b) Z_IS_EQ(a, b) @@ -367,26 +367,26 @@ extern "C" { #define UTIL_AND(a, b) COND_CODE_1(UTIL_BOOL(a), (b), (0)) /** - * @brief UTIL_INC(x) for an integer literal x from 0 to 255 expands to an + * @brief UTIL_INC(x) for an integer literal x from 0 to 4095 expands to an * integer literal whose value is x+1. * * @see UTIL_DEC(x) */ -#define UTIL_INC(x) UTIL_PRIMITIVE_CAT(UTIL_INC_, x) +#define UTIL_INC(x) UTIL_PRIMITIVE_CAT(Z_UTIL_INC_, x) /** - * @brief UTIL_DEC(x) for an integer literal x from 0 to 255 expands to an + * @brief UTIL_DEC(x) for an integer literal x from 0 to 4095 expands to an * integer literal whose value is x-1. * * @see UTIL_INC(x) */ -#define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(UTIL_DEC_, x) +#define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(Z_UTIL_DEC_, x) /** - * @brief UTIL_X2(y) for an integer literal y from 0 to 255 expands to an + * @brief UTIL_X2(y) for an integer literal y from 0 to 4095 expands to an * integer literal whose value is 2y. */ -#define UTIL_X2(y) UTIL_PRIMITIVE_CAT(UTIL_X2_, y) +#define UTIL_X2(y) UTIL_PRIMITIVE_CAT(Z_UTIL_X2_, y) /** @@ -402,7 +402,7 @@ extern "C" { * { MY_PWM0 , MY_PWM1 } * * @param LEN The length of the sequence. Must be an integer literal less - * than 255. + * than 4095. * @param F A macro function that accepts at least two arguments: * F(i, ...). @p F is called repeatedly in the expansion. * Its first argument @p i is the index in the sequence, and diff --git a/scripts/utils/gen_util_macros.py b/scripts/utils/gen_util_macros.py new file mode 100644 index 00000000000..46db3db4e51 --- /dev/null +++ b/scripts/utils/gen_util_macros.py @@ -0,0 +1,163 @@ +""" +Utility script to generate headers for the following macros +- Z_LISTIFY +- Z_UTIL_INC +- Z_UTIL_DEC +- Z_UTIL_X2 +- Z_IS_EQ + +.. note:: + The script will simply create the header files in the current working directory, + they should be copied manually to $ZEPHYR_BASE/include/zephyr/sys/ accordingly. + +Usage:: + + python $ZEPHYR_BASE/scripts/utils/gen_util_macros.py -l 4095 + +Copyright (c) 2023, Meta +SPDX-License-Identifier: Apache-2.0 +""" + +import argparse + +def write_hidden_start(file): + file.write("/**\n") + file.write(" * @cond INTERNAL_HIDDEN\n") + file.write(" */\n") + + +def write_hidden_stop(file): + file.write("/**\n") + file.write(" * INTERNAL_HIDDEN @endcond\n") + file.write(" */\n") + + +def gen_util_listify(limit:int): + with open("util_listify.h", "w") as file: + write_hidden_start(file) + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_\n") + file.write("#error \"This header should not be used directly, please include util_loops.h instead\"\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_ */\n") + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_\n") + file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_\n") + file.write("\n") + + file.write("/* Set of UTIL_LISTIFY particles */\n") + file.write("#define Z_UTIL_LISTIFY_0(F, sep, ...)\n\n") + file.write("#define Z_UTIL_LISTIFY_1(F, sep, ...) \\\n") + file.write(" F(0, __VA_ARGS__)\n\n") + + for i in range(2, limit + 3): + file.write(f"#define Z_UTIL_LISTIFY_{i}(F, sep, ...) \\\n") + file.write(f" Z_UTIL_LISTIFY_{i - 1}(F, sep, __VA_ARGS__) __DEBRACKET sep \\\n") + file.write(f" F({i - 1}, __VA_ARGS__)\n") + + file.write("\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_ */\n") + file.write("\n") + write_hidden_stop(file) + + +def gen_util_internal_is_eq(limit): + with open("util_internal_is_eq.h", "w") as file: + write_hidden_start(file) + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n") + file.write("#error \"This header should not be used directly, \ +please include util_internal.h instead\"\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n") + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_\n") + file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_\n") + file.write("\n") + + for i in range(0, limit + 1): + file.write(f"#define Z_IS_{i}_EQ_{i}(...) \\,\n") + + file.write("\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ */\n") + file.write("\n") + write_hidden_stop(file) + + +def gen_util_internal_util_inc(limit): + with open("util_internal_util_inc.h", "w") as file: + write_hidden_start(file) + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n") + file.write("#error \"This header should not be used directly, \ +please include util_internal.h instead\"\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n") + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_\n") + file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_\n") + file.write("\n") + + for i in range(0, limit + 2): + file.write(f"#define Z_UTIL_INC_{i} {i + 1}\n") + + file.write("\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_ */\n") + file.write("\n") + write_hidden_stop(file) + + +def gen_util_internal_util_dec(limit): + with open("util_internal_util_dec.h", "w") as file: + write_hidden_start(file) + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n") + file.write("#error \"This header should not be used directly, \ +please include util_internal.h instead\"\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n") + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_\n") + file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_\n") + file.write("\n") + + file.write(f"#define Z_UTIL_DEC_0 0\n") + for i in range(1, limit + 2): + file.write(f"#define Z_UTIL_DEC_{i} {i - 1}\n") + + file.write("\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_ */\n") + file.write("\n") + write_hidden_stop(file) + + +def gen_util_internal_util_x2(limit): + with open("util_internal_util_x2.h", "w") as file: + write_hidden_start(file) + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n") + file.write("#error \"This header should not be used directly, \ +please include util_internal.h instead\"\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n") + file.write("\n") + file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_\n") + file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_\n") + file.write("\n") + + for i in range(0, limit + 1): + file.write(f"#define Z_UTIL_X2_{i} {i *2}\n") + + file.write("\n") + file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_ */\n") + file.write("\n") + write_hidden_stop(file) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument( + "-l", "--limit", type=int, required=True, help="Limit of macros" + ) + args = parser.parse_args() + + gen_util_listify(args.limit) + gen_util_internal_is_eq(args.limit) + gen_util_internal_util_inc(args.limit) + gen_util_internal_util_dec(args.limit) + gen_util_internal_util_x2(args.limit) From 93cbfcfee9916c828f822549b1c2af9943d79029 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 4 Oct 2023 16:08:34 +0800 Subject: [PATCH 1689/4498] board: riscv: qemu: increase ndev of PLIC to 1024 Increase the `ndev` of PLIC to the max of 1024 from 53, as supported by the RISCV PLIC. The total number of IRQs is now 1035(1024 + 11), up from 64(53 + 11). Signed-off-by: Yong Cong Sin --- dts/riscv/virt.dtsi | 2 +- soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/riscv/virt.dtsi b/dts/riscv/virt.dtsi index 45e4a7559a5..caef8cb28d3 100644 --- a/dts/riscv/virt.dtsi +++ b/dts/riscv/virt.dtsi @@ -164,7 +164,7 @@ plic: interrupt-controller@c000000 { riscv,max-priority = <7>; - riscv,ndev = < 0x35 >; + riscv,ndev = < 1024 >; reg = <0x0c000000 0x04000000>; interrupts-extended = < &hlic0 0x0b &hlic0 0x09 diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series b/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series index 77481104e3b..231d4519d67 100644 --- a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series +++ b/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series @@ -31,7 +31,7 @@ config MAX_IRQ_PER_AGGREGATOR default 52 config NUM_IRQS - default 64 + default 1035 config PMP_SLOTS default 16 From 38470a42316c4e15077b238fda229eab8a6e0b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 4 Oct 2023 11:17:20 +0200 Subject: [PATCH 1690/4498] drivers: pwm_nrfx: Connect IRQ handlers for anomaly 109 workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The workaround for the nRF52 anomaly 109 that is implemented in the nrfx_pwm driver uses interrupts generated by a selected EGU instance and by the enabled PWM instances (even if the interrupts are not used in generation of the PWM output signals). Add required IRQ_CONNECT calls so that those interrupts are properly handled. Signed-off-by: Andrzej Głąbek --- drivers/pwm/pwm_nrfx.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 373f8eef7e2..52257dce104 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -15,6 +15,22 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL); +/* NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED can be undefined or defined + * to 0 or 1, hence the use of #if IS_ENABLED(). + */ +#if IS_ENABLED(NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED) +#define ANOMALY_109_IRQ_CONNECT(...) IRQ_CONNECT(__VA_ARGS__) +#define ANOMALY_109_EGU_IRQ_CONNECT(idx) _EGU_IRQ_CONNECT(idx) +#define _EGU_IRQ_CONNECT(idx) \ + extern void nrfx_egu_##idx##_irq_handler(void); \ + IRQ_CONNECT(DT_IRQN(DT_NODELABEL(egu##idx)), \ + DT_IRQ(DT_NODELABEL(egu##idx), priority), \ + nrfx_isr, nrfx_egu_##idx##_irq_handler, 0) +#else +#define ANOMALY_109_IRQ_CONNECT(...) +#define ANOMALY_109_EGU_IRQ_CONNECT(idx) +#endif + #define PWM_NRFX_CH_POLARITY_MASK BIT(15) #define PWM_NRFX_CH_COMPARE_MASK BIT_MASK(15) #define PWM_NRFX_CH_VALUE(compare_value, inverted) \ @@ -238,6 +254,8 @@ static int pwm_nrfx_init(const struct device *dev) int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + ANOMALY_109_EGU_IRQ_CONNECT(NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE); + if (ret < 0) { return ret; } @@ -343,9 +361,16 @@ static int pwm_nrfx_pm_action(const struct device *dev, .seq.length = NRF_PWM_CHANNEL_COUNT, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)), \ }; \ + static int pwm_nrfx_init##idx(const struct device *dev) \ + { \ + ANOMALY_109_IRQ_CONNECT( \ + DT_IRQN(PWM(idx)), DT_IRQ(PWM(idx), priority), \ + nrfx_isr, nrfx_pwm_##idx##_irq_handler, 0); \ + return pwm_nrfx_init(dev); \ + }; \ PM_DEVICE_DT_DEFINE(PWM(idx), pwm_nrfx_pm_action); \ DEVICE_DT_DEFINE(PWM(idx), \ - pwm_nrfx_init, PM_DEVICE_DT_GET(PWM(idx)), \ + pwm_nrfx_init##idx, PM_DEVICE_DT_GET(PWM(idx)), \ &pwm_nrfx_##idx##_data, \ &pwm_nrfx_##idx##_config, \ POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ From 0cd135920a883c89437e9a754dc2a88f4cb39ee2 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 4 Oct 2023 11:11:24 +0800 Subject: [PATCH 1691/4498] kernel: work: check handler when submit to queue Assert that the handler of a work is not NULL when submitting it to the queue. This allows early detection of the code that is submitting a non-NULL work with NULL handler to the work queue (where it happens), rather than right before the work item get executed in the queue (when it happens). Signed-off-by: Yong Cong Sin --- kernel/work.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/work.c b/kernel/work.c index 010cd732183..c5d7c9b5bb8 100644 --- a/kernel/work.c +++ b/kernel/work.c @@ -370,6 +370,7 @@ int z_work_submit_to_queue(struct k_work_q *queue, struct k_work *work) { __ASSERT_NO_MSG(work != NULL); + __ASSERT_NO_MSG(work->handler != NULL); k_spinlock_key_t key = k_spin_lock(&lock); From 019ae15f0567b2a614cf24e2c2b33a82923d73a7 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 5 Oct 2023 16:06:54 +0800 Subject: [PATCH 1692/4498] tests: kernel: work: fix uninitialized timer's work item The `test_1cpu_drain_wait` tests iff the thread of a work queue that is waiting to be drained can submit work item to the queue. A timer is created with a callback funciton to submit a work item to the same queue, to help demonstrate that behavior. However, the work item submitted by `test_drain_wait_cb` to the `coophi_queue` isn't initialized, and can hit assertion if it is processed by the work queue. Fixes #63559 Signed-off-by: Yong Cong Sin --- tests/kernel/workq/work/src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/kernel/workq/work/src/main.c b/tests/kernel/workq/work/src/main.c index 8c3368227cd..68a89588379 100644 --- a/tests/kernel/workq/work/src/main.c +++ b/tests/kernel/workq/work/src/main.c @@ -875,6 +875,7 @@ static void test_drain_wait_cb(struct k_timer *timer) ZTEST(work_1cpu, test_1cpu_drain_wait) { struct test_drain_wait_timer *ctx = &test_drain_wait_ctx; + struct k_work *wp = &ctx->work; int rc; /* Reset state, allow one re-submission, and use the delaying @@ -882,10 +883,10 @@ ZTEST(work_1cpu, test_1cpu_drain_wait) */ reset_counters(); atomic_set(&resubmits_left, 1); - k_work_init(&common_work, delay_handler); + k_work_init(wp, delay_handler); /* Submit to the cooperative queue. */ - rc = k_work_submit_to_queue(&coophi_queue, &common_work); + rc = k_work_submit_to_queue(&coophi_queue, wp); zassert_equal(rc, 1); zassert_equal(coophi_counter(), 0); From c5d844fe41a78bcb361dbd1a11ffafe4de3de97e Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Thu, 28 Sep 2023 13:35:34 +0200 Subject: [PATCH 1693/4498] Bluetooth: controller: fix comparision of unsigned int to 0 Fix the coverity issue CWE570, comparison of unsigned int to 0 in the definition of IS_SYNC_ISO_HANDLE There is a potentially the same issue for IS_ADV_ISO_HANDLE, fixed that as well Signed-off-by: Andries Kruithof --- subsys/bluetooth/controller/ll_sw/ull_iso_types.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso_types.h b/subsys/bluetooth/controller/ll_sw/ull_iso_types.h index 18d9a0f7bfe..457ad1d2458 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_iso_types.h @@ -9,11 +9,18 @@ #define LL_BIS_ADV_HANDLE_BASE BT_CTLR_ADV_ISO_STREAM_HANDLE_BASE #define LL_BIS_ADV_IDX_FROM_HANDLE(conn_handle) \ ((conn_handle) - (LL_BIS_ADV_HANDLE_BASE)) +/* Conditional compile to prevent coverity issue CWE570, comparison of unsigned int to 0 */ +#if (LL_BIS_ADV_HANDLE_BASE > 0) #define IS_ADV_ISO_HANDLE(conn_handle) \ (((conn_handle) >= (LL_BIS_ADV_HANDLE_BASE)) && \ ((conn_handle) <= ((LL_BIS_ADV_HANDLE_BASE) + \ (BT_CTLR_ADV_ISO_STREAM_MAX) - 1U))) #else +#define IS_ADV_ISO_HANDLE(conn_handle) \ + ((conn_handle) <= ((LL_BIS_ADV_HANDLE_BASE) + \ + (BT_CTLR_ADV_ISO_STREAM_MAX) - 1U)) +#endif /* LL_BIS_ADV_HANDLE_BASE */ +#else #define LL_BIS_ADV_IDX_FROM_HANDLE(conn_handle) 0U #define IS_ADV_ISO_HANDLE(conn_handle) 0U #endif /* CONFIG_BT_CTLR_ADV_ISO */ @@ -23,11 +30,18 @@ #define LL_BIS_SYNC_HANDLE_BASE BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE #define LL_BIS_SYNC_IDX_FROM_HANDLE(conn_handle) \ ((conn_handle) - (LL_BIS_SYNC_HANDLE_BASE)) +/* Conditional compile to prevent coverity issue CWE570, comparison of unsigned int to 0 */ +#if (LL_BIS_SYNC_HANDLE_BASE > 0) #define IS_SYNC_ISO_HANDLE(conn_handle) \ (((conn_handle) >= (LL_BIS_SYNC_HANDLE_BASE)) && \ ((conn_handle) <= ((LL_BIS_SYNC_HANDLE_BASE) + \ (BT_CTLR_SYNC_ISO_STREAM_MAX) - 1U))) #else +#define IS_SYNC_ISO_HANDLE(conn_handle) \ + ((conn_handle) <= ((LL_BIS_SYNC_HANDLE_BASE) + \ + (BT_CTLR_SYNC_ISO_STREAM_MAX) - 1U)) +#endif /* LL_BIS_SYNC_HANDLE_BASE */ +#else #define LL_BIS_SYNC_IDX_FROM_HANDLE(conn_handle) 0U #define IS_SYNC_ISO_HANDLE(conn_handle) 0U #endif /* CONFIG_BT_CTLR_SYNC_ISO */ From f4221d66c1985055319393dbc45bd7b519a23731 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 4 Oct 2023 10:29:55 +0200 Subject: [PATCH 1694/4498] Bluetooth: Controller: Make aa in radio_aa_set const Make the aa argument const to solve a Coverity issue that assumes that any value that is being byteswapped is tainted. Making the argument const should avoid this assumption from Coverity. Signed-off-by: Emil Gydesen --- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 2 +- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h | 2 +- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c | 2 +- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index a657ab95dfe..c6becbe322f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -382,7 +382,7 @@ void radio_whiten_iv_set(uint32_t iv) RADIO_PCNF1_WHITEEN_Msk; } -void radio_aa_set(uint8_t *aa) +void radio_aa_set(const uint8_t *aa) { NRF_RADIO->TXADDRESS = (((0UL) << RADIO_TXADDRESS_TXADDRESS_Pos) & diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index 4bf833b233a..fc355af1edc 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -70,7 +70,7 @@ int8_t radio_tx_power_max_get(void); int8_t radio_tx_power_floor(int8_t power); void radio_freq_chan_set(uint32_t chan); void radio_whiten_iv_set(uint32_t iv); -void radio_aa_set(uint8_t *aa); +void radio_aa_set(const uint8_t *aa); void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags); void radio_pkt_rx_set(void *rx_packet); void radio_pkt_tx_set(void *tx_packet); diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c index 6107bfc9c68..ecdf17bbe43 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c @@ -684,7 +684,7 @@ void radio_whiten_iv_set(uint32_t iv) GENFSK->WHITEN_SZ_THR |= GENFSK_WHITEN_SZ_THR_WHITEN_SZ_THR(0); } -void radio_aa_set(uint8_t *aa) +void radio_aa_set(const uint8_t *aa) { /* Configure Access Address detection using NETWORK ADDRESS 0 */ GENFSK->NTW_ADR_0 = *((uint32_t *)aa); diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h index 1168804bbd5..cc3fda99964 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h @@ -20,7 +20,7 @@ void radio_tx_power_set(uint32_t power); void radio_tx_power_max_set(void); void radio_freq_chan_set(uint32_t chan); void radio_whiten_iv_set(uint32_t iv); -void radio_aa_set(uint8_t *aa); +void radio_aa_set(const uint8_t *aa); void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags); void radio_pkt_rx_set(void *rx_packet); void radio_pkt_tx_set(void *tx_packet); From 147cef6660f2f368457447a0fdc94ea06ce268dd Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 3 Oct 2023 15:35:40 +0200 Subject: [PATCH 1695/4498] Bluetooth: Controller: Add hdl checks in isoal.c Add checks to verify the `hdl` parameters before accessing the sink and source arrays. Signed-off-by: Emil Gydesen --- subsys/bluetooth/controller/ll_sw/isoal.c | 78 +++++++++++++++++------ 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index d43233f0289..48ad0835074 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -226,8 +226,17 @@ static isoal_status_t isoal_sink_allocate(isoal_sink_handle_t *hdl) */ static void isoal_sink_deallocate(isoal_sink_handle_t hdl) { - isoal_global.sink_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; - (void)memset(&isoal_global.sink_state[hdl], 0, sizeof(struct isoal_sink)); + if (hdl < ARRAY_SIZE(isoal_global.sink_allocated)) { + isoal_global.sink_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; + } else { + LL_ASSERT(0); + } + + if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { + (void)memset(&isoal_global.sink_state[hdl], 0, sizeof(struct isoal_sink)); + } else { + LL_ASSERT(0); + } } /** @@ -365,12 +374,16 @@ isoal_status_t isoal_sink_create( */ void isoal_sink_enable(isoal_sink_handle_t hdl) { - /* Reset bookkeeping state */ - memset(&isoal_global.sink_state[hdl].sdu_production, 0, - sizeof(isoal_global.sink_state[hdl].sdu_production)); + if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { + /* Reset bookkeeping state */ + memset(&isoal_global.sink_state[hdl].sdu_production, 0, + sizeof(isoal_global.sink_state[hdl].sdu_production)); - /* Atomically enable */ - isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; + /* Atomically enable */ + isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; + } else { + LL_ASSERT(0); + } } /** @@ -379,8 +392,12 @@ void isoal_sink_enable(isoal_sink_handle_t hdl) */ void isoal_sink_disable(isoal_sink_handle_t hdl) { - /* Atomically disable */ - isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; + if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { + /* Atomically disable */ + isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; + } else { + LL_ASSERT(0); + } } /** @@ -1442,7 +1459,13 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) struct isoal_pdu_production *pp; struct isoal_source *source; - source = &isoal_global.source_state[hdl]; + if (hdl < ARRAY_SIZE(isoal_global.source_state)) { + source = &isoal_global.source_state[hdl]; + } else { + LL_ASSERT(0); + return; + } + pp = &source->pdu_production; if (pp->pdu_available > 0) { @@ -1454,8 +1477,13 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) } } - isoal_global.source_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; - (void)memset(&isoal_global.source_state[hdl], 0, sizeof(struct isoal_source)); + if (hdl < ARRAY_SIZE(isoal_global.source_allocated)) { + isoal_global.source_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; + } else { + LL_ASSERT(0); + } + + (void)memset(source, 0, sizeof(struct isoal_source)); } /** @@ -1465,8 +1493,8 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) */ static isoal_status_t isoal_check_source_hdl_valid(isoal_source_handle_t hdl) { - if (hdl < CONFIG_BT_CTLR_ISOAL_SOURCES && - isoal_global.source_allocated[hdl] == ISOAL_ALLOC_STATE_TAKEN) { + if (hdl < ARRAY_SIZE(isoal_global.source_allocated) && + isoal_global.source_allocated[hdl] == ISOAL_ALLOC_STATE_TAKEN) { return ISOAL_STATUS_OK; } @@ -1560,12 +1588,16 @@ isoal_status_t isoal_source_create( */ void isoal_source_enable(isoal_source_handle_t hdl) { - /* Reset bookkeeping state */ - memset(&isoal_global.source_state[hdl].pdu_production, 0, - sizeof(isoal_global.source_state[hdl].pdu_production)); + if (hdl < ARRAY_SIZE(isoal_global.source_state)) { + /* Reset bookkeeping state */ + memset(&isoal_global.source_state[hdl].pdu_production, 0, + sizeof(isoal_global.source_state[hdl].pdu_production)); - /* Atomically enable */ - isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; + /* Atomically enable */ + isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; + } else { + LL_ASSERT(0); + } } /** @@ -1574,8 +1606,12 @@ void isoal_source_enable(isoal_source_handle_t hdl) */ void isoal_source_disable(isoal_source_handle_t hdl) { - /* Atomically disable */ - isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; + if (hdl < ARRAY_SIZE(isoal_global.source_state)) { + /* Atomically disable */ + isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; + } else { + LL_ASSERT(0); + } } /** From e032f9520dfe545eb21d28cdd270d3b6baa26383 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Sun, 1 Oct 2023 12:39:47 +1300 Subject: [PATCH 1696/4498] drivers: systick: Fix Cortex-M systick jumping forward and back again The existing implementation did not properly handle when `SysTick->VAL` is zero. This caused three subtle edge cases: * val1=0,COUNTFLAG=0,val2=0 This should result in no cycles elapsed, however `(last_load - val2) = last_load`. So an extra `last_load` cycles was returned. * val1=0,COUNTFLAG=0,val2=(last_load-1) This should result in 1 cycle elapsed, however `val1 < val2` so an extra `last_load` cycles was returned. * val1=[2,1,0],COUNTFLAG=1,val2=0 This should result in `last_load` cycles elapsed. However, `last_load * 2` cycles was returned. To fix the calculation, val1 and val2 are first wrapped/realigned from [0:last_load-1] to [1:last_load]. Tidy comments to better reflect the SysTick behaviour and link reference manuals. Signed-off-by: Grant Ramsay --- drivers/timer/cortex_m_systick.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index f415f99ea0d..ff4414c5619 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -101,10 +101,19 @@ static uint32_t elapsed(void) uint32_t ctrl = SysTick->CTRL; /* B */ uint32_t val2 = SysTick->VAL; /* C */ - /* SysTick behavior: The counter wraps at zero automatically, - * setting the COUNTFLAG field of the CTRL register when it - * does. Reading the control register automatically clears - * that field. + /* SysTick behavior: The counter wraps after zero automatically. + * The COUNTFLAG field of the CTRL register is set when it + * decrements from 1 to 0. Reading the control register + * automatically clears that field. When a timer is started, + * count begins at zero then wraps after the first cycle. + * Reference: + * Armv6-m (B3.3.1) https://developer.arm.com/documentation/ddi0419 + * Armv7-m (B3.3.1) https://developer.arm.com/documentation/ddi0403 + * Armv8-m (B11.1) https://developer.arm.com/documentation/ddi0553 + * + * First, manually wrap/realign val1 and val2 from [0:last_load-1] + * to [1:last_load]. This allows subsequent code to assume that + * COUNTFLAG and wrapping occur on the same cycle. * * If the count wrapped... * 1) Before A then COUNTFLAG will be set and val1 >= val2 @@ -115,6 +124,13 @@ static uint32_t elapsed(void) * So the count in val2 is post-wrap and last_load needs to be * added if and only if COUNTFLAG is set or val1 < val2. */ + if (val1 == 0) { + val1 = last_load; + } + if (val2 == 0) { + val2 = last_load; + } + if ((ctrl & SysTick_CTRL_COUNTFLAG_Msk) || (val1 < val2)) { overflow_cyc += last_load; From 1951d837836a1d2fadf7bf6840a33e9fecdc519d Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Sun, 1 Oct 2023 12:42:35 +1300 Subject: [PATCH 1697/4498] tests: timer_monotonic: Add mps2_an385 test with icount disabled This is to validate that GH-48608 is fixed and stays fixed. Signed-off-by: Grant Ramsay --- tests/kernel/timer/timer_monotonic/testcase.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/kernel/timer/timer_monotonic/testcase.yaml b/tests/kernel/timer/timer_monotonic/testcase.yaml index 058a821123b..9c38d456986 100644 --- a/tests/kernel/timer/timer_monotonic/testcase.yaml +++ b/tests/kernel/timer/timer_monotonic/testcase.yaml @@ -15,3 +15,11 @@ tests: extra_configs: - CONFIG_APIC_TSC_DEADLINE_TIMER=y - CONFIG_HPET_TIMER=n + kernel.timer.monotonic.icount_off: + # Extra test for GH-48608 + tags: + - kernel + - timer + platform_allow: mps2_an385 + extra_configs: + - CONFIG_QEMU_ICOUNT=n From 236318332b84496f69feef9080bd1b0145be6c82 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Wed, 4 Oct 2023 10:08:42 +1300 Subject: [PATCH 1698/4498] drivers: systick: Fix Cortex-M SysTick dropping 1 cycle per tick `last_load` is the full N cycles and `SysTick->LOAD` should be loaded with `last_load - 1` for the calculations work correctly. Note: This only affects a kernel in ticked operation. Tickless kernels periodically restart the timer correctly. Signed-off-by: Grant Ramsay --- drivers/timer/cortex_m_systick.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index ff4414c5619..e026c3603c6 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -314,9 +314,9 @@ static int sys_clock_driver_init(void) { NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET); - last_load = CYC_PER_TICK - 1; + last_load = CYC_PER_TICK; overflow_cyc = 0U; - SysTick->LOAD = last_load; + SysTick->LOAD = last_load - 1; SysTick->VAL = 0; /* resets timer to last_load */ SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | From 7aebe0c2a48977241510cee049fb40a3155d512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 20:11:39 +0200 Subject: [PATCH 1699/4498] boards/sparc: Update simulator_exec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tsim executable is named tsim-leon3, tsim-leon4, tsim-gr716, etc. This is needed to find the emulator program for twister to do the run step. Signed-off-by: Martin Åberg --- boards/sparc/generic_leon3/generic_leon3.yaml | 2 +- boards/sparc/gr716a_mini/gr716a_mini.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/sparc/generic_leon3/generic_leon3.yaml b/boards/sparc/generic_leon3/generic_leon3.yaml index 7f16d2f25d5..0ada3593846 100644 --- a/boards/sparc/generic_leon3/generic_leon3.yaml +++ b/boards/sparc/generic_leon3/generic_leon3.yaml @@ -2,7 +2,7 @@ identifier: generic_leon3 name: Generic LEON3 system type: mcu simulation: tsim -simulation_exec: tsim +simulation_exec: tsim-leon3 arch: sparc ram: 4096 flash: 2048 diff --git a/boards/sparc/gr716a_mini/gr716a_mini.yaml b/boards/sparc/gr716a_mini/gr716a_mini.yaml index 09e39864a62..228eb701232 100644 --- a/boards/sparc/gr716a_mini/gr716a_mini.yaml +++ b/boards/sparc/gr716a_mini/gr716a_mini.yaml @@ -2,7 +2,7 @@ identifier: gr716a_mini name: GR716-MINI Development Board type: mcu simulation: tsim -simulation_exec: tsim +simulation_exec: tsim-leon3 arch: sparc toolchain: - zephyr From 7fb2929e5ba058da82716b6555f75c112c252072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 20:08:06 +0200 Subject: [PATCH 1700/4498] boards/sparc: Ignore tests for net and bluetooth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These boards do not typically use Bluetooth or the Zephyr network stack. Signed-off-by: Martin Åberg --- boards/sparc/generic_leon3/generic_leon3.yaml | 4 ++++ boards/sparc/gr716a_mini/gr716a_mini.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/boards/sparc/generic_leon3/generic_leon3.yaml b/boards/sparc/generic_leon3/generic_leon3.yaml index 0ada3593846..3aecda82e0e 100644 --- a/boards/sparc/generic_leon3/generic_leon3.yaml +++ b/boards/sparc/generic_leon3/generic_leon3.yaml @@ -11,4 +11,8 @@ toolchain: - xtools supported: - netif +testing: + ignore_tags: + - net + - bluetooth vendor: gaisler diff --git a/boards/sparc/gr716a_mini/gr716a_mini.yaml b/boards/sparc/gr716a_mini/gr716a_mini.yaml index 228eb701232..4107097aab5 100644 --- a/boards/sparc/gr716a_mini/gr716a_mini.yaml +++ b/boards/sparc/gr716a_mini/gr716a_mini.yaml @@ -9,4 +9,8 @@ toolchain: - xtools supported: - netif +testing: + ignore_tags: + - net + - bluetooth vendor: gaisler From 8b4994f22fe9185cafff84fae33d392837f6d81e Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 5 Oct 2023 11:20:45 +0200 Subject: [PATCH 1701/4498] tests: bluetooth: tester: Allow to pass int instead of bool in comp cmd This will allow to choose more variants of cdp in future if needed. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 6b58d1515dc..c2636d1445d 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -78,7 +78,7 @@ struct btp_mesh_provision_node_cmd_v2 { #define BTP_MESH_INIT 0x04 struct btp_mesh_init_cmd { - bool comp_alt; + uint8_t comp; } __packed; #define BTP_MESH_RESET 0x05 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 083d2987150..a2574636902 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1243,7 +1243,7 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, const struct btp_mesh_init_cmd *cp = cmd; int err; - if (!cp->comp_alt) { + if (cp->comp == 0) { LOG_WRN("Loading default comp data"); err = bt_mesh_init(&prov, &comp); } else { From fed811573326c163cf5d3773c168a1723589f65f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 5 Oct 2023 10:27:47 +0100 Subject: [PATCH 1702/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 13767d0b72eb14ce42eb8aad1e5a133ef66afc54 Brings following Zephyr relevant fixes: - bootutil: Disable MCUBOOT_BOOT_MAX_ALIGN assert for non-swap modes Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 4556e0dcaa7..33f1dd3e9ba 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 4fe28b3cf6d30c3e57d6a4f7ee3dba8617aa9a0a + revision: 13767d0b72eb14ce42eb8aad1e5a133ef66afc54 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From b3c515075301fb49ee7651e1770ed68cddad3beb Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 5 Oct 2023 10:29:29 +0100 Subject: [PATCH 1703/4498] doc: release: 3.5: Add fixed bug to MCUboot log Adds a note on a bug being fixed with align on non-swap modes Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 3e72a039516..63be9550fa0 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -507,6 +507,8 @@ MCUboot * Fixed issue with serial recovery use of MBEDTLS having undefined operations which led to usage faults when the secondary slot image was encrypted. + * Fixed issue with bootutil asserting on maximum alignment in non-swap modes. + * Added error output when flash device fails to open and asserts are disabled, which will now panic the bootloader. From 1816b6380b14590a4eb35f22107bff3af4924ae2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 5 Oct 2023 14:36:26 +0200 Subject: [PATCH 1704/4498] modem: modem_cmux: Set C/R bit in UIH frames This commit sets the C/R (command/response) bit when UIH CMUX frames are sent from the modem_cmux module. This bit is ignored by some modems like the Quectel BG95, as there is no defined response to this specific CMUX frame type. However, other modems, like the TELIT ME910, require the bit to be set (command). If the bit is not set, the modem will simply ignore the frame completely. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 2 +- tests/subsys/modem/modem_cmux/src/main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index d91514d6178..690af4ddce8 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -790,7 +790,7 @@ static int modem_cmux_dlci_pipe_api_transmit(void *data, const uint8_t *buf, siz struct modem_cmux_frame frame = { .dlci_address = dlci->dlci_address, - .cr = false, + .cr = true, .pf = false, .type = MODEM_CMUX_FRAME_TYPE_UIH, .data = buf, diff --git a/tests/subsys/modem/modem_cmux/src/main.c b/tests/subsys/modem/modem_cmux/src/main.c index 115b3bd89b9..243aa6112c8 100644 --- a/tests/subsys/modem/modem_cmux/src/main.c +++ b/tests/subsys/modem/modem_cmux/src/main.c @@ -150,10 +150,10 @@ static uint8_t cmux_frame_resync[] = {0xF9, 0xF9, 0xF9}; /* DLCI2 PPP CMUX frames */ /*************************************************************************************************/ static uint8_t cmux_frame_dlci2_ppp_52[] = { - 0xF9, 0x09, 0xEF, 0x69, 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0x7D, 0x20, 0x7D, + 0xF9, 0x0B, 0xEF, 0x69, 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x38, 0x7D, 0x22, 0x7D, 0x26, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x23, 0x7D, 0x24, 0xC0, 0x23, 0x7D, 0x25, 0x7D, 0x26, 0x53, 0x96, 0x7D, 0x38, 0xAA, - 0x7D, 0x27, 0x7D, 0x22, 0x7D, 0x28, 0x7D, 0x22, 0xD5, 0xA8, 0x7E, 0x97, 0xF9}; + 0x7D, 0x27, 0x7D, 0x22, 0x7D, 0x28, 0x7D, 0x22, 0xD5, 0xA8, 0x7E, 0xF6, 0xF9}; static uint8_t cmux_frame_data_dlci2_ppp_52[] = { 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0x7D, 0x20, 0x7D, 0x20, 0x7D, @@ -161,9 +161,9 @@ static uint8_t cmux_frame_data_dlci2_ppp_52[] = { 0x7D, 0x23, 0x7D, 0x24, 0xC0, 0x23, 0x7D, 0x25, 0x7D, 0x26, 0x53, 0x96, 0x7D, 0x38, 0xAA, 0x7D, 0x27, 0x7D, 0x22, 0x7D, 0x28, 0x7D, 0x22, 0xD5, 0xA8, 0x7E}; -static uint8_t cmux_frame_dlci2_ppp_18[] = {0xF9, 0x09, 0xEF, 0x25, 0x7E, 0xFF, 0x7D, 0x23, +static uint8_t cmux_frame_dlci2_ppp_18[] = {0xF9, 0x0B, 0xEF, 0x25, 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20, - 0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E, 0xEE, 0xF9}; + 0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E, 0x8F, 0xF9}; static uint8_t cmux_frame_data_dlci2_ppp_18[] = {0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20, From 9e8d609b5d20d3e07fb0eb4907213c02bdab95ce Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Thu, 5 Oct 2023 08:49:58 -0500 Subject: [PATCH 1705/4498] rtio: Remove unused Kconfigs for executors There's only one executor now and its always built, no need for these old crufty Kconfigs. Signed-off-by: Tom Burdick --- subsys/rtio/Kconfig | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/subsys/rtio/Kconfig b/subsys/rtio/Kconfig index 3a28bbdf965..7231d6fefbb 100644 --- a/subsys/rtio/Kconfig +++ b/subsys/rtio/Kconfig @@ -6,21 +6,6 @@ menuconfig RTIO if RTIO -config RTIO_EXECUTOR_SIMPLE - bool "A simple executor for RTIO" - default y - help - An simple RTIO executor that will execute a queue of requested I/O - operations as if they are a single chain of submission queue entries. This - does not support concurrent chains or submissions. - -config RTIO_EXECUTOR_CONCURRENT - bool "A low cost concurrent executor for RTIO" - default y - help - A low memory cost RTIO executor that will execute a queue of requested I/O - with a fixed amount of concurrency using minimal memory overhead. - config RTIO_SUBMIT_SEM bool "Use a semaphore when waiting for completions in rtio_submit" help From 3ba4b6f95b10909975f245db3eabd896ecdd458c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 5 Oct 2023 12:28:47 +0200 Subject: [PATCH 1706/4498] doc: Improve documentation guidelines intro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intro of this document was starting to show its age. Simplified some of the wording and added a reference to the documentation build instructions. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/guidelines.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index 20ca94e2948..a98fa751916 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -11,11 +11,10 @@ Zephyr Project content is written using the `reStructuredText`_ markup language (.rst file extension) with Sphinx extensions, and processed using Sphinx to create a formatted standalone website. Developers can view this content either in its raw form as .rst markup files, or (with -Sphinx installed) they can build the documentation using the Makefile -on Linux systems, or make.bat on Windows, to -generate the HTML content. The HTML content can then be viewed using a -web browser. This same .rst content is also fed into the -`Zephyr documentation`_ website (with a different theme applied). +Sphinx installed) they can :ref:`build the documentation ` locally +to generate the documentation in HTML or PDF format. The HTML content can +then be viewed using a web browser. This same .rst content is served by the +`Zephyr documentation`_ website. You can read details about `reStructuredText`_ and about `Sphinx extensions`_ from their respective websites. From 620f6b9a6de000c87ce30ed5db7ea7314f87d1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 5 Oct 2023 18:18:17 +0200 Subject: [PATCH 1707/4498] doc: guidelines: remove stale mention to nightly builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the mention to nightly builds being posted to the build@ mailing list. Signed-off-by: Benjamin Cabé --- doc/contribute/guidelines.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 82e903580bf..7f11d078419 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -950,10 +950,6 @@ results page where a table with all the different builds will be shown. To see what build or test failed click on the row that contains the failed (i.e. non-green) build. -The `builds@lists.zephyrproject.org mailing list -`_ archives any nightly build results -produced by CI. - Contributions to External Modules ********************************** From 6db5d84dbbbe0a2365d2425380dd6bacb4b584bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 4 Oct 2023 21:51:16 +0200 Subject: [PATCH 1708/4498] doc: Improve "Contributing to Zephyr" landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Contributing to Zephyr" page used to be a simple table of contents with pointers to sub-pages. This bland page was not very inviting to new contributors, and provided little to no context as to what to expect in each sub-section. This commit improves the landing page by implenmenting the following changes: - Remove auto toctree and replace with manually curated entries that provide more context about each sub-section. - Add a section about the Zephyr Contributor Badge. - Add a section about getting help, with links to Discord and dev mailing list. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/index.rst | 10 --- doc/contribute/index.rst | 101 ++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 13 deletions(-) delete mode 100644 doc/contribute/documentation/index.rst diff --git a/doc/contribute/documentation/index.rst b/doc/contribute/documentation/index.rst deleted file mode 100644 index 0bb801fb36d..00000000000 --- a/doc/contribute/documentation/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _documentation: - -Documentation -############# - -.. toctree:: - :maxdepth: 1 - - guidelines.rst - generation.rst diff --git a/doc/contribute/index.rst b/doc/contribute/index.rst index d57f5156975..44106539d53 100644 --- a/doc/contribute/index.rst +++ b/doc/contribute/index.rst @@ -3,13 +3,108 @@ Contributing to Zephyr ###################### +Contributions from the community are the backbone of the project. Whether it is by submitting code, +improving documentation, or proposing new features, your efforts are highly appreciated. This page +lists useful resources and guidelines to help you in your contribution journey. + +General Guidelines +================== + .. toctree:: :maxdepth: 1 + :hidden: guidelines.rst - contributor_expectations.rst - proposals_and_rfcs.rst coding_guidelines/index.rst - documentation/index.rst + proposals_and_rfcs.rst + contributor_expectations.rst + +:ref:`contribute_guidelines` + Learn about the overall process and guidelines for contributing to the Zephyr project. + + This page is a mandatory read for first-time contributors as it contains important information on + how to ensure your contribution can be considered for inclusion in the project and potentially + merged. + +:ref:`contributor-expectations` + This document is another mandatory read that describes the expected behavior of `all` + contributors to the project. + +:ref:`coding_guidelines` + Code contributions are expected to follow a set of coding guidelines to ensure consistency and + readability across the code base. + + This page describes these guidelines and introduces important considerations regarding the use of + :ref:`inclusive language `. + +:ref:`rfcs` + Learn when and how to submit RFCs (Request for Comments) for new features and changes to the + project. + +Documentation +============= + +The Zephyr project thrives on good documentation. Whether it is as part of a code contribution or +as a standalone effort, contributing documentation is particularly valuable to the project. + +.. toctree:: + :maxdepth: 1 + :hidden: + + documentation/guidelines.rst + documentation/generation.rst + +:ref:`doc_guidelines` + This page provides some simple guidelines for writing documentation using the reSTructuredText + (reST) markup language and Sphinx documentation generator. + +:ref:`zephyr_doc` + As you write documentation, it can be helpful to see how it will look when rendered. + + This page describes how to build the Zephyr documentation locally. + + +Dealing with external components +================================ + +.. toctree:: + :maxdepth: 1 + :hidden: + external.rst bin_blobs.rst + +:ref:`external-contributions` + Basic functionality or features that would make useful addition to Zephyr might be readily + available in other open source projects, and it is recommended and encouraged to reuse such code. + This page describes in more details when and how to import external source code into Zephyr. + +:ref:`external-tooling` + Similarly, external tooling used during compilation, code analysis, testing or simulation, can be + beneficial and is covered in this section. + +:ref:`bin-blobs` + As some functionality might only be made available with the help of executable code distributed + in binary form, this page describes the process and guidelines for :ref:`contributing binary + blobs ` to the project. + +Zephyr Contributor Badge +======================== + +When your first contribution to the Zephyr project gets merged, you'll become eligible to claim your +Zephyr Contributor Badge. This digital badge can be displayed on your website, blog, social media +profile, etc. It will allow you to showcase your involvement in the Zephyr project and help raise +its awareness. + +You may apply for your Contributor Badge by filling out the `Zephyr Contributor Badge form`_. + +Need help along the way? +======================== + +If you have questions related to the contribution process, the Zephyr community is here to help. +You may join our Discord_ channel or use the `Developer Mailing List`_. + + +.. _Discord: https://chat.zephyrproject.org +.. _Developer Mailing List: https://lists.zephyrproject.org/g/devel +.. _Zephyr Contributor Badge form: https://forms.gle/oCw9iAPLhUsHTapc8 From 468973513a20e4159845765cd7123da3bece43e9 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Thu, 5 Oct 2023 12:52:07 -0600 Subject: [PATCH 1709/4498] rtio: cleanup blocking loop The current blocking model will try calling `rtio_mpsc_pop` twice in a row without any delay. Probably not the actual intent. Signed-off-by: Yuval Peress --- include/zephyr/rtio/rtio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index ecbacb9a161..8ad07281cee 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -986,8 +986,8 @@ static inline struct rtio_cqe *rtio_cqe_consume_block(struct rtio *r) #endif node = rtio_mpsc_pop(&r->cq); while (node == NULL) { - node = rtio_mpsc_pop(&r->cq); Z_SPIN_DELAY(1); + node = rtio_mpsc_pop(&r->cq); } cqe = CONTAINER_OF(node, struct rtio_cqe, q); From e89b005368a638d5a6fdfefedf187c5c7defe580 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Wed, 4 Oct 2023 16:27:57 +0530 Subject: [PATCH 1710/4498] drivers: pcie: add config for enable PRT add config support for enable IRQ information retrieve via ACPI PRT (PCI Routing Table) Signed-off-by: Najumon B.A --- drivers/pcie/host/Kconfig | 7 +++++++ drivers/pcie/host/pcie.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pcie/host/Kconfig b/drivers/pcie/host/Kconfig index 80925657702..2dcb9bba612 100644 --- a/drivers/pcie/host/Kconfig +++ b/drivers/pcie/host/Kconfig @@ -73,6 +73,13 @@ config PCIE_PTM This will enable support both PTM root and PTM requester features. Up to the PCIe device driver to enable its PTM requester capability. +config PCIE_PRT + bool "Support for IRQ information retrieve via ACPI PRT (PCI Routing Table)" + default y if ACPI_DSDT_SUPPORT + help + This will enable retrieve interrupt routing information for PCI legacy + interrupt via ACPI PRT (PCI Routing Table) + config PCIE_SHELL bool "PCIe/new PCI Shell" default y diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c index 1d6c1678094..a4d9fdbe504 100644 --- a/drivers/pcie/host/pcie.c +++ b/drivers/pcie/host/pcie.c @@ -291,7 +291,7 @@ unsigned int pcie_alloc_irq(pcie_bdf_t bdf) irq >= CONFIG_MAX_IRQ_LINES || arch_irq_is_used(irq)) { -#ifdef CONFIG_ACPI +#ifdef CONFIG_PCIE_PRT irq = acpi_legacy_irq_get(bdf); #else irq = arch_irq_allocate(); From bec3b09f3823f6ffe46cd6b0d28694e5e0b1e337 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Wed, 4 Oct 2023 16:29:30 +0530 Subject: [PATCH 1711/4498] boards: ehl: disable PRT support for PCI interrupt disable PRT support for retrieve interrupt routing information for PCI legacy interrupt via ACPI PRT Signed-off-by: Najumon B.A --- boards/x86/intel_ehl/intel_ehl_crb_defconfig | 1 + boards/x86/intel_ehl/intel_ehl_crb_sbl_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/x86/intel_ehl/intel_ehl_crb_defconfig b/boards/x86/intel_ehl/intel_ehl_crb_defconfig index 7b4bfc6f9b7..e25760a5a05 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb_defconfig +++ b/boards/x86/intel_ehl/intel_ehl_crb_defconfig @@ -11,3 +11,4 @@ CONFIG_X2APIC=y CONFIG_SMP=y CONFIG_BUILD_OUTPUT_EFI=y CONFIG_BUILD_NO_GAP_FILL=y +CONFIG_PCIE_PRT=n diff --git a/boards/x86/intel_ehl/intel_ehl_crb_sbl_defconfig b/boards/x86/intel_ehl/intel_ehl_crb_sbl_defconfig index aeac38cda96..1ccff387dc1 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb_sbl_defconfig +++ b/boards/x86/intel_ehl/intel_ehl_crb_sbl_defconfig @@ -9,3 +9,4 @@ CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_X2APIC=y CONFIG_SMP=y +CONFIG_PCIE_PRT=n From b86b4b96a166821e7049bd4ecd673c4322c5ec01 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Wed, 4 Oct 2023 18:24:07 +0530 Subject: [PATCH 1712/4498] lib: acpi: update DSDT Kconfig with condition enable update DSDT_SUPPORT Kconfig with condition enable only if both ACPI and PCI enabled Signed-off-by: Najumon B.A --- modules/acpica/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/acpica/Kconfig b/modules/acpica/Kconfig index 29153cd78dd..18e7cd1482a 100644 --- a/modules/acpica/Kconfig +++ b/modules/acpica/Kconfig @@ -1,10 +1,12 @@ # Copyright (c) 2023 Intel Corporation. # SPDX-License-Identifier: Apache-2.0 +menu "ACPI driver support" + config ACPI bool -menu "ACPI driver support" +if ACPI config ACPI_DSDT_SUPPORT bool "Build source code for DSDT ACPICA support" @@ -12,4 +14,6 @@ config ACPI_DSDT_SUPPORT help Build source code for DSDT support +endif #ACPI + endmenu From cb1b1ce7d111fe830eade1dfbd95229f10f99005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 6 Oct 2023 09:17:05 +0200 Subject: [PATCH 1713/4498] bluetooth: common: Kconfig: Add missing dependency for BT_MONITOR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This module calls `log_output_*` functions so it should enable the `LOG_OUTPUT` Kconfig option explicitly. Signed-off-by: Andrzej Głąbek --- subsys/bluetooth/common/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index d72ce90afa6..bf4aee75e48 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -282,6 +282,7 @@ endif # BT_ASSERT config BT_MONITOR bool + select LOG_OUTPUT choice BT_DEBUG_TYPE prompt "Bluetooth debug type" From a5e7ba356465cdf0b7f3387f5b46ddc016339250 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 5 Oct 2023 12:55:24 +0200 Subject: [PATCH 1714/4498] Bluetooth: Controller: Remove legacy BT_CTLR_FAST_ENC option When the legacy LLCP implementation was removed this Kconfig option was mistakenly left over. Remove it now with all its users. Fixes #63212. Signed-off-by: Carles Cufi --- drivers/entropy/entropy_nrf5.c | 5 ----- drivers/entropy/entropy_smartbond.c | 5 ----- drivers/entropy/entropy_stm32.c | 9 +-------- subsys/bluetooth/controller/Kconfig.ll_sw_split | 12 ------------ tests/bluetooth/init/prj_ctlr_4_0.conf | 1 - tests/bluetooth/init/prj_ctlr_4_0_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_ticker.conf | 1 - tests/bluetooth/init/prj_ctlr_tiny.conf | 1 - 10 files changed, 1 insertion(+), 36 deletions(-) diff --git a/drivers/entropy/entropy_nrf5.c b/drivers/entropy/entropy_nrf5.c index 8febcfacb15..2f04bc06a37 100644 --- a/drivers/entropy/entropy_nrf5.c +++ b/drivers/entropy/entropy_nrf5.c @@ -116,10 +116,6 @@ static int random_byte_get(void) return retval; } -#pragma GCC push_options -#if defined(CONFIG_BT_CTLR_FAST_ENC) -#pragma GCC optimize ("Ofast") -#endif static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -175,7 +171,6 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) return len; } -#pragma GCC pop_options static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/drivers/entropy/entropy_smartbond.c b/drivers/entropy/entropy_smartbond.c index 0058baafce5..28b6f08e100 100644 --- a/drivers/entropy/entropy_smartbond.c +++ b/drivers/entropy/entropy_smartbond.c @@ -100,10 +100,6 @@ static int random_word_get(uint8_t buf[4]) return retval; } -#pragma GCC push_options -#if defined(CONFIG_BT_CTLR_FAST_ENC) -#pragma GCC optimize("Ofast") -#endif static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -159,7 +155,6 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) return len; } -#pragma GCC pop_options static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index cecff05e9e3..6627c648c47 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -378,13 +378,7 @@ static void pool_filling_work_handler(struct k_work *work) } } -#if defined(CONFIG_BT_CTLR_FAST_ENC) -#define __fast __attribute__((optimize("Ofast"))) -#else -#define __fast -#endif - -__fast static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, +static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -449,7 +443,6 @@ __fast static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, return len; } -#undef __fast static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index a7dade7a1db..e2975107f86 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -760,18 +760,6 @@ config BT_CTLR_PARAM_CHECK if BT_CONN -config BT_CTLR_FAST_ENC - bool "Fast Encryption Setup" - depends on BT_CTLR_LE_ENC - default y if BT_HCI_RAW - help - Enable connection encryption setup in 4 connection events. - Peripheral will respond to Encryption Request with Encryption Response - in the next connection event, and will transmit Start Encryption - Request PDU in the same connection event, hence completing encryption - setup in 4 connection events. Encrypted data would be transmitted as - fast as in 4th connection event from Encryption Request. - config BT_CTLR_LLCP_CONN int "Number of connections with worst-case overlapping procedures" default BT_MAX_CONN diff --git a/tests/bluetooth/init/prj_ctlr_4_0.conf b/tests/bluetooth/init/prj_ctlr_4_0.conf index ff3917be54b..4f9ec70d3bb 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0.conf @@ -19,7 +19,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=y CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y -CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n diff --git a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf index 4c101cc6e16..5fc61cf98c6 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf @@ -21,7 +21,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=y CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y -CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf index df0d006a13e..50f72889476 100644 --- a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf @@ -29,7 +29,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n -CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_dbg.conf b/tests/bluetooth/init/prj_ctlr_dbg.conf index 6aff0965ce9..2f8224cdfea 100644 --- a/tests/bluetooth/init/prj_ctlr_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_dbg.conf @@ -23,7 +23,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n -CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf index d77f519406b..4e5b962231e 100644 --- a/tests/bluetooth/init/prj_ctlr_ticker.conf +++ b/tests/bluetooth/init/prj_ctlr_ticker.conf @@ -23,7 +23,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n -CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_tiny.conf b/tests/bluetooth/init/prj_ctlr_tiny.conf index 7679de9a661..ce75583da16 100644 --- a/tests/bluetooth/init/prj_ctlr_tiny.conf +++ b/tests/bluetooth/init/prj_ctlr_tiny.conf @@ -22,7 +22,6 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y -CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n From 23b977d1c4b9c2ce13e526552f23c7d98795872f Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Fri, 29 Sep 2023 18:01:43 +0300 Subject: [PATCH 1715/4498] bindesc: Use UTC time by default and comply with ISO-8601 Use UTC time by default, and add the option to use local time. Also, change the default formats to comply with ISO-8601. Signed-off-by: Yonatan Schachter --- subsys/bindesc/CMakeLists.txt | 14 +++++++++++-- subsys/bindesc/Kconfig.build_time | 35 ++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/subsys/bindesc/CMakeLists.txt b/subsys/bindesc/CMakeLists.txt index 72634be12e6..7419a78e5a9 100644 --- a/subsys/bindesc/CMakeLists.txt +++ b/subsys/bindesc/CMakeLists.txt @@ -9,9 +9,19 @@ else() zephyr_linker_sources(ROM_START SORT_KEY 0x1bindesc bindesc.ld) endif() +# Wrapper macro around string(TIMESTAMP ...), that returns the time +# in either local time or UTC, depending on CONFIG_BINDESC_BUILD_TIME_USE_LOCAL_TIME. +macro(get_time out_var format) + if(CONFIG_BINDESC_BUILD_TIME_USE_LOCAL_TIME) + string(TIMESTAMP ${out_var} ${format}) + else() + string(TIMESTAMP ${out_var} ${format} UTC) + endif() +endmacro() + macro(gen_build_time_int_definition def_name format) if(CONFIG_BINDESC_${def_name}) - string(TIMESTAMP ${def_name} ${format}) + get_time(${def_name} ${format}) # remove leading zeros so that the output will not be interpreted as octal math(EXPR ${def_name} ${${def_name}}) zephyr_library_compile_definitions(${def_name}=${${def_name}}) @@ -20,7 +30,7 @@ endmacro() macro(gen_build_time_str_definition def_name format) if(CONFIG_BINDESC_${def_name}) - string(TIMESTAMP ${def_name} ${${format}}) + get_time(${def_name} ${${format}}) zephyr_library_compile_definitions(${def_name}="${${def_name}}") endif() endmacro() diff --git a/subsys/bindesc/Kconfig.build_time b/subsys/bindesc/Kconfig.build_time index 4c1a4c7c7de..f9917008852 100644 --- a/subsys/bindesc/Kconfig.build_time +++ b/subsys/bindesc/Kconfig.build_time @@ -8,6 +8,12 @@ menuconfig BINDESC_DEFINE_BUILD_TIME if BINDESC_DEFINE_BUILD_TIME +config BINDESC_BUILD_TIME_USE_LOCAL_TIME + bool "Use local time" + help + If enabled, the build time used for the descriptors will express + the local time, rather than UTC. + config BINDESC_BUILD_TIME_ALWAYS_REBUILD bool "Always rebuild" default y @@ -55,52 +61,57 @@ config BINDESC_BUILD_TIME_UNIX config BINDESC_BUILD_DATE_TIME_STRING bool "Build date and time as string" help - The date and time of compilation as a string, such as "2023/02/05 00:07:04" + The date and time of compilation as a string, such as "2023-09-29T17:43:14+0000" config BINDESC_BUILD_DATE_STRING bool "Build date as string" help - The date of compilation as a string, such as "2023/02/05" + The date of compilation as a string, such as "2023-09-29" config BINDESC_BUILD_TIME_STRING bool "Build time as string" help - The time of compilation as a string, such as "00:07:04" + The time of compilation as a string, such as "T17:43:14+0000" config BINDESC_BUILD_DATE_TIME_STRING_FORMAT depends on BINDESC_BUILD_DATE_TIME_STRING string "Date-Time format" - default "%Y/%m/%d %H:%M:%S" + default "%Y-%m-%dT%H:%M:%S%z" help Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...) function, so refer to string's documentation for more info on the different formats. This can also be used to set a specific time, when trying to reproduce an image. For - example, setting the format to "2023/02/05 00:07:04" will set it as the build time, + example, setting the format to "2023-02-05T00:07:04+0000" will set it as the build time, regardless of the actual build time. - Example of the default format: 2023/02/05 00:07:04 + If BINDESC_BUILD_TIME_USE_LOCAL_TIME is enabled, the time is the local time, else + it is UTC time. + Example of the default format: 2023-09-29T17:43:14+0000. + Note: the default format complies with ISO-8601. config BINDESC_BUILD_DATE_STRING_FORMAT depends on BINDESC_BUILD_DATE_STRING string "Date format" - default "%Y/%m/%d" + default "%Y-%m-%d" help Format of the build date string. This value is passed to cmake's string(TIMESTAMP ...) function, so refer to string's documentation for more info on the different formats. This can also be used to set a specific time, when trying to reproduce an image. For - example, setting the format to "2023/02/05" will set it as the build time, + example, setting the format to "2023-02-05" will set it as the build time, regardless of the actual build time. - Example of the default format: 2023/02/05 + Example of the default format: 2023-02-05 + Note: the default format complies with ISO-8601. config BINDESC_BUILD_TIME_STRING_FORMAT depends on BINDESC_BUILD_TIME_STRING string "Time format" - default "%H:%M:%S" + default "T%H:%M:%S%z" help Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...) function, so refer to string's documentation for more info on the different formats. This can also be used to set a specific time, when trying to reproduce an image. For - example, setting the format to "00:07:04" will set it as the build time, + example, setting the format to "T00:07:04+0000" will set it as the build time, regardless of the actual build time. - Example of the default format: 00:07:04 + Example of the default format: T00:07:04+0000. + Note: the default format complies with ISO-8601. endif # BINDESC_DEFINE_BUILD_TIME From 7495846b625be792c9c28a1d59eaad391f7be15d Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 5 Oct 2023 09:42:31 +0200 Subject: [PATCH 1716/4498] Bluetooth: Controller: Rename ticker reschedule variables Rename ticker reschedule in window variable to improve readability. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ticker/ticker.c | 123 +++++++++++--------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index e5c89dca905..9b5bb53a625 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -2326,43 +2326,46 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, uint32_t ticks_elapsed) { struct ticker_node *nodes; - uint8_t rescheduling = 1U; - uint8_t rescheduled = 0U; + uint8_t rescheduling; + uint8_t rescheduled; nodes = &instance->nodes[0]; /* Do until all pending re-schedules handled */ + rescheduling = 1U; + rescheduled = 0U; while (rescheduling) { - uint32_t ticks_to_expire_offset = 0U; - uint32_t ticks_start_offset = 0U; - uint32_t window_start_ticks = 0U; - uint32_t ticks_slot_window = 0U; - uint32_t ticks_to_expire = 0U; + struct ticker_node *ticker_resched; + uint32_t ticks_to_expire_offset; struct ticker_ext *ext_data; - struct ticker_node *ticker; - uint8_t ticker_id_head; + uint32_t ticks_start_offset; + uint32_t window_start_ticks; + uint32_t ticks_slot_window; + uint8_t ticker_id_resched; + uint32_t ticks_to_expire; uint8_t ticker_id_prev; - uint8_t ticker_id_iter; + uint8_t ticker_id_next; uint32_t ticks_slot; rescheduling = 0U; /* Find first pending re-schedule */ - ticker_id_head = instance->ticker_id_head; - while (ticker_id_head != TICKER_NULL) { - ticker = &nodes[ticker_id_head]; - if (TICKER_RESCHEDULE_PENDING(ticker)) { + ticker_id_resched = instance->ticker_id_head; + while (ticker_id_resched != TICKER_NULL) { + ticker_resched = &nodes[ticker_id_resched]; + if (TICKER_RESCHEDULE_PENDING(ticker_resched)) { /* Pending reschedule found */ break; } - ticker_id_head = ticker->next; + ticker_id_resched = ticker_resched->next; } - if (ticker_id_head == TICKER_NULL) { + if (ticker_id_resched == TICKER_NULL) { /* Done */ break; } /* Check for intersection with already active node */ + window_start_ticks = 0U; if (instance->ticks_slot_previous > ticks_elapsed) { /* Active node intersects - window starts after end of * active slot @@ -2371,7 +2374,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, ticks_elapsed; } - ticker_id_iter = nodes[ticker_id_head].next; + ticker_id_next = ticker_resched->next; /* If drift was applied to this node, this must be * taken into consideration. Reduce the window with @@ -2382,43 +2385,50 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, * ticker would have the best possible window to re-schedule in * and not be restricted to ticks_slot_window - ticks_drift. */ - ext_data = ticker->ext_data; + ext_data = ticker_resched->ext_data; if (ext_data->ticks_drift < ext_data->ticks_slot_window) { ticks_slot_window = ext_data->ticks_slot_window - ext_data->ticks_drift; } else { /* Window has been exhausted - we can't reschedule */ - ticker_id_iter = TICKER_NULL; + ticker_id_next = TICKER_NULL; + + /* Assignment will be unused when TICKER_NULL */ + ticks_slot_window = 0U; } /* Use ticker's reserved time ticks_slot, else for unreserved * tickers use the reschedule margin as ticks_slot. */ - if (ticker->ticks_slot) { - ticks_slot = ticker->ticks_slot; + if (ticker_resched->ticks_slot) { + ticks_slot = ticker_resched->ticks_slot; } else { - LL_ASSERT(TICKER_HAS_SLOT_WINDOW(ticker)); + LL_ASSERT(TICKER_HAS_SLOT_WINDOW(ticker_resched)); ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN; } /* Try to find available slot for re-scheduling */ - while ((ticker_id_iter != TICKER_NULL) && + ticks_to_expire_offset = 0U; + ticks_start_offset = 0U; + ticks_to_expire = 0U; + while ((ticker_id_next != TICKER_NULL) && ((ticks_start_offset + ticks_slot) <= ticks_slot_window)) { - uint32_t window_end_ticks = 0U; - struct ticker_node *node; + struct ticker_node *ticker_next; + uint32_t window_end_ticks; - node = &nodes[ticker_id_iter]; - ticks_to_expire_offset += node->ticks_to_expire; + ticker_next = &nodes[ticker_id_next]; + ticks_to_expire_offset += ticker_next->ticks_to_expire; /* Skip other pending re-schedule nodes and * tickers with no reservation or not periodic */ - if (TICKER_RESCHEDULE_PENDING(node) || - !node->ticks_slot || - !node->ticks_periodic) { - ticker_id_iter = node->next; + if (TICKER_RESCHEDULE_PENDING(ticker_next) || + !ticker_next->ticks_slot || + !ticker_next->ticks_periodic) { + ticker_id_next = ticker_next->next; + continue; } @@ -2444,7 +2454,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, */ if (window_end_ticks > (ticks_start_offset + ticks_slot)) { - if (!ticker->ticks_slot) { + if (!ticker_resched->ticks_slot) { /* Place at start of window */ ticks_to_expire = window_start_ticks; } else { @@ -2477,10 +2487,10 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, */ ticks_start_offset += ticks_to_expire_offset; window_start_ticks = ticks_start_offset + - node->ticks_slot; + ticker_next->ticks_slot; ticks_to_expire_offset = 0U; - if (!ticker->ticks_slot) { + if (!ticker_resched->ticks_slot) { /* Try at the end of the next node */ ticks_to_expire = window_start_ticks; } else { @@ -2493,56 +2503,61 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, ticks_slot; } - ticker_id_iter = node->next; + ticker_id_next = ticker_next->next; } ext_data->ticks_drift += ticks_to_expire - - ticker->ticks_to_expire; - ticker->ticks_to_expire = ticks_to_expire; - ticker_id_iter = nodes[ticker_id_head].next; - ticker_id_prev = TICKER_NULL; + ticker_resched->ticks_to_expire; + ticker_resched->ticks_to_expire = ticks_to_expire; /* Place the ticker node sorted by expiration time and adjust * delta times */ - while (ticker_id_iter != TICKER_NULL) { - struct ticker_node *node; + ticker_id_next = ticker_resched->next; + ticker_id_prev = TICKER_NULL; + while (ticker_id_next != TICKER_NULL) { + struct ticker_node *ticker_next; - node = &nodes[ticker_id_iter]; - if (ticker->ticks_to_expire > node->ticks_to_expire) { + ticker_next = &nodes[ticker_id_next]; + if (ticker_resched->ticks_to_expire > + ticker_next->ticks_to_expire) { /* Node is after this - adjust delta */ - ticker->ticks_to_expire -= - node->ticks_to_expire; + ticker_resched->ticks_to_expire -= + ticker_next->ticks_to_expire; } else { /* Node is before this one */ - node->ticks_to_expire -= - ticker->ticks_to_expire; + ticker_next->ticks_to_expire -= + ticker_resched->ticks_to_expire; break; } - ticker_id_prev = ticker_id_iter; - ticker_id_iter = node->next; + ticker_id_prev = ticker_id_next; + ticker_id_next = ticker_next->next; } + /* If the node moved in the list, insert it */ if (ticker_id_prev != TICKER_NULL) { + LL_ASSERT(instance->ticker_id_head == + ticker_id_resched); + /* Node did not become the first - update head and * insert node after 'previous' */ - instance->ticker_id_head = nodes[ticker_id_head].next; + instance->ticker_id_head = ticker_resched->next; /* Link inserted node */ - nodes[ticker_id_head].next = nodes[ticker_id_prev].next; - nodes[ticker_id_prev].next = ticker_id_head; + ticker_resched->next = nodes[ticker_id_prev].next; + nodes[ticker_id_prev].next = ticker_id_resched; } /* Remove latency added in ticker_worker */ - ticker->lazy_current--; + ticker_resched->lazy_current--; /* Prevent repeated re-scheduling */ ext_data->reschedule_state = TICKER_RESCHEDULE_STATE_DONE; #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) - ticker_mark_expire_info_outdated(instance, ticker_id_head); + ticker_mark_expire_info_outdated(instance, ticker_id_resched); #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ /* Check for other pending re-schedules and set exit flag */ From e50748b67cd9d7d554d87bf27ceef0307f9d63ac Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 5 Oct 2023 10:35:03 +0200 Subject: [PATCH 1717/4498] Bluetooth: Controller: Fix leak in scheduled ticker node Fix leak in scheduled ticker node when rescheduling ticker nodes. Applications having active Extended Advertising or Observer role with the use of ticker reschedule in window feature would experience assertion check failure due to delayed radio event preparation or stalled controller with no active roles. Fix updating of the ticker linked list when handling rescheduled tickers. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ticker/ticker.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index 9b5bb53a625..83bd6437d59 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -2337,6 +2337,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, while (rescheduling) { struct ticker_node *ticker_resched; uint32_t ticks_to_expire_offset; + uint8_t ticker_id_resched_prev; struct ticker_ext *ext_data; uint32_t ticks_start_offset; uint32_t window_start_ticks; @@ -2350,6 +2351,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, rescheduling = 0U; /* Find first pending re-schedule */ + ticker_id_resched_prev = TICKER_NULL; ticker_id_resched = instance->ticker_id_head; while (ticker_id_resched != TICKER_NULL) { ticker_resched = &nodes[ticker_id_resched]; @@ -2357,6 +2359,8 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, /* Pending reschedule found */ break; } + + ticker_id_resched_prev = ticker_id_resched; ticker_id_resched = ticker_resched->next; } if (ticker_id_resched == TICKER_NULL) { @@ -2536,13 +2540,15 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, /* If the node moved in the list, insert it */ if (ticker_id_prev != TICKER_NULL) { - LL_ASSERT(instance->ticker_id_head == - ticker_id_resched); - - /* Node did not become the first - update head and - * insert node after 'previous' - */ - instance->ticker_id_head = ticker_resched->next; + /* Remove node from its current position in list */ + if (ticker_id_resched_prev != TICKER_NULL) { + /* Node was not at the head of the list */ + nodes[ticker_id_resched_prev].next = + ticker_resched->next; + } else { + /* Node was at the head, move head forward */ + instance->ticker_id_head = ticker_resched->next; + } /* Link inserted node */ ticker_resched->next = nodes[ticker_id_prev].next; From b1da312e9d69f4879acd33580e3d0356166dabb5 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Fri, 6 Oct 2023 10:49:19 +0200 Subject: [PATCH 1718/4498] Bluetooth: ATT: discard RX on a disconnected connection A race condition between ATT RX and the connection teardown can happen, as the teardown is executed from a workqueue. For example: - connection is established - `connected` cb is called (in BT RX context) - user calls `bt_conn_disconnect` in that cb - connection is marked as disconnecting - ATT teardown & general conn cleanup is scheduled - BT RX gets an ATT request, tries to handle it - ATT bearer is still not GC'd, so it tries and fails to send it -> results in error message "not connected" on log - ATT teardown & general conn cleanup runs To avoid that, we not only check the bearer state, but also its ACL conn state. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/att.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 640c3acef90..18d22f5e98f 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -2867,9 +2867,15 @@ static att_type_t att_op_get_type(uint8_t op) return ATT_UNKNOWN; } +static struct bt_conn *get_conn(struct bt_att_chan *att_chan) +{ + return att_chan->chan.chan.conn; +} + static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) { struct bt_att_chan *att_chan = ATT_CHAN(chan); + struct bt_conn *conn = get_conn(att_chan); struct bt_att_hdr *hdr; const struct att_handler *handler; uint8_t err; @@ -2884,6 +2890,11 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) LOG_DBG("Received ATT chan %p code 0x%02x len %zu", att_chan, hdr->code, net_buf_frags_len(buf)); + if (conn->state != BT_CONN_CONNECTED) { + LOG_DBG("not connected: conn %p state %u", conn, conn->state); + return 0; + } + if (!att_chan->att) { LOG_DBG("Ignore recv on detached ATT chan"); return 0; From 7bc822df041b4a7ca316640f3f9b589a08e692c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Fri, 6 Oct 2023 09:23:39 +0200 Subject: [PATCH 1719/4498] boards: esp32: Fix documentation spelling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a simple documentation spelling typo on SoC name. Signed-off-by: Gaël PORTAY --- boards/riscv/esp32c3_devkitm/doc/index.rst | 2 +- boards/riscv/esp32c3_luatos_core/doc/index.rst | 2 +- boards/riscv/icev_wireless/doc/index.rst | 2 +- boards/riscv/stamp_c3/doc/index.rst | 2 +- boards/riscv/xiao_esp32c3/doc/index.rst | 2 +- boards/xtensa/esp32_devkitc_wrover/doc/index.rst | 2 +- boards/xtensa/esp32_ethernet_kit/doc/index.rst | 2 +- boards/xtensa/esp32s2_franzininho/doc/index.rst | 2 +- boards/xtensa/esp32s2_saola/doc/index.rst | 2 +- boards/xtensa/esp32s3_devkitm/doc/index.rst | 2 +- boards/xtensa/esp32s3_luatos_core/doc/index.rst | 2 +- boards/xtensa/esp_wrover_kit/doc/index.rst | 2 +- boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst | 2 +- boards/xtensa/m5stickc_plus/doc/index.rst | 2 +- boards/xtensa/odroid_go/doc/index.rst | 2 +- boards/xtensa/olimex_esp32_evb/doc/index.rst | 2 +- boards/xtensa/xiao_esp32s3/doc/index.rst | 2 +- boards/xtensa/yd_esp32/doc/index.rst | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/boards/riscv/esp32c3_devkitm/doc/index.rst b/boards/riscv/esp32c3_devkitm/doc/index.rst index 95b14e8a39b..6d21b2918c3 100644 --- a/boards/riscv/esp32c3_devkitm/doc/index.rst +++ b/boards/riscv/esp32c3_devkitm/doc/index.rst @@ -122,7 +122,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/riscv/esp32c3_luatos_core/doc/index.rst b/boards/riscv/esp32c3_luatos_core/doc/index.rst index 75f1f3c5e6a..c943931a9e6 100644 --- a/boards/riscv/esp32c3_luatos_core/doc/index.rst +++ b/boards/riscv/esp32c3_luatos_core/doc/index.rst @@ -140,7 +140,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/riscv/icev_wireless/doc/index.rst b/boards/riscv/icev_wireless/doc/index.rst index f6358fbfbcc..a3ae804c668 100644 --- a/boards/riscv/icev_wireless/doc/index.rst +++ b/boards/riscv/icev_wireless/doc/index.rst @@ -128,7 +128,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/riscv/stamp_c3/doc/index.rst b/boards/riscv/stamp_c3/doc/index.rst index d47ac110fba..8da74e9e1d8 100644 --- a/boards/riscv/stamp_c3/doc/index.rst +++ b/boards/riscv/stamp_c3/doc/index.rst @@ -86,7 +86,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/riscv/xiao_esp32c3/doc/index.rst b/boards/riscv/xiao_esp32c3/doc/index.rst index 4afc3cad4bc..18c56c3ff9b 100644 --- a/boards/riscv/xiao_esp32c3/doc/index.rst +++ b/boards/riscv/xiao_esp32c3/doc/index.rst @@ -110,7 +110,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32_devkitc_wrover/doc/index.rst b/boards/xtensa/esp32_devkitc_wrover/doc/index.rst index e749ac40826..e7615f13335 100644 --- a/boards/xtensa/esp32_devkitc_wrover/doc/index.rst +++ b/boards/xtensa/esp32_devkitc_wrover/doc/index.rst @@ -141,7 +141,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32_ethernet_kit/doc/index.rst b/boards/xtensa/esp32_ethernet_kit/doc/index.rst index 18638959af3..5227cd3646e 100644 --- a/boards/xtensa/esp32_ethernet_kit/doc/index.rst +++ b/boards/xtensa/esp32_ethernet_kit/doc/index.rst @@ -468,7 +468,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32s2_franzininho/doc/index.rst b/boards/xtensa/esp32s2_franzininho/doc/index.rst index 63407133c3d..684fbf5dd5c 100644 --- a/boards/xtensa/esp32s2_franzininho/doc/index.rst +++ b/boards/xtensa/esp32s2_franzininho/doc/index.rst @@ -84,7 +84,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32s2_saola/doc/index.rst b/boards/xtensa/esp32s2_saola/doc/index.rst index ee5b5c922d3..f52594c6649 100644 --- a/boards/xtensa/esp32s2_saola/doc/index.rst +++ b/boards/xtensa/esp32s2_saola/doc/index.rst @@ -118,7 +118,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32s3_devkitm/doc/index.rst b/boards/xtensa/esp32s3_devkitm/doc/index.rst index caa9f6a240f..851246a75d4 100644 --- a/boards/xtensa/esp32s3_devkitm/doc/index.rst +++ b/boards/xtensa/esp32s3_devkitm/doc/index.rst @@ -167,7 +167,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp32s3_luatos_core/doc/index.rst b/boards/xtensa/esp32s3_luatos_core/doc/index.rst index c4883db35d8..9160a20fcf4 100644 --- a/boards/xtensa/esp32s3_luatos_core/doc/index.rst +++ b/boards/xtensa/esp32s3_luatos_core/doc/index.rst @@ -166,7 +166,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/esp_wrover_kit/doc/index.rst b/boards/xtensa/esp_wrover_kit/doc/index.rst index 0e0a9921a0d..0154f2c9ad9 100644 --- a/boards/xtensa/esp_wrover_kit/doc/index.rst +++ b/boards/xtensa/esp_wrover_kit/doc/index.rst @@ -533,7 +533,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst b/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst index 69ad019e52e..1029b21dd60 100644 --- a/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst +++ b/boards/xtensa/heltec_wifi_lora32_v2/doc/index.rst @@ -72,7 +72,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/m5stickc_plus/doc/index.rst b/boards/xtensa/m5stickc_plus/doc/index.rst index f015fe3feee..1b042f4f30f 100644 --- a/boards/xtensa/m5stickc_plus/doc/index.rst +++ b/boards/xtensa/m5stickc_plus/doc/index.rst @@ -117,7 +117,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/odroid_go/doc/index.rst b/boards/xtensa/odroid_go/doc/index.rst index d53840882ce..933c167f535 100644 --- a/boards/xtensa/odroid_go/doc/index.rst +++ b/boards/xtensa/odroid_go/doc/index.rst @@ -128,7 +128,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/olimex_esp32_evb/doc/index.rst b/boards/xtensa/olimex_esp32_evb/doc/index.rst index 9f171498427..3bc02a82295 100644 --- a/boards/xtensa/olimex_esp32_evb/doc/index.rst +++ b/boards/xtensa/olimex_esp32_evb/doc/index.rst @@ -138,7 +138,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/xiao_esp32s3/doc/index.rst b/boards/xtensa/xiao_esp32s3/doc/index.rst index b0a200f49c2..62a5eb69eba 100644 --- a/boards/xtensa/xiao_esp32s3/doc/index.rst +++ b/boards/xtensa/xiao_esp32s3/doc/index.rst @@ -126,7 +126,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: diff --git a/boards/xtensa/yd_esp32/doc/index.rst b/boards/xtensa/yd_esp32/doc/index.rst index 9ffd9f89c66..c49bdc0cb60 100644 --- a/boards/xtensa/yd_esp32/doc/index.rst +++ b/boards/xtensa/yd_esp32/doc/index.rst @@ -147,7 +147,7 @@ Sysbuild ======== The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. +bootstrap the board with the ESP32 SoC. To build the sample application using sysbuild use the command: From 4667a0c07eb0531762368d80523884ffa112f92a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 22:02:26 +0000 Subject: [PATCH 1720/4498] doc: vuln: Add information about CVE-2023-4260 Information about CVE-2023-4260 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 41d3f0235e1..5295c596430 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1363,6 +1363,19 @@ This has been fixed in main for v3.5.0 - `PR 60079 fix for 3.3 `_ +CVE-2023-4260 +------------- + +Off-by-one buffer overflow vulnerability in the Zephyr FS subsystem + +- `Zephyr project bug tracker GHSA-gj27-862r-55wh + `_ + +This has been fixed in main for v3.5.0 + +- `PR 63079 fix for main + `_ + CVE-2023-4262 ------------- From 9a1c5e2603901b8bb7269306089b12c03d6072d7 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 22:04:53 +0000 Subject: [PATCH 1721/4498] doc: release: 3.5 Add info about CVE-2023-4260 Add CVE-2023-4260 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 63be9550fa0..c80538af120 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -25,6 +25,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ +* CVE-2023-4260 `Zephyr project bug tracker GHSA-gj27-862r-55wh + `_ + * CVE-2023-4264 `Zephyr project bug tracker GHSA-rgx6-3w4j-gf5j `_ From af953a1d0742186cf34491fa2705cc2572aebe2d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 4 Oct 2023 23:31:28 +0200 Subject: [PATCH 1722/4498] Bluetooth: BAP: Fix bug in BASE bis index The indexes were reset to 0 for each subgroup, which meant that if we had a broadcast source with 2 subgroups and 1 BIS in each, both of them would use index 0x01. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_source.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index bc5c2b8908d..b0af0cdf18d 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -306,7 +306,6 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup, struct bt_bap_stream *stream; const struct bt_audio_codec_cfg *codec_cfg; uint8_t stream_count; - uint8_t bis_index; uint8_t len; stream_count = 0; @@ -350,9 +349,10 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup, #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ /* Create BIS index bitfield */ - bis_index = 0; for (uint8_t i = 0U; i < stream_count; i++) { - bis_index++; + /* Set the bis_index to *streams_encoded plus 1 as the indexes start from 1 */ + const uint8_t bis_index = *streams_encoded + 1; + if ((buf->size - buf->len) < (sizeof(bis_index) + sizeof(uint8_t))) { LOG_DBG("No room for BIS[%d] index", i); @@ -378,7 +378,7 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup, net_buf_simple_add_mem(buf, stream_data[i].data, stream_data[i].data_len); #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ - streams_encoded++; + (*streams_encoded)++; } return true; From 13d74677bac1d2ecf3be356e0ed6ce626e199921 Mon Sep 17 00:00:00 2001 From: Steve Jacot-Guillarmod Date: Fri, 28 Jul 2023 09:40:08 +0200 Subject: [PATCH 1723/4498] drivers: led: pca9633: disable allcall The PCA9633 i2c LED controller offers an All Call address in its nominal operation, allowing simultaneous communication with all instances present on the same i2c bus. The default address is 0x70. While this functionality is convenient, it is possible that the board uses another i2c component that also uses this address (for example, the shtcx). In such cases, the address conflict prevents the proper functioning of the system. The idea is to add a "disable-allcall" property to the device tree. If this option is present, the initialization of the PCA9633 forces the bit 0 (ALLCALL) to be set to false, thereby disabling this function. It is necessary to add this property to all PCA9633 devices on the bus to free up the address 0x70. Signed-off-by: Steve Jacot-Guillarmod --- drivers/led/pca9633.c | 20 ++++++++++++++------ dts/bindings/led/nxp,pca9633.yaml | 5 +++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/led/pca9633.c b/drivers/led/pca9633.c index 96a04dc484c..a7f95d61872 100644 --- a/drivers/led/pca9633.c +++ b/drivers/led/pca9633.c @@ -37,6 +37,7 @@ LOG_MODULE_REGISTER(pca9633); #define PCA9633_LEDOUT 0x08 /* PCA9633 mode register 1 */ +#define PCA9633_MODE1_ALLCAL 0x01 /* All Call Address enabled */ #define PCA9633_MODE1_SLEEP 0x10 /* Sleep Mode */ /* PCA9633 mode register 2 */ #define PCA9633_MODE2_DMBLNK 0x20 /* Enable blinking */ @@ -45,6 +46,7 @@ LOG_MODULE_REGISTER(pca9633); struct pca9633_config { struct i2c_dt_spec i2c; + bool disable_allcall; }; struct pca9633_data { @@ -192,11 +194,16 @@ static int pca9633_led_init(const struct device *dev) return -ENODEV; } - /* Take the LED driver out from Sleep mode. */ - if (i2c_reg_update_byte_dt(&config->i2c, - PCA9633_MODE1, - PCA9633_MODE1_SLEEP, - ~PCA9633_MODE1_SLEEP)) { + /* + * Take the LED driver out from Sleep mode and disable All Call Address + * if specified in DT. + */ + if (i2c_reg_update_byte_dt( + &config->i2c, PCA9633_MODE1, + config->disable_allcall ? PCA9633_MODE1_SLEEP | PCA9633_MODE1_ALLCAL + : PCA9633_MODE1_SLEEP, + config->disable_allcall ? ~(PCA9633_MODE1_SLEEP | PCA9633_MODE1_ALLCAL) + : ~PCA9633_MODE1_SLEEP)) { LOG_ERR("LED reg update failed"); return -EIO; } @@ -218,7 +225,8 @@ static const struct led_driver_api pca9633_led_api = { #define PCA9633_DEVICE(id) \ static const struct pca9633_config pca9633_##id##_cfg = { \ - .i2c = I2C_DT_SPEC_INST_GET(id) \ + .i2c = I2C_DT_SPEC_INST_GET(id), \ + .disable_allcall = DT_INST_PROP(id, disable_allcall), \ }; \ static struct pca9633_data pca9633_##id##_data; \ \ diff --git a/dts/bindings/led/nxp,pca9633.yaml b/dts/bindings/led/nxp,pca9633.yaml index ec82d694573..a7e13b45fc2 100644 --- a/dts/bindings/led/nxp,pca9633.yaml +++ b/dts/bindings/led/nxp,pca9633.yaml @@ -3,3 +3,8 @@ description: NXP PCA9633 LED compatible: "nxp,pca9633" include: i2c-device.yaml + +properties: + disable-allcall: + type: boolean + description: Disable response to LED All Call address request From 42ea06cf211da23bef6dc3adbe343b9ed8865c0b Mon Sep 17 00:00:00 2001 From: Detlev Zundel Date: Thu, 14 Sep 2023 17:13:51 +0200 Subject: [PATCH 1724/4498] soc: xtensa,riscv: esp32c3: Fix SOC_PART_NUMBER choices Add the ESP32-C3-WROOM-02 modules with 4 or 8 MiB flash. The temperature and antenna / connector variants are not mentioned explicitely as they do not influence the software. Signed-off-by: Detlev Zundel --- soc/riscv/espressif_esp32/esp32c3/Kconfig.soc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soc/riscv/espressif_esp32/esp32c3/Kconfig.soc b/soc/riscv/espressif_esp32/esp32c3/Kconfig.soc index dce91fcc86a..66a6e918f31 100644 --- a/soc/riscv/espressif_esp32/esp32c3/Kconfig.soc +++ b/soc/riscv/espressif_esp32/esp32c3/Kconfig.soc @@ -17,10 +17,10 @@ choice SOC_PART_NUMBER bool "ESP32C3_FX4" config SOC_ESP32C3_MINI_N4 bool "ESP32C3_MINI_N4" - config SOC_ESP32C3_WROOM_H2 - bool "ESP32C3_MINI_N4" - config SOC_ESP32C3_WROOM_H4 - bool "ESP32C3_MINI_N4" + config SOC_ESP32C3_WROOM_02_N4 + bool "ESP32C3_WROOM_02_N4" + config SOC_ESP32C3_WROOM_02_N8 + bool "ESP32C3_WROOM_02_N8" endchoice # SOC_PART_NUMBER From de66defa44c0aae08df4efd012706a4b863d28a5 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Tue, 3 Oct 2023 20:43:19 +0300 Subject: [PATCH 1725/4498] west.yml: Update hal_silabs to pull request #45 Update hal_silabs to pull request #45, fixing a file that was copied from a wrong version. Signed-off-by: Yonatan Schachter --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 33f1dd3e9ba..09ac8f93616 100644 --- a/west.yml +++ b/west.yml @@ -222,7 +222,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 6a4521e5934d2e787f782b9e5370f3206e6cc9d2 + revision: d191d981c4eb20c0c7445a4061fcdbcfa686113a path: modules/hal/silabs groups: - hal From dbb4e8aa9d37c69c90b0c75713301dd7b0d92e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 6 Oct 2023 11:53:39 +0200 Subject: [PATCH 1726/4498] drivers: usb_dc_nrfx: Isochronous endpoint cannot be bulk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent use of isochronous endpoints as bulk and/or interrupt endpoint. The issue was observed when trying to use 4 CDC ACM instances where the 4th instance would claim the isochronous IN endpoint 0x88 to be bulk. Because the isochronous endpoints cannot respond with handshake packet the iso endpoints cannot be used as bulk or interrupt substitue. Properly fail endpoint check and therefore make 4 CDC ACM instances not enumerate at all because the hardware has endpoints that only allows up to 3 CDC ACM instances. Signed-off-by: Tomasz Moń --- drivers/usb/device/usb_dc_nrfx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/device/usb_dc_nrfx.c b/drivers/usb/device/usb_dc_nrfx.c index 76c27647509..a8032baf1f1 100644 --- a/drivers/usb/device/usb_dc_nrfx.c +++ b/drivers/usb/device/usb_dc_nrfx.c @@ -1397,6 +1397,12 @@ int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data *const ep_cfg) return -1; } + if ((ep_cfg->ep_type != USB_DC_EP_ISOCHRONOUS) && + (NRF_USBD_EPISO_CHECK(ep_cfg->ep_addr))) { + LOG_WRN("iso endpoint can only be iso"); + return -1; + } + return 0; } From a601b43ef891d0e11feeaa09cb93c82671f16d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 4 Oct 2023 12:13:39 +0200 Subject: [PATCH 1727/4498] security: doc: add missing headings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add headings for 2022 and 2023 CVEs to make document navigation easier. Signed-off-by: Benjamin Cabé --- doc/security/vulnerabilities.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 5295c596430..6b6bb3c07b9 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1157,6 +1157,9 @@ This has been fixed in main for v3.0.0 - `PR 42167 fix for v2.7.0 `_ +CVE-2022 +======== + CVE-2022-0553 ------------- @@ -1264,6 +1267,9 @@ DoS: Invalid Initialization in le_read_buffer_size_complete() - `Zephyr project bug tracker GHSA-w525-fm68-ppq3 `_ +CVE-2023 +======== + CVE-2023-0396 ------------- From d00d44c92537938fe72e4cc19a05f8e752fb6097 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Thu, 8 Jun 2023 11:58:00 +0200 Subject: [PATCH 1728/4498] Bluetooth: controller: fix failing EBQ advertising tests Updates the chaining for advertising. Instead of unconditionally adding a new PDU when new data is added we now instead fill the last PDU in the chain with the incoming data, only adding a new PDU when there is not enough room. This reduces the nr. of PDUs used for advertising, and also fixes some qualification failures Signed-off-by: Andries Kruithof --- .../src/broadcaster_multiple.c | 1 - .../bluetooth/controller/ll_sw/ull_adv_aux.c | 154 ++++++++++++------ tests/bsim/bluetooth/host/adv/chain/prj.conf | 5 +- 3 files changed, 111 insertions(+), 49 deletions(-) diff --git a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c index 56cc210de78..d1c6d792e95 100644 --- a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c +++ b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c @@ -75,7 +75,6 @@ int broadcaster_multiple(void) printk("Bluetooth init failed (err %d)\n", err); return err; } - for (int index = 0; index < CONFIG_BT_EXT_ADV_MAX_ADV_SET; index++) { /* Use advertising set instance index as SID */ adv_param.sid = index; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 302dc6da785..0754a047207 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -117,6 +117,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t ad_len_overflow; uint8_t ad_len_chain; struct pdu_adv *pdu; + uint8_t ad_len = 0U; #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */ /* Get the advertising set instance */ @@ -301,7 +302,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, struct pdu_adv *pdu_chain_prev; struct pdu_adv *pdu_chain; uint16_t ad_len_total; - uint8_t ad_len_prev; + uint8_t ad_len_prev = 0U; /* Traverse to next set clear hdr data parameter */ val_ptr += sizeof(data); @@ -317,28 +318,22 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ad_len_total = 0U; pdu_chain_prev = pdu_prev; pdu_chain = pdu; + /* make a copy of the previous chain, until we reach the end */ do { - /* Prepare for aux ptr field reference to be returned, hence - * second parameter will be for AD data field. - */ - *val_ptr = 0U; - (void)memset((void *)&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET], - 0U, ULL_ADV_HDR_DATA_DATA_PTR_SIZE); + val_ptr = hdr_data; + *val_ptr++ = 0U; + (void)memset((void *)val_ptr, 0U, + ULL_ADV_HDR_DATA_DATA_PTR_SIZE); pdu_prev = pdu_chain_prev; pdu = pdu_chain; - /* Add Aux Ptr field if not already present */ err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, - (ULL_ADV_PDU_HDR_FIELD_AD_DATA | - ULL_ADV_PDU_HDR_FIELD_AUX_PTR), - 0, hdr_data); - LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG)); + ULL_ADV_PDU_HDR_FIELD_AD_DATA, + 0U, hdr_data); + ad_len_prev = hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET]; - /* Get PDUs previous AD data length */ - ad_len_prev = - hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + - ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE]; + LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG)); /* Check of max supported AD data len */ ad_len_total += ad_len_prev; @@ -365,31 +360,10 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, (!pdu_chain_prev && !pdu_chain)); } while (pdu_chain_prev); - if (err == BT_HCI_ERR_PACKET_TOO_LONG) { - ad_len_overflow = - hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + - ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + - ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - - /* Prepare for aux ptr field reference to be returned, - * hence second parameter will be for AD data field. - * Fill it with reduced AD data length. - */ - *val_ptr = ad_len_prev - ad_len_overflow; - - /* AD data len in chain PDU */ - ad_len_chain = len; - - /* Proceed to add chain PDU */ - err = 0U; - } else { - /* No AD data overflow */ - ad_len_overflow = 0U; - - /* No AD data in chain PDU */ - ad_len_chain = 0U; - } + /* No AD data overflow */ + ad_len_overflow = 0U; + /* No AD data in chain PDU */ + ad_len_chain = 0U; } #else /* !CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */ } else { @@ -411,8 +385,88 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) if ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) || - (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG) || - ad_len_overflow) { + (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) { + /* in the previous step we duplicated the chain + * the next step is to append new data in the last existing pdu in the chain, + */ + + uint8_t chain_err = 0U; + + val_ptr = hdr_data; + *val_ptr++ = len; + (void)memcpy(val_ptr, &data, sizeof(data)); + + /* Append data to the last PDU */ + chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, + ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND, + 0U, hdr_data); + + LL_ASSERT((!chain_err) || (chain_err == BT_HCI_ERR_PACKET_TOO_LONG)); + + /* FIXME: the code has become quite complex, an alternative and simpler + * implementation would be to first fill an array with all data that + * must be send, and create the chained PDUs from this array + */ + if (chain_err == BT_HCI_ERR_PACKET_TOO_LONG) { + /* We could not fit all the data, append as much as possible + * ad_len_overflow is how much overflows with the AUX ptr + */ + uint8_t ad_len_overflow_first_try; + const uint16_t chain_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND | + ULL_ADV_PDU_HDR_FIELD_AUX_PTR; + + ad_len_overflow_first_try = hdr_data[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + + val_ptr = hdr_data; + *val_ptr++ = len; + (void)memcpy(val_ptr, &data, sizeof(data)); + val_ptr += sizeof(data); + *val_ptr++ = len; + (void)memcpy(val_ptr, &data, sizeof(data)); + chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, + chain_add_fields, + 0U, hdr_data); + ad_len_overflow = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + + ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + + ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + + /* ad_len_overflow - ad_len_overflow_first_try is the size of + * the aux pointer + * ad_len_prev is how much data is already present, ad_len is how + * much data we can add to this PDU + */ + ad_len = PDU_AC_PAYLOAD_SIZE_MAX - ad_len_prev - + (ad_len_overflow - ad_len_overflow_first_try) - 4; + + val_ptr = hdr_data; + *val_ptr++ = ad_len; + (void)memcpy(val_ptr, &data, sizeof(data)); + val_ptr += sizeof(data); + *val_ptr++ = ad_len; + (void)memcpy(val_ptr, &data, sizeof(data)); + + /* we now know how much data we can add to the + * last PDU without getting an overflow + */ + chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, + chain_add_fields, + 0U, hdr_data); + LL_ASSERT(chain_err == 0U); + /* + * in the next PDU we still need to add ad_len_chain bytes of data + * but we do not have overflow, since we already added + * the exact amount that would fit + */ + ad_len_chain = len - ad_len; + ad_len_overflow = 0U; + } else { + ad_len_overflow = 0U; + } + } + + if (ad_len_chain || ad_len_overflow) { struct pdu_adv_com_ext_adv *com_hdr_chain; struct pdu_adv_com_ext_adv *com_hdr; struct pdu_adv_ext_hdr *hdr_chain; @@ -425,6 +479,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint16_t sec_len; uint8_t *dptr; + len = ad_len_chain; /* Get reference to flags in superior PDU */ com_hdr = &pdu->adv_ext_ind; if (com_hdr->ext_hdr_len) { @@ -450,6 +505,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0]; dptr_chain = (void *)hdr_chain; + LL_ASSERT(dptr_chain); /* Flags */ *dptr_chain = 0U; @@ -498,6 +554,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, if (ad_len_overflow) { uint8_t *ad_overflow; + val_ptr = hdr_data; /* Copy overflowed AD data from previous PDU into this * new chain PDU */ @@ -505,6 +562,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, &val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET], sizeof(ad_overflow)); ad_overflow += *val_ptr; + (void)memcpy(dptr_chain, ad_overflow, ad_len_overflow); dptr_chain += ad_len_overflow; @@ -529,8 +587,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, return err; } - /* AD data len in chain PDU besides the overflow */ - len = ad_len_chain; } /* Check AdvData overflow */ @@ -555,7 +611,13 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, pdu_chain->len = sec_len + ad_len_overflow + len; /* Fill AD Data in chain PDU */ - (void)memcpy(dptr_chain, data, len); + if (ad_len_overflow != 0U) { + (void)memcpy(dptr_chain, data, ad_len_overflow); + } + + if (ad_len_chain != 0U) { + (void)memcpy(dptr_chain, &data[ad_len + ad_len_overflow], ad_len_chain); + } /* Get reference to aux ptr in superior PDU */ (void)memcpy(&aux_ptr, diff --git a/tests/bsim/bluetooth/host/adv/chain/prj.conf b/tests/bsim/bluetooth/host/adv/chain/prj.conf index 3e7f11009c2..85861dccd66 100644 --- a/tests/bsim/bluetooth/host/adv/chain/prj.conf +++ b/tests/bsim/bluetooth/host/adv/chain/prj.conf @@ -30,8 +30,9 @@ CONFIG_BT_EXT_SCAN_BUF_SIZE=1650 # Set maximum scan data length for Extended Scanning in Bluetooth LE Controller CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 -# Zephyr Bluetooth LE Controller needs 16 event buffers to generate Extended -# Advertising Report for receiving the complete 1650 bytes of data +# Zephyr Controller does not combine all the 1650 bytes before fragmenting them +# into 8 HCI reports, if a PDU has 255 bytes, it will generate 2 HCI reports +# and so we need to reserve 16 buffers CONFIG_BT_BUF_EVT_RX_COUNT=16 # Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain From e8716bf793c45b5cc562161cdde8669e96643178 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Mon, 2 Oct 2023 12:15:47 +0200 Subject: [PATCH 1729/4498] Bluetooth: controller: change calc for data in PDU The existing formula for the amount of data that can be filled in in the current PDU is correct but confusing. Replace it with a simpler formula. Signed-off-by: Andries Kruithof --- .../bluetooth/controller/ll_sw/ull_adv_aux.c | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 0754a047207..2480c286e4b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -411,13 +411,9 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, /* We could not fit all the data, append as much as possible * ad_len_overflow is how much overflows with the AUX ptr */ - uint8_t ad_len_overflow_first_try; const uint16_t chain_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND | ULL_ADV_PDU_HDR_FIELD_AUX_PTR; - ad_len_overflow_first_try = hdr_data[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - val_ptr = hdr_data; *val_ptr++ = len; (void)memcpy(val_ptr, &data, sizeof(data)); @@ -427,18 +423,18 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, chain_add_fields, 0U, hdr_data); - ad_len_overflow = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + - ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + - ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - - /* ad_len_overflow - ad_len_overflow_first_try is the size of - * the aux pointer - * ad_len_prev is how much data is already present, ad_len is how - * much data we can add to this PDU + ad_len_chain = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + + ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + + ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + + /* len is the total amount of datawe want to add + * ad_len_chain is the amount of data that does + * not fit in the current PDU + * the difference of the two is the amount that + * we can fit in the current PDU */ - ad_len = PDU_AC_PAYLOAD_SIZE_MAX - ad_len_prev - - (ad_len_overflow - ad_len_overflow_first_try) - 4; + ad_len = len - ad_len_chain; val_ptr = hdr_data; *val_ptr++ = ad_len; @@ -457,9 +453,10 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, /* * in the next PDU we still need to add ad_len_chain bytes of data * but we do not have overflow, since we already added - * the exact amount that would fit + * the exact amount that would fit. We explicitly set overflow to 0. + * FIXME: ad_len_overflow already should be 0, to be verified. We wait + * fixing this until rewriting this whole function */ - ad_len_chain = len - ad_len; ad_len_overflow = 0U; } else { ad_len_overflow = 0U; From e04c963d9c2daf1c38e4498a19362cbed9375eea Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Tue, 18 Jul 2023 11:13:31 +0200 Subject: [PATCH 1730/4498] Test: Bluetooth: controller: add CI testing for advertising chaining Update babblesim tests for testing chaining for advertising to ensure that we spill over to the next PDU Signed-off-by: Andries Kruithof --- .../broadcaster_multiple/src/broadcaster_multiple.c | 10 +++++++++- tests/bsim/bluetooth/host/adv/chain/prj.conf | 6 +++--- tests/bsim/bluetooth/host/adv/chain/src/main.c | 10 +++++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c index d1c6d792e95..30fe35d3dec 100644 --- a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c +++ b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c @@ -47,11 +47,18 @@ BT_AD_DATA_FORMAT_LEN_SIZE - \ BT_AD_DATA_FORMAT_TYPE_SIZE - \ BT_DEVICE_NAME_AD_DATA_LEN))) - +/* + * Datalength is an integer, so BT_MFG_DATA_LEN can not be larger than 255. + * To ensure that we need to chain PDUs we therefore add manufacturer data + * twice when chaining is enabled + */ static uint8_t mfg_data[BT_MFG_DATA_LEN] = { 0xFF, 0xFF, }; static const struct bt_data ad[] = { BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), +#if defined(CONFIG_BT_CTLR_ADV_DATA_CHAIN) + BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), +#endif }; static struct bt_le_ext_adv *adv[CONFIG_BT_EXT_ADV_MAX_ADV_SET]; @@ -75,6 +82,7 @@ int broadcaster_multiple(void) printk("Bluetooth init failed (err %d)\n", err); return err; } + for (int index = 0; index < CONFIG_BT_EXT_ADV_MAX_ADV_SET; index++) { /* Use advertising set instance index as SID */ adv_param.sid = index; diff --git a/tests/bsim/bluetooth/host/adv/chain/prj.conf b/tests/bsim/bluetooth/host/adv/chain/prj.conf index 85861dccd66..82eb16e5db0 100644 --- a/tests/bsim/bluetooth/host/adv/chain/prj.conf +++ b/tests/bsim/bluetooth/host/adv/chain/prj.conf @@ -30,9 +30,9 @@ CONFIG_BT_EXT_SCAN_BUF_SIZE=1650 # Set maximum scan data length for Extended Scanning in Bluetooth LE Controller CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 -# Zephyr Controller does not combine all the 1650 bytes before fragmenting them -# into 8 HCI reports, if a PDU has 255 bytes, it will generate 2 HCI reports -# and so we need to reserve 16 buffers +# The Zephyr Controller does not combine all the 1650 bytes before +# fragmenting into 8 HCI reports, if a PDU has 255 bytes, +# it will generate 2 HCI reports and so we need to reserve 16 buffers CONFIG_BT_BUF_EVT_RX_COUNT=16 # Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain diff --git a/tests/bsim/bluetooth/host/adv/chain/src/main.c b/tests/bsim/bluetooth/host/adv/chain/src/main.c index 4475a069535..d58d2a3890f 100644 --- a/tests/bsim/bluetooth/host/adv/chain/src/main.c +++ b/tests/bsim/bluetooth/host/adv/chain/src/main.c @@ -34,8 +34,12 @@ #define NAME_LEN 30 #define BT_AD_DATA_NAME_SIZE (sizeof(CONFIG_BT_DEVICE_NAME) - 1U + 2U) #define BT_AD_DATA_MFG_DATA_SIZE (254U + 2U) +/* + * for testing chaining the manufacturing data is duplicated, hence DATA_LEN needs to + * add twice the size for this element + */ #define DATA_LEN MIN((BT_AD_DATA_NAME_SIZE + \ - BT_AD_DATA_MFG_DATA_SIZE), \ + BT_AD_DATA_MFG_DATA_SIZE + BT_AD_DATA_MFG_DATA_SIZE), \ CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) static K_SEM_DEFINE(sem_recv, 0, 1); @@ -94,6 +98,7 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, data_len = buf->len; if (data_len != DATA_LEN) { + printk("Received datalength: %d\n", data_len); return; } @@ -101,11 +106,13 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, bt_data_parse(buf, data_cb, name); if (strcmp(name, CONFIG_BT_DEVICE_NAME)) { + printk("Wrong name %s\n", name); return; } for (uint8_t i = 0; i < sid_count; i++) { if (sid[i] == info->sid) { + printk("Received SID %d\n", info->sid); return; } } @@ -113,6 +120,7 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, sid[sid_count++] = info->sid; if (sid_count < CONFIG_BT_EXT_ADV_MAX_ADV_SET) { + printk("Received advertising sets: %d\n", sid_count); return; } From a5d15ec01737e9f555c370533f358847877cbb94 Mon Sep 17 00:00:00 2001 From: Ingar Kulbrandstad Date: Mon, 2 Oct 2023 17:41:31 +0200 Subject: [PATCH 1731/4498] Bluetooth: Mesh: Fixed issue with RPR server and client. Fixed issue when reprovisioning is done on a device with both RPR client and server on the same device. Signed-off-by: Ingar Kulbrandstad --- subsys/bluetooth/mesh/provisioner.c | 71 +++ .../bsim/bluetooth/mesh/src/test_provision.c | 464 +++++++++++++----- .../pb_remote_client_server_same_dev.sh | 32 ++ 3 files changed, 444 insertions(+), 123 deletions(-) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 361f373cb7b..717cdbee610 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -857,6 +857,72 @@ int bt_mesh_pb_remote_open(struct bt_mesh_rpr_cli *cli, return link_open(uuid, &pb_remote_cli, net_idx, addr, 0, &ctx, 0); } +/* Remote Provision done where client and server is on same node, skip open link + * and sending of reprovision message, just execute reprovisioning on it self. + */ +static int reprovision_local_client_server(uint16_t addr) +{ + int err; + const uint8_t *pub_key; + const uint8_t *priv_key = NULL; + + if (atomic_test_and_set_bit(bt_mesh_prov_link.flags, LINK_ACTIVE)) { + return -EBUSY; + } + + LOG_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x", + prov_device.node->net_idx, bt_mesh_cdb.iv_index, addr); + + atomic_set_bit(bt_mesh_prov_link.flags, REPROVISION); + atomic_set_bit(bt_mesh_prov_link.flags, PROVISIONER); + bt_mesh_prov_link.addr = addr; + bt_mesh_prov_link.bearer = &pb_remote_cli; + bt_mesh_prov_link.role = &role_provisioner; + prov_device.net_idx = prov_device.node->net_idx; + prov_device.attention_duration = 0; + + if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) && + bt_mesh_prov->public_key_be && bt_mesh_prov->private_key_be) { + LOG_DBG("Use OOB Public and Private key"); + pub_key = bt_mesh_prov->public_key_be; + priv_key = bt_mesh_prov->private_key_be; + } else { + pub_key = bt_mesh_pub_key_get(); + } + + if (!pub_key) { + LOG_ERR("No public key available"); + return -ENOEXEC; + } + + if (bt_mesh_dhkey_gen(pub_key, priv_key, bt_mesh_prov_link.dhkey)) { + LOG_ERR("Failed to generate DHKey"); + return -ENOEXEC; + } + LOG_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, DH_KEY_SIZE)); + + err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey, + bt_mesh_prov_link.prov_salt, prov_device.new_dev_key); + if (err) { + LOG_ERR("Unable to generate device key"); + return err; + } + + bt_mesh_dev_key_cand(prov_device.new_dev_key); + /* Mark the link that was never opened as closed. */ + atomic_set_bit(bt_mesh_prov_link.flags, COMPLETE); + bt_mesh_reprovision(addr); + bt_mesh_dev_key_cand_activate(); + + if (bt_mesh_prov->reprovisioned) { + LOG_DBG("Application reprovisioned callback 0x%04x", bt_mesh_primary_addr()); + bt_mesh_prov->reprovisioned(bt_mesh_primary_addr()); + } + + prov_link_closed(PROV_BEARER_LINK_STATUS_SUCCESS); + return 0; +} + int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, struct bt_mesh_rpr_node *srv, uint16_t addr, bool composition_change) @@ -877,6 +943,11 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, return -ENOENT; } + /* Check if server is on same device as client */ + if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV) && bt_mesh_has_addr(srv->addr)) { + return reprovision_local_client_server(addr); + } + return link_open(NULL, &pb_remote_cli, prov_device.node->net_idx, addr, 0, &ctx, 0); } diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index e1c0da46bdd..54258746524 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -139,6 +139,19 @@ static const struct bt_mesh_comp rpr_srv_comp = { .elem_count = 1, }; +static const struct bt_mesh_comp rpr_cli_srv_comp = { + .elem = + (struct bt_mesh_elem[]){ + BT_MESH_ELEM(1, + MODEL_LIST(BT_MESH_MODEL_CFG_SRV, + BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}), + BT_MESH_MODEL_RPR_CLI(&rpr_cli), + BT_MESH_MODEL_RPR_SRV), + BT_MESH_MODEL_NONE), + }, + .elem_count = 1, +}; + static int mock_pdu_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1072,18 +1085,127 @@ static void test_provisioner_pb_remote_client_provision_timeout(void) PASS(); } +static void reprovision_remote_devkey_client(struct bt_mesh_rpr_node *srv, + struct bt_mesh_cdb_node *node) +{ + uint8_t status; + uint8_t prev_node_dev_key[16]; + + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, false); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check device key by adding appkey. */ + ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, + &status)); + ASSERT_OK(status); + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); +} + +static void reprovision_remote_comp_data_client(struct bt_mesh_rpr_node *srv, + struct bt_mesh_cdb_node *node, + struct net_buf_simple *dev_comp) +{ + NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX); + uint8_t prev_node_dev_key[16]; + uint8_t page; + + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, true); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check that Composition Data Page 128 is now Page 0. */ + net_buf_simple_reset(&new_dev_comp); + ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, + &new_dev_comp)); + + ASSERT_EQUAL(0, page); + ASSERT_EQUAL(dev_comp->len, new_dev_comp.len); + if (memcmp(dev_comp->data, new_dev_comp.data, dev_comp->len)) { + FAIL("Wrong composition data page 0"); + } + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); +} + +static void reprovision_remote_address_client(struct bt_mesh_rpr_node *srv, + struct bt_mesh_cdb_node *node) +{ + uint8_t status; + uint8_t prev_node_dev_key[16]; + + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr + 1, false); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + current_dev_addr++; + srv->addr++; + + /* Check that device doesn't respond to old address with old and new device key. */ + struct bt_mesh_cdb_node *prev_node; + uint8_t tmp[16]; + + prev_node = bt_mesh_cdb_node_alloc((uint8_t[16]) {}, current_dev_addr - 1, 1, 0); + ASSERT_TRUE(node); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, prev_node_dev_key), + "Can't import device key into cdb"); + ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, + test_app_key, &status)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, tmp), + "Can't export device key from cdb"); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, tmp), + "Can't import device key into cdb"); + ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, + test_app_key, &status)); + bt_mesh_cdb_node_del(prev_node, false); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check new device address by adding appkey. */ + ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, + &status)); + ASSERT_OK(status); + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); + +} + /** @brief Verify robustness of NPPI procedures on a RPR Client by running Device Key Refresh, * Node Composition Refresh and Node Address Refresh procedures. */ static void test_provisioner_pb_remote_client_nppi_robustness(void) { NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX); - NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX); uint8_t page; uint16_t pb_remote_server_addr; uint8_t status; struct bt_mesh_cdb_node *node; - uint8_t prev_node_dev_key[16]; provisioner_pb_remote_client_setup(); @@ -1111,96 +1233,23 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void) node = bt_mesh_cdb_node_get(current_dev_addr); ASSERT_TRUE(node); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); LOG_INF("Testing DevKey refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Refreshing device key #%d...\n", i); - bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, false); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check device key by adding appkey. */ - ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, - &status)); - ASSERT_OK(status); - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); + reprovision_remote_devkey_client(&srv, node); } LOG_INF("Testing Composition Data refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Changing Composition Data #%d...\n", i); - bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, true); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check that Composition Data Page 128 is now Page 0. */ - net_buf_simple_reset(&new_dev_comp); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, - &new_dev_comp)); - ASSERT_EQUAL(0, page); - ASSERT_EQUAL(dev_comp.len, new_dev_comp.len); - if (memcmp(dev_comp.data, new_dev_comp.data, dev_comp.len)) { - FAIL("Wrong composition data page 0"); - } - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); + reprovision_remote_comp_data_client(&srv, node, &dev_comp); } LOG_INF("Testing address refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Changing address #%d...\n", i); - bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr + 1, false); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - current_dev_addr++; - srv.addr++; - - /* Check that device doesn't respond to old address with old and new device key. */ - struct bt_mesh_cdb_node *prev_node; - uint8_t tmp[16]; - - prev_node = bt_mesh_cdb_node_alloc((uint8_t[16]) {}, current_dev_addr - 1, 1, 0); - ASSERT_TRUE(node); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, prev_node_dev_key), - "Can't import device key into cdb"); - ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, - test_app_key, &status)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, tmp), - "Can't export device key from cdb"); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, tmp), - "Can't import device key into cdb"); - ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, - test_app_key, &status)); - bt_mesh_cdb_node_del(prev_node, false); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check new device address by adding appkey. */ - ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, - &status)); - ASSERT_OK(status); - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); + reprovision_remote_address_client(&srv, node); } PASS(); @@ -1240,13 +1289,78 @@ static void test_device_pb_remote_server_proved(void) PASS(); } +static void reprovision_remote_devkey_server(const uint16_t initial_addr) +{ + uint8_t prev_dev_key[16]; + uint8_t dev_key[16]; + + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(&prev_dev_key, dev_key, sizeof(dev_key))); +} + +static void reprovision_remote_comp_data_server(const uint16_t initial_addr) +{ + u_int8_t prev_dev_key[16]; + u_int8_t dev_key[16]; + + /* The RPR Server won't let to run Node Composition Refresh procedure without first + * setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a + * "bt/mesh/cmp" entry in settings. The entry is added by the + * `bt_mesh_comp_change_prepare() call. The test suite is not compiled + * with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the + * test is to check RPR Server behavior, but not the actual swap of the Composition + * Data, the flag is toggled directly from the test. + */ + atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + + /* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */ + atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); + + ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); +} + +static void reprovision_remote_address_server(const uint16_t initial_addr) +{ + uint8_t prev_dev_key[16]; + uint8_t dev_key[16]; + + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + ASSERT_EQUAL(initial_addr + 1, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); +} + /** @brief Verify robustness of NPPI procedures on a RPR Server by running Device Key Refresh, * Node Composition Refresh and Node Address Refresh procedures multiple times each. */ static void test_device_pb_remote_server_nppi_robustness(void) { - struct bt_mesh_key prev_dev_key; - k_sem_init(&prov_sem, 0, 1); k_sem_init(&reprov_sem, 0, 1); @@ -1259,65 +1373,25 @@ static void test_device_pb_remote_server_nppi_robustness(void) ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); const uint16_t initial_addr = bt_mesh_primary_addr(); - memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); - LOG_INF("Enabling PB-Remote server"); ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); /* Test Device Key Refresh procedure robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Devkey refresh loop #%d, waiting for being reprov ...\n", i); - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); - memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); + reprovision_remote_devkey_server(initial_addr); } /* Test Node Composition Refresh procedure robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { - /* The RPR Server won't let to run Node Composition Refresh procedure without first - * setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a - * "bt/mesh/cmp" entry in settings. The entry is added by the - * `bt_mesh_comp_change_prepare() call. The test suite is not compiled - * with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the - * test is to check RPR Server behavior, but not the actual swap of the Composition - * Data, the flag is toggled directly from the test. - */ - atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); - LOG_INF("Composition data refresh loop #%d, waiting for being reprov ...\n", i); - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - - /* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */ - atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); - - ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); - memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); + reprovision_remote_comp_data_server(initial_addr); } /* Node Address Refresh robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Address refresh loop #%d, waiting for being reprov ...\n", i); - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - ASSERT_EQUAL(initial_addr + 1 + i, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); - memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); + reprovision_remote_address_server(initial_addr+i); } PASS(); @@ -1354,6 +1428,146 @@ static void test_provisioner_pb_remote_client_ncrp_provision(void) PASS(); } +/** @brief A device running a Remote Provisioning client and server that is used to reprovision + * another device and it self with the client. + */ +static void test_device_pb_remote_client_server_same_dev(void) +{ + NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX); + uint8_t status; + struct bt_mesh_cdb_node *node; + uint8_t page; + uint8_t prev_dev_key[16]; + uint16_t test_vector[] = { 0x0002, 0x0001 }; + + k_sem_init(&prov_sem, 0, 1); + k_sem_init(&reprov_sem, 0, 1); + + bt_mesh_device_setup(&prov, &rpr_cli_srv_comp); + + ASSERT_OK(bt_mesh_cdb_create(test_net_key)); + ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key)); + + LOG_INF("Enabling PB-Remote server"); + ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); + + /* Provision a remote device with RPR Client and Server with local RPR Server. */ + current_dev_addr = 0x0001; + struct bt_mesh_rpr_node srv = { + .addr = current_dev_addr, + .net_idx = 0, + .ttl = 3, + }; + + LOG_INF("Provisioner prov, waiting for prov ...\n"); + ASSERT_OK(provision_remote(&srv, 1, &srv.addr)); + + ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); + + /* Check device key by adding bt_mesh_reprovision_remote appkey. */ + ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, &status)); + ASSERT_OK(status); + + /* Swap callback to catch when device reprovisioned. */ + prov.node_added = prov_node_added_rpr; + + /* Reprovision a device with both RPR Client and Server. */ + for (int i = 0; i < ARRAY_SIZE(test_vector); i++) { + current_dev_addr = test_vector[i]; + srv.addr = current_dev_addr; + bool self_reprov = (bool)(current_dev_addr == bt_mesh_primary_addr()); + + /* Store initial Composition Data Page 0. */ + net_buf_simple_reset(&dev_comp); + ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp)); + + node = bt_mesh_cdb_node_get(current_dev_addr); + ASSERT_TRUE(node); + + LOG_INF("Refreshing 0x%04x device key ...\n", srv.addr); + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + reprovision_remote_devkey_client(&srv, node); + if (self_reprov) { + uint8_t dev_key[16]; + + ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key + * and verify that it has been changed. + */ + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); + } + + LOG_INF("Changing 0x%04x Composition Data ...\n", srv.addr); + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + reprovision_remote_comp_data_client(&srv, node, &dev_comp); + if (self_reprov) { + uint8_t dev_key[16]; + + ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key + * and verify that it has been changed. + */ + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(struct bt_mesh_key))); + } + + LOG_INF("Changing 0x%04x address ...\n", srv.addr); + ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); + reprovision_remote_address_client(&srv, node); + if (self_reprov) { + uint8_t dev_key[16]; + + ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key + * and verify that it has been changed. + */ + ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); + ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); + } + } + + PASS(); +} + +/** @brief Verify that the Remote Provisioning client and server is able to be reprovision + * by another device with a Remote Provisioning client and server. + */ +static void test_device_pb_remote_server_same_dev(void) +{ + k_sem_init(&prov_sem, 0, 1); + k_sem_init(&reprov_sem, 0, 1); + + bt_mesh_device_setup(&prov, &rpr_cli_srv_comp); + + ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV)); + + LOG_INF("Waiting for being provisioned..."); + ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); + + LOG_INF("Enabling PB-Remote server"); + ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); + + /* Swap callback to catch when device reprovisioned. */ + prov.node_added = prov_node_added_rpr; + + const uint16_t initial_addr = bt_mesh_primary_addr(); + + LOG_INF("Devkey refresh, waiting for being reprov ...\n"); + reprovision_remote_devkey_server(initial_addr); + + LOG_INF("Composition data refresh, waiting for being reprov ...\n"); + reprovision_remote_comp_data_server(initial_addr); + + LOG_INF("Address refresh, waiting for being reprov ...\n"); + reprovision_remote_address_server(initial_addr); + + PASS(); +} + static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_simple *comp) { uint8_t page_rsp; @@ -1573,6 +1787,10 @@ static const struct bst_test_instance test_connect[] = { "Device: pb-remote reprovisioning, NPPI robustness"), TEST_CASE(device, pb_remote_server_unproved_unresponsive, "Device: used for remote provisioning, starts unprovisioned, stops responding"), + TEST_CASE(device, pb_remote_client_server_same_dev, + "Device: used for remote provisioning, with both client and server"), + TEST_CASE(device, pb_remote_server_same_dev, + "Device: used for remote reprovisioning, with both client and server"), #endif TEST_CASE(provisioner, pb_adv_no_oob, diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh new file mode 100755 index 00000000000..33de74370e1 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test a node re-provisioning through Remote Provisioning models. Procedure: +# 1. Device (prov_device_pb_remote_client_server_same_dev) provisions it self +# and start scanning for an upprovisioned device, and provisions the the +# second device (prov_device_pb_remote_server_same_dev) with local RPR server. +# 2. The first device (prov_device_pb_remote_client_server_same_dev) execute +# device key refresh procedure the second device (prov_device_pb_remote_server_same_dev). +# 3. The first device (prov_device_pb_remote_client_server_same_dev) execute +# composition refresh procedure the second device (prov_device_pb_remote_server_same_dev). +# 4. The first device (prov_device_pb_remote_client_server_same_dev) execute +# address refresh procedure the second device (prov_device_pb_remote_server_same_dev). +# 5. The first device (prov_device_pb_remote_client_server_same_dev) execute +# device key refresh procedure on it self with local RPR client and server. +# 6. The first device (prov_device_pb_remote_client_server_same_dev) execute +# composition refresh procedure on it self with local RPR client and server. +# 7. The first device (prov_device_pb_remote_client_server_same_dev) execute +# address refresh procedure on it self with local RPR client and server. +conf=prj_mesh1d1_conf +RunTest mesh_prov_pb_remote_client_server_same_dev \ + prov_device_pb_remote_client_server_same_dev \ + prov_device_pb_remote_server_same_dev + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_prov_pb_remote_client_server_same_dev \ + prov_device_pb_remote_client_server_same_dev \ + prov_device_pb_remote_server_same_dev From 6e789e7492049af5a530302b8d43ac8d60629f84 Mon Sep 17 00:00:00 2001 From: Abram Early Date: Tue, 3 Oct 2023 16:45:13 -0600 Subject: [PATCH 1732/4498] drivers: can: mcan: Move RF0L and RF1L to line 1 The code is designed to handle RF0L and RF1L in line 1, but they were being sent to line 0. Becuase they weren't handled, the interrupts would never be handled which locked up the chip. Signed-off-by: Abram Early --- drivers/can/can_mcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index b49f6c7c5ed..df796350263 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -1511,7 +1511,7 @@ int can_mcan_init(const struct device *dev) return err; } - reg = CAN_MCAN_ILS_RF0NL | CAN_MCAN_ILS_RF1NL; + reg = CAN_MCAN_ILS_RF0NL | CAN_MCAN_ILS_RF1NL | CAN_MCAN_ILS_RF0LL | CAN_MCAN_ILS_RF1LL; err = can_mcan_write_reg(dev, CAN_MCAN_ILS, reg); if (err != 0) { return err; From 5dcaf267fbee8023d285d18191eeb717ce59235d Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 4 Oct 2023 16:06:30 +0300 Subject: [PATCH 1733/4498] net: lwm2m: Add Docker based test script Add Docker based test script for LwM2M interoperability test. Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/interop/README.md | 8 +++++++- tests/net/lib/lwm2m/interop/docker-test.sh | 20 +++++++++++++++++++ .../lib/lwm2m/interop/pytest/test_lwm2m.py | 3 ++- west.yml | 2 +- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 tests/net/lib/lwm2m/interop/docker-test.sh diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md index 858f5007f64..19883ac1821 100644 --- a/tests/net/lib/lwm2m/interop/README.md +++ b/tests/net/lib/lwm2m/interop/README.md @@ -74,7 +74,13 @@ Install with `pip install CoAPthon3` ``` twister -p native_posix -vv --enable-slow -T tests/net/lib/lwm2m/interop -`````` +``` + +Or use the Docker based testing + +``` +./scripts/net/run-sample-tests.sh tests/net/lib/lwm2m/interop +``` ## Test specification diff --git a/tests/net/lib/lwm2m/interop/docker-test.sh b/tests/net/lib/lwm2m/interop/docker-test.sh new file mode 100644 index 00000000000..9184461aec4 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/docker-test.sh @@ -0,0 +1,20 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if [ -z "$RUNNING_FROM_MAIN_SCRIPT" ]; then + echo "Do not run this script directly!" + echo "Run $ZEPHYR_BASE/scripts/net/run-sample-tests.sh instead." + exit 1 +fi + +IP="--ip=192.0.2.2 --ip6=2001:db8::2" +FWD="-p 8080:8080 -p 8081:8081 -p 5683:5683/udp" + +start_configuration "$IP $FWD" || return $? +start_docker "/net-tools/start-leshan.sh" || return $? + +twister -p native_posix -T ./ --enable-slow -vv + +result=$? + +stop_docker diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index 21ed51ef1e6..53a205fadb9 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -112,7 +112,7 @@ def verify_LightweightM2M_1_1_int_107(shell: Shell, leshan: Leshan, endpoint: st lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) lifetime = int(lines[0]) assert lifetime == 120 - logger.debug(f'sleeping for {lifetime} s') + logger.debug(f'Wait for update, max {lifetime} s') shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=lifetime) assert leshan.get(f'/clients/{endpoint}') @@ -123,6 +123,7 @@ def verify_LightweightM2M_1_1_int_108(leshan, endpoint): def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: str): logger.info("LightweightM2M-1.1-int-109 - Behavior in Queue Mode") verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) + logger.debug('Wait for Queue RX OFF') shell._device.readlines_until(regex='.*Queue mode RX window closed', timeout=120) # Restore previous value shell.exec_command('lwm2m write 1/0/1 -u32 86400') diff --git a/west.yml b/west.yml index 09ac8f93616..d3aa85303e2 100644 --- a/west.yml +++ b/west.yml @@ -289,7 +289,7 @@ manifest: - debug revision: a819419603a2dfcb47f7f39092e1bc112e45d1ef - name: net-tools - revision: e0828aa9629b533644dc96ff6d1295c939bd713c + revision: d68ee9d17648a1bb3729c2023abfcb735dfe92fa path: tools/net-tools groups: - tools From 1ecd4fda1a2e3f3aea84453962cde098565535f6 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 5 Oct 2023 13:44:45 +0300 Subject: [PATCH 1734/4498] net: script: Fix the net-tools path Fix the correct path to net-tools directory. Also default to Bash instead of /bin/sh as we use Bash syntax. Signed-off-by: Seppo Takalo --- scripts/net/run-sample-tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/net/run-sample-tests.sh b/scripts/net/run-sample-tests.sh index f99215685e0..11162b30b5e 100755 --- a/scripts/net/run-sample-tests.sh +++ b/scripts/net/run-sample-tests.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright (c) 2019 Intel Corporation # SPDX-License-Identifier: Apache-2.0 @@ -36,7 +36,7 @@ check_dirs () do local l - l="$d/net-tools" + l="$d/tools/net-tools" if [ -d "$l" ]; then NET_TOOLS_BASE="$l" break From f977457c07b7e7d670ff900136561cb6e6bc6018 Mon Sep 17 00:00:00 2001 From: Henrik Eriksen Date: Thu, 5 Oct 2023 09:00:21 +0200 Subject: [PATCH 1735/4498] bluetooth: tester: pacs: Added set Locations and Contexts. - Set Locations. - Set Available Contexts. - Set Supported Contexts. Signed-off-by: Henrik Eriksen --- tests/bluetooth/tester/src/btp/btp_pacs.h | 20 ++++++- tests/bluetooth/tester/src/btp_bap.c | 65 +++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp/btp_pacs.h b/tests/bluetooth/tester/src/btp/btp_pacs.h index f0fab1553ea..91f9596e869 100644 --- a/tests/bluetooth/tester/src/btp/btp_pacs.h +++ b/tests/bluetooth/tester/src/btp/btp_pacs.h @@ -19,7 +19,25 @@ struct btp_pacs_read_supported_commands_rp { #define BTP_PACS_CHARACTERISTIC_AVAILABLE_AUDIO_CONTEXTS 0x05 #define BTP_PACS_CHARACTERISTIC_SUPPORTED_AUDIO_CONTEXTS 0x06 -#define BTP_PACS_UPDATE_CHARACTERISTIC 0x02 +#define BTP_PACS_UPDATE_CHARACTERISTIC 0x02 struct btp_pacs_update_characteristic_cmd { uint8_t characteristic; } __packed; + +#define BTP_PACS_SET_LOCATION 0x03 +struct btp_pacs_set_location_cmd { + uint8_t dir; + uint32_t location; +} __packed; + +#define BTP_PACS_SET_AVAILABLE_CONTEXTS 0x04 +struct btp_pacs_set_available_contexts_cmd { + uint16_t sink_contexts; + uint16_t source_contexts; +} __packed; + +#define BTP_PACS_SET_SUPPORTED_CONTEXTS 0x05 +struct btp_pacs_set_supported_contexts_cmd { + uint16_t sink_contexts; + uint16_t source_contexts; +} __packed; diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index dda0dfc138b..3e171e2407c 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -2483,6 +2483,10 @@ static uint8_t pacs_supported_commands(const void *cmd, uint16_t cmd_len, /* octet 0 */ tester_set_bit(rp->data, BTP_PACS_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_PACS_UPDATE_CHARACTERISTIC); + tester_set_bit(rp->data, BTP_PACS_SET_LOCATION); + tester_set_bit(rp->data, BTP_PACS_SET_AVAILABLE_CONTEXTS); + tester_set_bit(rp->data, BTP_PACS_SET_SUPPORTED_CONTEXTS); *rsp_len = sizeof(*rp) + 1; @@ -2535,6 +2539,52 @@ static uint8_t pacs_update_characteristic(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t pacs_set_location(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_pacs_set_location_cmd *cp = cmd; + int err; + + err = bt_pacs_set_location((enum bt_audio_dir)cp->dir, + (enum bt_audio_location)cp->location); + + return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; +} + +static uint8_t pacs_set_available_contexts(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_pacs_set_available_contexts_cmd *cp = cmd; + int err; + + err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK, + (enum bt_audio_context)cp->sink_contexts); + if (err) { + return BTP_STATUS_FAILED; + } + err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE, + (enum bt_audio_context)cp->source_contexts); + + return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; +} + +static uint8_t pacs_set_supported_contexts(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_pacs_set_supported_contexts_cmd *cp = cmd; + int err; + + err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK, + (enum bt_audio_context)cp->sink_contexts); + if (err) { + return BTP_STATUS_FAILED; + } + err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE, + (enum bt_audio_context)cp->source_contexts); + + return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; +} + static const struct btp_handler pacs_handlers[] = { { .opcode = BTP_PACS_READ_SUPPORTED_COMMANDS, @@ -2547,6 +2597,21 @@ static const struct btp_handler pacs_handlers[] = { .expect_len = sizeof(struct btp_pacs_update_characteristic_cmd), .func = pacs_update_characteristic, }, + { + .opcode = BTP_PACS_SET_LOCATION, + .expect_len = sizeof(struct btp_pacs_set_location_cmd), + .func = pacs_set_location + }, + { + .opcode = BTP_PACS_SET_AVAILABLE_CONTEXTS, + .expect_len = sizeof(struct btp_pacs_set_available_contexts_cmd), + .func = pacs_set_available_contexts + }, + { + .opcode = BTP_PACS_SET_SUPPORTED_CONTEXTS, + .expect_len = sizeof(struct btp_pacs_set_supported_contexts_cmd), + .func = pacs_set_supported_contexts + } }; static uint8_t bap_supported_commands(const void *cmd, uint16_t cmd_len, From 8db7be7a6f5bbca57ef0ae487979143b27545819 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 6 Oct 2023 10:44:18 +0200 Subject: [PATCH 1736/4498] samples: Bluetooth: Fix seq_num in broadcast audio source When using multiple streams the seq_num provided to the controller would be incorrect as we used a single global seq_num rather than a proper seq_num per stream. Signed-off-by: Emil Gydesen --- .../broadcast_audio_source/src/main.c | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_source/src/main.c b/samples/bluetooth/broadcast_audio_source/src/main.c index f1ab4034987..e30243791b5 100644 --- a/samples/bluetooth/broadcast_audio_source/src/main.c +++ b/samples/bluetooth/broadcast_audio_source/src/main.c @@ -21,7 +21,11 @@ BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED, static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); -static struct bt_bap_stream streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; +static struct broadcast_source_stream { + struct bt_bap_stream stream; + uint16_t seq_num; + size_t sent_cnt; +} streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; static struct bt_bap_broadcast_source *broadcast_source; NET_BUF_POOL_FIXED_DEFINE(tx_pool, @@ -39,6 +43,11 @@ static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); static void stream_started_cb(struct bt_bap_stream *stream) { + struct broadcast_source_stream *source_stream = + CONTAINER_OF(stream, struct broadcast_source_stream, stream); + + source_stream->seq_num = 0U; + source_stream->sent_cnt = 0U; k_sem_give(&sem_started); } @@ -49,7 +58,8 @@ static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) static void stream_sent_cb(struct bt_bap_stream *stream) { - static uint32_t sent_cnt; + struct broadcast_source_stream *source_stream = + CONTAINER_OF(stream, struct broadcast_source_stream, stream); struct net_buf *buf; int ret; @@ -66,8 +76,7 @@ static void stream_sent_cb(struct bt_bap_stream *stream) net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); net_buf_add_mem(buf, mock_data, preset_16_2_1.qos.sdu); - ret = bt_bap_stream_send(stream, buf, seq_num++, - BT_ISO_TIMESTAMP_NONE); + ret = bt_bap_stream_send(stream, buf, source_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { /* This will end broadcasting on this stream. */ printk("Unable to broadcast data on %p: %d\n", stream, ret); @@ -75,9 +84,9 @@ static void stream_sent_cb(struct bt_bap_stream *stream) return; } - sent_cnt++; - if ((sent_cnt % 1000U) == 0U) { - printk("Sent %u total ISO packets\n", sent_cnt); + source_stream->sent_cnt++; + if ((source_stream->sent_cnt % 1000U) == 0U) { + printk("Stream %p: Sent %u total ISO packets\n", stream, source_stream->sent_cnt); } } @@ -106,7 +115,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) } for (size_t j = 0U; j < ARRAY_SIZE(stream_params); j++) { - stream_params[j].stream = &streams[j]; + stream_params[j].stream = &streams[j].stream; stream_params[j].data = NULL; stream_params[j].data_len = 0U; bt_bap_stream_cb_register(stream_params[j].stream, &stream_ops); @@ -249,7 +258,7 @@ int main(void) /* Initialize sending */ for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) { - stream_sent_cb(&streams[i]); + stream_sent_cb(&streams[i].stream); } } From ee0314a8320c651555af8b802e97ca283310c34c Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 6 Oct 2023 10:44:14 +0200 Subject: [PATCH 1737/4498] Bluetooth: host: Replace length check assert with if statement A few of the length checks that deal with HCI packets coming from the controller were using assert statements. But the recommended practice is to drop invalid packets and continue execution whenever a malformed packet arrives from an external source, so replace those assert statements with branches that will drop the packet and return. Signed-off-by: Carles Cufi --- subsys/bluetooth/host/hci_core.c | 19 +++++++++++++++---- subsys/bluetooth/host/iso.c | 6 +++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 710dbf3fe21..7b607d6f048 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -508,8 +508,11 @@ static void hci_acl(struct net_buf *buf) uint8_t flags; LOG_DBG("buf %p", buf); - - BT_ASSERT(buf->len >= sizeof(*hdr)); + if (buf->len < sizeof(*hdr)) { + LOG_ERR("Invalid HCI ACL packet size (%u)", buf->len); + net_buf_unref(buf); + return; + } hdr = net_buf_pull_mem(buf, sizeof(*hdr)); len = sys_le16_to_cpu(hdr->len); @@ -2650,7 +2653,11 @@ static void hci_event(struct net_buf *buf) { struct bt_hci_evt_hdr *hdr; - BT_ASSERT(buf->len >= sizeof(*hdr)); + if (buf->len < sizeof(*hdr)) { + LOG_ERR("Invalid HCI event size (%u)", buf->len); + net_buf_unref(buf); + return; + } hdr = net_buf_pull_mem(buf, sizeof(*hdr)); LOG_DBG("event 0x%02x", hdr->evt); @@ -3714,7 +3721,11 @@ void hci_event_prio(struct net_buf *buf) net_buf_simple_save(&buf->b, &state); - BT_ASSERT(buf->len >= sizeof(*hdr)); + if (buf->len < sizeof(*hdr)) { + LOG_ERR("Invalid HCI event size (%u)", buf->len); + net_buf_unref(buf); + return; + } hdr = net_buf_pull_mem(buf, sizeof(*hdr)); evt_flags = bt_hci_evt_get_flags(hdr->evt); diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 49dd52d0ffb..a1b645c0e2f 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -105,7 +105,11 @@ void hci_iso(struct net_buf *buf) BT_ISO_DATA_DBG("buf %p", buf); - BT_ASSERT(buf->len >= sizeof(*hdr)); + if (buf->len < sizeof(*hdr)) { + LOG_ERR("Invalid HCI ISO packet size (%u)", buf->len); + net_buf_unref(buf); + return; + } hdr = net_buf_pull_mem(buf, sizeof(*hdr)); len = bt_iso_hdr_len(sys_le16_to_cpu(hdr->len)); From c0a349eac4c88ec35dd6920f01fad9d272b10643 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 6 Oct 2023 11:05:23 +0200 Subject: [PATCH 1738/4498] drivers: bluetooth: rpmsg: Send reset only when the Host is included The rpmsg_close() call uses the HCI reset command to reset the controller. But when building as controller-only we do not bring in the infrastructure to send HCI commands (nor should we) and rpmsg_close() will not be called anyway. Fixes #63534. Signed-off-by: Carles Cufi --- drivers/bluetooth/hci/rpmsg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index e1fc5180df5..9025791f1c0 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -339,10 +339,12 @@ static int bt_rpmsg_close(void) { int err; - err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL); - if (err) { - LOG_ERR("Sending reset command failed with: %d", err); - return err; + if (IS_ENABLED(CONFIG_BT_HCI_HOST)) { + err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL); + if (err) { + LOG_ERR("Sending reset command failed with: %d", err); + return err; + } } err = ipc_service_deregister_endpoint(&hci_ept); From 12c1fe4d8374147a8d57ac7bc3e1497f41c32d18 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 6 Oct 2023 12:20:08 +0200 Subject: [PATCH 1739/4498] cmake: fix git dependency for version.h creation Fixes: #63610 Fix a variable spelling mistake which caused a required dependency to not be set. Together with this fix, then remove an unneeded CMake cache update. The `ZEPHYR_GIT_INDEX-NOTFOUND` value is not really useful in this case as a not set var will also ensure that Zephyr is checked to be a git repo or not. And when detected as a git repo, then `ZEPHYR_GIT_INDEX` is set to correct value. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d5c643f3e4..7aae816c4b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -511,11 +511,9 @@ endif() if(DEFINED BUILD_VERSION) set(build_version_argument "-DBUILD_VERSION=${BUILD_VERSION}") elseif(NOT ZEPHYR_GIT_INDEX) - set(ZEPHYR_GIT_INDEX ZEPHYR_GIT_INDEX-NOTFOUND CACHE PATH - "Path to Zephyr git repository index file") if(EXISTS ${ZEPHYR_BASE}/.git/index) - set(ZEPHYR_GIT_DIR ${ZEPHYR_BASE}/.git/index CACHE PATH - "Path to Zephyr git repository index file" FORCE) + set(ZEPHYR_GIT_INDEX ${ZEPHYR_BASE}/.git/index CACHE PATH + "Path to Zephyr git repository index file") elseif(EXISTS ${ZEPHYR_BASE}/.git) # Likely a git-submodule. Let's ask git where the real database is located. find_package(Git QUIET) @@ -535,7 +533,7 @@ elseif(NOT ZEPHYR_GIT_INDEX) message(WARNING "BUILD_VERSION: git rev-parse warned: ${stderr}") endif() set(ZEPHYR_GIT_INDEX ${zephyr_git_dir}/index CACHE PATH - "Path to Zephyr git repository index file" FORCE) + "Path to Zephyr git repository index file") endif() else() message(WARNING "Could not find git installation, " From 0eb027ab7cc2f372d969f7c5a1fbac39294163e8 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 6 Oct 2023 14:12:18 +0200 Subject: [PATCH 1740/4498] tests: bluetooth: tester: Fix self-update test DFU/SR/FD/BV-59-C DFU/SR/FD/BV-59-C tests Distributor self-update. Because the actuall firmware swapping doesn't happen, we need to just simulate the swapping by setting new Firmware ID sent by LT. We use slot to take firmware id as by procedure, Fw Update Server doesn't know about it. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp_mesh.c | 33 ++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index a2574636902..5f3492c45e5 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -17,6 +17,7 @@ #include #include #include +#include "mesh/access.h" #include #define LOG_MODULE_NAME bttester_mesh @@ -112,6 +113,19 @@ static const struct bt_mesh_blob_io dummy_blob_io = { #endif #if defined(CONFIG_BT_MESH_DFD_SRV) +static const struct bt_mesh_dfu_slot *dfu_self_update_slot; + +static bool is_self_update(struct bt_mesh_dfd_srv *srv) +{ + for (int i = 0; i < ARRAY_SIZE(srv->targets); i++) { + if (bt_mesh_has_addr(srv->targets[i].blob.addr)) { + return true; + } + } + + return false; +} + /* DFD Model data*/ static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv, const struct bt_mesh_dfu_slot *slot, @@ -138,6 +152,13 @@ static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, *io = &dummy_blob_io; + dfu_self_update_slot = NULL; + + if (is_self_update(srv)) { + LOG_DBG("DFD server starts self-update..."); + dfu_self_update_slot = slot; + } + return 0; } @@ -216,7 +237,7 @@ static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers }; #if defined(CONFIG_BT_MESH_DFU_SRV) const char *metadata_data = "1100000000000011"; -static uint8_t dfu_fwid[] = { +static uint8_t dfu_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -284,6 +305,16 @@ static int dfu_apply(struct bt_mesh_dfu_srv *srv, LOG_DBG("Applying DFU transfer..."); +#if defined(CONFIG_BT_MESH_DFD_SRV) + if (is_self_update(&dfd_srv) && dfu_self_update_slot != NULL) { + LOG_DBG("Swapping fwid for self-update"); + /* Simulate self-update by swapping fwid. */ + memcpy(&dfu_fwid[0], dfu_self_update_slot->fwid, dfu_self_update_slot->fwid_len); + dfu_imgs[0].fwid_len = dfu_self_update_slot->fwid_len; + } + +#endif + return 0; } From 57cb1b1ccb11a47c911772678b05cb309c9dcaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 5 Oct 2023 13:19:51 +0200 Subject: [PATCH 1741/4498] Bluetooth: Mesh: Add missing comp pages to LCD mod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for all composition data pages to the Large Composition Data model. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/Kconfig | 10 + subsys/bluetooth/mesh/access.c | 228 ++++++++++++-------- subsys/bluetooth/mesh/access.h | 2 +- subsys/bluetooth/mesh/large_comp_data_srv.c | 53 ++++- 4 files changed, 199 insertions(+), 94 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index a2f5ffc1097..7527a1beb16 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1375,6 +1375,16 @@ config BT_MESH_PRIV_BEACON_CLI endif # BT_MESH_PRIV_BEACONS +config BT_MESH_COMP_PST_BUF_SIZE + int "Composition Data Page persistence buffer size" + default 100 + help + Stack allocated buffer used to temporarily hold Composition + Data Pages during flash operations. Should reflect the size + of the largest Composition Data Page present in the application. + Note that this buffer should still be large enough to restore previously stored + pages after a performed device firmware update. + config BT_MESH_COMP_PAGE_1 bool "Support for Composition Data Page 1" depends on BT_MESH_MODEL_EXTENSIONS diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index b6dab2d67a7..24259165e05 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -173,6 +173,18 @@ static void data_buf_add_le16_offset(struct net_buf_simple *buf, } } +static void data_buf_add_mem_offset(struct net_buf_simple *buf, uint8_t *data, size_t len, + size_t *offset) +{ + if (*offset >= len) { + *offset -= len; + return; + } + + net_buf_simple_add_mem(buf, data + *offset, len - *offset); + *offset = 0; +} + static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, void *user_data) { @@ -187,20 +199,6 @@ static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) -static void data_buf_add_mem_offset(struct net_buf_simple *buf, - const void *mem, size_t len, - size_t *offset) -{ - if (*offset >= len) { - *offset -= len; - return; - } else if (*offset > 0) { - net_buf_simple_add_mem(buf, ((uint8_t *)mem), (len - *offset)); - - } else { - net_buf_simple_add_mem(buf, mem, len); - } -} static size_t metadata_model_size(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd) @@ -366,23 +364,6 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) } #endif -size_t bt_mesh_comp_page_0_size(void) -{ - const struct bt_mesh_comp *comp; - const struct bt_mesh_elem *elem; - size_t size = 10; - int i; - - comp = bt_mesh_comp_get(); - - for (i = 0; i < comp->elem_count; i++) { - elem = &comp->elem[i]; - size += bt_mesh_comp_elem_size(elem); - } - - return size; -} - static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, size_t *offset) { @@ -398,7 +379,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, return 0; } - if (net_buf_simple_tailroom(buf) < (elem_size + BT_MESH_MIC_SHORT)) { + if (net_buf_simple_tailroom(buf) < ((elem_size - *offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, @@ -516,8 +497,8 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id) return false; } -static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, - uint8_t *mod_cnt, struct net_buf_simple *buf) +static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t *mod_cnt, + struct net_buf_simple *buf, size_t *offset) { uint8_t ext_mod_cnt; bool cor_present; @@ -536,41 +517,41 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, if (cor_present) { mod_elem_info |= BIT(0); } - net_buf_simple_add_u8(buf, mod_elem_info); + data_buf_add_u8_offset(buf, mod_elem_info, offset); if (cor_present) { - net_buf_simple_add_u8(buf, *cor_id); + data_buf_add_u8_offset(buf, *cor_id, offset); } memset(mod_cnt, ext_mod_cnt, sizeof(uint8_t)); } static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod, - uint8_t ext_mod_cnt) + uint8_t ext_mod_cnt, size_t *offset) { - int i, offset; + int i, elem_offset; uint8_t mod_idx; MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i)) { - offset = mod->elem_idx - mod_rel_list[i].elem_base; + elem_offset = mod->elem_idx - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && - offset < 4 && - offset > -5) { + elem_offset < 4 && + elem_offset > -5) { /* short format */ - if (offset < 0) { - offset += 8; + if (elem_offset < 0) { + elem_offset += 8; } - offset |= mod_idx << 3; - net_buf_simple_add_u8(buf, offset); + elem_offset |= mod_idx << 3; + data_buf_add_u8_offset(buf, elem_offset, offset); } else { /* long format */ - if (offset < 0) { - offset += 256; + if (elem_offset < 0) { + elem_offset += 256; } - net_buf_simple_add_u8(buf, offset); - net_buf_simple_add_u8(buf, mod_idx); + data_buf_add_u8_offset(buf, elem_offset, offset); + data_buf_add_u8_offset(buf, mod_idx, offset); } } } @@ -613,7 +594,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) return temp_size; } -static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) +static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offset) { const struct bt_mesh_comp *comp; uint8_t cor_id = 0; @@ -623,8 +604,14 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) comp = bt_mesh_comp_get(); for (i = 0; i < comp->elem_count; i++) { - if (net_buf_simple_tailroom(buf) < - (page1_elem_size(&comp->elem[i]) + BT_MESH_MIC_SHORT)) { + size_t elem_size = page1_elem_size(&comp->elem[i]); + + if (offset >= elem_size) { + offset -= elem_size; + continue; + } + + if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, @@ -639,49 +626,53 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) return -E2BIG; } - net_buf_simple_add_u8(buf, comp->elem[i].model_count); - net_buf_simple_add_u8(buf, comp->elem[i].vnd_model_count); + data_buf_add_u8_offset(buf, comp->elem[i].model_count, &offset); + data_buf_add_u8_offset(buf, comp->elem[i].vnd_model_count, &offset); for (j = 0; j < comp->elem[i].model_count; j++) { - prep_model_item_header(&comp->elem[i].models[j], - &cor_id, &ext_mod_cnt, buf); + prep_model_item_header(&comp->elem[i].models[j], &cor_id, &ext_mod_cnt, buf, + &offset); if (ext_mod_cnt != 0) { - add_items_to_page(buf, - &comp->elem[i].models[j], - ext_mod_cnt); + add_items_to_page(buf, &comp->elem[i].models[j], ext_mod_cnt, + &offset); } } for (j = 0; j < comp->elem[i].vnd_model_count; j++) { - prep_model_item_header(&comp->elem[i].vnd_models[j], - &cor_id, &ext_mod_cnt, buf); + prep_model_item_header(&comp->elem[i].vnd_models[j], &cor_id, &ext_mod_cnt, + buf, &offset); if (ext_mod_cnt != 0) { - add_items_to_page(buf, - &comp->elem[i].vnd_models[j], - ext_mod_cnt); + add_items_to_page(buf, &comp->elem[i].vnd_models[j], ext_mod_cnt, + &offset); } } } return 0; } -static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf) +static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offset) { if (!dev_comp2) { LOG_ERR("Composition data P2 not registered"); return -ENODEV; } + size_t elem_size; + for (int i = 0; i < dev_comp2->record_cnt; i++) { - if (net_buf_simple_tailroom(buf) < - (8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len + - BT_MESH_MIC_SHORT)) { + elem_size = + 8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len; + if (offset >= elem_size) { + offset -= elem_size; + continue; + } + + if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, * the element shall not be reported. */ - LOG_DBG("Record 0x%04x didn't fit in the Data field", - i); + LOG_DBG("Record 0x%04x didn't fit in the Data field", i); return 0; } @@ -689,20 +680,20 @@ static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf) return -E2BIG; } - net_buf_simple_add_le16(buf, dev_comp2->record[i].id); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.x); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.y); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.z); - net_buf_simple_add_u8(buf, dev_comp2->record[i].elem_offset_cnt); + data_buf_add_le16_offset(buf, dev_comp2->record[i].id, &offset); + data_buf_add_u8_offset(buf, dev_comp2->record[i].version.x, &offset); + data_buf_add_u8_offset(buf, dev_comp2->record[i].version.y, &offset); + data_buf_add_u8_offset(buf, dev_comp2->record[i].version.z, &offset); + data_buf_add_u8_offset(buf, dev_comp2->record[i].elem_offset_cnt, &offset); if (dev_comp2->record[i].elem_offset_cnt) { - net_buf_simple_add_mem(buf, dev_comp2->record[i].elem_offset, - dev_comp2->record[i].elem_offset_cnt); + data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].elem_offset, + dev_comp2->record[i].elem_offset_cnt, &offset); } - net_buf_simple_add_le16(buf, dev_comp2->record[i].data_len); + data_buf_add_le16_offset(buf, dev_comp2->record[i].data_len, &offset); if (dev_comp2->record[i].data_len) { - net_buf_simple_add_mem(buf, dev_comp2->record[i].data, - dev_comp2->record[i].data_len); + data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].data, + dev_comp2->record[i].data_len, &offset); } } @@ -2212,20 +2203,89 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o if (page == 0 || page == 128) { return bt_mesh_comp_data_get_page_0(buf, offset); } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { - return bt_mesh_comp_data_get_page_1(buf); + return bt_mesh_comp_data_get_page_1(buf, offset); } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { - return bt_mesh_comp_data_get_page_2(buf); + return bt_mesh_comp_data_get_page_2(buf, offset); } return -EINVAL; } +size_t comp_page_0_size(void) +{ + const struct bt_mesh_comp *comp; + const struct bt_mesh_elem *elem; + size_t size = 10; /* Non-variable length params of comp page 0. */ + + comp = bt_mesh_comp_get(); + + for (int i = 0; i < comp->elem_count; i++) { + elem = &comp->elem[i]; + size += bt_mesh_comp_elem_size(elem); + } + + return size; +} + +size_t comp_page_1_size(void) +{ + const struct bt_mesh_comp *comp; + size_t size = 0; + + comp = bt_mesh_comp_get(); + + for (int i = 0; i < comp->elem_count; i++) { + + size += page1_elem_size(&comp->elem[i]); + } + + return size; +} + +size_t comp_page_2_size(void) +{ + size_t size = 0; + + if (!dev_comp2) { + LOG_ERR("Composition data P2 not registered"); + return size; + } + + for (int i = 0; i < dev_comp2->record_cnt; i++) { + size += 8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len; + } + return size; +} + +size_t bt_mesh_comp_page_size(uint8_t page) +{ + if (page == 0 || page == 128) { + return comp_page_0_size(); + } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { + return comp_page_1_size(); + } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { + return comp_page_2_size(); + } + + return 0; +} + int bt_mesh_comp_store(void) { - NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX); +#if IS_ENABLED(CONFIG_BT_MESH_V1d1) + NET_BUF_SIMPLE_DEFINE(buf, CONFIG_BT_MESH_COMP_PST_BUF_SIZE); int err; for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) { + size_t page_size = bt_mesh_comp_page_size(i); + + if (page_size > CONFIG_BT_MESH_COMP_PST_BUF_SIZE) { + LOG_WRN("CDP%d is larger than the CDP persistence buffer. " + "Please increase the CDP persistence buffer size " + "to the required size (%d bytes)", + i, page_size); + } + net_buf_simple_reset(&buf); err = bt_mesh_comp_data_get_page(&buf, comp_data_pages[i].page, 0); @@ -2242,7 +2302,7 @@ int bt_mesh_comp_store(void) LOG_DBG("Stored CDP%d", comp_data_pages[i].page); } - +#endif return 0; } diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 4740963dd21..6027768ea94 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -23,7 +23,7 @@ enum { void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); uint8_t bt_mesh_elem_count(void); -size_t bt_mesh_comp_page_0_size(void); +size_t bt_mesh_comp_page_size(uint8_t page); int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset); size_t bt_mesh_metadata_page_0_size(void); int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 9f097f4355a..12497d053a2 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -59,24 +59,59 @@ static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mes LOG_DBG("page %u offset %u", page, offset); bt_mesh_model_msg_init(&rsp, OP_LARGE_COMP_DATA_STATUS); - - if (page != 0U) { + if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 130U; + } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 129U; + } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 128U; + } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + page = 2U; + } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + page = 1U; + } else if (page != 0U) { LOG_DBG("Composition page %u not available", page); page = 0U; } net_buf_simple_add_u8(&rsp, page); - - total_size = bt_mesh_comp_page_0_size(); net_buf_simple_add_le16(&rsp, offset); - net_buf_simple_add_le16(&rsp, total_size); - if (offset < total_size) { - err = bt_mesh_comp_data_get_page_0(&rsp, offset); - if (err && err != -E2BIG) { - LOG_ERR("comp_get_page_0 returned error"); + if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && page < 128) { + size_t msg_space; + + NET_BUF_SIMPLE_DEFINE(temp_buf, CONFIG_BT_MESH_COMP_PST_BUF_SIZE); + err = bt_mesh_comp_read(&temp_buf, page); + if (err) { + LOG_ERR("Could not read comp data p%d, err: %d", page, err); return err; } + + net_buf_simple_add_le16(&rsp, temp_buf.len); + if (offset > temp_buf.len) { + return 0; + } + + msg_space = net_buf_simple_tailroom(&rsp) - BT_MESH_MIC_SHORT; + net_buf_simple_add_mem( + &rsp, temp_buf.data + offset, + (msg_space < (temp_buf.len - offset)) ? msg_space : temp_buf.len - offset); + } else { + total_size = bt_mesh_comp_page_size(page); + net_buf_simple_add_le16(&rsp, total_size); + + if (offset < total_size) { + err = bt_mesh_comp_data_get_page(&rsp, page, offset); + if (err && err != -E2BIG) { + LOG_ERR("Could not read comp data p%d, err: %d", page, err); + return err; + } + } } if (bt_mesh_model_send(model, ctx, &rsp, NULL, NULL)) { From 2e3ae017e3c7e3c51da87f59ce83f52d9daba4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 5 Oct 2023 13:19:51 +0200 Subject: [PATCH 1742/4498] tests: Bluetooth: Mesh: LCD test all comp pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test for verifying split get operation for all composition data pages. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/CMakeLists.txt | 2 +- tests/bsim/bluetooth/mesh/overlay_pst.conf | 1 + tests/bsim/bluetooth/mesh/src/main.c | 4 +- tests/bsim/bluetooth/mesh/src/test_lcd.c | 91 ++++++++++++++----- ..._data_split.sh => get_comp0_data_split.sh} | 11 ++- .../get_comp0_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp128_data_split.sh | 30 ++++++ .../get_comp128_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp129_data_split.sh | 30 ++++++ .../get_comp129_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp130_data_split.sh | 30 ++++++ .../get_comp130_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp1_data_split.sh | 30 ++++++ .../get_comp1_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp2_data_split.sh | 30 ++++++ .../get_comp2_data_split_dfu.sh | 33 +++++++ .../large_comp_data/get_comp_data_max_sdu.sh | 3 +- .../large_comp_data/get_metadata_max_sdu.sh | 3 +- .../large_comp_data/get_metadata_split.sh | 3 +- 19 files changed, 434 insertions(+), 32 deletions(-) rename tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/{get_comp_data_split.sh => get_comp0_data_split.sh} (76%) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split_dfu.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split_dfu.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split_dfu.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split_dfu.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split_dfu.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split.sh create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split_dfu.sh diff --git a/tests/bsim/bluetooth/mesh/CMakeLists.txt b/tests/bsim/bluetooth/mesh/CMakeLists.txt index 0fb2357826c..bc528ae3f4b 100644 --- a/tests/bsim/bluetooth/mesh/CMakeLists.txt +++ b/tests/bsim/bluetooth/mesh/CMakeLists.txt @@ -30,6 +30,7 @@ if(CONFIG_SETTINGS) src/test_dfu.c src/test_blob.c src/test_sar.c + src/test_lcd.c ) endif() @@ -78,7 +79,6 @@ else() src/test_blob.c src/test_op_agg.c src/test_sar.c - src/test_lcd.c ) endif() diff --git a/tests/bsim/bluetooth/mesh/overlay_pst.conf b/tests/bsim/bluetooth/mesh/overlay_pst.conf index 0933bdf1020..6a56ec8065b 100644 --- a/tests/bsim/bluetooth/mesh/overlay_pst.conf +++ b/tests/bsim/bluetooth/mesh/overlay_pst.conf @@ -19,3 +19,4 @@ CONFIG_BT_MESH_SEQ_STORE_RATE=1 CONFIG_BT_MESH_RPL_STORE_TIMEOUT=1 CONFIG_BT_MESH_STORE_TIMEOUT=1 CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT=1 +CONFIG_BT_MESH_COMP_PST_BUF_SIZE=600 diff --git a/tests/bsim/bluetooth/mesh/src/main.c b/tests/bsim/bluetooth/mesh/src/main.c index ea7ceff0883..97f8b34c5ca 100644 --- a/tests/bsim/bluetooth/mesh/src/main.c +++ b/tests/bsim/bluetooth/mesh/src/main.c @@ -14,6 +14,7 @@ extern struct bst_test_list *test_provision_pst_install(struct bst_test_list *te #if defined(CONFIG_BT_MESH_V1d1) extern struct bst_test_list *test_dfu_install(struct bst_test_list *test); extern struct bst_test_list *test_blob_pst_install(struct bst_test_list *test); +extern struct bst_test_list *test_lcd_install(struct bst_test_list *test); extern struct bst_test_list *test_sar_pst_install(struct bst_test_list *test); #endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_MESH_GATT_PROXY) @@ -39,7 +40,6 @@ extern struct bst_test_list *test_adv_install(struct bst_test_list *test); extern struct bst_test_list *test_blob_install(struct bst_test_list *test); extern struct bst_test_list *test_op_agg_install(struct bst_test_list *test); extern struct bst_test_list *test_sar_install(struct bst_test_list *test); -extern struct bst_test_list *test_lcd_install(struct bst_test_list *test); #endif /* defined(CONFIG_BT_MESH_V1d1) */ #endif @@ -51,6 +51,7 @@ bst_test_install_t test_installers[] = { test_provision_pst_install, test_dfu_install, test_blob_pst_install, + test_lcd_install, test_sar_pst_install, #endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_MESH_GATT_PROXY) @@ -75,7 +76,6 @@ bst_test_install_t test_installers[] = { test_blob_install, test_op_agg_install, test_sar_install, - test_lcd_install, #endif /* defined(CONFIG_BT_MESH_V1d1) */ #endif NULL diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index dc819b8d0de..c4b64447987 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -15,6 +15,7 @@ #include #include +#include "argparse.h" LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); @@ -50,6 +51,41 @@ const struct bt_mesh_model_op dummy_op[] = { BT_MESH_MODEL_OP_END, }; +static const uint8_t elem_offset2[3] = {4, 5, 6}; +static const uint8_t additional_data[2] = {100, 200}; /* A Mesh Profile may have additional data. */ +static const struct bt_mesh_comp2_record comp_rec[40] = { + [0 ... 39] = {.id = 10, + .version.x = 20, + .version.y = 30, + .version.z = 40, + .elem_offset_cnt = sizeof(elem_offset2), + .elem_offset = elem_offset2, + .data_len = sizeof(additional_data), + .data = additional_data}, +}; +static const struct bt_mesh_comp2 comp_p2 = {.record_cnt = ARRAY_SIZE(comp_rec), + .record = comp_rec}; + +static int comp_page; +static bool comp_changed; +static void test_args_parse(int argc, char *argv[]) +{ + bs_args_struct_t args_struct[] = { + {.dest = &comp_page, + .type = 'i', + .name = "{page}", + .option = "page", + .descript = "Current composition data page"}, + {.dest = &comp_changed, + .type = 'b', + .name = "{0, 1}", + .option = "comp-changed-mode", + .descript = "Composition data has changed"}, + }; + + bs_args_parse_all_cmd_line(argc, argv, args_struct); +} + static struct bt_mesh_models_metadata_entry *dummy_meta_entry[] = {}; /* Empty elements to create large composition/meta data */ @@ -224,7 +260,7 @@ static void test_cli_max_sdu_comp_data_request(void) if (err && err != -E2BIG) { FAIL("CLIENT: Failed to get comp data Page 0: %d", err); } - total_size = bt_mesh_comp_page_0_size(); + total_size = bt_mesh_comp_page_size(0); /* Get server composition data and check integrity */ ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, page, offset, &srv_rsp)); @@ -238,12 +274,11 @@ static void test_cli_max_sdu_comp_data_request(void) static void test_cli_split_comp_data_request(void) { int err; - uint8_t page = 0; - uint16_t offset, total_size, prev_len = 0; + uint16_t offset = 0, prev_len = 0; - NET_BUF_SIMPLE_DEFINE(local_comp, 200); - NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_1, 64); - NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_2, 64); + NET_BUF_SIMPLE_DEFINE(local_comp, CONFIG_BT_MESH_COMP_PST_BUF_SIZE); + NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_1, 500); + NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_2, 500); net_buf_simple_init(&local_comp, 0); net_buf_simple_init(&srv_rsp_comp_1, 0); net_buf_simple_init(&srv_rsp_comp_2, 0); @@ -255,32 +290,38 @@ static void test_cli_split_comp_data_request(void) .data = &srv_rsp_comp_2, }; - bt_mesh_device_setup(&prov, &comp_1); + bt_mesh_device_setup(&prov, (comp_page == 0 || comp_page == 128) ? &comp_1 : &comp_2); + bt_mesh_comp2_register(&comp_p2); prov_and_conf(cli_cfg); - target_node_alloc(comp_1, srv_cfg); - - offset = 0; + target_node_alloc((comp_page == 0 || comp_page == 128) ? comp_1 : comp_2, srv_cfg); /* Get local data */ - err = bt_mesh_comp_data_get_page_0(&local_comp, offset); + err = bt_mesh_comp_data_get_page(&local_comp, comp_page, 0); /* Operation is successful even if all data cannot fit in the buffer (-E2BIG) */ if (err && err != -E2BIG) { - FAIL("CLIENT: Failed to get comp data Page 0: %d", err); + FAIL("CLIENT: Failed to get comp data Page %d: %d", err, comp_page); } - total_size = bt_mesh_comp_page_0_size(); + + uint16_t total_size = bt_mesh_comp_page_size(comp_page); + + /* Verify that the total comp page size is not larger than the provided buffer */ + ASSERT_TRUE(total_size <= CONFIG_BT_MESH_COMP_PST_BUF_SIZE); + + /* Wait a bit until the server is ready to respond*/ + k_sleep(K_SECONDS(2)); /* Get first server composition data sample and verify data */ - ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, page, offset, &srv_rsp_1)); - rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_comp, page, offset, total_size, - &prev_len); + ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, comp_page, offset, &srv_rsp_1)); + rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_comp, comp_page, offset, + total_size, &prev_len); prev_len = srv_rsp_comp_1.len; - offset += prev_len; + offset = prev_len; /* Get next server composition data sample */ - ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, page, offset, &srv_rsp_2)); - rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_2, &local_comp, page, offset, total_size, - &prev_len); + ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, comp_page, offset, &srv_rsp_2)); + rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_2, &local_comp, comp_page, offset, + total_size, &prev_len); /* Check data integrity of merged sample data */ merge_and_compare_assert(&srv_rsp_comp_1, &srv_rsp_comp_2, &local_comp); @@ -383,9 +424,16 @@ static void test_cli_split_metadata_request(void) static void test_srv_comp_data_status_respond(void) { - bt_mesh_device_setup(&prov, &comp_1); + bt_mesh_device_setup(&prov, (comp_page == 0 || comp_page == 128) ? &comp_1 : &comp_2); + bt_mesh_comp2_register(&comp_p2); prov_and_conf(srv_cfg); + /* Simulate an update of composition data */ + if (comp_changed) { + bt_mesh_comp_change_prepare(); + atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); + } + /* No server callback available. Wait 10 sec for message to be recived */ k_sleep(K_SECONDS(10)); @@ -411,6 +459,7 @@ static void test_srv_metadata_status_respond(void) { \ .test_id = "lcd_" #role "_" #name, \ .test_descr = description, \ + .test_args_f = test_args_parse, \ .test_tick_f = bt_mesh_test_timeout, \ .test_post_init_f = test_##role##_init, \ .test_main_f = test_##role##_##name, \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh similarity index 76% rename from tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_split.sh rename to tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh index 45d2c103246..d65326b3d7f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_split.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh @@ -20,10 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 6. Client merges the two samples and checks that the collected data is # correctly merged, continuous, and matches its local comp data. conf=prj_mesh1d1_conf -RunTest mesh_lcd_test_split_comp_data \ - lcd_cli_split_comp_data_request lcd_srv_comp_data_status_respond +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp0_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=0 conf=prj_mesh1d1_conf -overlay=overlay_psa_conf -RunTest mesh_lcd_test_split_comp_data_psa \ - lcd_cli_split_comp_data_request lcd_srv_comp_data_status_respond +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp0_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=0 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split_dfu.sh new file mode 100755 index 00000000000..6a65a2492ed --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp0_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=0 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp0_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=0 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split.sh new file mode 100755 index 00000000000..77d4a1737a5 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp128_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=128 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp128_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=128 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split_dfu.sh new file mode 100755 index 00000000000..9abdfd00dd7 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp128_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp128_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=128 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp128_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=128 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split.sh new file mode 100755 index 00000000000..fba1760cb36 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp129_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=129 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp129_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=129 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split_dfu.sh new file mode 100755 index 00000000000..282c3425c81 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp129_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp129_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=129 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp129_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=129 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split.sh new file mode 100755 index 00000000000..e3e8f2bad85 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp130_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=130 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp130_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=130 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split_dfu.sh new file mode 100755 index 00000000000..5daf32c54c0 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp130_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp130_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=130 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp130_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=130 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split.sh new file mode 100755 index 00000000000..bc24a9c9bf9 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp1_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp1_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split_dfu.sh new file mode 100755 index 00000000000..59383bb18f1 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp1_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp1_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=1 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp1_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=1 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split.sh new file mode 100755 index 00000000000..53def43d5a0 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp2_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=2 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp2_data_split \ + lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=2 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split_dfu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split_dfu.sh new file mode 100755 index 00000000000..f314f00d6ef --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp2_data_split_dfu.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the LCD server model is able to split the +# composition data when the total size exceeds the maximum access message size. +# The test environment simulates a scenario where the server has completed DFU. +# +# Test procedure: +# 0. Provisioning and setup. Server and client has same comp data. +# 1. Client requests a sample exceeding the maximum avaialble payload from the +# server's composition data. +# 2. Client fetch its local comp data. +# 3. When server status arrive, remove status field data and compare received +# comp data with corresponding bytes in local comp data. +# 4. Client requests the next sample from server's composition data. +# 5. When server status arrive, remove status field data and compare received +# comp data with correspending bytes in local comp data. +# 6. Client merges the two samples and checks that the collected data is +# correctly merged, continuous, and matches its local comp data. +conf=prj_mesh1d1_conf +overlay=overlay_pst_conf +RunTest mesh_lcd_test_comp2_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=2 comp-changed-mode=1 + +conf=prj_mesh1d1_conf +overlay="overlay_pst_conf_overlay_psa_conf" +RunTest mesh_lcd_test_comp2_data_split_dfu \ + lcd_srv_comp_data_status_respond \ + lcd_cli_split_comp_data_request -- -argstest page=2 comp-changed-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_max_sdu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_max_sdu.sh index 99f05637653..b050037ccf0 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_max_sdu.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp_data_max_sdu.sh @@ -15,10 +15,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # comp data with local comp data and assure that the received message length # is 378 bytes (380 bytes access payload). conf=prj_mesh1d1_conf +overlay=overlay_pst_conf RunTest mesh_lcd_test_max_access_payload \ lcd_cli_max_sdu_comp_data_request lcd_srv_comp_data_status_respond conf=prj_mesh1d1_conf -overlay=overlay_psa_conf +overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_lcd_test_max_access_payload_psa \ lcd_cli_max_sdu_comp_data_request lcd_srv_comp_data_status_respond diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_max_sdu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_max_sdu.sh index 83cc788844f..9b0be5ea20f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_max_sdu.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_max_sdu.sh @@ -16,10 +16,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 4. Remove status field data and compare received metadata with # local metadata data. conf=prj_mesh1d1_conf +overlay=overlay_pst_conf RunTest mesh_lcd_test_max_metadata_access_payload \ lcd_cli_max_sdu_metadata_request lcd_srv_metadata_status_respond conf=prj_mesh1d1_conf -overlay=overlay_psa_conf +overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_lcd_test_max_metadata_access_payload_psa \ lcd_cli_max_sdu_metadata_request lcd_srv_metadata_status_respond diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_split.sh index 622b4ce5dba..0e29e7d4219 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_split.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_metadata_split.sh @@ -19,10 +19,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 6. Client merges the two samples and checks that the collected data is # correctly merged, continuous, and matches its local metadata. conf=prj_mesh1d1_conf +overlay=overlay_pst_conf RunTest mesh_lcd_test_split_metadata \ lcd_cli_split_metadata_request lcd_srv_metadata_status_respond conf=prj_mesh1d1_conf -overlay=overlay_psa_conf +overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_lcd_test_split_metadata_psa \ lcd_cli_split_metadata_request lcd_srv_metadata_status_respond From 65f029e1850090887317efa37fc37758c2bffa93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Fri, 6 Oct 2023 08:56:49 +0200 Subject: [PATCH 1743/4498] Bluetooth: Mesh: Common comp page parse func MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create common composition page parser function. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/access.c | 27 +++++++++++++++++++++ subsys/bluetooth/mesh/access.h | 1 + subsys/bluetooth/mesh/cfg_srv.c | 22 +---------------- subsys/bluetooth/mesh/large_comp_data_srv.c | 22 +---------------- 4 files changed, 30 insertions(+), 42 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 24259165e05..2ea7ece90df 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -2562,3 +2562,30 @@ void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod) mod->flags |= BT_MESH_MOD_DATA_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } + +uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf) +{ + uint8_t page = net_buf_simple_pull_u8(buf); + + if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 130U; + } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 129U; + } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 128U; + } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + page = 2U; + } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + page = 1U; + } else if (page != 0U) { + LOG_DBG("Composition page %u not available", page); + page = 0U; + } + + return page; +} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 6027768ea94..f58c6f1d449 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -64,6 +64,7 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); int bt_mesh_comp_store(void); int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page); +uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf); int bt_mesh_models_metadata_store(void); int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index eb732a34910..f65d2cba3c7 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -59,27 +59,7 @@ static int dev_comp_data_get(struct bt_mesh_model *model, LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - page = net_buf_simple_pull_u8(buf); - - if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 130U; - } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 129U; - } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 128U; - } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - page = 2U; - } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { - page = 1U; - } else if (page != 0U) { - LOG_DBG("Composition page %u not available", page); - page = 0U; - } + page = bt_mesh_comp_parse_page(buf); LOG_DBG("Preparing Composition data page %d", page); bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS); diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 12497d053a2..4ee591d9efd 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -53,32 +53,12 @@ static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mes ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - page = net_buf_simple_pull_u8(buf); + page = bt_mesh_comp_parse_page(buf); offset = net_buf_simple_pull_le16(buf); LOG_DBG("page %u offset %u", page, offset); bt_mesh_model_msg_init(&rsp, OP_LARGE_COMP_DATA_STATUS); - if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 130U; - } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 129U; - } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 128U; - } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - page = 2U; - } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { - page = 1U; - } else if (page != 0U) { - LOG_DBG("Composition page %u not available", page); - page = 0U; - } - net_buf_simple_add_u8(&rsp, page); net_buf_simple_add_le16(&rsp, offset); From f4a592f3bb9223fa09a34de3ef150076f1ce237b Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 4 Oct 2023 14:47:39 +0200 Subject: [PATCH 1744/4498] Bluetooth: Mesh: Don't reset mod pointer Don't reset values set in init callback as it is called only once by bt_mesh_init call. The reset callback is called on every node reset. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/rpr_srv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index c8639d8b514..8fb28e56472 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -1337,7 +1337,6 @@ static void rpr_srv_reset(struct bt_mesh_model *mod) atomic_clear(srv.flags); srv.link.dev = NULL; srv.scan.dev = NULL; - srv.mod = NULL; } const struct bt_mesh_model_cb _bt_mesh_rpr_srv_cb = { From 3563347b108a8fe323595060576572fccdb81be6 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Thu, 5 Oct 2023 10:51:02 +0300 Subject: [PATCH 1745/4498] modules: Kconfig.mcux: Remove implicit selection of HAS_CMSIS_CORE CONFIG_HAS_MCUX is also selected by ARM64 and XTENSA-based cores which don't have any CMSIS files. As such, it's wrong to implicitly select CONFIG_HAS_CMSIS_CORE when CONFIG_HAS_MCUX is selected. Since the ARM32-based cores implicitly select CONFIG_HAS_CMSIS_CORE there's no point in CONFIG_HAS_MCUX also selecting it too. The old approach caused config-related warnings in external projects such as SOF after the introduction of Commit '8d5ed53' ("modules: remove uncessary source for external cmsis kconfig"). The warnings were in the form of: "HAS_CMSIS_CORE (defined at modules/cmsis/Kconfig:7) has direct dependencies 0 with value n ..." Signed-off-by: Laurentiu Mihalcea --- modules/Kconfig.mcux | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index 4664b8c0423..fb5b18a63d3 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -5,7 +5,6 @@ config HAS_MCUX bool - select HAS_CMSIS_CORE if !SOC_FAMILY_NXP_ADSP depends on SOC_FAMILY_KINETIS || SOC_FAMILY_IMX || SOC_FAMILY_LPC || \ SOC_FAMILY_NXP_ADSP || SOC_FAMILY_NXP_S32 From 96175fcc476dc0a19a870d7da9e893f9f548e06f Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Tue, 3 Oct 2023 13:49:46 -0600 Subject: [PATCH 1746/4498] sensors: Fix alignment issues Add padding to the header and remove unnecessary memset in order to fix alignment faults in cores such as M0 or ones that support CONFIG_TRAP_UNALIGNED_ACCESS Signed-off-by: Yuval Peress --- drivers/sensor/default_rtio_sensor.c | 27 +++++++++++++++++++++++---- drivers/sensor/icm42688/icm42688.c | 5 ++--- include/zephyr/drivers/sensor.h | 5 ++++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index 60534c84d28..88d3196181a 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -12,6 +12,12 @@ LOG_MODULE_REGISTER(sensor_compat, CONFIG_SENSOR_LOG_LEVEL); +/* + * Ensure that the size of the generic header aligns with the sensor channel enum. If it doesn't, + * then cores that require aligned memory access will fail to read channel[0]. + */ +BUILD_ASSERT((sizeof(struct sensor_data_generic_header) % sizeof(enum sensor_channel)) == 0); + static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); static void sensor_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) @@ -49,6 +55,21 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_ return num_samples; } +/** + * @brief Compute the required header size + * + * This function takes into account alignment of the q31 values that will follow the header. + * + * @param[in] num_output_samples The number of samples to represent + * @return The number of bytes needed for this sample frame's header + */ +static inline uint32_t compute_header_size(int num_output_samples) +{ + uint32_t size = sizeof(struct sensor_data_generic_header) + + (num_output_samples * sizeof(enum sensor_channel)); + return (size + 3) & ~0x3; +} + /** * @brief Compute the minimum number of bytes needed * @@ -57,8 +78,7 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_ */ static inline uint32_t compute_min_buf_len(int num_output_samples) { - return sizeof(struct sensor_data_generic_header) + (num_output_samples * sizeof(q31_t)) + - (num_output_samples * sizeof(enum sensor_channel)); + return compute_header_size(num_output_samples) + (num_output_samples * sizeof(q31_t)); } /** @@ -121,8 +141,7 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s header->num_channels = num_output_samples; header->shift = 0; - q31_t *q = (q31_t *)(buf + sizeof(struct sensor_data_generic_header) + - num_output_samples * sizeof(enum sensor_channel)); + q31_t *q = (q31_t *)(buf + compute_header_size(num_output_samples)); /* Populate values, update shift, and set channels */ for (size_t i = 0, sample_idx = 0; i < cfg->count; ++i) { diff --git a/drivers/sensor/icm42688/icm42688.c b/drivers/sensor/icm42688/icm42688.c index b8ebef4f147..43fd6a72f47 100644 --- a/drivers/sensor/icm42688/icm42688.c +++ b/drivers/sensor/icm42688/icm42688.c @@ -251,12 +251,11 @@ int icm42688_init(const struct device *dev) } #endif - memset(&data->cfg, 0, sizeof(struct icm42688_cfg)); data->cfg.accel_mode = ICM42688_ACCEL_LN; - data->cfg.gyro_mode = ICM42688_GYRO_LN; data->cfg.accel_fs = ICM42688_ACCEL_FS_2G; - data->cfg.gyro_fs = ICM42688_GYRO_FS_125; data->cfg.accel_odr = ICM42688_ACCEL_ODR_1000; + data->cfg.gyro_mode = ICM42688_GYRO_LN; + data->cfg.gyro_fs = ICM42688_GYRO_FS_125; data->cfg.gyro_odr = ICM42688_GYRO_ODR_1000; data->cfg.fifo_en = false; diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 76b65da4880..903acb6f03a 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -801,11 +801,14 @@ struct __attribute__((__packed__)) sensor_data_generic_header { * The number of channels present in the frame. This will be the true number of elements in * channel_info and in the q31 values that follow the header. */ - size_t num_channels; + uint32_t num_channels; /* Shift value for all samples in the frame */ int8_t shift; + /* This padding is needed to make sure that the 'channels' field is aligned */ + int8_t _padding[sizeof(enum sensor_channel) - 1]; + /* Channels present in the frame */ enum sensor_channel channels[0]; }; From df23b0177f20e083ed3bcc94acc045723041b6de Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 6 Oct 2023 11:12:13 +0100 Subject: [PATCH 1747/4498] maintainers: Change regulator maintainer Change regulator maintainer to aasinclair Move gmarull from maintainer to collaborator Signed-off-by: Andy Sinclair --- MAINTAINERS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 78183be61bb..d23cf483890 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1150,10 +1150,10 @@ Release Notes: "Drivers: Regulators": status: maintained maintainers: - - gmarull + - aasinclair collaborators: - danieldegrasse - - aasinclair + - gmarull files: - drivers/regulator/ - include/zephyr/drivers/regulator/ From fefbb28edb36e58011aaa82332a9d94e1b6a7167 Mon Sep 17 00:00:00 2001 From: Fredrik Danebjer Date: Fri, 6 Oct 2023 11:20:14 +0200 Subject: [PATCH 1748/4498] Bluetooth: Audio: Fix return code in PACS notify Fix errenous return value in pacs_gatt_notify function. The function would always return zero, and not forward the error correctly. Signed-off-by: Fredrik Danebjer --- subsys/bluetooth/audio/pacs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/audio/pacs.c b/subsys/bluetooth/audio/pacs.c index f566645d5b5..2ce6db23a9f 100644 --- a/subsys/bluetooth/audio/pacs.c +++ b/subsys/bluetooth/audio/pacs.c @@ -795,11 +795,11 @@ static int pacs_gatt_notify(struct bt_conn *conn, atomic_clear(¬ify_rdy); } - if (err == -ENOTCONN) { - return 0; - } else { - return 0; + if (err && err != -ENOTCONN) { + return err; } + + return 0; } static void notify_cb(struct bt_conn *conn, void *data) From 410c02ac57e2c73f46859e4166ec3b6eb47b8723 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 Oct 2023 13:47:49 +0200 Subject: [PATCH 1749/4498] drivers: can: sja1000: remove excessive debug logging Remove excessive debug logging from the SJA1000 driver backend. Logging each register access makes generic CAN debug logging unusable. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_sja1000.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index 815f9d43488..d7287fa2451 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -23,19 +23,14 @@ static inline void can_sja1000_write_reg(const struct device *dev, uint8_t reg, { const struct can_sja1000_config *config = dev->config; - LOG_DBG("write reg %d = 0x%02x", reg, val); return config->write_reg(dev, reg, val); } static inline uint8_t can_sja1000_read_reg(const struct device *dev, uint8_t reg) { const struct can_sja1000_config *config = dev->config; - uint8_t val; - val = config->read_reg(dev, reg); - LOG_DBG("read reg %d = 0x%02x", reg, val); - - return val; + return config->read_reg(dev, reg); } static inline int can_sja1000_enter_reset_mode(const struct device *dev) From f2af4a7bfd623f7bcdf6b869796f0d96837aaf06 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 6 Oct 2023 12:45:34 +0200 Subject: [PATCH 1750/4498] Bluetooth: host: document the connection states Connection states are non-trivial to understand based on their names only, so add short descriptions in the header file explaining what they do. Signed-off-by: Carles Cufi --- subsys/bluetooth/host/conn_internal.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index bddbf11ae7d..e3fd60da34e 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -12,15 +12,15 @@ #include typedef enum __packed { - BT_CONN_DISCONNECTED, - BT_CONN_DISCONNECT_COMPLETE, - BT_CONN_CONNECTING_SCAN, - BT_CONN_CONNECTING_AUTO, - BT_CONN_CONNECTING_ADV, - BT_CONN_CONNECTING_DIR_ADV, - BT_CONN_CONNECTING, - BT_CONN_CONNECTED, - BT_CONN_DISCONNECTING, + BT_CONN_DISCONNECTED, /* Disconnected, conn is completely down */ + BT_CONN_DISCONNECT_COMPLETE, /* Received disconn comp event, transition to DISCONNECTED */ + BT_CONN_CONNECTING_SCAN, /* Central passive scanning */ + BT_CONN_CONNECTING_AUTO, /* Central connection establishment w/ filter */ + BT_CONN_CONNECTING_ADV, /* Peripheral connectable advertising */ + BT_CONN_CONNECTING_DIR_ADV, /* Peripheral directed advertising */ + BT_CONN_CONNECTING, /* Central connection establishment */ + BT_CONN_CONNECTED, /* Peripheral or Central connected */ + BT_CONN_DISCONNECTING, /* Peripheral or Central issued disconnection command */ } bt_conn_state_t; /* bt_conn flags: the flags defined here represent connection parameters */ From ea61c8c1bd936d6604cb10248f0737d2ff027394 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Oct 2023 10:28:07 -0700 Subject: [PATCH 1751/4498] sys/time_units.h: Work around clang div-by-zero warning clang emits a warning for this code: foo.c:1:25: warning: division by zero is undefined [-Wdivision-by-zero] int i = (10 > 100 ? (20 / (10 / 100)) : (20 * (100 / 10))); ^ ~~~~~~~~~~ The warning is generated for code whose value does not affect the expression result, but technically it is still 'undefined behavior'. Work around this warning by checking for a zero divisor and substituting one to make the compiler happy. Signed-off-by: Keith Packard --- include/zephyr/sys/time_units.h | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/include/zephyr/sys/time_units.h b/include/zephyr/sys/time_units.h index 318ffd3d0ce..c7469e6c548 100644 --- a/include/zephyr/sys/time_units.h +++ b/include/zephyr/sys/time_units.h @@ -138,6 +138,16 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) (__round_up) ? ((__from_hz) / (__to_hz)) - 1 : \ 0) +/* Clang emits a divide-by-zero warning even though the int_div macro + * results are only used when the divisor will not be zero. Work + * around this by substituting 1 to make the compiler happy. + */ +#ifdef __clang__ +#define z_tmcvt_divisor(a, b) ((a) / (b) ?: 1) +#else +#define z_tmcvt_divisor(a, b) ((a) / (b)) +#endif + /* * Compute the offset needed to round the result correctly when * the conversion requires a full mul/div @@ -154,12 +164,12 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) ((uint32_t)((__t) + \ z_tmcvt_off_div(__from_hz, __to_hz, \ __round_up, __round_off)) / \ - ((__from_hz) / (__to_hz))) \ + z_tmcvt_divisor(__from_hz, __to_hz)) \ : \ (uint32_t) (((uint64_t) (__t) + \ z_tmcvt_off_div(__from_hz, __to_hz, \ __round_up, __round_off)) / \ - ((__from_hz) / (__to_hz))) \ + z_tmcvt_divisor(__from_hz, __to_hz)) \ ) /* Integer multiplication 32-bit conversion */ @@ -173,9 +183,9 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) /* Integer division 64-bit conversion */ #define z_tmcvt_int_div_64(__t, __from_hz, __to_hz, __round_up, __round_off) \ - ((uint64_t) (__t) + z_tmcvt_off_div(__from_hz, __to_hz, \ - __round_up, __round_off)) / \ - ((__from_hz) / (__to_hz)) + (((uint64_t) (__t) + z_tmcvt_off_div(__from_hz, __to_hz, \ + __round_up, __round_off)) / \ + z_tmcvt_divisor(__from_hz, __to_hz)) /* Integer multiplcation 64-bit conversion */ #define z_tmcvt_int_mul_64(__t, __from_hz, __to_hz) \ From d8b276e929c73690462ca05068330748093bfff0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Oct 2023 13:33:42 -0700 Subject: [PATCH 1752/4498] sys/time_units.h: Make sys_clock_hw_cycles_per_sec() constant if possible To be used in a global initializer, this must be a macro instead of a static inline when the return value is constant. Signed-off-by: Keith Packard --- include/zephyr/sys/time_units.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/zephyr/sys/time_units.h b/include/zephyr/sys/time_units.h index c7469e6c548..7f2db1a1f55 100644 --- a/include/zephyr/sys/time_units.h +++ b/include/zephyr/sys/time_units.h @@ -70,14 +70,11 @@ static inline int z_impl_sys_clock_hw_cycles_per_sec_runtime_get(void) * @brief Get the system timer frequency. * @return system timer frequency in Hz */ -static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void) -{ #if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME) - return sys_clock_hw_cycles_per_sec_runtime_get(); +#define sys_clock_hw_cycles_per_sec() sys_clock_hw_cycles_per_sec_runtime_get() #else - return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; +#define sys_clock_hw_cycles_per_sec() CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC #endif -} /** @internal * Macro determines if fast conversion algorithm can be used. It checks if From 1b057d6295cba9ef73048185ace4b5d8e4ee2101 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Oct 2023 13:35:04 -0700 Subject: [PATCH 1753/4498] tests/timer_api: Make sure constant time conversions are constants When the timer frequency is known at compile time, make sure we can use any time conversion macro as a global initializer. Signed-off-by: Keith Packard --- tests/kernel/timer/timer_api/src/timer_convert.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/kernel/timer/timer_api/src/timer_convert.c b/tests/kernel/timer/timer_api/src/timer_convert.c index f29af361cee..19b96419d1b 100644 --- a/tests/kernel/timer/timer_api/src/timer_convert.c +++ b/tests/kernel/timer/timer_api/src/timer_convert.c @@ -33,7 +33,16 @@ struct test_rec { (void *)test_##src##_to_##dst##_##round##prec \ } \ +#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME +#define TESTVAR(src, dst, round, prec) +#else +#define TESTVAR(src, dst, round, prec) \ + uint##prec##_t test_##src##_to_##dst##_##round##prec##_val = \ + k_##src##_to_##dst##_##round##prec(42); +#endif + #define TESTFUNC(src, dst, round, prec) \ + TESTVAR(src, dst, round, prec) \ static uint##prec##_t test_##src##_to_##dst##_##round##prec(uint##prec##_t t) { \ return k_##src##_to_##dst##_##round##prec(t); \ } From c1b1dd78e2a83285f6cf5780fa1fcf4089e0367b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Oct 2023 20:06:12 +0300 Subject: [PATCH 1754/4498] release: Zephyr v3.5.0-rc2 Bump the version to v3.5.0-rc2. Signed-off-by: Johan Hedberg --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 091da5fcbd2..71917906205 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ VERSION_MAJOR = 3 VERSION_MINOR = 5 PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = rc1 +EXTRAVERSION = rc2 From ee588bae7a6106721328bd7a3d3cd7c856e2c7ec Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Fri, 6 Oct 2023 12:42:30 -0500 Subject: [PATCH 1755/4498] llext: Update the sample readme with a board The commands showing west build had -b None which isn't quite right. Add a :board: property with the tdk_robokit1 as its what I tested on myself. Also noted that llext isn't supported on every architecture but intentionally left this a bit vague as updating this little comment every time something is added seems like a recipe for doc rot. Signed-off-by: Tom Burdick --- samples/subsys/llext/shell_loader/README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/subsys/llext/shell_loader/README.rst b/samples/subsys/llext/shell_loader/README.rst index d24ff89478f..7d0d70151c3 100644 --- a/samples/subsys/llext/shell_loader/README.rst +++ b/samples/subsys/llext/shell_loader/README.rst @@ -13,13 +13,14 @@ ability to manage loadable code extensions in the shell. Requirements ************ -A board with shell capable console. +A board with a supported llext architecture and shell capable console. Building ******** .. zephyr-app-commands:: :zephyr-app: samples/subsys/llext/shell_loader + :board: tdk_robokit1 :goals: build :compact: From 4ebc963ed5dfa8d2049abad1f6d437f4e0acc448 Mon Sep 17 00:00:00 2001 From: Thomas Chiantia Date: Tue, 3 Oct 2023 18:34:38 -0400 Subject: [PATCH 1756/4498] drivers: eth: gmac: Fixed ethernet startup when fixed-link When upgrading to version 3.4, our hardware lost ethernet connectivity. Our hardware assumes a fixed link and does not communicate with the underlying phy via the mdio bus. I confirmed that the atsame54_xpro board also will lose ethernet functionality when the atsame54_xpro configures the phy via to use a fixed link... The eth_sam_gmac driver changed the initialization behavior to call net_if_carrier_off and notes to wait until phy link is up (via callback.) However, when in a fixed link configuration, the callback is never called. So the net_if_carrier_on event never occurs. This patch adds a check to see if link is up already before calling net_if_carrior_off. This check works because in fixed-link mode, link-up is set synchronously during phy driver initialization. I tested that atsame54_xpro with fixed-link configuration will now work after this patch. Signed-off-by: Thomas Chiantia --- drivers/ethernet/eth_sam_gmac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_sam_gmac.c b/drivers/ethernet/eth_sam_gmac.c index 9cd9daa6908..dec6ea6df20 100644 --- a/drivers/ethernet/eth_sam_gmac.c +++ b/drivers/ethernet/eth_sam_gmac.c @@ -1973,7 +1973,9 @@ static void eth0_iface_init(struct net_if *iface) } /* Do not start the interface until PHY link is up */ - net_if_carrier_off(iface); + if (!(dev_data->link_up)) { + net_if_carrier_off(iface); + } init_done = true; } From 22a086216a9feda88d7cf21cecad198bab17d73e Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Fri, 6 Oct 2023 15:01:01 +0300 Subject: [PATCH 1757/4498] dts: bindings: adxl372-i2c: update description Specify only the bus corresponding to the current yaml file, as done in the adi,adxl372-spi.yaml. Signed-off-by: Antoniu Miclaus --- dts/bindings/sensor/adi,adxl372-i2c.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/bindings/sensor/adi,adxl372-i2c.yaml b/dts/bindings/sensor/adi,adxl372-i2c.yaml index 2da0abcac77..f6f0ac197ed 100644 --- a/dts/bindings/sensor/adi,adxl372-i2c.yaml +++ b/dts/bindings/sensor/adi,adxl372-i2c.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2018 Analog Devices Inc. # SPDX-License-Identifier: Apache-2.0 -description: ADXL372 3-axis high-g I2C/SPI accelerometer +description: ADXL372 3-axis high-g accelerometer, accessed through I2C bus compatible: "adi,adxl372" From 7a9600816a5023ff21ee593c12fb1aef8af60d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Thu, 28 Sep 2023 18:54:37 +0200 Subject: [PATCH 1758/4498] tests: posix: Enable pthread_pressure test on SPARC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This sets the stack size appropriate for SPARC. Tested on the board configurations qemu_leon3 and gr716a_mini. Signed-off-by: Martin Åberg --- tests/posix/pthread_pressure/Kconfig | 1 + tests/posix/pthread_pressure/testcase.yaml | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/posix/pthread_pressure/Kconfig b/tests/posix/pthread_pressure/Kconfig index e861f0a5be7..2bbdfcc2110 100644 --- a/tests/posix/pthread_pressure/Kconfig +++ b/tests/posix/pthread_pressure/Kconfig @@ -27,6 +27,7 @@ config TEST_DELAY_US config TEST_STACK_SIZE int "Size of each thread stack in this test" default 1024 if 64BIT + default 1024 if SPARC default 512 help The minimal stack size required to run a minimal thread. diff --git a/tests/posix/pthread_pressure/testcase.yaml b/tests/posix/pthread_pressure/testcase.yaml index 273757f73ab..73a8fa34e23 100644 --- a/tests/posix/pthread_pressure/testcase.yaml +++ b/tests/posix/pthread_pressure/testcase.yaml @@ -5,8 +5,6 @@ common: - posix integration_platforms: - qemu_riscv64_smp - platform_exclude: - - qemu_leon3 tests: portability.posix.pthread_pressure: extra_configs: From faf55932720a18afbbb81f20cc82a732eb312b5f Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 3 Oct 2023 21:49:35 +0000 Subject: [PATCH 1759/4498] soc: arm: nxp_lpc: Only clock core from PLL1 when CONFIG_FLASH=n Do not clock the LPC55xxx cores from PLL1 when CONFIG_FLASH is set. This is required due to the following limitation of the flash controller (documented in the reference manual): Flash operations (erase, blank check, program) and reading a single word can only be performed for CPU frequencies of up to 100 MHz. These operations cannot be performed for frequencies above 100 MHz. The PLL1 clock source will result in a core clock of 150MHz, which violates this requirement. Fixes #62963 Signed-off-by: Daniel DeGrasse --- soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index a7bae5aafb0..a1531b8ede4 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -123,10 +123,12 @@ config INIT_PLL0 config INIT_PLL1 bool "Initialize PLL1" default "y" - depends on !SOC_LPC55S06 + depends on !(SOC_LPC55S06 || FLASH) help In the LPC55XXX Family, this is currently being used to set the core clock value at it's highest frequency which clocks at 150MHz. + Note that flash programming operations are limited to 100MHz, and + this PLL should not be used as the core clock in those cases. config SECOND_CORE_MCUX bool "LPC55xxx's second core" From b12813468a77201eaa3b08d9de6a5e4a86b2e8a5 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 5 Oct 2023 18:09:58 -0500 Subject: [PATCH 1760/4498] boards: arm: lpcxpresso: update core clock documentation Update documentation for core clock frequency on LPC55xxx boards, to indicate that they are clocked from PLL1 at 150MHz by default. Add a note about the reduction to 96MHz required when using the flash controller. Signed-off-by: Daniel DeGrasse --- boards/arm/lpcxpresso55s16/doc/index.rst | 8 +++++--- boards/arm/lpcxpresso55s28/doc/index.rst | 8 +++++--- boards/arm/lpcxpresso55s69/doc/index.rst | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/boards/arm/lpcxpresso55s16/doc/index.rst b/boards/arm/lpcxpresso55s16/doc/index.rst index fa6971c988a..abb9170543e 100644 --- a/boards/arm/lpcxpresso55s16/doc/index.rst +++ b/boards/arm/lpcxpresso55s16/doc/index.rst @@ -138,9 +138,11 @@ the functionality of a pin. System Clock ============ -The LPC55S16 SoC is configured to use the internal FRO at 96MHz as a -source for the system clock. Other sources for the system clock are -provided in the SOC, depending on your system requirements. +The LPC55S16 SoC is configured to use PLL1 clocked from the external 24MHz +crystal, running at 150MHz as a source for the system clock. When the flash +controller is enabled, the core clock will be reduced to 96MHz. The application +may reconfigure clocks after initialization, provided that the core clock is +always set to 96MHz when flash programming operations are performed. Serial Port =========== diff --git a/boards/arm/lpcxpresso55s28/doc/index.rst b/boards/arm/lpcxpresso55s28/doc/index.rst index b55bddb6291..e624a115136 100644 --- a/boards/arm/lpcxpresso55s28/doc/index.rst +++ b/boards/arm/lpcxpresso55s28/doc/index.rst @@ -125,9 +125,11 @@ the functionality of a pin. System Clock ============ -The LPC55S28 SoC is configured to use the internal FRO at 96MHz as a -source for the system clock. Other sources for the system clock are -provided in the SOC, depending on your system requirements. +The LPC55S28 SoC is configured to use PLL1 clocked from the external 24MHz +crystal, running at 150MHz as a source for the system clock. When the flash +controller is enabled, the core clock will be reduced to 96MHz. The application +may reconfigure clocks after initialization, provided that the core clock is +always set to 96MHz when flash programming operations are performed. Serial Port =========== diff --git a/boards/arm/lpcxpresso55s69/doc/index.rst b/boards/arm/lpcxpresso55s69/doc/index.rst index 1bd0ccfbae5..d6ec337ae9e 100644 --- a/boards/arm/lpcxpresso55s69/doc/index.rst +++ b/boards/arm/lpcxpresso55s69/doc/index.rst @@ -256,9 +256,11 @@ Dual Core samples System Clock ============ -The LPC55S69 SoC is configured to use the internal FRO at 96MHz as a source for -the system clock. Other sources for the system clock are provided in the SOC, -depending on your system requirements. +The LPC55S69 SoC is configured to use PLL1 clocked from the external 24MHz +crystal, running at 150MHz as a source for the system clock. When the flash +controller is enabled, the core clock will be reduced to 96MHz. The application +may reconfigure clocks after initialization, provided that the core clock is +always set to 96MHz when flash programming operations are performed. Serial Port =========== From a6adaedd51ffe1b658304da798892bce0a67382b Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 4 Oct 2023 19:43:18 +0000 Subject: [PATCH 1761/4498] drivers: i2s: mcux_sai: fix PCM data format and respect CLK format This commit fixes the following issues with the PCM data format output by the MCUX SAI driver: - WS signal should be only one clock cycle in length for short PCM format - Word count should not be fixed to 2, except for classic I2S format - BCLK polarity should be on falling edge for PCM long and short format Additionally, the I2S_FMT_CLK_ constants now flip the frame and bit clock polarity from the normal value expected for the selected I2S format, as expected by the API. Fixes #63041 Signed-off-by: Daniel DeGrasse --- drivers/i2s/i2s_mcux_sai.c | 41 ++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index 3e4f6f19f84..5294127f759 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -577,11 +577,18 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, SAI_GetDSPConfig(&config, kSAI_FrameSyncLenOneBitClk, word_size_bits, kSAI_Stereo, dev_cfg->tx_channel); + /* We need to set the data word count manually, since the HAL + * function does not + */ + config.serialData.dataWordNum = num_words; + config.frameSync.frameSyncEarly = true; + config.bitClock.bclkPolarity = kSAI_SampleOnFallingEdge; break; case I2S_FMT_DATA_FORMAT_PCM_LONG: SAI_GetTDMConfig(&config, kSAI_FrameSyncLenPerWordWidth, word_size_bits, num_words, dev_cfg->tx_channel); + config.bitClock.bclkPolarity = kSAI_SampleOnFallingEdge; break; default: LOG_ERR("Unsupported I2S data format"); @@ -629,31 +636,43 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, /* clock signal polarity */ switch (i2s_cfg->format & I2S_FMT_CLK_FORMAT_MASK) { case I2S_FMT_CLK_NF_NB: - config.frameSync.frameSyncPolarity = - kSAI_PolarityActiveLow; - config.bitClock.bclkSrcSwap = false; + /* No action required, leave the configuration untouched */ break; case I2S_FMT_CLK_NF_IB: - config.frameSync.frameSyncPolarity = - kSAI_PolarityActiveLow; - config.bitClock.bclkSrcSwap = true; + /* Swap bclk polarity */ + config.bitClock.bclkPolarity = + (config.bitClock.bclkPolarity == kSAI_SampleOnFallingEdge) ? + kSAI_SampleOnRisingEdge : + kSAI_SampleOnFallingEdge; break; case I2S_FMT_CLK_IF_NB: + /* Swap frame sync polarity */ config.frameSync.frameSyncPolarity = - kSAI_PolarityActiveHigh; - config.bitClock.bclkSrcSwap = false; + (config.frameSync.frameSyncPolarity == kSAI_PolarityActiveHigh) ? + kSAI_PolarityActiveLow : + kSAI_PolarityActiveHigh; break; case I2S_FMT_CLK_IF_IB: + /* Swap frame sync and bclk polarity */ config.frameSync.frameSyncPolarity = - kSAI_PolarityActiveHigh; - config.bitClock.bclkSrcSwap = true; + (config.frameSync.frameSyncPolarity == kSAI_PolarityActiveHigh) ? + kSAI_PolarityActiveLow : + kSAI_PolarityActiveHigh; + config.bitClock.bclkPolarity = + (config.bitClock.bclkPolarity == kSAI_SampleOnFallingEdge) ? + kSAI_SampleOnRisingEdge : + kSAI_SampleOnFallingEdge; break; } - config.frameSync.frameSyncWidth = (uint8_t)word_size_bits; + /* PCM short format always requires that WS be one BCLK cycle */ + if ((i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK) != + I2S_FMT_DATA_FORMAT_PCM_SHORT) { + config.frameSync.frameSyncWidth = (uint8_t)word_size_bits; + } if (dir == I2S_DIR_TX) { memcpy(&dev_data->tx.cfg, i2s_cfg, sizeof(struct i2s_config)); From b122685eff5b4f22a88359402a8b07b36c381d0c Mon Sep 17 00:00:00 2001 From: Dennis Grijalva Date: Fri, 6 Oct 2023 13:32:29 -0700 Subject: [PATCH 1762/4498] bluetooth: conn: Fix compiler warning When compiling conn.c using arm-none-eabi-gcc version 11.3.1 20220712 with the -Wmaybe-uninitialized flag a warning is emitted due to pending_no_cb not being initialized. I'm not sure if initializing it to NULL is the "correct" fix, but it's certainly not any worse then it being uninitialized, and it fixes the warning. Signed-off-by: Dennis Grijalva --- subsys/bluetooth/host/conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index cc0e8bc6b33..1fd2f5fbc49 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -579,7 +579,7 @@ static inline uint16_t conn_mtu(struct bt_conn *conn) static int do_send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags) { struct bt_conn_tx *tx = tx_data(buf)->tx; - uint32_t *pending_no_cb; + uint32_t *pending_no_cb = NULL; unsigned int key; int err = 0; From 06f35916e1259d9191943b4ac615f87f28b39f7a Mon Sep 17 00:00:00 2001 From: Kai Meinhard Date: Wed, 4 Oct 2023 11:56:29 +0200 Subject: [PATCH 1763/4498] i2c: silabs: Fix I2C target crash on long ISR execution Long I2C target callback functions could lead to an unresponsive I2C peripheral. This commit ports the official ISR implementation from Silicon labs to Zephyr: https://github.com/SiliconLabs/peripheral_examples/blob/master/series2/i2c/i2c_follower/src/main.c Signed-off-by: Kai Meinhard --- drivers/i2c/i2c_gecko.c | 89 ++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/drivers/i2c/i2c_gecko.c b/drivers/i2c/i2c_gecko.c index edeef470434..0c537add17a 100644 --- a/drivers/i2c/i2c_gecko.c +++ b/drivers/i2c/i2c_gecko.c @@ -45,7 +45,6 @@ struct i2c_gecko_data { uint32_t dev_config; #if defined(CONFIG_I2C_TARGET) struct i2c_target_config *target_cfg; - volatile bool target_read; #endif }; @@ -81,9 +80,6 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw struct i2c_gecko_data *data = dev->data; I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT; uint32_t baudrate; -#if defined(CONFIG_I2C_TARGET) - const struct i2c_gecko_config *config = dev->config; -#endif if (!(I2C_MODE_CONTROLLER & dev_config_raw)) { return -EINVAL; @@ -108,7 +104,6 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw #if defined(CONFIG_I2C_TARGET) i2cInit.master = 0; - BUS_RegBitWrite(&(config->base->CTRL), _I2C_CTRL_AUTOACK_SHIFT, 1); #endif I2C_Init(base, &i2cInit); @@ -212,7 +207,8 @@ static int i2c_gecko_target_register(const struct device *dev, struct i2c_target I2C_SlaveAddressMaskSet(config->base, _I2C_SADDRMASK_SADDRMASK_MASK); I2C_IntDisable(config->base, _I2C_IEN_MASK); - I2C_IntEnable(config->base, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP); + I2C_IntEnable(config->base, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_ACK | I2C_IEN_SSTOP | + I2C_IEN_BUSERR | I2C_IEN_ARBLOST); config->irq_config_func(dev); @@ -242,57 +238,60 @@ static const struct i2c_driver_api i2c_gecko_driver_api = { }; #if defined(CONFIG_I2C_TARGET) -static void i2c_gecko_isr(const struct device *dev) +void i2c_gecko_isr(const struct device *dev) { const struct i2c_gecko_config *config = dev->config; struct i2c_gecko_data *data = dev->data; - uint32_t status; - uint32_t rx_data; - uint8_t tx_byte; - status = config->base->IF; + uint32_t pending; + uint32_t rx_byte; + uint8_t tx_byte; - if (status & I2C_IF_ADDR && status & I2C_IF_RXDATAV) { - /* Address Match */ - rx_data = config->base->RXDATA; - if (rx_data & 0x1) { - data->target_read = true; + pending = config->base->IF; + + /* If some sort of fault, abort transfer. */ + if (pending & (I2C_IF_BUSERR | I2C_IF_ARBLOST)) { + LOG_ERR("I2C Bus Error"); + I2C_IntClear(config->base, I2C_IF_BUSERR); + I2C_IntClear(config->base, I2C_IF_ARBLOST); + } else { + if (pending & I2C_IF_ADDR) { + /* Address Match, indicating that reception is started */ + rx_byte = config->base->RXDATA; + config->base->CMD = I2C_CMD_ACK; + + /* Check if read bit set */ + if (rx_byte & 0x1) { + data->target_cfg->callbacks->read_requested(data->target_cfg, + &tx_byte); + config->base->TXDATA = tx_byte; + } else { + data->target_cfg->callbacks->write_requested(data->target_cfg); + } - data->target_cfg->callbacks->read_requested(data->target_cfg, &tx_byte); - config->base->TXDATA = tx_byte; + I2C_IntClear(config->base, I2C_IF_ADDR | I2C_IF_RXDATAV); + } else if (pending & I2C_IF_RXDATAV) { + rx_byte = config->base->RXDATA; + /* Read new data and write to target address */ + data->target_cfg->callbacks->write_received(data->target_cfg, rx_byte); + config->base->CMD = I2C_CMD_ACK; - I2C_IntEnable(config->base, I2C_IEN_BUSHOLD); - } else { - data->target_read = false; - data->target_cfg->callbacks->write_requested(data->target_cfg); - } - I2C_IntClear(config->base, I2C_IF_ADDR); - I2C_IntClear(config->base, I2C_IF_RXDATAV); - } else if (status & I2C_IF_RXDATAV) { - if (data->target_read == true) { - LOG_ERR("Unexpected Data"); - } else { - rx_data = config->base->RXDATA; - data->target_cfg->callbacks->write_received(data->target_cfg, rx_data); + I2C_IntClear(config->base, I2C_IF_RXDATAV); } - I2C_IntClear(config->base, I2C_IF_RXDATAV); - } else if (data->target_read && status & I2C_IF_BUSHOLD && !(status & I2C_IF_SSTOP)) { - data->target_cfg->callbacks->read_processed(data->target_cfg, &tx_byte); - config->base->TXDATA = tx_byte; - I2C_IntClear(config->base, I2C_IF_BUSHOLD); - } + if (pending & I2C_IF_ACK) { + /* Leader ACK'ed, so requesting more data */ + data->target_cfg->callbacks->read_processed(data->target_cfg, &tx_byte); + config->base->TXDATA = tx_byte; - if (status & I2C_IF_SSTOP) { - if (config->base->STATUS & I2C_STATUS_RXDATAV) { - LOG_ERR("Still valid data"); + I2C_IntClear(config->base, I2C_IF_ACK); } - /* Stop received, reception is ended */ - data->target_cfg->callbacks->stop(data->target_cfg); - I2C_IntClear(config->base, I2C_IF_SSTOP); - I2C_IntClear(config->base, I2C_IF_BUSHOLD); - I2C_IntDisable(config->base, I2C_IEN_BUSHOLD); + if (pending & I2C_IF_SSTOP) { + /* End of transaction */ + data->target_cfg->callbacks->stop(data->target_cfg); + I2C_IntClear(config->base, I2C_IF_SSTOP); + } } } #endif From 77dc74136cf7c64c651b7edf5748d02c584c6c91 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 3 Oct 2023 14:46:23 -0700 Subject: [PATCH 1764/4498] kernel: tls: fix doc on arch_tls_stack_setup() There was a typo there so fix it. Signed-off-by: Daniel Leung --- kernel/include/kernel_arch_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index 16cfda41f54..09572bbe148 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -597,7 +597,7 @@ uint16_t arch_coredump_tgt_code_get(void); * @brief Setup Architecture-specific TLS area in stack * * This sets up the stack area for thread local storage. - * The structure inside in area is architecture specific. + * The structure inside TLS area is architecture specific. * * @param new_thread New thread object * @param stack_ptr Stack pointer From dd6a7eb77d4474bfaa9e72c544b5d39994f65a7e Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 3 Oct 2023 14:54:39 -0700 Subject: [PATCH 1765/4498] kernel: demand_paging: add doc to enum arch_page_location This adds doc to enum arch_page_location. Signed-off-by: Daniel Leung --- kernel/include/kernel_arch_interface.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index 09572bbe148..d1cd87df859 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -402,9 +402,17 @@ void arch_mem_page_in(void *addr, uintptr_t phys); */ void arch_mem_scratch(uintptr_t phys); +/** + * Status of a particular page location. + */ enum arch_page_location { + /** The page has been evicted to the backing store. */ ARCH_PAGE_LOCATION_PAGED_OUT, + + /** The page is resident in memory. */ ARCH_PAGE_LOCATION_PAGED_IN, + + /** The page is not mapped. */ ARCH_PAGE_LOCATION_BAD }; From edfbc2d7dc5b1a77fdd20ff186f98719eba28864 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 3 Oct 2023 15:05:21 -0700 Subject: [PATCH 1766/4498] kernel: userspace: fix and clean up doxygen This fixes and cleans up the doxygen doc for architecture specific userspace APIs. Signed-off-by: Daniel Leung --- include/zephyr/sys/arch_interface.h | 38 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index 0e6d43fdf25..e350b1436c1 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -530,7 +530,7 @@ static inline unsigned int arch_num_cpus(void); * should be enabled when invoking the system call marshallers from the * dispatch table. Thread preemption may occur when handling system calls. * - * Call ids are untrusted and must be bounds-checked, as the value is used to + * Call IDs are untrusted and must be bounds-checked, as the value is used to * index the system call dispatch table, containing function pointers to the * specific system call code. * @@ -641,7 +641,7 @@ static inline uintptr_t arch_syscall_invoke6(uintptr_t arg1, uintptr_t arg2, /** * Indicate whether we are currently running in user mode * - * @return true if the CPU is currently running with user permissions + * @return True if the CPU is currently running with user permissions */ static inline bool arch_is_user_context(void); @@ -768,11 +768,11 @@ int arch_mem_domain_partition_add(struct k_mem_domain *domain, * if the supplied memory buffer spans multiple enabled memory management * regions (even if all such regions permit user access). * - * @warning 0 size buffer has undefined behavior. + * @warning Buffer of size zero (0) has undefined behavior. * * @param addr start address of the buffer * @param size the size of the buffer - * @param write If nonzero, additionally check if the area is writable. + * @param write If non-zero, additionally check if the area is writable. * Otherwise, just check if the memory can be read. * * @return nonzero if the permissions don't match. @@ -787,10 +787,12 @@ int arch_buffer_validate(void *addr, size_t size, int write); * This call returns the optimal virtual address alignment in order to permit * such optimization in the following MMU mapping call. * - * @param[in] phys Physical address of region to be mapped, aligned to MMU_PAGE_SIZE - * @param[in] size Size of region to be mapped, aligned to MMU_PAGE_SIZE + * @param[in] phys Physical address of region to be mapped, + * aligned to @kconfig{CONFIG_MMU_PAGE_SIZE} + * @param[in] size Size of region to be mapped, + * aligned to @kconfig{CONFIG_MMU_PAGE_SIZE} * - * @retval alignment to apply on the virtual address of this region + * @return Alignment to apply on the virtual address of this region */ size_t arch_virt_region_align(uintptr_t phys, size_t size); @@ -834,9 +836,9 @@ FUNC_NORETURN void arch_syscall_oops(void *ssf); /** * @brief Safely take the length of a potentially bad string * - * This must not fault, instead the err parameter must have -1 written to it. + * This must not fault, instead the @p err parameter must have -1 written to it. * This function otherwise should work exactly like libc strnlen(). On success - * *err should be set to 0. + * @p err should be set to 0. * * @param s String to measure * @param maxsize Max length of the string @@ -898,15 +900,15 @@ static inline bool arch_mem_coherent(void *ptr) * is not sufficient on many architectures and coordination with the * arch_switch() implementation is likely required. * - * @arg old_thread The old thread to be flushed before being allowed - * to run on other CPUs. - * @arg old_switch_handle The switch handle to be stored into - * old_thread (it will not be valid until the - * cache is flushed so is not present yet). - * This will be NULL if inside z_swap() - * (because the arch_switch() has not saved it - * yet). - * @arg new_thread The new thread to be invalidated before it runs locally. + * @param old_thread The old thread to be flushed before being allowed + * to run on other CPUs. + * @param old_switch_handle The switch handle to be stored into + * old_thread (it will not be valid until the + * cache is flushed so is not present yet). + * This will be NULL if inside z_swap() + * (because the arch_switch() has not saved it + * yet). + * @param new_thread The new thread to be invalidated before it runs locally. */ #ifndef CONFIG_KERNEL_COHERENCE static inline void arch_cohere_stacks(struct k_thread *old_thread, From 2c2d53c7e56ab194ffb514bc3f3726d495efc5f2 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 3 Oct 2023 15:10:37 -0700 Subject: [PATCH 1767/4498] kernel: remove deprecate wording on arch_kernel_init() The wording on deprecating arch_kernel_init() in favor of prep_c() has never been materialized. Various architectures are using it to perform initialization. So remove the wording. Signed-off-by: Daniel Leung --- kernel/include/kernel_arch_interface.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index d1cd87df859..0173a4ae398 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -562,9 +562,6 @@ int arch_printk_char_out(int c); * * This function is invoked near the top of _Cstart, for additional * architecture-specific setup before the rest of the kernel is brought up. - * - * TODO: Deprecate, most arches are using a prep_c() function to do the same - * thing in a simpler way */ static inline void arch_kernel_init(void); From c91a572b0e18f7927057382cd02ee53b88e37184 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 5 Oct 2023 14:30:21 -0700 Subject: [PATCH 1768/4498] i3c: some doxygen API doc polishing This polishes the doxygen doc on I3C API to make it, hopefully, more usable. Fixed some typos too. Signed-off-by: Daniel Leung --- include/zephyr/drivers/i3c.h | 177 +++++++++++++++- include/zephyr/drivers/i3c/addresses.h | 16 ++ include/zephyr/drivers/i3c/ccc.h | 231 ++++++++++++++++++++- include/zephyr/drivers/i3c/ibi.h | 7 +- include/zephyr/drivers/i3c/target_device.h | 4 +- 5 files changed, 420 insertions(+), 15 deletions(-) diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index 58a85d35566..36a93fc01de 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -27,8 +27,9 @@ extern "C" { #endif -/* - * Bus Characteristic Register (BCR) +/** + * @name Bus Characteristic Register (BCR) + * * - BCR[7:6]: Device Role * - 0: I3C Target * - 1: I3C Controller capable @@ -55,24 +56,82 @@ extern "C" { * - BCR[0]: Max Data Speed Limitation * - 0: No Limitation * - 1: Limitation obtained via GETMXDS CCC. + * + * @{ + */ + +/** + * @brief Max Data Speed Limitation bit. + * + * 0 - No Limitation. + * 1 - Limitation obtained via GETMXDS CCC. */ #define I3C_BCR_MAX_DATA_SPEED_LIMIT BIT(0) + +/** @brief IBI Request Capable bit. */ #define I3C_BCR_IBI_REQUEST_CAPABLE BIT(1) + +/** + * @brief IBI Payload bit. + * + * 0 - No data bytes following the accepted IBI. + * 1 - One data byte (MDB, Mandatory Data Byte) follows the accepted IBI. + * Additional data bytes may also follows. + */ #define I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE BIT(2) + +/** + * @brief Offline Capable bit. + * + * 0 - Will always respond to I3C commands. + * 1 - Will not always respond to I3C commands. + */ #define I3C_BCR_OFFLINE_CAPABLE BIT(3) + +/** + * @brief Virtual Target Support bit. + * + * 0 - Is not a virtual target. + * 1 - Is a virtual target. + */ #define I3C_BCR_VIRTUAL_TARGET BIT(4) + +/** + * @brief Advanced Capabilities bit. + * + * 0 - Does not support optional advanced capabilities. + * 1 - Supports optional advanced capabilities which can be viewed via + * GETCAPS CCC. + */ #define I3C_BCR_ADV_CAPABILITIES BIT(5) +/** Device Role - I3C Target. */ #define I3C_BCR_DEVICE_ROLE_I3C_TARGET 0U + +/** Device Role - I3C Controller Capable. */ #define I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE 1U +/** Device Role bit shift value. */ #define I3C_BCR_DEVICE_ROLE_SHIFT 6U + +/** Device Role bit shift mask. */ #define I3C_BCR_DEVICE_ROLE_MASK (0x03U << I3C_BCR_DEVICE_ROLE_SHIFT) +/** + * @brief Device Role + * + * Obtain Device Role value from the BCR value obtained via GETBCR. + * + * @param bcr BCR value + */ #define I3C_BCR_DEVICE_ROLE(bcr) \ (((bcr) & I3C_BCR_DEVICE_ROLE_MASK) >> I3C_BCR_DEVICE_ROLE_SHIFT) -/* +/** @} */ + +/** + * @name Device Characteristic Register (DCR) + * * Legacy Virtual Register (LVR) * - LVR[7:5]: I2C device index: * - 0: I2C device has a 50 ns spike filter where @@ -85,26 +144,74 @@ extern "C" { * - 0: FM+ mode * - 1: FM mode * - LVR[3:0]: Reserved. + * + * @{ */ + +/** I2C FM+ Mode. */ #define I3C_DCR_I2C_FM_PLUS_MODE 0 + +/** I2C FM Mode. */ #define I3C_DCR_I2C_FM_MODE 1 +/** I2C Mode Indicator bit shift value. */ #define I3C_DCR_I2C_MODE_SHIFT 4 + +/** I2C Mode Indicator bitmask. */ #define I3C_DCR_I2C_MODE_MASK BIT(4) +/** + * @brief I2C Mode + * + * Obtain I2C Mode value from the DCR value obtained via GETDCR. + * + * @param dcr DCR value + */ #define I3C_DCR_I2C_MODE(dcr) \ (((mode) & I3C_DCR_I2C_MODE_MASK) >> I3C_DCR_I2C_MODE_SHIFT) +/** + * @brief I2C Device Index 0. + * + * I2C device has a 50 ns spike filter where it is not affected by high + * frequency on SCL. + */ #define I3C_DCR_I2C_DEV_IDX_0 0 + +/** + * @brief I2C Device Index 1. + * + * I2C device does not have a 50 ns spike filter but can work with high + * frequency on SCL. + */ #define I3C_DCR_I2C_DEV_IDX_1 1 + +/** + * @brief I2C Device Index 2. + * + * I2C device does not have a 50 ns spike filter and cannot work with high + * frequency on SCL. + */ #define I3C_DCR_I2C_DEV_IDX_2 2 +/** I2C Device Index bit shift value. */ #define I3C_DCR_I2C_DEV_IDX_SHIFT 5 + +/** I2C Device Index bitmask. */ #define I3C_DCR_I2C_DEV_IDX_MASK (0x07U << I3C_DCR_I2C_DEV_IDX_SHIFT) +/** + * @brief I2C Device Index + * + * Obtain I2C Device Index value from the DCR value obtained via GETDCR. + * + * @param dcr DCR value + */ #define I3C_DCR_I2C_DEV_IDX(dcr) \ (((dcr) & I3C_DCR_I2C_DEV_IDX_MASK) >> I3C_DCR_I2C_DEV_IDX_SHIFT) +/** @} */ + /** * @brief I3C bus mode */ @@ -258,6 +365,12 @@ enum i3c_sdr_target_error_codes { I3C_ERROR_TE_INVALID, }; +/** + * @brief I3C Transfer API + * @defgroup i3c_transfer_api I3C Transfer API + * @{ + */ + /* * I3C_MSG_* are I3C Message flags. */ @@ -328,6 +441,13 @@ enum i3c_sdr_target_error_codes { /** I3C HDR-BT (Bulk Transport) */ #define I3C_MSG_HDR_BT I3C_MSG_HDR_MODE3 +/** @} */ + +/** + * @addtogroup i3c_transfer_api + * @{ + */ + /** * @brief One I3C Message. * @@ -361,6 +481,8 @@ struct i3c_msg { uint8_t hdr_mode; }; +/** @} */ + /** * @brief Type of configuration being passed to configure function. */ @@ -770,8 +892,13 @@ struct i3c_device_id { * Field @c node should not be initialized or modified manually. */ struct i3c_device_desc { - /** Private, do not modify */ + /** + * Used to attach this node onto a linked list. + * + * @cond INTERNAL_HIDDEN + */ sys_snode_t node; + /** @endcond */ /** I3C bus to which this target device is attached */ const struct device * const bus; @@ -894,8 +1021,13 @@ struct i3c_device_desc { uint8_t max_ibi; } data_length; - /** Private data by the controller to aid in transactions. Do not modify. */ + /** + * Private data by the controller to aid in transactions. Do not modify. + * + * @cond INTERNAL_HIDDEN + */ void *controller_priv; + /** @endcond */ #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__) /** @@ -919,8 +1051,13 @@ struct i3c_device_desc { * reference to I3C controller device APIs. */ struct i3c_i2c_device_desc { - /** Private, do not modify */ + /** + * Used to attach this node onto a linked list. + * + * @cond INTERNAL_HIDDEN + */ sys_snode_t node; + /** @endcond */ /** I3C bus to which this I2C device is attached */ const struct device *bus; @@ -944,8 +1081,13 @@ struct i3c_i2c_device_desc { */ const uint8_t lvr; - /** Private data by the controller to aid in transactions. Do not modify. */ + /** + * Private data by the controller to aid in transactions. Do not modify. + * + * @cond INTERNAL_HIDDEN + */ void *controller_priv; + /** @endcond */ }; /** @@ -1400,6 +1542,11 @@ static inline int z_impl_i3c_do_ccc(const struct device *dev, return api->do_ccc(dev, payload); } +/** + * @addtogroup i3c_transfer_api + * @{ + */ + /** * @brief Perform data transfer from the controller to a I3C target device. * @@ -1438,6 +1585,8 @@ static inline int z_impl_i3c_transfer(struct i3c_device_desc *target, return api->i3c_xfers(target->bus, target, msgs, num_msgs); } +/** @} */ + /** * Find a registered I3C target device. * @@ -1466,6 +1615,11 @@ struct i3c_device_desc *i3c_device_find(const struct device *dev, return api->i3c_device_find(dev, id); } +/** + * @addtogroup i3c_ibi + * @{ + */ + /** * @brief Raise an In-Band Interrupt (IBI). * @@ -1574,6 +1728,13 @@ static inline int i3c_device_is_ibi_capable(struct i3c_device_desc *target) == I3C_BCR_IBI_REQUEST_CAPABLE; } +/** @} */ + +/** + * @addtogroup i3c_transfer_api + * @{ + */ + /** * @brief Write a set amount of data to an I3C target device. * @@ -1835,6 +1996,8 @@ static inline int i3c_reg_update_byte(struct i3c_device_desc *target, void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs, uint8_t num_msgs, struct i3c_device_desc *target); +/** @} */ + /** * @brief Generic helper function to perform bus initialization. * diff --git a/include/zephyr/drivers/i3c/addresses.h b/include/zephyr/drivers/i3c/addresses.h index 95f05f180e1..191e7f881da 100644 --- a/include/zephyr/drivers/i3c/addresses.h +++ b/include/zephyr/drivers/i3c/addresses.h @@ -22,16 +22,32 @@ extern "C" { #endif +/** Broadcast Address on I3C bus. */ #define I3C_BROADCAST_ADDR 0x7E + +/** Maximum value of device addresses. */ #define I3C_MAX_ADDR 0x7F struct i3c_dev_list; +/** + * Enum to indicate whether an address is reserved, has I2C/I3C device attached, + * or no device attached. + */ enum i3c_addr_slot_status { + /** Address has not device attached. */ I3C_ADDR_SLOT_STATUS_FREE = 0U, + + /** Address is reserved. */ I3C_ADDR_SLOT_STATUS_RSVD, + + /** Address is associated with an I3C device. */ I3C_ADDR_SLOT_STATUS_I3C_DEV, + + /** Address is associated with an I2C device. */ I3C_ADDR_SLOT_STATUS_I2C_DEV, + + /** Bit masks used to filter status bits. */ I3C_ADDR_SLOT_STATUS_MASK = 0x03U, }; diff --git a/include/zephyr/drivers/i3c/ccc.h b/include/zephyr/drivers/i3c/ccc.h index fcb0ac6e1e4..606d44f79ae 100644 --- a/include/zephyr/drivers/i3c/ccc.h +++ b/include/zephyr/drivers/i3c/ccc.h @@ -304,17 +304,25 @@ struct i3c_ccc_events { uint8_t events; } __packed; -/* For Enable Events */ +/** Enable Events (ENEC) - Target Interrupt Requests. */ #define I3C_CCC_ENEC_EVT_ENINTR BIT(0) + +/** Enable Events (ENEC) - Controller Role Requests. */ #define I3C_CCC_ENEC_EVT_ENCR BIT(1) + +/** Enable Events (ENEC) - Hot-Join Event. */ #define I3C_CCC_ENEC_EVT_ENHJ BIT(3) #define I3C_CCC_ENEC_EVT_ALL \ (I3C_CCC_ENEC_EVT_ENINTR | I3C_CCC_ENEC_EVT_ENCR | I3C_CCC_ENEC_EVT_ENHJ) -/* For Disable Events */ +/** Disable Events (DISEC) - Target Interrupt Requests. */ #define I3C_CCC_DISEC_EVT_DISINTR BIT(0) + +/** Disable Events (DISEC) - Controller Role Requests. */ #define I3C_CCC_DISEC_EVT_DISCR BIT(1) + +/** Disable Events (DISEC) - Hot-Join Event. */ #define I3C_CCC_DISEC_EVT_DISHJ BIT(3) #define I3C_CCC_DISEC_EVT_ALL \ @@ -324,10 +332,17 @@ struct i3c_ccc_events { * Events for both enabling and disabling since * they have the same bits. */ + +/** Events - Target Interrupt Requests. */ #define I3C_CCC_EVT_INTR BIT(0) + +/** Events - Controller Role Requests. */ #define I3C_CCC_EVT_CR BIT(1) + +/** Events - Hot-Join Event. */ #define I3C_CCC_EVT_HJ BIT(3) +/** Bitmask for all events. */ #define I3C_CCC_EVT_ALL \ (I3C_CCC_EVT_INTR | I3C_CCC_EVT_CR | I3C_CCC_EVT_HJ) @@ -488,14 +503,24 @@ struct i3c_ccc_getdcr { * @brief Indicate which format of GETSTATUS to use. */ enum i3c_ccc_getstatus_fmt { + /** GETSTATUS Format 1 */ GETSTATUS_FORMAT_1, + + /** GETSTATUS Format 2 */ GETSTATUS_FORMAT_2, }; +/** + * @brief Defining byte values for GETSTATUS Format 2. + */ enum i3c_ccc_getstatus_defbyte { + /** Target status. */ GETSTATUS_FORMAT_2_TGTSTAT = 0x00U, + + /** PRECR - Alternate status format describing Controller-capable device. */ GETSTATUS_FORMAT_2_PRECR = 0x91U, + /** Invalid defining byte. */ GETSTATUS_FORMAT_2_INVALID = 0x100U }; @@ -546,28 +571,51 @@ union i3c_ccc_getstatus { } fmt2; } __packed; +/** GETSTATUS Format 1 - Protocol Error bit. */ #define I3C_CCC_GETSTATUS_PROTOCOL_ERR BIT(5) +/** GETSTATUS Format 1 - Activity Mode bit shift value. */ #define I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT 6 +/** GETSTATUS Format 1 - Activity Mode bitmask. */ #define I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK \ (0x03U << I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT) +/** + * @brief GETSTATUS Format 1 - Activity Mode + * + * Obtain Activity Mode from GETSTATUS Format 1 value obtained via + * GETSTATUS. + * + * @param status GETSTATUS Format 1 value + */ #define I3C_CCC_GETSTATUS_ACTIVITY_MODE(status) \ (((status) & I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK) \ >> I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT) +/** GETSTATUS Format 1 - Number of Pending Interrupts bit shift value. */ #define I3C_CCC_GETSTATUS_NUM_INT_SHIFT 0 +/** GETSTATUS Format 1 - Number of Pending Interrupts bitmask. */ #define I3C_CCC_GETSTATUS_NUM_INT_MASK \ (0x0FU << I3C_CCC_GETSTATUS_NUM_INT_SHIFT) +/** + * @brief GETSTATUS Format 1 - Number of Pending Interrupts + * + * Obtain Number of Pending Interrupts from GETSTATUS Format 1 value + * obtained via GETSTATUS. + * + * @param status GETSTATUS Format 1 value + */ #define I3C_CCC_GETSTATUS_NUM_INT(status) \ (((status) & I3C_CCC_GETSTATUS_NUM_INT_MASK) \ >> I3C_CCC_GETSTATUS_NUM_INT_SHIFT) +/** GETSTATUS Format 2 - PERCR - Deep Sleep Detected bit. */ #define I3C_CCC_GETSTATUS_PRECR_DEEP_SLEEP_DETECTED BIT(0) +/** GETSTATUS Format 2 - PERCR - Handoff Delay NACK. */ #define I3C_CCC_GETSTATUS_PRECR_HANDOFF_DELAY_NACK BIT(1) /** @@ -654,59 +702,122 @@ union i3c_ccc_getmxds { } fmt3; } __packed; +/** Get Max Data Speed (GETMXDS) - Default Max Sustained Data Rate. */ #define I3C_CCC_GETMXDS_MAX_SDR_FSCL_MAX 0 + +/** Get Max Data Speed (GETMXDS) - 8MHz Max Sustained Data Rate. */ #define I3C_CCC_GETMXDS_MAX_SDR_FSCL_8MHZ 1 + +/** Get Max Data Speed (GETMXDS) - 6MHz Max Sustained Data Rate. */ #define I3C_CCC_GETMXDS_MAX_SDR_FSCL_6MHZ 2 + +/** Get Max Data Speed (GETMXDS) - 4MHz Max Sustained Data Rate. */ #define I3C_CCC_GETMXDS_MAX_SDR_FSCL_4MHZ 3 + +/** Get Max Data Speed (GETMXDS) - 2MHz Max Sustained Data Rate. */ #define I3C_CCC_GETMXDS_MAX_SDR_FSCL_2MHZ 4 +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround <= 8ns. */ #define I3C_CCC_GETMXDS_TSCO_8NS 0 + +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround <= 9ns. */ #define I3C_CCC_GETMXDS_TSCO_9NS 1 + +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround <= 10ns. */ #define I3C_CCC_GETMXDS_TSCO_10NS 2 + +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround <= 11ns. */ #define I3C_CCC_GETMXDS_TSCO_11NS 3 + +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround <= 12ns. */ #define I3C_CCC_GETMXDS_TSCO_12NS 4 + +/** Get Max Data Speed (GETMXDS) - Clock to Data Turnaround > 12ns. */ #define I3C_CCC_GETMXDS_TSCO_GT_12NS 7 +/** Get Max Data Speed (GETMXDS) - maxWr - Optional Defining Byte Support. */ #define I3C_CCC_GETMXDS_MAXWR_DEFINING_BYTE_SUPPORT BIT(3) +/** Get Max Data Speed (GETMXDS) - Max Sustained Data Rate bit shift value. */ #define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_SHIFT 0 +/** Get Max Data Speed (GETMXDS) - Max Sustained Data Rate bitmask. */ #define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_MASK \ (0x07U << I3C_CCC_GET_MXDS_MAXWR_MAX_SDR_FSCL_SHIFT) +/** + * @brief Get Max Data Speed (GETMXDS) - maxWr - Max Sustained Data Rate + * + * Obtain Max Sustained Data Rate value from GETMXDS maxWr value + * obtained via GETMXDS. + * + * @param maxwr GETMXDS maxWr value. + */ #define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL(maxwr) \ (((maxwr) & \ I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_MASK) \ >> I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_SHIFT) +/** Get Max Data Speed (GETMXDS) - maxRd - Write-to-Read Permits Stop Between. */ #define I3C_CCC_GETMXDS_MAXRD_W2R_PERMITS_STOP_BETWEEN BIT(6) +/** Get Max Data Speed (GETMXDS) - maxRd - Clock to Data Turnaround bit shift value. */ #define I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT 3 +/** Get Max Data Speed (GETMXDS) - maxRd - Clock to Data Turnaround bitmask. */ #define I3C_CCC_GETMXDS_MAXRD_TSCO_MASK \ (0x07U << I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT) +/** + * @brief Get Max Data Speed (GETMXDS) - maxRd - Clock to Data Turnaround + * + * Obtain Clock to Data Turnaround value from GETMXDS maxRd value + * obtained via GETMXDS. + * + * @param maxrd GETMXDS maxRd value. + */ #define I3C_CCC_GETMXDS_MAXRD_TSCO(maxrd) \ (((maxrd) & I3C_CCC_GETMXDS_MAXRD_TSCO_MASK) \ >> I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT) +/** Get Max Data Speed (GETMXDS) - maxRd - Max Sustained Data Rate bit shift value. */ #define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_SHIFT 0 +/** Get Max Data Speed (GETMXDS) - maxRd - Max Sustained Data Rate bitmask. */ #define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_MASK \ (0x07U << I3C_CCC_GET_MXDS_MAXRD_MAX_SDR_FSCL_SHIFT) +/** + * @brief Get Max Data Speed (GETMXDS) - maxRd - Max Sustained Data Rate + * + * Obtain Max Sustained Data Rate value from GETMXDS maxRd value + * obtained via GETMXDS. + * + * @param maxrd GETMXDS maxRd value. + */ #define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL(maxrd) \ (((maxrd) & \ I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_MASK) \ >> I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_SHIFT) +/** Get Max Data Speed (GETMXDS) - CRDHLY1 - Set Bus Activity State bit shift value. */ #define I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE BIT(2) +/** Get Max Data Speed (GETMXDS) - CRDHLY1 - Controller Handoff Activity State bit shift value. */ #define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_SHIFT 0 +/** Get Max Data Speed (GETMXDS) - CRDHLY1 - Controller Handoff Activity State bitmask. */ #define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_MASK \ (0x03U << I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE_SHIFT) +/** + * @brief Get Max Data Speed (GETMXDS) - CRDHLY1 - Controller Handoff Activity State + * + * Obtain Controller Handoff Activity State value from GETMXDS value + * obtained via GETMXDS. + * + * @param crhdly1 GETMXDS value. + */ #define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(crhdly1) \ (((crhdly1) & \ I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE_MASK) \ @@ -724,51 +835,163 @@ struct i3c_ccc_getcaps { uint8_t getcaps[4]; } __packed; +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR-DDR mode bit. */ #define I3C_CCC_GETCAPS1_HDR_DDR BIT(0) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR-BT mode bit. */ #define I3C_CCC_GETCAPS1_HDR_BT BIT(3) +/** + * @brief Get Optional Feature Capabilities (GETCAPS) - HDR Mode + * + * Get the bit corresponding to HDR mode. + * + * @param x HDR mode + */ #define I3C_CCC_GETCAPS1_HDR_MODE(x) BIT(x) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 0. */ #define I3C_CCC_GETCAPS1_HDR_MODE0 BIT(0) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 1. */ #define I3C_CCC_GETCAPS1_HDR_MODE1 BIT(1) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 2. */ #define I3C_CCC_GETCAPS1_HDR_MODE2 BIT(2) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 3. */ #define I3C_CCC_GETCAPS1_HDR_MODE3 BIT(3) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 4. */ #define I3C_CCC_GETCAPS1_HDR_MODE4 BIT(4) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 5. */ #define I3C_CCC_GETCAPS1_HDR_MODE5 BIT(5) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 6. */ #define I3C_CCC_GETCAPS1_HDR_MODE6 BIT(6) + +/** Get Optional Feature Capabilities (GETCAPS) Format 1 - HDR Mode 7. */ #define I3C_CCC_GETCAPS1_HDR_MODE7 BIT(7) +/** Get Optional Feature Capabilities (GETCAPS) Format 2 - HDR-DDR Write Abort bit. */ #define I3C_CCC_GETCAPS2_HDRDDR_WRITE_ABORT BIT(6) + +/** Get Optional Feature Capabilities (GETCAPS) Format 2 - HDR-DDR Abort CRC bit. */ #define I3C_CCC_GETCAPS2_HDRDDR_ABORT_CRC BIT(7) +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - + * Group Address Capabilities bit shift value. + */ #define I3C_CCC_GETCAPS2_GRPADDR_CAP_SHIFT 4 + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - + * Group Address Capabilities bitmask. + */ #define I3C_CCC_GETCAPS2_GRPADDR_CAP_MASK \ (0x03U << I3C_CCC_GETCAPS2_GRPADDR_CAP_SHIFT) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - Group Address Capabilities. + * + * Obtain Group Address Capabilities value from GETCAPS Format 2 value + * obtained via GETCAPS. + * + * @param getcaps2 GETCAPS2 value. + */ #define I3C_CCC_GETCAPS2_GRPADDR_CAP(getcaps2) \ (((getcaps2) & \ I3C_CCC_GETCAPS2_GRPADDR_CAP_MASK) \ >> I3C_CCC_GETCAPS_GRPADDR_CAP_SHIFT) +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - + * I3C 1.x Specification Version bit shift value. + */ #define I3C_CCC_GETCAPS2_SPEC_VER_SHIFT 0 + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - + * I3C 1.x Specification Version bitmask. + */ #define I3C_CCC_GETCAPS2_SPEC_VER_MASK \ (0x0FU << I3C_CCC_GETCAPS2_SPEC_VER_SHIFT) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 2 - + * I3C 1.x Specification Version. + * + * Obtain I3C 1.x Specification Version value from GETCAPS Format 2 value + * obtained via GETCAPS. + * + * @param getcaps2 GETCAPS2 value. + */ #define I3C_CCC_GETCAPS2_SPEC_VER(getcaps2) \ (((getcaps2) & \ I3C_CCC_GETCAPS2_SPEC_VER_MASK) \ >> I3C_CCC_GETCAPS_SPEC_VER_SHIFT) -#define I3C_CCC_GETCAPS3_MLAME_SUPPORT BIT(0) +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * Multi-Lane Data Transfer Support bit. + */ +#define I3C_CCC_GETCAPS3_MLANE_SUPPORT BIT(0) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * Device to Device Transfer (D2DXFER) Support bit. + */ #define I3C_CCC_GETCAPS3_D2DXFER_SUPPORT BIT(1) -#define I3C_CCC_GETCAPS3_D3DXFER_IBI_CAPABLE BIT(2) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * Device to Device Transfer (D2DXFER) IBI Capable bit. + */ +#define I3C_CCC_GETCAPS3_D2DXFER_IBI_CAPABLE BIT(2) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * Defining Byte Support in GETCAPS bit. + */ #define I3C_CCC_GETCAPS3_GETCAPS_DEFINING_BYTE_SUPPORT BIT(3) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * Defining Byte Support in GETSTATUS bit. + */ #define I3C_CCC_GETCAPS3_GETSTATUS_DEFINING_BYTE_SUPPORT BIT(4) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * HDR-BT CRC-32 Support bit. + */ #define I3C_CCC_GETCAPS3_HDRBT_CRC32_SUPPORT BIT(5) + +/** + * @brief Get Optional Feature Capabilities (GETCAPS) Format 3 - + * IBI MDB Support for Pending Read Notification bit. + */ #define I3C_CCC_GETCAPS3_IBI_MDR_PENDING_READ_NOTIFICATION BIT(6) +/** + * @brief Enum for I3C Reset Action (RSTACT) Defining Byte Values. + */ enum i3c_ccc_rstact_defining_byte { + /** No Reset on Target Reset Pattern. */ I3C_CCC_RSTACT_NO_RESET = 0x00U, + + /** Reset the I3C Peripheral Only. */ I3C_CCC_RSTACT_PERIPHERAL_ONLY = 0x01U, + + /** Reset the Whole Target. */ I3C_CCC_RSTACT_RESET_WHOLE_TARGET = 0x02U, + + /** Debug Network Adapter Reset. */ I3C_CCC_RSTACT_DEBUG_NETWORK_ADAPTER = 0x03U, + + /** Virtual Target Detect. */ I3C_CCC_RSTACT_VIRTUAL_TARGET_DETECT = 0x04U, }; diff --git a/include/zephyr/drivers/i3c/ibi.h b/include/zephyr/drivers/i3c/ibi.h index 8156db1c22e..2483b5de5a2 100644 --- a/include/zephyr/drivers/i3c/ibi.h +++ b/include/zephyr/drivers/i3c/ibi.h @@ -44,7 +44,7 @@ enum i3c_ibi_type { I3C_IBI_TYPE_MAX = I3C_IBI_HOTJOIN, - /* + /** * Not an actual IBI type, but simply used by * the IBI workq for generic callbacks. */ @@ -87,9 +87,12 @@ struct i3c_ibi_payload { */ struct i3c_ibi_work { /** - * Private, do not modify. + * @cond INTERNAL_HIDDEN + * + * Used for keeping track of work in a queue. */ sys_snode_t node; + /** @endcond */ /** * k_work struct. diff --git a/include/zephyr/drivers/i3c/target_device.h b/include/zephyr/drivers/i3c/target_device.h index 6cfac503c61..ca699814078 100644 --- a/include/zephyr/drivers/i3c/target_device.h +++ b/include/zephyr/drivers/i3c/target_device.h @@ -9,7 +9,7 @@ /** * @brief I3C Target Device API - * @defgroup i3c_target_device Target Device API + * @defgroup i3c_target_device I3C Target Device API * @ingroup i3c_interface * @{ */ @@ -217,7 +217,7 @@ struct i3c_target_driver_api { }; /** - * @brief Writes to the Target's TX FIFO + * @brief Writes to the target's TX FIFO * * Write to the TX FIFO @p dev I3C bus driver using the provided * buffer and length. Some I3C targets will NACK read requests until data From fe8d30dd42b21c6f528872a63b93b3e90bc37f96 Mon Sep 17 00:00:00 2001 From: Jeroen van Dooren Date: Fri, 6 Oct 2023 09:52:14 +0200 Subject: [PATCH 1769/4498] net: ip: tcp: Fix kernel crash on idle thread Fixing kernel crash caused by memory release while having a scheduled work item pending. Signed-off-by: Jeroen van Dooren --- subsys/net/ip/tcp.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 4f59ad40758..c12eff69f06 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -569,7 +569,20 @@ static int tcp_conn_unref(struct tcp *conn) tcp_send_queue_flush(conn); - k_work_cancel_delayable(&conn->send_data_timer); + /* Cancel all possible delayed work and prevent any execution of newly scheduled work + * in one of the work item handlers + * Essential because the work items are destructed at the bottom of this method. + * A current ongoing execution might access the connection and schedule new work + * Solution: + * While holding the lock, cancel all delayable work. + * Because every delayable work execution takes the same lock and releases the lock, + * we're either here, or currently executing one of the workers. + * Then, after cancelling the workers within the lock, either those workers have finished + * or have been cancelled and will not execute anymore + */ + k_mutex_lock(&conn->lock, K_FOREVER); + + (void)k_work_cancel_delayable(&conn->send_data_timer); tcp_pkt_unref(conn->send_data); if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) { @@ -580,6 +593,10 @@ static int tcp_conn_unref(struct tcp *conn) (void)k_work_cancel_delayable(&conn->fin_timer); (void)k_work_cancel_delayable(&conn->persist_timer); (void)k_work_cancel_delayable(&conn->ack_timer); + (void)k_work_cancel_delayable(&conn->send_timer); + (void)k_work_cancel_delayable(&conn->recv_queue_timer); + + k_mutex_unlock(&conn->lock); sys_slist_find_and_remove(&tcp_conns, &conn->next); @@ -695,10 +712,12 @@ static void tcp_send_process(struct k_work *work) struct tcp *conn = CONTAINER_OF(dwork, struct tcp, send_timer); bool unref; + /* take the lock to prevent a race-condition with tcp_conn_unref */ k_mutex_lock(&conn->lock, K_FOREVER); unref = tcp_send_process_no_lock(conn); + /* release the lock only after possible scheduling of work */ k_mutex_unlock(&conn->lock); if (unref) { @@ -1403,6 +1422,7 @@ static void tcp_cleanup_recv_queue(struct k_work *work) struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct tcp *conn = CONTAINER_OF(dwork, struct tcp, recv_queue_timer); + /* take the lock to prevent a race-condition with tcp_conn_unref */ k_mutex_lock(&conn->lock, K_FOREVER); NET_DBG("Cleanup recv queue conn %p len %zd seq %u", conn, @@ -1412,6 +1432,7 @@ static void tcp_cleanup_recv_queue(struct k_work *work) net_buf_unref(conn->queue_recv_data->buffer); conn->queue_recv_data->buffer = NULL; + /* release the lock only after possible scheduling of work */ k_mutex_unlock(&conn->lock); } @@ -1423,6 +1444,7 @@ static void tcp_resend_data(struct k_work *work) int ret; int exp_tcp_rto; + /* take the lock to prevent a race-condition with tcp_conn_unref */ k_mutex_lock(&conn->lock, K_FOREVER); NET_DBG("send_data_retries=%hu", conn->send_data_retries); @@ -1486,6 +1508,7 @@ static void tcp_resend_data(struct k_work *work) K_MSEC(exp_tcp_rto)); out: + /* release the lock only after possible scheduling of work */ k_mutex_unlock(&conn->lock); if (conn_unref) { @@ -1498,6 +1521,7 @@ static void tcp_timewait_timeout(struct k_work *work) struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct tcp *conn = CONTAINER_OF(dwork, struct tcp, timewait_timer); + /* no need to acquire the conn->lock as there is nothing scheduled here */ NET_DBG("conn: %p %s", conn, tcp_conn_state(conn, NULL)); (void)tcp_conn_close(conn, -ETIMEDOUT); @@ -1516,6 +1540,7 @@ static void tcp_fin_timeout(struct k_work *work) struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct tcp *conn = CONTAINER_OF(dwork, struct tcp, fin_timer); + /* no need to acquire the conn->lock as there is nothing scheduled here */ if (conn->state == TCP_SYN_RECEIVED) { tcp_establish_timeout(conn); return; @@ -1532,6 +1557,7 @@ static void tcp_send_zwp(struct k_work *work) struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct tcp *conn = CONTAINER_OF(dwork, struct tcp, persist_timer); + /* take the lock to prevent a race-condition with tcp_conn_unref */ k_mutex_lock(&conn->lock, K_FOREVER); (void)tcp_out_ext(conn, ACK, NULL, conn->seq - 1); @@ -1555,6 +1581,7 @@ static void tcp_send_zwp(struct k_work *work) &tcp_work_q, &conn->persist_timer, K_MSEC(timeout)); } + /* release the lock only after possible scheduling of work */ k_mutex_unlock(&conn->lock); } @@ -1563,10 +1590,12 @@ static void tcp_send_ack(struct k_work *work) struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct tcp *conn = CONTAINER_OF(dwork, struct tcp, ack_timer); + /* take the lock to prevent a race-condition with tcp_conn_unref */ k_mutex_lock(&conn->lock, K_FOREVER); tcp_out(conn, ACK); + /* release the lock only after possible scheduling of work */ k_mutex_unlock(&conn->lock); } From ff074551b0442bd4b28d99517bd11c23f3ca57ad Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 17:41:57 +0000 Subject: [PATCH 1770/4498] entropy: gecko_se: Remove unnecessary callback get_entropy_isr is not implemented, just remove it and let the driver interface handle it. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_gecko_se.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/entropy/entropy_gecko_se.c b/drivers/entropy/entropy_gecko_se.c index 2efe1e2307c..133df43e0a3 100644 --- a/drivers/entropy/entropy_gecko_se.c +++ b/drivers/entropy/entropy_gecko_se.c @@ -40,13 +40,6 @@ static int entropy_gecko_se_get_entropy(const struct device *dev, return err; } -static int entropy_gecko_se_get_entropy_isr(const struct device *dev, - uint8_t *buf, - uint16_t len, uint32_t flags) -{ - return -ENOTSUP; -} - static int entropy_gecko_se_init(const struct device *dev) { if (sl_se_init()) { @@ -58,7 +51,6 @@ static int entropy_gecko_se_init(const struct device *dev) static const struct entropy_driver_api entropy_gecko_se_api_funcs = { .get_entropy = entropy_gecko_se_get_entropy, - .get_entropy_isr = entropy_gecko_se_get_entropy_isr }; #define GECKO_SE_INIT(n) \ From 5133ac8af48179d01f61e230411a96de46bb4a6f Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 20:23:02 +0000 Subject: [PATCH 1771/4498] entropy: b91_trng: Fix callback return get_entropy_isr() has to return the number of bytes copied or a negative value for error. Since this driver is assuming that it will always (????) get the number of requested bytes, change the function to return it instead of 0. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_b91_trng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_b91_trng.c b/drivers/entropy/entropy_b91_trng.c index 7d719e01a2d..914b70003b3 100644 --- a/drivers/entropy/entropy_b91_trng.c +++ b/drivers/entropy/entropy_b91_trng.c @@ -55,7 +55,7 @@ static int entropy_b91_trng_get_entropy_isr(const struct device *dev, /* No specific handling in case of running from ISR, just call standard API */ entropy_b91_trng_get_entropy(dev, buffer, length); - return 0; + return length; } /* Entropy driver APIs structure */ From 58b0c8f4b797ccb573a43cefe3c53d36b5f54ad5 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 20:32:05 +0000 Subject: [PATCH 1772/4498] entropy: neorv32: Return ENODATA on error Return -ENODATA in neorv32_trng_get_entropy_isr when there is no data available. This is consistent with other drivers. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_neorv32_trng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_neorv32_trng.c b/drivers/entropy/entropy_neorv32_trng.c index 269339adb9d..2163f8c1928 100644 --- a/drivers/entropy/entropy_neorv32_trng.c +++ b/drivers/entropy/entropy_neorv32_trng.c @@ -69,7 +69,7 @@ static int neorv32_trng_get_entropy_isr(const struct device *dev, uint8_t *buffe } /* No entropy available */ - return 0; + return -ENODATA; } err = neorv32_trng_get_entropy(dev, buffer, len); From 1dcaf4637e8075ed91f2673bc0d360d9e5dc04d6 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 20:40:21 +0000 Subject: [PATCH 1773/4498] entropy: fake_entropy: Fix return value in isr callback get_entropy_isr() has to return the number of bytes copied or a negative value in case of error. Signed-off-by: Flavio Ceolin --- drivers/entropy/fake_entropy_native_posix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/entropy/fake_entropy_native_posix.c b/drivers/entropy/fake_entropy_native_posix.c index b39c07bbf30..33658155595 100644 --- a/drivers/entropy/fake_entropy_native_posix.c +++ b/drivers/entropy/fake_entropy_native_posix.c @@ -59,7 +59,9 @@ static int entropy_native_posix_get_entropy_isr(const struct device *dev, * entropy_native_posix_get_entropy() is also safe for ISRs * and always produces data. */ - return entropy_native_posix_get_entropy(dev, buf, len); + entropy_native_posix_get_entropy(dev, buf, len); + + return len; } static int entropy_native_posix_init(const struct device *dev) From 78af9885464059f01bd407c6c9c5818e58b7c4c8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 6 Oct 2023 17:38:03 +0000 Subject: [PATCH 1774/4498] entropy: sam: Fix get_entropy() behavior entropy_get_entropy blocks if required to generate the necessary random data. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_sam.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/entropy/entropy_sam.c b/drivers/entropy/entropy_sam.c index b01569b899b..f4c40321f3b 100644 --- a/drivers/entropy/entropy_sam.c +++ b/drivers/entropy/entropy_sam.c @@ -41,6 +41,8 @@ static inline uint32_t _data(Trng * const trng) static int entropy_sam_wait_ready(Trng * const trng, uint32_t flags) { + ARG_UNUSED(flags); + /* According to the reference manual, the generator provides * one 32-bit random value every 84 peripheral clock cycles. * MCK may not be smaller than HCLK/4, so it should not take @@ -56,17 +58,6 @@ static int entropy_sam_wait_ready(Trng * const trng, uint32_t flags) if (timeout-- == 0) { return -ETIMEDOUT; } - - if ((flags & ENTROPY_BUSYWAIT) == 0U) { - /* This internal function is used by both get_entropy, - * and get_entropy_isr APIs. The later may call this - * function with the ENTROPY_BUSYWAIT flag set. In - * that case make no assumption that the kernel is - * initialized when the function is called; so, just - * do busy-wait for the random data to be ready. - */ - k_yield(); - } } return 0; From 39068456c4d6dba8a00682a093e5c329ee82670b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 6 Oct 2023 18:54:54 +0000 Subject: [PATCH 1775/4498] entropy: sam: Remove unused parameter Do not propagate unused parameter. ISR callback is already handling the given flags, there is not need to propagate it through internal calls. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_sam.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/entropy/entropy_sam.c b/drivers/entropy/entropy_sam.c index f4c40321f3b..57bdb8f8419 100644 --- a/drivers/entropy/entropy_sam.c +++ b/drivers/entropy/entropy_sam.c @@ -39,10 +39,8 @@ static inline uint32_t _data(Trng * const trng) #endif } -static int entropy_sam_wait_ready(Trng * const trng, uint32_t flags) +static int entropy_sam_wait_ready(Trng * const trng) { - ARG_UNUSED(flags); - /* According to the reference manual, the generator provides * one 32-bit random value every 84 peripheral clock cycles. * MCK may not be smaller than HCLK/4, so it should not take @@ -65,7 +63,7 @@ static int entropy_sam_wait_ready(Trng * const trng, uint32_t flags) static int entropy_sam_get_entropy_internal(const struct device *dev, uint8_t *buffer, - uint16_t length, uint32_t flags) + uint16_t length) { const struct trng_sam_dev_cfg *config = dev->config; Trng *const trng = config->regs; @@ -75,7 +73,7 @@ static int entropy_sam_get_entropy_internal(const struct device *dev, uint32_t value; int res; - res = entropy_sam_wait_ready(trng, flags); + res = entropy_sam_wait_ready(trng); if (res < 0) { return res; } @@ -94,7 +92,7 @@ static int entropy_sam_get_entropy_internal(const struct device *dev, static int entropy_sam_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) { - return entropy_sam_get_entropy_internal(dev, buffer, length, 0); + return entropy_sam_get_entropy_internal(dev, buffer, length); } static int entropy_sam_get_entropy_isr(const struct device *dev, @@ -135,7 +133,7 @@ static int entropy_sam_get_entropy_isr(const struct device *dev, /* Allowed to busy-wait */ int ret = entropy_sam_get_entropy_internal(dev, - buffer, length, flags); + buffer, length); if (ret == 0) { /* Data retrieved successfully. */ From d66cf91706a4069f94d5b5793c54c394f1b78e9c Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 6 Oct 2023 13:11:33 -0400 Subject: [PATCH 1776/4498] doc: Add missing threads references to object cores Two references to the integration of object cores with threads were missing from the documentation. This fixes that. Signed-off-by: Peter Mitsis --- doc/kernel/object_cores/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/kernel/object_cores/index.rst b/doc/kernel/object_cores/index.rst index 6ccd41df7ad..3e8a72d68a5 100644 --- a/doc/kernel/object_cores/index.rst +++ b/doc/kernel/object_cores/index.rst @@ -31,6 +31,7 @@ Object cores have been integrated into following kernel objects: * :ref:`Mutexes ` * :ref:`Pipes ` * :ref:`Semaphores ` + * :ref:`Threads ` * :ref:`Timers ` * :ref:`System Memory Blocks ` @@ -218,6 +219,7 @@ Related configuration options: * :kconfig:option:`CONFIG_OBJ_CORE_PIPE` * :kconfig:option:`CONFIG_OBJ_CORE_SEM` * :kconfig:option:`CONFIG_OBJ_CORE_STACK` +* :kconfig:option:`CONFIG_OBJ_CORE_THREAD` * :kconfig:option:`CONFIG_OBJ_CORE_TIMER` * :kconfig:option:`CONFIG_OBJ_CORE_SYS_MEM_BLOCKS` * :kconfig:option:`CONFIG_OBJ_CORE_STATS` From 49e811bb2d46c859917c394fe274a27ad6414830 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 21:46:19 +0000 Subject: [PATCH 1777/4498] doc: release: 3.5: Add info about CVE-2023-3725 Add CVE-2023-3725 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c80538af120..ee79befd6f9 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -20,6 +20,9 @@ The following CVEs are addressed by this release: More detailed information can be found in: https://docs.zephyrproject.org/latest/security/vulnerabilities.html +* CVE-2023-3725 `Zephyr project bug tracker GHSA-2g3m-p6c7-8rr3 + `_ + * CVE-2023-4257: Under embargo until 2023-10-12 * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 From 29f6ea431dd9e23893a58505252cfd525247becf Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 5 Oct 2023 21:53:03 +0000 Subject: [PATCH 1778/4498] doc: vuln: Add information about CVE-2023-3725 Information about CVE-2023-3725 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 6b6bb3c07b9..882a8d8b8a1 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1345,6 +1345,28 @@ This has been fixed in main for v3.4.0 - `PR 56709 fix for main `_ +CVE-2023-3725 +------------- + +Potential buffer overflow vulnerability in the Zephyr CANbus subsystem. + +- `Zephyr project bug tracker GHSA-2g3m-p6c7-8rr3 + `_ + +This has been fixed in main for v3.5.0 + +- `PR 61502 fix for main + `_ + +- `PR 61518 fix for 3.4 + `_ + +- `PR 61517 fix for 3.3 + `_ + +- `PR 61516 fix for 2.7 + `_ + CVE-2023-4257 ------------- From f8e812aa3f5ace9abb01affe2aed267f2a6cde08 Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Fri, 6 Oct 2023 21:04:21 -0400 Subject: [PATCH 1779/4498] dts: arm: st: u5: correct lptim2 clock enable bit The LPTIM2 clock enable is bit 5 of RCC APB1 clock enable register 2 (RM0456 Rev 4 11.8.34). Signed-off-by: Brett Witherspoon --- dts/arm/st/u5/stm32u5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index b7abd1dd17a..7363181e663 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -443,7 +443,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x40009400 0x400>; - clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>; + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000020>; interrupts = <68 0>; interrupt-names = "global"; st,static-prescaler; From e7f399f4a3216d2e86b95683f476eb9d2cc871da Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Mon, 9 Oct 2023 10:25:11 +0200 Subject: [PATCH 1780/4498] drivers: can: avoid integer overflow in expression Change the integer arithmetic to divide first before multiply. The muliplication of sys_clock_hw_cycles_per_sec() by ten leads to a really big number on boards with high-speed clocking, thus to the overflow warning, and to errors for integration tests. Fixes: #63678 Signed-off-by: Stephan Linz --- drivers/can/can_stm32_bxcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index abae476e7d1..9ded24233d2 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(can_stm32, CONFIG_CAN_LOG_LEVEL); -#define CAN_INIT_TIMEOUT (10 * sys_clock_hw_cycles_per_sec() / MSEC_PER_SEC) +#define CAN_INIT_TIMEOUT (10 * (sys_clock_hw_cycles_per_sec() / MSEC_PER_SEC)) #define DT_DRV_COMPAT st_stm32_bxcan From d53b1a1c0efcd784239d5a73eefd25a62ced6f30 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 9 Oct 2023 08:38:05 +0000 Subject: [PATCH 1781/4498] sensors: default_rtio_sensor: fix build warning Fix a build warning on 64 bit architectures: zephyr/drivers/sensor/default_rtio_sensor.c:238:17: error: format '%zu' expects argument of type 'size_t', but argument 2 has type 'uint32_t' {aka 'unsigned int'} num_channels type changed to uint32_t in 96175fcc47. Signed-off-by: Fabio Baltieri --- drivers/sensor/default_rtio_sensor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index 88d3196181a..e088b4f61c2 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -235,7 +235,7 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s } sample_idx += num_samples; } - LOG_DBG("Total channels in header: %zu", header->num_channels); + LOG_DBG("Total channels in header: %u", header->num_channels); rtio_iodev_sqe_ok(iodev_sqe, 0); } From b0a3736efff5fe142555f5f706a62e39433782f9 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 6 Oct 2023 20:30:20 -0400 Subject: [PATCH 1782/4498] doc: posix: add posix timers and clock selection Update the POSIX API documentation with details on POSIX_TIMERS and POSIX_CLOCK_SELECTION. Signed-off-by: Christopher Friedt --- doc/services/portability/posix.rst | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/services/portability/posix.rst b/doc/services/portability/posix.rst index 38be76f9118..392147594c8 100644 --- a/doc/services/portability/posix.rst +++ b/doc/services/portability/posix.rst @@ -85,11 +85,11 @@ Zephyr. :widths: 50,10 _POSIX_BARRIERS,yes - _POSIX_CLOCK_SELECTION, + _POSIX_CLOCK_SELECTION,yes _POSIX_FSYNC, _POSIX_MEMLOCK, _POSIX_MEMLOCK_RANGE, - _POSIX_MONOTONIC_CLOCK, + _POSIX_MONOTONIC_CLOCK,yes _POSIX_NO_TRUNC, _POSIX_REALTIME_SIGNALS, _POSIX_SEMAPHORES,yes @@ -104,7 +104,7 @@ Zephyr. _POSIX_THREAD_PRIORITY_SCHEDULING,yes _POSIX_THREAD_SPORADIC_SERVER, _POSIX_TIMEOUTS, - _POSIX_TIMERS, + _POSIX_TIMERS,yes _POSIX2_C_DEV, _POSIX2_SW_DEV, @@ -453,3 +453,31 @@ POSIX_DEVICE_IO vprintf(),yes vscanf(), write(),yes + +POSIX_TIMERS +++++++++++++ + +.. csv-table:: POSIX_TIMERS + :header: API, Supported + :widths: 50,10 + + clock_getres(), + clock_gettime(),yes + clock_settime(),yes + nanosleep(),yes + timer_create(),yes + timer_delete(),yes + timer_gettime(),yes + timer_getoverrun(),yes + timer_settime(),yes + +POSIX_CLOCK_SELECTION ++++++++++++++++++++++ + +.. csv-table:: POSIX_CLOCK_SELECTION + :header: API, Supported + :widths: 50,10 + + pthread_condattr_getclock(),yes + pthread_condattr_setclock(),yes + clock_nanosleep(),yes From 086dd2e03c6de591dc0f0371c2cf12a4648123a1 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 6 Oct 2023 20:38:26 -0400 Subject: [PATCH 1783/4498] doc: release: 3.5: add posix api release notes Add release notes with POSIX API updates for v3.5.0. Signed-off-by: Christopher Friedt --- doc/releases/release-notes-3.5.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index ee79befd6f9..eb3372efd7a 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -476,6 +476,25 @@ Libraries / Subsystems * Added the :ref:`binary_descriptors` (``bindesc``) subsystem. +* POSIX API + + * Added dynamic thread stack support for :c:func:`pthread_create` + * Fixed :c:func:`stat` so that it returns file stats instead of filesystem stats + * Implemented :c:func:`pthread_barrierattr_destroy`, :c:func:`pthread_barrierattr_getpshared`, + :c:func:`pthread_barrierattr_init`, :c:func:`pthread_barrierattr_setpshared`, + :c:func:`pthread_condattr_destroy`, :c:func:`pthread_condattr_init`, + :c:func:`pthread_mutexattr_destroy`, :c:func:`pthread_mutexattr_init`, :c:func:`uname`, + :c:func:`sigaddset`, :c:func:`sigdelset`, :c:func:`sigemptyset`, :c:func:`sigfillset`, + :c:func:`sigismember`, :c:func:`strsignal`, :c:func:`pthread_spin_destroy`, + :c:func:`pthread_spin_init`, :c:func:`pthread_spin_lock`, :c:func:`pthread_spin_trylock`, + :c:func:`pthread_spin_unlock`, :c:func:`timer_getoverrun`, :c:func:`pthread_condattr_getclock`, + :c:func:`pthread_condattr_setclock`, :c:func:`clock_nanosleep` + * Added support for querying the number of bytes available to read via the + :c:macro:`FIONREAD` request to :c:func:`ioctl` + * Added :kconfig:option:`CONFIG_FDTABLE` to conditionally compile file descriptor table + * Added logging to POSIX threads, mutexes, and condition variables + * Fixed :c:func:`poll` issue with event file descriptors + HALs **** From 9cd81c1640ed5d6a217450386b631c14fafb0437 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 6 Oct 2023 20:58:53 -0400 Subject: [PATCH 1784/4498] doc: release: 3.5: (partial) kernel release notes Include dynamic thread stack allocation and support for k_spin_trylock(). Signed-off-by: Christopher Friedt --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index eb3372efd7a..b88cb90636b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -47,6 +47,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html Kernel ****** +* Added support for dynamic thread stack allocation via :c:func:`k_thread_stack_alloc` +* Added support for :c:func:`k_spin_trylock` + Architectures ************* From 94bd09b1f8a7152bef9a4b4f628da5c5288bbefe Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 6 Oct 2023 20:15:08 +0200 Subject: [PATCH 1785/4498] tests: bluetooth: tester: Fix prov ctx init in PTS tests This fixes regression introduced in https://github.com/zephyrproject-rtos/zephyr/pull/63556 In the PR above `bt_mesh_init()` call was moved to `BTP_MESH_INIT` command to allow to select alternative composition data when starting the stack. AutoPTS sends `BTP_MESH_CONFIG_PROVISIONING` command before `BTP_MESH_INIT` to prepare the provisioning context. But because `bt_mesh_init()` is now called after `BTP_MESH_CONFIG_PROVISIONING` command is sent, this configuration is reset to the default which makes PTS tests to fail. To solve this, this commit calls introduces a new command, `BTP_MESH_START`, which will replace the original `BTP_MESH_INIT` command. `bt_mesh_init()` will stay in `BTP_MESH_INIT` while the stack will be started in `BTP_MESH_START` command. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 ++ tests/bluetooth/tester/src/btp_mesh.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index c2636d1445d..b5ab169b263 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -1038,6 +1038,8 @@ struct btp_proxy_solicit_cmd { uint16_t net_idx; } __packed; +#define BTP_MESH_START 0x78 + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 5f3492c45e5..c231c3dca38 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1289,6 +1289,14 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } + return BTP_STATUS_SUCCESS; +} + +static uint8_t start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + LOG_DBG(""); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { @@ -4945,6 +4953,11 @@ static const struct btp_handler handlers[] = { .func = proxy_solicit }, #endif + { + .opcode = BTP_MESH_START, + .expect_len = 0, + .func = start + }, }; From 80997cc98fb1fff44ebd5a0ee921bac692f6e797 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 9 Oct 2023 12:47:24 +0200 Subject: [PATCH 1786/4498] doc: release-notes: add EEPROM release notes for v3.5.0 Add EEPROM related release notes for Zephyr v3.5.0. Signed-off-by: Henrik Brix Andersen --- doc/releases/release-notes-3.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b88cb90636b..969f0f93d15 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -223,6 +223,8 @@ Drivers and Sensors * EEPROM + * Added support for Fujitsu MB85RCxx series I2C FRAM (:dtcompatible:`fujitsu,mb85rcxx`). + * Entropy * ESPI From 955d85aa6707cb4ce67d79508ea51856a9113f80 Mon Sep 17 00:00:00 2001 From: Al Semjonovs Date: Mon, 2 Oct 2023 11:55:05 -0600 Subject: [PATCH 1787/4498] libc: picolibc: Fix picolibc to allow third party CPP Picolibc dependencies limit ability to use third party minimal implementations of CPP when enablng PICOLIBC_USE_MODULE. Signed-off-by: Al Semjonovs --- cmake/linker/ld/target_cpp.cmake | 8 +++++--- lib/cpp/Kconfig | 7 ++++++- lib/libc/Kconfig | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmake/linker/ld/target_cpp.cmake b/cmake/linker/ld/target_cpp.cmake index 057bb02bc6d..a6601347172 100644 --- a/cmake/linker/ld/target_cpp.cmake +++ b/cmake/linker/ld/target_cpp.cmake @@ -4,8 +4,10 @@ macro(toolchain_ld_cpp) - zephyr_link_libraries( - -lstdc++ - ) + if(NOT CONFIG_EXTERNAL_MODULE_LIBCPP) + zephyr_link_libraries( + -lstdc++ + ) + endif() endmacro() diff --git a/lib/cpp/Kconfig b/lib/cpp/Kconfig index 52084fbe690..696df05102a 100644 --- a/lib/cpp/Kconfig +++ b/lib/cpp/Kconfig @@ -107,7 +107,12 @@ config ARCMWDT_LIBCPP config EXTERNAL_LIBCPP bool "External C++ standard library" help - Build with an external/user-provided C++ standard library. + Build and link with an external/user-provided C++ standard library. + +config EXTERNAL_MODULE_LIBCPP + bool "External C++ standard library module" + help + Build an external/user-provided C++ standard library. endchoice # LIBCPP_IMPLEMENTATION diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 7febf1574d4..3bb83af5b1e 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -36,7 +36,7 @@ config PICOLIBC_SUPPORTED bool depends on !NATIVE_APPLICATION depends on ("$(TOOLCHAIN_HAS_PICOLIBC)" = "y") || (NATIVE_LIBRARY) - depends on !(CPP && ("$(TOOLCHAIN_HAS_PICOLIBC)" = "y")) + depends on !REQUIRES_FULL_LIBCPP || ("$(TOOLCHAIN_HAS_PICOLIBC)" = "y") default y select FULL_LIBC_SUPPORTED help From ea753eb52a475fc1f518d00f8f2caac07223aebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Mon, 9 Oct 2023 08:28:26 +0200 Subject: [PATCH 1788/4498] Bluetooth: mesh: Change cfg_cli buffer length check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed buffer length check in bt_mesh_comp_p1_elem_pull. The previous threshold would result in the method not detecting the final element when it consisted of just one model. Signed-off-by: Håvard Reierstad --- subsys/bluetooth/mesh/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 68af4fae59d..c9f4f98f39d 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -2320,7 +2320,7 @@ struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_el struct bt_mesh_comp_p1_elem *bt_mesh_comp_p1_elem_pull(struct net_buf_simple *buf, struct bt_mesh_comp_p1_elem *elem) { - if (buf->len < 6) { + if (buf->len < 4) { LOG_DBG("No more elements to pull or missing data"); return NULL; } From 3d40d91f8682d023e939af4ef2cfe6509d17a3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Mon, 9 Oct 2023 08:28:26 +0200 Subject: [PATCH 1789/4498] Bluetooth: mesh: access: Fix model relation register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added offset to the model relation register for vendor models to find correct model index for Composition Data Page 1. The previous implementation used the 'mod_idx' from the 'bt_mesh_model' struct, which led to issues in the model relation register due to SIG and vender models having the same model index. Modified existing functions related to the model relation register to take in the offset. Modified macros for determining if a model is a base- or extending model. Added check in 'add_items_to_page' to check whether the model relation is an extension. Signed-off-by: Håvard Reierstad --- subsys/bluetooth/mesh/access.c | 92 +++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 2ea7ece90df..63c4f76c392 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -91,17 +91,13 @@ static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE]; mod_rel_list[(idx)].idx_ext == 0); \ (idx)++) -#define IS_MOD_BASE(mod, idx) \ +#define IS_MOD_BASE(mod, idx, offset) \ (mod_rel_list[(idx)].elem_base == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_base == (mod)->mod_idx && \ - !(mod_rel_list[(idx)].elem_ext != (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_ext != (mod)->mod_idx)) + mod_rel_list[(idx)].idx_base == (mod)->mod_idx + (offset)) -#define IS_MOD_EXTENSION(mod, idx) \ +#define IS_MOD_EXTENSION(mod, idx, offset) \ (mod_rel_list[(idx)].elem_ext == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_ext == (mod)->mod_idx && \ - !(mod_rel_list[(idx)].elem_base != (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_base != (mod)->mod_idx)) + mod_rel_list[(idx)].idx_ext == (mod)->mod_idx + (offset)) #define RELATION_TYPE_EXT 0xFF @@ -456,14 +452,14 @@ int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset) return 0; } -static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset) +static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset, uint8_t sig_offset) { int i; uint8_t extensions = 0; int8_t offset, offset_record = 0; MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i) && + if (IS_MOD_EXTENSION(mod, i, sig_offset) && mod_rel_list[i].type == RELATION_TYPE_EXT) { extensions++; offset = mod_rel_list[i].elem_ext - @@ -480,17 +476,18 @@ static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset) return extensions; } -static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id) +static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t sig_offset) { int i; - MOD_REL_LIST_FOR_EACH(i) { - if ((IS_MOD_BASE(mod, i) || IS_MOD_EXTENSION(mod, i)) && + MOD_REL_LIST_FOR_EACH(i) + { + if ((IS_MOD_BASE(mod, i, sig_offset) || + IS_MOD_EXTENSION(mod, i, sig_offset)) && mod_rel_list[i].type < RELATION_TYPE_EXT) { if (cor_id) { memcpy(cor_id, &mod_rel_list[i].type, sizeof(uint8_t)); } - return true; } } @@ -498,15 +495,15 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id) } static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t *mod_cnt, - struct net_buf_simple *buf, size_t *offset) + struct net_buf_simple *buf, size_t *offset, uint8_t sig_offset) { uint8_t ext_mod_cnt; bool cor_present; uint8_t mod_elem_info = 0; int8_t max_offset; - ext_mod_cnt = count_mod_ext(mod, &max_offset); - cor_present = is_cor_present(mod, cor_id); + ext_mod_cnt = count_mod_ext(mod, &max_offset, sig_offset); + cor_present = is_cor_present(mod, cor_id, sig_offset); mod_elem_info = ext_mod_cnt << 2; if (ext_mod_cnt > 31 || @@ -526,13 +523,14 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, u } static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod, - uint8_t ext_mod_cnt, size_t *offset) + uint8_t ext_mod_cnt, size_t *offset, uint8_t sig_offset) { int i, elem_offset; uint8_t mod_idx; MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i)) { + if (IS_MOD_EXTENSION(mod, i, sig_offset) && + mod_rel_list[i].type == RELATION_TYPE_EXT) { elem_offset = mod->elem_idx - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && @@ -557,18 +555,18 @@ static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model * } } -static size_t mod_items_size(struct bt_mesh_model *mod) +static size_t mod_items_size(struct bt_mesh_model *mod, uint8_t sig_offset) { int i, offset; size_t temp_size = 0; - int ext_mod_cnt = count_mod_ext(mod, NULL); + int ext_mod_cnt = count_mod_ext(mod, NULL, sig_offset); if (!ext_mod_cnt) { return 0; } MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i)) { + if (IS_MOD_EXTENSION(mod, i, sig_offset)) { offset = mod->elem_idx - mod_rel_list[i].elem_base; temp_size += (ext_mod_cnt < 32 && offset < 4 && offset > -5) ? 1 : 2; } @@ -582,13 +580,13 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) size_t temp_size = 2; for (int i = 0; i < elem->model_count; i++) { - temp_size += is_cor_present(&elem->models[i], NULL) ? 2 : 1; - temp_size += mod_items_size(&elem->models[i]); + temp_size += is_cor_present(&elem->models[i], NULL, 0) ? 2 : 1; + temp_size += mod_items_size(&elem->models[i], 0); } for (int i = 0; i < elem->vnd_model_count; i++) { - temp_size += is_cor_present(&elem->vnd_models[i], NULL) ? 2 : 1; - temp_size += mod_items_size(&elem->vnd_models[i]); + temp_size += is_cor_present(&elem->vnd_models[i], NULL, elem->model_count) ? 2 : 1; + temp_size += mod_items_size(&elem->vnd_models[i], elem->model_count); } return temp_size; @@ -630,19 +628,22 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse data_buf_add_u8_offset(buf, comp->elem[i].vnd_model_count, &offset); for (j = 0; j < comp->elem[i].model_count; j++) { prep_model_item_header(&comp->elem[i].models[j], &cor_id, &ext_mod_cnt, buf, - &offset); + &offset, 0); if (ext_mod_cnt != 0) { add_items_to_page(buf, &comp->elem[i].models[j], ext_mod_cnt, - &offset); + &offset, + 0); } } for (j = 0; j < comp->elem[i].vnd_model_count; j++) { prep_model_item_header(&comp->elem[i].vnd_models[j], &cor_id, &ext_mod_cnt, - buf, &offset); + buf, &offset, + comp->elem[i].model_count); if (ext_mod_cnt != 0) { add_items_to_page(buf, &comp->elem[i].vnd_models[j], ext_mod_cnt, - &offset); + &offset, + comp->elem[i].model_count); } } } @@ -1616,6 +1617,22 @@ void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, } #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS +/* For vendor models, determine the offset within the model relation list + * by counting the number of standard SIG models in the associated element. + */ +static uint8_t get_sig_offset(struct bt_mesh_model *mod) +{ + const struct bt_mesh_elem *elem = bt_mesh_model_elem(mod); + uint8_t i; + + for (i = 0U; i < elem->vnd_model_count; i++) { + if (&elem->vnd_models[i] == mod) { + return elem->model_count; + } + } + return 0; +} + static int mod_rel_register(struct bt_mesh_model *base, struct bt_mesh_model *ext, uint8_t type) @@ -1623,9 +1640,9 @@ static int mod_rel_register(struct bt_mesh_model *base, LOG_DBG(""); struct mod_relation extension = { base->elem_idx, - base->mod_idx, + base->mod_idx + get_sig_offset(base), ext->elem_idx, - ext->mod_idx, + ext->mod_idx + get_sig_offset(ext), type, }; int i; @@ -1696,16 +1713,19 @@ int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, return -ENOTSUP; } + uint8_t base_offset = get_sig_offset(base_mod); + uint8_t corresponding_offset = get_sig_offset(corresponding_mod); + MOD_REL_LIST_FOR_EACH(i) { if (mod_rel_list[i].type < RELATION_TYPE_EXT && mod_rel_list[i].type > cor_id) { cor_id = mod_rel_list[i].type; } - if ((IS_MOD_BASE(base_mod, i) || - IS_MOD_EXTENSION(base_mod, i) || - IS_MOD_BASE(corresponding_mod, i) || - IS_MOD_EXTENSION(corresponding_mod, i)) && + if ((IS_MOD_BASE(base_mod, i, base_offset) || + IS_MOD_EXTENSION(base_mod, i, base_offset) || + IS_MOD_BASE(corresponding_mod, i, corresponding_offset) || + IS_MOD_EXTENSION(corresponding_mod, i, corresponding_offset)) && mod_rel_list[i].type < RELATION_TYPE_EXT) { return mod_rel_register(base_mod, corresponding_mod, mod_rel_list[i].type); } From 5969ad7811100bc7ce239576b72d6d7312579be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Mon, 9 Oct 2023 08:28:26 +0200 Subject: [PATCH 1790/4498] bsim: Bluetooth: mesh: Implement CDP1 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds bsim test to verify that composition data page 1 (CDP1) is encoded and decoded correctly. Signed-off-by: Håvard Reierstad --- tests/bsim/bluetooth/mesh/CMakeLists.txt | 1 + tests/bsim/bluetooth/mesh/src/main.c | 2 + tests/bsim/bluetooth/mesh/src/test_cdp1.c | 434 ++++++++++++++++++ .../comp_data/cdp1_encode_decode.sh | 23 + 4 files changed, 460 insertions(+) create mode 100644 tests/bsim/bluetooth/mesh/src/test_cdp1.c create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/comp_data/cdp1_encode_decode.sh diff --git a/tests/bsim/bluetooth/mesh/CMakeLists.txt b/tests/bsim/bluetooth/mesh/CMakeLists.txt index bc528ae3f4b..44c72dd9cbb 100644 --- a/tests/bsim/bluetooth/mesh/CMakeLists.txt +++ b/tests/bsim/bluetooth/mesh/CMakeLists.txt @@ -79,6 +79,7 @@ else() src/test_blob.c src/test_op_agg.c src/test_sar.c + src/test_cdp1.c ) endif() diff --git a/tests/bsim/bluetooth/mesh/src/main.c b/tests/bsim/bluetooth/mesh/src/main.c index 97f8b34c5ca..127e52faa49 100644 --- a/tests/bsim/bluetooth/mesh/src/main.c +++ b/tests/bsim/bluetooth/mesh/src/main.c @@ -40,6 +40,7 @@ extern struct bst_test_list *test_adv_install(struct bst_test_list *test); extern struct bst_test_list *test_blob_install(struct bst_test_list *test); extern struct bst_test_list *test_op_agg_install(struct bst_test_list *test); extern struct bst_test_list *test_sar_install(struct bst_test_list *test); +extern struct bst_test_list *test_cdp1_install(struct bst_test_list *test); #endif /* defined(CONFIG_BT_MESH_V1d1) */ #endif @@ -76,6 +77,7 @@ bst_test_install_t test_installers[] = { test_blob_install, test_op_agg_install, test_sar_install, + test_cdp1_install, #endif /* defined(CONFIG_BT_MESH_V1d1) */ #endif NULL diff --git a/tests/bsim/bluetooth/mesh/src/test_cdp1.c b/tests/bsim/bluetooth/mesh/src/test_cdp1.c new file mode 100644 index 00000000000..7884ef17437 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/src/test_cdp1.c @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + * + * Composition Data Page 1 (CDP1) test + */ + +#include "mesh_test.h" + +#include +#include +#include +#include + +#include +#define LOG_MODULE_NAME test_cdp1 +LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); + +#define NODE_ADDR 0x00a1 +#define WAIT_TIME 60 /* seconds */ + +#define TEST_MODEL_ID_1 0x2a2a +#define TEST_MODEL_ID_2 0x2b2b +#define TEST_MODEL_ID_3 0x2c2c +#define TEST_MODEL_ID_4 0x2d2d +#define TEST_MODEL_ID_5 0x2e2e +#define TEST_MODEL_ID_6 0x2f2f +#define TEST_VND_MODEL_ID_1 0x3a3a + +#define TEST_MODEL_DECLARE(number) \ + static int model_##number##_init(struct bt_mesh_model *model); \ + static const struct bt_mesh_model_cb test_model_##number##_cb = { \ + .init = model_##number##_init, \ + }; \ + static const struct bt_mesh_model_op model_op_##number[] = { \ + BT_MESH_MODEL_OP_END, \ + }; + +TEST_MODEL_DECLARE(1); +TEST_MODEL_DECLARE(2); +TEST_MODEL_DECLARE(3); +TEST_MODEL_DECLARE(4); +TEST_MODEL_DECLARE(5); +TEST_MODEL_DECLARE(6); +TEST_MODEL_DECLARE(vnd1); + +static uint8_t app_key[16] = {0xaa}; +static uint8_t net_key[16] = {0xcc}; + +static const struct bt_mesh_test_cfg node_1_cfg = { + .addr = NODE_ADDR, + .dev_key = {0xaa}, +}; + +static struct bt_mesh_prov prov; +static struct bt_mesh_cfg_cli cfg_cli; + +static struct bt_mesh_model models_1[] = { + BT_MESH_MODEL_CFG_SRV, + BT_MESH_MODEL_CFG_CLI(&cfg_cli), + BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_op_1, NULL, NULL, &test_model_1_cb), + BT_MESH_MODEL_CB(TEST_MODEL_ID_2, model_op_2, NULL, NULL, &test_model_2_cb), + BT_MESH_MODEL_CB(TEST_MODEL_ID_3, model_op_3, NULL, NULL, &test_model_3_cb), +}; + +static struct bt_mesh_model models_2[] = { + BT_MESH_MODEL_CB(TEST_MODEL_ID_4, model_op_4, NULL, NULL, &test_model_4_cb), +}; + +static struct bt_mesh_model models_3[] = { + BT_MESH_MODEL_CB(TEST_MODEL_ID_5, model_op_5, NULL, NULL, &test_model_5_cb), +}; + +static struct bt_mesh_model models_4[] = { + BT_MESH_MODEL_CB(TEST_MODEL_ID_6, model_op_6, NULL, NULL, &test_model_6_cb), +}; + +static struct bt_mesh_model models_vnd1[] = { + BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MODEL_ID_1, model_op_vnd1, NULL, NULL, + &test_model_vnd1_cb), +}; + +static struct bt_mesh_elem elems[] = { + BT_MESH_ELEM(0, models_1, models_vnd1), + BT_MESH_ELEM(1, models_2, BT_MESH_MODEL_NONE), + BT_MESH_ELEM(2, models_3, BT_MESH_MODEL_NONE), + BT_MESH_ELEM(3, models_3, BT_MESH_MODEL_NONE), + BT_MESH_ELEM(4, models_4, BT_MESH_MODEL_NONE), +}; + +static const struct bt_mesh_comp comp = { + .cid = TEST_VND_COMPANY_ID, + .vid = 0xdead, + .pid = 0xface, + .elem = elems, + .elem_count = ARRAY_SIZE(elems), +}; + +/* The extensions and correspondence between models are as follows: + * Within elements: + * E0: M2 extends M1. VND1 extends M2. M3 and VND1 corresponds. + * + * Between elements: + * M3 on E0 extends M4 on E1. + * M2 on E0 and M4 on E1 corresponds. + * M6 on E4 extends M1 on E0 + */ +static int model_1_init(struct bt_mesh_model *model) +{ + return 0; +} + +static int model_2_init(struct bt_mesh_model *model) +{ + ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); + return 0; +} + +static int model_3_init(struct bt_mesh_model *model) +{ + return 0; +} + +static int model_4_init(struct bt_mesh_model *model) +{ + ASSERT_OK(bt_mesh_model_extend(bt_mesh_model_find(&elems[0], TEST_MODEL_ID_3), model)); + ASSERT_OK(bt_mesh_model_correspond(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_2))); + return 0; +} + +static int model_5_init(struct bt_mesh_model *model) +{ + return 0; +} + +static int model_6_init(struct bt_mesh_model *model) +{ + ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); + return 0; +} + +static int model_vnd1_init(struct bt_mesh_model *model) +{ + ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); + ASSERT_OK(bt_mesh_model_correspond(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_3))); + return 0; +} + +/* Hardcoded version of the CDP1 fields. + * Extensions are named extending-model_base-model. + */ + +static struct bt_mesh_comp_p1_ext_item test_p1_ext_mod2_mod1 = {.type = SHORT, + .short_item = { + .elem_offset = 0, + .mod_item_idx = 2, + }}; + +static struct bt_mesh_comp_p1_ext_item test_p1_ext_vnd1_mod1 = {.type = SHORT, + .short_item = { + .elem_offset = 0, + .mod_item_idx = 2, + }}; + +static struct bt_mesh_comp_p1_ext_item test_p1_ext_mod3_mod4 = {.type = SHORT, + .short_item = { + .elem_offset = 7, + .mod_item_idx = 0, + }}; + +static struct bt_mesh_comp_p1_ext_item test_p1_ext_mod6_mod1 = {.type = LONG, + .long_item = { + .elem_offset = 4, + .mod_item_idx = 2, + }}; + +static const struct bt_mesh_comp_p1_model_item test_p1_cfg_srv_mod = { + .cor_present = 0, + .format = 0, + .ext_item_cnt = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_cfg_cli_mod = { + .cor_present = 0, + .format = 0, + .ext_item_cnt = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod1 = { + .cor_present = 0, + .format = 0, + .ext_item_cnt = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod2 = { + .cor_present = 1, + .format = 0, + .ext_item_cnt = 1, + .cor_id = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod3 = { + .cor_present = 1, + .format = 0, + .ext_item_cnt = 1, + .cor_id = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod4 = { + .cor_present = 1, + .format = 0, + .ext_item_cnt = 0, + .cor_id = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod5 = { + .cor_present = 0, + .format = 0, + .ext_item_cnt = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_mod6 = { + .cor_present = 0, + .format = 1, + .ext_item_cnt = 1, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_vnd1 = { + .cor_present = 1, + .format = 0, + .ext_item_cnt = 1, + .cor_id = 0, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_elem0_models[] = { + test_p1_cfg_srv_mod, test_p1_cfg_cli_mod, test_p1_mod1, + test_p1_mod2, test_p1_mod3, test_p1_vnd1, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_elem1_models[] = { + test_p1_mod4, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_elem2_models[] = { + test_p1_mod5, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_elem3_models[] = { + test_p1_mod5, +}; + +static const struct bt_mesh_comp_p1_model_item test_p1_elem4_models[] = { + test_p1_mod6, +}; + +static const struct bt_mesh_comp_p1_model_item *test_p1_elem_models[] = { + test_p1_elem0_models, test_p1_elem1_models, test_p1_elem2_models, + test_p1_elem3_models, test_p1_elem4_models, +}; + +static const struct bt_mesh_comp_p1_elem test_p1_elem0 = { + .nsig = 5, + .nvnd = 1, +}; + +static const struct bt_mesh_comp_p1_elem test_p1_elem1 = { + .nsig = 1, + .nvnd = 0, +}; + +static const struct bt_mesh_comp_p1_elem test_p1_elem2 = { + .nsig = 1, + .nvnd = 0, +}; + +static const struct bt_mesh_comp_p1_elem test_p1_elem3 = { + .nsig = 1, + .nvnd = 0, +}; + +static const struct bt_mesh_comp_p1_elem test_p1_elem4 = { + .nsig = 1, + .nvnd = 0, +}; + +static struct bt_mesh_comp_p1_elem test_p1_elems[] = { + test_p1_elem0, test_p1_elem1, test_p1_elem2, test_p1_elem3, test_p1_elem4, +}; + +static void provision_and_configure(struct bt_mesh_test_cfg cfg) +{ + int err; + uint8_t status; + + err = bt_mesh_provision(net_key, 0, 0, 0, cfg.addr, cfg.dev_key); + if (err) { + FAIL("Provisioning failed (err %d)", err); + } + + err = bt_mesh_cfg_cli_app_key_add(0, cfg.addr, 0, 0, app_key, &status); + if (err || status) { + FAIL("AppKey add failed (err %d, status %u)", err, status); + } +} + +static void verify_model_item(struct bt_mesh_comp_p1_model_item *mod_item, int elem_idx, + int mod_idx, int offset) +{ + ASSERT_EQUAL(test_p1_elem_models[elem_idx][mod_idx + offset].cor_present, + mod_item->cor_present); + ASSERT_EQUAL(test_p1_elem_models[elem_idx][mod_idx + offset].format, mod_item->format); + ASSERT_EQUAL(test_p1_elem_models[elem_idx][mod_idx + offset].ext_item_cnt, + mod_item->ext_item_cnt); + if (mod_item->cor_present) { + ASSERT_EQUAL(test_p1_elem_models[elem_idx][mod_idx + offset].cor_id, + mod_item->cor_id); + } +} + +static void verify_ext_item(struct bt_mesh_comp_p1_ext_item *ext_item, int elem_idx, int mod_idx, + int offset) +{ + struct bt_mesh_comp_p1_ext_item *test_p1_ext_item; + + switch (elem_idx * 100 + (mod_idx + offset)) { + case 3: /* elem_idx=0, mod_idx=3, offset = 0 */ + test_p1_ext_item = &test_p1_ext_mod2_mod1; + break; + case 4: /* elem_idx=0, mod_idx=4, offset = 0 */ + test_p1_ext_item = &test_p1_ext_mod3_mod4; + break; + case 5: /* elem_idx=0, mod_idx=0, offset = 5 */ + test_p1_ext_item = &test_p1_ext_vnd1_mod1; + break; + case 400: /* elem_idx=4, mod_idx=0, offset = 0 */ + test_p1_ext_item = &test_p1_ext_mod6_mod1; + break; + default: + FAIL("Unexpected call to %s (elem %d, mod %d, offset %d)", __func__, elem_idx, + mod_idx, offset); + } + + ASSERT_EQUAL(test_p1_ext_item->type, ext_item->type); + if (ext_item->type == SHORT) { + ASSERT_EQUAL(test_p1_ext_item->short_item.elem_offset, + ext_item->short_item.elem_offset); + ASSERT_EQUAL(test_p1_ext_item->short_item.mod_item_idx, + ext_item->short_item.mod_item_idx); + } else { + ASSERT_EQUAL(test_p1_ext_item->long_item.elem_offset, + ext_item->long_item.elem_offset); + ASSERT_EQUAL(test_p1_ext_item->long_item.mod_item_idx, + ext_item->long_item.mod_item_idx); + } +} + +static void verify_cdp1(struct bt_mesh_comp_p1_elem *p1_elem, + struct bt_mesh_comp_p1_model_item *mod_item, + struct bt_mesh_comp_p1_ext_item *ext_item, + struct net_buf_simple *p1_dev_comp) +{ + int elem_idx = 0; + + while (bt_mesh_comp_p1_elem_pull(p1_dev_comp, p1_elem)) { + ASSERT_EQUAL(test_p1_elems[elem_idx].nsig, p1_elem->nsig); + ASSERT_EQUAL(test_p1_elems[elem_idx].nvnd, p1_elem->nvnd); + + for (int mod_idx = 0; mod_idx < p1_elem->nsig; mod_idx++) { + if (bt_mesh_comp_p1_item_pull(p1_elem, mod_item)) { + verify_model_item(mod_item, elem_idx, mod_idx, 0); + } + + for (int ext_mod_idx = 0; ext_mod_idx < mod_item->ext_item_cnt; + ext_mod_idx++) { + bt_mesh_comp_p1_pull_ext_item(mod_item, ext_item); + verify_ext_item(ext_item, elem_idx, mod_idx, 0); + } + } + + for (int mod_idx = 0; mod_idx < p1_elem->nvnd; mod_idx++) { + if (bt_mesh_comp_p1_item_pull(p1_elem, mod_item)) { + verify_model_item(mod_item, elem_idx, mod_idx, p1_elem->nsig); + } + + for (int ext_mod_idx = 0; ext_mod_idx < mod_item->ext_item_cnt; + ext_mod_idx++) { + bt_mesh_comp_p1_pull_ext_item(mod_item, ext_item); + verify_ext_item(ext_item, elem_idx, mod_idx, p1_elem->nsig); + } + } + elem_idx++; + } +} + +static void test_node_data_comparison(void) +{ + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_device_setup(&prov, &comp); + provision_and_configure(node_1_cfg); + + NET_BUF_SIMPLE_DEFINE(p1_dev_comp, 500); + uint8_t page_rsp; + + ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, node_1_cfg.addr, 1, &page_rsp, &p1_dev_comp)); + ASSERT_EQUAL(1, page_rsp); + + NET_BUF_SIMPLE_DEFINE(p1_buf, 500); + NET_BUF_SIMPLE_DEFINE(p1_item_buf, 500); + struct bt_mesh_comp_p1_elem p1_elem = {._buf = &p1_buf}; + struct bt_mesh_comp_p1_model_item mod_item = {._buf = &p1_item_buf}; + struct bt_mesh_comp_p1_ext_item ext_item = {0}; + + verify_cdp1(&p1_elem, &mod_item, &ext_item, &p1_dev_comp); + + PASS(); +} + +#define TEST_CASE(role, name, description) \ + { \ + .test_id = "cdp1_" #role "_" #name, .test_descr = description, \ + .test_tick_f = bt_mesh_test_timeout, .test_main_f = test_##role##_##name, \ + } + +static const struct bst_test_instance test_cdp1[] = { + TEST_CASE(node, data_comparison, "Compare encoded and decoded CDP1 data."), + + BSTEST_END_MARKER}; + +struct bst_test_list *test_cdp1_install(struct bst_test_list *tests) +{ + tests = bst_add_tests(tests, test_cdp1); + return tests; +} diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/comp_data/cdp1_encode_decode.sh b/tests/bsim/bluetooth/mesh/tests_scripts/comp_data/cdp1_encode_decode.sh new file mode 100755 index 00000000000..e4f99e80d5d --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/comp_data/cdp1_encode_decode.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that the composition data page 1 (CDP1) is encoded correctly. The +# composition consists of model extensions within and between elements, +# extensions requiring long and short formats, and correspondence between +# a SIG and vendor model. +# +# Test procedure: +# 0. Provisioning and setup. +# 1. Configuration client requests the node's CDP1. +# 2. The received CDP1 is compared to a hardcoded version. +conf=prj_mesh1d1_conf +RunTest mesh_cdp1_test \ + cdp1_node_data_comparison + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_cdp1_test_psa \ + cdp1_node_data_comparison From 73f45f65734012ddf2a64f90ccf8495b72b32588 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 4 Oct 2023 05:34:10 +0900 Subject: [PATCH 1791/4498] doc: migration-guide: add notes on SSD1306 Kconfig changes Some SSD1306 Kconfig options replaced by dts to make able to configure per device. Add the description how to migrate it. Signed-off-by: TOKITA Hiroshi --- doc/releases/migration-guide-3.5.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index a605fbefe59..0f6ab5d62e7 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -189,6 +189,24 @@ Required changes previous implementation, any application using them has to be changed accordingly. +* The configuration options for the SSD1306 display driver can now be provided + via the Devicetree binding :dtcompatible:`solomon,ssd1306fb`. The following + Kconfig options: ``CONFIG_SSD1306_DEFAULT``, + ``CONFIG_SSD1306_SH1106_COMPATIBLE``, and ``CONFIG_SSD1306_REVERSE_MODE`` have + been removed. + + * You can remove ``CONFIG_SSD1306_DEFAULT`` without any other modification. + + * ``CONFIG_SSD1306_SH1106_COMPATIBLE`` was used to assert that the device is + (compatible with) SH1106. This has been replaced by a dedicated dts + compatible declaration. You may update an existing sh1106 node to change the + ``compatible`` designation from :dtcompatible:`solomon,ssd1306fb` to + :dtcompatible:`sinowealth,sh1106`. + + * ``CONFIG_SSD1306_REVERSE_MODE`` is now set using the ``inversion-on`` + property of the devicetree node. + + Recommended Changes ******************* From a27d28172234bbb132eb7b9785f1899862ed6368 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 9 Oct 2023 12:43:00 +0200 Subject: [PATCH 1792/4498] doc: release-notes: add CAN release notes for v3.5.0 Add CAN related release notes for Zephyr v3.5.0. API changes are already described in the migration guide for v3.5.0. Signed-off-by: Henrik Brix Andersen --- doc/releases/release-notes-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 969f0f93d15..732d7bd06b4 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -201,6 +201,13 @@ Drivers and Sensors * CAN + * Added support for TI TCAN4x5x CAN-FD controller with integrated transceiver + (:dtcompatible:`ti,tcan4x5x`). + * Added support for Microchip MCP251xFD CAN-FD controller (:dtcompatible:`microchip,mcp251xfd`). + * Added support for CAN statistics to the Bosch M_CAN controller driver backend. + * Switched the NXP S32 CANXL driver to use clock control for the CAN clock instead of hard-coding + a CAN clock frequency in the devicetree. + * Clock control * Added support for Nuvoton NuMaker M46x From 28c9c7b41d5dda62a381a382f02743fc69b3545e Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 11:27:50 +0200 Subject: [PATCH 1793/4498] doc: release-notes: add regulator API changes Add relevant changes to the regulator area. Signed-off-by: Gerard Marull-Paretas --- doc/releases/release-notes-3.5.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 732d7bd06b4..fdcd3423a95 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -328,6 +328,20 @@ Drivers and Sensors * Regulators + * Added support for GPIO-controlled voltage regulator + + * Added support for AXP192 PMIC + + * Added support for NXP VREF regulator + + * Fixed regulators can now specify their operating voltage + + * PFM mode is now support for nPM1300 + + * Added new API to configure "ship" mode + + * Regulator shell allows to configure DVS modes + * Reset * Added support for Nuvoton NuMaker M46x From f7c21e5dd2a50ea8f8ce75b9538e0aab85010b2e Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 11:31:29 +0200 Subject: [PATCH 1794/4498] doc: release-notes: add documentation infra changes Only relevant thing: Sphinx upgrade. Signed-off-by: Gerard Marull-Paretas --- doc/releases/release-notes-3.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index fdcd3423a95..8024f0a0b49 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -617,6 +617,8 @@ zcbor Documentation ************* +* Upgraded Sphinx to 6.2 + Tests and Samples ***************** From 2d3ea64d056dd355d7d3f555ee2a12a862126cf1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 11:35:16 +0200 Subject: [PATCH 1795/4498] doc: migration-guide: inform about GPIO optional ops changes Related to https://github.com/zephyrproject-rtos/zephyr/pull/62394 changes. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 0f6ab5d62e7..7c30e0becba 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -207,6 +207,11 @@ Required changes property of the devicetree node. +* GPIO drivers not implementing IRQ related operations must now provide + ``NULL`` to the relevant operations: ``pin_interrupt_configure``, + ``manage_callback``, ``get_pending_int``. The public API will return + ``-ENOSYS`` when these are not available, instead of ``-ENOTSUP``. + Recommended Changes ******************* From c4a579c5da011dcfbece3414e27dc4ffdf63bdb7 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 11:49:37 +0200 Subject: [PATCH 1796/4498] doc: migration-guide: add PM/poweroff changes Inform about required changes related to PM/poweroff. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 7c30e0becba..ea2d046a2a5 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -212,6 +212,21 @@ Required changes ``manage_callback``, ``get_pending_int``. The public API will return ``-ENOSYS`` when these are not available, instead of ``-ENOTSUP``. +* Platforms that implement power management hooks must explicitly select + :kconfig:option:`CONFIG_HAS_PM` in Kconfig. This is now a dependency of + :kconfig:option:`CONFIG_PM`. Before this change all platforms could enable + :kconfig:option:`CONFIG_PM` because empty weak stubs were provided, however, + this is no longer supported. As a result of this change, power management + hooks are no longer defined as weaks. + +* Multiple platforms no longer support powering the system off using + :c:func:`pm_state_force`. The new :c:func:`sys_poweroff` API must be used. + Migrated platforms include Nordic nRF, STM32, ESP32 and TI CC13XX/26XX. The + new API is independent from :kconfig:option:`CONFIG_PM`. It requires + :kconfig:option:`CONFIG_POWEROFF` to be enabled, which depends on + :kconfig:option:`CONFIG_HAS_POWEROFF`, an option selected by platforms + implementing the required new hooks. + Recommended Changes ******************* From a7cbfa4970004f4d18a5f89d2a5c7eddda12a5e5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 12:08:56 +0200 Subject: [PATCH 1797/4498] doc: migration-guide: inform about NMI_INIT removal It may be needed by out-of-tree ARM SoCs. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index ea2d046a2a5..b6fe18ab672 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -227,6 +227,9 @@ Required changes :kconfig:option:`CONFIG_HAS_POWEROFF`, an option selected by platforms implementing the required new hooks. +* ARM SoC initialization routines no longer need to call `NMI_INIT()`. The + macro call has been removed as it was not doing anything useful. + Recommended Changes ******************* From f767cf48c99dbde5496ed288ccb87eccc953bac4 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 12:12:33 +0200 Subject: [PATCH 1798/4498] doc: migration-guide: inform about CMSIS header changes arch headers are deprecated, header in CMSIS glue code must be used instead. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index b6fe18ab672..67b525e78e8 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -285,3 +285,8 @@ Recommended Changes * ``prop-seg-data`` * ``phase-seg1-data`` * ``phase-seg1-data`` + +* ```` and + ```` are now deprecated in favor of + including ```` instead. The new header is part of the CMSIS glue + code in the ``modules`` directory. From 474aa963ff5248def83842f78e57634b64bb36ab Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 12:17:59 +0200 Subject: [PATCH 1799/4498] doc: migration-guide: inform about device dependencies changes Device dependencies are now optional, before they were always built. Signed-off-by: Gerard Marull-Paretas --- doc/releases/migration-guide-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 67b525e78e8..c49a64b037c 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -230,6 +230,11 @@ Required changes * ARM SoC initialization routines no longer need to call `NMI_INIT()`. The macro call has been removed as it was not doing anything useful. +* Device dependencies (incorrectly referred as "device handles" in some areas) + are now an optional feature enabled by :kconfig:option:`CONFIG_DEVICE_DEPS`. + This means that an extra linker stage is no longer necessary if this option is + not enabled. + Recommended Changes ******************* From 33bd2fed0887703183171ddcc2af0549da2f313d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Fri, 6 Oct 2023 11:35:40 +0200 Subject: [PATCH 1800/4498] task_wdt: fix race condition for task_wdt_add function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The task_wdt_add function changes the reload_period of the channel to a non-null value, which indicates that the channel is used. If the function is interrupted by a task_wdt_trigger running in ISR context before adding of the new channel has finished, the next timeout will be scheduled based on inconsistent channel data. Using a spinlock avoids such data races. Fixes #61004 Signed-off-by: Martin Jäger --- subsys/task_wdt/task_wdt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/subsys/task_wdt/task_wdt.c b/subsys/task_wdt/task_wdt.c index 035a26017be..b7171a14e23 100644 --- a/subsys/task_wdt/task_wdt.c +++ b/subsys/task_wdt/task_wdt.c @@ -39,6 +39,7 @@ struct task_wdt_channel { /* array of all task watchdog channels */ static struct task_wdt_channel channels[CONFIG_TASK_WDT_CHANNELS]; +static struct k_spinlock channels_lock; /* timer used for watchdog handling */ static struct k_timer timer; @@ -153,10 +154,18 @@ int task_wdt_init(const struct device *hw_wdt) int task_wdt_add(uint32_t reload_period, task_wdt_callback_t callback, void *user_data) { + k_spinlock_key_t key; + if (reload_period == 0) { return -EINVAL; } + /* + * k_spin_lock instead of k_sched_lock required here to avoid being interrupted by a + * triggering other task watchdog channel (executed in ISR context). + */ + key = k_spin_lock(&channels_lock); + /* look for unused channel (reload_period set to 0) */ for (int id = 0; id < ARRAY_SIZE(channels); id++) { if (channels[id].reload_period == 0) { @@ -176,21 +185,31 @@ int task_wdt_add(uint32_t reload_period, task_wdt_callback_t callback, /* must be called after hw wdt has been started */ task_wdt_feed(id); + k_spin_unlock(&channels_lock, key); + return id; } } + k_spin_unlock(&channels_lock, key); + return -ENOMEM; } int task_wdt_delete(int channel_id) { + k_spinlock_key_t key; + if (channel_id < 0 || channel_id >= ARRAY_SIZE(channels)) { return -EINVAL; } + key = k_spin_lock(&channels_lock); + channels[channel_id].reload_period = 0; + k_spin_unlock(&channels_lock, key); + return 0; } From ab15043b72d82268ced461281a6e51a6dc933416 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 4 Sep 2023 16:52:48 +0200 Subject: [PATCH 1801/4498] tests: Bluetooth: BAP Broadcast source id and BASE unit tests Add unit test to test the get_id and get_base functions. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 170 +++++++++++++++++- 1 file changed, 162 insertions(+), 8 deletions(-) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index a41fd8f219b..fab60070ba3 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -42,6 +42,10 @@ struct bap_broadcast_source_test_suite_fixture { static void bap_broadcast_source_test_suite_fixture_init( struct bap_broadcast_source_test_suite_fixture *fixture) { + const uint8_t bis_cfg_data[] = { + BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, + BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT), + }; const size_t streams_per_subgroup = CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT / CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; const enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; @@ -55,8 +59,10 @@ static void bap_broadcast_source_test_suite_fixture_init( const uint32_t pd = 40000U; /* us */ const uint16_t sdu = 40U; /* octets */ const uint8_t rtn = 2U; + uint8_t *bis_data; zassert_true(streams_per_subgroup > 0U); + zassert_true(sizeof(bis_cfg_data) <= CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE); /* Allocate memory for everything */ fixture->param = malloc(sizeof(struct bt_bap_broadcast_source_param)); @@ -72,6 +78,8 @@ static void bap_broadcast_source_test_suite_fixture_init( zassert_not_null(codec_qos); streams = malloc(sizeof(struct bt_bap_stream) * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); zassert_not_null(streams); + bis_data = malloc(CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE); + zassert_not_null(bis_data); /* Memset everything to 0 */ memset(fixture->param, 0, sizeof(*fixture->param)); @@ -84,10 +92,12 @@ static void bap_broadcast_source_test_suite_fixture_init( memset(codec_cfg, 0, sizeof(struct bt_audio_codec_cfg)); memset(codec_qos, 0, sizeof(struct bt_audio_codec_qos)); memset(streams, 0, sizeof(struct bt_bap_stream) * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT); + memset(bis_data, 0, CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE); /* Initialize default values*/ *codec_cfg = BT_AUDIO_CODEC_LC3_CONFIG_16_2(loc, ctx); *codec_qos = BT_AUDIO_CODEC_LC3_QOS_10_UNFRAMED(sdu, rtn, latency, pd); + memcpy(bis_data, bis_cfg_data, sizeof(bis_cfg_data)); for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT; i++) { subgroup_param[i].params_count = streams_per_subgroup; @@ -97,8 +107,8 @@ static void bap_broadcast_source_test_suite_fixture_init( for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT; i++) { stream_params[i].stream = &streams[i]; - stream_params[i].data = NULL; - stream_params[i].data_len = 0U; + stream_params[i].data = bis_data; + stream_params[i].data_len = sizeof(bis_cfg_data); bt_bap_stream_cb_register(stream_params[i].stream, &mock_bap_stream_ops); } @@ -131,6 +141,7 @@ static void bap_broadcast_source_test_suite_before(void *f) static void bap_broadcast_source_test_suite_after(void *f) { struct bap_broadcast_source_test_suite_fixture *fixture = f; + struct bt_bap_broadcast_source_param *param; if (fixture->source != NULL) { int err; @@ -142,12 +153,15 @@ static void bap_broadcast_source_test_suite_after(void *f) fixture->source = NULL; } - free(fixture->param->params[0].params[0].stream); - free(fixture->param->params[0].params); - free(fixture->param->params[0].codec_cfg); - free(fixture->param->params); - free(fixture->param->qos); - free(fixture->param); + param = fixture->param; + + free(param->params[0].params[0].data); + free(param->params[0].params[0].stream); + free(param->params[0].params); + free(param->params[0].codec_cfg); + free(param->params); + free(param->qos); + free(param); } static void bap_broadcast_source_test_suite_teardown(void *f) @@ -1048,3 +1062,143 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_delete_inval_doub err = bt_bap_broadcast_source_delete(source); zassert_not_equal(0, err, "Did not fail with deleting already deleting source"); } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_id) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + uint32_t broadcast_id; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_id(fixture->source, &broadcast_id); + zassert_equal(0, err, "Unable to get broadcast ID: err %d", err); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_single_bis) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + const uint8_t expected_base[] = { + 0x51, 0x18, /* uuid */ + 0x40, 0x9C, 0x00, /* pd */ + 0x01, /* subgroup count */ + 0x01, /* bis count */ + 0x06, 0x00, 0x00, 0x00, 0x00, /* LC3 codec_id*/ + 0x10, /* cc length */ + 0x02, 0x01, 0x03, 0x02, 0x02, 0x01, 0x05, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x04, 0x28, 0x00, /* cc */ + 0x04, /* meta length */ + 0x03, 0x02, 0x01, 0x00, /* meta */ + 0x01, /* bis index */ + 0x03, /* bis cc length */ + 0x02, 0x03, 0x03 /* bis cc length */ + }; + + NET_BUF_SIMPLE_DEFINE(base_buf, 64); + + /* Make the create param simpler for verification */ + create_param->params_count = 1U; + create_param->params[0].params_count = 1U; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_base(fixture->source, &base_buf); + zassert_equal(0, err, "Unable to get broadcast source BASE: err %d", err); + + zassert_equal(sizeof(expected_base), base_buf.len, "Incorrect base_buf.len %u, expected %u", + base_buf.len, sizeof(expected_base)); + + /* Use memcmp to print the buffers if they are not identical as zassert_mem_equal does not + * do that + */ + if (memcmp(expected_base, base_buf.data, base_buf.len) != 0) { + for (size_t i = 0U; i < base_buf.len; i++) { + printk("[%zu]: 0x%02X %s 0x%02X\n", i, expected_base[i], + expected_base[i] == base_buf.data[i] ? "==" : "!=", + base_buf.data[i]); + } + + zassert_mem_equal(expected_base, base_buf.data, base_buf.len); + } + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + const uint8_t expected_base[] = { + 0x51, 0x18, /* uuid */ + 0x40, 0x9C, 0x00, /* pd */ + 0x02, /* subgroup count */ + 0x01, /* Subgroup 1: bis count */ + 0x06, 0x00, 0x00, 0x00, 0x00, /* LC3 codec_id*/ + 0x10, /* cc length */ + 0x02, 0x01, 0x03, 0x02, 0x02, 0x01, 0x05, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x04, 0x28, 0x00, /* cc */ + 0x04, /* meta length */ + 0x03, 0x02, 0x01, 0x00, /* meta */ + 0x01, /* bis index */ + 0x03, /* bis cc length */ + 0x02, 0x03, 0x03, /* bis cc length */ + 0x01, /* Subgroup 1: bis count */ + 0x06, 0x00, 0x00, 0x00, 0x00, /* LC3 codec_id*/ + 0x10, /* cc length */ + 0x02, 0x01, 0x03, 0x02, 0x02, 0x01, 0x05, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x04, 0x28, 0x00, /* cc */ + 0x04, /* meta length */ + 0x03, 0x02, 0x01, 0x00, /* meta */ + 0x02, /* bis index */ + 0x03, /* bis cc length */ + 0x02, 0x03, 0x03 /* bis cc length */ + }; + + NET_BUF_SIMPLE_DEFINE(base_buf, 128); + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_base(fixture->source, &base_buf); + zassert_equal(0, err, "Unable to get broadcast source BASE: err %d", err); + + zassert_equal(sizeof(expected_base), base_buf.len, "Incorrect base_buf.len %u, expected %u", + base_buf.len, sizeof(expected_base)); + + /* Use memcmp to print the buffers if they are not identical as zassert_mem_equal does not + * do that + */ + if (memcmp(expected_base, base_buf.data, base_buf.len) != 0) { + for (size_t i = 0U; i < base_buf.len; i++) { + printk("[%zu]: 0x%02X %s 0x%02X\n", i, expected_base[i], + expected_base[i] == base_buf.data[i] ? "==" : "!=", + base_buf.data[i]); + } + + zassert_mem_equal(expected_base, base_buf.data, base_buf.len); + } + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} From 68365d5b67057c8e960a5168c2cf99f4b8c457c1 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Mon, 9 Oct 2023 09:47:17 +0200 Subject: [PATCH 1802/4498] Bluetooth: Mesh: Reset targets state before starting DFU on DFD srv The list of receives in the Firmware Distribution Server model and and the Firmware Update Client model are 2 different lists. In the Firmware Update Client model it is called the Update Receives state and the Active Update Receivers state which is a subset of receivers from the Update Receivers State. In the Firmware Distribution Server model it is called the Distribution Receivers List state. When Distribute Firmware procedure starts, in the Initiate step, the Receivers List input (which is the input for the Update Receivers state), is composed of the Distribution Receives List state. During DFU, the Update Receivers state becomes the Active Update Receivers state which keeps only active nodes. Timed out or failed nodes dropped out from this list. The Distribution Receivers List state stays unchanged and thus don't need to be populated again after every successfull and failed DFU. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 59fe5b830d1..5d3ada4b4aa 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -1015,6 +1015,13 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv, sys_slist_init(&srv->inputs.targets); for (i = 0; i < srv->target_cnt; i++) { + uint16_t addr = srv->targets[i].blob.addr; + + memset(&srv->targets[i].blob, 0, sizeof(struct bt_mesh_blob_target)); + memset(&srv->pull_ctxs[i], 0, sizeof(struct bt_mesh_blob_target_pull)); + srv->targets[i].blob.addr = addr; + srv->targets[i].blob.pull = &srv->pull_ctxs[i]; + sys_slist_append(&srv->inputs.targets, &srv->targets[i].blob.n); } From 32b27384a68f250a1279246dd50a9455eba86d81 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Thu, 5 Oct 2023 16:59:58 -0600 Subject: [PATCH 1803/4498] fuel_gauge: Fix desired current/voltage units The desired current/voltage properties make use of milliamps/volts while the present current/voltage properties make use of microamps/volts. Fix the desired current/voltage properties to be consistent with the present current/voltage properties where they're most likely to be used with. Signed-off-by: Aaron Massey --- drivers/fuel_gauge/bq27z746/bq27z746.c | 4 ++-- drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 4 ++-- include/zephyr/drivers/fuel_gauge.h | 8 ++++---- tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/fuel_gauge/bq27z746/bq27z746.c b/drivers/fuel_gauge/bq27z746/bq27z746.c index b028e590b1c..98918faaa76 100644 --- a/drivers/fuel_gauge/bq27z746/bq27z746.c +++ b/drivers/fuel_gauge/bq27z746/bq27z746.c @@ -175,11 +175,11 @@ static int bq27z746_get_prop(const struct device *dev, fuel_gauge_prop_t prop, break; case FUEL_GAUGE_CHARGE_VOLTAGE: rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &tmp_val); - val->chg_voltage = tmp_val; + val->chg_voltage = tmp_val * 1000; break; case FUEL_GAUGE_CHARGE_CURRENT: rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &tmp_val); - val->chg_current = tmp_val; + val->chg_current = tmp_val * 1000; break; case FUEL_GAUGE_STATUS: rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &tmp_val); diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index 01740f858f9..4c9ba6702aa 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -127,11 +127,11 @@ static int sbs_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, break; case FUEL_GAUGE_CHARGE_CURRENT: rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_CURRENT, &tmp_val); - val->chg_current = tmp_val; + val->chg_current = tmp_val * 1000; break; case FUEL_GAUGE_CHARGE_VOLTAGE: rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_VOLTAGE, &tmp_val); - val->chg_voltage = tmp_val; + val->chg_voltage = tmp_val * 1000; break; case FUEL_GAUGE_STATUS: rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FLAGS, &tmp_val); diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 81bffc11ae8..2b86c16f565 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -72,9 +72,9 @@ enum fuel_gauge_prop_type { FUEL_GAUGE_VOLTAGE, /** Battery Mode (flags) */ FUEL_GAUGE_SBS_MODE, - /** Battery desired Max Charging Current (mA) */ + /** Battery desired Max Charging Current (uA) */ FUEL_GAUGE_CHARGE_CURRENT, - /** Battery desired Max Charging Voltage (mV) */ + /** Battery desired Max Charging Voltage (uV) */ FUEL_GAUGE_CHARGE_VOLTAGE, /** Alarm, Status and Error codes (flags) */ FUEL_GAUGE_STATUS, @@ -153,9 +153,9 @@ union fuel_gauge_prop_val { /** FUEL_GAUGE_SBS_MODE */ uint16_t sbs_mode; /** FUEL_GAUGE_CHARGE_CURRENT */ - uint16_t chg_current; + uint32_t chg_current; /** FUEL_GAUGE_CHARGE_VOLTAGE */ - uint16_t chg_voltage; + uint32_t chg_voltage; /** FUEL_GAUGE_STATUS */ uint16_t fg_status; /** FUEL_GAUGE_DESIGN_CAPACITY */ diff --git a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c index 644d66c7b6c..a45dc096008 100644 --- a/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c +++ b/tests/drivers/fuel_gauge/bq27z746/src/test_bq27z746.c @@ -139,8 +139,8 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok) zassert_equal(vals[10].voltage, 1000); zassert_equal(vals[11].sbs_at_rate, -2); zassert_equal(vals[12].sbs_at_rate_time_to_empty, 1); - zassert_equal(vals[13].chg_voltage, 1); - zassert_equal(vals[14].chg_current, 1); + zassert_equal(vals[13].chg_voltage, 1000); + zassert_equal(vals[14].chg_current, 1000); zassert_equal(vals[15].fg_status, 1); zassert_equal(vals[16].design_cap, 1); #else From 771770a772318e49611eacf6947a40ad5d433e67 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Fri, 6 Oct 2023 08:25:45 -0600 Subject: [PATCH 1804/4498] fuel_gauge: Remove keep alphabetized comment The fuel gauge header asks to alphabetize the properties in order to keep them organized and easy to read. However, this is difficult to enforce without adding an adhoc script for just this header. In addition, there aren't so many properties such that it's difficult to parse unsorted. Since the alphabetization is already not followed and not likely to be easily followed in the future, remove this ask from the header. Remove "keep properties alphabetized" from the header. Signed-off-by: Aaron Massey --- include/zephyr/drivers/fuel_gauge.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 2b86c16f565..760201d6f76 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -26,8 +26,6 @@ extern "C" { #include -/* Keep these alphabetized wrt property name */ - enum fuel_gauge_prop_type { /** Runtime Dynamic Battery Parameters */ /** From 8203646cc48c5bfe224b5b5dd2e7dec78e0b1b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Tue, 3 Oct 2023 08:25:58 +0200 Subject: [PATCH 1805/4498] boards: arm: nrf9161dk_nrf9161: Add ext flash support for 0.7.0 version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for external flash on the 0.7.0 DK version. Signed-off-by: Eivind Jølsgard --- .../nrf9161dk_nrf9161_0_7_0.overlay | 7 +++++ .../nrf9161dk_nrf9161_common_0_7_0.dtsi | 31 +++++++++++++++++++ .../nrf9161dk_nrf9161_ns_0_7_0.overlay | 7 +++++ boards/arm/nrf9161dk_nrf9161/revision.cmake | 8 +++++ 4 files changed, 53 insertions(+) create mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay create mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi create mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay create mode 100644 boards/arm/nrf9161dk_nrf9161/revision.cmake diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay new file mode 100644 index 00000000000..22e9f970dab --- /dev/null +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf9161dk_nrf9161_common_0_7_0.dtsi" diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi new file mode 100644 index 00000000000..ae67df77b22 --- /dev/null +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi3 { + gd25lb256: gd25lb256e3ir@1 { + compatible = "jedec,spi-nor"; + status = "okay"; + reg = <1>; + spi-max-frequency = <60000000>; + jedec-id = [c8 67 19]; + sfdp-bfp = [ + e5 20 ea ff ff ff ff 0f 44 eb 08 6b 00 3b 00 bb + fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 + 10 d8 00 ff d5 31 b1 fe 82 e4 14 4c ec 60 06 33 + 7a 75 7a 75 04 bd d5 5c 29 06 74 00 08 50 00 01 + ]; + size = <268435456>; + has-dpd; + t-enter-dpd = <3000>; + t-exit-dpd = <30000>; + }; +}; + +/ { + aliases { + spi-flash0 = &gd25lb256; + }; +}; diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay new file mode 100644 index 00000000000..22e9f970dab --- /dev/null +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf9161dk_nrf9161_common_0_7_0.dtsi" diff --git a/boards/arm/nrf9161dk_nrf9161/revision.cmake b/boards/arm/nrf9161dk_nrf9161/revision.cmake new file mode 100644 index 00000000000..2a899f61a83 --- /dev/null +++ b/boards/arm/nrf9161dk_nrf9161/revision.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +board_check_revision( + FORMAT MAJOR.MINOR.PATCH + DEFAULT_REVISION 0.9.0 + VALID_REVISIONS 0.7.0 0.9.0 +) From e5240422cb0216f7a54151bc7c571ba62ee2f51b Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Mon, 9 Oct 2023 10:50:12 +0200 Subject: [PATCH 1806/4498] Bluetooth: hci_driver: Require coop prio bt_recv Document the general consensus among maintainers that `bt_recv` may not be called from preemptible priorites. Signed-off-by: Aleksander Wasaznik --- include/zephyr/drivers/bluetooth/hci_driver.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/drivers/bluetooth/hci_driver.h b/include/zephyr/drivers/bluetooth/hci_driver.h index 3774c8264ad..c305ecc37c3 100644 --- a/include/zephyr/drivers/bluetooth/hci_driver.h +++ b/include/zephyr/drivers/bluetooth/hci_driver.h @@ -89,6 +89,8 @@ static inline uint8_t bt_hci_evt_get_flags(uint8_t evt) * for so-called high priority HCI events, which should instead be delivered to * the host stack through bt_recv_prio(). * + * @note This function must only be called from a cooperative thread. + * * @param buf Network buffer containing data from the controller. * * @return 0 on success or negative error number on failure. From f187d1bdf4394a5dedd78a2fcfa26bfd3c1d61ef Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Mon, 9 Oct 2023 10:50:12 +0200 Subject: [PATCH 1807/4498] Bluetooth: drivers/rpmsg: Ensure coop prio bt_recv Ensure that the Bluetooth rpmsg driver thread is temporarly in cooperative mode using `k_sched_lock`. The previous commit added the documentation on `bt_recv` stemming from the general consensus among maintainers that `bt_recv` may not be called from preemptible priorites. Many uses may be affected by this race condition, since the default configuration of rpmsg driver selects a preemtible priority. Signed-off-by: Aleksander Wasaznik --- drivers/bluetooth/hci/rpmsg.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index 9025791f1c0..b3611f5f3e2 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -230,7 +230,18 @@ static void bt_rpmsg_rx(const uint8_t *data, size_t len) if (buf) { LOG_DBG("Calling bt_recv(%p)", buf); + /* The IPC service does not guarantee that the handler thread + * is cooperative. In particular, the OpenAMP implementation is + * preemtible by default. OTOH, the HCI driver interface requires + * that the bt_recv() function is called from a cooperative + * thread. + * + * Calling `k_sched lock()` has the effect of making the current + * thread cooperative. + */ + k_sched_lock(); bt_recv(buf); + k_sched_unlock(); LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:"); } From 9473b638b686c06069f0e87bc7c67613cf638442 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 9 Oct 2023 16:47:00 +0200 Subject: [PATCH 1808/4498] doc: release-notes: Add 3.5.0 release notes for nanopb Added section for nanopb changes done for release 3.5.0. Signed-off-by: Pieter De Gendt --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 8024f0a0b49..b2f3633fd65 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -600,6 +600,15 @@ MCUboot * The MCUboot version in this release is version ``2.0.0+0-rc1``. +Nanopb +****** + + * Changed project status to maintained. + + * Added a separate nanopb.cmake file to be included by applications. + + * Added helper cmake function ``zephyr_nanopb_sources`` to simplify ``.proto`` file inclusion. + Storage ******* From f09b67b304dd11fd7f7adaedd1865eec3a5f868a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 9 Oct 2023 15:36:57 +0200 Subject: [PATCH 1809/4498] doc: release: Fix formatting of bullet lists Without the extra newline, Sphinx does not render bullet lists correctly. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-3.5.rst | 1 + doc/releases/release-notes-3.5.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index c49a64b037c..d311ad41917 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -282,6 +282,7 @@ Recommended Changes * The following CAN controller devicetree properties are now deprecated in favor specifying the initial CAN bitrate using the ``bus-speed``, ``sample-point``, ``bus-speed-data``, and ``sample-point-data`` properties: + * ``sjw`` * ``prop-seg`` * ``phase-seg1`` diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b2f3633fd65..216fc8aeb57 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -415,6 +415,7 @@ Networking * Added new :c:macro:`LWM2M_RD_CLIENT_EVENT_DEREGISTER` event. * Wi-Fi + * Added Passive scan support. * The Wi-Fi scan API updated with Wi-Fi scan parameter to allow scan mode selection. From fc078f9d0239d6ba0cb2ea78ec0ab93fe80e63da Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 9 Oct 2023 21:37:52 +0200 Subject: [PATCH 1810/4498] drivers: can: sja1000: do not attempt to sleep in IRQ context The can_sja1000_handle_error_warning_irq() function should only attempt to start bus-off recovery, but not wait for the result. Fixes: #63712 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_sja1000.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index d7287fa2451..b7a415df59e 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -53,6 +53,14 @@ static inline int can_sja1000_enter_reset_mode(const struct device *dev) return 0; } +static inline void can_sja1000_leave_reset_mode_nowait(const struct device *dev) +{ + uint8_t mod; + + mod = can_sja1000_read_reg(dev, CAN_SJA1000_MOD); + can_sja1000_write_reg(dev, CAN_SJA1000_MOD, mod & ~(CAN_SJA1000_MOD_RM)); +} + static inline int can_sja1000_leave_reset_mode(const struct device *dev) { int retries = CAN_SJA1000_RESET_MODE_RETRIES; @@ -590,7 +598,7 @@ static void can_sja1000_handle_error_warning_irq(const struct device *dev) can_sja1000_tx_done(dev, -ENETUNREACH); #ifdef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY if (data->started) { - (void)can_sja1000_leave_reset_mode(dev); + can_sja1000_leave_reset_mode_nowait(dev); } #endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */ } else if ((sr & CAN_SJA1000_SR_ES) != 0) { From cf75c88a6154ab5599257091c6b6b722c1059bdd Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 4 Oct 2023 11:32:08 +0000 Subject: [PATCH 1811/4498] tests: newlib/thread_safety: exclude acrn_ehl_crb from more tests This was already excluded from libraries.libc.newlib_nano.thread_safety.userspace.stress and it's now failing in libraries.libc.newlib.thread_safety.userspace.stress as well. The issue is being rootcaused to a toolchain issue but a proper fix has not been identified yet, exclude that test as well in the meantime. Link: https://github.com/zephyrproject-rtos/zephyr/issues/61129 Signed-off-by: Fabio Baltieri --- tests/lib/newlib/thread_safety/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/newlib/thread_safety/testcase.yaml b/tests/lib/newlib/thread_safety/testcase.yaml index 334e8568eba..a798336ec49 100644 --- a/tests/lib/newlib/thread_safety/testcase.yaml +++ b/tests/lib/newlib/thread_safety/testcase.yaml @@ -31,6 +31,7 @@ tests: - userspace min_ram: 192 timeout: 120 + platform_exclude: acrn_ehl_crb # See #61129 libraries.libc.newlib_nano.thread_safety: extra_configs: - CONFIG_NEWLIB_LIBC_NANO=y From d52cb2202fd1239b106a3a3b730ec2dd6ef5a1ee Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 9 Oct 2023 11:30:16 +0300 Subject: [PATCH 1812/4498] doc: release: 3.5: Add Ethernet and Wi-Fi info Add changes to Ethernet and Wi-Fi drivers for v3.5. Also add information about generic Ethernet and Wi-Fi changes. Signed-off-by: Jukka Rissanen --- doc/releases/release-notes-3.5.rst | 42 +++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 216fc8aeb57..cd7c1307c26 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -239,6 +239,23 @@ Drivers and Sensors * Ethernet * Added :kconfig:option:`CONFIG_ETH_NATIVE_POSIX_RX_TIMEOUT` to set rx timeout for native posix. + * Added support for adin2111. + * Added support for NXP S32 GMAC. + * Added support for promiscuous mode in eth_smsc91x. + * Added support for STM32H5X SOC series. + * Added support for MDIO Clause 45 APIs. + * Added support for YD-ESP32 board Ethernet. + * Fixed stm32 to generate more unique MAC address by using device id as a base for the MAC. + * Fixed mcux to increase the PTP timestamp accuracy from 20us to 200ns. + * Fixed Ethernet max header size when using VLAN. + * Removed the ``mdio`` DT property. Please use :c:macro:`DT_INST_BUS()` in the driver instead. + * Reworked the device node hierarchy in smsc91x. + * Renamed the phy-dev property with phy-handle to match the Linux ethernet-controller binding + and move it up to ethernet.yaml so that it can be used by other drivers. + * Updated Ethernet PHY to use ``reg`` property in DT bindings. + * Updated driver DT bindings to use ``ethernet-phy`` devicetree node name consistently. + * Updated esp32 and sam-gmac DT so that the phy is pointed by a phandle rather than + a child node, this makes the phy device a child of mdio. * Flash @@ -390,6 +407,13 @@ Drivers and Sensors * WiFi + * Increased esp32 default network (TCP workq, RX and mgmt event) stack sizes to 2048 bytes. + * Reduced the RAM usage for esp32s2_saola in Wi-Fi samples. + * Fixed undefined declarations in winc1500. + * Fixed SPI buffer length in eswifi. + * Fixed esp32 data sending and channel selection in AP mode. + * Fixed esp_at driver init and network interface dormant state setting. + Networking ********** @@ -407,6 +431,16 @@ Networking devices that stay on for more than 49 days when the 32 bit uptime counter might roll over and cause CoAP packets to not timeout at all on this event. +* Ethernet: + + * Fixed ARP queueing so that the queued network packet is sent immediately + instead of queued 2nd time in the core network stack. + +* gPTP: + + * Added support for detecting gPTP packets that use the default multicast destination address. + * Fixed Announce and Follow Up message handling. + * LwM2M: * Added support for tickless mode. This removes the 500 ms timeout from the socket loop @@ -414,10 +448,16 @@ Networking :kconfig:option:`CONFIG_LWM2M_TICKLESS`. * Added new :c:macro:`LWM2M_RD_CLIENT_EVENT_DEREGISTER` event. -* Wi-Fi +* Wi-Fi: * Added Passive scan support. * The Wi-Fi scan API updated with Wi-Fi scan parameter to allow scan mode selection. + * Updated TWT handling. + * Added support for generic network manager API. + * Added support for Wi-Fi mode setting and selection. + * Added user input validation for SSID and PSK in Wi-Fi shell. + * Added scan extension for specifying channels, limiting scan results, filtering SSIDs, + setting active and passive channel dwell times and frequency bands. USB *** From 4c269d0d61af85ff261d46b8c84892cb09f3bcfc Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 9 Oct 2023 17:22:16 +0200 Subject: [PATCH 1813/4498] tests: bluetooth: tester: Increase BT RX thread stack Default stack size if not enought and was causing MPU faults. This was affecting GATT/SR/GAW/BV-14-C qualification test case. bttester_gatt: gatt_db_add: handle 0x0000 os: ***** MPU FAULT ***** os: Stacking error (context area might be not valid) os: Data Access Violation os: MMFAR Address: 0x2000aa38 os: r0/a1: 0x00000000 r1/a2: 0x00000000 r2/a3: 0x00000000 os: r3/a4: 0x00000000 r12/ip: 0x00000000 r14/lr: 0x00000000 os: xpsr: 0x00000000 os: Faulting instruction address (r15/pc): 0x00000000 os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0 os: Current thread: 0x20002d28 (BT RX) os: Halting system Signed-off-by: Szymon Janc --- tests/bluetooth/tester/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/bluetooth/tester/prj.conf b/tests/bluetooth/tester/prj.conf index 58e8cdc34a1..b24eca84c6a 100644 --- a/tests/bluetooth/tester/prj.conf +++ b/tests/bluetooth/tester/prj.conf @@ -32,6 +32,7 @@ CONFIG_BT_ATT_RETRY_ON_SEC_ERR=n CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_EXT_ADV=y CONFIG_BT_BUF_ACL_RX_SIZE=100 +CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_BT_TINYCRYPT_ECC=y CONFIG_BT_TESTING=y From 1a00636895ad3b661105f4e206e1bc067b09cb6c Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 3 Oct 2023 13:36:40 +0200 Subject: [PATCH 1814/4498] samples: tfm_regression_test: Provide a working partition for nucleo_l5 This partition is designed to work regression TFM configuration. Fixes #59794 Signed-off-by: Erwan Gouriou --- .../boards/nucleo_l552ze_q_ns.overlay | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 samples/tfm_integration/tfm_regression_test/boards/nucleo_l552ze_q_ns.overlay diff --git a/samples/tfm_integration/tfm_regression_test/boards/nucleo_l552ze_q_ns.overlay b/samples/tfm_integration/tfm_regression_test/boards/nucleo_l552ze_q_ns.overlay new file mode 100644 index 00000000000..01744d106f4 --- /dev/null +++ b/samples/tfm_integration/tfm_regression_test/boards/nucleo_l552ze_q_ns.overlay @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + + + /* This partition table could be used along with TFM configuration: + * - TEST_S=ON (REGRESSION) + * - TFM_PSA_API=ON (IPC) + * + */ + +/ { + chosen { + zephyr,code-partition = &slot1_partition; + }; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(80)>; + read-only; + }; + /* Secure image primary slot */ + slot0_partition: partition@14000 { + label = "image-0"; + reg = <0x00014000 DT_SIZE_K(224)>; + }; + /* Non-secure image primary slot */ + slot1_partition: partition@4c000 { + label = "image-1"; + reg = <0x0004c000 DT_SIZE_K(172)>; + }; + /* + * The flash starting at 0x7F000 and ending at + * 0x80000 is reserved for the application. + */ + storage_partition: partition@77000 { + label = "storage"; + reg = <0x0007F000 DT_SIZE_K(40)>; + }; + }; +}; From daf6de7b993d57b70cb9162cc717c2d6a160d24e Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 6 Oct 2023 12:33:16 -0500 Subject: [PATCH 1815/4498] drivers: flash: flexspi_mx25um513: enforce write size limit in DTR mode Per the MX25UM51325G datasheet, all page programs in OPI DTR mode need to start at an even address, and be of even length. Update the minimum write size reported by the driver and check all writes when OPI DTR mode is enabled, so that subsystems using the flash driver can align to this requirement. Fixes #63639 Signed-off-by: Daniel DeGrasse --- drivers/flash/flash_mcux_flexspi_mx25um51345g.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c index 0caa535529c..be3b59dcf12 100644 --- a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c +++ b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c @@ -17,7 +17,6 @@ #include #endif -#define NOR_WRITE_SIZE 1 #define NOR_ERASE_VALUE 0xff #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER @@ -40,8 +39,11 @@ static uint8_t nor_write_buf[SPI_NOR_PAGE_SIZE]; /* FLASH_ENABLE_OCTAL_CMD: (01 = STR OPI Enable) , (02 = DTR OPI Enable) */ #if CONFIG_FLASH_MCUX_FLEXSPI_MX25UM51345G_OPI_DTR #define NOR_FLASH_ENABLE_OCTAL_CMD 0x2 +/* In OPI DTR mode, all writes must be 2 byte aligned, and multiples of 2 bytes */ +#define NOR_WRITE_SIZE 2 #else #define NOR_FLASH_ENABLE_OCTAL_CMD 0x1 +#define NOR_WRITE_SIZE 1 #endif LOG_MODULE_REGISTER(flash_flexspi_nor, CONFIG_FLASH_LOG_LEVEL); @@ -388,6 +390,12 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, */ key = irq_lock(); } + if (IS_ENABLED(CONFIG_FLASH_MCUX_FLEXSPI_MX25UM51345G_OPI_DTR)) { + /* Check that write size and length are even */ + if ((offset & 0x1) || (len & 0x1)) { + return -EINVAL; + } + } while (len) { /* If the offset isn't a multiple of the NOR page size, we first need From 2504329b76c0ac877dba7eaf98253634ad702b66 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 15:37:57 -0700 Subject: [PATCH 1816/4498] drivers: eswifi: Fix possible buffer overflow Limit the number of the copied ssid to WIFI_SSID_MAX_LEN and avoid a possible one byte overflow. Signed-off-by: Flavio Ceolin --- drivers/wifi/eswifi/eswifi_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index 83ef8393552..f4794bbb8b3 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -490,8 +490,8 @@ int eswifi_mgmt_iface_status(const struct device *dev, } status->state = WIFI_STATE_COMPLETED; - strcpy(status->ssid, sta->ssid); - status->ssid_len = strlen(sta->ssid); + status->ssid_len = strnlen(sta->ssid, WIFI_SSID_MAX_LEN); + strncpy(status->ssid, sta->ssid, sta->ssid_len); status->band = WIFI_FREQ_BAND_2_4_GHZ; status->channel = 0; From ea109f6a205b9e5ae1afaca50d9c97073873df98 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 25 Sep 2023 15:44:36 -0700 Subject: [PATCH 1817/4498] drivers: eswifi: shell: Fix possible overflow Limit the copied data to the buffer's size. Signed-off-by: Flavio Ceolin --- drivers/wifi/eswifi/eswifi_shell.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/wifi/eswifi/eswifi_shell.c b/drivers/wifi/eswifi/eswifi_shell.c index ee5cf4a15ba..de122d4ef1f 100644 --- a/drivers/wifi/eswifi/eswifi_shell.c +++ b/drivers/wifi/eswifi/eswifi_shell.c @@ -25,6 +25,7 @@ static int eswifi_shell_atcmd(const struct shell *sh, size_t argc, char **argv) { int i; + size_t len = 0; if (eswifi == NULL) { shell_print(sh, "no eswifi device registered"); @@ -40,9 +41,16 @@ static int eswifi_shell_atcmd(const struct shell *sh, size_t argc, memset(eswifi->buf, 0, sizeof(eswifi->buf)); for (i = 1; i < argc; i++) { - strcat(eswifi->buf, argv[i]); + size_t argv_len = strlen(argv[i]); + + if ((len + argv_len) >= sizeof(eswifi->buf) - 1) { + break; + } + + memcpy(eswifi->buf + len, argv[i], argv_len); + len += argv_len; } - strcat(eswifi->buf, "\r"); + eswifi->buf[len] = '\r'; shell_print(sh, "> %s", eswifi->buf); eswifi_at_cmd(eswifi, eswifi->buf); From f0d71f54d96dc7aa83e9c3def37b3746ba42a608 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 17:22:33 -0700 Subject: [PATCH 1818/4498] doc: release/3.5: add some bits on Xtensa This adds some bits on added Xtensa MMU support, refactoring of ESP32 folder, and various board additions/removals. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index cd7c1307c26..3109163a38a 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -68,6 +68,8 @@ Architectures * Xtensa + * Added basic MMU v2 Support. + * POSIX * Has been reworked to use the native simulator. @@ -109,6 +111,7 @@ Boards & SoC Support and CONFIG_NXP_IMX_EXTERNAL_SDRAM to enabled. * i.MX RT SOCs no longer support CONFIG_OCRAM_NOCACHE, as this functionality can be achieved using devicetree memory regions + * Refactored ESP32 SoC folders. So now these are a proper SoC series. * Added support for these ARC boards: @@ -124,6 +127,19 @@ Boards & SoC Support * Added support for these Xtensa boards: + * Added ``esp32_devkitc_wroom`` and ``esp32_devkitc_wrover``. + + * Added ``esp32s3_luatos_core``. + + * Added ``m5stack_core2``. + + * Added ``qemu_xtensa_mmu`` utilizing Diamond DC233c SoC to support + testing Xtensa MMU. + + * Added ``xiao_esp32s3``. + + * Added ``yd_esp32``. + * Added support for these POSIX boards: * :ref:`native_sim(_64) ` @@ -142,6 +158,12 @@ Boards & SoC Support * Made these changes for Xtensa boards: + * esp32s3_devkitm: + + * Added USB-CDC support. + + * Added CAN support. + * Made these changes for POSIX boards: * nrf52_bsim: @@ -161,6 +183,8 @@ Boards & SoC Support * Removed support for these Xtensa boards: + * Removed ``esp32``. Use ``esp32_devkitc_*`` instead. + * Made these changes in other boards: * Added support for these following shields: From 83a6223da229038d120d7f487f4648baa0a5343f Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 17:38:23 -0700 Subject: [PATCH 1819/4498] doc: release/3.5: add bits for PCIe This adds some bits about changes on PCIe subsystem. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 3109163a38a..6e81a4d6713 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -357,6 +357,15 @@ Drivers and Sensors * PCIE + * Added support in shell to display PCIe capabilities. + + * Added virtual channel support. + + * Added kconfig :kconfig:option:`CONFIG_PCIE_INIT_PRIORITY` to specify + initialization priority for host controller. + + * Added support to get IRQ from ACPI PCI Routing Table (PRT). + * PECI * Pin control From 61f939da304262057af89aa7a31d71524a6062f6 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 17:42:22 -0700 Subject: [PATCH 1820/4498] doc: release/3.5: added bits on I3C driver changes This adds some bits about changes to the I3C CDNS driver. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 6e81a4d6713..de15577f999 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -304,6 +304,13 @@ Drivers and Sensors * I3C + * ``i3c_cdns``: + + * Fixed build error when :kconfig:option:`CONFIG_I3C_USE_IBI` is disabled. + + * Fixed transfer issue when controller is busy. Now wait for controller to + idle before proceeding with another transfer. + * IEEE 802.15.4 * A new mandatory method attr_get() was introduced into ieee802154_radio_api. From e28a80d42b2564ce557de1bf72d127f10308b8fc Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 17:54:11 -0700 Subject: [PATCH 1821/4498] doc: release/3.5: add bits about userspace and syscalls This adds bits about changes related to userspace and syscalls. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index de15577f999..6a77880449a 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -49,6 +49,8 @@ Kernel * Added support for dynamic thread stack allocation via :c:func:`k_thread_stack_alloc` * Added support for :c:func:`k_spin_trylock` +* Added :c:func:`k_object_is_valid` to check if a kernel object is valid. This replaces + code that has been duplicated throughout the tree. Architectures ************* @@ -216,6 +218,10 @@ Build system and infrastructure * Added a new ``initlevels`` target for printing the final device and :c:macro:`SYS_INIT` initialization sequence from the final ELF file. +* Reworked syscall code generations so that not all marshalling functions + will be included in the final binary. Syscalls associated with disabled + subsystems no longer have their marshalling functions generated. + Drivers and Sensors ******************* From 73acdbbcafdf28ec4f9f3cab1a4f33ea7deebcfa Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 18:00:05 -0700 Subject: [PATCH 1822/4498] doc: release/3.5: add bits about shadow variable warning This adds bits about partially enabling warnings on shadow variables for a subset of in-tree code. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 6a77880449a..b48ac668921 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -222,6 +222,10 @@ Build system and infrastructure will be included in the final binary. Syscalls associated with disabled subsystems no longer have their marshalling functions generated. +* Partially enabled compiler warning about shadow variables for subset of + in-tree code. Out-of-tree code needs to be patched before we can fully + enable shadow variable warnings. + Drivers and Sensors ******************* From 54c7cdb6a16e3ac263f2733aaa075036a879ec3c Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 9 Oct 2023 18:12:23 -0700 Subject: [PATCH 1823/4498] doc: release/3.5: add bits about UART drivers This adds some bits on additions and changes for UART drivers. Signed-off-by: Daniel Leung --- doc/releases/release-notes-3.5.rst | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b48ac668921..adc957c550d 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -433,10 +433,32 @@ Drivers and Sensors * NS16550: Reworked how device initialization macros. - * CONFIG_UART_NS16550_ACCESS_IOPORT and CONFIG_UART_NS16550_SIMULT_ACCESS - are removed. For UART using IO port access, add "io-mapped" property to + * ``CONFIG_UART_NS16550_ACCESS_IOPORT`` and ``CONFIG_UART_NS16550_SIMULT_ACCESS`` + are removed. For UART using IO port access, add ``io-mapped`` property to device tree node. + * Added async support for ESP32S3. + + * Added support for serial TTY under ``native_posix``. + + * Added support for UART on Efinix Sapphire SoCs. + + * Added Intel SEDI UART driver. + + * Added support for UART on BCM2711. + + * ``uart_stm32``: + + * Added RS485 support. + + * Added wide data support. + + * ``uart_pl011``: added support for Ambiq SoCs. + + * ``serial_test``: added support for interrupt and async APIs. + + * ``uart_emul``: added support for interrupt API. + * SPI * Remove npcx spi driver implemented by Flash Interface Unit (FIU) module. From 0c040501e6df500a000c50e7d0ecf4c953673e4b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 9 Oct 2023 19:48:56 +0000 Subject: [PATCH 1824/4498] doc: relnotes: 3.5: Entropy drivers release notes Add relevant information about entropy drivers. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index adc957c550d..d2f16b552af 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -268,6 +268,9 @@ Drivers and Sensors * Entropy + * Added a requirement for ``entropy_get_entropy()`` to be thread-safe because + of random subsystem needs. + * ESPI * Ethernet From 5f53d4977f26f1ba95a84902f25d838bf6a50367 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 9 Oct 2023 19:56:37 +0000 Subject: [PATCH 1825/4498] doc: relnotes: 3.5: Random subsys release notes Information about the removal of a deprecated symbol. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index d2f16b552af..a26f44faafb 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -607,6 +607,10 @@ Libraries / Subsystems operation for SDMMC devices in case when we align buffers on CONFIG_SDHC_BUFFER_ALIGNMENT, because we can avoid extra copy of data from card bffer to read/prog buffer. +* Random + + * ``CONFIG_XOROSHIRO_RANDOM_GENERATOR``, deprecated a long time ago, is finally removed. + * Retention * Added the :ref:`blinfo_api` subsystem. From 4f57614cbddc66dbe264691352fe07223e3974e0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 9 Oct 2023 23:01:41 +0200 Subject: [PATCH 1826/4498] tests: bluetooth: tester: Fix GATT read multiple Pass only speficied number of handler to read_params for GATT read multiple. This is to avoid sending invalid (zeros) handles in ATT_READ_MULTIPLE_REQ. This was affecting GATT/CL/GAR/BI-18-C and GATT/CL/GAR/BI-19-C qualification test cases. Signed-off-by: Szymon Janc --- tests/bluetooth/tester/src/btp_gatt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_gatt.c b/tests/bluetooth/tester/src/btp_gatt.c index 4d046cc3aad..6509ca7fe4b 100644 --- a/tests/bluetooth/tester/src/btp_gatt.c +++ b/tests/bluetooth/tester/src/btp_gatt.c @@ -1651,11 +1651,11 @@ static uint8_t read_multiple(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - if (cp->handles_count > ARRAY_SIZE(handles)) { + if (cp->handles_count == 0 || cp->handles_count > ARRAY_SIZE(handles)) { return BTP_STATUS_FAILED; } - for (i = 0; i < ARRAY_SIZE(handles); i++) { + for (i = 0; i < cp->handles_count; i++) { handles[i] = sys_le16_to_cpu(cp->handles[i]); } @@ -1670,7 +1670,7 @@ static uint8_t read_multiple(const void *cmd, uint16_t cmd_len, } read_params.func = read_cb; - read_params.handle_count = i; + read_params.handle_count = cp->handles_count; read_params.multiple.handles = handles; /* not used in read func */ read_params.multiple.variable = false; read_params.chan_opt = BT_ATT_CHAN_OPT_NONE; From c928e3b125197fcff692cb19a8cf6d86e2239cc8 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 10 Oct 2023 19:57:45 +1000 Subject: [PATCH 1827/4498] doc: release-notes: Add 3.5.0 notes for LoRaWAN Document the upgrade from v4.6.0 to v4.7.0. Signed-off-by: Jordan Yates --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index a26f44faafb..882c42b66e1 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -641,6 +641,10 @@ Libraries / Subsystems * Added logging to POSIX threads, mutexes, and condition variables * Fixed :c:func:`poll` issue with event file descriptors +* LoRa/LoRaWAN + + * Updated ``loramac-node`` from v4.6.0 to v4.7.0 + HALs **** From e7bd10ae719d1773f8d6b189c18f775d9dfcc93d Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 6 Oct 2023 22:38:53 +0000 Subject: [PATCH 1828/4498] random: Rename random header rand32.h does not make much sense, since the random subsystem provides more APIs than just getting a random 32 bits value. Rename it to random.h and get consistently with other subsystems. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_mcux_caam.c | 2 +- drivers/entropy/entropy_mcux_css.c | 2 +- drivers/entropy/entropy_mcux_rng.c | 2 +- drivers/entropy/entropy_mcux_rnga.c | 2 +- drivers/entropy/entropy_mcux_trng.c | 2 +- drivers/entropy/entropy_rv32m1_trng.c | 2 +- drivers/entropy/entropy_stm32.c | 2 +- drivers/ethernet/eth.h | 2 +- drivers/flash/flash_simulator.c | 2 +- drivers/ieee802154/ieee802154_b91.c | 2 +- drivers/ieee802154/ieee802154_cc1200.c | 2 +- drivers/ieee802154/ieee802154_cc13xx_cc26xx.c | 2 +- .../ieee802154_cc13xx_cc26xx_subg.c | 2 +- drivers/ieee802154/ieee802154_cc2520.c | 2 +- drivers/ieee802154/ieee802154_dw1000.c | 2 +- drivers/ieee802154/ieee802154_kw41z.c | 2 +- drivers/ieee802154/ieee802154_mcr20a.c | 2 +- drivers/ieee802154/ieee802154_nrf5.c | 2 +- drivers/ieee802154/ieee802154_rf2xx.c | 2 +- drivers/ieee802154/ieee802154_uart_pipe.c | 2 +- drivers/modem/wncm14a2a.c | 2 +- drivers/net/ppp.c | 2 +- drivers/net/slip.c | 2 +- include/zephyr/random/rand32.h | 77 +--------------- include/zephyr/random/random.h | 87 +++++++++++++++++++ kernel/init.c | 2 +- kernel/thread.c | 2 +- lib/os/thread_entry.c | 2 +- modules/mbedtls/zephyr_init.c | 2 +- modules/openthread/platform/entropy.c | 2 +- modules/openthread/platform/settings.c | 2 +- samples/arch/smp/pktqueue/src/main.h | 2 +- samples/arch/smp/pktqueue/src/pktqueue.h | 2 +- samples/basic/hash_map/src/main.c | 2 +- samples/bluetooth/peripheral_csc/src/main.c | 2 +- samples/net/cloud/aws_iot_mqtt/src/main.c | 2 +- samples/net/cloud/mqtt_azure/src/main.c | 2 +- samples/net/cloud/tagoio_http_post/src/main.c | 2 +- samples/net/lwm2m_client/src/temperature.c | 2 +- samples/net/mqtt_publisher/src/main.c | 2 +- samples/net/sockets/echo_client/src/tcp.c | 2 +- samples/net/sockets/echo_client/src/udp.c | 2 +- .../net/sockets/websocket_client/src/main.c | 2 +- samples/net/wpan_serial/src/main.c | 2 +- samples/subsys/usb/hid-cdc/src/main.c | 2 +- soc/arm/nxp_kinetis/k2x/soc.h | 2 +- soc/x86/alder_lake/soc.h | 2 +- soc/x86/apollo_lake/soc.h | 2 +- soc/x86/atom/soc.h | 2 +- soc/x86/elkhart_lake/soc.h | 2 +- soc/x86/ia32/soc.h | 2 +- soc/x86/intel_ish/intel_ish5/soc.h | 2 +- soc/x86/raptor_lake/soc.h | 2 +- subsys/bluetooth/mesh/dfu_cli.c | 2 +- subsys/bluetooth/mesh/rpr_srv.c | 2 +- subsys/fs/ext2/ext2_format.c | 2 +- subsys/jwt/jwt.c | 4 +- subsys/lorawan/services/clock_sync.c | 2 +- subsys/mgmt/osdp/src/osdp_common.c | 2 +- subsys/net/ip/dhcpv4.c | 2 +- subsys/net/ip/dhcpv6.c | 2 +- subsys/net/ip/icmp.c | 2 +- subsys/net/ip/ipv4_autoconf.c | 2 +- subsys/net/ip/ipv4_fragment.c | 2 +- subsys/net/ip/ipv6_fragment.c | 2 +- subsys/net/ip/net_context.c | 2 +- subsys/net/ip/net_if.c | 2 +- subsys/net/ip/net_shell.c | 2 +- subsys/net/ip/tcp.c | 2 +- subsys/net/ip/tcp_internal.h | 2 +- subsys/net/ip/trickle.c | 2 +- subsys/net/l2/ethernet/ethernet.c | 2 +- subsys/net/l2/ethernet/gptp/gptp.c | 2 +- subsys/net/l2/ieee802154/ieee802154.c | 2 +- .../l2/ieee802154/ieee802154_radio_csma_ca.c | 2 +- subsys/net/l2/ppp/fsm.c | 2 +- subsys/net/l2/virtual/virtual.c | 2 +- subsys/net/lib/coap/coap.c | 2 +- subsys/net/lib/dns/resolve.c | 2 +- subsys/net/lib/sockets/sockets_tls.c | 2 +- subsys/net/lib/websocket/websocket.c | 2 +- subsys/random/CMakeLists.txt | 2 +- subsys/random/rand32_handlers.c | 2 +- subsys/random/rand32_timer.c | 2 +- subsys/testsuite/busy_sim/busy_sim.c | 2 +- subsys/testsuite/ztest/src/ztest_new.c | 2 +- subsys/testsuite/ztest/src/ztress.c | 2 +- tests/benchmarks/mbedtls/src/benchmark.c | 2 +- .../cache_coex/src/cache_coex.c | 2 +- tests/crypto/rand32/src/main.c | 2 +- tests/crypto/tinycrypt/src/ecc_dsa.c | 2 +- .../drivers/disk/disk_performance/src/main.c | 2 +- .../sbs_gauge/boards/qemu_cortex_a53.conf | 5 +- tests/drivers/smbus/smbus_emul/src/smbus.c | 2 +- .../uart/uart_mix_fifo_poll/src/main.c | 2 +- tests/kernel/sched/deadline/src/main.c | 2 +- .../timer/timer_api/src/timer_convert.c | 2 +- tests/lib/hash_function/src/main.c | 2 +- tests/lib/mpsc_pbuf/src/concurrent.c | 2 +- tests/lib/mpsc_pbuf/src/main.c | 2 +- tests/lib/p4workq/src/main.c | 2 +- tests/lib/ringbuffer/src/concurrent.c | 2 +- tests/lib/spsc_pbuf/src/main.c | 2 +- tests/net/arp/src/main.c | 2 +- tests/net/checksum_offload/src/main.c | 2 +- tests/net/context/src/main.c | 2 +- tests/net/hostname/src/main.c | 2 +- tests/net/iface/src/main.c | 2 +- tests/net/igmp/src/main.c | 2 +- tests/net/ip-addr/src/main.c | 2 +- tests/net/ipv4_fragment/src/main.c | 2 +- tests/net/ipv6/src/main.c | 2 +- tests/net/ipv6_fragment/src/main.c | 2 +- tests/net/lib/dns_addremove/src/main.c | 2 +- tests/net/lib/dns_resolve/src/main.c | 2 +- .../mqtt_publisher/src/test_mqtt_publish.c | 2 +- .../lib/mqtt_pubsub/src/test_mqtt_pubsub.c | 2 +- .../mqtt_subscriber/src/test_mqtt_subscribe.c | 2 +- tests/net/mld/src/main.c | 2 +- tests/net/net_pkt/src/main.c | 2 +- tests/net/pm/src/main.c | 2 +- tests/net/ptp/clock/src/main.c | 2 +- tests/net/route/src/main.c | 2 +- tests/net/route_mcast/src/main.c | 2 +- tests/net/shell/src/main.c | 2 +- .../socket/af_packet_ipproto_raw/src/main.c | 2 +- tests/net/traffic_class/src/main.c | 2 +- tests/net/tx_timestamp/src/main.c | 2 +- tests/net/udp/src/main.c | 2 +- tests/net/virtual/src/main.c | 2 +- tests/net/vlan/src/main.c | 2 +- tests/net/wifi/wifi_nm/src/main.c | 2 +- tests/subsys/logging/log_stress/src/main.c | 2 +- 133 files changed, 225 insertions(+), 206 deletions(-) create mode 100644 include/zephyr/random/random.h mode change 120000 => 100644 tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf diff --git a/drivers/entropy/entropy_mcux_caam.c b/drivers/entropy/entropy_mcux_caam.c index 252453d919c..586b2137ff3 100644 --- a/drivers/entropy/entropy_mcux_caam.c +++ b/drivers/entropy/entropy_mcux_caam.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/entropy/entropy_mcux_css.c b/drivers/entropy/entropy_mcux_css.c index 24f3bce44ab..e0a5853aa25 100644 --- a/drivers/entropy/entropy_mcux_css.c +++ b/drivers/entropy/entropy_mcux_css.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static int entropy_mcux_css_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) { diff --git a/drivers/entropy/entropy_mcux_rng.c b/drivers/entropy/entropy_mcux_rng.c index dc5f0fc1fa3..b205c4fa21b 100644 --- a/drivers/entropy/entropy_mcux_rng.c +++ b/drivers/entropy/entropy_mcux_rng.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include "fsl_rng.h" diff --git a/drivers/entropy/entropy_mcux_rnga.c b/drivers/entropy/entropy_mcux_rnga.c index 5004ec719b4..b82bd22ff0e 100644 --- a/drivers/entropy/entropy_mcux_rnga.c +++ b/drivers/entropy/entropy_mcux_rnga.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include "fsl_rnga.h" diff --git a/drivers/entropy/entropy_mcux_trng.c b/drivers/entropy/entropy_mcux_trng.c index 8718694e59c..c48e3aab25d 100644 --- a/drivers/entropy/entropy_mcux_trng.c +++ b/drivers/entropy/entropy_mcux_trng.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include "fsl_trng.h" diff --git a/drivers/entropy/entropy_rv32m1_trng.c b/drivers/entropy/entropy_rv32m1_trng.c index 3e12429d105..0e44afb7c18 100644 --- a/drivers/entropy/entropy_rv32m1_trng.c +++ b/drivers/entropy/entropy_rv32m1_trng.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include "fsl_trng.h" diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 6627c648c47..3dd8f82e8a5 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/ethernet/eth.h b/drivers/ethernet/eth.h index 06ba7558466..ebbff29a9d9 100644 --- a/drivers/ethernet/eth.h +++ b/drivers/ethernet/eth.h @@ -8,7 +8,7 @@ #define ZEPHYR_DRIVERS_ETHERNET_ETH_H_ #include -#include +#include /* helper macro to return mac address octet from local_mac_address prop */ #define NODE_MAC_ADDR_OCTET(node, n) DT_PROP_BY_IDX(node, local_mac_address, n) diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 9fe5d230207..7f753b534f5 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 16a3c794f18..3c47c56fc9a 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -19,7 +19,7 @@ #include LOG_MODULE_REGISTER(LOG_MODULE_NAME); -#include +#include #include #include #if defined(CONFIG_NET_L2_OPENTHREAD) diff --git a/drivers/ieee802154/ieee802154_cc1200.c b/drivers/ieee802154/ieee802154_cc1200.c index 464417731de..0c7901dfda3 100644 --- a/drivers/ieee802154/ieee802154_cc1200.c +++ b/drivers/ieee802154/ieee802154_cc1200.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index cd3cd298bd1..5d5a53ed08e 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx); #include #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 9aba1a35166..b5cc9b36176 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx_subg); #include #include #include -#include +#include #include #include #include diff --git a/drivers/ieee802154/ieee802154_cc2520.c b/drivers/ieee802154/ieee802154_cc2520.c index 688a6827a77..05404314d1f 100644 --- a/drivers/ieee802154/ieee802154_cc2520.c +++ b/drivers/ieee802154/ieee802154_cc2520.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include +#include #include diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index 730828d78ea..d20df488966 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(dw1000, LOG_LEVEL_INF); #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_kw41z.c b/drivers/ieee802154/ieee802154_kw41z.c index 4947c4733ff..aee802ad6ff 100644 --- a/drivers/ieee802154/ieee802154_kw41z.c +++ b/drivers/ieee802154/ieee802154_kw41z.c @@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include #include "fsl_xcvr.h" diff --git a/drivers/ieee802154/ieee802154_mcr20a.c b/drivers/ieee802154/ieee802154_mcr20a.c index 96907cad145..5ba4e844a95 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.c +++ b/drivers/ieee802154/ieee802154_mcr20a.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index f02ce5bda8f..8e1032718e4 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -39,7 +39,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index 54894910829..870eb8a2f70 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include +#include #include #include diff --git a/drivers/ieee802154/ieee802154_uart_pipe.c b/drivers/ieee802154/ieee802154_uart_pipe.c index 299c9824d83..cdb420d9747 100644 --- a/drivers/ieee802154/ieee802154_uart_pipe.c +++ b/drivers/ieee802154/ieee802154_uart_pipe.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include #include #include diff --git a/drivers/modem/wncm14a2a.c b/drivers/modem/wncm14a2a.c index 669c19393d5..520c4312580 100644 --- a/drivers/modem/wncm14a2a.c +++ b/drivers/modem/wncm14a2a.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #include #include #include -#include +#include #include #include diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index c8d06fa146b..ecfdb7c3af1 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(net_ppp, LOG_LEVEL); #include #include #include -#include +#include #include "../../subsys/net/ip/net_stats.h" #include "../../subsys/net/ip/net_private.h" diff --git a/drivers/net/slip.c b/drivers/net/slip.c index ba9bdd27d69..cf1fef83041 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -28,7 +28,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include #include "slip.h" diff --git a/include/zephyr/random/rand32.h b/include/zephyr/random/rand32.h index 4bf39fe45de..cb9ef54ca63 100644 --- a/include/zephyr/random/rand32.h +++ b/include/zephyr/random/rand32.h @@ -1,86 +1,15 @@ /* * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright (c) 2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief Random number generator header file - * - * This header file declares prototypes for the kernel's random number - * generator APIs. - * - * Typically, a platform enables the appropriate source for the random - * number generation based on the hardware platform's capabilities or - * (for testing purposes only) enables the TEST_RANDOM_GENERATOR - * configuration option. - */ - #ifndef ZEPHYR_INCLUDE_RANDOM_RAND32_H_ #define ZEPHYR_INCLUDE_RANDOM_RAND32_H_ -#include -#include -#include - -/** - * @brief Random Function APIs - * @defgroup random_api Random Function APIs - * @ingroup crypto - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Return a 32-bit random value that should pass general - * randomness tests. - * - * @note The random value returned is not a cryptographically secure - * random number value. - * - * @return 32-bit random value. - */ -__syscall uint32_t sys_rand32_get(void); - -/** - * @brief Fill the destination buffer with random data values that should - * pass general randomness tests. - * - * @note The random values returned are not considered cryptographically - * secure random number values. - * - * @param [out] dst destination buffer to fill with random data. - * @param len size of the destination buffer. - * - */ -__syscall void sys_rand_get(void *dst, size_t len); - -/** - * @brief Fill the destination buffer with cryptographically secure - * random data values. - * - * @note If the random values requested do not need to be cryptographically - * secure then use sys_rand_get() instead. - * - * @param [out] dst destination buffer to fill. - * @param len size of the destination buffer. - * - * @return 0 if success, -EIO if entropy reseed error - * - */ -__syscall int sys_csrand_get(void *dst, size_t len); - -#ifdef __cplusplus -} -#endif +#include -/** - * @} - */ +#warning " is deprecated, include instead" -#include #endif /* ZEPHYR_INCLUDE_RANDOM_RAND32_H_ */ diff --git a/include/zephyr/random/random.h b/include/zephyr/random/random.h new file mode 100644 index 00000000000..e4b52f683aa --- /dev/null +++ b/include/zephyr/random/random.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Random number generator header file + * + * This header file declares prototypes for the kernel's random number + * generator APIs. + * + * Typically, a platform enables the appropriate source for the random + * number generation based on the hardware platform's capabilities or + * (for testing purposes only) enables the TEST_RANDOM_GENERATOR + * configuration option. + */ + +#ifndef ZEPHYR_INCLUDE_RANDOM_RANDOM_H_ +#define ZEPHYR_INCLUDE_RANDOM_RANDOM_H_ + +#include +#include +#include + +/** + * @brief Random Function APIs + * @defgroup random_api Random Function APIs + * @ingroup crypto + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Return a 32-bit random value that should pass general + * randomness tests. + * + * @note The random value returned is not a cryptographically secure + * random number value. + * + * @return 32-bit random value. + */ +__syscall uint32_t sys_rand32_get(void); + +/** + * @brief Fill the destination buffer with random data values that should + * pass general randomness tests. + * + * @note The random values returned are not considered cryptographically + * secure random number values. + * + * @param [out] dst destination buffer to fill with random data. + * @param len size of the destination buffer. + * + */ +__syscall void sys_rand_get(void *dst, size_t len); + +/** + * @brief Fill the destination buffer with cryptographically secure + * random data values. + * + * @note If the random values requested do not need to be cryptographically + * secure then use sys_rand_get() instead. + * + * @param [out] dst destination buffer to fill. + * @param len size of the destination buffer. + * + * @return 0 if success, -EIO if entropy reseed error + * + */ +__syscall int sys_csrand_get(void *dst, size_t len); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#include +#endif /* ZEPHYR_INCLUDE_RANDOM_RANDOM_H_ */ diff --git a/kernel/init.c b/kernel/init.c index cd4b0e748fa..536756268b3 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/thread.c b/kernel/thread.c index 75ca7864772..8800eddafc9 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/os/thread_entry.c b/lib/os/thread_entry.c index 4fd03f3357e..89eb2fe7b4b 100644 --- a/lib/os/thread_entry.c +++ b/lib/os/thread_entry.c @@ -13,7 +13,7 @@ #include #ifdef CONFIG_THREAD_LOCAL_STORAGE -#include +#include __thread k_tid_t z_tls_current; #endif diff --git a/modules/mbedtls/zephyr_init.c b/modules/mbedtls/zephyr_init.c index 70f7783e2ee..d882b0aedb8 100644 --- a/modules/mbedtls/zephyr_init.c +++ b/modules/mbedtls/zephyr_init.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/modules/openthread/platform/entropy.c b/modules/openthread/platform/entropy.c index b02ab3c3ee9..a52f885e306 100644 --- a/modules/openthread/platform/entropy.c +++ b/modules/openthread/platform/entropy.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/modules/openthread/platform/settings.c b/modules/openthread/platform/settings.c index f716baa842b..ce5fefde0c8 100644 --- a/modules/openthread/platform/settings.c +++ b/modules/openthread/platform/settings.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include diff --git a/samples/arch/smp/pktqueue/src/main.h b/samples/arch/smp/pktqueue/src/main.h index 0ecac944278..20020563ca1 100644 --- a/samples/arch/smp/pktqueue/src/main.h +++ b/samples/arch/smp/pktqueue/src/main.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include /* Amount of parallel processed sender/receiver queues of packet headers */ diff --git a/samples/arch/smp/pktqueue/src/pktqueue.h b/samples/arch/smp/pktqueue/src/pktqueue.h index e46d7ed194f..d4e683d659a 100644 --- a/samples/arch/smp/pktqueue/src/pktqueue.h +++ b/samples/arch/smp/pktqueue/src/pktqueue.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include struct phdr_desc { struct phdr_desc *next; /* Next pkt descriptor in respective queue */ diff --git a/samples/basic/hash_map/src/main.c b/samples/basic/hash_map/src/main.c index 803a43b9c75..3c919283963 100644 --- a/samples/basic/hash_map/src/main.c +++ b/samples/basic/hash_map/src/main.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include LOG_MODULE_REGISTER(hashmap_sample); diff --git a/samples/bluetooth/peripheral_csc/src/main.c b/samples/bluetooth/peripheral_csc/src/main.c index 2f91e201492..eba60137097 100644 --- a/samples/bluetooth/peripheral_csc/src/main.c +++ b/samples/bluetooth/peripheral_csc/src/main.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/samples/net/cloud/aws_iot_mqtt/src/main.c b/samples/net/cloud/aws_iot_mqtt/src/main.c index 2eeec0fd240..09999d2e4eb 100644 --- a/samples/net/cloud/aws_iot_mqtt/src/main.c +++ b/samples/net/cloud/aws_iot_mqtt/src/main.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/cloud/mqtt_azure/src/main.c b/samples/net/cloud/mqtt_azure/src/main.c index 0d1d0a2da6f..420750e416c 100644 --- a/samples/net/cloud/mqtt_azure/src/main.c +++ b/samples/net/cloud/mqtt_azure/src/main.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(mqtt_azure, LOG_LEVEL_DBG); #include #include -#include +#include #include #include diff --git a/samples/net/cloud/tagoio_http_post/src/main.c b/samples/net/cloud/tagoio_http_post/src/main.c index 29edb2c7084..fb97c15c18e 100644 --- a/samples/net/cloud/tagoio_http_post/src/main.c +++ b/samples/net/cloud/tagoio_http_post/src/main.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(tagoio_http_post, CONFIG_TAGOIO_HTTP_POST_LOG_LEVEL); #include #include #include -#include +#include #include #include "wifi.h" diff --git a/samples/net/lwm2m_client/src/temperature.c b/samples/net/lwm2m_client/src/temperature.c index 8d2c0efefb1..6d251fafbdb 100644 --- a/samples/net/lwm2m_client/src/temperature.c +++ b/samples/net/lwm2m_client/src/temperature.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include #include static struct k_work_delayable temp_work; diff --git a/samples/net/mqtt_publisher/src/main.c b/samples/net/mqtt_publisher/src/main.c index a4b391d9148..8ff34f271c2 100644 --- a/samples/net/mqtt_publisher/src/main.c +++ b/samples/net/mqtt_publisher/src/main.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(net_mqtt_publisher_sample, LOG_LEVEL_DBG); #include #include #include -#include +#include #include #include diff --git a/samples/net/sockets/echo_client/src/tcp.c b/samples/net/sockets/echo_client/src/tcp.c index 5ff80eb25ad..5833d399088 100644 --- a/samples/net/sockets/echo_client/src/tcp.c +++ b/samples/net/sockets/echo_client/src/tcp.c @@ -16,7 +16,7 @@ LOG_MODULE_DECLARE(net_echo_client_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include "common.h" #include "ca_certificate.h" diff --git a/samples/net/sockets/echo_client/src/udp.c b/samples/net/sockets/echo_client/src/udp.c index 6b52615ff28..1889fdb591d 100644 --- a/samples/net/sockets/echo_client/src/udp.c +++ b/samples/net/sockets/echo_client/src/udp.c @@ -16,7 +16,7 @@ LOG_MODULE_DECLARE(net_echo_client_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include "common.h" #include "ca_certificate.h" diff --git a/samples/net/sockets/websocket_client/src/main.c b/samples/net/sockets/websocket_client/src/main.c index f58e6d47b41..1b55b6b62ea 100644 --- a/samples/net/sockets/websocket_client/src/main.c +++ b/samples/net/sockets/websocket_client/src/main.c @@ -11,7 +11,7 @@ LOG_MODULE_REGISTER(net_websocket_client_sample, LOG_LEVEL_DBG); #include #include #include -#include +#include #include #include "ca_certificate.h" diff --git a/samples/net/wpan_serial/src/main.c b/samples/net/wpan_serial/src/main.c index 33ac597ef91..1e702dc9590 100644 --- a/samples/net/wpan_serial/src/main.c +++ b/samples/net/wpan_serial/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(wpan_serial, CONFIG_USB_DEVICE_LOG_LEVEL); #include #include #include -#include +#include #include #include diff --git a/samples/subsys/usb/hid-cdc/src/main.c b/samples/subsys/usb/hid-cdc/src/main.c index 2873ca5b270..7e06a2c5d0b 100644 --- a/samples/subsys/usb/hid-cdc/src/main.c +++ b/samples/subsys/usb/hid-cdc/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/soc/arm/nxp_kinetis/k2x/soc.h b/soc/arm/nxp_kinetis/k2x/soc.h index 75789df6531..cb88009a49d 100644 --- a/soc/arm/nxp_kinetis/k2x/soc.h +++ b/soc/arm/nxp_kinetis/k2x/soc.h @@ -35,7 +35,7 @@ extern "C" { #include #include #include -#include +#include #endif /* !_ASMLANGUAGE */ diff --git a/soc/x86/alder_lake/soc.h b/soc/x86/alder_lake/soc.h index dda2272ea61..e1c6a04e834 100644 --- a/soc/x86/alder_lake/soc.h +++ b/soc/x86/alder_lake/soc.h @@ -20,7 +20,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif #ifdef CONFIG_GPIO_INTEL diff --git a/soc/x86/apollo_lake/soc.h b/soc/x86/apollo_lake/soc.h index 47e719dac14..8d4dc0f5bf8 100644 --- a/soc/x86/apollo_lake/soc.h +++ b/soc/x86/apollo_lake/soc.h @@ -20,7 +20,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif #ifdef CONFIG_GPIO_INTEL diff --git a/soc/x86/atom/soc.h b/soc/x86/atom/soc.h index 9af32283e53..199820fa7bd 100644 --- a/soc/x86/atom/soc.h +++ b/soc/x86/atom/soc.h @@ -19,7 +19,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif /* PCI definitions */ diff --git a/soc/x86/elkhart_lake/soc.h b/soc/x86/elkhart_lake/soc.h index 1e47a01c38d..0b9c96ea5ad 100644 --- a/soc/x86/elkhart_lake/soc.h +++ b/soc/x86/elkhart_lake/soc.h @@ -20,7 +20,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif #ifdef CONFIG_GPIO_INTEL diff --git a/soc/x86/ia32/soc.h b/soc/x86/ia32/soc.h index 0fedc9a4d0d..51da1d1cdf4 100644 --- a/soc/x86/ia32/soc.h +++ b/soc/x86/ia32/soc.h @@ -19,7 +19,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif /* PCI definitions */ diff --git a/soc/x86/intel_ish/intel_ish5/soc.h b/soc/x86/intel_ish/intel_ish5/soc.h index 69528a74b68..e474a33b3f8 100644 --- a/soc/x86/intel_ish/intel_ish5/soc.h +++ b/soc/x86/intel_ish/intel_ish5/soc.h @@ -11,7 +11,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #ifdef CONFIG_HPET_TIMER #include "sedi_driver_hpet.h" diff --git a/soc/x86/raptor_lake/soc.h b/soc/x86/raptor_lake/soc.h index 6de3f7fa9c0..bb4adb62fa0 100644 --- a/soc/x86/raptor_lake/soc.h +++ b/soc/x86/raptor_lake/soc.h @@ -18,7 +18,7 @@ #ifndef _ASMLANGUAGE #include -#include +#include #endif #ifdef CONFIG_GPIO_INTEL diff --git a/subsys/bluetooth/mesh/dfu_cli.c b/subsys/bluetooth/mesh/dfu_cli.c index 3805a04e450..9e800a6231f 100644 --- a/subsys/bluetooth/mesh/dfu_cli.c +++ b/subsys/bluetooth/mesh/dfu_cli.c @@ -10,7 +10,7 @@ #include "access.h" #include "dfu.h" #include "blob.h" -#include +#include #include #define LOG_LEVEL CONFIG_BT_MESH_DFU_LOG_LEVEL diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index 8fb28e56472..df63b1166c5 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/subsys/fs/ext2/ext2_format.c b/subsys/fs/ext2/ext2_format.c index 6e35555e53f..9fb9792df75 100644 --- a/subsys/fs/ext2/ext2_format.c +++ b/subsys/fs/ext2/ext2_format.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/subsys/jwt/jwt.c b/subsys/jwt/jwt.c index 11745073796..0db2426195b 100644 --- a/subsys/jwt/jwt.c +++ b/subsys/jwt/jwt.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #endif #ifdef CONFIG_JWT_SIGN_ECDSA @@ -24,7 +24,7 @@ #include #include -#include +#include #endif /* diff --git a/subsys/lorawan/services/clock_sync.c b/subsys/lorawan/services/clock_sync.c index 2f627d30dea..9e4bbe447a0 100644 --- a/subsys/lorawan/services/clock_sync.c +++ b/subsys/lorawan/services/clock_sync.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include LOG_MODULE_REGISTER(lorawan_clock_sync, CONFIG_LORAWAN_SERVICES_LOG_LEVEL); diff --git a/subsys/mgmt/osdp/src/osdp_common.c b/subsys/mgmt/osdp/src/osdp_common.c index 2898659bd09..2b0fcaf81c9 100644 --- a/subsys/mgmt/osdp/src/osdp_common.c +++ b/subsys/mgmt/osdp/src/osdp_common.c @@ -12,7 +12,7 @@ #ifdef CONFIG_OSDP_SC_ENABLED #include -#include +#include #endif #include "osdp_common.h" diff --git a/subsys/net/ip/dhcpv4.c b/subsys/net/ip/dhcpv4.c index d5aefb3ba90..918b71d1d6b 100644 --- a/subsys/net/ip/dhcpv4.c +++ b/subsys/net/ip/dhcpv4.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_dhcpv4, CONFIG_NET_DHCPV4_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index fdfef3c5147..3d464c92954 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -13,7 +13,7 @@ LOG_MODULE_REGISTER(net_dhcpv6, CONFIG_NET_DHCPV6_LOG_LEVEL); #include #include -#include +#include #include #include "dhcpv6_internal.h" diff --git a/subsys/net/ip/icmp.c b/subsys/net/ip/icmp.c index 37a8668432c..97902c1e4f5 100644 --- a/subsys/net/ip/icmp.c +++ b/subsys/net/ip/icmp.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(net_icmp, ICMP_LOG_LEVEL); #include -#include +#include #include #include #include diff --git a/subsys/net/ip/ipv4_autoconf.c b/subsys/net/ip/ipv4_autoconf.c index eed61e3f2d0..aa18a27ef63 100644 --- a/subsys/net/ip/ipv4_autoconf.c +++ b/subsys/net/ip/ipv4_autoconf.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_ipv4_autoconf, CONFIG_NET_IPV4_AUTO_LOG_LEVEL); #include #include #include -#include +#include #include "ipv4_autoconf_internal.h" diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index 04df53304a8..d61dd246075 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -14,7 +14,7 @@ LOG_MODULE_DECLARE(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL); #include #include #include -#include +#include #include "net_private.h" #include "connection.h" #include "icmpv4.h" diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 959aaef0b16..3aa2a49fb65 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -17,7 +17,7 @@ LOG_MODULE_DECLARE(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include -#include +#include #include "net_private.h" #include "connection.h" #include "icmpv6.h" diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 9de988e54f8..fc9e3b172d1 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(net_ctx, CONFIG_NET_CONTEXT_LOG_LEVEL); #include -#include +#include #include #include #include diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 2b084de071f..1a84d07e926 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -11,7 +11,7 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index f00a83b7b64..69efc8b0826 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index c12eff69f06..e7592a55353 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -11,7 +11,7 @@ LOG_MODULE_REGISTER(net_tcp, CONFIG_NET_TCP_LOG_LEVEL); #include #include #include -#include +#include #if defined(CONFIG_NET_TCP_ISN_RFC6528) #include diff --git a/subsys/net/ip/tcp_internal.h b/subsys/net/ip/tcp_internal.h index e76ba859e49..e282900b16c 100644 --- a/subsys/net/ip/tcp_internal.h +++ b/subsys/net/ip/tcp_internal.h @@ -14,7 +14,7 @@ #define __TCP_INTERNAL_H #include -#include +#include #include #include diff --git a/subsys/net/ip/trickle.c b/subsys/net/ip/trickle.c index debe2d16181..bddac8ced69 100644 --- a/subsys/net/ip/trickle.c +++ b/subsys/net/ip/trickle.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(net_trickle, CONFIG_NET_TRICKLE_LOG_LEVEL); #include #include -#include +#include #include #include diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index 4671f20aec1..c62c986d838 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(net_ethernet, CONFIG_NET_L2_ETHERNET_LOG_LEVEL); #include #include #include -#include +#include #if defined(CONFIG_NET_LLDP) #include diff --git a/subsys/net/l2/ethernet/gptp/gptp.c b/subsys/net/l2/ethernet/gptp/gptp.c index 7ba4294a2fa..f72386a1e46 100644 --- a/subsys/net/l2/ethernet/gptp/gptp.c +++ b/subsys/net/l2/ethernet/gptp/gptp.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(net_gptp, CONFIG_NET_GPTP_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index fc9c13c4f55..09fdf8d28cf 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL); #include #include #include -#include +#include #ifdef CONFIG_NET_6LO #include "ieee802154_6lo.h" diff --git a/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c b/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c index 29556d43df1..06b00b7964f 100644 --- a/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c +++ b/subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(net_ieee802154_csma, CONFIG_NET_L2_IEEE802154_LOG_LEVEL); #include #include #include -#include +#include #include #include diff --git a/subsys/net/l2/ppp/fsm.c b/subsys/net/l2/ppp/fsm.c index 7e2c739e779..1f64de14f13 100644 --- a/subsys/net/l2/ppp/fsm.c +++ b/subsys/net/l2/ppp/fsm.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL); #include #include -#include +#include #include "net_private.h" diff --git a/subsys/net/l2/virtual/virtual.c b/subsys/net/l2/virtual/virtual.c index 2efd365b0cf..ad50eb12041 100644 --- a/subsys/net/l2/virtual/virtual.c +++ b/subsys/net/l2/virtual/virtual.c @@ -13,7 +13,7 @@ LOG_MODULE_REGISTER(net_virtual, CONFIG_NET_L2_VIRTUAL_LOG_LEVEL); #include #include #include -#include +#include #include "net_private.h" diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index e3427844bb5..429d3fd3d4a 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL); #include #include #include -#include +#include #include #include diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index eae02bc88ed..2741ed13a97 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(net_dns_resolve, CONFIG_DNS_RESOLVER_LOG_LEVEL); #include -#include +#include #include #include #include diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index a4aab077beb..e0d44b68df2 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include #include diff --git a/subsys/net/lib/websocket/websocket.c b/subsys/net/lib/websocket/websocket.c index f5975dea147..811f89c5b28 100644 --- a/subsys/net/lib/websocket/websocket.c +++ b/subsys/net/lib/websocket/websocket.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(net_websocket, CONFIG_NET_WEBSOCKET_LOG_LEVEL); #include #include -#include +#include #include #include #include diff --git a/subsys/random/CMakeLists.txt b/subsys/random/CMakeLists.txt index e8bbd0f0dd8..cde2431ae2e 100644 --- a/subsys/random/CMakeLists.txt +++ b/subsys/random/CMakeLists.txt @@ -3,7 +3,7 @@ if (CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR OR CONFIG_TIMER_RANDOM_GENERATOR OR CONFIG_XOSHIRO_RANDOM_GENERATOR) -zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/random/rand32.h) +zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/random/random.h) zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE rand32_handlers.c) endif() diff --git a/subsys/random/rand32_handlers.c b/subsys/random/rand32_handlers.c index 4a407c01e65..52130110be7 100644 --- a/subsys/random/rand32_handlers.c +++ b/subsys/random/rand32_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include diff --git a/subsys/random/rand32_timer.c b/subsys/random/rand32_timer.c index 6b14e166ce0..b5e2769b1ce 100644 --- a/subsys/random/rand32_timer.c +++ b/subsys/random/rand32_timer.c @@ -14,7 +14,7 @@ * provide a random number generator. */ -#include +#include #include #include #include diff --git a/subsys/testsuite/busy_sim/busy_sim.c b/subsys/testsuite/busy_sim/busy_sim.c index 9ca5534851a..d401aeafdd8 100644 --- a/subsys/testsuite/busy_sim/busy_sim.c +++ b/subsys/testsuite/busy_sim/busy_sim.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #define BUFFER_SIZE 32 diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index 61453f25339..b100921ab21 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -22,7 +22,7 @@ static bool failed_expectation; #include #include -#include +#include #define NUM_ITER_PER_SUITE CONFIG_ZTEST_SHUFFLE_SUITE_REPEAT_COUNT #define NUM_ITER_PER_TEST CONFIG_ZTEST_SHUFFLE_TEST_REPEAT_COUNT #else diff --git a/subsys/testsuite/ztest/src/ztress.c b/subsys/testsuite/ztest/src/ztress.c index a0515558e8a..0ca15b0fc96 100644 --- a/subsys/testsuite/ztest/src/ztress.c +++ b/subsys/testsuite/ztest/src/ztress.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include /* Flag set at startup which determines if stress test can run on this platform. diff --git a/tests/benchmarks/mbedtls/src/benchmark.c b/tests/benchmarks/mbedtls/src/benchmark.c index 985388faedc..12bc3cdc3d5 100644 --- a/tests/benchmarks/mbedtls/src/benchmark.c +++ b/tests/benchmarks/mbedtls/src/benchmark.c @@ -70,7 +70,7 @@ #include #include -#include +#include #include diff --git a/tests/boards/espressif_esp32/cache_coex/src/cache_coex.c b/tests/boards/espressif_esp32/cache_coex/src/cache_coex.c index b89b6c8aece..7f2370ed6e1 100644 --- a/tests/boards/espressif_esp32/cache_coex/src/cache_coex.c +++ b/tests/boards/espressif_esp32/cache_coex/src/cache_coex.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include /* definitions used in Flash & RAM operations */ diff --git a/tests/crypto/rand32/src/main.c b/tests/crypto/rand32/src/main.c index 7500fb42382..39cf40543bc 100644 --- a/tests/crypto/rand32/src/main.c +++ b/tests/crypto/rand32/src/main.c @@ -15,7 +15,7 @@ #include #include -#include +#include #define N_VALUES 10 diff --git a/tests/crypto/tinycrypt/src/ecc_dsa.c b/tests/crypto/tinycrypt/src/ecc_dsa.c index 96bf71fda83..f62f63c77dc 100644 --- a/tests/crypto/tinycrypt/src/ecc_dsa.c +++ b/tests/crypto/tinycrypt/src/ecc_dsa.c @@ -67,7 +67,7 @@ #include #include "test_ecc_utils.h" #include -#include +#include #include #include diff --git a/tests/drivers/disk/disk_performance/src/main.c b/tests/drivers/disk/disk_performance/src/main.c index 84402429082..7d3a67b7a51 100644 --- a/tests/drivers/disk/disk_performance/src/main.c +++ b/tests/drivers/disk/disk_performance/src/main.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #if defined(CONFIG_DISK_DRIVER_SDMMC) #define DISK_NAME CONFIG_SDMMC_VOLUME_NAME diff --git a/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf b/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf deleted file mode 120000 index 851b864e289..00000000000 --- a/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf +++ /dev/null @@ -1 +0,0 @@ -emulated_board.conf \ No newline at end of file diff --git a/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf b/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf new file mode 100644 index 00000000000..f8452191dba --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/boards/qemu_cortex_a53.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y diff --git a/tests/drivers/smbus/smbus_emul/src/smbus.c b/tests/drivers/smbus/smbus_emul/src/smbus.c index a41a4894662..1d2a3b5200e 100644 --- a/tests/drivers/smbus/smbus_emul/src/smbus.c +++ b/tests/drivers/smbus/smbus_emul/src/smbus.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/drivers/uart/uart_mix_fifo_poll/src/main.c b/tests/drivers/uart/uart_mix_fifo_poll/src/main.c index f26cce740c0..a080945a067 100644 --- a/tests/drivers/uart/uart_mix_fifo_poll/src/main.c +++ b/tests/drivers/uart/uart_mix_fifo_poll/src/main.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include /* RX and TX pins have to be connected together*/ #if DT_NODE_EXISTS(DT_NODELABEL(dut)) diff --git a/tests/kernel/sched/deadline/src/main.c b/tests/kernel/sched/deadline/src/main.c index f221ec8967e..a3fd777a779 100644 --- a/tests/kernel/sched/deadline/src/main.c +++ b/tests/kernel/sched/deadline/src/main.c @@ -5,7 +5,7 @@ */ #include #include -#include +#include #define NUM_THREADS 8 /* this should be large enough for us diff --git a/tests/kernel/timer/timer_api/src/timer_convert.c b/tests/kernel/timer/timer_api/src/timer_convert.c index 19b96419d1b..5e4d76723c7 100644 --- a/tests/kernel/timer/timer_api/src/timer_convert.c +++ b/tests/kernel/timer/timer_api/src/timer_convert.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #define NUM_RANDOM 100 diff --git a/tests/lib/hash_function/src/main.c b/tests/lib/hash_function/src/main.c index f793b9c72eb..510bd42e4be 100644 --- a/tests/lib/hash_function/src/main.c +++ b/tests/lib/hash_function/src/main.c @@ -6,7 +6,7 @@ #include -#include +#include #include #include diff --git a/tests/lib/mpsc_pbuf/src/concurrent.c b/tests/lib/mpsc_pbuf/src/concurrent.c index f23560785e9..313278d1f61 100644 --- a/tests/lib/mpsc_pbuf/src/concurrent.c +++ b/tests/lib/mpsc_pbuf/src/concurrent.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include LOG_MODULE_REGISTER(test); diff --git a/tests/lib/mpsc_pbuf/src/main.c b/tests/lib/mpsc_pbuf/src/main.c index 2f45903feaf..201eced47f9 100644 --- a/tests/lib/mpsc_pbuf/src/main.c +++ b/tests/lib/mpsc_pbuf/src/main.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #define PUT_EXT_LEN \ ((sizeof(union mpsc_pbuf_generic) + sizeof(void *)) / sizeof(uint32_t)) diff --git a/tests/lib/p4workq/src/main.c b/tests/lib/p4workq/src/main.c index 5730d2863ac..9567acd5def 100644 --- a/tests/lib/p4workq/src/main.c +++ b/tests/lib/p4workq/src/main.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include #include #include diff --git a/tests/lib/ringbuffer/src/concurrent.c b/tests/lib/ringbuffer/src/concurrent.c index b0d221ff95c..60e9aa1c263 100644 --- a/tests/lib/ringbuffer/src/concurrent.c +++ b/tests/lib/ringbuffer/src/concurrent.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include /** diff --git a/tests/lib/spsc_pbuf/src/main.c b/tests/lib/spsc_pbuf/src/main.c index 00332d673ea..55edbc65ede 100644 --- a/tests/lib/spsc_pbuf/src/main.c +++ b/tests/lib/spsc_pbuf/src/main.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #define HDR_LEN sizeof(uint32_t) #define TLEN(len) ROUND_UP(HDR_LEN + len, sizeof(uint32_t)) diff --git a/tests/net/arp/src/main.c b/tests/net/arp/src/main.c index 79965812286..a196599214f 100644 --- a/tests/net/arp/src/main.c +++ b/tests/net/arp/src/main.c @@ -25,7 +25,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_ARP_LOG_LEVEL); #include #include #include -#include +#include #include "arp.h" diff --git a/tests/net/checksum_offload/src/main.c b/tests/net/checksum_offload/src/main.c index 90beb4deb3c..bd248632151 100644 --- a/tests/net/checksum_offload/src/main.c +++ b/tests/net/checksum_offload/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/context/src/main.c b/tests/net/context/src/main.c index e6f69f00bd6..bad60738629 100644 --- a/tests/net/context/src/main.c +++ b/tests/net/context/src/main.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_CONTEXT_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/hostname/src/main.c b/tests/net/hostname/src/main.c index 3a5ad644f42..d2a56ca2782 100644 --- a/tests/net/hostname/src/main.c +++ b/tests/net/hostname/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include #include diff --git a/tests/net/iface/src/main.c b/tests/net/iface/src/main.c index 2c12e5e15bb..80042ff84bd 100644 --- a/tests/net/iface/src/main.c +++ b/tests/net/iface/src/main.c @@ -19,7 +19,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/igmp/src/main.c b/tests/net/igmp/src/main.c index 99e591e1d8a..473b66d3241 100644 --- a/tests/net/igmp/src/main.c +++ b/tests/net/igmp/src/main.c @@ -28,7 +28,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV4_LOG_LEVEL); #include #include -#include +#include #include "ipv4.h" diff --git a/tests/net/ip-addr/src/main.c b/tests/net/ip-addr/src/main.c index f3e37b29e29..23f8d4b6437 100644 --- a/tests/net/ip-addr/src/main.c +++ b/tests/net/ip-addr/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/ipv4_fragment/src/main.c b/tests/net/ipv4_fragment/src/main.c index 5ebe3817330..4db5b877d4f 100644 --- a/tests/net/ipv4_fragment/src/main.c +++ b/tests/net/ipv4_fragment/src/main.c @@ -13,7 +13,7 @@ LOG_MODULE_REGISTER(net_ipv4_test, CONFIG_NET_IPV4_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/tests/net/ipv6/src/main.c b/tests/net/ipv6/src/main.c index f9dd456cdca..6d8a1a5deee 100644 --- a/tests/net/ipv6/src/main.c +++ b/tests/net/ipv6/src/main.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/ipv6_fragment/src/main.c b/tests/net/ipv6_fragment/src/main.c index 0d76f9cedf0..890ddc32b57 100644 --- a/tests/net/ipv6_fragment/src/main.c +++ b/tests/net/ipv6_fragment/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV6_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/lib/dns_addremove/src/main.c b/tests/net/lib/dns_addremove/src/main.c index 9e0394ba819..6d992776800 100644 --- a/tests/net/lib/dns_addremove/src/main.c +++ b/tests/net/lib/dns_addremove/src/main.c @@ -13,7 +13,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_DNS_RESOLVER_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/lib/dns_resolve/src/main.c b/tests/net/lib/dns_resolve/src/main.c index 18ff9e42070..39e7d286dfb 100644 --- a/tests/net/lib/dns_resolve/src/main.c +++ b/tests/net/lib/dns_resolve/src/main.c @@ -13,7 +13,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_DNS_RESOLVER_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/lib/mqtt_publisher/src/test_mqtt_publish.c b/tests/net/lib/mqtt_publisher/src/test_mqtt_publish.c index 8e0a98c5feb..32dda35a78c 100644 --- a/tests/net/lib/mqtt_publisher/src/test_mqtt_publish.c +++ b/tests/net/lib/mqtt_publisher/src/test_mqtt_publish.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(net_test, LOG_LEVEL_WRN); #include #include -#include +#include #include "config.h" diff --git a/tests/net/lib/mqtt_pubsub/src/test_mqtt_pubsub.c b/tests/net/lib/mqtt_pubsub/src/test_mqtt_pubsub.c index 8887ef01ba4..606ab78a0ba 100644 --- a/tests/net/lib/mqtt_pubsub/src/test_mqtt_pubsub.c +++ b/tests/net/lib/mqtt_pubsub/src/test_mqtt_pubsub.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(net_test, LOG_LEVEL_WRN); #include #include #include -#include +#include #include #include diff --git a/tests/net/lib/mqtt_subscriber/src/test_mqtt_subscribe.c b/tests/net/lib/mqtt_subscriber/src/test_mqtt_subscribe.c index 974c4e153fb..ad09e8ecd96 100644 --- a/tests/net/lib/mqtt_subscriber/src/test_mqtt_subscribe.c +++ b/tests/net/lib/mqtt_subscriber/src/test_mqtt_subscribe.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(net_test, LOG_LEVEL_WRN); #include #include #include -#include +#include #include #include diff --git a/tests/net/mld/src/main.c b/tests/net/mld/src/main.c index 3846e61421f..d374b207cbd 100644 --- a/tests/net/mld/src/main.c +++ b/tests/net/mld/src/main.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV6_LOG_LEVEL); #include #include -#include +#include #include "icmpv6.h" #include "ipv6.h" diff --git a/tests/net/net_pkt/src/main.c b/tests/net/net_pkt/src/main.c index 1cf3516f785..29f5ba1080a 100644 --- a/tests/net/net_pkt/src/main.c +++ b/tests/net/net_pkt/src/main.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include diff --git a/tests/net/pm/src/main.c b/tests/net/pm/src/main.c index 5831bdf28e5..4aa7bffff7d 100644 --- a/tests/net/pm/src/main.c +++ b/tests/net/pm/src/main.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/net/ptp/clock/src/main.c b/tests/net/ptp/clock/src/main.c index 34cb6e19f3c..a00f3e0c540 100644 --- a/tests/net/ptp/clock/src/main.c +++ b/tests/net/ptp/clock/src/main.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include -#include +#include #define NET_LOG_ENABLED 1 #include "net_private.h" diff --git a/tests/net/route/src/main.c b/tests/net/route/src/main.c index da0c8d64d5b..1a48dd2ebc3 100644 --- a/tests/net/route/src/main.c +++ b/tests/net/route/src/main.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_ROUTE_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/route_mcast/src/main.c b/tests/net/route_mcast/src/main.c index cb10b830fa9..3db8a05fc0b 100644 --- a/tests/net/route_mcast/src/main.c +++ b/tests/net/route_mcast/src/main.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_ROUTE_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/shell/src/main.c b/tests/net/shell/src/main.c index 86d3ba1b45a..528958698f8 100644 --- a/tests/net/shell/src/main.c +++ b/tests/net/shell/src/main.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include "ipv4.h" #include "ipv6.h" diff --git a/tests/net/socket/af_packet_ipproto_raw/src/main.c b/tests/net/socket/af_packet_ipproto_raw/src/main.c index 840a1be25d4..95852262df7 100644 --- a/tests/net/socket/af_packet_ipproto_raw/src/main.c +++ b/tests/net/socket/af_packet_ipproto_raw/src/main.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/traffic_class/src/main.c b/tests/net/traffic_class/src/main.c index b48bb3db166..6187e124401 100644 --- a/tests/net/traffic_class/src/main.c +++ b/tests/net/traffic_class/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/tx_timestamp/src/main.c b/tests/net/tx_timestamp/src/main.c index c07bbb3246e..13561c53730 100644 --- a/tests/net/tx_timestamp/src/main.c +++ b/tests/net/tx_timestamp/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/udp/src/main.c b/tests/net/udp/src/main.c index 0457d38828a..0de851fffff 100644 --- a/tests/net/udp/src/main.c +++ b/tests/net/udp/src/main.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include "ipv4.h" #include "ipv6.h" diff --git a/tests/net/virtual/src/main.c b/tests/net/virtual/src/main.c index 9d9cef4ec99..be0ba1715b6 100644 --- a/tests/net/virtual/src/main.c +++ b/tests/net/virtual/src/main.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/vlan/src/main.c b/tests/net/vlan/src/main.c index 9ada9ff5b84..cfcab203193 100644 --- a/tests/net/vlan/src/main.c +++ b/tests/net/vlan/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/net/wifi/wifi_nm/src/main.c b/tests/net/wifi/wifi_nm/src/main.c index 0ca9e633553..43fcee530ec 100644 --- a/tests/net/wifi/wifi_nm/src/main.c +++ b/tests/net/wifi/wifi_nm/src/main.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #include #include #include -#include +#include #include diff --git a/tests/subsys/logging/log_stress/src/main.c b/tests/subsys/logging/log_stress/src/main.c index bf979b2d4c7..8ca43f47b3d 100644 --- a/tests/subsys/logging/log_stress/src/main.c +++ b/tests/subsys/logging/log_stress/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include From 97d608b98f9f5e255747ba49f1b365e5fe6f2025 Mon Sep 17 00:00:00 2001 From: Emil Lindqvist Date: Tue, 10 Oct 2023 08:11:49 +0200 Subject: [PATCH 1829/4498] display: stm32: fix bug where missing backlight pin causes crash When backlight pin is not defined, a display suspend will cause a crash since it looks at the wrong pin when deciding if it exists. Signed-off-by: Emil Lindqvist --- drivers/display/display_stm32_ltdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/display/display_stm32_ltdc.c b/drivers/display/display_stm32_ltdc.c index 81ca122ed22..99001c3b37b 100644 --- a/drivers/display/display_stm32_ltdc.c +++ b/drivers/display/display_stm32_ltdc.c @@ -336,7 +336,7 @@ static int stm32_ltdc_suspend(const struct device *dev) } /* Turn off backlight (if its GPIO is defined in device tree) */ - if (config->disp_on_gpio.port) { + if (config->bl_ctrl_gpio.port) { err = gpio_pin_set_dt(&config->bl_ctrl_gpio, 0); if (err < 0) { return err; From 916df03e7aeceb9164c62a326e81a86d74742bb7 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 9 Oct 2023 15:37:54 +0200 Subject: [PATCH 1830/4498] Bluetooth: ascs: Fix Source ASE link loss state transition According to the ASCS_v1.0 the ASE in Streaming state shall transit to QoS Configured state when link loss happen. Relates: ES-24215 (errata) Fixes: BAP/USR/SCC/BV-168-C Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/ascs.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index b74cc5ce284..2dd079e8172 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -357,10 +357,6 @@ static void ase_set_state_disabling(struct bt_ascs_ase *ase) if (ops != NULL && ops->disabled != NULL) { ops->disabled(stream); } - - if (ase->unexpected_iso_link_loss) { - ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_QOS_CONFIGURED); - } } static void ase_set_state_releasing(struct bt_ascs_ase *ase) @@ -475,7 +471,11 @@ int ascs_ep_set_state(struct bt_bap_ep *ep, uint8_t state) break; case BT_BAP_EP_STATE_ENABLING: case BT_BAP_EP_STATE_STREAMING: - valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SINK; + /* Source ASE transition Streaming->QoS configured is valid on case of CIS + * link-loss. + */ + valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SINK || + ase->unexpected_iso_link_loss; break; default: break; @@ -879,20 +879,14 @@ static void ascs_ep_iso_disconnected(struct bt_bap_ep *ep, uint8_t reason) if (ep->status.state == BT_BAP_EP_STATE_RELEASING) { ascs_ep_set_state(ep, BT_BAP_EP_STATE_IDLE); - } else if (ep->status.state == BT_BAP_EP_STATE_STREAMING) { - /* CIS has been unexpectedly disconnected */ - ase->unexpected_iso_link_loss = true; - - /* The ASE state machine goes into different states from this operation - * based on whether it is a source or a sink ASE. + } else if (ep->status.state == BT_BAP_EP_STATE_STREAMING || + ep->status.state == BT_BAP_EP_STATE_DISABLING) { + /* ASCS_v1.0 3.2 ASE state machine transitions + * + * If the server detects link loss of a CIS for an ASE in the Streaming + * state or the Disabling state, the server shall immediately transition + * that ASE to the QoS Configured state. */ - if (ep->dir == BT_AUDIO_DIR_SOURCE) { - ascs_ep_set_state(ep, BT_BAP_EP_STATE_DISABLING); - } else { - ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED); - } - } else if (ep->status.state == BT_BAP_EP_STATE_DISABLING) { - /* CIS has been unexpectedly disconnected */ ase->unexpected_iso_link_loss = true; ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED); From 493fe169a885b8e5a0b77537ed3692ce25b0b707 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 10 Oct 2023 15:00:42 +0300 Subject: [PATCH 1831/4498] drivers: eswifi: Fix the SSID copying The wrong ssid_len was used which causes build error. Signed-off-by: Jukka Rissanen --- drivers/wifi/eswifi/eswifi_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index f4794bbb8b3..0beecd4a4fc 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -491,7 +491,7 @@ int eswifi_mgmt_iface_status(const struct device *dev, status->state = WIFI_STATE_COMPLETED; status->ssid_len = strnlen(sta->ssid, WIFI_SSID_MAX_LEN); - strncpy(status->ssid, sta->ssid, sta->ssid_len); + strncpy(status->ssid, sta->ssid, status->ssid_len); status->band = WIFI_FREQ_BAND_2_4_GHZ; status->channel = 0; From 2fcf4e34991a31f79037c8bc4c208657ddedc67c Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Thu, 5 Oct 2023 13:41:15 +0200 Subject: [PATCH 1832/4498] scripts: pylib: build_helpers: flash_order fix If flash_order were to be missing from the YAML, the Domains init would crash instead of substituting an empty list. This commit fixes that. Signed-off-by: Lukasz Mrugala --- scripts/pylib/build_helpers/domains.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 978569d9547..760217cc282 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -78,7 +78,7 @@ def __init__(self, domains_yaml): # Now that self._domains has been initialized, we can leverage # the common checks in self.get_domain to verify this. self._default_domain = self.get_domain(data['default']) - self._flash_order = self.get_domains(data['flash_order'] or []) + self._flash_order = self.get_domains(data.get('flash_order', [])) @staticmethod def from_file(domains_file): From 76f9a024c3e86f7b627994751907823f4da294bd Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Thu, 5 Oct 2023 13:43:43 +0200 Subject: [PATCH 1833/4498] scripts: tests: twister: Domains tests fix PR #63195 has changed how Domains work without triggering necessary tests, thus breaking them. This commit fixes the domains tests. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_domains.py | 171 ++++++++++++++++---------- 1 file changed, 104 insertions(+), 67 deletions(-) diff --git a/scripts/tests/twister/test_domains.py b/scripts/tests/twister/test_domains.py index 27b32ebbe15..2222b142693 100644 --- a/scripts/tests/twister/test_domains.py +++ b/scripts/tests/twister/test_domains.py @@ -23,21 +23,9 @@ ('', False, 1, ['domains.yaml file not found: domains.yaml']), ( """ -default: some default -build_dir: my/dir -domains: -- name: some default - build_dir: dir/2 -- name: another - build_dir: dir/3 -flash_order: I don\'t think this is correct -""", - True, 1, ['ERROR: Malformed yaml in file: domains.yaml'] - ), - ( -""" default: None build_dir: some/dir +domains: [] """, True, None, [] ), @@ -46,7 +34,7 @@ @pytest.mark.parametrize( 'f_contents, f_exists, exit_code, expected_logs', TESTDATA_1, - ids=['no file', 'schema error', 'valid'] + ids=['no file', 'valid'] ) def test_from_file(caplog, f_contents, f_exists, exit_code, expected_logs): def mock_open(*args, **kwargs): @@ -71,43 +59,51 @@ def mock_open(*args, **kwargs): TESTDATA_2 = [ - ({'build_dir': None, 'default': None}, True, None, [], None, {}), ( - { - 'build_dir': os.path.join('build', 'dir'), - 'domains': [ - { - 'name': 'a domain', - 'build_dir': os.path.join('dir', '1') - }, - { - 'name': 'default_domain', - 'build_dir': os.path.join('dir', '2') - } - ], - 'default': 'default_domain', - 'flash_order': ['default_domain', 'a domain'] - }, - False, - os.path.join('build', 'dir'), - [('default_domain', os.path.join('dir', '2')), - ('a domain', os.path.join('dir', '1'))], - ('default_domain', os.path.join('dir', '2')), - {'a domain': ('a domain', os.path.join('dir', '1')), - 'default_domain': ('default_domain', os.path.join('dir', '2'))} +""" +default: some default +build_dir: my/dir +domains: +- name: some default + build_dir: dir/2 +- name: another + build_dir: dir/3 +flash_order: I don\'t think this is correct +""", + 1, None, None, None, None + ), + ( +""" +build_dir: build/dir +domains: +- name: a domain + build_dir: dir/1 +- name: default_domain + build_dir: dir/2 +default: default_domain +flash_order: +- default_domain +- a domain +""", + None, + 'build/dir', + [('default_domain', 'dir/2'), ('a domain', 'dir/1')], + ('default_domain', 'dir/2'), + {'a domain': ('a domain', 'dir/1'), + 'default_domain': ('default_domain', 'dir/2')} ), ] @pytest.mark.parametrize( - 'data, expect_warning, expected_build_dir, expected_flash_order,' \ + 'data, exit_code, expected_build_dir, expected_flash_order,' \ ' expected_default, expected_domains', TESTDATA_2, - ids=['required only', 'with default domain'] + ids=['invalid', 'valid'] ) -def test_from_data( +def test_from_yaml( caplog, data, - expect_warning, + exit_code, expected_build_dir, expected_flash_order, expected_default, @@ -116,15 +112,13 @@ def test_from_data( def mock_domain(name, build_dir, *args, **kwargs): return name, build_dir - warning_log = "no domains defined; this probably won't work" + with mock.patch('domains.Domain', side_effect=mock_domain), \ + pytest.raises(SystemExit) if exit_code else nullcontext() as exit_st: + doms = domains.Domains.from_yaml(data) - with mock.patch('domains.Domain', side_effect=mock_domain): - doms = domains.Domains.from_data(data) - - if expect_warning: - assert warning_log in caplog.text - else: - assert warning_log not in caplog.text + if exit_code: + assert str(exit_st.value) == str(exit_code) + return assert doms.get_default_domain() == expected_default assert doms.get_top_build_dir() == expected_build_dir @@ -139,50 +133,93 @@ def mock_domain(name, build_dir, *args, **kwargs): ( None, True, - None, - [], [('some', os.path.join('dir', '2')), ('order', os.path.join('dir', '1'))] ), ( None, False, - None, - [], [('order', os.path.join('dir', '1')), ('some', os.path.join('dir', '2'))] ), - ( - ['some', 'other'], - False, - 1, - ['domain other not found, valid domains are: order, some'], - [('some', os.path.join('dir', '2')), - ('order', os.path.join('dir', '1'))] - ), ( ['some'], False, - None, - [], [('some', os.path.join('dir', '2'))] ), ] @pytest.mark.parametrize( - 'names, default_flash_order, exit_code, expected_logs, expected_result', + 'names, default_flash_order, expected_result', TESTDATA_3, - ids=['order only', 'no parameters', 'domain not found', 'valid'] + ids=['order only', 'no parameters', 'valid'] ) def test_get_domains( caplog, names, default_flash_order, + expected_result +): + doms = domains.Domains( +""" +domains: +- name: dummy + build_dir: dummy +default: dummy +build_dir: dummy +""" + ) + doms._flash_order = [ + ('some', os.path.join('dir', '2')), + ('order', os.path.join('dir', '1')) + ] + doms._domains = { + 'order': ('order', os.path.join('dir', '1')), + 'some': ('some', os.path.join('dir', '2')) + } + + result = doms.get_domains(names, default_flash_order) + + assert result == expected_result + + + +TESTDATA_3 = [ + ( + 'other', + 1, + ['domain "other" not found, valid domains are: order, some'], + None + ), + ( + 'some', + None, + [], + ('some', os.path.join('dir', '2')) + ), +] + +@pytest.mark.parametrize( + 'name, exit_code, expected_logs, expected_result', + TESTDATA_3, + ids=['domain not found', 'valid'] +) +def test_get_domain( + caplog, + name, exit_code, expected_logs, expected_result ): - doms = domains.Domains({'domains': [], 'default': None}) + doms = domains.Domains( +""" +domains: +- name: dummy + build_dir: dummy +default: dummy +build_dir: dummy +""" + ) doms._flash_order = [ ('some', os.path.join('dir', '2')), ('order', os.path.join('dir', '1')) @@ -193,7 +230,7 @@ def test_get_domains( } with pytest.raises(SystemExit) if exit_code else nullcontext() as s_exit: - result = doms.get_domains(names, default_flash_order) + result = doms.get_domain(name) assert all([log in caplog.text for log in expected_logs]) From eeb142d40976eec4edcd1a6e144a6d23e4f9d50c Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Thu, 5 Oct 2023 13:45:28 +0200 Subject: [PATCH 1834/4498] .github: workflows: Workflow for build_helpers PR #63195 has managed to change code under test without triggering those tests. This change should remedy that by creating a new workflow, based on twister_tests.yaml, that runs tests in scripts/tests/build_helpers if build_helpers are modified. Such a workflow should be easily extendable if we ever have more non-Twister things to test in scripts/pylib. Signed-off-by: Lukasz Mrugala --- .github/workflows/pylib_tests.yml | 54 +++++++++++++++++++ .../test_domains.py | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pylib_tests.yml rename scripts/tests/{twister => build_helpers}/test_domains.py (98%) diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml new file mode 100644 index 00000000000..06f61f32c24 --- /dev/null +++ b/.github/workflows/pylib_tests.yml @@ -0,0 +1,54 @@ +# Copyright (c) 2023 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +name: Misc. Pylib Scripts TestSuite + +on: + push: + branches: + - main + - v*-branch + paths: + - 'scripts/pylib/build_helpers/**' + - '.github/workflows/pylib_tests.yml' + pull_request: + branches: + - main + - v*-branch + paths: + - 'scripts/pylib/build_helpers/**' + - '.github/workflows/pylib_tests.yml' + +jobs: + pylib-tests: + name: Misc. Pylib Unit Tests + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [3.8, 3.9, '3.10'] + os: [ubuntu-22.04] + steps: + - name: checkout + uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: cache-pip-linux + if: startsWith(runner.os, 'Linux') + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }} + - name: install-packages + run: | + pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt + - name: Run pytest for build_helpers + env: + ZEPHYR_BASE: ./ + ZEPHYR_TOOLCHAIN_VARIANT: zephyr + run: | + echo "Run build_helpers tests" + PYTHONPATH=./scripts/tests pytest ./scripts/tests/build_helpers diff --git a/scripts/tests/twister/test_domains.py b/scripts/tests/build_helpers/test_domains.py similarity index 98% rename from scripts/tests/twister/test_domains.py rename to scripts/tests/build_helpers/test_domains.py index 2222b142693..0ebdeaf6cb2 100644 --- a/scripts/tests/twister/test_domains.py +++ b/scripts/tests/build_helpers/test_domains.py @@ -12,7 +12,7 @@ import sys ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") -sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) +sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/build_helpers")) import domains From 22042e7b4e63faecf6b4f629d1a9346bf74fd928 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 12:24:58 +0000 Subject: [PATCH 1835/4498] ci: tags: include wifi/net drivers in the net group Changes to networking and wifi drivers should trigger networking tests. Signed-off-by: Anas Nashif --- scripts/ci/tags.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/ci/tags.yaml b/scripts/ci/tags.yaml index 32088673057..b9152b10d68 100644 --- a/scripts/ci/tags.yaml +++ b/scripts/ci/tags.yaml @@ -50,6 +50,11 @@ net: files: - subsys/net/ - include/zephyr/net/ + - drivers/wifi/ + - drivers/net/ + - drivers/ethernet/ + - drivers/ieee802154/ + - drivers/ptp_clock/ test_framework: files: From f8455b410e1000240e5c267f3cd3c8c1f65e3a47 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 3 Oct 2023 13:15:59 +0200 Subject: [PATCH 1836/4498] west runner: Add exe file to configuration Add the exe fle to the runnerconfiguration class, so we can use it from runners which will need it. Signed-off-by: Alberto Escolar Piedras --- cmake/flash/CMakeLists.txt | 8 ++++++++ scripts/west_commands/run_common.py | 1 + scripts/west_commands/runners/core.py | 1 + scripts/west_commands/tests/conftest.py | 3 ++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 892cfa081e8..392274891f1 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -36,6 +36,14 @@ function(runners_yaml_append_config) get_runners_prop(elf_file elf "${KERNEL_ELF_NAME}") runners_yaml_append(" # Build outputs:") runners_yaml_append(" elf_file: ${elf}") + if(CONFIG_BUILD_OUTPUT_EXE) + get_runners_prop(exe_file exe "${KERNEL_EXE_NAME}") + else() + get_runners_prop(exe_file exe "") + endif() + if(exe) + runners_yaml_append(" exe_file: ${exe}") + endif() if(CONFIG_BUILD_OUTPUT_HEX) get_runners_prop(hex_file hex "${KERNEL_HEX_NAME}") else() diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py index ba62c5c46f7..43d736f2b68 100644 --- a/scripts/west_commands/run_common.py +++ b/scripts/west_commands/run_common.py @@ -411,6 +411,7 @@ def filetype(attr): return RunnerConfig(build_dir, yaml_config['board_dir'], output_file('elf'), + output_file('exe'), output_file('hex'), output_file('bin'), output_file('uf2'), diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index c1f9eb7439f..fa697fa66cf 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -283,6 +283,7 @@ class RunnerConfig(NamedTuple): build_dir: str # application build directory board_dir: str # board definition directory elf_file: Optional[str] # zephyr.elf path, or None + exe_file: Optional[str] # zephyr.exe path, or None hex_file: Optional[str] # zephyr.hex path, or None bin_file: Optional[str] # zephyr.bin path, or None uf2_file: Optional[str] # zephyr.uf2 path, or None diff --git a/scripts/west_commands/tests/conftest.py b/scripts/west_commands/tests/conftest.py index da89a2df571..0224ad95a64 100644 --- a/scripts/west_commands/tests/conftest.py +++ b/scripts/west_commands/tests/conftest.py @@ -11,6 +11,7 @@ RC_BUILD_DIR = '/test/build-dir' RC_BOARD_DIR = '/test/zephyr/boards/test-arch/test-board' RC_KERNEL_ELF = 'test-zephyr.elf' +RC_KERNEL_EXE = 'test-zephyr.exe' RC_KERNEL_HEX = 'test-zephyr.hex' RC_KERNEL_BIN = 'test-zephyr.bin' RC_GDB = 'test-none-gdb' @@ -21,7 +22,7 @@ @pytest.fixture def runner_config(): '''Fixture which provides a runners.core.RunnerConfig.''' - return RunnerConfig(RC_BUILD_DIR, RC_BOARD_DIR, RC_KERNEL_ELF, + return RunnerConfig(RC_BUILD_DIR, RC_BOARD_DIR, RC_KERNEL_ELF, RC_KERNEL_EXE, RC_KERNEL_HEX, RC_KERNEL_BIN, None, FileType.OTHER, gdb=RC_GDB, openocd=RC_OPENOCD, openocd_search=RC_OPENOCD_SEARCH) From 07e88a9fba659b0cb3eb2aa3ea25f61c0d9cb1d4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 3 Oct 2023 13:49:50 +0200 Subject: [PATCH 1837/4498] west native_gdb runner: Fix to use exe instead of elf The runnable output from the build system is the exe file. In native_posix the elf happend to also be runnable, but this is not the case in general, and not for native_sim or the nrf5*bsim boards. So lets use the exe instead. Signed-off-by: Alberto Escolar Piedras --- scripts/west_commands/runners/native_gdb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/west_commands/runners/native_gdb.py b/scripts/west_commands/runners/native_gdb.py index 777290cd3e8..163fe01793b 100644 --- a/scripts/west_commands/runners/native_gdb.py +++ b/scripts/west_commands/runners/native_gdb.py @@ -36,11 +36,11 @@ def do_run(self, command: str, **kwargs): if self.cfg.gdb is None: raise ValueError("The provided RunnerConfig is missing the required field 'gdb'.") - if self.cfg.elf_file is None: - raise ValueError("The provided RunnerConfig is missing the required field 'elf_file'.") + if self.cfg.exe_file is None: + raise ValueError("The provided RunnerConfig is missing the required field 'exe_file'.") self.call([ self.cfg.gdb, '--quiet', - self.cfg.elf_file, + self.cfg.exe_file, ]) From 9ce33d7512e1809e3e989541c1c1a4b1f2aac27a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 3 Oct 2023 13:51:19 +0200 Subject: [PATCH 1838/4498] native sim: Set native_gdb as debug runner Set native_gdb as the runner for the debug build target. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_sim/board.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/posix/native_sim/board.cmake b/boards/posix/native_sim/board.cmake index 0ec9fc6a83a..d9d444c1be9 100644 --- a/boards/posix/native_sim/board.cmake +++ b/boards/posix/native_sim/board.cmake @@ -1,3 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 set(SUPPORTED_EMU_PLATFORMS native) + +board_set_debugger_ifnset(native_gdb) +board_finalize_runner_args(native_gdb) From b1515ac3648bb7af016d5947f384f5877e3c0bcd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 3 Oct 2023 14:46:47 +0200 Subject: [PATCH 1839/4498] boards nrf_bsim: Set native_gdb as debug runner Set native_gdb as the runner for the debug build target Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/board.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/posix/nrf_bsim/board.cmake b/boards/posix/nrf_bsim/board.cmake index 0ec9fc6a83a..d9d444c1be9 100644 --- a/boards/posix/nrf_bsim/board.cmake +++ b/boards/posix/nrf_bsim/board.cmake @@ -1,3 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 set(SUPPORTED_EMU_PLATFORMS native) + +board_set_debugger_ifnset(native_gdb) +board_finalize_runner_args(native_gdb) From 86d606ba2dcc7d384cf0f8f44020fc2aaf98fe0a Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Fri, 6 Oct 2023 16:26:23 +0200 Subject: [PATCH 1840/4498] flash: nxp: fix lpc55s36 flash read Add additional check if page is erased, to avoid a possible fault exception. Fixes #63087 Signed-off-by: Andrej Butok --- drivers/flash/soc_flash_mcux.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index a8b2d282107..f3f4059da44 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -193,9 +193,18 @@ static int flash_mcux_read(const struct device *dev, off_t offset, #ifdef CONFIG_CHECK_BEFORE_READING #ifdef CONFIG_SOC_LPC55S36 + /* Validates the given address range is loaded in the flash hiding region. */ rc = FLASH_IsFlashAreaReadable(&priv->config, addr, len); if (rc != kStatus_FLASH_Success) { rc = -EIO; + } else { + /* Check whether the flash is erased ("len" and "addr" must be word-aligned). */ + rc = FLASH_VerifyErase(&priv->config, ((addr + 0x3) & ~0x3), ((len + 0x3) & ~0x3)); + if (rc == kStatus_FLASH_Success) { + rc = -ENODATA; + } else { + rc = 0; + } } #else rc = is_area_readable(addr, len); From 416dde7dd141d8873be64e5206d851c94153a1ab Mon Sep 17 00:00:00 2001 From: Stefan Petersen Date: Mon, 9 Oct 2023 14:29:23 +0200 Subject: [PATCH 1841/4498] drivers: ethernet: eth_stm32_hal.c Fix mixup of DMA error and MAC error There seems to be a copy-paste error where GetDMAError() et al is used twice. The comment states that it is actually getMACError() et al that should be used in the second instance. Signed-off-by: Stefan Petersen --- drivers/ethernet/eth_stm32_hal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ethernet/eth_stm32_hal.c b/drivers/ethernet/eth_stm32_hal.c index bdb4771d01f..755134359eb 100644 --- a/drivers/ethernet/eth_stm32_hal.c +++ b/drivers/ethernet/eth_stm32_hal.c @@ -489,10 +489,10 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) } /* Check for MAC errors */ - if (HAL_ETH_GetDMAError(heth)) { - LOG_ERR("%s: ETH DMA error: macerror:%x", + if (HAL_ETH_GetMACError(heth)) { + LOG_ERR("%s: ETH MAC error: macerror:%x", __func__, - HAL_ETH_GetDMAError(heth)); + HAL_ETH_GetMACError(heth)); /* MAC errors are putting in error state*/ /* TODO recover from this */ } From 9ea9c85f00b3973810ec355caea4e91f341b6f71 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 3 Oct 2023 11:04:02 +0100 Subject: [PATCH 1842/4498] doc: retained_mem: Add note on mutex configuration Adds a note on how to configure and what to beware of when disabling mutex support in a multithreading application Signed-off-by: Jamie McCrae --- doc/hardware/peripherals/retained_mem.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/hardware/peripherals/retained_mem.rst b/doc/hardware/peripherals/retained_mem.rst index bed5694d451..07fb20bbd88 100644 --- a/doc/hardware/peripherals/retained_mem.rst +++ b/doc/hardware/peripherals/retained_mem.rst @@ -17,6 +17,20 @@ Related configuration options: * :kconfig:option:`CONFIG_RETAINED_MEM` * :kconfig:option:`CONFIG_RETAINED_MEM_INIT_PRIORITY` +* :kconfig:option:`CONFIG_RETAINED_MEM_MUTEX_FORCE_DISABLE` + +Mutex protection +**************** + +Mutex protection of retained memory drivers is enabled by default when +applications are compiled with multithreading support. This means that +different threads can safely call the retained memory functions without +clashing with other concurrent thread function usage, but means that retained +memory functions cannot be used from ISRs. It is possible to disable mutex +protection globally on all retained memory drivers by enabling +:kconfig:option:`CONFIG_RETAINED_MEM_MUTEX_FORCE_DISABLE` - users are then +responsible for ensuring that the function calls do not conflict with each +other. API Reference ************* From 365a6f5da00798f97da2de732cc666ff4722e234 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 3 Oct 2023 11:04:48 +0100 Subject: [PATCH 1843/4498] doc: retention: Add note on mutex configuration Adds a note on how to configure and what to beware of when disabling mutex support in a multithreading application Signed-off-by: Jamie McCrae --- doc/services/retention/index.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/services/retention/index.rst b/doc/services/retention/index.rst index dc4572ec090..1f6de06eae2 100644 --- a/doc/services/retention/index.rst +++ b/doc/services/retention/index.rst @@ -121,6 +121,20 @@ When the write function is called, the magic header and checksum (if enabled) will be set on the area, and it will be marked as valid from that point onwards. +Mutex protection +**************** + +Mutex protection of retention areas is enabled by default when applications are +compiled with multithreading support. This means that different threads can +safely call the retention functions without clashing with other concurrent +thread function usage, but means that retention functions cannot be used from +ISRs. It is possible to disable mutex protection globally on all retention +areas by enabling :kconfig:option:`CONFIG_RETENTION_MUTEX_FORCE_DISABLE` - +users are then responsible for ensuring that the function calls do not conflict +with each other. Note that to use this, retention driver mutex support must +also be disabled by enabling +:kconfig:option:`CONFIG_RETAINED_MEM_MUTEX_FORCE_DISABLE`. + .. _boot_mode_api: Boot mode From ae109c6ea5f4a9b4255599d9a0e82e4d139e37a4 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 9 Oct 2023 13:01:54 +0200 Subject: [PATCH 1844/4498] doc: release-notes: Add 3.5.0 release notes for networking Add 3.5.0 release notes for networking. Signed-off-by: Robert Lubos --- doc/releases/release-notes-3.5.rst | 155 +++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 8 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 882c42b66e1..c1988eac1cb 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -492,19 +492,35 @@ Drivers and Sensors Networking ********** -* Time and timestamps in the network subsystem, PTP and IEEE 802.15.4 - were more precisely specified and all in-tree call sites updated accordingly. - Fields for timed TX and TX/RX timestamps have been consolidated. See - :c:type:`net_time_t`, :c:struct:`net_ptp_time`, :c:struct:`ieee802154_config`, - :c:struct:`ieee802154_radio_api` and :c:struct:`net_pkt` for extensive - documentation. As this is largely an internal API, existing applications will - most probably continue to work unchanged. - * CoAP: + * Optimized CoAP client library to use only a single thread internally. + * Converted CoAP client library to use ``zsock_*`` API internally. + * Fixed a bug in CoAP client library, which resulted in an incorrect + retransmission timeout calculation. * Use 64 bit timer values for calculating transmission timeouts. This fixes potential problems for devices that stay on for more than 49 days when the 32 bit uptime counter might roll over and cause CoAP packets to not timeout at all on this event. + * API documentation improvements. + * Added new API functions: + + * :c:func:`coap_has_descriptive_block_option` + * :c:func:`coap_remove_descriptive_block_option` + * :c:func:`coap_packet_remove_option` + * :c:func:`coap_packet_set_path` + +* Connection Manager: + + * Added support for auto-connect and auto-down behaviors (controlled by + :c:enum:`CONN_MGR_IF_NO_AUTO_CONNECT` and :c:enum:`CONN_MGR_IF_NO_AUTO_DOWN` + flags). + * Split Connection Manager APIs into separate header files. + * Extended Connection Manager documentation to cover new functionalities. + +* DHCP: + + * Added support for DHCPv4 unicast replies processing. + * Added support for DHCPv6 protocol. * Ethernet: @@ -516,12 +532,135 @@ Networking * Added support for detecting gPTP packets that use the default multicast destination address. * Fixed Announce and Follow Up message handling. +* ICMP: + + * Fixed ICMPv6 error message type check. + * Reworked ICMP callback registration and handling, which allows to register + multiple handlers for the same ICMP message. + * Introduced an API to send ICMP Echo Request (ping). + * Added possibility to register offloaded ICMP ping handlers. + * Added support for setting packet priority for ping. + +* IPv6: + + * Made sure that ongoing DAD procedure is cancelled when IPv6 address is removed. + * Fixed a bug, where Solicited-Node multicast address could be removed while + still in use. + * LwM2M: * Added support for tickless mode. This removes the 500 ms timeout from the socket loop so the engine does not constantly wake up the CPU. This can be enabled by :kconfig:option:`CONFIG_LWM2M_TICKLESS`. * Added new :c:macro:`LWM2M_RD_CLIENT_EVENT_DEREGISTER` event. + * Block-wise sending now supports LwM2M read and composite-read operations as well. + When :kconfig:option:`CONFIG_LWM2M_COAP_BLOCK_TRANSFER` is enabled, any content that is larger + than :kconfig:option:`CONFIG_LWM2M_COAP_MAX_MSG_SIZE` is split into a block-wise transfer. + * Block-wise transfers don't require tokens to match anymore as this was not in line + with CoAP specification (CoAP doesn't require tokens re-use). + * Various fixes to bootstrap. Now client ensures that Bootstrap-Finish command is sent, + before closing the DTLS pipe. Also allows Bootstrap server to close the DTLS pipe. + Added timeout when waiting for bootstrap commands. + * Added support for X509 certificates. + * Various fixes to string handling. Allow setting string to zero length. + Ensure string termination when using string operations on opaque resources. + * Added support for Connection Monitoring object version 1.3. + * Added protection for Security object to prevent read/writes by the server. + * Fixed a possible notification stall in case of observation token change. + * Added new shell command, ``lwm2m create``, which allows to create LwM2M object instances. + * Added LwM2M interoperability test-suite against Leshan server. + * API documentation improvements. + * Several other minor fixes and improvements. + +* Misc: + + * Time and timestamps in the network subsystem, PTP and IEEE 802.15.4 + were more precisely specified and all in-tree call sites updated accordingly. + Fields for timed TX and TX/RX timestamps have been consolidated. See + :c:type:`net_time_t`, :c:struct:`net_ptp_time`, :c:struct:`ieee802154_config`, + :c:struct:`ieee802154_radio_api` and :c:struct:`net_pkt` for extensive + documentation. As this is largely an internal API, existing applications will + most probably continue to work unchanged. + * Added support for additional net_pkt filter hooks: + + * :kconfig:option:`CONFIG_NET_PKT_FILTER_IPV4_HOOK` + * :kconfig:option:`CONFIG_NET_PKT_FILTER_IPV6_HOOK` + * :kconfig:option:`CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK` + + * Reworked several networking components to use timepoint API. + * Added API functions facilitate going through all IPv4/IPv6 registered on an + interface (:c:func:`net_if_ipv4_addr_foreach`, :c:func:`net_if_ipv6_addr_foreach`). + * ``NET_EVENT_IPV6_PREFIX_ADD`` and ``NET_EVENT_IPV6_PREFIX_DEL`` events now provide + more detailed information about the prefix (:c:struct:`net_event_ipv6_prefix`). + * General cleanup of the shadowed variables across the networking subsystem. + * Added ``qemu_cortex_a53`` networking support. + * Introduced new modem subsystem. + * Added new :zephyr:code-sample:`cellular-modem` sample. + * Added support for network interface names (instead of reusing underlying device name). + * Removed support for Google Cloud IoT sample due to service retirement. + * Fixed a bug where packets passed in promiscuous mode could have been modified + by L2 in certain cases. + * Added support for setting syslog server (used for networking log backend) + IP address at runtime. + * Removed no longer used ``queued`` and ``sent`` net_pkt flags. + * Added support for binding zperf TCP/UDP server to a specific IP address. + +* MQTT-SN: + + * Improved thread safety of internal buffers allocation. + * API documentation improvements. + +* OpenThread: + + * Reworked :c:func:`otPlatEntropyGet` to use :c:func:`sys_csrand_get` internally. + * Introduced ``ieee802154_radio_openthread.h`` radio driver extension interface + specific for OpenThread. Added new transmit mode, specific to OpenThread, + :c:enum:`IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA`. + +* PPP: + + * Fixed PPP L2 usage of the network interface carrier state. + * Made PPP L2 thread priority configurable (:kconfig:option:`CONFIG_NET_L2_PPP_THREAD_PRIO`). + * Moved PPP L2 out of experimental stage. + * Prevent PPP connection reestablish when carrier is down. + +* Sockets: + + * Added support for statically allocated socketpairs (in case no heap is available). + * Made send timeout configurable (:kconfig:option:`CONFIG_NET_SOCKET_MAX_SEND_WAIT`). + * Added support for ``FIONREAD`` and ``FIONBIO`` :c:func:`ioctl` commands. + * Fixed input filtering for connected datagram sockets. + * Fixed :c:func:`getsockname` operation on unconnected sockets. + * Added new secure socket options for DTLS Connection ID support: + + * :c:macro:`TLS_DTLS_CID` + * :c:macro:`TLS_DTLS_CID_VALUE` + * :c:macro:`TLS_DTLS_PEER_CID_VALUE` + * :c:macro:`TLS_DTLS_CID_STATUS` + + * Added support for :c:macro:`SO_REUSEADDR` and :c:macro:`SO_REUSEPORT` socket options. + +* TCP: + + * Fixed potential stall in data retransmission, when data was only partially acknowledged. + * Made TCP work queue priority configurable (:kconfig:option:`CONFIG_NET_TCP_WORKER_PRIO`). + * Added support for TCP new Reno collision avoidance algorithm. + * Fixed source address selection on bound sockets. + * Fixed possible memory leak in case listening socket was closed during active handshake. + * Fixed RST packet handling during handshake. + * Refactored the code responsible for connection teardown to fix found bugs and + simplify future maintenance. + +* TFTP: + + * Added new :zephyr:code-sample:`tftp-client` sample. + * API documentation improvements. + +* WebSocket + + * WebSocket library no longer closes underlying TCP socket automatically on disconnect. + This aligns with the connect behavior, where the WebSocket library expects an already + connected TCP socket. * Wi-Fi: From fdaba20b2cef812d611d2d2f665d43c9f20c2833 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 10 Oct 2023 10:35:14 +0200 Subject: [PATCH 1845/4498] doc: net: Add page for net_time So that the type is visible and "referencable" in the documentation. Signed-off-by: Robert Lubos --- doc/connectivity/networking/api/net_time.rst | 9 +++++++++ doc/connectivity/networking/api/tsn.rst | 1 + include/zephyr/net/net_time.h | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 doc/connectivity/networking/api/net_time.rst diff --git a/doc/connectivity/networking/api/net_time.rst b/doc/connectivity/networking/api/net_time.rst new file mode 100644 index 00000000000..b736d9f1ed6 --- /dev/null +++ b/doc/connectivity/networking/api/net_time.rst @@ -0,0 +1,9 @@ +.. _net_time_interface: + +Network time representation in the network stack +################################################ + +API Reference +************* + +.. doxygengroup:: net_time diff --git a/doc/connectivity/networking/api/tsn.rst b/doc/connectivity/networking/api/tsn.rst index 50e594c4a71..c9d00cfcc5c 100644 --- a/doc/connectivity/networking/api/tsn.rst +++ b/doc/connectivity/networking/api/tsn.rst @@ -7,4 +7,5 @@ Time Sensitive Networking :maxdepth: 1 gptp.rst + net_time.rst ptp_time.rst diff --git a/include/zephyr/net/net_time.h b/include/zephyr/net/net_time.h index 17795a9df95..3e37ccacedb 100644 --- a/include/zephyr/net/net_time.h +++ b/include/zephyr/net/net_time.h @@ -12,6 +12,10 @@ * Inspired by * https://github.com/torvalds/linux/blob/master/include/linux/ktime.h and * https://github.com/torvalds/linux/blob/master/[tools/]include/linux/time64.h + * + * @defgroup net_time Network time representation. + * @ingroup networking + * @{ */ #ifndef ZEPHYR_INCLUDE_NET_NET_TIME_H_ @@ -112,4 +116,8 @@ typedef int64_t net_time_t; } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_NET_NET_TIME_H_ */ From c5064cf70835f1dd730932c0dd28b0a7ec9a0ff3 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Tue, 10 Oct 2023 11:51:12 +0200 Subject: [PATCH 1846/4498] doc: release-notes: Add 3.5.0 release notes for LVGL Added section for LVGL changes done for release 3.5.0. Signed-off-by: Fabian Blatz --- doc/releases/release-notes-3.5.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c1988eac1cb..6f67f0080d2 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -872,6 +872,20 @@ Nanopb * Added helper cmake function ``zephyr_nanopb_sources`` to simplify ``.proto`` file inclusion. +LVGL +**** + + * Changed project status to maintained. + + * Library has been updated to release v8.3.7. + + * Added ``zephyr,lvgl-{pointer,button,encoder}-input`` pseudo device bindings. + :kconfig:option:`CONFIG_LV_Z_KSCAN_POINTER` is still supported but touch controllers + need a :dtcompatible:`zephyr,kscan-input` child node to emit input events. + + * LVGL shell allows for monkey testing (requires :kconfig:option:`CONFIG_LV_USE_MONKEY`) + and inspecting memory usage. + Storage ******* From a19c7f22948ddc9a3e5eeed41b3b403dfafd9fd0 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 10 Oct 2023 15:12:02 +0200 Subject: [PATCH 1847/4498] tests: lib: hash_map: fix libc heap size setting The malloc arena/heap size setting can be adjusted using different Kconfig options, depending on the libc implementation. This means prj.conf can't be used to set this value on projects that can be built for multiple libcs without generating a Kconfig warning. Note: similar fix was applied for the hash_map sample, see 7ef8911e8cb75a82e54ad2280658cb039b8ec875 Signed-off-by: Gerard Marull-Paretas --- tests/lib/hash_map/prj.conf | 3 --- tests/lib/hash_map/testcase.yaml | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/lib/hash_map/prj.conf b/tests/lib/hash_map/prj.conf index 3b37f590afb..ff212c933ec 100644 --- a/tests/lib/hash_map/prj.conf +++ b/tests/lib/hash_map/prj.conf @@ -5,9 +5,6 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 -CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 - CONFIG_SYS_HASH_FUNC32=y CONFIG_SYS_HASH_MAP=y diff --git a/tests/lib/hash_map/testcase.yaml b/tests/lib/hash_map/testcase.yaml index f0540430069..06f3ce5bfca 100644 --- a/tests/lib/hash_map/testcase.yaml +++ b/tests/lib/hash_map/testcase.yaml @@ -10,14 +10,18 @@ common: tests: libraries.hash_map.separate_chaining.djb2: extra_configs: + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_SC=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.open_addressing.djb2: extra_configs: + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_OA_LP=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.cxx.djb2: # need newlib for the c++ runtime filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: + - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_CXX=y From b1fdce63360f961f9c2981a1c121303d3d8e18f2 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 09:51:11 -0700 Subject: [PATCH 1848/4498] doc: vuln: Add information about CVE-2023-4259 Information about CVE-2023-4259 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 882a8d8b8a1..73f550a7d0c 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1391,6 +1391,22 @@ This has been fixed in main for v3.5.0 - `PR 60079 fix for 3.3 `_ +CVE-2023-4259 +------------- + +Buffer overflow vulnerabilities in the Zephyr eS-WiFi driver + +- `Zephyr project bug tracker GHSA-gghm-c696-f4j4 + `_ + +This has been fixed in main for v3.5.0 + +- `PR 63074 fix for main + `_ + +- `PR 63750 fix for main + `_ + CVE-2023-4260 ------------- From cd291e5c98f88c9fe91d5f31dd054c976c1a1099 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 09:55:29 -0700 Subject: [PATCH 1849/4498] doc: release: 3.5: Add info about CVE-2023-4259 Add CVE-2023-4259 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 6f67f0080d2..4a61a7ee796 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -28,6 +28,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ +* CVE-2023-4259 `Zephyr project bug tracker GHSA-gghm-c696-f4j4 + `_ + * CVE-2023-4260 `Zephyr project bug tracker GHSA-gj27-862r-55wh `_ From 13e0abf4a545066283097d403686f3472187576c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Tue, 10 Oct 2023 21:34:18 +0200 Subject: [PATCH 1850/4498] doc: releases: release-notes v3.5: update DAC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add section for added DAC drivers in this release. Signed-off-by: Martin Jäger --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 4a61a7ee796..5549b152dd2 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -255,6 +255,9 @@ Drivers and Sensors * DAC + * Added support for Analog Devices AD56xx + * Added support for NXP lpcxpresso55s36 (LPDAC) + * DFU * Disk From eb024b655fa78bc3e698fc0086ca362e124562c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 4 Oct 2023 09:17:27 -0700 Subject: [PATCH 1851/4498] libc: Control Z_LIBC_PARTITION_EXISTS from Kconfig Instead of adding every possible subsystem which places variables in the C library memory partition in libc-hooks.h, place those conditions in the related Kconfig files and simplify the libc-hooks.h to just looking at CONFIG_NEED_LIBC_MEM_PARTITION. Signed-off-by: Keith Packard --- include/zephyr/sys/libc-hooks.h | 4 +--- kernel/Kconfig | 1 + lib/libc/Kconfig | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/libc-hooks.h b/include/zephyr/sys/libc-hooks.h index d1a1afcbf40..e00efc6de26 100644 --- a/include/zephyr/sys/libc-hooks.h +++ b/include/zephyr/sys/libc-hooks.h @@ -92,9 +92,7 @@ __syscall size_t zephyr_fwrite(const void *ZRESTRICT ptr, size_t size, extern struct k_mem_partition z_malloc_partition; #endif -#if defined(CONFIG_NEWLIB_LIBC) || (defined(CONFIG_STACK_CANARIES) && \ - !defined(CONFIG_STACK_CANARIES_TLS)) || \ -defined(CONFIG_PICOLIBC) || defined(CONFIG_NEED_LIBC_MEM_PARTITION) +#ifdef CONFIG_NEED_LIBC_MEM_PARTITION /* - All newlib globals will be placed into z_libc_partition. * - Minimal C library globals, if any, will be placed into * z_libc_partition. diff --git a/kernel/Kconfig b/kernel/Kconfig index b2dde710121..2178b041cfd 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -975,6 +975,7 @@ menu "Security Options" config STACK_CANARIES bool "Compiler stack canaries" depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR + select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS help This option enables compiler stack canaries. diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 3bb83af5b1e..4ebf556dd5c 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -74,6 +74,7 @@ config PICOLIBC select COMMON_LIBC_ABORT select THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE select LIBC_ERRNO if THREAD_LOCAL_STORAGE + select NEED_LIBC_MEM_PARTITION imply COMMON_LIBC_MALLOC depends on !NATIVE_APPLICATION depends on PICOLIBC_SUPPORTED @@ -87,6 +88,7 @@ config NEWLIB_LIBC select COMMON_LIBC_ABORT depends on !NATIVE_APPLICATION depends on NEWLIB_LIBC_SUPPORTED + select NEED_LIBC_MEM_PARTITION help Build with newlib library. The newlib library is expected to be part of the SDK in this case. From e7126b5d848b042226de67fe1a86616106f72468 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 4 Oct 2023 09:31:04 -0700 Subject: [PATCH 1852/4498] libc/common: Place malloc data structures in libc partition Leave the malloc partition so that it only contains the heap itself; this lets the initialization code adjust the address range when configuring the arena at startup. Signed-off-by: Keith Packard --- lib/libc/common/Kconfig | 1 + lib/libc/common/source/stdlib/malloc.c | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/libc/common/Kconfig b/lib/libc/common/Kconfig index e4bcf9a72f2..56ac8f7b22b 100644 --- a/lib/libc/common/Kconfig +++ b/lib/libc/common/Kconfig @@ -13,6 +13,7 @@ config COMMON_LIBC_TIME config COMMON_LIBC_MALLOC bool "Common C library malloc implementation" + select NEED_LIBC_MEM_PARTITION if COMMON_LIBC_MALLOC_ARENA_SIZE != 0 help Common implementation of malloc family that uses the kernel heap API. diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index a98b3e234d3..6762c38e927 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -33,10 +33,8 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); # if Z_MALLOC_PARTITION_EXISTS K_APPMEM_PARTITION_DEFINE(z_malloc_partition); # define POOL_SECTION Z_GENERIC_SECTION(K_APP_DMEM_SECTION(z_malloc_partition)) -# define MALLOC_SECTION Z_GENERIC_SECTION(K_APP_DMEM_SECTION(z_malloc_partition)) # else # define POOL_SECTION __noinit -# define MALLOC_SECTION # endif /* CONFIG_USERSPACE */ # if defined(CONFIG_MMU) && CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE < 0 @@ -77,6 +75,8 @@ K_APPMEM_PARTITION_DEFINE(z_malloc_partition); # if CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE > 0 +# define HEAP_STATIC + /* Static allocation of heap in BSS */ # define HEAP_SIZE ROUND_UP(CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE, HEAP_ALIGN) @@ -114,10 +114,10 @@ extern char _heap_sentry[]; # endif /* else ALLOCATE_HEAP_AT_STARTUP */ -POOL_SECTION static struct sys_heap z_malloc_heap; +Z_LIBC_DATA static struct sys_heap z_malloc_heap; #ifdef CONFIG_MULTITHREADING -MALLOC_SECTION SYS_MUTEX_DEFINE(z_malloc_heap_mutex); +Z_LIBC_DATA SYS_MUTEX_DEFINE(z_malloc_heap_mutex); static inline void malloc_lock(void) { @@ -225,7 +225,7 @@ static int malloc_prepare(void) heap_size = HEAP_SIZE; #endif -#if Z_MALLOC_PARTITION_EXISTS +#if Z_MALLOC_PARTITION_EXISTS && !defined(HEAP_STATIC) z_malloc_partition.start = POINTER_TO_UINT(heap_base); z_malloc_partition.size = heap_size; z_malloc_partition.attr = K_MEM_PARTITION_P_RW_U_RW; From 01c31f2dc5f136ad3963c2690c12094cf1dd9bce Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 10 Oct 2023 15:40:06 +0200 Subject: [PATCH 1853/4498] doc: release note 3.5: Document STM32 changes Document STM32 related changes made on V3.5 release. Signed-off-by: Erwan Gouriou --- doc/releases/release-notes-3.5.rst | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 5549b152dd2..18b920d25f1 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -106,6 +106,11 @@ Boards & SoC Support * Added support for these SoC series: * Nuvoton NuMaker M46x series + * Added support for STM32F072X8 SoC variants + * Added support for STM32L051X6 SoC variants + * Added support for STM32L451XX SoC variants + * Added support for STM32L4Q5XX SoC variants + * Added support for STM32WBA SoC series * Removed support for these SoC series: @@ -123,6 +128,8 @@ Boards & SoC Support * Added support for these ARM boards: * Nuvoton NuMaker Platform M467 + * ST Nucleo U5A5ZJ Q + * ST Nucleo WBA52CG * Added support for these ARM64 boards: @@ -155,6 +162,8 @@ Boards & SoC Support * Made these changes for ARM boards: + * ST morpho connector description was added on ST nucleo boards. + * Made these changes for ARM64 boards: * Made these changes for RISC-V boards: @@ -234,6 +243,13 @@ Drivers and Sensors * ADC + * Added support for STM32F0 HSI14 clock (dedicated ADC clock) + * Added support for STM32 ADC source clock and prescaler. On STM32F1 and STM32F3 + series, ADC prescaler can be configured using dedicated RCC Clock Controller + option. + * Added support for the ADC sequencer for all STM32 series (except F1) + * Fixed STM32F4 ADC temperature and Vbat measurement. + * Battery-backed RAM * CAN @@ -251,6 +267,9 @@ Drivers and Sensors * Counter + * Added :kconfig:option:`CONFIG_COUNTER_RTC_STM32_SUBSECONDS` to enable subsecond as + the basic time tick on STM32 RTC based counter driver. + * Crypto * DAC @@ -306,6 +325,8 @@ Drivers and Sensors single Flash Interface Unit (FIU) module and Direct Read Access (DRA) mode for better performance. * Added support for Nuvoton NuMaker M46x embedded flash + * STM32 QSPI driver now supports Jedec SFDP parameter reading. + * STM32 OSPI driver now supports both Low and High ports of IO manager. * FPGA @@ -319,6 +340,10 @@ Drivers and Sensors * I2C + * STM32 V1 driver now supports large transactions (more than 256 bytes chunks) + * STM32 V2 driver now supports 10-bit addressing. + * I2C devices can now be used as wakeup source from STOP modes on STM32. + * I2S * I3C @@ -400,6 +425,8 @@ Drivers and Sensors * PWM + * Added 4 channels capture on STM32 PWM driver. + * Power domain * Regulators @@ -429,6 +456,11 @@ Drivers and Sensors * Fixed issue with user mode support not working. +* RTC + + * Added support for STM32 RTC API driver. This driver is not compatible with + the use of RTC based implementation of COUNTER API. + * SDHC * Sensor @@ -482,6 +514,10 @@ Drivers and Sensors * USB + * Added UDC driver for STM32 based MCU, relying on HAL/PCD. This driver is compatible + with UDC API (experimental). + * Added support for STM32H5 series on USB driver. + * W1 * Watchdog @@ -744,6 +780,8 @@ Libraries / Subsystems minimum encoding levels for in-tree groups if :kconfig:option:`CONFIG_ZCBOR_CANONICAL` is enabled. + * Added STM32 SPI backend for EC Host command protocol. + * File systems * Added support for ext2 file system. From dc3295608ac50c3f61186e29897468859796a539 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 10 Oct 2023 15:41:36 +0200 Subject: [PATCH 1854/4498] doc: migration guide 3.5: Document STM32 changes Document STM32 breaking or not backward compatible changes made on V3.5 release. Signed-off-by: Erwan Gouriou --- doc/releases/migration-guide-3.5.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index d311ad41917..687e8fb74ea 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -235,6 +235,30 @@ Required changes This means that an extra linker stage is no longer necessary if this option is not enabled. +* STM32 Ethernet driver was misusing :c:func:`hwinfo_get_device_id` to generate + last 3 bytes of mac address, resulting in a high risk of collision when using + SoCs from the same lot. This is now fixed to use the whole range of entropy + available from the unique ID (96 bits). Devices using unique ID based mac address + will see last 3 bytes of their MAC address modified by this change. + +* On all STM32 (except F1x and F37x series), two new required properties have been + added to ADC to configure the source clock and the prescaler. + ``st,adc-clock-source`` allows choosing either synchronous or asynchronous clock source. + ``st,adc-prescaler`` allows setting the value of the prescaler for the chosen clock source. + Not all combinations are allowed. Refer to the appropriate RefMan for more information. + When choosing asynchronous clock, the choice of the kernel source clock is made in the + ``clocks`` node as it is done for other peripherals, for example, to select + HSI16 as clock source for STM32G0: + + .. code-block:: devicetree + + &adc { + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00100000>, + <&rcc STM32_SRC_HSI ADC_SEL(2)>; + }; + + + Recommended Changes ******************* From e0192e12878828883e3c05e65839ee7df5042f9c Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 10 Oct 2023 15:48:32 +0200 Subject: [PATCH 1855/4498] doc: release note 3.5: Document Shields additions Document shields added in V3.5 release. Signed-off-by: Erwan Gouriou --- doc/releases/release-notes-3.5.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 18b920d25f1..d14c5c0d2ad 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -203,6 +203,14 @@ Boards & SoC Support * Added support for these following shields: + * Adafruit PiCowbell CAN Bus Shield for Pico + * Arduino UNO click shield + * G1120B0MIPI MIPI Display + * MikroElektronika MCP2518FD Click shield (CAN-FD) + * RK055HDMIPI4M MIPI Display + * RK055HDMIPI4MA0 MIPI Display + * Semtech SX1276MB1MAS LoRa Shield + Build system and infrastructure ******************************* From b1cc4e9a148b87b59e45222cbed36d8c1950abb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Tue, 10 Oct 2023 21:16:58 +0200 Subject: [PATCH 1856/4498] doc: releases: release-notes-3.5: update CAN ISO-TP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sections for CAN ISO-TP changes in this release and describe API changes in migration guide. Signed-off-by: Martin Jäger --- doc/releases/migration-guide-3.5.rst | 10 ++++++++++ doc/releases/release-notes-3.5.rst | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 687e8fb74ea..a31cfddae14 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -125,6 +125,16 @@ Required changes :c:func:`can_set_bitrate` and :c:func:`can_set_bitrate_data` now also automatically calculate a suitable SJW, but their SJW cannot be overwritten by the caller. +* The CAN ISO-TP message configuration in :c:struct:`isotp_msg_id` is changed to use the following + flags instead of bit fields: + + * :c:macro:`ISOTP_MSG_EXT_ADDR` to enable ISO-TP extended addressing + * :c:macro:`ISOTP_MSG_FIXED_ADDR` to enable ISO-TP fixed addressing + * :c:macro:`ISOTP_MSG_IDE` to use extended (29-bit) CAN IDs + + The two new flags :c:macro:`ISOTP_MSG_FDF` and :c:macro:`ISOTP_MSG_BRS` were added for CAN FD + mode. + * Ethernet PHY devicetree bindings were updated to use the standard ``reg`` property for the PHY address instead of a custom ``address`` property. As a result, MDIO controller nodes now require ``#address-cells`` and diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index d14c5c0d2ad..1b2c13052b5 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -836,6 +836,10 @@ Libraries / Subsystems * Updated ``loramac-node`` from v4.6.0 to v4.7.0 +* CAN ISO-TP + + * Added support for CAN FD. + HALs **** From 2d25fae42eeedc8aff4a653efa2fd8e293b8a6dc Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 10 Oct 2023 13:50:16 -0700 Subject: [PATCH 1857/4498] kernel: remove deprecated STACK EXTERN macros These macros have been deprecated since v3.2.0. So remove them. () K_KERNEL_STACK_EXTERN Use K_KERNEL_STACK_DECLARE instead. () K_KERNEL_STACK_ARRAY_EXTERN Use K_KERNEL_STACK_ARRAY_DECLARE instead. () K_KERNEL_PINNED_STACK_ARRAY_EXTERN Use K_KERNEL_PINNED_STACK_ARRAY_DECLARE instead. () K_THREAD_STACK_EXTERN Use K_THREAD_STACK_DECLARE instead. () K_THREAD_STACK_ARRAY_EXTERN Use K_THREAD_STACK_ARRAY_DECLARE instead. Signed-off-by: Daniel Leung --- include/zephyr/kernel/thread_stack.h | 76 ---------------------------- 1 file changed, 76 deletions(-) diff --git a/include/zephyr/kernel/thread_stack.h b/include/zephyr/kernel/thread_stack.h index 41c4c5e4ebf..2ecfcb3aeac 100644 --- a/include/zephyr/kernel/thread_stack.h +++ b/include/zephyr/kernel/thread_stack.h @@ -153,51 +153,6 @@ static inline char *z_stack_ptr_align(char *ptr) extern struct z_thread_stack_element \ sym[nmemb][Z_KERNEL_STACK_LEN(size)] -/** - * @brief Obtain an extern reference to a stack - * - * This macro properly brings the symbol of a thread stack defined - * elsewhere into scope. - * - * @deprecated Use @c K_KERNEL_STACK_DECLARE() instead. - * - * @param sym Thread stack symbol name - */ -#define K_KERNEL_STACK_EXTERN(sym) __DEPRECATED_MACRO \ - extern k_thread_stack_t sym[] - -/** - * @brief Obtain an extern reference to a stack array - * - * This macro properly brings the symbol of a stack array defined - * elsewhere into scope. - * - * @deprecated Use @c K_KERNEL_STACK_ARRAY_DECLARE() instead. - * - * @param sym Thread stack symbol name - * @param nmemb Number of stacks defined - * @param size Size of the stack memory region - */ -#define K_KERNEL_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \ - extern struct z_thread_stack_element \ - sym[nmemb][Z_KERNEL_STACK_LEN(size)] - -/** - * @brief Obtain an extern reference to a pinned stack array - * - * This macro properly brings the symbol of a pinned stack array - * defined elsewhere into scope. - * - * @deprecated Use @c K_KERNEL_PINNED_STACK_ARRAY_DECLARE() instead. - * - * @param sym Thread stack symbol name - * @param nmemb Number of stacks defined - * @param size Size of the stack memory region - */ -#define K_KERNEL_PINNED_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \ - extern struct z_thread_stack_element \ - sym[nmemb][Z_KERNEL_STACK_LEN(size)] - /** * @brief Define a toplevel kernel stack memory region in specified section * @@ -342,8 +297,6 @@ static inline char *Z_KERNEL_STACK_BUFFER(k_thread_stack_t *sym) #define Z_THREAD_STACK_BUFFER Z_KERNEL_STACK_BUFFER #define K_THREAD_STACK_DECLARE K_KERNEL_STACK_DECLARE #define K_THREAD_STACK_ARRAY_DECLARE K_KERNEL_STACK_ARRAY_DECLARE -#define K_THREAD_STACK_EXTERN K_KERNEL_STACK_EXTERN -#define K_THREAD_STACK_ARRAY_EXTERN K_KERNEL_STACK_ARRAY_EXTERN #define K_THREAD_PINNED_STACK_DEFINE K_KERNEL_PINNED_STACK_DEFINE #define K_THREAD_PINNED_STACK_ARRAY_DEFINE \ K_KERNEL_PINNED_STACK_ARRAY_DEFINE @@ -467,35 +420,6 @@ static inline char *Z_KERNEL_STACK_BUFFER(k_thread_stack_t *sym) extern struct z_thread_stack_element \ sym[nmemb][K_THREAD_STACK_LEN(size)] -/** - * @brief Obtain an extern reference to a stack - * - * This macro properly brings the symbol of a thread stack defined - * elsewhere into scope. - * - * @deprecated Use @c K_THREAD_STACK_DECLARE() instead. - * - * @param sym Thread stack symbol name - */ -#define K_THREAD_STACK_EXTERN(sym) __DEPRECATED_MACRO \ - extern k_thread_stack_t sym[] - -/** - * @brief Obtain an extern reference to a thread stack array - * - * This macro properly brings the symbol of a stack array defined - * elsewhere into scope. - * - * @deprecated Use @c K_THREAD_STACK_ARRAY_DECLARE() instead. - * - * @param sym Thread stack symbol name - * @param nmemb Number of stacks defined - * @param size Size of the stack memory region - */ -#define K_THREAD_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \ - extern struct z_thread_stack_element \ - sym[nmemb][K_THREAD_STACK_LEN(size)] - /** * @brief Return the size in bytes of a stack memory region * From 1c2d326579ee8cea4c809eb737585537e3482677 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 25 Sep 2023 17:45:49 +0200 Subject: [PATCH 1858/4498] drivers: serial: stm32: Make it compatible with runtime PM on console Since #53979, runtime PM can be applied on serial device used by console. While it should be transparent on serial driver side as the application (console in this case) is driving the PM runtime requests, on STM32 it requires some modification on serial driver as UART interrupts are generated to handle internal power management house cleaning. When these interrupts are generated, PM runtime should also be driven to ensure clock availability when treating the uart ISR. On STM32, some additional changes are required Signed-off-by: Erwan Gouriou --- drivers/serial/uart_stm32.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 9243b10d7e7..8cf10e6a151 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_UART_ASYNC_API #include @@ -671,6 +672,11 @@ static void uart_stm32_poll_out_visitor(const struct device *dev, void *out, pol */ uart_stm32_pm_policy_state_lock_get(dev); + /* Resume device if needed before enabling IT */ + if (pm_device_runtime_is_enabled(dev)) { + (void)pm_device_runtime_get(dev); + } + /* Enable TC interrupt so we can release suspend * constraint when done */ @@ -1263,6 +1269,11 @@ static void uart_stm32_isr(const struct device *dev) async_evt_tx_done(data); #ifdef CONFIG_PM + /* Device can now be released */ + if (pm_device_runtime_is_enabled(dev)) { + (void)pm_device_runtime_put(dev); + } + uart_stm32_pm_policy_state_lock_put(dev); #endif } else if (LL_USART_IsEnabledIT_RXNE(config->usart) && From c4e53dabf7238db612cc9438e8526142d4d0c93f Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Fri, 6 Oct 2023 08:41:49 +0200 Subject: [PATCH 1859/4498] nrf53: fix RTC pretick power usage for events on RTC0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For RTC0 events the RTC1 pretick event was not cleared what caused the WDT to be not stopped. This resulted in increased power usage. Signed-off-by: Andrzej Kuroś --- soc/arm/nordic_nrf/nrf53/soc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index aa93dfd4b54..c18228ac4fa 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -410,6 +410,8 @@ static void rtc_pretick_rtc_isr_hook(void) { NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= ~IPC_PUBLISH_RECEIVE_EN_Msk; + + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); } void rtc_pretick_rtc0_isr_hook(void) @@ -420,10 +422,6 @@ void rtc_pretick_rtc0_isr_hook(void) void rtc_pretick_rtc1_isr_hook(void) { rtc_pretick_rtc_isr_hook(); - - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - } } static int rtc_pretick_cpunet_init(void) From 3eef769209d05b0b758e38ea608b89716fd87d4a Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 10 Oct 2023 16:14:14 +0200 Subject: [PATCH 1860/4498] nrf53: fix RTC pretick for RTC rescheduling by other interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It might happen that while some interrupt handler other than for RTC0 or RTC1 (e.g. for RADIO) is executed, the scheduled pretick CC triggers. This starts pretick pulses due to the loop through IPC. The change in pretick schedule did not stop the pretick pulses going through IPC loop, what caused heavy increase in power consumption. This commit fixes this behavior. Added also clarifications for Kconfig option `SOC_NRF53_RTC_PRETICK`. Signed-off-by: Andrzej Kuroś --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 6 +++++- soc/arm/nordic_nrf/nrf53/soc.c | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 87d8a6d0c7a..87d961d6fb3 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -58,7 +58,11 @@ config SOC_NRF53_RTC_PRETICK select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET help Indicates that the pre-tick workaround for the anomaly 165 that affects - the nRF5340 SoC should be applied. + the nRF5340 SoC should be applied. The workaround applies to wake ups caused + by EVENTS_COMPARE and EVENTS_OVRFLW on RTC0 and RTC1 for which interrupts are + enabled through INTENSET register. The case when these events are generated + by EVTEN but without interrupts enabled through INTENSET is not handled. + The EVENTS_TICK event is not handled. if SOC_NRF53_RTC_PRETICK diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index c18228ac4fa..396ce79f49e 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -224,6 +224,15 @@ static bool cpu_idle_prepare_monitor_end(void) return __STREXB(0U, &cpu_idle_prepare_monitor_dummy); } +static void rtc_pretick_finish_previous(void) +{ + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= + ~IPC_PUBLISH_RECEIVE_EN_Msk; + + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); +} + + void z_arm_on_enter_cpu_idle_prepare(void) { bool ok_to_sleep = true; @@ -263,6 +272,7 @@ void z_arm_on_enter_cpu_idle_prepare(void) if (rtc_pretick_cc_val != nrf_rtc_cc_get(NRF_RTC1, RTC1_PRETICK_CC_CHAN)) { /* The CC for pretick needs to be updated. */ + rtc_pretick_finish_previous(); nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, rtc_pretick_cc_val); if (rtc_ticks_to_next_event >= NRF_RTC_COUNTER_MAX/2) { @@ -406,22 +416,14 @@ static int rtc_pretick_cpuapp_init(void) } #else /* CONFIG_SOC_NRF5340_CPUNET */ -static void rtc_pretick_rtc_isr_hook(void) -{ - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= - ~IPC_PUBLISH_RECEIVE_EN_Msk; - - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); -} - void rtc_pretick_rtc0_isr_hook(void) { - rtc_pretick_rtc_isr_hook(); + rtc_pretick_finish_previous(); } void rtc_pretick_rtc1_isr_hook(void) { - rtc_pretick_rtc_isr_hook(); + rtc_pretick_finish_previous(); } static int rtc_pretick_cpunet_init(void) From adec56bcee504d34b11a78a2fbf89bcdb51030b7 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 10 Oct 2023 20:14:30 +0200 Subject: [PATCH 1861/4498] nrf5340: pretick decoupled from workaround anomaly 160 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Coupling in code between workarounds for anomaly 160 and anomaly 165 (pretick) is decreased. Signed-off-by: Andrzej Kuroś --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 + soc/arm/nordic_nrf/nrf53/soc.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 87d961d6fb3..2cd934af324 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -53,6 +53,7 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND config SOC_NRF53_RTC_PRETICK bool "Pre-tick workaround for nRF5340 anomaly 165" + depends on (SYS_CLOCK_EXISTS && SOC_NRF5340_CPUNET) || SOC_NRF5340_CPUAPP select NRFX_DPPI select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 396ce79f49e..39d64d72cc2 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -133,6 +133,7 @@ static bool nrf53_anomaly_160_check(void) return true; } +#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ #if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) @@ -337,6 +338,8 @@ void z_arm_on_enter_cpu_idle_prepare(void) } #endif /* CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET */ +#if defined(CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND) || \ + (defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET)) bool z_arm_on_enter_cpu_idle(void) { bool ok_to_sleep = true; @@ -357,6 +360,7 @@ bool z_arm_on_enter_cpu_idle(void) } #endif +#if defined(CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND) if (ok_to_sleep) { ok_to_sleep = nrf53_anomaly_160_check(); @@ -371,6 +375,7 @@ bool z_arm_on_enter_cpu_idle(void) } #endif } +#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ #if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) if (!ok_to_sleep) { @@ -382,7 +387,9 @@ bool z_arm_on_enter_cpu_idle(void) return ok_to_sleep; } -#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ +#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND || + * (CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET) + */ #if CONFIG_SOC_NRF53_RTC_PRETICK #ifdef CONFIG_SOC_NRF5340_CPUAPP From 47822586e41a76d834e4432c2bcc75ab17fcfaca Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Tue, 10 Oct 2023 15:15:38 +0200 Subject: [PATCH 1862/4498] doc: Remove two redundant characters in rst file Remove additional dot and bracket. Signed-off-by: Marcin Gasiorek --- doc/kernel/memory_management/slabs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/kernel/memory_management/slabs.rst b/doc/kernel/memory_management/slabs.rst index 72d276399cc..ae57a789b19 100644 --- a/doc/kernel/memory_management/slabs.rst +++ b/doc/kernel/memory_management/slabs.rst @@ -71,7 +71,7 @@ A memory slab is defined using a variable of type :c:type:`k_mem_slab`. It must then be initialized by calling :c:func:`k_mem_slab_init`. The following code defines and initializes a memory slab that has 6 blocks -that are 400 bytes long, each of which is aligned to a 4-byte boundary.. +that are 400 bytes long, each of which is aligned to a 4-byte boundary. .. code-block:: c @@ -109,7 +109,7 @@ A warning is printed if a suitable block is not obtained. char *block_ptr; - if (k_mem_slab_alloc(&my_slab, &block_ptr, 100) == 0)) { + if (k_mem_slab_alloc(&my_slab, &block_ptr, 100) == 0) { memset(block_ptr, 0, 400); ... } else { From 4773f42c2775afcda6946ba6dbd8bdad652a3bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 19 Sep 2023 10:53:13 +0200 Subject: [PATCH 1863/4498] west: bossac: handle stty from coreutils on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There might be situations where people are running the coreutils version of stty on macOS, hence the need for being smarter at detecting when that might be the case Signed-off-by: Benjamin Cabé --- scripts/west_commands/runners/bossac.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/west_commands/runners/bossac.py b/scripts/west_commands/runners/bossac.py index ab214210c78..fcbd6fdf92b 100644 --- a/scripts/west_commands/runners/bossac.py +++ b/scripts/west_commands/runners/bossac.py @@ -149,12 +149,19 @@ def get_image_offset(self, supports_offset): return None + def is_gnu_coreutils_stty(self): + try: + result = subprocess.run(['stty', '--version'], capture_output=True, text=True, check=True) + return 'coreutils' in result.stdout + except subprocess.CalledProcessError: + return False + def set_serial_config(self): if platform.system() == 'Linux' or platform.system() == 'Darwin': self.require('stty') # GNU coreutils uses a capital F flag for 'file' - flag = '-F' if platform.system() == 'Linux' else '-f' + flag = '-F' if self.is_gnu_coreutils_stty() else '-f' if self.is_extended_samba_protocol(): self.speed = '1200' From 1204b18aa3e0a04ad527a789de8d6e8e87cf53f0 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 5 Oct 2023 16:59:00 +0200 Subject: [PATCH 1864/4498] drivers: sensor: stm32 vref sensor depends on ADC Set the CONFIG_STM32_VREF depending on the ADC, like the CONFIG_STM32_VBAT does Signed-off-by: Francois Ramu --- drivers/sensor/stm32_vref/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/stm32_vref/Kconfig b/drivers/sensor/stm32_vref/Kconfig index 375c0b4bc3d..192cd3fd922 100644 --- a/drivers/sensor/stm32_vref/Kconfig +++ b/drivers/sensor/stm32_vref/Kconfig @@ -7,6 +7,6 @@ config STM32_VREF bool "STM32 VREF Sensor" default y depends on DT_HAS_ST_STM32_VREF_ENABLED - select ADC + depends on ADC && (SOC_FAMILY_STM32 && !SOC_SERIES_STM32F1X) help Enable driver for STM32 Vref sensor. From c5f84272368df58f451256cc1bc0c158cd4ed38f Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 5 Oct 2023 16:19:53 +0200 Subject: [PATCH 1865/4498] boards: arm: disco_l475_iot1 do not declare adc1 input on PA0 Do not declare the in5 on pin PA0 of the adc1 since it makes conflict with uart4_tx_pa0. Other ADC1 adc1_in1_pc0 or adc1_in2_pc1 are not available (used by the i2c3). Signed-off-by: Francois Ramu --- boards/arm/disco_l475_iot1/disco_l475_iot1.dts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts index fb6b138b931..8505b05656f 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts @@ -288,9 +288,8 @@ zephyr_udc0: &usbotg_fs { }; &adc1 { - pinctrl-0 = <&adc1_in5_pa0 &adc1_in3_pc2 - &adc1_in4_pc3 &adc1_in13_pc4 - &adc1_in14_pc5>; + pinctrl-0 = <&adc1_in3_pc2 &adc1_in4_pc3 + &adc1_in13_pc4 &adc1_in14_pc5>; pinctrl-names = "default"; st,adc-clock-source = ; st,adc-prescaler = <4>; From 153c4187874cf877a7914f07caa1acbff48f98bb Mon Sep 17 00:00:00 2001 From: Rihards Skuja Date: Mon, 9 Oct 2023 18:23:06 +0300 Subject: [PATCH 1866/4498] pinctrl: gecko: fix broken UART when SPI is enabled on Series 2 When SPI is enabled, pinctrl driver configures all the pins in UART pinctrl config as gpioModeDisabled. Signed-off-by: Rihards Skuja --- drivers/pinctrl/pinctrl_gecko.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl_gecko.c b/drivers/pinctrl/pinctrl_gecko.c index 2aede54a325..cdb1118768f 100644 --- a/drivers/pinctrl/pinctrl_gecko.c +++ b/drivers/pinctrl/pinctrl_gecko.c @@ -249,6 +249,8 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp GPIO->USARTROUTE[usart_num].CLKROUTE = (pin_config.pin << _GPIO_USART_CLKROUTE_PIN_SHIFT) | (pin_config.port << _GPIO_USART_CLKROUTE_PORT_SHIFT); + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); break; case GECKO_FUN_SPI_MOSI: @@ -258,6 +260,8 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp GPIO->USARTROUTE[usart_num].TXROUTE = (pin_config.pin << _GPIO_USART_TXROUTE_PIN_SHIFT) | (pin_config.port << _GPIO_USART_TXROUTE_PORT_SHIFT); + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); break; case GECKO_FUN_SPI_MISO: @@ -267,6 +271,8 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp GPIO->USARTROUTE[usart_num].RXROUTE = (pin_config.pin << _GPIO_USART_RXROUTE_PIN_SHIFT) | (pin_config.port << _GPIO_USART_RXROUTE_PORT_SHIFT); + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); break; #endif /* CONFIG_SOC_GECKO_SERIES1 */ #endif /* CONFIG_SPI_GECKO */ @@ -274,10 +280,6 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp default: return -ENOTSUP; } -#if defined(CONFIG_SPI_GECKO) && !defined(CONFIG_SOC_GECKO_SERIES1) - GPIO_PinModeSet(pin_config.port, pin_config.pin, - pin_config.mode, pin_config.out); -#endif /* defined(CONFIG_SPI_GECKO) && !defined(CONFIG_SOC_GECKO_SERIES1) */ } return 0; From 4d598683972a3601c2e90b53d58ffbb6e33e99ea Mon Sep 17 00:00:00 2001 From: Jonas Otto Date: Tue, 10 Oct 2023 15:30:23 +0200 Subject: [PATCH 1867/4498] dts: usb-c: fix invalid power-role in example The example sets the power-role to "SINK", but the value is case-sensitive and only accepts lowercase "sink". Signed-off-by: Jonas Otto --- dts/bindings/usb-c/usb-c-connector.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/bindings/usb-c/usb-c-connector.yaml b/dts/bindings/usb-c/usb-c-connector.yaml index 1984486b7e6..c5e69653a33 100644 --- a/dts/bindings/usb-c/usb-c-connector.yaml +++ b/dts/bindings/usb-c/usb-c-connector.yaml @@ -29,7 +29,7 @@ description: | reg = <1>; tcpc = <&ucpd1>; vbus = <&vbus1>; - power-role = "SINK"; + power-role = "sink"; sink-pdos = ; op-sink-microwatt = <10000000>; From 9641864a200f83531fe0d0c866d53dda96c905ea Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 09:52:28 +0200 Subject: [PATCH 1868/4498] Bluetooth: Mesh: Fix Upload Progress for already received fw In OOB upload, when Check Firmware OOB procedure completes successfully and the firmware is already received, we send Firmware Distribution Upload Status message with update Phase set to Transfer Success. In this case, we must set Upload Progress to 100%. This can't be done through the callback as the application layer doesn't yet know that the firmware is already received. This will happen by the exist from bt_mesh_dfd_srv_oob_check_complete function, which will return error code -EEXIST. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 5d3ada4b4aa..a67a3a778ca 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -342,9 +342,10 @@ static int handle_apply(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, - struct bt_mesh_msg_ctx *ctx, - enum bt_mesh_dfd_status status) +static void upload_status_rsp_with_progress(struct bt_mesh_dfd_srv *srv, + struct bt_mesh_msg_ctx *ctx, + enum bt_mesh_dfd_status status, + uint8_t progress) { BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_UPLOAD_STATUS, DFD_UPLOAD_STATUS_MSG_MAXLEN); @@ -361,14 +362,13 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD if (srv->upload.is_oob) { - net_buf_simple_add_u8(&rsp, - srv->cb->oob_progress_get(srv, srv->upload.slot) | BIT(7)); + net_buf_simple_add_u8(&rsp, progress | BIT(7)); net_buf_simple_add_mem(&rsp, srv->upload.oob.current_fwid, srv->upload.oob.current_fwid_len); } else #endif { - net_buf_simple_add_u8(&rsp, bt_mesh_blob_srv_progress(&srv->upload.blob)); + net_buf_simple_add_u8(&rsp, progress); net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, srv->upload.slot->fwid_len); } @@ -376,6 +376,24 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } +static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, + struct bt_mesh_msg_ctx *ctx, + enum bt_mesh_dfd_status status) +{ + uint8_t progress; + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + if (srv->upload.is_oob) { + progress = srv->cb->oob_progress_get(srv, srv->upload.slot); + } else +#endif + { + progress = bt_mesh_blob_srv_progress(&srv->upload.blob); + } + + upload_status_rsp_with_progress(srv, ctx, status, progress); +} + static int handle_upload_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -400,7 +418,7 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms case -EEXIST: /* Img with this fwid already is in list */ srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); + upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); break; case 0: srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; From 1329a9d31292f3f2e5f4134e9cc61acb76daa5a9 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 09:59:19 +0200 Subject: [PATCH 1869/4498] Bluetooth: Mesh: Fix Fw Dist Upload OOB Start msg length check This message _at least_ 2 bytes long, but can be longer, thus BT_MESH_LEN_MIN should be used. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index a67a3a778ca..f060e263ace 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -761,7 +761,7 @@ const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[] = { { BT_MESH_DFD_OP_APPLY, BT_MESH_LEN_EXACT(0), handle_apply }, { BT_MESH_DFD_OP_UPLOAD_GET, BT_MESH_LEN_EXACT(0), handle_upload_get }, { BT_MESH_DFD_OP_UPLOAD_START, BT_MESH_LEN_MIN(16), handle_upload_start }, - { BT_MESH_DFD_OP_UPLOAD_START_OOB, BT_MESH_LEN_EXACT(2), handle_upload_start_oob }, + { BT_MESH_DFD_OP_UPLOAD_START_OOB, BT_MESH_LEN_MIN(2), handle_upload_start_oob }, { BT_MESH_DFD_OP_UPLOAD_CANCEL, BT_MESH_LEN_EXACT(0), handle_upload_cancel }, { BT_MESH_DFD_OP_FW_GET, BT_MESH_LEN_MIN(0), handle_fw_get }, { BT_MESH_DFD_OP_FW_GET_BY_INDEX, BT_MESH_LEN_EXACT(2), handle_fw_get_by_index }, From 7154f356af59c3a1b61168b885a7b9f23b3f6404 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 10:52:46 +0200 Subject: [PATCH 1870/4498] Bluetooth: Mesh: Ignore duplicate OOB upload request If a Fw Distribution Client sends the Upload OOB Start message, but the application layer didn't call bt_mesh_dfd_srv_oob_check_complete yet, we have no other option other than ignore the message. The next phase in this case could be Transfer Active, Transfer Success or Failed and it will be set only after Check Firmware OOB procedure completes. Signed-off-by: Pavel Vasilyev --- include/zephyr/bluetooth/mesh/dfd_srv.h | 1 + subsys/bluetooth/mesh/dfd_srv.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/mesh/dfd_srv.h b/include/zephyr/bluetooth/mesh/dfd_srv.h index da339c57ec6..666e0d8ad3d 100644 --- a/include/zephyr/bluetooth/mesh/dfd_srv.h +++ b/include/zephyr/bluetooth/mesh/dfd_srv.h @@ -228,6 +228,7 @@ struct bt_mesh_dfd_srv { struct bt_mesh_blob_srv blob; #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD bool is_oob; + bool is_pending_oob_check; struct { uint8_t uri_len; uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index f060e263ace..f8dfaf0b97f 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -586,6 +586,11 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg #endif upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD); return 0; +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + } else if (srv->upload.is_oob && srv->upload.is_pending_oob_check) { + /* Ignore the request if we didn't confirm the previous one. */ + return 0; +#endif } #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD @@ -618,6 +623,8 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg if (status != BT_MESH_DFD_SUCCESS) { upload_status_rsp(srv, ctx, status); bt_mesh_dfu_slot_release(srv->upload.slot); + } else { + srv->upload.is_pending_oob_check = true; } #else upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_URI_NOT_SUPPORTED); @@ -1211,13 +1218,16 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, int err; if (slot != srv->upload.slot || !srv->upload.is_oob || - srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) { + srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE || + !srv->upload.is_pending_oob_check) { /* This should not happen, unless the application calls the function with a * "wrong" pointer or at a wrong time. */ return -EINVAL; } + srv->upload.is_pending_oob_check = false; + if (status != BT_MESH_DFD_SUCCESS) { bt_mesh_dfu_slot_release(srv->upload.slot); upload_status_rsp(srv, &srv->upload.oob.ctx, status); From d1c2ca252556fffd043dcdff2edb1277bcaedb31 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 07:57:32 +0200 Subject: [PATCH 1871/4498] Bluetooth: Mesh: Release previously reserved slot before reserving again If the previous upload was in-band and it didn't complete, the slot will stay reserved. By design we release slot not at the end of the upload phase, but at the start of a new upload phase. This fixes DFU/SR/FD/BV-13-C. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index f8dfaf0b97f..cfcc82eb8d1 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -607,6 +607,13 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg return 0; } + /* This will be a no-op if the slot state isn't RESERVED, which is + * what we want. + */ + if (srv->upload.slot) { + bt_mesh_dfu_slot_release(srv->upload.slot); + } + srv->upload.is_oob = true; srv->upload.slot = slot; memcpy(srv->upload.oob.uri, uri, uri_len); From 1c1c5e22b73a2f628696d7e10e78e08c7468176f Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 08:54:48 +0200 Subject: [PATCH 1872/4498] tests: bluetooth: tester: Add Upload OOB support for mesh tester This allow to run the following PTS test: - DFU/SR/FD/BV-06-C - DFU/SR/FD/BV-13-C - DFU/SR/FD/BV-14-C - DFU/SR/FD/BV-15-C - DFU/SR/FD/BV-16-C - DFU/SR/FD/BV-17-C - DFU/SR/FD/BV-18-C - DFU/SR/FD/BV-22-C Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp_mesh.c | 119 ++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c231c3dca38..586b6ae1bd7 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -162,13 +162,132 @@ static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, return 0; } +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD +static struct { + uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; + uint8_t uri_len; + uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; + uint8_t fwid_len; + const struct bt_mesh_dfu_slot *slot; + uint8_t progress; + bool started; +} dfd_srv_oob_ctx; + +static void oob_check_handler(struct k_work *work); +static K_WORK_DEFINE(oob_check, oob_check_handler); +static void oob_store_handler(struct k_work *work); +static K_WORK_DEFINE(oob_store, oob_store_handler); + +static int dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot, + const char *uri, uint8_t uri_len, + const uint8_t *fwid, uint16_t fwid_len) +{ + LOG_DBG("Start OOB Upload"); + + memcpy(dfd_srv_oob_ctx.uri, uri, uri_len); + dfd_srv_oob_ctx.uri_len = uri_len; + memcpy(dfd_srv_oob_ctx.fwid, fwid, fwid_len); + dfd_srv_oob_ctx.fwid_len = fwid_len; + dfd_srv_oob_ctx.slot = slot; + dfd_srv_oob_ctx.progress = 0; + dfd_srv_oob_ctx.started = true; + + k_work_submit(&oob_check); + + return BT_MESH_DFD_SUCCESS; +} + +static void dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot) +{ + LOG_DBG("Cancel OOB Upload"); + + dfd_srv_oob_ctx.started = false; +} + +static uint8_t dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv *srv, + const struct bt_mesh_dfu_slot *slot) +{ + uint8_t progress; + + if (dfd_srv_oob_ctx.started) { + progress = dfd_srv_oob_ctx.progress; + + dfd_srv_oob_ctx.progress = MIN(dfd_srv_oob_ctx.progress + 25, 99); + + if (dfd_srv_oob_ctx.progress == 99) { + k_work_submit(&oob_store); + } + } else { + progress = 0; + } + + LOG_DBG("OOB Progress Get (%sstarted: %d %%)", dfd_srv_oob_ctx.started ? "" : "not ", + progress); + return progress; +} +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ + static struct bt_mesh_dfd_srv_cb dfd_srv_cb = { .recv = dfd_srv_recv, .del = dfd_srv_del, .send = dfd_srv_send, +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD + .start_oob_upload = dfd_srv_start_oob_upload, + .cancel_oob_upload = dfd_srv_cancel_oob_upload, + .oob_progress_get = dfd_srv_oob_progress_get, +#endif }; static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb); + +#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD +#define SUPPORTED_SCHEME "http" + +static void oob_check_handler(struct k_work *work) +{ + uint8_t scheme[10]; + int i; + int status; + int err; + + for (i = 0; i < MIN(dfd_srv_oob_ctx.uri_len, sizeof(scheme)); i++) { + if (IN_RANGE(dfd_srv_oob_ctx.uri[i], 48, 57) || /* DIGIT */ + IN_RANGE(dfd_srv_oob_ctx.uri[i], 65, 90) || /* ALPHA UPPER CASE */ + IN_RANGE(dfd_srv_oob_ctx.uri[i], 97, 122) || /* ALPHA LOWER CASE */ + dfd_srv_oob_ctx.uri[i] == '.' || + dfd_srv_oob_ctx.uri[i] == '+' || + dfd_srv_oob_ctx.uri[i] == '-') { + scheme[i] = dfd_srv_oob_ctx.uri[i]; + } else { + break; + } + } + + if (i == dfd_srv_oob_ctx.uri_len || dfd_srv_oob_ctx.uri[i] != ':') { + status = BT_MESH_DFD_ERR_URI_MALFORMED; + } else if (i != strlen(SUPPORTED_SCHEME) || + memcmp(scheme, SUPPORTED_SCHEME, strlen(SUPPORTED_SCHEME))) { + status = BT_MESH_DFD_ERR_URI_NOT_SUPPORTED; + } else { + status = BT_MESH_DFD_SUCCESS; + } + + err = bt_mesh_dfd_srv_oob_check_complete(&dfd_srv, dfd_srv_oob_ctx.slot, status, + dfd_srv_oob_ctx.fwid, dfd_srv_oob_ctx.fwid_len); + LOG_DBG("OOB check completed (err %d)", err); +} + +static void oob_store_handler(struct k_work *work) +{ + int err; + + err = bt_mesh_dfd_srv_oob_store_complete(&dfd_srv, dfd_srv_oob_ctx.slot, true, + 10000, "metadata", 8); + LOG_DBG("OOB store completed (err %d)", err); +} +#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ #endif #if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) From 2c9fc043d712e23754f8605b04ef8d10e9fa8be6 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 10 Oct 2023 09:50:18 +0200 Subject: [PATCH 1873/4498] Bluetooth: Mesh: Print URI and FWID in Upload OOB Start msg this is useful for debugging. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index cfcc82eb8d1..2547c07a5b4 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -572,6 +572,10 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg fwid_len = buf->len; fwid = net_buf_simple_pull_mem(buf, fwid_len); + LOG_DBG("Upload OOB Start"); + LOG_HEXDUMP_DBG(uri, uri_len, "URI"); + LOG_HEXDUMP_DBG(fwid, fwid_len, "FWID"); + if (upload_is_busy(srv)) { #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD if (srv->upload.is_oob && From 739bbbb153c7504027e9087b2923b75da2345a0e Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 4 Oct 2023 11:15:40 +0200 Subject: [PATCH 1874/4498] doc/releases/release-notes-3.5: add RISC-V release notes This commit adds RISC-V release notes for Zephyr v3.5.0. Signed-off-by: Filip Kokosinski --- doc/releases/migration-guide-3.5.rst | 2 ++ doc/releases/release-notes-3.5.rst | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index a31cfddae14..4bb9ca28fe0 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -268,6 +268,8 @@ Required changes }; +* The :kconfig:option:`CONFIG_RISCV_MTVEC_VECTORED_MODE` Kconfig option was renamed to + :kconfig:option:`CONFIG_RISCV_VECTORED_MODE`. Recommended Changes ******************* diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 1b2c13052b5..28894e9352d 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -71,6 +71,16 @@ Architectures * RISC-V + * Added support for detecting null pointer exception using PMP. + * Added the :kconfig:option:`CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET` + option to allow IRQ vector at a specified offset to meet the requirements + set by the Core-Local Interrupt Controller RISC-V specification. + * Added the :kconfig:option:`CONFIG_RISCV_SOC_HAS_CUSTOM_SYS_IO` option to + allow the use of custom system input/output functions. + * Introduced the :kconfig:option:`CONFIG_RISCV_TRAP_HANDLER_ALIGNMENT` option + to set the correct alignment of the trap handling code which is dependent on + the ``MTVEC.BASE`` field size and is platform or application-specific. + * Xtensa * Added basic MMU v2 Support. From dd743c97a40a5e3069d65e0a1bfc76920e80f54c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:26:36 +0000 Subject: [PATCH 1875/4498] tests: drivers: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/drivers/adc/adc_dma/testcase.yaml | 2 +- tests/drivers/bbram/testcase.yaml | 2 +- tests/drivers/bc12/testcase.yaml | 3 +- .../drivers/charger/sbs_charger/testcase.yaml | 40 ++++++++++--------- .../disk/disk_performance/testcase.yaml | 2 +- .../drivers/fuel_gauge/bq27z746/testcase.yaml | 5 ++- .../drivers/fuel_gauge/max17048/testcase.yaml | 5 ++- .../fuel_gauge/sbs_gauge/testcase.yaml | 7 ++-- tests/drivers/led/led_api/testcase.yaml | 2 +- tests/drivers/spi/spi_loopback/testcase.yaml | 10 ++--- tests/drivers/udc/testcase.yaml | 2 +- 11 files changed, 43 insertions(+), 37 deletions(-) diff --git a/tests/drivers/adc/adc_dma/testcase.yaml b/tests/drivers/adc/adc_dma/testcase.yaml index daf073bab5c..6db57d4be6c 100644 --- a/tests/drivers/adc/adc_dma/testcase.yaml +++ b/tests/drivers/adc/adc_dma/testcase.yaml @@ -4,7 +4,7 @@ common: - dma - trigger tests: - drivers.adc-dma: + drivers.adc.dma: depends_on: - adc - dma diff --git a/tests/drivers/bbram/testcase.yaml b/tests/drivers/bbram/testcase.yaml index 00f0eb9bcc9..db1d1640772 100644 --- a/tests/drivers/bbram/testcase.yaml +++ b/tests/drivers/bbram/testcase.yaml @@ -22,7 +22,7 @@ tests: filter: dt_compat_enabled("st,stm32-bbram") integration_platforms: - stm32f746g_disco - driver.bbram.stm32_rtc: + drivers.bbram.stm32_rtc: extra_args: OVERLAY_CONFIG="stm32_rtc.conf" filter: dt_compat_enabled("st,stm32-bbram") integration_platforms: diff --git a/tests/drivers/bc12/testcase.yaml b/tests/drivers/bc12/testcase.yaml index f7244908edf..1562b625592 100644 --- a/tests/drivers/bc12/testcase.yaml +++ b/tests/drivers/bc12/testcase.yaml @@ -1,6 +1,7 @@ tests: - drivers.bc12: + drivers.usb.bc12: tags: - drivers + - usb - bc12 platform_allow: native_posix diff --git a/tests/drivers/charger/sbs_charger/testcase.yaml b/tests/drivers/charger/sbs_charger/testcase.yaml index 680f0b6caa3..1cc4904010b 100644 --- a/tests/drivers/charger/sbs_charger/testcase.yaml +++ b/tests/drivers/charger/sbs_charger/testcase.yaml @@ -1,7 +1,9 @@ tests: # section.subsection - drivers.sbs_charger.emulated: - tags: drivers charger + drivers.charger.sbs.emulated: + tags: + - drivers + - charger filter: > dt_compat_enabled("sbs,sbs-charger") and (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) @@ -9,26 +11,28 @@ tests: CONF_FILE="prj.conf;boards/emulated_board.conf" DTC_OVERLAY_FILE="boards/emulated_board.overlay" platform_exclude: - qemu_cortex_a53 - qemu_cortex_a53_smp - qemu_kvm_arm64 - xenvm - xenvm_gicv3 - hifive_unmatched - rcar_h3ulcb_ca57 - rcar_salvator_xs_m3 - numaker_pfm_m467 - drivers.sbs_charger.emulated_64_bit_i2c_addr: - tags: drivers charger + - qemu_cortex_a53 + - qemu_cortex_a53_smp + - qemu_kvm_arm64 + - xenvm + - xenvm_gicv3 + - hifive_unmatched + - rcar_h3ulcb_ca57 + - rcar_salvator_xs_m3 + - numaker_pfm_m467 + drivers.charger.sbs.emulated_64_bit_i2c_addr: + tags: + - drivers + - charger filter: > dt_compat_enabled("sbs,sbs-charger") and (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) platform_allow: - qemu_cortex_a53 - qemu_cortex_a53_smp - qemu_kvm_arm64 - xenvm - xenvm_gicv3 + - qemu_cortex_a53 + - qemu_cortex_a53_smp + - qemu_kvm_arm64 + - xenvm + - xenvm_gicv3 extra_args: CONF_FILE="prj.conf;boards/qemu_cortex_a53.conf" DTC_OVERLAY_FILE="boards/qemu_cortex_a53.overlay" diff --git a/tests/drivers/disk/disk_performance/testcase.yaml b/tests/drivers/disk/disk_performance/testcase.yaml index f51e9f196e7..af008bf56e0 100644 --- a/tests/drivers/disk/disk_performance/testcase.yaml +++ b/tests/drivers/disk/disk_performance/testcase.yaml @@ -11,7 +11,7 @@ tests: integration_platforms: - mimxrt1064_evk - mimxrt595_evk_cm33 - drivers.disk_performance.disk.nvme: + drivers.disk.disk_performance.disk.nvme: extra_configs: - CONFIG_NVME=y platform_allow: qemu_x86_64 diff --git a/tests/drivers/fuel_gauge/bq27z746/testcase.yaml b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml index 6d9096b3a98..21f149d4da2 100644 --- a/tests/drivers/fuel_gauge/bq27z746/testcase.yaml +++ b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml @@ -1,5 +1,6 @@ tests: - # section.subsection - drivers.bq27z746: + drivers.fuel_gauge.bq27z746: + tags: + - fuel_gauge filter: dt_compat_enabled("ti,bq27z746") platform_allow: native_posix diff --git a/tests/drivers/fuel_gauge/max17048/testcase.yaml b/tests/drivers/fuel_gauge/max17048/testcase.yaml index 742d2fee9ea..33c8def4195 100644 --- a/tests/drivers/fuel_gauge/max17048/testcase.yaml +++ b/tests/drivers/fuel_gauge/max17048/testcase.yaml @@ -1,5 +1,6 @@ tests: - # section.subsection - drivers.max17048: + drivers.fuel_gauge.max17048: + tags: + - fuel_gauge filter: dt_compat_enabled("maxim,max17048") platform_allow: native_posix diff --git a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml index d7f85f58bb6..66e3dde18df 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml +++ b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml @@ -1,6 +1,5 @@ tests: - # section.subsection - drivers.sbs_gauge_new_api.emulated: + drivers.fuel_gauge.sbs_gauge_new_api.emulated: tags: - drivers - fuel_gauge @@ -21,7 +20,7 @@ tests: - rcar_salvator_xs_m3 integration_platforms: - qemu_x86 - drivers.sbs_gauge_new_api.emulated_64_bit_i2c_addr: + drivers.fuel_gauge.sbs_gauge_new_api.emulated_64_bit_i2c_addr: tags: - drivers - fuel_gauge @@ -40,7 +39,7 @@ tests: extra_args: - CONF_FILE="prj.conf;boards/qemu_cortex_a53.conf" - DTC_OVERLAY_FILE="boards/qemu_cortex_a53.overlay" - drivers.sbs_gauge_new_api.emulated.cutoff: + drivers.fuel_gauge.sbs_gauge_new_api.emulated.cutoff: tags: - drivers - fuel_gauge diff --git a/tests/drivers/led/led_api/testcase.yaml b/tests/drivers/led/led_api/testcase.yaml index 3af8b79d855..35e3eaca9d4 100644 --- a/tests/drivers/led/led_api/testcase.yaml +++ b/tests/drivers/led/led_api/testcase.yaml @@ -1,5 +1,5 @@ tests: - drivers.led_api.i2c: + drivers.led.api.i2c: tags: - drivers - led diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index 4abf97911ce..ed2339d8f54 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -110,31 +110,31 @@ tests: - gd32vf103v_eval - longan_nano - longan_nano_lite - drivers.pl022_spi_interrupt.loopback: + drivers.spi.pl022_spi_interrupt.loopback: extra_configs: - CONFIG_SPI_PL022_INTERRUPT=y - CONFIG_SPI_PL022_DMA=n platform_allow: rpi_pico - drivers.pl022_spi_dma.loopback: + drivers.spi.pl022_spi_dma.loopback: extra_configs: - CONFIG_SPI_PL022_INTERRUPT=n - CONFIG_SPI_PL022_DMA=y - CONFIG_DMA=y platform_allow: rpi_pico - drivers.pl022_spi_dma_and_interrupt.loopback: + drivers.spi.pl022_spi_dma_and_interrupt.loopback: extra_configs: - CONFIG_SPI_PL022_INTERRUPT=y - CONFIG_SPI_PL022_DMA=y - CONFIG_DMA=y platform_allow: rpi_pico - drivers.pl022_spi_dma_no_dma_props.loopback: + drivers.spi.pl022_spi_dma_no_dma_props.loopback: extra_args: DTC_OVERLAY_FILE="boards/rpi_pico_delete_dma_props.overlay" extra_configs: - CONFIG_SPI_PL022_INTERRUPT=n - CONFIG_SPI_PL022_DMA=y - CONFIG_DMA=y platform_allow: rpi_pico - drivers.pl022_spi_dma_and_interrupt_no_dma_props.loopback: + drivers.spi.pl022_spi_dma_and_interrupt_no_dma_props.loopback: extra_args: DTC_OVERLAY_FILE="boards/rpi_pico_delete_dma_props.overlay" extra_configs: - CONFIG_SPI_PL022_INTERRUPT=y diff --git a/tests/drivers/udc/testcase.yaml b/tests/drivers/udc/testcase.yaml index 0379e3de615..97b644d6d8c 100644 --- a/tests/drivers/udc/testcase.yaml +++ b/tests/drivers/udc/testcase.yaml @@ -1,5 +1,5 @@ tests: - drivers.udc: + drivers.usb.udc: tags: - usb - drivers From b0b8f2ff80fdf7c0f6a14c782f65d8d9633b63a0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:27:14 +0000 Subject: [PATCH 1876/4498] tests: sensors: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/drivers/sensor/sbs_gauge/testcase.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/sensor/sbs_gauge/testcase.yaml b/tests/drivers/sensor/sbs_gauge/testcase.yaml index 9be31c476a9..b19fffaab42 100644 --- a/tests/drivers/sensor/sbs_gauge/testcase.yaml +++ b/tests/drivers/sensor/sbs_gauge/testcase.yaml @@ -1,6 +1,6 @@ tests: # section.subsection - drivers.sensors.sbs_gauge: + drivers.sensor.sbs_gauge: build_only: true tags: - drivers @@ -9,7 +9,7 @@ tests: dt_compat_enabled("sbs,sbs-gauge") and not dt_compat_enabled("zephyr,i2c-emul-controller") integration_platforms: - nucleo_f070rb - drivers.sensors.sbs_gauge.emulated: + drivers.sensor.sbs_gauge.emulated: tags: - drivers - sensors From d5bac8c9a20d6038b046182f6a89350419c49a28 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:28:22 +0000 Subject: [PATCH 1877/4498] tests: clock: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- .../stm32_common_core/testcase.yaml | 76 +++++++++---------- .../stm32_common_devices/testcase.yaml | 22 +++--- .../stm32h5_core/testcase.yaml | 18 ++--- .../stm32h7_core/testcase.yaml | 14 ++-- .../stm32h7_devices/testcase.yaml | 14 ++-- .../stm32u5_core/testcase.yaml | 22 +++--- .../stm32u5_devices/testcase.yaml | 8 +- .../stm32wba_core/testcase.yaml | 12 +-- 8 files changed, 93 insertions(+), 93 deletions(-) diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml index 7800f6ed294..da7df163972 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml @@ -8,7 +8,7 @@ common: timeout: 5 tags: clock-control tests: - drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_48_msi_4: + drivers.clock.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_48_msi_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_48_msi_4.overlay" platform_allow: @@ -17,7 +17,7 @@ tests: - stm32l562e_dk integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_64_hsi_16.overlay" platform_allow: @@ -26,7 +26,7 @@ tests: - stm32l562e_dk integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.sysclksrc_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hsi_16.overlay" platform_allow: @@ -37,7 +37,7 @@ tests: - nucleo_wl55jc integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.sysclksrc_msi_48: + drivers.clock.stm32_clock_configuration.common_core.sysclksrc_msi_48: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/msi_range11.overlay" platform_allow: @@ -48,7 +48,7 @@ tests: - nucleo_wb55rg integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_hse_8.fixup: + drivers.clock.stm32_clock_configuration.common_core.l4_l5.sysclksrc_hse_8.fixup: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hse_8.overlay" platform_allow: @@ -60,7 +60,7 @@ tests: fixture: mco_sb_closed integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hse_8.fixup: + drivers.clock.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hse_8.fixup: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_64_hse_8.overlay" platform_allow: @@ -72,7 +72,7 @@ tests: fixture: mco_sb_closed integration_platforms: - disco_l475_iot1 - drivers.stm32_clock_configuration.common_core.g0.sysclksrc_pll_64_hse_8: + drivers.clock.stm32_clock_configuration.common_core.g0.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_64_hse_8.overlay" platform_allow: nucleo_g071rb harness: ztest @@ -80,40 +80,40 @@ tests: fixture: mco_sb_closed integration_platforms: - nucleo_g071rb - drivers.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16_div_2: + drivers.clock.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16_div_2: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_g0_16_div_2.overlay" platform_allow: nucleo_g071rb integration_platforms: - nucleo_g071rb - drivers.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16_div_4: + drivers.clock.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16_div_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_g0_16_div_4.overlay" platform_allow: nucleo_g071rb integration_platforms: - nucleo_g071rb - drivers.stm32_clock_configuration.common_core.g4.sysclksrc_pll_64_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.g4.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_64_hsi_16.overlay" platform_allow: nucleo_g474re integration_platforms: - nucleo_g474re - drivers.stm32_clock_configuration.common_core.g0.sysclksrc_pll_g0_64_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.g0.sysclksrc_pll_g0_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_g0_64_hsi_16.overlay" platform_allow: nucleo_g071rb integration_platforms: - nucleo_g071rb - drivers.stm32_clock_configuration.common_core.g4.sysclksrc_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.g4.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_16.overlay" platform_allow: nucleo_g474re integration_platforms: - nucleo_g474re - drivers.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16: + drivers.clock.stm32_clock_configuration.common_core.g0.sysclksrc_hsi_g0_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_g0_16.overlay" platform_allow: nucleo_g071rb integration_platforms: - nucleo_g071rb - drivers.stm32_clock_configuration.common_core.g4.sysclksrc_hse_24: + drivers.clock.stm32_clock_configuration.common_core.g4.sysclksrc_hse_24: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_24.overlay" platform_allow: nucleo_g474re - drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_hse_8: + drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hse_8.overlay" platform_allow: @@ -121,77 +121,77 @@ tests: - nucleo_l073rz integration_platforms: - nucleo_l152re - drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hse_8: + drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_32_hse_8.overlay" platform_allow: - nucleo_l152re - nucleo_l073rz integration_platforms: - nucleo_l152re - drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_32_hsi_16.overlay" platform_allow: - nucleo_l152re - nucleo_l073rz integration_platforms: - nucleo_l152re - drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_msi_range6: + drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_msi_range6: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/msi_range6.overlay" platform_allow: - nucleo_l152re - nucleo_l073rz integration_platforms: - nucleo_l152re - drivers.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_48_hsi_16.overlay" platform_allow: nucleo_wl55jc integration_platforms: - nucleo_wl55jc - drivers.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hse_32: + drivers.clock.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wl_pll_48_hse_32.overlay" platform_allow: nucleo_wl55jc integration_platforms: - nucleo_wl55jc - drivers.stm32_clock_configuration.common_core.wl.sysclksrc_hse_32: + drivers.clock.stm32_clock_configuration.common_core.wl.sysclksrc_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wl_32_hse.overlay" platform_allow: nucleo_wl55jc integration_platforms: - nucleo_wl55jc - drivers.stm32_clock_configuration.common_core.wb.sysclksrc_hse_32: + drivers.clock.stm32_clock_configuration.common_core.wb.sysclksrc_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_32.overlay" platform_allow: nucleo_wb55rg integration_platforms: - nucleo_wb55rg - drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_48_hsi_16.overlay" platform_allow: nucleo_wb55rg integration_platforms: - nucleo_wb55rg - drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_64_hse_32: + drivers.clock.stm32_clock_configuration.common_core.wb.sysclksrc_pll_64_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_64_hse_32.overlay" platform_allow: nucleo_wb55rg integration_platforms: - nucleo_wb55rg - drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_msi_4: + drivers.clock.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_msi_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_48_msi_4.overlay" platform_allow: nucleo_wb55rg integration_platforms: - nucleo_wb55rg - drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hsi_8: + drivers.clock.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hsi_8.overlay" platform_allow: - nucleo_f091rc - stm32f3_disco integration_platforms: - nucleo_f091rc - drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hse_8_bypass.overlay" platform_allow: - nucleo_f091rc - stm32f3_disco integration_platforms: - nucleo_f091rc - drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hsi_8: + drivers.clock.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f0_f3_pll_32_hsi_8.overlay" platform_allow: @@ -199,7 +199,7 @@ tests: - stm32f3_disco integration_platforms: - nucleo_f091rc - drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f0_f3_pll_32_hse_8.overlay" platform_allow: @@ -207,29 +207,29 @@ tests: - stm32f3_disco integration_platforms: - nucleo_f091rc - drivers.stm32_clock_configuration.common_core.f1.sysclksrc_hsi_8: + drivers.clock.stm32_clock_configuration.common_core.f1.sysclksrc_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hsi_8.overlay" platform_allow: nucleo_f103rb integration_platforms: - nucleo_f103rb - drivers.stm32_clock_configuration.common_core.f1.sysclksrc_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f1.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hse_8.overlay" platform_allow: nucleo_f103rb integration_platforms: - nucleo_f103rb - drivers.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hsi_8: + drivers.clock.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f1_pll_64_hsi_8.overlay" platform_allow: nucleo_f103rb integration_platforms: - nucleo_f103rb - drivers.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f1_pll_64_hse_8.overlay" platform_allow: nucleo_f103rb integration_platforms: - nucleo_f103rb - drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/hsi_16.overlay" platform_allow: - nucleo_f207zg @@ -238,7 +238,7 @@ tests: - nucleo_f746zg integration_platforms: - nucleo_f207zg - drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/hse_8.overlay" platform_allow: - nucleo_f207zg @@ -247,7 +247,7 @@ tests: - nucleo_f746zg integration_platforms: - nucleo_f207zg - drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_64_hsi_16.overlay" platform_allow: @@ -257,7 +257,7 @@ tests: - nucleo_f746zg integration_platforms: - nucleo_f207zg - drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hse_8: + drivers.clock.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_64_hse_8.overlay" platform_allow: @@ -267,7 +267,7 @@ tests: - nucleo_f746zg integration_platforms: - nucleo_f207zg - drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_100_hsi_16_ahb2: + drivers.clock.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_100_hsi_16_ahb2: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay" platform_allow: diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml index 351268c6a5f..535a16a4ed9 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml @@ -1,36 +1,36 @@ common: timeout: 5 tests: - drivers.stm32_clock_configuration.common_device.wb.i2c1_hsi_lptim1_lse: + drivers.clock.stm32_clock_configuration.common_device.wb.i2c1_hsi_lptim1_lse: extra_args: DTC_OVERLAY_FILE="boards/wb_i2c1_hsi_lptim1_lse.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common_device.wb.i2c1_sysclk_lptim1_lsi: + drivers.clock.stm32_clock_configuration.common_device.wb.i2c1_sysclk_lptim1_lsi: extra_args: DTC_OVERLAY_FILE="boards/wb_i2c1_sysclk_lptim1_lsi.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common_device.g0.i2c1_sysclk_lptim1_lsi: + drivers.clock.stm32_clock_configuration.common_device.g0.i2c1_sysclk_lptim1_lsi: extra_args: DTC_OVERLAY_FILE="boards/g0_i2c1_sysclk_lptim1_lsi.overlay" platform_allow: nucleo_g071rb - drivers.stm32_clock_configuration.common_device.g0.i2c1_hsi_lptim1_lse_adc1_pllp: + drivers.clock.stm32_clock_configuration.common_device.g0.i2c1_hsi_lptim1_lse_adc1_pllp: extra_args: DTC_OVERLAY_FILE="boards/g0_i2c1_hsi_lptim1_lse_adc1_pllp.overlay" platform_allow: nucleo_g071rb - drivers.stm32_clock_configuration.common_device.wl.i2c1_hsi_lptim1_lse_adc1_pllp: + drivers.clock.stm32_clock_configuration.common_device.wl.i2c1_hsi_lptim1_lse_adc1_pllp: extra_args: DTC_OVERLAY_FILE="boards/wl_i2c1_hsi_lptim1_lse_adc1_pllp.overlay" platform_allow: nucleo_wl55jc - drivers.stm32_clock_configuration.common_device.wl.i2c1_sysclk_lptim1_lsi: + drivers.clock.stm32_clock_configuration.common_device.wl.i2c1_sysclk_lptim1_lsi: extra_args: DTC_OVERLAY_FILE="boards/wl_i2c1_sysclk_lptim1_lsi.overlay" platform_allow: nucleo_wl55jc - drivers.stm32_clock_configuration.common_device.l4.i2c1_sysclk_lptim1_lsi: + drivers.clock.stm32_clock_configuration.common_device.l4.i2c1_sysclk_lptim1_lsi: extra_args: DTC_OVERLAY_FILE="boards/l4_i2c1_sysclk_lptim1_lsi.overlay" platform_allow: disco_l475_iot1 - drivers.stm32_clock_configuration.common_device.l4.i2c1_hsi_lptim1_lse: + drivers.clock.stm32_clock_configuration.common_device.l4.i2c1_hsi_lptim1_lse: extra_args: DTC_OVERLAY_FILE="boards/l4_i2c1_hsi_lptim1_lse.overlay" platform_allow: disco_l475_iot1 - drivers.stm32_clock_configuration.common_device.g4.i2c1_hsi_adc1_pllp: + drivers.clock.stm32_clock_configuration.common_device.g4.i2c1_hsi_adc1_pllp: extra_args: DTC_OVERLAY_FILE="boards/g4_i2c1_hsi_adc1_pllp.overlay" platform_allow: nucleo_g474re - drivers.stm32_clock_configuration.common_device.f0.i2c1_hsi: + drivers.clock.stm32_clock_configuration.common_device.f0.i2c1_hsi: extra_args: DTC_OVERLAY_FILE="boards/f0_i2c1_hsi.overlay" platform_allow: nucleo_f091rc - drivers.stm32_clock_configuration.common_device.f3.i2c1_hsi: + drivers.clock.stm32_clock_configuration.common_device.f3.i2c1_hsi: extra_args: DTC_OVERLAY_FILE="boards/f3_i2c1_hsi.overlay" platform_allow: stm32f3_disco diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/testcase.yaml index d1e72c25174..0fce41b326f 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/testcase.yaml @@ -3,30 +3,30 @@ common: tags: clock_control tests: - drivers.stm32_clock_configuration.h5.sysclksrc_pll_csi_100: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_pll_csi_100: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_csi_100.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_pll_csi_240: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_pll_csi_240: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_csi_240.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_pll_hsi_240: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_pll_hsi_240: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_240.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_pll_hse25_100: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_pll_hse25_100: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse25_100.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_pll_hse25_240: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_pll_hse25_240: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse25_240.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_csi4: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_csi4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/csi4.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.sysclksrc_hse_25: + drivers.clock.stm32_clock_configuration.h5.sysclksrc_hse_25: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse25.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.pll_csi_ahb_2_100: + drivers.clock.stm32_clock_configuration.h5.pll_csi_ahb_2_100: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_csi_ahb_2_100.overlay" platform_allow: stm32h573i_dk - drivers.stm32_clock_configuration.h5.pll_hse25_ahb_2_100: + drivers.clock.stm32_clock_configuration.h5.pll_hse25_ahb_2_100: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse25_ahb_2_100.overlay" platform_allow: stm32h573i_dk diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/testcase.yaml index 4883264e303..f134f811906 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/testcase.yaml @@ -3,37 +3,37 @@ common: tags: clock_control tests: - drivers.stm32_clock_configuration.h7_core.sysclksrc_pll_hse_96: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_pll_hse_96: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_96.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_pll_hsi_96: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_pll_hsi_96: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_96.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_hsi_64: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_hsi_64: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_64.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_csi_4: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_csi_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/csi_4.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_hse_8: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_8.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_pll_csi_96: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_pll_csi_96: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_csi_96.overlay" platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi - drivers.stm32_clock_configuration.h7_core.sysclksrc_pll_hse_550: + drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_pll_hse_550: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_550.overlay" platform_allow: - nucleo_h723zg diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml index d914bb93ae3..692c716fcee 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml @@ -2,17 +2,17 @@ common: timeout: 5 platform_allow: nucleo_h723zg tests: - drivers.stm32_clock_configuration.h7_dev.spi1_pllq_1_d1ppre_1: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_pllq_1_d1ppre_1: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pllq_1_d1ppre_1.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_pllq_2_d1ppre_4: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_pllq_2_d1ppre_4: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pllq_2_d1ppre_4.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_pll2p_1: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_pll2p_1: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pll2p_1.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_pll3p_1_d1ppre_4: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_pll3p_1_d1ppre_4: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pll3p_1_d1ppre_4.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_per_ck_d1ppre_1: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_per_ck_d1ppre_1: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_per_ck_d1ppre_1.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_per_ck_hsi: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_per_ck_hsi: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_per_ck_hsi.overlay" - drivers.stm32_clock_configuration.h7_dev.spi1_per_ck_hse: + drivers.clock.stm32_clock_configuration.h7_dev.spi1_per_ck_hse: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_per_ck_hse.overlay" diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml index 7a45d2c5e62..8c6e003b913 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml @@ -2,31 +2,31 @@ common: timeout: 5 platform_allow: b_u585i_iot02a tests: - drivers.stm32_clock_configuration.u5.sysclksrc_pll_msis_160: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_msis_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_msis_160.overlay" - drivers.stm32_clock_configuration.u5.pll_msis_ahb_2_40: + drivers.clock.stm32_clock_configuration.u5.pll_msis_ahb_2_40: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_msis_ahb_2_40.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_160: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_hsi_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_160.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_40: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_hsi_40: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_40.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_msis_48: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_msis_48: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/msis_48.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_msis_24: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_msis_24: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/msis_24.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_hsi_16: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_16.overlay" - drivers.stm32_clock_configuration.u5.sysclksrc_hse_16: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_hse_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_16.overlay" # Build only as HSE not implemened on available boards build_only: true - drivers.stm32_clock_configuration.u5.sysclksrc_pll_hse_160: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_hse_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_160.overlay" # Build only as HSE not implemened on available boards build_only: true - drivers.stm32_clock_configuration.u5.sysclksrc_pll_hse_fracn_160: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_hse_fracn_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_fracn_160.overlay" # Build only as HSE not implemened on available boards build_only: true - drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_fracn_160: + drivers.clock.stm32_clock_configuration.u5.sysclksrc_pll_hsi_fracn_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_fracn_160.overlay" diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml index 5f27ed3bfbc..1a01b0c3895 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml @@ -2,11 +2,11 @@ common: timeout: 5 platform_allow: b_u585i_iot02a tests: - drivers.stm32_clock_configuration.dev_u5.spi1_pclk2: + drivers.clock.stm32_clock_configuration.dev_u5.spi1_pclk2: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pclk2.overlay" - drivers.stm32_clock_configuration.dev_u5.spi1_hsi_16: + drivers.clock.stm32_clock_configuration.dev_u5.spi1_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_hsi_16.overlay" - drivers.stm32_clock_configuration.dev_u5.spi1_msik: + drivers.clock.stm32_clock_configuration.dev_u5.spi1_msik: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_msik.overlay" - drivers.stm32_clock_configuration.dev_u5.spi1_sysclk: + drivers.clock.stm32_clock_configuration.dev_u5.spi1_sysclk: extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_sysclk.overlay" diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/testcase.yaml index e540315bcea..bdaf05c588e 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/testcase.yaml @@ -2,15 +2,15 @@ common: timeout: 5 platform_allow: nucleo_wba52cg tests: - drivers.stm32_clock_configuration.wba.sysclksrc_hsi_32: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_hsi_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_16.overlay" - drivers.stm32_clock_configuration.wba.sysclksrc_hsi_32_ahb5_div: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_hsi_32_ahb5_div: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_16_ahb5_div.overlay" - drivers.stm32_clock_configuration.wba.sysclksrc_hse_16: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_hse_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_16.overlay" - drivers.stm32_clock_configuration.wba.sysclksrc_hse_32: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_32.overlay" - drivers.stm32_clock_configuration.wba.sysclksrc_pll_hse_100: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_pll_hse_100: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_100.overlay" - drivers.stm32_clock_configuration.wba.sysclksrc_pll_hse_50: + drivers.clock.stm32_clock_configuration.wba.sysclksrc_pll_hse_50: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hse_100_ahb_50.overlay" From 4373f250bf3267b5c8e19693e7731d84830e09e8 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:28:38 +0000 Subject: [PATCH 1878/4498] tests: uart: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/drivers/uart/uart_emul/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/uart/uart_emul/testcase.yaml b/tests/drivers/uart/uart_emul/testcase.yaml index 3731e8ee0b9..68838e56a36 100644 --- a/tests/drivers/uart/uart_emul/testcase.yaml +++ b/tests/drivers/uart/uart_emul/testcase.yaml @@ -4,5 +4,5 @@ common: - uart harness: ztest tests: - drivers.uart_emul.polling: + drivers.uart.emul.polling: platform_allow: qemu_x86 From 36dde2c2ef2ab8d201cf85a7b93211716e0b9c20 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:32:25 +0000 Subject: [PATCH 1879/4498] tests: fs: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/subsys/fs/fcb/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/fs/fcb/testcase.yaml b/tests/subsys/fs/fcb/testcase.yaml index 4902bfa2a65..951b9c5c945 100644 --- a/tests/subsys/fs/fcb/testcase.yaml +++ b/tests/subsys/fs/fcb/testcase.yaml @@ -10,7 +10,7 @@ tests: tags: flash_circural_buffer integration_platforms: - nrf52840dk_nrf52840 - filesystem.native_posix.fcb_0x00: + filesystem.fcb.native_posix.fcb_0x00: extra_args: DTC_OVERLAY_FILE=boards/native_posix_ev_0x00.overlay platform_allow: native_posix filesystem.qemu_x86.fcb_0x00: From 47983916a2e29b94b35f6cee6243607902f59f51 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:40:30 +0000 Subject: [PATCH 1880/4498] tests: nvs: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/subsys/fs/nvs/testcase.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/subsys/fs/nvs/testcase.yaml b/tests/subsys/fs/nvs/testcase.yaml index 83ae545ab22..fd8386ffbd7 100644 --- a/tests/subsys/fs/nvs/testcase.yaml +++ b/tests/subsys/fs/nvs/testcase.yaml @@ -3,10 +3,10 @@ common: tests: filesystem.nvs: platform_allow: qemu_x86 - filesystem.nvs_0x00: + filesystem.nvs.0x00: extra_args: DTC_OVERLAY_FILE=boards/qemu_x86_ev_0x00.overlay platform_allow: qemu_x86 - filesystem.nvs_cache: + filesystem.nvs.cache: extra_args: - CONFIG_NVS_LOOKUP_CACHE=y - CONFIG_NVS_LOOKUP_CACHE_SIZE=64 From c9a2e0f0e8f8fb10023e17a726b13b7a14c8c376 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:40:42 +0000 Subject: [PATCH 1881/4498] tests: fcb: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/subsys/fs/fcb/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/fs/fcb/testcase.yaml b/tests/subsys/fs/fcb/testcase.yaml index 951b9c5c945..0d5d1938b25 100644 --- a/tests/subsys/fs/fcb/testcase.yaml +++ b/tests/subsys/fs/fcb/testcase.yaml @@ -13,6 +13,6 @@ tests: filesystem.fcb.native_posix.fcb_0x00: extra_args: DTC_OVERLAY_FILE=boards/native_posix_ev_0x00.overlay platform_allow: native_posix - filesystem.qemu_x86.fcb_0x00: + filesystem.fcb.qemu_x86.fcb_0x00: extra_args: DTC_OVERLAY_FILE=boards/qemu_x86_ev_0x00.overlay platform_allow: qemu_x86 From b2af50a8361a0a69ae9f412cd6863915c8d7a585 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:40:49 +0000 Subject: [PATCH 1882/4498] tests: object cores: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/kernel/obj_core/obj_core_stats/testcase.yaml | 2 +- tests/kernel/obj_core/obj_core_stats_api/testcase.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/kernel/obj_core/obj_core_stats/testcase.yaml b/tests/kernel/obj_core/obj_core_stats/testcase.yaml index e2276a001b8..28bbaf1ec71 100644 --- a/tests/kernel/obj_core/obj_core_stats/testcase.yaml +++ b/tests/kernel/obj_core/obj_core_stats/testcase.yaml @@ -1,5 +1,5 @@ tests: - kernel.obj_core_stats: + kernel.obj_core.stats: tags: kernel ignore_faults: true integration_platforms: diff --git a/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml b/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml index 6ac7bfe663b..c17ff99e213 100644 --- a/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml +++ b/tests/kernel/obj_core/obj_core_stats_api/testcase.yaml @@ -1,5 +1,5 @@ tests: - kernel.obj_core_stats_api: + kernel.obj_core.stats.api: tags: kernel ignore_faults: true integration_platforms: From 38a480c20e2f1112df589b599ae1d365bd9f00ed Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:44:46 +0000 Subject: [PATCH 1883/4498] tests: cbprintf: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/lib/cbprintf_fp/testcase.yaml | 18 +++++------ tests/lib/cbprintf_package/testcase.yaml | 40 ++++++++++++------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/lib/cbprintf_fp/testcase.yaml b/tests/lib/cbprintf_fp/testcase.yaml index 1d8585c53b5..6cc638b5060 100644 --- a/tests/lib/cbprintf_fp/testcase.yaml +++ b/tests/lib/cbprintf_fp/testcase.yaml @@ -7,7 +7,7 @@ common: - qemu_x86_64 filter: CONFIG_CONSOLE_HAS_DRIVER tests: - libraries.cbprintf_fp.printk: + libraries.cbprintf.fp.printk: extra_configs: - CONFIG_APP_FORMATTER_PRINTK=y harness_config: @@ -16,7 +16,7 @@ tests: regex: - "Hello with printk" - "Complete" - libraries.cbprintf_fp.printf: + libraries.cbprintf.fp.printf: extra_configs: - CONFIG_APP_FORMATTER_PRINTF=y harness_config: @@ -25,7 +25,7 @@ tests: regex: - "Hello with printf" - "Complete" - libraries.cbprintf_fp.printf_nl: + libraries.cbprintf.fp.printf_nl: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_APP_FORMATTER_PRINTF=y @@ -36,7 +36,7 @@ tests: regex: - "Hello with printf/newlib" - "Complete" - libraries.cbprintf_fp.printfcb: + libraries.cbprintf.fp.printfcb: extra_configs: - CONFIG_APP_FORMATTER_PRINTFCB=y harness_config: @@ -45,7 +45,7 @@ tests: regex: - "Hello with printfcb" - "Complete" - libraries.cbprintf_fp.printfcb_nl: + libraries.cbprintf.fp.printfcb_nl: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_APP_FORMATTER_PRINTFCB=y @@ -56,7 +56,7 @@ tests: regex: - "Hello with printfcb/newlib" - "Complete" - libraries.cbprintf_fp.fprintf: + libraries.cbprintf.fp.fprintf: extra_configs: - CONFIG_APP_FORMATTER_FPRINTF=y harness_config: @@ -65,7 +65,7 @@ tests: regex: - "Hello with fprintf" - "Complete" - libraries.cbprintf_fp.fprintfcb: + libraries.cbprintf.fp.fprintfcb: extra_configs: - CONFIG_APP_FORMATTER_FPRINTFCB=y harness_config: @@ -74,7 +74,7 @@ tests: regex: - "Hello with fprintfcb" - "Complete" - libraries.cbprintf_fp.printf.picolibc: + libraries.cbprintf.fp.printf.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -86,7 +86,7 @@ tests: regex: - "Hello with printf" - "Complete" - libraries.cbprintf_fp.printfcb.picolibc: + libraries.cbprintf.fp.printfcb.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: diff --git a/tests/lib/cbprintf_package/testcase.yaml b/tests/lib/cbprintf_package/testcase.yaml index 61654bc1187..61545936181 100644 --- a/tests/lib/cbprintf_package/testcase.yaml +++ b/tests/lib/cbprintf_package/testcase.yaml @@ -5,20 +5,20 @@ common: tags: cbprintf min_flash: 48 tests: - libraries.cbprintf_package: + libraries.cbprintf.package: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y integration_platforms: - native_posix - libraries.cbprintf_package_no_generic: + libraries.cbprintf.package_no_generic: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y - CONFIG_COMPILER_OPT="-DZ_C_GENERIC=0" integration_platforms: - native_posix - libraries.cbprintf_package_fp: + libraries.cbprintf.package_fp: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CBPRINTF_FP_SUPPORT=y @@ -27,7 +27,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_fp_align_offset: + libraries.cbprintf.package_fp_align_offset: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CBPRINTF_FP_SUPPORT=y @@ -37,7 +37,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_long_double: + libraries.cbprintf.package_long_double: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CBPRINTF_FP_SUPPORT=y @@ -48,7 +48,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_long_double_align_offset: + libraries.cbprintf.package_long_double_align_offset: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CBPRINTF_FP_SUPPORT=y @@ -60,21 +60,21 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_nano: + libraries.cbprintf.package_nano: extra_configs: - CONFIG_CBPRINTF_NANO=y integration_platforms: - native_posix # Same test but with test compiled as C++ - libraries.cbprintf_package_cpp: + libraries.cbprintf.package_cpp: extra_configs: - CONFIG_CPP=y - CONFIG_CBPRINTF_COMPLETE=y integration_platforms: - native_posix - libraries.cbprintf_package_no_generic_cpp: + libraries.cbprintf.package_no_generic_cpp: extra_configs: - CONFIG_CPP=y - CONFIG_CBPRINTF_COMPLETE=y @@ -82,7 +82,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_fp_cpp: + libraries.cbprintf.package_fp_cpp: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CPP=y @@ -92,7 +92,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_fp_align_offset_cpp: + libraries.cbprintf.package_fp_align_offset_cpp: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CPP=y @@ -103,7 +103,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_long_double_cpp: + libraries.cbprintf.package_long_double_cpp: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CPP=y @@ -115,7 +115,7 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_long_double_align_offset_cpp: + libraries.cbprintf.package_long_double_align_offset_cpp: filter: CONFIG_CPU_HAS_FPU extra_configs: - CONFIG_CPP=y @@ -128,14 +128,14 @@ tests: integration_platforms: - native_posix - libraries.cbprintf_package_nano_cpp: + libraries.cbprintf.package_nano_cpp: extra_configs: - CONFIG_CPP=y - CONFIG_CBPRINTF_NANO=y integration_platforms: - native_posix - libraries.cbprintf_package.picolibc: + libraries.cbprintf.package.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -144,7 +144,7 @@ tests: integration_platforms: - qemu_x86 - libraries.cbprintf_package_no_generic.picolibc: + libraries.cbprintf.package_no_generic.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -154,7 +154,7 @@ tests: integration_platforms: - qemu_x86 - libraries.cbprintf_package_fp.picolibc: + libraries.cbprintf.package_fp.picolibc: filter: CONFIG_CPU_HAS_FPU and CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -166,7 +166,7 @@ tests: - qemu_x86 # Same test but with test compiled as C++ - libraries.cbprintf_package_cpp.picolibc: + libraries.cbprintf.package_cpp.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -176,7 +176,7 @@ tests: integration_platforms: - qemu_x86 - libraries.cbprintf_package_no_generic_cpp.picolibc: + libraries.cbprintf.package_no_generic_cpp.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: @@ -187,7 +187,7 @@ tests: integration_platforms: - qemu_x86 - libraries.cbprintf_package_fp_cpp.picolibc: + libraries.cbprintf.package_fp_cpp.picolibc: filter: CONFIG_CPU_HAS_FPU and CONFIG_PICOLIBC_SUPPORTED tags: picolibc extra_configs: From 1164e33e0f7154225a2b4c90171436210987bfa1 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:49:23 +0000 Subject: [PATCH 1884/4498] tests: mpsc: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/lib/mpsc_pbuf/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/mpsc_pbuf/testcase.yaml b/tests/lib/mpsc_pbuf/testcase.yaml index 4a9cb29028c..df896168fdf 100644 --- a/tests/lib/mpsc_pbuf/testcase.yaml +++ b/tests/lib/mpsc_pbuf/testcase.yaml @@ -19,7 +19,7 @@ tests: integration_platforms: - native_posix - libraries.mpsc_pbuf_concurrent: + libraries.mpsc_pbuf.concurrent: tags: mpsc_pbuf platform_allow: - qemu_cortex_m3 From 3a81c76b3aa753f2e8bfa8b482ded187e838093e Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 15:50:40 +0000 Subject: [PATCH 1885/4498] tests: fdtable: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/lib/fdtable/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/fdtable/testcase.yaml b/tests/lib/fdtable/testcase.yaml index 4380327353b..0cc9df820c7 100644 --- a/tests/lib/fdtable/testcase.yaml +++ b/tests/lib/fdtable/testcase.yaml @@ -1,5 +1,5 @@ tests: - libraries.os.fdtable: + libraries.fdtable: tags: fdtable integration_platforms: - qemu_x86 From f7456cb7cd5efa2990b896afae59eea5caae26cf Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 16:55:37 +0000 Subject: [PATCH 1886/4498] tests: spsc_pbuf/ringbuffer: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/lib/ringbuffer/testcase.yaml | 2 +- tests/lib/spsc_pbuf/testcase.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/lib/ringbuffer/testcase.yaml b/tests/lib/ringbuffer/testcase.yaml index 9314885599d..b2f11681616 100644 --- a/tests/lib/ringbuffer/testcase.yaml +++ b/tests/lib/ringbuffer/testcase.yaml @@ -10,7 +10,7 @@ tests: - native_posix - native_posix_64 - libraries.ring_buffer_concurrent: + libraries.ring_buffer.concurrent: platform_allow: qemu_x86 extra_configs: - CONFIG_SYS_CLOCK_TICKS_PER_SEC=100000 diff --git a/tests/lib/spsc_pbuf/testcase.yaml b/tests/lib/spsc_pbuf/testcase.yaml index 8dd63eb1b3f..daff2fc46f2 100644 --- a/tests/lib/spsc_pbuf/testcase.yaml +++ b/tests/lib/spsc_pbuf/testcase.yaml @@ -6,7 +6,7 @@ tests: platform_exclude: ast1030_evb timeout: 120 - libraries.spsc_pbuf_cache: + libraries.spsc_pbuf.cache: integration_platforms: - native_posix # Exclude platform which does not link with cache functions @@ -15,7 +15,7 @@ tests: extra_configs: - CONFIG_SPSC_PBUF_CACHE_ALWAYS=y - libraries.spsc_pbuf_nocache: + libraries.spsc_pbuf.nocache.: integration_platforms: - native_posix # Exclude platform which does not link with cache functions @@ -24,7 +24,7 @@ tests: extra_configs: - CONFIG_SPSC_PBUF_CACHE_NEVER=y - libraries.spsc_pbuf_utilization: + libraries.spsc_pbuf.utilization: integration_platforms: - native_posix # Exclude platform which does not link with cache functions @@ -33,7 +33,7 @@ tests: extra_configs: - CONFIG_SPSC_PBUF_UTILIZATION=y - libraries.spsc_pbuf_stress: + libraries.spsc_pbuf.stress: platform_allow: qemu_x86 timeout: 120 extra_configs: From 2144d6f5e6b1571e60787e87e88678eed87b1882 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 16:57:25 +0000 Subject: [PATCH 1887/4498] tests: bluetooth: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/bluetooth/hci_uart_async/testcase.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/hci_uart_async/testcase.yaml b/tests/bluetooth/hci_uart_async/testcase.yaml index f7f4a6255eb..31b7ac8bde4 100644 --- a/tests/bluetooth/hci_uart_async/testcase.yaml +++ b/tests/bluetooth/hci_uart_async/testcase.yaml @@ -1,6 +1,8 @@ tests: - samples.bluetooth.hci_uart_async: - tags: bluetooth uart + bluetooth.hci_uart_async: + tags: + - bluetooth + - uart harness: ztest platform_allow: - native_posix From 276a0e02c611316f55abac494232ccd63ffe082c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 16:59:06 +0000 Subject: [PATCH 1888/4498] tests: mcumgr: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/subsys/mgmt/mcumgr/cb_notifications/testcase.yaml | 2 +- tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/subsys/mgmt/mcumgr/cb_notifications/testcase.yaml b/tests/subsys/mgmt/mcumgr/cb_notifications/testcase.yaml index 96503b2acea..4208556288b 100644 --- a/tests/subsys/mgmt/mcumgr/cb_notifications/testcase.yaml +++ b/tests/subsys/mgmt/mcumgr/cb_notifications/testcase.yaml @@ -4,7 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 # tests: - cb.notifications: + mgmt.mcumgr.cb.notifications: platform_allow: - qemu_cortex_m3 - native_posix diff --git a/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml b/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml index 20e6b7f4fef..cc7c8888dc7 100644 --- a/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml +++ b/tests/subsys/mgmt/mcumgr/smp_version/testcase.yaml @@ -4,7 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 # tests: - smp.version: + mgmt.mcumgr.smp.version: tags: - smp_version - mcumgr @@ -15,7 +15,7 @@ tests: - posix platform_exclude: - qemu_kvm_arm64 - smp.version_no_legacy: + mgmt.mcumgr.smp.version_no_legacy: tags: - smp_version - mcumgr From 4dabea6f67b793dc7ec04ed311767a34fb83cbb0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 17:05:01 +0000 Subject: [PATCH 1889/4498] tests: settings: fix test meta data and components Fix meta data and standarize components in test identifiers. Signed-off-by: Anas Nashif --- tests/subsys/settings/fcb/testcase.yaml | 6 ++++-- tests/subsys/settings/fcb_init/testcase.yaml | 6 ++++-- tests/subsys/settings/file/testcase.yaml | 7 ++++--- .../settings/functional/fcb/testcase.yaml | 12 ++++++++---- .../settings/functional/file/testcase.yaml | 6 ++++-- .../settings/functional/nvs/testcase.yaml | 18 ++++++++++++------ tests/subsys/settings/nvs/testcase.yaml | 6 ++++-- 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/tests/subsys/settings/fcb/testcase.yaml b/tests/subsys/settings/fcb/testcase.yaml index 15d286e565d..dd000db1c09 100644 --- a/tests/subsys/settings/fcb/testcase.yaml +++ b/tests/subsys/settings/fcb/testcase.yaml @@ -1,5 +1,5 @@ tests: - system.settings.fcb.raw: + settings.fcb.raw: platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 @@ -9,4 +9,6 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - native_posix - tags: settings_fcb + tags: + - settings + - fcb diff --git a/tests/subsys/settings/fcb_init/testcase.yaml b/tests/subsys/settings/fcb_init/testcase.yaml index 5db96cf101b..fd0d0209c71 100644 --- a/tests/subsys/settings/fcb_init/testcase.yaml +++ b/tests/subsys/settings/fcb_init/testcase.yaml @@ -1,8 +1,10 @@ tests: - system.settings.fcb: + settings.fcb: platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 integration_platforms: - nrf52840dk_nrf52840 - tags: settings_intialization_fcb + tags: + - settings + - fcb diff --git a/tests/subsys/settings/file/testcase.yaml b/tests/subsys/settings/file/testcase.yaml index 2d1e2635873..68add10790b 100644 --- a/tests/subsys/settings/file/testcase.yaml +++ b/tests/subsys/settings/file/testcase.yaml @@ -2,12 +2,13 @@ # Copyright (c) 2019 Nordic Semiconductor ASA tests: - system.settings.file.raw: + settings.file.raw: platform_allow: - nrf52840dk_nrf52840 - native_posix - native_posix_64 - mr_canhubk3 tags: - - settings_file - - settings_file_littlefs + - settings + - file + - littlefs diff --git a/tests/subsys/settings/functional/fcb/testcase.yaml b/tests/subsys/settings/functional/fcb/testcase.yaml index 5d02f3c701b..fb484e210b1 100644 --- a/tests/subsys/settings/functional/fcb/testcase.yaml +++ b/tests/subsys/settings/functional/fcb/testcase.yaml @@ -1,5 +1,5 @@ tests: - system.settings.functional.fcb: + settings.functional.fcb: platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 @@ -8,8 +8,10 @@ tests: - mr_canhubk3 integration_platforms: - nrf52840dk_nrf52840 - tags: settings_fcb - system.settings.functional.fcb.chosen: + tags: + - settings + - fcb + settings.functional.fcb.chosen: extra_args: DTC_OVERLAY_FILE=./chosen.overlay platform_allow: - native_posix @@ -17,4 +19,6 @@ tests: - mr_canhubk3 integration_platforms: - native_posix - tags: settings_fcb + tags: + - settings + - fcb diff --git a/tests/subsys/settings/functional/file/testcase.yaml b/tests/subsys/settings/functional/file/testcase.yaml index 49c3e4c32af..7a28a2f41bc 100644 --- a/tests/subsys/settings/functional/file/testcase.yaml +++ b/tests/subsys/settings/functional/file/testcase.yaml @@ -1,5 +1,5 @@ tests: - system.settings.file: + settings.file: platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 @@ -8,4 +8,6 @@ tests: - mr_canhubk3 integration_platforms: - native_posix - tags: settings_file + tags: + - settings + - file diff --git a/tests/subsys/settings/functional/nvs/testcase.yaml b/tests/subsys/settings/functional/nvs/testcase.yaml index 94ec6ffa082..6f2be71a86f 100644 --- a/tests/subsys/settings/functional/nvs/testcase.yaml +++ b/tests/subsys/settings/functional/nvs/testcase.yaml @@ -1,21 +1,27 @@ tests: - system.settings.functional.nvs: + settings.functional.nvs: platform_allow: - qemu_x86 - native_posix - native_posix_64 - tags: settings_nvs - system.settings.functional.nvs.chosen: + tags: + - settings + - nvs + settings.functional.nvs.chosen: extra_args: DTC_OVERLAY_FILE=./chosen.overlay platform_allow: - native_posix - native_posix_64 - tags: settings_nvs - system.settings.functional.nvs.dk: + tags: + - settings + - nvs + settings.functional.nvs.dk: extra_args: OVERLAY_CONFIG=mpu.conf platform_allow: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 integration_platforms: - nrf52840dk_nrf52840 - tags: settings_nvs + tags: + - settings + - nvs diff --git a/tests/subsys/settings/nvs/testcase.yaml b/tests/subsys/settings/nvs/testcase.yaml index fa1673a8307..c78bd712826 100644 --- a/tests/subsys/settings/nvs/testcase.yaml +++ b/tests/subsys/settings/nvs/testcase.yaml @@ -1,5 +1,7 @@ tests: - system.settings.nvs: + settings.nvs: depends_on: nvs min_ram: 32 - tags: settings_nvs + tags: + - settings + - nvs From a2ed99687ba0ecf3796a2d73bf0fa9f957eddd13 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 17:41:22 +0000 Subject: [PATCH 1890/4498] tests: group all build system tests under build_system Consistent naming of components related to build system. Signed-off-by: Anas Nashif --- tests/cmake/config_dir/testcase.yaml | 2 +- tests/cmake/overlays/var_expansions/testcase.yaml | 6 +++--- tests/cmake/snippets/testcase.yaml | 10 +++++----- tests/cmake/zephyr_get/testcase.yaml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/cmake/config_dir/testcase.yaml b/tests/cmake/config_dir/testcase.yaml index 86bbfd786d8..16105025664 100644 --- a/tests/cmake/config_dir/testcase.yaml +++ b/tests/cmake/config_dir/testcase.yaml @@ -1,5 +1,5 @@ tests: - cmake.config_dir.user_defined: + buildsystem.config_dir.user_defined: platform_allow: native_posix build_only: true extra_args: APPLICATION_CONFIG_DIR:PATH=foo diff --git a/tests/cmake/overlays/var_expansions/testcase.yaml b/tests/cmake/overlays/var_expansions/testcase.yaml index 9aff9128526..1149a7f7c28 100644 --- a/tests/cmake/overlays/var_expansions/testcase.yaml +++ b/tests/cmake/overlays/var_expansions/testcase.yaml @@ -3,16 +3,16 @@ common: build_only: true platform_allow: native_posix tests: - cmake.overlays.var_expansions.CONF_FILE: + buildsystem.overlays.var_expansions.CONF_FILE: extra_conf_files: - ${ZEPHYR_MY_MODULE_NAME_MODULE_DIR}/zephyr/my_module-overlay.conf - ${ZEPHYR_MY_EXTRA_MODULE_NAME_MODULE_DIR}/zephyr/my_extra_module-overlay.conf - prj.conf - cmake.overlays.var_expansions.OVERLAY_CONFIG: + buildsystem.overlays.var_expansions.OVERLAY_CONFIG: extra_overlay_confs: - ${ZEPHYR_MY_MODULE_NAME_MODULE_DIR}/zephyr/my_module-overlay.conf - ${ZEPHYR_MY_EXTRA_MODULE_NAME_MODULE_DIR}/zephyr/my_extra_module-overlay.conf - cmake.overlays.var_expansions.DTC_OVERLAY_FILE: + buildsystem.overlays.var_expansions.DTC_OVERLAY_FILE: extra_dtc_overlay_files: - ${ZEPHYR_MY_MODULE_NAME_MODULE_DIR}/zephyr/my_module-board.overlay - ${ZEPHYR_MY_EXTRA_MODULE_NAME_MODULE_DIR}/zephyr/my_extra_module-board.overlay diff --git a/tests/cmake/snippets/testcase.yaml b/tests/cmake/snippets/testcase.yaml index 08eaee0fc16..c8dad26a94f 100644 --- a/tests/cmake/snippets/testcase.yaml +++ b/tests/cmake/snippets/testcase.yaml @@ -10,26 +10,26 @@ common: tests: # Test the initial state with no snippets applied - cmake.snippets.none: + buildsystem.snippets.none: extra_configs: - CONFIG_TEST_TYPE_NONE=y # Test the `foo` snippet from the default application snippet root - cmake.snippets.foo: + buildsystem.snippets.foo: extra_args: SNIPPET="foo" extra_configs: - CONFIG_TEST_TYPE_FOO=y # Test the `bar` snippet from an extra snippet root - cmake.snippets.bar: + buildsystem.snippets.bar: extra_args: SNIPPET="bar" extra_configs: - CONFIG_TEST_TYPE_BAR=y # Test the snippet processing order (1. foo, 2. bar) - cmake.snippets.foo_bar: + buildsystem.snippets.foo_bar: extra_args: SNIPPET="foo;bar" extra_configs: - CONFIG_TEST_TYPE_FOO_BAR=y # Test the snippet processing order (1. bar, 2. foo) - cmake.snippets.bar_foo: + buildsystem.snippets.bar_foo: extra_args: SNIPPET="bar;foo" extra_configs: - CONFIG_TEST_TYPE_BAR_FOO=y diff --git a/tests/cmake/zephyr_get/testcase.yaml b/tests/cmake/zephyr_get/testcase.yaml index 901b9200798..5159efb093c 100644 --- a/tests/cmake/zephyr_get/testcase.yaml +++ b/tests/cmake/zephyr_get/testcase.yaml @@ -3,9 +3,9 @@ common: build_only: true platform_allow: native_posix tests: - zephyr_get.no_sysbuild: + buildsystem.extensions.zephyr_get.no_sysbuild: sysbuild: false - zephyr_get.sysbuild: + buildsystem.extensions.zephyr_get.sysbuild: sysbuild: true extra_args: TESTCASE_VARIABLE="sysbuild.main" zephyr_get_2nd_TESTCASE_VARIABLE="sysbuild.2nd" From b1ee8b248ae928e256d54c46c914342b647d8c96 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 17:54:20 +0000 Subject: [PATCH 1891/4498] tests: logging: group logging testing and cleanup identifiers Better group for logging tests removing verbosity and redundancy in identifiers and making the sub-component a bit more uniform and clear. Signed-off-by: Anas Nashif --- tests/subsys/logging/log_api/testcase.yaml | 126 +++++++++--------- .../logging/log_backend_fs/testcase.yaml | 10 +- .../logging/log_backend_init/testcase.yaml | 2 +- .../logging/log_benchmark/testcase.yaml | 6 +- tests/subsys/logging/log_cache/testcase.yaml | 2 +- .../logging/log_core_additional/testcase.yaml | 6 +- .../logging/log_immediate/testcase.yaml | 4 +- tests/subsys/logging/log_msg/testcase.yaml | 10 +- tests/subsys/logging/log_output/testcase.yaml | 6 +- tests/subsys/logging/log_stack/testcase.yaml | 16 +-- tests/subsys/logging/log_stress/testcase.yaml | 6 +- .../logging/log_switch_format/testcase.yaml | 6 +- tests/subsys/logging/log_syst/testcase.yaml | 4 +- .../logging/log_timestamp/testcase.yaml | 4 +- 14 files changed, 104 insertions(+), 104 deletions(-) diff --git a/tests/subsys/logging/log_api/testcase.yaml b/tests/subsys/logging/log_api/testcase.yaml index 36727d8d346..2b389d01073 100644 --- a/tests/subsys/logging/log_api/testcase.yaml +++ b/tests/subsys/logging/log_api/testcase.yaml @@ -12,28 +12,28 @@ common: - native_posix min_ram: 32 tests: - logging.log_api_deferred_overflow_rt_filter: + logging.deferred.api.overflow_rt_filter: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - CONFIG_LOG_RUNTIME_FILTERING=y - logging.log_api_deferred_overflow: + logging.deferred.api.overflow: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - logging.log_api_deferred_no_overflow: + logging.deferred.api.no_overflow: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=n - logging.log_api_deferred_static_filter: + logging.deferred.api.static_filter: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - logging.log_api_deferred_printk: + logging.deferred.api.printk: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y @@ -41,18 +41,18 @@ tests: # When LOG_PRINTK is enabled, thread must process otherwise test output would be lost. - CONFIG_LOG_PROCESS_THREAD=y - logging.log_api_deferred_func_prefix: + logging.deferred.api.func_prefix: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y - logging.log_api_deferred_64b_timestamp: + logging.deferred.api.64b_timestamp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_TIMESTAMP_64BIT=y - logging.log_api_deferred_override_level: + logging.deferred.api.override_level: # Testing on selected platforms as it enables all logs in the application # and it cannot be handled on many platforms. platform_allow: @@ -63,47 +63,47 @@ tests: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_OVERRIDE_LEVEL=4 - logging.log_api_immediate: + logging.immediate.api: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - logging.log_api_immediate_printk: + logging.immediate.api.printk: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_PRINTK=y - logging.log_api_immediate_rt_filter: + logging.immediate.api.rt_filter: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_RUNTIME_FILTERING=y - logging.log_api_immediate_static_filter: + logging.immediate.api.static_filter: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - logging.log_api_immediate_64b_timestamp: + logging.immediate.api.64b_timestamp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_TIMESTAMP_64BIT=y - logging.log_api_frontend_dbg: + logging.frontend.dbg: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - logging.log_api_frontend: + logging.frontend: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_DEFERRED=y - logging.log_api_frontend_immediate: + logging.frontend.immediate: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_IMMEDIATE=y - logging.log_api_frontend_immediate_override_level: + logging.frontend.immediate_override_level: # Testing on selected platforms as it enables all logs in the application # and it cannot be handled on many platforms. platform_allow: @@ -115,7 +115,7 @@ tests: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_OVERRIDE_LEVEL=4 - logging.log_api_deferred_override_level_rt_filtering: + logging.deferred.api.override_level_rt_filtering: # Testing on selected platforms as it enables all logs in the application # and it cannot be handled on many platforms. platform_allow: @@ -127,12 +127,12 @@ tests: - CONFIG_LOG_RUNTIME_FILTERING=y - CONFIG_LOG_OVERRIDE_LEVEL=4 - logging.log_api_frontend_only: + logging.frontend.only: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_FRONTEND_ONLY=y - logging.log_api_frontend_no_backends: + logging.frontend.no_backends: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_FRONTEND_ONLY=y @@ -142,32 +142,32 @@ tests: - CONFIG_LOG_BACKEND_XTENSA_SIM=n extra_args: EXTRA_CPPFLAGS=-DNO_BACKENDS=1 - logging.log_api_deferred_overflow_rt_filter_cpp: + logging.deferred.api.overflow_rt_filter_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - CONFIG_LOG_RUNTIME_FILTERING=y - CONFIG_CPP=y - logging.log_api_deferred_overflow_cpp: + logging.deferred.api.overflow_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - CONFIG_CPP=y - logging.log_api_deferred_no_overflow_cpp: + logging.deferred.api.no_overflowcpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=n - CONFIG_CPP=y - logging.log_api_deferred_static_filter_cpp: + logging.deferred.api.static_filter_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_CPP=y - logging.log_api_deferred_printk_cpp: + logging.deferred.api.printk_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y @@ -176,74 +176,74 @@ tests: - CONFIG_LOG_PROCESS_THREAD=y - CONFIG_CPP=y - logging.log_api_deferred_func_prefix_cpp: + logging.deferred.api.func_prefix_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y - CONFIG_CPP=y - logging.log_api_deferred_64b_timestamp_cpp: + logging.deferred.api.64b_timestamp_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_TIMESTAMP_64BIT=y - CONFIG_CPP=y - logging.log_api_immediate_cpp: + logging.immediate.api.cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_CPP=y - logging.log_api_immediate_printk_cpp: + logging.immediate.api.printk_cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_PRINTK=y - CONFIG_CPP=y - logging.log_api_immediate_rt_filter_cpp: + logging.immediate.api.rt_filter_cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_RUNTIME_FILTERING=y - CONFIG_CPP=y - logging.log_api_immediate_static_filter_cpp: + logging.immediate.api.static_filter_cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_CPP=y - logging.log_api_immediate_64b_timestamp_cpp: + logging.immediate.api.64b_timestamp_cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_TIMESTAMP_64BIT=y - CONFIG_CPP=y - logging.log_api_frontend_dbg_cpp: + logging.frontend.dbg_cpp: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_CPP=y - logging.log_api_frontend_cpp: + logging.frontend.cpp: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_CPP=y - logging.log_api_frontend_immediate_cpp: + logging.frontend.immediate_cpp: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_CPP=y - logging.log_api_frontend_only_cpp: + logging.frontend.only_cpp: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_FRONTEND_ONLY=y - CONFIG_CPP=y - logging.log_api_frontend_no_backends_cpp: + logging.frontend.no_backends_cpp: extra_configs: - CONFIG_LOG_FRONTEND=y - CONFIG_LOG_FRONTEND_ONLY=y @@ -254,7 +254,7 @@ tests: - CONFIG_CPP=y extra_args: EXTRA_CPPFLAGS=-DNO_BACKENDS=1 - logging.log_api_deferred_overflow_rt_filter.tagged_args: + logging.deferred.api.overflow_rt_filter.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -262,28 +262,28 @@ tests: - CONFIG_LOG_RUNTIME_FILTERING=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_overflow.tagged_args: + logging.deferred.api.overflow.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_no_overflow.tagged_args: + logging.deferred.api.no_overflowtagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=n - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_static_filter.tagged_args: + logging.deferred.api.static_filter.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_printk.tagged_args: + logging.deferred.api.printk.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -293,7 +293,7 @@ tests: - CONFIG_LOG_PROCESS_THREAD=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_func_prefix.tagged_args: + logging.deferred.api.func_prefix.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -301,14 +301,14 @@ tests: - CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_64b_timestamp.tagged_args: + logging.deferred.api.64b_timestamp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_TIMESTAMP_64BIT=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_override_level.tagged_args: + logging.deferred.api.override_level.tagged_args: # Testing on selected platforms as it enables all logs in the application # and it cannot be handled on many platforms. platform_allow: @@ -321,7 +321,7 @@ tests: - CONFIG_LOG_OVERRIDE_LEVEL=4 - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_override_level_rt_filtering.tagged_args: + logging.deferred.api.override_level_rt_filtering.tagged_args: # Testing on selected platforms as it enables all logs in the application # and it cannot be handled on many platforms. platform_allow: @@ -335,41 +335,41 @@ tests: - CONFIG_LOG_OVERRIDE_LEVEL=4 - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate.tagged_args: + logging.immediate.api.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_printk.tagged_args: + logging.immediate.api.printk.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_PRINTK=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_rt_filter.tagged_args: + logging.immediate.api.rt_filter.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_RUNTIME_FILTERING=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_static_filter.tagged_args: + logging.immediate.api.static_filter.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_SAMPLE_MODULE_LOG_LEVEL_DBG=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_64b_timestamp.tagged_args: + logging.immediate.api.64b_timestamp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_LOG_TIMESTAMP_64BIT=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_overflow_rt_filter_cpp.tagged_args: + logging.deferred.api.overflow_rt_filter_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -378,7 +378,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_overflow_cpp.tagged_args: + logging.deferred.api.overflow_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -386,7 +386,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_no_overflow_cpp.tagged_args: + logging.deferred.api.no_overflowcpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -394,7 +394,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_static_filter_cpp.tagged_args: + logging.deferred.api.static_filter_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -402,7 +402,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_printk_cpp.tagged_args: + logging.deferred.api.printk_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -413,7 +413,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_func_prefix_cpp.tagged_args: + logging.deferred.api.func_prefix_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -422,7 +422,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_deferred_64b_timestamp_cpp.tagged_args: + logging.deferred.api.64b_timestamp_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_DEFERRED=y @@ -430,14 +430,14 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_cpp.tagged_args: + logging.immediate.api.cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_printk_cpp.tagged_args: + logging.immediate.api.printk_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y @@ -445,7 +445,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_rt_filter_cpp.tagged_args: + logging.immediate.api.rt_filter_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y @@ -453,7 +453,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_static_filter_cpp.tagged_args: + logging.immediate.api.static_filter_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y @@ -461,7 +461,7 @@ tests: - CONFIG_CPP=y - CONFIG_LOG_USE_TAGGED_ARGUMENTS=y - logging.log_api_immediate_64b_timestamp_cpp.tagged_args: + logging.immediate.api.64b_timestamp_cpp.tagged_args: toolchain_exclude: xcc extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y diff --git a/tests/subsys/logging/log_backend_fs/testcase.yaml b/tests/subsys/logging/log_backend_fs/testcase.yaml index 99213286cb2..f372776f10f 100644 --- a/tests/subsys/logging/log_backend_fs/testcase.yaml +++ b/tests/subsys/logging/log_backend_fs/testcase.yaml @@ -8,7 +8,7 @@ common: - fs - littlefs tests: - logging.log_backend_fs.automounted: + logging.backend.fs.automounted: platform_allow: - native_posix - native_posix_64 @@ -16,21 +16,21 @@ tests: - mr_canhubk3 integration_platforms: - native_posix - logging.log_backend_fs.manualmounted.native_posix: + logging.backend.fs.manualmounted.native_posix: platform_allow: native_posix extra_args: DTC_OVERLAY_FILE="./boards/native_posix.overlay;./boards/automount.overlay" integration_platforms: - native_posix - logging.log_backend_fs.manualmounted.native_posix_64: + logging.backend.fs.manualmounted.native_posix_64: platform_allow: native_posix_64 extra_args: DTC_OVERLAY_FILE="./boards/native_posix_64.overlay;./boards/automount.overlay" integration_platforms: - native_posix_64 - logging.log_backend_fs.manualmounted.nrf5840dk: + logging.backend.fs.manualmounted.nrf5840dk: platform_allow: nrf52840dk_nrf52840 extra_args: DTC_OVERLAY_FILE="./boards/nrf52840dk_nrf52840.overlay;./boards/automount.overlay" integration_platforms: - nrf52840dk_nrf52840 - logging.log_backend_fs.manualmounted.mr_canhubk3: + logging.backend.fs.manualmounted.mr_canhubk3: platform_allow: mr_canhubk3 extra_args: DTC_OVERLAY_FILE="./boards/mr_canhubk3.overlay;./boards/automount.overlay" diff --git a/tests/subsys/logging/log_backend_init/testcase.yaml b/tests/subsys/logging/log_backend_init/testcase.yaml index a8f9144f7ec..b9d7c79dcd1 100644 --- a/tests/subsys/logging/log_backend_init/testcase.yaml +++ b/tests/subsys/logging/log_backend_init/testcase.yaml @@ -1,5 +1,5 @@ tests: - logging.log_backend_initialization: + logging.backend.initialization: integration_platforms: - qemu_x86 tags: diff --git a/tests/subsys/logging/log_benchmark/testcase.yaml b/tests/subsys/logging/log_benchmark/testcase.yaml index b11171bb0ea..bbb2a66826f 100644 --- a/tests/subsys/logging/log_benchmark/testcase.yaml +++ b/tests/subsys/logging/log_benchmark/testcase.yaml @@ -1,5 +1,5 @@ tests: - logging.log_benchmark: + logging.benchmark: integration_platforms: - native_posix tags: logging @@ -7,7 +7,7 @@ tests: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_CBPRINTF_COMPLETE=y - logging.log_benchmark_speed: + logging.benchmark_speed: integration_platforms: - native_posix tags: logging @@ -16,7 +16,7 @@ tests: - CONFIG_CBPRINTF_COMPLETE=y - CONFIG_LOG_SPEED=y - logging.log_benchmark_user: + logging.benchmark_user: integration_platforms: - native_posix tags: logging diff --git a/tests/subsys/logging/log_cache/testcase.yaml b/tests/subsys/logging/log_cache/testcase.yaml index 4d14cc1de1e..65aa2fa388e 100644 --- a/tests/subsys/logging/log_cache/testcase.yaml +++ b/tests/subsys/logging/log_cache/testcase.yaml @@ -3,7 +3,7 @@ common: - native_posix tests: - logging.log_cache: + logging.cache: tags: - log_cache - logging diff --git a/tests/subsys/logging/log_core_additional/testcase.yaml b/tests/subsys/logging/log_core_additional/testcase.yaml index a4919fc8ad6..7fc508440ee 100644 --- a/tests/subsys/logging/log_core_additional/testcase.yaml +++ b/tests/subsys/logging/log_core_additional/testcase.yaml @@ -1,15 +1,15 @@ tests: - logging.add.async: + logging.async: tags: logging extra_args: CONF_FILE=prj.conf integration_platforms: - native_posix - logging.add.sync: + logging.sync: tags: logging extra_args: CONF_FILE=log_sync.conf integration_platforms: - native_posix - logging.add.log_user: + logging.log_user: tags: logging filter: CONFIG_USERSPACE extra_args: diff --git a/tests/subsys/logging/log_immediate/testcase.yaml b/tests/subsys/logging/log_immediate/testcase.yaml index 676b283149f..dd63de3c17f 100644 --- a/tests/subsys/logging/log_immediate/testcase.yaml +++ b/tests/subsys/logging/log_immediate/testcase.yaml @@ -3,7 +3,7 @@ common: - native_posix tests: - logging.log_immediate: + logging.immediate: tags: - log_core - logging @@ -13,7 +13,7 @@ tests: - nucleo_f030r8 - stm32f0_disco - nrf52_bsim - logging.log_immediate.clean_output: + logging.immediate.clean_output: extra_args: CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT=y tags: - log_core diff --git a/tests/subsys/logging/log_msg/testcase.yaml b/tests/subsys/logging/log_msg/testcase.yaml index 6ab444d6592..543eb046630 100644 --- a/tests/subsys/logging/log_msg/testcase.yaml +++ b/tests/subsys/logging/log_msg/testcase.yaml @@ -9,25 +9,25 @@ common: - native_posix filter: not CONFIG_LOG_ALWAYS_RUNTIME tests: - logging.log_msg: + logging.message: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y - logging.log_msg_no_overflow: + logging.message.no_overflow: extra_configs: - CONFIG_LOG_MODE_OVERFLOW=n - logging.log_msg_64b_timestamp: + logging.message.64b_timestamp: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y - CONFIG_LOG_TIMESTAMP_64BIT=y - logging.log_msg_fp: + logging.message.fp: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y - CONFIG_CBPRINTF_FP_SUPPORT=y - logging.log_msg_fp_64b_timestamp: + logging.message.fp_64b_timestamp: extra_configs: - CONFIG_CBPRINTF_COMPLETE=y - CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/tests/subsys/logging/log_output/testcase.yaml b/tests/subsys/logging/log_output/testcase.yaml index 66b8f675089..cb265420276 100644 --- a/tests/subsys/logging/log_output/testcase.yaml +++ b/tests/subsys/logging/log_output/testcase.yaml @@ -3,19 +3,19 @@ common: - native_posix tests: - logging.log_output: + logging.output: tags: - log_output - logging extra_configs: - CONFIG_LOG_TIMESTAMP_64BIT=n - logging.log_output_ts64: + logging.output.ts64: tags: - log_output - logging extra_configs: - CONFIG_LOG_TIMESTAMP_64BIT=y - logging.log_output.thread_id: + logging.output.thread_id: tags: - log_output - logging diff --git a/tests/subsys/logging/log_stack/testcase.yaml b/tests/subsys/logging/log_stack/testcase.yaml index 25ead504276..92534b65ab0 100644 --- a/tests/subsys/logging/log_stack/testcase.yaml +++ b/tests/subsys/logging/log_stack/testcase.yaml @@ -8,42 +8,42 @@ common: integration_platforms: - qemu_x86 tests: - logging.log_stack_deferred: + logging.stack.deferred: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - logging.log_stack_deferred_no_opt: + logging.stack.deferred_no_opt: filter: not CONFIG_MIPS extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_NO_OPTIMIZATIONS=y - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_IDLE_STACK_SIZE=2048 - logging.log_stack_immediate: + logging.stack.immediate: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - logging.log_stack_immediate_no_opt: + logging.stack.immediate_no_opt: filter: not CONFIG_MIPS extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_NO_OPTIMIZATIONS=y - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_IDLE_STACK_SIZE=2048 - logging.log_stack_deferred_cpp: + logging.stack.deferred_cpp: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_CPP=y - logging.log_stack_deferred_cpp_no_opt: + logging.stack.deferred_cpp_no_opt: filter: not CONFIG_MIPS extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_NO_OPTIMIZATIONS=y - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_CPP=y - logging.log_stack_immediate_cpp: + logging.stack.immediate_cpp: extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y - CONFIG_CPP=y - logging.log_stack_immediate_cpp_no_opt: + logging.stack.immediate_cpp_no_opt: filter: not CONFIG_MIPS extra_configs: - CONFIG_LOG_MODE_IMMEDIATE=y diff --git a/tests/subsys/logging/log_stress/testcase.yaml b/tests/subsys/logging/log_stress/testcase.yaml index bc074dbc5b0..3f6843760a8 100644 --- a/tests/subsys/logging/log_stress/testcase.yaml +++ b/tests/subsys/logging/log_stress/testcase.yaml @@ -6,11 +6,11 @@ common: integration_platforms: - qemu_x86 tests: - logging.log_stress_light: + logging.stress.light: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=y - logging.log_stress_light_no_overflow: + logging.stress.light_no_overflow: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=n @@ -23,7 +23,7 @@ tests: - qemu_x86 - qemu_cortex_a9 - qemu_x86_64 - logging.log_stress_no_overflow: + logging.stress.no_overflow: extra_configs: - CONFIG_LOG_MODE_DEFERRED=y - CONFIG_LOG_MODE_OVERFLOW=n diff --git a/tests/subsys/logging/log_switch_format/testcase.yaml b/tests/subsys/logging/log_switch_format/testcase.yaml index bd0e3a4a0e1..911c8e2c178 100644 --- a/tests/subsys/logging/log_switch_format/testcase.yaml +++ b/tests/subsys/logging/log_switch_format/testcase.yaml @@ -11,7 +11,7 @@ common: - sparc filter: not CONFIG_64BIT tests: - logging.log_switch_format.deferred: + logging.format.switch.deferred: integration_platforms: - mps2_an385 - qemu_x86 @@ -25,7 +25,7 @@ tests: filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_REQUIRES_FULL_LIBC=y - logging.log_switch_format.immediate: + logging.format.switch.immediate: extra_args: OVERLAY_CONFIG=overlay_immediate.conf integration_platforms: - mps2_an385 @@ -33,7 +33,7 @@ tests: filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_REQUIRES_FULL_LIBC=y - logging.log_switch_format.custom_output: + logging.format.switch.custom_output: extra_args: OVERLAY_CONFIG=overlay_custom_output.conf integration_platforms: - mps2_an385 diff --git a/tests/subsys/logging/log_syst/testcase.yaml b/tests/subsys/logging/log_syst/testcase.yaml index 18f4a7cc273..db2160b60f0 100644 --- a/tests/subsys/logging/log_syst/testcase.yaml +++ b/tests/subsys/logging/log_syst/testcase.yaml @@ -1,7 +1,7 @@ common: filter: not CONFIG_64BIT tests: - logging.log_syst.mipi_syst: + logging.mipi_syst: tags: - log_syst - logging @@ -25,7 +25,7 @@ tests: - CONFIG_LOG_MIPI_SYST_ENABLE=y - CONFIG_LOG_BACKEND_MOCK_OUTPUT_SYST=y - CONFIG_REQUIRES_FULL_LIBC=y - logging.log_syst.text: + logging.mipi_syst.text: tags: - log_syst - logging diff --git a/tests/subsys/logging/log_timestamp/testcase.yaml b/tests/subsys/logging/log_timestamp/testcase.yaml index 973bb04eb47..6173e67c1d2 100644 --- a/tests/subsys/logging/log_timestamp/testcase.yaml +++ b/tests/subsys/logging/log_timestamp/testcase.yaml @@ -3,12 +3,12 @@ common: - native_posix tests: - logging.log_output_default_timestamp: + logging.output.default_timestamp: tags: - log_output - logging - timestamp - logging.log_output_custom_timestamp: + logging.output.custom_timestamp: tags: - log_output - logging From 8c6a3dbe37abd9b905ac89a375b97a811470dcbd Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 20:56:24 +0000 Subject: [PATCH 1892/4498] tests: mcuboot: fix identifier: boot -> bootloader Be consistent with other tests using bootloader. Signed-off-by: Anas Nashif --- tests/boot/mcuboot_data_sharing/testcase.yaml | 2 +- tests/boot/mcuboot_recovery_retention/testcase.yaml | 4 ++-- tests/boot/test_mcuboot/testcase.yaml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/boot/mcuboot_data_sharing/testcase.yaml b/tests/boot/mcuboot_data_sharing/testcase.yaml index 26eefd39523..b12fb012f4b 100644 --- a/tests/boot/mcuboot_data_sharing/testcase.yaml +++ b/tests/boot/mcuboot_data_sharing/testcase.yaml @@ -6,7 +6,7 @@ common: sysbuild: true tests: - mcuboot.data.sharing: + bootloader.mcuboot.data.sharing: platform_allow: nrf52840dk_nrf52840 tags: - mcuboot diff --git a/tests/boot/mcuboot_recovery_retention/testcase.yaml b/tests/boot/mcuboot_recovery_retention/testcase.yaml index a66c361c1d2..084aedcba58 100644 --- a/tests/boot/mcuboot_recovery_retention/testcase.yaml +++ b/tests/boot/mcuboot_recovery_retention/testcase.yaml @@ -21,13 +21,13 @@ common: - "Secondary image: magic" - "Boot source: none" tests: - mcuboot.recovery.retention: + bootloader.mcuboot.recovery.retention: platform_allow: nrf52840dk_nrf52840 tags: - mcuboot - sysbuild - recovery - mcuboot.recovery.retention.mem: + bootloader.mcuboot.recovery.retention.mem: platform_allow: nrf52840dk_nrf52840 extra_args: - OVERLAY_CONFIG="boards/nrf52840dk_nrf52840_mem.conf" diff --git a/tests/boot/test_mcuboot/testcase.yaml b/tests/boot/test_mcuboot/testcase.yaml index 20f29f0a41b..91b5919759e 100644 --- a/tests/boot/test_mcuboot/testcase.yaml +++ b/tests/boot/test_mcuboot/testcase.yaml @@ -10,7 +10,7 @@ common: - "I: Starting swap using (.*)" - "Swapped application booted on (.*)" tests: - boot.mcuboot: + bootloader.mcuboot: tags: mcuboot skip: true # disabled due to issue #58080 platform_allow: @@ -20,7 +20,7 @@ tests: integration_platforms: - frdm_k64f - nrf52840dk_nrf52840 - boot.mcuboot.assert: + bootloader.mcuboot.assert: tags: mcuboot platform_allow: - b_u585i_iot02a From 8f7180bece64fc972f07db4eab5b29bfeae38846 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 11 Oct 2023 11:05:30 +0200 Subject: [PATCH 1893/4498] cmake: remove clang++ lookup in clang/generic.cmake Fixes: #63771 The 'compiler/*/generic.cmake' is intended to set a C preprocessor which can be used for devicetree preprocessing. No C++ compiler is needed as host tool and should therefore not be set in this file. Remove the code to avoid setting a not required C++ compiler. Signed-off-by: Torsten Rasmussen --- cmake/compiler/clang/generic.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/compiler/clang/generic.cmake b/cmake/compiler/clang/generic.cmake index fa2f5790299..afc8d80766c 100644 --- a/cmake/compiler/clang/generic.cmake +++ b/cmake/compiler/clang/generic.cmake @@ -5,7 +5,6 @@ if(DEFINED TOOLCHAIN_HOME) endif() find_program(CMAKE_C_COMPILER clang ${find_program_clang_args} REQUIRED) -find_program(CMAKE_CXX_COMPILER clang++ ${find_program_clang_args}) find_program(CMAKE_LLVM_COV llvm-cov ${find_program_clang_args}) set(CMAKE_GCOV "${CMAKE_LLVM_COV} gcov") From 6b8b49c64a328e9b71b2544ea781ab4e14774bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Wed, 11 Oct 2023 10:29:34 +0200 Subject: [PATCH 1894/4498] drivers: i2s_nrfx: Fix write race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is inherent race condition between i2s_nrfx_write() and I2S interrupt handler because I2S operates independently from the rest of the system. If software takes too long to supply next TX pointer then nRF I2S peripheral will simply resupply the previous buffer. The race window is rather short. The failed race executes as follows: 1. i2s_nrfx_write() checks state and loads next_tx_buffer_needed 2. I2S interrupt handler executes and calls data_handler() which notices empty TX queue and therefore sets next_tx_buffer_needed 3. i2s_nrfx_write() continues with the queue TX path (because the next_tx_buffer_needed was false when it was accessed) If next i2s_nrfx_write() executes before next I2S interrupt: 4a. i2s_nrfx_write() notices next_tx_buffer_needed is true and supplies the buffer directly to I2S peripheral. Previously queued buffer will remain in the queue until the just supplied buffer starts transmitting. Effectively swapping whole I2S block leads to clearly audible artifacts under normal circumstances. If next I2S interrupt executes before next i2s_nrfx_write(): 4b. data_handler() notices that buffer was reused and stops despite having a buffer available in TX queue Modify i2s_nrfx_write() to always queue the TX pointer first and only supply the buffer to nrfx if the queue was empty when interrupt handler executed. This prevents both the out-of-order TX and premature stop. Fixes: #63730 Signed-off-by: Tomasz Moń --- drivers/i2s/i2s_nrfx.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/i2s/i2s_nrfx.c b/drivers/i2s/i2s_nrfx.c index ea1aed635a6..57910c464ab 100644 --- a/drivers/i2s/i2s_nrfx.c +++ b/drivers/i2s/i2s_nrfx.c @@ -583,6 +583,7 @@ static int i2s_nrfx_write(const struct device *dev, void *mem_block, size_t size) { struct i2s_nrfx_drv_data *drv_data = dev->data; + int ret; if (!drv_data->tx_configured) { LOG_ERR("Device is not configured"); @@ -601,26 +602,41 @@ static int i2s_nrfx_write(const struct device *dev, return -EIO; } + ret = k_msgq_put(&drv_data->tx_queue, + &mem_block, + SYS_TIMEOUT_MS(drv_data->tx.cfg.timeout)); + if (ret < 0) { + return ret; + } + + LOG_DBG("Queued TX %p", mem_block); + + /* Check if interrupt wanted to get next TX buffer before current buffer + * was queued. Do not move this check before queuing because doing so + * opens the possibility for a race condition between this function and + * data_handler() that is called in interrupt context. + */ if (drv_data->state == I2S_STATE_RUNNING && drv_data->next_tx_buffer_needed) { - nrfx_i2s_buffers_t next = { .p_tx_buffer = mem_block }; + nrfx_i2s_buffers_t next = { 0 }; + + if (!get_next_tx_buffer(drv_data, &next)) { + /* Log error because this is definitely unexpected. + * Do not return error because the caller is no longer + * responsible for releasing the buffer. + */ + LOG_ERR("Cannot reacquire queued buffer"); + return 0; + } drv_data->next_tx_buffer_needed = false; - LOG_DBG("Next TX %p", mem_block); + LOG_DBG("Next TX %p", next.p_tx_buffer); if (!supply_next_buffers(drv_data, &next)) { return -EIO; } - } else { - int ret = k_msgq_put(&drv_data->tx_queue, - &mem_block, - SYS_TIMEOUT_MS(drv_data->tx.cfg.timeout)); - if (ret < 0) { - return ret; - } - LOG_DBG("Queued TX %p", mem_block); } return 0; From 1d0f28737baf7e5aa37383972a4b5e30ca43522a Mon Sep 17 00:00:00 2001 From: Cyril Fougeray Date: Thu, 8 Jun 2023 12:09:18 +0200 Subject: [PATCH 1895/4498] sensors: vl53l1: build_all without the default Kconfig in case CONFIG_VL53L1X_INTERRUPT_MODE=n or CONFIG_VL53L1X_XSHUT=n, the driver won't compile Signed-off-by: Cyril Fougeray --- tests/drivers/build_all/sensor/sensors_no_default.conf | 2 ++ tests/drivers/build_all/sensor/testcase.yaml | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 tests/drivers/build_all/sensor/sensors_no_default.conf diff --git a/tests/drivers/build_all/sensor/sensors_no_default.conf b/tests/drivers/build_all/sensor/sensors_no_default.conf new file mode 100644 index 00000000000..ac42f5db80f --- /dev/null +++ b/tests/drivers/build_all/sensor/sensors_no_default.conf @@ -0,0 +1,2 @@ +CONFIG_VL53L1X_INTERRUPT_MODE=n +CONFIG_VL53L1X_XSHUT=n diff --git a/tests/drivers/build_all/sensor/testcase.yaml b/tests/drivers/build_all/sensor/testcase.yaml index bfc423b65f6..1d69f1ae8d0 100644 --- a/tests/drivers/build_all/sensor/testcase.yaml +++ b/tests/drivers/build_all/sensor/testcase.yaml @@ -13,6 +13,8 @@ tests: extra_args: OVERLAY_CONFIG=sensors_trigger_global.conf sensors.build.trigger.none: extra_args: OVERLAY_CONFIG=sensors_trigger_none.conf + sensors.build.no_default: + extra_args: OVERLAY_CONFIG=sensors_no_default.conf sensors.build: tags: sensors sensors.build.pm: From 49126e2aa968c57af2e5270aecc2ce20dd111492 Mon Sep 17 00:00:00 2001 From: Cyril Fougeray Date: Thu, 8 Jun 2023 12:35:23 +0200 Subject: [PATCH 1896/4498] sensors: vl53l1: fix compilation without xshut or interrupt pin Fix compilation when CONFIG_VL53L1X_INTERRUPT_MODE=n or CONFIG_VL53L1X_XSHUT=n Signed-off-by: Cyril Fougeray --- drivers/sensor/vl53l1x/vl53l1.c | 76 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/drivers/sensor/vl53l1x/vl53l1.c b/drivers/sensor/vl53l1x/vl53l1.c index 714007a1a71..35187423342 100644 --- a/drivers/sensor/vl53l1x/vl53l1.c +++ b/drivers/sensor/vl53l1x/vl53l1.c @@ -65,59 +65,56 @@ static VL53L1_Error vl53l1x_read_sensor(struct vl53l1x_data *drv_data) return VL53L1_ERROR_NONE; } +#ifdef CONFIG_VL53L1X_INTERRUPT_MODE static void vl53l1x_worker(struct k_work *work) { - if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { - struct vl53l1x_data *drv_data = CONTAINER_OF(work, struct vl53l1x_data, work); + struct vl53l1x_data *drv_data = CONTAINER_OF(work, struct vl53l1x_data, work); - vl53l1x_read_sensor(drv_data); - } + vl53l1x_read_sensor(drv_data); } static void vl53l1x_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { - if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { - struct vl53l1x_data *drv_data = CONTAINER_OF(cb, struct vl53l1x_data, gpio_cb); + struct vl53l1x_data *drv_data = CONTAINER_OF(cb, struct vl53l1x_data, gpio_cb); - k_work_submit(&drv_data->work); - } + k_work_submit(&drv_data->work); } static int vl53l1x_init_interrupt(const struct device *dev) { - if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { - struct vl53l1x_data *drv_data = dev->data; - const struct vl53l1x_config *config = dev->config; - int ret; - - drv_data->dev = dev; + struct vl53l1x_data *drv_data = dev->data; + const struct vl53l1x_config *config = dev->config; + int ret; - if (!gpio_is_ready_dt(&config->gpio1)) { - LOG_ERR("%s: device %s is not ready", dev->name, config->gpio1.port->name); - return -ENODEV; - } + drv_data->dev = dev; - ret = gpio_pin_configure_dt(&config->gpio1, GPIO_INPUT | GPIO_PULL_UP); - if (ret < 0) { - LOG_ERR("[%s] Unable to configure GPIO interrupt", dev->name); - return -EIO; - } + if (!gpio_is_ready_dt(&config->gpio1)) { + LOG_ERR("%s: device %s is not ready", dev->name, config->gpio1.port->name); + return -ENODEV; + } - gpio_init_callback(&drv_data->gpio_cb, - vl53l1x_gpio_callback, - BIT(config->gpio1.pin)); + ret = gpio_pin_configure_dt(&config->gpio1, GPIO_INPUT | GPIO_PULL_UP); + if (ret < 0) { + LOG_ERR("[%s] Unable to configure GPIO interrupt", dev->name); + return -EIO; + } - ret = gpio_add_callback(config->gpio1.port, &drv_data->gpio_cb); - if (ret < 0) { - LOG_ERR("Failed to set gpio callback!"); - return -EIO; - } + gpio_init_callback(&drv_data->gpio_cb, + vl53l1x_gpio_callback, + BIT(config->gpio1.pin)); - drv_data->work.handler = vl53l1x_worker; + ret = gpio_add_callback(config->gpio1.port, &drv_data->gpio_cb); + if (ret < 0) { + LOG_ERR("Failed to set gpio callback!"); + return -EIO; } + + drv_data->work.handler = vl53l1x_worker; + return 0; } +#endif static int vl53l1x_initialize(const struct device *dev) { @@ -304,7 +301,6 @@ static int vl53l1x_sample_fetch(const struct device *dev, enum sensor_channel chan) { struct vl53l1x_data *drv_data = dev->data; - const struct vl53l1x_config *config = dev->config; VL53L1_Error ret; __ASSERT_NO_MSG((chan == SENSOR_CHAN_ALL) @@ -317,13 +313,15 @@ static int vl53l1x_sample_fetch(const struct device *dev, return -EBUSY; } - if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { - ret = gpio_pin_interrupt_configure_dt(&config->gpio1, GPIO_INT_EDGE_TO_INACTIVE); - if (ret < 0) { - LOG_ERR("[%s] Unable to config interrupt", dev->name); - return -EIO; - } +#ifdef CONFIG_VL53L1X_INTERRUPT_MODE + const struct vl53l1x_config *config = dev->config; + + ret = gpio_pin_interrupt_configure_dt(&config->gpio1, GPIO_INT_EDGE_TO_INACTIVE); + if (ret < 0) { + LOG_ERR("[%s] Unable to config interrupt", dev->name); + return -EIO; } +#endif ret = VL53L1_StartMeasurement(&drv_data->vl53l1x); if (ret != VL53L1_ERROR_NONE) { From 3ee0f305b0890745b68cdad6fb240d2f68e4c47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 11 Oct 2023 13:24:04 +0200 Subject: [PATCH 1897/4498] dts: bindings: fix typo in iSentek spelling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a typo in the spelling of the sensor's manufacturer. Signed-off-by: Benjamin Cabé --- dts/bindings/sensor/istentek,ist8310.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/bindings/sensor/istentek,ist8310.yaml b/dts/bindings/sensor/istentek,ist8310.yaml index a31821aa5e8..761278d24bb 100644 --- a/dts/bindings/sensor/istentek,ist8310.yaml +++ b/dts/bindings/sensor/istentek,ist8310.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Istentek ist8310 Geomagnetic sensor. See more info at: + iSentek ist8310 Geomagnetic sensor. See more info at: https://isentek.com/products_view.php?PID=10&sn=13 compatible: "isentek,ist8310" From 45c369f4196aa19716ad57d622b50d753623eab5 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 9 Oct 2023 10:48:50 +0200 Subject: [PATCH 1898/4498] sysbuild: Support SB_CONF_FILE and SB_EXTRA_CONF_FILE as lists These variables need to be converted to absolute paths internally, but so far this has only worked when each value consisted of a single path. Add a common loop to handle lists of paths. As a bonus, run `string(CONFIGURE)` to expand those variables in the same way as the regular CONF_FILE and EXTRA_CONF_FILE. Signed-off-by: Grzegorz Swiderski --- .../cmake/modules/sysbuild_kconfig.cmake | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake index 830ad326fd2..12ab32e55c2 100644 --- a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -24,22 +24,23 @@ else() # SYSBuild dedicated configuration file. endif() -if(DEFINED SB_CONF_FILE AND NOT IS_ABSOLUTE SB_CONF_FILE) - cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR}) -endif() - -if(DEFINED SB_OVERLAY_CONFIG AND NOT IS_ABSOLUTE SB_OVERLAY_CONFIG) - cmake_path(ABSOLUTE_PATH SB_OVERLAY_CONFIG BASE_DIRECTORY ${APP_DIR}) -endif() - -if(DEFINED SB_EXTRA_CONF_FILE AND NOT IS_ABSOLUTE SB_EXTRA_CONF_FILE) - cmake_path(ABSOLUTE_PATH SB_EXTRA_CONF_FILE BASE_DIRECTORY ${APP_DIR}) -endif() - if(NOT DEFINED SB_EXTRA_CONF_FILE AND DEFINED SB_OVERLAY_CONFIG) set(SB_EXTRA_CONF_FILE ${SB_OVERLAY_CONFIG}) endif() +# Let SB_CONF_FILE and SB_EXTRA_CONF_FILE be relative to APP_DIR. +# Either variable can be a list of paths, so we must make all of them absolute. +foreach(conf_file_var SB_CONF_FILE SB_EXTRA_CONF_FILE) + if(DEFINED ${conf_file_var}) + string(CONFIGURE "${${conf_file_var}}" conf_file_expanded) + set(${conf_file_var} "") + foreach(conf_file ${conf_file_expanded}) + cmake_path(ABSOLUTE_PATH conf_file BASE_DIRECTORY ${APP_DIR}) + list(APPEND ${conf_file_var} ${conf_file}) + endforeach() + endif() +endforeach() + if(DEFINED SB_CONF_FILE AND NOT DEFINED CACHE{SB_CONF_FILE}) # We only want to set this in cache it has been defined and is not already there. set(SB_CONF_FILE ${SB_CONF_FILE} CACHE STRING "If desired, you can build the application with \ From ce1b8d6d16bf8e7fd86ad7175579a8492d8a48d6 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 9 Oct 2023 10:48:50 +0200 Subject: [PATCH 1899/4498] scripts: kconfig: Make DEPRECATED/EXPERIMENTAL symbols optional Make `kconfig.py` not crash when any one of these settings is undefined: * DEPRECATED * EXPERIMENTAL * WARN_DEPRECATED * WARN_EXPERIMENTAL While these will continue to exist in Zephyr, they shouldn't be strictly required for the script to work. One situation in which they could go missing is when a user creates an application-specific Kconfig root, but forgets to source "Kconfig.zephyr" inside it - not that this is expected to work anyway, but it could at least raise a more intelligible error. Note that when WARN_DEPRECATED is undefined, selecting DEPRECATED will always produce warnings. Same with WARN_EXPERIMENTAL and EXPERIMENTAL. This matches the fact that the WARN_* symbols normally have `default y`. Signed-off-by: Grzegorz Swiderski --- scripts/kconfig/kconfig.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/kconfig/kconfig.py b/scripts/kconfig/kconfig.py index db2e6da8c44..c0de8245cab 100755 --- a/scripts/kconfig/kconfig.py +++ b/scripts/kconfig/kconfig.py @@ -78,10 +78,10 @@ def main(): check_assigned_sym_values(kconf) check_assigned_choice_values(kconf) - if kconf.syms['WARN_DEPRECATED'].tri_value == 2: + if kconf.syms.get('WARN_DEPRECATED', kconf.y).tri_value == 2: check_deprecated(kconf) - if kconf.syms['WARN_EXPERIMENTAL'].tri_value == 2: + if kconf.syms.get('WARN_EXPERIMENTAL', kconf.y).tri_value == 2: check_experimental(kconf) # Hack: Force all symbols to be evaluated, to catch warnings generated @@ -237,8 +237,8 @@ def check_assigned_choice_values(kconf): def check_deprecated(kconf): - deprecated = kconf.syms['DEPRECATED'] - dep_expr = deprecated.rev_dep + deprecated = kconf.syms.get('DEPRECATED') + dep_expr = kconf.n if deprecated is None else deprecated.rev_dep if dep_expr is not kconf.n: selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2] @@ -248,8 +248,8 @@ def check_deprecated(kconf): def check_experimental(kconf): - experimental = kconf.syms['EXPERIMENTAL'] - dep_expr = experimental.rev_dep + experimental = kconf.syms.get('EXPERIMENTAL') + dep_expr = kconf.n if experimental is None else experimental.rev_dep if dep_expr is not kconf.n: selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2] From 7772cec6bd38d682bd3f319080e35ffd89c9c0a2 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 11 Oct 2023 12:52:26 +0200 Subject: [PATCH 1900/4498] edtlib: always insert root node to the graph When we have an empty Devicetree, ie, ``` /dts-v1/; / { }; ``` The node's dep_ordinal is never initialized because the node graph is empty. This ends up with invalid ordinal tokens (-1) in devicetree_generated.h which in turn produce some cryptic compiler errors, see e.g. ``` error: pasting "dts_ord_" and "-" does not give a valid preprocessing token 95 | #define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id)) ... include/zephyr/devicetree.h:2498:41: note: in expansion of macro 'DT_FOREACH_OKAY_HELPER' 2498 | #define DT_FOREACH_STATUS_OKAY_NODE(fn) DT_FOREACH_OKAY_HELPER(fn) | ^~~~~~~~~~~~~~~~~~~~~~ include/zephyr/device.h:1022:1: note: in expansion of macro 'DT_FOREACH_STATUS_OKAY_NODE' 1022 | DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL) ``` (devicetree_generated.h) ``` ... #define DT_N_ORD -1 #define DT_N_ORD_STR_SORTABLE 000-1 ... ``` This patch makes sure root node is always inserted (without any target) so that it gets initialized later. Discovered as part of https://github.com/zephyrproject-rtos/zephyr/pull/63696 Signed-off-by: Gerard Marull-Paretas --- scripts/dts/python-devicetree/src/devicetree/edtlib.py | 4 ++++ scripts/dts/python-devicetree/src/devicetree/grutils.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index b52a516d454..0eb8dd832d1 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -2061,6 +2061,10 @@ def _init_graph(self) -> None: # first time the scc_order property is read. for node in self.nodes: + # Always insert root node + if not node.parent: + self._graph.add_node(node) + # A Node always depends on its parent. for child in node.children.values(): self._graph.add_edge(child, node) diff --git a/scripts/dts/python-devicetree/src/devicetree/grutils.py b/scripts/dts/python-devicetree/src/devicetree/grutils.py index c3ce825b202..452ee4aaaae 100644 --- a/scripts/dts/python-devicetree/src/devicetree/grutils.py +++ b/scripts/dts/python-devicetree/src/devicetree/grutils.py @@ -26,6 +26,12 @@ def __init__(self, root=None): self.__reverse_map = collections.defaultdict(set) self.__nodes = set() + def add_node(self, node): + """ + Add a node without any target to the graph. + """ + self.__nodes.add(node) + def add_edge(self, source, target): """ Add a directed edge from the C{source} to the C{target}. From 125e65a976ff2cb4d3f3ac885810ea050244f22e Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Thu, 5 Oct 2023 14:58:26 +0200 Subject: [PATCH 1901/4498] samples: Bluetooth: remove dup pointer in broadcast_audio_sink In the broadcast_audio_sink sample there are two pointers defined, both referencing the same address. We reduce this to one pointer Signed-off-by: Andries Kruithof --- .../bluetooth/broadcast_audio_sink/src/main.c | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index c7b89b7b18c..1d8613386fb 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -40,7 +40,7 @@ static K_SEM_DEFINE(sem_bis_sync_requested, 0U, 1U); static K_SEM_DEFINE(sem_bis_synced, 0U, CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT); /* Sample assumes that we only have a single Scan Delegator receive state */ -static const struct bt_bap_scan_delegator_recv_state *sink_recv_state; +static const struct bt_bap_scan_delegator_recv_state *req_recv_state; static struct bt_bap_broadcast_sink *broadcast_sink; static struct bt_le_scan_recv_info broadcaster_info; static bt_addr_le_t broadcaster_addr; @@ -158,20 +158,18 @@ static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { .syncable = syncable_cb, }; -const struct bt_bap_scan_delegator_recv_state *broadcast_recv_state; - static void pa_timer_handler(struct k_work *work) { - if (broadcast_recv_state != NULL) { + if (req_recv_state != NULL) { enum bt_bap_pa_state pa_state; - if (broadcast_recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { + if (req_recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { pa_state = BT_BAP_PA_STATE_NO_PAST; } else { pa_state = BT_BAP_PA_STATE_FAILED; } - bt_bap_scan_delegator_set_pa_state(broadcast_recv_state->src_id, + bt_bap_scan_delegator_set_pa_state(req_recv_state->src_id, pa_state); } @@ -228,9 +226,7 @@ static int pa_sync_req_cb(struct bt_conn *conn, { int err; - sink_recv_state = recv_state; - - broadcast_recv_state = recv_state; + req_recv_state = recv_state; if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED || recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { @@ -257,7 +253,7 @@ static int pa_sync_term_req_cb(struct bt_conn *conn, { int err; - sink_recv_state = recv_state; + req_recv_state = recv_state; err = bt_bap_broadcast_sink_delete(broadcast_sink); if (err != 0) { @@ -275,7 +271,7 @@ static void broadcast_code_cb(struct bt_conn *conn, { printk("Broadcast code received for %p\n", recv_state); - sink_recv_state = recv_state; + req_recv_state = recv_state; (void)memcpy(sink_broadcast_code, broadcast_code, BT_AUDIO_BROADCAST_CODE_SIZE); @@ -408,9 +404,10 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) if (broadcast_assistant_conn == NULL) { /* Not requested by Broadcast Assistant */ k_sem_give(&sem_broadcaster_found); - } else if (sink_recv_state != NULL && bt_addr_le_eq(info->addr, &sink_recv_state->addr) && - info->sid == sink_recv_state->adv_sid && - broadcast_id == sink_recv_state->broadcast_id) { + } else if (req_recv_state != NULL && + bt_addr_le_eq(info->addr, &req_recv_state->addr) && + info->sid == req_recv_state->adv_sid && + broadcast_id == req_recv_state->broadcast_id) { k_sem_give(&sem_broadcaster_found); } @@ -497,7 +494,7 @@ static int reset(void) bis_index_bitfield = 0U; requested_bis_sync = 0U; - sink_recv_state = NULL; + req_recv_state = NULL; (void)memset(sink_broadcast_code, 0, sizeof(sink_broadcast_code)); (void)memset(&broadcaster_info, 0, sizeof(broadcaster_info)); (void)memset(&broadcaster_addr, 0, sizeof(broadcaster_addr)); From c8a5cf6728f241010dec472f4db857a1266912ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 11 Sep 2023 13:35:59 +0700 Subject: [PATCH 1902/4498] intc: add NXP S32 WKPU interrupt controller driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce an interrupt controller for the NXP S32 WKPU peripheral that can be integrated with GPIO to trigger interrupts through external interrupt pad inputs. WKPU can trigger interrupts from certain input pads that support this function, as well as wake-up events to the power management domain. This patch only adds WKPU functionality as an interrupt controller to extend the number of input pads that can interrupt the core. Power management functionalities are not supported. Signed-off-by: Manuel Argüelles --- drivers/interrupt_controller/CMakeLists.txt | 1 + drivers/interrupt_controller/Kconfig.nxp_s32 | 10 +- .../interrupt_controller/intc_wkpu_nxp_s32.c | 194 ++++++++++++++++++ .../interrupt-controller/nxp,s32-wkpu.yaml | 28 +++ .../interrupt_controller/intc_wkpu_nxp_s32.h | 68 ++++++ 5 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 drivers/interrupt_controller/intc_wkpu_nxp_s32.c create mode 100644 dts/bindings/interrupt-controller/nxp,s32-wkpu.yaml create mode 100644 include/zephyr/drivers/interrupt_controller/intc_wkpu_nxp_s32.h diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 90163e7eaa5..c4d92304cf0 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -33,6 +33,7 @@ zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex. zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c) zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_nuclei_eclic.c) zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c) +zephyr_library_sources_ifdef(CONFIG_NXP_S32_WKPU intc_wkpu_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c) diff --git a/drivers/interrupt_controller/Kconfig.nxp_s32 b/drivers/interrupt_controller/Kconfig.nxp_s32 index 95bba9ec7d8..b4d54ea5f5b 100644 --- a/drivers/interrupt_controller/Kconfig.nxp_s32 +++ b/drivers/interrupt_controller/Kconfig.nxp_s32 @@ -1,6 +1,6 @@ # Configuration for NXP S32 external interrupt controller -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 config NXP_S32_EIRQ @@ -10,3 +10,11 @@ config NXP_S32_EIRQ select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help External interrupt controller driver for NXP S32 MCUs + +config NXP_S32_WKPU + bool "Wake-up Unit interrupt controller driver for NXP S32 MCUs" + default y + depends on DT_HAS_NXP_S32_WKPU_ENABLED + select NOCACHE_MEMORY + help + Wake-up Unit interrupt controller driver for NXP S32 MCUs diff --git a/drivers/interrupt_controller/intc_wkpu_nxp_s32.c b/drivers/interrupt_controller/intc_wkpu_nxp_s32.c new file mode 100644 index 00000000000..5a3a7b5b075 --- /dev/null +++ b/drivers/interrupt_controller/intc_wkpu_nxp_s32.c @@ -0,0 +1,194 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_s32_wkpu + +#include +#include +#include +#include +#include + +#include + +#define NXP_S32_NUM_CHANNELS WKPU_IP_NUM_OF_CHANNELS +#define NXP_S32_NUM_CHANNELS_DEBRACKET __DEBRACKET WKPU_IP_NUM_OF_CHANNELS + +struct wkpu_nxp_s32_config { + uint8_t instance; + + const WKPU_Type *base; + + const Wkpu_Ip_IrqConfigType *wkpu_cfg; +}; + +/* Wrapper callback for each WKPU line, from low level driver callback to GPIO callback */ +struct wkpu_nxp_s32_cb { + wkpu_nxp_s32_callback_t cb; + uint8_t pin; + void *data; +}; + +struct wkpu_nxp_s32_data { + struct wkpu_nxp_s32_cb *cb; +}; + +int wkpu_nxp_s32_set_callback(const struct device *dev, uint8_t line, + wkpu_nxp_s32_callback_t cb, uint8_t pin, void *arg) +{ + struct wkpu_nxp_s32_data *data = dev->data; + + __ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range"); + + if (data->cb[line].cb) { + return -EBUSY; + } + + data->cb[line].cb = cb; + data->cb[line].pin = pin; + data->cb[line].data = arg; + + return 0; +} + +void wkpu_nxp_s32_unset_callback(const struct device *dev, uint8_t line) +{ + struct wkpu_nxp_s32_data *data = dev->data; + + __ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range"); + + data->cb[line].cb = NULL; + data->cb[line].pin = 0; + data->cb[line].data = NULL; +} + +void wkpu_nxp_s32_enable_interrupt(const struct device *dev, uint8_t line, + Wkpu_Ip_EdgeType edge_type) +{ + const struct wkpu_nxp_s32_config *config = dev->config; + + __ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range"); + + Wkpu_Ip_SetActivationCondition(config->instance, line, edge_type); + Wkpu_Ip_EnableNotification(line); + Wkpu_Ip_EnableInterrupt(config->instance, line); +} + +void wkpu_nxp_s32_disable_interrupt(const struct device *dev, uint8_t line) +{ + const struct wkpu_nxp_s32_config *config = dev->config; + + __ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range"); + + Wkpu_Ip_DisableInterrupt(config->instance, line); + Wkpu_Ip_DisableNotification(line); + Wkpu_Ip_SetActivationCondition(config->instance, line, WKPU_IP_NONE_EDGE); +} + +uint64_t wkpu_nxp_s32_get_pending(const struct device *dev) +{ + const struct wkpu_nxp_s32_config *config = dev->config; + uint64_t flags; + + flags = config->base->WISR & config->base->IRER; +#if defined(WKPU_IP_64_CH_USED) && (WKPU_IP_64_CH_USED == STD_ON) + flags |= ((uint64_t)(config->base->WISR_64 & config->base->IRER_64)) << 32U; +#endif + + return flags; +} + +static void wkpu_nxp_s32_callback(const struct device *dev, uint8 line) +{ + const struct wkpu_nxp_s32_data *data = dev->data; + + if (data->cb[line].cb != NULL) { + data->cb[line].cb(data->cb[line].pin, data->cb[line].data); + } +} + +static int wkpu_nxp_s32_init(const struct device *dev) +{ + const struct wkpu_nxp_s32_config *config = dev->config; + + if (Wkpu_Ip_Init(config->instance, config->wkpu_cfg)) { + return -EINVAL; + } + + return 0; +} + +#define WKPU_NXP_S32_CALLBACK(line, n) \ + void nxp_s32_wkpu_##n##wkpu_line_##line##_callback(void) \ + { \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ + \ + wkpu_nxp_s32_callback(dev, line); \ + } + +#define WKPU_NXP_S32_CHANNEL_CONFIG(idx, n) \ + { \ + .hwChannel = idx, \ + .filterEn = DT_INST_PROP_OR(DT_INST_CHILD(n, line_##idx), filter_enable, 0), \ + .edgeEvent = WKPU_IP_NONE_EDGE, \ + .WkpuChannelNotification = nxp_s32_wkpu_##n##wkpu_line_##idx##_callback, \ + .callback = NULL, \ + .callbackParam = 0U \ + } + +#define WKPU_NXP_S32_CHANNELS_CONFIG(n) \ + static const Wkpu_Ip_ChannelConfigType wkpu_##n##_channel_nxp_s32_cfg[] = { \ + LISTIFY(NXP_S32_NUM_CHANNELS_DEBRACKET, WKPU_NXP_S32_CHANNEL_CONFIG, (,), n) \ + } + +#define WKPU_NXP_S32_INSTANCE_CONFIG(n) \ + static const Wkpu_Ip_IrqConfigType wkpu_##n##_nxp_s32_cfg = { \ + .numChannels = NXP_S32_NUM_CHANNELS, \ + .pChannelsConfig = &wkpu_##n##_channel_nxp_s32_cfg, \ + } + +#define WKPU_NXP_S32_CONFIG(n) \ + LISTIFY(NXP_S32_NUM_CHANNELS_DEBRACKET, WKPU_NXP_S32_CALLBACK, (), n) \ + WKPU_NXP_S32_CHANNELS_CONFIG(n); \ + WKPU_NXP_S32_INSTANCE_CONFIG(n); + +#define WKPU_NXP_S32_INIT_DEVICE(n) \ + WKPU_NXP_S32_CONFIG(n) \ + static const struct wkpu_nxp_s32_config wkpu_nxp_s32_conf_##n = { \ + .instance = n, \ + .base = (WKPU_Type *)DT_INST_REG_ADDR(n), \ + .wkpu_cfg = (Wkpu_Ip_IrqConfigType *)&wkpu_##n##_nxp_s32_cfg, \ + }; \ + static struct wkpu_nxp_s32_cb wkpu_nxp_s32_cb_##n[NXP_S32_NUM_CHANNELS]; \ + static struct wkpu_nxp_s32_data wkpu_nxp_s32_data_##n = { \ + .cb = wkpu_nxp_s32_cb_##n, \ + }; \ + static int wkpu_nxp_s32_init##n(const struct device *dev) \ + { \ + int err; \ + \ + err = wkpu_nxp_s32_init(dev); \ + if (err) { \ + return err; \ + } \ + \ + IRQ_CONNECT(DT_INST_IRQ(n, irq), DT_INST_IRQ(n, priority), \ + WKPU_EXT_IRQ_SINGLE_ISR, NULL, \ + COND_CODE_1(CONFIG_GIC, (DT_INST_IRQ(n, flags)), (0))); \ + irq_enable(DT_INST_IRQ(n, irq)); \ + \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(n, \ + wkpu_nxp_s32_init##n, \ + NULL, \ + &wkpu_nxp_s32_data_##n, \ + &wkpu_nxp_s32_conf_##n, \ + PRE_KERNEL_2, \ + CONFIG_INTC_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(WKPU_NXP_S32_INIT_DEVICE) diff --git a/dts/bindings/interrupt-controller/nxp,s32-wkpu.yaml b/dts/bindings/interrupt-controller/nxp,s32-wkpu.yaml new file mode 100644 index 00000000000..8afa1b56b50 --- /dev/null +++ b/dts/bindings/interrupt-controller/nxp,s32-wkpu.yaml @@ -0,0 +1,28 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP S32 Wake-up Unit + +compatible: "nxp,s32-wkpu" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + NXP S32 WKPU interrupt line configuration. Specific requirements for each + interrupt line can be specified by adding children nodes to this controller, + labeled `line_`. For example: + + line_0: line_0 { + filter-enable; + }; + + properties: + filter-enable: + type: boolean + description: | + Enable analog glitch filter on the external interrupt pad input. diff --git a/include/zephyr/drivers/interrupt_controller/intc_wkpu_nxp_s32.h b/include/zephyr/drivers/interrupt_controller/intc_wkpu_nxp_s32.h new file mode 100644 index 00000000000..c87a783e422 --- /dev/null +++ b/include/zephyr/drivers/interrupt_controller/intc_wkpu_nxp_s32.h @@ -0,0 +1,68 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Wake-up interrupt/event controller in NXP S32 MCUs + */ + +#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_WKPU_NXP_S32_H_ +#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_WKPU_NXP_S32_H_ + +#include + +/* Wrapper callback for WKPU line */ +typedef void (*wkpu_nxp_s32_callback_t)(uint8_t pin, void *arg); + +/** + * @brief Unset WKPU callback for line + * + * @param dev WKPU device + * @param line WKPU line + */ +void wkpu_nxp_s32_unset_callback(const struct device *dev, uint8_t line); + +/** + * @brief Set WKPU callback for line + * + * @param dev WKPU device + * @param line WKPU line + * @param cb Callback + * @param pin GPIO pin + * @param arg Callback data + * + * @retval 0 on SUCCESS + * @retval -EBUSY if callback for the line is already set + */ +int wkpu_nxp_s32_set_callback(const struct device *dev, uint8_t line, + wkpu_nxp_s32_callback_t cb, uint8_t pin, void *arg); + +/** + * @brief Set edge event and enable interrupt for WKPU line + * + * @param dev WKPU device + * @param line WKPU line + * @param edge_type Type of edge event + */ +void wkpu_nxp_s32_enable_interrupt(const struct device *dev, uint8_t line, + Wkpu_Ip_EdgeType edge_type); + +/** + * @brief Disable interrupt for WKPU line + * + * @param dev WKPU device + * @param line WKPU line + */ +void wkpu_nxp_s32_disable_interrupt(const struct device *dev, uint8_t line); + +/** + * @brief Get pending interrupt for WKPU device + * + * @param dev WKPU device + * @return A mask contains pending flags + */ +uint64_t wkpu_nxp_s32_get_pending(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_WKPU_NXP_S32_H_ */ From ea08227dd07b3e60635c2c8ef4837f795b791cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 11 Sep 2023 13:47:26 +0700 Subject: [PATCH 1903/4498] gpio: nxp_s32: prepare to support multiple interrupt controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor external interrupts infrastructure to prepare supporting multiple interrupt controllers. Signed-off-by: Manuel Argüelles --- drivers/gpio/gpio_nxp_s32.c | 143 +++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/drivers/gpio/gpio_nxp_s32.c b/drivers/gpio/gpio_nxp_s32.c index de5dbd39dd7..c40b5691931 100644 --- a/drivers/gpio/gpio_nxp_s32.c +++ b/drivers/gpio/gpio_nxp_s32.c @@ -9,20 +9,27 @@ #include #include #include +#include #include #include +LOG_MODULE_REGISTER(nxp_s32_gpio, CONFIG_GPIO_LOG_LEVEL); + #ifdef CONFIG_NXP_S32_EIRQ #include -struct eirq_nxp_s32_info { - const struct device *eirq_dev; - uint8_t num_lines; - struct gpio_pin_line { - uint8_t pin; - uint8_t line; - } gpio_pin_lines[]; +#define NXP_S32_GPIO_LINE_NOT_FOUND 0xff + +struct gpio_nxp_s32_irq_map { + uint8_t pin; + uint8_t line; +} __packed; + +struct gpio_nxp_s32_irq_config { + const struct device *ctrl; + uint8_t map_cnt; + struct gpio_nxp_s32_irq_map *map; }; #endif @@ -34,7 +41,7 @@ struct gpio_nxp_s32_config { Siul2_Port_Ip_PortType *port_base; #ifdef CONFIG_NXP_S32_EIRQ - struct eirq_nxp_s32_info *eirq_info; + struct gpio_nxp_s32_irq_config *eirq_info; #endif }; @@ -155,17 +162,26 @@ static int nxp_s32_gpio_port_toggle_bits(const struct device *port, #ifdef CONFIG_NXP_S32_EIRQ -static uint8_t nxp_s32_gpio_pin_to_line(const struct eirq_nxp_s32_info *eirq_info, uint8_t pin) +static uint8_t nxp_s32_gpio_pin_to_line(const struct gpio_nxp_s32_irq_config *irq_cfg, + uint8_t pin) { uint8_t i; - for (i = 0; i < eirq_info->num_lines; i++) { - if (eirq_info->gpio_pin_lines[i].pin == pin) { - return eirq_info->gpio_pin_lines[i].line; + for (i = 0; i < irq_cfg->map_cnt; i++) { + if (irq_cfg->map[i].pin == pin) { + return irq_cfg->map[i].line; } } - return SIUL2_ICU_IP_NUM_OF_CHANNELS; + return NXP_S32_GPIO_LINE_NOT_FOUND; +} + +static void nxp_s32_gpio_isr(uint8_t pin, void *arg) +{ + const struct device *dev = (struct device *)arg; + struct gpio_nxp_s32_data *data = dev->data; + + gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); } static int nxp_s32_gpio_eirq_get_trigger(Siul2_Icu_Ip_EdgeType *edge_type, @@ -198,63 +214,58 @@ static int nxp_s32_gpio_eirq_get_trigger(Siul2_Icu_Ip_EdgeType *edge_type, return 0; } -static void nxp_s32_gpio_isr(uint8_t pin, void *arg) -{ - const struct device *dev = (struct device *)arg; - struct gpio_nxp_s32_data *data = dev->data; - - gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); -} - -static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) +static int nxp_s32_gpio_config_eirq(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) { const struct gpio_nxp_s32_config *config = dev->config; - const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; - - uint8_t eirq_line; - + const struct gpio_nxp_s32_irq_config *irq_cfg = config->eirq_info; + uint8_t irq_line; Siul2_Icu_Ip_EdgeType edge_type; - if (eirq_info == NULL) { - /* - * There is no external interrupt device for - * the GPIO port or exists but is not enabled - */ + if (irq_cfg == NULL) { + LOG_ERR("external interrupt controller not available or enabled"); return -ENOTSUP; } - eirq_line = nxp_s32_gpio_pin_to_line(eirq_info, pin); - - if (eirq_line == SIUL2_ICU_IP_NUM_OF_CHANNELS) { - /* - * GPIO pin cannot be used for processing - * external interrupt signal - */ + if (nxp_s32_gpio_eirq_get_trigger(&edge_type, mode, trig)) { + LOG_ERR("trigger or mode not supported"); return -ENOTSUP; } - if (nxp_s32_gpio_eirq_get_trigger(&edge_type, mode, trig)) { + irq_line = nxp_s32_gpio_pin_to_line(irq_cfg, pin); + if (irq_line == NXP_S32_GPIO_LINE_NOT_FOUND) { + if (edge_type == SIUL2_ICU_DISABLE) { + return 0; + } + LOG_ERR("pin %d cannot be used for external interrupt", pin); return -ENOTSUP; } if (edge_type == SIUL2_ICU_DISABLE) { - eirq_nxp_s32_disable_interrupt(eirq_info->eirq_dev, eirq_line); - eirq_nxp_s32_unset_callback(eirq_info->eirq_dev, eirq_line); + eirq_nxp_s32_disable_interrupt(irq_cfg->ctrl, irq_line); + eirq_nxp_s32_unset_callback(irq_cfg->ctrl, irq_line); } else { - if (eirq_nxp_s32_set_callback(eirq_info->eirq_dev, eirq_line, - nxp_s32_gpio_isr, pin, (void *)dev)) { + if (eirq_nxp_s32_set_callback(irq_cfg->ctrl, irq_line, + nxp_s32_gpio_isr, pin, (void *)dev)) { + LOG_ERR("pin %d is already in use", pin); return -EBUSY; } - - eirq_nxp_s32_enable_interrupt(eirq_info->eirq_dev, eirq_line, edge_type); + eirq_nxp_s32_enable_interrupt(irq_cfg->ctrl, irq_line, edge_type); } return 0; } +static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return nxp_s32_gpio_config_eirq(dev, pin, mode, trig); +} + static int nxp_s32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set) { @@ -266,7 +277,7 @@ static int nxp_s32_gpio_manage_callback(const struct device *dev, static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) { const struct gpio_nxp_s32_config *config = dev->config; - const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; + const struct gpio_nxp_s32_irq_config *eirq_info = config->eirq_info; if (eirq_info == NULL) { /* @@ -280,7 +291,7 @@ static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) * Return all pending lines of the interrupt controller * that GPIO port belongs to */ - return eirq_nxp_s32_get_pending(eirq_info->eirq_dev); + return eirq_nxp_s32_get_pending(eirq_info->ctrl); } #endif /* CONFIG_NXP_S32_EIRQ */ @@ -424,30 +435,30 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { DT_INST_PHANDLE(n, interrupt_parent) #define GPIO_NXP_S32_EIRQ_PIN_LINE(idx, n) \ - { \ - .pin = DT_INST_IRQ_BY_IDX(n, idx, gpio_pin), \ - .line = DT_INST_IRQ_BY_IDX(n, idx, eirq_line), \ - } + DT_INST_IRQ_BY_IDX(n, idx, gpio_pin), \ + DT_INST_IRQ_BY_IDX(n, idx, eirq_line) \ #define GPIO_NXP_S32_SET_EIRQ_INFO(n) \ BUILD_ASSERT((DT_NODE_HAS_PROP(DT_DRV_INST(n), interrupt_parent) == \ DT_NODE_HAS_PROP(DT_DRV_INST(n), interrupts)), \ - "interrupts and interrupt-parent must be set when" \ - " using external interrupts"); \ - IF_ENABLED(DT_NODE_HAS_STATUS(GPIO_NXP_S32_EIRQ_NODE(n), okay), \ - (static struct eirq_nxp_s32_info eirq_nxp_s32_info_##n = { \ - .eirq_dev = DEVICE_DT_GET(GPIO_NXP_S32_EIRQ_NODE(n)), \ - .gpio_pin_lines = { \ - LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \ - GPIO_NXP_S32_EIRQ_PIN_LINE, (,), n) \ - }, \ - .num_lines = DT_NUM_IRQS(DT_DRV_INST(n)) \ + "interrupts and interrupt-parent must be set when " \ + "using external interrupts"); \ + IF_ENABLED(DT_NODE_HAS_STATUS(GPIO_NXP_S32_EIRQ_NODE(n), okay), ( \ + static uint8_t gpio_nxp_s32_eirq_data_##n[] = { \ + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \ + GPIO_NXP_S32_EIRQ_PIN_LINE, (,), n) \ + }; \ + static struct gpio_nxp_s32_irq_config gpio_nxp_s32_eirq_##n = { \ + .ctrl = DEVICE_DT_GET(GPIO_NXP_S32_EIRQ_NODE(n)), \ + .map_cnt = DT_NUM_IRQS(DT_DRV_INST(n)), \ + .map = (struct gpio_nxp_s32_irq_map *) \ + gpio_nxp_s32_eirq_data_##n, \ }; \ - )) + )) #define GPIO_NXP_S32_GET_EIRQ_INFO(n) \ .eirq_info = UTIL_AND(DT_NODE_HAS_STATUS(GPIO_NXP_S32_EIRQ_NODE(n), okay),\ - &eirq_nxp_s32_info_##n) + &gpio_nxp_s32_eirq_##n), #else #define GPIO_NXP_S32_SET_EIRQ_INFO(n) #define GPIO_NXP_S32_GET_EIRQ_INFO(n) From a034cce23c81014f0df5c58b2ea2d6d6221d69fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 11 Sep 2023 14:47:48 +0700 Subject: [PATCH 1904/4498] gpio: nxp_s32: support passing external interrupts to WKPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the NXP S32 GPIO driver to be able to route external interrupts to either SIUL2 EIRQ interrupt controller or, when available on the SoC, WKPU interrupt controller. Since WKPU can support up to 64 external interrupt sources and SIUL2 EIRQ up to 32, gpio_get_pending_int() is removed and the interrupt controller specific API must be used instead. Signed-off-by: Manuel Argüelles --- drivers/gpio/gpio_nxp_s32.c | 168 +++++++++++++++--- dts/bindings/gpio/nxp,s32-gpio.yaml | 47 ++++- .../zephyr/dt-bindings/gpio/nxp-s32-gpio.h | 39 ++++ 3 files changed, 227 insertions(+), 27 deletions(-) create mode 100644 include/zephyr/dt-bindings/gpio/nxp-s32-gpio.h diff --git a/drivers/gpio/gpio_nxp_s32.c b/drivers/gpio/gpio_nxp_s32.c index c40b5691931..2d272cdea09 100644 --- a/drivers/gpio/gpio_nxp_s32.c +++ b/drivers/gpio/gpio_nxp_s32.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -18,7 +19,12 @@ LOG_MODULE_REGISTER(nxp_s32_gpio, CONFIG_GPIO_LOG_LEVEL); #ifdef CONFIG_NXP_S32_EIRQ #include +#endif +#ifdef CONFIG_NXP_S32_WKPU +#include +#endif +#if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) #define NXP_S32_GPIO_LINE_NOT_FOUND 0xff struct gpio_nxp_s32_irq_map { @@ -43,14 +49,20 @@ struct gpio_nxp_s32_config { #ifdef CONFIG_NXP_S32_EIRQ struct gpio_nxp_s32_irq_config *eirq_info; #endif +#ifdef CONFIG_NXP_S32_WKPU + struct gpio_nxp_s32_irq_config *wkpu_info; +#endif }; struct gpio_nxp_s32_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; -#ifdef CONFIG_NXP_S32_EIRQ +#if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) sys_slist_t callbacks; +#if defined(CONFIG_NXP_S32_WKPU) + uint32_t pin_wkpu_mask; +#endif /* defined(CONFIG_NXP_S32_WKPU) */ #endif }; @@ -66,6 +78,16 @@ static int nxp_s32_gpio_configure(const struct device *dev, gpio_pin_t pin, return -ENOTSUP; } +#if defined(CONFIG_NXP_S32_WKPU) + struct gpio_nxp_s32_data *data = dev->data; + + WRITE_BIT(data->pin_wkpu_mask, pin, (flags & NXP_S32_GPIO_INT_WKPU)); +#else + if (flags & NXP_S32_GPIO_INT_WKPU) { + return -ENOTSUP; + } +#endif + switch (flags & GPIO_DIR_MASK) { case GPIO_INPUT: Siul2_Port_Ip_SetPinDirection(port_base, pin, SIUL2_PORT_IN); @@ -160,7 +182,7 @@ static int nxp_s32_gpio_port_toggle_bits(const struct device *port, return 0; } -#ifdef CONFIG_NXP_S32_EIRQ +#if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) static uint8_t nxp_s32_gpio_pin_to_line(const struct gpio_nxp_s32_irq_config *irq_cfg, uint8_t pin) @@ -184,6 +206,7 @@ static void nxp_s32_gpio_isr(uint8_t pin, void *arg) gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); } +#if defined(CONFIG_NXP_S32_EIRQ) static int nxp_s32_gpio_eirq_get_trigger(Siul2_Icu_Ip_EdgeType *edge_type, enum gpio_int_mode mode, enum gpio_int_trig trigger) @@ -257,13 +280,100 @@ static int nxp_s32_gpio_config_eirq(const struct device *dev, return 0; } +#endif /* CONFIG_NXP_S32_EIRQ */ + +#if defined(CONFIG_NXP_S32_WKPU) +static int nxp_s32_gpio_wkpu_get_trigger(Wkpu_Ip_EdgeType *edge_type, + enum gpio_int_mode mode, + enum gpio_int_trig trigger) +{ + if (mode == GPIO_INT_MODE_DISABLED) { + *edge_type = WKPU_IP_NONE_EDGE; + return 0; + } + + if (mode == GPIO_INT_MODE_LEVEL) { + return -ENOTSUP; + } + + switch (trigger) { + case GPIO_INT_TRIG_LOW: + *edge_type = WKPU_IP_FALLING_EDGE; + break; + case GPIO_INT_TRIG_HIGH: + *edge_type = WKPU_IP_RISING_EDGE; + break; + case GPIO_INT_TRIG_BOTH: + *edge_type = WKPU_IP_BOTH_EDGES; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int nxp_s32_gpio_config_wkpu(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct gpio_nxp_s32_config *config = dev->config; + const struct gpio_nxp_s32_irq_config *irq_cfg = config->wkpu_info; + uint8_t irq_line; + Wkpu_Ip_EdgeType edge_type; + + if (irq_cfg == NULL) { + LOG_ERR("WKPU controller not available or enabled"); + return -ENOTSUP; + } + + if (nxp_s32_gpio_wkpu_get_trigger(&edge_type, mode, trig)) { + LOG_ERR("trigger or mode not supported"); + return -ENOTSUP; + } + + irq_line = nxp_s32_gpio_pin_to_line(irq_cfg, pin); + if (irq_line == NXP_S32_GPIO_LINE_NOT_FOUND) { + if (edge_type == WKPU_IP_NONE_EDGE) { + return 0; + } + LOG_ERR("pin %d cannot be used for external interrupt", pin); + return -ENOTSUP; + } + + if (edge_type == WKPU_IP_NONE_EDGE) { + wkpu_nxp_s32_disable_interrupt(irq_cfg->ctrl, irq_line); + wkpu_nxp_s32_unset_callback(irq_cfg->ctrl, irq_line); + } else { + if (wkpu_nxp_s32_set_callback(irq_cfg->ctrl, irq_line, + nxp_s32_gpio_isr, pin, (void *)dev)) { + LOG_ERR("pin %d is already in use", pin); + return -EBUSY; + } + wkpu_nxp_s32_enable_interrupt(irq_cfg->ctrl, irq_line, edge_type); + } + + return 0; +} +#endif /* CONFIG_NXP_S32_WKPU */ static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { +#if defined(CONFIG_NXP_S32_WKPU) + struct gpio_nxp_s32_data *data = dev->data; + + if (data->pin_wkpu_mask & BIT(pin)) { + return nxp_s32_gpio_config_wkpu(dev, pin, mode, trig); + } +#endif + +#if defined(CONFIG_NXP_S32_EIRQ) return nxp_s32_gpio_config_eirq(dev, pin, mode, trig); +#endif } static int nxp_s32_gpio_manage_callback(const struct device *dev, @@ -273,27 +383,7 @@ static int nxp_s32_gpio_manage_callback(const struct device *dev, return gpio_manage_callback(&data->callbacks, cb, set); } - -static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) -{ - const struct gpio_nxp_s32_config *config = dev->config; - const struct gpio_nxp_s32_irq_config *eirq_info = config->eirq_info; - - if (eirq_info == NULL) { - /* - * There is no external interrupt device for - * the GPIO port or exists but is not enabled - */ - return 0; - } - - /* - * Return all pending lines of the interrupt controller - * that GPIO port belongs to - */ - return eirq_nxp_s32_get_pending(eirq_info->ctrl); -} -#endif /* CONFIG_NXP_S32_EIRQ */ +#endif /* defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) */ #ifdef CONFIG_GPIO_GET_CONFIG static int nxp_s32_gpio_pin_get_config(const struct device *dev, @@ -386,10 +476,9 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { .port_set_bits_raw = nxp_s32_gpio_port_set_bits_raw, .port_clear_bits_raw = nxp_s32_gpio_port_clear_bits_raw, .port_toggle_bits = nxp_s32_gpio_port_toggle_bits, -#ifdef CONFIG_NXP_S32_EIRQ +#if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) .pin_interrupt_configure = nxp_s32_gpio_pin_interrupt_configure, .manage_callback = nxp_s32_gpio_manage_callback, - .get_pending_int = nxp_s32_gpio_get_pending_int, #endif #ifdef CONFIG_GPIO_GET_CONFIG .pin_get_config = nxp_s32_gpio_pin_get_config, @@ -464,8 +553,36 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { #define GPIO_NXP_S32_GET_EIRQ_INFO(n) #endif /* CONFIG_NXP_S32_EIRQ */ +#ifdef CONFIG_NXP_S32_WKPU +#define GPIO_NXP_S32_WKPU_NODE(n) DT_INST_PHANDLE(n, nxp_wkpu) + +#define GPIO_NXP_S32_SET_WKPU_INFO(n) \ + BUILD_ASSERT((DT_INST_NODE_HAS_PROP(n, nxp_wkpu) == \ + DT_INST_NODE_HAS_PROP(n, nxp_wkpu_interrupts)), \ + "nxp,wkpu and nxp,wkpu-interrupts must be provided"); \ + IF_ENABLED(DT_NODE_HAS_STATUS(GPIO_NXP_S32_WKPU_NODE(n), okay), ( \ + static uint8_t gpio_nxp_s32_wkpu_data_##n[] = \ + DT_INST_PROP(n, nxp_wkpu_interrupts); \ + static struct gpio_nxp_s32_irq_config gpio_nxp_s32_wkpu_##n = { \ + .ctrl = DEVICE_DT_GET(GPIO_NXP_S32_WKPU_NODE(n)), \ + .map_cnt = sizeof(gpio_nxp_s32_wkpu_data_##n) / \ + sizeof(struct gpio_nxp_s32_irq_map), \ + .map = (struct gpio_nxp_s32_irq_map *) \ + gpio_nxp_s32_wkpu_data_##n, \ + }; \ + )) + +#define GPIO_NXP_S32_GET_WKPU_INFO(n) \ + .wkpu_info = UTIL_AND(DT_NODE_HAS_STATUS(GPIO_NXP_S32_WKPU_NODE(n), okay),\ + &gpio_nxp_s32_wkpu_##n) +#else +#define GPIO_NXP_S32_SET_WKPU_INFO(n) +#define GPIO_NXP_S32_GET_WKPU_INFO(n) +#endif /* CONFIG_NXP_S32_WKPU */ + #define GPIO_NXP_S32_DEVICE_INIT(n) \ GPIO_NXP_S32_SET_EIRQ_INFO(n) \ + GPIO_NXP_S32_SET_WKPU_INFO(n) \ static const struct gpio_nxp_s32_config gpio_nxp_s32_config_##n = { \ .common = { \ .port_pin_mask = GPIO_NXP_S32_PORT_PIN_MASK(n), \ @@ -473,6 +590,7 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { .gpio_base = GPIO_NXP_S32_REG_ADDR(n), \ .port_base = GPIO_NXP_S32_PORT_REG_ADDR(n), \ GPIO_NXP_S32_GET_EIRQ_INFO(n) \ + GPIO_NXP_S32_GET_WKPU_INFO(n) \ }; \ static struct gpio_nxp_s32_data gpio_nxp_s32_data_##n; \ static int gpio_nxp_s32_init_##n(const struct device *dev) \ diff --git a/dts/bindings/gpio/nxp,s32-gpio.yaml b/dts/bindings/gpio/nxp,s32-gpio.yaml index 3d19b61c9b3..5ebdb38979b 100644 --- a/dts/bindings/gpio/nxp,s32-gpio.yaml +++ b/dts/bindings/gpio/nxp,s32-gpio.yaml @@ -1,7 +1,39 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 -description: NXP S32 GPIO node +description: | + NXP S32 GPIO controller. + + The GPIO controller provides the option to route external input pad interrupts + to either the SIUL2 EIRQ interrupt controller or, when available on the SoC, + the WKPU interrupt controller. By default, GPIO interrupts are routed to the + SIUL2 EIRQ interrupt controller. + + To route external interrupts to the WKPU interrupt controller, the GPIO + specifier must be supplied with the flag `NXP_S32_GPIO_INT_WKPU`. For example, + the following snippet of devicetree source code instructs the GPIO controller + to route the interrupt from pin 9 of `gpioa` to the WKPU interrupt controller: + + #include + + &device { + gpios = <&gpioa 9 (NXP_S32_GPIO_INT_WKPU | GPIO_ACTIVE_HIGH)>; + }; + + Explicitly specifying the routing of a GPIO interrupt to a particular + interrupt controller allows for the allocation of distinct interrupt + priorities according to application-specific requirements. This is owing to + the fact that each interrupt controller features its own interrupt vector. + To illustrate, it is plausible to allocate the board's button interrupts to + the interrupt controller configured with a lower priority compared to the one + designated for the data-ready interrupt originating from a sensor. This + decision is justified by the potentially higher importance of the latter + interrupt to the overall system operation. + + The `NXP_S32_GPIO_INT_WKPU` flag is intended exclusively for specifying WKPU + as the interrupt controller for the corresponding GPIO. It's worth noting that + despite being named WKPU, the flag is not meant to configure GPIOs as wake-up + sources. compatible: "nxp,s32-gpio" @@ -20,6 +52,17 @@ properties: external interrupt signal, this is a list of GPIO pins and respective external interrupt lines (). + nxp,wkpu: + type: phandle + description: | + NXP WKPU controller associated to this GPIO port. + + nxp,wkpu-interrupts: + type: array + description: | + Map between WKPU external interrupt sources and pins of this GPIO port, + as in a tuple ``. + "#gpio-cells": const: 2 diff --git a/include/zephyr/dt-bindings/gpio/nxp-s32-gpio.h b/include/zephyr/dt-bindings/gpio/nxp-s32-gpio.h new file mode 100644 index 00000000000..ebd789e5d8b --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/nxp-s32-gpio.h @@ -0,0 +1,39 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_NXP_S32_GPIO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_NXP_S32_GPIO_H_ + +/** + * @brief NXP S32 GPIO specific flags + * + * The driver flags are encoded in the 8 upper bits of @ref gpio_dt_flags_t as + * follows: + * + * - Bit 8: Interrupt controller to which the respective GPIO interrupt is routed. + * + * @ingroup gpio_interface + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ +#define NXP_S32_GPIO_INT_CONTROLLER_POS 8 +#define NXP_S32_GPIO_INT_CONTROLLER_MASK (0x1U << NXP_S32_GPIO_INT_CONTROLLER_POS) +/** @endcond */ + +/** + * @name NXP S32 GPIO interrupt controller routing flags + * @brief NXP S32 GPIO interrupt controller routing flags + * @{ + */ + +/** Interrupt routed to the WKPU controller */ +#define NXP_S32_GPIO_INT_WKPU (0x1U << NXP_S32_GPIO_INT_CONTROLLER_POS) + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_NXP_S32_GPIO_H_ */ From 7c661c625c42eb5b832c8db6e189a0809afcde65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 11 Sep 2023 14:53:44 +0700 Subject: [PATCH 1905/4498] nxp_s32k344: add external interrupts for WKPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define WKPU interrupt controller node and its respective interrupt sources mapping to GPIO pins. Signed-off-by: Manuel Argüelles --- dts/arm/nxp/nxp_s32k344_m7.dtsi | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 91a4a2d989c..60196628a57 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -108,6 +108,9 @@ <5 5>, <6 6>, <7 7>, <8 16>, <9 17>, <10 18>, <11 19>, <12 20>, <13 21>, <14 22>, <15 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <1 9>, <2 4>, <6 19>, + <8 27>, <9 25>, <13 8>, <15 24>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -121,6 +124,9 @@ interrupt-parent = <&eirq0>; interrupts = <0 4>, <2 0>, <3 1>, <4 2>, <5 3>, <9 5>, <12 6>, <14 7>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 35>, <4 63>, <9 38>, + <10 39>, <14 41>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -135,6 +141,9 @@ interrupts = <0 8>, <1 9>, <2 10>, <3 11>, <4 12>, <5 13>, <8 14>, <9 15>, <10 24>, <11 25>, <12 26>, <13 27>, <14 28>, <15 29>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 11>, <2 12>, <8 29>, + <9 21>, <11 20>, <12 16>, <13 15>, <15 37>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -149,6 +158,9 @@ interrupt-parent = <&eirq0>; interrupts = <0 30>, <1 31>, <5 8>, <6 9>, <7 10>, <8 11>, <9 12>, <10 13>, <12 14>, <15 15>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 17>, <1 18>, <3 42>, + <5 43>, <7 44>, <10 45>, <12 46>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -164,6 +176,8 @@ <5 5>, <6 6>, <7 7>, <8 16>, <9 17>, <10 18>, <11 19>, <12 20>, <13 21>, <14 22>, <15 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <6 7>, <7 6>, <9 14>, <11 22>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -177,6 +191,9 @@ interrupt-parent = <&eirq0>; interrupts = <4 16>, <5 17>, <7 18>, <8 19>, <9 20>, <10 21>, <11 22>, <13 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <2 40>, <4 47>, <7 48>, + <8 50>, <9 49>, <10 52>, <13 51>, <15 53>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -192,6 +209,9 @@ <5 13>, <6 14>, <7 15>, <8 24>, <9 25>, <10 26>, <11 27>, <12 28>, <13 29>, <14 30>, <15 31>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 10>, <2 13>, <3 5>, + <4 26>, <13 28>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -205,6 +225,9 @@ interrupt-parent = <&eirq0>; interrupts = <1 24>, <4 25>, <5 26>, <6 27>, <7 28>, <8 29>, <11 30>, <12 31>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <4 58>, <7 54>, <11 55>, + <13 56>, <15 57>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -220,6 +243,9 @@ <4 4>, <5 5>, <6 6>, <8 7>, <9 8>, <10 9>, <11 10>, <12 11>, <13 12>, <14 13>, <15 14>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 30>, <2 31>, <5 36>, + <6 33>, <11 32>, <14 34>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -232,6 +258,9 @@ reg-names = "pgpdo", "mscr"; interrupt-parent = <&eirq0>; interrupts = <0 15>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 23>, <2 59>, <5 60>, + <7 61>, <9 62>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -289,6 +318,13 @@ }; }; + wkpu: wkpu@402b4000 { + compatible = "nxp,s32-wkpu"; + reg = <0x402b4000 0x4000>; + interrupts = <83 0>; + status = "disabled"; + }; + lpuart0: uart@40328000 { compatible = "nxp,kinetis-lpuart"; reg = <0x40328000 0x4000>; From f95c10d548e3dd9552e329c19bebc2c7da778e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 11 Sep 2023 14:57:11 +0700 Subject: [PATCH 1906/4498] mr_canhubk3: document WKPU interrupt controller support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhance the documentation by providing an explanation of WKPU interrupt controller support and how it integrates with GPIO. Signed-off-by: Manuel Argüelles --- boards/arm/mr_canhubk3/doc/index.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boards/arm/mr_canhubk3/doc/index.rst b/boards/arm/mr_canhubk3/doc/index.rst index a26b6dd3ec2..63dbb36666b 100644 --- a/boards/arm/mr_canhubk3/doc/index.rst +++ b/boards/arm/mr_canhubk3/doc/index.rst @@ -48,6 +48,7 @@ Interface Controller Driver/Component SIUL2 on-chip | pinctrl | gpio | external interrupt controller +WKPU on-chip interrupt controller LPUART on-chip serial QSPI on-chip flash FLEXCAN on-chip can @@ -70,6 +71,21 @@ Each GPIO port is divided into two banks: low bank, from pin 0 to 15, and high bank, from pin 16 to 31. For example, ``PTA2`` is the pin 2 of ``gpioa_l`` (low bank), and ``PTA20`` is the pin 4 of ``gpioa_h`` (high bank). +The GPIO controller provides the option to route external input pad interrupts +to either the SIUL2 EIRQ or WKPU interrupt controllers, as supported by the SoC. +By default, GPIO interrupts are routed to SIUL2 EIRQ interrupt controller, +unless they are explicity configured to be directed to the WKPU interrupt +controller, as outlined in :zephyr_file:`dts/bindings/gpio/nxp,s32-gpio.yaml`. + +To find information about which GPIOs are compatible with each interrupt +controller, refer to the device reference manual. + +.. note:: + + It is important to highlight that the current board configuration lacks + support for wake-up events and power-management features. WKPU functionality + is restricted solely to serving as an interrupt controller. + LEDs ---- From 8a4ec8e024a9fa92032e21238d77fc596efa492b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 14 Sep 2023 11:26:16 +0700 Subject: [PATCH 1907/4498] tests: gpio_basic_api: use GPIO flags from DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When configuring in/out pins for callback tests, pass the GPIO flags coming from the in/out-gpios respective nodes. Signed-off-by: Manuel Argüelles --- tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c | 4 ++-- tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c | 4 ++-- tests/drivers/gpio/gpio_basic_api/src/test_gpio.h | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c b/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c index 97e217f298a..3a409009c70 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c +++ b/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c @@ -43,12 +43,12 @@ static int init_callback(const struct device *dev, } if (rc == 0) { /* 1. set PIN_OUT */ - rc = gpio_pin_configure(dev, PIN_OUT, GPIO_OUTPUT_LOW); + rc = gpio_pin_configure(dev, PIN_OUT, (GPIO_OUTPUT_LOW | PIN_OUT_FLAGS)); } if (rc == 0) { /* 2. configure PIN_IN callback, but don't enable */ - rc = gpio_pin_configure(dev, PIN_IN, GPIO_INPUT); + rc = gpio_pin_configure(dev, PIN_IN, (GPIO_INPUT | PIN_IN_FLAGS)); } if (rc == 0) { diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c b/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c index 2209e988230..868e3822399 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c +++ b/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c @@ -40,7 +40,7 @@ static int test_callback(int mode) gpio_pin_interrupt_configure(dev, PIN_OUT, GPIO_INT_DISABLE); /* 1. set PIN_OUT to logical initial state inactive */ - uint32_t out_flags = GPIO_OUTPUT_LOW; + uint32_t out_flags = GPIO_OUTPUT_LOW | PIN_OUT_FLAGS; if ((mode & GPIO_INT_LOW_0) != 0) { out_flags = GPIO_OUTPUT_HIGH | GPIO_ACTIVE_LOW; @@ -54,7 +54,7 @@ static int test_callback(int mode) } /* 2. configure PIN_IN callback and trigger condition */ - rc = gpio_pin_configure(dev, PIN_IN, GPIO_INPUT); + rc = gpio_pin_configure(dev, PIN_IN, (GPIO_INPUT | PIN_IN_FLAGS)); if (rc != 0) { TC_ERROR("config PIN_IN fail: %d\n", rc); goto err_exit; diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_gpio.h b/tests/drivers/gpio/gpio_basic_api/src/test_gpio.h index 38a15dc3dce..ba3d3ae5eba 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/test_gpio.h +++ b/tests/drivers/gpio/gpio_basic_api/src/test_gpio.h @@ -25,7 +25,9 @@ #define DEV_IN DT_GPIO_CTLR(DT_INST(0, test_gpio_basic_api), in_gpios) #define DEV DEV_OUT /* DEV_OUT should equal DEV_IN, we test for this */ #define PIN_OUT DT_GPIO_PIN(DT_INST(0, test_gpio_basic_api), out_gpios) +#define PIN_OUT_FLAGS DT_GPIO_FLAGS(DT_INST(0, test_gpio_basic_api), out_gpios) #define PIN_IN DT_GPIO_PIN(DT_INST(0, test_gpio_basic_api), in_gpios) +#define PIN_IN_FLAGS DT_GPIO_FLAGS(DT_INST(0, test_gpio_basic_api), in_gpios) #elif DT_NODE_HAS_STATUS(DT_ALIAS(gpio_0), okay) #define DEV DT_GPIO_CTLR(DT_ALIAS(gpio_0)) From 402e1da58d6451390b98b8469b5a01a403d85c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Wed, 13 Sep 2023 17:30:58 +0700 Subject: [PATCH 1908/4498] tests: gpio_basic_api: add WKPU interrupts test for mr_canhubk3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the same pins as when testing with SIUL2 EIRQ interrupt controller, but instead test routing the external interrupts to WKPU controller. Signed-off-by: Manuel Argüelles --- .../boards/mr_canhubk3_wkpu.overlay | 20 +++++++++++++++++++ .../drivers/gpio/gpio_basic_api/testcase.yaml | 4 ++++ 2 files changed, 24 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/mr_canhubk3_wkpu.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/mr_canhubk3_wkpu.overlay b/tests/drivers/gpio/gpio_basic_api/boards/mr_canhubk3_wkpu.overlay new file mode 100644 index 00000000000..e9ca00dbabf --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/mr_canhubk3_wkpu.overlay @@ -0,0 +1,20 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + resources { + compatible = "test-gpio-basic-api"; + /* Use LPSPI1 MISO/MOSI pins which are also used for spi_loopback test */ + out-gpios = <&gpioa_h 13 0>; + in-gpios = <&gpioa_h 14 NXP_S32_GPIO_INT_WKPU>; + }; +}; + +&wkpu { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/testcase.yaml b/tests/drivers/gpio/gpio_basic_api/testcase.yaml index 9fb9d7fb292..cc572e82ef0 100644 --- a/tests/drivers/gpio/gpio_basic_api/testcase.yaml +++ b/tests/drivers/gpio/gpio_basic_api/testcase.yaml @@ -16,3 +16,7 @@ tests: platform_allow: nrf52840dk_nrf52840 nrf52_bsim extra_args: "DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840.overlay;\ boards/nrf52840dk_nrf52840_sense_edge.overlay" + + drivers.gpio.mr_canhubk3_wkpu: + platform_allow: mr_canhubk3 + extra_args: "DTC_OVERLAY_FILE=boards/mr_canhubk3_wkpu.overlay" From 905b7dbf3ba5868eb246140a48ecdbe88e946250 Mon Sep 17 00:00:00 2001 From: Kevin Townsend Date: Wed, 11 Oct 2023 17:22:33 +0200 Subject: [PATCH 1909/4498] doc: releases: Rename Arm to Arc Fixes a typo in the release notes where two 'Arm' entries were present, and the first should have been 'Arc'. Signed-off-by: Kevin Townsend --- doc/releases/release-notes-3.5.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 28894e9352d..323c5774177 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -58,6 +58,8 @@ Kernel Architectures ************* +* ARC + * ARM * Architectural support for Arm Cortex-M has been separated from Arm @@ -65,8 +67,6 @@ Architectures tasks like IRQ management, exception handling, thread handling and swap. For implementation details see :github:`60031`. -* ARM - * ARM64 * RISC-V From 517bec233e14c48fd85d07eae142a72fbca29ea5 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 11 Oct 2023 15:51:33 +0200 Subject: [PATCH 1910/4498] modem: modem_cmux: Increase modem cmux buf size This commit increases the buffer used for commands in the control channel within an instance of the modem_cmux module. The buffer was not large enough to store an MSC command if the optional break signals where included. This commit fixes the issue and updates the test suite to use the max size MSC message. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 2 +- tests/subsys/modem/modem_cmux/src/main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 690af4ddce8..a73241a7a46 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -23,7 +23,7 @@ LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_MODULES_LOG_LEVEL); #define MODEM_CMUX_DATA_FRAME_SIZE_MIN (MODEM_CMUX_FRAME_SIZE_MAX + \ MODEM_CMUX_DATA_SIZE_MIN) -#define MODEM_CMUX_CMD_DATA_SIZE_MAX (0x04) +#define MODEM_CMUX_CMD_DATA_SIZE_MAX (0x08) #define MODEM_CMUX_CMD_FRAME_SIZE_MAX (MODEM_CMUX_FRAME_SIZE_MAX + \ MODEM_CMUX_CMD_DATA_SIZE_MAX) diff --git a/tests/subsys/modem/modem_cmux/src/main.c b/tests/subsys/modem/modem_cmux/src/main.c index 243aa6112c8..9df6837efc5 100644 --- a/tests/subsys/modem/modem_cmux/src/main.c +++ b/tests/subsys/modem/modem_cmux/src/main.c @@ -100,11 +100,11 @@ static uint8_t cmux_frame_dlci2_sabm_cmd[] = {0xF9, 0x0B, 0x3F, 0x01, 0x59, 0xF9 static uint8_t cmux_frame_dlci2_sabm_ack[] = {0xF9, 0x0B, 0x73, 0x01, 0x92, 0xF9}; static uint8_t cmux_frame_dlci2_disc_cmd[] = {0xF9, 0x0B, 0x53, 0x01, 0xB8, 0xF9}; static uint8_t cmux_frame_dlci2_ua_ack[] = {0xF9, 0x0B, 0x73, 0x01, 0x92, 0xF9}; -static uint8_t cmux_frame_control_msc_cmd[] = {0xF9, 0x01, 0xFF, 0x09, 0xE3, - 0x05, 0x0B, 0x09, 0x8F, 0xF9}; +static uint8_t cmux_frame_control_msc_cmd[] = {0xF9, 0x01, 0xFF, 0x0B, 0xE3, + 0x07, 0x0B, 0x09, 0x01, 0x6C, 0xF9}; -static uint8_t cmux_frame_control_msc_ack[] = {0xF9, 0x01, 0xFF, 0x09, 0xE1, - 0x05, 0x0B, 0x09, 0x8F, 0xF9}; +static uint8_t cmux_frame_control_msc_ack[] = {0xF9, 0x01, 0xFF, 0x0B, 0xE1, + 0x07, 0x0B, 0x09, 0x01, 0x6C, 0xF9}; static uint8_t cmux_frame_control_fcon_cmd[] = {0xF9, 0x01, 0xFF, 0x05, 0xA3, 0x01, 0x86, 0xF9}; static uint8_t cmux_frame_control_fcon_ack[] = {0xF9, 0x01, 0xFF, 0x05, 0xA1, 0x01, 0x86, 0xF9}; From 0339f2d41ff9ef3c09a000ee41ee29c68b612bb6 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 11 Oct 2023 16:14:58 +0200 Subject: [PATCH 1911/4498] modem: modem_cellular: Adjust chat scripts This commit adjust the chat scripts for the simcom sim7080 and gsm_ppp compatibles to fix an issue found when trying to use a sim7080 modem. The CMUX command includes optional parameters which are not identical for all modems, so the AT+CMUX command has been adjusted to only contain the mandatory parameters. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/modem_cellular.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 9a6e91e99be..f1536ee37d5 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1329,8 +1329,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds, * too short, modems have been observed to simply deadlock, * refusing to respond to any CMUX command. */ - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 300)); + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300)); MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_init_chat_script, zephyr_gsm_ppp_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1365,8 +1364,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 0)); + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300)); MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); From 9ceb8ce10a3983c4b3a34bee1a89e9f25e354403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Wed, 11 Oct 2023 09:30:28 -0700 Subject: [PATCH 1912/4498] doc: west: build: fix info on --pristine default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit commit c19c6fb438b98e54d38eeff4a606d6d9a3d801c8 ("Revert "scripts: west build: default build.pristine to auto""), we set the default --pristine value back to 'never', but the documentation never got updated. Fix it. Signed-off-by: Martí Bolívar --- doc/develop/west/build-flash-debug.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/develop/west/build-flash-debug.rst b/doc/develop/west/build-flash-debug.rst index abe26614aea..0f9f15ef9d7 100644 --- a/doc/develop/west/build-flash-debug.rst +++ b/doc/develop/west/build-flash-debug.rst @@ -177,8 +177,12 @@ it the value ``always``. For example, these commands are equivalent:: west build -p -b reel_board samples/hello_world west build -p=always -b reel_board samples/hello_world -By default, ``west build`` applies a heuristic to detect if the build directory -needs to be made pristine. This is the same as using ``--pristine=auto``. +By default, ``west build`` makes no attempt to detect if the build directory +needs to be made pristine. This can lead to errors if you do something like +try to re-use a build directory for a different ``--board``. + +Using ``--pristine=auto`` makes ``west build`` detect some of these situations +and make the build directory pristine before trying the build. .. tip:: From d2001eeb96d87b1a8145b0e46032486f7183026e Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Sat, 7 Oct 2023 23:18:41 -0300 Subject: [PATCH 1913/4498] doc: zbus: update documentation with changes for 3.5 Add documentation for the new way to storage observers, the message subscribers, and the confirmed message sample. Signed-off-by: Rodrigo Peixoto --- .../zbus/images/zbus_observation_mask.svg | 152 ++++++ doc/services/zbus/images/zbus_operations.svg | 55 +- .../zbus_publishing_process_example.svg | 73 ++- .../zbus_publishing_process_example2.svg | 67 +++ ...us_publishing_process_example_scenario.svg | 38 +- .../zbus/images/zbus_type_of_observers.svg | 14 + doc/services/zbus/index.rst | 475 +++++++++++++++--- 7 files changed, 784 insertions(+), 90 deletions(-) create mode 100644 doc/services/zbus/images/zbus_observation_mask.svg create mode 100644 doc/services/zbus/images/zbus_publishing_process_example2.svg create mode 100644 doc/services/zbus/images/zbus_type_of_observers.svg diff --git a/doc/services/zbus/images/zbus_observation_mask.svg b/doc/services/zbus/images/zbus_observation_mask.svg new file mode 100644 index 00000000000..4405a8f3e4a --- /dev/null +++ b/doc/services/zbus/images/zbus_observation_mask.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/services/zbus/images/zbus_operations.svg b/doc/services/zbus/images/zbus_operations.svg index d0f96881745..6ed8648e9e0 100644 --- a/doc/services/zbus/images/zbus_operations.svg +++ b/doc/services/zbus/images/zbus_operations.svg @@ -1,3 +1,52 @@ - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/services/zbus/images/zbus_publishing_process_example.svg b/doc/services/zbus/images/zbus_publishing_process_example.svg index 0e9ba3dc351..72d7430a163 100644 --- a/doc/services/zbus/images/zbus_publishing_process_example.svg +++ b/doc/services/zbus/images/zbus_publishing_process_example.svg @@ -1,3 +1,70 @@ - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/services/zbus/images/zbus_publishing_process_example2.svg b/doc/services/zbus/images/zbus_publishing_process_example2.svg new file mode 100644 index 00000000000..f71a3c29ca2 --- /dev/null +++ b/doc/services/zbus/images/zbus_publishing_process_example2.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/services/zbus/images/zbus_publishing_process_example_scenario.svg b/doc/services/zbus/images/zbus_publishing_process_example_scenario.svg index 6d473a45a83..abcb27de217 100644 --- a/doc/services/zbus/images/zbus_publishing_process_example_scenario.svg +++ b/doc/services/zbus/images/zbus_publishing_process_example_scenario.svg @@ -1,3 +1,35 @@ - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/services/zbus/images/zbus_type_of_observers.svg b/doc/services/zbus/images/zbus_type_of_observers.svg new file mode 100644 index 00000000000..34b1be73307 --- /dev/null +++ b/doc/services/zbus/images/zbus_type_of_observers.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 441e9f887f4..45e9e0ea69a 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -1,9 +1,16 @@ .. _zbus: -Zephyr message bus (zbus) -######################### +Zephyr bus (zbus) +################# -The :dfn:`Zephyr message bus - Zbus` is a lightweight and flexible message bus enabling a simple way for threads to talk to one another. +.. + Note to documentation authors: the diagrams included in this documentation page were designed + using the following Figma library: + https://www.figma.com/community/file/1292866458780627559/zbus-diagram-assets + + +The :dfn:`Zephyr bus - zbus` is a lightweight and flexible software bus enabling a simple way for +threads to talk to one another in a many-to-many way. .. contents:: :local: @@ -11,8 +18,19 @@ The :dfn:`Zephyr message bus - Zbus` is a lightweight and flexible message bus e Concepts ******** +Threads can send messages to one or more observers using zbus. It makes the many-to-many +communication possible. The bus implements message-passing and publish/subscribe communication +paradigms that enable threads to communicate synchronously or asynchronously through shared memory. -Threads can broadcast messages to all interested observers using zbus. Many-to-many communication is possible. The bus implements message-passing and publish/subscribe communication paradigms that enable threads to communicate synchronously or asynchronously through shared memory. The communication through zbus is channel-based, where threads publish and read to and from using messages. Additionally, threads can observe channels and receive notifications from the bus when the channels are modified. The figure below shows an example of a typical application using zbus in which the application logic (hardware independent) talks to other threads via message bus. Note that the threads are decoupled from each other because they only use zbus' channels and do not need to know each other to talk. +The communication through zbus is channel-based. Threads (or callbacks) use channels to exchange +messages. Additionally, besides other actions, threads can publish and observe channels. When a +thread publishes a message on a channel, the bus will make the message available to all the +published channel's observers. Based on the observer's type, it can access the message directly, +receive a copy of it, or even receive only a reference of the published channel. + +The figure below shows an example of a typical application using zbus in which the application logic +(hardware independent) talks to other threads via software bus. Note that the threads are decoupled +from each other because they only use zbus channels and do not need to know each other to talk. .. figure:: images/zbus_overview.svg @@ -23,36 +41,104 @@ Threads can broadcast messages to all interested observers using zbus. Many-to-m The bus comprises: -* Set of channels that consists of a unique identifier, its control metadata information, and the message itself; -* :dfn:`Virtual distributed event dispatcher` (VDED), the bus logic responsible for sending notifications to the observers. The VDED logic runs inside the publishing action in the same thread context, giving the bus an idea of a distributed execution. When a thread publishes to a channel, it also propagates the notifications to the observers; -* Threads (subscribers) and callbacks (listeners) publishing, reading, and receiving notifications from the bus. +* Set of channels that consists of the control metadata information, and the message itself; +* :dfn:`Virtual Distributed Event Dispatcher` (VDED), the bus logic responsible for sending + notifications/messages to the observers. The VDED logic runs inside the publishing action in the same + thread context, giving the bus an idea of a distributed execution. When a thread publishes to a + channel, it also propagates the notifications to the observers; +* Threads (subscribers and message subscribers) and callbacks (listeners) publishing, reading, and + receiving notifications from the bus. .. figure:: images/zbus_anatomy.svg - :alt: Zbus anatomy + :alt: ZBus anatomy + :width: 70% + + ZBus anatomy. + +The bus makes the publish, read, claim, finish, notify, and subscribe actions available over +channels. Publishing, reading, claiming, and finishing are available in all RTOS thread contexts. +However, it cannot run inside Interrupt Service Routines (ISR) because it uses mutexes to control +channel access, and mutexes cannot work appropriately inside ISRs. The publish and read operations +are simple and fast; the procedure is a mutex locking followed by a memory copy to and from a shared +memory region and then a mutex unlocking. Another essential aspect of zbus is the observers. There +are three types of observers: + +.. figure:: images/zbus_type_of_observers.svg + :alt: ZBus observers type :width: 70% - Zbus anatomy. + ZBus observers. + +* Listeners, a callback that the event dispatcher executes every time an observed channel is + published or notified; +* Subscriber, a thread-based observer that relies internally on a message queue where the event + dispatcher puts a changed channel's reference every time an observed channel is published or + notified. Note this kind of observer does not receive the message itself. It should read the + message from the channel after receiving the notification; +* Message subscribers, a thread-based observer that relies internally on a FIFO where the event + dispatcher puts a copy of the message every time an observed channel is published or notified. + +Channel observation structures define the relationship between a channel and its observers. For +every observation, a pair channel/observer. Developers can statically allocate observation using the +:c:macro:`ZBUS_CHAN_DEFINE` or :c:macro:`ZBUS_CHAN_ADD_OBS`. There are also runtime observers, +enabling developers to create runtime observations. It is possible to disable an observer entirely +or observations individually. The event dispatcher will ignore disabled observers and observations. + +.. figure:: images/zbus_observation_mask.svg + :alt: ZBus observation mask. + :width: 75% -The bus makes the publish, read, and subscribe actions available over channels. Publishing and reading are available in all RTOS thread contexts. However, it cannot run inside Interrupt Service Routines (ISR) because it uses mutexes to control channels access, and mutexes cannot work appropriately inside ISRs. The publish and read operations are simple and fast; the procedure is a mutex locking followed by a memory copy to and from a shared memory region and then a mutex unlocking. Another essential aspect of zbus is the observers, which can be: + ZBus observation mask. -* Static; defined in compile time. It is not possible to remove it at runtime, but it is possible to suppress it by calling the :c:func:`zbus_obs_set_enable`; -* Dynamic; it can be added and removed to and from a channel at runtime. +The above figure illustrates some states, from (a) to (d), for channels from ``C1`` to ``C5``, +``Subscriber 1``, and the observations. The last two are in orange to indicate they are dynamically +allocated (runtime observation). (a) shows that the observer and all observations are enabled. (b) +shows the observer is disabled, so the event dispatcher will ignore it. (c) shows the observer +enabled. However, there is one static observervation disabled. The event dispatcher will only stop +sending notifications from channel ``C3``. In (d), the event dispatcher will stop sending +notifications from channels ``C3`` and ``C5`` to ``Subscriber 1``. -For illustration purposes, suppose a usual sensor-based solution in the figure below. When the timer is triggered, it pushes an action to a work queue that publishes to the ``Start trigger`` channel. As the sensor thread subscribed to the ``Start trigger`` channel, it fetches the sensor data. Notice the VDED executes the blink callback because it also listens to the ``Start trigger`` channel. When the sensor data is ready, the sensor thread publishes it to the ``Sensor data`` channel. The core thread, as a ``Sensor data`` channel subscriber, processes the sensor data and stores it in an internal sample buffer. It repeats until the sample buffer is full; when it happens, the core thread aggregates the sample buffer information, prepares a package, and publishes that to the ``Payload`` channel. The Lora thread receives that because it is a ``Payload`` channel subscriber and sends the payload to the cloud. When it completes the transmission, the Lora thread publishes to the ``Transmission done`` channel. The VDED executes the blink callback again since it listens to the ``Transmission done`` channel. +Suppose a usual sensor-based solution is in the figure below for illustration purposes. When +triggered, the timer pushes an action to a work queue that publishes to the ``Trigger`` channel. As +the sensor thread subscribed to the ``Trigger`` channel, it receives the sensor data. Notice the +VDED executes the ``Blink`` because it also listens to the ``Trigger`` channel. When the sensor data +is ready, the sensor thread publishes it to the ``Sensor data`` channel. The core thread receives +the message as a ``Sensor data`` channel message subscriber, processes the sensor data, and stores +it in an internal sample buffer. It repeats until the sample buffer is full; when it happens, the +core thread aggregates the sample buffer information, prepares a package, and publishes that to the +``Payload`` channel. The Lora thread receives that because it is a ``Payload`` channel message +subscriber and sends the payload to the cloud. When it completes the transmission, the Lora thread +publishes to the ``Transmission done`` channel. The VDED executes the ``Blink`` again since it +listens to the ``Transmission done`` channel. .. figure:: images/zbus_operations.svg - :alt: Zbus sensor-based application - :width: 80% + :alt: ZBus sensor-based application + :width: 85% - Zbus sensor-based application. + ZBus sensor-based application. -This way of implementing the solution makes the application more flexible, enabling us to change things independently. For example, we want to change the trigger from a timer to a button press. We can do that, and the change does not affect other parts of the system. Likewise, we would like to change the communication interface from LoRa to Bluetooth; we only need to change the LoRa thread. No other change is required in order to make that work. Thus, the developer would do that for every block of the image. Based on that, there is a sign zbus promotes decoupling in the system architecture. +This way of implementing the solution makes the application more flexible, enabling us to change +things independently. For example, we want to change the trigger from a timer to a button press. We +can do that, and the change does not affect other parts of the system. Likewise, we would like to +change the communication interface from LoRa to Bluetooth; we only need to change the LoRa thread. +No other change is required in order to make that work. Thus, the developer would do that for every +block of the image. Based on that, there is a sign zbus promotes decoupling in the system +architecture. -Another important aspect of using zbus is the reuse of system modules. If a code portion with well-defined behaviors (we call that module) only uses zbus channels and not hardware interfaces, it can easily be reused in other solutions. The new solution must implement the interfaces (set of channels) the module needs to work. That indicates zbus could improve the module reuse. +Another important aspect of using zbus is the reuse of system modules. If a code portion with +well-defined behaviors (we call that module) only uses zbus channels and not hardware interfaces, it +can easily be reused in other solutions. The new solution must implement the interfaces (set of +channels) the module needs to work. That indicates zbus could improve the module reuse. -The last important note is the zbus solution reach. We can count on many ways of using zbus to enable the developer to be as free as possible to create what they need. For example, messages can be dynamic or static allocated; notifications can be synchronous or asynchronous; the developer can control the channel in so many different ways claiming the channel, developers can add their metadata information to a channel by using the user-data field, the discretionary use of a validator enables the systems to be accurate over message format, and so on. Those characteristics increase the solutions that can be done with zbus and make it a good fit as an open-source community tool. +The last important note is the zbus solution reach. We can count on many ways of using zbus to +enable the developer to be as free as possible to create what they need. For example, messages can +be dynamic or static allocated; notifications can be synchronous or asynchronous; the developer can +control the channel in so many different ways claiming the channel, developers can add their +metadata information to a channel by using the user-data field, the discretionary use of a validator +enables the systems to be accurate over message format, and so on. Those characteristics increase +the solutions that can be done with zbus and make it a good fit as an open-source community tool. .. _Virtual Distributed Event Dispatcher: @@ -60,108 +146,227 @@ The last important note is the zbus solution reach. We can count on many ways of Virtual Distributed Event Dispatcher ==================================== -The VDED execution always happens in the publishing's (thread) context. So it cannot occur inside an Interrupt Service Routine (ISR). Therefore, the IRSs must only access channels indirectly. The basic description of the execution is as follows: +The VDED execution always happens in the publishing's (thread) context. So it cannot occur inside an +Interrupt Service Routine (ISR). Therefore, the IRSs must only access channels indirectly. The basic +description of the execution is as follows: * The channel mutex is acquired; * The channel receives the new message via direct copy (by a raw :c:func:`memcpy`); -* The event dispatcher logic executes the listeners and pushes the channel's reference to the subscribers' notification message queue in the same sequence they appear on the channel observers' list. The listeners can perform non-copy quick access to the constant message reference directly (via the :c:func:`zbus_chan_const_msg` function) since the channel is still locked; +* The event dispatcher logic executes the listeners, sends a copy of the message to the message + subscribers, and pushes the channel's reference to the subscribers' notification message queue in + the same sequence they appear on the channel observers' list. The listeners can perform non-copy + quick access to the constant message reference directly (via the :c:func:`zbus_chan_const_msg` + function) since the channel is still locked; * At last, the publishing function unlocks the channel. -To illustrate the VDED execution, consider the example illustrated below. We have four threads in ascending priority T1, T2, T3, and T4 (the highest priority); two listeners, L1 and L2; and channel A. Supposing L1, L2, T2, T3, and T4 observer channel A. +To illustrate the VDED execution, consider the example illustrated below. We have four threads in +ascending priority ``S1``, ``MS2``, ``MS1``, and ``T1`` (the highest priority); two listeners, +``L1`` and ``L2``; and channel A. Supposing ``L1``, ``L2``, ``MS1``, ``MS2``, and ``S1`` observer +channel A. .. figure:: images/zbus_publishing_process_example_scenario.svg - :alt: Zbus example scenario - :width: 55% + :alt: ZBus example scenario + :width: 45% - Zbus VDED execution example scenario. + ZBus VDED execution example scenario. The following code implements channel A. Note the ``struct a_msg`` is illustrative only. .. code-block:: c - ZBUS_CHAN_DEFINE(a_chan, /* Name */ - struct a_msg, /* Message type */ + ZBUS_CHAN_DEFINE(a_chan, /* Name */ + struct a_msg, /* Message type */ - NULL, /* Validator */ - NULL, /* User Data */ - ZBUS_OBSERVERS(L1, L2, T2, T3, T4), /* observers */ - ZBUS_MSG_INIT(0) /* Initial value {0} */ + NULL, /* Validator */ + NULL, /* User Data */ + ZBUS_OBSERVERS(L1, L2, MS1, MS2, S1), /* observers */ + ZBUS_MSG_INIT(0) /* Initial value {0} */ ); -In the figure below, the letters indicate some action related to the VDED execution. The X-axis represents the time, and the Y-axis represents the priority of threads. Channel A's message, represented by a voice balloon, is only one memory portion (shared memory). It appears several times only as an illustration of the message at that point in time. +In the figure below, the letters indicate some action related to the VDED execution. The X-axis +represents the time, and the Y-axis represents the priority of threads. Channel A's message, +represented by a voice balloon, is only one memory portion (shared memory). It appears several times +only as an illustration of the message at that point in time. .. figure:: images/zbus_publishing_process_example.svg - :alt: Zbus publish processing detail + :alt: ZBus publish processing detail :width: 85% - Zbus VDED execution detail. + ZBus VDED execution detail for priority T1 > MS1 > MS2 > S1. -The figure above illustrates the actions performed during the VDED execution when T1 publishes to channel A. Thus, the figure below describes the actions (represented by a letter) of the VDED execution. +The figure above illustrates the actions performed during the VDED execution when T1 publishes to +channel A. Thus, the table below describes the activities (represented by a letter) of the VDED +execution. The scenario considers the following priorities: T1 > MS1 > MS2 > S1. T1 has the highest +priority. -.. list-table:: VDED execution steps in detail. +.. list-table:: VDED execution steps in detail for priority T1 > MS1 > MS2 > S1. :widths: 5 65 :header-rows: 1 * - Actions - Description * - a - - T1 starts and at some point, publishes to channel A. + - T1 starts and, at some point, publishes to channel A. * - b - The publishing (VDED) process starts. The VDED locks the channel A's mutex. * - c - The VDED copies the T1 message to the channel A message. * - d, e - - The VDED executes L1 and L2 in the respective sequence. Inside the listeners, usually, there is a call to the :c:func:`zbus_chan_const_msg` function, which provides a direct constant reference to channel A's message. It is quick, and no copy is needed here. - - * - f, g, h - - The VDED pushes the notification message to queues of T2, T3, and T4 sequentially. Notice the threads get ready to execute right after receiving the notification. However, they go to a pending state because they cannot access the channel since it is still locked. At that moment, the T1 thread gets its priority elevated (priority inheritance due to the mutex) to the highest pending thread (caused by channel A unavailability). In that case, T4's priority. It ensures the T1 will finish the VDED execution as quickly as possible without preemption from threads with priority below the engaged ones. + - The VDED executes L1 and L2 in the respective sequence. Inside the listeners, usually, there + is a call to the :c:func:`zbus_chan_const_msg` function, which provides a direct constant + reference to channel A's message. It is quick, and no copy is needed here. + + * - f, g + - The VDED copies the message and sends that to MS1 and MS2 sequentially. Notice the threads + get ready to execute right after receiving the notification. However, they go to a pending + state because they have less priority than T1. + * - h + - The VDED pushes the notification message to the queue of S1. Notice the thread gets ready to + execute right after receiving the notification. However, it goes to a pending state because + it cannot access the channel since it is still locked. * - i - VDED finishes the publishing by unlocking channel A. - * - j, k - - The T4 leaves the pending state since channel A is not locked. It gets in the CPU again and starts executing. As it did receive a notification from channel A, it performs a channel read (as simple as lock, memory copy, unlock), continues its execution, and goes out the CPU. + * - j, k, l + - The S1 leaves the pending state since channel A is not locked. It gets in the CPU again and + starts executing. As it did receive a notification from channel A, it performs a channel read + (as simple as lock, memory copy, unlock), continues its execution, and goes out the CPU. + * - m + - S1 goes out of the MCU. + + * - n, o + - MS2 and MS1 execute and finish their workload. - * - l,m, n - - Now, T3 can access the channel. It repeats the same steps from T4 (j and k). T2 does the same. That is the end of the VDED execution! + +The figure below illustrates the actions performed during the VDED execution when T1 publishes to +channel A. The scenario considers the following priorities: T1 < MS1 < MS2 < S1. + +.. figure:: images/zbus_publishing_process_example2.svg + :alt: ZBus publish processing detail + :width: 85% + + ZBus VDED execution detail for priority T1 < MS1 < MS2 < S1. + +Thus, the table below describes the activities (represented by a letter) of the VDED execution. + +.. list-table:: VDED execution steps in detail for priority T1 < MS1 < MS2 < S1. + :widths: 5 65 + :header-rows: 1 + + * - Actions + - Description + * - a + - T1 starts and, at some point, publishes to channel A. + * - b + - The publishing (VDED) process starts. The VDED locks the channel A's mutex. + * - c + - The VDED copies the T1 message to the channel A message. + + * - d, e + - The VDED executes L1 and L2 in the respective sequence. Inside the listeners, usually, there + is a call to the :c:func:`zbus_chan_const_msg` function, which provides a direct constant + reference to channel A's message. It is quick, and no copy is needed here. + + * - f + - The VDED copies the message and sends that to MS1. MS1 preempts T1 and starts working. + After that, the T1 regain MCU. + + * - g + - The VDED copies the message and sends that to MS2. MS2 preempts T1 and starts working. + After that, the T1 regain MCU. + + * - h + - The VDED pushes the notification message to the queue of S1. Notice the thread gets ready to + execute right after receiving the notification. However, it goes to a pending state because + it cannot access the channel since it is still locked. At that moment, the T1 thread gets its + priority elevated (priority inheritance due to the mutex) to the highest pending thread + (caused by channel A unavailability). In that case, S1's priority. It ensures the T1 will + finish the VDED execution as quickly as possible without preemption from threads with + priority below the engaged ones. + + * - i + - VDED finishes the publishing by unlocking channel A. + + * - j, k, l + - The S1 leaves the pending state since channel A is not locked. It gets in the CPU again and + starts executing. As it did receive a notification from channel A, it performs a channel read + (as simple as lock, memory copy, unlock), continues its execution, and goes out the CPU. Limitations =========== -Based on the fact that developers can use zbus to solve many different problems, some challenges arise. Zbus will not solve every problem, so it is necessary to analyze the situation to be sure zbus is applicable. For instance, based on the zbus benchmark, it would not be well suited to a high-speed stream of bytes between threads. The `Pipe` kernel object solves this kind of need. +Based on the fact that developers can use zbus to solve many different problems, some challenges +arise. ZBus will not solve every problem, so it is necessary to analyze the situation to be sure +zbus is applicable. For instance, based on the zbus benchmark, it would not be well suited to a +high-speed stream of bytes between threads. The `Pipe` kernel object solves this kind of need. Delivery guarantees ------------------- -Zbus always delivers the messages to the listeners. However, there are no message delivery guarantees for subscribers because zbus only sends the notification, but the message reading depends on the subscriber's implementation. This is because channels have a mutex protected singleton objects for which message transfer is used. In other words, it can be seen as a single size queue where publishers always overwrite if queue is full. It is possible to increase the delivery rate by following design tips: +ZBus always delivers the messages to the listeners and message subscribers. However, there are no +message delivery guarantees for subscribers because zbus only sends the notification, but the +message reading depends on the subscriber's implementation. It is possible to increase the delivery +rate by following design tips: -* Keep the listeners quick-as-possible (deal with them as ISRs). If some processing is needed, consider submitting a work to a work-queue; +* Keep the listeners quick-as-possible (deal with them as ISRs). If some processing is needed, + consider submitting a work to a work-queue; * Try to give producers a high priority to avoid losses; * Leave spare CPU for observers to consume data produced; * Consider using message queues or pipes for intensive byte transfers. +.. warning:: + ZBus uses :zephyr_file:`include/zephyr/net/buf.h` (network buffers) to exchange data with message + subscribers. So, chose carefully the configurations + :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE` and + :kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE`. They are crucial to a proper VDED execution + (delivery garantee) considering message subscribers. + +.. warning:: + Subscribers will receive only the reference of the changing channel. A data loss may be perceived + if the channel is published twice before the subscriber reads it. The second publication + overwrites the value from the first. Thus, the subscriber will receive two notifications, but + only the last data is there. + + + +.. _zbus delivery sequence: Message delivery sequence ------------------------- -The listeners (synchronous observers) will follow the channel definition sequence as the notification and message consumption sequence. However, the subscribers, as they have an asynchronous nature, will all receive the notification as the channel definition sequence but only will consume the data when they execute again. Hence, the delivery respects the order, but the priority assigned to the subscribers will define the reaction sequence. The delivery sequence is first the static observers and then the runtime ones. +The message delivery will follow the precedence: + +#. Observers defined in a channel using the :c:macro:`ZBUS_CHAN_DEFINE` (following the definition + sequence); +#. Observers defined using the :c:macro:`ZBUS_CHAN_ADD_OBS` based on the sequence priority + (parameter of the macro); +#. The latest is the runtime observers in the addition sequence using the + :c:func:`zbus_chan_add_obs`. + +.. note:: + The VDED will ignore all disabled observers or observations. Usage ***** -Zbus operation depends on channels and observers. Therefore, it is necessary to determine its message and observers list during the channel definition. A message is a regular C struct; the observer can be a subscriber (asynchronous) or a listener (synchronous). +ZBus operation depends on channels and observers. Therefore, it is necessary to determine its +message and observers list during the channel definition. A message is a regular C struct; the +observer can be a subscriber (asynchronous), a message subscriber (asynchronous), or a listener +(synchronous). -The following code defines and initializes a regular channel and its dependencies. This channel exchanges accelerometer data, for example. +The following code defines and initializes a regular channel and its dependencies. This channel +exchanges accelerometer data, for example. .. code-block:: c @@ -176,7 +381,8 @@ The following code defines and initializes a regular channel and its dependencie NULL, /* Validator */ NULL, /* User Data */ - ZBUS_OBSERVERS(my_listener, my_subscriber), /* observers */ + ZBUS_OBSERVERS(my_listener, my_subscriber, + my_msg_subscriber), /* observers */ ZBUS_MSG_INIT(.x = 0, .y = 0, .z = 0) /* Initial value */ ); @@ -212,13 +418,44 @@ The following code defines and initializes a regular channel and its dependencie } K_THREAD_DEFINE(subscriber_task_id, 512, subscriber_task, NULL, NULL, NULL, 3, 0, 0); -It is possible to add static observers to a channel using the :c:macro:`ZBUS_CHAN_ADD_OBS`. We call that a post-definition static observer. The command enables us to indicate an initialization priority that affects the observers' initialization order. The priority param only affects the post-definition static observers. There is no possibility to overwrite the execution sequence of the static observers. + ZBUS_MSG_SUBSCRIBER_DEFINE(my_msg_subscriber); + static void msg_subscriber_task(void *sub) + { + const struct zbus_channel *chan; + + struct acc_msg acc = {0}; + + while (!zbus_sub_wait_msg(&my_msg_subscriber, &chan, &acc, K_FOREVER)) { + if (&acc_chan == chan) { + LOG_INF("From msg subscriber -> Acc x=%d, y=%d, z=%d", acc.x, acc.y, acc.z); + } + } + } + K_THREAD_DEFINE(msg_subscriber_task_id, 1024, msg_subscriber_task, NULL, NULL, NULL, 3, 0, 0); + + + +It is possible to add static observers to a channel using the :c:macro:`ZBUS_CHAN_ADD_OBS`. We call +that a post-definition static observer. The command enables us to indicate an initialization +priority that affects the observers' initialization order. The sequence priority param only affects +the post-definition static observers. There is no possibility to overwrite the message delivery +sequence of the static observers. .. note:: - It is unnecessary to claim/lock a channel before accessing the message inside the listener since the event dispatcher calls listeners with the notifying channel already locked. Subscribers, however, must claim/lock that or use regular read operations to access the message after being notified. + It is unnecessary to claim/lock a channel before accessing the message inside the listener since + the event dispatcher calls listeners with the notifying channel already locked. Subscribers, + however, must claim/lock that or use regular read operations to access the message after being + notified. -Channels can have a ``validator function`` that enables a channel to accept only valid messages. Publish attempts invalidated by hard channels will return immediately with an error code. This allows original creators of a channel to exert some authority over other developers/publishers who may want to piggy-back on their channels. The following code defines and initializes a :dfn:`hard channel` and its dependencies. Only valid messages can be published to a :dfn:`hard channel`. It is possible because a ``validator function`` was passed to the channel's definition. In this example, only messages with ``move`` equal to 0, -1, and 1 are valid. Publish function will discard all other values to ``move``. +Channels can have a `validator function` that enables a channel to accept only valid messages. +Publish attempts invalidated by hard channels will return immediately with an error code. This +allows original creators of a channel to exert some authority over other developers/publishers who +may want to piggy-back on their channels. The following code defines and initializes a :dfn:`hard +channel` and its dependencies. Only valid messages can be published to a :dfn:`hard channel`. It is +possible because a `validator function` was passed to the channel's definition. In this example, +only messages with ``move`` equal to 0, -1, and 1 are valid. Publish function will discard all other +values to ``move``. .. code-block:: c @@ -251,7 +488,11 @@ The following sections describe in detail how to use zbus features. Publishing to a channel ======================= -Messages are published to a channel in zbus by calling :c:func:`zbus_chan_pub`. For example, the following code builds on the examples above and publishes to channel ``acc_chan``. The code is trying to publish the message ``acc1`` to channel ``acc_chan``, and it will wait up to one second for the message to be published. Otherwise, the operation fails. As can be inferred from the code sample, it's OK to use stack allocated messages since VDED copies the data internally. +Messages are published to a channel in zbus by calling :c:func:`zbus_chan_pub`. For example, the +following code builds on the examples above and publishes to channel ``acc_chan``. The code is +trying to publish the message ``acc1`` to channel ``acc_chan``, and it will wait up to one second +for the message to be published. Otherwise, the operation fails. As can be inferred from the code +sample, it's OK to use stack allocated messages since VDED copies the data internally. .. code-block:: c @@ -266,7 +507,9 @@ Messages are published to a channel in zbus by calling :c:func:`zbus_chan_pub`. Reading from a channel ====================== -Messages are read from a channel in zbus by calling :c:func:`zbus_chan_read`. So, for example, the following code tries to read the channel ``acc_chan``, which will wait up to 500 milliseconds to read the message. Otherwise, the operation fails. +Messages are read from a channel in zbus by calling :c:func:`zbus_chan_read`. So, for example, the +following code tries to read the channel ``acc_chan``, which will wait up to 500 milliseconds to +read the message. Otherwise, the operation fails. .. code-block:: c @@ -277,12 +520,20 @@ Messages are read from a channel in zbus by calling :c:func:`zbus_chan_read`. So Do not use this function inside an ISR. .. warning:: - Choose the timeout of :c:func:`zbus_chan_read` after receiving a notification from :c:func:`zbus_sub_wait` carefully because the channel will always be unavailable during the VDED execution. Using ``K_NO_WAIT`` for reading is highly likely to return a timeout error if there are more than one subscriber. For example, consider the VDED illustration again and notice how ``T3`` and ``T4's`` read attempts would definitely fail with K_NO_WAIT. For more details, check the `Virtual Distributed Event Dispatcher`_ section. + Choose the timeout of :c:func:`zbus_chan_read` after receiving a notification from + :c:func:`zbus_sub_wait` carefully because the channel will always be unavailable during the VDED + execution. Using ``K_NO_WAIT`` for reading is highly likely to return a timeout error if there + are more than one subscriber. For example, consider the VDED illustration again and notice how + ``S1`` read attempts would definitely fail with K_NO_WAIT. For more details, check + the `Virtual Distributed Event Dispatcher`_ section. -Forcing channel notification -============================ +Notifying a channel +=================== -It is possible to force zbus to notify a channel's observers by calling :c:func:`zbus_chan_notify`. For example, the following code builds on the examples above and forces a notification for the channel ``acc_chan``. Note this can send events with no message, which does not require any data exchange. See the code example under `Claim and finish a channel`_ where this may become useful. +It is possible to force zbus to notify a channel's observers by calling :c:func:`zbus_chan_notify`. +For example, the following code builds on the examples above and forces a notification for the +channel ``acc_chan``. Note this can send events with no message, which does not require any data +exchange. See the code example under `Claim and finish a channel`_ where this may become useful. .. code-block:: c @@ -294,7 +545,13 @@ It is possible to force zbus to notify a channel's observers by calling :c:func: Declaring channels and observers ================================ -For accessing channels or observers from files other than its defining files, it is necessary to declare them by calling :c:macro:`ZBUS_CHAN_DECLARE` and :c:macro:`ZBUS_OBS_DECLARE`. In other words, zbus channel definitions and declarations with the same channel names in different files would point to the same (global) channel. Thus, developers should be careful about existing channels, and naming new channels or linking will fail. It is possible to declare more than one channel or observer on the same call. The following code builds on the examples above and displays the defined channels and observers. +For accessing channels or observers from files other than its defining files, it is necessary to +declare them by calling :c:macro:`ZBUS_CHAN_DECLARE` and :c:macro:`ZBUS_OBS_DECLARE`. In other +words, zbus channel definitions and declarations with the same channel names in different files +would point to the same (global) channel. Thus, developers should be careful about existing +channels, and naming new channels or linking will fail. It is possible to declare more than one +channel or observer on the same call. The following code builds on the examples above and displays +the defined channels and observers. .. code-block:: c @@ -305,7 +562,14 @@ For accessing channels or observers from files other than its defining files, it Iterating over channels and observers ===================================== -Zbus subsystem also implements :ref:`Iterable Sections ` for channels and observers, for which there are supporting APIs like :c:func:`zbus_iterate_over_channels`, :c:func:`zbus_iterate_over_channels_with_user_data`, :c:func:`zbus_iterate_over_observers` and :c:func:`zbus_iterate_over_observers_with_user_data`. This feature enables developers to call a procedure over all declared channels, where the procedure parameter is a :c:struct:`zbus_channel`. The execution sequence is in the alphabetical name order of the channels (see :ref:`Iterable Sections ` documentation for details). Zbus also implements this feature for :c:struct:`zbus_observer`. +ZBus subsystem also implements :ref:`Iterable Sections ` for channels and +observers, for which there are supporting APIs like :c:func:`zbus_iterate_over_channels`, +:c:func:`zbus_iterate_over_channels_with_user_data`, :c:func:`zbus_iterate_over_observers` and +:c:func:`zbus_iterate_over_observers_with_user_data`. This feature enables developers to call a +procedure over all declared channels, where the procedure parameter is a :c:struct:`zbus_channel`. +The execution sequence is in the alphabetical name order of the channels (see :ref:`Iterable +Sections ` documentation for details). ZBus also implements this feature for +:c:struct:`zbus_observer`. .. code-block:: c @@ -389,12 +653,17 @@ The code will log the following output: Advanced channel control ======================== -Zbus was designed to be as flexible and extensible as possible. Thus, there are some features designed to provide some control and extensibility to the bus. +ZBus was designed to be as flexible and extensible as possible. Thus, there are some features +designed to provide some control and extensibility to the bus. Listeners message access ------------------------ -For performance purposes, listeners can access the receiving channel message directly since they already have the mutex lock for it. To access the channel's message, the listener should use the :c:func:`zbus_chan_const_msg` because the channel passed as an argument to the listener function is a constant pointer to the channel. The const pointer return type tells developers not to modify the message. +For performance purposes, listeners can access the receiving channel message directly since they +already have the mutex lock for it. To access the channel's message, the listener should use the +:c:func:`zbus_chan_const_msg` because the channel passed as an argument to the listener function is +a constant pointer to the channel. The const pointer return type tells developers not to modify the +message. .. code-block:: c @@ -412,21 +681,32 @@ For performance purposes, listeners can access the receiving channel message dir User Data --------- -It is possible to pass custom data into the channel's ``user_data`` for various purposes, such as writing channel metadata. That can be achieved by passing a pointer to the channel definition macro's ``user_data`` field, which will then be accessible by others. Note that ``user_data`` is individual for each channel. Also, note that ``user_data`` access is not thread-safe. For thread-safe access to ``user_data``, see the next section. +It is possible to pass custom data into the channel's ``user_data`` for various purposes, such as +writing channel metadata. That can be achieved by passing a pointer to the channel definition +macro's ``user_data`` field, which will then be accessible by others. Note that ``user_data`` is +individual for each channel. Also, note that ``user_data`` access is not thread-safe. For +thread-safe access to ``user_data``, see the next section. Claim and finish a channel -------------------------- -To take more control over channels, two functions were added :c:func:`zbus_chan_claim` and :c:func:`zbus_chan_finish`. With these functions, it is possible to access the channel's metadata safely. When a channel is claimed, no actions are available to that channel. After finishing the channel, all the actions are available again. +To take more control over channels, two functions were added :c:func:`zbus_chan_claim` and +:c:func:`zbus_chan_finish`. With these functions, it is possible to access the channel's metadata +safely. When a channel is claimed, no actions are available to that channel. After finishing the +channel, all the actions are available again. .. warning:: - Never change the fields of the channel struct directly. It may cause zbus behavior inconsistencies and scheduling issues. + Never change the fields of the channel struct directly. It may cause zbus behavior + inconsistencies and scheduling issues. .. warning:: Do not use these functions inside an ISR. -The following code builds on the examples above and claims the ``acc_chan`` to set the ``user_data`` to the channel. Suppose we would like to count how many times the channels exchange messages. We defined the ``user_data`` to have the 32 bits integer. This code could be added to the listener code described above. +The following code builds on the examples above and claims the ``acc_chan`` to set the ``user_data`` +to the channel. Suppose we would like to count how many times the channels exchange messages. We +defined the ``user_data`` to have the 32 bits integer. This code could be added to the listener code +described above. .. code-block:: c @@ -463,7 +743,11 @@ The following code has the exact behavior of the code in :ref:`reading from a ch Runtime observer registration ----------------------------- -It is possible to add observers to channels in runtime. This feature uses the heap to allocate the nodes dynamically. The heap size limits the number of dynamic observers Zbus can create. Therefore, set the :kconfig:option:`CONFIG_ZBUS_RUNTIME_OBSERVERS` to enable the feature. It is possible to adjust the heap size by changing the configuration :kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE`. The following example illustrates the runtime registration usage. +It is possible to add observers to channels in runtime. This feature uses the heap to allocate the +nodes dynamically. The heap size limits the number of dynamic observers zbus can create. Therefore, +set the :kconfig:option:`CONFIG_ZBUS_RUNTIME_OBSERVERS` to enable the feature. It is possible to +adjust the heap size by changing the configuration :kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE`. The +following example illustrates the runtime registration usage. @@ -482,23 +766,40 @@ It is possible to add observers to channels in runtime. This feature uses the he Samples ******* -For a complete overview of zbus usage, take a look at the samples. There are the following samples available: +For a complete overview of zbus usage, take a look at the samples. There are the following samples +available: * :zephyr:code-sample:`zbus-hello-world` illustrates the code used above in action; -* :zephyr:code-sample:`zbus-work-queue` shows how to define and use different kinds of observers. Note there is an example of using a work queue instead of executing the listener as an execution option; -* :zephyr:code-sample:`zbus-dyn-channel` demonstrates how to use dynamically allocated exchanging data in zbus; -* :zephyr:code-sample:`zbus-uart-bridge` shows an example of sending the operation of the channel to a host via serial; -* :zephyr:code-sample:`zbus-remote-mock` illustrates how to implement an external mock (on the host) to send and receive messages to and from the bus. -* :zephyr:code-sample:`zbus-runtime-obs-registration` illustrates a way of using the runtime observer registration feature; +* :zephyr:code-sample:`zbus-work-queue` shows how to define and use different kinds of observers. + Note there is an example of using a work queue instead of executing the listener as an execution + option; +* :zephyr:code-sample:`zbus-msg-subscriber` illustrates how to use message subscribers; +* :zephyr:code-sample:`zbus-dyn-channel` demonstrates how to use dynamically allocated exchanging + data in zbus; +* :zephyr:code-sample:`zbus-uart-bridge` shows an example of sending the operation of the channel to + a host via serial; +* :zephyr:code-sample:`zbus-remote-mock` illustrates how to implement an external mock (on the host) + to send and receive messages to and from the bus; +* :zephyr:code-sample:`zbus-runtime-obs-registration` illustrates a way of using the runtime + observer registration feature; +* :zephyr:code-sample:`zbus-confirmed-channel` implements a way of implement confirmed channel only + with subscribers; * :zephyr:code-sample:`zbus-benchmark` implements a benchmark with different combinations of inputs. Suggested Uses ************** -Use zbus to transfer data (messages) between threads in one-to-one, one-to-many, and many-to-many synchronously or asynchronously. Choosing the proper observer type is crucial. Use subscribers for scenarios that can tolerate message losses and duplications; when they cannot, use listeners. In addition to the listener, another asynchronous message processing mechanism (like :ref:`message queues `) may be necessary to retain the pending message until it gets processed. +Use zbus to transfer data (messages) between threads in one-to-one, one-to-many, and many-to-many +synchronously or asynchronously. Choosing the proper observer type is crucial. Use subscribers for +scenarios that can tolerate message losses and duplications; when they cannot, use message +subscribers (if you need a thread) or listeners (if you need to be lean and fast). In addition to +the listener, another asynchronous message processing mechanism (like :ref:`message queues +`) may be necessary to retain the pending message until it gets processed. .. note:: - Zbus can be used to transfer streams from the producer to the consumer. However, this can increase zbus' communication latency. So maybe consider a Pipe a good alternative for this communication topology. + ZBus can be used to transfer streams from the producer to the consumer. However, this can + increase zbus' communication latency. So maybe consider a Pipe a good alternative for this + communication topology. Configuration Options ********************* @@ -507,10 +808,22 @@ For enabling zbus, it is necessary to enable the :kconfig:option:`CONFIG_ZBUS` o Related configuration options: -* :kconfig:option:`CONFIG_ZBUS_CHANNEL_NAME` enables the name of channels to be available inside the channels metadata. The log uses this information to show the channels' names; -* :kconfig:option:`CONFIG_ZBUS_OBSERVER_NAME` enables the name of observers to be available inside the channels metadata; +* :kconfig:option:`CONFIG_ZBUS_CHANNELS_SYS_INIT_PRIORITY` determine the :c:macro:`SYS_INIT` + priority used by zbus to organize the channels observations by channel; +* :kconfig:option:`CONFIG_ZBUS_CHANNEL_NAME` enables the name of channels to be available inside the + channels metadata. The log uses this information to show the channels' names; +* :kconfig:option:`CONFIG_ZBUS_OBSERVER_NAME` enables the name of observers to be available inside + the channels metadata; +* :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER` enables the message subscriber observer type; +* :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC` uses the heap to allocate message + buffers; +* :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC` uses the stack to allocate message + buffers; +* :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE` the available number of message + buffers to be used simultaneously; +* :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE` the biggest message of zbus + channels to be transported into a message buffer; * :kconfig:option:`CONFIG_ZBUS_RUNTIME_OBSERVERS` enables the runtime observer registration. -* :kconfig:option:`CONFIG_ZBUS_CHANNELS_SYS_INIT_PRIORITY` determine the :c:macro:`SYS_INIT` priority used by Zbus to organize the channels observations by channel. API Reference ************* From 28eb47922ed5673be25b6ee00a744baef7345189 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Wed, 11 Oct 2023 08:44:44 -0300 Subject: [PATCH 1914/4498] doc: zbus: add entries to the migration guide ZBus had one break change related to the runtime observers' configuration, and the VDED delivery sequence has changed. This commit adds entries on the migration guide about the mentioned changes. Signed-off-by: Rodrigo Peixoto --- doc/releases/migration-guide-3.5.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 4bb9ca28fe0..22fa8558655 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -271,6 +271,17 @@ Required changes * The :kconfig:option:`CONFIG_RISCV_MTVEC_VECTORED_MODE` Kconfig option was renamed to :kconfig:option:`CONFIG_RISCV_VECTORED_MODE`. +* ZBus runtime observers implementation now relies on the HEAP memory instead of a memory slab. + Thus, zbus' configuration (kconfig) related to runtime observers has changed. To keep your runtime + observers code working correctly, you need to: + + - Replace the integer ``CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE`` with the boolean + :kconfig:option:`CONFIG_ZBUS_RUNTIME_OBSERVERS`; + - Set the HEAP size with the :kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE`. + +* The zbus VDED delivery sequence has changed. Check the :ref:`documentation` to verify if it will affect your code. + Recommended Changes ******************* From de85a208a04dc875e95222ca180a026e97699503 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 9 Oct 2023 10:48:50 +0200 Subject: [PATCH 1915/4498] cmake: extensions: Robustify dt_node_has_status Calling this function with an output variable named `var` or `okay` could produce an incorrect result, due to the variable being mishandled. Add simple changes to avoid this. Signed-off-by: Grzegorz Swiderski --- cmake/modules/extensions.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 1e38ae7ba72..0c79947cd37 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -3267,13 +3267,13 @@ function(dt_node_has_status var) return() endif() - dt_prop(${var} PATH ${canonical} PROPERTY status) + dt_prop(status PATH ${canonical} PROPERTY status) - if(NOT DEFINED ${var} OR "${${var}}" STREQUAL ok) - set(${var} okay) + if(NOT DEFINED status OR status STREQUAL "ok") + set(status "okay") endif() - if(${var} STREQUAL ${DT_NODE_STATUS}) + if(status STREQUAL "${DT_NODE_STATUS}") set(${var} TRUE PARENT_SCOPE) else() set(${var} FALSE PARENT_SCOPE) From 5cf5282e60ba0a9df91690a4a08a5900bca7b818 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 9 Oct 2023 10:48:50 +0200 Subject: [PATCH 1916/4498] cmake: extensions: Check status of "zephyr,memory-region" DT nodes Functions `zephyr_linker_dts_memory()` and `zephyr_linker_dts_section()` are described as defining a memory region or section based on a DT node, as long as it "exists and has status okay". However, only the existence of the node is actually checked, using `dt_node_exists()`. To fix that, employ `dt_node_has_status()` instead, which can check both conditions. The status check is important, because both functions require the given DT node to contain a `zephyr,memory-region` property (not to be confused with the compatible string). This property is required by the associated binding as well, but required properties can be omitted from nodes which don't have status "okay". In those cases, edtlib won't raise an error, and neither should CMake, because those nodes should be ignored. Speaking of that property, add a missing error check for it as a bonus (tucked behind the status check, of course). Signed-off-by: Grzegorz Swiderski --- cmake/modules/extensions.cmake | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 0c79947cd37..061ed7747c1 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -4049,8 +4049,8 @@ function(zephyr_linker_dts_section) ) endif() - dt_node_exists(exists PATH ${DTS_SECTION_PATH}) - if(NOT ${exists}) + dt_node_has_status(okay PATH ${DTS_SECTION_PATH} STATUS okay) + if(NOT ${okay}) return() endif() @@ -4122,14 +4122,19 @@ function(zephyr_linker_dts_memory) return() endif() - dt_node_exists(exists PATH ${DTS_MEMORY_PATH}) - if(NOT ${exists}) + dt_node_has_status(okay PATH ${DTS_MEMORY_PATH} STATUS okay) + if(NOT ${okay}) return() endif() dt_reg_addr(addr PATH ${DTS_MEMORY_PATH}) dt_reg_size(size PATH ${DTS_MEMORY_PATH}) dt_prop(name PATH ${DTS_MEMORY_PATH} PROPERTY "zephyr,memory-region") + if(NOT DEFINED name) + message(FATAL_ERROR "zephyr_linker_dts_memory(${ARGV0} ...) missing " + "\"zephyr,memory-region\" property" + ) + endif() zephyr_string(SANITIZE name ${name}) zephyr_linker_memory( From 37b6ddd918be0479e90646bfdf608f0c48ff56a2 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 10 Oct 2023 12:53:25 +0200 Subject: [PATCH 1917/4498] Bluetooth: BAP: Broadcast Sink only set synced BIS indexes When updating the Scan Delegator receive state, we shall only set the BIS indexes in bis_sync that we are actually synced to. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 9 ++++++++- subsys/bluetooth/audio/bap_endpoint.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 296989244af..f9592d22b03 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -109,12 +109,17 @@ static void update_recv_state_big_synced(const struct bt_bap_broadcast_sink *sin struct bt_bap_scan_delegator_subgroup *subgroup_param = &mod_src_param.subgroups[i]; const struct bt_bap_base_subgroup *subgroup = &base->subgroups[i]; - /* Update the BIS sync indexes for the subgroup */ + /* Update the BIS sync indexes for the subgroup based on the BASE*/ for (size_t j = 0U; j < subgroup->bis_count; j++) { const struct bt_bap_base_bis_data *bis_data = &subgroup->bis_data[j]; subgroup_param->bis_sync |= BIT(bis_data->index); } + + /* Update the bis_sync so that the bis_sync value only contains the indexes that we + * are actually synced to + */ + subgroup_param->bis_sync &= sink->indexes_bitfield; } if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ) { @@ -776,6 +781,7 @@ static void broadcast_sink_cleanup_streams(struct bt_bap_broadcast_sink *sink) } sink->stream_count = 0; + sink->indexes_bitfield = 0U; } static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink) @@ -1017,6 +1023,7 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde return err; } + sink->indexes_bitfield = indexes_bitfield; for (size_t i = 0; i < stream_count; i++) { struct bt_bap_ep *ep = streams[i]->ep; diff --git a/subsys/bluetooth/audio/bap_endpoint.h b/subsys/bluetooth/audio/bap_endpoint.h index a13a14d54dd..46ef3031e68 100644 --- a/subsys/bluetooth/audio/bap_endpoint.h +++ b/subsys/bluetooth/audio/bap_endpoint.h @@ -125,6 +125,7 @@ struct bt_bap_broadcast_sink { uint16_t iso_interval; uint16_t biginfo_num_bis; uint32_t broadcast_id; /* 24 bit */ + uint32_t indexes_bitfield; struct bt_bap_base base; struct bt_audio_codec_qos codec_qos; struct bt_le_per_adv_sync *pa_sync; From 73398490771970fc099f6f3724ef75fbb1fc8542 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 11 Oct 2023 15:16:59 +0200 Subject: [PATCH 1918/4498] Bluetooth: BAP: Broadcast Sink should not terminate the PA Sync When calling bt_bap_broadcast_sink_delete, the broadcast sink should not attempt to terminate the PA Sync. The PA sync can live on without the broadcast sink, just as the broadcast sink can live on without the PA sync (which is why the PA sync check was completely removed). Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index f9592d22b03..d4d5325ba84 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -1082,8 +1082,6 @@ int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink) { - int err; - CHECKIF(sink == NULL) { LOG_DBG("sink is NULL"); return -EINVAL; @@ -1105,17 +1103,6 @@ int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink) } } - if (sink->pa_sync == NULL) { - LOG_DBG("Broadcast sink is already deleted"); - return -EALREADY; - } - - err = bt_le_per_adv_sync_delete(sink->pa_sync); - if (err != 0) { - LOG_DBG("Failed to delete periodic advertising sync (err %d)", err); - return err; - } - /* Reset the broadcast sink */ broadcast_sink_cleanup(sink); From de67ec9e67d350e311b6071ad7978c7ae553516e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 5 Oct 2023 14:14:04 +0200 Subject: [PATCH 1919/4498] Bluetooth: BAP: Fix broadcast source reconfig with subset of streams When the bt_bap_broadcast_source_reconfig was supplied with a subset of the streams, it would only update the codec cfg and qos for the streams provided in the parameters. This commit changes that, so all streams are properly updated, as they share some common values. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_source.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index b0af0cdf18d..8e5010cc007 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -821,6 +821,7 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, for (size_t i = 0U; i < param->params_count; i++) { const struct bt_bap_broadcast_source_subgroup_param *subgroup_param; struct bt_audio_codec_cfg *codec_cfg; + struct bt_bap_stream *stream; if (i == 0) { subgroup = @@ -837,8 +838,6 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, const struct bt_bap_broadcast_source_stream_param *stream_param; struct bt_audio_broadcast_stream_data *stream_data; struct bt_bap_stream *subgroup_stream; - struct bt_iso_chan_io_qos *iso_qos; - struct bt_bap_stream *stream; size_t stream_idx; stream_param = &subgroup_param->params[j]; @@ -853,14 +852,6 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, stream_idx++; } - iso_qos = stream->ep->iso->chan.qos->tx; - - bt_bap_stream_attach(NULL, stream, stream->ep, codec_cfg); - - bt_audio_codec_qos_to_iso_qos(iso_qos, qos); - bt_audio_codec_cfg_to_iso_path(iso_qos->path, codec_cfg); - stream->qos = qos; - /* Store the BIS specific codec configuration data in the broadcast source. * It is stored in the broadcast* source, instead of the stream object, * as this is only relevant for the broadcast source, and not used @@ -870,6 +861,30 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, (void)memcpy(stream_data->data, stream_param->data, stream_param->data_len); stream_data->data_len = stream_param->data_len; } + + /* Apply the codec_cfg to all streams in the subgroup, and not just the ones in the + * params + */ + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) { + struct bt_iso_chan_io_qos *iso_qos; + + iso_qos = stream->ep->iso->chan.qos->tx; + bt_bap_stream_attach(NULL, stream, stream->ep, codec_cfg); + bt_audio_codec_cfg_to_iso_path(iso_qos->path, codec_cfg); + } + } + + /* Finally we apply the new qos and to all streams */ + SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) { + struct bt_bap_stream *stream; + + SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) { + struct bt_iso_chan_io_qos *iso_qos; + + iso_qos = stream->ep->iso->chan.qos->tx; + bt_audio_codec_qos_to_iso_qos(iso_qos, qos); + stream->qos = qos; + } } source->qos = qos; From b63d8ffb2fa9e85c24e9d4b29cf1e6d71d3b9e3b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 5 Oct 2023 14:15:23 +0200 Subject: [PATCH 1920/4498] tests: Bluetooth: BAP: Improve validation of broadcast source reconfig Add verification of all stream's SDU, RTN and PHY rather than just the first. Also add another test case where only a subset of streams are being reconfigured, but where the above values shall be updated for all streams. Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 105 ++++++++++++++++-- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index fab60070ba3..ff974565240 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -176,7 +176,6 @@ ZTEST_SUITE(bap_broadcast_source_test_suite, NULL, bap_broadcast_source_test_sui ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) { struct bt_bap_broadcast_source_param *create_param = fixture->param; - struct bt_bap_stream *stream = create_param->params[0].params[0].stream; int err; printk("Creating broadcast source with %zu subgroups with %zu streams\n", @@ -185,9 +184,19 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_create_delete) err = bt_bap_broadcast_source_create(create_param, &fixture->source); zassert_equal(0, err, "Unable to create broadcast source: err %d", err); - zassert_equal(create_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); - zassert_equal(create_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); - zassert_equal(create_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); + for (size_t i = 0u; i < create_param->params_count; i++) { + for (size_t j = 0u; j < create_param->params[i].params_count; j++) { + const struct bt_bap_stream *stream = + create_param->params[i].params[j].stream; + + zassert_equal(create_param->qos->sdu, stream->qos->sdu, + "Unexpected stream SDU"); + zassert_equal(create_param->qos->rtn, stream->qos->rtn, + "Unexpected stream RTN"); + zassert_equal(create_param->qos->phy, stream->qos->phy, + "Unexpected stream PHY"); + } + } err = bt_bap_broadcast_source_delete(fixture->source); zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); @@ -520,22 +529,84 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_start_inval_doubl zassert_not_equal(0, err, "Did not fail with starting already started source"); } -ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure) +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_single_subgroup) { struct bt_bap_broadcast_source_param *reconf_param = fixture->param; - struct bt_bap_stream *stream = reconf_param->params[0].params[0].stream; + const size_t subgroup_cnt = reconf_param->params_count; int err; printk("Creating broadcast source with %zu subgroups with %zu streams\n", reconf_param->params_count, fixture->stream_cnt); err = bt_bap_broadcast_source_create(reconf_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + for (size_t i = 0u; i < reconf_param->params_count; i++) { + for (size_t j = 0u; j < reconf_param->params[i].params_count; j++) { + const struct bt_bap_stream *stream = + reconf_param->params[i].params[j].stream; + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, + "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, + "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, + "Unexpected stream PHY"); + } + } + + reconf_param->params_count = 1U; + reconf_param->qos->sdu = 100U; + reconf_param->qos->rtn = 3U; + reconf_param->qos->phy = 1U; + + err = bt_bap_broadcast_source_reconfig(fixture->source, reconf_param); + zassert_equal(0, err, "Unable to reconfigure broadcast source: err %d", err); + + for (size_t i = 0u; i < subgroup_cnt; i++) { + for (size_t j = 0u; j < reconf_param->params[i].params_count; j++) { + const struct bt_bap_stream *stream = + reconf_param->params[i].params[j].stream; + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, + "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, + "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, + "Unexpected stream PHY"); + } + } + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} - zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); - zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); - zassert_equal(reconf_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure_all) +{ + struct bt_bap_broadcast_source_param *reconf_param = fixture->param; + int err; + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + reconf_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(reconf_param, &fixture->source); zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + for (size_t i = 0u; i < reconf_param->params_count; i++) { + for (size_t j = 0u; j < reconf_param->params[i].params_count; j++) { + const struct bt_bap_stream *stream = + reconf_param->params[i].params[j].stream; + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, + "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, + "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, + "Unexpected stream PHY"); + } + } + reconf_param->qos->sdu = 100U; reconf_param->qos->rtn = 3U; reconf_param->qos->phy = 1U; @@ -543,9 +614,19 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_reconfigure) err = bt_bap_broadcast_source_reconfig(fixture->source, reconf_param); zassert_equal(0, err, "Unable to reconfigure broadcast source: err %d", err); - zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, "Unexpected stream SDU"); - zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, "Unexpected stream RTN"); - zassert_equal(reconf_param->qos->phy, stream->qos->phy, "Unexpected stream PHY"); + for (size_t i = 0u; i < reconf_param->params_count; i++) { + for (size_t j = 0u; j < reconf_param->params[i].params_count; j++) { + const struct bt_bap_stream *stream = + reconf_param->params[i].params[j].stream; + + zassert_equal(reconf_param->qos->sdu, stream->qos->sdu, + "Unexpected stream SDU"); + zassert_equal(reconf_param->qos->rtn, stream->qos->rtn, + "Unexpected stream RTN"); + zassert_equal(reconf_param->qos->phy, stream->qos->phy, + "Unexpected stream PHY"); + } + } err = bt_bap_broadcast_source_delete(fixture->source); zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); From fc682c35a215883c00f4900becadad832b58b007 Mon Sep 17 00:00:00 2001 From: Yanfeng Liu Date: Wed, 11 Oct 2023 11:25:43 +0800 Subject: [PATCH 1921/4498] doc: build:kconfig:settings align with guidelines use unnumbered list to align with guidelines Signed-off-by: Yanfeng Liu --- doc/build/kconfig/setting.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 2fd78ff463b..38a1fc51e89 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -139,7 +139,7 @@ known as a Kconfig fragment, which are then merged to get the final configuration used for a particular build). By default, :file:`prj.conf` is used. -1. If ``CONF_FILE`` is set, the configuration file(s) specified in it are +#. If ``CONF_FILE`` is set, the configuration file(s) specified in it are merged and used as the application configuration. ``CONF_FILE`` can be set in various ways: @@ -149,25 +149,25 @@ used. 3. From the CMake variable cache -2. Otherwise if ``CONF_FILE`` is set, and a single configuration file of the +#. Otherwise if ``CONF_FILE`` is set, and a single configuration file of the form :file:`prj_.conf` is used, then if file :file:`boards/_.conf` exists in same folder as file :file:`prj_.conf`, the result of merging :file:`prj_.conf` and :file:`boards/_.conf` is used. -3. Otherwise, :file:`prj_.conf` is used if it exists in the application +#. Otherwise, :file:`prj_.conf` is used if it exists in the application configuration directory. -4. Otherwise, if :file:`boards/.conf` exists in the application +#. Otherwise, if :file:`boards/.conf` exists in the application configuration directory, the result of merging it with :file:`prj.conf` is used. -5. Otherwise, if board revisions are used and +#. Otherwise, if board revisions are used and :file:`boards/_.conf` exists in the application configuration directory, the result of merging it with :file:`prj.conf` and :file:`boards/.conf` is used. -6. Otherwise, :file:`prj.conf` is used from the application configuration +#. Otherwise, :file:`prj.conf` is used from the application configuration directory. If it does not exist then a fatal error will be emitted. All configuration files will be taken from the application's configuration From a275e45c856667d687c3092438077e4c75e66788 Mon Sep 17 00:00:00 2001 From: Yanfeng Liu Date: Wed, 11 Oct 2023 11:28:06 +0800 Subject: [PATCH 1922/4498] doc: build:kconfig:settings rewise CONF_FILE description make item#2 as part of item#1 to reduce confusions. Signed-off-by: Yanfeng Liu --- doc/build/kconfig/setting.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 38a1fc51e89..dbc1ff845d8 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -149,8 +149,8 @@ used. 3. From the CMake variable cache -#. Otherwise if ``CONF_FILE`` is set, and a single configuration file of the - form :file:`prj_.conf` is used, then if file + Furthermore if ``CONF_FILE`` is set as single configuration file of the + form :file:`prj_.conf` and if file :file:`boards/_.conf` exists in same folder as file :file:`prj_.conf`, the result of merging :file:`prj_.conf` and :file:`boards/_.conf` is used. From 7ee427ff58958dbf91d4ff8f262fc11a8679b09a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 11 Oct 2023 08:41:12 +0200 Subject: [PATCH 1923/4498] Bluetooth: Controller: Fix CIS encryption when DF support enabled Fix hung Controller when establishing CIS on an encrypted ACL connection with Controller built with direction finding support enabled. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index c6becbe322f..739c2d06962 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -1692,20 +1692,25 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ mode |= (CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; + + if (false) { + #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) - /* When direction finding CTE receive feature is enabled then on-the-fly PDU - * parsing for CTEInfo is always done. In such situation, the CCM TASKS_CRYPT - * must be started with short delay. That give the Radio time to store received bits - * in shared memory. - */ - radio_bc_configure(CCM_TASKS_CRYPT_DELAY_BITS); - radio_bc_status_reset(); - hal_trigger_crypt_by_bcmatch_ppi_config(); - hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_DELAY_PPI)); -#else - hal_trigger_crypt_ppi_config(); - hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI)); + } else if (pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) { + /* When direction finding CTE receive feature is enabled then on-the-fly + * PDU parsing for CTEInfo is always done. In such situation, the CCM + * TASKS_CRYPT must be started with short delay. That give the Radio time + * to store received bits in shared memory. + */ + radio_bc_configure(CCM_TASKS_CRYPT_DELAY_BITS); + radio_bc_status_reset(); + hal_trigger_crypt_by_bcmatch_ppi_config(); + hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_DELAY_PPI)); #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ + } else { + hal_trigger_crypt_ppi_config(); + hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI)); + } break; case PHY_2M: From 2f79f5e992d1cf456ae33b77b5b96f4ea023557d Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Tue, 10 Oct 2023 15:23:56 +0200 Subject: [PATCH 1924/4498] MAINTAINERS: Create dedicated entries for 3rd party toolchains Fixes: #63738 Create dedicated entries for ARC MWDT, arm compiler 6, and one Api toolchains. This helps contributors to identify whom to contact in case of issues related to those toolchains. The Zephyr SDK, cross-compile, and other GCC based compilers are covered as part of the general cmake/toolchain,compiler,linker,bintools entry in the MAINTAINERS file. Signed-off-by: Torsten Rasmussen --- MAINTAINERS.yml | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index d23cf483890..6a1f03bb764 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2795,7 +2795,7 @@ TF-M Integration: labels: - "area: TF-M" -Toolchain Integration: +"Toolchain Integration": status: maintained maintainers: - tejlmand @@ -2809,6 +2809,40 @@ Toolchain Integration: labels: - "area: Toolchains" +"Toolchain ARC MWDT": + status: maintained + maintainers: + - evgeniy-paltsev + - abrodkin + files: + - cmake/*/arcmwdt/ + - include/zephyr/toolchain/mwdt.h + - lib/libc/arcmwdt/* + labels: + - "area: Toolchains" + +"Toolchain arm compiler 6": + status: maintained + maintainers: + - tejlmand + files: + - cmake/*/armclang/ + - cmake/linker/armlink/ + - include/zephyr/toolchain/armclang.h + - lib/libc/armstdc/* + labels: + - "area: Toolchains" + +"Toolchain oneApi": + status: maintained + maintainers: + - nashif + files: + - cmake/*/oneApi/ + - cmake/compiler/icx/ + labels: + - "area: Toolchains" + Tracing: status: maintained maintainers: From 0a16d5c7c332efc13ead8babf512ec0358135eea Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 10 Oct 2023 13:40:08 +0300 Subject: [PATCH 1925/4498] net: socket: mgmt: Check buf size in recvfrom() Return EMSGSIZE if trying to copy too much data into user supplied buffer. Signed-off-by: Jukka Rissanen --- subsys/net/lib/sockets/sockets_net_mgmt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_net_mgmt.c b/subsys/net/lib/sockets/sockets_net_mgmt.c index daccfdf40a6..91e13ec415b 100644 --- a/subsys/net/lib/sockets/sockets_net_mgmt.c +++ b/subsys/net/lib/sockets/sockets_net_mgmt.c @@ -209,8 +209,12 @@ static ssize_t znet_mgmt_recvfrom(struct net_mgmt_socket *mgmt, void *buf, if (info) { ret = info_len + sizeof(hdr); - ret = MIN(max_len, ret); - memcpy(©_to[sizeof(hdr)], info, ret); + if (ret > max_len) { + errno = EMSGSIZE; + return -1; + } + + memcpy(©_to[sizeof(hdr)], info, info_len); } else { ret = 0; } From 5c6dca3c52c0e554331866f69ee52f65d0dfe059 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 10 Oct 2023 13:41:21 +0300 Subject: [PATCH 1926/4498] tests: net: sockets: mgmt: Add tests for too long message Add test that checks we get proper return code if trying to copy too much data. Signed-off-by: Jukka Rissanen --- tests/net/socket/net_mgmt/src/main.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/net/socket/net_mgmt/src/main.c b/tests/net/socket/net_mgmt/src/main.c index a13f4537206..0f5bec63462 100644 --- a/tests/net/socket/net_mgmt/src/main.c +++ b/tests/net/socket/net_mgmt/src/main.c @@ -457,6 +457,34 @@ ZTEST_USER(net_socket_net_mgmt, test_net_mgmt_catch_user) test_net_mgmt_catch_events(); } +static void test_net_mgmt_catch_events_failure(void) +{ +#define SMALL_BUF_LEN 16 + struct sockaddr_nm event_addr; + socklen_t event_addr_len; + uint8_t buf[SMALL_BUF_LEN]; + int ret; + + memset(buf, 0, sizeof(buf)); + event_addr_len = sizeof(event_addr); + + ret = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *)&event_addr, + &event_addr_len); + zassert_equal(ret, -1, "Msg check failed, %d", errno); + zassert_equal(errno, EMSGSIZE, "Msg check failed, errno %d", errno); +} + +ZTEST(net_socket_net_mgmt, test_net_mgmt_catch_failure_kernel) +{ + test_net_mgmt_catch_events_failure(); +} + +ZTEST_USER(net_socket_net_mgmt, test_net_mgmt_catch_failure_user) +{ + test_net_mgmt_catch_events_failure(); +} + ZTEST(net_socket_net_mgmt, test_net_mgmt_cleanup) { k_thread_abort(trigger_events_thread_id); From 04a0cf7d79f2f7fef63b6754b6da1bd85becb3fd Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 10 Oct 2023 14:02:01 -0700 Subject: [PATCH 1927/4498] kernel: deprecate K_THREAD_STACK_MEMBER The macro K_THREAD_STACK_MEMBER has actually been deprecated since v2.4.0 in the macro doxygen description, but it was never marked with __DEPRECATED_MACRO. Since this was being used in various drivers, make it follow the deprecation process. Signed-off-by: Daniel Leung --- doc/kernel/usermode/mpu_stack_objects.rst | 3 +-- drivers/adc/adc_ads1x1x.c | 2 +- drivers/adc/adc_b91.c | 2 +- drivers/adc/adc_max1125x.c | 2 +- drivers/ethernet/eth_w5500_priv.h | 2 +- drivers/sensor/fdc2x1x/fdc2x1x.h | 2 +- drivers/sensor/sm351lt/sm351lt.h | 2 +- drivers/sensor/tmag5170/tmag5170.h | 2 +- drivers/sensor/tsl2540/tsl2540.h | 2 +- drivers/sensor/vcnl4040/vcnl4040.h | 2 +- include/zephyr/kernel/thread_stack.h | 6 +++--- 11 files changed, 13 insertions(+), 14 deletions(-) diff --git a/doc/kernel/usermode/mpu_stack_objects.rst b/doc/kernel/usermode/mpu_stack_objects.rst index 944be144ada..477a4596757 100644 --- a/doc/kernel/usermode/mpu_stack_objects.rst +++ b/doc/kernel/usermode/mpu_stack_objects.rst @@ -6,8 +6,7 @@ MPU Stack Objects Thread Stack Creation ********************* -Thread stacks are declared statically with :c:macro:`K_THREAD_STACK_DEFINE()` -or embedded within structures using :c:macro:`K_THREAD_STACK_MEMBER()` +Thread stacks are declared statically with :c:macro:`K_THREAD_STACK_DEFINE()`. For architectures which utilize memory protection unit (MPU) hardware, stacks are physically contiguous allocations. This contiguous allocation diff --git a/drivers/adc/adc_ads1x1x.c b/drivers/adc/adc_ads1x1x.c index 5549c7a83a0..a448eb6bf72 100644 --- a/drivers/adc/adc_ads1x1x.c +++ b/drivers/adc/adc_ads1x1x.c @@ -140,7 +140,7 @@ struct ads1x1x_data { struct k_thread thread; bool differential; - K_THREAD_STACK_MEMBER(stack, CONFIG_ADC_ADS1X1X_ACQUISITION_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_ADS1X1X_ACQUISITION_THREAD_STACK_SIZE); }; static int ads1x1x_read_reg(const struct device *dev, enum ads1x1x_reg reg_addr, uint16_t *buf) diff --git a/drivers/adc/adc_b91.c b/drivers/adc/adc_b91.c index 6779665c459..4b1d4abba26 100644 --- a/drivers/adc/adc_b91.c +++ b/drivers/adc/adc_b91.c @@ -35,7 +35,7 @@ struct b91_adc_data { struct k_sem acq_sem; struct k_thread thread; - K_THREAD_STACK_MEMBER(stack, CONFIG_ADC_B91_ACQUISITION_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_B91_ACQUISITION_THREAD_STACK_SIZE); }; struct b91_adc_cfg { diff --git a/drivers/adc/adc_max1125x.c b/drivers/adc/adc_max1125x.c index 82a85d2af1c..7a9bf0ed026 100644 --- a/drivers/adc/adc_max1125x.c +++ b/drivers/adc/adc_max1125x.c @@ -226,7 +226,7 @@ struct max1125x_data { struct k_thread thread; bool differential; - K_THREAD_STACK_MEMBER(stack, CONFIG_ADC_MAX1125X_ACQUISITION_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_MAX1125X_ACQUISITION_THREAD_STACK_SIZE); }; static void max1125x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb, diff --git a/drivers/ethernet/eth_w5500_priv.h b/drivers/ethernet/eth_w5500_priv.h index aed1fe4adfa..5367300d5ef 100644 --- a/drivers/ethernet/eth_w5500_priv.h +++ b/drivers/ethernet/eth_w5500_priv.h @@ -90,7 +90,7 @@ struct w5500_config { struct w5500_runtime { struct net_if *iface; - K_THREAD_STACK_MEMBER(thread_stack, + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ETH_W5500_RX_THREAD_STACK_SIZE); struct k_thread thread; uint8_t mac_addr[6]; diff --git a/drivers/sensor/fdc2x1x/fdc2x1x.h b/drivers/sensor/fdc2x1x/fdc2x1x.h index 33b94168d67..7442de37631 100644 --- a/drivers/sensor/fdc2x1x/fdc2x1x.h +++ b/drivers/sensor/fdc2x1x/fdc2x1x.h @@ -159,7 +159,7 @@ struct fdc2x1x_data { const struct device *dev; #ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD - K_THREAD_STACK_MEMBER(thread_stack, CONFIG_FDC2X1X_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_FDC2X1X_THREAD_STACK_SIZE); struct k_sem gpio_sem; struct k_thread thread; #elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD diff --git a/drivers/sensor/sm351lt/sm351lt.h b/drivers/sensor/sm351lt/sm351lt.h index 78b5aa01725..6e1edf67931 100644 --- a/drivers/sensor/sm351lt/sm351lt.h +++ b/drivers/sensor/sm351lt/sm351lt.h @@ -30,7 +30,7 @@ struct sm351lt_data { const struct sensor_trigger *changed_trigger; #if defined(CONFIG_SM351LT_TRIGGER_OWN_THREAD) - K_THREAD_STACK_MEMBER(thread_stack, CONFIG_SM351LT_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_SM351LT_THREAD_STACK_SIZE); struct k_thread thread; struct k_sem gpio_sem; #elif defined(CONFIG_SM351LT_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/tmag5170/tmag5170.h b/drivers/sensor/tmag5170/tmag5170.h index 91778e81c56..28f76d2e12b 100644 --- a/drivers/sensor/tmag5170/tmag5170.h +++ b/drivers/sensor/tmag5170/tmag5170.h @@ -48,7 +48,7 @@ struct tmag5170_data { struct k_sem sem; struct k_thread thread; - K_THREAD_STACK_MEMBER(thread_stack, + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_TMAG5170_THREAD_STACK_SIZE); #elif defined(CONFIG_TMAG5170_TRIGGER_GLOBAL_THREAD) struct k_work work; diff --git a/drivers/sensor/tsl2540/tsl2540.h b/drivers/sensor/tsl2540/tsl2540.h index 36822f82da2..7cabaaeb519 100644 --- a/drivers/sensor/tsl2540/tsl2540.h +++ b/drivers/sensor/tsl2540/tsl2540.h @@ -91,7 +91,7 @@ struct tsl2540_data { sensor_trigger_handler_t als_handler; #endif #ifdef CONFIG_TSL2540_TRIGGER_OWN_THREAD - K_THREAD_STACK_MEMBER(thread_stack, CONFIG_TSL2540_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_TSL2540_THREAD_STACK_SIZE); struct k_thread thread; struct k_sem trig_sem; #endif diff --git a/drivers/sensor/vcnl4040/vcnl4040.h b/drivers/sensor/vcnl4040/vcnl4040.h index 755d9de31af..1341375f71b 100644 --- a/drivers/sensor/vcnl4040/vcnl4040.h +++ b/drivers/sensor/vcnl4040/vcnl4040.h @@ -118,7 +118,7 @@ struct vcnl4040_data { const struct sensor_trigger *als_trigger; #endif #ifdef CONFIG_VCNL4040_TRIGGER_OWN_THREAD - K_THREAD_STACK_MEMBER(thread_stack, CONFIG_VCNL4040_THREAD_STACK_SIZE); + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_VCNL4040_THREAD_STACK_SIZE); struct k_thread thread; struct k_sem trig_sem; #endif diff --git a/include/zephyr/kernel/thread_stack.h b/include/zephyr/kernel/thread_stack.h index 2ecfcb3aeac..133f055c08f 100644 --- a/include/zephyr/kernel/thread_stack.h +++ b/include/zephyr/kernel/thread_stack.h @@ -625,13 +625,13 @@ static inline char *Z_KERNEL_STACK_BUFFER(k_thread_stack_t *sym) * A user thread can only be started with a stack defined in this way if * the thread starting it is in supervisor mode. * - * This is now deprecated, as stacks defined in this way are not usable from - * user mode. Use K_KERNEL_STACK_MEMBER. + * @deprecated This is now deprecated, as stacks defined in this way are not + * usable from user mode. Use K_KERNEL_STACK_MEMBER. * * @param sym Thread stack symbol name * @param size Size of the stack memory region */ -#define K_THREAD_STACK_MEMBER(sym, size) \ +#define K_THREAD_STACK_MEMBER(sym, size) __DEPRECATED_MACRO \ Z_THREAD_STACK_DEFINE_IN(sym, size,) /** @} */ From 65bb96f37c6a45b923fd53c19df855fa1dc7c5a9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 12 Oct 2023 07:50:48 +0100 Subject: [PATCH 1928/4498] retention: blinfo: Fix issue with crash writing to keys Fixes an issue which would cause a fault if someone attempted to write to the (non-writable) blinfo keys Signed-off-by: Jamie McCrae --- subsys/retention/blinfo_mcuboot.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/retention/blinfo_mcuboot.c b/subsys/retention/blinfo_mcuboot.c index 35845dee712..8c4ccaaa674 100644 --- a/subsys/retention/blinfo_mcuboot.c +++ b/subsys/retention/blinfo_mcuboot.c @@ -78,10 +78,12 @@ int blinfo_lookup(uint16_t key, char *val, int val_len_max) #if defined(CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS) static int blinfo_handle_get(const char *name, char *val, int val_len_max); +static int blinfo_handle_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg); static struct settings_handler blinfo_handler = { .name = "blinfo", .h_get = blinfo_handle_get, + .h_set = blinfo_handle_set, }; static int blinfo_handle_get(const char *name, char *val, int val_len_max) @@ -110,6 +112,11 @@ static int blinfo_handle_get(const char *name, char *val, int val_len_max) return blinfo_lookup(index, val, val_len_max); } + +static int blinfo_handle_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg) +{ + return -ENOTSUP; +} #endif static int blinfo_init(void) From 828940b4203a5ea5e48e692fcafbf3e93b3afb35 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 12 Oct 2023 08:02:08 +0100 Subject: [PATCH 1929/4498] mcumgr: grp: fs_mgmt: Fix error on hash/checksum of empty file Fixes the error code being returned when trying to perform a hash/checksum on an empty file to show it is because the file is empty, not because a paramter (which was not provided) was too large. Signed-off-by: Jamie McCrae --- include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h | 3 +++ subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h index b48ea8edc8e..9db23ac0b0e 100644 --- a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h @@ -79,6 +79,9 @@ enum fs_mgmt_err_code_t { /** The specified mount point is that of a read-only filesystem. */ FS_MGMT_ERR_READ_ONLY_FILESYSTEM, + + /** The operation cannot be performed because the file is empty with no contents. */ + FS_MGMT_ERR_FILE_EMPTY, }; #ifdef __cplusplus diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c index 2d0402fc451..3458c3d6f8b 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c @@ -732,9 +732,12 @@ static int fs_mgmt_file_hash_checksum(struct smp_streamer *ctxt) } if (file_len <= off) { - /* Requested offset is larger than target file size */ + /* Requested offset is larger than target file size or file length is 0, which + * means no hash/checksum can be performed + */ ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, - FS_MGMT_ERR_FILE_OFFSET_LARGER_THAN_FILE); + (file_len == 0 ? FS_MGMT_ERR_FILE_EMPTY : + FS_MGMT_ERR_FILE_OFFSET_LARGER_THAN_FILE)); goto end; } From c67560cbbd96556ee4394e60eb958660cf434dde Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 12 Oct 2023 07:56:36 +0100 Subject: [PATCH 1930/4498] mcumgr: grp: settings_mgmt: Handle settings return values Handles return values from settings handlers which were missing and would return "Unknown error" to clients instead of the read error Signed-off-by: Jamie McCrae --- .../mgmt/mcumgr/grp/settings_mgmt/settings_mgmt.h | 9 +++++++++ .../mcumgr/grp/settings_mgmt/src/settings_mgmt.c | 12 +++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt.h index 2a1a3f77747..9aab1cdcc4a 100644 --- a/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt.h @@ -37,6 +37,15 @@ enum settings_mgmt_ret_code_t { /** The provided key name does not support being read. */ SETTINGS_MGMT_ERR_READ_NOT_SUPPORTED, + + /** The provided root key name does not exist. */ + SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND, + + /** The provided key name does not support being written. */ + SETTINGS_MGMT_ERR_WRITE_NOT_SUPPORTED, + + /** The provided key name does not support being deleted. */ + SETTINGS_MGMT_ERR_DELETE_NOT_SUPPORTED, }; #ifdef __cplusplus diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c index e5fdcf00d41..bafab97db7c 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c @@ -120,6 +120,8 @@ static int settings_mgmt_read(struct smp_streamer *ctxt) if (rc < 0) { if (rc == -EINVAL) { + rc = SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND; + } else if (rc == -ENOENT) { rc = SETTINGS_MGMT_ERR_KEY_NOT_FOUND; } else if (rc == -ENOTSUP) { rc = SETTINGS_MGMT_ERR_READ_NOT_SUPPORTED; @@ -231,7 +233,11 @@ static int settings_mgmt_write(struct smp_streamer *ctxt) if (rc < 0) { if (rc == -EINVAL) { + rc = SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND; + } else if (rc == -ENOENT) { rc = SETTINGS_MGMT_ERR_KEY_NOT_FOUND; + } else if (rc == -ENOTSUP) { + rc = SETTINGS_MGMT_ERR_WRITE_NOT_SUPPORTED; } else { rc = SETTINGS_MGMT_ERR_UNKNOWN; } @@ -329,8 +335,12 @@ static int settings_mgmt_delete(struct smp_streamer *ctxt) #endif if (rc < 0) { - if (rc == -ENOENT) { + if (rc == -EINVAL) { + rc = SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND; + } else if (rc == -ENOENT) { rc = SETTINGS_MGMT_ERR_KEY_NOT_FOUND; + } else if (rc == -ENOTSUP) { + rc = SETTINGS_MGMT_ERR_DELETE_NOT_SUPPORTED; } else { rc = SETTINGS_MGMT_ERR_UNKNOWN; } From 5cf6218c627d35560afaa70a2162a5952f055bdb Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 12 Oct 2023 10:36:45 +0200 Subject: [PATCH 1931/4498] Bluetooth: Mesh: Fix Capabilities Status message with OOB upload enabled The `else` case was incorrectly excluded by preprocessor. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 2547c07a5b4..d225f67bb77 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -233,11 +233,10 @@ static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg net_buf_simple_add_mem(&rsp, srv->oob_schemes.schemes, srv->oob_schemes.count); } else -#else +#endif { net_buf_simple_add_u8(&rsp, 0); } -#endif bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL); From 9cdb0aaa14ae9cf5d66a4a358f75d01ca398c901 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Tue, 3 Oct 2023 16:40:34 +0200 Subject: [PATCH 1932/4498] twister: harness: Fix Console pattern matching for ztest Fix the Twister Console harness ordered 'multi_line' and 'one_line' pattern matching to treat the ztest as failed when not all of the expected patterns were found in the console output, but the ztest application itself reports 'PROJECT EXECUTION SUCCESSFUL'. Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/harness.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index b34c5a8b68c..55525076f8f 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -164,18 +164,23 @@ def configure(self, instance): super(Console, self).configure(instance) if self.type == "one_line": self.pattern = re.compile(self.regex[0]) + self.patterns_expected = 1 elif self.type == "multi_line": self.patterns = [] for r in self.regex: self.patterns.append(re.compile(r)) + self.patterns_expected = len(self.patterns) def handle(self, line): if self.type == "one_line": if self.pattern.search(line): + logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED({self.next_pattern}):'{self.pattern.pattern}'") + self.next_pattern += 1 self.state = "passed" elif self.type == "multi_line" and self.ordered: if (self.next_pattern < len(self.patterns) and self.patterns[self.next_pattern].search(line)): + logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED({self.next_pattern}):'{self.patterns[self.next_pattern].pattern}'") self.next_pattern += 1 if self.next_pattern >= len(self.patterns): self.state = "passed" @@ -213,6 +218,17 @@ def handle(self, line): self.recording.append(csv) self.process_test(line) + # Reset the resulting test state to 'failed' for 'one_line' and + # ordered 'multi_line' patterns when not all of these patterns were + # found in the output, but just ztest's 'PROJECT EXECUTION SUCCESSFUL'. + # It might happen because of the pattern sequence diverged from the + # test code, the test platform has console issues, or even some other + # test image was executed. + # TODO: Introduce explicit match policy type either to reject + # unexpected console output, or to allow missing patterns. + if self.state == "passed" and self.ordered and self.next_pattern < self.patterns_expected: + logger.error(f"HARNESS:{self.__class__.__name__}: failed with only {self.next_pattern} matched patterns from expected {self.patterns_expected}") + self.state = "failed" tc = self.instance.get_case_or_create(self.id) if self.state == "passed": From 496509cd65f9f9d53560d844db984a5014739de8 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 6 Oct 2023 21:31:30 +0200 Subject: [PATCH 1933/4498] twister: Reset TestInstance status before run Reset TestInstance status when ProjectBuilder.run() is called to run the test after its successful build, so the build status will not propagate as the run status if the run fails. Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/runner.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index fbffa817bb2..fc3145c7676 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1037,6 +1037,9 @@ def run(self): instance = self.instance if instance.handler.ready: + logger.info(f"Reset instance status from '{instance.status}' to None before run.") + instance.status = None + if instance.handler.type_str == "device": instance.handler.duts = self.duts From 8be25e284a06756e48cb4ac0aa72b264c3481c24 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 29 Sep 2023 21:27:07 -0700 Subject: [PATCH 1934/4498] drivers/fdc2x1x: Depend on full C library, not just newlib This driver uses the math library, so it cannot use the minimal C library. However, it should be fine with any complete C library, not just newlib. Signed-off-by: Keith Packard --- drivers/sensor/fdc2x1x/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/fdc2x1x/Kconfig b/drivers/sensor/fdc2x1x/Kconfig index bf6f7b148d7..2d6ac596bf3 100644 --- a/drivers/sensor/fdc2x1x/Kconfig +++ b/drivers/sensor/fdc2x1x/Kconfig @@ -7,7 +7,7 @@ menuconfig FDC2X1X bool "FDC2X1X Capacitance-to-Digital Converter" default y depends on DT_HAS_TI_FDC2X1X_ENABLED - depends on NEWLIB_LIBC || EXTERNAL_LIBC + depends on FULL_LIBC_SUPPORTED || EXTERNAL_LIBC select I2C help Enable driver for FDC2X1X Capacitance-to-Digital Converter. From 4d76e26f173060d0fd0c9ccbed1e617fff615434 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Thu, 5 Oct 2023 04:24:28 +0300 Subject: [PATCH 1935/4498] drivers: pinctrl: Update Infineon CAT1 pinctrl driver - if we have input enable use CY_GPIO_DM_xxxx else CY_GPIO_DM_xxx_IN_OFF; - added bias_high_impedance option - Updated HIGHZ drive mode, now it sets if: --- we have bias_high_impedance --- or if input_enable and no addition bias mode Signed-off-by: Nazar Palamar --- drivers/pinctrl/pinctrl_ifx_cat1.c | 29 ++++++++++--------- .../pinctrl/infineon,cat1-pinctrl.yaml | 2 ++ soc/arm/infineon_cat1/common/pinctrl_soc.h | 6 +++- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl_ifx_cat1.c b/drivers/pinctrl/pinctrl_ifx_cat1.c index 8f2bbcb0e43..dbeaab855f3 100644 --- a/drivers/pinctrl/pinctrl_ifx_cat1.c +++ b/drivers/pinctrl/pinctrl_ifx_cat1.c @@ -52,41 +52,44 @@ static uint32_t soc_gpio_get_drv_mode(uint32_t flags) if (_flags & SOC_GPIO_OPENDRAIN) { /* drive_open_drain */ - drv_mode = CY_GPIO_DM_OD_DRIVESLOW_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_OD_DRIVESLOW + : CY_GPIO_DM_OD_DRIVESLOW_IN_OFF; } else if (_flags & SOC_GPIO_OPENSOURCE) { /* drive_open_source */ - drv_mode = CY_GPIO_DM_OD_DRIVESHIGH_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_OD_DRIVESHIGH + : CY_GPIO_DM_OD_DRIVESHIGH_IN_OFF; } else if (_flags & SOC_GPIO_PUSHPULL) { /* drive_push_pull */ - drv_mode = CY_GPIO_DM_STRONG_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_STRONG + : CY_GPIO_DM_STRONG_IN_OFF; } else if ((_flags & SOC_GPIO_PULLUP) && (_flags & SOC_GPIO_PULLDOWN)) { /* bias_pull_up and bias_pull_down */ - drv_mode = CY_GPIO_DM_PULLUP_DOWN_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLUP_DOWN + : CY_GPIO_DM_PULLUP_DOWN_IN_OFF; } else if (_flags & SOC_GPIO_PULLUP) { /* bias_pull_up */ - drv_mode = CY_GPIO_DM_PULLUP_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLUP + : CY_GPIO_DM_PULLUP_IN_OFF; } else if (_flags & SOC_GPIO_PULLDOWN) { /* bias_pull_down */ - drv_mode = CY_GPIO_DM_PULLDOWN_IN_OFF; + drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLDOWN + : CY_GPIO_DM_PULLDOWN_IN_OFF; + } else if ((_flags & SOC_GPIO_HIGHZ) | (_flags & SOC_GPIO_INPUTENABLE)) { + /* bias_pull_down */ + drv_mode = CY_GPIO_DM_HIGHZ; } else { /* nothing do here */ } - if (_flags & SOC_GPIO_INPUTENABLE) { - /* input_enable */ - drv_mode |= CY_GPIO_DM_HIGHZ; - } - return drv_mode; } -int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, - uintptr_t reg) +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { ARG_UNUSED(reg); diff --git a/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml b/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml index 09e089b1baa..2335a08b098 100644 --- a/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml +++ b/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml @@ -21,6 +21,7 @@ description: | Pin configuration can also specify the pin properties, for example the 'bias-pull-up' property. Here is a list of the supported standard pin properties: + * bias-high-impedance * bias-pull-up * bias-pull-down * drive-open-drain @@ -105,6 +106,7 @@ child-binding: include: - name: pincfg-node.yaml property-allowlist: + - bias-high-impedance - bias-pull-down - bias-pull-up - drive-push-pull diff --git a/soc/arm/infineon_cat1/common/pinctrl_soc.h b/soc/arm/infineon_cat1/common/pinctrl_soc.h index 51c01fcaaa1..7832c1b39de 100644 --- a/soc/arm/infineon_cat1/common/pinctrl_soc.h +++ b/soc/arm/infineon_cat1/common/pinctrl_soc.h @@ -59,6 +59,9 @@ extern "C" { #define SOC_GPIO_INPUTENABLE_POS (5) #define SOC_GPIO_INPUTENABLE (1 << SOC_GPIO_INPUTENABLE_POS) +#define SOC_GPIO_HIGHZ_POS (6) +#define SOC_GPIO_HIGHZ (1 << SOC_GPIO_HIGHZ_POS) + /** Type for CAT1 Soc pin. */ typedef struct { /** @@ -96,7 +99,8 @@ typedef struct { (DT_PROP(node_id, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS) | \ (DT_PROP(node_id, drive_open_source) << SOC_GPIO_OPENSOURCE_POS) | \ (DT_PROP(node_id, drive_push_pull) << SOC_GPIO_PUSHPULL_POS) | \ - (DT_PROP(node_id, input_enable) << SOC_GPIO_INPUTENABLE_POS)) + (DT_PROP(node_id, input_enable) << SOC_GPIO_INPUTENABLE_POS) | \ + (DT_PROP(node_id, bias_high_impedance) << SOC_GPIO_HIGHZ_POS)) /** * @brief Utility macro to initialize each pin. From 0af523eba75fc5afece9539f576cc15b8b914dfe Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 12 Oct 2023 12:29:59 +0200 Subject: [PATCH 1936/4498] Bluetooth: Mesh: Fix failing DFU/SR/FD/BV-08-C test The `upload_status_rsp_with_progress` function uses the currently set slot pointer to set firmware id field in the message. If another upload starts but the firmware is already received, the slot API won't let us to set the fwid and will return an error code. In this case, the slot pointer stays invalid as fwid wasn't set, and `upload_status_rsp_with_progress` will not add fwid as the lenght is zero. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfd_srv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index d225f67bb77..0a9ecba6cec 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -412,12 +412,20 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms case -EFBIG: /* Fwid too long */ case -EALREADY: /* Other server is in progress with this fwid */ bt_mesh_dfu_slot_release(srv->upload.slot); + srv->upload.slot = NULL; upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); break; case -EEXIST: /* Img with this fwid already is in list */ srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); + + err = bt_mesh_dfu_slot_get(fwid, fwid_len, &srv->upload.slot); + if (!err) { + upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); + } else { + srv->upload.slot = NULL; + upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); + } break; case 0: srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; From 24e3966c988c3b565e5ecad117511a1e7a20283d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 9 Oct 2023 15:52:42 +0200 Subject: [PATCH 1937/4498] Bluetooth: Improve bt_le_per_adv_sync_create documentation The bt_le_per_adv_sync_create documentation did not mention anything about the (lack of) timeout when using the function. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/bluetooth.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 6f3aeb96775..c97e1445cb3 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -1690,6 +1690,10 @@ struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_addr(const bt_addr_le_t *ad * to periodic advertising reports from an advertiser. Scan shall either be * disabled or extended scan shall be enabled. * + * This function does not timeout, and will continue to look for an advertiser until it either + * finds it or bt_le_per_adv_sync_delete() is called. It is thus suggested to implement a timeout + * when using this, if it is expected to find the advertiser within a reasonable timeframe. + * * @param[in] param Periodic advertising sync parameters. * @param[out] out_sync Periodic advertising sync object on. * From 16bb2265933373babc7b3cb54094a84743ec02e1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 12 Oct 2023 09:01:52 +0100 Subject: [PATCH 1938/4498] doc: release: 3.5: Add note on 2 fixed MCUmgr bugs Adds notes on a fixed settings_mgmt and fs_mgmt bug Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 323c5774177..83dcfc60c03 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -800,6 +800,11 @@ Libraries / Subsystems * Added STM32 SPI backend for EC Host command protocol. + * Fixed settings_mgmt returning unknown error instead of invalid key specified error. + + * Fixed fs_mgmt returning parameter too large error instead of file is empty error when + attempting to hash/checksum a file which is empty. + * File systems * Added support for ext2 file system. From 8dfa116750119262e6da801960bcf75e32c155c1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Oct 2023 08:19:00 +0300 Subject: [PATCH 1939/4498] drivers: dma: intel-adsp-hda: Correct DGCS:SCS bit for 32bit sample size If the channel was used for 16bit in the once, subsequent 32bit sample size audio will be broken since the SCS bit remains set. Example sequence with SOF: normal audio playback with 16bit ChainDMA audio playback with 16bit normal audio playback with 16bit The last playback results garbled audio. Introduce intel_adsp_hda_set_sample_container_size() helper function to handle the SCS bit and use it in the driver. Signed-off-by: Peter Ujfalusi --- drivers/dma/dma_intel_adsp_hda.c | 26 +++++++------------ .../common/include/intel_adsp_hda.h | 22 ++++++++++++++++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/dma/dma_intel_adsp_hda.c b/drivers/dma/dma_intel_adsp_hda.c index daf0a4622b8..2dd0bea6ed6 100644 --- a/drivers/dma/dma_intel_adsp_hda.c +++ b/drivers/dma/dma_intel_adsp_hda.c @@ -53,10 +53,8 @@ int intel_adsp_hda_dma_host_in_config(const struct device *dev, *DGMBS(cfg->base, cfg->regblock_size, channel) = blk_cfg->block_size & HDA_ALIGN_MASK; - if (dma_cfg->source_data_size <= 3) { - /* set the sample container set bit to 16bits */ - *DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS; - } + intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel, + dma_cfg->source_data_size); } return res; @@ -90,10 +88,8 @@ int intel_adsp_hda_dma_host_out_config(const struct device *dev, *DGMBS(cfg->base, cfg->regblock_size, channel) = blk_cfg->block_size & HDA_ALIGN_MASK; - if (dma_cfg->dest_data_size <= 3) { - /* set the sample container set bit to 16bits */ - *DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS; - } + intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel, + dma_cfg->dest_data_size); } return res; @@ -120,10 +116,9 @@ int intel_adsp_hda_dma_link_in_config(const struct device *dev, buf = (uint8_t *)(uintptr_t)(blk_cfg->dest_address); res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf, blk_cfg->block_size); - - if (res == 0 && dma_cfg->dest_data_size <= 3) { - /* set the sample container set bit to 16bits */ - *DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS; + if (res == 0) { + intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel, + dma_cfg->dest_data_size); } return res; @@ -152,10 +147,9 @@ int intel_adsp_hda_dma_link_out_config(const struct device *dev, res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf, blk_cfg->block_size); - - if (res == 0 && dma_cfg->source_data_size <= 3) { - /* set the sample container set bit to 16bits */ - *DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS; + if (res == 0) { + intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel, + dma_cfg->source_data_size); } return res; diff --git a/soc/xtensa/intel_adsp/common/include/intel_adsp_hda.h b/soc/xtensa/intel_adsp/common/include/intel_adsp_hda.h index 2d166d8950a..2b403eb17a4 100644 --- a/soc/xtensa/intel_adsp/common/include/intel_adsp_hda.h +++ b/soc/xtensa/intel_adsp/common/include/intel_adsp_hda.h @@ -469,4 +469,26 @@ static inline uint32_t intel_adsp_hda_check_buffer_interrupt(uint32_t base, uint return (*DGCS(base, regblock_size, sid) & DGCS_BSC) == DGCS_BSC; } +/** + * @brief Set the Sample Container Size (SCS) + * + * Sample Container Size indicates the container size of the audio samples in local memory + * SCS bit must cleared to 0 for 32bit sample size (HD Audio container size) + * SCS bit must be set to 1 for non 32bit sample sizes + * + * @param base Base address of the IP register block + * @param regblock_size Register block size + * @param sid Stream ID + * @param sample_size + */ +static inline void intel_adsp_hda_set_sample_container_size(uint32_t base, uint32_t regblock_size, + uint32_t sid, uint32_t sample_size) +{ + if (sample_size <= 3) { + *DGCS(base, regblock_size, sid) |= DGCS_SCS; + } else { + *DGCS(base, regblock_size, sid) &= ~DGCS_SCS; + } +} + #endif /* ZEPHYR_INCLUDE_INTEL_ADSP_HDA_H */ From c2eb47a9f7246da8068b75a35f31edbef5109b59 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 12 Oct 2023 06:06:53 -0400 Subject: [PATCH 1940/4498] MAINTAINER: SimpleLink platform should only include ti_simplelink Do not include all TI platform in something that is supposed to include Simplelink. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 6a1f03bb764..1e5c936bc1c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2673,7 +2673,7 @@ TI SimpleLink Platforms: - drivers/*/*cc32* - dts/arm/ti/ - dts/bindings/*/ti,* - - soc/arm/ti*/ + - soc/arm/ti_simplelink/ - dts/bindings/*/ti,* labels: - "platform: TI SimpleLink" From 625faa7f03e7ac4a8c9795bfc03ba278010973df Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 12 Oct 2023 13:13:40 +0200 Subject: [PATCH 1941/4498] Bluetooth: Mesh: fix proxy solicitation Commit makes workable proxy solicitation functionality only server part without dependencies on client part. Only on demand proxy server is required. Signed-off-by: Aleksandr Khromykh --- include/zephyr/bluetooth/uuid.h | 2 +- subsys/bluetooth/mesh/crypto.c | 2 +- subsys/bluetooth/mesh/proxy_srv.c | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/uuid.h b/include/zephyr/bluetooth/uuid.h index 1fa8ece6466..cab12eac74b 100644 --- a/include/zephyr/bluetooth/uuid.h +++ b/include/zephyr/bluetooth/uuid.h @@ -587,7 +587,7 @@ struct bt_uuid_128 { /** * @brief Proxy Solicitation UUID value */ -#define BT_UUID_MESH_PROXY_SOLICITATION_VAL 0x7fcb +#define BT_UUID_MESH_PROXY_SOLICITATION_VAL 0x1859 /** * @brief Reconnection Configuration Service UUID value */ diff --git a/subsys/bluetooth/mesh/crypto.c b/subsys/bluetooth/mesh/crypto.c index e42717475c0..b79458f7ea2 100644 --- a/subsys/bluetooth/mesh/crypto.c +++ b/subsys/bluetooth/mesh/crypto.c @@ -419,7 +419,7 @@ int bt_mesh_net_decrypt(const struct bt_mesh_key *key, struct net_buf_simple *bu if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && type == BT_MESH_NONCE_PROXY) { create_proxy_nonce(nonce, buf->data, iv_index); - } else if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && + } else if (IS_ENABLED(CONFIG_BT_MESH_SOLICITATION) && type == BT_MESH_NONCE_SOLICITATION) { create_proxy_sol_nonce(nonce, buf->data); } else { diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 62c46582fa0..12775b93651 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -698,9 +698,11 @@ static void gatt_proxy_solicited(struct bt_mesh_subnet *sub) if (sub->priv_net_id_sent > 0) { timeout = sub->priv_net_id_sent + MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); + remaining = MIN(timeout - now, INT32_MAX); + } else { + remaining = MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); } - remaining = MIN(timeout - now, INT32_MAX); if ((timeout > 0 && now > timeout) || (remaining / MSEC_PER_SEC < 1)) { LOG_DBG("Advertising Private Network ID timed out " "after solicitation"); From 917a3e6e6418515b80459c9d3c4e5e650c81362f Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 12 Oct 2023 13:17:01 +0200 Subject: [PATCH 1942/4498] tests: bluetooth: tester: enable proxy solicitation Commit enables proxy solicitation functionality (server part) for mesh proxy PTS tests. Signed-off-by: Aleksandr Khromykh --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 1 + tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf index 7a3907cc78c..5f59970b421 100644 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ b/tests/bluetooth/tester/overlay-mesh-v1d1.conf @@ -23,6 +23,7 @@ CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_BT_MESH_PRIV_BEACONS=y CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y +CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y CONFIG_BT_MESH_MODEL_EXTENSIONS=y CONFIG_BT_MESH_COMP_PAGE_1=y diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 586b6ae1bd7..eacdb8b3b0c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -5065,7 +5065,7 @@ static const struct btp_handler handlers[] = { .func = srpl_clear }, #endif -#if defined(CONFIG_BT_MESH_SOLICITATION) +#if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) { .opcode = BTP_MESH_PROXY_SOLICIT, .expect_len = sizeof(struct btp_proxy_solicit_cmd), From 00457ae6c629ef138fd7b7ce10bdd1c0b07e4286 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 12 Oct 2023 14:50:01 +0200 Subject: [PATCH 1943/4498] Bluetooth: Mesh: improve solicitation debug logging Commits adds debug logging for all reasons preventing of the proxy solicitation. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/solicitation.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index f6543dcb320..e2100fa42db 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -190,13 +190,14 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_od_priv_proxy_get() == 0) { + LOG_DBG("Not soliciting"); return; } /* Get rid of ad_type that was checked in bt_mesh_scan_cb */ type = net_buf_simple_pull_u8(buf); if (type != BT_DATA_UUID16_SOME && type != BT_DATA_UUID16_ALL) { - LOG_ERR("Invalid type 0x%x, expected 0x%x or 0x%x", + LOG_DBG("Invalid type 0x%x, expected 0x%x or 0x%x", type, BT_DATA_UUID16_SOME, BT_DATA_UUID16_ALL); return; } @@ -215,6 +216,7 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (!sol_uuid_found) { + LOG_DBG("No solicitation UUID found"); return; } @@ -230,6 +232,7 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (buf->len <= reported_len - 3) { + LOG_DBG("Invalid length (%u) Solicitation PDU", buf->len); return; } @@ -237,12 +240,13 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (!svc_data_found) { + LOG_DBG("No solicitation service data found"); return; } type = net_buf_simple_pull_u8(buf); if (type != 0) { - LOG_ERR("Invalid type %d, expected 0x00", type); + LOG_DBG("Invalid type %d, expected 0x00", type); return; } From 58e40239fd0eaf04ad2e03df7f3f324526caf83d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 10 Oct 2023 12:45:53 +0200 Subject: [PATCH 1944/4498] Bluetooth: BAP: Scan delegator missing state change for bis_sync If the bis_sync value changes, that should trigger a state change notification. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_scan_delegator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 251bd722ec4..7d5cd700e5f 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -1340,7 +1340,10 @@ int bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_par const struct bt_bap_scan_delegator_subgroup *param_subgroup = ¶m->subgroups[i]; struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i]; - subgroup->bis_sync = param_subgroup->bis_sync; + if (subgroup->bis_sync != param_subgroup->bis_sync) { + subgroup->bis_sync = param_subgroup->bis_sync; + state_changed = true; + } /* If the metadata len is 0, we shall not overwrite the existing metadata */ if (param_subgroup->metadata_len == 0U) { From 00deb0ea754baa6df5f46a43422791eac3df6fa0 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 10 Oct 2023 14:09:53 +0200 Subject: [PATCH 1945/4498] Bluetooth: BAP: Remove static from state_changed in mod_src For some reason the state_change variable was static, which does not make any sense. Changed it to a regular local bool in bt_bap_scan_delegator_mod_src. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_scan_delegator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 7d5cd700e5f..19d33997453 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -1298,7 +1298,7 @@ int bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_par { struct bass_recv_state_internal *internal_state = NULL; struct bt_bap_scan_delegator_recv_state *state; - static bool state_changed; + bool state_changed = false; CHECKIF(!valid_bt_bap_scan_delegator_mod_src_param(param)) { return -EINVAL; From c47b7f7936dc39b1d2369122c1ab669acef75bc9 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 12 Oct 2023 10:42:57 +0200 Subject: [PATCH 1946/4498] Bluetooth: BAP: Broadcast sink: Clear pa_sync on PA terminated If the PA gets terminated, we clear the pa_sync field of the corresponding broadcast sink object. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index d4d5325ba84..04771ab53ef 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -570,6 +570,16 @@ static void pa_recv(struct bt_le_per_adv_sync *sync, bt_data_parse(buf, pa_decode_base, (void *)sink); } +static void pa_term_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_term_info *info) +{ + struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync); + + if (sink != NULL) { + sink->pa_sync = NULL; + } +} + static void update_recv_state_encryption(const struct bt_bap_broadcast_sink *sink) { struct bt_bap_scan_delegator_mod_src_param mod_src_param = { 0 }; @@ -1114,6 +1124,7 @@ static int broadcast_sink_init(void) static struct bt_le_per_adv_sync_cb cb = { .recv = pa_recv, .biginfo = biginfo_recv, + .term = pa_term_cb, }; bt_le_per_adv_sync_cb_register(&cb); From e1647e35c01114855533f80723b5d504af4cd559 Mon Sep 17 00:00:00 2001 From: Franciszek Pindel Date: Fri, 29 Sep 2023 08:47:06 +0200 Subject: [PATCH 1947/4498] linker: riscv: Align .last_section Zephyr expects __rom_region_size to be aligned to 4, otherwise assertion will fail. This commit alignes last_section which results in aligned __rom_region_size. Signed-off-by: Franciszek Pindel --- include/zephyr/arch/riscv/common/linker.ld | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index 3dbec5f0a20..5bed82439d6 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -396,6 +396,10 @@ SECTION_PROLOGUE(.last_section,,) /* Fill last section with a word to ensure location counter and actual rom * region data usage match. */ LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN) + /* __rom_region_size is used when configuring the PMP entry of the ROM region. + * Addresses (pmpaddr) in PMP registers need to be aligned to 4. Align + * __rom_region_size to 4 to meet that requirement. */ + MPU_MIN_SIZE_ALIGN #endif } GROUP_LINK_IN(ROMABLE_REGION) From 4cd7df2eec31969e84cae74cb49b0bb5710c200d Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Thu, 12 Oct 2023 13:15:00 +0200 Subject: [PATCH 1948/4498] twister: Fix error for --device-testing with not runnable integration An urforseen error was introduce with #62713. When "--device-testing" or "--filter runnable" is used in CLI, twister will skip tests which cannot be executed (not just built) on a given platform. If a given platform is among integration platforms it will cause an error. However, it shouldn't be the case. Such skip is intentional and shouldn't be an error. Fixed by assigning an existing Filter.CMD_LINE, which is exempted from being turned to error. fixes: #63844 Signed-off-by: Maciej Perkowski --- scripts/pylib/twister/twisterlib/testplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 042dcebb737..4607544efa7 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -751,7 +751,7 @@ def apply_filters(self, **kwargs): instance.add_filter("Not part of requested test plan", Filters.TESTSUITE) if runnable and not instance.run: - instance.add_filter("Not runnable on device", Filters.PLATFORM) + instance.add_filter("Not runnable on device", Filters.CMD_LINE) if self.options.integration and ts.integration_platforms and plat.name not in ts.integration_platforms: instance.add_filter("Not part of integration platforms", Filters.TESTSUITE) From 3828f1cec2af4a67f9bccf5721192bd48b8a363f Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 10 Oct 2023 11:16:47 +0200 Subject: [PATCH 1949/4498] Bluetooth: ascs: Check subscription state on ASE notification Check whether peer is subscribed for ASE state notification before calling bt_gatt_notify. This handles an assert thrown when the notification failed to be sent. Fixes: #63728 Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/ascs.c | 3 ++- tests/bluetooth/audio/mocks/include/gatt.h | 2 ++ tests/bluetooth/audio/mocks/src/gatt.c | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 2dd079e8172..94cff37f6b7 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -147,7 +147,8 @@ static void ase_status_changed(struct bt_ascs_ase *ase, uint8_t state) return; } - if (conn_info.state == BT_CONN_STATE_CONNECTED) { + if (conn_info.state == BT_CONN_STATE_CONNECTED && + bt_gatt_is_subscribed(conn, ase->attr, BT_GATT_CCC_NOTIFY)) { const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ const uint16_t max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; uint16_t ntf_size; diff --git a/tests/bluetooth/audio/mocks/include/gatt.h b/tests/bluetooth/audio/mocks/include/gatt.h index f54ad42492e..43b56dac29e 100644 --- a/tests/bluetooth/audio/mocks/include/gatt.h +++ b/tests/bluetooth/audio/mocks/include/gatt.h @@ -15,6 +15,8 @@ void mock_bt_gatt_cleanup(void); DECLARE_FAKE_VALUE_FUNC(int, mock_bt_gatt_notify_cb, struct bt_conn *, struct bt_gatt_notify_params *); +DECLARE_FAKE_VALUE_FUNC(bool, mock_bt_gatt_is_subscribed, struct bt_conn *, + const struct bt_gatt_attr *, uint16_t); void bt_gatt_notify_cb_reset(void); uint16_t bt_gatt_get_mtu(struct bt_conn *conn); diff --git a/tests/bluetooth/audio/mocks/src/gatt.c b/tests/bluetooth/audio/mocks/src/gatt.c index be2ca633df8..d020306b04d 100644 --- a/tests/bluetooth/audio/mocks/src/gatt.c +++ b/tests/bluetooth/audio/mocks/src/gatt.c @@ -18,9 +18,12 @@ LOG_MODULE_REGISTER(bt_gatt); /* List of fakes used by this unit tester */ #define FFF_FAKES_LIST(FAKE) \ FAKE(mock_bt_gatt_notify_cb) \ + FAKE(mock_bt_gatt_is_subscribed) \ DEFINE_FAKE_VALUE_FUNC(int, mock_bt_gatt_notify_cb, struct bt_conn *, struct bt_gatt_notify_params *); +DEFINE_FAKE_VALUE_FUNC(bool, mock_bt_gatt_is_subscribed, struct bt_conn *, + const struct bt_gatt_attr *, uint16_t); ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) @@ -53,6 +56,8 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, const struct bt_gatt_attr * void mock_bt_gatt_init(void) { FFF_FAKES_LIST(RESET_FAKE); + + mock_bt_gatt_is_subscribed_fake.return_val = true; } static void notify_params_deep_copy_destroy(void) @@ -246,3 +251,9 @@ uint16_t bt_gatt_get_mtu(struct bt_conn *conn) { return 64; } + +bool bt_gatt_is_subscribed(struct bt_conn *conn, + const struct bt_gatt_attr *attr, uint16_t ccc_type) +{ + return mock_bt_gatt_is_subscribed(conn, attr, ccc_type); +} From f1f5be1d1a07cec5d28492fe47e196b6df8f506b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 12 Oct 2023 14:53:17 +0000 Subject: [PATCH 1950/4498] boards: numaker_pfm_m467: do not treat as a default test platform This is not something we run in CI, so remove as a default test platform. Signed-off-by: Anas Nashif --- boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml index 74adba17eb0..d668f51facb 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.yaml @@ -13,6 +13,4 @@ ram: 512 flash: 1024 supported: - gpio -testing: - default: true vendor: nuvoton From a16d58cdf34736853b6c22801de9e6eff03c6665 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 12 Oct 2023 15:24:55 +0000 Subject: [PATCH 1951/4498] Revert "tests: kernel: xip: exclude qemu_riscv32_xip" This reverts commit 341590545ac80b7a2abd9902b7f10d577323ccde, the issue has been fixed in e1647e35c0, tested with west build -t run -p -b qemu_riscv32_xip \ -T tests/kernel/xip/arch.common.xip west build -t run -p -b qemu_riscv32_xip \ -T tests/kernel/xip/arch.common.xip.minimallibc Signed-off-by: Fabio Baltieri --- tests/kernel/xip/testcase.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/kernel/xip/testcase.yaml b/tests/kernel/xip/testcase.yaml index 82cd883b6bc..0992d219064 100644 --- a/tests/kernel/xip/testcase.yaml +++ b/tests/kernel/xip/testcase.yaml @@ -7,8 +7,6 @@ tests: integration_platforms: - qemu_arc_em - qemu_x86_xip - platform_exclude: - - qemu_riscv32_xip # See issue #62975 arch.common.xip.minimallibc: filter: CONFIG_XIP and CONFIG_MINIMAL_LIBC_SUPPORTED tags: @@ -17,7 +15,5 @@ tests: integration_platforms: - qemu_arc_em - qemu_x86_xip - platform_exclude: - - qemu_riscv32_xip # See issue #62975 extra_configs: - CONFIG_MINIMAL_LIBC=y From 8596697f0868dc98fe1a3da145740d7a6f5b54c0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 12 Oct 2023 15:26:56 +0100 Subject: [PATCH 1952/4498] tests: boot: mcuboot_data_sharing: Add missing Kconfig Adds a missing Kconfig after some retention code was refactored Signed-off-by: Jamie McCrae --- tests/boot/mcuboot_data_sharing/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/boot/mcuboot_data_sharing/prj.conf b/tests/boot/mcuboot_data_sharing/prj.conf index 05ac5db1ab1..a5a00851f52 100644 --- a/tests/boot/mcuboot_data_sharing/prj.conf +++ b/tests/boot/mcuboot_data_sharing/prj.conf @@ -11,3 +11,4 @@ CONFIG_SETTINGS=y CONFIG_SETTINGS_RUNTIME=y CONFIG_RETENTION_BOOTLOADER_INFO=y CONFIG_RETENTION_BOOTLOADER_INFO_TYPE_MCUBOOT=y +CONFIG_RETENTION_BOOTLOADER_INFO_OUTPUT_SETTINGS=y From 362d8906a6df4bc5127197ea1ee631ac1eb4fd05 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Oct 2023 16:47:57 -0700 Subject: [PATCH 1953/4498] kernel: Support platforms with runtime timer freq for thread init_delay Platforms that determine their basic timer frequency at runtime instead of build time cannot compute thread initialization timeouts during compilation. Switch back to storing the init_delay value in milliseconds and perform the conversion to a k_timeout_t at runtime. Signed-off-by: Keith Packard --- include/zephyr/kernel.h | 14 +++++++++++++- kernel/thread.c | 6 ++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 386c5369326..e387338fca7 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -691,9 +691,21 @@ struct _static_thread_data { int init_prio; uint32_t init_options; const char *init_name; +#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME + int32_t init_delay_ms; +#else k_timeout_t init_delay; +#endif }; +#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME +#define Z_THREAD_INIT_DELAY_INITIALIZER(ms) .init_delay_ms = (ms) +#define Z_THREAD_INIT_DELAY(thread) SYS_TIMEOUT_MS((thread)->init_delay_ms) +#else +#define Z_THREAD_INIT_DELAY_INITIALIZER(ms) .init_delay = SYS_TIMEOUT_MS(ms) +#define Z_THREAD_INIT_DELAY(thread) (thread)->init_delay +#endif + #define Z_THREAD_INITIALIZER(thread, stack, stack_size, \ entry, p1, p2, p3, \ prio, options, delay, tname) \ @@ -708,7 +720,7 @@ struct _static_thread_data { .init_prio = (prio), \ .init_options = (options), \ .init_name = STRINGIFY(tname), \ - .init_delay = SYS_TIMEOUT_MS(delay), \ + Z_THREAD_INIT_DELAY_INITIALIZER(delay) \ } /* diff --git a/kernel/thread.c b/kernel/thread.c index 8800eddafc9..f19c502a3ff 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -834,9 +834,11 @@ void z_init_static_threads(void) */ k_sched_lock(); _FOREACH_STATIC_THREAD(thread_data) { - if (!K_TIMEOUT_EQ(thread_data->init_delay, K_FOREVER)) { + k_timeout_t init_delay = Z_THREAD_INIT_DELAY(thread_data); + + if (!K_TIMEOUT_EQ(init_delay, K_FOREVER)) { schedule_new_thread(thread_data->init_thread, - thread_data->init_delay); + init_delay); } } k_sched_unlock(); From 38e86c8e86f8bc9b0c0794edc26151f7907145cf Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 12 Oct 2023 16:17:48 +0000 Subject: [PATCH 1954/4498] twister: runner: change log message from info to debug Very verbose log message without too much context that should be a debug message rather than a info(). Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index fc3145c7676..25e96a36038 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1037,7 +1037,7 @@ def run(self): instance = self.instance if instance.handler.ready: - logger.info(f"Reset instance status from '{instance.status}' to None before run.") + logger.debug(f"Reset instance status from '{instance.status}' to None before run.") instance.status = None if instance.handler.type_str == "device": From 2b3821212d1c31c1604db8b2feea8eea98c30400 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Sat, 30 Sep 2023 08:35:21 -0400 Subject: [PATCH 1955/4498] kernel: remove unused mailbox message field Removing the legacy field '_rx_data' from the mailbox message structure 'k_mbox_msg' as the mailbox code that used it was removed over six years ago. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index e387338fca7..3642f3caaee 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -4700,8 +4700,6 @@ struct k_mbox_msg { uint32_t info; /** sender's message data buffer */ void *tx_data; - /** internal use only - needed for legacy API support */ - void *_rx_data; /** message data block descriptor */ struct k_mem_block tx_block; /** source thread id */ From e9987aabbcd46dc583624f10004ddd2b32bbeb3d Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Sat, 30 Sep 2023 11:28:31 -0400 Subject: [PATCH 1956/4498] kernel: Remove legacy mem block from mailbox Memory blocks are a legacy feature and are to be removed from mailboxes. Signed-off-by: Peter Mitsis --- .../services/data_passing/mailboxes.rst | 2 - include/zephyr/kernel.h | 14 +- kernel/mailbox.c | 15 +-- .../kernel/mbox/mbox_api/src/test_mbox_api.c | 120 +----------------- 4 files changed, 8 insertions(+), 143 deletions(-) diff --git a/doc/kernel/services/data_passing/mailboxes.rst b/doc/kernel/services/data_passing/mailboxes.rst index 41140d8aed4..4561bce7780 100644 --- a/doc/kernel/services/data_passing/mailboxes.rst +++ b/doc/kernel/services/data_passing/mailboxes.rst @@ -248,7 +248,6 @@ portion of the message isn't used. send_msg.info = random_value; send_msg.size = 0; send_msg.tx_data = NULL; - send_msg.tx_block.data = NULL; send_msg.tx_target_thread = K_ANY; /* send message and wait until a consumer receives it */ @@ -284,7 +283,6 @@ the maximum size message buffer that each thread can handle. send_msg.info = buffer_bytes_used; send_msg.size = buffer_bytes_used; send_msg.tx_data = buffer; - send_msg.tx_block.data = NULL; send_msg.tx_target_thread = K_ANY; /* send message and wait until a consumer receives it */ diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 3642f3caaee..5dc58488985 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -4700,8 +4700,6 @@ struct k_mbox_msg { uint32_t info; /** sender's message data buffer */ void *tx_data; - /** message data block descriptor */ - struct k_mem_block tx_block; /** source thread id */ k_tid_t rx_source_thread; /** target thread id */ @@ -4770,8 +4768,8 @@ extern void k_mbox_init(struct k_mbox *mbox); * @brief Send a mailbox message in a synchronous manner. * * This routine sends a message to @a mbox and waits for a receiver to both - * receive and process it. The message data may be in a buffer, in a memory - * pool block, or non-existent (i.e. an empty message). + * receive and process it. The message data may be in a buffer or non-existent + * (i.e. an empty message). * * @param mbox Address of the mailbox. * @param tx_msg Address of the transmit message descriptor. @@ -4792,10 +4790,10 @@ extern int k_mbox_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, * @brief Send a mailbox message in an asynchronous manner. * * This routine sends a message to @a mbox without waiting for a receiver - * to process it. The message data may be in a buffer, in a memory pool block, - * or non-existent (i.e. an empty message). Optionally, the semaphore @a sem - * will be given when the message has been both received and completely - * processed by the receiver. + * to process it. The message data may be in a buffer or non-existent + * (i.e. an empty message). Optionally, the semaphore @a sem will be given + * when the message has been both received and completely processed by + * the receiver. * * @param mbox Address of the mailbox. * @param tx_msg Address of the transmit message descriptor. diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 50c23345684..2d7d28da03a 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -140,14 +140,6 @@ static int mbox_message_match(struct k_mbox_msg *tx_msg, /* update data location fields for receiver only */ rx_msg->tx_data = tx_msg->tx_data; - rx_msg->tx_block = tx_msg->tx_block; - if (rx_msg->tx_data != NULL) { - rx_msg->tx_block.data = NULL; - } else if (rx_msg->tx_block.data != NULL) { - rx_msg->tx_data = rx_msg->tx_block.data; - } else { - /* no data */ - } /* update syncing thread field for receiver only */ rx_msg->_syncing_thread = tx_msg->_syncing_thread; @@ -161,8 +153,7 @@ static int mbox_message_match(struct k_mbox_msg *tx_msg, /** * @brief Dispose of received message. * - * Releases any memory pool block still associated with the message, - * then notifies the sender that message processing is complete. + * Notifies the sender that message processing is complete. * * @param rx_msg Pointer to receive message descriptor. */ @@ -176,10 +167,6 @@ static void mbox_message_dispose(struct k_mbox_msg *rx_msg) return; } - if (rx_msg->tx_block.data != NULL) { - rx_msg->tx_block.data = NULL; - } - /* recover sender info */ sending_thread = rx_msg->_syncing_thread; rx_msg->_syncing_thread = NULL; diff --git a/tests/kernel/mbox/mbox_api/src/test_mbox_api.c b/tests/kernel/mbox/mbox_api/src/test_mbox_api.c index c2e192819b9..e0268ea96e6 100644 --- a/tests/kernel/mbox/mbox_api/src/test_mbox_api.c +++ b/tests/kernel/mbox/mbox_api/src/test_mbox_api.c @@ -30,10 +30,9 @@ static struct k_mbox mbox; static k_tid_t sender_tid, receiver_tid, random_tid; static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); -static K_THREAD_STACK_DEFINE(rtstack, STACK_SIZE); static K_THREAD_STACK_DEFINE(tstack_1, STACK_SIZE); static K_THREAD_STACK_ARRAY_DEFINE(waiting_get_stack, 5, STACK_SIZE); -static struct k_thread tdata, rtdata, async_tid, waiting_get_tid[5]; +static struct k_thread tdata, async_tid, waiting_get_tid[5]; static struct k_sem end_sema, sync_sema; @@ -164,7 +163,6 @@ static void tmbox_put(struct k_mbox *pmbox) /* Get a msg and dispose it by making the size = 0 */ mmsg.size = 0; mmsg.tx_data = data[1]; - mmsg.tx_block.data = NULL; mmsg.tx_target_thread = K_ANY; zassert_true(k_mbox_put(pmbox, &mmsg, K_FOREVER) == 0); break; @@ -432,122 +430,6 @@ ZTEST(mbox_api, test_mbox_kdefine) tmbox(&kmbox); } -static void thread_mbox_data_get_null(void *p1, void *p2, void *p3) -{ - struct k_mbox_msg get_msg = {0}; - char str_data[] = "it string for get msg test"; - - get_msg.size = 16; - get_msg.rx_source_thread = K_ANY; - get_msg.tx_block.data = str_data; - get_msg._syncing_thread = NULL; - - k_mbox_data_get(&get_msg, NULL); - k_sem_give(&end_sema); -} - -/** - * - * @brief Test k_mbox_data_get() API - * - * @details - * - Init a mbox and just invoke k_mbox_data_get() with different - * input to check robust of API. - * - * @see k_mbox_data_get() - * - * @ingroup kernel_mbox_api - */ -ZTEST(mbox_api, test_mbox_data_get_null) -{ - k_sem_reset(&end_sema); - - receiver_tid = k_thread_create(&tdata, tstack, STACK_SIZE, - thread_mbox_data_get_null, - NULL, NULL, NULL, - K_PRIO_PREEMPT(0), 0, - K_NO_WAIT); - k_sem_take(&end_sema, K_FOREVER); - /*test case teardown*/ - k_thread_abort(receiver_tid); -} - -static void thread_mbox_get_block_data(void *p1, void *p2, void *p3) -{ - k_sem_take(&sync_sema, K_FOREVER); - struct k_mbox_msg bdmsg = {0}; - - bdmsg.size = MAIL_LEN; - bdmsg.rx_source_thread = sender_tid; - bdmsg.tx_target_thread = receiver_tid; - bdmsg.tx_data = NULL; - bdmsg.tx_block.data = data; - bdmsg.tx_data = data; - - zassert_equal(k_mbox_get((struct k_mbox *)p1, &bdmsg, p2, K_FOREVER), - 0, NULL); - - k_sem_give(&end_sema); -} - -/* give a block data to API k_mbox_async_put */ -static void thread_mbox_put_block_data(void *p1, void *p2, void *p3) -{ - struct k_mbox_msg put_msg = {0}; - - put_msg.size = MAIL_LEN; - put_msg.tx_data = NULL; - put_msg.tx_block.data = p2; - put_msg.tx_target_thread = receiver_tid; - put_msg.rx_source_thread = sender_tid; - - k_mbox_async_put((struct k_mbox *)p1, &put_msg, NULL); -} - -/** - * - * @brief Test put and get mailbox with block data - * - * @details - * - Create two threads to put and get block data with - * specify thread ID and K_FOREVER for each other. - * - Check the result after finished exchange. - * - * @see k_mbox_init() k_mbox_async_put() k_mbox_get() - * - * @ingroup kernel_mbox_api - */ -ZTEST(mbox_api, test_mbox_get_put_block_data) -{ - struct k_mbox bdmbox; - /*test case setup*/ - k_sem_reset(&end_sema); - k_sem_reset(&sync_sema); - k_mbox_init(&bdmbox); - char buff[MAIL_LEN]; - char data_put[] = "mbox put data"; - - /**TESTPOINT: thread-thread data passing via mbox*/ - sender_tid = k_current_get(); - receiver_tid = k_thread_create(&rtdata, rtstack, STACK_SIZE, - thread_mbox_get_block_data, - &bdmbox, buff, NULL, - K_PRIO_PREEMPT(0), 0, K_NO_WAIT); - - sender_tid = k_thread_create(&tdata, tstack, STACK_SIZE, - thread_mbox_put_block_data, - &bdmbox, data_put, NULL, - K_PRIO_PREEMPT(0), 0, K_NO_WAIT); - k_sem_give(&sync_sema); - k_sem_take(&end_sema, K_FOREVER); - /*abort receiver thread*/ - k_thread_abort(receiver_tid); - k_thread_abort(sender_tid); - - zassert_equal(memcmp(buff, data_put, sizeof(data_put)), 0, - NULL); -} - static ZTEST_BMEM char __aligned(4) buffer[8]; /** From 52f343c5c7817b9d4ba7440b93fa3c131bf473d4 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Sat, 30 Sep 2023 12:05:43 -0400 Subject: [PATCH 1957/4498] drivers: usb: Replace k_mem_block usage The k_mem_block structure has been obsolete for some years with a few loose ends still remaining. As its usage in the usb_dc_mcux codebase was confined to needing its "void *" pointer field, it was simple to enough to hoist that field to remove another loose end. Signed-off-by: Peter Mitsis --- drivers/usb/device/usb_dc_mcux.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/device/usb_dc_mcux.c b/drivers/usb/device/usb_dc_mcux.c index 27f7d254b8d..7278d25d728 100644 --- a/drivers/usb/device/usb_dc_mcux.c +++ b/drivers/usb/device/usb_dc_mcux.c @@ -89,7 +89,7 @@ K_HEAP_DEFINE(ep_buf_pool, 1024 * EP_BUF_NUMOF_BLOCKS); struct usb_ep_ctrl_data { usb_device_callback_message_struct_t transfer_message; - struct k_mem_block block; + void *block; usb_dc_ep_callback callback; uint16_t ep_mps; uint8_t ep_enabled : 1; @@ -276,21 +276,21 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg) /* Allocate buffers used during read operation */ if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) { #endif - struct k_mem_block *block; + void **block; block = &(eps->block); - if (block->data) { - k_heap_free(&ep_buf_pool, block->data); - block->data = NULL; + if (*block) { + k_heap_free(&ep_buf_pool, *block); + *block = NULL; } - block->data = k_heap_alloc(&ep_buf_pool, cfg->ep_mps, K_NO_WAIT); - if (block->data == NULL) { + *block = k_heap_alloc(&ep_buf_pool, cfg->ep_mps, K_NO_WAIT); + if (*block == NULL) { LOG_ERR("Failed to allocate memory"); return -ENOMEM; } - memset(block->data, 0, cfg->ep_mps); + memset(*block, 0, cfg->ep_mps); #ifdef CONFIG_USB_DC_NXP_LPCIP3511 } #endif @@ -362,7 +362,7 @@ int usb_dc_ep_clear_stall(const uint8_t ep) (USB_EP_DIR_IS_OUT(ep))) { status = dev_state.dev_struct.controllerInterface->deviceRecv( dev_state.dev_struct.controllerHandle, ep, - (uint8_t *)dev_state.eps[ep_abs_idx].block.data, + (uint8_t *)dev_state.eps[ep_abs_idx].block, (uint32_t)dev_state.eps[ep_abs_idx].ep_mps); if (kStatus_USB_Success != status) { LOG_ERR("Failed to enable reception on 0x%02x", ep); @@ -438,7 +438,7 @@ int usb_dc_ep_enable(const uint8_t ep) (USB_EP_DIR_IS_OUT(ep))) { status = dev_state.dev_struct.controllerInterface->deviceRecv( dev_state.dev_struct.controllerHandle, ep, - (uint8_t *)dev_state.eps[ep_abs_idx].block.data, + (uint8_t *)dev_state.eps[ep_abs_idx].block, (uint32_t)dev_state.eps[ep_abs_idx].ep_mps); if (kStatus_USB_Success != status) { LOG_ERR("Failed to enable reception on 0x%02x", ep); @@ -520,7 +520,7 @@ int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data, * if available. */ #ifndef CONFIG_USB_DC_NXP_LPCIP3511 - buffer = (uint8_t *)dev_state.eps[ep_abs_idx].block.data; + buffer = (uint8_t *)dev_state.eps[ep_abs_idx].block; if (data_len > dev_state.eps[ep_abs_idx].ep_mps) { len_to_send = dev_state.eps[ep_abs_idx].ep_mps; @@ -674,7 +674,7 @@ int usb_dc_ep_read_continue(uint8_t ep) status = dev_state.dev_struct.controllerInterface->deviceRecv( dev_state.dev_struct.controllerHandle, ep, - (uint8_t *)dev_state.eps[ep_abs_idx].block.data, + (uint8_t *)dev_state.eps[ep_abs_idx].block, dev_state.eps[ep_abs_idx].ep_mps); if (kStatus_USB_Success != status) { LOG_ERR("Failed to enable reception on ep 0x%02x", ep); From a35e40f410750f3205f0d87489aa0dfa4006e1d3 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 18 Sep 2023 11:08:49 -0400 Subject: [PATCH 1958/4498] kernel: Remove mempool_heap Removes the mempool_heap.h header file as nothing needs it anymore. Signed-off-by: Peter Mitsis --- include/zephyr/kernel/mempool_heap.h | 31 ---------------------------- include/zephyr/kernel_includes.h | 1 - 2 files changed, 32 deletions(-) delete mode 100644 include/zephyr/kernel/mempool_heap.h diff --git a/include/zephyr/kernel/mempool_heap.h b/include/zephyr/kernel/mempool_heap.h deleted file mode 100644 index d9126facc01..00000000000 --- a/include/zephyr/kernel/mempool_heap.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_INCLUDE_MEMPOOL_HEAP_H_ -#define ZEPHYR_INCLUDE_MEMPOOL_HEAP_H_ - -/* Compatibility implementation of a k_mem_pool backend in terms of a - * k_heap - */ - -/* The "ID" of a k_heap-based mempool is just the tuple of the data - * block pointer and the heap that allocated it - */ -struct k_mem_block_id { - void *data; - struct k_heap *heap; -}; - -/* Note the data pointer gets unioned with the same value stored in - * the ID field to save space. - */ -struct k_mem_block { - union { - void *data; - struct k_mem_block_id id; - }; -}; - -#endif /* ZEPHYR_INCLUDE_MEMPOOL_HEAP_H_ */ diff --git a/include/zephyr/kernel_includes.h b/include/zephyr/kernel_includes.h index 31c6da3d617..752c92da46d 100644 --- a/include/zephyr/kernel_includes.h +++ b/include/zephyr/kernel_includes.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include From 86ed4c0ae89e9db02dd7c3b209e045c3eb485507 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 5 Oct 2023 13:56:36 -0400 Subject: [PATCH 1959/4498] west.yml: Pull in latest percepio updates Pulls in the latest percepio updates that removes references to the defunct k_pipe_block_put() routine (and k_mem_block too). Signed-off-by: Peter Mitsis --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d3aa85303e2..5e3d157a0ba 100644 --- a/west.yml +++ b/west.yml @@ -304,7 +304,7 @@ manifest: path: modules/lib/openthread - name: percepio path: modules/debug/percepio - revision: 79d586d592fca3e9fecd8886af6acd8c7bb66314 + revision: a3728efccc47dd372f40e6313589ca4c5cc7d5e9 groups: - debug - name: picolibc From f9c7a5e6fb44cfd67c3cb6bd33dfaa17fcc7378f Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 9 Oct 2023 15:22:18 -0700 Subject: [PATCH 1960/4498] kernel: random: Rename early random get function Rename z_early_boot_rand_get with z_early_rand_get to get consistent with other early functions. Signed-off-by: Flavio Ceolin --- kernel/include/kernel_internal.h | 2 +- kernel/init.c | 4 ++-- kernel/thread.c | 2 +- tests/crypto/rand32/src/main.c | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index 3c379559f72..711313b5ce7 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -149,7 +149,7 @@ extern void smp_timer_init(void); #endif #endif -extern void z_early_boot_rand_get(uint8_t *buf, size_t length); +extern void z_early_rand_get(uint8_t *buf, size_t length); #if CONFIG_STACK_POINTER_RANDOM extern int z_stack_adjust_initialized; diff --git a/kernel/init.c b/kernel/init.c index 536756268b3..7ea56714192 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -510,7 +510,7 @@ static FUNC_NORETURN void switch_to_main_thread(char *stack_ptr) #if defined(CONFIG_ENTROPY_HAS_DRIVER) || defined(CONFIG_TEST_RANDOM_GENERATOR) __boot_func -void z_early_boot_rand_get(uint8_t *buf, size_t length) +void z_early_rand_get(uint8_t *buf, size_t length) { #ifdef CONFIG_ENTROPY_HAS_DRIVER const struct device *const entropy = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); @@ -592,7 +592,7 @@ FUNC_NORETURN void z_cstart(void) #ifdef CONFIG_STACK_CANARIES uintptr_t stack_guard; - z_early_boot_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard)); + z_early_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard)); __stack_chk_guard = stack_guard; __stack_chk_guard <<= 8; #endif /* CONFIG_STACK_CANARIES */ diff --git a/kernel/thread.c b/kernel/thread.c index f19c502a3ff..2703116aca5 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -464,7 +464,7 @@ static size_t random_offset(size_t stack_size) size_t random_val; if (!z_stack_adjust_initialized) { - z_early_boot_rand_get((uint8_t *)&random_val, sizeof(random_val)); + z_early_rand_get((uint8_t *)&random_val, sizeof(random_val)); } else { sys_rand_get((uint8_t *)&random_val, sizeof(random_val)); } diff --git a/tests/crypto/rand32/src/main.c b/tests/crypto/rand32/src/main.c index 39cf40543bc..1f2492e69e3 100644 --- a/tests/crypto/rand32/src/main.c +++ b/tests/crypto/rand32/src/main.c @@ -8,7 +8,7 @@ /* * This tests the following random number routines: - * void z_early_boot_rand_get(uint8_t *buf, size_t length) + * void z_early_rand_get(uint8_t *buf, size_t length) * uint32_t sys_rand32_get(void); */ @@ -35,11 +35,11 @@ ZTEST(rand32_common, test_rand32) /* Test early boot random number generation function */ /* Cover the case, where argument "length" is < size of "size_t" */ - z_early_boot_rand_get((uint8_t *)&tmp, (size_t)1); - z_early_boot_rand_get((uint8_t *)&last_gen, sizeof(last_gen)); - z_early_boot_rand_get((uint8_t *)&gen, sizeof(gen)); + z_early_rand_get((uint8_t *)&tmp, (size_t)1); + z_early_rand_get((uint8_t *)&last_gen, sizeof(last_gen)); + z_early_rand_get((uint8_t *)&gen, sizeof(gen)); zassert_true(last_gen != gen && last_gen != tmp && tmp != gen, - "z_early_boot_rand_get failed"); + "z_early_rand_get failed"); /* * Test subsequently calls sys_rand32_get(), checking From 974e3361408029864be53b376b7745acb3cc673a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 9 Oct 2023 15:25:42 -0700 Subject: [PATCH 1961/4498] kernel: random: Make z_early_rand_get a weak symbol Allow targets come up with their own early random generator since the default can be NOT so random due constraints. Signed-off-by: Flavio Ceolin --- kernel/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/init.c b/kernel/init.c index 7ea56714192..a4ae985d6dc 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -510,7 +510,7 @@ static FUNC_NORETURN void switch_to_main_thread(char *stack_ptr) #if defined(CONFIG_ENTROPY_HAS_DRIVER) || defined(CONFIG_TEST_RANDOM_GENERATOR) __boot_func -void z_early_rand_get(uint8_t *buf, size_t length) +void __weak z_early_rand_get(uint8_t *buf, size_t length) { #ifdef CONFIG_ENTROPY_HAS_DRIVER const struct device *const entropy = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); From 6c0fad2888255e661925ef9f49b8b776844d809a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 9 Oct 2023 20:52:07 -0700 Subject: [PATCH 1962/4498] kernel: Fixes for z_early_rand_get The early random get function was making many wrong assumptions about random subsys and entropy drivers. First, it was assuming that entropy_get_entropy() would be ISR safe, that is not right, the driver has an ISR safe callback and if it is not implemented or not working it is not ok using the other callback. Second, the fallback to the random subsys is even more problematic since they can use kernel services to protect internal states and be thread-safe. Another incorrect thing in this function was the guard around it. It was needed by features like stack randomization and stack canaries, and not when those conditions were match. Just remove it and in case it is not needed the linker will take care of it. The drawback of this change is that in the absence of an entropy generator with support to be called from ISR the randomness is very weak. Signed-off-by: Flavio Ceolin --- kernel/init.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index a4ae985d6dc..caa7724acc4 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -508,46 +508,38 @@ static FUNC_NORETURN void switch_to_main_thread(char *stack_ptr) } #endif /* CONFIG_MULTITHREADING */ -#if defined(CONFIG_ENTROPY_HAS_DRIVER) || defined(CONFIG_TEST_RANDOM_GENERATOR) __boot_func void __weak z_early_rand_get(uint8_t *buf, size_t length) { -#ifdef CONFIG_ENTROPY_HAS_DRIVER - const struct device *const entropy = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); + static uint64_t state = 123456789UL; int rc; - if (!device_is_ready(entropy)) { - goto sys_rand_fallback; - } - - /* Try to see if driver provides an ISR-specific API */ - rc = entropy_get_entropy_isr(entropy, buf, length, ENTROPY_BUSYWAIT); - if (rc == -ENOTSUP) { - /* Driver does not provide an ISR-specific API, assume it can - * be called from ISR context - */ - rc = entropy_get_entropy(entropy, buf, length); - } +#ifdef CONFIG_ENTROPY_HAS_DRIVER + const struct device *const entropy = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); - if (rc >= 0) { - return; + if ((entropy != NULL) && device_is_ready(entropy)) { + /* Try to see if driver provides an ISR-specific API */ + rc = entropy_get_entropy_isr(entropy, buf, length, ENTROPY_BUSYWAIT); + if (rc > 0) { + length -= rc; + buf += rc; + } } +#endif - /* Fall through to fallback */ + while (length > 0) { + uint32_t val; -sys_rand_fallback: -#endif + state = state + k_cycle_get_32(); + state = state * 2862933555777941757ULL + 3037000493ULL; + val = (uint32_t)(state >> 32); + rc = MIN(length, sizeof(val)); + z_early_memcpy((void *)buf, &val, rc); - /* FIXME: this assumes sys_rand32_get() won't use any synchronization - * primitive, like semaphores or mutexes. It's too early in the boot - * process to use any of them. Ideally, only the path where entropy - * devices are available should be built, this is only a fallback for - * those devices without a HWRNG entropy driver. - */ - sys_rand_get(buf, length); + length -= rc; + buf += rc; + } } -/* defined(CONFIG_ENTROPY_HAS_DRIVER) || defined(CONFIG_TEST_RANDOM_GENERATOR) */ -#endif /** * From a99a0700ba99228bd7ab993a11e086e67e2981fe Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 10:17:36 -0700 Subject: [PATCH 1963/4498] random: kconfig: Allow customizing timer initial state Add a build option to allow changing the initial state used in the timer based random generator and by the kernel in the early random number generator. Signed-off-by: Flavio Ceolin --- subsys/random/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/random/Kconfig b/subsys/random/Kconfig index b8b6b2135c2..72106f09b57 100644 --- a/subsys/random/Kconfig +++ b/subsys/random/Kconfig @@ -28,6 +28,14 @@ config TEST_RANDOM_GENERATOR device-backed random number generator, if available, will be selected by default even when CONFIG_TEST_RANDOM_GENERATOR=y. +config TIMER_RANDOM_INITIAL_STATE + int "Initial state used by clock based number generator" + default 123456789 + help + Initial state value used by TIMER_RANDOM_GENERATOR and + early random number genenator. + + choice RNG_GENERATOR_CHOICE prompt "Random generator" default ENTROPY_DEVICE_RANDOM_GENERATOR if ENTROPY_HAS_DRIVER From 991ff6f48b5adaa9633d6171bbe7791a7612739c Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 10:31:35 -0700 Subject: [PATCH 1964/4498] kernel: init: Build constant in early random generator Use a Kconfig symbol for initial state in the early random number generator. Signed-off-by: Flavio Ceolin --- kernel/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/init.c b/kernel/init.c index caa7724acc4..c2109499a07 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -511,7 +511,7 @@ static FUNC_NORETURN void switch_to_main_thread(char *stack_ptr) __boot_func void __weak z_early_rand_get(uint8_t *buf, size_t length) { - static uint64_t state = 123456789UL; + static uint64_t state = (uint64_t)CONFIG_TIMER_RANDOM_INITIAL_STATE; int rc; #ifdef CONFIG_ENTROPY_HAS_DRIVER From 5fcae0c0216ab82f200880e3c979cca2fb585fef Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 10:34:23 -0700 Subject: [PATCH 1965/4498] random: timer: Use build constant for seed Use Kconfig symbol for initial seed. Signed-off-by: Flavio Ceolin --- subsys/random/rand32_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/random/rand32_timer.c b/subsys/random/rand32_timer.c index b5e2769b1ce..4232dccfbc8 100644 --- a/subsys/random/rand32_timer.c +++ b/subsys/random/rand32_timer.c @@ -35,7 +35,8 @@ static struct k_spinlock rand32_lock; */ uint32_t z_impl_sys_rand32_get(void) { - static uint64_t state = 123456789UL; /* initial seed value */ + /* initial seed value */ + static uint64_t state = (uint64_t)CONFIG_TIMER_RANDOM_INITIAL_STATE; k_spinlock_key_t key = k_spin_lock(&rand32_lock); state = state + k_cycle_get_32(); From 0136759707aff48e50ec03e0f7a3a4bc085edc13 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Sun, 8 Oct 2023 17:28:44 +0800 Subject: [PATCH 1966/4498] test: posix: common: nanosleep test fix in test_nanosleep_execution, the actual_ns = k_cyc_to_ns_ceil64((now - then * selection)); is wrong, according to posix driver code lib/posix/clock.c line: 156 if ((flags & TIMER_ABSTIME) == 0) { ns += uptime_ns; } so we need change to actual_ns = k_cyc_to_ns_ceil64((now + then * selection)); fixing: #62889 Co-authored-by: Christopher Friedt Signed-off-by: Hake Huang --- tests/posix/common/src/nanosleep.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/posix/common/src/nanosleep.c b/tests/posix/common/src/nanosleep.c index 5e4d3bcf88d..f59ead94aaa 100644 --- a/tests/posix/common/src/nanosleep.c +++ b/tests/posix/common/src/nanosleep.c @@ -120,6 +120,22 @@ ZTEST(posix_apis, test_clock_nanosleep_errors_errno) zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d", rem.tv_nsec, 0); } +/** + * @brief Check that a call to nanosleep has yielded executiuon for some minimum time. + * + * Check that the actual time slept is >= the total time specified by @p s (in seconds) and + * @p ns (in nanoseconds). + * + * @note The time specified by @p s and @p ns is assumed to be absolute (i.e. a time-point) + * when @p selection is set to @ref SELECT_CLOCK_NANOSLEEP. The time is assumed to be relative + * when @p selection is set to @ref SELECT_NANOSLEEP. + * + * @param selection Either @ref SELECT_CLOCK_NANOSLEEP or @ref SELECT_NANOSLEEP + * @param clock_id The clock to test (e.g. @ref CLOCK_MONOTONIC or @ref CLOCK_REALTIME) + * @param flags Flags to pass to @ref clock_nanosleep + * @param s Partial lower bound for yielded time (in seconds) + * @param ns Partial lower bound for yielded time (in nanoseconds) + */ static void common_lower_bound_check(int selection, clockid_t clock_id, int flags, const uint32_t s, uint32_t ns) { @@ -143,7 +159,19 @@ static void common_lower_bound_check(int selection, clockid_t clock_id, int flag zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d", rem.tv_sec, 0); zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d", rem.tv_nsec, 0); - actual_ns = k_cyc_to_ns_ceil64((now - then * selection)); + switch (selection) { + case SELECT_NANOSLEEP: + /* exp_ns and actual_ns are relative (i.e. durations) */ + actual_ns = k_cyc_to_ns_ceil64(now + then); + break; + case SELECT_CLOCK_NANOSLEEP: + /* exp_ns and actual_ns are absolute (i.e. time-points) */ + actual_ns = k_cyc_to_ns_ceil64(now); + break; + default: + zassert_unreachable(); + break; + } exp_ns = (uint64_t)s * NSEC_PER_SEC + ns; /* round up to the nearest microsecond for k_busy_wait() */ From cdd17ce100fdce027ae82e0c7baec362120716a9 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Thu, 12 Oct 2023 11:38:02 +0800 Subject: [PATCH 1967/4498] test: posix: nanosleep: use k_cycle_64 as possible as posix nanosleep is actually call us, so we need use a higher clock to compare the result. try to use k_cycle_64 as possible. Co-authored-by: Christopher Friedt Signed-off-by: Hake Huang --- tests/posix/common/src/nanosleep.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/posix/common/src/nanosleep.c b/tests/posix/common/src/nanosleep.c index f59ead94aaa..d2d92a5ce6b 100644 --- a/tests/posix/common/src/nanosleep.c +++ b/tests/posix/common/src/nanosleep.c @@ -23,6 +23,15 @@ static inline int select_nanosleep(int selection, clockid_t clock_id, int flags, return clock_nanosleep(clock_id, flags, rqtp, rmtp); } +static inline uint64_t cycle_get_64(void) +{ + if (IS_ENABLED(CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER)) { + return k_cycle_get_64(); + } else { + return k_cycle_get_32(); + } +} + static void common_errors(int selection, clockid_t clock_id, int flags) { struct timespec rem = {}; @@ -142,15 +151,15 @@ static void common_lower_bound_check(int selection, clockid_t clock_id, int flag int r; uint64_t actual_ns; uint64_t exp_ns; - uint32_t now; - uint32_t then; + uint64_t now; + uint64_t then; struct timespec rem = {0, 0}; struct timespec req = {s, ns}; errno = 0; - then = k_cycle_get_32(); + then = cycle_get_64(); r = select_nanosleep(selection, clock_id, flags, &req, &rem); - now = k_cycle_get_32(); + now = cycle_get_64(); zassert_equal(r, 0, "actual: %d expected: %d", r, 0); zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0); From 4d2251ad09014490b8aa44997854519024043efa Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:18:47 +0200 Subject: [PATCH 1968/4498] tests: drivers: can: api: only compare frame data for non-RTR frames Only compare frame data contents for non-RTR frames as RTR frames do not carry any data. Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/api/src/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/drivers/can/api/src/common.c b/tests/drivers/can/api/src/common.c index fd85c2938bf..8d6889fd28f 100644 --- a/tests/drivers/can/api/src/common.c +++ b/tests/drivers/can/api/src/common.c @@ -252,5 +252,9 @@ void assert_frame_equal(const struct can_frame *frame1, zassert_equal(frame1->flags, frame2->flags, "Flags do not match"); zassert_equal(frame1->id | id_mask, frame2->id | id_mask, "ID does not match"); zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match"); - zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ"); + + if ((frame1->flags & CAN_FRAME_RTR) == 0U) { + zassert_mem_equal(frame1->data, frame2->data, can_dlc_to_bytes(frame1->dlc), + "Received data differ"); + } } From b603910214c01215698053e42421a3c426d19780 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:20:34 +0200 Subject: [PATCH 1969/4498] tests: net: socket: can: split RTR flag from data contents test Split the conversion of the RTR frame flags from the data contents test as RTR frames do not carry any data. Replace a couple of direct DLC assignments with proper use of can_bytes_to_dlc(). Signed-off-by: Henrik Brix Andersen --- tests/net/socket/can/src/main.c | 37 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/tests/net/socket/can/src/main.c b/tests/net/socket/can/src/main.c index d4021fbf170..02d209c022e 100644 --- a/tests/net/socket/can/src/main.c +++ b/tests/net/socket/can/src/main.c @@ -23,13 +23,14 @@ ZTEST(socket_can, test_socketcan_frame_to_can_frame) const uint8_t data[SOCKETCAN_MAX_DLEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; - sframe.can_id = BIT(31) | BIT(30) | 1234; + sframe.can_id = BIT(31) | 1234; sframe.len = sizeof(data); memcpy(sframe.data, data, sizeof(sframe.data)); - expected.flags = CAN_FRAME_IDE | CAN_FRAME_RTR; + expected.flags = CAN_FRAME_IDE; expected.id = 1234U; - expected.dlc = sizeof(data); + expected.dlc = can_bytes_to_dlc(sizeof(data)); + memcpy(expected.data, data, sizeof(data)); socketcan_to_can_frame(&sframe, &zframe); @@ -40,6 +41,17 @@ ZTEST(socket_can, test_socketcan_frame_to_can_frame) zassert_equal(zframe.flags, expected.flags, "Flags not equal"); zassert_equal(zframe.id, expected.id, "CAN id invalid"); zassert_equal(zframe.dlc, expected.dlc, "Msg length invalid"); + zassert_mem_equal(&zframe.data, &expected.data, can_dlc_to_bytes(expected.dlc), + "CAN data not same"); + + /* Test RTR flag conversion after comparing data payload */ + sframe.can_id |= BIT(30); + expected.flags |= CAN_FRAME_RTR; + + socketcan_to_can_frame(&sframe, &zframe); + + zassert_equal(zframe.flags, expected.flags, "Flags not equal"); + zassert_equal(zframe.id, expected.id, "CAN id invalid"); } /** @@ -53,13 +65,13 @@ ZTEST(socket_can, test_can_frame_to_socketcan_frame) const uint8_t data[SOCKETCAN_MAX_DLEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; - expected.can_id = BIT(31) | BIT(30) | 1234; + expected.can_id = BIT(31) | 1234; expected.len = sizeof(data); memcpy(expected.data, data, sizeof(expected.data)); - zframe.flags = CAN_FRAME_IDE | CAN_FRAME_RTR; + zframe.flags = CAN_FRAME_IDE; zframe.id = 1234U; - zframe.dlc = sizeof(data); + zframe.dlc = can_bytes_to_dlc(sizeof(data)); memcpy(zframe.data, data, sizeof(data)); socketcan_from_can_frame(&zframe, &sframe); @@ -69,10 +81,15 @@ ZTEST(socket_can, test_can_frame_to_socketcan_frame) LOG_HEXDUMP_DBG((const uint8_t *)&expected, sizeof(expected), "expected"); zassert_equal(sframe.can_id, expected.can_id, "CAN ID not same"); - zassert_mem_equal(&sframe.data, &expected.data, sizeof(sframe.data), - "CAN data not same"); - zassert_equal(sframe.len, expected.len, - "CAN msg length not same"); + zassert_equal(sframe.len, expected.len, "CAN msg length not same"); + zassert_mem_equal(&sframe.data, &expected.data, sizeof(sframe.data), "CAN data not same"); + + /* Test RTR flag conversion after comparing data payload */ + expected.can_id |= BIT(30); + zframe.flags |= CAN_FRAME_RTR; + + socketcan_from_can_frame(&zframe, &sframe); + zassert_equal(sframe.can_id, expected.can_id, "CAN ID not same"); } /** From 912fc489b82ba9d93d1246d4daa46e05d8d43647 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:24:08 +0200 Subject: [PATCH 1970/4498] net: socketcan: only copy data payload for non-RTR frames Only copy the data payload for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- include/zephyr/net/socketcan_utils.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/socketcan_utils.h b/include/zephyr/net/socketcan_utils.h index 24a95776e0b..22364cd328b 100644 --- a/include/zephyr/net/socketcan_utils.h +++ b/include/zephyr/net/socketcan_utils.h @@ -44,7 +44,11 @@ static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe, zframe->flags |= (sframe->flags & CANFD_BRS) != 0 ? CAN_FRAME_BRS : 0; zframe->id = sframe->can_id & BIT_MASK(29); zframe->dlc = can_bytes_to_dlc(sframe->len); - memcpy(zframe->data, sframe->data, MIN(sizeof(sframe->data), sizeof(zframe->data))); + + if ((zframe->flags & CAN_FRAME_RTR) == 0U) { + memcpy(zframe->data, sframe->data, + MIN(sframe->len, MIN(sizeof(sframe->data), sizeof(zframe->data)))); + } } /** @@ -71,7 +75,10 @@ static inline void socketcan_from_can_frame(const struct can_frame *zframe, sframe->flags |= CANFD_BRS; } - memcpy(sframe->data, zframe->data, MIN(sizeof(zframe->data), sizeof(sframe->data))); + if ((zframe->flags & CAN_FRAME_RTR) == 0U) { + memcpy(sframe->data, zframe->data, + MIN(sframe->len, MIN(sizeof(zframe->data), sizeof(sframe->data)))); + } } /** From 27323a8af57771dabd4d946ed8ca821f77ad6b03 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:27:47 +0200 Subject: [PATCH 1971/4498] drivers: can: mcan: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcan.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index df796350263..550f29b2334 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -694,14 +694,16 @@ static void can_mcan_get_message(const struct device *dev, uint16_t fifo_offset, data_length = can_dlc_to_bytes(frame.dlc); if (data_length <= sizeof(frame.data)) { - err = can_mcan_read_mram(dev, fifo_offset + get_idx * - sizeof(struct can_mcan_rx_fifo) + - offsetof(struct can_mcan_rx_fifo, data_32), - &frame.data_32, - ROUND_UP(data_length, sizeof(uint32_t))); - if (err != 0) { - LOG_ERR("failed to read Rx FIFO data (err %d)", err); - return; + if ((frame.flags & CAN_FRAME_RTR) == 0U) { + err = can_mcan_read_mram(dev, fifo_offset + get_idx * + sizeof(struct can_mcan_rx_fifo) + + offsetof(struct can_mcan_rx_fifo, data_32), + &frame.data_32, + ROUND_UP(data_length, sizeof(uint32_t))); + if (err != 0) { + LOG_ERR("failed to read Rx FIFO data (err %d)", err); + return; + } } if ((frame.flags & CAN_FRAME_IDE) != 0) { @@ -953,13 +955,15 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim goto err_unlock; } - err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_BUFFER] + put_idx * - sizeof(struct can_mcan_tx_buffer) + - offsetof(struct can_mcan_tx_buffer, data_32), - &frame->data_32, ROUND_UP(data_length, sizeof(uint32_t))); - if (err != 0) { - LOG_ERR("failed to write Tx Buffer data (err %d)", err); - goto err_unlock; + if ((frame->flags & CAN_FRAME_RTR) == 0U) { + err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_BUFFER] + + put_idx * sizeof(struct can_mcan_tx_buffer) + + offsetof(struct can_mcan_tx_buffer, data_32), + &frame->data_32, ROUND_UP(data_length, sizeof(uint32_t))); + if (err != 0) { + LOG_ERR("failed to write Tx Buffer data (err %d)", err); + goto err_unlock; + } } __ASSERT_NO_MSG(put_idx < cbs->num_tx); From 4d321448add4145756d7b9e751331b7586775958 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:28:58 +0200 Subject: [PATCH 1972/4498] drivers: can: mcp2515: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Limit the amount of data copied to the actual DLC. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcp2515.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index e6092d0ce92..703aeb1543d 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -219,7 +219,7 @@ static void mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame { uint8_t rtr; uint8_t dlc; - uint8_t data_idx = 0U; + uint8_t data_idx; if ((source->flags & CAN_FRAME_IDE) != 0) { target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21; @@ -239,16 +239,18 @@ static void mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame target[MCP2515_FRAME_OFFSET_DLC] = rtr | dlc; - for (; data_idx < CAN_MAX_DLC; data_idx++) { - target[MCP2515_FRAME_OFFSET_D0 + data_idx] = - source->data[data_idx]; + if (rtr == 0U) { + for (data_idx = 0U; data_idx < dlc; data_idx++) { + target[MCP2515_FRAME_OFFSET_D0 + data_idx] = + source->data[data_idx]; + } } } static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source, struct can_frame *target) { - uint8_t data_idx = 0U; + uint8_t data_idx; memset(target, 0, sizeof(*target)); @@ -269,11 +271,11 @@ static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source, if ((source[MCP2515_FRAME_OFFSET_DLC] & BIT(6)) != 0) { target->flags |= CAN_FRAME_RTR; - } - - for (; data_idx < CAN_MAX_DLC; data_idx++) { - target->data[data_idx] = source[MCP2515_FRAME_OFFSET_D0 + - data_idx]; + } else { + for (data_idx = 0U; data_idx < target->dlc; data_idx++) { + target->data[data_idx] = source[MCP2515_FRAME_OFFSET_D0 + + data_idx]; + } } } From 66daf0543581d603bb2087d969e87025567c5c47 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:30:25 +0200 Subject: [PATCH 1973/4498] drivers: can: mcp251xfd: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcp251xfd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c index 055fc454ef3..3f94ed52319 100644 --- a/drivers/can/can_mcp251xfd.c +++ b/drivers/can/can_mcp251xfd.c @@ -30,7 +30,7 @@ LOG_MODULE_REGISTER(can_mcp251xfd, CONFIG_CAN_LOG_LEVEL); static void mcp251xfd_canframe_to_txobj(const struct can_frame *src, int mailbox_idx, struct mcp251xfd_txobj *dst) { - dst->flags = 0; + memset(dst, 0, sizeof(*dst)); if ((src->flags & CAN_FRAME_IDE) != 0) { dst->id = FIELD_PREP(MCP251XFD_OBJ_ID_SID_MASK, src->id >> 18); @@ -45,10 +45,6 @@ static void mcp251xfd_canframe_to_txobj(const struct can_frame *src, int mailbox dst->flags |= MCP251XFD_OBJ_FLAGS_BRS; } - if ((src->flags & CAN_FRAME_RTR) != 0) { - dst->flags |= MCP251XFD_OBJ_FLAGS_RTR; - } - dst->flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_DLC_MASK, src->dlc); #if defined(CONFIG_CAN_FD_MODE) if ((src->flags & CAN_FRAME_FDF) != 0) { @@ -60,7 +56,11 @@ static void mcp251xfd_canframe_to_txobj(const struct can_frame *src, int mailbox dst->id = sys_cpu_to_le32(dst->id); dst->flags = sys_cpu_to_le32(dst->flags); - memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(src->dlc), CAN_MAX_DLEN)); + if ((src->flags & CAN_FRAME_RTR) != 0) { + dst->flags |= MCP251XFD_OBJ_FLAGS_RTR; + } else { + memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(src->dlc), CAN_MAX_DLEN)); + } } static void *mcp251xfd_read_reg(const struct device *dev, uint16_t addr, int len) @@ -208,7 +208,7 @@ static int mcp251xfd_fifo_write(const struct device *dev, int mailbox_idx, static void mcp251xfd_rxobj_to_canframe(struct mcp251xfd_rxobj *src, struct can_frame *dst) { - memset(dst, 0, offsetof(struct can_frame, data)); + memset(dst, 0, sizeof(*dst)); src->id = sys_le32_to_cpu(src->id); src->flags = sys_le32_to_cpu(src->flags); @@ -225,10 +225,6 @@ static void mcp251xfd_rxobj_to_canframe(struct mcp251xfd_rxobj *src, struct can_ dst->flags |= CAN_FRAME_BRS; } - if ((src->flags & MCP251XFD_OBJ_FLAGS_RTR) != 0) { - dst->flags |= CAN_FRAME_RTR; - } - #if defined(CONFIG_CAN_FD_MODE) if ((src->flags & MCP251XFD_OBJ_FLAGS_FDF) != 0) { dst->flags |= CAN_FRAME_FDF; @@ -241,7 +237,11 @@ static void mcp251xfd_rxobj_to_canframe(struct mcp251xfd_rxobj *src, struct can_ dst->timestamp = sys_le32_to_cpu(src->timestamp); #endif - memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(dst->dlc), CAN_MAX_DLEN)); + if ((src->flags & MCP251XFD_OBJ_FLAGS_RTR) != 0) { + dst->flags |= CAN_FRAME_RTR; + } else { + memcpy(dst->data, src->data, MIN(can_dlc_to_bytes(dst->dlc), CAN_MAX_DLEN)); + } } static int mcp251xfd_get_mode_internal(const struct device *dev, uint8_t *mode) From c986dcc027a91beb371e57dda5a540503765ea53 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:31:50 +0200 Subject: [PATCH 1974/4498] drivers: can: mcux: flexcan: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. The limitation of how much data to copy is currently handled in the NXP HAL. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcux_flexcan.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 5b4e557a931..a80204e28c5 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -520,11 +520,11 @@ static void mcux_flexcan_from_can_frame(const struct can_frame *src, dest->type = kFLEXCAN_FrameTypeRemote; } else { dest->type = kFLEXCAN_FrameTypeData; + dest->dataWord0 = sys_cpu_to_be32(src->data_32[0]); + dest->dataWord1 = sys_cpu_to_be32(src->data_32[1]); } dest->length = src->dlc; - dest->dataWord0 = sys_cpu_to_be32(src->data_32[0]); - dest->dataWord1 = sys_cpu_to_be32(src->data_32[1]); } static void mcux_flexcan_to_can_frame(const flexcan_frame_t *src, @@ -541,11 +541,12 @@ static void mcux_flexcan_to_can_frame(const flexcan_frame_t *src, if (src->type == kFLEXCAN_FrameTypeRemote) { dest->flags |= CAN_FRAME_RTR; + } else { + dest->data_32[0] = sys_be32_to_cpu(src->dataWord0); + dest->data_32[1] = sys_be32_to_cpu(src->dataWord1); } dest->dlc = src->length; - dest->data_32[0] = sys_be32_to_cpu(src->dataWord0); - dest->data_32[1] = sys_be32_to_cpu(src->dataWord1); #ifdef CONFIG_CAN_RX_TIMESTAMP dest->timestamp = src->timestamp; #endif /* CAN_RX_TIMESTAMP */ @@ -571,6 +572,10 @@ static void mcux_flexcan_fd_from_can_frame(const struct can_frame *src, dest->type = kFLEXCAN_FrameTypeRemote; } else { dest->type = kFLEXCAN_FrameTypeData; + + for (i = 0; i < ARRAY_SIZE(dest->dataWord); i++) { + dest->dataWord[i] = sys_cpu_to_be32(src->data_32[i]); + } } if ((src->flags & CAN_FRAME_FDF) != 0) { @@ -582,9 +587,6 @@ static void mcux_flexcan_fd_from_can_frame(const struct can_frame *src, } dest->length = src->dlc; - for (i = 0; i < ARRAY_SIZE(dest->dataWord); i++) { - dest->dataWord[i] = sys_cpu_to_be32(src->data_32[i]); - } } static void mcux_flexcan_fd_to_can_frame(const flexcan_fd_frame_t *src, @@ -603,6 +605,10 @@ static void mcux_flexcan_fd_to_can_frame(const flexcan_fd_frame_t *src, if (src->type == kFLEXCAN_FrameTypeRemote) { dest->flags |= CAN_FRAME_RTR; + } else { + for (i = 0; i < ARRAY_SIZE(dest->data_32); i++) { + dest->data_32[i] = sys_be32_to_cpu(src->dataWord[i]); + } } if (src->edl != 0) { @@ -618,9 +624,7 @@ static void mcux_flexcan_fd_to_can_frame(const flexcan_fd_frame_t *src, } dest->dlc = src->length; - for (i = 0; i < ARRAY_SIZE(dest->data_32); i++) { - dest->data_32[i] = sys_be32_to_cpu(src->dataWord[i]); - } + #ifdef CONFIG_CAN_RX_TIMESTAMP dest->timestamp = src->timestamp; #endif /* CAN_RX_TIMESTAMP */ From 443847f0f6ac48e6a1c21049ee7429fa864f3982 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:33:29 +0200 Subject: [PATCH 1975/4498] drivers: can: nxp: s32: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_nxp_s32_canxl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index bf6b4dd86f3..a4ab50838cb 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -728,14 +728,12 @@ static void can_nxp_s32_err_callback(const struct device *dev, static void nxp_s32_msg_data_to_zcan_frame(Canexcel_RxFdMsg msg_data, struct can_frame *frame) { + memset(frame, 0, sizeof(*frame)); + if (!!(msg_data.Header.Id & CANXL_TX_HEADER_IDE_MASK)) { frame->flags |= CAN_FRAME_IDE; } - if (!!(msg_data.Header.Id & CANXL_TX_HEADER_RTR_MASK)) { - frame->flags |= CAN_FRAME_RTR; - } - if (!!(frame->flags & CAN_FRAME_IDE)) { frame->id = (msg_data.Header.Id & CANXL_IP_ID_EXT_MASK); } else { @@ -754,7 +752,11 @@ static void nxp_s32_msg_data_to_zcan_frame(Canexcel_RxFdMsg msg_data, frame->flags |= CAN_FRAME_BRS; } - memcpy(frame->data, msg_data.data, can_dlc_to_bytes(frame->dlc)); + if (!!(msg_data.Header.Id & CANXL_TX_HEADER_RTR_MASK)) { + frame->flags |= CAN_FRAME_RTR; + } else { + memcpy(frame->data, msg_data.data, can_dlc_to_bytes(frame->dlc)); + } #ifdef CONFIG_CAN_RX_TIMESTAMP frame->timestamp = msg_data.timeStampL; From bb4a22fdbc83672ff5f0b60e4c3d91350a067de2 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:34:16 +0200 Subject: [PATCH 1976/4498] drivers: can: rcar: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_rcar.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index 85dfbc8916c..1dfaf715414 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -399,10 +399,6 @@ static void can_rcar_rx_isr(const struct device *dev) frame.id = (val & RCAR_CAN_MB_SID_MASK) >> RCAR_CAN_MB_SID_SHIFT; } - if (val & RCAR_CAN_MB_RTR) { - frame.flags |= CAN_FRAME_RTR; - } - frame.dlc = sys_read16(config->reg_addr + RCAR_CAN_MB_60 + RCAR_CAN_MB_DLC_OFFSET) & 0xF; @@ -413,9 +409,13 @@ static void can_rcar_rx_isr(const struct device *dev) frame.dlc = CAN_MAX_DLC; } - for (i = 0; i < frame.dlc; i++) { - frame.data[i] = sys_read8(config->reg_addr + - RCAR_CAN_MB_60 + RCAR_CAN_MB_DATA_OFFSET + i); + if (val & RCAR_CAN_MB_RTR) { + frame.flags |= CAN_FRAME_RTR; + } else { + for (i = 0; i < frame.dlc; i++) { + frame.data[i] = sys_read8(config->reg_addr + + RCAR_CAN_MB_60 + RCAR_CAN_MB_DATA_OFFSET + i); + } } #if defined(CONFIG_CAN_RX_TIMESTAMP) /* read upper byte */ @@ -914,9 +914,11 @@ static int can_rcar_send(const struct device *dev, const struct can_frame *frame sys_write16(frame->dlc, config->reg_addr + RCAR_CAN_MB_56 + RCAR_CAN_MB_DLC_OFFSET); - for (i = 0; i < frame->dlc; i++) { - sys_write8(frame->data[i], config->reg_addr - + RCAR_CAN_MB_56 + RCAR_CAN_MB_DATA_OFFSET + i); + if ((frame->flags & CAN_FRAME_RTR) == 0) { + for (i = 0; i < frame->dlc; i++) { + sys_write8(frame->data[i], config->reg_addr + + RCAR_CAN_MB_56 + RCAR_CAN_MB_DATA_OFFSET + i); + } } compiler_barrier(); From cb207c4a119f91fec21a3d8658320ba7528e4558 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:34:55 +0200 Subject: [PATCH 1977/4498] drivers: can: sja1000: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_sja1000.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index b7a415df59e..9212778ad9d 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -292,8 +292,11 @@ static void can_sja1000_read_frame(const struct device *dev, struct can_frame *f frame->id |= FIELD_PREP(GENMASK(4, 0), can_sja1000_read_reg(dev, CAN_SJA1000_EFF_ID4) >> 3); - for (i = 0; i < frame->dlc; i++) { - frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_EFF_DATA + i); + if ((frame->flags & CAN_FRAME_RTR) == 0U) { + for (i = 0; i < frame->dlc; i++) { + frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_EFF_DATA + + i); + } } } else { frame->id = FIELD_PREP(GENMASK(10, 3), @@ -301,8 +304,11 @@ static void can_sja1000_read_frame(const struct device *dev, struct can_frame *f frame->id |= FIELD_PREP(GENMASK(2, 0), can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID2) >> 5); - for (i = 0; i < frame->dlc; i++) { - frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_SFF_DATA + i); + if ((frame->flags & CAN_FRAME_RTR) == 0U) { + for (i = 0; i < frame->dlc; i++) { + frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_SFF_DATA + + i); + } } } } @@ -334,8 +340,11 @@ void can_sja1000_write_frame(const struct device *dev, const struct can_frame *f can_sja1000_write_reg(dev, CAN_SJA1000_EFF_ID4, FIELD_GET(GENMASK(4, 0), frame->id) << 3); - for (i = 0; i < frame->dlc; i++) { - can_sja1000_write_reg(dev, CAN_SJA1000_EFF_DATA + i, frame->data[i]); + if ((frame->flags & CAN_FRAME_RTR) == 0U) { + for (i = 0; i < frame->dlc; i++) { + can_sja1000_write_reg(dev, CAN_SJA1000_EFF_DATA + i, + frame->data[i]); + } } } else { can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID1, @@ -343,8 +352,11 @@ void can_sja1000_write_frame(const struct device *dev, const struct can_frame *f can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID2, FIELD_GET(GENMASK(2, 0), frame->id) << 5); - for (i = 0; i < frame->dlc; i++) { - can_sja1000_write_reg(dev, CAN_SJA1000_SFF_DATA + i, frame->data[i]); + if ((frame->flags & CAN_FRAME_RTR) == 0U) { + for (i = 0; i < frame->dlc; i++) { + can_sja1000_write_reg(dev, CAN_SJA1000_SFF_DATA + i, + frame->data[i]); + } } } } From e6197fed5fc9001023fb3d90ec41cbee51594c0c Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 11 Oct 2023 13:35:33 +0200 Subject: [PATCH 1978/4498] drivers: can: stm32: bxcan: only copy frame data for non-RTR frames Only copy frame data for non-RTR frames as RTR frames do not carry any data. Fixes: #57002 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_stm32_bxcan.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index 9ded24233d2..d7eab7aea35 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -126,11 +126,12 @@ static void can_stm32_rx_fifo_pop(CAN_FIFOMailBox_TypeDef *mbox, struct can_fram if ((mbox->RIR & CAN_RI0R_RTR) != 0) { frame->flags |= CAN_FRAME_RTR; + } else { + frame->data_32[0] = mbox->RDLR; + frame->data_32[1] = mbox->RDHR; } frame->dlc = mbox->RDTR & (CAN_RDT0R_DLC >> CAN_RDT0R_DLC_Pos); - frame->data_32[0] = mbox->RDLR; - frame->data_32[1] = mbox->RDHR; #ifdef CONFIG_CAN_RX_TIMESTAMP frame->timestamp = ((mbox->RDTR & CAN_RDT0R_TIME) >> CAN_RDT0R_TIME_Pos); #endif @@ -857,14 +858,14 @@ static int can_stm32_send(const struct device *dev, const struct can_frame *fram if ((frame->flags & CAN_FRAME_RTR) != 0) { mailbox->TIR |= CAN_TI1R_RTR; + } else { + mailbox->TDLR = frame->data_32[0]; + mailbox->TDHR = frame->data_32[1]; } mailbox->TDTR = (mailbox->TDTR & ~CAN_TDT1R_DLC) | ((frame->dlc & 0xF) << CAN_TDT1R_DLC_Pos); - mailbox->TDLR = frame->data_32[0]; - mailbox->TDHR = frame->data_32[1]; - mailbox->TIR |= CAN_TI0R_TXRQ; k_mutex_unlock(&data->inst_mutex); From d385d10130f9a50b469f083ff3de36e7a4db0abf Mon Sep 17 00:00:00 2001 From: Alexander Stark Date: Wed, 13 Sep 2023 15:17:57 -0600 Subject: [PATCH 1979/4498] mgmt: mcumgr: update bt smp initialization Oneline fix to smp_bt.c smp transport register. smp_client_transport_register() is a void function and has no return value, so it should be ignored. Signed-off-by: Alexander Stark --- subsys/mgmt/mcumgr/transport/src/smp_bt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/transport/src/smp_bt.c b/subsys/mgmt/mcumgr/transport/src/smp_bt.c index f2aa3eaf542..85377a12e2a 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_bt.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_bt.c @@ -675,7 +675,7 @@ static void smp_bt_setup(void) if (rc == 0) { smp_client_transport.smpt = &smp_bt_transport; smp_client_transport.smpt_type = SMP_BLUETOOTH_TRANSPORT; - rc = smp_client_transport_register(&smp_client_transport); + smp_client_transport_register(&smp_client_transport); } #endif From d912be1c51e0b6bd579fbdb8d09c7819c4e6f3f4 Mon Sep 17 00:00:00 2001 From: Dmytro Semenets Date: Tue, 15 Aug 2023 20:34:34 +0300 Subject: [PATCH 1980/4498] drivers/i2c: remove unnecessary includes i2c_rcar.c includes soc.h header which doesn't need for this source and exists not for all boards. soc.h header doesn't exist for rcar-gen3 soc based on arm64 core. soc.h consists soc-depended defenitions and need to be included by soc-depended sources. Signed-off-by: Dmytro Semenets --- drivers/i2c/i2c_rcar.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/i2c_rcar.c b/drivers/i2c/i2c_rcar.c index 5eeecc6a64e..d6ac6678853 100644 --- a/drivers/i2c/i2c_rcar.c +++ b/drivers/i2c/i2c_rcar.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include From 12ea06cac2b35e52423f4f502acb6003600c74a3 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Thu, 12 Oct 2023 20:59:31 -0400 Subject: [PATCH 1981/4498] posix: fdtable: ensure stdin, stdout, and stderr are initialized Ensure that stdin, stdout, and stderr are initialized statically. Previously, the mutex and condition variable were uninitialized. Signed-off-by: Christopher Friedt --- lib/os/fdtable.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 1d5c340cc19..b261c958de2 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -14,6 +14,8 @@ */ #include +#include + #include #include #include @@ -41,17 +43,23 @@ static struct fd_entry fdtable[CONFIG_POSIX_MAX_FDS] = { { /* STDIN */ .vtable = &stdinout_fd_op_vtable, - .refcount = ATOMIC_INIT(1) + .refcount = ATOMIC_INIT(1), + .lock = Z_MUTEX_INITIALIZER(fdtable[0].lock), + .cond = Z_CONDVAR_INITIALIZER(fdtable[0].cond), }, { /* STDOUT */ .vtable = &stdinout_fd_op_vtable, - .refcount = ATOMIC_INIT(1) + .refcount = ATOMIC_INIT(1), + .lock = Z_MUTEX_INITIALIZER(fdtable[1].lock), + .cond = Z_CONDVAR_INITIALIZER(fdtable[1].cond), }, { /* STDERR */ .vtable = &stdinout_fd_op_vtable, - .refcount = ATOMIC_INIT(1) + .refcount = ATOMIC_INIT(1), + .lock = Z_MUTEX_INITIALIZER(fdtable[2].lock), + .cond = Z_CONDVAR_INITIALIZER(fdtable[2].cond), }, #else { @@ -124,6 +132,30 @@ static int _check_fd(int fd) return 0; } +#ifdef CONFIG_ZTEST +bool fdtable_fd_is_initialized(int fd) +{ + struct k_mutex ref_lock; + struct k_condvar ref_cond; + + if (fd < 0 || fd >= ARRAY_SIZE(fdtable)) { + return false; + } + + ref_lock = (struct k_mutex)Z_MUTEX_INITIALIZER(fdtable[fd].lock); + if (memcmp(&ref_lock, &fdtable[fd].lock, sizeof(ref_lock)) != 0) { + return false; + } + + ref_cond = (struct k_condvar)Z_CONDVAR_INITIALIZER(fdtable[fd].cond); + if (memcmp(&ref_cond, &fdtable[fd].cond, sizeof(ref_cond)) != 0) { + return false; + } + + return true; +} +#endif /* CONFIG_ZTEST */ + void *z_get_fd_obj(int fd, const struct fd_op_vtable *vtable, int err) { struct fd_entry *entry; From 254c6711eda323adcb924b4433e7e8535663b389 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Thu, 12 Oct 2023 21:01:11 -0400 Subject: [PATCH 1982/4498] tests: posix: common: init check for stdin, stdout, and stderr Add a test to help ensure stdin, stdout, and stderr are initialized statically. Signed-off-by: Christopher Friedt --- tests/posix/common/src/_main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/posix/common/src/_main.c b/tests/posix/common/src/_main.c index 264b2e403fd..cfec4adbd44 100644 --- a/tests/posix/common/src/_main.c +++ b/tests/posix/common/src/_main.c @@ -4,8 +4,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include -ZTEST_SUITE(posix_apis, NULL, NULL, NULL, NULL, NULL); +extern bool fdtable_fd_is_initialized(int fd); + +static void *setup(void) +{ + /* ensure that the the stdin, stdout, and stderr fdtable entries are initialized */ + zassert_true(fdtable_fd_is_initialized(0)); + zassert_true(fdtable_fd_is_initialized(1)); + zassert_true(fdtable_fd_is_initialized(2)); + + return NULL; +} + +ZTEST_SUITE(posix_apis, NULL, setup, NULL, NULL, NULL); From f02c612c99baaf2e5be685d5242275017aad5df0 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Fri, 13 Oct 2023 06:14:55 +0200 Subject: [PATCH 1983/4498] mgmt: ec_host_cmd: align buffers Align the rx and tx buffers to prevent unaligned access. Signed-off-by: Dawid Niedzwiecki --- subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c index e322b5b8412..c8f471411e7 100644 --- a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c +++ b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c @@ -33,9 +33,11 @@ BUILD_ASSERT(NUMBER_OF_CHOSEN_BACKENDS < 2, "Number of chosen backends > 1"); #define TX_HEADER_SIZE (sizeof(struct ec_host_cmd_response_header)) COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF, - (static uint8_t hc_rx_buffer[CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE];), ()) + (static uint8_t hc_rx_buffer[CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE] __aligned(4);), + ()) COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_DEF, - (static uint8_t hc_tx_buffer[CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE];), ()) + (static uint8_t hc_tx_buffer[CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE] __aligned(4);), + ()) #ifdef CONFIG_EC_HOST_CMD_DEDICATED_THREAD static K_KERNEL_STACK_DEFINE(hc_stack, CONFIG_EC_HOST_CMD_HANDLER_STACK_SIZE); From b9675b05d38f94b6a041fece1df2877b2c63be58 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 12 Oct 2023 14:05:39 +0200 Subject: [PATCH 1984/4498] drivers: can: mcux: flexcan: override maximum HAL wait loop iterations Add option for overriding the maximum number of wait loop iterations for entering/leaving freeze mode. Set the default to 10000 (as opposed to a default of 1000 used in the HAL). Fixes: #56171 Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.mcux | 7 +++++++ modules/hal_nxp/CMakeLists.txt | 3 +++ 2 files changed, 10 insertions(+) diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index 6ccaad15e45..67ab4c26873 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -21,6 +21,13 @@ config CAN_MCUX_FLEXCAN_FD help Enable support for CAN-FD capable NXP FlexCAN devices. +config CAN_MCUX_FLEXCAN_WAIT_TIMEOUT + int "Maximum number of wait loop iterations" + default 10000 + help + Maximum number of wait loop iterations for the MCUX FlexCAN HAL when entering/leaving + freeze mode. + config CAN_MAX_MB int "Maximum number of message buffers for concurrent active instances" default 16 diff --git a/modules/hal_nxp/CMakeLists.txt b/modules/hal_nxp/CMakeLists.txt index 17f5cfdd078..01e6d58ccae 100644 --- a/modules/hal_nxp/CMakeLists.txt +++ b/modules/hal_nxp/CMakeLists.txt @@ -12,4 +12,7 @@ if(CONFIG_HAS_MCUX OR CONFIG_HAS_IMX_HAL OR CONFIG_HAS_NXP_S32_HAL) zephyr_include_directories_ifdef(CONFIG_PWM_MCUX_CTIMER ${ZEPHYR_CURRENT_MODULE_DIR}/mcux/mcux-sdk/drivers/ctimer/) zephyr_include_directories(.) + + zephyr_compile_definitions_ifdef(CONFIG_CAN_MCUX_FLEXCAN + FLEXCAN_WAIT_TIMEOUT=${CONFIG_CAN_MCUX_FLEXCAN_WAIT_TIMEOUT}) endif() From 179d435a3090317767dafd811b573b16efe2733a Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Fri, 13 Oct 2023 10:09:12 +0200 Subject: [PATCH 1985/4498] Revert "drivers: serial: stm32: Make it compatible with runtime PM .... This reverts commit 1c2d326579ee8cea4c809eb737585537e3482677. which was limited to CONFIG_UART_ASYNC_API=y case and causing regression otherwise. Fixes #63885 Signed-off-by: Erwan Gouriou --- drivers/serial/uart_stm32.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 8cf10e6a151..9243b10d7e7 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -23,7 +23,6 @@ #include #include #include -#include #ifdef CONFIG_UART_ASYNC_API #include @@ -672,11 +671,6 @@ static void uart_stm32_poll_out_visitor(const struct device *dev, void *out, pol */ uart_stm32_pm_policy_state_lock_get(dev); - /* Resume device if needed before enabling IT */ - if (pm_device_runtime_is_enabled(dev)) { - (void)pm_device_runtime_get(dev); - } - /* Enable TC interrupt so we can release suspend * constraint when done */ @@ -1269,11 +1263,6 @@ static void uart_stm32_isr(const struct device *dev) async_evt_tx_done(data); #ifdef CONFIG_PM - /* Device can now be released */ - if (pm_device_runtime_is_enabled(dev)) { - (void)pm_device_runtime_put(dev); - } - uart_stm32_pm_policy_state_lock_put(dev); #endif } else if (LL_USART_IsEnabledIT_RXNE(config->usart) && From 7d5d4ed907fad929fe71489adeaaf666390ac72d Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 12 Oct 2023 15:44:17 -0500 Subject: [PATCH 1986/4498] drivers: eth_mcux: cache must be dcache Currently the Kconfig for eth_mcux selects nocache if HAS_MCUX_CACHE is set. But, for platforms that have a flexspi cache but not a CPU cache, this is invalid, so clarify this in the Kconfig definition. Signed-off-by: Declan Snyder --- drivers/ethernet/Kconfig.mcux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/Kconfig.mcux b/drivers/ethernet/Kconfig.mcux index 1ecf0db8dc9..8996d7239ff 100644 --- a/drivers/ethernet/Kconfig.mcux +++ b/drivers/ethernet/Kconfig.mcux @@ -7,7 +7,7 @@ menuconfig ETH_MCUX bool "MCUX Ethernet driver" default y depends on DT_HAS_NXP_KINETIS_ETHERNET_ENABLED - select NOCACHE_MEMORY if HAS_MCUX_CACHE + select NOCACHE_MEMORY if HAS_MCUX_CACHE && CPU_HAS_DCACHE select ARM_MPU if CPU_CORTEX_M7 select NET_POWER_MANAGEMENT if PM_DEVICE help From ac67f245e7f00decccddc5ba454b509f08c2b2c1 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 10 Oct 2023 22:39:47 -0300 Subject: [PATCH 1987/4498] west.yml: update esp32s3 to enable all flash ranges Current hal only enable up to 16MB flash size in esp32s3 SoC. This updates hal_espressif to include 32MB, 64MB and 128MB. Signed-off-by: Sylvio Alves --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 5e3d157a0ba..8866ec48a78 100644 --- a/west.yml +++ b/west.yml @@ -155,7 +155,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 635063971ee16d1fcdfd35136feda99a90926327 + revision: 31fc5758f3507f8f0af00b1dea1a0df7af99bfc0 path: modules/hal/espressif west-commands: west/west-commands.yml groups: From 4b5331ba45b037f0e5a791da96b533d5c7253fc7 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 26 Sep 2023 07:53:18 -0300 Subject: [PATCH 1988/4498] linker: esp32: move snippets-section within rom boundary This will guarantee that application snippets will be placed into ROM section properly. Signed-off-by: Sylvio Alves --- soc/riscv/espressif_esp32/esp32c3/default.ld | 3 +-- soc/xtensa/espressif_esp32/esp32/default.ld | 3 +-- soc/xtensa/espressif_esp32/esp32_net/linker.ld | 3 +-- soc/xtensa/espressif_esp32/esp32s2/default.ld | 3 +-- soc/xtensa/espressif_esp32/esp32s3/default.ld | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/soc/riscv/espressif_esp32/esp32c3/default.ld b/soc/riscv/espressif_esp32/esp32c3/default.ld index 9fb9f0c1ab0..0965036fb42 100644 --- a/soc/riscv/espressif_esp32/esp32c3/default.ld +++ b/soc/riscv/espressif_esp32/esp32c3/default.ld @@ -197,6 +197,7 @@ SECTIONS #include #include #include + #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ @@ -311,8 +312,6 @@ SECTIONS . = ALIGN(4); } GROUP_LINK_IN(RAMABLE_REGION) - #include - .dram0.data : { . = ALIGN(4); diff --git a/soc/xtensa/espressif_esp32/esp32/default.ld b/soc/xtensa/espressif_esp32/esp32/default.ld index ddc95c4527f..20dc3c28ef5 100644 --- a/soc/xtensa/espressif_esp32/esp32/default.ld +++ b/soc/xtensa/espressif_esp32/esp32/default.ld @@ -221,6 +221,7 @@ SECTIONS #include #include #include + #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ @@ -234,8 +235,6 @@ SECTIONS _image_dram_size = LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - _image_dram_start; _image_dram_vaddr = ADDR(.dram0.data); - #include - .dram0.data : { __data_start = ABSOLUTE(.); diff --git a/soc/xtensa/espressif_esp32/esp32_net/linker.ld b/soc/xtensa/espressif_esp32/esp32_net/linker.ld index 2b815957e84..69a4c48ef78 100644 --- a/soc/xtensa/espressif_esp32/esp32_net/linker.ld +++ b/soc/xtensa/espressif_esp32/esp32_net/linker.ld @@ -212,6 +212,7 @@ SECTIONS #include #include #include + #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ @@ -225,8 +226,6 @@ SECTIONS _image_dram_size = LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - _image_dram_start; _image_dram_vaddr = ADDR(.dram0.data); - #include - .dram0.data : { __data_start = ABSOLUTE(.); diff --git a/soc/xtensa/espressif_esp32/esp32s2/default.ld b/soc/xtensa/espressif_esp32/esp32s2/default.ld index 35e2889db56..4ef27a6384c 100644 --- a/soc/xtensa/espressif_esp32/esp32s2/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s2/default.ld @@ -192,6 +192,7 @@ SECTIONS #include #include #include + #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ @@ -363,8 +364,6 @@ SECTIONS . = ALIGN(8); } GROUP_LINK_IN(RAMABLE_REGION) -#include - .dram0.data : { . = ALIGN (8); diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index c9bab6f3cad..36944d69c60 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -229,6 +229,7 @@ SECTIONS #include #include #include + #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ @@ -426,8 +427,6 @@ SECTIONS . = ALIGN(8) ; } GROUP_LINK_IN(RAMABLE_REGION) -#include - .dram0.data : { . = ALIGN (8); From 69d50db53aab595b17526013a06ad5d9f575346c Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Fri, 13 Oct 2023 09:50:17 +0200 Subject: [PATCH 1989/4498] shell: fix a memory corruption coverity issue Added a condition to check if the size of the copied memory is a positive number. Fixes #58700 Fixes #58703 Signed-off-by: Jakub Rzeszutko --- subsys/shell/shell_log_backend.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/shell/shell_log_backend.c b/subsys/shell/shell_log_backend.c index 2a90478ee97..38ee97c3ff9 100644 --- a/subsys/shell/shell_log_backend.c +++ b/subsys/shell/shell_log_backend.c @@ -143,6 +143,9 @@ static bool copy_to_pbuffer(struct mpsc_pbuf_buffer *mpsc_buffer, uint8_t *src_data = (uint8_t *)msg + sizeof(struct mpsc_pbuf_hdr); size_t hdr_wlen = DIV_ROUND_UP(sizeof(struct mpsc_pbuf_hdr), sizeof(uint32_t)); + if (wlen <= hdr_wlen) { + return false; + } dst->hdr.data = msg->buf.hdr.data; memcpy(dst_data, src_data, (wlen - hdr_wlen) * sizeof(uint32_t)); From bdd8edd67b075c2856ac2d85228f6750b5f57007 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 25 Aug 2023 17:00:02 +0300 Subject: [PATCH 1990/4498] dts: x86: Remove old atom.dtsi Remove old unused atom.dtsi and intel,atom.yaml binding. Signed-off-by: Andrei Emeltchenko --- dts/bindings/cpu/intel,atom.yaml | 8 --- dts/x86/intel/atom.dtsi | 91 -------------------------------- 2 files changed, 99 deletions(-) delete mode 100644 dts/bindings/cpu/intel,atom.yaml delete mode 100644 dts/x86/intel/atom.dtsi diff --git a/dts/bindings/cpu/intel,atom.yaml b/dts/bindings/cpu/intel,atom.yaml deleted file mode 100644 index d6c4dd771cd..00000000000 --- a/dts/bindings/cpu/intel,atom.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021 Intel Corp. -# SPDX-License-Identifier: Apache-2.0 - -description: Intel Atom CPU - -compatible: "intel,atom" - -include: cpu.yaml diff --git a/dts/x86/intel/atom.dtsi b/dts/x86/intel/atom.dtsi deleted file mode 100644 index f1aee1502df..00000000000 --- a/dts/x86/intel/atom.dtsi +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "skeleton.dtsi" -#include - -/ { - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "intel,atom"; - d-cache-line-size = <64>; - reg = <0>; - }; - }; - - dram0: memory@0 { - device_type = "memory"; - reg = <0x0 DT_DRAM_SIZE>; - }; - - intc: ioapic@fec00000 { - compatible = "intel,ioapic"; - reg = <0xfec00000 0x1000>; - interrupt-controller; - #interrupt-cells = <3>; - }; - - intc_loapic: loapic@fee00000 { - compatible = "intel,loapic"; - reg = <0xfee00000 0x1000>; - interrupt-controller; - #interrupt-cells = <3>; - }; - - soc { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - - uart0: uart@3f8 { - compatible = "ns16550"; - reg = <0x000003f8 0x100>; - io-mapped; - clock-frequency = <1843200>; - interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; - interrupt-parent = <&intc>; - reg-shift = <0>; - status = "disabled"; - }; - - uart1: uart@2f8 { - compatible = "ns16550"; - reg = <0x000002f8 0x100>; - io-mapped; - clock-frequency = <1843200>; - interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; - interrupt-parent = <&intc>; - reg-shift = <0>; - status = "disabled"; - }; - - hpet: hpet@fed00000 { - compatible = "intel,hpet"; - reg = <0xfed00000 0x400>; - interrupts = <2 IRQ_TYPE_FIXED_EDGE_RISING 4>; - interrupt-parent = <&intc>; - - status = "disabled"; - }; - - rtc: counter: rtc@70 { - compatible = "motorola,mc146818"; - reg = <0x70 0x0D 0x71 0x0D>; - interrupts = <8 IRQ_TYPE_LOWEST_EDGE_RISING 3>; - interrupt-parent = <&intc>; - alarms-count = <1>; - - status = "okay"; - }; - - }; -}; From f6fe61e5982139e344227ea4cf03891b09e4a068 Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Tue, 3 Oct 2023 19:12:53 +0100 Subject: [PATCH 1991/4498] arch: arm: cortex_m: Fix constraint on inline assembly for armv8-m.baseline `mov` on armv8-m.baseline, when used with an immediate value is limited to registers `r0` to `r7`. `=r` tells the compiler any register can be used. `=l` needs to be used instead. Signed-off-by: Wilfried Chauveau --- include/zephyr/arch/arm/asm_inline_gcc.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/zephyr/arch/arm/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h index ee7a31debb5..63a118e97e6 100644 --- a/include/zephyr/arch/arm/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -61,7 +61,15 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) "mrs %0, BASEPRI;" "msr BASEPRI_MAX, %1;" "isb;" - : "=r"(key), "=r"(tmp) + : "=r"(key), +#if defined(CONFIG_ARMV8_M_BASELINE) + /* armv8-m.baseline's mov is limited to registers r0-r7. + * Let the compiler know we have this constraint on tmp. + */ + "=l"(tmp) +#else + "=r"(tmp) +#endif : "i"(_EXC_IRQ_DEFAULT_PRIO) : "memory"); #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ From d661c86e350995a0c878d565a67f9c54c9c063b1 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 13 Oct 2023 11:43:53 +0300 Subject: [PATCH 1992/4498] drivers: modem_cellular: Fix missing break There is no fallthrough statement or comment so I assume break is missing. Fixes build time warning from some tools. Signed-off-by: Andrei Emeltchenko --- drivers/modem/modem_cellular.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index f1536ee37d5..e47b04d0761 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -647,6 +647,7 @@ static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data case MODEM_CELLULAR_EVENT_TIMEOUT: modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data); modem_pipe_open_async(data->uart_pipe); + break; case MODEM_CELLULAR_EVENT_BUS_OPENED: modem_cmux_attach(&data->cmux, data->uart_pipe); From 7e8953ed7f2d3b17a9a2bb8420ed5331d8d97638 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 13 Oct 2023 08:18:02 -0400 Subject: [PATCH 1993/4498] posix: ensure that pooled ipc type is user-configurable Previously it was not possible to n-select e.g. CONFIG_PTHREAD_BARRIER because the Kconfig template for it lacked a prompt. This made it impossible to disable some unused POSIX features and unnecessarily increased code size if unused code sections were not discarded by the linker. Add a prompt so that each pooled IPC type is user-configurable and can be disabled if unneeded. Further, ensure that only the selected sources from lib/posix are included in the cmake build. Signed-off-by: Christopher Friedt --- lib/posix/CMakeLists.txt | 12 ++++++------ lib/posix/Kconfig.template.pooled_ipc_type | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index 48bb598ef2d..c6b3a88aeab 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -48,15 +48,15 @@ zephyr_library_sources_ifdef(CONFIG_POSIX_MQUEUE mqueue.c) zephyr_library_sources_ifdef(CONFIG_POSIX_SIGNAL signal.c ${STRSIGNAL_TABLE_H}) zephyr_library_sources_ifdef(CONFIG_POSIX_UNAME uname.c) zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC _common.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC barrier.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC cond.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC key.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC mutex.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC pthread.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD_BARRIER barrier.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD_COND cond.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD_KEY key.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD_MUTEX mutex.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD pthread.c) zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC rwlock.c) zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC sched.c) zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC semaphore.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC spinlock.c) +zephyr_library_sources_ifdef(CONFIG_PTHREAD_SPINLOCK spinlock.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/lib/posix/Kconfig.template.pooled_ipc_type b/lib/posix/Kconfig.template.pooled_ipc_type index 557a98f8849..d28ed345b6a 100644 --- a/lib/posix/Kconfig.template.pooled_ipc_type +++ b/lib/posix/Kconfig.template.pooled_ipc_type @@ -7,9 +7,9 @@ source "lib/posix/Kconfig.template.with_logging" # Not user configurable (i.e. private for now) config $(TYPE) - bool - default y + bool "POSIX $(type) support" depends on PTHREAD_IPC + default y help Support for $(TYPE) For more info, see From c678f25bc1ac5d5aad8f18779e2a578246febb8c Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 4 Oct 2023 11:33:16 -0500 Subject: [PATCH 1994/4498] llext: Fix a bug in section linking When relocating section symbol addresses the value where the relocation is to be written is an offset into the section to load. Simply rewriting it with the section address is not enough, we need to write the address of the section with the offset into it. Signed-off-by: Tom Burdick --- samples/subsys/llext/shell_loader/README.rst | 117 ++++++++++++------- subsys/llext/llext.c | 9 +- tests/subsys/llext/hello_world/hello_world.c | 9 +- 3 files changed, 83 insertions(+), 52 deletions(-) diff --git a/samples/subsys/llext/shell_loader/README.rst b/samples/subsys/llext/shell_loader/README.rst index 7d0d70151c3..583299028be 100644 --- a/samples/subsys/llext/shell_loader/README.rst +++ b/samples/subsys/llext/shell_loader/README.rst @@ -61,60 +61,89 @@ On a host machine with the zephyr sdk setup and the arm toolchain in PATH .. code-block:: console $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o hello_world.elf tests/subsys/llext/hello_world/hello_world.c - $ arm-zephyr-eabi-objdump -x -t hello_world.elf - - hello_world.elf: file format elf32-littlearm - hello_world.elf - architecture: armv4t, flags 0x00000011: - HAS_RELOC, HAS_SYMS - start address 0x00000000 - private flags = 0x5000000: [Version5 EABI] - - Sections: - Idx Name Size VMA LMA File off Algn - 0 .text 00000024 00000000 00000000 00000034 2**2 - CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE - 1 .data 00000000 00000000 00000000 00000058 2**0 - CONTENTS, ALLOC, LOAD, DATA - 2 .bss 00000000 00000000 00000000 00000058 2**0 - ALLOC - 3 .rodata 0000000d 00000000 00000000 00000058 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 4 .comment 00000021 00000000 00000000 00000065 2**0 - CONTENTS, READONLY - 5 .ARM.attributes 0000002a 00000000 00000000 00000086 2**0 - CONTENTS, READONLY - arm-zephyr-eabi-objdump: hello_world.elf: not a dynamic object - SYMBOL TABLE: - 00000000 l df *ABS* 00000000 hello_world.c - 00000000 l d .text 00000000 .text - 00000000 l d .data 00000000 .data - 00000000 l d .bss 00000000 .bss - 00000000 l d .rodata 00000000 .rodata - 00000000 l d .comment 00000000 .comment - 00000000 l d .ARM.attributes 00000000 .ARM.attributes - 00000000 g F .text 00000020 hello_world - 00000000 *UND* 00000000 printk - - - RELOCATION RECORDS FOR [.text]: - OFFSET TYPE VALUE - 00000018 R_ARM_ABS32 .rodata - 0000001c R_ARM_ABS32 printk + $ arm-zephyr-eabi-objdump -r -d -x hello_world.elf + + hello_world.elf: file format elf32-littlearm + hello_world.elf + architecture: armv4t, flags 0x00000011: + HAS_RELOC, HAS_SYMS + start address 0x00000000 + private flags = 0x5000000: [Version5 EABI] + + Sections: + Idx Name Size VMA LMA File off Algn + 0 .text 00000038 00000000 00000000 00000034 2**2 + CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE + 1 .data 00000000 00000000 00000000 0000006c 2**0 + CONTENTS, ALLOC, LOAD, DATA + 2 .bss 00000000 00000000 00000000 0000006c 2**0 + ALLOC + 3 .rodata 00000025 00000000 00000000 0000006c 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 4 .comment 00000021 00000000 00000000 00000091 2**0 + CONTENTS, READONLY + 5 .ARM.attributes 0000002a 00000000 00000000 000000b2 2**0 + CONTENTS, READONLY + SYMBOL TABLE: + 00000000 l df *ABS* 00000000 hello_world.c + 00000000 l d .text 00000000 .text + 00000000 l d .data 00000000 .data + 00000000 l d .bss 00000000 .bss + 00000000 l d .rodata 00000000 .rodata + 00000000 l O .rodata 00000004 number + 00000000 l d .comment 00000000 .comment + 00000000 l d .ARM.attributes 00000000 .ARM.attributes + 00000000 g F .text 00000034 hello_world + 00000000 *UND* 00000000 printk + + + + Disassembly of section .text: + + 00000000 : + 0: b580 push {r7, lr} + 2: af00 add r7, sp, #0 + 4: 4b08 ldr r3, [pc, #32] ; (28 ) + 6: 0018 movs r0, r3 + 8: 4b08 ldr r3, [pc, #32] ; (2c ) + a: f000 f813 bl 34 + e: 222a movs r2, #42 ; 0x2a + 10: 4b07 ldr r3, [pc, #28] ; (30 ) + 12: 0011 movs r1, r2 + 14: 0018 movs r0, r3 + 16: 4b05 ldr r3, [pc, #20] ; (2c ) + 18: f000 f80c bl 34 + 1c: 46c0 nop ; (mov r8, r8) + 1e: 46bd mov sp, r7 + 20: bc80 pop {r7} + 22: bc01 pop {r0} + 24: 4700 bx r0 + 26: 46c0 nop ; (mov r8, r8) + 28: 00000004 .word 0x00000004 + 28: R_ARM_ABS32 .rodata + 2c: 00000000 .word 0x00000000 + 2c: R_ARM_ABS32 printk + 30: 00000014 .word 0x00000014 + 30: R_ARM_ABS32 .rodata + 34: 4718 bx r3 + 36: 46c0 nop ; (mov r8, r8) $ xxd -p hello_world.elf | tr -d '\n' - The resulting hex string can be used to load the extension. .. code-block:: console - uart:~$ llext load_hex hello_world 7f454c4601010100000000000000000001002800010000000000000000000000180200000000000534000000000028000b000a0080b500af044b1800044b00f009f8c046bd4680bc01bc004700000000000000001847c04668656c6c6f20776f726c640a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff00000000000000000000000003000100000000000000000000000000030003000000000000000000000000000300040000000000000000000000000003000500090000000000000000000000000005000c000000000000000000000000000100090000001800000000000000000001000c00000020000000000000000000010000000000000000000000000003000600000000000000000000000000030007000f0000000100000020000000120001001b0000000000000000000000100000000068656c6c6f2e630024640024740068656c6c6f5f776f726c64007072696e746b00000018000000020500001c000000020d0000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000024000000000000000000000004000000000000001b000000090000004000000000000000b40100001000000008000000010000000400000008000000250000000100000003000000000000005800000000000000000000000000000001000000000000002b00000008000000030000000000000058000000000000000000000000000000010000000000000030000000010000000200000000000000580000000d000000000000000000000004000000000000003800000001000000300000000000000065000000210000000000000000000000010000000100000041000000030000700000000000000000860000002a0000000000000000000000010000000000000001000000020000000000000000000000b0000000e0000000090000000c00000004000000100000000900000003000000000000000000000090010000220000000000000000000000010000000000000011000000030000000000000000000000c40100005100000000000000000000000100000000000000 + uart:~$ llext load_hex hello_world 7f454c4601010100000000000000000001002800010000000000000000000000680200000000000534000000000028000b000a0080b500af084b1800084b00f013f82a22074b11001800054b00f00cf8c046bd4680bc01bc0047c0460400000000000000140000001847c0462a00000068656c6c6f20776f726c640a0000000041206e756d62657220697320256c750a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff000000000000000000000000030001000000000000000000000000000300030000000000000000000000000003000400000000000000000000000000030005000f00000000000000000000000000050012000000000000000400000001000500190000000000000000000000000001000f0000002800000000000000000001001900000034000000000000000000010000000000000000000000000003000600000000000000000000000000030007001c000000010000003400000012000100280000000000000000000000100000000068656c6c6f5f776f726c642e63002464006e756d6265720024740068656c6c6f5f776f726c64007072696e746b000028000000020500002c000000020e00003000000002050000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000038000000000000000000000004000000000000001b000000090000004000000000000000fc0100001800000008000000010000000400000008000000250000000100000003000000000000006c00000000000000000000000000000001000000000000002b0000000800000003000000000000006c0000000000000000000000000000000100000000000000300000000100000002000000000000006c00000025000000000000000000000004000000000000003800000001000000300000000000000091000000210000000000000000000000010000000100000041000000030000700000000000000000b20000002a0000000000000000000000010000000000000001000000020000000000000000000000dc000000f0000000090000000d000000040000001000000009000000030000000000000000000000cc0100002f0000000000000000000000010000000000000011000000030000000000000000000000140200005100000000000000000000000100000000000000 -This extension can then be seen in the list of loaded extensions (`list`), its symbols printed (`list_symbols`), and the hello_world -function which the extension exports can be called and run (`call_fn`). +This extension can then be seen in the list of loaded extensions (`list`), its symbols printed +(`list_symbols`), and the hello_world function which the extension exports can be called and +run (`call_fn`). .. code-block:: console uart:~$ llext call_fn hello_world hello_world hello world + A number is 42 + +In this sample there are 3 absolute (R_ARM_ABS32) relocations, 2 of which are meant to hold addresses into the .rodata sections where the strings are located. A third is an address of where the printk function (symbol) can be found. At load time llext replaces the values in the .text section with real memory addresses so that printk works as expected with the strings included in the hello world sample. diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 1a4739564a3..5c195dc704c 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -508,6 +508,8 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) uintptr_t link_addr, op_loc, op_code; + op_loc = loc + rel.r_offset; + /* If symbol is undefined, then we need to look it up */ if (sym.st_shndx == SHN_UNDEF) { link_addr = (uintptr_t)llext_find_sym(NULL, name); @@ -525,7 +527,10 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) name, link_addr, op_code); } } else if (ELF_ST_TYPE(sym.st_info) == STT_SECTION) { - link_addr = (uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]]; + /* Current relocation location holds an offset into the section */ + link_addr = (uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]] + + sym.st_value + + *((uintptr_t *)op_loc); LOG_INF("found section symbol %s addr 0x%lx", name, link_addr); } else { @@ -533,8 +538,6 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) continue; } - op_loc = loc + rel.r_offset; - LOG_INF("relocating (linking) symbol %s type %d binding %d ndx %d offset " "%d link section %d", name, ELF_ST_TYPE(sym.st_info), ELF_ST_BIND(sym.st_info), diff --git a/tests/subsys/llext/hello_world/hello_world.c b/tests/subsys/llext/hello_world/hello_world.c index 4f5c5eed526..93d55ed5422 100644 --- a/tests/subsys/llext/hello_world/hello_world.c +++ b/tests/subsys/llext/hello_world/hello_world.c @@ -11,15 +11,14 @@ * a function. */ -/* Various build options should be documented here to generate the test elf for - * each architecture. - * - * armv7-thumb: -mlong-call -mthumb -c -o hello_world_armv7_thumb.elf hello_world.c - */ +#include extern void printk(char *fmt, ...); +static const uint32_t number = 42; + extern void hello_world(void) { printk("hello world\n"); + printk("A number is %lu\n", number); } From 5e10b34a565115167d467cb1a21e5b43508a952b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 12 Oct 2023 16:14:04 -0700 Subject: [PATCH 1995/4498] doc: release: 3.5: Add info about CVE-2023-5563 Add CVE-2023-5563 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 83dcfc60c03..1f19d21622c 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -46,6 +46,8 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-5184 `Zephyr project bug tracker GHSA-8x3p-q3r5-xh9g `_ +* CVE-2023-5563 `Zephyr project bug tracker GHSA-98mc-rj7w-7rpv + `_ Kernel ****** From 49d4ad9315e0581cb8968d661966b747cff82d3f Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 12 Oct 2023 16:18:54 -0700 Subject: [PATCH 1996/4498] doc: vuln: Add information about CVE-2023-5563 Information about CVE-2023-5563 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 73f550a7d0c..d2281c32bbc 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1495,3 +1495,24 @@ This has been fixed in main for v3.5.0 - `PR 63069 fix for main `_ + +CVE-2023-5563 +------------- + +The SJA1000 CAN controller driver backend automatically attempts to recover +from a bus-off event when built with CONFIG_CAN_AUTO_BUS_OFF_RECOVERY=y. This +results in calling k_sleep() in IRQ context, causing a fatal exception. + +- `Zephyr project bug tracker GHSA-98mc-rj7w-7rpv + `_ + +This has been fixed in main for v3.5.0 + +- `PR 63713 fix for main + `_ + +- `PR 63718 fix for 3.4 + `_ + +- `PR 63717 fix for 3.3 + `_ From 12c0204b6066962f983fd000bdfdf0eda5b93531 Mon Sep 17 00:00:00 2001 From: Martin Calsyn Date: Sat, 7 Oct 2023 13:44:34 +0200 Subject: [PATCH 1997/4498] drivers: fuel_gauge: max17048: Fix overflow when calculating voltage Annotate the calculation with type casts to force promotion to uint32_t and then cast back down to uint16_t for the return. This solves the issue with invalid voltage (mV) values being returned due to overflow during the conversion from the register value on the max17048 chip. Signed-off-by: Martin Calsyn --- drivers/fuel_gauge/max17048/max17048.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/fuel_gauge/max17048/max17048.c b/drivers/fuel_gauge/max17048/max17048.c index 4a39f108495..a54fb331ae5 100644 --- a/drivers/fuel_gauge/max17048/max17048.c +++ b/drivers/fuel_gauge/max17048/max17048.c @@ -90,7 +90,7 @@ int max17048_voltage(const struct device *i2c_dev, uint16_t *response) * milli volts instead of volts. */ - *response = *response * 78125 / 1000000; + *response = (uint16_t)((uint32_t)*response * 78125L / 1000000L); return 0; } From a0db5288370a7ebe3d032a6e68526e7741cc56d4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 12 Oct 2023 23:28:10 -0700 Subject: [PATCH 1998/4498] maintainers: random: Add Flavio Ceolin as maintainer Mark this subsystem as maintained and add myself as maintainer. Signed-off-by: Flavio Ceolin --- MAINTAINERS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1e5c936bc1c..13bdf72abd0 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3681,8 +3681,8 @@ Emulation: - "area: HW Emulation" Random: - status: odd fixes - collaborators: + status: maintained + maintainers: - ceolin files: - subsys/random/ From ded2c49e8a4052cabaa91a3bcbca1af02f08df1a Mon Sep 17 00:00:00 2001 From: Artur Lipowski Date: Fri, 13 Oct 2023 14:23:30 +0200 Subject: [PATCH 1999/4498] fs: nvs: Note about nvs_write with len equal to 0. Add a note to explain what happens when entry with 0 data length is written to NVS storage. Signed-off-by: Artur Lipowski --- include/zephyr/fs/nvs.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/fs/nvs.h b/include/zephyr/fs/nvs.h index 30315d77b20..1d0a4e3b1d3 100644 --- a/include/zephyr/fs/nvs.h +++ b/include/zephyr/fs/nvs.h @@ -94,6 +94,11 @@ int nvs_clear(struct nvs_fs *fs); /** * @brief Write an entry to the file system. * + * @note When @p len parameter is equal to @p 0 then entry is effectively removed (it is + * equivalent to calling of nvs_delete). Any calls to nvs_read for entries with data of length + * @p 0 will return error.@n It is not possible to distinguish between deleted entry and entry + * with data of length 0. + * * @param fs Pointer to file system * @param id Id of the entry to be written * @param data Pointer to the data to be written From 5e38471e714f41cd7b25b5e22e6b01998329fcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 13 Oct 2023 17:03:01 +0200 Subject: [PATCH 2000/4498] modules: hal_nordic: cmake: Fix checking if uicr DT node is accessible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to cmake documentation, in the `if()` expression the string evaluates to false unless its value is one of the true constants. Thus, the commands under `if(${uicr_path})` are never executed. Use `if(DEFINED uicr_path)` instead, since `uicr_path` is returned by `dt_nodelabel()` and it will be undefined if such node does not exist. Signed-off-by: Andrzej Głąbek --- modules/hal_nordic/nrfx/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 3edab6336c3..4d637ba43f1 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -118,7 +118,7 @@ endif() # doing the proper configuration sequence during system init dt_nodelabel(uicr_path NODELABEL "uicr") -if(${uicr_path}) +if(DEFINED uicr_path) dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") if(${nfct_pins_as_gpios}) zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) From 390b6520b892ca8bed0a5c13352664aa05f57270 Mon Sep 17 00:00:00 2001 From: Ladislav Podivin Date: Fri, 13 Oct 2023 16:29:16 +0200 Subject: [PATCH 2001/4498] Logging: improve help message of LOG_PRINTK Kconfig option Improve it so that: - it mentions the important fact that it redirects `printk` messages to the logging subsystem - it is consistent with the help messages of the other options in this file (i.e. it starts with "If enabled") Signed-off-by: Ladislav Podivin --- subsys/logging/Kconfig.processing | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/logging/Kconfig.processing b/subsys/logging/Kconfig.processing index 107dc5033ff..a1d7c955d40 100644 --- a/subsys/logging/Kconfig.processing +++ b/subsys/logging/Kconfig.processing @@ -9,7 +9,8 @@ config LOG_PRINTK bool "Process printk messages" default y if PRINTK && (!ZTEST || ZTEST_NEW_API) help - LOG_PRINTK messages are formatted in place and logged unconditionally. + If enabled, printk messages are redirected to the logging subsystem. + The messages are formatted in place and logged unconditionally. if LOG_MODE_DEFERRED && !LOG_FRONTEND_ONLY From e9a8497b0d91540573cd95b75735502020e1785c Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Fri, 13 Oct 2023 14:24:25 -0500 Subject: [PATCH 2002/4498] doc: release: Add sensor release notes for v3.5.0 Added comments about new drivers, bug fixes, and enhancements made to sensor drivers since the last release. Signed-off-by: Maureen Helm --- doc/releases/release-notes-3.5.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 1f19d21622c..f3f54e5a76b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -487,6 +487,24 @@ Drivers and Sensors * Reworked the :dtcompatible:`ti,bq274xx` to add ``BQ27427`` support, fixed units for capacity and power channels. + * Added ADC current sense amplifier and voltage sensor drivers. + * Added ADI LTC2990 voltage, current, and temperature sensor driver. + * Added AMS TSL2540 ambient light sensor driver. + * Added Bosch BMI08x accelerometer/gyroscope driver. + * Added DFRobot A01NYUB distance sensor driver. + * Added Fintek F75303 temperature sensor driver. + * Added Isentek IST8310 magnetometer driver. + * Added Microchip TCN75A temperature sensor driver. + * Added NXP TEMPMON driver. + * Added Seeed HM330X dust sensor driver. + * Added TI TMAG5170 3D Hall sensor driver. + * Added power management support to BMM150, LM75, and Microchip tachometer + drivers. + * Added trigger support to the BMM150 magnetometer driver. + * Added tap trigger support to the LIS2DH accelerometer driver. + * Updated ST sensor drivers to use STMEMSC HAL i/f v2.3 + * Updated the decoder APIs to vertically decode raw sensor data. + * Various fixes and enhancements in the NTC thermistor and INA23x drivers. * Serial From 433a85e7bf32ffc77ba194bb903bcca84c44c047 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Thu, 12 Oct 2023 16:21:26 +0100 Subject: [PATCH 2003/4498] test: posix: skip nanosleep testcase for ARC HSDK boards The comparison of cycles we get with k_cycle_get_32 may be incorrect if counter wrap happened. In case of ARC HSDK and ARC HSDK4xD platforms we have high counter clock frequency (500MHz or 1GHz) so counter wrap quite likely to happen if we wait long enough. As in some test cases we wait more than 1 second, there are significant chances to get false-positive assertion. So let's skip nanosleep testcase for ARC HSDK and ARC HSDK4xD boards. The proper fix is to use k_cycle_get_64 in this test case, but we need to provide k_cycle_get_64 support for ARC HSDK and ARC HSDK4xD platforms first. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- tests/posix/common/src/nanosleep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/posix/common/src/nanosleep.c b/tests/posix/common/src/nanosleep.c index d2d92a5ce6b..7820f823eb0 100644 --- a/tests/posix/common/src/nanosleep.c +++ b/tests/posix/common/src/nanosleep.c @@ -186,8 +186,16 @@ static void common_lower_bound_check(int selection, clockid_t clock_id, int flag /* round up to the nearest microsecond for k_busy_wait() */ exp_ns = DIV_ROUND_UP(exp_ns, NSEC_PER_USEC) * NSEC_PER_USEC; + /* The comparison may be incorrect if counter wrap happened. In case of ARC HSDK platforms + * we have high counter clock frequency (500MHz or 1GHz) so counter wrap quite likely to + * happen if we wait long enough. As in some test cases we wait more than 1 second, there + * are significant chances to get false-positive assertion. + * TODO: switch test for k_cycle_get_64 usage where available. + */ +#if !defined(CONFIG_SOC_ARC_HSDK) && !defined(CONFIG_SOC_ARC_HSDK4XD) /* lower bounds check */ zassert_true(actual_ns >= exp_ns, "actual: %llu expected: %llu", actual_ns, exp_ns); +#endif /* TODO: Upper bounds check when hr timers are available */ } From dde691bdd49a8864a441c21aae9a78eccd70f3f6 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 13 Oct 2023 12:03:59 -0500 Subject: [PATCH 2004/4498] doc: migration-guide-3.5: LPC DMA dma-channels Include in migration guide about how the meaning of dma-channels to the LPC DMA driver has been changed/fixed, which will affect downstream boards, and information about the new Kconfig achieving the old functionality of dma-channels. Signed-off-by: Declan Snyder --- doc/releases/migration-guide-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 22fa8558655..57b40867660 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -282,6 +282,13 @@ Required changes * The zbus VDED delivery sequence has changed. Check the :ref:`documentation` to verify if it will affect your code. +* On NXP boards with LPC DMA, the DMA controller node used to have its ``dma-channels`` property + set in the board DTS as a way to configure the amount of structures the driver will allocate. + This did not match the zephyr dma-controller binding, so this property is now fixed and set + in the SOC devicetree definition. Downstream boards should not override this property and + instead use the new driver Kconfig + :kconfig:option:`CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED`. + Recommended Changes ******************* From 17032a093d31da46a106a2abff97af6177367b8d Mon Sep 17 00:00:00 2001 From: Emilio Benavente Date: Tue, 19 Sep 2023 07:19:50 -0500 Subject: [PATCH 2005/4498] drivers: spi: spi_mcux_lpspi: Updated the Async api Updated the Async API allowing the code path for DMA while Async is enabled. Added common DMA function that sets up both tx and rx dma channels. Signed-off-by: Emilio Benavente --- drivers/spi/spi_mcux_lpspi.c | 169 ++++++++++++++++++++++++----------- 1 file changed, 118 insertions(+), 51 deletions(-) diff --git a/drivers/spi/spi_mcux_lpspi.c b/drivers/spi/spi_mcux_lpspi.c index 8af05a28434..9b230d1c53f 100644 --- a/drivers/spi/spi_mcux_lpspi.c +++ b/drivers/spi/spi_mcux_lpspi.c @@ -248,6 +248,8 @@ static int spi_mcux_configure(const struct device *dev, } #ifdef CONFIG_SPI_MCUX_LPSPI_DMA +static int spi_mcux_dma_rxtx_load(const struct device *dev, + size_t *dma_size); /* This function is executed in the interrupt context */ static void spi_mcux_dma_callback(const struct device *dev, void *arg, @@ -276,6 +278,26 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, data->status_flags |= SPI_MCUX_LPSPI_DMA_ERROR_FLAG; } } +#if CONFIG_SPI_ASYNC + if (data->ctx.asynchronous && + ((data->status_flags & SPI_MCUX_LPSPI_DMA_DONE_FLAG) == + SPI_MCUX_LPSPI_DMA_DONE_FLAG)) { + /* Load dma blocks of equal length */ + size_t dma_size = MIN(data->ctx.tx_len, data->ctx.rx_len); + + if (dma_size == 0) { + dma_size = MAX(data->ctx.tx_len, data->ctx.rx_len); + } + + spi_context_update_tx(&data->ctx, 1, dma_size); + spi_context_update_rx(&data->ctx, 1, dma_size); + + if (data->ctx.tx_len == 0 && data->ctx.rx_len == 0) { + spi_context_complete(&data->ctx, spi_dev, 0); + } + return; + } +#endif spi_context_complete(&data->ctx, spi_dev, 0); } @@ -386,6 +408,45 @@ static int wait_dma_rx_tx_done(const struct device *dev) } } +static inline int spi_mcux_dma_rxtx_load(const struct device *dev, + size_t *dma_size) +{ + struct spi_mcux_data *lpspi_data = dev->data; + int ret = 0; + + /* Clear status flags */ + lpspi_data->status_flags = 0U; + /* Load dma blocks of equal length */ + *dma_size = MIN(lpspi_data->ctx.tx_len, lpspi_data->ctx.rx_len); + if (*dma_size == 0) { + *dma_size = MAX(lpspi_data->ctx.tx_len, lpspi_data->ctx.rx_len); + } + + ret = spi_mcux_dma_tx_load(dev, lpspi_data->ctx.tx_buf, + *dma_size); + if (ret != 0) { + return ret; + } + + ret = spi_mcux_dma_rx_load(dev, lpspi_data->ctx.rx_buf, + *dma_size); + if (ret != 0) { + return ret; + } + + /* Start DMA */ + ret = dma_start(lpspi_data->dma_tx.dma_dev, + lpspi_data->dma_tx.channel); + if (ret != 0) { + return ret; + } + + ret = dma_start(lpspi_data->dma_rx.dma_dev, + lpspi_data->dma_rx.channel); + return ret; + +} + static int transceive_dma(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, @@ -400,78 +461,74 @@ static int transceive_dma(const struct device *dev, int ret; size_t dma_size; - spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); + if (!asynchronous) { + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); + } ret = spi_mcux_configure(dev, spi_cfg); if (ret) { - goto out; + if (!asynchronous) { + spi_context_release(&data->ctx, ret); + } + return ret; } - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); - - spi_context_cs_control(&data->ctx, true); - /* DMA is fast enough watermarks are not required */ LPSPI_SetFifoWatermarks(base, 0U, 0U); - /* Send each spi buf via DMA, updating context as DMA completes */ - while (data->ctx.rx_len > 0 || data->ctx.tx_len > 0) { - /* Clear status flags */ - data->status_flags = 0U; - /* Load dma blocks of equal length */ - dma_size = MIN(data->ctx.tx_len, data->ctx.rx_len); - if (dma_size == 0) { - dma_size = MAX(data->ctx.tx_len, data->ctx.rx_len); - } - ret = spi_mcux_dma_tx_load(dev, data->ctx.tx_buf, dma_size); - if (ret != 0) { - goto out; + if (!asynchronous) { + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + spi_context_cs_control(&data->ctx, true); + + /* Send each spi buf via DMA, updating context as DMA completes */ + while (data->ctx.rx_len > 0 || data->ctx.tx_len > 0) { + /* Load dma block */ + ret = spi_mcux_dma_rxtx_load(dev, &dma_size); + if (ret != 0) { + goto out; + } + /* Enable DMA Requests */ + LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + + /* Wait for DMA to finish */ + ret = wait_dma_rx_tx_done(dev); + if (ret != 0) { + goto out; + } + while ((LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)) { + /* wait until module is idle */ + } + + /* Disable DMA */ + LPSPI_DisableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + + /* Update SPI contexts with amount of data we just sent */ + spi_context_update_tx(&data->ctx, 1, dma_size); + spi_context_update_rx(&data->ctx, 1, dma_size); } + spi_context_cs_control(&data->ctx, false); - ret = spi_mcux_dma_rx_load(dev, data->ctx.rx_buf, dma_size); - if (ret != 0) { - goto out; - } +out: + spi_context_release(&data->ctx, ret); + } +#if CONFIG_SPI_ASYNC + else { + data->ctx.asynchronous = asynchronous; + data->ctx.callback = cb; + data->ctx.callback_data = userdata; - /* Start DMA */ - ret = dma_start(data->dma_tx.dma_dev, data->dma_tx.channel); - if (ret != 0) { - goto out; - } - ret = dma_start(data->dma_rx.dma_dev, data->dma_rx.channel); + ret = spi_mcux_dma_rxtx_load(dev, &dma_size); if (ret != 0) { goto out; } /* Enable DMA Requests */ LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); - - /* Wait for DMA to finish */ - ret = wait_dma_rx_tx_done(dev); - if (ret != 0) { - goto out; - } - - while ((LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)) { - /* wait until module is idle */ - } - - /* Disable DMA */ - LPSPI_DisableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); - - /* Update SPI contexts with amount of data we just sent */ - spi_context_update_tx(&data->ctx, 1, dma_size); - spi_context_update_rx(&data->ctx, 1, dma_size); } - - spi_context_cs_control(&data->ctx, false); - -out: - spi_context_release(&data->ctx, ret); +#endif return ret; } - #endif static int transceive(const struct device *dev, @@ -530,7 +587,17 @@ static int spi_mcux_transceive_async(const struct device *dev, spi_callback_t cb, void *userdata) { +#ifdef CONFIG_SPI_MCUX_LPSPI_DMA + struct spi_mcux_data *data = dev->data; + + if (data->dma_rx.dma_dev && data->dma_tx.dma_dev) { + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + } + + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +#else return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +#endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ } #endif /* CONFIG_SPI_ASYNC */ From b9613389fbe471cca4594e9324885354886415a7 Mon Sep 17 00:00:00 2001 From: Emilio Benavente Date: Tue, 19 Sep 2023 07:22:27 -0500 Subject: [PATCH 2006/4498] tests: drivers: spi: spi_loopback: Added mimxrt1170_evk_cm7 Added overlay inside the spi loopback test for the mimxrt1170_evk_cm7, enabled DMA and Async by default. Added testcase for async and dma. Signed-off-by: Emilio Benavente --- .../arm/mimxrt1170_evk/mimxrt1170_evk_cm7.dts | 2 ++ .../arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.dts | 2 ++ boards/arm/twr_ke18f/twr_ke18f.dts | 2 ++ .../boards/mimxrt1170_evk_cm7.conf | 6 ++++++ .../boards/mimxrt1170_evk_cm7.overlay | 18 ++++++++++++++++++ tests/drivers/spi/spi_loopback/testcase.yaml | 14 ++++++++++++++ 6 files changed, 44 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.overlay diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.dts b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.dts index 1bf1ef1597f..48564a03b4d 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.dts +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7.dts @@ -82,6 +82,8 @@ zephyr_mipi_dsi: &mipi_dsi { }; &lpspi1 { + dmas = <&edma0 0 36>, <&edma0 1 37>; + dma-names = "rx", "tx"; status = "okay"; }; diff --git a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.dts b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.dts index 727ada86cd3..5700b77837c 100644 --- a/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.dts +++ b/boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm4.dts @@ -71,6 +71,8 @@ }; &lpspi1 { + dmas = <&edma_lpsr0 0 36>, <&edma_lpsr0 1 37>; + dma-names = "rx", "tx"; status = "okay"; }; diff --git a/boards/arm/twr_ke18f/twr_ke18f.dts b/boards/arm/twr_ke18f/twr_ke18f.dts index b8ab3e8af4d..92a11d68842 100644 --- a/boards/arm/twr_ke18f/twr_ke18f.dts +++ b/boards/arm/twr_ke18f/twr_ke18f.dts @@ -266,6 +266,8 @@ }; &lpspi0 { + dmas = <&edma 0 14>, <&edma 1 15>; + dma-names = "rx", "tx"; status = "okay"; pinctrl-0 = <&lpspi0_default>; pinctrl-names = "default"; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.conf b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.conf new file mode 100644 index 00000000000..1ce2ad49200 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.conf @@ -0,0 +1,6 @@ +# +# Copyright 2023 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_SPI_MCUX_LPSPI_DMA=y diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.overlay new file mode 100644 index 00000000000..fa2b906bbd7 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_cm7.overlay @@ -0,0 +1,18 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&lpspi1 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index ed2339d8f54..3c6995e37cd 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -13,6 +13,20 @@ tests: drivers.spi.loopback: {} drivers.spi.loopback.internal: filter: CONFIG_SPI_LOOPBACK_MODE_LOOP + drivers.spi.loopback.lpspi.dma: + filter: CONFIG_HAS_MCUX_LPSPI and CONFIG_HAS_MCUX_EDMA + extra_configs: + - CONFIG_SPI_MCUX_LPSPI_DMA=y + drivers.spi.loopback.lpspi.async.unset: + filter: CONFIG_HAS_MCUX_LPSPI and CONFIG_HAS_MCUX_EDMA + extra_configs: + - CONFIG_SPI_MCUX_LPSPI_DMA=n + - CONFIG_SPI_ASYNC=n + drivers.spi.loopback.lpspi.dma.async.unset: + filter: CONFIG_HAS_MCUX_LPSPI and CONFIG_HAS_MCUX_EDMA + extra_configs: + - CONFIG_SPI_MCUX_LPSPI_DMA=y + - CONFIG_SPI_ASYNC=n drivers.spi.loopback.rtio: extra_configs: - CONFIG_SPI_RTIO=y From bbf46b96ceba44faac1039cd9f6755b5d9f0c946 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 14 Oct 2023 10:56:17 +0300 Subject: [PATCH 2007/4498] release: Zephyr 3.5.0-rc3 Bump the version to 3.5.0-rc3. Signed-off-by: Johan Hedberg --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 71917906205..5ed75f8b8ea 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ VERSION_MAJOR = 3 VERSION_MINOR = 5 PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = rc2 +EXTRAVERSION = rc3 From 14c1ff25b13547ee471e8a83b59656aec33e7610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Sat, 14 Oct 2023 10:53:37 +0200 Subject: [PATCH 2008/4498] doc: ring_buffer: Properly expose Doxygen doc for ring_buf struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the ring_buf struct in the Doxygen group containing all other APIs. Signed-off-by: Benjamin Cabé --- include/zephyr/sys/ring_buffer.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/zephyr/sys/ring_buffer.h b/include/zephyr/sys/ring_buffer.h index 812824ade58..bd2cd5ef1ef 100644 --- a/include/zephyr/sys/ring_buffer.h +++ b/include/zephyr/sys/ring_buffer.h @@ -25,6 +25,16 @@ extern "C" { "Size too big" /** @endcond */ +/** + * @file + * @defgroup ring_buffer_apis Ring Buffer APIs + * @ingroup datastructure_apis + * + * @brief Simple ring buffer implementation. + * + * @{ + */ + /** * @brief A structure to represent a ring buffer */ @@ -41,16 +51,6 @@ struct ring_buf { /** @endcond */ }; -/** - * @file - * @defgroup ring_buffer_apis Ring Buffer APIs - * @ingroup datastructure_apis - * - * @brief Simple ring buffer implementation. - * - * @{ - */ - /** * @brief Function to force ring_buf internal states to given value * From 8ec1a27920b5eb5f937014defbdfed101ae86adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Sat, 14 Oct 2023 09:17:26 +0200 Subject: [PATCH 2009/4498] doc: ring_buffer: fix typos and incoherences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed an incorrect mention of buffer size being expressed in 32-byte words for data item mode when it's in fact 32-bit. Fixed a few broken references to C functions and structs. Signed-off-by: Benjamin Cabé --- doc/kernel/data_structures/ring_buffers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/kernel/data_structures/ring_buffers.rst b/doc/kernel/data_structures/ring_buffers.rst index 63ff3f2b4eb..d077cf1f21f 100644 --- a/doc/kernel/data_structures/ring_buffers.rst +++ b/doc/kernel/data_structures/ring_buffers.rst @@ -44,7 +44,7 @@ A ring buffer has the following key properties: bytes or 32-bit words that have been added to the ring buffer but not yet removed. -* A **data buffer size**, measured in bytes or 32-byte words. This governs +* A **data buffer size**, measured in bytes or 32-bit words. This governs the maximum amount of data (including possible metadata values) the ring buffer can hold. @@ -53,7 +53,7 @@ data buffer to empty. A ``struct ring_buf`` may be placed anywhere in user-accessible memory, and must be initialized with :c:func:`ring_buf_init` or -:c:func:`ring_buf_element_init` before use. This must be provided a region +:c:func:`ring_buf_item_init` before use. This must be provided a region of user-controlled memory for use as the buffer itself. Note carefully that the units of the size of the buffer passed change (either bytes or words) depending on how the ring buffer will be used later. Macros for combining these steps in a From bcd3882f88bbaa3ce49d3338de2fdcb8b1905a87 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 13 Oct 2023 13:49:59 -0700 Subject: [PATCH 2010/4498] doc: release: 3.5: Add info about CVE-2023-4263 Add CVE-2023-4263 info to release notes. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index f3f54e5a76b..1cee2559413 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -34,6 +34,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-4260 `Zephyr project bug tracker GHSA-gj27-862r-55wh `_ +* CVE-2023-4263 `Zephyr project bug tracker GHSA-rf6q-rhhp-pqhf + `_ + * CVE-2023-4264 `Zephyr project bug tracker GHSA-rgx6-3w4j-gf5j `_ From 52cf7e6fdf51e0d00e62bcd085aaae92da7a8c8e Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 13 Oct 2023 13:56:08 -0700 Subject: [PATCH 2011/4498] doc: vuln: Add information about CVE-2023-4263 Information about CVE-2023-4263 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index d2281c32bbc..1261f50be89 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1430,6 +1430,25 @@ Potential buffer overflow vulnerabilities in the Zephyr Mgmt subsystem - This issue has not been fixed. +CVE-2023-4263 +------------- + +Potential buffer overflow vulnerability in the Zephyr IEEE 802.15.4 nRF 15.4 driver. + +- `Zephyr project bug tracker GHSA-rf6q-rhhp-pqhf + `_ + +This has been fixed in main for v3.5.0 + +- `PR 60528 fix for main + `_ + +- `PR 61384 fix for 3.4 + `_ + +- `PR 61216 fix for 2.7 + `_ + CVE-2023-4264 ------------- From 90b9809c6f5563c8a8f93310fa65fdb8f321bc06 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 13 Oct 2023 14:20:24 -0700 Subject: [PATCH 2012/4498] doc: security: cve-2023-4257 left embargo Disclose information about cve-2023-4257. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 ++- doc/security/vulnerabilities.rst | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 1cee2559413..f66ff4c2053 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -23,7 +23,8 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-3725 `Zephyr project bug tracker GHSA-2g3m-p6c7-8rr3 `_ -* CVE-2023-4257: Under embargo until 2023-10-12 +* CVE-2023-4257 `Zephyr project bug tracker GHSA-853q-q69w-gf5j + `_ * CVE-2023-4258 `Zephyr project bug tracker GHSA-m34c-cp63-rwh7 `_ diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 1261f50be89..669383e7d0f 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1370,7 +1370,19 @@ This has been fixed in main for v3.5.0 CVE-2023-4257 ------------- -Under embargo until 2023/10/12 +Unchecked user input length in the Zephyr WiFi shell module can cause +buffer overflows. + +- `Zephyr project bug tracker GHSA-853q-q69w-gf5j + `_ + +This has been fixed in main for v3.5.0 + +- `PR 605377 fix for main + `_ + +- `PR 61383 fix for 3.4 + `_ CVE-2023-4258 ------------- From 137097f5c3153cefb9f585aa7b2d88bf09a384aa Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 15 Oct 2023 09:42:09 -0400 Subject: [PATCH 2013/4498] logging: log_core: correct timeout of -1 ms to K_FOREVER Many releases ago, specifying to block indefinitely in the log processing thread would do just that. However, a subtle bug was introduced such that specifying -1 for `CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS` would have the exact opposite effect than what was intended. As per Kconfig, a value of -1 should translate to a timeout of `K_FOREVER`. However, conversion via `K_MSEC(-1)` results in a `k_timeout_t` that is equal to `K_NO_WAIT` rather than the intent which is `K_FOREVER`. Add a dedicated check to to ensure that a value of -1 is correctly interpreted as `K_FOREVER` in `log_core.c`. For reference, the blocking feature was described in #15196, added in #16194, and it would appear that the regression happened in c5f2cdef09. Signed-off-by: Christopher Friedt --- subsys/logging/log_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index 8322732d434..7ba2cde3c77 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -597,8 +597,11 @@ static struct log_msg *msg_alloc(struct mpsc_pbuf_buffer *buffer, uint32_t wlen) return NULL; } - return (struct log_msg *)mpsc_pbuf_alloc(buffer, wlen, - K_MSEC(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS)); + return (struct log_msg *)mpsc_pbuf_alloc( + buffer, wlen, + (CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS == -1) + ? K_FOREVER + : K_MSEC(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS)); } struct log_msg *z_log_msg_alloc(uint32_t wlen) From 24085d05e6fa48c69e694efed176e4195dbcd76c Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Mon, 9 Oct 2023 09:40:16 +0200 Subject: [PATCH 2014/4498] boards: doc: Add programming tabs for mimx8mq_evk Improve documentation by putting programming methods into tabs. Signed-off-by: Jeppe Odgaard --- boards/arm/mimx8mq_evk/doc/index.rst | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/boards/arm/mimx8mq_evk/doc/index.rst b/boards/arm/mimx8mq_evk/doc/index.rst index 4cdc9233b4d..486bf298fec 100644 --- a/boards/arm/mimx8mq_evk/doc/index.rst +++ b/boards/arm/mimx8mq_evk/doc/index.rst @@ -140,48 +140,48 @@ The available configurations are: Load and run Zephyr on M4 from A53 using u-boot. -From an SD card: +.. tabs:: -Copy the compiled ``zephyr.bin`` to the first FAT partition of the -SD card and plug the SD card into the board. Power it up and stop the u-boot -execution at prompt. + .. group-tab:: From an SD card + Copy the compiled ``zephyr.bin`` to the first FAT partition of the + SD card and plug the SD card into the board. Power it up and stop the u-boot + execution at prompt. -Load the M4 binary onto the desired memory and start its execution using: + Load the M4 binary onto the desired memory and start its execution using: -.. code-block:: console - - fatload mmc 0:1 0x40480000 zephyr.bin - cp.b 0x40480000 0x7e0000 0x8000 - bootaux 0x7e0000 + .. code-block:: console -From serial: + fatload mmc 0:1 0x40480000 zephyr.bin + cp.b 0x40480000 0x7e0000 0x8000 + bootaux 0x7e0000 -This procedure requires `screen` and `lrzsz` to be installed. + .. group-tab:: From serial + This procedure requires ``screen`` and ``lrzsz`` to be installed. -Start ``screen``, power up the board, and stop the u-boot execution at prompt: + Start ``screen``, power up the board, and stop the u-boot execution at prompt: -.. code-block:: console + .. code-block:: console - screen 115200 + screen 115200 -Start ``loadx`` with offset ``7e0000``: + Start ``loadx`` with offset ``7e0000``: -.. code-block:: console + .. code-block:: console - loadx 7e0000 115200 + loadx 7e0000 115200 -Send the compiled ``zephyr.bin`` with ``sx`` by pressing Ctrl-a followed by ':' -and write: + Send the compiled ``zephyr.bin`` with ``sx`` by pressing :kbd:`Ctrl-a` followed by :kbd:`:` + and write: -.. code-block:: console + .. code-block:: console - exec !! sx + exec !! sx -Start execution: + Start execution: -.. code-block:: console + .. code-block:: console - bootaux 0x7e0000 + bootaux 0x7e0000 Debugging ========= From cb9230ee307a0a46ca0fefe38c908c0fbb8dae8a Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 16 Oct 2023 11:29:27 -0500 Subject: [PATCH 2015/4498] docs: releases: Add DMA release notes for 3.5 Adds notable bug fixes, driver additions, and feature additions to the DMA API and drivers in 3.5. Signed-off-by: Tom Burdick --- doc/releases/release-notes-3.5.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index f66ff4c2053..9466659dd2b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -311,6 +311,14 @@ Drivers and Sensors * DMA + * Added support for NXP S32K to the eDMA driver + * Added support for NXP SMARTDMA + * Added support for NXP Pixel Pipeline (PXP) for display acceleration + * Added support for DMA get_status() to the SAM XDMAC driver + * Fixes for Intel HDA driver for L1 entry/exit, explicit SCS (sample container) settings + * Fixes for STM32U5 enables error interrupts, fixes block size and data size configuration + * Better Kconfig options for tuning static memory usage in NXP LPC driver + * EEPROM * Added support for Fujitsu MB85RCxx series I2C FRAM (:dtcompatible:`fujitsu,mb85rcxx`). From b272760f062b36fe6ce5d14c7a3d9065d40a570a Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 16 Oct 2023 11:41:07 -0500 Subject: [PATCH 2016/4498] docs: releases: Adds I2C release notes for 3.5 Adds a subset (there was a lot!) of notable fixes, features, and driver additions for I2C Signed-off-by: Tom Burdick --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9466659dd2b..7616242a3dc 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -375,6 +375,15 @@ Drivers and Sensors * STM32 V1 driver now supports large transactions (more than 256 bytes chunks) * STM32 V2 driver now supports 10-bit addressing. * I2C devices can now be used as wakeup source from STOP modes on STM32. + * Fix long ISR execution in Silicon Labs I2C target callback + * Fail gracefully on DMA max size for nRF52 devices in the TWIM driver + * Added support for Intel LPSS DMA usage in the DesignWare driver + * Added filtering of dumped messages for debugging using DeviceTree + * Added target mode to Silicon Labs Gecko driver + * Added Intel SEDI driver + * Added Infineon XMC4 driver + * Added Microchip PolarFire SoC driver + * Added Ambiq driver for Apollo4 SoCs * I2S From edfddd6a1174b9a32006709287be2e34eb97d396 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 16 Oct 2023 11:13:34 -0500 Subject: [PATCH 2017/4498] docs: releases: RTIO Release Notes for 3.5 Adds release notes for the RTIO subsystem for 3.5 with notable bug fixes, changes, and feature additions. Signed-off-by: Tom Burdick --- doc/releases/release-notes-3.5.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7616242a3dc..4294e1e09d9 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -896,6 +896,13 @@ Libraries / Subsystems * Added support for CAN FD. +* RTIO + + * Added atomic completion counter fixing a race caught by unit tests + * Added a :c:macro:`RTIO_SQE_NO_RESPONSE` flag for submissions when no completion notification + is needed + * Removed unused Kconfig options for different executors + HALs **** From 9fcc6092371f894c6e0f8cf8c5ddb3bbc2102020 Mon Sep 17 00:00:00 2001 From: Andrei Hutanu Date: Mon, 21 Aug 2023 10:28:20 +0200 Subject: [PATCH 2018/4498] docs: mem: slabs: fix for mem_slab docs snippets Attempting to run the memory slab docs snippets will result in build issues. This PR is an attempt to fix those. Signed-off-by: Andrei Hutanu --- doc/kernel/memory_management/slabs.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/kernel/memory_management/slabs.rst b/doc/kernel/memory_management/slabs.rst index ae57a789b19..7f6945ee386 100644 --- a/doc/kernel/memory_management/slabs.rst +++ b/doc/kernel/memory_management/slabs.rst @@ -109,7 +109,7 @@ A warning is printed if a suitable block is not obtained. char *block_ptr; - if (k_mem_slab_alloc(&my_slab, &block_ptr, 100) == 0) { + if (k_mem_slab_alloc(&my_slab, (void **)&block_ptr, K_MSEC(100)) == 0) { memset(block_ptr, 0, 400); ... } else { @@ -128,9 +128,9 @@ then releases it once it is no longer needed. char *block_ptr; - k_mem_slab_alloc(&my_slab, &block_ptr, K_FOREVER); + k_mem_slab_alloc(&my_slab, (void **)&block_ptr, K_FOREVER); ... /* use memory block pointed at by block_ptr */ - k_mem_slab_free(&my_slab, block_ptr); + k_mem_slab_free(&my_slab, (void *)block_ptr); Suggested Uses ************** From b1b8b3b4d0b767dc6398fa359fafd2313758dfcd Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 10 Oct 2023 22:19:39 -0700 Subject: [PATCH 2019/4498] doc: migration-guide-3.5: Random subsys update Add information about header name changes. Signed-off-by: Flavio Ceolin --- doc/releases/migration-guide-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 57b40867660..41b3f4eb4bb 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -350,3 +350,7 @@ Recommended Changes ```` are now deprecated in favor of including ```` instead. The new header is part of the CMSIS glue code in the ``modules`` directory. + +* Random API header ```` is deprecated in favor of + ````. The old header will be removed in future releases + and its usage should be avoided. From 1b34ddae965102212f54ec995ccce3f8d57c71d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 16 Oct 2023 19:14:23 -0400 Subject: [PATCH 2020/4498] doc: releases: Move release notes of EOL releases to a dedicated page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ever growing list of release notes for past releases was making it too easy to miss the migration guide for the latest release. This commit moves the release notes for EOL releases to a dedicated page. Signed-off-by: Benjamin Cabé --- doc/releases/eol_releases.rst | 14 ++++++++++++++ doc/releases/index.rst | 12 +++--------- 2 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 doc/releases/eol_releases.rst diff --git a/doc/releases/eol_releases.rst b/doc/releases/eol_releases.rst new file mode 100644 index 00000000000..22900a55e44 --- /dev/null +++ b/doc/releases/eol_releases.rst @@ -0,0 +1,14 @@ +End-of-life releases +==================== + +Release notes for end-of-life releases of Zephyr RTOS are kept here for historical purposes. + +.. toctree:: + :maxdepth: 1 + :glob: + :reversed: + + release-notes-1.? + release-notes-1.* + release-notes-2.[0-6] + release-notes-3.[0-2] diff --git a/doc/releases/index.rst b/doc/releases/index.rst index 48855b65fae..9610464491c 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -74,20 +74,14 @@ so with the help of west. The project's technical documentation is also tagged to correspond with a specific release and can be found at https://docs.zephyrproject.org/. -.. comment We need to split the globbing of release notes to get the - single-digit and double-digit subversions sorted correctly. Specify - names in normal order and use the :reversed: option to reverse it. - This will get us through 10 subversions (0-9) before we need to - update this list for two-digit subversions again. - .. toctree:: :maxdepth: 1 :glob: :reversed: - release-notes-1.? - release-notes-1.* - release-notes-* + eol_releases + release-notes-2.7 + release-notes-3.[3-5] Migration Guides **************** From 9e9f439522c1f0f0ef58d562283f7c979954bb86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 16 Oct 2023 19:28:00 -0400 Subject: [PATCH 2021/4498] doc: releases: clean-up release notes section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The contents of the Release notes section was partly outdated and partly misplaced. Moved the relevant bits to the actual intro of the doc. Signed-off-by: Benjamin Cabé --- doc/releases/index.rst | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/doc/releases/index.rst b/doc/releases/index.rst index 9610464491c..7433df77e0b 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -3,11 +3,17 @@ Releases ######## -Zephyr project is provided as source code and build scripts for different -target architectures and configurations, and not as a binary image. Updated -versions of the Zephyr project are released approximately every four months. +Zephyr project is provided as source code and build scripts for different target +architectures and configurations, and not as a binary image. Updated versions of +the Zephyr project are released approximately every four months. -All Zephyr project source code is maintained in a `GitHub repository`_. +All Zephyr project source code is maintained in a `GitHub repository`_. In order +to use a released version of the Zephyr project, it is recommended that you use +:ref:`west` to :ref:`get_the_code` of the release you are interested in. + +The technical documentation for current and past releases is available at +https://docs.zephyrproject.org/ (use the version selector to select your release +of interest). Release Life Cycle and Maintenance ********************************** @@ -62,18 +68,6 @@ As of 2022-01-01, LTS1 (1.14.x) is not supported and has reached end of life (EO Release Notes ************* -For Zephyr versions up to 1.13, you can either download source as a tar.gz file -(see the bottom of the `GitHub tagged releases`_ page corresponding to each -release), or clone the GitHub repository. - -With the introduction of the :ref:`west` tool after the release of Zephyr 1.13, -it is no longer recommended to download or clone the source code manually. -Instead we recommend you follow the instructions in :ref:`get_the_code` to do -so with the help of west. - -The project's technical documentation is also tagged to correspond with a -specific release and can be found at https://docs.zephyrproject.org/. - .. toctree:: :maxdepth: 1 :glob: From 1244f109eed60cf8d9c29929e32f12f495d15635 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 16 Oct 2023 17:08:42 +0200 Subject: [PATCH 2022/4498] zbus: Remove obsolete function from header _zbus_timeout_remainder was removed in a7b3584 however 7e44469 re-introduced it in the header. Signed-off-by: Pieter De Gendt --- include/zephyr/zbus/zbus.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index 8a4188aa821..7e5557ef84e 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -225,7 +225,6 @@ struct zbus_channel_observation { #define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */ -k_timeout_t _zbus_timeout_remainder(uint64_t end_ticks); /** @endcond */ /** From 475361b22c0b86d36dfe12a8ec7c31aef6435f80 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Mon, 16 Oct 2023 12:22:38 -0300 Subject: [PATCH 2023/4498] doc: releases: v3.5.0: zbus release notes Add the changes of zbus during the Zephyr v3.5.0 development. Signed-off-by: Rodrigo Peixoto --- doc/releases/release-notes-3.5.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 4294e1e09d9..17ebc99b46c 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -903,6 +903,30 @@ Libraries / Subsystems is needed * Removed unused Kconfig options for different executors +* ZBus + + * Changed channels' and observers' metadata to comply with the data/config approach. ZBus stores + immutable config in iterable sections in Flash and the mutable portion of data in the RAM. + * The relationship between channels and observers is mapped using a new entity called + observation. The observation enables us to increase the granularity of masking observation. + Developers can mask individual observations, disable the observer, or use runtime observers. + * Added API :c:macro:`ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a + channel. That can replace the runtime observer feature, enabling developers to add static + observers after the channel definition in different files. It increases the composability of + the system using ZBus, making post-definition channel observation rely on the stack instead of + the heap. + * Added a new type of observer called Message Subscriber. ZBus' VDED will send a copy of the + message during the publication/notification process. + * Changed the VDED delivery sequence. Check the ref:`documentation`. + * ZBus runtime observers now rely on the heap instead of a memory pool. + * Added new iterable section iterators APIs (for channels and observers) can now receive a + ``user_data`` pointer to keep context between the function calls. + * Added APIs :c:macro:`ZBUS_LISTENER_DEFINE_WITH_ENABLE` and + :c:macro:`ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE` that allows developers to define observers' + statuses (enabled/disabled) programmatically. With the API, developers can create observers + initially disabled and enable them in runtime. + + HALs **** @@ -1030,5 +1054,10 @@ Tests and Samples * Created common sample for file systems (`fs_sample`). It originates from sample for FAT (`fat_fs`) and supports both FAT and ext2 file systems. +* Created the zbus confirmed channel sample to demonstrate how to implement a delivery-guaranteed + channel using subscribers. + +* Created the zbus message subscriber sample to demonstrate how to use message subscribers. + Known Issues ************ From 3b9acef1ba5f935883260a4d09214ad11e68295a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 21:32:58 +0000 Subject: [PATCH 2024/4498] ci: move footprint workflows to zephyr runners looks like our docker image is way too big for the GH runners, so move to own runners until we have a better solution. Signed-off-by: Anas Nashif --- .github/workflows/footprint-tracking.yml | 2 +- .github/workflows/footprint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index 63a1277be17..fee3a00449f 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -22,7 +22,7 @@ concurrency: jobs: footprint-tracking: - runs-on: ubuntu-22.04 + runs-on: zephyr-runner-linux-x64-4xlarge if: github.repository_owner == 'zephyrproject-rtos' container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 diff --git a/.github/workflows/footprint.yml b/.github/workflows/footprint.yml index 6a7005f1880..685c5644b0c 100644 --- a/.github/workflows/footprint.yml +++ b/.github/workflows/footprint.yml @@ -8,7 +8,7 @@ concurrency: jobs: footprint-delta: - runs-on: ubuntu-22.04 + runs-on: zephyr-runner-linux-x64-4xlarge if: github.repository == 'zephyrproject-rtos/zephyr' container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 From b732c6d564e542fd25b63041ec713346e01711aa Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 17 Oct 2023 14:55:45 +0200 Subject: [PATCH 2025/4498] actions: manifest: Update action revision Upgrade to v1.2.0, which comes with a bugfix and support for processing PRs that have removed modifications to the manifest. Signed-off-by: Carles Cufi --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 49f67fb95b7..eeee77e61a6 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -26,7 +26,7 @@ jobs: west init -l . || true - name: Manifest - uses: zephyrproject-rtos/action-manifest@f223dce288b0d8f30bfd57eb2b14b18c230a7d8b + uses: zephyrproject-rtos/action-manifest@v1.2.0 with: github-token: ${{ secrets.ZB_GITHUB_TOKEN }} manifest-path: 'west.yml' From b9748b53772a77302019511d8c990200e602e53b Mon Sep 17 00:00:00 2001 From: Nando Galliard Date: Mon, 16 Oct 2023 12:20:23 +0200 Subject: [PATCH 2026/4498] drivers: serial: Support STM32 LPUART if LPUART1 is not defined. When LPUART1 is not defined, the driver did not compile even if any other LPUART was defined. This patch fixes that. Signed-off-by: Nando Galliard --- drivers/serial/uart_stm32.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 9243b10d7e7..6c41d0f0a2e 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -51,8 +51,7 @@ LOG_MODULE_REGISTER(uart_stm32, CONFIG_UART_LOG_LEVEL); #define STM32_UART_DOMAIN_CLOCK_SUPPORT 0 #endif -#define HAS_LPUART_1 (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), \ - st_stm32_lpuart, okay)) +#define HAS_LPUART DT_HAS_COMPAT_STATUS_OKAY(st_stm32_lpuart) /* Available everywhere except l1, f1, f2, f4. */ #ifdef USART_CR3_DEM @@ -61,7 +60,7 @@ LOG_MODULE_REGISTER(uart_stm32, CONFIG_UART_LOG_LEVEL); #define HAS_DRIVER_ENABLE 0 #endif -#if HAS_LPUART_1 +#if HAS_LPUART #ifdef USART_PRESC_PRESCALER uint32_t lpuartdiv_calc(const uint64_t clock_rate, const uint16_t presc_idx, const uint32_t baud_rate) @@ -87,7 +86,7 @@ uint32_t lpuartdiv_calc(const uint64_t clock_rate, const uint32_t baud_rate) return (uint32_t)lpuartdiv; } #endif /* USART_PRESC_PRESCALER */ -#endif /* HAS_LPUART_1 */ +#endif /* HAS_LPUART */ #ifdef CONFIG_PM static void uart_stm32_pm_policy_state_lock_get(const struct device *dev) @@ -135,7 +134,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba } } -#if HAS_LPUART_1 +#if HAS_LPUART if (IS_LPUART_INSTANCE(config->usart)) { uint32_t lpuartdiv; #ifdef USART_PRESC_PRESCALER @@ -178,7 +177,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba __ASSERT(LL_LPUART_ReadReg(config->usart, BRR) < 0x000FFFFFU, "BaudRateReg < 0xFFFF"); } else { -#endif /* HAS_LPUART_1 */ +#endif /* HAS_LPUART */ #ifdef USART_CR1_OVER8 LL_USART_SetOverSampling(config->usart, LL_USART_OVERSAMPLING_16); @@ -196,9 +195,9 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba __ASSERT(LL_USART_ReadReg(config->usart, BRR) >= 16, "BaudRateReg >= 16"); -#if HAS_LPUART_1 +#if HAS_LPUART } -#endif /* HAS_LPUART_1 */ +#endif /* HAS_LPUART */ } static inline void uart_stm32_set_parity(const struct device *dev, @@ -315,12 +314,12 @@ static inline uint32_t uart_stm32_cfg2ll_stopbits(const struct uart_stm32_config /* Some MCU's don't support 0.5 stop bits */ #ifdef LL_USART_STOPBITS_0_5 case UART_CFG_STOP_BITS_0_5: -#if HAS_LPUART_1 +#if HAS_LPUART if (IS_LPUART_INSTANCE(config->usart)) { /* return the default */ return LL_USART_STOPBITS_1; } -#endif /* HAS_LPUART_1 */ +#endif /* HAS_LPUART */ return LL_USART_STOPBITS_0_5; #endif /* LL_USART_STOPBITS_0_5 */ case UART_CFG_STOP_BITS_1: @@ -328,7 +327,7 @@ static inline uint32_t uart_stm32_cfg2ll_stopbits(const struct uart_stm32_config /* Some MCU's don't support 1.5 stop bits */ #ifdef LL_USART_STOPBITS_1_5 case UART_CFG_STOP_BITS_1_5: -#if HAS_LPUART_1 +#if HAS_LPUART if (IS_LPUART_INSTANCE(config->usart)) { /* return the default */ return LL_USART_STOPBITS_2; From ec273d1357e3c39ee55c2a4eddbc185beeb14cb4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 17 Oct 2023 14:00:08 +0200 Subject: [PATCH 2027/4498] twister: Fix description of relationship between filter and allow/exclude The current description of the relationship between the tests filter and the arch/platform allow/exclude was actually incorrect. Let's fix it. Signed-off-by: Alberto Escolar Piedras --- scripts/twister | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/twister b/scripts/twister index f41349871ed..c66b81d84e1 100755 --- a/scripts/twister +++ b/scripts/twister @@ -142,15 +142,6 @@ pairs: not (right associative) all comparison operators (non-associative) - arch_allow, arch_exclude, platform_allow, platform_exclude - are all syntactic sugar for these expressions. For instance - - arch_exclude = x86 arc - - Is the same as: - - filter = not ARCH in ["x86", "arc"] - The ':' operator compiles the string argument as a regular expression, and then returns a true value only if the symbol's value in the environment matches. For example, if CONFIG_SOC="stm32f107xc" then @@ -159,6 +150,22 @@ pairs: Would match it. + Note that arch_allow, arch_exclude, platform_allow, platform_exclude + are not just syntactic sugar for filter expressions. For instance + + arch_exclude = x86 arc + + Can appear at first glance to have a similar effect to + + filter = not ARCH in ["x86", "arc"] + + but unlike "filter", these cause platforms to be filtered already during the testplan + generation. While "filter" does not exclue platforms at the testplan generation, and instead + relies on the result of running the build configuration stage. That is, to evaluate the filter + expression, cmake is run for that target, and then the filter evaluated as a gate for the + build and run steps. + Therefore filtering by using {platform|arch}_{exclude|allow} is much faster. + The set of test cases that actually run depends on directives in the testsuite files and options passed in on the command line. If there is any confusion, running with -v or examining the test plan report (testplan.json) From a34fd9970db7e57200b5048c0ffc57c4637d503b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 16 Oct 2023 20:25:10 -0400 Subject: [PATCH 2028/4498] doc: README: remove mention of nightly builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit removed stale mention of nightly builds Signed-off-by: Benjamin Cabé --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index 9770417087d..c22d25212c7 100644 --- a/README.rst +++ b/README.rst @@ -66,8 +66,6 @@ Here's a quick summary of resources to help you find your way around: respectively. You can join the developer's list and search its archives at `Zephyr Development mailing list`_. The other `Zephyr mailing list subgroups`_ have their own archives and sign-up pages. -* **Nightly CI Build Status**: https://lists.zephyrproject.org/g/builds - The builds@lists.zephyrproject.org mailing list archives the CI nightly build results. * **Chat**: Real-time chat happens in Zephyr's Discord Server. Use this `Discord Invite`_ to register. * **Contributing**: see the `Contribution Guide`_ From a32d035fd68f42e91fc015ac853f18fad47c7878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 16 Oct 2023 20:33:24 -0400 Subject: [PATCH 2029/4498] doc: README: Rework Resources section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With close to 20 different links, the Resources section was not really easy to navigate, defeating the purpose of providing quick access to information. Reworked the section to break it down into sub sections, and reworded the links to make them self explanatory. Each sub-section has been re-ordered so that most important links appear first. Signed-off-by: Benjamin Cabé --- README.rst | 90 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/README.rst b/README.rst index c22d25212c7..45a3998194d 100644 --- a/README.rst +++ b/README.rst @@ -54,37 +54,59 @@ Resources Here's a quick summary of resources to help you find your way around: -* **Help**: `Asking for Help Tips`_ -* **Documentation**: http://docs.zephyrproject.org (`Getting Started Guide`_) -* **Source Code**: https://github.com/zephyrproject-rtos/zephyr is the main - repository; https://elixir.bootlin.com/zephyr/latest/source contains a - searchable index -* **Releases**: https://github.com/zephyrproject-rtos/zephyr/releases -* **Samples and example code**: see `Sample and Demo Code Examples`_ -* **Mailing Lists**: users@lists.zephyrproject.org and - devel@lists.zephyrproject.org are the main user and developer mailing lists, - respectively. You can join the developer's list and search its archives at - `Zephyr Development mailing list`_. The other `Zephyr mailing list - subgroups`_ have their own archives and sign-up pages. -* **Chat**: Real-time chat happens in Zephyr's Discord Server. Use - this `Discord Invite`_ to register. -* **Contributing**: see the `Contribution Guide`_ -* **Wiki**: `Zephyr GitHub wiki`_ -* **Issues**: https://github.com/zephyrproject-rtos/zephyr/issues -* **Security Issues**: Email vulnerabilities@zephyrproject.org to report - security issues; also see our `Security`_ documentation. Security issues are - tracked separately at https://zephyrprojectsec.atlassian.net. -* **Zephyr Project Website**: https://zephyrproject.org - -.. _Discord Invite: https://chat.zephyrproject.org -.. _supported boards: http://docs.zephyrproject.org/latest/boards/index.html -.. _Zephyr Documentation: http://docs.zephyrproject.org -.. _Introduction to Zephyr: http://docs.zephyrproject.org/latest/introduction/index.html -.. _Getting Started Guide: http://docs.zephyrproject.org/latest/develop/getting_started/index.html -.. _Contribution Guide: http://docs.zephyrproject.org/latest/contribute/index.html -.. _Zephyr GitHub wiki: https://github.com/zephyrproject-rtos/zephyr/wiki -.. _Zephyr Development mailing list: https://lists.zephyrproject.org/g/devel -.. _Zephyr mailing list subgroups: https://lists.zephyrproject.org/g/main/subgroups -.. _Sample and Demo Code Examples: http://docs.zephyrproject.org/latest/samples/index.html -.. _Security: http://docs.zephyrproject.org/latest/security/index.html -.. _Asking for Help Tips: https://docs.zephyrproject.org/latest/develop/getting_started/index.html#asking-for-help +Getting Started +--------------- + + | 📖 `Zephyr Documentation`_ + | 🚀 `Getting Started Guide`_ + | 🙋🏽 `Tips when asking for help`_ + | 💻 `Code samples`_ + +Code and Development +-------------------- + + | 🌐 `Source Code Repository`_ + | 📦 `Releases`_ + | 🤝 `Contribution Guide`_ + +Community and Support +--------------------- + + | 💬 `Discord Server`_ for real-time community discussions + | 📧 `User mailing list (users@lists.zephyrproject.org)`_ + | 📧 `Developer mailing list (devel@lists.zephyrproject.org)`_ + | 📬 `Other project mailing lists`_ + | 📚 `Project Wiki`_ + +Issue Tracking and Security +--------------------------- + + | 🐛 `GitHub Issues`_ + | 🔒 `Security documentation`_ + | 🛡️ `Security Advisories Repository`_ + | ⚠️ Report security vulnerabilities at vulnerabilities@zephyrproject.org + +Additional Resources +-------------------- + | 🌐 `Zephyr Project Website`_ + | 📺 `Zephyr Tech Talks`_ + +.. _Zephyr Project Website: https://www.zephyrproject.org +.. _Discord Server: https://chat.zephyrproject.org +.. _supported boards: https://docs.zephyrproject.org/latest/boards/index.html +.. _Zephyr Documentation: https://docs.zephyrproject.org +.. _Introduction to Zephyr: https://docs.zephyrproject.org/latest/introduction/index.html +.. _Getting Started Guide: https://docs.zephyrproject.org/latest/develop/getting_started/index.html +.. _Contribution Guide: https://docs.zephyrproject.org/latest/contribute/index.html +.. _Source Code Repository: https://github.com/zephyrproject-rtos/zephyr +.. _GitHub Issues: https://github.com/zephyrproject-rtos/zephyr/issues +.. _Releases: https://github.com/zephyrproject-rtos/zephyr/releases +.. _Project Wiki: https://github.com/zephyrproject-rtos/zephyr/wiki +.. _User mailing list (users@lists.zephyrproject.org): https://lists.zephyrproject.org/g/users +.. _Developer mailing list (devel@lists.zephyrproject.org): https://lists.zephyrproject.org/g/devel +.. _Other project mailing lists: https://lists.zephyrproject.org/g/main/subgroups +.. _Code samples: https://docs.zephyrproject.org/latest/samples/index.html +.. _Security documentation: https://docs.zephyrproject.org/latest/security/index.html +.. _Security Advisories Repository: https://github.com/zephyrproject-rtos/zephyr/security +.. _Tips when asking for help: https://docs.zephyrproject.org/latest/develop/getting_started/index.html#asking-for-help +.. _Zephyr Tech Talks: https://www.zephyrproject.org/tech-talks From 54f51cbcb3fc670a54af21c384d20e6db5d04f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 08:09:05 -0400 Subject: [PATCH 2030/4498] doc: intro: fix improper definition list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add missing blank line to not have the sentence render as a definition list. Signed-off-by: Benjamin Cabé --- doc/introduction/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index 918801fc7d4..d83a778e526 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -9,6 +9,7 @@ sensors and LED wearables to sophisticated embedded controllers, smart watches, and IoT wireless applications. The Zephyr kernel supports multiple architectures, including: + - ARCv2 (EM and HS) and ARCv3 (HS6X) - ARMv6-M, ARMv7-M, and ARMv8-M (Cortex-M) - ARMv7-A and ARMv8-A (Cortex-A, 32- and 64-bit) From 6e39775e5b465940e0e9ce7f68a233d97ba32225 Mon Sep 17 00:00:00 2001 From: Piotr Wojnarowski Date: Tue, 17 Oct 2023 13:34:37 +0200 Subject: [PATCH 2031/4498] doc: riscv: rv32m1_vega: Restore reset button image This image was accidentally shrunk too much in e81e92dbb9092a3d67ec7e17f0c2190239635a50. Restore the previous version. Fixes #64021 Signed-off-by: Piotr Wojnarowski --- boards/riscv/rv32m1_vega/doc/ri5cy_boot.jpg | Bin 321 -> 35861 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/boards/riscv/rv32m1_vega/doc/ri5cy_boot.jpg b/boards/riscv/rv32m1_vega/doc/ri5cy_boot.jpg index 6483f98642f6f49afe57436d52ae81420026fddd..f119572c517a376d5e1fd02f17a13b3095d3381c 100644 GIT binary patch literal 35861 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 YyD5#Xo8B02`v5@!@IZVxANF7W*%dOAR{#J2 literal 321 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<$bZOynFS~;Dagpc#EdKq Date: Mon, 16 Oct 2023 09:55:53 +0200 Subject: [PATCH 2032/4498] bsim: Bluetooth: mesh: fix model extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 'test_access.c', model 3 on element 1 extending model 3 on element 0 is now registered correctly. When calling 'bt_mesh_model_extend' on models on different elements, this needs to called from the model with the highest element index to be registered correctly. Signed-off-by: Håvard Reierstad --- tests/bsim/bluetooth/mesh/src/test_access.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index 56fce393388..9bddf0e8058 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -261,8 +261,8 @@ static int model3_init(struct bt_mesh_model *model) ASSERT_OK(bt_mesh_model_extend(model, model - 2)); ASSERT_OK(bt_mesh_model_extend(model, model - 1)); - if (model->elem_idx == 0) { - ASSERT_OK(bt_mesh_model_extend(&models_ne[2], model)); + if (model->elem_idx == 1) { + ASSERT_OK(bt_mesh_model_extend(model, &models[4])); } return 0; From 0ec6f184342777bc3df238ae172362f11b0c8eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Mon, 16 Oct 2023 14:24:15 +0200 Subject: [PATCH 2033/4498] Bluetooth: mesh: update model extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specifies that if Composition Data Page 1 is enabled, the models passed to 'bt_mesh_model_extend' needs to be initialized prior to the call. This is to ensure that the composition data is registered correctly. Signed-off-by: Håvard Reierstad --- include/zephyr/bluetooth/mesh/access.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 2db8a55e986..5272abe5645 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -1070,6 +1070,10 @@ void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod); * extension list and element, giving the models extended subscription list * capacity. * + * If @kconfig{CONFIG_BT_MESH_COMP_PAGE_1} is enabled, it is not allowed to call + * this function before the @ref bt_mesh_model_cb.init callback is called + * for both models, except if it is called as part of the final callback. + * * @param extending_mod Mesh model that is extending the base model. * @param base_mod The model being extended. * From 0269170420c2de4f1a4479f3da9a727914d124c8 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Tue, 17 Oct 2023 09:33:38 +0200 Subject: [PATCH 2034/4498] drivers: ieee802154: b91: buflen sanity check Introduces a (currently redundant) buffer length sanity check to prepare for L2s that support PHYs with PHY payloads > 127 bytes. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_b91.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 3c47c56fc9a..0557c533944 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -173,19 +173,26 @@ static void b91_update_rssi_and_lqi(struct net_pkt *pkt) } /* Prepare TX buffer */ -static void b91_set_tx_payload(uint8_t *payload, uint8_t payload_len) +static int b91_set_tx_payload(uint8_t *payload, uint8_t payload_len) { unsigned char rf_data_len; unsigned int rf_tx_dma_len; + /* See Telink SDK Dev Handbook, AN-21010600, section 21.5.2.2. */ + if (payload_len > (B91_TRX_LENGTH - B91_PAYLOAD_OFFSET - IEEE802154_FCS_LENGTH)) { + return -EINVAL; + } + rf_data_len = payload_len + 1; rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); data.tx_buffer[0] = rf_tx_dma_len & 0xff; data.tx_buffer[1] = (rf_tx_dma_len >> 8) & 0xff; data.tx_buffer[2] = (rf_tx_dma_len >> 16) & 0xff; data.tx_buffer[3] = (rf_tx_dma_len >> 24) & 0xff; - data.tx_buffer[4] = payload_len + 2; + data.tx_buffer[4] = payload_len + IEEE802154_FCS_LENGTH; memcpy(data.tx_buffer + B91_PAYLOAD_OFFSET, payload, payload_len); + + return 0; } /* Enable ack handler */ @@ -243,7 +250,10 @@ static void b91_send_ack(uint8_t seq_num) { uint8_t ack_buf[] = { B91_ACK_TYPE, 0, seq_num }; - b91_set_tx_payload(ack_buf, sizeof(ack_buf)); + if (b91_set_tx_payload(ack_buf, sizeof(ack_buf))) { + return; + } + rf_set_txmode(); delay_us(CONFIG_IEEE802154_B91_SET_TXRX_DELAY_US); rf_tx_pkt(data.tx_buffer); @@ -534,7 +544,10 @@ static int b91_tx(const struct device *dev, } /* prepare tx buffer */ - b91_set_tx_payload(frag->data, frag->len); + status = b91_set_tx_payload(frag->data, frag->len); + if (status) { + return status; + } /* reset semaphores */ k_sem_reset(&b91->tx_wait); From f3cbd27e5a7930cb963233bfc03637fe79e09b8a Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Tue, 17 Oct 2023 09:37:20 +0200 Subject: [PATCH 2035/4498] drivers: ieee802154: cc13xx_cc26xx_subg: buflen sanity check Introduces a (currently redundant) buffer length sanity check to prepare for L2s that support PHYs with PHY payloads > 127 bytes. Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index b5cc9b36176..780700aac4f 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -673,6 +673,10 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, RF_EventMask events; int ret = 0; + if (buf->len > (CC13XX_CC26XX_TX_BUF_SIZE - IEEE802154_PHY_SUN_FSK_PHR_LEN)) { + return -EINVAL; + } + if (mode != IEEE802154_TX_MODE_DIRECT) { /* For backwards compatibility we only log an error but do not bail. */ NET_ERR("TX mode %d not supported - sending directly instead.", mode); @@ -698,9 +702,10 @@ static int ieee802154_cc13xx_cc26xx_subg_tx(const struct device *dev, /* Complete the SUN FSK PHY header, see IEEE 802.15.4, section 19.2.4. */ drv_data->tx_data[0] = buf->len + IEEE802154_FCS_LENGTH; - /* Set TX data */ - __ASSERT_NO_MSG(buf->len + IEEE802154_PHY_SUN_FSK_PHR_LEN <= CC13XX_CC26XX_TX_BUF_SIZE); - /* TODO: Zero-copy TX, see discussion in #49775. */ + /* Set TX data + * + * TODO: Zero-copy TX, see discussion in #49775. + */ memcpy(&drv_data->tx_data[IEEE802154_PHY_SUN_FSK_PHR_LEN], buf->data, buf->len); drv_data->cmd_prop_tx_adv.pktLen = buf->len + IEEE802154_PHY_SUN_FSK_PHR_LEN; From dbfd1971d8a5cd628f7e2fdb50d562dd0e7d90e4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 16 Oct 2023 12:49:18 -0700 Subject: [PATCH 2036/4498] doc: release: Add power management relnotes for 3.5 Add relevant power management notes for 3.5 release. Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 17ebc99b46c..688cdf72624 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -926,6 +926,15 @@ Libraries / Subsystems statuses (enabled/disabled) programmatically. With the API, developers can create observers initially disabled and enable them in runtime. +* Power management + + * Added :kconfig:option:`CONFIG_PM_NEED_ALL_DEVICES_IDLE`. When this + option is set the power management will keep the system active + if there is any device busy. + * :c:func:`pm_device_runtime_get` can be called from ISR now. + * Power states can be disabled directly in devicetree doing ``status = "disabled";`` + * Added the helper function, :c:func:`pm_device_driver_init`, for + initializing devices into a specific power state. HALs **** From 4b930e888d9ebdcc73cdbd01fa2bfd4881a3b444 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 16 Oct 2023 12:55:45 -0700 Subject: [PATCH 2037/4498] doc: migration-guide-3.5: Power management update Add information about power management required changes. Signed-off-by: Flavio Ceolin --- doc/releases/migration-guide-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 41b3f4eb4bb..74bc58b8ba0 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -289,6 +289,9 @@ Required changes instead use the new driver Kconfig :kconfig:option:`CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED`. +* :c:func:`pm_state_set` and :c:func:`pm_exit_post_ops` are mandatory now + for any platform supporting power management. + Recommended Changes ******************* From fb1af7785c21a8a8d786217caf3f89e7934279b7 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 17 Oct 2023 09:34:09 +0000 Subject: [PATCH 2038/4498] submanifests: optional: update CHRE revision Update CHRE revision to include a linker setup fix. Signed-off-by: Fabio Baltieri --- submanifests/optional.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index ef40d0201fb..e69781bdfb2 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -4,7 +4,7 @@ manifest: url-base: https://github.com/zephyrproject-rtos projects: - name: chre - revision: b7955c27e50485b7dafdc3888d7d6afdc2ac6d96 + revision: 3b32c76efee705af146124fb4190f71be5a4e36e path: modules/lib/chre remote: upstream groups: From b43d0ed2eebe8c6f3f275d7fd4a33878d930633c Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 10 Oct 2023 16:11:51 -0400 Subject: [PATCH 2039/4498] tests: Update app_kernel README Removes stale information from the app_kernel benchmark's README.txt file. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/README.txt | 42 ++------------------------ 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/tests/benchmarks/app_kernel/README.txt b/tests/benchmarks/app_kernel/README.txt index 42423891a2f..e4057c87de6 100644 --- a/tests/benchmarks/app_kernel/README.txt +++ b/tests/benchmarks/app_kernel/README.txt @@ -1,31 +1,9 @@ -Title: Microkernel Object Performance +Title: Kernel Object Performance Description: -AppKernel is used to measure the performance of microkernel events, mutexes, -semaphores, FIFOs, mailboxes, pipes, memory maps, and memory pools. - --------------------------------------------------------------------------------- - -Building and Running Project: - -This project outputs to the console. It can be built and executed -on QEMU as follows: - - make run - --------------------------------------------------------------------------------- - -Troubleshooting: - -Problems caused by out-dated project information can be addressed by -issuing one of the following commands then rebuilding the project: - - make clean # discard results of previous builds - # but keep existing configuration info -or - make pristine # discard results of previous builds - # and restore pre-defined configuration info +The app_kernel test is used to measure the performance of the following +kernel objects: message queues, semaphores, memory slabs, mailboxes and pipes. -------------------------------------------------------------------------------- @@ -45,25 +23,11 @@ Sample Output: | signal semaphore | NNNNNN| | signal to waiting high pri task | NNNNNN| | signal to waiting high pri task, with timeout | NNNNNN| -| signal to waitm (2) | NNNNNN| -| signal to waitm (2), with timeout | NNNNNN| -| signal to waitm (3) | NNNNNN| -| signal to waitm (3), with timeout | NNNNNNN| -| signal to waitm (4) | NNNNNNN| -| signal to waitm (4), with timeout | NNNNNNN| |-----------------------------------------------------------------------------| | average lock and unlock mutex | NNNNNN| |-----------------------------------------------------------------------------| | average alloc and dealloc memory page | NNNNNN| |-----------------------------------------------------------------------------| -| average alloc and dealloc memory pool block | NNNNNN| -|-----------------------------------------------------------------------------| -| Signal enabled event | NNNNNN| -| Signal event & Test event | NNNNNN| -| Signal event & TestW event | NNNNNN| -| Signal event with installed handler | -| Handler responds OK | -|-----------------------------------------------------------------------------| | M A I L B O X M E A S U R E M E N T S | |-----------------------------------------------------------------------------| | Send mailbox message to waiting high priority task and wait | From 36defb42871e2bcb59505e27509ea93eaf74c913 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 10 Oct 2023 16:31:48 -0400 Subject: [PATCH 2040/4498] tests: Update sys_kernel benchmark This updates the sys_kernel benchmark project to replace references to the defunct TICKS_NONE symbol with K_NO_WAIT. It also removes the outdated build instructions from the README. Signed-off-by: Peter Mitsis --- tests/benchmarks/sys_kernel/README.txt | 33 ++++-------------------- tests/benchmarks/sys_kernel/src/lifo.c | 2 +- tests/benchmarks/sys_kernel/src/mwfifo.c | 2 +- tests/benchmarks/sys_kernel/src/sema.c | 2 +- 4 files changed, 8 insertions(+), 31 deletions(-) diff --git a/tests/benchmarks/sys_kernel/README.txt b/tests/benchmarks/sys_kernel/README.txt index 086887d4675..5579acd2720 100644 --- a/tests/benchmarks/sys_kernel/README.txt +++ b/tests/benchmarks/sys_kernel/README.txt @@ -7,34 +7,12 @@ lifo, fifo, stack and memslab objects. -------------------------------------------------------------------------------- -Building and Running Project: - -This project outputs to the console. It can be built and executed -on QEMU as follows: - - make run - --------------------------------------------------------------------------------- - -Troubleshooting: - -Problems caused by out-dated project information can be addressed by -issuing one of the following commands then rebuilding the project: - - make clean # discard results of previous builds - # but keep existing configuration info -or - make pristine # discard results of previous builds - # and restore pre-defined configuration info - --------------------------------------------------------------------------------- - Sample Output: MODULE: kernel API test -KERNEL VERSION: 0x1066300 +KERNEL VERSION: 0xXXYYZZZZ -Each test below is repeated 5000 times; +Each test below is repeated 10 times; average time for one iteration is displayed. TEST CASE: Semaphore #1 @@ -50,7 +28,7 @@ END TEST CASE TEST CASE: Semaphore #2 TEST COVERAGE: k_sem_init - k_sem_take(TICKS_NONE) + k_sem_take(K_NO_WAIT) k_yield k_sem_give Starting test. Please wait... @@ -84,7 +62,7 @@ TEST CASE: LIFO #2 TEST COVERAGE: k_lifo_init k_lifo_get(K_FOREVER) - k_lifo_get(TICKS_NONE) + k_lifo_get(K_NO_WAIT) k_lifo_put k_yield Starting test. Please wait... @@ -118,7 +96,7 @@ TEST CASE: FIFO #2 TEST COVERAGE: k_fifo_init k_fifo_get(K_FOREVER) - k_fifo_get(TICKS_NONE) + k_fifo_get(K_NO_WAIT) k_fifo_put k_yield Starting test. Please wait... @@ -189,4 +167,3 @@ DETAILS: Average time for 1 iteration: NNNN nSec END TEST CASE PROJECT EXECUTION SUCCESSFUL -QEMU: Terminated diff --git a/tests/benchmarks/sys_kernel/src/lifo.c b/tests/benchmarks/sys_kernel/src/lifo.c index 2d7d6497648..bc076a77055 100644 --- a/tests/benchmarks/sys_kernel/src/lifo.c +++ b/tests/benchmarks/sys_kernel/src/lifo.c @@ -177,7 +177,7 @@ int lifo_test(void) fprintf(output_file, sz_description, "\n\tk_lifo_init" "\n\tk_lifo_get(K_FOREVER)" - "\n\tk_lifo_get(TICKS_NONE)" + "\n\tk_lifo_get(K_NO_WAIT)" "\n\tk_lifo_put" "\n\tk_yield"); printf(sz_test_start_fmt); diff --git a/tests/benchmarks/sys_kernel/src/mwfifo.c b/tests/benchmarks/sys_kernel/src/mwfifo.c index 25e1969baa2..bd0fbe04019 100644 --- a/tests/benchmarks/sys_kernel/src/mwfifo.c +++ b/tests/benchmarks/sys_kernel/src/mwfifo.c @@ -177,7 +177,7 @@ int fifo_test(void) fprintf(output_file, sz_description, "\n\tk_fifo_init" "\n\tk_fifo_get(K_FOREVER)" - "\n\tk_fifo_get(TICKS_NONE)" + "\n\tk_fifo_get(K_NO_WAIT)" "\n\tk_fifo_put" "\n\tk_yield"); printf(sz_test_start_fmt); diff --git a/tests/benchmarks/sys_kernel/src/sema.c b/tests/benchmarks/sys_kernel/src/sema.c index e6d08735c30..ac01068d94f 100644 --- a/tests/benchmarks/sys_kernel/src/sema.c +++ b/tests/benchmarks/sys_kernel/src/sema.c @@ -137,7 +137,7 @@ int sema_test(void) "Semaphore #2"); fprintf(output_file, sz_description, "\n\tk_sem_init" - "\n\tk_sem_take(TICKS_NONE)" + "\n\tk_sem_take(K_NO_WAIT)" "\n\tk_yield" "\n\tk_sem_give"); printf(sz_test_start_fmt); From 32918ddd928e556859816a2b2eaa317c5b106aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 10:29:14 -0400 Subject: [PATCH 2041/4498] doc: Fix broken references to Kconfig options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a few occurrences of incorrect references to Kconfig options (missing the CONFIG_ prefix) Signed-off-by: Benjamin Cabé --- doc/connectivity/bluetooth/api/mesh/shell.rst | 18 +++++++++--------- doc/kernel/services/interrupts.rst | 2 +- doc/services/shell/index.rst | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 2522cd9f38b..66bfcdf6168 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -344,7 +344,7 @@ and :kconfig:option:`CONFIG_BT_MESH_PB_GATT_CLIENT` configuration options must b Get or set the mesh node's UUID, used in the unprovisioned beacons. - * ``UUID``: If present, new 128-bit UUID value. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. If omitted, the current UUID will be printed. To enable this command, the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. + * ``UUID``: If present, new 128-bit UUID value. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. If omitted, the current UUID will be printed. To enable this command, the :kconfig:option:`CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. ``mesh prov input-num `` @@ -373,7 +373,7 @@ and :kconfig:option:`CONFIG_BT_MESH_PB_GATT_CLIENT` configuration options must b Set or clear the static OOB authentication value. The static OOB authentication value must be set before provisioning starts to have any effect. The static OOB value must be same on both participants in the provisioning. To enable this command, the - :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. + :kconfig:option:`CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. * ``Val``: If present, indicates the new hexadecimal value of the static OOB. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. If omitted, the static OOB value is cleared. @@ -394,7 +394,7 @@ and :kconfig:option:`CONFIG_BT_MESH_PB_GATT_CLIENT` configuration options must b Enable or disable printing of incoming unprovisioned beacons. Allows a provisioner device to detect nearby unprovisioned devices and provision them. To enable this command, the - :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. + :kconfig:option:`CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. * ``Val``: Whether to enable the unprovisioned beacon printing. @@ -499,16 +499,16 @@ enabled, and as long as the Configuration Client model is present in the model c application. This shell module can be used for configuring itself and other nodes in the mesh network. -The Configuration Client uses general message parameters set by ``mesh target dst`` and -``mesh target net`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, -given that the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option is enabled with the shell +The Configuration Client uses general message parameters set by ``mesh target dst`` and ``mesh +target net`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, given that +the :kconfig:option:`CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE` option is enabled with the shell provisioning context initialized, the Configuration Client model targets itself by default. Similarly, when another node has been provisioned by the Bluetooth mesh shell, the Configuration Client model targets the new node. In most common use-cases, the Configuration Client is depending on the provisioning features and the Configuration database to be fully functional. The -Configuration Client always sends messages using the Device key bound to the destination address, -so it will only be able to configure itself and the mesh nodes it provisioned. The following steps -are an example of how you can set up a device to start using the Configuration Client commands: +Configuration Client always sends messages using the Device key bound to the destination address, so +it will only be able to configure itself and the mesh nodes it provisioned. The following steps are +an example of how you can set up a device to start using the Configuration Client commands: * Initialize the client node (``mesh init``). * Create the CDB (``mesh cdb create``). diff --git a/doc/kernel/services/interrupts.rst b/doc/kernel/services/interrupts.rst index b940540e600..849e614a562 100644 --- a/doc/kernel/services/interrupts.rst +++ b/doc/kernel/services/interrupts.rst @@ -233,7 +233,7 @@ become shared, meaning the two ISR/argument pairs (previous one and the one that has just been registered) will be invoked each time the interrupt is triggered. The entities that make use of an interrupt line in the shared interrupt context are known as clients. The maximum number of allowed clients for an interrupt is -controlled by :kconfig:option:`SHARED_IRQ_MAX_NUM_CLIENTS`. +controlled by :kconfig:option:`CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS`. Interrupt sharing is transparent to the user. As such, the user may register interrupts using :c:macro:`IRQ_CONNECT` and :c:func:`irq_connect_dynamic` as diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 6ce250f563a..15213954200 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -634,21 +634,21 @@ backend and the Log RTT backend does not work by default, because both default to channel ``0``. There are two options: 1. The Shell buffer can use an alternate channel, for example using -:kconfig:option:`SHELL_BACKEND_RTT_BUFFER` set to ``1``. +:kconfig:option:`CONFIG_SHELL_BACKEND_RTT_BUFFER` set to ``1``. This allows monitoring the log using `JLinkRTTViewer `_ while a script interfaces over channel 1. 2. The Log buffer can use an alternate channel, for example using -:kconfig:option:`LOG_BACKEND_RTT_BUFFER` set to ``1``. +:kconfig:option:`CONFIG_LOG_BACKEND_RTT_BUFFER` set to ``1``. This allows interactive use of the shell through JLinkRTTViewer, while the log is written to file. .. warning:: Regardless of the channel selection, the RTT log backend must be explicitly - enabled using :kconfig:option:`LOG_BACKEND_RTT` set to ``y``, because it + enabled using :kconfig:option:`CONFIG_LOG_BACKEND_RTT` set to ``y``, because it defaults to ``n`` when the Shell RTT backend is also enabled using - :kconfig:option:`SHELL_BACKEND_RTT` being set to ``y``. + :kconfig:option:`CONFIG_SHELL_BACKEND_RTT` being set to ``y``. Usage ***** From cc03017b13384facde1e9995835d43e2cf585d0e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 14 Oct 2023 16:21:38 +0200 Subject: [PATCH 2042/4498] doc: _doxygen: define modem group Add @defgroup for modem APIs Signed-off-by: Bjarki Arge Andreasen --- doc/_doxygen/groups.dox | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/_doxygen/groups.dox b/doc/_doxygen/groups.dox index dbb67e7e694..7aca51503db 100644 --- a/doc/_doxygen/groups.dox +++ b/doc/_doxygen/groups.dox @@ -60,4 +60,9 @@ @{ @} +@brief Modem APIs +@defgroup modem Modem APIs +@{ +@} + */ From a7564220cf04b869aeca3211f96dc3a343066711 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 14 Oct 2023 16:22:36 +0200 Subject: [PATCH 2043/4498] modem: modem_cmux: Update documentation This commit updates the documentation for the modem_cmux modem module. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/cmux.h | 56 +++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/include/zephyr/modem/cmux.h b/include/zephyr/modem/cmux.h index b64c00b9927..4562cb544d9 100644 --- a/include/zephyr/modem/cmux.h +++ b/include/zephyr/modem/cmux.h @@ -33,14 +33,14 @@ extern "C" { #endif -struct modem_cmux; +/** + * @brief Modem CMUX + * @defgroup modem_cmux Modem CMUX + * @ingroup modem + * @{ + */ -enum modem_cmux_state { - MODEM_CMUX_STATE_DISCONNECTED = 0, - MODEM_CMUX_STATE_CONNECTING, - MODEM_CMUX_STATE_CONNECTED, - MODEM_CMUX_STATE_DISCONNECTING, -}; +struct modem_cmux; enum modem_cmux_event { MODEM_CMUX_EVENT_CONNECTED = 0, @@ -50,6 +50,17 @@ enum modem_cmux_event { typedef void (*modem_cmux_callback)(struct modem_cmux *cmux, enum modem_cmux_event event, void *user_data); +/** + * @cond INTERNAL_HIDDEN + */ + +enum modem_cmux_state { + MODEM_CMUX_STATE_DISCONNECTED = 0, + MODEM_CMUX_STATE_CONNECTING, + MODEM_CMUX_STATE_CONNECTED, + MODEM_CMUX_STATE_DISCONNECTING, +}; + enum modem_cmux_receive_state { MODEM_CMUX_RECEIVE_STATE_SOF = 0, MODEM_CMUX_RECEIVE_STATE_RESYNC_0, @@ -74,11 +85,6 @@ enum modem_cmux_dlci_state { MODEM_CMUX_DLCI_STATE_CLOSING, }; -enum modem_cmux_dlci_event { - MODEM_CMUX_DLCI_EVENT_OPENED, - MODEM_CMUX_DLCI_EVENT_CLOSED, -}; - struct modem_cmux_dlci { sys_snode_t node; @@ -157,6 +163,10 @@ struct modem_cmux { struct k_event event; }; +/** + * @endcond + */ + /** * @brief Contains CMUX instance configuration data */ @@ -205,7 +215,7 @@ struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cm const struct modem_cmux_dlci_config *config); /** - * @brief Initialize CMUX instance + * @brief Attach CMUX instance to pipe * * @param cmux CMUX instance * @param pipe Pipe instance to attach CMUX instance to @@ -243,7 +253,8 @@ int modem_cmux_connect_async(struct modem_cmux *cmux); * * @param cmux CMUX instance * - * @note When disconnected, the bus pipe can be used directly again + * @note The bus pipe must be released using modem_cmux_release() after disconnecting + * before being reused. */ int modem_cmux_disconnect(struct modem_cmux *cmux); @@ -254,12 +265,27 @@ int modem_cmux_disconnect(struct modem_cmux *cmux); * * @param cmux CMUX instance * - * @note When disconnected, the bus pipe can be used directly again + * @note The bus pipe must be released using modem_cmux_release() after disconnecting + * before being reused. */ int modem_cmux_disconnect_async(struct modem_cmux *cmux); +/** + * @brief Release CMUX instance from pipe + * + * @details Releases the pipe and hard resets the CMUX instance internally. CMUX should + * be disconnected using modem_cmux_disconnect(). + * + * @param cmux CMUX instance + * + * @note The bus pipe can be used directly again after CMUX instance is released. + */ void modem_cmux_release(struct modem_cmux *cmux); +/** + * @} + */ + #ifdef __cplusplus } #endif From 125ae5343114add0ec85f0a9a7c15f0cae336eb7 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 14 Oct 2023 16:23:35 +0200 Subject: [PATCH 2044/4498] modem: modem_pipe: Update documentation This commit updates the documentation for the modem_pipe modem module. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/pipe.h | 54 ++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/include/zephyr/modem/pipe.h b/include/zephyr/modem/pipe.h index 124af5d4269..abf8d74918e 100644 --- a/include/zephyr/modem/pipe.h +++ b/include/zephyr/modem/pipe.h @@ -14,8 +14,37 @@ extern "C" { #endif +/** + * @brief Modem Pipe + * @defgroup modem_pipe Modem Pipe + * @ingroup modem + * @{ + */ + +/** Modem pipe event */ +enum modem_pipe_event { + MODEM_PIPE_EVENT_OPENED = 0, + MODEM_PIPE_EVENT_RECEIVE_READY, + MODEM_PIPE_EVENT_CLOSED, +}; + +/** + * @cond INTERNAL_HIDDEN + */ + struct modem_pipe; +/** + * @endcond + */ + +typedef void (*modem_pipe_api_callback)(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data); + +/** + * @cond INTERNAL_HIDDEN + */ + typedef int (*modem_pipe_api_open)(void *data); typedef int (*modem_pipe_api_transmit)(void *data, const uint8_t *buf, size_t size); @@ -36,15 +65,6 @@ enum modem_pipe_state { MODEM_PIPE_STATE_OPEN, }; -enum modem_pipe_event { - MODEM_PIPE_EVENT_OPENED = 0, - MODEM_PIPE_EVENT_RECEIVE_READY, - MODEM_PIPE_EVENT_CLOSED, -}; - -typedef void (*modem_pipe_api_callback)(struct modem_pipe *pipe, enum modem_pipe_event event, - void *user_data); - struct modem_pipe { void *data; struct modem_pipe_api *api; @@ -65,6 +85,10 @@ struct modem_pipe { */ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api *api); +/** + * @endcond + */ + /** * @brief Open pipe * @@ -158,6 +182,10 @@ int modem_pipe_close(struct modem_pipe *pipe); */ int modem_pipe_close_async(struct modem_pipe *pipe); +/** + * @cond INTERNAL_HIDDEN + */ + /** * @brief Notify user of pipe that it has opened * @@ -185,6 +213,14 @@ void modem_pipe_notify_closed(struct modem_pipe *pipe); */ void modem_pipe_notify_receive_ready(struct modem_pipe *pipe); +/** + * @endcond + */ + +/** + * @} + */ + #ifdef __cplusplus } #endif From 9123559961c5b6e485ea54f570eb3658715ffad2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 14 Oct 2023 16:24:09 +0200 Subject: [PATCH 2045/4498] modem: modem_ppp: Update documentation This commit updates the documentation for the modem_ppp modem module. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/ppp.h | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/include/zephyr/modem/ppp.h b/include/zephyr/modem/ppp.h index 5d6d485e308..c0eca885fcd 100644 --- a/include/zephyr/modem/ppp.h +++ b/include/zephyr/modem/ppp.h @@ -20,6 +20,20 @@ extern "C" { #endif +/** + * @brief Modem PPP + * @defgroup modem_ppp Modem PPP + * @ingroup modem + * @{ + */ + +/** L2 network interface init callback */ +typedef void (*modem_ppp_init_iface)(struct net_if *iface); + +/** + * @cond INTERNAL_HIDDEN + */ + enum modem_ppp_receive_state { /* Searching for start of frame and header */ MODEM_PPP_RECEIVE_STATE_HDR_SOF = 0, @@ -57,8 +71,6 @@ enum modem_ppp_transmit_state { MODEM_PPP_TRANSMIT_STATE_EOF, }; -typedef void (*modem_ppp_init_iface)(struct net_if *iface); - struct modem_ppp { /* Network interface instance is bound to */ struct net_if *iface; @@ -103,6 +115,10 @@ struct modem_ppp { #endif }; +/** + * @endcond + */ + /** * @brief Attach pipe to instance and connect * @@ -126,6 +142,10 @@ struct net_if *modem_ppp_get_iface(struct modem_ppp *ppp); */ void modem_ppp_release(struct modem_ppp *ppp); +/** + * @cond INTERNAL_HIDDEN + */ + /** * @brief Initialize modem PPP instance device * @param dev Device instance associated with network interface @@ -133,6 +153,10 @@ void modem_ppp_release(struct modem_ppp *ppp); */ int modem_ppp_init_internal(const struct device *dev); +/** + * @endcond + */ + /** * @brief Define a modem PPP module and bind it to a network interface * @@ -163,6 +187,9 @@ int modem_ppp_init_internal(const struct device *dev); modem_ppp_init_internal, NULL, &_name, NULL, _prio, &modem_ppp_ppp_api, \ PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), _mtu) +/** + * @} + */ #ifdef __cplusplus } From 61e87932925f7ef1c596438f52e90f91fb9b1a43 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 14 Oct 2023 16:24:56 +0200 Subject: [PATCH 2046/4498] doc: services: Add modem entry This commit adds an entry for the modem subsystem in the services documentation section. Signed-off-by: Bjarki Arge Andreasen --- doc/services/index.rst | 1 + doc/services/modem/index.rst | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 doc/services/modem/index.rst diff --git a/doc/services/index.rst b/doc/services/index.rst index 87bebc24379..c9055e8081f 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -22,6 +22,7 @@ OS Services resource_management/index.rst mem_mgmt/index.rst modbus/index.rst + modem/index.rst notify.rst pm/index.rst portability/index.rst diff --git a/doc/services/modem/index.rst b/doc/services/modem/index.rst new file mode 100644 index 00000000000..d831d254626 --- /dev/null +++ b/doc/services/modem/index.rst @@ -0,0 +1,53 @@ +.. _modem: + +Modem modules +############# + +This service provides modules necessary to communicate with modems. + +Modems are self-contained devices that implement the hardware and +software necessary to perform RF (Radio-Frequency) communication, +including GNSS, Cellular, WiFi etc. + +The modem modules are inter-connected dynamically using +data-in/data-out pipes making them independently testable and +highly flexible, ensuring stability and scalability. + +Modem pipe +********** + +This module is used to abstract data-in/data-out communication over +a variety of mechanisms, like UART and CMUX DLCI channels, in a +thread-safe manner. + +A modem backend will internally contain an instance of a modem_pipe +structure, alongside any buffers and additional structures required +to abstract away its underlying mechanism. + +The modem backend will return a pointer to its internal modem_pipe +structure when initialized, which will be used to interact with the +backend through the modem pipe API. + +.. doxygengroup:: modem_pipe + +Modem PPP +********* + +This module defines and binds a L2 PPP network interface, described in +:ref:`net_l2_interface`, to a modem backend. The L2 PPP interface sends +and receives network packets. These network packets have to be wrapped +in PPP frames before being transported via a modem backend. This module +performs said wrapping. + +.. doxygengroup:: modem_ppp + +Modem CMUX +********** + +This module is an implementation of CMUX following the 3GPP 27.010 +specification. CMUX is a multiplexing protocol, allowing for multiple +bi-directional streams of data, called DLCI channels. The module +attaches to a single modem backend, exposing multiple modem backends, +each representing a DLCI channel. + +.. doxygengroup:: modem_cmux From 8fada117616d0f7e797d8d5b3eac02cff674e5ac Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 16 Oct 2023 19:43:27 +0200 Subject: [PATCH 2047/4498] doc: releases: Add modem modules to release notes 3.5 This commit adds an entry for the modem modules to the release notes for release 3.5 Signed-off-by: Bjarki Arge Andreasen --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 688cdf72624..9c659bb5c9b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -936,6 +936,10 @@ Libraries / Subsystems * Added the helper function, :c:func:`pm_device_driver_init`, for initializing devices into a specific power state. +* Modem modules + + * Added the :ref:`modem` subsystem. + HALs **** From 363320a09e8b27cdf4d691afd9f302dab721c120 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 13 Oct 2023 14:41:27 -0700 Subject: [PATCH 2048/4498] github: security: Fix supported versions Update supported versions in the github security policy. Signed-off-by: Flavio Ceolin --- .github/SECURITY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 1b16d94b575..a4e9730d0a1 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -8,12 +8,12 @@ updates: - The most recent release, and the release prior to that. - Active LTS releases. -At this time, with the latest release of v3.3, the supported +At this time, with the latest release of v3.5, the supported versions are: - v2.7: Current LTS - - v3.2: Prior release - - v3.3: Current release + - v3.4: Prior release + - v3.5: Current release ## Reporting process From 447d19b70104bc8ad7fa920f36ebeb7a6d688b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 18:09:54 -0400 Subject: [PATCH 2049/4498] doc: smf: Properly highlight C code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set default syntax highlighting language to C for this page. Signed-off-by: Benjamin Cabé --- doc/services/smf/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/services/smf/index.rst b/doc/services/smf/index.rst index d82de94513a..d5f1f918471 100644 --- a/doc/services/smf/index.rst +++ b/doc/services/smf/index.rst @@ -3,6 +3,8 @@ State Machine Framework ####################### +.. highlight:: c + Overview ======== From b2b2afc672f15f9941912b58ac4c9f9576a29602 Mon Sep 17 00:00:00 2001 From: Emilio Benavente Date: Mon, 16 Oct 2023 14:19:53 -0500 Subject: [PATCH 2050/4498] docs: migration-guide-3.5: LPC55XXX Clock Init The inclusion of this note in the migration guide explains the clocking change that occured in the LPC55XXX soc as well as the added Kconfig that toggles the PLL1 from being initialized. Also updated the lpc board docs to state the correct System Clock Value. Signed-off-by: Emilio Benavente --- boards/arm/lpcxpresso55s16/doc/index.rst | 2 +- boards/arm/lpcxpresso55s28/doc/index.rst | 2 +- boards/arm/lpcxpresso55s36/doc/index.rst | 5 +++-- boards/arm/lpcxpresso55s69/doc/index.rst | 2 +- doc/releases/migration-guide-3.5.rst | 5 +++++ 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/boards/arm/lpcxpresso55s16/doc/index.rst b/boards/arm/lpcxpresso55s16/doc/index.rst index abb9170543e..9c25ac8898e 100644 --- a/boards/arm/lpcxpresso55s16/doc/index.rst +++ b/boards/arm/lpcxpresso55s16/doc/index.rst @@ -139,7 +139,7 @@ System Clock ============ The LPC55S16 SoC is configured to use PLL1 clocked from the external 24MHz -crystal, running at 150MHz as a source for the system clock. When the flash +crystal, running at 144MHz as a source for the system clock. When the flash controller is enabled, the core clock will be reduced to 96MHz. The application may reconfigure clocks after initialization, provided that the core clock is always set to 96MHz when flash programming operations are performed. diff --git a/boards/arm/lpcxpresso55s28/doc/index.rst b/boards/arm/lpcxpresso55s28/doc/index.rst index e624a115136..7750254d423 100644 --- a/boards/arm/lpcxpresso55s28/doc/index.rst +++ b/boards/arm/lpcxpresso55s28/doc/index.rst @@ -126,7 +126,7 @@ System Clock ============ The LPC55S28 SoC is configured to use PLL1 clocked from the external 24MHz -crystal, running at 150MHz as a source for the system clock. When the flash +crystal, running at 144MHz as a source for the system clock. When the flash controller is enabled, the core clock will be reduced to 96MHz. The application may reconfigure clocks after initialization, provided that the core clock is always set to 96MHz when flash programming operations are performed. diff --git a/boards/arm/lpcxpresso55s36/doc/index.rst b/boards/arm/lpcxpresso55s36/doc/index.rst index e35e285ff6c..a8914f20154 100644 --- a/boards/arm/lpcxpresso55s36/doc/index.rst +++ b/boards/arm/lpcxpresso55s36/doc/index.rst @@ -147,8 +147,9 @@ the functionality of a pin. System Clock ============ -The LPC55S36 SoC is configured to use the internal FRO at 96MHz as a -source for the system clock. Other sources for the system clock are +The LPC55S36 SoC is configured to use PLL1 clocked from the external 24MHz +crystal, running at 144MHz as a source for the system clock. When the flash +controller is enabled, the core clock will be reduced to 96MHz. Other sources for the system clock are provided in the SOC, depending on your system requirements. Serial Port diff --git a/boards/arm/lpcxpresso55s69/doc/index.rst b/boards/arm/lpcxpresso55s69/doc/index.rst index d6ec337ae9e..9ae2c85f78e 100644 --- a/boards/arm/lpcxpresso55s69/doc/index.rst +++ b/boards/arm/lpcxpresso55s69/doc/index.rst @@ -257,7 +257,7 @@ System Clock ============ The LPC55S69 SoC is configured to use PLL1 clocked from the external 24MHz -crystal, running at 150MHz as a source for the system clock. When the flash +crystal, running at 144MHz as a source for the system clock. When the flash controller is enabled, the core clock will be reduced to 96MHz. The application may reconfigure clocks after initialization, provided that the core clock is always set to 96MHz when flash programming operations are performed. diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 74bc58b8ba0..1fec9c41dc1 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -292,6 +292,11 @@ Required changes * :c:func:`pm_state_set` and :c:func:`pm_exit_post_ops` are mandatory now for any platform supporting power management. +* The LPC55XXX series SOC (except LPC55S06) default main clock has been + updated to PLL1 source from XTAL32K running at 144MHZ. If the new + kconfig option :kconfig:option:`CONFIG_INIT_PLL1` + is disabled then the main clock is muxed to FRO_HR as before. + Recommended Changes ******************* From 822904733e814550843ed212bc072c4107683d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 21:46:03 -0400 Subject: [PATCH 2051/4498] doc: twister: syntax highlight + formatting cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added language info to code-blocks when relevant (ex. for yaml snippets) - Formatted grammar for expression language as antlr and added syntax highlighting - Fixed various formatting issues with lists, definition lists... Signed-off-by: Benjamin Cabé --- doc/develop/test/twister.rst | 317 +++++++++++++++++++---------------- 1 file changed, 172 insertions(+), 145 deletions(-) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 445fc020b9b..ddccee908eb 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -136,7 +136,9 @@ required for best test coverage for this specific board: identifier: A string that matches how the board is defined in the build system. This same string is used when building, for example when calling ``west build`` or - ``cmake``:: + ``cmake``: + + .. code-block:: console # with west west build -b reel_board @@ -153,7 +155,7 @@ arch: Architecture of the board toolchain: The list of supported toolchains that can build this board. This should match - one of the values used for 'ZEPHYR_TOOLCHAIN_VARIANT' when building on the command line + one of the values used for :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` when building on the command line ram: Available RAM on the board (specified in KB). This is used to match testcase requirements. If not specified we default to 128KB. @@ -164,7 +166,7 @@ supported: A list of features this board supports. This can be specified as a single word feature or as a variant of a feature class. For example: - :: + .. code-block:: yaml supported: - pci @@ -172,7 +174,7 @@ supported: This indicates the board does support PCI. You can make a testcase build or run only on such boards, or: - :: + .. code-block:: yaml supported: - netif:eth @@ -206,7 +208,7 @@ testing: Test Cases ********** -Test cases are detected by the presence of a 'testcase.yaml' or a 'sample.yaml' +Test cases are detected by the presence of a ``testcase.yaml`` or a ``sample.yaml`` files in the application's project directory. This file may contain one or more entries in the test section each identifying a test scenario. @@ -244,7 +246,7 @@ samples. The following is an example test with a few options that are explained in this document. -:: + .. code-block:: yaml tests: bluetooth.gatt: @@ -263,7 +265,7 @@ explained in this document. A sample with tests will have the same structure with additional information related to the sample and what is being demonstrated: -:: + .. code-block:: yaml sample: name: hello world @@ -280,11 +282,7 @@ related to the sample and what is being demonstrated: tags: tests min_ram: 16 -The full canonical name for each test case is: - -:: - - / +The full canonical name for each test case is:``/`` Each test block in the testcase meta data can define the following key/value pairs: @@ -298,7 +296,7 @@ skip: (default False) skip testcase unconditionally. This can be used for broken tests. slow: (default False) - Don't run this test case unless --enable-slow or --enable-slow-only was + Don't run this test case unless ``--enable-slow`` or ``--enable-slow-only`` was passed in on the command line. Intended for time-consuming test cases that are only run under certain circumstances, like daily builds. These test cases are still compiled. @@ -309,7 +307,9 @@ extra_args: extra_configs: Extra configuration options to be merged with a master prj.conf - when building or running the test case. For example:: + when building or running the test case. For example: + + .. code-block:: yaml common: tags: drivers adc @@ -321,7 +321,9 @@ extra_configs: - CONFIG_ADC_ASYNC=y Using namespacing, it is possible to apply a configuration only to some - hardware. Currently both architectures and platforms are supported:: + hardware. Currently both architectures and platforms are supported: + + .. code-block:: yaml common: tags: drivers adc @@ -355,7 +357,7 @@ depends_on: A board or platform can announce what features it supports, this option will enable the test only those platforms that provide this feature. -levels: Test levels this test should be part of. If a level is present, this test will be selectable using the command line option ``--level `` @@ -387,7 +389,7 @@ platform_allow: integration_platforms: This option limits the scope to the listed platforms when twister is - invoked with the --integration option. Use this instead of + invoked with the ``--integration`` option. Use this instead of platform_allow if the goal is to limit scope due to timing or resource constraints. @@ -403,7 +405,7 @@ sysbuild: (default False) Build the project using sysbuild infrastructure. Only the main project's generated devicetree and Kconfig will be used for filtering tests. on device testing must use the hardware map, or west flash to load - the images onto the target. The --erase option of west flash is + the images onto the target. The ``--erase`` option of west flash is not supported with this option. Usage of unsupported options will result in tests requiring sysbuild support being skipped. @@ -452,7 +454,9 @@ platform_key: that. For example to key on (arch, simulation) to ensure a test is run once - per arch and simulation (as would be most common):: + per arch and simulation (as would be most common): + + .. code-block:: yaml platform_key: - arch @@ -476,7 +480,6 @@ harness_config: record: - regex: (required) Any string that the particular test case prints to record test results. @@ -496,7 +499,7 @@ harness_config: and identify setups that fulfill this dependency. It depends on specific test setup and board selection logic to pick the particular board(s) out of multiple boards that fulfill the dependency in an - automation setup based on "fixture" keyword. Some sample fixture names + automation setup based on ``fixture`` keyword. Some sample fixture names are i2c_hts221, i2c_bme280, i2c_FRAM, ble_fw and gpio_loop. Only one fixture can be defined per testcase and the fixture name has to @@ -516,7 +519,7 @@ harness_config: The following is an example yaml file with a few harness_config options. - :: + .. code-block:: yaml sample: name: HTS221 Temperature and Humidity Monitor @@ -539,7 +542,7 @@ harness_config: default pytest_root name "pytest" will be used if pytest_root not specified. please refer the examples in samples/subsys/testsuite/pytest/. - :: + .. code-block:: yaml common: harness: pytest @@ -558,7 +561,7 @@ harness_config: The following is an example yaml file with robot harness_config options. - :: + .. code-block:: yaml tests: robot.example: @@ -570,7 +573,7 @@ filter: Filter whether the testcase should be run by evaluating an expression against an environment containing the following values: - :: + .. code-block:: none { ARCH : , PLATFORM : , @@ -586,51 +589,57 @@ filter: The grammar for the expression language is as follows: - expression ::= expression "and" expression - | expression "or" expression - | "not" expression - | "(" expression ")" - | symbol "==" constant - | symbol "!=" constant - | symbol "<" number - | symbol ">" number - | symbol ">=" number - | symbol "<=" number - | symbol "in" list - | symbol ":" string - | symbol + .. code-block:: antlr - list ::= "[" list_contents "]" + expression : expression 'and' expression + | expression 'or' expression + | 'not' expression + | '(' expression ')' + | symbol '==' constant + | symbol '!=' constant + | symbol '<' NUMBER + | symbol '>' NUMBER + | symbol '>=' NUMBER + | symbol '<=' NUMBER + | symbol 'in' list + | symbol ':' STRING + | symbol + ; - list_contents ::= constant - | list_contents "," constant + list : '[' list_contents ']'; - constant ::= number - | string + list_contents : constant (',' constant)*; + constant : NUMBER | STRING; - For the case where expression ::= symbol, it evaluates to true + For the case where ``expression ::= symbol``, it evaluates to ``true`` if the symbol is defined to a non-empty string. Operator precedence, starting from lowest to highest: - or (left associative) - and (left associative) - not (right associative) - all comparison operators (non-associative) + * or (left associative) + * and (left associative) + * not (right associative) + * all comparison operators (non-associative) + + ``arch_allow``, ``arch_exclude``, ``platform_allow``, ``platform_exclude`` + are all syntactic sugar for these expressions. For instance: - arch_allow, arch_exclude, platform_allow, platform_exclude - are all syntactic sugar for these expressions. For instance + .. code-block:: none arch_exclude = x86 arc Is the same as: + .. code-block:: none + filter = not ARCH in ["x86", "arc"] - The ':' operator compiles the string argument as a regular expression, + The ``:`` operator compiles the string argument as a regular expression, and then returns a true value only if the symbol's value in the environment - matches. For example, if CONFIG_SOC="stm32f107xc" then + matches. For example, if ``CONFIG_SOC="stm32f107xc"`` then + + .. code-block:: none filter = CONFIG_SOC : "stm.*" @@ -646,7 +655,7 @@ required_snippets: The following is an example yaml file with 2 required snippets. - :: + .. code-block:: yaml tests: snippet.example: @@ -656,16 +665,16 @@ required_snippets: The set of test cases that actually run depends on directives in the testcase filed and options passed in on the command line. If there is any confusion, -running with -v or examining the discard report +running with ``-v`` or examining the discard report (:file:`twister_discard.csv`) can help show why particular test cases were skipped. Metrics (such as pass/fail state and binary size) for the last code -release are stored in scripts/release/twister_last_release.csv. -To update this, pass the --all --release options. +release are stored in ``scripts/release/twister_last_release.csv``. +To update this, pass the ``--all --release`` options. -To load arguments from a file, write '+' before the file name, e.g., -+file_name. File content must be one or more valid arguments separated by +To load arguments from a file, add ``+`` before the file name, e.g., +``+file_name``. File content must be one or more valid arguments separated by line break instead of white spaces. Most everyday users will run with no arguments. @@ -691,7 +700,7 @@ Running in Integration Mode This mode is used in continuous integration (CI) and other automated environments used to give developers fast feedback on changes. The mode can -be activated using the --integration option of twister and narrows down +be activated using the ``--integration`` option of twister and narrows down the scope of builds and tests if applicable to platforms defined under the integration keyword in the testcase definition file (testcase.yaml and sample.yaml). @@ -705,7 +714,7 @@ supports running any out-of-tree custom emulator defined in the board's :file:`b To use this type of simulation, add the following properties to :file:`custom_board/custom_board.yaml`: -:: +.. code-block:: yaml simulation: custom simulation_exec: @@ -715,14 +724,14 @@ make sure this binary exists in the PATH. Then, in :file:`custom_board/board.cmake`, set the supported emulation platforms to ``custom``: -:: +.. code-block:: cmake set(SUPPORTED_EMU_PLATFORMS custom) Finally, implement the ``run_custom`` target in :file:`custom_board/board.cmake`. It should look something like this: -:: +.. code-block:: cmake add_custom_target(run_custom COMMAND @@ -829,40 +838,40 @@ devices, for example: .. group-tab:: Linux - :: - - - connected: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: unknown - product: DAPLink CMSIS-DAP - runner: pyocd - serial: /dev/cu.usbmodem146114202 - - connected: true - id: 000683759358 - platform: unknown - product: J-Link - runner: unknown - serial: /dev/cu.usbmodem0006837593581 + .. code-block:: yaml + + - connected: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: unknown + product: DAPLink CMSIS-DAP + runner: pyocd + serial: /dev/cu.usbmodem146114202 + - connected: true + id: 000683759358 + platform: unknown + product: J-Link + runner: unknown + serial: /dev/cu.usbmodem0006837593581 .. group-tab:: Windows - :: + .. code-block:: yaml - - connected: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: unknown - product: unknown - runner: unknown - serial: COM1 - - connected: true - id: 000683759358 - platform: unknown - product: unknown - runner: unknown - serial: COM2 + - connected: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: unknown + product: unknown + runner: unknown + serial: COM1 + - connected: true + id: 000683759358 + platform: unknown + product: unknown + runner: unknown + serial: COM2 -Any options marked as 'unknown' need to be changed and set with the correct +Any options marked as ``unknown`` need to be changed and set with the correct values, in the above example the platform names, the products and the runners need to be replaced with the correct values corresponding to the connected hardware. In this example we are using a reel_board and an nrf52840dk_nrf52840: @@ -871,41 +880,41 @@ In this example we are using a reel_board and an nrf52840dk_nrf52840: .. group-tab:: Linux - :: - - - connected: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: reel_board - product: DAPLink CMSIS-DAP - runner: pyocd - serial: /dev/cu.usbmodem146114202 - baud: 9600 - - connected: true - id: 000683759358 - platform: nrf52840dk_nrf52840 - product: J-Link - runner: nrfjprog - serial: /dev/cu.usbmodem0006837593581 - baud: 9600 + .. code-block:: yaml + + - connected: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: reel_board + product: DAPLink CMSIS-DAP + runner: pyocd + serial: /dev/cu.usbmodem146114202 + baud: 9600 + - connected: true + id: 000683759358 + platform: nrf52840dk_nrf52840 + product: J-Link + runner: nrfjprog + serial: /dev/cu.usbmodem0006837593581 + baud: 9600 .. group-tab:: Windows - :: - - - connected: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: reel_board - product: DAPLink CMSIS-DAP - runner: pyocd - serial: COM1 - baud: 9600 - - connected: true - id: 000683759358 - platform: nrf52840dk_nrf52840 - product: J-Link - runner: nrfjprog - serial: COM2 - baud: 9600 + .. code-block:: yaml + + - connected: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: reel_board + product: DAPLink CMSIS-DAP + runner: pyocd + serial: COM1 + baud: 9600 + - connected: true + id: 000683759358 + platform: nrf52840dk_nrf52840 + product: J-Link + runner: nrfjprog + serial: COM2 + baud: 9600 The baud entry is only needed if not running at 115200. @@ -944,17 +953,19 @@ command line options as ``flash-timeout`` and ``flash-with-test`` fields respect These hardware map values override command line options for the particular platform. Serial PTY support using ``--device-serial-pty`` can also be used in the -hardware map:: +hardware map: + +.. code-block:: yaml - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: path/to/script.py - runner_params: - - --remote-host=remote_host_ip_addr - - --key=/path/to/key.pem + - connected: true + id: None + platform: intel_adsp_cavs25 + product: None + runner: intel_adsp + serial_pty: path/to/script.py + runner_params: + - --remote-host=remote_host_ip_addr + - --key=/path/to/key.pem The runner_params field indicates the parameters you want to pass to the @@ -994,7 +1005,9 @@ specify the fixture it needs which can then be matched with hardware capability of a board and the fixtures it supports via the command line or using the hardware map file. -Fixtures are defined in the hardware map file as a list:: +Fixtures are defined in the hardware map file as a list: + +.. code-block:: yaml - connected: true fixtures: @@ -1021,8 +1034,10 @@ Notes +++++ It may be useful to annotate board descriptions in the hardware map file -with additional information. Use the "notes" keyword to do this. For -example:: +with additional information. Use the ``notes`` keyword to do this. For +example: + +.. code-block:: yaml - connected: false fixtures: @@ -1041,11 +1056,13 @@ example:: Overriding Board Identifier +++++++++++++++++++++++++++ -When (re-)generated the hardware map file will contain an "id" keyword +When (re-)generated the hardware map file will contain an ``id`` keyword that serves as the argument to ``--board-id`` when flashing. In some cases the detected ID is not the correct one to use, for example when -using an external J-Link probe. The "probe_id" keyword overrides the -"id" keyword for this purpose. For example:: +using an external J-Link probe. The ``probe_id`` keyword overrides the +``id`` keyword for this purpose. For example: + +.. code-block:: yaml - connected: false id: 0229000005d9ebc600000000000000000000000097969905 @@ -1072,8 +1089,8 @@ The current status of tests on the quarantine list can also be verified by addin which are not on the given list. A quarantine yaml has to be a sequence of dictionaries. Each dictionary has to have -"scenarios" and "platforms" entries listing combinations of scenarios and platforms -to put under quarantine. In addition, an optional entry "comment" can be used, where +``scenarios`` and ``platforms`` entries listing combinations of scenarios and platforms +to put under quarantine. In addition, an optional entry ``comment`` can be used, where some more details can be given (e.g. link to a reported issue). These comments will also be added to the output reports. @@ -1082,7 +1099,9 @@ when dealing with multiple issues within a subsystem, it is possible to use regular expressions, for example, **kernel.*** would quarantine all kernel tests. -An example of entries in a quarantine yaml:: +An example of entries in a quarantine yaml: + +.. code-block:: yaml - scenarios: - sample.basic.helloworld @@ -1096,7 +1115,9 @@ An example of entries in a quarantine yaml:: - .*_cortex_.* - native_posix -To exclude a platform, use the following syntax:: +To exclude a platform, use the following syntax: + +.. code-block:: yaml - platforms: - qemu_x86 @@ -1157,7 +1178,9 @@ The following options control platform filtering in twister: can either be used to replace the existing default platforms or can extend it depending on the value of `override_default_platforms`. -And example platforms configuration:: +And example platforms configuration: + +.. code-block:: yaml platforms: override_default_platforms: true @@ -1177,7 +1200,9 @@ In the configuration file you can include complete components using regular expressions and you can specify which test level to import from the same file, making management of levels simple. -And example test level configuration:: +And example test level configuration: + +.. code-block:: yaml levels: - name: my-test-level @@ -1195,7 +1220,9 @@ Combined configuration To mix the Platform and level configuration, you can take an example as below: -And example platforms plus level configuration:: +And example platforms plus level configuration: + +.. code-block:: yaml platforms: override_default_platforms: true From 88ecf576f48560ce0e463547285d4bdc4519bd0a Mon Sep 17 00:00:00 2001 From: Artur Lipowski Date: Tue, 17 Oct 2023 11:34:10 +0200 Subject: [PATCH 2052/4498] doc: kernel: k_busy_wait behavior with SYSTEM_CLOCK_SLOPPY_IDLE and PM Added note k_busy_wait may not work when CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE and CONFIG_PM are enabled. In such case timer used for time measurement may be disabled. Fixes: #53522 Signed-off-by: Artur Lipowski --- include/zephyr/kernel.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 5dc58488985..607f08320d6 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -531,6 +531,10 @@ __syscall int32_t k_usleep(int32_t us); * k_sleep(). For example k_busy_wait(1000) may take slightly more or * less time than k_sleep(K_MSEC(1)), with the offset dependent on * clock tolerances. + * + * @note In case when @kconfig{CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE} and + * @kconfig{CONFIG_PM} options are enabled, this function may not work. + * The timer/clock used for delay processing may be disabled/inactive. */ __syscall void k_busy_wait(uint32_t usec_to_wait); From 1be457f2808b4c1510e1c8171581293657425cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 20:32:50 -0400 Subject: [PATCH 2053/4498] doc: kconfig: Add syntax highlighting for Kconfig snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add proper pygments settings to make Kconfig snippets look pretty. Also fixed a few config and devicetree code blocks. Signed-off-by: Benjamin Cabé --- doc/build/kconfig/extensions.rst | 8 +- doc/build/kconfig/preprocessor-functions.rst | 6 +- doc/build/kconfig/setting.rst | 24 +++--- doc/build/kconfig/tips.rst | 90 ++++++++++---------- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/doc/build/kconfig/extensions.rst b/doc/build/kconfig/extensions.rst index c8cb285aeb5..efa0ee18ffa 100644 --- a/doc/build/kconfig/extensions.rst +++ b/doc/build/kconfig/extensions.rst @@ -26,7 +26,7 @@ which includes some Kconfig extensions: Consider the following example: - .. code-block:: none + .. code-block:: kconfig source "foo/bar/*/Kconfig" @@ -34,7 +34,7 @@ which includes some Kconfig extensions: :file:`foo/bar/baz/Kconfig` and :file:`foo/bar/qaz/Kconfig`, the statement above is equivalent to the following two ``source`` statements: - .. code-block:: none + .. code-block:: kconfig source "foo/bar/baz/Kconfig" source "foo/bar/qaz/Kconfig" @@ -61,7 +61,7 @@ which includes some Kconfig extensions: :file:`Kconfig` file, and that :file:`foo/bar/Kconfig` has the following statements: - .. code-block:: none + .. code-block:: kconfig source "qaz/Kconfig1" rsource "qaz/Kconfig2" @@ -83,7 +83,7 @@ which includes some Kconfig extensions: For example, the following statement will include :file:`Kconfig1` and :file:`Kconfig2` from the current directory (if they exist): - .. code-block:: none + .. code-block:: kconfig orsource "Kconfig[12]" diff --git a/doc/build/kconfig/preprocessor-functions.rst b/doc/build/kconfig/preprocessor-functions.rst index 295d50af7c4..cb66658d2e4 100644 --- a/doc/build/kconfig/preprocessor-functions.rst +++ b/doc/build/kconfig/preprocessor-functions.rst @@ -75,7 +75,7 @@ Example Usage Assume that the devicetree for some board looks like this: -.. code-block:: none +.. code-block:: devicetree { soc { @@ -94,14 +94,14 @@ The second entry in ``reg`` in ``spi@1001400`` (``<0x20010000 0x3c0900>``) corresponds to ``mem``, and has the address ``0x20010000``. This address can be inserted into Kconfig as follows: -.. code-block:: none +.. code-block:: kconfig config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/spi@1001400,1) After preprocessor expansion, this turns into the definition below: -.. code-block:: none +.. code-block:: kconfig config FLASH_BASE_ADDRESS default 0x20010000 diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index dbc1ff845d8..147549c0503 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -28,7 +28,7 @@ between *visible* and *invisible* symbols. Here's an example of a visible symbol: - .. code-block:: none + .. code-block:: kconfig config FPU bool "Support floating point operations" @@ -47,7 +47,7 @@ between *visible* and *invisible* symbols. Here's an example of an invisible symbol: - .. code-block:: none + .. code-block:: kconfig config CPU_HAS_FPU bool @@ -68,7 +68,7 @@ board with application settings, usually from :file:`prj.conf`. See Assignments in configuration files use this syntax: -.. code-block:: none +.. code-block:: cfg CONFIG_= @@ -78,7 +78,7 @@ There should be no spaces around the equals sign. respectively. The ``FPU`` symbol from the example above could be enabled like this: -.. code-block:: none +.. code-block:: cfg CONFIG_FPU=y @@ -87,7 +87,7 @@ this: A boolean symbol can also be set to ``n`` with a comment formatted like this: - .. code-block:: none + .. code-block:: cfg # CONFIG_SOME_OTHER_BOOL is not set @@ -100,14 +100,14 @@ this: Other symbol types are assigned like this: -.. code-block:: none +.. code-block:: cfg CONFIG_SOME_STRING="cool value" CONFIG_SOME_INT=123 Comments use a #: -.. code-block:: none +.. code-block:: cfg # This is a comment @@ -212,7 +212,7 @@ Assigning values in :file:`Kconfig.defconfig` relies on defining a Kconfig symbol in multiple locations. As an example, say we want to set ``FOO_WIDTH`` below to 32: -.. code-block:: none +.. code-block:: kconfig config FOO_WIDTH int @@ -220,7 +220,7 @@ below to 32: To do this, we extend the definition of ``FOO_WIDTH`` as follows, in :file:`Kconfig.defconfig`: -.. code-block:: none +.. code-block:: kconfig if BOARD_MY_BOARD @@ -255,7 +255,7 @@ symbol properties, so the above ``default`` is equivalent to For example, the direct dependencies of the symbol below becomes ``DEP1 || DEP2``: - .. code-block:: none + .. code-block:: kconfig config FOO ... @@ -312,7 +312,7 @@ There are two ways to configure a Kconfig ``choice``: As an example, assume that a choice has the following base definition (here, the name of the choice is ``FOO``): - .. code-block:: none + .. code-block:: kconfig choice FOO bool "Foo choice" @@ -329,7 +329,7 @@ There are two ways to configure a Kconfig ``choice``: To change the default symbol of ``FOO`` to ``A``, you would add the following definition to :file:`Kconfig.defconfig`: - .. code-block:: none + .. code-block:: kconfig choice FOO default A diff --git a/doc/build/kconfig/tips.rst b/doc/build/kconfig/tips.rst index 276157cdc08..9bae4d2a1c7 100644 --- a/doc/build/kconfig/tips.rst +++ b/doc/build/kconfig/tips.rst @@ -92,7 +92,7 @@ The ``select`` statement is used to force one symbol to ``y`` whenever another symbol is ``y``. For example, the following code forces ``CONSOLE`` to ``y`` whenever ``USB_CONSOLE`` is ``y``: -.. code-block:: none +.. code-block:: kconfig config CONSOLE bool "Console support" @@ -116,7 +116,7 @@ For example, say that a new dependency is added to the ``CONSOLE`` symbol above, by a developer who is unaware of the ``USB_CONSOLE`` symbol (or simply forgot about it): -.. code-block:: none +.. code-block:: kconfig config CONSOLE bool "Console support" @@ -128,7 +128,7 @@ Enabling ``USB_CONSOLE`` now forces ``CONSOLE`` to ``y``, even if To fix the problem, the ``STRING_ROUTINES`` dependency needs to be added to ``USB_CONSOLE`` as well: -.. code-block:: none +.. code-block:: kconfig config USB_CONSOLE bool "USB console support" @@ -146,7 +146,7 @@ statements are common. An alternative attempt to solve the issue might be to turn the ``depends on`` into another ``select``: -.. code-block:: none +.. code-block:: kconfig config CONSOLE bool "Console support" @@ -181,7 +181,7 @@ Alternatives to ``select`` For the example in the previous section, a better solution is usually to turn the ``select`` into a ``depends on``: -.. code-block:: none +.. code-block:: kconfig config CONSOLE bool "Console support" @@ -198,7 +198,7 @@ dependencies only ever have to be updated in a single spot. An objection to using ``depends on`` here might be that configuration files that enable ``USB_CONSOLE`` now also need to enable ``CONSOLE``: -.. code-block:: none +.. code-block:: cfg CONFIG_CONSOLE=y CONFIG_USB_CONSOLE=y @@ -206,7 +206,7 @@ that enable ``USB_CONSOLE`` now also need to enable ``CONSOLE``: This comes down to a trade-off, but if enabling ``CONSOLE`` is the norm, then a mitigation is to make ``CONSOLE`` default to ``y``: -.. code-block:: none +.. code-block:: kconfig config CONSOLE bool "Console support" @@ -214,14 +214,14 @@ mitigation is to make ``CONSOLE`` default to ``y``: This gives just a single assignment in configuration files: -.. code-block:: none +.. code-block:: cfg CONFIG_USB_CONSOLE=y Note that configuration files that do not want ``CONSOLE`` enabled now have to explicitly disable it: -.. code-block:: none +.. code-block:: cfg CONFIG_CONSOLE=n @@ -238,7 +238,7 @@ dependencies. For example, a helper symbol for indicating that a particular CPU/SoC has an FPU could be defined as follows: -.. code-block:: none +.. code-block:: kconfig config CPU_HAS_FPU bool @@ -260,7 +260,7 @@ FPU could be defined as follows: This makes it possible for other symbols to check for FPU support in a generic way, without having to look for particular architectures: -.. code-block:: none +.. code-block:: kconfig config FPU bool "Support floating point operations" @@ -269,7 +269,7 @@ way, without having to look for particular architectures: The alternative would be to have dependencies like the following, possibly duplicated in several spots: -.. code-block:: none +.. code-block:: kconfig config FPU bool "Support floating point operations" @@ -279,7 +279,7 @@ Invisible helper symbols can also be useful without ``select``. For example, the following code defines a helper symbol that has the value ``y`` if the machine has some arbitrarily-defined "large" amount of memory: -.. code-block:: none +.. code-block:: kconfig config LARGE_MEM def_bool MEM_SIZE >= 64 @@ -288,7 +288,7 @@ machine has some arbitrarily-defined "large" amount of memory: This is short for the following: - .. code-block:: none + .. code-block:: kconfig config LARGE_MEM bool @@ -325,7 +325,7 @@ on`` was used. A common misunderstanding related to ``if`` is to think that the following code conditionally includes the file :file:`Kconfig.other`: -.. code-block:: none +.. code-block:: kconfig if DEP source "Kconfig.other" @@ -342,14 +342,14 @@ meaning around a ``source``. Say that :file:`Kconfig.other` above contains this definition: -.. code-block:: none +.. code-block:: kconfig config FOO bool "Support foo" In this case, ``FOO`` will end up with this definition: -.. code-block:: none +.. code-block:: kconfig config FOO bool "Support foo" @@ -371,7 +371,7 @@ twice. There is a common subtle gotcha related to interdependent configuration symbols with prompts. Consider these symbols: -.. code-block:: none +.. code-block:: kconfig config FOO bool "Foo" @@ -396,7 +396,7 @@ To understand what's going on, remember that ``STACK_SIZE`` has a prompt, meaning it is user-configurable, and consider that all Kconfig has to go on from the initial configuration is this: -.. code-block:: none +.. code-block:: cfg CONFIG_STACK_SIZE=0x100 @@ -412,7 +412,7 @@ with suggestions: - If ``STACK_SIZE`` can always be derived automatically and does not need to be user-configurable, then just remove the prompt: - .. code-block:: none + .. code-block:: kconfig config STACK_SIZE hex @@ -425,7 +425,7 @@ with suggestions: 0x200 when ``FOO`` is enabled, then disable its prompt when ``FOO`` is enabled, as described in `optional prompts`_: - .. code-block:: none + .. code-block:: kconfig config STACK_SIZE hex "Stack size" if !FOO @@ -436,7 +436,7 @@ with suggestions: set to a custom value in rare circumstances, then add another option for making ``STACK_SIZE`` user-configurable: - .. code-block:: none + .. code-block:: kconfig config CUSTOM_STACK_SIZE bool "Use a custom stack size" @@ -500,7 +500,7 @@ calculating symbol values. The Kconfig definitions below will hide the ``FOO_DEVICE_FREQUENCY`` symbol and disable any configuration output for it when ``FOO_DEVICE`` is disabled. -.. code-block:: none +.. code-block:: kconfig config FOO_DEVICE bool "Foo device" @@ -530,7 +530,7 @@ children in a separate menu rooted at ``FOO``. ``menuconfig`` can cut down on the number of menus and make the menu structure easier to navigate. For example, say you have the following definitions: -.. code-block:: none +.. code-block:: kconfig menu "Foo subsystem" @@ -557,7 +557,7 @@ easier to navigate. For example, say you have the following definitions: In this case, it's probably better to get rid of the ``menu`` and turn ``FOO_SUBSYSTEM`` into a ``menuconfig`` symbol: -.. code-block:: none +.. code-block:: kconfig menuconfig FOO_SUBSYSTEM bool "Foo subsystem" @@ -599,7 +599,7 @@ Commas in macro arguments Kconfig uses commas to separate macro arguments. This means a construct like this will fail: -.. code-block:: none +.. code-block:: kconfig config FOO bool @@ -608,7 +608,7 @@ This means a construct like this will fail: To solve this problem, create a variable with the text and use this variable as argument, as follows: -.. code-block:: none +.. code-block:: kconfig DT_CHOSEN_ZEPHYR_BAR := zephyr,bar @@ -688,7 +688,7 @@ be factored out with an ``if``. As an example, consider the following code: -.. code-block:: none +.. code-block:: kconfig config FOO bool "Foo" @@ -712,7 +712,7 @@ As an example, consider the following code: Here, the ``DEP`` dependency can be factored out like this: -.. code-block:: none +.. code-block:: kconfig if DEP @@ -742,7 +742,7 @@ Here, the ``DEP`` dependency can be factored out like this: If a sequence of symbols/choices with shared dependencies are all in the same menu, the dependency can be put on the menu itself: -.. code-block:: none +.. code-block:: kconfig menu "Foo features" depends on FOO_SUPPORT @@ -782,7 +782,7 @@ a previously defined ``default y``. That is, FOO will be set to ``n`` in the example below. If the ``default n`` was omitted in the first definition, FOO would have been set to ``y``. - .. code-block:: none + .. code-block:: kconfig config FOO bool "foo" @@ -794,7 +794,7 @@ omitted in the first definition, FOO would have been set to ``y``. In the following example FOO will get the value ``y``. - .. code-block:: none + .. code-block:: kconfig config FOO bool "foo" @@ -814,12 +814,12 @@ Kconfig has two shorthands that deal with prompts and defaults. - `` "prompt"`` is a shorthand for giving a symbol/choice a type and a prompt at the same time. These two definitions are equal: - .. code-block:: none + .. code-block:: kconfig config FOO bool "foo" - .. code-block:: none + .. code-block:: kconfig config FOO bool @@ -830,12 +830,12 @@ Kconfig has two shorthands that deal with prompts and defaults. - ``def_ `` is a shorthand for giving a type and a value at the same time. These two definitions are equal: - .. code-block:: none + .. code-block:: kconfig config FOO def_bool BAR && BAZ - .. code-block:: none + .. code-block:: kconfig config FOO bool @@ -907,7 +907,7 @@ doesn't force a value. For example, the following code could be used to enable USB keyboard support by default on the FOO SoC, while still allowing the user to turn it off: -.. code-block:: none +.. code-block:: kconfig config SOC_FOO bool "FOO SoC" @@ -928,7 +928,7 @@ A condition can be put on a symbol's prompt to make it optionally configurable by the user. For example, a value ``MASK`` that's hardcoded to 0xFF on some boards and configurable on others could be expressed as follows: -.. code-block:: none +.. code-block:: kconfig config MASK hex "Bitmask" if HAS_CONFIGURABLE_MASK @@ -938,7 +938,7 @@ boards and configurable on others could be expressed as follows: This is short for the following: - .. code-block:: none + .. code-block:: kconfig config MASK hex @@ -956,7 +956,7 @@ Optional choices Defining a choice with the ``optional`` keyword allows the whole choice to be toggled off to select none of the symbols: -.. code-block:: none +.. code-block:: kconfig choice prompt "Use legacy protocol" @@ -983,7 +983,7 @@ within it, while still allowing symbol default values to kick in. As a motivating example, consider the following code: -.. code-block:: none +.. code-block:: kconfig menu "Foo subsystem" depends on HAS_CONFIGURABLE_FOO @@ -1002,7 +1002,7 @@ When ``HAS_CONFIGURABLE_FOO`` is ``n``, no configuration output is generated for ``FOO_SETTING_1`` and ``FOO_SETTING_2``, as the code above is logically equivalent to the following code: -.. code-block:: none +.. code-block:: kconfig config FOO_SETTING_1 int "Foo setting 1" @@ -1018,7 +1018,7 @@ If we want the symbols to still get their default values even when ``HAS_CONFIGURABLE_FOO`` is ``n``, but not be configurable by the user, then we can use ``visible if`` instead: -.. code-block:: none +.. code-block:: kconfig menu "Foo subsystem" visible if HAS_CONFIGURABLE_FOO @@ -1035,7 +1035,7 @@ can use ``visible if`` instead: This is logically equivalent to the following: -.. code-block:: none +.. code-block:: kconfig config FOO_SETTING_1 int "Foo setting 1" if HAS_CONFIGURABLE_FOO @@ -1053,7 +1053,7 @@ This is logically equivalent to the following: When ``HAS_CONFIGURABLE`` is ``n``, we now get the following configuration output for the symbols, instead of no output: -.. code-block:: none +.. code-block:: cfg ... CONFIG_FOO_SETTING_1=1 From 00fc22a44a8461c70d41ba3dfa6453aa3a205eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 20:50:28 -0400 Subject: [PATCH 2054/4498] doc: porting: Set proper languages for syntax highlighting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure devicetree, kconfig, etc. code snippets all have proper pygments language set. Signed-off-by: Benjamin Cabé --- doc/hardware/porting/arch.rst | 8 ++++---- doc/hardware/porting/board_porting.rst | 10 +++++----- doc/hardware/porting/shields.rst | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/hardware/porting/arch.rst b/doc/hardware/porting/arch.rst index a4e1e753cff..9069db2ec73 100644 --- a/doc/hardware/porting/arch.rst +++ b/doc/hardware/porting/arch.rst @@ -535,7 +535,7 @@ The region specified by ``thread.stack_info.start`` and the initial stack pointer from the very end of the stack object, taking into account storage for TLS and ASLR random offsets. -:: +.. code-block:: none +---------------------+ <- thread.stack_obj | Reserved Memory | } K_(THREAD|KERNEL)_STACK_RESERVED @@ -624,7 +624,7 @@ simply leave an non-present virtual page below every stack when it is mapped into the address space. The stack object will still need to be properly aligned and sized to page granularity. -:: +.. code-block:: none +-----------------------------+ <- thread.stack_obj | Guard reserved memory | } K_KERNEL_STACK_RESERVED @@ -683,7 +683,7 @@ On systems without power-of-two region requirements, the reserved memory area for threads stacks defined by :c:macro:`K_THREAD_STACK_RESERVED` may be used to contain the privilege mode stack. The layout could be something like: -:: +.. code-block:: none +------------------------------+ <- thread.stack_obj | Other platform data | @@ -742,7 +742,7 @@ of the privilege stacks can be looked up quickly at runtime based on the thread stack address using :c:func:`z_priv_stack_find()`. These stacks are laid out the same way as other kernel-only stacks. -:: +.. code-block:: none +-----------------------------+ <- z_priv_stack_find(thread.stack_obj) | Reserved memory | } K_KERNEL_STACK_RESERVED diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index 5b21cbf2b68..5be561aecb2 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -327,7 +327,7 @@ named ``plank``: This should at least contain a definition for a ``BOARD_PLANK`` option, which looks something like this: - .. code-block:: none + .. code-block:: kconfig config BOARD_PLANK bool "Plank board" @@ -340,7 +340,7 @@ named ``plank``: The entire file should be inside an ``if BOARD_PLANK`` / ``endif`` pair of lines, like this: - .. code-block:: none + .. code-block:: kconfig if BOARD_PLANK @@ -369,10 +369,10 @@ named ``plank``: your system clock, console, etc. The results are architecture-specific, but typically look something like this: - .. code-block:: none + .. code-block:: cfg - CONFIG_SOC_${VENDOR_XYZ3000}=y /* select your SoC */ - CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 /* set up your clock, etc */ + CONFIG_SOC_${VENDOR_XYZ3000}=y # select your SoC + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 # set up your clock, etc CONFIG_SERIAL=y :file:`plank_x_y_z.conf` diff --git a/doc/hardware/porting/shields.rst b/doc/hardware/porting/shields.rst index 0f6c1a9a7a4..9eca06177b4 100644 --- a/doc/hardware/porting/shields.rst +++ b/doc/hardware/porting/shields.rst @@ -101,7 +101,7 @@ CMake command Alternatively, it could be set by default in a project's CMakeLists.txt: -.. code-block:: none +.. code-block:: cmake set(SHIELD x_nucleo_iks01a1) @@ -153,7 +153,7 @@ node`_ that looks like the following into the board devicetree file: .. _nexus node: https://github.com/devicetree-org/devicetree-specification/blob/4b1dac80eaca45b4babf5299452a951008a5d864/source/devicetree-basics.rst#nexus-nodes-and-specifier-mapping -.. code-block:: none +.. code-block:: devicetree arduino_header: connector { compatible = "arduino-header-r3"; @@ -193,7 +193,7 @@ bits of the flags correspond to features that can be configured in devicetree. In some cases it's necessary to use a non-zero flag value to tell the driver how a particular pin behaves, as with: -.. code-block:: none +.. code-block:: devicetree drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>; From 02226208bf1ade1181ac36e9436c70d9f2def1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 11:25:54 -0400 Subject: [PATCH 2055/4498] doc: intro: cleanup VFS section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add mention of ext2 as a supported file system. * remove unnecessary mention to configurability and logging since it's not unique to VFS. * capitalize FatFS properly Signed-off-by: Benjamin Cabé --- doc/introduction/index.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index d83a778e526..5444694dd21 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -147,10 +147,9 @@ Zephyr offers a large and ever growing number of features including: systems. A native POSIX port lets you build and run Zephyr as a native application on Linux and other OSes, aiding development and testing. -**Virtual File System Interface with LittleFS and FATFS Support** - LittleFS and FATFS Support, - FCB (Flash Circular Buffer) for memory constrained applications, and - file system enhancements for logging and configuration. +**Virtual File System Interface with ext2, FatFs, and LittleFS Support** + ext2, LittleFS and FatFS support; FCB (Flash Circular Buffer) for memory constrained + applications. **Powerful multi-backend logging Framework** Support for log filtering, object dumping, panic mode, multiple backends From edf9435a68a42150e7198c5ccdca30791602d944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 17:23:46 -0400 Subject: [PATCH 2056/4498] doc: guidelines: Properly highlight .rst snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes syntax higlighting of all the reStructuredText snippets in the documentation guidelines by setting default higlighting language to rst. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/guidelines.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index a98fa751916..307356492e1 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -3,6 +3,8 @@ Documentation Guidelines ######################## +.. highlight:: rst + .. note:: For instructions on building the documentation, see :ref:`zephyr_doc`. @@ -302,9 +304,7 @@ External Cross-Reference Linking With Sphinx's help, we can create link-references to any tagged text within the Zephyr Project documentation. -Target locations in a document are defined with a label directive: - - .. code-block:: rst +Target locations in a document are defined with a label directive:: .. _my label name: @@ -325,10 +325,7 @@ To enable easy cross-page linking within the site, each file should have a reference label before its title so it can be referenced from another file. These reference labels must be unique across the whole site, so generic names such as "samples" should be -avoided. For example the top of this document's .rst file is: - - -.. code-block:: rst +avoided. For example the top of this document's .rst file is:: .. _doc_guidelines: From 57c17da5288400a26e776e919d6e4495b44831ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 22:02:17 -0400 Subject: [PATCH 2057/4498] doc: devicetree: Fix highlighting of code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure devicetree code blocks all have proper pygments language set. Fixed a few other "none" code blocks as well. Signed-off-by: Benjamin Cabé --- doc/build/dts/howtos.rst | 13 ++++++++----- doc/build/dts/intro-input-output.rst | 4 +++- doc/build/dts/intro-syntax-structure.rst | 8 +++++--- doc/build/dts/troubleshooting.rst | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/doc/build/dts/howtos.rst b/doc/build/dts/howtos.rst index 02580ad223d..cb556bb782d 100644 --- a/doc/build/dts/howtos.rst +++ b/doc/build/dts/howtos.rst @@ -149,7 +149,9 @@ that the node has ``status = "okay"``, like this: If you see the ``#error`` output, make sure to enable the node in your devicetree. In some situations your code will compile but it will fail to link -with a message similar to:: +with a message similar to: + +.. code-block:: none ...undefined reference to `__device_dts_ord_N' collect2: error: ld returned 1 exit status @@ -299,6 +301,7 @@ For example, if your BOARD.dts contains this node: These are equivalent ways to override the ``current-speed`` value in an overlay: +.. Disable syntax highlighting as this construct does not seem supported by pygments .. code-block:: none /* Option 1 */ @@ -316,7 +319,7 @@ We'll use the ``&serial0`` style for the rest of these examples. You can add aliases to your devicetree using overlays: an alias is just a property of the ``/aliases`` node. For example: -.. code-block:: none +.. code-block:: devicetree / { aliases { @@ -326,7 +329,7 @@ property of the ``/aliases`` node. For example: Chosen nodes work the same way. For example: -.. code-block:: none +.. code-block:: devicetree / { chosen { @@ -337,7 +340,7 @@ Chosen nodes work the same way. For example: To delete a property (in addition to deleting properties in general, this is how to set a boolean property to false if it's true in BOARD.dts): -.. code-block:: none +.. code-block:: devicetree &serial0 { /delete-property/ some-unwanted-property; @@ -346,7 +349,7 @@ how to set a boolean property to false if it's true in BOARD.dts): You can add subnodes using overlays. For example, to configure a SPI or I2C child device on an existing bus node, do something like this: -.. code-block:: none +.. code-block:: devicetree /* SPI device example */ &spi1 { diff --git a/doc/build/dts/intro-input-output.rst b/doc/build/dts/intro-input-output.rst index 7b2c2a1119c..365d9fd3c37 100644 --- a/doc/build/dts/intro-input-output.rst +++ b/doc/build/dts/intro-input-output.rst @@ -23,7 +23,9 @@ There are four types of devicetree input files: - overlays (``.overlay``) - bindings (``.yaml``) -The devicetree files inside the :file:`zephyr` directory look like this:: +The devicetree files inside the :file:`zephyr` directory look like this: + +.. code-block:: none boards///.dts dts/common/skeleton.dtsi diff --git a/doc/build/dts/intro-syntax-structure.rst b/doc/build/dts/intro-syntax-structure.rst index 8f5d3aa84d0..f3b7c6cebd7 100644 --- a/doc/build/dts/intro-syntax-structure.rst +++ b/doc/build/dts/intro-syntax-structure.rst @@ -387,9 +387,11 @@ Additional notes on the above: that order. - Parentheses, arithmetic operators, and bitwise operators are allowed. The - ``bar`` property contains a single cell with value 64:: + ``bar`` property contains a single cell with value 64: - bar = <(2 * (1 << 5))>; + .. code-block:: devicetree + + bar = <(2 * (1 << 5))>; Note that the entire expression must be parenthesized. @@ -419,7 +421,7 @@ Additional notes on the above: - Array and similar type property values can be split into several ``<>`` blocks, like this: - .. code-block:: none + .. code-block:: devicetree foo = <1 2>, <3 4>; // Okay for 'type: array' foo = <&label1 &label2>, <&label3 &label4>; // Okay for 'type: phandles' diff --git a/doc/build/dts/troubleshooting.rst b/doc/build/dts/troubleshooting.rst index 563ce04aac5..54169b3ab42 100644 --- a/doc/build/dts/troubleshooting.rst +++ b/doc/build/dts/troubleshooting.rst @@ -193,7 +193,7 @@ as you enable the devicetree node. Otherwise, it is sometimes as simple as adding a line like this to your application's :file:`prj.conf` file and then making sure to :ref:`dt-trouble-try-pristine`: -.. code-block:: none +.. code-block:: cfg CONFIG_FOO=y From 90c4498ca1dea1214f32dbd566d6575d02d52763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 21:05:08 -0400 Subject: [PATCH 2058/4498] doc: boards: Set proper languages for syntax highlighting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure devicetree, kconfig, etc. code snippets all have proper pygments language set. Note: only existing code-block:: directives have been updated. Another pass should be made to address implicit code-blocks (`::`) Signed-off-by: Benjamin Cabé --- boards/arm/cc3220sf_launchxl/doc/index.rst | 2 +- boards/arm/cc3235sf_launchxl/doc/index.rst | 2 +- boards/arm/mimxrt1050_evk/doc/index.rst | 4 ++-- boards/arm/msp_exp432p401r_launchxl/doc/index.rst | 2 +- boards/arm/nrf9160dk_nrf52840/doc/index.rst | 6 +++--- boards/arm/twr_ke18f/doc/index.rst | 2 +- boards/riscv/rv32m1_vega/doc/index.rst | 2 +- boards/shields/x_nucleo_idb05a1/doc/index.rst | 2 +- boards/xtensa/esp32_ethernet_kit/doc/index.rst | 8 ++++++-- 9 files changed, 17 insertions(+), 13 deletions(-) diff --git a/boards/arm/cc3220sf_launchxl/doc/index.rst b/boards/arm/cc3220sf_launchxl/doc/index.rst index 8b88133ccbd..4e941cef91e 100644 --- a/boards/arm/cc3220sf_launchxl/doc/index.rst +++ b/boards/arm/cc3220sf_launchxl/doc/index.rst @@ -172,7 +172,7 @@ Prerequisites: to the paths of the OpenOCD binary and its scripts, before including the common openocd.board.cmake file: - .. code-block:: none + .. code-block:: cmake set(OPENOCD "/usr/local/bin/openocd" CACHE FILEPATH "" FORCE) set(OPENOCD_DEFAULT_PATH /usr/local/share/openocd/scripts) diff --git a/boards/arm/cc3235sf_launchxl/doc/index.rst b/boards/arm/cc3235sf_launchxl/doc/index.rst index 71d8a44a8fb..80a4fb3c0e9 100644 --- a/boards/arm/cc3235sf_launchxl/doc/index.rst +++ b/boards/arm/cc3235sf_launchxl/doc/index.rst @@ -172,7 +172,7 @@ Prerequisites: to the paths of the OpenOCD binary and its scripts, before including the common openocd.board.cmake file: - .. code-block:: none + .. code-block:: cmake set(OPENOCD "/usr/local/bin/openocd" CACHE FILEPATH "" FORCE) set(OPENOCD_DEFAULT_PATH /usr/local/share/openocd/scripts) diff --git a/boards/arm/mimxrt1050_evk/doc/index.rst b/boards/arm/mimxrt1050_evk/doc/index.rst index 3081e162138..5d48e823f79 100644 --- a/boards/arm/mimxrt1050_evk/doc/index.rst +++ b/boards/arm/mimxrt1050_evk/doc/index.rst @@ -436,9 +436,9 @@ Board Revisions *************** The original MIMXRT1050-EVK (rev A0) board was updated with a newer -MIMXRT1050-EVKB (rev A1) board, with these major hardware differences:: +MIMXRT1050-EVKB (rev A1) board, with these major hardware differences: -- SoC changed from MIMXRT1052DVL6**A** to MIMXRT1052DVL6**B** +- SoC changed from MIMXRT1052DVL6\ **A** to MIMXRT1052DVL6\ **B** - Hardware bug fixes for: power, interfaces, and memory - Arduino headers included diff --git a/boards/arm/msp_exp432p401r_launchxl/doc/index.rst b/boards/arm/msp_exp432p401r_launchxl/doc/index.rst index 462aeb04de0..d2a2e12153a 100644 --- a/boards/arm/msp_exp432p401r_launchxl/doc/index.rst +++ b/boards/arm/msp_exp432p401r_launchxl/doc/index.rst @@ -88,7 +88,7 @@ Prerequisites: to the paths of the OpenOCD binary and its scripts, before including the common openocd.board.cmake file: - .. code-block:: none + .. code-block:: cmake set(OPENOCD "/usr/local/bin/openocd" CACHE FILEPATH "" FORCE) set(OPENOCD_DEFAULT_PATH /usr/local/share/openocd/scripts) diff --git a/boards/arm/nrf9160dk_nrf52840/doc/index.rst b/boards/arm/nrf9160dk_nrf52840/doc/index.rst index 752eee4c6fa..e16d6bc30e4 100644 --- a/boards/arm/nrf9160dk_nrf52840/doc/index.rst +++ b/boards/arm/nrf9160dk_nrf52840/doc/index.rst @@ -228,7 +228,7 @@ P0.17, P0.18, and P0.19 so that they are routed to nRF52840 pins P0.17, P0.20, and P0.15, respectively, add the following in the devicetree overlay in your application: -.. code-block:: none +.. code-block:: devicetree &nrf_interface_pins_0_2_routing { status = "okay"; @@ -237,7 +237,7 @@ application: And if you want to, for example, disable routing for the VCOM2 pins, add the following: -.. code-block:: none +.. code-block:: devicetree &vcom2_pins_routing { status = "disabled"; @@ -252,7 +252,7 @@ configure the signal routing between nRF9160 and nRF52840 on the nRF9160 DK. For example, to use ``uart1`` on both these chips for communication between them, add the following line in the overlays for applications on both sides: -.. code-block:: none +.. code-block:: devicetree #include diff --git a/boards/arm/twr_ke18f/doc/index.rst b/boards/arm/twr_ke18f/doc/index.rst index 336099ddca0..fd2c8c803d8 100644 --- a/boards/arm/twr_ke18f/doc/index.rst +++ b/boards/arm/twr_ke18f/doc/index.rst @@ -117,7 +117,7 @@ In order to support FXOS8700 triggers (interrupts) the 0 ohm resistors devicetree must also be modified to describe the FXOS8700 interrupt GPIOs: -.. code-block:: none +.. code-block:: devicetree /dts-v1/; diff --git a/boards/riscv/rv32m1_vega/doc/index.rst b/boards/riscv/rv32m1_vega/doc/index.rst index defd9177435..867a86a2c69 100644 --- a/boards/riscv/rv32m1_vega/doc/index.rst +++ b/boards/riscv/rv32m1_vega/doc/index.rst @@ -498,7 +498,7 @@ first make sure you're booting the right core. The output should look like this: - .. code-block:: none + .. code-block:: console $ ~/rv32m1-openocd -f boards/riscv/rv32m1_vega/support/openocd_rv32m1_vega_ri5cy.cfg Open On-Chip Debugger 0.10.0+dev-00431-ge1ec3c7d (2018-10-31-07:29) diff --git a/boards/shields/x_nucleo_idb05a1/doc/index.rst b/boards/shields/x_nucleo_idb05a1/doc/index.rst index c210e6ac6f1..d2c6f006f77 100644 --- a/boards/shields/x_nucleo_idb05a1/doc/index.rst +++ b/boards/shields/x_nucleo_idb05a1/doc/index.rst @@ -85,7 +85,7 @@ build command: Alternatively, set use of this shield in the project's ``CMakeLists.txt`` file: -.. code-block:: none +.. code-block:: cmake set(SHIELD x_nucleo_idb05a1) diff --git a/boards/xtensa/esp32_ethernet_kit/doc/index.rst b/boards/xtensa/esp32_ethernet_kit/doc/index.rst index 5227cd3646e..7159681dccd 100644 --- a/boards/xtensa/esp32_ethernet_kit/doc/index.rst +++ b/boards/xtensa/esp32_ethernet_kit/doc/index.rst @@ -581,7 +581,9 @@ You can debug an application in the usual way. Here is an example for the :ref:` Enabling Ethernet ***************** -Enable Ethernet MAC, PHY and MDIO; add these to your device tree overlay:: +Enable Ethernet MAC, PHY and MDIO; add these to your device tree overlay: + +.. code-block:: devicetree ð { status = "okay"; @@ -595,7 +597,9 @@ Enable Ethernet MAC, PHY and MDIO; add these to your device tree overlay:: status = "okay"; }; -Enable Ethernet in KConfig:: +Enable Ethernet in KConfig: + +.. code-block:: cfg CONFIG_ETH_ESP32=y CONFIG_NETWORKING=y From a58bf96d0dd46325d7f6f5c9277cfdf19dc145df Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Wed, 18 Oct 2023 13:52:52 +0200 Subject: [PATCH 2059/4498] fs: fix missing semicolon in fuse_fs_access.c Add missing semicolon in fuse_fs_access.c. Signed-off-by: Jeppe Odgaard --- subsys/fs/fuse_fs_access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/fs/fuse_fs_access.c b/subsys/fs/fuse_fs_access.c index 11e8f0225d9..e39416f91cf 100644 --- a/subsys/fs/fuse_fs_access.c +++ b/subsys/fs/fuse_fs_access.c @@ -183,7 +183,7 @@ static int fuse_fs_access_readdir(const char *path, void *buf, return -ENOMEM; } - memcpy(mount_path, path, len) + memcpy(mount_path, path, len); mount_path[len] = '/'; err = fs_opendir(&dir, mount_path); } else { From 9b8b7b36bee401ca46a93e6f274c9e99632fa890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 23:01:25 -0400 Subject: [PATCH 2060/4498] doc: samples: edac: add syntax highlight to code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit display Zephyr shell snippets as "console" code blocks. Signed-off-by: Benjamin Cabé --- samples/subsys/edac/README.rst | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/samples/subsys/edac/README.rst b/samples/subsys/edac/README.rst index 2548284928a..fb556b1c07b 100644 --- a/samples/subsys/edac/README.rst +++ b/samples/subsys/edac/README.rst @@ -34,7 +34,9 @@ Getting help ============ After the application has started help can be read with the following -command:: +command: + +.. code-block:: console uart:~$ edac -h edac - EDAC information @@ -44,7 +46,9 @@ command:: inject :Inject ECC error commands edac inject -Help for subcommand info can be read with:: +Help for subcommand info can be read with: + +.. code-block:: console uart:~$ edac info -h info - Show EDAC information @@ -53,7 +57,9 @@ Help for subcommand info can be read with:: ecc_error :ECC Error Show / Clear commands parity_error :Parity Error Show / Clear commands -Injection help can be received with:: +Injection help can be received with: + +.. code-block:: console uart:~$ edac inject -h inject - Inject ECC error commands @@ -70,7 +76,9 @@ Injection help can be received with:: Testing Error Injection ======================= -Set Error Injection parameters with:: +Set Error Injection parameters with: + +.. code-block:: console uart:~$ edac inject addr 0x1000 Set injection address base to: 0x1000 @@ -81,13 +89,17 @@ Set Error Injection parameters with:: uart:~$ edac inject error_type correctable Set injection error type: correctable -Trigger injection with:: +Trigger injection with: + +.. code-block:: console uart:~$ edac inject trigger Triggering injection Now Read / Write to the injection address to trigger Error Injection with -following devmem commands:: +following devmem commands: + +.. code-block:: console uart:~$ devmem 0x1000 32 0xabcd Mapped 0x1000 to 0x2ffcf000 @@ -101,6 +113,8 @@ following devmem commands:: Using data width 32 Read value 0xabcd -We should get the following message on screen indicating an IBECC event:: +We should get the following message on screen indicating an IBECC event: + +.. code-block:: none Got notification about IBECC event From d15ce54db1d5be5e9ad414b0d2c5fe3d74a17dfe Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 13 Oct 2023 11:29:44 +0200 Subject: [PATCH 2061/4498] doc: releases: v3.5.0: Add Bluetooth release notes Add Bluetooth release notes for Zephyr v3.5.0. Signed-off-by: Vinayak Kariappa Chettimada --- doc/releases/release-notes-3.5.rst | 136 +++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9c659bb5c9b..9dd507b1219 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -106,14 +106,150 @@ Bluetooth * Audio + Improved memory usage of codec configurations and codec capabilities. Fixed several bugs in BAP + and the BAP-related services (ASCS, PACS, BASS), as well as missing features such as proper + notification handling. + + * Added BAP ``bt_bap_stream_get_tx_sync`` + * Added CAP stream send and tx sync + * Added ``bt_audio_codec_cap_get`` helper functions + * Added support for long read/write in CAP + * Fixed ASCS Source ASE link loss state transition + * Fixed ASCS possible ASE leak + * Fixed ASCS to drop ISO PDUs if ASE is not in streaming state + * Fixed BAP ``bt_bap_scan_delegator_find_state`` implementation + * Fixed BAP issue with PA sync and ID in ``broadcast_sink_create`` + * Fixed TMAS characteristic permissions + * Fixed ``tbs_client`` missing discovery complete event + * Fixed audio stack to accept empty CCID list in audio metadata + * Fixed bad size of metadata_backup in ASCS + * Fixed possible ASCS ASE stuck in releasing state + * Refactored ``bt_audio_codec_cap`` to flat arrays + * Refactored ``bt_audio_codec_cfg`` to flat arrays + * Removed ``CONFIG_BT_PACS_{SNK,SRC}_CONTEXT`` + * Removed scanning and PA sync from broadcast sink + * Renamed ``bt_codec`` to ``bt_audio_codec_{cap, conf, data}`` + * Renamed codec qos framing + * Replaced ``BT_AUDIO_CODEC_LC3_ID`` -> ``BT_HCI_CODING_FORMAT_LC3`` + * Replaced ``BT_AUDIO_CODEC_PARSE_ERR_`` values with errno values. + * Reworked PACS notify system + * Updated ASCS ISO QOS based on BAP QOS + * Updated BAP to filter PA data duplicates by default + * Updated CSIP to unlock Non-bonded devices immediately. + * Updated PACS to notify bonded clients on reconnect + * Updated ``bt_cap_stream_ops_register`` to always register BAP callbacks + * Updated the ASCS ACL disconnect behavior + * Updated to split ``bt_audio_codec_meta_get`` to ``cfg`` and ``cap`` + * Direction Finding * Host + * Added SMP bondable flag overlay per connection + * Added USE_NRPA advertising option + * Added ``BT_CONN_PARAM_ANY`` to allow setting any value to connection parameters + * Added advanced broadcast ISO parameters + * Added advanced unicast ISO parameters + * Added new API to manage Bluetooth settings storage + * Fixed HCI ISO Data packets fragmentation + * Fixed HCI ISO SDU length sent to controller + * Fixed OTS ``bt_ots_init`` parameter struct naming + * Fixed OTS memory leak while procedure is not finished + * Fixed a connection reference leak + * Fixed forced pairing request handling + * Fixed host to invalidate the Resolvable Private Address when starting legacy advertising + * Fixed issue with ``bt_iso_cig_reconfigure`` + * Fixed possible buffer overflow in ``bt_conn_le_start_encryption`` + * Fixed some SMP issues + * Fixed to abort pairing if connection disconnected + * Updated L2CAP accept callbacks + * Updated LE L2CAP connected callback to be after connection response + * Updated PAwR implementation to use RPA as responder address if BT_PRIVACY=y + * Mesh + * Added TF-M support. + * Added support to use both tinycrypt and PSA based crypto + * Added full virtual addresses support with the collisions resolution. The + :kconfig:option:`CONFIG_BT_MESH_LABEL_NO_RECOVER` Kconfig option is introduced to restore the + addresses for the subscription list and model publication. + * Added statistic module. + * Fixed an issue where a node acting as a LPN was triggering Friend Poll messages when sending a + segmented message over the loopback interface. + * Fixed an issue where provisioning completes successfully on a node when the identical Public Key + is used by a provisioner. + * Fixed an issue where the :c:func:`settings_load` function called from a cooperative thread other + than the system workqueue caused the GATT Mesh Proxy Service registration to fail. + * Fixed an issue where a node could enter IV Update in Progress state if an old SNB with the + current IV Index and IV Update flag set to 1 was resent. + + * Mesh Protocol v1.1 changes + + * Added storing Private GATT Proxy state persistently. + * Added support for Firmware Distribution Upload OOB Start message in the Firwmware Distribution + Server model. The message support can be enabled with the + :kconfig:option:`CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD` Kconfig option. + * Added extended provisioning protocol timeout when OOB methods are used in the provisioning. + * Added support for Composition Data Pages 2, 129 and 130. + * Added documentation for Composition Data Pages 0, 1, 2, 128, 129 and 130. + * Added documentation for the Segmentation and Reassembly in the Transport layer. + * Added documentation for the SAR Configuration models + * Fixed an issue where the Opcode Aggregator Server model did not compile without the Opcode + Aggregator Client model. + * Fixed an issue where the identity address was used in Private GATT Proxy advertisements + instead of Non-Resolvable Private Addresses. + * Fixed the Proxy Privacy parameter support. + * Fixed an issue where the Composition Data Page 128 was not present on a node that has + instantiated the Remote Provisioning Server model. + * Fixed an issue where the Large Composition Data Server model did not support Composition Data + Pages other then 0. + * Fixed an issue where the Remote Provisioning Client model instanted on a node together with + the Remote Provisioning Server model could not reprovision itself. + * Fixed an issue where the acknowledgment timer in the Segmentation and Reassembly was not + restarted when the incoming Segment Acknowledgment message did not contain at least one + segment newly marked as acknowledged. + * Fixed an issue where the On-Demand Private Proxy Server and Client models had interdependency + that did not allow to compile them separately. + * Controller + Improved support for Broadcast and Connected Isochronous channels in the Controller, enabling + LE audio application development. The Controller is experimental, is missing implementations for + interleaved packing in Isochronous channels' lower link layer. + + * Added Checks for minimum sizes of Adv PDUs + * Added Kconfig Option to ignore Tx HCI ISO Data Packet Seq Num + * Added Kconfig for avoiding ISO SDU fragmentation + * Added Kconfig to maximize BIG event length and preempt PTO & CTRL subevents + * Added ``BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX`` Kconfig + * Added memory barrier to ticker transactions + * Added missing nRF53x Tx Power Kconfig + * Added support for Flush Timeout in Connected ISO + * Fixed BIS payload sliding window overrun check + * Fixed CIS Central FT calculation + * Fixed CIS Central error handling + * Fixed CIS assymmetric PHY usage + * Fixed CIS encryption when DF support enabled + * Fixed ISO-AL for quality tests and time stamps + * Fixed PHY value in HCI LE CIS Established Event + * Fixed ULL stuck in semaphore under rare conditions + * Fixed assertion due to late PER CIS active set + * Fixed compiler instruction re-ordering that caused assertions + * Fixed connected ISO dynamic tx power + * Fixed failing advertising conformance tests + * Fixed handling received Auxiliary PDUs when Coded PHY not supported + * Fixed leak in scheduled ticker node when rescheduling ticker nodes + * Fixed missing host feature reset + * Fixed nRF53 SoC back-to-back PDU chaining + * Fixed nRF53 SoC back-to-back Tx Rx implementation + * Fixed regression in Adv PDU overflow calculation + * Fixed regression in observer that caused assertions and scheduling stall + * Fixed use of pre-programmed PPI on nRF SoCs + * Removed HCI ISO data with invalid status in preparation for FT support + * Updated Extended Advertising Report to not be generated when ``AUX_ADV_IND`` not received + * Updated to have ``EVENT_OVERHEAD_START_US`` verbose assertion in each state/role LLL + * Updated to stop following ``aux_ptr`` if ``DATA_LEN_MAX`` is reached during extended scanning + * HCI Driver Boards & SoC Support From b640bbe1f77050d4e9865dea65e8ac36266bf672 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 18 Oct 2023 12:36:14 +0000 Subject: [PATCH 2062/4498] MAINTAINERS: add migration guide under "Release Notes" Release notes and migration guides go hand in hand right now, put the file under the "Release Notes" area and exclude it from the normal "Documentation" one. Signed-off-by: Fabio Baltieri --- MAINTAINERS.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 13bdf72abd0..74772a4d75b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -632,6 +632,7 @@ Documentation: - doc/templates/sample.tmpl - doc/templates/board.tmpl files-exclude: + - doc/releases/migration-guide-* - doc/releases/release-notes-* labels: - "area: Documentation" @@ -659,7 +660,10 @@ Release Notes: - jhedberg - fabiobaltieri files: + - doc/releases/migration-guide-* - doc/releases/release-notes-* + collaborators: + - kartben labels: - "Release Notes" From b3a52f4882fedd3c563cf185b413004ec56e936d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 17 Oct 2023 22:38:31 -0400 Subject: [PATCH 2063/4498] doc: Configure copybutton extension for ignoring shell prompts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add required settings for telling the copybutton Sphinx extension to ignore prompts when copying a code block. Both bash prompt and Zephyr UART prompt are ignored. Examples of the new behavior: .. code-block:: console $ echo "Hello World" Hello World The copied text will be: 'echo "Hello World"'. .. code-block:: console uart:~$ l2cap connect 29 Chan sec: 1 L2CAP connection pending Channel 0x20000210 connected Channel 0x20000210 status 1 uart:~$ l2cap send 3 14 Rem 2 Rem 1 Rem 0 Outgoing data channel 0x20000210 transmitted Outgoing data channel 0x20000210 transmitted Outgoing data channel 0x20000210 transmitted The copied text will be: 'l2cap connect 29\nl2cap send 3 14'. Signed-off-by: Benjamin Cabé --- doc/conf.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/conf.py b/doc/conf.py index 2785ec5438b..388ccd66015 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -313,6 +313,11 @@ "-Ecolor=gray60", ] +# -- Options for sphinx_copybutton ---------------------------------------- + +copybutton_prompt_text = r"\$ |uart:~\$ " +copybutton_prompt_is_regexp = True + # -- Linkcheck options ---------------------------------------------------- extlinks = { From d3487c48bf6b6f10f2f8d90d3ed9898032f01fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 18 Oct 2023 08:23:55 -0400 Subject: [PATCH 2064/4498] doc: Group linkcheck options together in conf.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Group all sections related to linkcheck target together. Signed-off-by: Benjamin Cabé --- doc/conf.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 388ccd66015..0ac0dd2bfd0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -200,12 +200,6 @@ ("index-tex", "zephyr.tex", "Zephyr Project Documentation", author, "manual"), ] -# -- Options for linkcheck ------------------------------------------------ - -linkcheck_ignore = [ - r"https://github.com/zephyrproject-rtos/zephyr/issues/.*" -] - # -- Options for zephyr.doxyrunner plugin --------------------------------- doxyrunner_doxygen = os.environ.get("DOXYGEN_EXECUTABLE", "doxygen") @@ -320,6 +314,10 @@ # -- Linkcheck options ---------------------------------------------------- +linkcheck_ignore = [ + r"https://github.com/zephyrproject-rtos/zephyr/issues/.*" +] + extlinks = { "github": ("https://github.com/zephyrproject-rtos/zephyr/issues/%s", "GitHub #%s"), } From a8493030580b1442cdfb6f69c38156c65178d41e Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Tue, 17 Oct 2023 12:32:13 +0900 Subject: [PATCH 2065/4498] doc: release: 3.5: Add note on RaspberryPi Pico related changes Adds notes on changes about rpi_pico Signed-off-by: TOKITA Hiroshi --- doc/releases/release-notes-3.5.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 9dd507b1219..8294cbc2b2d 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -274,6 +274,7 @@ Boards & SoC Support * i.MX RT SOCs no longer support CONFIG_OCRAM_NOCACHE, as this functionality can be achieved using devicetree memory regions * Refactored ESP32 SoC folders. So now these are a proper SoC series. + * RP2040: Changed to reset the I2C device on initializing * Added support for these ARC boards: @@ -316,6 +317,10 @@ Boards & SoC Support * ST morpho connector description was added on ST nucleo boards. + * rpi_pico: + + * The default adapter when debugging with openocd has been changed to cmsis-dap. + * Made these changes for ARM64 boards: * Made these changes for RISC-V boards: @@ -430,6 +435,8 @@ Drivers and Sensors * Added :kconfig:option:`CONFIG_COUNTER_RTC_STM32_SUBSECONDS` to enable subsecond as the basic time tick on STM32 RTC based counter driver. + * Added support for Raspberry Pi Pico Timer + * Crypto * DAC @@ -695,9 +702,12 @@ Drivers and Sensors * ``uart_emul``: added support for interrupt API. + * ``uart_rpi_pico``: fixed handling Modbus DE-RE signal + * SPI * Remove npcx spi driver implemented by Flash Interface Unit (FIU) module. + * Added support for Raspberry Pi Pico PIO based SPI. * Timer From 86bff1e0729989de1e615dd5fdf42300403f1354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 18 Oct 2023 09:35:41 -0400 Subject: [PATCH 2066/4498] doc: Render app commands with "shell" language MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'console' language in pygments is for Bash shell session, i.e code snippets were commands MUST start with a prompt. The commands rendered by the ZephyrAppCommandsDirective do not include a prompt, and should therefore be set as "shell". Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/application.py b/doc/_extensions/zephyr/application.py index 9369fb7becf..5d2b17f2f33 100644 --- a/doc/_extensions/zephyr/application.py +++ b/doc/_extensions/zephyr/application.py @@ -229,7 +229,7 @@ def _lit_block(self, content): # Create the nodes. literal = nodes.literal_block(content, content) self.add_name(literal) - literal['language'] = 'console' + literal['language'] = 'shell' return literal From d2c78faf7544fea0c753fcedf254c48767a28984 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 18 Oct 2023 16:17:39 +0300 Subject: [PATCH 2067/4498] doc: samples: smbus: Add console highlight to code block Display Zephyr console as 'code-block:: console'. Signed-off-by: Andrei Emeltchenko --- samples/drivers/smbus/README.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/samples/drivers/smbus/README.rst b/samples/drivers/smbus/README.rst index cd2e7ed90d1..28558247706 100644 --- a/samples/drivers/smbus/README.rst +++ b/samples/drivers/smbus/README.rst @@ -27,13 +27,17 @@ The sample can be built and run as follows for the ``qemu_x86_64`` board: Sample Output ************* -Output from console when application started:: +Output from console when application started: + +.. code-block:: console *** Booting Zephyr OS build zephyr-v3.2.0-804-gfedd72615e82 *** Start SMBUS shell sample qemu_x86_64 uart:~$ -List available SMBus shell commands with:: +List available SMBus shell commands with: + +.. code-block:: console uart:~$ smbus smbus - smbus commands @@ -59,7 +63,9 @@ List available SMBus shell commands with:: block_read :SMBus: Block Read command Usage: block_read -Scan for available SMBus devices with command:: +Scan for available SMBus devices with command: + +.. code-block:: console uart:~$ smbus scan smbus@fb00 0 1 2 3 4 5 6 7 8 9 a b c d e f From 4940a31b9e8b4467ea0989e1adfed4764f09df74 Mon Sep 17 00:00:00 2001 From: Yanfeng Liu Date: Wed, 18 Oct 2023 18:59:29 +0800 Subject: [PATCH 2068/4498] doc: hardware:porting:arch fix typo remove unnessary item break to fix XIP kernel case. Signed-off-by: Yanfeng Liu --- doc/hardware/porting/arch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/hardware/porting/arch.rst b/doc/hardware/porting/arch.rst index 9069db2ec73..0e31a62707b 100644 --- a/doc/hardware/porting/arch.rst +++ b/doc/hardware/porting/arch.rst @@ -59,7 +59,7 @@ Common steps for all architectures: * Setup an initial stack. * If running an :abbr:`XIP (eXecute-In-Place)` kernel, copy initialized data -* from ROM to RAM. + from ROM to RAM. * If not using an ELF loader, zero the BSS section. * Jump to :code:`_Cstart()`, the early kernel initialization From 70b49c7f5161d952cbff34c1d03405750c80a7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 18 Oct 2023 09:06:35 -0400 Subject: [PATCH 2069/4498] doc: build: Fix highlighting of code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set appropriate language for code blocks to show up with the right syntax highlighting. Signed-off-by: Benjamin Cabé --- doc/build/sysbuild/index.rst | 46 +++++++++++++++++------------- doc/build/version/index.rst | 4 +-- doc/build/zephyr_cmake_package.rst | 14 +++++---- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index e09ee3e5617..b66ec8938c7 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -104,21 +104,27 @@ As mentioned above, you can run sysbuild via ``west build`` or ``cmake``. .. tip:: To configure ``west build`` to use ``--sysbuild`` by default from now on, - run:: + run: - west config build.sysbuild True + .. code-block:: shell + + west config build.sysbuild True Since sysbuild supports both single- and multi-image builds, this lets you use sysbuild all the time, without worrying about what type of build you are running. - To turn this off, run this before generating your build system:: + To turn this off, run this before generating your build system: + + .. code-block:: shell + + west config build.sysbuild False - west config build.sysbuild False + To turn this off for just one ``west build`` command, run: - To turn this off for just one ``west build`` command, run:: + .. code-block:: shell - west build --no-sysbuild ... + west build --no-sysbuild ... .. group-tab:: ``cmake`` @@ -206,15 +212,15 @@ build system to the value ``BAR``, run the following commands: .. group-tab:: ``west build`` - :: + .. code-block:: shell west build --sysbuild ... -- -Dmy_sample_FOO=BAR .. group-tab:: ``cmake`` - :: + .. code-block:: shell - cmake -Dmy_sample_FOO=BAR ... + cmake -Dmy_sample_FOO=BAR ... .. _sysbuild_kconfig_namespacing: @@ -242,13 +248,13 @@ build system to the value ``BAR``, run the following commands: .. group-tab:: ``west build`` - :: + .. code-block:: shell west build --sysbuild ... -- -Dmy_sample_CONFIG_FOO=BAR .. group-tab:: ``cmake`` - :: + .. code-block:: shell cmake -Dmy_sample_CONFIG_FOO=BAR ... @@ -263,13 +269,13 @@ build system to the value ``BAR``, run the following commands: the same syntax for setting Kconfig values at CMake time. For example, the following commands will work in the same way: - :: + .. code-block:: shell - west build -b my_sample -- -DCONFIG_FOO=BAR + west build -b my_sample -- -DCONFIG_FOO=BAR - :: + .. code-block:: shell - west build -b --sysbuild my_sample -- -DCONFIG_FOO=BAR + west build -b --sysbuild my_sample -- -DCONFIG_FOO=BAR Sysbuild flashing using ``west flash`` ************************************** @@ -359,7 +365,7 @@ MCUboot whenever sysbuild is used: └── sysbuild.conf -.. code-block:: none +.. code-block:: cfg SB_CONFIG_BOOTLOADER_MCUBOOT=y @@ -432,7 +438,7 @@ target to execute and it will run. location, the ``rom_report`` build target for ``mcuboot`` can be ran with: - .. code-block:: bash + .. code-block:: shell west build -d build/mcuboot -t rom_report @@ -442,7 +448,7 @@ target to execute and it will run. using ``ninja`` using sysbuild with mcuboot enabled, the ``rom_report`` build target for ``mcuboot`` can be ran with: - .. code-block:: bash + .. code-block:: shell ninja -C mcuboot rom_report @@ -452,7 +458,7 @@ target to execute and it will run. using ``make`` using sysbuild with mcuboot enabled, the ``rom_report`` build target for ``mcuboot`` can be ran with: - .. code-block:: bash + .. code-block:: shell make -C mcuboot rom_report @@ -607,7 +613,7 @@ file or a devicetree overlay :file:`sysbuild/my_sample.overlay`. A Kconfig fragment could look as: -.. code-block:: none +.. code-block:: cfg # sysbuild/my_sample.conf CONFIG_FOO=n diff --git a/doc/build/version/index.rst b/doc/build/version/index.rst index de4e713c6b6..8d169a85bf5 100644 --- a/doc/build/version/index.rst +++ b/doc/build/version/index.rst @@ -26,7 +26,7 @@ which must be placed at the base directory of the application, where the CMakeLi located. This is a simple text file which contains the various version information fields, each on a newline. The basic ``VERSION`` file has the following structure: -.. code-block:: none +.. code-block:: cfg VERSION_MAJOR = VERSION_MINOR = @@ -58,7 +58,7 @@ manually re-ran for changes to this file. For the sections below, examples are provided for the following :file:`VERSION` file: -.. code-block:: none +.. code-block:: cfg VERSION_MAJOR = 1 VERSION_MINOR = 2 diff --git a/doc/build/zephyr_cmake_package.rst b/doc/build/zephyr_cmake_package.rst index fd8eeadd270..499765556bd 100644 --- a/doc/build/zephyr_cmake_package.rst +++ b/doc/build/zephyr_cmake_package.rst @@ -233,15 +233,17 @@ In case no Zephyr is found which satisfies the version required, as example, the find_package(Zephyr 2.z) project(app) -then an error similar to below will be printed:: +then an error similar to below will be printed: - Could not find a configuration file for package "Zephyr" that is compatible - with requested version "2.z". +.. code-block:: none + + Could not find a configuration file for package "Zephyr" that is compatible + with requested version "2.z". - The following configuration files were considered but not accepted: + The following configuration files were considered but not accepted: - /zephyr-workspace-2.a/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.a.0 - /zephyr-workspace-2.b/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.b.0 + /zephyr-workspace-2.a/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.a.0 + /zephyr-workspace-2.b/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.b.0 .. note:: It can also be beneficial to specify a version number for Zephyr repository applications From cfe667deb894a7f9cf67cfdae8a30824f59927e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 18 Oct 2023 09:24:45 -0400 Subject: [PATCH 2070/4498] doc: gsg: fix syntax highlighting of code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added explicit code blocks throughout the document. Removed several incorrect uses of "console" language where it should have been shell or bat. "console" is only for _bash_ sessions that include a prompt. Signed-off-by: Benjamin Cabé --- doc/develop/getting_started/index.rst | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 59f41a503d6..ae0e6ce535d 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -94,7 +94,9 @@ The current minimum required version for the main dependencies are: python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \ make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 - #. Verify the versions of the main dependencies installed on your system by entering:: + #. Verify the versions of the main dependencies installed on your system by entering: + + .. code-block:: bash cmake --version python3 --version @@ -153,13 +155,13 @@ The current minimum required version for the main dependencies are: #. Disable global confirmation to avoid having to confirm the installation of individual programs: - .. code-block:: console + .. code-block:: bat choco feature enable -n allowGlobalConfirmation #. Use ``choco`` to install the required dependencies: - .. code-block:: console + .. code-block:: bat choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' choco install ninja gperf python git dtc-msys2 wget 7zip @@ -246,7 +248,7 @@ additional Python dependencies. automatically load boilerplate code required for building Zephyr applications. - .. code-block:: console + .. code-block:: bash west zephyr-export @@ -280,7 +282,7 @@ additional Python dependencies. automatically load boilerplate code required for building Zephyr applications. - .. code-block:: console + .. code-block:: bash west zephyr-export @@ -336,7 +338,7 @@ additional Python dependencies. automatically load boilerplate code required for building Zephyr applications. - .. code-block:: console + .. code-block:: bash west zephyr-export @@ -367,7 +369,7 @@ additional Python dependencies. automatically load boilerplate code required for building Zephyr applications. - .. code-block:: console + .. code-block:: bash west zephyr-export @@ -411,13 +413,13 @@ additional Python dependencies. #. Install west: - .. code-block:: bash + .. code-block:: bat pip install west #. Get the Zephyr source code: - .. code-block:: bash + .. code-block:: bat west init zephyrproject cd zephyrproject @@ -427,14 +429,14 @@ additional Python dependencies. automatically load boilerplate code required for building Zephyr applications. - .. code-block:: console + .. code-block:: bat west zephyr-export #. Zephyr's ``scripts\requirements.txt`` file declares additional Python dependencies. Install them with ``pip``. - .. code-block:: bash + .. code-block:: bat pip install -r %HOMEPATH%\zephyrproject\zephyr\scripts\requirements.txt @@ -599,14 +601,14 @@ that are used to emulate, flash and debug Zephyr applications. #. Download the `Zephyr SDK bundle `_: - .. code-block:: console + .. code-block:: bat cd %HOMEPATH% wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z #. Extract the Zephyr SDK bundle archive: - .. code-block:: console + .. code-block:: bat 7z x zephyr-sdk-0.16.3_windows-x86_64.7z @@ -622,7 +624,7 @@ that are used to emulate, flash and debug Zephyr applications. #. Run the Zephyr SDK bundle setup script: - .. code-block:: console + .. code-block:: bat cd zephyr-sdk-0.16.3 setup.cmd @@ -686,7 +688,7 @@ If in doubt about what to do, check your board's page in :ref:`boards`. Then flash the sample using :ref:`west flash `: -.. code-block:: console +.. code-block:: shell west flash From 47385a93ab35ec68f138cca50ae6c6c20380a0f3 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Wed, 18 Oct 2023 18:11:45 +0100 Subject: [PATCH 2071/4498] doc: add release-notes for ARC architecture and platforms Add release notes for ARC for 3.5 release Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- doc/releases/release-notes-3.5.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 8294cbc2b2d..bf335ae6e15 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -66,6 +66,15 @@ Architectures * ARC + * Introduced the scalar ARC VPX CPUs port + * Introduced support for ARCv3 HS (both 32 and 64 bit) SMP platforms with up to 12 CPU cores + * Reworked GNU helper tools usage for ARC MWDT toolchain. Now helper tools can be used from + Zephyr SDK (if SDK is installed) + * Fixed dynamic thread stack allocation + * Fixed STR assembly macro offset calculation issue which may cause build error for ARCv3 64bit + * Cleaned-up and made more user friendly handling of the ARC MWDT toolchain path + (ARCMWDT_TOOLCHAIN_PATH) + * ARM * Architectural support for Arm Cortex-M has been separated from Arm @@ -278,6 +287,13 @@ Boards & SoC Support * Added support for these ARC boards: + * Added support for nsim_vpx5 - simulation (nSIM) platform with ARCv2 VPX5 core, close to + vpx5_integer_full template + * Added support for nsim_hs5x_smp_12cores - simulation (nSIM) platform with 12 cores SMP 32-bit + ARCv3 HS + * Added support for nsim_hs6x_smp_12cores - simulation (nSIM) platform with 12 cores SMP 64-bit + ARCv3 HS + * Added support for these ARM boards: * Nuvoton NuMaker Platform M467 @@ -313,6 +329,9 @@ Boards & SoC Support * Made these changes for ARC boards: + * Turned off unsupported stack checking option for hsdk4xd platform + * Changed vendor prefix for ARC QEMU platforms from "qemu" to "snps" + * Made these changes for ARM boards: * ST morpho connector description was added on ST nucleo boards. From 6076d54d079ca6a3f40f191f826e9bd0b620a0ec Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Wed, 18 Oct 2023 21:15:34 +0100 Subject: [PATCH 2072/4498] doc: release-notes: arc: reword VPX part Reword VPX part as was requested by @abrodkin Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- doc/releases/release-notes-3.5.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index bf335ae6e15..4064b0097da 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -66,7 +66,7 @@ Architectures * ARC - * Introduced the scalar ARC VPX CPUs port + * Introduced the scalar port for ARC VPX processors * Introduced support for ARCv3 HS (both 32 and 64 bit) SMP platforms with up to 12 CPU cores * Reworked GNU helper tools usage for ARC MWDT toolchain. Now helper tools can be used from Zephyr SDK (if SDK is installed) From 19912af70d02a50355a1089cb08a981010c7ff83 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Wed, 18 Oct 2023 18:18:31 +0100 Subject: [PATCH 2073/4498] board: nsim: doc: fix typo in platform name Fix typo in nsim_hs6x_smp_12cores platform name (as previously we had nsim_hs5x_smp_12cores platform mentioned two times) Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/nsim/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arc/nsim/doc/index.rst b/boards/arc/nsim/doc/index.rst index 64f6f4666f4..4e7054fc43b 100644 --- a/boards/arc/nsim/doc/index.rst +++ b/boards/arc/nsim/doc/index.rst @@ -34,7 +34,7 @@ available configurations are listed below: * ``nsim_hs5x`` - 32-bit ARCv3 HS core with rich set of options * ``nsim_hs6x`` - 64-bit ARCv3 HS core with rich set of options * ``nsim_hs5x_smp_12cores`` - SMP 12 cores 32-bit ARCv3 HS platform -* ``nsim_hs5x_smp_12cores`` - SMP 12 cores 64-bit ARCv3 HS platform +* ``nsim_hs6x_smp_12cores`` - SMP 12 cores 64-bit ARCv3 HS platform .. _board_arc_nsim_prop_args_files: From 69fd128771e3d13933254f46eda88d7a715d8a44 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 17 Oct 2023 12:59:32 -0400 Subject: [PATCH 2074/4498] doc: add sections to migration guide Add sections to the migration guide to make it easier to spot and follow suggestions of specific areas. Signed-off-by: Anas Nashif --- doc/releases/migration-guide-3.5.rst | 230 +++++++++++++++------------ 1 file changed, 129 insertions(+), 101 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 1fec9c41dc1..72c133ab7b8 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -11,6 +11,9 @@ application from Zephyr v3.4.0 to Zephyr v3.5.0. Required changes **************** +Kernel +====== + * The kernel :c:func:`k_mem_slab_free` function has changed its signature, now taking a ``void *mem`` pointer instead of a ``void **mem`` double-pointer. The new signature will not immediately trigger a compiler error or warning, @@ -19,40 +22,23 @@ Required changes detect if you pass the function memory not belonging to the memory blocks in the slab. -* The :kconfig:option:`CONFIG_BOOTLOADER_SRAM_SIZE` default value is now ``0`` (was - ``16``). Bootloaders that use a part of the SRAM should set this value to an - appropriate size. :github:`60371` - -* The Kconfig option ``CONFIG_GPIO_NCT38XX_INTERRUPT`` has been renamed to - :kconfig:option:`CONFIG_GPIO_NCT38XX_ALERT`. - -* MCUmgr SMP version 2 error codes entry has changed due to a collision with an - existing response in shell_mgmt. Previously, these errors had the entry ``ret`` - but now have the entry ``err``. ``smp_add_cmd_ret()`` is now deprecated and - :c:func:`smp_add_cmd_err` should be used instead, ``MGMT_CB_ERROR_RET`` is - now deprecated and :c:enumerator:`MGMT_CB_ERROR_ERR` should be used instead. - SMP version 2 error code defines for in-tree modules have been updated to - replace the ``*_RET_RC_*`` parts with ``*_ERR_*``. - -* MCUmgr SMP version 2 error translation (to legacy MCUmgr error code) is now - handled in function handlers by setting the ``mg_translate_error`` function - pointer of :c:struct:`mgmt_group` when registering a group. See - :c:type:`smp_translate_error_fn` for function details. Any SMP version 2 - handlers made for Zephyr 3.4 need to be updated to include these translation - functions when the groups are registered. +* :c:macro:`CONTAINER_OF` now performs type checking, this was very commonly + misused to obtain user structure from :c:struct:`k_work` pointers without + passing from :c:struct:`k_work_delayable`. This would now result in a build + error and have to be done correctly using + :c:func:`k_work_delayable_from_work`. -* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` and its type - moved from 'enum' to 'int'. To have a seamless conversion this is the - required change in the DT: +Bluetooth +========= - .. code-block:: none +* The ``accept()`` callback's signature in :c:struct:`bt_l2cap_server` has + changed to ``int (*accept)(struct bt_conn *conn, struct bt_l2cap_server + *server, struct bt_l2cap_chan **chan)``, + adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` + structure instance the callback relates to. :github:`60536` - - "RAM" -> <( DT_MEM_ARM(ATTR_MPU_RAM) )> - - "RAM_NOCACHE" -> <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )> - - "FLASH" -> <( DT_MEM_ARM(ATTR_MPU_FLASH) )> - - "PPB" -> <( DT_MEM_ARM(ATTR_MPU_PPB) )> - - "IO" -> <( DT_MEM_ARM(ATTR_MPU_IO) )> - - "EXTMEM" -> <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )> +Networking +========== * A new networking Kconfig option :kconfig:option:`CONFIG_NET_INTERFACE_NAME` defaults to ``y``. The option allows user to set a name to a network interface. @@ -64,11 +50,29 @@ Required changes If the Kconfig option is set to ``y`` (current default), then the network interface name is used by the ``SO_BINDTODEVICE`` socket option. -* On all STM32 ADC, it is no longer possible to read sensor channels (Vref, - Vbat or temperature) using the ADC driver. The dedicated sensor driver should - be used instead. This change is due to a limitation on STM32F4 where the - channels for temperature and Vbat are identical, and the impossibility of - determining what we want to measure using solely the ADC API. +* Ethernet PHY devicetree bindings were updated to use the standard ``reg`` + property for the PHY address instead of a custom ``address`` property. As a + result, MDIO controller nodes now require ``#address-cells`` and + ``#size-cells`` properties. Similarly, Ethernet PHY devicetree nodes and + corresponding driver were updated to consistently use the node name + ``ethernet-phy`` instead of ``phy``. Devicetrees and overlays must be updated + accordingly: + + .. code-block:: devicetree + + mdio { + compatible = "mdio-controller"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + }; + }; + +C Library +========= * The default C library used on most targets has changed from the built-in minimal C library to Picolibc. While both provide standard C library @@ -115,6 +119,9 @@ Required changes to a smaller, but inexact conversion algorithm. This requires building Picolibc as a module. +CAN Controller +============== + * The CAN controller timing API functions :c:func:`can_set_timing` and :c:func:`can_set_timing_data` no longer fallback to the (Re-)Synchronization Jump Width (SJW) value set in the devicetree properties for the given CAN controller upon encountering an SJW value corresponding to @@ -135,32 +142,32 @@ Required changes The two new flags :c:macro:`ISOTP_MSG_FDF` and :c:macro:`ISOTP_MSG_BRS` were added for CAN FD mode. -* Ethernet PHY devicetree bindings were updated to use the standard ``reg`` - property for the PHY address instead of a custom ``address`` property. As a - result, MDIO controller nodes now require ``#address-cells`` and - ``#size-cells`` properties. Similarly, Ethernet PHY devicetree nodes and - corresponding driver were updated to consistently use the node name - ``ethernet-phy`` instead of ``phy``. Devicetrees and overlays must be updated - accordingly: +Device Drivers and Device Tree +============================== - .. code-block:: devicetree +* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` and its type + moved from 'enum' to 'int'. To have a seamless conversion this is the + required change in the DT: - mdio { - compatible = "mdio-controller"; - #address-cells = <1>; - #size-cells = <0>; + .. code-block:: none - ethernet-phy@0 { - compatible = "ethernet-phy"; - reg = <0>; - }; - }; + - "RAM" -> <( DT_MEM_ARM(ATTR_MPU_RAM) )> + - "RAM_NOCACHE" -> <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )> + - "FLASH" -> <( DT_MEM_ARM(ATTR_MPU_FLASH) )> + - "PPB" -> <( DT_MEM_ARM(ATTR_MPU_PPB) )> + - "IO" -> <( DT_MEM_ARM(ATTR_MPU_IO) )> + - "EXTMEM" -> <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )> -* The ``accept()`` callback's signature in :c:struct:`bt_l2cap_server` has - changed to ``int (*accept)(struct bt_conn *conn, struct bt_l2cap_server - *server, struct bt_l2cap_chan **chan)``, - adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` - structure instance the callback relates to. :github:`60536` +* Device dependencies (incorrectly referred as "device handles" in some areas) + are now an optional feature enabled by :kconfig:option:`CONFIG_DEVICE_DEPS`. + This means that an extra linker stage is no longer necessary if this option is + not enabled. + +* On all STM32 ADC, it is no longer possible to read sensor channels (Vref, + Vbat or temperature) using the ADC driver. The dedicated sensor driver should + be used instead. This change is due to a limitation on STM32F4 where the + channels for temperature and Vbat are identical, and the impossibility of + determining what we want to measure using solely the ADC API. * The RAM disk driver has been changed to support multiple instances and instantiation using devicetree. As a result, Kconfig option :kconfig:option:`CONFIG_DISK_RAM_VOLUME_SIZE` @@ -188,12 +195,6 @@ Required changes :dtcompatible:`gpio-keys` and the callback definition has been renamed from ``INPUT_LISTENER_CB_DEFINE`` to :c:macro:`INPUT_CALLBACK_DEFINE`. -* :c:macro:`CONTAINER_OF` now performs type checking, this was very commonly - misused to obtain user structure from :c:struct:`k_work` pointers without - passing from :c:struct:`k_work_delayable`. This would now result in a build - error and have to be done correctly using - :c:func:`k_work_delayable_from_work`. - * The :dtcompatible:`ti,bq274xx` driver was using incorrect units for capacity and power channels, these have been fixed and scaled by x1000 factor from the previous implementation, any application using them has to be changed @@ -216,35 +217,11 @@ Required changes * ``CONFIG_SSD1306_REVERSE_MODE`` is now set using the ``inversion-on`` property of the devicetree node. - * GPIO drivers not implementing IRQ related operations must now provide ``NULL`` to the relevant operations: ``pin_interrupt_configure``, ``manage_callback``, ``get_pending_int``. The public API will return ``-ENOSYS`` when these are not available, instead of ``-ENOTSUP``. -* Platforms that implement power management hooks must explicitly select - :kconfig:option:`CONFIG_HAS_PM` in Kconfig. This is now a dependency of - :kconfig:option:`CONFIG_PM`. Before this change all platforms could enable - :kconfig:option:`CONFIG_PM` because empty weak stubs were provided, however, - this is no longer supported. As a result of this change, power management - hooks are no longer defined as weaks. - -* Multiple platforms no longer support powering the system off using - :c:func:`pm_state_force`. The new :c:func:`sys_poweroff` API must be used. - Migrated platforms include Nordic nRF, STM32, ESP32 and TI CC13XX/26XX. The - new API is independent from :kconfig:option:`CONFIG_PM`. It requires - :kconfig:option:`CONFIG_POWEROFF` to be enabled, which depends on - :kconfig:option:`CONFIG_HAS_POWEROFF`, an option selected by platforms - implementing the required new hooks. - -* ARM SoC initialization routines no longer need to call `NMI_INIT()`. The - macro call has been removed as it was not doing anything useful. - -* Device dependencies (incorrectly referred as "device handles" in some areas) - are now an optional feature enabled by :kconfig:option:`CONFIG_DEVICE_DEPS`. - This means that an extra linker stage is no longer necessary if this option is - not enabled. - * STM32 Ethernet driver was misusing :c:func:`hwinfo_get_device_id` to generate last 3 bytes of mac address, resulting in a high risk of collision when using SoCs from the same lot. This is now fixed to use the whole range of entropy @@ -267,10 +244,61 @@ Required changes <&rcc STM32_SRC_HSI ADC_SEL(2)>; }; +* On NXP boards with LPC DMA, the DMA controller node used to have its ``dma-channels`` property + set in the board DTS as a way to configure the amount of structures the driver will allocate. + This did not match the zephyr dma-controller binding, so this property is now fixed and set + in the SOC devicetree definition. Downstream boards should not override this property and + instead use the new driver Kconfig + :kconfig:option:`CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED`. + +* The LPC55XXX series SOC (except LPC55S06) default main clock has been + updated to PLL1 source from XTAL32K running at 144MHZ. If the new + kconfig option :kconfig:option:`CONFIG_INIT_PLL1` + is disabled then the main clock is muxed to FRO_HR as before. + +* The Kconfig option ``CONFIG_GPIO_NCT38XX_INTERRUPT`` has been renamed to + :kconfig:option:`CONFIG_GPIO_NCT38XX_ALERT`. + +Power Management +================ + +* Platforms that implement power management hooks must explicitly select + :kconfig:option:`CONFIG_HAS_PM` in Kconfig. This is now a dependency of + :kconfig:option:`CONFIG_PM`. Before this change all platforms could enable + :kconfig:option:`CONFIG_PM` because empty weak stubs were provided, however, + this is no longer supported. As a result of this change, power management + hooks are no longer defined as weaks. + +* Multiple platforms no longer support powering the system off using + :c:func:`pm_state_force`. The new :c:func:`sys_poweroff` API must be used. + Migrated platforms include Nordic nRF, STM32, ESP32 and TI CC13XX/26XX. The + new API is independent from :kconfig:option:`CONFIG_PM`. It requires + :kconfig:option:`CONFIG_POWEROFF` to be enabled, which depends on + :kconfig:option:`CONFIG_HAS_POWEROFF`, an option selected by platforms + implementing the required new hooks. + +Bootloader +========== + +* The :kconfig:option:`CONFIG_BOOTLOADER_SRAM_SIZE` default value is now ``0`` (was + ``16``). Bootloaders that use a part of the SRAM should set this value to an + appropriate size. :github:`60371` + +ARM +==== + +* ARM SoC initialization routines no longer need to call `NMI_INIT()`. The + macro call has been removed as it was not doing anything useful. + +RISC V +====== * The :kconfig:option:`CONFIG_RISCV_MTVEC_VECTORED_MODE` Kconfig option was renamed to :kconfig:option:`CONFIG_RISCV_VECTORED_MODE`. +Subsystems +========== + * ZBus runtime observers implementation now relies on the HEAP memory instead of a memory slab. Thus, zbus' configuration (kconfig) related to runtime observers has changed. To keep your runtime observers code working correctly, you need to: @@ -282,20 +310,20 @@ Required changes * The zbus VDED delivery sequence has changed. Check the :ref:`documentation` to verify if it will affect your code. -* On NXP boards with LPC DMA, the DMA controller node used to have its ``dma-channels`` property - set in the board DTS as a way to configure the amount of structures the driver will allocate. - This did not match the zephyr dma-controller binding, so this property is now fixed and set - in the SOC devicetree definition. Downstream boards should not override this property and - instead use the new driver Kconfig - :kconfig:option:`CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED`. - -* :c:func:`pm_state_set` and :c:func:`pm_exit_post_ops` are mandatory now - for any platform supporting power management. +* MCUmgr SMP version 2 error codes entry has changed due to a collision with an + existing response in shell_mgmt. Previously, these errors had the entry ``ret`` + but now have the entry ``err``. ``smp_add_cmd_ret()`` is now deprecated and + :c:func:`smp_add_cmd_err` should be used instead, ``MGMT_CB_ERROR_RET`` is + now deprecated and :c:enumerator:`MGMT_CB_ERROR_ERR` should be used instead. + SMP version 2 error code defines for in-tree modules have been updated to + replace the ``*_RET_RC_*`` parts with ``*_ERR_*``. -* The LPC55XXX series SOC (except LPC55S06) default main clock has been - updated to PLL1 source from XTAL32K running at 144MHZ. If the new - kconfig option :kconfig:option:`CONFIG_INIT_PLL1` - is disabled then the main clock is muxed to FRO_HR as before. +* MCUmgr SMP version 2 error translation (to legacy MCUmgr error code) is now + handled in function handlers by setting the ``mg_translate_error`` function + pointer of :c:struct:`mgmt_group` when registering a group. See + :c:type:`smp_translate_error_fn` for function details. Any SMP version 2 + handlers made for Zephyr 3.4 need to be updated to include these translation + functions when the groups are registered. Recommended Changes ******************* From 1465c75483ae0e7a68dbf7989a33697fc6238481 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 10:56:56 +0300 Subject: [PATCH 2075/4498] doc: release: 3.5: Add information for new x86 boards Mention ISH and Intel Alder Lake which which were added for 3.5. Signed-off-by: Johan Hedberg --- doc/releases/release-notes-3.5.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 4064b0097da..b11eebc82c2 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -100,6 +100,11 @@ Architectures * Added basic MMU v2 Support. +* x86 + + * Added support for Intel Alder Lake boards + * Added support for Intel Sensor Hub (ISH) + * POSIX * Has been reworked to use the native simulator. From 3e22bb332d95fc3bdc7eb8c8081987dcd2e7f8fc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 10:57:55 +0300 Subject: [PATCH 2076/4498] doc: release: 3.5: Mention ACPICA library ACPI support was enhanced for 3.5 by adopting the ACPICA library as a new module. Signed-off-by: Johan Hedberg --- doc/releases/release-notes-3.5.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b11eebc82c2..30dac07d67b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -625,6 +625,10 @@ Drivers and Sensors * Added support to get IRQ from ACPI PCI Routing Table (PRT). +* ACPI + + * Adopted the ACPICA library as a new module to further enhance ACPI support. + * PECI * Pin control From 75860cd49a7cb41bd4cc1dff23cd1574ab438046 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 11:25:03 +0300 Subject: [PATCH 2077/4498] doc: release: 3.5: Provide a link to the migration guide Add a reference from the release notes to the migration guide. Signed-off-by: Johan Hedberg --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 30dac07d67b..c8926027154 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -11,6 +11,9 @@ Major enhancements with this release include: * Added native_sim (successor to native_posix) +An overview of the changes required or recommended when migrating your application from Zephyr +v3.4.0 to Zephyr v3.5.0 can be found in the separate :ref:`migration guide`. + The following sections provide detailed lists of changes by component. Security Vulnerability Related From 7842fd9e4ffbc1f15d117f1485b42a69af1b1812 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 13:44:34 +0300 Subject: [PATCH 2078/4498] doc: migration-guide: Remove extra backtick Remove an extra backtick character. Signed-off-by: Johan Hedberg --- doc/releases/migration-guide-3.5.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 72c133ab7b8..daa13999fbf 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -360,7 +360,7 @@ Recommended Changes Instead the new :kconfig:option:`CONFIG_MODEM_CELLULAR` driver should be used. As part of this :kconfig:option:`CONFIG_GSM_MUX` and :kconfig:option:`CONFIG_UART_MUX` are being marked as deprecated as well. The new modem subsystem :kconfig:option:`CONFIG_MODEM_CMUX` - and :kconfig:option:`CONFIG_MODEM_PPP`` should be used instead. + and :kconfig:option:`CONFIG_MODEM_PPP` should be used instead. * Device drivers should now be restricted to ``PRE_KERNEL_1``, ``PRE_KERNEL_2`` and ``POST_KERNEL`` initialization levels. Other device initialization levels, From 76757a6bf012691691828d7a667459e96387a305 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 13:55:18 +0300 Subject: [PATCH 2079/4498] doc: migration-guide: Add a link to the release notes Add a link to the 3.5 release notes from the migration guide. Signed-off-by: Johan Hedberg --- doc/releases/migration-guide-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index daa13999fbf..b74f9f2930d 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -8,6 +8,9 @@ Migration guide to Zephyr v3.5.0 (Working Draft) This document describes the changes required or recommended when migrating your application from Zephyr v3.4.0 to Zephyr v3.5.0. +Any other changes (not directly related to migrating applications) can be found in +the :ref:`release notes`. + Required changes **************** From 6f7f80fe8af9261278b1ded7d28c717b83cb755d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 14:21:56 +0300 Subject: [PATCH 2080/4498] doc: migration-guide: Reorder the sections more logically Reorder the sections so that the core/wide impact ones come first (e.g. Kernel and C-Library) and more specific ones (e.g. architectures) come last. Signed-off-by: Johan Hedberg --- doc/releases/migration-guide-3.5.rst | 149 +++++++++++++-------------- 1 file changed, 73 insertions(+), 76 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index b74f9f2930d..7f4e0701c77 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -31,49 +31,6 @@ Kernel error and have to be done correctly using :c:func:`k_work_delayable_from_work`. -Bluetooth -========= - -* The ``accept()`` callback's signature in :c:struct:`bt_l2cap_server` has - changed to ``int (*accept)(struct bt_conn *conn, struct bt_l2cap_server - *server, struct bt_l2cap_chan **chan)``, - adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` - structure instance the callback relates to. :github:`60536` - -Networking -========== - -* A new networking Kconfig option :kconfig:option:`CONFIG_NET_INTERFACE_NAME` - defaults to ``y``. The option allows user to set a name to a network interface. - During system startup a default name is assigned to the network interface like - ``eth0`` to the first Ethernet network interface. The option affects the behavior - of ``SO_BINDTODEVICE`` BSD socket option. If the Kconfig option is set to ``n``, - which is how the system worked earlier, then the name of the device assigned - to the network interface is used by the ``SO_BINDTODEVICE`` socket option. - If the Kconfig option is set to ``y`` (current default), then the network - interface name is used by the ``SO_BINDTODEVICE`` socket option. - -* Ethernet PHY devicetree bindings were updated to use the standard ``reg`` - property for the PHY address instead of a custom ``address`` property. As a - result, MDIO controller nodes now require ``#address-cells`` and - ``#size-cells`` properties. Similarly, Ethernet PHY devicetree nodes and - corresponding driver were updated to consistently use the node name - ``ethernet-phy`` instead of ``phy``. Devicetrees and overlays must be updated - accordingly: - - .. code-block:: devicetree - - mdio { - compatible = "mdio-controller"; - #address-cells = <1>; - #size-cells = <0>; - - ethernet-phy@0 { - compatible = "ethernet-phy"; - reg = <0>; - }; - }; - C Library ========= @@ -122,29 +79,6 @@ C Library to a smaller, but inexact conversion algorithm. This requires building Picolibc as a module. -CAN Controller -============== - -* The CAN controller timing API functions :c:func:`can_set_timing` and :c:func:`can_set_timing_data` - no longer fallback to the (Re-)Synchronization Jump Width (SJW) value set in the devicetree - properties for the given CAN controller upon encountering an SJW value corresponding to - ``CAN_SJW_NO_CHANGE`` (which is no longer available). The caller will therefore need to fill in - the ``sjw`` field in :c:struct:`can_timing`. To aid in this, the :c:func:`can_calc_timing` and - :c:func:`can_calc_timing_data` functions now automatically calculate a suitable SJW. The - calculated SJW can be overwritten by the caller if needed. The CAN controller API functions - :c:func:`can_set_bitrate` and :c:func:`can_set_bitrate_data` now also automatically calculate a - suitable SJW, but their SJW cannot be overwritten by the caller. - -* The CAN ISO-TP message configuration in :c:struct:`isotp_msg_id` is changed to use the following - flags instead of bit fields: - - * :c:macro:`ISOTP_MSG_EXT_ADDR` to enable ISO-TP extended addressing - * :c:macro:`ISOTP_MSG_FIXED_ADDR` to enable ISO-TP fixed addressing - * :c:macro:`ISOTP_MSG_IDE` to use extended (29-bit) CAN IDs - - The two new flags :c:macro:`ISOTP_MSG_FDF` and :c:macro:`ISOTP_MSG_BRS` were added for CAN FD - mode. - Device Drivers and Device Tree ============================== @@ -262,6 +196,26 @@ Device Drivers and Device Tree * The Kconfig option ``CONFIG_GPIO_NCT38XX_INTERRUPT`` has been renamed to :kconfig:option:`CONFIG_GPIO_NCT38XX_ALERT`. +* The CAN controller timing API functions :c:func:`can_set_timing` and :c:func:`can_set_timing_data` + no longer fallback to the (Re-)Synchronization Jump Width (SJW) value set in the devicetree + properties for the given CAN controller upon encountering an SJW value corresponding to + ``CAN_SJW_NO_CHANGE`` (which is no longer available). The caller will therefore need to fill in + the ``sjw`` field in :c:struct:`can_timing`. To aid in this, the :c:func:`can_calc_timing` and + :c:func:`can_calc_timing_data` functions now automatically calculate a suitable SJW. The + calculated SJW can be overwritten by the caller if needed. The CAN controller API functions + :c:func:`can_set_bitrate` and :c:func:`can_set_bitrate_data` now also automatically calculate a + suitable SJW, but their SJW cannot be overwritten by the caller. + +* The CAN ISO-TP message configuration in :c:struct:`isotp_msg_id` is changed to use the following + flags instead of bit fields: + + * :c:macro:`ISOTP_MSG_EXT_ADDR` to enable ISO-TP extended addressing + * :c:macro:`ISOTP_MSG_FIXED_ADDR` to enable ISO-TP fixed addressing + * :c:macro:`ISOTP_MSG_IDE` to use extended (29-bit) CAN IDs + + The two new flags :c:macro:`ISOTP_MSG_FDF` and :c:macro:`ISOTP_MSG_BRS` were added for CAN FD + mode. + Power Management ================ @@ -287,20 +241,51 @@ Bootloader ``16``). Bootloaders that use a part of the SRAM should set this value to an appropriate size. :github:`60371` -ARM -==== +Bluetooth +========= -* ARM SoC initialization routines no longer need to call `NMI_INIT()`. The - macro call has been removed as it was not doing anything useful. +* The ``accept()`` callback's signature in :c:struct:`bt_l2cap_server` has + changed to ``int (*accept)(struct bt_conn *conn, struct bt_l2cap_server + *server, struct bt_l2cap_chan **chan)``, + adding a new ``server`` parameter pointing to the :c:struct:`bt_l2cap_server` + structure instance the callback relates to. :github:`60536` -RISC V -====== +Networking +========== -* The :kconfig:option:`CONFIG_RISCV_MTVEC_VECTORED_MODE` Kconfig option was renamed to - :kconfig:option:`CONFIG_RISCV_VECTORED_MODE`. +* A new networking Kconfig option :kconfig:option:`CONFIG_NET_INTERFACE_NAME` + defaults to ``y``. The option allows user to set a name to a network interface. + During system startup a default name is assigned to the network interface like + ``eth0`` to the first Ethernet network interface. The option affects the behavior + of ``SO_BINDTODEVICE`` BSD socket option. If the Kconfig option is set to ``n``, + which is how the system worked earlier, then the name of the device assigned + to the network interface is used by the ``SO_BINDTODEVICE`` socket option. + If the Kconfig option is set to ``y`` (current default), then the network + interface name is used by the ``SO_BINDTODEVICE`` socket option. -Subsystems -========== +* Ethernet PHY devicetree bindings were updated to use the standard ``reg`` + property for the PHY address instead of a custom ``address`` property. As a + result, MDIO controller nodes now require ``#address-cells`` and + ``#size-cells`` properties. Similarly, Ethernet PHY devicetree nodes and + corresponding driver were updated to consistently use the node name + ``ethernet-phy`` instead of ``phy``. Devicetrees and overlays must be updated + accordingly: + + .. code-block:: devicetree + + mdio { + compatible = "mdio-controller"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + }; + }; + +Other Subsystems +================ * ZBus runtime observers implementation now relies on the HEAP memory instead of a memory slab. Thus, zbus' configuration (kconfig) related to runtime observers has changed. To keep your runtime @@ -328,6 +313,18 @@ Subsystems handlers made for Zephyr 3.4 need to be updated to include these translation functions when the groups are registered. +ARM +=== + +* ARM SoC initialization routines no longer need to call `NMI_INIT()`. The + macro call has been removed as it was not doing anything useful. + +RISC V +====== + +* The :kconfig:option:`CONFIG_RISCV_MTVEC_VECTORED_MODE` Kconfig option was renamed to + :kconfig:option:`CONFIG_RISCV_VECTORED_MODE`. + Recommended Changes ******************* From 7e5b4219db7c3cfa206f72e2133a6fbb5be87b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 19 Oct 2023 16:31:24 +0200 Subject: [PATCH 2081/4498] doc: release: Add v3.5 notes for ADC, I2S, PWM, and Nordic HAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add release notes for ADC, I2S, and PWM drivers, and for Nordic HAL. Signed-off-by: Andrzej Głąbek --- doc/releases/release-notes-3.5.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c8926027154..b67c1d1ad11 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -441,6 +441,12 @@ Drivers and Sensors option. * Added support for the ADC sequencer for all STM32 series (except F1) * Fixed STM32F4 ADC temperature and Vbat measurement. + * Added driver for TI ADS1112. + * Added driver for TI TLA2021. + * Added driver for Gecko ADC. + * Added driver for NXP S32 ADC SAR. + * Added driver for MAX1125x family. + * Added driver for MAX11102-MAX1117. * Battery-backed RAM @@ -557,6 +563,8 @@ Drivers and Sensors * I2S + * Fixed handling of the PCM data format in the NXP MCUX driver. + * I3C * ``i3c_cdns``: @@ -641,6 +649,16 @@ Drivers and Sensors * PWM * Added 4 channels capture on STM32 PWM driver. + * Added driver for Intel Blinky PWM. + * Added driver for MAX31790. + * Added driver for Infineon XMC4XXX CCU4. + * Added driver for Infineon XMC4XXX CCU8. + * Added MCUX CTimer based PWM driver. + * Added PWM driver based on TI CC13xx/CC26xx GPT timer. + * Reworked the pwm_nrf5_sw driver so that it can be used also on nRF53 and + nRF91 Series. Consequently, the driver was renamed to pwm_nrf_sw. + * Added driver for Nuvoton NuMaker family. + * Added PWM driver based on NXP S32 EMIOS peripheral. * Power domain @@ -1120,6 +1138,10 @@ Libraries / Subsystems HALs **** +* Nordic + + * Updated nrfx to version 3.1.0. + * Nuvoton * Added Nuvoton NuMaker M46x From 7d32b552d080f52c35e72337ef704137356d77b1 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 19 Oct 2023 09:51:01 -0500 Subject: [PATCH 2082/4498] docs: migration-guide-3.5: add changes for i.MX RT boards Add migration guide notes for i.MX RT boards, including the following changes: - i.MX RT boards must now manually enable CONFIG_DEVICE_CONFIGURATION_DATA and CONFIG_NXP_IMX_EXTERNAL_SDRAM when required - SNVS pin names have changed for i.MX RT11xx series boards Signed-off-by: Daniel DeGrasse --- doc/releases/migration-guide-3.5.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 7f4e0701c77..4165d1d4b48 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -216,6 +216,17 @@ Device Drivers and Device Tree The two new flags :c:macro:`ISOTP_MSG_FDF` and :c:macro:`ISOTP_MSG_BRS` were added for CAN FD mode. +* NXP i.MX RT based boards should now enable + :kconfig:option:`CONFIG_DEVICE_CONFIGURATION_DATA` at the board level when + using a DCD with the RT bootrom, and enable + :kconfig:option:`CONFIG_NXP_IMX_EXTERNAL_SDRAM` when using external SDRAM + via the SEMC + +* NXP i.MX RT11xx series SNVS pin control name identifiers have been updated to + match with the source data for these SOCs. The pin names have had the + suffix ``dig`` added. For example, ``iomuxc_snvs_wakeup_gpio13_io00`` has + been renamed to ``iomuxc_snvs_wakeup_dig_gpio13_io00`` + Power Management ================ From 11374943c453e85e19559720fcc183c4245f3e3d Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Thu, 19 Oct 2023 11:36:58 +0200 Subject: [PATCH 2083/4498] boards: arm: disco_l475_iot1: add stm32cubeprogrammer add stm32cubeprogrammer runner for disco_l475_iot1 boards Signed-off-by: Marc Desvaux --- boards/arm/disco_l475_iot1/board.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arm/disco_l475_iot1/board.cmake b/boards/arm/disco_l475_iot1/board.cmake index e38b92214d9..7e6faf6c383 100644 --- a/boards/arm/disco_l475_iot1/board.cmake +++ b/boards/arm/disco_l475_iot1/board.cmake @@ -1,6 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") board_runner_args(jlink "--device=STM32L475VG" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) From 1bc3bd71ea37aa9c6f2dc0428350a9e5ec50bdc4 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 18 Oct 2023 13:54:23 -0600 Subject: [PATCH 2084/4498] maintainers: Become maintainer of json/jwt Become the maintainer for the jwt/json code. The json code has been in tree for a while, and I am the author of the jwt code. Signed-off-by: David Brown --- CODEOWNERS | 5 +++++ MAINTAINERS.yml | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 2aabb0a3299..1a054c4d3f6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -694,6 +694,7 @@ /include/zephyr/dt-bindings/usb/usb.h @galak /include/zephyr/dt-bindings/adc/ads114s0x_adc.h @benediktibk /include/zephyr/drivers/emul.h @sjg20 +/include/zephyr/data/ @d3zd3z /include/zephyr/fs/ @nashif @de-nordic /include/zephyr/init.h @nashif @andyross /include/zephyr/irq.h @dcpleung @nashif @andyross @@ -741,6 +742,7 @@ /lib/open-amp/ @arnopo /lib/os/ @dcpleung @nashif @andyross /lib/os/cbprintf_packaged.c @npitre +/lib/os/json.c @d3zd3z /lib/posix/ @cfriedt /lib/posix/getopt/ @jakub-uC /subsys/portability/ @nashif @@ -864,6 +866,7 @@ scripts/build/gen_image_info.py @tejlmand /subsys/fs/nvs/ @Laczen /subsys/ipc/ @carlocaione /subsys/ipc/ipc_service/*/*icmsg* @emob-nordic +/subsys/jwt/ @d3zd3z /subsys/logging/ @nordic-krch /subsys/logging/backends/log_backend_net.c @nordic-krch @rlubos @jukkar /subsys/lorawan/ @Mani-Sadhasivam @@ -932,6 +935,7 @@ scripts/build/gen_image_info.py @tejlmand /tests/kernel/ @dcpleung @andyross @nashif /tests/lib/ @nashif /tests/lib/cmsis_dsp/ @stephanosio +/tests/lib/json/ @d3zd3z /tests/net/ @rlubos @tbursztyka @jukkar /tests/net/buf/ @jhedberg @tbursztyka @jukkar /tests/net/conn_mgr_monitor/ @rlubos @glarsennordic @jukkar @@ -948,6 +952,7 @@ scripts/build/gen_image_info.py @tejlmand /tests/net/socket/ @rlubos @tbursztyka @jukkar /tests/subsys/debug/coredump/ @dcpleung /tests/subsys/fs/ @nashif @de-nordic +/tests/subsys/jwt/ @d3zd3z /tests/subsys/mgmt/mcumgr/ @de-nordic @nordicjm /tests/subsys/sd/ @danieldegrasse /tests/subsys/rtio/ @teburd diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 74772a4d75b..2073c0ff2f5 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1597,7 +1597,9 @@ IPC: - "area: IPC" JSON Web Token: - status: odd fixes + status: maintained + maintainers: + - d3zd3z collaborators: - mrfuchs - sir-branch From b8e6da0c8635221f2126dda7b61ee4933f7efc90 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 19 Oct 2023 09:38:53 -0500 Subject: [PATCH 2085/4498] doc: release: 3.5: add release notes for SDHC and Disk drivers Add release notes for SDHC and disk driver updates merged since 3.4 Signed-off-by: Daniel DeGrasse --- doc/releases/release-notes-3.5.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index b67c1d1ad11..430d14fad2b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -481,6 +481,9 @@ Drivers and Sensors * Disk + * Ramdisk driver is now configured using devicetree, and supports multiple + instances + * Display * Added support for ST7735S (in ST7735R driver) @@ -696,6 +699,9 @@ Drivers and Sensors * SDHC + * Added driver for EMMC Host controller present on Alder lake platforms + * Added driver for Atmel HSMCI controller present on SAM4E MCU series + * Sensor * Reworked the :dtcompatible:`ti,bq274xx` to add ``BQ27427`` support, fixed From f190547dda688a57424f3c5dbd96a61edd9fbba0 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 19 Oct 2023 10:58:15 -0500 Subject: [PATCH 2086/4498] docs: migration-guide-3.5: add note about ramdisk instantiation Add note to migration guide describing how to instantiate a ramdisk using devicetree, and calling out Kconfig options that have been removed with this change Signed-off-by: Daniel DeGrasse --- doc/releases/migration-guide-3.5.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 4165d1d4b48..4d394797c16 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -227,6 +227,19 @@ Device Drivers and Device Tree suffix ``dig`` added. For example, ``iomuxc_snvs_wakeup_gpio13_io00`` has been renamed to ``iomuxc_snvs_wakeup_dig_gpio13_io00`` +* Ramdisk drivers are now instantiated using devicetree. Kconfig options + ``CONFIG_DISK_RAM_VOLUME_NAME`` and ``CONFIG_DISK_RAM_VOLUME_SIZE`` have + been removed. Instead, instantiate a ramdisk within devicetree like so: + + .. code-block:: devicetree + + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <128>; + }; + Power Management ================ From 853b8c4ca0e662dbf51a110000015cfe6638ee91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 13:47:42 -0700 Subject: [PATCH 2087/4498] dts: add sqn to vendor-prefixes.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed since commit f66b73197d4828cc55e363b5e78b6fdd17690f83 ("drivers: hwspinlock: implement sqn hwspinlock driver") started using it. Not sure how this got past CI. Signed-off-by: Martí Bolívar --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 4b2ab91c73e..f47aa335a33 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -581,6 +581,7 @@ sony Sony Corporation spansion Spansion Inc. sparkfun SparkFun Electronics sprd Spreadtrum Communications Inc. +sqn Sequans Communications sst Silicon Storage Technology, Inc. sstar Xiamen Xingchen(SigmaStar) Technology Co., Ltd. (formerly part of MStar Semiconductor, Inc.) st STMicroelectronics From 64f6ef860a600f3e7ca580b1eeccf5b592c47d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 14:21:05 -0700 Subject: [PATCH 2088/4498] doc: release-notes-3.5: devicetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the changes in this release. Signed-off-by: Martí Bolívar --- doc/releases/release-notes-3.5.rst | 1081 ++++++++++++++++++++++++++++ 1 file changed, 1081 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 430d14fad2b..40979b3fb1d 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -984,6 +984,1087 @@ USB Devicetree ********** +API +=== + +New general-purpose macros: + +- :c:macro:`DT_REG_ADDR_U64` +- :c:macro:`DT_REG_ADDR_BY_NAME_U64` +- :c:macro:`DT_INST_REG_ADDR_BY_NAME_U64` +- :c:macro:`DT_INST_REG_ADDR_U64` +- :c:macro:`DT_FOREACH_STATUS_OKAY_NODE_VARGS` +- :c:macro:`DT_FOREACH_NODE_VARGS` +- :c:macro:`DT_HAS_COMPAT_ON_BUS_STATUS_OKAY` + +New special-purpose macros introduced for dependency ordinals: + +- :c:macro:`DT_DEP_ORD_STR_SORTABLE` + +New general purpose macros introduced for fixed flash partitions: + +- :c:macro:`DT_MEM_FROM_FIXED_PARTITION` +- :c:macro:`DT_FIXED_PARTITION_ADDR` + +Bindings +======== + +* Generic or vendor-independent: + + * New bindings: + + * :dtcompatible:`current-sense-amplifier` + * :dtcompatible:`current-sense-shunt` + * :dtcompatible:`gpio-qdec` + * :dtcompatible:`regulator-gpio` + * :dtcompatible:`usb-audio-feature-volume` + + * Modified bindings: + + * CAN (Controller Area Network) controller bindings: + + * property ``phase-seg1-data`` deprecation status changed from False to True + * property ``phase-seg1`` deprecation status changed from False to True + * property ``phase-seg2-data`` deprecation status changed from False to True + * property ``phase-seg2`` deprecation status changed from False to True + * property ``prop-seg-data`` deprecation status changed from False to True + * property ``prop-seg`` deprecation status changed from False to True + * property ``sjw-data`` default value changed from None to 1 + * property ``sjw-data`` deprecation status changed from False to True + * property ``sjw`` default value changed from None to 1 + * property ``sjw`` deprecation status changed from False to True + + * Ethernet controller bindings: new ``phy-handle`` property (in some + bindings, this was renamed from ``phy-dev``), matching the Linux + ethernet-controller binding. + + * The ``riscv,isa`` property used by RISC-V CPU bindings no longer has an + ``enum`` value. + + * :dtcompatible:`neorv32-cpu`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + + * :dtcompatible:`regulator-fixed`: + + * new property: ``regulator-min-microvolt`` + * new property: ``regulator-max-microvolt`` + * property ``enable-gpios`` is no longer required + + * :dtcompatible:`ethernet-phy`: + + * removed property: ``address`` + * removed property: ``mdio`` + * property ``reg`` is now required + + * :dtcompatible:`usb-audio-hs` and :dtcompatible:`usb-audio-hp`: + + * new property: ``volume-max`` + * new property: ``volume-min`` + * new property: ``volume-res`` + * new property: ``status`` + * new property: ``compatible`` + * new property: ``reg`` + * new property: ``reg-names`` + * new property: ``interrupts`` + * new property: ``interrupts-extended`` + * new property: ``interrupt-names`` + * new property: ``interrupt-parent`` + * new property: ``label`` + * new property: ``clocks`` + * new property: ``clock-names`` + * new property: ``#address-cells`` + * new property: ``#size-cells`` + * new property: ``dmas`` + * new property: ``dma-names`` + * new property: ``io-channels`` + * new property: ``io-channel-names`` + * new property: ``mboxes`` + * new property: ``mbox-names`` + * new property: ``wakeup-source`` + * new property: ``power-domain`` + * new property: ``zephyr,pm-device-runtime-auto`` + + * :dtcompatible:`ntc-thermistor-generic`: + + * removed property: ``r25-ohm`` + + * :dtcompatible:`ns16550`: + + * new property: ``resets`` + * new property: ``reset-names`` + + * :dtcompatible:`fixed-clock`: + + * removed property: ``clocks`` + + * All CPU bindings got a new ``enable-method`` property. `pull request + 60210 `_ for + details. + +* Analog Devices, Inc. (adi): + + * New bindings: + + * :dtcompatible:`adi,ad5628` + * :dtcompatible:`adi,ad5648` + * :dtcompatible:`adi,ad5668` + * :dtcompatible:`adi,ad5672` + * :dtcompatible:`adi,ad5674` + * :dtcompatible:`adi,ad5676` + * :dtcompatible:`adi,ad5679` + * :dtcompatible:`adi,ad5684` + * :dtcompatible:`adi,ad5686` + * :dtcompatible:`adi,ad5687` + * :dtcompatible:`adi,ad5689` + * :dtcompatible:`adi,adin1110` + * :dtcompatible:`adi,adltc2990` + + * Modified bindings: + + * :dtcompatible:`adi,adin2111-mdio` (on adin2111 bus): + + * removed property: ``protocol`` + +* Altera Corp. (altr): + + * New bindings: + + * :dtcompatible:`altr,pio-1.0` + +* Ambiq Micro, Inc. (ambiq): + + * New bindings: + + * :dtcompatible:`ambiq,am1805` + * :dtcompatible:`ambiq,apollo4-pinctrl` + * :dtcompatible:`ambiq,counter` + * :dtcompatible:`ambiq,i2c` + * :dtcompatible:`ambiq,mspi` + * :dtcompatible:`ambiq,pwrctrl` + * :dtcompatible:`ambiq,spi` + * :dtcompatible:`ambiq,stimer` + * :dtcompatible:`ambiq,uart` + * :dtcompatible:`ambiq,watchdog` + +* AMS AG (ams): + + * New bindings: + + * :dtcompatible:`ams,tsl2540` + +* Andes Technology Corporation (andestech): + + * New bindings: + + * :dtcompatible:`andestech,atcwdt200` + * :dtcompatible:`andestech,plic-sw` + * :dtcompatible:`andestech,qspi-nor` + +* ARM Ltd. (arm): + + * New bindings: + + * :dtcompatible:`arm,cortex-a76` + * :dtcompatible:`arm,gic-v1` + * :dtcompatible:`arm,gic-v2` + * :dtcompatible:`arm,gic-v3` + * :dtcompatible:`arm,psci-1.1` + +* ASPEED Technology Inc. (aspeed): + + * Modified bindings: + + * :dtcompatible:`aspeed,ast10x0-reset`: + + * specifier cells for space "reset" are now named: ['id'] (old value: None) + * specifier cells for space "clock" are now named: None (old value: ['reset_id']) + +* Atmel Corporation (atmel): + + * New bindings: + + * :dtcompatible:`atmel,sam-hsmci` + + * Modified bindings: + + * :dtcompatible:`atmel,sam-mdio`: + + * removed property: ``protocol`` + * property ``#address-cells`` const value changed from None to 1 + * property ``#size-cells`` const value changed from None to 0 + * property ``#address-cells`` is now required + * property ``#size-cells`` is now required + +* Bosch Sensortec GmbH (bosch): + + * New bindings: + + * :dtcompatible:`bosch,bmi08x-accel` + * :dtcompatible:`bosch,bmi08x-accel` + * :dtcompatible:`bosch,bmi08x-gyro` + * :dtcompatible:`bosch,bmi08x-gyro` + + * Modified bindings: + + * :dtcompatible:`bosch,bmm150`: + + * new property: ``drdy-gpios`` + + * :dtcompatible:`bosch,bmi270`: + + * new property: ``irq-gpios`` + +* Broadcom Corporation (brcm): + + * New bindings: + + * :dtcompatible:`brcm,bcm2711-aux-uart` + +* Cadence Design Systems Inc. (cdns): + + * New bindings: + + * :dtcompatible:`cdns,tensilica-xtensa-lx3` + +* DFRobot (dfrobot): + + * New bindings: + + * :dtcompatible:`dfrobot,a01nyub` + +* Efinix Inc (efinix): + + * New bindings: + + * :dtcompatible:`efinix,sapphire-gpio` + * :dtcompatible:`efinix,sapphire-timer0` + * :dtcompatible:`efinix,sapphire-uart0` + +* EPCOS AG (epcos): + + * Modified bindings: + + * :dtcompatible:`epcos,b57861s0103a039`: + + * removed property: ``r25-ohm`` + +* Espressif Systems (espressif): + + * Modified bindings: + + * :dtcompatible:`espressif,esp-at` (on uart bus): + + * new property: ``external-reset`` + + * :dtcompatible:`espressif,esp32-mdio`: + + * removed property: ``protocol`` + * property ``#address-cells`` const value changed from None to 1 + * property ``#size-cells`` const value changed from None to 0 + * property ``#address-cells`` is now required + * property ``#size-cells`` is now required + + * :dtcompatible:`espressif,riscv`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + + * :dtcompatible:`espressif,esp32-spi`: + + * new property: ``line-idle-low`` + +* Feature Integration Technology Inc. (fintek): + + * New bindings: + + * :dtcompatible:`fintek,f75303` + +* FocalTech Systems Co.,Ltd (focaltech): + + * Modified bindings: + + * :dtcompatible:`focaltech,ft5336` (on i2c bus): + + * new property: ``reset-gpios`` + +* Fujitsu Ltd. (fujitsu): + + * New bindings: + + * :dtcompatible:`fujitsu,mb85rcxx` + +* Shenzhen Huiding Technology Co., Ltd. (goodix): + + * Modified bindings: + + * :dtcompatible:`goodix,gt911` (on i2c bus): + + * bus list changed from ['kscan'] to [] + * new property: ``alt-addr`` + +* Himax Technologies, Inc. (himax): + + * New bindings: + + * :dtcompatible:`himax,hx8394` + +* Infineon Technologies (infineon): + + * New bindings: + + * :dtcompatible:`infineon,cat1-counter` + * :dtcompatible:`infineon,cat1-spi` + * :dtcompatible:`infineon,xmc4xxx-ccu4-pwm` + * :dtcompatible:`infineon,xmc4xxx-ccu8-pwm` + * :dtcompatible:`infineon,xmc4xxx-i2c` + +* Intel Corporation (intel): + + * New bindings: + + * :dtcompatible:`intel,agilex5-clock` + * :dtcompatible:`intel,alder-lake` + * :dtcompatible:`intel,apollo-lake` + * :dtcompatible:`intel,blinky-pwm` + * :dtcompatible:`intel,elkhart-lake` + * :dtcompatible:`intel,emmc-host` + * :dtcompatible:`intel,ish` + * :dtcompatible:`intel,loapic` + * :dtcompatible:`intel,sedi-gpio` + * :dtcompatible:`intel,sedi-i2c` + * :dtcompatible:`intel,sedi-ipm` + * :dtcompatible:`intel,sedi-uart` + * :dtcompatible:`intel,socfpga-agilex-sip-smc` + * :dtcompatible:`intel,socfpga-reset` + * :dtcompatible:`intel,timeaware-gpio` + + * Removed bindings: + + * ``intel,agilex-socfpga-sip-smc`` + * ``intel,apollo_lake`` + * ``intel,elkhart_lake`` + * ``intel,gna`` + + * Modified bindings: + + * :dtcompatible:`intel,niosv`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + + * :dtcompatible:`intel,adsp-imr`: + + * new property: ``zephyr,memory-attr`` + * property ``zephyr,memory-region-mpu`` enum value changed from ['RAM', 'RAM_NOCACHE', 'FLASH', 'PPB', 'IO', 'EXTMEM'] to None + * property ``zephyr,memory-region-mpu`` deprecation status changed from False to True + + * :dtcompatible:`intel,lpss`: + + * new property: ``dma-parent`` + + * :dtcompatible:`intel,adsp-shim-clkctl`: + + * new property: ``adsp-clkctl-clk-ipll`` + +* Isentek Inc. (isentek): + + * New bindings: + + * :dtcompatible:`isentek,ist8310` + +* Integrated Silicon Solutions Inc. (issi): + + * New bindings: + + * :dtcompatible:`issi,is31fl3216a` + * :dtcompatible:`issi,is31fl3733` + +* ITE Tech. Inc. (ite): + + * New bindings: + + * :dtcompatible:`ite,it8xxx2-sha` + + * Modified bindings: + + * :dtcompatible:`ite,it8xxx2-pinctrl-func`: + + * new property: ``func3-ext`` + * new property: ``func3-ext-mask`` + + * :dtcompatible:`ite,riscv-ite`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + + * :dtcompatible:`ite,enhance-i2c`: + + * new property: ``target-enable`` + * new property: ``target-pio-mode`` + +* Linaro Limited (linaro): + + * New bindings: + + * :dtcompatible:`linaro,ivshmem-ipm` + +* Maxim Integrated Products (maxim): + + * New bindings: + + * :dtcompatible:`maxim,max11102` + * :dtcompatible:`maxim,max11103` + * :dtcompatible:`maxim,max11105` + * :dtcompatible:`maxim,max11106` + * :dtcompatible:`maxim,max11110` + * :dtcompatible:`maxim,max11111` + * :dtcompatible:`maxim,max11115` + * :dtcompatible:`maxim,max11116` + * :dtcompatible:`maxim,max11117` + * :dtcompatible:`maxim,max11253` + * :dtcompatible:`maxim,max11254` + * :dtcompatible:`maxim,max31790` + +* Microchip Technology Inc. (microchip): + + * New bindings: + + * :dtcompatible:`microchip,mcp251xfd` + * :dtcompatible:`microchip,mpfs-i2c` + * :dtcompatible:`microchip,tcn75a` + + * Modified bindings: + + * :dtcompatible:`microchip,xec-pwmbbled`: + + * new property: ``enable-low-power-32k`` + + * :dtcompatible:`microchip,cap1203` (on i2c bus): + + * bus list changed from ['kscan'] to [] + * new property: ``input-codes`` + + * :dtcompatible:`microchip,xec-ps2`: + + * new property: ``wakerx-gpios`` + +* Motorola, Inc. (motorola): + + * Modified bindings: + + * :dtcompatible:`motorola,mc146818`: + + * new property: ``clock-frequency`` + +* Murata Manufacturing Co., Ltd. (murata): + + * New bindings: + + * :dtcompatible:`murata,ncp15wb473` + +* Nordic Semiconductor (nordic): + + * New bindings: + + * :dtcompatible:`nordic,npm1300-led` + * :dtcompatible:`nordic,npm1300-wdt` + + * Removed bindings: + + * ``nordic,nrf-cc310`` + * ``nordic,nrf-cc312`` + + * Modified bindings: + + * :dtcompatible:`nordic,nrf-ccm`: + + * new property: ``headermask-supported`` + + * :dtcompatible:`nordic,nrf-twi`: + + * new property: ``easydma-maxcnt-bits`` + + * :dtcompatible:`nordic,nrf-twim` and :dtcompatible:`nordic,nrf-twis`: + + * new property: ``easydma-maxcnt-bits`` + * new property: ``memory-regions`` + * new property: ``memory-region-names`` + + * :dtcompatible:`nordic,nrf-spi`, :dtcompatible:`nordic,nrf-spis`, and + :dtcompatible:`nordic,nrf-spim`: + + * new property: ``wake-gpios`` + + * :dtcompatible:`nordic,npm1300-charger`: + + * new property: ``thermistor-cold-millidegrees`` + * new property: ``thermistor-cool-millidegrees`` + * new property: ``thermistor-warm-millidegrees`` + * new property: ``thermistor-hot-millidegrees`` + * new property: ``trickle-microvolt`` + * new property: ``term-current-percent`` + * new property: ``vbatlow-charge-enable`` + * new property: ``disable-recharge`` + + * :dtcompatible:`nordic,nrf-uicr`: + + * new property: ``nfct-pins-as-gpios`` + * new property: ``gpio-as-nreset`` + + * :dtcompatible:`nordic,npm1300` (on i2c bus): + + * new property: ``host-int-gpios`` + * new property: ``pmic-int-pin`` + +* Nuclei System Technology (nuclei): + + * Modified bindings: + + * :dtcompatible:`nuclei,bumblebee`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + +* Nuvoton Technology Corporation (nuvoton): + + * New bindings: + + * :dtcompatible:`nuvoton,nct38xx` + * :dtcompatible:`nuvoton,nct38xx-gpio` + * :dtcompatible:`nuvoton,npcx-fiu-nor` + * :dtcompatible:`nuvoton,npcx-fiu-qspi` + * :dtcompatible:`nuvoton,numaker-fmc` + * :dtcompatible:`nuvoton,numaker-gpio` + * :dtcompatible:`nuvoton,numaker-pcc` + * :dtcompatible:`nuvoton,numaker-pinctrl` + * :dtcompatible:`nuvoton,numaker-pwm` + * :dtcompatible:`nuvoton,numaker-rst` + * :dtcompatible:`nuvoton,numaker-scc` + * :dtcompatible:`nuvoton,numaker-spi` + * :dtcompatible:`nuvoton,numaker-uart` + + * Removed bindings: + + * ``nuvoton,nct38xx-gpio`` + * ``nuvoton,npcx-spi-fiu`` + + * Modified bindings: + + * :dtcompatible:`nuvoton,npcx-sha`: + + * new property: ``context-buffer-size`` + + * :dtcompatible:`nuvoton,npcx-adc`: + + * new property: ``vref-mv`` + * removed property: ``threshold-reg-offset`` + + * :dtcompatible:`nuvoton,adc-cmp`: + + * new property: ``thr-sel`` + + * :dtcompatible:`nuvoton,npcx-pcc`: + + * new property: ``pwdwn-ctl-val`` + * property ``clock-frequency`` enum value changed from [100000000, 96000000, 90000000, 80000000, 66000000, 50000000, 48000000, 40000000, 33000000] to [120000000, 100000000, 96000000, 90000000, 80000000, 66000000, 50000000, 48000000] + * property ``ram-pd-depth`` enum value changed from [12, 15] to [8, 12, 15] + +* NXP Semiconductors (nxp): + + * New bindings: + + * :dtcompatible:`nxp,ctimer-pwm` + * :dtcompatible:`nxp,fs26-wdog` + * :dtcompatible:`nxp,imx-flexspi-w956a8mbya` + * :dtcompatible:`nxp,irqsteer-intc` + * :dtcompatible:`nxp,lpdac` + * :dtcompatible:`nxp,mbox-imx-mu` + * :dtcompatible:`nxp,mcux-dcp` + * :dtcompatible:`nxp,mcux-edma-v3` + * :dtcompatible:`nxp,pcf8563` + * :dtcompatible:`nxp,pxp` + * :dtcompatible:`nxp,s32-adc-sar` + * :dtcompatible:`nxp,s32-clock` + * :dtcompatible:`nxp,s32-emios` + * :dtcompatible:`nxp,s32-emios-pwm` + * :dtcompatible:`nxp,s32-gmac` + * :dtcompatible:`nxp,s32-qspi` + * :dtcompatible:`nxp,s32-qspi-device` + * :dtcompatible:`nxp,s32-qspi-nor` + * :dtcompatible:`nxp,s32k3-pinctrl` + * :dtcompatible:`nxp,smartdma` + * :dtcompatible:`nxp,tempmon` + * :dtcompatible:`nxp,vref` + + * Modified bindings: + + * :dtcompatible:`nxp,s32-netc-emdio`: + + * removed property: ``protocol`` + * property ``#address-cells`` const value changed from None to 1 + * property ``#size-cells`` const value changed from None to 0 + * property ``#address-cells`` is now required + * property ``#size-cells`` is now required + + * :dtcompatible:`nxp,mipi-dsi-2l`: + + * property ``nxp,lcdif`` is no longer required + + * :dtcompatible:`nxp,imx-mipi-dsi`: + + * property ``nxp,lcdif`` is no longer required + + * :dtcompatible:`nxp,pca9633` (on i2c bus): + + * new property: ``disable-allcall`` + + * :dtcompatible:`nxp,s32-sys-timer`: + + * removed property: ``clock-frequency`` + * property ``clocks`` is now required + + * :dtcompatible:`nxp,imx-lpspi`: + + * new property: ``data-pin-config`` + + * :dtcompatible:`nxp,s32-spi`: + + * property ``clock-frequency`` is no longer required + * property ``clocks`` is now required + + * :dtcompatible:`nxp,imx-wdog`: + + * pinctrl support + + * :dtcompatible:`nxp,s32-swt`: + + * removed property: ``clock-frequency`` + * property ``clocks`` is now required + + * :dtcompatible:`nxp,lpc-lpadc`: + + * new property: ``nxp,reference-supply`` + + * :dtcompatible:`nxp,kinetis-pit`: + + * new property: ``max-load-value`` + * property ``clocks`` is now required + + * :dtcompatible:`nxp,mcux-edma`: + + * new property: ``dmamux-reg-offset`` + * new property: ``channel-gap`` + * new property: ``irq-shared-offset`` + + * :dtcompatible:`nxp,imx-elcdif`: + + * new property: ``nxp,pxp`` + +* ON Semiconductor Corp. (onnn): + + * New bindings: + + * :dtcompatible:`onnn,ncp5623` + +* Princeton Technology Corp. (ptc): + + * New bindings: + + * :dtcompatible:`ptc,pt6314` + +* Quectel Wireless Solutions Co., Ltd. (quectel): + + * New bindings: + + * :dtcompatible:`quectel,bg95` + +* QuickLogic Corp. (quicklogic): + + * New bindings: + + * :dtcompatible:`quicklogic,eos-s3-pinctrl` + + * Modified bindings: + + * :dtcompatible:`quicklogic,usbserialport-s3b`: + + * pinctrl support + +* Raspberry Pi Foundation (raspberrypi): + + * New bindings: + + * :dtcompatible:`raspberrypi,pico-header` + * :dtcompatible:`raspberrypi,pico-i2c` + * :dtcompatible:`raspberrypi,pico-spi-pio` + * :dtcompatible:`raspberrypi,pico-timer` + +* Raydium Semiconductor Corp. (raydium): + + * New bindings: + + * :dtcompatible:`raydium,rm67162` + +* Renesas Electronics Corporation (renesas): + + * New bindings: + + * :dtcompatible:`renesas,smartbond-lp-osc` + * :dtcompatible:`renesas,smartbond-timer` + + * Modified bindings: + + * :dtcompatible:`renesas,smartbond-flash-controller`: + + * new property: ``read-cs-idle-delay`` + * new property: ``erase-cs-idle-delay`` + +* Smart Battery System (sbs): + + * New bindings: + + * :dtcompatible:`sbs,default-sbs-gauge` + * :dtcompatible:`sbs,sbs-charger` + +* Seeed Technology Co., Ltd (seeed): + + * New bindings: + + * :dtcompatible:`seeed,hm330x` + +* SiFive, Inc. (sifive): + + * Modified bindings: + + * :dtcompatible:`sifive,i2c0`: + + * pinctrl support + +* Silicon Laboratories (silabs): + + * New bindings: + + * :dtcompatible:`silabs,gecko-adc` + +* Sino Wealth Electronic Ltd (sinowealth): + + * New bindings: + + * :dtcompatible:`sinowealth,sh1106` + * :dtcompatible:`sinowealth,sh1106` + +* Sitronix Technology Corporation (sitronix): + + * Modified bindings: + + * :dtcompatible:`sitronix,st7735r` (on spi bus): + + * property ``reset-gpios`` is no longer required + +* Standard Microsystems Corporation (smsc): + + * Modified bindings: + + * :dtcompatible:`smsc,lan91c111-mdio`: + + * removed property: ``protocol`` + * property ``#address-cells`` const value changed from None to 1 + * property ``#size-cells`` const value changed from None to 0 + * property ``#address-cells`` is now required + * property ``#size-cells`` is now required + + * :dtcompatible:`smsc,lan91c111`: + + * new property: ``local-mac-address`` + * new property: ``zephyr,random-mac-address`` + * property ``reg`` is no longer required + +* Synopsys, Inc. (snps): + + * New bindings: + + * :dtcompatible:`snps,dw-timers` + +* Solomon Systech Limited (solomon): + + * Modified bindings: + + * :dtcompatible:`solomon,ssd1306fb` + + * new property: ``inversion-on`` + * new property: ``ready-time-ms`` + +* Sequans Communications (sqn): + + * New bindings: + + * :dtcompatible:`sqn,hwspinlock` + +* STMicroelectronics (st): + + * New bindings: + + * :dtcompatible:`st,stm32-bxcan` + * :dtcompatible:`st,stm32-spi-host-cmd` + * :dtcompatible:`st,stm32f1-rcc` + * :dtcompatible:`st,stm32f3-rcc` + * :dtcompatible:`st,stm32wba-flash-controller` + * :dtcompatible:`st,stm32wba-hse-clock` + * :dtcompatible:`st,stm32wba-pll-clock` + * :dtcompatible:`st,stm32wba-rcc` + * :dtcompatible:`st,stmpe811` + + * Removed bindings: + + * ``st,stm32-can`` + + * Modified bindings: + + * :dtcompatible:`st,stm32-pwm`: + + * new property: ``four-channel-capture-support`` + + * :dtcompatible:`st,stm32f4-adc`: + + * new property: ``st,adc-clock-source`` + * new property: ``st,adc-prescaler`` + * new property: ``st,adc-sequencer`` + * removed property: ``temp-channel`` + * removed property: ``vref-channel`` + * removed property: ``vbat-channel`` + + * :dtcompatible:`st,stm32-adc`: + + * new property: ``st,adc-clock-source`` + * new property: ``st,adc-prescaler`` + * new property: ``st,adc-sequencer`` + * removed property: ``temp-channel`` + * removed property: ``vref-channel`` + * removed property: ``vbat-channel`` + + * :dtcompatible:`st,stm32f1-adc`: + + * new property: ``st,adc-sequencer`` + * removed property: ``temp-channel`` + * removed property: ``vref-channel`` + * removed property: ``vbat-channel`` + + * :dtcompatible:`st,stm32-ospi`: + + * new property: ``io-low-port`` + * new property: ``io-high-port`` + + * :dtcompatible:`st,stm32c0-hsi-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32-hse-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32wl-hse-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32g0-hsi-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32h7-hsi-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32-lse-clock`: + + * removed property: ``clocks`` + + * :dtcompatible:`st,stm32u5-pll-clock`: + + * new property: ``fracn`` + +* Telink Semiconductor (telink): + + * Modified bindings: + + * :dtcompatible:`telink,b91-pwm`: + + * pinctrl support + + * :dtcompatible:`telink,b91`: + + * new property: ``mmu-type`` + * new property: ``riscv,isa`` + + * :dtcompatible:`telink,b91-i2c`: + + * pinctrl support + + * :dtcompatible:`telink,b91-spi`: + + * pinctrl support + + * :dtcompatible:`telink,b91-uart`: + + * pinctrl support + +* Texas Instruments (ti): + + * New bindings: + + * :dtcompatible:`ti,ads1112` + * :dtcompatible:`ti,bq27z746` + * :dtcompatible:`ti,cc13xx-cc26xx-rtc-timer` + * :dtcompatible:`ti,cc13xx-cc26xx-timer` + * :dtcompatible:`ti,cc13xx-cc26xx-timer-pwm` + * :dtcompatible:`ti,cc32xx-pinctrl` + * :dtcompatible:`ti,davinci-gpio` + * :dtcompatible:`ti,davinci-gpio-nexus` + * :dtcompatible:`ti,lp5009` + * :dtcompatible:`ti,lp5012` + * :dtcompatible:`ti,lp5018` + * :dtcompatible:`ti,lp5024` + * :dtcompatible:`ti,lp5030` + * :dtcompatible:`ti,lp5036` + * :dtcompatible:`ti,lp5569` + * :dtcompatible:`ti,tas6422dac` + * :dtcompatible:`ti,tcan4x5x` + * :dtcompatible:`ti,tla2021` + * :dtcompatible:`ti,tmag5170` + * :dtcompatible:`ti,vim` + + * Removed bindings: + + * ``ti,cc13xx-cc26xx-rtc`` + * ``ti,lp503x`` + + * Modified bindings: + + * :dtcompatible:`ti,cc32xx-i2c`: + + * pinctrl support + + * :dtcompatible:`ti,ina230` (on i2c bus): + + * new property: ``alert-config`` + * new property: ``adc-mode`` + * new property: ``vbus-conversion-time-us`` + * new property: ``vshunt-conversion-time-us`` + * new property: ``avg-count`` + * new property: ``rshunt-micro-ohms`` + * removed property: ``rshunt-milliohms`` + * property ``config`` default value changed from None to 0 + * property ``config`` deprecation status changed from False to True + * property ``config`` is no longer required + + * :dtcompatible:`ti,ina237` (on i2c bus): + + * new property: ``adc-mode`` + * new property: ``vbus-conversion-time-us`` + * new property: ``vshunt-conversion-time-us`` + * new property: ``temp-conversion-time-us`` + * new property: ``avg-count`` + * new property: ``high-precision`` + * new property: ``rshunt-micro-ohms`` + * removed property: ``rshunt-milliohms`` + * property ``adc-config`` default value changed from None to 0 + * property ``config`` default value changed from None to 0 + * property ``adc-config`` deprecation status changed from False to True + * property ``config`` deprecation status changed from False to True + * property ``adc-config`` is no longer required + * property ``config`` is no longer required + + * :dtcompatible:`ti,cc32xx-uart`: + + * pinctrl support + +* A stand-in for a real vendor which can be used in examples and tests (vnd): + + * New bindings: + + * :dtcompatible:`vnd,memory-attr` + * :dtcompatible:`vnd,reg-holder-64` + * :dtcompatible:`vnd,reserved-compat` + + * Modified bindings: + + * :dtcompatible:`vnd,serial`: + + * property ``reg`` is no longer required + +* X-Powers (x-powers): + + * New bindings: + + * :dtcompatible:`x-powers,axp192` + * :dtcompatible:`x-powers,axp192-gpio` + * :dtcompatible:`x-powers,axp192-regulator` + +* Xen Hypervisor (xen): + + * New bindings: + + * :dtcompatible:`xen,xen` + + * Removed bindings: + + * ``xen,xen-4.15`` + +* Xilinx (xlnx): + + * New bindings: + + * :dtcompatible:`xlnx,zynqmp-ipi-mailbox` + +* Shenzhen Xptek Technology Co., Ltd (xptek): + + * Modified bindings: + + * :dtcompatible:`xptek,xpt2046` (on spi bus): + + * bus list changed from ['kscan'] to [] + +* Zephyr-specific binding (zephyr): + + * New bindings: + + * :dtcompatible:`zephyr,fake-rtc` + * :dtcompatible:`zephyr,i2c-dump-allowlist` + * :dtcompatible:`zephyr,lvgl-button-input` + * :dtcompatible:`zephyr,lvgl-encoder-input` + * :dtcompatible:`zephyr,lvgl-pointer-input` + * :dtcompatible:`zephyr,mdio-gpio` + * :dtcompatible:`zephyr,native-tty-uart` + * :dtcompatible:`zephyr,ram-disk` + * :dtcompatible:`zephyr,sensing` + * :dtcompatible:`zephyr,sensing-phy-3d-sensor` + + * Removed bindings: + + * ``zephyr,gpio-keys`` + + * Modified bindings: + + * :dtcompatible:`zephyr,mmc-disk` (on sd bus): + + * new property: ``bus-width`` + + * :dtcompatible:`zephyr,bt-hci-spi` (on spi bus): + + * new property: ``controller-data-delay-us`` + + * :dtcompatible:`zephyr,sdhc-spi-slot` (on spi bus): + + * new property: ``pwr-gpios`` + + * :dtcompatible:`zephyr,memory-region`: + + * new property: ``zephyr,memory-attr`` + * property ``zephyr,memory-region-mpu`` enum value changed from ['RAM', 'RAM_NOCACHE', 'FLASH', 'PPB', 'IO', 'EXTMEM'] to None + * property ``zephyr,memory-region-mpu`` deprecation status changed from False to True + * property ``reg`` is now required + Libraries / Subsystems ********************** From 201b666ecb545c32039c6766e6c9c5524f381c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 19 Oct 2023 18:42:53 +0200 Subject: [PATCH 2089/4498] doc: use XeLaTeX as TeX typesetting engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XeLaTeX is a TeX typesetting engine that extends LaTeX with support for Unicode and modern font technologies such as OpenType. It is included in all the LaTeX distro recommended for Zephyr so it is safe to assume it is available to the user interested in building the PDF documentation locally Signed-off-by: Benjamin Cabé --- doc/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/conf.py b/doc/conf.py index 0ac0dd2bfd0..1ee3a60f88e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -199,6 +199,7 @@ latex_documents = [ ("index-tex", "zephyr.tex", "Zephyr Project Documentation", author, "manual"), ] +latex_engine = "xelatex" # -- Options for zephyr.doxyrunner plugin --------------------------------- From 472def94e7b96e9d340c8bd5de69477880a1b404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 19 Oct 2023 18:46:47 +0200 Subject: [PATCH 2090/4498] doc: use more modern fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Noto as baseline font and Inconsolata Nerd Font for source code. These are both esthetically pleasing and have good Unicode coverage. NOTE: Unsupported characters (i.e. emojis, at the time of this commit) are rendered as tofu (i.e. a square). Signed-off-by: Benjamin Cabé --- doc/conf.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 1ee3a60f88e..dcdbd22be94 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -5,6 +5,7 @@ import os from pathlib import Path import re +import textwrap from sphinx.cmd.build import get_parser import sphinx_rtd_theme @@ -182,7 +183,11 @@ "papersize": "a4paper", "maketitle": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read(), "preamble": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read(), - "fontpkg": r"\usepackage{charter}", + "fontpkg": textwrap.dedent(r""" + \usepackage{noto} + \usepackage{inconsolata-nerd-font} + \usepackage[T1]{fontenc} + """), "sphinxsetup": ",".join( ( # NOTE: colors match those found in light.css stylesheet From 6597a65b23ff87ee526644c407dbbff7d257743a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 20:46:19 +0300 Subject: [PATCH 2091/4498] doc: release: 3.5: Add more content to the major enhancements List more items in the "major encements" section. Signed-off-by: Johan Hedberg --- doc/releases/release-notes-3.5.rst | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 40979b3fb1d..3c2ad7317f0 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -9,7 +9,19 @@ We are pleased to announce the release of Zephyr version 3.5.0. Major enhancements with this release include: -* Added native_sim (successor to native_posix) +* Added support for linkable loadable extensions (llext) +* Added native_sim simulator target (successor to native_posix) +* Added new battery charger driver API +* Added new hardware spinlock driver API +* Added new modem subsystem +* Added support for 45+ new boards +* Networking: improvements to CoAP, Connection Manager, DHCP, Ethernet, gPTP, ICMP, + IPv6 and LwM2M +* Bluetooth: improvements to the Controller, Audio, Mesh, as well as the host stack in + general +* Improved LVGL graphics library integration +* Integrated support with the CodeChecker static analyzer +* Picolibc is now the default C standard library An overview of the changes required or recommended when migrating your application from Zephyr v3.4.0 to Zephyr v3.5.0 can be found in the separate :ref:`migration guide`. From 625d1bfc61b576514c123be0e63f38470b998a4b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 21:17:50 +0300 Subject: [PATCH 2092/4498] doc: release: 3.5: Remove empty sections Remove empty sections from the document. Signed-off-by: Johan Hedberg --- doc/releases/release-notes-3.5.rst | 46 ------------------------------ 1 file changed, 46 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 3c2ad7317f0..d7448c1df26 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -279,8 +279,6 @@ Bluetooth * Updated to have ``EVENT_OVERHEAD_START_US`` verbose assertion in each state/role LLL * Updated to stop following ``aux_ptr`` if ``DATA_LEN_MAX`` is reached during extended scanning -* HCI Driver - Boards & SoC Support ******************** @@ -460,8 +458,6 @@ Drivers and Sensors * Added driver for MAX1125x family. * Added driver for MAX11102-MAX1117. -* Battery-backed RAM - * CAN * Added support for TI TCAN4x5x CAN-FD controller with integrated transceiver @@ -482,15 +478,11 @@ Drivers and Sensors * Added support for Raspberry Pi Pico Timer -* Crypto - * DAC * Added support for Analog Devices AD56xx * Added support for NXP lpcxpresso55s36 (LPDAC) -* DFU - * Disk * Ramdisk driver is now configured using devicetree, and supports multiple @@ -519,8 +511,6 @@ Drivers and Sensors * Added a requirement for ``entropy_get_entropy()`` to be thread-safe because of random subsystem needs. -* ESPI - * Ethernet * Added :kconfig:option:`CONFIG_ETH_NATIVE_POSIX_RX_TIMEOUT` to set rx timeout for native posix. @@ -551,16 +541,10 @@ Drivers and Sensors * STM32 QSPI driver now supports Jedec SFDP parameter reading. * STM32 OSPI driver now supports both Low and High ports of IO manager. -* FPGA - -* Fuel Gauge - * GPIO * Added support for Nuvoton NuMaker M46x -* hwinfo - * I2C * STM32 V1 driver now supports large transactions (more than 256 bytes chunks) @@ -630,16 +614,6 @@ Drivers and Sensors * Renamed the callback definition macro from ``INPUT_LISTENER_CB_DEFINE`` to :c:macro:`INPUT_CALLBACK_DEFINE`. -* IPM - -* KSCAN - -* LED - -* MBOX - -* MEMC - * PCIE * Added support in shell to display PCIe capabilities. @@ -655,8 +629,6 @@ Drivers and Sensors * Adopted the ACPICA library as a new module to further enhance ACPI support. -* PECI - * Pin control * Added support for Nuvoton NuMaker M46x @@ -675,8 +647,6 @@ Drivers and Sensors * Added driver for Nuvoton NuMaker family. * Added PWM driver based on NXP S32 EMIOS peripheral. -* Power domain - * Regulators * Added support for GPIO-controlled voltage regulator @@ -790,10 +760,6 @@ Drivers and Sensors with UDC API (experimental). * Added support for STM32H5 series on USB driver. -* W1 - -* Watchdog - * WiFi * Increased esp32 default network (TCP workq, RX and mgmt event) stack sizes to 2048 bytes. @@ -2340,20 +2306,11 @@ LVGL * LVGL shell allows for monkey testing (requires :kconfig:option:`CONFIG_LV_USE_MONKEY`) and inspecting memory usage. -Storage -******* - -Trusted Firmware-M -****************** - Trusted Firmware-A ****************** * Updated to TF-A 2.9.0. -zcbor -***** - Documentation ************* @@ -2369,6 +2326,3 @@ Tests and Samples channel using subscribers. * Created the zbus message subscriber sample to demonstrate how to use message subscribers. - -Known Issues -************ From 97956e402ec21965f6e8bf9aacd13bd342d2f889 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2023 22:33:42 +0300 Subject: [PATCH 2093/4498] doc: release: Remove "Working Draft" from titles Remove "Working Draft" from the release notes and migration guide Signed-off-by: Johan Hedberg --- doc/releases/migration-guide-3.5.rst | 4 ++-- doc/releases/release-notes-3.5.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 4d394797c16..50a71554f20 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -2,8 +2,8 @@ .. _migration_3.5: -Migration guide to Zephyr v3.5.0 (Working Draft) -################################################ +Migration guide to Zephyr v3.5.0 +################################ This document describes the changes required or recommended when migrating your application from Zephyr v3.4.0 to Zephyr v3.5.0. diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index d7448c1df26..eddebb7bc74 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -2,8 +2,8 @@ .. _zephyr_3.5: -Zephyr 3.5.0 (Working Draft) -############################ +Zephyr 3.5.0 +############ We are pleased to announce the release of Zephyr version 3.5.0. From aa316fbd2e066e2de3229eb006041234c6caafdb Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 20 Oct 2023 08:51:37 +0000 Subject: [PATCH 2094/4498] docs: migration-guide-3.5: deduplicate the ram-disk notes This point ended up being mentioned twice for some reasons. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.5.rst | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 50a71554f20..179e8cd9a80 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -227,19 +227,6 @@ Device Drivers and Device Tree suffix ``dig`` added. For example, ``iomuxc_snvs_wakeup_gpio13_io00`` has been renamed to ``iomuxc_snvs_wakeup_dig_gpio13_io00`` -* Ramdisk drivers are now instantiated using devicetree. Kconfig options - ``CONFIG_DISK_RAM_VOLUME_NAME`` and ``CONFIG_DISK_RAM_VOLUME_SIZE`` have - been removed. Instead, instantiate a ramdisk within devicetree like so: - - .. code-block:: devicetree - - ramdisk0 { - compatible = "zephyr,ram-disk"; - disk-name = "RAM"; - sector-size = <512>; - sector-count = <128>; - }; - Power Management ================ From 0d907c74280c679b2bd226652beafd71d2d5b2b0 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 20 Oct 2023 09:42:16 +0300 Subject: [PATCH 2095/4498] doc: add 3.5.0 to the index of releases Add the new release to the doc index. Signed-off-by: Johan Hedberg --- doc/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/conf.py b/doc/conf.py index dcdbd22be94..6ff43b07f2b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -164,6 +164,7 @@ "current_version": version, "versions": ( ("latest", "/"), + ("3.5.0", "/3.5.0/"), ("3.4.0", "/3.4.0/"), ("3.3.0", "/3.3.0/"), ("2.7.5 (LTS)", "/2.7.5/"), From bafcf57ac1987cfedeb89d8726d06df5e298c7e8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 20 Oct 2023 12:03:00 +0300 Subject: [PATCH 2096/4498] doc: release: add Zephyr 3.5 as supported release Add Zephyr 3.5 as a supported release until July 26th 2024, i.e. when 3.7 is planned to be released. Signed-off-by: Johan Hedberg --- doc/releases/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/index.rst b/doc/releases/index.rst index 7433df77e0b..b9365c64a69 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -58,6 +58,8 @@ Supported Releases +=================+================+===============+ | `Zephyr 2.7.5`_ | 2023-06-01 | 2024-08-31 | +-----------------+----------------+---------------+ +| `Zephyr 3.5.0`_ | 2023-10-20 | 2024-07-26 | ++-----------------+----------------+---------------+ | `Zephyr 3.4.0`_ | 2023-06-16 | 2024-02-29 | +-----------------+----------------+---------------+ | `Zephyr 3.3.0`_ | 2023-02-19 | 2023-10-31 | @@ -95,3 +97,4 @@ users transition from the previous release. .. _`Zephyr 2.7.5`: https://docs.zephyrproject.org/2.7.5/ .. _`Zephyr 3.3.0`: https://docs.zephyrproject.org/3.3.0/ .. _`Zephyr 3.4.0`: https://docs.zephyrproject.org/3.4.0/ +.. _`Zephyr 3.5.0`: https://docs.zephyrproject.org/3.5.0/ From a6eef0ba3755f2530c5ce93524e5ac4f5be30194 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 20 Oct 2023 09:49:31 +0300 Subject: [PATCH 2097/4498] release: Zephyr 3.5.0 release Update the version for the final release. Signed-off-by: Johan Hedberg --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5ed75f8b8ea..1f6bff6f170 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ VERSION_MAJOR = 3 VERSION_MINOR = 5 PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = rc3 +EXTRAVERSION = From 697b44f0131705003f56be98ebba498c0234fab6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 20 Oct 2023 13:46:21 +0300 Subject: [PATCH 2098/4498] release: bump main to v3.5.99 Update main development branch to version v3.5.99. Signed-off-by: Johan Hedberg --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1f6bff6f170..a2cbf5c1335 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 3 VERSION_MINOR = 5 -PATCHLEVEL = 0 +PATCHLEVEL = 99 VERSION_TWEAK = 0 EXTRAVERSION = From 0521ffd5a3f6df277d8c1493d324b1095e564f30 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Sep 2023 13:12:48 +0200 Subject: [PATCH 2099/4498] Bluetooth: ISO: Rename BT_ISO_ADVANCED to BT_ISO_TEST_PARAMS Rename the Kconfig option from BT_ISO_ADVANCED to BT_ISO_TEST_PARAMS to more explicitly denote that it enables support for using the ISO test parameters. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/iso.h | 17 ++++--- .../iso_broadcast_benchmark/src/broadcaster.c | 32 ++++++------- .../iso_connected_benchmark/src/main.c | 48 +++++++++---------- subsys/bluetooth/Kconfig.iso | 4 +- subsys/bluetooth/host/iso.c | 48 +++++++++---------- tests/bsim/bluetooth/ll/bis/src/main.c | 8 ++-- 6 files changed, 78 insertions(+), 79 deletions(-) diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index 05b9b0fbed9..ad89b62ee77 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -200,7 +200,7 @@ struct bt_iso_chan_io_qos { */ struct bt_iso_chan_path *path; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) /** @brief Maximum PDU size * * Maximum size, in octets, of the payload from link layer to link @@ -219,7 +219,7 @@ struct bt_iso_chan_io_qos { * Value range @ref BT_ISO_BN_MIN to @ref BT_ISO_BN_MAX. */ uint8_t burst_number; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @brief ISO Channel QoS structure. */ @@ -241,7 +241,7 @@ struct bt_iso_chan_qos { */ struct bt_iso_chan_io_qos *tx; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) /** @brief Number of subevents * * Maximum number of subevents in each CIS or BIS event. @@ -249,7 +249,7 @@ struct bt_iso_chan_qos { * Value range @ref BT_ISO_NSE_MIN to @ref BT_ISO_NSE_MAX. */ uint8_t num_subevents; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @brief ISO Channel Data Path structure. */ @@ -371,7 +371,7 @@ struct bt_iso_cig_param { */ uint8_t framing; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) /** @brief Central to Peripheral flush timeout * * The flush timeout in multiples of ISO_Interval for each payload sent @@ -398,8 +398,7 @@ struct bt_iso_cig_param { * @ref BT_ISO_ISO_INTERVAL_MAX. */ uint16_t iso_interval; -#endif /* CONFIG_BT_ISO_ADVANCED */ - +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** ISO connection parameters structure */ @@ -470,7 +469,7 @@ struct bt_iso_big_create_param { */ uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE]; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) /** @brief Immediate Repetition Count * * The number of times the scheduled payloads are transmitted in a @@ -496,7 +495,7 @@ struct bt_iso_big_create_param { * @ref BT_ISO_ISO_INTERVAL_MAX. */ uint16_t iso_interval; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @brief Broadcast Isochronous Group (BIG) Sync Parameters */ diff --git a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c index 735ac7a3318..6c52e2aef82 100644 --- a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c +++ b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c @@ -22,14 +22,14 @@ LOG_MODULE_REGISTER(iso_broadcast_broadcaster, LOG_LEVEL_DBG); #define DEFAULT_BIS_PACKING 0 #define DEFAULT_BIS_FRAMING 0 #define DEFAULT_BIS_COUNT CONFIG_BT_ISO_MAX_CHAN -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) #define DEFAULT_BIS_NSE BT_ISO_NSE_MIN #define DEFAULT_BIS_BN BT_ISO_BN_MIN #define DEFAULT_BIS_PDU_SIZE CONFIG_BT_ISO_TX_MTU #define DEFAULT_BIS_IRC BT_ISO_IRC_MIN #define DEFAULT_BIS_PTO BT_ISO_PTO_MIN #define DEFAULT_BIS_ISO_INTERVAL DEFAULT_BIS_INTERVAL_US / 1250U /* N * 10 ms */ -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), @@ -53,11 +53,11 @@ static struct bt_iso_big_create_param big_create_param = { .framing = DEFAULT_BIS_FRAMING, /* 0 - unframed, 1 - framed */ .interval = DEFAULT_BIS_INTERVAL_US, /* in microseconds */ .latency = DEFAULT_BIS_LATENCY_MS, /* milliseconds */ -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .irc = DEFAULT_BIS_IRC, .pto = DEFAULT_BIS_PTO, .iso_interval = DEFAULT_BIS_ISO_INTERVAL, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static void iso_connected(struct bt_iso_chan *chan) @@ -91,17 +91,17 @@ static struct bt_iso_chan_io_qos iso_tx_qos = { .sdu = DEFAULT_BIS_SDU, /* bytes */ .rtn = DEFAULT_BIS_RTN, .phy = DEFAULT_BIS_PHY, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .max_pdu = DEFAULT_BIS_PDU_SIZE, .burst_number = DEFAULT_BIS_BN, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static struct bt_iso_chan_qos bis_iso_qos = { .tx = &iso_tx_qos, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .num_subevents = DEFAULT_BIS_NSE, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static size_t get_chars(char *buffer, size_t max_size) @@ -241,7 +241,7 @@ static int parse_sdu_arg(void) return (int)sdu; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) static int parse_irc_arg(void) { size_t char_count; @@ -385,7 +385,7 @@ static int parse_bn_arg(void) return (int)burst_number; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ static int parse_packing_arg(void) { @@ -468,14 +468,14 @@ static int parse_args(void) int packing; int framing; int bis_count; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) int num_subevents; int iso_interval; int burst_number; int max_pdu; int irc; int pto; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -519,7 +519,7 @@ static int parse_args(void) return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) irc = parse_irc_arg(); if (irc < 0) { return -EINVAL; @@ -549,7 +549,7 @@ static int parse_args(void) if (burst_number < 0) { return -EINVAL; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ iso_tx_qos.rtn = rtn; iso_tx_qos.phy = phy; @@ -559,14 +559,14 @@ static int parse_args(void) big_create_param.packing = packing; big_create_param.framing = framing; big_create_param.num_bis = bis_count; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) bis_iso_qos.num_subevents = num_subevents; iso_tx_qos.max_pdu = max_pdu; iso_tx_qos.burst_number = burst_number; big_create_param.irc = irc; big_create_param.pto = pto; big_create_param.iso_interval = iso_interval; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return 0; } diff --git a/samples/bluetooth/iso_connected_benchmark/src/main.c b/samples/bluetooth/iso_connected_benchmark/src/main.c index 99b308ccbb2..3b4cd46f63d 100644 --- a/samples/bluetooth/iso_connected_benchmark/src/main.c +++ b/samples/bluetooth/iso_connected_benchmark/src/main.c @@ -38,13 +38,13 @@ enum benchmark_role { #define DEFAULT_CIS_COUNT 1U #define DEFAULT_CIS_SEC_LEVEL BT_SECURITY_L1 -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) #define DEFAULT_CIS_NSE BT_ISO_NSE_MIN #define DEFAULT_CIS_BN BT_ISO_BN_MIN #define DEFAULT_CIS_PDU_SIZE CONFIG_BT_ISO_TX_MTU #define DEFAULT_CIS_FT BT_ISO_FT_MIN #define DEFAULT_CIS_ISO_INTERVAL DEFAULT_CIS_INTERVAL_US / 1250U /* N * 1.25 ms */ -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ #define BUFFERS_ENQUEUED 2 /* Number of buffers enqueue for each channel */ @@ -91,28 +91,28 @@ static struct bt_iso_chan_io_qos iso_tx_qos = { .sdu = DEFAULT_CIS_SDU_SIZE, /* bytes */ .rtn = DEFAULT_CIS_RTN, .phy = DEFAULT_CIS_PHY, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .max_pdu = DEFAULT_CIS_PDU_SIZE, .burst_number = DEFAULT_CIS_BN, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static struct bt_iso_chan_io_qos iso_rx_qos = { .sdu = DEFAULT_CIS_SDU_SIZE, /* bytes */ .rtn = DEFAULT_CIS_RTN, .phy = DEFAULT_CIS_PHY, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .max_pdu = DEFAULT_CIS_PDU_SIZE, .burst_number = DEFAULT_CIS_BN, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static struct bt_iso_chan_qos iso_qos = { .tx = &iso_tx_qos, .rx = &iso_rx_qos, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .num_subevents = DEFAULT_CIS_NSE, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static struct bt_iso_cig_param cig_create_param = { @@ -123,11 +123,11 @@ static struct bt_iso_cig_param cig_create_param = { .framing = DEFAULT_CIS_FRAMING, .cis_channels = cis, .num_cis = DEFAULT_CIS_COUNT, -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) .c_to_p_ft = DEFAULT_CIS_FT, .p_to_c_ft = DEFAULT_CIS_FT, .iso_interval = DEFAULT_CIS_ISO_INTERVAL, -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; static enum benchmark_role device_role_select(void) @@ -632,7 +632,7 @@ static int parse_sdu_arg(struct bt_iso_chan_io_qos *qos) return (int)sdu; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) static int parse_c_to_p_ft_arg(void) { char buffer[4]; @@ -778,7 +778,7 @@ static int parse_bn_arg(const struct bt_iso_chan_io_qos *qos) return (int)bn; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ static int parse_cis_count_arg(void) { @@ -808,12 +808,12 @@ static int parse_cig_args(void) int interval; int latency; int cis_count; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) int c_to_p_ft; int p_to_c_ft; int iso_interval; int num_subevents; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -832,7 +832,7 @@ static int parse_cig_args(void) return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) c_to_p_ft = parse_c_to_p_ft_arg(); if (c_to_p_ft < 0) { return -EINVAL; @@ -852,17 +852,17 @@ static int parse_cig_args(void) if (num_subevents < 0) { return -EINVAL; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ cig_create_param.interval = interval; cig_create_param.latency = latency; cig_create_param.num_cis = cis_count; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) cig_create_param.c_to_p_ft = c_to_p_ft; cig_create_param.p_to_c_ft = p_to_c_ft; cig_create_param.iso_interval = iso_interval; iso_qos.num_subevents = num_subevents; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return 0; } @@ -872,10 +872,10 @@ static int parse_cis_args(struct bt_iso_chan_io_qos *qos) int rtn; int phy; int sdu; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) int max_pdu; int burst_number; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -894,7 +894,7 @@ static int parse_cis_args(struct bt_iso_chan_io_qos *qos) return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) max_pdu = parse_pdu_arg(qos); if (max_pdu < 0) { return -EINVAL; @@ -904,15 +904,15 @@ static int parse_cis_args(struct bt_iso_chan_io_qos *qos) if (burst_number < 0) { return -EINVAL; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ qos->rtn = rtn; qos->phy = phy; qos->sdu = sdu; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) qos->max_pdu = max_pdu; qos->burst_number = burst_number; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return 0; } diff --git a/subsys/bluetooth/Kconfig.iso b/subsys/bluetooth/Kconfig.iso index 304c408f42f..0fc4be1401b 100644 --- a/subsys/bluetooth/Kconfig.iso +++ b/subsys/bluetooth/Kconfig.iso @@ -120,8 +120,8 @@ config BT_ISO_RX_MTU This is the actual data payload. It doesn't include the optional HCI ISO Data packet fields (e.g. `struct bt_hci_iso_ts_data_hdr`) -config BT_ISO_ADVANCED - bool "Advanced ISO parameters" +config BT_ISO_TEST_PARAMS + bool "ISO test parameters support" help Enabling advanced ISO parameters will allow the use of the ISO test parameters for creating a CIG or a BIG. These test parameters were diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index a1b645c0e2f..2422574e3bb 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -843,7 +843,7 @@ static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos, return false; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) if (advanced) { if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && is_broadcast) { if (!IN_RANGE(io_qos->max_pdu, @@ -873,7 +873,7 @@ static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos, } #else ARG_UNUSED(advanced); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return true; } @@ -1456,14 +1456,14 @@ static void bt_iso_remove_data_path(struct bt_conn *iso) static bool valid_chan_qos(const struct bt_iso_chan_qos *qos, bool advanced) { -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) if (advanced && !IN_RANGE(qos->num_subevents, BT_ISO_NSE_MIN, BT_ISO_NSE_MAX)) { LOG_DBG("Invalid NSE: %u", qos->num_subevents); return false; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ if (qos->rx != NULL) { if (!valid_chan_io_qos(qos->rx, false, false, advanced)) { @@ -1590,7 +1590,7 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, return rsp; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, const struct bt_iso_cig_param *param) { @@ -1720,7 +1720,7 @@ static bool is_advanced_cig_param(const struct bt_iso_cig_param *param) return false; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan) { @@ -1872,7 +1872,7 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, return false; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) if (advanced) { if (!IN_RANGE(param->c_to_p_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) { LOG_DBG("Invalid Central to Peripheral FT %u", @@ -1896,7 +1896,7 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, return false; } } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return true; } @@ -1935,9 +1935,9 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) advanced = is_advanced_cig_param(param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ CHECKIF(!valid_cig_param(param, advanced, NULL)) { LOG_DBG("Invalid CIG params"); @@ -1959,10 +1959,10 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, if (!advanced) { rsp = hci_le_set_cig_params(cig, param); -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) } else { rsp = hci_le_set_cig_test_params(cig, param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ } if (rsp == NULL) { @@ -2038,9 +2038,9 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) advanced = is_advanced_cig_param(param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ CHECKIF(!valid_cig_param(param, advanced, cig)) { LOG_DBG("Invalid CIG params"); @@ -2059,10 +2059,10 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, if (!advanced) { rsp = hci_le_set_cig_params(cig, param); -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) } else { rsp = hci_le_set_cig_test_params(cig, param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ } if (rsp == NULL) { @@ -2583,7 +2583,7 @@ static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big, return err; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, struct bt_iso_big *big, const struct bt_iso_big_create_param *param) @@ -2675,7 +2675,7 @@ static bool is_advanced_big_param(const struct bt_iso_big_create_param *param) return false; } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ static bool valid_big_param(const struct bt_iso_big_create_param *param, bool advanced) @@ -2761,7 +2761,7 @@ static bool valid_big_param(const struct bt_iso_big_create_param *param, return false; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) if (advanced) { CHECKIF(!IN_RANGE(param->irc, BT_ISO_IRC_MIN, BT_ISO_IRC_MAX)) { LOG_DBG("Invalid IRC %u", param->irc); @@ -2783,7 +2783,7 @@ static bool valid_big_param(const struct bt_iso_big_create_param *param, return false; } } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ return true; } @@ -2800,9 +2800,9 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param return -EINVAL; } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) advanced = is_advanced_big_param(param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ if (!valid_big_param(param, advanced)) { LOG_DBG("Invalid BIG parameters"); @@ -2826,10 +2826,10 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param if (!advanced) { err = hci_le_create_big(padv, big, param); -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) } else { err = hci_le_create_big_test(padv, big, param); -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ } if (err) { diff --git a/tests/bsim/bluetooth/ll/bis/src/main.c b/tests/bsim/bluetooth/ll/bis/src/main.c index eb1edeb6711..d15de7ff196 100644 --- a/tests/bsim/bluetooth/ll/bis/src/main.c +++ b/tests/bsim/bluetooth/ll/bis/src/main.c @@ -338,7 +338,7 @@ static void create_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big) printk("ISO connected\n"); } -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) static void create_advanced_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big) { struct bt_iso_big_create_param big_create_param; @@ -377,7 +377,7 @@ static void create_advanced_big(struct bt_le_ext_adv *adv, struct bt_iso_big **b } printk("ISO connected\n"); } -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ static void terminate_big(struct bt_iso_big *big) { @@ -469,7 +469,7 @@ static void test_iso_main(void) terminate_big(big); big = NULL; -#if defined(CONFIG_BT_ISO_ADVANCED) +#if defined(CONFIG_BT_ISO_TEST_PARAMS) /* Quick check to just verify that creating a BIG using advanced/test * parameters work */ @@ -477,7 +477,7 @@ static void test_iso_main(void) terminate_big(big); big = NULL; -#endif /* CONFIG_BT_ISO_ADVANCED */ +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ k_sleep(K_MSEC(10000)); From 84c01bb527b9974edccd7b12d285c07ce5a9be5e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 23 Jan 2023 14:33:54 +0100 Subject: [PATCH 2100/4498] Bluetooth: Audio: Add ISO test parameters to the BAP API Add support for the ISO test parameters in the BAP API. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 25 ++++++++ include/zephyr/bluetooth/audio/bap.h | 57 +++++++++++++++++++ include/zephyr/bluetooth/audio/cap.h | 28 +++++++++ subsys/bluetooth/audio/bap_broadcast_source.c | 13 +++++ subsys/bluetooth/audio/bap_endpoint.h | 6 ++ subsys/bluetooth/audio/bap_stream.c | 4 ++ subsys/bluetooth/audio/bap_unicast_client.c | 24 ++++++-- tests/bluetooth/shell/audio.conf | 1 + 8 files changed, 153 insertions(+), 5 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 5bf6fad74a6..3d5f28372aa 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -479,6 +479,31 @@ struct bt_audio_codec_qos { * Value range 0 to @ref BT_AUDIO_PD_MAX. */ uint32_t pd; + +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + /** @brief Maximum PDU size + * + * Maximum size, in octets, of the payload from link layer to link + * layer. + * + * Value range @ref BT_ISO_PDU_MIN to @ref BT_ISO_PDU_MAX. + */ + uint16_t max_pdu; + + /** @brief Burst number + * + * Value range @ref BT_ISO_BN_MIN to @ref BT_ISO_BN_MAX. + */ + uint8_t burst_number; + + /** @brief Number of subevents + * + * Maximum number of subevents in each CIS or BIS event. + * + * Value range @ref BT_ISO_NSE_MIN to @ref BT_ISO_NSE_MAX. + */ + uint8_t num_subevents; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index db5737f2152..faa51923d0e 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1049,6 +1049,35 @@ struct bt_bap_unicast_group_param { * @note This is a recommendation to the controller, which the controller may ignore. */ uint8_t packing; + +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + /** @brief Central to Peripheral flush timeout + * + * The flush timeout in multiples of ISO_Interval for each payload sent + * from the Central to Peripheral. + * + * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX + */ + uint8_t c_to_p_ft; + + /** @brief Peripheral to Central flush timeout + * + * The flush timeout in multiples of ISO_Interval for each payload sent + * from the Peripheral to Central. + * + * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX. + */ + uint8_t p_to_c_ft; + + /** @brief ISO interval + * + * Time between consecutive CIS anchor points. + * + * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to + * @ref BT_ISO_ISO_INTERVAL_MAX. + */ + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @@ -1439,6 +1468,34 @@ struct bt_bap_broadcast_source_param { * [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00] */ uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; + +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + /** @brief Immediate Repetition Count + * + * The number of times the scheduled payloads are transmitted in a + * given event. + * + * Value range from @ref BT_ISO_MIN_IRC to @ref BT_ISO_MAX_IRC. + */ + uint8_t irc; + + /** @brief Pre-transmission offset + * + * Offset used for pre-transmissions. + * + * Value range from @ref BT_ISO_MIN_PTO to @ref BT_ISO_MAX_PTO. + */ + uint8_t pto; + + /** @brief ISO interval + * + * Time between consecutive BIS anchor points. + * + * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to + * @ref BT_ISO_ISO_INTERVAL_MAX. + */ + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** diff --git a/include/zephyr/bluetooth/audio/cap.h b/include/zephyr/bluetooth/audio/cap.h index fd2c455588c..2327907310f 100644 --- a/include/zephyr/bluetooth/audio/cap.h +++ b/include/zephyr/bluetooth/audio/cap.h @@ -393,6 +393,34 @@ struct bt_cap_initiator_broadcast_create_param { * [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00] */ uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; + +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + /** @brief Immediate Repetition Count + * + * The number of times the scheduled payloads are transmitted in a + * given event. + * + * Value range from @ref BT_ISO_MIN_IRC to @ref BT_ISO_MAX_IRC. + */ + uint8_t irc; + + /** @brief Pre-transmission offset + * + * Offset used for pre-transmissions. + * + * Value range from @ref BT_ISO_MIN_PTO to @ref BT_ISO_MAX_PTO. + */ + uint8_t pto; + + /** @brief ISO interval + * + * Time between consecutive BIS anchor points. + * + * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to + * @ref BT_ISO_ISO_INTERVAL_MAX. + */ + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 8e5010cc007..8978e2816cb 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -289,6 +289,9 @@ static int broadcast_source_setup_stream(uint8_t index, struct bt_bap_stream *st bt_audio_codec_qos_to_iso_qos(iso->chan.qos->tx, qos); bt_audio_codec_cfg_to_iso_path(iso->chan.qos->tx->path, codec_cfg); +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + iso->chan.qos->num_subevents = qos->num_subevents; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ bt_bap_iso_unref(iso); @@ -725,6 +728,11 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param, broadcast_source_set_state(source, BT_BAP_EP_STATE_QOS_CONFIGURED); source->qos = qos; source->packing = param->packing; +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + source->irc = param->irc; + source->pto = param->pto; + source->iso_interval = param->iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ source->encryption = param->encryption; if (source->encryption) { @@ -980,6 +988,11 @@ int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct (void)memcpy(param.bcode, source->broadcast_code, sizeof(param.bcode)); } +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + param.irc = source->irc; + param.pto = source->pto; + param.iso_interval = source->iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ /* Set the enabling state early in case that the BIS is connected before we can manage to * set it afterwards diff --git a/subsys/bluetooth/audio/bap_endpoint.h b/subsys/bluetooth/audio/bap_endpoint.h index 46ef3031e68..1c5aa3d5fc5 100644 --- a/subsys/bluetooth/audio/bap_endpoint.h +++ b/subsys/bluetooth/audio/bap_endpoint.h @@ -83,6 +83,12 @@ struct bt_bap_broadcast_source { struct bt_iso_big *big; struct bt_audio_codec_qos *qos; +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + /* Stored advanced parameters */ + uint8_t irc; + uint8_t pto; + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 /* The codec specific configured data for each stream in the subgroup */ diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 0a6a26014ef..0b1c9cd9d27 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -51,6 +51,10 @@ void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, io->sdu = codec_qos->sdu; io->phy = codec_qos->phy; io->rtn = codec_qos->rtn; +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + io->burst_number = codec_qos->burst_number; + io->max_pdu = codec_qos->max_pdu; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ } #endif /* CONFIG_BT_BAP_UNICAST_CLIENT || \ * CONFIG_BT_BAP_BROADCAST_SOURCE || \ diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 1ff81daeb60..09d1eb1203b 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -2085,13 +2085,23 @@ static void unicast_client_ep_reset(struct bt_conn *conn, uint8_t reason) } static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param, - const struct bt_audio_codec_qos *qos) + const struct bt_audio_codec_qos *qos, + const struct bt_bap_unicast_group_param *group_param) { cig_param->framing = qos->framing; cig_param->packing = BT_ISO_PACKING_SEQUENTIAL; /* TODO: Add to QoS struct */ cig_param->interval = qos->interval; cig_param->latency = qos->latency; cig_param->sca = BT_GAP_SCA_UNKNOWN; + + if (group_param != NULL) { + cig_param->packing = group_param->packing; +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + cig_param->c_to_p_ft = group_param->c_to_p_ft; + cig_param->p_to_c_ft = group_param->p_to_c_ft; + cig_param->iso_interval = group_param->iso_interval; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ + } } /* FIXME: Remove `qos` parameter. Some of the QoS related CIG can be different @@ -2099,7 +2109,8 @@ static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param, * unicast_group instead. */ static int bt_audio_cig_create(struct bt_bap_unicast_group *group, - const struct bt_audio_codec_qos *qos) + const struct bt_audio_codec_qos *qos, + const struct bt_bap_unicast_group_param *group_param) { struct bt_iso_cig_param param; uint8_t cis_count; @@ -2119,7 +2130,7 @@ static int bt_audio_cig_create(struct bt_bap_unicast_group *group, param.num_cis = cis_count; param.cis_channels = group->cis; - bt_audio_codec_qos_to_cig_param(¶m, qos); + bt_audio_codec_qos_to_cig_param(¶m, qos, group_param); err = bt_iso_cig_create(¶m, &group->cig); if (err != 0) { @@ -2153,7 +2164,7 @@ static int bt_audio_cig_reconfigure(struct bt_bap_unicast_group *group, param.num_cis = cis_count; param.cis_channels = group->cis; - bt_audio_codec_qos_to_cig_param(¶m, qos); + bt_audio_codec_qos_to_cig_param(¶m, qos, NULL); err = bt_iso_cig_reconfigure(group->cig, ¶m); if (err != 0) { @@ -2301,6 +2312,9 @@ static void unicast_client_codec_qos_to_iso_qos(struct bt_bap_iso *iso, } bt_audio_codec_qos_to_iso_qos(io_qos, qos); +#if defined(CONFIG_BT_ISO_TEST_PARAMS) + iso->chan.qos->num_subevents = qos->num_subevents; +#endif /* CONFIG_BT_ISO_TEST_PARAMS */ if (other_io_qos != NULL) { /* If the opposing ASE of the CIS is not yet configured, we @@ -2591,7 +2605,7 @@ int bt_bap_unicast_group_create(struct bt_bap_unicast_group_param *param, } } - err = bt_audio_cig_create(unicast_group, group_qos); + err = bt_audio_cig_create(unicast_group, group_qos, param); if (err != 0) { LOG_DBG("bt_audio_cig_create failed: %d", err); unicast_group_free(unicast_group); diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index e43583cc160..2a8d64858f4 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -46,6 +46,7 @@ CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=4 +CONFIG_BT_ISO_TEST_PARAMS=y CONFIG_BT_ISO_TX_BUF_COUNT=10 CONFIG_BT_ISO_RX_BUF_COUNT=20 CONFIG_BT_ISO_TX_MTU=310 From d3a73cdb0eda205414f181835ec8be795ead81e1 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 7 Jun 2023 17:43:15 +0800 Subject: [PATCH 2101/4498] drivers: dma: Add Andestech atcdmac300 driver. Support the Andes atcdmac300 dma driver. Signed-off-by: Kevin Wang --- .../riscv/adp_xc7k_ae350/adp_xc7k_ae350.dts | 4 + .../riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml | 1 + drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 2 + drivers/dma/Kconfig.andes_atcdmac300 | 12 + drivers/dma/dma_andes_atcdmac300.c | 536 ++++++++++++++++++ dts/bindings/dma/andestech,atcdmac300.yaml | 84 +++ dts/riscv/andes/andes_v5_ae350.dtsi | 10 + .../boards/adp_xc7k_ae350.conf | 1 + .../boards/adp_xc7k_ae350.overlay | 9 + .../loop_transfer/boards/adp_xc7k_ae350.conf | 1 + .../boards/adp_xc7k_ae350.overlay | 9 + 12 files changed, 670 insertions(+) create mode 100644 drivers/dma/Kconfig.andes_atcdmac300 create mode 100644 drivers/dma/dma_andes_atcdmac300.c create mode 100644 dts/bindings/dma/andestech,atcdmac300.yaml create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.overlay diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.dts b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.dts index bc39000962b..58c91613057 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.dts +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.dts @@ -211,3 +211,7 @@ &wdt { status = "okay"; }; + +&dma0 { + status = "okay"; +}; diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml index 6d5233e3cd8..5716d7e6e13 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml @@ -15,6 +15,7 @@ supported: - watchdog - mbox - flash + - dma testing: ignore_tags: - bluetooth diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 5a11cd7f324..98e5642c904 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -34,3 +34,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_XMC4XXX dma_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) +zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 37cd83383d8..71059a0e27f 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -64,4 +64,6 @@ source "drivers/dma/Kconfig.mcux_pxp" source "drivers/dma/Kconfig.mcux_smartdma" +source "drivers/dma/Kconfig.andes_atcdmac300" + endif # DMA diff --git a/drivers/dma/Kconfig.andes_atcdmac300 b/drivers/dma/Kconfig.andes_atcdmac300 new file mode 100644 index 00000000000..cb1133cdeb5 --- /dev/null +++ b/drivers/dma/Kconfig.andes_atcdmac300 @@ -0,0 +1,12 @@ +# Andestech ATCDMAC300 configuration options +# Copyright (c) 2023 Andes Technology Corporation. + +# SPDX-License-Identifier: Apache-2.0 + + +config DMA_ANDES_ATCDMAC300 + bool "Using Andes ATCDMAC300 DMA driver" + default y + depends on DT_HAS_ANDESTECH_ATCDMAC300_ENABLED + help + Andes ATCDMAC300 DMA driver. diff --git a/drivers/dma/dma_andes_atcdmac300.c b/drivers/dma/dma_andes_atcdmac300.c new file mode 100644 index 00000000000..ef90868f943 --- /dev/null +++ b/drivers/dma/dma_andes_atcdmac300.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2023 Andes Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT andestech_atcdmac300 + +#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL +#include +LOG_MODULE_REGISTER(dma_andes_atcdmac300); + +#define ATCDMAC100_MAX_CHAN 8 + +#define DMA_ABORT(dev) (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x24) +#define DMA_INT_STATUS(dev) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x30) + +#define DMA_CH_OFFSET(ch) (ch * 0x20) +#define DMA_CH_CTRL(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x40 + DMA_CH_OFFSET(ch)) +#define DMA_CH_TRANSIZE(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x44 + DMA_CH_OFFSET(ch)) +#define DMA_CH_SRC_ADDR_L(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x48 + DMA_CH_OFFSET(ch)) +#define DMA_CH_SRC_ADDR_H(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x4C + DMA_CH_OFFSET(ch)) +#define DMA_CH_DST_ADDR_L(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x50 + DMA_CH_OFFSET(ch)) +#define DMA_CH_DST_ADDR_H(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x54 + DMA_CH_OFFSET(ch)) +#define DMA_CH_LL_PTR_L(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x58 + DMA_CH_OFFSET(ch)) +#define DMA_CH_LL_PTR_H(dev, ch) \ + (((struct dma_atcdmac300_cfg *)dev->config)->base + 0x5C + DMA_CH_OFFSET(ch)) + +/* Source burst size options */ +#define DMA_BSIZE_1 (0) +#define DMA_BSIZE_2 (1) +#define DMA_BSIZE_4 (2) +#define DMA_BSIZE_8 (3) +#define DMA_BSIZE_16 (4) +#define DMA_BSIZE_32 (5) +#define DMA_BSIZE_64 (6) +#define DMA_BSIZE_128 (7) +#define DMA_BSIZE_256 (8) +#define DMA_BSIZE_512 (9) +#define DMA_BSIZE_1024 (10) + +/* Source/Destination transfer width options */ +#define DMA_WIDTH_BYTE (0) +#define DMA_WIDTH_HALFWORD (1) +#define DMA_WIDTH_WORD (2) +#define DMA_WIDTH_DWORD (3) +#define DMA_WIDTH_QWORD (4) +#define DMA_WIDTH_EWORD (5) + +/* Bus interface index */ +#define DMA_INF_IDX0 (0) +#define DMA_INF_IDX1 (1) + +/* DMA Channel Control Register Definition */ +#define DMA_CH_CTRL_SBINF_MASK BIT(31) +#define DMA_CH_CTRL_DBINF_MASK BIT(30) +#define DMA_CH_CTRL_PRIORITY_HIGH BIT(29) +#define DMA_CH_CTRL_SBSIZE_MASK BIT(24) +#define DMA_CH_CTRL_SBSIZE(n) FIELD_PREP(DMA_CH_CTRL_SBSIZE_MASK, (n)) +#define DMA_CH_CTRL_SWIDTH_MASK GENMASK(23, 21) +#define DMA_CH_CTRL_SWIDTH(n) FIELD_PREP(DMA_CH_CTRL_SWIDTH_MASK, (n)) +#define DMA_CH_CTRL_DWIDTH_MASK GENMASK(20, 18) +#define DMA_CH_CTRL_DWIDTH(n) FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (n)) +#define DMA_CH_CTRL_SMODE_HANDSHAKE BIT(17) +#define DMA_CH_CTRL_DMODE_HANDSHAKE BIT(17) +#define DMA_CH_CTRL_SRCADDRCTRL_MASK GENMASK(15, 14) +#define DMA_CH_CTRL_SRCADDR_INC FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (0)) +#define DMA_CH_CTRL_SRCADDR_DEC FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (1)) +#define DMA_CH_CTRL_SRCADDR_FIX FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (2)) +#define DMA_CH_CTRL_DSTADDRCTRL_MASK GENMASK(13, 12) +#define DMA_CH_CTRL_DSTADDR_INC FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (0)) +#define DMA_CH_CTRL_DSTADDR_DEC FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (1)) +#define DMA_CH_CTRL_DSTADDR_FIX FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (2)) +#define DMA_CH_CTRL_SRCREQ_MASK GENMASK(11, 8) +#define DMA_CH_CTRL_SRCREQ(n) FIELD_PREP(DMA_CH_CTRL_SRCREQ_MASK, (n)) +#define DMA_CH_CTRL_DSTREQ_MASK GENMASK(7, 4) +#define DMA_CH_CTRL_DSTREQ(n) FIELD_PREP(DMA_CH_CTRL_DSTREQ_MASK, (n)) +#define DMA_CH_CTRL_INTABT BIT(3) +#define DMA_CH_CTRL_INTERR BIT(2) +#define DMA_CH_CTRL_INTTC BIT(1) +#define DMA_CH_CTRL_ENABLE BIT(0) + +/* DMA Interrupt Status Register Definition */ +#define DMA_INT_STATUS_TC_MASK GENMASK(23, 16) +#define DMA_INT_STATUS_ABORT_MASK GENMASK(15, 8) +#define DMA_INT_STATUS_ERROR_MASK GENMASK(7, 0) +#define DMA_INT_STATUS_TC_VAL(x) FIELD_GET(DMA_INT_STATUS_TC_MASK, (x)) +#define DMA_INT_STATUS_ABORT_VAL(x) FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (x)) +#define DMA_INT_STATUS_ERROR_VAL(x) FIELD_GET(DMA_INT_STATUS_ERROR_MASK, (x)) +#define DMA_INT_STATUS_CH_MSK(ch) (0x111 << ch) + +typedef void (*atcdmac300_cfg_func_t)(void); + +struct chain_block { + uint32_t ctrl; + uint32_t transize; + uint32_t srcaddrl; + uint32_t srcaddrh; + uint32_t dstaddrl; + uint32_t dstaddrh; + uint32_t llpointerl; + uint32_t llpointerh; +#if __riscv_xlen == 32 + uint32_t reserved; +#endif + struct chain_block *next_block; +}; + +/* data for each DMA channel */ +struct dma_chan_data { + void *blkuser_data; + dma_callback_t blkcallback; + struct chain_block *head_block; + struct dma_status status; +}; + +/* Device run time data */ +struct dma_atcdmac300_data { + struct dma_chan_data chan[ATCDMAC100_MAX_CHAN]; + struct k_spinlock lock; +}; + +/* Device constant configuration parameters */ +struct dma_atcdmac300_cfg { + atcdmac300_cfg_func_t irq_config; + uint32_t base; + uint32_t irq_num; +}; + +static struct __aligned(64) + chain_block dma_chain[ATCDMAC100_MAX_CHAN][sizeof(struct chain_block) * 16]; + +static void dma_atcdmac300_isr(const struct device *dev) +{ + uint32_t int_status, int_ch_status, channel; + struct dma_atcdmac300_data *const data = dev->data; + struct dma_chan_data *ch_data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + int_status = sys_read32(DMA_INT_STATUS(dev)); + /* Clear interrupt*/ + sys_write32(int_status, DMA_INT_STATUS(dev)); + + k_spin_unlock(&data->lock, key); + + /* Handle terminal count status */ + int_ch_status = DMA_INT_STATUS_TC_VAL(int_status); + while (int_ch_status) { + channel = find_msb_set(int_ch_status) - 1; + int_ch_status &= ~(BIT(channel)); + + ch_data = &data->chan[channel]; + if (ch_data->blkcallback) { + ch_data->blkcallback(dev, ch_data->blkuser_data, channel, 0); + } + data->chan[channel].status.busy = false; + } + + /* Handle error status */ + int_ch_status = DMA_INT_STATUS_ERROR_VAL(int_status); + while (int_ch_status) { + channel = find_msb_set(int_ch_status) - 1; + int_ch_status &= ~(BIT(channel)); + + ch_data = &data->chan[channel]; + if (ch_data->blkcallback) { + ch_data->blkcallback(dev, ch_data->blkuser_data, channel, -EIO); + } + } +} + +static int dma_atcdmac300_config(const struct device *dev, uint32_t channel, + struct dma_config *cfg) +{ + struct dma_atcdmac300_data *const data = dev->data; + uint32_t src_width, dst_width, src_burst_size, ch_ctrl, tfr_size; + int32_t ret = 0; + struct dma_block_config *cfg_blocks; + k_spinlock_key_t key; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + __ASSERT_NO_MSG(cfg->source_data_size == cfg->dest_data_size); + __ASSERT_NO_MSG(cfg->source_burst_length == cfg->dest_burst_length); + + if (cfg->source_data_size != 1 && cfg->source_data_size != 2 && + cfg->source_data_size != 4) { + LOG_ERR("Invalid 'source_data_size' value"); + ret = -EINVAL; + goto end; + } + + cfg_blocks = cfg->head_block; + if (cfg_blocks == NULL) { + ret = -EINVAL; + goto end; + } + + tfr_size = cfg_blocks->block_size/cfg->source_data_size; + if (tfr_size == 0) { + ret = -EINVAL; + goto end; + } + + ch_ctrl = 0; + + switch (cfg->channel_direction) { + case MEMORY_TO_MEMORY: + break; + case MEMORY_TO_PERIPHERAL: + ch_ctrl |= DMA_CH_CTRL_DSTREQ(cfg->dma_slot); + ch_ctrl |= DMA_CH_CTRL_DMODE_HANDSHAKE; + break; + case PERIPHERAL_TO_MEMORY: + ch_ctrl |= DMA_CH_CTRL_SRCREQ(cfg->dma_slot); + ch_ctrl |= DMA_CH_CTRL_SMODE_HANDSHAKE; + break; + default: + ret = -EINVAL; + goto end; + } + + + switch (cfg_blocks->source_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + switch (cfg_blocks->dest_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + ch_ctrl |= DMA_CH_CTRL_INTABT; + + /* Disable the error callback */ + if (!cfg->error_callback_en) { + ch_ctrl |= DMA_CH_CTRL_INTERR; + } + + src_width = find_msb_set(cfg->source_data_size) - 1; + dst_width = find_msb_set(cfg->dest_data_size) - 1; + src_burst_size = find_msb_set(cfg->source_burst_length) - 1; + + ch_ctrl |= DMA_CH_CTRL_SWIDTH(src_width) | + DMA_CH_CTRL_DWIDTH(dst_width) | + DMA_CH_CTRL_SBSIZE(src_burst_size); + + + /* Reset DMA channel configuration */ + sys_write32(0, DMA_CH_CTRL(dev, channel)); + + key = k_spin_lock(&data->lock); + /* Clear DMA interrupts status */ + sys_write32(DMA_INT_STATUS_CH_MSK(channel), DMA_INT_STATUS(dev)); + k_spin_unlock(&data->lock, key); + + /* Set transfer size */ + sys_write32(tfr_size, DMA_CH_TRANSIZE(dev, channel)); + + /* Update the status of channel */ + data->chan[channel].status.dir = cfg->channel_direction; + data->chan[channel].status.pending_length = cfg->source_data_size; + + /* Configure a callback appropriately depending on whether the + * interrupt is requested at the end of transaction completion or + * at the end of each block. + */ + data->chan[channel].blkcallback = cfg->dma_callback; + data->chan[channel].blkuser_data = cfg->user_data; + + sys_write32(ch_ctrl, DMA_CH_CTRL(dev, channel)); + + /* Set source and destination address */ + sys_write32(cfg_blocks->source_address, + DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(0, DMA_CH_SRC_ADDR_H(dev, channel)); + sys_write32(cfg_blocks->dest_address, + DMA_CH_DST_ADDR_L(dev, channel)); + sys_write32(0, DMA_CH_DST_ADDR_H(dev, channel)); + + if (cfg->dest_chaining_en == 1 && cfg_blocks->next_block) { + uint32_t current_block_idx = 0; + + sys_write32((uint32_t)((long)&dma_chain[channel][current_block_idx]), + DMA_CH_LL_PTR_L(dev, channel)); + sys_write32(0, DMA_CH_LL_PTR_H(dev, channel)); + + for (cfg_blocks = cfg_blocks->next_block; cfg_blocks != NULL; + cfg_blocks = cfg_blocks->next_block) { + + ch_ctrl &= ~(DMA_CH_CTRL_SRCADDRCTRL_MASK | + DMA_CH_CTRL_DSTADDRCTRL_MASK); + + switch (cfg_blocks->source_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + switch (cfg_blocks->dest_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + dma_chain[channel][current_block_idx].ctrl = ch_ctrl; + dma_chain[channel][current_block_idx].transize = + cfg_blocks->block_size/cfg->source_data_size; + + dma_chain[channel][current_block_idx].srcaddrl = + (uint32_t)cfg_blocks->source_address; + dma_chain[channel][current_block_idx].srcaddrh = 0x0; + + dma_chain[channel][current_block_idx].dstaddrl = + (uint32_t)((long)cfg_blocks->dest_address); + dma_chain[channel][current_block_idx].dstaddrh = 0x0; + + if (cfg_blocks->next_block) { + dma_chain[channel][current_block_idx].llpointerl = + (uint32_t)&dma_chain[channel][current_block_idx + 1]; + dma_chain[channel][current_block_idx].llpointerh = 0x0; + + current_block_idx = current_block_idx + 1; + + } else { + dma_chain[channel][current_block_idx].llpointerl = 0x0; + dma_chain[channel][current_block_idx].llpointerh = 0x0; + dma_chain[channel][current_block_idx].next_block = NULL; + } + } + } else { + /* Single transfer is supported, but Chain transfer is still + * not supported. Therefore, set LLPointer to zero + */ + sys_write32(0, DMA_CH_LL_PTR_L(dev, channel)); + sys_write32(0, DMA_CH_LL_PTR_H(dev, channel)); + } + +end: + return ret; +} + +static int dma_atcdmac300_reload(const struct device *dev, uint32_t channel, + uint32_t src, uint32_t dst, size_t size) +{ + uint32_t src_width; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + /* Set source and destination address */ + sys_write32(src, DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(0, DMA_CH_SRC_ADDR_H(dev, channel)); + sys_write32(dst, DMA_CH_DST_ADDR_L(dev, channel)); + sys_write32(0, DMA_CH_DST_ADDR_H(dev, channel)); + + src_width = FIELD_GET(DMA_CH_CTRL_SWIDTH_MASK, sys_read32(DMA_CH_CTRL(dev, channel))); + src_width = BIT(src_width); + + /* Set transfer size */ + sys_write32(size/src_width, DMA_CH_TRANSIZE(dev, channel)); + + return 0; +} + +static int dma_atcdmac300_transfer_start(const struct device *dev, + uint32_t channel) +{ + struct dma_atcdmac300_data *const data = dev->data; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + sys_write32(sys_read32(DMA_CH_CTRL(dev, channel)) | DMA_CH_CTRL_ENABLE, + DMA_CH_CTRL(dev, channel)); + + data->chan[channel].status.busy = true; + + return 0; +} + +static int dma_atcdmac300_transfer_stop(const struct device *dev, + uint32_t channel) +{ + struct dma_atcdmac300_data *const data = dev->data; + k_spinlock_key_t key; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + sys_write32(BIT(channel), DMA_ABORT(dev)); + sys_write32(0, DMA_CH_CTRL(dev, channel)); + sys_write32(FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (channel)), DMA_INT_STATUS(dev)); + data->chan[channel].status.busy = false; + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int dma_atcdmac300_init(const struct device *dev) +{ + const struct dma_atcdmac300_cfg *const config = (struct dma_atcdmac300_cfg *)dev->config; + uint32_t ch_num; + + /* Disable all channels and Channel interrupts */ + for (ch_num = 0; ch_num < ATCDMAC100_MAX_CHAN; ch_num++) { + sys_write32(0, DMA_CH_CTRL(dev, ch_num)); + } + + sys_write32(0xFFFFFF, DMA_INT_STATUS(dev)); + + /* Configure interrupts */ + config->irq_config(); + + irq_enable(config->irq_num); + + return 0; +} + +static int dma_atcdmac300_get_status(const struct device *dev, + uint32_t channel, + struct dma_status *stat) +{ + struct dma_atcdmac300_data *const data = dev->data; + + stat->busy = data->chan[channel].status.busy; + stat->dir = data->chan[channel].status.dir; + stat->pending_length = data->chan[channel].status.pending_length; + + return 0; +} + +static const struct dma_driver_api dma_atcdmac300_api = { + .config = dma_atcdmac300_config, + .reload = dma_atcdmac300_reload, + .start = dma_atcdmac300_transfer_start, + .stop = dma_atcdmac300_transfer_stop, + .get_status = dma_atcdmac300_get_status +}; + +#define ATCDMAC300_INIT(n) \ + \ + static void dma_atcdmac300_irq_config_##n(void); \ + \ + static const struct dma_atcdmac300_cfg dma_config_##n = { \ + .irq_config = dma_atcdmac300_irq_config_##n, \ + .base = DT_INST_REG_ADDR(n), \ + .irq_num = DT_INST_IRQN(n), \ + }; \ + \ + static struct dma_atcdmac300_data dma_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(0, \ + dma_atcdmac300_init, \ + NULL, \ + &dma_data_##n, \ + &dma_config_##n, \ + POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &dma_atcdmac300_api); \ + \ + static void dma_atcdmac300_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + 1, \ + dma_atcdmac300_isr, \ + DEVICE_DT_INST_GET(n), \ + 0); \ + } + + +DT_INST_FOREACH_STATUS_OKAY(ATCDMAC300_INIT) diff --git a/dts/bindings/dma/andestech,atcdmac300.yaml b/dts/bindings/dma/andestech,atcdmac300.yaml new file mode 100644 index 00000000000..931cc1ffaeb --- /dev/null +++ b/dts/bindings/dma/andestech,atcdmac300.yaml @@ -0,0 +1,84 @@ +# +# Copyright (c) 2023 Andes Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 + +compatible: "andestech,atcdmac300" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + chain-transfer: + type: int + + "#dma-cells": + const: 3 + +dma-cells: + - channel + - slot + - channel-config + +description: | + Andes DMA controller + channel: a phandle to the DMA controller plus the following four integer cells: + 1. channel: the dma channel + 2. slot: DMA peripherial request ID + 3. channel-config: A 32bit mask specifying the DMA channel configuration + which is device dependent: + -bit 0-1 : Direction (see dma.h) + 0x0: MEM to MEM + 0x1: MEM to PERIPH + 0x2: PERIPH to MEM + 0x3: reserved for PERIPH to PERIPH + -bit 2 : Peripheral Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 3 : Memory Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 4-6 : Peripheral data size + 0x0: Byte (8 bits) + 0x1: Half-word (16 bits) + 0x2: Word (32 bits) + 0x3: Double word (64 bits) + 0x4: Quad word (128 bits) + 0x5: Eight word (256 bits) + 0x6-0x7: reserved + -bit 7-9 : Memory data size + 0x0: Byte (8 bits) + 0x1: Half-word (16 bits) + 0x2: Word (32 bits) + 0x3: Double word (64 bits) + 0x4: Quad word (128 bits) + 0x5: Eight word (256 bits) + 0x6-0x7: reserved + -bit 10 : Priority level + 0x0: lower priority + 0x1: higher priority + + examples for andes_v5_ae350 DMA instance + dma0: dma0@f0c00000 { + compatible = "andestech,atcdmac300"; + ... + dma-channels = <8>; + dma-requests = <16>; + status = "disabled"; + label = "DMA_0"; + }; + + For the client part, example for andes_ae350 DMA instance + Tx using channel 2, slot 0 + Rx using channel 3, slot 1 + spi1: spi@f0f00000 { + compatible = "andestech,atcspi200" + dmas = <&dma0 2 0 0x0129>, + <&dma0 3 1 0x012A>; + dma-names = "tx", "rx"; + }; diff --git a/dts/riscv/andes/andes_v5_ae350.dtsi b/dts/riscv/andes/andes_v5_ae350.dtsi index 1b5abf0ee8c..7af3e25ef62 100644 --- a/dts/riscv/andes/andes_v5_ae350.dtsi +++ b/dts/riscv/andes/andes_v5_ae350.dtsi @@ -275,6 +275,9 @@ reg-names = "control", "mem"; interrupts = <4 1>; interrupt-parent = <&plic0>; + dmas = <&dma0 0 0 0x009>, + <&dma0 1 1 0x00A>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; clock-frequency = <66000000>; @@ -287,6 +290,9 @@ reg-names = "control"; interrupts = <5 1>; interrupt-parent = <&plic0>; + dmas = <&dma0 2 2 0x009>, + <&dma0 3 3 0x00A>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; clock-frequency = <66000000>; @@ -299,6 +305,10 @@ interrupts = <10 1>; interrupt-parent = <&plic0>; dma-channels = <8>; + dma-requests = <16>; + chain-transfer = <1>; + #dma-cells = <3>; + status = "disabled"; }; eth0: eth@e0100000 { diff --git a/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.conf b/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.conf new file mode 100644 index 00000000000..c448e14811f --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.conf @@ -0,0 +1 @@ +CONFIG_NOCACHE_MEMORY=y diff --git a/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.overlay b/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.overlay new file mode 100644 index 00000000000..c58ffdfcc20 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/adp_xc7k_ae350.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Andes Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma0: &dma0 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.conf b/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.conf new file mode 100644 index 00000000000..c448e14811f --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.conf @@ -0,0 +1 @@ +CONFIG_NOCACHE_MEMORY=y diff --git a/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.overlay b/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.overlay new file mode 100644 index 00000000000..c58ffdfcc20 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/adp_xc7k_ae350.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Andes Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma0: &dma0 { + status = "okay"; +}; From debc65fa631d5497a85b0a418b96e1df323de0f3 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Tue, 27 Jun 2023 13:07:42 -0600 Subject: [PATCH 2102/4498] drivers: flash: atmel SAM0 fix flash_write to handle smaller length. Fix flash_sam0_write to handle byte lengths smaller than FLASH_PAGE_SIZE Signed-off-by: Daniel Evans --- drivers/flash/flash_sam0.c | 43 ++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/flash/flash_sam0.c b/drivers/flash/flash_sam0.c index b5fc5567cb8..eb55c5d36a0 100644 --- a/drivers/flash/flash_sam0.c +++ b/drivers/flash/flash_sam0.c @@ -5,6 +5,7 @@ */ #define DT_DRV_COMPAT atmel_sam0_nvmctrl +#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) #define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL #include @@ -17,6 +18,9 @@ LOG_MODULE_REGISTER(flash_sam0); #include #include +#define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size) +BUILD_ASSERT((FLASH_WRITE_BLK_SZ % sizeof(uint32_t)) == 0, "unsupported write-block-size"); + /* * Zephyr and the SAM0 series use different and conflicting names for * the erasable units and programmable units: @@ -67,7 +71,7 @@ static const struct flash_parameters flash_sam0_parameters = { #if CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES .write_block_size = 1, #else - .write_block_size = DT_PROP(DT_INST(0, soc_nv_flash), write_block_size), + .write_block_size = FLASH_WRITE_BLK_SZ, #endif .erase_value = 0xff, }; @@ -147,11 +151,18 @@ static int flash_sam0_check_status(off_t offset) return 0; } +/* + * Data to be written to the NVM block are first written to and stored + * in an internal buffer called the page buffer. The page buffer contains + * the same number of bytes as an NVM page. Writes to the page buffer must + * be 16 or 32 bits. 8-bit writes to the page buffer are not allowed and + * will cause a system exception + */ static int flash_sam0_write_page(const struct device *dev, off_t offset, - const void *data) + const void *data, size_t len) { const uint32_t *src = data; - const uint32_t *end = src + FLASH_PAGE_SIZE / sizeof(*src); + const uint32_t *end = src + (len / sizeof(*src)); uint32_t *dst = FLASH_MEM(offset); int err; @@ -178,7 +189,7 @@ static int flash_sam0_write_page(const struct device *dev, off_t offset, return err; } - if (memcmp(data, FLASH_MEM(offset), FLASH_PAGE_SIZE) != 0) { + if (memcmp(data, FLASH_MEM(offset), len) != 0) { LOG_ERR("verify error at offset 0x%lx", (long)offset); return -EIO; } @@ -213,7 +224,7 @@ static int flash_sam0_commit(const struct device *dev, off_t base) for (page = 0; page < PAGES_PER_ROW; page++) { err = flash_sam0_write_page( dev, base + page * FLASH_PAGE_SIZE, - &ctx->buf[page * FLASH_PAGE_SIZE]); + &ctx->buf[page * FLASH_PAGE_SIZE], ROW_SIZE); if (err != 0) { return err; } @@ -280,19 +291,18 @@ static int flash_sam0_write(const struct device *dev, off_t offset, { const uint8_t *pdata = data; int err; - size_t idx; err = flash_sam0_valid_range(offset, len); if (err != 0) { return err; } - if ((offset % FLASH_PAGE_SIZE) != 0) { + if ((offset % FLASH_WRITE_BLK_SZ) != 0) { LOG_WRN("0x%lx: not on a write block boundary", (long)offset); return -EINVAL; } - if ((len % FLASH_PAGE_SIZE) != 0) { + if ((len % FLASH_WRITE_BLK_SZ) != 0) { LOG_WRN("%zu: not a integer number of write blocks", len); return -EINVAL; } @@ -301,12 +311,20 @@ static int flash_sam0_write(const struct device *dev, off_t offset, err = flash_sam0_write_protection(dev, false); if (err == 0) { - for (idx = 0; idx < len; idx += FLASH_PAGE_SIZE) { - err = flash_sam0_write_page(dev, offset + idx, - &pdata[idx]); + /* Maximum size without crossing a page */ + size_t eop_len = FLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE); + size_t write_len = MIN(len, eop_len); + + while (len > 0) { + err = flash_sam0_write_page(dev, offset, pdata, write_len); if (err != 0) { break; } + + offset += write_len; + pdata += write_len; + len -= write_len; + write_len = MIN(len, FLASH_PAGE_SIZE); } } @@ -454,6 +472,9 @@ static int flash_sam0_init(const struct device *dev) #ifdef NVMCTRL_CTRLB_MANW /* Require an explicit write command */ NVMCTRL->CTRLB.bit.MANW = 1; +#elif NVMCTRL_CTRLA_WMODE + /* Set manual write mode */ + NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN_Val; #endif return flash_sam0_write_protection(dev, false); From 105fb2a6e7461347ee0766282f3c8af8b86b4a5f Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Wed, 16 Aug 2023 12:47:11 -0600 Subject: [PATCH 2103/4498] boards: arm: atmel: Add flash support to SAM0 xpro boards Add the following XPRO boards to flash driver test: SAMD20, SAMDE54 and SAMR21 Signed-off-by: Daniel Evans Co-authored-by: Gerson Fernando Budke nandojve@gmail.com --- boards/arm/atsamd20_xpro/atsamd20_xpro.yaml | 1 + boards/arm/atsame54_xpro/atsame54_xpro.dts | 18 ++++++++++++++++++ boards/arm/atsame54_xpro/atsame54_xpro.yaml | 1 + boards/arm/atsamr21_xpro/atsamr21_xpro.dts | 18 ++++++++++++++++++ boards/arm/atsamr21_xpro/atsamr21_xpro.yaml | 1 + tests/drivers/flash/common/testcase.yaml | 5 +++++ 6 files changed, 44 insertions(+) diff --git a/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml b/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml index d0a541196fb..4138e137100 100644 --- a/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml +++ b/boards/arm/atsamd20_xpro/atsamd20_xpro.yaml @@ -10,6 +10,7 @@ toolchain: - xtools supported: - adc + - flash - gpio - i2c - spi diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.dts b/boards/arm/atsame54_xpro/atsame54_xpro.dts index b5f9ab19b39..a9bc92ad8a7 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.dts +++ b/boards/arm/atsame54_xpro/atsame54_xpro.dts @@ -138,3 +138,21 @@ zephyr_udc0: &usb0 { reg = <0>; }; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@fc000 { + label = "storage"; + reg = <0x000fc000 0x00004000>; + }; + }; +}; diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.yaml b/boards/arm/atsame54_xpro/atsame54_xpro.yaml index 27238959131..f23ef379363 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.yaml +++ b/boards/arm/atsame54_xpro/atsame54_xpro.yaml @@ -12,6 +12,7 @@ toolchain: - xtools supported: - adc + - flash - gpio - pwm - spi diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts index 9dd7f6f91d6..86981d86cfe 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts @@ -207,3 +207,21 @@ ext2_spi: &sercom5 { ext2_i2c: &sercom1 { }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@3c000 { + label = "storage"; + reg = <0x0003c000 0x00004000>; + }; + }; +}; diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml index 5ecfcb166c2..04608ed2afb 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml @@ -13,6 +13,7 @@ toolchain: - xtools supported: - adc + - flash - gpio - i2c - netif diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index d9cf78ebcab..f7ee0b7fc6d 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -83,3 +83,8 @@ tests: extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor_wp_hold.overlay + drivers.flash.common.sam0: + platform_allow: + - atsamd20_xpro + - atsamr21_xpro + - atsame54_xpro From 9e6b1d5ba6d50c3be3c0d08a6dc7f61a9aa95240 Mon Sep 17 00:00:00 2001 From: Niek Ilmer Date: Thu, 22 Jun 2023 15:08:49 +0200 Subject: [PATCH 2104/4498] SOC: Smartbond: Add DA14695 This commits adds the DA14695 variant. The main difference with the DA14699 is a smaller package with less GPIO. Signed-off-by: Niek Ilmer --- dts/arm/renesas/smartbond/da14695.dtsi | 12 ++++++++++++ .../da1469x/Kconfig.defconfig.da14695 | 9 +++++++++ soc/arm/renesas_smartbond/da1469x/Kconfig.soc | 5 ++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 dts/arm/renesas/smartbond/da14695.dtsi create mode 100644 soc/arm/renesas_smartbond/da1469x/Kconfig.defconfig.da14695 diff --git a/dts/arm/renesas/smartbond/da14695.dtsi b/dts/arm/renesas/smartbond/da14695.dtsi new file mode 100644 index 00000000000..37d75e4ecc4 --- /dev/null +++ b/dts/arm/renesas/smartbond/da14695.dtsi @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "da1469x.dtsi" + +&sram0 { + reg = <0x20000000 DT_SIZE_K(512)>; +}; + +&gpio1 { + ngpios = <12>; +}; diff --git a/soc/arm/renesas_smartbond/da1469x/Kconfig.defconfig.da14695 b/soc/arm/renesas_smartbond/da1469x/Kconfig.defconfig.da14695 new file mode 100644 index 00000000000..101e275b79f --- /dev/null +++ b/soc/arm/renesas_smartbond/da1469x/Kconfig.defconfig.da14695 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +if SOC_DA14695 + +config SOC + default "da14695" + +endif # SOC_DA14695 diff --git a/soc/arm/renesas_smartbond/da1469x/Kconfig.soc b/soc/arm/renesas_smartbond/da1469x/Kconfig.soc index edce4039867..b1e7eddb850 100644 --- a/soc/arm/renesas_smartbond/da1469x/Kconfig.soc +++ b/soc/arm/renesas_smartbond/da1469x/Kconfig.soc @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Renesas Electronics Corporation +# Copyright (c) 2022-2023 Renesas Electronics Corporation and/or its affiliates # SPDX-License-Identifier: Apache-2.0 choice @@ -8,4 +8,7 @@ choice config SOC_DA14699 bool "DA14699" +config SOC_DA14695 + bool "DA14695" + endchoice From 4b38ee65dbed3546a604081b8f05842b013d38bf Mon Sep 17 00:00:00 2001 From: Niek Ilmer Date: Thu, 6 Jul 2023 10:11:43 +0200 Subject: [PATCH 2105/4498] devicetree: DA1469x: Add UART2 and UART3 to devicetree This commit adds devicetree bindings for UART2 and 3 Signed-off-by: Niek Ilmer --- dts/arm/renesas/smartbond/da1469x.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dts/arm/renesas/smartbond/da1469x.dtsi b/dts/arm/renesas/smartbond/da1469x.dtsi index fa6ccd6bb25..2df3f5bdd43 100644 --- a/dts/arm/renesas/smartbond/da1469x.dtsi +++ b/dts/arm/renesas/smartbond/da1469x.dtsi @@ -199,6 +199,22 @@ status = "disabled"; }; + uart2: uart@50020100 { + compatible = "renesas,smartbond-uart"; + reg = <0x50020100 0x100>; + periph-clock-config = <0x02>; + interrupts = <6 0>; + status = "disabled"; + }; + + uart3: uart@50020200 { + compatible = "renesas,smartbond-uart"; + reg = <0x50020200 0x100>; + periph-clock-config = <0x08>; + interrupts = <7 0>; + status = "disabled"; + }; + adc: adc@50030900 { compatible = "renesas,smartbond-adc"; reg = <0x50030900 0x1C>; From bbba08ffe6dc8ee1ca7eabacde5fc167b2e9d4da Mon Sep 17 00:00:00 2001 From: Niek Ilmer Date: Wed, 21 Jun 2023 13:46:37 +0200 Subject: [PATCH 2106/4498] Boards: add da14695_dk_usb This commit adds board files for the da14695_dk_usb. The board features two Mikrobus sockets, these are added to the dts Signed-off-by: Niek Ilmer --- boards/arm/da14695_dk_usb/Kconfig | 4 + boards/arm/da14695_dk_usb/Kconfig.board | 8 + boards/arm/da14695_dk_usb/Kconfig.defconfig | 11 + boards/arm/da14695_dk_usb/board.cmake | 10 + .../da14695_dk_usb-pinctrl.dtsi | 78 ++++++ boards/arm/da14695_dk_usb/da14695_dk_usb.dts | 223 ++++++++++++++++++ boards/arm/da14695_dk_usb/da14695_dk_usb.yaml | 16 ++ .../da14695_dk_usb/da14695_dk_usb_defconfig | 22 ++ .../doc/da14695-00hqdevkt-u-usb-board.jpg | Bin 0 -> 52172 bytes boards/arm/da14695_dk_usb/doc/index.rst | 116 +++++++++ 10 files changed, 488 insertions(+) create mode 100644 boards/arm/da14695_dk_usb/Kconfig create mode 100644 boards/arm/da14695_dk_usb/Kconfig.board create mode 100644 boards/arm/da14695_dk_usb/Kconfig.defconfig create mode 100644 boards/arm/da14695_dk_usb/board.cmake create mode 100644 boards/arm/da14695_dk_usb/da14695_dk_usb-pinctrl.dtsi create mode 100644 boards/arm/da14695_dk_usb/da14695_dk_usb.dts create mode 100644 boards/arm/da14695_dk_usb/da14695_dk_usb.yaml create mode 100644 boards/arm/da14695_dk_usb/da14695_dk_usb_defconfig create mode 100644 boards/arm/da14695_dk_usb/doc/da14695-00hqdevkt-u-usb-board.jpg create mode 100644 boards/arm/da14695_dk_usb/doc/index.rst diff --git a/boards/arm/da14695_dk_usb/Kconfig b/boards/arm/da14695_dk_usb/Kconfig new file mode 100644 index 00000000000..38ccd826507 --- /dev/null +++ b/boards/arm/da14695_dk_usb/Kconfig @@ -0,0 +1,4 @@ +# DA14695 Development Kit USB board configuration + +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm/da14695_dk_usb/Kconfig.board b/boards/arm/da14695_dk_usb/Kconfig.board new file mode 100644 index 00000000000..67dbe731ffa --- /dev/null +++ b/boards/arm/da14695_dk_usb/Kconfig.board @@ -0,0 +1,8 @@ +# DA14695 Development Kit USB board configuration + +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_DA14695_DK_USB + bool "DA14695 Development Kit USB board" + depends on SOC_SERIES_DA1469X diff --git a/boards/arm/da14695_dk_usb/Kconfig.defconfig b/boards/arm/da14695_dk_usb/Kconfig.defconfig new file mode 100644 index 00000000000..8208a705bd8 --- /dev/null +++ b/boards/arm/da14695_dk_usb/Kconfig.defconfig @@ -0,0 +1,11 @@ +# DA14695 Development Kit USB board configuration + +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_DA14695_DK_USB + +config BOARD + default "da14695_dk_usb" + +endif # BOARD_DA14695_DK_USB diff --git a/boards/arm/da14695_dk_usb/board.cmake b/boards/arm/da14695_dk_usb/board.cmake new file mode 100644 index 00000000000..fc5981bb391 --- /dev/null +++ b/boards/arm/da14695_dk_usb/board.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(ezflashcli) +board_runner_args(jlink --device=DA14695) +include(${ZEPHYR_BASE}/boards/common/ezflashcli.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/da14695_dk_usb/da14695_dk_usb-pinctrl.dtsi b/boards/arm/da14695_dk_usb/da14695_dk_usb-pinctrl.dtsi new file mode 100644 index 00000000000..d16ad945fa8 --- /dev/null +++ b/boards/arm/da14695_dk_usb/da14695_dk_usb-pinctrl.dtsi @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart_default: uart_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + uart2_default: uart2_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + uart3_default: uart3_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + i2c_default: i2c_default { + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; + + i2c2_default: i2c2_default { + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; + + spi_controller: spi_controller { + group1 { + pinmux = < SMARTBOND_PINMUX(SPI_CLK, 0, 21) >, + ; + output-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + spi2_controller: spi2_controller { + group1 { + pinmux = < SMARTBOND_PINMUX(SPI2_CLK, 1, 3) >, + ; + output-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; +}; diff --git a/boards/arm/da14695_dk_usb/da14695_dk_usb.dts b/boards/arm/da14695_dk_usb/da14695_dk_usb.dts new file mode 100644 index 00000000000..eff5299dcff --- /dev/null +++ b/boards/arm/da14695_dk_usb/da14695_dk_usb.dts @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "da14695_dk_usb-pinctrl.dtsi" +#include + +/ { + model = "DA14695 series Development Kit USB"; + compatible = "renesas,da14695_dk_usb"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart; + zephyr,shell-uart = &uart; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 6 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "Push button switch K1"; + zephyr,code = ; + }; + }; + + mikrobus_header{ + mikrobus-connector-1 { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 25 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio1 2 0>, /* CS */ + <3 0 &gpio1 3 0>, /* SCK */ + <4 0 &gpio1 4 0>, /* MISO */ + <5 0 &gpio1 5 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 6 0>, /* PWM */ + <7 0 &gpio1 7 0>, /* INT */ + <8 0 &gpio1 8 0>, /* RX */ + <9 0 &gpio0 17 0>, /* TX */ + <10 0 &gpio0 18 0>, /* SCL */ + <11 0 &gpio0 19 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + mikrobus-connector-2 { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 9 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio0 20 0>, /* CS */ + <3 0 &gpio0 21 0>, /* SCK */ + <4 0 &gpio0 24 0>, /* MISO */ + <5 0 &gpio0 26 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 1 0>, /* PWM */ + <7 0 &gpio0 27 0>, /* INT */ + <8 0 &gpio0 28 0>, /* RX */ + <9 0 &gpio0 29 0>, /* TX */ + <10 0 &gpio0 30 0>, /* SCL */ + <11 0 &gpio0 31 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + }; + + aliases { + led0 = &red_led; + watchdog0 = &wdog; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = <32000000>; + #clock-cells = <0>; + }; +}; + +&flash0 { + reg = <0x16000000 DT_SIZE_M(1)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Flash area from 0x0000 to 0x2400 is reserved + * for product header added by flasher. + */ + + boot_partition: partition@2400 { + label = "mcuboot"; + reg = <0x000002400 0x00009c00>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 0x00076000>; + }; + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00082000 0x00076000>; + }; + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart_default>; + pinctrl-names = "default"; +}; + +&uart2 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart2_default>; + pinctrl-names = "default"; +}; + +&uart3 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart3_default>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usbd { + compatible = "renesas,smartbond-usbd"; + status = "okay"; +}; + +&rc32m { + status = "disabled"; +}; + +&xtal32m { + status = "okay"; +}; + +&xtal32k { + status = "okay"; +}; + +&lp_clk { + clock-src = <&xtal32k>; +}; + +&sys_clk { + clock-src = <&xtal32m>; +}; + +&pll { + status = "okay"; +}; +&i2c { + status = "okay"; + pinctrl-0 = <&i2c_default>; + pinctrl-names = "default"; +}; + +&i2c2 { + status = "okay"; + pinctrl-0 = <&i2c2_default>; + pinctrl-names = "default"; +}; + +&spi { + status = "okay"; + pinctrl-0 = <&spi_controller>; + pinctrl-names = "default"; +}; + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_controller>; + pinctrl-names = "default"; +}; + +mikrobus_1_i2c: &i2c {}; + +mikrobus_1_spi: &spi {}; + +mikrobus_1_uart: &uart2 {}; + +mikrobus_2_i2c: &i2c2 {}; + +mikrobus_2_spi: &spi2 {}; + +mikrobus_2_uart: &uart3 {}; diff --git a/boards/arm/da14695_dk_usb/da14695_dk_usb.yaml b/boards/arm/da14695_dk_usb/da14695_dk_usb.yaml new file mode 100644 index 00000000000..1bb6100e339 --- /dev/null +++ b/boards/arm/da14695_dk_usb/da14695_dk_usb.yaml @@ -0,0 +1,16 @@ +identifier: da14695_dk_usb +name: DA14695_DK_USB +type: mcu +arch: arm +ram: 512 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - arduino_gpio + - gpio + - watchdog + - i2c + - spi + - usb_device diff --git a/boards/arm/da14695_dk_usb/da14695_dk_usb_defconfig b/boards/arm/da14695_dk_usb/da14695_dk_usb_defconfig new file mode 100644 index 00000000000..d0a67243034 --- /dev/null +++ b/boards/arm/da14695_dk_usb/da14695_dk_usb_defconfig @@ -0,0 +1,22 @@ +# +# Copyright (c) 2023 Renesas Electronics Corporation and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_DA1469X=y +CONFIG_SOC_DA14695=y +CONFIG_BOARD_DA14695_DK_USB=y + +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_GPIO=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y + +CONFIG_BUILD_OUTPUT_HEX=n + +CONFIG_I2C=y +CONFIG_I2C_CALLBACK=y diff --git a/boards/arm/da14695_dk_usb/doc/da14695-00hqdevkt-u-usb-board.jpg b/boards/arm/da14695_dk_usb/doc/da14695-00hqdevkt-u-usb-board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f0c6021e763af19cb703fe3c5563c711e3f02e8 GIT binary patch literal 52172 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 literal 0 HcmV?d00001 diff --git a/boards/arm/da14695_dk_usb/doc/index.rst b/boards/arm/da14695_dk_usb/doc/index.rst new file mode 100644 index 00000000000..84f5c772d8a --- /dev/null +++ b/boards/arm/da14695_dk_usb/doc/index.rst @@ -0,0 +1,116 @@ +.. _da14695_dk_usb: + +DA14695 Development Kit USB +########################### + +Overview +******** + +The DA14695 Development Kit USB is a low cost development board for DA14695. +The development kit comes with an integrated debugger and an USB hub +to have both the on-chip USB and the J-Link connected via a single port. + +.. figure:: da14695-00hqdevkt-u-usb-board.jpg + :width: 442px + :align: center + :alt: DA14695 Development Kit USB + + DA14695 Development Kit USB (Credit: Renesas Electronics Corporation) + +Hardware +******** + +DA14695 Development Kit USB has two external oscillators. The frequency of +the sleep clock is 32768 Hz. The frequency of the system clock is 32 MHz. + +Supported Features +================== + +The _da14695_dk_usb board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ + +Other hardware features, including the Configurable MAC (CMAC) controller, +are currently not supported by the port. + +For more information about the DA14695 Development Kit see: + +- `DA14695 DK USB website`_ + +System Clock +============ + +The DA14695 Development Kit USB is configured to use the 32 MHz external oscillator +on the board. + +Connections and IOs +=================== + +The DA14695 Development Kit USB has one LED and one push button which can be used +by applications. The UART is connected to on-board serial converter and accessible +via USB1 port on motherboard. + +The pin connections are as follows: + +* LED (red), = P1.01 +* BUTTON, labeled k1 = P0.06 +* UART RX, connected to J-Link serial = P0.08 +* UART TX, connected to J-Link serial = P0.09 + +Programming and Debugging +************************* + +Applications for the ``da14695_dk_usb`` board configuration can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +The DA14695 boots from an external flash connected to QSPI interface. The image +written to flash has to have proper header prepended. The process is simplified +by using dedicated `eZFlashCLI`_ tool that takes care of writing header and can +handle different types of flash chips connected to DA1469x MCU. Follow instructions +on `ezFlashCLI`_ to install the tool. Once installed, flashing can be done in the +usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: da14695_dk_usb + :goals: build flash + +Debugging +========= + +The DA14695 Development Kit USB includes a `J-Link`_ adaptor built-in +which provides both debugging interface and serial port. +Application can be debugged in the usual way once DA14695 Development Kit USB +is connected to PC via USB. + +References +********** + +.. target-notes:: + +.. _DA14695 DK USB website: https://www.renesas.com/us/en/products/wireless-connectivity/bluetooth-low-energy/da14695-00hqdevkt-u-smartbond-da14695-bluetooth-low-energy-52-usb-development-kit +.. _DA1469x Datasheet: https://www.renesas.com/eu/en/document/dst/da1469x-datasheet +.. _J-Link: https://www.segger.com/jlink-debug-probes.html +.. _ezFlashCLI: https://github.com/ezflash/ezFlashCLI/ From 2f7cb40dd22f94022ab529af75693e3462f3d057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Anikiel?= Date: Mon, 7 Aug 2023 12:06:30 +0000 Subject: [PATCH 2107/4498] drivers: sensor: Add driver for SB-TSI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a driver for the SB Temperature Sensor Interface. This is an I2C temperature sensor on AMD SoCs. Signed-off-by: Paweł Anikiel --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/amd_sb_tsi/CMakeLists.txt | 5 + drivers/sensor/amd_sb_tsi/Kconfig | 21 ++++ drivers/sensor/amd_sb_tsi/sb_tsi.c | 131 +++++++++++++++++++ drivers/sensor/amd_sb_tsi/sb_tsi.h | 15 +++ drivers/sensor/amd_sb_tsi/sb_tsi_emul.c | 153 +++++++++++++++++++++++ dts/bindings/sensor/amd,sb-tsi.yaml | 8 ++ tests/drivers/build_all/sensor/i2c.dtsi | 5 + 9 files changed, 340 insertions(+) create mode 100644 drivers/sensor/amd_sb_tsi/CMakeLists.txt create mode 100644 drivers/sensor/amd_sb_tsi/Kconfig create mode 100644 drivers/sensor/amd_sb_tsi/sb_tsi.c create mode 100644 drivers/sensor/amd_sb_tsi/sb_tsi.h create mode 100644 drivers/sensor/amd_sb_tsi/sb_tsi_emul.c create mode 100644 dts/bindings/sensor/amd,sb-tsi.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 782115ca130..7506b62a37f 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory_ifdef(CONFIG_ADXL362 adxl362) add_subdirectory_ifdef(CONFIG_ADXL372 adxl372) add_subdirectory_ifdef(CONFIG_AK8975 ak8975) add_subdirectory_ifdef(CONFIG_AKM09918C akm09918c) +add_subdirectory_ifdef(CONFIG_AMD_SB_TSI amd_sb_tsi) add_subdirectory_ifdef(CONFIG_AMG88XX amg88xx) add_subdirectory_ifdef(CONFIG_AMS_AS5600 ams_as5600) add_subdirectory_ifdef(CONFIG_AMS_IAQ_CORE ams_iAQcore) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index f406b6d1ffe..fae18d967ea 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -66,6 +66,7 @@ source "drivers/sensor/adxl362/Kconfig" source "drivers/sensor/adxl372/Kconfig" source "drivers/sensor/ak8975/Kconfig" source "drivers/sensor/akm09918c/Kconfig" +source "drivers/sensor/amd_sb_tsi/Kconfig" source "drivers/sensor/amg88xx/Kconfig" source "drivers/sensor/ams_as5600/Kconfig" source "drivers/sensor/ams_iAQcore/Kconfig" diff --git a/drivers/sensor/amd_sb_tsi/CMakeLists.txt b/drivers/sensor/amd_sb_tsi/CMakeLists.txt new file mode 100644 index 00000000000..e9a33c445ae --- /dev/null +++ b/drivers/sensor/amd_sb_tsi/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(sb_tsi.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_AMD_SB_TSI sb_tsi_emul.c) diff --git a/drivers/sensor/amd_sb_tsi/Kconfig b/drivers/sensor/amd_sb_tsi/Kconfig new file mode 100644 index 00000000000..93e7ddb52e1 --- /dev/null +++ b/drivers/sensor/amd_sb_tsi/Kconfig @@ -0,0 +1,21 @@ +# SB-TSI configuration options + +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config AMD_SB_TSI + bool "AMD SB Temperature Sensor Interface" + default y + depends on DT_HAS_AMD_SB_TSI_ENABLED + select I2C + help + Enable the driver for SB Temperature Sensor Interface. This + is an I2C temperature sensor on AMD SoCs. + +config EMUL_AMD_SB_TSI + bool "Emulator for AMD SB-TSI" + default y + depends on AMD_SB_TSI + depends on EMUL + help + Enable the hardware emulator for the AMD SB-TSI. diff --git a/drivers/sensor/amd_sb_tsi/sb_tsi.c b/drivers/sensor/amd_sb_tsi/sb_tsi.c new file mode 100644 index 00000000000..de0b91f570d --- /dev/null +++ b/drivers/sensor/amd_sb_tsi/sb_tsi.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT amd_sb_tsi + +#include +#include +#include +#include +#include +#include +#include "sb_tsi.h" + +LOG_MODULE_REGISTER(AMD_SB_TSI, CONFIG_SENSOR_LOG_LEVEL); + +struct sb_tsi_data { + uint8_t sample_int; + uint8_t sample_dec; +}; + +struct sb_tsi_config { + struct i2c_dt_spec i2c; +}; + +static int sb_tsi_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct sb_tsi_data *data = dev->data; + const struct sb_tsi_config *config = dev->config; + enum pm_device_state pm_state; + int res; + + (void)pm_device_state_get(dev, &pm_state); + if (pm_state != PM_DEVICE_STATE_ACTIVE) { + return -EIO; + } + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + /* + * ReadOrder specifies the order for atomically reading the temp. + * The reset value is 0, which means reading Int latches Dec. + */ + res = i2c_reg_read_byte_dt(&config->i2c, SB_TSI_TEMP_INT, &data->sample_int); + if (res) { + return res; + } + + res = i2c_reg_read_byte_dt(&config->i2c, SB_TSI_TEMP_DEC, &data->sample_dec); + if (res) { + return res; + } + + return 0; +} + +static int sb_tsi_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct sb_tsi_data *data = dev->data; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + val->val1 = data->sample_int; + val->val2 = (data->sample_dec >> SB_TSI_TEMP_DEC_SHIFT) * + (1000000 / SB_TSI_TEMP_DEC_SCALE); + + return 0; +} + +static const struct sensor_driver_api sb_tsi_driver_api = { + .sample_fetch = sb_tsi_sample_fetch, + .channel_get = sb_tsi_channel_get, +}; + +static int sb_tsi_init(const struct device *dev) +{ + const struct sb_tsi_config *config = dev->config; + int res = 0; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_init_suspended(dev); + + res = pm_device_runtime_enable(dev); + if (res) { + LOG_ERR("Failed to enable runtime power management"); + } +#endif + + return res; +} + +#ifdef CONFIG_PM_DEVICE +static int sb_tsi_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_RESUME: + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_SUSPEND: + return 0; + default: + return -ENOTSUP; + } +} +#endif + +#define SB_TSI_INST(inst) \ + static struct sb_tsi_data sb_tsi_data_##inst; \ + static const struct sb_tsi_config sb_tsi_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, sb_tsi_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, sb_tsi_init, PM_DEVICE_DT_INST_GET(inst), \ + &sb_tsi_data_##inst, &sb_tsi_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &sb_tsi_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SB_TSI_INST) diff --git a/drivers/sensor/amd_sb_tsi/sb_tsi.h b/drivers/sensor/amd_sb_tsi/sb_tsi.h new file mode 100644 index 00000000000..10cb0fa28c6 --- /dev/null +++ b/drivers/sensor/amd_sb_tsi/sb_tsi.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_SB_TSI_SB_TSI_H_ +#define ZEPHYR_DRIVERS_SENSOR_SB_TSI_SB_TSI_H_ + +#define SB_TSI_TEMP_INT 0x01 +#define SB_TSI_TEMP_DEC 0x10 +#define SB_TSI_TEMP_DEC_SHIFT 5 +#define SB_TSI_TEMP_DEC_SCALE 8 + +#endif diff --git a/drivers/sensor/amd_sb_tsi/sb_tsi_emul.c b/drivers/sensor/amd_sb_tsi/sb_tsi_emul.c new file mode 100644 index 00000000000..fee197f1d90 --- /dev/null +++ b/drivers/sensor/amd_sb_tsi/sb_tsi_emul.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT amd_sb_tsi + +#include +#include +#include +#include +#include +#include +#include "sb_tsi.h" + +LOG_MODULE_DECLARE(AMD_SB_TSI, CONFIG_SENSOR_LOG_LEVEL); + +#define NUM_REGS 128 + +struct sb_tsi_emul_data { + uint8_t reg[NUM_REGS]; +}; + +static void sb_tsi_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val) +{ + struct sb_tsi_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg < NUM_REGS); + data->reg[reg] = val; +} + +static uint8_t sb_tsi_emul_get_reg(const struct emul *target, uint8_t reg) +{ + struct sb_tsi_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg < NUM_REGS); + return data->reg[reg]; +} + +static void sb_tsi_emul_reset(const struct emul *target) +{ + struct sb_tsi_emul_data *data = target->data; + + memset(data->reg, 0, NUM_REGS); +} + +static int sb_tsi_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, + int num_msgs, int addr) +{ + /* Largely copied from emul_bmi160.c */ + unsigned int val; + int reg; + + __ASSERT_NO_MSG(msgs && num_msgs); + + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); + switch (num_msgs) { + case 2: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len != 1) { + LOG_ERR("Unexpected msg0 length %d", msgs->len); + return -EIO; + } + reg = msgs->buf[0]; + + /* Now process the 'read' part of the message */ + msgs++; + if (msgs->flags & I2C_MSG_READ) { + switch (msgs->len) { + case 1: + val = sb_tsi_emul_get_reg(target, reg); + msgs->buf[0] = val; + break; + default: + LOG_ERR("Unexpected msg1 length %d", msgs->len); + return -EIO; + } + } else { + if (msgs->len != 1) { + LOG_ERR("Unexpected msg1 length %d", msgs->len); + } + sb_tsi_emul_set_reg(target, reg, msgs->buf[0]); + } + break; + default: + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + + return 0; +} + +static int sb_tsi_emul_init(const struct emul *target, const struct device *parent) +{ + sb_tsi_emul_reset(target); + return 0; +} + +static int sb_tsi_emul_set_channel(const struct emul *target, enum sensor_channel chan, + q31_t value, int8_t shift) +{ + struct sb_tsi_emul_data *data = target->data; + int64_t scaled_value; + int32_t millicelsius; + int32_t reg_value; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + scaled_value = (int64_t)value << shift; + millicelsius = scaled_value * 1000 / ((int64_t)INT32_MAX + 1); + reg_value = CLAMP(millicelsius / 125, 0, 0x7ff); + + data->reg[SB_TSI_TEMP_INT] = reg_value >> 3; + data->reg[SB_TSI_TEMP_DEC] = (reg_value & 0x7) << 5; + + return 0; +} + +static int sb_tsi_emul_get_sample_range(const struct emul *target, enum sensor_channel chan, + q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift) +{ + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + *shift = 8; + *lower = 0; + *upper = (int64_t)(255.875 * ((int64_t)INT32_MAX + 1)) >> *shift; + *epsilon = (int64_t)(0.125 * ((int64_t)INT32_MAX + 1)) >> *shift; + + return 0; +} + +static const struct i2c_emul_api sb_tsi_emul_api_i2c = { + .transfer = sb_tsi_emul_transfer_i2c, +}; + +static const struct emul_sensor_backend_api sb_tsi_emul_api_sensor = { + .set_channel = sb_tsi_emul_set_channel, + .get_sample_range = sb_tsi_emul_get_sample_range, +}; + +#define SB_TSI_EMUL(n) \ + struct sb_tsi_emul_data sb_tsi_emul_data_##n; \ + EMUL_DT_INST_DEFINE(n, sb_tsi_emul_init, &sb_tsi_emul_data_##n, NULL, \ + &sb_tsi_emul_api_i2c, &sb_tsi_emul_api_sensor) + +DT_INST_FOREACH_STATUS_OKAY(SB_TSI_EMUL) diff --git a/dts/bindings/sensor/amd,sb-tsi.yaml b/dts/bindings/sensor/amd,sb-tsi.yaml new file mode 100644 index 00000000000..f9204b79db2 --- /dev/null +++ b/dts/bindings/sensor/amd,sb-tsi.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: AMD SB Temperature Sensor Interface. + +compatible: "amd,sb-tsi" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 618905d78b6..433a00d6c8a 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -771,3 +771,8 @@ test_i2c_hm330x@73 { reg = <0x73>; status = "okay"; }; + +test_i2c_amd_sb_tsi: amd_sb_tsi@74 { + compatible = "amd,sb-tsi"; + reg = <0x74>; +}; From 53f1af9bd706b75c1ffd3193a994fa222469e438 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Mon, 4 Sep 2023 13:34:56 +0530 Subject: [PATCH 2108/4498] timer: add support for sigev_thread flag in zephyr timer posix api add support for the sigev_thread flag in zephyr timer posix api following the behaviour described in the linux man page. with this enhancement, a single thread is created to receive all notifications from timers Signed-off-by: Arunmani Alagarsamy --- include/zephyr/posix/pthread.h | 2 ++ lib/posix/timer.c | 49 +++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 45940123cf5..d978e914a5e 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -442,7 +442,9 @@ int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +#ifdef CONFIG_PTHREAD_IPC int pthread_once(pthread_once_t *once, void (*initFunc)(void)); +#endif void pthread_exit(void *retval); int pthread_join(pthread_t thread, void **status); int pthread_cancel(pthread_t pthread); diff --git a/lib/posix/timer.c b/lib/posix/timer.c index 11081f1b4d8..39668a1c402 100644 --- a/lib/posix/timer.c +++ b/lib/posix/timer.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,9 @@ struct timer_obj { struct k_timer ztimer; void (*sigev_notify_function)(union sigval val); union sigval val; + int sigev_notify; + struct k_sem sem_cond; + pthread_t thread; struct timespec interval; /* Reload value */ uint32_t reload; /* Reload value in ms */ uint32_t status; @@ -40,6 +44,31 @@ static void zephyr_timer_wrapper(struct k_timer *ztimer) (timer->sigev_notify_function)(timer->val); } +static void *zephyr_thread_wrapper(void *arg) +{ + struct timer_obj *timer = (struct timer_obj *)arg; + + while (1) { + if (timer->reload == 0U) { + timer->status = NOT_ACTIVE; + } + + k_sem_take(&timer->sem_cond, K_FOREVER); + + (timer->sigev_notify_function)(timer->val); + } + + return NULL; +} + +static void zephyr_timer_interrupt(struct k_timer *ztimer) +{ + struct timer_obj *timer; + + timer = (struct timer_obj *)ztimer; + k_sem_give(&timer->sem_cond); +} + /** * @brief Create a per-process timer. * @@ -55,7 +84,8 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) if (clockid != CLOCK_MONOTONIC || evp == NULL || (evp->sigev_notify != SIGEV_NONE && - evp->sigev_notify != SIGEV_SIGNAL)) { + evp->sigev_notify != SIGEV_SIGNAL && + evp->sigev_notify != SIGEV_THREAD)) { errno = EINVAL; return -1; } @@ -76,6 +106,20 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) if (evp->sigev_notify == SIGEV_NONE) { k_timer_init(&timer->ztimer, NULL, NULL); + } else if (evp->sigev_notify == SIGEV_THREAD) { + int ret; + + timer->sigev_notify = SIGEV_THREAD; + k_sem_init(&timer->sem_cond, 0, 1); + ret = pthread_create(&timer->thread, evp->sigev_notify_attributes, + zephyr_thread_wrapper, timer); + if (ret != 0) { + k_mem_slab_free(&posix_timer_slab, (void *) &timer); + return ret; + } + + pthread_detach(timer->thread); + k_timer_init(&timer->ztimer, zephyr_timer_interrupt, NULL); } else { k_timer_init(&timer->ztimer, zephyr_timer_wrapper, NULL); } @@ -222,6 +266,9 @@ int timer_delete(timer_t timerid) k_timer_stop(&timer->ztimer); } + if (timer->sigev_notify == SIGEV_THREAD) + pthread_cancel(timer->thread); + k_mem_slab_free(&posix_timer_slab, (void *)timer); return 0; From 71c1f894404f7ceec5b16402791a131dd1416105 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Mon, 4 Sep 2023 13:43:24 +0530 Subject: [PATCH 2109/4498] tests: posix: common: timer: add test for SIGEV_THREAD this flag enables the timer expiry handler runs on thread Signed-off-by: Arunmani Alagarsamy --- tests/posix/common/prj.conf | 3 +++ tests/posix/common/src/timer.c | 17 ++++++++++++++--- tests/posix/common/testcase.yaml | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/posix/common/prj.conf b/tests/posix/common/prj.conf index a1904b507d0..1c7e7bd220e 100644 --- a/tests/posix/common/prj.conf +++ b/tests/posix/common/prj.conf @@ -9,3 +9,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAX_THREAD_BYTES=4 CONFIG_THREAD_NAME=y CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_DYNAMIC_THREAD=y +CONFIG_THREAD_STACK_INFO=y +CONFIG_DYNAMIC_THREAD_POOL_SIZE=4 diff --git a/tests/posix/common/src/timer.c b/tests/posix/common/src/timer.c index 0b5f07f8fb9..6a5d10dd863 100644 --- a/tests/posix/common/src/timer.c +++ b/tests/posix/common/src/timer.c @@ -23,7 +23,7 @@ void handler(union sigval val) ++exp_count); } -ZTEST(posix_apis, test_timer) +void test_timer(int sigev_notify) { int ret; struct sigevent sig = { 0 }; @@ -32,11 +32,16 @@ ZTEST(posix_apis, test_timer) struct timespec ts, te; int64_t nsecs_elapsed, secs_elapsed, total_secs_timer; - sig.sigev_notify = SIGEV_SIGNAL; + exp_count = 0; + sig.sigev_notify = sigev_notify; sig.sigev_notify_function = handler; sig.sigev_value.sival_int = 20; - printk("POSIX timer test\n"); + if (sigev_notify == SIGEV_SIGNAL) + printk("POSIX timer test SIGEV_SIGNAL\n"); + else + printk("POSIX timer test SIGEV_THREAD\n"); + ret = timer_create(CLOCK_MONOTONIC, &sig, &timerid); /*TESTPOINT: Check if timer is created successfully*/ @@ -90,6 +95,12 @@ ZTEST(posix_apis, test_timer) "POSIX timer test has failed"); } +ZTEST(posix_apis, test_timer) +{ + test_timer(SIGEV_SIGNAL); + test_timer(SIGEV_THREAD); +} + ZTEST(posix_apis, test_timer_overrun) { timer_t timerid; diff --git a/tests/posix/common/testcase.yaml b/tests/posix/common/testcase.yaml index 949fd839f4c..3d54e6c55d9 100644 --- a/tests/posix/common/testcase.yaml +++ b/tests/posix/common/testcase.yaml @@ -2,6 +2,7 @@ common: filter: not (CONFIG_NATIVE_BUILD and CONFIG_EXTERNAL_LIBC) # FIXME: qemu_leon3 is excluded because of the alignment-related failure # reported in the GitHub issue zephyrproject-rtos/zephyr#48992. + arch_exclude: posix platform_exclude: qemu_leon3 tags: posix min_ram: 64 From e7799eb55187f30c8755b63606f42dac937b2f77 Mon Sep 17 00:00:00 2001 From: Roland Lezuo Date: Thu, 10 Aug 2023 15:23:00 +0200 Subject: [PATCH 2110/4498] drivers: flash: Add RDP (readout protection) support for STM32L4x flash Add support for Flash readout protection on the STM32L4x series Signed-off-by: Roland Lezuo --- drivers/flash/Kconfig.stm32 | 5 +- drivers/flash/flash_stm32.c | 2 +- drivers/flash/flash_stm32f4x.c | 16 ++-- drivers/flash/flash_stm32l4x.c | 152 +++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 12 deletions(-) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index aa7d24cbd6d..602c3792392 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -13,7 +13,6 @@ config SOC_FLASH_STM32 default y select FLASH_PAGE_LAYOUT select FLASH_HAS_PAGE_LAYOUT - select FLASH_HAS_EX_OP if SOC_SERIES_STM32F4X select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable flash driver for STM32 series @@ -23,6 +22,7 @@ if SOC_FLASH_STM32 config FLASH_STM32_WRITE_PROTECT bool "Extended operation for flash write protection control" depends on SOC_SERIES_STM32F4X + select FLASH_HAS_EX_OP default n help Enables flash extended operation for enabling/disabling flash write @@ -38,7 +38,8 @@ config FLASH_STM32_WRITE_PROTECT_DISABLE_PREVENTION config FLASH_STM32_READOUT_PROTECTION bool "Extended operation for flash readout protection control" - depends on SOC_SERIES_STM32F4X + depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32L4X + select FLASH_HAS_EX_OP default n help Enables flash extended operation for enabling/disabling flash readout diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index cba4a76a969..36e3103c56d 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -390,7 +390,7 @@ int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) return 0; } -#if defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) +#if defined(CONFIG_FLASH_EX_OP_ENABLED) && defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) static int flash_stm32_control_register_disable(const struct device *dev) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); diff --git a/drivers/flash/flash_stm32f4x.c b/drivers/flash/flash_stm32f4x.c index f94c1b2e979..4261c26a589 100644 --- a/drivers/flash/flash_stm32f4x.c +++ b/drivers/flash/flash_stm32f4x.c @@ -292,8 +292,7 @@ int flash_stm32_update_rdp(const struct device *dev, bool enable, switch (current_level) { case FLASH_STM32_RDP2: if (!enable || !permanent) { - __ASSERT(false, "RDP level 2 is permanent and can't be " - "changed!"); + LOG_ERR("RDP level 2 is permanent and can't be changed!"); return -ENOTSUP; } break; @@ -304,9 +303,8 @@ int flash_stm32_update_rdp(const struct device *dev, bool enable, #if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) target_level = FLASH_STM32_RDP2; #else - __ASSERT(false, - "Permanent readout protection (RDP " - "level 0 -> 2) not allowed"); + LOG_ERR("Permanent readout protection (RDP " + "level 0 -> 2) not allowed"); return -ENOTSUP; #endif } @@ -317,8 +315,8 @@ int flash_stm32_update_rdp(const struct device *dev, bool enable, #if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) target_level = FLASH_STM32_RDP2; #else - __ASSERT(false, "Permanent readout protection (RDP " - "level 1 -> 2) not allowed"); + LOG_ERR("Permanent readout protection (RDP " + "level 1 -> 2) not allowed"); return -ENOTSUP; #endif } @@ -326,8 +324,8 @@ int flash_stm32_update_rdp(const struct device *dev, bool enable, #if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW) target_level = FLASH_STM32_RDP0; #else - __ASSERT(false, "Disabling readout protection (RDP " - "level 1 -> 0) not allowed"); + LOG_ERR("Disabling readout protection (RDP " + "level 1 -> 0) not allowed"); return -EACCES; #endif } diff --git a/drivers/flash/flash_stm32l4x.c b/drivers/flash/flash_stm32l4x.c index 24644aba95e..ead57fb3df4 100644 --- a/drivers/flash/flash_stm32l4x.c +++ b/drivers/flash/flash_stm32l4x.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #include #include #include +#include #include #include @@ -244,6 +245,157 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } +static __unused int write_optb(const struct device *dev, uint32_t mask, + uint32_t value) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + int rc; + + if (regs->CR & FLASH_CR_OPTLOCK) { + return -EIO; + } + + if ((regs->OPTR & mask) == value) { + return 0; + } + + rc = flash_stm32_wait_flash_idle(dev); + if (rc < 0) { + return rc; + } + + regs->OPTR = (regs->OPTR & ~mask) | value; + regs->CR |= FLASH_CR_OPTSTRT; + + /* Make sure previous write is completed. */ + barrier_dsync_fence_full(); + + rc = flash_stm32_wait_flash_idle(dev); + if (rc < 0) { + return rc; + } + + return 0; +} + +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) + +/* + * Remark for future development implementing Write Protection for the L4 parts: + * + * STM32L4 allows for 2 write protected memory areas, c.f. FLASH_WEP1AR, FLASH_WRP1BR + * which are defined by their start and end pages. + * + * Other STM32 parts (i.e. F4 series) uses bitmask to select sectors. + * + * To implement Write Protection for L4 one should thus add a new EX_OP like + * FLASH_STM32_EX_OP_SECTOR_WP_RANGED in stm32_flash_api_extensions.h + */ + +#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ + +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) +int flash_stm32_update_rdp(const struct device *dev, bool enable, + bool permanent) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uint8_t current_level, target_level; + + current_level = + (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos; + target_level = current_level; + + /* + * 0xAA = RDP level 0 (no protection) + * 0xCC = RDP level 2 (permanent protection) + * others = RDP level 1 (protection active) + */ + switch (current_level) { + case FLASH_STM32_RDP2: + if (!enable || !permanent) { + LOG_ERR("RDP level 2 is permanent and can't be changed!"); + return -ENOTSUP; + } + break; + case FLASH_STM32_RDP0: + if (enable) { + target_level = FLASH_STM32_RDP1; + if (permanent) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) + target_level = FLASH_STM32_RDP2; +#else + LOG_ERR("Permanent readout protection (RDP " + "level 0 -> 2) not allowed"); + return -ENOTSUP; +#endif + } + } + break; + default: /* FLASH_STM32_RDP1 */ + if (enable && permanent) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) + target_level = FLASH_STM32_RDP2; +#else + LOG_ERR("Permanent readout protection (RDP " + "level 1 -> 2) not allowed"); + return -ENOTSUP; +#endif + } + if (!enable) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW) + target_level = FLASH_STM32_RDP0; +#else + LOG_ERR("Disabling readout protection (RDP " + "level 1 -> 0) not allowed"); + return -EACCES; +#endif + } + } + + /* Update RDP level if needed */ + if (current_level != target_level) { + LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level, + target_level); + + write_optb(dev, FLASH_OPTR_RDP_Msk, + (uint32_t)target_level << FLASH_OPTR_RDP_Pos); + } + return 0; +} + +int flash_stm32_get_rdp(const struct device *dev, bool *enabled, + bool *permanent) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uint8_t current_level; + + current_level = + (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos; + + /* + * 0xAA = RDP level 0 (no protection) + * 0xCC = RDP level 2 (permanent protection) + * others = RDP level 1 (protection active) + */ + switch (current_level) { + case FLASH_STM32_RDP2: + *enabled = true; + *permanent = true; + break; + case FLASH_STM32_RDP0: + *enabled = false; + *permanent = false; + break; + default: /* FLASH_STM32_RDP1 */ + *enabled = true; + *permanent = false; + } + return 0; +} +#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ + + + void flash_stm32_page_layout(const struct device *dev, const struct flash_pages_layout **layout, size_t *layout_size) From b97376d71f3d67292893e49057db6378f7c133ff Mon Sep 17 00:00:00 2001 From: Roland Lezuo Date: Wed, 6 Sep 2023 18:21:59 +0200 Subject: [PATCH 2111/4498] test: drivers: flash: Add RDP (readout protection) tests for STM32L4x Add device tests (successfully executed locally) Signed-off-by: Roland Lezuo --- tests/drivers/flash/stm32/prj.conf | 2 -- tests/drivers/flash/stm32/src/main.c | 11 +++++++++++ tests/drivers/flash/stm32/testcase.yaml | 15 +++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tests/drivers/flash/stm32/prj.conf b/tests/drivers/flash/stm32/prj.conf index 4f43063f0cd..68d772c1946 100644 --- a/tests/drivers/flash/stm32/prj.conf +++ b/tests/drivers/flash/stm32/prj.conf @@ -4,8 +4,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_EX_OP_ENABLED=y -CONFIG_FLASH_STM32_READOUT_PROTECTION=y -CONFIG_FLASH_STM32_WRITE_PROTECT=y CONFIG_FLASH_STM32_BLOCK_REGISTERS=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/drivers/flash/stm32/src/main.c b/tests/drivers/flash/stm32/src/main.c index 9d8ae0acc5b..d4d0bf1c201 100644 --- a/tests/drivers/flash/stm32/src/main.c +++ b/tests/drivers/flash/stm32/src/main.c @@ -20,6 +20,8 @@ #define EXPECTED_SIZE 512 static const struct device *const flash_dev = TEST_AREA_DEVICE; + +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) static const struct flash_parameters *flash_params; static uint32_t sector_mask; static uint8_t __aligned(4) expected[EXPECTED_SIZE]; @@ -39,14 +41,17 @@ static int sector_mask_from_offset(const struct device *dev, off_t offset, return 0; } +#endif static void *flash_stm32_setup(void) { +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) struct flash_stm32_ex_op_sector_wp_out wp_status; struct flash_stm32_ex_op_sector_wp_in wp_request; uint8_t buf[EXPECTED_SIZE]; bool is_buf_clear = true; int rc; +#endif /* Check if tested region fits in flash. */ zassert_true((TEST_AREA_OFFSET + EXPECTED_SIZE) < TEST_AREA_MAX, @@ -54,6 +59,7 @@ static void *flash_stm32_setup(void) zassert_true(device_is_ready(flash_dev)); +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) flash_params = flash_get_parameters(flash_dev); rc = sector_mask_from_offset(flash_dev, TEST_AREA_OFFSET, EXPECTED_SIZE, @@ -102,10 +108,12 @@ static void *flash_stm32_setup(void) for (int i = 0; i < EXPECTED_SIZE; i++) { expected[i] = i; } +#endif return NULL; } +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) ZTEST(flash_stm32, test_stm32_write_protection) { struct flash_stm32_ex_op_sector_wp_in wp_request; @@ -153,7 +161,9 @@ ZTEST(flash_stm32, test_stm32_write_protection) zassert_equal(memcmp(buf, expected, EXPECTED_SIZE), 0, "Read data doesn't match expected data"); } +#endif +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) ZTEST(flash_stm32, test_stm32_readout_protection_disabled) { struct flash_stm32_ex_op_rdp rdp_status; @@ -167,5 +177,6 @@ ZTEST(flash_stm32, test_stm32_readout_protection_disabled) TC_PRINT("RDP is disabled\n"); } +#endif ZTEST_SUITE(flash_stm32, NULL, flash_stm32_setup, NULL, NULL, NULL); diff --git a/tests/drivers/flash/stm32/testcase.yaml b/tests/drivers/flash/stm32/testcase.yaml index 9fcfa102744..50014898591 100644 --- a/tests/drivers/flash/stm32/testcase.yaml +++ b/tests/drivers/flash/stm32/testcase.yaml @@ -3,9 +3,20 @@ common: - drivers - flash tests: - drivers.flash.stm32.default: + drivers.flash.stm32.f4: platform_allow: - nucleo_f429zi - google_dragonclaw - filter: dt_compat_enabled("st,stm32-flash-controller") and + extra_configs: + - CONFIG_FLASH_STM32_WRITE_PROTECT=y + - CONFIG_FLASH_STM32_READOUT_PROTECTION=y + filter: dt_compat_enabled("st,stm32f4-flash-controller") and + dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions") + drivers.flash.stm32.l4: + platform_allow: + - nucleo_l452re_p + - disco_l475_iot1 + extra_configs: + - CONFIG_FLASH_STM32_READOUT_PROTECTION=y + filter: dt_compat_enabled("st,stm32l4-flash-controller") and dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions") From 13a87081b930d3a8ba7a811b694fd6d901781d80 Mon Sep 17 00:00:00 2001 From: Jeff Daly Date: Mon, 14 Aug 2023 17:29:16 -0400 Subject: [PATCH 2112/4498] Microchip: MEC172X DTS files reorganization MEC172X series SoCs share most IP but the -LJ series expands the PWM and ADC channels available as well as defines extra pinctrl pins. Separating these better to be able to simplify their inclusion and driver code. Any board based on either the -SZ or -LJ package can just include the mec172x dtsi files for their specific package. Signed-off-by: Jeff Daly --- dts/arm/microchip/mec1727nsz.dtsi | 41 +- .../microchip/mec172x/mec172xnlj-pinctrl.dtsi | 2 +- dts/arm/microchip/mec172x_common.dtsi | 1001 +++++++++++++++++ dts/arm/microchip/mec172xnlj.dtsi | 67 +- dts/arm/microchip/mec172xnsz.dtsi | 995 +--------------- 5 files changed, 1109 insertions(+), 997 deletions(-) create mode 100644 dts/arm/microchip/mec172x_common.dtsi diff --git a/dts/arm/microchip/mec1727nsz.dtsi b/dts/arm/microchip/mec1727nsz.dtsi index 565e5f9ff45..62d4d0985d5 100644 --- a/dts/arm/microchip/mec1727nsz.dtsi +++ b/dts/arm/microchip/mec1727nsz.dtsi @@ -11,14 +11,53 @@ #include #include -#include "mec172xnsz.dtsi" #include "mec172x/mec172x-vw-routing.dtsi" #include "mec172x/mec172xnsz-pinctrl.dtsi" / { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4"; + reg = <0>; + cpu-power-states = <&idle &suspend_to_ram>; + }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1000000>; + }; + + suspend_to_ram: suspend_to_ram { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <2000000>; + }; + }; + }; + + flash0: flash@c0000 { + reg = <0x000C0000 0x58000>; + }; + flash1: flash@60000000 { reg = <0x60000000 0x80000>; }; + + sram0: memory@118000 { + compatible = "mmio-sram"; + reg = <0x00118000 0x10000>; + }; + + soc { + #include "mec172x_common.dtsi" + }; + }; &spi0 { diff --git a/dts/arm/microchip/mec172x/mec172xnlj-pinctrl.dtsi b/dts/arm/microchip/mec172x/mec172xnlj-pinctrl.dtsi index ac5b43a67a3..47502d289c6 100644 --- a/dts/arm/microchip/mec172x/mec172xnlj-pinctrl.dtsi +++ b/dts/arm/microchip/mec172x/mec172xnlj-pinctrl.dtsi @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "mec172xnsz-pinctrl.dtsi" &pinctrl { diff --git a/dts/arm/microchip/mec172x_common.dtsi b/dts/arm/microchip/mec172x_common.dtsi new file mode 100644 index 00000000000..03a6a00fb4f --- /dev/null +++ b/dts/arm/microchip/mec172x_common.dtsi @@ -0,0 +1,1001 @@ +/* + * Copyright (c) 2021 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +ecs: ecs@4000fc00 { + reg = <0x4000fc00 0x200>; +}; +pcr: pcr@40080100 { + compatible = "microchip,xec-pcr"; + reg = <0x40080100 0x100 0x4000a400 0x100>; + reg-names = "pcrr", "vbatr"; + interrupts = <174 0>; + core-clock-div = <1>; + /* MEC172x allows sources to be different */ + pll-32k-src = ; + periph-32k-src = ; + clk32kmon-period-min = <1435>; + clk32kmon-period-max = <1495>; + clk32kmon-duty-cycle-var-max = <132>; + clk32kmon-valid-min = <4>; + xtal-enable-delay-ms = <300>; + pll-lock-timeout-ms = <30>; + /* pin configured only if one of the sources is set to PIN */ + pinctrl-0 = <&clk_32khz_in_gpio165>; + pinctrl-names = "default"; + #clock-cells = <3>; +}; +ecia: ecia@4000e000 { + compatible = "microchip,xec-ecia"; + reg = <0x4000e000 0x400>; + direct-capable-girqs = <13 14 15 16 17 18 19 20 21 23>; + clocks = <&pcr 1 0 MCHP_XEC_PCR_CLK_PERIPH>; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x0 0x4000e000 0x400>; + + girq8: girq8@0 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x0 0x14>; + interrupts = <0 0>; + girq-id = <0>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 21 22 24 25 + 26 27 28 29>; + status = "disabled"; + }; + girq9: girq9@14 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x14 0x14>; + interrupts = <1 0>; + girq-id = <1>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29>; + status = "disabled"; + }; + girq10: girq10@28 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x28 0x14>; + interrupts = <2 0>; + girq-id = <2>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30>; + status = "disabled"; + }; + girq11: girq11@3c { + compatible = "microchip,xec-ecia-girq"; + reg = <0x3c 0x14>; + interrupts = <3 0>; + girq-id = <3>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30>; + status = "disabled"; + }; + girq12: girq12@50 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x50 0x14>; + interrupts = <4 0>; + girq-id = <4>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30>; + status = "disabled"; + }; + girq13: girq13@64 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x64 0x14>; + interrupts = <5 0>; + girq-id = <5>; + sources = <0 1 2 3 4>; + status = "disabled"; + }; + girq14: girq14@78 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x78 0x14>; + interrupts = <6 0>; + girq-id = <6>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15>; + status = "disabled"; + }; + girq15: girq15@8c { + compatible = "microchip,xec-ecia-girq"; + reg = <0x8c 0x14>; + interrupts = <7 0>; + girq-id = <7>; + sources = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 22>; + status = "disabled"; + }; + girq16: girq16@a0 { + compatible = "microchip,xec-ecia-girq"; + reg = <0xa0 0x14>; + interrupts = <8 0>; + girq-id = <8>; + sources = <0 2 3>; + status = "disabled"; + }; + girq17: girq17@b4 { + compatible = "microchip,xec-ecia-girq"; + reg = <0xb4 0x14>; + interrupts = <9 0>; + girq-id = <9>; + sources = <0 1 2 3 4 8 9 10 11 12 13 14 15 + 16 17 20 21 22 23>; + status = "disabled"; + }; + girq18: girq18@c8 { + compatible = "microchip,xec-ecia-girq"; + reg = <0xc8 0x14>; + interrupts = <10 0>; + girq-id = <10>; + sources = <0 1 2 3 4 5 6 7 + 10 20 21 22 23 + 24 25 26 27 28>; + status = "disabled"; + }; + girq19: girq19@dc { + compatible = "microchip,xec-ecia-girq"; + reg = <0xdc 0x14>; + interrupts = <11 0>; + girq-id = <11>; + sources = <0 1 2 3 4 5 6 7 8 9 10>; + status = "disabled"; + }; + girq20: girq20@f0 { + compatible = "microchip,xec-ecia-girq"; + reg = <0xf0 0x14>; + interrupts = <12 0>; + girq-id = <12>; + sources = <3 9>; + status = "disabled"; + }; + girq21: girq21@104 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x104 0x14>; + interrupts = <13 0>; + girq-id = <13>; + sources = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 18 19 25 26>; + status = "disabled"; + }; + girq22: girq22@118 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x118 0x14>; + interrupts = <255 0>; + girq-id = <14>; + sources = <0 1 2 3 4 5 9 15>; + status = "disabled"; + }; + girq23: girq23@12c { + compatible = "microchip,xec-ecia-girq"; + reg = <0x12c 0x14>; + interrupts = <14 0>; + girq-id = <15>; + sources = <0 1 2 3 4 5 6 7 8 9 10 16 17>; + status = "disabled"; + }; + girq24: girq24@140 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x140 0x14>; + interrupts = <15 0>; + girq-id = <16>; + sources = <0 1 2 3 4 5 6 7 8 9 10 11 + 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27>; + status = "disabled"; + }; + girq25: girq25@154 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x154 0x14>; + interrupts = <16 0>; + girq-id = <17>; + sources = <0 1 2 3 4 5 6 7 8 9 10 11 + 12 13 14 15>; + status = "disabled"; + }; + girq26: girq26@168 { + compatible = "microchip,xec-ecia-girq"; + reg = <0x168 0x14>; + interrupts = <17 0>; + girq-id = <18>; + sources = <0 1 2 3 4 5 6 12 13>; + status = "disabled"; + }; +}; +pinctrl: pin-controller@40081000 { + compatible = "microchip,xec-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40081000 0x1000>; + + gpio_000_036: gpio@40081000 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081000 0x80 0x40081300 0x04 + 0x40081380 0x04 0x400813fc 0x04>; + interrupts = <3 2>; + gpio-controller; + port-id = <0>; + girq-id = <11>; + #gpio-cells=<2>; + }; + gpio_040_076: gpio@40081080 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081080 0x80 0x40081304 0x04 + 0x40081384 0x04 0x400813f8 0x4>; + interrupts = <2 2>; + gpio-controller; + port-id = <1>; + girq-id = <10>; + #gpio-cells=<2>; + }; + gpio_100_136: gpio@40081100 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081100 0x80 0x40081308 0x04 + 0x40081388 0x04 0x400813f4 0x04>; + gpio-controller; + interrupts = <1 2>; + port-id = <2>; + girq-id = <9>; + #gpio-cells=<2>; + }; + gpio_140_176: gpio@40081180 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081180 0x80 0x4008130c 0x04 + 0x4008138c 0x04 0x400813f0 0x04>; + gpio-controller; + interrupts = <0 2>; + port-id = <3>; + girq-id = <8>; + #gpio-cells=<2>; + }; + gpio_200_236: gpio@40081200 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081200 0x80 0x40081310 0x04 + 0x40081390 0x04 0x400813ec 0x04>; + gpio-controller; + interrupts = <4 2>; + port-id = <4>; + girq-id = <12>; + #gpio-cells=<2>; + }; + gpio_240_276: gpio@40081280 { + compatible = "microchip,xec-gpio-v2"; + reg = < 0x40081280 0x80 0x40081314 0x04 + 0x40081394 0x04 0x400813e8 0x04>; + gpio-controller; + interrupts = <17 2>; + port-id = <5>; + girq-id = <26>; + #gpio-cells=<2>; + }; +}; +wdog: watchdog@40000400 { + compatible = "microchip,xec-watchdog"; + reg = <0x40000400 0x400>; + interrupts = <171 0>; + girqs = <21 2>; + pcrs = <1 9>; +}; +rtimer: timer@40007400 { + compatible = "microchip,xec-rtos-timer"; + reg = <0x40007400 0x10>; + interrupts = <111 0>; + girqs = <23 10>; +}; +timer0: timer@40000c00 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000c00 0x20>; + interrupts = <136 0>; + girqs = <23 0>; + pcrs = <1 30>; + max-value = <0xFFFF>; + prescaler = <0>; + status = "disabled"; +}; +timer1: timer@40000c20 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000c20 0x20>; + interrupts = <137 0>; + girqs = <23 1>; + pcrs = <1 31>; + max-value = <0xFFFF>; + prescaler = <0>; + status = "disabled"; +}; +timer2: timer@40000c40 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000c40 0x20>; + interrupts = <138 0>; + girqs = <23 2>; + pcrs = <3 21>; + max-value = <0xFFFF>; + prescaler = <0>; + status = "disabled"; +}; +timer3: timer@40000c60 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000c60 0x20>; + interrupts = <139 0>; + girqs = <23 3>; + pcrs = <3 22>; + max-value = <0xFFFF>; + prescaler = <0>; + status = "disabled"; +}; +/* + * NOTE: When RTOS timer used as kernel timer, timer4 used + * to provide high speed busy wait counter. Keep disabled to + * prevent counter driver from claiming it. + */ +timer4: timer@40000c80 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000c80 0x20>; + interrupts = <140 0>; + girqs = <23 4>; + pcrs = <3 23>; + max-value = <0xFFFFFFFF>; + prescaler = <0>; + status = "disabled"; +}; +timer5: timer@40000ca0 { + compatible = "microchip,xec-timer"; + clock-frequency = <48000000>; + reg = <0x40000ca0 0x20>; + interrupts = <141 0>; + girqs = <23 5>; + pcrs = <3 24>; + max-value = <0xFFFFFFFF>; + prescaler = <0>; + status = "disabled"; +}; +cntr0: timer@40000d00 { + reg = <0x40000d00 0x20>; + interrupts = <142 0>; + girqs = <23 6>; + pcrs = <4 2>; + status = "disabled"; +}; +cntr1: timer@40000d20 { + reg = <0x40000d20 0x20>; + interrupts = <143 0>; + girqs = <23 7>; + pcrs = <4 3>; + status = "disabled"; +}; +cntr2: timer@40000d40 { + reg = <0x40000d40 0x20>; + interrupts = <144 0>; + girqs = <23 8>; + pcrs = <4 3>; + status = "disabled"; +}; +cntr3: timer@40000d60 { + reg = <0x40000d60 0x20>; + interrupts = <145 0>; + girqs = <23 9>; + pcrs = <4 4>; + status = "disabled"; +}; +cctmr0: timer@40001000 { + reg = <0x40001000 0x40>; + interrupts = <146 0>, <147 0>, <148 0>, <149 0>, + <150 0>, <151 0>, <152 0>, <153 0>, + <154 0>; + girqs = <18 20>, <18 21>, <18 22>, <18 23>, <18 24>, + <18 25>, <18 26>, <18 27>, <18 28>; + pcrs = <3 30>; + status = "disabled"; +}; +hibtimer0: timer@40009800 { + reg = <0x40009800 0x20>; + interrupts = <112 0>; + girqs = <23 16>; +}; +hibtimer1: timer@40009820 { + reg = <0x40009820 0x20>; + interrupts = <113 0>; + girqs = <23 17>; +}; +weektmr0: timer@4000ac80 { + reg = <0x4000ac80 0x80>; + interrupts = <114 0>, <115 0>, <116 0>, + <117 0>, <118 0>; + girqs = <21 3>, <21 4>, <21 5>, <21 6>, <21 7>; + status = "disabled"; +}; +bbram: bb-ram@4000a800 { + compatible = "microchip,xec-bbram"; + reg = <0x4000a800 0x100>; + reg-names = "memory"; +}; +vci0: vci@4000ae00 { + reg = <0x4000ae00 0x40>; + interrupts = <121 0>, <122 0>, <123 0>, + <124 0>, <125 0>; + girqs = <21 10>, <21 11>, <21 12>, <21 13>, <21 14>; + status = "disabled"; +}; +dmac: dmac@40002400 { + compatible = "microchip,xec-dmac"; + reg = <0x40002400 0xc00>; + interrupts = <24 1>, <25 1>, <26 1>, <27 1>, + <28 1>, <29 1>, <30 1>, <31 1>, + <32 1>, <33 1>, <34 1>, <35 1>, + <36 1>, <37 1>, <38 1>, <39 1>; + girqs = < MCHP_XEC_ECIA(14, 0, 6, 24) + MCHP_XEC_ECIA(14, 1, 6, 25) + MCHP_XEC_ECIA(14, 2, 6, 26) + MCHP_XEC_ECIA(14, 3, 6, 27) + MCHP_XEC_ECIA(14, 4, 6, 28) + MCHP_XEC_ECIA(14, 5, 6, 29) + MCHP_XEC_ECIA(14, 6, 6, 30) + MCHP_XEC_ECIA(14, 7, 6, 31) + MCHP_XEC_ECIA(14, 8, 6, 32) + MCHP_XEC_ECIA(14, 9, 6, 33) + MCHP_XEC_ECIA(14, 10, 6, 34) + MCHP_XEC_ECIA(14, 11, 6, 35) + MCHP_XEC_ECIA(14, 12, 6, 36) + MCHP_XEC_ECIA(14, 13, 6, 37) + MCHP_XEC_ECIA(14, 14, 6, 38) + MCHP_XEC_ECIA(14, 15, 6, 39) >; + pcrs = <1 6>; + #dma-cells = <2>; + dma-channels = <16>; + dma-requests = <16>; + status = "disabled"; +}; +i2c_smb_0: i2c@40004000 { + compatible = "microchip,xec-i2c-v2"; + reg = <0x40004000 0x80>; + clock-frequency = ; + interrupts = <20 1>; + girqs = <13 0>; + pcrs = <1 10>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +i2c_smb_1: i2c@40004400 { + compatible = "microchip,xec-i2c-v2"; + reg = <0x40004400 0x80>; + clock-frequency = ; + interrupts = <21 1>; + girqs = <13 1>; + pcrs = <3 13>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +i2c_smb_2: i2c@40004800 { + compatible = "microchip,xec-i2c-v2"; + reg = <0x40004800 0x80>; + clock-frequency = ; + interrupts = <22 1>; + girqs = <13 2>; + pcrs = <3 14>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +i2c_smb_3: i2c@40004c00 { + compatible = "microchip,xec-i2c-v2"; + reg = <0x40004C00 0x80>; + clock-frequency = ; + interrupts = <23 1>; + girqs = <13 3>; + pcrs = <3 15>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +i2c_smb_4: i2c@40005000 { + compatible = "microchip,xec-i2c-v2"; + reg = <0x40005000 0x80>; + clock-frequency = ; + interrupts = <158 1>; + girqs = <13 4>; + pcrs = <3 20>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +ps2_0: ps2@40009000 { + compatible = "microchip,xec-ps2"; + reg = <0x40009000 0x40>; + interrupts = <100 1>; + girqs = <18 10>, <21 18>; + pcrs = <3 5>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +pwm0: pwm@40005800 { + compatible = "microchip,xec-pwm"; + reg = <0x40005800 0x20>; + pcrs = <1 4>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm1: pwm@40005810 { + compatible = "microchip,xec-pwm"; + reg = <0x40005810 0x20>; + pcrs = <1 20>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm2: pwm@40005820 { + compatible = "microchip,xec-pwm"; + reg = <0x40005820 0x20>; + pcrs = <1 21>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm3: pwm@40005830 { + compatible = "microchip,xec-pwm"; + reg = <0x40005830 0x20>; + pcrs = <1 22>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm4: pwm@40005840 { + compatible = "microchip,xec-pwm"; + reg = <0x40005840 0x20>; + pcrs = <1 23>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm5: pwm@40005850 { + compatible = "microchip,xec-pwm"; + reg = <0x40005850 0x20>; + pcrs = <1 24>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm6: pwm@40005860 { + compatible = "microchip,xec-pwm"; + reg = <0x40005860 0x20>; + pcrs = <1 25>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm7: pwm@40005870 { + compatible = "microchip,xec-pwm"; + reg = <0x40005870 0x20>; + pcrs = <1 26>; + status = "disabled"; + #pwm-cells = <3>; +}; +pwm8: pwm@40005880 { + compatible = "microchip,xec-pwm"; + reg = <0x40005880 0x20>; + pcrs = <1 27>; + status = "disabled"; + #pwm-cells = <3>; +}; +tach0: tach@40006000 { + compatible = "microchip,xec-tach"; + reg = <0x40006000 0x10>; + interrupts = <71 4>; + girqs = <17 1>; + pcrs = <1 2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +tach1: tach@40006010 { + compatible = "microchip,xec-tach"; + reg = <0x40006010 0x10>; + interrupts = <72 4>; + girqs = <17 2>; + pcrs = <1 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +tach2: tach@40006020 { + compatible = "microchip,xec-tach"; + reg = <0x40006020 0x10>; + interrupts = <73 4>; + girqs = <17 3>; + pcrs = <1 12>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +tach3: tach@40006030 { + compatible = "microchip,xec-tach"; + reg = <0x40006030 0x10>; + interrupts = <159 4>; + girqs = <17 4>; + pcrs = <1 13>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +rpmfan0: rpmfan@4000a000 { + reg = <0x4000a000 0x80>; + interrupts = <74 1>, <75 1>; + girqs = <17 20>, <17 21>; + pcrs = <3 12>; + status = "disabled"; +}; +rpmfan1: rpmfan@4000a080 { + reg = <0x4000a080 0x80>; + interrupts = <76 1>, <77 1>; + girqs = <17 22>, <17 23>; + pcrs = <4 7>; + status = "disabled"; +}; +adc0: adc@40007c00 { + compatible = "microchip,xec-adc"; + reg = <0x40007c00 0x90>; + interrupts = <78 0>, <79 0>; + girqs = <17 8>, <17 9>; + pcrs = <3 3>; + status = "disabled"; + #io-channel-cells = <1>; + clktime = <32>; +}; +kscan0: kscan@40009c00 { + compatible = "microchip,xec-kscan"; + reg = <0x40009c00 0x18>; + interrupts = <135 0>; + girqs = <21 25>; + pcrs = <3 11>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; +}; +peci0: peci@40006400 { + compatible = "microchip,xec-peci"; + reg = <0x40006400 0x80>; + interrupts = <70 4>; + girqs = <17 0>; + pcrs = <1 1>; + #address-cells = <1>; + #size-cells = <0>; +}; +spi0: spi@40070000 { + reg = <0x40070000 0x400>; + interrupts = <91 2>; + girqs = < MCHP_XEC_ECIA(18, 1, 10, 91) >; + clocks = <&pcr 4 8 MCHP_XEC_PCR_CLK_PERIPH>; + clock-frequency = <12000000>; + lines = <1>; + chip-select = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; +spi1: spi@40009400 { + reg = <0x40009400 0x80>; + interrupts = <92 2>, <93 2>; + girqs = <18 2>, <18 3>; + pcrs = <3 9>; + status = "disabled"; +}; +spi2: spi@40009480 { + reg = <0x40009480 0x80>; + interrupts = <94 2>, <95 2>; + girqs = <18 4>, <18 5>; + pcrs = <4 22>; + status = "disabled"; +}; +prochot0: prochot@40003400 { + reg = <0x40003400 0x20>; + interrupts = <87 0>; + girqs = <17 17>; + pcrs = <4 13>; + status = "disabled"; +}; +rcid0: rcid@40001400 { + reg = <0x40001400 0x80>; + interrupts = <80 0>; + girqs = <17 10>; + pcrs = <4 10>; + status = "disabled"; +}; +rcid1: rcid@40001480 { + reg = <0x40001480 0x80>; + interrupts = <81 0>; + girqs = <17 11>; + pcrs = <4 11>; + status = "disabled"; +}; +rcid2: rcid@40001500 { + reg = <0x40001500 0x80>; + interrupts = <82 0>; + girqs = <17 12>; + pcrs = <4 12>; + status = "disabled"; +}; +spip0: spip@40007000 { + reg = <0x40007000 0x100>; + interrupts = <90 0>; + girqs = <18 0>; + pcrs = <4 16>; + status = "disabled"; +}; +bbled0: bbled@4000b800 { + reg = <0x4000b800 0x100>; + interrupts = <83 0>; + girqs = <17 13>; + pcrs = <3 16>; + status = "disabled"; +}; +bbled1: bbled@4000b900 { + reg = <0x4000b900 0x100>; + interrupts = <84 0>; + girqs = <17 14>; + pcrs = <3 17>; + status = "disabled"; +}; +bbled2: bbled@4000ba00 { + reg = <0x4000ba00 0x100>; + interrupts = <85 0>; + girqs = <17 15>; + pcrs = <3 18>; + status = "disabled"; +}; +bbled3: bbled@4000bb00 { + reg = <0x4000bb00 0x100>; + interrupts = <86 0>; + girqs = <17 16>; + pcrs = <3 25>; + status = "disabled"; +}; +bclink0: bclink@4000cd00 { + reg = <0x4000cd00 0x20>; + interrupts = <96 0>, <97 0>; + girqs = <18 7>, <18 6>; + pcrs = <3 19>; + status = "disabled"; +}; +tfdp0: tfdp@40008c00 { + reg = <0x40008c00 0x10>; + pcrs = <1 7>; + status = "disabled"; +}; +glblcfg0: glblcfg@400fff00 { + reg = <0x400fff00 0x40>; + pcrs = <2 12>; + status = "disabled"; +}; +uart0: uart@400f2400 { + compatible = "microchip,xec-uart"; + reg = <0x400f2400 0x400>; + interrupts = <40 1>; + clock-frequency = <1843200>; + current-speed = <38400>; + girqs = <15 0>; + pcrs = <2 1>; + ldn = <9>; + status = "disabled"; +}; +uart1: uart@400f2800 { + compatible = "microchip,xec-uart"; + reg = <0x400f2800 0x400>; + interrupts = <41 1>; + clock-frequency = <1843200>; + current-speed = <38400>; + girqs = <15 1>; + pcrs = <2 2>; + ldn = <10>; + status = "disabled"; +}; +espi0: espi@400f3400 { + compatible = "microchip,xec-espi-v2"; + /* reg tuple contains one 32-bit address cell and one + * 32-bit length(size) cell. + */ + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x400f3400 0x400 + 0x400f3800 0x400 + 0x400f9c00 0x400>; + reg-names = "io", "mem", "vw"; + interrupts = <103 3>, <104 3>, <105 3>, <106 3>, + <107 3>, <108 3>, <109 3>, <110 2>, + <156 3>; + interrupt-names = "pc", "bm1", "bm2", "ltr", "oob_up", + "oob_dn", "fc", "rst", "vw_chan_en"; + girqs = < MCHP_XEC_ECIA(19, 0, 11, 103) + MCHP_XEC_ECIA(19, 1, 11, 104) + MCHP_XEC_ECIA(19, 2, 11, 105) + MCHP_XEC_ECIA(19, 3, 11, 106) + MCHP_XEC_ECIA(19, 4, 11, 107) + MCHP_XEC_ECIA(19, 5, 11, 108) + MCHP_XEC_ECIA(19, 6, 11, 109) + MCHP_XEC_ECIA(19, 7, 11, 110) + MCHP_XEC_ECIA(19, 8, 11, 156) >; + pcrs = <2 19>; + status = "disabled"; + + espi_saf0: espi_saf@40008000 { + compatible = "microchip,xec-espi-saf-v2"; + reg = <0x40008000 0x400>, <0x40070000 0x400>, + <0x40071000 0x400>; + reg-names = "safbr", "safqspi", "safcomm"; + interrupts = <166 3>, <167 3>; + interrupt-names = "done", "err"; + girqs = < MCHP_XEC_ECIA(19, 9, 11, 166) >, + < MCHP_XEC_ECIA(19, 10, 11, 167) >; + pcrs = <2 27>; + status = "disabled"; + }; + + mbox0: mbox@400f0000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f0000 0x200>; + interrupts = <60 3>; + girqs = < MCHP_XEC_ECIA(15, 20, 7, 60) >; + pcrs = <2 17>; + ldn = <0>; + status = "disabled"; + }; + kbc0: kbc@400f0400 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f0400 0x400>; + interrupts = <58 3>, <59 3>; + interrupt-names = "kbc_obe", "kbc_ibf"; + girqs = < MCHP_XEC_ECIA(15, 18, 7, 58) + MCHP_XEC_ECIA(15, 19, 7, 59) >; + ldn = <1>; + status = "disabled"; + }; + acpi_ec0: acpi_ec@400f0800 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f0800 0x400>; + interrupts = <45 3>, <46 3>; + interrupt-names = "acpi_ibf", "acpi_obe"; + girqs = < MCHP_XEC_ECIA(15, 5, 7, 45) + MCHP_XEC_ECIA(15, 6, 7, 46) >; + ldn = <2>; + status = "disabled"; + }; + acpi_ec1: acpi_ec@400f0c00 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f0c00 0x400>; + interrupts = <47 3>, <48 3>; + interrupt-names = "acpi_ibf", "acpi_obe"; + girqs = < MCHP_XEC_ECIA(15, 7, 7, 47) + MCHP_XEC_ECIA(15, 8, 7, 48) >; + ldn = <3>; + status = "disabled"; + }; + acpi_ec2: acpi_ec@400f1000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f1000 0x400>; + interrupts = <49 3>, <50 3>; + interrupt-names = "acpi_ibf", "acpi_obe"; + girqs = < MCHP_XEC_ECIA(15, 9, 7, 49) + MCHP_XEC_ECIA(15, 10, 7, 50) >; + ldn = <4>; + status = "disabled"; + }; + acpi_ec3: acpi_ec@400f1400 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f1400 0x400>; + interrupts = <51 3>, <52 3>; + interrupt-names = "acpi_ibf", "acpi_obe"; + girqs = < MCHP_XEC_ECIA(15, 11, 7, 51) + MCHP_XEC_ECIA(15, 12, 7, 52) >; + ldn = <5>; + status = "disabled"; + }; + acpi_ec4: acpi_ec@400f1800 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f1800 0x400>; + interrupts = <53 3>, <54 3>; + interrupt-names = "acpi_ibf", "acpi_obe"; + girqs = < MCHP_XEC_ECIA(15, 13, 7, 53) + MCHP_XEC_ECIA(15, 14, 7, 54) >; + ldn = <6>; + status = "disabled"; + }; + acpi_pm1: acpi_pm1@400f1c00 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f1c00 0x400>; + interrupts = <55 3>, <56 3>, <57 3>; + interrupt-names = "pm1_ctl", "pm1_en", "pm1_sts"; + girqs = < MCHP_XEC_ECIA(15, 15, 7, 55) + MCHP_XEC_ECIA(15, 16, 7, 56) + MCHP_XEC_ECIA(15, 17, 7, 57) >; + ldn = <7>; + status = "disabled"; + }; + port92: port92@400f2000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f2000 0x400>; + ldn = <8>; + status = "disabled"; + }; + emi0: emi@400f4000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f4000 0x400>; + interrupts = <42 3>; + girqs = < MCHP_XEC_ECIA(15, 2, 7, 42) >; + ldn = <16>; + status = "disabled"; + }; + emi1: emi@400f4400 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f4400 0x400>; + interrupts = <43 3>; + girqs = < MCHP_XEC_ECIA(15, 3, 7, 43) >; + ldn = <17>; + status = "disabled"; + }; + emi2: emi@400f4800 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f4800 0x400>; + interrupts = <44 3>; + girqs = < MCHP_XEC_ECIA(15, 4, 7, 44) >; + ldn = <18>; + status = "disabled"; + }; + rtc0: rtc@400f5000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f5000 0x100>; + interrupts = <119 3>, <120 3>; + girqs = < MCHP_XEC_ECIA(21, 8, 13, 119) + MCHP_XEC_ECIA(21, 9, 13, 120) >; + pcrs = <2 18>; + ldn = <20>; + status = "disabled"; + }; + /* Capture writes to host I/O 0x80 - 0x83 */ + p80bd0: p80bd@400f8000 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f8000 0x400>; + interrupts = <62 0>; + girqs = < MCHP_XEC_ECIA(15, 22, 7, 62) >; + pcrs = <2 25>; + ldn = <32>; + status = "disabled"; + }; + /* Capture writes to an 8-bit I/O and map to one of 0x80 to 0x83 */ + p80bd0_alias: p80bd@400f8400 { + compatible = "microchip,xec-espi-host-dev"; + reg = <0x400f8400 0x400>; + ldn = <33>; + host-io = <0x90>; + /* map 0x90 to 0x80 */ + host-io-addr-mask = <0x01>; + status = "disabled"; + }; +}; + +symcr: symcr@40100000 { + compatible = "microchip,xec-symcr"; + reg = <0x40100000 0x1000>; + interrupts = <68 1>; + clocks = <&pcr 3 26 MCHP_XEC_PCR_CLK_PERIPH>; + girqs = <16 3>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <1>; +}; + +rom_api: rom_api@1f000 { + reg = <0x1f000 0x1000>; + status = "disabled"; +}; diff --git a/dts/arm/microchip/mec172xnlj.dtsi b/dts/arm/microchip/mec172xnlj.dtsi index 968c1e95c36..00d27b422c0 100644 --- a/dts/arm/microchip/mec172xnlj.dtsi +++ b/dts/arm/microchip/mec172xnlj.dtsi @@ -4,11 +4,68 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "mec172xnsz.dtsi" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mec172x/mec172x-vw-routing.dtsi" / { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4"; + reg = <0>; + cpu-power-states = <&idle &suspend_to_ram>; + }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1000000>; + }; + + suspend_to_ram: suspend_to_ram { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <2000000>; + }; + }; + }; + + flash0: flash@c0000 { + reg = <0x000C0000 0x58000>; + }; + + sram0: memory@118000 { + compatible = "mmio-sram"; + reg = <0x00118000 0x10000>; + }; soc { + #include "mec172x_common.dtsi" + + eeprom: eeprom@40002c00 { + compatible = "microchip,xec-eeprom"; + reg = <0x40002c00 0x400>; + interrupts = <155 2>; + size = <8192>; + girqs = <18 13>; + pcrs = <4 14>; + status = "disabled"; + }; + pwm9: pwm@40005890 { compatible = "microchip,xec-pwm"; reg = <0x40005890 0x20>; @@ -32,6 +89,14 @@ status = "disabled"; #pwm-cells = <3>; }; + }; }; +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&systick { + status = "disabled"; +}; diff --git a/dts/arm/microchip/mec172xnsz.dtsi b/dts/arm/microchip/mec172xnsz.dtsi index 8a95e8ec800..cbb84f21877 100644 --- a/dts/arm/microchip/mec172xnsz.dtsi +++ b/dts/arm/microchip/mec172xnsz.dtsi @@ -54,464 +54,8 @@ }; soc { - ecs: ecs@4000fc00 { - reg = <0x4000fc00 0x200>; - }; - pcr: pcr@40080100 { - compatible = "microchip,xec-pcr"; - reg = <0x40080100 0x100 0x4000a400 0x100>; - reg-names = "pcrr", "vbatr"; - interrupts = <174 0>; - core-clock-div = <1>; - /* MEC172x allows sources to be different */ - pll-32k-src = ; - periph-32k-src = ; - clk32kmon-period-min = <1435>; - clk32kmon-period-max = <1495>; - clk32kmon-duty-cycle-var-max = <132>; - clk32kmon-valid-min = <4>; - xtal-enable-delay-ms = <300>; - pll-lock-timeout-ms = <30>; - /* pin configured only if one of the sources is set to PIN */ - pinctrl-0 = <&clk_32khz_in_gpio165>; - pinctrl-names = "default"; - #clock-cells = <3>; - }; - ecia: ecia@4000e000 { - compatible = "microchip,xec-ecia"; - reg = <0x4000e000 0x400>; - direct-capable-girqs = <13 14 15 16 17 18 19 20 21 23>; - clocks = <&pcr 1 0 MCHP_XEC_PCR_CLK_PERIPH>; - #address-cells = <1>; - #size-cells = <1>; - - ranges = <0x0 0x4000e000 0x400>; + #include "mec172x_common.dtsi" - girq8: girq8@0 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x0 0x14>; - interrupts = <0 0>; - girq-id = <0>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 21 22 24 25 - 26 27 28 29>; - status = "disabled"; - }; - girq9: girq9@14 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x14 0x14>; - interrupts = <1 0>; - girq-id = <1>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 23 - 24 25 26 27 28 29>; - status = "disabled"; - }; - girq10: girq10@28 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x28 0x14>; - interrupts = <2 0>; - girq-id = <2>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 23 - 24 25 26 27 28 29 30>; - status = "disabled"; - }; - girq11: girq11@3c { - compatible = "microchip,xec-ecia-girq"; - reg = <0x3c 0x14>; - interrupts = <3 0>; - girq-id = <3>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 23 - 24 25 26 27 28 29 30>; - status = "disabled"; - }; - girq12: girq12@50 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x50 0x14>; - interrupts = <4 0>; - girq-id = <4>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 23 - 24 25 26 27 28 29 30>; - status = "disabled"; - }; - girq13: girq13@64 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x64 0x14>; - interrupts = <5 0>; - girq-id = <5>; - sources = <0 1 2 3 4>; - status = "disabled"; - }; - girq14: girq14@78 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x78 0x14>; - interrupts = <6 0>; - girq-id = <6>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15>; - status = "disabled"; - }; - girq15: girq15@8c { - compatible = "microchip,xec-ecia-girq"; - reg = <0x8c 0x14>; - interrupts = <7 0>; - girq-id = <7>; - sources = <0 1 2 3 4 5 6 7 - 8 9 10 11 12 13 14 15 - 16 17 18 19 20 22>; - status = "disabled"; - }; - girq16: girq16@a0 { - compatible = "microchip,xec-ecia-girq"; - reg = <0xa0 0x14>; - interrupts = <8 0>; - girq-id = <8>; - sources = <0 2 3>; - status = "disabled"; - }; - girq17: girq17@b4 { - compatible = "microchip,xec-ecia-girq"; - reg = <0xb4 0x14>; - interrupts = <9 0>; - girq-id = <9>; - sources = <0 1 2 3 4 8 9 10 11 12 13 14 15 - 16 17 20 21 22 23>; - status = "disabled"; - }; - girq18: girq18@c8 { - compatible = "microchip,xec-ecia-girq"; - reg = <0xc8 0x14>; - interrupts = <10 0>; - girq-id = <10>; - sources = <0 1 2 3 4 5 6 7 - 10 20 21 22 23 - 24 25 26 27 28>; - status = "disabled"; - }; - girq19: girq19@dc { - compatible = "microchip,xec-ecia-girq"; - reg = <0xdc 0x14>; - interrupts = <11 0>; - girq-id = <11>; - sources = <0 1 2 3 4 5 6 7 8 9 10>; - status = "disabled"; - }; - girq20: girq20@f0 { - compatible = "microchip,xec-ecia-girq"; - reg = <0xf0 0x14>; - interrupts = <12 0>; - girq-id = <12>; - sources = <3 9>; - status = "disabled"; - }; - girq21: girq21@104 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x104 0x14>; - interrupts = <13 0>; - girq-id = <13>; - sources = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 - 18 19 25 26>; - status = "disabled"; - }; - girq22: girq22@118 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x118 0x14>; - interrupts = <255 0>; - girq-id = <14>; - sources = <0 1 2 3 4 5 9 15>; - status = "disabled"; - }; - girq23: girq23@12c { - compatible = "microchip,xec-ecia-girq"; - reg = <0x12c 0x14>; - interrupts = <14 0>; - girq-id = <15>; - sources = <0 1 2 3 4 5 6 7 8 9 10 16 17>; - status = "disabled"; - }; - girq24: girq24@140 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x140 0x14>; - interrupts = <15 0>; - girq-id = <16>; - sources = <0 1 2 3 4 5 6 7 8 9 10 11 - 12 13 14 15 16 17 18 19 - 20 21 22 23 24 25 26 27>; - status = "disabled"; - }; - girq25: girq25@154 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x154 0x14>; - interrupts = <16 0>; - girq-id = <17>; - sources = <0 1 2 3 4 5 6 7 8 9 10 11 - 12 13 14 15>; - status = "disabled"; - }; - girq26: girq26@168 { - compatible = "microchip,xec-ecia-girq"; - reg = <0x168 0x14>; - interrupts = <17 0>; - girq-id = <18>; - sources = <0 1 2 3 4 5 6 12 13>; - status = "disabled"; - }; - }; - pinctrl: pin-controller@40081000 { - compatible = "microchip,xec-pinctrl"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40081000 0x1000>; - - gpio_000_036: gpio@40081000 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081000 0x80 0x40081300 0x04 - 0x40081380 0x04 0x400813fc 0x04>; - interrupts = <3 2>; - gpio-controller; - port-id = <0>; - girq-id = <11>; - #gpio-cells=<2>; - }; - gpio_040_076: gpio@40081080 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081080 0x80 0x40081304 0x04 - 0x40081384 0x04 0x400813f8 0x4>; - interrupts = <2 2>; - gpio-controller; - port-id = <1>; - girq-id = <10>; - #gpio-cells=<2>; - }; - gpio_100_136: gpio@40081100 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081100 0x80 0x40081308 0x04 - 0x40081388 0x04 0x400813f4 0x04>; - gpio-controller; - interrupts = <1 2>; - port-id = <2>; - girq-id = <9>; - #gpio-cells=<2>; - }; - gpio_140_176: gpio@40081180 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081180 0x80 0x4008130c 0x04 - 0x4008138c 0x04 0x400813f0 0x04>; - gpio-controller; - interrupts = <0 2>; - port-id = <3>; - girq-id = <8>; - #gpio-cells=<2>; - }; - gpio_200_236: gpio@40081200 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081200 0x80 0x40081310 0x04 - 0x40081390 0x04 0x400813ec 0x04>; - gpio-controller; - interrupts = <4 2>; - port-id = <4>; - girq-id = <12>; - #gpio-cells=<2>; - }; - gpio_240_276: gpio@40081280 { - compatible = "microchip,xec-gpio-v2"; - reg = < 0x40081280 0x80 0x40081314 0x04 - 0x40081394 0x04 0x400813e8 0x04>; - gpio-controller; - interrupts = <17 2>; - port-id = <5>; - girq-id = <26>; - #gpio-cells=<2>; - }; - }; - wdog: watchdog@40000400 { - compatible = "microchip,xec-watchdog"; - reg = <0x40000400 0x400>; - interrupts = <171 0>; - girqs = <21 2>; - pcrs = <1 9>; - }; - rtimer: timer@40007400 { - compatible = "microchip,xec-rtos-timer"; - reg = <0x40007400 0x10>; - interrupts = <111 0>; - girqs = <23 10>; - }; - timer0: timer@40000c00 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000c00 0x20>; - interrupts = <136 0>; - girqs = <23 0>; - pcrs = <1 30>; - max-value = <0xFFFF>; - prescaler = <0>; - status = "disabled"; - }; - timer1: timer@40000c20 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000c20 0x20>; - interrupts = <137 0>; - girqs = <23 1>; - pcrs = <1 31>; - max-value = <0xFFFF>; - prescaler = <0>; - status = "disabled"; - }; - timer2: timer@40000c40 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000c40 0x20>; - interrupts = <138 0>; - girqs = <23 2>; - pcrs = <3 21>; - max-value = <0xFFFF>; - prescaler = <0>; - status = "disabled"; - }; - timer3: timer@40000c60 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000c60 0x20>; - interrupts = <139 0>; - girqs = <23 3>; - pcrs = <3 22>; - max-value = <0xFFFF>; - prescaler = <0>; - status = "disabled"; - }; - /* - * NOTE: When RTOS timer used as kernel timer, timer4 used - * to provide high speed busy wait counter. Keep disabled to - * prevent counter driver from claiming it. - */ - timer4: timer@40000c80 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000c80 0x20>; - interrupts = <140 0>; - girqs = <23 4>; - pcrs = <3 23>; - max-value = <0xFFFFFFFF>; - prescaler = <0>; - status = "disabled"; - }; - timer5: timer@40000ca0 { - compatible = "microchip,xec-timer"; - clock-frequency = <48000000>; - reg = <0x40000ca0 0x20>; - interrupts = <141 0>; - girqs = <23 5>; - pcrs = <3 24>; - max-value = <0xFFFFFFFF>; - prescaler = <0>; - status = "disabled"; - }; - cntr0: timer@40000d00 { - reg = <0x40000d00 0x20>; - interrupts = <142 0>; - girqs = <23 6>; - pcrs = <4 2>; - status = "disabled"; - }; - cntr1: timer@40000d20 { - reg = <0x40000d20 0x20>; - interrupts = <143 0>; - girqs = <23 7>; - pcrs = <4 3>; - status = "disabled"; - }; - cntr2: timer@40000d40 { - reg = <0x40000d40 0x20>; - interrupts = <144 0>; - girqs = <23 8>; - pcrs = <4 3>; - status = "disabled"; - }; - cntr3: timer@40000d60 { - reg = <0x40000d60 0x20>; - interrupts = <145 0>; - girqs = <23 9>; - pcrs = <4 4>; - status = "disabled"; - }; - cctmr0: timer@40001000 { - reg = <0x40001000 0x40>; - interrupts = <146 0>, <147 0>, <148 0>, <149 0>, - <150 0>, <151 0>, <152 0>, <153 0>, - <154 0>; - girqs = <18 20>, <18 21>, <18 22>, <18 23>, <18 24>, - <18 25>, <18 26>, <18 27>, <18 28>; - pcrs = <3 30>; - status = "disabled"; - }; - hibtimer0: timer@40009800 { - reg = <0x40009800 0x20>; - interrupts = <112 0>; - girqs = <23 16>; - }; - hibtimer1: timer@40009820 { - reg = <0x40009820 0x20>; - interrupts = <113 0>; - girqs = <23 17>; - }; - weektmr0: timer@4000ac80 { - reg = <0x4000ac80 0x80>; - interrupts = <114 0>, <115 0>, <116 0>, - <117 0>, <118 0>; - girqs = <21 3>, <21 4>, <21 5>, <21 6>, <21 7>; - status = "disabled"; - }; - bbram: bb-ram@4000a800 { - compatible = "microchip,xec-bbram"; - reg = <0x4000a800 0x100>; - reg-names = "memory"; - }; - vci0: vci@4000ae00 { - reg = <0x4000ae00 0x40>; - interrupts = <121 0>, <122 0>, <123 0>, - <124 0>, <125 0>; - girqs = <21 10>, <21 11>, <21 12>, <21 13>, <21 14>; - status = "disabled"; - }; - dmac: dmac@40002400 { - compatible = "microchip,xec-dmac"; - reg = <0x40002400 0xc00>; - interrupts = <24 1>, <25 1>, <26 1>, <27 1>, - <28 1>, <29 1>, <30 1>, <31 1>, - <32 1>, <33 1>, <34 1>, <35 1>, - <36 1>, <37 1>, <38 1>, <39 1>; - girqs = < MCHP_XEC_ECIA(14, 0, 6, 24) - MCHP_XEC_ECIA(14, 1, 6, 25) - MCHP_XEC_ECIA(14, 2, 6, 26) - MCHP_XEC_ECIA(14, 3, 6, 27) - MCHP_XEC_ECIA(14, 4, 6, 28) - MCHP_XEC_ECIA(14, 5, 6, 29) - MCHP_XEC_ECIA(14, 6, 6, 30) - MCHP_XEC_ECIA(14, 7, 6, 31) - MCHP_XEC_ECIA(14, 8, 6, 32) - MCHP_XEC_ECIA(14, 9, 6, 33) - MCHP_XEC_ECIA(14, 10, 6, 34) - MCHP_XEC_ECIA(14, 11, 6, 35) - MCHP_XEC_ECIA(14, 12, 6, 36) - MCHP_XEC_ECIA(14, 13, 6, 37) - MCHP_XEC_ECIA(14, 14, 6, 38) - MCHP_XEC_ECIA(14, 15, 6, 39) >; - pcrs = <1 6>; - #dma-cells = <2>; - dma-channels = <16>; - dma-requests = <16>; - status = "disabled"; - }; eeprom: eeprom@40002c00 { compatible = "microchip,xec-eeprom"; reg = <0x40002c00 0x400>; @@ -521,543 +65,6 @@ pcrs = <4 14>; status = "disabled"; }; - i2c_smb_0: i2c@40004000 { - compatible = "microchip,xec-i2c-v2"; - reg = <0x40004000 0x80>; - clock-frequency = ; - interrupts = <20 1>; - girqs = <13 0>; - pcrs = <1 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - i2c_smb_1: i2c@40004400 { - compatible = "microchip,xec-i2c-v2"; - reg = <0x40004400 0x80>; - clock-frequency = ; - interrupts = <21 1>; - girqs = <13 1>; - pcrs = <3 13>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - i2c_smb_2: i2c@40004800 { - compatible = "microchip,xec-i2c-v2"; - reg = <0x40004800 0x80>; - clock-frequency = ; - interrupts = <22 1>; - girqs = <13 2>; - pcrs = <3 14>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - i2c_smb_3: i2c@40004c00 { - compatible = "microchip,xec-i2c-v2"; - reg = <0x40004C00 0x80>; - clock-frequency = ; - interrupts = <23 1>; - girqs = <13 3>; - pcrs = <3 15>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - i2c_smb_4: i2c@40005000 { - compatible = "microchip,xec-i2c-v2"; - reg = <0x40005000 0x80>; - clock-frequency = ; - interrupts = <158 1>; - girqs = <13 4>; - pcrs = <3 20>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - ps2_0: ps2@40009000 { - compatible = "microchip,xec-ps2"; - reg = <0x40009000 0x40>; - interrupts = <100 1>; - girqs = <18 10>, <21 18>; - pcrs = <3 5>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - pwm0: pwm@40005800 { - compatible = "microchip,xec-pwm"; - reg = <0x40005800 0x20>; - pcrs = <1 4>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm1: pwm@40005810 { - compatible = "microchip,xec-pwm"; - reg = <0x40005810 0x20>; - pcrs = <1 20>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm2: pwm@40005820 { - compatible = "microchip,xec-pwm"; - reg = <0x40005820 0x20>; - pcrs = <1 21>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm3: pwm@40005830 { - compatible = "microchip,xec-pwm"; - reg = <0x40005830 0x20>; - pcrs = <1 22>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm4: pwm@40005840 { - compatible = "microchip,xec-pwm"; - reg = <0x40005840 0x20>; - pcrs = <1 23>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm5: pwm@40005850 { - compatible = "microchip,xec-pwm"; - reg = <0x40005850 0x20>; - pcrs = <1 24>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm6: pwm@40005860 { - compatible = "microchip,xec-pwm"; - reg = <0x40005860 0x20>; - pcrs = <1 25>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm7: pwm@40005870 { - compatible = "microchip,xec-pwm"; - reg = <0x40005870 0x20>; - pcrs = <1 26>; - status = "disabled"; - #pwm-cells = <3>; - }; - pwm8: pwm@40005880 { - compatible = "microchip,xec-pwm"; - reg = <0x40005880 0x20>; - pcrs = <1 27>; - status = "disabled"; - #pwm-cells = <3>; - }; - tach0: tach@40006000 { - compatible = "microchip,xec-tach"; - reg = <0x40006000 0x10>; - interrupts = <71 4>; - girqs = <17 1>; - pcrs = <1 2>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - tach1: tach@40006010 { - compatible = "microchip,xec-tach"; - reg = <0x40006010 0x10>; - interrupts = <72 4>; - girqs = <17 2>; - pcrs = <1 11>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - tach2: tach@40006020 { - compatible = "microchip,xec-tach"; - reg = <0x40006020 0x10>; - interrupts = <73 4>; - girqs = <17 3>; - pcrs = <1 12>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - tach3: tach@40006030 { - compatible = "microchip,xec-tach"; - reg = <0x40006030 0x10>; - interrupts = <159 4>; - girqs = <17 4>; - pcrs = <1 13>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - rpmfan0: rpmfan@4000a000 { - reg = <0x4000a000 0x80>; - interrupts = <74 1>, <75 1>; - girqs = <17 20>, <17 21>; - pcrs = <3 12>; - status = "disabled"; - }; - rpmfan1: rpmfan@4000a080 { - reg = <0x4000a080 0x80>; - interrupts = <76 1>, <77 1>; - girqs = <17 22>, <17 23>; - pcrs = <4 7>; - status = "disabled"; - }; - adc0: adc@40007c00 { - compatible = "microchip,xec-adc"; - reg = <0x40007c00 0x90>; - interrupts = <78 0>, <79 0>; - girqs = <17 8>, <17 9>; - pcrs = <3 3>; - status = "disabled"; - #io-channel-cells = <1>; - clktime = <32>; - }; - kscan0: kscan@40009c00 { - compatible = "microchip,xec-kscan"; - reg = <0x40009c00 0x18>; - interrupts = <135 0>; - girqs = <21 25>; - pcrs = <3 11>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - peci0: peci@40006400 { - compatible = "microchip,xec-peci"; - reg = <0x40006400 0x80>; - interrupts = <70 4>; - girqs = <17 0>; - pcrs = <1 1>; - #address-cells = <1>; - #size-cells = <0>; - }; - spi0: spi@40070000 { - reg = <0x40070000 0x400>; - interrupts = <91 2>; - girqs = < MCHP_XEC_ECIA(18, 1, 10, 91) >; - clocks = <&pcr 4 8 MCHP_XEC_PCR_CLK_PERIPH>; - clock-frequency = <12000000>; - lines = <1>; - chip-select = <0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - spi1: spi@40009400 { - reg = <0x40009400 0x80>; - interrupts = <92 2>, <93 2>; - girqs = <18 2>, <18 3>; - pcrs = <3 9>; - status = "disabled"; - }; - spi2: spi@40009480 { - reg = <0x40009480 0x80>; - interrupts = <94 2>, <95 2>; - girqs = <18 4>, <18 5>; - pcrs = <4 22>; - status = "disabled"; - }; - prochot0: prochot@40003400 { - reg = <0x40003400 0x20>; - interrupts = <87 0>; - girqs = <17 17>; - pcrs = <4 13>; - status = "disabled"; - }; - rcid0: rcid@40001400 { - reg = <0x40001400 0x80>; - interrupts = <80 0>; - girqs = <17 10>; - pcrs = <4 10>; - status = "disabled"; - }; - rcid1: rcid@40001480 { - reg = <0x40001480 0x80>; - interrupts = <81 0>; - girqs = <17 11>; - pcrs = <4 11>; - status = "disabled"; - }; - rcid2: rcid@40001500 { - reg = <0x40001500 0x80>; - interrupts = <82 0>; - girqs = <17 12>; - pcrs = <4 12>; - status = "disabled"; - }; - spip0: spip@40007000 { - reg = <0x40007000 0x100>; - interrupts = <90 0>; - girqs = <18 0>; - pcrs = <4 16>; - status = "disabled"; - }; - bbled0: bbled@4000b800 { - reg = <0x4000b800 0x100>; - interrupts = <83 0>; - girqs = <17 13>; - pcrs = <3 16>; - status = "disabled"; - }; - bbled1: bbled@4000b900 { - reg = <0x4000b900 0x100>; - interrupts = <84 0>; - girqs = <17 14>; - pcrs = <3 17>; - status = "disabled"; - }; - bbled2: bbled@4000ba00 { - reg = <0x4000ba00 0x100>; - interrupts = <85 0>; - girqs = <17 15>; - pcrs = <3 18>; - status = "disabled"; - }; - bbled3: bbled@4000bb00 { - reg = <0x4000bb00 0x100>; - interrupts = <86 0>; - girqs = <17 16>; - pcrs = <3 25>; - status = "disabled"; - }; - bclink0: bclink@4000cd00 { - reg = <0x4000cd00 0x20>; - interrupts = <96 0>, <97 0>; - girqs = <18 7>, <18 6>; - pcrs = <3 19>; - status = "disabled"; - }; - tfdp0: tfdp@40008c00 { - reg = <0x40008c00 0x10>; - pcrs = <1 7>; - status = "disabled"; - }; - glblcfg0: glblcfg@400fff00 { - reg = <0x400fff00 0x40>; - pcrs = <2 12>; - status = "disabled"; - }; - uart0: uart@400f2400 { - compatible = "microchip,xec-uart"; - reg = <0x400f2400 0x400>; - interrupts = <40 1>; - clock-frequency = <1843200>; - current-speed = <38400>; - girqs = <15 0>; - pcrs = <2 1>; - ldn = <9>; - status = "disabled"; - }; - uart1: uart@400f2800 { - compatible = "microchip,xec-uart"; - reg = <0x400f2800 0x400>; - interrupts = <41 1>; - clock-frequency = <1843200>; - current-speed = <38400>; - girqs = <15 1>; - pcrs = <2 2>; - ldn = <10>; - status = "disabled"; - }; - espi0: espi@400f3400 { - compatible = "microchip,xec-espi-v2"; - /* reg tuple contains one 32-bit address cell and one - * 32-bit length(size) cell. - */ - #address-cells = <1>; - #size-cells = <1>; - reg = < 0x400f3400 0x400 - 0x400f3800 0x400 - 0x400f9c00 0x400>; - reg-names = "io", "mem", "vw"; - interrupts = <103 3>, <104 3>, <105 3>, <106 3>, - <107 3>, <108 3>, <109 3>, <110 2>, - <156 3>; - interrupt-names = "pc", "bm1", "bm2", "ltr", "oob_up", - "oob_dn", "fc", "rst", "vw_chan_en"; - girqs = < MCHP_XEC_ECIA(19, 0, 11, 103) - MCHP_XEC_ECIA(19, 1, 11, 104) - MCHP_XEC_ECIA(19, 2, 11, 105) - MCHP_XEC_ECIA(19, 3, 11, 106) - MCHP_XEC_ECIA(19, 4, 11, 107) - MCHP_XEC_ECIA(19, 5, 11, 108) - MCHP_XEC_ECIA(19, 6, 11, 109) - MCHP_XEC_ECIA(19, 7, 11, 110) - MCHP_XEC_ECIA(19, 8, 11, 156) >; - pcrs = <2 19>; - status = "disabled"; - - espi_saf0: espi_saf@40008000 { - compatible = "microchip,xec-espi-saf-v2"; - reg = <0x40008000 0x400>, <0x40070000 0x400>, - <0x40071000 0x400>; - reg-names = "safbr", "safqspi", "safcomm"; - interrupts = <166 3>, <167 3>; - interrupt-names = "done", "err"; - girqs = < MCHP_XEC_ECIA(19, 9, 11, 166) >, - < MCHP_XEC_ECIA(19, 10, 11, 167) >; - pcrs = <2 27>; - status = "disabled"; - }; - - mbox0: mbox@400f0000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f0000 0x200>; - interrupts = <60 3>; - girqs = < MCHP_XEC_ECIA(15, 20, 7, 60) >; - pcrs = <2 17>; - ldn = <0>; - status = "disabled"; - }; - kbc0: kbc@400f0400 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f0400 0x400>; - interrupts = <58 3>, <59 3>; - interrupt-names = "kbc_obe", "kbc_ibf"; - girqs = < MCHP_XEC_ECIA(15, 18, 7, 58) - MCHP_XEC_ECIA(15, 19, 7, 59) >; - ldn = <1>; - status = "disabled"; - }; - acpi_ec0: acpi_ec@400f0800 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f0800 0x400>; - interrupts = <45 3>, <46 3>; - interrupt-names = "acpi_ibf", "acpi_obe"; - girqs = < MCHP_XEC_ECIA(15, 5, 7, 45) - MCHP_XEC_ECIA(15, 6, 7, 46) >; - ldn = <2>; - status = "disabled"; - }; - acpi_ec1: acpi_ec@400f0c00 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f0c00 0x400>; - interrupts = <47 3>, <48 3>; - interrupt-names = "acpi_ibf", "acpi_obe"; - girqs = < MCHP_XEC_ECIA(15, 7, 7, 47) - MCHP_XEC_ECIA(15, 8, 7, 48) >; - ldn = <3>; - status = "disabled"; - }; - acpi_ec2: acpi_ec@400f1000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f1000 0x400>; - interrupts = <49 3>, <50 3>; - interrupt-names = "acpi_ibf", "acpi_obe"; - girqs = < MCHP_XEC_ECIA(15, 9, 7, 49) - MCHP_XEC_ECIA(15, 10, 7, 50) >; - ldn = <4>; - status = "disabled"; - }; - acpi_ec3: acpi_ec@400f1400 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f1400 0x400>; - interrupts = <51 3>, <52 3>; - interrupt-names = "acpi_ibf", "acpi_obe"; - girqs = < MCHP_XEC_ECIA(15, 11, 7, 51) - MCHP_XEC_ECIA(15, 12, 7, 52) >; - ldn = <5>; - status = "disabled"; - }; - acpi_ec4: acpi_ec@400f1800 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f1800 0x400>; - interrupts = <53 3>, <54 3>; - interrupt-names = "acpi_ibf", "acpi_obe"; - girqs = < MCHP_XEC_ECIA(15, 13, 7, 53) - MCHP_XEC_ECIA(15, 14, 7, 54) >; - ldn = <6>; - status = "disabled"; - }; - acpi_pm1: acpi_pm1@400f1c00 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f1c00 0x400>; - interrupts = <55 3>, <56 3>, <57 3>; - interrupt-names = "pm1_ctl", "pm1_en", "pm1_sts"; - girqs = < MCHP_XEC_ECIA(15, 15, 7, 55) - MCHP_XEC_ECIA(15, 16, 7, 56) - MCHP_XEC_ECIA(15, 17, 7, 57) >; - ldn = <7>; - status = "disabled"; - }; - port92: port92@400f2000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f2000 0x400>; - ldn = <8>; - status = "disabled"; - }; - emi0: emi@400f4000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f4000 0x400>; - interrupts = <42 3>; - girqs = < MCHP_XEC_ECIA(15, 2, 7, 42) >; - ldn = <16>; - status = "disabled"; - }; - emi1: emi@400f4400 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f4400 0x400>; - interrupts = <43 3>; - girqs = < MCHP_XEC_ECIA(15, 3, 7, 43) >; - ldn = <17>; - status = "disabled"; - }; - emi2: emi@400f4800 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f4800 0x400>; - interrupts = <44 3>; - girqs = < MCHP_XEC_ECIA(15, 4, 7, 44) >; - ldn = <18>; - status = "disabled"; - }; - rtc0: rtc@400f5000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f5000 0x100>; - interrupts = <119 3>, <120 3>; - girqs = < MCHP_XEC_ECIA(21, 8, 13, 119) - MCHP_XEC_ECIA(21, 9, 13, 120) >; - pcrs = <2 18>; - ldn = <20>; - status = "disabled"; - }; - /* Capture writes to host I/O 0x80 - 0x83 */ - p80bd0: p80bd@400f8000 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f8000 0x400>; - interrupts = <62 0>; - girqs = < MCHP_XEC_ECIA(15, 22, 7, 62) >; - pcrs = <2 25>; - ldn = <32>; - status = "disabled"; - }; - /* Capture writes to an 8-bit I/O and map to one of 0x80 to 0x83 */ - p80bd0_alias: p80bd@400f8400 { - compatible = "microchip,xec-espi-host-dev"; - reg = <0x400f8400 0x400>; - ldn = <33>; - host-io = <0x90>; - /* map 0x90 to 0x80 */ - host-io-addr-mask = <0x01>; - status = "disabled"; - }; - }; - - symcr: symcr@40100000 { - compatible = "microchip,xec-symcr"; - reg = <0x40100000 0x1000>; - interrupts = <68 1>; - clocks = <&pcr 3 26 MCHP_XEC_PCR_CLK_PERIPH>; - girqs = <16 3>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <1>; - }; - - rom_api: rom_api@1f000 { - reg = <0x1f000 0x1000>; - status = "disabled"; - }; }; }; From f9b7f8c96d1e9837d5f6e6cf9ecc906dc147de69 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 4 Aug 2023 13:43:28 -0500 Subject: [PATCH 2113/4498] drivers: memc: memc_mcux_flexspi.c: update XIP state check Check XIP state based on the value of CONFIG_FLASH_BASE_ADDRESS. This check should be more reliable than the SOC based method currently used. Signed-off-by: Daniel DeGrasse --- drivers/memc/memc_mcux_flexspi.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/memc/memc_mcux_flexspi.c b/drivers/memc/memc_mcux_flexspi.c index d67e730fd91..950ee379552 100644 --- a/drivers/memc/memc_mcux_flexspi.c +++ b/drivers/memc/memc_mcux_flexspi.c @@ -252,12 +252,13 @@ static int memc_flexspi_pm_action(const struct device *dev, enum pm_device_actio } #endif -#if defined(CONFIG_XIP) && defined(CONFIG_CODE_FLEXSPI) -#define MEMC_FLEXSPI_CFG_XIP(node_id) DT_SAME_NODE(node_id, DT_NODELABEL(flexspi)) -#elif defined(CONFIG_XIP) && defined(CONFIG_CODE_FLEXSPI2) -#define MEMC_FLEXSPI_CFG_XIP(node_id) DT_SAME_NODE(node_id, DT_NODELABEL(flexspi2)) -#elif defined(CONFIG_SOC_SERIES_IMX_RT6XX) || defined(CONFIG_SOC_SERIES_IMX_RT5XX) -#define MEMC_FLEXSPI_CFG_XIP(node_id) DT_SAME_NODE(node_id, DT_NODELABEL(flexspi)) +#if defined(CONFIG_XIP) && defined(CONFIG_FLASH_MCUX_FLEXSPI_XIP) +/* Checks if image flash base address is in the FlexSPI AHB base region */ +#define MEMC_FLEXSPI_CFG_XIP(node_id) \ + ((CONFIG_FLASH_BASE_ADDRESS) >= DT_REG_ADDR_BY_IDX(node_id, 1)) && \ + ((CONFIG_FLASH_BASE_ADDRESS) < (DT_REG_ADDR_BY_IDX(node_id, 1) + \ + DT_REG_SIZE_BY_IDX(node_id, 1))) + #else #define MEMC_FLEXSPI_CFG_XIP(node_id) false #endif From 9a63f39cd8e7e103d25f432ccc9ac8b14a69d752 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 4 Aug 2023 22:02:34 +0000 Subject: [PATCH 2114/4498] drivers: memc: update interface of memc flexspi driver for multi device Update interface of memc flexspi driver to better handle multiple devices. Previously, using multiple devices on one FlexSPI bus would require the user to configure each device to install its command table (referred to as a LUT table by the driver) at an offset, so that it did not overlap with other devices on the bus. This commit changes the interface of the memc flexspi driver to instead configure the LUT and flash device in one call. This allows the memc driver to record the port each LUT sequence is used with, so that future FlexSPI transfer requests can have their LUT offsets adjusted based on the target port (which will correspond to a target device) Signed-off-by: Daniel DeGrasse --- drivers/flash/flash_mcux_flexspi_hyperflash.c | 29 ++----- .../flash/flash_mcux_flexspi_mx25um51345g.c | 28 ++----- drivers/flash/flash_mcux_flexspi_nor.c | 29 ++----- drivers/memc/memc_mcux_flexspi.c | 78 +++++++++++++++---- drivers/memc/memc_mcux_flexspi.h | 77 +++++++++++++++++- drivers/memc/memc_mcux_flexspi_aps6408l.c | 11 +-- drivers/memc/memc_mcux_flexspi_s27ks0641.c | 11 +-- drivers/memc/memc_mcux_flexspi_w956a8mbya.c | 11 +-- 8 files changed, 169 insertions(+), 105 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_hyperflash.c b/drivers/flash/flash_mcux_flexspi_hyperflash.c index d1c6cb1ee06..b0a04ee63ed 100644 --- a/drivers/flash/flash_mcux_flexspi_hyperflash.c +++ b/drivers/flash/flash_mcux_flexspi_hyperflash.c @@ -596,7 +596,6 @@ static int flash_flexspi_hyperflash_init(const struct device *dev) { const struct flash_flexspi_hyperflash_config *config = dev->config; struct flash_flexspi_hyperflash_data *data = dev->data; - uint32_t temp_lut[sizeof(flash_flexspi_hyperflash_lut) / sizeof(uint32_t)]; /* Since the controller variable may be used in critical sections, * copy the device pointer into a variable stored in RAM @@ -610,27 +609,15 @@ static int flash_flexspi_hyperflash_init(const struct device *dev) memc_flexspi_wait_bus_idle(&data->controller); - if (!memc_flexspi_is_running_xip(&data->controller) && - memc_flexspi_set_device_config(&data->controller, &data->config, - data->port)) { - LOG_ERR("Could not set device configuration"); - return -EINVAL; + if (memc_flexspi_is_running_xip(&data->controller)) { + /* Wait for bus idle before configuring */ + memc_flexspi_wait_bus_idle(&data->controller); } - - /* - * Using the LUT stored in the FlexSPI directly when updating - * the FlexSPI can result in an invalid LUT entry being stored, - * as the LUT itself describes how the FlexSPI should access the flash. - * To resolve this, copy the LUT to a array placed in RAM before - * updating the FlexSPI. - */ - memcpy(temp_lut, flash_flexspi_hyperflash_lut, - sizeof(flash_flexspi_hyperflash_lut)); - - if (memc_flexspi_update_lut(&data->controller, 0, - (const uint32_t *) temp_lut, - sizeof(temp_lut) / sizeof(uint32_t))) { - LOG_ERR("Could not update lut"); + if (memc_flexspi_set_device_config(&data->controller, &data->config, + (const uint32_t *)flash_flexspi_hyperflash_lut, + sizeof(flash_flexspi_hyperflash_lut) / MEMC_FLEXSPI_CMD_SIZE, + data->port)) { + LOG_ERR("Could not set device configuration"); return -EINVAL; } diff --git a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c index be3b59dcf12..b72da49d154 100644 --- a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c +++ b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c @@ -512,34 +512,22 @@ static int flash_flexspi_nor_init(const struct device *dev) { struct flash_flexspi_nor_data *data = dev->data; uint8_t vendor_id; - uint32_t temp_lut[sizeof(flash_flexspi_nor_lut) / sizeof(uint32_t)]; if (!device_is_ready(data->controller)) { LOG_ERR("Controller device not ready"); return -ENODEV; } - if (!memc_flexspi_is_running_xip(data->controller) && - memc_flexspi_set_device_config(data->controller, &data->config, - data->port)) { - LOG_ERR("Could not set device configuration"); - return -EINVAL; + if (memc_flexspi_is_running_xip(data->controller)) { + /* Wait for bus idle before configuring */ + memc_flexspi_wait_bus_idle(data->controller); } - /* - * Using the LUT stored in the FlexSPI directly when updating - * the FlexSPI can result in an invalid LUT entry being stored, - * as the LUT itself describes how the FlexSPI should access the flash. - * To resolve this, copy the LUT to a array placed in RAM before - * updating the FlexSPI. - */ - memcpy(temp_lut, flash_flexspi_nor_lut, - sizeof(flash_flexspi_nor_lut)); - - if (memc_flexspi_update_lut(data->controller, 0, - (const uint32_t *) temp_lut, - sizeof(temp_lut) / sizeof(uint32_t))) { - LOG_ERR("Could not update lut"); + if (memc_flexspi_set_device_config(data->controller, &data->config, + (const uint32_t *)flash_flexspi_nor_lut, + sizeof(flash_flexspi_nor_lut) / MEMC_FLEXSPI_CMD_SIZE, + data->port)) { + LOG_ERR("Could not set device configuration"); return -EINVAL; } diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index e863bc9b8db..78d353e9160 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -506,34 +506,21 @@ static int flash_flexspi_nor_init(const struct device *dev) { struct flash_flexspi_nor_data *data = dev->data; uint8_t vendor_id; - uint32_t temp_lut[sizeof(flash_flexspi_nor_lut) / sizeof(uint32_t)]; if (!device_is_ready(data->controller)) { LOG_ERR("Controller device is not ready"); return -ENODEV; } - if (!memc_flexspi_is_running_xip(data->controller) && - memc_flexspi_set_device_config(data->controller, &data->config, - data->port)) { - LOG_ERR("Could not set device configuration"); - return -EINVAL; + if (memc_flexspi_is_running_xip(data->controller)) { + /* Wait for bus idle before configuring */ + memc_flexspi_wait_bus_idle(data->controller); } - - /* - * Using the LUT stored in the FlexSPI directly when updating - * the FlexSPI can result in an invalid LUT entry being stored, - * as the LUT itself describes how the FlexSPI should access the flash. - * To resolve this, copy the LUT to a array placed in RAM before - * updating the FlexSPI. - */ - memcpy(temp_lut, flash_flexspi_nor_lut, - sizeof(flash_flexspi_nor_lut)); - - if (memc_flexspi_update_lut(data->controller, 0, - (const uint32_t *) temp_lut, - sizeof(temp_lut) / sizeof(uint32_t))) { - LOG_ERR("Could not update lut"); + if (memc_flexspi_set_device_config(data->controller, &data->config, + (const uint32_t *)flash_flexspi_nor_lut, + sizeof(flash_flexspi_nor_lut) / MEMC_FLEXSPI_CMD_SIZE, + data->port)) { + LOG_ERR("Could not set device configuration"); return -EINVAL; } diff --git a/drivers/memc/memc_mcux_flexspi.c b/drivers/memc/memc_mcux_flexspi.c index 950ee379552..84ab86a793a 100644 --- a/drivers/memc/memc_mcux_flexspi.c +++ b/drivers/memc/memc_mcux_flexspi.c @@ -26,6 +26,8 @@ read-while-write hazards. This configuration is not recommended." #endif +#define FLEXSPI_MAX_LUT 64U + LOG_MODULE_REGISTER(memc_flexspi, CONFIG_MEMC_LOG_LEVEL); struct memc_flexspi_buf_cfg { @@ -35,6 +37,12 @@ struct memc_flexspi_buf_cfg { uint16_t buf_size; } __packed; +/* Structure tracking LUT offset and usage per each port */ +struct port_lut { + uint8_t lut_offset; + uint8_t lut_used; +}; + /* flexspi device data should be stored in RAM to avoid read-while-write hazards */ struct memc_flexspi_data { FLEXSPI_Type *base; @@ -49,6 +57,7 @@ struct memc_flexspi_data { flexspi_read_sample_clock_t rx_sample_clock; const struct pinctrl_dev_config *pincfg; size_t size[kFLEXSPI_PortCount]; + struct port_lut port_luts[kFLEXSPI_PortCount]; struct memc_flexspi_buf_cfg *buf_cfg; uint8_t buf_cfg_cnt; }; @@ -68,16 +77,6 @@ bool memc_flexspi_is_running_xip(const struct device *dev) return data->xip; } -int memc_flexspi_update_lut(const struct device *dev, uint32_t index, - const uint32_t *cmd, uint32_t count) -{ - struct memc_flexspi_data *data = dev->data; - - FLEXSPI_UpdateLUT(data->base, index, cmd, count); - - return 0; -} - int memc_flexspi_update_clock(const struct device *dev, flexspi_device_config_t *device_config, flexspi_port_t port, enum memc_flexspi_clock_t clock) @@ -108,20 +107,65 @@ int memc_flexspi_update_clock(const struct device *dev, int memc_flexspi_set_device_config(const struct device *dev, const flexspi_device_config_t *device_config, + const uint32_t *lut_array, + uint8_t lut_count, flexspi_port_t port) { + flexspi_device_config_t tmp_config; + uint32_t tmp_lut[FLEXSPI_MAX_LUT]; struct memc_flexspi_data *data = dev->data; + const uint32_t *lut_ptr = lut_array; + uint8_t lut_used = 0U; + unsigned int key = 0; if (port >= kFLEXSPI_PortCount) { LOG_ERR("Invalid port number"); return -EINVAL; } + if (data->port_luts[port].lut_used < lut_count) { + /* We cannot reuse the existing LUT slot, + * Check if the LUT table will fit into the remaining LUT slots + */ + for (uint8_t i = 0; i < kFLEXSPI_PortCount; i++) { + lut_used += data->port_luts[i].lut_used; + } + + if ((lut_used + lut_count) > FLEXSPI_MAX_LUT) { + return -ENOBUFS; + } + } + data->size[port] = device_config->flashSize * KB(1); - FLEXSPI_SetFlashConfig(data->base, - (flexspi_device_config_t *) device_config, - port); + if (memc_flexspi_is_running_xip(dev)) { + /* We need to avoid flash access while configuring the FlexSPI. + * To do this, we will copy the LUT array into stack-allocated + * temporary memory + */ + memcpy(tmp_lut, lut_array, lut_count * MEMC_FLEXSPI_CMD_SIZE); + lut_ptr = tmp_lut; + } + + memcpy(&tmp_config, device_config, sizeof(tmp_config)); + /* Update FlexSPI AWRSEQID and ARDSEQID values based on where the LUT + * array will actually be loaded. + */ + if (data->port_luts[port].lut_used < lut_count) { + /* Update lut offset with new value */ + data->port_luts[port].lut_offset = lut_used; + } + data->port_luts[port].lut_used = lut_count; + tmp_config.ARDSeqIndex += data->port_luts[port].lut_offset; + tmp_config.AWRSeqIndex += data->port_luts[port].lut_offset; + + /* Lock IRQs before reconfiguring FlexSPI, to prevent XIP */ + key = irq_lock(); + + FLEXSPI_SetFlashConfig(data->base, &tmp_config, port); + FLEXSPI_UpdateLUT(data->base, data->port_luts[port].lut_offset, + lut_ptr, lut_count); + irq_unlock(key); return 0; } @@ -139,7 +183,11 @@ int memc_flexspi_transfer(const struct device *dev, flexspi_transfer_t *transfer) { struct memc_flexspi_data *data = dev->data; - status_t status = FLEXSPI_TransferBlocking(data->base, transfer); + status_t status; + + /* Adjust transfer LUT index based on port */ + transfer->seqIndex += data->port_luts[transfer->port].lut_offset; + status = FLEXSPI_TransferBlocking(data->base, transfer); if (status != kStatus_Success) { LOG_ERR("Transfer error: %d", status); @@ -161,7 +209,7 @@ void *memc_flexspi_get_ahb_address(const struct device *dev, } for (i = 0; i < port; i++) { - offset += data->size[port]; + offset += data->size[i]; } return data->ahb_base + offset; diff --git a/drivers/memc/memc_mcux_flexspi.h b/drivers/memc/memc_mcux_flexspi.h index 3d201c7b6d7..a8495fc9289 100644 --- a/drivers/memc/memc_mcux_flexspi.h +++ b/drivers/memc/memc_mcux_flexspi.h @@ -1,5 +1,5 @@ /* - * Copyright 2020 NXP + * Copyright 2020,2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,25 +15,94 @@ enum memc_flexspi_clock_t { MEMC_FLEXSPI_CLOCK_42M, }; +/* Size of a command in the LUT table */ +#define MEMC_FLEXSPI_CMD_SIZE 4U + +/** + * @brief Wait for the FlexSPI bus to be idle + * + * Waits for the FlexSPI bus to be idle. Can be used when reconfiguring + * the FlexSPI to make sure no flash access is occurring before changing + * settings. + * + * @param dev: FlexSPI device + */ void memc_flexspi_wait_bus_idle(const struct device *dev); +/** + * @brief Check if FlexSPI is being used in XIP mode. + * + * Checks if the FlexSPI is being used for code execution in the current + * application. + * + * @param dev: FlexSPI device + * @retval true if FlexSPI being used for XIP + */ bool memc_flexspi_is_running_xip(const struct device *dev); -int memc_flexspi_update_lut(const struct device *dev, uint32_t index, - const uint32_t *cmd, uint32_t count); - +/** + * @brief Update clock selection of the FlexSPI device + * + * Updates clock selection of the FlexSPI device to a new clock speed. + * + * @param dev: FlexSPI device + * @param device_config: External device configuration. + * @param port: FlexSPI port to use for this external device + * @param clock: new clock selection to apply + * @return 0 on success, negative value on failure + */ int memc_flexspi_update_clock(const struct device *dev, flexspi_device_config_t *device_config, flexspi_port_t port, enum memc_flexspi_clock_t clock); +/** + * @brief configure new FlexSPI device + * + * Configures new device on the FlexSPI bus. + * @param dev: FlexSPI device + * @param device_config: External device configuration. + * @param lut_array: Lookup table of FlexSPI flash commands for device + * @param lut_count: number of command entries (16 bytes each) in LUT + * @param port: FlexSPI port to use for this external device + * @return 0 on success, negative value on failure + */ int memc_flexspi_set_device_config(const struct device *dev, const flexspi_device_config_t *device_config, + const uint32_t *lut_array, + uint8_t lut_count, flexspi_port_t port); + +/** + * @brief Perform software reset of FlexSPI + * + * Software reset of FlexSPI. Does not clear configuration registers. + * @param dev: FlexSPI device + * @return 0 on success, negative value on failure + */ int memc_flexspi_reset(const struct device *dev); +/** + * @brief Send blocking IP transfer + * + * Send blocking IP transfer using FlexSPI. + * @param dev: FlexSPI device + * @param transfer: FlexSPI transfer. seqIndex should be set as though the + * LUT array was loaded at offset 0. + * @return 0 on success, negative value on failure + */ int memc_flexspi_transfer(const struct device *dev, flexspi_transfer_t *transfer); +/** + * @brief Get AHB address for FlexSPI port + * + * Get AHB address for FlexSPI port. This address is memory mapped, and can be + * read from (and written to, for PSRAM) as though it were internal memory. + * @param dev: FlexSPI device + * @param port: FlexSPI port external device is on + * @param offset: byte offset from start of device to get AHB address for + * @return 0 on success, negative value on failure + */ void *memc_flexspi_get_ahb_address(const struct device *dev, flexspi_port_t port, off_t offset); diff --git a/drivers/memc/memc_mcux_flexspi_aps6408l.c b/drivers/memc/memc_mcux_flexspi_aps6408l.c index 0c295221a10..a9b51e77bfa 100644 --- a/drivers/memc/memc_mcux_flexspi_aps6408l.c +++ b/drivers/memc/memc_mcux_flexspi_aps6408l.c @@ -215,18 +215,13 @@ static int memc_flexspi_aps6408l_init(const struct device *dev) } if (memc_flexspi_set_device_config(data->controller, &config->config, - config->port)) { + (const uint32_t *) memc_flexspi_aps6408l_lut, + sizeof(memc_flexspi_aps6408l_lut) / MEMC_FLEXSPI_CMD_SIZE, + config->port)) { LOG_ERR("Could not set device configuration"); return -EINVAL; } - if (memc_flexspi_update_lut(data->controller, 0, - (const uint32_t *) memc_flexspi_aps6408l_lut, - sizeof(memc_flexspi_aps6408l_lut) / 4)) { - LOG_ERR("Could not update lut"); - return -EINVAL; - } - memc_flexspi_reset(data->controller); if (memc_flexspi_aps6408l_reset(dev)) { diff --git a/drivers/memc/memc_mcux_flexspi_s27ks0641.c b/drivers/memc/memc_mcux_flexspi_s27ks0641.c index ee7431c9201..36fc5bf8306 100644 --- a/drivers/memc/memc_mcux_flexspi_s27ks0641.c +++ b/drivers/memc/memc_mcux_flexspi_s27ks0641.c @@ -122,18 +122,13 @@ static int memc_flexspi_s27ks0641_init(const struct device *dev) } if (memc_flexspi_set_device_config(data->controller, &config->config, - config->port)) { + (const uint32_t *) memc_flexspi_s27ks0641_lut, + sizeof(memc_flexspi_s27ks0641_lut) / MEMC_FLEXSPI_CMD_SIZE, + config->port)) { LOG_ERR("Could not set device configuration"); return -EINVAL; } - if (memc_flexspi_update_lut(data->controller, 0, - (const uint32_t *) memc_flexspi_s27ks0641_lut, - sizeof(memc_flexspi_s27ks0641_lut) / 4)) { - LOG_ERR("Could not update lut"); - return -EINVAL; - } - memc_flexspi_reset(data->controller); if (memc_flexspi_s27ks0641_get_vendor_id(dev, &vendor_id)) { diff --git a/drivers/memc/memc_mcux_flexspi_w956a8mbya.c b/drivers/memc/memc_mcux_flexspi_w956a8mbya.c index ad24ecccdc7..60c5949b73f 100644 --- a/drivers/memc/memc_mcux_flexspi_w956a8mbya.c +++ b/drivers/memc/memc_mcux_flexspi_w956a8mbya.c @@ -114,18 +114,13 @@ static int memc_flexspi_w956a8mbya_init(const struct device *dev) } if (memc_flexspi_set_device_config(data->controller, &config->config, - config->port)) { + (const uint32_t *) memc_flexspi_w956a8mbya_lut, + sizeof(memc_flexspi_w956a8mbya_lut) / MEMC_FLEXSPI_CMD_SIZE, + config->port)) { LOG_ERR("Could not set device configuration"); return -EINVAL; } - if (memc_flexspi_update_lut(data->controller, 0, - (const uint32_t *) memc_flexspi_w956a8mbya_lut, - sizeof(memc_flexspi_w956a8mbya_lut) / 4)) { - LOG_ERR("Could not update lut"); - return -EINVAL; - } - memc_flexspi_reset(data->controller); if (memc_flexspi_w956a8mbya_get_vendor_id(dev, &vendor_id)) { From 96d6d70f13a4e6ef174cc4c1de94dda650091e96 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 17 Aug 2023 16:01:57 -0500 Subject: [PATCH 2115/4498] samples: drivers: memc: get AHB address dynamically Use MEMC API to extract AHB address from FlexSPI when using it with the MEMC sample. Signed-off-by: Daniel DeGrasse --- samples/drivers/memc/CMakeLists.txt | 5 +++++ samples/drivers/memc/src/main.c | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/samples/drivers/memc/CMakeLists.txt b/samples/drivers/memc/CMakeLists.txt index 1e46e72f25b..04025a6b0fb 100644 --- a/samples/drivers/memc/CMakeLists.txt +++ b/samples/drivers/memc/CMakeLists.txt @@ -5,4 +5,9 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(memc) + +if(CONFIG_MEMC_MCUX_FLEXSPI) + target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers/memc) +endif() + target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/memc/src/main.c b/samples/drivers/memc/src/main.c index 86b7ff86b60..60bc1170761 100644 --- a/samples/drivers/memc/src/main.c +++ b/samples/drivers/memc/src/main.c @@ -7,8 +7,11 @@ #include #if DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi) -/* FlexSPI memory mapped region is second register property of parent dev */ -#define MEMC_BASE DT_REG_ADDR_BY_IDX(DT_PARENT(DT_ALIAS(sram_ext)), 1) +/* Use memc API to get AHB base address for the device */ +#include "memc_mcux_flexspi.h" +#define FLEXSPI_DEV DEVICE_DT_GET(DT_PARENT(DT_ALIAS(sram_ext))) +#define MEMC_PORT DT_REG_ADDR(DT_ALIAS(sram_ext)) +#define MEMC_BASE memc_flexspi_get_ahb_address(FLEXSPI_DEV, MEMC_PORT, 0) #define MEMC_SIZE (DT_PROP(DT_ALIAS(sram_ext), size) / 8) #endif @@ -49,7 +52,7 @@ int main(void) for (i = 0; i < BUF_SIZE; i++) { memc_write_buffer[i] = (uint8_t)i; } - printk("Writing to memory region with base 0x%0x, size 0x%0x\n\n", + printk("Writing to memory region with base %p, size 0x%0x\n\n", MEMC_BASE, MEMC_SIZE); /* Copy write buffer into memc region */ for (i = 0, j = 0; j < (MEMC_SIZE / BUF_SIZE); i += BUF_SIZE, j++) { From b10f02da61b823dc3453c4dd283fb3dd2bc7d62b Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 11 Aug 2023 12:13:14 +0200 Subject: [PATCH 2116/4498] Bluetooth: audio: has: Fix checking wrong flag This fixes testing and clearing features flag. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index b8e70e4e164..d8696ca5a2c 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -1296,7 +1296,7 @@ static void features_work_process(struct k_work *work) /* mark to notify on reconnect */ atomic_set_bit(client->flags, FLAG_FEATURES_CHANGED); continue; - } else if (atomic_test_and_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY)) { + } else if (atomic_test_and_clear_bit(client->flags, FLAG_FEATURES_CHANGED)) { err = bt_gatt_notify(client->conn, FEATURES_ATTR, &has.features, sizeof(has.features)); if (err != 0) { From cf2f2df61d52b45103f6582503f9a70bddc3ceda Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 11 Aug 2023 12:20:05 +0200 Subject: [PATCH 2117/4498] Bluetooth: audio: has: Fix indentation This fixes code indentation. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index d8696ca5a2c..0509a254ba3 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -829,11 +829,11 @@ static void preset_active_set(uint8_t index) if (index != has.active_index) { has.active_index = index; - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; + for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { + struct has_client *client = &has_client_list[i]; /* mark to notify */ - atomic_set_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED); - } + atomic_set_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED); + } /* Emit active preset notification */ k_work_submit(&active_preset_work); From c44f0da4f1c9c63eb4112f8a7c780c8c4b43eb2a Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 23 Aug 2023 16:42:04 +0200 Subject: [PATCH 2118/4498] Bluetooth: audio: has: Don't revert features value on error This removes revering the features value back to previous state if work submission failes. Even if it fails it indicates an internal sysworkq issue, so even retry won't help. The client can read the features value anyway, thus it's sane to just log an error in such case. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index 0509a254ba3..d929d2fa3c9 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -1308,7 +1308,6 @@ static void features_work_process(struct k_work *work) int bt_has_features_set(const struct bt_has_features_param *features) { - uint8_t tmp_features; int err; if (!has.registered) { @@ -1322,36 +1321,21 @@ int bt_has_features_set(const struct bt_has_features_param *features) return 0; } - tmp_features = has.features; - err = has_features_register(features); if (err != 0) { LOG_DBG("Failed to register features"); return err; } - bool tmp_pending_ntf_features[ARRAY_SIZE(has_client_list)]; - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { struct has_client *client = &has_client_list[i]; - /* save old state */ - tmp_pending_ntf_features[i] = atomic_test_bit(client->flags, FLAG_FEATURES_CHANGED); - /* mark to notify */ + atomic_set_bit(client->flags, FLAG_FEATURES_CHANGED); } err = k_work_submit(&features_work); if (err < 0) { - /* restore old values */ - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; - - atomic_set_bit_to(client->flags, FLAG_FEATURES_CHANGED, - tmp_pending_ntf_features[i]); - } - has.features = tmp_features; - - return err; + LOG_ERR("Failed to reschedule features notification err %d", err); } return 0; From f63726da799e2970f21002fac4a6622d31bb8ebe Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 28 Aug 2023 11:22:04 +0200 Subject: [PATCH 2119/4498] Bluetooth: audio: has: Fix sending notifications on reconnect This fixes missing setting of FLAG_CONTROL_POINT_NOTIFY flag that indicate whether submit control_point_work. In case the there are more indications/notifications to sent (is_last flag is unset), the FLAG_CONTROL_POINT_NOTIFY shall be set to resubmit control_point_work. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index d929d2fa3c9..766791cce79 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -275,7 +275,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_ #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) /* Notify after reconnection */ - if (atomic_test_and_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED)) { + if (atomic_test_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED)) { /* Emit active preset notification */ k_work_submit(&active_preset_work); } @@ -287,8 +287,8 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_ #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ #if defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) - if (atomic_test_and_clear_bit(client->flags, FLAG_FEATURES_CHANGED)) { - /* Emit preset changed notifications */ + if (atomic_test_bit(client->flags, FLAG_FEATURES_CHANGED)) { + /* Emit features changed notification */ k_work_submit(&features_work); } #endif /* CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ @@ -644,7 +644,7 @@ static void process_control_point_work(struct k_work *work) client->read_presets_req.start_index = preset->index + 1; client->read_presets_req.num_presets--; } - } else if (atomic_test_and_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY)) { + } else { const struct has_preset *preset = NULL; const struct has_preset *next = NULL; bool is_last = true; @@ -664,12 +664,9 @@ static void process_control_point_work(struct k_work *work) err = bt_has_cp_generic_update(client, preset, is_last); if (err) { LOG_ERR("bt_has_cp_read_preset_rsp failed (err %d)", err); - } - - if (err || is_last) { - atomic_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY); - } else { + } else if (!is_last) { client->preset_changed_index_next = preset->index + 1; + atomic_set_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY); } } } From b89cdadc748954015ecc3c2cdcb410e676023d30 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 30 Aug 2023 09:34:40 +0200 Subject: [PATCH 2120/4498] Bluetooth: audio: has: Factor out set_preset_availability function This moves common code to set_preset_availability function to be called from bt_has_preset_available and bt_has_preset_unavailable. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 60 ++++++++++++++---------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index 766791cce79..acbaf13d757 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -1117,9 +1117,12 @@ int bt_has_preset_unregister(uint8_t index) return control_point_send_all(&buf); } -int bt_has_preset_available(uint8_t index) +static int set_preset_availability(uint8_t index, bool available) { + NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + + sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); struct has_preset *preset = NULL; + uint8_t change_id; CHECKIF(index == BT_HAS_PRESET_INDEX_NONE) { LOG_ERR("index is invalid"); @@ -1131,50 +1134,33 @@ int bt_has_preset_available(uint8_t index) return -ENOENT; } - /* toggle property bit if needed */ - if (!(preset->properties & BT_HAS_PROP_AVAILABLE)) { - NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + - sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); - - preset->properties ^= BT_HAS_PROP_AVAILABLE; - - preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_PRESET_AVAILABLE, BT_HAS_IS_LAST); - net_buf_simple_add_u8(&buf, preset->index); - - return control_point_send_all(&buf); + if ((preset->properties & BT_HAS_PROP_AVAILABLE) == available) { + /* availability not changed */ + return 0; } - return 0; -} - -int bt_has_preset_unavailable(uint8_t index) -{ - struct has_preset *preset = NULL; - - CHECKIF(index == BT_HAS_PRESET_INDEX_NONE) { - LOG_ERR("index is invalid"); - return -EINVAL; - } + preset->properties ^= BT_HAS_PROP_AVAILABLE; - preset_foreach(index, index, preset_found, &preset); - if (preset == NULL) { - return -ENOENT; + if (is_preset_available(preset)) { + change_id = BT_HAS_CHANGE_ID_PRESET_AVAILABLE; + } else { + change_id = BT_HAS_CHANGE_ID_PRESET_UNAVAILABLE; } - /* toggle property bit if needed */ - if (preset->properties & BT_HAS_PROP_AVAILABLE) { - NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + - sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); - - preset->properties ^= BT_HAS_PROP_AVAILABLE; + preset_changed_prepare(&buf, change_id, BT_HAS_IS_LAST); + net_buf_simple_add_u8(&buf, preset->index); - preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_PRESET_UNAVAILABLE, BT_HAS_IS_LAST); - net_buf_simple_add_u8(&buf, preset->index); + return control_point_send_all(&buf); +} - return control_point_send_all(&buf); - } +int bt_has_preset_available(uint8_t index) +{ + return set_preset_availability(index, true); +} - return 0; +int bt_has_preset_unavailable(uint8_t index) +{ + return set_preset_availability(index, false); } struct bt_has_preset_foreach_data { From 2735339a82c8d6cf6bc46c3bd7165c277890398e Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 25 Aug 2023 16:56:40 +0200 Subject: [PATCH 2121/4498] tests: Bluetooth: has: Add test Preset Changed Offline Behavior Verify that a HAS Server IUT sends changed characteristic notifications or indications when the Lower Tester reconnects. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has_internal.h | 1 + tests/bsim/bluetooth/audio/prj.conf | 1 + tests/bsim/bluetooth/audio/src/common.c | 12 + tests/bsim/bluetooth/audio/src/common.h | 1 + .../bluetooth/audio/src/has_client_test.c | 457 +++++++++++++++++- tests/bsim/bluetooth/audio/src/has_test.c | 59 ++- .../audio/test_scripts/has_offline.sh | 26 + 7 files changed, 548 insertions(+), 9 deletions(-) create mode 100755 tests/bsim/bluetooth/audio/test_scripts/has_offline.sh diff --git a/subsys/bluetooth/audio/has_internal.h b/subsys/bluetooth/audio/has_internal.h index 96fafda9473..c4152eaea1c 100644 --- a/subsys/bluetooth/audio/has_internal.h +++ b/subsys/bluetooth/audio/has_internal.h @@ -77,6 +77,7 @@ struct bt_has_cp_read_preset_rsp { struct bt_has_cp_preset_changed { uint8_t change_id; uint8_t is_last; + uint8_t additional_params[0]; } __packed; struct bt_has_cp_generic_update { diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index 8f2d6a585a9..e4d25d1ed0f 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -117,6 +117,7 @@ CONFIG_BT_BAP_BROADCAST_ASSISTANT=y # Hearing Access CONFIG_BT_HAS=y +CONFIG_BT_HAS_PRESET_COUNT=3 CONFIG_BT_HAS_CLIENT=y CONFIG_BT_HAS_FEATURES_NOTIFIABLE=y diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 90a8cb98efa..8a518c62fe8 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -11,6 +11,7 @@ extern enum bst_result_t bst_result; struct bt_conn *default_conn; atomic_t flag_connected; atomic_t flag_conn_updated; +volatile bt_security_t security_level; const struct bt_data ad[AD_SIZE] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) @@ -94,6 +95,7 @@ void disconnected(struct bt_conn *conn, uint8_t reason) default_conn = NULL; UNSET_FLAG(flag_connected); UNSET_FLAG(flag_conn_updated); + security_level = BT_SECURITY_L1; } static void conn_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint16_t latency, @@ -105,10 +107,20 @@ static void conn_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint1 SET_FLAG(flag_conn_updated); } +static void security_changed_cb(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + printk("Security changed: %p level %d err %d\n", conn, level, err); + + if (err == BT_SECURITY_ERR_SUCCESS) { + security_level = level; + } +} + BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = connected, .disconnected = disconnected, .le_param_updated = conn_param_updated_cb, + .security_changed = security_changed_cb, }; void test_tick(bs_time_t HW_device_time) diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 14d6dbbc092..bcbd91e6d18 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -70,6 +70,7 @@ extern const struct bt_data ad[AD_SIZE]; extern struct bt_conn *default_conn; extern atomic_t flag_connected; extern atomic_t flag_conn_updated; +extern volatile bt_security_t security_level; void disconnected(struct bt_conn *conn, uint8_t reason); void test_tick(bs_time_t HW_device_time); diff --git a/tests/bsim/bluetooth/audio/src/has_client_test.c b/tests/bsim/bluetooth/audio/src/has_client_test.c index 6690c6b032e..27ad787fef1 100644 --- a/tests/bsim/bluetooth/audio/src/has_client_test.c +++ b/tests/bsim/bluetooth/audio/src/has_client_test.c @@ -4,9 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifdef CONFIG_BT_HAS_CLIENT #include +#include "../../subsys/bluetooth/audio/has_internal.h" + #include "common.h" extern enum bst_result_t bst_result; @@ -14,12 +15,15 @@ extern enum bst_result_t bst_result; extern const char *test_preset_name_1; extern const char *test_preset_name_5; extern const uint8_t test_preset_index_1; +extern const uint8_t test_preset_index_3; extern const uint8_t test_preset_index_5; extern const enum bt_has_properties test_preset_properties; +#ifdef CONFIG_BT_HAS_CLIENT CREATE_FLAG(g_service_discovered); CREATE_FLAG(g_preset_switched); CREATE_FLAG(g_preset_1_found); +CREATE_FLAG(g_preset_3_found); CREATE_FLAG(g_preset_5_found); static struct bt_has *g_has; @@ -82,10 +86,23 @@ static void preset_read_rsp_cb(struct bt_has *has, int err, } } +static void preset_update_cb(struct bt_has *has, uint8_t index_prev, + const struct bt_has_preset_record *record, bool is_last) +{ + if (record->index == test_preset_index_1) { + SET_FLAG(g_preset_1_found); + } else if (record->index == test_preset_index_3) { + SET_FLAG(g_preset_3_found); + } else if (record->index == test_preset_index_5) { + SET_FLAG(g_preset_5_found); + } +} + static const struct bt_has_client_cb has_cb = { .discover = discover_cb, .preset_switch = preset_switch_cb, .preset_read_rsp = preset_read_rsp_cb, + .preset_update = preset_update_cb, }; static bool test_preset_switch(uint8_t index) @@ -229,14 +246,445 @@ static void test_main(void) PASS("HAS main PASS\n"); } +#endif /* CONFIG_BT_HAS_CLIENT */ + +#define FEATURES_SUB_NTF BIT(0) +#define ACTIVE_INDEX_SUB_NTF BIT(1) +#define PRESET_CHANGED_SUB_NTF BIT(2) +#define SUB_NTF_ALL (FEATURES_SUB_NTF | ACTIVE_INDEX_SUB_NTF | PRESET_CHANGED_SUB_NTF) + +CREATE_FLAG(flag_features_discovered); +CREATE_FLAG(flag_active_preset_index_discovered); +CREATE_FLAG(flag_control_point_discovered); +CREATE_FLAG(flag_all_notifications_received); + +enum preset_state { + STATE_UNKNOWN, + STATE_AVAILABLE, + STATE_UNAVAILABLE, + STATE_DELETED, +}; + +static enum preset_state preset_state_1; +static enum preset_state preset_state_3; +static enum preset_state preset_state_5; + +static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0); +static struct bt_gatt_discover_params discover_params; +static struct bt_gatt_subscribe_params features_sub; +static struct bt_gatt_subscribe_params active_preset_index_sub; +static struct bt_gatt_subscribe_params control_point_sub; +static uint8_t notify_received_mask; + +static void preset_availability_changed(uint8_t index, bool available) +{ + enum preset_state state = available ? STATE_AVAILABLE : STATE_UNAVAILABLE; + + if (index == test_preset_index_1) { + preset_state_1 = state; + } else if (index == test_preset_index_3) { + preset_state_3 = state; + } else if (index == test_preset_index_5) { + preset_state_5 = state; + } else { + FAIL("invalid preset index 0x%02x", index); + } +} + +static uint8_t notify_handler(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) +{ + printk("conn %p params %p data %p length %u\n", (void *)conn, params, data, length); + + if (params == &features_sub) { + if (data == NULL) { + printk("features_sub [UNSUBSCRIBED]\n"); + return BT_GATT_ITER_STOP; + } + + printk("Received features_sub notification\n"); + notify_received_mask |= FEATURES_SUB_NTF; + } else if (params == &active_preset_index_sub) { + if (data == NULL) { + printk("active_preset_index_sub_sub [UNSUBSCRIBED]\n"); + return BT_GATT_ITER_STOP; + } + + printk("Received active_preset_index_sub_sub notification\n"); + notify_received_mask |= ACTIVE_INDEX_SUB_NTF; + } else if (params == &control_point_sub) { + const struct bt_has_cp_hdr *hdr; + + if (data == NULL) { + printk("control_point_sub [UNSUBSCRIBED]\n"); + return BT_GATT_ITER_STOP; + } + + if (length < sizeof(*hdr)) { + FAIL("malformed bt_has_cp_hdr"); + return BT_GATT_ITER_STOP; + } + + hdr = data; + + if (hdr->opcode == BT_HAS_OP_PRESET_CHANGED) { + const struct bt_has_cp_preset_changed *pc; + + if (length < (sizeof(*hdr) + sizeof(*pc))) { + FAIL("malformed bt_has_cp_preset_changed"); + return BT_GATT_ITER_STOP; + } + + pc = (const void *)hdr->data; + + switch (pc->change_id) { + case BT_HAS_CHANGE_ID_GENERIC_UPDATE: { + const struct bt_has_cp_generic_update *gu; + bool is_available; + + if (length < (sizeof(*hdr) + sizeof(*pc) + sizeof(*gu))) { + FAIL("malformed bt_has_cp_generic_update"); + return BT_GATT_ITER_STOP; + } + + gu = (const void *)pc->additional_params; + + printk("Received generic update index 0x%02x props 0x%02x\n", + gu->index, gu->properties); + + is_available = (gu->properties & BT_HAS_PROP_AVAILABLE) != 0; + + preset_availability_changed(gu->index, is_available); + break; + } + default: + printk("Unexpected Change ID 0x%02x", pc->change_id); + return BT_GATT_ITER_STOP; + } + + if (pc->is_last) { + notify_received_mask |= PRESET_CHANGED_SUB_NTF; + } + } else { + printk("Unexpected opcode 0x%02x", hdr->opcode); + return BT_GATT_ITER_STOP; + } + } + + printk("pacs_instance.notify_received_mask is %d\n", notify_received_mask); + + if (notify_received_mask == SUB_NTF_ALL) { + SET_FLAG(flag_all_notifications_received); + notify_received_mask = 0; + } + + return BT_GATT_ITER_CONTINUE; +} + +static void subscribe_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_subscribe_params *params) +{ + if (err != BT_ATT_ERR_SUCCESS) { + return; + } + + printk("[SUBSCRIBED]\n"); + + if (params == &features_sub) { + SET_FLAG(flag_features_discovered); + return; + } + + if (params == &control_point_sub) { + SET_FLAG(flag_control_point_discovered); + return; + } + + if (params == &active_preset_index_sub) { + SET_FLAG(flag_active_preset_index_discovered); + return; + } +} + +static uint8_t discover_features_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_gatt_subscribe_params *subscribe_params; + int err; + + if (!attr) { + printk("Discover complete\n"); + (void)memset(params, 0, sizeof(*params)); + return BT_GATT_ITER_STOP; + } + + if (!bt_uuid_cmp(params->uuid, BT_UUID_HAS_HEARING_AID_FEATURES)) { + printk("HAS Hearing Aid Features handle at %d\n", attr->handle); + memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = attr->handle + 2; + discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + subscribe_params = &features_sub; + subscribe_params->value_handle = bt_gatt_attr_value_handle(attr); + + err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Discover failed (err %d)\n", err); + } + } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) { + printk("CCC handle at %d\n", attr->handle); + subscribe_params = &features_sub; + subscribe_params->notify = notify_handler; + subscribe_params->value = BT_GATT_CCC_NOTIFY; + subscribe_params->ccc_handle = attr->handle; + subscribe_params->subscribe = subscribe_cb; + + err = bt_gatt_subscribe(conn, subscribe_params); + if (err && err != -EALREADY) { + printk("Subscribe failed (err %d)\n", err); + } + } else { + printk("Unknown handle at %d\n", attr->handle); + return BT_GATT_ITER_CONTINUE; + } + + return BT_GATT_ITER_STOP; +} + +static void discover_and_subscribe_features(void) +{ + int err = 0; + + printk("%s\n", __func__); + + memcpy(&uuid, BT_UUID_HAS_HEARING_AID_FEATURES, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discover_params.func = discover_features_cb; + + err = bt_gatt_discover(default_conn, &discover_params); + if (err != 0) { + FAIL("Service Discovery failed (err %d)\n", err); + return; + } +} + +static uint8_t discover_active_preset_index_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_gatt_subscribe_params *subscribe_params; + int err; + + if (!attr) { + printk("Discover complete\n"); + (void)memset(params, 0, sizeof(*params)); + return BT_GATT_ITER_STOP; + } + + if (!bt_uuid_cmp(params->uuid, BT_UUID_HAS_ACTIVE_PRESET_INDEX)) { + printk("HAS Hearing Aid Features handle at %d\n", attr->handle); + memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = attr->handle + 2; + discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + subscribe_params = &active_preset_index_sub; + subscribe_params->value_handle = bt_gatt_attr_value_handle(attr); + + err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Discover failed (err %d)\n", err); + } + } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) { + printk("CCC handle at %d\n", attr->handle); + subscribe_params = &active_preset_index_sub; + subscribe_params->notify = notify_handler; + subscribe_params->value = BT_GATT_CCC_NOTIFY; + subscribe_params->ccc_handle = attr->handle; + subscribe_params->subscribe = subscribe_cb; + + err = bt_gatt_subscribe(conn, subscribe_params); + if (err && err != -EALREADY) { + printk("Subscribe failed (err %d)\n", err); + } + } else { + printk("Unknown handle at %d\n", attr->handle); + return BT_GATT_ITER_CONTINUE; + } + + return BT_GATT_ITER_STOP; +} + +static void discover_and_subscribe_active_preset_index(void) +{ + int err = 0; + + printk("%s\n", __func__); + + memcpy(&uuid, BT_UUID_HAS_ACTIVE_PRESET_INDEX, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discover_params.func = discover_active_preset_index_cb; + + err = bt_gatt_discover(default_conn, &discover_params); + if (err != 0) { + FAIL("Service Discovery failed (err %d)\n", err); + return; + } +} + +static uint8_t discover_control_point_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_gatt_subscribe_params *subscribe_params; + int err; + + if (!attr) { + printk("Discover complete\n"); + (void)memset(params, 0, sizeof(*params)); + return BT_GATT_ITER_STOP; + } + + if (!bt_uuid_cmp(params->uuid, BT_UUID_HAS_PRESET_CONTROL_POINT)) { + printk("HAS Control Point handle at %d\n", attr->handle); + memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = attr->handle + 2; + discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + subscribe_params = &control_point_sub; + subscribe_params->value_handle = bt_gatt_attr_value_handle(attr); + + err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Discover failed (err %d)\n", err); + } + } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) { + printk("CCC handle at %d\n", attr->handle); + subscribe_params = &control_point_sub; + subscribe_params->notify = notify_handler; + subscribe_params->value = BT_GATT_CCC_INDICATE; + subscribe_params->ccc_handle = attr->handle; + subscribe_params->subscribe = subscribe_cb; + + err = bt_gatt_subscribe(conn, subscribe_params); + if (err && err != -EALREADY) { + printk("Subscribe failed (err %d)\n", err); + } + } else { + printk("Unknown handle at %d\n", attr->handle); + return BT_GATT_ITER_CONTINUE; + } + + return BT_GATT_ITER_STOP; +} + +static void discover_and_subscribe_control_point(void) +{ + int err = 0; + + printk("%s\n", __func__); + + memcpy(&uuid, BT_UUID_HAS_PRESET_CONTROL_POINT, sizeof(uuid)); + discover_params.uuid = &uuid.uuid; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discover_params.func = discover_control_point_cb; + + err = bt_gatt_discover(default_conn, &discover_params); + if (err != 0) { + FAIL("Control Point failed (err %d)\n", err); + return; + } +} + +static void test_gatt_client(void) +{ + int err; + + err = bt_enable(NULL); + if (err < 0) { + FAIL("Bluetooth discover failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + bt_le_scan_cb_register(&common_scan_cb); + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + if (err < 0) { + FAIL("Scanning failed to start (err %d)\n", err); + return; + } + + printk("Scanning successfully started\n"); + + WAIT_FOR_FLAG(flag_connected); + + err = bt_conn_set_security(default_conn, BT_SECURITY_L2); + if (err) { + FAIL("Failed to set security level %d (err %d)\n", BT_SECURITY_L2, err); + return; + } + + WAIT_FOR_COND(security_level == BT_SECURITY_L2); + + discover_and_subscribe_features(); + WAIT_FOR_FLAG(flag_features_discovered); + + discover_and_subscribe_active_preset_index(); + WAIT_FOR_FLAG(flag_active_preset_index_discovered); + + discover_and_subscribe_control_point(); + WAIT_FOR_FLAG(flag_control_point_discovered); + + bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + WAIT_FOR_UNSET_FLAG(flag_connected); + + notify_received_mask = 0; + UNSET_FLAG(flag_all_notifications_received); + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + if (err < 0) { + FAIL("Scanning failed to start (err %d)\n", err); + return; + } + + printk("Scanning successfully started\n"); + + WAIT_FOR_FLAG(flag_connected); + + err = bt_conn_set_security(default_conn, BT_SECURITY_L2); + if (err) { + FAIL("Failed to set security level %d (err %d)\n", BT_SECURITY_L2, err); + return; + } + + WAIT_FOR_FLAG(flag_all_notifications_received); + + PASS("HAS main PASS\n"); +} static const struct bst_test_instance test_has[] = { +#ifdef CONFIG_BT_HAS_CLIENT { .test_id = "has_client", .test_post_init_f = test_init, .test_tick_f = test_tick, .test_main_f = test_main, }, +#endif /* CONFIG_BT_HAS_CLIENT */ + { + .test_id = "has_client_offline_behavior", + .test_descr = "Test receiving notifications after reconnection", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_gatt_client, + }, BSTEST_END_MARKER }; @@ -244,10 +692,3 @@ struct bst_test_list *test_has_client_install(struct bst_test_list *tests) { return bst_add_tests(tests, test_has); } -#else -struct bst_test_list *test_has_client_install(struct bst_test_list *tests) -{ - return tests; -} - -#endif /* CONFIG_BT_HAS_CLIENT */ diff --git a/tests/bsim/bluetooth/audio/src/has_test.c b/tests/bsim/bluetooth/audio/src/has_test.c index f8178b61d26..f2b5bdeade9 100644 --- a/tests/bsim/bluetooth/audio/src/has_test.c +++ b/tests/bsim/bluetooth/audio/src/has_test.c @@ -13,8 +13,10 @@ extern enum bst_result_t bst_result; const uint8_t test_preset_index_1 = 0x01; +const uint8_t test_preset_index_3 = 0x03; const uint8_t test_preset_index_5 = 0x05; const char *test_preset_name_1 = "test_preset_name_1"; +const char *test_preset_name_3 = "test_preset_name_3"; const char *test_preset_name_5 = "test_preset_name_5"; const enum bt_has_properties test_preset_properties = BT_HAS_PROP_AVAILABLE; @@ -27,7 +29,7 @@ static const struct bt_has_preset_ops preset_ops = { .select = preset_select, }; -static void test_main(void) +static void test_common(void) { struct bt_has_features_param has_param = {0}; struct bt_has_preset_register_param preset_param; @@ -94,6 +96,55 @@ static void test_main(void) PASS("HAS passed\n"); } +static void test_main(void) +{ + test_common(); + + PASS("HAS passed\n"); +} + +static void test_offline_behavior(void) +{ + struct bt_has_preset_register_param preset_param; + struct bt_has_features_param has_param = {0}; + int err; + + test_common(); + + WAIT_FOR_FLAG(flag_connected); + WAIT_FOR_UNSET_FLAG(flag_connected); + + preset_param.index = test_preset_index_3; + preset_param.properties = test_preset_properties; + preset_param.name = test_preset_name_3; + preset_param.ops = &preset_ops, + + err = bt_has_preset_register(&preset_param); + if (err) { + FAIL("Preset register failed (err %d)\n", err); + return; + } + + has_param.type = BT_HAS_HEARING_AID_TYPE_BINAURAL; + has_param.preset_sync_support = true; + + err = bt_has_features_set(&has_param); + if (err) { + FAIL("Features set failed (err %d)\n", err); + return; + } + + err = bt_has_preset_active_set(test_preset_index_3); + if (err) { + FAIL("Preset activation failed (err %d)\n", err); + return; + } + + WAIT_FOR_FLAG(flag_connected); + + PASS("HAS passed\n"); +} + static const struct bst_test_instance test_has[] = { { .test_id = "has", @@ -101,6 +152,12 @@ static const struct bst_test_instance test_has[] = { .test_tick_f = test_tick, .test_main_f = test_main, }, + { + .test_id = "has_offline_behavior", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_offline_behavior, + }, BSTEST_END_MARKER, }; diff --git a/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh b/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh new file mode 100755 index 00000000000..c05b40adaee --- /dev/null +++ b/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2023 Codecoup +# +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +SIMULATION_ID="has_offline_behavior" +VERBOSITY_LEVEL=2 +EXECUTE_TIMEOUT=20 + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n Running Preset Changed Offline Behavior test \n\n" + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=has_offline_behavior -rs=24 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=has_client_offline_behavior -rs=46 + +Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs From 31e329bb2d32b20733bc14f84d034e01ba802d91 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 11 Aug 2023 14:45:05 +0200 Subject: [PATCH 2122/4498] Bluetooth: audio: has: Defer notifications to sysworkq Defer sending the features, active index, preset list and preset read response to sysworkq and retry sending in case failed due to buffers not available at the moment. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 381 +++++++++++++++++------------------ 1 file changed, 190 insertions(+), 191 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index acbaf13d757..d4dec445af4 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -52,12 +52,8 @@ static void active_preset_index_cfg_changed(const struct bt_gatt_attr *attr, uin #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) struct has_client; -/* Active preset notification work */ -static void active_preset_work_process(struct k_work *work); -static K_WORK_DEFINE(active_preset_work, active_preset_work_process); - -static void process_control_point_work(struct k_work *work); -static void read_presets_req_free(struct has_client *client); +static int read_preset_response(struct has_client *client); +static int list_current_presets(struct has_client *client); static ssize_t write_control_point(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *data, uint16_t len, uint16_t offset, uint8_t flags); @@ -115,8 +111,6 @@ static ssize_t read_features(struct bt_conn *conn, const struct bt_gatt_attr *at read_features, NULL, NULL), #endif /* CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ - - #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) #if defined(CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE) #define BT_HAS_CHR_PRESET_CONTROL_POINT \ @@ -157,28 +151,17 @@ static struct bt_gatt_attr has_attrs[] = { }; static struct bt_gatt_service has_svc; - -#if defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) -/* Features notification work */ -static void features_work_process(struct k_work *work); -static K_WORK_DEFINE(features_work, features_work_process); - -#define FEATURES_ATTR &has_attrs[2] -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) -#define PRESET_CONTROL_POINT_ATTR &has_attrs[5] -#define ACTIVE_PRESET_INDEX_ATTR &has_attrs[8] -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ -#else -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) -#define PRESET_CONTROL_POINT_ATTR &has_attrs[4] -#define ACTIVE_PRESET_INDEX_ATTR &has_attrs[7] -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ -#endif /* CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ +static struct bt_gatt_attr *hearing_aid_features_attr; +static struct bt_gatt_attr *preset_control_point_attr; +static struct bt_gatt_attr *active_preset_index_attr; #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) -enum { +static void notify_work_handler(struct k_work *work); + +enum flag_internal { FLAG_ACTIVE_INDEX_CHANGED, - FLAG_CONTROL_POINT_NOTIFY, + FLAG_PENDING_READ_PRESET_RESPONSE, + FLAG_NOTIFY_PRESET_LIST, FLAG_FEATURES_CHANGED, FLAG_NUM, }; @@ -195,8 +178,8 @@ static struct has_client { uint8_t preset_changed_index_next; struct bt_has_cp_read_presets_req read_presets_req; - struct k_work control_point_work; #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ + struct k_work_delayable notify_work; ATOMIC_DEFINE(flags, FLAG_NUM); } has_client_list[BT_HAS_MAX_CONN]; @@ -219,26 +202,22 @@ static struct has_client *client_get_or_new(struct bt_conn *conn) client->conn = bt_conn_ref(conn); -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) - k_work_init(&client->control_point_work, process_control_point_work); -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) + k_work_init_delayable(&client->notify_work, notify_work_handler); +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ return client; } static void client_free(struct has_client *client) { -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) - (void)k_work_cancel(&client->control_point_work); - read_presets_req_free(client); -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) + (void)k_work_cancel_delayable(&client->notify_work); +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ - atomic_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY); - atomic_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED); - atomic_clear_bit(client->flags, FLAG_FEATURES_CHANGED); + atomic_clear(client->flags); bt_conn_unref(client->conn); - client->conn = NULL; } @@ -273,25 +252,9 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_ return; } -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) - /* Notify after reconnection */ - if (atomic_test_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED)) { - /* Emit active preset notification */ - k_work_submit(&active_preset_work); - } - - if (atomic_test_and_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY)) { - /* Emit preset changed notifications */ - k_work_submit(&client->control_point_work); + if (atomic_get(client->flags) != 0) { + k_work_reschedule(&client->notify_work, K_NO_WAIT); } -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ - -#if defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) - if (atomic_test_bit(client->flags, FLAG_FEATURES_CHANGED)) { - /* Emit features changed notification */ - k_work_submit(&features_work); - } -#endif /* CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ } static void connected(struct bt_conn *conn, uint8_t err) @@ -328,6 +291,94 @@ BT_CONN_CB_DEFINE(conn_cb) = { .disconnected = disconnected, .security_changed = security_changed, }; + +static void notify_work_reschedule(struct has_client *client, enum flag_internal flag, + k_timeout_t delay) +{ + int err; + + atomic_set_bit(client->flags, flag); + + if (client->conn == NULL) { + return; + } + + if (k_work_delayable_remaining_get(&client->notify_work) > 0) { + return; + } + + err = k_work_reschedule(&client->notify_work, delay); + if (err < 0) { + LOG_ERR("Failed to reschedule notification work err %d", err); + } +} + +static void notify_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct has_client *client = CONTAINER_OF(dwork, struct has_client, notify_work); + int err; + + if (IS_ENABLED(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) && + atomic_test_and_clear_bit(client->flags, FLAG_FEATURES_CHANGED) && + bt_gatt_is_subscribed(client->conn, hearing_aid_features_attr, BT_GATT_CCC_NOTIFY)) { + err = bt_gatt_notify(client->conn, hearing_aid_features_attr, &has.features, + sizeof(has.features)); + if (err == -ENOMEM) { + notify_work_reschedule(client, FLAG_FEATURES_CHANGED, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify features err %d", err); + } + } + +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) + if (atomic_test_and_clear_bit(client->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { + err = read_preset_response(client); + if (err == -ENOMEM) { + notify_work_reschedule(client, FLAG_PENDING_READ_PRESET_RESPONSE, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify read preset response err %d", err); + } + } else if (atomic_test_and_clear_bit(client->flags, FLAG_NOTIFY_PRESET_LIST)) { + err = list_current_presets(client); + if (err == -ENOMEM) { + notify_work_reschedule(client, FLAG_NOTIFY_PRESET_LIST, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify generic update all presets err %d", err); + } + } +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ + + if (IS_ENABLED(CONFIG_BT_HAS_PRESET_SUPPORT) && + atomic_test_and_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED) && + bt_gatt_is_subscribed(client->conn, active_preset_index_attr, BT_GATT_CCC_NOTIFY)) { + err = bt_gatt_notify(client->conn, active_preset_index_attr, + &has.active_index, sizeof(has.active_index)); + if (err == -ENOMEM) { + notify_work_reschedule(client, FLAG_ACTIVE_INDEX_CHANGED, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify active index err %d", err); + } + } +} + +static void notify(struct has_client *client, enum flag_internal flag) +{ + if (client != NULL) { + notify_work_reschedule(client, flag, K_NO_WAIT); + return; + } + + for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { + client = &has_client_list[i]; + + notify_work_reschedule(client, flag, K_NO_WAIT); + } +} #endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) @@ -346,16 +397,6 @@ static struct has_preset { /* Number of registered presets */ static uint8_t has_preset_num; -static bool read_presets_req_pending_cp(const struct has_client *client) -{ - return client->read_presets_req.num_presets > 0; -} - -static void read_presets_req_free(struct has_client *client) -{ - client->read_presets_req.num_presets = 0; -} - typedef uint8_t (*preset_func_t)(const struct has_preset *preset, void *user_data); static void preset_foreach(uint8_t start_index, uint8_t end_index, preset_func_t func, @@ -447,10 +488,8 @@ static void control_point_ntf_complete(struct bt_conn *conn, void *user_data) LOG_DBG("conn %p", (void *)conn); /* Resubmit if needed */ - if (client != NULL && - (read_presets_req_pending_cp(client) || - atomic_test_and_clear_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY))) { - k_work_submit(&client->control_point_work); + if (client != NULL && atomic_get(client->flags) != 0) { + k_work_reschedule(&client->notify_work, K_NO_WAIT); } } @@ -470,8 +509,8 @@ static int control_point_send(struct has_client *client, struct net_buf_simple * { #if defined(CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE) if (bt_eatt_count(client->conn) > 0 && - bt_gatt_is_subscribed(client->conn, PRESET_CONTROL_POINT_ATTR, BT_GATT_CCC_NOTIFY)) { - client->params.ntf.attr = PRESET_CONTROL_POINT_ATTR; + bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_NOTIFY)) { + client->params.ntf.attr = preset_control_point_attr; client->params.ntf.func = control_point_ntf_complete; client->params.ntf.data = buf->data; client->params.ntf.len = buf->len; @@ -480,8 +519,8 @@ static int control_point_send(struct has_client *client, struct net_buf_simple * } #endif /* CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE */ - if (bt_gatt_is_subscribed(client->conn, PRESET_CONTROL_POINT_ATTR, BT_GATT_CCC_INDICATE)) { - client->params.ind.attr = PRESET_CONTROL_POINT_ATTR; + if (bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_INDICATE)) { + client->params.ind.attr = preset_control_point_attr; client->params.ind.func = control_point_ind_complete; client->params.ind.destroy = NULL; client->params.ind.data = buf->data; @@ -503,7 +542,7 @@ static int control_point_send_all(struct net_buf_simple *buf) if (!client->conn) { /* Mark preset changed operation as pending */ - atomic_set_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY); + atomic_set_bit(client->flags, FLAG_NOTIFY_PRESET_LIST); /* For simplicity we simply start with the first index, * rather than keeping detailed logs of which clients * have knowledge of which presets @@ -512,7 +551,7 @@ static int control_point_send_all(struct net_buf_simple *buf) continue; } - if (!bt_gatt_is_subscribed(client->conn, PRESET_CONTROL_POINT_ATTR, + if (!bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE)) { continue; } @@ -601,74 +640,72 @@ static int bt_has_cp_generic_update(struct has_client *client, const struct has_ } } -static void process_control_point_work(struct k_work *work) +static int read_preset_response(struct has_client *client) { - struct has_client *client = CONTAINER_OF(work, struct has_client, control_point_work); + const struct has_preset *preset = NULL; + bool is_last = true; int err; - if (!client->conn) { - return; - } + __ASSERT_NO_MSG(client != NULL); - if (read_presets_req_pending_cp(client)) { - const struct has_preset *preset = NULL; - bool is_last = true; + preset_foreach(client->read_presets_req.start_index, BT_HAS_PRESET_INDEX_LAST, + preset_found, &preset); - preset_foreach(client->read_presets_req.start_index, BT_HAS_PRESET_INDEX_LAST, - preset_found, &preset); + if (unlikely(preset == NULL)) { + return bt_has_cp_read_preset_rsp(client, NULL, BT_HAS_IS_LAST); + } - if (unlikely(preset == NULL)) { - (void)bt_has_cp_read_preset_rsp(client, NULL, 0x01); + if (client->read_presets_req.num_presets > 1) { + const struct has_preset *next = NULL; - return; - } + preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, preset_found, &next); - if (client->read_presets_req.num_presets > 1) { - const struct has_preset *next = NULL; + is_last = next == NULL; - preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, - preset_found, &next); + } - is_last = next == NULL; + err = bt_has_cp_read_preset_rsp(client, preset, is_last); + if (err != 0 || is_last) { + return err; + } - } + client->read_presets_req.start_index = preset->index + 1; + client->read_presets_req.num_presets--; - err = bt_has_cp_read_preset_rsp(client, preset, is_last); - if (err) { - LOG_ERR("bt_has_cp_read_preset_rsp failed (err %d)", err); - } + notify_work_reschedule(client, FLAG_PENDING_READ_PRESET_RESPONSE, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); - if (err || is_last) { - read_presets_req_free(client); - } else { - client->read_presets_req.start_index = preset->index + 1; - client->read_presets_req.num_presets--; - } - } else { - const struct has_preset *preset = NULL; - const struct has_preset *next = NULL; - bool is_last = true; + return 0; +} + +static int list_current_presets(struct has_client *client) +{ + const struct has_preset *preset = NULL; + const struct has_preset *next = NULL; + bool is_last = true; + int err; - preset_foreach(client->preset_changed_index_next, - BT_HAS_PRESET_INDEX_LAST, preset_found, &preset); + preset_foreach(client->preset_changed_index_next, BT_HAS_PRESET_INDEX_LAST, preset_found, + &preset); - if (preset == NULL) { - return; - } + if (preset == NULL) { + return 0; + } - preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, - preset_found, &next); + preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, preset_found, &next); - is_last = next == NULL; + is_last = next == NULL; - err = bt_has_cp_generic_update(client, preset, is_last); - if (err) { - LOG_ERR("bt_has_cp_read_preset_rsp failed (err %d)", err); - } else if (!is_last) { - client->preset_changed_index_next = preset->index + 1; - atomic_set_bit(client->flags, FLAG_CONTROL_POINT_NOTIFY); - } + err = bt_has_cp_generic_update(client, preset, is_last); + if (err != 0 || is_last) { + return err; } + client->preset_changed_index_next = preset->index + 1; + + notify_work_reschedule(client, FLAG_NOTIFY_PRESET_LIST, + K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + + return 0; } static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simple *buf) @@ -685,7 +722,7 @@ static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simpl * shall be returned if client writes Read Presets Request but is not registered for * indications. */ - if (!bt_gatt_is_subscribed(conn, PRESET_CONTROL_POINT_ATTR, BT_GATT_CCC_INDICATE)) { + if (!bt_gatt_is_subscribed(conn, preset_control_point_attr, BT_GATT_CCC_INDICATE)) { return BT_ATT_ERR_CCC_IMPROPER_CONF; } @@ -706,7 +743,7 @@ static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simpl } /* Reject if already in progress */ - if (read_presets_req_pending_cp(client)) { + if (atomic_test_bit(client->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { return BT_HAS_ERR_OPERATION_NOT_POSSIBLE; } @@ -714,7 +751,7 @@ static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simpl client->read_presets_req.start_index = req->start_index; client->read_presets_req.num_presets = req->num_presets; - k_work_submit(&client->control_point_work); + notify(client, FLAG_PENDING_READ_PRESET_RESPONSE); return 0; } @@ -773,7 +810,7 @@ static uint8_t handle_write_preset_name(struct bt_conn *conn, struct net_buf_sim * shall be returned if client writes Write Preset Name opcode but is not registered for * indications. */ - if (!bt_gatt_is_subscribed(conn, PRESET_CONTROL_POINT_ATTR, BT_GATT_CCC_INDICATE)) { + if (!bt_gatt_is_subscribed(conn, preset_control_point_attr, BT_GATT_CCC_INDICATE)) { return BT_ATT_ERR_CCC_IMPROPER_CONF; } @@ -798,42 +835,12 @@ static uint8_t handle_write_preset_name(struct bt_conn *conn, struct net_buf_sim return BT_ATT_ERR_SUCCESS; } -static void active_preset_work_process(struct k_work *work) -{ - const uint8_t active_index = bt_has_preset_active_get(); - - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; - int err; - - if (client->conn == NULL) { - /* mark to notify on reconnect */ - atomic_set_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED); - continue; - } else if (atomic_test_and_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED)) { - err = bt_gatt_notify(client->conn, ACTIVE_PRESET_INDEX_ATTR, &active_index, - sizeof(active_index)); - if (err != 0) { - LOG_DBG("failed to notify active_index for %p: %d", client->conn, - err); - } - } - } -} - static void preset_active_set(uint8_t index) { if (index != has.active_index) { has.active_index = index; - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; - /* mark to notify */ - atomic_set_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED); - } - - /* Emit active preset notification */ - k_work_submit(&active_preset_work); + notify(NULL, FLAG_ACTIVE_INDEX_CHANGED); } } @@ -861,6 +868,11 @@ static uint8_t preset_select(const struct has_preset *preset, bool sync) return 0; } +static bool is_preset_available(const struct has_preset *preset) +{ + return (preset->properties & BT_HAS_PROP_AVAILABLE) != 0; +} + static uint8_t handle_set_active_preset(struct net_buf_simple *buf, bool sync) { const struct bt_has_cp_set_active_preset *pdu; @@ -1269,26 +1281,6 @@ static int has_features_register(const struct bt_has_features_param *features) } #if defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) -static void features_work_process(struct k_work *work) -{ - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; - int err; - - if (client->conn == NULL) { - /* mark to notify on reconnect */ - atomic_set_bit(client->flags, FLAG_FEATURES_CHANGED); - continue; - } else if (atomic_test_and_clear_bit(client->flags, FLAG_FEATURES_CHANGED)) { - err = bt_gatt_notify(client->conn, FEATURES_ATTR, &has.features, - sizeof(has.features)); - if (err != 0) { - LOG_DBG("failed to notify features for %p: %d", client->conn, err); - } - } - } -} - int bt_has_features_set(const struct bt_has_features_param *features) { int err; @@ -1310,16 +1302,7 @@ int bt_has_features_set(const struct bt_has_features_param *features) return err; } - for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; - - atomic_set_bit(client->flags, FLAG_FEATURES_CHANGED); - } - - err = k_work_submit(&features_work); - if (err < 0) { - LOG_ERR("Failed to reschedule features notification err %d", err); - } + notify(NULL, FLAG_FEATURES_CHANGED); return 0; } @@ -1353,6 +1336,22 @@ int bt_has_register(const struct bt_has_features_param *features) return err; } + if (IS_ENABLED(CONFIG_BT_HAS_FEATURES_NOTIFIABLE)) { + hearing_aid_features_attr = bt_gatt_find_by_uuid(has_svc.attrs, has_svc.attr_count, + BT_UUID_HAS_HEARING_AID_FEATURES); + __ASSERT_NO_MSG(hearing_aid_features_attr != NULL); + } + + if (IS_ENABLED(CONFIG_BT_HAS_PRESET_SUPPORT)) { + preset_control_point_attr = bt_gatt_find_by_uuid(has_svc.attrs, has_svc.attr_count, + BT_UUID_HAS_PRESET_CONTROL_POINT); + __ASSERT_NO_MSG(preset_control_point_attr != NULL); + + active_preset_index_attr = bt_gatt_find_by_uuid(has_svc.attrs, has_svc.attr_count, + BT_UUID_HAS_ACTIVE_PRESET_INDEX); + __ASSERT_NO_MSG(active_preset_index_attr != NULL); + } + has.registered = true; return 0; From 9c6419c6156a4367e159ce6a8bc5c39b077b4279 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 31 Aug 2023 12:53:50 +0200 Subject: [PATCH 2123/4498] Bluetooth: audio: has: Refactor preset list to single-linked list This refactors the preset list to use sys_slist API. There have been various issues seen while iterating presets, thus it's more save to use well-defined and tested sys_slist API. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 331 +++++++++++++++++++++-------------- 1 file changed, 195 insertions(+), 136 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index d4dec445af4..45a72db11d6 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "../bluetooth/host/conn_internal.h" #include "../bluetooth/host/hci_core.h" @@ -65,14 +66,17 @@ static void preset_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t valu static ssize_t read_active_preset_index(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { + uint8_t active_index; + LOG_DBG("conn %p attr %p offset %d", (void *)conn, attr, offset); - if (offset > sizeof(has.active_index)) { + if (offset > sizeof(active_index)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); } - return bt_gatt_attr_read(conn, attr, buf, len, offset, &has.active_index, - sizeof(has.active_index)); + active_index = bt_has_preset_active_get(); + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &active_index, sizeof(active_index)); } #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ @@ -355,8 +359,12 @@ static void notify_work_handler(struct k_work *work) if (IS_ENABLED(CONFIG_BT_HAS_PRESET_SUPPORT) && atomic_test_and_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED) && bt_gatt_is_subscribed(client->conn, active_preset_index_attr, BT_GATT_CCC_NOTIFY)) { + uint8_t active_index; + + active_index = bt_has_preset_active_get(); + err = bt_gatt_notify(client->conn, active_preset_index_attr, - &has.active_index, sizeof(has.active_index)); + &active_index, sizeof(active_index)); if (err == -ENOMEM) { notify_work_reschedule(client, FLAG_ACTIVE_INDEX_CHANGED, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); @@ -382,6 +390,8 @@ static void notify(struct has_client *client, enum flag_internal flag) #endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) +static struct has_preset *active_preset; + /* HAS internal preset representation */ static struct has_preset { uint8_t index; @@ -392,19 +402,20 @@ static struct has_preset { const char *name; #endif /* CONFIG_BT_HAS_PRESET_NAME_DYNAMIC */ const struct bt_has_preset_ops *ops; -} has_preset_list[CONFIG_BT_HAS_PRESET_COUNT]; + sys_snode_t node; +} preset_pool[CONFIG_BT_HAS_PRESET_COUNT]; -/* Number of registered presets */ -static uint8_t has_preset_num; +static sys_slist_t preset_list = SYS_SLIST_STATIC_INIT(&preset_list); +static sys_slist_t preset_free_list = SYS_SLIST_STATIC_INIT(&preset_free_list); typedef uint8_t (*preset_func_t)(const struct has_preset *preset, void *user_data); static void preset_foreach(uint8_t start_index, uint8_t end_index, preset_func_t func, void *user_data) { - for (size_t i = 0; i < ARRAY_SIZE(has_preset_list); i++) { - const struct has_preset *preset = &has_preset_list[i]; + struct has_preset *preset, *tmp; + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&preset_list, preset, tmp, node) { if (preset->index < start_index) { continue; } @@ -428,57 +439,132 @@ static uint8_t preset_found(const struct has_preset *preset, void *user_data) return BT_HAS_PRESET_ITER_STOP; } -static int preset_index_compare(const void *p1, const void *p2) +static void preset_insert(struct has_preset *preset) { - const struct has_preset *preset_1 = p1; - const struct has_preset *preset_2 = p2; - - if (preset_1->index == BT_HAS_PRESET_INDEX_NONE) { - return 1; - } + struct has_preset *tmp, *prev = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&preset_list, tmp, node) { + if (tmp->index > preset->index) { + if (prev) { + sys_slist_insert(&preset_list, &prev->node, &preset->node); + } else { + sys_slist_prepend(&preset_list, &preset->node); + } + return; + } - if (preset_2->index == BT_HAS_PRESET_INDEX_NONE) { - return -1; + prev = tmp; } - return preset_1->index - preset_2->index; + sys_slist_append(&preset_list, &preset->node); } static struct has_preset *preset_alloc(uint8_t index, enum bt_has_properties properties, const char *name, const struct bt_has_preset_ops *ops) { - struct has_preset *preset = NULL; + struct has_preset *preset; + sys_snode_t *node; - if (has_preset_num < ARRAY_SIZE(has_preset_list)) { - preset = &has_preset_list[has_preset_num]; - preset->index = index; - preset->properties = properties; + node = sys_slist_get(&preset_free_list); + if (node == NULL) { + return NULL; + } + + preset = CONTAINER_OF(node, struct has_preset, node); + preset->index = index; + preset->properties = properties; #if defined(CONFIG_BT_HAS_PRESET_NAME_DYNAMIC) - utf8_lcpy(preset->name, name, ARRAY_SIZE(preset->name)); + utf8_lcpy(preset->name, name, ARRAY_SIZE(preset->name)); #else - preset->name = name; + preset->name = name; #endif /* CONFIG_BT_HAS_PRESET_NAME_DYNAMIC */ - preset->ops = ops; - - has_preset_num++; + preset->ops = ops; - /* sort the presets in index ascending order */ - qsort(has_preset_list, has_preset_num, sizeof(*preset), preset_index_compare); - } + preset_insert(preset); return preset; } static void preset_free(struct has_preset *preset) { - preset->index = BT_HAS_PRESET_INDEX_NONE; + bool removed; - /* sort the presets in index ascending order */ - if (has_preset_num > 1) { - qsort(has_preset_list, has_preset_num, sizeof(*preset), preset_index_compare); + removed = sys_slist_find_and_remove(&preset_list, &preset->node); + if (removed) { + sys_slist_append(&preset_free_list, &preset->node); } +} + +static struct has_preset *preset_get_head(void) +{ + struct has_preset *next; + + return SYS_SLIST_PEEK_HEAD_CONTAINER(&preset_list, next, node); +} + +static struct has_preset *preset_get_tail(void) +{ + struct has_preset *prev; - has_preset_num--; + return SYS_SLIST_PEEK_TAIL_CONTAINER(&preset_list, prev, node); +} + +static struct has_preset *preset_get_prev(const struct has_preset *preset) +{ + struct has_preset *prev; + + SYS_SLIST_FOR_EACH_CONTAINER(&preset_list, prev, node) { + if (SYS_SLIST_PEEK_NEXT_CONTAINER(prev, node) == preset) { + return prev; + } + } + + prev = preset_get_tail(); + if (prev == preset) { + return NULL; + } + + return prev; +} + +static struct has_preset *preset_lookup_index(uint8_t index) +{ + struct has_preset *preset; + + SYS_SLIST_FOR_EACH_CONTAINER(&preset_list, preset, node) { + if (preset->index == index) { + return preset; + } + } + + return NULL; +} + +static struct has_preset *preset_get_next(struct has_preset *preset) +{ + struct has_preset *next; + + next = SYS_SLIST_PEEK_NEXT_CONTAINER(preset, node); + if (next == NULL) { + next = preset_get_head(); + if (next == preset) { + return NULL; + } + } + + return next; +} + +static uint8_t preset_get_prev_index(const struct has_preset *preset) +{ + const struct has_preset *prev; + + prev = preset_get_prev(preset); + if (prev == NULL || prev->index >= preset->index) { + return BT_HAS_PRESET_INDEX_NONE; + } + + return prev->index; } static void control_point_ntf_complete(struct bt_conn *conn, void *user_data) @@ -587,23 +673,6 @@ static int bt_has_cp_read_preset_rsp(struct has_client *client, const struct has return control_point_send(client, &buf); } -static uint8_t get_prev_preset_index(const struct has_preset *preset) -{ - const struct has_preset *prev = NULL; - - for (size_t i = 0; i < ARRAY_SIZE(has_preset_list); i++) { - const struct has_preset *tmp = &has_preset_list[i]; - - if (tmp->index == BT_HAS_PRESET_INDEX_NONE || tmp == preset) { - break; - } - - prev = tmp; - } - - return prev ? prev->index : BT_HAS_PRESET_INDEX_NONE; -} - static void preset_changed_prepare(struct net_buf_simple *buf, uint8_t change_id, uint8_t is_last) { struct bt_has_cp_hdr *hdr; @@ -628,7 +697,7 @@ static int bt_has_cp_generic_update(struct has_client *client, const struct has_ preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_GENERIC_UPDATE, is_last); generic_update = net_buf_simple_add(&buf, sizeof(*generic_update)); - generic_update->prev_index = get_prev_preset_index(preset); + generic_update->prev_index = preset_get_prev_index(preset); generic_update->index = preset->index; generic_update->properties = preset->properties; net_buf_simple_add_mem(&buf, preset->name, strlen(preset->name)); @@ -661,7 +730,6 @@ static int read_preset_response(struct has_client *client) preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, preset_found, &next); is_last = next == NULL; - } err = bt_has_cp_read_preset_rsp(client, preset, is_last); @@ -835,16 +903,16 @@ static uint8_t handle_write_preset_name(struct bt_conn *conn, struct net_buf_sim return BT_ATT_ERR_SUCCESS; } -static void preset_active_set(uint8_t index) +static void preset_set_active(struct has_preset *preset) { - if (index != has.active_index) { - has.active_index = index; + if (active_preset != preset) { + active_preset = preset; notify(NULL, FLAG_ACTIVE_INDEX_CHANGED); } } -static uint8_t preset_select(const struct has_preset *preset, bool sync) +static uint8_t preset_select(struct has_preset *preset, bool sync) { const int err = preset->ops->select(preset->index, sync); @@ -863,7 +931,7 @@ static uint8_t preset_select(const struct has_preset *preset, bool sync) return BT_ATT_ERR_UNLIKELY; } - preset_active_set(preset->index); + preset_set_active(preset); return 0; } @@ -876,7 +944,7 @@ static bool is_preset_available(const struct has_preset *preset) static uint8_t handle_set_active_preset(struct net_buf_simple *buf, bool sync) { const struct bt_has_cp_set_active_preset *pdu; - const struct has_preset *preset = NULL; + struct has_preset *preset; if (buf->len < sizeof(*pdu)) { return BT_HAS_ERR_INVALID_PARAM_LEN; @@ -884,12 +952,12 @@ static uint8_t handle_set_active_preset(struct net_buf_simple *buf, bool sync) pdu = net_buf_simple_pull_mem(buf, sizeof(*pdu)); - preset_foreach(pdu->index, pdu->index, preset_found, &preset); + preset = preset_lookup_index(pdu->index); if (preset == NULL) { return BT_ATT_ERR_OUT_OF_RANGE; } - if (!(preset->properties & BT_HAS_PROP_AVAILABLE)) { + if (!is_preset_available(preset)) { return BT_HAS_ERR_OPERATION_NOT_POSSIBLE; } @@ -898,80 +966,52 @@ static uint8_t handle_set_active_preset(struct net_buf_simple *buf, bool sync) static uint8_t handle_set_next_preset(bool sync) { - const struct has_preset *next_avail = NULL; - const struct has_preset *first_avail = NULL; + struct has_preset *next, *tmp; - for (size_t i = 0; i < has_preset_num; i++) { - const struct has_preset *tmp = &has_preset_list[i]; + if (active_preset == NULL) { + next = preset_get_head(); + } else { + next = preset_get_next(active_preset); + } - if (tmp->index == BT_HAS_PRESET_INDEX_NONE) { + tmp = next; + do { + if (next == NULL) { break; } - if (!(tmp->properties & BT_HAS_PROP_AVAILABLE)) { - continue; + if (is_preset_available(next)) { + return preset_select(next, sync); } - if (tmp->index < has.active_index && !first_avail) { - first_avail = tmp; - continue; - } - - if (tmp->index > has.active_index) { - next_avail = tmp; - break; - } - } - - if (next_avail) { - return preset_select(next_avail, sync); - } - - if (first_avail) { - return preset_select(first_avail, sync); - } + next = preset_get_next(next); + } while (tmp != next); return BT_HAS_ERR_OPERATION_NOT_POSSIBLE; } static uint8_t handle_set_prev_preset(bool sync) { - const struct has_preset *prev_available = NULL; - const struct has_preset *last_available = NULL; - - for (size_t i = 0; i < ARRAY_SIZE(has_preset_list); i++) { - const struct has_preset *tmp = &has_preset_list[i]; - - if (tmp->index == BT_HAS_PRESET_INDEX_NONE) { - break; - } + struct has_preset *prev, *tmp; - if (!(tmp->properties & BT_HAS_PROP_AVAILABLE)) { - continue; - } - - if (tmp->index < has.active_index) { - prev_available = tmp; - continue; - } + if (active_preset == NULL) { + prev = preset_get_tail(); + } else { + prev = preset_get_prev(active_preset); + } - if (prev_available) { + tmp = prev; + do { + if (prev == NULL) { break; } - if (tmp->index > has.active_index) { - last_available = tmp; - continue; + if (is_preset_available(prev)) { + return preset_select(prev, sync); } - } - if (prev_available) { - return preset_select(prev_available, sync); - } - - if (last_available) { - return preset_select(last_available, sync); - } + prev = preset_get_prev(prev); + } while (tmp != prev); return BT_HAS_ERR_OPERATION_NOT_POSSIBLE; } @@ -1052,7 +1092,7 @@ static ssize_t write_control_point(struct bt_conn *conn, const struct bt_gatt_at int bt_has_preset_register(const struct bt_has_preset_register_param *param) { - struct has_preset *preset = NULL; + struct has_preset *preset; size_t name_len; CHECKIF(param == NULL) { @@ -1091,7 +1131,7 @@ int bt_has_preset_register(const struct bt_has_preset_register_param *param) return -EINVAL; } - preset_foreach(param->index, param->index, preset_found, &preset); + preset = preset_lookup_index(param->index); if (preset != NULL) { return -EALREADY; } @@ -1106,7 +1146,7 @@ int bt_has_preset_register(const struct bt_has_preset_register_param *param) int bt_has_preset_unregister(uint8_t index) { - struct has_preset *preset = NULL; + struct has_preset *preset; NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); @@ -1116,11 +1156,15 @@ int bt_has_preset_unregister(uint8_t index) return -EINVAL; } - preset_foreach(index, index, preset_found, &preset); + preset = preset_lookup_index(index); if (preset == NULL) { return -ENOENT; } + if (preset == active_preset) { + return -EADDRINUSE; + } + preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_PRESET_DELETED, BT_HAS_IS_LAST); net_buf_simple_add_u8(&buf, preset->index); @@ -1133,7 +1177,7 @@ static int set_preset_availability(uint8_t index, bool available) { NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); - struct has_preset *preset = NULL; + struct has_preset *preset; uint8_t change_id; CHECKIF(index == BT_HAS_PRESET_INDEX_NONE) { @@ -1141,12 +1185,12 @@ static int set_preset_availability(uint8_t index, bool available) return -EINVAL; } - preset_foreach(index, index, preset_found, &preset); + preset = preset_lookup_index(index); if (preset == NULL) { return -ENOENT; } - if ((preset->properties & BT_HAS_PROP_AVAILABLE) == available) { + if (is_preset_available(preset) == available) { /* availability not changed */ return 0; } @@ -1207,27 +1251,34 @@ void bt_has_preset_foreach(uint8_t index, bt_has_preset_func_t func, void *user_ int bt_has_preset_active_set(uint8_t index) { - if (index != BT_HAS_PRESET_INDEX_NONE) { - struct has_preset *preset = NULL; + struct has_preset *preset; - preset_foreach(index, index, preset_found, &preset); - if (preset == NULL) { - return -ENOENT; - } + if (index == BT_HAS_PRESET_INDEX_NONE) { + preset_set_active(NULL); + return 0; + } - if (!(preset->properties & BT_HAS_PROP_AVAILABLE)) { - return -EINVAL; - } + preset = preset_lookup_index(index); + if (preset == NULL) { + return -ENOENT; + } + + if (!is_preset_available(preset)) { + return -EINVAL; } - preset_active_set(index); + preset_set_active(preset); return 0; } uint8_t bt_has_preset_active_get(void) { - return has.active_index; + if (active_preset == NULL) { + return BT_HAS_PRESET_INDEX_NONE; + } + + return active_preset->index; } int bt_has_preset_name_change(uint8_t index, const char *name) @@ -1352,6 +1403,14 @@ int bt_has_register(const struct bt_has_features_param *features) __ASSERT_NO_MSG(active_preset_index_attr != NULL); } +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) + for (size_t i = 0; i < ARRAY_SIZE(preset_pool); i++) { + struct has_preset *preset = &preset_pool[i]; + + sys_slist_append(&preset_free_list, &preset->node); + } +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ + has.registered = true; return 0; From a7406aa8f417b1fd404ed81506439c4f29299681 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 11 Oct 2023 09:18:48 +0200 Subject: [PATCH 2124/4498] Bluetooth: has: Factor out bonded client persistent data Some of the data shall be persistent across connections to bonded clients. This includes notidication state flags that are used to determine whether notify bonded client after reconnection. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 311 ++++++++++++++++++++++++----------- 1 file changed, 213 insertions(+), 98 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index 45a72db11d6..e7d9be838c8 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -4,11 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include - -#include #include #include @@ -23,15 +19,16 @@ #include "audio_internal.h" #include "has_internal.h" +#include "common/bt_str.h" + #include LOG_MODULE_REGISTER(bt_has, CONFIG_BT_HAS_LOG_LEVEL); /* The service allows operations with paired devices only. - * For now, the context is kept for connected devices only, thus the number of contexts is - * equal to maximum number of simultaneous connections to paired devices. + * The number of clients is set to maximum number of simultaneous connections to paired devices. */ -#define BT_HAS_MAX_CONN MIN(CONFIG_BT_MAX_CONN, CONFIG_BT_MAX_PAIRED) +#define MAX_INSTS MIN(CONFIG_BT_MAX_CONN, CONFIG_BT_MAX_PAIRED) #define BITS_CHANGED(_new_value, _old_value) ((_new_value) ^ (_old_value)) #define FEATURE_DEVICE_TYPE_UNCHANGED(_new_value) \ @@ -40,6 +37,8 @@ LOG_MODULE_REGISTER(bt_has, CONFIG_BT_HAS_LOG_LEVEL); !BITS_CHANGED(_new_value, ((has.features & BT_HAS_FEAT_PRESET_SYNC_SUPP) != 0 ? 1 : 0)) #define FEATURE_IND_PRESETS_UNCHANGED(_new_value) \ !BITS_CHANGED(_new_value, ((has.features & BT_HAS_FEAT_INDEPENDENT_PRESETS) != 0 ? 1 : 0)) +#define BONDED_CLIENT_INIT_FLAGS \ + (BIT(FLAG_ACTIVE_INDEX_CHANGED) | BIT(FLAG_NOTIFY_PRESET_LIST) | BIT(FLAG_FEATURES_CHANGED)) static struct bt_has has; @@ -170,6 +169,15 @@ enum flag_internal { FLAG_NUM, }; +/* Stored client context */ +static struct client_context { + bt_addr_le_t addr; + + /* Pending notification flags */ + ATOMIC_DEFINE(flags, FLAG_NUM); +} contexts[CONFIG_BT_MAX_PAIRED]; + +/* Connected client clientance */ static struct has_client { struct bt_conn *conn; #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) @@ -184,11 +192,68 @@ static struct has_client { struct bt_has_cp_read_presets_req read_presets_req; #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ struct k_work_delayable notify_work; - ATOMIC_DEFINE(flags, FLAG_NUM); -} has_client_list[BT_HAS_MAX_CONN]; + struct client_context *context; +} has_client_list[MAX_INSTS]; + + +static struct client_context *context_find(const bt_addr_le_t *addr) +{ + for (size_t i = 0; i < ARRAY_SIZE(contexts); i++) { + if (bt_addr_le_eq(&contexts[i].addr, addr)) { + return &contexts[i]; + } + } + + return NULL; +} + +static struct client_context *context_alloc(const bt_addr_le_t *addr) +{ + struct client_context *context; + + /* Free contexts has BT_ADDR_LE_ANY as the address */ + context = context_find(BT_ADDR_LE_ANY); + if (context == NULL) { + return NULL; + } + + memset(context, 0, sizeof(*context)); + + bt_addr_le_copy(&context->addr, addr); + + return context; +} + +static void context_free(struct client_context *context) +{ + bt_addr_le_copy(&context->addr, BT_ADDR_LE_ANY); +} + +static void client_free(struct has_client *client) +{ + struct bt_conn_info info = { 0 }; + int err; + +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) + (void)k_work_cancel_delayable(&client->notify_work); +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ + + err = bt_conn_get_info(client->conn, &info); + __ASSERT_NO_MSG(err == 0); -static struct has_client *client_get_or_new(struct bt_conn *conn) + if (client->context != NULL && !bt_addr_le_is_bonded(info.id, info.le.dst)) { + /* Free stored context of non-bonded client */ + context_free(client->context); + client->context = NULL; + } + + bt_conn_unref(client->conn); + client->conn = NULL; +} + +static struct has_client *client_alloc(struct bt_conn *conn) { + struct bt_conn_info info = { 0 }; struct has_client *client = NULL; for (size_t i = 0; i < ARRAY_SIZE(has_client_list); i++) { @@ -197,35 +262,44 @@ static struct has_client *client_get_or_new(struct bt_conn *conn) } /* first free slot */ - if (!client && !has_client_list[i].conn) { + if (!client && has_client_list[i].conn == NULL) { client = &has_client_list[i]; } } __ASSERT(client, "failed to get client for conn %p", (void *)conn); + memset(client, 0, sizeof(*client)); + client->conn = bt_conn_ref(conn); #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) k_work_init_delayable(&client->notify_work, notify_work_handler); #endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ - return client; -} + bt_conn_get_info(conn, &info); -static void client_free(struct has_client *client) -{ -#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) - (void)k_work_cancel_delayable(&client->notify_work); -#endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ + client->context = context_find(info.le.dst); + if (client->context == NULL) { + client->context = context_alloc(info.le.dst); + if (client->context == NULL) { + LOG_ERR("Failed to allocate client_context for %s", + bt_addr_le_str(info.le.dst)); - atomic_clear(client->flags); + client_free(client); - bt_conn_unref(client->conn); - client->conn = NULL; + return NULL; + } + + LOG_DBG("New client_context for %s", bt_addr_le_str(info.le.dst)); + } else { + LOG_DBG("Restored client_context for %s", bt_addr_le_str(info.le.dst)); + } + + return client; } -static struct has_client *client_get(struct bt_conn *conn) +static struct has_client *client_find_by_conn(struct bt_conn *conn) { for (size_t i = 0; i < ARRAY_SIZE(has_client_list); i++) { if (conn == has_client_list[i].conn) { @@ -236,46 +310,45 @@ static struct has_client *client_get(struct bt_conn *conn) return NULL; } -static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +static void notify_work_reschedule(struct has_client *client, k_timeout_t delay) { - struct has_client *client; - - LOG_DBG("conn %p level %d err %d", (void *)conn, level, err); - - if (err != BT_SECURITY_ERR_SUCCESS) { - return; - } + int err; - client = client_get_or_new(conn); - if (unlikely(!client)) { - LOG_ERR("Failed to allocate client"); - return; - } + __ASSERT(client->conn, "Not connected"); - if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { + if (k_work_delayable_remaining_get(&client->notify_work) > 0) { return; } - if (atomic_get(client->flags) != 0) { - k_work_reschedule(&client->notify_work, K_NO_WAIT); + err = k_work_reschedule(&client->notify_work, delay); + if (err < 0) { + LOG_ERR("Failed to reschedule notification work err %d", err); } } -static void connected(struct bt_conn *conn, uint8_t err) +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { struct has_client *client; - LOG_DBG("conn %p err %d", conn, err); + LOG_DBG("conn %p level %d err %d", (void *)conn, level, err); - if (err != 0 || !bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { + if (err != BT_SECURITY_ERR_SUCCESS) { return; } - client = client_get_or_new(conn); + client = client_alloc(conn); if (unlikely(!client)) { LOG_ERR("Failed to allocate client"); return; } + + if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { + return; + } + + if (atomic_get(client->context->flags) != 0) { + notify_work_reschedule(client, K_NO_WAIT); + } } static void disconnected(struct bt_conn *conn, uint8_t reason) @@ -284,39 +357,33 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) LOG_DBG("conn %p reason %d", (void *)conn, reason); - client = client_get(conn); + client = client_find_by_conn(conn); if (client) { client_free(client); } } -BT_CONN_CB_DEFINE(conn_cb) = { - .connected = connected, - .disconnected = disconnected, - .security_changed = security_changed, -}; - -static void notify_work_reschedule(struct has_client *client, enum flag_internal flag, - k_timeout_t delay) +static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa, + const bt_addr_le_t *identity) { - int err; + struct has_client *client; - atomic_set_bit(client->flags, flag); + LOG_DBG("conn %p %s -> %s", (void *)conn, bt_addr_le_str(rpa), bt_addr_le_str(identity)); - if (client->conn == NULL) { + client = client_find_by_conn(conn); + if (client == NULL) { return; } - if (k_work_delayable_remaining_get(&client->notify_work) > 0) { - return; - } - - err = k_work_reschedule(&client->notify_work, delay); - if (err < 0) { - LOG_ERR("Failed to reschedule notification work err %d", err); - } + bt_addr_le_copy(&client->context->addr, identity); } +BT_CONN_CB_DEFINE(conn_cb) = { + .disconnected = disconnected, + .security_changed = security_changed, + .identity_resolved = identity_resolved, +}; + static void notify_work_handler(struct k_work *work) { struct k_work_delayable *dwork = k_work_delayable_from_work(work); @@ -324,32 +391,32 @@ static void notify_work_handler(struct k_work *work) int err; if (IS_ENABLED(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) && - atomic_test_and_clear_bit(client->flags, FLAG_FEATURES_CHANGED) && + atomic_test_and_clear_bit(client->context->flags, FLAG_FEATURES_CHANGED) && bt_gatt_is_subscribed(client->conn, hearing_aid_features_attr, BT_GATT_CCC_NOTIFY)) { err = bt_gatt_notify(client->conn, hearing_aid_features_attr, &has.features, sizeof(has.features)); if (err == -ENOMEM) { - notify_work_reschedule(client, FLAG_FEATURES_CHANGED, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_FEATURES_CHANGED); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); } else if (err < 0) { LOG_ERR("Notify features err %d", err); } } #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) - if (atomic_test_and_clear_bit(client->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { + if (atomic_test_and_clear_bit(client->context->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { err = read_preset_response(client); if (err == -ENOMEM) { - notify_work_reschedule(client, FLAG_PENDING_READ_PRESET_RESPONSE, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_PENDING_READ_PRESET_RESPONSE); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); } else if (err < 0) { LOG_ERR("Notify read preset response err %d", err); } - } else if (atomic_test_and_clear_bit(client->flags, FLAG_NOTIFY_PRESET_LIST)) { + } else if (atomic_test_and_clear_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST)) { err = list_current_presets(client); if (err == -ENOMEM) { - notify_work_reschedule(client, FLAG_NOTIFY_PRESET_LIST, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); } else if (err < 0) { LOG_ERR("Notify generic update all presets err %d", err); } @@ -357,7 +424,7 @@ static void notify_work_handler(struct k_work *work) #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ if (IS_ENABLED(CONFIG_BT_HAS_PRESET_SUPPORT) && - atomic_test_and_clear_bit(client->flags, FLAG_ACTIVE_INDEX_CHANGED) && + atomic_test_and_clear_bit(client->context->flags, FLAG_ACTIVE_INDEX_CHANGED) && bt_gatt_is_subscribed(client->conn, active_preset_index_attr, BT_GATT_CCC_NOTIFY)) { uint8_t active_index; @@ -366,8 +433,8 @@ static void notify_work_handler(struct k_work *work) err = bt_gatt_notify(client->conn, active_preset_index_attr, &active_index, sizeof(active_index)); if (err == -ENOMEM) { - notify_work_reschedule(client, FLAG_ACTIVE_INDEX_CHANGED, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_ACTIVE_INDEX_CHANGED); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); } else if (err < 0) { LOG_ERR("Notify active index err %d", err); } @@ -377,16 +444,55 @@ static void notify_work_handler(struct k_work *work) static void notify(struct has_client *client, enum flag_internal flag) { if (client != NULL) { - notify_work_reschedule(client, flag, K_NO_WAIT); + atomic_set_bit(client->context->flags, flag); + notify_work_reschedule(client, K_NO_WAIT); return; } + /* Mark notification to be sent to all clients */ + for (size_t i = 0U; i < ARRAY_SIZE(contexts); i++) { + atomic_set_bit(contexts[i].flags, flag); + } + for (size_t i = 0U; i < ARRAY_SIZE(has_client_list); i++) { client = &has_client_list[i]; - notify_work_reschedule(client, flag, K_NO_WAIT); + if (client->conn == NULL) { + continue; + } + + notify_work_reschedule(client, K_NO_WAIT); + } +} + +static void bond_deleted_cb(uint8_t id, const bt_addr_le_t *addr) +{ + struct client_context *context; + + context = context_find(addr); + if (context != NULL) { + context_free(context); + } +} + +static struct bt_conn_auth_info_cb auth_info_cb = { + .bond_deleted = bond_deleted_cb, +}; + +static void restore_client_context(const struct bt_bond_info *info, void *user_data) +{ + struct client_context *context; + + context = context_alloc(&info->addr); + if (context == NULL) { + LOG_ERR("Failed to allocate client_context for %s", bt_addr_le_str(&info->addr)); + return; } + + /* Notify all the characteristics values after reboot */ + atomic_set(context->flags, BONDED_CLIENT_INIT_FLAGS); } + #endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) @@ -569,13 +675,13 @@ static uint8_t preset_get_prev_index(const struct has_preset *preset) static void control_point_ntf_complete(struct bt_conn *conn, void *user_data) { - struct has_client *client = client_get(conn); + struct has_client *client = client_find_by_conn(conn); LOG_DBG("conn %p", (void *)conn); /* Resubmit if needed */ - if (client != NULL && atomic_get(client->flags) != 0) { - k_work_reschedule(&client->notify_work, K_NO_WAIT); + if (client != NULL && atomic_get(client->context->flags) != 0) { + notify_work_reschedule(client, K_NO_WAIT); } } @@ -622,18 +728,21 @@ static int control_point_send_all(struct net_buf_simple *buf) { int result = 0; - for (size_t i = 0; i < ARRAY_SIZE(has_client_list); i++) { - struct has_client *client = &has_client_list[i]; + for (size_t i = 0U; i < ARRAY_SIZE(contexts); i++) { + struct client_context *context = &contexts[i]; + struct has_client *client = NULL; int err; - if (!client->conn) { + for (size_t j = 0U; j < ARRAY_SIZE(has_client_list); j++) { + if (has_client_list[j].context == context) { + client = &has_client_list[j]; + break; + } + } + + if (client == NULL || client->conn == NULL) { /* Mark preset changed operation as pending */ - atomic_set_bit(client->flags, FLAG_NOTIFY_PRESET_LIST); - /* For simplicity we simply start with the first index, - * rather than keeping detailed logs of which clients - * have knowledge of which presets - */ - client->preset_changed_index_next = BT_HAS_PRESET_INDEX_FIRST; + atomic_set_bit(context->flags, FLAG_NOTIFY_PRESET_LIST); continue; } @@ -740,8 +849,8 @@ static int read_preset_response(struct has_client *client) client->read_presets_req.start_index = preset->index + 1; client->read_presets_req.num_presets--; - notify_work_reschedule(client, FLAG_PENDING_READ_PRESET_RESPONSE, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_PENDING_READ_PRESET_RESPONSE); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); return 0; } @@ -753,8 +862,8 @@ static int list_current_presets(struct has_client *client) bool is_last = true; int err; - preset_foreach(client->preset_changed_index_next, BT_HAS_PRESET_INDEX_LAST, preset_found, - &preset); + preset_foreach(client->preset_changed_index_next, BT_HAS_PRESET_INDEX_LAST, + preset_found, &preset); if (preset == NULL) { return 0; @@ -770,8 +879,8 @@ static int list_current_presets(struct has_client *client) } client->preset_changed_index_next = preset->index + 1; - notify_work_reschedule(client, FLAG_NOTIFY_PRESET_LIST, - K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + atomic_set_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); return 0; } @@ -794,8 +903,8 @@ static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simpl return BT_ATT_ERR_CCC_IMPROPER_CONF; } - client = client_get(conn); - if (!client) { + client = client_find_by_conn(conn); + if (client == NULL) { return BT_ATT_ERR_UNLIKELY; } @@ -811,7 +920,7 @@ static uint8_t handle_read_preset_req(struct bt_conn *conn, struct net_buf_simpl } /* Reject if already in progress */ - if (atomic_test_bit(client->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { + if (atomic_test_bit(client->context->flags, FLAG_PENDING_READ_PRESET_RESPONSE)) { return BT_HAS_ERR_OPERATION_NOT_POSSIBLE; } @@ -882,7 +991,7 @@ static uint8_t handle_write_preset_name(struct bt_conn *conn, struct net_buf_sim return BT_ATT_ERR_CCC_IMPROPER_CONF; } - client = client_get(conn); + client = client_find_by_conn(conn); if (!client) { return BT_ATT_ERR_UNLIKELY; } @@ -1411,6 +1520,12 @@ int bt_has_register(const struct bt_has_features_param *features) } #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ +#if defined(CONFIG_BT_HAS_PRESET_SUPPORT) || defined(CONFIG_BT_HAS_FEATURES_NOTIFIABLE) + bt_conn_auth_info_cb_register(&auth_info_cb); + + bt_foreach_bond(BT_ID_DEFAULT, restore_client_context, NULL); +#endif /* CONFIG_BT_HAS_PRESET_SUPPORT || CONFIG_BT_HAS_FEATURES_NOTIFIABLE */ + has.registered = true; return 0; From 4d023023a303ff31edc23cf7eb5da370c38d847f Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 12 Oct 2023 17:22:53 +0200 Subject: [PATCH 2125/4498] Bluetooth: has: Fix preset list notifications after reconnection This fixes sending proper Preset List notifications after reconnection. The issue was observed when the last preset known to the client has been removed. As we do not hold the information about the deleted presets, we need to use Generic Update procedure to: 1. Notify the presets that have been removed in range (PrevIndex = current_preset_last, Index=previous_preset_last) 2. Notify deletion of preset Index=previous_preset_last. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 222 ++++++++++++++++++++++++++++++----- 1 file changed, 195 insertions(+), 27 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index e7d9be838c8..b66793b5f2c 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -53,7 +53,9 @@ static void active_preset_index_cfg_changed(const struct bt_gatt_attr *attr, uin struct has_client; static int read_preset_response(struct has_client *client); -static int list_current_presets(struct has_client *client); +static int preset_list_changed(struct has_client *client); +static int preset_list_changed_generic_update_tail(struct has_client *client); +static int preset_list_changed_record_deleted_last(struct has_client *client); static ssize_t write_control_point(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *data, uint16_t len, uint16_t offset, uint8_t flags); @@ -165,6 +167,8 @@ enum flag_internal { FLAG_ACTIVE_INDEX_CHANGED, FLAG_PENDING_READ_PRESET_RESPONSE, FLAG_NOTIFY_PRESET_LIST, + FLAG_NOTIFY_PRESET_LIST_GENERIC_UPDATE_TAIL, + FLAG_NOTIFY_PRESET_LIST_RECORD_DELETED_LAST, FLAG_FEATURES_CHANGED, FLAG_NUM, }; @@ -175,6 +179,9 @@ static struct client_context { /* Pending notification flags */ ATOMIC_DEFINE(flags, FLAG_NUM); + + /* Last notified preset index */ + uint8_t last_preset_index_known; } contexts[CONFIG_BT_MAX_PAIRED]; /* Connected client clientance */ @@ -413,14 +420,35 @@ static void notify_work_handler(struct k_work *work) LOG_ERR("Notify read preset response err %d", err); } } else if (atomic_test_and_clear_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST)) { - err = list_current_presets(client); + err = preset_list_changed(client); if (err == -ENOMEM) { atomic_set_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST); notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); } else if (err < 0) { - LOG_ERR("Notify generic update all presets err %d", err); + LOG_ERR("Notify preset list changed err %d", err); + } + } else if (atomic_test_and_clear_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_GENERIC_UPDATE_TAIL)) { + err = preset_list_changed_generic_update_tail(client); + if (err == -ENOMEM) { + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_GENERIC_UPDATE_TAIL); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify preset list changed generic update tail err %d", err); + } + } else if (atomic_test_and_clear_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_RECORD_DELETED_LAST)) { + err = preset_list_changed_record_deleted_last(client); + if (err == -ENOMEM) { + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_RECORD_DELETED_LAST); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } else if (err < 0) { + LOG_ERR("Notify preset list changed recoed deleted last err %d", err); } } + #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ if (IS_ENABLED(CONFIG_BT_HAS_PRESET_SUPPORT) && @@ -794,8 +822,8 @@ static void preset_changed_prepare(struct net_buf_simple *buf, uint8_t change_id preset_changed->is_last = is_last; } -static int bt_has_cp_generic_update(struct has_client *client, const struct has_preset *preset, - uint8_t is_last) +static int bt_has_cp_generic_update(struct has_client *client, uint8_t prev_index, uint8_t index, + uint8_t properties, const char *name, uint8_t is_last) { struct bt_has_cp_generic_update *generic_update; @@ -803,13 +831,16 @@ static int bt_has_cp_generic_update(struct has_client *client, const struct has_ sizeof(struct bt_has_cp_preset_changed) + sizeof(struct bt_has_cp_generic_update) + BT_HAS_PRESET_NAME_MAX); + LOG_DBG("client %p prev_index 0x%02x index 0x%02x prop 0x%02x %s is_last %d", + client, prev_index, index, properties, name, is_last); + preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_GENERIC_UPDATE, is_last); generic_update = net_buf_simple_add(&buf, sizeof(*generic_update)); - generic_update->prev_index = preset_get_prev_index(preset); - generic_update->index = preset->index; - generic_update->properties = preset->properties; - net_buf_simple_add_mem(&buf, preset->name, strlen(preset->name)); + generic_update->prev_index = prev_index; + generic_update->index = index; + generic_update->properties = properties; + net_buf_simple_add_mem(&buf, name, strlen(name)); if (client) { return control_point_send(client, &buf); @@ -818,6 +849,23 @@ static int bt_has_cp_generic_update(struct has_client *client, const struct has_ } } +static void update_last_preset_index_known(struct has_client *client, uint8_t index) +{ + if (client != NULL) { + client->context->last_preset_index_known = index; + return; + } + + for (size_t i = 0; i < ARRAY_SIZE(has_client_list); i++) { + client = &has_client_list[i]; + + /* For each connected client */ + if (client->conn != NULL && client->context != NULL) { + client->context->last_preset_index_known = index; + } + } +} + static int read_preset_response(struct has_client *client) { const struct has_preset *preset = NULL; @@ -842,26 +890,107 @@ static int read_preset_response(struct has_client *client) } err = bt_has_cp_read_preset_rsp(client, preset, is_last); - if (err != 0 || is_last) { + if (err != 0) { return err; } - client->read_presets_req.start_index = preset->index + 1; - client->read_presets_req.num_presets--; + if (preset->index > client->context->last_preset_index_known) { + update_last_preset_index_known(client, preset->index); + } + + if (!is_last) { + client->read_presets_req.start_index = preset->index + 1; + client->read_presets_req.num_presets--; atomic_set_bit(client->context->flags, FLAG_PENDING_READ_PRESET_RESPONSE); - notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + } + + return 0; +} + +static int bt_has_cp_preset_record_deleted(struct has_client *client, uint8_t index) +{ + NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + + sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); + + preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_PRESET_DELETED, BT_HAS_IS_LAST); + net_buf_simple_add_u8(&buf, index); + + if (client != NULL) { + return control_point_send(client, &buf); + } else { + return control_point_send_all(&buf); + } +} + +/* Generic Update the last (already deleted) preset */ +static int preset_list_changed_generic_update_tail(struct has_client *client) +{ + const struct has_preset *prev; + struct has_preset last = { + /* The index value of the last preset the client knew about. */ + .index = client->context->last_preset_index_known, + + /* As the properties of deleted preset is not available anymore, we set this value + * to 0x00 meaning the preset is unavailable and non-writable which is actually true + */ + .properties = BT_HAS_PROP_NONE, + + /* As the name of deleted preset are not available anymore, we set this value + * to the value what is compliant with specification. + * As per HAS_v1.0 the Name is 1-40 octet value. + */ + .name = "N/A", + }; + int err; + + prev = preset_get_tail(); + + err = bt_has_cp_generic_update(client, prev ? prev->index : BT_HAS_PRESET_INDEX_NONE, + last.index, last.properties, last.name, false); + if (err != 0) { + return err; + } + + return 0; +} + +static int preset_list_changed_record_deleted_last(struct has_client *client) +{ + const struct has_preset *last; + int err; + + err = bt_has_cp_preset_record_deleted(client, client->context->last_preset_index_known); + if (err != 0) { + return err; + } + + last = preset_get_tail(); + + update_last_preset_index_known(client, last ? last->index : BT_HAS_PRESET_INDEX_NONE); return 0; } -static int list_current_presets(struct has_client *client) +static int preset_list_changed(struct has_client *client) { const struct has_preset *preset = NULL; const struct has_preset *next = NULL; bool is_last = true; int err; + if (sys_slist_is_empty(&preset_list)) { + /* The preset list is empty. We need to indicate deletion of all presets */ + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_GENERIC_UPDATE_TAIL); + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_RECORD_DELETED_LAST); + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); + + return 0; + } + preset_foreach(client->preset_changed_index_next, BT_HAS_PRESET_INDEX_LAST, preset_found, &preset); @@ -871,15 +1000,44 @@ static int list_current_presets(struct has_client *client) preset_foreach(preset->index + 1, BT_HAS_PRESET_INDEX_LAST, preset_found, &next); - is_last = next == NULL; + /* It is last Preset Changed notification if there are no presets left to notify and the + * currently notified preset have the highest index known to the client. + */ + is_last = next == NULL && preset->index >= client->context->last_preset_index_known; - err = bt_has_cp_generic_update(client, preset, is_last); - if (err != 0 || is_last) { + err = bt_has_cp_generic_update(client, preset_get_prev_index(preset), preset->index, + preset->properties, preset->name, is_last); + if (err != 0) { return err; } - client->preset_changed_index_next = preset->index + 1; - atomic_set_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST); + if (is_last) { + client->preset_changed_index_next = 0; + + /* It's the last preset notified, so update the highest index known to the client */ + update_last_preset_index_known(client, preset->index); + + return 0; + } + + if (next == NULL) { + /* If we end up here, the last preset known to the client has been removed. + * As we do not hold the information about the deleted presets, we need to use + * Generic Update procedure to: + * 1. Notify the presets that have been removed in range + * (PrevIndex = current_preset_last, Index=previous_preset_last) + * 2. Notify deletion of preset Index=previous_preset_last. + */ + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_GENERIC_UPDATE_TAIL); + atomic_set_bit(client->context->flags, + FLAG_NOTIFY_PRESET_LIST_RECORD_DELETED_LAST); + } else { + client->preset_changed_index_next = preset->index + 1; + + atomic_set_bit(client->context->flags, FLAG_NOTIFY_PRESET_LIST); + } + notify_work_reschedule(client, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); return 0; @@ -970,7 +1128,8 @@ static int set_preset_name(uint8_t index, const char *name, size_t len) preset->ops->name_changed(index, preset->name); } - return bt_has_cp_generic_update(NULL, preset, BT_HAS_IS_LAST); + return bt_has_cp_generic_update(NULL, preset_get_prev_index(preset), preset->index, + preset->properties, preset->name, BT_HAS_IS_LAST); } static uint8_t handle_write_preset_name(struct bt_conn *conn, struct net_buf_simple *buf) @@ -1250,15 +1409,18 @@ int bt_has_preset_register(const struct bt_has_preset_register_param *param) return -ENOMEM; } - return bt_has_cp_generic_update(NULL, preset, BT_HAS_IS_LAST); + if (preset == preset_get_tail()) { + update_last_preset_index_known(NULL, preset->index); + } + + return bt_has_cp_generic_update(NULL, preset_get_prev_index(preset), preset->index, + preset->properties, preset->name, BT_HAS_IS_LAST); } int bt_has_preset_unregister(uint8_t index) { struct has_preset *preset; - - NET_BUF_SIMPLE_DEFINE(buf, sizeof(struct bt_has_cp_hdr) + - sizeof(struct bt_has_cp_preset_changed) + sizeof(uint8_t)); + int err; CHECKIF(index == BT_HAS_PRESET_INDEX_NONE) { LOG_ERR("index is invalid"); @@ -1274,12 +1436,18 @@ int bt_has_preset_unregister(uint8_t index) return -EADDRINUSE; } - preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_PRESET_DELETED, BT_HAS_IS_LAST); - net_buf_simple_add_u8(&buf, preset->index); + err = bt_has_cp_preset_record_deleted(NULL, preset->index); + if (err != 0) { + return err; + } + + if (preset == preset_get_tail()) { + update_last_preset_index_known(NULL, preset_get_prev_index(preset)); + } preset_free(preset); - return control_point_send_all(&buf); + return 0; } static int set_preset_availability(uint8_t index, bool available) From b0e7a1b0ac18c198be95fd9a190a3cef24b37c4b Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 16 Oct 2023 15:20:49 +0200 Subject: [PATCH 2126/4498] Bluetooth: audio: has: Fix missing memset of parameters This fixes missing memset of parameters used for indications and/or notifications. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index b66793b5f2c..ceb273c5248 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -730,6 +730,7 @@ static int control_point_send(struct has_client *client, struct net_buf_simple * #if defined(CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE) if (bt_eatt_count(client->conn) > 0 && bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_NOTIFY)) { + memset(&client->params.ntf, 0, sizeof(client->params.ntf)); client->params.ntf.attr = preset_control_point_attr; client->params.ntf.func = control_point_ntf_complete; client->params.ntf.data = buf->data; @@ -740,6 +741,7 @@ static int control_point_send(struct has_client *client, struct net_buf_simple * #endif /* CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE */ if (bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_INDICATE)) { + memset(&client->params.ind, 0, sizeof(client->params.ind)); client->params.ind.attr = preset_control_point_attr; client->params.ind.func = control_point_ind_complete; client->params.ind.destroy = NULL; From df1fd21892fe7620a38d694caec82d417e4e3d2e Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 19 Oct 2023 10:53:54 +0200 Subject: [PATCH 2127/4498] Bluetooth: audio: has: Truncate Control Point notifications to ATT MTU This will truncate ATT notifications/indications if exceed ATT MTU size. It is up to the client to exchange MTU. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index ceb273c5248..eca2761e43f 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -727,6 +727,15 @@ static void control_point_ind_complete(struct bt_conn *conn, static int control_point_send(struct has_client *client, struct net_buf_simple *buf) { + const uint16_t mtu_size = bt_gatt_get_mtu(client->conn); + /* PDU structure is [Opcode (1)] [Handle (2)] [...] */ + const uint16_t pdu_size = 3 + buf->len; + + if (mtu_size < pdu_size) { + LOG_WRN("Sending truncated control point PDU %d < %d", mtu_size, pdu_size); + buf->len -= (pdu_size - mtu_size); + } + #if defined(CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE) if (bt_eatt_count(client->conn) > 0 && bt_gatt_is_subscribed(client->conn, preset_control_point_attr, BT_GATT_CCC_NOTIFY)) { From 27049744b97289b1a9ee98ff312b9bbe49c493e3 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 19 Oct 2023 10:58:20 +0200 Subject: [PATCH 2128/4498] Bluetooth: audio: has: Remove include of conn_internal header This makes use of bt_conn_get_info function to access the conn address. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index eca2761e43f..07635f1e00d 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -14,7 +14,6 @@ #include #include -#include "../bluetooth/host/conn_internal.h" #include "../bluetooth/host/hci_core.h" #include "audio_internal.h" #include "has_internal.h" @@ -336,6 +335,8 @@ static void notify_work_reschedule(struct has_client *client, k_timeout_t delay) static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { struct has_client *client; + struct bt_conn_info info; + int ret; LOG_DBG("conn %p level %d err %d", (void *)conn, level, err); @@ -349,7 +350,13 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_ return; } - if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { + ret = bt_conn_get_info(client->conn, &info); + if (ret < 0) { + LOG_ERR("bt_conn_get_info err %d", ret); + return; + } + + if (!bt_addr_le_is_bonded(info.id, info.le.dst)) { return; } From 49e70303637375fdb66cf13239d051abf97d8fff Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 19 Oct 2023 11:01:50 +0200 Subject: [PATCH 2129/4498] Bluetooth: audio: has: Minor logging improvement This adds more logs for debugging purposes. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/audio/has.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index 07635f1e00d..fc1aba7aec2 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -815,7 +815,8 @@ static int bt_has_cp_read_preset_rsp(struct has_client *client, const struct has NET_BUF_SIMPLE_DEFINE(buf, sizeof(*hdr) + sizeof(*rsp) + BT_HAS_PRESET_NAME_MAX); - LOG_DBG("conn %p preset %p is_last 0x%02x", (void *)client->conn, preset, is_last); + LOG_DBG("conn %p index 0x%02x prop 0x%02x %s is_last 0x%02x", (void *)client->conn, + preset->index, preset->properties, preset->name, is_last); hdr = net_buf_simple_add(&buf, sizeof(*hdr)); hdr->opcode = BT_HAS_OP_READ_PRESET_RSP; @@ -1369,7 +1370,7 @@ static ssize_t write_control_point(struct bt_conn *conn, const struct bt_gatt_at err = handle_control_point_op(conn, &buf); if (err) { - LOG_WRN("err 0x%02x", err); + LOG_WRN("handle_control_point_op err 0x%02x", err); return BT_GATT_ERR(err); } From b14d235c31e5e79c857e0e46a1a632f35e2ca77e Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Wed, 6 Sep 2023 16:11:20 +0800 Subject: [PATCH 2130/4498] Bluetooth: Mesh: Remove bits for adv tag since tag for buf single only, no need for bit, also for save some memory for rfu. Signed-off-by: Lingao Meng --- subsys/bluetooth/mesh/adv.c | 14 +++++------ subsys/bluetooth/mesh/adv.h | 17 +++++++++---- subsys/bluetooth/mesh/adv_ext.c | 42 +++++++++++++++---------------- subsys/bluetooth/mesh/statistic.c | 12 ++++----- 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index 2132c14e151..e67d96414e7 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -138,7 +138,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) - if (tag & BT_MESH_RELAY_ADV) { + if (tag == BT_MESH_RELAY_ADV) { return bt_mesh_adv_create_from_pool(&relay_buf_pool, adv_relay_pool, type, tag, xmit, timeout); @@ -146,7 +146,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - if (tag & BT_MESH_FRIEND_ADV) { + if (tag == BT_MESH_FRIEND_ADV) { return bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_friend_pool, type, tag, xmit, timeout); @@ -202,14 +202,14 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return process_events(events, ARRAY_SIZE(events)); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tag & BT_MESH_FRIEND_ADV) { + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tags & BT_MESH_FRIEND_ADV_BIT) { return net_buf_get(&bt_mesh_friend_queue, timeout); } #if CONFIG_BT_MESH_RELAY_ADV_SETS - if (tag & BT_MESH_RELAY_ADV) { + if (tags & BT_MESH_RELAY_ADV_BIT) { return net_buf_get(&bt_mesh_relay_queue, timeout); } #endif @@ -222,9 +222,9 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return net_buf_get(&bt_mesh_adv_queue, timeout); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { - ARG_UNUSED(tag); + ARG_UNUSED(tags); return bt_mesh_adv_buf_get(timeout); } diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 3d0acf8a7ac..22a8e0645e1 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -26,10 +26,17 @@ enum bt_mesh_adv_type { }; enum bt_mesh_adv_tag { - BT_MESH_LOCAL_ADV = BIT(0), - BT_MESH_RELAY_ADV = BIT(1), - BT_MESH_PROXY_ADV = BIT(2), - BT_MESH_FRIEND_ADV = BIT(3), + BT_MESH_LOCAL_ADV, + BT_MESH_RELAY_ADV, + BT_MESH_PROXY_ADV, + BT_MESH_FRIEND_ADV, +}; + +enum bt_mesh_adv_tags { + BT_MESH_LOCAL_ADV_BIT = BIT(BT_MESH_LOCAL_ADV), + BT_MESH_RELAY_ADV_BIT = BIT(BT_MESH_RELAY_ADV), + BT_MESH_PROXY_ADV_BIT = BIT(BT_MESH_PROXY_ADV), + BT_MESH_FRIEND_ADV_BIT = BIT(BT_MESH_FRIEND_ADV), }; struct bt_mesh_adv { @@ -57,7 +64,7 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); -struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout); +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 88c631a5867..9dbbea31fb5 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -57,7 +57,7 @@ enum { }; struct bt_mesh_ext_adv { - uint8_t tag; + enum bt_mesh_adv_tags tags; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; struct net_buf *buf; @@ -70,17 +70,17 @@ static void send_pending_adv(struct k_work *work); static bool schedule_send(struct bt_mesh_ext_adv *adv); static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { - .tag = ( + .tags = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_FRIEND_ADV | + BT_MESH_FRIEND_ADV_BIT | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_PROXY_ADV | + BT_MESH_PROXY_ADV_BIT | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_RELAY_ADV | + BT_MESH_RELAY_ADV_BIT | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ - BT_MESH_LOCAL_ADV), + BT_MESH_LOCAL_ADV_BIT), .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; @@ -88,7 +88,7 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { #if CONFIG_BT_MESH_RELAY_ADV_SETS static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_RELAY_ADV_SETS) = { [0 ... CONFIG_BT_MESH_RELAY_ADV_SETS - 1] = { - .tag = BT_MESH_RELAY_ADV, + .tags = BT_MESH_RELAY_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), } }; @@ -97,7 +97,7 @@ static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) #define ADV_EXT_FRIEND 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { - .tag = BT_MESH_FRIEND_ADV, + .tags = BT_MESH_FRIEND_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ @@ -107,7 +107,7 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) #define ADV_EXT_GATT 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { - .tag = BT_MESH_PROXY_ADV, + .tags = BT_MESH_PROXY_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ @@ -234,18 +234,18 @@ static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) return err; } -static const char *adv_tag_to_str(enum bt_mesh_adv_tag tag) +static const char *adv_tag_to_str(enum bt_mesh_adv_tags tags) { - if (tag & BT_MESH_LOCAL_ADV) { + if (tags & BT_MESH_LOCAL_ADV_BIT) { return "local adv"; - } else if (tag & BT_MESH_PROXY_ADV) { + } else if (tags & BT_MESH_PROXY_ADV_BIT) { return "proxy adv"; - } else if (tag & BT_MESH_RELAY_ADV) { + } else if (tags & BT_MESH_RELAY_ADV_BIT) { return "relay adv"; - } else if (tag & BT_MESH_FRIEND_ADV) { + } else if (tags & BT_MESH_FRIEND_ADV_BIT) { return "friend adv"; } else { - return "(unknown tag)"; + return "(unknown tags)"; } } @@ -264,8 +264,8 @@ static void send_pending_adv(struct k_work *work) */ int64_t duration = k_uptime_delta(&adv->timestamp); - LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tag, - adv_tag_to_str(adv->tag)); + LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tags, + adv_tag_to_str(adv->tags)); atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); @@ -283,7 +283,7 @@ static void send_pending_adv(struct k_work *work) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED); - while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tag, K_NO_WAIT))) { + while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tags, K_NO_WAIT))) { /* busy == 0 means this was canceled */ if (!BT_MESH_ADV(buf)->busy) { net_buf_unref(buf); @@ -301,7 +301,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tag & BT_MESH_PROXY_ADV)) { + !(adv->tags & BT_MESH_RELAY_ADV_BIT)) { return; } @@ -344,8 +344,8 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); - if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tag & BT_MESH_FRIEND_ADV) || - (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tag == BT_MESH_RELAY_ADV)) { + if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tags & BT_MESH_FRIEND_ADV_BIT) || + (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_RELAY_ADV_BIT)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 5b1ffe7e0f5..046fa3c0eeb 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -24,22 +24,22 @@ void bt_mesh_stat_reset(void) void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) { - if (adv->tag & BT_MESH_LOCAL_ADV) { + if (adv->tag == BT_MESH_LOCAL_ADV) { stat.tx_local_planned++; - } else if (adv->tag & BT_MESH_RELAY_ADV) { + } else if (adv->tag == BT_MESH_RELAY_ADV) { stat.tx_adv_relay_planned++; - } else if (adv->tag & BT_MESH_FRIEND_ADV) { + } else if (adv->tag == BT_MESH_FRIEND_ADV) { stat.tx_friend_planned++; } } void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) { - if (adv->tag & BT_MESH_LOCAL_ADV) { + if (adv->tag == BT_MESH_LOCAL_ADV) { stat.tx_local_succeeded++; - } else if (adv->tag & BT_MESH_RELAY_ADV) { + } else if (adv->tag == BT_MESH_RELAY_ADV) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag & BT_MESH_FRIEND_ADV) { + } else if (adv->tag == BT_MESH_FRIEND_ADV) { stat.tx_friend_succeeded++; } } From 141467a2611bde904cacc7d3f6b89ac282c617ac Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Wed, 6 Sep 2023 16:47:20 +0800 Subject: [PATCH 2131/4498] Bluetooth: Mesh: Rename adv relay to adv simultaneous Since notice that simultaneous advertising is not only used by relay message, provision over pb-adv can also be used. so it was changed to a more general name. refs:https://github.com/zephyrproject-rtos/zephyr/pull/48903 Signed-off-by: Lingao Meng --- subsys/bluetooth/mesh/Kconfig | 40 +++++-- subsys/bluetooth/mesh/adv.c | 44 +++---- subsys/bluetooth/mesh/adv.h | 22 ++-- subsys/bluetooth/mesh/adv_ext.c | 109 ++++++++++++------ subsys/bluetooth/mesh/adv_legacy.c | 8 +- subsys/bluetooth/mesh/beacon.c | 6 +- subsys/bluetooth/mesh/friend.c | 2 +- subsys/bluetooth/mesh/net.c | 2 +- subsys/bluetooth/mesh/pb_adv.c | 19 ++- subsys/bluetooth/mesh/statistic.c | 12 +- subsys/bluetooth/mesh/transport.c | 4 +- subsys/bluetooth/mesh/transport_legacy.c | 4 +- tests/bluetooth/mesh/basic/multi_ext_adv.conf | 2 +- .../bsim/bluetooth/mesh/src/test_advertiser.c | 18 +-- 14 files changed, 185 insertions(+), 107 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 7527a1beb16..f9d4d3bcf98 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -103,22 +103,22 @@ menuconfig BT_MESH_ADV_EXT if BT_MESH_ADV_EXT -config BT_MESH_RELAY_ADV_SETS - int "Maximum of simultaneous relay message support" +config BT_MESH_SIMULT_ADV_SETS + int "Maximum number of parallel advertising sets that can be used by the Bluetooth Mesh stack" default 0 range 0 BT_EXT_ADV_MAX_ADV_SET - depends on BT_MESH_RELAY + depends on BT_MESH_RELAY || BT_MESH_PB_ADV help - Maximum of simultaneous relay message support. Requires controller support + Maximum of simultaneous message support. Requires controller support multiple advertising sets. config BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET bool "Use the main advertising set to relay messages" - depends on BT_MESH_RELAY_ADV_SETS > 0 + depends on BT_MESH_SIMULT_ADV_SETS > 0 help When this option is enabled, there is a message that needs to be relayed, all relay advertising sets defined by - CONFIG_BT_MESH_RELAY_ADV_SETS are busy with relaying messages + CONFIG_BT_MESH_SIMULT_ADV_SETS are busy with relaying messages and the main advertising set is not busy with sending local messages, the stack will use the main advertising set to relay the message. This maximizes the utilization efficiency of @@ -199,6 +199,32 @@ config BT_MESH_PB_ADV_RETRANS_TIMEOUT help Timeout value of retransmit provisioning PDUs. +config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT + int "Link Open and Transaction PDU retransmit count" + default 7 if BT_MESH_SIMULT_ADV_SETS > 0 + default 0 + range 0 7 + help + Controls the number of retransmissions of original Link Open and Transaction PDU, + in addition to the first transmission. + +config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT + int "Link Ack and Transaction Ack retransmit count" + default 2 + range 0 7 + help + Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, + in addition to the first transmission. + +config BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT + int "Link Close retransmit count" + default 7 if BT_MESH_SIMULT_ADV_SETS > 0 + default 2 + range 0 7 + help + Controls the number of retransmissions of original Link Close, + in addition to the first transmission. + endif # BT_MESH_PB_ADV if BT_CONN @@ -375,7 +401,7 @@ config BT_MESH_RELAY_BUF_COUNT of packet drops. When considering the message latency, also consider the values of BT_MESH_RELAY_RETRANSMIT_COUNT and BT_MESH_RELAY_RETRANSMIT_INTERVAL. A higher number of - BT_MESH_RELAY_ADV_SETS allows the increase in the number of buffers + BT_MESH_SIMULT_ADV_SETS allows the increase in the number of buffers while maintaining the latency. endif # BT_MESH_RELAY diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index e67d96414e7..c7abcd53d70 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -44,7 +44,7 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { static bool active_scanning; static K_FIFO_DEFINE(bt_mesh_adv_queue); -static K_FIFO_DEFINE(bt_mesh_relay_queue); +static K_FIFO_DEFINE(bt_mesh_simult_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) @@ -138,7 +138,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) - if (tag == BT_MESH_RELAY_ADV) { + if (tag == BT_MESH_ADV_TAG_RELAY) { return bt_mesh_adv_create_from_pool(&relay_buf_pool, adv_relay_pool, type, tag, xmit, timeout); @@ -146,7 +146,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - if (tag == BT_MESH_FRIEND_ADV) { + if (tag == BT_MESH_ADV_TAG_FRIEND) { return bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_friend_pool, type, tag, xmit, timeout); @@ -157,7 +157,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, tag, xmit, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE +#if CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE static struct net_buf *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { @@ -189,7 +189,7 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &bt_mesh_relay_queue, + &bt_mesh_simult_queue, 0), #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ }; @@ -204,19 +204,20 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tags & BT_MESH_FRIEND_ADV_BIT) { + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && + tags & BT_MESH_ADV_TAG_FRIEND_BIT) { return net_buf_get(&bt_mesh_friend_queue, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS - if (tags & BT_MESH_RELAY_ADV_BIT) { - return net_buf_get(&bt_mesh_relay_queue, timeout); + if (tags & BT_MESH_ADV_TAG_LOCAL_BIT) { + return bt_mesh_adv_buf_get(timeout); } -#endif - return bt_mesh_adv_buf_get(timeout); +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + return net_buf_get(&bt_mesh_simult_queue, timeout); +#endif } -#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ +#else /* !(CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) { return net_buf_get(&bt_mesh_adv_queue, timeout); @@ -228,7 +229,7 @@ struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout return bt_mesh_adv_buf_get(timeout); } -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ void bt_mesh_adv_buf_get_cancel(void) { @@ -236,9 +237,9 @@ void bt_mesh_adv_buf_get_cancel(void) k_fifo_cancel_wait(&bt_mesh_adv_queue); -#if CONFIG_BT_MESH_RELAY_ADV_SETS - k_fifo_cancel_wait(&bt_mesh_relay_queue); -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + k_fifo_cancel_wait(&bt_mesh_simult_queue); +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { k_fifo_cancel_wait(&bt_mesh_friend_queue); @@ -260,16 +261,17 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, } if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - BT_MESH_ADV(buf)->tag == BT_MESH_FRIEND_ADV) { + BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_FRIEND) { net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf)); bt_mesh_adv_buf_friend_ready(); return; } -#if CONFIG_BT_MESH_RELAY_ADV_SETS - if (BT_MESH_ADV(buf)->tag == BT_MESH_RELAY_ADV) { - net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_relay_ready(); +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + if (BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY || + BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV) { + net_buf_put(&bt_mesh_simult_queue, net_buf_ref(buf)); + bt_mesh_adv_buf_simult_ready(); return; } #endif diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 22a8e0645e1..50c5b47604c 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -26,17 +26,19 @@ enum bt_mesh_adv_type { }; enum bt_mesh_adv_tag { - BT_MESH_LOCAL_ADV, - BT_MESH_RELAY_ADV, - BT_MESH_PROXY_ADV, - BT_MESH_FRIEND_ADV, + BT_MESH_ADV_TAG_LOCAL, + BT_MESH_ADV_TAG_RELAY, + BT_MESH_ADV_TAG_PROXY, + BT_MESH_ADV_TAG_FRIEND, + BT_MESH_ADV_TAG_PROV, }; enum bt_mesh_adv_tags { - BT_MESH_LOCAL_ADV_BIT = BIT(BT_MESH_LOCAL_ADV), - BT_MESH_RELAY_ADV_BIT = BIT(BT_MESH_RELAY_ADV), - BT_MESH_PROXY_ADV_BIT = BIT(BT_MESH_PROXY_ADV), - BT_MESH_FRIEND_ADV_BIT = BIT(BT_MESH_FRIEND_ADV), + BT_MESH_ADV_TAG_LOCAL_BIT = BIT(BT_MESH_ADV_TAG_LOCAL), + BT_MESH_ADV_TAG_RELAY_BIT = BIT(BT_MESH_ADV_TAG_RELAY), + BT_MESH_ADV_TAG_PROXY_BIT = BIT(BT_MESH_ADV_TAG_PROXY), + BT_MESH_ADV_TAG_FRIEND_BIT = BIT(BT_MESH_ADV_TAG_FRIEND), + BT_MESH_ADV_TAG_PROV_BIT = BIT(BT_MESH_ADV_TAG_PROV), }; struct bt_mesh_adv { @@ -80,7 +82,9 @@ int bt_mesh_adv_enable(void); void bt_mesh_adv_buf_local_ready(void); -void bt_mesh_adv_buf_relay_ready(void); +void bt_mesh_adv_buf_simult_ready(void); + +void bt_mesh_adv_buf_terminate(struct net_buf *buf); void bt_mesh_adv_buf_friend_ready(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 9dbbea31fb5..b5be40b3658 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -30,8 +30,8 @@ LOG_MODULE_REGISTER(bt_mesh_adv_ext); /* Convert from ms to 0.625ms units */ #define ADV_INT_FAST_MS 20 -#ifndef CONFIG_BT_MESH_RELAY_ADV_SETS -#define CONFIG_BT_MESH_RELAY_ADV_SETS 0 +#ifndef CONFIG_BT_MESH_SIMULT_ADV_SETS +#define CONFIG_BT_MESH_SIMULT_ADV_SETS 0 #endif enum { @@ -72,32 +72,40 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv); static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { .tags = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_FRIEND_ADV_BIT | + BT_MESH_ADV_TAG_FRIEND_BIT | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_PROXY_ADV_BIT | + BT_MESH_ADV_TAG_PROXY_BIT | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_RELAY_ADV_BIT | + BT_MESH_ADV_TAG_RELAY_BIT | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ - BT_MESH_LOCAL_ADV_BIT), + BT_MESH_ADV_TAG_LOCAL_BIT), .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; -#if CONFIG_BT_MESH_RELAY_ADV_SETS -static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_RELAY_ADV_SETS) = { - [0 ... CONFIG_BT_MESH_RELAY_ADV_SETS - 1] = { - .tags = BT_MESH_RELAY_ADV_BIT, +#if CONFIG_BT_MESH_SIMULT_ADV_SETS +static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_SIMULT_ADV_SETS) = { + [0 ... CONFIG_BT_MESH_SIMULT_ADV_SETS - 1] = { + .tags = ( +#if defined(CONFIG_BT_MESH_RELAY) + BT_MESH_ADV_TAG_RELAY_BIT | +#endif /* CONFIG_BT_MESH_RELAY */ +#if defined(CONFIG_BT_MESH_PB_ADV) + BT_MESH_ADV_TAG_PROV_BIT | +#endif /* CONFIG_BT_MESH_PB_ADV */ + 0), + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), } }; -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) #define ADV_EXT_FRIEND 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { - .tags = BT_MESH_FRIEND_ADV_BIT, + .tags = BT_MESH_ADV_TAG_FRIEND_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ @@ -107,25 +115,25 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) #define ADV_EXT_GATT 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { - .tags = BT_MESH_PROXY_ADV_BIT, + .tags = BT_MESH_ADV_TAG_PROXY_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #define ADV_EXT_GATT 0 #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ -#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) +#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_SIMULT_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT, "Insufficient adv instances"); static inline struct bt_mesh_ext_adv *relay_adv_get(void) { -#if CONFIG_BT_MESH_RELAY_ADV_SETS +#if CONFIG_BT_MESH_SIMULT_ADV_SETS return adv_relay; -#else /* !CONFIG_BT_MESH_RELAY_ADV_SETS */ +#else /* !CONFIG_BT_MESH_SIMULT_ADV_SETS */ return &adv_main; -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ } static inline struct bt_mesh_ext_adv *gatt_adv_get(void) @@ -234,20 +242,13 @@ static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) return err; } -static const char *adv_tag_to_str(enum bt_mesh_adv_tags tags) -{ - if (tags & BT_MESH_LOCAL_ADV_BIT) { - return "local adv"; - } else if (tags & BT_MESH_PROXY_ADV_BIT) { - return "proxy adv"; - } else if (tags & BT_MESH_RELAY_ADV_BIT) { - return "relay adv"; - } else if (tags & BT_MESH_FRIEND_ADV_BIT) { - return "friend adv"; - } else { - return "(unknown tags)"; - } -} +static const char * const adv_tag_to_str[] = { + [BT_MESH_ADV_TAG_LOCAL] = "local adv", + [BT_MESH_ADV_TAG_RELAY] = "relay adv", + [BT_MESH_ADV_TAG_PROXY] = "proxy adv", + [BT_MESH_ADV_TAG_FRIEND] = "friend adv", + [BT_MESH_ADV_TAG_PROV] = "prov adv", +}; static void send_pending_adv(struct k_work *work) { @@ -264,8 +265,9 @@ static void send_pending_adv(struct k_work *work) */ int64_t duration = k_uptime_delta(&adv->timestamp); - LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tags, - adv_tag_to_str(adv->tags)); + LOG_DBG("Advertising stopped after %u ms for %s", (uint32_t)duration, + adv->buf ? adv_tag_to_str[BT_MESH_ADV(adv->buf)->tag] : + adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]); atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); @@ -301,7 +303,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_RELAY_ADV_BIT)) { + !(adv->tags & BT_MESH_ADV_TAG_PROXY_BIT)) { return; } @@ -344,8 +346,9 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); - if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tags & BT_MESH_FRIEND_ADV_BIT) || - (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_RELAY_ADV_BIT)) { + if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && + adv->tags & BT_MESH_ADV_TAG_FRIEND_BIT) || + (CONFIG_BT_MESH_SIMULT_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_RELAY_BIT)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. @@ -369,11 +372,11 @@ void bt_mesh_adv_buf_local_ready(void) (void)schedule_send(&adv_main); } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_buf_simult_ready(void) { struct bt_mesh_ext_adv *adv = relay_adv_get(); - for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { + for (int i = 0; i < CONFIG_BT_MESH_SIMULT_ADV_SETS; i++) { if (schedule_send(&adv[i])) { return; } @@ -392,6 +395,36 @@ void bt_mesh_adv_buf_friend_ready(void) #endif } +void bt_mesh_adv_buf_terminate(struct net_buf *buf) +{ + int err; + + STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { + if (adv->buf != buf) { + continue; + } + + if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { + return; + } + + err = bt_le_ext_adv_stop(adv->instance); + if (err) { + LOG_ERR("Failed to stop adv %d", err); + return; + } + + /* Do not call `cb:end`, since this user action */ + BT_MESH_ADV(adv->buf)->cb = NULL; + + atomic_set_bit(adv->flags, ADV_FLAG_SENT); + + k_work_submit(&adv->work.work); + + break; + } +} + void bt_mesh_adv_init(void) { struct bt_le_adv_param adv_param = { diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index 8136aef9f22..cb4028662f9 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -195,7 +195,7 @@ void bt_mesh_adv_buf_local_ready(void) /* Will be handled automatically */ } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_buf_simult_ready(void) { /* Will be handled automatically */ } @@ -205,6 +205,12 @@ void bt_mesh_adv_gatt_update(void) bt_mesh_adv_buf_get_cancel(); } +void bt_mesh_adv_buf_terminate(struct net_buf *buf) +{ + /* todo */ + ARG_UNUSED(buf); +} + void bt_mesh_adv_init(void) { k_thread_create(&adv_thread_data, adv_thread_stack, diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index 8c0ac3b54e9..afdea5b4c6a 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -271,7 +271,7 @@ static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *b return false; } - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, PROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate beacon buffer"); @@ -335,7 +335,7 @@ static int unprovisioned_beacon_send(void) LOG_DBG(""); - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, UNPROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate beacon buffer"); @@ -362,7 +362,7 @@ static int unprovisioned_beacon_send(void) if (prov->uri) { size_t len; - buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_ADV_TAG_LOCAL, UNPROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate URI buffer"); diff --git a/subsys/bluetooth/mesh/friend.c b/subsys/bluetooth/mesh/friend.c index 179755d9706..73b75eadf4f 100644 --- a/subsys/bluetooth/mesh/friend.c +++ b/subsys/bluetooth/mesh/friend.c @@ -1281,7 +1281,7 @@ static void friend_timeout(struct k_work *work) frnd->queue_size--; send_last: - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_FRIEND_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_FRIEND, FRIEND_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate friend adv buffer"); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 2cfc709c648..61efaeb2c81 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -712,7 +712,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, transmit = bt_mesh_net_transmit_get(); } - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_RELAY_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY, transmit, K_NO_WAIT); if (!buf) { LOG_DBG("Out of relay buffers"); diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index 27d55763298..cb5f53f32b7 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -55,11 +55,11 @@ LOG_MODULE_REGISTER(bt_mesh_pb_adv); /* Acked messages, will do retransmissions manually, taking acks into account: */ -#define RETRANSMITS_RELIABLE 0 +#define RETRANSMITS_RELIABLE CONFIG_BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT /* PDU acks: */ -#define RETRANSMITS_ACK 2 +#define RETRANSMITS_ACK CONFIG_BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT /* Link close retransmits: */ -#define RETRANSMITS_LINK_CLOSE 2 +#define RETRANSMITS_LINK_CLOSE CONFIG_BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT enum { ADV_LINK_ACTIVE, /* Link has been opened */ @@ -178,8 +178,15 @@ static void free_segments(void) } link.tx.buf[i] = NULL; - /* Mark as canceled */ - BT_MESH_ADV(buf)->busy = 0U; + + /* Terminate active adv */ + if (BT_MESH_ADV(buf)->busy == 0U) { + bt_mesh_adv_buf_terminate(buf); + } else { + /* Mark as canceled */ + BT_MESH_ADV(buf)->busy = 0U; + } + net_buf_unref(buf); } } @@ -251,7 +258,7 @@ static struct net_buf *adv_buf_create(uint8_t retransmits) { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, BT_MESH_TRANSMIT(retransmits, 20), BUF_TIMEOUT); if (!buf) { diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 046fa3c0eeb..21c451bee73 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -24,22 +24,22 @@ void bt_mesh_stat_reset(void) void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_LOCAL_ADV) { + if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_planned++; - } else if (adv->tag == BT_MESH_RELAY_ADV) { + } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_planned++; - } else if (adv->tag == BT_MESH_FRIEND_ADV) { + } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_planned++; } } void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_LOCAL_ADV) { + if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_succeeded++; - } else if (adv->tag == BT_MESH_RELAY_ADV) { + } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag == BT_MESH_FRIEND_ADV) { + } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_succeeded++; } } diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index 0343993e348..f4c49aa6856 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -124,7 +124,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); if (!buf) { LOG_ERR("Out of network buffers"); @@ -414,7 +414,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); if (!seg) { LOG_DBG("Allocating segment failed"); diff --git a/subsys/bluetooth/mesh/transport_legacy.c b/subsys/bluetooth/mesh/transport_legacy.c index 475a0429f75..23e103b4370 100644 --- a/subsys/bluetooth/mesh/transport_legacy.c +++ b/subsys/bluetooth/mesh/transport_legacy.c @@ -131,7 +131,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); if (!buf) { LOG_ERR("Out of network buffers"); @@ -401,7 +401,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); if (!seg) { LOG_DBG("Allocating segment failed"); diff --git a/tests/bluetooth/mesh/basic/multi_ext_adv.conf b/tests/bluetooth/mesh/basic/multi_ext_adv.conf index 610318f847b..0278bd557bd 100644 --- a/tests/bluetooth/mesh/basic/multi_ext_adv.conf +++ b/tests/bluetooth/mesh/basic/multi_ext_adv.conf @@ -51,5 +51,5 @@ CONFIG_BT_MESH_CRYPTO_LOG_LEVEL_DBG=y CONFIG_BT_MESH_ADV_LOG_LEVEL_DBG=y CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 -CONFIG_BT_MESH_RELAY_ADV_SETS=1 +CONFIG_BT_MESH_SIMULT_ADV_SETS=1 CONFIG_BT_MESH_ADV_EXT=y diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 70d3e2f4a17..603985afefc 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -81,7 +81,7 @@ static void adv_init(void) static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmit) { for (int i = 0; i < num_buf; i++) { - *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); ASSERT_FALSE_MSG(!*buf, "Out of buffers\n"); @@ -94,7 +94,7 @@ static void verify_adv_queue_overflow(void) struct net_buf *dummy_buf; /* Verity Queue overflow */ - dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_TRUE_MSG(!dummy_buf, "Unexpected extra buffer\n"); } @@ -160,7 +160,7 @@ static void realloc_end_cb(int err, void *cb_data) struct net_buf *buf = (struct net_buf *)cb_data; ASSERT_EQUAL(0, err); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); @@ -425,7 +425,7 @@ static void test_tx_cb_single(void) bt_init(); adv_init(); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); @@ -530,7 +530,7 @@ static void test_tx_proxy_mixin(void) * Advertising the proxy service should be resumed after * finishing advertising the message. */ - struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(5, 20), K_NO_WAIT); net_buf_add_mem(buf, txt_msg, sizeof(txt_msg)); bt_mesh_adv_send(buf, NULL, NULL); @@ -636,16 +636,16 @@ static void test_tx_random_order(void) /* Verify random order calls */ num_adv_sent = ARRAY_SIZE(buf); previous_checker = 0xff; - buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n"); - buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + ASSERT_FALSE(!buf[0], "Out of buffers\n"); + buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); ASSERT_FALSE_MSG(!buf[1], "Out of buffers\n"); send_adv_buf(buf[0], 0, 0xff); - buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, + buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); ASSERT_FALSE_MSG(!buf[2], "Out of buffers\n"); From 1b22324317ceafc4fc3d1243eba0be371af22e2d Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Thu, 7 Sep 2023 16:04:00 +0800 Subject: [PATCH 2132/4498] Bluetooth: Mesh: Use system workqueue for dhkey gen Since the default process dhkey gen in bt rx, will block send Trans Ack, cause peer device send more package. Signed-off-by: Lingao Meng --- subsys/bluetooth/mesh/Kconfig | 2 +- subsys/bluetooth/mesh/prov_device.c | 9 ++++++++- subsys/bluetooth/mesh/provisioner.c | 11 ++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index f9d4d3bcf98..667e80f45ab 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -210,7 +210,7 @@ config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT int "Link Ack and Transaction Ack retransmit count" - default 2 + default 0 range 0 7 help Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 992bf656202..6e56519eefb 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -358,6 +358,13 @@ static void prov_dh_key_gen(void) } } +static void prov_dh_key_gen_handler(struct k_work *work) +{ + prov_dh_key_gen(); +} + +static K_WORK_DEFINE(dh_gen_work, prov_dh_key_gen_handler); + static void prov_pub_key(const uint8_t *data) { LOG_DBG("Remote Public Key: %s", bt_hex(data, PUB_KEY_SIZE)); @@ -385,7 +392,7 @@ static void prov_pub_key(const uint8_t *data) PDU_LEN_PUB_KEY); } - prov_dh_key_gen(); + k_work_submit(&dh_gen_work); } static void notify_input_complete(void) diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 717cdbee610..6bf759272dd 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -20,6 +20,8 @@ #include "common/bt_str.h" +#include "host/long_wq.h" + #include "crypto.h" #include "adv.h" #include "mesh.h" @@ -450,6 +452,13 @@ static void prov_dh_key_gen(void) send_confirm(); } +static void prov_dh_key_gen_handler(struct k_work *work) +{ + prov_dh_key_gen(); +} + +static K_WORK_DEFINE(dh_gen_work, prov_dh_key_gen_handler); + static void prov_pub_key(const uint8_t *data) { LOG_DBG("Remote Public Key: %s", bt_hex(data, PUB_KEY_SIZE)); @@ -460,7 +469,7 @@ static void prov_pub_key(const uint8_t *data) memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, PUB_KEY_SIZE); bt_mesh_prov_link.bearer->clear_tx(); - prov_dh_key_gen(); + k_work_submit(&dh_gen_work); } static void notify_input_complete(void) From c2b2641fc18233df68e7cec3f0665aa1dbf29f5f Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 8 Sep 2023 13:56:10 +0800 Subject: [PATCH 2133/4498] Bluetooth: Mesh: Move ext adv sector to vector Obviously, it looks obscure by putting it in a sector, so, let's move to vector. refs: https://github.com/zephyrproject-rtos/zephyr/pull/57883 Signed-off-by: Lingao Meng --- cmake/linker_script/common/common-ram.cmake | 3 - include/zephyr/linker/common-ram.ld | 4 - subsys/bluetooth/mesh/Kconfig | 38 +++-- subsys/bluetooth/mesh/adv.c | 41 ++--- subsys/bluetooth/mesh/adv.h | 18 +-- subsys/bluetooth/mesh/adv_ext.c | 151 +++++++++--------- subsys/bluetooth/mesh/adv_legacy.c | 5 +- subsys/bluetooth/mesh/provisioner.c | 2 - tests/bluetooth/mesh/basic/multi_ext_adv.conf | 2 +- .../bsim/bluetooth/mesh/src/test_advertiser.c | 2 +- 10 files changed, 129 insertions(+), 137 deletions(-) diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index e6ef59eaf29..9c051477d10 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -111,9 +111,6 @@ if(CONFIG_UVB) zephyr_iterable_section(NAME uvb_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) endif() -if(CONFIG_BT_MESH_ADV_EXT) - zephyr_iterable_section(NAME bt_mesh_ext_adv GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) -endif() if(CONFIG_LOG) zephyr_iterable_section(NAME log_mpsc_pbuf GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index d2d1a5ca7f1..c03351abf98 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -12,10 +12,6 @@ #endif #endif /* NETWORKING */ -#if defined(CONFIG_BT_MESH) - ITERABLE_SECTION_RAM(bt_mesh_ext_adv, 4) -#endif - #if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_DYNAMIC_INTERRUPTS) SECTION_DATA_PROLOGUE(sw_isr_table,,) { diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 667e80f45ab..8667c1e70a0 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -103,22 +103,22 @@ menuconfig BT_MESH_ADV_EXT if BT_MESH_ADV_EXT -config BT_MESH_SIMULT_ADV_SETS - int "Maximum number of parallel advertising sets that can be used by the Bluetooth Mesh stack" +config BT_MESH_RELAY_ADV_SETS + int "Maximum of simultaneous relay message support" default 0 range 0 BT_EXT_ADV_MAX_ADV_SET - depends on BT_MESH_RELAY || BT_MESH_PB_ADV + depends on BT_MESH_RELAY help - Maximum of simultaneous message support. Requires controller support + Maximum of simultaneous relay message support. Requires controller support multiple advertising sets. config BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET bool "Use the main advertising set to relay messages" - depends on BT_MESH_SIMULT_ADV_SETS > 0 + depends on BT_MESH_RELAY_ADV_SETS > 0 help When this option is enabled, there is a message that needs to be relayed, all relay advertising sets defined by - CONFIG_BT_MESH_SIMULT_ADV_SETS are busy with relaying messages + CONFIG_BT_MESH_RELAY_ADV_SETS are busy with relaying messages and the main advertising set is not busy with sending local messages, the stack will use the main advertising set to relay the message. This maximizes the utilization efficiency of @@ -192,16 +192,15 @@ config BT_MESH_UNPROV_BEACON_INT if BT_MESH_PB_ADV -config BT_MESH_PB_ADV_RETRANS_TIMEOUT - int "Timeout value of retransmit provisioning PDUs" - default 500 - range 100 800 +config BT_MESH_PB_ADV_USE_RELAY_SETS + bool "Use relay advertising sets to send provisioning PDUs" + depends on BT_MESH_RELAY_ADV_SETS > 0 help - Timeout value of retransmit provisioning PDUs. + Use relay advertising sets to send provisioning PDUs config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT int "Link Open and Transaction PDU retransmit count" - default 7 if BT_MESH_SIMULT_ADV_SETS > 0 + default 7 if BT_MESH_PB_ADV_USE_RELAY_SETS default 0 range 0 7 help @@ -210,21 +209,28 @@ config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT int "Link Ack and Transaction Ack retransmit count" - default 0 + default 2 range 0 7 help - Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, + Controls the number of retransmissions of original Link Ack and Transaction Acknowledgment PDU, in addition to the first transmission. config BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT int "Link Close retransmit count" - default 7 if BT_MESH_SIMULT_ADV_SETS > 0 + default 7 if BT_MESH_PB_ADV_USE_RELAY_SETS default 2 range 0 7 help Controls the number of retransmissions of original Link Close, in addition to the first transmission. +config BT_MESH_PB_ADV_RETRANS_TIMEOUT + int "Timeout value of retransmit provisioning PDUs" + default 500 + range 100 800 + help + Timeout value of retransmit provisioning PDUs. + endif # BT_MESH_PB_ADV if BT_CONN @@ -401,7 +407,7 @@ config BT_MESH_RELAY_BUF_COUNT of packet drops. When considering the message latency, also consider the values of BT_MESH_RELAY_RETRANSMIT_COUNT and BT_MESH_RELAY_RETRANSMIT_INTERVAL. A higher number of - BT_MESH_SIMULT_ADV_SETS allows the increase in the number of buffers + BT_MESH_RELAY_ADV_SETS allows the increase in the number of buffers while maintaining the latency. endif # BT_MESH_RELAY diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index c7abcd53d70..b24523aacf3 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -44,7 +44,7 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { static bool active_scanning; static K_FIFO_DEFINE(bt_mesh_adv_queue); -static K_FIFO_DEFINE(bt_mesh_simult_queue); +static K_FIFO_DEFINE(bt_mesh_relay_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) @@ -157,7 +157,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, tag, xmit, timeout); } -#if CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE +#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE static struct net_buf *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { @@ -189,7 +189,7 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &bt_mesh_simult_queue, + &bt_mesh_relay_queue, 0), #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ }; @@ -202,34 +202,34 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return process_events(events, ARRAY_SIZE(events)); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) { if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - tags & BT_MESH_ADV_TAG_FRIEND_BIT) { + tags & BT_MESH_ADV_TAG_BIT_FRIEND) { return net_buf_get(&bt_mesh_friend_queue, timeout); } - if (tags & BT_MESH_ADV_TAG_LOCAL_BIT) { - return bt_mesh_adv_buf_get(timeout); +#if CONFIG_BT_MESH_RELAY_ADV_SETS + if (!(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { + return net_buf_get(&bt_mesh_relay_queue, timeout); } - -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - return net_buf_get(&bt_mesh_simult_queue, timeout); #endif + + return bt_mesh_adv_buf_get(timeout); } -#else /* !(CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ +#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) { return net_buf_get(&bt_mesh_adv_queue, timeout); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) { ARG_UNUSED(tags); return bt_mesh_adv_buf_get(timeout); } -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ void bt_mesh_adv_buf_get_cancel(void) { @@ -237,9 +237,9 @@ void bt_mesh_adv_buf_get_cancel(void) k_fifo_cancel_wait(&bt_mesh_adv_queue); -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - k_fifo_cancel_wait(&bt_mesh_simult_queue); -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ +#if CONFIG_BT_MESH_RELAY_ADV_SETS + k_fifo_cancel_wait(&bt_mesh_relay_queue); +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { k_fifo_cancel_wait(&bt_mesh_friend_queue); @@ -267,11 +267,12 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, return; } -#if CONFIG_BT_MESH_SIMULT_ADV_SETS +#if CONFIG_BT_MESH_RELAY_ADV_SETS if (BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY || - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV) { - net_buf_put(&bt_mesh_simult_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_simult_ready(); + (IS_ENABLED(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) && + BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV)) { + net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); + bt_mesh_adv_buf_relay_ready(); return; } #endif diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 50c5b47604c..a80ff7e8d4b 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -33,12 +33,12 @@ enum bt_mesh_adv_tag { BT_MESH_ADV_TAG_PROV, }; -enum bt_mesh_adv_tags { - BT_MESH_ADV_TAG_LOCAL_BIT = BIT(BT_MESH_ADV_TAG_LOCAL), - BT_MESH_ADV_TAG_RELAY_BIT = BIT(BT_MESH_ADV_TAG_RELAY), - BT_MESH_ADV_TAG_PROXY_BIT = BIT(BT_MESH_ADV_TAG_PROXY), - BT_MESH_ADV_TAG_FRIEND_BIT = BIT(BT_MESH_ADV_TAG_FRIEND), - BT_MESH_ADV_TAG_PROV_BIT = BIT(BT_MESH_ADV_TAG_PROV), +enum bt_mesh_adv_tag_bit { + BT_MESH_ADV_TAG_BIT_LOCAL = BIT(BT_MESH_ADV_TAG_LOCAL), + BT_MESH_ADV_TAG_BIT_RELAY = BIT(BT_MESH_ADV_TAG_RELAY), + BT_MESH_ADV_TAG_BIT_PROXY = BIT(BT_MESH_ADV_TAG_PROXY), + BT_MESH_ADV_TAG_BIT_FRIEND = BIT(BT_MESH_ADV_TAG_FRIEND), + BT_MESH_ADV_TAG_BIT_PROV = BIT(BT_MESH_ADV_TAG_PROV), }; struct bt_mesh_adv { @@ -66,7 +66,7 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout); +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); @@ -82,9 +82,9 @@ int bt_mesh_adv_enable(void); void bt_mesh_adv_buf_local_ready(void); -void bt_mesh_adv_buf_simult_ready(void); +void bt_mesh_adv_buf_relay_ready(void); -void bt_mesh_adv_buf_terminate(struct net_buf *buf); +void bt_mesh_adv_buf_terminate(const struct net_buf *buf); void bt_mesh_adv_buf_friend_ready(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index b5be40b3658..0bfc2041c7d 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -30,8 +30,8 @@ LOG_MODULE_REGISTER(bt_mesh_adv_ext); /* Convert from ms to 0.625ms units */ #define ADV_INT_FAST_MS 20 -#ifndef CONFIG_BT_MESH_SIMULT_ADV_SETS -#define CONFIG_BT_MESH_SIMULT_ADV_SETS 0 +#ifndef CONFIG_BT_MESH_RELAY_ADV_SETS +#define CONFIG_BT_MESH_RELAY_ADV_SETS 0 #endif enum { @@ -57,7 +57,7 @@ enum { }; struct bt_mesh_ext_adv { - enum bt_mesh_adv_tags tags; + const enum bt_mesh_adv_tag_bit tags; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; struct net_buf *buf; @@ -69,80 +69,71 @@ struct bt_mesh_ext_adv { static void send_pending_adv(struct k_work *work); static bool schedule_send(struct bt_mesh_ext_adv *adv); -static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { - .tags = ( +static struct bt_mesh_ext_adv advs[] = { + [0] = { + .tags = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_ADV_TAG_FRIEND_BIT | + BT_MESH_ADV_TAG_BIT_FRIEND | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_ADV_TAG_PROXY_BIT | + BT_MESH_ADV_TAG_BIT_PROXY | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_ADV_TAG_RELAY_BIT | + BT_MESH_ADV_TAG_BIT_RELAY | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ - BT_MESH_ADV_TAG_LOCAL_BIT), - - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), -}; - -#if CONFIG_BT_MESH_SIMULT_ADV_SETS -static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_SIMULT_ADV_SETS) = { - [0 ... CONFIG_BT_MESH_SIMULT_ADV_SETS - 1] = { +#if defined(CONFIG_BT_MESH_PB_ADV) + BT_MESH_ADV_TAG_BIT_PROV | +#endif /* CONFIG_BT_MESH_PB_ADV */ + BT_MESH_ADV_TAG_BIT_LOCAL + ), + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + }, +#if CONFIG_BT_MESH_RELAY_ADV_SETS + [1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = { .tags = ( #if defined(CONFIG_BT_MESH_RELAY) - BT_MESH_ADV_TAG_RELAY_BIT | + BT_MESH_ADV_TAG_BIT_RELAY | #endif /* CONFIG_BT_MESH_RELAY */ -#if defined(CONFIG_BT_MESH_PB_ADV) - BT_MESH_ADV_TAG_PROV_BIT | -#endif /* CONFIG_BT_MESH_PB_ADV */ +#if defined(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) + BT_MESH_ADV_TAG_BIT_PROV | +#endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */ 0), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), - } -}; -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ - + }, +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) -#define ADV_EXT_FRIEND 1 -static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { - .tags = BT_MESH_ADV_TAG_FRIEND_BIT, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), -}; -#else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ -#define ADV_EXT_FRIEND 0 + { + .tags = BT_MESH_ADV_TAG_BIT_FRIEND, + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + }, #endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ - #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) -#define ADV_EXT_GATT 1 -static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { - .tags = BT_MESH_ADV_TAG_PROXY_BIT, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), -}; -#else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ -#define ADV_EXT_GATT 0 + { + .tags = BT_MESH_ADV_TAG_BIT_PROXY, + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + }, #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ +}; -#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_SIMULT_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) - -BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT, +BUILD_ASSERT(ARRAY_SIZE(advs) <= CONFIG_BT_EXT_ADV_MAX_ADV_SET, "Insufficient adv instances"); static inline struct bt_mesh_ext_adv *relay_adv_get(void) { -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - return adv_relay; -#else /* !CONFIG_BT_MESH_SIMULT_ADV_SETS */ - return &adv_main; -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ + if (!!(CONFIG_BT_MESH_RELAY_ADV_SETS)) { + return &advs[1]; + } else { + return &advs[0]; + } } static inline struct bt_mesh_ext_adv *gatt_adv_get(void) { -#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - return &adv_gatt; -#else /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ - return &adv_main; -#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)) { + return &advs[ARRAY_SIZE(advs) - 1]; + } else { + return &advs[0]; + } } static int adv_start(struct bt_mesh_ext_adv *adv, @@ -303,7 +294,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_ADV_TAG_PROXY_BIT)) { + !(adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { return; } @@ -347,8 +338,8 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tags & BT_MESH_ADV_TAG_FRIEND_BIT) || - (CONFIG_BT_MESH_SIMULT_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_RELAY_BIT)) { + adv->tags & BT_MESH_ADV_TAG_BIT_FRIEND) || + (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_BIT_RELAY)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. @@ -369,14 +360,14 @@ void bt_mesh_adv_gatt_update(void) void bt_mesh_adv_buf_local_ready(void) { - (void)schedule_send(&adv_main); + (void)schedule_send(advs); } -void bt_mesh_adv_buf_simult_ready(void) +void bt_mesh_adv_buf_relay_ready(void) { struct bt_mesh_ext_adv *adv = relay_adv_get(); - for (int i = 0; i < CONFIG_BT_MESH_SIMULT_ADV_SETS; i++) { + for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { if (schedule_send(&adv[i])) { return; } @@ -384,22 +375,26 @@ void bt_mesh_adv_buf_simult_ready(void) /* Attempt to use the main adv set for the sending of relay messages. */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)) { - (void)schedule_send(&adv_main); + (void)schedule_send(advs); } } void bt_mesh_adv_buf_friend_ready(void) { -#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - (void)schedule_send(&adv_friend); -#endif + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { + schedule_send(&advs[1 + CONFIG_BT_MESH_RELAY_ADV_SETS]); + } else { + schedule_send(&advs[0]); + } } -void bt_mesh_adv_buf_terminate(struct net_buf *buf) +void bt_mesh_adv_buf_terminate(const struct net_buf *buf) { int err; - STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + struct bt_mesh_ext_adv *adv = &advs[i]; + if (adv->buf != buf) { continue; } @@ -421,7 +416,7 @@ void bt_mesh_adv_buf_terminate(struct net_buf *buf) k_work_submit(&adv->work.work); - break; + return; } } @@ -434,17 +429,18 @@ void bt_mesh_adv_init(void) #if defined(CONFIG_BT_MESH_DEBUG_USE_ID_ADDR) .options = BT_LE_ADV_OPT_USE_IDENTITY, #endif -}; - STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { - (void)memcpy(&adv->adv_param, &adv_param, sizeof(adv_param)); + }; + + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + (void)memcpy(&advs[i].adv_param, &adv_param, sizeof(adv_param)); } } static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance) { - STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { - if (adv->instance == instance) { - return adv; + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + if (advs[i].instance == instance) { + return &advs[i]; } } @@ -494,15 +490,14 @@ int bt_mesh_adv_enable(void) #endif /* CONFIG_BT_MESH_GATT_SERVER */ }; - if (adv_main.instance) { + if (advs[0].instance) { /* Already initialized */ return 0; } - - STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { - err = bt_le_ext_adv_create(&adv->adv_param, &adv_cb, - &adv->instance); + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + err = bt_le_ext_adv_create(&advs[i].adv_param, &adv_cb, + &advs[i].instance); if (err) { return err; } @@ -532,5 +527,5 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len) { - return bt_data_send(&adv_main, num_events, adv_interval, ad, ad_len); + return bt_data_send(advs, num_events, adv_interval, ad, ad_len); } diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index cb4028662f9..a7d7dd1a320 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -195,7 +195,7 @@ void bt_mesh_adv_buf_local_ready(void) /* Will be handled automatically */ } -void bt_mesh_adv_buf_simult_ready(void) +void bt_mesh_adv_buf_relay_ready(void) { /* Will be handled automatically */ } @@ -205,9 +205,8 @@ void bt_mesh_adv_gatt_update(void) bt_mesh_adv_buf_get_cancel(); } -void bt_mesh_adv_buf_terminate(struct net_buf *buf) +void bt_mesh_adv_buf_terminate(const struct net_buf *buf) { - /* todo */ ARG_UNUSED(buf); } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 6bf759272dd..a65bd25ab53 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -20,8 +20,6 @@ #include "common/bt_str.h" -#include "host/long_wq.h" - #include "crypto.h" #include "adv.h" #include "mesh.h" diff --git a/tests/bluetooth/mesh/basic/multi_ext_adv.conf b/tests/bluetooth/mesh/basic/multi_ext_adv.conf index 0278bd557bd..610318f847b 100644 --- a/tests/bluetooth/mesh/basic/multi_ext_adv.conf +++ b/tests/bluetooth/mesh/basic/multi_ext_adv.conf @@ -51,5 +51,5 @@ CONFIG_BT_MESH_CRYPTO_LOG_LEVEL_DBG=y CONFIG_BT_MESH_ADV_LOG_LEVEL_DBG=y CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 -CONFIG_BT_MESH_SIMULT_ADV_SETS=1 +CONFIG_BT_MESH_RELAY_ADV_SETS=1 CONFIG_BT_MESH_ADV_EXT=y diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 603985afefc..073651ae843 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -638,7 +638,7 @@ static void test_tx_random_order(void) previous_checker = 0xff; buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE(!buf[0], "Out of buffers\n"); + ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n"); buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); ASSERT_FALSE_MSG(!buf[1], "Out of buffers\n"); From 7c7ea3847196c57dab9f85ed196cf02dad0c3747 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 17 Oct 2023 14:07:52 +0200 Subject: [PATCH 2134/4498] bsim: bluetooth: mesh: Increase Net Transmit Count value on the node This is to increase probability of reception of responses (Config Status messages) from the node when the provisioner sends a Set message and the node response with a Status message at the same time so that the message collide. Signed-off-by: Pavel Vasilyev --- tests/bsim/bluetooth/mesh/src/test_persistence.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 24d992e48e8..2f8d523bede 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -544,6 +544,17 @@ static void node_configure(void) uint16_t va; struct bt_mesh_cfg_cli_mod_pub pub_params; + /* Set Network Transmit Count state on the device greater than on provisioner to increase + * probability of reception responses. + */ + uint8_t net_transmit; + + net_transmit = BT_MESH_TRANSMIT(3, 20); + err = bt_mesh_cfg_cli_net_transmit_set(test_netkey_idx, TEST_ADDR, net_transmit, &status); + if (err || status != net_transmit) { + FAIL("Net transmit set failed (err %d, transmit %x)", err, status); + } + struct test_appkey_t test_appkeys[] = { { .idx = TEST_APPKEY_0_IDX, .key = TEST_APPKEY_0_KEY }, { .idx = TEST_APPKEY_1_IDX, .key = TEST_APPKEY_1_KEY }, From f9f0748c9686b85d2ad56e81529dc2e42dcdfe60 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 7 Sep 2023 12:47:44 +0200 Subject: [PATCH 2135/4498] cmake: Zephyr kernel version.h and app_version.h creation Change the creation of version.h and app_version.h to apply the KERNEL_VERSION_CUSTOMIZATION APP_VERSION_CUSTOMIZATION values as target properties instead of CMake variables. This allows more freedom for users / Zephyr modules to adjust the value of KERNEL_VERSION_CUSTOMIZATION and APP_VERSION_CUSTOMIZATION values and thereby make use of the functionality introduced with #61635. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aae816c4b9..666c9079c9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -555,10 +555,11 @@ add_custom_command( -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/version.h -DVERSION_TYPE=KERNEL -DVERSION_FILE=${ZEPHYR_BASE}/VERSION - -DKERNEL_VERSION_CUSTOMIZATION="${KERNEL_VERSION_CUSTOMIZATION}" + -DKERNEL_VERSION_CUSTOMIZATION="$" ${build_version_argument} -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake DEPENDS ${ZEPHYR_BASE}/VERSION ${git_dependency} + COMMAND_EXPAND_LISTS ) add_custom_target(version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/version.h) @@ -569,10 +570,11 @@ if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION) -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/app_version.h -DVERSION_TYPE=APP -DVERSION_FILE=${APPLICATION_SOURCE_DIR}/VERSION - -DAPP_VERSION_CUSTOMIZATION="${APP_VERSION_CUSTOMIZATION}" + -DAPP_VERSION_CUSTOMIZATION="$" ${build_version_argument} -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake DEPENDS ${APPLICATION_SOURCE_DIR}/VERSION ${git_dependency} + COMMAND_EXPAND_LISTS ) add_custom_target(app_version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/app_version.h) add_dependencies(zephyr_interface app_version_h) From bb1cfbad19d97a684164f921755abe0a299a0846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8nningstad?= Date: Thu, 7 Sep 2023 13:13:23 +0200 Subject: [PATCH 2136/4498] twister: Add option for generating rom.json and ram.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generate the files via the 'footprint' target for each project. Signed-off-by: Øyvind Rønningstad --- scripts/pylib/twister/twisterlib/environment.py | 5 +++++ scripts/pylib/twister/twisterlib/runner.py | 2 ++ 2 files changed, 7 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 9c676ceb733..efa903218fb 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -364,6 +364,11 @@ def add_parse_arguments(parser = None): parser.add_argument("--enable-size-report", action="store_true", help="Enable expensive computation of RAM/ROM segment sizes.") + parser.add_argument("--create-rom-ram-report", action="store_true", + help="Generate detailed ram/rom json reports for " + "each build, via cmake build calls with the " + "`--target footprint` argument") + parser.add_argument( "--filter", choices=['buildable', 'runnable'], default='buildable', diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 25e96a36038..13c2bad7b91 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1062,6 +1062,8 @@ def run(self): sys.stdout.flush() def gather_metrics(self, instance: TestInstance): + if self.options.create_rom_ram_report: + self.run_build(['--build', self.build_dir, "--target", "footprint"]) if self.options.enable_size_report and not self.options.cmake_only: self.calc_size(instance=instance, from_buildlog=self.options.footprint_from_buildlog) else: From 90bd7863c714eb58d89846526dcd75d8a6b22eb8 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 4 Sep 2023 05:03:49 +0900 Subject: [PATCH 2137/4498] drivers: spi: pl022: correcting error check condition Only negative return values of pinctrl_apply_state are errors. Signed-off-by: TOKITA Hiroshi --- drivers/spi/spi_pl022.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi_pl022.c b/drivers/spi/spi_pl022.c index d71516f17df..29f92d3050c 100644 --- a/drivers/spi/spi_pl022.c +++ b/drivers/spi/spi_pl022.c @@ -889,7 +889,7 @@ static int spi_pl022_init(const struct device *dev) #if defined(CONFIG_PINCTRL) ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); - if (ret) { + if (ret < 0) { LOG_ERR("Failed to apply pinctrl state"); return ret; } From a32feddaf3bacda4b3f2fa2c8616db26613794e6 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 10:18:05 -0500 Subject: [PATCH 2138/4498] charger: Adds CHARGER_CHARGE_TYPE property Adds a new runtime property called CHARGER_PROP_CHARGE_TYPE to the charger API. This can be used to get/set the charging scheme used to charge the battery pack. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 8e72ae03b0b..db5ffd47778 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -37,6 +37,9 @@ enum charger_property { /** Represents the charging status of the charger. */ /** Value should be of type enum charger_status */ CHARGER_PROP_STATUS, + /** Represents the charging algo type of the charger. */ + /** Value should be of type enum charger_charge_type */ + CHARGER_PROP_CHARGE_TYPE, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -84,6 +87,39 @@ enum charger_status { CHARGER_STATUS_FULL, }; +/** + * @brief Charge algorithm types + */ +enum charger_charge_type { + /** Charge type is unknown */ + CHARGER_CHARGE_TYPE_UNKNOWN = 0, + /** Charging is not occurring */ + CHARGER_CHARGE_TYPE_NONE, + /* + * Charging is occurring at the slowest desired charge rate, + * typically for battery detection or preconditioning + */ + CHARGER_CHARGE_TYPE_TRICKLE, + /** Charging is occurring at the fastest desired charge rate */ + CHARGER_CHARGE_TYPE_FAST, + /** Charging is occurring at a moderate charge rate */ + CHARGER_CHARGE_TYPE_STANDARD, + /* + * Charging is being dynamically adjusted by the charger device + */ + CHARGER_CHARGE_TYPE_ADAPTIVE, + /* + * Charging is occurring at a reduced charge rate to preserve + * battery health + */ + CHARGER_CHARGE_TYPE_LONGLIFE, + /* + * The charger device is being bypassed and the power conversion + * is being handled externally, typically by a "smart" wall adaptor + */ + CHARGER_CHARGE_TYPE_BYPASS, +}; + /** * @brief container for a charger_property value * @@ -99,6 +135,8 @@ union charger_propval { bool present; /** CHARGER_PROP_STATUS */ enum charger_status status; + /** CHARGER_PROP_CHARGE_TYPE */ + enum charger_charge_type charge_type; }; /** From d47447c763e2bf87e2e5014b4f93bb0278574594 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 10:34:31 -0500 Subject: [PATCH 2139/4498] charger: Adds CHARGER_HEALTH property Adds a new runtime property called CHARGER_PROP_HEALTH to the charger API. This can be used to get the charger health condition. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index db5ffd47778..3b56c3cfd50 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -40,6 +40,9 @@ enum charger_property { /** Represents the charging algo type of the charger. */ /** Value should be of type enum charger_charge_type */ CHARGER_PROP_CHARGE_TYPE, + /** Represents the health of the charger. */ + /** Value should be of type enum charger_health */ + CHARGER_PROP_HEALTH, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -120,6 +123,43 @@ enum charger_charge_type { CHARGER_CHARGE_TYPE_BYPASS, }; +/** + * @brief Charger health conditions + * + * These conditions determine the ability to, or the rate of, charge + */ +enum charger_health { + /** Charger health condition is unknown */ + CHARGER_HEALTH_UNKNOWN = 0, + /** Charger health condition is good */ + CHARGER_HEALTH_GOOD, + /** The charger device is overheated */ + CHARGER_HEALTH_OVERHEAT, + /** The battery voltage has exceeded its overvoltage threshold */ + CHARGER_HEALTH_OVERVOLTAGE, + /* + * The battery or charger device is experiencing an unspecified + * failure. + */ + CHARGER_HEALTH_UNSPEC_FAILURE, + /** The battery temperature is below the "cold" threshold */ + CHARGER_HEALTH_COLD, + /** The charger device's watchdog timer has expired */ + CHARGER_HEALTH_WATCHDOG_TIMER_EXPIRE, + /** The charger device's safety timer has expired */ + CHARGER_HEALTH_SAFETY_TIMER_EXPIRE, + /** The charger device requires calibration */ + CHARGER_HEALTH_CALIBRATION_REQUIRED, + /** The battery temperature is in the "warm" range */ + CHARGER_HEALTH_WARM, + /** The battery temperature is in the "cool" range */ + CHARGER_HEALTH_COOL, + /** The battery temperature is below the "hot" threshold */ + CHARGER_HEALTH_HOT, + /** The charger device does not detect a battery */ + CHARGER_HEALTH_NO_BATTERY, +}; + /** * @brief container for a charger_property value * @@ -137,6 +177,8 @@ union charger_propval { enum charger_status status; /** CHARGER_PROP_CHARGE_TYPE */ enum charger_charge_type charge_type; + /** CHARGER_PROP_HEALTH */ + enum charger_health health; }; /** From ec024b850e5497e69aa568c985c4fef508a381da Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 10:47:50 -0500 Subject: [PATCH 2140/4498] charger: Adds CHARGER_CONSTANT_CHARGE_CURRENT property Adds a new runtime property called CHARGER_PROP_CONSTANT_CHARGE_CURRENT to the charger API. This can be used to get/set the charger constant current sink target. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 3b56c3cfd50..0f5c3e63d4b 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -43,6 +43,8 @@ enum charger_property { /** Represents the health of the charger. */ /** Value should be of type enum charger_health */ CHARGER_PROP_HEALTH, + /** Configuration of current sink used for charging in µA */ + CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -179,6 +181,8 @@ union charger_propval { enum charger_charge_type charge_type; /** CHARGER_PROP_HEALTH */ enum charger_health health; + /** CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA */ + uint32_t const_charge_current_ua; }; /** From 610143dab4687d6750265aea6878db20818b3a48 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 11:12:39 -0500 Subject: [PATCH 2141/4498] charger: Adds CHARGER_PRECHARGE_CURRENT property Adds a new runtime property called CHARGER_PROP_PRECHARGE_CURRENT to the charger API. This can be used to get/set the charger conditioning current sink target. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 0f5c3e63d4b..c620ad10ba4 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -45,6 +45,8 @@ enum charger_property { CHARGER_PROP_HEALTH, /** Configuration of current sink used for charging in µA */ CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA, + /** Configuration of current sink used for conditioning in µA */ + CHARGER_PROP_PRECHARGE_CURRENT_UA, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -183,6 +185,8 @@ union charger_propval { enum charger_health health; /** CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA */ uint32_t const_charge_current_ua; + /** CHARGER_PROP_PRECHARGE_CURRENT_UA */ + uint32_t precharge_current_ua; }; /** From c7f22eee9ffd131ccb5d7ab2901756d802dc290e Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 11:22:40 -0500 Subject: [PATCH 2142/4498] charger: Adds CHARGER_CHARGE_TERM_CURRENT property Adds a new runtime property called CHARGER_PROP_CHARGE_TERM_CURRENT to the charger API. This can be used to get/set the charger termination current target. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index c620ad10ba4..1c316a0f1db 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -47,6 +47,8 @@ enum charger_property { CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA, /** Configuration of current sink used for conditioning in µA */ CHARGER_PROP_PRECHARGE_CURRENT_UA, + /** Configuration of charge termination target in µA */ + CHARGER_PROP_CHARGE_TERM_CURRENT_UA, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -187,6 +189,8 @@ union charger_propval { uint32_t const_charge_current_ua; /** CHARGER_PROP_PRECHARGE_CURRENT_UA */ uint32_t precharge_current_ua; + /** CHARGER_PROP_CHARGE_TERM_CURRENT_UA */ + uint32_t charge_term_current_ua; }; /** From 59bb1c523c9ccef6e47f09e23f1d6bc8bb927eb2 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 8 Sep 2023 11:49:34 -0500 Subject: [PATCH 2143/4498] charger: Adds CHARGER_CONSTANT_CHARGE_VOLTAGE property Adds a new runtime property called CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE to the charger API. This can be used to get/set the charger constant voltage regulation target. Signed-off-by: Ricardo Rivera-Matos --- include/zephyr/drivers/charger.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 1c316a0f1db..25802e6b76a 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -49,6 +49,8 @@ enum charger_property { CHARGER_PROP_PRECHARGE_CURRENT_UA, /** Configuration of charge termination target in µA */ CHARGER_PROP_CHARGE_TERM_CURRENT_UA, + /** Configuration of charge voltage regulation target in µV */ + CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** @@ -191,6 +193,8 @@ union charger_propval { uint32_t precharge_current_ua; /** CHARGER_PROP_CHARGE_TERM_CURRENT_UA */ uint32_t charge_term_current_ua; + /** CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV */ + uint32_t const_charge_voltage_uv; }; /** From 5b1a7b0f2ae9865513fbc869616eadbdf71d1f62 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Mon, 11 Sep 2023 14:16:16 -0500 Subject: [PATCH 2144/4498] dts: battery: Create bindings for common battery properties Adds a devicetree for describing common battery characteristics used by multiple devices and subsystems. Signed-off-by: Ricardo Rivera-Matos --- dts/bindings/battery/battery.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 dts/bindings/battery/battery.yaml diff --git a/dts/bindings/battery/battery.yaml b/dts/bindings/battery/battery.yaml new file mode 100644 index 00000000000..90bb20532d4 --- /dev/null +++ b/dts/bindings/battery/battery.yaml @@ -0,0 +1,25 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Static Battery Characteristics + + Properties are inherited from Linux. See + linux/Documentation/devicetree/bindings/power/supply/battery.yaml + +properties: + precharge-current-microamp: + type: int + description: current for pre-charge phase + + charge-term-current-microamp: + type: int + description: current for charge termination phase + + constant-charge-current-max-microamp: + type: int + description: maximum constant input current + + constant-charge-voltage-max-microvolt: + type: int + description: maximum constant input voltage From 65c36b75195ad7d0bd6907a06ac2755fcf4a2dee Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Tue, 12 Sep 2023 09:11:13 -0500 Subject: [PATCH 2145/4498] dts: charger: bq24190: Adds dt-bindings for BQ24190 Adds devicetree bindings for the BQ24190 family of charging ICs Signed-off-by: Ricardo Rivera-Matos --- dts/bindings/charger/ti,bq24190.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 dts/bindings/charger/ti,bq24190.yaml diff --git a/dts/bindings/charger/ti,bq24190.yaml b/dts/bindings/charger/ti,bq24190.yaml new file mode 100644 index 00000000000..34d271754f3 --- /dev/null +++ b/dts/bindings/charger/ti,bq24190.yaml @@ -0,0 +1,8 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments family of BQ24190 of charging ICs + +include: [battery.yaml, i2c-device.yaml] + +compatible: "ti,bq24190" From fd06cd7c97fb0e1cb2aeb57ae0fe47a28efaec08 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 10 May 2023 09:26:33 -0500 Subject: [PATCH 2146/4498] drivers: charger: Introduces BQ24190 support Adds support for the BQ24190 family of charging ICs. Signed-off-by: Ricardo Rivera-Matos --- drivers/charger/CMakeLists.txt | 1 + drivers/charger/Kconfig | 1 + drivers/charger/Kconfig.bq24190 | 10 + drivers/charger/bq24190.c | 493 ++++++++++++++++++++++++++++++++ drivers/charger/bq24190.h | 167 +++++++++++ 5 files changed, 672 insertions(+) create mode 100644 drivers/charger/Kconfig.bq24190 create mode 100644 drivers/charger/bq24190.c create mode 100644 drivers/charger/bq24190.h diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt index 6b4b36ae61a..84b34009423 100644 --- a/drivers/charger/CMakeLists.txt +++ b/drivers/charger/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) +zephyr_library_sources_ifdef(CONFIG_BQ24190 bq24190.c) zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig index 532a0a4545d..4a6071fd8f8 100644 --- a/drivers/charger/Kconfig +++ b/drivers/charger/Kconfig @@ -20,5 +20,6 @@ config CHARGER_INIT_PRIORITY Battery charger initialization priority. source "drivers/charger/Kconfig.sbs_charger" +source "drivers/charger/Kconfig.bq24190" endif # CHARGER diff --git a/drivers/charger/Kconfig.bq24190 b/drivers/charger/Kconfig.bq24190 new file mode 100644 index 00000000000..3327f671c69 --- /dev/null +++ b/drivers/charger/Kconfig.bq24190 @@ -0,0 +1,10 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BQ24190 + bool "BQ24190 Battery Charger" + default y + depends on DT_HAS_TI_BQ24190_ENABLED + select I2C + help + Enable I2C-based driver for the TI BQ24190 Battery Charger. diff --git a/drivers/charger/bq24190.c b/drivers/charger/bq24190.c new file mode 100644 index 00000000000..0661bd92796 --- /dev/null +++ b/drivers/charger/bq24190.c @@ -0,0 +1,493 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_bq24190 + +#include + +#include "bq24190.h" + +#include "zephyr/device.h" +#include "zephyr/drivers/charger.h" +#include "zephyr/drivers/i2c.h" +#include "zephyr/kernel.h" +#include "zephyr/sys/util.h" +#include "zephyr/logging/log.h" +#include + +LOG_MODULE_REGISTER(ti_bq24190); + +struct bq24190_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec ce_gpio; +}; + +struct bq24190_data { + uint8_t ss_reg; + unsigned int ichg_ua; + unsigned int vreg_uv; + enum charger_status state; + enum charger_online online; +}; + +static int bq24190_register_reset(const struct device *dev) +{ + const struct bq24190_config *const config = dev->config; + int ret, limit = BQ24190_RESET_MAX_TRIES; + uint8_t val; + + ret = i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_POC, BQ24190_REG_POC_RESET_MASK, + BQ24190_REG_POC_RESET_MASK); + if (ret) { + return ret; + } + + /* + * No explicit reset timing characteristcs are provided in the datasheet. + * Instead, poll every 100µs for 100 attempts to see if the reset request + * bit has cleared. + */ + do { + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &val); + if (ret) { + return ret; + } + + if (!(val & BQ24190_REG_POC_RESET_MASK)) { + return 0; + } + + k_usleep(100); + } while (--limit); + + return -EIO; +} + +static int bq24190_charger_get_charge_type(const struct device *dev, + enum charger_charge_type *charge_type) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + *charge_type = CHARGER_CHARGE_TYPE_UNKNOWN; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_POC_CHG_CONFIG_MASK, v); + + if (!v) { + *charge_type = CHARGER_CHARGE_TYPE_NONE; + } else { + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_CCC_FORCE_20PCT_MASK, v); + + if (v) { + *charge_type = CHARGER_CHARGE_TYPE_TRICKLE; + } else { + *charge_type = CHARGER_CHARGE_TYPE_FAST; + } + } + + return 0; +} + +static int bq24190_charger_get_health(const struct device *dev, enum charger_health *health) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &v); + if (ret) { + return ret; + } + + if (v & BQ24190_REG_F_NTC_FAULT_MASK) { + switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) { + case BQ24190_NTC_FAULT_TS1_COLD: + case BQ24190_NTC_FAULT_TS2_COLD: + case BQ24190_NTC_FAULT_TS1_TS2_COLD: + *health = CHARGER_HEALTH_COLD; + break; + case BQ24190_NTC_FAULT_TS1_HOT: + case BQ24190_NTC_FAULT_TS2_HOT: + case BQ24190_NTC_FAULT_TS1_TS2_HOT: + *health = CHARGER_HEALTH_HOT; + break; + default: + *health = CHARGER_HEALTH_UNKNOWN; + } + } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) { + *health = CHARGER_HEALTH_OVERVOLTAGE; + } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) { + switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) { + case BQ24190_CHRG_FAULT_INPUT_FAULT: + /* + * This could be over-voltage or under-voltage + * and there's no way to tell which. Instead + * of looking foolish and returning 'OVERVOLTAGE' + * when its really under-voltage, just return + * 'UNSPEC_FAILURE'. + */ + *health = CHARGER_HEALTH_UNSPEC_FAILURE; + break; + case BQ24190_CHRG_FAULT_TSHUT: + *health = CHARGER_HEALTH_OVERHEAT; + break; + case BQ24190_CHRG_SAFETY_TIMER: + *health = CHARGER_HEALTH_SAFETY_TIMER_EXPIRE; + break; + default: /* prevent compiler warning */ + *health = CHARGER_HEALTH_UNKNOWN; + } + } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { + /* + * This could be over-current or over-voltage but there's + * no way to tell which. Return 'OVERVOLTAGE' since there + * isn't an 'OVERCURRENT' value defined that we can return + * even if it was over-current. + */ + *health = CHARGER_HEALTH_OVERVOLTAGE; + } else { + *health = CHARGER_HEALTH_GOOD; + } + + return 0; +} + +static int bq24190_charger_get_online(const struct device *dev, enum charger_online *online) +{ + const struct bq24190_config *const config = dev->config; + uint8_t pg_stat, batfet_disable; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &pg_stat); + if (ret) { + return ret; + } + + pg_stat = FIELD_GET(BQ24190_REG_SS_PG_STAT_MASK, pg_stat); + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_MOC, &batfet_disable); + if (ret) { + return ret; + } + + batfet_disable = FIELD_GET(BQ24190_REG_MOC_BATFET_DISABLE_MASK, batfet_disable); + + if (pg_stat && !batfet_disable) { + *online = CHARGER_ONLINE_FIXED; + } else { + *online = CHARGER_ONLINE_OFFLINE; + } + + return 0; +} + +static int bq24190_charger_get_status(const struct device *dev, enum charger_status *status) +{ + const struct bq24190_config *const config = dev->config; + uint8_t ss_reg, chrg_fault; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &chrg_fault); + if (ret) { + return ret; + } + + chrg_fault = FIELD_GET(BQ24190_REG_F_CHRG_FAULT_MASK, chrg_fault); + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &ss_reg); + if (ret) { + return ret; + } + + /* + * The battery must be discharging when any of these are true: + * - there is no good power source; + * - there is a charge fault. + * Could also be discharging when in "supplement mode" but + * there is no way to tell when its in that mode. + */ + if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) { + *status = CHARGER_STATUS_DISCHARGING; + } else { + ss_reg = FIELD_GET(BQ24190_REG_SS_CHRG_STAT_MASK, ss_reg); + + switch (ss_reg) { + case BQ24190_CHRG_STAT_NOT_CHRGING: + *status = CHARGER_STATUS_NOT_CHARGING; + break; + case BQ24190_CHRG_STAT_PRECHRG: + case BQ24190_CHRG_STAT_FAST_CHRG: + *status = CHARGER_STATUS_CHARGING; + break; + case BQ24190_CHRG_STAT_CHRG_TERM: + *status = CHARGER_STATUS_FULL; + break; + default: + return -EIO; + } + } + + return 0; +} + +static int bq24190_charger_get_constant_charge_current(const struct device *dev, + uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + bool frc_20pct; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK; + + v = FIELD_GET(BQ24190_REG_CCC_ICHG_MASK, v); + + *current_ua = (v * BQ24190_REG_CCC_ICHG_STEP_UA) + BQ24190_REG_CCC_ICHG_OFFSET_UA; + + if (frc_20pct) { + *current_ua /= 5; + } + + return 0; +} + +static int bq24190_charger_get_precharge_current(const struct device *dev, uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + bool frc_20pct; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_PCTCC_IPRECHG_MASK, v); + + *current_ua = (v * BQ24190_REG_PCTCC_IPRECHG_STEP_UA) + BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA; + + if (frc_20pct) { + *current_ua /= 2; + } + + return 0; +} + +static int bq24190_charger_get_charge_term_current(const struct device *dev, uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_PCTCC_ITERM_MASK, v); + + *current_ua = (v * BQ24190_REG_PCTCC_ITERM_STEP_UA) + BQ24190_REG_PCTCC_ITERM_OFFSET_UA; + + return 0; +} + +static int bq24190_get_constant_charge_voltage(const struct device *dev, uint32_t *voltage_uv) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CVC, &v); + if (ret < 0) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_CVC_VREG_MASK, v); + + *voltage_uv = (v * BQ24190_REG_CVC_VREG_STEP_UV) + BQ24190_REG_CVC_VREG_OFFSET_UV; + + return 0; +} + +static int bq24190_set_constant_charge_current(const struct device *dev, uint32_t current_ua) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret < 0) { + return ret; + } + + v &= BQ24190_REG_CCC_FORCE_20PCT_MASK; + + if (v) { + current_ua *= 5; + } + + current_ua = CLAMP(current_ua, BQ24190_REG_CCC_ICHG_MIN_UA, BQ24190_REG_CCC_ICHG_MAX_UA); + + v = (current_ua - BQ24190_REG_CCC_ICHG_OFFSET_UA) / BQ24190_REG_CCC_ICHG_STEP_UA; + + v = FIELD_PREP(BQ24190_REG_CCC_ICHG_MASK, v); + + return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CCC, BQ24190_REG_CCC_ICHG_MASK, v); +} + +static int bq24190_set_constant_charge_voltage(const struct device *dev, uint32_t voltage_uv) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + + voltage_uv = CLAMP(voltage_uv, BQ24190_REG_CVC_VREG_MIN_UV, BQ24190_REG_CVC_VREG_MAX_UV); + + v = (voltage_uv - BQ24190_REG_CVC_VREG_OFFSET_UV) / BQ24190_REG_CVC_VREG_STEP_UV; + + v = FIELD_PREP(BQ24190_REG_CVC_VREG_MASK, v); + + return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CVC, BQ24190_REG_CVC_VREG_MASK, v); +} + +static int bq24190_set_config(const struct device *dev) +{ + struct bq24190_data *data = dev->data; + union charger_propval val; + int ret; + + val.const_charge_current_ua = data->ichg_ua; + + ret = bq24190_set_constant_charge_current(dev, val.const_charge_current_ua); + if (ret < 0) { + return ret; + } + + val.const_charge_voltage_uv = data->vreg_uv; + + return bq24190_set_constant_charge_voltage(dev, val.const_charge_voltage_uv); +} + +static int bq24190_get_prop(const struct device *dev, charger_prop_t prop, + union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_ONLINE: + return bq24190_charger_get_online(dev, &val->online); + case CHARGER_PROP_CHARGE_TYPE: + return bq24190_charger_get_charge_type(dev, &val->charge_type); + case CHARGER_PROP_HEALTH: + return bq24190_charger_get_health(dev, &val->health); + case CHARGER_PROP_STATUS: + return bq24190_charger_get_status(dev, &val->status); + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return bq24190_charger_get_constant_charge_current(dev, + &val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return bq24190_get_constant_charge_voltage(dev, &val->const_charge_voltage_uv); + case CHARGER_PROP_PRECHARGE_CURRENT_UA: + return bq24190_charger_get_precharge_current(dev, &val->precharge_current_ua); + case CHARGER_PROP_CHARGE_TERM_CURRENT_UA: + return bq24190_charger_get_charge_term_current(dev, &val->charge_term_current_ua); + default: + return -ENOTSUP; + } +} + +static int bq24190_set_prop(const struct device *dev, charger_prop_t prop, + const union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return bq24190_set_constant_charge_current(dev, val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return bq24190_set_constant_charge_voltage(dev, val->const_charge_voltage_uv); + default: + return -ENOTSUP; + } +} + +static int bq24190_init(const struct device *dev) +{ + const struct bq24190_config *const config = dev->config; + struct bq24190_data *data = dev->data; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_VPRS, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(BQ24190_REG_VPRS_PN_MASK, val); + + switch (val) { + case BQ24190_REG_VPRS_PN_24190: + case BQ24190_REG_VPRS_PN_24192: + case BQ24190_REG_VPRS_PN_24192I: + break; + default: + LOG_ERR("Error unknown model: 0x%02x\n", val); + return -ENODEV; + } + + ret = bq24190_register_reset(dev); + if (ret) { + return ret; + } + + ret = bq24190_set_config(dev); + if (ret) { + return ret; + } + + return i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &data->ss_reg); +} + +static const struct charger_driver_api bq24190_driver_api = { + .get_property = &bq24190_get_prop, + .set_property = &bq24190_set_prop, +}; + +#define BQ24190_INIT(inst) \ + \ + static const struct bq24190_config bq24190_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + static struct bq24190_data bq24190_data_##inst = { \ + .ichg_ua = DT_INST_PROP(inst, constant_charge_current_max_microamp), \ + .vreg_uv = DT_INST_PROP(inst, constant_charge_voltage_max_microvolt), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &bq24190_init, NULL, &bq24190_data_##inst, \ + &bq24190_config_##inst, POST_KERNEL, CONFIG_CHARGER_INIT_PRIORITY, \ + &bq24190_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BQ24190_INIT) diff --git a/drivers/charger/bq24190.h b/drivers/charger/bq24190.h new file mode 100644 index 00000000000..06d5d3ba299 --- /dev/null +++ b/drivers/charger/bq24190.h @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CHARGER_BQ24190_H_ +#define ZEPHYR_DRIVERS_CHARGER_BQ24190_H_ + +/* Input Source Control */ +#define BQ24190_REG_ISC 0x00 +#define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7) +#define BQ24190_REG_ISC_EN_HIZ_SHIFT 7 +#define BQ24190_REG_ISC_VINDPM_MASK GENMASK(6, 3) +#define BQ24190_REG_ISC_VINDPM_SHIFT 3 +#define BQ24190_REG_ISC_IINLIM_MASK GENMASK(2, 0) + +/* Power-On Configuration */ +#define BQ24190_REG_POC 0x01 +#define BQ24190_REG_POC_RESET_MASK BIT(7) +#define BQ24190_REG_POC_RESET_SHIFT 7 +#define BQ24190_RESET_MAX_TRIES 100 +#define BQ24190_REG_POC_WDT_RESET_MASK BIT(6) +#define BQ24190_REG_POC_WDT_RESET_SHIFT 6 +#define BQ24190_REG_POC_CHG_CONFIG_MASK GENMASK(5, 4) +#define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4 +#define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0 +#define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1 +#define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2 +#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3 +#define BQ24190_REG_POC_SYS_MIN_MASK GENMASK(3, 1) +#define BQ24190_REG_POC_SYS_MIN_SHIFT 1 +#define BQ24190_REG_POC_SYS_MIN_MIN_UV 3000000 +#define BQ24190_REG_POC_SYS_MIN_MAX_UV 3700000 +#define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0) +#define BQ24190_REG_POC_BOOST_LIM_SHIFT 0 + +/* Charge Current Control */ +#define BQ24190_REG_CCC 0x02 +#define BQ24190_REG_CCC_ICHG_MASK GENMASK(7, 2) +#define BQ24190_REG_CCC_ICHG_SHIFT 2 +#define BQ24190_REG_CCC_ICHG_STEP_UA 64000 +#define BQ24190_REG_CCC_ICHG_OFFSET_UA 512000 +#define BQ24190_REG_CCC_ICHG_MIN_UA BQ24190_REG_CCC_ICHG_OFFSET_UA +#define BQ24190_REG_CCC_ICHG_MAX_UA 4544000 +#define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0) +#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0 + +/* Pre-charge/Termination Current Cntl */ +#define BQ24190_REG_PCTCC 0x03 +#define BQ24190_REG_PCTCC_IPRECHG_MASK GENMASK(7, 4) +#define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4 +#define BQ24190_REG_PCTCC_IPRECHG_STEP_UA 128000 +#define BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA 128000 +#define BQ24190_REG_PCTCC_IPRECHG_MIN_UA BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA +#define BQ24190_REG_PCTCC_IPRECHG_MAX_UA 2048000 +#define BQ24190_REG_PCTCC_ITERM_MASK GENMASK(3, 0) +#define BQ24190_REG_PCTCC_ITERM_SHIFT 0 +#define BQ24190_REG_PCTCC_ITERM_STEP_UA 128000 +#define BQ24190_REG_PCTCC_ITERM_OFFSET_UA 128000 +#define BQ24190_REG_PCTCC_ITERM_MIN_UA BQ24190_REG_PCTCC_ITERM_OFFSET_UA +#define BQ24190_REG_PCTCC_ITERM_MAX_UA 2048000 + +/* Charge Voltage Control */ +#define BQ24190_REG_CVC 0x04 +#define BQ24190_REG_CVC_VREG_MASK GENMASK(7, 2) +#define BQ24190_REG_CVC_VREG_SHIFT 2 +#define BQ24190_REG_CVC_VREG_STEP_UV 16000 +#define BQ24190_REG_CVC_VREG_OFFSET_UV 3504000 +#define BQ24190_REG_CVC_VREG_MIN_UV BQ24190_REG_CVC_VREG_OFFSET_UV +#define BQ24190_REG_CVC_VREG_MAX_UV 4400000 +#define BQ24190_REG_CVC_BATLOWV_MASK BIT(1) +#define BQ24190_REG_CVC_BATLOWV_SHIFT 1 +#define BQ24190_REG_CVC_VRECHG_MASK BIT(0) +#define BQ24190_REG_CVC_VRECHG_SHIFT 0 + +/* Charge Term/Timer Control */ +#define BQ24190_REG_CTTC 0x05 +#define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7) +#define BQ24190_REG_CTTC_EN_TERM_SHIFT 7 +#define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6) +#define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6 +#define BQ24190_REG_CTTC_WATCHDOG_MASK GENMASK(5, 4) +#define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4 +#define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3) +#define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3 +#define BQ24190_REG_CTTC_CHG_TIMER_MASK GENMASK(2, 1) +#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1 +#define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0) +#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0 + +/* IR Comp/Thermal Regulation Control */ +#define BQ24190_REG_ICTRC 0x06 +#define BQ24190_REG_ICTRC_BAT_COMP_MASK GENMASK(7, 5) +#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5 +#define BQ24190_REG_ICTRC_VCLAMP_MASK GENMASK(4, 2) +#define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2 +#define BQ24190_REG_ICTRC_TREG_MASK GENMASK(1, 0) +#define BQ24190_REG_ICTRC_TREG_SHIFT 0 + +/* Misc. Operation Control */ +#define BQ24190_REG_MOC 0x07 +#define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7) +#define BQ24190_REG_MOC_DPDM_EN_SHIFT 7 +#define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6) +#define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6 +#define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5) +#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5 +#define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4) +#define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4 +#define BQ24190_REG_MOC_INT_MASK_MASK GENMASK(1, 0) +#define BQ24190_REG_MOC_INT_MASK_SHIFT 0 + +/* System Status */ +#define BQ24190_REG_SS 0x08 +#define BQ24190_REG_SS_VBUS_STAT_MASK GENMASK(7, 6) +#define BQ24190_REG_SS_VBUS_STAT_SHIFT 6 +#define BQ24190_REG_SS_CHRG_STAT_MASK GENMASK(5, 4) +#define BQ24190_REG_SS_CHRG_STAT_SHIFT 4 +#define BQ24190_CHRG_STAT_NOT_CHRGING 0x0 +#define BQ24190_CHRG_STAT_PRECHRG 0x1 +#define BQ24190_CHRG_STAT_FAST_CHRG 0x2 +#define BQ24190_CHRG_STAT_CHRG_TERM 0x3 +#define BQ24190_REG_SS_DPM_STAT_MASK BIT(3) +#define BQ24190_REG_SS_DPM_STAT_SHIFT 3 +#define BQ24190_REG_SS_PG_STAT_MASK BIT(2) +#define BQ24190_REG_SS_PG_STAT_SHIFT 2 +#define BQ24190_REG_SS_THERM_STAT_MASK BIT(1) +#define BQ24190_REG_SS_THERM_STAT_SHIFT 1 +#define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0) +#define BQ24190_REG_SS_VSYS_STAT_SHIFT 0 + +/* Fault */ +#define BQ24190_REG_F 0x09 +#define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7) +#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7 +#define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6) +#define BQ24190_REG_F_BOOST_FAULT_SHIFT 6 +#define BQ24190_REG_F_CHRG_FAULT_MASK GENMASK(5, 4) +#define BQ24190_REG_F_CHRG_FAULT_SHIFT 4 +#define BQ24190_CHRG_FAULT_INPUT_FAULT 0x1 +#define BQ24190_CHRG_FAULT_TSHUT 0x2 +#define BQ24190_CHRG_SAFETY_TIMER 0x3 +#define BQ24190_REG_F_BAT_FAULT_MASK BIT(3) +#define BQ24190_REG_F_BAT_FAULT_SHIFT 3 +#define BQ24190_REG_F_NTC_FAULT_MASK GENMASK(2, 0) +#define BQ24190_REG_F_NTC_FAULT_SHIFT 0 +#define BQ24190_NTC_FAULT_TS1_COLD 0x1 +#define BQ24190_NTC_FAULT_TS1_HOT 0x2 +#define BQ24190_NTC_FAULT_TS2_COLD 0x3 +#define BQ24190_NTC_FAULT_TS2_HOT 0x4 +#define BQ24190_NTC_FAULT_TS1_TS2_COLD 0x5 +#define BQ24190_NTC_FAULT_TS1_TS2_HOT 0x6 + +/* Vendor/Part/Revision Status */ +#define BQ24190_REG_VPRS 0x0A +#define BQ24190_REG_VPRS_PN_MASK GENMASK(5, 3) +#define BQ24190_REG_VPRS_PN_SHIFT 3 +#define BQ24190_REG_VPRS_PN_24190 0x4 +#define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193, 24196 */ +#define BQ24190_REG_VPRS_PN_24192I 0x3 +#define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2) +#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2 +#define BQ24190_REG_VPRS_DEV_REG_MASK GENMASK(1, 0) +#define BQ24190_REG_VPRS_DEV_REG_SHIFT 0 + +#endif From 2107c9109fc0ff05e678d76bca5110ddd03a6926 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 4 Oct 2023 15:10:46 -0500 Subject: [PATCH 2147/4498] samples: charger: Creates a generic sample application for chargers Creates a generic sample application that executes a simple charging task loop capable of completing a basic charge cycle. Signed-off-by: Ricardo Rivera-Matos --- samples/charger/CMakeLists.txt | 9 +++ samples/charger/prj.conf | 1 + samples/charger/sample.yaml | 6 ++ samples/charger/src/main.c | 101 +++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 samples/charger/CMakeLists.txt create mode 100644 samples/charger/prj.conf create mode 100644 samples/charger/sample.yaml create mode 100644 samples/charger/src/main.c diff --git a/samples/charger/CMakeLists.txt b/samples/charger/CMakeLists.txt new file mode 100644 index 00000000000..e0f9e77b374 --- /dev/null +++ b/samples/charger/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(charger) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/charger/prj.conf b/samples/charger/prj.conf new file mode 100644 index 00000000000..922c6f65a09 --- /dev/null +++ b/samples/charger/prj.conf @@ -0,0 +1 @@ +CONFIG_CHARGER=y diff --git a/samples/charger/sample.yaml b/samples/charger/sample.yaml new file mode 100644 index 00000000000..18ab714b99c --- /dev/null +++ b/samples/charger/sample.yaml @@ -0,0 +1,6 @@ +sample: + name: Generic charger +tests: + sample.drivers.charger: + tags: charger + depends_on: charger diff --git a/samples/charger/src/main.c b/samples/charger/src/main.c new file mode 100644 index 00000000000..4f24e1932d9 --- /dev/null +++ b/samples/charger/src/main.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "zephyr/sys/printk.h" +#include +#include +#include +#include +#include + +static const struct device *chgdev = DEVICE_DT_GET(DT_NODELABEL(charger)); + +int main(void) +{ + union charger_propval val; + int ret; + + if (chgdev == NULL) { + printk("Error: no charger device found.\n"); + return 0; + } + + if (!device_is_ready(chgdev)) { + printk("Error: Device \"%s\" is not ready; " + "check the driver initialization logs for errors.\n", + chgdev->name); + return 0; + } + + printk("Found device \"%s\", getting charger data\n", chgdev->name); + + while (1) { + /* Poll until external power is presented to the charger */ + do { + ret = charger_get_prop(chgdev, CHARGER_PROP_ONLINE, &val); + if (ret < 0) { + return ret; + } + + k_msleep(100); + } while (val.online == CHARGER_ONLINE_OFFLINE); + + val.status = CHARGER_STATUS_CHARGING; + + ret = charger_set_prop(chgdev, CHARGER_PROP_STATUS, &val); + if (ret == -ENOTSUP) { + printk("Enabling charge not supported, assuming auto charge enable\n"); + continue; + } else if (ret < 0) { + return ret; + } + + k_msleep(500); + + ret = charger_get_prop(chgdev, CHARGER_PROP_STATUS, &val); + if (ret < 0) { + return ret; + } + + switch (val.status) { + case CHARGER_STATUS_CHARGING: + printk("Charging in progress...\n"); + + ret = charger_get_prop(chgdev, CHARGER_PROP_CHARGE_TYPE, &val); + if (ret < 0) { + return ret; + } + + printk("Device \"%s\" charge type is %d\n", chgdev->name, val.charge_type); + break; + case CHARGER_STATUS_NOT_CHARGING: + printk("Charging halted...\n"); + + ret = charger_get_prop(chgdev, CHARGER_PROP_HEALTH, &val); + if (ret < 0) { + return ret; + } + + printk("Device \"%s\" health is %d\n", chgdev->name, val.health); + break; + case CHARGER_STATUS_FULL: + printk("Charging complete!"); + return 0; + case CHARGER_STATUS_DISCHARGING: + printk("External power removed, discharging\n"); + + ret = charger_get_prop(chgdev, CHARGER_PROP_ONLINE, &val); + if (ret < 0) { + return ret; + } + break; + default: + return -EIO; + } + + k_msleep(500); + } +} From e8e907b5a5623a0bcce0b10228e6d9cf722ecefe Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 4 Oct 2023 16:39:36 -0500 Subject: [PATCH 2148/4498] tests: build_all: charger: Builds BQ24190 driver Adds the BQ24190 driver to the build_all test. Signed-off-by: Ricardo Rivera-Matos --- .../drivers/build_all/charger/CMakeLists.txt | 8 +++++++ tests/drivers/build_all/charger/app.overlay | 24 +++++++++++++++++++ tests/drivers/build_all/charger/i2c.dtsi | 17 +++++++++++++ tests/drivers/build_all/charger/prj.conf | 1 + tests/drivers/build_all/charger/src/main.c | 9 +++++++ tests/drivers/build_all/charger/testcase.yaml | 10 ++++++++ 6 files changed, 69 insertions(+) create mode 100644 tests/drivers/build_all/charger/CMakeLists.txt create mode 100644 tests/drivers/build_all/charger/app.overlay create mode 100644 tests/drivers/build_all/charger/i2c.dtsi create mode 100644 tests/drivers/build_all/charger/prj.conf create mode 100644 tests/drivers/build_all/charger/src/main.c create mode 100644 tests/drivers/build_all/charger/testcase.yaml diff --git a/tests/drivers/build_all/charger/CMakeLists.txt b/tests/drivers/build_all/charger/CMakeLists.txt new file mode 100644 index 00000000000..65cdb555717 --- /dev/null +++ b/tests/drivers/build_all/charger/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(build_all) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/build_all/charger/app.overlay b/tests/drivers/build_all/charger/app.overlay new file mode 100644 index 00000000000..1df6a67da98 --- /dev/null +++ b/tests/drivers/build_all/charger/app.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + + #include + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_i2c: i2c@11112222 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "vnd,i2c"; + reg = <0x11112222 0x1000>; + status = "okay"; + clock-frequency = ; + + #include "i2c.dtsi" + }; + }; +}; diff --git a/tests/drivers/build_all/charger/i2c.dtsi b/tests/drivers/build_all/charger/i2c.dtsi new file mode 100644 index 00000000000..53cbcf0e59b --- /dev/null +++ b/tests/drivers/build_all/charger/i2c.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/**************************************** + * PLEASE KEEP REG ADDRESSES SEQUENTIAL * + ***************************************/ + +bq24190@0 { + compatible = "ti,bq24190"; + reg = <0x0>; + status = "okay"; + + constant-charge-current-max-microamp = <1000000>; + constant-charge-voltage-max-microvolt = <4208000>; +}; diff --git a/tests/drivers/build_all/charger/prj.conf b/tests/drivers/build_all/charger/prj.conf new file mode 100644 index 00000000000..922c6f65a09 --- /dev/null +++ b/tests/drivers/build_all/charger/prj.conf @@ -0,0 +1 @@ +CONFIG_CHARGER=y diff --git a/tests/drivers/build_all/charger/src/main.c b/tests/drivers/build_all/charger/src/main.c new file mode 100644 index 00000000000..504c9ebc22c --- /dev/null +++ b/tests/drivers/build_all/charger/src/main.c @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + return 0; +} diff --git a/tests/drivers/build_all/charger/testcase.yaml b/tests/drivers/build_all/charger/testcase.yaml new file mode 100644 index 00000000000..f2005d9f238 --- /dev/null +++ b/tests/drivers/build_all/charger/testcase.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.charger.build: + tags: + - drivers + - charger + build_only: true + platform_allow: native_posix From d75127caa4ae1db13ed5111b0327216cc94501e2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 13 Sep 2023 14:53:14 +0300 Subject: [PATCH 2149/4498] drivers: intel: ssp: Correct FIFO depth value for CAVS25 platforms The actual FIFO depth in Tiger Lake platforms is 32 and not 16. Signed-off-by: Peter Ujfalusi --- drivers/dai/intel/ssp/ssp.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index 1d37b9a3335..4f08553c91f 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -29,7 +29,11 @@ #define DAI_INTEL_SSP_DEFAULT_IDX 1 /* the SSP port fifo depth */ +#if (CONFIG_BOARD_INTEL_ADSP_CAVS25 || CONFIG_BOARD_INTEL_ADSP_CAVS25_TGPH) +#define DAI_INTEL_SSP_FIFO_DEPTH 32 +#else #define DAI_INTEL_SSP_FIFO_DEPTH 16 +#endif /* the watermark for the SSP fifo depth setting */ #define DAI_INTEL_SSP_FIFO_WATERMARK 8 From 97bb67d66cd7461b8cbc7fb72c4b6773013d6dd4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 13 Sep 2023 14:54:37 +0300 Subject: [PATCH 2150/4498] drivers: intel: ssp: Revise receive FIFO draining The receive FIFO needs to be drained in a different way depending when it is done. - before start If the RX FIFO is in overflow state then we must read all the entries out to empty it (it was after all full). - before stop The DMA might be already running to read out data. Check the FIFO level change in one sample time which gives us the needed information to decide to wait for another loop for the DMA burst to finish, wait for the DMA to start it's burst (DMA request was asserted) or drain the FIFO directly. No need to drain the RX fifo at probe time. Signed-off-by: Peter Ujfalusi --- drivers/dai/intel/ssp/ssp.c | 89 ++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 809cc9833eb..b39442b0011 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -837,36 +837,73 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) } } -/* empty SSP receive FIFO */ -static void dai_ssp_empty_rx_fifo(struct dai_intel_ssp *dp) +static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) { - struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp); uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; - uint32_t entries; - uint32_t i; + uint32_t i, sssr; - /* - * To make sure all the RX FIFO entries are read out for the flushing, - * we need to wait a minimal SSP port delay after entries are all read, - * and then re-check to see if there is any subsequent entries written - * to the FIFO. This will help to make sure there is no sample mismatched - * issue for the next run with the SSP RX. - */ - while ((sys_read32(dai_base(dp) + SSSR) & SSSR_RNE) && retry--) { - entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); - LOG_DBG("%s before flushing, entries %d", __func__, entries); - for (i = 0; i < entries + 1; i++) { - /* read to try empty fifo */ + sssr = sys_read32(dai_base(dp) + SSSR); + + if (sssr & SSSR_ROR) { + /* The RX FIFO is in overflow condition, empty it */ + for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++) sys_read32(dai_base(dp) + SSDR); + + /* Clear the overflow status */ + dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); + /* Re-read the SSSR register */ + sssr = sys_read32(dai_base(dp) + SSSR); + } + + while ((sssr & SSSR_RNE) && retry--) { + uint32_t entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); + + /* Empty the RX FIFO (the DMA is not running at this point) */ + for (i = 0; i < entries + 1; i++) + sys_read32(dai_base(dp) + SSDR); + + sssr = sys_read32(dai_base(dp) + SSSR); + } +} + +static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) +{ + struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp); + uint64_t sample_ticks = ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0; + uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; + uint32_t entries[2]; + uint32_t i, sssr; + + sssr = sys_read32(dai_base(dp) + SSSR); + entries[0] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); + + while ((sssr & SSSR_RNE) && retry--) { + /* Wait one sample time */ + k_busy_wait(sample_ticks); + + entries[1] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); + sssr = sys_read32(dai_base(dp) + SSSR); + + if (entries[0] > entries[1]) { + /* + * The DMA is reading the FIFO, check the status in the + * next loop + */ + entries[0] = entries[1]; + } else if (!(sssr & SSSR_RFS)) { + /* + * The DMA request is not asserted, read the FIFO + * directly, otherwise let the next loop iteration to + * check the status + */ + for (i = 0; i < entries[1] + 1; i++) + sys_read32(dai_base(dp) + SSDR); } - /* wait to get valid fifo status and re-check */ - k_busy_wait(ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0); - entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); - LOG_DBG("%s after flushing, entries %d", __func__, entries); + sssr = sys_read32(dai_base(dp) + SSSR); } - /* clear interrupt */ + /* Just in case clear the overflow status */ dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); } @@ -1901,6 +1938,10 @@ static void dai_ssp_early_start(struct dai_intel_ssp *dp, int direction) key = k_spin_lock(&dp->lock); + /* RX fifo must be cleared before start */ + if (direction == DAI_DIR_CAPTURE) + ssp_empty_rx_fifo_on_start(dp); + /* request mclk/bclk */ dai_ssp_pre_start(dp); @@ -1981,7 +2022,7 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_CAPTURE && ssp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0); - dai_ssp_empty_rx_fifo(dp); + ssp_empty_rx_fifo_on_stop(dp); ssp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; LOG_INF("%s RX stop", __func__); } @@ -2159,8 +2200,6 @@ static int dai_ssp_probe(struct dai_intel_ssp *dp) /* Disable dynamic clock gating before touching any register */ dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, dp->index); - dai_ssp_empty_rx_fifo(dp); - return 0; } From 2a86016aff8b81d7f18b989c6188cf4a1c2fb055 Mon Sep 17 00:00:00 2001 From: Ye Weize Date: Wed, 27 Sep 2023 10:36:32 +0800 Subject: [PATCH 2151/4498] drivers: spi: Add Intel SEDI driver Add a new SPI shim driver for Intel SoCs. Builds upon the SEDI bare metal SPI driver in the hal-intel module. Co-Authored-By: Kong Li Signed-off-by: Ye Weize --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 2 + drivers/spi/Kconfig.sedi | 14 + drivers/spi/spi_sedi.c | 415 +++++++++++++++++++++++++++ dts/bindings/spi/intel,sedi-spi.yaml | 23 ++ dts/x86/intel/intel_ish5.dtsi | 24 ++ dts/x86/intel/intel_ish5_8.dtsi | 12 + 7 files changed, 491 insertions(+) create mode 100644 drivers/spi/Kconfig.sedi create mode 100644 drivers/spi/spi_sedi.c create mode 100644 dts/bindings/spi/intel,sedi-spi.yaml diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index 269b28549eb..956b6d3397a 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -49,3 +49,4 @@ zephyr_library_sources_ifdef(CONFIG_SPI_RTIO spi_rtio.c) zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c) zephyr_library_sources_ifdef(CONFIG_SPI_INFINEON_CAT1 spi_ifx_cat1.c) +zephyr_library_sources_ifdef(CONFIG_SPI_SEDI spi_sedi.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 75f7993ef27..24982cae90e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -135,4 +135,6 @@ source "drivers/spi/Kconfig.rpi_pico" source "drivers/spi/Kconfig.ifx_cat1" +source "drivers/spi/Kconfig.sedi" + endif # SPI diff --git a/drivers/spi/Kconfig.sedi b/drivers/spi/Kconfig.sedi new file mode 100644 index 00000000000..a9f9ca6c90a --- /dev/null +++ b/drivers/spi/Kconfig.sedi @@ -0,0 +1,14 @@ +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SPI_SEDI + bool "Intel SEDI SPI driver" + default y + depends on DT_HAS_INTEL_SEDI_SPI_ENABLED + help + This option enables the Intel SEDI SPI driver. + This driver is simply a shim driver built upon the SEDI + bare metal SPI driver in the hal-intel module diff --git a/drivers/spi/spi_sedi.c b/drivers/spi/spi_sedi.c new file mode 100644 index 00000000000..b3c4d22f730 --- /dev/null +++ b/drivers/spi/spi_sedi.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_sedi_spi + +#include +#include +#include + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +#include +LOG_MODULE_REGISTER(spi_sedi); + +#include "sedi_driver_spi.h" +#include "spi_context.h" + + +struct spi_sedi_config { + DEVICE_MMIO_ROM; + sedi_spi_t spi_device; + void (*irq_config)(void); +}; + +struct spi_sedi_data { + DEVICE_MMIO_RAM; + struct spi_context ctx; + bool tx_data_updated; + bool rx_data_updated; + uint32_t tx_dummy_len; + uint32_t rx_dummy_len; +}; + +static int spi_sedi_configure(const struct device *dev, + const struct spi_config *config) +{ + struct spi_sedi_data *data = dev->data; + const struct spi_sedi_config *info = dev->config; + uint32_t word_size, cpol, cpha, loopback; + + if (spi_context_configured(&data->ctx, config) == true) { + return 0; + } + + word_size = SPI_WORD_SIZE_GET(config->operation); + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_DATA_WIDTH, + word_size); + + /* CPOL and CPHA */ + cpol = SPI_MODE_GET(config->operation) & SPI_MODE_CPOL; + cpha = SPI_MODE_GET(config->operation) & SPI_MODE_CPHA; + + if ((cpol == 0) && (cpha == 0)) { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_CPOL0_CPHA0, + 0); + } else if ((cpol == 0) && (cpha == 1U)) { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_CPOL0_CPHA1, + 0); + } else if ((cpol == 1) && (cpha == 0U)) { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_CPOL1_CPHA0, + 0); + } else { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_CPOL1_CPHA1, + 0); + } + + /* MSB and LSB */ + if (config->operation & SPI_TRANSFER_LSB) { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_LSB, 0); + } + + /* Set loopack */ + loopback = SPI_MODE_GET(config->operation) & SPI_MODE_LOOP; + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_LOOPBACK, loopback); + + /* Set baudrate */ + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_SPEED_SET, + config->frequency); + + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_CS_HW, config->slave); + + data->ctx.config = config; + spi_context_cs_control(&data->ctx, true); + + return 0; +} + +static int transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, bool asynchronous, + spi_callback_t cb, + void *userdata) +{ + const struct spi_sedi_config *info = dev->config; + struct spi_sedi_data *spi = dev->data; + struct spi_context *ctx = &spi->ctx; + int ret; + uint32_t transfer_bytes = 0; + uint8_t *data_out = NULL, *data_in = NULL; + uint32_t i, dummy_len = 0; + const struct spi_buf *buf; + bool is_multibufs = false; + + spi_context_lock(&spi->ctx, asynchronous, cb, userdata, config); + pm_device_busy_set(dev); + + /* Power up use default setting */ + ret = sedi_spi_set_power(info->spi_device, SEDI_POWER_FULL); + if (ret) { + goto out; + } + + /* If need to configure, re-configure */ + spi_sedi_configure(dev, config); + + spi->tx_data_updated = false; + spi->rx_data_updated = false; + /* Set buffers info */ + spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, 1); + + if ((ctx->tx_count > 1) || (ctx->rx_count > 1)) { + is_multibufs = true; + } + + if (ctx->tx_count > ctx->rx_count) { + spi->tx_dummy_len = 0; + for (i = ctx->rx_count; i < ctx->tx_count; i++) { + buf = ctx->current_tx + i; + dummy_len += buf->len; + } + spi->rx_dummy_len = dummy_len; + } else if (ctx->tx_count < ctx->rx_count) { + spi->rx_dummy_len = 0; + for (i = ctx->tx_count; i < ctx->rx_count; i++) { + buf = ctx->current_rx + i; + dummy_len += buf->len; + } + spi->tx_dummy_len = dummy_len; + } else { + spi->tx_dummy_len = 0; + spi->rx_dummy_len = 0; + } + + if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { + spi_context_cs_control(&spi->ctx, true); + spi_context_complete(&spi->ctx, dev, 0); + return 0; + } + + /* For multiple buffers, using continuous mode */ + if (is_multibufs) { + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_BUFFER_SETS, 1); + } + + if (ctx->tx_len == 0) { + /* rx only, nothing to tx */ + data_out = NULL; + data_in = (uint8_t *)ctx->rx_buf; + transfer_bytes = ctx->rx_len; + spi->tx_dummy_len -= transfer_bytes; + } else if (ctx->rx_len == 0) { + /* tx only, nothing to rx */ + data_out = (uint8_t *)ctx->tx_buf; + data_in = NULL; + transfer_bytes = ctx->tx_len; + spi->rx_dummy_len -= transfer_bytes; + } else if (ctx->tx_len == ctx->rx_len) { + /* rx and tx are the same length */ + data_out = (uint8_t *)ctx->tx_buf; + data_in = (uint8_t *)ctx->rx_buf; + transfer_bytes = ctx->tx_len; + } else if (ctx->tx_len > ctx->rx_len) { + /* Break up the tx into multiple transfers so we don't have to + * rx into a longer intermediate buffer. Leave chip select + * active between transfers. + */ + data_out = (uint8_t *)ctx->tx_buf; + data_in = ctx->rx_buf; + transfer_bytes = ctx->rx_len; + } else { + /* Break up the rx into multiple transfers so we don't have to + * tx from a longer intermediate buffer. Leave chip select + * active between transfers. + */ + data_out = (uint8_t *)ctx->tx_buf; + data_in = ctx->rx_buf; + transfer_bytes = ctx->tx_len; + } + + spi_context_cs_control(&spi->ctx, false); + + ret = sedi_spi_transfer(info->spi_device, data_out, data_in, + transfer_bytes); + + if (ret != SEDI_DRIVER_OK) { + goto out; + } + + ret = spi_context_wait_for_completion(&spi->ctx); + if (ret != 0) { + sedi_spi_status_t spi_status = {0}; + + sedi_spi_get_status(info->spi_device, &spi_status); + + /* SPI ABORT */ + sedi_spi_control(info->spi_device, SEDI_SPI_IOCTL_ABORT, 0); + /* Toggle GPIO back */ + spi_context_cs_control(&spi->ctx, true); + } +out: + spi_context_release(&spi->ctx, ret); + pm_device_busy_clear(dev); + + return ret; +} + +static int spi_sedi_transceive(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_sedi_transceive_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + spi_callback_t cb, + void *userdata) +{ + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_sedi_release(const struct device *dev, + const struct spi_config *config) +{ + struct spi_sedi_data *spi = dev->data; + + if (!spi_context_configured(&spi->ctx, config)) { + return -EINVAL; + } + + spi_context_unlock_unconditionally(&spi->ctx); + + return 0; +} + +extern void spi_isr(sedi_spi_t device); + +void spi_sedi_callback(uint32_t event, void *param) +{ + const struct device *dev = (const struct device *)param; + const struct spi_sedi_config *info = dev->config; + struct spi_sedi_data *spi = dev->data; + struct spi_context *ctx = &spi->ctx; + int error; + + if (event == SEDI_SPI_EVENT_DATA_LOST) { + error = -EIO; + } else { + error = 0; + } + + if ((event == SEDI_SPI_EVENT_COMPLETE) || + (event == SEDI_SPI_EVENT_DATA_LOST)) { + spi_context_cs_control(&spi->ctx, true); + spi_context_complete(&spi->ctx, dev, error); + } else if (event == SEDI_SPI_EVENT_TX_FINISHED) { + spi_context_update_tx(ctx, 1, ctx->tx_len); + if (ctx->tx_len != 0) { + sedi_spi_update_tx_buf(info->spi_device, ctx->tx_buf, + ctx->tx_len); + if ((ctx->rx_len == 0) && + (spi->rx_data_updated == false)) { + /* Update rx length if always no rx */ + sedi_spi_update_rx_buf(info->spi_device, NULL, + spi->rx_dummy_len); + spi->rx_data_updated = true; + } + } else if (spi->tx_data_updated == false) { + sedi_spi_update_tx_buf(info->spi_device, NULL, + spi->tx_dummy_len); + spi->tx_data_updated = true; + } + } else if (event == SEDI_SPI_EVENT_RX_FINISHED) { + spi_context_update_rx(ctx, 1, ctx->rx_len); + if (ctx->rx_len != 0) { + sedi_spi_update_rx_buf(info->spi_device, ctx->rx_buf, + ctx->rx_len); + } + } +} + +static const struct spi_driver_api sedi_spi_api = { + .transceive = spi_sedi_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_sedi_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ + .release = spi_sedi_release, +}; + +static int spi_sedi_init(const struct device *dev) +{ + const struct spi_sedi_config *info = dev->config; + struct spi_sedi_data *spi = dev->data; + int ret; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + ret = sedi_spi_init(info->spi_device, spi_sedi_callback, (void *)dev, + DEVICE_MMIO_GET(dev)); + if (ret != SEDI_DRIVER_OK) { + return -ENODEV; + } + + /* Init and connect IRQ */ + info->irq_config(); + + spi_context_unlock_unconditionally(&spi->ctx); + + return 0; +} + +#ifdef CONFIG_PM_DEVICE + +static int spi_suspend_device(const struct device *dev) +{ + const struct spi_sedi_config *config = dev->config; + + if (pm_device_is_busy(dev)) { + return -EBUSY; + } + + int ret = sedi_spi_set_power(config->spi_device, SEDI_POWER_SUSPEND); + + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + return 0; +} + +static int spi_resume_device_from_suspend(const struct device *dev) +{ + const struct spi_sedi_config *config = dev->config; + int ret; + + ret = sedi_spi_set_power(config->spi_device, SEDI_POWER_FULL); + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + pm_device_busy_clear(dev); + + return 0; +} + +static int spi_sedi_device_ctrl(const struct device *dev, + enum pm_device_action action) +{ + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = spi_suspend_device(dev); + break; + case PM_DEVICE_ACTION_RESUME: + ret = spi_resume_device_from_suspend(dev); + break; + default: + ret = -ENOTSUP; + } + + return ret; +} + +#endif /* CONFIG_PM_DEVICE */ + +#define SPI_SEDI_IRQ_FLAGS_SENSE0(n) 0 +#define SPI_SEDI_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) +#define SPI_SEDI_IRQ_FLAGS(n) \ + _CONCAT(SPI_SEDI_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + +#define CREATE_SEDI_SPI_INSTANCE(num) \ + static void spi_##num##_irq_init(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(num), \ + DT_INST_IRQ(num, priority), \ + spi_isr, num, SPI_SEDI_IRQ_FLAGS(num)); \ + irq_enable(DT_INST_IRQN(num)); \ + } \ + static struct spi_sedi_data spi_##num##_data = { \ + SPI_CONTEXT_INIT_LOCK(spi_##num##_data, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_##num##_data, ctx), \ + }; \ + const static struct spi_sedi_config spi_##num##_config = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(num)), \ + .spi_device = num, .irq_config = spi_##num##_irq_init, \ + }; \ + PM_DEVICE_DEFINE(spi_##num, spi_sedi_device_ctrl); \ + DEVICE_DT_INST_DEFINE(num, \ + &spi_sedi_init, \ + PM_DEVICE_GET(spi_##num), \ + &spi_##num##_data, \ + &spi_##num##_config, \ + POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, \ + &sedi_spi_api); + +DT_INST_FOREACH_STATUS_OKAY(CREATE_SEDI_SPI_INSTANCE) diff --git a/dts/bindings/spi/intel,sedi-spi.yaml b/dts/bindings/spi/intel,sedi-spi.yaml new file mode 100644 index 00000000000..ef3af78460a --- /dev/null +++ b/dts/bindings/spi/intel,sedi-spi.yaml @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Intel SEDI SPI controller + +compatible: "intel,sedi-spi" + +include: spi-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + peripheral-id: + type: int + description: Peripheral Instance ID + required: true diff --git a/dts/x86/intel/intel_ish5.dtsi b/dts/x86/intel/intel_ish5.dtsi index 375b9cc4ea4..8215748511d 100644 --- a/dts/x86/intel/intel_ish5.dtsi +++ b/dts/x86/intel/intel_ish5.dtsi @@ -163,5 +163,29 @@ status = "okay"; }; + + spi0: spi@8000000 { + compatible = "intel,sedi-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x8000000 0x1000>; + peripheral-id = <0>; + interrupt-parent = <&intc>; + interrupts = <19 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "okay"; + }; + + spi1: spi@8002000 { + compatible = "intel,sedi-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x8002000 0x1000>; + peripheral-id = <1>; + interrupt-parent = <&intc>; + interrupts = <20 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "disabled"; + }; }; }; diff --git a/dts/x86/intel/intel_ish5_8.dtsi b/dts/x86/intel/intel_ish5_8.dtsi index fba74881cf4..5600798d8e8 100644 --- a/dts/x86/intel/intel_ish5_8.dtsi +++ b/dts/x86/intel/intel_ish5_8.dtsi @@ -41,3 +41,15 @@ status = "okay"; }; + +&spi0 { + interrupts = <23 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "okay"; +}; + +&spi1 { + interrupts = <24 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + + status = "disabled"; +}; From 0bb77191c04f2118d3f6f57d3dc2b0f69f5fab8b Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 25 Sep 2023 09:16:50 +0800 Subject: [PATCH 2152/4498] drivers/serial: ns16550: Add high speed baud rate support for IT8XXX2 Add the support of high speed baud rate 230.4k and 460.8k for IT8XXX2 of ITE. Signed-off-by: Tim Lin --- drivers/serial/Kconfig.it8xxx2 | 1 + drivers/serial/Kconfig.ns16550 | 6 +++ drivers/serial/uart_ns16550.c | 73 ++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/serial/Kconfig.it8xxx2 b/drivers/serial/Kconfig.it8xxx2 index 0a7a59ce08d..f89874fef41 100644 --- a/drivers/serial/Kconfig.it8xxx2 +++ b/drivers/serial/Kconfig.it8xxx2 @@ -4,6 +4,7 @@ config UART_ITE_IT8XXX2 bool "ITE IT8XXX2 UART driver" default y + select UART_NS16550_ITE_HIGH_SPEED_BUADRATE depends on DT_HAS_ITE_IT8XXX2_UART_ENABLED help IT8XXX2 uses shared ns16550.c driver which does not diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 90c29046044..1c97a08637e 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -77,6 +77,12 @@ config UART_NS16550_TI_K3 Texas Instruments K3 SoCs by enabling a vendor specific extended register set. +config UART_NS16550_ITE_HIGH_SPEED_BUADRATE + bool "IT8XXX2 specific baud rate configuration" + help + Enable IT8XXX2 specific baud rate configuration. + This applies to high-speed baud rate configuration. + menu "NS16550 Workarounds" config UART_NS16550_WA_ISR_REENABLE_INTERRUPT diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index c3f74b30dd5..5adf0eca645 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -242,6 +242,23 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); #define IIRC(dev) (((struct uart_ns16550_dev_data *)(dev)->data)->iir_cache) +#ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE +/* Register definitions (ITE_IT8XXX2) */ +#define REG_ECSPMR 0x08 /* EC Serial port mode reg */ + +/* Fields for ITE IT8XXX2 UART module */ +#define ECSPMR_ECHS 0x02 /* EC high speed select */ + +/* IT8XXX2 UART high speed baud rate settings */ +#define UART_BAUDRATE_115200 115200 +#define UART_BAUDRATE_230400 230400 +#define UART_BAUDRATE_460800 460800 +#define IT8XXX2_230400_DIVISOR 32770 +#define IT8XXX2_460800_DIVISOR 32769 + +#define ECSPMR(dev) (get_port(dev) + REG_ECSPMR * reg_interval(dev)) +#endif + /* device config */ struct uart_ns16550_device_config { union { @@ -395,6 +412,50 @@ static inline uintptr_t get_port(const struct device *dev) return port; } +static uint32_t get_uart_burdrate_divisor(const struct device *dev, + uint32_t baud_rate, + uint32_t pclk) +{ + ARG_UNUSED(dev); + /* + * calculate baud rate divisor. a variant of + * (uint32_t)(pclk / (16.0 * baud_rate) + 0.5) + */ + return ((pclk + (baud_rate << 3)) / baud_rate) >> 4; +} + +#ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE +static uint32_t get_ite_uart_burdrate_divisor(const struct device *dev, + uint32_t baud_rate, + uint32_t pclk) +{ + const struct uart_ns16550_device_config * const dev_cfg = dev->config; + uint32_t divisor = 0; + + if (baud_rate > UART_BAUDRATE_115200) { + /* Baud rate divisor for high speed */ + if (baud_rate == UART_BAUDRATE_230400) { + divisor = IT8XXX2_230400_DIVISOR; + } else if (baud_rate == UART_BAUDRATE_460800) { + divisor = IT8XXX2_460800_DIVISOR; + } + /* + * This bit indicates that the supported baud rate of + * UART1/UART2 can be up to 230.4k and 460.8k. + * Other bits are reserved and have no setting, so we + * directly write the ECSPMR register. + */ + ns16550_outbyte(dev_cfg, ECSPMR(dev), ECSPMR_ECHS); + } else { + divisor = get_uart_burdrate_divisor(dev, baud_rate, pclk); + /* Set ECSPMR register as default */ + ns16550_outbyte(dev_cfg, ECSPMR(dev), 0); + } + + return divisor; +} +#endif + static void set_baud_rate(const struct device *dev, uint32_t baud_rate, uint32_t pclk) { struct uart_ns16550_dev_data * const dev_data = dev->data; @@ -403,13 +464,11 @@ static void set_baud_rate(const struct device *dev, uint32_t baud_rate, uint32_t uint8_t lcr_cache; if ((baud_rate != 0U) && (pclk != 0U)) { - /* - * calculate baud rate divisor. a variant of - * (uint32_t)(pclk / (16.0 * baud_rate) + 0.5) - */ - divisor = ((pclk + (baud_rate << 3)) - / baud_rate) >> 4; - +#ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE + divisor = get_ite_uart_burdrate_divisor(dev, baud_rate, pclk); +#else + divisor = get_uart_burdrate_divisor(dev, baud_rate, pclk); +#endif /* set the DLAB to access the baud rate divisor registers */ lcr_cache = ns16550_inbyte(dev_cfg, LCR(dev)); ns16550_outbyte(dev_cfg, LCR(dev), LCR_DLAB | lcr_cache); From 9c47eb924faf272c76c36bdae47c59cd63003146 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 27 Sep 2023 11:27:01 +0200 Subject: [PATCH 2153/4498] Bluetooth: Audio: Refactor codec_cfg_get_frame_duration_us Refactor the codec_cfg_get_frame_duration function to return the assigned numbers value, instead of a converted value, but with support for converting the value. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 37 ++++++++++++- include/zephyr/bluetooth/audio/lc3.h | 18 ++++--- samples/bluetooth/hap_ha/src/bap_unicast_sr.c | 8 ++- .../tmap_peripheral/src/bap_unicast_sr.c | 8 ++- .../bluetooth/unicast_audio_client/src/main.c | 6 ++- .../bluetooth/unicast_audio_server/src/main.c | 18 ++++--- subsys/bluetooth/audio/codec.c | 54 ++++++++++++++++--- subsys/bluetooth/audio/shell/bap.c | 16 ++++-- tests/bluetooth/audio/codec/src/main.c | 45 ++++++++++++++-- tests/bluetooth/tester/src/btp_bap.c | 15 +++--- 10 files changed, 185 insertions(+), 40 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 3d5f28372aa..403993172ea 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -635,16 +635,49 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg); int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_codec_config_freq freq); +/** + * @brief Convert assigned numbers frame duration to duration in microseconds. + * + * @param frame_dur The assigned numbers frame duration to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The converted frame duration value in microseconds. + */ +int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur); + +/** + * @brief Convert frame duration in microseconds to assigned numbers frame duration. + * + * @param frame_dur_us The frame duration in microseconds to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The assigned numbers frame duration (@ref bt_audio_codec_config_frame_dur). + */ +int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us); + /** @brief Extract frame duration from BT codec config * * @param codec_cfg The codec configuration to extract data from. * - * @retval Frame duration in microseconds + * @retval A @ref bt_audio_codec_config_frame_dur value * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg); +int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg); + +/** + * @brief Set the frame duration of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param frame_dur The assigned numbers frame duration to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_frame_dur frame_dur); /** @brief Extract channel allocation from BT codec config * diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 28737fc367f..5ca0f276849 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -243,14 +243,16 @@ enum bt_audio_codec_config_freq { BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ = 0x0d, }; -/** - * @brief LC3 7.5 msec Frame Duration configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 0x00 -/** - * @brief LC3 10 msec Frame Duration configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 0x01 +enum bt_audio_codec_config_frame_dur { + /** + * @brief LC3 7.5 msec Frame Duration configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 = 0x00, + /** + * @brief LC3 10 msec Frame Duration configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 = 0x01, +}; /** * @brief Helper to declare LC3 codec capability diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 5ed64e86202..1eca1fd25c2 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -87,8 +87,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index ef78551efd1..bb431ef478a 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -76,8 +76,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index a3aca0424fa..0e35a7d5a3d 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -234,7 +234,11 @@ static int init_lc3(void) return ret; } - frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } + octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index 7c20ee34df8..7625bcdbf7f 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -147,8 +147,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } @@ -354,8 +358,7 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t #if defined(CONFIG_LIBLC3) { - const int frame_duration_us = - bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); + int frame_duration_us; int freq; int ret; @@ -369,11 +372,14 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t return ret; } - if (frame_duration_us < 0) { + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { printk("Error: Frame duration not set, cannot start codec."); *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID, BT_BAP_ASCS_REASON_CODEC_DATA); - return -1; + return ret; } frames_per_sdu = diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 8a9826f8633..5b064987a25 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -88,6 +88,30 @@ int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz) } } +int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur) +{ + switch (frame_dur) { + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: + return 7500; + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: + return 10000; + default: + return -EINVAL; + } +} + +int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us) +{ + switch (frame_dur_us) { + case 7500U: + return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5; + case 10000U: + return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10; + default: + return -EINVAL; + } +} + struct search_type_param { bool found; uint8_t type; @@ -309,8 +333,9 @@ int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, sizeof(freq_u8)); } -int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg) +int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg) { + enum bt_audio_codec_config_frame_dur frame_dur; const uint8_t *data; uint8_t data_len; @@ -328,14 +353,29 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co return -EBADMSG; } - switch (data[0]) { - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: - return 7500; - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: - return 10000; - default: + frame_dur = data[0]; + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) { + LOG_DBG("Invalid frame_dur value: 0x%02X", frame_dur); return -EBADMSG; } + + return frame_dur; +} + +int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_frame_dur frame_dur) +{ + uint8_t frame_dur_u8; + + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) { + LOG_DBG("Invalid freq value: %d", frame_dur); + return -EINVAL; + } + + frame_dur_u8 = (uint8_t)frame_dur; + + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, + &frame_dur_u8, sizeof(frame_dur_u8)); } int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg, diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 82ed1d3c5e4..aa6561f6795 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -245,7 +245,13 @@ static int init_lc3(const struct bt_bap_stream *stream) return ret; } - lc3_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); + ret = bt_audio_codec_cfg_get_frame_dur(stream->codec_cfg); + if (ret > 0) { + lc3_frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { + return ret; + } + lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg); lc3_frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(stream->codec_cfg, true); lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg); @@ -2637,8 +2643,12 @@ static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream) return false; } - stream_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(bap_stream->codec_cfg); - if (stream_frame_duration_us != lc3_frame_duration_us) { + err = bt_audio_codec_cfg_get_frame_dur(bap_stream->codec_cfg); + if (err > 0) { + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(err) != lc3_frame_duration_us) { + return false; + } + } else { return false; } diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 28dee9bdec1..edc87c56007 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -73,15 +73,54 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_freq) zassert_equal(ret, 0x06, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_duration_us) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_frame_dur_to_frame_dur_us) +{ + const struct frame_dur_test_input { + enum bt_audio_codec_config_frame_dur frame_dur; + uint32_t frame_dur_us; + } frame_dur_test_inputs[] = { + {.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5, .frame_dur_us = 7500U}, + {.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10, .frame_dur_us = 10000U}, + }; + + for (size_t i = 0U; i < ARRAY_SIZE(frame_dur_test_inputs); i++) { + const struct frame_dur_test_input *fdti = &frame_dur_test_inputs[i]; + + zassert_equal(bt_audio_codec_cfg_frame_dur_to_frame_dur_us(fdti->frame_dur), + fdti->frame_dur_us, "frame_dur %d was not coverted to %u", + fdti->frame_dur, fdti->frame_dur_us); + zassert_equal(bt_audio_codec_cfg_frame_dur_us_to_frame_dur(fdti->frame_dur_us), + fdti->frame_dur, "frame_dur_us %u was not coverted to %d", + fdti->frame_dur_us, fdti->frame_dur); + } +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_dur) { const struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_48_2_2(BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); int ret; - ret = bt_audio_codec_cfg_get_frame_duration_us(&preset.codec_cfg); - zassert_equal(ret, 10000u, "unexpected return value %d", ret); + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x01, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_frame_dur) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + int ret; + + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_frame_dur(&preset.codec_cfg, + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation) diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 3e171e2407c..7d457810007 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -148,8 +148,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) LOG_DBG(" Frequency: %d Hz", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - LOG_DBG(" Frame Duration: %d us", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + LOG_DBG(" Frame Duration: %d us", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { LOG_DBG(" Channel allocation: 0x%x", chan_allocation); } @@ -260,14 +264,12 @@ static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) { - int frame_duration_us; int frames_per_sdu; int octets_per_frame; int chan_allocation_err; enum bt_audio_location chan_allocation; int ret; - frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); chan_allocation_err = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); @@ -279,8 +281,9 @@ static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) return -EINVAL; } - if (frame_duration_us < 0) { - LOG_DBG("Error: Invalid frame duration."); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret < 0) { + LOG_DBG("Error: Invalid frame duration: %d", ret); return -EINVAL; } From ab60f5e6bceb590bc961a41fc5fc98140aa14ad7 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 14:26:20 +0200 Subject: [PATCH 2154/4498] tests: bsim: Bluetooth: BAP Broadcast data validation Add validation of sending and receiving dummy data. Previously, due to a bug, we actually never sent any data and still passed the test. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_sink_test.c | 42 +++++++++++++++++-- .../audio/src/bap_broadcast_source_test.c | 40 ++++++++---------- tests/bsim/bluetooth/audio/src/common.h | 21 ++++++++++ 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index 59c832ac3e3..63196d32e93 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -29,7 +29,11 @@ static struct bt_le_scan_recv_info broadcaster_info; static bt_addr_le_t broadcaster_addr; static struct bt_le_per_adv_sync *pa_sync; static uint32_t broadcaster_broadcast_id; -static struct bt_bap_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; +static struct broadcast_sink_stream { + struct bt_bap_stream stream; + struct bt_iso_recv_info last_info; + size_t rx_cnt; +} broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)]; static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( @@ -201,7 +205,39 @@ static void recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { - SET_FLAG(flag_received); + struct broadcast_sink_stream *sink_stream = + CONTAINER_OF(stream, struct broadcast_sink_stream, stream); + + if (sink_stream->rx_cnt > 0U && info->ts == sink_stream->last_info.ts) { + FAIL("Duplicated timestamp received: %u\n", sink_stream->last_info.ts); + return; + } + + if (sink_stream->rx_cnt > 0U && info->seq_num == sink_stream->last_info.seq_num) { + FAIL("Duplicated PSN received: %u\n", sink_stream->last_info.seq_num); + return; + } + + if (info->flags & BT_ISO_FLAGS_ERROR) { + FAIL("ISO receive error\n"); + return; + } + + if (info->flags & BT_ISO_FLAGS_LOST) { + FAIL("ISO receive lost\n"); + return; + } + + if (memcmp(buf->data, mock_iso_data, buf->len) == 0) { + sink_stream->rx_cnt++; + + if (sink_stream->rx_cnt >= MIN_SEND_COUNT) { + /* We set the flag is just one stream has received the expected */ + SET_FLAG(flag_received); + } + } else { + FAIL("Unexpected data received"); + } } static struct bt_bap_stream_ops stream_ops = { @@ -249,7 +285,7 @@ static int init(void) UNSET_FLAG(pa_synced); for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { - streams[i] = &broadcast_sink_streams[i]; + streams[i] = &broadcast_sink_streams[i].stream; bt_bap_stream_cb_register(streams[i], &stream_ops); } diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index b606f5d6fda..0cbbc40b456 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -28,16 +28,16 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); extern enum bst_result_t bst_result; +static volatile size_t sent_count; static struct bt_bap_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; -static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_source_streams)]; static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); static struct bt_bap_lc3_preset preset_16_2_2 = BT_BAP_LC3_BROADCAST_PRESET_16_2_2( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); CREATE_FLAG(flag_stopping); -static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(streams)); -static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); +static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(broadcast_source_streams)); +static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(broadcast_source_streams)); static void started_cb(struct bt_bap_stream *stream) { @@ -53,8 +53,6 @@ static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason) static void sent_cb(struct bt_bap_stream *stream) { - static uint8_t mock_data[CONFIG_BT_ISO_TX_MTU]; - static bool mock_data_initialized; static uint16_t seq_num; struct net_buf *buf; int ret; @@ -63,14 +61,6 @@ static void sent_cb(struct bt_bap_stream *stream) return; } - if (!mock_data_initialized) { - for (size_t i = 0U; i < ARRAY_SIZE(mock_data); i++) { - /* Initialize mock data */ - mock_data[i] = (uint8_t)i; - } - mock_data_initialized = true; - } - buf = net_buf_alloc(&tx_pool, K_FOREVER); if (buf == NULL) { printk("Could not allocate buffer when sending on %p\n", @@ -80,15 +70,16 @@ static void sent_cb(struct bt_bap_stream *stream) net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); /* Use preset_16_2_1 as that is the config we end up using */ - net_buf_add_mem(buf, mock_data, preset_16_2_1.qos.sdu); - ret = bt_bap_stream_send(stream, buf, seq_num++, - BT_ISO_TIMESTAMP_NONE); + net_buf_add_mem(buf, mock_iso_data, preset_16_2_1.qos.sdu); + ret = bt_bap_stream_send(stream, buf, seq_num++, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { /* This will end broadcasting on this stream. */ - printk("Unable to broadcast data on %p: %d\n", stream, ret); net_buf_unref(buf); + FAIL("Unable to broadcast data on %p: %d\n", stream, ret); return; } + + sent_count++; } static struct bt_bap_stream_ops stream_ops = { @@ -351,7 +342,7 @@ static void test_broadcast_source_start(struct bt_bap_broadcast_source *source, /* Wait for all to be started */ printk("Waiting for streams to be started\n"); - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { k_sem_take(&sem_started, K_FOREVER); } } @@ -371,7 +362,7 @@ static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source) /* Wait for all to be stopped */ printk("Waiting for streams to be stopped\n"); - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { k_sem_take(&sem_stopped, K_FOREVER); } } @@ -447,14 +438,17 @@ static void test_main(void) test_broadcast_source_start(source, adv); /* Initialize sending */ - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + printk("Sending data\n"); + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) { - sent_cb(streams[i]); + sent_cb(&broadcast_source_streams[i]); } } - /* Keeping running for a little while */ - k_sleep(K_SECONDS(15)); + /* Keep sending until we reach the minimum expected */ + while (sent_count < (MIN_SEND_COUNT * ARRAY_SIZE(broadcast_source_streams))) { + k_sleep(K_MSEC(100)); + } /* Update metadata while streaming */ printk("Updating metadata\n"); diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index bcbd91e6d18..9193d423c61 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -28,6 +28,27 @@ #include #include +static const uint8_t mock_iso_data[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, + 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +#define MIN_SEND_COUNT 100 #define WAIT_SECONDS 60 /* seconds */ #define WAIT_TIME (WAIT_SECONDS * USEC_PER_SEC) /* microseconds*/ From f67f840def46b6715fa7df86c112635bb8a6356a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 11 Sep 2023 13:10:14 +0200 Subject: [PATCH 2155/4498] tests: Bluetooth: Add tx/rx and data verification for BAP unicast The BAP unicast babblesim tests now does RX and TX and verifies that the data is correctly received on both the client and server. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_stream.c | 2 +- tests/bsim/bluetooth/audio/prj.conf | 2 +- .../audio/src/bap_broadcast_sink_test.c | 23 +-- .../audio/src/bap_broadcast_source_test.c | 75 +++++--- .../audio/src/bap_unicast_client_test.c | 176 ++++++++++++++++-- .../audio/src/bap_unicast_server_test.c | 171 ++++++++++++++++- tests/bsim/bluetooth/audio/src/common.c | 2 +- tests/bsim/bluetooth/audio/src/common.h | 13 ++ 8 files changed, 400 insertions(+), 64 deletions(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 0b1c9cd9d27..0c7f67f326c 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -793,7 +793,7 @@ int bt_bap_stream_release(struct bt_bap_stream *stream) LOG_DBG("stream %p", stream); CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) { - LOG_DBG("Invalid stream"); + LOG_DBG("Invalid stream (ep %p, conn %p)", stream->ep, (void *)stream->conn); return -EINVAL; } diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index e4d25d1ed0f..8f387c8016f 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -202,7 +202,7 @@ CONFIG_BT_CTLR_ISOAL_SOURCES=2 CONFIG_BT_CTLR_ISOAL_SINKS=2 CONFIG_BT_CTLR_CONN_ISO_LOW_LATENCY_POLICY=y -CONFIG_BT_CTLR_ISO_TX_BUFFERS=3 +CONFIG_BT_CTLR_ISO_TX_BUFFERS=4 # Controller advanced options CONFIG_BT_CTLR_ADVANCED_FEATURES=y diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index 63196d32e93..18608ae7256 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -29,11 +29,7 @@ static struct bt_le_scan_recv_info broadcaster_info; static bt_addr_le_t broadcaster_addr; static struct bt_le_per_adv_sync *pa_sync; static uint32_t broadcaster_broadcast_id; -static struct broadcast_sink_stream { - struct bt_bap_stream stream; - struct bt_iso_recv_info last_info; - size_t rx_cnt; -} broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; +static struct bap_test_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)]; static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( @@ -205,16 +201,17 @@ static void recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { - struct broadcast_sink_stream *sink_stream = - CONTAINER_OF(stream, struct broadcast_sink_stream, stream); + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); - if (sink_stream->rx_cnt > 0U && info->ts == sink_stream->last_info.ts) { - FAIL("Duplicated timestamp received: %u\n", sink_stream->last_info.ts); + printk("Incoming audio on stream %p len %u and ts %u\n", stream, buf->len, info->ts); + + if (test_stream->rx_cnt > 0U && info->ts == test_stream->last_info.ts) { + FAIL("Duplicated timestamp received: %u\n", test_stream->last_info.ts); return; } - if (sink_stream->rx_cnt > 0U && info->seq_num == sink_stream->last_info.seq_num) { - FAIL("Duplicated PSN received: %u\n", sink_stream->last_info.seq_num); + if (test_stream->rx_cnt > 0U && info->seq_num == test_stream->last_info.seq_num) { + FAIL("Duplicated PSN received: %u\n", test_stream->last_info.seq_num); return; } @@ -229,9 +226,9 @@ static void recv_cb(struct bt_bap_stream *stream, } if (memcmp(buf->data, mock_iso_data, buf->len) == 0) { - sink_stream->rx_cnt++; + test_stream->rx_cnt++; - if (sink_stream->rx_cnt >= MIN_SEND_COUNT) { + if (test_stream->rx_cnt >= MIN_SEND_COUNT) { /* We set the flag is just one stream has received the expected */ SET_FLAG(flag_received); } diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 0cbbc40b456..fbb64a85f18 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -28,13 +28,11 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); extern enum bst_result_t bst_result; -static volatile size_t sent_count; -static struct bt_bap_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; +static struct bap_test_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); -static struct bt_bap_lc3_preset preset_16_2_2 = BT_BAP_LC3_BROADCAST_PRESET_16_2_2( +static struct bt_bap_lc3_preset preset_16_1_1 = BT_BAP_LC3_BROADCAST_PRESET_16_1_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); -CREATE_FLAG(flag_stopping); static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(broadcast_source_streams)); static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(broadcast_source_streams)); @@ -51,16 +49,18 @@ static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason) k_sem_give(&sem_stopped); } -static void sent_cb(struct bt_bap_stream *stream) +static void stream_sent_cb(struct bt_bap_stream *stream) { - static uint16_t seq_num; + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); struct net_buf *buf; int ret; - if (TEST_FLAG(flag_stopping)) { + if (!test_stream->tx_active) { return; } + printk("Sent with seq_num %u\n", test_stream->seq_num); + buf = net_buf_alloc(&tx_pool, K_FOREVER); if (buf == NULL) { printk("Could not allocate buffer when sending on %p\n", @@ -69,23 +69,27 @@ static void sent_cb(struct bt_bap_stream *stream) } net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - /* Use preset_16_2_1 as that is the config we end up using */ - net_buf_add_mem(buf, mock_iso_data, preset_16_2_1.qos.sdu); - ret = bt_bap_stream_send(stream, buf, seq_num++, BT_ISO_TIMESTAMP_NONE); + net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size); + ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { /* This will end broadcasting on this stream. */ net_buf_unref(buf); - FAIL("Unable to broadcast data on %p: %d\n", stream, ret); + + /* Only fail if tx is active (may fail if we are disabling the stream) */ + if (test_stream->tx_active) { + FAIL("Unable to broadcast data on %p: %d\n", stream, ret); + } + return; } - sent_count++; + test_stream->tx_cnt++; } static struct bt_bap_stream_ops stream_ops = { .started = started_cb, .stopped = stopped_cb, - .sent = sent_cb + .sent = stream_sent_cb, }; static int setup_broadcast_source(struct bt_bap_broadcast_source **source) @@ -105,7 +109,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) sizeof(broadcast_source_streams)); for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) { - stream_params[i].stream = &broadcast_source_streams[i]; + stream_params[i].stream = &broadcast_source_streams[i].stream; bt_bap_stream_cb_register(stream_params[i].stream, &stream_ops); #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 @@ -117,7 +121,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) for (size_t i = 0U; i < ARRAY_SIZE(subgroup_params); i++) { subgroup_params[i].params_count = 1U; subgroup_params[i].params = &stream_params[i]; - subgroup_params[i].codec_cfg = &preset_16_2_1.codec_cfg; + subgroup_params[i].codec_cfg = &preset_16_1_1.codec_cfg; } create_param.params_count = ARRAY_SIZE(subgroup_params); @@ -134,6 +138,12 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) return err; } + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { + struct bap_test_stream *test_stream = &broadcast_source_streams[i]; + + test_stream->tx_sdu_size = preset_16_1_1.qos.sdu; + } + return 0; } @@ -303,7 +313,7 @@ static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *sourc int err; for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) { - stream_params[i].stream = &broadcast_source_streams[i]; + stream_params[i].stream = &broadcast_source_streams[i].stream; stream_params[i].data_len = ARRAY_SIZE(bis_codec_data); stream_params[i].data = bis_codec_data; } @@ -311,12 +321,12 @@ static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *sourc for (size_t i = 0U; i < ARRAY_SIZE(subgroup_params); i++) { subgroup_params[i].params_count = 1U; subgroup_params[i].params = &stream_params[i]; - subgroup_params[i].codec_cfg = &preset_16_2_2.codec_cfg; + subgroup_params[i].codec_cfg = &preset_16_1_1.codec_cfg; } reconfig_param.params_count = ARRAY_SIZE(subgroup_params); reconfig_param.params = subgroup_params; - reconfig_param.qos = &preset_16_2_2.qos; + reconfig_param.qos = &preset_16_1_1.qos; reconfig_param.packing = BT_ISO_PACKING_SEQUENTIAL; reconfig_param.encryption = false; @@ -326,6 +336,12 @@ static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *sourc FAIL("Unable to reconfigure broadcast source: %d\n", err); return; } + + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { + struct bap_test_stream *test_stream = &broadcast_source_streams[i]; + + test_stream->tx_sdu_size = preset_16_1_1.qos.sdu; + } } static void test_broadcast_source_start(struct bt_bap_broadcast_source *source, @@ -351,9 +367,12 @@ static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source) { int err; - SET_FLAG(flag_stopping); printk("Stopping broadcast source\n"); + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { + broadcast_source_streams[i].tx_active = false; + } + err = bt_bap_broadcast_source_stop(source); if (err != 0) { FAIL("Unable to stop broadcast source: %d\n", err); @@ -371,7 +390,6 @@ static void test_broadcast_source_delete(struct bt_bap_broadcast_source *source) { int err; - SET_FLAG(flag_stopping); printk("Deleting broadcast source\n"); err = bt_bap_broadcast_source_delete(source); @@ -441,13 +459,22 @@ static void test_main(void) printk("Sending data\n"); for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) { - sent_cb(&broadcast_source_streams[i]); + struct bap_test_stream *test_stream = + CONTAINER_OF(&broadcast_source_streams[i].stream, + struct bap_test_stream, stream); + + test_stream->tx_active = true; + stream_sent_cb(&broadcast_source_streams[i].stream); } } - /* Keep sending until we reach the minimum expected */ - while (sent_count < (MIN_SEND_COUNT * ARRAY_SIZE(broadcast_source_streams))) { - k_sleep(K_MSEC(100)); + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { + /* Keep sending until we reach 5 times the minimum expected to be pretty sure + * that the receiver receives enough + */ + while (broadcast_source_streams[i].tx_cnt < MIN_SEND_COUNT) { + k_sleep(K_MSEC(100)); + } } /* Update metadata while streaming */ diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index 3fbd70458b9..96265267e80 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -16,9 +16,15 @@ #define BAP_STREAM_RETRY_WAIT K_MSEC(100) +#define ENQUEUE_COUNT 2U +#define TOTAL_BUF_NEEDED (ENQUEUE_COUNT * CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT) +NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + extern enum bst_result_t bst_result; -static struct bt_bap_stream g_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; +static volatile size_t sent_count; +static struct bap_test_stream g_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; static struct bt_bap_ep *g_sinks[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; static struct bt_bap_ep *g_sources[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT]; @@ -39,6 +45,7 @@ static atomic_t flag_stream_qos_configured; CREATE_FLAG(flag_stream_enabled); CREATE_FLAG(flag_stream_metadata); CREATE_FLAG(flag_stream_started); +CREATE_FLAG(flag_stream_disabled); CREATE_FLAG(flag_stream_released); CREATE_FLAG(flag_operation_success); @@ -56,8 +63,12 @@ static void stream_configured(struct bt_bap_stream *stream, static void stream_qos_set(struct bt_bap_stream *stream) { + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + printk("QoS set stream %p\n", stream); + test_stream->tx_sdu_size = stream->qos->sdu; + atomic_inc(&flag_stream_qos_configured); } @@ -84,7 +95,13 @@ static void stream_metadata_updated(struct bt_bap_stream *stream) static void stream_disabled(struct bt_bap_stream *stream) { + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + + test_stream->tx_active = false; + printk("Disabled stream %p\n", stream); + + SET_FLAG(flag_stream_disabled); } static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) @@ -99,6 +116,74 @@ static void stream_released(struct bt_bap_stream *stream) SET_FLAG(flag_stream_released); } +static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + + printk("Incoming audio on stream %p len %u and ts %u\n", stream, buf->len, info->ts); + + if (test_stream->rx_cnt > 0U && info->ts == test_stream->last_info.ts) { + FAIL("Duplicated timestamp received: %u\n", test_stream->last_info.ts); + return; + } + + if (test_stream->rx_cnt > 0U && info->seq_num == test_stream->last_info.seq_num) { + FAIL("Duplicated PSN received: %u\n", test_stream->last_info.seq_num); + return; + } + + if (info->flags & BT_ISO_FLAGS_ERROR) { + FAIL("ISO receive error\n"); + return; + } + + if (info->flags & BT_ISO_FLAGS_LOST) { + FAIL("ISO receive lost\n"); + return; + } + + if (memcmp(buf->data, mock_iso_data, buf->len) == 0) { + test_stream->rx_cnt++; + } else { + FAIL("Unexpected data received"); + } +} + +static void stream_sent_cb(struct bt_bap_stream *stream) +{ + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + struct net_buf *buf; + int ret; + + if (!test_stream->tx_active) { + return; + } + + buf = net_buf_alloc(&tx_pool, K_FOREVER); + if (buf == NULL) { + printk("Could not allocate buffer when sending on %p\n", stream); + return; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size); + ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + /* This will end broadcasting on this stream. */ + net_buf_unref(buf); + + /* Only fail if tx is active (may fail if we are disabling the stream) */ + if (test_stream->tx_active) { + FAIL("Unable to send data on %p: %d\n", stream, ret); + } + + return; + } + + test_stream->tx_cnt++; +} + static struct bt_bap_stream_ops stream_ops = { .configured = stream_configured, .qos_set = stream_qos_set, @@ -108,6 +193,8 @@ static struct bt_bap_stream_ops stream_ops = { .disabled = stream_disabled, .stopped = stream_stopped, .released = stream_released, + .recv = stream_recv_cb, + .sent = stream_sent_cb, }; static void unicast_client_location_cb(struct bt_conn *conn, @@ -403,7 +490,7 @@ static void init(void) } for (size_t i = 0; i < ARRAY_SIZE(g_streams); i++) { - g_streams[i].ops = &stream_ops; + g_streams[i].stream.ops = &stream_ops; } bt_le_scan_cb_register(&bap_scan_cb); @@ -587,7 +674,7 @@ static int enable_stream(struct bt_bap_stream *stream) static void enable_streams(size_t stream_cnt) { for (size_t i = 0U; i < stream_cnt; i++) { - struct bt_bap_stream *stream = &g_streams[i]; + struct bt_bap_stream *stream = &g_streams[i].stream; int err; err = enable_stream(stream); @@ -626,7 +713,7 @@ static int metadata_update_stream(struct bt_bap_stream *stream) static void metadata_update_streams(size_t stream_cnt) { for (size_t i = 0U; i < stream_cnt; i++) { - struct bt_bap_stream *stream = &g_streams[i]; + struct bt_bap_stream *stream = &g_streams[i].stream; int err; err = metadata_update_stream(stream); @@ -692,7 +779,64 @@ static void start_streams(void) } } -static size_t release_streams(size_t stream_cnt) +static void transceive_streams(void) +{ + struct bt_bap_stream *source_stream; + struct bt_bap_stream *sink_stream; + + source_stream = pair_params[0].rx_param == NULL ? NULL : pair_params[0].rx_param->stream; + sink_stream = pair_params[0].tx_param == NULL ? NULL : pair_params[0].tx_param->stream; + + if (sink_stream != NULL) { + struct bap_test_stream *test_stream = + CONTAINER_OF(sink_stream, struct bap_test_stream, stream); + + test_stream->tx_active = true; + for (unsigned int i = 0U; i < ENQUEUE_COUNT; i++) { + stream_sent_cb(sink_stream); + } + + /* Keep sending until we reach the minimum expected */ + while (test_stream->tx_cnt < MIN_SEND_COUNT) { + k_sleep(K_MSEC(100)); + } + } + + if (source_stream != NULL) { + const struct bap_test_stream *test_stream = + CONTAINER_OF(source_stream, struct bap_test_stream, stream); + + /* Keep receiving until we reach the minimum expected */ + while (test_stream->rx_cnt < MIN_SEND_COUNT) { + k_sleep(K_MSEC(100)); + } + } +} + +static void disable_streams(size_t stream_cnt) +{ + for (size_t i = 0; i < stream_cnt; i++) { + int err; + + UNSET_FLAG(flag_operation_success); + UNSET_FLAG(flag_stream_disabled); + + do { + err = bt_bap_stream_disable(&g_streams[i].stream); + if (err == -EBUSY) { + k_sleep(BAP_STREAM_RETRY_WAIT); + } else if (err != 0) { + FAIL("Could not disable stream: %d\n", err); + return; + } + } while (err == -EBUSY); + + WAIT_FOR_FLAG(flag_operation_success); + WAIT_FOR_FLAG(flag_stream_disabled); + } +} + +static void release_streams(size_t stream_cnt) { for (size_t i = 0; i < stream_cnt; i++) { int err; @@ -701,20 +845,18 @@ static size_t release_streams(size_t stream_cnt) UNSET_FLAG(flag_stream_released); do { - err = bt_bap_stream_release(&g_streams[i]); + err = bt_bap_stream_release(&g_streams[i].stream); if (err == -EBUSY) { k_sleep(BAP_STREAM_RETRY_WAIT); } else if (err != 0) { FAIL("Could not release stream: %d\n", err); - return err; + return; } } while (err == -EBUSY); WAIT_FOR_FLAG(flag_operation_success); WAIT_FOR_FLAG(flag_stream_released); } - - return stream_cnt; } static size_t create_unicast_group(struct bt_bap_unicast_group **unicast_group) @@ -732,7 +874,7 @@ static size_t create_unicast_group(struct bt_bap_unicast_group **unicast_group) break; } - stream_params[stream_cnt].stream = &g_streams[stream_cnt]; + stream_params[stream_cnt].stream = &g_streams[stream_cnt].stream; stream_params[stream_cnt].qos = &preset_16_2_1.qos; pair_params[i].tx_param = &stream_params[stream_cnt]; @@ -746,7 +888,7 @@ static size_t create_unicast_group(struct bt_bap_unicast_group **unicast_group) break; } - stream_params[stream_cnt].stream = &g_streams[stream_cnt]; + stream_params[stream_cnt].stream = &g_streams[stream_cnt].stream; stream_params[stream_cnt].qos = &preset_16_2_1.qos; pair_params[i].rx_param = &stream_params[stream_cnt]; @@ -839,6 +981,12 @@ static void test_main(void) printk("Starting streams\n"); start_streams(); + printk("Starting transceiving\n"); + transceive_streams(); + + printk("Stopping streams\n"); + disable_streams(stream_cnt); + printk("Releasing streams\n"); release_streams(stream_cnt); @@ -860,6 +1008,8 @@ static void test_main_acl_disconnect(void) init(); + stream_ops.recv = NULL; /* We do not care about data in this test */ + scan_and_connect(); exchange_mtu(); @@ -868,10 +1018,6 @@ static void test_main_acl_disconnect(void) discover_sources(); - /* Run the stream setup multiple time to ensure states are properly - * set and reset - */ - printk("Creating unicast group\n"); stream_cnt = create_unicast_group(&unicast_group); diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index 9dcf878de9b..e9e43a8a14a 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -19,6 +19,11 @@ extern enum bst_result_t bst_result; #define PREF_CONTEXT (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA) +#define ENQUEUE_COUNT 2U +#define TOTAL_BUF_NEEDED (ENQUEUE_COUNT * CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT) +NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + static const struct bt_audio_codec_cap lc3_codec_cap = { .path_id = BT_ISO_DATA_PATH_HCI, .id = BT_HCI_CODING_FORMAT_LC3, @@ -43,7 +48,7 @@ static const struct bt_audio_codec_cap lc3_codec_cap = { }, }; -static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; +static struct bap_test_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; static const struct bt_audio_codec_qos_pref qos_pref = BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000); @@ -64,7 +69,7 @@ static const struct bt_data unicast_server_ad[] = { static struct bt_le_ext_adv *ext_adv; CREATE_FLAG(flag_stream_configured); - +CREATE_FLAG(flag_stream_started); static void print_ase_info(struct bt_bap_ep *ep, void *user_data) { struct bt_bap_ep_info info; @@ -76,7 +81,7 @@ static void print_ase_info(struct bt_bap_ep *ep, void *user_data) static struct bt_bap_stream *stream_alloc(void) { for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { - struct bt_bap_stream *stream = &streams[i]; + struct bt_bap_stream *stream = &streams[i].stream; if (!stream->conn) { return stream; @@ -128,10 +133,14 @@ static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir, static int lc3_qos(struct bt_bap_stream *stream, const struct bt_audio_codec_qos *qos, struct bt_bap_ascs_rsp *rsp) { + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + printk("QoS: stream %p qos %p\n", stream, qos); print_qos(qos); + test_stream->tx_sdu_size = qos->sdu; + return 0; } @@ -173,8 +182,12 @@ static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + printk("Disable: stream %p\n", stream); + test_stream->tx_active = false; + return 0; } @@ -228,17 +241,153 @@ static void stream_enabled_cb(struct bt_bap_stream *stream) } } -static void stream_recv(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, - struct net_buf *buf) +static void stream_started_cb(struct bt_bap_stream *stream) { - printk("Incoming audio on stream %p len %u\n", stream, buf->len); + printk("Started: stream %p\n", stream); + + SET_FLAG(flag_stream_started); +} + +static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + + printk("Incoming audio on stream %p len %u and ts %u\n", stream, buf->len, info->ts); + + if (test_stream->rx_cnt > 0U && info->ts == test_stream->last_info.ts) { + FAIL("Duplicated timestamp received: %u\n", test_stream->last_info.ts); + return; + } + + if (test_stream->rx_cnt > 0U && info->seq_num == test_stream->last_info.seq_num) { + FAIL("Duplicated PSN received: %u\n", test_stream->last_info.seq_num); + return; + } + + if (info->flags & BT_ISO_FLAGS_ERROR) { + FAIL("ISO receive error\n"); + return; + } + + if (info->flags & BT_ISO_FLAGS_LOST) { + FAIL("ISO receive lost\n"); + return; + } + + if (memcmp(buf->data, mock_iso_data, buf->len) == 0) { + test_stream->rx_cnt++; + } else { + FAIL("Unexpected data received"); + } +} + +static void stream_sent_cb(struct bt_bap_stream *stream) +{ + struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); + struct net_buf *buf; + int ret; + + if (!test_stream->tx_active) { + return; + } + + buf = net_buf_alloc(&tx_pool, K_FOREVER); + if (buf == NULL) { + printk("Could not allocate buffer when sending on %p\n", stream); + return; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size); + ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + /* This will end broadcasting on this stream. */ + net_buf_unref(buf); + + /* Only fail if tx is active (may fail if we are disabling the stream) */ + if (test_stream->tx_active) { + FAIL("Unable to send data on %p: %d\n", stream, ret); + } + + return; + } + + test_stream->tx_cnt++; } static struct bt_bap_stream_ops stream_ops = { .enabled = stream_enabled_cb, - .recv = stream_recv + .started = stream_started_cb, + .recv = stream_recv_cb, + .sent = stream_sent_cb, }; +static void transceive_streams(void) +{ + struct bt_bap_stream *source_stream = NULL; + struct bt_bap_stream *sink_stream = NULL; + struct bt_bap_ep_info info; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + struct bt_bap_stream *stream = &streams[i].stream; + + if (stream->ep == NULL) { + break; + } + + while (true) { + err = bt_bap_ep_get_info(stream->ep, &info); + if (err != 0) { + FAIL("Failed to get endpoint info for stream[%zu] %p: %d\n", i, + stream, err); + return; + } + + /* Ensure that all configured streams are in the streaming state before + * starting TX and RX + */ + if (info.state == BT_BAP_EP_STATE_STREAMING) { + break; + } + + k_sleep(K_MSEC(100)); + } + + if (info.dir == BT_AUDIO_DIR_SINK && sink_stream == NULL) { + sink_stream = stream; + } else if (info.dir == BT_AUDIO_DIR_SOURCE && source_stream == NULL) { + source_stream = stream; + } + } + + if (source_stream != NULL) { + struct bap_test_stream *test_stream = + CONTAINER_OF(source_stream, struct bap_test_stream, stream); + + test_stream->tx_active = true; + for (unsigned int i = 0U; i < ENQUEUE_COUNT; i++) { + stream_sent_cb(source_stream); + } + + /* Keep sending until we reach the minimum expected */ + while (test_stream->tx_cnt < MIN_SEND_COUNT) { + k_sleep(K_MSEC(100)); + } + } + + if (sink_stream != NULL) { + const struct bap_test_stream *test_stream = + CONTAINER_OF(sink_stream, struct bap_test_stream, stream); + + /* Keep receiving until we reach the minimum expected */ + while (test_stream->rx_cnt < MIN_SEND_COUNT) { + k_sleep(K_MSEC(100)); + } + } +} + static void set_location(void) { int err; @@ -333,7 +482,7 @@ static void init(void) set_available_contexts(); for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { - bt_bap_stream_cb_register(&streams[i], &stream_ops); + bt_bap_stream_cb_register(&streams[i].stream, &stream_ops); } /* Create a non-connectable non-scannable advertising set */ @@ -367,8 +516,10 @@ static void test_main(void) WAIT_FOR_FLAG(flag_connected); WAIT_FOR_FLAG(flag_stream_configured); - WAIT_FOR_UNSET_FLAG(flag_connected); + WAIT_FOR_FLAG(flag_stream_started); + transceive_streams(); + WAIT_FOR_UNSET_FLAG(flag_connected); PASS("Unicast server passed\n"); } @@ -405,6 +556,8 @@ static void test_main_acl_disconnect(void) init(); + stream_ops.recv = NULL; /* We do not care about data in this test */ + /* Create CONFIG_BT_MAX_CONN - 1 dummy advertising sets, to ensure that we only have 1 free * connection when attempting to restart advertising, which should ensure that the * bt_conn object is properly unref'ed by the stack diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 8a518c62fe8..3e8ca12fcb1 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -75,7 +75,7 @@ static void connected(struct bt_conn *conn, uint8_t err) return; } - printk("Connected to %s\n", addr); + printk("Connected to %s (%p)\n", addr, conn); SET_FLAG(flag_connected); } diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 9193d423c61..811a5d2a453 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -97,4 +98,16 @@ void disconnected(struct bt_conn *conn, uint8_t reason); void test_tick(bs_time_t HW_device_time); void test_init(void); +struct bap_test_stream { + struct bt_bap_stream stream; + + uint16_t seq_num; + bool tx_active; + size_t tx_cnt; + uint16_t tx_sdu_size; + + struct bt_iso_recv_info last_info; + size_t rx_cnt; +}; + #endif /* ZEPHYR_TEST_BSIM_BT_AUDIO_TEST_ */ From 24d152ace3d05cfd2330e8a413342fbc6de716f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 18:44:50 +0200 Subject: [PATCH 2156/4498] usbc: add "tcpc" shell command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "tcpc" shell command with "dump" subcommand used to dump all registers of all the TCPCs. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/CMakeLists.txt | 1 + drivers/usb_c/tcpc/Kconfig | 6 +++ drivers/usb_c/tcpc/shell.c | 69 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 drivers/usb_c/tcpc/shell.c diff --git a/drivers/usb_c/tcpc/CMakeLists.txt b/drivers/usb_c/tcpc/CMakeLists.txt index b81aa5224d6..cc5eaf71ea6 100644 --- a/drivers/usb_c/tcpc/CMakeLists.txt +++ b/drivers/usb_c/tcpc/CMakeLists.txt @@ -2,4 +2,5 @@ zephyr_library() +zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_SHELL shell.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_STM32 ucpd_stm32.c) diff --git a/drivers/usb_c/tcpc/Kconfig b/drivers/usb_c/tcpc/Kconfig index 51b9a79c394..8d0e2ad1017 100644 --- a/drivers/usb_c/tcpc/Kconfig +++ b/drivers/usb_c/tcpc/Kconfig @@ -19,6 +19,12 @@ config USBC_TCPC_INIT_PRIORITY Note that the priority needs to be lower than the USBC stack so that it can start before the USBC sub-system. +config USBC_TCPC_SHELL + bool "Shell commands for TCPC subsystem" + help + Enable support for TCPC shell commands that helps with USB-C diagnostics. + Example functions are printing vbus, chip information and dumping registers. + source "drivers/usb_c/tcpc/Kconfig.tcpc_stm32" module = USBC diff --git a/drivers/usb_c/tcpc/shell.c b/drivers/usb_c/tcpc/shell.c new file mode 100644 index 00000000000..c1d8869d706 --- /dev/null +++ b/drivers/usb_c/tcpc/shell.c @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/** Macro used to call the dump_std_reg function from the TCPC device pointer */ +#define TCPC_DUMP_DEV(dev) ret |= tcpc_dump_std_reg(dev); + +/** Macro used to call the dump_std_reg function from the USB-C connector node */ +#define TCPC_DUMP_CONN_NODE(node) TCPC_DUMP_DEV(DEVICE_DT_GET(DT_PROP(node, tcpc))) + +/** + * @brief Shell command that dumps standard registers of TCPCs for all available USB-C ports + * + * @param sh Shell structure + * @param argc Arguments count + * @param argv Device name + * @return int ORed return values of all the functions executed, 0 in case of success + */ +static int cmd_tcpc_dump(const struct shell *sh, size_t argc, char **argv) +{ + int ret = 0; + + if (argc <= 1) { + DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_DUMP_CONN_NODE); + } else { + const struct device *dev = device_get_binding(argv[1]); + + if (dev != NULL) { + TCPC_DUMP_DEV(dev); + } else { + ret = -ENODEV; + } + } + + return ret; +} + +/** + * @brief Function used to create subcommands with devices names + * + * @param idx counter of devices + * @param entry shell structure that will be filled + */ +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_lookup(idx, NULL); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(list_device_names, device_name_get); + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_tcpc_cmds, + SHELL_CMD_ARG(dump, &list_device_names, + "Dump TCPC registers\n" + "Usage: tcpc dump []", + cmd_tcpc_dump, 1, 1), + SHELL_SUBCMD_SET_END); + +SHELL_CMD_REGISTER(tcpc, &sub_tcpc_cmds, "TCPC (USB-C PD) diagnostics", NULL); From 8270d0495deb86a747c882e6abd0534476110ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 18:47:13 +0200 Subject: [PATCH 2157/4498] usbc: add "vbus" subcommand for "tcpc" shell command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "vbus" subcommand that displays VBUS voltages for all USB-C connectors. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/shell.c | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/usb_c/tcpc/shell.c b/drivers/usb_c/tcpc/shell.c index c1d8869d706..88ff651b938 100644 --- a/drivers/usb_c/tcpc/shell.c +++ b/drivers/usb_c/tcpc/shell.c @@ -14,6 +14,17 @@ /** Macro used to call the dump_std_reg function from the USB-C connector node */ #define TCPC_DUMP_CONN_NODE(node) TCPC_DUMP_DEV(DEVICE_DT_GET(DT_PROP(node, tcpc))) +/** Macro used to call the vbus_measure function from the VBUS device pointer */ +#define TCPC_VBUS_DEV(dev) \ + { \ + int val; \ + ret |= usbc_vbus_measure(dev, &val); \ + shell_print(sh, "%s vbus: %d mV", dev->name, val); \ + } + +/** Macro used to call the vbus_measure function from the USB-C connector node */ +#define TCPC_VBUS_CONN_NODE(node) TCPC_VBUS_DEV(DEVICE_DT_GET(DT_PROP(node, vbus))) + /** * @brief Shell command that dumps standard registers of TCPCs for all available USB-C ports * @@ -41,6 +52,33 @@ static int cmd_tcpc_dump(const struct shell *sh, size_t argc, char **argv) return ret; } +/** + * @brief Shell command that prints the vbus measures for all available USB-C ports + * + * @param sh Shell structure + * @param argc Arguments count + * @param argv Device name + * @return int ORed return values of all the functions executed, 0 in case of success + */ +static int cmd_tcpc_vbus(const struct shell *sh, size_t argc, char **argv) +{ + int ret = 0; + + if (argc <= 1) { + DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_VBUS_CONN_NODE); + } else { + const struct device *dev = device_get_binding(argv[1]); + + if (dev != NULL) { + TCPC_VBUS_DEV(dev); + } else { + ret = -ENODEV; + } + } + + return ret; +} + /** * @brief Function used to create subcommands with devices names * @@ -64,6 +102,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_tcpc_cmds, "Dump TCPC registers\n" "Usage: tcpc dump []", cmd_tcpc_dump, 1, 1), + SHELL_CMD_ARG(vbus, &list_device_names, + "Display VBUS voltage\n" + "Usage: tcpc vbus []", + cmd_tcpc_vbus, 1, 1), SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(tcpc, &sub_tcpc_cmds, "TCPC (USB-C PD) diagnostics", NULL); From 2e3fcbfaa4078f52526b6de47a620f150d5b46b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 18:48:31 +0200 Subject: [PATCH 2158/4498] usbc: add "chip" subcommand for "tcpc" shell command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "chip" subcommand that displays the vendor, product and device identifiers for all TCPC referenced by USB-C connectors. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/shell.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/usb_c/tcpc/shell.c b/drivers/usb_c/tcpc/shell.c index 88ff651b938..43ea2a9077c 100644 --- a/drivers/usb_c/tcpc/shell.c +++ b/drivers/usb_c/tcpc/shell.c @@ -25,6 +25,20 @@ /** Macro used to call the vbus_measure function from the USB-C connector node */ #define TCPC_VBUS_CONN_NODE(node) TCPC_VBUS_DEV(DEVICE_DT_GET(DT_PROP(node, vbus))) +/** Macro used to call the get_chip function from the TCPC device pointer */ +#define TCPC_GET_CHIP_DEV(dev) \ + { \ + ret |= tcpc_get_chip_info(dev, &chip_info); \ + shell_print(sh, "Chip: %s", dev->name); \ + shell_print(sh, "\tVendor: %04x", chip_info.vendor_id); \ + shell_print(sh, "\tProduct: %04x", chip_info.product_id); \ + shell_print(sh, "\tDevice: %04x", chip_info.device_id); \ + shell_print(sh, "\tFirmware: %llx", chip_info.fw_version_number); \ + } + +/** Macro used to call the get_chip function from the USB-C connector node */ +#define TCPC_GET_CHIP_CONN_NODE(node) TCPC_GET_CHIP_DEV(DEVICE_DT_GET(DT_PROP(node, tcpc))) + /** * @brief Shell command that dumps standard registers of TCPCs for all available USB-C ports * @@ -79,6 +93,34 @@ static int cmd_tcpc_vbus(const struct shell *sh, size_t argc, char **argv) return ret; } +/** + * @brief Shell command that prints the TCPCs chips information for all available USB-C ports + * + * @param sh Shell structure + * @param argc Arguments count + * @param argv Device name + * @return int ORed return values of all the functions executed, 0 in case of success + */ +static int cmd_tcpc_chip_info(const struct shell *sh, size_t argc, char **argv) +{ + struct tcpc_chip_info chip_info; + int ret = 0; + + if (argc <= 1) { + DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_GET_CHIP_CONN_NODE); + } else { + const struct device *dev = device_get_binding(argv[1]); + + if (dev != NULL) { + TCPC_GET_CHIP_DEV(dev); + } else { + ret = -ENODEV; + } + } + + return ret; +} + /** * @brief Function used to create subcommands with devices names * @@ -106,6 +148,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_tcpc_cmds, "Display VBUS voltage\n" "Usage: tcpc vbus []", cmd_tcpc_vbus, 1, 1), + SHELL_CMD_ARG(chip, &list_device_names, + "Display chip information\n" + "Usage: tcpc chip []", + cmd_tcpc_chip_info, 1, 1), SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(tcpc, &sub_tcpc_cmds, "TCPC (USB-C PD) diagnostics", NULL); From 88b6fc62d5aedcf19e09dac75ac98aad671c135a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Mon, 10 Jul 2023 17:23:15 +0200 Subject: [PATCH 2159/4498] usbc: change type for functions that may return error code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TCPC API functions should be able to inform the caller if the function is supported and successfully executed. Bool values doesn't allow this so it is needed to change the type to int. For is_rx_pending_msg function the return code should conform to existing error codes, so in case of function being not supported, the -ENOSYS should be returned. In case of successful execution, if there is no pending message, the -ENODATA should be returned and in case of message pending, the value of 0. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/ucpd_stm32.c | 14 +++++++------- include/zephyr/drivers/usb_c/usbc_tcpc.h | 16 ++++++++-------- subsys/usb/usb_c/usbc_prl.c | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index 7082342dd1e..5a9522ed128 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -1027,21 +1027,21 @@ static int ucpd_transmit_data(const struct device *dev, /** * @brief Tests if a received Power Delivery message is pending * - * @retval true if message is pending, else false + * @retval 0 if there is no pending message + * @retval 1 if there is a pending message */ -static bool ucpd_is_rx_pending_msg(const struct device *dev, - enum pd_packet_type *type) +static int ucpd_is_rx_pending_msg(const struct device *dev, enum pd_packet_type *type) { struct tcpc_data *data = dev->data; - bool ret; + bool pending; - ret = (*(uint32_t *)data->ucpd_rx_buffer > 0); + pending = (*(uint32_t *)data->ucpd_rx_buffer > 0); - if (ret & (type != NULL)) { + if (pending & (type != NULL)) { *type = *(uint16_t *)data->ucpd_rx_buffer; } - return ret; + return (pending) ? 1 : 0; } /** diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 2788aea2e40..97af24bf75c 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -137,7 +137,7 @@ __subsystem struct tcpc_driver_api { int (*set_roles)(const struct device *dev, enum tc_power_role power_role, enum tc_data_role data_role); int (*receive_data)(const struct device *dev, struct pd_msg *msg); - bool (*is_rx_pending_msg)(const struct device *dev, enum pd_packet_type *type); + int (*is_rx_pending_msg)(const struct device *dev, enum pd_packet_type *type); int (*set_rx_enable)(const struct device *dev, bool enable); int (*set_cc_polarity)(const struct device *dev, enum tc_cc_polarity polarity); int (*transmit_data)(const struct device *dev, struct pd_msg *msg); @@ -152,8 +152,8 @@ __subsystem struct tcpc_driver_api { int (*set_debug_accessory)(const struct device *dev, bool enable); int (*set_debug_detach)(const struct device *dev); int (*set_drp_toggle)(const struct device *dev, bool enable); - bool (*get_snk_ctrl)(const struct device *dev); - bool (*get_src_ctrl)(const struct device *dev); + int (*get_snk_ctrl)(const struct device *dev); + int (*get_src_ctrl)(const struct device *dev); int (*get_chip_info)(const struct device *dev, struct tcpc_chip_info *chip_info); int (*set_low_power_mode)(const struct device *dev, bool enable); int (*sop_prime_enable)(const struct device *dev, bool enable); @@ -460,12 +460,12 @@ static inline int tcpc_set_roles(const struct device *dev, * @param dev Runtime device structure * @param type pointer to where message type is written. Can be NULL * - * @retval true if message is pending, else false + * @retval 0 if there is no pending message + * @retval 1 if there is a pending message * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline bool tcpc_is_rx_pending_msg(const struct device *dev, - enum pd_packet_type *type) +static inline int tcpc_is_rx_pending_msg(const struct device *dev, enum pd_packet_type *type) { const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; @@ -767,7 +767,7 @@ static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable) * @retval false if not sinking power * @retval -ENOSYS if not implemented */ -static inline bool tcpc_get_snk_ctrl(const struct device *dev) +static inline int tcpc_get_snk_ctrl(const struct device *dev) { const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; @@ -788,7 +788,7 @@ static inline bool tcpc_get_snk_ctrl(const struct device *dev) * @retval false if not sourcing power * @retval -ENOSYS if not implemented */ -static inline bool tcpc_get_src_ctrl(const struct device *dev) +static inline int tcpc_get_src_ctrl(const struct device *dev) { const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; diff --git a/subsys/usb/usb_c/usbc_prl.c b/subsys/usb/usb_c/usbc_prl.c index 8eb78e5ebe2..9b78f1cd506 100644 --- a/subsys/usb/usb_c/usbc_prl.c +++ b/subsys/usb/usb_c/usbc_prl.c @@ -446,7 +446,7 @@ static void increment_msgid_counter(const struct device *dev) /** * @brief Get the SOP* header for the current received message */ -static uint32_t get_sop_star_header(const struct device *dev) +static uint16_t get_sop_star_header(const struct device *dev) { struct usbc_port_data *data = dev->data; struct protocol_layer_tx_t *prl_tx = data->prl_tx; From 216bc4db731dcbf378203721b1667dca4d1be72d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 12:43:36 +0200 Subject: [PATCH 2160/4498] usbc: add check if tcpc initialization was successful MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TCPC driver initialization can be unsuccessful and it should be checked and logged if that's the case. Signed-off-by: Michał Barnaś --- subsys/usb/usb_c/usbc_tc_common.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/subsys/usb/usb_c/usbc_tc_common.c b/subsys/usb/usb_c/usbc_tc_common.c index 2cbfd30a345..605fad03908 100644 --- a/subsys/usb/usb_c/usbc_tc_common.c +++ b/subsys/usb/usb_c/usbc_tc_common.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(usbc_stack, CONFIG_USBC_STACK_LOG_LEVEL); #include "usbc_tc_common_internal.h" static const struct smf_state tc_states[TC_STATE_COUNT]; -static void tc_init(const struct device *dev); +static int tc_init(const struct device *dev); /** * @brief Initializes the state machine and enters the Disabled state @@ -55,7 +55,11 @@ void tc_run(const struct device *dev, const int32_t dpm_request) /* fall through */ case SM_INIT: /* Initialize the Type-C layer */ - tc_init(dev); + if (tc_init(dev) != 0) { + LOG_ERR("Error initializing Type-C layer"); + break; + } + data->tc_sm_state = SM_RUN; /* fall through */ case SM_RUN: @@ -100,11 +104,12 @@ bool tc_is_in_attached_state(const struct device *dev) /** * @brief Initializes the Type-C layer */ -static void tc_init(const struct device *dev) +static int tc_init(const struct device *dev) { struct usbc_port_data *data = dev->data; struct tc_sm_t *tc = data->tc; const struct device *tcpc = data->tcpc; + int ret; /* Initialize the timers */ usbc_timer_init(&tc->tc_t_error_recovery, TC_T_ERROR_RECOVERY_SOURCE_MIN_MS); @@ -118,7 +123,11 @@ static void tc_init(const struct device *dev) tc->flags = ATOMIC_INIT(0); /* Initialize the TCPC */ - tcpc_init(tcpc); + ret = tcpc_init(tcpc); + if (ret != 0) { + LOG_ERR("TCPC initialization failed: %d", ret); + return ret; + } #ifdef CONFIG_USBC_CSM_SOURCE_ONLY /* Stop sourcing VBUS */ @@ -134,6 +143,8 @@ static void tc_init(const struct device *dev) * short while if this is a system reset. */ tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + + return 0; } /** From 0f4eb42c97e77bc318cfb49c19ff47e02ac53027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 12:46:56 +0200 Subject: [PATCH 2161/4498] usbc: check if message is pending before trying to receive it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If TCPC supports checking for pending messages, it should be done instead of forcefully trying to read the message and getting no-data result. This helps with powereficiency for chips that go to sleep when there is no message pending. Trying to read the message can wake up the chip providing higher power usage. Signed-off-by: Michał Barnaś --- subsys/usb/usb_c/usbc_prl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/usb/usb_c/usbc_prl.c b/subsys/usb/usb_c/usbc_prl.c index 9b78f1cd506..c5923ad9dd2 100644 --- a/subsys/usb/usb_c/usbc_prl.c +++ b/subsys/usb/usb_c/usbc_prl.c @@ -1177,7 +1177,7 @@ static void prl_rx_wait_for_phy_message(const struct device *dev) uint8_t power_role; /* Get the message */ - if (tcpc_receive_data(tcpc, rx_emsg) <= 0) { + if (tcpc_is_rx_pending_msg(tcpc, NULL) == 0 || tcpc_receive_data(tcpc, rx_emsg) <= 0) { /* No pending message or problem getting the message */ return; } From cff8bb2687bc373bce84e13e622585e5bc741eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 14:15:40 +0200 Subject: [PATCH 2162/4498] usbc: check if sampling CC lines were successful MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the get_cc function returns error, the CC lines should be considered as open. It may happen either due to some chip malfunction or chip going into sleep mode and needing time to reinitialize. TCPC should only go to sleep if there is no partner attaches, so in case of this error, the lines should be considered as disconnected. Signed-off-by: Michał Barnaś --- subsys/usb/usb_c/usbc_tc_common.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/subsys/usb/usb_c/usbc_tc_common.c b/subsys/usb/usb_c/usbc_tc_common.c index 605fad03908..88749b51d8d 100644 --- a/subsys/usb/usb_c/usbc_tc_common.c +++ b/subsys/usb/usb_c/usbc_tc_common.c @@ -70,7 +70,14 @@ void tc_run(const struct device *dev, const int32_t dpm_request) } /* Sample CC lines */ - tcpc_get_cc(tcpc, &tc->cc1, &tc->cc2); + if (tcpc_get_cc(tcpc, &tc->cc1, &tc->cc2) != 0) { + /* If this function fails, it may mean that the TCPC is in sleep mode or + * the communication with TCPC has failed, so we can assume that the CC + * lines are open or existing connection is faulty. + */ + tc->cc1 = TC_CC_VOLT_OPEN; + tc->cc2 = TC_CC_VOLT_OPEN; + } /* Detect polarity */ tc->cc_polarity = (tc->cc1 > tc->cc2) ? TC_POLARITY_CC1 : TC_POLARITY_CC2; From 793d29d23f3728bc32871454153f91d86c32d43a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 14:18:29 +0200 Subject: [PATCH 2163/4498] usbc: check if setting the CC and VCONN was successful MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds check in cc_open entry state and logs if setting either of the values were unsuccessful. Signed-off-by: Michał Barnaś --- subsys/usb/usb_c/usbc_tc_common.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/subsys/usb/usb_c/usbc_tc_common.c b/subsys/usb/usb_c/usbc_tc_common.c index 88749b51d8d..63063aea9ce 100644 --- a/subsys/usb/usb_c/usbc_tc_common.c +++ b/subsys/usb/usb_c/usbc_tc_common.c @@ -214,14 +214,23 @@ static void tc_cc_open_entry(void *obj) const struct device *dev = tc->dev; struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; tc->cc_voltage = TC_CC_VOLT_OPEN; /* Disable VCONN */ - tcpc_set_vconn(tcpc, false); + ret = tcpc_set_vconn(tcpc, false); + if (ret != 0 && ret != -ENOSYS) { + LOG_ERR("Set vconn failed: %d", ret); + return; + } /* Open CC lines */ - tcpc_set_cc(tcpc, TC_CC_OPEN); + ret = tcpc_set_cc(tcpc, TC_CC_OPEN); + if (ret != 0) { + LOG_ERR("Set CC lines failed: %d", ret); + return; + } } /** From fe0b6af3375720aa9d5e348e1f6dd57dbe695140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Mon, 25 Sep 2023 18:10:07 +0200 Subject: [PATCH 2164/4498] usbc: merge the is_rx and get_rx_pending_msg functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two functions are used together so there is no need for splitting them into two functions. This commit also makes this function required to be implemented by the TCPC driver. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/ucpd_stm32.c | 41 +++++-------------- include/zephyr/drivers/usb_c/usbc_tcpc.h | 52 ++++++------------------ subsys/usb/usb_c/usbc_prl.c | 2 +- 3 files changed, 24 insertions(+), 71 deletions(-) diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index 5a9522ed128..ae007667a10 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -1024,45 +1024,25 @@ static int ucpd_transmit_data(const struct device *dev, return 0; } -/** - * @brief Tests if a received Power Delivery message is pending - * - * @retval 0 if there is no pending message - * @retval 1 if there is a pending message - */ -static int ucpd_is_rx_pending_msg(const struct device *dev, enum pd_packet_type *type) -{ - struct tcpc_data *data = dev->data; - bool pending; - - pending = (*(uint32_t *)data->ucpd_rx_buffer > 0); - - if (pending & (type != NULL)) { - *type = *(uint16_t *)data->ucpd_rx_buffer; - } - - return (pending) ? 1 : 0; -} - /** * @brief Retrieves the Power Delivery message from the TCPC * - * @retval number of bytes received - * @retval -EIO on no message to retrieve - * @retval -EFAULT on buf being NULL + * @retval number of bytes received if msg parameter is provided + * @retval 0 if there is a message pending and the msg parameter is NULL + * @retval -ENODATA if there is no pending message */ -static int ucpd_receive_data(const struct device *dev, struct pd_msg *msg) +static int ucpd_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg) { struct tcpc_data *data = dev->data; int ret = 0; - if (msg == NULL) { - return -EFAULT; + /* Make sure we have a message to retrieve */ + if (*(uint32_t *)data->ucpd_rx_buffer == 0) { + return -ENODATA; } - /* Make sure we have a message to retrieve */ - if (!ucpd_is_rx_pending_msg(dev, NULL)) { - return -EIO; + if (msg == NULL) { + return 0; } msg->type = *(uint16_t *)data->ucpd_rx_buffer; @@ -1443,8 +1423,7 @@ static const struct tcpc_driver_api driver_api = { .set_alert_handler_cb = ucpd_set_alert_handler_cb, .get_cc = ucpd_get_cc, .set_rx_enable = ucpd_set_rx_enable, - .is_rx_pending_msg = ucpd_is_rx_pending_msg, - .receive_data = ucpd_receive_data, + .get_rx_pending_msg = ucpd_get_rx_pending_msg, .transmit_data = ucpd_transmit_data, .select_rp_value = ucpd_select_rp_value, .get_rp_value = ucpd_get_rp_value, diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 97af24bf75c..15bdacf9c8a 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -136,8 +136,7 @@ __subsystem struct tcpc_driver_api { int (*set_vconn)(const struct device *dev, bool enable); int (*set_roles)(const struct device *dev, enum tc_power_role power_role, enum tc_data_role data_role); - int (*receive_data)(const struct device *dev, struct pd_msg *msg); - int (*is_rx_pending_msg)(const struct device *dev, enum pd_packet_type *type); + int (*get_rx_pending_msg)(const struct device *dev, struct pd_msg *msg); int (*set_rx_enable)(const struct device *dev, bool enable); int (*set_cc_polarity)(const struct device *dev, enum tc_cc_polarity polarity); int (*transmit_data)(const struct device *dev, struct pd_msg *msg); @@ -455,50 +454,25 @@ static inline int tcpc_set_roles(const struct device *dev, } /** - * @brief Tests if a received Power Delivery message is pending + * @brief Retrieves the Power Delivery message from the TCPC. + * If buf is NULL, then only the status is returned, where 0 means there is a message pending and + * -ENODATA means there is no pending message. * - * @param dev Runtime device structure - * @param type pointer to where message type is written. Can be NULL - * - * @retval 0 if there is no pending message - * @retval 1 if there is a pending message - * @retval -EIO on failure - * @retval -ENOSYS if not implemented - */ -static inline int tcpc_is_rx_pending_msg(const struct device *dev, enum pd_packet_type *type) -{ - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; - - if (api->is_rx_pending_msg == NULL) { - return -ENOSYS; - } - - return api->is_rx_pending_msg(dev, type); -} - -/** - * @brief Retrieves the Power Delivery message from the TCPC - * - * @param dev Runtime device structure - * @param buf pointer where the pd_buf pointer is written + * @param dev Runtime device structure + * @param buf pointer where the pd_buf pointer is written, NULL if only checking the status * - * @retval Greater or equal to 0 is the number of bytes received + * @retval Greater or equal to 0 is the number of bytes received if buf parameter is provided + * @retval 0 if there is a message pending and buf parameter is NULL * @retval -EIO on failure - * @retval -EFAULT on buf being NULL - * @retval -ENOSYS if not implemented + * @retval -ENODATA if no message is pending */ -static inline int tcpc_receive_data(const struct device *dev, - struct pd_msg *buf) +static inline int tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *buf) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - if (api->receive_data == NULL) { - return -ENOSYS; - } + __ASSERT(api->get_rx_pending_msg != NULL, "Callback pointer should not be NULL"); - return api->receive_data(dev, buf); + return api->get_rx_pending_msg(dev, buf); } /** diff --git a/subsys/usb/usb_c/usbc_prl.c b/subsys/usb/usb_c/usbc_prl.c index c5923ad9dd2..ca0465bac6d 100644 --- a/subsys/usb/usb_c/usbc_prl.c +++ b/subsys/usb/usb_c/usbc_prl.c @@ -1177,7 +1177,7 @@ static void prl_rx_wait_for_phy_message(const struct device *dev) uint8_t power_role; /* Get the message */ - if (tcpc_is_rx_pending_msg(tcpc, NULL) == 0 || tcpc_receive_data(tcpc, rx_emsg) <= 0) { + if (tcpc_get_rx_pending_msg(tcpc, rx_emsg) <= 0) { /* No pending message or problem getting the message */ return; } From 3848e4c023f6dea9cf9c41e30e21345f12e161f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Mon, 25 Sep 2023 19:21:54 +0200 Subject: [PATCH 2165/4498] usbc: add checks for results of TCPC functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds checks for results and in case of error, handles it. The failed initialization of the TCPC can postpone initialization in case the TCPC needs more time after powering up. Otherwise if other error happened, the Type-C Layer will be disabled. Errors in other places of the USB-C stack, like communication errors, moves the state machine to the error recovery, restarting the communication with parner. Signed-off-by: Michał Barnaś --- include/zephyr/drivers/usb_c/usbc_tcpc.h | 1 + subsys/usb/usb_c/usbc_tc_common.c | 47 +++++++++++++++++++----- subsys/usb/usb_c/usbc_tc_snk_states.c | 15 +++++++- subsys/usb/usb_c/usbc_tc_src_states.c | 28 ++++++++++++-- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 15bdacf9c8a..1b62a39db68 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -231,6 +231,7 @@ static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, * * @retval 0 on success * @retval -EIO on failure + * @retval -EAGAIN if initialization should be postponed */ static inline int tcpc_init(const struct device *dev) { diff --git a/subsys/usb/usb_c/usbc_tc_common.c b/subsys/usb/usb_c/usbc_tc_common.c index 63063aea9ce..94b34edf218 100644 --- a/subsys/usb/usb_c/usbc_tc_common.c +++ b/subsys/usb/usb_c/usbc_tc_common.c @@ -38,6 +38,7 @@ void tc_run(const struct device *dev, const int32_t dpm_request) struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; struct tc_sm_t *tc = data->tc; + int ret; /* These requests are implicitly set by the Device Policy Manager */ if (dpm_request == PRIV_PORT_REQUEST_START) { @@ -55,8 +56,15 @@ void tc_run(const struct device *dev, const int32_t dpm_request) /* fall through */ case SM_INIT: /* Initialize the Type-C layer */ - if (tc_init(dev) != 0) { - LOG_ERR("Error initializing Type-C layer"); + ret = tc_init(dev); + if (ret != 0 && ret != -EAGAIN) { + /* Transition to Disabled State */ + LOG_ERR("Disabling the Type-C Layer"); + data->tc_enabled = false; + tc_set_state(dev, TC_DISABLED_STATE); + } + + if (ret != 0) { break; } @@ -137,11 +145,19 @@ static int tc_init(const struct device *dev) } #ifdef CONFIG_USBC_CSM_SOURCE_ONLY - /* Stop sourcing VBUS */ - data->policy_cb_src_en(dev, false); + /* Stop sourcing VBUS by policy callback and/or TCPC */ + ret = data->policy_cb_src_en(dev, false); + if (ret != 0) { + LOG_ERR("Couldn't disable vbus sourcing: %d", ret); + return ret; + } /* Stop sourcing VCONN */ - tcpc_set_vconn(tcpc, false); + ret = tcpc_set_vconn(tcpc, false); + if (ret != 0 && ret != -ENOTSUP) { + LOG_ERR("Couldn't disable vconn: %d", ret); + return ret; + } #endif /* Initialize the state machine */ @@ -197,12 +213,22 @@ void tc_select_src_collision_rp(const struct device *dev, enum tc_rp_value rp) { struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; /* Select Rp value */ - tcpc_select_rp_value(tcpc, rp); + ret = tcpc_select_rp_value(tcpc, rp); + if (ret != 0 && ret != -ENOTSUP) { + LOG_ERR("Couldn't set Rp value to %d: %d", rp, ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + return; + } /* Place Rp on CC lines */ - tcpc_set_cc(tcpc, TC_CC_RP); + ret = tcpc_set_cc(tcpc, TC_CC_RP); + if (ret != 0) { + LOG_ERR("Couldn't set CC lines to Rp: %d", ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + } } /** @@ -221,15 +247,16 @@ static void tc_cc_open_entry(void *obj) /* Disable VCONN */ ret = tcpc_set_vconn(tcpc, false); if (ret != 0 && ret != -ENOSYS) { - LOG_ERR("Set vconn failed: %d", ret); + LOG_ERR("Couldn't disable vconn: %d", ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); return; } /* Open CC lines */ ret = tcpc_set_cc(tcpc, TC_CC_OPEN); if (ret != 0) { - LOG_ERR("Set CC lines failed: %d", ret); - return; + LOG_ERR("Couldn't set CC lines to open: %d", ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); } } diff --git a/subsys/usb/usb_c/usbc_tc_snk_states.c b/subsys/usb/usb_c/usbc_tc_snk_states.c index 36e8cef7db1..273f4bacdbd 100644 --- a/subsys/usb/usb_c/usbc_tc_snk_states.c +++ b/subsys/usb/usb_c/usbc_tc_snk_states.c @@ -174,11 +174,17 @@ void tc_attached_snk_entry(void *obj) const struct device *dev = tc->dev; struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; LOG_INF("Attached.SNK"); /* Set CC polarity */ - tcpc_set_cc_polarity(tcpc, tc->cc_polarity); + ret = tcpc_set_cc_polarity(tcpc, tc->cc_polarity); + if (ret != 0) { + LOG_ERR("Couldn't set CC polarity to %d: %d", tc->cc_polarity, ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + return; + } /* Enable PD */ tc_pd_enable(dev, true); @@ -227,6 +233,11 @@ void tc_cc_rd_entry(void *obj) const struct device *dev = tc->dev; struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; - tcpc_set_cc(tcpc, TC_CC_RD); + ret = tcpc_set_cc(tcpc, TC_CC_RD); + if (ret != 0) { + LOG_ERR("Couldn't set CC lines to Rd: %d", ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + } } diff --git a/subsys/usb/usb_c/usbc_tc_src_states.c b/subsys/usb/usb_c/usbc_tc_src_states.c index 2fe703dfb76..972c7cdef54 100644 --- a/subsys/usb/usb_c/usbc_tc_src_states.c +++ b/subsys/usb/usb_c/usbc_tc_src_states.c @@ -222,6 +222,7 @@ void tc_attached_src_entry(void *obj) const struct device *dev = tc->dev; struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; LOG_INF("Attached.SRC"); @@ -229,7 +230,12 @@ void tc_attached_src_entry(void *obj) tcpc_set_roles(tcpc, TC_ROLE_SOURCE, TC_ROLE_DFP); /* Set cc polarity */ - tcpc_set_cc_polarity(tcpc, tc->cc_polarity); + ret = tcpc_set_cc_polarity(tcpc, tc->cc_polarity); + if (ret != 0) { + LOG_ERR("Couldn't set CC polarity to %d: %d", tc->cc_polarity, ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + return; + } /* Start sourcing VBUS */ if (data->policy_cb_src_en(dev, true) == 0) { @@ -287,6 +293,7 @@ void tc_attached_src_exit(void *obj) const struct device *dev = tc->dev; struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; + int ret; __ASSERT(data->policy_cb_src_en != NULL, "policy_cb_src_en must not be NULL"); @@ -298,7 +305,10 @@ void tc_attached_src_exit(void *obj) data->policy_cb_src_en(dev, false); /* Stop sourcing VCONN */ - tcpc_set_vconn(tcpc, false); + ret = tcpc_set_vconn(tcpc, false); + if (ret != 0 && ret != -ENOSYS) { + LOG_ERR("Couldn't disable VCONN source"); + } } /** @@ -312,6 +322,7 @@ void tc_cc_rp_entry(void *obj) struct usbc_port_data *data = dev->data; const struct device *tcpc = data->tcpc; enum tc_rp_value rp = TC_RP_USB; + int ret; /* * Get initial Rp value from Device Policy Manager or use @@ -322,8 +333,17 @@ void tc_cc_rp_entry(void *obj) } /* Select Rp value */ - tcpc_select_rp_value(tcpc, rp); + ret = tcpc_select_rp_value(tcpc, rp); + if (ret != 0 && ret != -ENOTSUP) { + LOG_ERR("Couldn't set Rp value to %d: %d", rp, ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + return; + } /* Place Rp on CC lines */ - tcpc_set_cc(tcpc, TC_CC_RP); + ret = tcpc_set_cc(tcpc, TC_CC_RP); + if (ret != 0) { + LOG_ERR("Couldn't set CC lines to Rp: %d", ret); + tc_set_state(dev, TC_ERROR_RECOVERY_STATE); + } } From 5246cea80047bdbe0794b4dc96e3e0873f5ef984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Fri, 29 Sep 2023 16:27:47 +0200 Subject: [PATCH 2166/4498] usbc: improve error handling in the ucpd_stm32 and vbus_adc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As noted in PR#63165 checking of result should use comparison to success value instead of checking if result is negative. It will allow to check if function returned invalid but positive value. Signed-off-by: Michał Barnaś --- drivers/usb_c/tcpc/ucpd_stm32.c | 2 +- drivers/usb_c/vbus/usbc_vbus_adc.c | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index ae007667a10..2fca84346fc 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -1366,7 +1366,7 @@ static int ucpd_init(const struct device *dev) LOG_DBG("Pinctrl signals configuration"); ret = pinctrl_apply_state(config->ucpd_pcfg, PINCTRL_STATE_DEFAULT); - if (ret < 0) { + if (ret != 0) { LOG_ERR("USB pinctrl setup failed (%d)", ret); return ret; } diff --git a/drivers/usb_c/vbus/usbc_vbus_adc.c b/drivers/usb_c/vbus/usbc_vbus_adc.c index a1fbe6f3421..1b2d576a3ed 100644 --- a/drivers/usb_c/vbus/usbc_vbus_adc.c +++ b/drivers/usb_c/vbus/usbc_vbus_adc.c @@ -146,13 +146,12 @@ static int adc_vbus_init(const struct device *dev) /* Configure VBUS Measurement enable pin if defined */ if (gcp->port) { - ret = device_is_ready(gcp->port); - if (ret < 0) { + if (!device_is_ready(gcp->port)) { LOG_ERR("%s: device not ready", gcp->port->name); - return ret; + return -EIO; } ret = gpio_pin_configure_dt(gcp, GPIO_OUTPUT_INACTIVE); - if (ret < 0) { + if (ret != 0) { LOG_ERR("Failed to control feed %s.%u: %d", gcp->port->name, gcp->pin, ret); return ret; @@ -161,13 +160,12 @@ static int adc_vbus_init(const struct device *dev) /* Configure VBUS Discharge pin if defined */ if (gcd->port) { - ret = device_is_ready(gcd->port); - if (ret == false) { + if (!device_is_ready(gcd->port)) { LOG_ERR("%s: device not ready", gcd->port->name); - return ret; + return -EIO; } ret = gpio_pin_configure_dt(gcd, GPIO_OUTPUT_INACTIVE); - if (ret < 0) { + if (ret != 0) { LOG_ERR("Failed to control feed %s.%u: %d", gcd->port->name, gcd->pin, ret); return ret; @@ -179,13 +177,13 @@ static int adc_vbus_init(const struct device *dev) data->sequence.buffer_size = sizeof(data->sample); ret = adc_channel_setup_dt(&config->adc_channel); - if (ret < 0) { + if (ret != 0) { LOG_INF("Could not setup channel (%d)\n", ret); return ret; } ret = adc_sequence_init_dt(&config->adc_channel, &data->sequence); - if (ret < 0) { + if (ret != 0) { LOG_INF("Could not init sequence (%d)\n", ret); return ret; } From 8ffb64d46f2422ba166699c25fb2a7ecedf5f7ed Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 28 Sep 2023 13:28:33 +0300 Subject: [PATCH 2167/4498] net: lwm2m: Allow configuring update period Add new configuration value CONFIG_LWM2M_UPDATE_PERIOD that allows calculating update period from last update, instead of calculating it from the lifetime. In runtime, server is allowed to change the lifetime of the registration which causes update perdiod to be effected. When fixed update period is preferred, UPDATE_PERIOD config is then used. Signed-off-by: Seppo Takalo --- .../api/images/lwm2m_lifetime_both.png | Bin 0 -> 17612 bytes .../images/lwm2m_lifetime_seconds_early.png | Bin 0 -> 14563 bytes doc/connectivity/networking/api/lwm2m.rst | 47 ++++++++++++++++++ samples/net/lwm2m_client/overlay-queue.conf | 6 ++- subsys/net/lib/lwm2m/Kconfig | 12 ++++- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 22 +++++--- tests/net/lib/lwm2m/interop/prj.conf | 2 + .../lib/lwm2m/lwm2m_rd_client/CMakeLists.txt | 1 + 8 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 doc/connectivity/networking/api/images/lwm2m_lifetime_both.png create mode 100644 doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png new file mode 100644 index 0000000000000000000000000000000000000000..1cdf0bbb662965d525b6b24f6dade674d9b2f0fe GIT binary patch literal 17612 zcmd^n2Ut|wk}e`Bh)PZ>N=BmOAVG3&K!P*^LIX`~GBh~~LK9VjWDyZ0C&@X9f|7HP zBp_KpBniIN2|T5ATC1x53ae^=qSRF6E?u~C0Rsc$l7hUn zItB(N1YGCfoCDt;uCLd?pEHi?a*`PNo!1sIFi7m2WS~yguBH|UI0gfc)UPWBZccMs zM<)gzX$Ed?n4KMmi3QBe0cP#UVFPypL*Tx(t%-%H1>EG<9Bxi-9(GP4c5XpUP9X*! z30_|C#m&dT&%=5D*L;{6+~$NJ#Ma#cfq*e^%kpt>0#Y}jTwDx1lHf|&!p7MZ{B;%N zH{j=G23Hbxb_lpO+(^j+tSigMBf!DKkA6f+UK66sz%2!?5f)Z(@J9}AY-NjnM9SR3 z)*6h+a&ZZ8aH9W#K@FHG%)#O}5@;Tfa0f>VTbmOWxH$MZgnn%n?gTSCVO~?n#K^(S zK?UMyWzS{cqNIa>{+i?DW(WT@#{`bFFa`^9Gw{eTa7qBe=ns$7iO|3g8yMKou`tzu z9N4*jQLs1>9=o|SmjKMjQXOhyq-HOtaNo`OSjfLqJEdvuD(3*RGl$rkz!8A3iR;Pc z1vmwM5jAo9HNwR!c*2aC!|6gN>!JrVEZk3a#07SX7KWL#g$dm8L;Q7A+rq@j{MTGTzLV{t zXUoGa%*;<$=HfiLV+}iUd@p8 zOwgt$>0)l-1lO>GfzZGs?E<_u82hu;nA+Mn{T1(Mg78yh{Mxx4?B9?0(@4R?_h+o} zoM7!Yi{KJC8T;KNPUoFs@^|$A?*Q`OrD@*3Xj)56T0&FiFN$?Ax3xBM1_t^M#s8b1 z`(3pR+&m^QxS**qcr`f;Lgbw{_ko>=tS}-X35R_SM8iy?(fPu9s4g) z&IzD?GsC~A1%%||Y{?V>cRdLc=vZ(XF^mx~M@I{^_#)7{n z{`4&HTP)x{O@)4UH~*!v;N+n5&)kg}@Evw1fcUGwJ~_d_j7~G;6Ce8@7-j!Hqx-{( zf0yj3nf)%=Q&T*(_W#r^GOxrH*-Dl#%eO^3aaSi&;OXz{NIY((=*s#b3LyAD(`!ot^W(vk<%02-wIK` z+v@S%)6&v2=g@W)a zGcAS0hck4h7gJMHgDJ$_QYpkq&Zg25DO2yagyEj04L+l$Ol>N2G0t_K?Z|3qe>uOd zIUvQuY#zDeSxTk^bI;B}zAESx($ZLd?sK%)7A-A~^~a}}=ru!6`gK}NTI!QeC9XX0 zoM}4KA5)|o=o9*J|Mrs_>kKM`;PJO$oM7LRk34S{{vSVr#c?o+AT-pAgoFfVPCk## z)o=XqgTRjfi#|b8yqE4hLjxbY)N&vjiH#SdT8gLcd-18}Gt4P9GW2%TB*fDcl3(1! zx_94#;oxAso^`Iaoh1kQ@Z2TDq}NUNq7orJghHLN#gT9Hk-Ov4rSvktLyD5jJ`kM-K}nGr%d zS;3UgIrM1R&8di|WsQ4?KUs=2zx}o0?CP*_WS(pDt@es&BnYtC4q( z3L77uul_MwW^Fa;xfQ;>IyO}H$=%9oC||#GC;dXf`5T_yr9;uo8V=st$GQ;j1&U;- z4YYdg9h|Y%Dcq$asjl%{%nR}P-IMPF+6Fp@``cEp158_qAg{93vdtB}*5?y#ZO&6U zJ=XVFEqxIh&5|JLa~D4ZC|R76;ITQ&L)m;3izzV#D#=mvRq|ja^j0oVLB1>4T*X28 z-qwOJ%|M>6z|IcoJ?M+HUE{Z5MLGFZ?P3QjJY#MP$*Z5ERLf=~?|iB|+PBKlF8Jg? zi-Y$b?8F-Cy?YI>zx#!h^?;Uk>1e6d7*N{U<|o(L@Kx|Y8Q+jzA4lb9qN{hjYaA^$ zCXFM6-o~tMcHAo0Ht-s#yjC=-ha7<;8_t{;ygOX)^D~6|llyXB*=pGs$3jYTwrp+I zc~~ zWKiF$O~#@3CHKLIpz&d|=t7^|4KEXDg8!OO0He)E@S|T850vtf+`q3_@R)VJkqy66 ziM+j1*vztdp|6gwM|E2T4gYsRzS0_EZ@wYSF@qV&dd{3Zr|G${@Z6_Nr^Iwb$1EAn zu3PqIA;lwKlGAx*xaYFaX9A{xPi_lTOmS5%>uYT4^jO`@nMp=wDQ+2|DEBWff|4qz z2N{#iY1b!QCMWE42(`a`AF~w}AjK2G`~rqb2lI5RU8WSrocbWi7|=3AJnIeG<#%+E zZ&dFb_9Mrv1$J!4eeN9Xz6@=X4EQ=?;Bz<^Kq)x`SavbOE+P!Gs5<;UmZ$WLV-4T! z>x9I^b0gP1R$%yde%J+?(~{wC@Y+p@?_3Wc#k}PAG}3%#Z|9Rom;I2p`bJS+HY#)moTc8$g? zGLw@i(jPqc+(hM7uT`nMp0k|nrc(L^zDq=p&9fzT6}+9R#O;=pI4cYgMY)d&D6mYr zQbem~=*K<^Os@FH6=4)n8(WXSpXsl33a{rjJZcaZc?HlKO~9=b%f{6%*>s`hJ!b$V z^MGiOIql_l=bg4bgbRE!j}-k5eYKk-J1)!^N0!pK|?{50|$vL@#teV0oEbqd$akYYreofo>Lx8rgzDmYwN&M!xfSY)Zi~z}7zD7HPr)18uekviKe=x& z%^h8O5z>0eirD&Dj+a}(Q?&DM@dMz#cAxnXT$#Mj3HaUH9q$333*(4%e6igIRERQa zonWjl19H{l`-oYd*THwvNFzdEjkVlwd8ad)oCAC%)2VChm{#k59&toErQw$AsMQea z_P>NE&U(O?G=FR}{ zNV3yrhZZ(qOVf!95=HXOr-gDjFx9H}ox6&dV$-^6Q}F_lA~MoSx#tAbC$tR75V!kz zE$v|{d?t~M{l1BT_ui|L&2(Z&%beX(7gN5n>rz&xo-*l7xcI8Tq-S5*h-so)8py8NuRR|Iydm86Xm5dBpEqzi%=vY98p^d;Z#D7Co9oSM`Lva#_M$xx;l6LJoolm+BQ>fD$2OwXM*WU+1%pD%Sy)clcdEgtwGV5L`45CakEDS=VL$X`At#??9$tu$G+FR%#MtGHhf_2u%wMXe_shPlg|&Qo>XeX$3QS)Y+P4I* zpXD$F+`5v5hbl3cJ(jv&Qxn;@63TZT5YpGMx~gh?Wm3CoKx3TXnYb_$CNI-q&vMyM zJ~^8;!PO;yCpJxWiRw82(Z|Flh9qGc5l-P(Ycdetq(6g&)i|Y#D3XyWgGN-mBP7f? z&OBOaQ@8V=CbQ29q&0qw=CUb$VCJ*=Zo1i|&SU#YgsGEIrSWQI2T=qIJ4mWDL2@S3 zdNt<*LxRzO-kdJfzg#GxQ-Oc&nq_Y~DpY1>$$x4>X--L=kNgbbO)?-iqbK18bwrR2 zE1nqWapssB0P;6Q9O0RQr{*E9XR}<7Lx;DiP$a<)s*zNZQRK^vl0&)QHzd4R9UU;-Q%O$hglgSxiveBrW%uQsY4DlVI#=CY$i3t_dc5lNd z*W|RfD|cV}Xfmd5yx5c2GUgpRkIJBZ9T{h;W7mTfq)e_izvQ|va)A9}hE8mRB1R>$Y05D^sO^G3GL;p8de-V>2;?Gb}>kn1E{HcNHCvXCp=D&ZyI10^TybYb@Zl} z0imN4Wj_%R9p=ukPDi%)Mt?nbZ~NE6*>Yer?mwP>TlGg}&`aFa|65v~YQ84)g7h@u zCh(&te*B90eO^u#>NHCy2?M^mQH_P}G%rWbF;{e0&bIlbK=6%CN8O{z8Qm^_!jv@i zd%)P!@hWu4`b9{*5p0e0;wx^V)5YYu0ZQo0^OqRW0z-e)I04GArLw~Q*xyrS;B@~3 zx1(E%E3)~HZm`I>&2r)8MQQ3Am`g5u-MuBWYPZ4KuZ;5qTEoN_I+IuZ&R;L=xK%&C z|80@Dq&KI+o`KV-1?Qm4=g2sS3K<7U;APGqP^*-oegZfp8p+Mpq`}d1c+c=1q!q*C zm5zDN%Y(?~O9CXcx^py`l(^rP209*i@4?4lK~%X9YTfzGyQzDCEP@Gu6ma++g%GiW zM6b8O@9b)Nlu9x1U!yklhe)g8LfD%N*}W|(4Nn=A^ls!B)YmN=KRl0*bOu)B)t8Nl z3uGT%cuvdtf?Pu=W4)ce=SC|!LoI*3TD6=X=<&pX#R{{;^rM6SVhgcqE`dUpS3&NX ztW8=18o)83CY7y-NO=`XZC{=hZ4Ut!vnvKpX~sgjI%_n2nSEY~*JH~ta@X9GI;GR1*ohb{^w z9aR;KBOL`$#5*SQDg?t1fj89qN-0?w9?myt7y4jzw3JTGh?M3smiNJ`08^FE-W>Um z%Tj+MhqzFTVEL#tWm{@N4w!}B|n zsMYVQV`E>Zn|b_k`gYo%rCD-d@}Z$WKfL^rkcj{}eTC05dV76x5|?Rh@Gg;`6IR6* z9$p_fLac`IbiTX5jF=?009MqCUXIP-ub5p@gLU3o?G0%3gjw}0B$o&hL z+WO8h`i>v@_+d?0V`k629O}5A*FEFm5&Z>YY*NTYrwBMJN?aYM`+4)Hm@RN#xUJMQ zsB3EtPB;n|Fb7^HV5x|1YwA|my(p1JA2T&=5|pH1EQ?ZmAFvtN;~v~o$HXRwM2oG^ zYV;;7!D-cKG4-pFr81#pl`_Tlvu_#Pa~=@$VTO|5Lejd=h6|MG+Sc+}wraR-Qd4&r zTrVU#dM&NdbQL;~Ly7t0!30EL;&XsT&}Ayi3<7tnaKbn-uPVo(?<*sHhY?BYHQ?CS zT77sy#~qa+*{k`0mVlbmZPUceqGGLTIoD%n%}9e0>um&;m07ZLEb#|9Dre33{@Wu1 z(dLTCgLw^MREDSdq7LD^sD>K1tt7iqpPz@;0J?78x{+<+;`QE#D;sS$T>P`Na_-r) z*0m>s1Td=V5fk;Xhm&Fay0`GW+8}S?om(Qmb;u8XxPb=N{D=72{G>QxmwY~O7RU&B zu|tMV8wpe2@+zS+;`oz7sPKUYY<-!0K}%65;erhJ{XKbJnH*8eVqPK$pMt@<3h$X4 zeY_5z{GEr*EW>Uj}vcb#O%2>kLd@y zGn4H1-vr-X)$C88=JYx8WJ&_(WwYiW{4Qt!r&j@Edx1-ccqQ=bEIZdz_q8pi?^iix z>HfH9;N@%v%hsm@caY(`e5_-B> zW-Ey0^(%IT*GR}J^j#+S)&?~8=p+pXb9GdLpW8Lz&KDq_n1{&EzNVmkED6G{z9g0d zG~wLkYhTDp(JmG@06M&hdha9saSO+Of_lez z!65L9qu@aL2y5t`Rw$+)@aQ8TTp)y33Lg&SXsf0%UkFd*4i@)C$?I*}KO(ar@y$we^f74#9N>zdJ#e=Wvgr~#$aVhG z-I(IO#5`MxKG=Q#Ul~*wn!XfSe&as881vR}_1Z-Bs76LTBrZwI#wH!&X%D4EK zC{V7UDmqYwTumrT#`$L5|N05K{_!0c>sWS9{!+^9QMB^p1|^m2l;0!D)u3olovN;0 z#ogqP>^x{szN~NGN;+5!?+B@xYMb*oB8mLzdn1Ek-XHI}&*8Qst?UP{(Wp zu&Tdt=w#iNHor>up{kz`KOBIwa@{I8o*_X6M+mt` zpN|^0E}uaA%yJ+f+scBbN0mtn@_KhS0VQqsh&|g-_A0Mfq@+xs67_-X)&qobTSVz4{^5p8h=2%k$k9%cYXoWrR6Xq;MqQ3sD^JO< zUb{Wp1%jn%`M5(UmB&iany9ZN^{!Kw=*}>Zzyk$oUhC2R%VN8RO!A*V1PNx-_p5<8&J&$atYIl$0MLQt{qIh~)<-#M31fDbqEuUskaU|ISG zj#pKv&u_2VzR|j;(>lI95ZG>9V#)6NEBQ!6zd*d5e6CxKw8^{gH6LXMGv>!kIi;&2 zZjU(C14FY}g+-;<9GUt3{Mw8^ArdO+y3tC`I@ml_)#&~%hV-+a_zp8$rpu()&^8m+ z;XPgJn6jlej!PM0#4odRL*oaHe_rlNh5&;&To2JM8Ket?mQYIJz|;(>Dq~%JIAbduKI7*#!V@E?psMV%+`<~f^ z;$bCb#M8dJU!pIjD3iUsF6us9yYp!oc{7VSahq+ZLG^GP{|b`iC{6h12T-gw)U~O6 zWo3dS@lJz(o!eh6LBP{X8Xu$1vJxrTP&i?X`B}Dt^jmeiO_U4-JBum>Z}0KK ztc}VWY(f=iqs%ce&pyP%rHpQTk5_W-A!-7@t5B+W)E}FfPey|GF5`!}XiCDUF6qR) zvj-8bpoTTV)pjlF9xoS^FlI%$Zxze7ZqL-rNX0oXBT@OVyi?nECv+YN)E6F{I^!j0bHr z7h8J9&Cm?aWqXdbT*tzV*fPB|l=F=TU(W9H)36q{ScaBoff85;S6H6;X6(iKm+g!R zulZsh7u4;yLwLn{&e*%1q0}aw8h(|2KsczEhU+NcvY)P`EWS8ywwUsf-<(3TVq8UR z&xE{Vis}CC;KG zB*(+*GQ@7al<={)WycQJ5HcHU-JV5{sX*W0Osf3t=+i6ZA|6;9x8$Q?2{PAl?@FSp zin+HuZ$6Hv!PH~n=d~^ZbXwnQFzgW=tzHD0>kvhTXl)HcMJ(Q1kFzGX(3I#5OJzPPK&6* z=)$x6py?BP^s{Wl5Z zl=WKpHVmHor{R9W`sh~gk>Rc;=RaV7<1-Ot_HDT1nSEsvthdM3Ur15>#8A@gT1f?= zYq*R61uG$v?O;N1w(UH=+3cfI6qQq%uZ7PS>>YyH@lZxGVlpGWO+?vc!71Mwc1YH2 z682@9*0&+8*Ojh0QpR$znN&7ik2V*+t{1-PvVA$=z2D%11CKCe3+f+ z+Hec8$J=wRU%Fq|KstbcLkLAWUA}13*DwV$@Ye-jVN=PqekmJXoFeLRFI$D8Cpzn> z#lJ_pDMQb1s?nKi#XX6cAc=c=-ZVMG$8E@#qNl|LRX|r3R@dZ00Et(BFGI|PQ5a_; zEZXM3{E$FHwQDcLP{ovBw`+?O(kSBvj`7YTz0~L)-Bpnv0&xx~#@j5WeNMP{yoaNV z7FAStMYMIT`N)G;Rb_WkvA9C|cGoe_ku#z$huKb^Z=QYB(km54PDQ`nuc*d5{gm!Y zM5+R&0uO`#cDxfqLX!%sd%hk{AqCGuVPzBiQLqs3!mFSFfV}sm&^R7KYagEUj?Pd( zdxk2QW`>4`fz0Nu^X;C1YW!zc$j;747s_t!^!GW&kAIElmupEj;G70UkF>aG5Vkt86|R-ya7zL)QvYK0b&sAF*GB)~pkO2eTR>5?JE1+a zr)4xaF~XVmON5H{(9=*xB#AObLGAZZhq=b~W}9=ZL6e^zw)D%+DQJdBw9Z^}a+@Q9 zfU<=nqvg*BGl@82%Fl++5OGo{1Hfijku)JWedST`X?B8kZ@KSAjD1GWaLp;u_L9b(ZOLiDO{kAEDm`5Lysq<#xQm zWYWjLZxm)7KsYO6ZZYGQ&r2(bOwHF%wE%Gd=hxJMYS96i!hoHuuO z9DJF#?*|*|m{+G_T%b$f)_+OxNa<_5CuU=Fe%m6OXBd-z8LW9hB2od`BVD<;lUtC* zB&)Hk@6Z#V^awlQOhQ7OJSR^tpt)$}FrJKEHOXMDxTf>A*c?e>~J^pguRZ$ud7 z^_&{1RI_9>fV#74npEC+-qJX4s@}RE5GnYMcKh44v?%^&t!KBVpWNZlbmdks)ae*N zI;jPia=vAol*n3;p>D^rJD44%jU^D!w50VWAZ&8n3xmIC7OO5_yB3a~Y_%Dc{EzmE= z0Bs77W8eI~vyZ)HmM`b3*2ZaXW`k~_=YzP^J%Mxhjj>`3TD;RN47-=` zt_y3f%PNyX;<_t^Lpr_+qKHIFn|BJKJuso##;K2k$One@3XDa%pr9a)`G7wCDo+a~ zES!2bI^0Ao?Y)6egCD7X#Y5a>;-7ElBOw>@1h-gdl#HdhvTuOt6*jGyXs2?=^tTzqge-^6m zc8K($vX$X9*Zf!+pzj_|lh=9q+nWUvKt7Z}e+c$}#;3Y_PJ}?hZ@D8B2Yy}F(9Oz> zL`Fkw*}e?QeZz;Gq!>j2i8JF`H-a^gbSz%vEZg?y zC4g_~U?+SE{q~iChuWUlu+vl^P%8q}ofyKSZ=;}Vmx&XF(-lyAll`KwC>`cqx`rAq z(+?Eog@o=6Gwn6aX>F!~kaKwV#f;-`8%a=KK37g;e+}vrzigK`wS;p{)UiM15`JdD z2pg>mP7`A+A*_udvEqxTB2&U{SOsD3yL8Q-X!lBZhJ6I}O#iieSN!|;Zf%Jfo#T?t zWi4XZ%Rm_U))+RsHz#4A#e7x7IjtpLNb_~`5N2a!4$X<%dW|Qsl56#bJ(TZajS{ax z4@u2!XawjShEY1&d=R3vG+$8M4CEA{QcR+0j!fg38*m>$bq^UgC*aLpF{G8 zhM3?nrQ;@bdyF`wGbSL&q*^G6zmffsN0FY!ZEZsqyvv@iszYdSKY-$3e@F|-S0-Ir zbIuif+1S^^?&0VjO>{K+$(A2>?YDGiTCUkc=Mn^=k6AZ#17WwEI%Bl^#h#gm+z)*% z^2Z*Y(1U{1d(*ow{@7<4C`d6|vZrmH^n84Aq@RL19etuq;2&L|;47e1__{Q>o$j>j zL!bayd4eD#WwF2_^Zb?vNiG@wZq+xOAdr>#W+_YTxHCkCZabvKYrRjP_cg3qY!t|| z4h=_q|Dl@O_JW-u$+B4Dn+>`Q_L>%uXYubFlBT|R=2qNgo5^whk<mM7ozPF&U!f^W`cmo; znj>*SbPMZDb}^eRW+hfsfQH)+{=fq)Y3e$#xtTE}iyIbh0I4#O3L!#-^jIAZps}Y; zPUwe8_)eQsL68)urWoD3^CKbzl~zLYTE-EqY?e6sq^A?NG=;&q2^d$r=aJ3NC!Sh` zUi#b>NC64@2^K&p8d21~?G5|m|bxw&GNT?)kE1bPNC<<^?TIE1g6!4o7eR8rH>P!a{3DqhFLd>kqcK|i3! zp5BG7TBh=%i_^_IwkT%5*Erxt9Fm$;7YOh!7$+J?%2uYqm4=`NRqPz|42{aqpjXQ5 zW4bR(Nf4ZE_|%T&VP_@_c(+VC7U0SxQ5HLg8S^eV;G1uN=i39og#&0QXs(HhZx={Y za{vh{P-&y3p$Obicq%Omf4wmF>hM8~7}G;i?fdWVmru01 z@6-+-O=Lq}St{4;ovTKO-$?xNWvguUyY*_g_QI%r(8^lMp2x^!*~)tTgonHw)#OLy za$)4Q;6`_d&sO|^ZFhG@{SUu`<+kVSrOZ5J&`2rW`&*38p@ERS<2Uhi&>gJ~Q|(tY zk1b*Q(+BI4sEn&Y_(jZp^IGDbhMQQ`={~lJT&56s&1RBV^woy--ir*MuNFq?pa2AFis%wCxqXxxlYB0_&h)Ae~D~uJzPO8 zkegVG1C-jLQF`+-0K|-)Rz4xq<4y)`tsZHuM1cnrYi=vp2PQq|W2B?n>{PmD^K5F* z@lO?7P2BnD4SST__p(Iv>*s4@C97oLKZoL3AIgTazSffCeLq98(U~~|8q_Ul6d)2+ zunSoHl)03(2qEB2)u0KFg*^V5c8TvRtT#r(EFv>WA?1 zTr+Nm71P;$oG2J^cRqq!mycAaPx$O_oVO}orkTjKEzKP&N(hBdt>~Rui>o{vGza@R41?YWjNhlC z9IZo5*;k5~cZO5zGRHn>-zgioXV6?*UKPt|usdSQR($K(k>SGiTI-S05*9YJBMk)I z0ZsF?_FJ1++&T&9!najX&z0}pZ?q95>QrptSu zp*vdnlM?YVp9&#xxqkdgZh76oD5$-!%7%vUUm9RA?GbJZj{Vp08W{F7#mGPxTG2-Oewr&K;`4fWDDYQ}k|=^aa39`tJt zUm$SPiB%@Ow_^0Ydn&(=e`8u5GVn&)%P~1G!;`C1)&$|j^q`1Rv3@VFHsK(1v{buf zehgt|W?&azI$l;PD(W1f-}_V9!?e>QCjav8(ZNrhpuxn^(wFOn6Fax5Uz*Rf`;F%0 z)#)XQZZ}Ci{a zZ{dB#qAm|Sp9+z3Ai{d?_?44s5S;>N(=*#2i)#i(VQEkzWwmqwYKeezrR}-MBCQFW ztDpj>Oljt8J+SN?c%d!p+I=18Tr%K|!GwxyuYdHOH?4BC31U<;O zjrO|9z~1_G<>x{#`Xvy7wVy0vvVa%5#pBVP!>!AyOAB(T{piisfA8r7OVFw*17WnL z=hP4@q-vsXJeiP-LBI9D1-PIPNC|o12%=CDeH?Hx+oou~-$|q2j*-I3mQRJE#Ts%c ztpNQl${(sw<@b}s1G_cZAso2`Q`#AeN#j zVT7l$p@Eh94m=TZ5jye=-!J4kGNH8k{qOhW>!j9ijiUd;nF{;cEf$OJ?=9%%*YolW? zd;$IX4=&+NT0hNcfOP5McF?gE#|i;2xn#Zbjj6?Po$fDdmF4$1Vj7(7jvcH~(D(cG zu1_!}kXIaET*y^bOq|RtN3t<*>nlo}ttGfxmgpT8{yh5@Gw^6UKztnh_aqn!GAh#f Il7{~O3l2&u4FCWD literal 0 HcmV?d00001 diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png new file mode 100644 index 0000000000000000000000000000000000000000..119005ce5c7f0ea96030961a6f8c04cbf6ec4d11 GIT binary patch literal 14563 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 client.lifetime) { + early = client.lifetime; + } + + next = MIN(period, client.lifetime - early); + next = MAX(next, MINIMUM_PERIOD); + + return client.last_update + next * MSEC_PER_SEC; } static int64_t next_rx_off(void) diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 5d255e0513e..66d6334264f 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -61,6 +61,8 @@ CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 # Use QUEUE mode by default CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 +CONFIG_LWM2M_UPDATE_PERIOD=30 +CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10 # LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 81e129c56c1..2a8e8959c25 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -32,3 +32,4 @@ add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_ENABLED=1) add_compile_definitions(CONFIG_LWM2M_TLS_SESSION_CACHING=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=1) +add_compile_definitions(CONFIG_LWM2M_UPDATE_PERIOD=0) From 768fe29f904463a34138acc1b62e73b04492d2c6 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 28 Sep 2023 16:29:44 +0200 Subject: [PATCH 2168/4498] arm: stm32: nucleo_g431rb: Enable support for Random Number Generator (RNG) The nucleo_g431rb board is equipped with STM32G491RE microcontroller, which do have the RNG IP block. However, by default it is not enabled. To make it working properly, the provided clock needs to fulfill following condition: fRNGCLK < fHCLK/32, otherwise RNG_SR would set CEIS (bit5) and CECS (bit1). When combined with enabled interrupt from RNG, one would experience the interrupt storm. In this patch the DTS for this board has been adjusted properly, as well as the board description has been updated to reflect RNG support. Signed-off-by: Lukasz Majewski --- boards/arm/nucleo_g431rb/doc/index.rst | 2 ++ boards/arm/nucleo_g431rb/nucleo_g431rb.dts | 10 ++++++++++ boards/arm/nucleo_g431rb/nucleo_g431rb.yaml | 1 + 3 files changed, 13 insertions(+) diff --git a/boards/arm/nucleo_g431rb/doc/index.rst b/boards/arm/nucleo_g431rb/doc/index.rst index dfe1b680fe6..7d60b8c5426 100644 --- a/boards/arm/nucleo_g431rb/doc/index.rst +++ b/boards/arm/nucleo_g431rb/doc/index.rst @@ -119,6 +119,8 @@ The Zephyr nucleo_g431rb board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | SPI | on-chip | spi | +-----------+------------+-------------------------------------+ +| RNG | on-chip | rng | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb.dts b/boards/arm/nucleo_g431rb/nucleo_g431rb.dts index 2ab18ec7360..0bdf2b7d301 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb.dts +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb.dts @@ -63,6 +63,10 @@ status = "okay"; }; +&clk_hsi48 { + status = "okay"; +}; + &clk_hse { clock-frequency = ; status = "okay"; @@ -86,6 +90,12 @@ apb2-prescaler = <1>; }; +&rng { + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x04000000>, + <&rcc STM32_SRC_HSI48 CLK48_SEL(0)>; + status = "okay"; +}; + &usart1 { pinctrl-0 = <&usart1_tx_pc4 &usart1_rx_pc5>; pinctrl-names = "default"; diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml index 642b8a68c49..71ca5707ac5 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml @@ -19,6 +19,7 @@ supported: - usb device - counter - spi + - rng - dac - watchdog vendor: st From 62396443fc5be0d540704dc1137539741a6132ca Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Fri, 22 Sep 2023 18:47:13 +0200 Subject: [PATCH 2169/4498] drivers: ieee802154: deprecate OT "sleep" nomenclature "Sleeping" has a well defined meaning in Zephyr related to threading and power management. This differs from OpenThread's definition: - Deprecates the "SLEEP_TO_TX" capability as it is redundant and conflicts with all of Zephyr's nomenclature, #61227, RFC 2863, Thread standard and IEEE 802.15.4. This binds the API to an implementation detail of OpenThread, instead. See #63670 for the agreed migration path. - Renames the "SLEEP" event to "RX_OFF" which conforms to the nomenclature in Zephyr, this API and IEEE 802.15.4. Fixes: #62995 Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_nrf5.c | 4 ++-- include/zephyr/net/ieee802154_radio.h | 27 +++++++++++++++++++++++++-- modules/openthread/platform/radio.c | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 8e1032718e4..ddcef3947eb 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -663,7 +663,7 @@ static int nrf5_stop(const struct device *dev) #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) if (nrf_802154_sleep_if_idle() != NRF_802154_SLEEP_ERROR_NONE) { if (nrf5_data.event_handler) { - nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL); + nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); } else { LOG_WRN("Transition to radio sleep cannot be handled."); } @@ -1024,7 +1024,7 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) * As a side effect, regular failure notifications would be reported with the * incorrect ID. */ - nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL); + nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); #endif if (error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) { return; diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index f4d8ff6d318..6e36c9a356f 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -482,7 +482,30 @@ enum ieee802154_hw_caps { /** TX at specified time supported */ IEEE802154_HW_TXTIME = BIT(8), - /** TX directly from sleep supported */ + /** TX directly from sleep supported + * + * @note This HW capability does not conform to the requirements + * specified in #61227 as it closely couples the driver to OpenThread's + * capability and device model which is different from Zephyr's: + * - "Sleeping" is a well defined term in Zephyr related to internal + * power and thread management and different from "RX off" as + * defined in OT. + * - Currently all OT-capable drivers have the "sleep to TX" + * capability anyway plus we expect future drivers to implement it + * ootb as well, so no information is actually conveyed by this + * capability. + * - The `start()`/`stop()` API of a net device controls the + * interface's operational state. Drivers MUST respond with + * -ENETDOWN when calling `tx()` while their operational state is + * "DOWN", only devices in the "UP" state MAY transmit packets (RFC + * 2863). + * - A migration path has been defined in #63670 for actual removal of + * this capability in favor of a standard compliant + * `configure(rx_on/rx_off)` call, see there for details. + * + * @deprecated Drivers and L2 SHALL not introduce additional references + * to this capability and remove existing ones as outlined in #63670. + */ IEEE802154_HW_SLEEP_TO_TX = BIT(9), /** Timed RX window scheduling supported */ @@ -524,7 +547,7 @@ enum ieee802154_event { * synchronously switched of due to a call to `stop()` or an RX slot * being configured. */ - IEEE802154_EVENT_SLEEP, + IEEE802154_EVENT_RX_OFF, }; /** RX failed event reasons, see @ref IEEE802154_EVENT_RX_FAILED */ diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 17753ee852d..555710aba49 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -224,7 +224,7 @@ void handle_radio_event(const struct device *dev, enum ieee802154_event evt, set_pending_event(PENDING_EVENT_RX_FAILED); } break; - case IEEE802154_EVENT_SLEEP: + case IEEE802154_EVENT_RX_OFF: set_pending_event(PENDING_EVENT_SLEEP); break; default: From 80da9ddfef98127a370ee929daaac55068f404c6 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Wed, 20 Sep 2023 19:31:47 +0200 Subject: [PATCH 2170/4498] drivers: ieee802154: improve ACK header IE config Improves standard conformance of the IEEE802154_CONFIG_ENH_ACK_HEADER_IE option and introduces certain "soft MAC" capabilities around header IEs: * Introduces types and helpers that allow driver maintainers to represent, parse, write and validate header IEs. * Introduces helper functions to access non-aligned fields in header IEs, namely element IDs. Updates the only existing L2 and driver pair that uses IEEE802154_CONFIG_ENH_ACK_HEADER_IE: OpenThread platform radio and nRF5 and improves header IE validation in the nRF5 driver. This change should help further driver maintainers to support OpenThread's CSL and vendor IE extensions. It is based on the rules specified in RFC #61227. It is also a precondition to generically support both, "soft MAC" and "hard MAC", approaches to header IEs in the TSCH protocol, namely the time synchronization IE. Fixes: #62940 Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_nrf5.c | 51 ++- include/zephyr/net/ieee802154_ie.h | 356 ++++++++++++++++++ include/zephyr/net/ieee802154_radio.h | 115 ++++-- .../zephyr/net/ieee802154_radio_openthread.h | 11 + modules/openthread/platform/radio.c | 54 +-- 5 files changed, 527 insertions(+), 60 deletions(-) create mode 100644 include/zephyr/net/ieee802154_ie.h diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index ddcef3947eb..1660de2592b 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -877,27 +877,46 @@ static int nrf5_configure(const struct device *dev, #endif /* CONFIG_NRF_802154_ENCRYPTION */ case IEEE802154_CONFIG_ENH_ACK_HEADER_IE: { - uint8_t short_addr_le[SHORT_ADDRESS_SIZE]; uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE]; + uint8_t short_addr_le[SHORT_ADDRESS_SIZE]; + uint8_t element_id; + + if (config->ack_ie.short_addr == IEEE802154_BROADCAST_ADDRESS || + config->ack_ie.ext_addr == NULL) { + return -ENOTSUP; + } + + element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie); + + if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE && + (!IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) || + element_id != IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE)) { + return -ENOTSUP; + } + +#if defined(CONFIG_NET_L2_OPENTHREAD) + uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] = + IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI; + + if (element_id == IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE && + memcmp(config->ack_ie.header_ie->content.vendor_specific.vendor_oui, + vendor_oui_le, sizeof(vendor_oui_le))) { + return -ENOTSUP; + } +#endif sys_put_le16(config->ack_ie.short_addr, short_addr_le); - /** - * The extended address field passed to this function starts - * with the most significant octet and ends with the least - * significant octet (i.e. big endian byte order). - * The IEEE 802.15.4 transmission order mandates this order to be - * reversed (i.e. little endian byte order) in a transmitted frame. - * - * The nrf_802154_ack_data_set expects extended address in transmission - * order. - */ sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE); - if (config->ack_ie.data_len > 0) { - nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.data, - config->ack_ie.data_len, NRF_802154_ACK_DATA_IE); - nrf_802154_ack_data_set(ext_addr_le, true, config->ack_ie.data, - config->ack_ie.data_len, NRF_802154_ACK_DATA_IE); + if (config->ack_ie.header_ie && config->ack_ie.header_ie->length > 0) { + nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.header_ie, + config->ack_ie.header_ie->length + + IEEE802154_HEADER_IE_HEADER_LENGTH, + NRF_802154_ACK_DATA_IE); + nrf_802154_ack_data_set(ext_addr_le, true, config->ack_ie.header_ie, + config->ack_ie.header_ie->length + + IEEE802154_HEADER_IE_HEADER_LENGTH, + NRF_802154_ACK_DATA_IE); } else { nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE); nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE); diff --git a/include/zephyr/net/ieee802154_ie.h b/include/zephyr/net/ieee802154_ie.h new file mode 100644 index 00000000000..0be4c1576e5 --- /dev/null +++ b/include/zephyr/net/ieee802154_ie.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2023 Florian Grandel, Zephyr Project. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief IEEE 802.15.4 MAC information element (IE) related types and helpers + * + * This is not to be included by the application. This file contains only those + * parts of the types required for IE support that need to be visible to IEEE + * 802.15.4 drivers and L2 at the same time, i.e. everything related to header + * IE representation, parsing and generation. + * + * All specification references in this file refer to IEEE 802.15.4-2020. + * + * @note All structs and attributes in this file that directly represent parts + * of IEEE 802.15.4 frames are in LITTLE ENDIAN, see section 4, especially + * section 4.3. + */ + +#ifndef ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_ +#define ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_ + +#include +#include + +/** + * @addtogroup ieee802154_driver + * @{ + * + * @name IEEE 802.15.4, section 7.4.2: MAC header information elements + * @{ + */ + +/** + * @brief Information Element Types. + * + * @details See sections 7.4.2.1 and 7.4.3.1. + */ +enum ieee802154_ie_type { + IEEE802154_IE_TYPE_HEADER = 0x0, + IEEE802154_IE_TYPE_PAYLOAD, +}; + +/** + * @brief Header Information Element IDs. + * + * @details See section 7.4.2.1, table 7-7, partial list, only IEs actually used + * are implemented. + */ +enum ieee802154_header_ie_element_id { + IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE = 0x00, + IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE = 0x1a, + IEEE802154_HEADER_IE_ELEMENT_ID_RIT_IE = 0x1b, + IEEE802154_HEADER_IE_ELEMENT_ID_RENDEZVOUS_TIME_IE = 0x1d, + IEEE802154_HEADER_IE_ELEMENT_ID_TIME_CORRECTION_IE = 0x1e, + IEEE802154_HEADER_IE_ELEMENT_ID_HEADER_TERMINATION_1 = 0x7e, + IEEE802154_HEADER_IE_ELEMENT_ID_HEADER_TERMINATION_2 = 0x7f, + /* partial list, add additional ids as needed */ +}; + +/** @cond INTERNAL_HIDDEN */ +#define IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN 3 +/** INTERNAL_HIDDEN @endcond */ + +/** @brief Vendor Specific Header IE, see section 7.4.2.3. */ +struct ieee802154_header_ie_vendor_specific { + uint8_t vendor_oui[IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN]; + uint8_t *vendor_specific_info; +} __packed; + +/** @brief Full CSL IE, see section 7.4.2.3. */ +struct ieee802154_header_ie_csl_full { + uint16_t csl_phase; + uint16_t csl_period; + uint16_t csl_rendezvous_time; +} __packed; + +/** @brief Reduced CSL IE, see section 7.4.2.3. */ +struct ieee802154_header_ie_csl_reduced { + uint16_t csl_phase; + uint16_t csl_period; +} __packed; + +/** @brief Generic CSL IE, see section 7.4.2.3. */ +struct ieee802154_header_ie_csl { + union { + struct ieee802154_header_ie_csl_full full; + struct ieee802154_header_ie_csl_reduced reduced; + }; +} __packed; + +/** @brief RIT IE, see section 7.4.2.4. */ +struct ieee802154_header_ie_rit { + uint8_t time_to_first_listen; + uint8_t number_of_repeat_listen; + uint16_t repeat_listen_interval; +} __packed; + +/** + * @brief Full Rendezvous Time IE, see section 7.4.2.6 + * (macCslInterval is nonzero). + */ +struct ieee802154_header_ie_rendezvous_time_full { + uint16_t rendezvous_time; + uint16_t wakeup_interval; +} __packed; + +/** + * @brief Reduced Rendezvous Time IE, see section 7.4.2.6 + * (macCslInterval is zero). + */ +struct ieee802154_header_ie_rendezvous_time_reduced { + uint16_t rendezvous_time; +} __packed; + +/** @brief Rendezvous Time IE, see section 7.4.2.6. */ +struct ieee802154_header_ie_rendezvous_time { + union { + struct ieee802154_header_ie_rendezvous_time_full full; + struct ieee802154_header_ie_rendezvous_time_reduced reduced; + }; +} __packed; + +/** @brief Time Correction IE, see section 7.4.2.7. */ +struct ieee802154_header_ie_time_correction { + uint16_t time_sync_info; +} __packed; + +/* @brief Generic Header IE, see section 7.4.2.1. */ +struct ieee802154_header_ie { +#if CONFIG_LITTLE_ENDIAN + uint16_t length : 7; + uint16_t element_id_low : 1; /* see enum ieee802154_header_ie_element_id */ + uint16_t element_id_high : 7; + uint16_t type : 1; /* always 0 */ +#else + uint16_t element_id_low : 1; /* see enum ieee802154_header_ie_element_id */ + uint16_t length : 7; + uint16_t type : 1; /* always 0 */ + uint16_t element_id_high : 7; +#endif + union { + struct ieee802154_header_ie_vendor_specific vendor_specific; + struct ieee802154_header_ie_csl csl; + struct ieee802154_header_ie_rit rit; + struct ieee802154_header_ie_rendezvous_time rendezvous_time; + struct ieee802154_header_ie_time_correction time_correction; + /* add additional supported header IEs here */ + } content; +} __packed; + +/** @brief The header IE's header length (2 bytes). */ +#define IEEE802154_HEADER_IE_HEADER_LENGTH sizeof(uint16_t) + + +/** @cond INTERNAL_HIDDEN */ +#define IEEE802154_DEFINE_HEADER_IE(_element_id, _length, _content, _content_type) \ + (struct ieee802154_header_ie) { \ + .length = (_length), \ + .element_id_high = (_element_id) >> 1U, .element_id_low = (_element_id) & 0x01, \ + .type = IEEE802154_IE_TYPE_HEADER, \ + .content._content_type = _content, \ + } + +#define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT_LEN(_vendor_specific_info_len) \ + (IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN + (_vendor_specific_info_len)) + +#define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT(_vendor_oui, _vendor_specific_info) \ + (struct ieee802154_header_ie_vendor_specific) { \ + .vendor_oui = _vendor_oui, .vendor_specific_info = (_vendor_specific_info), \ + } + +#define IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED_CONTENT(_csl_phase, _csl_period) \ + (struct ieee802154_header_ie_csl_reduced) { \ + .csl_phase = sys_cpu_to_le16(_csl_phase), \ + .csl_period = sys_cpu_to_le16(_csl_period), \ + } + +#define IEEE802154_DEFINE_HEADER_IE_CSL_FULL_CONTENT(_csl_phase, _csl_period, \ + _csl_rendezvous_time) \ + (struct ieee802154_header_ie_csl_full) { \ + .csl_phase = sys_cpu_to_le16(_csl_phase), \ + .csl_period = sys_cpu_to_le16(_csl_period), \ + .csl_rendezvous_time = sys_cpu_to_le16(_csl_rendezvous_time), \ + } + +#define IEEE802154_HEADER_IE_TIME_CORRECTION_NACK 0x8000 +#define IEEE802154_HEADER_IE_TIME_CORRECTION_MASK 0x0fff +#define IEEE802154_HEADER_IE_TIME_CORRECTION_SIGN_BIT_MASK 0x0800 + +#define IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION_CONTENT(_ack, _time_correction_us) \ + (struct ieee802154_header_ie_time_correction) { \ + .time_sync_info = sys_cpu_to_le16( \ + (!(_ack) * IEEE802154_HEADER_IE_TIME_CORRECTION_NACK) | \ + ((_time_correction_us) & IEEE802154_HEADER_IE_TIME_CORRECTION_MASK)), \ + } +/** INTERNAL_HIDDEN @endcond */ + +/** + * @brief Define a vendor specific header IE, see section 7.4.2.3. + * + * @details Example usage (all parameters in little endian): + * + * @code{.c} + * uint8_t vendor_specific_info[] = {...some vendor specific IE content...}; + * struct ieee802154_header_ie header_ie = IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC( + * {0x9b, 0xb8, 0xea}, vendor_specific_info, sizeof(vendor_specific_info)); + * @endcode + * + * @param _vendor_oui an initializer for a 3 byte vendor oui array in little + * endian + * @param _vendor_specific_info pointer to a variable length uint8_t array with + * the vendor specific IE content + * @param _vendor_specific_info_len the length of the vendor specific IE content + * (in bytes) + */ +#define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC(_vendor_oui, _vendor_specific_info, \ + _vendor_specific_info_len) \ + IEEE802154_DEFINE_HEADER_IE(IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE, \ + IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT_LEN( \ + _vendor_specific_info_len), \ + IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT( \ + _vendor_oui, _vendor_specific_info), \ + vendor_specific) + +/** + * @brief Define a reduced CSL IE, see section 7.4.2.3. + * + * @details Example usage (all parameters in CPU byte order): + * + * @code{.c} + * uint16_t csl_phase = ...; + * uint16_t csl_period = ...; + * struct ieee802154_header_ie header_ie = + * IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(csl_phase, csl_period); + * @endcode + * + * @param _csl_phase CSL phase in CPU byte order + * @param _csl_period CSL period in CPU byte order + */ +#define IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(_csl_phase, _csl_period) \ + IEEE802154_DEFINE_HEADER_IE( \ + IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE, \ + sizeof(struct ieee802154_header_ie_csl_reduced), \ + IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED_CONTENT(_csl_phase, _csl_period), \ + csl.reduced) + +/** + * @brief Define a full CSL IE, see section 7.4.2.3. + * + * @details Example usage (all parameters in CPU byte order): + * + * @code{.c} + * uint16_t csl_phase = ...; + * uint16_t csl_period = ...; + * uint16_t csl_rendezvous_time = ...; + * struct ieee802154_header_ie header_ie = + * IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(csl_phase, csl_period, csl_rendezvous_time); + * @endcode + * + * @param _csl_phase CSL phase in CPU byte order + * @param _csl_period CSL period in CPU byte order + * @param _csl_rendezvous_time CSL rendezvous time in CPU byte order + */ +#define IEEE802154_DEFINE_HEADER_IE_CSL_FULL(_csl_phase, _csl_period, _csl_rendezvous_time) \ + IEEE802154_DEFINE_HEADER_IE(IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE, \ + sizeof(struct ieee802154_header_ie_csl_full), \ + IEEE802154_DEFINE_HEADER_IE_CSL_FULL_CONTENT( \ + _csl_phase, _csl_period, _csl_rendezvous_time), \ + csl.full) + +/** + * @brief Define a Time Correction IE, see section 7.4.2.7. + * + * @details Example usage (parameter in CPU byte order): + * + * @code{.c} + * uint16_t time_sync_info = ...; + * struct ieee802154_header_ie header_ie = + * IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION(true, time_sync_info); + * @endcode + * + * @param _ack whether or not the enhanced ACK frame that receives this IE is an + * ACK (true) or NACK (false) + * @param _time_correction_us the positive or negative deviation from expected + * RX time in microseconds + */ +#define IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION(_ack, _time_correction_us) \ + IEEE802154_DEFINE_HEADER_IE( \ + IEEE802154_HEADER_IE_ELEMENT_ID_TIME_CORRECTION_IE, \ + sizeof(struct ieee802154_header_ie_time_correction), \ + IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION_CONTENT(_ack, _time_correction_us), \ + time_correction) + +/** + * @brief Retrieve the time correction value in microseconds from a Time Correction IE, + * see section 7.4.2.7. + * + * @param[in] ie pointer to the Time Correction IE structure + * + * @return The time correction value in microseconds. + */ +static inline int16_t +ieee802154_header_ie_get_time_correction_us(struct ieee802154_header_ie_time_correction *ie) +{ + if (ie->time_sync_info & IEEE802154_HEADER_IE_TIME_CORRECTION_SIGN_BIT_MASK) { + /* Negative integer */ + return (int16_t)ie->time_sync_info | ~IEEE802154_HEADER_IE_TIME_CORRECTION_MASK; + } + + /* Positive integer */ + return (int16_t)ie->time_sync_info & IEEE802154_HEADER_IE_TIME_CORRECTION_MASK; +} + +/** + * @brief Set the element ID of a header IE. + * + * @param[in] ie pointer to a header IE + * @param[in] element_id IE element id in CPU byte order + */ +static inline void ieee802154_header_ie_set_element_id(struct ieee802154_header_ie *ie, + uint8_t element_id) +{ + ie->element_id_high = element_id >> 1U; + ie->element_id_low = element_id & 0x01; +} + +/** + * @brief Get the element ID of a header IE. + * + * @param[in] ie pointer to a header IE + * + * @return header IE element id in CPU byte order + */ +static inline uint8_t ieee802154_header_ie_get_element_id(struct ieee802154_header_ie *ie) +{ + return (ie->element_id_high << 1U) | ie->element_id_low; +} + +/** @brief The length in bytes of a "Time Correction" header IE. */ +#define IEEE802154_TIME_CORRECTION_HEADER_IE_LEN \ + (IEEE802154_HEADER_IE_HEADER_LENGTH + sizeof(struct ieee802154_header_ie_time_correction)) + +/** @brief The length in bytes of a "Header Termination 1" header IE. */ +#define IEEE802154_HEADER_TERMINATION_1_HEADER_IE_LEN IEEE802154_HEADER_IE_HEADER_LENGTH + +/** + * @} + * + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_ */ diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 6e36c9a356f..b73c55860eb 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -837,15 +838,78 @@ enum ieee802154_config_type { IEEE802154_CONFIG_CSL_RX_TIME, /** - * Indicates whether to inject IE into ENH ACK Frame for specific address - * or not. Disabling the ENH ACK with no address provided (NULL pointer) - * should disable it for all enabled addresses. - * - * @note Available in any interface operational state. - * - * @warning This configuration option does not conform to the - * requirements specified in #61227 as it is incompatible with standard - * primitives and may therefore be modified in the future. + * Adds a header information element (IE) to be injected into enhanced + * ACK frames generated by the driver if the given destination address + * filter matches. + * + * @details Drivers implementing the @ref IEEE802154_HW_RX_TX_ACK + * capability generate ACK frames autonomously. Setting this + * configuration will ask the driver to inject the given preconfigured + * header IE when generating enhanced ACK frames where appropriate by + * the standard. IEs for all other frame types SHALL be provided by L2. + * + * The driver shall return -ENOTSUP in the following cases: + * - It does not support the @ref IEEE802154_HW_RX_TX_ACK, + * - It does not support header IE injection, + * - It cannot inject the runtime fields on-the-fly required for the + * given IE element ID (see list below). + * + * Enhanced ACK header IEs (element IDs in parentheses) that either + * need to be rejected or explicitly supported and parsed by the driver + * because they require on-the-fly timing information injection are: + * - CSL IE (0x1a) + * - Rendezvous Time IE (0x1d) + * - Time Correction IE (0x1e) + * + * Drivers accepting this configuration option SHALL check the list of + * configured IEs for each outgoing enhanced ACK frame, select the ones + * appropriate for the received frame based on their element ID, inject + * any required runtime information on-the-fly and include the selected + * IEs into the enhanced ACK frame's MAC header. + * + * Drivers supporting enhanced ACK header IE injection SHALL + * autonomously inject header termination IEs as required by the + * standard. + * + * A destination short address and extended address MAY be given by L2 + * to filter the devices to which the given IE is included. Setting the + * short address to the broadcast address and the extended address to + * NULL will inject the given IE into all ACK frames unless a more + * specific filter is also present for any given destination device + * (fallback configuration). L2 SHALL take care to either set both + * address fields to valid device addresses or none. + * + * This configuration type may be called several times with distinct + * element IDs and/or addresses. The driver SHALL either store all + * configured IE/address combinations or return -ENOMEM if no + * additional configuration can be stored. + * + * Configuring a header IE with a previously configured element ID and + * address filter SHALL override the previous configuration. This + * implies that repetition of the same header IE/address combination is + * NOT supported. + * + * Configuring an existing element ID/address filter combination with + * the header IE's length field set to zero SHALL remove that + * configuration. SHALL remove the fallback configuration if no address + * is given. + * + * Configuring a header IE for an address filter with the header IE + * pointer set to NULL SHALL remove all header IE's for that address + * filter. SHALL remove ALL header IE configuration (including but not + * limited to fallbacks) if no address is given. + * + * If any of the deleted configurations didn't previously exist, then + * the call SHALL be ignored. Whenever the length field is set to zero, + * the content fields MUST NOT be accessed by the driver. + * + * L2 SHALL minimize the space required to keep IE configuration inside + * the driver by consolidating address filters and by removing + * configuation that is no longer required. + * + * @note requires @ref IEEE802154_HW_RX_TX_ACK capability and is + * available in any interface operational state. Currently we only + * support header IEs but that may change in the future. */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, @@ -970,32 +1034,37 @@ struct ieee802154_config { /** see @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE */ struct { /** - * Header IEs to be added to the Enh-Ack frame. + * Pointer to the header IE, see section 7.4.2.1, + * figure 7-21 * - * in little endian + * Certain header IEs may be incomplete if they require + * timing information to be injected at runtime + * on-the-fly, see the list in @ref + * IEEE802154_CONFIG_ENH_ACK_HEADER_IE. */ - const uint8_t *data; - - /** length of the header IEs */ - uint16_t data_len; + struct ieee802154_header_ie *header_ie; /** * Filters the devices that will receive this IE by - * short address. MAY be set to @ref - * IEEE802154_BROADCAST_ADDRESS to disable the filter. + * extended address. MAY be set to NULL to configure a + * fallback for all devices (implies that short_addr + * MUST also be set to @ref + * IEEE802154_BROADCAST_ADDRESS). * - * in CPU byte order + * in big endian */ - uint16_t short_addr; + const uint8_t *ext_addr; /** * Filters the devices that will receive this IE by - * extended address. MAY be set to NULL to disable the - * filter. + * short address. MAY be set to @ref + * IEEE802154_BROADCAST_ADDRESS to configure a fallback + * for all devices (implies that ext_addr MUST also set + * to NULL in this case). * - * in big endian + * in CPU byte order */ - const uint8_t *ext_addr; + uint16_t short_addr; } ack_ie; }; }; diff --git a/include/zephyr/net/ieee802154_radio_openthread.h b/include/zephyr/net/ieee802154_radio_openthread.h index 39a316b3251..f6f9949d328 100644 --- a/include/zephyr/net/ieee802154_radio_openthread.h +++ b/include/zephyr/net/ieee802154_radio_openthread.h @@ -79,6 +79,17 @@ enum ieee802154_openthread_config_type { IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS = IEEE802154_CONFIG_PRIV_START }; +/** + * Thread vendor OUI for vendor specific header or nested information elements, + * see IEEE 802.15.4-2020, sections 7.4.2.2 and 7.4.4.30. + * + * in little endian + */ +#define IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI { 0x9b, 0xb8, 0xea } + +/** length of IEEE 802.15.4-2020 vendor OUIs */ +#define IEEE802154_OPENTHREAD_VENDOR_OUI_LEN 3 + /** OpenThread specific configuration data of ieee802154 driver. */ struct ieee802154_openthread_config { union { diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 555710aba49..f32182f4862 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -1234,29 +1234,42 @@ void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacF otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr) { + struct ieee802154_config config = { + .ack_ie.short_addr = aShortAddr, + .ack_ie.ext_addr = aExtAddr->m8, + }; int result; - uint8_t ie_header[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE]; - struct ieee802154_config config; ARG_UNUSED(aInstance); - ie_header[0] = CSL_IE_HEADER_BYTES_LO; - ie_header[1] = CSL_IE_HEADER_BYTES_HI; - /* Leave CSL Phase empty intentionally */ - sys_put_le16(aCslPeriod, &ie_header[OT_IE_HEADER_SIZE + 2]); - config.ack_ie.data = ie_header; - config.ack_ie.short_addr = aShortAddr; - config.ack_ie.ext_addr = aExtAddr->m8; + /* Configure the CSL period first to give drivers a chance to validate + * the IE for consistency if they wish to. + */ + config.csl_period = aCslPeriod; + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config); + if (result) { + return OT_ERROR_FAILED; + } + /* Configure the CSL IE. */ if (aCslPeriod > 0) { - config.ack_ie.data_len = OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE; + uint8_t header_ie_buf[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE] = { + CSL_IE_HEADER_BYTES_LO, + CSL_IE_HEADER_BYTES_HI, + }; + struct ieee802154_header_ie *header_ie = + (struct ieee802154_header_ie *)header_ie_buf; + + /* Write CSL period and leave CSL phase empty as it will be + * injected on-the-fly by the driver. + */ + header_ie->content.csl.reduced.csl_period = sys_cpu_to_le16(aCslPeriod); + config.ack_ie.header_ie = header_ie; } else { - config.ack_ie.data_len = 0; + config.ack_ie.header_ie = NULL; } - result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); - config.csl_period = aCslPeriod; - result += radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config); + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); return result ? OT_ERROR_FAILED : OT_ERROR_NONE; } @@ -1384,20 +1397,19 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a const otShortAddress aShortAddress, const otExtAddress *aExtAddress) { - int result; - uint8_t ie_header[OT_ACK_IE_MAX_SIZE]; - uint16_t ie_header_len; struct ieee802154_config config = { .ack_ie.short_addr = aShortAddress, .ack_ie.ext_addr = aExtAddress->m8, }; + uint8_t header_ie_buf[OT_ACK_IE_MAX_SIZE]; + uint16_t header_ie_len; + int result; ARG_UNUSED(aInstance); - ie_header_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, - aLinkMetrics.mRssi, ie_header); - config.ack_ie.data = ie_header; - config.ack_ie.data_len = ie_header_len; + header_ie_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, + aLinkMetrics.mRssi, header_ie_buf); + config.ack_ie.header_ie = (struct ieee802154_ie_header *)header_ie_buf; result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); return result ? OT_ERROR_FAILED : OT_ERROR_NONE; From e9d5a98e9da627753bfe64184a90a278b24fc2af Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 21 Sep 2023 14:51:07 +0200 Subject: [PATCH 2171/4498] drivers: ieee802154: improve CSL standard conformance This change slightly simplifies the configuration of a CSL receiver and generalized CSL_RX_TIME to EXPECTED_RX_TIME as a re-usable primitive across several timing-sensitive IEEE 802.15.4 standard sub-protocols (namely BE-PANs/DSME/CSL/RIT/TSCH). This API change is based on the rules outlined in RFC #61227. Fixes: #62918 Signed-off-by: Florian Grandel --- drivers/ieee802154/ieee802154_nrf5.c | 5 +- include/zephyr/net/ieee802154_radio.h | 227 +++++++++++++++++++------- modules/openthread/platform/radio.c | 14 +- tests/subsys/openthread/radio_test.c | 8 +- 4 files changed, 191 insertions(+), 63 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 1660de2592b..d4dde149ac7 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -924,8 +924,9 @@ static int nrf5_configure(const struct device *dev, } break; #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) - case IEEE802154_CONFIG_CSL_RX_TIME: { - nrf_802154_csl_writer_anchor_time_set(config->csl_rx_time / NSEC_PER_USEC); + case IEEE802154_CONFIG_EXPECTED_RX_TIME: { + nrf_802154_csl_writer_anchor_time_set(nrf_802154_timestamp_phr_to_mhr_convert( + config->expected_rx_time / NSEC_PER_USEC)); } break; case IEEE802154_CONFIG_RX_SLOT: { diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index b73c55860eb..9c2aa3816e4 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -781,61 +781,184 @@ enum ieee802154_config_type { IEEE802154_CONFIG_RX_SLOT, /** - * Configure CSL receiver (Endpoint) period. - * - * @details In order to configure a CSL receiver the upper layer should combine several - * configuration options in the following way: - * 1. Use @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE once to inform the driver of the - * short and extended addresses of the peer to which it should inject CSL IEs. - * 2. Use @ref IEEE802154_CONFIG_CSL_RX_TIME periodically, before each use of - * @ref IEEE802154_CONFIG_CSL_PERIOD setting parameters of the nearest CSL RX window, - * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not - * the nearest one) CSL RX window, to allow the driver to calculate the proper - * CSL phase to the nearest CSL window to inject in the CSL IEs for both transmitted - * data and ACK frames. - * 3. Use @ref IEEE802154_CONFIG_CSL_PERIOD on each value change to update the current - * CSL period value which will be injected in the CSL IEs together with the CSL phase - * based on @ref IEEE802154_CONFIG_CSL_RX_TIME. - * 4. Use @ref IEEE802154_CONFIG_RX_SLOT periodically to schedule the immediate receive - * window early enough before the expected window start time, taking into account - * possible clock drifts and scheduling uncertainties. - * - * This diagram shows the usage of the four options over time: - * - * Start CSL Schedule CSL window - * - * ENH_ACK_HEADER_IE CSL_RX_TIME (following window) - * | | - * | CSL_RX_TIME (nearest window) | RX_SLOT (nearest window) - * | | | | - * | | CSL_PERIOD | | - * | | | | | - * v v v v v - * ----------------------------------------------------------[ CSL window ]-----+ - * ^ | - * | | - * +--------------------- loop ---------+ + * Enables or disables a device as a CSL receiver and configures its CSL + * period. + * + * @details Configures the CSL period in units of 10 symbol periods. + * Values greater than zero enable CSL if the driver supports it and the + * device starts to operate as a CSL receiver. Setting this to zero + * disables CSL on the device. If the driver does not support CSL, the + * configuration call SHALL return -ENOTSUP. + * + * See section 7.4.2.3 and section 8.4.3.6, table 8-104, macCslPeriod. + * + * @note Confusingly the standard calls the CSL receiver "CSL + * coordinator" (i.e. "coordinating the CSL protocol timing", see + * section 6.12.2.2), although, typically, a CSL coordinator is NOT also + * an IEEE 802.15.4 FFD coordinator or PAN coordintor but a simple RFD + * end device (compare the device roles outlined in sections 5.1, 5.3, + * 5.5 and 6.1). To avoid confusion we therefore prefer calling CSL + * coordinators (typically an RFD end device) "CSL receivers" and CSL + * peer devices (typically FFD coordinators or PAN coordinators) "CSL + * transmitters". Also note that at this time, we do NOT support + * unsynchronized transmission with CSL wake up frames as specified in + * section 6.12.2.4.4. + * + * To offload CSL receiver timing to the driver the upper layer SHALL + * combine several configuration options in the following way: + * + * 1. Use @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE once with an + * appropriate pre-filled CSL IE and the CSL phase set to an + * arbitrary value or left uninitialized. The CSL phase SHALL be + * injected on-the-fly by the driver at runtime as outlined in 2. + * below. Adding a short and extended address will inform the driver + * of the specific CSL receiver to which it SHALL inject CSL IEs. If + * no addresses are given then the CSL IE will be injected into all + * enhanced ACK frames as soon as CSL is enabled. This configuration + * SHALL be done before enabling CSL by setting a CSL period greater + * than zero. + * + * 2. Configure @ref IEEE802154_CONFIG_EXPECTED_RX_TIME immediately + * followed by @ref IEEE802154_CONFIG_CSL_PERIOD. To prevent race + * conditions, the upper layer SHALL ensure that the receiver is not + * enabled during or between the two calls (e.g. by a previously + * configured RX slot) nor SHALL a frame be transmitted concurrently. + * + * The expected RX time SHALL point to the end of SFD of an ideally + * timed RX frame in an arbitrary past or future CSL channel sample, + * i.e. whose "end of SFD" arrives exactly at the locally predicted + * time inside the CSL channel sample. + * + * The driver SHALL derive CSL anchor points and the CSL phase from + * the given expected RX time as follows: + * + * cslAnchorPointNs = last expected RX time + * + PHY-specific PHR duration in ns + * + * startOfMhrNs = start of MHR of the frame containing the + * CSL IE relative to the local network clock + * + * cslPhase = (startOfMhrNs - cslAnchorPointNs) + * / (10 * PHY specific symbol period in ns) + * % cslPeriod + * + * The driver SHALL set the CSL phase in the IE configured in 1. and + * inject that IE on-the-fly into outgoing enhanced ACK frames if the + * destination address conforms to the IE's address filter. + * + * 3. Use @ref IEEE802154_CONFIG_RX_SLOT periodically to schedule + * each CSL channel sample early enough before its start time. The + * size of the CSL channel sample SHALL take relative clock drift and + * scheduling uncertainties with respect to CSL transmitters into + * account as specified by the standard such that at least the full + * SHR of a legitimate RX frame is guaranteed to land inside the + * channel sample. + * + * To this avail, the last configured expected RX time plus an + * integer number of CSL periods SHALL point to a fixed offset of the + * RX slot (not necessarily its center): + * + * expectedRxTimeNs_N = last expected RX time + * + N * (cslPeriod * 10 * PHY-specific symbol period in ns) + * + * expectedRxTimeNs_N - rxSlot_N.start == const for all N + * + * While the configured CSL period is greater than zero, drivers + * SHOULD validate the offset of the expected RX time inside each RX + * slot accordingly. If the driver finds that the offset varies from + * slot to slot, drivers SHOULD log the difference but SHALL + * nevertheless accept and schedule the RX slot with a zero success + * value to work around minor implementation or rounding errors in + * upper layers. + * + * Configure and start a CSL receiver: + * + * ENH_ACK_HEADER_IE + * | + * | EXPECTED_RX_TIME (end of SFD of a perfectly timed RX frame + * | | in any past or future channel sample) + * | | + * | | CSL_PERIOD (>0) RX_SLOT + * | | | | + * v v v v + * -----------------------------------------------[-CSL channel sample ]----+ + * ^ | + * | | + * +--------------------- loop ---------+ + * + * Disable CSL on the receiver: + * + * CSL_PERIOD (=0) + * | + * v + * --------------------- + * + * Update the CSL period to a new value: + * + * EXPECTED_RX_TIME (based on updated period) + * | + * | CSL_PERIOD (>0, updated) RX_SLOT + * | | | + * v v v + * -----------------------------------------------[-CSL channel sample ]----+ + * ^ | + * | | + * +--------------------- loop ---------+ * * @note Available in any interface operational state. - * - * @warning This configuration option does not conform to the - * requirements specified in #61227 as it is incompatible with standard - * primitives and may therefore be deprecated in the future. */ IEEE802154_CONFIG_CSL_PERIOD, /** - * @brief Configure the next CSL receive window (i.e. "channel sample") - * center, in units of nanoseconds relative to the network subsystem's - * local clock. + * Configure a timepoint at which an RX frame is expected to arrive. + * + * @details Configure the nanosecond resolution timepoint relative to + * the network subsystem's local clock at which an RX frame's end of SFD + * (i.e. equivalently its end of SHR, start of PHR, or in the case of + * PHYs with RDEV or ERDEV capability the RMARKER) is expected to arrive + * at the local antenna assuming perfectly synchronized local and remote + * network clocks and zero distance between antennas. + * + * This parameter MAY be used to offload parts of timing sensitive TDMA + * (e.g. TSCH, beacon-enabled PAN including DSME), low-energy (e.g. + * CSL, RIT) or ranging (TDoA) protocols to the driver. In these + * protocols, medium access is tightly controlled such that the expected + * arrival time of a frame can be predicted within a well-defined time + * window. This feature will typically be combined with @ref + * IEEE802154_CONFIG_RX_SLOT although this is not a hard requirement. + * + * The "expected RX time" MAY be interpreted slightly differently + * depending on the protocol context: + * - CSL phase (i.e. time to the next expected CSL transmission) or anchor + * time (i.e. any arbitrary timepoint with "zero CSL phase") SHALL be + * derived by adding the PHY header duration to the expected RX time + * to calculate the "start of MHR" ("first symbol of MAC", see section + * 6.12.2.1) required by the CSL protocol, compare @ref + * IEEE802154_CONFIG_CSL_PERIOD. + * - In TSCH the expected RX time MAY be set to macTsRxOffset + + * macTsRxWait / 2. Then the time correction SHALL be calculated as + * the expected RX time minus actual arrival timestamp, see section + * 6.5.4.3. + * - In ranging applications, time difference of arrival (TDOA) MAY be + * calculated inside the driver comparing actual RMARKER timestamps + * against the assumed synchronized time at which the ranging frame + * was sent, see IEEE 802.15.4z. + * + * In case of periodic protocols (e.g. CSL channel samples, periodic + * beacons of a single PAN, periodic ranging "blinks"), a single + * timestamp at any time in the past or in the future may be given from + * which other expected timestamps can be derived by adding or + * substracting multiples of the RX period. See e.g. the CSL + * documentation in this API. + * + * Additionally this parameter MAY be used by drivers to discipline + * their local representation of a distributed network clock by deriving + * synchronization instants related to a remote representation of the + * same clock (as in PTP). * * @note Available in any interface operational state. - * - * @warning This configuration option does not conform to the - * requirements specified in #61227 as it is incompatible with standard - * primitives and may therefore be deprecated in the future. */ - IEEE802154_CONFIG_CSL_RX_TIME, + IEEE802154_CONFIG_EXPECTED_RX_TIME, /** * Adds a header information element (IE) to be injected into enhanced @@ -1014,22 +1137,14 @@ struct ieee802154_config { /** * see @ref IEEE802154_CONFIG_CSL_PERIOD * - * The CSL period in units of 10 symbol periods, - * see section 7.4.2.3. - * * in CPU byte order */ uint32_t csl_period; /** - * see @ref IEEE802154_CONFIG_CSL_RX_TIME - * - * Nanosecond resolution timestamp relative to the network - * subsystem's local clock defining the center of the CSL RX window - * at which the receiver is expected to be fully started up - * (i.e. not including any startup times). + * see @ref IEEE802154_CONFIG_EXPECTED_RX_TIME */ - net_time_t csl_rx_time; + net_time_t expected_rx_time; /** see @ref IEEE802154_CONFIG_ENH_ACK_HEADER_IE */ struct { diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index f32182f4862..67360860c56 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -58,6 +58,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #define CHANNEL_COUNT OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN + 1 +/* PHY header duration in us (i.e. 2 symbol periods @ 62.5k symbol rate), see + * IEEE 802.15.4, sections 12.1.3.1, 12.2.5 and 12.3.3. + */ +#define PHR_DURATION_US 32U + enum pending_events { PENDING_EVENT_FRAME_TO_SEND, /* There is a tx frame to send */ PENDING_EVENT_FRAME_RECEIVED, /* Radio has received new frame */ @@ -1278,10 +1283,15 @@ void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTi { ARG_UNUSED(aInstance); + /* CSL sample time points to "start of MAC" while the expected RX time + * refers to "end of SFD". + */ struct ieee802154_config config = { - .csl_rx_time = convert_32bit_us_wrapped_to_64bit_ns(aCslSampleTime)}; + .expected_rx_time = + convert_32bit_us_wrapped_to_64bit_ns(aCslSampleTime - PHR_DURATION_US), + }; - (void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, &config); + (void)radio_api->configure(radio_dev, IEEE802154_CONFIG_EXPECTED_RX_TIME, &config); } #endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */ diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index a5b9014825c..8c7a9fcb79e 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -901,8 +901,8 @@ static int custom_configure_csl_rx_time(const struct device *dev, const struct ieee802154_config *config) { zassert_equal(dev, radio, "Device handle incorrect."); - zassert_equal(type, IEEE802154_CONFIG_CSL_RX_TIME, "Config type incorrect."); - custom_configure_csl_rx_time_mock_csl_rx_time = config->csl_rx_time; + zassert_equal(type, IEEE802154_CONFIG_EXPECTED_RX_TIME, "Config type incorrect."); + custom_configure_csl_rx_time_mock_csl_rx_time = config->expected_rx_time; return 0; } @@ -910,11 +910,13 @@ static int custom_configure_csl_rx_time(const struct device *dev, ZTEST(openthread_radio, test_csl_receiver_sample_time) { uint32_t sample_time = 50U; + uint32_t phr_duration = 32U; configure_mock_fake.custom_fake = custom_configure_csl_rx_time; otPlatRadioUpdateCslSampleTime(NULL, sample_time); zassert_equal(1, configure_mock_fake.call_count); - zassert_equal(sample_time * NSEC_PER_USEC, custom_configure_csl_rx_time_mock_csl_rx_time); + zassert_equal((sample_time - phr_duration) * NSEC_PER_USEC, + custom_configure_csl_rx_time_mock_csl_rx_time); } From 48b93ee0aaeebbf5ff490a94e6f2b8558ce1bda8 Mon Sep 17 00:00:00 2001 From: Radoslaw Koppel Date: Wed, 26 Jul 2023 16:52:21 +0200 Subject: [PATCH 2172/4498] scripts: build: gen_isr_tables: Cleanup access to ".intList" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit removes the needs or generating isrList.bin temporary file. Now gen_isr_tables.py script access the required section directly in elf file, that was accessed by the script anyway. It simplifies the building removing one step. Signed-off-by: Radosław Koppel --- CMakeLists.txt | 13 +++---------- scripts/build/gen_isr_tables.py | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 666c9079c9d..15671fc8ad3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1239,20 +1239,13 @@ if(CONFIG_GEN_ISR_TABLES) # isr_tables.c is generated from ${ZEPHYR_LINK_STAGE_EXECUTABLE} by # gen_isr_tables.py add_custom_command( - OUTPUT isr_tables.c isrList.bin - COMMAND $ - $ - $${OUTPUT_FORMAT} - $binary - $.intList - $$ - $isrList.bin - $ + OUTPUT isr_tables.c COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_isr_tables.py --output-source isr_tables.c --kernel $ - --intlist isrList.bin + --intlist-section .intList + --intlist-section intList $<$:--big-endian> $<$:--debug> ${GEN_ISR_TABLE_EXTRA_ARG} diff --git a/scripts/build/gen_isr_tables.py b/scripts/build/gen_isr_tables.py index 5c525d67878..cd329f85551 100755 --- a/scripts/build/gen_isr_tables.py +++ b/scripts/build/gen_isr_tables.py @@ -42,7 +42,7 @@ def endian_prefix(): else: return "<" -def read_intlist(intlist_path, syms): +def read_intlist(elfobj, syms, snames): """read a binary file containing the contents of the kernel's .intList section. This is an instance of a header created by include/zephyr/linker/intlist.ld: @@ -66,7 +66,7 @@ def read_intlist(intlist_path, syms): const void *param; }; """ - + intList_sect = None intlist = {} prefix = endian_prefix() @@ -77,8 +77,16 @@ def read_intlist(intlist_path, syms): else: intlist_entry_fmt = prefix + "iiII" - with open(intlist_path, "rb") as fp: - intdata = fp.read() + for sname in snames: + intList_sect = elfobj.get_section_by_name(sname) + if intList_sect is not None: + debug("Found intlist section: \"{}\"".format(sname)) + break + + if intList_sect is None: + error("Cannot find the intlist section!") + + intdata = intList_sect.data() header_sz = struct.calcsize(intlist_header_fmt) header = struct.unpack_from(intlist_header_fmt, intdata, 0) @@ -122,8 +130,9 @@ def parse_args(): help="Generate SW ISR table") parser.add_argument("-V", "--vector-table", action="store_true", help="Generate vector table") - parser.add_argument("-i", "--intlist", required=True, - help="Zephyr intlist binary for intList extraction") + parser.add_argument("-i", "--intlist-section", action="append", required=True, + help="The name of the section to search for the interrupt data. " + "This is accumulative argument. The first section found would be used.") args = parser.parse_args() @@ -286,6 +295,7 @@ def main(): with open(args.kernel, "rb") as fp: kernel = ELFFile(fp) syms = get_symbols(kernel) + intlist = read_intlist(kernel, syms, args.intlist_section) if "CONFIG_MULTI_LEVEL_INTERRUPTS" in syms: max_irq_per = syms["CONFIG_MAX_IRQ_PER_AGGREGATOR"] @@ -313,7 +323,6 @@ def main(): debug('3rd level offsets: {}'.format(list_3rd_lvl_offsets)) - intlist = read_intlist(args.intlist, syms) nvec = intlist["num_vectors"] offset = intlist["offset"] From ffb4426877cd98d72d42752ae3683faf1d161ecc Mon Sep 17 00:00:00 2001 From: Mark Olsson Date: Fri, 29 Sep 2023 13:19:46 +0200 Subject: [PATCH 2173/4498] boards: shields: add MikroElektronika ACCEL 13 Click shield Add shield definition for the MikroElektronika ACCEL 13 Click. The ACCEL 13 Click carries a IIS2DLPC ultra-low power triaxial accelerometer sensor in a mikroBUS form factor. Signed-off-by: Mark Olsson --- .../mikroe_accel13_click/Kconfig.shield | 5 ++ .../doc/accel-13-click.jpg | Bin 0 -> 72152 bytes .../mikroe_accel13_click/doc/index.rst | 56 ++++++++++++++++++ .../mikroe_accel13_click.overlay | 23 +++++++ 4 files changed, 84 insertions(+) create mode 100644 boards/shields/mikroe_accel13_click/Kconfig.shield create mode 100644 boards/shields/mikroe_accel13_click/doc/accel-13-click.jpg create mode 100644 boards/shields/mikroe_accel13_click/doc/index.rst create mode 100644 boards/shields/mikroe_accel13_click/mikroe_accel13_click.overlay diff --git a/boards/shields/mikroe_accel13_click/Kconfig.shield b/boards/shields/mikroe_accel13_click/Kconfig.shield new file mode 100644 index 00000000000..335781b3b9b --- /dev/null +++ b/boards/shields/mikroe_accel13_click/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Mark Olsson +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_MIKROE_ACCEL13_CLICK + def_bool $(shields_list_contains,mikroe_accel13_click) diff --git a/boards/shields/mikroe_accel13_click/doc/accel-13-click.jpg b/boards/shields/mikroe_accel13_click/doc/accel-13-click.jpg new file mode 100644 index 0000000000000000000000000000000000000000..20c2bccb90d4936af9aefe9abda1b5aaac4ed3a7 GIT binary patch literal 72152 zcmeFYWmH_v_a+JiMZ`fxM#cI6?cVyJFcDy?AQ$vUsCSsqFqqJ915m{O zln@^B`+pqtI~Z6vc!c+mSV9O1Fwp-n@ju-=nD@}IaBs^{C@|1a?=WC6AS@ll|Ig_E z8~DEr{GY}EvN9iFn9~tE4|p(YuuH{p6XM-9=^nz@4KFK^Wyvo`yoS~;t>l_AndIi1 za|q8P0122Je!ey*Ii!22fR~q_2rep|Fe@&cz~na~p2sfEpJ3xRoS^mj5@42oSQ$?L zNOGe45a_pYV7|5X>+kGhT{BW#5EMlcm{KN5W4UrsG8*RESjz$P z52{xL(Y-FloJsK?J0~$iK1su4$n8wakIbvbS>X4fDHD7=VvR57A{YgGkR7M2Ww?L@ zvI6HqZvLJxzV;_T;3tdA@&}>lSCQ`^c=C^O(KU)xGh1BLS90Leqt&JOv`^j%Ql^I}(%CtOdcmtl?A|V>HZ!$Xa>GF9JeK-_@r#gtN=FM}T*}Dzf;*!wsY_4zTLH(!U zX*nl~xOD>O>fm;DhKljh)H{#Hj=|OkA+?!ZpHFkQ5+XrObXJ8cgt+v>YPvK#rtDPR zc_O9F_T5=~0qJWu`HsK;3JnHsr>1eIYMrw#wL}?_iGR19edx4%L>gx^Q%6ajKuNop z>ZN{4?kUgu=9Wa^^;Sr)`P%pAd^l)7s%oK!(+`x0Med>EYguMklWX5;pgC`iPdN8#IcNK<7p7S8l}<(#WWm#! z7CQM_(U=e{0ISOW!>geQ9tMDu23^ZSA%Wp>3|-|=_1=wJmU@Y|TiN}KsDA5T>4EBf zpsn_1;E6++g+RdvrC$u`tTe1B6*c}&WD8=8CO`R%T}V2qW04g$;dicF=grfQx;D2u z9v4Mo5hr(MANK3lr)zUXgc(LtQt40q_0^j<3#oCqf&6QpWT?s-pDwkpCm6aoW-5&w z@}>&WZ0vizu+Py7`_;IcxNk$tv{RU$~U?4}W2LotH3Oai|V1oq{Y+ zREvd6%VQ^KUi#Rot>fU*tHx3FZiQK>!TRPL(&Bo&{xi6wh1Ha-;S@MyEY7{0F?%zv z4k3&TB}A%PhWJeE4pd;(@q(gVy|E ztl8m2z{P*8$To)R2O^#XL{n~KB)P^(Z>;K-^HQ}GUXy5y7+W{m_7*fs<(WrEpJuu1 zS66TIa0)GNnv?eL>FwWB-5(nZmF&9(L9+rUN3T*F?f%ME0)RIta<}B&OoMeMUCG_T z!>iFFZDhcZ))>1rXsb=1*$vd>W0mn}X59H7JMMtb#{p6kJ7RFgNO}>e2NTF1zU1m* z*)u^LQ%be=$BLeHfSNa`!daaCw5f*-NPo{xw^t&c%Diz7vY1cbb@3C_q=DcbC|ESH* zghk?ntdZ2~?!xg$x{h6WiD56Gfcr+0uddxh0d+1xCqM`L$X7AR)<;Bn$j#?mN7#+f z{>lDqm>+My;QXeUS$Rws$F?{Y;20UotHEw;;mx{sSj1nymisDp@al9@jybl~XXDzY zn{-l3#(jM6Ik@qmXY@Fhvg}@vStmFyp`1;ol1%)!9eLs=oK}f9F=0uWfj+=8e zte~{jc5+R2YaRdAyD^5ZXlz@nSS>?+!~W*Z-_U%YpU~f-H|XqK0D|+yq{aHLIH7}GwG9pk1=qZmD*PsVx&2uvs7iwB*8t{_c2WStlO4F7D^PXG^WgxD9*JT zU6<0UQ7V`gJNeMb`ONi{u~>?EKP5dp``XS{tFzi*JHONA-XrAB9B0C~^jBO^ro@Z0 zo%=?LkxomQ7jvElPL?w}TWxU5{Y;Bx*MgQ0dEF|ado&EeYT zNho+`^<|pd0h#OTUvc0o6M1Mes_rd6ceJOO6*zgU6)NXdmTs(90^DA$tlMV7Q4;w& zIZRQmwi%j|xupizG--A&?)2&n8=_tDLpqpm!G}k_GWtWcjP$d$?7GF`Y|)cI!~$__ zF|dbH+Y1>%oxm|i;?YiBsJ&^7ZWT4EA6-rvETFE*lUKtK- zGOPSjsT`WTL#ki>dWYzJ-Out(o1>S*LT6vcHJ~pCjMv_=lGDfF?a-MfzRXq4z~$%| zweJ|2^B=1oWv@GN`^ax)l{tV^(pY9T^HS+W-VEP9c|(p zlot3m&}_t>IAFphMyu6`x)!~5qV2=!f@bM>8wtP`tm9`YKiD9orC;gNdA4C>PiAub z5gL%m-#A9?c7 zac!|xcc1G0$VzUXeB1_OI~ZPCtlP%5hoc@hGw+?(JAp!Y1}h(yG`B(6CzUeZQEQIf zHQ+GSrPLP2dFJl)#YTSk&yG(oUmH~Z3K2TgHBZY`k(UQONYR18Wj%P-caOI&>RusM zYr9o?c3vC2Unv%#`IZ&Op%S`?N;g=3YJ8 z-g3v}8**oGe;2ahnyy>*SEx{Zt><-Z6?y!<7QoTE>?_P#!RE2(nTpQjt4Q4n^J<$) z0b4uf&>l+?q7>d!0eGZJ0e0K&(bUsRV?fpX z-coK?VEUcgF`2=10l4m>I-hQH{oJnp%Ha8?G@$J6gvb`7$>_{46}aAR>~44va`W}C z2=T2*J>coo_xH3EV}d-}H%zt(=Dqw@ybQts2aENS=jQ7Oi&Fhezh>(N$BZ!E8B^bmDC{|53jbu4;Z=ZZFHrjAI$i`3m5C`z8=4C{9Dl0qGdBTg(|e` zvu&=r*xZK2ccsRpo`$`4{Cu$y!8!E?En12K4JhH-3THg#lYTifE{(>52d6QIMV^3; zcRr$jMTNo<-NBPYcU`q`mOa#FlsMubutjjQ<4G-iuVU%ljbK8znKu>mQDcUhUI3k^ zc}3tFHKnvB?S(2Mpsizfu@ztyM>xOpc(72M_A8Oi6-yZ^QwQ7X@eN9_MVg3nWxHV- zbcQ0)(0i)ME_^?s?4xH@u-nBcecxcM{Q0k-pu;ZjjW4Tpnms7v)OP#@HYC<4;s9WP zdqUW09~)z{;V+PcFg{eYtZnsG18tq-xV-d>@t1YNQNck+9-$b93;HJxic_D|(+uOv zQd#eYPQt20nrPcZHUZ)>)UkaJk=f3!vy_fF*g@)(s%|I6dad(7nu=m367(*2?uQ1^ z{{$`6tyJo&OQ+t6doq9YHb>rLC!0J^;HV*YzkZ&Rx$mv}i@F-`OD^{FO2&)*7D!C8b*K>mknY!uXZ8$?&BMV1|s| zZ1$Z|Tl;eMf~x`bRCqs`y)uqapMOkc4Ug{!!7<6T{ZglgpSllYuGn9G)sJz0e!?iX6?`XRU;3qO!dmF!-mG{^_S}#} z%Q5xW9Zh$K<;)BLYzf!guZ9&N?}k+ws_QAK$xfQ&lXxK8x_GK@gauZE)Dj1Z1Z^5Z zKH+paw#9<=jk~3Q^Zco?9k?s8c~`sN;C4zpUyEHq@_!8znu))^-?8gq!fIkI&mol9 zMY*O-I#w>N%DQ7z^~hGq^@iU=BKy$Yy(>-diD$g#x~IjzcLHi-TU`HXz%5L&=f7bST?4X&Wa$$9HVMhikw1 zrPIgXwZ3>EXCw``2g%2Qf)OJj5aeu~NapVPaum zQ^4ck;+cG4Y{KD~m)aJg=%)TwePwO_B#tCSl^DjXBy9oyP90vI8V@}4tpM4ET1KIY8-74a< zn?CH56PabrV8#wsx5Ri4W^^ofudKp>Y*MO&OIr9SenHupE#^3g@O$BaA-NWF9Oi!o zNy!f`KgdMzqYciIQXT$xDapUm&;LIAPY_-vqFqqzp9C>b&Teox zZxloWsT0=z3&R-dzvBl)j*_b5NLTAG6FX;8<(?735Te2bi#0kBqSb4z<1Du| zgmZiCDG`JFvv`Ac(&vUsut+^qi4DSttai*w@19XG z*nS-L8+E~pfxhAUzyEC^054W1-os;gwBS_W#+-hH`^bN>2q{I`96^kiZ`iJ!-s&{P z`#!GCIZWrYwie=-c6`}CzGy_>POB-`^`(QweoSM*_5O5#6lc91^+(vZ`eShKq1i$9 zc+)V^ACd1y!oQ2@)fT$)OJ@5>-7}?!lLgj;yW-D7knAj7cdoON3RbH+r7Q;Lvu&D@ zZ63Zp!ob&}_oxXeOsST~cJc=?6B6WxaU$N|`E@Y~VQ0Q@Z}h?;8<7RpIe$drlGjUV zi}C8{i2dMw#iMk)(%BOa;+c4CfLq}u?cw8 zaD=wdeRdB`OhAHB0`=x(^wzp#u}a)ZVFvPt>?ClZy?XBm<9hJkpwg@cUzKP0T0jnD z2X-LUj`A|QT3o`SYDariZq;~OI4)t>{<0%7rolD|?_ku<#xx&yF203@ZG$VDR~O6- z*hUwPZNFcjNPm7*E+Xk{&S$2lCt>Q3{r@Bxop&02D~tr&E3Z*pJrOdCO#oL7SLnQW zDQDwIJ=aA{QHm4Fc>6U(RyvzfRs+zQ=*4-@N2gk}5FAm8IgZ+`OdhUI0?|$YGvWI{ z=E;$HfqzT>;lTb#bmUtQc@w?bs!^X!(U8~yKPp^^gth;yMKeJbuSlFu1(7o&*w{6- zxC>9;X{5>WSIx|UG<-n`7UhfE#LMWCoh|w z&P2k?Ia@Bm5Z@>Mhc_t6y$wa43!!c6<371Kx60ixFbzfl+nhCb`Z9tDQD;H(mL-p2 z^k=I|jY&UKG;5J)3x4?~k{N}@i2=?#i)M}3v*&-bnN86}NhZG1YFO7{TX z4bEmBI>w`5Jv72>I~UF^Lz&G*QJM0>4eFS2=YC{y1FSFk{f=$Q<;%lr zM8Oo4ZS4gyI0dPvsMfsSU5I~yijLGQr5m%UnYtt#v4KwqK5@>|JkK4xLX2J5S%9Gx zN+0i?a0zg%{REiYT$kh@yX47ZWm+&j$gyV%Zsed(N!!!5^#DK-nk~j4*Io-8Jb!Hx?Jd7zLr|4)N|HC z&-i)9X2uTe9{`u!@}!`eV3icSjvFrW&FTS1RKc`FIk=>dQVfhu{zRg%-@(V=q4hVY zgY1>V=BXPLtVT#5$gtOQNN4B?qq2(9o4y$I%^l9tBzm~hZdj?4lMwK9!1+7(n>DYU zOV_|yq&M|66FjOTH<6y9Qf82{2JN+nPm+K!q)wE0F8E=l-Qj;ET^rxTt@ESTp?VQq zaQrq&L}^d)-A5S;<7AryEY_0#7#UVcVr`@+OkK|}P69H0hEO4I&sh%;kO&-Ws2#IA z$X+~b9=qWrwB<%EP@V{!RkiC^ex|Q$Yp$sMl|M{lyE!D8Y{yT6iO2mU7x%HEn={IL ziJ0!=21bsSA%HMOj7(i+&JocltSFnSHAcb-yC~(B9fBXa1#zIz(3hM2^1tg4`a0Jp zC8Y3qoxMSXww%AE%H%D#>Q2ZLC1Z+(XPIni?t<9bcUM-e&2^h}`x?t9H4&p$T0J5@ zEa_{(vlIO+a%Q`Kveip$FBY3HWxAGEdiusIiPBM!Lsi7-6FWKfTwCB~TuLN_Kj-^r zM4^#U z6)_q|QO;z}d(0C(8nL6@NP0bOO=jm!-uRy8xv@6vyfwZaAOb70SaBoZ)Q%Zyw)4`5JN@~iNNaI(~A_nFt{v%|FJq!$gSPCKtUNeQo z@;1T4`pS}fRweu!zZSy^%Mz|dZUCF-kWr!!yra4|+lJ%s1^6v-E*g036e!~Lam(m+ zs>JcTJMeS4Zh+Zu(O$$JCWb$J&xvAzs3MCE7f(Fwmm-pTc}kqs1gof0C6}$AA8H>3 zh6p2Wo1J(~H)ke~LMX8H%7vn4|ynXBP zRppec=$mP`C$t(K&c-{CT1#!+!Y-t=UY4+qH*OO-Q3(5bLzwmsM~_6tI`l#L0>h@5 zzumfqP1XYTfW49MVzKPkGS|vyp{fxf<2f=c@-@j0^WO^e#Anl(%c!OFQ-}%>-zmyX&m%VwCy{3-?2M*hOq@2D)q6jP}D+eiin=6g2@7+ znC^hD9d z(fm;dJZ1~K0OnFS<+K66>!l(rCA*sy5qO+J%kHk#tF{)Q zAKG!&tnWG`Yd_ybLivh)Wp=YxKSuF?yf}I7cT+F)9C6iAN1xWrsZKSH@v>XGqkrl6 z?t{ki?ujnJxdCVK$|g6C9!=daF#2M;Y|!D54~Jp5wBRjju-%1j zf3H=z^$E@!RM6D9m5d2lc?Llt;Q>N#`i}EmVv-`2A62$W%YUYom z&>j!UP`RcXc*;OgJ(h4z_%Y~y6KPE>vO}PYGCkeP7ld0DyA$cYB}juzu{aaRyUFpl;2!K=n_fdMphm3 zfuuSkTU#3I`Vbvw?C|E znmI_p^|0Sf)|epfRPoL&seq%1Z!mZXezgR09PSz_EMA`~0rpe7@$L%;YWPWLsoe-5j;~g#@eMOFy zF&Rr$d)NsMP-NURHT61u4avIDLYtI_nykMe$4~p;N!~MULRTXdkeKYD_SHLBI0WU7 zEf-O^p<07n`LzwJRDi6pC2|@2fr~EdGGb$7^Yn3&TQ1!k@7B7`5r6PACjs(JEybfj zHI@KxB-QqvH-0#MA%Ph!FsEJS4GOwv^PjepbfaWenzr)u2gMdA%s|~0DWz!sMwxi2 z*~-(I$b|Y07TQ8yYtaowEex51^kys8Fpn7Fl{xFAi{*^>>wrKmn2E)FfhD2cR_NCp z7h#NaPf&f+u`DfGDsqJzv1pv9Ix0g~jSIbz@XsFR(~mG81y^P@gGR_ngOL89i! z>w(dbk>}@J8E?KVg$l3-qt1JgSx&b^Vz^R;el@XpOaD`ecDC8c@1Bu=bj&qVOxi$q z#JlBGP%7osP7qhmNN?Dbix2y(-}Oiy#K_iNP1+vAYt0|ii4v|3KkYk|E&m3E1%G4I zJ5p8Z_Y zz4cJ7*BRGjOV$7?uEj-y&2seg+Rq@=oQ0T7h5h&z*ZP#R^I@GnK89 zYHN{6Yhy`ncG9Q0@oMz5!z~R?M+Psg@G#=KR)6 zNV#wlH#Ww{%_@cUdNDW;xPw1a#rzm6$KbpLm1Lv*!M{h9{%utTnIrR{uIalBn0DP> zZjiy!UAS(j;n&B{T%Bk%$>fHXm^W*JuftB$3fw3`BtgB5;BpUphHzOM36kZ0_>Y=k zP>LU&8&RRO*jlGL5tFQ5lAzsiwJBal zKGE2%RMg0`7=NiVv}@=&g%sMKU(MrV&4a3LO28WwbqgYRN%zwkxIrUY51<`~Cq4i% zMD=JXJkEB`9RX%IbkWo;lIm?8QyX^&bL>x}tQPLm8>*^lJx_e17_bZ^YKN);9f(|j z6NT>y5ba)43O3n|2{r*QrgEd{EOFn0UU;mlS#EUZXFrwUmeb2cBBn4d(&MQFkT@mt zaKl@PEIrb)9mkeU(5%Ladan(`&YHSViI5Bxbzj)_DR@k2l5))Q1rfF$zbbZr_K(CQ zTWhSecBs*5C}=E^?&o}U^QzO|%}hSV!f9CazNoAYI0KTTgYlbxog5V;C)3dlYlXOzq38vjUBYiy!T1+u7uho^jKS%q4k zz_!f~#e?tn7)0YzcvH=GYnY7e+?2W61()`k(irMP{KYW#2x&PO+z2#^<$%;Taq2b{ zoq>&~MF5SN;zfn1_{$p*6V z&%{Npz5L3?G@cesJJ^abf%i*>1}mJE3T-(pCD(s zy^r1RtQ30W(X|&EB_o+|!fxWRHW<(>YRqyK)f|6(nc!V}p->kP`Mt2nEj`F-rD>`c zf;JftIK!6)YGM~?Q`e_nsAj_aG9_4~+>bCH&}@%usOZDea01=`7m%$(Ck!ZZF{lZY-s; zYlV2tk!m+!;z7|r^UX?{iWwQ$b@_W?12*-GrY!iJyrG{8ic{M}!wQYqwa4VRxL9lK zd|-s&e%ld-u#r3*g&J%-scSV62Vr*s=9B$`YljxdY7}e)GbEBekzNgK39RihFjH-4 zn^&_BN%(IoO$rg}`+@c_#l*^zz`(%x8ztjKGDAh_`Gp1B%*;@P#+wn2vLLhG&7jf< zY)w?qkBT@f4h7d%X@@o~TCjsn%AhNqBZ)RsrzduGeMNV1MMe4fbPU@E%}RVB_4-qW zXTsyS!va};AhByi#kOqGtf8#^d%9qa`$!=1FD3k7gz7qKv+;U#;<(Z@v-qnWf2wKf zxl)qdpkmf}xI&n?wQ7GzZy-R}wL<51QLM@160B4esekE*(%1uonU~r~Cm-O|_r?Zi$N8qHvc#yc?h!Zzob&z-6lzo6Y z8mG0|bmVC{O_JPruq)2;j-JAnoR&Y;GG{PQ=Oe3)16o6^S%0ow5MI zlG2@XVAqY31&D-pf|{iCg{HWGSA^AkIeVbR)QT%&$I9I~vv`b1rLd@sL zBH}dDJ>`B{GCJ&yKSC!RVag7q07iM)pQ>$+JyyvjUrrqgmqvNEV*O0@l`3^^FOa}j zLyRAXLS<B+zCq2>lk6__z&osZet;(! zsnKhrvsuk-8x1KNrtHv_+>?Y1xV{J3V~2~X9n zg&D>IlP6vhi5z1iEl(9CoVc7YG3@u*2i(7eZ#pblTD%V7ABXflEIO)xpsjU@oMDep zIa*435YN%KT$>9!(ll==^l+IqE^s4lJr7l)FgiI}q>`+QZ%tl6P#t!Ti~qgDFVGN- zBc72{P||vwHGwGU?v}->_lb6W#bB3-Us&pgR>Vg@{`4&7jMlvsyM}#*Ito_?)8M?h zlO~Uq&(;9nKAJ*w&II}1q*OQqgTJAIc4$|RdHB%1u#9M~BkRjIAPErj@dV#1$6$Cg7W-2nBFzaLI1VDrb*^YuX zEsXS`Lu46JTksAVbx{iCKZjk3eF{e>Sll!bB0oNjxQApRREf55*?v^k2{GC@$w?x6EK7wHz7Rer z{I{g{3kcdm&EUEDw>6|}mmP&Zj;_!;dEfwFD^_jLxd0#fDo-;tSu9^jAg%dk?<^%z zC+wtuuLd)ZuQS(|^|;<9B}T3-h1p=d#&4&>1VHt&Zo4a%*fbpbvP_G-_v~W!?sS;XY)DHRmb(vK*y;X) zm4xErRb{sfdYFVmp(g7k#7CwR#gIR_irxC_a#MbU)9W?0-P0mj{zvcgxt*%~R@@10 zuU*NZ6WZeRTiol@tk!C|Acd{klAJYx#%Xo-h}-6g0z;8j+bz{O))2{D zhGAXN9v`hynVKGvOVTLVCdw*P{R0-hZI8*ane~Vz2d6c6kXSf&4W)XtLW_jX>VE0c zb_4y2ZLC7ntsUZMHXDxxdc#m&z;gZ(pJCS13uLCu+XtkMtDB199#sCEgNvB;T~9oA z(4LO#LGqna8_oO{ejOdMgyrKcoDb?MV6zsB{Fv%WttMwhY;D{VfOb;1mMl;|?5T5h zOfjN!Hi>rf+ok@>lK0u>mUnBX$!B!>3|D1EVY&fXx2(>kJg#q7T?fm2>jm-+3$i3I zRw|cUF*=&d$p#YlWpQWr;aDqKx=hYGYNCcYI&LqS{pnKy9&n=7il#U|6JAgSF~PF| zky9yZpI}Ih>agm*%c!gi*-oEnhZErMW<{Mm zqd>NR*gf1+{I z3m4#ZQ4%`H?mt`t9?ByQXs=}JjyWJW_LDX5p`EQpq@oX(+DbOG77TS`LX0r*N+i72 zSP9hYHp@RFFqb;SO+6bCxFcg-nOnemqqMYnukYi}a#g~wUFkBcs7*`gZCz8u{DFfN zE)Q(WN$81A23nqF{+Yfn*l909>!?8`BXKG06MHLWO1H5y9k`=F#+Hm71ltvQAMB>3 z1+I(c7~aEv>yJnU4c_Id^C}+@*VPmF?;WEx#=Pk(;tPXSZbErThJpCINoD@wlzhWR zgpvFYdeBZ;q{D#yPbX}hQ3>s8*(LxuacI3eF0rd4AB7gn_1?N*jNy%SbBcS^~j|DC4A zz*;t_LT`+}X-RI(fHJG}Hz;`d!4!$JYOiPVi`nIB0tHY>ky6#VsNAEbJ%ljaG7w_a zOE?|YAGIhiIc418) zqM7>+*puXAvA%gJ%qW`KNmf%_U^O(}27%&?UZ9wkl6 zfbUggqBV_>VgV~!EQ!zfT#OP^mgxhTL;We`%)*oyJyJ;-V<2EBw^gl2|k|G!L8< z9@R*pOT}9g&;MK<$T})Vq4)aXH6wf0sGv6LG(a^VeOJb6_MF~DwPvM-#!@r~VT{41 z_0PR!-qgQ%CfKVNoyD6dy&ZY8rz*h$wS!vn6jGF2fWG0eB<%R5vx(TVrL)sm3A2u7 zPDvY0Z!FsrO}brK$H!TIoBB}Jr!@1DCG*HcV-F*`Jkg*r?_$cBk#V|A%SAd%F$J$8 z+4~Qh0IE(cJh@Q@c{W+SmV{3gB;%C))Jhs{^@UiZ>QlBE_2xX_wCjIH)h%-E6GJ~H zz2Ns8`p}>YpUvO%k2!)+70Y{)Pa5>xJu$MYe3BB0awsO~{L8E#Wa3w4g}yNjtjy$S z(hV04M*{WYQ6z(&?~P-3tfVwEO@m8<9#i7jMeFXqO>>GK=%JgPGSZTY zg{W{Qd-!X)P(Bi=wmK0&wvsOD{xRtx^vPr!k&(8@Khesxk@#8!t)l^_ZZAc|zYAWNF z%PD(*Q)RCHPp{)QDCvPiup>`iw!*5%uhN~X!oCupt|k#N!CtMB+ju`>%fG}FpK z?$}>bc~Je|ne+vPX}=IjJ^K8!N8-n{O+V82b>_~#sSFYaj0PKCpzg*Os&N~Kt*R1O z${K;l9Sk&FW+@P+-4>X|QRFKD)>$>R=1#o@B?ZuJ(9R|T=*ToA8?8{^+!^yOGc}-F z#s+@J_O4SOvt&St=mt5Cmd@iaQVX)sJ){c2Wz19(h@^Wfhx zpWUNj7W;@*Y}~`AY@TQwy_P%pBx|E6HI?5-NARp${w;Gs%t$tY$3|qpU4&P8r_H`p z%d<9%l=qSY>*Wu9N&+yG(y$G4m}%j-o_Q_R|Jf_7uqXa}K;WQ?x0IqP6~m4q?8p4L zCR`Q1ie%UvhPg=uCaMseH6>ESY~SG)FY%xq2~uyl20By`tADNy) z=}BLW8F!2l`l&b>DV!R{o~9@ccU+BHR(8mOas!)N#FnbW~kAZ4H9D~ z(?HmJGW64ztqO7j|37XjNylx68wl%8hRS@|%Sp#8pgrtVkQ;2B4YSpQPR`PUy{P5I zI`v@0a4xeDBbK4bzrR7Pi9j|fv0*|%!@#_I4+jkk^$zBr%~g=o^Dyr*u_)LuuyMpb zvU8}Ynv%m(imSO$eN+D$|L^W3$kBTd=r^eILvrL4YR^~Jc5pzNAYiF{4kAz=1}xm~$PBW&RJuZGUbkCEoNrFWAQy9|DhLzXmxq-1aUI%c@{22~5JZlB5jU}(stw~K#XAqd!F z4qtXW`aVNCX4u|?{3Cs(&@$97wi3gaS?7-mh->SxvD&6F^kkr$+8S$ohQHURM zH+tFFN&W2$sFF%>qB>W+lT_ z_ynksSx*Zu+Nen%OyvBLp>9#Kc2@L&8{~y&iYmB~fxIx_t*Y-#n4&00wC$5xS2fdK zmi?Fk=bs|!H!=sPwTu;;nQPJj;VWf1BmF`y%K^(bfyin;{SSDrf(T-&5((oKz|$v( zO=aE?5}bMBAE+%#mssMl5(KTE@aBe!qldQ8@%=^(gDi_l=0E%pN^J?C9F2o2d?{nj zK8YD^M`{?EvI6ho{*6qI-F-+77MNc(ojs zP3N!Dqq;=d2km)~qnxb!V|LLtst{88g|jT_Uo4bW?Or17JA+Q_071M~AA$S=r?Xyj zN@foVLeKE4lVHlC4<0oNl_SfBDN@{&pKg(ppE*v-bUoJsejK;*1mhc>hy#;1nkVMp zptchW)0KZG0Vw6kAZ-1U0Zv`rZ%g}jufXSRMs4vbBD7$z5U%He*vYWJ&n? zPWaEzN-@EI3Z@S)84`z3H9WAkFrS4}S6NmrOI~FT)j9b^vD0Cok+{trcU2WgCveFM zgiRzWcBcn_tLS`(YG_&BZb<%ybFYBo?5U^8(J2LEuddYCC`r4aJa-W>HO2 zhdE-iqHa^!CE-yOepIRa#NC9KPZ~r%S58M__p`$IvoGURpQw8Ad&h5=dodCo&Z@-4 z?JX_HH50*7alIxDcRG5PqnU?Mf59`Gbs_{1F@& z1s?%yPdRmluK1v%Q%-NcLJvuqNy+=`;8;q*10}<`NnKf2O+m`;pEj-*`Ye$8@kb)( z@&)!b3&!xf5rF@?=>x{yZfoAkrHdcnPxkLgA)?@|&QG!>jMgvS_u#^c-@SbzVT z_Az)H?fO&bF38+|I*a4i%!l1Q#j+%e39p62>$Y`^35{XeQg6AgQ6f6b>+N=G(Ei(hZH$8=1LM3p0{M9SVc2 zHv+LTlciVIQ0G+I`Wb2rT9is%E{!#ba_{wyw1D_sbCSGSm8_l;Fl*La?Y_%?gX%uw z>tn2NV(w4S6)^=nx~|Jo5lRj6?$SFIo-L_d>b!35Vtr%jpfyciQ*#~_UXyntw5_`8 z@znDgttJI{W6!FMLcx-vsgYQ1XnifFcJaqDFki()>; z@P$p7+>k$^jXzDwG6%}zc{*wtigg2P@YA+(=v=^3TdfkTjKsltFG&*VP5_FjR*gq# zp;WJjL@4!56Cw(H=7uz-!BLcWU7@ug^UlTxgO^3#-9(O!dgksC+n?GOTW!|JoS{K6 zStY#$&|!}6!NN#8y4d2NLDMTQ6c+VQuEJ8k zxcKRyxa zuNWNhvB~1e0J-IoAyp4@^u5gZ0p`Pcx6_B3C}R&lT?F|APPJGE;J((-(2NzfkP)_! zGN_sU*N=dB6udHj2{={WCR^O+?0YjCP`Qf}#IP?th=ngQ%NMm)-V57+QHM1^p9^ypCU-$TJb;weEx z49owS(7$_+4*ieGBV`p*Q2fj+tnW*%WdA=5-uwSy@NW7aei;3KT$X6|Ch%S;jl424DXCfa+l{_xcy%P<6wq-3j4?%!S@iSef6%dZZuXwtHn$^a zRc)aHqC5bNsR|Skdw34GW3lNdg5dIsaekktsL3ARs>#zZv0xkWEgg? zLvrx2ldH$Cvk4d2kPaIhl+md@I~PVd@Se=cM-^2v@TodFEsLr41OirIqZ*0>Z%u z2k5xb!_zpM(aB@~RVjvPtBmb4Z|8sgDO2%SOpZxJMj}?_VbDPs@4spf^^ys$`j_mx z-KWDFI#^bt1NHBpfVu)aR7=z0^+3Dla34a$<}Lf$lJLKnD5CK(F$$Wc_l`t+?)T39 zViO*DSiEK1Tw~juNn{aTS>CO+6nR&Ppq&dQ*~5VZH3^Tujrk(?7XhJiH0S?YbP&-g z?{mdI5!mk!lTBMY0e;;6wMLCuy1_PZj$Wxzq87b3SNF&h3x=gBe1AvO#T(uQ=TCAX4g*uNY+Nb1YOtlVOd+v%IOoah(HmUf@uwC;J0s$ER6G5nHL>*t;&9&r{JwA_=XSZRy?Pc;T&h7;^r3 z-hH?Le=6OqorsE8a!q9^yU<$=*5C~2dl}7l!5UPCMoJGQFQGv6e9a@KYv`WlNQ z++)`*K!JT!9J>n}rA|%5H|N_rHtY`U4!jQZNSmO%+=OYx2Wc@2E(_HZA5Kebt%tuC z(^P^xP%fPxEy2ol>aCD+=loknlxF1JR%rpcmDGhUOGJozp?zIqq!zc?ULINekP)lB zUAs)85i1_b->e+kKTuO75E`n02H7dUe-DEI{{ar}{a=@!|J^BLum~x_LUzjf_P#N( zXqcqr?84t`m^qXje&t|^7{ujvPg8vT;pn$@sciJk(7(3l>O*w(%>TIgd=UKS=CgE% z+z$ekhfQwj{(*A%{hZXf+Wxk8@tes9Liw|8?f-qrV0&3%d#<&y+R)hp zd4l9GE0x>m;{QM)g3tFxTml@{wt!8p>Rek7>RcCy2Si)Ioi@4*7ynB8^-rMLExOD% zENd2iS)f*6RC{cz?4WpeWu{^D9A|8ZXJBTQAwh#Z-tsB9X0_o>T5q>=$?_$!bJ+4F z>6yV0WJxrtx7+B#kTGiNu(a9`xmO4Bsr{cD$afm&T7wQ?-o%>a?+w#M?+wv0orjl% zFN+c1VSV#VioEz$8s?O^MBGVf@drxWH-*_Dy`H@*vtYcl{fEs3aHVyD^ZahSwcQ{V z@S%cFY{R^m_c>5EK$e?N>}s%El|PGPWw&l6q)hea69b`V%!mW#?M`_)!$QN#EA~$o zzGHaMxH*1A#9T?1oDe6RnHu=R?4hbp(90WQ=`sA>D<%B(_dR|@cYClJ_P$(`?QLGt z+FaHNiy?k|iX}H?-;QquSgavGU}C{wA=?GgrNu{4o24B&H#(i-xnXe^kfL6eNI!UW z+JTio*N&bEz(xrqrWi0NvcKWOyC#bu&SRCISM#y`(ZzoQbW)Df69>CyO zW^j6KQyhiU8mHKR5p<5RJlU!4$lKm&tqYT}kHfv`Z~Bgu4OrEC&xLLECuBlkmfNAS z@<%ZCzC6v!E7G3V{p8eML$--c6I~gTa*4@kr8U~jN>qJA|F*_jz&QS8!U5(>m0Rol zKzrUa$yfPqRh=x3hYmk+V%guB0sLH(=4v)Z*BPCMvTH$g!{8PiEHJRvmyrSzVr=hu ze7$y|b+{lb<^tew6Y8zrwsySJdW6s@w{oefZVG88*{!3Z(FO#f+3?@x4C90GXOOTS zeNK^Q$LGc^YOGV>3r(%ztIniy-ckE9huQAY<-h+hTo9D@I}PO4FG#m;wp_{E5wXAx zQ14dtfVyPYf#)h;?Z?$HX7O zTa`b>%3*gf_wKI~x{GefWcbdd{i%A`PvI-OiJwt;O&!vC#tdocV9J?l)D943+!*|a z=M&EDn)$z|=W5?S*R_|gTDQ5gzomi<)ydSeTl1&s<69>;A)DJHTRYb>ak3qKJG|qT z1AJdr_5i8FGn$CTZqFn*`-d6U2b6wunz10m)NB(LIb&ynjDC>QW^G|wK;fLKb zm>Dh=2aLJ|Xr^kS><4_;A@p1GmPoPZNIP$r_JuP(Rb92YX*G?L#sT~rabDgxE|4yv zOyt|<+*;s0;D zPkyJh1KrqTqEwtBMkh!o&o~T-V;*SB>h@c`a4}js0ta40U1<$xW+qmdptaIxLTG6z zaJ36;*1uEii;C1;ek?m!>=Q-F$!jO zIwqy1vF)G7SKGF;^!`n);ru8rXGonif1ohb$PPQ6AXM$Yh88*bFo~%D_M&&|Z}{6c z|6p{10C|881~BkL5YxAQA=J3&{kK5nhFDew@A)ftDS8GJm;Ec{Wqr(zwl>Io^F?;O za;B+*!mYpFM$47$Sym$`{^f6H>U2a1YVqrdu`8mJyowv4aiFkuI%fw*rgFYvkrUhx zHCfzHy>nr^kqgf>zA_VGV}t8!+<)5SIZHs^{%r!2=X ziYv0_U!{mULvK~TN?QdioBoZNCp3IU7ntSHt;`ynJ2jiH^r{#Q83f8HvT(}l3ifle z5$m#CyRumpkqG*zhN3l)pmiU6ahAAA$O{YVmD7h7cMl8n4OhxZ{#B^$LcJHoKv}a3 z=1Gi&43vSrqA*49yw@Kn*m-Bq1>3y$F6vWI9672=D-&)E0>_L$s_Sj#e)%uuku%+j zUURh%nhS_Y7IqkRN@&C<%cCPU{H%58uo9MtNyFXBYQF;X& zf=d8Z#q{&uqs)eXHHw@UK?sHVzp=&RqFyA!q8E%s+8;y3BuAGue=2u!o4ythvi;QK zy6Qy^E~#djI7SMe;Teqi*WA4Me@l$>6Z@aiE-;|dB70NP1}LW-*MKw(`=tQyF$L8fO-35gT(C9V_~c#hx9ETW;J7&C(rq_Gj|TvaPq9@L4ii z5?U0F)lMG&Bd{T?rDA?;1N7qGMLTN1%lIG+S9Jg&K);(|tt_-&3t|D64Eb!Q+_jiL zaHSvY&N>s9yaUS)V{{*#MG%nQYmgg;;ONqN20}Q>YhY{iiuGIn=(u6&qtvKaZ2_$v z^PPv*I-J1$B{|1w*-eHgv}cpVen1~Q6IO0i#FLK@9iDQ*Yo~!Poom+$R1IuEVlYK_ z@CWRSSuY(95>`weL&5!x-h-@o!ymq9=~Wq znvTkx2uvJ+s5$pu&N04@C670eIz#;9%!lhSX&x;<@JuQ#nd7(PKKc}OdFb`UHP5d` z8KigvFvVW;)|)T?mZHjenVo2Ke{sUwz$&n-`UxL({So82JdPIn)0jtfh0=q{l<*+v z`Xiry*^DFG`$xQZv-$b8t2%+mD!LpWtmWmieo2f+8BWey=&v9;jAi6+>3J`SRitG> zVT6H?Rt}y_=1!{ROIVY+Ul$xo&Gk!+kUty{*c4*1au#p#B`$Bt!g73boL)hnVf*A! zl+Yk=JicQc|6`VILF`;;VFuID{>nI7;|~-EwO!M_-W#Q5*Hzz5{k$yfEuydJ9`Lr*1z}fH`GhEZ6UtBUao2sRpYflQ%8OzJ+cv051FpTm*^XM+7jYCM3ZDD2>&H{rAJB*F2;(0p_L|H@M3qhj zjhFl%cN+mGJ^a)MCcRk_GO2J8bZ(4qlG8FhgAGf+N<4l45iazyG6t)bo8Q8*&Kshh z^v5FSmH*ojitiRtZecHG_k0D*4l7ydV87lZKiwcsj|TjKGJeF0X&G3`++tOyS!?>qbk`Eud%9Z@AdkrMSi2anMZdxX@2(Y?xQD( zVm@D#W{LK#mspx*eK6bjF-@nHz)_qCX>opB9Q7kfUcD+SvrWr^Hr2Ytt9pP2?$Qi? zbxWnRBLV&RTd)Yy53uCi`)&@E`EQm}oZattfCO!5!Pe^VbtDu9csY?}{%t}!1I-z` z0a=;)E6JLV`+g?*Y~^o6l5gfwLWV(-Rgf)#P8R#Z+&81v3KL@1Pdw_PVSKnwl%vXY z$E3>xP>99GqzpyXJwz2|WP8i6h!$lH75SVVIu)G7lbAfZHh>eFOUbxJD|Lh!K~A&V zyzHn8RSfZd&l|JR7KU9<_CI0Ymq{G7T9mcIi%%zyMY1xqUFR6L`eR% zf1rAKpXWQzAu#0Jp>}kgH{5W zlh8UC!H5Z3IdaZj%Nwy6TC?{?_TBCMl1l@S2YsGY9i_12Hy@QOUCC%hq7v+A(d(hm z)|3{%cRd3qHFGPSx$vIQ^Hj5#=0_tlB-hB!-+6=|2euSFbXRcde9&~qUxYO0*2K|< z^;45D070-O-I1gYI{~L4ug$vrH`4aBhhL6t0O;je`+sYEbJ3k`L&+vVpK)#>|Y@mur{jA4y>~@&qb~M zqq?)U4%3O!FwC_Ivr(8o|3Il|?ASeDiS=Exz4LAFA`8-e577~&&3!w7+i+TVKRluQ z;i+e~wp&G1dYpaH)Tzg3FDkakkBHnLVPX)^`D+4u!gZ6ZttzHGsN+uR!8jy=rB3W& z{X{RHT%^!wc20sl8AS%MGPY!E?yQ%>)4Cf6^mL+a5?4~%l3B7f)wf0O;=CCi>9l&B zD`HzrgZD+Ku(+wj>y(AI&~7v@lb$me2Tl-2c=KZVj^VqN=XZ)migSd<}V_rUR3;3v>xR zS$mU-Tm~kwn#ig1r#cfP^E~*;;Yv*!qJsvrGfLY*XIww)6BGb&r)^kXAu-=p9e5cm zX$ju`s=L1MjWLho)tKMH5~5n!2;3y$H=@t`K;lBP_0!vji!BJB*N7vuHc`{&l@@(W zX#PpD_sGcb4RGZ0OhbLbkZ&>tk`A@$gtTwSe1*=RVgqWfI&>IHbdXiyL@frJQ?^6= z6~Y%w9zT|ON9Bz|ysCkA#&{5kwU?&IbH0%e+|;0#ZUHwWwDMu~Ddm?_c0G`8zvy$q z-y0xhFD#!xc3R(zmQR-CT^9O1&=VMd{HlaAep*qNJ#nPxW5Rd!A zi%i7~sPRF#IjjqGe!gZ^1C5>VMYt42I02b4IRg!Dd|AHXjQS$f@>9}n+WFu`2$rG z{8V4(cO}yA?CcFI?3(3Y>e^DdK-zMs`^wV3pO(SvnKvUogv2v>pLF_y2wQ*Vk<)5YoV&zY3& zO{+}Y?_Em1bmy5h))|zfKWPvi3=jg3OhBCqwO(KPNTZpLkWyLKl{NP#My(U^3|ai@ z1K5DeL4gOanS7!=78c@4HL-z9mx1VZ4jpTfv4rCdn%bmiq01gI^r<{8QMzsmI!2aRQkRT#-hJu=~SMc@@A1z*v!@o7-Kn+fZ`6}Q%KAN z+-WV!9Y_C|N?%j%igpWG-n>|$%ysI861bd}sC)is$!*)L;Rz|)dNVwMz z2NEo~xkWWU8GVZHXTt*!tt}ifMbZ-GEuYmv>+KVF=Pnh5iKmLPczK}-(RH|S1ac?a zP@Z#9`Y?JLZa({Jox|9Y4XVsDEhUSt1?Bxg{Lam?GeUF>bRyDS*0sDWnA5Gp6>Kk) z*NOm-pF$w~WP)YJvWds2w>`;&rfK~<_0<$``pH(WNfZB9>NSCI87+LEURCYMN3p%d zs*HQ8sHOi{Q=A@WEF}xuKn)$D#1EO2x9)MYpU1}+ol66ir#UmFA|0ep6l%334pQHl z?eX-)x^deAhV9Di9n90K*&^r?$0Z)^83Pb5yQ7ya7lR0YM+2@CRGsTjjfag49! zV>7E{NeQDK_6%P#IMU#asqgCzz3?Z|9Ll zVC#Xl@X_M2>@9inRQ6!R|a^8!>Vllfzov?H>eqU#Oo)gpF&S-%_)vXvVy9)wp2?ji66(p={viZ=|ocE zB5KmKYo~I5T25-$yKSIy?|l-E*5*yBDmR;a3SIY*eC|J+%W6|*BQUDtmH`k5{1vDb z_Ttd2+*9kQQsZl{z~K)k2(@ScnVe5g#7o=;Q-^aJuJq-d_$bAiG<8j}_%iK8&#Xg# zz_RVK{HS`S^S>f!p5=MdXb2xDKnHZ7dz9AwflB`al_IC@dfE$S10t-v#H0E~P)e;4 zgaq@_As;uhYqq#7qClLw-5J_L>(H7=;@y)N9Fpi6HMCMauw&^X!R4|eijTP{;zNWS z{<>BOYkT1vf;?{$Y+L2ff^4$5ktCYZYo;^RYmIQGyAoI0v9pspMvzQADF% zM?qn1Mn(KjVzJrwAJVBW3E$>!n|J(mhI-}YUAFq1jWW0_O?_K#ZTdC=6?_`(>Wx%9 z!wnyJ+0V?IX)64E%(%7PfBXz}n9wHk8dWI8=lm*LBk@fA4!u+6l)mdyC0d4gsMmlm zoaDFOu<|EHm=wL}2Sp@9ze5DyFT`W;Fvw)&|)<6pek;o{C^CHeq^bzyJIWR$fO|J=}IK%4qU1EjMR#Wb$umfPNLZbUO#k*s_X`I3>7KPlE1g5 z2&(I1zyM=|Nj;!!*k2^#6_3uWy0eI*#AHesVs6XY9D#g%J?;Lm<#}!X#VWFfUd|Gq zot0(MxIw=*5?e3)RdzneVhbP!ZD?&GYm?oqSW9RZTm!()-h-Ko!OQ=!PkE-kd0ZNa zyajC^&~rxRP#hK@-DNC^oBOQ3*erPKc*n{swJNNtnK%t$8?758z}ZWKh=`_AkU&`X z4cvBR1qa?gw+ z7jxzNF{E=RWCY7L^QJJ1lJ?(aN4hK!_5MvNh%U=tOMa2D%QWf|iE4BfB&T2_DEBGI-69;j!&&lrV2f@4o36@}q)e_tFJ zQBZ9_%6=**TkOO}qD*L@!vX*Rh80y1antw}SV32@h;8hs=>WRgJ@Er}Yp<+;=@Hpq zH=4~nS&?Hx<5WIc6@^9n_&Y&EQoap+k03rvYq`82zZDAW@YcA2g-$Kjf#rd2kHhMy zjH#JHWpekQZx)s0qDAbFpji#B`^bVPu}~tIM$1}z{**$H7+tE4ya&&~=#q`Vqbk}g zuqOYfRLvNbq|6z?xNOLwute#*>d9c7dO#PB0N*=PF2SEv14n7WuZ1w8OZL@bXg^Yd zY}s+RrXSuHXDSg<5?C}r^lc*hX-Xox+b0|W%Hm2(@ANxM-erFt=~4L^_RJMT5xT?~2E+T^vECfUtgX5At!Gk1pD+TK!a1Q6SuKC9w( z9$z1+x<7lSdo1GmSll5-L-$FF2;tW+D?(hox z+51pcgDd%(&~rVu0Dl(Oh^6hP>-%C$?R-n|y*F4RHiN14zNzS41$#q5K}3%#rZDS( zG61#<+?XwU)-jUYvUSPXeXxF_$^mDiD-6hsvPZZ>asGTLt?{)zvX6L1`^!0!0>&hL zmj$XlZ3nlZ$L-m>W@pQ{Qg>+_R%w*-^JJ82>^QY41%~$ay}|;<5PuVd4iDv&fxZn7 z1FrVv$U6>IUi*Huy9g?+qAhA$*#qQ#h6_f_MA|s{pRq6MJB-NAE;b~wNEpu9MkToE zAF#jg=v9uiu#h|cqPqW8NJKLGPlGR7iDND3ohg^p+-KT9z za1}6B;+a`((b)I>ho8_;V)#gv;Cm|`#@0^HtM*8MiRV&O@0 z8o_`WJ4~Jxobuj?Lq3*9%c+{lqWF@&^q7w(zP@1JMGzx>e~C{p_O(O0oXI+WeI|fI zW-?IWT*1cZvp76oX7U1sdo5N1C&r_V$quQ1b4l1;}!W8Ct@)ceTGjsY|#j4#>$ zZSTbZwh{+hi3gh?%(lg>eGj!y#oeKnI0eqB4x(B@oIM{&Hq% zto!AdEMjA8Qg#8x^mw~B8$c0fEk)V-Cm?}xs`Rz0{j2HlVwMmNba8>5P2p{I?PT!XrndiCcz|DvtAzPSE#p7|I#MsT2Uzal~A#{ zIjKP`$Xntnj7I6P$I=^aG~F&h+bmQDH?P91;r~6Wx`N=wq^Bt$wCDLHA>ksTwu6_I zPk0lfL21Ekg|J{Bu!Rjb!nYYiyvj3@$9{E~>j>q0sM{o&$9CoDe%_$=28kd<@Iw8p z-!VbkDr;nFUn7?^VUf4;y{ope^peS{DAKv}-^Ag1&S5npT+-dKG-6l} zx97ua2YcmjP35yB)`Ww9r^lH^ezd_&eZG>AkKat>bO^VZ%Px(s9|TZ9r*0vAe3?Iy z7u+(K87(tZ2JY{eaW}bJ8(~%DHsN;RH>>3Y2~pGp_FEh4N)rBoYO`tPj&6>_)X)K! z9zhN%8z#4&OOciC`4I12y~*d@0QfLB?3;Ym&qbh8Q?uPz@|6F+J9MzR0_HW~ySEij z=;*MbC|?WiK|`j~drU$iS;}NF`wqq8Ea50&d-%4Y_64f<+>uwEm^}c@6 zB(w(<6e)i1MlodP5)7ElSE|?rx@9vOSia4UM!uNbE~yMW#h`^RRj${|*R6PFu8FE> zt9JaAXJ(H9`Z&%txfgu5dpP|Ziee>EVxopuoQgW-^H}ZAtRG855tmr{6%(1AXkAN< zJTEyS(Fm;c-X#0&^%+M`cbjSZ1}*I;m9{>z1~t#L@{dY0Rzy5W6L}y`si5T67LUF; zR++y*{F*%E58h6eeK^hpQ}46JJ>>V>i*9sh+6z2{Lt5mu5BM6M7~RIO-Yw>(6ltpd zfyyV!PpQ!kYo^_lWSk-3Ivp4Jdf(h)CLLCu_i1cqpp*HzNHu7&dC$LuR{H>b4C+VN z9nWh!oirI^x?}}}HT$b=0xFwwaN){r)^#SG9kjir$#mapv#MURYx24ruCF4nH%z+;C43SF|{0dTX2YGI+%4L|bUoJn=a zZEzUE68lFD_E;PiK{CKXI?!2@Fsga06NAkK#3sx=l*whn=}b|1j$LUIskiUU#-=t= ze3{x&i_gep?};&CUt|5bLmfG(C6W{SG1xk+yfBv7Mv_pty=6|RQ!?9iA?!0+z>Ga7 z%fEKa37A)5vFC2z&s2IR{VrRkfqNRoNuMFu)2HS1M{na}gm|Ox!-fA%wrDI2yN{8? z2}VmaP$imAb)AT~F@5eB1)sIFT%mIs87N6v*Fk~<=tk%`FgQ^pI71 zq|j;rOQaY4Z%!to*yCCnd<`u&xPSCm4GG)%So2qu(ojpU!ya$D!^V0bz10bj8iDa` z!YM1)0V050``I4^?<~SrBTh{9;ZWM?Z3LV@odn0zv!kK79n&YV+O5ipCyzfEH+`$P zxO_)>e+=AdUEn&uo8WE#5qTlot4#f3Y;RF`6%QPNctRRV2x;iCpSlh;Opun=ZUeVD zAObpwJ(dPLj-dHsT23Tw632^W6Sg#_$~Grk_*rsONg4?tlei)@GB7Z6>ixD;1JR=@g!_tjeQ}z1pY-Wyd72s&}ZV zD0oZQgHn$o84mc@>Fl!gO+D}CGOQjNTXHK3(#?y8|>B}zbDXiyE<(@!!J0_@@lBw@LyFkJiF z0h#_sP~*z-xzowp=;6Pu70k)&ufi$i>oGBtS%c%kd=fL0n@~buEKj}$h252U)Io(b z4xOk>wFrDS5dy0?xw4Cvo8d}@OqwA6TxE1wxgChjXuvJvL|yDC_iL*v`+h-pJj9Ej zr`El$KF{(n@>G!#MR#2G2dY?oo_={iW~UE7A_)dG)B0@E ziY!%#$P+@M3~i6QKHu{l5)`EtSPkleTmzN%W$6}1$|`0wuLl9BaLU6B%KNRin_E3R z@l&|Ry13ixc0S*%u|zzCl+8BOUDJNpVWv|rcj@+yYZorhN`5|;r3)j+&uBiCWor?W zIZcI0$xPE^PtCnwf3TyWya_S%-HrR`W(;DDsILqOumYSKi|o)rgU)39+%14AL;HR7aFH+b#FK zmJAfreR0-){9U}nfW=9LeZ*Y5YOCt=+HdEV8&C}`iBUaR{0U2i138YRpB_Kr57d)h zxzfOxxOrdd!AA{EXCm`L+|j2*Ph}&@AAQLw211MZsrtkbeKFyB>=02yZ*KLjMQ4HZ z8*kG4n(IR?ozcd8JO+`{cG0V5D^-Wtz^8@x2LSVyP1$?ZS~hK~i&(?O7kr_(_?SV( zfq3^GqjqqVhH-TqxU}Q&fwr#LbFNxve8<2rtvbi_c+r8H+5QGZCn1j~&UTpRrTl@2 z;huKrBYlH(4F*VI=iNj;0Om}o1>Zz@lC-V>e*tlF*d_>pcNn95YF06dq)@GSH&7}M8wj6><$0;b-yMOEp&|s3{a~>8AVzX$u{yWZ)W5M zQnmlQioVUZ8yn-Kmpu4P?o3dm`qgo{jnWOpnYA6I2upQ?NBj zOEcH4y!71N~{HKYifsWezD<<0l!3h0VGI{HX7!A7!(ibVM zu(epIcN_o6c;!Ye`S?=dw8L4(*=~D8Tgor2qP`kDslqoT_FJ^*3;@^#cJCXXEhZTb@3yly9?If*cgOR?pFz zQK&do!v&bNn;QWVg8FhpDgpBO*_-?5eAuNQ6RhY#OduD{NJeU1lWX&#cd=S|aEO8d)xmS<#2j zd8;X_PN=1M!?~VQ$pT+AvQuSHC}bmaX;}(Y!SC|GAW- zVwe6i1@&dv{0ldVw2Qk71bi@(@~Q3eA1EU*`-gfXs0YTPy8S4cnx< z@>Tn9#CN|jc;@aQ%a6BIzV$Ey;UnJ$`A-Wn<&Fxy8=`-?sQKeUW>I*Mjs}BJxb+rO;BZo_7HZOF`Ab}PuvZey6>{} zfj(X_ittHCPkw@Y2;2M&uxJI=gUp#cHEvo^<9F=lr0?iIxL}{pFi-%+FHkj1qK5!@ z*wiS&Z=+zEiTK-gP6R?7w7HqfR7XSd`$RY;oyM9Sm~WUoyeBnC$fEEG85B&)qS;G>8DK`x%2T6vnu*S0RAW6a) z2_8@bD2NACnJ@)zQb%+M>ka_>^JuK`y$OGbf2=SOfCxbZ4{B@M6xkUS( z(>=X)MXJF3e}~=(lKnmOhMK`Fbc0~*<=ac2as$dj2`_Oz&MT#7X1;Wknx~xSImvIs zep@~zF{D@YL^eH9tmX`3)WhIwS1z`)$xr*2icL3K=J|XIo%gvaFT?YKg4ZNxg@Vf| z_m8=FH=1$xrmuwK&-Nau1y>1r=E$Jb5lRK30ho0{9|@R>k!Q|I*PvmHVoAq8P>QPp zx%MwmeQREy#-qN8$4#Sc9fe%piY*uA>J01RZbXStzad1uyPjyB4mp?(Il49dF&*`g z>=cwpK791+=5VZPb3){B1Y)?V)4i8H<#5C&P_I)&aMQ$R`c3{3*9nzg z^_65dFK$$D-#GjU&pW6_p-PRT3VwaQCGWJ(icbBP2~$Sv{;XQ2VMiG3)$SlP+{fyzwS8h2J$P zER+a1J$)|2q&5nbk{RcXnaI05$&d>b3=_GYn4g#qUFzs73#aPGgL%D4)%WO`?R2D% zRrqmGmt?pLiADTDK$86lyGM1VjXnVcJ#;?GWH|saLoZGN z5ZBl4rF=~#He{fBf0a_@vs=UKy@ykrhe8T328~rbLtUGtAfgfEFpa!QhE_rslVnEl z6Qwp_>GYXK+ZzFCYg>&59X@KxoafU^_ZV4c+s{t}+EeF)Z_S;3s{JY8 zE^sUG+6#Qsv=9REYsNTEg*28{f4=mD<)(#eYZmFjGvmX4>g7?IHEI|H^C1L(2}HnT zoj+n(mHt9b?2AO2V@lJXaIaLA;?MA++t-j{`SDl`AoJ)2-B$L6VboSHf#wJ*qH7%MTC;>Q|=+^!D*2$Tn)B2)13WOXq=U3lTLL0j3Y0$3k-zB>=(f+GF-z3bz?~n zwHE85Y%!!)Dc(RIcUW4b%#Wl2&Y<99(_6Ua3FW74O{01?28YGQs_Zi^OWv1>I+MbQ zvG761hwr??hrWNH+$I!1l6u!Xj`3a+9ERFFMX`VY(~m;L)CPA(8{hg{lVlXSZ)n@} z;{oq2bhc@l)1g3~6*8;(;c39$oZg!LOrhgbX0heYnro_Vgsdb4g*a2Qkow zZigXH&?DL)Kd`auXK8zAq(lqGiX8}&acbCJ^hzvQlbVARR^ffAuioYYQfIo$>gs6r-m3i!D%$o*3miM2o`GIVxE{Z2#L zrTS1r<0(TRQJRq_UT-dl4%OjpM0LvpBj?~$Oj9AzfU=Nb=>jWgKSvp@UQa6JgrzSG z4Iwoin+t#$lgOj!uyK;JVXGm)#GUB&>ET<(R1{vziY4^HsnYcffzOTZ$dO6 zFk|eHD}S4Fblv?|Rf~(Mo4%f{cYe0hY_#tinSv|txO`}iy9SD{xsskTh)o>x0?n_j z1V2OHJdwwf^|Wo(s%@f9)$6FX{kT{2MyKm7LAIEsM`%1 zZ@qVkXJV+ErzX%AQ#~skmxL=9?|a5EQeTV6NeE7+9@%VKl4w?U5T&V}!)zEgUe<}> zU7w-+x?Bu)xxLaweCB!?c@c}|1v&3~1Si=Od%J1<+ zBaH`aVJpz}GCA4nvy1U=F+k*P?ch%gL_T&2GFOQli0IRwNkGOapX(HuyJ5r@ z!h2zC#-s{qLNh8&*81Yg$zALw?fG`FF1NT6M8$yJmgI!zd-iB8=@};9==!^zK5N{p zCSeTb8u?ozndKBj1qd1=br#jU^C2w5Pb0l5&P^6z6r?iSD^>u7=@m#ZQJhHPCB-2+qRuPx$mc*s`taWuFt3HyjA;h8V(r02=@NS0S->h;F@A3>P;_lO8tbPHWUkW_U>+p3V640nOCKrAkZg|3kE>WmeBGnPhk z84;80?6>evT~Uh!T#iIE$!YurAR>@qeA}mn8FWF3rn(hrh&gnjDH&hI&SsakqI`^& zkHcNMLi}ecIrIFK0^Acs#&UU#myidu%nD+c96-l%9>OL3O{VMs&{k!Nk@idl+L=A# zpB_ML9Nw<~XX~z+pXiTKDvS51AXZ>?HIq)sK&YN4;*EY^shDN9$QhTRzD5FxQKwUs zl(xEL9%_{I8&pY!n?;0g+nhgJr0|fb%Bgk97Z;%>J`mrf&Me6iJ3&SU&|tdXqzA} z>q-WRY{bNsQN!T4T)Ap&{z?X8S%SdRDp%ns{T?(%lIvZN$@O#zQkM>@hUkKP=6z z+<1?OZ*-0`x$+ zIs1^YG)`s*oo0-Bi+XPtH6XK}0p(6y*WlxZ@*Hgp;omYZBU_}1kM*O0C&GMEDv+Av zN@Qk53CKjJIeF;@6W>#jFqkx5F1g~(?AMWu3xAJUnxXN%6PR~FsL?5qKy#+3gHX#SJU6|EUs0{nomR6-^Yj}5QVm$m&mz?HO2$(Z<_lF=!vGlASA(D@d{Z;x5u0F%K3dmP`IC#dz^VS#Oh&G%PJJbzLLW&iqHsSM^>3 zml{faDekXSmaAjk4pT^tX2+=t$mwL8z#m)K+h`WQ$&71Llrt*9%8pZJdnd@!5@A6m z$>F$xL|mJk0{S@WfsaXGJ&$kHg+6R4go5*YwC0#S;>}$J5UA-xHUzs6 zBr3F2Y&mlPrW8AL`Gf8uM~p({+@7~=&OgqF5&Qz9MONyyRD^BlLSH;SMtb-|Q!|`Arrf9>@i3@URh)tng((Bv9xOTo@TAp;U92^!Xtb#V+NFkbe2w7{q4VVH&@SxmwpJoNM~mCAb*j`3wd&@miZ}y1S8c~z zUoI9|WM40SDwQ<~RJXTc#3R|R0W4elB${I(*CcJqKiq~iKud=Fe3(tVs_QbnmTLL0 zP6^GtMRJ1FW{dB5vk%5AUpDKG2fNu3B-}F?#Wi<|31JGNM#ia1qgKJE@jyItVdfeL zEAYn0T*KAc>bgSbTNpL`2!0k|YZ3yB{j2Y21avxZGVv0w#gQxc(<2AKud~IJ(Vuhr zlm!`sf2G|vP94}rS4;$8L9))aov1Ki=5JdWDc+X-4y7E_aq2jPe^CcDxwUi}?jkbb zvCgi-T>{pLH6+WC&1b;^8w>H{5U*e0b$Le}(e#@>`^RdL!KeJScK!L8oj5|&zjMTi zSMdK(bO1k~8G{mmn?j@Z7*If9+zi-@RwYMFWy~hSk+fnwUoUCMK<8@-g>Q`zTgI|R z3k-v;4(uCm*u~=Zj$aW9U_P9rED=$qeM%$=Bvuf8;4nmV$Efh!Z>XJZwm2rfcQ|5Z zj1+^Cm{MQSXKb{3nIRlzlPL*pr#?+X%B#kDf_rfdOA#qD?f>&?w|Cs01WSs87N%Iq zG500`B3)xh$UOf=2g328JEt2!!5vYOjKu6zOdZq3G78;Zv$R&R1J*0|=}QM6XtR>L z;q#BQgMS*(1y%VHq!|_y6Rr2O1Tb!*`dY4dX_j}=2hZ)H9pMX_U})MXF4BS)fXE>p z+0PNbKV;c$=r1==y9n0T$g$%QUGTV1u|0f9V=R5EPC!yBT&fwmr=hDD$Ppv8liSbhpiwZ(|9D!t&Q%z;~R zq1kE@*-9+#?2pB7rSX4^8ceeG#uGfR->S$9e+R-Jttbb*^9VI0luGYanIL2#cP@R7 zg-btD!YP;mNt*v~u9$lT2Fvg)W(63#&nQg*z&0jL21?8-LOp|K@o_FlEyjx({CrhZLL}oCQXw^E#b4>!I zGKwh5z%XDajO>%YJ(Orp1wZI-86U4jMVHpdluZlrpSO)c5vZ)CBvL>2hgHe^j5Oi- zNGMXCfl)X#0eb$Kl+M!G?$_9Z7B&7&SePG?tBDrmlQ!8Xj(yC!SiDY@@RT#z%OmUm zc>!^P*}vHtA=N;>H3NPDjhjY}abNaIlbr`NLZifDa{YANtEvo!wo80gh0JS351?Ym;q{jD0bmJYutPGK};TLd)D~ zIYOPRVvzj)6E()=3yMRC8mzoQKHJ1ZisMU`*jq%3g5qF1HLoU@H=r@lKQ58O?3T=m zYK86EZlbw#G=AmnbvP)$~v68vZC+62nfM_jhqh|ZXL920SsN9=V+(Oe; z#^K0v-J+WnIGjr@EjO=vIUBp7q62>#0(!o(Y7G#tp*_F?x`<12r^0KvkA`Tdjbf76 z=XLrKON50Gkm$^w@G%`w4ZDT@*{u$mLhi9;`X!`^T_T2|i)hoZ6o_PC8z$j-Q2)mA zd%Y7apnC36eeVr*N?5T0^c<7WH(<5|bu2zVE{<4U- znx+?G%!@DmS_*94SHhlAv{qH{&AAh!F4TZl4R5cHZdqd0kqKn2P)FhVbC_@edrfTy z54s$~E>x~dPt3H6Ih50#g=s&pTy{*%ILH9vI|CW2YHY%4IUwEmo5D4SyN!!}DsVyH zA;@seIloRa5>Yw^YCsC1$Jm`rb?Qf|3Z%@hQ*Z3G>U>53uiRW3Rf-=7hd+S1j+cgB zPh<74K-U2>up@zecBc%3(|ToUlW}N8wb5N49J;N_V31^l>ekaKaWu_p50Bdlb1<}~3ygRh&H(zW3W_}~$WvR#_QM&J-oKiwQl_K%JaHjz+t)>x>@ z$wjAi>+f#8`SLd_<+cpy>^GaAD&P_B)?KA3-U06^Hq$-{?<(&pUCN(iDWlMdd)o|@ ziRJqk@o4ewCg5lB3Qx zb@O<4j)U6{`Rd*(o7@8JPJNK4>(O+P;pffi9#UwFZdJXAZNiPtr8PyBe)DWfF>PZ? zNXS(Eu6<4mc^Ma+)L!mOnyisv{As$0d4NRgk8k_qWiskk*v2$UbxG^=RX0;(y>|#P zimfYhk+vO9TcZ6lsM;dqDhX%mh;%Dvg{U=j66=#midQDTIQgjW0(Q-=nT9`CtV6W# ztxRcngiVQc1^RvA;y;suQdG^-1+M=Q-}-QYRgzb3{qA)#+A;wJ!Vh)Z@)QTqMc5PC zHpX5C)o`wm#%YnoQ1PK|&j+$P-;dzRDBO#5!}hkE&=ZhbkpU1mkue+1&5@jEwQ; zY%LH-kF8lb!l{~63^=vDfuWLESzz3cN%R+Xl9`K~{+C@Vx6#=q$d*wyMaTxAX^bC! zh1}l6f`2N+hJ=^wQsC-7#3Zs#K9%^07~*)>fP@$v{;APkY!A&%?J zL%q~|9+S3W6nPKmrEaVxl@!O-N$Q8Z(NvO;*78A3y@%0mR6Bt;ViQE+YT3cxEVsu$ zxRKyqSi2)RhnM=YD#XwYa18vIRL8h0K20JvQ9N^zfBiV8c35cSe>#HRnBqdq^%Lhe z>MNUG3Y;Q2&QqO=&k2up8FJFdP}t@0eLjI{xLf6f+WWKix$3EJ;?BAnkkw$znALNW%S3btk4KvXIuWSD&o_uOXFwj(SsTR~j zJ4J=+#uPFl(rA)=o?apv>LB%g=BSsk(Al~XL3Cf-AL0ScsYrGhy`>d4+40`wuqzcC zH;|A(2=4yNik2fArjS=}5Cokqi;~fsrR$;&;vHOlMr?Kk%qz$01VnwKoo9k*;04Xh zgT_!MuO|3swNV@O{c#?pm41b4o+YQr8x^ltM~l)ir)dHYM5^nyhXSh8rFVYmz|i-X z653}i<}OtBvx1qU>r!K44Xb3wC_>JPqTC#2M*AU@hBVLnj-`TkpLoiO>V~E(hG}he z`Z@;(9F5u)+?oKrxJ-i7YAy0!XGirUjcIl%aT6$A32qYzje}@P(fhvugSmItZaL%T zD+&9)<)0K_S>shXNQU^*1x&r_lVqkWjN%uBFG6ofj}ZGce0E5f-#9%Fgy2|M5r0g~ z(P$XSX+TNmk5C_&!}ACymZ4|D-X^Zz;_Q6{Hr9KQvmd^j!2GCn_Qs1)R^;>jAlC;I zG!aBvP4}Pg>5*$6i9ET^G%FZr(d$3MhWO#ze%CCNZ6z8)SNcPF@B7J1IvXV-RO%rV zhM`I{QAR*qu?{n+8~j8i@}FFB9&k)?O_el>q?N9sOq~?3NcSGwEk{!c-jYnRu{UWA zesJxyjidswAc=M|6i^O&Brc@i$JGI=g|lrrY`~i&D&Ca1?=$J<1hf;fyR=)NBwa6P z(@rVG?P7HEWjR_#J@+l;Ga9=zwMA=J&?IL;(eK5)c?Ip11?@iN4SS4PL-L~D7`V~U zCda$)I^H{{HzPsPzXcTb->7CT&Lv{^VpTs$A7`}P#A1_Xw${*>g#sSnP%4iQ1$BuY zXS*&#!g?QN${TLr!oa|Ck*4u0OCDp;DWxGq!6w~b#Ybn!eZmqM@zIL&8IsRMNMMBL z#v2VqMR1d-muS6}-U8TkxnV{wy zT!?BZ$`wukpR$Nw50HOD^BidPZGwD+I@@43yB;1Qat;`m&0{0Ld~P6LFT%-R9gULU z($&SoFZ%VF1w~1sAr=Nr+Mgkyd-U4vsYF`0oM0RX(R$2)NCWVbVvA84BV7E%9uP^J z=P+j6Qxy>47)u?uavn<3@$7?B)+Q~?S9a!xF5p3%o1EIh3Butrq=(fVM|#OEOK8Sj z8sqwv)d?BibYEm-V_y!*ht>LRL|AoA#sBOAt^Fj2R0up7p~RwSYVk~3o9OL> zAU=$jU4RXPux?rtN2O!Fi(-~JY5zQ7vM5}>KcqdHQZ`|ktbC5H;Mvr>rZ4)cIk;k7 zL~=6=4Xz$~qt~BHn3Oak-;`m;?Y$>p`EiS}{}+%#^#|lxbg0+)XoK&3f8GS(7Mq5dE)8=PV)U-A#At20D!` z7PR_m>83#q=Xy3X0)}su=EuDoolM80Rmq*rN$LquPT0&25sthuJ;)D~At;(;ezt;f z^e-I(qntNPNdtvm2QSS8vE~jeNloK|HStss0zr-`g5{TFm`k2A-yp&*Q>h`Q($_jG zgmtAe3wNIsX|=0xZjzap8n`gsRR^zZF)(*5e$Y&7bcT{&yH%yEGAL%Ovpxq0qo%-l zBC|io;)M)_oSl17A;N$TI?J(tWF}7&n}8u`lwyx2A8)~hXE}}Ahi}ILj>)Q!L+mGu zPr=PiOEa}gBh0w}XOklUWoK{wER1Dd^p*#+b;r@ddWJB=GX9SJzcXWnV%%6y` zCw9E)YfCsAdnMPg!khR^Dr&Qu{T=J~j0=pMzY8|*v*a1Leg*Er^(ryr5a`sBNJ0%s zZ5Uq@?XOMbr~L(x3K`e*Go=wK6aaY2d-YKT3o4H@#ZP7!@MF+rL4X)|R$r6`Ym#g= zp1SS2*~M$SC_7YQFa16AQRjL-L|JIqeiyXJh;E9ucQ@kRZk$yFLo?LZo-EWsaCBD4 z>tEN=L2eu0ZGO2g-JKUp`))Q9jPR77Y zdh-;b1uP_4nO7|f+XoCKwCZ^FRV+j5VKagaMh%AOl{9iv7Ys1bwYo;yEtDD24&b`V zB@^)M;#Clb#9a^}!Aon*iO<{1e9(?pftO3k*93025AysRMJRU1%(q916()s1Z*keQ zBv^o+u=hm!94sGiDK^~z8k*9E(26o-I)}dttq~%9r8are(tgZ7&fJgWrpF&dWH9#B zS;3_v`Pqim7T<|WgEI*>NhEQVa^6(QRrqb;!iq?HZqU;AV+Rf)t7@B{eBzZ6PgTuT zcV^Yc`#DW}P9W>k0RzutRKI`FydUgA2kOB(%6RSWQ;gi?lMTZX41Gahgd&j|F47;b zZ#a>r&{!6D|Li*_J0}W6xYc?Uz7|_Nleda?DDR3fEUSpP8ZIdhrux2U;bB*h9!sya zfvQxFu~%Rd-ky(gQdW`Ls%zY!OPlo$IBTCVQE@c2Frt|2>IK>2Gaj8+cR!LU%(fTC zaB8;O6MD*}!rGSU?;;NeTNJyvhH;s(Uc+K-GYM_AQ z%hfhBsB(CT)DM57zR5yEL&wyc5ucc6g(PZDK_cM1;G>?mImF3*ehMdITvQ)A+EiX} zhZ2yLIMmp;@<;?gp(!>G7aJ0`GMGB8ses9-+mM=*s{TfeHpy)2dlNOn1Rtt!YIO$F zM!i9nAkqlc&0_sX@+p24eCn$2{OX}G)W3k!9Z7gj7isF@0#gJ;TU?7TsKU1*fzk?e z2&;NCp6B}nym26^OI~V1RKBwu@?0VxXj-Yffw#Ez#nd%24PJHW_CiUxeVWIt}J zBK+q2h1hM>7$5+$#f+)4UDS)P3to)f>*G_pYvmuIjcT}IK5xEh}gB6!KV^%p-zF{gT{#&^gl$i{4Yh8q-CAuX! zntX}jckBx5I#3nyOap3cRRinChGV3vDxuHO8%<`c$Edo~W=P0Q{w=_w90~C0?1|BYtj#?g1Js+fGSWM&PxBd*RX{Dt;NA9#vq+F7G(G zbhDiPT$$QtG~5>=-yYoCkP6DAhjy6s;zdS1eHJm<2zUlAv_9=*&{q|lr2zt{Eo-TW zgq6BFuIG*vapd{13ts*UfKHA(apg=y?)09i0}aUkNCw}k2^mOag*Avb4+_w*gChM+ zp4&J0p2uGC>y75Q=@s=&0ym0ofYTIldPm%u;J+fVV!N zT23h_&dwH;!&emQX>`7ZsPRo4vJPsN?H=49EMD0x_JSE$UyI-3>$2e@XwkucAtlZ`z)ASjk`5*}%a6U*z>=Ax@i0oBvrGo)9S;(q?^`rI@ zb8x69Gk(8%R5w9*XUZmu_Q#v7wYcmCok+IBq&6&i$5DQN$M1bd!r5Kc`E zEKN98;oy>CdGm)=q=&+uY3l8~EtG8-rFo^IYw-Rq1T%=tbc#d2bi-PZHwMr?feZzS zpWx&?WbVtxk=^8yk-wUz7H5j&WVN{dygu6!s5|TW_PM?M;>}W4K1Sy%t9ntybNMr# zWM+nJ>g#oYU*PQo%HBq{sezAgQ=0SRc#o$MlLhBMS*qEs>@sJ_wf7EEEO(gIb9|eB zy9`#S_DG|qscE_$#8RZu&PQGLnc%VH$JgXzXkdC<-p+iSq`Fe1k-Al+WqB%$sbyOP zRqxd_sd`}}-<~mX3d+uEZIo7sD4+jFcRIPvE8G-MV-YOzknh7Q zQfE7V(DS>0`ob9K=+S+%baY-JfQd|8YxCXhSxEDJmqw3se2NJcOv48YgzyNVnTT#s z4=OnG4q52eV7?7&z8WF!eTwZTzDTN5%E3!$>(UPYP{Ee=tk`b$_s(pwdq}%jkTj01 z&?5(YQD6F!b>o}x?*l)Q(2t^M!2SP-bYUX+d6<5y+yK}#3~5?7M}aU$sbT+$S~ZOz z0ws&HM|nziXYeX=_vaZd;M)ZtsamvptREauW>n`4>IzD#EvjhF56t2>R>k$|3Tf+y z`UU4GGU(G*KSyi!I+n}CF=vol*0Qw9&1k1V7#&owByDH&VdigUtJ`rZ`J2lY%=DrOImsv%y!wo+~&1rky?Rrj8t&Xkx zNe6Es=mNzCdK6jC7to!}be||cQt?My*VZ{)N=F({p-MY%QXSXT&*MFTMW6x_%uc|D zf6c?*a(W*lqT}4lk<@AkSOXoEbt0M9$=&GBoqly-P;#*A$Sp?qfBMldtL3D!H?h9@ zDv?gs9R=jcC6c}TH#&LIT~lmhVIi5Jn~P~g{}qMlXJ0+9`9RQE|npNY`5nv zopFD|??8KE0fYY|9-^Vx??1NRng1N9)5u95fRX8si3veksuiNFo`myU$b4zvb&g&; z^VR25cv=~r$40{ownkadw+o4am8BBHz-L1Bj1n-ZJ`;&!C$XaqKHriqSzl}$Sl8NA zpPl&4JI^Q2JN%1~fpqjK#43~LztTD({rvmgn><~Kkft%K;gNpq)q)zNe4FAgfavsF zuTG1POdvXbJ-tZ`tA3<3tr8%jtQMlksEJ@?Pil@%su4Cifll++IOjGQ8|xt&ljEcb z#mkPh+8Np#^LF@mTxV?I=1e`@?#ZnpLs1sp%zJ}6ZQ(Mn%5~vs!1Mfx4j3hB(Y{n zu13s3%ZWUM$gWOLrWD7I_%-%a1TG$GKScua*{u>}@xOqlS!m#^AlCBl zmegL%u`w@>BxGLtoWmf^QFaA7EA#)5v4cqK$E3sYPp2MKY7j@)Z?H`sy^y@I#o0-wlwS46*K} zoA6}_kP#r}>Khi4PH^~LF(h@XTqKY_u1FH-6IsRwL76%SO z*-p@>Y*0bgZOTJWyqft74i|WpogJf;1PLsE6*pI0o@4tXYC3P>S zErE}z2=5&ZP}@(=L$F?jHh|Xw0PZp#Cp+2eJxQBMAoxXFx6sKu{ABCGq*^ zX`xRL9%oOtMC-}&Np#~5fBp+E^UsQ}*SHIRsBNnf{~9$-ftEW~{`?ok8k6W(5kDdF zf}p)^L>~w`8QcFknALg0NG3i44~YS2KzA23UHdPJd#)VI?&*C}`CuCyHY)*#~MNOFF64!OkcW3M!Ddp z2P{MQBbtNoFM_AiO3R{4lZ%O|N!~`Q|J=vw|FhuRfR|XTZw=6*V@x>gd!TlNdjBFg zUBu3T0(qba{pPXhqV5q%|6g(ft6)-36*#BVAH&f*z@%{ z%!leAtNgRzYg76JO0X>?R68?uc39oHe5ZdAY=j8mXX!TFQ=d`@$4^X|^z_epIYpr6 zQaTIg1qu@d)#wEI6Sw*=;Gd)WnB`Ro_x=KWx#G_@lq>vMbJhP@@?Bm&7KcV7Mq#f; zqSF8XcQoZ+B!80Z%xfL{c18s2@)FW~1R?#ih$+yM(@&tZXh+!z_Ewk1-b>}xKL>YT zOYTJ3mm$r@!7LQBa67&I+jDp4V02GFpY8@JG@7{DFf+XN@h^%CG89PoI*O}p8n>R6 zoF_1m+W$G2tIRQsL%lbw3=5EIOpn{zw)M}7r#!-C{~U}$wY}pUvBO7ha6PQ5 zAKY90k7>+wH*i_VbvbgB?Yb-vC*&pfjm;?P|NZW6qnNId?*VpcdF;0tN+GuWF%uG0 zbE5wcJc&&eN6irwbb!**6MZj}@JK667yB>S_W%8#zS=XXQU0er6B6{x&l}`FrjY;J zo~dXTms>mI*Mq!see-`%6-eeCTa<|7qtIyM_RvfCu)A+ zM_T_2Nd1_+%6-e45`CgtJNDjLx)*flI`%&Dnf{;euSB1CKSM5kYCfhOiCVq@X$g-* z$L9~XZZFqHO2v%sGbq~7cM(x?B6~ZEe4Yw-@II?1MFNH4Y2kO6R!TopImc@lc78AOy<1-oVi8b5|Jdo3V{ zvd6YtJ-h6VlgWGMsH)tc#=jhJph*?e6GgiE3m^`uqnA?+5Szd&hbA$oG7=6wpBZ8p z*N^Ozxa(;8_0|rxeqan4q!H6)q(Ul>AeVq#4;YXyioiC;U)f$!OYu)-LvVO@*<$np zzsZt560zKXi_vJna;_TZx{LYy(-&g3HAfbJMlomO!!st}g!~NKR4xNe5FESvuPC|- zoUk*9yy*HVc3DY722#o~T2_mS0q^VM#B@Uhv@fq^8rktC#84ClULV11h?#>o-;H@j z5^i2*7L{C?RO8_IIq(ch#kVk?a6E78? zRZ;?UDglFnyu08^K!3{r`1YeO-GAWRsAHhfB*}>}4@TZyCZYC(YbLQ7A&r8hPHp`? z{wjXy#$a9;(Ot6b4inA}%%7jaAoFXFBmkE`_QcvRZU?r4H&Khfb&Y|Kdlz9`)um{Y z)&Vz;-x_xYb^&*QT6A|lk%OGGE)#%~IU=0ShkbhcG0v2)WVMo%Xa~UYW$-@;7LPH` z#nzoW)oKmUkwBe;?~}S@2Myp1oi`1;_4dTy0A}xW7q|r<_{&BG%@G{|d`|i?QD8-qX5;IPNn^^abdx*HzjJT71pxC>Zt0xAQ2&r5+uUew1 zl^B%fL}LD}k@v7?#UVRQ!Yi_aE6tVmT+psd+9ye<#4bug zKeW>1PYMn{9*J@8(z<|ulzOVIMrQLRLlt%>sp;z&S(=#WG3lwc?rG-^FT#stkZSE2 z^g(fehvwQ7zS?)Qw+HY(*feu*ibqlFoZ#j_SkoNNjKO@X8(9*$7LdlK2(!WgHTb87Ixdquk$)OG^LU>3(7YXy$0>LvJ0`S)5;w6tu$WnI5T2g@ zh=$_fP5QxMlhemvM@Og*1Wp4vcg9}m1WD7|1Cu+ZgT-XwnL5sd_l`mbYhNfJD24>= ziQ)cewva~-Hy|=$JQ)&ooQBG<*pPe>zVY%GFS==83`ZZZXDG7{Rs@{0N29y>W8hE2 z`0gF7^VmoEGf+mhejM@%#ew;&j~dUnAHSOu633XS`45gNqHwTgj zDKd&mY}&3hes0hx)~t^Ir%@pwt;tONQ|9nmpZXxn7j~f+2m50TRdK5iCB3%xHfg={ zeK^w2Dq*;ldx1!daCzvDhFjnmljumm8jw} zg#zSR0&|N8Ihd)g-vwQhUKVzvsF1I?y&U)uvSL&-Ndv_)bz2%1GUs>!4m!v1O@3+# zgd3XHD>5wEGkMRHfA|KrONoryq%mG+#{4(;8F4+=6gr*KWa8CTj2Y@#^*zN`WFcwa z7MpCmQRaij?8jdcWnFxuIBWXNj(nbY%@@qmM1q$;ZO%YT1CCIbE}QV!fJz`j0|V$3 zh5$zfer$JXLaD}PSmemPR4nnGpwO;^(ChXUA)S|+J*Y`$p=;G48FW0MKOhg`6$t#+ zIvfij=3~}{c#$HAzaUT1(<$y?8Qsd?M;q|<4=EPULRc0j%rYg~EhcUV6&&FR#5{ha z3G#_yB`Q0nx-xWc*l}XJ$;36ys^1H?NLM%sHuDPcAEU2W)-ygav*k!f&nZ#i>bJ|P zvOE|1B=)xY!Ua411t?q+m%IDeVNn+JlRPIK^I_%fyd*leWsuAOt)o197ZGZyfqq!1 zx?~r&YA9yEMwQa?C>v3Zf^{$?{dZR&zF(cyQSFK92Wx`OLf0hLsQW))!*ZtwW7IOX zE2~NRoT8#;y~#d~atJVhb}aR2T-m26$MmU#=Y&tR>=k&bC1J5D)s_zl&a3q}Ic15{ zg_o72N4nS?>HwT0py8R68jf%*87GZgDwKr0fyLXo`6_@Y!nyE$bZLpLP}?ByLZ)fq z;IGPNR?;@wRZ?Vp=aOS_RpF#FaCh}pm5Kr#mKdf00h~mgOGXZwFCNZL%{)*Q%d8(` zyG&{ZX-;u%s$E0gD~}9T0J@&!&`7a9%)Jb=>7D5gTJ0qHVNu{lz*V!Q}+pll$k*K`z#)lJ+KLjDfK zMFJPveT-8eD=#M}QpNj=vI(2C&IFG?^->DEh~*Oqrb~QaaXCnL8>X%JsUls75_yh-_|C(DdC<3--%a zGg8w!Pb@hVanEu8Gr#SR2nY*5JTOKe5L!u|< z@+U*TrbB2%J}e)~8|7ROi*f^!rX6U%jLul}NYC7RDSj?u4xY13F!PqgRIdXwo z7ExyBxq)8B-I5>pv1i+(unVFUk6BNDuK0`Hm=?C-rkF@WR8r^FEYlcw=skannJ?7H z(ekFEQ54a%t66?RJwtth?tLxDX#QtG2L8p&0RMWy_rD7=VK+D5am6yX= zNR=Vmqot+GE!;CCYFA!dQb$tP2uUu6E5|60#7fvL-&C`lZi<_y4ymXJ;)rBHby#dD z3@8s-52?X3K3;m;4=VD=UYbjk)on9mQi*uteu?a`mi)T=chr!1@offD47`#c)wYV- zM&+^V{#GD#cyUJXVf0M549*^!n(Pdmti%wW)OrF0CLHQ5GeHh?G}5=36?Zp51>bx- zDL*Q06>ttA44|*XDtW(phY&MEDkN#?_WFNAuc4TslO zDVC@47X?sRTCq9n{Z^O@2~a;l-eyXojk2btrb8Aqq=n~NV51m9(EYmlu<$s%+*JUz z;eduv=QJJ7D7b2DZsgToZf2X*;b*!%jir^le=e8hc?T1~e0R?e)}eS)Jh%C58*Y?= zxR1(;Ql`J*Sq2J{gb~ku%;fXZ;MYr-{Z}+H%fkSzAKW+?sr03(lUVseuayW|uij2d zJ3{fi@|dl>2KO>6h^6^?2MX$arbsAsF(&EQ{Eu8q`y0-F2wNGfz}q}Tgj>+o;1ZQZ zXhor+JTGoGXMLI?6J_G#5WkXKBeOmgghYv>Mn|bheQ;ITb@g>e#WY`}=C{~sUTRck zhB!b2^-+JRison9koFt^3|z(jqPHfUm)blKVg*4OoOu?AlyFn3sEY)TOj=$$w<`{Y z0CHXkNJ1C@1NJd~|5fsUd{&nSmq+C(7NgU;FvLj|E!Yzj|9}9IBe!1pCA}+%-98B~87-01O$3CKS6Jse zQ0!TYX$HczQ&pKB%-aflPln((pp%J$y)63Wowuy!gDg!l5_;Z|q-3~)OsmLvPuzuR zBm!1agob|>y8bG|mROJ|EwjojdV=jC^Tq2&D}*nYSy2P6GH5nDeV+_?iUNaOA@M$8FizBM*tS<4bNve+c1mDm!i#!d8Yf27a z@@tP9K#gx`G~rV1RBWT06BymbB0c40De4 zuQXyuZ@xUR0a;Zu>L=?L#w;2`o?v%YGGd3qkW$N|rKt(3bJAQ=q;~WsN1FX&bo-_K z2J@Kk)jO!xnE$a58ot+4A;gCJ7B;~EZ9U?h2lSwaVLnA?c7!X{gW1#JWLYe*PEF3k z07vaKMXgRnuWZq0dTkYh1TJ&=9*hHLWM@`1F=&!h=*YB0XlTP}V_SAbc~Q_fzt{PM35mDM z$cT@Pf4?5!HbR#U*A5@JR5MjatZ+?=knqmw5L9AEx`6AtAxNpq8D%3sXi>l)-x0~%Y?V%eBl#}LBTckQ zD^=1guOQ<;9agMEWEAyz_=VXhsZ{%_nmBo$-J%nks{jYw;Zkdq7J1KuLk=k>)}Mhp ze@HV9N7rrin5k182b-S{boGNKsSBKU=O&i5i_uq%SFA&rKj0{^O1Dcd=%~>0&uxHz z9gqV4gGHkGFBSM-^?UX1eOSXr)tlt^zX<<}Ka>wTq*BA&JHFyX16>uv7fviD0<`(-4SUAIeFTZ>I!i zdUjr<^M3)1p&i9XpSH=2F)w{VUlrVu5~54@126D4pAO>;KC&(}J54v-FdiSw9h5Kg zU3yO^{&vSiMVhixN6K04bA9)|`(3|_a87&%A$xEB0LR!=m(z z^bAJ)oc}qJ771a$BtTBp`WQ__))0iB3lC^+#3HV3Z!t18XfIUO93$cyB+~G+%82WI zK@l9FJD01`7glgJu~w=UeL@ZRxv{?EE8q={iL1N09jlzvzQk-E*olndNI$P?cZ5t= zKcpPz9sg(4uSjuPfNbMWI^4`hT5Of#_G(m@x$eZE6P>Vp{m1A+`S^*K!llO9;cPd0 zJGf*PNOZs5{&UCx!u~uHuM=lg9we21h0+o)S)y$Ee+r|8{ITY!%3ebA0juQ!c48uQ zRT5`m!lrgMhDzLf+9D-30pP0g;3-;E0w&-RpQge}crC&^LqpGnpMlaY>O_HPP?4!= zT>SYInWl>NRCfK0WvqC9Vs(RHS2$pMsUp$MiD0Ts>X@6rg4PnhpV7e=*Cz|3Oii$~T1?lzC%r~P5^LH?mWC;28lFvb^5xL?+|Y!N zbHckQ2?{viKzY=GNT=Y75RCIQAB74ano8qz93n(Oa8jA)0WpVVcmgNza=t;Jg{fXxuJ2;ac} z$Ifv+uk}#PUqE=-hOw`u%i9}T2JV^v(h6oicc9!Psm_E5 zj^Ev(er*ge1OI`}kKA-I1c%w@5y%UGCWlp{-{Y&XUx9)W%3J0FLz`A2*k6~U>N2;> z7|3fUC2}(b$={bf5`r52ENTVees=XSQNd6ZvUv+8lz}-CU zSr7W~(fmWA?050i1rmVX*=ZO2k9smiXMP%bsM|zeDvfg`ErhoLX5M+3mj-C!PwtOH z6tY?c4Yk26hNa)z=N4ngm#(_BZLU+=esIuwZ z!QqX7D=(#8BpeY7F0pQ&{{>K99izw}DwwQT^KT1_w1&3UN(UiqbCX&{54~bt5y9D) z|3ncd&8N584$H=)l~aU%>qlohA>N#7!b{^?1|2NdOAW(gDBphaVLC5YQHlAM(`z{( ziUreK$%p4I>f_JtrJW{{eE%`Mqqua*w6};8ZUf-U-7;%|_vMmU;BZr5=a0u7=00S( zEFaf`V84Url(%Vyg%C>+xgF&k{Ayri9arSi9bL9NG?_pMI)U`g-pw+u5EjMu3Izca zcf16XmM1|c!n>Xl)3*66 zQ}y%!ICE^?5U2(yh!$-@2aNB+#q?g8S9YLW(X-q8xyYD^3Gr-3uuUg>Q>c9iTp*(a zj~?BsoE}Q;^gHw3fv#zwZ!&#J*g+Ro4@sJ1L!odGD93f1{|^AEKvutQ4pvn{tPD4D z<4(-6&dvca$y#c^#Zx8MO~?h$=n!0hCAqQAfx!8X3yW$}x@mVdQEyWFRrfFuGatOg zKpvjrR?sb#n#0L(rHr@5tF-YIjKG6oH9Jr~qsbJ-7{sJ?9i`pd{{XO(x;SCYA7?VX zrY*%Vz==vMPDJV>M2|Dsq>IeuZ$M)Pr9G6#qQ2Re%2CTdt# z@VbRDWtCWo##T7d>cE#O>D*v4WAPh(QN(sA;_Eg3DUcU15xjmVNE8ok#FFp_1u~mV zm0=dN`jH`cJ9vfUnYGYA*Du)Z<;!aR#MmCL*GEU*Fj<=7Cegdy%Uwds?OtJ=%Xp6c zCvx!#FVkqQw3up!6TMpy}w_6UMh6lcROdhbEkhE80L`p>6lAvlZ9oPrVuq8|2 zxohe<+%~q_+lhuiDzgnaJz|h7CfC#KeVK$!cmc{C_Ir@MLh=d#La@Z=1xgCbiGkiF zogU;GEW1TqVU-f?9wi)$`G9l+JrVtXifF{j0_b31VV;qtT;wGMY3^eb?x{^MpD0~S zZqcRITe|iL?AbhrL)YJO&~6<@@X^ZLSh{rFv4}dkNUZw7K}>Zo2rh7>;Cq%5yey=+ zz}t6@<{jEGIlMep92==%B9}{-66?k_&W4?u*|}$%2!i?1$_~qhdK+x+hEp|DKnoJa z3mf)*GD5c*}k(OD8t4;dj{8i71o0(HraHDwY z3IWNmi5XGJUw+|e5CX4w!DSjh8G2CeQ*f_DLO2d8CBdwqrYZ;!z3y1LRrMWoSQm zn|AP5((WoHvJgvf`p2X-tiGN+@u(m{M*ulPzRz-HxM3Mlts5|g2O@GuWn)FFv&T=f zD%eozhS1^Np5%4vu+CRZ2KQp~6}fR(NCo8TkPX%ExkUx4^DJ+737JM1!_|df;(`Uz zFg}H&^oqf2Ow<6-O6E4k!PEd+^_LMS!OpO4l>Y#dB8Q|^3z7)qe8$Hn3BZWma~zvs z+)dU5b0A~MJlWVAy7CWW^lSrnX!WjjxxYiYemjR``|f*e6NjJof0IycNg?Hxd{bh3D0>roF5 zl@Axbr9r3G5X=POES|p+MnO`p)+!@@)m+Jqxi_kd>V&=#iJ;;F8+lH61O#5-e33pR|Bd^)3Q}(q+PAr>IhsXpQI`bjKxz0zzy9g z@rl$`oAHaAtY|VXEXo{r3#(vrTZlBZ@hGf%NsCq_s+MVOLKjVr2= zo*aQ@7oKR;T0Sq*8@5Kx`S_=ZR;X0GmEYM1OU8L>j8;tW7(DlK;kBtBp6dhnWRxx zq%V0(^9!M>G!9}AKX?JV_Ns*%y^_cX{ZK=GpoS&3D}2WSkg=3%lbE2wsmko})9mpC zg`Aiiq2Fh@Er&*B^)<0XQo!tdN_A{D*5}iw*?@SU=aBESh<9ERn1yklZyMiTQb8{e9#CVHDx0^6H4;2)V zNH)ID9(|aBR8Zh@fyv44LCq5c<@uEL5-ozXkm1~gzSpNuvlmn-FnI^u;$95W?R3N) z{iakZoq9o&Xs)pT0E%FaSz)2m?U1cDa>p5Z7~?@f423GC9wQ#e*y_CfF-kC+A*^h2 z!DOzWAhXJ{sc)Oq(e`}Ga-%i%lrj~Y=4S?dB{cvKQL-jY6Tj54>5h0FatOwek5tP3B5}&jb8^-wE)!J@napeN~vU@Ut!qijW*D`s9N)?9j z3Zbq8GaCtA%h_9$6;h|rwFV7V>g6Ut`oyTQA|;6M$~vNZUHWwUJVixHI1|brbKH(% z@yhyO;DUi+$o53_Mz+@cbo(%BpbiP-KIafl4i&Z2Dj=ZZyh1vxuO`iTuklt>WF>85 z^+F&FuHb;SV_nKLcEib|GTAvr{9^bW?~DcrUBJ?`$>LFCY}C9t2H9IPE?zk`J+8?f za$Y%x^h8>m07AasF61@K82P|x27rjtkBuSA@fOf`wH?>@H97C{QRQIFf~6o0Cxcaf zkGvNkI3cT8eq~%H$aQ@Cn3lAka?hNSzcBV)}$jTk@$gVmKRbRE=n zSTE)jHsBydTk;S_fK&?u#X@yQyC&=K`!LHw>kKS8@kuV zDa*gpDLT7xEuptqnC}(bskXVfQBQH&mRWbG?@Q;*eoAB%;-Cw#%fY(-5lZkN2WtwZ zS~k4pivIw_vD%c+Rx)h+%KR-2WI8ToI>vjWonz`-=@P=TuA*n*04E|tfl-+6V?*W! zPFKk0C<9fP=U*e<$m=v+ApA;>RBC30`J2$ZvWQi)he3!qbv}gRDhPnK*hDFhXtNE~ z`SqQ^A87~-=O?^8p-2no74?b*s}}iyVc+V7VaGIIam^Yj55M@T+f_-j^&vsA#`+SH z#vy@qiA93m7>Kde$9x!luoqgUImR2S6~^VFo5Grm1NVhO;hSvtnQ2#us0TbtOHdXA zo$NUC8IKa646L?5ZZtVhmXCQ<_Z-S0Qk7XU&Qkb>Qy|nf=bgb9>^PeY@=6mELbyb@ zvH0`Q7IZc30tsfXP=rJb-A4LYGFywX0}#DpGUlS;5x+0la(%#;ax)TXiivz7o4vXHR>0oqz{rQjVnp|AL5Ho zafmHHSt_Jj>v6cz>l6#mY|VhjjLzY(_`@csx6=c3Ze|%fs2zgnzYv!N^Lv(z1}6Yg zqQs~Y`P1k@I%1%psBTa-;MbNAaR%@pymz@_C{eVJ4UFn_Jd8^=3S#--WB7)^p%ms zcQMCAKxr^Q(Bc=HaBVfi?~l*;qPGH`A()FZd_v6%YjTd-D|HLhyW*u{luidi=bUG# zm#=IR#a%EJ=;~4cBetU4o#@OeHSYq2-f%^rc=Kux!3;PN%3cp>Vyds1MXPXJ+ca>+ zl(ia_2k8|6`oX(_i15KNYSh;kFHX(~h*t1LYnlRG61@6GGiPK)K>N^U{s~{R#a;;? zkd3mqsBGl+@eQ_&LPWPW0JX8*%Zqq7DHoiz?=5$2eUry`EjwR{fQB;n6(S@ybW;S# zh(&t8;)*3r@CrpgiV`E<8HD4UOfhGn1_zjKZ3iC6cKPG&hLBWXLh*uERg0ZO1~Zsd zE+C4`)*}c@x7l^|ih;!i3O`roErExa!Vs+ihFqgLIE7df5Q(+Es}pdZh!o24c3Jmj ziYgsLst2`YtwFw`rIkcN4BRS~80AE-%v#X0OREwOLqrVHE-5Ut54olscC&Kih01F> zmqoQdyg4OBDy3~`!|@lr@&Wf^a2bbkIa-3tp3#UJKrNKO!I%6|MC}PBjf{8TmYQre zFEGvbF(!(JQ$8TL6bsLUD(ffVnP)e{DUc5p27nd@9b73Z7=%y+OzXat+}%JnYrz)4J|cyB zP2EPBXQEq_DP-t;pAja8O@J`$LVFQgme9I$<|KHkyA!lBeXstUdepMOAeAUSMN1 z>I4~VH*oc|#cyDJDiZ;5bnYmZ2P6|kOBPHHw1iXIDTq1V6os*do7tdt7MA3_nf7*;H^Slb;5 zE7m-O)E(+DV9s5%6|A~uUCq*^wU32L4w+f<1!>iVRlP?2ZXsJHFTgp%|TFEQYAO>2X$Wx4$l{_cu2P2LsY7@v3%SPT3-?5->(w20|5A( zr*XYQ2pyw-nwusf0IbM-)x+e6(qaq^oQUZr;Dy4@I(~*^ju*hT^=|}Gj*F3`Lach> zA&j&Db8@f6ns+~VFnSJq9~wR7iG#R~2a(hXRd#MAW}9w0(YV6oeRTyQl!00vim}%E zi+fHgwN=|5vlJCu!{WZN7vurR6hytGr;u*rz z5>9Gos!zxGtuDbQdg||pJF;toZ_)x@vc83|UR{6gQG)*fJj!8< z?zK_Sv&bM;6iC=9w@|7+B5Ch;3aD;lytiCN6ezHgiLo^~q40LL9}jiuwo^lcLC_M41O1!Ud81-5vE+!gp!6PVV$r(+$! zcHsX2T4PpkH#4VBS)%|!&Ae(f)PT|%pwx;?jpg>`Qd^2~=YOAk3%R=eKeMHlrL3-gGViSL)62IV5?wWBQj5U=5;tLB5^ z<%-r#j{p_*gLKlSaaBl#uC=GtmVKkvjo)wMTqQ^dyt2R){v3ai|haY1^kkgPtZXB}84agR%NYgi@*kOKrRd+8 zi@%17vW_zYVc`JDm>dF6t4!ukmr@bv2a*AM|^L33M|Ci6-=q{*wDJ&+Y* zgKhB_61S@6ASmJke4e9tPdbXcb;K1YRptwTS42=OO}dI4#OYi%K#d3~KMi~znAsRK z{1=DWj1?wCw8F=b5j`b3=e7JwZW=gy5dwkh6^adKM*z*txJ64-FDuHvk@Go1r^^?x z(ECI+aEv$Dz=g+{=a{SfOhxJlDb{A|3ZsV37@q>!xVi}Av6kH!)BBi2@S55f;02C8}pq!9hHOzK#C{!!4c=*vW z9wB%~hU$Xl@iuKW3sy%$ue|JTdOP%U*vrouc-O8Ptq)khrG|Xltn|#YTP+so;p_hZ zAdTU30`=lyHRp(i^BN{D&Ulmp!VqI~5Xr?tx>NTO#E96CuJ67c&Lyt`g%8;&twz`# zA!(L8Zj-Be%=;}7ZnCUnxEy-2 zhoBd4{_bBO4wy2psvh#2#_%v2tXC-wDA)rjYB9(Q!+3$cTQ*s-i)@` zmikIGw(-7WGh0|MtMd%W6M`*xFJeX!Ys+xG7u0cI7Z-{OYV{~-%m^{469w)8;pX{^ zmyV{4{rH_%$blHj?3 zII=N!?{TSlJz$KS<{yUC2yuwBns~;e7QEECOK+lMRlb?MIj$fTo%o1txl5>pD{wj2 zyjF)HjyI$x!st2oJ$#+aa}RPV+dW9em^U(@m33@51HpqHLVsSMiWYUWgKG; z0Bj%t)nE%EeIAP3BX^s8V;96x5SfCpe5KRmWB#XYDy$v`4eG;0#GWdR!$UVF`aS{+ zG>HPfOBMhJ%?p`DIA#>wSW$dSCa7J;tIi?7W0p1zSk*zFkuZVfiD1|>iHW-F#38Zq zxGxEQl7+2t0-CPSn-^&jajt4D+twvE28h-vaP4ohBZwxNyP6uz6^A`bkd*m^*LCJl zC28l}%H8JkDqarRWQyknM_YcV!&)={06auNPAb&``|1p^g4+c=`Ga4MwPpdx0C#O9 z4XsPTi*#d!uCX*F_0nYEymG^Fyf*ox{wO>f0Y$auS4iuqqS4yt7S`g1?RJ}dK(4D; z@7Tcd3@uQ-TtLjI(=#cL6<|R8;J1QDNV3yOWM4p;zK6 zr7@Qoe9jOrV-R#`*$XBmbq#iq7H`zd9LBL2FslU9Hw6H>15}g^sLFsCXvj+wZy$_# zWN6WWqT)a!z$6vO+}yeX+dTI-+-}=1&eEV8y4@-{L=;m^ifR7<6af~1M#9;AL(1rd z4)eE$?Hf4H7ZqWxsIE%Vn9<>4^;&|t!Ejhp%`L;UEmKuZ!@|j&)vvY0_1t9|Sb>F= zUwCe2poM|uf}O8X$qqAy4(i=v0#~3t!k%9<6s&hT*BSV|^C(oXdFm5X#vnA*Ks~TZ z4V-O^p$e+R6h6-o16gVzPC1Ggy5rISpreu?7;<7bX`A+ey_MP!WrtHLOM*>Wb#*F& zaX^*xFAysOuj><)4d9r}hVNIu|z|M4!_c3so>0zW*sNrrpi)BGcboAuIUSZ?B zzLR++`oi8LYyK&U$`M%}_dqV)In{Z$5cC+uEo3!Tr#`ZgyKpIQ7f$vzGF;}~lnb6# zF($qUsvdnI1H?vDLg9%LWM8URF#!tL8wed*gtR)lHF}J~*6QV_hv8a)$Sl`! z61^$=)*f7Oo**~Cez-=}- z$LT7lo2u9gst_=70b6n6-WMpJ{s?sny65Y}BPIYiG?%U82BjOJN9q(Y#^tf{I|4rv z!uVEY!;BFVG{RqDP`d4T^o2o2bx|#>)-AbgQm)7@s=L9tPin3ZcLUNDXr*80FuHIu zh(uE=irY#{jHZ;JQ)W}O?5#$8*;`Q0p(;3jvh7}tzLPoe;Di;0TD*;9L@x1G(5=xSuf6zY|0P^(^8qS#&A zo%apV*%FpJ{&friXTWGJ_fMIfMSTMlZ#mwkjDT;N~_=M4?*xWcq-$|kgc(`z_XWyuP$c5O8s&6Mbh89+`rp!|~ z#^HzAVz8IXW438_08TavnBB_5K2dlvT>3_DO)SYvT-%e<83J)$rQ4bY2BxLaSsZ28 zn7q^}w3Tac>RhW!t;Hp_uH{A5K4Pr5$i>-)gLL-BA!;}!5o%}BQWnPQ3bRL;($+6# zrxn$;h>5twbKmn5v*`j->mm!TUl92vhgGwFV?0DPN>mQK%opTTr5kHvdqv#@WXK%~ z9o`F#1$Q;aE>?^0P|F7Bd>_B@UT~Z&$+MCYeIa&ylE4yg9yk>Uz#wgSjUPZ!_L--y zWAM7U3(45-YDCWUS{Tp{+{*UFMI|QjGT1Zqj*7P^ntZPk}p%(S1Yig#6rk(ozr2gIjKVG04=*7Wl1FRngt+xphd8y3_7oG(k8H5 z1-m%>#;~&%xQQ1%W}wj7)M0x}H(P+AP6b-US_Ygkci|IK3yBrcc<~&PhWCOzIKO=KzTO zhr}sYK(f7RG6!#wwTx92_`;f@O}>0M+;%{a2&YB$)}{9*$!Xgwk{HKn)BIBa5MWsG zr%~Q81TCz0Fo8B7vk*`oT<#BVZA6}@PY{V7ZcPIUJAvPMRjF#`D3oEMxQ6m1x*WTJ zA|Ieqn!7U;7pX|v?jTiB1WuD8c!*URX-K*2(gQWXaspw|k7z&|Q2HT${Vv>0Rj&7_ zy5bs4)!+*O=Fp>aUi-#{j(Xo+XFffuLJtaN1s5 zi3?h@2A)iFE>0=uDMSihh5$I2F<)RG5t~1@)i2R!7RPO)QUrC`V;#$AtP~#=F(OU3 z9@nX2``W(Y5M_3aeIi1%7M0UIVijxU{Fvine|U{lI*VQCV2(0n&-kE9)l=&vZ`>Jl z9D;z=<-o(=T|%)!haenQaB(YVww59^AxP1RNt2sZN>xwxr;HTfD%XICZ3zWHpr*MT zl@&a19GFb0FAj*jIk|0A@WBu~jLl}ir5YUP^DsacS5*1I22gqN{s|z^o9153`+pI=k?qPOZZEP1;Sh0qwq!!M0%YI9xjP-U?{lZY*cK+!@ox0D*#|sbwRHa$Xe+1 z05R!^Swb4D#JO~P+Y_RnS(Sr2Ve(8;ICs@#s#pQomPMXY!~xz#zz{&u{{R?YiO_GH-O5*~4rVqg*-A4@zTRdL zL4oxM)eR-o$dd@cbRGZ*h6t|aunlFWsa|Z-Y?oN;quyZXTep`7<%&7D=lBo|%8J?f zhSGt3wJXOZG^d!rgpjptl^0kcp}B!WJX}JNnavSyvcxU<ADhpsa^IK^M?9;A~oy zQCR9CMYk@M&>{u8YnTF&`c({#ShO*k%&F(A5za>NMbuho!UFIt&lfX>vX;>{6-s!h z1MY}!TnAZ7c%@}wheSb-X@sN#4~SP*kg#;IsQw25MoTeZ;WILzc!1Tb>{mqE^=t4) zHqfV59G=cEalJ{%OuTGe#~}h)7ur5ldKb>BU*i7&#Y$+=_B)O>hn=jEYF({5`p=gn zR3!>55HmP-35Y7GZoW{k>#==jZ<)f}+^qmWZm9dftBEvGE`=5kc**v81JC4OT;-OU zF?4Rfs_rH^Sp)0`-fFAy8-QYoR&35S1W>>pR*$PNeAc!zo%s;r>}E9*xPsnQksn1H zm#o|aRb5xzg5<)Cmt-!vMx_OpyZS9S^ShY0mWoi^aO^uE1`4==T49*GE~Zeb(d5g% zGZ5^6i3-miqlsIF)fC}XRR(!uzd{uw)C_(}j|f4;0Sm$wxVqvh7Y)jdUOWyTn)bj2&uVz6L1#tIbr~0BUu0Xt%)*nQXG^y2q2+R2UC5M!bH^trvqgDvvb% zW`|b_i*Gzk;S%GEDdJ@w%r{GFb8E!DQXa$y+FDlGy|9k&3It}B=PB_ENKBcRRz2a; zU8}xSmb$I5wfum@0Kgp*x>$GQZs}TXoKa+Kvgu~13b4uak2&l3)OS62ABl$1>-vtp z*c)ESP!&^=7SD)~VUf`GKIFVb5}qGZr`hm~?ukn3F<4VdV0&yV_l-?5G=J>Dl>5d! z6@gi{mfwe<<jOw#ILt6M-vVGxl_h|$JloJd;D%bO?Z|7RaUJU-$ZYd()jTVzy(9RE>=+{W&MSPa z-xV-ggFuxFW&K3KF#fe!4AHotDm7-@fmYUTB)>~c01gVnA0Swh*c2=n1!LY^*G6U$ z1H7~&mWb(wj}TgeiBSmv+2e6AlI}&>oH?uS5valH(JkbJ3b_}nX;d^hbz~V@Grwn! zK3*$GXuVqDel7&%F@lwsWAPt8qW9I)gU+BJOlS`#8AzNB){FBW@I$mPO9P+TQp29J z)Yg5a+Uc3;aV1Pa(nNAyz2K{NhhW$3Dx6yq%bYamvmOY8TJ~E59WI$pT;>C0X}mG6 z+)D|N{{R(+#~Ccma&i%sY4jEOB~7}hk_;kYWNNXt#ginJ1$+T{?e3-EJtOf}y?|NT z#_PL*kS$WKx~;OTmr}|#<0`|9Ai5=_bSJtRE0lxkhXfQ6%VH_SHjMjn(TBtqxd|=G zk46{K=g$zZjakg6gU;9(RRs%{gq8_zb}uWJ-Y)AQ)F6!cyDXncS#n64A4t|XGZ0Rqnx7~*CaWpQ&XE1131mtq#aQe1;)tv+AOOaWY$b(4^^-vSp zI`BYb>x@Jw5KC;1Jr1L5!ZxM8Ks9)A64rZyRi(PayQhdW5Rz9xeCfD10^ z!F@t0rH$mr?;63dOqWI1u0D|{Y7ZxN46egEXfqucuvS_JbhqFlwlncxwEqAUplvc# z@iw46I}8Ld6lqGYcAYrCu4OiEIqf;~8aQ?a}86g88R^-eOb zbNZtP3Q%4fz8LF7)(YtJ=ZIv0(34?YdFBLCZ{M#^60!F`;V9-3>yJ`WR=bPEhN6^P zFD&ocTtO(sg^$k9yRMcx4WHEwl}CI1ut|QaRePGl=mXqFJEkVdUE$gBjz7pZ+bLVU%kYFWm^nZ$S z=^>eK1&>C80$n8lyq8S)mGBEvj?85Aog1o^AC>`|+yh@oLqqHOAn{$c8~Z^DcBA^4 zP!Pn`l`>&&yg*_F6>|&g&odKMZA|$;Q5x1o%%Q-xFF128S~kEg@Ww>RmFO=0fRiC8 zU)8U)6)dGaSYQJWB{6cTx;z&}kmTL0#anAQfvp%8CbKsI!ukx%ZkJ^^vR2Dangz8@ zXe%$7eou)<3pr}i-N3fusBQJi799<>s)ZMeVNBB0AEJR$6imy9Jeq)1o|Co8`DI=1 z2vKMd&;Y8MYnq9vqNYzwtT3N6)F`B4%VvVQtwa`%zPi7pS%D;o1T#n~MwK$A)TP*C zVpkKwEa_nZ^1- zV3%N8M7`8j36ZtINASZHw_wZd{Xs5kdYSYFD9#H7!ARbW+Kkp$H#K}Vpn9U73OS6~ zlkg!}rp}60SH0(aLJ_%-3w_~KG^C#Y)D2pH zs+LWFb!;UF3ceJ>Q!B$oA66`Ct%6e5G+XT+wJ{M^?*zqhGCGr1^5^ps>&upAG5|&e zr7jT$lSZ?p0bXE;FH+5f-G(XBd4rKkJViB)3o9p5oN>HC<%%Z~o@j&9_?8iQ3WQa3 z5yOhRVHj$&R9cOc-%cVpV`*lEY`~9&oWL`m&HgARb$o!2IlfQR9LpQ=Yykk7S(5NZ zK+MqF0`0QJuMx7pC0JV=s_o8mFm0K@tAsc?S*T$X%SWKe?`7OGZ4ym(b`*}F_hcN^ z5XcpaGXn8g4XC7b;Fop`CTicT=0l65u>S4>!ngs^k@@z95m9MfC~G-ov9Lhyk*|8F zfMymHS$1)LV^D~Sd-5arm}?+nN-w`pW+N^74;(M|KEUTrQFsHY#f ziwqTmldpM-)+iBZ1!-xCc%=<*B0Sc2UXq(wknWl`Im71S5U3lX7j^DOj&6h6gX>b8 zg$<#>)$T5VNE!ykgakDn>p0@Rm@vYMpeV^$5;Lqs00#fCATS}=|Rs})gI z`@9Q{CcH(a?!cO%K1J$C(ko?1rJ$~aIuE_a>Rw4v;p|K>-iuj_Wax^qVNcPD$IEaf z(sS)m0rq)MTC4K}bvm^AR4son>yfinds%v`T3K*{g;%0VLRSU~ZO(MF zKmci#xaO*$sCcmXsci^Q^j|IC(&dgiDMOR4rA6^T2CUtd(n|B0tzKGg*G=&*Rw@+s zXk5ag#VTrCY^>sGGD|Hqa2!iVK&^h~_l~F)jKG#DcFE`0QAJi9W>M%{zFUU6*n^Cd z{O|lzJ7mG7ne#slGVk##8aH@;u+Z%geV9!x+i#hb=D6c=ju~wajRlI2xrVWmxVbKf zG{vTz3bTBpR4vby`tt@iviR&{gU7q)E<`tX%UxB`%zYoCW|7UjTYDI;u<31x?ANqm zyEM=R$*w*~a^!hb?Hh9Mxmr{cq$s-=^APq_GW@$r&vKRWqVg8#s{DDE=hiqd!uH3W zAOOJwaP*Jo*~DB^P(QQT?*y#^%z}3s8l5dYT&sfx6)M>(B+4+*m2iTs4Iyb@e<^24 zEVQEM1XV|zQr}R$x`6`DfuUyUR<{*Y^AT%>G}X$%pCP~6@uRzs~r z3PCQ?x^b8bde~n%!Hd+Qj>ZF$g^|xvoWsgz#08;C+xlaUiP5+$2xI3#i{HoirYS5M zyMq`a=8)aI1@Fjn1F?k1&_J4Q?-aFAG9)f6V#14Ynp)(u6yD2*1$^oKzRay8Yxwirc?r=(*P?j(`@roN^p4j@>-_)iNc+D<`%}0Ksis7 z6Akf#qMfT&v$h$D8v!<^1&8w!sjWfvSVazcV#hnv4Y{=rAUNR?23Jm+plbNKrWQ8C zJ00Ra=#7*Qt*!+>ynt%k*nh6b?P%jJJcsP@rVDjQ7(ef4x#h60EOHVoZvBz8frY*! z+e_&LL32w2mw0>ap#^b15NE|w%@Q-!ZGn8a$4 zr>adN3FwNIX;^bjFu&s8v6k7b17!`jMsWa5F-D>|0TpoD(lU|MY{Vu?qIC)HphbHJ z4o8HH48v)*HcZkyGNTI#rAiu6L*+Y#%W-nqN?bOcij<0YUQiBuGG|hqYl)&C3UGblVRsBGRTKg_Ie>L}j|VVxGUmvdYZpjCU&`U(a4-fi=eTQlnV0(PgGEpm zUJ>i3*^U9?5FZqWfa*h0d8DA1LG+ZhLlTU@sd)(vtdp!mf|guqJv`F6jWtb9W40jn zMb*nldqDQk>O7pA!^qZUI%KOMvpJ$u3p`a8K;4u9uQJG(@uMX;!$*iVVD*V%t7zb` zeY&YUd|%88fq_IzvH-W2q)iD`umdgmnR*RlmhhJLi}k(%k0PU*0;0QrSfX z1H&bQlLTXa6&Lip$Ifn47Q;|pym}Ch{DmKS^ERrdt>9L0n9OaMy%{%FHX5&-l-GF@#M?&1 zc>dIQC=HoB!_)|27?bs~x|XY+xF7>Ui{U8bv}=+Pcw-^uS4LXCrVzE9jzL(8P^OcIXE@V>;TA_$>LbOwUM)!r zH-OYDLUe8cBH|YDcf=gjP;w*;wy=N^D48HlE)qH7^)LmRgd4OUd3k5NnZhP%JA3g3WN5&+TpDs*&5aOxg&$Ha6_$b5yawm=kQ{rm z6e`!55sN)PcpA}c4wY}jCwi6Y5JKNWnTEoE9+P49E*0Nu%djtL68S<4^@Ehkya(oI zf_GS0qBVuUwa(5VpsUMFI*Zi=KFv9b!9rptuAJ@MXo+@3^>T+@o_VLyf5j@;rjkJ_ z+0gCiij`1r6F^aKf-oem$QreAq`+wuU(9?4BU=2xtkUn;U1QA5 z8j6>k<=n?DULt^X3*c&Qx^WVUtLj*d6w4o^(#vsG6vdzLm_qaT2|_5_AgDqYaRR1_ z;CaQzGRyN2oo&PyLcua&#=5xDY9O|N;5SPtur#PsM1c!#*Mo2m}=?l zhgD!&MiaQi$+VkifPy|4PvjEY3m)u4V3e&rmo4wX3k>^vfPm;h=B47>L~w_6*V;Q` z8LqW`_aTI{@wF7$@6453o7S>wA=MqJ}#?dvEO7V55+_teP95eqeW3XcS171ip*1r^Mo zN;MDzcN<%Ux-&K~!n9sqY9+P0(+-8P-Ya*qOe{Ui1#C!6tj^%8N-Ta15e*LfM@0_2 zMMSY^DwHag)8#qf?`i`5AS5wTF6+=>qj_zZG29fv0t$wE1`u|}RTVR1#*{TQX6*0$ zQ$h@+1{tl>Y3@`PfffW2Qnj5bz4B}h0K6`!N9h(TSOq*-*NTgmtcJC-baB|7LmF%f z>7UNvS3rPHQ&ymq$G$q31+3Ffa={q5G{kE8DlDlq&j32 z@_R;qLloa1pl&KOL91IYOW?sB)0YLGsMc7m_rC5ZWmePkDlpMXjEWnnSCrk{wRq~I zF0wTGVGIP6Xmo;%MUP3l$j(csG-4r5p$6)+dx|Yu;h0P$VKB@NU0=K@7c27zNoJ~P z6!o-$VEQpOWihq*n>Jx7v0N%M)JwJsyFh*5?Q~MjrF zjUcQt4qN{K6o*KYQdqF!{{VT0V=M?FB?5Ar<_zqEXFQZ=I^t4Z7)|zveVoPXVl{c8 z$r#z%0QgAzrr3{a<_>HJr-5UNxDx{}QNIvO>fk2Y;w%-Di-xDn5IA{_${Na(2%~xE z<@O?NXx1n|C7okY`;NryD1KMV26$tmMIMA@YNE{sVT=pYpB81P(GjKZ4i-Krg~2&- zEr+tB48fs^BZ24(cy9e(@a&~1tAjj5#;#r(=$2Ym&h5rL#&PzLb}gsc z7b#KCBBW}yv|kGR{{V_oK~-8Y5h?)8BDd=W;@uId3ND@XEyFCTI=NFOSaY^scw$Nk zTt&;LFEBJb7bNe@Q_J32D12Rp2nLY^vhmDSF)f_bDAGBW#uxJrP9c|DjFlojX@Nmd zviSh?E)vS=3Z8~rnY;$6Y->*Zu{;y+%GFjX;%2$x6-PJBEGgCdSgAsYX?6U{&u&Y# zdgDo1j5sp^pn4a!d_m3e6x;Nbrns3LUfq$;5VIZlwvRi&|mkQcLVfBCAf?Ge;^$VPLq%s|y8W#otlH)u|1k zR0jssJBz#slB8ALl-)S)Y#@;|wZ|wf9;Pg|EKmeCY9i^e)8|ZTV0U)RjWK}`pfJBcQ%t>G%}Ir58Nb8&p)4&`O^R%6x< zwLxP+<0PzuTY{a~#qvaEtsSc}lj6Y2RIOXiHv58_oT11N8!n&-2@pcMQwJC^aa+`; zinW0_g2C@{&T%nCQh71o_YtHWb!pQ|=bw1k)lCtC%RsJqnVi-(GOlqoDiMMeT76}x z8(AD0qqH4!wJ+eu@kO&oed#L-vt$M~gHVV+Kk z=9;w5aMv{V6&}sYP^iCAeI@-cwM|$fy}7Qsi*|ruAPK+#I09Tq2`n>;QQthh!Wt=D zodUD2;^|wJDxMrJQbt(uEn?7Gy<7wVYYb>{mCwvn;Ql&qG!~=P>R|P2728Im= zJ3WA7kX1U4yof6$b7k`j$+*l53E}+18ZoUbA$V}R%p&zhslBDWrD+vnZ9p=<^#szP z8fF$4ImZy&H=U{i`?mK^WskEy35QL^z?5Q^xRy>KIm*E*m(|fO`wNyUY;kGi;ylFW zHiu(c%}g%G?*(5`uUN9yXk-mHu1UiqEEYdO4q!`6Ii+tJ@{tL6!;<=5J|k!o3SENG z*Imu?Bd=fh{{R#Owk=&u;DFx1_E^uEe2QbJL*NJAAR!s}Wwkh`>~%GMV#r zH(lia05My2Y9pfBJ>~~R0J+Q>z>Ilfs`muP(qM=tCEdag#4B0cw53#Yn9X1)m^|DG zGbI2^?lcseydPO}o{drRC6#9kJrRLcf<-H>o*8S2;KUl9iTNLfBJhM8IIP#SWON6m zni}LfvF{XDEedq#Kp22i8-`eLMh?|LB_DURy)ZI{-`dOjSR_=t+!z8rrALdZw8?y@ zc@1MB@f^0Q0Tl)6`o)M{y^>;%&Zra7qFJ(SPvJG%GaVftb`1UxkeYueSd_x zNm3x@CCL%y1ES;8`8624O*q6ZekPZ2RhYD0`^Lt-=8;J<06^ody}`*06%|PlfYM_3 ziU76H24zkai-q}yQ3Vn45u)OhL*!--&V|cooWUD|GWw9wJ|^L5yQ=CDyrSAD+iW|e z!i*@61N4<5?U1ZnLN{L1S|vxI!c&47aW>z*Yu<3&So##EHbBa(@pHfz3@%>geSSF&q@227rTeD#}a$0QcQRsF4WgFx<{jjIy9H3Z0*TfHtBR&E{c3 zz*U;A=UIfT)y9=)lTG zGpNXea2nme)9r-O8mvQmv&o(-4w@pm5Xk7ha0};ySV3tLF?=O|kXN&s%mZ zqqSX1FK9RohZd@-Qvqtc$xcFazHeX|WeKDapWWtVD#2NA~^xqi~( zT#(yo%faaxENgTvgxz0{tg6w=lDKlxzG1DgGN=G>&@NQ@HU{YJ!E6lX33pR4tAj)l z*n@@LQ;o->UpCK`J`Uc2%L|yw7@!6KB65w&JIqI!bha0RfBxp;fAV;l{{Y}K0+-DP z%r(jAK@41KyUYPizzmH?x(lj>*tjq*=1T;#ANnOm3us@!a>nNkAHtO{&)*(IN@W0R zB~#Q&K0`razG)!*N{A}fUE7aH)vwtLR+Q6a&0V+5vIFIDE`d-!hM_l{mWyhgM;l3Q z4KhnxfNxtHs=MM`tKcz!G`D{6+IE==2-jJdr>5gJyl+7hq5-XX${n(}geKnc+`MJ# ziI&hd2R|_B9BPUzY4n*L@UdB5xVUWA>T^?&QO}s`qHKM-1FmCr2rUsn;8wuZVwX!t z9GH8H;agAyv)~DxKS-gLnq^C)j2_QRa8lv+f z(Qx*PgCE2^CZKX;h^1Q>%%o7sY(C5>x&e^m{?jzx_4HlCIMwJ}ZB^nU8O~4G)kT7+GsT8a3!(>O$G-BjYXSY&u|-F@l6_;QB>2lF|R5I ztWRhlZ16vE&!)iH000JxpJp@~+WIn%#l>Cw^94R~UKN;xq7;E&;1G6AbrzXFEFCPn zU%7La-TvsRoq8W;Ug_yKA9_W^(Q6JZ2k?80(f)gn(Ek7(#b|%7=L`9~$BX&A$N2BO z{;TsJFy`D*o@R{=@S>fc($kKQsFe%>L{1{{Y8_{{SRN{*&`R zwEV;Q54=Bs`_JG%Fy;P_Fy)jBaDv-^UBXQ R0M~YhRUYsM{{Y=D|Jh@R|9$`f literal 0 HcmV?d00001 diff --git a/boards/shields/mikroe_accel13_click/doc/index.rst b/boards/shields/mikroe_accel13_click/doc/index.rst new file mode 100644 index 00000000000..24d6a69443a --- /dev/null +++ b/boards/shields/mikroe_accel13_click/doc/index.rst @@ -0,0 +1,56 @@ +.. _mikroe_accel13_click_shield: + +MikroElektronika ACCEL 13 Click +############################### + +Overview +******** + +The MikroElektronika ACCEL 13 Click carries the `IIS2DLPC`_ ultra-low +power triaxial accelerometer sensor in a `mikroBUS`_ |trade| form factor. + +The `IIS2DLPC`_ sensor supports both SPI and I2C bus protocols. Currently +only I2C is supported for this shield. + +.. figure:: accel-13-click.jpg + :align: center + :alt: MikroElektronika ACCEL 13 Click + + MikroElektronika ACCEL 13 Click (Credit: MikroElektronika) + +Requirements +************ + +This shield can only be used with a development board that provides a +configuration for mikroBUS connectors and defines a node alias for the mikroBUS +I2C interface (see :ref:`shields` for more details). + +For more information about interfacing the IIS2DLPC and the ACCEL 13 Click, +see the following documentation: + +- `IIS2DLPC Datasheet`_ +- `ACCEL 13 Click`_ + +Programming +*********** + +Set ``-DSHIELD=mikro_accel13_click`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: test/boards/board_shell + :board: lpcxpresso55s69 + :shield: mikroe_accel13_click + :goals: build + +.. _IIS2DLPC: + https://www.st.com/en/mems-and-sensors/iis2dlpc.html + +.. _mikroBUS: + https://www.mikroe.com/mikrobus + +.. _IIS2DLPC Datasheet: + https://www.st.com/resource/en/datasheet/iis2dlpc.pdf + +.. _ACCEL 13 Click: + https://www.mikroe.com/accel-13-click diff --git a/boards/shields/mikroe_accel13_click/mikroe_accel13_click.overlay b/boards/shields/mikroe_accel13_click/mikroe_accel13_click.overlay new file mode 100644 index 00000000000..e2979b384d3 --- /dev/null +++ b/boards/shields/mikroe_accel13_click/mikroe_accel13_click.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Mark Olsson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + accel0 = &iis2dlpc_mikroe_accel13_click; + }; +}; + +&mikrobus_i2c { + status = "okay"; + + iis2dlpc_mikroe_accel13_click: iis2dlpc@18 { + compatible = "st,iis2dlpc"; + reg = <0x18>; + drdy-gpios = <&mikrobus_header 7 GPIO_ACTIVE_HIGH>; + drdy-int = <2>; + status = "okay"; + }; +}; From ce438da14f8a03b0cf13593f336e9838991b97d5 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Wed, 27 Sep 2023 16:22:36 +0200 Subject: [PATCH 2174/4498] llvm: Add support for LLVM libc++ C++ Standard Library LLVM toolchain provides its own C++ standard library called libc++. This patch adds new LLVM_LIBCXX config which should be used to indicate that libc++ is used. Information about library can be found at https://libcxx.llvm.org Signed-off-by: Patryk Duda --- cmake/linker/lld/target.cmake | 2 +- cmake/linker/lld/target_cpp.cmake | 11 +++++++++++ lib/cpp/Kconfig | 12 ++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 cmake/linker/lld/target_cpp.cmake diff --git a/cmake/linker/lld/target.cmake b/cmake/linker/lld/target.cmake index 77ebf8d3121..f71a217e5be 100644 --- a/cmake/linker/lld/target.cmake +++ b/cmake/linker/lld/target.cmake @@ -110,6 +110,6 @@ endfunction(toolchain_ld_link_elf) # Load toolchain_ld-family macros include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake) include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake) -include(${ZEPHYR_BASE}/cmake/linker/ld/target_cpp.cmake) +include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake) include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake) diff --git a/cmake/linker/lld/target_cpp.cmake b/cmake/linker/lld/target_cpp.cmake new file mode 100644 index 00000000000..1004c0e6865 --- /dev/null +++ b/cmake/linker/lld/target_cpp.cmake @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +# See root CMakeLists.txt for description and expectations of these macros + +macro(toolchain_ld_cpp) + + zephyr_link_libraries( + -lc++ + ) + +endmacro() diff --git a/lib/cpp/Kconfig b/lib/cpp/Kconfig index 696df05102a..6ac4dae170a 100644 --- a/lib/cpp/Kconfig +++ b/lib/cpp/Kconfig @@ -74,6 +74,7 @@ config FULL_LIBCPP_SUPPORTED choice LIBCPP_IMPLEMENTATION prompt "C++ Standard Library Implementation" default EXTERNAL_LIBCPP if REQUIRES_FULL_LIBCPP && NATIVE_BUILD + default LIBCXX_LIBCPP if REQUIRES_FULL_LIBCPP && "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "llvm" default GLIBCXX_LIBCPP if REQUIRES_FULL_LIBCPP default MINIMAL_LIBCPP @@ -96,6 +97,17 @@ config GLIBCXX_LIBCPP Build with GNU C++ Standard Library (libstdc++) provided by the GNU Compiler Collection (GCC)-based toolchain. +config LIBCXX_LIBCPP + bool "LLVM C++ Standard Library" + depends on !NATIVE_APPLICATION + depends on NEWLIB_LIBC + depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "llvm" + select FULL_LIBCPP_SUPPORTED + help + Build with LLVM C++ Standard Library (libc++) provided by LLVM + toolchain. Information about library can be found at + https://libcxx.llvm.org + config ARCMWDT_LIBCPP bool "ARC MWDT C++ Library" depends on !NATIVE_APPLICATION From 3aeeeb746a4f27185d8e39ec9619fda819672e95 Mon Sep 17 00:00:00 2001 From: Henrik Eriksen Date: Mon, 18 Sep 2023 09:18:01 +0200 Subject: [PATCH 2175/4498] bluetooth: tester: cas: Added support for testing Common Audio Service - Set Member Lock - Get Member RSI Signed-off-by: Henrik Eriksen --- tests/bluetooth/tester/CMakeLists.txt | 4 + tests/bluetooth/tester/overlay-le-audio.conf | 5 + tests/bluetooth/tester/src/btp/btp.h | 4 +- tests/bluetooth/tester/src/btp/btp_cas.h | 29 +++++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_cas.c | 106 +++++++++++++++++++ tests/bluetooth/tester/src/btp_core.c | 13 +++ 7 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_cas.h create mode 100644 tests/bluetooth/tester/src/btp_cas.c diff --git a/tests/bluetooth/tester/CMakeLists.txt b/tests/bluetooth/tester/CMakeLists.txt index d773e6b0da2..d76de937f5d 100644 --- a/tests/bluetooth/tester/CMakeLists.txt +++ b/tests/bluetooth/tester/CMakeLists.txt @@ -55,3 +55,7 @@ endif() if (CONFIG_BT_TBS_CLIENT) target_sources(app PRIVATE src/btp_ccp.c) endif() + +if (CONFIG_BT_CAP_ACCEPTOR) + target_sources(app PRIVATE src/btp_cas.c) +endif() diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 99cb4f8f8ef..101b04f9f9b 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -5,6 +5,7 @@ CONFIG_BT_BAP_UNICAST_CLIENT=y CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4 +CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=16 # Ring buffer for streaming ISO data CONFIG_RING_BUFFER=y @@ -87,3 +88,7 @@ CONFIG_BT_CSIP_SET_MEMBER=y CONFIG_BT_L2CAP_TX_BUF_COUNT=12 CONFIG_BT_TBS_CLIENT_GTBS=y CONFIG_BT_TBS_CLIENT_TBS=n + +# CAS +CONFIG_BT_CAP_ACCEPTOR=y +CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER=y diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index c4d52c161fd..b1092dc6d5d 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -29,6 +29,7 @@ #include "btp_mics.h" #include "btp_ccp.h" #include "btp_vcp.h" +#include "btp_cas.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -57,8 +58,9 @@ #define BTP_SERVICE_ID_MICS 18 #define BTP_SERVICE_ID_CCP 19 #define BTP_SERVICE_ID_VCP 20 +#define BTP_SERVICE_ID_CAS 21 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_VCP +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CAS #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/tests/bluetooth/tester/src/btp/btp_cas.h b/tests/bluetooth/tester/src/btp/btp_cas.h new file mode 100644 index 00000000000..a0e63342f97 --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_cas.h @@ -0,0 +1,29 @@ +/* btp_cas.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Oticon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* CAS commands */ +#define BTP_CAS_READ_SUPPORTED_COMMANDS 0x01 +struct btp_cas_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_CAS_SET_MEMBER_LOCK 0x02 +struct btp_cas_set_member_lock_cmd { + bt_addr_le_t address; + uint8_t lock; + uint8_t force; +} __packed; + +#define BTP_CAS_GET_MEMBER_RSI 0x03 +struct btp_cas_get_member_rsi_cmd { + bt_addr_le_t address; +} __packed; + +struct btp_cas_get_member_rsi_rp { + uint8_t rsi[BT_CSIP_RSI_SIZE]; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 1602658ad17..b6ddc561cf4 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -111,3 +111,6 @@ uint8_t tester_unregister_ccp(void); uint8_t tester_init_vcp(void); uint8_t tester_unregister_vcp(void); + +uint8_t tester_init_cas(void); +uint8_t tester_unregister_cas(void); diff --git a/tests/bluetooth/tester/src/btp_cas.c b/tests/bluetooth/tester/src/btp_cas.c new file mode 100644 index 00000000000..feb64ea3323 --- /dev/null +++ b/tests/bluetooth/tester/src/btp_cas.c @@ -0,0 +1,106 @@ +/* btp_cas.c - Bluetooth CAS Tester */ + +/* + * Copyright (c) 2023 Oticon + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "btp/btp.h" +#include "zephyr/sys/byteorder.h" +#include + +#include +#define LOG_MODULE_NAME bttester_cas +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); + +static struct bt_csip_set_member_svc_inst *csis_svc_inst; + +static uint8_t cas_supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_cas_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_CAS_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_CAS_SET_MEMBER_LOCK); + tester_set_bit(rp->data, BTP_CAS_GET_MEMBER_RSI); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t cas_set_member_lock(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_cas_set_member_lock_cmd *cp = cmd; + int err = -EINVAL; + + if (csis_svc_inst) { + err = bt_csip_set_member_lock(csis_svc_inst, cp->lock, cp->force); + } + + return BTP_STATUS_VAL(err); +} + +static uint8_t cas_get_member_rsi(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_cas_get_member_rsi_rp *rp = rsp; + int err = -EINVAL; + + if (csis_svc_inst) { + err = bt_csip_set_member_generate_rsi(csis_svc_inst, rp->rsi); + } + *rsp_len = sizeof(*rp); + + return BTP_STATUS_VAL(err); +} + +static const struct btp_handler cas_handlers[] = { + { + .opcode = BTP_CAS_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = cas_supported_commands + }, + { + .opcode = BTP_CAS_SET_MEMBER_LOCK, + .expect_len = sizeof(struct btp_cas_set_member_lock_cmd), + .func = cas_set_member_lock + }, + { + .opcode = BTP_CAS_GET_MEMBER_RSI, + .expect_len = sizeof(struct btp_cas_get_member_rsi_cmd), + .func = cas_get_member_rsi + } +}; + +uint8_t tester_init_cas(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_CAS, cas_handlers, + ARRAY_SIZE(cas_handlers)); + +#if defined(CONFIG_BT_CAP_ACCEPTOR) && defined(CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER) + struct bt_csip_set_member_register_param register_params = { + .set_size = 2, + .set_sirk = { 0xB8, 0x03, 0xEA, 0xC6, 0xAF, 0xBB, 0x65, 0xA2, + 0x5A, 0x41, 0xF1, 0x53, 0x05, 0x68, 0x8E, 0x83 }, + .lockable = true, + .rank = 1, + .cb = NULL + }; + int err = bt_cap_acceptor_register(®ister_params, &csis_svc_inst); +#else + int err = 0; +#endif /* CONFIG_BT_CAP_ACCEPTOR && CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */ + + return BTP_STATUS_VAL(err); +} + +uint8_t tester_unregister_cas(void) +{ + return BTP_STATUS_SUCCESS; +} diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 522bcb5aa75..b91aa5be1e1 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -89,6 +89,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_VCP_VOL_CTLR) tester_set_bit(rp->data, BTP_SERVICE_ID_VCP); #endif /* CONFIG_BT_VCP_VOL_CTLR */ +#if defined(CONFIG_BT_CAP_ACCEPTOR) + tester_set_bit(rp->data, BTP_SERVICE_ID_CAS); +#endif /* CONFIG_BT_CAP_ACCEPTOR */ *rsp_len = sizeof(*rp) + 2; @@ -184,6 +187,11 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_ccp(); break; #endif /* CONFIG_BT_TBS_CLIENT */ +#if defined(CONFIG_BT_CAP_ACCEPTOR) + case BTP_SERVICE_ID_CAS: + status = tester_init_cas(); + break; +#endif /* CONFIG_BT_CAP_ACCEPTOR */ default: LOG_WRN("unknown id: 0x%02x", cp->id); status = BTP_STATUS_FAILED; @@ -278,6 +286,11 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_ccp(); break; #endif /* CONFIG_BT_TBS_CLIENT */ +#if defined(CONFIG_BT_CAP_ACCEPTOR) + case BTP_SERVICE_ID_CAS: + status = tester_unregister_cas(); + break; +#endif /* CONFIG_BT_CAP_ACCEPTOR */ default: LOG_WRN("unknown id: 0x%x", cp->id); status = BTP_STATUS_FAILED; From cc85223ed4d5907bd457cb8145672c2167821cbf Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Mon, 2 Oct 2023 09:12:43 +0200 Subject: [PATCH 2176/4498] net: openthread: Remove waiting for DTR in openthread UART. Uart driver for openthread have been waiting for host to start communicating with coprocessor, during booting of the Zephyr and by that blocking start os OS. There is no longer a need for that since the stack will be soft rebooted after host connects to coprocessor, removing the need to wait on host communication. Signed-off-by: Przemyslaw Bida --- modules/openthread/platform/uart.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/modules/openthread/platform/uart.c b/modules/openthread/platform/uart.c index dd62d36ee11..ebf156ded15 100644 --- a/modules/openthread/platform/uart.c +++ b/modules/openthread/platform/uart.c @@ -170,7 +170,6 @@ otError otPlatUartEnable(void) if (DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_ot_uart), zephyr_cdc_acm_uart)) { int ret; - uint32_t dtr = 0U; ret = usb_enable(NULL); if (ret != 0 && ret != -EALREADY) { @@ -178,20 +177,6 @@ otError otPlatUartEnable(void) return OT_ERROR_FAILED; } - LOG_INF("Waiting for host to be ready to communicate"); - - /* Data Terminal Ready - check if host is ready to communicate */ - while (!dtr) { - ret = uart_line_ctrl_get(ot_uart.dev, - UART_LINE_CTRL_DTR, &dtr); - if (ret) { - LOG_ERR("Failed to get Data Terminal Ready line state: %d", - ret); - continue; - } - k_msleep(100); - } - /* Data Carrier Detect Modem - mark connection as established */ (void)uart_line_ctrl_set(ot_uart.dev, UART_LINE_CTRL_DCD, 1); /* Data Set Ready - the NCP SoC is ready to communicate */ From 17fad703c586fb232c1bdec5156ff50134e5d72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 2 Oct 2023 11:43:44 +0200 Subject: [PATCH 2177/4498] samples: lvgl: sensor: Add LVGL sample for real-time sensor data chart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a new sample for LVGL that displays a real-time chart for accelerometer data acquired from &accel0 sensor. This also adds the appropriate overlays so that the sample can also run on native POSIX and native sim using emulated BMI160. Signed-off-by: Benjamin Cabé --- .../lvgl/accelerometer_chart/CMakeLists.txt | 9 ++ .../modules/lvgl/accelerometer_chart/Kconfig | 17 ++++ .../lvgl/accelerometer_chart/README.rst | 51 ++++++++++ .../boards/native_posix.conf | 1 + .../boards/native_posix.overlay | 16 ++++ .../boards/native_posix_64.conf | 1 + .../boards/native_posix_64.overlay | 1 + .../boards/native_sim.conf | 1 + .../boards/native_sim.overlay | 1 + .../boards/native_sim_64.conf | 1 + .../boards/native_sim_64.overlay | 1 + .../modules/lvgl/accelerometer_chart/prj.conf | 9 ++ .../lvgl/accelerometer_chart/sample.yaml | 18 ++++ .../lvgl/accelerometer_chart/src/main.c | 96 +++++++++++++++++++ 14 files changed, 223 insertions(+) create mode 100644 samples/modules/lvgl/accelerometer_chart/CMakeLists.txt create mode 100644 samples/modules/lvgl/accelerometer_chart/Kconfig create mode 100644 samples/modules/lvgl/accelerometer_chart/README.rst create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_posix.conf create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_posix.overlay create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.conf create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.overlay create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_sim.conf create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_sim.overlay create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.conf create mode 100644 samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.overlay create mode 100644 samples/modules/lvgl/accelerometer_chart/prj.conf create mode 100644 samples/modules/lvgl/accelerometer_chart/sample.yaml create mode 100644 samples/modules/lvgl/accelerometer_chart/src/main.c diff --git a/samples/modules/lvgl/accelerometer_chart/CMakeLists.txt b/samples/modules/lvgl/accelerometer_chart/CMakeLists.txt new file mode 100644 index 00000000000..6c4a568b1e5 --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(accelerometer_chart) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/modules/lvgl/accelerometer_chart/Kconfig b/samples/modules/lvgl/accelerometer_chart/Kconfig new file mode 100644 index 00000000000..bba256103be --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/Kconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Benjamin Cabé +# SPDX-License-Identifier: Apache-2.0 + +config SAMPLE_CHART_POINTS_PER_SERIES + int "Number of points per series" + default 50 + range 10 200 + help + Maximum number of points per series in the accelerometer chart. + Warning: More points means more memory usage, and slower rendering! + +config SAMPLE_ACCEL_SAMPLING_RATE + int "Accelerometer sampling rate (Hz)" + default 50 + range 1 100 + +source "Kconfig.zephyr" diff --git a/samples/modules/lvgl/accelerometer_chart/README.rst b/samples/modules/lvgl/accelerometer_chart/README.rst new file mode 100644 index 00000000000..95d7287c89e --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/README.rst @@ -0,0 +1,51 @@ +.. zephyr:code-sample:: lvgl-accelerometer-chart + :name: LVGL line chart with accelerometer data + :relevant-api: display_interface sensor_interface + + Display acceleration data on a real-time chart using LVGL. + +Overview +******** + +A sample application that demonstrates how to use LVGL and the :ref:`sensor API ` to +display acceleration data on a line chart that is updated in real time. + +This sample creates a line chart with three series, one for each axis of the accelerometer. An LVGL +timer fetches the latest acceleration data from the sensor every 20 ms (default value) and updates +the chart. The update period is configurable, see +:ref:`lvgl_accelerometer_chart_building_and_running` below. + +Requirements +************ + +* A board with a display. +* A sensor that provides acceleration data (:c:enumerator:`SENSOR_CHAN_ACCEL_XYZ`) and available + under the ``&accel0`` Devicetree alias. + +.. note:: + + A Devicetree overlay declaring an emulated BMI160 accelerometer is provided for the + ``native_posix*`` and ``native_sim*`` board variants, making it possible to run this sample on + your local machine. + +.. _lvgl_accelerometer_chart_building_and_running: + +Building and Running +******************** + +The maximum number of points to display for each series and the sampling rate of the +accelerometer can be configured using the :kconfig:option:`CONFIG_SAMPLE_CHART_POINTS_PER_SERIES` +and :kconfig:option:`CONFIG_SAMPLE_ACCEL_SAMPLING_RATE` Kconfig options, respectively. + +The default sampling rate is 50 Hz, and the default maximum number of points per series is 50. + +The demo can be built as follows (note how in this particular case the sampling rate is set to a +custom value of 20 Hz): + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/accelerometer_chart + :host-os: unix + :board: native_posix + :gen-args: -DCONFIG_SAMPLE_ACCEL_SAMPLING_RATE=20 + :goals: run + :compact: diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_posix.conf b/samples/modules/lvgl/accelerometer_chart/boards/native_posix.conf new file mode 100644 index 00000000000..e01c80e9dfa --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_posix.conf @@ -0,0 +1 @@ +CONFIG_BMI160_TRIGGER_NONE=y diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_posix.overlay b/samples/modules/lvgl/accelerometer_chart/boards/native_posix.overlay new file mode 100644 index 00000000000..dc4174b58d7 --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_posix.overlay @@ -0,0 +1,16 @@ +/* Copyright (c) 2023 Benjamin Cabé + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + accel0 = &bmi_i2c; + }; +}; + +&i2c0 { + bmi_i2c: bmi@68 { + compatible = "bosch,bmi160"; + reg = <0x68>; + }; +}; diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.conf b/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.conf new file mode 100644 index 00000000000..e01c80e9dfa --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.conf @@ -0,0 +1 @@ +CONFIG_BMI160_TRIGGER_NONE=y diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.overlay b/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.overlay new file mode 100644 index 00000000000..2b055bf3de6 --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_posix_64.overlay @@ -0,0 +1 @@ +#include "native_posix.overlay" diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_sim.conf b/samples/modules/lvgl/accelerometer_chart/boards/native_sim.conf new file mode 100644 index 00000000000..e01c80e9dfa --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_sim.conf @@ -0,0 +1 @@ +CONFIG_BMI160_TRIGGER_NONE=y diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_sim.overlay b/samples/modules/lvgl/accelerometer_chart/boards/native_sim.overlay new file mode 100644 index 00000000000..2b055bf3de6 --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_sim.overlay @@ -0,0 +1 @@ +#include "native_posix.overlay" diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.conf b/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.conf new file mode 100644 index 00000000000..e01c80e9dfa --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.conf @@ -0,0 +1 @@ +CONFIG_BMI160_TRIGGER_NONE=y diff --git a/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.overlay b/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.overlay new file mode 100644 index 00000000000..6a3daca3241 --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/boards/native_sim_64.overlay @@ -0,0 +1 @@ +#include "native_sim.overlay" diff --git a/samples/modules/lvgl/accelerometer_chart/prj.conf b/samples/modules/lvgl/accelerometer_chart/prj.conf new file mode 100644 index 00000000000..a5d6e2e831e --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/prj.conf @@ -0,0 +1,9 @@ +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_LOG=y + +CONFIG_LVGL=y +CONFIG_LV_Z_MEM_POOL_SIZE=16384 + +CONFIG_DISPLAY=y +CONFIG_INPUT=y +CONFIG_SENSOR=y diff --git a/samples/modules/lvgl/accelerometer_chart/sample.yaml b/samples/modules/lvgl/accelerometer_chart/sample.yaml new file mode 100644 index 00000000000..cca7fe07ffe --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/sample.yaml @@ -0,0 +1,18 @@ +sample: + description: Real-time visualization of acceleration data using LVGL chart widget + name: LVGL acceleration chart +tests: + sample.modules.lvgl.accelerometer_chart: + filter: dt_chosen_enabled("zephyr,display") and dt_alias_exists("accel0") + min_flash: 250 + min_ram: 32 + harness: none + tags: + - samples + - display + - gui + - lvgl + modules: + - lvgl + integration_platforms: + - native_posix_64 diff --git a/samples/modules/lvgl/accelerometer_chart/src/main.c b/samples/modules/lvgl/accelerometer_chart/src/main.c new file mode 100644 index 00000000000..2aaee9fad0d --- /dev/null +++ b/samples/modules/lvgl/accelerometer_chart/src/main.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Benjamin Cabé + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(app, CONFIG_LOG_DEFAULT_LEVEL); + +static lv_obj_t *chart1; +static lv_chart_series_t *ser_x; +static lv_chart_series_t *ser_y; +static lv_chart_series_t *ser_z; +static lv_timer_t *sensor_timer; + +const struct device *accel_sensor; + +/* Timer handler: fetches sensor data and appends it to the chart */ +static void sensor_timer_cb(lv_timer_t *timer) +{ + struct sensor_value accel[3]; + int rc = sensor_sample_fetch(accel_sensor); + + if (rc == 0) { + rc = sensor_channel_get(accel_sensor, SENSOR_CHAN_ACCEL_XYZ, accel); + } + if (rc < 0) { + LOG_ERR("ERROR: Update failed: %d\n", rc); + return; + } + lv_chart_set_next_value(chart1, ser_x, sensor_value_to_double(&accel[0])); + lv_chart_set_next_value(chart1, ser_y, sensor_value_to_double(&accel[1])); + lv_chart_set_next_value(chart1, ser_z, sensor_value_to_double(&accel[2])); +} + +static void create_accelerometer_chart(lv_obj_t *parent) +{ + chart1 = lv_chart_create(parent); + lv_obj_set_size(chart1, LV_HOR_RES, LV_VER_RES); + lv_chart_set_type(chart1, LV_CHART_TYPE_LINE); + lv_chart_set_div_line_count(chart1, 5, 8); + lv_chart_set_range(chart1, LV_CHART_AXIS_PRIMARY_Y, -20, 20); /* roughly -/+ 2G */ + lv_chart_set_update_mode(chart1, LV_CHART_UPDATE_MODE_SHIFT); + + ser_x = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_RED), + LV_CHART_AXIS_PRIMARY_Y); + ser_y = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_BLUE), + LV_CHART_AXIS_PRIMARY_Y); + ser_z = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_GREEN), + LV_CHART_AXIS_PRIMARY_Y); + + lv_chart_set_point_count(chart1, CONFIG_SAMPLE_CHART_POINTS_PER_SERIES); + + /* Do not display point markers on the data */ + lv_obj_set_style_size(chart1, 0, LV_PART_INDICATOR); +} + +int main(void) +{ + const struct device *display_dev; + + display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); + if (!device_is_ready(display_dev)) { + LOG_ERR("Device not ready, aborting test"); + return -ENODEV; + } + + accel_sensor = DEVICE_DT_GET(DT_ALIAS(accel0)); + if (!device_is_ready(accel_sensor)) { + LOG_ERR("Device %s is not ready\n", accel_sensor->name); + return -ENODEV; + } + + create_accelerometer_chart(lv_scr_act()); + sensor_timer = lv_timer_create(sensor_timer_cb, + 1000 / CONFIG_SAMPLE_ACCEL_SAMPLING_RATE, + NULL); + lv_task_handler(); + display_blanking_off(display_dev); + + while (1) { + k_msleep(lv_task_handler()); + } + + return 0; +} From 7a7aeb21e233df9c3f1d5f53ec85856caf8551b7 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 13 Sep 2023 12:45:50 -0700 Subject: [PATCH 2178/4498] boards: qemu_xtensa: use dc233c core This changes qemu_xtensa to use dc233c core instead of sample_controller. The sample_controller uses a very basic configuration which lacks features usually needed in real world applications. Instead, use the dc233c core as the base for qemu_xtensa so we can use QEMU to cover more of our code path. Signed-off-by: Daniel Leung --- boards/xtensa/qemu_xtensa/Kconfig.board | 2 +- boards/xtensa/qemu_xtensa/board.cmake | 8 +------- boards/xtensa/qemu_xtensa/qemu_xtensa.dts | 6 +++--- boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig | 2 +- soc/xtensa/dc233c/Kconfig.defconfig | 3 ++- soc/xtensa/dc233c/include/xtensa-dc233c.ld | 5 +++++ .../code_relocation/linker_xtensa_qemu_sram2.ld | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/boards/xtensa/qemu_xtensa/Kconfig.board b/boards/xtensa/qemu_xtensa/Kconfig.board index 8c517c88dc0..4695b26396c 100644 --- a/boards/xtensa/qemu_xtensa/Kconfig.board +++ b/boards/xtensa/qemu_xtensa/Kconfig.board @@ -5,7 +5,7 @@ config BOARD_QEMU_XTENSA bool "Xtensa emulation using QEMU" - depends on SOC_XTENSA_SAMPLE_CONTROLLER + depends on SOC_XTENSA_DC233C select QEMU_TARGET config BOARD_QEMU_XTENSA_MMU diff --git a/boards/xtensa/qemu_xtensa/board.cmake b/boards/xtensa/qemu_xtensa/board.cmake index 7d6997c702c..56a6c358be4 100644 --- a/boards/xtensa/qemu_xtensa/board.cmake +++ b/boards/xtensa/qemu_xtensa/board.cmake @@ -2,13 +2,7 @@ set(SUPPORTED_EMU_PLATFORMS qemu) -if(CONFIG_BOARD_QEMU_XTENSA) - set(QEMU_CPU_TYPE_${ARCH} sample_controller) - - set(QEMU_FLAGS_${ARCH} - -machine sim -semihosting -nographic -cpu sample_controller - ) -elseif(CONFIG_BOARD_QEMU_XTENSA_MMU) +if(CONFIG_BOARD_QEMU_XTENSA OR CONFIG_BOARD_QEMU_XTENSA_MMU) set(QEMU_CPU_TYPE_${ARCH} dc233c) set(QEMU_FLAGS_${ARCH} diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa.dts b/boards/xtensa/qemu_xtensa/qemu_xtensa.dts index 4fa67abf2ec..da45a72dbc6 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa.dts +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa.dts @@ -1,16 +1,16 @@ /* - * Copyright (c) 2019 Intel Corporation. + * Copyright (c) 2019, 2023 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; -#include "sample_controller.dtsi" +#include "dc233c.dtsi" / { model = "qemu_xtensa"; - compatible = "cdns,xtensa-sample-controller"; + compatible = "cdns,xtensa-dc233c"; chosen { zephyr,sram = &sram0; diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig b/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig index 08e8295cc80..ec51bb17a38 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig @@ -3,7 +3,7 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_BOARD_QEMU_XTENSA=y CONFIG_CONSOLE=y -CONFIG_SOC_XTENSA_SAMPLE_CONTROLLER=y +CONFIG_SOC_XTENSA_DC233C=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000 CONFIG_STACK_SENTINEL=y CONFIG_GEN_ISR_TABLES=y diff --git a/soc/xtensa/dc233c/Kconfig.defconfig b/soc/xtensa/dc233c/Kconfig.defconfig index c78c8cd7337..dc5be860b4a 100644 --- a/soc/xtensa/dc233c/Kconfig.defconfig +++ b/soc/xtensa/dc233c/Kconfig.defconfig @@ -22,7 +22,8 @@ config XTENSA_MMU_NUM_L2_TABLES # via TLB way 4 (which covers 1MB). config SRAM_OFFSET hex - default 0x100000 + default 0x100000 if XTENSA_MMU + default 0x2400 config KERNEL_VM_OFFSET hex diff --git a/soc/xtensa/dc233c/include/xtensa-dc233c.ld b/soc/xtensa/dc233c/include/xtensa-dc233c.ld index 65f47f5ce9b..b165016fa6a 100644 --- a/soc/xtensa/dc233c/include/xtensa-dc233c.ld +++ b/soc/xtensa/dc233c/include/xtensa-dc233c.ld @@ -346,6 +346,10 @@ SECTIONS } >vec_helpers :vec_helpers_phdr #endif /* CONFIG_XTENSA_MMU */ +#ifdef CONFIG_CODE_DATA_RELOCATION +#include +#endif + .ResetVector.text : ALIGN(4) { __rom_region_start = ABSOLUTE(.); @@ -363,6 +367,7 @@ SECTIONS *(.entry.text) *(.init.literal) *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *(.iram1.literal .iram1) KEEP(*(.init)) *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.fini.literal) diff --git a/tests/application_development/code_relocation/linker_xtensa_qemu_sram2.ld b/tests/application_development/code_relocation/linker_xtensa_qemu_sram2.ld index 3cf73a090cf..3fd33186a8f 100644 --- a/tests/application_development/code_relocation/linker_xtensa_qemu_sram2.ld +++ b/tests/application_development/code_relocation/linker_xtensa_qemu_sram2.ld @@ -26,4 +26,4 @@ PHDRS #define MPU_ALIGN(region_size) \ . = ALIGN(4) -#include +#include From a2ab57c2405e3dfa4745f33260d7b8247cab8bdb Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 3 Oct 2023 10:44:59 +0200 Subject: [PATCH 2179/4498] Bluetooth: Audio: Update bsim and shell to use codec set chan alloc Update the BSIM test and the shell to use bt_audio_codec_cfg_set_chan_allocation rather than implementing their own versions. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/audio.h | 23 --------- subsys/bluetooth/audio/shell/cap_initiator.c | 12 ++--- .../audio/src/cap_initiator_unicast_test.c | 50 ++++++------------- 3 files changed, 20 insertions(+), 65 deletions(-) diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index 7f19d9105d8..8beae301036 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -286,29 +286,6 @@ static inline void copy_broadcast_source_preset(struct broadcast_source *source, memcpy(&source->qos, &named_preset->preset.qos, sizeof(source->qos)); memcpy(&source->codec_cfg, &named_preset->preset.codec_cfg, sizeof(source->codec_cfg)); } - -static inline int codec_set_chan_alloc(struct bt_audio_codec_cfg *codec_cfg, - enum bt_audio_location loc) -{ - for (size_t i = 0U; i < codec_cfg->data_len;) { - const uint8_t len = codec_cfg->data[i++]; - const uint8_t type = codec_cfg->data[i++]; - uint8_t *value = &codec_cfg->data[i]; - const uint8_t value_len = len - sizeof(type); - - if (type == BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC) { - const uint32_t loc_32 = loc; - - sys_put_le32(loc_32, value); - - return 0; - } - i += value_len; - } - - return -ENODATA; -} - #endif /* CONFIG_BT_AUDIO */ #endif /* __AUDIO_H */ diff --git a/subsys/bluetooth/audio/shell/cap_initiator.c b/subsys/bluetooth/audio/shell/cap_initiator.c index a57050a5607..afdd686160c 100644 --- a/subsys/bluetooth/audio/shell/cap_initiator.c +++ b/subsys/bluetooth/audio/shell/cap_initiator.c @@ -573,10 +573,10 @@ static int cap_ac_unicast_start(const struct bap_unicast_ac_param *param, stream_cnt++; if (param->conn_cnt > 1) { - const int err = - codec_set_chan_alloc(stream_param->codec_cfg, BIT(i)); + const int err = bt_audio_codec_cfg_set_chan_allocation( + stream_param->codec_cfg, (enum bt_audio_location)BIT(i)); - if (err != 0) { + if (err < 0) { shell_error(ctx_shell, "Failed to set channel allocation for " "snk[%zu][%zu]: %d", @@ -600,10 +600,10 @@ static int cap_ac_unicast_start(const struct bap_unicast_ac_param *param, stream_cnt++; if (param->conn_cnt > 1) { - const int err = - codec_set_chan_alloc(stream_param->codec_cfg, BIT(i)); + const int err = bt_audio_codec_cfg_set_chan_allocation( + stream_param->codec_cfg, (enum bt_audio_location)BIT(i)); - if (err != 0) { + if (err < 0) { shell_error(ctx_shell, "Failed to set channel allocation for " "src[%zu][%zu]: %d", diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c index abc1098cd9d..335b2894838 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c @@ -1015,40 +1015,6 @@ static int cap_initiator_ac_create_unicast_group(const struct cap_initiator_ac_p return bt_bap_unicast_group_create(&group_param, unicast_group); } -static int set_chan_alloc(enum bt_audio_location loc, struct bt_audio_codec_cfg *codec_cfg) -{ - for (size_t i = 0U; i < codec_cfg->data_len;) { - const uint8_t len = codec_cfg->data[i++]; - uint8_t value_len; - uint8_t *value; - uint8_t type; - - if (len == 0 || len > codec_cfg->data_len - i) { - /* Invalid len field */ - return false; - } - - type = codec_cfg->data[i++]; - value = &codec_cfg->data[i]; - value_len = len - sizeof(type); - - if (type == BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC) { - const uint32_t loc_32 = loc; - - sys_put_le32(loc_32, value); - - return 0; - } - - /* Since we are incrementing i by the value_len, we don't need to increment it - * further in the `for` statement - */ - i += value_len; - } - - return -ENOENT; -} - static int cap_initiator_ac_cap_unicast_start(const struct cap_initiator_ac_param *param, struct unicast_stream *snk_uni_streams[], size_t snk_cnt, @@ -1138,7 +1104,13 @@ static int cap_initiator_ac_cap_unicast_start(const struct cap_initiator_ac_para stream_cnt++; if (param->conn_cnt > 1) { - set_chan_alloc(BIT(i), stream_param->codec_cfg); + const int err = bt_audio_codec_cfg_set_chan_allocation( + stream_param->codec_cfg, (enum bt_audio_location)BIT(i)); + + if (err < 0) { + FAIL("Failed to set channel allocation: %d\n", err); + return err; + } } } @@ -1155,7 +1127,13 @@ static int cap_initiator_ac_cap_unicast_start(const struct cap_initiator_ac_para stream_cnt++; if (param->conn_cnt > 1) { - set_chan_alloc(BIT(i), stream_param->codec_cfg); + const int err = bt_audio_codec_cfg_set_chan_allocation( + stream_param->codec_cfg, (enum bt_audio_location)BIT(i)); + + if (err < 0) { + FAIL("Failed to set channel allocation: %d\n", err); + return err; + } } } } From e3b63e7baf09af720a560fd5284122ebbac241aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Fri, 29 Sep 2023 16:49:16 +0200 Subject: [PATCH 2180/4498] bluetooth: tester: Enable composition data page 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabling the composition data page 2 feature and adding tester support. Signed-off-by: Alperen Şener --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf index 5f59970b421..52045ce34df 100644 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ b/tests/bluetooth/tester/overlay-mesh-v1d1.conf @@ -26,5 +26,5 @@ CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y CONFIG_BT_MESH_MODEL_EXTENSIONS=y CONFIG_BT_MESH_COMP_PAGE_1=y - +CONFIG_BT_MESH_COMP_PAGE_2=y CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index eacdb8b3b0c..1d6f696f729 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1252,6 +1252,22 @@ static const struct bt_mesh_comp comp_alt = { .vid = 2, }; +#if defined(CONFIG_BT_MESH_COMP_PAGE_2) +static const uint8_t cmp2_elem_offset[1] = {0}; + +static const struct bt_mesh_comp2_record comp_rec = { + .id = 0x1600, + .version.x = 1, + .version.y = 0, + .version.z = 0, + .elem_offset_cnt = 1, + .elem_offset = cmp2_elem_offset, + .data_len = 0 +}; + +static const struct bt_mesh_comp2 comp_p2 = {.record_cnt = 1, .record = &comp_rec}; +#endif + static struct bt_mesh_prov prov = { .uuid = dev_uuid, .static_val = static_auth, @@ -5343,6 +5359,10 @@ uint8_t tester_init_mesh(void) bt_test_cb_register(&bt_test_cb); } +#if defined(CONFIG_BT_MESH_COMP_PAGE_2) + bt_mesh_comp2_register(&comp_p2); +#endif + tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); From 28bd5423fff961b82f084e2925fce6f56e9087ff Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 4 Oct 2023 10:41:59 +0300 Subject: [PATCH 2181/4498] drivers: eth: native: Remove automatic start script support As the automatic start requires that the zephyr exe is run as a root user, it is somewhat cumbersome to use. Remove the script support and require that the zeth device is created beforehand by the net-setup.sh script found in net-tools zephyr project. Signed-off-by: Jukka Rissanen --- drivers/ethernet/Kconfig.native_posix | 53 ------------------- drivers/ethernet/eth_native_posix.c | 29 ----------- drivers/ethernet/eth_native_posix_adapt.c | 62 ----------------------- drivers/ethernet/eth_native_posix_priv.h | 18 ------- 4 files changed, 162 deletions(-) diff --git a/drivers/ethernet/Kconfig.native_posix b/drivers/ethernet/Kconfig.native_posix index 5fc33450540..24f488aa44c 100644 --- a/drivers/ethernet/Kconfig.native_posix +++ b/drivers/ethernet/Kconfig.native_posix @@ -11,59 +11,6 @@ menuconfig ETH_NATIVE_POSIX a process in your host system. if ETH_NATIVE_POSIX -config ETH_NATIVE_POSIX_STARTUP_AUTOMATIC - bool "Start network interface automatically" - help - If set, the native_posix ethernet driver will set up the network - interface, requiring ``zephyr.exe`` to be run with root privileges - (needed to create and configure the TAP device). - If not set (the default and recommended way), the network interface - must be set up manually using ``net-setup.sh`` (from the net-tools - project repo). The ``zephyr.exe`` program can then be run as a - non-root user. - -if ETH_NATIVE_POSIX_STARTUP_AUTOMATIC - -config ETH_NATIVE_POSIX_SETUP_SCRIPT - string "Host setup script" - default "${ZEPHYR_BASE}/samples/net/eth_native_posix/net_setup_host" - help - This option sets the name of the script that is run when the host TAP - network interface is created. The script should setup IP addresses - etc. for the host TAP network interface. - The default script accepts following options: - -i|--interface , default is zeth - -f|--file , default is net_setup_host.conf - If needed, you can add these options to this script name option. - Note that the driver will add -i option with the value of - CONFIG_ETH_NATIVE_POSIX_DRV_NAME option to the end of the options - list when calling the host setup script. - -config ETH_NATIVE_POSIX_STARTUP_SCRIPT - string "Host startup script" - default "" - help - This option sets the name of the script that is run when the host TAP - network interface is created and setup script has been run. - The startup script could launch e.g., wireshark to capture - the network traffic for the freshly started network interface. - Note that the network interface name CONFIG_ETH_NATIVE_POSIX_DRV_NAME - is appended at the end of this startup script name. - Example script for starting wireshark is provided in - ${ZEPHYR_BASE}/samples/net/eth_native_posix/net_start_wireshark.sh - file. - -config ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER - string "Username to run the host startup script" - default "" - help - By default the startup script is run as a root user. Set here the - username to run the script if running it as a root user is not - desired. Note that this setting is only for startup script and not - for the setup script. The setup script needs to be run always as - a root user. - -endif # ETH_NATIVE_POSIX_STARTUP_AUTOMATIC config ETH_NATIVE_POSIX_INTERFACE_COUNT int "Number of network interfaces created" diff --git a/drivers/ethernet/eth_native_posix.c b/drivers/ethernet/eth_native_posix.c index 874077b61a1..55059afaeee 100644 --- a/drivers/ethernet/eth_native_posix.c +++ b/drivers/ethernet/eth_native_posix.c @@ -474,10 +474,6 @@ static void eth_iface_init(struct net_if *iface) } else { /* Create a thread that will handle incoming data from host */ create_rx_handler(ctx); - - eth_setup_host(ctx->if_name); - - eth_start_script(ctx->if_name); } } @@ -573,36 +569,11 @@ static int vlan_setup(const struct device *dev, struct net_if *iface, } #endif /* CONFIG_NET_VLAN */ -static int eth_start_device(const struct device *dev) -{ - struct eth_context *context = dev->data; - int ret; - - context->status = true; - - ret = eth_if_up(context->if_name); - - eth_setup_host(context->if_name); - - return ret; -} - -static int eth_stop_device(const struct device *dev) -{ - struct eth_context *context = dev->data; - - context->status = false; - - return eth_if_down(context->if_name); -} - static const struct ethernet_api eth_if_api = { .iface_api.init = eth_iface_init, .get_capabilities = eth_posix_native_get_capabilities, .set_config = set_config, - .start = eth_start_device, - .stop = eth_stop_device, .send = eth_send, #if defined(CONFIG_NET_VLAN) diff --git a/drivers/ethernet/eth_native_posix_adapt.c b/drivers/ethernet/eth_native_posix_adapt.c index 14f73d6916a..8cbda81bd3e 100644 --- a/drivers/ethernet/eth_native_posix_adapt.c +++ b/drivers/ethernet/eth_native_posix_adapt.c @@ -105,41 +105,6 @@ static int ssystem(const char *fmt, ...) return -WEXITSTATUS(ret); } -int eth_setup_host(const char *if_name) -{ - if (!IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC)) { - return 0; - } - - /* User might have added -i option to setup script string, so - * check that situation in the script itself so that the -i option - * we add here is ignored in that case. - */ - return ssystem("%s -i %s", ETH_NATIVE_POSIX_SETUP_SCRIPT, - if_name); -} - -int eth_start_script(const char *if_name) -{ - if (!IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC)) { - return 0; - } - - if (ETH_NATIVE_POSIX_STARTUP_SCRIPT[0] == '\0') { - return 0; - } - - if (ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER[0] == '\0') { - return ssystem("%s %s", ETH_NATIVE_POSIX_STARTUP_SCRIPT, - if_name); - } else { - return ssystem("sudo -u %s %s %s", - ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER, - ETH_NATIVE_POSIX_STARTUP_SCRIPT, - if_name); - } -} - int eth_wait_data(int fd) { struct timeval timeout; @@ -196,34 +161,7 @@ int eth_clock_gettime(struct net_ptp_time *time) #if defined(CONFIG_NET_PROMISCUOUS_MODE) int eth_promisc_mode(const char *if_name, bool enable) { - if (!IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC)) { - return 0; - } - return ssystem("ip link set dev %s promisc %s", if_name, enable ? "on" : "off"); } #endif /* CONFIG_NET_PROMISCUOUS_MODE */ - -/* If we have enabled manual setup, then interface cannot be - * taken up or down by the driver as we normally do not have - * enough permissions. - */ - -int eth_if_up(const char *if_name) -{ - if (!IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC)) { - return 0; - } - - return ssystem("ip link set dev %s up", if_name); -} - -int eth_if_down(const char *if_name) -{ - if (!IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC)) { - return 0; - } - - return ssystem("ip link set dev %s down", if_name); -} diff --git a/drivers/ethernet/eth_native_posix_priv.h b/drivers/ethernet/eth_native_posix_priv.h index 2d925fd83dc..012f59dfe66 100644 --- a/drivers/ethernet/eth_native_posix_priv.h +++ b/drivers/ethernet/eth_native_posix_priv.h @@ -11,29 +11,11 @@ #ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NATIVE_POSIX_PRIV_H_ #define ZEPHYR_DRIVERS_ETHERNET_ETH_NATIVE_POSIX_PRIV_H_ -#define ETH_NATIVE_POSIX_DRV_NAME CONFIG_ETH_NATIVE_POSIX_DRV_NAME -#define ETH_NATIVE_POSIX_DEV_NAME CONFIG_ETH_NATIVE_POSIX_DEV_NAME - -#if defined(CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC) -#define ETH_NATIVE_POSIX_SETUP_SCRIPT CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT -#define ETH_NATIVE_POSIX_STARTUP_SCRIPT CONFIG_ETH_NATIVE_POSIX_STARTUP_SCRIPT -#define ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER \ - CONFIG_ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER -#else -#define ETH_NATIVE_POSIX_SETUP_SCRIPT "" -#define ETH_NATIVE_POSIX_STARTUP_SCRIPT "" -#define ETH_NATIVE_POSIX_STARTUP_SCRIPT_USER "" -#endif - int eth_iface_create(const char *if_name, bool tun_only); int eth_iface_remove(int fd); -int eth_setup_host(const char *if_name); -int eth_start_script(const char *if_name); int eth_wait_data(int fd); ssize_t eth_read_data(int fd, void *buf, size_t buf_len); ssize_t eth_write_data(int fd, void *buf, size_t buf_len); -int eth_if_up(const char *if_name); -int eth_if_down(const char *if_name); #if defined(CONFIG_NET_GPTP) int eth_clock_gettime(struct net_ptp_time *time); From 7b40014504e5bf3286065db13949144e932464b0 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 4 Oct 2023 11:07:08 +0300 Subject: [PATCH 2182/4498] samples: net: Remove eth_native_posix sample app This application is no longer needed as we have removed the automatic startup support which was used by this sample. Signed-off-by: Jukka Rissanen --- samples/net/eth_native_posix/CMakeLists.txt | 9 -- samples/net/eth_native_posix/README.rst | 147 ------------------ samples/net/eth_native_posix/net_setup_host | 81 ---------- .../net/eth_native_posix/net_setup_host.conf | 11 -- .../eth_native_posix/net_start_wireshark.sh | 35 ----- samples/net/eth_native_posix/prj.conf | 40 ----- samples/net/eth_native_posix/sample.yaml | 13 -- samples/net/eth_native_posix/src/main.c | 22 --- 8 files changed, 358 deletions(-) delete mode 100644 samples/net/eth_native_posix/CMakeLists.txt delete mode 100644 samples/net/eth_native_posix/README.rst delete mode 100755 samples/net/eth_native_posix/net_setup_host delete mode 100644 samples/net/eth_native_posix/net_setup_host.conf delete mode 100755 samples/net/eth_native_posix/net_start_wireshark.sh delete mode 100644 samples/net/eth_native_posix/prj.conf delete mode 100644 samples/net/eth_native_posix/sample.yaml delete mode 100644 samples/net/eth_native_posix/src/main.c diff --git a/samples/net/eth_native_posix/CMakeLists.txt b/samples/net/eth_native_posix/CMakeLists.txt deleted file mode 100644 index 4b116d7f47f..00000000000 --- a/samples/net/eth_native_posix/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(eth_native_posix) - -target_sources(app PRIVATE src/main.c) - -include(${ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/samples/net/eth_native_posix/README.rst b/samples/net/eth_native_posix/README.rst deleted file mode 100644 index 7d7232acd5c..00000000000 --- a/samples/net/eth_native_posix/README.rst +++ /dev/null @@ -1,147 +0,0 @@ -.. zephyr:code-sample:: eth-native-posix - :name: Native POSIX Ethernet - :relevant-api: net_core ethernet - - Create a network interface to the host system. - -Overview -******** - -The eth_native_posix sample application for Zephyr creates a **zeth** network -interface to the host system. One can communicate with Zephyr via this network -interface. - -The source code for this sample application can be found at: -:zephyr_file:`samples/net/eth_native_posix`. - -Building And Running -******************** - -To build the eth_native_posix sample application, follow the steps -below. - -.. zephyr-app-commands:: - :zephyr-app: samples/net/eth_native_posix - :host-os: unix - :board: native_posix - :conf: - :goals: build - :compact: - -Normally one needs extra privileges to create and configure the TAP device in -the host system. If the user has set the -:kconfig:option:`CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC` option (this is disabled -by default), then the user needs to use ``sudo`` to execute the Zephyr process -with admin privileges, like this: - -.. code-block:: console - - sudo --preserve-env=ZEPHYR_BASE make -Cbuild run - -If the ``sudo --preserve-env=ZEPHYR_BASE`` gives an error, -just use ``sudo --preserve-env`` instead. - -If the :kconfig:option:`CONFIG_ETH_NATIVE_POSIX_STARTUP_AUTOMATIC` option -is not enabled (this is the default), then the user should -execute the ``net-setup.sh`` script from Zephyr `net-tools`_ repository. -The script should be run before executing the Zephyr process. The script -will create the zeth interface and set up IP addresses and routes. -While running ``net-setup.sh`` requires root access, afterwards Zephyr -process can be run as a non-root user. - -You can run the ``net-setup.sh`` script like this:: - - cd net-tools - sudo ./net-setup.sh - -or:: - - sudo ./net-setup.sh --config ./zeth-vlan.conf - -See also other command line options by typing ``net-setup.sh --help``. - -When the network interface is set up manually, you can leave the wireshark -to monitor the interface, and then start and stop the zephyr process without -stopping the wireshark. - -Setting things manually works the same as working with SLIP connectivity -in QEMU. - -If you want to connect two Zephyr instances together, you can do it like this: - -Create two Zephyr config files prj1.conf and prj2.conf. You can use -:zephyr_file:`samples/net/eth_native_posix/prj.conf` as a base. - -Set prj1.conf IP address configuration like this: - -.. code-block:: console - - CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8:100::1" - CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8:100::2" - CONFIG_NET_CONFIG_MY_IPV4_ADDR="198.51.100.1" - CONFIG_NET_CONFIG_PEER_IPV4_ADDR="198.51.100.2" - CONFIG_NET_CONFIG_MY_IPV4_GW="203.0.113.1" - CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=n - CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:64" - CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT="echo" - CONFIG_ETH_NATIVE_POSIX_DRV_NAME="zeth.1" - -Set prj2.conf IP address configuration like this: - -.. code-block:: console - - CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8:200::1" - CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8:200::2" - CONFIG_NET_CONFIG_MY_IPV4_ADDR="203.0.113.1" - CONFIG_NET_CONFIG_PEER_IPV4_ADDR="203.0.113.2" - CONFIG_NET_CONFIG_MY_IPV4_GW="198.51.100.1" - CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=n - CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:c8" - CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT="echo" - CONFIG_ETH_NATIVE_POSIX_DRV_NAME="zeth.2" - -Then compile and run two Zephyr instances -(if ``sudo --preserve-env=ZEPHYR_BASE`` gives an error, -just use ``sudo --preserve-env`` instead): - -.. code-block:: console - - cmake -DCONF_FILE=prj1.conf -DBOARD=native_posix -Bbuild1/native_posix . - make -s -C build1/native_posix - sudo --preserve-env=ZEPHYR_BASE make -s -C build1/native_posix run - -.. code-block:: console - - cmake -DCONF_FILE=prj2.conf -DBOARD=native_posix -Bbuild2/native_posix . - make -s -C build2/native_posix - sudo --preserve-env=ZEPHYR_BASE make -s -C build2/native_posix run - -Bridge the two Zephyr instances together: - -.. code-block:: console - - sudo brctl addbr zeth-br - sudo brctl addif zeth-br zeth.1 - sudo brctl addif zeth-br zeth.2 - sudo ifconfig zeth-br up - -After this, you are able to ping device 1 from device 2 in net-shell: - -.. code-block:: console - - # In device 1 - net ping 2001:db8:200::1 - net ping 203.0.113.1 - -.. code-block:: console - - # In device 2 - net ping 2001:db8:100::1 - net ping 198.51.100.1 - -Note that in this setup you cannot access these two Zephyr devices from -your host. If you want to do that, then you could create a new network -interface with proper IP addresses and add that interface to the Zephyr -bridge. - -.. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools diff --git a/samples/net/eth_native_posix/net_setup_host b/samples/net/eth_native_posix/net_setup_host deleted file mode 100755 index e1ee7b80c09..00000000000 --- a/samples/net/eth_native_posix/net_setup_host +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2018 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script is called by native-posix board when TAP network interface -# is taken up by Zephyr. The script should setup the host system so that -# connectivity will work with Zephyr. - -while [ $# -gt 0 ]; do - case "$1" in - -f|--file) - CONF_FILE="$2" - shift - shift;; - -i|--interface) - # Only first -i option is taken into account. This way - # the driver added -i option is ignored if user has specified - # the -i option to host setup script command. - if [ -z "$IFACE" ]; then - IFACE="$2" - fi - shift - shift;; - *) - shift;; - esac -done - -if [ `id -u` != 0 ]; then - echo "Warning: This script will need admin rights to setup \ -network interface!" -fi - -if [ -z "$IFACE" ]; then - IFACE="zeth" -fi - -if [ -z "$CONF_FILE" ]; then - DIR=`dirname $0` - CONF_FILE="$DIR/net_setup_host.conf" -fi - -if [ -f "$CONF_FILE" ]; then - . $CONF_FILE -else - echo "Warning: config file $CONF_FILE does not exist!" -fi - -ip link set dev $IFACE up - -if [ ! -z "$HWADDR" ]; then - ip link set dev $IFACE address $HWADDR -fi - -if [ ! -z "$IPV6_ADDR_1" ]; then - ip -6 address add $IPV6_ADDR_1 dev $IFACE -fi - -if [ ! -z "$IPV6_ROUTE_1" ]; then - ip -6 route add $IPV6_ROUTE_1 dev $IFACE -fi - -if [ ! -z "$IPV4_ADDR_1" ]; then - ip address add $IPV4_ADDR_1 dev $IFACE -fi - -if [ ! -z "$IPV4_ROUTE_1" ]; then - ip route add $IPV4_ROUTE_1 dev $IFACE -fi diff --git a/samples/net/eth_native_posix/net_setup_host.conf b/samples/net/eth_native_posix/net_setup_host.conf deleted file mode 100644 index 4e6ab7a5574..00000000000 --- a/samples/net/eth_native_posix/net_setup_host.conf +++ /dev/null @@ -1,11 +0,0 @@ -# -# Configuration options for setting up the host network interface -# - -HWADDR="00:00:5e:00:53:ff" - -IPV6_ADDR_1="2001:db8::2" -IPV6_ROUTE_1="2001:db8::/64" - -IPV4_ADDR_1="192.0.2.2" -IPV4_ROUTE_1="192.0.2.0/24" diff --git a/samples/net/eth_native_posix/net_start_wireshark.sh b/samples/net/eth_native_posix/net_start_wireshark.sh deleted file mode 100755 index 2fcdeded9d1..00000000000 --- a/samples/net/eth_native_posix/net_start_wireshark.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2018 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script can be called by native-posix board when TAP network interface -# is created. This script will start wireshark so that it is possible to -# monitor the network traffic for the interface. - -if [ ! -z "$1" ]; then - IFACE="$1" -else - IFACE="zeth" -fi - -WIRESHARK="wireshark -k -i $IFACE" - -echo "Starting \"$WIRESHARK\" as \"`id -u -n`\" user." - -$WIRESHARK & - -# The startup of wireshark is slow so sleep here a bit so that everything -# in wireshark is setup properly before continuing with zephyr startup. -sleep 5 diff --git a/samples/net/eth_native_posix/prj.conf b/samples/net/eth_native_posix/prj.conf deleted file mode 100644 index dedd8e86bfc..00000000000 --- a/samples/net/eth_native_posix/prj.conf +++ /dev/null @@ -1,40 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NET_UDP=y -CONFIG_NET_TCP=y -CONFIG_NET_IPV6=y -CONFIG_NET_IPV4=y -#CONFIG_NET_DHCPV4=y - -CONFIG_ENTROPY_GENERATOR=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_INIT_STACKS=y - -CONFIG_NET_LOG=y -CONFIG_LOG=y - -CONFIG_NET_STATISTICS=y - -CONFIG_NET_PKT_RX_COUNT=32 -CONFIG_NET_PKT_TX_COUNT=32 -CONFIG_NET_BUF_RX_COUNT=32 -CONFIG_NET_BUF_TX_COUNT=32 - -CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 -CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4 -CONFIG_NET_MAX_CONTEXTS=10 - -CONFIG_NET_SHELL=y - -CONFIG_NET_CONFIG_SETTINGS=y -CONFIG_NET_CONFIG_NEED_IPV6=y -CONFIG_NET_CONFIG_NEED_IPV4=y -CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" -CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" -CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" -CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" - -CONFIG_NET_L2_ETHERNET=y - -CONFIG_ETH_NATIVE_POSIX=y -CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y -#CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" diff --git a/samples/net/eth_native_posix/sample.yaml b/samples/net/eth_native_posix/sample.yaml deleted file mode 100644 index d60d6adf68b..00000000000 --- a/samples/net/eth_native_posix/sample.yaml +++ /dev/null @@ -1,13 +0,0 @@ -common: - harness: net - tags: net -sample: - description: Can be used to test native posix connectivity via ethernet. - name: Native posix ethernet demo application -tests: - sample.net.eth_native_posix: - platform_allow: - - native_posix - - native_posix_64 - integration_platforms: - - native_posix diff --git a/samples/net/eth_native_posix/src/main.c b/samples/net/eth_native_posix/src/main.c deleted file mode 100644 index fccb0ddde9d..00000000000 --- a/samples/net/eth_native_posix/src/main.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(net_native_posix_sample, LOG_LEVEL_DBG); - -#include -#include - -#include - -/* This application itself does nothing as there is net-shell that can be used - * to monitor things. - */ -int main(void) -{ - LOG_INF("Start application"); - return 0; -} From 0bd323ab88653ea5d491ceecc6bb07a01858b204 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 4 Oct 2023 11:15:58 +0300 Subject: [PATCH 2183/4498] board: native: Update the posix Ethernet driver documentation Remove the mention of startup script and update the documentation to reflect the current way of working i.e., using net-setup.sh script before starting the zephyr.exe process. Signed-off-by: Jukka Rissanen --- boards/posix/native_posix/doc/index.rst | 24 +++++++++++++----------- boards/posix/native_sim/doc/index.rst | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 73e3eb4110d..92827acbacf 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -323,17 +323,19 @@ The following peripherals are currently provided with this board: such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal). **Ethernet driver**: - A simple TAP based ethernet driver is provided. The driver will create - a **zeth** network interface to the host system. One can communicate with - Zephyr via this network interface. Multiple TAP based network interfaces can - be created if needed. The IP address configuration can be specified for each - network interface instance. - See :kconfig:option:`CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT` option for more details. - The :zephyr:code-sample:`eth-native-posix` sample app provides - some use examples and more information about this driver configuration. - - Note that this device can only be used with Linux hosts, and that the user - needs elevated permissions. + A simple TAP based ethernet driver is provided. The driver expects that the + **zeth** network interface already exists in the host system. The **zeth** + network interface can be created by the ``net-setup.sh`` script found in + the `net-tools`_ zephyr project repository. User can communicate with the + Zephyr instance via the **zeth** network interface. Multiple TAP based + network interfaces can be created if needed. The IP address configuration + can be specified for each network interface instance. + + Note that this device can only be used with Linux hosts. + +.. _net-tools: + https://github.com/zephyrproject-rtos/net-tools + **Bluetooth controller**: It's possible to use the host's Bluetooth adapter as a Bluetooth diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 5286de1b425..bd332c1e081 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -113,7 +113,7 @@ host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). display, display SDL, :kconfig:option:`CONFIG_SDL_DISPLAY`, all entropy, native posix entropy, :kconfig:option:`CONFIG_FAKE_ENTROPY_NATIVE_POSIX`, all eprom, eprom emulator, :kconfig:option:`CONFIG_EEPROM_EMULATOR`, host libC - ethernet, eth native_posix, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, host libC + ethernet, eth native_posix, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, all flash, flash simulator, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, all flash, host based flash access, :kconfig:option:`CONFIG_FUSE_FS_ACCESS`, host libC gpio, GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL`, all From c345f59910f09251531bc798e2170e1972a984ca Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 3 Oct 2023 14:58:25 +0300 Subject: [PATCH 2184/4498] drivers: eth: native: Add native-sim support to posix Ethernet driver This will enable Ethernet driver to be used when compiling for native-sim board. Signed-off-by: Jukka Rissanen --- drivers/ethernet/CMakeLists.txt | 9 ++++-- drivers/ethernet/Kconfig.native_posix | 2 +- drivers/ethernet/eth_native_posix.c | 8 ++--- drivers/ethernet/eth_native_posix_adapt.c | 36 ++++++----------------- drivers/ethernet/eth_native_posix_priv.h | 18 ++---------- 5 files changed, 23 insertions(+), 50 deletions(-) diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index 6f963cd68d0..b40872e8146 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -48,8 +48,13 @@ if(CONFIG_ETH_NATIVE_POSIX) set_source_files_properties(${native_posix_source_files} PROPERTIES COMPILE_DEFINITIONS "NO_POSIX_CHEATS;_BSD_SOURCE;_DEFAULT_SOURCE" - ) - zephyr_library_sources(${native_posix_source_files}) + ) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(${native_posix_source_files}) + else() + zephyr_library_sources(eth_native_posix.c) + target_sources(native_simulator INTERFACE eth_native_posix_adapt.c) + endif() endif() add_subdirectory(phy) diff --git a/drivers/ethernet/Kconfig.native_posix b/drivers/ethernet/Kconfig.native_posix index 24f488aa44c..8ab1033d477 100644 --- a/drivers/ethernet/Kconfig.native_posix +++ b/drivers/ethernet/Kconfig.native_posix @@ -5,7 +5,7 @@ menuconfig ETH_NATIVE_POSIX bool "Native Posix Ethernet driver" - depends on ARCH_POSIX && EXTERNAL_LIBC + depends on ARCH_POSIX help Enable native posix ethernet driver. Note, this driver is run inside a process in your host system. diff --git a/drivers/ethernet/eth_native_posix.c b/drivers/ethernet/eth_native_posix.c index 55059afaeee..83697642f77 100644 --- a/drivers/ethernet/eth_native_posix.c +++ b/drivers/ethernet/eth_native_posix.c @@ -153,7 +153,7 @@ static void update_gptp(struct net_if *iface, struct net_pkt *pkt, struct gptp_hdr *hdr; int ret; - ret = eth_clock_gettime(×tamp); + ret = eth_clock_gettime(×tamp.second, ×tamp.nanosecond); if (ret < 0) { return; } @@ -460,7 +460,7 @@ static void eth_iface_init(struct net_if *iface) * change the documentation etc. and break things. */ if (CONFIG_ETH_NATIVE_POSIX_INTERFACE_COUNT == 1) { - ctx->if_name = ETH_NATIVE_POSIX_DRV_NAME; + ctx->if_name = CONFIG_ETH_NATIVE_POSIX_DRV_NAME; } LOG_DBG("Interface %p using \"%s\"", iface, ctx->if_name); @@ -468,7 +468,7 @@ static void eth_iface_init(struct net_if *iface) net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len, NET_LINK_ETHERNET); - ctx->dev_fd = eth_iface_create(ctx->if_name, false); + ctx->dev_fd = eth_iface_create(CONFIG_ETH_NATIVE_POSIX_DEV_NAME, ctx->if_name, false); if (ctx->dev_fd < 0) { LOG_ERR("Cannot create %s (%d)", ctx->if_name, -errno); } else { @@ -642,7 +642,7 @@ static int ptp_clock_get_native_posix(const struct device *clk, { ARG_UNUSED(clk); - return eth_clock_gettime(tm); + return eth_clock_gettime(&tm->second, &tm->nanosecond); } static int ptp_clock_adjust_native_posix(const struct device *clk, diff --git a/drivers/ethernet/eth_native_posix_adapt.c b/drivers/ethernet/eth_native_posix_adapt.c index 8cbda81bd3e..7e3864910dc 100644 --- a/drivers/ethernet/eth_native_posix_adapt.c +++ b/drivers/ethernet/eth_native_posix_adapt.c @@ -25,39 +25,25 @@ #include #include #include -#include +#include +#include #ifdef __linux +#include #include #endif -/* Zephyr include files. Be very careful here and only include minimum - * things needed. - */ -#define LOG_MODULE_NAME eth_posix_adapt -#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL - -#include -LOG_MODULE_REGISTER(LOG_MODULE_NAME); - -#include -#include - -#if defined(CONFIG_NET_GPTP) -#include -#endif - #include "eth_native_posix_priv.h" /* Note that we cannot create the TUN/TAP device from the setup script * as we need to get a file descriptor to communicate with the interface. */ -int eth_iface_create(const char *if_name, bool tun_only) +int eth_iface_create(const char *dev_name, const char *if_name, bool tun_only) { struct ifreq ifr; int fd, ret = -EINVAL; - fd = open(ETH_NATIVE_POSIX_DEV_NAME, O_RDWR); + fd = open(dev_name, O_RDWR); if (fd < 0) { return -errno; } @@ -98,7 +84,7 @@ static int ssystem(const char *fmt, ...) vsnprintf(cmd, sizeof(cmd), fmt, ap); va_end(ap); - posix_print_trace("%s\n", cmd); + nsi_print_trace("%s\n", cmd); ret = system(cmd); @@ -140,8 +126,7 @@ ssize_t eth_write_data(int fd, void *buf, size_t buf_len) return write(fd, buf, buf_len); } -#if defined(CONFIG_NET_GPTP) -int eth_clock_gettime(struct net_ptp_time *time) +int eth_clock_gettime(uint64_t *second, uint32_t *nanosecond) { struct timespec tp; int ret; @@ -151,17 +136,14 @@ int eth_clock_gettime(struct net_ptp_time *time) return -errno; } - time->second = tp.tv_sec; - time->nanosecond = tp.tv_nsec; + *second = (uint64_t)tp.tv_sec; + *nanosecond = (uint32_t)tp.tv_nsec; return 0; } -#endif /* CONFIG_NET_GPTP */ -#if defined(CONFIG_NET_PROMISCUOUS_MODE) int eth_promisc_mode(const char *if_name, bool enable) { return ssystem("ip link set dev %s promisc %s", if_name, enable ? "on" : "off"); } -#endif /* CONFIG_NET_PROMISCUOUS_MODE */ diff --git a/drivers/ethernet/eth_native_posix_priv.h b/drivers/ethernet/eth_native_posix_priv.h index 012f59dfe66..7ce8c19f67a 100644 --- a/drivers/ethernet/eth_native_posix_priv.h +++ b/drivers/ethernet/eth_native_posix_priv.h @@ -11,26 +11,12 @@ #ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NATIVE_POSIX_PRIV_H_ #define ZEPHYR_DRIVERS_ETHERNET_ETH_NATIVE_POSIX_PRIV_H_ -int eth_iface_create(const char *if_name, bool tun_only); +int eth_iface_create(const char *dev_name, const char *if_name, bool tun_only); int eth_iface_remove(int fd); int eth_wait_data(int fd); ssize_t eth_read_data(int fd, void *buf, size_t buf_len); ssize_t eth_write_data(int fd, void *buf, size_t buf_len); - -#if defined(CONFIG_NET_GPTP) -int eth_clock_gettime(struct net_ptp_time *time); -#endif - -#if defined(CONFIG_NET_PROMISCUOUS_MODE) +int eth_clock_gettime(uint64_t *second, uint32_t *nanosecond); int eth_promisc_mode(const char *if_name, bool enable); -#else -static inline int eth_promisc_mode(const char *if_name, bool enable) -{ - ARG_UNUSED(if_name); - ARG_UNUSED(enable); - - return -ENOTSUP; -} -#endif #endif /* ZEPHYR_DRIVERS_ETHERNET_ETH_NATIVE_POSIX_PRIV_H_ */ From 82552b86277e246e3b3f90453835167e99945f35 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 4 Oct 2023 17:37:14 +0200 Subject: [PATCH 2185/4498] samples: Bluetooth: Add rx stats for BAP Broadcast Sink Add additional RX stats for the BAP broadcast sink so that a user can easily follow how well the RX is working, and for several streams. This also adds some additional logging to better see what we are syncing to. Signed-off-by: Emil Gydesen --- .../bluetooth/broadcast_audio_sink/src/main.c | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index 1d8613386fb..6c114d80f77 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -46,7 +46,13 @@ static struct bt_le_scan_recv_info broadcaster_info; static bt_addr_le_t broadcaster_addr; static struct bt_le_per_adv_sync *pa_sync; static uint32_t broadcaster_broadcast_id; -static struct bt_bap_stream streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; +static struct broadcast_sink_stream { + struct bt_bap_stream stream; + size_t recv_cnt; + size_t loss_cnt; + size_t error_cnt; + size_t valid_cnt; +} streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)]; static struct bt_conn *broadcast_assistant_conn; static struct bt_le_ext_adv *ext_adv; @@ -67,8 +73,16 @@ static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; static void stream_started_cb(struct bt_bap_stream *stream) { + struct broadcast_sink_stream *sink_stream = + CONTAINER_OF(stream, struct broadcast_sink_stream, stream); + printk("Stream %p started\n", stream); + sink_stream->recv_cnt = 0U; + sink_stream->loss_cnt = 0U; + sink_stream->valid_cnt = 0U; + sink_stream->error_cnt = 0U; + k_sem_give(&sem_bis_synced); } @@ -88,21 +102,26 @@ static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { - static uint32_t recv_cnt; + struct broadcast_sink_stream *sink_stream = + CONTAINER_OF(stream, struct broadcast_sink_stream, stream); if (info->flags & BT_ISO_FLAGS_ERROR) { - printk("ISO receive error\n"); - return; + sink_stream->error_cnt++; } if (info->flags & BT_ISO_FLAGS_LOST) { - printk("ISO receive lost\n"); - return; + sink_stream->loss_cnt++; } - recv_cnt++; - if ((recv_cnt % 1000U) == 0U) { - printk("Received %u total ISO packets\n", recv_cnt); + if (info->flags & BT_ISO_FLAGS_VALID) { + sink_stream->valid_cnt++; + } + + sink_stream->recv_cnt++; + if ((sink_stream->recv_cnt % 1000U) == 0U) { + printk("Stream %p: received %u total ISO packets: Valid %u | Error %u | Loss %u\n", + &sink_stream->stream, sink_stream->recv_cnt, sink_stream->valid_cnt, + sink_stream->error_cnt, sink_stream->loss_cnt); } } @@ -124,9 +143,14 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap base->subgroup_count, sink); for (size_t i = 0U; i < base->subgroup_count; i++) { - for (size_t j = 0U; j < base->subgroups[i].bis_count; j++) { + const size_t bis_count = base->subgroups[i].bis_count; + + printk("Subgroup[%zu] has %zu streams\n", i, bis_count); + for (size_t j = 0U; j < bis_count; j++) { const uint8_t index = base->subgroups[i].bis_data[j].index; + printk("\tIndex 0x%02x\n", index); + base_bis_index_bitfield |= BIT(index); } } @@ -482,7 +506,7 @@ static int init(void) bt_le_scan_cb_register(&bap_scan_cb); for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { - streams[i].ops = &stream_ops; + streams[i].stream.ops = &stream_ops; } return 0; @@ -659,10 +683,12 @@ int main(void) } for (size_t i = 0U; i < ARRAY_SIZE(streams_p); i++) { - streams_p[i] = &streams[i]; + streams_p[i] = &streams[i].stream; } while (true) { + uint32_t sync_bitfield; + err = reset(); if (err != 0) { printk("Resetting failed: %d - Aborting\n", err); @@ -785,10 +811,10 @@ int main(void) continue; } - printk("Syncing to broadcast\n"); - err = bt_bap_broadcast_sink_sync(broadcast_sink, - bis_index_bitfield & requested_bis_sync, - streams_p, sink_broadcast_code); + sync_bitfield = bis_index_bitfield & requested_bis_sync; + printk("Syncing to broadcast with bitfield: 0x%08x\n", sync_bitfield); + err = bt_bap_broadcast_sink_sync(broadcast_sink, sync_bitfield, streams_p, + sink_broadcast_code); if (err != 0) { printk("Unable to sync to broadcast source: %d\n", err); return 0; From 078cec1e1f3aaf608af3b3115b5e7ea576ea864e Mon Sep 17 00:00:00 2001 From: Alexander Kaiser Date: Wed, 4 Oct 2023 10:10:15 -0600 Subject: [PATCH 2186/4498] usb: msc: Added check for negative overflow length Added a check for when current_offset plus size is less than BLOCK_SIZE. Signed-off-by: Alexander Kaiser --- subsys/usb/device/class/msc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/usb/device/class/msc.c b/subsys/usb/device/class/msc.c index 6eae1f6a3ab..37871ffdc31 100644 --- a/subsys/usb/device/class/msc.c +++ b/subsys/usb/device/class/msc.c @@ -818,6 +818,10 @@ static void thread_memory_write_done(void) uint32_t size = defered_wr_sz; size_t overflowed_len = (curr_offset + size) - BLOCK_SIZE; + if (BLOCK_SIZE > (curr_offset + size)) { + overflowed_len = 0; + } + if (overflowed_len > 0) { memmove(page, &page[BLOCK_SIZE], overflowed_len); } From 906ee538342b60cc2ef876d190d0536d4caeb79b Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 4 Oct 2023 16:09:27 +0000 Subject: [PATCH 2187/4498] drivers: i2s: i2s_mcux_sai: use clock-mux property to select SAI mux Use a new property, "clock-mux" to select the clock mux for the SAI. Previously, the clock mux was being selected using the "bits" specifier of the "clocks" phandle property, which is not the purpose of this specifier. This can be shown by the regression introduced by 5bebbb91, which changed the "bits" field to the clock gate shift (which is the intended meaning). This incidently worked for the SAI1 and SAI3 peripherals, as the lower 2 bits of the correct clock source selection (0b10) are the same as the new value placed in the "bit" specifier. For SAI2, the clock source was switched to PLL3 PDF0 by this change. To resolve this, use an explict "clock-mux" property for this selection. Fixes #63541 Signed-off-by: Daniel DeGrasse --- drivers/i2s/i2s_mcux_sai.c | 6 ++---- dts/arm/nxp/nxp_rt1010.dtsi | 4 ++++ dts/arm/nxp/nxp_rt10xx.dtsi | 10 ++++++++-- dts/arm/nxp/nxp_rt11xx.dtsi | 10 +++++++++- dts/bindings/i2s/nxp,mcux-i2s.yaml | 7 ++++++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index 5294127f759..08bcdbb6343 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 NXP Semiconductor INC. + * Copyright 2021,2023 NXP Semiconductor INC. * All rights reserved. * * SPDX-License-Identifier: Apache-2.0 @@ -1254,9 +1254,7 @@ static const struct i2s_driver_api i2s_mcux_driver_api = { \ static const struct i2s_mcux_config i2s_##i2s_id##_config = { \ .base = (I2S_Type *)DT_INST_REG_ADDR(i2s_id), \ - .clk_src = \ - DT_CLOCKS_CELL_BY_IDX(DT_DRV_INST(i2s_id), \ - 0, bits), \ + .clk_src = DT_INST_PROP(i2s_id, clock_mux), \ .clk_pre_div = DT_INST_PROP(i2s_id, pre_div), \ .clk_src_div = DT_INST_PROP(i2s_id, podf), \ .pll_src = \ diff --git a/dts/arm/nxp/nxp_rt1010.dtsi b/dts/arm/nxp/nxp_rt1010.dtsi index 00b1ce14b4e..cdd132b59df 100644 --- a/dts/arm/nxp/nxp_rt1010.dtsi +++ b/dts/arm/nxp/nxp_rt1010.dtsi @@ -272,6 +272,8 @@ #pinmux-cells = <2>; reg = <0x401e0000 0x4000>; clocks = <&ccm IMX_CCM_SAI1_CLK 0x7C 18>; + /* Source clock from Audio PLL */ + clock-mux = <2>; /* Audio PLL Output Frequency is determined by: * (Fref * (DIV_SELECT + NUM/DENOM)) / POST_DIV * = (24MHz * (32 + 77 / 100)) / 1 = 786.48 MHz @@ -310,6 +312,8 @@ #pinmux-cells = <2>; reg = <0x401e8000 0x4000>; clocks = <&ccm IMX_CCM_SAI3_CLK 0x7C 22>; + /* Source clock from Audio PLL */ + clock-mux = <2>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0x70 0xC000 0>, diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index fede96dece6..d6c247ba651 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NXP + * Copyright 2017,2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -937,11 +937,13 @@ #pinmux-cells = <2>; reg = <0x40384000 0x4000>; clocks = <&ccm IMX_CCM_SAI1_CLK 0x7C 18>; + /* Source clock from Audio PLL */ + clock-mux = <2>; /* Audio PLL Output Frequency is determined by: * (Fref * (DIV_SELECT + NUM/DENOM)) / POST_DIV * = (24MHz * (32 + 77 / 100)) / 1 = 786.48 MHz */ - pll-clocks = <&anatop 0x70 0xC000 0>, + pll-clocks = <&anatop 0x70 0xC000 0>, <&anatop 0x70 0x7F 32>, <&anatop 0x70 0x180000 1>, <&anatop 0x80 0x3FFFFFFF 77>, @@ -975,6 +977,8 @@ #pinmux-cells = <2>; reg = <0x40388000 0x4000>; clocks = <&ccm IMX_CCM_SAI2_CLK 0x7C 20>; + /* Source clock from Audio PLL */ + clock-mux = <2>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0x70 0xC000 0x0>, @@ -1000,6 +1004,8 @@ #pinmux-cells = <2>; reg = <0x4038C000 0x4000>; clocks = <&ccm IMX_CCM_SAI3_CLK 0x7C 22>; + /* Source clock from Audio PLL */ + clock-mux = <2>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0x70 0xC000 0>, diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index d3448a029b9..faf4b9cae7b 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NXP + * Copyright 2021,2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -990,6 +990,8 @@ #pinmux-cells = <2>; reg = <0x40404000 0x4000>; clocks = <&ccm IMX_CCM_SAI1_CLK 0x2004 4>; + /* Source from audio PLL */ + clock-mux = <4>; pre-div = <0>; podf = <4>; pll-clocks = <&anatop 0 0 0>, @@ -1011,6 +1013,8 @@ #pinmux-cells = <2>; reg = <0x40408000 0x4000>; clocks = <&ccm IMX_CCM_SAI2_CLK 0x2084 4>; + /* Source from audio PLL */ + clock-mux = <4>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0 0 0>, @@ -1032,6 +1036,8 @@ #pinmux-cells = <2>; reg = <0x4040c000 0x4000>; clocks = <&ccm IMX_CCM_SAI3_CLK 0x2104 4>; + /* Source from audio PLL */ + clock-mux = <4>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0 0 0>, @@ -1053,6 +1059,8 @@ #pinmux-cells = <2>; reg = <0x40c40000 0x4000>; clocks = <&ccm IMX_CCM_SAI4_CLK 0x2184 6>; + /* Source from audio PLL */ + clock-mux = <6>; pre-div = <0>; podf = <63>; pll-clocks = <&anatop 0 0 0>, diff --git a/dts/bindings/i2s/nxp,mcux-i2s.yaml b/dts/bindings/i2s/nxp,mcux-i2s.yaml index a4eae452396..25295432874 100644 --- a/dts/bindings/i2s/nxp,mcux-i2s.yaml +++ b/dts/bindings/i2s/nxp,mcux-i2s.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021, NXP +# Copyright 2021,2023 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP mcux SAI-I2S controller @@ -60,3 +60,8 @@ properties: nxp,tx-channel: type: int description: tx channel the maximum number is SOC dependent + + clock-mux: + required: true + type: int + description: Clock mux source for SAI root clock From 921104042d1b1f4c39c11a9d051c1e709314680d Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Mon, 16 Oct 2023 10:53:32 +0200 Subject: [PATCH 2188/4498] drivers: flash: enable MPU_ALLOW_FLASH_WRITE for ARM MPUs Select MPU_ALLOW_FLASH_WRITE to avoid write test failure for ARM MPUs. Signed-off-by: Jeppe Odgaard --- drivers/flash/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 8660bed13e4..ce7f92dd94a 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -52,6 +52,7 @@ config FLASH_JESD216_API config FLASH_SHELL bool "Flash shell" depends on SHELL && FLASH_PAGE_LAYOUT + select MPU_ALLOW_FLASH_WRITE if ARM_MPU default y help Enable the flash shell with flash related commands such as test, From f1ae151ef632c2916ffba9d391ac4b79aa8ea63d Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Wed, 4 Oct 2023 20:14:14 +0200 Subject: [PATCH 2189/4498] samples: flash_shell: remove sample code and use FLASH_SHELL The flash sample and flash shell have implementations that differ providing similar features. This commit removes all the code in main.c, only `main()` remains to reduce redundancy. Features or improved implementations has not been merged into the flash shell in this commit. It should be possible to do in future commits if desired. Signed-off-by: Jeppe Odgaard --- samples/drivers/flash_shell/Kconfig | 9 - samples/drivers/flash_shell/README.rst | 37 +- samples/drivers/flash_shell/prj.conf | 7 +- samples/drivers/flash_shell/src/main.c | 761 +------------------------ 4 files changed, 26 insertions(+), 788 deletions(-) delete mode 100644 samples/drivers/flash_shell/Kconfig diff --git a/samples/drivers/flash_shell/Kconfig b/samples/drivers/flash_shell/Kconfig deleted file mode 100644 index aa7016fa9ae..00000000000 --- a/samples/drivers/flash_shell/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2020, Linaro Ltd. -# SPDX-License-Identifier: Apache-2.0 - -source "Kconfig.zephyr" - -if ARM_MPU -config MPU_ALLOW_FLASH_WRITE - def_bool y -endif diff --git a/samples/drivers/flash_shell/README.rst b/samples/drivers/flash_shell/README.rst index 1c8513bf2c0..f6e1b78a38c 100644 --- a/samples/drivers/flash_shell/README.rst +++ b/samples/drivers/flash_shell/README.rst @@ -27,19 +27,24 @@ Sample Output .. code-block:: console - uart:~$ flash_sample page_count - Flash device contains 1024 pages. - uart:~$ flash_sample page_erase 1023 - Erasing page 1023 (start offset 0xffc00, size 0x400) - uart:~$ flash_sample page_write 1023 8 17 19 28 39 - Reading back written bytes: - 11 13 1c 27 - uart:~$ flash_sample page_write 1023 4 77 9 1 2 - Reading back written bytes: - 4d 09 01 02 - uart:~$ flash_sample page_read 1023 4 12 - 4d 09 01 02 | 11 13 1c 27 - ff ff ff ff - uart:~$ flash_sample page_read 1023 0 16 - ff ff ff ff | 4d 09 01 02 - 11 13 1c 27 | ff ff ff ff + uart:~$ flash page_info 0 + Page for address 0x0: + start offset: 0x0 + size: 4096 + index: 0 + uart:~$ flash erase 0x1000 + Erase success. + uart:~$ flash write 0x1000 0x12345678 0x9abcdef0 + Write OK. + Verified. + uart:~$ flash write 0x1000 0x11111111 + Write internal ERROR! + uart:~$ flash read 0x1000 0x10 + 00001000: 78 56 34 12 f0 de bc 9a ff ff ff ff ff ff ff ff |xV4..... ........| + + uart:~$ flash write 0x101c 0xabcd1234 + Write OK. + Verified. + uart:~$ flash read 0x1000 0x20 + 00001000: 78 56 34 12 f0 de bc 9a ff ff ff ff ff ff ff ff |xV4..... ........| + 00001010: ff ff ff ff ff ff ff ff ff ff ff ff 34 12 cd ab |........ ....4...| diff --git a/samples/drivers/flash_shell/prj.conf b/samples/drivers/flash_shell/prj.conf index 4e60a63bd0a..657776e96ce 100644 --- a/samples/drivers/flash_shell/prj.conf +++ b/samples/drivers/flash_shell/prj.conf @@ -2,8 +2,5 @@ CONFIG_PRINTK=y CONFIG_SHELL=y CONFIG_LOG=y CONFIG_FLASH=y -# Your flash driver may not enable this, even if it's supported. -# If that's the case and you're interested in the flash layout, enable -# it here. -# CONFIG_FLASH_PAGE_LAYOUT=y -CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_FLASH_SHELL=y +CONFIG_FLASH_SHELL_TEST_COMMANDS=y diff --git a/samples/drivers/flash_shell/src/main.c b/samples/drivers/flash_shell/src/main.c index e7e1b2d3b4b..2de337414d5 100644 --- a/samples/drivers/flash_shell/src/main.c +++ b/samples/drivers/flash_shell/src/main.c @@ -3,767 +3,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -LOG_MODULE_REGISTER(app); - -#define PR_SHELL(sh, fmt, ...) \ - shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__) -#define PR_ERROR(sh, fmt, ...) \ - shell_fprintf(sh, SHELL_ERROR, fmt, ##__VA_ARGS__) -#define PR_INFO(sh, fmt, ...) \ - shell_fprintf(sh, SHELL_INFO, fmt, ##__VA_ARGS__) -#define PR_WARNING(sh, fmt, ...) \ - shell_fprintf(sh, SHELL_WARNING, fmt, ##__VA_ARGS__) - -/* Command usage info. */ -#define WRITE_BLOCK_SIZE_HELP \ - ("Print the device's write block size. This is the smallest amount" \ - " of data which may be written to the device, in bytes.") -#define READ_HELP \ - (" \n" \ - "Read bytes from device offset .") -#define ERASE_HELP \ - (" \n\n" \ - "Erase bytes from device offset , " \ - "subject to hardware page limitations.") -#define WRITE_HELP \ - (" [... byteN]\n\n" \ - "Write given bytes, starting at device offset .\n" \ - "Pages must be erased before they can be written.") -#define WRITE_UNALIGNED_HELP \ - (" [... byteN]\n\n" \ - "Write given bytes, starting at device offset .\n" \ - "Being unaligned, affected memory areas are backed up, erased, protected" \ - " and then overwritten.\n" \ - "This command is designed to test writing to large flash pages.") -#define WRITE_PATTERN_HELP \ - (" \n\n" \ - "Writes a pattern of (0x00 0x01 .. 0xFF 0x00 ..) of length" \ - " at the offset .\n" \ - "Unaligned writing is used, i.e. protection and erasing are automated." \ - "This command is designed to test writing to large flash pages.") -#ifdef CONFIG_FLASH_PAGE_LAYOUT -#define PAGE_COUNT_HELP \ - "\n\nPrint the number of pages on the flash device." -#define PAGE_LAYOUT_HELP \ - ("[start_page] [end_page]\n\n" \ - "Print layout of flash pages in the range [start_page, end_page]," \ - " which is inclusive. By default, all pages are printed.") -#define PAGE_READ_HELP \ - (" OR \n\n" \ - "Read bytes from given page, starting at page offset ," \ - "or offset 0 if not given. No checks are made that bytes read are" \ - " all within the page.") -#define PAGE_ERASE_HELP \ - (" [num]\n\n" \ - "Erase [num] pages (default 1), starting at page .") -#define PAGE_WRITE_HELP \ - (" [... byteN]\n\n" \ - "Write given bytes to given page, starting at page offset ." \ - " No checks are made that the bytes all fall within the page." \ - " Pages must be erased before they can be written.") -#endif -#define SET_DEV_HELP \ - ("\n\n" \ - "Set flash device by name. If a flash device was not found," \ - " this command must be run first to bind a device to this module.") - -#if (CONFIG_SHELL_ARGC_MAX > 4) -#define ARGC_MAX (CONFIG_SHELL_ARGC_MAX - 4) -#else -#error Please increase CONFIG_SHELL_ARGC_MAX parameter. -#endif - -static const struct device *flash_device = - DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); - -static int check_flash_device(const struct shell *sh) -{ - if (flash_device == NULL) { - PR_ERROR(sh, "Flash device is unknown." - " Run set_device first.\n"); - return -ENODEV; - } - return 0; -} - -static int dump_buffer(const struct shell *sh, uint8_t *buf, size_t size, - uint8_t *cmp_buf) -{ - int ret = 0; - size_t i; - - for (i = 0; i < size; i++) { - /* Print each byte mismatch as error */ - if (cmp_buf != NULL && buf[i] != cmp_buf[i]) { - PR_ERROR(sh, "%02x ", buf[i]); - ret = -EIO; - } else { - PR_SHELL(sh, "%02x ", buf[i]); - } - - if ((i + 1) % 16 == 0) { - PR_SHELL(sh, "\n"); - } else if ((i + 1) % 4 == 0) { - PR_SHELL(sh, "| "); - } - } - - if (i % 16 != 0) { - PR_SHELL(sh, "\n"); - } - - return ret; -} - -static int parse_ul(const char *str, unsigned long *result) -{ - char *end; - unsigned long val; - - val = strtoul(str, &end, 0); - - if (*str == '\0' || *end != '\0') { - return -EINVAL; - } - - *result = val; - return 0; -} - -static int parse_u8(const char *str, uint8_t *result) -{ - unsigned long val; - - if (parse_ul(str, &val) || val > 0xff) { - return -EINVAL; - } - *result = (uint8_t)val; - return 0; -} - -/* Read bytes, dumping contents to console and printing on error. */ -static int do_read(const struct shell *sh, off_t offset, size_t len, - uint8_t *cmp_buf) -{ - uint8_t buf[64]; - int ret; - size_t read_len; - bool cmp_error = false; - - do { - read_len = len > sizeof(buf) ? sizeof(buf) : len; - ret = flash_read(flash_device, offset, buf, read_len); - if (ret != 0) { - PR_ERROR(sh, "flash_read error: %d\n", ret); - return ret; - } - ret = dump_buffer(sh, buf, read_len, cmp_buf); - if (ret == -EIO) { - cmp_error = true; - } - if (cmp_buf != NULL) { - cmp_buf += read_len; - } - len -= read_len; - offset += read_len; - } while (len > 0); - - if (cmp_error) { - PR_ERROR(sh, "Write verification error, unexpected values " - "marked red\n"); - } - - return 0; -} - -/* Erase area and printing on error. */ -static int do_erase(const struct shell *sh, off_t offset, size_t size) -{ - int ret; - - ret = flash_erase(flash_device, offset, size); - if (ret) { - PR_ERROR(sh, "flash_erase failed (err:%d).\n", ret); - return ret; - } - - return ret; -} - -/* Write bytes and printing on error. */ -static int do_write(const struct shell *sh, off_t offset, uint8_t *buf, - size_t len, bool read_back) -{ - int ret; - - ret = flash_write(flash_device, offset, buf, len); - if (ret) { - PR_ERROR(sh, "flash_write failed (err:%d).\n", ret); - return ret; - } - - if (read_back) { - PR_SHELL(sh, "Reading back written bytes:\n"); - ret = do_read(sh, offset, len, buf); - } - return ret; -} - -static int do_write_unaligned(const struct shell *sh, off_t offset, uint8_t *buf, - size_t len, bool read_back) -{ - int ret = 0; - size_t page_size = flash_get_write_block_size(flash_device); - size_t size_before = offset % page_size; - size_t size_after = page_size - ((size_before + len) % page_size); - size_t aligned_size = size_before + len + size_after; - off_t start_page = offset - size_before; - off_t last_page = start_page + aligned_size - page_size; - bool single_page_write = (size_before + len < page_size); - - char *before_data; - char *after_data; - - if (0 == size_before && 0 == size_after) { - /* Aligned write */ - flash_erase(flash_device, offset, len); - flash_write(flash_device, offset, buf, len); - - return 0; - } - - before_data = k_malloc(page_size); - after_data = k_malloc(page_size); - - if (!before_data || !after_data) { - PR_ERROR(sh, "No heap memory for flash manipulation\n"); - ret = -ENOMEM; - goto free_buffers; - } - - /* Stash useful data from the pages that will be affected. */ - if (single_page_write) { - /* Read old data before new data is written. */ - if (size_before) { - flash_read(flash_device, start_page, before_data, size_before); - } - /* Fill the with new data. */ - memcpy(before_data + size_before, buf, len); - /* Fill the last part of old data. */ - if (size_after) { - flash_read(flash_device, offset + len, - before_data + size_before + len, - size_after); - } - } else { - /* Multipage write, different start and end pages. */ - if (size_before) { - flash_read(flash_device, start_page, before_data, - size_before); - /* Fill the rest with new data. */ - memcpy(before_data + size_before, buf, - page_size - size_before); - } - if (size_after) { - /* Copy ending part of new data. */ - memcpy((void *)after_data, - (void *)(buf + len - - ((len + size_before) % page_size)), - page_size - size_after); - /* Copy ending part of flash page. */ - flash_read(flash_device, offset + len, - after_data + (page_size - size_after), - size_after); - } - } - - /* Erase all the pages that overlap with new data. */ - flash_erase(flash_device, start_page, aligned_size); - - /* Write stashed and new data. */ - if (single_page_write || size_before > 0) { - /* Write first page if available. */ - flash_write(flash_device, start_page, before_data, - page_size); - } - if (!single_page_write) { - size_t middle_data_len = aligned_size; - off_t middle_page_start = start_page; - off_t data_offset = (off_t)buf; - - /* Write the middle bit if available */ - if (size_before > 0) { - middle_page_start += page_size; - middle_data_len -= page_size; - data_offset += (page_size - size_before); - } - if (size_after > 0) { - middle_data_len -= page_size; - } - if (middle_data_len > 0) { - flash_write(flash_device, middle_page_start, - (const void *)data_offset, - middle_data_len); - } - - /* Write the last page if needed. */ - if (size_after > 0) { - flash_write(flash_device, last_page, after_data, - page_size); - } - } - - if (read_back) { - PR_SHELL(sh, "Reading back written bytes:\n"); - ret = do_read(sh, offset, len, buf); - } - -free_buffers: - k_free(before_data); - k_free(after_data); - - return ret; -} - -static int cmd_write_block_size(const struct shell *sh, size_t argc, - char **argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - int err = check_flash_device(sh); - - if (!err) { - PR_SHELL(sh, "%zu\n", - flash_get_write_block_size(flash_device)); - } - - return err; -} - -static int cmd_read(const struct shell *sh, size_t argc, char **argv) -{ - int err = check_flash_device(sh); - unsigned long int offset, len; - - if (err) { - goto exit; - } - - if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) { - PR_ERROR(sh, "Invalid arguments.\n"); - err = -EINVAL; - goto exit; - } - - err = do_read(sh, offset, len, NULL); - -exit: - return err; -} - -static int cmd_erase(const struct shell *sh, size_t argc, char **argv) -{ - int err = check_flash_device(sh); - unsigned long int offset; - unsigned long int size; - - if (err) { - goto exit; - } - - if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &size)) { - PR_ERROR(sh, "Invalid arguments.\n"); - err = -EINVAL; - goto exit; - } - - err = do_erase(sh, (off_t)offset, (size_t)size); -exit: - return err; -} - -static int cmd_write_template(const struct shell *sh, size_t argc, char **argv, bool unaligned) -{ - unsigned long int i, offset; - uint8_t buf[ARGC_MAX]; - - int err = check_flash_device(sh); - - if (err) { - goto exit; - } - - err = parse_ul(argv[1], &offset); - if (err) { - PR_ERROR(sh, "Invalid argument.\n"); - goto exit; - } - - if ((argc - 2) > ARGC_MAX) { - /* Can only happen if Zephyr limit is increased. */ - PR_ERROR(sh, "At most %lu bytes can be written.\n" - "In order to write more bytes please increase" - " parameter: CONFIG_SHELL_ARGC_MAX.\n", - (unsigned long)ARGC_MAX); - err = -EINVAL; - goto exit; - } - - /* skip cmd name and offset */ - argc -= 2; - argv += 2; - for (i = 0; i < argc; i++) { - if (parse_u8(argv[i], &buf[i])) { - PR_ERROR(sh, "Argument %lu (%s) is not a byte.\n" - "Bytes shall be passed in decimal" - " notation.\n", - i + 1, argv[i]); - err = -EINVAL; - goto exit; - } - } - - if (!unaligned) { - err = do_write(sh, offset, buf, i, true); - } else { - err = do_write_unaligned(sh, offset, buf, i, true); - } - -exit: - return err; -} - -static int cmd_write(const struct shell *sh, size_t argc, char **argv) -{ - return cmd_write_template(sh, argc, argv, false); -} - -static int cmd_write_unaligned(const struct shell *sh, size_t argc, char **argv) -{ - return cmd_write_template(sh, argc, argv, true); -} - -static int cmd_write_pattern(const struct shell *sh, size_t argc, char **argv) -{ - int err = check_flash_device(sh); - unsigned long int offset, len, i; - static uint8_t *buf; - - if (err) { - goto exit; - } - - if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) { - PR_ERROR(sh, "Invalid arguments.\n"); - err = -EINVAL; - goto exit; - } - - buf = k_malloc(len); - - if (!buf) { - PR_ERROR(sh, "No heap memory for data pattern\n"); - err = -ENOMEM; - goto exit; - } - - for (i = 0; i < len; i++) { - buf[i] = i & 0xFF; - } - - err = do_write_unaligned(sh, offset, buf, i, true); - - k_free(buf); - -exit: - return err; -} - -#ifdef CONFIG_FLASH_PAGE_LAYOUT -static int cmd_page_count(const struct shell *sh, size_t argc, char **argv) -{ - ARG_UNUSED(argv); - ARG_UNUSED(argc); - - int err = check_flash_device(sh); - size_t page_count; - - if (!err) { - page_count = flash_get_page_count(flash_device); - PR_SHELL(sh, "Flash device contains %lu pages.\n", - (unsigned long int)page_count); - } - - return err; -} - -struct page_layout_data { - unsigned long int start_page; - unsigned long int end_page; - const struct shell *sh; -}; - -static bool page_layout_cb(const struct flash_pages_info *info, void *datav) -{ - struct page_layout_data *data = datav; - unsigned long int sz; - - if (info->index < data->start_page) { - return true; - } else if (info->index > data->end_page) { - return false; - } - - sz = info->size; - PR_SHELL(data->sh, - "\tPage %u: start 0x%08x, length 0x%lx (%lu, %lu KB)\n", - info->index, (uint32_t)info->start_offset, sz, sz, sz / KB(1)); - return true; -} - -static int cmd_page_layout(const struct shell *sh, size_t argc, char **argv) -{ - unsigned long int start_page, end_page; - struct page_layout_data data; - - int err = check_flash_device(sh); - - if (err) { - goto bail; - } - - switch (argc) { - case 1: - start_page = 0; - end_page = flash_get_page_count(flash_device) - 1; - break; - case 2: - if (parse_ul(argv[1], &start_page)) { - err = -EINVAL; - goto bail; - } - end_page = flash_get_page_count(flash_device) - 1; - break; - case 3: - if (parse_ul(argv[1], &start_page) || - parse_ul(argv[2], &end_page)) { - err = -EINVAL; - goto bail; - } - break; - default: - PR_ERROR(sh, "Invalid argument count.\n"); - return -EINVAL; - } - - data.start_page = start_page; - data.end_page = end_page; - data.sh = sh; - flash_page_foreach(flash_device, page_layout_cb, &data); - return 0; - -bail: - PR_ERROR(sh, "Invalid arguments.\n"); - return err; -} - -static int cmd_page_read(const struct shell *sh, size_t argc, char **argv) -{ - unsigned long int page, offset, len; - struct flash_pages_info info; - int ret; - - ret = check_flash_device(sh); - if (ret) { - return ret; - } - - if (argc == 3) { - if (parse_ul(argv[1], &page) || parse_ul(argv[2], &len)) { - ret = -EINVAL; - goto bail; - } - offset = 0; - } else if (parse_ul(argv[1], &page) || parse_ul(argv[2], &offset) || - parse_ul(argv[3], &len)) { - ret = -EINVAL; - goto bail; - } - - ret = flash_get_page_info_by_idx(flash_device, page, &info); - if (ret) { - PR_ERROR(sh, "Function flash_page_info_by_idx returned an" - " error: %d\n", ret); - return ret; - } - offset += info.start_offset; - ret = do_read(sh, offset, len, NULL); - return ret; - - bail: - PR_ERROR(sh, "Invalid arguments.\n"); - return ret; -} - -static int cmd_page_erase(const struct shell *sh, size_t argc, char **argv) -{ - struct flash_pages_info info; - unsigned long int i, page, num; - int ret; - - ret = check_flash_device(sh); - if (ret) { - return ret; - } - - if (parse_ul(argv[1], &page)) { - ret = -EINVAL; - goto bail; - } - if (argc == 2) { - num = 1; - } else if (parse_ul(argv[2], &num)) { - goto bail; - } - - for (i = 0; i < num; i++) { - ret = flash_get_page_info_by_idx(flash_device, page + i, &info); - if (ret) { - PR_ERROR(sh, "flash_get_page_info_by_idx error:" - " %d\n", ret); - return ret; - } - PR_SHELL(sh, "Erasing page %u (start offset 0x%x," - " size 0x%x)\n", - info.index, (uint32_t)info.start_offset, (uint32_t)info.size); - ret = do_erase(sh, info.start_offset, (uint32_t)info.size); - if (ret) { - return ret; - } - } - - return ret; - - bail: - PR_ERROR(sh, "Invalid arguments.\n"); - return ret; -} - -static int cmd_page_write(const struct shell *sh, size_t argc, char **argv) -{ - struct flash_pages_info info; - unsigned long int page, off; - uint8_t buf[ARGC_MAX]; - size_t i; - int ret; - - ret = check_flash_device(sh); - if (ret) { - return ret; - } - - if (parse_ul(argv[1], &page) || parse_ul(argv[2], &off)) { - ret = -EINVAL; - goto bail; - } - - argc -= 3; - argv += 3; - for (i = 0; i < argc; i++) { - if (parse_u8(argv[i], &buf[i])) { - PR_ERROR(sh, "Argument %d (%s) is not a byte.\n", - (int)i + 2, argv[i]); - ret = -EINVAL; - goto bail; - } - } - - ret = flash_get_page_info_by_idx(flash_device, page, &info); - if (ret) { - PR_ERROR(sh, "flash_get_page_info_by_idx: %d\n", ret); - return ret; - } - ret = do_write(sh, info.start_offset + off, buf, i, true); - return ret; - - bail: - PR_ERROR(sh, "Invalid arguments.\n"); - return ret; -} -#endif /* CONFIG_FLASH_PAGE_LAYOUT */ - -static int cmd_set_dev(const struct shell *sh, size_t argc, char **argv) -{ - const struct device *dev; - const char *name; - - name = argv[1]; - - /* Run command. */ - dev = device_get_binding(name); - if (!dev) { - PR_ERROR(sh, "No device named %s.\n", name); - return -ENOEXEC; - } - if (flash_device) { - PR_SHELL(sh, "Leaving behind device %s\n", - flash_device->name); - } - flash_device = dev; - - return 0; -} +#include int main(void) { - if (device_is_ready(flash_device)) { - printk("Found flash controller %s.\n", flash_device->name); - printk("Flash I/O commands can be run.\n"); - } else { - flash_device = NULL; - printk("**Flash controller not ready or not found!**\n"); - printk("Run set_device to specify one " - "before using other commands.\n"); - } + printf("Flash shell sample"); + return 0; } - - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_flash, - /* Alphabetically sorted to ensure correct Tab autocompletion. */ - SHELL_CMD_ARG(erase, NULL, ERASE_HELP, cmd_erase, 3, 0), -#ifdef CONFIG_FLASH_PAGE_LAYOUT - SHELL_CMD_ARG(page_count, NULL, PAGE_COUNT_HELP, cmd_page_count, 1, 0), - SHELL_CMD_ARG(page_erase, NULL, PAGE_ERASE_HELP, cmd_page_erase, 2, 1), - SHELL_CMD_ARG(page_layout, NULL, PAGE_LAYOUT_HELP, - cmd_page_layout, 1, 2), - SHELL_CMD_ARG(page_read, NULL, PAGE_READ_HELP, cmd_page_read, 3, 1), - SHELL_CMD_ARG(page_write, NULL, PAGE_WRITE_HELP, - cmd_page_write, 3, 255), -#endif - SHELL_CMD_ARG(read, NULL, READ_HELP, cmd_read, 3, 0), - SHELL_CMD_ARG(set_device, NULL, SET_DEV_HELP, cmd_set_dev, 2, 0), - SHELL_CMD_ARG(write, NULL, WRITE_HELP, cmd_write, 3, 255), - SHELL_CMD_ARG(write_block_size, NULL, WRITE_BLOCK_SIZE_HELP, - cmd_write_block_size, 1, 0), - SHELL_CMD_ARG(write_unaligned, NULL, WRITE_UNALIGNED_HELP, - cmd_write_unaligned, 3, 255), - SHELL_CMD_ARG(write_pattern, NULL, WRITE_PATTERN_HELP, - cmd_write_pattern, 3, 255), - SHELL_SUBCMD_SET_END /* Array terminated. */ -); - -SHELL_CMD_REGISTER(flash_sample, &sub_flash, "Flash related commands.", NULL); From 50793e32a84ae28acec009e7d2fb36644cc65154 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 13:39:58 +0200 Subject: [PATCH 2190/4498] tests posix event_fd: Fix for native targets The infinite loop during the stress needs to be broken with a small delay when built for native targets. Let's add it. Note that this delay is only added for ARCH_POSIX targets and not any other. Signed-off-by: Alberto Escolar Piedras --- tests/posix/eventfd/src/stress.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/posix/eventfd/src/stress.c b/tests/posix/eventfd/src/stress.c index f16f3c7f2df..40d55671521 100644 --- a/tests/posix/eventfd/src/stress.c +++ b/tests/posix/eventfd/src/stress.c @@ -78,6 +78,7 @@ static void th_fun(void *arg1, void *arg2, void *arg3) report += report_ms; } } + Z_SPIN_DELAY(10); } printk("avg: %zu %s/s\n", (size_t)((count[id] * MSEC_PER_SEC) / end_ms), msg[id]); From 11aa5c513fb00ddcbece9f431d6fe5e568ae0282 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 13:41:25 +0200 Subject: [PATCH 2191/4498] tests posix getopt: Minor fix for native targets This test should be compiled without host headers when built without the host libC, and at the same time, it does not support building with the host libC, so let's remove the condition that includes the host libC header to avoid extra confusion. Signed-off-by: Alberto Escolar Piedras --- tests/posix/getopt/src/main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/posix/getopt/src/main.c b/tests/posix/getopt/src/main.c index b18aee1569a..158d0dd085e 100644 --- a/tests/posix/getopt/src/main.c +++ b/tests/posix/getopt/src/main.c @@ -12,11 +12,7 @@ #include #include #include -#ifdef CONFIG_ARCH_POSIX -#include -#else #include -#endif #include ZTEST_SUITE(getopt_test_suite, NULL, NULL, NULL, NULL, NULL); From 5acca099ff76a8f580ee0cb7c378cb8f1f656b35 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 14:51:02 +0200 Subject: [PATCH 2192/4498] POSIX API: Fix posix_types.h for native builds The inclusion of the compiler provided sys/types.h should depend on not using the host C library, and not just of building for a native target. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/posix/posix_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/posix/posix_types.h b/include/zephyr/posix/posix_types.h index ed56e78c225..73a7485f000 100644 --- a/include/zephyr/posix/posix_types.h +++ b/include/zephyr/posix/posix_types.h @@ -7,7 +7,7 @@ #ifndef ZEPHYR_INCLUDE_POSIX_TYPES_H_ #define ZEPHYR_INCLUDE_POSIX_TYPES_H_ -#ifndef CONFIG_ARCH_POSIX +#if !(defined(CONFIG_ARCH_POSIX) && defined(CONFIG_EXTERNAL_LIBC)) #include #endif From 826c54efc997b88bb57963fa36ec1791271a28f1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 15:15:32 +0200 Subject: [PATCH 2193/4498] tests posix pthread_pressure: Fix for native targtets The infinite loop during the test needs to be broken with a small delay when built for native targets. Let's add it. Note that this delay is only added for ARCH_POSIX targets and not any other. Signed-off-by: Alberto Escolar Piedras --- tests/posix/pthread_pressure/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/posix/pthread_pressure/src/main.c b/tests/posix/pthread_pressure/src/main.c index adab1ba7ff7..c7881de4e6f 100644 --- a/tests/posix/pthread_pressure/src/main.c +++ b/tests/posix/pthread_pressure/src/main.c @@ -122,6 +122,7 @@ static void test_create_join_common(const char *tag, create_fn create, join_fn j print_stats(now_ms, end_ms); } + Z_SPIN_DELAY(100); } while (end_ms > now_ms); print_stats(now_ms, end_ms); From 5f8057e26211e0ce69c782adfbfe511fa27b598d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 13:07:00 +0200 Subject: [PATCH 2194/4498] libC kconfig: default to PICOLIBC for NATIVE_LIBRARY if POSIX_API When building with the POSIX_API we cannot use the host libC. When using GETOPT it is similarly quite difficult for users to use the host libC. So to make it easier for users, let's just default to PICOBLIC in those cases, while we continue defaulting to the host library in other cases so users can use the Linux APIs for whatever test functionality they want. Signed-off-by: Alberto Escolar Piedras --- lib/libc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 4ebf556dd5c..540dc1e782a 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -53,7 +53,7 @@ menu "C Library" choice LIBC_IMPLEMENTATION prompt "C Library Implementation" - default EXTERNAL_LIBC if NATIVE_BUILD + default EXTERNAL_LIBC if NATIVE_BUILD && !(NATIVE_LIBRARY && (POSIX_API || GETOPT)) default PICOLIBC default NEWLIB_LIBC if REQUIRES_FULL_LIBC default MINIMAL_LIBC From a12dff48ac56bf2caa484dd5c21893700d3086cf Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 12 Oct 2023 15:41:52 +0200 Subject: [PATCH 2195/4498] samples net/posix: Rename old Makefiles and clarify READMEs The old Makefiles which can be used to build this samples directly as Linux apps and the description in the READMEs could be quite missleading. Building this apps in this way has nothing to do with the Zephyr native_posix/sim targets. This is about building them as actual Linux applications without Zephyr or any HW models. So let's rename the Makefiles and change the description in the docs to avoid confusion. Signed-off-by: Alberto Escolar Piedras --- .../big_http_download/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/big_http_download/README.rst | 4 ++-- .../dumb_http_server/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/dumb_http_server/README.rst | 4 ++-- samples/net/sockets/echo/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/echo/README.rst | 4 ++-- .../net/sockets/echo_async/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/echo_async/README.rst | 4 ++-- .../echo_async_select/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/echo_async_select/README.rst | 4 ++-- .../net/sockets/http_get/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/http_get/README.rst | 4 ++-- .../net/sockets/socketpair/{Makefile.posix => Makefile.host} | 0 samples/net/sockets/socketpair/README.rst | 4 ++-- samples/posix/eventfd/{Makefile.posix => Makefile.host} | 0 samples/posix/gettimeofday/{Makefile.posix => Makefile.host} | 0 samples/posix/gettimeofday/README.rst | 5 ++--- 17 files changed, 16 insertions(+), 17 deletions(-) rename samples/net/sockets/big_http_download/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/dumb_http_server/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/echo/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/echo_async/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/echo_async_select/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/http_get/{Makefile.posix => Makefile.host} (100%) rename samples/net/sockets/socketpair/{Makefile.posix => Makefile.host} (100%) rename samples/posix/eventfd/{Makefile.posix => Makefile.host} (100%) rename samples/posix/gettimeofday/{Makefile.posix => Makefile.host} (100%) diff --git a/samples/net/sockets/big_http_download/Makefile.posix b/samples/net/sockets/big_http_download/Makefile.host similarity index 100% rename from samples/net/sockets/big_http_download/Makefile.posix rename to samples/net/sockets/big_http_download/Makefile.host diff --git a/samples/net/sockets/big_http_download/README.rst b/samples/net/sockets/big_http_download/README.rst index d0b4551648b..b3bf8e7f2e3 100644 --- a/samples/net/sockets/big_http_download/README.rst +++ b/samples/net/sockets/big_http_download/README.rst @@ -96,11 +96,11 @@ Running application on POSIX Host The same application source code can be built for a POSIX system, e.g. Linux. -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/dumb_http_server/Makefile.posix b/samples/net/sockets/dumb_http_server/Makefile.host similarity index 100% rename from samples/net/sockets/dumb_http_server/Makefile.posix rename to samples/net/sockets/dumb_http_server/Makefile.host diff --git a/samples/net/sockets/dumb_http_server/README.rst b/samples/net/sockets/dumb_http_server/README.rst index 56e6ac281e4..659f94c82cd 100644 --- a/samples/net/sockets/dumb_http_server/README.rst +++ b/samples/net/sockets/dumb_http_server/README.rst @@ -64,11 +64,11 @@ The same application source code can be built for a POSIX system, e.g. Linux. (Note: if you look at the source, you will see that the code is the same except the header files are different for Zephyr vs POSIX.) -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/echo/Makefile.posix b/samples/net/sockets/echo/Makefile.host similarity index 100% rename from samples/net/sockets/echo/Makefile.posix rename to samples/net/sockets/echo/Makefile.host diff --git a/samples/net/sockets/echo/README.rst b/samples/net/sockets/echo/README.rst index 005036ca538..8a409b9e8f1 100644 --- a/samples/net/sockets/echo/README.rst +++ b/samples/net/sockets/echo/README.rst @@ -51,11 +51,11 @@ The same application source code can be built for a POSIX system, e.g. Linux. (Note: if you look at the source, you will see that the code is the same except the header files are different for Zephyr vs POSIX.) -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/echo_async/Makefile.posix b/samples/net/sockets/echo_async/Makefile.host similarity index 100% rename from samples/net/sockets/echo_async/Makefile.posix rename to samples/net/sockets/echo_async/Makefile.host diff --git a/samples/net/sockets/echo_async/README.rst b/samples/net/sockets/echo_async/README.rst index 0499973fc2e..826b3ffbda5 100644 --- a/samples/net/sockets/echo_async/README.rst +++ b/samples/net/sockets/echo_async/README.rst @@ -57,11 +57,11 @@ Linux. (Note: if you look at the source, you will see that the code is the same except the header files are different for Zephyr vs POSIX, and there's an additional option to set for Linux to make a socket IPv6-only). -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/echo_async_select/Makefile.posix b/samples/net/sockets/echo_async_select/Makefile.host similarity index 100% rename from samples/net/sockets/echo_async_select/Makefile.posix rename to samples/net/sockets/echo_async_select/Makefile.host diff --git a/samples/net/sockets/echo_async_select/README.rst b/samples/net/sockets/echo_async_select/README.rst index cc2b48735d8..963b1005928 100644 --- a/samples/net/sockets/echo_async_select/README.rst +++ b/samples/net/sockets/echo_async_select/README.rst @@ -55,11 +55,11 @@ Linux. (Note: if you look at the source, you will see that the code is the same except the header files are different for Zephyr vs POSIX, and there's an additional option to set for Linux to make a socket IPv6-only). -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/http_get/Makefile.posix b/samples/net/sockets/http_get/Makefile.host similarity index 100% rename from samples/net/sockets/http_get/Makefile.posix rename to samples/net/sockets/http_get/Makefile.host diff --git a/samples/net/sockets/http_get/README.rst b/samples/net/sockets/http_get/README.rst index 790b9756f31..09bfb2050d1 100644 --- a/samples/net/sockets/http_get/README.rst +++ b/samples/net/sockets/http_get/README.rst @@ -76,11 +76,11 @@ The same application source code can be built for a POSIX system, e.g. Linux. (Note: if you look at the source, you will see that the code is the same except the header files are different for Zephyr vs POSIX.) -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/net/sockets/socketpair/Makefile.posix b/samples/net/sockets/socketpair/Makefile.host similarity index 100% rename from samples/net/sockets/socketpair/Makefile.posix rename to samples/net/sockets/socketpair/Makefile.host diff --git a/samples/net/sockets/socketpair/README.rst b/samples/net/sockets/socketpair/README.rst index 3dce3caea7e..948a2b2d8bf 100644 --- a/samples/net/sockets/socketpair/README.rst +++ b/samples/net/sockets/socketpair/README.rst @@ -62,11 +62,11 @@ Running application on POSIX Host The same application source code can be built for a POSIX system, e.g. Linux. -To build for a host POSIX OS: +To build: .. code-block:: console - $ make -f Makefile.posix + $ make -f Makefile.host To run: diff --git a/samples/posix/eventfd/Makefile.posix b/samples/posix/eventfd/Makefile.host similarity index 100% rename from samples/posix/eventfd/Makefile.posix rename to samples/posix/eventfd/Makefile.host diff --git a/samples/posix/gettimeofday/Makefile.posix b/samples/posix/gettimeofday/Makefile.host similarity index 100% rename from samples/posix/gettimeofday/Makefile.posix rename to samples/posix/gettimeofday/Makefile.host diff --git a/samples/posix/gettimeofday/README.rst b/samples/posix/gettimeofday/README.rst index c2c5def96d8..c01f1c65e33 100644 --- a/samples/posix/gettimeofday/README.rst +++ b/samples/posix/gettimeofday/README.rst @@ -34,9 +34,8 @@ on QEMU as follows: :goals: run :compact: -For comparison, a version for native POSIX operating systems (e.g. Linux) -can be built using: +For comparison, to build directly for your host OS if it is POSIX compliant (for ex. Linux): .. code-block:: console - make -f Makefile.posix + make -f Makefile.host From b435dc1c6a2b91c33533c920b5ac26598e27b61d Mon Sep 17 00:00:00 2001 From: Michele Imbriani - Oticon Date: Thu, 5 Oct 2023 14:20:01 +0200 Subject: [PATCH 2196/4498] bluetooth: shell: Fixed logic in is_substring function Fixed the character check in is_substring function. Signed-off-by: Michele Imbriani - Oticon --- subsys/bluetooth/shell/bt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index 37e817a3aa7..3f1af44de6f 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -169,7 +169,7 @@ static bool is_substring(const char *substr, const char *str) } for (size_t pos = 0; pos < str_len; pos++) { - if (tolower(substr[0]) == tolower(str[pos])) { + if (tolower(substr[pos]) == tolower(str[pos])) { if (pos + sub_str_len > str_len) { return false; } From a8f2dc21b5c5b0a70b176cb58c93eb12ffd0ad6b Mon Sep 17 00:00:00 2001 From: Michele Imbriani - Oticon Date: Thu, 5 Oct 2023 12:41:38 +0200 Subject: [PATCH 2197/4498] bluetooth: audio: added broadcast source filtering Added filtering the broadcast sources by CONFIG_BT_DEVICE_NAME. Signed-off-by: Michele Imbriani - Oticon --- .../bluetooth/broadcast_audio_sink/Kconfig | 7 +++ .../bluetooth/broadcast_audio_sink/README.rst | 4 ++ .../bluetooth/broadcast_audio_sink/src/main.c | 63 ++++++++++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/samples/bluetooth/broadcast_audio_sink/Kconfig b/samples/bluetooth/broadcast_audio_sink/Kconfig index 7a61a7b64fc..189c9f210a2 100644 --- a/samples/bluetooth/broadcast_audio_sink/Kconfig +++ b/samples/bluetooth/broadcast_audio_sink/Kconfig @@ -28,4 +28,11 @@ config SCAN_DELAY Time to advertise connectable for a Broadcast Assistant to connect before starting scanning for Broadcast Sources. +config TARGET_BROADCAST_NAME + string "Target Broadcast Device Name" + default "" + help + Name of target broadcast device. If not empty string, sink device + will only listen to the specified broadcast source. Not case sensitive. + source "Kconfig.zephyr" diff --git a/samples/bluetooth/broadcast_audio_sink/README.rst b/samples/bluetooth/broadcast_audio_sink/README.rst index cb0aabc970d..42bcc2a2c0a 100644 --- a/samples/bluetooth/broadcast_audio_sink/README.rst +++ b/samples/bluetooth/broadcast_audio_sink/README.rst @@ -23,4 +23,8 @@ This sample can be found under Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. +Use `CONFIG_TARGET_BROADCAST_NAME` Kconfig to specify the name (CONFIG_BT_DEVICE_NAME) +of a broadcast source to listen to. With default value (empty string), sink +device will listen to all available broadcast sources. + See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index 6c114d80f77..763647b688c 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + #include #include #include @@ -25,6 +28,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD), #define INVALID_BROADCAST_ID (BT_AUDIO_BROADCAST_ID_MAX + 1) #define SYNC_RETRY_COUNT 6 /* similar to retries for connections */ #define PA_SYNC_SKIP 5 +#define NAME_LEN sizeof(CONFIG_TARGET_BROADCAST_NAME) + 1 static K_SEM_DEFINE(sem_connected, 0U, 1U); static K_SEM_DEFINE(sem_disconnected, 0U, 1U); @@ -57,6 +61,7 @@ static struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)]; static struct bt_conn *broadcast_assistant_conn; static struct bt_le_ext_adv *ext_adv; + static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_24KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 60u, 1u, @@ -444,9 +449,59 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) return false; } +static bool is_substring(const char *substr, const char *str) +{ + const size_t str_len = strlen(str); + const size_t sub_str_len = strlen(substr); + + if (sub_str_len > str_len) { + return false; + } + + for (size_t pos = 0; pos < str_len; pos++) { + if (tolower(substr[pos]) == tolower(str[pos])) { + if (pos + sub_str_len > str_len) { + return false; + } + + if (strncasecmp(substr, &str[pos], sub_str_len) == 0) { + return true; + } + } + } + + return false; +} + +static bool data_cb(struct bt_data *data, void *user_data) +{ + char *name = user_data; + + switch (data->type) { + case BT_DATA_NAME_SHORTENED: + case BT_DATA_NAME_COMPLETE: + case BT_DATA_BROADCAST_NAME: + memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1)); + return false; + default: + return true; + } +} + static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) { if (info->interval != 0U) { + /* call to bt_data_parse consumes netbufs so shallow clone for verbose output */ + if (strlen(CONFIG_TARGET_BROADCAST_NAME) > 0U) { + struct net_buf_simple buf_copy; + char name[NAME_LEN] = {0}; + + net_buf_simple_clone(ad, &buf_copy); + bt_data_parse(&buf_copy, data_cb, name); + if (!(is_substring(CONFIG_TARGET_BROADCAST_NAME, name))) { + return; + } + } bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info); } } @@ -735,7 +790,13 @@ int main(void) } } - printk("Scanning for broadcast sources\n"); + if (strlen(CONFIG_TARGET_BROADCAST_NAME) > 0U) { + printk("Scanning for broadcast sources containing`" + CONFIG_TARGET_BROADCAST_NAME "`\n"); + } else { + printk("Scanning for broadcast sources\n"); + } + err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL); if (err != 0 && err != -EALREADY) { printk("Unable to start scan for broadcast sources: %d\n", From 5b9a7d0553c3e518cba52a6b991c6e08b4bf5758 Mon Sep 17 00:00:00 2001 From: Adrian Wojak Date: Thu, 5 Oct 2023 13:36:04 +0200 Subject: [PATCH 2198/4498] drivers/sensor: lis2dw12: add wakeup_duration support Add wakeup_duration support. (WAKE_DUR in WAKE_UP_DUR) Value is configurable through DT per instance. Signed-off-by: Adrian Wojak --- drivers/sensor/lis2dw12/lis2dw12.c | 16 ++++++++++++++++ drivers/sensor/lis2dw12/lis2dw12.h | 3 +++ dts/bindings/sensor/st,lis2dw12-common.yaml | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/drivers/sensor/lis2dw12/lis2dw12.c b/drivers/sensor/lis2dw12/lis2dw12.c index 2f77cbbf8c8..97452d78c41 100644 --- a/drivers/sensor/lis2dw12/lis2dw12.c +++ b/drivers/sensor/lis2dw12/lis2dw12.c @@ -476,6 +476,14 @@ static int lis2dw12_init(const struct device *dev) return ret; } +#ifdef CONFIG_LIS2DW12_THRESHOLD + ret = lis2dw12_wkup_dur_set(ctx, cfg->wakeup_duration); + if (ret < 0) { + LOG_ERR("wakeup duration config error %d", ret); + return ret; + } +#endif /* CONFIG_LIS2DW12_THRESHOLD */ + return 0; } @@ -521,6 +529,13 @@ static int lis2dw12_init(const struct device *dev) #define LIS2DW12_CONFIG_FREEFALL(inst) #endif /* CONFIG_LIS2DW12_FREEFALL */ +#ifdef CONFIG_LIS2DW12_THRESHOLD +#define LIS2DW12_CONFIG_THRESHOLD(inst) \ + .wakeup_duration = DT_INST_PROP(inst, wakeup_duration), +#else +#define LIS2DW12_CONFIG_THRESHOLD(inst) +#endif + #ifdef CONFIG_LIS2DW12_TRIGGER #define LIS2DW12_CFG_IRQ(inst) \ .gpio_int = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \ @@ -540,6 +555,7 @@ static int lis2dw12_init(const struct device *dev) .drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \ LIS2DW12_CONFIG_TAP(inst) \ LIS2DW12_CONFIG_FREEFALL(inst) \ + LIS2DW12_CONFIG_THRESHOLD(inst) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \ (LIS2DW12_CFG_IRQ(inst)), ()) diff --git a/drivers/sensor/lis2dw12/lis2dw12.h b/drivers/sensor/lis2dw12/lis2dw12.h index ba61a764114..d52312193c0 100644 --- a/drivers/sensor/lis2dw12/lis2dw12.h +++ b/drivers/sensor/lis2dw12/lis2dw12.h @@ -96,6 +96,9 @@ struct lis2dw12_device_config { uint8_t freefall_duration; uint8_t freefall_threshold; #endif /* CONFIG_LIS2DW12_FREEFALL */ +#ifdef CONFIG_LIS2DW12_THRESHOLD + uint8_t wakeup_duration; +#endif /* CONFIG_LIS2DW12_THRESHOLD */ #endif /* CONFIG_LIS2DW12_TRIGGER */ }; diff --git a/dts/bindings/sensor/st,lis2dw12-common.yaml b/dts/bindings/sensor/st,lis2dw12-common.yaml index 635e9d9e9d5..364e4320849 100644 --- a/dts/bindings/sensor/st,lis2dw12-common.yaml +++ b/dts/bindings/sensor/st,lis2dw12-common.yaml @@ -246,3 +246,19 @@ properties: - 5 - 6 - 7 + + wakeup-duration: + type: int + default: 0 + description: | + The wakeup duration. Default value is the register reset value. + If the accelerometer readings of the all axes are higher + than the wakeup threshold value for the wakeup duration long, + then a wakeup trigger occurs. This value is 2 bits long in the + register and 1 LSB = 1 * 1/ODR. + + enum: + - 0 + - 1 + - 2 + - 3 From 6054714a0879c8db101418ec3275a2763464939a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 6 Oct 2023 11:16:20 +0200 Subject: [PATCH 2199/4498] Bluetooth: BAP: Add PSN debug log support Add a Kconfig that enables support for logging and debugging invalid sequence numbers. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/bap.h | 4 ++++ subsys/bluetooth/audio/Kconfig.bap | 9 +++++++++ subsys/bluetooth/audio/bap_stream.c | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index faa51923d0e..1436f38494e 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -484,6 +484,10 @@ struct bt_bap_stream { /** Stream user data */ void *user_data; +#if defined(CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM) + uint16_t _prev_seq_num; +#endif /* CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM */ + /* Internally used list node */ sys_snode_t _node; }; diff --git a/subsys/bluetooth/audio/Kconfig.bap b/subsys/bluetooth/audio/Kconfig.bap index 64c07ca60d7..0b5e1c3e291 100644 --- a/subsys/bluetooth/audio/Kconfig.bap +++ b/subsys/bluetooth/audio/Kconfig.bap @@ -277,5 +277,14 @@ config BT_BAP_STREAM default y if BT_ASCS || BT_BAP_UNICAST_CLIENT || \ BT_BAP_BROADCAST_SOURCE || BT_BAP_BROADCAST_SINK +config BT_BAP_DEBUG_STREAM_SEQ_NUM + bool "Bluetooth Audio Stream sequence number debug" + depends on BT_BAP_STREAM_LOG_LEVEL >= BT_BAP_STREAM_LOG_LEVEL_WRN + default y + help + Use this option to enable Bluetooth Audio Stream sequence number debugging logs for + the Bluetooth Audio functionality. This will provide a warning if the application + provides unexpected sequence numbers. + rsource "Kconfig.pacs" rsource "Kconfig.ascs" diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 0c7f67f326c..23e5bb8564b 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -277,6 +277,16 @@ int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, return -EBADMSG; } +#if defined(CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM) + if (stream->_prev_seq_num != 0U && seq_num != 0U && + (stream->_prev_seq_num + 1U) != seq_num) { + LOG_WRN("Unexpected seq_num diff between %u and %u for %p", stream->_prev_seq_num, + seq_num, stream); + } + + stream->_prev_seq_num = seq_num; +#endif /* CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM */ + /* TODO: Add checks for broadcast sink */ return bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream), From 5c1daef5ab6c510be67e449e3c73b880969aa81f Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 5 Oct 2023 13:20:57 +0200 Subject: [PATCH 2200/4498] drivers: spi: nrfx: Add SPIM Kconfig symbols for new instances Add support for upcomming SPIM instances. Signed-off-by: Adam Wojasinski --- drivers/spi/Kconfig.nrfx | 15 ++++++ modules/hal_nordic/nrfx/Kconfig | 75 ++++++++++++++++++++++++++ modules/hal_nordic/nrfx/nrfx_config.h | 45 ++++++++++++++++ soc/arm/nordic_nrf/Kconfig.peripherals | 45 ++++++++++++++++ 4 files changed, 180 insertions(+) diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index a1a2182c265..c185efa9f8f 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -27,6 +27,21 @@ config SPI_NRFX_SPIM select NRFX_SPIM2 if HAS_HW_NRF_SPIM2 select NRFX_SPIM3 if HAS_HW_NRF_SPIM3 select NRFX_SPIM4 if HAS_HW_NRF_SPIM4 + select NRFX_SPIM00 if HAS_HW_NRF_SPIM00 + select NRFX_SPIM20 if HAS_HW_NRF_SPIM20 + select NRFX_SPIM21 if HAS_HW_NRF_SPIM21 + select NRFX_SPIM22 if HAS_HW_NRF_SPIM22 + select NRFX_SPIM30 if HAS_HW_NRF_SPIM30 + select NRFX_SPIM120 if HAS_HW_NRF_SPIM120 + select NRFX_SPIM121 if HAS_HW_NRF_SPIM121 + select NRFX_SPIM130 if HAS_HW_NRF_SPIM130 + select NRFX_SPIM131 if HAS_HW_NRF_SPIM131 + select NRFX_SPIM132 if HAS_HW_NRF_SPIM132 + select NRFX_SPIM133 if HAS_HW_NRF_SPIM133 + select NRFX_SPIM134 if HAS_HW_NRF_SPIM134 + select NRFX_SPIM135 if HAS_HW_NRF_SPIM135 + select NRFX_SPIM136 if HAS_HW_NRF_SPIM136 + select NRFX_SPIM137 if HAS_HW_NRF_SPIM137 config SPI_NRFX_SPIS def_bool y diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 41b9c40c9a9..e1d49946a4c 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -230,6 +230,81 @@ config NRFX_SPIM4 depends on $(dt_nodelabel_has_compat,spi4,$(DT_COMPAT_NORDIC_NRF_SPIM)) select NRFX_SPIM +config NRFX_SPIM00 + bool "SPIM00 driver instance" + depends on $(dt_nodelabel_has_compat,spi00,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM20 + bool "SPIM20 driver instance" + depends on $(dt_nodelabel_has_compat,spi20,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM21 + bool "SPIM21 driver instance" + depends on $(dt_nodelabel_has_compat,spi21,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM22 + bool "SPIM22 driver instance" + depends on $(dt_nodelabel_has_compat,spi22,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM30 + bool "SPIM30 driver instance" + depends on $(dt_nodelabel_has_compat,spi30,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM120 + bool "SPIM120 driver instance" + depends on $(dt_nodelabel_has_compat,spi120,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM121 + bool "SPIM121 driver instance" + depends on $(dt_nodelabel_has_compat,spi121,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM130 + bool "SPIM130 driver instance" + depends on $(dt_nodelabel_has_compat,spi130,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM131 + bool "SPIM131 driver instance" + depends on $(dt_nodelabel_has_compat,spi131,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM132 + bool "SPIM132 driver instance" + depends on $(dt_nodelabel_has_compat,spi132,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM133 + bool "SPIM133 driver instance" + depends on $(dt_nodelabel_has_compat,spi133,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM134 + bool "SPIM134 driver instance" + depends on $(dt_nodelabel_has_compat,spi134,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM135 + bool "SPIM135 driver instance" + depends on $(dt_nodelabel_has_compat,spi135,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM136 + bool "SPIM136 driver instance" + depends on $(dt_nodelabel_has_compat,spi136,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + +config NRFX_SPIM137 + bool "SPIM137 driver instance" + depends on $(dt_nodelabel_has_compat,spi137,$(DT_COMPAT_NORDIC_NRF_SPIM)) + select NRFX_SPIM + config NRFX_SPIS bool diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index a843e96c3ba..0df5393d250 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -320,6 +320,51 @@ DT_PROP(DT_NODELABEL(spi4), rx_delay_supported)) #define NRFX_SPIM_EXTENDED_ENABLED 1 #endif +#ifdef CONFIG_NRFX_SPIM00 +#define NRFX_SPIM00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM20 +#define NRFX_SPIM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM21 +#define NRFX_SPIM21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM22 +#define NRFX_SPIM22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM30 +#define NRFX_SPIM30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM120 +#define NRFX_SPIM120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM121 +#define NRFX_SPIM121_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM130 +#define NRFX_SPIM130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM131 +#define NRFX_SPIM131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM132 +#define NRFX_SPIM132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM133 +#define NRFX_SPIM133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM134 +#define NRFX_SPIM134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM135 +#define NRFX_SPIM135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM136 +#define NRFX_SPIM136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM137 +#define NRFX_SPIM137_ENABLED 1 +#endif #ifdef CONFIG_NRFX_SPIS #define NRFX_SPIS_ENABLED 1 diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index 9a4152a6d84..eea79e5260e 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -192,6 +192,51 @@ config HAS_HW_NRF_SPIM3 config HAS_HW_NRF_SPIM4 def_bool $(dt_nodelabel_enabled_with_compat,spi4,$(DT_COMPAT_NORDIC_NRF_SPIM)) +config HAS_HW_NRF_SPIM00 + def_bool $(dt_nodelabel_enabled_with_compat,spi00,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM20 + def_bool $(dt_nodelabel_enabled_with_compat,spi20,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM21 + def_bool $(dt_nodelabel_enabled_with_compat,spi21,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM22 + def_bool $(dt_nodelabel_enabled_with_compat,spi22,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM30 + def_bool $(dt_nodelabel_enabled_with_compat,spi30,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM120 + def_bool $(dt_nodelabel_enabled_with_compat,spi120,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM121 + def_bool $(dt_nodelabel_enabled_with_compat,spi121,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM130 + def_bool $(dt_nodelabel_enabled_with_compat,spi130,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM131 + def_bool $(dt_nodelabel_enabled_with_compat,spi131,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM132 + def_bool $(dt_nodelabel_enabled_with_compat,spi132,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM133 + def_bool $(dt_nodelabel_enabled_with_compat,spi133,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM134 + def_bool $(dt_nodelabel_enabled_with_compat,spi134,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM135 + def_bool $(dt_nodelabel_enabled_with_compat,spi135,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM136 + def_bool $(dt_nodelabel_enabled_with_compat,spi136,$(DT_COMPAT_NORDIC_NRF_SPIM)) + +config HAS_HW_NRF_SPIM137 + def_bool $(dt_nodelabel_enabled_with_compat,spi137,$(DT_COMPAT_NORDIC_NRF_SPIM)) + config HAS_HW_NRF_SPIS0 def_bool $(dt_nodelabel_enabled_with_compat,spi0,$(DT_COMPAT_NORDIC_NRF_SPIS)) From 30b8d4ca9992d9123182a98125d3b967cc1721d4 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 5 Oct 2023 09:15:24 +0200 Subject: [PATCH 2201/4498] drivers: spi: spi_nrfx_spim: Add new SPIM instances in driver Add support for new instances. Signed-off-by: Adam Wojasinski --- drivers/spi/spi_nrfx_spim.c | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 256250b5d08..8b187f54c52 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -672,3 +672,63 @@ SPI_NRFX_SPIM_DEFINE(3); #ifdef CONFIG_HAS_HW_NRF_SPIM4 SPI_NRFX_SPIM_DEFINE(4); #endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM00 +SPI_NRFX_SPIM_DEFINE(00); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM20 +SPI_NRFX_SPIM_DEFINE(20); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM21 +SPI_NRFX_SPIM_DEFINE(21); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM22 +SPI_NRFX_SPIM_DEFINE(22); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM30 +SPI_NRFX_SPIM_DEFINE(30); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM120 +SPI_NRFX_SPIM_DEFINE(120); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM121 +SPI_NRFX_SPIM_DEFINE(121); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM130 +SPI_NRFX_SPIM_DEFINE(130); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM131 +SPI_NRFX_SPIM_DEFINE(131); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM132 +SPI_NRFX_SPIM_DEFINE(132); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM133 +SPI_NRFX_SPIM_DEFINE(133); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM134 +SPI_NRFX_SPIM_DEFINE(134); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM135 +SPI_NRFX_SPIM_DEFINE(135); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM136 +SPI_NRFX_SPIM_DEFINE(136); +#endif + +#ifdef CONFIG_HAS_HW_NRF_SPIM137 +SPI_NRFX_SPIM_DEFINE(137); +#endif From 78b4735e07fee8f8b420e774536fb59a6cce9ab3 Mon Sep 17 00:00:00 2001 From: Dennis Grijalva Date: Fri, 6 Oct 2023 09:56:07 -0700 Subject: [PATCH 2202/4498] drivers: led: led_pwm: Fix PM callback error logging If the underlying PWM device does not have a PM callback, the PWM LED driver will flood the console with error logs. The change ignores the error if there is no PM callback for the PWM device. Signed-off-by: Dennis Grijalva --- drivers/led/led_pwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/led/led_pwm.c b/drivers/led/led_pwm.c index 72cb616a6e5..7a860ec97b7 100644 --- a/drivers/led/led_pwm.c +++ b/drivers/led/led_pwm.c @@ -116,7 +116,7 @@ static int led_pwm_pm_action(const struct device *dev, err = pm_device_action_run(led->dev, action); if (err && (err != -EALREADY)) { - LOG_ERR("Cannot switch PWM %p power state", led->dev); + LOG_DBG("Cannot switch PWM %p power state (err = %d)", led->dev, err); } } From a9aad1de31ebe9a569c7163c72ad8ba459ac6cc1 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 6 Oct 2023 17:38:16 -0500 Subject: [PATCH 2203/4498] samples: modules: lvgl: enable widgets demo Enable LVGL widgets demo within Zephyr. This demo requires additional stack and heap space in order to execute correctly, so raise the stack and heap size to enable it to run. Signed-off-by: Daniel DeGrasse --- samples/modules/lvgl/demos/CMakeLists.txt | 7 +++++++ samples/modules/lvgl/demos/Kconfig | 6 ++++++ samples/modules/lvgl/demos/prj.conf | 4 ++-- samples/modules/lvgl/demos/src/main.c | 6 ++++-- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt index 78185c61196..c80e3b4364b 100644 --- a/samples/modules/lvgl/demos/CMakeLists.txt +++ b/samples/modules/lvgl/demos/CMakeLists.txt @@ -81,3 +81,10 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE ${LVGL_DIR}/demos/stress/lv_demo_stress.c ) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE + ${LVGL_DIR}/demos/widgets/assets/img_clothes.c + ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c + ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c + ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c +) diff --git a/samples/modules/lvgl/demos/Kconfig b/samples/modules/lvgl/demos/Kconfig index 01cf2f40195..6f61694f651 100644 --- a/samples/modules/lvgl/demos/Kconfig +++ b/samples/modules/lvgl/demos/Kconfig @@ -25,6 +25,12 @@ config LV_Z_DEMO_STRESS help Build stress testing demo application. +config LV_Z_DEMO_WIDGETS + bool "LVGL widgets demo" + select LV_USE_DEMO_WIDGETS + help + Build stress testing demo application. + endchoice source "Kconfig.zephyr" diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf index 0b7217242f2..3392d5c4fd3 100644 --- a/samples/modules/lvgl/demos/prj.conf +++ b/samples/modules/lvgl/demos/prj.conf @@ -1,9 +1,9 @@ -CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=4096 CONFIG_LOG=y CONFIG_SHELL=y CONFIG_LVGL=y -CONFIG_LV_Z_MEM_POOL_SIZE=16384 +CONFIG_LV_Z_MEM_POOL_SIZE=49152 CONFIG_LV_Z_SHELL=y CONFIG_LV_USE_MONKEY=y diff --git a/samples/modules/lvgl/demos/src/main.c b/samples/modules/lvgl/demos/src/main.c index c17ba02c88f..2e3785d8298 100644 --- a/samples/modules/lvgl/demos/src/main.c +++ b/samples/modules/lvgl/demos/src/main.c @@ -29,9 +29,11 @@ int main(void) lv_demo_benchmark(); #elif defined(CONFIG_LV_USE_DEMO_STRESS) lv_demo_stress(); +#elif defined(CONFIG_LV_USE_DEMO_WIDGETS) + lv_demo_widgets(); #else -#error Enable one of the demos CONFIG_LV_USE_DEMO_MUSIC, CONFIG_LV_USE_DEMO_BENCHMARK \ -or CONFIG_LV_USE_DEMO_STRESS. +#error Enable one of the demos CONFIG_LV_USE_DEMO_MUSIC, CONFIG_LV_USE_DEMO_BENCHMARK ,\ + CONFIG_LV_USE_DEMO_STRESS, or CONFIG_LV_USE_DEMO_WIDGETS #endif lv_task_handler(); From 65501061eda31fd7ed07260fdb0540ca569780a0 Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Sun, 8 Oct 2023 17:20:18 +0200 Subject: [PATCH 2204/4498] Bluetooth: Controller: Kconfig: Move out BT_LL_SW_SPLIT configs BT_CTLR_ISOAL_LOG_DBG_VERBOSE, BT_CTLR_ISO_TX_SEG_PLAYLOAD_MIN, and BT_CTLR_CONN_ISO_AVOID_SEGMENTATION are very tied to the BT_LL_SW_SPLIT implementation. It is very unlikely that these will ever be used by another controller Therefore move them out to the BT_LL_SW_SPLIT specific configuration file. This will likely create less confusion when using another controller. Signed-off-by: Rubin Gerritsen --- subsys/bluetooth/controller/Kconfig | 27 ------------------- .../bluetooth/controller/Kconfig.ll_sw_split | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 9a3b2bdf437..742534beff3 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -206,13 +206,6 @@ config BT_CTLR_ISO_TX_BUFFER_SIZE Size of the Isochronous Tx buffers and the value returned in HCI LE Read Buffer Size V2 command response. -config BT_CTLR_ISOAL_LOG_DBG_VERBOSE - bool "ISO-AL verbose debug logging" - depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 - default n - help - Use this option to enable ISO-AL verbose debug logging. - config BT_CTLR_ISOAL_SOURCES int "Number of Isochronous Adaptation Layer sources" depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO @@ -244,15 +237,6 @@ config BT_CTLR_ISO_RX_SDU_BUFFERS maximum size of an SDU that can be accurately declared in the HCI ISO Data header. -config BT_CTLR_ISO_TX_SEG_PLAYLOAD_MIN - int "Minimum number of playload data bytes in a new segment" - depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO - default 1 - range 1 64 - help - Minimum number of payload bytes that would make inserting a new - segment into a PDU worthwhile. - config BT_CTLR_ISO_VENDOR_DATA_PATH bool "Vendor-specific ISO data path" depends on BT_CTLR_SYNC_ISO || BT_CTLR_CONN_ISO @@ -909,17 +893,6 @@ config BT_CTLR_CONN_ISO_STREAMS_MAX_FT help Maximum number of CIS flush timeout events. -config BT_CTLR_CONN_ISO_AVOID_SEGMENTATION - bool "Avoid SDU fragmentation for framed mode" - depends on BT_CTLR_CENTRAL_ISO - help - When creating a CIG, the Max_PDU size is calculated according to BT - Core 5.4 Vol 6, Part G, Section 2.2. However, HAP specifies a need for - avoiding segmentation by forcing the Max_PDU to the appropriate value. - Since there is no way to control the Max_PDU using the non-test - interface, the config provides a way to force the Max_PDU to Max_SDU + - 5 (header + offset). - config BT_CTLR_ISO bool default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index e2975107f86..2b9e33ef82d 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -206,6 +206,22 @@ config BT_CTLR_CHECK_SAME_PEER_SYNC endif # BT_CTLR_ADV_EXT +config BT_CTLR_ISOAL_LOG_DBG_VERBOSE + bool "ISO-AL verbose debug logging" + depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 + default n + help + Use this option to enable ISO-AL verbose debug logging. + +config BT_CTLR_ISO_TX_SEG_PLAYLOAD_MIN + int "Minimum number of playload data bytes in a new segment" + depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO + default 1 + range 1 64 + help + Minimum number of payload bytes that would make inserting a new + segment into a PDU worthwhile. + config BT_CTLR_CONN_ISO_HCI_DATAPATH_SKIP_INVALID_DATA bool "Do not pass invalid SDUs on HCI datapath" depends on BT_CTLR_CONN_ISO @@ -213,6 +229,17 @@ config BT_CTLR_CONN_ISO_HCI_DATAPATH_SKIP_INVALID_DATA This allows for applications to decide whether to forward invalid SDUs through HCI upwards. +config BT_CTLR_CONN_ISO_AVOID_SEGMENTATION + bool "Avoid SDU fragmentation for framed mode" + depends on BT_CTLR_CENTRAL_ISO + help + When creating a CIG, the Max_PDU size is calculated according to BT + Core 5.4 Vol 6, Part G, Section 2.2. However, HAP specifies a need for + avoiding segmentation by forcing the Max_PDU to the appropriate value. + Since there is no way to control the Max_PDU using the non-test + interface, the config provides a way to force the Max_PDU to Max_SDU + + 5 (header + offset). + config BT_CTLR_ADVANCED_FEATURES bool "Show advanced features" help From c9e651b12ce77e9832d8a15210e55e235e3d8b11 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Sun, 8 Oct 2023 11:09:01 +0200 Subject: [PATCH 2205/4498] tests: samples: gdbstub: make test out of the sample Clone samples/subsys/debug/gdbstub to tests and convert it back to a build-only sample aligned with documentation. Signed-off-by: Dmitrii Golovanov --- samples/subsys/debug/gdbstub/sample.yaml | 2 +- tests/subsys/debug/gdbstub/CMakeLists.txt | 12 ++++++ .../debug/gdbstub/boards/qemu_x86.overlay | 7 ++++ tests/subsys/debug/gdbstub/prj.conf | 4 ++ .../debug/gdbstub/pytest/test_gdbstub.py | 0 tests/subsys/debug/gdbstub/run.gdbinit | 17 +++++++++ tests/subsys/debug/gdbstub/src/main.c | 38 +++++++++++++++++++ tests/subsys/debug/gdbstub/testcase.yaml | 13 +++++++ 8 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/subsys/debug/gdbstub/CMakeLists.txt create mode 100644 tests/subsys/debug/gdbstub/boards/qemu_x86.overlay create mode 100644 tests/subsys/debug/gdbstub/prj.conf rename {samples => tests}/subsys/debug/gdbstub/pytest/test_gdbstub.py (100%) create mode 100644 tests/subsys/debug/gdbstub/run.gdbinit create mode 100644 tests/subsys/debug/gdbstub/src/main.c create mode 100644 tests/subsys/debug/gdbstub/testcase.yaml diff --git a/samples/subsys/debug/gdbstub/sample.yaml b/samples/subsys/debug/gdbstub/sample.yaml index 638c5ec16cc..5f75a801541 100644 --- a/samples/subsys/debug/gdbstub/sample.yaml +++ b/samples/subsys/debug/gdbstub/sample.yaml @@ -8,8 +8,8 @@ sample: name: gdbstub sample tests: sample.debug.gdbstub: + build_only: true platform_allow: qemu_x86 - harness: pytest tags: - debug - gdbstub diff --git a/tests/subsys/debug/gdbstub/CMakeLists.txt b/tests/subsys/debug/gdbstub/CMakeLists.txt new file mode 100644 index 00000000000..6bbcb336d18 --- /dev/null +++ b/tests/subsys/debug/gdbstub/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +if(BOARD MATCHES "qemu_x86") + list(APPEND QEMU_EXTRA_FLAGS -serial tcp:127.0.0.1:5678,server) +endif() + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(debug_gdbstub) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/debug/gdbstub/boards/qemu_x86.overlay b/tests/subsys/debug/gdbstub/boards/qemu_x86.overlay new file mode 100644 index 00000000000..e6c560fae72 --- /dev/null +++ b/tests/subsys/debug/gdbstub/boards/qemu_x86.overlay @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + chosen { + zephyr,gdbstub-uart = &uart1; + }; +}; diff --git a/tests/subsys/debug/gdbstub/prj.conf b/tests/subsys/debug/gdbstub/prj.conf new file mode 100644 index 00000000000..da68f3823c4 --- /dev/null +++ b/tests/subsys/debug/gdbstub/prj.conf @@ -0,0 +1,4 @@ +CONFIG_GDBSTUB=y +CONFIG_NO_OPTIMIZATIONS=y +CONFIG_USERSPACE=y +CONFIG_KOBJECT_TEXT_AREA=4096 diff --git a/samples/subsys/debug/gdbstub/pytest/test_gdbstub.py b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py similarity index 100% rename from samples/subsys/debug/gdbstub/pytest/test_gdbstub.py rename to tests/subsys/debug/gdbstub/pytest/test_gdbstub.py diff --git a/tests/subsys/debug/gdbstub/run.gdbinit b/tests/subsys/debug/gdbstub/run.gdbinit new file mode 100644 index 00000000000..abce598f54a --- /dev/null +++ b/tests/subsys/debug/gdbstub/run.gdbinit @@ -0,0 +1,17 @@ +set pagination off +#symbol-file build/zephyr/zephyr.elf +target remote :5678 +b test +b main.c:33 +c + +s +set var a = 2 +c +if ret == 6 + printf "PASSED\n" + quit 0 +else + printf "FAILED\n" + quit 1 +end diff --git a/tests/subsys/debug/gdbstub/src/main.c b/tests/subsys/debug/gdbstub/src/main.c new file mode 100644 index 00000000000..51995db4ab7 --- /dev/null +++ b/tests/subsys/debug/gdbstub/src/main.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define STACKSIZE 512 + +static int test(void) +{ + int a; + int b; + + a = 10; + b = a * 2; + + return a + b; +} + +static void thread_entry(void *p1, void *p2, void *p3) +{ + printk("Hello from user thread!\n"); +} + +int main(void) +{ + int ret; + + ret = test(); + printk("%d\n", ret); + return 0; +} + +K_THREAD_DEFINE(thread, STACKSIZE, thread_entry, NULL, NULL, NULL, + 7, K_USER, 0); diff --git a/tests/subsys/debug/gdbstub/testcase.yaml b/tests/subsys/debug/gdbstub/testcase.yaml new file mode 100644 index 00000000000..60c1f20d115 --- /dev/null +++ b/tests/subsys/debug/gdbstub/testcase.yaml @@ -0,0 +1,13 @@ +# +# Copyright (c) 2020 intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +tests: + debug.gdbstub.sample: + platform_allow: qemu_x86 + harness: pytest + tags: + - debug + - gdbstub From cbbb1cabd66ef0f76455166398e294e3a37a68ee Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Sun, 8 Oct 2023 13:17:52 +0200 Subject: [PATCH 2206/4498] tests: gdbstub: Improve test case Gdbstub test improvements: using pytest fixtures, parametrization, and expected pattern matching on outputs from GDB and the test application. Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/gdbstub/prj.conf | 1 + tests/subsys/debug/gdbstub/pytest/conftest.py | 20 ++++++ .../debug/gdbstub/pytest/test_gdbstub.py | 66 ++++++++++++++----- tests/subsys/debug/gdbstub/run.gdbinit | 17 ----- tests/subsys/debug/gdbstub/src/main.c | 11 +--- .../debug/gdbstub/test_breakpoints.gdbinit | 23 +++++++ tests/subsys/debug/gdbstub/testcase.yaml | 8 ++- 7 files changed, 103 insertions(+), 43 deletions(-) create mode 100644 tests/subsys/debug/gdbstub/pytest/conftest.py delete mode 100644 tests/subsys/debug/gdbstub/run.gdbinit create mode 100644 tests/subsys/debug/gdbstub/test_breakpoints.gdbinit diff --git a/tests/subsys/debug/gdbstub/prj.conf b/tests/subsys/debug/gdbstub/prj.conf index da68f3823c4..8b490380226 100644 --- a/tests/subsys/debug/gdbstub/prj.conf +++ b/tests/subsys/debug/gdbstub/prj.conf @@ -1,4 +1,5 @@ CONFIG_GDBSTUB=y +CONFIG_GDBSTUB_SERIAL_BACKEND=y CONFIG_NO_OPTIMIZATIONS=y CONFIG_USERSPACE=y CONFIG_KOBJECT_TEXT_AREA=4096 diff --git a/tests/subsys/debug/gdbstub/pytest/conftest.py b/tests/subsys/debug/gdbstub/pytest/conftest.py new file mode 100644 index 00000000000..08a5a35db30 --- /dev/null +++ b/tests/subsys/debug/gdbstub/pytest/conftest.py @@ -0,0 +1,20 @@ +# +# Copyright (c) 2023 intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import pytest + +def pytest_addoption(parser): + parser.addoption('--gdb_timeout') + parser.addoption('--gdb_script') + +@pytest.fixture() +def gdb_script(request): + return request.config.getoption('--gdb_script') + +@pytest.fixture() +def gdb_timeout(request): + return int(request.config.getoption('--gdb_timeout', default=60)) +# diff --git a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py index 41dca1cfcae..ba5eb4ab257 100755 --- a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py +++ b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py @@ -4,10 +4,12 @@ import os import subprocess -from twister_harness import DeviceAdapter import sys import logging import shlex +import re +import pytest +from twister_harness import DeviceAdapter ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "pylib", "twister")) @@ -15,20 +17,54 @@ logger = logging.getLogger(__name__) - -def test_gdbstub(dut: DeviceAdapter): - """ - Test gdbstub feature using a gdb script. We connect to the DUT and run some - basic gdb commands and evaluate return code to determine pass or failure. - """ +@pytest.fixture() +def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout): build_dir = dut.device_config.build_dir - cmake_cache = CMakeCache.from_file(build_dir / 'CMakeCache.txt') - gdb = cmake_cache.get('CMAKE_GDB', None) - assert gdb + cmake_cache = CMakeCache.from_file(os.path.join(build_dir, 'CMakeCache.txt')) + gdb_exec = cmake_cache.get('CMAKE_GDB', None) + assert gdb_exec source_dir = cmake_cache.get('APPLICATION_SOURCE_DIR', None) assert source_dir - cmd = [gdb, '-x', f'{source_dir}/run.gdbinit', f'{build_dir}/zephyr/zephyr.elf'] - logger.info(f'Test command: {shlex.join(cmd)}') - result = subprocess.run(cmd, capture_output=True, text=True, timeout=20) - logger.debug('Output:\n%s' % result.stdout) - assert result.returncode == 0 + build_image = cmake_cache.get('BYPRODUCT_KERNEL_ELF_NAME', None) + assert build_image + gdb_log_file = os.path.join(build_dir, 'gdb.log') + cmd = [gdb_exec, '-batch', '-ex', f'set logging file {gdb_log_file}', + '-x', f'{source_dir}/{gdb_script}', build_image] + logger.info(f'Run GDB: {shlex.join(cmd)}') + result = subprocess.run(cmd, capture_output=True, text=True, timeout=gdb_timeout) + logger.info(f'GDB ends rc={result.returncode}') + return result +# + +@pytest.fixture(scope="module") +def expected_app(): + return [ + re.compile(r"Booting from ROM"), + re.compile(r"Booting Zephyr OS build"), + re.compile(r"main\(\):enter"), + ] + +@pytest.fixture(scope="module") +def expected_gdb(): + return [ + re.compile(r'Breakpoint 1 at 0x'), + re.compile(r'Breakpoint 2 at 0x'), + re.compile(r'Breakpoint 1, test '), + re.compile(r'Breakpoint 2, main '), + re.compile(r'GDB:PASSED'), + ] + +def test_gdbstub(dut: DeviceAdapter, gdb_process, expected_app, expected_gdb): + """ + Test gdbstub feature using a GDB script. We connect to the DUT, run the + GDB script then evaluate return code and expected patterns at the GDB + and Test Applicaiton outputs. + """ + logger.debug(f"GDB output:\n{gdb_process.stdout}\n") + assert gdb_process.returncode == 0 + assert all([ex_re.search(gdb_process.stdout, re.MULTILINE) for ex_re in expected_gdb]), 'No expected GDB output' + assert 'Inferior 1 [Remote target] will be killed' in gdb_process.stdout,'Expecting explicit quit from the GDB script and kill QEMU test app.' + app_output = '\n'.join(dut.readlines(print_output = False)) + logger.debug(f"App output:\n{app_output}\n") + assert all([ex_re.search(app_output, re.MULTILINE) for ex_re in expected_app]), 'No expected Application output' +# diff --git a/tests/subsys/debug/gdbstub/run.gdbinit b/tests/subsys/debug/gdbstub/run.gdbinit deleted file mode 100644 index abce598f54a..00000000000 --- a/tests/subsys/debug/gdbstub/run.gdbinit +++ /dev/null @@ -1,17 +0,0 @@ -set pagination off -#symbol-file build/zephyr/zephyr.elf -target remote :5678 -b test -b main.c:33 -c - -s -set var a = 2 -c -if ret == 6 - printf "PASSED\n" - quit 0 -else - printf "FAILED\n" - quit 1 -end diff --git a/tests/subsys/debug/gdbstub/src/main.c b/tests/subsys/debug/gdbstub/src/main.c index 51995db4ab7..4d54f6b2ff9 100644 --- a/tests/subsys/debug/gdbstub/src/main.c +++ b/tests/subsys/debug/gdbstub/src/main.c @@ -20,19 +20,12 @@ static int test(void) return a + b; } -static void thread_entry(void *p1, void *p2, void *p3) -{ - printk("Hello from user thread!\n"); -} - int main(void) { int ret; + printk("%s():enter\n", __func__); ret = test(); - printk("%d\n", ret); + printk("ret=%d\n", ret); return 0; } - -K_THREAD_DEFINE(thread, STACKSIZE, thread_entry, NULL, NULL, NULL, - 7, K_USER, 0); diff --git a/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit b/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit new file mode 100644 index 00000000000..9d5aa7ab647 --- /dev/null +++ b/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit @@ -0,0 +1,23 @@ +set pagination off +set trace-commands on +set logging enabled on + +target remote :5678 + +b test +b main.c:29 +c + +# break at test() +s +set var a = 2 +c + +# break at main() +if ret == 6 + printf "GDB:PASSED\n" + quit 0 +else + printf "GDB:FAILED\n" + quit 1 +end diff --git a/tests/subsys/debug/gdbstub/testcase.yaml b/tests/subsys/debug/gdbstub/testcase.yaml index 60c1f20d115..8437a12421e 100644 --- a/tests/subsys/debug/gdbstub/testcase.yaml +++ b/tests/subsys/debug/gdbstub/testcase.yaml @@ -1,13 +1,17 @@ # -# Copyright (c) 2020 intel Corporation. +# Copyright (c) 2020, 2023 intel Corporation. # # SPDX-License-Identifier: Apache-2.0 # tests: - debug.gdbstub.sample: + debug.gdbstub.breakpoints: platform_allow: qemu_x86 harness: pytest + harness_config: + pytest_root: + - "pytest/test_gdbstub.py" + pytest_args: ["--gdb_timeout", "20", "--gdb_script", "test_breakpoints.gdbinit"] tags: - debug - gdbstub From 5008c31f8c6d2094cc3ce9de876fba0fb9338a9d Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 9 Oct 2023 14:57:39 +0200 Subject: [PATCH 2207/4498] config: qemu: Add QEMU_EXTRA_FLAGS config option Add QEMU_EXTRA_FLAGS as QEMU board config option. This allows Twister tests to provide additional device setup commands to QEMU in prj.conf or testcase.yaml configuration files. Example use case: to setup TCP or UDP network interfaces with non-conflicting port numbers in different test suites to avoid conflicts when Twister run tests in parallel on the same host. Signed-off-by: Dmitrii Golovanov --- boards/Kconfig | 9 +++++++++ cmake/emu/qemu.cmake | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/boards/Kconfig b/boards/Kconfig index fbab1e97d98..f56c2cab04e 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -111,6 +111,15 @@ config QEMU_GDBSERVER_LISTEN_DEV as the `QEMU_EXTRA_FLAGS` environment variable. Refer to application development doc and/or QEMU invocation doc for more info. +config QEMU_EXTRA_FLAGS + string "QEMU extra flags" + depends on QEMU_TARGET + default "" + help + This option is to pass onto QEMU an extra list of parameters + to setup devices, for example to allocate interface for Zephyr + GDBstub over serial with `-serial tcp:127.0.0.1:5678,server` + # There might not be any board options, hence the optional source osource "$(BOARD_DIR)/Kconfig" endmenu diff --git a/cmake/emu/qemu.cmake b/cmake/emu/qemu.cmake index a3a8a94515b..6103fc1cefc 100644 --- a/cmake/emu/qemu.cmake +++ b/cmake/emu/qemu.cmake @@ -399,6 +399,13 @@ set(env_qemu $ENV{QEMU_EXTRA_FLAGS}) separate_arguments(env_qemu) list(APPEND QEMU_EXTRA_FLAGS ${env_qemu}) +# Also append QEMU flags from config +if(NOT CONFIG_QEMU_EXTRA_FLAGS STREQUAL "") + set(config_qemu_flags ${CONFIG_QEMU_EXTRA_FLAGS}) + separate_arguments(config_qemu_flags) + list(APPEND QEMU_EXTRA_FLAGS "${config_qemu_flags}") +endif() + list(APPEND MORE_FLAGS_FOR_debugserver_qemu -S) if(NOT CONFIG_QEMU_GDBSERVER_LISTEN_DEV STREQUAL "") From 236c1ac5de5c4570d59fa8955cb928c9ad8e1f61 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 9 Oct 2023 15:09:26 +0200 Subject: [PATCH 2208/4498] tests: gdbstub: Add GDB remote target parameter Add `gdb_target_remote` test parameter for GDB `target remote` command instead of its hardcoded value to allow different types of gdbstub serial interfaces as well as different TCP ports in gdbstub test suites possibly run in parallel on the same host. Move all GDB log configuration parameters from GDB script to the fixture code. Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/gdbstub/CMakeLists.txt | 4 ---- tests/subsys/debug/gdbstub/pytest/conftest.py | 5 +++++ tests/subsys/debug/gdbstub/pytest/test_gdbstub.py | 9 +++++++-- tests/subsys/debug/gdbstub/test_breakpoints.gdbinit | 6 ------ tests/subsys/debug/gdbstub/testcase.yaml | 12 +++++++++++- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/subsys/debug/gdbstub/CMakeLists.txt b/tests/subsys/debug/gdbstub/CMakeLists.txt index 6bbcb336d18..69377e717f5 100644 --- a/tests/subsys/debug/gdbstub/CMakeLists.txt +++ b/tests/subsys/debug/gdbstub/CMakeLists.txt @@ -2,10 +2,6 @@ cmake_minimum_required(VERSION 3.20.0) -if(BOARD MATCHES "qemu_x86") - list(APPEND QEMU_EXTRA_FLAGS -serial tcp:127.0.0.1:5678,server) -endif() - find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(debug_gdbstub) diff --git a/tests/subsys/debug/gdbstub/pytest/conftest.py b/tests/subsys/debug/gdbstub/pytest/conftest.py index 08a5a35db30..12d5ced7590 100644 --- a/tests/subsys/debug/gdbstub/pytest/conftest.py +++ b/tests/subsys/debug/gdbstub/pytest/conftest.py @@ -7,6 +7,7 @@ import pytest def pytest_addoption(parser): + parser.addoption('--gdb_target_remote') parser.addoption('--gdb_timeout') parser.addoption('--gdb_script') @@ -17,4 +18,8 @@ def gdb_script(request): @pytest.fixture() def gdb_timeout(request): return int(request.config.getoption('--gdb_timeout', default=60)) + +@pytest.fixture() +def gdb_target_remote(request): + return request.config.getoption('--gdb_target_remote', default=":5678") # diff --git a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py index ba5eb4ab257..d088e6b08ab 100755 --- a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py +++ b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) @pytest.fixture() -def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout): +def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout, gdb_target_remote): build_dir = dut.device_config.build_dir cmake_cache = CMakeCache.from_file(os.path.join(build_dir, 'CMakeCache.txt')) gdb_exec = cmake_cache.get('CMAKE_GDB', None) @@ -28,7 +28,12 @@ def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout): build_image = cmake_cache.get('BYPRODUCT_KERNEL_ELF_NAME', None) assert build_image gdb_log_file = os.path.join(build_dir, 'gdb.log') - cmd = [gdb_exec, '-batch', '-ex', f'set logging file {gdb_log_file}', + cmd = [gdb_exec, '-batch', + '-ex', f'set pagination off', + '-ex', f'set trace-commands on', + '-ex', f'set logging file {gdb_log_file}', + '-ex', f'set logging enabled on', + '-ex', f'target remote {gdb_target_remote}', '-x', f'{source_dir}/{gdb_script}', build_image] logger.info(f'Run GDB: {shlex.join(cmd)}') result = subprocess.run(cmd, capture_output=True, text=True, timeout=gdb_timeout) diff --git a/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit b/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit index 9d5aa7ab647..d79e1aa5f28 100644 --- a/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit +++ b/tests/subsys/debug/gdbstub/test_breakpoints.gdbinit @@ -1,9 +1,3 @@ -set pagination off -set trace-commands on -set logging enabled on - -target remote :5678 - b test b main.c:29 c diff --git a/tests/subsys/debug/gdbstub/testcase.yaml b/tests/subsys/debug/gdbstub/testcase.yaml index 8437a12421e..ce170392810 100644 --- a/tests/subsys/debug/gdbstub/testcase.yaml +++ b/tests/subsys/debug/gdbstub/testcase.yaml @@ -11,7 +11,17 @@ tests: harness_config: pytest_root: - "pytest/test_gdbstub.py" - pytest_args: ["--gdb_timeout", "20", "--gdb_script", "test_breakpoints.gdbinit"] + pytest_args: + - "--gdb_timeout" + - "20" + - "--gdb_script" + - "test_breakpoints.gdbinit" + - "--gdb_target_remote" + - "tcp:127.0.0.1:5678" tags: - debug - gdbstub + extra_configs: + # Make sure the gdbstub port chosen is unique for this test to avoid conflicts + # when Twister runs tests in parallel on the same host. + - CONFIG_QEMU_EXTRA_FLAGS="-serial tcp:127.0.0.1:5678,server" From 664d96785b970a4e6d1a5208faeed03b54f2a23d Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 9 Oct 2023 21:31:41 +0200 Subject: [PATCH 2209/4498] tests: gdbstub: qemu: Cross-validate test behavior Add a testcase to run the same test application and GDB script which we use for Zephyr GDB stub testing, but now with the GDB stub enabled at QEMU itself using it as a reference RDP backend implementation. This allows to check the Zephyr's gdbstub implementation has similar behavior as the reference. Signed-off-by: Dmitrii Golovanov --- .../debug/gdbstub/pytest/test_gdbstub.py | 14 ++++++-- tests/subsys/debug/gdbstub/testcase.yaml | 36 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py index d088e6b08ab..fe063905df7 100755 --- a/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py +++ b/tests/subsys/debug/gdbstub/pytest/test_gdbstub.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) @pytest.fixture() -def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout, gdb_target_remote): +def gdb_process(dut: DeviceAdapter, gdb_script, gdb_timeout, gdb_target_remote) -> subprocess.CompletedProcess: build_dir = dut.device_config.build_dir cmake_cache = CMakeCache.from_file(os.path.join(build_dir, 'CMakeCache.txt')) gdb_exec = cmake_cache.get('CMAKE_GDB', None) @@ -59,7 +59,15 @@ def expected_gdb(): re.compile(r'GDB:PASSED'), ] -def test_gdbstub(dut: DeviceAdapter, gdb_process, expected_app, expected_gdb): +@pytest.fixture(scope="module") +def expected_gdb_detach(): + return [ + re.compile(r'Inferior.*will be killed'), # Zephyr gdbstub + re.compile(r'Inferior.*detached') # QEMU gdbstub + ] + + +def test_gdbstub(dut: DeviceAdapter, gdb_process, expected_app, expected_gdb, expected_gdb_detach): """ Test gdbstub feature using a GDB script. We connect to the DUT, run the GDB script then evaluate return code and expected patterns at the GDB @@ -68,7 +76,7 @@ def test_gdbstub(dut: DeviceAdapter, gdb_process, expected_app, expected_gdb): logger.debug(f"GDB output:\n{gdb_process.stdout}\n") assert gdb_process.returncode == 0 assert all([ex_re.search(gdb_process.stdout, re.MULTILINE) for ex_re in expected_gdb]), 'No expected GDB output' - assert 'Inferior 1 [Remote target] will be killed' in gdb_process.stdout,'Expecting explicit quit from the GDB script and kill QEMU test app.' + assert any([ex_re.search(gdb_process.stdout, re.MULTILINE) for ex_re in expected_gdb_detach]), 'No expected GDB quit' app_output = '\n'.join(dut.readlines(print_output = False)) logger.debug(f"App output:\n{app_output}\n") assert all([ex_re.search(app_output, re.MULTILINE) for ex_re in expected_app]), 'No expected Application output' diff --git a/tests/subsys/debug/gdbstub/testcase.yaml b/tests/subsys/debug/gdbstub/testcase.yaml index ce170392810..adb259b4122 100644 --- a/tests/subsys/debug/gdbstub/testcase.yaml +++ b/tests/subsys/debug/gdbstub/testcase.yaml @@ -5,6 +5,7 @@ # tests: + # Connect to Zephyr gdbstub and run a simple GDB script debug.gdbstub.breakpoints: platform_allow: qemu_x86 harness: pytest @@ -17,11 +18,42 @@ tests: - "--gdb_script" - "test_breakpoints.gdbinit" - "--gdb_target_remote" - - "tcp:127.0.0.1:5678" + - "tcp::5678" tags: - debug - gdbstub extra_configs: # Make sure the gdbstub port chosen is unique for this test to avoid conflicts # when Twister runs tests in parallel on the same host. - - CONFIG_QEMU_EXTRA_FLAGS="-serial tcp:127.0.0.1:5678,server" + - CONFIG_QEMU_EXTRA_FLAGS="-serial tcp::5678,server" + + # Connect to QEMU gdbstub backend and run the same GDB test script + # to check it against a reference RDP backend implementation expecting + # similar behavior as for Zephyr's gdbstub. + # Use non-default QEMU gdbstub port 1235 for this test to avoid conflicts + # with some other test on QEMU running in parallel. + debug.gdbstub_qemu.breakpoints: + platform_allow: qemu_x86 + harness: pytest + harness_config: + pytest_root: + - "pytest/test_gdbstub.py" + pytest_args: + - "--gdb_timeout" + - "20" + - "--gdb_script" + - "test_breakpoints.gdbinit" + - "--gdb_target_remote" + - "tcp::1235" + tags: + - debug + - gdbstub + extra_configs: + # Turn off Zephyr's gdbstub for this test case. + - CONFIG_GDBSTUB=n + - CONFIG_GDBSTUB_SERIAL_BACKEND=n + # Make sure the gdbstub port chosen is unique for this test to avoid conflicts + # when Twister runs tests in parallel on the same host. + - CONFIG_QEMU_EXTRA_FLAGS="-S -gdb tcp::1235" + # Clear QEMU default 'tcp::1234' + - CONFIG_QEMU_GDBSERVER_LISTEN_DEV="" From c8d6a62b9d83ca8f60cead2365fb16d51a180aab Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 13 Oct 2023 13:58:54 +0200 Subject: [PATCH 2210/4498] samples: gdbstub: doc: Remove redundant sample Remove gdbstub sample (samples/subsys/debug/gdbstub) as duplicated by a test (tests/subsys/debug/gdbstub). Update the GDB stub documentation. Signed-off-by: Dmitrii Golovanov --- doc/services/debugging/gdbstub.rst | 5 ++- samples/subsys/debug/gdbstub/CMakeLists.txt | 12 ------ samples/subsys/debug/gdbstub/README.rst | 31 --------------- .../debug/gdbstub/boards/qemu_x86.overlay | 7 ---- .../debug/gdbstub/boards/qemu_x86_64.overlay | 7 ---- samples/subsys/debug/gdbstub/prj.conf | 4 -- samples/subsys/debug/gdbstub/run.gdbinit | 17 --------- samples/subsys/debug/gdbstub/sample.yaml | 15 -------- samples/subsys/debug/gdbstub/src/main.c | 38 ------------------- 9 files changed, 3 insertions(+), 133 deletions(-) delete mode 100644 samples/subsys/debug/gdbstub/CMakeLists.txt delete mode 100644 samples/subsys/debug/gdbstub/README.rst delete mode 100644 samples/subsys/debug/gdbstub/boards/qemu_x86.overlay delete mode 100644 samples/subsys/debug/gdbstub/boards/qemu_x86_64.overlay delete mode 100644 samples/subsys/debug/gdbstub/prj.conf delete mode 100644 samples/subsys/debug/gdbstub/run.gdbinit delete mode 100644 samples/subsys/debug/gdbstub/sample.yaml delete mode 100644 samples/subsys/debug/gdbstub/src/main.c diff --git a/doc/services/debugging/gdbstub.rst b/doc/services/debugging/gdbstub.rst index 5b702d95698..50b830fb5b8 100644 --- a/doc/services/debugging/gdbstub.rst +++ b/doc/services/debugging/gdbstub.rst @@ -87,8 +87,9 @@ Using Serial Backend Example ******* -This is an example using ``samples/subsys/debug/gdbstub`` to demonstrate -how GDB stub works. +This is an example to demonstrate how GDB stub works. +You can also refer to ``tests/subsys/debug/gdbstub`` +for its implementation as a Twister test. #. Open two terminal windows. diff --git a/samples/subsys/debug/gdbstub/CMakeLists.txt b/samples/subsys/debug/gdbstub/CMakeLists.txt deleted file mode 100644 index 9759ca6c7f0..00000000000 --- a/samples/subsys/debug/gdbstub/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -if(BOARD MATCHES "qemu_x86") - list(APPEND QEMU_EXTRA_FLAGS -serial tcp:127.0.0.1:5678,server) -endif() - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(debug) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/subsys/debug/gdbstub/README.rst b/samples/subsys/debug/gdbstub/README.rst deleted file mode 100644 index dc8430cd339..00000000000 --- a/samples/subsys/debug/gdbstub/README.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. zephyr:code-sample:: gdb-debug - :name: GDB debug - - Use GDB Remote Serial Protocol to debug a Zephyr application running on QEMU. - -Overview -******** - -A simple sample that can be used with QEMU to show debug using GDB -Remote Serial Protocol (RSP) capabilities. - -Building and Running -******************** - -This application can be built and executed on QEMU as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/subsys/debug/gdbstub - :host-os: unix - :board: qemu_x86 - :goals: run - :compact: - -Open a new terminal and use gdb to connect to the running qemu as follows: - -.. code-block:: bash - - gdb build/zephyr/zephyr.elf - (gdb) target remote :5678 - -Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. diff --git a/samples/subsys/debug/gdbstub/boards/qemu_x86.overlay b/samples/subsys/debug/gdbstub/boards/qemu_x86.overlay deleted file mode 100644 index e6c560fae72..00000000000 --- a/samples/subsys/debug/gdbstub/boards/qemu_x86.overlay +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/ { - chosen { - zephyr,gdbstub-uart = &uart1; - }; -}; diff --git a/samples/subsys/debug/gdbstub/boards/qemu_x86_64.overlay b/samples/subsys/debug/gdbstub/boards/qemu_x86_64.overlay deleted file mode 100644 index e6c560fae72..00000000000 --- a/samples/subsys/debug/gdbstub/boards/qemu_x86_64.overlay +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/ { - chosen { - zephyr,gdbstub-uart = &uart1; - }; -}; diff --git a/samples/subsys/debug/gdbstub/prj.conf b/samples/subsys/debug/gdbstub/prj.conf deleted file mode 100644 index da68f3823c4..00000000000 --- a/samples/subsys/debug/gdbstub/prj.conf +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_GDBSTUB=y -CONFIG_NO_OPTIMIZATIONS=y -CONFIG_USERSPACE=y -CONFIG_KOBJECT_TEXT_AREA=4096 diff --git a/samples/subsys/debug/gdbstub/run.gdbinit b/samples/subsys/debug/gdbstub/run.gdbinit deleted file mode 100644 index abce598f54a..00000000000 --- a/samples/subsys/debug/gdbstub/run.gdbinit +++ /dev/null @@ -1,17 +0,0 @@ -set pagination off -#symbol-file build/zephyr/zephyr.elf -target remote :5678 -b test -b main.c:33 -c - -s -set var a = 2 -c -if ret == 6 - printf "PASSED\n" - quit 0 -else - printf "FAILED\n" - quit 1 -end diff --git a/samples/subsys/debug/gdbstub/sample.yaml b/samples/subsys/debug/gdbstub/sample.yaml deleted file mode 100644 index 5f75a801541..00000000000 --- a/samples/subsys/debug/gdbstub/sample.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2020 intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -sample: - name: gdbstub sample -tests: - sample.debug.gdbstub: - build_only: true - platform_allow: qemu_x86 - tags: - - debug - - gdbstub diff --git a/samples/subsys/debug/gdbstub/src/main.c b/samples/subsys/debug/gdbstub/src/main.c deleted file mode 100644 index 51995db4ab7..00000000000 --- a/samples/subsys/debug/gdbstub/src/main.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#define STACKSIZE 512 - -static int test(void) -{ - int a; - int b; - - a = 10; - b = a * 2; - - return a + b; -} - -static void thread_entry(void *p1, void *p2, void *p3) -{ - printk("Hello from user thread!\n"); -} - -int main(void) -{ - int ret; - - ret = test(); - printk("%d\n", ret); - return 0; -} - -K_THREAD_DEFINE(thread, STACKSIZE, thread_entry, NULL, NULL, NULL, - 7, K_USER, 0); From 5685af0923f314e390ed1dac7385947ccf152a63 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 29 Jun 2023 17:07:18 +0200 Subject: [PATCH 2211/4498] modules: hal_nordic: Add support for new TWIM instances Add Kconfig and symbols for twim: 20-22, 30, 121, 130-137 instances Signed-off-by: Adam Wojasinski --- modules/hal_nordic/nrfx/Kconfig | 65 ++++++++++++++++++++++++++ modules/hal_nordic/nrfx/nrfx_config.h | 39 ++++++++++++++++ soc/arm/nordic_nrf/Kconfig.peripherals | 39 ++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index e1d49946a4c..25ba1194da8 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -400,6 +400,71 @@ config NRFX_TWIM3 depends on $(dt_nodelabel_has_compat,i2c3,$(DT_COMPAT_NORDIC_NRF_TWIM)) select NRFX_TWIM +config NRFX_TWIM20 + bool "TWIM20 driver instance" + depends on $(dt_nodelabel_has_compat,i2c20,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM21 + bool "TWIM21 driver instance" + depends on $(dt_nodelabel_has_compat,i2c21,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM22 + bool "TWIM22 driver instance" + depends on $(dt_nodelabel_has_compat,i2c22,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM30 + bool "TWIM30 driver instance" + depends on $(dt_nodelabel_has_compat,i2c30,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM120 + bool "TWIM120 driver instance" + depends on $(dt_nodelabel_has_compat,i2c120,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM130 + bool "TWIM130 driver instance" + depends on $(dt_nodelabel_has_compat,i2c130,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM131 + bool "TWIM131 driver instance" + depends on $(dt_nodelabel_has_compat,i2c131,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM132 + bool "TWIM132 driver instance" + depends on $(dt_nodelabel_has_compat,i2c132,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM133 + bool "TWIM133 driver instance" + depends on $(dt_nodelabel_has_compat,i2c133,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM134 + bool "TWIM134 driver instance" + depends on $(dt_nodelabel_has_compat,i2c134,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM135 + bool "TWIM135 driver instance" + depends on $(dt_nodelabel_has_compat,i2c135,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM136 + bool "TWIM136 driver instance" + depends on $(dt_nodelabel_has_compat,i2c136,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + +config NRFX_TWIM137 + bool "TWIM137 driver instance" + depends on $(dt_nodelabel_has_compat,i2c137,$(DT_COMPAT_NORDIC_NRF_TWIM)) + select NRFX_TWIM + config NRFX_TWIS bool diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 0df5393d250..3236daa12b4 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -452,6 +452,45 @@ #ifdef CONFIG_NRFX_TWIM3 #define NRFX_TWIM3_ENABLED 1 #endif +#ifdef CONFIG_NRFX_TWIM20 +#define NRFX_TWIM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM21 +#define NRFX_TWIM21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM22 +#define NRFX_TWIM22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM30 +#define NRFX_TWIM30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM120 +#define NRFX_TWIM120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM130 +#define NRFX_TWIM130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM131 +#define NRFX_TWIM131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM132 +#define NRFX_TWIM132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM133 +#define NRFX_TWIM133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM134 +#define NRFX_TWIM134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM135 +#define NRFX_TWIM135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM136 +#define NRFX_TWIM136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM137 +#define NRFX_TWIM137_ENABLED 1 +#endif #ifdef CONFIG_NRFX_TWIS #define NRFX_TWIS_ENABLED 1 diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index eea79e5260e..d62238f1c8b 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -306,6 +306,45 @@ config HAS_HW_NRF_TWIM2 config HAS_HW_NRF_TWIM3 def_bool $(dt_nodelabel_enabled_with_compat,i2c3,$(DT_COMPAT_NORDIC_NRF_TWIM)) +config HAS_HW_NRF_TWIM20 + def_bool $(dt_nodelabel_enabled_with_compat,i2c20,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM21 + def_bool $(dt_nodelabel_enabled_with_compat,i2c21,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM22 + def_bool $(dt_nodelabel_enabled_with_compat,i2c22,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM30 + def_bool $(dt_nodelabel_enabled_with_compat,i2c30,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM120 + def_bool $(dt_nodelabel_enabled_with_compat,i2c120,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM130 + def_bool $(dt_nodelabel_enabled_with_compat,i2c130,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM131 + def_bool $(dt_nodelabel_enabled_with_compat,i2c131,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM132 + def_bool $(dt_nodelabel_enabled_with_compat,i2c132,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM133 + def_bool $(dt_nodelabel_enabled_with_compat,i2c133,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM134 + def_bool $(dt_nodelabel_enabled_with_compat,i2c134,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM135 + def_bool $(dt_nodelabel_enabled_with_compat,i2c135,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM136 + def_bool $(dt_nodelabel_enabled_with_compat,i2c136,$(DT_COMPAT_NORDIC_NRF_TWIM)) + +config HAS_HW_NRF_TWIM137 + def_bool $(dt_nodelabel_enabled_with_compat,i2c137,$(DT_COMPAT_NORDIC_NRF_TWIM)) + config HAS_HW_NRF_TWIS0 def_bool $(dt_nodelabel_enabled_with_compat,i2c0,$(DT_COMPAT_NORDIC_NRF_TWIS)) From 97b351fb666b47ea4b222e19a8d938ffd4de65a8 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Mon, 24 Jul 2023 14:23:12 +0200 Subject: [PATCH 2212/4498] drivers: i2c: i2c_nrfx_twim: Add support for new instances This patch intoduces new instances in TWIM SHIM for i2c driver. Signed-off-by: Adam Wojasinski --- drivers/i2c/Kconfig.nrfx | 13 ++++++++++ drivers/i2c/i2c_nrfx_twim.c | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/drivers/i2c/Kconfig.nrfx b/drivers/i2c/Kconfig.nrfx index bfde27721a8..78967177a3a 100644 --- a/drivers/i2c/Kconfig.nrfx +++ b/drivers/i2c/Kconfig.nrfx @@ -27,6 +27,19 @@ config I2C_NRFX_TWIM select NRFX_TWIM1 if HAS_HW_NRF_TWIM1 select NRFX_TWIM2 if HAS_HW_NRF_TWIM2 select NRFX_TWIM3 if HAS_HW_NRF_TWIM3 + select NRFX_TWIM20 if HAS_HW_NRF_TWIM20 + select NRFX_TWIM21 if HAS_HW_NRF_TWIM21 + select NRFX_TWIM22 if HAS_HW_NRF_TWIM22 + select NRFX_TWIM30 if HAS_HW_NRF_TWIM30 + select NRFX_TWIM120 if HAS_HW_NRF_TWIM120 + select NRFX_TWIM130 if HAS_HW_NRF_TWIM130 + select NRFX_TWIM131 if HAS_HW_NRF_TWIM131 + select NRFX_TWIM132 if HAS_HW_NRF_TWIM132 + select NRFX_TWIM133 if HAS_HW_NRF_TWIM133 + select NRFX_TWIM134 if HAS_HW_NRF_TWIM134 + select NRFX_TWIM135 if HAS_HW_NRF_TWIM135 + select NRFX_TWIM136 if HAS_HW_NRF_TWIM136 + select NRFX_TWIM137 if HAS_HW_NRF_TWIM137 config I2C_NRFX_TRANSFER_TIMEOUT int "Transfer timeout [ms]" diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 13df5051ac7..55160a44c72 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -455,3 +455,55 @@ I2C_NRFX_TWIM_DEVICE(2); #ifdef CONFIG_HAS_HW_NRF_TWIM3 I2C_NRFX_TWIM_DEVICE(3); #endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM20 +I2C_NRFX_TWIM_DEVICE(20); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM21 +I2C_NRFX_TWIM_DEVICE(21); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM22 +I2C_NRFX_TWIM_DEVICE(22); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM30 +I2C_NRFX_TWIM_DEVICE(30); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM120 +I2C_NRFX_TWIM_DEVICE(120); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM130 +I2C_NRFX_TWIM_DEVICE(130); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM131 +I2C_NRFX_TWIM_DEVICE(131); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM132 +I2C_NRFX_TWIM_DEVICE(132); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM133 +I2C_NRFX_TWIM_DEVICE(133); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM134 +I2C_NRFX_TWIM_DEVICE(134); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM135 +I2C_NRFX_TWIM_DEVICE(135); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM136 +I2C_NRFX_TWIM_DEVICE(136); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIM137 +I2C_NRFX_TWIM_DEVICE(137); +#endif From 01281ed8afdea50cd2dad9df9bdfffa1183e8669 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 9 Oct 2023 23:32:38 +0000 Subject: [PATCH 2213/4498] ztest: enable ZTEST_NEW_API by default Enable by default so we can remove kconfigs from tests/samples and keep things working as before. Signed-off-by: Anas Nashif --- subsys/testsuite/ztest/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/testsuite/ztest/Kconfig b/subsys/testsuite/ztest/Kconfig index d48961cc844..91c942b7a5c 100644 --- a/subsys/testsuite/ztest/Kconfig +++ b/subsys/testsuite/ztest/Kconfig @@ -12,6 +12,7 @@ if ZTEST config ZTEST_NEW_API bool "Use the new Ztest API" + default y help Enables the new Ztest APIs for creating suites and unit tests in separate compilation units as well as the new 'rules' API. From 345735d0a844d20549c0ce7bc2675ffb3f482804 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 9 Oct 2023 23:33:50 +0000 Subject: [PATCH 2214/4498] tests: remove CONFIG_ZTEST_NEW_API in all tests Remove all usage of CONFIG_ZTEST_NEW_API from tests and sample as this is now enabled by default. Signed-off-by: Anas Nashif --- samples/subsys/testsuite/integration/prj.conf | 1 - samples/subsys/testsuite/pytest/basic/prj.conf | 1 - tests/application_development/code_relocation/prj.conf | 1 - tests/application_development/code_relocation/prj_riscv.conf | 1 - tests/application_development/code_relocation/prj_xtensa.conf | 1 - tests/application_development/gen_inc_file/prj.conf | 1 - tests/arch/arc/arc_dsp_sharing/prj.conf | 1 - tests/arch/arm/arm_hardfault_validation/prj.conf | 1 - tests/arch/arm/arm_interrupt/prj.conf | 1 - tests/arch/arm/arm_irq_advanced_features/prj.conf | 1 - tests/arch/arm/arm_irq_vector_table/prj.conf | 1 - tests/arch/arm/arm_irq_zero_latency_levels/prj.conf | 1 - tests/arch/arm/arm_mem_protect/prj.conf | 1 - tests/arch/arm/arm_no_multithreading/prj.conf | 1 - tests/arch/arm/arm_ramfunc/prj.conf | 1 - tests/arch/arm/arm_runtime_nmi/prj.conf | 1 - tests/arch/arm/arm_sw_vector_relay/prj.conf | 1 - tests/arch/arm/arm_thread_swap/prj.conf | 1 - tests/arch/arm/arm_thread_swap_tz/prj.conf | 1 - tests/arch/arm/arm_tz_wrap_func/prj.conf | 1 - tests/arch/arm64/arm64_gicv3_its/prj.conf | 1 - tests/arch/arm64/arm64_high_addresses/prj.conf | 1 - tests/arch/arm64/arm64_psci/prj.conf | 1 - tests/arch/arm64/arm64_smc_call/prj.conf | 1 - tests/arch/common/semihost/prj.conf | 1 - tests/arch/common/timing/prj.conf | 1 - tests/arch/riscv/fpu_sharing/prj.conf | 1 - tests/arch/x86/cpu_scrubs_regs/prj.conf | 1 - tests/arch/x86/direct_isr/prj.conf | 1 - tests/arch/x86/nmi/prj.conf | 1 - tests/arch/x86/pagetables/prj.conf | 1 - tests/arch/x86/static_idt/prj.conf | 1 - tests/benchmarks/cmsis_dsp/basicmath/prj.conf | 1 - tests/benchmarks/data_structure_perf/dlist_perf/prj.conf | 1 - tests/benchmarks/data_structure_perf/rbtree_perf/prj.conf | 1 - tests/bluetooth/addr/prj.conf | 1 - tests/bluetooth/adv/prj.conf | 1 - tests/bluetooth/at/prj.conf | 1 - tests/bluetooth/audio/ascs/prj.conf | 1 - tests/bluetooth/audio/bap_broadcast_source/prj.conf | 1 - tests/bluetooth/audio/codec/prj.conf | 1 - tests/bluetooth/bluetooth/prj.conf | 1 - tests/bluetooth/bt_crypto/prj.conf | 1 - tests/bluetooth/bt_crypto_ccm/prj.conf | 1 - tests/bluetooth/controller/ctrl_api/prj.conf | 1 - tests/bluetooth/controller/ctrl_chmu/prj.conf | 1 - tests/bluetooth/controller/ctrl_cis_create/prj.conf | 1 - tests/bluetooth/controller/ctrl_cis_terminate/prj.conf | 1 - tests/bluetooth/controller/ctrl_collision/prj.conf | 1 - tests/bluetooth/controller/ctrl_conn_update/prj.conf | 1 - tests/bluetooth/controller/ctrl_conn_update/prj_apm.conf | 1 - .../bluetooth/controller/ctrl_conn_update/prj_no_param_req.conf | 1 - tests/bluetooth/controller/ctrl_cte_req/prj.conf | 1 - tests/bluetooth/controller/ctrl_data_length_update/prj.conf | 1 - .../controller/ctrl_data_length_update/prj_nocoded.conf | 1 - .../bluetooth/controller/ctrl_data_length_update/prj_nophy.conf | 1 - tests/bluetooth/controller/ctrl_encrypt/prj.conf | 1 - tests/bluetooth/controller/ctrl_feature_exchange/prj.conf | 1 - tests/bluetooth/controller/ctrl_hci/prj.conf | 1 - tests/bluetooth/controller/ctrl_invalid/prj.conf | 1 - tests/bluetooth/controller/ctrl_le_ping/prj.conf | 1 - tests/bluetooth/controller/ctrl_min_used_chans/prj.conf | 1 - tests/bluetooth/controller/ctrl_phy_update/prj.conf | 1 - tests/bluetooth/controller/ctrl_phy_update/prj_rx_cnt.conf | 1 - tests/bluetooth/controller/ctrl_sca_update/prj.conf | 1 - tests/bluetooth/controller/ctrl_terminate/prj.conf | 1 - tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj.conf | 1 - tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_1.conf | 1 - tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_2.conf | 1 - tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_3.conf | 1 - tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max.conf | 1 - .../controller/ctrl_tx_buffer_alloc/prj_max_common.conf | 1 - tests/bluetooth/controller/ctrl_tx_queue/prj.conf | 1 - tests/bluetooth/controller/ctrl_unsupported/prj.conf | 1 - .../bluetooth/controller/ctrl_unsupported/prj_unsupported.conf | 1 - tests/bluetooth/controller/ctrl_version/prj.conf | 1 - tests/bluetooth/ctrl_isoal/prj.conf | 1 - tests/bluetooth/ctrl_sw_privacy/prj.conf | 1 - tests/bluetooth/ctrl_sw_privacy_unit/prj.conf | 1 - tests/bluetooth/ctrl_user_ext/prj.conf | 1 - tests/bluetooth/df/connection_cte_req/prj.conf | 1 - tests/bluetooth/df/connection_cte_tx_params/prj.conf | 1 - tests/bluetooth/df/connectionless_cte_chains/prj.conf | 1 - tests/bluetooth/df/connectionless_cte_rx/prj.conf | 1 - tests/bluetooth/df/connectionless_cte_tx/prj.conf | 1 - tests/bluetooth/gatt/prj.conf | 1 - tests/bluetooth/hci_codecs_info/prj.conf | 1 - tests/bluetooth/hci_prop_evt/prj.conf | 1 - tests/bluetooth/hci_uart_async/prj.conf | 1 - tests/bluetooth/host/buf/bt_buf_get_cmd_complete/prj.conf | 1 - tests/bluetooth/host/buf/bt_buf_get_evt/prj.conf | 1 - tests/bluetooth/host/buf/bt_buf_get_rx/prj.conf | 1 - tests/bluetooth/host/buf/bt_buf_get_type/prj.conf | 1 - tests/bluetooth/host/crypto/bt_encrypt_be/prj.conf | 1 - tests/bluetooth/host/crypto/bt_encrypt_le/prj.conf | 1 - tests/bluetooth/host/crypto/bt_rand/prj.conf | 1 - tests/bluetooth/host/crypto/prng_init/prj.conf | 1 - tests/bluetooth/host/data/bt_data_parse/prj.conf | 1 - tests/bluetooth/host/ecc/bt_dh_key_gen/prj.conf | 1 - tests/bluetooth/host/ecc/bt_pub_key_gen/prj.conf | 1 - tests/bluetooth/host/ecc/bt_pub_key_get/prj.conf | 1 - tests/bluetooth/host/ecc/bt_pub_key_is_debug/prj.conf | 1 - tests/bluetooth/host/id/bt_br_oob_get_local/prj.conf | 1 - tests/bluetooth/host/id/bt_id_add/prj.conf | 1 - tests/bluetooth/host/id/bt_id_adv_random_addr_check/prj.conf | 1 - tests/bluetooth/host/id/bt_id_create/prj.conf | 1 - tests/bluetooth/host/id/bt_id_del/prj.conf | 1 - tests/bluetooth/host/id/bt_id_delete/prj.conf | 1 - tests/bluetooth/host/id/bt_id_get/prj.conf | 1 - tests/bluetooth/host/id/bt_id_init/prj.conf | 1 - tests/bluetooth/host/id/bt_id_read_public_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_reset/prj.conf | 1 - tests/bluetooth/host/id/bt_id_scan_random_addr_check/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_adv_own_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_adv_private_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_adv_random_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_create_conn_own_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_private_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_id_set_scan_own_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_le_ext_adv_oob_get_local/prj.conf | 1 - tests/bluetooth/host/id/bt_le_oob_get_local/prj.conf | 1 - tests/bluetooth/host/id/bt_le_oob_get_sc_data/prj.conf | 1 - tests/bluetooth/host/id/bt_le_oob_set_legacy_tk/prj.conf | 1 - tests/bluetooth/host/id/bt_le_oob_set_sc_data/prj.conf | 1 - tests/bluetooth/host/id/bt_lookup_id_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_setup_public_id_addr/prj.conf | 1 - tests/bluetooth/host/id/bt_setup_random_id_addr/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_add_type/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_clear/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_find/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_find_addr/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_find_irk/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_foreach_bond/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_foreach_type/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_get_addr/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_get_type/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_store/prj.conf | 1 - tests/bluetooth/host/keys/bt_keys_update_usage/prj.conf | 1 - tests/bluetooth/host_long_adv_recv/prj.conf | 1 - tests/bluetooth/init/prj.conf | 1 - tests/bluetooth/init/prj_0.conf | 1 - tests/bluetooth/init/prj_1.conf | 1 - tests/bluetooth/init/prj_10.conf | 1 - tests/bluetooth/init/prj_11.conf | 1 - tests/bluetooth/init/prj_12.conf | 1 - tests/bluetooth/init/prj_13.conf | 1 - tests/bluetooth/init/prj_14.conf | 1 - tests/bluetooth/init/prj_15.conf | 1 - tests/bluetooth/init/prj_16.conf | 1 - tests/bluetooth/init/prj_17.conf | 1 - tests/bluetooth/init/prj_18.conf | 1 - tests/bluetooth/init/prj_19.conf | 1 - tests/bluetooth/init/prj_2.conf | 1 - tests/bluetooth/init/prj_20.conf | 1 - tests/bluetooth/init/prj_21.conf | 1 - tests/bluetooth/init/prj_22.conf | 1 - tests/bluetooth/init/prj_3.conf | 1 - tests/bluetooth/init/prj_4.conf | 1 - tests/bluetooth/init/prj_5.conf | 1 - tests/bluetooth/init/prj_6.conf | 1 - tests/bluetooth/init/prj_7.conf | 1 - tests/bluetooth/init/prj_8.conf | 1 - tests/bluetooth/init/prj_9.conf | 1 - tests/bluetooth/init/prj_ctlr.conf | 1 - tests/bluetooth/init/prj_ctlr_4_0.conf | 1 - tests/bluetooth/init/prj_ctlr_4_0_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_broadcaster.conf | 1 - tests/bluetooth/init/prj_ctlr_broadcaster_ext.conf | 1 - tests/bluetooth/init/prj_ctlr_broadcaster_iso.conf | 1 - tests/bluetooth/init/prj_ctlr_central.conf | 1 - tests/bluetooth/init/prj_ctlr_central_ext.conf | 1 - tests/bluetooth/init/prj_ctlr_central_ext_priv.conf | 1 - tests/bluetooth/init/prj_ctlr_central_iso.conf | 1 - tests/bluetooth/init/prj_ctlr_central_priv.conf | 1 - tests/bluetooth/init/prj_ctlr_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_observer.conf | 1 - tests/bluetooth/init/prj_ctlr_observer_ext.conf | 1 - tests/bluetooth/init/prj_ctlr_per_adv.conf | 1 - tests/bluetooth/init/prj_ctlr_per_adv_no_adi.conf | 1 - tests/bluetooth/init/prj_ctlr_per_sync.conf | 1 - tests/bluetooth/init/prj_ctlr_per_sync_no_adi.conf | 1 - tests/bluetooth/init/prj_ctlr_per_sync_no_filter.conf | 1 - tests/bluetooth/init/prj_ctlr_peripheral.conf | 1 - tests/bluetooth/init/prj_ctlr_peripheral_ext.conf | 1 - tests/bluetooth/init/prj_ctlr_peripheral_ext_priv.conf | 1 - tests/bluetooth/init/prj_ctlr_peripheral_iso.conf | 1 - tests/bluetooth/init/prj_ctlr_peripheral_priv.conf | 1 - tests/bluetooth/init/prj_ctlr_sync_iso.conf | 1 - tests/bluetooth/init/prj_ctlr_ticker.conf | 1 - tests/bluetooth/init/prj_ctlr_tiny.conf | 1 - tests/bluetooth/init/prj_h5.conf | 1 - tests/bluetooth/init/prj_h5_dbg.conf | 1 - tests/bluetooth/init/prj_llcp.conf | 1 - tests/bluetooth/l2cap/prj.conf | 1 - tests/bluetooth/ll_settings/prj.conf | 1 - tests/bluetooth/mesh/blob_io_flash/prj.conf | 2 -- tests/bluetooth/mesh/rpl/prj.conf | 1 - tests/bluetooth/uuid/prj.conf | 1 - tests/boards/altera_max10/i2c_master/prj.conf | 1 - tests/boards/altera_max10/msgdma/prj.conf | 1 - tests/boards/altera_max10/qspi/prj.conf | 1 - tests/boards/altera_max10/sysid/prj.conf | 1 - tests/boards/espressif_esp32/cache_coex/prj.conf | 1 - tests/boards/frdm_k64f/i2c/prj.conf | 1 - tests/boards/intel_adsp/cache/prj.conf | 1 - tests/boards/intel_adsp/hda/prj.conf | 1 - tests/boards/intel_adsp/hda_log/prj.conf | 1 - tests/boards/intel_adsp/mm/prj.conf | 1 - tests/boards/intel_adsp/smoke/prj.conf | 1 - tests/boards/intel_adsp/ssp/prj.conf | 1 - tests/boards/mec15xxevb_assy6853/i2c_api/prj.conf | 1 - tests/boards/mec15xxevb_assy6853/qspi/prj.conf | 1 - tests/boards/mec172xevb_assy6906/i2c_api/prj.conf | 1 - tests/boards/mec172xevb_assy6906/qspi/prj.conf | 1 - tests/boards/native_posix/cpu_wait/prj.conf | 1 - tests/boards/native_posix/rtc/prj.conf | 1 - tests/boards/nrf52_bsim/egu/prj.conf | 1 - tests/boot/mcuboot_data_sharing/prj.conf | 1 - tests/cmake/overlays/var_expansions/prj.conf | 1 - tests/cmake/snippets/prj.conf | 1 - tests/crypto/crypto_hash/prj.conf | 1 - tests/crypto/mbedtls/prj.conf | 1 - tests/crypto/rand32/prj.conf | 1 - tests/crypto/rand32/prj_ctr_drbg.conf | 1 - tests/crypto/rand32/prj_hw_random_psa_crypto.conf | 1 - tests/crypto/rand32/prj_hw_random_xoshiro.conf | 1 - tests/crypto/rand32/prj_sw_random_systimer.conf | 1 - tests/crypto/tinycrypt/prj.conf | 1 - tests/crypto/tinycrypt_hmac_prng/prj.conf | 1 - tests/drivers/adc/adc_api/prj.conf | 1 - tests/drivers/adc/adc_dma/prj.conf | 1 - tests/drivers/adc/adc_emul/prj.conf | 1 - tests/drivers/adc/adc_rescale/prj.conf | 1 - tests/drivers/bbram/emul/prj.conf | 1 - tests/drivers/bbram/prj.conf | 1 - tests/drivers/bc12/prj.conf | 1 - tests/drivers/build_all/sensor/testcase.yaml | 1 - tests/drivers/can/api/prj.conf | 1 - tests/drivers/can/shell/prj.conf | 1 - tests/drivers/can/timing/prj.conf | 1 - tests/drivers/charger/sbs_charger/prj.conf | 1 - tests/drivers/clock_control/adsp_clock/prj.conf | 1 - tests/drivers/clock_control/clock_control_api/nrf_lfclk_rc.conf | 1 - tests/drivers/clock_control/clock_control_api/prj.conf | 1 - tests/drivers/clock_control/fixed_clock/prj.conf | 1 - tests/drivers/clock_control/nrf_clock_calibration/prj.conf | 1 - tests/drivers/clock_control/nrf_lf_clock_start/prj.conf | 1 - tests/drivers/clock_control/nrf_onoff_and_bt/prj.conf | 1 - tests/drivers/clock_control/onoff/prj.conf | 1 - .../stm32_clock_configuration/stm32_common_core/prj.conf | 1 - .../stm32_clock_configuration/stm32_common_devices/prj.conf | 1 - .../stm32_clock_configuration/stm32h5_core/prj.conf | 1 - .../stm32_clock_configuration/stm32h7_core/prj.conf | 1 - .../stm32_clock_configuration/stm32h7_devices/prj.conf | 1 - .../stm32_clock_configuration/stm32u5_core/prj.conf | 1 - .../stm32_clock_configuration/stm32u5_devices/prj.conf | 1 - .../stm32_clock_configuration/stm32wba_core/prj.conf | 1 - tests/drivers/coredump/coredump_api/prj.conf | 1 - tests/drivers/counter/counter_basic_api/prj.conf | 1 - tests/drivers/counter/counter_nrf_rtc/fixed_top/prj.conf | 1 - tests/drivers/counter/counter_seconds/prj.conf | 1 - tests/drivers/counter/maxim_ds3231_api/prj.conf | 1 - tests/drivers/dac/dac_api/prj.conf | 1 - tests/drivers/dac/dac_loopback/prj.conf | 1 - tests/drivers/disk/disk_access/prj.conf | 1 - tests/drivers/disk/disk_performance/prj.conf | 1 - tests/drivers/dma/chan_blen_transfer/prj.conf | 1 - tests/drivers/dma/chan_link_transfer/prj.conf | 1 - tests/drivers/dma/loop_transfer/prj.conf | 1 - tests/drivers/dma/scatter_gather/prj.conf | 1 - tests/drivers/eeprom/api/prj.conf | 1 - tests/drivers/eeprom/shell/prj.conf | 1 - tests/drivers/entropy/api/prj.conf | 1 - tests/drivers/espi/prj.conf | 1 - tests/drivers/ethernet/eth_ivshmem_queue/prj.conf | 1 - tests/drivers/flash/common/prj.conf | 1 - tests/drivers/flash/stm32/prj.conf | 1 - tests/drivers/flash_simulator/prj.conf | 1 - tests/drivers/fuel_gauge/bq27z746/prj.conf | 1 - tests/drivers/fuel_gauge/max17048/prj.conf | 1 - tests/drivers/fuel_gauge/sbs_gauge/prj.conf | 1 - tests/drivers/gpio/gpio_api_1pin/prj.conf | 1 - tests/drivers/gpio/gpio_basic_api/prj.conf | 1 - tests/drivers/gpio/gpio_enable_disable_interrupt/prj.conf | 1 - tests/drivers/gpio/gpio_get_direction/prj.conf | 1 - tests/drivers/gpio/gpio_hogs/prj.conf | 1 - tests/drivers/gpio/gpio_reserved_ranges/prj.conf | 1 - tests/drivers/hwinfo/api/prj.conf | 1 - tests/drivers/i2c/i2c_api/prj.conf | 1 - tests/drivers/i2c/i2c_target_api/prj.conf | 1 - tests/drivers/i2c/i2c_tca954x/prj.conf | 1 - tests/drivers/i2s/i2s_api/prj.conf | 1 - tests/drivers/i2s/i2s_speed/prj.conf | 1 - tests/drivers/input/gpio_keys/prj.conf | 1 - tests/drivers/kscan/kscan_api/mec15xxevb_assy6853.conf | 1 - tests/drivers/kscan/kscan_api/prj.conf | 1 - tests/drivers/kscan/kscan_input/prj.conf | 1 - tests/drivers/led/led_api/prj.conf | 1 - tests/drivers/memc/ram/prj.conf | 1 - tests/drivers/mipi_dsi/api/prj.conf | 1 - tests/drivers/mm/sys_mm_drv_api/prj.conf | 1 - tests/drivers/mm/sys_mm_drv_bank/prj.conf | 1 - tests/drivers/pinctrl/api/prj.conf | 1 - tests/drivers/pinctrl/gd32/prj.conf | 1 - tests/drivers/pinctrl/nrf/prj.conf | 1 - tests/drivers/pwm/pwm_api/prj.conf | 1 - tests/drivers/pwm/pwm_loopback/prj.conf | 1 - tests/drivers/regulator/api/prj.conf | 1 - tests/drivers/regulator/fixed/prj.conf | 1 - tests/drivers/regulator/voltage/prj.conf | 1 - tests/drivers/retained_mem/api/prj.conf | 1 - tests/drivers/rtc/rtc_api/prj.conf | 1 - tests/drivers/rtc/rtc_api_helpers/prj.conf | 1 - tests/drivers/rtc/shell/prj.conf | 1 - tests/drivers/sdhc/prj.conf | 1 - tests/drivers/sensor/accel/prj.conf | 1 - tests/drivers/sensor/akm09918c/prj.conf | 1 - tests/drivers/sensor/generic/prj.conf | 1 - tests/drivers/sensor/generic/prj_fpu.conf | 1 - tests/drivers/sensor/icm42688/prj.conf | 1 - tests/drivers/sensor/ina230/prj.conf | 1 - tests/drivers/sensor/ina237/prj.conf | 1 - tests/drivers/sensor/sbs_gauge/prj.conf | 1 - tests/drivers/smbus/smbus_api/prj.conf | 1 - tests/drivers/smbus/smbus_emul/prj.conf | 1 - tests/drivers/spi/dt_spec/prj.conf | 1 - tests/drivers/spi/spi_loopback/prj.conf | 1 - tests/drivers/syscon/prj.conf | 1 - tests/drivers/timer/nrf_rtc_timer/prj.conf | 1 - tests/drivers/uart/uart_async_api/prj.conf | 1 - tests/drivers/uart/uart_basic_api/prj.conf | 1 - tests/drivers/uart/uart_basic_api/prj_poll.conf | 1 - tests/drivers/uart/uart_basic_api/prj_shell.conf | 1 - tests/drivers/uart/uart_emul/prj.conf | 1 - tests/drivers/uart/uart_mix_fifo_poll/prj.conf | 1 - tests/drivers/uart/uart_pm/prj.conf | 1 - tests/drivers/udc/prj.conf | 1 - tests/drivers/virtualization/ivshmem/plain/prj.conf | 1 - tests/drivers/w1/w1_api/prj.conf | 1 - tests/drivers/watchdog/wdt_basic_api/prj.conf | 1 - tests/drivers/watchdog/wdt_basic_reset_none/prj.conf | 1 - tests/kernel/cache/prj.conf | 1 - tests/kernel/common/prj.conf | 1 - tests/kernel/condvar/condvar_api/prj.conf | 1 - tests/kernel/context/prj.conf | 1 - tests/kernel/device/prj.conf | 1 - tests/kernel/early_sleep/prj.conf | 1 - tests/kernel/events/event_api/prj.conf | 1 - tests/kernel/events/sys_event/prj.conf | 1 - tests/kernel/fatal/exception/prj.conf | 1 - tests/kernel/fatal/exception/prj_arm_fpu_sharing.conf | 1 - tests/kernel/fatal/exception/prj_armv8m_mpu_stack_guard.conf | 1 - tests/kernel/fatal/exception/protection_no_userspace.conf | 1 - tests/kernel/fatal/exception/sentinel.conf | 1 - tests/kernel/fatal/no-multithreading/prj.conf | 1 - tests/kernel/fifo/fifo_api/prj.conf | 1 - tests/kernel/fifo/fifo_timeout/prj.conf | 1 - tests/kernel/fifo/fifo_usage/prj.conf | 1 - tests/kernel/fpu_sharing/float_disable/prj.conf | 1 - tests/kernel/fpu_sharing/float_disable/prj_x86.conf | 1 - tests/kernel/fpu_sharing/generic/prj.conf | 1 - tests/kernel/fpu_sharing/generic/prj_x86.conf | 1 - tests/kernel/gen_isr_table/prj.conf | 1 - tests/kernel/interrupt/prj.conf | 1 - tests/kernel/lifo/lifo_api/prj.conf | 1 - tests/kernel/lifo/lifo_usage/prj.conf | 1 - tests/kernel/mbox/mbox_api/prj.conf | 1 - tests/kernel/mbox/mbox_usage/prj.conf | 1 - tests/kernel/mem_heap/k_heap_api/prj.conf | 1 - tests/kernel/mem_heap/mheap_api_concept/prj.conf | 1 - tests/kernel/mem_heap/shared_multi_heap/prj.conf | 1 - tests/kernel/mem_protect/demand_paging/prj.conf | 1 - tests/kernel/mem_protect/futex/prj.conf | 1 - tests/kernel/mem_protect/mem_map/prj.conf | 1 - tests/kernel/mem_protect/mem_map/prj_x86_64_coverage_exec.conf | 1 - tests/kernel/mem_protect/mem_protect/prj.conf | 1 - tests/kernel/mem_protect/obj_validation/prj.conf | 1 - tests/kernel/mem_protect/protection/prj.conf | 1 - tests/kernel/mem_protect/stack_random/prj.conf | 1 - tests/kernel/mem_protect/stackprot/prj.conf | 1 - tests/kernel/mem_protect/sys_sem/prj.conf | 1 - tests/kernel/mem_protect/syscalls/prj.conf | 1 - tests/kernel/mem_protect/userspace/prj.conf | 1 - tests/kernel/mem_slab/mslab/prj.conf | 1 - tests/kernel/mem_slab/mslab_api/prj.conf | 1 - tests/kernel/mem_slab/mslab_concept/prj.conf | 1 - tests/kernel/mem_slab/mslab_stats/prj.conf | 1 - tests/kernel/mem_slab/mslab_threadsafe/prj.conf | 1 - tests/kernel/mp/prj.conf | 1 - tests/kernel/msgq/msgq_api/prj.conf | 1 - tests/kernel/msgq/msgq_usage/prj.conf | 1 - tests/kernel/mutex/mutex_api/prj.conf | 1 - tests/kernel/mutex/mutex_error_case/prj.conf | 1 - tests/kernel/mutex/sys_mutex/prj.conf | 1 - tests/kernel/obj_core/obj_core/prj.conf | 1 - tests/kernel/obj_core/obj_core_stats/prj.conf | 1 - tests/kernel/obj_core/obj_core_stats_api/prj.conf | 1 - tests/kernel/obj_tracking/prj.conf | 1 - tests/kernel/pending/prj.conf | 1 - tests/kernel/pipe/pipe/prj.conf | 1 - tests/kernel/pipe/pipe_api/prj.conf | 1 - tests/kernel/poll/prj.conf | 1 - tests/kernel/profiling/profiling_api/prj.conf | 1 - tests/kernel/queue/prj.conf | 1 - tests/kernel/sched/deadline/prj.conf | 1 - tests/kernel/sched/metairq/prj.conf | 1 - tests/kernel/sched/preempt/prj.conf | 1 - tests/kernel/sched/schedule_api/prj.conf | 1 - tests/kernel/sched/schedule_api/prj_dumb.conf | 1 - tests/kernel/sched/schedule_api/prj_multiq.conf | 1 - tests/kernel/semaphore/semaphore/prj.conf | 1 - tests/kernel/semaphore/sys_sem/prj.conf | 1 - tests/kernel/sleep/prj.conf | 1 - tests/kernel/smp/prj.conf | 1 - tests/kernel/smp_boot_delay/prj.conf | 1 - tests/kernel/spinlock/prj.conf | 1 - tests/kernel/stack/stack/prj.conf | 1 - tests/kernel/threads/dynamic_thread/prj.conf | 1 - tests/kernel/threads/dynamic_thread_stack/prj.conf | 1 - tests/kernel/threads/no-multithreading/prj.conf | 1 - tests/kernel/threads/thread_apis/prj.conf | 1 - tests/kernel/threads/thread_error_case/prj.conf | 1 - tests/kernel/threads/thread_init/prj.conf | 1 - tests/kernel/threads/thread_stack/prj.conf | 1 - .../kernel/threads/thread_stack/prj_armv8m_mpu_stack_guard.conf | 1 - tests/kernel/threads/tls/prj.conf | 1 - tests/kernel/tickless/tickless_concept/prj.conf | 1 - tests/kernel/timer/cycle64/prj.conf | 1 - tests/kernel/timer/starve/prj.conf | 1 - tests/kernel/timer/timepoints/prj.conf | 1 - tests/kernel/timer/timer_api/prj.conf | 1 - tests/kernel/timer/timer_api/prj_tickless.conf | 1 - tests/kernel/timer/timer_behavior/prj.conf | 1 - tests/kernel/timer/timer_error_case/prj.conf | 1 - tests/kernel/timer/timer_monotonic/prj.conf | 1 - tests/kernel/usage/thread_runtime_stats/prj.conf | 1 - tests/kernel/workq/critical/prj.conf | 1 - tests/kernel/workq/user_work/prj.conf | 1 - tests/kernel/workq/work/prj.conf | 1 - tests/kernel/workq/work_queue/prj.conf | 1 - tests/kernel/xip/prj.conf | 1 - tests/lib/c_lib/prj.conf | 1 - tests/lib/cbprintf_package/prj.conf | 1 - tests/lib/cmsis_dsp/bayes/prj.conf | 1 - tests/lib/cmsis_dsp/complexmath/prj.conf | 1 - tests/lib/cmsis_dsp/distance/prj.conf | 1 - tests/lib/cmsis_dsp/fastmath/prj.conf | 1 - tests/lib/cmsis_dsp/filtering/prj.conf | 1 - tests/lib/cmsis_dsp/filtering/prj_base.conf | 1 - tests/lib/cmsis_dsp/interpolation/prj.conf | 1 - tests/lib/cmsis_dsp/matrix/prj.conf | 1 - tests/lib/cmsis_dsp/matrix/prj_base.conf | 1 - tests/lib/cmsis_dsp/quaternionmath/prj.conf | 1 - tests/lib/cmsis_dsp/statistics/prj.conf | 1 - tests/lib/cmsis_dsp/support/prj.conf | 1 - tests/lib/cmsis_dsp/svm/prj.conf | 1 - tests/lib/cmsis_dsp/transform/prj.conf | 1 - tests/lib/cmsis_dsp/transform/prj_base.conf | 1 - tests/lib/cmsis_nn/prj.conf | 1 - tests/lib/cpp/cxx/prj.conf | 1 - tests/lib/cpp/libcxx/prj.conf | 1 - tests/lib/devicetree/api/prj.conf | 1 - tests/lib/devicetree/api_ext/prj.conf | 1 - tests/lib/devicetree/devices/prj.conf | 1 - tests/lib/devicetree/memory_region/prj.conf | 1 - tests/lib/fdtable/prj.conf | 1 - tests/lib/gui/lvgl/prj.conf | 1 - tests/lib/hash_function/prj.conf | 1 - tests/lib/hash_map/prj.conf | 1 - tests/lib/heap/prj.conf | 1 - tests/lib/heap_align/prj.conf | 1 - tests/lib/json/prj.conf | 1 - tests/lib/linear_range/prj.conf | 1 - tests/lib/mem_alloc/prj.conf | 1 - tests/lib/mem_alloc/prj_negative_testing.conf | 1 - tests/lib/mem_alloc/prj_newlib.conf | 1 - tests/lib/mem_alloc/prj_newlibnano.conf | 1 - tests/lib/mem_alloc/prj_picolibc.conf | 1 - tests/lib/mem_blocks/prj.conf | 1 - tests/lib/mem_blocks_stats/prj.conf | 1 - tests/lib/mpsc_pbuf/prj.conf | 1 - tests/lib/newlib/heap_listener/prj.conf | 1 - tests/lib/newlib/thread_safety/prj.conf | 1 - tests/lib/newlib/thread_safety/prj_userspace.conf | 1 - tests/lib/notify/prj.conf | 1 - tests/lib/onoff/prj.conf | 1 - tests/lib/p4workq/prj.conf | 1 - tests/lib/ringbuffer/prj.conf | 1 - tests/lib/smf/prj.conf | 1 - tests/lib/sprintf/prj.conf | 1 - tests/lib/sprintf/prj_new.conf | 1 - tests/lib/sprintf/prj_picolibc.conf | 1 - tests/lib/sprintf/prj_picolibc_new.conf | 1 - tests/lib/spsc_pbuf/prj.conf | 1 - tests/lib/sys_util/prj.conf | 1 - tests/lib/thrift/ThriftTest/prj.conf | 1 - tests/lib/time/prj.conf | 1 - tests/misc/iterable_sections/prj.conf | 1 - tests/misc/kconfigoptions/prj.conf | 1 - tests/modules/nanopb/prj.conf | 1 - tests/modules/uoscore/prj.conf | 1 - tests/net/6lo/prj.conf | 1 - tests/net/all/prj.conf | 1 - tests/net/arp/prj.conf | 1 - tests/net/bridge/prj.conf | 1 - tests/net/buf/prj.conf | 1 - tests/net/buf_simple/prj.conf | 1 - tests/net/checksum_offload/prj.conf | 1 - tests/net/conn_mgr_conn/prj.conf | 1 - tests/net/conn_mgr_monitor/prj.conf | 1 - tests/net/context/prj.conf | 1 - tests/net/dhcpv4/prj.conf | 1 - tests/net/dhcpv6/prj.conf | 1 - tests/net/ethernet_mgmt/prj.conf | 1 - tests/net/hostname/prj.conf | 1 - tests/net/icmp/prj.conf | 1 - tests/net/icmpv4/prj.conf | 1 - tests/net/icmpv6/prj.conf | 1 - tests/net/ieee802154/6lo_fragment/prj.conf | 1 - tests/net/ieee802154/custom_l2/prj.conf | 1 - tests/net/ieee802154/l2/prj.conf | 1 - tests/net/iface/prj.conf | 1 - tests/net/igmp/prj.conf | 1 - tests/net/ip-addr/prj.conf | 1 - tests/net/ipv4_fragment/prj.conf | 1 - tests/net/ipv6/prj.conf | 1 - tests/net/ipv6_fragment/prj.conf | 1 - tests/net/lib/coap/prj.conf | 1 - tests/net/lib/coap_client/prj.conf | 1 - tests/net/lib/dns_addremove/prj.conf | 1 - tests/net/lib/dns_packet/prj.conf | 1 - tests/net/lib/dns_resolve/prj-no-ipv6.conf | 1 - tests/net/lib/dns_resolve/prj.conf | 1 - tests/net/lib/dns_sd/prj-no-ipv6.conf | 1 - tests/net/lib/dns_sd/prj.conf | 1 - tests/net/lib/http_header_fields/prj.conf | 1 - tests/net/lib/http_server/common/prj.conf | 1 - tests/net/lib/lwm2m/block_transfer/prj.conf | 1 - tests/net/lib/lwm2m/content_json/prj.conf | 1 - tests/net/lib/lwm2m/content_link_format/prj.conf | 1 - tests/net/lib/lwm2m/content_oma_tlv/prj.conf | 1 - tests/net/lib/lwm2m/content_plain_text/prj.conf | 1 - tests/net/lib/lwm2m/content_raw_cbor/prj.conf | 1 - tests/net/lib/lwm2m/content_senml_cbor/prj.conf | 1 - tests/net/lib/lwm2m/engine/prj.conf | 1 - tests/net/lib/lwm2m/lwm2m_engine/prj.conf | 1 - tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf | 1 - tests/net/lib/lwm2m/lwm2m_registry/prj.conf | 1 - tests/net/lib/mqtt_packet/prj.conf | 1 - tests/net/lib/mqtt_publisher/prj.conf | 1 - tests/net/lib/mqtt_publisher/prj_tls.conf | 1 - tests/net/lib/mqtt_pubsub/prj.conf | 1 - tests/net/lib/mqtt_sn_client/prj.conf | 1 - tests/net/lib/mqtt_sn_packet/prj.conf | 1 - tests/net/lib/mqtt_subscriber/prj.conf | 1 - tests/net/lib/tls_credentials/prj.conf | 1 - tests/net/mgmt/prj.conf | 1 - tests/net/mld/prj.conf | 1 - tests/net/neighbor/prj.conf | 1 - tests/net/net_pkt/prj.conf | 1 - tests/net/npf/prj.conf | 1 - tests/net/offloaded_netdev/prj.conf | 1 - tests/net/pm/prj.conf | 1 - tests/net/ppp/driver/prj.conf | 1 - tests/net/promiscuous/prj.conf | 1 - tests/net/ptp/clock/prj.conf | 1 - tests/net/route/prj.conf | 1 - tests/net/route_mcast/prj.conf | 1 - tests/net/shell/prj.conf | 1 - tests/net/socket/af_packet/prj.conf | 1 - tests/net/socket/af_packet_ipproto_raw/prj.conf | 1 - tests/net/socket/can/prj.conf | 1 - tests/net/socket/getaddrinfo/prj.conf | 1 - tests/net/socket/getnameinfo/prj.conf | 1 - tests/net/socket/misc/prj.conf | 1 - tests/net/socket/net_mgmt/prj.conf | 1 - tests/net/socket/offload_dispatcher/prj.conf | 1 - tests/net/socket/poll/prj.conf | 1 - tests/net/socket/register/prj.conf | 1 - tests/net/socket/reuseaddr_reuseport/prj.conf | 1 - tests/net/socket/select/prj.conf | 1 - tests/net/socket/socketpair/prj.conf | 1 - tests/net/socket/tcp/prj.conf | 1 - tests/net/socket/tls/prj.conf | 1 - tests/net/socket/tls_ext/prj.conf | 1 - tests/net/socket/udp/prj.conf | 1 - tests/net/socket/websocket/prj.conf | 1 - tests/net/tcp/prj.conf | 1 - tests/net/traffic_class/prj.conf | 1 - tests/net/trickle/prj.conf | 1 - tests/net/tx_timestamp/prj.conf | 1 - tests/net/udp/prj.conf | 1 - tests/net/utils/prj.conf | 1 - tests/net/virtual/prj.conf | 1 - tests/net/vlan/prj.conf | 1 - tests/net/wifi/wifi_nm/prj.conf | 1 - tests/posix/common/prj.conf | 1 - tests/posix/eventfd/prj.conf | 1 - tests/posix/fs/prj.conf | 1 - tests/posix/getopt/prj.conf | 1 - tests/posix/headers/prj.conf | 1 - tests/posix/pthread_pressure/prj.conf | 1 - tests/subsys/bindesc/definition/prj.conf | 1 - tests/subsys/canbus/isotp/conformance/prj.conf | 1 - tests/subsys/canbus/isotp/implementation/prj.conf | 1 - tests/subsys/debug/coredump_backends/prj.conf | 1 - tests/subsys/debug/coredump_backends/prj_backend_other.conf | 1 - tests/subsys/debug/coredump_backends/prj_flash_partition.conf | 1 - tests/subsys/dfu/img_util/prj.conf | 1 - tests/subsys/dfu/mcuboot/prj.conf | 1 - tests/subsys/dfu/mcuboot_multi/prj.conf | 1 - tests/subsys/dsp/basicmath/prj.conf | 1 - tests/subsys/dsp/basicmath/prj_arc.conf | 1 - tests/subsys/dsp/print_format/prj.conf | 1 - tests/subsys/edac/ibecc/prj.conf | 1 - tests/subsys/edac/ibecc_cov/prj.conf | 1 - tests/subsys/emul/prj.conf | 1 - tests/subsys/fs/ext2/prj.conf | 1 - tests/subsys/fs/ext2/prj_big.conf | 1 - tests/subsys/fs/ext2/prj_flash.conf | 1 - tests/subsys/fs/ext2/prj_sdcard.conf | 1 - tests/subsys/fs/fat_fs_api/prj.conf | 1 - tests/subsys/fs/fat_fs_api/prj_lfn.conf | 1 - tests/subsys/fs/fat_fs_api/prj_mmc.conf | 1 - tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf | 1 - tests/subsys/fs/fat_fs_dual_drive/prj.conf | 1 - tests/subsys/fs/fcb/prj.conf | 1 - tests/subsys/fs/fs_api/prj.conf | 1 - tests/subsys/fs/littlefs/prj.conf | 1 - tests/subsys/fs/multi-fs/prj.conf | 1 - tests/subsys/fs/multi-fs/prj_fs_shell.conf | 1 - tests/subsys/fs/nvs/prj.conf | 1 - tests/subsys/input/api/prj.conf | 1 - tests/subsys/input/input_longpress/prj.conf | 1 - tests/subsys/ipc/ipc_service/prj.conf | 1 - tests/subsys/jwt/prj.conf | 2 -- tests/subsys/llext/prj.conf | 1 - tests/subsys/logging/log_api/prj.conf | 1 - tests/subsys/logging/log_backend_fs/prj.conf | 1 - tests/subsys/logging/log_backend_init/prj.conf | 1 - tests/subsys/logging/log_benchmark/prj.conf | 1 - tests/subsys/logging/log_cache/prj.conf | 1 - tests/subsys/logging/log_core_additional/log_sync.conf | 1 - tests/subsys/logging/log_core_additional/log_user.conf | 1 - tests/subsys/logging/log_core_additional/prj.conf | 1 - tests/subsys/logging/log_custom_header/prj.conf | 1 - tests/subsys/logging/log_immediate/prj.conf | 1 - tests/subsys/logging/log_link_order/prj.conf | 1 - tests/subsys/logging/log_links/prj.conf | 1 - tests/subsys/logging/log_msg/prj.conf | 1 - tests/subsys/logging/log_output/prj.conf | 1 - tests/subsys/logging/log_stack/prj.conf | 1 - tests/subsys/logging/log_stress/prj.conf | 1 - tests/subsys/logging/log_switch_format/prj.conf | 1 - tests/subsys/logging/log_syst/prj.conf | 1 - tests/subsys/logging/log_timestamp/prj.conf | 1 - tests/subsys/mem_mgmt/mem_attr/prj.conf | 1 - tests/subsys/mgmt/ec_host_cmd/simulator/prj.conf | 1 - tests/subsys/mgmt/ec_host_cmd/uart/prj.conf | 1 - tests/subsys/mgmt/mcumgr/all_options/prj.conf | 1 - tests/subsys/mgmt/mcumgr/cb_notifications/prj.conf | 1 - tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf | 1 - tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf | 1 - tests/subsys/mgmt/mcumgr/os_mgmt_echo/prj.conf | 1 - tests/subsys/mgmt/mcumgr/os_mgmt_info/prj.conf | 1 - tests/subsys/mgmt/mcumgr/settings_mgmt/prj.conf | 1 - tests/subsys/mgmt/mcumgr/smp_client/prj.conf | 1 - tests/subsys/mgmt/mcumgr/smp_reassembly/prj.conf | 1 - tests/subsys/mgmt/mcumgr/smp_version/prj.conf | 1 - tests/subsys/mgmt/mcumgr/zcbor_bulk/prj.conf | 1 - tests/subsys/modbus/prj.conf | 1 - tests/subsys/modem/backends/tty/prj.conf | 1 - tests/subsys/modem/modem_chat/prj.conf | 1 - tests/subsys/modem/modem_cmux/prj.conf | 1 - tests/subsys/modem/modem_ppp/prj.conf | 1 - tests/subsys/openthread/prj.conf | 1 - tests/subsys/pm/device_driver_init/prj.conf | 1 - tests/subsys/pm/device_power_domains/prj.conf | 1 - tests/subsys/pm/device_runtime_api/prj.conf | 1 - tests/subsys/pm/device_wakeup_api/prj.conf | 1 - tests/subsys/pm/policy_api/prj.conf | 1 - tests/subsys/pm/power_domain/prj.conf | 1 - tests/subsys/pm/power_mgmt/prj.conf | 1 - tests/subsys/pm/power_mgmt_multicore/prj.conf | 1 - tests/subsys/pm/power_mgmt_soc/prj.conf | 1 - tests/subsys/pm/power_states_api/prj.conf | 1 - tests/subsys/portability/cmsis_rtos_v1/prj.conf | 1 - tests/subsys/portability/cmsis_rtos_v2/prj.conf | 1 - tests/subsys/rtio/rtio_api/prj.conf | 1 - tests/subsys/sd/mmc/prj.conf | 1 - tests/subsys/sd/sdmmc/prj.conf | 1 - tests/subsys/settings/fcb/prj.conf | 1 - tests/subsys/settings/fcb_init/prj.conf | 1 - tests/subsys/settings/file/prj.conf | 1 - tests/subsys/settings/functional/fcb/prj.conf | 1 - tests/subsys/settings/functional/file/prj.conf | 1 - tests/subsys/settings/functional/nvs/prj.conf | 1 - tests/subsys/settings/nvs/prj.conf | 1 - tests/subsys/shell/shell/prj.conf | 1 - tests/subsys/shell/shell/shell_min.conf | 1 - tests/subsys/shell/shell/shell_min_cmds.conf | 1 - tests/subsys/shell/shell/shell_min_cmds_all.conf | 1 - tests/subsys/shell/shell/shell_min_cmds_resize.conf | 1 - tests/subsys/shell/shell/shell_min_cmds_select.conf | 1 - tests/subsys/shell/shell/shell_min_colors.conf | 1 - tests/subsys/shell/shell/shell_min_help.conf | 1 - tests/subsys/shell/shell/shell_min_help_all.conf | 1 - tests/subsys/shell/shell/shell_min_history.conf | 1 - tests/subsys/shell/shell/shell_min_log_backend.conf | 1 - tests/subsys/shell/shell/shell_min_metakeys.conf | 1 - tests/subsys/shell/shell/shell_min_tab.conf | 1 - tests/subsys/shell/shell/shell_min_tab_auto.conf | 1 - tests/subsys/shell/shell/shell_min_wildcards.conf | 1 - tests/subsys/shell/shell_flash/prj.conf | 1 - tests/subsys/shell/shell_history/prj.conf | 1 - tests/subsys/sip_svc/prj.conf | 1 - tests/subsys/storage/flash_map/prj.conf | 1 - tests/subsys/storage/stream/stream_flash/prj.conf | 1 - tests/subsys/testsuite/fff_fake_contexts/prj.conf | 1 - tests/subsys/tracing/tracing_api/prj.conf | 1 - tests/subsys/usb/bos/prj.conf | 1 - tests/subsys/usb/desc_sections/prj.conf | 1 - tests/subsys/usb/device/prj.conf | 1 - tests/subsys/usb/device_next/prj.conf | 1 - tests/subsys/usb/os_desc/prj.conf | 1 - tests/subsys/zbus/dyn_channel/prj.conf | 1 - tests/subsys/zbus/integration/prj.conf | 1 - tests/subsys/zbus/runtime_observers_registration/prj.conf | 1 - tests/subsys/zbus/unittests/prj.conf | 1 - tests/subsys/zbus/user_data/prj.conf | 1 - tests/unit/base64/prj.conf | 2 +- tests/unit/cbprintf/prj.conf | 2 +- tests/unit/crc/prj.conf | 1 - tests/unit/intmath/prj.conf | 2 +- tests/unit/list/prj.conf | 1 - tests/unit/math_extras/prj.conf | 2 +- tests/unit/net_timeout/prj.conf | 2 +- tests/unit/pot/prj.conf | 1 - tests/unit/rbtree/prj.conf | 1 - tests/unit/time_units/prj.conf | 1 - tests/unit/timeutil/prj.conf | 2 +- tests/unit/util/prj.conf | 2 +- tests/unit/winstream/prj.conf | 2 +- tests/ztest/base/prj.conf | 1 - tests/ztest/base/prj_cpp.conf | 1 - tests/ztest/base/prj_verbose_0.conf | 1 - tests/ztest/base/prj_verbose_1.conf | 1 - tests/ztest/base/prj_verbose_2.conf | 1 - tests/ztest/busy_sim/prj.conf | 1 - tests/ztest/error_hook/prj.conf | 1 - tests/ztest/error_hook/prj_no_userspace.conf | 1 - tests/ztest/fail/core/prj.conf | 1 - tests/ztest/fail/prj.conf | 1 - tests/ztest/summary/prj.conf | 1 - tests/ztest/zexpect/prj.conf | 1 - tests/ztest/ztress/prj.conf | 1 - 757 files changed, 8 insertions(+), 759 deletions(-) diff --git a/samples/subsys/testsuite/integration/prj.conf b/samples/subsys/testsuite/integration/prj.conf index 9228251051e..9467c292689 100644 --- a/samples/subsys/testsuite/integration/prj.conf +++ b/samples/subsys/testsuite/integration/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/samples/subsys/testsuite/pytest/basic/prj.conf b/samples/subsys/testsuite/pytest/basic/prj.conf index 989b0c1b2cf..c3e81438ced 100644 --- a/samples/subsys/testsuite/pytest/basic/prj.conf +++ b/samples/subsys/testsuite/pytest/basic/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IDLE_STACK_SIZE=4096 diff --git a/tests/application_development/code_relocation/prj.conf b/tests/application_development/code_relocation/prj.conf index 8028191ca70..16d8d83470e 100644 --- a/tests/application_development/code_relocation/prj.conf +++ b/tests/application_development/code_relocation/prj.conf @@ -1,6 +1,5 @@ CONFIG_CODE_DATA_RELOCATION=y CONFIG_COVERAGE=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_sram2.ld" diff --git a/tests/application_development/code_relocation/prj_riscv.conf b/tests/application_development/code_relocation/prj_riscv.conf index 1bc4054f2d6..a4f229f85a7 100644 --- a/tests/application_development/code_relocation/prj_riscv.conf +++ b/tests/application_development/code_relocation/prj_riscv.conf @@ -1,5 +1,4 @@ CONFIG_CODE_DATA_RELOCATION=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_riscv_qemu_sram2.ld" diff --git a/tests/application_development/code_relocation/prj_xtensa.conf b/tests/application_development/code_relocation/prj_xtensa.conf index 2c0a3874f30..6be828a0385 100644 --- a/tests/application_development/code_relocation/prj_xtensa.conf +++ b/tests/application_development/code_relocation/prj_xtensa.conf @@ -1,5 +1,4 @@ CONFIG_CODE_DATA_RELOCATION=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_xtensa_qemu_sram2.ld" diff --git a/tests/application_development/gen_inc_file/prj.conf b/tests/application_development/gen_inc_file/prj.conf index bee34382821..f6d97748604 100644 --- a/tests/application_development/gen_inc_file/prj.conf +++ b/tests/application_development/gen_inc_file/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/arch/arc/arc_dsp_sharing/prj.conf b/tests/arch/arc/arc_dsp_sharing/prj.conf index b2d117d0bcb..f3be5294428 100644 --- a/tests/arch/arc/arc_dsp_sharing/prj.conf +++ b/tests/arch/arc/arc_dsp_sharing/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ARC_DSP=y CONFIG_ARC_DSP_SHARING=y CONFIG_MAIN_STACK_SIZE=1024 diff --git a/tests/arch/arm/arm_hardfault_validation/prj.conf b/tests/arch/arm/arm_hardfault_validation/prj.conf index 729ee22ed38..396aa78a87d 100644 --- a/tests/arch/arm/arm_hardfault_validation/prj.conf +++ b/tests/arch/arm/arm_hardfault_validation/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT_TEST=y diff --git a/tests/arch/arm/arm_interrupt/prj.conf b/tests/arch/arm/arm_interrupt/prj.conf index 4b453e77cff..5c3b1e83798 100644 --- a/tests/arch/arm/arm_interrupt/prj.conf +++ b/tests/arch/arm/arm_interrupt/prj.conf @@ -3,5 +3,4 @@ CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_IDLE_STACK_SIZE=512 -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT_TEST=y diff --git a/tests/arch/arm/arm_irq_advanced_features/prj.conf b/tests/arch/arm/arm_irq_advanced_features/prj.conf index ff88b08e88b..c5c24cf5873 100644 --- a/tests/arch/arm/arm_irq_advanced_features/prj.conf +++ b/tests/arch/arm/arm_irq_advanced_features/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_DYNAMIC_DIRECT_INTERRUPTS=y CONFIG_ZERO_LATENCY_IRQS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm/arm_irq_vector_table/prj.conf b/tests/arch/arm/arm_irq_vector_table/prj.conf index 28479ac0577..74a22e9196a 100644 --- a/tests/arch/arm/arm_irq_vector_table/prj.conf +++ b/tests/arch/arm/arm_irq_vector_table/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_GEN_ISR_TABLES=n CONFIG_NUM_IRQS=3 -CONFIG_ZTEST_NEW_API=y # Force Bluetooth disable (required by platforms that enable Bluetooth by default) CONFIG_BT=n diff --git a/tests/arch/arm/arm_irq_zero_latency_levels/prj.conf b/tests/arch/arm/arm_irq_zero_latency_levels/prj.conf index 68622c39af1..b6165cdbc99 100644 --- a/tests/arch/arm/arm_irq_zero_latency_levels/prj.conf +++ b/tests/arch/arm/arm_irq_zero_latency_levels/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_DYNAMIC_DIRECT_INTERRUPTS=y CONFIG_ZERO_LATENCY_IRQS=y diff --git a/tests/arch/arm/arm_mem_protect/prj.conf b/tests/arch/arm/arm_mem_protect/prj.conf index 3971afe4e55..e39776e7067 100644 --- a/tests/arch/arm/arm_mem_protect/prj.conf +++ b/tests/arch/arm/arm_mem_protect/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/arch/arm/arm_no_multithreading/prj.conf b/tests/arch/arm/arm_no_multithreading/prj.conf index 65dd4e51c05..33e8aebc274 100644 --- a/tests/arch/arm/arm_no_multithreading/prj.conf +++ b/tests/arch/arm/arm_no_multithreading/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MULTITHREADING=n CONFIG_ASSERT=y CONFIG_FPU=y diff --git a/tests/arch/arm/arm_ramfunc/prj.conf b/tests/arch/arm/arm_ramfunc/prj.conf index 04099e417a1..e39776e7067 100644 --- a/tests/arch/arm/arm_ramfunc/prj.conf +++ b/tests/arch/arm/arm_ramfunc/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm/arm_runtime_nmi/prj.conf b/tests/arch/arm/arm_runtime_nmi/prj.conf index 5662b1aa1b7..e5c468604ab 100644 --- a/tests/arch/arm/arm_runtime_nmi/prj.conf +++ b/tests/arch/arm/arm_runtime_nmi/prj.conf @@ -1,3 +1,2 @@ CONFIG_RUNTIME_NMI=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm/arm_sw_vector_relay/prj.conf b/tests/arch/arm/arm_sw_vector_relay/prj.conf index a36923beda2..fd20f02d7ad 100644 --- a/tests/arch/arm/arm_sw_vector_relay/prj.conf +++ b/tests/arch/arm/arm_sw_vector_relay/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_SW_VECTOR_RELAY=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm/arm_thread_swap/prj.conf b/tests/arch/arm/arm_thread_swap/prj.conf index a618b61b5ad..df696389344 100644 --- a/tests/arch/arm/arm_thread_swap/prj.conf +++ b/tests/arch/arm/arm_thread_swap/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_DYNAMIC_INTERRUPTS=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_MAIN_STACK_SIZE=1024 diff --git a/tests/arch/arm/arm_thread_swap_tz/prj.conf b/tests/arch/arm/arm_thread_swap_tz/prj.conf index 5839417932f..e5fce445828 100644 --- a/tests/arch/arm/arm_thread_swap_tz/prj.conf +++ b/tests/arch/arm/arm_thread_swap_tz/prj.conf @@ -11,5 +11,4 @@ CONFIG_TFM_IPC=y CONFIG_FPU=y CONFIG_FPU_SHARING=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y -CONFIG_ZTEST_NEW_API=y CONFIG_QEMU_ICOUNT_SHIFT=8 diff --git a/tests/arch/arm/arm_tz_wrap_func/prj.conf b/tests/arch/arm/arm_tz_wrap_func/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/arch/arm/arm_tz_wrap_func/prj.conf +++ b/tests/arch/arm/arm_tz_wrap_func/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm64/arm64_gicv3_its/prj.conf b/tests/arch/arm64/arm64_gicv3_its/prj.conf index 91e91fc99b7..178daa8fc44 100644 --- a/tests/arch/arm64/arm64_gicv3_its/prj.conf +++ b/tests/arch/arm64/arm64_gicv3_its/prj.conf @@ -1,4 +1,3 @@ CONFIG_LOG=y CONFIG_ZTEST=y CONFIG_GIC_V3_ITS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm64/arm64_high_addresses/prj.conf b/tests/arch/arm64/arm64_high_addresses/prj.conf index 41614cd2a01..cc08fb4b743 100644 --- a/tests/arch/arm64/arm64_high_addresses/prj.conf +++ b/tests/arch/arm64/arm64_high_addresses/prj.conf @@ -5,4 +5,3 @@ CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=y CONFIG_MAIN_STACK_SIZE=2560 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm64/arm64_psci/prj.conf b/tests/arch/arm64/arm64_psci/prj.conf index 0f96f29acbf..232de93ca9d 100644 --- a/tests/arch/arm64/arm64_psci/prj.conf +++ b/tests/arch/arm64/arm64_psci/prj.conf @@ -1,3 +1,2 @@ CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/arm64/arm64_smc_call/prj.conf b/tests/arch/arm64/arm64_smc_call/prj.conf index 0f96f29acbf..232de93ca9d 100644 --- a/tests/arch/arm64/arm64_smc_call/prj.conf +++ b/tests/arch/arm64/arm64_smc_call/prj.conf @@ -1,3 +1,2 @@ CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/common/semihost/prj.conf b/tests/arch/common/semihost/prj.conf index afb77490fa9..071acb7c66f 100644 --- a/tests/arch/common/semihost/prj.conf +++ b/tests/arch/common/semihost/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SEMIHOST=y diff --git a/tests/arch/common/timing/prj.conf b/tests/arch/common/timing/prj.conf index df10e05a4ce..f483da96cd7 100644 --- a/tests/arch/common/timing/prj.conf +++ b/tests/arch/common/timing/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TIMING_FUNCTIONS=y CONFIG_FPU=y CONFIG_SCHED_CPU_MASK=y diff --git a/tests/arch/riscv/fpu_sharing/prj.conf b/tests/arch/riscv/fpu_sharing/prj.conf index f9caa918d65..ebec0da18b6 100644 --- a/tests/arch/riscv/fpu_sharing/prj.conf +++ b/tests/arch/riscv/fpu_sharing/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FPU=y CONFIG_FPU_SHARING=y CONFIG_IRQ_OFFLOAD=y diff --git a/tests/arch/x86/cpu_scrubs_regs/prj.conf b/tests/arch/x86/cpu_scrubs_regs/prj.conf index 9f61e775c1b..6f61be1eff5 100644 --- a/tests/arch/x86/cpu_scrubs_regs/prj.conf +++ b/tests/arch/x86/cpu_scrubs_regs/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y diff --git a/tests/arch/x86/direct_isr/prj.conf b/tests/arch/x86/direct_isr/prj.conf index 1d84481424d..ebc05bbae73 100644 --- a/tests/arch/x86/direct_isr/prj.conf +++ b/tests/arch/x86/direct_isr/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_THREAD_STACK_INFO=y diff --git a/tests/arch/x86/nmi/prj.conf b/tests/arch/x86/nmi/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/arch/x86/nmi/prj.conf +++ b/tests/arch/x86/nmi/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/arch/x86/pagetables/prj.conf b/tests/arch/x86/pagetables/prj.conf index 6207cb18599..1c2858b3e00 100644 --- a/tests/arch/x86/pagetables/prj.conf +++ b/tests/arch/x86/pagetables/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_HW_STACK_PROTECTION=n CONFIG_TEST_USERSPACE=y CONFIG_EXCEPTION_DEBUG=y diff --git a/tests/arch/x86/static_idt/prj.conf b/tests/arch/x86/static_idt/prj.conf index 322bec144cc..ec99b0dbe30 100644 --- a/tests/arch/x86/static_idt/prj.conf +++ b/tests/arch/x86/static_idt/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_EXCEPTION_DEBUG=n CONFIG_MAIN_THREAD_PRIORITY=6 diff --git a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf +++ b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/benchmarks/data_structure_perf/dlist_perf/prj.conf b/tests/benchmarks/data_structure_perf/dlist_perf/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/benchmarks/data_structure_perf/dlist_perf/prj.conf +++ b/tests/benchmarks/data_structure_perf/dlist_perf/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/benchmarks/data_structure_perf/rbtree_perf/prj.conf b/tests/benchmarks/data_structure_perf/rbtree_perf/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/benchmarks/data_structure_perf/rbtree_perf/prj.conf +++ b/tests/benchmarks/data_structure_perf/rbtree_perf/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/addr/prj.conf b/tests/bluetooth/addr/prj.conf index 84088e6b035..fec5098eecf 100644 --- a/tests/bluetooth/addr/prj.conf +++ b/tests/bluetooth/addr/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/adv/prj.conf b/tests/bluetooth/adv/prj.conf index e6fddd337d0..21011240824 100644 --- a/tests/bluetooth/adv/prj.conf +++ b/tests/bluetooth/adv/prj.conf @@ -3,4 +3,3 @@ CONFIG_LOG=y CONFIG_BT_DEVICE_NAME="Test Adv Data" CONFIG_ASSERT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/at/prj.conf b/tests/bluetooth/at/prj.conf index 32b489c0b08..42737f3052b 100644 --- a/tests/bluetooth/at/prj.conf +++ b/tests/bluetooth/at/prj.conf @@ -3,5 +3,4 @@ CONFIG_BT_BREDR=y CONFIG_BT_HFP_HF=y CONFIG_NET_BUF=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SERIAL=y diff --git a/tests/bluetooth/audio/ascs/prj.conf b/tests/bluetooth/audio/ascs/prj.conf index 9376de2355b..9dfa71a952a 100644 --- a/tests/bluetooth/audio/ascs/prj.conf +++ b/tests/bluetooth/audio/ascs/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_MAX_CONN=1 diff --git a/tests/bluetooth/audio/bap_broadcast_source/prj.conf b/tests/bluetooth/audio/bap_broadcast_source/prj.conf index b56abbec6c8..4f4534ac2a5 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/prj.conf +++ b/tests/bluetooth/audio/bap_broadcast_source/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_AUDIO=y diff --git a/tests/bluetooth/audio/codec/prj.conf b/tests/bluetooth/audio/codec/prj.conf index 308958c0fe3..7701c36e5e3 100644 --- a/tests/bluetooth/audio/codec/prj.conf +++ b/tests/bluetooth/audio/codec/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_AUDIO=y diff --git a/tests/bluetooth/bluetooth/prj.conf b/tests/bluetooth/bluetooth/prj.conf index c150a19272d..ee911c43132 100644 --- a/tests/bluetooth/bluetooth/prj.conf +++ b/tests/bluetooth/bluetooth/prj.conf @@ -4,4 +4,3 @@ CONFIG_BT_NO_DRIVER=y CONFIG_LOG=y CONFIG_UART_INTERRUPT_DRIVEN=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/bt_crypto/prj.conf b/tests/bluetooth/bt_crypto/prj.conf index 84088e6b035..fec5098eecf 100644 --- a/tests/bluetooth/bt_crypto/prj.conf +++ b/tests/bluetooth/bt_crypto/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/bt_crypto_ccm/prj.conf b/tests/bluetooth/bt_crypto_ccm/prj.conf index 37164576b39..68662d4a0c5 100644 --- a/tests/bluetooth/bt_crypto_ccm/prj.conf +++ b/tests/bluetooth/bt_crypto_ccm/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/controller/ctrl_api/prj.conf b/tests/bluetooth/controller/ctrl_api/prj.conf index ff1da608b4e..7718b673947 100644 --- a/tests/bluetooth/controller/ctrl_api/prj.conf +++ b/tests/bluetooth/controller/ctrl_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_chmu/prj.conf b/tests/bluetooth/controller/ctrl_chmu/prj.conf index ff1da608b4e..7718b673947 100644 --- a/tests/bluetooth/controller/ctrl_chmu/prj.conf +++ b/tests/bluetooth/controller/ctrl_chmu/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_cis_create/prj.conf b/tests/bluetooth/controller/ctrl_cis_create/prj.conf index 095af7f8082..7b2d389656b 100644 --- a/tests/bluetooth/controller/ctrl_cis_create/prj.conf +++ b/tests/bluetooth/controller/ctrl_cis_create/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_cis_terminate/prj.conf b/tests/bluetooth/controller/ctrl_cis_terminate/prj.conf index 095af7f8082..7b2d389656b 100644 --- a/tests/bluetooth/controller/ctrl_cis_terminate/prj.conf +++ b/tests/bluetooth/controller/ctrl_cis_terminate/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_collision/prj.conf b/tests/bluetooth/controller/ctrl_collision/prj.conf index ff1da608b4e..7718b673947 100644 --- a/tests/bluetooth/controller/ctrl_collision/prj.conf +++ b/tests/bluetooth/controller/ctrl_collision/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_conn_update/prj.conf b/tests/bluetooth/controller/ctrl_conn_update/prj.conf index c1f2003a02e..6026d874f22 100644 --- a/tests/bluetooth/controller/ctrl_conn_update/prj.conf +++ b/tests/bluetooth/controller/ctrl_conn_update/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_conn_update/prj_apm.conf b/tests/bluetooth/controller/ctrl_conn_update/prj_apm.conf index 6fdf6b43600..5827974497f 100644 --- a/tests/bluetooth/controller/ctrl_conn_update/prj_apm.conf +++ b/tests/bluetooth/controller/ctrl_conn_update/prj_apm.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_conn_update/prj_no_param_req.conf b/tests/bluetooth/controller/ctrl_conn_update/prj_no_param_req.conf index 661adea35c0..7c90aa769a1 100644 --- a/tests/bluetooth/controller/ctrl_conn_update/prj_no_param_req.conf +++ b/tests/bluetooth/controller/ctrl_conn_update/prj_no_param_req.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_cte_req/prj.conf b/tests/bluetooth/controller/ctrl_cte_req/prj.conf index aacab6b2903..8941e79bc4f 100644 --- a/tests/bluetooth/controller/ctrl_cte_req/prj.conf +++ b/tests/bluetooth/controller/ctrl_cte_req/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_data_length_update/prj.conf b/tests/bluetooth/controller/ctrl_data_length_update/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_data_length_update/prj.conf +++ b/tests/bluetooth/controller/ctrl_data_length_update/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_data_length_update/prj_nocoded.conf b/tests/bluetooth/controller/ctrl_data_length_update/prj_nocoded.conf index 0eea80b585c..dcfc2eded1d 100644 --- a/tests/bluetooth/controller/ctrl_data_length_update/prj_nocoded.conf +++ b/tests/bluetooth/controller/ctrl_data_length_update/prj_nocoded.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_data_length_update/prj_nophy.conf b/tests/bluetooth/controller/ctrl_data_length_update/prj_nophy.conf index f1bf04d0f4a..115ad42a41a 100644 --- a/tests/bluetooth/controller/ctrl_data_length_update/prj_nophy.conf +++ b/tests/bluetooth/controller/ctrl_data_length_update/prj_nophy.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_encrypt/prj.conf b/tests/bluetooth/controller/ctrl_encrypt/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_encrypt/prj.conf +++ b/tests/bluetooth/controller/ctrl_encrypt/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_feature_exchange/prj.conf b/tests/bluetooth/controller/ctrl_feature_exchange/prj.conf index ff1da608b4e..7718b673947 100644 --- a/tests/bluetooth/controller/ctrl_feature_exchange/prj.conf +++ b/tests/bluetooth/controller/ctrl_feature_exchange/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_hci/prj.conf b/tests/bluetooth/controller/ctrl_hci/prj.conf index 80b2156e0fa..5f5a1abb057 100644 --- a/tests/bluetooth/controller/ctrl_hci/prj.conf +++ b/tests/bluetooth/controller/ctrl_hci/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_invalid/prj.conf b/tests/bluetooth/controller/ctrl_invalid/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_invalid/prj.conf +++ b/tests/bluetooth/controller/ctrl_invalid/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_le_ping/prj.conf b/tests/bluetooth/controller/ctrl_le_ping/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_le_ping/prj.conf +++ b/tests/bluetooth/controller/ctrl_le_ping/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_min_used_chans/prj.conf b/tests/bluetooth/controller/ctrl_min_used_chans/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_min_used_chans/prj.conf +++ b/tests/bluetooth/controller/ctrl_min_used_chans/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_phy_update/prj.conf b/tests/bluetooth/controller/ctrl_phy_update/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_phy_update/prj.conf +++ b/tests/bluetooth/controller/ctrl_phy_update/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_phy_update/prj_rx_cnt.conf b/tests/bluetooth/controller/ctrl_phy_update/prj_rx_cnt.conf index e35492c67ff..20d9e982e95 100644 --- a/tests/bluetooth/controller/ctrl_phy_update/prj_rx_cnt.conf +++ b/tests/bluetooth/controller/ctrl_phy_update/prj_rx_cnt.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_sca_update/prj.conf b/tests/bluetooth/controller/ctrl_sca_update/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_sca_update/prj.conf +++ b/tests/bluetooth/controller/ctrl_sca_update/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_terminate/prj.conf b/tests/bluetooth/controller/ctrl_terminate/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_terminate/prj.conf +++ b/tests/bluetooth/controller/ctrl_terminate/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj.conf index 4076b0b23c1..e3a1f8d893b 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_1.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_1.conf index 12186f6b20b..de0e26455ee 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_1.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_1.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_2.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_2.conf index 5e350b3767f..46650448d02 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_2.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_2.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_3.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_3.conf index c3dd3905e17..b829cf265e4 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_3.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_3.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max.conf index b504bee37e7..c01ee28211d 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max_common.conf b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max_common.conf index 444758372dc..7b83d2d6a12 100644 --- a/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max_common.conf +++ b/tests/bluetooth/controller/ctrl_tx_buffer_alloc/prj_max_common.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_tx_queue/prj.conf b/tests/bluetooth/controller/ctrl_tx_queue/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_tx_queue/prj.conf +++ b/tests/bluetooth/controller/ctrl_tx_queue/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_unsupported/prj.conf b/tests/bluetooth/controller/ctrl_unsupported/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_unsupported/prj.conf +++ b/tests/bluetooth/controller/ctrl_unsupported/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_unsupported/prj_unsupported.conf b/tests/bluetooth/controller/ctrl_unsupported/prj_unsupported.conf index b763fb00f5d..f01e17406ee 100644 --- a/tests/bluetooth/controller/ctrl_unsupported/prj_unsupported.conf +++ b/tests/bluetooth/controller/ctrl_unsupported/prj_unsupported.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/controller/ctrl_version/prj.conf b/tests/bluetooth/controller/ctrl_version/prj.conf index 23f11745d4c..09d9cd9bab9 100644 --- a/tests/bluetooth/controller/ctrl_version/prj.conf +++ b/tests/bluetooth/controller/ctrl_version/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/ctrl_isoal/prj.conf b/tests/bluetooth/ctrl_isoal/prj.conf index 2f429dd8c47..18fd120fcbe 100644 --- a/tests/bluetooth/ctrl_isoal/prj.conf +++ b/tests/bluetooth/ctrl_isoal/prj.conf @@ -1,6 +1,5 @@ CONFIG_NET_BUF=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_ASSERT_VERBOSE=3 CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_ZTEST_ASSERT_HOOK=y diff --git a/tests/bluetooth/ctrl_sw_privacy/prj.conf b/tests/bluetooth/ctrl_sw_privacy/prj.conf index 89c8424a243..7324043fdbd 100644 --- a/tests/bluetooth/ctrl_sw_privacy/prj.conf +++ b/tests/bluetooth/ctrl_sw_privacy/prj.conf @@ -4,6 +4,5 @@ CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT_PRIVACY=y CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY=y diff --git a/tests/bluetooth/ctrl_sw_privacy_unit/prj.conf b/tests/bluetooth/ctrl_sw_privacy_unit/prj.conf index 44906f1edc0..3cc871bc394 100644 --- a/tests/bluetooth/ctrl_sw_privacy_unit/prj.conf +++ b/tests/bluetooth/ctrl_sw_privacy_unit/prj.conf @@ -2,5 +2,4 @@ CONFIG_NET_BUF=y CONFIG_ZTEST=y CONFIG_ZTEST_ASSERT_VERBOSE=3 CONFIG_ZTEST_STACK_SIZE=4096 -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_PARAMETER_COUNT=32 diff --git a/tests/bluetooth/ctrl_user_ext/prj.conf b/tests/bluetooth/ctrl_user_ext/prj.conf index 368094d9b8f..d254da34fba 100644 --- a/tests/bluetooth/ctrl_user_ext/prj.conf +++ b/tests/bluetooth/ctrl_user_ext/prj.conf @@ -4,7 +4,6 @@ CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT_CTLR_ADVANCED_FEATURES=y CONFIG_BT_CTLR_USER_EXT=y CONFIG_BT_CTLR_USER_EVT_RANGE=10 diff --git a/tests/bluetooth/df/connection_cte_req/prj.conf b/tests/bluetooth/df/connection_cte_req/prj.conf index 9796e6a3763..77d3260135d 100644 --- a/tests/bluetooth/df/connection_cte_req/prj.conf +++ b/tests/bluetooth/df/connection_cte_req/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y diff --git a/tests/bluetooth/df/connection_cte_tx_params/prj.conf b/tests/bluetooth/df/connection_cte_tx_params/prj.conf index 9284e101e44..162d6ba6b77 100644 --- a/tests/bluetooth/df/connection_cte_tx_params/prj.conf +++ b/tests/bluetooth/df/connection_cte_tx_params/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y # It does not matter for the test whether central or peripheral is used. diff --git a/tests/bluetooth/df/connectionless_cte_chains/prj.conf b/tests/bluetooth/df/connectionless_cte_chains/prj.conf index d0b26e94e0e..45e5534c44d 100644 --- a/tests/bluetooth/df/connectionless_cte_chains/prj.conf +++ b/tests/bluetooth/df/connectionless_cte_chains/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/df/connectionless_cte_rx/prj.conf b/tests/bluetooth/df/connectionless_cte_rx/prj.conf index f7f7068e7d6..4d2cb06c548 100644 --- a/tests/bluetooth/df/connectionless_cte_rx/prj.conf +++ b/tests/bluetooth/df/connectionless_cte_rx/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/df/connectionless_cte_tx/prj.conf b/tests/bluetooth/df/connectionless_cte_tx/prj.conf index d229af80f19..6f215ed07fb 100644 --- a/tests/bluetooth/df/connectionless_cte_tx/prj.conf +++ b/tests/bluetooth/df/connectionless_cte_tx/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/gatt/prj.conf b/tests/bluetooth/gatt/prj.conf index 796b840d681..c59f96a921e 100644 --- a/tests/bluetooth/gatt/prj.conf +++ b/tests/bluetooth/gatt/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/hci_codecs_info/prj.conf b/tests/bluetooth/hci_codecs_info/prj.conf index 92653f4a3e1..316132fffc1 100644 --- a/tests/bluetooth/hci_codecs_info/prj.conf +++ b/tests/bluetooth/hci_codecs_info/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=y diff --git a/tests/bluetooth/hci_prop_evt/prj.conf b/tests/bluetooth/hci_prop_evt/prj.conf index 242ff1e1954..4951f0c3b3a 100644 --- a/tests/bluetooth/hci_prop_evt/prj.conf +++ b/tests/bluetooth/hci_prop_evt/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/hci_uart_async/prj.conf b/tests/bluetooth/hci_uart_async/prj.conf index b038c7c4312..408e8f611e4 100644 --- a/tests/bluetooth/hci_uart_async/prj.conf +++ b/tests/bluetooth/hci_uart_async/prj.conf @@ -7,4 +7,3 @@ CONFIG_LOG=y CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/host/buf/bt_buf_get_cmd_complete/prj.conf b/tests/bluetooth/host/buf/bt_buf_get_cmd_complete/prj.conf index 86979a3110d..652e7e5d169 100644 --- a/tests/bluetooth/host/buf/bt_buf_get_cmd_complete/prj.conf +++ b/tests/bluetooth/host/buf/bt_buf_get_cmd_complete/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/host/buf/bt_buf_get_evt/prj.conf b/tests/bluetooth/host/buf/bt_buf_get_evt/prj.conf index 86979a3110d..652e7e5d169 100644 --- a/tests/bluetooth/host/buf/bt_buf_get_evt/prj.conf +++ b/tests/bluetooth/host/buf/bt_buf_get_evt/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/host/buf/bt_buf_get_rx/prj.conf b/tests/bluetooth/host/buf/bt_buf_get_rx/prj.conf index 86979a3110d..652e7e5d169 100644 --- a/tests/bluetooth/host/buf/bt_buf_get_rx/prj.conf +++ b/tests/bluetooth/host/buf/bt_buf_get_rx/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/host/buf/bt_buf_get_type/prj.conf b/tests/bluetooth/host/buf/bt_buf_get_type/prj.conf index 86979a3110d..652e7e5d169 100644 --- a/tests/bluetooth/host/buf/bt_buf_get_type/prj.conf +++ b/tests/bluetooth/host/buf/bt_buf_get_type/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 diff --git a/tests/bluetooth/host/crypto/bt_encrypt_be/prj.conf b/tests/bluetooth/host/crypto/bt_encrypt_be/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/crypto/bt_encrypt_be/prj.conf +++ b/tests/bluetooth/host/crypto/bt_encrypt_be/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/crypto/bt_encrypt_le/prj.conf b/tests/bluetooth/host/crypto/bt_encrypt_le/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/crypto/bt_encrypt_le/prj.conf +++ b/tests/bluetooth/host/crypto/bt_encrypt_le/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/crypto/bt_rand/prj.conf b/tests/bluetooth/host/crypto/bt_rand/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/crypto/bt_rand/prj.conf +++ b/tests/bluetooth/host/crypto/bt_rand/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/crypto/prng_init/prj.conf b/tests/bluetooth/host/crypto/prng_init/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/crypto/prng_init/prj.conf +++ b/tests/bluetooth/host/crypto/prng_init/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/data/bt_data_parse/prj.conf b/tests/bluetooth/host/data/bt_data_parse/prj.conf index c68da48c1fb..432d8998c06 100644 --- a/tests/bluetooth/host/data/bt_data_parse/prj.conf +++ b/tests/bluetooth/host/data/bt_data_parse/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 CONFIG_ASSERT_VERBOSE=y diff --git a/tests/bluetooth/host/ecc/bt_dh_key_gen/prj.conf b/tests/bluetooth/host/ecc/bt_dh_key_gen/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/ecc/bt_dh_key_gen/prj.conf +++ b/tests/bluetooth/host/ecc/bt_dh_key_gen/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/ecc/bt_pub_key_gen/prj.conf b/tests/bluetooth/host/ecc/bt_pub_key_gen/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/ecc/bt_pub_key_gen/prj.conf +++ b/tests/bluetooth/host/ecc/bt_pub_key_gen/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/ecc/bt_pub_key_get/prj.conf b/tests/bluetooth/host/ecc/bt_pub_key_get/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/ecc/bt_pub_key_get/prj.conf +++ b/tests/bluetooth/host/ecc/bt_pub_key_get/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/ecc/bt_pub_key_is_debug/prj.conf b/tests/bluetooth/host/ecc/bt_pub_key_is_debug/prj.conf index 542d140aa56..9b9d1e2cafc 100644 --- a/tests/bluetooth/host/ecc/bt_pub_key_is_debug/prj.conf +++ b/tests/bluetooth/host/ecc/bt_pub_key_is_debug/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/id/bt_br_oob_get_local/prj.conf b/tests/bluetooth/host/id/bt_br_oob_get_local/prj.conf index a047bb3413e..8d352723bb4 100644 --- a/tests/bluetooth/host/id/bt_br_oob_get_local/prj.conf +++ b/tests/bluetooth/host/id/bt_br_oob_get_local/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_BREDR=y diff --git a/tests/bluetooth/host/id/bt_id_add/prj.conf b/tests/bluetooth/host/id/bt_id_add/prj.conf index 32e36bb46eb..82e46bfe20f 100644 --- a/tests/bluetooth/host/id/bt_id_add/prj.conf +++ b/tests/bluetooth/host/id/bt_id_add/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_adv_random_addr_check/prj.conf b/tests/bluetooth/host/id/bt_id_adv_random_addr_check/prj.conf index 7c5a2780471..3de82617e40 100644 --- a/tests/bluetooth/host/id/bt_id_adv_random_addr_check/prj.conf +++ b/tests/bluetooth/host/id/bt_id_adv_random_addr_check/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_ID_MAX=2 CONFIG_ASSERT=y diff --git a/tests/bluetooth/host/id/bt_id_create/prj.conf b/tests/bluetooth/host/id/bt_id_create/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_create/prj.conf +++ b/tests/bluetooth/host/id/bt_id_create/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_del/prj.conf b/tests/bluetooth/host/id/bt_id_del/prj.conf index 32e36bb46eb..82e46bfe20f 100644 --- a/tests/bluetooth/host/id/bt_id_del/prj.conf +++ b/tests/bluetooth/host/id/bt_id_del/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_delete/prj.conf b/tests/bluetooth/host/id/bt_id_delete/prj.conf index e53ac736d42..cae35e7d56c 100644 --- a/tests/bluetooth/host/id/bt_id_delete/prj.conf +++ b/tests/bluetooth/host/id/bt_id_delete/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_get/prj.conf b/tests/bluetooth/host/id/bt_id_get/prj.conf index e53ac736d42..cae35e7d56c 100644 --- a/tests/bluetooth/host/id/bt_id_get/prj.conf +++ b/tests/bluetooth/host/id/bt_id_get/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_init/prj.conf b/tests/bluetooth/host/id/bt_id_init/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_init/prj.conf +++ b/tests/bluetooth/host/id/bt_id_init/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_read_public_addr/prj.conf b/tests/bluetooth/host/id/bt_id_read_public_addr/prj.conf index cabe512642a..42703d41300 100644 --- a/tests/bluetooth/host/id/bt_id_read_public_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_read_public_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_ASSERT=y diff --git a/tests/bluetooth/host/id/bt_id_reset/prj.conf b/tests/bluetooth/host/id/bt_id_reset/prj.conf index e53ac736d42..cae35e7d56c 100644 --- a/tests/bluetooth/host/id/bt_id_reset/prj.conf +++ b/tests/bluetooth/host/id/bt_id_reset/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_scan_random_addr_check/prj.conf b/tests/bluetooth/host/id/bt_id_scan_random_addr_check/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_scan_random_addr_check/prj.conf +++ b/tests/bluetooth/host/id/bt_id_scan_random_addr_check/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_set_adv_own_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_adv_own_addr/prj.conf index 10ea773d687..2682cec05b5 100644 --- a/tests/bluetooth/host/id/bt_id_set_adv_own_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_adv_own_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_set_adv_private_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_adv_private_addr/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_set_adv_private_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_adv_private_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_set_adv_random_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_adv_random_addr/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_set_adv_random_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_adv_random_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_set_create_conn_own_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_create_conn_own_addr/prj.conf index 10ea773d687..2682cec05b5 100644 --- a/tests/bluetooth/host/id/bt_id_set_create_conn_own_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_create_conn_own_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_id_set_private_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_private_addr/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_id_set_private_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_private_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_id_set_scan_own_addr/prj.conf b/tests/bluetooth/host/id/bt_id_set_scan_own_addr/prj.conf index 10ea773d687..2682cec05b5 100644 --- a/tests/bluetooth/host/id/bt_id_set_scan_own_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_id_set_scan_own_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_le_ext_adv_oob_get_local/prj.conf b/tests/bluetooth/host/id/bt_le_ext_adv_oob_get_local/prj.conf index f0c02aa41d3..7041a2b047e 100644 --- a/tests/bluetooth/host/id/bt_le_ext_adv_oob_get_local/prj.conf +++ b/tests/bluetooth/host/id/bt_le_ext_adv_oob_get_local/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/host/id/bt_le_oob_get_local/prj.conf b/tests/bluetooth/host/id/bt_le_oob_get_local/prj.conf index 10ea773d687..2682cec05b5 100644 --- a/tests/bluetooth/host/id/bt_le_oob_get_local/prj.conf +++ b/tests/bluetooth/host/id/bt_le_oob_get_local/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y diff --git a/tests/bluetooth/host/id/bt_le_oob_get_sc_data/prj.conf b/tests/bluetooth/host/id/bt_le_oob_get_sc_data/prj.conf index f0c02aa41d3..7041a2b047e 100644 --- a/tests/bluetooth/host/id/bt_le_oob_get_sc_data/prj.conf +++ b/tests/bluetooth/host/id/bt_le_oob_get_sc_data/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/host/id/bt_le_oob_set_legacy_tk/prj.conf b/tests/bluetooth/host/id/bt_le_oob_set_legacy_tk/prj.conf index f0c02aa41d3..7041a2b047e 100644 --- a/tests/bluetooth/host/id/bt_le_oob_set_legacy_tk/prj.conf +++ b/tests/bluetooth/host/id/bt_le_oob_set_legacy_tk/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/host/id/bt_le_oob_set_sc_data/prj.conf b/tests/bluetooth/host/id/bt_le_oob_set_sc_data/prj.conf index f0c02aa41d3..7041a2b047e 100644 --- a/tests/bluetooth/host/id/bt_le_oob_set_sc_data/prj.conf +++ b/tests/bluetooth/host/id/bt_le_oob_set_sc_data/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_EXT_ADV=y diff --git a/tests/bluetooth/host/id/bt_lookup_id_addr/prj.conf b/tests/bluetooth/host/id/bt_lookup_id_addr/prj.conf index af15b84fb76..5f8cdcef017 100644 --- a/tests/bluetooth/host/id/bt_lookup_id_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_lookup_id_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_ID_MAX=2 diff --git a/tests/bluetooth/host/id/bt_setup_public_id_addr/prj.conf b/tests/bluetooth/host/id/bt_setup_public_id_addr/prj.conf index cabe512642a..42703d41300 100644 --- a/tests/bluetooth/host/id/bt_setup_public_id_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_setup_public_id_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_ASSERT=y diff --git a/tests/bluetooth/host/id/bt_setup_random_id_addr/prj.conf b/tests/bluetooth/host/id/bt_setup_random_id_addr/prj.conf index cabe512642a..42703d41300 100644 --- a/tests/bluetooth/host/id/bt_setup_random_id_addr/prj.conf +++ b/tests/bluetooth/host/id/bt_setup_random_id_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_ASSERT=y diff --git a/tests/bluetooth/host/keys/bt_keys_add_type/prj.conf b/tests/bluetooth/host/keys/bt_keys_add_type/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_add_type/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_add_type/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host/keys/bt_keys_clear/prj.conf b/tests/bluetooth/host/keys/bt_keys_clear/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_clear/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_clear/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host/keys/bt_keys_find/prj.conf b/tests/bluetooth/host/keys/bt_keys_find/prj.conf index 4f07ff59817..b7101de0bf0 100644 --- a/tests/bluetooth/host/keys/bt_keys_find/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_find/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/keys/bt_keys_find_addr/prj.conf b/tests/bluetooth/host/keys/bt_keys_find_addr/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_find_addr/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_find_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host/keys/bt_keys_find_irk/prj.conf b/tests/bluetooth/host/keys/bt_keys_find_irk/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_find_irk/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_find_irk/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host/keys/bt_keys_foreach_bond/prj.conf b/tests/bluetooth/host/keys/bt_keys_foreach_bond/prj.conf index f974a1868bb..d50176dd3d3 100644 --- a/tests/bluetooth/host/keys/bt_keys_foreach_bond/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_foreach_bond/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=4 diff --git a/tests/bluetooth/host/keys/bt_keys_foreach_type/prj.conf b/tests/bluetooth/host/keys/bt_keys_foreach_type/prj.conf index e45b77e8764..b650eff88e5 100644 --- a/tests/bluetooth/host/keys/bt_keys_foreach_type/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_foreach_type/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/keys/bt_keys_get_addr/prj.conf b/tests/bluetooth/host/keys/bt_keys_get_addr/prj.conf index f974a1868bb..d50176dd3d3 100644 --- a/tests/bluetooth/host/keys/bt_keys_get_addr/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_get_addr/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=4 diff --git a/tests/bluetooth/host/keys/bt_keys_get_type/prj.conf b/tests/bluetooth/host/keys/bt_keys_get_type/prj.conf index 4f07ff59817..b7101de0bf0 100644 --- a/tests/bluetooth/host/keys/bt_keys_get_type/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_get_type/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=7 diff --git a/tests/bluetooth/host/keys/bt_keys_store/prj.conf b/tests/bluetooth/host/keys/bt_keys_store/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_store/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_store/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host/keys/bt_keys_update_usage/prj.conf b/tests/bluetooth/host/keys/bt_keys_update_usage/prj.conf index 2d9af947d94..419fdcd6047 100644 --- a/tests/bluetooth/host/keys/bt_keys_update_usage/prj.conf +++ b/tests/bluetooth/host/keys/bt_keys_update_usage/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_PAIRED=11 diff --git a/tests/bluetooth/host_long_adv_recv/prj.conf b/tests/bluetooth/host_long_adv_recv/prj.conf index 68a16e68501..c25b96cf196 100644 --- a/tests/bluetooth/host_long_adv_recv/prj.conf +++ b/tests/bluetooth/host_long_adv_recv/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/init/prj.conf b/tests/bluetooth/init/prj.conf index 2103829ea4e..ccc9ef1dcef 100644 --- a/tests/bluetooth/init/prj.conf +++ b/tests/bluetooth/init/prj.conf @@ -1,4 +1,3 @@ CONFIG_BT=y CONFIG_LOG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_0.conf b/tests/bluetooth/init/prj_0.conf index efb286cf1ec..371990240bf 100644 --- a/tests/bluetooth/init/prj_0.conf +++ b/tests/bluetooth/init/prj_0.conf @@ -1,3 +1,2 @@ CONFIG_BT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_1.conf b/tests/bluetooth/init/prj_1.conf index 354c519cb44..4c8c6144a5c 100644 --- a/tests/bluetooth/init/prj_1.conf +++ b/tests/bluetooth/init/prj_1.conf @@ -1,4 +1,3 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_10.conf b/tests/bluetooth/init/prj_10.conf index c2f94c28bad..6aca7357972 100644 --- a/tests/bluetooth/init/prj_10.conf +++ b/tests/bluetooth/init/prj_10.conf @@ -7,4 +7,3 @@ CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_TINYCRYPT_ECC=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_11.conf b/tests/bluetooth/init/prj_11.conf index 39046408626..6b46c845df8 100644 --- a/tests/bluetooth/init/prj_11.conf +++ b/tests/bluetooth/init/prj_11.conf @@ -9,4 +9,3 @@ CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_12.conf b/tests/bluetooth/init/prj_12.conf index 45ad9163b66..55111c5b288 100644 --- a/tests/bluetooth/init/prj_12.conf +++ b/tests/bluetooth/init/prj_12.conf @@ -8,4 +8,3 @@ CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_13.conf b/tests/bluetooth/init/prj_13.conf index c6b607952af..0de0be405ce 100644 --- a/tests/bluetooth/init/prj_13.conf +++ b/tests/bluetooth/init/prj_13.conf @@ -8,4 +8,3 @@ CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_14.conf b/tests/bluetooth/init/prj_14.conf index ecd5f2bf8d7..a25c48d4bbb 100644 --- a/tests/bluetooth/init/prj_14.conf +++ b/tests/bluetooth/init/prj_14.conf @@ -5,4 +5,3 @@ CONFIG_BT_SMP=y CONFIG_BT_SIGNING=y CONFIG_BT_TINYCRYPT_ECC=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_15.conf b/tests/bluetooth/init/prj_15.conf index 466cc3fcdd1..3839272ce11 100644 --- a/tests/bluetooth/init/prj_15.conf +++ b/tests/bluetooth/init/prj_15.conf @@ -5,4 +5,3 @@ CONFIG_BT_SMP=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_TINYCRYPT_ECC=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_16.conf b/tests/bluetooth/init/prj_16.conf index ba1a467bca4..bc30a21c277 100644 --- a/tests/bluetooth/init/prj_16.conf +++ b/tests/bluetooth/init/prj_16.conf @@ -5,4 +5,3 @@ CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_17.conf b/tests/bluetooth/init/prj_17.conf index 9c2b3689f3a..f085ad19fcd 100644 --- a/tests/bluetooth/init/prj_17.conf +++ b/tests/bluetooth/init/prj_17.conf @@ -20,4 +20,3 @@ CONFIG_BT_ATT_LOG_LEVEL_DBG=y CONFIG_BT_GATT_LOG_LEVEL_DBG=y CONFIG_BT_BREDR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_18.conf b/tests/bluetooth/init/prj_18.conf index 3c9228643a1..66348e7e53d 100644 --- a/tests/bluetooth/init/prj_18.conf +++ b/tests/bluetooth/init/prj_18.conf @@ -2,4 +2,3 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_BREDR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_19.conf b/tests/bluetooth/init/prj_19.conf index 55306b30462..af0aac027f8 100644 --- a/tests/bluetooth/init/prj_19.conf +++ b/tests/bluetooth/init/prj_19.conf @@ -2,4 +2,3 @@ CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_BREDR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_2.conf b/tests/bluetooth/init/prj_2.conf index 349f9bfdf76..a1f822a48ab 100644 --- a/tests/bluetooth/init/prj_2.conf +++ b/tests/bluetooth/init/prj_2.conf @@ -1,4 +1,3 @@ CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_20.conf b/tests/bluetooth/init/prj_20.conf index 23b7ed7cb6f..96dc6501491 100644 --- a/tests/bluetooth/init/prj_20.conf +++ b/tests/bluetooth/init/prj_20.conf @@ -27,4 +27,3 @@ CONFIG_BT_A2DP=y CONFIG_BT_HFP_HF=y CONFIG_BT_HFP_HF_LOG_LEVEL_DBG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_21.conf b/tests/bluetooth/init/prj_21.conf index 5ddee9de9e1..8ec212aa4eb 100644 --- a/tests/bluetooth/init/prj_21.conf +++ b/tests/bluetooth/init/prj_21.conf @@ -20,4 +20,3 @@ CONFIG_BT_ATT_LOG_LEVEL_DBG=y CONFIG_BT_GATT_LOG_LEVEL_DBG=y CONFIG_BT_BREDR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_22.conf b/tests/bluetooth/init/prj_22.conf index 173ad3938ae..5fab545bc2c 100644 --- a/tests/bluetooth/init/prj_22.conf +++ b/tests/bluetooth/init/prj_22.conf @@ -3,4 +3,3 @@ CONFIG_BT_BREDR=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_3.conf b/tests/bluetooth/init/prj_3.conf index 33e4cacf9b5..9a0afb63d16 100644 --- a/tests/bluetooth/init/prj_3.conf +++ b/tests/bluetooth/init/prj_3.conf @@ -2,4 +2,3 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_4.conf b/tests/bluetooth/init/prj_4.conf index 334beabe5fe..ff9b717cf8b 100644 --- a/tests/bluetooth/init/prj_4.conf +++ b/tests/bluetooth/init/prj_4.conf @@ -2,4 +2,3 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_5.conf b/tests/bluetooth/init/prj_5.conf index dff5403766a..490d3509e31 100644 --- a/tests/bluetooth/init/prj_5.conf +++ b/tests/bluetooth/init/prj_5.conf @@ -2,4 +2,3 @@ CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_6.conf b/tests/bluetooth/init/prj_6.conf index cece23f25f3..2a8566b9b46 100644 --- a/tests/bluetooth/init/prj_6.conf +++ b/tests/bluetooth/init/prj_6.conf @@ -3,4 +3,3 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_7.conf b/tests/bluetooth/init/prj_7.conf index a5a4afde20c..93423f64742 100644 --- a/tests/bluetooth/init/prj_7.conf +++ b/tests/bluetooth/init/prj_7.conf @@ -4,4 +4,3 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y CONFIG_BT_SIGNING=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_8.conf b/tests/bluetooth/init/prj_8.conf index e596936e543..2fdd7773009 100644 --- a/tests/bluetooth/init/prj_8.conf +++ b/tests/bluetooth/init/prj_8.conf @@ -5,4 +5,3 @@ CONFIG_BT_SMP=y CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_9.conf b/tests/bluetooth/init/prj_9.conf index 1b55964abcb..be22972e42d 100644 --- a/tests/bluetooth/init/prj_9.conf +++ b/tests/bluetooth/init/prj_9.conf @@ -6,4 +6,3 @@ CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_TINYCRYPT_ECC=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr.conf b/tests/bluetooth/init/prj_ctlr.conf index dc31bd76e08..d64a64cc2a2 100644 --- a/tests/bluetooth/init/prj_ctlr.conf +++ b/tests/bluetooth/init/prj_ctlr.conf @@ -14,4 +14,3 @@ CONFIG_BT_BREDR=n CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_4_0.conf b/tests/bluetooth/init/prj_ctlr_4_0.conf index 4f9ec70d3bb..eed589e96d8 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0.conf @@ -37,4 +37,3 @@ CONFIG_BT_BREDR=n CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf index 5fc61cf98c6..95b9763b073 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf @@ -39,4 +39,3 @@ CONFIG_BT_BREDR=n CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf index 50f72889476..03e6838e3ed 100644 --- a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf @@ -72,4 +72,3 @@ CONFIG_DEBUG=y CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_broadcaster.conf b/tests/bluetooth/init/prj_ctlr_broadcaster.conf index 8bc2c0c7403..d062716f66b 100644 --- a/tests/bluetooth/init/prj_ctlr_broadcaster.conf +++ b/tests/bluetooth/init/prj_ctlr_broadcaster.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_broadcaster_ext.conf b/tests/bluetooth/init/prj_ctlr_broadcaster_ext.conf index 5edaf811ec9..389e622135d 100644 --- a/tests/bluetooth/init/prj_ctlr_broadcaster_ext.conf +++ b/tests/bluetooth/init/prj_ctlr_broadcaster_ext.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_broadcaster_iso.conf b/tests/bluetooth/init/prj_ctlr_broadcaster_iso.conf index 0f6faaf70c1..cd6f57dd75c 100644 --- a/tests/bluetooth/init/prj_ctlr_broadcaster_iso.conf +++ b/tests/bluetooth/init/prj_ctlr_broadcaster_iso.conf @@ -9,4 +9,3 @@ CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_CTLR_ADV_ISO=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_central.conf b/tests/bluetooth/init/prj_ctlr_central.conf index b2b5b4d7952..f00fe35ea64 100644 --- a/tests/bluetooth/init/prj_ctlr_central.conf +++ b/tests/bluetooth/init/prj_ctlr_central.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_central_ext.conf b/tests/bluetooth/init/prj_ctlr_central_ext.conf index 7ceaa6367c2..4508d629e35 100644 --- a/tests/bluetooth/init/prj_ctlr_central_ext.conf +++ b/tests/bluetooth/init/prj_ctlr_central_ext.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_central_ext_priv.conf b/tests/bluetooth/init/prj_ctlr_central_ext_priv.conf index c4523b00c10..59f8a46addb 100644 --- a/tests/bluetooth/init/prj_ctlr_central_ext_priv.conf +++ b/tests/bluetooth/init/prj_ctlr_central_ext_priv.conf @@ -10,4 +10,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_central_iso.conf b/tests/bluetooth/init/prj_ctlr_central_iso.conf index 96efca2d081..ad23e1c6675 100644 --- a/tests/bluetooth/init/prj_ctlr_central_iso.conf +++ b/tests/bluetooth/init/prj_ctlr_central_iso.conf @@ -5,4 +5,3 @@ CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_ISO_CENTRAL=y CONFIG_BT_CTLR_CENTRAL_ISO=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_central_priv.conf b/tests/bluetooth/init/prj_ctlr_central_priv.conf index 9a6770f2f47..3bf4650f1e7 100644 --- a/tests/bluetooth/init/prj_ctlr_central_priv.conf +++ b/tests/bluetooth/init/prj_ctlr_central_priv.conf @@ -10,4 +10,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_dbg.conf b/tests/bluetooth/init/prj_ctlr_dbg.conf index 2f8224cdfea..ac9efeb9338 100644 --- a/tests/bluetooth/init/prj_ctlr_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_dbg.conf @@ -58,4 +58,3 @@ CONFIG_DEBUG=y CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_observer.conf b/tests/bluetooth/init/prj_ctlr_observer.conf index e785cda5f1d..96d1d2d8edb 100644 --- a/tests/bluetooth/init/prj_ctlr_observer.conf +++ b/tests/bluetooth/init/prj_ctlr_observer.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_observer_ext.conf b/tests/bluetooth/init/prj_ctlr_observer_ext.conf index ae744255677..4d540d59f25 100644 --- a/tests/bluetooth/init/prj_ctlr_observer_ext.conf +++ b/tests/bluetooth/init/prj_ctlr_observer_ext.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_per_adv.conf b/tests/bluetooth/init/prj_ctlr_per_adv.conf index 4897e55fa55..c070838fc06 100644 --- a/tests/bluetooth/init/prj_ctlr_per_adv.conf +++ b/tests/bluetooth/init/prj_ctlr_per_adv.conf @@ -11,4 +11,3 @@ CONFIG_BT_CTLR_ADV_PERIODIC=y CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_per_adv_no_adi.conf b/tests/bluetooth/init/prj_ctlr_per_adv_no_adi.conf index 3701e092252..e2bd0cc711c 100644 --- a/tests/bluetooth/init/prj_ctlr_per_adv_no_adi.conf +++ b/tests/bluetooth/init/prj_ctlr_per_adv_no_adi.conf @@ -11,4 +11,3 @@ CONFIG_BT_CTLR_ADV_PERIODIC=y CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_per_sync.conf b/tests/bluetooth/init/prj_ctlr_per_sync.conf index 0c3d99e87af..60142f55adc 100644 --- a/tests/bluetooth/init/prj_ctlr_per_sync.conf +++ b/tests/bluetooth/init/prj_ctlr_per_sync.conf @@ -12,4 +12,3 @@ CONFIG_BT_CTLR_SYNC_PERIODIC=y CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_per_sync_no_adi.conf b/tests/bluetooth/init/prj_ctlr_per_sync_no_adi.conf index 4fa71725642..c2e9ce0defc 100644 --- a/tests/bluetooth/init/prj_ctlr_per_sync_no_adi.conf +++ b/tests/bluetooth/init/prj_ctlr_per_sync_no_adi.conf @@ -12,4 +12,3 @@ CONFIG_BT_CTLR_SYNC_PERIODIC=y CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_per_sync_no_filter.conf b/tests/bluetooth/init/prj_ctlr_per_sync_no_filter.conf index 1fe748a9590..62b952a7e89 100644 --- a/tests/bluetooth/init/prj_ctlr_per_sync_no_filter.conf +++ b/tests/bluetooth/init/prj_ctlr_per_sync_no_filter.conf @@ -12,4 +12,3 @@ CONFIG_BT_CTLR_SYNC_PERIODIC=y CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_peripheral.conf b/tests/bluetooth/init/prj_ctlr_peripheral.conf index 60f89899c28..3a41b00e864 100644 --- a/tests/bluetooth/init/prj_ctlr_peripheral.conf +++ b/tests/bluetooth/init/prj_ctlr_peripheral.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_peripheral_ext.conf b/tests/bluetooth/init/prj_ctlr_peripheral_ext.conf index f2e3218db6d..9f1b6919aa9 100644 --- a/tests/bluetooth/init/prj_ctlr_peripheral_ext.conf +++ b/tests/bluetooth/init/prj_ctlr_peripheral_ext.conf @@ -8,4 +8,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_peripheral_ext_priv.conf b/tests/bluetooth/init/prj_ctlr_peripheral_ext_priv.conf index e7e5ac7ed7b..e0c3f9487c0 100644 --- a/tests/bluetooth/init/prj_ctlr_peripheral_ext_priv.conf +++ b/tests/bluetooth/init/prj_ctlr_peripheral_ext_priv.conf @@ -10,4 +10,3 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_CTLR_ADV_EXT=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_peripheral_iso.conf b/tests/bluetooth/init/prj_ctlr_peripheral_iso.conf index 5efb8c6b848..c2e3ca23a5b 100644 --- a/tests/bluetooth/init/prj_ctlr_peripheral_iso.conf +++ b/tests/bluetooth/init/prj_ctlr_peripheral_iso.conf @@ -10,4 +10,3 @@ CONFIG_BT_CTLR_ADVANCED_FEATURES=y CONFIG_BT_CTLR_PERIPHERAL_ISO_EARLY_CIG_START=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_peripheral_priv.conf b/tests/bluetooth/init/prj_ctlr_peripheral_priv.conf index a7628e54aec..9175c302272 100644 --- a/tests/bluetooth/init/prj_ctlr_peripheral_priv.conf +++ b/tests/bluetooth/init/prj_ctlr_peripheral_priv.conf @@ -10,4 +10,3 @@ CONFIG_BT_EXT_ADV=n CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_sync_iso.conf b/tests/bluetooth/init/prj_ctlr_sync_iso.conf index 8ae4e44e450..c61443085e1 100644 --- a/tests/bluetooth/init/prj_ctlr_sync_iso.conf +++ b/tests/bluetooth/init/prj_ctlr_sync_iso.conf @@ -11,4 +11,3 @@ CONFIG_BT_CTLR_SYNC_PERIODIC=y CONFIG_BT_CTLR_SYNC_ISO=y CONFIG_BT_LL_SW_SPLIT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf index 4e5b962231e..efeae970f31 100644 --- a/tests/bluetooth/init/prj_ctlr_ticker.conf +++ b/tests/bluetooth/init/prj_ctlr_ticker.conf @@ -61,4 +61,3 @@ CONFIG_DEBUG=y CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_ctlr_tiny.conf b/tests/bluetooth/init/prj_ctlr_tiny.conf index ce75583da16..f0056881680 100644 --- a/tests/bluetooth/init/prj_ctlr_tiny.conf +++ b/tests/bluetooth/init/prj_ctlr_tiny.conf @@ -44,4 +44,3 @@ CONFIG_ASSERT=n CONFIG_FLASH=y CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_h5.conf b/tests/bluetooth/init/prj_h5.conf index 5a1eb7ae2c6..976697e3dba 100644 --- a/tests/bluetooth/init/prj_h5.conf +++ b/tests/bluetooth/init/prj_h5.conf @@ -1,4 +1,3 @@ CONFIG_BT=y CONFIG_BT_H5=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_h5_dbg.conf b/tests/bluetooth/init/prj_h5_dbg.conf index 28ef86d3e09..a0e25ac20d2 100644 --- a/tests/bluetooth/init/prj_h5_dbg.conf +++ b/tests/bluetooth/init/prj_h5_dbg.conf @@ -3,4 +3,3 @@ CONFIG_BT_H5=y CONFIG_LOG=y CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/prj_llcp.conf b/tests/bluetooth/init/prj_llcp.conf index ffa52753363..626e6c40e2b 100644 --- a/tests/bluetooth/init/prj_llcp.conf +++ b/tests/bluetooth/init/prj_llcp.conf @@ -16,4 +16,3 @@ CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=y CONFIG_BT_CTLR_ADVANCED_FEATURES=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/l2cap/prj.conf b/tests/bluetooth/l2cap/prj.conf index 3a7449d2618..69eb3d64ca7 100644 --- a/tests/bluetooth/l2cap/prj.conf +++ b/tests/bluetooth/l2cap/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/bluetooth/ll_settings/prj.conf b/tests/bluetooth/ll_settings/prj.conf index eddcfe8428b..ab133036bf9 100644 --- a/tests/bluetooth/ll_settings/prj.conf +++ b/tests/bluetooth/ll_settings/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=y diff --git a/tests/bluetooth/mesh/blob_io_flash/prj.conf b/tests/bluetooth/mesh/blob_io_flash/prj.conf index e65e7914724..2a0e98421fa 100644 --- a/tests/bluetooth/mesh/blob_io_flash/prj.conf +++ b/tests/bluetooth/mesh/blob_io_flash/prj.conf @@ -19,5 +19,3 @@ CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_BLOB_SRV=y CONFIG_BT_MESH_BLOB_CLI=y CONFIG_BT_MESH_BLOB_IO_FLASH=y - -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/mesh/rpl/prj.conf b/tests/bluetooth/mesh/rpl/prj.conf index 0d11d85e2fa..31c31ebcd12 100644 --- a/tests/bluetooth/mesh/rpl/prj.conf +++ b/tests/bluetooth/mesh/rpl/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_MOCKING=y diff --git a/tests/bluetooth/uuid/prj.conf b/tests/bluetooth/uuid/prj.conf index 84088e6b035..fec5098eecf 100644 --- a/tests/bluetooth/uuid/prj.conf +++ b/tests/bluetooth/uuid/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BT=y CONFIG_BT_CTLR=n diff --git a/tests/boards/altera_max10/i2c_master/prj.conf b/tests/boards/altera_max10/i2c_master/prj.conf index 875d1696308..3ec96195906 100644 --- a/tests/boards/altera_max10/i2c_master/prj.conf +++ b/tests/boards/altera_max10/i2c_master/prj.conf @@ -1,4 +1,3 @@ CONFIG_I2C=y CONFIG_I2C_INIT_PRIORITY=60 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/altera_max10/msgdma/prj.conf b/tests/boards/altera_max10/msgdma/prj.conf index 1d460e0c60f..ac2c3481e93 100644 --- a/tests/boards/altera_max10/msgdma/prj.conf +++ b/tests/boards/altera_max10/msgdma/prj.conf @@ -1,3 +1,2 @@ CONFIG_DMA=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/altera_max10/qspi/prj.conf b/tests/boards/altera_max10/qspi/prj.conf index 3c9f3c6f619..c1de9b374e2 100644 --- a/tests/boards/altera_max10/qspi/prj.conf +++ b/tests/boards/altera_max10/qspi/prj.conf @@ -2,4 +2,3 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_FLASH=y CONFIG_SOC_FLASH_NIOS2_QSPI=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/altera_max10/sysid/prj.conf b/tests/boards/altera_max10/sysid/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/boards/altera_max10/sysid/prj.conf +++ b/tests/boards/altera_max10/sysid/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/espressif_esp32/cache_coex/prj.conf b/tests/boards/espressif_esp32/cache_coex/prj.conf index 6265acda775..577a3f115e1 100644 --- a/tests/boards/espressif_esp32/cache_coex/prj.conf +++ b/tests/boards/espressif_esp32/cache_coex/prj.conf @@ -5,4 +5,3 @@ CONFIG_ESP_HEAP_SEARCH_ALL_REGIONS=n CONFIG_FLASH=y CONFIG_ENTROPY_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/frdm_k64f/i2c/prj.conf b/tests/boards/frdm_k64f/i2c/prj.conf index cc1ebd041b5..21a62cda1d8 100644 --- a/tests/boards/frdm_k64f/i2c/prj.conf +++ b/tests/boards/frdm_k64f/i2c/prj.conf @@ -3,4 +3,3 @@ CONFIG_I2C_CALLBACK=y CONFIG_POLL=y CONFIG_I2C_INIT_PRIORITY=60 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/intel_adsp/cache/prj.conf b/tests/boards/intel_adsp/cache/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/boards/intel_adsp/cache/prj.conf +++ b/tests/boards/intel_adsp/cache/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/intel_adsp/hda/prj.conf b/tests/boards/intel_adsp/hda/prj.conf index a91b5e32bbd..0d43e90cdf3 100644 --- a/tests/boards/intel_adsp/hda/prj.conf +++ b/tests/boards/intel_adsp/hda/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DMA=y diff --git a/tests/boards/intel_adsp/hda_log/prj.conf b/tests/boards/intel_adsp/hda_log/prj.conf index 0e6000bdc4f..2fd4793b5d9 100644 --- a/tests/boards/intel_adsp/hda_log/prj.conf +++ b/tests/boards/intel_adsp/hda_log/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DMA=y CONFIG_ASSERT=y CONFIG_LOG=y diff --git a/tests/boards/intel_adsp/mm/prj.conf b/tests/boards/intel_adsp/mm/prj.conf index 7ccdfd1ddf2..06a1545dad7 100644 --- a/tests/boards/intel_adsp/mm/prj.conf +++ b/tests/boards/intel_adsp/mm/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MM_DRV=y diff --git a/tests/boards/intel_adsp/smoke/prj.conf b/tests/boards/intel_adsp/smoke/prj.conf index 0ab9b6f7c60..a30e22b8c55 100644 --- a/tests/boards/intel_adsp/smoke/prj.conf +++ b/tests/boards/intel_adsp/smoke/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SMP=y CONFIG_SMP_BOOT_DELAY=y CONFIG_SCHED_CPU_MASK=y diff --git a/tests/boards/intel_adsp/ssp/prj.conf b/tests/boards/intel_adsp/ssp/prj.conf index 49124c6d82c..5acbe35fdf4 100644 --- a/tests/boards/intel_adsp/ssp/prj.conf +++ b/tests/boards/intel_adsp/ssp/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DAI=y CONFIG_INTEL_MN=y CONFIG_DMA_DW_HOST_MASK=1 diff --git a/tests/boards/mec15xxevb_assy6853/i2c_api/prj.conf b/tests/boards/mec15xxevb_assy6853/i2c_api/prj.conf index 7e3f6b38804..4b19609ecfb 100644 --- a/tests/boards/mec15xxevb_assy6853/i2c_api/prj.conf +++ b/tests/boards/mec15xxevb_assy6853/i2c_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_I2C=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/mec15xxevb_assy6853/qspi/prj.conf b/tests/boards/mec15xxevb_assy6853/qspi/prj.conf index 0637abd47e2..45cd80f14c1 100644 --- a/tests/boards/mec15xxevb_assy6853/qspi/prj.conf +++ b/tests/boards/mec15xxevb_assy6853/qspi/prj.conf @@ -1,5 +1,4 @@ CONFIG_SPI=y CONFIG_SPI_EXTENDED_MODES=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/boards/mec172xevb_assy6906/i2c_api/prj.conf b/tests/boards/mec172xevb_assy6906/i2c_api/prj.conf index 7e3f6b38804..4b19609ecfb 100644 --- a/tests/boards/mec172xevb_assy6906/i2c_api/prj.conf +++ b/tests/boards/mec172xevb_assy6906/i2c_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_I2C=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/mec172xevb_assy6906/qspi/prj.conf b/tests/boards/mec172xevb_assy6906/qspi/prj.conf index 0637abd47e2..45cd80f14c1 100644 --- a/tests/boards/mec172xevb_assy6906/qspi/prj.conf +++ b/tests/boards/mec172xevb_assy6906/qspi/prj.conf @@ -1,5 +1,4 @@ CONFIG_SPI=y CONFIG_SPI_EXTENDED_MODES=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/boards/native_posix/cpu_wait/prj.conf b/tests/boards/native_posix/cpu_wait/prj.conf index 55d02e5dad7..868a51c52b0 100644 --- a/tests/boards/native_posix/cpu_wait/prj.conf +++ b/tests/boards/native_posix/cpu_wait/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TICKLESS_KERNEL=n CONFIG_ZTEST_THREAD_PRIORITY=1 diff --git a/tests/boards/native_posix/rtc/prj.conf b/tests/boards/native_posix/rtc/prj.conf index 82d90a522d3..686b5a9dee3 100644 --- a/tests/boards/native_posix/rtc/prj.conf +++ b/tests/boards/native_posix/rtc/prj.conf @@ -1,3 +1,2 @@ CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/boards/nrf52_bsim/egu/prj.conf b/tests/boards/nrf52_bsim/egu/prj.conf index bcc4d42973f..ac89734f004 100644 --- a/tests/boards/nrf52_bsim/egu/prj.conf +++ b/tests/boards/nrf52_bsim/egu/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GEN_IRQ_VECTOR_TABLE=y CONFIG_DYNAMIC_INTERRUPTS=y diff --git a/tests/boot/mcuboot_data_sharing/prj.conf b/tests/boot/mcuboot_data_sharing/prj.conf index a5a00851f52..ba709fadb62 100644 --- a/tests/boot/mcuboot_data_sharing/prj.conf +++ b/tests/boot/mcuboot_data_sharing/prj.conf @@ -4,7 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_RETAINED_MEM=y CONFIG_RETENTION=y CONFIG_SETTINGS=y diff --git a/tests/cmake/overlays/var_expansions/prj.conf b/tests/cmake/overlays/var_expansions/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/cmake/overlays/var_expansions/prj.conf +++ b/tests/cmake/overlays/var_expansions/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/cmake/snippets/prj.conf b/tests/cmake/snippets/prj.conf index 32b9aa38ccc..4eb46139fd2 100644 --- a/tests/cmake/snippets/prj.conf +++ b/tests/cmake/snippets/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_FOO_VAL=774392 CONFIG_TEST_BAR_VAL=182834 CONFIG_TEST_COMMON_VAL=588411 diff --git a/tests/crypto/crypto_hash/prj.conf b/tests/crypto/crypto_hash/prj.conf index 0b8d6e2aa48..5aba0ef5c39 100644 --- a/tests/crypto/crypto_hash/prj.conf +++ b/tests/crypto/crypto_hash/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y diff --git a/tests/crypto/mbedtls/prj.conf b/tests/crypto/mbedtls/prj.conf index 7532e84b251..9b6af503e03 100644 --- a/tests/crypto/mbedtls/prj.conf +++ b/tests/crypto/mbedtls/prj.conf @@ -3,7 +3,6 @@ CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y CONFIG_MINIMAL_LIBC_RAND=y diff --git a/tests/crypto/rand32/prj.conf b/tests/crypto/rand32/prj.conf index 78b88c04317..420e89ab17f 100644 --- a/tests/crypto/rand32/prj.conf +++ b/tests/crypto/rand32/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/crypto/rand32/prj_ctr_drbg.conf b/tests/crypto/rand32/prj_ctr_drbg.conf index e5848839734..996a530cd41 100644 --- a/tests/crypto/rand32/prj_ctr_drbg.conf +++ b/tests/crypto/rand32/prj_ctr_drbg.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/crypto/rand32/prj_hw_random_psa_crypto.conf b/tests/crypto/rand32/prj_hw_random_psa_crypto.conf index 91638df0cf3..4c6c2180c46 100644 --- a/tests/crypto/rand32/prj_hw_random_psa_crypto.conf +++ b/tests/crypto/rand32/prj_hw_random_psa_crypto.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_HARDWARE_DEVICE_CS_GENERATOR=y diff --git a/tests/crypto/rand32/prj_hw_random_xoshiro.conf b/tests/crypto/rand32/prj_hw_random_xoshiro.conf index 97b69d65f39..aaabc2e41c9 100644 --- a/tests/crypto/rand32/prj_hw_random_xoshiro.conf +++ b/tests/crypto/rand32/prj_hw_random_xoshiro.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_XOSHIRO_RANDOM_GENERATOR=y diff --git a/tests/crypto/rand32/prj_sw_random_systimer.conf b/tests/crypto/rand32/prj_sw_random_systimer.conf index 2adbee9e418..6a6c996b86b 100644 --- a/tests/crypto/rand32/prj_sw_random_systimer.conf +++ b/tests/crypto/rand32/prj_sw_random_systimer.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/crypto/tinycrypt/prj.conf b/tests/crypto/tinycrypt/prj.conf index 8869f167ef3..4cb73548b4f 100644 --- a/tests/crypto/tinycrypt/prj.conf +++ b/tests/crypto/tinycrypt/prj.conf @@ -13,4 +13,3 @@ CONFIG_TINYCRYPT_ECC_DH=y CONFIG_TINYCRYPT_ECC_DSA=y CONFIG_ZTEST_STACK_SIZE=5120 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/crypto/tinycrypt_hmac_prng/prj.conf b/tests/crypto/tinycrypt_hmac_prng/prj.conf index 718b2bb5dc2..8e3d3dbd042 100644 --- a/tests/crypto/tinycrypt_hmac_prng/prj.conf +++ b/tests/crypto/tinycrypt_hmac_prng/prj.conf @@ -4,4 +4,3 @@ CONFIG_TINYCRYPT_SHA256=y CONFIG_TINYCRYPT_SHA256_HMAC=y CONFIG_TINYCRYPT_SHA256_HMAC_PRNG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/adc/adc_api/prj.conf b/tests/drivers/adc/adc_api/prj.conf index 94f86d9fcb4..d95ab6031c2 100644 --- a/tests/drivers/adc/adc_api/prj.conf +++ b/tests/drivers/adc/adc_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ADC=y CONFIG_ADC_ASYNC=y diff --git a/tests/drivers/adc/adc_dma/prj.conf b/tests/drivers/adc/adc_dma/prj.conf index 81a73e12de1..e2b567f4bd8 100644 --- a/tests/drivers/adc/adc_dma/prj.conf +++ b/tests/drivers/adc/adc_dma/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ADC=y CONFIG_ADC_LOG_LEVEL_INF=y diff --git a/tests/drivers/adc/adc_emul/prj.conf b/tests/drivers/adc/adc_emul/prj.conf index eaab1b20102..ab4663f4f9b 100644 --- a/tests/drivers/adc/adc_emul/prj.conf +++ b/tests/drivers/adc/adc_emul/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ADC=y CONFIG_ADC_LOG_LEVEL_INF=y diff --git a/tests/drivers/adc/adc_rescale/prj.conf b/tests/drivers/adc/adc_rescale/prj.conf index eaab1b20102..ab4663f4f9b 100644 --- a/tests/drivers/adc/adc_rescale/prj.conf +++ b/tests/drivers/adc/adc_rescale/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ADC=y CONFIG_ADC_LOG_LEVEL_INF=y diff --git a/tests/drivers/bbram/emul/prj.conf b/tests/drivers/bbram/emul/prj.conf index 79984859b7e..61986e63a19 100644 --- a/tests/drivers/bbram/emul/prj.conf +++ b/tests/drivers/bbram/emul/prj.conf @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BBRAM=y diff --git a/tests/drivers/bbram/prj.conf b/tests/drivers/bbram/prj.conf index 79984859b7e..61986e63a19 100644 --- a/tests/drivers/bbram/prj.conf +++ b/tests/drivers/bbram/prj.conf @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BBRAM=y diff --git a/tests/drivers/bc12/prj.conf b/tests/drivers/bc12/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/bc12/prj.conf +++ b/tests/drivers/bc12/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/build_all/sensor/testcase.yaml b/tests/drivers/build_all/sensor/testcase.yaml index 1d69f1ae8d0..eeca799df94 100644 --- a/tests/drivers/build_all/sensor/testcase.yaml +++ b/tests/drivers/build_all/sensor/testcase.yaml @@ -26,7 +26,6 @@ tests: extra_configs: - CONFIG_GENERIC_SENSOR_TEST=y - CONFIG_ZTEST=y - - CONFIG_ZTEST_NEW_API=y - CONFIG_EMUL=y - CONFIG_NATIVE_UART_0_ON_STDINOUT=y - CONFIG_SENSOR_ASYNC_API=y diff --git a/tests/drivers/can/api/prj.conf b/tests/drivers/can/api/prj.conf index 8fa4d640945..dfd79c22526 100644 --- a/tests/drivers/can/api/prj.conf +++ b/tests/drivers/can/api/prj.conf @@ -3,6 +3,5 @@ CONFIG_CAN_FD_MODE=y CONFIG_CAN_AUTO_BUS_OFF_RECOVERY=n CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # The canfd test suite may be skipped CONFIG_ZTEST_VERIFY_RUN_ALL=n diff --git a/tests/drivers/can/shell/prj.conf b/tests/drivers/can/shell/prj.conf index fd34da718d2..15c6eafdff7 100644 --- a/tests/drivers/can/shell/prj.conf +++ b/tests/drivers/can/shell/prj.conf @@ -6,5 +6,4 @@ CONFIG_CAN_AUTO_BUS_OFF_RECOVERY=n CONFIG_CAN_FD_MODE=y CONFIG_CAN_SHELL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=1536 diff --git a/tests/drivers/can/timing/prj.conf b/tests/drivers/can/timing/prj.conf index 52b5adf9c2d..137d8604819 100644 --- a/tests/drivers/can/timing/prj.conf +++ b/tests/drivers/can/timing/prj.conf @@ -2,4 +2,3 @@ CONFIG_CAN=y CONFIG_CAN_FD_MODE=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/charger/sbs_charger/prj.conf b/tests/drivers/charger/sbs_charger/prj.conf index be0b77722e0..9703f17c7cb 100644 --- a/tests/drivers/charger/sbs_charger/prj.conf +++ b/tests/drivers/charger/sbs_charger/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/clock_control/adsp_clock/prj.conf b/tests/drivers/clock_control/adsp_clock/prj.conf index 664faa92589..903dc40185b 100644 --- a/tests/drivers/clock_control/adsp_clock/prj.conf +++ b/tests/drivers/clock_control/adsp_clock/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CLOCK_CONTROL=y diff --git a/tests/drivers/clock_control/clock_control_api/nrf_lfclk_rc.conf b/tests/drivers/clock_control/clock_control_api/nrf_lfclk_rc.conf index 5ac091262bd..46e88f7b150 100644 --- a/tests/drivers/clock_control/clock_control_api/nrf_lfclk_rc.conf +++ b/tests/drivers/clock_control/clock_control_api/nrf_lfclk_rc.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=n diff --git a/tests/drivers/clock_control/clock_control_api/prj.conf b/tests/drivers/clock_control/clock_control_api/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/clock_control_api/prj.conf +++ b/tests/drivers/clock_control/clock_control_api/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/fixed_clock/prj.conf b/tests/drivers/clock_control/fixed_clock/prj.conf index b60d57cd846..bbeba0a33c4 100644 --- a/tests/drivers/clock_control/fixed_clock/prj.conf +++ b/tests/drivers/clock_control/fixed_clock/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL_FIXED_RATE_CLOCK=y diff --git a/tests/drivers/clock_control/nrf_clock_calibration/prj.conf b/tests/drivers/clock_control/nrf_clock_calibration/prj.conf index e885da62fd6..5c7bfc52ad7 100644 --- a/tests/drivers/clock_control/nrf_clock_calibration/prj.conf +++ b/tests/drivers/clock_control/nrf_clock_calibration/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP=1 CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_TEMP_DIFF=2 diff --git a/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf b/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf +++ b/tests/drivers/clock_control/nrf_lf_clock_start/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/nrf_onoff_and_bt/prj.conf b/tests/drivers/clock_control/nrf_onoff_and_bt/prj.conf index 8471c482366..d25c9c7d100 100644 --- a/tests/drivers/clock_control/nrf_onoff_and_bt/prj.conf +++ b/tests/drivers/clock_control/nrf_onoff_and_bt/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/drivers/clock_control/onoff/prj.conf b/tests/drivers/clock_control/onoff/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/onoff/prj.conf +++ b/tests/drivers/clock_control/onoff/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h5_core/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_core/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/prj.conf +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32wba_core/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/coredump/coredump_api/prj.conf b/tests/drivers/coredump/coredump_api/prj.conf index 55308753805..9684306ce68 100644 --- a/tests/drivers/coredump/coredump_api/prj.conf +++ b/tests/drivers/coredump/coredump_api/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_COREDUMP_DEVICE=y diff --git a/tests/drivers/counter/counter_basic_api/prj.conf b/tests/drivers/counter/counter_basic_api/prj.conf index 934b7d4a9de..cc386ea8623 100644 --- a/tests/drivers/counter/counter_basic_api/prj.conf +++ b/tests/drivers/counter/counter_basic_api/prj.conf @@ -1,6 +1,5 @@ CONFIG_COUNTER=y CONFIG_BT=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/counter/counter_nrf_rtc/fixed_top/prj.conf b/tests/drivers/counter/counter_nrf_rtc/fixed_top/prj.conf index cf88000ca13..e00e8973c78 100644 --- a/tests/drivers/counter/counter_nrf_rtc/fixed_top/prj.conf +++ b/tests/drivers/counter/counter_nrf_rtc/fixed_top/prj.conf @@ -1,4 +1,3 @@ CONFIG_COUNTER=y CONFIG_BT=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/counter/counter_seconds/prj.conf b/tests/drivers/counter/counter_seconds/prj.conf index ebdc464620e..e99f557e87c 100644 --- a/tests/drivers/counter/counter_seconds/prj.conf +++ b/tests/drivers/counter/counter_seconds/prj.conf @@ -1,3 +1,2 @@ CONFIG_COUNTER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/counter/maxim_ds3231_api/prj.conf b/tests/drivers/counter/maxim_ds3231_api/prj.conf index ca174661fcb..7efb84aa558 100644 --- a/tests/drivers/counter/maxim_ds3231_api/prj.conf +++ b/tests/drivers/counter/maxim_ds3231_api/prj.conf @@ -4,6 +4,5 @@ CONFIG_COUNTER_MAXIM_DS3231=y CONFIG_COUNTER_INIT_PRIORITY=65 CONFIG_BT=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/dac/dac_api/prj.conf b/tests/drivers/dac/dac_api/prj.conf index 7e6cabcc12b..c9ef47c7248 100644 --- a/tests/drivers/dac/dac_api/prj.conf +++ b/tests/drivers/dac/dac_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DAC=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/dac/dac_loopback/prj.conf b/tests/drivers/dac/dac_loopback/prj.conf index a5f652dd229..4ec36d6e3e0 100644 --- a/tests/drivers/dac/dac_loopback/prj.conf +++ b/tests/drivers/dac/dac_loopback/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DAC=y CONFIG_ADC=y diff --git a/tests/drivers/disk/disk_access/prj.conf b/tests/drivers/disk/disk_access/prj.conf index 2fa7f3a59f1..0fbfa56642f 100644 --- a/tests/drivers/disk/disk_access/prj.conf +++ b/tests/drivers/disk/disk_access/prj.conf @@ -1,4 +1,3 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DISK_ACCESS=y diff --git a/tests/drivers/disk/disk_performance/prj.conf b/tests/drivers/disk/disk_performance/prj.conf index 8973b711ba5..db25d96059d 100644 --- a/tests/drivers/disk/disk_performance/prj.conf +++ b/tests/drivers/disk/disk_performance/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DISK_ACCESS=y CONFIG_TIMING_FUNCTIONS=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/drivers/dma/chan_blen_transfer/prj.conf b/tests/drivers/dma/chan_blen_transfer/prj.conf index 178b21813f2..605d90989ed 100644 --- a/tests/drivers/dma/chan_blen_transfer/prj.conf +++ b/tests/drivers/dma/chan_blen_transfer/prj.conf @@ -2,4 +2,3 @@ CONFIG_DMA=y CONFIG_ZTEST=y CONFIG_LOG=y CONFIG_DMA_LOG_LEVEL_INF=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/dma/chan_link_transfer/prj.conf b/tests/drivers/dma/chan_link_transfer/prj.conf index 178b21813f2..605d90989ed 100644 --- a/tests/drivers/dma/chan_link_transfer/prj.conf +++ b/tests/drivers/dma/chan_link_transfer/prj.conf @@ -2,4 +2,3 @@ CONFIG_DMA=y CONFIG_ZTEST=y CONFIG_LOG=y CONFIG_DMA_LOG_LEVEL_INF=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/dma/loop_transfer/prj.conf b/tests/drivers/dma/loop_transfer/prj.conf index 809f21a15e7..40e96629277 100644 --- a/tests/drivers/dma/loop_transfer/prj.conf +++ b/tests/drivers/dma/loop_transfer/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_DMA=y CONFIG_LOG=y CONFIG_DMA_LOG_LEVEL_INF=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/dma/scatter_gather/prj.conf b/tests/drivers/dma/scatter_gather/prj.conf index 809f21a15e7..40e96629277 100644 --- a/tests/drivers/dma/scatter_gather/prj.conf +++ b/tests/drivers/dma/scatter_gather/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_DMA=y CONFIG_LOG=y CONFIG_DMA_LOG_LEVEL_INF=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/eeprom/api/prj.conf b/tests/drivers/eeprom/api/prj.conf index e6a92b035af..97ba3259588 100644 --- a/tests/drivers/eeprom/api/prj.conf +++ b/tests/drivers/eeprom/api/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_EEPROM=y diff --git a/tests/drivers/eeprom/shell/prj.conf b/tests/drivers/eeprom/shell/prj.conf index b3aeff1e25a..82e8a22cf7b 100644 --- a/tests/drivers/eeprom/shell/prj.conf +++ b/tests/drivers/eeprom/shell/prj.conf @@ -5,4 +5,3 @@ CONFIG_EEPROM=y CONFIG_EEPROM_SHELL=y CONFIG_EEPROM_SHELL_BUFFER_SIZE=8 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/entropy/api/prj.conf b/tests/drivers/entropy/api/prj.conf index aa099f9564f..a33b10382d4 100644 --- a/tests/drivers/entropy/api/prj.conf +++ b/tests/drivers/entropy/api/prj.conf @@ -1,3 +1,2 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/espi/prj.conf b/tests/drivers/espi/prj.conf index df2c524adf9..cb0a355b123 100644 --- a/tests/drivers/espi/prj.conf +++ b/tests/drivers/espi/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ESPI=y CONFIG_EMUL=y CONFIG_EMUL_ESPI_HOST=y diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf b/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf index ec2681e0763..c1f98dab82f 100644 --- a/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf +++ b/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_OPENAMP=y diff --git a/tests/drivers/flash/common/prj.conf b/tests/drivers/flash/common/prj.conf index cb2c08a8bd1..cffa07b7f26 100644 --- a/tests/drivers/flash/common/prj.conf +++ b/tests/drivers/flash/common/prj.conf @@ -1,5 +1,4 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/drivers/flash/stm32/prj.conf b/tests/drivers/flash/stm32/prj.conf index 68d772c1946..15aa2063b47 100644 --- a/tests/drivers/flash/stm32/prj.conf +++ b/tests/drivers/flash/stm32/prj.conf @@ -1,6 +1,5 @@ CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_EX_OP_ENABLED=y diff --git a/tests/drivers/flash_simulator/prj.conf b/tests/drivers/flash_simulator/prj.conf index ecaec58f5c6..c9fb30e0402 100644 --- a/tests/drivers/flash_simulator/prj.conf +++ b/tests/drivers/flash_simulator/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_SIMULATOR=y CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=n diff --git a/tests/drivers/fuel_gauge/bq27z746/prj.conf b/tests/drivers/fuel_gauge/bq27z746/prj.conf index 23ceb0b3cdd..ce11abb435a 100644 --- a/tests/drivers/fuel_gauge/bq27z746/prj.conf +++ b/tests/drivers/fuel_gauge/bq27z746/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_I2C=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/fuel_gauge/max17048/prj.conf b/tests/drivers/fuel_gauge/max17048/prj.conf index 23ceb0b3cdd..ce11abb435a 100644 --- a/tests/drivers/fuel_gauge/max17048/prj.conf +++ b/tests/drivers/fuel_gauge/max17048/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_I2C=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/fuel_gauge/sbs_gauge/prj.conf b/tests/drivers/fuel_gauge/sbs_gauge/prj.conf index 23ceb0b3cdd..ce11abb435a 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/prj.conf +++ b/tests/drivers/fuel_gauge/sbs_gauge/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_I2C=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/gpio/gpio_api_1pin/prj.conf b/tests/drivers/gpio/gpio_api_1pin/prj.conf index 962df8f1d50..0e799280f51 100644 --- a/tests/drivers/gpio/gpio_api_1pin/prj.conf +++ b/tests/drivers/gpio/gpio_api_1pin/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y diff --git a/tests/drivers/gpio/gpio_basic_api/prj.conf b/tests/drivers/gpio/gpio_basic_api/prj.conf index 41559c7df1f..b5511690df7 100644 --- a/tests/drivers/gpio/gpio_basic_api/prj.conf +++ b/tests/drivers/gpio/gpio_basic_api/prj.conf @@ -1,7 +1,6 @@ CONFIG_GPIO=y CONFIG_GPIO_GET_CONFIG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y #CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/gpio/gpio_enable_disable_interrupt/prj.conf b/tests/drivers/gpio/gpio_enable_disable_interrupt/prj.conf index 26e3362e645..510d8b6359c 100644 --- a/tests/drivers/gpio/gpio_enable_disable_interrupt/prj.conf +++ b/tests/drivers/gpio/gpio_enable_disable_interrupt/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT=y diff --git a/tests/drivers/gpio/gpio_get_direction/prj.conf b/tests/drivers/gpio/gpio_get_direction/prj.conf index 3d3a27cb855..11186aeb7fb 100644 --- a/tests/drivers/gpio/gpio_get_direction/prj.conf +++ b/tests/drivers/gpio/gpio_get_direction/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y CONFIG_GPIO_GET_DIRECTION=y diff --git a/tests/drivers/gpio/gpio_hogs/prj.conf b/tests/drivers/gpio/gpio_hogs/prj.conf index 7361f2b9ee8..4bb163987af 100644 --- a/tests/drivers/gpio/gpio_hogs/prj.conf +++ b/tests/drivers/gpio/gpio_hogs/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y CONFIG_GPIO_GET_DIRECTION=y CONFIG_GPIO_GET_CONFIG=y diff --git a/tests/drivers/gpio/gpio_reserved_ranges/prj.conf b/tests/drivers/gpio/gpio_reserved_ranges/prj.conf index 66f87b668e8..caec3b5f874 100644 --- a/tests/drivers/gpio/gpio_reserved_ranges/prj.conf +++ b/tests/drivers/gpio/gpio_reserved_ranges/prj.conf @@ -1,4 +1,3 @@ CONFIG_GPIO=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y #CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/hwinfo/api/prj.conf b/tests/drivers/hwinfo/api/prj.conf index b00bb9bf425..616a826fabb 100644 --- a/tests/drivers/hwinfo/api/prj.conf +++ b/tests/drivers/hwinfo/api/prj.conf @@ -1,3 +1,2 @@ CONFIG_HWINFO=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/i2c/i2c_api/prj.conf b/tests/drivers/i2c/i2c_api/prj.conf index 7e3f6b38804..4b19609ecfb 100644 --- a/tests/drivers/i2c/i2c_api/prj.conf +++ b/tests/drivers/i2c/i2c_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_I2C=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/i2c/i2c_target_api/prj.conf b/tests/drivers/i2c/i2c_target_api/prj.conf index 9fe909e2e72..b79f33ce0a9 100644 --- a/tests/drivers/i2c/i2c_target_api/prj.conf +++ b/tests/drivers/i2c/i2c_target_api/prj.conf @@ -2,7 +2,6 @@ CONFIG_LOG=y CONFIG_I2C_LOG_LEVEL_INF=y CONFIG_BOOT_BANNER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_I2C_EEPROM_TARGET=y diff --git a/tests/drivers/i2c/i2c_tca954x/prj.conf b/tests/drivers/i2c/i2c_tca954x/prj.conf index fc01984ad47..0066bf2a93c 100644 --- a/tests/drivers/i2c/i2c_tca954x/prj.conf +++ b/tests/drivers/i2c/i2c_tca954x/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_I2C=y CONFIG_I2C_TCA954X_ROOT_INIT_PRIO=61 CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO=62 diff --git a/tests/drivers/i2s/i2s_api/prj.conf b/tests/drivers/i2s/i2s_api/prj.conf index d225c836f56..7c088b1ffe4 100644 --- a/tests/drivers/i2s/i2s_api/prj.conf +++ b/tests/drivers/i2s/i2s_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_I2S=y CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/i2s/i2s_speed/prj.conf b/tests/drivers/i2s/i2s_speed/prj.conf index 018e9027158..99ff252406a 100644 --- a/tests/drivers/i2s/i2s_speed/prj.conf +++ b/tests/drivers/i2s/i2s_speed/prj.conf @@ -1,3 +1,2 @@ CONFIG_I2S=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/input/gpio_keys/prj.conf b/tests/drivers/input/gpio_keys/prj.conf index 0da3a38cadf..5cd6cb6ceb3 100644 --- a/tests/drivers/input/gpio_keys/prj.conf +++ b/tests/drivers/input/gpio_keys/prj.conf @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y CONFIG_INPUT=y CONFIG_INPUT_MODE_SYNCHRONOUS=y diff --git a/tests/drivers/kscan/kscan_api/mec15xxevb_assy6853.conf b/tests/drivers/kscan/kscan_api/mec15xxevb_assy6853.conf index c72a6a75259..ded66973827 100644 --- a/tests/drivers/kscan/kscan_api/mec15xxevb_assy6853.conf +++ b/tests/drivers/kscan/kscan_api/mec15xxevb_assy6853.conf @@ -1,3 +1,2 @@ CONFIG_KSCAN=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/kscan/kscan_api/prj.conf b/tests/drivers/kscan/kscan_api/prj.conf index b6f267a8907..f291b8d5b75 100644 --- a/tests/drivers/kscan/kscan_api/prj.conf +++ b/tests/drivers/kscan/kscan_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_KSCAN=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/kscan/kscan_input/prj.conf b/tests/drivers/kscan/kscan_input/prj.conf index 965fbe4cb78..79104173119 100644 --- a/tests/drivers/kscan/kscan_input/prj.conf +++ b/tests/drivers/kscan/kscan_input/prj.conf @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_KSCAN=y CONFIG_INPUT=y CONFIG_INPUT_MODE_SYNCHRONOUS=y diff --git a/tests/drivers/led/led_api/prj.conf b/tests/drivers/led/led_api/prj.conf index e50218a7c38..acfa3b1fa62 100644 --- a/tests/drivers/led/led_api/prj.conf +++ b/tests/drivers/led/led_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_LED=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_LOG=y diff --git a/tests/drivers/memc/ram/prj.conf b/tests/drivers/memc/ram/prj.conf index f4133ef834e..4aba052c6b4 100644 --- a/tests/drivers/memc/ram/prj.conf +++ b/tests/drivers/memc/ram/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_MEMC=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/mipi_dsi/api/prj.conf b/tests/drivers/mipi_dsi/api/prj.conf index 2d62518bcaf..f27ed3f141b 100644 --- a/tests/drivers/mipi_dsi/api/prj.conf +++ b/tests/drivers/mipi_dsi/api/prj.conf @@ -1,4 +1,3 @@ CONFIG_DISPLAY=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/mm/sys_mm_drv_api/prj.conf b/tests/drivers/mm/sys_mm_drv_api/prj.conf index 7ccdfd1ddf2..06a1545dad7 100644 --- a/tests/drivers/mm/sys_mm_drv_api/prj.conf +++ b/tests/drivers/mm/sys_mm_drv_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MM_DRV=y diff --git a/tests/drivers/mm/sys_mm_drv_bank/prj.conf b/tests/drivers/mm/sys_mm_drv_bank/prj.conf index 7ccdfd1ddf2..06a1545dad7 100644 --- a/tests/drivers/mm/sys_mm_drv_bank/prj.conf +++ b/tests/drivers/mm/sys_mm_drv_bank/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MM_DRV=y diff --git a/tests/drivers/pinctrl/api/prj.conf b/tests/drivers/pinctrl/api/prj.conf index 2068a8582f2..e2f20b2b829 100644 --- a/tests/drivers/pinctrl/api/prj.conf +++ b/tests/drivers/pinctrl/api/prj.conf @@ -2,6 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PINCTRL=y CONFIG_PINCTRL_DYNAMIC=y diff --git a/tests/drivers/pinctrl/gd32/prj.conf b/tests/drivers/pinctrl/gd32/prj.conf index 7bd26f0e73a..bb844ad2efa 100644 --- a/tests/drivers/pinctrl/gd32/prj.conf +++ b/tests/drivers/pinctrl/gd32/prj.conf @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PINCTRL_TEST_NON_STATIC=y diff --git a/tests/drivers/pinctrl/nrf/prj.conf b/tests/drivers/pinctrl/nrf/prj.conf index 217560e6308..5e341d7d387 100644 --- a/tests/drivers/pinctrl/nrf/prj.conf +++ b/tests/drivers/pinctrl/nrf/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PINCTRL_TEST_NON_STATIC=y diff --git a/tests/drivers/pwm/pwm_api/prj.conf b/tests/drivers/pwm/pwm_api/prj.conf index 7375a2bd0b4..21d92de3cb4 100644 --- a/tests/drivers/pwm/pwm_api/prj.conf +++ b/tests/drivers/pwm/pwm_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_PWM=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/pwm/pwm_loopback/prj.conf b/tests/drivers/pwm/pwm_loopback/prj.conf index 3d01d55ecb8..73f7ae3cd45 100644 --- a/tests/drivers/pwm/pwm_loopback/prj.conf +++ b/tests/drivers/pwm/pwm_loopback/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_PWM=y diff --git a/tests/drivers/regulator/api/prj.conf b/tests/drivers/regulator/api/prj.conf index cff67c610cd..27ddee1caa1 100644 --- a/tests/drivers/regulator/api/prj.conf +++ b/tests/drivers/regulator/api/prj.conf @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_REGULATOR=y diff --git a/tests/drivers/regulator/fixed/prj.conf b/tests/drivers/regulator/fixed/prj.conf index b127d7b5fac..1f835c10be6 100644 --- a/tests/drivers/regulator/fixed/prj.conf +++ b/tests/drivers/regulator/fixed/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_GPIO=y CONFIG_REGULATOR=y diff --git a/tests/drivers/regulator/voltage/prj.conf b/tests/drivers/regulator/voltage/prj.conf index b4cfccb82b3..2a0ced2728d 100644 --- a/tests/drivers/regulator/voltage/prj.conf +++ b/tests/drivers/regulator/voltage/prj.conf @@ -2,6 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ADC=y CONFIG_REGULATOR=y diff --git a/tests/drivers/retained_mem/api/prj.conf b/tests/drivers/retained_mem/api/prj.conf index bc2d8751acb..dced67bae05 100644 --- a/tests/drivers/retained_mem/api/prj.conf +++ b/tests/drivers/retained_mem/api/prj.conf @@ -1,3 +1,2 @@ CONFIG_RETAINED_MEM=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/rtc/rtc_api/prj.conf b/tests/drivers/rtc/rtc_api/prj.conf index 2d8e4c373a8..f03c21df912 100644 --- a/tests/drivers/rtc/rtc_api/prj.conf +++ b/tests/drivers/rtc/rtc_api/prj.conf @@ -3,4 +3,3 @@ CONFIG_RTC=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/rtc/rtc_api_helpers/prj.conf b/tests/drivers/rtc/rtc_api_helpers/prj.conf index 2d8e4c373a8..f03c21df912 100644 --- a/tests/drivers/rtc/rtc_api_helpers/prj.conf +++ b/tests/drivers/rtc/rtc_api_helpers/prj.conf @@ -3,4 +3,3 @@ CONFIG_RTC=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/rtc/shell/prj.conf b/tests/drivers/rtc/shell/prj.conf index 095af0ea29d..3629fad7e72 100644 --- a/tests/drivers/rtc/shell/prj.conf +++ b/tests/drivers/rtc/shell/prj.conf @@ -4,5 +4,4 @@ CONFIG_SHELL_BACKEND_DUMMY=y CONFIG_RTC=y CONFIG_RTC_SHELL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=1536 diff --git a/tests/drivers/sdhc/prj.conf b/tests/drivers/sdhc/prj.conf index 794d5e61d32..3dd36a8597a 100644 --- a/tests/drivers/sdhc/prj.conf +++ b/tests/drivers/sdhc/prj.conf @@ -1,4 +1,3 @@ CONFIG_TEST=y CONFIG_ZTEST=y CONFIG_SDHC=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/sensor/accel/prj.conf b/tests/drivers/sensor/accel/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/sensor/accel/prj.conf +++ b/tests/drivers/sensor/accel/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/sensor/akm09918c/prj.conf b/tests/drivers/sensor/akm09918c/prj.conf index 640be4b7c72..aa2dcfc0b9b 100644 --- a/tests/drivers/sensor/akm09918c/prj.conf +++ b/tests/drivers/sensor/akm09918c/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Set log levels CONFIG_I2C_LOG_LEVEL_WRN=y diff --git a/tests/drivers/sensor/generic/prj.conf b/tests/drivers/sensor/generic/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/drivers/sensor/generic/prj.conf +++ b/tests/drivers/sensor/generic/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/sensor/generic/prj_fpu.conf b/tests/drivers/sensor/generic/prj_fpu.conf index 9aa1950dbdb..b93a5675d97 100644 --- a/tests/drivers/sensor/generic/prj_fpu.conf +++ b/tests/drivers/sensor/generic/prj_fpu.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FPU=y diff --git a/tests/drivers/sensor/icm42688/prj.conf b/tests/drivers/sensor/icm42688/prj.conf index 39b8b60e462..61addc37590 100644 --- a/tests/drivers/sensor/icm42688/prj.conf +++ b/tests/drivers/sensor/icm42688/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Enable GPIO CONFIG_GPIO=y diff --git a/tests/drivers/sensor/ina230/prj.conf b/tests/drivers/sensor/ina230/prj.conf index b3d184bfa78..6ad5ef41b56 100644 --- a/tests/drivers/sensor/ina230/prj.conf +++ b/tests/drivers/sensor/ina230/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SENSOR=y CONFIG_EMUL=y diff --git a/tests/drivers/sensor/ina237/prj.conf b/tests/drivers/sensor/ina237/prj.conf index 3c7471b31b9..4e594c68f66 100644 --- a/tests/drivers/sensor/ina237/prj.conf +++ b/tests/drivers/sensor/ina237/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SENSOR=y CONFIG_EMUL=y diff --git a/tests/drivers/sensor/sbs_gauge/prj.conf b/tests/drivers/sensor/sbs_gauge/prj.conf index 58b778780af..7185ba608b4 100644 --- a/tests/drivers/sensor/sbs_gauge/prj.conf +++ b/tests/drivers/sensor/sbs_gauge/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SENSOR=y CONFIG_I2C=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/smbus/smbus_api/prj.conf b/tests/drivers/smbus/smbus_api/prj.conf index 5dc81c75693..92a1cb2ef95 100644 --- a/tests/drivers/smbus/smbus_api/prj.conf +++ b/tests/drivers/smbus/smbus_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SMBUS=y CONFIG_SMBUS_INTEL_PCH=y diff --git a/tests/drivers/smbus/smbus_emul/prj.conf b/tests/drivers/smbus/smbus_emul/prj.conf index 9dd20e84904..996a530cd41 100644 --- a/tests/drivers/smbus/smbus_emul/prj.conf +++ b/tests/drivers/smbus/smbus_emul/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/drivers/spi/dt_spec/prj.conf b/tests/drivers/spi/dt_spec/prj.conf index 34d372396ca..e86373a9930 100644 --- a/tests/drivers/spi/dt_spec/prj.conf +++ b/tests/drivers/spi/dt_spec/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SPI=y CONFIG_GPIO=y diff --git a/tests/drivers/spi/spi_loopback/prj.conf b/tests/drivers/spi/spi_loopback/prj.conf index 2f981c600ec..f0e641f7623 100644 --- a/tests/drivers/spi/spi_loopback/prj.conf +++ b/tests/drivers/spi/spi_loopback/prj.conf @@ -4,4 +4,3 @@ CONFIG_SPI=y CONFIG_SPI_ASYNC=y CONFIG_SPI_LOG_LEVEL_INF=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/drivers/syscon/prj.conf b/tests/drivers/syscon/prj.conf index 7dabbfb75d9..9970e77ce57 100644 --- a/tests/drivers/syscon/prj.conf +++ b/tests/drivers/syscon/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYSCON=y CONFIG_MMU=y CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y diff --git a/tests/drivers/timer/nrf_rtc_timer/prj.conf b/tests/drivers/timer/nrf_rtc_timer/prj.conf index d0b55e455c7..84caa9eb85b 100644 --- a/tests/drivers/timer/nrf_rtc_timer/prj.conf +++ b/tests/drivers/timer/nrf_rtc_timer/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 diff --git a/tests/drivers/uart/uart_async_api/prj.conf b/tests/drivers/uart/uart_async_api/prj.conf index 630e06c9306..ef0d6054812 100644 --- a/tests/drivers/uart/uart_async_api/prj.conf +++ b/tests/drivers/uart/uart_async_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/uart/uart_basic_api/prj.conf b/tests/drivers/uart/uart_basic_api/prj.conf index 56d8fda633b..d12c995df09 100644 --- a/tests/drivers/uart/uart_basic_api/prj.conf +++ b/tests/drivers/uart/uart_basic_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_SERIAL=y -CONFIG_ZTEST_NEW_API=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_ZTEST=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/drivers/uart/uart_basic_api/prj_poll.conf b/tests/drivers/uart/uart_basic_api/prj_poll.conf index 2840968fd40..772072f1c4d 100644 --- a/tests/drivers/uart/uart_basic_api/prj_poll.conf +++ b/tests/drivers/uart/uart_basic_api/prj_poll.conf @@ -1,4 +1,3 @@ CONFIG_SERIAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/drivers/uart/uart_basic_api/prj_shell.conf b/tests/drivers/uart/uart_basic_api/prj_shell.conf index a1bcae5b67e..6ecbf8931a4 100644 --- a/tests/drivers/uart/uart_basic_api/prj_shell.conf +++ b/tests/drivers/uart/uart_basic_api/prj_shell.conf @@ -1,7 +1,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL_CMD_BUFF_SIZE=90 CONFIG_SHELL=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/drivers/uart/uart_emul/prj.conf b/tests/drivers/uart/uart_emul/prj.conf index 99676d377b4..79043ef148e 100644 --- a/tests/drivers/uart/uart_emul/prj.conf +++ b/tests/drivers/uart/uart_emul/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SERIAL=y diff --git a/tests/drivers/uart/uart_mix_fifo_poll/prj.conf b/tests/drivers/uart/uart_mix_fifo_poll/prj.conf index ec19f1d90b5..fa22b3a47b8 100644 --- a/tests/drivers/uart/uart_mix_fifo_poll/prj.conf +++ b/tests/drivers/uart/uart_mix_fifo_poll/prj.conf @@ -1,6 +1,5 @@ CONFIG_SERIAL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_THREAD_PRIORITY=5 CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/drivers/uart/uart_pm/prj.conf b/tests/drivers/uart/uart_pm/prj.conf index fbd77228aa2..81baa4cf552 100644 --- a/tests/drivers/uart/uart_pm/prj.conf +++ b/tests/drivers/uart/uart_pm/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SERIAL=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y CONFIG_PM=y diff --git a/tests/drivers/udc/prj.conf b/tests/drivers/udc/prj.conf index 8d4e846b181..e57264e1a24 100644 --- a/tests/drivers/udc/prj.conf +++ b/tests/drivers/udc/prj.conf @@ -3,7 +3,6 @@ CONFIG_LOG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_UDC_DRIVER=y CONFIG_UDC_BUF_COUNT=32 diff --git a/tests/drivers/virtualization/ivshmem/plain/prj.conf b/tests/drivers/virtualization/ivshmem/plain/prj.conf index 208db061ed3..f3553216f5f 100644 --- a/tests/drivers/virtualization/ivshmem/plain/prj.conf +++ b/tests/drivers/virtualization/ivshmem/plain/prj.conf @@ -2,7 +2,6 @@ CONFIG_STACK_CANARIES=n CONFIG_INIT_STACKS=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_PCIE=y diff --git a/tests/drivers/w1/w1_api/prj.conf b/tests/drivers/w1/w1_api/prj.conf index d1c628b0bc7..44a7057de64 100644 --- a/tests/drivers/w1/w1_api/prj.conf +++ b/tests/drivers/w1/w1_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_W1=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/watchdog/wdt_basic_api/prj.conf b/tests/drivers/watchdog/wdt_basic_api/prj.conf index 4954b4358b0..fe10038e334 100644 --- a/tests/drivers/watchdog/wdt_basic_api/prj.conf +++ b/tests/drivers/watchdog/wdt_basic_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_WATCHDOG=y CONFIG_WDT_DISABLE_AT_BOOT=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BOOT_BANNER=n diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/prj.conf b/tests/drivers/watchdog/wdt_basic_reset_none/prj.conf index d4844704878..df54d156dc7 100644 --- a/tests/drivers/watchdog/wdt_basic_reset_none/prj.conf +++ b/tests/drivers/watchdog/wdt_basic_reset_none/prj.conf @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_WATCHDOG=y diff --git a/tests/kernel/cache/prj.conf b/tests/kernel/cache/prj.conf index 3971afe4e55..e39776e7067 100644 --- a/tests/kernel/cache/prj.conf +++ b/tests/kernel/cache/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/common/prj.conf b/tests/kernel/common/prj.conf index a31c6961785..eb2a4d4ccd8 100644 --- a/tests/kernel/common/prj.conf +++ b/tests/kernel/common/prj.conf @@ -6,4 +6,3 @@ CONFIG_BOOT_DELAY=500 CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_BOUNDS_CHECK_BYPASS_MITIGATION=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/condvar/condvar_api/prj.conf b/tests/kernel/condvar/condvar_api/prj.conf index 3fe44daafe5..13ae16f5400 100644 --- a/tests/kernel/condvar/condvar_api/prj.conf +++ b/tests/kernel/condvar/condvar_api/prj.conf @@ -3,4 +3,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/context/prj.conf b/tests/kernel/context/prj.conf index 1a2e48f4d80..b138c1a230f 100644 --- a/tests/kernel/context/prj.conf +++ b/tests/kernel/context/prj.conf @@ -4,4 +4,3 @@ CONFIG_ZTEST=y #CONFIG_ZTEST_STACK_SIZE=2048 #CONFIG_IDLE_STACK_SIZE=512 CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/device/prj.conf b/tests/kernel/device/prj.conf index bf4d69ece20..4818bf0f5f9 100644 --- a/tests/kernel/device/prj.conf +++ b/tests/kernel/device/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/early_sleep/prj.conf b/tests/kernel/early_sleep/prj.conf index a4371f75a4d..dc48ba72008 100644 --- a/tests/kernel/early_sleep/prj.conf +++ b/tests/kernel/early_sleep/prj.conf @@ -1,4 +1,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_ZTEST=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/events/event_api/prj.conf b/tests/kernel/events/event_api/prj.conf index 57c597956a4..43f8d28ad1e 100644 --- a/tests/kernel/events/event_api/prj.conf +++ b/tests/kernel/events/event_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_IRQ_OFFLOAD=y CONFIG_EVENTS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/events/sys_event/prj.conf b/tests/kernel/events/sys_event/prj.conf index 1e2b887abac..12449507de4 100644 --- a/tests/kernel/events/sys_event/prj.conf +++ b/tests/kernel/events/sys_event/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y CONFIG_EVENTS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/exception/prj.conf b/tests/kernel/fatal/exception/prj.conf index 348bab96d49..b06bc82f596 100644 --- a/tests/kernel/fatal/exception/prj.conf +++ b/tests/kernel/fatal/exception/prj.conf @@ -3,4 +3,3 @@ CONFIG_COVERAGE=n CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/exception/prj_arm_fpu_sharing.conf b/tests/kernel/fatal/exception/prj_arm_fpu_sharing.conf index caaba597a6e..b06edc0788b 100644 --- a/tests/kernel/fatal/exception/prj_arm_fpu_sharing.conf +++ b/tests/kernel/fatal/exception/prj_arm_fpu_sharing.conf @@ -5,4 +5,3 @@ CONFIG_ZTEST=y CONFIG_COVERAGE=n CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/exception/prj_armv8m_mpu_stack_guard.conf b/tests/kernel/fatal/exception/prj_armv8m_mpu_stack_guard.conf index 167d9c3a144..c8b61ce52f6 100644 --- a/tests/kernel/fatal/exception/prj_armv8m_mpu_stack_guard.conf +++ b/tests/kernel/fatal/exception/prj_armv8m_mpu_stack_guard.conf @@ -4,4 +4,3 @@ CONFIG_TEST_USERSPACE=y CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_BUILTIN_STACK_GUARD=n CONFIG_MPU_STACK_GUARD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/exception/protection_no_userspace.conf b/tests/kernel/fatal/exception/protection_no_userspace.conf index 6d333fb999c..ef423fc99da 100644 --- a/tests/kernel/fatal/exception/protection_no_userspace.conf +++ b/tests/kernel/fatal/exception/protection_no_userspace.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_COVERAGE=n CONFIG_TEST_USERSPACE=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/exception/sentinel.conf b/tests/kernel/fatal/exception/sentinel.conf index a875554f246..b4750a403c4 100644 --- a/tests/kernel/fatal/exception/sentinel.conf +++ b/tests/kernel/fatal/exception/sentinel.conf @@ -5,4 +5,3 @@ CONFIG_HW_STACK_PROTECTION=n CONFIG_ZTEST=y CONFIG_COVERAGE=n CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fatal/no-multithreading/prj.conf b/tests/kernel/fatal/no-multithreading/prj.conf index d981eb1d25e..b9f5efeec95 100644 --- a/tests/kernel/fatal/no-multithreading/prj.conf +++ b/tests/kernel/fatal/no-multithreading/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_COVERAGE=n CONFIG_TEST_USERSPACE=n CONFIG_MULTITHREADING=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fifo/fifo_api/prj.conf b/tests/kernel/fifo/fifo_api/prj.conf index 1d97b0e7c43..9a75212e89d 100644 --- a/tests/kernel/fifo/fifo_api/prj.conf +++ b/tests/kernel/fifo/fifo_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_IRQ_OFFLOAD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fifo/fifo_timeout/prj.conf b/tests/kernel/fifo/fifo_timeout/prj.conf index b45f6f7c6f4..4fb51ffd857 100644 --- a/tests/kernel/fifo/fifo_timeout/prj.conf +++ b/tests/kernel/fifo/fifo_timeout/prj.conf @@ -3,4 +3,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_TIMESLICING=n CONFIG_ASSERT_VERBOSE=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fifo/fifo_usage/prj.conf b/tests/kernel/fifo/fifo_usage/prj.conf index a5cc7194765..dfb5d99e39b 100644 --- a/tests/kernel/fifo/fifo_usage/prj.conf +++ b/tests/kernel/fifo/fifo_usage/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_IRQ_OFFLOAD=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fpu_sharing/float_disable/prj.conf b/tests/kernel/fpu_sharing/float_disable/prj.conf index fea7fb1f898..10a56920dcd 100644 --- a/tests/kernel/fpu_sharing/float_disable/prj.conf +++ b/tests/kernel/fpu_sharing/float_disable/prj.conf @@ -5,4 +5,3 @@ CONFIG_FPU_SHARING=y CONFIG_CBPRINTF_NANO=y CONFIG_MAIN_STACK_SIZE=1024 CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fpu_sharing/float_disable/prj_x86.conf b/tests/kernel/fpu_sharing/float_disable/prj_x86.conf index 7bc3bc35aed..ed987a5581e 100644 --- a/tests/kernel/fpu_sharing/float_disable/prj_x86.conf +++ b/tests/kernel/fpu_sharing/float_disable/prj_x86.conf @@ -3,4 +3,3 @@ CONFIG_TEST_USERSPACE=y CONFIG_FPU=y CONFIG_FPU_SHARING=y CONFIG_X86_SSE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/fpu_sharing/generic/prj.conf b/tests/kernel/fpu_sharing/generic/prj.conf index b655c5fef0f..1d88a6850a5 100644 --- a/tests/kernel/fpu_sharing/generic/prj.conf +++ b/tests/kernel/fpu_sharing/generic/prj.conf @@ -4,5 +4,4 @@ CONFIG_FPU_SHARING=y CONFIG_STDOUT_CONSOLE=y CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/fpu_sharing/generic/prj_x86.conf b/tests/kernel/fpu_sharing/generic/prj_x86.conf index f0e2d45ae8c..20c8ab24669 100644 --- a/tests/kernel/fpu_sharing/generic/prj_x86.conf +++ b/tests/kernel/fpu_sharing/generic/prj_x86.conf @@ -3,4 +3,3 @@ CONFIG_FPU=y CONFIG_X86_SSE=y CONFIG_FPU_SHARING=y CONFIG_STDOUT_CONSOLE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/gen_isr_table/prj.conf b/tests/kernel/gen_isr_table/prj.conf index 02a10f05087..a3f0a41c8d2 100644 --- a/tests/kernel/gen_isr_table/prj.conf +++ b/tests/kernel/gen_isr_table/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_DYNAMIC_INTERRUPTS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/interrupt/prj.conf b/tests/kernel/interrupt/prj.conf index 538b1511178..bfddd929c43 100644 --- a/tests/kernel/interrupt/prj.conf +++ b/tests/kernel/interrupt/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_THREAD_STACK_INFO=y diff --git a/tests/kernel/lifo/lifo_api/prj.conf b/tests/kernel/lifo/lifo_api/prj.conf index 1d97b0e7c43..9a75212e89d 100644 --- a/tests/kernel/lifo/lifo_api/prj.conf +++ b/tests/kernel/lifo/lifo_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_IRQ_OFFLOAD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/lifo/lifo_usage/prj.conf b/tests/kernel/lifo/lifo_usage/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/lifo/lifo_usage/prj.conf +++ b/tests/kernel/lifo/lifo_usage/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mbox/mbox_api/prj.conf b/tests/kernel/mbox/mbox_api/prj.conf index eda7ea93a01..bc5762b0edd 100644 --- a/tests/kernel/mbox/mbox_api/prj.conf +++ b/tests/kernel/mbox/mbox_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NUM_MBOX_ASYNC_MSGS=5 CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mbox/mbox_usage/prj.conf b/tests/kernel/mbox/mbox_usage/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/mbox/mbox_usage/prj.conf +++ b/tests/kernel/mbox/mbox_usage/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mem_heap/k_heap_api/prj.conf b/tests/kernel/mem_heap/k_heap_api/prj.conf index 0e28a855341..9a75212e89d 100644 --- a/tests/kernel/mem_heap/k_heap_api/prj.conf +++ b/tests/kernel/mem_heap/k_heap_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y diff --git a/tests/kernel/mem_heap/mheap_api_concept/prj.conf b/tests/kernel/mem_heap/mheap_api_concept/prj.conf index d5c24a96c5a..9491650b184 100644 --- a/tests/kernel/mem_heap/mheap_api_concept/prj.conf +++ b/tests/kernel/mem_heap/mheap_api_concept/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_HEAP_MEM_POOL_SIZE=256 diff --git a/tests/kernel/mem_heap/shared_multi_heap/prj.conf b/tests/kernel/mem_heap/shared_multi_heap/prj.conf index 0da3bf56922..c596cfecac4 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/prj.conf +++ b/tests/kernel/mem_heap/shared_multi_heap/prj.conf @@ -3,4 +3,3 @@ CONFIG_ZTEST=y CONFIG_SHARED_MULTI_HEAP=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mem_protect/demand_paging/prj.conf b/tests/kernel/mem_protect/demand_paging/prj.conf index 1efbc867ff0..bbdf6393496 100644 --- a/tests/kernel/mem_protect/demand_paging/prj.conf +++ b/tests/kernel/mem_protect/demand_paging/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DEMAND_PAGING_STATS=y CONFIG_DEMAND_PAGING_THREAD_STATS=y CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM=y diff --git a/tests/kernel/mem_protect/futex/prj.conf b/tests/kernel/mem_protect/futex/prj.conf index d8e436e42a2..fb220f5594d 100644 --- a/tests/kernel/mem_protect/futex/prj.conf +++ b/tests/kernel/mem_protect/futex/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mem_protect/mem_map/prj.conf b/tests/kernel/mem_protect/mem_map/prj.conf index 3971afe4e55..e39776e7067 100644 --- a/tests/kernel/mem_protect/mem_map/prj.conf +++ b/tests/kernel/mem_protect/mem_map/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/mem_protect/mem_map/prj_x86_64_coverage_exec.conf b/tests/kernel/mem_protect/mem_map/prj_x86_64_coverage_exec.conf index 0c816860494..5ec0e877e4e 100644 --- a/tests/kernel/mem_protect/mem_map/prj_x86_64_coverage_exec.conf +++ b/tests/kernel/mem_protect/mem_map/prj_x86_64_coverage_exec.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Enable large memory model to avoid relative addressing # so the execution test can run with the function at diff --git a/tests/kernel/mem_protect/mem_protect/prj.conf b/tests/kernel/mem_protect/mem_protect/prj.conf index 26e3e5c04df..ffb1d6279ef 100644 --- a/tests/kernel/mem_protect/mem_protect/prj.conf +++ b/tests/kernel/mem_protect/mem_protect/prj.conf @@ -1,6 +1,5 @@ CONFIG_STACK_CANARIES=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_MAX_THREAD_BYTES=4 CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/mem_protect/obj_validation/prj.conf b/tests/kernel/mem_protect/obj_validation/prj.conf index 99a7ff95e16..cb297c820e6 100644 --- a/tests/kernel/mem_protect/obj_validation/prj.conf +++ b/tests/kernel/mem_protect/obj_validation/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_DYNAMIC_OBJECTS=y CONFIG_HEAP_MEM_POOL_SIZE=8192 diff --git a/tests/kernel/mem_protect/protection/prj.conf b/tests/kernel/mem_protect/protection/prj.conf index 00d6c1e6499..a3b3b01065c 100644 --- a/tests/kernel/mem_protect/protection/prj.conf +++ b/tests/kernel/mem_protect/protection/prj.conf @@ -1,3 +1,2 @@ CONFIG_HEAP_MEM_POOL_SIZE=256 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mem_protect/stack_random/prj.conf b/tests/kernel/mem_protect/stack_random/prj.conf index 7bd01029e8a..85d03412f0e 100644 --- a/tests/kernel/mem_protect/stack_random/prj.conf +++ b/tests/kernel/mem_protect/stack_random/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_STACK_POINTER_RANDOM=64 CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/kernel/mem_protect/stackprot/prj.conf b/tests/kernel/mem_protect/stackprot/prj.conf index 641dc9c6b38..63875657b1b 100644 --- a/tests/kernel/mem_protect/stackprot/prj.conf +++ b/tests/kernel/mem_protect/stackprot/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_STACK_CANARIES=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/kernel/mem_protect/sys_sem/prj.conf b/tests/kernel/mem_protect/sys_sem/prj.conf index 57b97c472ee..29f2d64944e 100644 --- a/tests/kernel/mem_protect/sys_sem/prj.conf +++ b/tests/kernel/mem_protect/sys_sem/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/mem_protect/syscalls/prj.conf b/tests/kernel/mem_protect/syscalls/prj.conf index a8996be31e6..cf42fb16e3f 100644 --- a/tests/kernel/mem_protect/syscalls/prj.conf +++ b/tests/kernel/mem_protect/syscalls/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_TIMESLICING=y CONFIG_TIMESLICE_SIZE=20 diff --git a/tests/kernel/mem_protect/userspace/prj.conf b/tests/kernel/mem_protect/userspace/prj.conf index 471a4af8f41..c963d1f7f94 100644 --- a/tests/kernel/mem_protect/userspace/prj.conf +++ b/tests/kernel/mem_protect/userspace/prj.conf @@ -1,6 +1,5 @@ CONFIG_STACK_CANARIES=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INIT_STACKS=y CONFIG_APPLICATION_DEFINED_SYSCALL=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/mem_slab/mslab/prj.conf b/tests/kernel/mem_slab/mslab/prj.conf index 83b0a650119..2ed231771b6 100644 --- a/tests/kernel/mem_slab/mslab/prj.conf +++ b/tests/kernel/mem_slab/mslab/prj.conf @@ -1,5 +1,4 @@ CONFIG_BT=n CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mem_slab/mslab_api/prj.conf b/tests/kernel/mem_slab/mslab_api/prj.conf index b889211aa64..dfb5d99e39b 100644 --- a/tests/kernel/mem_slab/mslab_api/prj.conf +++ b/tests/kernel/mem_slab/mslab_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mem_slab/mslab_concept/prj.conf b/tests/kernel/mem_slab/mslab_concept/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/mem_slab/mslab_concept/prj.conf +++ b/tests/kernel/mem_slab/mslab_concept/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mem_slab/mslab_stats/prj.conf b/tests/kernel/mem_slab/mslab_stats/prj.conf index 670062ee387..a5a2801a982 100644 --- a/tests/kernel/mem_slab/mslab_stats/prj.conf +++ b/tests/kernel/mem_slab/mslab_stats/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mem_slab/mslab_threadsafe/prj.conf b/tests/kernel/mem_slab/mslab_threadsafe/prj.conf index e546e87d271..8ef1ecc8faa 100644 --- a/tests/kernel/mem_slab/mslab_threadsafe/prj.conf +++ b/tests/kernel/mem_slab/mslab_threadsafe/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 # FIXME: restore after #13813 is resolved # 1 millisecond diff --git a/tests/kernel/mp/prj.conf b/tests/kernel/mp/prj.conf index 6c2881737d8..5b0d7a6bdea 100644 --- a/tests/kernel/mp/prj.conf +++ b/tests/kernel/mp/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SMP=n diff --git a/tests/kernel/msgq/msgq_api/prj.conf b/tests/kernel/msgq/msgq_api/prj.conf index 57b97c472ee..29f2d64944e 100644 --- a/tests/kernel/msgq/msgq_api/prj.conf +++ b/tests/kernel/msgq/msgq_api/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/msgq/msgq_usage/prj.conf b/tests/kernel/msgq/msgq_usage/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/msgq/msgq_usage/prj.conf +++ b/tests/kernel/msgq/msgq_usage/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/mutex/mutex_api/prj.conf b/tests/kernel/mutex/mutex_api/prj.conf index d8e436e42a2..fb220f5594d 100644 --- a/tests/kernel/mutex/mutex_api/prj.conf +++ b/tests/kernel/mutex/mutex_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mutex/mutex_error_case/prj.conf b/tests/kernel/mutex/mutex_error_case/prj.conf index e9ab90559ca..d144e826538 100644 --- a/tests/kernel/mutex/mutex_error_case/prj.conf +++ b/tests/kernel/mutex/mutex_error_case/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/mutex/sys_mutex/prj.conf b/tests/kernel/mutex/sys_mutex/prj.conf index 19669cdffb6..25081bfa959 100644 --- a/tests/kernel/mutex/sys_mutex/prj.conf +++ b/tests/kernel/mutex/sys_mutex/prj.conf @@ -1,4 +1,3 @@ CONFIG_MAIN_THREAD_PRIORITY=10 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/obj_core/obj_core/prj.conf b/tests/kernel/obj_core/obj_core/prj.conf index 59e79100e29..6c006bcb8e9 100644 --- a/tests/kernel/obj_core/obj_core/prj.conf +++ b/tests/kernel/obj_core/obj_core/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_OBJ_CORE=y CONFIG_EVENTS=y CONFIG_PIPES=y diff --git a/tests/kernel/obj_core/obj_core_stats/prj.conf b/tests/kernel/obj_core/obj_core_stats/prj.conf index 47b02f61737..0e9e95a76cd 100644 --- a/tests/kernel/obj_core/obj_core_stats/prj.conf +++ b/tests/kernel/obj_core/obj_core_stats/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_OBJ_CORE=y CONFIG_OBJ_CORE_STATS=y CONFIG_SCHED_THREAD_USAGE=y diff --git a/tests/kernel/obj_core/obj_core_stats_api/prj.conf b/tests/kernel/obj_core/obj_core_stats_api/prj.conf index c6a53340e13..d163a31e105 100644 --- a/tests/kernel/obj_core/obj_core_stats_api/prj.conf +++ b/tests/kernel/obj_core/obj_core_stats_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_OBJ_CORE=y CONFIG_OBJ_CORE_STATS=y CONFIG_PIPES=y diff --git a/tests/kernel/obj_tracking/prj.conf b/tests/kernel/obj_tracking/prj.conf index 3e52a83f308..38956d67953 100644 --- a/tests/kernel/obj_tracking/prj.conf +++ b/tests/kernel/obj_tracking/prj.conf @@ -3,6 +3,5 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_TRACING=y CONFIG_TRACING_OBJECT_TRACKING=y CONFIG_TRACING_NONE=y -CONFIG_ZTEST_NEW_API=y CONFIG_PIPES=y CONFIG_EVENTS=y diff --git a/tests/kernel/pending/prj.conf b/tests/kernel/pending/prj.conf index 2e877ea403a..f8d48f84037 100644 --- a/tests/kernel/pending/prj.conf +++ b/tests/kernel/pending/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/pipe/pipe/prj.conf b/tests/kernel/pipe/pipe/prj.conf index 36ceb4e4501..05f0c74d408 100644 --- a/tests/kernel/pipe/pipe/prj.conf +++ b/tests/kernel/pipe/pipe/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y CONFIG_PIPES=y diff --git a/tests/kernel/pipe/pipe_api/prj.conf b/tests/kernel/pipe/pipe_api/prj.conf index 8afa8604aca..d080e2fbdbd 100644 --- a/tests/kernel/pipe/pipe_api/prj.conf +++ b/tests/kernel/pipe/pipe_api/prj.conf @@ -4,5 +4,4 @@ CONFIG_TEST_USERSPACE=y CONFIG_DYNAMIC_OBJECTS=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y -CONFIG_ZTEST_NEW_API=y CONFIG_PIPES=y diff --git a/tests/kernel/poll/prj.conf b/tests/kernel/poll/prj.conf index 43621e0d7eb..1369b5d2775 100644 --- a/tests/kernel/poll/prj.conf +++ b/tests/kernel/poll/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_POLL=y CONFIG_DYNAMIC_OBJECTS=y CONFIG_TEST_USERSPACE=y diff --git a/tests/kernel/profiling/profiling_api/prj.conf b/tests/kernel/profiling/profiling_api/prj.conf index 2fe7fe30d2f..f46372c436c 100644 --- a/tests/kernel/profiling/profiling_api/prj.conf +++ b/tests/kernel/profiling/profiling_api/prj.conf @@ -12,4 +12,3 @@ CONFIG_PM_POLICY_CUSTOM=y CONFIG_IDLE_STACK_SIZE=2048 # to check isr CONFIG_IRQ_OFFLOAD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/queue/prj.conf b/tests/kernel/queue/prj.conf index 44334ab367d..3f4e0e82950 100644 --- a/tests/kernel/queue/prj.conf +++ b/tests/kernel/queue/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/sched/deadline/prj.conf b/tests/kernel/sched/deadline/prj.conf index 1777becdf07..d2c392f6dba 100644 --- a/tests/kernel/sched/deadline/prj.conf +++ b/tests/kernel/sched/deadline/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_SCHED_DEADLINE=y diff --git a/tests/kernel/sched/metairq/prj.conf b/tests/kernel/sched/metairq/prj.conf index 2f46ed04f50..bb706e14ab5 100644 --- a/tests/kernel/sched/metairq/prj.conf +++ b/tests/kernel/sched/metairq/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_NUM_METAIRQ_PRIORITIES=1 diff --git a/tests/kernel/sched/preempt/prj.conf b/tests/kernel/sched/preempt/prj.conf index e7528fd6031..f68b1a7dcb6 100644 --- a/tests/kernel/sched/preempt/prj.conf +++ b/tests/kernel/sched/preempt/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_NUM_METAIRQ_PRIORITIES=1 CONFIG_IRQ_OFFLOAD=y diff --git a/tests/kernel/sched/schedule_api/prj.conf b/tests/kernel/sched/schedule_api/prj.conf index b24271c4232..fe5125047e3 100644 --- a/tests/kernel/sched/schedule_api/prj.conf +++ b/tests/kernel/sched/schedule_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_NUM_PREEMPT_PRIORITIES=30 CONFIG_NUM_COOP_PRIORITIES=30 diff --git a/tests/kernel/sched/schedule_api/prj_dumb.conf b/tests/kernel/sched/schedule_api/prj_dumb.conf index 9d996d2c9fb..c0ddfbd7c3f 100644 --- a/tests/kernel/sched/schedule_api/prj_dumb.conf +++ b/tests/kernel/sched/schedule_api/prj_dumb.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_SCHED_DUMB=y diff --git a/tests/kernel/sched/schedule_api/prj_multiq.conf b/tests/kernel/sched/schedule_api/prj_multiq.conf index d1074c07585..18d04dd8656 100644 --- a/tests/kernel/sched/schedule_api/prj_multiq.conf +++ b/tests/kernel/sched/schedule_api/prj_multiq.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_SCHED_MULTIQ=y diff --git a/tests/kernel/semaphore/semaphore/prj.conf b/tests/kernel/semaphore/semaphore/prj.conf index c882831edb0..a8b0a3e4d25 100644 --- a/tests/kernel/semaphore/semaphore/prj.conf +++ b/tests/kernel/semaphore/semaphore/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/semaphore/sys_sem/prj.conf b/tests/kernel/semaphore/sys_sem/prj.conf index 2abfa9b67e9..869fd338e6a 100644 --- a/tests/kernel/semaphore/sys_sem/prj.conf +++ b/tests/kernel/semaphore/sys_sem/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/sleep/prj.conf b/tests/kernel/sleep/prj.conf index d658dc25122..a948cf31924 100644 --- a/tests/kernel/sleep/prj.conf +++ b/tests/kernel/sleep/prj.conf @@ -2,4 +2,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/smp/prj.conf b/tests/kernel/smp/prj.conf index 97fab31062d..82aba8421f9 100644 --- a/tests/kernel/smp/prj.conf +++ b/tests/kernel/smp/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_SMP=y CONFIG_TRACE_SCHED_IPI=y CONFIG_POLL=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/smp_boot_delay/prj.conf b/tests/kernel/smp_boot_delay/prj.conf index d486230020e..a7c6e63161a 100644 --- a/tests/kernel/smp_boot_delay/prj.conf +++ b/tests/kernel/smp_boot_delay/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_SMP=y CONFIG_SMP_BOOT_DELAY=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/spinlock/prj.conf b/tests/kernel/spinlock/prj.conf index 801265f63e3..57fec00f826 100644 --- a/tests/kernel/spinlock/prj.conf +++ b/tests/kernel/spinlock/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_SPIN_VALIDATE=y CONFIG_SPIN_LOCK_TIME_LIMIT=100000 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/stack/stack/prj.conf b/tests/kernel/stack/stack/prj.conf index 9baa4dcc23c..3fc9377dc69 100644 --- a/tests/kernel/stack/stack/prj.conf +++ b/tests/kernel/stack/stack/prj.conf @@ -3,4 +3,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/threads/dynamic_thread/prj.conf b/tests/kernel/threads/dynamic_thread/prj.conf index da83027ca77..f70a552b445 100644 --- a/tests/kernel/threads/dynamic_thread/prj.conf +++ b/tests/kernel/threads/dynamic_thread/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/kernel/threads/dynamic_thread_stack/prj.conf b/tests/kernel/threads/dynamic_thread_stack/prj.conf index 07c01bd661f..3a4e7fd4159 100644 --- a/tests/kernel/threads/dynamic_thread_stack/prj.conf +++ b/tests/kernel/threads/dynamic_thread_stack/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INIT_STACKS=y CONFIG_THREAD_STACK_INFO=y CONFIG_MAX_THREAD_BYTES=5 diff --git a/tests/kernel/threads/no-multithreading/prj.conf b/tests/kernel/threads/no-multithreading/prj.conf index 1fbc3608d0f..ac4088fe07f 100644 --- a/tests/kernel/threads/no-multithreading/prj.conf +++ b/tests/kernel/threads/no-multithreading/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MULTITHREADING=n CONFIG_BT=n CONFIG_USB_DEVICE_STACK=n diff --git a/tests/kernel/threads/thread_apis/prj.conf b/tests/kernel/threads/thread_apis/prj.conf index 7df1af4b9ae..68e030211e7 100644 --- a/tests/kernel/threads/thread_apis/prj.conf +++ b/tests/kernel/threads/thread_apis/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_THREAD_MONITOR=y CONFIG_THREAD_CUSTOM_DATA=y CONFIG_THREAD_NAME=y diff --git a/tests/kernel/threads/thread_error_case/prj.conf b/tests/kernel/threads/thread_error_case/prj.conf index 9b1f9bcd5a7..292c830bc05 100644 --- a/tests/kernel/threads/thread_error_case/prj.conf +++ b/tests/kernel/threads/thread_error_case/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_THREAD_MONITOR=y CONFIG_THREAD_CUSTOM_DATA=y CONFIG_THREAD_NAME=y diff --git a/tests/kernel/threads/thread_init/prj.conf b/tests/kernel/threads/thread_init/prj.conf index e2cf6732b3f..390173dc4a5 100644 --- a/tests/kernel/threads/thread_init/prj.conf +++ b/tests/kernel/threads/thread_init/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_SMP=n diff --git a/tests/kernel/threads/thread_stack/prj.conf b/tests/kernel/threads/thread_stack/prj.conf index ddc7b71cef9..b6b5951635d 100644 --- a/tests/kernel/threads/thread_stack/prj.conf +++ b/tests/kernel/threads/thread_stack/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INIT_STACKS=y CONFIG_THREAD_STACK_INFO=y CONFIG_APPLICATION_DEFINED_SYSCALL=y diff --git a/tests/kernel/threads/thread_stack/prj_armv8m_mpu_stack_guard.conf b/tests/kernel/threads/thread_stack/prj_armv8m_mpu_stack_guard.conf index a16b81cc689..143e2667522 100644 --- a/tests/kernel/threads/thread_stack/prj_armv8m_mpu_stack_guard.conf +++ b/tests/kernel/threads/thread_stack/prj_armv8m_mpu_stack_guard.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INIT_STACKS=y CONFIG_THREAD_STACK_INFO=y CONFIG_APPLICATION_DEFINED_SYSCALL=y diff --git a/tests/kernel/threads/tls/prj.conf b/tests/kernel/threads/tls/prj.conf index 390b9c589d7..36a39b3c777 100644 --- a/tests/kernel/threads/tls/prj.conf +++ b/tests/kernel/threads/tls/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_THREAD_LOCAL_STORAGE=y diff --git a/tests/kernel/tickless/tickless_concept/prj.conf b/tests/kernel/tickless/tickless_concept/prj.conf index ce473bdd87d..9290ae5a65d 100644 --- a/tests/kernel/tickless/tickless_concept/prj.conf +++ b/tests/kernel/tickless/tickless_concept/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_PM=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/timer/cycle64/prj.conf b/tests/kernel/timer/cycle64/prj.conf index 90c1449d102..bb965b32e32 100644 --- a/tests/kernel/timer/cycle64/prj.conf +++ b/tests/kernel/timer/cycle64/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PRINTK=y diff --git a/tests/kernel/timer/starve/prj.conf b/tests/kernel/timer/starve/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/timer/starve/prj.conf +++ b/tests/kernel/timer/starve/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/timer/timepoints/prj.conf b/tests/kernel/timer/timepoints/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/timer/timepoints/prj.conf +++ b/tests/kernel/timer/timepoints/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/timer/timer_api/prj.conf b/tests/kernel/timer/timer_api/prj.conf index 7b39ab9d874..dfcd95a730f 100644 --- a/tests/kernel/timer/timer_api/prj.conf +++ b/tests/kernel/timer/timer_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/timer/timer_api/prj_tickless.conf b/tests/kernel/timer/timer_api/prj_tickless.conf index 5fcd26b74bf..2b00d1fe866 100644 --- a/tests/kernel/timer/timer_api/prj_tickless.conf +++ b/tests/kernel/timer/timer_api/prj_tickless.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PM=y CONFIG_TICKLESS_KERNEL=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/timer/timer_behavior/prj.conf b/tests/kernel/timer/timer_behavior/prj.conf index 3333fd8dd41..92eef4c0ddb 100644 --- a/tests/kernel/timer/timer_behavior/prj.conf +++ b/tests/kernel/timer/timer_behavior/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CBPRINTF_FP_SUPPORT=y # Make sure this is off. Otherwise a single 60-character line at diff --git a/tests/kernel/timer/timer_error_case/prj.conf b/tests/kernel/timer/timer_error_case/prj.conf index bf7f45f9b92..29c94cedb7d 100644 --- a/tests/kernel/timer/timer_error_case/prj.conf +++ b/tests/kernel/timer/timer_error_case/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_IRQ_OFFLOAD=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/timer/timer_monotonic/prj.conf b/tests/kernel/timer/timer_monotonic/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/timer/timer_monotonic/prj.conf +++ b/tests/kernel/timer/timer_monotonic/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/usage/thread_runtime_stats/prj.conf b/tests/kernel/usage/thread_runtime_stats/prj.conf index 2f491e3188c..7be342bcae7 100644 --- a/tests/kernel/usage/thread_runtime_stats/prj.conf +++ b/tests/kernel/usage/thread_runtime_stats/prj.conf @@ -4,4 +4,3 @@ CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_THREAD_RUNTIME_STATS=y CONFIG_SCHED_THREAD_USAGE_ALL=y CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/kernel/workq/critical/prj.conf b/tests/kernel/workq/critical/prj.conf index 16f71a11c09..f8d48f84037 100644 --- a/tests/kernel/workq/critical/prj.conf +++ b/tests/kernel/workq/critical/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/kernel/workq/user_work/prj.conf b/tests/kernel/workq/user_work/prj.conf index a93770f3515..d94ab7302d1 100644 --- a/tests/kernel/workq/user_work/prj.conf +++ b/tests/kernel/workq/user_work/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_THREAD_NAME=y diff --git a/tests/kernel/workq/work/prj.conf b/tests/kernel/workq/work/prj.conf index 8dda06ff724..bb385ff2fc4 100644 --- a/tests/kernel/workq/work/prj.conf +++ b/tests/kernel/workq/work/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_THREAD_NAME=y diff --git a/tests/kernel/workq/work_queue/prj.conf b/tests/kernel/workq/work_queue/prj.conf index 33189097be7..1df67695310 100644 --- a/tests/kernel/workq/work_queue/prj.conf +++ b/tests/kernel/workq/work_queue/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_POLL=y CONFIG_ASSERT=y diff --git a/tests/kernel/xip/prj.conf b/tests/kernel/xip/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kernel/xip/prj.conf +++ b/tests/kernel/xip/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/c_lib/prj.conf b/tests/lib/c_lib/prj.conf index d21e1ad31fb..331c19559db 100644 --- a/tests/lib/c_lib/prj.conf +++ b/tests/lib/c_lib/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y diff --git a/tests/lib/cbprintf_package/prj.conf b/tests/lib/cbprintf_package/prj.conf index c1c71f42bc4..d89dc93d02d 100644 --- a/tests/lib/cbprintf_package/prj.conf +++ b/tests/lib/cbprintf_package/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CBPRINTF_LIBC_SUBSTS=y CONFIG_TEST_EXTRA_STACK_SIZE=1024 diff --git a/tests/lib/cmsis_dsp/bayes/prj.conf b/tests/lib/cmsis_dsp/bayes/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/bayes/prj.conf +++ b/tests/lib/cmsis_dsp/bayes/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/complexmath/prj.conf b/tests/lib/cmsis_dsp/complexmath/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/complexmath/prj.conf +++ b/tests/lib/cmsis_dsp/complexmath/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/distance/prj.conf b/tests/lib/cmsis_dsp/distance/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/distance/prj.conf +++ b/tests/lib/cmsis_dsp/distance/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/fastmath/prj.conf b/tests/lib/cmsis_dsp/fastmath/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/fastmath/prj.conf +++ b/tests/lib/cmsis_dsp/fastmath/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/filtering/prj.conf b/tests/lib/cmsis_dsp/filtering/prj.conf index b40c98d36e5..e9e39e0e354 100644 --- a/tests/lib/cmsis_dsp/filtering/prj.conf +++ b/tests/lib/cmsis_dsp/filtering/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/filtering/prj_base.conf b/tests/lib/cmsis_dsp/filtering/prj_base.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/filtering/prj_base.conf +++ b/tests/lib/cmsis_dsp/filtering/prj_base.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/interpolation/prj.conf b/tests/lib/cmsis_dsp/interpolation/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/interpolation/prj.conf +++ b/tests/lib/cmsis_dsp/interpolation/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/matrix/prj.conf b/tests/lib/cmsis_dsp/matrix/prj.conf index 744d8f3d75d..40ed01f715e 100644 --- a/tests/lib/cmsis_dsp/matrix/prj.conf +++ b/tests/lib/cmsis_dsp/matrix/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/matrix/prj_base.conf b/tests/lib/cmsis_dsp/matrix/prj_base.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/matrix/prj_base.conf +++ b/tests/lib/cmsis_dsp/matrix/prj_base.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/quaternionmath/prj.conf b/tests/lib/cmsis_dsp/quaternionmath/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/quaternionmath/prj.conf +++ b/tests/lib/cmsis_dsp/quaternionmath/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/statistics/prj.conf b/tests/lib/cmsis_dsp/statistics/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/statistics/prj.conf +++ b/tests/lib/cmsis_dsp/statistics/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/support/prj.conf b/tests/lib/cmsis_dsp/support/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/support/prj.conf +++ b/tests/lib/cmsis_dsp/support/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/svm/prj.conf b/tests/lib/cmsis_dsp/svm/prj.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/svm/prj.conf +++ b/tests/lib/cmsis_dsp/svm/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/transform/prj.conf b/tests/lib/cmsis_dsp/transform/prj.conf index 219f62788d8..6a515162015 100644 --- a/tests/lib/cmsis_dsp/transform/prj.conf +++ b/tests/lib/cmsis_dsp/transform/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y -CONFIG_ZTEST_NEW_API=y CONFIG_CMSIS_DSP=y # Test Options diff --git a/tests/lib/cmsis_dsp/transform/prj_base.conf b/tests/lib/cmsis_dsp/transform/prj_base.conf index 75aa99c4887..7a253195e00 100644 --- a/tests/lib/cmsis_dsp/transform/prj_base.conf +++ b/tests/lib/cmsis_dsp/transform/prj_base.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_nn/prj.conf b/tests/lib/cmsis_nn/prj.conf index 6614e4a9fba..b8dea680868 100644 --- a/tests/lib/cmsis_nn/prj.conf +++ b/tests/lib/cmsis_nn/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_CMSIS_DSP=y CONFIG_CMSIS_NN=y diff --git a/tests/lib/cpp/cxx/prj.conf b/tests/lib/cpp/cxx/prj.conf index 70945ee8a6e..15ae9ce1ebd 100644 --- a/tests/lib/cpp/cxx/prj.conf +++ b/tests/lib/cpp/cxx/prj.conf @@ -3,7 +3,6 @@ CONFIG_NET_BUF=y CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=128 -CONFIG_ZTEST_NEW_API=y CONFIG_CRC=y # RTIO diff --git a/tests/lib/cpp/libcxx/prj.conf b/tests/lib/cpp/libcxx/prj.conf index fff9acb3adc..f6c6a2a9db4 100644 --- a/tests/lib/cpp/libcxx/prj.conf +++ b/tests/lib/cpp/libcxx/prj.conf @@ -3,4 +3,3 @@ CONFIG_STD_CPP17=y CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=5120 CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=32768 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/devicetree/api/prj.conf b/tests/lib/devicetree/api/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/lib/devicetree/api/prj.conf +++ b/tests/lib/devicetree/api/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/devicetree/api_ext/prj.conf b/tests/lib/devicetree/api_ext/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/lib/devicetree/api_ext/prj.conf +++ b/tests/lib/devicetree/api_ext/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/devicetree/devices/prj.conf b/tests/lib/devicetree/devices/prj.conf index fc3755cc035..fa50f0de8c6 100644 --- a/tests/lib/devicetree/devices/prj.conf +++ b/tests/lib/devicetree/devices/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y CONFIG_I2C=n -CONFIG_ZTEST_NEW_API=y CONFIG_DEVICE_DEPS=y CONFIG_CHECK_INIT_PRIORITIES=n diff --git a/tests/lib/devicetree/memory_region/prj.conf b/tests/lib/devicetree/memory_region/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/lib/devicetree/memory_region/prj.conf +++ b/tests/lib/devicetree/memory_region/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/fdtable/prj.conf b/tests/lib/fdtable/prj.conf index f14a42c8a0e..90f6fec41c8 100644 --- a/tests/lib/fdtable/prj.conf +++ b/tests/lib/fdtable/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_POSIX_API=y -CONFIG_ZTEST_NEW_API=y CONFIG_FDTABLE=y diff --git a/tests/lib/gui/lvgl/prj.conf b/tests/lib/gui/lvgl/prj.conf index 3e88939a88a..92668655692 100644 --- a/tests/lib/gui/lvgl/prj.conf +++ b/tests/lib/gui/lvgl/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_DISPLAY=y CONFIG_SDL_DISPLAY=n CONFIG_DUMMY_DISPLAY=y diff --git a/tests/lib/hash_function/prj.conf b/tests/lib/hash_function/prj.conf index d165fcfc36b..cdf1925fc15 100644 --- a/tests/lib/hash_function/prj.conf +++ b/tests/lib/hash_function/prj.conf @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_HASH_FUNC32=y diff --git a/tests/lib/hash_map/prj.conf b/tests/lib/hash_map/prj.conf index ff212c933ec..d7c68435fca 100644 --- a/tests/lib/hash_map/prj.conf +++ b/tests/lib/hash_map/prj.conf @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_HASH_FUNC32=y CONFIG_SYS_HASH_MAP=y diff --git a/tests/lib/heap/prj.conf b/tests/lib/heap/prj.conf index 7d81866b9a9..036a06f8b0a 100644 --- a/tests/lib/heap/prj.conf +++ b/tests/lib/heap/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_HEAP_VALIDATE=y CONFIG_SYS_HEAP_RUNTIME_STATS=y CONFIG_SYS_HEAP_LISTENER=y diff --git a/tests/lib/heap_align/prj.conf b/tests/lib/heap_align/prj.conf index d46d6c74ecf..dd9186e6a50 100644 --- a/tests/lib/heap_align/prj.conf +++ b/tests/lib/heap_align/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_HEAP_VALIDATE=y CONFIG_SYS_HEAP_RUNTIME_STATS=y diff --git a/tests/lib/json/prj.conf b/tests/lib/json/prj.conf index 1242eef6daf..700ea224bba 100644 --- a/tests/lib/json/prj.conf +++ b/tests/lib/json/prj.conf @@ -1,4 +1,3 @@ CONFIG_JSON_LIBRARY=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/lib/linear_range/prj.conf b/tests/lib/linear_range/prj.conf index 947f5c96234..bc9922291f5 100644 --- a/tests/lib/linear_range/prj.conf +++ b/tests/lib/linear_range/prj.conf @@ -2,4 +2,3 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_alloc/prj.conf b/tests/lib/mem_alloc/prj.conf index d8d148b1144..73573f7377e 100644 --- a/tests/lib/mem_alloc/prj.conf +++ b/tests/lib/mem_alloc/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2048 CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_alloc/prj_negative_testing.conf b/tests/lib/mem_alloc/prj_negative_testing.conf index 780ea37adc2..23ff207b374 100644 --- a/tests/lib/mem_alloc/prj_negative_testing.conf +++ b/tests/lib/mem_alloc/prj_negative_testing.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=0 CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_alloc/prj_newlib.conf b/tests/lib/mem_alloc/prj_newlib.conf index c9f0c2eb271..c24854dd3d1 100644 --- a/tests/lib/mem_alloc/prj_newlib.conf +++ b/tests/lib/mem_alloc/prj_newlib.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_ALIGNED_HEAP_SIZE=8192 CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_alloc/prj_newlibnano.conf b/tests/lib/mem_alloc/prj_newlibnano.conf index 6817a695b5a..74f3bd7d344 100644 --- a/tests/lib/mem_alloc/prj_newlibnano.conf +++ b/tests/lib/mem_alloc/prj_newlibnano.conf @@ -3,4 +3,3 @@ CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_NANO=y CONFIG_NEWLIB_LIBC_ALIGNED_HEAP_SIZE=2048 CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_alloc/prj_picolibc.conf b/tests/lib/mem_alloc/prj_picolibc.conf index 090aa34134f..5c6133017c6 100644 --- a/tests/lib/mem_alloc/prj_picolibc.conf +++ b/tests/lib/mem_alloc/prj_picolibc.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_PICOLIBC=y CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/mem_blocks/prj.conf b/tests/lib/mem_blocks/prj.conf index 9ae9394ba4d..5d303066504 100644 --- a/tests/lib/mem_blocks/prj.conf +++ b/tests/lib/mem_blocks/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_MEM_BLOCKS=y CONFIG_SYS_MEM_BLOCKS_LISTENER=y diff --git a/tests/lib/mem_blocks_stats/prj.conf b/tests/lib/mem_blocks_stats/prj.conf index 21b9227a8ef..e63280b8eb3 100644 --- a/tests/lib/mem_blocks_stats/prj.conf +++ b/tests/lib/mem_blocks_stats/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SYS_MEM_BLOCKS=y CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS=y diff --git a/tests/lib/mpsc_pbuf/prj.conf b/tests/lib/mpsc_pbuf/prj.conf index c801dcd30a7..92aebaf000c 100644 --- a/tests/lib/mpsc_pbuf/prj.conf +++ b/tests/lib/mpsc_pbuf/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_ZTRESS_MAX_THREADS=4 CONFIG_MPSC_PBUF=y diff --git a/tests/lib/newlib/heap_listener/prj.conf b/tests/lib/newlib/heap_listener/prj.conf index 31bc1ca7e76..e5a5dc6df4c 100644 --- a/tests/lib/newlib/heap_listener/prj.conf +++ b/tests/lib/newlib/heap_listener/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_HEAP_LISTENER=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/newlib/thread_safety/prj.conf b/tests/lib/newlib/thread_safety/prj.conf index dda7c274a81..3ccbeaa4562 100644 --- a/tests/lib/newlib/thread_safety/prj.conf +++ b/tests/lib/newlib/thread_safety/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=0 CONFIG_TIMESLICE_SIZE=1 diff --git a/tests/lib/newlib/thread_safety/prj_userspace.conf b/tests/lib/newlib/thread_safety/prj_userspace.conf index 89a95db2e72..a2cc6243c39 100644 --- a/tests/lib/newlib/thread_safety/prj_userspace.conf +++ b/tests/lib/newlib/thread_safety/prj_userspace.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=0 CONFIG_TIMESLICE_SIZE=1 diff --git a/tests/lib/notify/prj.conf b/tests/lib/notify/prj.conf index ef6676e85d1..a1274832e0e 100644 --- a/tests/lib/notify/prj.conf +++ b/tests/lib/notify/prj.conf @@ -1,4 +1,3 @@ CONFIG_POLL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NOTIFY=y diff --git a/tests/lib/onoff/prj.conf b/tests/lib/onoff/prj.conf index 4f28b8914ad..73e55c9d3de 100644 --- a/tests/lib/onoff/prj.conf +++ b/tests/lib/onoff/prj.conf @@ -1,4 +1,3 @@ CONFIG_POLL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ONOFF=y diff --git a/tests/lib/p4workq/prj.conf b/tests/lib/p4workq/prj.conf index 7687c980c2f..3e0283ee446 100644 --- a/tests/lib/p4workq/prj.conf +++ b/tests/lib/p4workq/prj.conf @@ -5,4 +5,3 @@ CONFIG_LOG_DEFAULT_LEVEL=1 # Test whiteboxes the wait_q and expects it to be a dlist CONFIG_WAITQ_SCALABLE=n CONFIG_WAITQ_DUMB=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/ringbuffer/prj.conf b/tests/lib/ringbuffer/prj.conf index 7f65d54518a..f66202abb23 100644 --- a/tests/lib/ringbuffer/prj.conf +++ b/tests/lib/ringbuffer/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_TEST_EXTRA_STACK_SIZE=1024 CONFIG_IRQ_OFFLOAD=y diff --git a/tests/lib/smf/prj.conf b/tests/lib/smf/prj.conf index ad39299c8b9..59f26ef31fe 100644 --- a/tests/lib/smf/prj.conf +++ b/tests/lib/smf/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_SMF=y diff --git a/tests/lib/sprintf/prj.conf b/tests/lib/sprintf/prj.conf index 34bba7f359e..084dd06744f 100644 --- a/tests/lib/sprintf/prj.conf +++ b/tests/lib/sprintf/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FPU=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/lib/sprintf/prj_new.conf b/tests/lib/sprintf/prj_new.conf index eee90586e22..36945d2c956 100644 --- a/tests/lib/sprintf/prj_new.conf +++ b/tests/lib/sprintf/prj_new.conf @@ -1,6 +1,5 @@ CONFIG_STDOUT_CONSOLE=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FPU=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/lib/sprintf/prj_picolibc.conf b/tests/lib/sprintf/prj_picolibc.conf index 205e6bef3c9..2d5cdd1fc8f 100644 --- a/tests/lib/sprintf/prj_picolibc.conf +++ b/tests/lib/sprintf/prj_picolibc.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PICOLIBC=y CONFIG_PICOLIBC_IO_FLOAT=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/lib/sprintf/prj_picolibc_new.conf b/tests/lib/sprintf/prj_picolibc_new.conf index 458e98c26f0..b9490e6301d 100644 --- a/tests/lib/sprintf/prj_picolibc_new.conf +++ b/tests/lib/sprintf/prj_picolibc_new.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_PICOLIBC=y CONFIG_PICOLIBC_IO_FLOAT=y CONFIG_STDOUT_CONSOLE=n diff --git a/tests/lib/spsc_pbuf/prj.conf b/tests/lib/spsc_pbuf/prj.conf index a5478a0e775..8710f041f32 100644 --- a/tests/lib/spsc_pbuf/prj.conf +++ b/tests/lib/spsc_pbuf/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_SPSC_PBUF=y diff --git a/tests/lib/sys_util/prj.conf b/tests/lib/sys_util/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/lib/sys_util/prj.conf +++ b/tests/lib/sys_util/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/thrift/ThriftTest/prj.conf b/tests/lib/thrift/ThriftTest/prj.conf index 4d2b145b13c..1c461c3ac8a 100755 --- a/tests/lib/thrift/ThriftTest/prj.conf +++ b/tests/lib/thrift/ThriftTest/prj.conf @@ -18,7 +18,6 @@ CONFIG_THRIFT=y # Test dependencies CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_TEST=y CONFIG_NET_DRIVERS=y diff --git a/tests/lib/time/prj.conf b/tests/lib/time/prj.conf index 2f34cdff296..786d6bc705e 100644 --- a/tests/lib/time/prj.conf +++ b/tests/lib/time/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_POSIX_CLOCK=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/misc/iterable_sections/prj.conf b/tests/misc/iterable_sections/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/misc/iterable_sections/prj.conf +++ b/tests/misc/iterable_sections/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/misc/kconfigoptions/prj.conf b/tests/misc/kconfigoptions/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/misc/kconfigoptions/prj.conf +++ b/tests/misc/kconfigoptions/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/modules/nanopb/prj.conf b/tests/modules/nanopb/prj.conf index 6d5e46c1ddd..139d6ef66fc 100644 --- a/tests/modules/nanopb/prj.conf +++ b/tests/modules/nanopb/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NANOPB=y diff --git a/tests/modules/uoscore/prj.conf b/tests/modules/uoscore/prj.conf index 406324798ea..0282e87b3bb 100644 --- a/tests/modules/uoscore/prj.conf +++ b/tests/modules/uoscore/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=16384 CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/net/6lo/prj.conf b/tests/net/6lo/prj.conf index b52665d1864..ed070a9ce85 100644 --- a/tests/net/6lo/prj.conf +++ b/tests/net/6lo/prj.conf @@ -21,4 +21,3 @@ CONFIG_NET_6LO_CONTEXT=y #Before modifying this value, add respective code in src/main.c CONFIG_NET_MAX_6LO_CONTEXTS=2 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/all/prj.conf b/tests/net/all/prj.conf index bb40e71fca1..3538a834048 100644 --- a/tests/net/all/prj.conf +++ b/tests/net/all/prj.conf @@ -7,7 +7,6 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_MAX_THREAD_BYTES=4 diff --git a/tests/net/arp/prj.conf b/tests/net/arp/prj.conf index 01ea831dfc2..4e5827b5dbd 100644 --- a/tests/net/arp/prj.conf +++ b/tests/net/arp/prj.conf @@ -15,5 +15,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 CONFIG_NET_IPV6=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=2 diff --git a/tests/net/bridge/prj.conf b/tests/net/bridge/prj.conf index 2bc1e019fc2..60457ce7ec4 100644 --- a/tests/net/bridge/prj.conf +++ b/tests/net/bridge/prj.conf @@ -10,4 +10,3 @@ CONFIG_NET_PKT_RX_COUNT=20 CONFIG_NET_BUF_RX_COUNT=20 CONFIG_NET_BUF_TX_COUNT=20 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/buf/prj.conf b/tests/net/buf/prj.conf index 2a62a683cc4..47e462402b3 100644 --- a/tests/net/buf/prj.conf +++ b/tests/net/buf/prj.conf @@ -4,4 +4,3 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 #CONFIG_NET_BUF_LOG=y #CONFIG_NET_BUF_LOG_LEVEL_DBG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/buf_simple/prj.conf b/tests/net/buf_simple/prj.conf index 2d34630767b..a437510f8d9 100644 --- a/tests/net/buf_simple/prj.conf +++ b/tests/net/buf_simple/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_ASSERT_LEVEL=2 CONFIG_ASSERT_VERBOSE=y diff --git a/tests/net/checksum_offload/prj.conf b/tests/net/checksum_offload/prj.conf index 41bfa3e27cc..ac345eaa1d7 100644 --- a/tests/net/checksum_offload/prj.conf +++ b/tests/net/checksum_offload/prj.conf @@ -21,7 +21,6 @@ CONFIG_NET_IF_MAX_IPV4_COUNT=2 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf index ec6b62f6be3..cc845d23a6f 100644 --- a/tests/net/conn_mgr_conn/prj.conf +++ b/tests/net/conn_mgr_conn/prj.conf @@ -20,7 +20,6 @@ CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y diff --git a/tests/net/conn_mgr_monitor/prj.conf b/tests/net/conn_mgr_monitor/prj.conf index f68f3f09fdc..376150b993e 100644 --- a/tests/net/conn_mgr_monitor/prj.conf +++ b/tests/net/conn_mgr_monitor/prj.conf @@ -19,7 +19,6 @@ CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y diff --git a/tests/net/context/prj.conf b/tests/net/context/prj.conf index 241bb9f0ade..0b8954cda5d 100644 --- a/tests/net/context/prj.conf +++ b/tests/net/context/prj.conf @@ -21,4 +21,3 @@ CONFIG_NET_PKT_RX_COUNT=5 CONFIG_NET_BUF_RX_COUNT=10 CONFIG_NET_BUF_TX_COUNT=10 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/dhcpv4/prj.conf b/tests/net/dhcpv4/prj.conf index cb83ac03418..5b126f90a14 100644 --- a/tests/net/dhcpv4/prj.conf +++ b/tests/net/dhcpv4/prj.conf @@ -26,7 +26,6 @@ CONFIG_NET_UDP_CHECKSUM=n CONFIG_MAIN_STACK_SIZE=3072 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX=2 diff --git a/tests/net/dhcpv6/prj.conf b/tests/net/dhcpv6/prj.conf index 0992b9f1d90..0c7e5c319ea 100644 --- a/tests/net/dhcpv6/prj.conf +++ b/tests/net/dhcpv6/prj.conf @@ -1,6 +1,5 @@ CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/ethernet_mgmt/prj.conf b/tests/net/ethernet_mgmt/prj.conf index dd0ade07970..73acc1e32e5 100644 --- a/tests/net/ethernet_mgmt/prj.conf +++ b/tests/net/ethernet_mgmt/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NETWORKING=y diff --git a/tests/net/hostname/prj.conf b/tests/net/hostname/prj.conf index e7419db995f..1b174c35c0e 100644 --- a/tests/net/hostname/prj.conf +++ b/tests/net/hostname/prj.conf @@ -20,7 +20,6 @@ CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=4 CONFIG_NET_IF_MAX_IPV6_COUNT=4 CONFIG_NET_HOSTNAME_ENABLE=y diff --git a/tests/net/icmp/prj.conf b/tests/net/icmp/prj.conf index 4116a90fdf1..2d365ff44fb 100644 --- a/tests/net/icmp/prj.conf +++ b/tests/net/icmp/prj.conf @@ -12,7 +12,6 @@ CONFIG_NET_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_NET_L2_DUMMY=y CONFIG_NET_IPV6_NBR_CACHE=n diff --git a/tests/net/icmpv4/prj.conf b/tests/net/icmpv4/prj.conf index e12e61ddb84..202ad498a50 100644 --- a/tests/net/icmpv4/prj.conf +++ b/tests/net/icmpv4/prj.conf @@ -13,6 +13,5 @@ CONFIG_NET_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_NET_IPV4_HDR_OPTIONS=y diff --git a/tests/net/icmpv6/prj.conf b/tests/net/icmpv6/prj.conf index dbd3d93f626..90ffdd82a96 100644 --- a/tests/net/icmpv6/prj.conf +++ b/tests/net/icmpv6/prj.conf @@ -12,7 +12,6 @@ CONFIG_NET_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_NET_L2_ETHERNET=n CONFIG_NET_L2_DUMMY=y diff --git a/tests/net/ieee802154/6lo_fragment/prj.conf b/tests/net/ieee802154/6lo_fragment/prj.conf index 5e1ae744fff..7f2727a8588 100644 --- a/tests/net/ieee802154/6lo_fragment/prj.conf +++ b/tests/net/ieee802154/6lo_fragment/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_NET_L2_DUMMY=y diff --git a/tests/net/ieee802154/custom_l2/prj.conf b/tests/net/ieee802154/custom_l2/prj.conf index e9fa365d3d1..b12cc61c0f8 100644 --- a/tests/net/ieee802154/custom_l2/prj.conf +++ b/tests/net/ieee802154/custom_l2/prj.conf @@ -9,4 +9,3 @@ CONFIG_NET_TEST=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/ieee802154/l2/prj.conf b/tests/net/ieee802154/l2/prj.conf index 7d6dbc936b6..f5b77b6c6e2 100644 --- a/tests/net/ieee802154/l2/prj.conf +++ b/tests/net/ieee802154/l2/prj.conf @@ -33,7 +33,6 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST_STACK_SIZE=3072 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=n diff --git a/tests/net/iface/prj.conf b/tests/net/iface/prj.conf index 6b024cd84d7..71b3f4dfcf8 100644 --- a/tests/net/iface/prj.conf +++ b/tests/net/iface/prj.conf @@ -25,7 +25,6 @@ CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=4 CONFIG_NET_IF_MAX_IPV6_COUNT=4 CONFIG_TEST_USERSPACE=y diff --git a/tests/net/igmp/prj.conf b/tests/net/igmp/prj.conf index aaa47ade92c..b9119257232 100644 --- a/tests/net/igmp/prj.conf +++ b/tests/net/igmp/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_TEST=y CONFIG_NETWORKING=y diff --git a/tests/net/ip-addr/prj.conf b/tests/net/ip-addr/prj.conf index 131a96a458d..3f718037e91 100644 --- a/tests/net/ip-addr/prj.conf +++ b/tests/net/ip-addr/prj.conf @@ -19,4 +19,3 @@ CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT=3 CONFIG_NET_L2_DUMMY=y CONFIG_NET_L2_ETHERNET=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/ipv4_fragment/prj.conf b/tests/net/ipv4_fragment/prj.conf index 546f866ccd7..d8c4d1ff534 100644 --- a/tests/net/ipv4_fragment/prj.conf +++ b/tests/net/ipv4_fragment/prj.conf @@ -22,7 +22,6 @@ CONFIG_NET_UDP_CHECKSUM=y CONFIG_NET_TCP_CHECKSUM=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_INIT_STACKS=y diff --git a/tests/net/ipv6/prj.conf b/tests/net/ipv6/prj.conf index 4051207d88c..c2f80f6ead4 100644 --- a/tests/net/ipv6/prj.conf +++ b/tests/net/ipv6/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y #CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NETWORKING=y diff --git a/tests/net/ipv6_fragment/prj.conf b/tests/net/ipv6_fragment/prj.conf index c7c62ce972f..e8a68b913b6 100644 --- a/tests/net/ipv6_fragment/prj.conf +++ b/tests/net/ipv6_fragment/prj.conf @@ -25,7 +25,6 @@ CONFIG_NET_UDP_CHECKSUM=y CONFIG_NET_IF_MAX_IPV6_COUNT=2 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_INIT_STACKS=y diff --git a/tests/net/lib/coap/prj.conf b/tests/net/lib/coap/prj.conf index 854a3320b36..63f863843fd 100644 --- a/tests/net/lib/coap/prj.conf +++ b/tests/net/lib/coap/prj.conf @@ -1,7 +1,6 @@ #Testing CONFIG_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y # Generic networking options diff --git a/tests/net/lib/coap_client/prj.conf b/tests/net/lib/coap_client/prj.conf index d185b3e493c..c7265029a21 100644 --- a/tests/net/lib/coap_client/prj.conf +++ b/tests/net/lib/coap_client/prj.conf @@ -1,4 +1,3 @@ #Testing CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/net/lib/dns_addremove/prj.conf b/tests/net/lib/dns_addremove/prj.conf index 2d7d81b1341..db691377acd 100644 --- a/tests/net/lib/dns_addremove/prj.conf +++ b/tests/net/lib/dns_addremove/prj.conf @@ -16,5 +16,4 @@ CONFIG_NET_IPV6=y CONFIG_NET_ARP=n CONFIG_PRINTK=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/net/lib/dns_packet/prj.conf b/tests/net/lib/dns_packet/prj.conf index c757cbeca69..5a15eeb1ac8 100644 --- a/tests/net/lib/dns_packet/prj.conf +++ b/tests/net/lib/dns_packet/prj.conf @@ -11,7 +11,6 @@ CONFIG_DNS_RESOLVER=y CONFIG_PRINTK=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_CRC=y diff --git a/tests/net/lib/dns_resolve/prj-no-ipv6.conf b/tests/net/lib/dns_resolve/prj-no-ipv6.conf index d980676230e..d7b7c5f8c1e 100644 --- a/tests/net/lib/dns_resolve/prj-no-ipv6.conf +++ b/tests/net/lib/dns_resolve/prj-no-ipv6.conf @@ -25,6 +25,5 @@ CONFIG_NET_ARP=n CONFIG_PRINTK=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1344 diff --git a/tests/net/lib/dns_resolve/prj.conf b/tests/net/lib/dns_resolve/prj.conf index 954eb867861..c43911ac3cd 100644 --- a/tests/net/lib/dns_resolve/prj.conf +++ b/tests/net/lib/dns_resolve/prj.conf @@ -27,6 +27,5 @@ CONFIG_NET_ARP=n CONFIG_PRINTK=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1344 diff --git a/tests/net/lib/dns_sd/prj-no-ipv6.conf b/tests/net/lib/dns_sd/prj-no-ipv6.conf index 2e31b260076..d973914fa47 100644 --- a/tests/net/lib/dns_sd/prj-no-ipv6.conf +++ b/tests/net/lib/dns_sd/prj-no-ipv6.conf @@ -22,7 +22,6 @@ CONFIG_DNS_SD=y CONFIG_DNS_SD_LOG_LEVEL_DBG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 # Maybe avoid stack overflow on mps2_an385? diff --git a/tests/net/lib/dns_sd/prj.conf b/tests/net/lib/dns_sd/prj.conf index 02d34005774..52c1916e210 100644 --- a/tests/net/lib/dns_sd/prj.conf +++ b/tests/net/lib/dns_sd/prj.conf @@ -15,7 +15,6 @@ CONFIG_DNS_SD=y CONFIG_DNS_SD_LOG_LEVEL_DBG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 # Maybe avoid stack overflow on mps2_an385? diff --git a/tests/net/lib/http_header_fields/prj.conf b/tests/net/lib/http_header_fields/prj.conf index 7edaa3b1a5b..a8dba22a09c 100644 --- a/tests/net/lib/http_header_fields/prj.conf +++ b/tests/net/lib/http_header_fields/prj.conf @@ -5,7 +5,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST_STACK_SIZE=1024 CONFIG_HTTP_PARSER=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=1280 # Enable strict parser by uncommenting the following line # CONFIG_HTTP_PARSER_STRICT=y diff --git a/tests/net/lib/http_server/common/prj.conf b/tests/net/lib/http_server/common/prj.conf index 4422a170d58..7fa5d3d6dd0 100644 --- a/tests/net/lib/http_server/common/prj.conf +++ b/tests/net/lib/http_server/common/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NETWORKING=y CONFIG_NET_TEST=y diff --git a/tests/net/lib/lwm2m/block_transfer/prj.conf b/tests/net/lib/lwm2m/block_transfer/prj.conf index f88f71b4d5d..ea874ac5925 100644 --- a/tests/net/lib/lwm2m/block_transfer/prj.conf +++ b/tests/net/lib/lwm2m/block_transfer/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_json/prj.conf b/tests/net/lib/lwm2m/content_json/prj.conf index 7ff07df9897..b660af21e1d 100644 --- a/tests/net/lib/lwm2m/content_json/prj.conf +++ b/tests/net/lib/lwm2m/content_json/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_link_format/prj.conf b/tests/net/lib/lwm2m/content_link_format/prj.conf index 952b54a4566..e7e630f91f1 100644 --- a/tests/net/lib/lwm2m/content_link_format/prj.conf +++ b/tests/net/lib/lwm2m/content_link_format/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_oma_tlv/prj.conf b/tests/net/lib/lwm2m/content_oma_tlv/prj.conf index 6041addad83..8dc442cb035 100644 --- a/tests/net/lib/lwm2m/content_oma_tlv/prj.conf +++ b/tests/net/lib/lwm2m/content_oma_tlv/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_plain_text/prj.conf b/tests/net/lib/lwm2m/content_plain_text/prj.conf index 877c969958f..79338ed1f31 100644 --- a/tests/net/lib/lwm2m/content_plain_text/prj.conf +++ b/tests/net/lib/lwm2m/content_plain_text/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_raw_cbor/prj.conf b/tests/net/lib/lwm2m/content_raw_cbor/prj.conf index 64ab6f89d22..6a29c438cab 100644 --- a/tests/net/lib/lwm2m/content_raw_cbor/prj.conf +++ b/tests/net/lib/lwm2m/content_raw_cbor/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/content_senml_cbor/prj.conf b/tests/net/lib/lwm2m/content_senml_cbor/prj.conf index 27a8364af58..e2f6bdb952f 100644 --- a/tests/net/lib/lwm2m/content_senml_cbor/prj.conf +++ b/tests/net/lib/lwm2m/content_senml_cbor/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/engine/prj.conf b/tests/net/lib/lwm2m/engine/prj.conf index 4477075056a..ad804ff4f1c 100644 --- a/tests/net/lib/lwm2m/engine/prj.conf +++ b/tests/net/lib/lwm2m/engine/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf index e051abf4191..775cea846a1 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf b/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf index e051abf4191..775cea846a1 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf index 4d5e497fe8d..84e3a4bb289 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf @@ -1,7 +1,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/mqtt_packet/prj.conf b/tests/net/lib/mqtt_packet/prj.conf index 883a38d2d9b..1c4a907a155 100644 --- a/tests/net/lib/mqtt_packet/prj.conf +++ b/tests/net/lib/mqtt_packet/prj.conf @@ -9,6 +9,5 @@ CONFIG_TEST_RANDOM_GENERATOR=y # enable the MQTT lib CONFIG_MQTT_LIB=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_MAIN_STACK_SIZE=1280 diff --git a/tests/net/lib/mqtt_publisher/prj.conf b/tests/net/lib/mqtt_publisher/prj.conf index 32ad6f7cfd8..c9342459893 100644 --- a/tests/net/lib/mqtt_publisher/prj.conf +++ b/tests/net/lib/mqtt_publisher/prj.conf @@ -32,4 +32,3 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_BUF_DATA_SIZE=256 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/mqtt_publisher/prj_tls.conf b/tests/net/lib/mqtt_publisher/prj_tls.conf index 9e575d1bc07..2cae0098472 100644 --- a/tests/net/lib/mqtt_publisher/prj_tls.conf +++ b/tests/net/lib/mqtt_publisher/prj_tls.conf @@ -48,4 +48,3 @@ CONFIG_MBEDTLS_HEAP_SIZE=30000 # for tls_entropy_func CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/mqtt_pubsub/prj.conf b/tests/net/lib/mqtt_pubsub/prj.conf index 26ff5f835ac..368a9c283dd 100644 --- a/tests/net/lib/mqtt_pubsub/prj.conf +++ b/tests/net/lib/mqtt_pubsub/prj.conf @@ -32,4 +32,3 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_BUF_DATA_SIZE=256 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/mqtt_sn_client/prj.conf b/tests/net/lib/mqtt_sn_client/prj.conf index 5c0a5c99f48..636d6248748 100644 --- a/tests/net/lib/mqtt_sn_client/prj.conf +++ b/tests/net/lib/mqtt_sn_client/prj.conf @@ -18,4 +18,3 @@ CONFIG_ZTEST_STACK_SIZE=8192 CONFIG_STACK_USAGE=y CONFIG_STACK_SENTINEL=y CONFIG_DEBUG=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/mqtt_sn_packet/prj.conf b/tests/net/lib/mqtt_sn_packet/prj.conf index 870f8a813db..afb67dc24da 100644 --- a/tests/net/lib/mqtt_sn_packet/prj.conf +++ b/tests/net/lib/mqtt_sn_packet/prj.conf @@ -14,4 +14,3 @@ CONFIG_NET_BUF_LOG_LEVEL_DBG=y CONFIG_MQTT_SN_LIB=y CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=1280 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/mqtt_subscriber/prj.conf b/tests/net/lib/mqtt_subscriber/prj.conf index 26ff5f835ac..368a9c283dd 100644 --- a/tests/net/lib/mqtt_subscriber/prj.conf +++ b/tests/net/lib/mqtt_subscriber/prj.conf @@ -32,4 +32,3 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_BUF_DATA_SIZE=256 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/lib/tls_credentials/prj.conf b/tests/net/lib/tls_credentials/prj.conf index c173e530849..91424b1715d 100644 --- a/tests/net/lib/tls_credentials/prj.conf +++ b/tests/net/lib/tls_credentials/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y CONFIG_NETWORKING=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/mgmt/prj.conf b/tests/net/mgmt/prj.conf index 90ecd17868c..3d41dd4d851 100644 --- a/tests/net/mgmt/prj.conf +++ b/tests/net/mgmt/prj.conf @@ -18,4 +18,3 @@ CONFIG_NET_IPV6=y CONFIG_NET_L2_DUMMY=y CONFIG_NET_L2_ETHERNET=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/mld/prj.conf b/tests/net/mld/prj.conf index 59d326f15cd..5eeab7f81ec 100644 --- a/tests/net/mld/prj.conf +++ b/tests/net/mld/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_TEST=y CONFIG_NETWORKING=y diff --git a/tests/net/neighbor/prj.conf b/tests/net/neighbor/prj.conf index ff1299a29f3..0116a6e1011 100644 --- a/tests/net/neighbor/prj.conf +++ b/tests/net/neighbor/prj.conf @@ -14,5 +14,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 CONFIG_NET_IPV6_MAX_NEIGHBORS=4 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_L2_ETHERNET=n diff --git a/tests/net/net_pkt/prj.conf b/tests/net/net_pkt/prj.conf index 9f2702d15e4..b1902d33c71 100644 --- a/tests/net/net_pkt/prj.conf +++ b/tests/net/net_pkt/prj.conf @@ -1,6 +1,5 @@ CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NETWORKING=y CONFIG_NET_L2_ETHERNET=y CONFIG_NET_IPV4=y diff --git a/tests/net/npf/prj.conf b/tests/net/npf/prj.conf index 57d62213090..a5b746ea3dc 100644 --- a/tests/net/npf/prj.conf +++ b/tests/net/npf/prj.conf @@ -10,7 +10,6 @@ CONFIG_NET_PKT_RX_COUNT=20 CONFIG_NET_BUF_RX_COUNT=20 CONFIG_NET_BUF_TX_COUNT=20 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_COMPILER_COLOR_DIAGNOSTICS=n CONFIG_NET_IPV4=y CONFIG_NET_PKT_FILTER_IPV4_HOOK=y diff --git a/tests/net/offloaded_netdev/prj.conf b/tests/net/offloaded_netdev/prj.conf index 8bdc82930bb..ad92b9bec28 100644 --- a/tests/net/offloaded_netdev/prj.conf +++ b/tests/net/offloaded_netdev/prj.conf @@ -4,7 +4,6 @@ CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_LOG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_NET_OFFLOAD=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/pm/prj.conf b/tests/net/pm/prj.conf index e7dae2dd227..5650693d56c 100644 --- a/tests/net/pm/prj.conf +++ b/tests/net/pm/prj.conf @@ -16,4 +16,3 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/ppp/driver/prj.conf b/tests/net/ppp/driver/prj.conf index 02f619cf24f..25ceb368947 100644 --- a/tests/net/ppp/driver/prj.conf +++ b/tests/net/ppp/driver/prj.conf @@ -23,6 +23,5 @@ CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_ND=n CONFIG_NET_CONFIG_AUTO_INIT=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y #CONFIG_NET_PPP_LOG_LEVEL_DBG=y CONFIG_CRC=y diff --git a/tests/net/promiscuous/prj.conf b/tests/net/promiscuous/prj.conf index 3c210710af5..5f56de6e98e 100644 --- a/tests/net/promiscuous/prj.conf +++ b/tests/net/promiscuous/prj.conf @@ -22,4 +22,3 @@ CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_MAX_NEIGHBORS=1 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/ptp/clock/prj.conf b/tests/net/ptp/clock/prj.conf index 1cfee2add56..71efa260d7c 100644 --- a/tests/net/ptp/clock/prj.conf +++ b/tests/net/ptp/clock/prj.conf @@ -19,7 +19,6 @@ CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n CONFIG_PTP_CLOCK=y diff --git a/tests/net/route/prj.conf b/tests/net/route/prj.conf index 05a1ad8c84b..0ce002a9f65 100644 --- a/tests/net/route/prj.conf +++ b/tests/net/route/prj.conf @@ -21,4 +21,3 @@ CONFIG_NET_MAX_ROUTES=4 CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/route_mcast/prj.conf b/tests/net/route_mcast/prj.conf index 3c0eb6107d6..c655d805cdb 100644 --- a/tests/net/route_mcast/prj.conf +++ b/tests/net/route_mcast/prj.conf @@ -21,6 +21,5 @@ CONFIG_NET_MAX_ROUTES=4 CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_MAX_MCAST_ROUTES=10 CONFIG_NET_ROUTE_MCAST=y diff --git a/tests/net/shell/prj.conf b/tests/net/shell/prj.conf index 082cee7758d..f6aef9e72c2 100644 --- a/tests/net/shell/prj.conf +++ b/tests/net/shell/prj.conf @@ -17,7 +17,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=2 CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_SHELL=y CONFIG_LOG_PRINTK=n CONFIG_SHELL_BACKEND_DUMMY=y diff --git a/tests/net/socket/af_packet/prj.conf b/tests/net/socket/af_packet/prj.conf index 8636ac9c5cf..c73bd698d18 100644 --- a/tests/net/socket/af_packet/prj.conf +++ b/tests/net/socket/af_packet/prj.conf @@ -17,7 +17,6 @@ CONFIG_ETH_DRIVER=n CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y CONFIG_NET_LOG=y CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/af_packet_ipproto_raw/prj.conf b/tests/net/socket/af_packet_ipproto_raw/prj.conf index bd6399ab152..57c66491ea1 100644 --- a/tests/net/socket/af_packet_ipproto_raw/prj.conf +++ b/tests/net/socket/af_packet_ipproto_raw/prj.conf @@ -19,7 +19,6 @@ CONFIG_NET_L2_DUMMY=y CONFIG_NET_IF_MAX_IPV4_COUNT=4 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y CONFIG_NET_LOG=y CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/can/prj.conf b/tests/net/socket/can/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/net/socket/can/prj.conf +++ b/tests/net/socket/can/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/socket/getaddrinfo/prj.conf b/tests/net/socket/getaddrinfo/prj.conf index f42658a1d92..0de25de2f00 100644 --- a/tests/net/socket/getaddrinfo/prj.conf +++ b/tests/net/socket/getaddrinfo/prj.conf @@ -26,7 +26,6 @@ CONFIG_DNS_SERVER2="127.0.0.1:15353" CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # User mode requirements CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/getnameinfo/prj.conf b/tests/net/socket/getnameinfo/prj.conf index eb7851f76fc..3b7eb423f45 100644 --- a/tests/net/socket/getnameinfo/prj.conf +++ b/tests/net/socket/getnameinfo/prj.conf @@ -24,7 +24,6 @@ CONFIG_DNS_SERVER2="192.0.2.2:15353" CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # User mode requirements CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/misc/prj.conf b/tests/net/socket/misc/prj.conf index b71231f2705..5d83f5013be 100644 --- a/tests/net/socket/misc/prj.conf +++ b/tests/net/socket/misc/prj.conf @@ -29,7 +29,6 @@ CONFIG_NET_IF_MAX_IPV4_COUNT=3 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # TCP handshake requires more packets CONFIG_NET_PKT_TX_COUNT=10 diff --git a/tests/net/socket/net_mgmt/prj.conf b/tests/net/socket/net_mgmt/prj.conf index 58b4fc6ce75..d5c337242aa 100644 --- a/tests/net/socket/net_mgmt/prj.conf +++ b/tests/net/socket/net_mgmt/prj.conf @@ -20,7 +20,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # User mode requirements CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/offload_dispatcher/prj.conf b/tests/net/socket/offload_dispatcher/prj.conf index 0d185939cec..2ba9d78fed7 100644 --- a/tests/net/socket/offload_dispatcher/prj.conf +++ b/tests/net/socket/offload_dispatcher/prj.conf @@ -1,6 +1,5 @@ CONFIG_NET_TEST=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 # Networking config diff --git a/tests/net/socket/poll/prj.conf b/tests/net/socket/poll/prj.conf index 709f46062d9..fb9b598e32c 100644 --- a/tests/net/socket/poll/prj.conf +++ b/tests/net/socket/poll/prj.conf @@ -20,7 +20,6 @@ CONFIG_ZTEST_STACK_SIZE=1280 CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT=100 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y CONFIG_NET_DRIVERS=y diff --git a/tests/net/socket/register/prj.conf b/tests/net/socket/register/prj.conf index 36da34741ce..d2b3e01b6c0 100644 --- a/tests/net/socket/register/prj.conf +++ b/tests/net/socket/register/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_NET_DRIVERS=y diff --git a/tests/net/socket/reuseaddr_reuseport/prj.conf b/tests/net/socket/reuseaddr_reuseport/prj.conf index 63b9e737e51..4d852d52e46 100644 --- a/tests/net/socket/reuseaddr_reuseport/prj.conf +++ b/tests/net/socket/reuseaddr_reuseport/prj.conf @@ -43,7 +43,6 @@ CONFIG_NET_TCP_TIME_WAIT_DELAY=200 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 # User mode requirements diff --git a/tests/net/socket/select/prj.conf b/tests/net/socket/select/prj.conf index 2641350a25d..7e962eee423 100644 --- a/tests/net/socket/select/prj.conf +++ b/tests/net/socket/select/prj.conf @@ -18,7 +18,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT=100 diff --git a/tests/net/socket/socketpair/prj.conf b/tests/net/socket/socketpair/prj.conf index 83ecd35957e..9789809556c 100644 --- a/tests/net/socket/socketpair/prj.conf +++ b/tests/net/socket/socketpair/prj.conf @@ -14,7 +14,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # User mode requirements CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/tcp/prj.conf b/tests/net/socket/tcp/prj.conf index 45695703542..9ef9b310916 100644 --- a/tests/net/socket/tcp/prj.conf +++ b/tests/net/socket/tcp/prj.conf @@ -40,7 +40,6 @@ CONFIG_NET_TCP_RETRY_COUNT=3 CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT=120 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_NET_CONTEXT_RCVTIMEO=y diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 6186a518624..842079fabb9 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -36,7 +36,6 @@ CONFIG_NET_BUF_TX_COUNT=32 CONFIG_NET_BUF_RX_COUNT=32 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=3072 CONFIG_MBEDTLS_ENABLE_HEAP=y diff --git a/tests/net/socket/tls_ext/prj.conf b/tests/net/socket/tls_ext/prj.conf index 5d8e65e8c70..b2e360bb4db 100644 --- a/tests/net/socket/tls_ext/prj.conf +++ b/tests/net/socket/tls_ext/prj.conf @@ -1,7 +1,6 @@ # General config CONFIG_SMP=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Networking config CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/socket/udp/prj.conf b/tests/net/socket/udp/prj.conf index e80eafaed3f..35289493288 100644 --- a/tests/net/socket/udp/prj.conf +++ b/tests/net/socket/udp/prj.conf @@ -24,7 +24,6 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_HEAP_MEM_POOL_SIZE=256 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_TEST=y CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/websocket/prj.conf b/tests/net/socket/websocket/prj.conf index 65058f79843..edf128a7df0 100644 --- a/tests/net/socket/websocket/prj.conf +++ b/tests/net/socket/websocket/prj.conf @@ -32,5 +32,4 @@ CONFIG_HEAP_MEM_POOL_SIZE=1500 # Test options CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/net/tcp/prj.conf b/tests/net/tcp/prj.conf index 810ce77b545..86f972f043d 100644 --- a/tests/net/tcp/prj.conf +++ b/tests/net/tcp/prj.conf @@ -36,7 +36,6 @@ CONFIG_NET_IPV6_NBR_CACHE=n CONFIG_NET_IPV6_MLD=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=3072 CONFIG_HEAP_MEM_POOL_SIZE=8192 diff --git a/tests/net/traffic_class/prj.conf b/tests/net/traffic_class/prj.conf index 6da597ef366..41ff756bdf9 100644 --- a/tests/net/traffic_class/prj.conf +++ b/tests/net/traffic_class/prj.conf @@ -27,6 +27,5 @@ CONFIG_NET_CONTEXT_PRIORITY=y CONFIG_NET_TC_TX_COUNT=8 CONFIG_NET_TC_RX_COUNT=8 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n diff --git a/tests/net/trickle/prj.conf b/tests/net/trickle/prj.conf index 1066b87eb6a..267aa020c0c 100644 --- a/tests/net/trickle/prj.conf +++ b/tests/net/trickle/prj.conf @@ -15,7 +15,6 @@ CONFIG_NET_BUF_RX_COUNT=5 CONFIG_NET_BUF_TX_COUNT=5 CONFIG_NET_TRICKLE=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=1024 CONFIG_NET_DRIVERS=y CONFIG_NET_LOOPBACK=y diff --git a/tests/net/tx_timestamp/prj.conf b/tests/net/tx_timestamp/prj.conf index e739c0688ed..7f028d9390a 100644 --- a/tests/net/tx_timestamp/prj.conf +++ b/tests/net/tx_timestamp/prj.conf @@ -23,4 +23,3 @@ CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n CONFIG_NET_PKT_TIMESTAMP=y CONFIG_NET_PKT_TIMESTAMP_THREAD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/udp/prj.conf b/tests/net/udp/prj.conf index a70f51e23e5..3782275cca8 100644 --- a/tests/net/udp/prj.conf +++ b/tests/net/udp/prj.conf @@ -23,4 +23,3 @@ CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 # Turn off UDP checksum checking as the test fails otherwise. CONFIG_NET_UDP_CHECKSUM=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/utils/prj.conf b/tests/net/utils/prj.conf index 404cfcdb48a..f63c6c8f05d 100644 --- a/tests/net/utils/prj.conf +++ b/tests/net/utils/prj.conf @@ -17,4 +17,3 @@ CONFIG_NET_UDP=y CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=1280 CONFIG_TEST_USERSPACE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/net/virtual/prj.conf b/tests/net/virtual/prj.conf index d9279fa4f8a..76683036a53 100644 --- a/tests/net/virtual/prj.conf +++ b/tests/net/virtual/prj.conf @@ -41,6 +41,5 @@ CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n diff --git a/tests/net/vlan/prj.conf b/tests/net/vlan/prj.conf index 92f107cd131..48fa390cded 100644 --- a/tests/net/vlan/prj.conf +++ b/tests/net/vlan/prj.conf @@ -23,7 +23,6 @@ CONFIG_NET_VLAN=y CONFIG_NET_VLAN_COUNT=4 CONFIG_NET_CONTEXT_PRIORITY=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NET_CONFIG_SETTINGS=n CONFIG_NET_SHELL=n diff --git a/tests/net/wifi/wifi_nm/prj.conf b/tests/net/wifi/wifi_nm/prj.conf index abeb08fca4f..aab25c2a734 100644 --- a/tests/net/wifi/wifi_nm/prj.conf +++ b/tests/net/wifi/wifi_nm/prj.conf @@ -12,7 +12,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Disable internal ethernet drivers as the test is self contained # and does not need the on board driver to function. diff --git a/tests/posix/common/prj.conf b/tests/posix/common/prj.conf index 1c7e7bd220e..6c0b9153b6a 100644 --- a/tests/posix/common/prj.conf +++ b/tests/posix/common/prj.conf @@ -2,7 +2,6 @@ CONFIG_PTHREAD_IPC=y CONFIG_POSIX_API=y CONFIG_MAX_PTHREAD_COUNT=10 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SEM_VALUE_MAX=32767 CONFIG_POSIX_MQUEUE=y CONFIG_HEAP_MEM_POOL_SIZE=4096 diff --git a/tests/posix/eventfd/prj.conf b/tests/posix/eventfd/prj.conf index ac1dcf7c06a..4fcab370408 100644 --- a/tests/posix/eventfd/prj.conf +++ b/tests/posix/eventfd/prj.conf @@ -7,7 +7,6 @@ CONFIG_NET_SOCKETS=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_POSIX_API=y CONFIG_EVENTFD=y diff --git a/tests/posix/fs/prj.conf b/tests/posix/fs/prj.conf index 24b214aa6ce..bb6d36b836e 100644 --- a/tests/posix/fs/prj.conf +++ b/tests/posix/fs/prj.conf @@ -4,6 +4,5 @@ CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_POSIX_API=y CONFIG_POSIX_FS=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=4096 CONFIG_EVENTFD=n diff --git a/tests/posix/getopt/prj.conf b/tests/posix/getopt/prj.conf index bcf51234f2a..034ce191ddf 100644 --- a/tests/posix/getopt/prj.conf +++ b/tests/posix/getopt/prj.conf @@ -2,5 +2,4 @@ CONFIG_GETOPT=y CONFIG_GETOPT_LONG=y CONFIG_LOG=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n diff --git a/tests/posix/headers/prj.conf b/tests/posix/headers/prj.conf index 43b6bc147c4..e64b889585a 100644 --- a/tests/posix/headers/prj.conf +++ b/tests/posix/headers/prj.conf @@ -1,6 +1,5 @@ CONFIG_POSIX_API=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # for POSIX_FS CONFIG_FILE_SYSTEM=y diff --git a/tests/posix/pthread_pressure/prj.conf b/tests/posix/pthread_pressure/prj.conf index 9499b191c2d..ba9a5f8487a 100644 --- a/tests/posix/pthread_pressure/prj.conf +++ b/tests/posix/pthread_pressure/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_POSIX_API=y ## Note: for benchmarking purposes, uncomment the Kconfig below diff --git a/tests/subsys/bindesc/definition/prj.conf b/tests/subsys/bindesc/definition/prj.conf index d264ff631de..80bd7e861c6 100644 --- a/tests/subsys/bindesc/definition/prj.conf +++ b/tests/subsys/bindesc/definition/prj.conf @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_BINDESC=y CONFIG_BINDESC_DEFINE=y diff --git a/tests/subsys/canbus/isotp/conformance/prj.conf b/tests/subsys/canbus/isotp/conformance/prj.conf index f3e50838304..5b25fdc81a6 100644 --- a/tests/subsys/canbus/isotp/conformance/prj.conf +++ b/tests/subsys/canbus/isotp/conformance/prj.conf @@ -1,6 +1,5 @@ CONFIG_CAN=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ISOTP=y CONFIG_ISOTP_USE_TX_BUF=y CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y diff --git a/tests/subsys/canbus/isotp/implementation/prj.conf b/tests/subsys/canbus/isotp/implementation/prj.conf index 4ab0fe51d38..648acdbf209 100644 --- a/tests/subsys/canbus/isotp/implementation/prj.conf +++ b/tests/subsys/canbus/isotp/implementation/prj.conf @@ -1,6 +1,5 @@ CONFIG_CAN=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ISOTP=y CONFIG_ISOTP_USE_TX_BUF=y CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y diff --git a/tests/subsys/debug/coredump_backends/prj.conf b/tests/subsys/debug/coredump_backends/prj.conf index dc18b00328a..dae6fd98be5 100644 --- a/tests/subsys/debug/coredump_backends/prj.conf +++ b/tests/subsys/debug/coredump_backends/prj.conf @@ -6,4 +6,3 @@ CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_LINKER_RAM=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/debug/coredump_backends/prj_backend_other.conf b/tests/subsys/debug/coredump_backends/prj_backend_other.conf index fd1dc6213cc..7b902485c10 100644 --- a/tests/subsys/debug/coredump_backends/prj_backend_other.conf +++ b/tests/subsys/debug/coredump_backends/prj_backend_other.conf @@ -4,4 +4,3 @@ CONFIG_DEBUG_COREDUMP_BACKEND_OTHER=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_LINKER_RAM=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/debug/coredump_backends/prj_flash_partition.conf b/tests/subsys/debug/coredump_backends/prj_flash_partition.conf index bd45af4cdd7..71e3eea70fe 100644 --- a/tests/subsys/debug/coredump_backends/prj_flash_partition.conf +++ b/tests/subsys/debug/coredump_backends/prj_flash_partition.conf @@ -7,4 +7,3 @@ CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_FLASH=y CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_LINKER_RAM=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/dfu/img_util/prj.conf b/tests/subsys/dfu/img_util/prj.conf index b8183095aaf..6beb6b102a0 100644 --- a/tests/subsys/dfu/img_util/prj.conf +++ b/tests/subsys/dfu/img_util/prj.conf @@ -7,4 +7,3 @@ CONFIG_IMG_MANAGER=y CONFIG_IMG_ENABLE_IMAGE_CHECK=y CONFIG_MCUBOOT_IMG_MANAGER=y CONFIG_IMG_BLOCK_BUF_SIZE=512 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/dfu/mcuboot/prj.conf b/tests/subsys/dfu/mcuboot/prj.conf index ebef72eb7e8..ddd227b82ca 100644 --- a/tests/subsys/dfu/mcuboot/prj.conf +++ b/tests/subsys/dfu/mcuboot/prj.conf @@ -6,4 +6,3 @@ CONFIG_STREAM_FLASH=y CONFIG_IMG_MANAGER=y CONFIG_MCUBOOT_IMG_MANAGER=y CONFIG_IMG_BLOCK_BUF_SIZE=512 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/dfu/mcuboot_multi/prj.conf b/tests/subsys/dfu/mcuboot_multi/prj.conf index 2ec75613572..672058b3a26 100644 --- a/tests/subsys/dfu/mcuboot_multi/prj.conf +++ b/tests/subsys/dfu/mcuboot_multi/prj.conf @@ -7,4 +7,3 @@ CONFIG_IMG_MANAGER=y CONFIG_MCUBOOT_IMG_MANAGER=y CONFIG_IMG_BLOCK_BUF_SIZE=512 CONFIG_UPDATEABLE_IMAGE_NUMBER=2 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/dsp/basicmath/prj.conf b/tests/subsys/dsp/basicmath/prj.conf index 4e2cb0cae14..e2b18830aa0 100644 --- a/tests/subsys/dsp/basicmath/prj.conf +++ b/tests/subsys/dsp/basicmath/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y diff --git a/tests/subsys/dsp/basicmath/prj_arc.conf b/tests/subsys/dsp/basicmath/prj_arc.conf index 865604bbd25..e0558196361 100644 --- a/tests/subsys/dsp/basicmath/prj_arc.conf +++ b/tests/subsys/dsp/basicmath/prj_arc.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ARCMWDT_LIBC=y CONFIG_CPLUSPLUS=y CONFIG_DSP=y diff --git a/tests/subsys/dsp/print_format/prj.conf b/tests/subsys/dsp/print_format/prj.conf index 9f0a63c9804..d675ac84890 100644 --- a/tests/subsys/dsp/print_format/prj.conf +++ b/tests/subsys/dsp/print_format/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_NEWLIB_LIBC=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y diff --git a/tests/subsys/edac/ibecc/prj.conf b/tests/subsys/edac/ibecc/prj.conf index 6dd0980fead..e82a8f1c952 100644 --- a/tests/subsys/edac/ibecc/prj.conf +++ b/tests/subsys/edac/ibecc/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_EDAC=y CONFIG_EDAC_IBECC=y CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/edac/ibecc_cov/prj.conf b/tests/subsys/edac/ibecc_cov/prj.conf index f205f0515e0..9707ccfa2df 100644 --- a/tests/subsys/edac/ibecc_cov/prj.conf +++ b/tests/subsys/edac/ibecc_cov/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/emul/prj.conf b/tests/subsys/emul/prj.conf index 452d3c4f157..81a9aca7dbd 100644 --- a/tests/subsys/emul/prj.conf +++ b/tests/subsys/emul/prj.conf @@ -3,6 +3,5 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SENSOR=y CONFIG_BMI160_TRIGGER_NONE=y diff --git a/tests/subsys/fs/ext2/prj.conf b/tests/subsys/fs/ext2/prj.conf index 86f11ba1086..8b965329f6b 100644 --- a/tests/subsys/fs/ext2/prj.conf +++ b/tests/subsys/fs/ext2/prj.conf @@ -8,5 +8,4 @@ CONFIG_DISK_DRIVER_RAM=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/fs/ext2/prj_big.conf b/tests/subsys/fs/ext2/prj_big.conf index 4590cd4cd57..1463ebfa8cc 100644 --- a/tests/subsys/fs/ext2/prj_big.conf +++ b/tests/subsys/fs/ext2/prj_big.conf @@ -10,7 +10,6 @@ CONFIG_EXT2_MAX_BLOCK_COUNT=20 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_APP_TEST_BIG=y diff --git a/tests/subsys/fs/ext2/prj_flash.conf b/tests/subsys/fs/ext2/prj_flash.conf index 741f45771af..ada4707349b 100644 --- a/tests/subsys/fs/ext2/prj_flash.conf +++ b/tests/subsys/fs/ext2/prj_flash.conf @@ -8,5 +8,4 @@ CONFIG_DISK_DRIVER_FLASH=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/fs/ext2/prj_sdcard.conf b/tests/subsys/fs/ext2/prj_sdcard.conf index 6089edf67c0..dcc472b4081 100644 --- a/tests/subsys/fs/ext2/prj_sdcard.conf +++ b/tests/subsys/fs/ext2/prj_sdcard.conf @@ -12,5 +12,4 @@ CONFIG_EXT2_DISK_STARTING_SECTOR=34 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/fs/fat_fs_api/prj.conf b/tests/subsys/fs/fat_fs_api/prj.conf index 3a46ae26ed6..5e22d035728 100644 --- a/tests/subsys/fs/fat_fs_api/prj.conf +++ b/tests/subsys/fs/fat_fs_api/prj.conf @@ -4,6 +4,5 @@ CONFIG_LOG=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_DISK_DRIVER_FLASH=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/fs/fat_fs_api/prj_lfn.conf b/tests/subsys/fs/fat_fs_api/prj_lfn.conf index 6058670cdf6..eaa76d5d695 100644 --- a/tests/subsys/fs/fat_fs_api/prj_lfn.conf +++ b/tests/subsys/fs/fat_fs_api/prj_lfn.conf @@ -5,6 +5,5 @@ CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_FS_FATFS_LFN=y CONFIG_DISK_DRIVER_FLASH=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/fs/fat_fs_api/prj_mmc.conf b/tests/subsys/fs/fat_fs_api/prj_mmc.conf index 62e1d08de4d..e3e903f5a89 100644 --- a/tests/subsys/fs/fat_fs_api/prj_mmc.conf +++ b/tests/subsys/fs/fat_fs_api/prj_mmc.conf @@ -4,6 +4,5 @@ CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_SPI=y CONFIG_GPIO=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MMC_VOLUME_NAME="NAND" CONFIG_MAIN_STACK_SIZE=4096 diff --git a/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf b/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf index bff7a3e070d..a7b02e5bce1 100644 --- a/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf +++ b/tests/subsys/fs/fat_fs_api/prj_native_posix_ram.conf @@ -3,6 +3,5 @@ CONFIG_FILE_SYSTEM_MKFS=y CONFIG_LOG=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/fs/fat_fs_dual_drive/prj.conf b/tests/subsys/fs/fat_fs_dual_drive/prj.conf index bfdefcdfdc4..1d31e8beb3b 100644 --- a/tests/subsys/fs/fat_fs_dual_drive/prj.conf +++ b/tests/subsys/fs/fat_fs_dual_drive/prj.conf @@ -4,5 +4,4 @@ CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_FS_FATFS_NUM_FILES=8 CONFIG_FS_FATFS_NUM_DIRS=8 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/subsys/fs/fcb/prj.conf b/tests/subsys/fs/fcb/prj.conf index e41051fb35a..c30a352a0e4 100644 --- a/tests/subsys/fs/fcb/prj.conf +++ b/tests/subsys/fs/fcb/prj.conf @@ -5,4 +5,3 @@ CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y CONFIG_FCB=y CONFIG_FCB_ALLOW_FIXED_ENDMARKER=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/fs/fs_api/prj.conf b/tests/subsys/fs/fs_api/prj.conf index d5feeed8bff..47eb9e2362c 100644 --- a/tests/subsys/fs/fs_api/prj.conf +++ b/tests/subsys/fs/fs_api/prj.conf @@ -1,3 +1,2 @@ CONFIG_FILE_SYSTEM=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/fs/littlefs/prj.conf b/tests/subsys/fs/littlefs/prj.conf index 9ccaa0d4589..de33b272ae6 100644 --- a/tests/subsys/fs/littlefs/prj.conf +++ b/tests/subsys/fs/littlefs/prj.conf @@ -1,7 +1,6 @@ CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_MKFS=y CONFIG_FILE_SYSTEM_LITTLEFS=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=4096 # Performance tests need custom buffer allocation diff --git a/tests/subsys/fs/multi-fs/prj.conf b/tests/subsys/fs/multi-fs/prj.conf index 7a2b28cffed..287f0363dca 100644 --- a/tests/subsys/fs/multi-fs/prj.conf +++ b/tests/subsys/fs/multi-fs/prj.conf @@ -10,5 +10,4 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/subsys/fs/multi-fs/prj_fs_shell.conf b/tests/subsys/fs/multi-fs/prj_fs_shell.conf index aa2c4cfd79c..327e2b4f2fb 100644 --- a/tests/subsys/fs/multi-fs/prj_fs_shell.conf +++ b/tests/subsys/fs/multi-fs/prj_fs_shell.conf @@ -14,5 +14,4 @@ CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_MAIN_STACK_SIZE=1024 CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/subsys/fs/nvs/prj.conf b/tests/subsys/fs/nvs/prj.conf index b4b850229e7..7d7f4aec2e9 100644 --- a/tests/subsys/fs/nvs/prj.conf +++ b/tests/subsys/fs/nvs/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=4096 -CONFIG_ZTEST_NEW_API=y CONFIG_STDOUT_CONSOLE=y CONFIG_FLASH=y diff --git a/tests/subsys/input/api/prj.conf b/tests/subsys/input/api/prj.conf index bd3dc1ced37..dff5c3dc7f6 100644 --- a/tests/subsys/input/api/prj.conf +++ b/tests/subsys/input/api/prj.conf @@ -1,5 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INPUT=y diff --git a/tests/subsys/input/input_longpress/prj.conf b/tests/subsys/input/input_longpress/prj.conf index b101f410c69..bc713698bbf 100644 --- a/tests/subsys/input/input_longpress/prj.conf +++ b/tests/subsys/input/input_longpress/prj.conf @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_INPUT=y CONFIG_INPUT_MODE_SYNCHRONOUS=y diff --git a/tests/subsys/ipc/ipc_service/prj.conf b/tests/subsys/ipc/ipc_service/prj.conf index 67befb6214a..01e20c4e9b9 100644 --- a/tests/subsys/ipc/ipc_service/prj.conf +++ b/tests/subsys/ipc/ipc_service/prj.conf @@ -4,4 +4,3 @@ CONFIG_ZTEST=y CONFIG_MMU=y CONFIG_IPC_SERVICE=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/jwt/prj.conf b/tests/subsys/jwt/prj.conf index fe632553ea3..046cc9ac429 100644 --- a/tests/subsys/jwt/prj.conf +++ b/tests/subsys/jwt/prj.conf @@ -20,5 +20,3 @@ CONFIG_MBEDTLS_USER_CONFIG_FILE="user-tls-conf.h" CONFIG_NET_SOCKETS=y CONFIG_NEWLIB_LIBC=y - -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/llext/prj.conf b/tests/subsys/llext/prj.conf index e6f45708208..ed104f56b08 100644 --- a/tests/subsys/llext/prj.conf +++ b/tests/subsys/llext/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=8192 CONFIG_LOG=y CONFIG_LOG_MODE_IMMEDIATE=y diff --git a/tests/subsys/logging/log_api/prj.conf b/tests/subsys/logging/log_api/prj.conf index b28665151be..c46ee4c1886 100644 --- a/tests/subsys/logging/log_api/prj.conf +++ b/tests/subsys/logging/log_api/prj.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y diff --git a/tests/subsys/logging/log_backend_fs/prj.conf b/tests/subsys/logging/log_backend_fs/prj.conf index 4f0984364c4..6ea2195cd8f 100644 --- a/tests/subsys/logging/log_backend_fs/prj.conf +++ b/tests/subsys/logging/log_backend_fs/prj.conf @@ -1,7 +1,6 @@ CONFIG_ZTEST=y CONFIG_ASSERT=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_LOG_BACKEND_FS=y diff --git a/tests/subsys/logging/log_backend_init/prj.conf b/tests/subsys/logging/log_backend_init/prj.conf index cbb5cf0b4b2..f28ddfb8fc3 100644 --- a/tests/subsys/logging/log_backend_init/prj.conf +++ b/tests/subsys/logging/log_backend_init/prj.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_PRINTK=n diff --git a/tests/subsys/logging/log_benchmark/prj.conf b/tests/subsys/logging/log_benchmark/prj.conf index 9e5cb801ccf..858c9ec0f95 100644 --- a/tests/subsys/logging/log_benchmark/prj.conf +++ b/tests/subsys/logging/log_benchmark/prj.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_PRINTK=n diff --git a/tests/subsys/logging/log_cache/prj.conf b/tests/subsys/logging/log_cache/prj.conf index 49146d8df2e..2bba192e203 100644 --- a/tests/subsys/logging/log_cache/prj.conf +++ b/tests/subsys/logging/log_cache/prj.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_PRINTK=n diff --git a/tests/subsys/logging/log_core_additional/log_sync.conf b/tests/subsys/logging/log_core_additional/log_sync.conf index c9894d82dd7..9e8b101f546 100644 --- a/tests/subsys/logging/log_core_additional/log_sync.conf +++ b/tests/subsys/logging/log_core_additional/log_sync.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_OUTPUT=y diff --git a/tests/subsys/logging/log_core_additional/log_user.conf b/tests/subsys/logging/log_core_additional/log_user.conf index 4922dfbb411..ae3240c0e21 100644 --- a/tests/subsys/logging/log_core_additional/log_user.conf +++ b/tests/subsys/logging/log_core_additional/log_user.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y diff --git a/tests/subsys/logging/log_core_additional/prj.conf b/tests/subsys/logging/log_core_additional/prj.conf index a2bacab3cf5..cd3008f3bcc 100644 --- a/tests/subsys/logging/log_core_additional/prj.conf +++ b/tests/subsys/logging/log_core_additional/prj.conf @@ -1,6 +1,5 @@ CONFIG_MAIN_THREAD_PRIORITY=5 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_OUTPUT=y diff --git a/tests/subsys/logging/log_custom_header/prj.conf b/tests/subsys/logging/log_custom_header/prj.conf index f905dd515d2..49d484e56cb 100644 --- a/tests/subsys/logging/log_custom_header/prj.conf +++ b/tests/subsys/logging/log_custom_header/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_LOG_OUTPUT=y CONFIG_LOG_PRINTK=n diff --git a/tests/subsys/logging/log_immediate/prj.conf b/tests/subsys/logging/log_immediate/prj.conf index a6a56e16dce..63b835d6c16 100644 --- a/tests/subsys/logging/log_immediate/prj.conf +++ b/tests/subsys/logging/log_immediate/prj.conf @@ -1,5 +1,4 @@ CONFIG_MAIN_THREAD_PRIORITY=5 -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y diff --git a/tests/subsys/logging/log_link_order/prj.conf b/tests/subsys/logging/log_link_order/prj.conf index c44f1e61558..205868ec699 100644 --- a/tests/subsys/logging/log_link_order/prj.conf +++ b/tests/subsys/logging/log_link_order/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_EXTRA_STACK_SIZE=2048 CONFIG_TEST_LOGGING_DEFAULTS=n diff --git a/tests/subsys/logging/log_links/prj.conf b/tests/subsys/logging/log_links/prj.conf index 38052819354..1a83e45c08e 100644 --- a/tests/subsys/logging/log_links/prj.conf +++ b/tests/subsys/logging/log_links/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y diff --git a/tests/subsys/logging/log_msg/prj.conf b/tests/subsys/logging/log_msg/prj.conf index be567582f34..e1248e780d1 100644 --- a/tests/subsys/logging/log_msg/prj.conf +++ b/tests/subsys/logging/log_msg/prj.conf @@ -1,5 +1,4 @@ CONFIG_MAIN_THREAD_PRIORITY=5 -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y diff --git a/tests/subsys/logging/log_output/prj.conf b/tests/subsys/logging/log_output/prj.conf index 77447af2010..b02eb949445 100644 --- a/tests/subsys/logging/log_output/prj.conf +++ b/tests/subsys/logging/log_output/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_OUTPUT=y diff --git a/tests/subsys/logging/log_stack/prj.conf b/tests/subsys/logging/log_stack/prj.conf index 21779201fdf..c323d2513c3 100644 --- a/tests/subsys/logging/log_stack/prj.conf +++ b/tests/subsys/logging/log_stack/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_TEST_LOGGING_DEFAULTS=n diff --git a/tests/subsys/logging/log_stress/prj.conf b/tests/subsys/logging/log_stress/prj.conf index 7724dc95051..57f0e43212b 100644 --- a/tests/subsys/logging/log_stress/prj.conf +++ b/tests/subsys/logging/log_stress/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_TEST_LOGGING_DEFAULTS=n diff --git a/tests/subsys/logging/log_switch_format/prj.conf b/tests/subsys/logging/log_switch_format/prj.conf index 1660a619226..a071c6e27e9 100644 --- a/tests/subsys/logging/log_switch_format/prj.conf +++ b/tests/subsys/logging/log_switch_format/prj.conf @@ -1,5 +1,4 @@ CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=n CONFIG_ZTEST=y CONFIG_LOG_MIPI_SYST_ENABLE=y diff --git a/tests/subsys/logging/log_syst/prj.conf b/tests/subsys/logging/log_syst/prj.conf index 53dc2bce553..13c5e464e2c 100644 --- a/tests/subsys/logging/log_syst/prj.conf +++ b/tests/subsys/logging/log_syst/prj.conf @@ -1,5 +1,4 @@ CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=n CONFIG_ZTEST=y CONFIG_LOG_BACKEND_MOCK=y diff --git a/tests/subsys/logging/log_timestamp/prj.conf b/tests/subsys/logging/log_timestamp/prj.conf index 77447af2010..b02eb949445 100644 --- a/tests/subsys/logging/log_timestamp/prj.conf +++ b/tests/subsys/logging/log_timestamp/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_LOGGING_DEFAULTS=n CONFIG_LOG=y CONFIG_LOG_OUTPUT=y diff --git a/tests/subsys/mem_mgmt/mem_attr/prj.conf b/tests/subsys/mem_mgmt/mem_attr/prj.conf index 2fcddad0bc8..6c71044ec51 100644 --- a/tests/subsys/mem_mgmt/mem_attr/prj.conf +++ b/tests/subsys/mem_mgmt/mem_attr/prj.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_MEM_ATTR=y diff --git a/tests/subsys/mgmt/ec_host_cmd/simulator/prj.conf b/tests/subsys/mgmt/ec_host_cmd/simulator/prj.conf index 317978c0814..2bad8038ea3 100644 --- a/tests/subsys/mgmt/ec_host_cmd/simulator/prj.conf +++ b/tests/subsys/mgmt/ec_host_cmd/simulator/prj.conf @@ -2,4 +2,3 @@ CONFIG_EC_HOST_CMD=y CONFIG_EC_HOST_CMD_BACKEND_SIMULATOR=y CONFIG_EC_HOST_CMD_DEDICATED_THREAD=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/mgmt/ec_host_cmd/uart/prj.conf b/tests/subsys/mgmt/ec_host_cmd/uart/prj.conf index f543a8d267f..550872463ac 100644 --- a/tests/subsys/mgmt/ec_host_cmd/uart/prj.conf +++ b/tests/subsys/mgmt/ec_host_cmd/uart/prj.conf @@ -2,7 +2,6 @@ CONFIG_EC_HOST_CMD=y CONFIG_EC_HOST_CMD_BACKEND_UART=y CONFIG_EC_HOST_CMD_DEDICATED_THREAD=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_MOCKING=y CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y diff --git a/tests/subsys/mgmt/mcumgr/all_options/prj.conf b/tests/subsys/mgmt/mcumgr/all_options/prj.conf index d3eb5c39aca..42ce2e03c86 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/prj.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/prj.conf @@ -4,7 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TINYCRYPT=y CONFIG_TINYCRYPT_SHA256=y CONFIG_FILE_SYSTEM=y diff --git a/tests/subsys/mgmt/mcumgr/cb_notifications/prj.conf b/tests/subsys/mgmt/mcumgr/cb_notifications/prj.conf index b9cdf93a5c1..f668a2f0f73 100644 --- a/tests/subsys/mgmt/mcumgr/cb_notifications/prj.conf +++ b/tests/subsys/mgmt/mcumgr/cb_notifications/prj.conf @@ -14,5 +14,4 @@ CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256 CONFIG_MCUMGR_GRP_OS=y CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf index b4e5aac0d27..ef6c180ce9f 100644 --- a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf +++ b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf @@ -17,4 +17,3 @@ CONFIG_MCUMGR_GRP_FS=y CONFIG_MCUMGR_GRP_FS_FILE_STATUS=n CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH=y CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_CMD=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf index 461a0ec9477..c9a88a391ee 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf @@ -5,7 +5,6 @@ # # ZTEST config CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_NET_BUF=y diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_echo/prj.conf b/tests/subsys/mgmt/mcumgr/os_mgmt_echo/prj.conf index 69cbe9882f6..ff4475a4f2e 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_echo/prj.conf +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_echo/prj.conf @@ -13,4 +13,3 @@ CONFIG_MCUMGR_TRANSPORT_DUMMY=y CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256 CONFIG_MCUMGR_GRP_OS=y CONFIG_MCUMGR_GRP_OS_ECHO=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_info/prj.conf b/tests/subsys/mgmt/mcumgr/os_mgmt_info/prj.conf index 0aa68bbfc49..ec21be76e91 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_info/prj.conf +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_info/prj.conf @@ -15,5 +15,4 @@ CONFIG_MCUMGR_GRP_OS=y CONFIG_MCUMGR_GRP_OS_INFO=y CONFIG_MCUMGR_GRP_OS_INFO_CUSTOM_HOOKS=y CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 diff --git a/tests/subsys/mgmt/mcumgr/settings_mgmt/prj.conf b/tests/subsys/mgmt/mcumgr/settings_mgmt/prj.conf index e570c43b7dd..403a318ac1a 100644 --- a/tests/subsys/mgmt/mcumgr/settings_mgmt/prj.conf +++ b/tests/subsys/mgmt/mcumgr/settings_mgmt/prj.conf @@ -14,7 +14,6 @@ CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256 CONFIG_MCUMGR_GRP_SETTINGS=y CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y CONFIG_MCUMGR_GRP_SETTINGS_ACCESS_HOOK=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_SETTINGS=y CONFIG_SETTINGS_RUNTIME=y diff --git a/tests/subsys/mgmt/mcumgr/smp_client/prj.conf b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf index 22740657b78..fa9a90cfd54 100644 --- a/tests/subsys/mgmt/mcumgr/smp_client/prj.conf +++ b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf @@ -5,7 +5,6 @@ # # ZTEST config CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_NET_BUF=y diff --git a/tests/subsys/mgmt/mcumgr/smp_reassembly/prj.conf b/tests/subsys/mgmt/mcumgr/smp_reassembly/prj.conf index f30eed7221b..8e9962d9a04 100644 --- a/tests/subsys/mgmt/mcumgr/smp_reassembly/prj.conf +++ b/tests/subsys/mgmt/mcumgr/smp_reassembly/prj.conf @@ -10,4 +10,3 @@ CONFIG_ZCBOR=y CONFIG_CRC=y CONFIG_MCUMGR=y CONFIG_MCUMGR_TRANSPORT_NETBUF_COUNT=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/mgmt/mcumgr/smp_version/prj.conf b/tests/subsys/mgmt/mcumgr/smp_version/prj.conf index fb9a0c91c5c..2573d131822 100644 --- a/tests/subsys/mgmt/mcumgr/smp_version/prj.conf +++ b/tests/subsys/mgmt/mcumgr/smp_version/prj.conf @@ -13,6 +13,5 @@ CONFIG_MCUMGR_TRANSPORT_DUMMY=y CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256 CONFIG_MCUMGR_GRP_OS=y CONFIG_MCUMGR_GRP_OS_INFO=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_REBOOT=n diff --git a/tests/subsys/mgmt/mcumgr/zcbor_bulk/prj.conf b/tests/subsys/mgmt/mcumgr/zcbor_bulk/prj.conf index 892964fae7c..eca7db02abd 100644 --- a/tests/subsys/mgmt/mcumgr/zcbor_bulk/prj.conf +++ b/tests/subsys/mgmt/mcumgr/zcbor_bulk/prj.conf @@ -5,5 +5,4 @@ # CONFIG_ZTEST=y CONFIG_ZCBOR=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/subsys/modbus/prj.conf b/tests/subsys/modbus/prj.conf index 1118316b304..06166d17f9b 100644 --- a/tests/subsys/modbus/prj.conf +++ b/tests/subsys/modbus/prj.conf @@ -3,7 +3,6 @@ CONFIG_LOG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_LINE_CTRL=n diff --git a/tests/subsys/modem/backends/tty/prj.conf b/tests/subsys/modem/backends/tty/prj.conf index 16c2f0b73cc..236f7804cf8 100644 --- a/tests/subsys/modem/backends/tty/prj.conf +++ b/tests/subsys/modem/backends/tty/prj.conf @@ -7,6 +7,5 @@ CONFIG_MODEM_MODULES=y CONFIG_MODEM_BACKEND_TTY=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y diff --git a/tests/subsys/modem/modem_chat/prj.conf b/tests/subsys/modem/modem_chat/prj.conf index 7937ad4f546..d93100a74c9 100644 --- a/tests/subsys/modem/modem_chat/prj.conf +++ b/tests/subsys/modem/modem_chat/prj.conf @@ -7,4 +7,3 @@ CONFIG_MODEM_MODULES=y CONFIG_MODEM_CHAT=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/modem/modem_cmux/prj.conf b/tests/subsys/modem/modem_cmux/prj.conf index daa8bc7f0ff..905fe8235d6 100644 --- a/tests/subsys/modem/modem_cmux/prj.conf +++ b/tests/subsys/modem/modem_cmux/prj.conf @@ -7,4 +7,3 @@ CONFIG_MODEM_MODULES=y CONFIG_MODEM_CMUX=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/modem/modem_ppp/prj.conf b/tests/subsys/modem/modem_ppp/prj.conf index 4221f36a610..ac0366608dd 100644 --- a/tests/subsys/modem/modem_ppp/prj.conf +++ b/tests/subsys/modem/modem_ppp/prj.conf @@ -10,7 +10,6 @@ CONFIG_NET_L2_PPP=y CONFIG_ETH_NATIVE_POSIX=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=4 diff --git a/tests/subsys/openthread/prj.conf b/tests/subsys/openthread/prj.conf index c3fdba67ef0..cee7218f847 100644 --- a/tests/subsys/openthread/prj.conf +++ b/tests/subsys/openthread/prj.conf @@ -1,6 +1,5 @@ CONFIG_SHELL=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IEEE802154=y CONFIG_NETWORKING=y diff --git a/tests/subsys/pm/device_driver_init/prj.conf b/tests/subsys/pm/device_driver_init/prj.conf index e6d05f591ac..a911722adb1 100644 --- a/tests/subsys/pm/device_driver_init/prj.conf +++ b/tests/subsys/pm/device_driver_init/prj.conf @@ -6,4 +6,3 @@ CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_GPIO=y CONFIG_GPIO_GET_CONFIG=y CONFIG_POWER_DOMAIN=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/device_power_domains/prj.conf b/tests/subsys/pm/device_power_domains/prj.conf index 967291a394d..e003169ea99 100644 --- a/tests/subsys/pm/device_power_domains/prj.conf +++ b/tests/subsys/pm/device_power_domains/prj.conf @@ -9,4 +9,3 @@ CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_GPIO=y CONFIG_POWER_DOMAIN=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/device_runtime_api/prj.conf b/tests/subsys/pm/device_runtime_api/prj.conf index 99fb0f9e62e..5708c297e9d 100644 --- a/tests/subsys/pm/device_runtime_api/prj.conf +++ b/tests/subsys/pm/device_runtime_api/prj.conf @@ -3,4 +3,3 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/device_wakeup_api/prj.conf b/tests/subsys/pm/device_wakeup_api/prj.conf index 15d773b235b..edd5b915dd8 100644 --- a/tests/subsys/pm/device_wakeup_api/prj.conf +++ b/tests/subsys/pm/device_wakeup_api/prj.conf @@ -4,4 +4,3 @@ CONFIG_PM=y CONFIG_PM_POLICY_CUSTOM=y CONFIG_GPIO=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/policy_api/prj.conf b/tests/subsys/pm/policy_api/prj.conf index 7cf9b06a2c2..cf84b4d2dd4 100644 --- a/tests/subsys/pm/policy_api/prj.conf +++ b/tests/subsys/pm/policy_api/prj.conf @@ -3,4 +3,3 @@ CONFIG_ZTEST=y CONFIG_PM=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/power_domain/prj.conf b/tests/subsys/pm/power_domain/prj.conf index a6880b99dfc..06b480e7ecb 100644 --- a/tests/subsys/pm/power_domain/prj.conf +++ b/tests/subsys/pm/power_domain/prj.conf @@ -7,4 +7,3 @@ CONFIG_POWER_DOMAIN=y CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC=y CONFIG_PM_DEVICE_RUNTIME=y CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/power_mgmt/prj.conf b/tests/subsys/pm/power_mgmt/prj.conf index 3dbc21b5b56..81edc8f7e26 100644 --- a/tests/subsys/pm/power_mgmt/prj.conf +++ b/tests/subsys/pm/power_mgmt/prj.conf @@ -5,4 +5,3 @@ CONFIG_PM_DEVICE_RUNTIME=y CONFIG_PM_POLICY_CUSTOM=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/power_mgmt_multicore/prj.conf b/tests/subsys/pm/power_mgmt_multicore/prj.conf index 6a259c68bbe..f0b806ca389 100644 --- a/tests/subsys/pm/power_mgmt_multicore/prj.conf +++ b/tests/subsys/pm/power_mgmt_multicore/prj.conf @@ -2,4 +2,3 @@ CONFIG_ZTEST=y CONFIG_PM=y CONFIG_PM_POLICY_CUSTOM=y CONFIG_MP_MAX_NUM_CPUS=2 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/power_mgmt_soc/prj.conf b/tests/subsys/pm/power_mgmt_soc/prj.conf index 278c555ad07..bb30385a3df 100644 --- a/tests/subsys/pm/power_mgmt_soc/prj.conf +++ b/tests/subsys/pm/power_mgmt_soc/prj.conf @@ -5,4 +5,3 @@ CONFIG_THREAD_NAME=y CONFIG_STATS=y CONFIG_PM_STATS=y CONFIG_IDLE_STACK_SIZE=640 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/power_states_api/prj.conf b/tests/subsys/pm/power_states_api/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/subsys/pm/power_states_api/prj.conf +++ b/tests/subsys/pm/power_states_api/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/portability/cmsis_rtos_v1/prj.conf b/tests/subsys/portability/cmsis_rtos_v1/prj.conf index 4a0cb1c2a20..f08e6d07ca4 100644 --- a/tests/subsys/portability/cmsis_rtos_v1/prj.conf +++ b/tests/subsys/portability/cmsis_rtos_v1/prj.conf @@ -7,4 +7,3 @@ CONFIG_IRQ_OFFLOAD=y CONFIG_CMSIS_THREAD_MAX_STACK_SIZE=2048 CONFIG_SMP=n CONFIG_THREAD_STACK_INFO=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/portability/cmsis_rtos_v2/prj.conf b/tests/subsys/portability/cmsis_rtos_v2/prj.conf index 8df8cf48aba..282d8c4ebcd 100644 --- a/tests/subsys/portability/cmsis_rtos_v2/prj.conf +++ b/tests/subsys/portability/cmsis_rtos_v2/prj.conf @@ -17,4 +17,3 @@ CONFIG_TIMEOUT_64BIT=n CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE=1024 CONFIG_CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE=1024 CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/rtio/rtio_api/prj.conf b/tests/subsys/rtio/rtio_api/prj.conf index babe8800f3a..b19c123d100 100644 --- a/tests/subsys/rtio/rtio_api/prj.conf +++ b/tests/subsys/rtio/rtio_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_RTIO=y CONFIG_RTIO_SYS_MEM_BLOCKS=y diff --git a/tests/subsys/sd/mmc/prj.conf b/tests/subsys/sd/mmc/prj.conf index 9f06d497b52..fbd9f184dbf 100644 --- a/tests/subsys/sd/mmc/prj.conf +++ b/tests/subsys/sd/mmc/prj.conf @@ -2,4 +2,3 @@ CONFIG_TEST=y CONFIG_ZTEST=y CONFIG_MMC_STACK=y CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/sd/sdmmc/prj.conf b/tests/subsys/sd/sdmmc/prj.conf index 186a5632a62..b5c81cd5aaf 100644 --- a/tests/subsys/sd/sdmmc/prj.conf +++ b/tests/subsys/sd/sdmmc/prj.conf @@ -2,4 +2,3 @@ CONFIG_TEST=y CONFIG_ZTEST=y CONFIG_SDMMC_STACK=y CONFIG_LOG=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/settings/fcb/prj.conf b/tests/subsys/settings/fcb/prj.conf index 67d8855910e..c0091de22ed 100644 --- a/tests/subsys/settings/fcb/prj.conf +++ b/tests/subsys/settings/fcb/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_FLASH=y diff --git a/tests/subsys/settings/fcb_init/prj.conf b/tests/subsys/settings/fcb_init/prj.conf index 68c33bdc68c..46c1ab88ff3 100644 --- a/tests/subsys/settings/fcb_init/prj.conf +++ b/tests/subsys/settings/fcb_init/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/settings/file/prj.conf b/tests/subsys/settings/file/prj.conf index 425f48aaf6b..07e79b3233e 100644 --- a/tests/subsys/settings/file/prj.conf +++ b/tests/subsys/settings/file/prj.conf @@ -2,7 +2,6 @@ # Copyright (c) 2019 Nordic Semiconductor ASA CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/settings/functional/fcb/prj.conf b/tests/subsys/settings/functional/fcb/prj.conf index f6a8bd83ff5..795a225d7fd 100644 --- a/tests/subsys/settings/functional/fcb/prj.conf +++ b/tests/subsys/settings/functional/fcb/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/settings/functional/file/prj.conf b/tests/subsys/settings/functional/file/prj.conf index ed4862e065d..fe506f01d99 100644 --- a/tests/subsys/settings/functional/file/prj.conf +++ b/tests/subsys/settings/functional/file/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_FLASH=y diff --git a/tests/subsys/settings/functional/nvs/prj.conf b/tests/subsys/settings/functional/nvs/prj.conf index 75036ef6953..2466686f555 100644 --- a/tests/subsys/settings/functional/nvs/prj.conf +++ b/tests/subsys/settings/functional/nvs/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/settings/nvs/prj.conf b/tests/subsys/settings/nvs/prj.conf index 75036ef6953..2466686f555 100644 --- a/tests/subsys/settings/nvs/prj.conf +++ b/tests/subsys/settings/nvs/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y diff --git a/tests/subsys/shell/shell/prj.conf b/tests/subsys/shell/shell/prj.conf index e6e92e28185..e254a3bc4ca 100644 --- a/tests/subsys/shell/shell/prj.conf +++ b/tests/subsys/shell/shell/prj.conf @@ -8,4 +8,3 @@ CONFIG_SHELL_METAKEYS=n CONFIG_LOG=n CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/shell/shell/shell_min.conf b/tests/subsys/shell/shell/shell_min.conf index 2fa40eb9ee0..8b5c618e02c 100644 --- a/tests/subsys/shell/shell/shell_min.conf +++ b/tests/subsys/shell/shell/shell_min.conf @@ -12,4 +12,3 @@ CONFIG_LOG=n CONFIG_THREAD_MONITOR=n CONFIG_INIT_STACKS=y CONFIG_BOOT_BANNER=n -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/shell/shell/shell_min_cmds.conf b/tests/subsys/shell/shell/shell_min_cmds.conf index da3364238ad..351b6fb4e60 100644 --- a/tests/subsys/shell/shell/shell_min_cmds.conf +++ b/tests/subsys/shell/shell/shell_min_cmds.conf @@ -6,7 +6,6 @@ CONFIG_SHELL_BACKEND_DUMMY=y CONFIG_SHELL_BACKEND_SERIAL=n CONFIG_THREAD_NAME=y CONFIG_SHELL_STACK_SIZE=2048 -CONFIG_ZTEST_NEW_API=y #using CBPRINTF_NANO decreases significantly Flash usage. CONFIG_CBPRINTF_NANO=y diff --git a/tests/subsys/shell/shell/shell_min_cmds_all.conf b/tests/subsys/shell/shell/shell_min_cmds_all.conf index 957320695ad..f81b9abd6f0 100644 --- a/tests/subsys/shell/shell/shell_min_cmds_all.conf +++ b/tests/subsys/shell/shell/shell_min_cmds_all.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_cmds_resize.conf b/tests/subsys/shell/shell/shell_min_cmds_resize.conf index 35e1fc3086f..2ab8fdbe521 100644 --- a/tests/subsys/shell/shell/shell_min_cmds_resize.conf +++ b/tests/subsys/shell/shell/shell_min_cmds_resize.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_cmds_select.conf b/tests/subsys/shell/shell/shell_min_cmds_select.conf index 71a7e8e36d6..ae4f9b5ea7a 100644 --- a/tests/subsys/shell/shell/shell_min_cmds_select.conf +++ b/tests/subsys/shell/shell/shell_min_cmds_select.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_colors.conf b/tests/subsys/shell/shell/shell_min_colors.conf index 8b0777f7c09..3281032781f 100644 --- a/tests/subsys/shell/shell/shell_min_colors.conf +++ b/tests/subsys/shell/shell/shell_min_colors.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_help.conf b/tests/subsys/shell/shell/shell_min_help.conf index 345755a08fc..1e10b709b34 100644 --- a/tests/subsys/shell/shell/shell_min_help.conf +++ b/tests/subsys/shell/shell/shell_min_help.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_help_all.conf b/tests/subsys/shell/shell/shell_min_help_all.conf index d67faeecf40..d2c1802e263 100644 --- a/tests/subsys/shell/shell/shell_min_help_all.conf +++ b/tests/subsys/shell/shell/shell_min_help_all.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_history.conf b/tests/subsys/shell/shell/shell_min_history.conf index 46e6b188b7e..03ad3188414 100644 --- a/tests/subsys/shell/shell/shell_min_history.conf +++ b/tests/subsys/shell/shell/shell_min_history.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_log_backend.conf b/tests/subsys/shell/shell/shell_min_log_backend.conf index 918085c37b7..2dfaac9a9dc 100644 --- a/tests/subsys/shell/shell/shell_min_log_backend.conf +++ b/tests/subsys/shell/shell/shell_min_log_backend.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_metakeys.conf b/tests/subsys/shell/shell/shell_min_metakeys.conf index 3eb36ab96be..5141e01d971 100644 --- a/tests/subsys/shell/shell/shell_min_metakeys.conf +++ b/tests/subsys/shell/shell/shell_min_metakeys.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_tab.conf b/tests/subsys/shell/shell/shell_min_tab.conf index 8a459f0e2d7..b265e191869 100644 --- a/tests/subsys/shell/shell/shell_min_tab.conf +++ b/tests/subsys/shell/shell/shell_min_tab.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_tab_auto.conf b/tests/subsys/shell/shell/shell_min_tab_auto.conf index 90d731fcb56..4bac7c7b6fa 100644 --- a/tests/subsys/shell/shell/shell_min_tab_auto.conf +++ b/tests/subsys/shell/shell/shell_min_tab_auto.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell/shell_min_wildcards.conf b/tests/subsys/shell/shell/shell_min_wildcards.conf index 29352b41671..e3fb21bd726 100644 --- a/tests/subsys/shell/shell/shell_min_wildcards.conf +++ b/tests/subsys/shell/shell/shell_min_wildcards.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_TEST_LOGGING_DEFAULTS=n -CONFIG_ZTEST_NEW_API=y CONFIG_SHELL=y CONFIG_SHELL_MINIMAL=y diff --git a/tests/subsys/shell/shell_flash/prj.conf b/tests/subsys/shell/shell_flash/prj.conf index 5d68b90f48a..c78ce7b6143 100644 --- a/tests/subsys/shell/shell_flash/prj.conf +++ b/tests/subsys/shell/shell_flash/prj.conf @@ -9,4 +9,3 @@ CONFIG_SHELL_PRINTF_BUFF_SIZE=15 CONFIG_SHELL_METAKEYS=n CONFIG_LOG=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/shell/shell_history/prj.conf b/tests/subsys/shell/shell_history/prj.conf index 79a361c4dc9..dd6a985d9bc 100644 --- a/tests/subsys/shell/shell_history/prj.conf +++ b/tests/subsys/shell/shell_history/prj.conf @@ -7,4 +7,3 @@ CONFIG_SHELL_METAKEYS=n CONFIG_SHELL_HISTORY=y CONFIG_LOG=n CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/sip_svc/prj.conf b/tests/subsys/sip_svc/prj.conf index 61be5b51966..323ada791c3 100644 --- a/tests/subsys/sip_svc/prj.conf +++ b/tests/subsys/sip_svc/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_ZTRESS_MAX_THREADS=16 CONFIG_NUM_PREEMPT_PRIORITIES=18 diff --git a/tests/subsys/storage/flash_map/prj.conf b/tests/subsys/storage/flash_map/prj.conf index f69cc81cd7a..fb9e5a0fd26 100644 --- a/tests/subsys/storage/flash_map/prj.conf +++ b/tests/subsys/storage/flash_map/prj.conf @@ -3,4 +3,3 @@ CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y CONFIG_FLASH_AREA_CHECK_INTEGRITY=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/storage/stream/stream_flash/prj.conf b/tests/subsys/storage/stream/stream_flash/prj.conf index 46737eefa75..6e5811b8fdc 100644 --- a/tests/subsys/storage/stream/stream_flash/prj.conf +++ b/tests/subsys/storage/stream/stream_flash/prj.conf @@ -14,4 +14,3 @@ CONFIG_SETTINGS=y CONFIG_STREAM_FLASH=y CONFIG_STREAM_FLASH_ERASE=y CONFIG_STREAM_FLASH_PROGRESS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/testsuite/fff_fake_contexts/prj.conf b/tests/subsys/testsuite/fff_fake_contexts/prj.conf index b79d06d0c64..2dea28a5282 100644 --- a/tests/subsys/testsuite/fff_fake_contexts/prj.conf +++ b/tests/subsys/testsuite/fff_fake_contexts/prj.conf @@ -2,4 +2,3 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/tracing/tracing_api/prj.conf b/tests/subsys/tracing/tracing_api/prj.conf index cbdf717f9b9..af5be66675f 100644 --- a/tests/subsys/tracing/tracing_api/prj.conf +++ b/tests/subsys/tracing/tracing_api/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TRACING=y CONFIG_TRACING_TEST=y CONFIG_TRACING_BACKEND_UART=y diff --git a/tests/subsys/usb/bos/prj.conf b/tests/subsys/usb/bos/prj.conf index 41f0df927f0..147852c73ea 100644 --- a/tests/subsys/usb/bos/prj.conf +++ b/tests/subsys/usb/bos/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_BOS=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/usb/desc_sections/prj.conf b/tests/subsys/usb/desc_sections/prj.conf index a7265e4f03c..07dbb1512d0 100644 --- a/tests/subsys/usb/desc_sections/prj.conf +++ b/tests/subsys/usb/desc_sections/prj.conf @@ -4,4 +4,3 @@ CONFIG_USB_DEVICE_LOG_LEVEL_DBG=y CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=4096 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/usb/device/prj.conf b/tests/subsys/usb/device/prj.conf index f40596f6d9f..26a6935756d 100644 --- a/tests/subsys/usb/device/prj.conf +++ b/tests/subsys/usb/device/prj.conf @@ -5,4 +5,3 @@ CONFIG_USB_DEVICE_LOG_LEVEL_DBG=y CONFIG_USB_DRIVER_LOG_LEVEL_DBG=y CONFIG_USB_DEVICE_STACK=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/usb/device_next/prj.conf b/tests/subsys/usb/device_next/prj.conf index 6025cf69cd5..54321edc952 100644 --- a/tests/subsys/usb/device_next/prj.conf +++ b/tests/subsys/usb/device_next/prj.conf @@ -3,7 +3,6 @@ CONFIG_LOG=y CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USBD_LOOPBACK_CLASS=y diff --git a/tests/subsys/usb/os_desc/prj.conf b/tests/subsys/usb/os_desc/prj.conf index edc74ced85f..508f4a0dd7f 100644 --- a/tests/subsys/usb/os_desc/prj.conf +++ b/tests/subsys/usb/os_desc/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_OS_DESC=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/zbus/dyn_channel/prj.conf b/tests/subsys/zbus/dyn_channel/prj.conf index fcb4160678f..86b0b96dd38 100644 --- a/tests/subsys/zbus/dyn_channel/prj.conf +++ b/tests/subsys/zbus/dyn_channel/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_LOG=y CONFIG_HEAP_MEM_POOL_SIZE=256 diff --git a/tests/subsys/zbus/integration/prj.conf b/tests/subsys/zbus/integration/prj.conf index 72f1d956e1e..c911616e2db 100644 --- a/tests/subsys/zbus/integration/prj.conf +++ b/tests/subsys/zbus/integration/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=n CONFIG_LOG=y CONFIG_ZBUS=y diff --git a/tests/subsys/zbus/runtime_observers_registration/prj.conf b/tests/subsys/zbus/runtime_observers_registration/prj.conf index 6f074e22a27..741938a265c 100644 --- a/tests/subsys/zbus/runtime_observers_registration/prj.conf +++ b/tests/subsys/zbus/runtime_observers_registration/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ZBUS=y CONFIG_ZBUS_ASSERT_MOCK=y diff --git a/tests/subsys/zbus/unittests/prj.conf b/tests/subsys/zbus/unittests/prj.conf index db4fd92b3b9..c6d0cbd6068 100644 --- a/tests/subsys/zbus/unittests/prj.conf +++ b/tests/subsys/zbus/unittests/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_LOG=y CONFIG_ZBUS=y diff --git a/tests/subsys/zbus/user_data/prj.conf b/tests/subsys/zbus/user_data/prj.conf index 5e78e1b452e..63a89fccd8d 100644 --- a/tests/subsys/zbus/user_data/prj.conf +++ b/tests/subsys/zbus/user_data/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ASSERT=y CONFIG_LOG=y CONFIG_ZBUS=y diff --git a/tests/unit/base64/prj.conf b/tests/unit/base64/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/base64/prj.conf +++ b/tests/unit/base64/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/cbprintf/prj.conf b/tests/unit/cbprintf/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/cbprintf/prj.conf +++ b/tests/unit/cbprintf/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/crc/prj.conf b/tests/unit/crc/prj.conf index fd4e42e2deb..3f282dbf061 100644 --- a/tests/unit/crc/prj.conf +++ b/tests/unit/crc/prj.conf @@ -1,2 +1 @@ -CONFIG_ZTEST_NEW_API=y CONFIG_CRC=y diff --git a/tests/unit/intmath/prj.conf b/tests/unit/intmath/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/intmath/prj.conf +++ b/tests/unit/intmath/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/list/prj.conf b/tests/unit/list/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/unit/list/prj.conf +++ b/tests/unit/list/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/unit/math_extras/prj.conf b/tests/unit/math_extras/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/math_extras/prj.conf +++ b/tests/unit/math_extras/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/net_timeout/prj.conf b/tests/unit/net_timeout/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/net_timeout/prj.conf +++ b/tests/unit/net_timeout/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/pot/prj.conf b/tests/unit/pot/prj.conf index 0d91a89b0ef..3aff91ca987 100644 --- a/tests/unit/pot/prj.conf +++ b/tests/unit/pot/prj.conf @@ -2,4 +2,3 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/unit/rbtree/prj.conf b/tests/unit/rbtree/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/unit/rbtree/prj.conf +++ b/tests/unit/rbtree/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/unit/time_units/prj.conf b/tests/unit/time_units/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/unit/time_units/prj.conf +++ b/tests/unit/time_units/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/unit/timeutil/prj.conf b/tests/unit/timeutil/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/timeutil/prj.conf +++ b/tests/unit/timeutil/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/util/prj.conf b/tests/unit/util/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/util/prj.conf +++ b/tests/unit/util/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/unit/winstream/prj.conf b/tests/unit/winstream/prj.conf index 963087265ce..9467c292689 100644 --- a/tests/unit/winstream/prj.conf +++ b/tests/unit/winstream/prj.conf @@ -1 +1 @@ -CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST=y diff --git a/tests/ztest/base/prj.conf b/tests/ztest/base/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/ztest/base/prj.conf +++ b/tests/ztest/base/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/ztest/base/prj_cpp.conf b/tests/ztest/base/prj_cpp.conf index 34f5b636a52..de04b5070db 100644 --- a/tests/ztest/base/prj_cpp.conf +++ b/tests/ztest/base/prj_cpp.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CPP=y diff --git a/tests/ztest/base/prj_verbose_0.conf b/tests/ztest/base/prj_verbose_0.conf index 4f00bd038ad..4a5ace8ad17 100644 --- a/tests/ztest/base/prj_verbose_0.conf +++ b/tests/ztest/base/prj_verbose_0.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_ASSERT_VERBOSE=0 CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/ztest/base/prj_verbose_1.conf b/tests/ztest/base/prj_verbose_1.conf index b92787f41c7..885394fe918 100644 --- a/tests/ztest/base/prj_verbose_1.conf +++ b/tests/ztest/base/prj_verbose_1.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_ASSERT_VERBOSE=1 CONFIG_ZTEST_SHUFFLE=y diff --git a/tests/ztest/base/prj_verbose_2.conf b/tests/ztest/base/prj_verbose_2.conf index c995cf19ee0..0bda78a5b4f 100644 --- a/tests/ztest/base/prj_verbose_2.conf +++ b/tests/ztest/base/prj_verbose_2.conf @@ -1,3 +1,2 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTEST_ASSERT_VERBOSE=2 diff --git a/tests/ztest/busy_sim/prj.conf b/tests/ztest/busy_sim/prj.conf index dc4e8293d29..c06383cada1 100644 --- a/tests/ztest/busy_sim/prj.conf +++ b/tests/ztest/busy_sim/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y CONFIG_TEST_BUSY_SIM=y CONFIG_ZTEST_THREAD_PRIORITY=1 -CONFIG_ZTEST_NEW_API=y diff --git a/tests/ztest/error_hook/prj.conf b/tests/ztest/error_hook/prj.conf index 421acadbe89..f0981ce3547 100644 --- a/tests/ztest/error_hook/prj.conf +++ b/tests/ztest/error_hook/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_TEST_USERSPACE=y CONFIG_IRQ_OFFLOAD=y CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/ztest/error_hook/prj_no_userspace.conf b/tests/ztest/error_hook/prj_no_userspace.conf index 7bdd8519046..b76cc814b07 100644 --- a/tests/ztest/error_hook/prj_no_userspace.conf +++ b/tests/ztest/error_hook/prj_no_userspace.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_IRQ_OFFLOAD=y CONFIG_ZTEST_FATAL_HOOK=y CONFIG_ZTEST_ASSERT_HOOK=y diff --git a/tests/ztest/fail/core/prj.conf b/tests/ztest/fail/core/prj.conf index 3538526b3a7..84d6dc0cff5 100644 --- a/tests/ztest/fail/core/prj.conf +++ b/tests/ztest/fail/core/prj.conf @@ -2,6 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CPP=y diff --git a/tests/ztest/fail/prj.conf b/tests/ztest/fail/prj.conf index b10ffd701c3..cba949460e6 100644 --- a/tests/ztest/fail/prj.conf +++ b/tests/ztest/fail/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_CPP=y CONFIG_EXTERNAL_LIBCPP=y diff --git a/tests/ztest/summary/prj.conf b/tests/ztest/summary/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/ztest/summary/prj.conf +++ b/tests/ztest/summary/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/ztest/zexpect/prj.conf b/tests/ztest/zexpect/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/ztest/zexpect/prj.conf +++ b/tests/ztest/zexpect/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/ztest/ztress/prj.conf b/tests/ztest/ztress/prj.conf index 7a560bc7187..219719d0fd6 100644 --- a/tests/ztest/ztress/prj.conf +++ b/tests/ztest/ztress/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_ZTRESS_MAX_THREADS=3 CONFIG_TEST_EXTRA_STACK_SIZE=2048 From e77a65969843a3653d6ec7d0983b69b1243ca95b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 9 Oct 2023 23:36:18 +0000 Subject: [PATCH 2215/4498] cmsis_dsp: remove handling of old ztest API Old ztest API is deprecated, so no need for the conditional code here. Signed-off-by: Anas Nashif --- tests/lib/cmsis_dsp/common/test_common.h | 44 ------------------------ 1 file changed, 44 deletions(-) diff --git a/tests/lib/cmsis_dsp/common/test_common.h b/tests/lib/cmsis_dsp/common/test_common.h index 033245ab812..f65637ac93b 100644 --- a/tests/lib/cmsis_dsp/common/test_common.h +++ b/tests/lib/cmsis_dsp/common/test_common.h @@ -26,7 +26,6 @@ #define ASSERT_MSG_ERROR_LIMIT_EXCEED "error limit exceeded" #define ASSERT_MSG_INCORRECT_COMP_RESULT "incorrect computation result" -#if defined(CONFIG_ZTEST_NEW_API) #define DEFINE_TEST_VARIANT1(suite, name, variant, a1) \ ZTEST(suite, test_##name##_##variant) \ { \ @@ -68,49 +67,6 @@ { \ test_##name(a1, a2, a3, a4, a5, a6, a7); \ } -#else /* !defined(CONFIG_ZTEST_NEW_API) */ -#define DEFINE_TEST_VARIANT1(name, variant, a1) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1); \ - } - -#define DEFINE_TEST_VARIANT2(name, variant, a1, a2) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2); \ - } - -#define DEFINE_TEST_VARIANT3(name, variant, a1, a2, a3) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2, a3); \ - } - -#define DEFINE_TEST_VARIANT4(name, variant, a1, a2, a3, a4) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2, a3, a4); \ - } - -#define DEFINE_TEST_VARIANT5(name, variant, a1, a2, a3, a4, a5) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2, a3, a4, a5); \ - } - -#define DEFINE_TEST_VARIANT6(name, variant, a1, a2, a3, a4, a5, a6) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2, a3, a4, a5, a6); \ - } - -#define DEFINE_TEST_VARIANT7(name, variant, a1, a2, a3, a4, a5, a6, a7) \ - static void test_##name##_##variant(void) \ - { \ - test_##name(a1, a2, a3, a4, a5, a6, a7); \ - } -#endif /* !defined(CONFIG_ZTEST_NEW_API) */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" From f067bc43c9a797cd47c256f46e9752f2ba539110 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 9 Oct 2023 23:36:42 +0000 Subject: [PATCH 2216/4498] tests: sensor: do not depend on ZTEST_NEW_API Old ztest API is deprecated, so no need for the conditional code here. Signed-off-by: Anas Nashif --- tests/drivers/build_all/sensor/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/build_all/sensor/Kconfig b/tests/drivers/build_all/sensor/Kconfig index 10730a1f50b..439e70051cb 100644 --- a/tests/drivers/build_all/sensor/Kconfig +++ b/tests/drivers/build_all/sensor/Kconfig @@ -3,7 +3,7 @@ config GENERIC_SENSOR_TEST bool "Compile and run the generic sensor tests" - depends on ZTEST && ZTEST_NEW_API + depends on ZTEST help Enables building and running the generic sensor test suite that will iterate through the device tree and run sample path tests on any From 85c4703a468ba1307978190b1f9ceaa3b1e3bc6e Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 9 Oct 2023 23:39:26 +0000 Subject: [PATCH 2217/4498] drivers: fake: now just check for CONFIG_ZTEST Old ztest API is deprecated, so only check for CONFIG_ZTEST. Signed-off-by: Anas Nashif --- drivers/can/can_fake.c | 8 ++++---- drivers/eeprom/eeprom_fake.c | 8 ++++---- drivers/rtc/rtc_fake.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/can/can_fake.c b/drivers/can/can_fake.c index cdc2fd34a86..88d7780eaad 100644 --- a/drivers/can/can_fake.c +++ b/drivers/can/can_fake.c @@ -9,9 +9,9 @@ #include #include -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST #include -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ #define DT_DRV_COMPAT zephyr_fake_can @@ -46,7 +46,7 @@ DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *, DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool); -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture) { ARG_UNUSED(test); @@ -68,7 +68,7 @@ static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void } ZTEST_RULE(fake_can_reset_rule, fake_can_reset_rule_before, NULL); -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ static int fake_can_get_core_clock(const struct device *dev, uint32_t *rate) { diff --git a/drivers/eeprom/eeprom_fake.c b/drivers/eeprom/eeprom_fake.c index c7ed9ff5cd4..f925671fba8 100644 --- a/drivers/eeprom/eeprom_fake.c +++ b/drivers/eeprom/eeprom_fake.c @@ -9,9 +9,9 @@ #include #include -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST #include -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ #define DT_DRV_COMPAT zephyr_fake_eeprom @@ -32,7 +32,7 @@ size_t fake_eeprom_size_delegate(const struct device *dev) return config->size; } -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST static void fake_eeprom_reset_rule_before(const struct ztest_unit_test *test, void *fixture) { ARG_UNUSED(test); @@ -47,7 +47,7 @@ static void fake_eeprom_reset_rule_before(const struct ztest_unit_test *test, vo } ZTEST_RULE(fake_eeprom_reset_rule, fake_eeprom_reset_rule_before, NULL); -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ static const struct eeprom_driver_api fake_eeprom_driver_api = { .read = fake_eeprom_read, diff --git a/drivers/rtc/rtc_fake.c b/drivers/rtc/rtc_fake.c index 86d66ebd5f8..3a96da7141d 100644 --- a/drivers/rtc/rtc_fake.c +++ b/drivers/rtc/rtc_fake.c @@ -11,9 +11,9 @@ #include #include -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST #include -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ DEFINE_FAKE_VALUE_FUNC(int, rtc_fake_set_time, const struct device *, const struct rtc_time *); DEFINE_FAKE_VALUE_FUNC(int, rtc_fake_get_time, const struct device *, struct rtc_time *); @@ -40,7 +40,7 @@ DEFINE_FAKE_VALUE_FUNC(int, rtc_fake_set_calibration, const struct device *, int DEFINE_FAKE_VALUE_FUNC(int, rtc_fake_get_calibration, const struct device *, int32_t *); #endif /* CONFIG_RTC_CALIBRATION */ -#ifdef CONFIG_ZTEST_NEW_API +#ifdef CONFIG_ZTEST static void fake_rtc_reset_rule_before(const struct ztest_unit_test *test, void *fixture) { ARG_UNUSED(test); @@ -68,7 +68,7 @@ static void fake_rtc_reset_rule_before(const struct ztest_unit_test *test, void } ZTEST_RULE(fake_rtc_reset_rule, fake_rtc_reset_rule_before, NULL); -#endif /* CONFIG_ZTEST_NEW_API */ +#endif /* CONFIG_ZTEST */ struct rtc_driver_api rtc_fake_driver_api = { .set_time = rtc_fake_set_time, From 996c8457d76fc9e229dfa0d7f2cf717bdc35d39a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 00:06:05 +0000 Subject: [PATCH 2218/4498] ztest: remove old ztest api Remove old Ztest API entirely. New API is the now the default. Signed-off-by: Anas Nashif --- cmake/linker_script/common/common-ram.cmake | 3 - cmake/modules/unittest.cmake | 19 +- scripts/build/gen_kobject_list.py | 4 +- subsys/logging/Kconfig.processing | 2 +- subsys/testsuite/include/zephyr/tc_util.h | 15 - subsys/testsuite/ztest/CMakeLists.txt | 14 +- subsys/testsuite/ztest/Kconfig | 13 +- .../ztest/include/zephyr/ztest_test.h | 551 +++++++++- .../include/zephyr/ztest_test_deprecated.h | 296 ------ .../ztest/include/zephyr/ztest_test_new.h | 560 ---------- subsys/testsuite/ztest/src/ztest.c | 959 ++++++++++++++---- subsys/testsuite/ztest/src/ztest_posix.c | 8 +- .../hci_uart_async/src/test_hci_uart_async.c | 2 +- .../kernel/spinlock/src/spinlock_error_case.c | 2 +- tests/subsys/emul/src/main.c | 2 +- 15 files changed, 1324 insertions(+), 1126 deletions(-) delete mode 100644 subsys/testsuite/ztest/include/zephyr/ztest_test_deprecated.h delete mode 100644 subsys/testsuite/ztest/include/zephyr/ztest_test_new.h diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index 9c051477d10..a116977ce8c 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -94,9 +94,6 @@ endif() if(CONFIG_ZTEST) zephyr_iterable_section(NAME ztest_suite_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME ztest_suite_stats GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) -endif() - -if(CONFIG_ZTEST_NEW_API) zephyr_iterable_section(NAME ztest_unit_test GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME ztest_test_rule GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME ztest_expected_result_entry GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) diff --git a/cmake/modules/unittest.cmake b/cmake/modules/unittest.cmake index be5fa56741a..306cc879585 100644 --- a/cmake/modules/unittest.cmake +++ b/cmake/modules/unittest.cmake @@ -103,19 +103,12 @@ if(LIBS) message(FATAL_ERROR "This variable is not supported, see SOURCES instead") endif() -if(CONFIG_ZTEST_NEW_API) - target_sources(testbinary PRIVATE - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_new.c - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_mock.c - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_rules.c - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_defaults.c - ) -else() - target_sources(testbinary PRIVATE - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest.c - ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_mock.c - ) -endif() +target_sources(testbinary PRIVATE + ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest.c + ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_mock.c + ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_rules.c + ${ZEPHYR_BASE}/subsys/testsuite/ztest/src/ztest_defaults.c +) target_compile_definitions(test_interface INTERFACE ZTEST_UNITTEST) diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index 64524c67499..420d96485d4 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -110,8 +110,8 @@ ("k_event", ("CONFIG_EVENTS", False, True)), ("ztest_suite_node", ("CONFIG_ZTEST", True, False)), ("ztest_suite_stats", ("CONFIG_ZTEST", True, False)), - ("ztest_unit_test", ("CONFIG_ZTEST_NEW_API", True, False)), - ("ztest_test_rule", ("CONFIG_ZTEST_NEW_API", True, False)), + ("ztest_unit_test", ("CONFIG_ZTEST", True, False)), + ("ztest_test_rule", ("CONFIG_ZTEST", True, False)), ("rtio", ("CONFIG_RTIO", False, False)), ("rtio_iodev", ("CONFIG_RTIO", False, False)), ("sensor_decoder_api", ("CONFIG_SENSOR_ASYNC_API", True, False)) diff --git a/subsys/logging/Kconfig.processing b/subsys/logging/Kconfig.processing index a1d7c955d40..9051b6e3b46 100644 --- a/subsys/logging/Kconfig.processing +++ b/subsys/logging/Kconfig.processing @@ -7,7 +7,7 @@ if !LOG_MODE_MINIMAL config LOG_PRINTK bool "Process printk messages" - default y if PRINTK && (!ZTEST || ZTEST_NEW_API) + default y if PRINTK help If enabled, printk messages are redirected to the logging subsystem. The messages are formatted in place and logged unconditionally. diff --git a/subsys/testsuite/include/zephyr/tc_util.h b/subsys/testsuite/include/zephyr/tc_util.h index 69c9359b50f..ea7ed98c8c7 100644 --- a/subsys/testsuite/include/zephyr/tc_util.h +++ b/subsys/testsuite/include/zephyr/tc_util.h @@ -127,18 +127,11 @@ static inline void print_nothing(const char *fmt, ...) } #ifndef TC_PRINT -/* Need to check for CONFIG_ZTEST_NEW_API since the TC_PRINT - * is also used by the old ztest. - */ -#ifdef CONFIG_ZTEST_NEW_API #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT) #define TC_PRINT(fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__) #else #define TC_PRINT(fmt, ...) print_nothing(fmt, ##__VA_ARGS__) #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */ -#else -#define TC_PRINT(fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__) -#endif /* CONFIG_ZTEST_NEW_API */ #endif /* TC_PRINT */ #ifndef TC_SUMMARY_PRINT @@ -146,15 +139,11 @@ static inline void print_nothing(const char *fmt, ...) #endif #ifndef TC_START_PRINT -#ifdef CONFIG_ZTEST_NEW_API #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT) #define TC_START_PRINT(name) PRINT_DATA("START - %s\n", name); #else #define TC_START_PRINT(name) print_nothing(name) #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */ -#else -#define TC_START_PRINT(name) PRINT_DATA("START - %s\n", name); -#endif /* CONFIG_ZTEST_NEW_API */ #endif /* TC_START_PRINT */ #ifndef TC_START @@ -169,15 +158,11 @@ static inline void print_nothing(const char *fmt, ...) #endif #ifndef TC_END_PRINT -#ifdef CONFIG_ZTEST_NEW_API #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT) #define TC_END_PRINT(result, fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__); PRINT_LINE #else #define TC_END_PRINT(result, fmt, ...) print_nothing(fmt) #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */ -#else -#define TC_END_PRINT(result, fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__); PRINT_LINE -#endif /* CONFIG_ZTEST_NEW_API */ #endif /* TC_END_PRINT */ /* prints result and the function name */ diff --git a/subsys/testsuite/ztest/CMakeLists.txt b/subsys/testsuite/ztest/CMakeLists.txt index c9c93328985..7817bc2f30b 100644 --- a/subsys/testsuite/ztest/CMakeLists.txt +++ b/subsys/testsuite/ztest/CMakeLists.txt @@ -3,7 +3,6 @@ zephyr_syscall_header( ${ZEPHYR_BASE}/subsys/testsuite/ztest/include/zephyr/ztest_error_hook.h ${ZEPHYR_BASE}/subsys/testsuite/ztest/include/zephyr/ztest_test.h - ${ZEPHYR_BASE}/subsys/testsuite/ztest/include/zephyr/ztest_test_new.h ) zephyr_include_directories( @@ -16,16 +15,17 @@ if(DEFINED TC_RUNID) endif() zephyr_library() -zephyr_library_sources_ifndef(CONFIG_ZTEST_NEW_API src/ztest.c) -zephyr_library_sources_ifdef(CONFIG_ZTEST_NEW_API src/ztest_new.c) -zephyr_library_sources( src/ztest_error_hook.c) -zephyr_library_sources_ifdef(CONFIG_ZTEST_NEW_API src/ztest_rules.c) +zephyr_library_sources( + src/ztest.c + src/ztest_error_hook.c + src/ztest_rules.c + ) zephyr_library_sources_ifdef(CONFIG_ZTEST_MOCKING src/ztest_mock.c) zephyr_library_sources_ifdef(CONFIG_ZTRESS src/ztress.c) if(CONFIG_ARCH_POSIX) - zephyr_library_sources_ifdef(CONFIG_ZTEST_NEW_API src/ztest_posix.c) + zephyr_library_sources(src/ztest_posix.c) else() - zephyr_library_sources_ifdef(CONFIG_ZTEST_NEW_API src/ztest_defaults.c) + zephyr_library_sources(src/ztest_defaults.c) endif() diff --git a/subsys/testsuite/ztest/Kconfig b/subsys/testsuite/ztest/Kconfig index 91c942b7a5c..977f882d838 100644 --- a/subsys/testsuite/ztest/Kconfig +++ b/subsys/testsuite/ztest/Kconfig @@ -10,13 +10,6 @@ config ZTEST if ZTEST -config ZTEST_NEW_API - bool "Use the new Ztest API" - default y - help - Enables the new Ztest APIs for creating suites and unit tests in - separate compilation units as well as the new 'rules' API. - config ZTEST_STACK_SIZE int "Test function thread stack size" default 2048 if COVERAGE_GCOV @@ -114,9 +107,7 @@ config ZTEST_WARN_NO_OPTIMIZATIONS optimizations. Please don't file issues when running tests that are not explicitly tuned to work in this configuration. -if ZTEST_NEW_API - -menu "ztest provided rules" +menu "ZTest provided rules" config ZTEST_RULE_1CPU bool "Run all the tests on a single CPU" @@ -185,8 +176,6 @@ config ZTEST_FAIL_ON_ASSUME result will be shown as a failure in order to increase visibility. This precludes tests that skipped with the ZTEST_EXPECT_SKIP annotation. -endif # ZTEST_NEW_API - config TEST_LOGGING_FLUSH_AFTER_TEST bool "When enabled logs are flushed after each test case" default y diff --git a/subsys/testsuite/ztest/include/zephyr/ztest_test.h b/subsys/testsuite/ztest/include/zephyr/ztest_test.h index b9635560c02..a95a73ec4a0 100644 --- a/subsys/testsuite/ztest/include/zephyr/ztest_test.h +++ b/subsys/testsuite/ztest/include/zephyr/ztest_test.h @@ -1,23 +1,558 @@ /* * Copyright (c) 2016 Intel Corporation - * Copyright (c) 2021 Google LLC * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_TESTSUITE_INCLUDE_ZTEST_TEST_H_ -#define ZEPHYR_TESTSUITE_INCLUDE_ZTEST_TEST_H_ +/** + * @file + * + * @brief Zephyr testing framework _test. + */ + +#ifndef ZEPHYR_TESTSUITE_ZTEST_TEST_H_ +#define ZEPHYR_TESTSUITE_ZTEST_TEST_H_ -#ifdef CONFIG_ZTEST_NEW_API -#include +#include +#include +#include +#include + +#if defined(CONFIG_USERSPACE) +#define __USERSPACE_FLAGS (K_USER) #else -#include -#endif /* !CONFIG_ZTEST_NEW_API */ +#define __USERSPACE_FLAGS (0) +#endif #ifdef __cplusplus extern "C" { #endif +/** + * @brief The expected result of a test. + * + * @see ZTEST_EXPECT_FAIL + * @see ZTEST_EXPECT_SKIP + */ +enum ztest_expected_result { + ZTEST_EXPECTED_RESULT_FAIL = 0, /**< Expect a test to fail */ + ZTEST_EXPECTED_RESULT_SKIP, /**< Expect a test to pass */ +}; + +/** + * @brief A single expectation entry allowing tests to fail/skip and be considered passing. + * + * @see ZTEST_EXPECT_FAIL + * @see ZTEST_EXPECT_SKIP + */ +struct ztest_expected_result_entry { + const char *test_suite_name; /**< The test suite's name for the expectation */ + const char *test_name; /**< The test's name for the expectation */ + enum ztest_expected_result expected_result; /**< The expectation */ +}; + +extern struct ztest_expected_result_entry _ztest_expected_result_entry_list_start[]; +extern struct ztest_expected_result_entry _ztest_expected_result_entry_list_end[]; + +#define __ZTEST_EXPECT(_suite_name, _test_name, expectation) \ + static const STRUCT_SECTION_ITERABLE( \ + ztest_expected_result_entry, \ + UTIL_CAT(UTIL_CAT(z_ztest_expected_result_, _suite_name), _test_name)) = { \ + .test_suite_name = STRINGIFY(_suite_name), \ + .test_name = STRINGIFY(_test_name), \ + .expected_result = expectation, \ + } + +/** + * @brief Expect a test to fail (mark it passing if it failed) + * + * Adding this macro to your logic will allow the failing test to be considered passing, example: + * + * ZTEST_EXPECT_FAIL(my_suite, test_x); + * ZTEST(my_suite, text_x) { + * zassert_true(false, NULL); + * } + * + * @param _suite_name The name of the suite + * @param _test_name The name of the test + */ +#define ZTEST_EXPECT_FAIL(_suite_name, _test_name) \ + __ZTEST_EXPECT(_suite_name, _test_name, ZTEST_EXPECTED_RESULT_FAIL) + +/** + * @brief Expect a test to skip (mark it passing if it failed) + * + * Adding this macro to your logic will allow the failing test to be considered passing, example: + * + * ZTEST_EXPECT_SKIP(my_suite, test_x); + * ZTEST(my_suite, text_x) { + * zassume_true(false, NULL); + * } + * + * @param _suite_name The name of the suite + * @param _test_name The name of the test + */ +#define ZTEST_EXPECT_SKIP(_suite_name, _test_name) \ + __ZTEST_EXPECT(_suite_name, _test_name, ZTEST_EXPECTED_RESULT_SKIP) + +struct ztest_unit_test { + const char *test_suite_name; + const char *name; + void (*test)(void *data); + uint32_t thread_options; + + /** Stats */ + struct ztest_unit_test_stats *const stats; +}; + +extern struct ztest_unit_test _ztest_unit_test_list_start[]; +extern struct ztest_unit_test _ztest_unit_test_list_end[]; +#define ZTEST_TEST_COUNT (_ztest_unit_test_list_end - _ztest_unit_test_list_start) + +/** + * Stats about a ztest suite + */ +struct ztest_suite_stats { + /** The number of times that the suite ran */ + uint32_t run_count; + /** The number of times that the suite was skipped */ + uint32_t skip_count; + /** The number of times that the suite failed */ + uint32_t fail_count; +}; + +struct ztest_unit_test_stats { + /** The number of times that the test ran */ + uint32_t run_count; + /** The number of times that the test was skipped */ + uint32_t skip_count; + /** The number of times that the test failed */ + uint32_t fail_count; + /** The number of times that the test passed */ + uint32_t pass_count; + /** The longest duration of the test across multiple times */ + uint32_t duration_worst_ms; +}; + +/** + * Setup function to run before running this suite + * + * @return Pointer to the data structure that will be used throughout this test suite + */ +typedef void *(*ztest_suite_setup_t)(void); + +/** + * Function to run before each test in this suite + * + * @param fixture The test suite's fixture returned from setup() + */ +typedef void (*ztest_suite_before_t)(void *fixture); + +/** + * Function to run after each test in this suite + * + * @param fixture The test suite's fixture returned from setup() + */ +typedef void (*ztest_suite_after_t)(void *fixture); + +/** + * Teardown function to run after running this suite + * + * @param fixture The test suite's data returned from setup() + */ +typedef void (*ztest_suite_teardown_t)(void *fixture); + +/** + * An optional predicate function to determine if the test should run. If NULL, then the + * test will only run once on the first attempt. + * + * @param global_state The current state of the test application. + * @return True if the suite should be run; false to skip. + */ +typedef bool (*ztest_suite_predicate_t)(const void *global_state); + +/** + * A single node of test suite. Each node should be added to a single linker section which will + * allow ztest_run_test_suites() to iterate over the various nodes. + */ +struct ztest_suite_node { + /** The name of the test suite. */ + const char *const name; + + /** Setup function */ + const ztest_suite_setup_t setup; + + /** Before function */ + const ztest_suite_before_t before; + + /** After function */ + const ztest_suite_after_t after; + + /** Teardown function */ + const ztest_suite_teardown_t teardown; + + /** Optional predicate filter */ + const ztest_suite_predicate_t predicate; + + /** Stats */ + struct ztest_suite_stats *const stats; +}; + +extern struct ztest_suite_node _ztest_suite_node_list_start[]; +extern struct ztest_suite_node _ztest_suite_node_list_end[]; +#define ZTEST_SUITE_COUNT (_ztest_suite_node_list_end - _ztest_suite_node_list_start) + +/** + * Create and register a ztest suite. Using this macro creates a new test suite (using + * ztest_test_suite). It then creates a struct ztest_suite_node in a specific linker section. + * + * Tests can then be run by calling ztest_run_test_suites(const void *state) by passing + * in the current state. See the documentation for ztest_run_test_suites for more info. + * + * @param SUITE_NAME The name of the suite (see ztest_test_suite for more info) + * @param PREDICATE A function to test against the state and determine if the test should run. + * @param setup_fn The setup function to call before running this test suite + * @param before_fn The function to call before each unit test in this suite + * @param after_fn The function to call after each unit test in this suite + * @param teardown_fn The function to call after running all the tests in this suite + */ +#define ZTEST_SUITE(SUITE_NAME, PREDICATE, setup_fn, before_fn, after_fn, teardown_fn) \ + struct ztest_suite_stats UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME); \ + static const STRUCT_SECTION_ITERABLE(ztest_suite_node, \ + UTIL_CAT(z_ztest_test_node_, SUITE_NAME)) = { \ + .name = STRINGIFY(SUITE_NAME), \ + .setup = (setup_fn), \ + .before = (before_fn), \ + .after = (after_fn), \ + .teardown = (teardown_fn), \ + .predicate = PREDICATE, \ + .stats = &UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME), \ + } +/** + * Default entry point for running or listing registered unit tests. + * + * @param state The current state of the machine as it relates to the test executable. + */ +void ztest_run_all(const void *state); + +/** + * The result of the current running test. It's possible that the setup function sets the result + * to ZTEST_RESULT_SUITE_* which will apply the failure/skip to every test in the suite. + */ +enum ztest_result { + ZTEST_RESULT_PENDING, + ZTEST_RESULT_PASS, + ZTEST_RESULT_FAIL, + ZTEST_RESULT_SKIP, + ZTEST_RESULT_SUITE_SKIP, + ZTEST_RESULT_SUITE_FAIL, +}; +/** + * Each enum member represents a distinct phase of execution for the test binary. + * TEST_PHASE_FRAMEWORK is active when internal ztest code is executing; the rest refer to + * corresponding phases of user test code. + */ +enum ztest_phase { + TEST_PHASE_SETUP, + TEST_PHASE_BEFORE, + TEST_PHASE_TEST, + TEST_PHASE_AFTER, + TEST_PHASE_TEARDOWN, + TEST_PHASE_FRAMEWORK, +}; + +/** + * Run the registered unit tests which return true from their predicate function. + * + * @param state The current state of the machine as it relates to the test executable. + * @return The number of tests that ran. + */ + +#ifdef ZTEST_UNITTEST +int z_impl_ztest_run_test_suites(const void *state); +static inline int ztest_run_test_suites(const void *state) +{ + return z_impl_ztest_run_test_suites(state); +} + +#else +__syscall int ztest_run_test_suites(const void *state); +#endif + +#ifdef ZTEST_UNITTEST +void z_impl___ztest_set_test_result(enum ztest_result new_result); +static inline void __ztest_set_test_result(enum ztest_result new_result) +{ + z_impl___ztest_set_test_result(new_result); +} + +void z_impl___ztest_set_test_phase(enum ztest_phase new_phase); +static inline void __ztest_set_test_phase(enum ztest_phase new_phase) +{ + z_impl___ztest_set_test_phase(new_phase); +} +#else +__syscall void __ztest_set_test_result(enum ztest_result new_result); +__syscall void __ztest_set_test_phase(enum ztest_phase new_phase); +#endif + +#ifndef ZTEST_UNITTEST +#include +#endif + +/** + * @brief Fails the test if any of the registered tests did not run. + * + * When registering test suites, a pragma function can be provided to determine WHEN the test should + * run. It is possible that a test suite could be registered but the pragma always prevents it from + * running. In cases where a test should make sure that ALL suites ran at least once, this function + * may be called at the end of test_main(). It will cause the test to fail if any suite was + * registered but never ran. + */ +void ztest_verify_all_test_suites_ran(void); + +/** + * @brief Run a test suite. + * + * Internal implementation. Do not call directly. This will run the full test suite along with some + * checks for fast failures and initialization. + * + * @param name The name of the suite to run. + * @return Negative value if the test suite never ran; otherwise, return the number of failures. + */ +int z_ztest_run_test_suite(const char *name); + +/** + * @brief Returns next test within suite. + * + * @param suite Name of suite to get next test from. + * @param prev Previous unit test acquired from suite, use NULL to return first + * unit test. + * @return struct ztest_unit_test* + */ +struct ztest_unit_test *z_ztest_get_next_test(const char *suite, struct ztest_unit_test *prev); + +/* definitions for use with testing application shared memory */ +#ifdef CONFIG_USERSPACE +#define ZTEST_DMEM K_APP_DMEM(ztest_mem_partition) +#define ZTEST_BMEM K_APP_BMEM(ztest_mem_partition) +#define ZTEST_SECTION K_APP_DMEM_SECTION(ztest_mem_partition) +extern struct k_mem_partition ztest_mem_partition; +#else +#define ZTEST_DMEM +#define ZTEST_BMEM +#define ZTEST_SECTION .data +#endif + +/** + * @defgroup ztest_test Ztest testing macros + * @ingroup ztest + * + * This module eases the testing process by providing helpful macros and other + * testing structures. + * + * @{ + */ + +/** + * @brief Fail the currently running test. + * + * This is the function called from failed assertions and the like. You + * probably don't need to call it yourself. + */ +void ztest_test_fail(void); + +/** + * @brief Pass the currently running test. + * + * Normally a test passes just by returning without an assertion failure. + * However, if the success case for your test involves a fatal fault, + * you can call this function from k_sys_fatal_error_handler to indicate that + * the test passed before aborting the thread. + */ +void ztest_test_pass(void); + +/** + * @brief Skip the current test. + * + */ +void ztest_test_skip(void); + + +void ztest_skip_failed_assumption(void); + +#define Z_TEST(suite, fn, t_options, use_fixture) \ + struct ztest_unit_test_stats z_ztest_unit_test_stats_##suite##_##fn; \ + static void _##suite##_##fn##_wrapper(void *data); \ + static void suite##_##fn( \ + COND_CODE_1(use_fixture, (struct suite##_fixture *fixture), (void))); \ + static STRUCT_SECTION_ITERABLE(ztest_unit_test, z_ztest_unit_test__##suite##__##fn) = { \ + .test_suite_name = STRINGIFY(suite), \ + .name = STRINGIFY(fn), \ + .test = (_##suite##_##fn##_wrapper), \ + .thread_options = t_options, \ + .stats = &z_ztest_unit_test_stats_##suite##_##fn \ + }; \ + static void _##suite##_##fn##_wrapper(void *wrapper_data) \ + { \ + COND_CODE_1(use_fixture, (suite##_##fn((struct suite##_fixture *)wrapper_data);), \ + (ARG_UNUSED(wrapper_data); suite##_##fn();)) \ + } \ + static inline void suite##_##fn( \ + COND_CODE_1(use_fixture, (struct suite##_fixture *fixture), (void))) + +#define Z_ZTEST(suite, fn, t_options) Z_TEST(suite, fn, t_options, 0) +#define Z_ZTEST_F(suite, fn, t_options) Z_TEST(suite, fn, t_options, 1) + +/** + * @brief Skips the test if config is enabled + * + * Use this macro at the start of your test case, to skip it when + * config is enabled. Useful when your test is still under development. + * + * @param config The Kconfig option used to skip the test. + */ +#define Z_TEST_SKIP_IFDEF(config) COND_CODE_1(config, (ztest_test_skip()), ()) + +/** + * @brief Skips the test if config is not enabled + * + * Use this macro at the start of your test case, to skip it when + * config is not enabled. Useful when your need to skip test if some + * conifiguration option is not enabled. + * + * @param config The Kconfig option used to skip the test (if not enabled). + */ +#define Z_TEST_SKIP_IFNDEF(config) COND_CODE_1(config, (), (ztest_test_skip())) + +/** + * @brief Create and register a new unit test. + * + * Calling this macro will create a new unit test and attach it to the declared `suite`. The `suite` + * does not need to be defined in the same compilation unit. + * + * @param suite The name of the test suite to attach this test + * @param fn The test function to call. + */ +#define ZTEST(suite, fn) Z_ZTEST(suite, fn, 0) + +/** + * @brief Define a test function that should run as a user thread + * + * This macro behaves exactly the same as ZTEST, but calls the test function in user space if + * `CONFIG_USERSPACE` was enabled. + * + * @param suite The name of the test suite to attach this test + * @param fn The test function to call. + */ +#define ZTEST_USER(suite, fn) Z_ZTEST(suite, fn, K_USER) + +/** + * @brief Define a test function + * + * This macro behaves exactly the same as ZTEST(), but the function takes an argument for the + * fixture of type `struct suite##_fixture*` named `this`. + * + * @param suite The name of the test suite to attach this test + * @param fn The test function to call. + */ +#define ZTEST_F(suite, fn) Z_ZTEST_F(suite, fn, 0) + +/** + * @brief Define a test function that should run as a user thread + * + * If CONFIG_USERSPACE is not enabled, this is functionally identical to ZTEST_F(). The test + * function takes a single fixture argument of type `struct suite##_fixture*` named `this`. + * + * @param suite The name of the test suite to attach this test + * @param fn The test function to call. + */ +#define ZTEST_USER_F(suite, fn) Z_ZTEST_F(suite, fn, K_USER) + +/** + * @brief Test rule callback function signature + * + * The function signature that can be used to register a test rule's before/after callback. This + * provides access to the test and the fixture data (if provided). + * + * @param test Pointer to the unit test in context + * @param data Pointer to the test's fixture data (may be NULL) + */ +typedef void (*ztest_rule_cb)(const struct ztest_unit_test *test, void *data); + +/** @private */ +struct ztest_test_rule { + ztest_rule_cb before_each; + ztest_rule_cb after_each; +}; + +/** + * @brief Define a test rule that will run before/after each unit test. + * + * Functions defined here will run before/after each unit test for every test suite. Along with the + * callback, the test functions are provided a pointer to the test being run, and the data. This + * provides a mechanism for tests to perform custom operations depending on the specific test or + * the data (for example logging may use the test's name). + * + * Ordering: + * - Test rule's `before` function will run before the suite's `before` function. This is done to + * allow the test suite's customization to take precedence over the rule which is applied to all + * suites. + * - Test rule's `after` function is not guaranteed to run in any particular order. + * + * @param name The name for the test rule (must be unique within the compilation unit) + * @param before_each_fn The callback function (ztest_rule_cb) to call before each test + * (may be NULL) + * @param after_each_fn The callback function (ztest_rule_cb) to call after each test (may be NULL) + */ +#define ZTEST_RULE(name, before_each_fn, after_each_fn) \ + static STRUCT_SECTION_ITERABLE(ztest_test_rule, z_ztest_test_rule_##name) = { \ + .before_each = (before_each_fn), \ + .after_each = (after_each_fn), \ + } + +extern struct ztest_test_rule _ztest_test_rule_list_start[]; +extern struct ztest_test_rule _ztest_test_rule_list_end[]; + +/** + * @brief A 'before' function to use in test suites that just need to start 1cpu + * + * Ignores data, and calls z_test_1cpu_start() + * + * @param data The test suite's data + */ +void ztest_simple_1cpu_before(void *data); + +/** + * @brief A 'after' function to use in test suites that just need to stop 1cpu + * + * Ignores data, and calls z_test_1cpu_stop() + * + * @param data The test suite's data + */ +void ztest_simple_1cpu_after(void *data); + +/** + * @brief Run the specified test suite. + * + * @param suite Test suite to run. + */ +#define ztest_run_test_suite(suite) z_ztest_run_test_suite(STRINGIFY(suite)) + +/** + * @brief Structure for architecture specific APIs + * + */ +struct ztest_arch_api { + void (*run_all)(const void *state); + bool (*should_suite_run)(const void *state, struct ztest_suite_node *suite); + bool (*should_test_run)(const char *suite, const char *test); +}; + +/** + * @} + */ + __syscall void z_test_1cpu_start(void); __syscall void z_test_1cpu_stop(void); @@ -31,4 +566,4 @@ __syscall void sys_clock_tick_set(uint64_t tick); #include #endif -#endif /* ZEPHYR_TESTSUITE_INCLUDE_ZTEST_TEST_H_ */ +#endif /* ZEPHYR_TESTSUITE_ZTEST_TEST_H_ */ diff --git a/subsys/testsuite/ztest/include/zephyr/ztest_test_deprecated.h b/subsys/testsuite/ztest/include/zephyr/ztest_test_deprecated.h deleted file mode 100644 index 8207b184a5d..00000000000 --- a/subsys/testsuite/ztest/include/zephyr/ztest_test_deprecated.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * @brief Zephyr testing framework _test_deprecated. - */ - -#ifndef ZEPHYR_TESTSUITE_ZTEST_TEST_H_ -#define ZEPHYR_TESTSUITE_ZTEST_TEST_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct unit_test { - const char *name; - void (*test)(void); - void (*setup)(void); - void (*teardown)(void); - uint32_t thread_options; -}; - -/** - * Stats about a ztest suite - */ -struct ztest_suite_stats { - /** The number of times that the suite ran */ - uint32_t run_count; - /** The number of times that the suite was skipped */ - uint32_t skip_count; - /** The number of times that the suite failed */ - uint32_t fail_count; -}; - -/** - * A single node of test suite. Each node should be added to a single linker section which will - * allow ztest_run_registered_test_suites() to iterate over the various nodes. - */ -struct ztest_suite_node { - /** The name of the test suite. */ - const char *name; - /** Pointer to the test suite. */ - struct unit_test *suite; - /** - * An optional predicate function to determine if the test should run. If NULL, then the - * test will only run once on the first attempt. - * - * @param state The current state of the test application. - * @return True if the suite should be run; false to skip. - */ - bool (*predicate)(const void *state); - /** Stats */ - struct ztest_suite_stats *stats; -}; - -extern struct ztest_suite_node _ztest_suite_node_list_start[]; -extern struct ztest_suite_node _ztest_suite_node_list_end[]; - -/** - * Create and register a ztest suite. Using this macro creates a new test suite (using - * ztest_test_suite). It then creates a struct ztest_suite_node in a specific linker section. - * - * Tests can then be run by calling ztest_run_registered_test_suites(const void *state) by passing - * in the current state. See the documentation for ztest_run_registered_test_suites for more info. - * - * @param SUITE_NAME The name of the suite (see ztest_test_suite for more info) - * @param PREDICATE A function to test against the state and determine if the test should run. - * @param args Varargs placeholder for the remaining arguments passed for the unit tests. - */ -#define ztest_register_test_suite(SUITE_NAME, PREDICATE, args...) \ - ztest_test_suite(SUITE_NAME, ##args); \ - struct ztest_suite_stats UTIL_CAT(z_ztest_test_node_stats_, SUITE_NAME); \ - static STRUCT_SECTION_ITERABLE(ztest_suite_node, z_ztest_test_node_##SUITE_NAME) = { \ - .name = #SUITE_NAME, \ - .suite = _##SUITE_NAME, \ - .predicate = PREDICATE, \ - .stats = &UTIL_CAT(z_ztest_test_node_stats_, SUITE_NAME), \ - }; - -/** - * Run the registered unit tests which return true from their pragma function. - * - * @param state The current state of the machine as it relates to the test executable. - * @return The number of tests that ran. - */ -__deprecated -int ztest_run_registered_test_suites(const void *state); - -/** - * @brief Fails the test if any of the registered tests did not run. - * - * When registering test suites, a pragma function can be provided to determine WHEN the test should - * run. It is possible that a test suite could be registered but the pragma always prevents it from - * running. In cases where a test should make sure that ALL suites ran at least once, this function - * may be called at the end of test_main(). It will cause the test to fail if any suite was - * registered but never ran. - */ -__deprecated -void ztest_verify_all_registered_test_suites_ran(void); - -/** - * @brief Run a test suite. - * - * Internal implementation. Do not call directly. This will run the full test suite along with some - * checks for fast failures and initialization. - * - * @param name The name of the suite to run. - * @param suite Pointer to the first unit test. - * @return Negative value if the test suite never ran; otherwise, return the number of failures. - */ -int z_ztest_run_test_suite(const char *name, struct unit_test *suite); - -/** - * @defgroup ztest_test_deprecated Ztest testing macros - * @ingroup ztest - * - * This module eases the testing process by providing helpful macros and other - * testing structures. - * - * @{ - */ - -/** - * @brief Fail the currently running test. - * - * This is the function called from failed assertions and the like. You - * probably don't need to call it yourself. - */ -void ztest_test_fail(void); - -/** - * @brief Pass the currently running test. - * - * Normally a test passes just by returning without an assertion failure. - * However, if the success case for your test involves a fatal fault, - * you can call this function from k_sys_fatal_error_handler to indicate that - * the test passed before aborting the thread. - */ -void ztest_test_pass(void); - -/** - * @brief Skip the current test. - */ -void ztest_test_skip(void); - -/** - * @brief Do nothing, successfully. - * - * Unit test / setup function / teardown function that does - * nothing, successfully. Can be used as a parameter to - * ztest_unit_test_setup_teardown(). - */ -static inline void unit_test_noop(void) -{ -} - -/** - * @brief Define a test with setup and teardown functions - * - * This should be called as an argument to ztest_test_suite. The test will - * be run in the following order: @a setup, @a fn, @a teardown. - * - * @param fn Main test function - * @param setup Setup function - * @param teardown Teardown function - */ -#define ztest_unit_test_setup_teardown(fn, setup, teardown) \ - { \ - STRINGIFY(fn), fn, setup, teardown, 0 \ - } - -/** - * @brief Define a user mode test with setup and teardown functions - * - * This should be called as an argument to ztest_test_suite. The test will - * be run in the following order: @a setup, @a fn, @a teardown. ALL - * test functions will be run in user mode, and only if CONFIG_USERSPACE - * is enabled, otherwise this is the same as ztest_unit_test_setup_teardown(). - * - * @param fn Main test function - * @param setup Setup function - * @param teardown Teardown function - */ -#define ztest_user_unit_test_setup_teardown(fn, setup, teardown) \ - { \ - STRINGIFY(fn), fn, setup, teardown, K_USER \ - } - -/** - * @brief Define a test function - * - * This should be called as an argument to ztest_test_suite. - * - * @param fn Test function - */ -#define ztest_unit_test(fn) \ - ztest_unit_test_setup_teardown(fn, unit_test_noop, unit_test_noop) - -/** - * @brief Define a test function that should run as a user thread - * - * This should be called as an argument to ztest_test_suite. - * If CONFIG_USERSPACE is not enabled, this is functionally identical to - * ztest_unit_test(). - * - * @param fn Test function - */ -#define ztest_user_unit_test(fn) \ - ztest_user_unit_test_setup_teardown(fn, unit_test_noop, unit_test_noop) - -/** - * @brief Define a SMP-unsafe test function - * - * As ztest_unit_test(), but ensures all test code runs on only - * one CPU when in SMP. - * - * @param fn Test function - */ -#ifdef CONFIG_SMP -#define ztest_1cpu_unit_test(fn) \ - ztest_unit_test_setup_teardown(fn, z_test_1cpu_start, z_test_1cpu_stop) -#else -#define ztest_1cpu_unit_test(fn) ztest_unit_test(fn) -#endif - -/** - * @brief Define a SMP-unsafe test function that should run as a user thread - * - * As ztest_user_unit_test(), but ensures all test code runs on only - * one CPU when in SMP. - * - * @param fn Test function - */ -#ifdef CONFIG_SMP -#define ztest_1cpu_user_unit_test(fn) \ - ztest_user_unit_test_setup_teardown(fn, z_test_1cpu_start, z_test_1cpu_stop) -#else -#define ztest_1cpu_user_unit_test(fn) ztest_user_unit_test(fn) -#endif - -/* definitions for use with testing application shared memory */ -#ifdef CONFIG_USERSPACE -#define ZTEST_DMEM K_APP_DMEM(ztest_mem_partition) -#define ZTEST_BMEM K_APP_BMEM(ztest_mem_partition) -#define ZTEST_SECTION K_APP_DMEM_SECTION(ztest_mem_partition) -extern struct k_mem_partition ztest_mem_partition; -#else -#define ZTEST_DMEM -#define ZTEST_BMEM -#define ZTEST_SECTION .data -#endif - -/** - * @brief Define a test suite - * - * This function should be called in the following fashion: - * ```{.c} - * ztest_test_suite(test_suite_name, - * ztest_unit_test(test_function), - * ztest_unit_test(test_other_function) - * ); - * - * ztest_run_test_suite(test_suite_name); - * ``` - * - * @param suite Name of the testing suite - */ -#define ztest_test_suite(suite, ...) __DEPRECATED_MACRO \ - static ZTEST_DMEM struct unit_test _##suite[] = { __VA_ARGS__, { 0 } } -/** - * @brief Run the specified test suite. - * - * @param suite Test suite to run. - */ -#define ztest_run_test_suite(suite) __DEPRECATED_MACRO \ - z_ztest_run_test_suite(#suite, _##suite) - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_TESTSUITE_ZTEST_TEST_H_ */ diff --git a/subsys/testsuite/ztest/include/zephyr/ztest_test_new.h b/subsys/testsuite/ztest/include/zephyr/ztest_test_new.h deleted file mode 100644 index e676bf7d3d8..00000000000 --- a/subsys/testsuite/ztest/include/zephyr/ztest_test_new.h +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * @brief Zephyr testing framework _test. - */ - -#ifndef ZEPHYR_TESTSUITE_ZTEST_TEST_H_ -#define ZEPHYR_TESTSUITE_ZTEST_TEST_H_ - -#include -#include -#include -#include - -#if defined(CONFIG_USERSPACE) -#define __USERSPACE_FLAGS (K_USER) -#else -#define __USERSPACE_FLAGS (0) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief The expected result of a test. - * - * @see ZTEST_EXPECT_FAIL - * @see ZTEST_EXPECT_SKIP - */ -enum ztest_expected_result { - ZTEST_EXPECTED_RESULT_FAIL = 0, /**< Expect a test to fail */ - ZTEST_EXPECTED_RESULT_SKIP, /**< Expect a test to pass */ -}; - -/** - * @brief A single expectation entry allowing tests to fail/skip and be considered passing. - * - * @see ZTEST_EXPECT_FAIL - * @see ZTEST_EXPECT_SKIP - */ -struct ztest_expected_result_entry { - const char *test_suite_name; /**< The test suite's name for the expectation */ - const char *test_name; /**< The test's name for the expectation */ - enum ztest_expected_result expected_result; /**< The expectation */ -}; - -extern struct ztest_expected_result_entry _ztest_expected_result_entry_list_start[]; -extern struct ztest_expected_result_entry _ztest_expected_result_entry_list_end[]; - -#define __ZTEST_EXPECT(_suite_name, _test_name, expectation) \ - static const STRUCT_SECTION_ITERABLE( \ - ztest_expected_result_entry, \ - UTIL_CAT(UTIL_CAT(z_ztest_expected_result_, _suite_name), _test_name)) = { \ - .test_suite_name = STRINGIFY(_suite_name), \ - .test_name = STRINGIFY(_test_name), \ - .expected_result = expectation, \ - } - -/** - * @brief Expect a test to fail (mark it passing if it failed) - * - * Adding this macro to your logic will allow the failing test to be considered passing, example: - * - * ZTEST_EXPECT_FAIL(my_suite, test_x); - * ZTEST(my_suite, text_x) { - * zassert_true(false, NULL); - * } - * - * @param _suite_name The name of the suite - * @param _test_name The name of the test - */ -#define ZTEST_EXPECT_FAIL(_suite_name, _test_name) \ - __ZTEST_EXPECT(_suite_name, _test_name, ZTEST_EXPECTED_RESULT_FAIL) - -/** - * @brief Expect a test to skip (mark it passing if it failed) - * - * Adding this macro to your logic will allow the failing test to be considered passing, example: - * - * ZTEST_EXPECT_SKIP(my_suite, test_x); - * ZTEST(my_suite, text_x) { - * zassume_true(false, NULL); - * } - * - * @param _suite_name The name of the suite - * @param _test_name The name of the test - */ -#define ZTEST_EXPECT_SKIP(_suite_name, _test_name) \ - __ZTEST_EXPECT(_suite_name, _test_name, ZTEST_EXPECTED_RESULT_SKIP) - -struct ztest_unit_test { - const char *test_suite_name; - const char *name; - void (*test)(void *data); - uint32_t thread_options; - - /** Stats */ - struct ztest_unit_test_stats *const stats; -}; - -extern struct ztest_unit_test _ztest_unit_test_list_start[]; -extern struct ztest_unit_test _ztest_unit_test_list_end[]; -#define ZTEST_TEST_COUNT (_ztest_unit_test_list_end - _ztest_unit_test_list_start) - -/** - * Stats about a ztest suite - */ -struct ztest_suite_stats { - /** The number of times that the suite ran */ - uint32_t run_count; - /** The number of times that the suite was skipped */ - uint32_t skip_count; - /** The number of times that the suite failed */ - uint32_t fail_count; -}; - -struct ztest_unit_test_stats { - /** The number of times that the test ran */ - uint32_t run_count; - /** The number of times that the test was skipped */ - uint32_t skip_count; - /** The number of times that the test failed */ - uint32_t fail_count; - /** The number of times that the test passed */ - uint32_t pass_count; - /** The longest duration of the test across multiple times */ - uint32_t duration_worst_ms; -}; - -/** - * Setup function to run before running this suite - * - * @return Pointer to the data structure that will be used throughout this test suite - */ -typedef void *(*ztest_suite_setup_t)(void); - -/** - * Function to run before each test in this suite - * - * @param fixture The test suite's fixture returned from setup() - */ -typedef void (*ztest_suite_before_t)(void *fixture); - -/** - * Function to run after each test in this suite - * - * @param fixture The test suite's fixture returned from setup() - */ -typedef void (*ztest_suite_after_t)(void *fixture); - -/** - * Teardown function to run after running this suite - * - * @param fixture The test suite's data returned from setup() - */ -typedef void (*ztest_suite_teardown_t)(void *fixture); - -/** - * An optional predicate function to determine if the test should run. If NULL, then the - * test will only run once on the first attempt. - * - * @param global_state The current state of the test application. - * @return True if the suite should be run; false to skip. - */ -typedef bool (*ztest_suite_predicate_t)(const void *global_state); - -/** - * A single node of test suite. Each node should be added to a single linker section which will - * allow ztest_run_test_suites() to iterate over the various nodes. - */ -struct ztest_suite_node { - /** The name of the test suite. */ - const char *const name; - - /** Setup function */ - const ztest_suite_setup_t setup; - - /** Before function */ - const ztest_suite_before_t before; - - /** After function */ - const ztest_suite_after_t after; - - /** Teardown function */ - const ztest_suite_teardown_t teardown; - - /** Optional predicate filter */ - const ztest_suite_predicate_t predicate; - - /** Stats */ - struct ztest_suite_stats *const stats; -}; - -extern struct ztest_suite_node _ztest_suite_node_list_start[]; -extern struct ztest_suite_node _ztest_suite_node_list_end[]; -#define ZTEST_SUITE_COUNT (_ztest_suite_node_list_end - _ztest_suite_node_list_start) - -/** - * Create and register a ztest suite. Using this macro creates a new test suite (using - * ztest_test_suite). It then creates a struct ztest_suite_node in a specific linker section. - * - * Tests can then be run by calling ztest_run_test_suites(const void *state) by passing - * in the current state. See the documentation for ztest_run_test_suites for more info. - * - * @param SUITE_NAME The name of the suite (see ztest_test_suite for more info) - * @param PREDICATE A function to test against the state and determine if the test should run. - * @param setup_fn The setup function to call before running this test suite - * @param before_fn The function to call before each unit test in this suite - * @param after_fn The function to call after each unit test in this suite - * @param teardown_fn The function to call after running all the tests in this suite - */ -#define ZTEST_SUITE(SUITE_NAME, PREDICATE, setup_fn, before_fn, after_fn, teardown_fn) \ - struct ztest_suite_stats UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME); \ - static const STRUCT_SECTION_ITERABLE(ztest_suite_node, \ - UTIL_CAT(z_ztest_test_node_, SUITE_NAME)) = { \ - .name = STRINGIFY(SUITE_NAME), \ - .setup = (setup_fn), \ - .before = (before_fn), \ - .after = (after_fn), \ - .teardown = (teardown_fn), \ - .predicate = PREDICATE, \ - .stats = &UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME), \ - } -/** - * Default entry point for running or listing registered unit tests. - * - * @param state The current state of the machine as it relates to the test executable. - */ -void ztest_run_all(const void *state); - -/** - * The result of the current running test. It's possible that the setup function sets the result - * to ZTEST_RESULT_SUITE_* which will apply the failure/skip to every test in the suite. - */ -enum ztest_result { - ZTEST_RESULT_PENDING, - ZTEST_RESULT_PASS, - ZTEST_RESULT_FAIL, - ZTEST_RESULT_SKIP, - ZTEST_RESULT_SUITE_SKIP, - ZTEST_RESULT_SUITE_FAIL, -}; -/** - * Each enum member represents a distinct phase of execution for the test binary. - * TEST_PHASE_FRAMEWORK is active when internal ztest code is executing; the rest refer to - * corresponding phases of user test code. - */ -enum ztest_phase { - TEST_PHASE_SETUP, - TEST_PHASE_BEFORE, - TEST_PHASE_TEST, - TEST_PHASE_AFTER, - TEST_PHASE_TEARDOWN, - TEST_PHASE_FRAMEWORK, -}; - -/** - * Run the registered unit tests which return true from their predicate function. - * - * @param state The current state of the machine as it relates to the test executable. - * @return The number of tests that ran. - */ - -#ifdef ZTEST_UNITTEST -int z_impl_ztest_run_test_suites(const void *state); -static inline int ztest_run_test_suites(const void *state) -{ - return z_impl_ztest_run_test_suites(state); -} - -#else -__syscall int ztest_run_test_suites(const void *state); -#endif - -#ifdef ZTEST_UNITTEST -void z_impl___ztest_set_test_result(enum ztest_result new_result); -static inline void __ztest_set_test_result(enum ztest_result new_result) -{ - z_impl___ztest_set_test_result(new_result); -} - -void z_impl___ztest_set_test_phase(enum ztest_phase new_phase); -static inline void __ztest_set_test_phase(enum ztest_phase new_phase) -{ - z_impl___ztest_set_test_phase(new_phase); -} -#else -__syscall void __ztest_set_test_result(enum ztest_result new_result); -__syscall void __ztest_set_test_phase(enum ztest_phase new_phase); -#endif - -#ifndef ZTEST_UNITTEST -#include -#endif - -/** - * @brief Fails the test if any of the registered tests did not run. - * - * When registering test suites, a pragma function can be provided to determine WHEN the test should - * run. It is possible that a test suite could be registered but the pragma always prevents it from - * running. In cases where a test should make sure that ALL suites ran at least once, this function - * may be called at the end of test_main(). It will cause the test to fail if any suite was - * registered but never ran. - */ -void ztest_verify_all_test_suites_ran(void); - -/** - * @brief Run a test suite. - * - * Internal implementation. Do not call directly. This will run the full test suite along with some - * checks for fast failures and initialization. - * - * @param name The name of the suite to run. - * @return Negative value if the test suite never ran; otherwise, return the number of failures. - */ -int z_ztest_run_test_suite(const char *name); - -/** - * @brief Returns next test within suite. - * - * @param suite Name of suite to get next test from. - * @param prev Previous unit test acquired from suite, use NULL to return first - * unit test. - * @return struct ztest_unit_test* - */ -struct ztest_unit_test *z_ztest_get_next_test(const char *suite, struct ztest_unit_test *prev); - -/* definitions for use with testing application shared memory */ -#ifdef CONFIG_USERSPACE -#define ZTEST_DMEM K_APP_DMEM(ztest_mem_partition) -#define ZTEST_BMEM K_APP_BMEM(ztest_mem_partition) -#define ZTEST_SECTION K_APP_DMEM_SECTION(ztest_mem_partition) -extern struct k_mem_partition ztest_mem_partition; -#else -#define ZTEST_DMEM -#define ZTEST_BMEM -#define ZTEST_SECTION .data -#endif - -/** - * @defgroup ztest_test Ztest testing macros - * @ingroup ztest - * - * This module eases the testing process by providing helpful macros and other - * testing structures. - * - * @{ - */ - -/** - * @brief Fail the currently running test. - * - * This is the function called from failed assertions and the like. You - * probably don't need to call it yourself. - */ -void ztest_test_fail(void); - -/** - * @brief Pass the currently running test. - * - * Normally a test passes just by returning without an assertion failure. - * However, if the success case for your test involves a fatal fault, - * you can call this function from k_sys_fatal_error_handler to indicate that - * the test passed before aborting the thread. - */ -void ztest_test_pass(void); - -/** - * @brief Skip the current test. - * - */ -void ztest_test_skip(void); - - -void ztest_skip_failed_assumption(void); - -#define Z_TEST(suite, fn, t_options, use_fixture) \ - struct ztest_unit_test_stats z_ztest_unit_test_stats_##suite##_##fn; \ - static void _##suite##_##fn##_wrapper(void *data); \ - static void suite##_##fn( \ - COND_CODE_1(use_fixture, (struct suite##_fixture *fixture), (void))); \ - static STRUCT_SECTION_ITERABLE(ztest_unit_test, z_ztest_unit_test__##suite##__##fn) = { \ - .test_suite_name = STRINGIFY(suite), \ - .name = STRINGIFY(fn), \ - .test = (_##suite##_##fn##_wrapper), \ - .thread_options = t_options, \ - .stats = &z_ztest_unit_test_stats_##suite##_##fn \ - }; \ - static void _##suite##_##fn##_wrapper(void *wrapper_data) \ - { \ - COND_CODE_1(use_fixture, (suite##_##fn((struct suite##_fixture *)wrapper_data);), \ - (ARG_UNUSED(wrapper_data); suite##_##fn();)) \ - } \ - static inline void suite##_##fn( \ - COND_CODE_1(use_fixture, (struct suite##_fixture *fixture), (void))) - -#define Z_ZTEST(suite, fn, t_options) Z_TEST(suite, fn, t_options, 0) -#define Z_ZTEST_F(suite, fn, t_options) Z_TEST(suite, fn, t_options, 1) - -/** - * @brief Skips the test if config is enabled - * - * Use this macro at the start of your test case, to skip it when - * config is enabled. Useful when your test is still under development. - * - * @param config The Kconfig option used to skip the test. - */ -#define Z_TEST_SKIP_IFDEF(config) COND_CODE_1(config, (ztest_test_skip()), ()) - -/** - * @brief Skips the test if config is not enabled - * - * Use this macro at the start of your test case, to skip it when - * config is not enabled. Useful when your need to skip test if some - * conifiguration option is not enabled. - * - * @param config The Kconfig option used to skip the test (if not enabled). - */ -#define Z_TEST_SKIP_IFNDEF(config) COND_CODE_1(config, (), (ztest_test_skip())) - -/** - * @brief Create and register a new unit test. - * - * Calling this macro will create a new unit test and attach it to the declared `suite`. The `suite` - * does not need to be defined in the same compilation unit. - * - * @param suite The name of the test suite to attach this test - * @param fn The test function to call. - */ -#define ZTEST(suite, fn) Z_ZTEST(suite, fn, 0) - -/** - * @brief Define a test function that should run as a user thread - * - * This macro behaves exactly the same as ZTEST, but calls the test function in user space if - * `CONFIG_USERSPACE` was enabled. - * - * @param suite The name of the test suite to attach this test - * @param fn The test function to call. - */ -#define ZTEST_USER(suite, fn) Z_ZTEST(suite, fn, K_USER) - -/** - * @brief Define a test function - * - * This macro behaves exactly the same as ZTEST(), but the function takes an argument for the - * fixture of type `struct suite##_fixture*` named `this`. - * - * @param suite The name of the test suite to attach this test - * @param fn The test function to call. - */ -#define ZTEST_F(suite, fn) Z_ZTEST_F(suite, fn, 0) - -/** - * @brief Define a test function that should run as a user thread - * - * If CONFIG_USERSPACE is not enabled, this is functionally identical to ZTEST_F(). The test - * function takes a single fixture argument of type `struct suite##_fixture*` named `this`. - * - * @param suite The name of the test suite to attach this test - * @param fn The test function to call. - */ -#define ZTEST_USER_F(suite, fn) Z_ZTEST_F(suite, fn, K_USER) - -/** - * @brief Test rule callback function signature - * - * The function signature that can be used to register a test rule's before/after callback. This - * provides access to the test and the fixture data (if provided). - * - * @param test Pointer to the unit test in context - * @param data Pointer to the test's fixture data (may be NULL) - */ -typedef void (*ztest_rule_cb)(const struct ztest_unit_test *test, void *data); - -/** @private */ -struct ztest_test_rule { - ztest_rule_cb before_each; - ztest_rule_cb after_each; -}; - -/** - * @brief Define a test rule that will run before/after each unit test. - * - * Functions defined here will run before/after each unit test for every test suite. Along with the - * callback, the test functions are provided a pointer to the test being run, and the data. This - * provides a mechanism for tests to perform custom operations depending on the specific test or - * the data (for example logging may use the test's name). - * - * Ordering: - * - Test rule's `before` function will run before the suite's `before` function. This is done to - * allow the test suite's customization to take precedence over the rule which is applied to all - * suites. - * - Test rule's `after` function is not guaranteed to run in any particular order. - * - * @param name The name for the test rule (must be unique within the compilation unit) - * @param before_each_fn The callback function (ztest_rule_cb) to call before each test - * (may be NULL) - * @param after_each_fn The callback function (ztest_rule_cb) to call after each test (may be NULL) - */ -#define ZTEST_RULE(name, before_each_fn, after_each_fn) \ - static STRUCT_SECTION_ITERABLE(ztest_test_rule, z_ztest_test_rule_##name) = { \ - .before_each = (before_each_fn), \ - .after_each = (after_each_fn), \ - } - -extern struct ztest_test_rule _ztest_test_rule_list_start[]; -extern struct ztest_test_rule _ztest_test_rule_list_end[]; - -/** - * @brief A 'before' function to use in test suites that just need to start 1cpu - * - * Ignores data, and calls z_test_1cpu_start() - * - * @param data The test suite's data - */ -void ztest_simple_1cpu_before(void *data); - -/** - * @brief A 'after' function to use in test suites that just need to stop 1cpu - * - * Ignores data, and calls z_test_1cpu_stop() - * - * @param data The test suite's data - */ -void ztest_simple_1cpu_after(void *data); - -/** - * @brief Run the specified test suite. - * - * @param suite Test suite to run. - */ -#define ztest_run_test_suite(suite) z_ztest_run_test_suite(STRINGIFY(suite)) - -/** - * @brief Structure for architecture specific APIs - * - */ -struct ztest_arch_api { - void (*run_all)(const void *state); - bool (*should_suite_run)(const void *state, struct ztest_suite_node *suite); - bool (*should_test_run)(const char *suite, const char *test); -}; - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_TESTSUITE_ZTEST_TEST_H_ */ diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 04e16b97f92..b100921ab21 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -4,53 +4,65 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - - #include + #include #ifdef CONFIG_USERSPACE #include #endif -#include #include +#include #ifdef KERNEL static struct k_thread ztest_thread; #endif +static bool failed_expectation; -#ifdef CONFIG_ARCH_POSIX -#include +#ifdef CONFIG_ZTEST_SHUFFLE +#include +#include + +#include +#define NUM_ITER_PER_SUITE CONFIG_ZTEST_SHUFFLE_SUITE_REPEAT_COUNT +#define NUM_ITER_PER_TEST CONFIG_ZTEST_SHUFFLE_TEST_REPEAT_COUNT +#else +#define NUM_ITER_PER_SUITE 1 +#define NUM_ITER_PER_TEST 1 #endif /* ZTEST_DMEM and ZTEST_BMEM are used for the application shared memory test */ -ZTEST_DMEM enum { - TEST_PHASE_SETUP, - TEST_PHASE_TEST, - TEST_PHASE_TEARDOWN, - TEST_PHASE_FRAMEWORK -} phase = TEST_PHASE_FRAMEWORK; - -static ZTEST_BMEM int test_status; +/** + * @brief The current status of the test binary + */ +enum ztest_status { + ZTEST_STATUS_OK, + ZTEST_STATUS_HAS_FAILURE, + ZTEST_STATUS_CRITICAL_ERROR +}; /** - * @brief Try to shorten a filename by removing the current directory - * - * This helps to reduce the very long filenames in assertion failures. It - * removes the current directory from the filename and returns the rest. - * This makes assertions a lot more readable, and sometimes they fit on one - * line. - * - * @param file Filename to check - * @returns Shortened filename, or @file if it could not be shortened + * @brief Tracks the current phase that ztest is operating in. */ -const char *__weak ztest_relative_filename(const char *file) +ZTEST_DMEM enum ztest_phase cur_phase = TEST_PHASE_FRAMEWORK; + +static ZTEST_BMEM enum ztest_status test_status = ZTEST_STATUS_OK; + +extern ZTEST_DMEM const struct ztest_arch_api ztest_api; + +static void __ztest_show_suite_summary(void); + +static void end_report(void) { - return file; + __ztest_show_suite_summary(); + if (test_status) { + TC_END_REPORT(TC_FAIL); + } else { + TC_END_REPORT(TC_PASS); + } } -static int cleanup_test(struct unit_test *test) +static int cleanup_test(struct ztest_unit_test *test) { int ret = TC_PASS; int mock_status; @@ -68,12 +80,10 @@ static int cleanup_test(struct unit_test *test) #endif if (!ret && mock_status == 1) { - PRINT("Test %s failed: Unused mock parameter values\n", - test->name); + PRINT("Test %s failed: Unused mock parameter values\n", test->name); ret = TC_FAIL; } else if (!ret && mock_status == 2) { - PRINT("Test %s failed: Unused mock return values\n", - test->name); + PRINT("Test %s failed: Unused mock return values\n", test->name); ret = TC_FAIL; } else { ; @@ -89,6 +99,7 @@ static int cleanup_test(struct unit_test *test) #define CPUHOLD_STACK_SZ (512 + CONFIG_TEST_EXTRA_STACK_SIZE) static struct k_thread cpuhold_threads[MAX_NUM_CPUHOLD]; K_KERNEL_STACK_ARRAY_DEFINE(cpuhold_stacks, MAX_NUM_CPUHOLD, CPUHOLD_STACK_SZ); + static struct k_sem cpuhold_sem; volatile int cpuhold_active; @@ -139,23 +150,21 @@ void z_impl_z_test_1cpu_start(void) unsigned int num_cpus = arch_num_cpus(); cpuhold_active = 1; -#ifdef CONFIG_THREAD_NAME char tname[CONFIG_THREAD_MAX_NAME_LEN]; -#endif + k_sem_init(&cpuhold_sem, 0, 999); /* Spawn N-1 threads to "hold" the other CPUs, waiting for * each to signal us that it's locked and spinning. */ - for (int i = 0; i < num_cpus - 1; i++) { - k_thread_create(&cpuhold_threads[i], - cpuhold_stacks[i], CPUHOLD_STACK_SZ, - (k_thread_entry_t) cpu_hold, NULL, NULL, NULL, - K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); -#ifdef CONFIG_THREAD_NAME - snprintk(tname, CONFIG_THREAD_MAX_NAME_LEN, "cpuhold%02d", i); - k_thread_name_set(&cpuhold_threads[i], tname); -#endif + for (int i = 0; i < num_cpus - 1; i++) { + k_thread_create(&cpuhold_threads[i], cpuhold_stacks[i], CPUHOLD_STACK_SZ, + (k_thread_entry_t)cpu_hold, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, + 0, K_NO_WAIT); + if (IS_ENABLED(CONFIG_THREAD_NAME)) { + snprintk(tname, CONFIG_THREAD_MAX_NAME_LEN, "cpuhold%02d", i); + k_thread_name_set(&cpuhold_threads[i], tname); + } k_sem_take(&cpuhold_sem, K_FOREVER); } #endif @@ -168,36 +177,107 @@ void z_impl_z_test_1cpu_stop(void) cpuhold_active = 0; - /* Note that NUM_CPUHOLD can be a value that causes coverity - * to flag the following loop as DEADCODE so suppress the warning. - */ - for (int i = 0; i < num_cpus - 1; i++) { + for (int i = 0; i < num_cpus - 1; i++) { k_thread_abort(&cpuhold_threads[i]); } #endif } #ifdef CONFIG_USERSPACE -void z_vrfy_z_test_1cpu_start(void) -{ - z_impl_z_test_1cpu_start(); -} +void z_vrfy_z_test_1cpu_start(void) { z_impl_z_test_1cpu_start(); } #include -void z_vrfy_z_test_1cpu_stop(void) -{ - z_impl_z_test_1cpu_stop(); -} +void z_vrfy_z_test_1cpu_stop(void) { z_impl_z_test_1cpu_stop(); } #include #endif /* CONFIG_USERSPACE */ #endif -static void run_test_functions(struct unit_test *test) +__maybe_unused static void run_test_rules(bool is_before, struct ztest_unit_test *test, void *data) { - phase = TEST_PHASE_SETUP; - test->setup(); - phase = TEST_PHASE_TEST; - test->test(); + for (struct ztest_test_rule *rule = _ztest_test_rule_list_start; + rule < _ztest_test_rule_list_end; ++rule) { + if (is_before && rule->before_each) { + rule->before_each(test, data); + } else if (!is_before && rule->after_each) { + rule->after_each(test, data); + } + } +} + +static void run_test_functions(struct ztest_suite_node *suite, struct ztest_unit_test *test, + void *data) +{ + __ztest_set_test_phase(TEST_PHASE_TEST); + test->test(data); +} + +COND_CODE_1(KERNEL, (ZTEST_BMEM), ()) static enum ztest_result test_result; + +static int get_final_test_result(const struct ztest_unit_test *test, int ret) +{ + enum ztest_expected_result expected_result = -1; + + for (struct ztest_expected_result_entry *expectation = + _ztest_expected_result_entry_list_start; + expectation < _ztest_expected_result_entry_list_end; ++expectation) { + if (strcmp(expectation->test_name, test->name) == 0 && + strcmp(expectation->test_suite_name, test->test_suite_name) == 0) { + expected_result = expectation->expected_result; + break; + } + } + + if (expected_result == ZTEST_EXPECTED_RESULT_FAIL) { + /* Expected a failure: + * - If we got a failure, return TC_PASS + * - Otherwise force a failure + */ + return (ret == TC_FAIL) ? TC_PASS : TC_FAIL; + } + if (expected_result == ZTEST_EXPECTED_RESULT_SKIP) { + /* Expected a skip: + * - If we got a skip, return TC_PASS + * - Otherwise force a failure + */ + return (ret == TC_SKIP) ? TC_PASS : TC_FAIL; + } + /* No expectation was made, no change is needed. */ + return ret; +} + +/** + * @brief Get a friendly name string for a given test phrase. + * + * @param phase an enum ztest_phase value describing the desired test phase + * @returns a string name for `phase` + */ +static inline const char *get_friendly_phase_name(enum ztest_phase phase) +{ + switch (phase) { + case TEST_PHASE_SETUP: + return "setup"; + case TEST_PHASE_BEFORE: + return "before"; + case TEST_PHASE_TEST: + return "test"; + case TEST_PHASE_AFTER: + return "after"; + case TEST_PHASE_TEARDOWN: + return "teardown"; + case TEST_PHASE_FRAMEWORK: + return "framework"; + default: + return "(unknown)"; + } +} + +static bool current_test_failed_assumption; +void ztest_skip_failed_assumption(void) +{ + if (IS_ENABLED(CONFIG_ZTEST_FAIL_ON_ASSUME)) { + current_test_failed_assumption = true; + } + ztest_test_skip(); } #ifndef KERNEL @@ -210,78 +290,95 @@ static void run_test_functions(struct unit_test *test) */ #include /* parasoft-suppress MISRAC2012-RULE_21_4-a MISRAC2012-RULE_21_4-b*/ #include -#include #include +#include #define FAIL_FAST 0 static jmp_buf test_fail; -static jmp_buf test_skip; static jmp_buf test_pass; +static jmp_buf test_skip; static jmp_buf stack_fail; +static jmp_buf test_suite_fail; void ztest_test_fail(void) { - raise(SIGABRT); -} - -void ztest_test_skip(void) -{ - longjmp(test_skip, 1); + switch (cur_phase) { + case TEST_PHASE_SETUP: + PRINT(" at %s function\n", get_friendly_phase_name(cur_phase)); + longjmp(test_suite_fail, 1); + case TEST_PHASE_BEFORE: + case TEST_PHASE_TEST: + PRINT(" at %s function\n", get_friendly_phase_name(cur_phase)); + longjmp(test_fail, 1); + case TEST_PHASE_AFTER: + case TEST_PHASE_TEARDOWN: + case TEST_PHASE_FRAMEWORK: + PRINT(" ERROR: cannot fail in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + longjmp(stack_fail, 1); + } } void ztest_test_pass(void) { - longjmp(test_pass, 1); + if (cur_phase == TEST_PHASE_TEST) { + longjmp(test_pass, 1); + } + PRINT(" ERROR: cannot pass in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + longjmp(stack_fail, 1); } -static void handle_signal(int sig) +void ztest_test_skip(void) { - static const char *const phase_str[] = { - "setup", - "unit test", - "teardown", - }; - - PRINT(" %s", strsignal(sig)); - switch (phase) { + switch (cur_phase) { case TEST_PHASE_SETUP: + case TEST_PHASE_BEFORE: case TEST_PHASE_TEST: - case TEST_PHASE_TEARDOWN: - PRINT(" at %s function\n", phase_str[phase]); - longjmp(test_fail, 1); - case TEST_PHASE_FRAMEWORK: - PRINT("\n"); + longjmp(test_skip, 1); + default: + PRINT(" ERROR: cannot skip in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); longjmp(stack_fail, 1); } } -static void init_testing(void) +void ztest_test_expect_fail(void) { - signal(SIGABRT, handle_signal); - signal(SIGSEGV, handle_signal); + failed_expectation = true; - if (setjmp(stack_fail)) { - PRINT("TESTSUITE crashed."); - exit(1); + switch (cur_phase) { + case TEST_PHASE_SETUP: + PRINT(" at %s function\n", get_friendly_phase_name(cur_phase)); + break; + case TEST_PHASE_BEFORE: + case TEST_PHASE_TEST: + PRINT(" at %s function\n", get_friendly_phase_name(cur_phase)); + break; + case TEST_PHASE_AFTER: + case TEST_PHASE_TEARDOWN: + case TEST_PHASE_FRAMEWORK: + PRINT(" ERROR: cannot fail in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + longjmp(stack_fail, 1); } } -static int run_test(struct unit_test *test) +static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test, void *data) { int ret = TC_PASS; - int skip = 0; TC_START(test->name); - get_start_time_cyc(); + __ztest_set_test_phase(TEST_PHASE_BEFORE); - if (setjmp(test_fail)) { + if (test_result == ZTEST_RESULT_SUITE_FAIL) { ret = TC_FAIL; goto out; } - if (setjmp(test_skip)) { - skip = 1; + if (setjmp(test_fail)) { + ret = TC_FAIL; goto out; } @@ -290,15 +387,36 @@ static int run_test(struct unit_test *test) goto out; } - run_test_functions(test); + if (setjmp(test_skip)) { + ret = TC_SKIP; + goto out; + } + + run_test_rules(/*is_before=*/true, test, data); + if (suite->before) { + suite->before(data); + } + run_test_functions(suite, test, data); out: + if (failed_expectation) { + failed_expectation = false; + ret = TC_FAIL; + } + + __ztest_set_test_phase(TEST_PHASE_AFTER); + if (test_result != ZTEST_RESULT_SUITE_FAIL) { + if (suite->after != NULL) { + suite->after(data); + } + run_test_rules(/*is_before=*/false, test, data); + } + __ztest_set_test_phase(TEST_PHASE_FRAMEWORK); ret |= cleanup_test(test); - get_test_duration_ms(); - if (skip) { - Z_TC_END_RESULT(TC_SKIP, test->name); - } else { - Z_TC_END_RESULT(ret, test->name); + ret = get_final_test_result(test, ret); + Z_TC_END_RESULT(ret, test->name); + if (ret == TC_SKIP && current_test_failed_assumption) { + test_status = 1; } return ret; @@ -315,9 +433,7 @@ static int run_test(struct unit_test *test) #define FAIL_FAST 0 #endif -K_THREAD_STACK_DEFINE(ztest_thread_stack, CONFIG_ZTEST_STACK_SIZE + - CONFIG_TEST_EXTRA_STACK_SIZE); -static ZTEST_BMEM int test_result; +K_THREAD_STACK_DEFINE(ztest_thread_stack, CONFIG_ZTEST_STACK_SIZE + CONFIG_TEST_EXTRA_STACK_SIZE); static void test_finalize(void) { @@ -329,91 +445,174 @@ static void test_finalize(void) void ztest_test_fail(void) { - test_result = -1; - test_finalize(); + switch (cur_phase) { + case TEST_PHASE_SETUP: + __ztest_set_test_result(ZTEST_RESULT_SUITE_FAIL); + break; + case TEST_PHASE_BEFORE: + case TEST_PHASE_TEST: + __ztest_set_test_result(ZTEST_RESULT_FAIL); + test_finalize(); + break; + default: + PRINT(" ERROR: cannot fail in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + test_status = ZTEST_STATUS_CRITICAL_ERROR; + break; + } } void ztest_test_pass(void) { - test_result = 0; - test_finalize(); + switch (cur_phase) { + case TEST_PHASE_TEST: + __ztest_set_test_result(ZTEST_RESULT_PASS); + test_finalize(); + break; + default: + PRINT(" ERROR: cannot pass in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + test_status = ZTEST_STATUS_CRITICAL_ERROR; + if (cur_phase == TEST_PHASE_BEFORE) { + test_finalize(); + } + } } void ztest_test_skip(void) { - test_result = -2; - test_finalize(); + switch (cur_phase) { + case TEST_PHASE_SETUP: + __ztest_set_test_result(ZTEST_RESULT_SUITE_SKIP); + break; + case TEST_PHASE_BEFORE: + case TEST_PHASE_TEST: + __ztest_set_test_result(ZTEST_RESULT_SKIP); + test_finalize(); + break; + default: + PRINT(" ERROR: cannot skip in test phase '%s()', bailing\n", + get_friendly_phase_name(cur_phase)); + test_status = ZTEST_STATUS_CRITICAL_ERROR; + break; + } } -static void init_testing(void) +void ztest_test_expect_fail(void) { - k_object_access_all_grant(&ztest_thread); + failed_expectation = true; } -static void test_cb(void *a, void *dummy2, void *dummy) +void ztest_simple_1cpu_before(void *data) { - struct unit_test *test = (struct unit_test *)a; + ARG_UNUSED(data); + z_test_1cpu_start(); +} - ARG_UNUSED(dummy2); - ARG_UNUSED(dummy); +void ztest_simple_1cpu_after(void *data) +{ + ARG_UNUSED(data); + z_test_1cpu_stop(); +} - test_result = 1; - run_test_functions(test); - test_result = 0; +static void test_cb(void *a, void *b, void *c) +{ + struct ztest_suite_node *suite = a; + struct ztest_unit_test *test = b; + const bool config_user_mode = FIELD_GET(K_USER, test->thread_options) != 0; + + if (!IS_ENABLED(CONFIG_USERSPACE) || !k_is_user_context()) { + __ztest_set_test_result(ZTEST_RESULT_PENDING); + run_test_rules(/*is_before=*/true, test, /*data=*/c); + if (suite->before) { + suite->before(/*data=*/c); + } + if (IS_ENABLED(CONFIG_USERSPACE) && config_user_mode) { + k_thread_user_mode_enter(test_cb, a, b, c); + } + } + run_test_functions(suite, test, c); + __ztest_set_test_result(ZTEST_RESULT_PASS); } -static int run_test(struct unit_test *test) +static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test, void *data) { int ret = TC_PASS; +#if CONFIG_ZTEST_TEST_DELAY_MS > 0 + k_busy_wait(CONFIG_ZTEST_TEST_DELAY_MS * USEC_PER_MSEC); +#endif TC_START(test->name); - get_start_time_cyc(); + __ztest_set_test_phase(TEST_PHASE_BEFORE); + + /* If the suite's setup function marked us as skipped, don't bother + * running the tests. + */ if (IS_ENABLED(CONFIG_MULTITHREADING)) { + get_start_time_cyc(); k_thread_create(&ztest_thread, ztest_thread_stack, K_THREAD_STACK_SIZEOF(ztest_thread_stack), - (k_thread_entry_t) test_cb, (struct unit_test *)test, - NULL, NULL, CONFIG_ZTEST_THREAD_PRIORITY, - test->thread_options | K_INHERIT_PERMS, - K_FOREVER); + (k_thread_entry_t)test_cb, suite, test, data, + CONFIG_ZTEST_THREAD_PRIORITY, + K_INHERIT_PERMS, K_FOREVER); - k_thread_access_grant(&ztest_thread, test); + k_thread_access_grant(&ztest_thread, suite, test, suite->stats); if (test->name != NULL) { k_thread_name_set(&ztest_thread, test->name); } - k_thread_start(&ztest_thread); - k_thread_join(&ztest_thread, K_FOREVER); + /* Only start the thread if we're not skipping the suite */ + if (test_result != ZTEST_RESULT_SUITE_SKIP && + test_result != ZTEST_RESULT_SUITE_FAIL) { + k_thread_start(&ztest_thread); + k_thread_join(&ztest_thread, K_FOREVER); + } + } else if (test_result != ZTEST_RESULT_SUITE_SKIP && + test_result != ZTEST_RESULT_SUITE_FAIL) { + __ztest_set_test_result(ZTEST_RESULT_PENDING); + get_start_time_cyc(); + run_test_rules(/*is_before=*/true, test, data); + if (suite->before) { + suite->before(data); + } + run_test_functions(suite, test, data); + } - } else { - test_result = 1; - run_test_functions(test); + __ztest_set_test_phase(TEST_PHASE_AFTER); + if (suite->after != NULL) { + suite->after(data); } + run_test_rules(/*is_before=*/false, test, data); + get_test_duration_ms(); + if (tc_spend_time > test->stats->duration_worst_ms) { + test->stats->duration_worst_ms = tc_spend_time; + } - phase = TEST_PHASE_TEARDOWN; - test->teardown(); - phase = TEST_PHASE_FRAMEWORK; + __ztest_set_test_phase(TEST_PHASE_FRAMEWORK); /* Flush all logs in case deferred mode and default logging thread are used. */ while (IS_ENABLED(CONFIG_TEST_LOGGING_FLUSH_AFTER_TEST) && - IS_ENABLED(CONFIG_LOG_PROCESS_THREAD) && - log_data_pending()) { + IS_ENABLED(CONFIG_LOG_PROCESS_THREAD) && log_data_pending()) { k_msleep(100); } - if (test_result == -1) { + if (test_result == ZTEST_RESULT_FAIL || test_result == ZTEST_RESULT_SUITE_FAIL || + failed_expectation) { ret = TC_FAIL; + failed_expectation = false; + } else if (test_result == ZTEST_RESULT_SKIP || test_result == ZTEST_RESULT_SUITE_SKIP) { + ret = TC_SKIP; } - if (!test_result || !FAIL_FAST) { + if (test_result == ZTEST_RESULT_PASS || !FAIL_FAST) { ret |= cleanup_test(test); } - get_test_duration_ms(); - if (test_result == -2) { - Z_TC_END_RESULT(TC_SKIP, test->name); - } else { - Z_TC_END_RESULT(ret, test->name); + ret = get_final_test_result(test, ret); + Z_TC_END_RESULT(ret, test->name); + if (ret == TC_SKIP && current_test_failed_assumption) { + test_status = 1; } return ret; @@ -421,63 +620,330 @@ static int run_test(struct unit_test *test) #endif /* !KERNEL */ -int z_ztest_run_test_suite(const char *name, struct unit_test *suite) +static struct ztest_suite_node *ztest_find_test_suite(const char *name) { + struct ztest_suite_node *node; + + for (node = _ztest_suite_node_list_start; node < _ztest_suite_node_list_end; ++node) { + if (strcmp(name, node->name) == 0) { + return node; + } + } + + return NULL; +} + +struct ztest_unit_test *z_ztest_get_next_test(const char *suite, struct ztest_unit_test *prev) +{ + struct ztest_unit_test *test = (prev == NULL) ? _ztest_unit_test_list_start : prev + 1; + + for (; test < _ztest_unit_test_list_end; ++test) { + if (strcmp(suite, test->test_suite_name) == 0) { + return test; + } + } + return NULL; +} + +#ifdef CONFIG_ZTEST_SHUFFLE +static void z_ztest_shuffle(void *dest[], intptr_t start, size_t num_items, size_t element_size) +{ + void *tmp; + + /* Initialize dest array */ + for (size_t i = 0; i < num_items; ++i) { + dest[i] = (void *)(start + (i * element_size)); + } + + /* Shuffle dest array */ + for (size_t i = num_items - 1; i > 0; i--) { + int j = sys_rand32_get() % (i + 1); + + if (i != j) { + tmp = dest[j]; + dest[j] = dest[i]; + dest[i] = tmp; + } + } +} +#endif /* CONFIG_ZTEST_SHUFFLE */ + +static int z_ztest_run_test_suite_ptr(struct ztest_suite_node *suite) +{ + struct ztest_unit_test *test = NULL; + void *data = NULL; int fail = 0; + int tc_result = TC_PASS; - if (test_status < 0) { + if (FAIL_FAST && test_status != ZTEST_STATUS_OK) { return test_status; } - init_testing(); + if (suite == NULL) { + test_status = ZTEST_STATUS_CRITICAL_ERROR; + return -1; + } + +#ifndef KERNEL + if (setjmp(stack_fail)) { + PRINT("TESTSUITE crashed.\n"); + test_status = ZTEST_STATUS_CRITICAL_ERROR; + end_report(); + exit(1); + } +#else + k_object_access_all_grant(&ztest_thread); +#endif - TC_SUITE_START(name); - while (suite->test) { - fail += run_test(suite); - suite++; + TC_SUITE_START(suite->name); + current_test_failed_assumption = false; + __ztest_set_test_result(ZTEST_RESULT_PENDING); + __ztest_set_test_phase(TEST_PHASE_SETUP); +#ifndef KERNEL + if (setjmp(test_suite_fail)) { + __ztest_set_test_result(ZTEST_RESULT_SUITE_FAIL); + } +#endif + if (test_result != ZTEST_RESULT_SUITE_FAIL && suite->setup != NULL) { + data = suite->setup(); + } - if (fail && FAIL_FAST) { - break; + for (int i = 0; i < NUM_ITER_PER_TEST; i++) { + fail = 0; + +#ifdef CONFIG_ZTEST_SHUFFLE + struct ztest_unit_test *tests_to_run[ZTEST_TEST_COUNT]; + + memset(tests_to_run, 0, ZTEST_TEST_COUNT * sizeof(struct ztest_unit_test *)); + z_ztest_shuffle((void **)tests_to_run, (intptr_t)_ztest_unit_test_list_start, + ZTEST_TEST_COUNT, sizeof(struct ztest_unit_test)); + for (size_t j = 0; j < ZTEST_TEST_COUNT; ++j) { + test = tests_to_run[j]; + /* Make sure that the test belongs to this suite */ + if (strcmp(suite->name, test->test_suite_name) != 0) { + continue; + } + if (ztest_api.should_test_run(suite->name, test->name)) { + test->stats->run_count++; + tc_result = run_test(suite, test, data); + if (tc_result == TC_PASS) { + test->stats->pass_count++; + } else if (tc_result == TC_SKIP) { + test->stats->skip_count++; + } else if (tc_result == TC_FAIL) { + test->stats->fail_count++; + } + if (tc_result == TC_FAIL) { + fail++; + } + } + + if ((fail && FAIL_FAST) || test_status == ZTEST_STATUS_CRITICAL_ERROR) { + break; + } + } +#else + while (((test = z_ztest_get_next_test(suite->name, test)) != NULL)) { + if (ztest_api.should_test_run(suite->name, test->name)) { + test->stats->run_count++; + tc_result = run_test(suite, test, data); + if (tc_result == TC_PASS) { + test->stats->pass_count++; + } else if (tc_result == TC_SKIP) { + test->stats->skip_count++; + } else if (tc_result == TC_FAIL) { + test->stats->fail_count++; + } + + if (tc_result == TC_FAIL) { + fail++; + } + } + + if ((fail && FAIL_FAST) || test_status == ZTEST_STATUS_CRITICAL_ERROR) { + break; + } + } +#endif + + if (test_status == ZTEST_STATUS_OK && fail != 0) { + test_status = ZTEST_STATUS_HAS_FAILURE; } } - TC_SUITE_END(name, (fail > 0 ? TC_FAIL : TC_PASS)); - test_status = (test_status || fail) ? 1 : 0; + TC_SUITE_END(suite->name, (fail > 0 ? TC_FAIL : TC_PASS)); + __ztest_set_test_phase(TEST_PHASE_TEARDOWN); + if (suite->teardown != NULL) { + suite->teardown(data); + } return fail; } -void end_report(void) +int z_ztest_run_test_suite(const char *name) { - if (test_status) { - TC_END_REPORT(TC_FAIL); - } else { - TC_END_REPORT(TC_PASS); - } + return z_ztest_run_test_suite_ptr(ztest_find_test_suite(name)); } #ifdef CONFIG_USERSPACE K_APPMEM_PARTITION_DEFINE(ztest_mem_partition); #endif -int ztest_run_registered_test_suites(const void *state) +static void __ztest_init_unit_test_result_for_suite(struct ztest_suite_node *suite) { - struct ztest_suite_node *ptr; - int count = 0; + struct ztest_unit_test *test = NULL; + + while (((test = z_ztest_get_next_test(suite->name, test)) != NULL)) { + test->stats->run_count = 0; + test->stats->skip_count = 0; + test->stats->fail_count = 0; + test->stats->pass_count = 0; + test->stats->duration_worst_ms = 0; + } +} - for (ptr = _ztest_suite_node_list_start; ptr < _ztest_suite_node_list_end; ++ptr) { - struct ztest_suite_stats *stats = ptr->stats; - bool should_run = true; +static void flush_log(void) +{ + if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) { + while (log_data_pending()) { + k_sleep(K_MSEC(10)); + } + k_sleep(K_MSEC(10)); + } else { + while (LOG_PROCESS()) { + } + } +} - if (ptr->predicate != NULL) { - should_run = ptr->predicate(state); - } else { - /* If pragma is NULL, only run this test once. */ - should_run = stats->run_count == 0; +/* Show one line summary for a test suite. + */ +static void __ztest_show_suite_summary_oneline(struct ztest_suite_node *suite) +{ + int distinct_pass = 0, distinct_fail = 0, distinct_skip = 0, distinct_total = 0; + int effective_total = 0; + int expanded_pass = 0, expanded_passrate = 0; + int passrate_major = 0, passrate_minor = 0, passrate_tail = 0; + int suite_result = TC_PASS; + + struct ztest_unit_test *test = NULL; + unsigned int suite_duration_worst_ms = 0; + + /** summary of disctinct run */ + while (((test = z_ztest_get_next_test(suite->name, test)) != NULL)) { + distinct_total++; + suite_duration_worst_ms += test->stats->duration_worst_ms; + if (test->stats->skip_count == test->stats->run_count) { + distinct_skip++; + } else if (test->stats->pass_count == test->stats->run_count) { + distinct_pass++; + } else { + distinct_fail++; } + } - if (should_run) { - int fail = z_ztest_run_test_suite(ptr->name, ptr->suite); + if (distinct_skip == distinct_total) { + suite_result = TC_SKIP; + passrate_major = passrate_minor = 0; + } else { + suite_result = (distinct_fail > 0) ? TC_FAIL : TC_PASS; + effective_total = distinct_total - distinct_skip; + expanded_pass = distinct_pass * 100000; + expanded_passrate = expanded_pass / effective_total; + passrate_major = expanded_passrate / 1000; + passrate_minor = (expanded_passrate - passrate_major * 1000) / 10; + passrate_tail = expanded_passrate - passrate_major * 1000 - passrate_minor * 10; + if (passrate_tail >= 5) { /* rounding */ + passrate_minor++; + } + } + + TC_SUMMARY_PRINT("SUITE %s - %3d.%02d%% [%s]: pass = %d, fail = %d, " + "skip = %d, total = %d duration = %u.%03u seconds\n", + TC_RESULT_TO_STR(suite_result), + passrate_major, passrate_minor, + suite->name, distinct_pass, distinct_fail, + distinct_skip, distinct_total, + suite_duration_worst_ms / 1000, suite_duration_worst_ms % 1000); + flush_log(); +} + +static void __ztest_show_suite_summary_verbose(struct ztest_suite_node *suite) +{ + struct ztest_unit_test *test = NULL; + int tc_result = TC_PASS; + int flush_frequency = 0; + + if (IS_ENABLED(CONFIG_ZTEST_VERBOSE_SUMMARY) == 0) { + return; + } + + while (((test = z_ztest_get_next_test(suite->name, test)) != NULL)) { + if (test->stats->skip_count == test->stats->run_count) { + tc_result = TC_SKIP; + } else if (test->stats->pass_count == test->stats->run_count) { + tc_result = TC_PASS; + } else if (test->stats->pass_count == 0) { + tc_result = TC_FAIL; + } else { + tc_result = TC_FLAKY; + } + + if (tc_result == TC_FLAKY) { + TC_SUMMARY_PRINT(" - %s - [%s.%s] - (Failed %d of %d attempts)" + " - duration = %u.%03u seconds\n", + TC_RESULT_TO_STR(tc_result), + test->test_suite_name, test->name, + test->stats->run_count - test->stats->pass_count, + test->stats->run_count, + test->stats->duration_worst_ms / 1000, + test->stats->duration_worst_ms % 1000); + } else { + TC_SUMMARY_PRINT(" - %s - [%s.%s] duration = %u.%03u seconds\n", + TC_RESULT_TO_STR(tc_result), + test->test_suite_name, test->name, + test->stats->duration_worst_ms / 1000, + test->stats->duration_worst_ms % 1000); + } + + if (flush_frequency % 3 == 0) { + /** Reduce the flush frequencey a bit to speed up the output */ + flush_log(); + } + flush_frequency++; + } + TC_SUMMARY_PRINT("\n"); + flush_log(); +} + +static void __ztest_show_suite_summary(void) +{ + if (IS_ENABLED(CONFIG_ZTEST_SUMMARY) == 0) { + return; + } + /* Flush the log a lot to ensure that no summary content + * is dropped if it goes through the logging subsystem. + */ + flush_log(); + TC_SUMMARY_PRINT("\n------ TESTSUITE SUMMARY START ------\n\n"); + flush_log(); + for (struct ztest_suite_node *ptr = _ztest_suite_node_list_start; + ptr < _ztest_suite_node_list_end; ++ptr) { + + __ztest_show_suite_summary_oneline(ptr); + __ztest_show_suite_summary_verbose(ptr); + } + TC_SUMMARY_PRINT("------ TESTSUITE SUMMARY END ------\n\n"); + flush_log(); +} + +static int __ztest_run_test_suite(struct ztest_suite_node *ptr, const void *state) +{ + struct ztest_suite_stats *stats = ptr->stats; + int count = 0; + + for (int i = 0; i < NUM_ITER_PER_SUITE; i++) { + if (ztest_api.should_suite_run(state, ptr)) { + int fail = z_ztest_run_test_suite_ptr(ptr); count++; stats->run_count++; @@ -490,27 +956,121 @@ int ztest_run_registered_test_suites(const void *state) return count; } -void ztest_verify_all_registered_test_suites_ran(void) +int z_impl_ztest_run_test_suites(const void *state) +{ + int count = 0; + + if (test_status == ZTEST_STATUS_CRITICAL_ERROR) { + return count; + } + +#ifdef CONFIG_ZTEST_SHUFFLE + struct ztest_suite_node *suites_to_run[ZTEST_SUITE_COUNT]; + + memset(suites_to_run, 0, ZTEST_SUITE_COUNT * sizeof(struct ztest_suite_node *)); + z_ztest_shuffle((void **)suites_to_run, (intptr_t)_ztest_suite_node_list_start, + ZTEST_SUITE_COUNT, sizeof(struct ztest_suite_node)); + for (size_t i = 0; i < ZTEST_SUITE_COUNT; ++i) { + __ztest_init_unit_test_result_for_suite(suites_to_run[i]); + } + for (size_t i = 0; i < ZTEST_SUITE_COUNT; ++i) { + count += __ztest_run_test_suite(suites_to_run[i], state); + /* Stop running tests if we have a critical error or if we have a failure and + * FAIL_FAST was set + */ + if (test_status == ZTEST_STATUS_CRITICAL_ERROR || + (test_status == ZTEST_STATUS_HAS_FAILURE && FAIL_FAST)) { + break; + } + } +#else + for (struct ztest_suite_node *ptr = _ztest_suite_node_list_start; + ptr < _ztest_suite_node_list_end; ++ptr) { + __ztest_init_unit_test_result_for_suite(ptr); + count += __ztest_run_test_suite(ptr, state); + /* Stop running tests if we have a critical error or if we have a failure and + * FAIL_FAST was set + */ + if (test_status == ZTEST_STATUS_CRITICAL_ERROR || + (test_status == ZTEST_STATUS_HAS_FAILURE && FAIL_FAST)) { + break; + } + } +#endif + + return count; +} + +void z_impl___ztest_set_test_result(enum ztest_result new_result) +{ + test_result = new_result; +} + +void z_impl___ztest_set_test_phase(enum ztest_phase new_phase) +{ + cur_phase = new_phase; +} + +#ifdef CONFIG_USERSPACE +void z_vrfy___ztest_set_test_result(enum ztest_result new_result) +{ + z_impl___ztest_set_test_result(new_result); +} +#include + +void z_vrfy___ztest_set_test_phase(enum ztest_phase new_phase) +{ + z_impl___ztest_set_test_phase(new_phase); +} +#include +#endif /* CONFIG_USERSPACE */ + +void ztest_verify_all_test_suites_ran(void) { bool all_tests_run = true; - struct ztest_suite_node *ptr; + struct ztest_suite_node *suite; + struct ztest_unit_test *test; + + if (IS_ENABLED(CONFIG_ZTEST_VERIFY_RUN_ALL)) { + for (suite = _ztest_suite_node_list_start; suite < _ztest_suite_node_list_end; + ++suite) { + if (suite->stats->run_count < 1) { + PRINT("ERROR: Test suite '%s' did not run.\n", suite->name); + all_tests_run = false; + } + } - for (ptr = _ztest_suite_node_list_start; ptr < _ztest_suite_node_list_end; ++ptr) { - if (ptr->stats->run_count < 1) { - PRINT("ERROR: Test '%s' did not run.\n", ptr->name); - all_tests_run = false; + for (test = _ztest_unit_test_list_start; test < _ztest_unit_test_list_end; ++test) { + suite = ztest_find_test_suite(test->test_suite_name); + if (suite == NULL) { + PRINT("ERROR: Test '%s' assigned to test suite '%s' which doesn't " + "exist\n", + test->name, test->test_suite_name); + all_tests_run = false; + } + } + + if (!all_tests_run) { + test_status = ZTEST_STATUS_HAS_FAILURE; } } - if (!all_tests_run) { - test_status = 1; + for (test = _ztest_unit_test_list_start; test < _ztest_unit_test_list_end; ++test) { + if (test->stats->fail_count + test->stats->pass_count + test->stats->skip_count != + test->stats->run_count) { + PRINT("Bad stats for %s.%s\n", test->test_suite_name, test->name); + test_status = 1; + } } } +void ztest_run_all(const void *state) { ztest_api.run_all(state); } + void __weak test_main(void) { - ztest_run_registered_test_suites(NULL); - ztest_verify_all_registered_test_suites_ran(); + ztest_run_all(NULL); + + ztest_verify_all_test_suites_ran(); } #ifndef KERNEL @@ -519,45 +1079,41 @@ int main(void) z_init_mock(); test_main(); end_report(); +#ifdef CONFIG_ZTEST_NO_YIELD + /* + * Rather than yielding to idle thread, keep the part awake so debugger can + * still access it, since some SOCs cannot be debugged in low power states. + */ + uint32_t key = irq_lock(); + while (1) { + ; /* Spin */ + } + irq_unlock(key); +#endif return test_status; } #else int main(void) { #ifdef CONFIG_USERSPACE - int ret; - /* Partition containing globals tagged with ZTEST_DMEM and ZTEST_BMEM * macros. Any variables that user code may reference need to be * placed in this partition if no other memory domain configuration * is made. */ - ret = k_mem_domain_add_partition(&k_mem_domain_default, - &ztest_mem_partition); - if (ret != 0) { - PRINT("ERROR: failed to add ztest_mem_partition to mem domain (%d)\n", - ret); - k_oops(); - } + k_mem_domain_add_partition(&k_mem_domain_default, &ztest_mem_partition); #ifdef Z_MALLOC_PARTITION_EXISTS /* Allow access to malloc() memory */ - if (z_malloc_partition.size != 0) { - ret = k_mem_domain_add_partition(&k_mem_domain_default, - &z_malloc_partition); - if (ret != 0) { - PRINT("ERROR: failed to add z_malloc_partition" - " to mem domain (%d)\n", - ret); - k_oops(); - } - } + k_mem_domain_add_partition(&k_mem_domain_default, &z_malloc_partition); #endif #endif /* CONFIG_USERSPACE */ z_init_mock(); test_main(); end_report(); + flush_log(); + LOG_PANIC(); if (IS_ENABLED(CONFIG_ZTEST_RETEST_IF_PASSED)) { static __noinit struct { uint32_t magic; @@ -571,8 +1127,7 @@ int main(void) } state.boots += 1; if (test_status == 0) { - PRINT("Reset board #%u to test again\n", - state.boots); + PRINT("Reset board #%u to test again\n", state.boots); k_msleep(10); sys_reboot(SYS_REBOOT_COLD); } else { diff --git a/subsys/testsuite/ztest/src/ztest_posix.c b/subsys/testsuite/ztest/src/ztest_posix.c index fbfb3ed4137..d2c1857c04c 100644 --- a/subsys/testsuite/ztest/src/ztest_posix.c +++ b/subsys/testsuite/ztest/src/ztest_posix.c @@ -9,7 +9,7 @@ #include "cmdline.h" /* native_posix command line options header */ #include "soc.h" #include -#include +#include #include "nsi_host_trampolines.h" static const char *test_args; @@ -47,7 +47,7 @@ NATIVE_TASK(add_test_filter_option, PRE_BOOT_1, 10); * This makes assertions a lot more readable, and sometimes they fit on one * line. * - * Overrides implementation in ztest_new.c + * Overrides implementation in ztest.c * * @param file Filename to check * @returns Shortened filename, or @file if it could not be shortened @@ -176,7 +176,7 @@ static bool z_ztest_testargs_contains(const char *suite_name, const char *test_n * @brief Determines if the test case should run based on test cases listed * in the command line argument. * - * Overrides implementation in ztest_new.c + * Overrides implementation in ztest.c * * @param suite - name of test suite * @param test - name of unit test @@ -197,7 +197,7 @@ bool z_ztest_should_test_run(const char *suite, const char *test) * @brief Determines if the test suite should run based on test cases listed * in the command line argument. * - * Overrides implementation in ztest_new.c + * Overrides implementation in ztest.c * * @param state The current state of the machine as it relates to the test * executable. diff --git a/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c b/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c index 1996aba177a..08ea8bc1a79 100644 --- a/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c +++ b/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/tests/kernel/spinlock/src/spinlock_error_case.c b/tests/kernel/spinlock/src/spinlock_error_case.c index f40bc86f89d..b69e12a0d74 100644 --- a/tests/kernel/spinlock/src/spinlock_error_case.c +++ b/tests/kernel/spinlock/src/spinlock_error_case.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include diff --git a/tests/subsys/emul/src/main.c b/tests/subsys/emul/src/main.c index 7c18b6000f8..6ac1091827d 100644 --- a/tests/subsys/emul/src/main.c +++ b/tests/subsys/emul/src/main.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #define TEST_ACCEL DT_NODELABEL(test_bmi) From 719fee2bbc0510803cfcecb648e50be0a8c0465a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 00:24:43 +0000 Subject: [PATCH 2219/4498] doc: ztest: adapt ztest docs Remove remaining usage and documenation of dropped kconfig that is now the default. Signed-off-by: Anas Nashif --- doc/develop/test/ztest.rst | 8 ++------ samples/sample_definition_and_criteria.rst | 2 +- .../tests/dummy/agnostic/group1/subgroup1/prj.conf | 1 - .../tests/dummy/agnostic/group1/subgroup2/prj.conf | 1 - .../test_data/tests/dummy/agnostic/group2/prj.conf | 1 - .../test_data/tests/dummy/device/group/prj.conf | 1 - subsys/testsuite/ztest/include/zephyr/ztest_test.h | 3 --- 7 files changed, 3 insertions(+), 14 deletions(-) diff --git a/doc/develop/test/ztest.rst b/doc/develop/test/ztest.rst index 1eff49906bf..c7d3d23911e 100644 --- a/doc/develop/test/ztest.rst +++ b/doc/develop/test/ztest.rst @@ -10,10 +10,6 @@ test structure. The framework can be used in two ways, either as a generic framework for integration testing, or for unit testing specific modules. -To enable support for the latest Ztest API, set -:kconfig:option:`CONFIG_ZTEST_NEW_API` to ``y``. There is also a legacy API -that is deprecated and will eventually be removed. - Creating a test suite ********************* @@ -581,7 +577,7 @@ Shuffling Test Sequence By default the tests are sorted and ran in alphanumerical order. Test cases may be dependent on this sequence. Enable :kconfig:option:`CONFIG_ZTEST_SHUFFLE` to randomize the order. The output from the test will display the seed for failed -tests. For native posix builds you can provide the seed as an argument to +tests. For native simulator builds you can provide the seed as an argument to twister with `--seed` Static configuration of ZTEST_SHUFFLE contains: @@ -592,7 +588,7 @@ Static configuration of ZTEST_SHUFFLE contains: Test Selection ************** -For POSIX enabled builds with ZTEST_NEW_API use command line arguments to list +For tests built for native simulator, use command line arguments to list or select tests to run. The test argument expects a comma separated list of ``suite::test`` . You can substitute the test name with an ``*`` to run all tests within a suite. diff --git a/samples/sample_definition_and_criteria.rst b/samples/sample_definition_and_criteria.rst index 5a75496aff6..be0c9dfc3ef 100644 --- a/samples/sample_definition_and_criteria.rst +++ b/samples/sample_definition_and_criteria.rst @@ -19,7 +19,7 @@ Sample Criteria * The primary purpose of a sample is to provide a reference to the user. * Samples must not use Zephyr's testing framework. - * Must not use :kconfig:option:`CONFIG_ZTEST` or :kconfig:option:`CONFIG_ZTEST_NEW_API`. + * Must not use :kconfig:option:`CONFIG_ZTEST` * Must not use zasserts in samples. * If a sample can provide output that can be verified, then output should be evaluated against diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/prj.conf b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/prj.conf index 9228251051e..9467c292689 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/prj.conf +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/prj.conf b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/prj.conf index 9228251051e..9467c292689 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/prj.conf +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/prj.conf b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/prj.conf index 9228251051e..9467c292689 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/prj.conf +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/device/group/prj.conf b/scripts/tests/twister_blackbox/test_data/tests/dummy/device/group/prj.conf index 9228251051e..9467c292689 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/device/group/prj.conf +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/device/group/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/subsys/testsuite/ztest/include/zephyr/ztest_test.h b/subsys/testsuite/ztest/include/zephyr/ztest_test.h index a95a73ec4a0..aac7a7b2ad8 100644 --- a/subsys/testsuite/ztest/include/zephyr/ztest_test.h +++ b/subsys/testsuite/ztest/include/zephyr/ztest_test.h @@ -296,9 +296,6 @@ __syscall void __ztest_set_test_result(enum ztest_result new_result); __syscall void __ztest_set_test_phase(enum ztest_phase new_phase); #endif -#ifndef ZTEST_UNITTEST -#include -#endif /** * @brief Fails the test if any of the registered tests did not run. From 488e959f03ba35a8742b7330132ab90817848b72 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 12:07:23 +0000 Subject: [PATCH 2220/4498] manifest: zsclib module sha Remove usage of obsolete Kconfig in module. Signed-off-by: Anas Nashif --- submanifests/optional.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index e69781bdfb2..b6a913c41ac 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -54,7 +54,7 @@ manifest: - optional - name: zscilib path: modules/lib/zscilib - revision: 34c3432e81085bb717e4871d21ca419ae0058ec5 + revision: 34a94b0995683822fa3626dcd5d838301c94c350 remote: upstream groups: - optional From 76c73938e7950b1057ca94a07cc556e9f5169ec0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 10 Oct 2023 10:11:02 +0300 Subject: [PATCH 2221/4498] drivers: ncp5623: Fix error check num_colors cannot be not equal to different values at the same time. Signed-off-by: Andrei Emeltchenko --- drivers/led/ncp5623.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/led/ncp5623.c b/drivers/led/ncp5623.c index 3cb58d4bc48..0fd0f128d37 100644 --- a/drivers/led/ncp5623.c +++ b/drivers/led/ncp5623.c @@ -149,9 +149,10 @@ static int ncp5623_led_init(const struct device *dev) return -ENODEV; } - if (led_info->num_colors != 3 || led_info->num_colors != 1) { - LOG_ERR("%s: invalid number of colors %d (must be %d or 1)", dev->name, - led_info->num_colors, NCP5623_CHANNEL_COUNT); + if (led_info->num_colors != NCP5623_CHANNEL_COUNT) { + LOG_ERR("%s: invalid number of colors %d (must be %d with a single LED)", + dev->name, led_info->num_colors, NCP5623_CHANNEL_COUNT); + return -EINVAL; } } else if (config->num_leds <= 3) { /* three single-channel LEDs */ for (i = 0; i < config->num_leds; i++) { From 5551b4cfadc060e49be78a46cf80723300f12236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Tue, 10 Oct 2023 10:09:35 +0200 Subject: [PATCH 2222/4498] Bluetooth: Mesh: Priv net id parse on proxy cli MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds parsing of Private Network Identity parsing in the proxy client, allowing the client to use these messages to establish a GATT connection. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/proxy_cli.c | 124 ++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 23 deletions(-) diff --git a/subsys/bluetooth/mesh/proxy_cli.c b/subsys/bluetooth/mesh/proxy_cli.c index 54cbf9ab2e9..4b95e894c9c 100644 --- a/subsys/bluetooth/mesh/proxy_cli.c +++ b/subsys/bluetooth/mesh/proxy_cli.c @@ -27,6 +27,7 @@ #include "proxy.h" #include "gatt_cli.h" #include "proxy_msg.h" +#include "crypto.h" #define LOG_LEVEL CONFIG_BT_MESH_PROXY_LOG_LEVEL #include @@ -157,14 +158,9 @@ static const struct bt_mesh_gatt_cli proxy = { .disconnected = proxy_disconnected }; -struct find_net_id { - const uint8_t *net_id; - struct bt_mesh_proxy_server *srv; -}; - -static bool has_net_id(struct bt_mesh_subnet *sub, void *user_data) +static bool proxy_srv_check_and_get(struct bt_mesh_subnet *sub, const uint8_t *net_id, + struct bt_mesh_proxy_server **p_srv) { - struct find_net_id *res = user_data; struct bt_mesh_proxy_server *srv; srv = find_proxy_srv(sub->net_idx, true, true); @@ -183,43 +179,125 @@ static bool has_net_id(struct bt_mesh_subnet *sub, void *user_data) } } - if (!memcmp(sub->keys[0].net_id, res->net_id, 8) || - (bt_mesh_subnet_has_new_key(sub) && - !memcmp(sub->keys[1].net_id, res->net_id, 8))) { - res->srv = srv; + /* If net_id is NULL we already know that the networks match */ + if (!net_id || !memcmp(sub->keys[0].net_id, net_id, 8) || + (bt_mesh_subnet_has_new_key(sub) && !memcmp(sub->keys[1].net_id, net_id, 8))) { + + *p_srv = srv; return true; } return false; } -void bt_mesh_proxy_cli_adv_recv(const struct bt_le_scan_recv_info *info, - struct net_buf_simple *buf) -{ +struct find_net_id { uint8_t type; + + union { + const uint8_t *net_id; + struct { + const uint8_t *hash; + const uint8_t *rand; + } priv; + } data; + + struct bt_mesh_proxy_server *srv; +}; + +static bool is_hash_equal(struct bt_mesh_subnet *sub, struct find_net_id *res, uint8_t idx) +{ + int err; + uint8_t in[16], out[16]; + + memcpy(&in[0], sub->keys[idx].net_id, 8); + memcpy(&in[8], res->data.priv.rand, 8); + err = bt_mesh_encrypt(&sub->keys[idx].identity, in, out); + if (err) { + LOG_ERR("Failed to generate hash (err: %d)", err); + return false; + } + + if (memcmp(&out[8], res->data.priv.hash, 8)) { + return false; + } + + return true; +} + +static bool has_net_id(struct bt_mesh_subnet *sub, void *user_data) +{ + struct find_net_id *res = user_data; + uint8_t *net_id = NULL; + + if (res->type == BT_MESH_ID_TYPE_NET) { + net_id = (uint8_t *)res->data.net_id; + goto end; + } + + /* Additional handling for BT_MESH_ID_TYPE_PRIV_NET msg type */ + if (!(is_hash_equal(sub, res, 0) || + (bt_mesh_subnet_has_new_key(sub) && is_hash_equal(sub, res, 1)))) { + return false; + } +end: + return proxy_srv_check_and_get(sub, net_id, &res->srv); +} + +static void handle_net_id(uint8_t type, const struct bt_le_scan_recv_info *info, + struct net_buf_simple *buf) +{ + int err; struct find_net_id res; struct bt_mesh_subnet *sub; - type = net_buf_simple_pull_u8(buf); - switch (type) { - case BT_MESH_ID_TYPE_NET: + res.type = type; + res.srv = NULL; + + if (type == BT_MESH_ID_TYPE_NET) { if (buf->len != 8) { - break; + return; } + res.data.net_id = net_buf_simple_pull_mem(buf, 8); - res.net_id = net_buf_simple_pull_mem(buf, 8); - res.srv = NULL; + } else { + if (buf->len != 16) { + return; + } + + res.data.priv.hash = net_buf_simple_pull_mem(buf, 8); + res.data.priv.rand = net_buf_simple_pull_mem(buf, 8); + } - sub = bt_mesh_subnet_find(has_net_id, (void *)&res); - if (sub && res.srv) { - (void)bt_mesh_gatt_cli_connect(info->addr, &proxy, res.srv); + sub = bt_mesh_subnet_find(has_net_id, (void *)&res); + if (sub && res.srv) { + err = bt_mesh_gatt_cli_connect(info->addr, &proxy, res.srv); + if (err) { + LOG_DBG("Failed to connect over GATT (err:%d)", err); } + } +} + +void bt_mesh_proxy_cli_adv_recv(const struct bt_le_scan_recv_info *info, + struct net_buf_simple *buf) +{ + uint8_t type; + type = net_buf_simple_pull_u8(buf); + switch (type) { + case BT_MESH_ID_TYPE_NET: + /* Fallthrough */ + case BT_MESH_ID_TYPE_PRIV_NET: { + handle_net_id(type, info, buf); break; + } case BT_MESH_ID_TYPE_NODE: { /* TODO */ break; } + case BT_MESH_ID_TYPE_PRIV_NODE: { + /* TODO */ + break; + } default: return; } From 6f2ebb963a3e7f67cf774287263c740d7475a597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 11 Oct 2023 16:19:57 +0200 Subject: [PATCH 2223/4498] Bluetooth: Mesh: Add proxy test API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds internal proxy API to enhance testabillity of the proxy implementation. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/proxy.h | 1 + subsys/bluetooth/mesh/proxy_cli.c | 9 +++++++++ subsys/bluetooth/mesh/proxy_cli.h | 2 ++ subsys/bluetooth/mesh/proxy_srv.c | 13 +++++++++++++ 4 files changed, 25 insertions(+) diff --git a/subsys/bluetooth/mesh/proxy.h b/subsys/bluetooth/mesh/proxy.h index 7f06be8f13f..a2f6bb45ff6 100644 --- a/subsys/bluetooth/mesh/proxy.h +++ b/subsys/bluetooth/mesh/proxy.h @@ -36,3 +36,4 @@ void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst); void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, uint16_t addr); +uint8_t bt_mesh_proxy_srv_connected_cnt(void); diff --git a/subsys/bluetooth/mesh/proxy_cli.c b/subsys/bluetooth/mesh/proxy_cli.c index 4b95e894c9c..a0a25751b41 100644 --- a/subsys/bluetooth/mesh/proxy_cli.c +++ b/subsys/bluetooth/mesh/proxy_cli.c @@ -391,3 +391,12 @@ static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) BT_MESH_SUBNET_CB_DEFINE(proxy_cli) = { .evt_handler = subnet_evt, }; + +bool bt_mesh_proxy_cli_is_connected(uint16_t net_idx) +{ + if (find_proxy_srv(net_idx, true, false)) { + return true; + } + + return false; +} diff --git a/subsys/bluetooth/mesh/proxy_cli.h b/subsys/bluetooth/mesh/proxy_cli.h index 9f8ec96458d..8c1fae10e84 100644 --- a/subsys/bluetooth/mesh/proxy_cli.h +++ b/subsys/bluetooth/mesh/proxy_cli.h @@ -9,3 +9,5 @@ void bt_mesh_proxy_cli_adv_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf); bool bt_mesh_proxy_cli_relay(struct net_buf *buf); + +bool bt_mesh_proxy_cli_is_connected(uint16_t net_idx); diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 12775b93651..4e260f8e937 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -1157,3 +1157,16 @@ BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = gatt_connected, .disconnected = gatt_disconnected, }; + +uint8_t bt_mesh_proxy_srv_connected_cnt(void) +{ + uint8_t cnt = 0; + + for (int i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].cli) { + cnt++; + } + } + + return cnt; +} From 49bd77ad54cb25d3c83c93d7f262e5fa34dd2a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Tue, 10 Oct 2023 10:12:28 +0200 Subject: [PATCH 2224/4498] tests: Bluetooth: Mesh: Priv Proxy GATT test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test verifying that Private Beacons are received over a GATT proxy connection. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/overlay_gatt.conf | 2 + tests/bsim/bluetooth/mesh/src/mesh_test.h | 17 +++++ tests/bsim/bluetooth/mesh/src/test_beacon.c | 66 +++++++++++++++++++ .../priv_beacon/priv_proxy_gatt.sh | 30 +++++++++ 4 files changed, 115 insertions(+) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_gatt.sh diff --git a/tests/bsim/bluetooth/mesh/overlay_gatt.conf b/tests/bsim/bluetooth/mesh/overlay_gatt.conf index a8ecf87d113..f94a26d623f 100644 --- a/tests/bsim/bluetooth/mesh/overlay_gatt.conf +++ b/tests/bsim/bluetooth/mesh/overlay_gatt.conf @@ -4,3 +4,5 @@ CONFIG_BT_MESH_PB_GATT=y CONFIG_BT_MESH_LOW_POWER=n CONFIG_BT_MESH_FRIEND=n +CONFIG_BT_CENTRAL=y +CONFIG_BT_MESH_PROXY_CLIENT=y diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index cfcf5a838dc..08cf2177796 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -122,6 +122,23 @@ } \ } while (0) +#define WAIT_FOR_COND(cond, wait) \ + do { \ + bool _err = false; \ + for (uint8_t sec = (wait); !(cond); sec--) { \ + if (!sec) { \ + _err = true; \ + break; \ + } \ + k_sleep(K_SECONDS(1)); \ + } \ + \ + if (_err) { \ + bst_result = Failed; \ + bs_trace_error_time_line("Waiting for " #cond " timed out\n"); \ + } \ + } while (0) + struct bt_mesh_test_cfg { uint16_t addr; uint8_t dev_key[16]; diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index fd2477f3907..1313791d7bb 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -13,6 +13,8 @@ #include "mesh/foundation.h" #include "mesh/crypto.h" #include "argparse.h" +#include "mesh/proxy_cli.h" +#include "mesh/proxy.h" #define LOG_MODULE_NAME test_beacon @@ -1695,6 +1697,68 @@ static void test_rx_priv_multi_net_id(void) PASS(); } + +static void test_tx_priv_gatt_proxy(void) +{ + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_device_setup(&prov, &prb_comp); + provision(&tx_cfg); + bt_mesh_iv_update_test(true); + + ASSERT_TRUE(bt_mesh.iv_index == 0); + + /* Disable SNB. */ + bt_mesh_beacon_set(false); + ASSERT_OK_MSG(bt_mesh_scan_disable(), "Failed to disable scanner"); + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), + "Failed to disable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_PRIV_GATT_PROXY_ENABLED), + "Failed to set private gatt proxy"); + + /* Wait for proxy connection to complete. */ + WAIT_FOR_COND(bt_mesh_proxy_srv_connected_cnt() == 1, 10); + + /* Wait a bit so RX device can disable scanner, then start IV update */ + k_sleep(K_SECONDS(2)); + ASSERT_TRUE(bt_mesh_iv_update()); + + /* Check that IV index has updated */ + ASSERT_TRUE(bt_mesh.iv_index == 1); + PASS(); +} + +static void test_rx_priv_gatt_proxy(void) +{ + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_device_setup(&prov, &prb_comp); + provision(&rx_cfg); + bt_mesh_iv_update_test(true); + + ASSERT_TRUE(bt_mesh.iv_index == 0); + + /* Disable SNB. */ + bt_mesh_beacon_set(false); + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), + "Failed to disable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_PRIV_GATT_PROXY_ENABLED), + "Failed to set private gatt proxy"); + ASSERT_OK_MSG(bt_mesh_proxy_connect(TEST_NET_IDX1), "Failed to connect over proxy"); + + /* Wait for connection to complete, then disable scanner + * to ensure that all RX communication arrives over GATT. + */ + WAIT_FOR_COND(bt_mesh_proxy_cli_is_connected(TEST_NET_IDX1), 10); + ASSERT_OK_MSG(bt_mesh_scan_disable(), "Failed to disable scanner"); + + /* Wait for the IV index to update. + * Verifying that IV index has changed proves that a private + * beacon arrived successfully over the GATT connection. + */ + WAIT_FOR_COND(bt_mesh.iv_index == 1, 10); + + PASS(); +} + #endif #endif /* CONFIG_BT_MESH_V1d1 */ @@ -1726,6 +1790,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(tx, priv_net_id, "Private Proxy: advertise Net ID"), TEST_CASE(tx, priv_node_id, "Private Proxy: advertise Node ID"), TEST_CASE(tx, priv_multi_net_id, "Private Proxy: advertise multiple Net ID"), + TEST_CASE(tx, priv_gatt_proxy, "Private Proxy: Send Private Beacons over GATT"), #endif #endif @@ -1743,6 +1808,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(rx, priv_net_id, "Private Proxy: scan for Net ID"), TEST_CASE(rx, priv_node_id, "Private Proxy: scan for Node ID"), TEST_CASE(rx, priv_multi_net_id, "Private Proxy: scan for multiple Net ID"), + TEST_CASE(rx, priv_gatt_proxy, "Private Proxy: Receive Private Beacons over GATT"), #endif #endif BSTEST_END_MARKER diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_gatt.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_gatt.sh new file mode 100755 index 00000000000..a1b9ea7d8d6 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_proxy_gatt.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Private over GATT connection +# +# Test procedure: +# 0. Both TX and RX device disables SNB and GATT proxy, and enables +# Private GATT proxy. Test mode for IV update is also enabled on both devices. +# 1. The RX device (Proxy CLI) establish a GATT connection to the TX device +# (Proxy SRV), using Private Network Identity. +# 2. Both TX and RX device disables the scanner to prevent interferance +# by the adv bearer. +# 3. The TX device (Proxy SRV) starts an IV update procedure. +# 4. Both TX and RX device verifies that the IV index has been updated. +# This proves that the RX device (Proxy CLI) successfully received +# a Private beacon over the GATT connection +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf +RunTest mesh_priv_proxy_gatt_priv_beacon \ + beacon_tx_priv_gatt_proxy \ + beacon_rx_priv_gatt_proxy + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_priv_proxy_gatt_priv_beacon \ + beacon_tx_priv_gatt_proxy \ + beacon_rx_priv_gatt_proxy From 3b58fec96c0abf147e07f63067b09762b9071b03 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 10 Oct 2023 14:38:32 +0200 Subject: [PATCH 2225/4498] Bluetooth: CAP: Add size and rank checks for CAS register For the CAP acceptor the size and rank characteristic shall be set as per the CAP spec. Add checks for 0, as 0 indicates not initializing the characteristics in the CSIS instance. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/cap_acceptor.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/subsys/bluetooth/audio/cap_acceptor.c b/subsys/bluetooth/audio/cap_acceptor.c index db32d382e2a..56ed5fa2daa 100644 --- a/subsys/bluetooth/audio/cap_acceptor.c +++ b/subsys/bluetooth/audio/cap_acceptor.c @@ -27,6 +27,16 @@ int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *par static struct bt_gatt_service cas; int err; + CHECKIF(param->set_size == 0U) { + LOG_DBG("param->set_size shall be non-zero"); + return -EINVAL; + } + + CHECKIF(param->rank == 0U) { + LOG_DBG("param->rank shall be non-zero"); + return -EINVAL; + } + err = bt_csip_set_member_register(param, svc_inst); if (err != 0) { LOG_DBG("Failed to register CSIP"); From 7d96c997e2989d9cc1183a9a868e887d02748026 Mon Sep 17 00:00:00 2001 From: Troels Nilsson Date: Tue, 10 Oct 2023 16:01:47 +0200 Subject: [PATCH 2226/4498] Bluetooth: Controller: Fix endianness issues for SyncInfo Fix bitfield crossing byte boundary - replaced with macros for setting/getting the values Fix missing endianness conversion for evt_cntr Changed aa from uint32_t to uint8_t[4] to align with the rest of the code and avoid any potential endianness issues Signed-off-by: Troels Nilsson --- subsys/bluetooth/controller/hci/hci.c | 8 ++--- subsys/bluetooth/controller/ll_sw/pdu.h | 34 ++++++++++++------- .../bluetooth/controller/ll_sw/ull_adv_sync.c | 25 +++++++------- subsys/bluetooth/controller/ll_sw/ull_sync.c | 10 +++--- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index c3dd070720b..7b1a3b86589 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -7053,10 +7053,10 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, LOG_DBG(" SyncInfo offs = %u, offs_unit = 0x%x, " "interval = 0x%x, sca = 0x%x, " "chan map = 0x%x 0x%x 0x%x 0x%x 0x%x, " - "AA = 0x%x, CRC = 0x%x 0x%x 0x%x, " + "AA = 0x%x%x%x%x, CRC = 0x%x 0x%x 0x%x, " "evt cntr = 0x%x", - sys_le16_to_cpu(si->offs), - si->offs_units, + PDU_ADV_SYNC_INFO_OFFSET_GET(si), + PDU_ADV_SYNC_INFO_OFFS_UNITS_GET(si), sys_le16_to_cpu(si->interval), ((si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] & PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK) >> @@ -7065,7 +7065,7 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, si->sca_chm[3], (si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] & ~PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK), - sys_le32_to_cpu(si->aa), + si->aa[3], si->aa[2], si->aa[1], si->aa[0], si->crc_init[0], si->crc_init[1], si->crc_init[2], sys_le16_to_cpu(si->evt_cntr)); } diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index 93e50e1ebcc..fe6fa8494f5 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -225,6 +225,19 @@ (((aux_ptr)->offs_phy_packed[1] & 0x1F) << 8)) #define PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) (((aux_ptr)->offs_phy_packed[1] >> 5) & 0x07) +/* Macros for getting/setting offset/offset_units/offset_adjust from pdu_adv_sync_info */ +#define PDU_ADV_SYNC_INFO_OFFSET_GET(si) ((si)->offs_packed[0] | \ + (((si)->offs_packed[1] & 0x1F) << 8)) +#define PDU_ADV_SYNC_INFO_OFFS_UNITS_GET(si) (((si)->offs_packed[1] >> 5) & 0x01) +#define PDU_ADV_SYNC_INFO_OFFS_ADJUST_GET(si) (((si)->offs_packed[1] >> 6) & 0x01) +#define PDU_ADV_SYNC_INFO_OFFS_SET(si, offs, offs_units, offs_adjust) \ + do { \ + (si)->offs_packed[0] = (offs) & 0xFF; \ + (si)->offs_packed[1] = (((offs) >> 8) & 0x1F) + \ + (((offs_units) << 5) & 0x20) + \ + (((offs_adjust) << 6) & 0x40); \ + } while (0) + /* Advertiser's Sleep Clock Accuracy Value */ #define SCA_500_PPM 500 /* 51 ppm to 500 ppm */ #define SCA_50_PPM 50 /* 0 ppm to 50 ppm */ @@ -488,20 +501,17 @@ enum pdu_adv_aux_phy { }; struct pdu_adv_sync_info { -#ifdef CONFIG_LITTLE_ENDIAN - uint16_t offs:13; - uint16_t offs_units:1; - uint16_t offs_adjust:1; - uint16_t rfu:1; -#else - uint16_t rfu:1; - uint16_t offs_adjust:1; - uint16_t offs_units:1; - uint16_t offs:13; -#endif /* CONFIG_LITTLE_ENDIAN */ + /* offs:13 + * offs_units:1 + * offs_adjust:1 + * rfu:1 + * NOTE: This layout as bitfields is not portable for BE using + * endianness conversion macros. + */ + uint8_t offs_packed[2]; uint16_t interval; uint8_t sca_chm[PDU_CHANNEL_MAP_SIZE]; - uint32_t aa; + uint8_t aa[4]; uint8_t crc_init[3]; uint16_t evt_cntr; } __packed; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c index f1f521ca235..5fec8a37534 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c @@ -1348,9 +1348,7 @@ void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync, * If sync_info is part of ADV PDU the offs_adjust field * is always set to 0. */ - si->offs_units = OFFS_UNIT_VALUE_30_US; - si->offs_adjust = 0U; - si->offs = 0U; + PDU_ADV_SYNC_INFO_OFFS_SET(si, 0U, OFFS_UNIT_VALUE_30_US, 0U); /* Fill the interval, access address and CRC init */ si->interval = sys_cpu_to_le16(sync->interval); @@ -2207,18 +2205,19 @@ void ull_adv_sync_lll_syncinfo_fill(struct pdu_adv *pdu, struct lll_adv_aux *lll static void sync_info_offset_fill(struct pdu_adv_sync_info *si, uint32_t offs) { + uint8_t offs_adjust = 0U; + if (offs >= OFFS_ADJUST_US) { offs -= OFFS_ADJUST_US; - si->offs_adjust = 1U; + offs_adjust = 1U; } offs = offs / OFFS_UNIT_30_US; if (!!(offs >> OFFS_UNIT_BITS)) { - si->offs = sys_cpu_to_le16(offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US)); - si->offs_units = OFFS_UNIT_VALUE_300_US; + PDU_ADV_SYNC_INFO_OFFS_SET(si, offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US), + OFFS_UNIT_VALUE_300_US, offs_adjust); } else { - si->offs = sys_cpu_to_le16(offs); - si->offs_units = OFFS_UNIT_VALUE_30_US; + PDU_ADV_SYNC_INFO_OFFS_SET(si, offs, OFFS_UNIT_VALUE_30_US, offs_adjust); } } @@ -2328,22 +2327,22 @@ static void sync_info_offset_fill(struct pdu_adv_sync_info *si, uint32_t remainder_us, uint32_t start_us) { + uint8_t offs_adjust = 0U; uint32_t offs; offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us; if (offs >= OFFS_ADJUST_US) { offs -= OFFS_ADJUST_US; - si->offs_adjust = 1U; + offs_adjust = 1U; } offs = offs / OFFS_UNIT_30_US; if (!!(offs >> OFFS_UNIT_BITS)) { - si->offs = sys_cpu_to_le16(offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US)); - si->offs_units = OFFS_UNIT_VALUE_300_US; + PDU_ADV_SYNC_INFO_OFFS_SET(si, offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US), + OFFS_UNIT_VALUE_300_US, offs_adjust); } else { - si->offs = sys_cpu_to_le16(offs); - si->offs_units = OFFS_UNIT_VALUE_30_US; + PDU_ADV_SYNC_INFO_OFFS_SET(si, offs, OFFS_UNIT_VALUE_30_US, offs_adjust); } } diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 265475196fd..18ec492621c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -711,10 +711,10 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, * CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT */ - memcpy(lll->access_addr, &si->aa, sizeof(lll->access_addr)); + memcpy(lll->access_addr, si->aa, sizeof(lll->access_addr)); lll->data_chan_id = lll_chan_id(lll->access_addr); memcpy(lll->crc_init, si->crc_init, sizeof(lll->crc_init)); - lll->event_counter = si->evt_cntr; + lll->event_counter = sys_le16_to_cpu(si->evt_cntr); lll->phy = aux->lll.phy; interval = sys_le16_to_cpu(si->interval); @@ -762,7 +762,7 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, lll_clock_ppm_get(sca)) * interval_us), USEC_PER_SEC); lll->window_widening_max_us = (interval_us >> 1) - EVENT_IFS_US; - if (si->offs_units) { + if (PDU_ADV_SYNC_INFO_OFFS_UNITS_GET(si)) { lll->window_size_event_us = OFFS_UNIT_300_US; } else { lll->window_size_event_us = OFFS_UNIT_30_US; @@ -809,10 +809,10 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, 1); sync_offset_us = ftr->radio_end_us; - sync_offset_us += (uint32_t)sys_le16_to_cpu(si->offs) * + sync_offset_us += PDU_ADV_SYNC_INFO_OFFSET_GET(si) * lll->window_size_event_us; /* offs_adjust may be 1 only if sync setup by LL_PERIODIC_SYNC_IND */ - sync_offset_us += (si->offs_adjust ? OFFS_ADJUST_US : 0U); + sync_offset_us += (PDU_ADV_SYNC_INFO_OFFS_ADJUST_GET(si) ? OFFS_ADJUST_US : 0U); sync_offset_us -= PDU_AC_US(pdu->len, lll->phy, ftr->phy_flags); sync_offset_us -= EVENT_TICKER_RES_MARGIN_US; sync_offset_us -= EVENT_JITTER_US; From 5d113be3411fe5cfedb58f5e8d5d67541b5fb401 Mon Sep 17 00:00:00 2001 From: Lukasz Hawrylko Date: Tue, 10 Oct 2023 16:44:03 +0200 Subject: [PATCH 2227/4498] drivers: crypto: add support for stm32wb family STM32WB MCUs have two AES peripherals: AES1 for application use and AES2 dedicated for network stack. This patch modifies stm32 crypto driver to use AES1 peripheral when building for STM32WB. Signed-off-by: Lukasz Hawrylko --- drivers/crypto/crypto_stm32.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/crypto/crypto_stm32.c b/drivers/crypto/crypto_stm32.c index ca80b2afe35..17250a944a9 100644 --- a/drivers/crypto/crypto_stm32.c +++ b/drivers/crypto/crypto_stm32.c @@ -43,8 +43,13 @@ LOG_MODULE_REGISTER(crypto_stm32); #define STM32_RCC_CRYPTO_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET #define STM32_CRYPTO_TYPEDEF CRYP_TypeDef #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_aes) +#if defined(CONFIG_SOC_SERIES_STM32WBX) +#define STM32_RCC_CRYPTO_FORCE_RESET __HAL_RCC_AES1_FORCE_RESET +#define STM32_RCC_CRYPTO_RELEASE_RESET __HAL_RCC_AES1_RELEASE_RESET +#else #define STM32_RCC_CRYPTO_FORCE_RESET __HAL_RCC_AES_FORCE_RESET #define STM32_RCC_CRYPTO_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#endif #define STM32_CRYPTO_TYPEDEF AES_TypeDef #endif From 6424949dfd719ca74e59a5e07f0bd18d292ae086 Mon Sep 17 00:00:00 2001 From: Lukasz Hawrylko Date: Tue, 10 Oct 2023 16:49:57 +0200 Subject: [PATCH 2228/4498] dts: arm: stm32: add AES1 peripheral to stm32wb family STM32WB MCUs has two AES peripeherals. Add AES1 definition, AES2 must not be used by application CPU core. Signed-off-by: Lukasz Hawrylko --- dts/arm/st/wb/stm32wb.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index 63687c09e8d..f6a1c785b86 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -501,6 +501,14 @@ clocks = <&rcc STM32_CLOCK_BUS_AHB3 0x00040000>; status = "disabled"; }; + + aes1: aes@50060000 { + compatible = "st,stm32-aes"; + reg = <0x50060000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00010000>; + interrupts = <51 0>; + status = "disabled"; + }; }; die_temp: dietemp { From a422e1d8fbf56db2a4d5b8c9a8e1802e54936978 Mon Sep 17 00:00:00 2001 From: Lukasz Hawrylko Date: Tue, 10 Oct 2023 16:51:19 +0200 Subject: [PATCH 2229/4498] boards: arm: nucleo_wb55rg: enable aes1 Enable AES1 peripheral by default to add support for drivers/crypto sample. Signed-off-by: Lukasz Hawrylko --- boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts index b92c921df38..eed2cef9368 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts @@ -202,6 +202,10 @@ zephyr_udc0: &usb { status = "okay"; }; +&aes1 { + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; From 779f725db30c64eb60a201bef8a0d3bf76d8f44a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 11 Oct 2023 10:09:46 +0200 Subject: [PATCH 2230/4498] Bluetooth: CAP: Add verification of CCIDs as the initiator When the initiator provides CCID in the metadata, we verify that the CCIDs exist on the device. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/cap_initiator.c | 36 ++++++++++++---- subsys/bluetooth/audio/ccid.c | 41 +++++++++++++++++++ subsys/bluetooth/audio/ccid_internal.h | 12 ++++++ .../audio/src/cap_initiator_broadcast_test.c | 13 ++++-- 4 files changed, 92 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index 7362ea94341..46b39afcb41 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -10,6 +10,7 @@ #include #include #include "cap_internal.h" +#include "ccid_internal.h" #include "csip_internal.h" #include "bap_endpoint.h" @@ -38,9 +39,14 @@ int bt_cap_initiator_register_cb(const struct bt_cap_initiator_cb *cb) return 0; } +struct valid_metadata_param { + bool stream_context_found; + bool valid; +}; + static bool data_func_cb(struct bt_data *data, void *user_data) { - bool *stream_context_found = (bool *)user_data; + struct valid_metadata_param *metadata_param = (struct valid_metadata_param *)user_data; LOG_DBG("type %u len %u data %s", data->type, data->data_len, bt_hex(data->data, data->data_len)); @@ -50,8 +56,21 @@ static bool data_func_cb(struct bt_data *data, void *user_data) return false; } - *stream_context_found = true; - return false; + metadata_param->stream_context_found = true; + } else if (IS_ENABLED(CONFIG_BT_CCID) && data->type == BT_AUDIO_METADATA_TYPE_CCID_LIST) { + /* If the application supplies a CCID list, we verify that the CCIDs exist on our + * device + */ + for (uint8_t i = 0U; i < data->data_len; i++) { + const uint8_t ccid = data->data[i]; + + if (bt_ccid_find_attr(ccid) == NULL) { + LOG_DBG("Unknown characterstic for CCID 0x%02X", ccid); + metadata_param->valid = false; + + return false; + } + } } return true; @@ -59,21 +78,24 @@ static bool data_func_cb(struct bt_data *data, void *user_data) static bool cap_initiator_valid_metadata(const uint8_t meta[], size_t meta_len) { - bool stream_context_found = false; + struct valid_metadata_param metadata_param = { + .stream_context_found = false, + .valid = true, + }; int err; LOG_DBG("meta %p len %zu", meta, meta_len); - err = bt_audio_data_parse(meta, meta_len, data_func_cb, &stream_context_found); + err = bt_audio_data_parse(meta, meta_len, data_func_cb, &metadata_param); if (err != 0 && err != -ECANCELED) { return false; } - if (!stream_context_found) { + if (!metadata_param.stream_context_found) { LOG_DBG("No streaming context supplied"); } - return stream_context_found; + return metadata_param.stream_context_found && metadata_param.valid; } #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) diff --git a/subsys/bluetooth/audio/ccid.c b/subsys/bluetooth/audio/ccid.c index c7bd56db234..c3a9d6a2b42 100644 --- a/subsys/bluetooth/audio/ccid.c +++ b/subsys/bluetooth/audio/ccid.c @@ -6,6 +6,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include #include "ccid_internal.h" @@ -23,3 +26,41 @@ uint8_t bt_ccid_get_value(void) return ccid_value++; } + +struct ccid_search_param { + const struct bt_gatt_attr *attr; + uint8_t ccid; +}; + +static uint8_t ccid_attr_cb(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) +{ + struct ccid_search_param *search_param = user_data; + + if (attr->read != NULL) { + uint8_t ccid = 0U; + ssize_t res; + + res = attr->read(NULL, attr, &ccid, sizeof(ccid), 0); + + if (res == sizeof(ccid) && search_param->ccid == ccid) { + search_param->attr = attr; + + return BT_GATT_ITER_STOP; + } + } + + return BT_GATT_ITER_CONTINUE; +} + +const struct bt_gatt_attr *bt_ccid_find_attr(uint8_t ccid) +{ + struct ccid_search_param search_param = { + .attr = NULL, + .ccid = ccid, + }; + + bt_gatt_foreach_attr_type(BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE, + BT_UUID_CCID, NULL, 0, ccid_attr_cb, &search_param); + + return search_param.attr; +} diff --git a/subsys/bluetooth/audio/ccid_internal.h b/subsys/bluetooth/audio/ccid_internal.h index e68b7bdb8f8..87cca3d7098 100644 --- a/subsys/bluetooth/audio/ccid_internal.h +++ b/subsys/bluetooth/audio/ccid_internal.h @@ -23,4 +23,16 @@ */ uint8_t bt_ccid_get_value(void); +/** + * @brief Get the GATT attribute of a CCID value + * + * Searches the current GATT database for a CCID characteristic that has the supplied CCID value. + * + * @param ccid The CCID the search for + * + * @retval NULL if none was found + * @retval A pointer to a GATT attribute if found + */ +const struct bt_gatt_attr *bt_ccid_find_attr(uint8_t ccid); + #endif /* ZEPHYR_INCLUDE_BLUETOOTH_CCID_H_ */ diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c index 6e533255a19..b5c98ba1a9c 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c @@ -406,11 +406,18 @@ static void test_broadcast_audio_update_inval(struct bt_cap_broadcast_source *br static void test_broadcast_audio_update(struct bt_cap_broadcast_source *broadcast_source) { - const uint16_t mock_ccid = 0xAB; +#if defined(CONFIG_BT_TBS) + /* TODO: We do not have a way to get the CCID value of GTBS, but for now set to 0x00 as we + * know that it is the first content control service initialized + */ + const uint16_t gtbs_ccid = 0x00; +#endif /* CONFIG_BT_TBS */ const uint8_t new_metadata[] = { BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, - BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_MEDIA)), - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, mock_ccid), + BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL)), +#if defined(CONFIG_BT_TBS) + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, gtbs_ccid), +#endif /* CONFIG_BT_TBS */ }; int err; From 028cf8037ba1a4d130c9ffba8afc8527b8dca34b Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Tue, 10 Oct 2023 15:14:41 +0200 Subject: [PATCH 2231/4498] tests: Bluetooth: add sleep in notify cb testcase Validates that nothing nefarious happens if the application decides to wait an arbitrary amount of time in notification callbacks. Also validates that a disconnection during said waiting works as expected. E.g. in #48505, the user was trying to send data synchronously over UART _inside_ the notification callback. Then the device was disconnected whilst still waiting. This kind of pattern is not recommended, but the stack should still function correctly, stalling the "BT RX" thread shouldn't result in state corruption or resource leakage. Signed-off-by: Jonathan Rico --- tests/bsim/bluetooth/host/compile.sh | 2 + .../host/misc/disconnect/common/sync.c | 65 ++ .../host/misc/disconnect/common/sync.h | 9 + .../host/misc/disconnect/common/utils.h | 63 ++ .../host/misc/disconnect/dut/CMakeLists.txt | 17 + .../host/misc/disconnect/dut/prj.conf | 38 ++ .../host/misc/disconnect/dut/src/main.c | 304 +++++++++ .../host/misc/disconnect/scripts/_compile.sh | 18 + .../misc/disconnect/scripts/disconnect.sh | 48 ++ .../misc/disconnect/tester/CMakeLists.txt | 18 + .../host/misc/disconnect/tester/prj.conf | 19 + .../host/misc/disconnect/tester/src/main.c | 627 ++++++++++++++++++ 12 files changed, 1228 insertions(+) create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/common/sync.c create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/common/sync.h create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/common/utils.h create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/dut/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/dut/prj.conf create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/dut/src/main.c create mode 100755 tests/bsim/bluetooth/host/misc/disconnect/scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/misc/disconnect/scripts/disconnect.sh create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/tester/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf create mode 100644 tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 4f9cd0409b8..e52408a089a 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -63,6 +63,8 @@ app=tests/bsim/bluetooth/host/l2cap/send_on_connect compile app=tests/bsim/bluetooth/host/l2cap/send_on_connect conf_file=prj_ecred.conf compile app=tests/bsim/bluetooth/host/misc/disable compile +app=tests/bsim/bluetooth/host/misc/disconnect/dut compile +app=tests/bsim/bluetooth/host/misc/disconnect/tester compile app=tests/bsim/bluetooth/host/privacy/central compile app=tests/bsim/bluetooth/host/privacy/peripheral compile diff --git a/tests/bsim/bluetooth/host/misc/disconnect/common/sync.c b/tests/bsim/bluetooth/host/misc/disconnect/common/sync.c new file mode 100644 index 00000000000..d66a01832b3 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/common/sync.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "argparse.h" +#include "bs_types.h" +#include "bs_tracing.h" +#include "time_machine.h" +#include "bstests.h" +#include "bs_pc_backchannel.h" + +#include +LOG_MODULE_REGISTER(sync, LOG_LEVEL_INF); + +#define CHANNEL_ID 0 +#define MSG_SIZE 1 + +int backchannel_init(void) +{ + uint device_number = get_device_nbr(); + uint peer_number = device_number ^ 1; + uint device_numbers[] = { peer_number }; + uint channel_numbers[] = { CHANNEL_ID }; + uint *ch; + + ch = bs_open_back_channel(device_number, device_numbers, channel_numbers, + ARRAY_SIZE(channel_numbers)); + + if (!ch) { + return -1; + } + + return 0; +} + +void backchannel_sync_send(void) +{ + uint8_t sync_msg[MSG_SIZE] = { get_device_nbr() }; + + LOG_INF("Sending sync"); + bs_bc_send_msg(CHANNEL_ID, sync_msg, ARRAY_SIZE(sync_msg)); +} + +void backchannel_sync_wait(void) +{ + uint8_t sync_msg[MSG_SIZE]; + + while (true) { + if (bs_bc_is_msg_received(CHANNEL_ID) > 0) { + bs_bc_receive_msg(CHANNEL_ID, sync_msg, ARRAY_SIZE(sync_msg)); + if (sync_msg[0] != get_device_nbr()) { + /* Received a message from another device, exit */ + break; + } + } + + k_sleep(K_MSEC(1)); + } + + LOG_INF("Sync received"); +} diff --git a/tests/bsim/bluetooth/host/misc/disconnect/common/sync.h b/tests/bsim/bluetooth/host/misc/disconnect/common/sync.h new file mode 100644 index 00000000000..aa3ef4e48ce --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/common/sync.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int backchannel_init(void); +void backchannel_sync_send(void); +void backchannel_sync_wait(void); diff --git a/tests/bsim/bluetooth/host/misc/disconnect/common/utils.h b/tests/bsim/bluetooth/host/misc/disconnect/common/utils.h new file mode 100644 index 00000000000..d5be7e04bb3 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/common/utils.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_tracing.h" +#include "bs_types.h" +#include "bstests.h" + +#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * USEC_PER_SEC) +#define TEST_TIMEOUT_SIMULATED BS_SECONDS(10) + +extern enum bst_result_t bst_result; + +#define DECLARE_FLAG(flag) extern atomic_t flag +#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) + +#define WAIT_FOR_EXPR(var, expr) \ + while (atomic_get(&var) expr) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_VAL(var, val) \ + while (atomic_get(&var) != val) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define WAIT_FOR_FLAG_UNSET(flag) \ + while ((bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } +#define TAKE_FLAG(flag) \ + while (!(bool)atomic_cas(&flag, true, false)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#define ASSERT(expr, ...) \ + do { \ + if (!(expr)) { \ + FAIL(__VA_ARGS__); \ + } \ + } while (0) + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +#define HVX_HANDLE 0x0012 +#define INDICATION_PAYLOAD "indication" +#define NOTIFICATION_PAYLOAD "notification" diff --git a/tests/bsim/bluetooth/host/misc/disconnect/dut/CMakeLists.txt b/tests/bsim/bluetooth/host/misc/disconnect/dut/CMakeLists.txt new file mode 100644 index 00000000000..9546e14eeb2 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/dut/CMakeLists.txt @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_disconnect_dut) + +target_sources(app PRIVATE + src/main.c + ../common/sync.c +) + +zephyr_include_directories( + ../common/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/misc/disconnect/dut/prj.conf b/tests/bsim/bluetooth/host/misc/disconnect/dut/prj.conf new file mode 100644 index 00000000000..4da2a5c3504 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/dut/prj.conf @@ -0,0 +1,38 @@ +CONFIG_LOG=y +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="Sequential" + +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION=n + +# Replace `Execute` with `gdb --args` in the shell script +# and get a nice backtrace on assert +CONFIG_ARCH_POSIX_TRAP_ON_FATAL=y + +# Prepend logs with thread names +CONFIG_THREAD_NAME=y +CONFIG_LOG_THREAD_ID_PREFIX=y + +# Enable those as needed +# CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y +# CONFIG_BT_ATT_LOG_LEVEL_DBG=y +# CONFIG_BT_GATT_LOG_LEVEL_DBG=y + +# Allow whole L2CAP PDUs to fit on-air +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_ACL_RX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_DATA_LEN_UPDATE=y +CONFIG_BT_USER_DATA_LEN_UPDATE=y + +# Disable auto-initiated procedures so they don't +# mess with the test's execution. +CONFIG_BT_AUTO_PHY_UPDATE=n +CONFIG_BT_AUTO_DATA_LEN_UPDATE=n +CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n + +CONFIG_BT_MAX_CONN=1 diff --git a/tests/bsim/bluetooth/host/misc/disconnect/dut/src/main.c b/tests/bsim/bluetooth/host/misc/disconnect/dut/src/main.c new file mode 100644 index 00000000000..90a70c30c52 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/dut/src/main.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "sync.h" +#include "bstests.h" + +#include +LOG_MODULE_REGISTER(dut, LOG_LEVEL_INF); + +DEFINE_FLAG(is_connected); +DEFINE_FLAG(is_subscribed); +DEFINE_FLAG(flag_data_length_updated); + +static atomic_t notifications; + +/* Defined in hci_core.c */ +extern k_tid_t bt_testing_tx_tid_get(void); + +static struct bt_conn *dconn; + +static void connected(struct bt_conn *conn, uint8_t conn_err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (conn_err) { + FAIL("Failed to connect to %s (%u)", addr, conn_err); + return; + } + + LOG_INF("%s: %s", __func__, addr); + + dconn = bt_conn_ref(conn); + SET_FLAG(is_connected); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + LOG_INF("%s: %p %s (reason 0x%02x)", __func__, conn, addr, reason); + + bt_conn_unref(dconn); + UNSET_FLAG(is_connected); +} + +static void data_len_updated(struct bt_conn *conn, + struct bt_conn_le_data_len_info *info) +{ + LOG_DBG("Data length updated: TX %d RX %d", + info->tx_max_len, + info->rx_max_len); + SET_FLAG(flag_data_length_updated); +} + +static void do_dlu(void) +{ + int err; + struct bt_conn_le_data_len_param param; + + param.tx_max_len = CONFIG_BT_CTLR_DATA_LENGTH_MAX; + param.tx_max_time = 2500; + + err = bt_conn_le_data_len_update(dconn, ¶m); + ASSERT(err == 0, "Can't update data length (err %d)\n", err); + + WAIT_FOR_FLAG(flag_data_length_updated); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, + .le_data_len_updated = data_len_updated, +}; + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + char str[BT_ADDR_LE_STR_LEN]; + struct bt_le_conn_param *param; + struct bt_conn *conn; + int err; + + err = bt_le_scan_stop(); + if (err) { + FAIL("Stop LE scan failed (err %d)", err); + return; + } + + bt_addr_le_to_str(addr, str, sizeof(str)); + LOG_DBG("Connecting to %s", str); + + param = BT_LE_CONN_PARAM_DEFAULT; + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &conn); + if (err) { + FAIL("Create conn failed (err %d)", err); + return; + } +} + +static void connect(void) +{ + int err; + struct bt_le_scan_param scan_param = { + .type = BT_LE_SCAN_TYPE_ACTIVE, + .options = BT_LE_SCAN_OPT_NONE, + .interval = BT_GAP_SCAN_FAST_INTERVAL, + .window = BT_GAP_SCAN_FAST_WINDOW, + }; + + UNSET_FLAG(is_connected); + + err = bt_le_scan_start(&scan_param, device_found); + ASSERT(!err, "Scanning failed to start (err %d)\n", err); + + LOG_DBG("Central initiating connection..."); + WAIT_FOR_FLAG(is_connected); + LOG_INF("Connected as central"); + + /* No security support on the tinyhost unfortunately */ +} + +static uint8_t notified(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) +{ + static uint8_t notification[] = NOTIFICATION_PAYLOAD; + static uint8_t indication[] = INDICATION_PAYLOAD; + bool is_nfy; + + LOG_HEXDUMP_DBG(data, length, "HVx data"); + + if (length == 0) { + /* The host's backward way of telling us we are unsubscribed + * from this characteristic. + */ + LOG_DBG("Unsubscribed"); + return BT_GATT_ITER_CONTINUE; + } + + ASSERT(length >= sizeof(indication), "Unexpected data\n"); + ASSERT(length <= sizeof(notification), "Unexpected data\n"); + + is_nfy = memcmp(data, notification, length) == 0; + + LOG_INF("%s from 0x%x", is_nfy ? "notified" : "indicated", + params->value_handle); + + ASSERT(is_nfy, "Unexpected indication\n"); + + atomic_inc(¬ifications); + + if (atomic_get(¬ifications) == 3) { + LOG_INF("##################### BRB.."); + backchannel_sync_send(); + + /* Make scheduler rotate us in and out multiple times */ + for (int i = 0; i < 10; i++) { + LOG_DBG("sleep"); + k_sleep(K_MSEC(100)); + LOG_DBG("sleep"); + } + + LOG_INF("##################### ..back to work"); + } + + return BT_GATT_ITER_CONTINUE; +} + +static void subscribed(struct bt_conn *conn, + uint8_t err, + struct bt_gatt_subscribe_params *params) +{ + ASSERT(!err, "Subscribe failed (err %d)\n", err); + + ASSERT(params, "params is NULL\n"); + + SET_FLAG(is_subscribed); + /* spoiler: tester doesn't really have attributes */ + LOG_INF("Subscribed to Tester attribute"); +} + +void subscribe(void) +{ + int err; + + /* Handle values don't matter, as long as they match on the tester */ + static struct bt_gatt_subscribe_params params = { + .notify = notified, + .subscribe = subscribed, + .value = BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE, + .value_handle = HVX_HANDLE, + .ccc_handle = (HVX_HANDLE + 1), + }; + + err = bt_gatt_subscribe(dconn, ¶ms); + ASSERT(!err, "Subscribe failed (err %d)\n", err); + + WAIT_FOR_FLAG(is_subscribed); +} + +void test_procedure_0(void) +{ + ASSERT(backchannel_init() == 0, "Failed to open backchannel\n"); + + LOG_DBG("Test start: ATT disconnect protocol"); + int err; + + err = bt_enable(NULL); + ASSERT(err == 0, "Can't enable Bluetooth (err %d)\n", err); + LOG_DBG("Central: Bluetooth initialized."); + + /* Test purpose: + * Make sure the host handles long blocking in notify callbacks + * gracefully, especially in the case of a disconnect while waiting. + * + * Test procedure: + * + * [setup] + * - connect ACL, DUT is central and GATT client + * - update data length (tinyhost doens't have recombination) + * - dut: subscribe to NOTIFY on tester CHRC + * + * [procedure] + * - tester: start periodic notifications + * - dut: wait 10x 100ms in notification RX callback + * - tester: disconnect (not gracefully) while DUT is waiting + * -> simulates a power or range loss situation + * - dut: exit notification callback + * - dut: wait for `disconnected` conn callback + * + * [verdict] + * - The DUT gets the `disconnected` callback, no hanging or timeouts. + */ + connect(); + subscribe(); + + do_dlu(); + + WAIT_FOR_EXPR(notifications, < 4); + + WAIT_FOR_FLAG_UNSET(is_connected); + + LOG_INF("##################### END TEST #####################"); + + PASS("DUT exit\n"); +} + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "dut", + .test_pre_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_procedure_0, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/misc/disconnect/scripts/_compile.sh b/tests/bsim/bluetooth/host/misc/disconnect/scripts/_compile.sh new file mode 100755 index 00000000000..555faa068f2 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/scripts/_compile.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Path checks, etc +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +BOARD="${BOARD:-nrf52_bsim}" +dut_exe="bs_${BOARD}_tests_bsim_bluetooth_host_misc_disconnect_dut_prj_conf" +tester_exe="bs_${BOARD}_tests_bsim_bluetooth_host_misc_disconnect_tester_prj_conf" + +# terminate running simulations (if any) +${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh + +west build -b ${BOARD} -d build_dut dut && \ + cp build_dut/zephyr/zephyr.exe "${BSIM_OUT_PATH}/bin/${dut_exe}" && +west build -b ${BOARD} -d build_tester tester && \ + cp build_tester/zephyr/zephyr.exe "${BSIM_OUT_PATH}/bin/${tester_exe}" diff --git a/tests/bsim/bluetooth/host/misc/disconnect/scripts/disconnect.sh b/tests/bsim/bluetooth/host/misc/disconnect/scripts/disconnect.sh new file mode 100755 index 00000000000..4380119a3e7 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/scripts/disconnect.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +BOARD="${BOARD:-nrf52_bsim}" +dut_exe="bs_${BOARD}_tests_bsim_bluetooth_host_misc_disconnect_dut_prj_conf" +tester_exe="bs_${BOARD}_tests_bsim_bluetooth_host_misc_disconnect_tester_prj_conf" + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_name="misc_disconnect" +simulation_id="${test_name}" +verbosity_level=2 +EXECUTE_TIMEOUT=30 +sim_length_us=10e6 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_2G4_phy_v1 \ + -v=${verbosity_level} -s="${simulation_id}" -D=2 -sim_length=${sim_length_us} $@ + +Execute "./$tester_exe" \ + -v=${verbosity_level} -s="${simulation_id}" -d=1 -testid=tester -RealEncryption=0 -rs=100 + +Execute "./$dut_exe" \ + -v=${verbosity_level} -s="${simulation_id}" -d=0 -testid=dut -RealEncryption=0 + +# wait_for_background_jobs, but doesn't exit on error +exit_code=0 +for process_id in $_process_ids; do +wait $process_id || let "exit_code=$?" +done + +# Make pcaps +for j in {0..1}; do + i=$(printf '%02i' $j) + + ${BSIM_OUT_PATH}/components/ext_2G4_phy_v1/dump_post_process/csv2pcap -o \ + ${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.Tx.pcap \ + ${BSIM_OUT_PATH}/results/${simulation_id}/d_2G4_$i.Tx.csv + + ${BSIM_OUT_PATH}/components/ext_2G4_phy_v1/dump_post_process/csv2pcap -o \ + ${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.Rx.pcap \ + ${BSIM_OUT_PATH}/results/${simulation_id}/d_2G4_$i.Rx.csv + + echo "${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.Tx.pcap" + echo "${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.Rx.pcap" +done diff --git a/tests/bsim/bluetooth/host/misc/disconnect/tester/CMakeLists.txt b/tests/bsim/bluetooth/host/misc/disconnect/tester/CMakeLists.txt new file mode 100644 index 00000000000..e3a567377ef --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/tester/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_disconnect_tester) + +target_sources(app PRIVATE + src/main.c + ../common/sync.c +) + +zephyr_include_directories( + ../common/ + ${ZEPHYR_BASE}/subsys/bluetooth/common/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) diff --git a/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf b/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf new file mode 100644 index 00000000000..461c7dd5029 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf @@ -0,0 +1,19 @@ +CONFIG_LOG=y +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_RESERVE=1 +CONFIG_BT_MAX_CONN=1 + +CONFIG_BT_BUF_CMD_TX_COUNT=10 + +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_CMD_TX_SIZE=255 +CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 + +# Allow whole L2CAP PDUs to fit on-air +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_ACL_RX_SIZE=251 +CONFIG_BT_DATA_LEN_UPDATE=y +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c b/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c new file mode 100644 index 00000000000..4755a55d4d3 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "common/bt_str.h" + +#include "host/conn_internal.h" +#include "host/l2cap_internal.h" + +#include "utils.h" +#include "sync.h" +#include "bstests.h" +#include "NRF_HWLowL.h" /* for hwll_disconnect_phy(); */ + +#include +LOG_MODULE_REGISTER(bt_tinyhost, LOG_LEVEL_INF); + +#define BT_ATT_OP_MTU_REQ 0x02 +#define BT_ATT_OP_MTU_RSP 0x03 +#define BT_ATT_OP_WRITE_REQ 0x12 +#define BT_ATT_OP_WRITE_RSP 0x13 +#define BT_ATT_OP_NOTIFY 0x1b +#define BT_ATT_OP_INDICATE 0x1d +#define BT_ATT_OP_CONFIRM 0x1e +#define BT_ATT_OP_WRITE_CMD 0x52 +#define BT_L2CAP_CID_ATT 0x0004 + +DEFINE_FLAG(is_connected); +DEFINE_FLAG(flag_data_length_updated); + +static K_FIFO_DEFINE(rx_queue); + +#define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, + CMD_BUF_SIZE, 8, NULL); + +static K_SEM_DEFINE(cmd_sem, 1, 1); +static struct k_sem acl_pkts; +static uint16_t conn_handle; + +static volatile uint16_t active_opcode = 0xFFFF; +static struct net_buf *cmd_rsp; + +struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) +{ + struct bt_hci_cmd_hdr *hdr; + struct net_buf *buf; + + LOG_DBG("opcode 0x%04x param_len %u", opcode, param_len); + + buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER); + ASSERT(buf, "failed allocation"); + + LOG_DBG("buf %p", buf); + + net_buf_reserve(buf, BT_BUF_RESERVE); + + bt_buf_set_type(buf, BT_BUF_CMD); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->opcode = sys_cpu_to_le16(opcode); + hdr->param_len = param_len; + + return buf; +} + +static void handle_cmd_complete(struct net_buf *buf) +{ + struct bt_hci_evt_hdr *hdr; + uint8_t status, ncmd; + uint16_t opcode; + struct net_buf_simple_state state; + + net_buf_simple_save(&buf->b, &state); + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + + if (hdr->evt == BT_HCI_EVT_CMD_COMPLETE) { + struct bt_hci_evt_cmd_complete *evt; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + status = 0; + ncmd = evt->ncmd; + opcode = sys_le16_to_cpu(evt->opcode); + + } else if (hdr->evt == BT_HCI_EVT_CMD_STATUS) { + struct bt_hci_evt_cmd_status *evt; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + status = buf->data[0]; + ncmd = evt->ncmd; + opcode = sys_le16_to_cpu(evt->opcode); + + } else { + FAIL("unhandled event 0x%x", hdr->evt); + } + + LOG_DBG("opcode 0x%04x status %x", opcode, status); + + ASSERT(status == 0x00, "cmd status: %x", status); + + ASSERT(active_opcode == opcode, "unexpected opcode %x != %x", active_opcode, opcode); + + if (active_opcode) { + active_opcode = 0xFFFF; + cmd_rsp = net_buf_ref(buf); + net_buf_simple_restore(&buf->b, &state); + } + + if (ncmd) { + k_sem_give(&cmd_sem); + } +} + +static void handle_meta_event(struct net_buf *buf) +{ + uint8_t code = buf->data[2]; + + switch (code) { + case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: + case BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2: + conn_handle = sys_get_le16(&buf->data[4]); + LOG_DBG("connected: handle: %d", conn_handle); + SET_FLAG(is_connected); + break; + case BT_HCI_EVT_LE_DATA_LEN_CHANGE: + SET_FLAG(flag_data_length_updated); + break; + case BT_HCI_EVT_LE_CHAN_SEL_ALGO: + /* do nothing */ + break; + default: + LOG_ERR("unhandled meta event %x", code); + LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI META EVT"); + } +} + +static void handle_ncp(struct net_buf *buf) +{ + struct bt_hci_evt_num_completed_packets *evt; + struct bt_hci_evt_hdr *hdr; + uint16_t handle, count; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + + evt = (void *)buf->data; + handle = sys_le16_to_cpu(evt->h[0].handle); + count = sys_le16_to_cpu(evt->h[0].count); + + LOG_DBG("sent %d packets", count); + + while (count--) { + k_sem_give(&acl_pkts); + } +} + +struct net_buf *alloc_l2cap_pdu(void); +static void send_l2cap_packet(struct net_buf *buf, uint16_t cid); + +static void send_write_rsp(void) +{ + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, BT_ATT_OP_WRITE_RSP); + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void handle_att_write(struct net_buf *buf) +{ + uint16_t handle = net_buf_pull_le16(buf); + + LOG_INF("Got write for 0x%04x len %d", handle, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "payload"); + + static uint8_t ccc_write[2] = {0x03, 0x00}; + + ASSERT(buf->len == 2, "unexpected write length: %d\n", buf->len); + ASSERT(memcmp(buf->data, ccc_write, sizeof(ccc_write)) == 0, "bad data\n"); + + send_write_rsp(); +} + +static void handle_att(struct net_buf *buf) +{ + uint8_t op = net_buf_pull_u8(buf); + + switch (op) { + case BT_ATT_OP_WRITE_REQ: + handle_att_write(buf); + return; + case BT_ATT_OP_MTU_RSP: + LOG_INF("got ATT MTU RSP"); + return; + default: + LOG_HEXDUMP_ERR(buf->data, buf->len, "payload"); + FAIL("unhandled opcode %x\n", op); + return; + } +} + +static void handle_l2cap(struct net_buf *buf) +{ + struct bt_l2cap_hdr *hdr; + uint16_t cid; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + cid = sys_le16_to_cpu(hdr->cid); + + LOG_DBG("Packet for CID %u len %u", cid, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "l2cap"); + + /* Make sure we don't have to recombine packets */ + ASSERT(buf->len == hdr->len, "buflen = %d != hdrlen %d", + buf->len, hdr->len); + + ASSERT(cid == BT_L2CAP_CID_ATT, "We only support (U)ATT"); + + /* (U)ATT PDU */ + handle_att(buf); +} + +static void handle_acl(struct net_buf *buf) +{ + struct bt_hci_acl_hdr *hdr; + uint16_t len, handle; + uint8_t flags; + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + len = sys_le16_to_cpu(hdr->len); + handle = sys_le16_to_cpu(hdr->handle); + + flags = bt_acl_flags(handle); + handle = bt_acl_handle(handle); + + ASSERT(flags == BT_ACL_START, + "Fragmentation not supported"); + + LOG_DBG("ACL: conn %d len %d flags %d", handle, len, flags); + LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI ACL"); + + handle_l2cap(buf); +} + +static void recv(struct net_buf *buf) +{ + LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI RX"); + + uint8_t code = buf->data[0]; + + if (bt_buf_get_type(buf) == BT_BUF_EVT) { + switch (code) { + case BT_HCI_EVT_CMD_COMPLETE: + case BT_HCI_EVT_CMD_STATUS: + handle_cmd_complete(buf); + break; + case BT_HCI_EVT_LE_META_EVENT: + handle_meta_event(buf); + break; + case BT_HCI_EVT_DISCONN_COMPLETE: + UNSET_FLAG(is_connected); + break; + case BT_HCI_EVT_NUM_COMPLETED_PACKETS: + handle_ncp(buf); + break; + default: + LOG_ERR("unhandled msg %x", code); + LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI EVT"); + } + + /* handlers should take a ref if they want to access the buffer + * later + */ + net_buf_unref(buf); + return; + } + + if (bt_buf_get_type(buf) == BT_BUF_ACL_IN) { + handle_acl(buf); + net_buf_unref(buf); + return; + } + + LOG_ERR("HCI RX (not data or event)"); + net_buf_unref(buf); +} + +static void send_cmd(uint16_t opcode, struct net_buf *cmd, struct net_buf **rsp) +{ + LOG_DBG("opcode %x", opcode); + + if (!cmd) { + cmd = bt_hci_cmd_create(opcode, 0); + } + + k_sem_take(&cmd_sem, K_FOREVER); + ASSERT(active_opcode == 0xFFFF, ""); + + active_opcode = opcode; + + LOG_HEXDUMP_DBG(cmd->data, cmd->len, "HCI TX"); + bt_send(cmd); + + /* Wait until the command completes */ + k_sem_take(&cmd_sem, K_FOREVER); + k_sem_give(&cmd_sem); + + net_buf_unref(cmd); + + /* return response. it's okay if cmd_rsp gets overwritten, since the app + * gets the ref to the underlying buffer when this fn returns. + */ + if (rsp) { + *rsp = cmd_rsp; + } else { + net_buf_unref(cmd_rsp); + cmd_rsp = NULL; + } +} + +static K_THREAD_STACK_DEFINE(rx_thread_stack, 1024); +static struct k_thread rx_thread_data; + +static void rx_thread(void *p1, void *p2, void *p3) +{ + LOG_DBG("start HCI rx"); + + while (true) { + struct net_buf *buf; + + /* Wait until a buffer is available */ + buf = net_buf_get(&rx_queue, K_FOREVER); + recv(buf); + } +} + +static void le_read_buffer_size_complete(struct net_buf *rsp) +{ + struct bt_hci_rp_le_read_buffer_size *rp = (void *)rsp->data; + + LOG_DBG("status 0x%02x", rp->status); + LOG_DBG("max len %d max num %d", rp->le_max_len, rp->le_max_num); + + k_sem_init(&acl_pkts, rp->le_max_num, rp->le_max_num); + net_buf_unref(rsp); +} + +static void read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time) +{ + struct bt_hci_rp_le_read_max_data_len *rp; + struct net_buf *rsp; + + send_cmd(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp); + + rp = (void *)rsp->data; + *tx_octets = sys_le16_to_cpu(rp->max_tx_octets); + *tx_time = sys_le16_to_cpu(rp->max_tx_time); + net_buf_unref(rsp); +} + +static void write_default_data_len(uint16_t tx_octets, uint16_t tx_time) +{ + struct bt_hci_cp_le_write_default_data_len *cp; + struct net_buf *buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, sizeof(*cp)); + + ASSERT(buf, ""); + + cp = net_buf_add(buf, sizeof(*cp)); + cp->max_tx_octets = sys_cpu_to_le16(tx_octets); + cp->max_tx_time = sys_cpu_to_le16(tx_time); + + send_cmd(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, buf, NULL); +} + +static void set_data_len(void) +{ + uint16_t tx_octets, tx_time; + + read_max_data_len(&tx_octets, &tx_time); + write_default_data_len(tx_octets, tx_time); +} + +static void set_event_mask(uint16_t opcode) +{ + struct bt_hci_cp_set_event_mask *cp_mask; + struct net_buf *buf; + uint64_t mask = 0U; + + /* The two commands have the same length/params */ + buf = bt_hci_cmd_create(opcode, sizeof(*cp_mask)); + ASSERT(buf, ""); + + /* Forward all events */ + cp_mask = net_buf_add(buf, sizeof(*cp_mask)); + mask = UINT64_MAX; + sys_put_le64(mask, cp_mask->events); + + send_cmd(opcode, buf, NULL); +} + +static void set_random_address(void) +{ + struct net_buf *buf; + bt_addr_le_t addr = {BT_ADDR_LE_RANDOM, {{0x0A, 0x89, 0x67, 0x45, 0x23, 0xC1}}}; + + LOG_DBG("%s", bt_addr_str(&addr.a)); + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(addr.a)); + ASSERT(buf, ""); + + net_buf_add_mem(buf, &addr.a, sizeof(addr.a)); + send_cmd(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, buf, NULL); +} + +void start_adv(void) +{ + struct bt_hci_cp_le_set_adv_param set_param; + struct net_buf *buf; + uint16_t interval = 60; /* Interval doesn't matter */ + + (void)memset(&set_param, 0, sizeof(set_param)); + + set_param.min_interval = sys_cpu_to_le16(interval); + set_param.max_interval = sys_cpu_to_le16(interval); + set_param.channel_map = 0x07; + set_param.filter_policy = BT_LE_ADV_FP_NO_FILTER; + set_param.type = BT_HCI_ADV_IND; + set_param.own_addr_type = 0x01; /* random */ + + /* configure */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(set_param)); + net_buf_add_mem(buf, &set_param, sizeof(set_param)); + send_cmd(BT_HCI_OP_LE_SET_ADV_PARAM, buf, NULL); + + /* start */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1); + net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE); + send_cmd(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); +} + +NET_BUF_POOL_DEFINE(acl_tx_pool, 5, BT_L2CAP_BUF_SIZE(200), 8, NULL); + +struct net_buf *alloc_l2cap_pdu(void) +{ + struct net_buf *buf; + uint16_t reserve; + + buf = net_buf_alloc(&acl_tx_pool, K_FOREVER); + ASSERT(buf, "failed ACL allocation"); + + reserve = sizeof(struct bt_l2cap_hdr); + reserve += sizeof(struct bt_hci_acl_hdr) + BT_BUF_RESERVE; + + net_buf_reserve(buf, reserve); + + return buf; +} + +static int send_acl(struct net_buf *buf) +{ + struct bt_hci_acl_hdr *hdr; + uint8_t flags = BT_ACL_START_NO_FLUSH; + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn_handle, flags)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + + bt_buf_set_type(buf, BT_BUF_ACL_OUT); + + k_sem_take(&acl_pkts, K_FOREVER); + + return bt_send(buf); +} + +static void send_l2cap_packet(struct net_buf *buf, uint16_t cid) +{ + struct bt_l2cap_hdr *hdr; + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + hdr->cid = sys_cpu_to_le16(cid); + + /* Always entire packets, no HCI fragmentation */ + ASSERT(buf->len <= CONFIG_BT_BUF_ACL_TX_SIZE, + "Fragmentation not supported"); + + send_acl(buf); +} + +static void gatt_notify(void) +{ + static uint8_t data[] = NOTIFICATION_PAYLOAD; + uint16_t handle = HVX_HANDLE; + struct net_buf *buf = alloc_l2cap_pdu(); + + net_buf_add_u8(buf, BT_ATT_OP_NOTIFY); + net_buf_add_le16(buf, handle); + net_buf_add_mem(buf, data, sizeof(data)); + + LOG_INF("send ATT notification"); + send_l2cap_packet(buf, BT_L2CAP_CID_ATT); +} + +static void prepare_controller(void) +{ + /* Initialize controller */ + struct net_buf *rsp; + + send_cmd(BT_HCI_OP_RESET, NULL, NULL); + send_cmd(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp); + le_read_buffer_size_complete(rsp); + + set_data_len(); + set_event_mask(BT_HCI_OP_SET_EVENT_MASK); + set_event_mask(BT_HCI_OP_LE_SET_EVENT_MASK); + set_random_address(); +} + +static void init_tinyhost(void) +{ + bt_enable_raw(&rx_queue); + + /* Start the RX thread */ + k_thread_create(&rx_thread_data, rx_thread_stack, + K_THREAD_STACK_SIZEOF(rx_thread_stack), rx_thread, + NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); + k_thread_name_set(&rx_thread_data, "HCI RX"); + + k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(0)); + + prepare_controller(); +} + +void test_procedure_0(void) +{ + ASSERT(backchannel_init() == 0, "Failed to open backchannel\n"); + + init_tinyhost(); + + /* Start advertising & wait for a connection */ + start_adv(); + WAIT_FOR_FLAG(is_connected); + LOG_INF("connected"); + + /* We need this to be able to send whole L2CAP PDUs on-air. */ + WAIT_FOR_FLAG(flag_data_length_updated); + + LOG_INF("##################### START TEST #####################"); + + for (int n = 0; n < 3; n++) { + gatt_notify(); + } + + /* Wait until DUT starts sleeping */ + backchannel_sync_wait(); + + /* Send some more, so DUT has some more data to process before having to + * handle the disconnect. + */ + for (int n = 0; n < 3; n++) { + gatt_notify(); + } + + /* Wait >2 conn events, to be sure at least one more notification makes + * it to the other peer before breaking the link. + */ + k_sleep(K_MSEC(50)); + + LOG_INF("kill radio"); + hwll_disconnect_phy(); + + /* Pass has to be before the exit() for process to not error out */ + PASS("Tester exit\n"); + bs_trace_silent_exit(0); +} + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result != Passed) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended.\n"); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); + bst_result = In_progress; +} + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "tester", + .test_pre_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_procedure_0, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + + +int main(void) +{ + bst_main(); + + return 0; +} From a38d534ae0d9bc38a39e459ddc9e84616f819cae Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 11 Oct 2023 14:18:55 +0200 Subject: [PATCH 2232/4498] Bluetooth: BAP: Shell: Add better checks for bis_sync Since the BIS indexes start at 0x01, then BIT(0) is a invalid BIS sync value and shall not be sent by the broadcast assistant. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/bap_broadcast_assistant.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c index 5f98a26f8c1..4ed37d01a16 100644 --- a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c @@ -25,6 +25,8 @@ #include "audio.h" #define INVALID_BROADCAST_ID 0xFFFFFFFFU +/* BIS sync is a 32-bit bitfield where BIT(0) is not allowed */ +#define VALID_BIS_SYNC(_bis_sync) ((bis_sync & BIT(0)) == 0U && bis_sync < UINT32_MAX) static struct bt_bap_base received_base; @@ -453,7 +455,7 @@ static int cmd_bap_broadcast_assistant_add_src(const struct shell *sh, return -ENOEXEC; } - if (bis_sync > UINT32_MAX) { + if (!VALID_BIS_SYNC(bis_sync)) { shell_error(sh, "Invalid bis_sync: %lu", bis_sync); return -ENOEXEC; @@ -640,7 +642,7 @@ static int cmd_bap_broadcast_assistant_add_broadcast_id(const struct shell *sh, shell_error(sh, "failed to parse bis_sync: %d", err); return -ENOEXEC; - } else if (bis_sync > UINT32_MAX) { + } else if (!VALID_BIS_SYNC(bis_sync)) { shell_error(sh, "Invalid bis_sync: %lu", bis_sync); return -ENOEXEC; @@ -738,7 +740,7 @@ static int cmd_bap_broadcast_assistant_mod_src(const struct shell *sh, return -ENOEXEC; } - if (bis_sync > UINT32_MAX) { + if (!VALID_BIS_SYNC(bis_sync)) { shell_error(sh, "Invalid bis_sync: %lu", bis_sync); return -ENOEXEC; From 52d47fcf969637457cc7e28f5c42c20cfe4d5f87 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 11 Oct 2023 17:31:30 +0200 Subject: [PATCH 2233/4498] dts: stm32wba: Add GPDMA support Add GPDMA1 node description to STM32WBA devices. Signed-off-by: Erwan Gouriou --- dts/arm/st/wba/stm32wba.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index c93b042babf..de7ec91d347 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -430,6 +431,18 @@ health-test-config = <0xaac7>; status = "disabled"; }; + + gpdma1: dma@40020000 { + compatible = "st,stm32u5-dma"; + #dma-cells = <3>; + reg = <0x40020000 0x1000>; + interrupts = <29 0 30 0 31 0 32 0 33 0 34 0 35 0 36 0>; + clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x1>; + dma-channels = <8>; + dma-requests = <52>; + dma-offset = <0>; + status = "disabled"; + }; }; }; From 1e464137290ef5659faee2244e8bd6576c2265f4 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 11 Oct 2023 17:33:33 +0200 Subject: [PATCH 2234/4498] boards: nucleo_wba52cg: Add LPUART node description Enable LPUART1 node on nucleo_wba52cg so it could be used to performed uart tests. Signed-off-by: Erwan Gouriou --- boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts index 0a6e03c7d6c..23b8f85e8cd 100644 --- a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts +++ b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts @@ -89,6 +89,13 @@ status = "okay"; }; +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pb5 &lpuart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + &spi1 { pinctrl-0 = <&spi1_nss_pa12 &spi1_sck_pb4 &spi1_miso_pb3 &spi1_mosi_pa15>; From 7b50c38ec93bf6a48bf34f8593f54cc2268419d7 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 11 Oct 2023 17:34:55 +0200 Subject: [PATCH 2235/4498] tests: drivers: serial: async: Add configuration for STM32WBA tests Add STM32WBA test configuration to enable async API serial tests. Signed-off-by: Erwan Gouriou --- .../uart_async_api/boards/nucleo_wba52cg.overlay | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/nucleo_wba52cg.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/nucleo_wba52cg.overlay b/tests/drivers/uart/uart_async_api/boards/nucleo_wba52cg.overlay new file mode 100644 index 00000000000..c495168048b --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/nucleo_wba52cg.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dut: &lpuart1 { + dmas = <&gpdma1 0 16 STM32_DMA_PERIPH_TX + &gpdma1 1 15 STM32_DMA_PERIPH_RX>; + dma-names = "tx", "rx"; +}; + +&gpdma1 { + status = "okay"; +}; From a6496e056bb6caf089ddfb712699601d91112545 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Fri, 22 Sep 2023 01:14:11 -0700 Subject: [PATCH 2236/4498] soc: npcx: replace Nuvoton NPCX series definitions in the npcx drivers Replace Nuvoton NPCX series definitions with new Kconfig definitions in the npcx drivers. The benefit of this approach is that we won't touch the npcx driver sources again during introducing a new npcx series next time. Signed-off-by: Mulin Chao --- drivers/adc/Kconfig.npcx | 16 +++++++++++++++ drivers/adc/adc_npcx.c | 8 ++++---- drivers/espi/Kconfig.npcx | 6 ++++++ drivers/espi/espi_npcx.c | 2 +- drivers/flash/Kconfig.npcx_fiu | 32 +++++++++++++++++++++++++++++ drivers/flash/flash_npcx_fiu_qspi.c | 12 +++++------ 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/drivers/adc/Kconfig.npcx b/drivers/adc/Kconfig.npcx index 8f48aefe760..0209fd845d9 100644 --- a/drivers/adc/Kconfig.npcx +++ b/drivers/adc/Kconfig.npcx @@ -11,3 +11,19 @@ config ADC_NPCX This option enables the ADC driver for NPCX family of processors. Say y if you wish to use ADC channels on NPCX MCU. + +if ADC_NPCX + +config ADC_NPCX_CMP_V1 + bool "ADC comparator version 1 support" + default y if SOC_SERIES_NPCX7 || SOC_SERIES_NPCX9 + help + This option enables ADC comparator V1 support. + +config ADC_NPCX_CMP_V2 + bool "ADC comparator version 2 support" + default y if SOC_SERIES_NPCX4 + help + This option enables ADC comparator V2 support. + +endif #ADC_NPCX diff --git a/drivers/adc/adc_npcx.c b/drivers/adc/adc_npcx.c index 6a5a1ad802a..ae1cf65ffbb 100644 --- a/drivers/adc/adc_npcx.c +++ b/drivers/adc/adc_npcx.c @@ -168,16 +168,16 @@ static inline void adc_npcx_enable_threshold_detect(const struct device *dev, ui const struct adc_npcx_config *config = dev->config; if (enable) { -#ifdef CONFIG_SOC_SERIES_NPCX4 +#ifdef CONFIG_ADC_NPCX_CMP_V2 THEN(config->base) |= BIT(th_sel); -#else +#else /* CONFIG_ADC_NPCX_CMP_V1 */ THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_THEN); #endif } else { -#ifdef CONFIG_SOC_SERIES_NPCX4 +#ifdef CONFIG_ADC_NPCX_CMP_V2 THEN(config->base) &= ~BIT(th_sel); -#else +#else /* CONFIG_ADC_NPCX_CMP_V1 */ THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_THEN); #endif } diff --git a/drivers/espi/Kconfig.npcx b/drivers/espi/Kconfig.npcx index 1da4f661217..d0680565a6d 100644 --- a/drivers/espi/Kconfig.npcx +++ b/drivers/espi/Kconfig.npcx @@ -80,4 +80,10 @@ config ESPI_PERIPHERAL_ACPI_SHM_REGION config ESPI_PERIPHERAL_CUSTOM_OPCODE default y +config ESPI_NPCX_SUPP_VW_GPIO + bool "Indicates that the eSPI hardware supports virtual wire GPIOs" + default y if SOC_SERIES_NPCX9 || SOC_SERIES_NPCX4 + help + Selected if NPCX series supports virtual wire GPIOs in eSPI module. + endif #ESPI_NPCX diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index 7d2679407a4..d6177dee388 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -164,7 +164,7 @@ static const struct npcx_vw_out_config vw_out_tbl[] = { /* Virtual wire GPIOs for platform level usage (High at Reset state) */ static const struct npcx_vw_out_config vw_out_gpio_tbl1[] = { /* Only NPCX9 and later series support this feature */ -#if !defined(CONFIG_SOC_SERIES_NPCX7) +#if defined(CONFIG_ESPI_NPCX_SUPP_VW_GPIO) /* index 50h (Out) */ NPCX_DT_VW_OUT_CONF(ESPI_VWIRE_SIGNAL_SLV_GPIO_0, vw_slv_gpio_0), NPCX_DT_VW_OUT_CONF(ESPI_VWIRE_SIGNAL_SLV_GPIO_1, vw_slv_gpio_1), diff --git a/drivers/flash/Kconfig.npcx_fiu b/drivers/flash/Kconfig.npcx_fiu index d46d7f2e0dc..e4ac74c9d44 100644 --- a/drivers/flash/Kconfig.npcx_fiu +++ b/drivers/flash/Kconfig.npcx_fiu @@ -24,6 +24,8 @@ config FLASH_NPCX_FIU_NOR This option enables the QSPI NOR Flash driver for NPCX family of processors. +if FLASH_NPCX_FIU_QSPI + config FLASH_NPCX_FIU_NOR_INIT bool "QSPI NOR flash feature during driver initialization" default y @@ -32,3 +34,33 @@ config FLASH_NPCX_FIU_NOR_INIT This option enables the QSPI NOR Flash features such as Quad-Enable, 4-byte address support and so on during driver initialization. Disable it if QSPI NOR devices are not ready during driver initialization. + +config FLASH_NPCX_FIU_DRA_V1 + bool "Direct Read Access version 1 support" + default y if SOC_SERIES_NPCX9 + help + This option enables DRA V1 support. + +config FLASH_NPCX_FIU_DRA_V2 + bool "Direct Read Access version 2 support" + default y if SOC_SERIES_NPCX4 + help + This option enables DRA V1 support. + +config FLASH_NPCX_FIU_SUPP_DRA_4B_ADDR + bool "4 byte address support in Direct Read Access mode" + default y if FLASH_NPCX_FIU_DRA_V1 || \ + FLASH_NPCX_FIU_DRA_V2 + help + Selected if NPCX series supports 4 byte address mode in Direct Read + Access mode. + +config FLASH_NPCX_FIU_SUPP_DRA_2_DEV + bool "4 byte address support in Direct Read Access mode" + default y if FLASH_NPCX_FIU_DRA_V1 || \ + FLASH_NPCX_FIU_DRA_V2 + help + Selected if NPCX series supports two external SPI devices in Direct + Read Access (DRA) on QSPI bus. + +endif #FLASH_NPCX_FIU_QSPI diff --git a/drivers/flash/flash_npcx_fiu_qspi.c b/drivers/flash/flash_npcx_fiu_qspi.c index 3af0d4092a6..37afe6cfa42 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.c +++ b/drivers/flash/flash_npcx_fiu_qspi.c @@ -99,10 +99,10 @@ static inline void qspi_npcx_config_uma_mode(const struct device *dev, static inline void qspi_npcx_config_dra_4byte_mode(const struct device *dev, const struct npcx_qspi_cfg *qspi_cfg) { -#if !defined(CONFIG_SOC_SERIES_NPCX7) /* NPCX7 doesn't support this feature */ +#if defined(CONFIG_FLASH_NPCX_FIU_SUPP_DRA_4B_ADDR) struct fiu_reg *const inst = HAL_INSTANCE(dev); -#if defined(CONFIG_SOC_SERIES_NPCX9) +#if defined(CONFIG_FLASH_NPCX_FIU_DRA_V1) if (qspi_cfg->enter_4ba != 0) { if ((qspi_cfg->flags & NPCX_QSPI_SEC_FLASH_SL) != 0) { inst->SPI1_DEV |= BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11); @@ -113,12 +113,12 @@ static inline void qspi_npcx_config_dra_4byte_mode(const struct device *dev, inst->SPI1_DEV &= ~(BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11) | BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS10)); } -#elif defined(CONFIG_SOC_SERIES_NPCX4) +#elif defined(CONFIG_FLASH_NPCX_FIU_DRA_V2) if (qspi_cfg->enter_4ba != 0) { SET_FIELD(inst->SPI_DEV, NPCX_SPI_DEV_NADDRB, NPCX_DEV_NUM_ADDR_4BYTE); } #endif -#endif /* CONFIG_SOC_SERIES_NPCX7 */ +#endif /* CONFIG_FLASH_NPCX_FIU_SUPP_DRA_4B_ADDR */ } static inline void qspi_npcx_config_dra_mode(const struct device *dev, @@ -127,7 +127,7 @@ static inline void qspi_npcx_config_dra_mode(const struct device *dev, struct fiu_reg *const inst = HAL_INSTANCE(dev); /* Select SPI device number for DRA mode in npcx4 series */ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX4)) { + if (IS_ENABLED(CONFIG_FLASH_NPCX_FIU_DRA_V2)) { int spi_dev_num = (qspi_cfg->flags & NPCX_QSPI_SEC_FLASH_SL) != 0 ? 1 : 0; SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, spi_dev_num); @@ -270,7 +270,7 @@ static int qspi_npcx_fiu_init(const struct device *dev) /* Enable direct access for 2 external SPI devices */ if (config->en_direct_access_2dev) { - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX9) || IS_ENABLED(CONFIG_SOC_SERIES_NPCX4)) { + if (IS_ENABLED(CONFIG_FLASH_NPCX_FIU_SUPP_DRA_2_DEV)) { inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); } } From 0d59aa1ab478103a141d417f1b90b6e344ed1ab4 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Tue, 26 Sep 2023 23:13:39 -0700 Subject: [PATCH 2237/4498] sensor: adc_cmp: npcx: use BUILD_ASSERT to check `thr-sel` value This CL uses BUILD_ASSERT macro to check whether `thr-sel` is out of range instead of using NPCX series definitions. Signed-off-by: Mulin Chao --- .../nuvoton_adc_cmp_npcx/adc_cmp_npcx.c | 35 ++++++++++--------- include/zephyr/drivers/sensor/adc_cmp_npcx.h | 2 -- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c index ff1871e8a40..cba37069ce9 100644 --- a/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c +++ b/drivers/sensor/nuvoton_adc_cmp_npcx/adc_cmp_npcx.c @@ -251,20 +251,23 @@ static const struct sensor_driver_api adc_cmp_npcx_api = { .channel_get = adc_cmp_npcx_channel_get, }; -#define NPCX_ADC_CMP_INIT(inst) \ - static struct adc_cmp_npcx_data adc_cmp_npcx_data_##inst; \ - static const struct adc_cmp_npcx_config adc_cmp_npcx_config_##inst = {\ - .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \ - .chnsel = DT_INST_IO_CHANNELS_INPUT(inst), \ - .th_sel = DT_INST_STRING_TOKEN_OR(inst, thr_sel, inst), \ - .thr_mv = DT_INST_PROP_OR(inst, threshold_mv, \ - ADC_CMP_NPCX_UNDEFINED), \ - .comparison = DT_INST_STRING_TOKEN_OR(inst, \ - comparison, ADC_CMP_NPCX_UNDEFINED) \ - }; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, adc_cmp_npcx_init, NULL, \ - &adc_cmp_npcx_data_##inst, \ - &adc_cmp_npcx_config_##inst, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ - &adc_cmp_npcx_api); +#define NPCX_ADC_CMP_INIT(inst) \ + static struct adc_cmp_npcx_data adc_cmp_npcx_data_##inst; \ + static const struct adc_cmp_npcx_config adc_cmp_npcx_config_##inst = { \ + .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \ + .chnsel = DT_INST_IO_CHANNELS_INPUT(inst), \ + .th_sel = DT_INST_STRING_TOKEN_OR(inst, thr_sel, inst), \ + .thr_mv = DT_INST_PROP_OR(inst, threshold_mv, \ + ADC_CMP_NPCX_UNDEFINED), \ + .comparison = DT_INST_STRING_TOKEN_OR(inst, \ + comparison, ADC_CMP_NPCX_UNDEFINED) \ + }; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, adc_cmp_npcx_init, NULL, \ + &adc_cmp_npcx_data_##inst, \ + &adc_cmp_npcx_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &adc_cmp_npcx_api); \ + BUILD_ASSERT(DT_INST_STRING_TOKEN_OR(inst, thr_sel, inst) < \ + DT_PROP(DT_INST_IO_CHANNELS_CTLR(inst), threshold_count), \ + "Exceed the number of threshold detectors adc supports"); DT_INST_FOREACH_STATUS_OKAY(NPCX_ADC_CMP_INIT) diff --git a/include/zephyr/drivers/sensor/adc_cmp_npcx.h b/include/zephyr/drivers/sensor/adc_cmp_npcx.h index 5e986dd1be7..0fa7f14ca1f 100644 --- a/include/zephyr/drivers/sensor/adc_cmp_npcx.h +++ b/include/zephyr/drivers/sensor/adc_cmp_npcx.h @@ -17,11 +17,9 @@ enum npcx_adc_cmp_thrctl { ADC_CMP_NPCX_THRCTL1, ADC_CMP_NPCX_THRCTL2, ADC_CMP_NPCX_THRCTL3, -#if !defined(CONFIG_SOC_SERIES_NPCX7) ADC_CMP_NPCX_THRCTL4, ADC_CMP_NPCX_THRCTL5, ADC_CMP_NPCX_THRCTL6, -#endif ADC_CMP_NPCX_THRCTL_COUNT, }; From 35e3dfed2dcb00b11d76ac2a0f2c0e35c3cc27e7 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Wed, 6 Sep 2023 13:44:56 +0800 Subject: [PATCH 2238/4498] ITE: soc: Add the variant of it82002aw This variant uses the same die as IT82202/IT82302 series and has a pinout compatible with IT513xx series packages. Signed-off-by: Tim Lin --- .../riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw | 12 ++++++++++++ soc/riscv/riscv-ite/it8xxx2/Kconfig.soc | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw b/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw new file mode 100644 index 00000000000..1edba5f674e --- /dev/null +++ b/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw @@ -0,0 +1,12 @@ +# Copyright (c) 2023 ITE Corporation. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_IT82002_AW + +config SOC + default "it82002aw" + +config SOC_IT8XXX2_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN + default y + +endif diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc b/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc index c33fe0f376f..38525449f89 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc +++ b/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc @@ -66,6 +66,10 @@ config SOC_IT82302_AX bool "IT82302 AX version" select SOC_IT8XXX2_REG_SET_V2 +config SOC_IT82002_AW + bool "IT82002 AW version" + select SOC_IT8XXX2_REG_SET_V2 + endchoice config SOC_IT8XXX2_PLL_FLASH_48M From 2df58f65ce0791725f79fdeb06081fcc4290f6a2 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 12 Oct 2023 12:11:26 +0300 Subject: [PATCH 2239/4498] samples: lwm2m: Add docker test script Add test script that uses same configuration that the interoperability test. This is only checking that unsecure client registers and responds to a GET query. Signed-off-by: Seppo Takalo --- samples/net/lwm2m_client/docker-test.sh | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 samples/net/lwm2m_client/docker-test.sh diff --git a/samples/net/lwm2m_client/docker-test.sh b/samples/net/lwm2m_client/docker-test.sh new file mode 100644 index 00000000000..a7200b21b4b --- /dev/null +++ b/samples/net/lwm2m_client/docker-test.sh @@ -0,0 +1,29 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if [ -z "$RUNNING_FROM_MAIN_SCRIPT" ]; then + echo "Do not run this script directly!" + echo "Run $ZEPHYR_BASE/scripts/net/run-sample-tests.sh instead." + exit 1 +fi + +IP="--ip=192.0.2.2 --ip6=2001:db8::2" +FWD="-p 8080:8080 -p 8081:8081 -p 5683:5683/udp" + +start_configuration "$IP $FWD" || return $? +start_docker "/net-tools/start-leshan.sh" || return $? + +start_zephyr + +sleep 5 +curl -s -X GET 'http://localhost:8080/api/clients/native_posix/3/0/0' | grep Zephyr 2>&1 >/dev/null +result=$? + +stop_zephyr +stop_docker + +if [ $result -eq 0 ]; then + return 0 +else + return 1 +fi From 0ce77c227bc786333173573613dc0158503cadb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 12 Oct 2023 14:29:00 +0200 Subject: [PATCH 2240/4498] Bluetooth: Host: CMake dependency for Mesh Bsim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Links host to mbedTLS library if Bluetooth Mesh is enabled, and CONFIG_BT_TESTING=y. Bluetooth Mesh has test dependencies in the host. In order to compile Bsim tests with these test features and PSA enabled, the libraries must be linked. Signed-off-by: Anders Storrø --- subsys/bluetooth/host/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/bluetooth/host/CMakeLists.txt b/subsys/bluetooth/host/CMakeLists.txt index a9810c8af32..e5ac8c707e0 100644 --- a/subsys/bluetooth/host/CMakeLists.txt +++ b/subsys/bluetooth/host/CMakeLists.txt @@ -123,3 +123,10 @@ if(CONFIG_BT_CONN_DISABLE_SECURITY) Do not use in production." ) endif() + +# Bluetooth Mesh has test dependencies in the host. +# In order to compile Bsim tests with these test features +# and PSA enabled, the libraries must be linked. +if(CONFIG_BT_MESH AND CONFIG_BT_TESTING) + zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) +endif() From f9ee38060d9663afa771f46fc759c9907e67cb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 12 Oct 2023 12:39:27 +0200 Subject: [PATCH 2241/4498] tests: Bluetooth: Mesh: Arg bug in beacon creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes bug in private_beacon_create function in beacon test implementation. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/src/test_beacon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index 1313791d7bb..9a5554ad8cb 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -1180,7 +1180,7 @@ static void private_beacon_create(struct net_buf_simple *buf, const uint8_t *net } bt_rand(random_val, sizeof(random_val)); - bt_mesh_beacon_encrypt(&priv_beacon_key, flags, bt_mesh.iv_index + 1, + bt_mesh_beacon_encrypt(&priv_beacon_key, flags, iv_index, random_val, data, auth); net_buf_simple_reset(buf); From eb480a7599ed806bbd1fc8879b0eeef91888a306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 12 Oct 2023 15:16:15 +0200 Subject: [PATCH 2242/4498] tests: Bluetooth: Mesh: Add SNB cache test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Bsim test that verifies SNB cache functionality. The test checks that replays of the same SNB message is discarded. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/prj.conf | 1 + tests/bsim/bluetooth/mesh/src/test_beacon.c | 74 +++++++++++++++++++ .../mesh/tests_scripts/beacon/beacon_cache.sh | 27 +++++++ 3 files changed, 102 insertions(+) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh diff --git a/tests/bsim/bluetooth/mesh/prj.conf b/tests/bsim/bluetooth/mesh/prj.conf index 2e55a6a588b..b0738c4fa05 100644 --- a/tests/bsim/bluetooth/mesh/prj.conf +++ b/tests/bsim/bluetooth/mesh/prj.conf @@ -43,3 +43,4 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=4 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MODEL_EXTENSIONS=y CONFIG_BT_MESH_SUBNET_COUNT=5 +CONFIG_BT_TESTING=y diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index 9a5554ad8cb..d72b8322478 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -54,6 +54,22 @@ static const struct bt_mesh_test_cfg rx_cfg = { .dev_key = { 0x02 }, }; +typedef void (*snb_cb)(const struct bt_mesh_snb *snb); + +static snb_cb snb_cb_ptr; +static struct k_sem beacon_sem; + +static void snb_received(const struct bt_mesh_snb *snb) +{ + if (snb_cb_ptr) { + snb_cb_ptr(snb); + } +} + +BT_MESH_BEACON_CB_DEFINE(snb) = { + .snb_received = snb_received, +}; + /* Setting for scanner defining what beacon is expected next, SNB as default */ static uint8_t expected_beacon = BEACON_TYPE_SECURE; #if CONFIG_BT_MESH_V1d1 @@ -992,6 +1008,62 @@ static void test_rx_secure_beacon_interval(void) PASS(); } +static uint8_t snb_cnt; + +static void snb_recv(const struct bt_mesh_snb *snb) +{ + /* IV idx of 2 marks end of test */ + if (snb->iv_idx == 2) { + k_sem_give(&beacon_sem); + return; + } + + ASSERT_EQUAL(snb->flags, 0x02); + ASSERT_EQUAL(snb->iv_idx, 1); + snb_cnt++; +} + +static void test_rx_beacon_cache(void) +{ + k_sem_init(&beacon_sem, 0, 1); + snb_cb_ptr = snb_recv; + + bt_mesh_test_cfg_set(&rx_cfg, WAIT_TIME); + bt_mesh_test_setup(); + + /* Wait for secondary SNB to end test. */ + ASSERT_OK_MSG(k_sem_take(&beacon_sem, K_SECONDS(40)), + "Didn't receive SNB in time"); + + /* Verify that only one SNB for IV_idx=1 was handled. */ + ASSERT_EQUAL(snb_cnt, 1); + PASS(); +} + +static void test_tx_beacon_cache(void) +{ + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_crypto_init(); + ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed"); + + NET_BUF_SIMPLE_DEFINE(iv1, 22); + NET_BUF_SIMPLE_DEFINE(iv2, 22); + beacon_create(&iv1, test_net_key, 0x02, 0x0001); + beacon_create(&iv2, test_net_key, 0x02, 0x0002); + + /* Send two copies of the same SNB. */ + for (size_t i = 0; i < 2; i++) { + k_sleep(K_SECONDS(5)); + send_beacon(&iv1); + } + + /* Send secondary SNB to mark end of test. */ + k_sleep(K_SECONDS(5)); + send_beacon(&iv2); + + PASS(); +} + #if CONFIG_BT_MESH_V1d1 static bool private_beacon_check(const uint8_t *net_id, void *ctx) { @@ -1780,6 +1852,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(tx, kr_old_key, "Beacon: send old Net Key"), TEST_CASE(tx, multiple_netkeys, "Beacon: multiple Net Keys"), TEST_CASE(tx, secure_beacon_interval, "Beacon: send secure beacons"), + TEST_CASE(tx, beacon_cache, "Beacon: advertise duplicate SNBs"), #if CONFIG_BT_MESH_V1d1 TEST_CASE(tx, priv_on_iv_update, "Private Beacon: send on IV update"), TEST_CASE(tx, priv_on_key_refresh, "Private Beacon: send on Key Refresh"), @@ -1800,6 +1873,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(rx, kr_old_key, "Beacon: receive old Net Key"), TEST_CASE(rx, multiple_netkeys, "Beacon: multiple Net Keys"), TEST_CASE(rx, secure_beacon_interval, "Beacon: receive and send secure beacons"), + TEST_CASE(rx, beacon_cache, "Beacon: receive duplicate SNBs"), #if CONFIG_BT_MESH_V1d1 TEST_CASE(rx, priv_adv, "Private Beacon: verify random regeneration"), TEST_CASE(rx, priv_invalid, "Private Beacon: receive invalid beacons"), diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh new file mode 100755 index 00000000000..c0f741e9aae --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Beacon cache +# +# Test procedure: +# 0. RX device starts monitoring all accepted SNB messages. +# 1. TX device sends two identical SNBs to the RX device. +# 2. TX device sends a secondary SNBs to the RX device, marking the end of the test. +# 3. RX device verifies that only one of the two identical beacons was processed. +RunTest mesh_beacon_cache \ + beacon_tx_beacon_cache \ + beacon_rx_beacon_cache + +conf=prj_mesh1d1_conf +RunTest mesh_beacon_cache \ + beacon_tx_beacon_cache \ + beacon_rx_beacon_cache + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_beacon_cache \ + beacon_tx_beacon_cache \ + beacon_rx_beacon_cache From cc878331163309143ff39e11fb27175362366030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 12 Oct 2023 15:16:43 +0200 Subject: [PATCH 2243/4498] tests: Bluetooth: Mesh: Add priv beacon cache test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Bsim test that verifies private beacon cache functionality. The test checks that replays of the same private beacon message is discarded. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 1 + tests/bsim/bluetooth/mesh/src/test_beacon.c | 75 +++++++++++++++++++ .../priv_beacon/priv_beacon_cache.sh | 24 ++++++ 3 files changed, 100 insertions(+) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_cache.sh diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index 15df7b8a5d3..8bfb3b9e887 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -66,6 +66,7 @@ CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y CONFIG_BT_MESH_OD_PRIV_PROXY_CLI=y CONFIG_BT_MESH_COMP_PAGE_1=y CONFIG_BT_MESH_COMP_PAGE_2=y +CONFIG_BT_TESTING=y # Needed for RPR tests due to huge amount of retransmitted messages CONFIG_BT_MESH_MSG_CACHE_SIZE=64 diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index d72b8322478..b80d777ba01 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -1065,6 +1065,22 @@ static void test_tx_beacon_cache(void) } #if CONFIG_BT_MESH_V1d1 + +typedef void (*priv_beacon_cb)(const struct bt_mesh_prb *prb); + +static priv_beacon_cb priv_beacon_cb_ptr; + +static void priv_received(const struct bt_mesh_prb *prb) +{ + if (priv_beacon_cb_ptr) { + priv_beacon_cb_ptr(prb); + } +} + +BT_MESH_BEACON_CB_DEFINE(priv_beacon) = { + .priv_received = priv_received, +}; + static bool private_beacon_check(const uint8_t *net_id, void *ctx) { bool ret; @@ -1467,6 +1483,63 @@ static void test_rx_priv_interleave(void) PASS(); } +static uint8_t prb_cnt; + +static void priv_beacon_recv(const struct bt_mesh_prb *prb) +{ + /* IV idx of 2 marks end of test */ + if (prb->iv_idx == 2) { + k_sem_give(&beacon_sem); + return; + } + + ASSERT_EQUAL(prb->flags, 0x02); + ASSERT_EQUAL(prb->iv_idx, 1); + prb_cnt++; +} + +static void test_rx_priv_beacon_cache(void) +{ + k_sem_init(&beacon_sem, 0, 1); + priv_beacon_cb_ptr = priv_beacon_recv; + + bt_mesh_test_cfg_set(&rx_cfg, WAIT_TIME); + bt_mesh_device_setup(&prov, &prb_comp); + provision(&rx_cfg); + + /* Wait for secondary private beacon to end test. */ + ASSERT_OK_MSG(k_sem_take(&beacon_sem, K_SECONDS(40)), + "Didn't receive private beacon in time"); + + /* Verify that only one private beacon for IV_idx=1 was handled. */ + ASSERT_EQUAL(prb_cnt, 1); + PASS(); +} + +static void test_tx_priv_beacon_cache(void) +{ + bt_mesh_test_cfg_set(NULL, WAIT_TIME); + bt_mesh_crypto_init(); + ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed"); + + NET_BUF_SIMPLE_DEFINE(iv1, 27); + NET_BUF_SIMPLE_DEFINE(iv2, 27); + private_beacon_create(&iv1, test_net_key, 0x02, 0x0001); + private_beacon_create(&iv2, test_net_key, 0x02, 0x0002); + + /* Send two copies of the same private beacon. */ + for (size_t i = 0; i < 2; i++) { + k_sleep(K_SECONDS(5)); + send_beacon(&iv1); + } + + /* Send secondary private beacon to mark end of test. */ + k_sleep(K_SECONDS(5)); + send_beacon(&iv2); + + PASS(); +} + #if IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) #define BEACON_TYPE_PRIVATE_NET_ID 2 @@ -1859,6 +1932,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(tx, priv_adv, "Private Beacon: advertise Private Beacons"), TEST_CASE(tx, priv_invalid, "Private Beacon: advertise invalid beacons"), TEST_CASE(tx, priv_interleave, "Private Beacon: advertise interleaved with SNB"), + TEST_CASE(tx, priv_beacon_cache, "Private Beacon: advertise duplicate Private Beacons"), #if CONFIG_BT_MESH_GATT_PROXY TEST_CASE(tx, priv_net_id, "Private Proxy: advertise Net ID"), TEST_CASE(tx, priv_node_id, "Private Proxy: advertise Node ID"), @@ -1878,6 +1952,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(rx, priv_adv, "Private Beacon: verify random regeneration"), TEST_CASE(rx, priv_invalid, "Private Beacon: receive invalid beacons"), TEST_CASE(rx, priv_interleave, "Private Beacon: interleaved with SNB"), + TEST_CASE(rx, priv_beacon_cache, "Private Beacon: receive duplicate Private Beacons"), #if CONFIG_BT_MESH_GATT_PROXY TEST_CASE(rx, priv_net_id, "Private Proxy: scan for Net ID"), TEST_CASE(rx, priv_node_id, "Private Proxy: scan for Node ID"), diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_cache.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_cache.sh new file mode 100755 index 00000000000..0cb5cdaea0a --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_cache.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Private Beacon cache +# +# Test procedure: +# 0. RX device starts monitoring all accepted private beacon messages. +# 1. TX device sends two identical private beacons to the RX device. +# 2. TX device sends a secondary private beacons to the RX device, marking the end of the test. +# 3. RX device verifies that only one of the two identical beacons was processed. + +conf=prj_mesh1d1_conf +RunTest mesh_priv_beacon_cache \ + beacon_tx_priv_beacon_cache \ + beacon_rx_priv_beacon_cache + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_priv_beacon_cache \ + beacon_tx_priv_beacon_cache \ + beacon_rx_priv_beacon_cache From 098b5bd05be5b371dc516552f42aee52548e80bc Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Thu, 12 Oct 2023 16:25:01 +0200 Subject: [PATCH 2244/4498] tests: bsim: send SIGKILL if app doesn't respond to SIGTERM I have seen the CI hang (both downstream and upstream) as the executable doesn't always respond to the SIGTERM sent by `timeout`. This will prevent that behavior. 5 whole seconds ought to be enough to clean-up a small program. Signed-off-by: Jonathan Rico --- tests/bsim/sh_common.source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/sh_common.source b/tests/bsim/sh_common.source index 05c29c79070..ddcce6df818 100644 --- a/tests/bsim/sh_common.source +++ b/tests/bsim/sh_common.source @@ -43,5 +43,5 @@ function Execute() { EXECUTE_TIMEOUT="${EXECUTE_TIMEOUT:-30}" check_program_exists $1 - run_in_background timeout -v ${EXECUTE_TIMEOUT} $@ + run_in_background timeout --kill-after=5 -v ${EXECUTE_TIMEOUT} $@ } From 297234138891272565b7d24d997382164bc394a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alperen=20=C5=9Eener?= Date: Thu, 12 Oct 2023 16:27:47 +0200 Subject: [PATCH 2245/4498] tests: bluetooth: tester: add page number to response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PTS requires IUT to send requests with page number with 0xFF or the highest supported page number in order to retrieve all the composition data pages from the lower tester. This commit add the page number to the response, thus the upper tester can follow the last page number and send the next page request until page 0 is requested. Signed-off-by: Alperen Şener --- tests/bluetooth/tester/src/btp_mesh.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 1d6f696f729..c43f19f04ce 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -2033,8 +2033,9 @@ static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - memcpy(rp->data, comp->data, comp->len); - *rsp_len = comp->len; + rp->data[0] = page; + memcpy(rp->data + 1, comp->data, comp->len); + *rsp_len = comp->len + 1; return BTP_STATUS_SUCCESS; } From b7df39f81fe705d83341de17c209fafa17c24c6e Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Fri, 29 Sep 2023 09:36:08 +0100 Subject: [PATCH 2246/4498] net: ip: Clarify highest priority traffic class The priority 3 (Critical applications) was incorrectly marked as "highest priority", which might have led to incorrect use of NET_PRIORITY_CA in some cases. Note that this is already correctly advertized in other places, as it was partially fixed in af8a0b1a5dec4dfcdbba3f4fee9d267e56df7971. NET_TC_SKIP_FOR_HIGH_PRIO was previously only allowing to push priority 3 (Critical applications) packets directly to the driver, but not the ones with a higher priority. Change it so that it is now in effect for priority 3 and above. Signed-off-by: Ambroise Vincent --- include/zephyr/net/net_ip.h | 4 ++-- subsys/net/ip/Kconfig | 4 ++-- subsys/net/ip/net_if.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/net_ip.h b/include/zephyr/net/net_ip.h index 6c78428c1c7..a1c4294bd61 100644 --- a/include/zephyr/net/net_ip.h +++ b/include/zephyr/net/net_ip.h @@ -423,11 +423,11 @@ enum net_priority { NET_PRIORITY_BK = 1, /**< Background (lowest) */ NET_PRIORITY_BE = 0, /**< Best effort (default) */ NET_PRIORITY_EE = 2, /**< Excellent effort */ - NET_PRIORITY_CA = 3, /**< Critical applications (highest) */ + NET_PRIORITY_CA = 3, /**< Critical applications */ NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */ NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter */ NET_PRIORITY_IC = 6, /**< Internetwork control */ - NET_PRIORITY_NC = 7 /**< Network control */ + NET_PRIORITY_NC = 7 /**< Network control (highest) */ } __packed; #define NET_MAX_PRIORITIES 8 /* How many priority values there are */ diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index b85da2a03de..d3e1fb593bf 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -219,8 +219,8 @@ config NET_TC_RX_COUNT config NET_TC_SKIP_FOR_HIGH_PRIO bool "Push high priority packets directly to network driver" help - If this is set, then high priority (NET_PRIORITY_CA) net_pkt will be - pushed directly to network driver and will skip the traffic class + If this is set, then high priority (>= NET_PRIORITY_CA) net_pkt will + be pushed directly to network driver and will skip the traffic class queues. This is currently not enabled by default. choice NET_TC_THREAD_TYPE diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 1a84d07e926..66ee02252dc 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -348,7 +348,7 @@ void net_if_queue_tx(struct net_if *iface, struct net_pkt *pkt) * directly to the driver. */ if ((IS_ENABLED(CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO) && - prio == NET_PRIORITY_CA) || NET_TC_TX_COUNT == 0) { + prio >= NET_PRIORITY_CA) || NET_TC_TX_COUNT == 0) { net_pkt_set_tx_stats_tick(pkt, k_cycle_get_32()); net_if_tx(net_pkt_iface(pkt), pkt); From d0ac02a18d2dcf9b565509216a0aeecf6390d558 Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Fri, 29 Sep 2023 10:06:42 +0100 Subject: [PATCH 2247/4498] net: gptp: Invert priority of outgoing packets The previous implementation was setting priority 3 (Critical applications) for Sync, Pdelay and Pdelay_Resp messages; and priority 6 (Internetwork control) for the other PTP messages. This might have been done under the incorrect understanding that "Critical applications" was the highest priority. This resulted in the Pdelay_Resp_Follow_Up getting sent before the Pdelay_Resp message when enough TC_TX queues were being used (NET_TC_TX_COUNT >= 2), which is an inversion compared to the intended order. Invert the priority of the outgoing PTP packets so that the PTP event messages are sent with higher priority, as was originally intended. Signed-off-by: Ambroise Vincent --- subsys/net/l2/ethernet/gptp/gptp_messages.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/net/l2/ethernet/gptp/gptp_messages.c b/subsys/net/l2/ethernet/gptp/gptp_messages.c index f5d1d79c3ed..780c1dedb6f 100644 --- a/subsys/net/l2/ethernet/gptp/gptp_messages.c +++ b/subsys/net/l2/ethernet/gptp/gptp_messages.c @@ -198,7 +198,7 @@ struct net_pkt *gptp_prepare_sync(int port) return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_CA); + net_pkt_set_priority(pkt, NET_PRIORITY_IC); port_ds = GPTP_PORT_DS(port); sync = GPTP_SYNC(pkt); @@ -254,7 +254,7 @@ struct net_pkt *gptp_prepare_follow_up(int port, struct net_pkt *sync) return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_IC); + net_pkt_set_priority(pkt, NET_PRIORITY_CA); hdr = GPTP_HDR(pkt); fup = GPTP_FOLLOW_UP(pkt); @@ -318,7 +318,7 @@ struct net_pkt *gptp_prepare_pdelay_req(int port) return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_CA); + net_pkt_set_priority(pkt, NET_PRIORITY_IC); port_ds = GPTP_PORT_DS(port); req = GPTP_PDELAY_REQ(pkt); @@ -373,7 +373,7 @@ struct net_pkt *gptp_prepare_pdelay_resp(int port, return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_CA); + net_pkt_set_priority(pkt, NET_PRIORITY_IC); port_ds = GPTP_PORT_DS(port); @@ -434,7 +434,7 @@ struct net_pkt *gptp_prepare_pdelay_follow_up(int port, return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_IC); + net_pkt_set_priority(pkt, NET_PRIORITY_CA); port_ds = GPTP_PORT_DS(port); @@ -503,7 +503,7 @@ struct net_pkt *gptp_prepare_announce(int port) return NULL; } - net_pkt_set_priority(pkt, NET_PRIORITY_IC); + net_pkt_set_priority(pkt, NET_PRIORITY_CA); hdr = GPTP_HDR(pkt); ann = GPTP_ANNOUNCE(pkt); From 357f88bb596fd4cf6f4e4788fb25e16184c7c36b Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Mon, 9 Oct 2023 16:03:05 +0100 Subject: [PATCH 2248/4498] net: ethernet: Don't use VLAN tag on gPTP messages According to IEEE Std 802.1AS-2011 11.3.3, gPTP messages are not VLAN-tagged. Remove the use of VLAN headers for gPTP messages on the TX path. The RX path is handled by the drivers. The network drivers in Zephyr might need to be updated as well in order to accept receiving non-VLAN-tagged gPTP messages when the CONFIG_NET_VLAN option is selected. Continue sending gPTP packets with VLAN tags when CONFIG_NET_GPTP_VLAN is enabled. Specify that this option is for testing purposes. Signed-off-by: Ambroise Vincent --- subsys/net/l2/ethernet/ethernet.c | 6 ++++-- subsys/net/l2/ethernet/gptp/Kconfig | 11 +++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index c62c986d838..97990dbc451 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -518,7 +518,8 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx, } if (IS_ENABLED(CONFIG_NET_VLAN) && - net_eth_is_vlan_enabled(ctx, net_pkt_iface(pkt))) { + net_eth_is_vlan_enabled(ctx, net_pkt_iface(pkt)) && + (IS_ENABLED(CONFIG_NET_GPTP_VLAN) || ptype != htons(NET_ETH_PTYPE_PTP))) { struct net_eth_vlan_hdr *hdr_vlan; hdr_vlan = (struct net_eth_vlan_hdr *)(hdr_frag->data); @@ -695,7 +696,8 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt) } if (IS_ENABLED(CONFIG_NET_VLAN) && - net_eth_is_vlan_enabled(ctx, iface)) { + net_eth_is_vlan_enabled(ctx, iface) && + (IS_ENABLED(CONFIG_NET_GPTP_VLAN) || ptype != htons(NET_ETH_PTYPE_PTP))) { if (set_vlan_tag(ctx, iface, pkt) == NET_DROP) { ret = -EINVAL; goto error; diff --git a/subsys/net/l2/ethernet/gptp/Kconfig b/subsys/net/l2/ethernet/gptp/Kconfig index 357edc2553d..661288180f1 100644 --- a/subsys/net/l2/ethernet/gptp/Kconfig +++ b/subsys/net/l2/ethernet/gptp/Kconfig @@ -117,10 +117,13 @@ config NET_GPTP_VLAN select NET_MGMT_EVENT select NET_MGMT_EVENT_INFO help - This setting allows gPTP to run over VLAN link. Currently only - one port can have VLAN tag set. Note that CONFIG_NET_GPTP_VLAN_TAG - setting must have a proper tag value set, otherwise the gPTP over - VLAN will not work. + The standard requires gPTP packets to not be VLAN-tagged (see IEEE + 802.1AS chapter 11.3.3). + This setting is for testing purposes. It allows to deviate from the + standard by running gPTP over a VLAN link. Currently only one port can + have VLAN tag set. Note that CONFIG_NET_GPTP_VLAN_TAG setting must + have a proper tag value set, otherwise the gPTP over VLAN will not + work. config NET_GPTP_VLAN_TAG int "VLAN tag to use" From 68dfd819c14b945faaa217b02070f448c6ce3ca0 Mon Sep 17 00:00:00 2001 From: Ambroise Vincent Date: Thu, 12 Oct 2023 08:48:56 +0100 Subject: [PATCH 2249/4498] net: gptp: Create a stack size Kconfig option The stack size was previously hardcoded in the source code, making it difficult to change when enabling options that require a larger stack. Signed-off-by: Ambroise Vincent --- subsys/net/l2/ethernet/gptp/Kconfig | 7 +++++++ subsys/net/l2/ethernet/gptp/gptp.c | 4 +--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/subsys/net/l2/ethernet/gptp/Kconfig b/subsys/net/l2/ethernet/gptp/Kconfig index 661288180f1..59dcbae2327 100644 --- a/subsys/net/l2/ethernet/gptp/Kconfig +++ b/subsys/net/l2/ethernet/gptp/Kconfig @@ -103,6 +103,13 @@ config NET_GPTP_CLOCK_ACCURACY default 0x31 if NET_GPTP_CLOCK_ACCURACY_GT_10S default 0xfe +config NET_GPTP_STACK_SIZE + int "gPTP thread stack size" + default 2048 + help + Set the gPTP thread stack size in bytes. The gPTP thread handles the + gPTP state machine. There is one gPTP thread in the system. + config NET_GPTP_NUM_PORTS int "Number of gPTP ports" default 1 diff --git a/subsys/net/l2/ethernet/gptp/gptp.c b/subsys/net/l2/ethernet/gptp/gptp.c index f72386a1e46..3f822ad548c 100644 --- a/subsys/net/l2/ethernet/gptp/gptp.c +++ b/subsys/net/l2/ethernet/gptp/gptp.c @@ -20,8 +20,6 @@ LOG_MODULE_REGISTER(net_gptp, CONFIG_NET_GPTP_LOG_LEVEL); #include "gptp_private.h" -#define NET_GPTP_STACK_SIZE 2048 - #if CONFIG_NET_GPTP_NUM_PORTS > 32 /* * Boolean arrays sizes have been hardcoded. @@ -31,7 +29,7 @@ LOG_MODULE_REGISTER(net_gptp, CONFIG_NET_GPTP_LOG_LEVEL); #error Maximum number of ports exceeded. (Max is 32). #endif -K_KERNEL_STACK_DEFINE(gptp_stack, NET_GPTP_STACK_SIZE); +K_KERNEL_STACK_DEFINE(gptp_stack, CONFIG_NET_GPTP_STACK_SIZE); K_FIFO_DEFINE(gptp_rx_queue); static k_tid_t tid; From 943e434559df34bfab1e3ec3d185364fc6617338 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 12 Oct 2023 10:50:53 -0700 Subject: [PATCH 2250/4498] mm: introduce CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK Sometimes the generic address range checker is not adequate (think Xtensa cached/uncached pointers). This provides a way to implement custom memory range checkers for those situations. When enabled, sys_mm_is_phys_addr_in_range() and sys_mm_is_virt_addr_in_range() must be implemented. Signed-off-by: Daniel Leung --- include/zephyr/sys/mem_manage.h | 48 ++++++++++++++++++++++++++++++++- kernel/Kconfig.vm | 9 +++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/zephyr/sys/mem_manage.h b/include/zephyr/sys/mem_manage.h index 1dfbabcc3b0..fe6d54ba3fe 100644 --- a/include/zephyr/sys/mem_manage.h +++ b/include/zephyr/sys/mem_manage.h @@ -143,12 +143,53 @@ struct k_mem_paging_histogram_t { #endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ }; +/** + * @brief Check if a physical address is within range of physical memory. + * + * This checks if the physical address (@p virt) is within + * permissible range, e.g. between + * :kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` and + * (:kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` + + * :kconfig:option:`CONFIG_SRAM_SIZE`). + * + * @note Only used if + * :kconfig:option:`CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK` + * is enabled. + * + * @param phys Physical address to be checked. + * + * @return True if physical address is within range, false if not. + */ +bool sys_mm_is_phys_addr_in_range(uintptr_t phys); + +/** + * @brief Check if a virtual address is within range of virtual memory. + * + * This checks if the virtual address (@p virt) is within + * permissible range, e.g. between + * :kconfig:option:`CONFIG_KERNEL_VM_BASE` and + * (:kconfig:option:`CONFIG_KERNEL_VM_BASE` + + * :kconfig:option:`CONFIG_KERNEL_VM_SIZE`). + * + * @note Only used if + * :kconfig:option:`CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK` + * is enabled. + * + * @param virt Virtual address to be checked. + * + * @return True if virtual address is within range, false if not. + */ +bool sys_mm_is_virt_addr_in_range(void *virt); + /* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */ static inline uintptr_t z_mem_phys_addr(void *virt) { uintptr_t addr = (uintptr_t)virt; -#ifdef CONFIG_MMU +#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) + __ASSERT(sys_mm_is_virt_addr_in_range(virt), + "address %p not in permanent mappings", virt); +#elif defined(CONFIG_MMU) __ASSERT( #if CONFIG_KERNEL_VM_BASE != 0 (addr >= CONFIG_KERNEL_VM_BASE) && @@ -178,6 +219,10 @@ static inline uintptr_t z_mem_phys_addr(void *virt) /* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */ static inline void *z_mem_virt_addr(uintptr_t phys) { +#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) + __ASSERT(sys_mm_is_phys_addr_in_range(phys), + "physical address 0x%lx not in RAM", (unsigned long)phys); +#else __ASSERT( #if CONFIG_SRAM_BASE_ADDRESS != 0 (phys >= CONFIG_SRAM_BASE_ADDRESS) && @@ -185,6 +230,7 @@ static inline void *z_mem_virt_addr(uintptr_t phys) (phys < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL))), "physical address 0x%lx not in RAM", (unsigned long)phys); +#endif /* TODO add assertion that this page frame is pinned to boot mapping, * the above check won't be sufficient with demand paging diff --git a/kernel/Kconfig.vm b/kernel/Kconfig.vm index 1845c24c16b..97d6c1f424b 100644 --- a/kernel/Kconfig.vm +++ b/kernel/Kconfig.vm @@ -198,4 +198,13 @@ config DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS endif # DEMAND_PAGING endif # MMU +config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK + bool + help + Use custom memory range check functions instead of the generic + checks in z_mem_phys_addr() and z_mem_virt_addr(). + + sys_mm_is_phys_addr_in_range() and + sys_mm_is_virt_addr_in_range() must be implemented. + endmenu # Virtual Memory Support From cdd4d8470323ad735c417ff452f0b8f5ed5ecd55 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 12 Oct 2023 11:00:45 -0700 Subject: [PATCH 2251/4498] xtensa: add custom mem range check functions This provides custom memory range check functions as it gets a bit complicated with cached/uncached regions. These functions are marked as __weak so SoC or board can override these if needed. Signed-off-by: Daniel Leung --- arch/xtensa/Kconfig | 1 + arch/xtensa/core/CMakeLists.txt | 5 +++++ arch/xtensa/core/mem_manage.c | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 arch/xtensa/core/mem_manage.c diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 6095a7046d7..29c06667f55 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -126,6 +126,7 @@ config XTENSA_MMU default n select MMU select XTENSA_SMALL_VECTOR_TABLE_ENTRY + select KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK if XTENSA_RPO_CACHE help Enable support for Xtensa Memory Management Unit. diff --git a/arch/xtensa/core/CMakeLists.txt b/arch/xtensa/core/CMakeLists.txt index 3bf29e88b64..c6fffd4f5e1 100644 --- a/arch/xtensa/core/CMakeLists.txt +++ b/arch/xtensa/core/CMakeLists.txt @@ -23,6 +23,11 @@ zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) zephyr_library_sources_ifdef(CONFIG_GDBSTUB gdbstub.c) zephyr_library_sources_ifdef(CONFIG_XTENSA_MMU xtensa_mmu.c) +zephyr_library_sources_ifdef( + CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK + mem_manage.c +) + if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "xcc") zephyr_library_sources(xcc_stubs.c) endif() diff --git a/arch/xtensa/core/mem_manage.c b/arch/xtensa/core/mem_manage.c new file mode 100644 index 00000000000..ee2d162c835 --- /dev/null +++ b/arch/xtensa/core/mem_manage.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +__weak bool sys_mm_is_phys_addr_in_range(uintptr_t phys) +{ + bool valid; + uintptr_t cached = (uintptr_t)arch_xtensa_cached_ptr((void *)phys); + + valid = ((phys >= CONFIG_SRAM_BASE_ADDRESS) && + (phys < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)))); + + valid |= ((cached >= CONFIG_SRAM_BASE_ADDRESS) && + (cached < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)))); + + return valid; +} + +__weak bool sys_mm_is_virt_addr_in_range(void *virt) +{ + bool valid; + uintptr_t addr = (uintptr_t)virt; + + uintptr_t cached = (uintptr_t)arch_xtensa_cached_ptr(virt); + + valid = ((addr >= CONFIG_KERNEL_VM_BASE) && + (addr < (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE))); + + valid |= ((cached >= CONFIG_KERNEL_VM_BASE) && + (cached < (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE))); + + return valid; +} From 84f679d22dae1684bf9a586e8514b1c9152a38b5 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 12 Oct 2023 14:32:43 -0700 Subject: [PATCH 2252/4498] logging: Fix misuse of const and k_tid_t "const k_tid_t" is "struct k_thread * const" and not "const struct k_thread *" as the code may be assuming. Just drop it. Signed-off-by: Flavio Ceolin --- include/zephyr/logging/log_output.h | 2 +- subsys/logging/log_output.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/logging/log_output.h b/include/zephyr/logging/log_output.h index e55170605c9..dff4ff81dcd 100644 --- a/include/zephyr/logging/log_output.h +++ b/include/zephyr/logging/log_output.h @@ -159,7 +159,7 @@ void log_output_process(const struct log_output *log_output, log_timestamp_t timestamp, const char *domain, const char *source, - const k_tid_t tid, + k_tid_t tid, uint8_t level, const uint8_t *package, const uint8_t *data, diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index 8a3fad06027..b93f3439961 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -328,7 +328,7 @@ static int ids_print(const struct log_output *output, bool thread_on, const char *domain, const char *source, - const k_tid_t tid, + k_tid_t tid, uint32_t level) { int total = 0; @@ -441,7 +441,7 @@ static uint32_t prefix_print(const struct log_output *output, log_timestamp_t timestamp, const char *domain, const char *source, - const k_tid_t tid, + k_tid_t tid, uint8_t level) { __ASSERT_NO_MSG(level <= LOG_LEVEL_DBG); @@ -506,7 +506,7 @@ void log_output_process(const struct log_output *output, log_timestamp_t timestamp, const char *domain, const char *source, - const k_tid_t tid, + k_tid_t tid, uint8_t level, const uint8_t *package, const uint8_t *data, From 136c5a9d572f0e7f2674774bf8f170eefd50001d Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 12 Oct 2023 16:07:08 +0200 Subject: [PATCH 2253/4498] tests: bluetooth: tester: Fix BLOB server model pointer PTS uses BLOB server model instantiated by DFD server for MBT tests as it is the first BLOB server model in the device composition data. DFU server, which also has BLOB server model, is instantiated after DFD server. Signed-off-by: Pavel Vasilyev --- tests/bluetooth/tester/src/btp_mesh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c43f19f04ce..5eff344540e 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -4468,10 +4468,10 @@ static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, struct model_data *model_bound; int err; -#if defined(CONFIG_BT_MESH_DFU_SRV) - struct bt_mesh_blob_srv *srv = &dfu_srv.blob; -#elif defined(CONFIG_BT_MESH_DFD_SRV) +#if defined(CONFIG_BT_MESH_DFD_SRV) struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; +#elif defined(CONFIG_BT_MESH_DFU_SRV) + struct bt_mesh_blob_srv *srv = &dfu_srv.blob; #endif model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); From 6a2c102aca9399bc0c14e5785076d147d2722f70 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Mon, 16 Oct 2023 13:19:29 +0200 Subject: [PATCH 2254/4498] Bluetooth: Mesh: Keep sending Partial Block Report message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the BLOB server is in Pull mode and all chunks were received for the current block, and the current block is the last block, then according to section 5.2.4 of MshMBTv1.0 the server should stop sending BLOB Partial Block Report messages if it determines that the client knows that the transfer is complete: ``` While the Pull BLOB State Machine is in the All Chunks Received state, the Pull BLOB State Machine continues to send the BLOB Partial Block Report messages until one of the following happens: • The Receive BLOB Timeout timer expires. • If the current block is not the last block, then the client starts a new block, in which case a new Pull BLOB State Machine is instantiated. • If the current block is the last block, then the server determines that the client knows the transfer is complete. For example, a higher-layer model may indicate that the client considers the transfer complete. ``` We currently don't have any OOB mean (for example, API) to determine whether the client knows that the transfer is complete. We also need to keep in mind that the Partial Block Report message can get lost so one transmission may not be enough. The client could immediately send BLOB Transfer Get message to get the transfer status, but this goes against its state machine defined in section 6.2.4.2, where a Block transmission completes when a BLOB Partial Block Report message is received with an empty list of requested chunks (table 6.4, figure 6.1). Because of this, we need to keep sending Partial Block Report messages. We can keep sending them at least until Block Report timer expires. If the client sends BLOB Transfer Get message, then it finished with sending the block and we can change the phase and finish the transfer. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/blob_srv.c | 70 +++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/mesh/blob_srv.c b/subsys/bluetooth/mesh/blob_srv.c index 56a89472ea6..1e6cb9bc91a 100644 --- a/subsys/bluetooth/mesh/blob_srv.c +++ b/subsys/bluetooth/mesh/blob_srv.c @@ -251,6 +251,37 @@ static void resume(struct bt_mesh_blob_srv *srv) reset_timer(srv); } +static void end(struct bt_mesh_blob_srv *srv) +{ + phase_set(srv, BT_MESH_BLOB_XFER_PHASE_COMPLETE); + k_work_cancel_delayable(&srv->rx_timeout); + k_work_cancel_delayable(&srv->pull.report); + io_close(srv); + erase_state(srv); + + if (srv->cb && srv->cb->end) { + srv->cb->end(srv, srv->state.xfer.id, true); + } +} + +static bool all_blocks_received(struct bt_mesh_blob_srv *srv) +{ + for (int i = 0; i < ARRAY_SIZE(srv->state.blocks); ++i) { + if (srv->state.blocks[i]) { + return false; + } + } + + return true; +} + +static bool pull_mode_xfer_complete(struct bt_mesh_blob_srv *srv) +{ + return srv->state.xfer.mode == BT_MESH_BLOB_XFER_MODE_PULL && + srv->phase == BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK && + all_blocks_received(srv); +} + static void timeout(struct k_work *work) { struct bt_mesh_blob_srv *srv = @@ -260,6 +291,8 @@ static void timeout(struct k_work *work) if (srv->phase == BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START) { cancel(srv); + } else if (pull_mode_xfer_complete(srv)) { + end(srv); } else { suspend(srv); } @@ -388,6 +421,15 @@ static int handle_xfer_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct struct bt_mesh_blob_srv *srv = mod->user_data; LOG_DBG(""); + + if (pull_mode_xfer_complete(srv)) { + /* The client requested transfer. If we are in Pull mode and all blocks were + * received, we should change the Transfer state here to Complete so that the client + * receives the correct state. + */ + end(srv); + } + xfer_status_rsp(srv, ctx, BT_MESH_BLOB_SUCCESS); return 0; @@ -685,7 +727,7 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_blob_chunk chunk; size_t expected_size = 0; uint16_t idx; - int i, err; + int err; idx = net_buf_simple_pull_le16(buf); chunk.size = buf->len; @@ -745,26 +787,26 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, atomic_clear_bit(srv->state.blocks, srv->block.number); - for (i = 0; i < ARRAY_SIZE(srv->state.blocks); ++i) { - if (!srv->state.blocks[i]) { - continue; - } - + if (!all_blocks_received(srv)) { phase_set(srv, BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK); store_state(srv); return 0; } - phase_set(srv, BT_MESH_BLOB_XFER_PHASE_COMPLETE); - k_work_cancel_delayable(&srv->rx_timeout); - k_work_cancel_delayable(&srv->pull.report); - io_close(srv); - erase_state(srv); - - if (srv->cb && srv->cb->end) { - srv->cb->end(srv, srv->state.xfer.id, true); + if (srv->state.xfer.mode == BT_MESH_BLOB_XFER_MODE_PULL) { + /* By spec (section 5.2.4), the BLOB Server stops sending BLOB Partial Block Report + * messages "If the current block is the last block, then the server determines that + * the client knows the transfer is complete. For example, a higher-layer model may + * indicate that the client considers the transfer complete." + * + * We don't have any way for higher-layer model to indicate that the transfer is + * complete. Therefore we need to keep sending Partial Block Report messages until + * the client sends BLOB Transfer Get message or the Block Timer expires. + */ + return 0; } + end(srv); return 0; } From 5b8a9517a1ceaa0370888205e42d94284af7804d Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 18 Oct 2023 12:55:20 +0200 Subject: [PATCH 2255/4498] tests: bluetooth: tester: Allow to compile mesh without LPN This can be needed to qualify features without LPN support. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/host/testing.c | 2 ++ tests/bluetooth/tester/src/btp_mesh.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/subsys/bluetooth/host/testing.c b/subsys/bluetooth/host/testing.c index c3121fd230d..3c118c51e0f 100644 --- a/subsys/bluetooth/host/testing.c +++ b/subsys/bluetooth/host/testing.c @@ -102,6 +102,7 @@ void bt_test_mesh_trans_incomp_timer_exp(void) } } +#if defined(CONFIG_BT_MESH_LOW_POWER) int bt_test_mesh_lpn_group_add(uint16_t group) { bt_mesh_lpn_group_add(group); @@ -115,6 +116,7 @@ int bt_test_mesh_lpn_group_remove(uint16_t *groups, size_t groups_count) return 0; } +#endif /* CONFIG_BT_MESH_LOW_POWER */ int bt_test_mesh_rpl_clear(void) { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 5eff344540e..bdc37c2f2e5 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1553,6 +1553,7 @@ static uint8_t ivu_toggle_state(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if defined(CONFIG_BT_MESH_LOW_POWER) static uint8_t lpn(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1584,6 +1585,7 @@ static uint8_t lpn_poll(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#endif /* CONFIG_BT_MESH_LOW_POWER */ static uint8_t net_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -1765,6 +1767,7 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, } #if defined(CONFIG_BT_TESTING) +#if defined(CONFIG_BT_MESH_LOW_POWER) static uint8_t lpn_subscribe(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1800,6 +1803,7 @@ static uint8_t lpn_unsubscribe(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#endif /* CONFIG_BT_MESH_LOW_POWER */ static uint8_t rpl_clear(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -4579,6 +4583,7 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = ivu_toggle_state, }, +#if defined(CONFIG_BT_MESH_LOW_POWER) { .opcode = BTP_MESH_LPN, .expect_len = sizeof(struct btp_mesh_lpn_set_cmd), @@ -4589,6 +4594,7 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = lpn_poll, }, +#endif /* CONFIG_BT_MESH_LOW_POWER */ { .opcode = BTP_MESH_NET_SEND, .expect_len = BTP_HANDLER_LENGTH_VARIABLE, @@ -4900,6 +4906,7 @@ static const struct btp_handler handlers[] = { .func = va_del, }, #if defined(CONFIG_BT_TESTING) +#if defined(CONFIG_BT_MESH_LOW_POWER) { .opcode = BTP_MESH_LPN_SUBSCRIBE, .expect_len = sizeof(struct btp_mesh_lpn_subscribe_cmd), @@ -4910,6 +4917,7 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_mesh_lpn_unsubscribe_cmd), .func = lpn_unsubscribe, }, +#endif /* CONFIG_BT_MESH_LOW_POWER */ { .opcode = BTP_MESH_RPL_CLEAR, .expect_len = 0, From 7904c6f0f3be4f1e096b10c87bf4b1f4a133f25c Mon Sep 17 00:00:00 2001 From: Jaxson Han Date: Fri, 13 Oct 2023 14:13:28 +0800 Subject: [PATCH 2256/4498] arch: arm64: Use voting lock for multi-core boot race condition The exclusive load/store instructions don't work well when MMU and cache are disabled on some cores e.g. Cortex-A72. Change it to voting lock[1] to select the primary core when multi-cores boot simultaneously. The voting lock has reasonable but minimal requirements on the memory system. [1] https://www.kernel.org/doc/html/next/arch/arm/vlocks.html Signed-off-by: Jaxson Han --- arch/arm64/core/boot.h | 5 +-- arch/arm64/core/macro_priv.inc | 21 +++++++++++ arch/arm64/core/reset.S | 65 ++++++++++++++++++++++++++-------- arch/arm64/core/smp.c | 4 ++- 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/arch/arm64/core/boot.h b/arch/arm64/core/boot.h index aa9e4526bba..d3f8e28eca3 100644 --- a/arch/arm64/core/boot.h +++ b/arch/arm64/core/boot.h @@ -20,7 +20,8 @@ extern void __start(void); #endif /* _ASMLANGUAGE */ /* Offsets into the boot_params structure */ -#define BOOT_PARAM_MPID_OFFSET 0 -#define BOOT_PARAM_SP_OFFSET 8 +#define BOOT_PARAM_MPID_OFFSET 0 +#define BOOT_PARAM_SP_OFFSET 8 +#define BOOT_PARAM_VOTING_OFFSET 16 #endif /* _BOOT_H_ */ diff --git a/arch/arm64/core/macro_priv.inc b/arch/arm64/core/macro_priv.inc index 616e705f47b..22cefe235fe 100644 --- a/arch/arm64/core/macro_priv.inc +++ b/arch/arm64/core/macro_priv.inc @@ -21,6 +21,27 @@ ubfx \xreg0, \xreg0, #0, #24 .endm +/* + * Get CPU logic id by looking up cpu_node_list + * returns + * xreg0: MPID + * xreg1: logic id (0 ~ CONFIG_MP_MAX_NUM_CPUS - 1) + * clobbers: xreg0, xreg1, xreg2, xreg3 + */ +.macro get_cpu_logic_id xreg0, xreg1, xreg2, xreg3 + get_cpu_id \xreg0 + ldr \xreg3, =cpu_node_list + mov \xreg1, 0 +1: ldr \xreg2, [\xreg3, \xreg1, lsl 3] + cmp \xreg2, \xreg0 + beq 2f + add \xreg1, \xreg1, 1 + cmp \xreg1, #CONFIG_MP_MAX_NUM_CPUS + bne 1b + b . +2: +.endm + /* * Get CPU pointer * Note: keep in sync with `arch_curr_cpu` in include/zephyr/arch/arm64/arch_inlines.h diff --git a/arch/arm64/core/reset.S b/arch/arm64/core/reset.S index 9b3b4462e85..81f11e6f2c9 100644 --- a/arch/arm64/core/reset.S +++ b/arch/arm64/core/reset.S @@ -121,38 +121,75 @@ resetwait: #if CONFIG_MP_MAX_NUM_CPUS > 1 + /* + * Deal with multi core booting simultaneously to race for being the primary core. + * Use voting lock[1] with reasonable but minimal requirements on the memory system + * to make sure only one core wins at last. + * + * [1] kernel.org/doc/html/next/arch/arm/vlocks.html + */ ldr x0, =arm64_cpu_boot_params - get_cpu_id x1 /* - * If the cores start up at the same time, we should atomically load and - * store the mpid into arm64_cpu_boot_params. + * Get the "logic" id defined by cpu_node_list statically for voting lock self-identify. + * It is worth noting that this is NOT the final logic id (arch_curr_cpu()->id) */ - ldaxr x2, [x0, #BOOT_PARAM_MPID_OFFSET] - cmp x2, #-1 - bne 1f - /* try to store x1 (mpid) */ - stlxr w3, x1, [x0] - /* If succeed, go to primary_core */ - cbz w3, primary_core + get_cpu_logic_id x1, x2, x3, x4 //x1: MPID, x2: logic id + + add x4, x0, #BOOT_PARAM_VOTING_OFFSET + + /* signal our desire to vote */ + mov w5, #1 + strb w5, [x4, x2] + ldr x3, [x0, #BOOT_PARAM_MPID_OFFSET] + cmn x3, #1 + beq 1f + + /* some core already won, release */ + strb wzr, [x4, x2] + b secondary_core + + /* suggest current core then release */ +1: str x1, [x0, #BOOT_PARAM_MPID_OFFSET] + strb wzr, [x4, x2] + dmb ish + + /* then wait until every core else is done voting */ + mov x5, #0 +2: ldrb w3, [x4, x5] + tst w3, #255 + /* wait */ + bne 2b + add x5, x5, #1 + cmp x5, #CONFIG_MP_MAX_NUM_CPUS + bne 2b + + + /* check if current core won */ + dmb ish + ldr x3, [x0, #BOOT_PARAM_MPID_OFFSET] + cmp x3, x1 + beq primary_core + /* fallthrough secondary */ /* loop until our turn comes */ -1: dmb ld +secondary_core: + dmb ish ldr x2, [x0, #BOOT_PARAM_MPID_OFFSET] cmp x1, x2 - bne 1b + bne secondary_core /* we can now load our stack pointer value and move on */ ldr x24, [x0, #BOOT_PARAM_SP_OFFSET] ldr x25, =z_arm64_secondary_prep_c - b 2f + b boot primary_core: #endif /* load primary stack and entry point */ ldr x24, =(z_interrupt_stacks + __z_interrupt_stack_SIZEOF) ldr x25, =z_arm64_prep_c -2: +boot: /* Prepare for calling C code */ bl __reset_prep_c diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index 6d21e5e9d7b..e67032eb2a4 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -35,6 +35,7 @@ struct boot_params { uint64_t mpid; char *sp; + uint8_t voting[CONFIG_MP_MAX_NUM_CPUS]; arch_cpustart_t fn; void *arg; int cpu_num; @@ -43,12 +44,13 @@ struct boot_params { /* Offsets used in reset.S */ BUILD_ASSERT(offsetof(struct boot_params, mpid) == BOOT_PARAM_MPID_OFFSET); BUILD_ASSERT(offsetof(struct boot_params, sp) == BOOT_PARAM_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, voting) == BOOT_PARAM_VOTING_OFFSET); volatile struct boot_params __aligned(L1_CACHE_BYTES) arm64_cpu_boot_params = { .mpid = -1, }; -static const uint64_t cpu_node_list[] = { +const uint64_t cpu_node_list[] = { DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,)) }; From 1d9098f3f0d217318de44512612386b3e4a75b07 Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Fri, 6 Oct 2023 10:40:06 +0300 Subject: [PATCH 2257/4498] net: coap: Add support for request-tag (RFC 9175) Add support for Request-Tag (RFC 9175) when doing block-wise send. Signed-off-by: Juha Ylinen --- include/zephyr/net/coap.h | 3 ++- include/zephyr/net/coap_client.h | 1 + subsys/net/lib/coap/coap_client.c | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 6fc21a6280b..77a6966794f 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -60,7 +60,8 @@ enum coap_option_num { COAP_OPTION_SIZE2 = 28, /**< Size2 (RFC 7959) */ COAP_OPTION_PROXY_URI = 35, /**< Proxy-Uri */ COAP_OPTION_PROXY_SCHEME = 39, /**< Proxy-Scheme */ - COAP_OPTION_SIZE1 = 60 /**< Size1 */ + COAP_OPTION_SIZE1 = 60, /**< Size1 */ + COAP_OPTION_REQUEST_TAG = 292 /**< Request-Tag (RFC 9175) */ }; /** diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h index 86c4911de5b..f836f339063 100644 --- a/include/zephyr/net/coap_client.h +++ b/include/zephyr/net/coap_client.h @@ -89,6 +89,7 @@ struct coap_client_internal_request { struct coap_pending pending; struct coap_client_request coap_request; struct coap_packet request; + uint8_t request_tag[COAP_TOKEN_MAX_LEN]; }; struct coap_client { diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index e78aafd6829..95a0f0d0ac4 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -215,6 +215,10 @@ static int coap_client_init_request(struct coap_client *client, coap_block_transfer_init(&internal_req->send_blk_ctx, coap_client_default_block_size(), req->len); + /* Generate request tag */ + uint8_t *tag = coap_next_token(); + + memcpy(internal_req->request_tag, tag, COAP_TOKEN_MAX_LEN); } ret = coap_append_block1_option(&internal_req->request, &internal_req->send_blk_ctx); @@ -223,6 +227,15 @@ static int coap_client_init_request(struct coap_client *client, LOG_ERR("Failed to append block1 option"); goto out; } + + ret = coap_packet_append_option(&internal_req->request, + COAP_OPTION_REQUEST_TAG, internal_req->request_tag, + COAP_TOKEN_MAX_LEN); + + if (ret < 0) { + LOG_ERR("Failed to append request tag option"); + goto out; + } } ret = coap_packet_append_payload_marker(&internal_req->request); From 1aef034126bdbeb40ea4a10aebde692dc5ed2a50 Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Mon, 9 Oct 2023 16:14:48 +0300 Subject: [PATCH 2258/4498] net: coap: add support for Echo option (RFC 9175) Resend the request with Echo option and the received Echo option value when receiving a 4.01 (Unauthorized) response with the Echo option. Add missing header file kernel.h to coap_client.h. Signed-off-by: Juha Ylinen --- include/zephyr/net/coap.h | 1 + include/zephyr/net/coap_client.h | 3 + subsys/net/lib/coap/coap_client.c | 70 +++++++++ tests/net/lib/coap_client/src/main.c | 220 +++++++++++++++++++++++++++ 4 files changed, 294 insertions(+) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 77a6966794f..325ced2ebbc 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -61,6 +61,7 @@ enum coap_option_num { COAP_OPTION_PROXY_URI = 35, /**< Proxy-Uri */ COAP_OPTION_PROXY_SCHEME = 39, /**< Proxy-Scheme */ COAP_OPTION_SIZE1 = 60, /**< Size1 */ + COAP_OPTION_ECHO = 252, /**< Echo (RFC 9175) */ COAP_OPTION_REQUEST_TAG = 292 /**< Request-Tag (RFC 9175) */ }; diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h index f836f339063..c3de1abee27 100644 --- a/include/zephyr/net/coap_client.h +++ b/include/zephyr/net/coap_client.h @@ -20,6 +20,7 @@ */ #include +#include #define MAX_COAP_MSG_LEN (CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE + \ @@ -101,6 +102,8 @@ struct coap_client { uint8_t send_buf[MAX_COAP_MSG_LEN]; uint8_t recv_buf[MAX_COAP_MSG_LEN]; struct coap_client_internal_request requests[CONFIG_COAP_CLIENT_MAX_REQUESTS]; + struct coap_option echo_option; + bool send_echo; }; /** @endcond */ diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index 95a0f0d0ac4..a947b15ae8e 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -332,6 +332,17 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr goto out; } + if (client->send_echo) { + ret = coap_packet_append_option(&internal_req->request, COAP_OPTION_ECHO, + client->echo_option.value, client->echo_option.len); + if (ret < 0) { + LOG_ERR("Failed to append echo option"); + k_mutex_unlock(&client->send_mutex); + goto out; + } + client->send_echo = false; + } + ret = coap_client_schedule_poll(client, sock, req, internal_req); if (ret < 0) { LOG_ERR("Failed to schedule polling"); @@ -604,6 +615,11 @@ struct coap_client_internal_request *get_request_with_token(struct coap_client * return NULL; } +static bool find_echo_option(const struct coap_packet *response, struct coap_option *option) +{ + return coap_find_options(response, COAP_OPTION_ECHO, option, 1); +} + static int handle_response(struct coap_client *client, const struct coap_packet *response) { int ret = 0; @@ -651,6 +667,60 @@ static int handle_response(struct coap_client *client, const struct coap_packet return 1; } + /* Received echo option */ + if (find_echo_option(response, &client->echo_option)) { + /* Resend request with echo option */ + if (response_code == COAP_RESPONSE_CODE_UNAUTHORIZED) { + k_mutex_lock(&client->send_mutex, K_FOREVER); + + ret = coap_client_init_request(client, &internal_req->coap_request, + internal_req, false); + + if (ret < 0) { + LOG_ERR("Error creating a CoAP request"); + k_mutex_unlock(&client->send_mutex); + goto fail; + } + + ret = coap_packet_append_option(&internal_req->request, COAP_OPTION_ECHO, + client->echo_option.value, + client->echo_option.len); + if (ret < 0) { + LOG_ERR("Failed to append echo option"); + k_mutex_unlock(&client->send_mutex); + goto fail; + } + + if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { + ret = coap_pending_init(&internal_req->pending, + &internal_req->request, &client->address, + internal_req->retry_count); + if (ret < 0) { + LOG_ERR("Error creating pending"); + k_mutex_unlock(&client->send_mutex); + goto fail; + } + + coap_pending_cycle(&internal_req->pending); + } + + ret = send_request(client->fd, internal_req->request.data, + internal_req->request.offset, 0, &client->address, + client->socklen); + k_mutex_unlock(&client->send_mutex); + + if (ret < 0) { + LOG_ERR("Error sending a CoAP request"); + goto fail; + } else { + return 1; + } + } else { + /* Send echo in next request */ + client->send_echo = true; + } + } + /* Send ack for CON */ if (response_type == COAP_TYPE_CON) { /* CON response is always a separate response, respond with empty ACK. */ diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index bb9d9fc38c5..1a6fd2d88bc 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -75,6 +75,89 @@ static ssize_t z_impl_zsock_sendto_custom_fake(int sock, void *buf, size_t len, last_response_code = ((uint8_t *) buf)[1]; LOG_INF("Latest message ID: %d", last_message_id); + + return 1; +} + +static ssize_t z_impl_zsock_sendto_custom_fake_echo(int sock, void *buf, size_t len, + int flags, const struct sockaddr *dest_addr, + socklen_t addrlen) +{ + uint16_t last_message_id = 0; + struct coap_packet response = {0}; + struct coap_option option = {0}; + + last_message_id |= ((uint8_t *) buf)[2] << 8; + last_message_id |= ((uint8_t *) buf)[3]; + + if (messages_needing_response[0] == 0) { + messages_needing_response[0] = last_message_id; + } else { + messages_needing_response[1] = last_message_id; + } + + last_response_code = ((uint8_t *) buf)[1]; + + LOG_INF("Latest message ID: %d", last_message_id); + + int ret = coap_packet_parse(&response, buf, len, NULL, 0); + + if (ret < 0) { + LOG_ERR("Invalid data received"); + } + + ret = coap_find_options(&response, COAP_OPTION_ECHO, &option, 1); + + zassert_equal(ret, 1, "Coap echo option not found, %d", ret); + zassert_mem_equal(option.value, "echo_value", option.len, "Incorrect echo data"); + + z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; + + return 1; +} + +static ssize_t z_impl_zsock_sendto_custom_fake_echo_next_req(int sock, void *buf, size_t len, + int flags, const struct sockaddr *dest_addr, + socklen_t addrlen) +{ + uint16_t last_message_id = 0; + struct coap_packet response = {0}; + struct coap_option option = {0}; + + last_message_id |= ((uint8_t *) buf)[2] << 8; + last_message_id |= ((uint8_t *) buf)[3]; + + if (messages_needing_response[0] == 0) { + messages_needing_response[0] = last_message_id; + } else { + messages_needing_response[1] = last_message_id; + } + + last_response_code = ((uint8_t *) buf)[1]; + + LOG_INF("Latest message ID: %d", last_message_id); + + int ret = coap_packet_parse(&response, buf, len, NULL, 0); + + if (ret < 0) { + LOG_ERR("Invalid data received"); + } + + ret = coap_header_get_code(&response); + zassert_equal(ret, COAP_METHOD_POST, "Incorrect method, %d", ret); + + uint16_t payload_len; + + const uint8_t *payload = coap_packet_get_payload(&response, &payload_len); + + zassert_mem_equal(payload, "echo testing", payload_len, "Incorrect payload"); + + ret = coap_find_options(&response, COAP_OPTION_ECHO, &option, 1); + zassert_equal(ret, 1, "Coap echo option not found, %d", ret); + zassert_mem_equal(option.value, "echo_value", option.len, "Incorrect echo data"); + + z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; + return 1; } @@ -158,6 +241,66 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_unmatching(int sock, void *buf, return sizeof(ack_data); } +static ssize_t z_impl_zsock_recvfrom_custom_fake_echo(int sock, void *buf, size_t max_len, + int flags, struct sockaddr *src_addr, + socklen_t *addrlen) +{ + uint16_t last_message_id = 0; + + LOG_INF("Recvfrom"); + uint8_t ack_data[] = {0x68, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xda, 0xef, 'e', 'c', + 'h', 'o', '_', 'v', 'a', 'l', 'u', 'e'}; + + if (messages_needing_response[0] != 0) { + last_message_id = messages_needing_response[0]; + messages_needing_response[0] = 0; + } else { + last_message_id = messages_needing_response[1]; + messages_needing_response[1] = 0; + } + + ack_data[2] = (uint8_t) (last_message_id >> 8); + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; + z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_echo; + + return sizeof(ack_data); +} + +static ssize_t z_impl_zsock_recvfrom_custom_fake_echo_next_req(int sock, void *buf, size_t max_len, + int flags, struct sockaddr *src_addr, + socklen_t *addrlen) +{ + uint16_t last_message_id = 0; + + LOG_INF("Recvfrom"); + uint8_t ack_data[] = {0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xda, 0xef, 'e', 'c', + 'h', 'o', '_', 'v', 'a', 'l', 'u', 'e'}; + + if (messages_needing_response[0] != 0) { + last_message_id = messages_needing_response[0]; + messages_needing_response[0] = 0; + } else { + last_message_id = messages_needing_response[1]; + messages_needing_response[1] = 0; + } + + ack_data[2] = (uint8_t) (last_message_id >> 8); + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; + z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_echo_next_req; + + return sizeof(ack_data); +} + static void *suite_setup(void) { coap_client_init(&client, NULL); @@ -214,6 +357,83 @@ ZTEST(coap_client, test_get_request) zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } +ZTEST(coap_client, test_echo_option) +{ + int ret = 0; + struct sockaddr address = {0}; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_echo; + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_echo_option_next_req) +{ + int ret = 0; + struct sockaddr address = {0}; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_echo_next_req; + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); + + char *payload = "echo testing"; + + client_request.method = COAP_METHOD_POST; + client_request.payload = payload; + client_request.len = strlen(payload); + + LOG_INF("Send next request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + ZTEST(coap_client, test_get_no_path) { int ret = 0; From db8191a33654cfdde1c6d4cd578ca0ab37ac4b8d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 13 Oct 2023 11:00:50 +0000 Subject: [PATCH 2259/4498] MAINTAINERS: few optimizations Some minor optimzations. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 2073c0ff2f5..f48ef698be6 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2485,6 +2485,8 @@ NXP Platforms: - drivers/*/*imx* - drivers/*/*lpc*.c - drivers/*/*mcux*.c + - drivers/*/*.mcux + - drivers/*/*.nxp - drivers/*/*nxp* - dts/arm/nxp/ - dts/bindings/*/nxp* @@ -2607,6 +2609,7 @@ STM32 Platforms: - drivers/*/*stm32*.c - drivers/*/*stm32*.h - drivers/*/*/*stm32* + - drivers/*/*stm32 - dts/arm/st/ - dts/bindings/*/*stm32* - soc/arm/st_stm32/ @@ -3644,6 +3647,7 @@ Continuous Integration: - scripts/ci/ - .checkpatch.conf - scripts/gitlint/ + - scripts/set_assignees.py labels: - "area: Continuous Integration" From d9a300e4ae29df48dc67ff648203066e3c5ab1d7 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 12 Oct 2023 10:24:06 +0000 Subject: [PATCH 2260/4498] ci: various set_assignee fixes Cleanup of script and change how we assign PR in general: Make sure that when multiple areas are changed, including platform or driver changes, we set assignee of the general areas and not the platform maintainers. For example, if I change 100 SoC files and touch the kernel file, the assignee is set to the kernel maintainer. First, we should as much possible try and split such changes and not have common area changes with platform changes at the same time. Second, it is important that such changes which affect everyone are reviewed and approved by the maintainer of the general areas rather than leave them to the platform maintainer. Signed-off-by: Anas Nashif --- scripts/set_assignees.py | 138 ++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 67 deletions(-) diff --git a/scripts/set_assignees.py b/scripts/set_assignees.py index fb1987cd9b9..aadfde1f076 100755 --- a/scripts/set_assignees.py +++ b/scripts/set_assignees.py @@ -64,88 +64,92 @@ def process_pr(gh, maintainer_file, number): labels = set() area_counter = defaultdict(int) - maint = defaultdict(int) + found_maintainers = defaultdict(int) num_files = 0 all_areas = set() fn = list(pr.get_files()) + + # one liner PRs should be trivial + if pr.commits == 1 and (pr.additions <= 1 and pr.deletions <= 1): + labels = {'trivial'} + if len(fn) > 500: log(f"Too many files changed ({len(fn)}), skipping....") return - for f in pr.get_files(): + + for changed_file in fn: num_files += 1 - log(f"file: {f.filename}") - areas = maintainer_file.path2areas(f.filename) - - if areas: - all_areas.update(areas) - for a in areas: - area_counter[a.name] += 1 - labels.update(a.labels) - for p in a.maintainers: - maint[p] += 1 - - ac = dict(sorted(area_counter.items(), key=lambda item: item[1], reverse=True)) - log(f"Area matches: {ac}") + log(f"file: {changed_file.filename}") + areas = maintainer_file.path2areas(changed_file.filename) + + if not areas: + continue + + all_areas.update(areas) + is_instance = False + sorted_areas = sorted(areas, key=lambda x: 'Platform' in x.name, reverse=True) + for area in sorted_areas: + c = 1 if not is_instance else 0 + + area_counter[area] += c + labels.update(area.labels) + # FIXME: Here we count the same file multiple times if it exists in + # multiple areas with same maintainer + for area_maintainer in area.maintainers: + found_maintainers[area_maintainer] += c + + if 'Platform' in area.name: + is_instance = True + + area_counter = dict(sorted(area_counter.items(), key=lambda item: item[1], reverse=True)) + log(f"Area matches: {area_counter}") log(f"labels: {labels}") # Create a list of collaborators ordered by the area match collab = list() - for a in ac: - collab += maintainer_file.areas[a].maintainers - collab += maintainer_file.areas[a].collaborators + for area in area_counter: + collab += maintainer_file.areas[area.name].maintainers + collab += maintainer_file.areas[area.name].collaborators collab = list(dict.fromkeys(collab)) log(f"collab: {collab}") - sm = dict(sorted(maint.items(), key=lambda item: item[1], reverse=True)) + _all_maintainers = dict(sorted(found_maintainers.items(), key=lambda item: item[1], reverse=True)) log(f"Submitted by: {pr.user.login}") - log(f"candidate maintainers: {sm}") - - maintainer = "None" - maintainers = list(sm.keys()) - - prop = 0 - if maintainers: - maintainer = maintainers[0] - - if len(ac) > 1 and list(ac.values())[0] == list(ac.values())[1]: - for aa in ac: - if 'Documentation' in aa: - log("++ With multiple areas of same weight including docs, take something else other than Documentation as the maintainer") - for a in all_areas: - if (a.name == aa and - a.maintainers and a.maintainers[0] == maintainer and - len(maintainers) > 1): - maintainer = maintainers[1] - elif 'Platform' in aa: - log("++ Platform takes precedence over subsystem...") - log(f"Set maintainer of area {aa}") - for a in all_areas: - if a.name == aa: - if a.maintainers: - maintainer = a.maintainers[0] - break - - - # if the submitter is the same as the maintainer, check if we have - # multiple maintainers - if pr.user.login == maintainer: - log("Submitter is same as Assignee, trying to find another assignee...") - aff = list(ac.keys())[0] - for a in all_areas: - if a.name == aff: - if len(a.maintainers) > 1: - maintainer = a.maintainers[1] - else: - log(f"This area has only one maintainer, keeping assignee as {maintainer}") - - prop = (maint[maintainer] / num_files) * 100 - if prop < 20: - maintainer = "None" - - log(f"Picked maintainer: {maintainer} ({prop:.2f}% ownership)") - log("+++++++++++++++++++++++++") + log(f"candidate maintainers: {_all_maintainers}") + + maintainers = list(_all_maintainers.keys()) + assignee = None + + # we start with areas with most files changed and pick the maintainer from the first one. + # if the first area is an implementation, i.e. driver or platform, we + # continue searching for any other areas + for area, count in area_counter.items(): + if count == 0: + continue + if len(area.maintainers) > 0: + assignee = area.maintainers[0] + + if 'Platform' not in area.name: + break + + # if the submitter is the same as the maintainer, check if we have + # multiple maintainers + if len(maintainers) > 1 and pr.user.login == assignee: + log("Submitter is same as Assignee, trying to find another assignee...") + aff = list(area_counter.keys())[0] + for area in all_areas: + if area.name == aff: + if len(area.maintainers) > 1: + assignee = area.maintainers[1] + else: + log(f"This area has only one maintainer, keeping assignee as {assignee}") + + if assignee: + prop = (found_maintainers[assignee] / num_files) * 100 + log(f"Picked assignee: {assignee} ({prop:.2f}% ownership)") + log("+++++++++++++++++++++++++") # Set labels if labels: @@ -197,9 +201,9 @@ def process_pr(gh, maintainer_file, number): ms = [] # assignees - if maintainer != 'None' and not pr.assignee: + if assignee and not pr.assignee: try: - u = gh.get_user(maintainer) + u = gh.get_user(assignee) ms.append(u) except GithubException: log(f"Error: Unknown user") From 2ab8c1b7793264e74bbaf2c96129b7c074492865 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 13 Oct 2023 13:50:34 +0000 Subject: [PATCH 2261/4498] ci: do not run twister on set_assignees.py changes No need to run twister when changing this script. Signed-off-by: Anas Nashif --- scripts/ci/twister_ignore.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index 59f735495ca..0ee6e93ea32 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -51,3 +51,4 @@ scripts/checkpatch/* scripts/checkpatch.pl scripts/ci/pylintrc scripts/footprint/* +scripts/set_assignees.py From acaaa9e2c5eb073fb9768f892f233e46a284e01b Mon Sep 17 00:00:00 2001 From: Maxin John Date: Fri, 13 Oct 2023 14:12:01 +0300 Subject: [PATCH 2262/4498] boards: riscv: longan_nano: add adc support Add ADC support for longan nano. Tested using samples/drivers/adc. Also added longan_nano.overlay and updated documentation. Signed-off-by: Maxin John --- boards/riscv/longan_nano/doc/index.rst | 3 +++ .../riscv/longan_nano/longan_nano-common.dtsi | 6 +++++ .../longan_nano/longan_nano-pinctrl.dtsi | 7 ++++++ .../drivers/adc/boards/longan_nano.overlay | 23 +++++++++++++++++++ .../adc/boards/longan_nano_lite.overlay | 23 +++++++++++++++++++ samples/drivers/adc/sample.yaml | 2 ++ 6 files changed, 64 insertions(+) create mode 100644 samples/drivers/adc/boards/longan_nano.overlay create mode 100644 samples/drivers/adc/boards/longan_nano_lite.overlay diff --git a/boards/riscv/longan_nano/doc/index.rst b/boards/riscv/longan_nano/doc/index.rst index c31abb6ec8f..b62d91c3130 100644 --- a/boards/riscv/longan_nano/doc/index.rst +++ b/boards/riscv/longan_nano/doc/index.rst @@ -71,6 +71,9 @@ The board configuration supports the following hardware features: * - DAC - :kconfig:option:`CONFIG_DAC` - :dtcompatible:`gd,gd32-dac` + * - ADC + - :kconfig:option:`CONFIG_ADC` + - :dtcompatible:`gd,gd32-adc` Serial Port =========== diff --git a/boards/riscv/longan_nano/longan_nano-common.dtsi b/boards/riscv/longan_nano/longan_nano-common.dtsi index 71f787b2df6..6d272ddd53d 100644 --- a/boards/riscv/longan_nano/longan_nano-common.dtsi +++ b/boards/riscv/longan_nano/longan_nano-common.dtsi @@ -165,6 +165,12 @@ }; }; +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + &fwdgt { status = "okay"; }; diff --git a/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi b/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi index 41dd3538534..93d8abc02bd 100644 --- a/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi +++ b/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi @@ -37,4 +37,11 @@ , ; }; }; + + adc0_default: adc0_default { + group1 { + pinmux = ; + }; + }; + }; diff --git a/samples/drivers/adc/boards/longan_nano.overlay b/samples/drivers/adc/boards/longan_nano.overlay new file mode 100644 index 00000000000..390534e74ff --- /dev/null +++ b/samples/drivers/adc/boards/longan_nano.overlay @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/boards/longan_nano_lite.overlay b/samples/drivers/adc/boards/longan_nano_lite.overlay new file mode 100644 index 00000000000..390534e74ff --- /dev/null +++ b/samples/drivers/adc/boards/longan_nano_lite.overlay @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/sample.yaml b/samples/drivers/adc/sample.yaml index 46b88fa6040..0af996a8bab 100644 --- a/samples/drivers/adc/sample.yaml +++ b/samples/drivers/adc/sample.yaml @@ -26,6 +26,8 @@ tests: - gd32l233r_eval - lpcxpresso55s36 - mr_canhubk3 + - longan_nano + - longan_nano_lite integration_platforms: - nucleo_l073rz - nrf52840dk_nrf52840 From aeb85db62708db2a496f88cf9342ea9e4e90c88d Mon Sep 17 00:00:00 2001 From: Nick Kraus Date: Sun, 15 Oct 2023 14:42:16 -0400 Subject: [PATCH 2263/4498] drivers: uart_emul: Add IRQ Based TX Added an interrupt based transmit routine and interrupt based uart_emul tests. Signed-off-by: Nick Kraus --- drivers/serial/uart_emul.c | 87 +++++++++++++++++++++++-- tests/drivers/uart/uart_emul/prj.conf | 1 + tests/drivers/uart/uart_emul/src/main.c | 62 ++++++++++++++++++ 3 files changed, 146 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 55c726f96b0..7b3c7ca1c39 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -41,6 +41,7 @@ struct uart_emul_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN bool rx_irq_en; + bool tx_irq_en; struct uart_emul_work irq_work; uart_irq_callback_user_data_t irq_cb; void *irq_cb_udata; @@ -114,6 +115,26 @@ static int uart_emul_config_get(const struct device *dev, struct uart_config *cf #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN +static int uart_emul_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + int ret; + struct uart_emul_data *data = dev->data; + const struct uart_emul_config *config = dev->config; + + K_SPINLOCK(&data->tx_lock) { + ret = ring_buf_put(data->tx_rb, tx_data, size); + } + + if (config->loopback) { + uart_emul_put_rx_data(dev, (uint8_t *)tx_data, ret); + } + if (data->tx_data_ready_cb) { + data->tx_data_ready_cb(dev, ring_buf_size_get(data->tx_rb), data->user_data); + } + + return ret; +} + static int uart_emul_fifo_read(const struct device *dev, uint8_t *rx_data, int size) { int ret; @@ -131,6 +152,22 @@ static int uart_emul_fifo_read(const struct device *dev, uint8_t *rx_data, int s return ret; } +static int uart_emul_irq_tx_ready(const struct device *dev) +{ + bool ready = false; + struct uart_emul_data *data = dev->data; + + K_SPINLOCK(&data->tx_lock) { + if (!data->tx_irq_en) { + K_SPINLOCK_BREAK; + } + + ready = ring_buf_space_get(data->tx_rb) > 0; + } + + return ready; +} + static int uart_emul_irq_rx_ready(const struct device *dev) { bool ready = false; @@ -163,6 +200,14 @@ static void uart_emul_irq_handler(struct k_work *work) while (true) { bool have_work = false; + K_SPINLOCK(&data->tx_lock) { + if (!data->tx_irq_en) { + K_SPINLOCK_BREAK; + } + + have_work = have_work || ring_buf_space_get(data->tx_rb) > 0; + } + K_SPINLOCK(&data->rx_lock) { if (!data->rx_irq_en) { K_SPINLOCK_BREAK; @@ -181,14 +226,22 @@ static void uart_emul_irq_handler(struct k_work *work) static int uart_emul_irq_is_pending(const struct device *dev) { - bool rx_pending; + return uart_emul_irq_tx_ready(dev) || uart_emul_irq_rx_ready(dev); +} + +static void uart_emul_irq_tx_enable(const struct device *dev) +{ + bool submit_irq_work; struct uart_emul_data *const data = dev->data; - K_SPINLOCK(&data->rx_lock) { - rx_pending = !ring_buf_is_empty(data->rx_rb); + K_SPINLOCK(&data->tx_lock) { + data->tx_irq_en = true; + submit_irq_work = ring_buf_space_get(data->tx_rb) > 0; } - return rx_pending; + if (submit_irq_work) { + (void)k_work_submit(&data->irq_work.work); + } } static void uart_emul_irq_rx_enable(const struct device *dev) @@ -206,6 +259,15 @@ static void uart_emul_irq_rx_enable(const struct device *dev) } } +static void uart_emul_irq_tx_disable(const struct device *dev) +{ + struct uart_emul_data *const data = dev->data; + + K_SPINLOCK(&data->tx_lock) { + data->tx_irq_en = false; + } +} + static void uart_emul_irq_rx_disable(const struct device *dev) { struct uart_emul_data *const data = dev->data; @@ -215,6 +277,18 @@ static void uart_emul_irq_rx_disable(const struct device *dev) } } +static int uart_emul_irq_tx_complete(const struct device *dev) +{ + bool tx_complete = false; + struct uart_emul_data *const data = dev->data; + + K_SPINLOCK(&data->tx_lock) { + tx_complete = ring_buf_is_empty(data->tx_rb); + } + + return tx_complete; +} + static void uart_emul_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, void *user_data) { @@ -239,10 +313,15 @@ static const struct uart_driver_api uart_emul_api = { #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ .err_check = uart_emul_err_check, #ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_emul_fifo_fill, .fifo_read = uart_emul_fifo_read, + .irq_tx_enable = uart_emul_irq_tx_enable, .irq_rx_enable = uart_emul_irq_rx_enable, + .irq_tx_disable = uart_emul_irq_tx_disable, .irq_rx_disable = uart_emul_irq_rx_disable, + .irq_tx_ready = uart_emul_irq_tx_ready, .irq_rx_ready = uart_emul_irq_rx_ready, + .irq_tx_complete = uart_emul_irq_tx_complete, .irq_callback_set = uart_emul_irq_callback_set, .irq_update = uart_emul_irq_update, .irq_is_pending = uart_emul_irq_is_pending, diff --git a/tests/drivers/uart/uart_emul/prj.conf b/tests/drivers/uart/uart_emul/prj.conf index 79043ef148e..0fe0e70acee 100644 --- a/tests/drivers/uart/uart_emul/prj.conf +++ b/tests/drivers/uart/uart_emul/prj.conf @@ -1,2 +1,3 @@ CONFIG_ZTEST=y CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/tests/drivers/uart/uart_emul/src/main.c b/tests/drivers/uart/uart_emul/src/main.c index 5e698d0b1e9..af04058171f 100644 --- a/tests/drivers/uart/uart_emul/src/main.c +++ b/tests/drivers/uart/uart_emul/src/main.c @@ -35,6 +35,9 @@ static void uart_emul_before(void *f) { struct uart_emul_fixture *fixture = f; + uart_irq_tx_disable(fixture->dev); + uart_irq_rx_disable(fixture->dev); + uart_emul_flush_rx_data(fixture->dev); uart_emul_flush_tx_data(fixture->dev); } @@ -75,4 +78,63 @@ ZTEST_F(uart_emul, test_polling_in) zassert_equal(rc, -1, "RX buffer should be empty"); } +static void uart_emul_isr(const struct device *dev, void *user_data) +{ + /* always of size SAMPLE_DATA_SIZE */ + uint8_t *buf = user_data; + + while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { + if (uart_irq_tx_ready(dev)) { + uart_fifo_fill(dev, buf, SAMPLE_DATA_SIZE); + uart_irq_tx_disable(dev); + } + + if (uart_irq_rx_ready(dev)) { + uart_fifo_read(dev, buf, SAMPLE_DATA_SIZE); + } + } +} + +ZTEST_F(uart_emul, test_irq_tx) +{ + uint8_t tx_content[SAMPLE_DATA_SIZE] = {0}; + size_t tx_len; + + uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, fixture->sample_data); + /* enabling the tx irq will call the callback, if set */ + uart_irq_tx_enable(fixture->dev); + /* allow space for work queue to run */ + k_yield(); + + tx_len = uart_emul_get_tx_data(fixture->dev, tx_content, SAMPLE_DATA_SIZE); + zassert_equal(tx_len, SAMPLE_DATA_SIZE, "TX buffer length does not match"); + zassert_mem_equal(tx_content, fixture->sample_data, SAMPLE_DATA_SIZE); + + /* No more data in TX buffer */ + tx_len = uart_emul_get_tx_data(fixture->dev, tx_content, sizeof(tx_content)); + zassert_equal(tx_len, 0, "TX buffer should be empty"); +} + +ZTEST_F(uart_emul, test_irq_rx) +{ + uint8_t rx_content[SAMPLE_DATA_SIZE] = {0}; + int rc; + + uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, rx_content); + uart_irq_rx_enable(fixture->dev); + + /* putting rx data will call the irq callback, if enabled */ + uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE); + /* allow space for work queue to run */ + k_yield(); + + zassert_mem_equal(rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); + + /* No more data in RX buffer */ + rc = uart_poll_in(fixture->dev, &rx_content[0]); + zassert_equal(rc, -1, "RX buffer should be empty"); + + uart_irq_rx_disable(fixture->dev); +} + ZTEST_SUITE(uart_emul, NULL, uart_emul_setup, uart_emul_before, NULL, NULL); From 0f50df41f1b5bce2cb8155c2bd19e8d8a2dda727 Mon Sep 17 00:00:00 2001 From: Nick Kraus Date: Sun, 15 Oct 2023 15:14:24 -0400 Subject: [PATCH 2264/4498] drivers: uart_emul: Add Emulated Errors Allows test code to set UART errors, for driver code wanting to test proper error handling. Signed-off-by: Nick Kraus --- drivers/serial/uart_emul.c | 18 +++++++++++++++++- include/zephyr/drivers/serial/uart_emul.h | 8 ++++++++ tests/drivers/uart/uart_emul/src/main.c | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 7b3c7ca1c39..f1d90d9efb1 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -29,6 +29,7 @@ struct uart_emul_work { /* Device run time data */ struct uart_emul_data { struct uart_config cfg; + int errors; struct ring_buf *rx_rb; struct k_spinlock rx_lock; @@ -93,7 +94,11 @@ static void uart_emul_poll_out(const struct device *dev, unsigned char out_char) static int uart_emul_err_check(const struct device *dev) { - return 0; + struct uart_emul_data *drv_data = dev->data; + int errors = drv_data->errors; + + drv_data->errors = 0; + return errors; } #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE @@ -350,6 +355,10 @@ uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t s IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (irq_en = drv_data->rx_irq_en;)); } + if (count < size) { + uart_emul_set_errors(dev, UART_ERROR_OVERRUN); + } + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( if (count > 0 && irq_en && !empty) { (void)k_work_submit(&drv_data->irq_work.work); @@ -397,6 +406,13 @@ uint32_t uart_emul_flush_tx_data(const struct device *dev) return count; } +void uart_emul_set_errors(const struct device *dev, int errors) +{ + struct uart_emul_data *drv_data = dev->data; + + drv_data->errors |= errors; +} + #define UART_EMUL_RX_FIFO_SIZE(inst) (DT_INST_PROP(inst, rx_fifo_size)) #define UART_EMUL_TX_FIFO_SIZE(inst) (DT_INST_PROP(inst, tx_fifo_size)) diff --git a/include/zephyr/drivers/serial/uart_emul.h b/include/zephyr/drivers/serial/uart_emul.h index 68a289841df..08e6be05b1a 100644 --- a/include/zephyr/drivers/serial/uart_emul.h +++ b/include/zephyr/drivers/serial/uart_emul.h @@ -83,6 +83,14 @@ uint32_t uart_emul_flush_rx_data(const struct device *dev); */ uint32_t uart_emul_flush_tx_data(const struct device *dev); +/** + * @brief Sets one or more driver errors + * + * @param dev The emulated UART device instance + * @param errors The @ref uart_rx_stop_reason errors to set + */ +void uart_emul_set_errors(const struct device *dev, int errors); + #ifdef __cplusplus } #endif diff --git a/tests/drivers/uart/uart_emul/src/main.c b/tests/drivers/uart/uart_emul/src/main.c index af04058171f..2de2cdfbd08 100644 --- a/tests/drivers/uart/uart_emul/src/main.c +++ b/tests/drivers/uart/uart_emul/src/main.c @@ -40,6 +40,8 @@ static void uart_emul_before(void *f) uart_emul_flush_rx_data(fixture->dev); uart_emul_flush_tx_data(fixture->dev); + + uart_err_check(fixture->dev); } ZTEST_F(uart_emul, test_polling_out) @@ -78,6 +80,27 @@ ZTEST_F(uart_emul, test_polling_in) zassert_equal(rc, -1, "RX buffer should be empty"); } +ZTEST_F(uart_emul, test_errors) +{ + int errors; + + uart_emul_set_errors(fixture->dev, (UART_ERROR_PARITY | UART_ERROR_FRAMING)); + errors = uart_err_check(fixture->dev); + zassert_equal(errors, (UART_ERROR_PARITY | UART_ERROR_FRAMING), "UART errors do not match"); + + /* uart_err_check should also clear existing errors */ + errors = uart_err_check(fixture->dev); + zassert_equal(errors, 0, "Should be no errors"); + + /* overflowing rx buffer should produce an overrun error */ + uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE); + errors = uart_err_check(fixture->dev); + zassert_equal(errors, 0, "Should be no errors"); + uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE); + errors = uart_err_check(fixture->dev); + zassert_equal(errors, UART_ERROR_OVERRUN, "UART errors do not match"); +} + static void uart_emul_isr(const struct device *dev, void *user_data) { /* always of size SAMPLE_DATA_SIZE */ From 8e9b2c745a2de87a7da709623f1e357bc01f4d35 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 16 Oct 2023 13:27:12 +0200 Subject: [PATCH 2265/4498] Bluetooh: BAP: Fix issue with SRC_ID_VALID flag The flag was not properly set when the broadcast sink did not add the source (e.g. if a broadcast assistant added it). This also downgrades two LOG_WRN to LOG_DBG as they may happen without indicating an issue. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/bap_broadcast_sink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 04771ab53ef..86c7076174a 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -151,7 +151,8 @@ static void update_recv_state_big_cleared(const struct bt_bap_broadcast_sink *si recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink); if (recv_state == NULL) { - LOG_WRN("Failed to find receive state for sink %p", sink); + /* This is likely due to the receive state being removed while we are BIG synced */ + LOG_DBG("Could not find receive state for sink %p", sink); return; } @@ -802,8 +803,8 @@ static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink) err = bt_bap_scan_delegator_rem_src(sink->bass_src_id); if (err != 0) { - LOG_WRN("Failed to remove Receive State for sink %p: %d", - sink, err); + /* This is likely due to the receive state been removed */ + LOG_DBG("Could not remove Receive State for sink %p: %d", sink, err); } } @@ -892,6 +893,7 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br } sink->bass_src_id = recv_state->src_id; + atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID); } atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED); From f58bea6b7bddba8b06c9ca9fcc4ebb04b361aaad Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 16 Oct 2023 13:29:12 +0200 Subject: [PATCH 2266/4498] Bluetooth: BAP: Scan Delegator bis_sync_req cb called on rem If a receive state is removed, then the bis_syn_req callback will be called with 0x00000000, to indicate to the application that the sink should be desynced. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/bap.h | 4 +++- subsys/bluetooth/audio/bap_scan_delegator.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 1436f38494e..77c63ba598b 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -406,7 +406,9 @@ struct bt_bap_scan_delegator_cb { * requested for the sync. * @param[in] bis_sync_req Array of bitfields of which BIS indexes * that is requested to sync for each subgroup - * by the Broadcast Assistant. + * by the Broadcast Assistant. A value of 0 + * indicates a request to terminate the BIG + * sync. * * @return 0 in case of accept, or other value to reject. */ diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 19d33997453..f23c438099d 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -830,6 +830,7 @@ static int scan_delegator_rem_src(struct bt_conn *conn, { struct bass_recv_state_internal *internal_state; struct bt_bap_scan_delegator_recv_state *state; + bool bis_sync_was_requested; uint8_t src_id; /* subtract 1 as the opcode has already been pulled */ @@ -862,6 +863,14 @@ static int scan_delegator_rem_src(struct bt_conn *conn, } } + bis_sync_was_requested = false; + for (uint8_t i = 0U; i < state->num_subgroups; i++) { + if (internal_state->requested_bis_sync[i] != 0U) { + bis_sync_was_requested = true; + break; + } + } + LOG_DBG("Index %u: Removed source with ID 0x%02x", internal_state->index, src_id); @@ -873,6 +882,9 @@ static int scan_delegator_rem_src(struct bt_conn *conn, (void)memset(internal_state->requested_bis_sync, 0, sizeof(internal_state->requested_bis_sync)); + if (bis_sync_was_requested) { + bis_sync_request_updated(conn, internal_state); + } receive_state_updated(conn, internal_state); return 0; From 0e67c990cdb7ae4e4c90a474e7dc478c44a7d494 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 16 Oct 2023 13:30:18 +0200 Subject: [PATCH 2267/4498] tests: Bluetooth: BAP: Add broadcast sink with assistant test Add a test for the broadcast sink that uses the BAP Scan Delegator functionality with a Broadcast Assistant device adding the broadcast source. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_sink_test.c | 175 +++++++++++++++++- .../bap_broadcast_audio_assistant.sh | 29 +++ 2 files changed, 195 insertions(+), 9 deletions(-) create mode 100755 tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index 18608ae7256..1c213694434 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -17,12 +17,14 @@ extern enum bst_result_t bst_result; CREATE_FLAG(broadcaster_found); -CREATE_FLAG(base_received); +CREATE_FLAG(flag_base_received); CREATE_FLAG(flag_base_metadata_updated); CREATE_FLAG(pa_synced); CREATE_FLAG(flag_syncable); CREATE_FLAG(pa_sync_lost); CREATE_FLAG(flag_received); +CREATE_FLAG(flag_pa_request); +CREATE_FLAG(flag_bis_sync_requested); static struct bt_bap_broadcast_sink *g_sink; static struct bt_le_scan_recv_info broadcaster_info; @@ -31,6 +33,9 @@ static struct bt_le_per_adv_sync *pa_sync; static uint32_t broadcaster_broadcast_id; static struct bap_test_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)]; +static uint32_t requested_bis_sync; +static struct bt_le_ext_adv *ext_adv; +static const struct bt_bap_scan_delegator_recv_state *req_recv_state; static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY, @@ -53,7 +58,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap { uint32_t base_bis_index_bitfield = 0U; - if (TEST_FLAG(base_received)) { + if (TEST_FLAG(flag_base_received)) { if (base->subgroup_count > 0 && memcmp(metadata, base->subgroups[0].codec_cfg.meta, @@ -82,7 +87,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap bis_index_bitfield = base_bis_index_bitfield & bis_index_mask; - SET_FLAG(base_received); + SET_FLAG(flag_base_received); } static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted) @@ -185,6 +190,61 @@ static struct bt_pacs_cap cap = { .codec_cap = &codec_cap, }; +static int pa_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + bool past_avail, uint16_t pa_interval) +{ + if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED || + recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { + /* Already syncing */ + /* TODO: Terminate existing sync and then sync to new?*/ + return -EALREADY; + } + + req_recv_state = recv_state; + + SET_FLAG(flag_pa_request); + + return 0; +} + +static int pa_sync_term_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state) +{ + if (pa_sync == NULL || recv_state->pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) { + return -EALREADY; + } + + req_recv_state = recv_state; + + UNSET_FLAG(flag_pa_request); + + return 0; +} + +static int bis_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + const uint32_t bis_sync_req[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS]) +{ + printk("BIS sync request received for %p: 0x%08x\n", recv_state, bis_sync_req[0]); + /* We only care about a single subgroup in this test */ + requested_bis_sync = bis_sync_req[0]; + broadcaster_broadcast_id = recv_state->broadcast_id; + if (bis_sync_req[0] != 0) { + SET_FLAG(flag_bis_sync_requested); + } else { + UNSET_FLAG(flag_bis_sync_requested); + } + + return 0; +} + +static struct bt_bap_scan_delegator_cb scan_delegator_cbs = { + .pa_sync_req = pa_sync_req_cb, + .pa_sync_term_req = pa_sync_term_req_cb, + .bis_sync_req = bis_sync_req_cb, +}; + static void started_cb(struct bt_bap_stream *stream) { printk("Stream %p started\n", stream); @@ -274,11 +334,12 @@ static int init(void) return err; } + bt_bap_scan_delegator_register_cb(&scan_delegator_cbs); bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb); bt_le_scan_cb_register(&bap_scan_cb); UNSET_FLAG(broadcaster_found); - UNSET_FLAG(base_received); + UNSET_FLAG(flag_base_received); UNSET_FLAG(pa_synced); for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { @@ -323,6 +384,18 @@ static int pa_sync_create(void) return bt_le_per_adv_sync_create(&create_params, &pa_sync); } +static void test_pa_sync_delete(void) +{ + int err; + + err = bt_le_per_adv_sync_delete(pa_sync); + if (err != 0) { + FAIL("Unable to stop sink: %d", err); + return; + } + + pa_sync = NULL; +} static void test_scan_and_pa_sync(void) { @@ -507,6 +580,7 @@ static void test_broadcast_delete(void) } /* No "sync lost" event is generated when we initialized the disconnect */ + g_sink = NULL; } static void test_broadcast_delete_inval(void) @@ -520,6 +594,39 @@ static void test_broadcast_delete_inval(void) } } +static void test_start_adv(void) +{ + const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL), + BT_UUID_16_ENCODE(BT_UUID_PACS_VAL)), + BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL)), + }; + int err; + + /* Create a non-connectable non-scannable advertising set */ + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN_NAME, NULL, &ext_adv); + if (err != 0) { + FAIL("Failed to create advertising set (err %d)\n", err); + + return; + } + + err = bt_le_ext_adv_set_data(ext_adv, ad, ARRAY_SIZE(ad), NULL, 0); + if (err != 0) { + FAIL("Failed to set advertising data (err %d)\n", err); + + return; + } + + err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + FAIL("Failed to start advertising set (err %d)\n", err); + + return; + } +} + static void test_common(void) { int err; @@ -536,7 +643,7 @@ static void test_common(void) test_broadcast_sink_create(); printk("Broadcast source PA synced, waiting for BASE\n"); - WAIT_FOR_FLAG(base_received); + WAIT_FOR_FLAG(flag_base_received); printk("BASE received\n"); printk("Waiting for BIG syncable\n"); @@ -585,25 +692,75 @@ static void test_sink_disconnect(void) test_broadcast_delete_inval(); test_broadcast_delete(); - g_sink = NULL; PASS("Broadcast sink disconnect passed\n"); } +static void broadcast_sink_with_assistant(void) +{ + int err; + + err = init(); + if (err) { + FAIL("Init failed (err %d)\n", err); + return; + } + + test_start_adv(); + WAIT_FOR_FLAG(flag_connected); + + printk("Waiting for PA sync request\n"); + WAIT_FOR_FLAG(flag_pa_request); + + test_scan_and_pa_sync(); + test_broadcast_sink_create(); + + printk("Broadcast source PA synced, waiting for BASE\n"); + WAIT_FOR_FLAG(flag_base_received); + printk("BASE received\n"); + + printk("Waiting for BIG syncable\n"); + WAIT_FOR_FLAG(flag_syncable); + + printk("Waiting for BIG sync request\n"); + WAIT_FOR_FLAG(flag_bis_sync_requested); + test_broadcast_sync(); + + printk("Waiting for data\n"); + WAIT_FOR_FLAG(flag_received); + + printk("Waiting for BIG sync terminate request\n"); + WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested); + test_broadcast_stop(); + + printk("Waiting for PA sync terminate request\n"); + WAIT_FOR_UNSET_FLAG(flag_pa_request); + test_pa_sync_delete(); + test_broadcast_delete(); + + PASS("Broadcast sink with assistant passed\n"); +} + static const struct bst_test_instance test_broadcast_sink[] = { { .test_id = "broadcast_sink", .test_post_init_f = test_init, .test_tick_f = test_tick, - .test_main_f = test_main + .test_main_f = test_main, }, { .test_id = "broadcast_sink_disconnect", .test_post_init_f = test_init, .test_tick_f = test_tick, - .test_main_f = test_sink_disconnect + .test_main_f = test_sink_disconnect, + }, + { + .test_id = "broadcast_sink_with_assistant", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = broadcast_sink_with_assistant, }, - BSTEST_END_MARKER + BSTEST_END_MARKER, }; struct bst_test_list *test_broadcast_sink_install(struct bst_test_list *tests) diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh new file mode 100755 index 00000000000..4f649af6395 --- /dev/null +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +SIMULATION_ID="bap_broadcast_audio_assistant" +VERBOSITY_LEVEL=2 +EXECUTE_TIMEOUT=20 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n======== Running BAP Broadcast Audio Assistant =========\n\n" + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_sink_with_assistant -rs=24 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=bap_broadcast_assistant_client_sync -rs=46 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=broadcast_source -rs=69 + +# Simulation time should be larger than the WAIT_TIME in common.h +Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 -sim_length=60e6 $@ + +wait_for_background_jobs From 9f76879a0be56b39742240d571f311917132dda1 Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Mon, 16 Oct 2023 14:57:21 +0300 Subject: [PATCH 2268/4498] drivers: rtc: smartbond: Support RTC peripheral. Add support for the RTC peripheral. Signed-off-by: Ioannis Karachalios --- drivers/rtc/CMakeLists.txt | 1 + drivers/rtc/Kconfig | 1 + drivers/rtc/Kconfig.smartbond | 9 + drivers/rtc/rtc_smartbond.c | 641 ++++++++++++++++++++ dts/bindings/rtc/renesas,smartbond-rtc.yaml | 15 + 5 files changed, 667 insertions(+) create mode 100644 drivers/rtc/Kconfig.smartbond create mode 100644 drivers/rtc/rtc_smartbond.c create mode 100644 dts/bindings/rtc/renesas,smartbond-rtc.yaml diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index 94cda7627c4..2475174ac68 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -14,3 +14,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_MOTOROLA_MC146818 rtc_mc146818.c) zephyr_library_sources_ifdef(CONFIG_RTC_STM32 rtc_ll_stm32.c) zephyr_library_sources_ifdef(CONFIG_RTC_SHELL rtc_shell.c) zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c) +zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 97cc21fef0e..e480aae0388 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -48,5 +48,6 @@ source "drivers/rtc/Kconfig.pcf8523" source "drivers/rtc/Kconfig.pcf8563" source "drivers/rtc/Kconfig.mc146818" source "drivers/rtc/Kconfig.stm32" +source "drivers/rtc/Kconfig.smartbond" endif # RTC diff --git a/drivers/rtc/Kconfig.smartbond b/drivers/rtc/Kconfig.smartbond new file mode 100644 index 00000000000..d21d3a962fa --- /dev/null +++ b/drivers/rtc/Kconfig.smartbond @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config RTC_SMARTBOND + bool "Smartbond RTC driver" + depends on DT_HAS_RENESAS_SMARTBOND_RTC_ENABLED + default y + help + Build RTC driver for Smartbond SoCs. diff --git a/drivers/rtc/rtc_smartbond.c b/drivers/rtc/rtc_smartbond.c new file mode 100644 index 00000000000..a16c8ebaeef --- /dev/null +++ b/drivers/rtc/rtc_smartbond.c @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(rtc_smartbond, CONFIG_RTC_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_smartbond_rtc + +#define SMARTBOND_IRQN DT_INST_IRQN(0) +#define SMARTBOND_IRQ_PRIO DT_INST_IRQ(0, priority) + +#define RTC_ALARMS_COUNT DT_PROP(DT_NODELABEL(rtc), alarms_count) + +#define TM_YEAR_REF 1900 +#define RTC_DIV_DENOM_1000 0 +#define RTC_DIV_DENOM_1024 1 + +#define RTC_SMARTBOND_SUPPORTED_ALARM_FIELDS \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY) + +#define RTC_TIME_REG_SET_FIELD(_field, _var, _val) \ + ((_var) = \ + ((_var) & ~(RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _U_Msk)) | \ + (((_val) << RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _U_Pos) & \ + (RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _U_Msk))) + +#define RTC_CALENDAR_REG_SET_FIELD(_field, _var, _val) \ + ((_var) = \ + ((_var) & ~(RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _U_Msk)) | \ + (((_val) << RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _U_Pos) & \ + (RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _U_Msk))) + +#define RTC_CALENDAR_ALARM_REG_SET_FIELD(_field, _var, _val) \ + ((_var) = \ + ((_var) & ~(RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _U_Msk)) | \ + (((_val) << RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _U_Pos) & \ + (RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _U_Msk))) + +#define RTC_TIME_ALARM_REG_SET_FIELD(_field, _var, _val) \ + ((_var) = \ + ((_var) & ~(RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _U_Msk)) | \ + (((_val) << RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _U_Pos) & \ + (RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _U_Msk))) + +#define RTC_TIME_REG_GET_FIELD(_field, _var) \ + (((_var) & (RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _U_Msk)) >> \ + RTC_RTC_TIME_REG_RTC_TIME_ ## _field ## _U_Pos) + +#define RTC_CALENDAR_REG_GET_FIELD(_field, _var) \ + (((_var) & (RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _U_Msk)) >> \ + RTC_RTC_CALENDAR_REG_RTC_CAL_ ## _field ## _U_Pos) + +#define RTC_CALENDAR_ALARM_REG_GET_FIELD(_field, _var) \ + (((_var) & (RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _T_Msk | \ + RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _U_Msk)) >> \ + RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_ ## _field ## _U_Pos) + +#define RTC_TIME_ALARM_REG_GET_FIELD(_field, _var) \ + (((_var) & (RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _T_Msk | \ + RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _U_Msk)) >> \ + RTC_RTC_TIME_ALARM_REG_RTC_TIME_ ## _field ## _U_Pos) + +#define CLK_RTCDIV_REG_SET_FIELD(_field, _var, _val) \ + ((_var) = \ + ((_var) & ~CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ ## _field ## _Msk) | \ + (((_val) << CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ ## _field ## _Pos) & \ + CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ ## _field ## _Msk)) + +struct rtc_smartbond_data { + struct k_mutex lock; + bool is_rtc_configured; +#if defined(CONFIG_RTC_ALARM) + volatile bool is_alarm_pending; + rtc_alarm_callback alarm_cb; + void *alarm_user_data; +#endif +#if defined(CONFIG_RTC_UPDATE) + rtc_update_callback update_cb; + void *update_user_data; +#endif +}; + +#if defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE) +static void smartbond_rtc_isr(const struct device *dev) +{ + struct rtc_smartbond_data *data = dev->data; + /* Exercise which events asserted the RTC IRQ line. Register is cleared upon read. */ + uint32_t rtc_event_flags_reg = RTC->RTC_EVENT_FLAGS_REG; + /* RTC_EVENT_FLASH_REG will be updated regardless of the interrupt mask. */ + uint32_t rtc_interrupt_mask_reg = RTC->RTC_INTERRUPT_MASK_REG; + +#if defined(CONFIG_RTC_ALARM) + if ((rtc_event_flags_reg & RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_ALRM_Msk) && + !(rtc_interrupt_mask_reg & RTC_RTC_INTERRUPT_MASK_REG_RTC_ALRM_INT_MSK_Msk)) { + if (data->alarm_cb) { + data->alarm_cb(dev, 0, data->alarm_user_data); + data->is_alarm_pending = false; + } else { + data->is_alarm_pending = true; + } + } +#endif + +#if defined(CONFIG_RTC_UPDATE) + if ((rtc_event_flags_reg & RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_SEC_Msk) && + !(rtc_interrupt_mask_reg & RTC_RTC_INTERRUPT_MASK_REG_RTC_SEC_INT_MSK_Msk)) { + if (data->update_cb) { + data->update_cb(dev, data->update_user_data); + } + } +#endif +} +#endif + +static inline void rtc_smartbond_set_status(bool status) +{ + if (status) { + CRG_TOP->CLK_RTCDIV_REG |= CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk; + RTC->RTC_CONTROL_REG = 0; + } else { + RTC->RTC_CONTROL_REG = (RTC_RTC_CONTROL_REG_RTC_CAL_DISABLE_Msk | + RTC_RTC_CONTROL_REG_RTC_TIME_DISABLE_Msk); + CRG_TOP->CLK_RTCDIV_REG &= ~CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk; + } +} + +static uint32_t rtc_time_to_bcd(const struct rtc_time *timeptr) +{ + uint32_t rtc_time_reg = 0; + + RTC_TIME_REG_SET_FIELD(S, rtc_time_reg, bin2bcd(timeptr->tm_sec)); /*[0, 59]*/ + RTC_TIME_REG_SET_FIELD(M, rtc_time_reg, bin2bcd(timeptr->tm_min)); /*[0, 59]*/ + RTC_TIME_REG_SET_FIELD(HR, rtc_time_reg, bin2bcd(timeptr->tm_hour)); /*[0, 23]*/ + + return rtc_time_reg; +} + +static uint32_t rtc_calendar_to_bcd(const struct rtc_time *timeptr) +{ + uint32_t rtc_calendar_reg = 0; + + RTC_CALENDAR_REG_SET_FIELD(D, rtc_calendar_reg, bin2bcd(timeptr->tm_mday)); /*[1, 31]*/ + RTC_CALENDAR_REG_SET_FIELD(Y, rtc_calendar_reg, + bin2bcd((timeptr->tm_year + TM_YEAR_REF) % 100)); /*[year - 1900]*/ + RTC_CALENDAR_REG_SET_FIELD(C, rtc_calendar_reg, + bin2bcd((timeptr->tm_year + TM_YEAR_REF) / 100)); + RTC_CALENDAR_REG_SET_FIELD(M, rtc_calendar_reg, bin2bcd(timeptr->tm_mon + 1)); /*[0, 11]*/ + + if (timeptr->tm_wday != -1) { + rtc_calendar_reg |= ((timeptr->tm_wday + 1) & + RTC_RTC_CALENDAR_REG_RTC_DAY_Msk); /*[0, 6]*/ + } + + return rtc_calendar_reg; +} + +static void bcd_to_rtc_time(struct rtc_time *timeptr) +{ + uint32_t rtc_time_reg = RTC->RTC_TIME_REG; + + timeptr->tm_sec = bcd2bin(RTC_TIME_REG_GET_FIELD(S, rtc_time_reg)); + timeptr->tm_min = bcd2bin(RTC_TIME_REG_GET_FIELD(M, rtc_time_reg)); + timeptr->tm_hour = bcd2bin(RTC_TIME_REG_GET_FIELD(HR, rtc_time_reg)); + + timeptr->tm_nsec = 0; /*Unknown*/ +} + +static void bcd_to_rtc_calendar(struct rtc_time *timeptr) +{ + uint32_t rtc_calendar_reg = RTC->RTC_CALENDAR_REG; + + timeptr->tm_mday = bcd2bin(RTC_CALENDAR_REG_GET_FIELD(D, rtc_calendar_reg)); + timeptr->tm_mon = bcd2bin(RTC_CALENDAR_REG_GET_FIELD(M, rtc_calendar_reg)) - 1; + timeptr->tm_year = bcd2bin(RTC_CALENDAR_REG_GET_FIELD(Y, rtc_calendar_reg)) + + (bcd2bin(RTC_CALENDAR_REG_GET_FIELD(C, rtc_calendar_reg)) * 100) - TM_YEAR_REF; + timeptr->tm_wday = (rtc_calendar_reg & RTC_RTC_CALENDAR_REG_RTC_DAY_Msk) - 1; + + timeptr->tm_yday = timeptr->tm_isdst = -1; /*Unknown*/ +} + +static int rtc_smartbond_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + struct rtc_smartbond_data *data = dev->data; + int ret = 0; + uint32_t rtc_time_reg, rtc_calendar_reg, rtc_status_reg; + + if (timeptr == NULL) { + LOG_ERR("No pointer is provided to set time"); + return -EINVAL; + } + + if (timeptr->tm_year + TM_YEAR_REF < TM_YEAR_REF) { + LOG_ERR("RTC time exceeds HW capabilities"); + return -EINVAL; + } + + if ((timeptr->tm_yday != -1) || (timeptr->tm_isdst != -1) || (timeptr->tm_nsec != 0)) { + LOG_WRN("Unsupported RTC sub-values"); + } + + k_mutex_lock(&data->lock, K_FOREVER); + rtc_smartbond_set_status(false); + + /* Store current counter values as it might happen that the requested time is not valid */ + rtc_time_reg = RTC->RTC_TIME_REG; + rtc_calendar_reg = RTC->RTC_CALENDAR_REG; + + RTC->RTC_TIME_REG = rtc_time_to_bcd(timeptr); + RTC->RTC_CALENDAR_REG = rtc_calendar_to_bcd(timeptr); + + /* Check if the new values were valid, otherwise reset back to the previous ones. */ + rtc_status_reg = RTC->RTC_STATUS_REG; + if (!(rtc_status_reg & RTC_RTC_STATUS_REG_RTC_VALID_CAL_Msk) || + !(rtc_status_reg & RTC_RTC_STATUS_REG_RTC_VALID_TIME_Msk)) { + RTC->RTC_TIME_REG = rtc_time_reg; + RTC->RTC_CALENDAR_REG = rtc_calendar_reg; + ret = -EINVAL; + } + + /* Mark the very first valid RTC configuration; used to check if RTC contains valid data. */ + if (!data->is_rtc_configured && (ret == 0)) { + data->is_rtc_configured = true; + } + + /* It might happen that the very first time RTC is not configured correctly; do not care. */ + rtc_smartbond_set_status(true); + k_mutex_unlock(&data->lock); + + return ret; +} + +static int rtc_smartbond_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + struct rtc_smartbond_data *data = dev->data; + + if (timeptr == NULL) { + LOG_ERR("No pointer is provided to store the requested time"); + return -EINVAL; + } + + if (!data->is_rtc_configured) { + LOG_ERR("RTC is not initialized yet"); + return -ENODATA; + } + + k_mutex_lock(&data->lock, K_FOREVER); + /* Stop RTC counters to obtain coherent data. */ + rtc_smartbond_set_status(false); + + bcd_to_rtc_time(timeptr); + bcd_to_rtc_calendar(timeptr); + + rtc_smartbond_set_status(true); + k_mutex_unlock(&data->lock); + + return 0; +} + +#if defined(CONFIG_RTC_ALARM) +BUILD_ASSERT(RTC_ALARMS_COUNT, "At least one alarm event should be supported"); + +/* Define a valid calendar value as a zero sub-field is not valid for the alarm calendar value */ +static uint32_t alarm_calendar_to_bcd(const struct rtc_time *timeptr, uint16_t mask) +{ + uint32_t rtc_calendar_alarm_reg = 0x0108; + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + RTC_CALENDAR_ALARM_REG_SET_FIELD(D, rtc_calendar_alarm_reg, + bin2bcd(timeptr->tm_mday)); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + RTC_CALENDAR_ALARM_REG_SET_FIELD(M, rtc_calendar_alarm_reg, + bin2bcd(timeptr->tm_mon + 1)); + } + + return rtc_calendar_alarm_reg; +} + +/* No need to parse the alarm mask as a zero sub-field is valid for the alarm time counter. */ +static inline uint32_t alarm_time_to_bcd(const struct rtc_time *timeptr) +{ + uint32_t rtc_time_alarm_reg = 0; + + RTC_TIME_ALARM_REG_SET_FIELD(S, rtc_time_alarm_reg, bin2bcd(timeptr->tm_sec)); /*[0, 59]*/ + RTC_TIME_ALARM_REG_SET_FIELD(M, rtc_time_alarm_reg, bin2bcd(timeptr->tm_min)); /*[0, 59]*/ + RTC_TIME_ALARM_REG_SET_FIELD(HR, rtc_time_alarm_reg, bin2bcd(timeptr->tm_hour)); /*[0, 23]*/ + + return rtc_time_alarm_reg; +} + +static void bcd_to_alarm_calendar(struct rtc_time *timeptr) +{ + uint32_t rtc_calendar_alarm_reg = RTC->RTC_CALENDAR_ALARM_REG; + + timeptr->tm_mday = bcd2bin(RTC_CALENDAR_ALARM_REG_GET_FIELD(D, rtc_calendar_alarm_reg)); + timeptr->tm_mon = bcd2bin(RTC_CALENDAR_ALARM_REG_GET_FIELD(M, rtc_calendar_alarm_reg)) - 1; + + timeptr->tm_yday = timeptr->tm_wday = timeptr->tm_isdst = timeptr->tm_year = -1; +} + +static void bcd_to_alarm_time(struct rtc_time *timeptr) +{ + uint32_t rtc_time_alarm_reg = RTC->RTC_TIME_ALARM_REG; + + timeptr->tm_sec = bcd2bin(RTC_TIME_ALARM_REG_GET_FIELD(S, rtc_time_alarm_reg)); + timeptr->tm_min = bcd2bin(RTC_TIME_ALARM_REG_GET_FIELD(M, rtc_time_alarm_reg)); + timeptr->tm_hour = bcd2bin(RTC_TIME_ALARM_REG_GET_FIELD(HR, rtc_time_alarm_reg)); + + timeptr->tm_nsec = 0; +} + +static uint32_t tm_to_rtc_alarm_mask(uint16_t mask) +{ + uint32_t rtc_alarm_enable_reg = 0; + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + rtc_alarm_enable_reg |= RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Msk; + } + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + rtc_alarm_enable_reg |= RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Msk; + } + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + rtc_alarm_enable_reg |= RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Msk; + } + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + rtc_alarm_enable_reg |= RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Msk; + } + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + rtc_alarm_enable_reg |= RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Msk; + } + + return rtc_alarm_enable_reg; +} + +static uint16_t rtc_to_tm_alarm_mask(uint32_t rtc_alarm_enable_reg) +{ + uint16_t mask = 0; + + if (rtc_alarm_enable_reg & RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Msk) { + mask |= RTC_ALARM_TIME_MASK_SECOND; + } + if (rtc_alarm_enable_reg & RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Msk) { + mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + if (rtc_alarm_enable_reg & RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Msk) { + mask |= RTC_ALARM_TIME_MASK_HOUR; + } + if (rtc_alarm_enable_reg & RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Msk) { + mask |= RTC_ALARM_TIME_MASK_MONTH; + } + if (rtc_alarm_enable_reg & RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Msk) { + mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + + return mask; +} + +static int rtc_smartbond_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + int ret = 0; + struct rtc_smartbond_data *data = dev->data; + uint32_t rtc_time_alarm_reg; + uint32_t rtc_calendar_alarm_reg; + uint32_t rtc_alarm_enable_reg; + uint32_t rtc_status_reg; + + if (id >= RTC_ALARMS_COUNT) { + LOG_ERR("Alarm id is out of range"); + return -EINVAL; + } + + if (mask & ~RTC_SMARTBOND_SUPPORTED_ALARM_FIELDS) { + LOG_ERR("Invalid alarm mask"); + return -EINVAL; + } + + if ((timeptr == NULL) && (mask != 0)) { + LOG_ERR("No pointer is provided to set alarm"); + return -EINVAL; + } + + if (!data->is_rtc_configured) { + LOG_WRN("RTC is not initialized yet"); + } + + k_mutex_lock(&data->lock, K_FOREVER); + + rtc_alarm_enable_reg = RTC->RTC_ALARM_ENABLE_REG; + + /* Disable alarm to obtain coherency and/or when the alarm mask is empty */ + RTC->RTC_ALARM_ENABLE_REG = 0; + RTC->RTC_INTERRUPT_DISABLE_REG = RTC_RTC_INTERRUPT_DISABLE_REG_RTC_ALRM_INT_DIS_Msk; + + if (mask) { + /* Store current counter values as it might happen requested alrm is not valid */ + rtc_time_alarm_reg = RTC->RTC_TIME_ALARM_REG; + rtc_calendar_alarm_reg = RTC->RTC_CALENDAR_ALARM_REG; + + RTC->RTC_TIME_ALARM_REG = alarm_time_to_bcd(timeptr); + RTC->RTC_CALENDAR_ALARM_REG = alarm_calendar_to_bcd(timeptr, mask); + + rtc_status_reg = RTC->RTC_STATUS_REG; + if (!(rtc_status_reg & RTC_RTC_STATUS_REG_RTC_VALID_CAL_ALM_Msk) || + !(rtc_status_reg & RTC_RTC_STATUS_REG_RTC_VALID_TIME_ALM_Msk)) { + RTC->RTC_TIME_ALARM_REG = rtc_time_alarm_reg; + RTC->RTC_CALENDAR_ALARM_REG = rtc_calendar_alarm_reg; + RTC->RTC_ALARM_ENABLE_REG = rtc_alarm_enable_reg; + ret = -EINVAL; + } else { + RTC->RTC_ALARM_ENABLE_REG = tm_to_rtc_alarm_mask(mask); + } + + RTC->RTC_INTERRUPT_ENABLE_REG = RTC_RTC_INTERRUPT_ENABLE_REG_RTC_ALRM_INT_EN_Msk; + } + + k_mutex_unlock(&data->lock); + + return ret; +} + +static int rtc_smartbond_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + struct rtc_smartbond_data *data = dev->data; + + if (id >= RTC_ALARMS_COUNT) { + LOG_ERR("Alarm id is out of range"); + return -EINVAL; + } + + if ((timeptr == NULL) || (mask == NULL)) { + LOG_ERR("No pointer is provided to store the requested alarm time/mask"); + return -EINVAL; + } + + if (!data->is_rtc_configured) { + LOG_WRN("RTC is not initialized yet"); + } + + k_mutex_lock(&data->lock, K_FOREVER); + + bcd_to_alarm_calendar(timeptr); + bcd_to_alarm_time(timeptr); + *mask = rtc_to_tm_alarm_mask(RTC->RTC_ALARM_ENABLE_REG); + + k_mutex_unlock(&data->lock); + + return 0; +} + +static int rtc_smartbond_alarm_is_pending(const struct device *dev, uint16_t id) +{ + unsigned int key; + int status; + struct rtc_smartbond_data *data = dev->data; + + if (id >= RTC_ALARMS_COUNT) { + LOG_ERR("Alarm id is out of range"); + return -EINVAL; + } + + /* Globally disable interrupts as the status flag can be updated within ISR */ + key = DA1469X_IRQ_DISABLE(); + status = data->is_alarm_pending; + /* After reading, the alarm status should be cleared. */ + data->is_alarm_pending = 0; + DA1469X_IRQ_ENABLE(key); + + return status; +} + +static int rtc_smartbond_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + struct rtc_smartbond_data *data = dev->data; + + if (id >= RTC_ALARMS_COUNT) { + LOG_ERR("Alarm id is out of range"); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + data->alarm_cb = callback; + data->alarm_user_data = user_data; + + k_mutex_unlock(&data->lock); + + return 0; +} + +static int rtc_smartbond_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + if (id >= RTC_ALARMS_COUNT) { + LOG_ERR("Alarm id is out of range"); + return -EINVAL; + } + + if (mask == NULL) { + LOG_ERR("Pointer to store the mask value is missed"); + return -EINVAL; + } + + *mask = (uint16_t)RTC_SMARTBOND_SUPPORTED_ALARM_FIELDS; + + return 0; +} +#endif + +#if defined(CONFIG_RTC_UPDATE) +static int rtc_smartbond_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data) +{ + struct rtc_smartbond_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + data->update_cb = callback; + data->update_user_data = user_data; + + if (data->update_cb) { + /* Enable asserting the RTC interrupt line when the second counter rolls over. */ + RTC->RTC_INTERRUPT_ENABLE_REG = RTC_RTC_INTERRUPT_ENABLE_REG_RTC_SEC_INT_EN_Msk; + } else { + RTC->RTC_INTERRUPT_DISABLE_REG = RTC_RTC_INTERRUPT_DISABLE_REG_RTC_SEC_INT_DIS_Msk; + } + + k_mutex_unlock(&data->lock); + + return 0; +} +#endif + +struct rtc_driver_api rtc_smartbond_driver_api = { + .get_time = rtc_smartbond_get_time, + .set_time = rtc_smartbond_set_time, +#if defined(CONFIG_RTC_ALARM) + .alarm_get_time = rtc_smartbond_alarm_get_time, + .alarm_set_time = rtc_smartbond_alarm_set_time, + .alarm_is_pending = rtc_smartbond_alarm_is_pending, + .alarm_set_callback = rtc_smartbond_alarm_set_callback, + .alarm_get_supported_fields = rtc_smartbond_alarm_get_supported_fields, +#endif +#if defined(CONFIG_RTC_UPDATE) + .update_set_callback = rtc_smartbond_update_set_callback, +#endif +}; + +static void rtc_smartbond_100HZ_clock_cfg(void) +{ + const struct device * const dev = DEVICE_DT_GET(DT_NODELABEL(osc)); + uint32_t lp_clk_rate; + uint32_t clk_rtcdiv_reg; + + if (!device_is_ready(dev)) { + __ASSERT_MSG_INFO("Clock device is not ready"); + } + + if (clock_control_get_rate(dev, (clock_control_subsys_t)SMARTBOND_CLK_LP_CLK, + &lp_clk_rate) < 0) { + __ASSERT_MSG_INFO("Cannot extract LP clock rate"); + } + + clk_rtcdiv_reg = CRG_TOP->CLK_RTCDIV_REG; + CLK_RTCDIV_REG_SET_FIELD(DENOM, clk_rtcdiv_reg, RTC_DIV_DENOM_1000); + CLK_RTCDIV_REG_SET_FIELD(INT, clk_rtcdiv_reg, lp_clk_rate / 100); + CLK_RTCDIV_REG_SET_FIELD(FRAC, clk_rtcdiv_reg, (lp_clk_rate % 100) * 10); + CRG_TOP->CLK_RTCDIV_REG = clk_rtcdiv_reg; +} + +static int rtc_smartbond_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* Wakeup device from RTC events (alarm/roll over) */ +#if CONFIG_PM + bool is_xtal32m_enabled = DT_NODE_HAS_STATUS(DT_NODELABEL(xtal32m), okay); + int pdc_idx = da1469x_pdc_add(MCU_PDC_TRIGGER_RTC_ALARM, MCU_PDC_MASTER_M33, + is_xtal32m_enabled ? MCU_PDC_EN_XTAL : 0); + + __ASSERT(pdc_idx >= 0, "Failed to add RTC PDC entry"); + da1469x_pdc_set(pdc_idx); + da1469x_pdc_ack(pdc_idx); +#endif + + rtc_smartbond_100HZ_clock_cfg(); + + /* Timer and calendar counters will not reset after SW reset */ + RTC->RTC_KEEP_RTC_REG |= RTC_RTC_KEEP_RTC_REG_RTC_KEEP_Msk; + +#if defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE) + IRQ_CONNECT(SMARTBOND_IRQN, SMARTBOND_IRQ_PRIO, smartbond_rtc_isr, + DEVICE_DT_INST_GET(0), 0); + irq_enable(SMARTBOND_IRQN); +#endif + + return 0; +} + +#define SMARTBOND_RTC_INIT(inst) \ + BUILD_ASSERT((inst) == 0, "multiple instances are not supported"); \ + \ + static struct rtc_smartbond_data rtc_smartbond_data_ ## inst; \ + \ + DEVICE_DT_INST_DEFINE(0, rtc_smartbond_init, NULL, \ + &rtc_smartbond_data_ ## inst, NULL, \ + POST_KERNEL, \ + CONFIG_RTC_INIT_PRIORITY, \ + &rtc_smartbond_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SMARTBOND_RTC_INIT) diff --git a/dts/bindings/rtc/renesas,smartbond-rtc.yaml b/dts/bindings/rtc/renesas,smartbond-rtc.yaml new file mode 100644 index 00000000000..afe21aef79b --- /dev/null +++ b/dts/bindings/rtc/renesas,smartbond-rtc.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas SmartBond(tm) RTC node + +compatible: "renesas,smartbond-rtc" + +include: rtc-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true From 833d2051ae3afc1f1d91bd77fb827257c67985ff Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Mon, 16 Oct 2023 14:34:22 +0300 Subject: [PATCH 2269/4498] dts: renesas: smartbond: Support the RTC peripheral. Update DTS and board configurations to support the RTC peripheral. Signed-off-by: Ioannis Karachalios --- boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml | 1 + dts/arm/renesas/smartbond/da1469x.dtsi | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml index 10687f70eae..d1d78c56055 100644 --- a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml +++ b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml @@ -15,4 +15,5 @@ supported: - i2c - spi - usb_device + - rtc vendor: renesas diff --git a/dts/arm/renesas/smartbond/da1469x.dtsi b/dts/arm/renesas/smartbond/da1469x.dtsi index 2df3f5bdd43..9d9a106bfb7 100644 --- a/dts/arm/renesas/smartbond/da1469x.dtsi +++ b/dts/arm/renesas/smartbond/da1469x.dtsi @@ -149,6 +149,14 @@ }; }; + rtc: rtc@50000400 { + compatible = "renesas,smartbond-rtc"; + reg = <0x50000400 0x98>; + interrupts = <18 0>; + alarms-count = <1>; + status = "disabled"; + }; + wdog: watchdog@50000700 { compatible = "renesas,smartbond-watchdog"; reg = <0x50000700 0x8>; From 05fb54b090c2a38573f1059077343de4dcfaf06e Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 16 Oct 2023 15:07:35 -0700 Subject: [PATCH 2270/4498] doc: security: Update info about tools Since there are multiple static analysis tools being used now, it is better to change references for a particular one and just point to static analysis section in the documentation. JIRA is no longer used for tracking security issues. Update it to Github. Signed-off-by: Flavio Ceolin --- doc/contribute/guidelines.rst | 1 + doc/security/secure-coding.rst | 2 +- doc/security/security-overview.rst | 18 ++++++++---------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 7f11d078419..5460d0954ed 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -507,6 +507,7 @@ issues, you can add option --no-verify to the git push command. A more complete alternative to this is using check_compliance.py script from ci-tools repo. +.. _static_analysis: Static Code Analysis ******************** diff --git a/doc/security/secure-coding.rst b/doc/security/secure-coding.rst index a22859d78da..fe712eea82c 100644 --- a/doc/security/secure-coding.rst +++ b/doc/security/secure-coding.rst @@ -207,7 +207,7 @@ scripting, missing authentication, and missing authorization. See the `CWE/SANS top 25`_ or `OWASP Top 10`_ for commonly used lists. .. Turn this into something specific. Can we find examples of - mistakes. Perhaps an example of things Coverity has sent us. + mistakes. Perhaps an example of things static analysis tool has sent us. .. _CWE/SANS top 25: http://cwe.mitre.org/top25/ diff --git a/doc/security/security-overview.rst b/doc/security/security-overview.rst index e02f42b5916..6ed15fa55ba 100644 --- a/doc/security/security-overview.rst +++ b/doc/security/security-overview.rst @@ -105,8 +105,8 @@ The three major security measures currently implemented are: requires all code to be reviewed before being committed to the common repository. Furthermore, the reuse of proven building blocks such as network stacks increases the overall quality level - and guarantees stable APIs. Static code analyses are provided by - Coverity Scan. + and guarantees stable APIs. Static code analyses provide additional + quality checks. - **Execution Protection** including thread separation, stack and memory protection is currently available in the upstream @@ -180,17 +180,15 @@ the experience of the reviewer. Especially for security relevant code, concrete and detailed guidelines need to be developed and aligned with the developers (see: :ref:`secure code`). -Static code analyses are run on the Zephyr code tree on a regular basis -using the open source Coverity Scan tool. Coverity Scan now includes -complexity analysis. +Static code analyses are run on the Zephyr code tree on a regular basis, +see :ref:`static_analysis`. -Bug and issue tracking and management is performed using Jira. The term +Bug and issue tracking and management is performed using Github. The term "survivability" was coined to cover pro-active security tasks such as -security issue categorization and management. Initial effort has been -started on the definition of vulnerability categorization and mitigation -processes within Jira. +security issue categorization and management. A problem identified as +vulnerability is managed within Github security advisories. -Issues determined by Coverity should have more stringent reviews before +Issues determined by static analyses should have more stringent reviews before they are closed as non-issues (at least another person educated in security processes need to agree on non-issue before closing). From e5e599c100a8735942fca434361174c4f996877b Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Tue, 17 Oct 2023 13:15:12 +0800 Subject: [PATCH 2271/4498] soc: npcx: add HAS_PM to npcx4 The Kconfig option HAS_PM, which must be needed for SoCs providing PM hooks, is missing in npcx4. This commit adds it to soc/arm/nuvoton_npcx/npcx4/Kconfig.series. Signed-off-by: Jun Lin --- soc/arm/nuvoton_npcx/npcx4/Kconfig.series | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/arm/nuvoton_npcx/npcx4/Kconfig.series b/soc/arm/nuvoton_npcx/npcx4/Kconfig.series index 2eb4ac5d184..1585ace4e98 100644 --- a/soc/arm/nuvoton_npcx/npcx4/Kconfig.series +++ b/soc/arm/nuvoton_npcx/npcx4/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_NPCX4 select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_NPCX + select HAS_PM help Enable support for Nuvoton NPCX4 series From 36d6a7257b3af95c90b4fb7fc9a6cd9f45385ac9 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 16 Oct 2023 16:13:18 +0300 Subject: [PATCH 2272/4498] net: lwm2m: Count null-terminator in string size As the lwm2m_registry.c and specificly lwm2m_set() functions already ensure null-terminator on string and count that into string lenght, the content type handlers should do the same. When string is written, strlen()+1 is the data length. When string is read, use the data length, so we don't leak uninitialized strings. If buffer overrun have removed the null-terminator the strlen() migh be larger than data_len. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 2733f6ed4a8..b649df74088 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -1089,7 +1089,7 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst, struct lwm2m_eng break; } - len = strlen((char *)write_buf); + len = strlen((char *)write_buf) + 1; break; case LWM2M_RES_TYPE_TIME: @@ -1251,8 +1251,10 @@ static int lwm2m_read_resource_data(struct lwm2m_message *msg, void *data_ptr, s break; case LWM2M_RES_TYPE_STRING: - ret = engine_put_string(&msg->out, &msg->path, (uint8_t *)data_ptr, - strlen((uint8_t *)data_ptr)); + if (data_len) { + data_len -= 1; /* Remove the '\0' */ + } + ret = engine_put_string(&msg->out, &msg->path, (uint8_t *)data_ptr, data_len); break; case LWM2M_RES_TYPE_U32: From 015b1103fb0db699bf8f881092e488126cf483b4 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 16 Oct 2023 16:15:07 +0300 Subject: [PATCH 2273/4498] net: lwm2m: Properly initialize buffers for resource instance When resource instances are initialized, we must calculate beginning of the data buffer using the index and maximum data length. Otherwise buffers would overlap with previous. Fixes #64011 Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_object.h | 2 +- tests/net/lib/lwm2m/lwm2m_registry/prj.conf | 1 + .../lwm2m/lwm2m_registry/src/lwm2m_registry.c | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index 170a99c023d..26322f50b1b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -251,7 +251,7 @@ struct lwm2m_engine_obj { if (_ri_ptr != NULL && _ri_count > 0) { \ for (int _i = 0; _i < _ri_count; _i++) { \ _ri_ptr[_ri_idx + _i].data_ptr = \ - (_data_ptr + _i); \ + ((uint8_t *) _data_ptr + (_i * _data_sz)); \ _ri_ptr[_ri_idx + _i].max_data_len = \ _data_sz; \ _ri_ptr[_ri_idx + _i].data_len = \ diff --git a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf index 84e3a4bb289..223f97a0762 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf @@ -13,3 +13,4 @@ CONFIG_LWM2M_IPSO_TEMP_SENSOR_VERSION_1_1=y CONFIG_LWM2M_IPSO_TEMP_SENSOR_INSTANCE_COUNT=4 CONFIG_LWM2M_CONN_MON_OBJ_SUPPORT=y CONFIG_LWM2M_CONNMON_OBJECT_VERSION_1_2=y +CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y diff --git a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c index d847b5a35cd..d4c0a7757a6 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -285,6 +285,42 @@ ZTEST(lwm2m_registry, test_resource_instance_creation_and_deletion) zassert_equal(ret, 0); } +ZTEST(lwm2m_registry, test_resource_instance_strings) +{ + int ret; + char buf[256] = {0}; + static const char string_a[] = "Hello"; + static const char string_b[] = "World"; + struct lwm2m_obj_path path_a = LWM2M_OBJ(16, 0, 0, 0); + struct lwm2m_obj_path path_b = LWM2M_OBJ(16, 0, 0, 1); + + ret = lwm2m_create_object_inst(&LWM2M_OBJ(16, 0)); + zassert_equal(ret, 0); + + ret = lwm2m_create_res_inst(&path_a); + zassert_equal(ret, 0); + + ret = lwm2m_create_res_inst(&path_b); + zassert_equal(ret, 0); + + ret = lwm2m_set_string(&path_a, string_a); + zassert_equal(ret, 0); + + ret = lwm2m_set_string(&path_b, string_b); + zassert_equal(ret, 0); + + ret = lwm2m_get_string(&path_a, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(0, memcmp(buf, string_a, sizeof(string_a))); + + ret = lwm2m_get_string(&path_b, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(0, memcmp(buf, string_b, sizeof(string_b))); + + ret = lwm2m_delete_object_inst(&LWM2M_OBJ(16, 0)); + zassert_equal(ret, 0); +} + ZTEST(lwm2m_registry, test_callbacks) { int ret; From bd0ad5bd662ca812f43ce68af66f100105c068d1 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 17 Oct 2023 13:47:47 +0300 Subject: [PATCH 2274/4498] net: lwm2m: Initialize empty string sizes correctly on objects When objects are initialized, empty strings should be set to length of zero, instead of length of the full buffer. So use INIT_OBJ_RES_DATA_LEN() to give both, the buffer size and data length. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/ipso_current_sensor.c | 8 ++++---- subsys/net/lib/lwm2m/ipso_generic_sensor.c | 12 ++++++------ subsys/net/lib/lwm2m/ipso_humidity_sensor.c | 4 ++-- subsys/net/lib/lwm2m/ipso_light_control.c | 8 ++++---- subsys/net/lib/lwm2m/ipso_pressure_sensor.c | 4 ++-- subsys/net/lib/lwm2m/ipso_temp_sensor.c | 4 ++-- subsys/net/lib/lwm2m/ipso_voltage_sensor.c | 8 ++++---- subsys/net/lib/lwm2m/lwm2m_obj_device.c | 4 ++-- subsys/net/lib/lwm2m/lwm2m_obj_gateway.c | 21 ++++++++++++--------- subsys/net/lib/lwm2m/lwm2m_obj_server.c | 9 ++++----- subsys/net/lib/lwm2m/ucifi_lpwan.c | 4 ++-- 11 files changed, 44 insertions(+), 42 deletions(-) diff --git a/subsys/net/lib/lwm2m/ipso_current_sensor.c b/subsys/net/lib/lwm2m/ipso_current_sensor.c index 99b12ea667b..0684db94220 100644 --- a/subsys/net/lib/lwm2m/ipso_current_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_current_sensor.c @@ -177,8 +177,8 @@ static struct lwm2m_engine_obj_inst *current_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); @@ -194,8 +194,8 @@ static struct lwm2m_engine_obj_inst *current_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES_DATA(CURRENT_CALIBRATION_RID, res[index], i, res_inst[index], j, &calibration_coefficient[index], sizeof(*calibration_coefficient)); - INIT_OBJ_RES_DATA(APPLICATION_TYPE_RID, res[index], i, res_inst[index], - j, app_type[index], APP_TYPE_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(APPLICATION_TYPE_RID, res[index], i, res_inst[index], + j, app_type[index], APP_TYPE_STR_MAX_SIZE, 0); #if defined(CONFIG_LWM2M_IPSO_CURRENT_SENSOR_VERSION_1_1) INIT_OBJ_RES_OPTDATA(TIMESTAMP_RID, res[index], i, res_inst[index], j); diff --git a/subsys/net/lib/lwm2m/ipso_generic_sensor.c b/subsys/net/lib/lwm2m/ipso_generic_sensor.c index 5f1d9801a7f..def650ce9e4 100644 --- a/subsys/net/lib/lwm2m/ipso_generic_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_generic_sensor.c @@ -186,8 +186,8 @@ static struct lwm2m_engine_obj_inst *generic_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); @@ -200,10 +200,10 @@ static struct lwm2m_engine_obj_inst *generic_sensor_create(uint16_t obj_inst_id) j, &max_range_value[index], sizeof(*max_range_value)); INIT_OBJ_RES_EXECUTE(RESET_MIN_MAX_MEASURED_VALUES_RID, res[index], i, reset_min_max_measured_values_cb); - INIT_OBJ_RES_DATA(APPLICATION_TYPE_RID, res[index], i, res_inst[index], - j, app_type[index], APP_TYPE_STR_MAX_SIZE); - INIT_OBJ_RES_DATA(SENSOR_TYPE_RID, res[index], i, res_inst[index], j, - sensor_type[index], SENSOR_TYPE_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(APPLICATION_TYPE_RID, res[index], i, res_inst[index], + j, app_type[index], APP_TYPE_STR_MAX_SIZE, 0); + INIT_OBJ_RES_DATA_LEN(SENSOR_TYPE_RID, res[index], i, res_inst[index], j, + sensor_type[index], SENSOR_TYPE_STR_MAX_SIZE, 0); #if defined(CONFIG_LWM2M_IPSO_GENERIC_SENSOR_VERSION_1_1) INIT_OBJ_RES_OPTDATA(TIMESTAMP_RID, res[index], i, res_inst[index], j); diff --git a/subsys/net/lib/lwm2m/ipso_humidity_sensor.c b/subsys/net/lib/lwm2m/ipso_humidity_sensor.c index fe338d1436a..24be33d37f2 100644 --- a/subsys/net/lib/lwm2m/ipso_humidity_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_humidity_sensor.c @@ -170,8 +170,8 @@ humidity_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); diff --git a/subsys/net/lib/lwm2m/ipso_light_control.c b/subsys/net/lib/lwm2m/ipso_light_control.c index beeb5f0f543..fc9a897461a 100644 --- a/subsys/net/lib/lwm2m/ipso_light_control.c +++ b/subsys/net/lib/lwm2m/ipso_light_control.c @@ -171,10 +171,10 @@ static struct lwm2m_engine_obj_inst *light_control_create(uint16_t obj_inst_id) INIT_OBJ_RES_DATA(POWER_FACTOR_RID, res[avail], i, res_inst[avail], j, &power_factor_value[avail], sizeof(*power_factor_value)); - INIT_OBJ_RES_DATA(COLOUR_RID, res[avail], i, res_inst[avail], j, - colour[avail], LIGHT_STRING_LONG); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[avail], i, res_inst[avail], j, - units[avail], LIGHT_STRING_SHORT); + INIT_OBJ_RES_DATA_LEN(COLOUR_RID, res[avail], i, res_inst[avail], j, + colour[avail], LIGHT_STRING_LONG, 0); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[avail], i, res_inst[avail], j, + units[avail], LIGHT_STRING_SHORT, 0); INIT_OBJ_RES_OPTDATA(APPLICATION_TYPE_RID, res[avail], i, res_inst[avail], j); diff --git a/subsys/net/lib/lwm2m/ipso_pressure_sensor.c b/subsys/net/lib/lwm2m/ipso_pressure_sensor.c index f58c718aed6..87f87e4a277 100644 --- a/subsys/net/lib/lwm2m/ipso_pressure_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_pressure_sensor.c @@ -171,8 +171,8 @@ pressure_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); diff --git a/subsys/net/lib/lwm2m/ipso_temp_sensor.c b/subsys/net/lib/lwm2m/ipso_temp_sensor.c index ff5a3bf767d..bdf59563833 100644 --- a/subsys/net/lib/lwm2m/ipso_temp_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_temp_sensor.c @@ -172,8 +172,8 @@ static struct lwm2m_engine_obj_inst *temp_sensor_create(uint16_t obj_inst_id) res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); diff --git a/subsys/net/lib/lwm2m/ipso_voltage_sensor.c b/subsys/net/lib/lwm2m/ipso_voltage_sensor.c index 1e4eff60b1b..55b45902234 100644 --- a/subsys/net/lib/lwm2m/ipso_voltage_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_voltage_sensor.c @@ -178,8 +178,8 @@ static struct lwm2m_engine_obj_inst *voltage_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1, false, true, &sensor_value[index], sizeof(*sensor_value), NULL, NULL, NULL, sensor_value_write_cb, NULL); - INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, - units[index], UNIT_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(SENSOR_UNITS_RID, res[index], i, res_inst[index], j, + units[index], UNIT_STR_MAX_SIZE, 0); INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i, res_inst[index], j, &min_measured_value[index], sizeof(*min_measured_value)); @@ -195,8 +195,8 @@ static struct lwm2m_engine_obj_inst *voltage_sensor_create(uint16_t obj_inst_id) INIT_OBJ_RES_DATA(CURRENT_CALIBRATION_RID, res[index], i, res_inst[index], j, &calibration_coefficient[index], sizeof(*calibration_coefficient)); - INIT_OBJ_RES_DATA(APPLICATION_TYPE_RID, res[index], i, res_inst[index], - j, app_type[index], APP_TYPE_STR_MAX_SIZE); + INIT_OBJ_RES_DATA_LEN(APPLICATION_TYPE_RID, res[index], i, res_inst[index], + j, app_type[index], APP_TYPE_STR_MAX_SIZE, 0); #if defined(CONFIG_LWM2M_IPSO_VOLTAGE_SENSOR_VERSION_1_1) INIT_OBJ_RES_OPTDATA(TIMESTAMP_RID, res[index], i, res_inst[index], j); diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_device.c b/subsys/net/lib/lwm2m/lwm2m_obj_device.c index 84db2f8c141..c17815795c2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_device.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_device.c @@ -251,8 +251,8 @@ static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id) NULL, current_time_post_write_cb, NULL); INIT_OBJ_RES_OPTDATA(DEVICE_UTC_OFFSET_ID, res, i, res_inst, j); INIT_OBJ_RES_OPTDATA(DEVICE_TIMEZONE_ID, res, i, res_inst, j); - INIT_OBJ_RES_DATA(DEVICE_SUPPORTED_BINDING_MODES_ID, res, i, - res_inst, j, binding_mode, DEVICE_STRING_SHORT); + INIT_OBJ_RES_DATA_LEN(DEVICE_SUPPORTED_BINDING_MODES_ID, res, i, + res_inst, j, binding_mode, DEVICE_STRING_SHORT, strlen(binding_mode) + 1); INIT_OBJ_RES_OPTDATA(DEVICE_TYPE_ID, res, i, res_inst, j); INIT_OBJ_RES_OPTDATA(DEVICE_HARDWARE_VERSION_ID, res, i, res_inst, j); INIT_OBJ_RES_OPTDATA(DEVICE_SOFTWARE_VERSION_ID, res, i, res_inst, j); diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c index 23b92fb19e5..711fd5fe127 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c @@ -127,15 +127,18 @@ static struct lwm2m_engine_obj_inst *lwm2m_gw_create(uint16_t obj_inst_id) init_res_instance(res_inst[index], ARRAY_SIZE(res_inst[index])); /* initialize instance resource data */ - INIT_OBJ_RES_DATA(LWM2M_GATEWAY_DEVICE_RID, res[index], i, res_inst[index], j, - device_table[index].device_id, - CONFIG_LWM2M_GATEWAY_DEVICE_ID_MAX_STR_SIZE); - INIT_OBJ_RES(LWM2M_GATEWAY_PREFIX_RID, res[index], i, res_inst[index], j, 1, false, true, - device_table[index].prefix, CONFIG_LWM2M_GATEWAY_PREFIX_MAX_STR_SIZE, NULL, - NULL, prefix_validation_cb, NULL, NULL); - INIT_OBJ_RES_DATA(LWM2M_GATEWAY_IOT_DEVICE_OBJECTS_RID, res[index], i, res_inst[index], j, - device_table[index].iot_device_objects, - sizeof(device_table[index].iot_device_objects)); + INIT_OBJ_RES_DATA_LEN(LWM2M_GATEWAY_DEVICE_RID, res[index], i, res_inst[index], j, + device_table[index].device_id, + CONFIG_LWM2M_GATEWAY_DEVICE_ID_MAX_STR_SIZE, + strlen(device_table[index].device_id) + 1); + INIT_OBJ_RES_LEN(LWM2M_GATEWAY_PREFIX_RID, res[index], i, res_inst[index], j, 1, false, + true, device_table[index].prefix, CONFIG_LWM2M_GATEWAY_PREFIX_MAX_STR_SIZE, + strlen(device_table[index].prefix) + 1, NULL, NULL, prefix_validation_cb, + NULL, NULL); + INIT_OBJ_RES_DATA_LEN(LWM2M_GATEWAY_IOT_DEVICE_OBJECTS_RID, res[index], i, res_inst[index], + j, device_table[index].iot_device_objects, + sizeof(device_table[index].iot_device_objects), + strlen(device_table[index].iot_device_objects) + 1); inst[index].resources = res[index]; inst[index].resource_count = i; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.c b/subsys/net/lib/lwm2m/lwm2m_obj_server.c index a73206df250..a1b2185ef1d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_server.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.c @@ -301,11 +301,10 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) &server_flag_store_notify[index], sizeof(*server_flag_store_notify)); /* Mark Transport Binding RO as we only support UDP atm */ - INIT_OBJ_RES_DATA(SERVER_TRANSPORT_BINDING_ID, res[index], i, - res_inst[index], j, - transport_binding[index], TRANSPORT_BINDING_LEN); - INIT_OBJ_RES_EXECUTE(SERVER_REG_UPDATE_TRIGGER_ID, res[index], i, - update_trigger_cb); + INIT_OBJ_RES_DATA_LEN(SERVER_TRANSPORT_BINDING_ID, res[index], i, res_inst[index], j, + transport_binding[index], TRANSPORT_BINDING_LEN, + strlen(transport_binding[index]) + 1); + INIT_OBJ_RES_EXECUTE(SERVER_REG_UPDATE_TRIGGER_ID, res[index], i, update_trigger_cb); #if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) INIT_OBJ_RES_EXECUTE(SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID, res[index], i, bootstrap_trigger_cb); diff --git a/subsys/net/lib/lwm2m/ucifi_lpwan.c b/subsys/net/lib/lwm2m/ucifi_lpwan.c index 4210387a201..82878724405 100644 --- a/subsys/net/lib/lwm2m/ucifi_lpwan.c +++ b/subsys/net/lib/lwm2m/ucifi_lpwan.c @@ -132,8 +132,8 @@ static struct lwm2m_engine_obj_inst *lpwan_create(uint16_t obj_inst_id) j, NETWORK_ADDRESS_MAX, false); INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_SECONDARY_ADDRESS_RID, res[index], i, res_inst[index], j, SECONDARY_NETWORK_ADDRESS_MAX, false); - INIT_OBJ_RES_DATA(UCIFI_LPWAN_MAC_ADDRESS_RID, res[index], i, res_inst[index], j, - mac[index], MAC_ADDRESS_SIZE); + INIT_OBJ_RES_DATA_LEN(UCIFI_LPWAN_MAC_ADDRESS_RID, res[index], i, res_inst[index], j, + mac[index], MAC_ADDRESS_SIZE, 0); INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_PEER_ADDRESS_RID, res[index], i, res_inst[index], j, PEER_ADDRESS_MAX, false); INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_MULTICAST_GRP_ADDRESS_RID, res[index], i, From 77ea861f127636bf03312822cc160a4968ae6edf Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 16 Oct 2023 22:38:18 +0300 Subject: [PATCH 2275/4498] net: lwm2m: Fix composite operations As composite operations don't have path in CoAP packet, it wrongly triggered a check for security object and got denied the access. Fixes #64012 Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index b649df74088..b0dde9e14f5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2420,7 +2420,8 @@ static int handle_request(struct coap_packet *request, struct lwm2m_message *msg goto error; } #endif - if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { + if (msg->path.level > LWM2M_PATH_LEVEL_NONE && + msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { r = -EACCES; goto error; } From a95bafec74220c1be7926ee4fab00d8b2bde3b3d Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 16 Oct 2023 22:56:48 +0300 Subject: [PATCH 2276/4498] net: lwm2m: Check access rights on composite operations Composite operations need to check read/write access rights as well. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 10 ++++++++++ subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c | 4 ++-- subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index b0dde9e14f5..a7d4492b981 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -3305,6 +3305,16 @@ int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmwa int do_composite_read_op_for_parsed_list(struct lwm2m_message *msg, uint16_t content_format, sys_slist_t *path_list) { + struct lwm2m_obj_path_list *entry; + + /* Check access rights */ + SYS_SLIST_FOR_EACH_CONTAINER(path_list, entry, node) { + if (entry->path.level > LWM2M_PATH_LEVEL_NONE && + entry->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { + return -EACCES; + } + } + switch (content_format) { #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c index 15dc9a9451e..dd963aa0583 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c @@ -940,10 +940,10 @@ int do_composite_read_op_senml_cbor(struct lwm2m_message *msg) lwm2m_engine_clear_duplicate_path(&lwm_path_list, &lwm_path_free_list); - return do_composite_read_op_for_parsed_path_senml_cbor(msg, &lwm_path_list); + return do_composite_read_op_for_parsed_list(msg, LWM2M_FORMAT_APP_SENML_CBOR, + &lwm_path_list); } - int do_write_op_senml_cbor(struct lwm2m_message *msg) { uint_fast8_t dret; diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c index a504ecceba2..6d2bb2b96b6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c @@ -1653,7 +1653,7 @@ int do_composite_read_op_senml_json(struct lwm2m_message *msg) /* Clear path which are part are part of recursive path /1 will include /1/0/1 */ lwm2m_engine_clear_duplicate_path(&path_list, &free_list); - return do_composite_read_op_for_parsed_list_senml_json(msg, &path_list); + return do_composite_read_op_for_parsed_list(msg, LWM2M_FORMAT_APP_SEML_JSON, &path_list); } int do_send_op_senml_json(struct lwm2m_message *msg, sys_slist_t *lwm2m_path_list) From 112611378f85409565bd8494f7db616739934c17 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 13 Oct 2023 20:40:37 +0200 Subject: [PATCH 2277/4498] soc: intel_adsp: hpsram init refactor This patch reuse existing macro for better readability. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/ace/sram.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/soc/xtensa/intel_adsp/ace/sram.c b/soc/xtensa/intel_adsp/ace/sram.c index d2f7bb6c27a..6a461d9e9ff 100644 --- a/soc/xtensa/intel_adsp/ace/sram.c +++ b/soc/xtensa/intel_adsp/ace/sram.c @@ -20,15 +20,13 @@ __imr void hp_sram_init(uint32_t memory_size) ARG_UNUSED(memory_size); uint32_t hpsram_ebb_quantity = ace_hpsram_get_bank_count(); - volatile uint32_t *l2hsbpmptr = (volatile uint32_t *)ACE_L2MM->l2hsbpmptr; - volatile uint8_t *status = (volatile uint8_t *)l2hsbpmptr + 4; uint32_t idx; for (idx = 0; idx < hpsram_ebb_quantity; ++idx) { - *(l2hsbpmptr + idx * 2) = 0; + HPSRAM_REGS(idx)->HSxPGCTL = 0; } for (idx = 0; idx < hpsram_ebb_quantity; ++idx) { - while (*(status + idx * 8) != 0) { + while (HPSRAM_REGS(idx)->HSxPGISTS != 0) { } } From 16f729214b50173d6a5f08939e21202564dfbfe7 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 13 Oct 2023 21:43:05 +0200 Subject: [PATCH 2278/4498] soc: intel_adsp: lpsram init refactor This patch contains small refactor of lpsram init function (defines registers and adds new macro). Signed-off-by: Tomasz Leman --- .../ace/include/intel_ace15_mtpm/adsp_memory.h | 18 ++++++++++++++++++ .../ace/include/intel_ace20_lnl/adsp_memory.h | 18 ++++++++++++++++++ soc/xtensa/intel_adsp/ace/sram.c | 6 ++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_memory.h b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_memory.h index 7290b1ef6cc..56e78cdca5f 100644 --- a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_memory.h +++ b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_memory.h @@ -147,6 +147,17 @@ struct ace_hpsram_regs { uint8_t HSxPGISTS; uint8_t reserved1[3]; }; + +struct ace_lpsram_regs { + /** @brief power gating control */ + uint8_t USxPGCTL; + /** @brief retention mode control */ + uint8_t USxRMCTL; + uint8_t reserved[2]; + /** @brief power gating status */ + uint8_t USxPGISTS; + uint8_t reserved1[3]; +}; #endif /* These registers are for the L2 HP SRAM bank power management control and status.*/ @@ -156,4 +167,11 @@ struct ace_hpsram_regs { #define HPSRAM_REGS(block_idx) ((volatile struct ace_hpsram_regs *const) \ (L2HSBPM_REG + L2HSBPM_REG_SIZE * (block_idx))) +/* These registers are for the L2 LP SRAM bank power management control and status.*/ +#define L2LSBPM_REG 0x71D80 +#define L2LSBPM_REG_SIZE 0x0008 + +#define LPSRAM_REGS(block_idx) ((volatile struct ace_lpsram_regs *const) \ + (L2LSBPM_REG + L2LSBPM_REG_SIZE * (block_idx))) + #endif /* ZEPHYR_SOC_INTEL_ADSP_MEMORY_H_ */ diff --git a/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_memory.h b/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_memory.h index 165831207f1..a45a8ae590d 100644 --- a/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_memory.h +++ b/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_memory.h @@ -145,6 +145,17 @@ struct ace_hpsram_regs { uint8_t HSxPGISTS; uint8_t reserved1[3]; }; + +struct ace_lpsram_regs { + /** @brief power gating control */ + uint8_t USxPGCTL; + /** @brief retention mode control */ + uint8_t USxRMCTL; + uint8_t reserved[2]; + /** @brief power gating status */ + uint8_t USxPGISTS; + uint8_t reserved1[3]; +}; #endif /* These registers are for the L2 HP SRAM bank power management control and status.*/ @@ -154,4 +165,11 @@ struct ace_hpsram_regs { #define HPSRAM_REGS(block_idx) ((volatile struct ace_hpsram_regs *const) \ (L2HSBPM_REG + L2HSBPM_REG_SIZE * (block_idx))) +/* These registers are for the L2 LP SRAM bank power management control and status.*/ +#define L2LSBPM_REG 0x71D80 +#define L2LSBPM_REG_SIZE 0x0008 + +#define LPSRAM_REGS(block_idx) ((volatile struct ace_lpsram_regs *const) \ + (L2LSBPM_REG + L2LSBPM_REG_SIZE * (block_idx))) + #endif /* ZEPHYR_SOC_INTEL_ADSP_MEMORY_H_ */ diff --git a/soc/xtensa/intel_adsp/ace/sram.c b/soc/xtensa/intel_adsp/ace/sram.c index 6a461d9e9ff..5783ff24d14 100644 --- a/soc/xtensa/intel_adsp/ace/sram.c +++ b/soc/xtensa/intel_adsp/ace/sram.c @@ -36,15 +36,13 @@ __imr void hp_sram_init(uint32_t memory_size) __imr void lp_sram_init(void) { uint32_t lpsram_ebb_quantity = ace_lpsram_get_bank_count(); - volatile uint32_t *l2usbpmptr = (volatile uint32_t *)ACE_L2MM->l2usbpmptr; - volatile uint8_t *status = (volatile uint8_t *)l2usbpmptr + 4; uint32_t idx; for (idx = 0; idx < lpsram_ebb_quantity; ++idx) { - *(l2usbpmptr + idx * 2) = 0; + LPSRAM_REGS(idx)->USxPGCTL = 0; } for (idx = 0; idx < lpsram_ebb_quantity; ++idx) { - while (*(status + idx * 8) != 0) { + while (LPSRAM_REGS(idx)->USxPGISTS != 0) { } } From eeb4f2f76d6de2b1389bba7d996eb3a84e2590d1 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 13 Oct 2023 20:49:09 +0200 Subject: [PATCH 2279/4498] soc: intel_adsp: hpsram enable retention mode This patch enables memory retention mode on hpsram. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/ace/sram.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/xtensa/intel_adsp/ace/sram.c b/soc/xtensa/intel_adsp/ace/sram.c index 5783ff24d14..0a7aac78d10 100644 --- a/soc/xtensa/intel_adsp/ace/sram.c +++ b/soc/xtensa/intel_adsp/ace/sram.c @@ -24,6 +24,7 @@ __imr void hp_sram_init(uint32_t memory_size) for (idx = 0; idx < hpsram_ebb_quantity; ++idx) { HPSRAM_REGS(idx)->HSxPGCTL = 0; + HPSRAM_REGS(idx)->HSxRMCTL = 1; } for (idx = 0; idx < hpsram_ebb_quantity; ++idx) { while (HPSRAM_REGS(idx)->HSxPGISTS != 0) { From adf6d0e3d80eb4daf98fde3b374c9e245dd9e89d Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 17 Oct 2023 10:52:54 +0200 Subject: [PATCH 2280/4498] soc: intel_adsp: lpsram enable retention mode This patch enables memory retention mode on lpsram. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/ace/sram.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/xtensa/intel_adsp/ace/sram.c b/soc/xtensa/intel_adsp/ace/sram.c index 0a7aac78d10..fb3348e0f33 100644 --- a/soc/xtensa/intel_adsp/ace/sram.c +++ b/soc/xtensa/intel_adsp/ace/sram.c @@ -41,6 +41,7 @@ __imr void lp_sram_init(void) for (idx = 0; idx < lpsram_ebb_quantity; ++idx) { LPSRAM_REGS(idx)->USxPGCTL = 0; + LPSRAM_REGS(idx)->USxRMCTL = 1; } for (idx = 0; idx < lpsram_ebb_quantity; ++idx) { while (LPSRAM_REGS(idx)->USxPGISTS != 0) { From 7c7c8f193e6a278b63bad7520af481693120510d Mon Sep 17 00:00:00 2001 From: Tahir Akram Date: Tue, 17 Oct 2023 13:32:26 +0200 Subject: [PATCH 2281/4498] drivers: modem: introducing config for cereg/creg for gsm This contribution addresses the support for various types of modems in gsm driver. As some 4G modems have failed to return correct output from AT+CREG?, so AT+CEREG? is the right AT command in such situation. This commit provides the possibility for user to select one type of AT command. This PR fixes zephyrproject-rtos#63917 Signed-off-by: Tahir Akram --- drivers/modem/Kconfig.gsm | 19 +++++++++++++++++++ drivers/modem/gsm_ppp.c | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/modem/Kconfig.gsm b/drivers/modem/Kconfig.gsm index 4d5666b6f76..101c1e2ece4 100644 --- a/drivers/modem/Kconfig.gsm +++ b/drivers/modem/Kconfig.gsm @@ -37,6 +37,25 @@ config MODEM_GSM_QUECTEL endchoice +choice MODEM_GSM_STATUS_COMMAND + prompt "Select status command Type" + default MODEM_GSM_STATUS_CMD_USE_CREG + help + Use particular type of AT command for cell tower registration status. + +config MODEM_GSM_STATUS_CMD_USE_CREG + bool "CREG command" + +config MODEM_GSM_STATUS_CMD_USE_CEREG + bool "CEREG command" + +endchoice + +config MODEM_GSM_STATUS_COMMAND + string "Status Command" + default "CREG" if MODEM_GSM_STATUS_CMD_USE_CREG + default "CEREG" if MODEM_GSM_STATUS_CMD_USE_CEREG + config MODEM_GSM_RX_STACK_SIZE int "Size of the stack allocated for receiving data from modem" default 512 diff --git a/drivers/modem/gsm_ppp.c b/drivers/modem/gsm_ppp.c index f1e8ff5ef99..34eb0bbb550 100644 --- a/drivers/modem/gsm_ppp.c +++ b/drivers/modem/gsm_ppp.c @@ -525,7 +525,7 @@ static const struct modem_cmd read_cops_cmd = MODEM_CMD_ARGS_MAX("+COPS:", on_cmd_atcmdinfo_cops, 1U, 4U, ","); static const struct modem_cmd check_net_reg_cmd = - MODEM_CMD("+CREG: ", on_cmd_net_reg_sts, 2U, ","); + MODEM_CMD("+" CONFIG_MODEM_GSM_STATUS_COMMAND, on_cmd_net_reg_sts, 2U, ","); static const struct modem_cmd check_attached_cmd = MODEM_CMD("+CGATT:", on_cmd_atcmdinfo_attached, 1U, ","); @@ -751,7 +751,7 @@ static void gsm_finalize_connection(struct k_work *work) ret = modem_cmd_send_nolock(&gsm->context.iface, &gsm->context.cmd_handler, &check_net_reg_cmd, 1, - "AT+CREG?", + "AT+" CONFIG_MODEM_GSM_STATUS_COMMAND "?", &gsm->sem_response, GSM_CMD_SETUP_TIMEOUT); if ((ret < 0) || ((gsm->net_state != GSM_NET_ROAMING) && From a28215d0286089f609deb99bbc9d54f7d2bec8d6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 16 Oct 2023 16:11:32 +0200 Subject: [PATCH 2282/4498] net: tcp: Add helper function to send RST packet w/o active connection Add a helper function which allows to send a RST packet in response to an unexpected TCP packet, w/o associated connection or net context. Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 76 ++++++++++++++++++++++++++++++++++++ subsys/net/ip/tcp_internal.h | 14 +++++++ subsys/net/ip/tcp_private.h | 17 ++++++++ 3 files changed, 107 insertions(+) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index e7592a55353..8c2a5542810 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1162,6 +1162,82 @@ static bool is_destination_local(struct net_pkt *pkt) return false; } +void net_tcp_reply_rst(struct net_pkt *pkt) +{ + NET_PKT_DATA_ACCESS_DEFINE(tcp_access_rst, struct tcphdr); + struct tcphdr *th_pkt = th_get(pkt); + struct tcphdr *th_rst; + struct net_pkt *rst; + int ret; + + if (th_pkt == NULL || (th_flags(th_pkt) & RST)) { + /* Don't reply to a RST segment. */ + return; + } + + rst = tcp_pkt_alloc_no_conn(pkt->iface, pkt->family, + sizeof(struct tcphdr)); + if (rst == NULL) { + return; + } + + /* IP header */ + if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) { + ret = net_ipv4_create(rst, + (struct in_addr *)NET_IPV4_HDR(pkt)->dst, + (struct in_addr *)NET_IPV4_HDR(pkt)->src); + } else if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) { + ret = net_ipv6_create(rst, + (struct in6_addr *)NET_IPV6_HDR(pkt)->dst, + (struct in6_addr *)NET_IPV6_HDR(pkt)->src); + } else { + ret = -EINVAL; + } + + if (ret < 0) { + goto err; + } + + /* TCP header */ + th_rst = (struct tcphdr *)net_pkt_get_data(rst, &tcp_access_rst); + if (th_rst == NULL) { + goto err; + } + + memset(th_rst, 0, sizeof(struct tcphdr)); + + UNALIGNED_PUT(th_pkt->th_dport, &th_rst->th_sport); + UNALIGNED_PUT(th_pkt->th_sport, &th_rst->th_dport); + th_rst->th_off = 5; + + if (th_flags(th_pkt) & ACK) { + UNALIGNED_PUT(RST, &th_rst->th_flags); + UNALIGNED_PUT(th_pkt->th_ack, &th_rst->th_seq); + } else { + uint32_t ack = ntohl(th_pkt->th_seq) + tcp_data_len(pkt); + + UNALIGNED_PUT(RST | ACK, &th_rst->th_flags); + UNALIGNED_PUT(htonl(ack), &th_rst->th_ack); + } + + ret = net_pkt_set_data(rst, &tcp_access_rst); + if (ret < 0) { + goto err; + } + + ret = tcp_finalize_pkt(rst); + if (ret < 0) { + goto err; + } + + tcp_send(rst); + + return; + +err: + tcp_pkt_unref(rst); +} + static int tcp_out_ext(struct tcp *conn, uint8_t flags, struct net_pkt *data, uint32_t seq) { diff --git a/subsys/net/ip/tcp_internal.h b/subsys/net/ip/tcp_internal.h index e282900b16c..42752060092 100644 --- a/subsys/net/ip/tcp_internal.h +++ b/subsys/net/ip/tcp_internal.h @@ -423,6 +423,20 @@ struct k_sem *net_tcp_tx_sem_get(struct net_context *context); */ struct k_sem *net_tcp_conn_sem_get(struct net_context *context); +/** + * @brief Send a TCP RST reply for the received packet w/o associated connection. + * + * @param pkt TCP packet to reply for. + */ +#if defined(CONFIG_NET_NATIVE_TCP) +void net_tcp_reply_rst(struct net_pkt *pkt); +#else +static inline void net_tcp_reply_rst(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); +} +#endif + #ifdef __cplusplus } #endif diff --git a/subsys/net/ip/tcp_private.h b/subsys/net/ip/tcp_private.h index 5d633f8b6a9..a7b8dff3574 100644 --- a/subsys/net/ip/tcp_private.h +++ b/subsys/net/ip/tcp_private.h @@ -98,6 +98,23 @@ _pkt; \ }) +#define tcp_pkt_alloc_no_conn(_iface, _family, _len) \ +({ \ + struct net_pkt *_pkt; \ + \ + if ((_len) > 0) { \ + _pkt = net_pkt_alloc_with_buffer( \ + (_iface), (_len), (_family), \ + IPPROTO_TCP, \ + TCP_PKT_ALLOC_TIMEOUT); \ + } else { \ + _pkt = net_pkt_alloc(TCP_PKT_ALLOC_TIMEOUT); \ + } \ + \ + tp_pkt_alloc(_pkt, tp_basename(__FILE__), __LINE__); \ + \ + _pkt; \ +}) #if defined(CONFIG_NET_TEST_PROTOCOL) #define conn_seq(_conn, _req) \ From 95d9543e2e9cb6ece47120cc20193335769a8de2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 16 Oct 2023 16:14:27 +0200 Subject: [PATCH 2283/4498] net: tcp: Send RST reply for unexpected TCP packets Send RST as a reply for unexpected TCP packets in the following scenarios: 1) Unexpected ACK value received during handshake (connection still open on the peer side), 2) Unexpected data packet on a listening port (accepted connection closed), 3) SYN received on a closed port. This allows the other end to detect that the connection is no longer valid (for example due to reboot) and release the resources. Signed-off-by: Robert Lubos --- subsys/net/ip/connection.c | 5 +++-- subsys/net/ip/tcp.c | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index be1366b32ca..6e6894a7f40 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -828,10 +828,11 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, if (IS_ENABLED(CONFIG_NET_IP) && (pkt_family == AF_INET || pkt_family == AF_INET6) && !(is_mcast_pkt || is_bcast_pkt)) { - conn_send_icmp_error(pkt); - if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) { + net_tcp_reply_rst(pkt); net_stats_update_tcp_seg_connrst(pkt_iface); + } else { + conn_send_icmp_error(pkt); } } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 8c2a5542810..878cdca38a1 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1859,6 +1859,8 @@ static enum net_verdict tcp_recv(struct net_conn *net_conn, in: if (conn) { verdict = tcp_in(conn, pkt); + } else { + net_tcp_reply_rst(pkt); } return verdict; @@ -2585,7 +2587,10 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) * priority. */ connection_ok = true; + } else if (pkt) { + net_tcp_reply_rst(pkt); } + break; case TCP_ESTABLISHED: /* full-close */ From 2b601b34ffe2288d647dcf64df20efd595e53bf6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 17 Oct 2023 14:04:59 +0200 Subject: [PATCH 2284/4498] tests: net: tcp: Add tests to cover improved RST handling Add tests which verify that Zephyr's TCP stack replies with RST packet as expected. Signed-off-by: Robert Lubos --- tests/net/tcp/src/main.c | 247 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 2 deletions(-) diff --git a/tests/net/tcp/src/main.c b/tests/net/tcp/src/main.c index d30aa8b9bd1..aafa3937ce0 100644 --- a/tests/net/tcp/src/main.c +++ b/tests/net/tcp/src/main.c @@ -111,7 +111,8 @@ enum test_state { T_FIN_ACK, T_FIN_1, T_FIN_2, - T_CLOSING + T_CLOSING, + T_RST, }; static enum test_state t_state; @@ -130,6 +131,9 @@ static void handle_client_closing_test(sa_family_t af, struct tcphdr *th); static void handle_data_fin1_test(sa_family_t af, struct tcphdr *th); static void handle_data_during_fin1_test(sa_family_t af, struct tcphdr *th); static void handle_server_recv_out_of_order(struct net_pkt *pkt); +static void handle_server_rst_on_closed_port(sa_family_t af, struct tcphdr *th); +static void handle_server_rst_on_listening_port(sa_family_t af, struct tcphdr *th); +static void handle_syn_invalid_ack(sa_family_t af, struct tcphdr *th); static void verify_flags(struct tcphdr *th, uint8_t flags, const char *fun, int line) @@ -375,6 +379,15 @@ static struct net_pkt *prepare_rst_packet(sa_family_t af, uint16_t src_port, return tester_prepare_tcp_pkt(af, src_port, dst_port, RST, NULL, 0U); } +static bool is_icmp_pkt(struct net_pkt *pkt) +{ + if (net_pkt_family(pkt) == AF_INET) { + return NET_IPV4_HDR(pkt)->proto == IPPROTO_ICMP; + } else { + return NET_IPV6_HDR(pkt)->nexthdr == IPPROTO_ICMPV6; + } +} + static int read_tcp_header(struct net_pkt *pkt, struct tcphdr *th) { int ret; @@ -405,6 +418,11 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt) struct tcphdr th; int ret; + /* Ignore ICMP explicitly */ + if (is_icmp_pkt(pkt)) { + return 0; + } + ret = read_tcp_header(pkt, &th); if (ret < 0) { goto fail; @@ -441,6 +459,16 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt) case 12: handle_syn_rst_ack(net_pkt_family(pkt), &th); break; + case 13: + handle_server_rst_on_closed_port(net_pkt_family(pkt), &th); + break; + case 14: + handle_server_rst_on_listening_port(net_pkt_family(pkt), &th); + break; + case 15: + handle_syn_invalid_ack(net_pkt_family(pkt), &th); + break; + default: zassert_true(false, "Undefined test case"); } @@ -714,7 +742,8 @@ static void handle_server_test(sa_family_t af, struct tcphdr *th) static void test_server_timeout(struct k_work *work) { - if (test_case_no == 3 || test_case_no == 4) { + if (test_case_no == 3 || test_case_no == 4 || test_case_no == 13 || + test_case_no == 14) { handle_server_test(AF_INET, NULL); } else if (test_case_no == 5) { handle_server_test(AF_INET6, NULL); @@ -1884,4 +1913,218 @@ ZTEST(net_tcp, test_server_out_of_order_data) test_server_timeout_out_of_order_data(); } +static void handle_server_rst_on_closed_port(sa_family_t af, struct tcphdr *th) +{ + switch (t_state) { + case T_SYN_ACK: + /* Port was closed so expect RST instead of SYN */ + test_verify_flags(th, RST | ACK); + zassert_equal(ntohl(th->th_seq), 0, "Invalid SEQ value"); + zassert_equal(ntohl(th->th_ack), seq, "Invalid ACK value"); + t_state = T_CLOSING; + test_sem_give(); + break; + default: + return; + } +} + +/* Test case scenario + * Send SYN + * expect RST ACK (closed port) + * any failures cause test case to fail. + */ +ZTEST(net_tcp, test_server_rst_on_closed_port) +{ + t_state = T_SYN; + test_case_no = 13; + seq = ack = 0; + + k_sem_reset(&test_sem); + + /* Trigger the peer to send SYN */ + k_work_reschedule(&test_server, K_NO_WAIT); + + /* Peer will release the semaphore after it receives RST */ + test_sem_take(K_MSEC(100), __LINE__); +} + +static void handle_server_rst_on_listening_port(sa_family_t af, struct tcphdr *th) +{ + switch (t_state) { + case T_DATA_ACK: + /* No active connection so expect RST instead of ACK */ + test_verify_flags(th, RST); + zassert_equal(ntohl(th->th_seq), ack, "Invalid SEQ value"); + t_state = T_CLOSING; + test_sem_give(); + break; + default: + return; + } +} + +static void dummy_accept_cb(struct net_context *ctx, struct sockaddr *addr, + socklen_t addrlen, int status, void *user_data) +{ + /* Should not ever be called. */ + zassert_unreachable("Should not have called dummy accept cb"); +} + +/* Test case scenario + * Open listening port + * Send DATA packet to the listening port + * expect RST (no matching connection) + * any failures cause test case to fail. + */ +ZTEST(net_tcp, test_server_rst_on_listening_port_no_active_connection) +{ + struct net_context *ctx; + int ret; + + t_state = T_DATA; + test_case_no = 14; + seq = ack = 200; + + k_sem_reset(&test_sem); + + ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ctx); + if (ret < 0) { + zassert_true(false, "Failed to get net_context"); + } + + net_context_ref(ctx); + + ret = net_context_bind(ctx, (struct sockaddr *)&my_addr_s, + sizeof(struct sockaddr_in)); + if (ret < 0) { + zassert_true(false, "Failed to bind net_context"); + } + + ret = net_context_listen(ctx, 1); + if (ret < 0) { + zassert_true(false, "Failed to listen on net_context"); + } + + ret = net_context_accept(ctx, dummy_accept_cb, K_NO_WAIT, NULL); + if (ret < 0) { + zassert_true(false, "Failed to set accept on net_context"); + } + + /* Trigger the peer to send data to the listening port w/o active connection */ + k_work_reschedule(&test_server, K_NO_WAIT); + + /* Peer will release the semaphore after it receives RST */ + test_sem_take(K_MSEC(100), __LINE__); + + net_context_put(ctx); +} + +/* Test case scenario + * Expect SYN + * Send ACK (wrong ACK number), + * expect RST, + * expect SYN (retransmission), + * send SYN ACK, + * expect ACK (handshake success), + * expect FIN, + * send FIN ACK, + * expect ACK. + * any failures cause test case to fail. + */ +static void handle_syn_invalid_ack(sa_family_t af, struct tcphdr *th) +{ + static bool invalid_ack = true; + struct net_pkt *reply; + int ret; + + + switch (t_state) { + case T_SYN: + test_verify_flags(th, SYN); + if (invalid_ack) { + ack = ntohl(th->th_seq) + 1000U; + reply = prepare_ack_packet(af, htons(MY_PORT), + th->th_sport); + /* Expect RST now. */ + t_state = T_RST; + invalid_ack = false; + } else { + ack = ntohl(th->th_seq) + 1U; + reply = prepare_syn_ack_packet(af, htons(MY_PORT), + th->th_sport); + /* Proceed with the handshake on second attempt. */ + t_state = T_SYN_ACK; + } + + break; + case T_SYN_ACK: + test_verify_flags(th, ACK); + /* connection is successful */ + t_state = T_FIN; + return; + case T_FIN: + test_verify_flags(th, FIN | ACK); + seq++; + ack++; + t_state = T_FIN_ACK; + reply = prepare_fin_ack_packet(af, htons(MY_PORT), + th->th_sport); + break; + case T_FIN_ACK: + test_verify_flags(th, ACK); + test_sem_give(); + return; + case T_RST: + test_verify_flags(th, RST); + zassert_equal(ntohl(th->th_seq), ack, "Invalid SEQ value"); + + /* Wait for SYN retransmission. */ + t_state = T_SYN; + return; + default: + return; + } + + ret = net_recv_data(net_iface, reply); + if (ret < 0) { + goto fail; + } + + return; +fail: + zassert_true(false, "%s failed", __func__); +} + +ZTEST(net_tcp, test_client_rst_on_unexpected_ack_on_syn) +{ + struct net_context *ctx; + int ret; + + t_state = T_SYN; + test_case_no = 15; + seq = ack = 0; + + ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ctx); + if (ret < 0) { + zassert_true(false, "Failed to get net_context"); + } + + net_context_ref(ctx); + + ret = net_context_connect(ctx, (struct sockaddr *)&peer_addr_s, + sizeof(struct sockaddr_in), + NULL, K_MSEC(1000), NULL); + + zassert_equal(ret, 0, "Connect failed"); + zassert_equal(net_context_get_state(ctx), NET_CONTEXT_CONNECTED, + "Context should be connected"); + + /* Just wait for the connection teardown. */ + net_context_put(ctx); + + /* Peer will release the semaphore after it receives final ACK */ + test_sem_take(K_MSEC(100), __LINE__); +} + ZTEST_SUITE(net_tcp, NULL, presetup, NULL, NULL, NULL); From 4ea3d247d038a5e3d32f52bddf287cd1b8dd2025 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 18 Oct 2023 10:09:41 +0200 Subject: [PATCH 2285/4498] net: tcp: Add Kconfig option to enable TCP RST on unbound ports Add Kconfig option to control TCP RST behavior on connection attempts on unbound ports. If enabled, TCP stack will reply with RST packet (enabled by default). Signed-off-by: Robert Lubos --- subsys/net/ip/Kconfig | 7 +++++++ subsys/net/ip/connection.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index d3e1fb593bf..af69f68f522 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -564,6 +564,13 @@ config NET_TCP_WORKER_PRIO execution to the lower layer network stack, with a high risk of running out of net_bufs. +config NET_TCP_REJECT_CONN_WITH_RST + bool "Reject connection attempts on unbound TCP ports with RST" + default y + help + If enabled, TCP stack will reject connection attempts on unbound ports + with TCP RST packet. + config NET_TEST_PROTOCOL bool "JSON based test protocol (UDP)" help diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 6e6894a7f40..272cf1c5d84 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -828,7 +828,8 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, if (IS_ENABLED(CONFIG_NET_IP) && (pkt_family == AF_INET || pkt_family == AF_INET6) && !(is_mcast_pkt || is_bcast_pkt)) { - if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) { + if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP && + IS_ENABLED(CONFIG_NET_TCP_REJECT_CONN_WITH_RST)) { net_tcp_reply_rst(pkt); net_stats_update_tcp_seg_connrst(pkt_iface); } else { From 822a82d6193b74a51f4844a11a2b3c4c723eba9d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 18 Oct 2023 13:16:10 +0200 Subject: [PATCH 2286/4498] tests: lib: thrift: Fix timing issues with TCP The test delegates putting the server socket into listening (i. e. calling listen() on the socket) to a separate thread, which did have a chance to run before client attempted to establish TCP connection. This was not visible before, as we did not reply with RST to a connection attempt on a closed port, so the connection was eventually establish after SYN retransmission. But as we do reject such a connection now with RST, the connection attempt failed. Therefore, a small delay was added after spawning the server thread, to give it a chance to configure the server socket. Additionally, lower the CONFIG_NET_TCP_TIME_WAIT_DELAY value so that TCP contexts are released earlier, and add a respective delay in the test teardown function. Not doing so also triggered unneeded SYN retransmissions, as there were no enough TCP context to accept the incoming connection, before freeing the resources allocated for the previous one. Signed-off-by: Robert Lubos --- tests/lib/thrift/ThriftTest/prj.conf | 1 + tests/lib/thrift/ThriftTest/src/main.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/tests/lib/thrift/ThriftTest/prj.conf b/tests/lib/thrift/ThriftTest/prj.conf index 1c461c3ac8a..afc07a9d8e0 100755 --- a/tests/lib/thrift/ThriftTest/prj.conf +++ b/tests/lib/thrift/ThriftTest/prj.conf @@ -22,6 +22,7 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_TEST=y CONFIG_NET_DRIVERS=y CONFIG_NET_LOOPBACK=y +CONFIG_NET_TCP_TIME_WAIT_DELAY=100 # Some platforms require relatively large stack sizes. # This can be tuned per-board. diff --git a/tests/lib/thrift/ThriftTest/src/main.cpp b/tests/lib/thrift/ThriftTest/src/main.cpp index b903f3c8a9b..654f74a309b 100644 --- a/tests/lib/thrift/ThriftTest/src/main.cpp +++ b/tests/lib/thrift/ThriftTest/src/main.cpp @@ -141,6 +141,9 @@ static void thrift_test_before(void *data) rv = pthread_create(&context.server_thread, attrp, server_func, nullptr); zassert_equal(0, rv, "pthread_create failed: %d", rv); + /* Give the server thread a chance to start and prepare the socket */ + k_msleep(50); + // set up client context.client = setup_client(); } @@ -160,6 +163,8 @@ static void thrift_test_after(void *data) context.client.reset(); context.server.reset(); + + k_msleep(CONFIG_NET_TCP_TIME_WAIT_DELAY); } ZTEST_SUITE(thrift, NULL, thrift_test_setup, thrift_test_before, thrift_test_after, NULL); From 337ba330a235304835bf296e9a04b74228716428 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 17 Oct 2023 16:08:18 +0200 Subject: [PATCH 2287/4498] Bluetooth: Mesh: Allow to set the extension list size to zero If instantiated models don't have any relations at all, then the extensions list will be empty. We should allow to disable it at all to not waste RAM. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 8667c1e70a0..154bf0b5b50 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1431,7 +1431,7 @@ config BT_MESH_COMP_PAGE_2 config BT_MESH_MODEL_EXTENSION_LIST_SIZE int "Model extensions list size" depends on BT_MESH_COMP_PAGE_1 - range 1 255 + range 0 255 default 10 help This option specifies how many models relations can be saved. From 281ffe5b4fa509efbbfd0be731ec0fa995e0edc9 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 17 Oct 2023 16:35:29 +0200 Subject: [PATCH 2288/4498] tests: Bluetooth: tester: Fix bt_micp_mic_ctlr_mute_get invalid usage The call to bt_micp_mic_ctlr_mute_get function will return the value of mute state in bt_micp_mic_ctlr_cb.mute callback. This fixes invalid function calls by storing the recent mute state value in the application. Fixes: MICP/CL/SPE/BI-01-C Signed-off-by: Mariusz Skamra --- tests/bluetooth/tester/src/btp_micp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_micp.c b/tests/bluetooth/tester/src/btp_micp.c index b9e596f3c2c..4ead39ca179 100644 --- a/tests/bluetooth/tester/src/btp_micp.c +++ b/tests/bluetooth/tester/src/btp_micp.c @@ -32,6 +32,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); static struct bt_micp_mic_ctlr *mic_ctlr; static struct bt_micp_mic_dev_register_param mic_dev_register_param; +static uint8_t mute_state; #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) static struct bt_micp_included micp_included; @@ -85,8 +86,10 @@ static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, ui { struct bt_conn *conn; + mute_state = mute; + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); - btp_send_micp_mute_state_ev(conn, err, mute); + btp_send_micp_mute_state_ev(conn, err, mute_state); LOG_DBG("MICP Mute cb (%d)", err); } @@ -94,7 +97,6 @@ static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, ui static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err) { struct bt_conn *conn; - uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); btp_send_micp_mute_state_ev(conn, err, mute_state); @@ -105,7 +107,6 @@ static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err) { struct bt_conn *conn; - uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); btp_send_micp_mute_state_ev(conn, err, mute_state); From c613e23b4a6aa28b3b96bad33092a6eca0159245 Mon Sep 17 00:00:00 2001 From: Ludvig Jordet Date: Tue, 17 Oct 2023 15:37:44 +0200 Subject: [PATCH 2289/4498] Bluetooth: Mesh: Fix issue where dfu_cli could get stuck This fixes an issue where the DFU client could get stuck trying to transmit a message to servers if the DFU client was misconfigured, for instance missing application key or network key. Signed-off-by: Ludvig Jordet --- subsys/bluetooth/mesh/dfu_cli.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/mesh/dfu_cli.c b/subsys/bluetooth/mesh/dfu_cli.c index 9e800a6231f..3adb63644d0 100644 --- a/subsys/bluetooth/mesh/dfu_cli.c +++ b/subsys/bluetooth/mesh/dfu_cli.c @@ -305,6 +305,23 @@ static void tx_end(int err, void *cb_data) blob_cli_broadcast_tx_complete(&cli->blob); } +static int tx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, + const struct bt_mesh_send_cb *cb, struct bt_mesh_dfu_cli *cli) +{ + int err; + + err = bt_mesh_model_send(mod, ctx, buf, cb, cli); + if (err) { + LOG_ERR("Send err: %d", err); + if (cb) { + cb->end(err, cli); + } + return err; + } + + return 0; +} + static int info_get(struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, uint8_t idx, uint8_t max_count, const struct bt_mesh_send_cb *cb) @@ -314,7 +331,7 @@ static int info_get(struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, net_buf_simple_add_u8(&buf, idx); net_buf_simple_add_u8(&buf, max_count); - return bt_mesh_model_send(cli->mod, ctx, &buf, cb, cli); + return tx(cli->mod, ctx, &buf, cb, cli); } static void send_info_get(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -352,7 +369,7 @@ static void send_update_start(struct bt_mesh_blob_cli *b, uint16_t dst) net_buf_simple_add_mem(&buf, cli->xfer.slot->metadata, cli->xfer.slot->metadata_len); - bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); + (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_get(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -363,7 +380,7 @@ static void send_update_get(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_GET, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_GET); - bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); + (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_cancel(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -374,7 +391,7 @@ static void send_update_cancel(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_CANCEL, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_CANCEL); - bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); + (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_apply(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -385,7 +402,7 @@ static void send_update_apply(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_APPLY, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_APPLY); - bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); + (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); } /******************************************************************************* From 2516aa8b0bd7d2a0d9f7e510f1937ee49abe21a1 Mon Sep 17 00:00:00 2001 From: Dennis Grijalva Date: Mon, 16 Oct 2023 16:31:39 -0700 Subject: [PATCH 2290/4498] drivers: regulator: pca9420: Add support for configuring ASYS UVLO Add support for configuring ASYS UVLO (under voltage lock out) threshold Signed-off-by: Dennis Grijalva --- drivers/regulator/regulator_pca9420.c | 21 ++++++++++++++++++++- dts/bindings/regulator/nxp,pca9420.yaml | 12 ++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/regulator_pca9420.c b/drivers/regulator/regulator_pca9420.c index 71dd55525b8..c7978242871 100644 --- a/drivers/regulator/regulator_pca9420.c +++ b/drivers/regulator/regulator_pca9420.c @@ -18,6 +18,8 @@ /** General purpose registers */ /** @brief Top level system ctrl 0 */ #define PCA9420_TOP_CNTL0 0x09U +/** @brief Top level system ctrl 2 */ +#define PCA9420_TOP_CNTL2 0x0BU /** @brief Top level system ctrl 3 */ #define PCA9420_TOP_CNTL3 0x0CU @@ -36,6 +38,10 @@ #define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_MASK 0xE0U #define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_DISABLED 0x7U +/** @brief ASYS UVLO threshold selection */ +#define PCA9420_TOP_CNTL2_ASYS_UVLO_SEL_POS 6U +#define PCA9420_TOP_CNTL2_ASYS_UVLO_SEL_MASK 0xC0U + /** @brief I2C Mode control mask */ #define PCA9420_TOP_CNTL3_MODE_I2C_POS 3U #define PCA9420_TOP_CNTL3_MODE_I2C_MASK 0x18U @@ -102,6 +108,7 @@ struct regulator_pca9420_common_config { struct i2c_dt_spec i2c; int32_t vin_ilim_ua; bool enable_modesel_pins; + uint8_t asys_uvlo_sel_mv; }; struct regulator_pca9420_common_data { @@ -427,10 +434,20 @@ static int regulator_pca9420_common_init(const struct device *dev) PCA9420_VIN_ILIM_UA_LSB; } - return i2c_reg_update_byte_dt( + ret = i2c_reg_update_byte_dt( &config->i2c, PCA9420_TOP_CNTL0, PCA9420_TOP_CNTL0_VIN_ILIM_SEL_MASK, reg_val << PCA9420_TOP_CNTL0_VIN_ILIM_SEL_POS); + + if (ret != 0) { + return ret; + } + + /* configure ASYS UVLO threshold */ + return i2c_reg_update_byte_dt(&config->i2c, PCA9420_TOP_CNTL2, + PCA9420_TOP_CNTL2_ASYS_UVLO_SEL_MASK, + config->asys_uvlo_sel_mv << + PCA9420_TOP_CNTL2_ASYS_UVLO_SEL_POS); } #define REGULATOR_PCA9420_DEFINE(node_id, id, name, _parent) \ @@ -465,6 +482,8 @@ static int regulator_pca9420_common_init(const struct device *dev) .vin_ilim_ua = DT_INST_PROP(inst, nxp_vin_ilim_microamp), \ .enable_modesel_pins = \ DT_INST_PROP(inst, nxp_enable_modesel_pins), \ + .asys_uvlo_sel_mv = \ + DT_INST_ENUM_IDX(inst, nxp_asys_uvlo_sel_millivolt), \ }; \ \ static struct regulator_pca9420_common_data data_##inst; \ diff --git a/dts/bindings/regulator/nxp,pca9420.yaml b/dts/bindings/regulator/nxp,pca9420.yaml index 1f881137601..2e4584d0a67 100644 --- a/dts/bindings/regulator/nxp,pca9420.yaml +++ b/dts/bindings/regulator/nxp,pca9420.yaml @@ -63,6 +63,18 @@ properties: To disable current limit, set property to zero. Defaults to 425mA, the IC default value. + nxp,asys-uvlo-sel-millivolt: + type: int + default: 2700 + enum: + - 2400 + - 2500 + - 2600 + - 2700 + description: | + ASYS UVLO (under voltage lock out) threshold, in millivolts. Defaults to + 2700mV to match the IC default value. + child-binding: include: - name: regulator.yaml From d1813e547e8981ea6d0011a54143a65a348d42ec Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 17 Oct 2023 13:05:08 -0700 Subject: [PATCH 2291/4498] arm: using -EAGAIN directly instead of _k_neg_eagain _k_neg_eagain is there for used in assembly where including errno.h is not possible. However, the usage in ARM was simply to assign value to swap_return_value in a C file, which is no need to use _k_neg_eagain as errno.h can be included. So change that to use -EAGAIN directly. Saves 4 bytes in built binaries in rodata. Signed-off-by: Daniel Leung --- arch/arm/core/cortex_a_r/swap.c | 4 ++-- arch/arm/core/cortex_m/swap.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/cortex_a_r/swap.c b/arch/arm/core/cortex_a_r/swap.c index 258999be7c7..2f7faba741a 100644 --- a/arch/arm/core/cortex_a_r/swap.c +++ b/arch/arm/core/cortex_a_r/swap.c @@ -7,7 +7,7 @@ #include #include -extern const int _k_neg_eagain; +#include /* The 'key' actually represents the BASEPRI register * prior to disabling interrupts via the BASEPRI mechanism. @@ -18,7 +18,7 @@ int arch_swap(unsigned int key) { /* store off key and return value */ _current->arch.basepri = key; - _current->arch.swap_return_value = _k_neg_eagain; + _current->arch.swap_return_value = -EAGAIN; z_arm_cortex_r_svc(); irq_unlock(key); diff --git a/arch/arm/core/cortex_m/swap.c b/arch/arm/core/cortex_m/swap.c index f41ae2e4e84..9a597ef219d 100644 --- a/arch/arm/core/cortex_m/swap.c +++ b/arch/arm/core/cortex_m/swap.c @@ -7,7 +7,7 @@ #include #include -extern const int _k_neg_eagain; +#include /* The 'key' actually represents the BASEPRI register * prior to disabling interrupts via the BASEPRI mechanism. @@ -34,7 +34,7 @@ int arch_swap(unsigned int key) { /* store off key and return value */ _current->arch.basepri = key; - _current->arch.swap_return_value = _k_neg_eagain; + _current->arch.swap_return_value = -EAGAIN; /* set pending bit to make sure we will take a PendSV exception */ SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; From 7e852d17088640d09b1fcf68a79b814b6e0d3eff Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 18 Oct 2023 09:04:24 +0200 Subject: [PATCH 2292/4498] drivers timer nrf: Correct dependencies for simulation Let's make the nrf rtc kconfig depend on the SOC_COMPATIBLE options which are set both by the real and simulated targets so the configuration matches in both cases. Signed-off-by: Alberto Escolar Piedras --- drivers/timer/Kconfig.nrf_rtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index acb6f123afe..baa917282bc 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -19,7 +19,7 @@ if NRF_RTC_TIMER config NRF_RTC_TIMER_USER_CHAN_COUNT int "Additional channels that can be used" - default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET + default 2 if NRF_802154_RADIO_DRIVER && SOC_COMPATIBLE_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 0 help From 765b31979f1147aa3c8780703d4868364f0fd420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Wed, 18 Oct 2023 09:11:23 +0200 Subject: [PATCH 2293/4498] Bluetooth: mesh: update model extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a goto statement to ensure that model extensions are registered in Composition Data Page 1 if it is enabled. Signed-off-by: Håvard Reierstad --- subsys/bluetooth/mesh/access.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 63c4f76c392..6ca7dbe580b 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1678,7 +1678,7 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod /* Check if a's list contains b */ for (it = a; (it != NULL) && (it->next != a); it = it->next) { if (it == b) { - return 0; + goto register_extension; } } @@ -1695,7 +1695,7 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod a->next = b; } - +register_extension: if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { return mod_rel_register(base_mod, extending_mod, RELATION_TYPE_EXT); } From ff2b8271439e650744818ae68a86f1d66ecbaef0 Mon Sep 17 00:00:00 2001 From: Martin Gritzan Date: Wed, 18 Oct 2023 14:02:09 +0200 Subject: [PATCH 2294/4498] drivers: stm32-exti: do not lock hwsem on irq disable Remove the HWSEM locking around stm32_exti_disable(). The STM32 EXTI driver uses the core-local interrupt mask regsiters on STM32H7x7 asym. dualcore MCUs. There is no need to lock the HWSEM guarding the EXTI when accessing these registers. Some sensor drivers toggle their interrupt mask every time the sensor triggers the IRQ line. Locking the HWSEM fails e.g. in situations where one coprocessor serivces the sensor and the other coprocessor sets up its interrupts initially during bootup. This prevents the sensor driver from locking the HWSEM and causes a kernel panic on the corresponding CPU. Note: The opposing stm32_exti_enable() was already correctly without locking. Signed-off-by: Martin Gritzan --- drivers/interrupt_controller/intc_exti_stm32.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/interrupt_controller/intc_exti_stm32.c b/drivers/interrupt_controller/intc_exti_stm32.c index 064d23cae20..f5f8bdc7d6e 100644 --- a/drivers/interrupt_controller/intc_exti_stm32.c +++ b/drivers/interrupt_controller/intc_exti_stm32.c @@ -73,8 +73,6 @@ void stm32_exti_enable(int line) void stm32_exti_disable(int line) { - z_stm32_hsem_lock(CFG_HW_EXTI_SEMID, HSEM_LOCK_DEFAULT_RETRY); - if (line < 32) { #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4) LL_C2_EXTI_DisableIT_0_31(BIT((uint32_t)line)); @@ -84,7 +82,6 @@ void stm32_exti_disable(int line) } else { __ASSERT_NO_MSG(line); } - z_stm32_hsem_unlock(CFG_HW_EXTI_SEMID); } /** From 31081d8411acef307575a383e30e329d3b6acb48 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 18 Oct 2023 18:08:12 +0300 Subject: [PATCH 2295/4498] net: tcp: Change FL() macro to avoid runtime overhead Instead of strlen() use sizeof() in FL() macro. This way all the checks are done at compile time instead of runtime. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp_private.h b/subsys/net/ip/tcp_private.h index a7b8dff3574..7dddf75c7b7 100644 --- a/subsys/net/ip/tcp_private.h +++ b/subsys/net/ip/tcp_private.h @@ -328,6 +328,6 @@ struct tcp { /* TCP connection */ }) #define FL(_fl, _op, _mask, _args...) \ - _flags(_fl, _op, _mask, strlen("" #_args) ? _args : true) + _flags(_fl, _op, _mask, sizeof(#_args) > 1 ? _args : true) typedef void (*net_tcp_cb_t)(struct tcp *conn, void *user_data); From 0a25a61c7df60cf1a59e5052e9ea719dafdd8563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 18 Oct 2023 17:43:13 +0200 Subject: [PATCH 2296/4498] Bluetooth: Mesh: Op agg mdl coex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactors the implementation of the Opcode Aggregator models to allow them to coexist on the same device. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/access.c | 6 +- subsys/bluetooth/mesh/op_agg.c | 91 ++++++++-------------------- subsys/bluetooth/mesh/op_agg.h | 39 +++--------- subsys/bluetooth/mesh/op_agg_cli.c | 96 ++++++++++++++++++------------ subsys/bluetooth/mesh/op_agg_srv.c | 66 ++++++++++++++------ 5 files changed, 141 insertions(+), 157 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 6ca7dbe580b..583652d4fbb 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1506,8 +1506,10 @@ int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data) { - if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG) && bt_mesh_op_agg_accept(ctx)) { - return bt_mesh_op_agg_send(model, ctx, msg, cb); + if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_SRV) && bt_mesh_op_agg_srv_accept(ctx, msg)) { + return bt_mesh_op_agg_srv_send(model, msg); + } else if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) && bt_mesh_op_agg_cli_accept(ctx, msg)) { + return bt_mesh_op_agg_cli_send(model, msg); } if (!bt_mesh_model_has_key(model, ctx->app_idx)) { diff --git a/subsys/bluetooth/mesh/op_agg.c b/subsys/bluetooth/mesh/op_agg.c index 1580c7f0847..8c4497e4f6f 100644 --- a/subsys/bluetooth/mesh/op_agg.c +++ b/subsys/bluetooth/mesh/op_agg.c @@ -16,83 +16,22 @@ LOG_MODULE_REGISTER(bt_mesh_op_agg); #define IS_LENGTH_LONG(buf) ((buf)->data[0] & 1) #define LENGTH_SHORT_MAX BIT_MASK(7) -NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); -NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX); - -static struct op_agg_ctx agg_ctx = { - .sdu = &sdu, -#if IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) - .srcs = &srcs, -#endif -}; - -struct op_agg_ctx *bt_mesh_op_agg_ctx_get(void) -{ - return &agg_ctx; -} - -static bool ctx_match(struct bt_mesh_msg_ctx *ctx) -{ - return (ctx->net_idx == agg_ctx.net_idx) && (ctx->addr == agg_ctx.addr) && - (ctx->app_idx == agg_ctx.app_idx); -} - -int bt_mesh_op_agg_accept(struct bt_mesh_msg_ctx *msg_ctx) -{ - return agg_ctx.initialized && ctx_match(msg_ctx); -} - -void bt_mesh_op_agg_ctx_reinit(void) -{ - agg_ctx.initialized = true; -} - -int bt_mesh_op_agg_send(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, - const struct bt_mesh_send_cb *cb) -{ - int err; - - /* Model responded so mark this message as acknowledged */ - agg_ctx.ack = true; - - if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI)) { - /* Store source address so that Opcodes Aggregator Client can - * match response with source model - */ - uint16_t src = bt_mesh_model_elem(model)->addr; - - if (net_buf_simple_tailroom(&srcs) < 2) { - return -ENOMEM; - } - - net_buf_simple_add_le16(&srcs, src); - } - - err = bt_mesh_op_agg_encode_msg(msg); - if (err) { - agg_ctx.rsp_err = ACCESS_STATUS_RESPONSE_OVERFLOW; - } - - return err; -} - -int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg) +int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf) { if (msg->len > LENGTH_SHORT_MAX) { - if (net_buf_simple_tailroom(agg_ctx.sdu) < (msg->len + 2)) { + if (net_buf_simple_tailroom(buf) < (msg->len + 2)) { return -ENOMEM; } - net_buf_simple_add_le16(agg_ctx.sdu, (msg->len << 1) | 1); + net_buf_simple_add_le16(buf, (msg->len << 1) | 1); } else { - if (net_buf_simple_tailroom(agg_ctx.sdu) < (msg->len + 1)) { + if (net_buf_simple_tailroom(buf) < (msg->len + 1)) { return -ENOMEM; } - net_buf_simple_add_u8(agg_ctx.sdu, msg->len << 1); + net_buf_simple_add_u8(buf, msg->len << 1); } - net_buf_simple_add_mem(agg_ctx.sdu, msg->data, msg->len); + net_buf_simple_add_mem(buf, msg->data, msg->len); return 0; } @@ -124,3 +63,21 @@ int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, return 0; } + +bool bt_mesh_op_agg_is_op_agg_msg(struct net_buf_simple *buf) +{ + if (buf->len >= 2 && (buf->data[0] >> 6) == 2) { + uint16_t opcode; + struct net_buf_simple_state state; + + net_buf_simple_save(buf, &state); + opcode = net_buf_simple_pull_be16(buf); + net_buf_simple_restore(buf, &state); + + if ((opcode == OP_OPCODES_AGGREGATOR_STATUS) || + (opcode == OP_OPCODES_AGGREGATOR_SEQUENCE)) { + return true; + } + } + return false; +} diff --git a/subsys/bluetooth/mesh/op_agg.h b/subsys/bluetooth/mesh/op_agg.h index a267fc737f7..8bb3d6c97ba 100644 --- a/subsys/bluetooth/mesh/op_agg.h +++ b/subsys/bluetooth/mesh/op_agg.h @@ -7,45 +7,20 @@ struct op_agg_ctx { /** Context is initialized. */ bool initialized; - /** NetKey Index of the subnet to send the message on. */ uint16_t net_idx; - /** AppKey Index to encrypt the message with. */ uint16_t app_idx; - /** Remote element address. */ uint16_t addr; - - /** List of source element addresses. - * Used by Client to match aggregated responses - * with local source client models. - */ - struct net_buf_simple *srcs; - - /** Response error code. */ - int rsp_err; - /** Aggregated message buffer. */ struct net_buf_simple *sdu; - - /** Used only by the Opcodes Aggregator Server. - * - * Indicates that the received aggregated message - * was acknowledged by local server model. - */ - bool ack; }; -struct op_agg_ctx *bt_mesh_op_agg_ctx_get(void); -void bt_mesh_op_agg_ctx_reinit(void); - -int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg); -int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, - struct net_buf_simple *buf); - -int bt_mesh_op_agg_accept(struct bt_mesh_msg_ctx *ctx); - -int bt_mesh_op_agg_send(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, - const struct bt_mesh_send_cb *cb); +int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf); +int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf); +int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg); +int bt_mesh_op_agg_cli_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); +int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg); +int bt_mesh_op_agg_srv_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); +bool bt_mesh_op_agg_is_op_agg_msg(struct net_buf_simple *buf); diff --git a/subsys/bluetooth/mesh/op_agg_cli.c b/subsys/bluetooth/mesh/op_agg_cli.c index d3371306a8b..612843a98cc 100644 --- a/subsys/bluetooth/mesh/op_agg_cli.c +++ b/subsys/bluetooth/mesh/op_agg_cli.c @@ -18,14 +18,24 @@ #include LOG_MODULE_REGISTER(bt_mesh_op_agg_cli); +NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX); +NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); + /** Mesh Opcodes Aggregator Client Model Context */ static struct bt_mesh_op_agg_cli { /** Composition data model entry pointer. */ struct bt_mesh_model *model; - - /* Internal parameters for tracking message responses. */ + /** Acknowledge context. */ struct bt_mesh_msg_ack_ctx ack_ctx; -} cli; + /** List of source element addresses. + * Used by Client to match aggregated responses + * with local source client models. + */ + struct net_buf_simple *srcs; + /** Aggregator context. */ + struct op_agg_ctx ctx; + +} cli = {.srcs = &srcs, .ctx.sdu = &sdu}; static int32_t msg_timeout; @@ -33,7 +43,6 @@ static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); struct net_buf_simple msg; uint8_t status; uint16_t elem_addr, addr; @@ -57,17 +66,17 @@ static int handle_status(struct bt_mesh_model *model, err = bt_mesh_op_agg_decode_msg(&msg, buf); if (err) { LOG_ERR("Cannot decode aggregated message %d", err); - bt_mesh_op_agg_ctx_reinit(); + cli.ctx.initialized = true; return -EINVAL; } - if (agg->srcs->len < 2) { + if (cli.srcs->len < 2) { LOG_ERR("Mismatch in sources address buffer"); - bt_mesh_op_agg_ctx_reinit(); + cli.ctx.initialized = true; return -ENOENT; } - addr = net_buf_simple_pull_le16(agg->srcs); + addr = net_buf_simple_pull_le16(cli.srcs); /* Empty item means unacked msg. */ if (!msg.len) { @@ -78,7 +87,7 @@ static int handle_status(struct bt_mesh_model *model, err = bt_mesh_model_recv(ctx, &msg); if (err) { LOG_ERR("Opcodes Aggregator receive error %d", err); - bt_mesh_op_agg_ctx_reinit(); + cli.ctx.initialized = true; return err; } } @@ -115,56 +124,51 @@ static int op_agg_cli_init(struct bt_mesh_model *model) int bt_mesh_op_agg_cli_seq_start(uint16_t net_idx, uint16_t app_idx, uint16_t dst, uint16_t elem_addr) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); - if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { LOG_ERR("Element address shall be a unicast address"); return -EINVAL; } - if (agg->initialized) { + if (cli.ctx.initialized) { LOG_ERR("Opcodes Aggregator is already configured"); return -EALREADY; } - agg->net_idx = net_idx; - agg->app_idx = app_idx; - agg->addr = dst; - agg->ack = false; - agg->rsp_err = 0; - agg->initialized = true; + cli.ctx.net_idx = net_idx; + cli.ctx.app_idx = app_idx; + cli.ctx.addr = dst; + cli.ctx.initialized = true; - net_buf_simple_init(agg->srcs, 0); - bt_mesh_model_msg_init(agg->sdu, OP_OPCODES_AGGREGATOR_SEQUENCE); - net_buf_simple_add_le16(agg->sdu, elem_addr); + net_buf_simple_init(cli.srcs, 0); + bt_mesh_model_msg_init(cli.ctx.sdu, OP_OPCODES_AGGREGATOR_SEQUENCE); + net_buf_simple_add_le16(cli.ctx.sdu, elem_addr); return 0; } int bt_mesh_op_agg_cli_seq_send(void) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); struct bt_mesh_msg_ctx ctx = { - .net_idx = agg->net_idx, - .app_idx = agg->app_idx, - .addr = agg->addr, + .net_idx = cli.ctx.net_idx, + .app_idx = cli.ctx.app_idx, + .addr = cli.ctx.addr, }; int err; - if (!agg->initialized) { + if (!cli.ctx.initialized) { LOG_ERR("Opcodes Aggregator not initialized"); return -EINVAL; } - err = bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, OP_OPCODES_AGGREGATOR_STATUS, agg->addr, - NULL); + err = bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, OP_OPCODES_AGGREGATOR_STATUS, + cli.ctx.addr, NULL); if (err) { return err; } - agg->initialized = false; + cli.ctx.initialized = false; - err = bt_mesh_model_send(cli.model, &ctx, agg->sdu, NULL, NULL); + err = bt_mesh_model_send(cli.model, &ctx, cli.ctx.sdu, NULL, NULL); if (err) { LOG_ERR("model_send() failed (err %d)", err); bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx); @@ -176,23 +180,17 @@ int bt_mesh_op_agg_cli_seq_send(void) void bt_mesh_op_agg_cli_seq_abort(void) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); - - agg->initialized = false; + cli.ctx.initialized = false; } bool bt_mesh_op_agg_cli_seq_is_started(void) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); - - return agg->initialized; + return cli.ctx.initialized; } size_t bt_mesh_op_agg_cli_seq_tailroom(void) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); - - return net_buf_simple_tailroom(agg->sdu); + return net_buf_simple_tailroom(cli.ctx.sdu); } int32_t bt_mesh_op_agg_cli_timeout_get(void) @@ -205,6 +203,26 @@ void bt_mesh_op_agg_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } +int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg) +{ + uint16_t src = bt_mesh_model_elem(model)->addr; + + if (net_buf_simple_tailroom(&srcs) < 2) { + return -ENOMEM; + } + + net_buf_simple_add_le16(&srcs, src); + return bt_mesh_op_agg_encode_msg(msg, cli.ctx.sdu); +} + +int bt_mesh_op_agg_cli_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) +{ + + return cli.ctx.initialized && (ctx->net_idx == cli.ctx.net_idx) && + (ctx->addr == cli.ctx.addr) && (ctx->app_idx == cli.ctx.app_idx) && + !bt_mesh_op_agg_is_op_agg_msg(buf); +} + const struct bt_mesh_model_cb _bt_mesh_op_agg_cli_cb = { .init = op_agg_cli_init, }; diff --git a/subsys/bluetooth/mesh/op_agg_srv.c b/subsys/bluetooth/mesh/op_agg_srv.c index bed3b54c946..a6e5f666411 100644 --- a/subsys/bluetooth/mesh/op_agg_srv.c +++ b/subsys/bluetooth/mesh/op_agg_srv.c @@ -17,17 +17,26 @@ #include LOG_MODULE_REGISTER(bt_mesh_op_agg_srv); +NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); + /** Mesh Opcodes Aggragator Server Model Context */ static struct bt_mesh_op_agg_srv { /** Composition data model entry pointer. */ struct bt_mesh_model *model; -} srv; + /** Response error code. */ + int rsp_err; + /** Indicates that the received aggregated message + * was acknowledged by local server model. + */ + bool ack; + /** Aggregator context. */ + struct op_agg_ctx ctx; +} srv = {.ctx.sdu = &sdu}; static int handle_sequence(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get(); struct net_buf_simple_state state; struct net_buf_simple msg; uint16_t elem; @@ -37,14 +46,14 @@ static int handle_sequence(struct bt_mesh_model *model, elem = net_buf_simple_pull_le16(buf); ctx->recv_dst = elem; - bt_mesh_model_msg_init(agg->sdu, OP_OPCODES_AGGREGATOR_STATUS); - status = net_buf_simple_add_u8(agg->sdu, 0); - net_buf_simple_add_le16(agg->sdu, elem); + bt_mesh_model_msg_init(srv.ctx.sdu, OP_OPCODES_AGGREGATOR_STATUS); + status = net_buf_simple_add_u8(srv.ctx.sdu, 0); + net_buf_simple_add_le16(srv.ctx.sdu, elem); - agg->net_idx = ctx->net_idx; - agg->app_idx = ctx->app_idx; - agg->addr = ctx->addr; - agg->initialized = true; + srv.ctx.net_idx = ctx->net_idx; + srv.ctx.app_idx = ctx->app_idx; + srv.ctx.addr = ctx->addr; + srv.ctx.initialized = true; if (!BT_MESH_ADDR_IS_UNICAST(elem)) { LOG_WRN("Address is not unicast, ignoring."); @@ -70,12 +79,12 @@ static int handle_sequence(struct bt_mesh_model *model, while (buf->len > 0) { (void) bt_mesh_op_agg_decode_msg(&msg, buf); - agg->ack = false; - agg->rsp_err = 0; + srv.ack = false; + srv.rsp_err = 0; err = bt_mesh_model_recv(ctx, &msg); - if (agg->rsp_err) { - *status = agg->rsp_err; + if (srv.rsp_err) { + *status = srv.rsp_err; break; } @@ -84,14 +93,14 @@ static int handle_sequence(struct bt_mesh_model *model, break; } - if (!agg->ack) { - net_buf_simple_add_u8(agg->sdu, 0); + if (!srv.ack) { + net_buf_simple_add_u8(srv.ctx.sdu, 0); } } send: - agg->initialized = false; - err = bt_mesh_model_send(model, ctx, agg->sdu, NULL, NULL); + srv.ctx.initialized = false; + err = bt_mesh_model_send(model, ctx, srv.ctx.sdu, NULL, NULL); if (err) { LOG_ERR("Unable to send Opcodes Aggregator Status"); return err; @@ -122,6 +131,29 @@ static int op_agg_srv_init(struct bt_mesh_model *model) return 0; } +int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg) +{ + int err; + + /* Model responded so mark this message as acknowledged */ + srv.ack = true; + + err = bt_mesh_op_agg_encode_msg(msg, srv.ctx.sdu); + if (err) { + srv.rsp_err = ACCESS_STATUS_RESPONSE_OVERFLOW; + } + + return err; +} + +int bt_mesh_op_agg_srv_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) +{ + + return srv.ctx.initialized && (ctx->net_idx == srv.ctx.net_idx) && + (ctx->addr == srv.ctx.addr) && (ctx->app_idx == srv.ctx.app_idx) && + !bt_mesh_op_agg_is_op_agg_msg(buf); +} + const struct bt_mesh_model_cb _bt_mesh_op_agg_srv_cb = { .init = op_agg_srv_init, }; From fc152c8e439d4e6b44898ad97e22b04b672056ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 18 Oct 2023 17:48:11 +0200 Subject: [PATCH 2297/4498] tests: Bluetooth: Mesh: Add op_agg coex test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds coexistence Bsim test for Opcode Aggregator models. The test verifies that the Opcode Aggregator server and client can be present and functional when operating on the same device. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/src/test_op_agg.c | 91 ++++++++++++++----- .../mesh/tests_scripts/op_agg/model_coex.sh | 31 +++++++ 2 files changed, 98 insertions(+), 24 deletions(-) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh diff --git a/tests/bsim/bluetooth/mesh/src/test_op_agg.c b/tests/bsim/bluetooth/mesh/src/test_op_agg.c index 9f091491e00..85bc1a6ba26 100644 --- a/tests/bsim/bluetooth/mesh/src/test_op_agg.c +++ b/tests/bsim/bluetooth/mesh/src/test_op_agg.c @@ -51,13 +51,6 @@ static struct k_sem cli_suspend_sem; static struct k_sem srv_suspend_sem; static const uint8_t dev_key[16] = {0xaa}; static uint8_t cli_sent_array[TEST_SEND_ITR], cli_rcvd_array[TEST_SEND_ITR]; - -static struct bt_mesh_msg_ctx test_ctx = { - .net_idx = 0, - .app_idx = 0, - .addr = SRV_ADDR, -}; - static struct bt_mesh_prov prov; static struct bt_mesh_cfg_cli cfg_cli; @@ -168,25 +161,43 @@ static void op_agg_test_prov_and_conf(uint16_t addr) } } -static void test_cli_max_len_sequence_msg_send(void) +static void common_init(uint16_t own_addr, uint16_t dst_addr, bool agg_cli_fill) { - struct bt_mesh_model *dummy_vnd_model = &elements[0].vnd_models[0]; - uint8_t seq; - bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &comp); - op_agg_test_prov_and_conf(CLI_ADDR); + op_agg_test_prov_and_conf(own_addr); ASSERT_OK(k_sem_init(&cli_suspend_sem, 0, 1)); - ASSERT_OK(bt_mesh_op_agg_cli_seq_start(0, 0, SRV_ADDR, SRV_ADDR)); + ASSERT_OK(k_sem_init(&srv_suspend_sem, 0, 1)); + ASSERT_OK(bt_mesh_op_agg_cli_seq_start(0, 0, dst_addr, dst_addr)); + if (!agg_cli_fill) { + return; + } + + struct bt_mesh_msg_ctx ctx = { + .net_idx = 0, + .app_idx = 0, + .addr = dst_addr, + }; + + /* Populate the op_agg sequence */ for (int i = 0; i < TEST_SEND_ITR; i++) { - seq = cli_sent_array[i] = i; - ASSERT_OK(dummy_vnd_mod_get(dummy_vnd_model, &test_ctx, seq)); + cli_sent_array[i] = i; + ASSERT_OK(dummy_vnd_mod_get(&elements[0].vnd_models[0], &ctx, i)); } +} - ASSERT_OK(bt_mesh_op_agg_cli_seq_send()); +static void confirm_agg_seq(void) +{ + /* Wait for all expected GET messages to be received */ + if (k_sem_take(&srv_suspend_sem, SEM_TIMEOUT)) { + FAIL("Server suspension timed out. Get-messages received: %d", get_rcvd_count); + } +} +static void confirm_agg_status(void) +{ /* Wait for all expected STATUS messages to be received */ if (k_sem_take(&cli_suspend_sem, SEM_TIMEOUT)) { FAIL("Client suspension timed out. Status-messages received: %d", @@ -196,22 +207,52 @@ static void test_cli_max_len_sequence_msg_send(void) if (memcmp(cli_sent_array, cli_rcvd_array, ARRAY_SIZE(cli_rcvd_array))) { FAIL("Message arrays (sent / rcvd) are not equal."); } +} +static void test_cli_max_len_sequence_msg_send(void) +{ + common_init(CLI_ADDR, SRV_ADDR, true); + ASSERT_OK(bt_mesh_op_agg_cli_seq_send()); + confirm_agg_status(); PASS(); } static void test_srv_max_len_status_msg_send(void) { - bt_mesh_test_cfg_set(NULL, WAIT_TIME); - bt_mesh_device_setup(&prov, &comp); - op_agg_test_prov_and_conf(SRV_ADDR); + common_init(SRV_ADDR, CLI_ADDR, false); + confirm_agg_seq(); + PASS(); +} - ASSERT_OK(k_sem_init(&srv_suspend_sem, 0, 1)); +static void test_tester_model_coex(void) +{ + common_init(CLI_ADDR, SRV_ADDR, true); - /* Wait for all expected GET messages to be received */ - if (k_sem_take(&srv_suspend_sem, SEM_TIMEOUT)) { - FAIL("Server suspension timed out. Get-messages received: %d", get_rcvd_count); - } + /* Immediately send aggregated sequence to srv device */ + ASSERT_OK(bt_mesh_op_agg_cli_seq_send()); + + /* Confirm status messages for sequence */ + confirm_agg_status(); + + /* Confirm incoming sequence messages from server */ + confirm_agg_seq(); + + PASS(); +} + +static void test_dut_model_coex(void) +{ + /* Start an aggregated sequence, but postpone sending it */ + common_init(SRV_ADDR, CLI_ADDR, true); + + /* Wait and confirm incoming sequence messages from cli device */ + confirm_agg_seq(); + + /* After incoming sequence completes, send aggregated sequence to srv device */ + ASSERT_OK(bt_mesh_op_agg_cli_seq_send()); + + /* Confirm status messages for sequence */ + confirm_agg_status(); PASS(); } @@ -228,8 +269,10 @@ static const struct bst_test_instance test_op_agg[] = { TEST_CASE(cli, max_len_sequence_msg_send, "OpAggCli composes a sequence request list, expecting a 380 Byte status message " "in return."), + TEST_CASE(tester, model_coex, "Tester: Coexistence of OpAggSrv and OpAggCli."), TEST_CASE(srv, max_len_status_msg_send, "OpAggSrv will respond with a 380 Byte status message. "), + TEST_CASE(dut, model_coex, "DUT: Coexistence of OpAggSrv and OpAggCli."), BSTEST_END_MARKER}; diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh new file mode 100755 index 00000000000..08fcdf9f41e --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that Opcode aggregator server and client can coexist on the same device. +# In this test scenario, the DUT has a sequence in progress on the Opcode +# Aggregator client model that is interrupted by an incoming sequence to the Opcode +# Aggregator server model. The test verifies that both the incoming and outgoing +# sequence on the DUT completes successfully. +# +# Test procedure: +# 1. Both Tester and DUT device initialize both Opcode aggregator server and client. +# Both devices starts an Opcode aggregator sequence and populates the buffer. +# 2. The Tester device immediately starts sending the sequence. +# 3. The DUT device waits, and verifies that the sequence is correctly received. +# Then it starts sending its own aggregated sequence. +# 4. The Tester device confirms that it received all status messages related to its +# own aggregated sequence from the DUT device, then it verifies that the +# aggregated sequence from the DUT device is correctly received. +# 5. Finally, the DUT device waits and confirms that it received all status messages +# related to its own aggregated sequence from the cli device. +conf=prj_mesh1d1_conf +RunTest mesh_op_agg_model_coex \ + op_agg_tester_model_coex op_agg_dut_model_coex + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_op_agg_model_coex \ + op_agg_tester_model_coex op_agg_dut_model_coex From fe9ffdadedbc9006841993a721a10df946536d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Thu, 19 Oct 2023 09:57:18 +0200 Subject: [PATCH 2298/4498] tests: Bluetooth: Mesh: Op_agg coex loopback test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds coexistence Bsim test for Opcode Aggregator models using loopback. The test verifies that the Opcode Aggregator server and client can send messages to each other on the loopback interface. Signed-off-by: Anders Storrø --- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 1 + tests/bsim/bluetooth/mesh/src/test_op_agg.c | 18 +++++++++++++++ .../mesh/tests_scripts/op_agg/loopback.sh | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index 8bfb3b9e887..ab6066e01bf 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -25,6 +25,7 @@ CONFIG_BT_MESH_TX_SEG_MAX=32 CONFIG_BT_MESH_RX_SEG_MAX=32 CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 CONFIG_BT_MESH_RX_SEG_MSG_COUNT=10 +CONFIG_BT_MESH_SEG_BUFS=100 CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_MODEL_GROUP_COUNT=3 CONFIG_BT_MESH_LOW_POWER=y diff --git a/tests/bsim/bluetooth/mesh/src/test_op_agg.c b/tests/bsim/bluetooth/mesh/src/test_op_agg.c index 85bc1a6ba26..d8bb50b3fd3 100644 --- a/tests/bsim/bluetooth/mesh/src/test_op_agg.c +++ b/tests/bsim/bluetooth/mesh/src/test_op_agg.c @@ -257,6 +257,23 @@ static void test_dut_model_coex(void) PASS(); } +static void test_dut_model_coex_loopback(void) +{ + /* Start an aggregated sequence */ + common_init(SRV_ADDR, SRV_ADDR, true); + + /* Send aggregated sequence to server model over loopback */ + ASSERT_OK(bt_mesh_op_agg_cli_seq_send()); + + /* Confirm incoming sequence messages */ + confirm_agg_seq(); + + /* Confirm status messages for sequence */ + confirm_agg_status(); + + PASS(); +} + #define TEST_CASE(role, name, description) \ { \ .test_id = "op_agg_" #role "_" #name, \ @@ -273,6 +290,7 @@ static const struct bst_test_instance test_op_agg[] = { TEST_CASE(srv, max_len_status_msg_send, "OpAggSrv will respond with a 380 Byte status message. "), TEST_CASE(dut, model_coex, "DUT: Coexistence of OpAggSrv and OpAggCli."), + TEST_CASE(dut, model_coex_loopback, "DUT: Coexistence for OpAggSrv and OpAggCli loopback."), BSTEST_END_MARKER}; diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh new file mode 100755 index 00000000000..3a4720bdaf4 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that an Opcode aggregated message can be sent and received on loopback. +# +# Test procedure: +# 1. The device initializes both Opcode aggregator server and client. +# The device starts an Opcode aggregator sequence and populates the buffer. +# 2. The device starts sending the sequence on loopback. +# 3. The device verifies that the sequence is correctly received by the server model. +# 4. The device confirms that the client model received all status messages. +conf=prj_mesh1d1_conf +RunTest mesh_op_agg_model_coex_loopback \ + op_agg_dut_model_coex_loopback + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_op_agg_model_coex_loopback \ + op_agg_dut_model_coex_loopback From 7aa34e6482a3394e178cf9178bf18006e0bc27bc Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 19 Oct 2023 11:33:40 +1000 Subject: [PATCH 2299/4498] bluetooth: hci_core: handle NUM_COMPLETED_PACKETS rsp The `BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS` is not expected to generate a response from the controller, but from the spec: Normally, no event is generated after the HCI_Host_Number_Of_Completed_Packets command has completed. However, if the HCI_Host_Number_Of_Completed_Packets command contains one or more invalid parameters, the Controller shall return an HCI_Command_Complete event with a failure status indicating the Invalid HCI Command Parameters error code. In practice, this can also be generated if flow control is inadvertedly turned off during operation. Running `hci_cmd_done` is not correct when the event happens (as there is no corresponding command buffer), and `ncmd` should not be returned as this command ignores the semaphore when sending. Signed-off-by: Jordan Yates --- subsys/bluetooth/host/hci_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 7b607d6f048..5dd68da4dce 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2337,6 +2337,14 @@ static void hci_cmd_complete(struct net_buf *buf) */ status = buf->data[0]; + /* HOST_NUM_COMPLETED_PACKETS should not generate a response under normal operation. + * The generation of this command ignores `ncmd_sem`, so should not be given here. + */ + if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) { + LOG_WRN("Unexpected HOST_NUM_COMPLETED_PACKETS (status 0x%02x)", status); + return; + } + hci_cmd_done(opcode, status, buf); /* Allow next command to be sent */ From eac3ba2b3d52d53cf9cbf98f9c9c8c3e859d7003 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Thu, 19 Oct 2023 09:21:53 +0200 Subject: [PATCH 2300/4498] mgmt: ec_host_cmd: remove timeout for UART callback Do not use timeout for UART callback. The UART IRQ bases on the IDLE line, so waiting for additional bytes is not necessary and it introduce additional latency. Another issue with the timeout is that the UART drivers use sysworkq for implementing timeout. The sysworkq thread may have lower prio than the host command thread, which may cause a delay in calling the UART callback, which gives the semaphore to the HC handler. Signed-off-by: Dawid Niedzwiecki --- .../ec_host_cmd/backends/ec_host_cmd_backend_uart.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c index a15eecfc4e7..0d43c9ccd79 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c @@ -100,8 +100,6 @@ static int request_expected_size(const struct ec_host_cmd_request_header *r) .ctx = &_name##_hc_uart, \ } -/* Waiting time in microseconds to detect overrun */ -#define UART_OVERRUN_TIMEOUT_US 300 /* Timeout after receiving first byte */ #define UART_REQ_RX_TIMEOUT K_MSEC(150) @@ -135,8 +133,7 @@ static void rx_timeout(struct k_work *work) } res = uart_rx_disable(hc_uart->uart_dev); - res = uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, - UART_OVERRUN_TIMEOUT_US); + res = uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, 0); hc_uart->state = UART_HOST_CMD_READY_TO_RX; } @@ -247,8 +244,7 @@ static int ec_host_cmd_uart_init(const struct ec_host_cmd_backend *backend, k_work_init_delayable(&hc_uart->timeout_work, rx_timeout); uart_callback_set(hc_uart->uart_dev, uart_callback, hc_uart); - ret = uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, - UART_OVERRUN_TIMEOUT_US); + ret = uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, 0); hc_uart->state = UART_HOST_CMD_READY_TO_RX; @@ -270,8 +266,7 @@ static int ec_host_cmd_uart_send(const struct ec_host_cmd_backend *backend) /* The rx buffer is no longer in use by command handler. * Enable receiving to be ready to get a new command right after sending the response. */ - uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, - UART_OVERRUN_TIMEOUT_US); + uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, 0); /* uart_tx is non-blocking asynchronous function. * The state is changed to UART_HOST_CMD_READY_TO_RX in the UART_TX_DONE event. From d933e7417f58a673886293448230d099e04eb211 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 19 Oct 2023 09:37:06 +0000 Subject: [PATCH 2301/4498] doc: guidelines: add a note about specialized drivers Add a note about requirements for specialized drivers, clarifying the requirements about using Zephyr APIs. Signed-off-by: Fabio Baltieri --- doc/contribute/guidelines.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 5460d0954ed..bc6bbed81b3 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -1026,3 +1026,18 @@ Some example past treewide changes are: Note that adding a new version of a widely used API while maintaining support for the old one is not a treewide change. Deprecation and removal of such APIs, however, are treewide changes. + +Specialized driver requirements +=============================== + +Drivers for standalone devices should use the Zephyr bus APIs (SPI, I2C...) +whenever possible so that the device can be used with any SoC from any vendor +implementing a compatible bus. + +If it is not technically possible to achieve full performance using the Zephyr +APIs due to specialized accelerators in a particular SoC family, one could +extend the support for an external device by providing a specialized path for +that SoC family. However, the driver must still provide a regular path (via +Zephyr APIs) for all other SoCs. Every exception must be approved by the +Architecture WG in order to be validated and potentially to be learned/improved +from. From 32d0c8d8e5c76039ea64e7101b6e7c1a0b56264c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 17 Oct 2023 17:06:01 +0200 Subject: [PATCH 2302/4498] nrf53: Refactor sync RTC options to their own file So they can be reused by the simulated board Signed-off-by: Alberto Escolar Piedras --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 74 +--------------------- soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc | 77 +++++++++++++++++++++++ 2 files changed, 78 insertions(+), 73 deletions(-) create mode 100644 soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 2cd934af324..f6a2c019f5f 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -188,78 +188,6 @@ config BUILD_WITH_TFM # TF-M nRF53 platform enables the cache unconditionally. select NRF_ENABLE_CACHE if SOC_NRF5340_CPUAPP -config NRF53_SYNC_RTC - bool "RTC clock synchronization" - default y if LOG && !LOG_MODE_MINIMAL - depends on NRF_RTC_TIMER - select NRFX_DPPI - select MBOX if !IPM - -if NRF53_SYNC_RTC - -module = SYNC_RTC -module-str = Synchronized RTC -source "subsys/logging/Kconfig.template.log_config" - -config NRF53_SYNC_RTC_INIT_PRIORITY - int "nRF53 Synchronized RTC init priority" - default APPLICATION_INIT_PRIORITY - help - nRF53 Synchronized RTC initialization priority. - -config NRF_RTC_TIMER_USER_CHAN_COUNT - default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET - default 3 if NRF_802154_RADIO_DRIVER - default 1 +rsource "Kconfig.sync_rtc" -config NRF53_SYNC_RTC_LOG_TIMESTAMP - bool "Use Synchronized RTC for logging timestamp" - default y - -config NRF53_SYNC_RTC_IPM_OUT - int "IPM channel from APP to NET" - range 0 15 - default 7 if SOC_NRF5340_CPUAPP - default 8 - -config NRF53_SYNC_RTC_IPM_IN - int "IPM channel from APP to NET" - range 0 15 - default 8 if SOC_NRF5340_CPUAPP - default 7 - -ipm_num = 0 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 1 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 2 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 3 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 4 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 5 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 6 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 7 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 8 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 9 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 10 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 11 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 12 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 13 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 14 -rsource "Kconfig.sync_rtc_ipm" -ipm_num = 15 -rsource "Kconfig.sync_rtc_ipm" - -endif # NRF53_SYNC_RTC endif # SOC_SERIES_NRF53X diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc b/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc new file mode 100644 index 00000000000..631e1db67df --- /dev/null +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc @@ -0,0 +1,77 @@ +# Copyright (c) 2019 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config NRF53_SYNC_RTC + bool "RTC clock synchronization" + default y if LOG && !LOG_MODE_MINIMAL + depends on NRF_RTC_TIMER + select NRFX_DPPI + select MBOX if !IPM + +if NRF53_SYNC_RTC + +module = SYNC_RTC +module-str = Synchronized RTC +source "subsys/logging/Kconfig.template.log_config" + +config NRF53_SYNC_RTC_INIT_PRIORITY + int "nRF53 Synchronized RTC init priority" + default APPLICATION_INIT_PRIORITY + help + nRF53 Synchronized RTC initialization priority. + +config NRF_RTC_TIMER_USER_CHAN_COUNT + default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET + default 3 if NRF_802154_RADIO_DRIVER + default 1 + +config NRF53_SYNC_RTC_LOG_TIMESTAMP + bool "Use Synchronized RTC for logging timestamp" + default y + +config NRF53_SYNC_RTC_IPM_OUT + int "IPM channel from APP to NET" + range 0 15 + default 7 if SOC_NRF5340_CPUAPP + default 8 + +config NRF53_SYNC_RTC_IPM_IN + int "IPM channel from APP to NET" + range 0 15 + default 8 if SOC_NRF5340_CPUAPP + default 7 + +ipm_num = 0 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 1 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 2 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 3 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 4 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 5 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 6 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 7 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 8 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 9 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 10 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 11 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 12 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 13 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 14 +rsource "Kconfig.sync_rtc_ipm" +ipm_num = 15 +rsource "Kconfig.sync_rtc_ipm" + +endif # NRF53_SYNC_RTC From 9834fabe2dfd091c2e3687af19165de411a37e14 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 18 Oct 2023 09:01:17 +0200 Subject: [PATCH 2303/4498] nrf53: Correct sync_rtc kconfig dependencies for simulation Let's make the sync_rtc kconfig depend on the SOC_COMPATIBLE options which are set both by the real and simulated targets, so this code works in the same way for both. Signed-off-by: Alberto Escolar Piedras --- soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc | 6 +++--- soc/arm/nordic_nrf/nrf53/sync_rtc.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc b/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc index 631e1db67df..475db911c67 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc @@ -21,7 +21,7 @@ config NRF53_SYNC_RTC_INIT_PRIORITY nRF53 Synchronized RTC initialization priority. config NRF_RTC_TIMER_USER_CHAN_COUNT - default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET + default 2 if NRF_802154_RADIO_DRIVER && SOC_COMPATIBLE_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 1 @@ -32,13 +32,13 @@ config NRF53_SYNC_RTC_LOG_TIMESTAMP config NRF53_SYNC_RTC_IPM_OUT int "IPM channel from APP to NET" range 0 15 - default 7 if SOC_NRF5340_CPUAPP + default 7 if SOC_COMPATIBLE_NRF5340_CPUAPP default 8 config NRF53_SYNC_RTC_IPM_IN int "IPM channel from APP to NET" range 0 15 - default 8 if SOC_NRF5340_CPUAPP + default 8 if SOC_COMPATIBLE_NRF5340_CPUAPP default 7 ipm_num = 0 diff --git a/soc/arm/nordic_nrf/nrf53/sync_rtc.c b/soc/arm/nordic_nrf/nrf53/sync_rtc.c index 235e9f26001..031f93244f7 100644 --- a/soc/arm/nordic_nrf/nrf53/sync_rtc.c +++ b/soc/arm/nordic_nrf/nrf53/sync_rtc.c @@ -119,7 +119,7 @@ static void free_resources(union rtc_sync_channels channels) int z_nrf_rtc_timer_nrf53net_offset_get(void) { - if (!IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) { + if (!IS_ENABLED(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)) { return -ENOSYS; } @@ -135,7 +135,7 @@ static void rtc_cb(int32_t id, uint64_t cc_value, void *user_data) channels.raw = (uint32_t)user_data; ppi_rtc_to_ipc(channels, false); - if (IS_ENABLED(CONFIG_SOC_NRF5340_CPUAPP)) { + if (IS_ENABLED(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP)) { /* APP: Synchronized completed */ free_resources(channels); } else { @@ -165,7 +165,7 @@ static void remote_callback(void *user_data) /* Clear previous task,event */ ppi_ipc_to_rtc(channels, false); - if (IS_ENABLED(CONFIG_SOC_NRF5340_CPUAPP)) { + if (IS_ENABLED(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP)) { /* Setup new connection from RTC to IPC and set RTC to a new * interval that contains captured offset. */ @@ -258,7 +258,7 @@ static int sync_rtc_setup(void) nrfx_gppi_channels_enable(BIT(channels.ch.ppi)); - if (IS_ENABLED(CONFIG_SOC_NRF5340_CPUAPP)) { + if (IS_ENABLED(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP)) { ppi_ipc_to_rtc(channels, true); } else { ppi_rtc_to_ipc(channels, true); From 2d5b781e999b2e36b43201b5730b409b2aa8a29a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 19 Oct 2023 13:21:59 -0700 Subject: [PATCH 2304/4498] llext: Fix wrong check In llext_copy_symbols the check after llext_read was looking the result of llext_seek operation instead of the read. Signed-off-by: Flavio Ceolin --- subsys/llext/llext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 5c195dc704c..a6bb7f57801 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -386,7 +386,7 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext goto out; } - llext_read(ldr, name, sizeof(name)); + ret = llext_read(ldr, name, sizeof(name)); if (ret != 0) { goto out; } From bc5da1a15819db5dda029c75d61d82959d80dd8c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 10:50:09 +0200 Subject: [PATCH 2305/4498] native simulator: Get latest from upstream Align with native_simulator's upstream main d32b2504ad2b6d6d541bc71a0f9b16ab7b6a3831 Which includes: * d32b250 Minor format fix * 7b4f35b native HW counter: Provide new API to reset and control * 4f815cb INT CNTLR: Bugfix for more than 32 interrupts * 1d36254 Provide new 64 version of nsi_find_lsb_set Signed-off-by: Alberto Escolar Piedras --- .../common/src/nsi_internal.h | 17 +++++++++++- .../native_simulator/native/src/hw_counter.c | 27 ++++++++++++++++++- .../native/src/include/hw_counter.h | 3 +++ .../native_simulator/native/src/irq_ctrl.c | 2 +- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/scripts/native_simulator/common/src/nsi_internal.h b/scripts/native_simulator/common/src/nsi_internal.h index 00e63897996..ebe8289b178 100644 --- a/scripts/native_simulator/common/src/nsi_internal.h +++ b/scripts/native_simulator/common/src/nsi_internal.h @@ -14,7 +14,6 @@ extern "C" { #endif /** - * * @brief find least significant bit set in a 32-bit word * * This routine finds the first bit set starting from the least significant bit @@ -30,6 +29,22 @@ static inline unsigned int nsi_find_lsb_set(uint32_t op) return __builtin_ffs(op); } +/** + * @brief find least significant bit set in a 64-bit word + * + * This routine finds the first bit set starting from the least significant bit + * in the argument passed in and returns the index of that bit. Bits are + * numbered starting at 1 from the least significant bit. A return value of + * zero indicates that the value passed is zero. + * + * @return least significant bit set, 0 if @a op is 0 + */ + +static inline unsigned int nsi_find_lsb_set64(uint64_t op) +{ + return __builtin_ffsll(op); +} + #ifdef __cplusplus } #endif diff --git a/scripts/native_simulator/native/src/hw_counter.c b/scripts/native_simulator/native/src/hw_counter.c index fc0770dc6a2..2429a57f076 100644 --- a/scripts/native_simulator/native/src/hw_counter.c +++ b/scripts/native_simulator/native/src/hw_counter.c @@ -17,6 +17,7 @@ static bool counter_running; static uint64_t counter_value; static uint64_t counter_target; static uint64_t counter_period; +static uint64_t counter_wrap; /** * Initialize the counter with prescaler of HW @@ -28,6 +29,7 @@ static void hw_counter_init(void) counter_value = 0; counter_running = false; counter_period = NSI_NEVER; + counter_wrap = NSI_NEVER; } NSI_TASK(hw_counter_init, HW_INIT, 10); @@ -40,7 +42,7 @@ static void hw_counter_triggered(void) } hw_counter_timer = nsi_hws_get_time() + counter_period; - counter_value = counter_value + 1; + counter_value = (counter_value + 1) % counter_wrap; if (counter_value == counter_target) { hw_irq_ctrl_set_irq(COUNTER_EVENT_IRQ); @@ -58,6 +60,16 @@ void hw_counter_set_period(uint64_t period) counter_period = period; } +/* + * Set the count value at which the counter will wrap + * The counter will count up to (counter_wrap-1), i.e.: + * 0, 1, 2,.., (counter_wrap - 1), 0 + */ +void hw_counter_set_wrap_value(uint64_t wrap_value) +{ + counter_wrap = wrap_value; +} + /** * Starts the counter. It must be previously configured with * hw_counter_set_period() and hw_counter_set_target(). @@ -86,6 +98,11 @@ void hw_counter_stop(void) nsi_hws_find_next_event(); } +bool hw_counter_is_started(void) +{ + return counter_running; +} + /** * Returns the current counter value. */ @@ -94,6 +111,14 @@ uint64_t hw_counter_get_value(void) return counter_value; } +/** + * Resets the counter value. + */ +void hw_counter_reset(void) +{ + counter_value = 0; +} + /** * Configures the counter to generate an interrupt * when its count value reaches target. diff --git a/scripts/native_simulator/native/src/include/hw_counter.h b/scripts/native_simulator/native/src/include/hw_counter.h index 766aa8e27c3..9230f930bdf 100644 --- a/scripts/native_simulator/native/src/include/hw_counter.h +++ b/scripts/native_simulator/native/src/include/hw_counter.h @@ -22,9 +22,12 @@ void hw_counter_triggered(void); void hw_counter_set_period(uint64_t period); void hw_counter_set_target(uint64_t counter_target); +void hw_counter_set_wrap_value(uint64_t wrap_value); void hw_counter_start(void); void hw_counter_stop(void); +bool hw_counter_is_started(void); uint64_t hw_counter_get_value(void); +void hw_counter_reset(void); #ifdef __cplusplus } diff --git a/scripts/native_simulator/native/src/irq_ctrl.c b/scripts/native_simulator/native/src/irq_ctrl.c index 40ee28487f0..2c187f77679 100644 --- a/scripts/native_simulator/native/src/irq_ctrl.c +++ b/scripts/native_simulator/native/src/irq_ctrl.c @@ -95,7 +95,7 @@ int hw_irq_ctrl_get_highest_prio_irq(void) int winner_prio = 256; while (irq_status != 0U) { - int irq_nbr = nsi_find_lsb_set(irq_status) - 1; + int irq_nbr = nsi_find_lsb_set64(irq_status) - 1; irq_status &= ~((uint64_t) 1 << irq_nbr); if ((winner_prio > (int)irq_prio[irq_nbr]) From 94e5311215a9a07130620d0f7e8566821f25f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 15:03:56 +0200 Subject: [PATCH 2306/4498] logging: Fix logical operator use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace & with &&. In that case there is no difference in the behavior but logical operator should be used here. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/logging/log_core.h b/include/zephyr/logging/log_core.h index f1ec8345073..58ab5445d81 100644 --- a/include/zephyr/logging/log_core.h +++ b/include/zephyr/logging/log_core.h @@ -290,7 +290,7 @@ static inline char z_log_minimal_level_to_char(int level) break; \ } \ /* For instance logging check instance specific static level */ \ - if (_inst & !IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) { \ + if (_inst && !IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) { \ if (_level > ((struct log_source_const_data *)_source)->level) { \ break; \ } \ From 02deea0e806a40a33eb70edf4b810221c14a0cad Mon Sep 17 00:00:00 2001 From: Jaroslaw Stelter Date: Mon, 2 Jan 2023 15:02:49 +0100 Subject: [PATCH 2307/4498] ace: alh: Only ACE1.5 has OSEL feature The OSEL bits in ALHASCTL register are present only in ACE1.5 version - MTL. Platforms ACE2.0 do not have the OSEL bits. Therefore DAI_ALH_HAS_OWNERSHIP configuration option should be set only for particular ACE1.5 version Signed-off-by: Jaroslaw Stelter --- drivers/dai/intel/alh/Kconfig.alh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dai/intel/alh/Kconfig.alh b/drivers/dai/intel/alh/Kconfig.alh index e2885a29e5d..785074454fb 100644 --- a/drivers/dai/intel/alh/Kconfig.alh +++ b/drivers/dai/intel/alh/Kconfig.alh @@ -16,8 +16,9 @@ config DAI_INTEL_ALH if DAI_INTEL_ALH config DAI_ALH_HAS_OWNERSHIP - bool "Intel ALH driver has ownership" - default y if SOC_SERIES_INTEL_ACE + bool "Intel ALH driver has ownership only on ACE 1.5" + default y + depends on SOC_INTEL_ACE15_MTPM help Select this to enable programming HW ownership From 6a06d2abe6398d8ff6e5896e6a10786f80b3d588 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 20 Oct 2023 10:52:24 +0000 Subject: [PATCH 2308/4498] MAINTAINERS: update "Release Notes" area maintainers Update Release Notes maintainers to point at the 3.6 release owners usernames. Signed-off-by: Fabio Baltieri --- MAINTAINERS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f48ef698be6..58c351f5b8a 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -657,13 +657,13 @@ Documentation Infrastructure: Release Notes: status: maintained maintainers: - - jhedberg - - fabiobaltieri + - MaureenHelm + - henrikbrixandersen + collaborators: + - kartben files: - doc/releases/migration-guide-* - doc/releases/release-notes-* - collaborators: - - kartben labels: - "Release Notes" From 6b60dc4e0d85c6a8459b76282d84b7f6d7533c39 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 20 Oct 2023 15:33:03 +0200 Subject: [PATCH 2309/4498] doc: releases: add working draft release notes + guide for v3.6.0 Add working draft for the release notes and migration guide for v3.6.0. Signed-off-by: Henrik Brix Andersen --- doc/releases/index.rst | 2 +- doc/releases/migration-guide-3.6.rst | 42 ++++ doc/releases/release-notes-3.6.rst | 280 +++++++++++++++++++++++++++ 3 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 doc/releases/migration-guide-3.6.rst create mode 100644 doc/releases/release-notes-3.6.rst diff --git a/doc/releases/index.rst b/doc/releases/index.rst index b9365c64a69..c426aa2ca68 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -77,7 +77,7 @@ Release Notes eol_releases release-notes-2.7 - release-notes-3.[3-5] + release-notes-3.[3-6] Migration Guides **************** diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst new file mode 100644 index 00000000000..6f30589e02f --- /dev/null +++ b/doc/releases/migration-guide-3.6.rst @@ -0,0 +1,42 @@ +:orphan: + +.. _migration_3.6: + +Migration guide to Zephyr v3.6.0 (Working Draft) +################################################ + +This document describes the changes required or recommended when migrating your +application from Zephyr v3.5.0 to Zephyr v3.6.0. + +Any other changes (not directly related to migrating applications) can be found in +the :ref:`release notes`. + +Required changes +**************** + +Kernel +====== + +C Library +========= + +Device Drivers and Device Tree +============================== + +Power Management +================ + +Bootloader +========== + +Bluetooth +========= + +Networking +========== + +Other Subsystems +================ + +Recommended Changes +******************* diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst new file mode 100644 index 00000000000..167dce4b4ac --- /dev/null +++ b/doc/releases/release-notes-3.6.rst @@ -0,0 +1,280 @@ +:orphan: + +.. _zephyr_3.6: + +Zephyr 3.6.0 (Working Draft) +############################ + +We are pleased to announce the release of Zephyr version 3.6.0. + +Major enhancements with this release include: + +An overview of the changes required or recommended when migrating your application from Zephyr +v3.5.0 to Zephyr v3.6.0 can be found in the separate :ref:`migration guide`. + +The following sections provide detailed lists of changes by component. + +Security Vulnerability Related +****************************** +The following CVEs are addressed by this release: + +More detailed information can be found in: +https://docs.zephyrproject.org/latest/security/vulnerabilities.html + +Kernel +****** + +Architectures +************* + +* ARC + +* ARM + +* ARM64 + +* RISC-V + +* Xtensa + +* x86 + +* POSIX + +Bluetooth +********* + +* Audio + +* Direction Finding + +* Host + +* Mesh + +* Controller + +Boards & SoC Support +******************** + +* Added support for these SoC series: + +* Removed support for these SoC series: + +* Made these changes in other SoC series: + +* Added support for these ARC boards: + +* Added support for these ARM boards: + +* Added support for these ARM64 boards: + +* Added support for these RISC-V boards: + +* Added support for these X86 boards: + +* Added support for these Xtensa boards: + +* Added support for these POSIX boards: + +* Made these changes for ARC boards: + +* Made these changes for ARM boards: + +* Made these changes for ARM64 boards: + +* Made these changes for RISC-V boards: + +* Made these changes for X86 boards: + +* Made these changes for Xtensa boards: + +* Made these changes for POSIX boards: + +* Removed support for these ARC boards: + +* Removed support for these ARM boards: + +* Removed support for these ARM64 boards: + +* Removed support for these RISC-V boards: + +* Removed support for these X86 boards: + +* Removed support for these Xtensa boards: + +* Made these changes in other boards: + +* Added support for these following shields: + +Build system and infrastructure +******************************* + +Drivers and Sensors +******************* + +* ADC + +* CAN + +* Clock control + +* Counter + +* DAC + +* Disk + +* Display + +* DMA + +* EEPROM + +* Entropy + +* Ethernet + +* Flash + +* GPIO + +* I2C + +* I2S + +* I3C + +* IEEE 802.15.4 + +* Interrupt Controller + +* Input + +* PCIE + +* ACPI + +* Pin control + +* PWM + +* Regulators + +* Reset + +* Retained memory + +* RTC + +* SDHC + +* Sensor + +* Serial + +* SPI + +* Timer + +* USB + +* WiFi + +Networking +********** + +* CoAP: + +* Connection Manager: + +* DHCP: + +* Ethernet: + +* gPTP: + +* ICMP: + +* IPv6: + +* LwM2M: + +* Misc: + +* MQTT-SN: + +* OpenThread: + +* PPP: + +* Sockets: + +* TCP: + +* TFTP: + +* WebSocket + +* Wi-Fi: + + +USB +*** + +Devicetree +********** + +API +=== + +Bindings +======== + +Libraries / Subsystems +********************** + +* Management + +* File systems + +* Modem modules + +* Power management + +* Random + +* Retention + +* Binary descriptors + +* POSIX API + +* LoRa/LoRaWAN + +* CAN ISO-TP + +* RTIO + +* ZBus + +HALs +**** + +MCUboot +******* + +Nanopb +****** + +LVGL +**** + +Trusted Firmware-A +****************** + +Documentation +************* + +Tests and Samples +***************** From 0f5c6b7d743b8cc4a26f7766cc3c7142b705f402 Mon Sep 17 00:00:00 2001 From: David Corbeil Date: Tue, 3 Oct 2023 12:51:20 -0400 Subject: [PATCH 2310/4498] drivers: flash: Fix union shadowing warning Because shadow variable warning is turned on, a warning was thrown and could fail some twister tests that don't use the -W option. This commit gets rid of the warning. Signed-off-by: David Corbeil --- drivers/flash/spi_nor.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 88d9725168e..631ee6a15ab 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -1029,10 +1029,10 @@ static int spi_nor_process_sfdp(const struct device *dev) /* We only process BFP so use one parameter block */ uint8_t raw[JESD216_SFDP_SIZE(decl_nph)]; struct jesd216_sfdp_header sfdp; - } u; - const struct jesd216_sfdp_header *hp = &u.sfdp; + } u_header; + const struct jesd216_sfdp_header *hp = &u_header.sfdp; - rc = spi_nor_sfdp_read(dev, 0, u.raw, sizeof(u.raw)); + rc = spi_nor_sfdp_read(dev, 0, u_header.raw, sizeof(u_header.raw)); if (rc != 0) { LOG_ERR("SFDP read failed: %d", rc); return rc; @@ -1062,10 +1062,11 @@ static int spi_nor_process_sfdp(const struct device *dev) union { uint32_t dw[MIN(php->len_dw, 20)]; struct jesd216_bfp bfp; - } u; - const struct jesd216_bfp *bfp = &u.bfp; + } u_param; + const struct jesd216_bfp *bfp = &u_param.bfp; - rc = spi_nor_sfdp_read(dev, jesd216_param_addr(php), u.dw, sizeof(u.dw)); + rc = spi_nor_sfdp_read(dev, jesd216_param_addr(php), + u_param.dw, sizeof(u_param.dw)); if (rc == 0) { rc = spi_nor_process_bfp(dev, php, bfp); } From a4e9aed68de223968e43f4ea4fa1abdda5b49c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Mon, 16 Oct 2023 12:46:29 +0200 Subject: [PATCH 2311/4498] tfm: Enable TFM_EXCEPTION_INFO_DUMP by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exception info dump is a very basic feature so it should IMHO be enabled by default. For instance, a simple null-pointer exception in the non-secure app will not be logged unless this option is enabled. Signed-off-by: Sebastian Bøe --- modules/trusted-firmware-m/Kconfig.tfm | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index a7276d79374..a9980819589 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -431,6 +431,7 @@ endchoice config TFM_EXCEPTION_INFO_DUMP bool "TF-M exception info dump" + default y help On fatal errors in the secure firmware, capture info about the exception. Print the info if the SPM log level is sufficient. From e1137a3e5e7c08531065485519fced3f02c73e47 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 11 Oct 2023 13:18:19 +0200 Subject: [PATCH 2312/4498] cmake: modules: dts: use devicetree stub file By providing a devicetree stub file, we make sure some internal macros required by devicetree.h are generated in devicetree_generated.h. This makes sure that systems without devicetree can continue working without extra ifdeffery. Signed-off-by: Gerard Marull-Paretas --- boards/common/stub.dts | 14 ++++++++++++++ cmake/modules/dts.cmake | 10 ++-------- misc/generated/generated_header.template | 1 - 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 boards/common/stub.dts delete mode 100644 misc/generated/generated_header.template diff --git a/boards/common/stub.dts b/boards/common/stub.dts new file mode 100644 index 00000000000..ebb8b852a92 --- /dev/null +++ b/boards/common/stub.dts @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/* empty stub file provided for systems not using devicetree */ + +/dts-v1/; + +#include + +/ { + +}; diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index 8236195ff85..8cdd94cd574 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -125,10 +125,6 @@ set(DTS_CMAKE ${PROJECT_BINARY_DIR}/dts.cmake) # modules. set(VENDOR_PREFIXES dts/bindings/vendor-prefixes.txt) -# -# Halt execution early if there is no devicetree. -# - # TODO: What to do about non-posix platforms where NOT CONFIG_HAS_DTS (xtensa)? # Drop support for NOT CONFIG_HAS_DTS perhaps? set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) @@ -138,10 +134,8 @@ if(EXISTS ${DTS_SOURCE}) list(APPEND DTS_SOURCE ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.overlay) endif() else() - # If we don't have a devicetree after all, there's not much to do. - set(header_template ${ZEPHYR_BASE}/misc/generated/generated_header.template) - zephyr_file_copy(${header_template} ${DEVICETREE_GENERATED_H} ONLY_IF_DIFFERENT) - return() + # If we don't have a devicetree, provide an empty stub + set(DTS_SOURCE ${ZEPHYR_BASE}/boards/common/stub.dts) endif() # diff --git a/misc/generated/generated_header.template b/misc/generated/generated_header.template deleted file mode 100644 index 2b323cd20e1..00000000000 --- a/misc/generated/generated_header.template +++ /dev/null @@ -1 +0,0 @@ -/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */ From 915cb05bb6e661cbb5f84ffd518726d5e04e911e Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 9 Oct 2023 13:08:40 +0200 Subject: [PATCH 2313/4498] dts: drop HAS_DTS HAS_DTS has become a redundant option. All Zephyr architectures now select this option, meaning devicetree has become a de-facto requirement. In fact, if any board does not provide a devicetree source, the build system uses an empty stub, meaning the devicetree machinery always runs. Signed-off-by: Gerard Marull-Paretas --- arch/Kconfig | 10 ---------- cmake/modules/dts.cmake | 5 ----- dts/Kconfig | 6 ------ include/zephyr/device.h | 2 -- include/zephyr/drivers/emul.h | 2 -- include/zephyr/drivers/sensor.h | 3 --- subsys/shell/backends/Kconfig.backends | 3 +-- 7 files changed, 1 insertion(+), 30 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 110938528ed..65b73557f7b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -19,7 +19,6 @@ source "$(ARCH_DIR)/$(ARCH)/Kconfig" config ARC bool select ARCH_IS_SET - select HAS_DTS imply XIP select ARCH_HAS_THREAD_LOCAL_STORAGE select ARCH_SUPPORTS_ROM_START @@ -30,7 +29,6 @@ config ARM bool select ARCH_IS_SET select ARCH_SUPPORTS_COREDUMP if CPU_CORTEX_M - select HAS_DTS # FIXME: current state of the code for all ARM requires this, but # is really only necessary for Cortex-M with ARM MPU! select GEN_PRIV_STACKS @@ -43,7 +41,6 @@ config ARM64 bool select ARCH_IS_SET select 64BIT - select HAS_DTS select ARCH_SUPPORTS_COREDUMP select HAS_ARM_SMCCC select ARCH_HAS_THREAD_LOCAL_STORAGE @@ -58,14 +55,12 @@ config MIPS bool select ARCH_IS_SET select ATOMIC_OPERATIONS_C - select HAS_DTS help MIPS architecture config SPARC bool select ARCH_IS_SET - select HAS_DTS select USE_SWITCH select USE_SWITCH_SUPPORTED select BIG_ENDIAN @@ -80,7 +75,6 @@ config X86 bool select ARCH_IS_SET select ATOMIC_OPERATIONS_BUILTIN - select HAS_DTS select ARCH_SUPPORTS_COREDUMP select ARCH_SUPPORTS_ROM_START if !X86_64 select CPU_HAS_MMU @@ -102,7 +96,6 @@ config NIOS2 bool select ARCH_IS_SET select ATOMIC_OPERATIONS_C - select HAS_DTS imply XIP select ARCH_HAS_TIMING_FUNCTIONS help @@ -111,7 +104,6 @@ config NIOS2 config RISCV bool select ARCH_IS_SET - select HAS_DTS select ARCH_SUPPORTS_COREDUMP select ARCH_SUPPORTS_ROM_START if !SOC_SERIES_ESP32C3 select ARCH_HAS_CODE_DATA_RELOCATION @@ -128,7 +120,6 @@ config RISCV config XTENSA bool select ARCH_IS_SET - select HAS_DTS select USE_SWITCH select USE_SWITCH_SUPPORTED select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD @@ -141,7 +132,6 @@ config XTENSA config ARCH_POSIX bool select ARCH_IS_SET - select HAS_DTS select ATOMIC_OPERATIONS_BUILTIN select ARCH_HAS_CUSTOM_SWAP_TO_MAIN select ARCH_HAS_CUSTOM_BUSY_WAIT diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index 8cdd94cd574..c9ac751a1e5 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -9,9 +9,6 @@ include(pre_dt) find_package(HostTools) find_package(Dtc 1.4.6) -# Zephyr code is usually configured using devicetree, but this is -# still technically optional (see e.g. CONFIG_HAS_DTS). -# # This module makes information from the devicetree available to # various build stages, as well as to other arbitrary Python scripts: # @@ -125,8 +122,6 @@ set(DTS_CMAKE ${PROJECT_BINARY_DIR}/dts.cmake) # modules. set(VENDOR_PREFIXES dts/bindings/vendor-prefixes.txt) -# TODO: What to do about non-posix platforms where NOT CONFIG_HAS_DTS (xtensa)? -# Drop support for NOT CONFIG_HAS_DTS perhaps? set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) if(EXISTS ${DTS_SOURCE}) # We found a devicetree. Check for a board revision overlay. diff --git a/dts/Kconfig b/dts/Kconfig index 46d1b85b6ec..0e71bd525c0 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -1,11 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -config HAS_DTS - bool - help - This option specifies that the target platform supports device tree - configuration. - menu "Devicetree Info" osource "$(KCONFIG_BINARY_DIR)/Kconfig.dts" diff --git a/include/zephyr/device.h b/include/zephyr/device.h index ca595795000..630a059c155 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -1005,7 +1005,6 @@ static inline bool z_impl_device_is_ready(const struct device *dev) \ Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, level, prio) -#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) /** * @brief Declare a device for each status "okay" devicetree node. * @@ -1020,7 +1019,6 @@ static inline bool z_impl_device_is_ready(const struct device *dev) extern const struct device DEVICE_DT_NAME_GET(node_id); DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL) -#endif /* CONFIG_HAS_DTS */ /** @endcond */ diff --git a/include/zephyr/drivers/emul.h b/include/zephyr/drivers/emul.h index 9ef6fb9ada5..7c306de9889 100644 --- a/include/zephyr/drivers/emul.h +++ b/include/zephyr/drivers/emul.h @@ -191,11 +191,9 @@ const struct emul *emul_get_binding(const char *name); * @} */ -#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) #define Z_MAYBE_EMUL_DECLARE_INTERNAL(node_id) extern const struct emul EMUL_DT_NAME_GET(node_id); DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_EMUL_DECLARE_INTERNAL); -#endif /* CONFIG_HAS_DTS || __DOXYGEN__ */ #ifdef __cplusplus } diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 903acb6f03a..bbc85fda86d 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -1260,8 +1260,6 @@ static inline int64_t sensor_value_to_micro(const struct sensor_value *val) * @} */ -#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) - /** * @brief Get the decoder name for the current driver * @@ -1309,7 +1307,6 @@ static inline int64_t sensor_value_to_micro(const struct sensor_value *val) ()) DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL) -#endif /* defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) */ #ifdef __cplusplus } diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index 9bab0be275d..44d27a812b5 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -18,8 +18,7 @@ config SHELL_BACKEND_SERIAL bool "Serial backend" # Serial (UART) requires interrupts and the RTT backend cannot be used from an ISR context. default n if SHELL_BACKEND_RTT - default "$(dt_chosen_enabled,$(DT_CHOSEN_Z_SHELL_UART))" if HAS_DTS - default y if !HAS_DTS + default "$(dt_chosen_enabled,$(DT_CHOSEN_Z_SHELL_UART))" select SERIAL select RING_BUFFER help From 97ac96f56df5aae7b957080cee867338c421c2fb Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 20:52:04 +0200 Subject: [PATCH 2314/4498] bsim tests: Fix incorrect libC free call from bstests The bstests code builds and executes with the embedded code, but had a call into "free()" which, when building the embedded code with an embedded C library lands in the embedded libC free, while it should always call into the host libC free. Fix it by calling thru the appropriate trampoline. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/common/bstests_entry.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/posix/nrf_bsim/common/bstests_entry.c b/boards/posix/nrf_bsim/common/bstests_entry.c index 3e771195478..c1f08deb9cd 100644 --- a/boards/posix/nrf_bsim/common/bstests_entry.c +++ b/boards/posix/nrf_bsim/common/bstests_entry.c @@ -10,6 +10,7 @@ #include "bs_tracing.h" #include "bstests.h" #include "bs_oswrap.h" +#include "nsi_host_trampolines.h" /* * Result of the testcase execution. @@ -230,7 +231,7 @@ uint8_t bst_delete(void) while (test_list_top) { struct bst_test_list *tmp = test_list_top->next; - free(test_list_top); + nsi_host_free(test_list_top); test_list_top = tmp; } From 18d6919092bb09e637b3fdf2ae636ba5554cdc06 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 21:13:24 +0200 Subject: [PATCH 2315/4498] tests bsim: Disable bap_broadcast_audio_assistant The test is currently broken in main and blocking all other development when triggered. Let's disable it by now as a provisional measure. Signed-off-by: Alberto Escolar Piedras --- ...dcast_audio_assistant.sh => _bap_broadcast_audio_assistant.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/bsim/bluetooth/audio/test_scripts/{bap_broadcast_audio_assistant.sh => _bap_broadcast_audio_assistant.sh} (100%) diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh b/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh similarity index 100% rename from tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh rename to tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh From f5ed51c17956e572cb16862a2d783011c8bd1367 Mon Sep 17 00:00:00 2001 From: Karthikeyan Krishnasamy Date: Sat, 19 Aug 2023 12:59:26 +0530 Subject: [PATCH 2316/4498] drivers: sensors: add MC3419 accel sensor support add basic sensor support for 3-axis accelerometer, currently this driver support data acquisition and motion detection features. Signed-off-by: Karthikeyan Krishnasamy --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/mc3419/CMakeLists.txt | 8 + drivers/sensor/mc3419/Kconfig | 48 ++++ drivers/sensor/mc3419/mc3419.c | 314 +++++++++++++++++++++++++ drivers/sensor/mc3419/mc3419.h | 102 ++++++++ drivers/sensor/mc3419/mc3419_trigger.c | 178 ++++++++++++++ dts/bindings/sensor/memsic,mc3419.yaml | 23 ++ 8 files changed, 675 insertions(+) create mode 100644 drivers/sensor/mc3419/CMakeLists.txt create mode 100644 drivers/sensor/mc3419/Kconfig create mode 100644 drivers/sensor/mc3419/mc3419.c create mode 100644 drivers/sensor/mc3419/mc3419.h create mode 100644 drivers/sensor/mc3419/mc3419_trigger.c create mode 100644 dts/bindings/sensor/memsic,mc3419.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 7506b62a37f..f6a57278943 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -89,6 +89,7 @@ add_subdirectory_ifdef(CONFIG_MAX31865 max31865) add_subdirectory_ifdef(CONFIG_MAX31875 max31875) add_subdirectory_ifdef(CONFIG_MAX44009 max44009) add_subdirectory_ifdef(CONFIG_MAX6675 max6675) +add_subdirectory_ifdef(CONFIG_MC3419 mc3419) add_subdirectory_ifdef(CONFIG_MCP9600 mcp9600) add_subdirectory_ifdef(CONFIG_MCP970X mcp970x) add_subdirectory_ifdef(CONFIG_MCP9808 mcp9808) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index fae18d967ea..2180d801df5 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -145,6 +145,7 @@ source "drivers/sensor/max31865/Kconfig" source "drivers/sensor/max31875/Kconfig" source "drivers/sensor/max44009/Kconfig" source "drivers/sensor/max6675/Kconfig" +source "drivers/sensor/mc3419/Kconfig" source "drivers/sensor/mchp_tach_xec/Kconfig" source "drivers/sensor/mcp9600/Kconfig" source "drivers/sensor/mcp970x/Kconfig" diff --git a/drivers/sensor/mc3419/CMakeLists.txt b/drivers/sensor/mc3419/CMakeLists.txt new file mode 100644 index 00000000000..650f3e9777e --- /dev/null +++ b/drivers/sensor/mc3419/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Linumiz + +zephyr_library() + +zephyr_library_sources(mc3419.c) +zephyr_library_sources_ifdef(CONFIG_MC3419_TRIGGER mc3419_trigger.c) diff --git a/drivers/sensor/mc3419/Kconfig b/drivers/sensor/mc3419/Kconfig new file mode 100644 index 00000000000..81e0665c3e0 --- /dev/null +++ b/drivers/sensor/mc3419/Kconfig @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023 Linumiz + +menuconfig MC3419 + bool "MC3419 acclerometer driver" + default y + depends on DT_HAS_MEMSIC_MC3419_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_MEMSIC_MC3419),i2c) + help + Enable driver for MC3419 acclerometer. + +if MC3419 + +config MC3419_TRIGGER + bool "Trigger mode" + +if MC3419_TRIGGER + +config MC3419_TRIGGER_OWN_THREAD + bool "Use own thread" + help + Enable trigger to run in own thread. By + default it is global thread mode. + +config MC3419_THREAD_PRIORITY + int "Own thread priority" + depends on MC3419_TRIGGER_OWN_THREAD + default 10 + +config MC3419_THREAD_STACK_SIZE + int "Own thread stask size" + depends on MC3419_TRIGGER_OWN_THREAD + default 1024 + +endif # MC3419_TRIGGER + +config MC3419_DECIMATION_RATE + int "Enable decimation rate" + range 0 15 + default 15 + help + This helps in producing slower interrupt. Internal Data + Rate is divide by this decimation rate. If decimation rate + is 0 then internal data rate is equal to output data rate, + then it produce interrupt floods. + +endif # MC3419 diff --git a/drivers/sensor/mc3419/mc3419.c b/drivers/sensor/mc3419/mc3419.c new file mode 100644 index 00000000000..41f69fd3646 --- /dev/null +++ b/drivers/sensor/mc3419/mc3419.c @@ -0,0 +1,314 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Linumiz + */ + +#define DT_DRV_COMPAT memsic_mc3419 + +#include +#include +#include +#include +#include +#include "mc3419.h" + +LOG_MODULE_REGISTER(MC3419, CONFIG_SENSOR_LOG_LEVEL); + +static const uint16_t mc3419_accel_sense_map[] = {1, 2, 4, 8, 6}; +static struct mc3419_odr_map odr_map_table[] = { + {25}, {50}, {62, 500}, {100}, + {125}, {250}, {500}, {1000} +}; + +static int mc3419_get_odr_value(uint16_t freq, uint16_t m_freq) +{ + for (int i = 0; i < ARRAY_SIZE(odr_map_table); i++) { + if (odr_map_table[i].freq == freq && + odr_map_table[i].mfreq == m_freq) { + return i; + } + } + + return -EINVAL; +} + +static inline int mc3419_set_op_mode(const struct mc3419_config *cfg, + enum mc3419_op_mode mode) +{ + return i2c_reg_write_byte_dt(&cfg->i2c, MC3419_REG_OP_MODE, mode); +} + +static int mc3419_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + int ret = 0; + const struct mc3419_config *cfg = dev->config; + struct mc3419_driver_data *data = dev->data; + + k_sem_take(&data->sem, K_FOREVER); + ret = i2c_burst_read_dt(&cfg->i2c, MC3419_REG_XOUT_L, + (uint8_t *)data->samples, + MC3419_SAMPLE_READ_SIZE); + k_sem_give(&data->sem); + return ret; +} + +static int mc3419_to_sensor_value(double sensitivity, int16_t *raw_data, + struct sensor_value *val) +{ + double value = sys_le16_to_cpu(*raw_data); + + value *= sensitivity * SENSOR_GRAVITY_DOUBLE / 1000; + + return sensor_value_from_double(val, value); +} + +static int mc3419_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + int ret = 0; + struct mc3419_driver_data *data = dev->data; + + k_sem_take(&data->sem, K_FOREVER); + switch (chan) { + case SENSOR_CHAN_ACCEL_X: + ret = mc3419_to_sensor_value(data->sensitivity, &data->samples[0], val); + break; + case SENSOR_CHAN_ACCEL_Y: + ret = mc3419_to_sensor_value(data->sensitivity, &data->samples[1], val); + break; + case SENSOR_CHAN_ACCEL_Z: + ret = mc3419_to_sensor_value(data->sensitivity, &data->samples[2], val); + break; + case SENSOR_CHAN_ACCEL_XYZ: + ret = mc3419_to_sensor_value(data->sensitivity, &data->samples[0], &val[0]); + ret |= mc3419_to_sensor_value(data->sensitivity, &data->samples[1], &val[1]); + ret |= mc3419_to_sensor_value(data->sensitivity, &data->samples[2], &val[2]); + break; + default: + LOG_ERR("Unsupported channel"); + ret = -ENOTSUP; + } + + k_sem_give(&data->sem); + return ret; +} + +static int mc3419_set_accel_range(const struct device *dev, uint8_t range) +{ + int ret = 0; + const struct mc3419_config *cfg = dev->config; + struct mc3419_driver_data *data = dev->data; + + if (range >= MC3419_ACCL_RANGE_END) { + LOG_ERR("Accel resolution is out of range"); + return -EINVAL; + } + + ret = i2c_reg_update_byte_dt(&cfg->i2c, MC3419_REG_RANGE_SELECT_CTRL, + MC3419_RANGE_MASK, range << 4); + if (ret < 0) { + LOG_ERR("Failed to set resolution (%d)", ret); + return ret; + } + + data->sensitivity = (double)(mc3419_accel_sense_map[range] * + SENSOR_GRAIN_VALUE); + + return 0; +} + +static int mc3419_set_odr(const struct device *dev, + const struct sensor_value *val) +{ + int ret = 0; + int data_rate = 0; + const struct mc3419_config *cfg = dev->config; + + ret = mc3419_get_odr_value(val->val1, val->val2); + if (ret < 0) { + LOG_ERR("Failed to get odr value from odr map (%d)", ret); + return ret; + } + + data_rate = MC3419_BASE_ODR_VAL + ret; + + ret = i2c_reg_write_byte_dt(&cfg->i2c, MC3419_REG_SAMPLE_RATE, + data_rate); + if (ret < 0) { + LOG_ERR("Failed to set ODR (%d)", ret); + return ret; + } + + LOG_DBG("Set ODR Rate to 0x%x", data_rate); + ret = i2c_reg_write_byte_dt(&cfg->i2c, MC3419_REG_SAMPLE_RATE_2, + CONFIG_MC3419_DECIMATION_RATE); + if (ret < 0) { + LOG_ERR("Failed to set decimation rate (%d)", ret); + return ret; + } + + return 0; +} + +#if defined(CONFIG_MC3419_TRIGGER) +static int mc3419_set_anymotion_threshold(const struct device *dev, + const struct sensor_value *val) +{ + int ret = 0; + const struct mc3419_config *cfg = dev->config; + uint8_t buf[3] = {0}; + + if (val->val1 > MC3419_ANY_MOTION_THRESH_MAX) { + return -EINVAL; + } + + buf[0] = MC3419_REG_ANY_MOTION_THRES; + sys_put_le16((uint16_t)val->val1, &buf[1]); + + ret = i2c_write_dt(&cfg->i2c, buf, sizeof(buf)); + if (ret < 0) { + LOG_ERR("Failed to set anymotion threshold (%d)", ret); + return ret; + } + + return 0; +} + +static int mc3419_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + int ret = 0; + const struct mc3419_config *cfg = dev->config; + struct mc3419_driver_data *data = dev->data; + + k_sem_take(&data->sem, K_FOREVER); + ret = mc3419_set_op_mode(cfg, MC3419_MODE_STANDBY); + if (ret < 0) { + goto exit; + } + + ret = mc3419_configure_trigger(dev, trig, handler); + if (ret < 0) { + LOG_ERR("Failed to set trigger (%d)", ret); + } + +exit: + mc3419_set_op_mode(cfg, MC3419_MODE_WAKE); + + k_sem_give(&data->sem); + return ret; +} +#endif + +static int mc3419_attr_set(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + int ret = 0; + struct mc3419_driver_data *data = dev->data; + + if (chan != SENSOR_CHAN_ACCEL_X && + chan != SENSOR_CHAN_ACCEL_Y && + chan != SENSOR_CHAN_ACCEL_Z && + chan != SENSOR_CHAN_ACCEL_XYZ) { + LOG_ERR("Not supported on this channel."); + return -ENOTSUP; + } + + k_sem_take(&data->sem, K_FOREVER); + ret = mc3419_set_op_mode(dev->config, MC3419_MODE_STANDBY); + if (ret < 0) { + goto exit; + } + + switch (attr) { + case SENSOR_ATTR_FULL_SCALE: + ret = mc3419_set_accel_range(dev, val->val1); + break; + case SENSOR_ATTR_SAMPLING_FREQUENCY: + ret = mc3419_set_odr(dev, val); + break; +#if defined(CONFIG_MC3419_TRIGGER) + case SENSOR_ATTR_SLOPE_TH: + ret = mc3419_set_anymotion_threshold(dev, val); + break; +#endif + default: + LOG_ERR("ACCEL attribute is not supported"); + ret = -EINVAL; + } + +exit: + mc3419_set_op_mode(dev->config, MC3419_MODE_WAKE); + + k_sem_give(&data->sem); + return ret; +} + +static int mc3419_init(const struct device *dev) +{ + int ret = 0; + struct mc3419_driver_data *data = dev->data; + const struct mc3419_config *cfg = dev->config; + + if (!(i2c_is_ready_dt(&cfg->i2c))) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + k_sem_init(&data->sem, 1, 1); + +#if defined(CONFIG_MC3419_TRIGGER) + ret = mc3419_trigger_init(dev); + if (ret < 0) { + LOG_ERR("Could not initialize interrupts"); + return ret; + } +#endif + + /* Leave the sensor in default power on state, will be + * enabled by configure attr or setting trigger. + */ + + LOG_INF("MC3419 Initialized"); + + return ret; +} + +static const struct sensor_driver_api mc3419_api = { + .attr_set = mc3419_attr_set, +#if defined(CONFIG_MC3419_TRIGGER) + .trigger_set = mc3419_trigger_set, +#endif + .sample_fetch = mc3419_sample_fetch, + .channel_get = mc3419_channel_get, +}; + +#if defined(CONFIG_MC3419_TRIGGER) +#define MC3419_CFG_IRQ(idx) \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(idx, int_gpios, { 0 }), \ + .int_cfg = DT_INST_PROP(idx, int_pin2), +#else +#define MC3419_CFG_IRQ(idx) +#endif + +#define MC3419_DEFINE(idx) \ + static const struct mc3419_config mc3419_config_##idx = { \ + .i2c = I2C_DT_SPEC_INST_GET(idx), \ + MC3419_CFG_IRQ(idx) \ + }; \ + static struct mc3419_driver_data mc3419_data_##idx; \ + SENSOR_DEVICE_DT_INST_DEFINE(idx, \ + mc3419_init, NULL, \ + &mc3419_data_##idx, \ + &mc3419_config_##idx, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &mc3419_api); + +DT_INST_FOREACH_STATUS_OKAY(MC3419_DEFINE) diff --git a/drivers/sensor/mc3419/mc3419.h b/drivers/sensor/mc3419/mc3419.h new file mode 100644 index 00000000000..6085c60bc48 --- /dev/null +++ b/drivers/sensor/mc3419/mc3419.h @@ -0,0 +1,102 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Linumiz + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_MC3419_H_ +#define ZEPHYR_DRIVERS_SENSOR_MC3419_H_ + +#include +#include +#include +#include +#include + +/* Registers */ +#define MC3419_REG_INT_CTRL 0x06 +#define MC3419_REG_OP_MODE 0x07 +#define MC3419_REG_SAMPLE_RATE 0x08 +#define MC3419_REG_MOTION_CTRL 0x09 +#define MC3419_REG_XOUT_L 0x0D +#define MC3419_REG_YOUT_L 0x0F +#define MC3419_REG_ZOUT_L 0x11 +#define MC3419_REG_STATUS 0x13 +#define MC3419_REG_INT_STATUS 0x14 +#define MC3419_REG_RANGE_SELECT_CTRL 0x20 +#define MC3419_REG_SAMPLE_RATE_2 0x30 +#define MC3419_REG_COMM_CTRL 0x31 +#define MC3419_REG_ANY_MOTION_THRES 0x43 + +#define MC3419_RANGE_MASK GENMASK(6, 4) +#define MC3419_DATA_READY_MASK BIT(7) +#define MC3419_ANY_MOTION_MASK BIT(2) +#define MC3419_INT_CLEAR 0x00 +#define MC3419_INT_ROUTE 0x10 + +#define MC3419_ANY_MOTION_THRESH_MAX 0x7FFF +#define MC3419_SAMPLE_SIZE 3 +#define MC3419_SAMPLE_READ_SIZE (MC3419_SAMPLE_SIZE * (sizeof(int16_t))) + +#define SENSOR_GRAIN_VALUE (61LL / 1000.0) +#define SENSOR_GRAVITY_DOUBLE (SENSOR_G / 1000000.0) +#define MC3419_BASE_ODR_VAL 0x10 + +#define MC3419_TRIG_DATA_READY 0 +#define MC3419_TRIG_ANY_MOTION 1 +#define MC3419_TRIG_SIZE 2 + +enum mc3419_op_mode { + MC3419_MODE_STANDBY = 0x00, + MC3419_MODE_WAKE = 0x01 +}; + +struct mc3419_odr_map { + int16_t freq; + int16_t mfreq; +}; + +enum mc3419_accl_range { + MC3419_ACCl_RANGE_2G, + MC3419_ACCl_RANGE_4G, + MC3419_ACCl_RANGE_8G, + MC3419_ACCl_RANGE_16G, + MC3419_ACCl_RANGE_12G, + MC3419_ACCL_RANGE_END +}; + +struct mc3419_config { + struct i2c_dt_spec i2c; +#if defined(CONFIG_MC3419_TRIGGER) + struct gpio_dt_spec int_gpio; + bool int_cfg; +#endif +}; + +struct mc3419_driver_data { + double sensitivity; + struct k_sem sem; + int16_t samples[MC3419_SAMPLE_SIZE]; +#if defined(CONFIG_MC3419_TRIGGER) + const struct device *gpio_dev; + struct gpio_callback gpio_cb; + sensor_trigger_handler_t handler[MC3419_TRIG_SIZE]; + const struct sensor_trigger *trigger[MC3419_TRIG_SIZE]; +#if defined(CONFIG_MC3419_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_MC3419_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem trig_sem; +#else + struct k_work work; +#endif +#endif +}; + +#if defined(CONFIG_MC3419_TRIGGER) +int mc3419_trigger_init(const struct device *dev); +int mc3419_configure_trigger(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); +#endif + +#endif diff --git a/drivers/sensor/mc3419/mc3419_trigger.c b/drivers/sensor/mc3419/mc3419_trigger.c new file mode 100644 index 00000000000..ab44fe79d24 --- /dev/null +++ b/drivers/sensor/mc3419/mc3419_trigger.c @@ -0,0 +1,178 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Linumiz + */ + +#include "mc3419.h" +#include + +LOG_MODULE_DECLARE(MC3419, CONFIG_SENSOR_LOG_LEVEL); + +static void mc3419_gpio_callback(const struct device *dev, + struct gpio_callback *cb, + uint32_t pin_mask) +{ + struct mc3419_driver_data *data = CONTAINER_OF(cb, + struct mc3419_driver_data, gpio_cb); + + const struct mc3419_config *cfg = data->gpio_dev->config; + + if ((pin_mask & BIT(cfg->int_gpio.pin)) == 0U) { + return; + } + +#if defined(CONFIG_MC3419_TRIGGER_OWN_THREAD) + k_sem_give(&data->trig_sem); +#else + k_work_submit(&data->work); +#endif +} + +static void mc3419_process_int(const struct device *dev) +{ + int ret = 0; + const struct mc3419_config *cfg = dev->config; + const struct mc3419_driver_data *data = dev->data; + uint8_t int_source = 0; + + ret = i2c_reg_read_byte_dt(&cfg->i2c, MC3419_REG_INT_STATUS, &int_source); + if (ret < 0) { + goto exit; + } + + if (int_source & MC3419_DATA_READY_MASK) { + if (data->handler[MC3419_TRIG_DATA_READY]) { + data->handler[MC3419_TRIG_DATA_READY](dev, + data->trigger[MC3419_TRIG_DATA_READY]); + } + } + + if (int_source & MC3419_ANY_MOTION_MASK) { + if (data->handler[MC3419_TRIG_ANY_MOTION]) { + data->handler[MC3419_TRIG_ANY_MOTION](dev, + data->trigger[MC3419_TRIG_ANY_MOTION]); + } + } +exit: + ret = i2c_reg_write_byte_dt(&cfg->i2c, MC3419_REG_INT_STATUS, + MC3419_INT_CLEAR); + if (ret < 0) { + LOG_ERR("Failed to clear interrupt (%d)", ret); + } +} + +#if defined(CONFIG_MC3419_TRIGGER_OWN_THREAD) +static void mc3419_thread(struct mc3419_driver_data *data) +{ + while (1) { + k_sem_take(&data->trig_sem, K_FOREVER); + mc3419_process_int(data->gpio_dev); + } +} +#else +static void mc3419_work_cb(struct k_work *work) +{ + struct mc3419_driver_data *data = CONTAINER_OF(work, + struct mc3419_driver_data, work); + + mc3419_process_int(data->gpio_dev); +} +#endif + +int mc3419_configure_trigger(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + int ret = 0; + uint8_t buf = 0; + const struct mc3419_config *cfg = dev->config; + struct mc3419_driver_data *data = dev->data; + + if (!(trig->type & SENSOR_TRIG_DATA_READY) && + !(trig->type & SENSOR_TRIG_MOTION)) { + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + if (trig->type & SENSOR_TRIG_DATA_READY) { + data->handler[MC3419_TRIG_DATA_READY] = handler; + data->trigger[MC3419_TRIG_DATA_READY] = trig; + buf |= MC3419_DATA_READY_MASK; + } + + if (trig->type & SENSOR_TRIG_MOTION) { + uint8_t int_mask = MC3419_ANY_MOTION_MASK; + + buf |= MC3419_ANY_MOTION_MASK; + data->handler[MC3419_TRIG_ANY_MOTION] = handler; + data->trigger[MC3419_TRIG_ANY_MOTION] = trig; + + ret = i2c_reg_update_byte_dt(&cfg->i2c, MC3419_REG_MOTION_CTRL, + int_mask, handler ? int_mask : 0); + if (ret < 0) { + LOG_ERR("Failed to configure motion interrupt (%d)", ret); + return ret; + } + } + + ret = i2c_reg_update_byte_dt(&cfg->i2c, MC3419_REG_INT_CTRL, + buf, buf); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt (%d)", ret); + return ret; + } + + gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_EDGE_FALLING); + + return ret; +} + +int mc3419_trigger_init(const struct device *dev) +{ + int ret = 0; + struct mc3419_driver_data *data = dev->data; + const struct mc3419_config *cfg = dev->config; + + if (!gpio_is_ready_dt(&cfg->int_gpio)) { + LOG_ERR("GPIO port %s not ready", cfg->int_gpio.port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt gpio"); + return ret; + } + + data->gpio_dev = dev; + +#if defined(CONFIG_MC3419_TRIGGER_OWN_THREAD) + k_sem_init(&data->trig_sem, 0, 1); + k_thread_create(&data->thread, data->thread_stack, + CONFIG_MC3419_THREAD_STACK_SIZE, + (k_thread_entry_t)mc3419_thread, data, NULL, + NULL, K_PRIO_COOP(CONFIG_MC3419_THREAD_PRIORITY), 0, + K_NO_WAIT); +#else + k_work_init(&data->work, mc3419_work_cb); +#endif + gpio_init_callback(&data->gpio_cb, mc3419_gpio_callback, + BIT(cfg->int_gpio.pin)); + ret = gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb); + if (ret < 0) { + LOG_ERR("Failed to set int callback"); + return ret; + } + + if (cfg->int_cfg) { + ret = i2c_reg_write_byte_dt(&cfg->i2c, MC3419_REG_COMM_CTRL, + MC3419_INT_ROUTE); + if (ret < 0) { + LOG_ERR("Failed to route the interrupt to INT2 pin (%d)", ret); + return ret; + } + } + + return 0; +} diff --git a/dts/bindings/sensor/memsic,mc3419.yaml b/dts/bindings/sensor/memsic,mc3419.yaml new file mode 100644 index 00000000000..accb86b667b --- /dev/null +++ b/dts/bindings/sensor/memsic,mc3419.yaml @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Linumiz + +description: MC3419 3-axis accel sensor + +compatible: "memsic,mc3419" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + This property specifies the connection for INT, this pin + defaults to active low when sample produce interrupt. + + int-pin2: + type: boolean + description: | + This property is used for interrupt routing.The sensor + has two interrupt pins.By default the interrupt are routed + to interrupt pin 1, by enabled this property interrupt are + routed to interrupt pin 2. From a4ad4311b269c9e470794e3452853fa779e23490 Mon Sep 17 00:00:00 2001 From: Karthikeyan Krishnasamy Date: Tue, 29 Aug 2023 18:12:40 +0530 Subject: [PATCH 2317/4498] tests: drivers: build_all: sensor: Add mc3419 sensor Included MC3419 3-axis accelerometer sensor in build_all test to test mc3419 driver Signed-off-by: Karthikeyan Krishnasamy --- tests/drivers/build_all/sensor/i2c.dtsi | 6 ++++++ tests/drivers/build_all/sensor/sensors_trigger_own.conf | 1 + 2 files changed, 7 insertions(+) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 433a00d6c8a..3fe5eee59e7 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -776,3 +776,9 @@ test_i2c_amd_sb_tsi: amd_sb_tsi@74 { compatible = "amd,sb-tsi"; reg = <0x74>; }; + +test_i2c_mc3419: mc3419@75 { + compatible = "memsic,mc3419"; + reg = <0x75>; + int-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index 17e1b6c29fa..a64f6aa5c8b 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -38,6 +38,7 @@ CONFIG_LSM6DSL_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSO_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSO16IS_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD=y +CONFIG_MC3419_TRIGGER_OWN_THREAD=y CONFIG_MCP9808_TRIGGER_OWN_THREAD=y CONFIG_MPU6050_TRIGGER_OWN_THREAD=y CONFIG_MPU9250_TRIGGER_OWN_THREAD=y From 52c55177ba71af328c6069ea56c007e6eb5cdf1d Mon Sep 17 00:00:00 2001 From: Jacob Preston Date: Wed, 18 Oct 2023 09:21:16 -0700 Subject: [PATCH 2318/4498] drivers: uart: nrf: rx_timeout_slab incorrectly set When rx_timeout is set to a sufficiently small value, rx_timeout_slab could potentially get set to a greater than necessary value that causes spurious UART_RX_RDY events. Fixes #62828 Signed-off-by: Jacob Preston --- drivers/serial/uart_nrfx_uarte.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 017efa6a2e5..b70af538abf 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -844,15 +844,7 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, } data->async->rx_timeout = timeout; - /* Set minimum interval to 3 RTC ticks. 3 is used due to RTC limitation - * which cannot set timeout for next tick. Assuming delay in processing - * 3 instead of 2 is used. Note that lower value would work in a similar - * way but timeouts would always occur later than expected, most likely - * after ~3 ticks. - */ - data->async->rx_timeout_slab = - MAX(timeout / RX_TIMEOUT_DIV, - NRFX_CEIL_DIV(3 * 1000000, CONFIG_SYS_CLOCK_TICKS_PER_SEC)); + data->async->rx_timeout_slab = timeout / RX_TIMEOUT_DIV; data->async->rx_buf = buf; data->async->rx_buf_len = len; From 09950b6d0beda9290dcc284fb0ecc8e9f4f108d5 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 28 Sep 2023 14:28:59 -0700 Subject: [PATCH 2319/4498] drivers: entropy: Small documentation tweaks Document driver API and moved around a flag. Signed-off-by: Flavio Ceolin --- include/zephyr/drivers/entropy.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/zephyr/drivers/entropy.h b/include/zephyr/drivers/entropy.h index 9bf4f37c3a8..1e1573d29a8 100644 --- a/include/zephyr/drivers/entropy.h +++ b/include/zephyr/drivers/entropy.h @@ -29,6 +29,9 @@ extern "C" { #endif +/** @brief Driver is allowed to busy-wait for random data to be ready */ +#define ENTROPY_BUSYWAIT BIT(0) + /** * @typedef entropy_get_entropy_t * @brief Callback API to get entropy. @@ -51,6 +54,12 @@ typedef int (*entropy_get_entropy_isr_t)(const struct device *dev, uint8_t *buffer, uint16_t length, uint32_t flags); + +/** + * @brief Entropy driver API structure. + * + * This is the mandatory API any Entropy driver needs to expose. + */ __subsystem struct entropy_driver_api { entropy_get_entropy_t get_entropy; entropy_get_entropy_isr_t get_entropy_isr; @@ -82,9 +91,6 @@ static inline int z_impl_entropy_get_entropy(const struct device *dev, return api->get_entropy(dev, buffer, length); } -/* Busy-wait for random data to be ready */ -#define ENTROPY_BUSYWAIT BIT(0) - /** * @brief Fills a buffer with entropy in a non-blocking or busy-wait manner. * Callable from ISRs. From bfa0b52a848bcbaf5dd28f864c7f5fd390e4aacc Mon Sep 17 00:00:00 2001 From: Teoh Shi Lin Date: Thu, 8 Jun 2023 15:24:15 +0800 Subject: [PATCH 2320/4498] drivers: serial: uart_intel_lw: add driver Enable driver for intel lw uart. Changes from review: - refactor spinlock to inside of loop - use menuconfig for kconfig - add CONFIG_UART_INTEL_LW_AUTO_LINE_CTRL_POLL Signed-off-by: Teoh Shi Lin --- CODEOWNERS | 1 + drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 2 + drivers/serial/Kconfig.intel_lw | 30 + drivers/serial/uart_intel_lw.c | 1025 +++++++++++++++++ dts/bindings/serial/intel,lw_uart.yaml | 19 + include/zephyr/drivers/serial/uart_intel_lw.h | 45 + 7 files changed, 1123 insertions(+) create mode 100644 drivers/serial/Kconfig.intel_lw create mode 100644 drivers/serial/uart_intel_lw.c create mode 100644 dts/bindings/serial/intel,lw_uart.yaml create mode 100644 include/zephyr/drivers/serial/uart_intel_lw.h diff --git a/CODEOWNERS b/CODEOWNERS index 1a054c4d3f6..2a3d3ccb249 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -451,6 +451,7 @@ /drivers/serial/uart_hvc_xen_consoleio.c @lorc @firscity /drivers/serial/Kconfig.it8xxx2 @GTLin08 /drivers/serial/uart_ite_it8xxx2.c @GTLin08 +/drivers/serial/*intel_lw* @shilinte /drivers/smbus/ @finikorg /drivers/sip_svc/ @maheshraotm /drivers/disk/ @jfischer-no diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 658ab50a71d..9ee77115e2b 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -65,6 +65,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_NUMAKER uart_numaker.c) zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) +zephyr_library_sources_ifdef(CONFIG_UART_INTEL_LW uart_intel_lw.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e4ab0953861..18845f8e394 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -243,4 +243,6 @@ source "drivers/serial/Kconfig.sedi" source "drivers/serial/Kconfig.bcm2711" +source "drivers/serial/Kconfig.intel_lw" + endif # SERIAL diff --git a/drivers/serial/Kconfig.intel_lw b/drivers/serial/Kconfig.intel_lw new file mode 100644 index 00000000000..478af03cf81 --- /dev/null +++ b/drivers/serial/Kconfig.intel_lw @@ -0,0 +1,30 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig UART_INTEL_LW + bool "Intel Lightweight UART driver" + depends on DT_HAS_INTEL_LW_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + Enable the Intel Lightweight UART driver, that can be built into Intel NiosV CPU designs. + +if UART_INTEL_LW + +config UART_INTEL_LW_EOP + bool "Include end of packet register" + depends on UART_DRV_CMD && UART_INTERRUPT_DRIVEN + help + Use driver command CMD_ENABLE_EOP and CMD_DISABLE_EOP to use the feature. + +config UART_INTEL_LW_AUTO_LINE_CTRL_POLL + bool "Auto set RTS signal during poll out" + depends on UART_LINE_CTRL + help + Assert RTS before polling out a character, + and deassert RTS after the character is polled out. + Please note that this is not suitable, when polling out several characters. + Please use uart_drv_cmd with CMD_POLL_ASSERT_RTS before polling out. + Then use CMD_POLL_DEASSERT_RTS to resume normal operation after polling. + +endif # UART_INTEL_LW diff --git a/drivers/serial/uart_intel_lw.c b/drivers/serial/uart_intel_lw.c new file mode 100644 index 00000000000..9b2a877fbdc --- /dev/null +++ b/drivers/serial/uart_intel_lw.c @@ -0,0 +1,1025 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief UART driver for Intel FPGA UART Core IP + * Reference : Embedded Peripherals IP User Guide (22.3 and above): 55. + * Lightweight UART Core + */ + +#define DT_DRV_COMPAT intel_lw_uart +#include +#include + +#include + +/* register offsets */ +#define INTEL_LW_UART_OFFSET (0x4) + +#define INTEL_LW_UART_RXDATA_REG_OFFSET (0 * INTEL_LW_UART_OFFSET) +#define INTEL_LW_UART_TXDATA_REG_OFFSET (1 * INTEL_LW_UART_OFFSET) +#define INTEL_LW_UART_STATUS_REG_OFFSET (2 * INTEL_LW_UART_OFFSET) +#define INTEL_LW_UART_CONTROL_REG_OFFSET (3 * INTEL_LW_UART_OFFSET) +#define INTEL_LW_UART_DIVISOR_REG_OFFSET (4 * INTEL_LW_UART_OFFSET) +#define INTEL_LW_UART_EOP_REG_OFFSET (5 * INTEL_LW_UART_OFFSET) + +/*status register mask */ +#define INTEL_LW_UART_STATUS_PE_MSK (0x1) +#define INTEL_LW_UART_STATUS_FE_MSK (0x2) +#define INTEL_LW_UART_STATUS_BRK_MSK (0x4) +#define INTEL_LW_UART_STATUS_ROE_MSK (0x8) +#define INTEL_LW_UART_STATUS_TOE_MSK (0x10) +#define INTEL_LW_UART_STATUS_TMT_MSK (0x20) +#define INTEL_LW_UART_STATUS_TRDY_MSK (0x40) +#define INTEL_LW_UART_STATUS_RRDY_MSK (0x80) +#define INTEL_LW_UART_STATUS_DCTS_MSK (0x400) +#define INTEL_LW_UART_STATUS_CTS_MSK (0x800) +#define INTEL_LW_UART_STATUS_E_MSK (0x100) +#define INTEL_LW_UART_STATUS_EOP_MSK (0x1000) + +/* control register mask */ +#define INTEL_LW_UART_CONTROL_TMT_MSK (0x20) +#define INTEL_LW_UART_CONTROL_TRDY_MSK (0x40) +#define INTEL_LW_UART_CONTROL_RRDY_MSK (0x80) +#define INTEL_LW_UART_CONTROL_E_MSK (0x100) +#define INTEL_LW_UART_CONTROL_TRBK_MSK (0x200) +#define INTEL_LW_UART_CONTROL_DCTS_MSK (0x400) +#define INTEL_LW_UART_CONTROL_RTS_MSK (0x800) +#define INTEL_LW_UART_CONTROL_EOP_MSK (0x1000) + +/* defined values */ +#define UART_INTEL_LW_NO_ERROR (0u) +#define INTEL_LW_UART_CLEAR_STATUS_VAL (0u) +#define INTEL_LW_UART_PENDING_MASK (INTEL_LW_UART_STATUS_RRDY_MSK | \ + INTEL_LW_UART_STATUS_TRDY_MSK | INTEL_LW_UART_STATUS_E_MSK \ + | INTEL_LW_UART_STATUS_EOP_MSK) + +/***********************/ +/* configuration flags */ +/* + * The value INTEL_LW_UART_FB is a value set in the devices flag field to + * indicate that the device has a fixed baud rate; i.e. if this flag is set + * software can not control the baud rate of the device. + */ +#define INTEL_LW_UART_FB 0x1 + +/* + * The value INTEL_LW_UART_FC is a value set in the device flag field to + * indicate the the device is using flow control, i.e. the driver must + * throttle on transmit if the nCTS pin is low. + */ +#define INTEL_LW_UART_FC 0x2 + +/* end of configuration flags */ +/******************************/ + +/* device data */ +struct uart_intel_lw_device_data { + struct uart_config uart_cfg; /* stores uart config from device tree*/ + struct k_spinlock lock; + uint32_t status_act; /* stores value of status register. */ +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t cb; /**< Callback function pointer */ + void *cb_data; /**< Callback function arg */ +#ifdef CONFIG_UART_INTEL_LW_EOP + uint8_t set_eop_cb; + uart_irq_callback_user_data_t cb_eop; /**< Callback function pointer */ + void *cb_data_eop; /**< Callback function arg */ +#endif /* CONFIG_UART_INTEL_LW_EOP */ + uint32_t control_val; /* stores value to set control register. */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +/* + * device config: + * stores data that cannot be changed during run time. + */ +struct uart_intel_lw_device_config { + mm_reg_t base; + uint32_t flags; /* refer to configuration flags */ +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; + unsigned int irq_num; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +/** + * function prototypes + */ +static int uart_intel_lw_irq_update(const struct device *dev); +static int uart_intel_lw_irq_tx_ready(const struct device *dev); +static int uart_intel_lw_irq_rx_ready(const struct device *dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +/** + * @brief Poll the device for input. + * + * This is a non-blocking function. + * + * This driver supports interrupt driven api. + * Polling for data under normal operation, might cause unexpected behaviour. + * If users wish to poll in for data, please ensure that the data is not retrieved + * in interrupt. + * + * If UART_LINE_CTRL is enabled, please do not disable the hardware + * interrupt for this uart device, as the flow control is handled in uart_intel_lw_dcts_isr. + * + * @param dev UART device instance + * @param p_char Pointer to character + * + * @return 0 if a character arrived, -1 if input buffer is empty. + * -EINVAL if p_char is null pointer + */ +static int uart_intel_lw_poll_in(const struct device *dev, unsigned char *p_char) +{ + const struct uart_intel_lw_device_config *config = dev->config; + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = -1; + uint32_t status; + + /* generate fatal error if CONFIG_ASSERT is enabled. */ + __ASSERT(p_char != NULL, "p_char is null pointer!"); + + /* Stop, if p_char is null pointer */ + if (p_char == NULL) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + /* check if received character is ready.*/ + status = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + if (status & INTEL_LW_UART_STATUS_RRDY_MSK) { + /* got a character */ + *p_char = sys_read32(config->base + INTEL_LW_UART_RXDATA_REG_OFFSET); + ret_val = 0; + } + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +/** + * @brief Output a character in polled mode. + * + * This function will block until transmitter is ready. + * Then, a character will be transmitted. + * + * This driver supports interrupt driven api. + * Polling for data under normal operation, might cause unexpected behaviour. + * If users wish to poll out data, please ensure that the data is not transmitted + * in interrupt. + * + * If UART_LINE_CTRL is enabled and users wish to poll out only 1 character, + * please enable UART_INTEL_LW_AUTO_LINE_CTRL_POLL. Please note that this might + * be inefficient, in case of polling out several characters. Instead of using + * UART_INTEL_LW_AUTO_LINE_CTRL_POLL, please consider using the api: uart_drv_cmd + * with CMD_POLL_ASSERT_RTS before polling out. Then use CMD_POLL_DEASSERT_RTS to + * resume normal operation after all characters are polled out. + * + * Please do not set CMD_TRBK_EN, when polling out data. + * + * @param dev UART device instance + * @param c Character to send + */ +static void uart_intel_lw_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_intel_lw_device_config *config = dev->config; + struct uart_intel_lw_device_data *data = dev->data; + uint32_t status; + bool tx_is_free = false; + bool poll_out_done = false; + k_spinlock_key_t key; + + /* wait until uart is free to transmit.*/ + do { + key = k_spin_lock(&data->lock); + + if (tx_is_free == false) { + status = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + + /* wait until there is space in fifo. */ + if (status & INTEL_LW_UART_STATUS_TRDY_MSK) { +#ifdef CONFIG_UART_INTEL_LW_AUTO_LINE_CTRL_POLL + data->control_val |= INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); +#endif + sys_write32(c, config->base + INTEL_LW_UART_TXDATA_REG_OFFSET); + tx_is_free = true; + } + } else { + status = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + + /* wait until fifo data is shifted out. */ + if (status & INTEL_LW_UART_STATUS_TMT_MSK) { +#ifdef CONFIG_UART_INTEL_LW_AUTO_LINE_CTRL_POLL + data->control_val &= ~INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); +#endif + poll_out_done = true; + } + } + + k_spin_unlock(&data->lock, key); + } while (!poll_out_done); +} + +/** + * @brief Initialise an instance of the driver + * + * This function initialise the interrupt configuration for the driver. + * + * @param dev UART device instance + * + * @return 0 to indicate success. + */ +static int uart_intel_lw_init(const struct device *dev) +{ +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + /* clear status to ensure, that interrupts are not triggered due to old status. */ + sys_write32(INTEL_LW_UART_CLEAR_STATUS_VAL, config->base + + INTEL_LW_UART_STATUS_REG_OFFSET); + + /* + * Enable hardware interrupt. + * The corresponding csr from IP still needs to be set, + * so that the IP generates interrupt signal. + */ + config->irq_config_func(dev); + +#ifdef CONFIG_UART_LINE_CTRL + /* Enable DCTS interrupt. */ + data->control_val = INTEL_LW_UART_CONTROL_DCTS_MSK; +#endif /* CONFIG_UART_LINE_CTRL */ + + sys_write32(data->control_val, config->base + INTEL_LW_UART_CONTROL_REG_OFFSET); + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + return 0; +} + +/** + * @brief Check if an error was received + * If error is received, it will be mapped to uart_rx_stop_reason. + * This function should be called after irq_update. + * If interrupt driven API is not enabled, + * this function will read and clear the status register. + * + * @param dev UART device struct + * + * @return UART_ERROR_OVERRUN, UART_ERROR_PARITY, UART_ERROR_FRAMING, + * UART_BREAK if an error was detected, 0 otherwise. + */ +static int uart_intel_lw_err_check(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + int err = UART_INTEL_LW_NO_ERROR; + +#ifndef CONFIG_UART_INTERRUPT_DRIVEN + const struct uart_intel_lw_device_config *config = dev->config; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->status_act = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); +#endif + + if (data->status_act & INTEL_LW_UART_STATUS_E_MSK) { + if (data->status_act & INTEL_LW_UART_STATUS_PE_MSK) { + err |= UART_ERROR_PARITY; + } + + if (data->status_act & INTEL_LW_UART_STATUS_FE_MSK) { + err |= UART_ERROR_FRAMING; + } + + if (data->status_act & INTEL_LW_UART_STATUS_BRK_MSK) { + err |= UART_BREAK; + } + + if (data->status_act & INTEL_LW_UART_STATUS_ROE_MSK) { + err |= UART_ERROR_OVERRUN; + } + } + +#ifndef CONFIG_UART_INTERRUPT_DRIVEN + /* clear status */ + sys_write32(INTEL_LW_UART_CLEAR_STATUS_VAL, config->base + + INTEL_LW_UART_STATUS_REG_OFFSET); + k_spin_unlock(&data->lock, key); +#endif + + return err; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +/*** + * @brief helper function to check, if the configuration is support. + * The only parameter that can be changed during runtime is the baudrate. + * + * @param cfg_stored The original configuration. + * @param cfg_in The input configuration. + * @return true if parameter other than baudrate remains the same. otherwise, false. + */ +static bool uart_intel_lw_check_configuration(const struct uart_config *cfg_stored, + const struct uart_config *cfg_in) +{ + bool ret_val = false; + + if ((cfg_stored->parity == cfg_in->parity) + && (cfg_stored->stop_bits == cfg_in->stop_bits) + && (cfg_stored->data_bits == cfg_in->data_bits) + && (cfg_stored->flow_ctrl == cfg_in->flow_ctrl)) { + ret_val = true; + } + + return ret_val; +} + +/** + * @brief Set UART configuration using data from *cfg_in. + * + * @param dev UART Device struct + * @param cfg_in The input configuration. + * + * @return 0 if success, -ENOTSUP, if input from cfg_in is not configurable. + * -EINVAL if cfg_in is null pointer + */ +static int uart_intel_lw_configure(const struct device *dev, + const struct uart_config *cfg_in) +{ + const struct uart_intel_lw_device_config *config = dev->config; + struct uart_intel_lw_device_data * const data = dev->data; + struct uart_config * const cfg_stored = &data->uart_cfg; + uint32_t divisor_val; + int ret_val; + + /* generate fatal error if CONFIG_ASSERT is enabled. */ + __ASSERT(cfg_in != NULL, "cfg_in is null pointer!"); + + /* Stop, if cfg_in is null pointer */ + if (cfg_in == NULL) { + return -EINVAL; + } + + /* check if configuration is supported. */ + if (uart_intel_lw_check_configuration(cfg_stored, cfg_in) + && !(config->flags & INTEL_LW_UART_FB)) { + /* parameter is valid, just return ok if baudrate is the same. */ + if (cfg_stored->baudrate != cfg_in->baudrate) { + /* calculate and set baudrate. */ + divisor_val = (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC/cfg_in->baudrate) - 1; + sys_write32(divisor_val, config->base + INTEL_LW_UART_DIVISOR_REG_OFFSET); + + /* update stored data. */ + cfg_stored->baudrate = cfg_in->baudrate; + } + + ret_val = 0; + } else { + /* return not supported */ + ret_val = -ENOTSUP; + } + + return ret_val; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +/** + * @brief Get UART configuration and stores in *cfg_out. + * + * @param dev UART Device struct + * @param cfg_out The output configuration. + * + * @return 0 if success. + * -EINVAL if cfg_out is null pointer + */ +static int uart_intel_lw_config_get(const struct device *dev, + struct uart_config *cfg_out) +{ + const struct uart_intel_lw_device_data *data = dev->data; + + /* generate fatal error if CONFIG_ASSERT is enabled. */ + __ASSERT(cfg_out != NULL, "cfg_out is null pointer!"); + + /* Stop, if cfg_out is null pointer */ + if (cfg_out == NULL) { + return -EINVAL; + } + + *cfg_out = data->uart_cfg; + return 0; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +/** + * @brief Fill FIFO with data + * This function is expected to be called from UART interrupt handler (ISR), + * if uart_irq_tx_ready() returns true. This function does not block! + * + * @param dev UART device struct + * @param tx_data Data to transmit + * @param size Number of bytes to send + * + * @return Number of bytes sent + */ +static int uart_intel_lw_fifo_fill(const struct device *dev, + const uint8_t *tx_data, + int size) +{ + const struct uart_intel_lw_device_config *config = dev->config; + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + k_spinlock_key_t key; + + /* generate fatal error if CONFIG_ASSERT is enabled. */ + __ASSERT(tx_data != NULL, "tx_data is null pointer!"); + + /* Stop, if tx_data is null pointer */ + if (tx_data == NULL) { + return 0; + } + + /* Stop, if transmit break is set */ + if (data->control_val & INTEL_LW_UART_CONTROL_TRBK_MSK) { + return 0; + } + + do { + if (data->status_act & INTEL_LW_UART_STATUS_TRDY_MSK) { + key = k_spin_lock(&data->lock); + sys_write32(tx_data[ret_val++], config->base + + INTEL_LW_UART_TXDATA_REG_OFFSET); + data->status_act = sys_read32(config->base + + INTEL_LW_UART_STATUS_REG_OFFSET); + k_spin_unlock(&data->lock, key); + } else { + /* stop because tx fifo is full! */ + break; + } + } while ((size - ret_val) > 0); + + return ret_val; +} + +/** + * @brief Read data from FIFO + * This function is expected to be called from UART interrupt handler (ISR), + * if uart_irq_rx_ready() returns true. + * + * @param dev UART device struct + * @param rx_data Data container + * @param size Container size + * + * @return Number of bytes read + */ +static int uart_intel_lw_fifo_read(const struct device *dev, uint8_t *rx_data, + const int size) +{ + const struct uart_intel_lw_device_config *config = dev->config; + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + k_spinlock_key_t key; + + /* generate fatal error if CONFIG_ASSERT is enabled. */ + __ASSERT(rx_data != NULL, "rx_data is null pointer!"); + + /* Stop, if rx_data is null pointer */ + if (rx_data == NULL) { + return 0; + } + + do { + if (data->status_act & INTEL_LW_UART_STATUS_RRDY_MSK) { + key = k_spin_lock(&data->lock); + rx_data[ret_val++] = sys_read32(config->base + + INTEL_LW_UART_RXDATA_REG_OFFSET); + data->status_act = sys_read32(config->base + + INTEL_LW_UART_STATUS_REG_OFFSET); + + k_spin_unlock(&data->lock, key); + } else { + break; + } + } while ((size - ret_val) > 0); + + return ret_val; +} + +/** + * @brief Enable TX interrupt + * + * @param dev UART device struct + */ +static void uart_intel_lw_irq_tx_enable(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->control_val |= INTEL_LW_UART_CONTROL_TRDY_MSK; + +#ifdef CONFIG_UART_LINE_CTRL + /* also enable RTS, if flow control is enabled. */ + data->control_val |= INTEL_LW_UART_CONTROL_RTS_MSK; +#endif + + sys_write32(data->control_val, config->base + INTEL_LW_UART_CONTROL_REG_OFFSET); + + k_spin_unlock(&data->lock, key); +} + +/** + * @brief Disable TX interrupt + * + * @param dev UART device struct + */ +static void uart_intel_lw_irq_tx_disable(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->control_val &= ~INTEL_LW_UART_CONTROL_TRDY_MSK; + +#ifdef CONFIG_UART_LINE_CTRL + /* also disable RTS, if flow control is enabled. */ + data->control_val &= ~INTEL_LW_UART_CONTROL_RTS_MSK; +#endif + + sys_write32(data->control_val, config->base + INTEL_LW_UART_CONTROL_REG_OFFSET); + + k_spin_unlock(&data->lock, key); +} + +/** + * @brief Check if UART TX buffer can accept a new char. + * + * @param dev UART device struct + * + * @return 1 if TX interrupt is enabled and at least one char can be written to UART. + * 0 if device is not ready to write a new byte. + */ +static int uart_intel_lw_irq_tx_ready(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + /* if TX interrupt is enabled */ + if (data->control_val & INTEL_LW_UART_CONTROL_TRDY_MSK) { + /* IP core does not have fifo. Wait until tx data is completely shifted. */ + if (data->status_act & INTEL_LW_UART_STATUS_TMT_MSK) { + ret_val = 1; + } + } + +#ifdef CONFIG_UART_LINE_CTRL + /* if flow control is enabled, set tx not ready, if CTS is low. */ + if ((data->status_act & INTEL_LW_UART_STATUS_CTS_MSK) == 0) { + ret_val = 0; + } + +#endif /* CONFIG_UART_LINE_CTRL */ + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +/** + * @brief Check if nothing remains to be transmitted + * + * @param dev UART device struct + * + * @return 1 if nothing remains to be transmitted, 0 otherwise + */ +static int uart_intel_lw_irq_tx_complete(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (data->status_act & INTEL_LW_UART_STATUS_TMT_MSK) { + ret_val = 1; + } + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +/** + * @brief Enable RX interrupt in + * + * @param dev UART device struct + */ +static void uart_intel_lw_irq_rx_enable(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->control_val |= INTEL_LW_UART_CONTROL_RRDY_MSK; + sys_write32(data->control_val, config->base + INTEL_LW_UART_CONTROL_REG_OFFSET); + + k_spin_unlock(&data->lock, key); +} + +/** + * @brief Disable RX interrupt + * + * @param dev UART device struct + */ +static void uart_intel_lw_irq_rx_disable(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->control_val &= ~INTEL_LW_UART_CONTROL_RRDY_MSK; + sys_write32(data->control_val, config->base + INTEL_LW_UART_CONTROL_REG_OFFSET); + + k_spin_unlock(&data->lock, key); +} + +/** + * @brief Check if Rx IRQ has been raised + * + * @param dev UART device struct + * + * @return 1 if an IRQ is ready, 0 otherwise + */ +static int uart_intel_lw_irq_rx_ready(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + /* if RX interrupt is enabled */ + if (data->control_val & INTEL_LW_UART_CONTROL_RRDY_MSK) { + /* check for space in rx data register */ + if (data->status_act & INTEL_LW_UART_STATUS_RRDY_MSK) { + ret_val = 1; + } + } + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +/** + * @brief This function will cache the status register. + * + * @param dev UART device struct + * + * @return 1 for success. + */ +static int uart_intel_lw_irq_update(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->status_act = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + + k_spin_unlock(&data->lock, key); + + return 1; +} + +/** + * @brief Check if any IRQ is pending + * + * @param dev UART device struct + * + * @return 1 if an IRQ is pending, 0 otherwise + */ +static int uart_intel_lw_irq_is_pending(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + int ret_val = 0; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (data->status_act & data->control_val & INTEL_LW_UART_PENDING_MASK) { + ret_val = 1; + } + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * @param cb_data Data to pass to callback function. + */ +static void uart_intel_lw_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_intel_lw_device_data *data = dev->data; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + +#ifdef CONFIG_UART_INTEL_LW_EOP + if (data->set_eop_cb) { + data->cb_eop = cb; + data->cb_data_eop = cb_data; + data->set_eop_cb = 0; + } else { + data->cb = cb; + data->cb_data = cb_data; + } +#else + data->cb = cb; + data->cb_data = cb_data; +#endif /* CONFIG_UART_INTEL_LW_EOP */ + + k_spin_unlock(&data->lock, key); +} + +#ifdef CONFIG_UART_LINE_CTRL +/** + * @brief DCTS Interrupt service routine. + * + * Handles assertion and deassettion of CTS/RTS stignal + * + * @param dev Pointer to UART device struct + */ +static void uart_intel_lw_dcts_isr(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + /* Assume that user follows zephyr requirement and update status in their call back. */ + if (data->status_act & INTEL_LW_UART_STATUS_CTS_MSK) { + + /* Assert RTS to inform other UART. */ + data->control_val |= INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + } else { + /* other UART deasserts RTS */ + if (data->status_act & INTEL_LW_UART_STATUS_TMT_MSK) { + /* only deasserts if not transmitting. */ + data->control_val &= ~INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + } + } + + k_spin_unlock(&data->lock, key); +} +#endif /* CONFIG_UART_LINE_CTRL */ + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param dev Pointer to UART device struct + * + */ +static void uart_intel_lw_isr(const struct device *dev) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + uart_irq_callback_user_data_t callback = data->cb; + + if (callback) { + callback(dev, data->cb_data); + } + + /* Post ISR */ +#if CONFIG_UART_INTEL_LW_EOP + data->status_act = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + if (data->status_act & INTEL_LW_UART_STATUS_EOP_MSK) { + callback = data->cb_eop; + if (callback) { + callback(dev, data->cb_data_eop); + } + } +#endif /* CONFIG_UART_INTEL_LW_EOP */ + +#ifdef CONFIG_UART_LINE_CTRL + data->status_act = sys_read32(config->base + INTEL_LW_UART_STATUS_REG_OFFSET); + /* handles RTS/CTS signal */ + if (data->status_act & INTEL_LW_UART_STATUS_DCTS_MSK) { + uart_intel_lw_dcts_isr(dev); + } +#endif + + /* clear status after all interrupts are handled. */ + sys_write32(INTEL_LW_UART_CLEAR_STATUS_VAL, config->base + + INTEL_LW_UART_STATUS_REG_OFFSET); +} + +#ifdef CONFIG_UART_DRV_CMD +/** + * @brief Send extra command to driver + * + * @param dev UART device struct + * @param cmd Command to driver + * @param p Parameter to the command + * + * @return 0 if successful, failed otherwise + */ +static int uart_intel_lw_drv_cmd(const struct device *dev, uint32_t cmd, + uint32_t p) +{ + struct uart_intel_lw_device_data *data = dev->data; + const struct uart_intel_lw_device_config *config = dev->config; + + int ret_val = -ENOTSUP; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + switch (cmd) { +#if CONFIG_UART_INTEL_LW_EOP + case CMD_ENABLE_EOP: + /* enable EOP interrupt */ + data->control_val |= INTEL_LW_UART_CONTROL_EOP_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + + /* set EOP character */ + sys_write32((uint8_t) p, config->base + INTEL_LW_UART_EOP_REG_OFFSET); + + /* after this, user needs to call uart_irq_callback_set + * to set data->cb_eop and data->cb_data_eop! + */ + data->set_eop_cb = 1; + ret_val = 0; + break; + + case CMD_DISABLE_EOP: + /* disable EOP interrupt */ + data->control_val &= ~INTEL_LW_UART_CONTROL_EOP_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + + /* clear call back */ + data->cb_eop = NULL; + data->cb_data_eop = NULL; + ret_val = 0; + break; +#endif /* CONFIG_UART_INTEL_LW_EOP */ + + case CMD_TRBK_EN: + /* enable transmit break */ + data->control_val |= INTEL_LW_UART_CONTROL_TRBK_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + ret_val = 0; + break; + + case CMD_TRBK_DIS: + /* disable transmit break */ + data->control_val &= ~INTEL_LW_UART_CONTROL_TRBK_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + ret_val = 0; + break; + + case CMD_POLL_ASSERT_RTS: + /* assert RTS */ + data->control_val |= INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + ret_val = 0; + break; + + case CMD_POLL_DEASSERT_RTS: + /* deassert RTS */ + data->control_val &= ~INTEL_LW_UART_CONTROL_RTS_MSK; + sys_write32(data->control_val, config->base + + INTEL_LW_UART_CONTROL_REG_OFFSET); + ret_val = 0; + break; + + default: + ret_val = -ENOTSUP; + break; + }; + + k_spin_unlock(&data->lock, key); + + return ret_val; +} + +#endif /* CONFIG_UART_DRV_CMD */ + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api uart_intel_lw_driver_api = { + .poll_in = uart_intel_lw_poll_in, + .poll_out = uart_intel_lw_poll_out, + .err_check = uart_intel_lw_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_intel_lw_configure, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + .config_get = uart_intel_lw_config_get, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_intel_lw_fifo_fill, + .fifo_read = uart_intel_lw_fifo_read, + .irq_tx_enable = uart_intel_lw_irq_tx_enable, + .irq_tx_disable = uart_intel_lw_irq_tx_disable, + .irq_tx_ready = uart_intel_lw_irq_tx_ready, + .irq_tx_complete = uart_intel_lw_irq_tx_complete, + .irq_rx_enable = uart_intel_lw_irq_rx_enable, + .irq_rx_disable = uart_intel_lw_irq_rx_disable, + .irq_rx_ready = uart_intel_lw_irq_rx_ready, + .irq_is_pending = uart_intel_lw_irq_is_pending, + .irq_update = uart_intel_lw_irq_update, + .irq_callback_set = uart_intel_lw_irq_callback_set, +#endif + +#ifdef CONFIG_UART_DRV_CMD + .drv_cmd = uart_intel_lw_drv_cmd, +#endif +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +#define UART_INTEL_LW_IRQ_CONFIG_FUNC(n) \ + static void uart_intel_lw_irq_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + uart_intel_lw_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + } + +#define UART_INTEL_LW_IRQ_CONFIG_INIT(n) \ + .irq_config_func = uart_intel_lw_irq_config_func_##n, \ + .irq_num = DT_INST_IRQN(n), + +#else + +#define UART_INTEL_LW_IRQ_CONFIG_FUNC(n) +#define UART_INTEL_LW_IRQ_CONFIG_INIT(n) + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#define UART_INTEL_LW_DEVICE_INIT(n) \ +UART_INTEL_LW_IRQ_CONFIG_FUNC(n) \ +static struct uart_intel_lw_device_data uart_intel_lw_dev_data_##n = { \ + .uart_cfg = \ + { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = DT_INST_ENUM_IDX_OR(n, parity, \ + UART_CFG_PARITY_NONE), \ + .stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, \ + UART_CFG_STOP_BITS_1), \ + .data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, \ + UART_CFG_DATA_BITS_8), \ + .flow_ctrl = DT_INST_PROP(n, hw_flow_control) ? \ + UART_CFG_FLOW_CTRL_RTS_CTS : \ + UART_CFG_FLOW_CTRL_NONE, \ + }, \ +}; \ + \ +static const struct uart_intel_lw_device_config uart_intel_lw_dev_cfg_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .flags = ((DT_INST_PROP(n, fixed_baudrate)?INTEL_LW_UART_FB:0) \ + |(DT_INST_PROP(n, hw_flow_control)?INTEL_LW_UART_FC:0)),\ + UART_INTEL_LW_IRQ_CONFIG_INIT(n) \ +}; \ + \ +DEVICE_DT_INST_DEFINE(n, \ + uart_intel_lw_init, \ + NULL, \ + &uart_intel_lw_dev_data_##n, \ + &uart_intel_lw_dev_cfg_##n, \ + PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_intel_lw_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_INTEL_LW_DEVICE_INIT) diff --git a/dts/bindings/serial/intel,lw_uart.yaml b/dts/bindings/serial/intel,lw_uart.yaml new file mode 100644 index 00000000000..798dfa53225 --- /dev/null +++ b/dts/bindings/serial/intel,lw_uart.yaml @@ -0,0 +1,19 @@ +description: Intel Lightweight UART + +compatible: "intel,lw-uart" + +include: uart-controller.yaml + +properties: + reg: + required: true + description: Base address of the uart controller. + + current-speed: + required: true + description: Default baudrate of the uart controller. + + fixed-baudrate: + type: boolean + description: | + Baud rate cannot be changed by software (Divisor register is not writable) diff --git a/include/zephyr/drivers/serial/uart_intel_lw.h b/include/zephyr/drivers/serial/uart_intel_lw.h new file mode 100644 index 00000000000..8ad8c26aab8 --- /dev/null +++ b/include/zephyr/drivers/serial/uart_intel_lw.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Header file for the INTEL LW UART + */ + +#ifndef ZEPHYR_DRIVERS_SERIAL_UART_INTEL_LW_H_ +#define ZEPHYR_DRIVERS_SERIAL_UART_INTEL_LW_H_ + +/* End of packet feature. + * Driver will trigger interrupt upon receiving end of package character. + * Please enable CONFIG_UART_INTEL_LW_EOP to use this feature. + * Use the api: uart_drv_cmd with CMD_ENABLE_EOP to enable the feature. + * This cmd will write the ip register and also set a flag to the driver. + * The flag will modify uart_irq_callback_user_data_set + * to set call back function for eop interrupt. + * Flag is cleared after uart_irq_callback_user_data_set is called. + */ +#define CMD_ENABLE_EOP 0x01 +#define CMD_DISABLE_EOP 0x02 + +/* Transmit break feature. + * Use uart_drv_cmd with CMD_TRBK_EN to break ongoing transmit. + * After this cmd, uart is unable to transmit any data. + * Please use CMD_TRBK_DIS to resume normal operation. + * Please also call uart_intel_lw_err_check, to clear the error caused + * by transmit break. + */ +#define CMD_TRBK_EN 0x03 +#define CMD_TRBK_DIS 0x04 + +/* This driver supports interrupt driven api. + * Polling for data under normal operation, might cause unexpected behaviour. + * If users wish to poll for data, please use the api: + * uart_drv_cmd with CMD_POLL_ASSERT_RTS before polling out/in. + * Then use CMD_POLL_DEASSERT_RTS to resume normal operation after polling. + */ +#define CMD_POLL_ASSERT_RTS 0x05 +#define CMD_POLL_DEASSERT_RTS 0x06 + +#endif /* ZEPHYR_DRIVERS_SERIAL_UART_INTEL_LW_H_ */ From fa054bf9da7d703974a01334a29994307a836ad9 Mon Sep 17 00:00:00 2001 From: Patryk Koscik Date: Fri, 6 Oct 2023 09:40:45 +0200 Subject: [PATCH 2321/4498] boards: arm: nrf52840dongle_nrf52840: Enable console by default Enables UART output for samples that do not enable `CONFIG_CONSOLE` in their config file Signed-off-by: Patryk Koscik --- boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig b/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig index 75a76b33293..76c7559be8d 100644 --- a/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig @@ -33,6 +33,9 @@ config USB_DEVICE_STACK config USB_CDC_ACM default SERIAL +config CONSOLE + default y + config UART_CONSOLE default CONSOLE From e2b2dde1c8e7c2cb9758005869f9054be0d1bc93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 17:14:28 -0700 Subject: [PATCH 2322/4498] .github: doc-build: build with west 1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is just released and we want the docstrings from there. Signed-off-by: Martí Bolívar --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 351cb041a83..7100c451629 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -26,7 +26,7 @@ on: env: # NOTE: west docstrings will be extracted from the version listed here - WEST_VERSION: 1.0.0 + WEST_VERSION: 1.2.0 # The latest CMake available directly with apt is 3.18, but we need >=3.20 # so we fetch that through pip. CMAKE_VERSION: 3.20.5 From fb3961db9fa83f4e01ab6f1c1eff20d7bd3eb4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 10:50:32 -0700 Subject: [PATCH 2323/4498] doc: west: sort built-in project commands by name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For convenience Signed-off-by: Martí Bolívar --- doc/develop/west/built-in.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/develop/west/built-in.rst b/doc/develop/west/built-in.rst index 085a37fdc64..150e4ec7bac 100644 --- a/doc/develop/west/built-in.rst +++ b/doc/develop/west/built-in.rst @@ -245,13 +245,13 @@ West has a few more commands for managing the projects in the workspace, which are summarized here. Run ``west -h`` for detailed help. +- ``west compare``: compare the state of the workspace against the manifest +- ``west diff``: run ``git diff`` in local project repositories +- ``west forall``: run an arbitrary command in local project repositories - ``west list``: print a line of information about each project in the manifest, according to a format string - ``west manifest``: manage the manifest file. See :ref:`west-manifest-cmd`. -- ``west diff``: run ``git diff`` in local project repositories - ``west status``: run ``git status`` in local project repositories -- ``west forall``: run an arbitrary command in local project repositories -- ``west compare``: compare the state of the workspace against the manifest Other built-in commands *********************** From a4392a31cdbd820a29f06a93cc36aa3a97ae3645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 10:51:27 -0700 Subject: [PATCH 2324/4498] doc: west: add docs for west grep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main documentation for the command itself is in the 'west help grep' output, so just add an entry in the list of built-in commands. Document the extra config options as well. Signed-off-by: Martí Bolívar --- doc/develop/west/built-in.rst | 1 + doc/develop/west/config.rst | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/doc/develop/west/built-in.rst b/doc/develop/west/built-in.rst index 150e4ec7bac..b54dbaad54f 100644 --- a/doc/develop/west/built-in.rst +++ b/doc/develop/west/built-in.rst @@ -248,6 +248,7 @@ detailed help. - ``west compare``: compare the state of the workspace against the manifest - ``west diff``: run ``git diff`` in local project repositories - ``west forall``: run an arbitrary command in local project repositories +- ``west grep``: search for patterns in local project repositories - ``west list``: print a line of information about each project in the manifest, according to a format string - ``west manifest``: manage the manifest file. See :ref:`west-manifest-cmd`. diff --git a/doc/develop/west/config.rst b/doc/develop/west/config.rst index 594b54cbbe7..eae6c7e4b9e 100644 --- a/doc/develop/west/config.rst +++ b/doc/develop/west/config.rst @@ -135,6 +135,24 @@ commands are documented in the pages for those commands. stdout is a terminal. * - ``commands.allow_extensions`` - Boolean, default ``true``, disables :ref:`west-extensions` if ``false`` + * - ``grep.color`` + - String, default empty. Set this to ``never`` to disable ``west grep`` + color output. If set, ``west grep`` passes the value to the grep tool's + ``--color`` option. + * - ``grep.tool`` + - String, one of ``"git-grep"`` (default), ``"ripgrep"``, or ``"grep"``. + The grep tool that ``west grep`` should use. + * - ``grep.-args`` + - String, default empty. The ```` part is a pattern that can be any + ``grep.tool`` value, so ``grep.ripgrep-args`` is an example + configuration option. If set, arguments that ``west grep`` should pass + to the corresponding grep tool. Run ``west help grep`` for details. + * - ``grep.-path`` + - String, default empty. The ```` part is a pattern that can be any + ``grep.tool`` value, so ``grep.ripgrep-path`` is an example + configuration option. The path to the corresponding tool that ``west + grep`` should use instead of searching for the command. Run ``west help + grep`` for details. * - ``manifest.file`` - String, default ``west.yml``. Relative path from the manifest repository root directory to the manifest file used by ``west init`` and other From cbc41bc8549c49ed9a6235818480c26b7be2b6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 11:24:15 -0700 Subject: [PATCH 2325/4498] doc: west: sort west.manifest.Project info by release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For legibility. Signed-off-by: Martí Bolívar --- doc/develop/west/west-apis.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/develop/west/west-apis.rst b/doc/develop/west/west-apis.rst index ec60bc6fe56..ff03f90765a 100644 --- a/doc/develop/west/west-apis.rst +++ b/doc/develop/west/west-apis.rst @@ -396,10 +396,6 @@ Manifest and sub-objects .. (note: attributes are part of the class docstring) - .. versionchanged:: 0.8.0 - The *west_commands* attribute is now always a list. In previous - releases, it could be a string or ``None``. - .. versionchanged:: 0.7.0 The *remote* attribute was removed. Its semantics could no longer be preserved when support for manifest ``import`` keys was added. @@ -407,6 +403,10 @@ Manifest and sub-objects .. versionadded:: 0.7.0 The *remote_name* and *name_and_path* attributes. + .. versionchanged:: 0.8.0 + The *west_commands* attribute is now always a list. In previous + releases, it could be a string or ``None``. + .. versionadded:: 0.9.0 The *group_filter* and *submodules* attributes. From 26ca13e30abc8f6a77c9ddf8045abfdb9ca4f148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 11:26:18 -0700 Subject: [PATCH 2326/4498] doc: west: manifest file format changes for v1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add information about changes to the file format. Signed-off-by: Martí Bolívar --- doc/develop/west/manifest.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/develop/west/manifest.rst b/doc/develop/west/manifest.rst index 3f2fa74e306..bb057272b01 100644 --- a/doc/develop/west/manifest.rst +++ b/doc/develop/west/manifest.rst @@ -174,9 +174,13 @@ Here is an example. We'll assume the ``remotes`` given above. # [... same remotes as above...] projects: - name: proj1 + description: the first example project remote: remote1 path: extra/project-1 - name: proj2 + description: | + A multi-line description of the second example + project. repo-path: my-path remote: remote2 revision: v1.3 @@ -229,6 +233,10 @@ next. reserved values "west" or "manifest". The name must be unique in the manifest file. + * - ``description`` + - Optional, an informational description of the project. Added in + west v1.2.0. + * - ``remote``, ``url`` - Mandatory (one of the two, but not both). @@ -331,9 +339,13 @@ so far using ``defaults`` is: projects: - name: proj1 + description: the first example project path: extra/project-1 revision: master - name: proj2 + description: | + A multi-line description of the second example + project. repo-path: my-path remote: remote2 - name: proj3 @@ -487,6 +499,10 @@ about the manifest file features that were introduced in that version. - Identical to ``"0.13"``, but available for use by users that do not wish to use a ``"0.x"`` version field. + * - ``"1.2"`` + - Support for ``description:`` in ``projects:`` + (:ref:`west-manifests-projects`) + .. note:: Versions of west without any new features in the manifest file format do not From 41ca16628fec3b07aee964788a43dbec58cff07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 11:26:49 -0700 Subject: [PATCH 2327/4498] doc: west: API changes for v1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are backwards compatible extensions in keeping with our promise to adhere to semantic versioning from now on. Signed-off-by: Martí Bolívar --- doc/develop/west/west-apis.rst | 40 ++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/doc/develop/west/west-apis.rst b/doc/develop/west/west-apis.rst index ff03f90765a..306cef813e8 100644 --- a/doc/develop/west/west-apis.rst +++ b/doc/develop/west/west-apis.rst @@ -137,14 +137,39 @@ WestCommand .. automethod:: add_pre_run_hook .. versionadded:: 1.0.0 - .. automethod:: check_call + .. NOTE: the following 'method' (not 'automethod') directives were added for + expediency during the west v1.2 release time frame to work around a build + failure in this zephyr documentation that could not be fixed without + cutting a west point release. (The docstrings in west had some RST syntax + errors). + These should be reverted back to automethod calls at the next release. + + .. method:: check_call(args, **kwargs) + + Runs ``subprocess.check_call(args, **kwargs)`` after + logging the call at Verbosity.DBG_MORE`` level. + + .. versionchanged:: 1.2.0 + The *cwd* keyword argument was replaced with a catch-all ``**kwargs``. .. versionchanged:: 0.11.0 - .. automethod:: check_output + .. method:: check_output(args, **kwargs) + + Runs ``subprocess.check_output(args, **kwargs)`` after + logging the call at Verbosity.DBG_MORE level. + .. versionchanged:: 1.2.0 + The *cwd* keyword argument was replaced with a catch-all ``**kwargs``. .. versionchanged:: 0.11.0 + .. method:: run_subprocess(args, **kwargs) + + Runs ``subprocess.run(args, **kwargs)`` after logging + the call at Verbosity.DBG_MORE level. + + .. versionadded:: 1.2.0 + All subclasses must provide the following abstract methods, which are used to implement the above: @@ -158,15 +183,23 @@ WestCommand "quiet" mode for west commands in a future release: .. automethod:: dbg + .. versionchanged:: 1.2.0 + The *end* argument. .. versionadded:: 1.0.0 .. automethod:: inf + .. versionchanged:: 1.2.0 + The *end* argument. .. versionadded:: 1.0.0 .. automethod:: wrn + .. versionchanged:: 1.2.0 + The *end* argument. .. versionadded:: 1.0.0 .. automethod:: err + .. versionchanged:: 1.2.0 + The *end* argument. .. versionadded:: 1.0.0 .. automethod:: die @@ -413,6 +446,9 @@ Manifest and sub-objects .. versionadded:: 0.12.0 The *userdata* attribute. + .. versionadded:: 1.2.0 + The *description* attribute. + Constructor: .. automethod:: __init__ From 1d3b8bd87949bf0a69cdacdb6ecbc717c5d21372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 6 Oct 2023 11:32:39 -0700 Subject: [PATCH 2328/4498] doc: west: release notes for v1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main new features are a 'west grep' command and a new 'description:' field in the manifest file's 'projects:' elements. Rather than try to keep the version number in index.rst up to date, which it frequently is not, just delete the paragraph. Signed-off-by: Martí Bolívar --- doc/develop/west/index.rst | 3 -- doc/develop/west/release-notes.rst | 75 ++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/doc/develop/west/index.rst b/doc/develop/west/index.rst index 627267fb250..7b5fd6b2cce 100644 --- a/doc/develop/west/index.rst +++ b/doc/develop/west/index.rst @@ -26,9 +26,6 @@ You can run ``west --help`` (or ``west -h`` for short) to get top-level help for available west commands, and ``west -h`` for detailed help on each command. -The following pages document west's ``v1.0.y`` releases, and provide additional -context about the tool. - .. toctree:: :maxdepth: 1 diff --git a/doc/develop/west/release-notes.rst b/doc/develop/west/release-notes.rst index 98d67da96d9..49dcc0a3116 100644 --- a/doc/develop/west/release-notes.rst +++ b/doc/develop/west/release-notes.rst @@ -3,6 +3,81 @@ West Release Notes ################## +v1.2.0 +****** + +Major changes: + +- New ``west grep`` command for running a "grep tool" in your west workspace's + repositories. Currently, ``git grep``, `ripgrep`_, and standard ``grep`` are + supported grep tools. + + To run this command to get ``git grep foo`` results from all cloned, + active repositories, run: + + .. code-block:: console + + west grep foo + + Here are some other examples for running different grep commands + with ``west grep``: + + .. list-table:: + + * - ``git grep --untracked`` + - ``west grep --untracked foo`` + * - ``ripgrep`` + - ``west grep --tool ripgrep foo`` + * - ``grep --recursive`` + - ``west grep --tool grep foo`` + + To switch the default grep tool in your workspace, run the appropriate + command in this table: + + .. list-table:: + + * - ``ripgrep`` + - ``west config grep.tool ripgrep`` + * - ``grep`` + - ``west config grep.tool grep`` + + For more details, run ``west help grep``. + +Other changes: + +- The manifest file format now supports a ``description`` field in each + ``projects:`` element. See :ref:`west-manifests-projects` for examples. + +- ``west list --format`` now accepts ``{description}`` in the format + string, which prints the project's ``description:`` value. + +- ``west compare`` now always prints information about + :ref:`west-manifest-rev`. + +Bug fixes: + +- ``west init`` aborts if the destination directory already exists. + +API changes: + +- ``west.commands.WestCommand`` methods ``check_call()`` and + ``check_output()`` now take any kwargs that can be passed on + to the underlying subprocess function. + +- ``west.commands.WestCommand.run_subprocess()``: new wrapper + around ``subprocess.run()``. This could not be named ``run()`` + because ``WestCommand`` already had a method by this name. + +- ``west.commands.WestCommand`` methods ``dbg()``, ``inf()``, + ``wrn()``, and ``err()`` now all take an ``end`` kwarg, which + is passed on to the call to ``print()``. + +- ``west.manifest.Project`` now has a ``description`` attribute, + which contains the parsed value of the ``description:`` field + in the manifest data. + +.. _ripgrep: https://github.com/BurntSushi/ripgrep#readme + v1.1.0 ****** From 7a27431a0c6351340d4627f5c1f37d643cd581e9 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 11 Oct 2023 12:01:08 -0700 Subject: [PATCH 2329/4498] sys: device_mmio: polish doxygen () Add marks to denote code blocks so they are rendered correctly on generated pages. () Fix misplaced in,out in @param. If any parameters are output, mark the others as input for clarity. () Also move the previously non-visible comment about the file into the doxyge group description. Signed-off-by: Daniel Leung --- include/zephyr/sys/device_mmio.h | 55 +++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/include/zephyr/sys/device_mmio.h b/include/zephyr/sys/device_mmio.h index 4358e246339..4aee3c30131 100644 --- a/include/zephyr/sys/device_mmio.h +++ b/include/zephyr/sys/device_mmio.h @@ -2,15 +2,6 @@ * Copyright (c) 2020 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 - * - * Definitions and helper macros for managing driver memory-mapped - * input/output (MMIO) regions appropriately in either RAM or ROM. - * - * In most cases drivers will just want to include device.h, but - * including this separately may be needed for arch-level driver code - * which uses the DEVICE_MMIO_TOPLEVEL variants and including the - * main device.h would introduce header dependency loops due to that - * header's reliance on kernel.h. */ #ifndef ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H #define ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H @@ -21,6 +12,16 @@ /** * @defgroup device-mmio Device memory-mapped IO management * @ingroup device_model + * + * Definitions and helper macros for managing driver memory-mapped + * input/output (MMIO) regions appropriately in either RAM or ROM. + * + * In most cases drivers will just want to include device.h, but + * including this separately may be needed for arch-level driver code + * which uses the DEVICE_MMIO_TOPLEVEL variants and including the + * main device.h would introduce header dependency loops due to that + * header's reliance on kernel.h. + * * @{ */ @@ -85,12 +86,12 @@ struct z_device_mmio_rom { * * @see k_map() * - * @param virt_addr [out] Output linear address storage location, most - * users will want some DEVICE_MMIO_RAM_PTR() value - * @param phys_addr Physical address base of the MMIO region - * @param size Size of the MMIO region - * @param flags Caching mode and access flags, see K_MEM_CACHE_* and - * K_MEM_PERM_* macros + * @param[out] virt_addr Output linear address storage location, most + * users will want some DEVICE_MMIO_RAM_PTR() value + * @param[in] phys_addr Physical address base of the MMIO region + * @param[in] size Size of the MMIO region + * @param[in] flags Caching mode and access flags, see K_MEM_CACHE_* and + * K_MEM_PERM_* macros */ __boot_func static inline void device_map(mm_reg_t *virt_addr, uintptr_t phys_addr, @@ -161,12 +162,16 @@ struct z_device_mmio_rom { * * Example for a driver named "foo": * + * @code{.c} + * * struct foo_driver_data { * DEVICE_MMIO_RAM; * int wibble; * ... * } * + * @endcode + * * No build-time initialization of this memory is necessary; it * will be set up in the init function by DEVICE_MMIO_MAP(). * @@ -210,12 +215,16 @@ struct z_device_mmio_rom { * * Example for a driver named "foo": * + * @code{.c} + * * struct foo_config { * DEVICE_MMIO_ROM; * int baz; * ... * } * + * @endcode + * * @see DEVICE_MMIO_ROM_INIT() */ #define DEVICE_MMIO_ROM struct z_device_mmio_rom _mmio @@ -240,12 +249,16 @@ struct z_device_mmio_rom { * * Example for a driver belonging to the "foo" subsystem: * + * @code{.c} + * * struct foo_config my_config = { * DEVICE_MMIO_ROM_INIT(DT_DRV_INST(...)), * .baz = 2; * ... * } * + * @endcode + * * @see DEVICE_MMIO_ROM() * * @param node_id DTS node_id @@ -332,6 +345,8 @@ struct z_device_mmio_rom { * * Example for a driver named "foo": * + * @code{.c} + * * struct foo_driver_data { * int blarg; * DEVICE_MMIO_NAMED_RAM(corge); @@ -340,6 +355,8 @@ struct z_device_mmio_rom { * ... * } * + * @endcode + * * No build-time initialization of this memory is necessary; it * will be set up in the init function by DEVICE_MMIO_NAMED_MAP(). * @@ -385,6 +402,8 @@ struct z_device_mmio_rom { * * Example for a driver named "foo": * + * @code{.c} + * * struct foo_config { * int bar; * DEVICE_MMIO_NAMED_ROM(corge); @@ -393,6 +412,8 @@ struct z_device_mmio_rom { * ... * } * + * @endcode + * * @see DEVICE_MMIO_NAMED_ROM_INIT() * * @param name Member name to store within config @@ -422,6 +443,8 @@ struct z_device_mmio_rom { * Example for an instance of a driver belonging to the "foo" subsystem * that will have two regions named 'corge' and 'grault': * + * @code{.c} + * * struct foo_config my_config = { * bar = 7; * DEVICE_MMIO_NAMED_ROM_INIT(corge, DT_DRV_INST(...)); @@ -430,6 +453,8 @@ struct z_device_mmio_rom { * ... * } * + * @endcode + * * @see DEVICE_MMIO_NAMED_ROM() * * @param name Member name within config for the MMIO region From 9ac85254961012dd6f26962c2bc1cade8f2abd8d Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 29 Sep 2023 09:09:58 +0200 Subject: [PATCH 2330/4498] boards: nrf5340dk_nrf5340: Add default HW flow control pins to uart1 Add the default HW flow control pins to the uart1 node. Signed-off-by: Joakim Andersson --- .../nrf5340_cpuapp_common-pinctrl.dtsi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi index 6db9767c0dc..f93e3a69402 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi @@ -84,10 +84,12 @@ uart1_default: uart1_default { group1 { - psels = ; + psels = , + ; }; group2 { - psels = ; + psels = , + ; bias-pull-up; }; }; @@ -95,7 +97,9 @@ uart1_sleep: uart1_sleep { group1 { psels = , - ; + , + , + ; low-power-enable; }; }; From f9874ca046abbaf74ef045c1a001b4fd108ebcc7 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 20 Oct 2023 16:35:38 +0200 Subject: [PATCH 2331/4498] west.yaml: Bump hal_atmel to commit #120 This commit bumps the hal_atmel module to revision 942d664e48f7a2725933a93facc112b87b1de32b, which is commit number 120 on master. Signed-off-by: Bjarki Arge Andreasen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 8866ec48a78..04bf704eb5b 100644 --- a/west.yml +++ b/west.yml @@ -150,7 +150,7 @@ manifest: groups: - hal - name: hal_atmel - revision: 5ab43007eda3f380c125f957f03638d2e8d1144d + revision: 942d664e48f7a2725933a93facc112b87b1de32b path: modules/hal/atmel groups: - hal From be83225ee6e8352cd8d02fb21ac578e71ca87d6d Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 20 Oct 2023 14:54:28 +0100 Subject: [PATCH 2332/4498] drivers: sensor: npm1300: Fixed charge current scaling The scaling factor for current measurement was incorrect. Full range scaling during charge is 1.25 * charge current limit, and there is no additional scaling factor applied in different charge modes. Signed-off-by: Andy Sinclair --- drivers/sensor/npm1300_charger/npm1300_charger.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c index 43ac54e8ca8..95634a0a506 100644 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -159,13 +159,11 @@ static void calc_current(const struct npm1300_charger_config *const config, full_scale_ma = config->dischg_limit_microamp / 1000; break; case IBAT_STAT_CHARGE_TRICKLE: - full_scale_ma = -config->current_microamp / 10000; - break; + /* Fallthrough */ case IBAT_STAT_CHARGE_COOL: - full_scale_ma = -config->current_microamp / 2000; - break; + /* Fallthrough */ case IBAT_STAT_CHARGE_NORMAL: - full_scale_ma = -config->current_microamp / 1000; + full_scale_ma = -config->current_microamp / 800; break; default: full_scale_ma = 0; From 7c43370997305804efed299a67f32bd78d1735e0 Mon Sep 17 00:00:00 2001 From: Jay Vasanth Date: Wed, 18 Oct 2023 11:59:13 -0400 Subject: [PATCH 2333/4498] microchip: ps2: fix compilation error fix compilation error when CONFIG_PM_DEVICE is not enabled Signed-off-by: Jay Vasanth --- drivers/ps2/ps2_mchp_xec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ps2/ps2_mchp_xec.c b/drivers/ps2/ps2_mchp_xec.c index ccd2957982e..f3b1a9e10bf 100644 --- a/drivers/ps2/ps2_mchp_xec.c +++ b/drivers/ps2/ps2_mchp_xec.c @@ -16,10 +16,8 @@ #include #endif #include -#ifdef CONFIG_PM_DEVICE #include #include -#endif #include #include #include From 1860af4bf4cfbf81ea85463ebb4bc35b5271b8e2 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 20 Oct 2023 13:43:33 +0300 Subject: [PATCH 2334/4498] tests: profiling: Remove unused Kconfig Remove unused Kconfig with unused KERNEL_PROFILING_API_TEST. Signed-off-by: Andrei Emeltchenko --- tests/kernel/profiling/profiling_api/Kconfig | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 tests/kernel/profiling/profiling_api/Kconfig diff --git a/tests/kernel/profiling/profiling_api/Kconfig b/tests/kernel/profiling/profiling_api/Kconfig deleted file mode 100644 index 658baad0aa8..00000000000 --- a/tests/kernel/profiling/profiling_api/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -config KERNEL_PROFILING_API_TEST - bool - default y - help - Hidden option enabling LPS_0 power state regardless of hardware - support. This ensures that power management hooks used in this - test to profile idle thread will be executed. - -# Include Zephyr's Kconfig. -source "Kconfig" From b1c207524b09e3cfe48ddfc42d7abd3d860afeb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 20 Oct 2023 17:59:05 +0200 Subject: [PATCH 2335/4498] ci: github: Only build docs for zephyrproject-rtos GH org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As documentation is now built using one of our self-hosted runners, have the GitHub action only run for the upstream repo, not for potential forks. Signed-off-by: Benjamin Cabé --- .github/workflows/doc-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 7100c451629..c1fed2dc333 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -35,6 +35,7 @@ env: jobs: doc-build-html: name: "Documentation Build (HTML)" + if: github.repository_owner == 'zephyrproject-rtos' runs-on: zephyr-runner-linux-x64-4xlarge timeout-minutes: 45 concurrency: @@ -130,7 +131,9 @@ jobs: doc-build-pdf: name: "Documentation Build (PDF)" - if: github.event_name != 'pull_request' + if: | + github.event_name != 'pull_request' && + github.repository_owner == 'zephyrproject-rtos' runs-on: zephyr-runner-linux-x64-4xlarge container: texlive/texlive:latest timeout-minutes: 60 From f97ac476f33f68d84f81c37a07e7214df34e1554 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 09:35:15 +0200 Subject: [PATCH 2336/4498] libC Kconfig: Do not default to picolibc for native_sim due to GETOPT Defaulting to picolibc when selecting GETOPT is a bit nicer for users in some cases, but not required. But too many things require GETOPT (for ex. some SHELL configurations) in combinations with native posix drivers which do not support yet embedded libcs (for ex. the native USB driver) (see https://github.com/zephyrproject-rtos/zephyr/issues/60096 ) Which leads to configurations in those cases which cannot be built. Keep defaulting to the external libC in this case. This reverts the getop part of this commit: 5f8057e26211e0ce69c782adfbfe511fa27b598d Signed-off-by: Alberto Escolar Piedras --- lib/libc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 540dc1e782a..1ee19062e38 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -53,7 +53,7 @@ menu "C Library" choice LIBC_IMPLEMENTATION prompt "C Library Implementation" - default EXTERNAL_LIBC if NATIVE_BUILD && !(NATIVE_LIBRARY && (POSIX_API || GETOPT)) + default EXTERNAL_LIBC if NATIVE_BUILD && !(NATIVE_LIBRARY && POSIX_API) default PICOLIBC default NEWLIB_LIBC if REQUIRES_FULL_LIBC default MINIMAL_LIBC From fd8f6bd7e61b7539f3c2b2a2f48b8ec70e05f439 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Mon, 2 Oct 2023 09:57:32 +0200 Subject: [PATCH 2337/4498] manifest: hal_nordic: Update nrf_802154 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit brings latest changes to the nRF 802.15.4 Radio Driver. Signed-off-by: Andrzej Kuroś --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 04bf704eb5b..28882981459 100644 --- a/west.yml +++ b/west.yml @@ -186,7 +186,7 @@ manifest: groups: - hal - name: hal_nordic - revision: d054a315eb888ba70e09e5f6decd4097b0276d1f + revision: 275548e2dca9e855a134d67f82375ba17b285b5d path: modules/hal/nordic groups: - hal From 0cfca8be858ac4303154cdc8ab42eb05476d232a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 3 Oct 2023 11:01:09 +0200 Subject: [PATCH 2338/4498] drivers: can: add accessor functions for the CAN statistics Add accessor functions for the individual CAN statistics. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_handlers.c | 60 +++++++++++++ include/zephyr/drivers/can.h | 158 +++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index e5a8d57b6aa..842c3786d5d 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -243,3 +243,63 @@ static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeo } #include #endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */ + +#ifdef CONFIG_CAN_STATS + +static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_bit0_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_bit1_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_bit1_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_stuff_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_stuff_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_crc_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_crc_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_form_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_form_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_ack_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_ack_errors(dev); +} +#include + +static inline uint32_t z_vrfy_can_stats_get_rx_overruns(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_rx_overruns(dev); +} +#include + +#endif /* CONFIG_CAN_STATS */ diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 54a75b93dc3..4f2b2c1f2fb 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -971,6 +971,8 @@ static inline int z_impl_can_get_capabilities(const struct device *dev, can_mode * enable the CAN controller to participate in CAN communication, and enable the CAN tranceiver, if * supported. * + * Starting the CAN controller resets all the CAN controller statistics. + * * @see can_stop() * @see can_transceiver_enable() * @@ -1333,6 +1335,162 @@ static inline void can_set_state_change_callback(const struct device *dev, /** @} */ +/** + * @name CAN statistics + * + * @{ + */ + +/** + * @brief Get the bit0 error counter for a CAN device + * + * The bit0 error counter is incremented when the CAN controller is unable to + * transmit a dominant bit. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return bit0 error counter + */ +__syscall uint32_t can_stats_get_bit0_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_bit0_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).bit0_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the bit1 error counter for a CAN device + * + * The bit1 error counter is incremented when the CAN controller is unable to + * transmit a recessive bit. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return bit1 error counter + */ +__syscall uint32_t can_stats_get_bit1_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_bit1_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).bit1_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the stuffing error counter for a CAN device + * + * The stuffing error counter is incremented when the CAN controller detects a + * bit stuffing error. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return stuffing error counter + */ +__syscall uint32_t can_stats_get_stuff_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_stuff_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).stuff_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the CRC error counter for a CAN device + * + * The CRC error counter is incremented when the CAN controller detects a frame + * with an invalid CRC. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return CRC error counter + */ +__syscall uint32_t can_stats_get_crc_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_crc_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).crc_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the form error counter for a CAN device + * + * The form error counter is incremented when the CAN controller detects a + * fixed-form bit field containing illegal bits. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return form error counter + */ +__syscall uint32_t can_stats_get_form_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_form_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).form_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the acknowledge error counter for a CAN device + * + * The acknowledge error counter is incremented when the CAN controller does not + * monitor a dominant bit in the ACK slot. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return acknowledge error counter + */ +__syscall uint32_t can_stats_get_ack_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_ack_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).ack_error; +} +#endif /* CONFIG_CAN_STATS */ + +/** + * @brief Get the RX overrun counter for a CAN device + * + * The RX overrun counter is incremented when the CAN controller receives a CAN + * frame matching an installed filter but lacks the capacity to store it (either + * due to an already full RX mailbox or a full RX FIFO). + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return RX overrun counter + */ +__syscall uint32_t can_stats_get_rx_overruns(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_rx_overruns(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).rx_overrun; +} +#endif /* CONFIG_CAN_STATS */ + +/** @} */ + /** * @name CAN utility functions * From 8beb0a356498ed0b845a48d0c6f6db85e50707ed Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 3 Oct 2023 11:18:55 +0200 Subject: [PATCH 2339/4498] tests: drivers: can: api: add simple test for CAN stats accessors Add a simple test to validate that the CAN statistics accessor functions can be called from user mode threads. Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/api/CMakeLists.txt | 1 + tests/drivers/can/api/prj.conf | 2 ++ tests/drivers/can/api/src/stats.c | 44 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 tests/drivers/can/api/src/stats.c diff --git a/tests/drivers/can/api/CMakeLists.txt b/tests/drivers/can/api/CMakeLists.txt index 5468c766cd3..fb936332e04 100644 --- a/tests/drivers/can/api/CMakeLists.txt +++ b/tests/drivers/can/api/CMakeLists.txt @@ -8,3 +8,4 @@ target_sources(app PRIVATE src/common.c) target_sources(app PRIVATE src/classic.c) target_sources(app PRIVATE src/utilities.c) target_sources_ifdef(CONFIG_CAN_FD_MODE app PRIVATE src/canfd.c) +target_sources_ifdef(CONFIG_CAN_STATS app PRIVATE src/stats.c) diff --git a/tests/drivers/can/api/prj.conf b/tests/drivers/can/api/prj.conf index dfd79c22526..a163dc5077f 100644 --- a/tests/drivers/can/api/prj.conf +++ b/tests/drivers/can/api/prj.conf @@ -1,6 +1,8 @@ CONFIG_CAN=y CONFIG_CAN_FD_MODE=y CONFIG_CAN_AUTO_BUS_OFF_RECOVERY=n +CONFIG_STATS=y +CONFIG_CAN_STATS=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST=y # The canfd test suite may be skipped diff --git a/tests/drivers/can/api/src/stats.c b/tests/drivers/can/api/src/stats.c new file mode 100644 index 00000000000..85320dc64ca --- /dev/null +++ b/tests/drivers/can/api/src/stats.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Vestas Wind Systems A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "common.h" + +/** + * @addtogroup t_driver_can + * @{ + * @defgroup t_can_stats test_can_stats + * @} + */ + +/** + * @brief Test that CAN statistics can be accessed from user mode threads. + */ +ZTEST_USER(can_stats, test_can_stats_accessors) +{ + uint32_t val; + + val = can_stats_get_bit0_errors(can_dev); + val = can_stats_get_bit1_errors(can_dev); + val = can_stats_get_stuff_errors(can_dev); + val = can_stats_get_crc_errors(can_dev); + val = can_stats_get_form_errors(can_dev); + val = can_stats_get_ack_errors(can_dev); + val = can_stats_get_rx_overruns(can_dev); +} + +void *can_stats_setup(void) +{ + k_object_access_grant(can_dev, k_current_get()); + + zassert_true(device_is_ready(can_dev), "CAN device not ready"); + + return NULL; +} + +ZTEST_SUITE(can_stats, NULL, can_stats_setup, NULL, NULL, NULL); From 1f779fa4428115e2f1b9598a943fd5cc6dbb746e Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 3 Oct 2023 11:03:36 +0200 Subject: [PATCH 2340/4498] drivers: can: shell: print CAN statistics when showing CAN details Print the CAN statistics when showing CAN controller details. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_shell.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index e07de338952..bc0286d2ea6 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -362,6 +362,17 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) timing_min->prescaler, timing_max->prescaler); } +#ifdef CONFIG_CAN_STATS + shell_print(sh, "statistics:"); + shell_print(sh, " bit0 errors: %u", can_stats_get_bit0_errors(dev)); + shell_print(sh, " bit1 errors: %u", can_stats_get_bit1_errors(dev)); + shell_print(sh, " stuff errors: %u", can_stats_get_stuff_errors(dev)); + shell_print(sh, " crc errors: %u", can_stats_get_crc_errors(dev)); + shell_print(sh, " form errors: %u", can_stats_get_form_errors(dev)); + shell_print(sh, " ack errors: %u", can_stats_get_ack_errors(dev)); + shell_print(sh, " rx overruns: %u", can_stats_get_rx_overruns(dev)); +#endif /* CONFIG_CAN_STATS */ + return 0; } From d9b69f9d33c363b040589c786ab5d72f2dda0cd1 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 3 Oct 2023 14:45:51 +0200 Subject: [PATCH 2341/4498] drivers: can: mcp2515: add CAN statistics support Add support for CAN statistics to the Microchip MCP2515 CAN controller driver. The hardware only supports reporting RX overruns. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcp2515.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 703aeb1543d..df403dfac62 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -451,6 +451,8 @@ static int mcp2515_start(const struct device *dev) } } + CAN_STATS_RESET(dev); + k_mutex_lock(&dev_data->mutex, K_FOREVER); ret = mcp2515_set_mode_int(dev, dev_data->mcp2515_mode); @@ -762,6 +764,20 @@ static int mcp2515_get_state(const struct device *dev, enum can_state *state, err_cnt->rx_err_cnt = err_cnt_buf[1]; } +#ifdef CONFIG_CAN_STATS + if ((eflg & (MCP2515_EFLG_RX0OVR | MCP2515_EFLG_RX1OVR)) != 0U) { + CAN_STATS_RX_OVERRUN_INC(dev); + + ret = mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_EFLG, + eflg & (MCP2515_EFLG_RX0OVR | MCP2515_EFLG_RX1OVR), + 0U); + if (ret < 0) { + LOG_ERR("Failed to clear RX overrun flags [%d]", ret); + return -EIO; + } + } +#endif /* CONFIG_CAN_STATS */ + return 0; } From 9b9fb685ecbb8c1c2386f5f35572fa10f6af6741 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 3 Oct 2023 15:19:35 +0200 Subject: [PATCH 2342/4498] boards/arm/ruuvi_ruuvitag: enable the console driver The Ruuvitag board selects the `uart0` node as `zephyr,console` in the `chosen` node. This required three options to be y-selected on Kconfig side so that printf/stdout etc. hooks are properly installed: * CONFIG_CONSOLE * CONFIG_SERIAL * CONFIG_UART_CONSOLE Without that, no console output is observed. Signed-off-by: Filip Kokosinski --- boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig index 7e28dde8423..08403e5d814 100644 --- a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig @@ -8,6 +8,11 @@ CONFIG_BOARD_RUUVI_RUUVITAG=y # Enable MPU CONFIG_ARM_MPU=y +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y + # Enable RTT CONFIG_USE_SEGGER_RTT=y From 251926b3320a0ad4cd93560eb937af06ab55c57d Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 3 Oct 2023 15:22:16 +0200 Subject: [PATCH 2343/4498] boards/arm/mikroe_clicker_2: enable the console driver The MikroE clicker 2 board selects the `uart4` node as `zephyr,console` in the `chosen` node. This required one additional option to be y-selected on Kconfig side so that printf/stdout etc. hooks are properly installed: * CONFIG_UART_CONSOLE Without that, no console output is observed. Signed-off-by: Filip Kokosinski --- boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig b/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig index 0d46fd7c84e..15ade5bcf58 100644 --- a/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig +++ b/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig @@ -9,6 +9,7 @@ CONFIG_SERIAL=y # console CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y # enable GPIO CONFIG_GPIO=y From 3549d816a10a231a7167d8f65e87c98f56754980 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 3 Oct 2023 15:23:26 +0200 Subject: [PATCH 2344/4498] boards/arm/nrf52840_mdk_usb_dongle: enable the console driver The nRF52840 MDK USB Dongle board selects the `uart0` node as `zephyr,console` in the `chosen` node. This required three additional options to be y-selected on Kconfig side so that printf/stdout etc. hooks are properly installed: * CONFIG_CONSOLE * CONFIG_SERIAL * CONFIG_UART_CONSOLE Without that, no console output is observed. Signed-off-by: Filip Kokosinski --- .../nrf52840_mdk_usb_dongle_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index c76e57e17a9..63decf69707 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -7,6 +7,11 @@ CONFIG_BOARD_NRF52840_MDK_USB_DONGLE=y # Enable MPU CONFIG_ARM_MPU=y +# Console +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + # Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y From 2aabcabad3677166520edf0d885eb827ca857f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 14:36:23 +0200 Subject: [PATCH 2345/4498] usbc: add function that prevents the USB-C stack from sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add internal function that prevents one sleep of the USB-C stack. It can allow to have longer sleep times to conserve more power, while still having possibility to respond in the required time and set specific registers. Signed-off-by: Michał Barnaś --- include/zephyr/usb_c/usbc.h | 9 +++++++++ subsys/usb/usb_c/usbc_stack.c | 14 +++++++++++++- subsys/usb/usb_c/usbc_stack.h | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/zephyr/usb_c/usbc.h b/include/zephyr/usb_c/usbc.h index 0a37b081838..db3045d03c1 100644 --- a/include/zephyr/usb_c/usbc.h +++ b/include/zephyr/usb_c/usbc.h @@ -350,6 +350,15 @@ int usbc_suspend(const struct device *dev); */ int usbc_request(const struct device *dev, const enum usbc_policy_request_t req); +/** + * @internal + * @brief Bypass the next USB-C stack sleep and execute one more iteration of the state machines. + * Used internally to decrease the response time. + * + * @param dev Runtime device structure + */ +void usbc_bypass_next_sleep(const struct device *dev); + /** * @brief Set pointer to Device Policy Manager (DPM) data * diff --git a/subsys/usb/usb_c/usbc_stack.c b/subsys/usb/usb_c/usbc_stack.c index 7620a3c8cc8..08ac7cd3cb7 100644 --- a/subsys/usb/usb_c/usbc_stack.c +++ b/subsys/usb/usb_c/usbc_stack.c @@ -37,7 +37,12 @@ static ALWAYS_INLINE void usbc_handler(void *port_dev) k_thread_suspend(port->port_thread); } - k_msleep(CONFIG_USBC_STATE_MACHINE_CYCLE_TIME); + /* Check if there wasn't any request to do a one more iteration of USB-C state machines */ + if (!port->bypass_next_sleep) { + k_msleep(CONFIG_USBC_STATE_MACHINE_CYCLE_TIME); + } else { + port->bypass_next_sleep = false; + } } #define USBC_SUBSYS_INIT(inst) \ @@ -133,6 +138,13 @@ int usbc_request(const struct device *dev, const enum usbc_policy_request_t req) return 0; } +void usbc_bypass_next_sleep(const struct device *dev) +{ + struct usbc_port_data *data = dev->data; + + data->bypass_next_sleep = true; +} + /** * @brief Sets the Device Policy Manager's data */ diff --git a/subsys/usb/usb_c/usbc_stack.h b/subsys/usb/usb_c/usbc_stack.h index 93a09130534..ca95f05f317 100644 --- a/subsys/usb/usb_c/usbc_stack.h +++ b/subsys/usb/usb_c/usbc_stack.h @@ -107,6 +107,9 @@ struct usbc_port_data { /** Device Policy manager Request */ struct request_value request; + /** Bypass next sleep and request one more iteration of the USB-C state machines */ + bool bypass_next_sleep; + /* USB-C Callbacks */ /** From 6fc22462a342d66d6062ef78fb74da17f63560f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Wed, 23 Aug 2023 14:40:27 +0200 Subject: [PATCH 2346/4498] usbc: add sleep prevention in places that may require it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sleep prevention in crucial USB-C stack functions to make state transitions faster and to send responses faster. Signed-off-by: Michał Barnaś --- subsys/usb/usb_c/usbc_pe_common.c | 6 ++++++ subsys/usb/usb_c/usbc_tc_snk_states.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/subsys/usb/usb_c/usbc_pe_common.c b/subsys/usb/usb_c/usbc_pe_common.c index 8c2e8d1fcf9..cc59cecbadc 100644 --- a/subsys/usb/usb_c/usbc_pe_common.c +++ b/subsys/usb/usb_c/usbc_pe_common.c @@ -345,6 +345,9 @@ void pe_message_received(const struct device *dev) struct policy_engine *pe = data->pe; atomic_set_bit(pe->flags, PE_FLAGS_MSG_RECEIVED); + + /* Allow the PE to be executed once more and respond faster for the received message */ + usbc_bypass_next_sleep(dev); } /** @@ -422,6 +425,9 @@ void pe_set_state(const struct device *dev, const enum usbc_pe_state state) __ASSERT(state < ARRAY_SIZE(pe_states), "invalid pe_state %d", state); smf_set_state(SMF_CTX(data->pe), &pe_states[state]); + + /* Allow the PE to execute logic from the new state without additional delay */ + usbc_bypass_next_sleep(dev); } /** diff --git a/subsys/usb/usb_c/usbc_tc_snk_states.c b/subsys/usb/usb_c/usbc_tc_snk_states.c index 273f4bacdbd..11cc456acfb 100644 --- a/subsys/usb/usb_c/usbc_tc_snk_states.c +++ b/subsys/usb/usb_c/usbc_tc_snk_states.c @@ -79,7 +79,15 @@ static void sink_power_sub_states(const struct device *dev) */ void tc_unattached_snk_entry(void *obj) { + struct tc_sm_t *tc = (struct tc_sm_t *)obj; + LOG_INF("Unattached.SNK"); + + /* + * Allow the state machine to immediately check the state of CC lines and go into + * Attach.Wait state in case the Rp value is detected on the CC lines + */ + usbc_bypass_next_sleep(tc->dev); } /** @@ -109,6 +117,12 @@ void tc_attach_wait_snk_entry(void *obj) LOG_INF("AttachWait.SNK"); tc->cc_state = TC_CC_NONE; + + /* + * Allow the debounce timers to start immediately without additional delay added + * by going into sleep + */ + usbc_bypass_next_sleep(tc->dev); } /** @@ -138,6 +152,11 @@ void tc_attach_wait_snk_run(void *obj) /* Wait for CC debounce */ if (usbc_timer_running(&tc->tc_t_cc_debounce) && usbc_timer_expired(&tc->tc_t_cc_debounce) == false) { + if (CONFIG_USBC_STATE_MACHINE_CYCLE_TIME >= TC_T_CC_DEBOUNCE_MIN_MS) { + /* Make sure the debounce time won't be longer than specified */ + usbc_bypass_next_sleep(tc->dev); + } + return; } @@ -156,6 +175,13 @@ void tc_attach_wait_snk_run(void *obj) if (vbus_present) { tc_set_state(dev, TC_ATTACHED_SNK_STATE); } + + /* + * In case of no VBUS present, this call prevents going into the sleep and allows for + * faster VBUS detection. In case of VBUS present, allows for immediate execution of logic + * from new state. + */ + usbc_bypass_next_sleep(tc->dev); } void tc_attach_wait_snk_exit(void *obj) From 19e32dc31e80d9021c8583aa09be9d9aa8748604 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 10 Oct 2023 17:37:57 +0300 Subject: [PATCH 2347/4498] drivers: timer: Refactor x86 system timer selection Refactor timer selection to allow to select only one timer. Signed-off-by: Andrei Emeltchenko --- boards/x86/up_squared/Kconfig.defconfig | 3 - drivers/timer/Kconfig | 3 +- drivers/timer/Kconfig.hpet | 17 ------ drivers/timer/{Kconfig.apic => Kconfig.x86} | 61 ++++++++++++++------- 4 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 drivers/timer/Kconfig.hpet rename drivers/timer/{Kconfig.apic => Kconfig.x86} (81%) diff --git a/boards/x86/up_squared/Kconfig.defconfig b/boards/x86/up_squared/Kconfig.defconfig index 659ecc336ef..cf1128a7d26 100644 --- a/boards/x86/up_squared/Kconfig.defconfig +++ b/boards/x86/up_squared/Kconfig.defconfig @@ -15,9 +15,6 @@ config HEAP_MEM_POOL_SIZE config BUILD_OUTPUT_STRIPPED default y -config APIC_TSC_DEADLINE_TIMER - default y - # TSC on this board is 1.5936 GHz, HPET and APIC are 19.2 MHz config SYS_CLOCK_HW_CYCLES_PER_SEC default 1593600000 if APIC_TSC_DEADLINE_TIMER diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index fb615c2b7cf..8a88e731986 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -65,7 +65,7 @@ config SYSTEM_CLOCK_LOCK_FREE_COUNT source "drivers/timer/Kconfig.altera_avalon" source "drivers/timer/Kconfig.ambiq" -source "drivers/timer/Kconfig.apic" +source "drivers/timer/Kconfig.x86" source "drivers/timer/Kconfig.arcv2" source "drivers/timer/Kconfig.arm_arch" source "drivers/timer/Kconfig.cavs" @@ -73,7 +73,6 @@ source "drivers/timer/Kconfig.cc13xx_cc26xx_rtc" source "drivers/timer/Kconfig.cortex_m_systick" source "drivers/timer/Kconfig.esp32c3_sys" source "drivers/timer/Kconfig.gecko" -source "drivers/timer/Kconfig.hpet" source "drivers/timer/Kconfig.ite_it8xxx2" source "drivers/timer/Kconfig.leon_gptimer" source "drivers/timer/Kconfig.litex" diff --git a/drivers/timer/Kconfig.hpet b/drivers/timer/Kconfig.hpet deleted file mode 100644 index c83af2b4615..00000000000 --- a/drivers/timer/Kconfig.hpet +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2014-2015 Wind River Systems, Inc. -# Copyright (c) 2016 Cadence Design Systems, Inc. -# Copyright (c) 2019 Intel Corp. -# SPDX-License-Identifier: Apache-2.0 - -config HPET_TIMER - bool "HPET timer" - default y - depends on DT_HAS_INTEL_HPET_ENABLED - select IOAPIC if X86 - select LOAPIC if X86 - imply TIMER_READS_ITS_FREQUENCY_AT_RUNTIME - select TICKLESS_CAPABLE - select TIMER_HAS_64BIT_CYCLE_COUNTER - help - This option selects High Precision Event Timer (HPET) as a - system timer. diff --git a/drivers/timer/Kconfig.apic b/drivers/timer/Kconfig.x86 similarity index 81% rename from drivers/timer/Kconfig.apic rename to drivers/timer/Kconfig.x86 index 5e745beb945..8e82580eb72 100644 --- a/drivers/timer/Kconfig.apic +++ b/drivers/timer/Kconfig.x86 @@ -1,12 +1,30 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Cadence Design Systems, Inc. -# Copyright (c) 2019 Intel Corp. +# Copyright (c) 2019-2023 Intel Corp. # SPDX-License-Identifier: Apache-2.0 -menuconfig APIC_TIMER - bool "New local APIC timer" +choice + prompt "Default System Timer" + default HPET depends on X86 - depends on LOAPIC + help + Select Default System Timer. + +config HPET_TIMER + bool "HPET timer" + depends on DT_HAS_INTEL_HPET_ENABLED + select IOAPIC + select LOAPIC + imply TIMER_READS_ITS_FREQUENCY_AT_RUNTIME + select TICKLESS_CAPABLE + select TIMER_HAS_64BIT_CYCLE_COUNTER + help + This option selects High Precision Event Timer (HPET) as a + system timer. + +config APIC_TIMER + bool "Local APIC timer" + select LOAPIC select TICKLESS_CAPABLE select SYSTEM_CLOCK_LOCK_FREE_COUNT help @@ -16,6 +34,24 @@ menuconfig APIC_TIMER without complete APIC emulation). Modern hardware will work better with CONFIG_APIC_TSC_DEADLINE_TIMER. +config APIC_TSC_DEADLINE_TIMER + bool "Local APIC timer using TSC deadline mode" + select LOAPIC + select TICKLESS_CAPABLE + select TIMER_HAS_64BIT_CYCLE_COUNTER + help + Extremely simple timer driver based the local APIC TSC + deadline capability. The use of a free-running 64 bit + counter with comparator eliminates almost all edge cases + from the handling, and the near-instruction-cycle resolution + permits effectively unlimited precision where needed (the + limit becomes the CPU time taken to execute the timing + logic). SMP-safe and very fast, this should be the obvious + choice for any x86 device with invariant TSC and TSC + deadline capability. + +endchoice + if APIC_TIMER config APIC_TIMER_IRQ @@ -52,23 +88,6 @@ endif # APIC_TIMER_TSC endif # APIC_TIMER -config APIC_TSC_DEADLINE_TIMER - bool "Even newer APIC timer using TSC deadline mode" - depends on X86 - select LOAPIC - select TICKLESS_CAPABLE - select TIMER_HAS_64BIT_CYCLE_COUNTER - help - Extremely simple timer driver based the local APIC TSC - deadline capability. The use of a free-running 64 bit - counter with comparator eliminates almost all edge cases - from the handling, and the near-instruction-cycle resolution - permits effectively unlimited precision where needed (the - limit becomes the CPU time taken to execute the timing - logic). SMP-safe and very fast, this should be the obvious - choice for any x86 device with invariant TSC and TSC - deadline capability. - config APIC_TIMER_IRQ_PRIORITY int "Local APIC timer interrupt priority" depends on APIC_TIMER || APIC_TSC_DEADLINE_TIMER From d6035f4a26e08ca6ca2b875f84910865fea1d43d Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 11 Oct 2023 12:23:04 +0300 Subject: [PATCH 2348/4498] drivers: timer: Select APIC_TSC_DEADLINE_TIMER by default Select APIC_TSC_DEADLINE_TIMER as default timer for x86. Signed-off-by: Andrei Emeltchenko --- drivers/timer/Kconfig.x86 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.x86 b/drivers/timer/Kconfig.x86 index 8e82580eb72..58d0fc24519 100644 --- a/drivers/timer/Kconfig.x86 +++ b/drivers/timer/Kconfig.x86 @@ -5,7 +5,7 @@ choice prompt "Default System Timer" - default HPET + default APIC_TSC_DEADLINE_TIMER depends on X86 help Select Default System Timer. From 4e946262cbcf712e01c9d9d631d3f843789e6c91 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 11 Oct 2023 14:06:21 +0300 Subject: [PATCH 2349/4498] boards: ish: Continue to use HPET_TIMER for ISH and Qemu Fot Qemu and intel_ish boards continue to use HPET_TIMER. Signed-off-by: Andrei Emeltchenko --- boards/x86/intel_ish/Kconfig.defconfig | 3 --- drivers/timer/Kconfig.x86 | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/boards/x86/intel_ish/Kconfig.defconfig b/boards/x86/intel_ish/Kconfig.defconfig index f989dfcd6ed..1f3d6809643 100644 --- a/boards/x86/intel_ish/Kconfig.defconfig +++ b/boards/x86/intel_ish/Kconfig.defconfig @@ -16,9 +16,6 @@ config TEST_EXTRA_STACK_SIZE default 1024 endif # TEST -config HPET_TIMER - default y - config SYS_CLOCK_TICKS_PER_SEC default 2048 if HPET_TIMER # HPET is 32768 HZ diff --git a/drivers/timer/Kconfig.x86 b/drivers/timer/Kconfig.x86 index 58d0fc24519..aa5f1a9c6d6 100644 --- a/drivers/timer/Kconfig.x86 +++ b/drivers/timer/Kconfig.x86 @@ -5,6 +5,7 @@ choice prompt "Default System Timer" + default HPET_TIMER if SOC_FAMILY_INTEL_ISH || SOC_IA32 || SOC_LAKEMONT default APIC_TSC_DEADLINE_TIMER depends on X86 help From 2e828eb6e7d4ea16b0f40f167ebaf5aa6b5cd7f9 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Wed, 18 Oct 2023 18:58:17 -0500 Subject: [PATCH 2350/4498] ci: Fix license check false pass The license check workflow quietly stopped working after commit 8f66f854c3238d67de7c64da86a3de18bf3e4683. Upgrading the checkout action changed default behavior to only fetch one commit instead of all history for all branches, which caused an uncaught fatal error in the scancode action: fatal: ambiguous argument 'origin/main..': unknown revision or path not in the working tree. The scancode action then completed successfully having not actually checked anything. Fix this by setting the checkout action fetch depth to 0, similar to other workflows. Signed-off-by: Maureen Helm --- .github/workflows/license_check.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index dd4e1928a2d..0efedb13489 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -9,6 +9,8 @@ jobs: steps: - name: Checkout the code uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Scan the code id: scancode uses: zephyrproject-rtos/action_scancode@v4 From eab871a1ffd79065bf1df45587965a34aab60d85 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 10:51:54 +0200 Subject: [PATCH 2351/4498] ipc: backend: rpmsg: Add support for POSIX arch To enable runninng and testing this backend on the POSIX architecture, we need to allow defining the shared memory buffer as a compiler provided symbol, instead of a hard address provided by the DTS. For this case we refer to a symbol a POSIX arch implementation (typically the board) needs to provide. It is the responsability of that implementation to ensure that symbol exists and points to a memory buffer of the DT defined size. Signed-off-by: Alberto Escolar Piedras --- .../ipc_service/backends/ipc_rpmsg_static_vrings.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c index 41f0a77ea22..dcbff7b360c 100644 --- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c +++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c @@ -774,11 +774,21 @@ static int backend_init(const struct device *instance) return 0; } + +#if defined(CONFIG_ARCH_POSIX) +#define BACKEND_PRE(i) extern char IPC##i##_shm_buffer[]; +#define BACKEND_SHM_ADDR(i) (const uintptr_t)IPC##i##_shm_buffer +#else +#define BACKEND_PRE(i) +#define BACKEND_SHM_ADDR(i) DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)) +#endif /* defined(CONFIG_ARCH_POSIX) */ + #define DEFINE_BACKEND_DEVICE(i) \ + BACKEND_PRE(i) \ static struct backend_config_t backend_config_##i = { \ .role = DT_ENUM_IDX_OR(DT_DRV_INST(i), role, ROLE_HOST), \ .shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, memory_region)), \ - .shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \ + .shm_addr = BACKEND_SHM_ADDR(i), \ .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ .wq_prio = COND_CODE_1(DT_INST_NODE_HAS_PROP(i, zephyr_priority), \ From 68b9cea69040bd5399c7d4409807e635d6e42f7e Mon Sep 17 00:00:00 2001 From: Dave Desrochers Date: Thu, 19 Oct 2023 11:16:31 -0700 Subject: [PATCH 2352/4498] arch: Fixes potential mangled isr table when SHARED_INTERRUPTS is enabled The linker was optimizing away z_shared_isr() the zephyr_pre0.elf image since the function is not used. However, zephyr.elf does use this function via isr_tables.c file, generated after zephyr_pre0.elf. This difference caused a shift in all symbol addresses by the size of the z_shared_isr() function. isr_tables.c had pointers for zephyr_pre0.elf. The build system assumes the ISR addresses are the same between both .elf files, when in fact, before this fix, they were not. When run on a device, interrupts were calling non-interrupt functions. Signed-off-by: Dave Desrochers --- .../zephyr/linker/common-rom/common-rom-kernel-devices.ld | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 3d074ac1b38..8adcaf5b1fb 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -40,6 +40,11 @@ /* TODO: does this section require alignment? */ KEEP(*(_SHARED_SW_ISR_TABLE_SECTION_SYMS)) } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + SECTION_PROLOGUE(.text.z_shared_isr,,) + { + KEEP(*(.text.z_shared_isr)) + } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) #endif #endif From 73e59fd463b69e6a62b0a5722c0c225c598c27a7 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Thu, 19 Oct 2023 15:57:18 -0600 Subject: [PATCH 2353/4498] tests: sbs_fuel_gauge Remove erroneous comments that don't describe what the test is actually doing. These comments were probably from copy/pasting test code. Signed-off-by: Aaron Massey --- tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 98adf73afaf..6b302c42f63 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -173,8 +173,6 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) { - /* Validate what props are supported by the driver */ - fuel_gauge_prop_t prop_types[] = { FUEL_GAUGE_SBS_MFR_ACCESS, FUEL_GAUGE_SBS_MODE, @@ -207,7 +205,6 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) { - /* Validate what props are supported by the driver */ uint32_t expected_uV = 5000 * 1000; uint32_t expected_uA = 3000 * 1000; @@ -225,8 +222,6 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop) { - /* Validate what props are supported by the driver */ - uint16_t test_value = 0x1001; union fuel_gauge_prop_val mfr_acc_set = { From b85ee74193857fe48cc692985ccb76c91f4e0595 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Fri, 20 Oct 2023 10:21:39 +0800 Subject: [PATCH 2354/4498] dts: arm: npcx: fix family and device ID for npcx4 This commit fixes the incorrect family/device ID declaration in npcx4m3f and npcx4m8f dtsi file. Signed-off-by: Jun Lin --- dts/arm/nuvoton/npcx/npcx4.dtsi | 1 + dts/arm/nuvoton/npcx4m3f.dtsi | 2 +- dts/arm/nuvoton/npcx4m8f.dtsi | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index 54616fbeed4..a01d5d69abf 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -318,6 +318,7 @@ }; soc-id { + family-id = <0x23>; chip-id = <0x0a>; revision-reg = <0x0000FFFC 4>; }; diff --git a/dts/arm/nuvoton/npcx4m3f.dtsi b/dts/arm/nuvoton/npcx4m3f.dtsi index 327e8754c77..334cd2db653 100644 --- a/dts/arm/nuvoton/npcx4m3f.dtsi +++ b/dts/arm/nuvoton/npcx4m3f.dtsi @@ -22,7 +22,7 @@ }; soc-id { - device-id = <0x2d>; + device-id = <0x25>; }; }; diff --git a/dts/arm/nuvoton/npcx4m8f.dtsi b/dts/arm/nuvoton/npcx4m8f.dtsi index 9baf3c255f9..ac141ab31b9 100644 --- a/dts/arm/nuvoton/npcx4m8f.dtsi +++ b/dts/arm/nuvoton/npcx4m8f.dtsi @@ -22,7 +22,7 @@ }; soc-id { - device-id = <0x2b>; + device-id = <0x23>; }; }; From a6b23e143b6db55043462dad386d11543e9c6417 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 20:58:45 +1100 Subject: [PATCH 2355/4498] dts: esp32: fix gpio-reserved-ranges Fixed to follow correct format. Signed-off-by: Nick Ward --- dts/xtensa/espressif/esp32/esp32_d0wd_v3.dtsi | 2 +- dts/xtensa/espressif/esp32/esp32_d0wdr2_v3.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_net.dtsi | 2 +- dts/xtensa/espressif/esp32/esp32_pico_d4.dtsi | 4 ++-- dts/xtensa/espressif/esp32/esp32_pico_v3.dtsi | 4 ++-- dts/xtensa/espressif/esp32/esp32_pico_v3_02.dtsi | 4 ++-- dts/xtensa/espressif/esp32/esp32_u4wdh.dtsi | 2 +- dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi | 8 ++++---- dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi | 8 ++++---- dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi | 8 ++++---- dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi | 6 +++--- dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi | 8 ++++---- 20 files changed, 55 insertions(+), 55 deletions(-) diff --git a/dts/xtensa/espressif/esp32/esp32_d0wd_v3.dtsi b/dts/xtensa/espressif/esp32/esp32_d0wd_v3.dtsi index 6511f3d351a..b2232505a9a 100644 --- a/dts/xtensa/espressif/esp32/esp32_d0wd_v3.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_d0wd_v3.dtsi @@ -8,7 +8,7 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <20 1>, <24 1>, <28 4>; // NC }; /* Add flash or psram on board or application level */ diff --git a/dts/xtensa/espressif/esp32/esp32_d0wdr2_v3.dtsi b/dts/xtensa/espressif/esp32/esp32_d0wdr2_v3.dtsi index eb5e239c1aa..2703231b821 100644 --- a/dts/xtensa/espressif/esp32/esp32_d0wdr2_v3.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_d0wdr2_v3.dtsi @@ -8,9 +8,9 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 10>, // embeddef psram - <11>, // flash CS - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 5>, // embeddef psram + <11 1>, // flash CS + <20 1>, <24 1>, <28 4>; // NC }; /* 2MB psram */ diff --git a/dts/xtensa/espressif/esp32/esp32_net.dtsi b/dts/xtensa/espressif/esp32/esp32_net.dtsi index 00657ac0425..b5357495666 100644 --- a/dts/xtensa/espressif/esp32/esp32_net.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_net.dtsi @@ -8,7 +8,7 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <20 1>, <24 1>, <28 4>; // NC }; &flash0 { diff --git a/dts/xtensa/espressif/esp32/esp32_pico_d4.dtsi b/dts/xtensa/espressif/esp32/esp32_pico_d4.dtsi index 8ed101d24bc..580d6fed892 100644 --- a/dts/xtensa/espressif/esp32/esp32_pico_d4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_pico_d4.dtsi @@ -8,8 +8,8 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 8>,<11>,<16 17>, // embedded flash - <20>, <24>, <28 31>; // NC + gpio-reserved-ranges = <6 3>, <11 1>, <16 2>, // embedded flash + <20 1>, <24 1>, <28 4>; // NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_pico_v3.dtsi b/dts/xtensa/espressif/esp32/esp32_pico_v3.dtsi index 76e4d4c05eb..d806b0b7c14 100644 --- a/dts/xtensa/espressif/esp32/esp32_pico_v3.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_pico_v3.dtsi @@ -8,8 +8,8 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <16 18>,<23>, // limitations - <24>,<28 31>; // NC + gpio-reserved-ranges = <16 3>, <23 1>, // limitations + <24 1>, <28 4>; // NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_pico_v3_02.dtsi b/dts/xtensa/espressif/esp32/esp32_pico_v3_02.dtsi index 249debca752..9d108bd4e57 100644 --- a/dts/xtensa/espressif/esp32/esp32_pico_v3_02.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_pico_v3_02.dtsi @@ -8,8 +8,8 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>, // flash - <24 25>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, // flash + <24 2>, <28 4>; // NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_u4wdh.dtsi b/dts/xtensa/espressif/esp32/esp32_u4wdh.dtsi index d26074898fa..34ca79156ef 100644 --- a/dts/xtensa/espressif/esp32/esp32_u4wdh.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_u4wdh.dtsi @@ -8,7 +8,7 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <20>, <24>, <28 31>; + gpio-reserved-ranges = <20 1>, <24 1>, <28 4>; }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi index 2461a803954..43ce14117a5 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>, // flash - <20>, <24>, <28 31>; // NC + gpio-reserved-ranges = <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi index 9c8ef71acfd..8f5f3d9dd10 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>, // flash - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi index 4dee1868cc3..42813aa6e68 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>, // flash - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi index f034a5b2898..f9f3bd81201 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi @@ -8,13 +8,13 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <2>,<25>, // NC/test - <6 11>, // flash - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <2 1>, <25 1>, // NC/test + <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi index 324c1bba2de..98f6d9dc9b2 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi @@ -8,13 +8,13 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <2>,<25>, // NC/test - <6 11>, // flash - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <2 1>, <25 1>, // NC/test + <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi index ec5583c4406..7beeda4e136 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi @@ -8,13 +8,13 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <2>,<25>, // NC/test - <6 11>, // flash - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <2 1>, <25 1>, // NC/test + <6 6>, // flash + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi index 712d86fc0f4..393dfa7b951 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi index 119e3e3ed6a..160800afdca 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi index 10ab7f11fa1..acac866076f 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi index b4367cc223d..8e463a3b3a7 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 1>, <7 1>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi index ef6037b394c..0197755fba5 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 1>, <7 1>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi index e8d902c73ae..5bc98caf706 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi @@ -8,12 +8,12 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi index 1ab318f3589..0f73058de08 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi @@ -8,13 +8,13 @@ /* Reserved GPIO pins */ &gpio0 { - gpio-reserved-ranges = <20>, <24>, <28 31>; - gpio-reserved-ranges = <6 11>,<16 17>, // flash&psram - <20>,<24>,<28 31>; // NC + gpio-reserved-ranges = <20 1>, <24 1>, <28 4>; + gpio-reserved-ranges = <6 6>, <16 2>, // flash&psram + <20 1>, <24 1>, <28 4>; // NC }; &gpio1 { - gpio-reserved-ranges = <6>,<7>; // GPIO37-38 NC + gpio-reserved-ranges = <6 2>; // GPIO37-38 NC }; /* 8MB flash */ From 56c1bb813fc68b27eaa8e0b89e9f3b3cc9712301 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:08:08 +0300 Subject: [PATCH 2356/4498] net: shell: Move the shell code to subsys/net/lib/shell This is preparation commit that moves the net shell code to subsys/net/lib/shell directory. The following commits will then refactor the code in net_shell.c to smaller and more manageable pieces. Signed-off-by: Jukka Rissanen --- subsys/net/ip/CMakeLists.txt | 10 +++------- subsys/net/ip/net_core.c | 2 +- subsys/net/lib/CMakeLists.txt | 1 + subsys/net/lib/shell/CMakeLists.txt | 12 ++++++++++++ subsys/net/{ip => lib/shell}/net_shell.c | 16 ++++++---------- subsys/net/{ip => lib/shell}/net_shell.h | 0 6 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 subsys/net/lib/shell/CMakeLists.txt rename subsys/net/{ip => lib/shell}/net_shell.c (99%) rename subsys/net/{ip => lib/shell}/net_shell.h (100%) diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index 84cfc523b8a..b9493b894a7 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -59,14 +59,10 @@ if(CONFIG_NET_TCP_ISN_RFC6528) endif() endif() +# To get private includes like net_shell.h +zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/lib) + zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include ) - -if(CONFIG_NET_SHELL) -zephyr_library_sources(net_shell.c) -zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/l2) -zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/lib) -zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) -endif() diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index c94607b4485..c3b8f5f8c1c 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -36,7 +36,7 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL); #endif #include "net_private.h" -#include "net_shell.h" +#include "shell/net_shell.h" #include "icmpv6.h" #include "ipv6.h" diff --git a/subsys/net/lib/CMakeLists.txt b/subsys/net/lib/CMakeLists.txt index 6c045b58692..756adb41341 100644 --- a/subsys/net/lib/CMakeLists.txt +++ b/subsys/net/lib/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory_ifdef(CONFIG_NET_SOCKETS sockets) add_subdirectory_ifdef(CONFIG_TLS_CREDENTIALS tls_credentials) add_subdirectory_ifdef(CONFIG_NET_CAPTURE capture) add_subdirectory_ifdef(CONFIG_NET_ZPERF zperf) +add_subdirectory_ifdef(CONFIG_NET_SHELL shell) if (CONFIG_DNS_RESOLVER OR CONFIG_MDNS_RESPONDER diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt new file mode 100644 index 00000000000..0e521cc7add --- /dev/null +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources(net_shell.c) +zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/l2) +zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/lib) +zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/ip) +zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) + +zephyr_library_include_directories( + ${ZEPHYR_BASE}/kernel/include + ${ARCH_DIR}/${ARCH}/include + ) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/lib/shell/net_shell.c similarity index 99% rename from subsys/net/ip/net_shell.c rename to subsys/net/lib/shell/net_shell.c index 69efc8b0826..460e3cbc145 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -1378,8 +1378,7 @@ static void get_addresses(struct net_context *context, char addr_local[], int local_len, char addr_remote[], int remote_len) { -#if defined(CONFIG_NET_IPV6) - if (context->local.family == AF_INET6) { + if (IS_ENABLED(CONFIG_NET_IPV6) && context->local.family == AF_INET6) { snprintk(addr_local, local_len, "[%s]:%u", net_sprint_ipv6_addr( net_sin6_ptr(&context->local)->sin6_addr), @@ -1388,10 +1387,8 @@ static void get_addresses(struct net_context *context, net_sprint_ipv6_addr( &net_sin6(&context->remote)->sin6_addr), ntohs(net_sin6(&context->remote)->sin6_port)); - } else -#endif -#if defined(CONFIG_NET_IPV4) - if (context->local.family == AF_INET) { + + } else if (IS_ENABLED(CONFIG_NET_IPV4) && context->local.family == AF_INET) { snprintk(addr_local, local_len, "%s:%d", net_sprint_ipv4_addr( net_sin_ptr(&context->local)->sin_addr), @@ -1400,9 +1397,8 @@ static void get_addresses(struct net_context *context, net_sprint_ipv4_addr( &net_sin(&context->remote)->sin_addr), ntohs(net_sin(&context->remote)->sin_port)); - } else -#endif - if (context->local.family == AF_UNSPEC) { + + } else if (context->local.family == AF_UNSPEC) { snprintk(addr_local, local_len, "AF_UNSPEC"); } else if (context->local.family == AF_PACKET) { snprintk(addr_local, local_len, "AF_PACKET"); @@ -6730,7 +6726,7 @@ SHELL_CMD_REGISTER(net, &net_commands, "Networking commands", NULL); int net_shell_init(void) { #if defined(CONFIG_NET_MGMT_EVENT_MONITOR_AUTO_START) - char *argv[] = { + static const char * const argv[] = { "on", NULL }; diff --git a/subsys/net/ip/net_shell.h b/subsys/net/lib/shell/net_shell.h similarity index 100% rename from subsys/net/ip/net_shell.h rename to subsys/net/lib/shell/net_shell.h From 394a40470dc22c3c615fc3d2514b149d6fb3640f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 29 Sep 2023 11:39:30 +0300 Subject: [PATCH 2357/4498] net: shell: Rename current command as net_old This is a preparation for the refactoring. The old "net" command is renamed "net_old" so that the individual commands can be placed into a separate .c files. This is done like this because we need to use the SHELL_SUBCMD_SET_CREATE() to create the sub-command and then use the SHELL_SUBCMD_ADD() in the .c files to add the command into the sub-command and not get conflict with the same name sub-command. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/net_shell.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 460e3cbc145..522145b8690 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -6721,7 +6721,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, SHELL_SUBCMD_SET_END ); -SHELL_CMD_REGISTER(net, &net_commands, "Networking commands", NULL); +SHELL_CMD_REGISTER(net_old, &net_commands, "Networking commands", NULL); + +/* Placeholder for net commands that are configured in the rest of the .c files */ +SHELL_SUBCMD_SET_CREATE(net_cmds, (net)); + +SHELL_CMD_REGISTER(net, &net_cmds, "Networking commands", NULL); int net_shell_init(void) { From 3f36f78654badc0e75dff06337ce20885d35596b Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:24:52 +0300 Subject: [PATCH 2358/4498] net: shell: Common header for all shell commands Some useful APIs and macros for all net shell commands to use. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/common.h | 31 +++++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 24 +----------------------- 2 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 subsys/net/lib/shell/common.h diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h new file mode 100644 index 00000000000..bf8f1eb63e8 --- /dev/null +++ b/subsys/net/lib/shell/common.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define PR(fmt, ...) \ + shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__) + +#define PR_SHELL(sh, fmt, ...) \ + shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__) + +#define PR_ERROR(fmt, ...) \ + shell_fprintf(sh, SHELL_ERROR, fmt, ##__VA_ARGS__) + +#define PR_INFO(fmt, ...) \ + shell_fprintf(sh, SHELL_INFO, fmt, ##__VA_ARGS__) + +#define PR_WARNING(fmt, ...) \ + shell_fprintf(sh, SHELL_WARNING, fmt, ##__VA_ARGS__) + +#include "net_private.h" + +struct net_shell_user_data { + const struct shell *sh; + void *user_data; +}; diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 522145b8690..43797b2d5d4 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -33,7 +33,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #endif /* CONFIG_NET_L2_ETHERNET */ -#include +#include "common.h" #include "route.h" #include "icmpv6.h" @@ -89,28 +89,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include "websocket/websocket_internal.h" -#define PR(fmt, ...) \ - shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__) - -#define PR_SHELL(sh, fmt, ...) \ - shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__) - -#define PR_ERROR(fmt, ...) \ - shell_fprintf(sh, SHELL_ERROR, fmt, ##__VA_ARGS__) - -#define PR_INFO(fmt, ...) \ - shell_fprintf(sh, SHELL_INFO, fmt, ##__VA_ARGS__) - -#define PR_WARNING(fmt, ...) \ - shell_fprintf(sh, SHELL_WARNING, fmt, ##__VA_ARGS__) - -#include "net_private.h" - -struct net_shell_user_data { - const struct shell *sh; - void *user_data; -}; - static inline const char *addrtype2str(enum net_addr_type addr_type) { switch (addr_type) { From e850517a15e32c90f34e957791e3a86d0d97d526 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:26:11 +0300 Subject: [PATCH 2359/4498] net: shell: Add allocs command Move "allocs" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 2 + subsys/net/lib/shell/allocs.c | 100 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 89 ------------------------- 3 files changed, 102 insertions(+), 89 deletions(-) create mode 100644 subsys/net/lib/shell/allocs.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 0e521cc7add..1b71b417010 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -6,6 +6,8 @@ zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/lib) zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) +zephyr_library_sources(allocs.c) + zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include diff --git a/subsys/net/lib/shell/allocs.c b/subsys/net/lib/shell/allocs.c new file mode 100644 index 00000000000..1c6e7288003 --- /dev/null +++ b/subsys/net/lib/shell/allocs.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) +static void allocs_cb(struct net_pkt *pkt, + struct net_buf *buf, + const char *func_alloc, + int line_alloc, + const char *func_free, + int line_free, + bool in_use, + void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + const char *str; + + if (in_use) { + str = "used"; + } else { + if (func_alloc) { + str = "free"; + } else { + str = "avail"; + } + } + + if (buf) { + goto buf; + } + + if (func_alloc) { + if (in_use) { + PR("%p/%ld\t%5s\t%5s\t%s():%d\n", + pkt, atomic_get(&pkt->atomic_ref), str, + net_pkt_slab2str(pkt->slab), + func_alloc, line_alloc); + } else { + PR("%p\t%5s\t%5s\t%s():%d -> %s():%d\n", + pkt, str, net_pkt_slab2str(pkt->slab), + func_alloc, line_alloc, func_free, + line_free); + } + } + + return; +buf: + if (func_alloc) { + struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id); + + if (in_use) { + PR("%p/%d\t%5s\t%5s\t%s():%d\n", + buf, buf->ref, + str, net_pkt_pool2str(pool), func_alloc, + line_alloc); + } else { + PR("%p\t%5s\t%5s\t%s():%d -> %s():%d\n", + buf, str, net_pkt_pool2str(pool), + func_alloc, line_alloc, func_free, + line_free); + } + } +} +#endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */ + +static int cmd_net_allocs(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) + struct net_shell_user_data user_data; +#endif + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) + user_data.sh = sh; + + PR("Network memory allocations\n\n"); + PR("memory\t\tStatus\tPool\tFunction alloc -> freed\n"); + net_pkt_allocs_foreach(allocs_cb, &user_data); +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DEBUG_NET_PKT_ALLOC", "net_pkt allocation"); +#endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */ + + return 0; +} + +SHELL_SUBCMD_ADD((net), allocs, NULL, + "Print network memory allocations.", + cmd_net_allocs, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 43797b2d5d4..101997541de 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -1627,93 +1627,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) -static void allocs_cb(struct net_pkt *pkt, - struct net_buf *buf, - const char *func_alloc, - int line_alloc, - const char *func_free, - int line_free, - bool in_use, - void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - const char *str; - - if (in_use) { - str = "used"; - } else { - if (func_alloc) { - str = "free"; - } else { - str = "avail"; - } - } - - if (buf) { - goto buf; - } - - if (func_alloc) { - if (in_use) { - PR("%p/%ld\t%5s\t%5s\t%s():%d\n", - pkt, atomic_get(&pkt->atomic_ref), str, - net_pkt_slab2str(pkt->slab), - func_alloc, line_alloc); - } else { - PR("%p\t%5s\t%5s\t%s():%d -> %s():%d\n", - pkt, str, net_pkt_slab2str(pkt->slab), - func_alloc, line_alloc, func_free, - line_free); - } - } - - return; -buf: - if (func_alloc) { - struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id); - - if (in_use) { - PR("%p/%d\t%5s\t%5s\t%s():%d\n", - buf, buf->ref, - str, net_pkt_pool2str(pool), func_alloc, - line_alloc); - } else { - PR("%p\t%5s\t%5s\t%s():%d -> %s():%d\n", - buf, str, net_pkt_pool2str(pool), - func_alloc, line_alloc, func_free, - line_free); - } - } -} -#endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */ - -/* Put the actual shell commands after this */ - -static int cmd_net_allocs(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) - struct net_shell_user_data user_data; -#endif - - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) - user_data.sh = sh; - - PR("Network memory allocations\n\n"); - PR("memory\t\tStatus\tPool\tFunction alloc -> freed\n"); - net_pkt_allocs_foreach(allocs_cb, &user_data); -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_DEBUG_NET_PKT_ALLOC", "net_pkt allocation"); -#endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */ - - return 0; -} - #if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_NATIVE) static void arp_cb(struct arp_entry *entry, void *user_data) { @@ -6647,8 +6560,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(allocs, NULL, "Print network memory allocations.", - cmd_net_allocs), SHELL_CMD(arp, &net_cmd_arp, "Print information about IPv4 ARP cache.", cmd_net_arp), SHELL_CMD(capture, &net_cmd_capture, From 0e3b197f840b5d5e7fd79b790d6bdc9774951438 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:33:09 +0300 Subject: [PATCH 2360/4498] net: shell: Add arp command Move "arp" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/arp.c | 97 +++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 85 ------------------------- 3 files changed, 98 insertions(+), 85 deletions(-) create mode 100644 subsys/net/lib/shell/arp.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 1b71b417010..4e5bc4e7e91 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_library_include_directories(. ${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) zephyr_library_sources(allocs.c) +zephyr_library_sources(arp.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/arp.c b/subsys/net/lib/shell/arp.c new file mode 100644 index 00000000000..fb1582411e9 --- /dev/null +++ b/subsys/net/lib/shell/arp.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +#if defined(CONFIG_NET_ARP) +#include "ethernet/arp.h" +#endif + +#if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_NATIVE) +static void arp_cb(struct arp_entry *entry, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + + if (*count == 0) { + PR(" Interface Link Address\n"); + } + + PR("[%2d] %d %s %s\n", *count, + net_if_get_by_iface(entry->iface), + net_sprint_ll_addr(entry->eth.addr, sizeof(struct net_eth_addr)), + net_sprint_ipv4_addr(&entry->ip)); + + (*count)++; +} +#endif /* CONFIG_NET_ARP */ + +#if !defined(CONFIG_NET_ARP) +static void print_arp_error(const struct shell *sh) +{ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_NATIVE, CONFIG_NET_ARP, CONFIG_NET_IPV4 and" + " CONFIG_NET_L2_ETHERNET", "ARP"); +} +#endif + +static int cmd_net_arp(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_ARP) + struct net_shell_user_data user_data; + int arg = 1; +#endif + + ARG_UNUSED(argc); + +#if defined(CONFIG_NET_ARP) + if (!argv[arg]) { + /* ARP cache content */ + int count = 0; + + user_data.sh = sh; + user_data.user_data = &count; + + if (net_arp_foreach(arp_cb, &user_data) == 0) { + PR("ARP cache is empty.\n"); + } + } +#else + print_arp_error(sh); +#endif + + return 0; +} + +static int cmd_net_arp_flush(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_ARP) + PR("Flushing ARP cache.\n"); + net_arp_clear_cache(NULL); +#else + print_arp_error(sh); +#endif + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_arp, + SHELL_CMD(flush, NULL, "Remove all entries from ARP cache.", + cmd_net_arp_flush), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), arp, &net_cmd_arp, + "Print information about IPv4 ARP cache.", + cmd_net_arp, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 101997541de..0352ec1caf4 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -47,10 +47,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "ipv6.h" -#if defined(CONFIG_NET_ARP) -#include "ethernet/arp.h" -#endif - #if defined(CONFIG_NET_L2_ETHERNET) #include #endif @@ -1627,79 +1623,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_NATIVE) -static void arp_cb(struct arp_entry *entry, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - - if (*count == 0) { - PR(" Interface Link Address\n"); - } - - PR("[%2d] %d %s %s\n", *count, - net_if_get_by_iface(entry->iface), - net_sprint_ll_addr(entry->eth.addr, sizeof(struct net_eth_addr)), - net_sprint_ipv4_addr(&entry->ip)); - - (*count)++; -} -#endif /* CONFIG_NET_ARP */ - -#if !defined(CONFIG_NET_ARP) -static void print_arp_error(const struct shell *sh) -{ - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_NATIVE, CONFIG_NET_ARP, CONFIG_NET_IPV4 and" - " CONFIG_NET_L2_ETHERNET", "ARP"); -} -#endif - -static int cmd_net_arp(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_ARP) - struct net_shell_user_data user_data; - int arg = 1; -#endif - - ARG_UNUSED(argc); - -#if defined(CONFIG_NET_ARP) - if (!argv[arg]) { - /* ARP cache content */ - int count = 0; - - user_data.sh = sh; - user_data.user_data = &count; - - if (net_arp_foreach(arp_cb, &user_data) == 0) { - PR("ARP cache is empty.\n"); - } - } -#else - print_arp_error(sh); -#endif - - return 0; -} - -static int cmd_net_arp_flush(const struct shell *sh, size_t argc, - char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_ARP) - PR("Flushing ARP cache.\n"); - net_arp_clear_cache(NULL); -#else - print_arp_error(sh); -#endif - - return 0; -} - #if defined(CONFIG_NET_CAPTURE) static const struct device *capture_dev; @@ -6187,12 +6110,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_arp, - SHELL_CMD(flush, NULL, "Remove all entries from ARP cache.", - cmd_net_arp_flush), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_capture, SHELL_CMD(setup, NULL, "Setup network packet capture.\n" "'net capture setup '\n" @@ -6560,8 +6477,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(arp, &net_cmd_arp, "Print information about IPv4 ARP cache.", - cmd_net_arp), SHELL_CMD(capture, &net_cmd_capture, "Configure network packet capture.", cmd_net_capture), SHELL_CMD(conn, NULL, "Print information about network connections.", From e03adee6e469eca70b0cd10e382b3558e353a756 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:40:52 +0300 Subject: [PATCH 2361/4498] net: shell: Add capture command Move "capture" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/capture.c | 268 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 259 --------------------------- 3 files changed, 269 insertions(+), 259 deletions(-) create mode 100644 subsys/net/lib/shell/capture.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 4e5bc4e7e91..c4725548148 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) zephyr_library_sources(allocs.c) zephyr_library_sources(arp.c) +zephyr_library_sources(capture.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/capture.c b/subsys/net/lib/shell/capture.c new file mode 100644 index 00000000000..f05531562ae --- /dev/null +++ b/subsys/net/lib/shell/capture.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#include + +#if defined(CONFIG_NET_CAPTURE) +static const struct device *capture_dev; + +static void get_address_str(const struct sockaddr *addr, + char *str, int str_len) +{ + if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6) { + snprintk(str, str_len, "[%s]:%u", + net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), + ntohs(net_sin6(addr)->sin6_port)); + + } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) { + snprintk(str, str_len, "%s:%d", + net_sprint_ipv4_addr(&net_sin(addr)->sin_addr), + ntohs(net_sin(addr)->sin_port)); + + } else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && + addr->sa_family == AF_PACKET) { + snprintk(str, str_len, "AF_PACKET"); + } else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && + addr->sa_family == AF_CAN) { + snprintk(str, str_len, "AF_CAN"); + } else if (addr->sa_family == AF_UNSPEC) { + snprintk(str, str_len, "AF_UNSPEC"); + } else { + snprintk(str, str_len, "AF_UNK(%d)", addr->sa_family); + } +} + +static void capture_cb(struct net_capture_info *info, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char addr_local[ADDR_LEN + 7]; + char addr_peer[ADDR_LEN + 7]; + + if (*count == 0) { + PR(" \t\tCapture Tunnel\n"); + PR("Device\t\tiface iface Local\t\t\tPeer\n"); + } + + get_address_str(info->local, addr_local, sizeof(addr_local)); + get_address_str(info->peer, addr_peer, sizeof(addr_peer)); + + PR("%s\t%c %d %s\t%s\n", info->capture_dev->name, + info->is_enabled ? + (net_if_get_by_iface(info->capture_iface) + '0') : '-', + net_if_get_by_iface(info->tunnel_iface), + addr_local, addr_peer); + + (*count)++; +} +#endif + +static int cmd_net_capture(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_CAPTURE) + bool ret; + + if (capture_dev == NULL) { + PR_INFO("Network packet capture %s\n", "not configured"); + } else { + struct net_shell_user_data user_data; + int count = 0; + + ret = net_capture_is_enabled(capture_dev); + PR_INFO("Network packet capture %s\n", + ret ? "enabled" : "disabled"); + + user_data.sh = sh; + user_data.user_data = &count; + + net_capture_foreach(capture_cb, &user_data); + } +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_CAPTURE", "network packet capture"); +#endif + return 0; +} + +static int cmd_net_capture_setup(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_CAPTURE) + int ret, arg = 1; + const char *remote, *local, *peer; + + remote = argv[arg++]; + if (!remote) { + PR_WARNING("Remote IP address not specified.\n"); + return -ENOEXEC; + } + + local = argv[arg++]; + if (!local) { + PR_WARNING("Local IP address not specified.\n"); + return -ENOEXEC; + } + + peer = argv[arg]; + if (!peer) { + PR_WARNING("Peer IP address not specified.\n"); + return -ENOEXEC; + } + + if (capture_dev != NULL) { + PR_INFO("Capture already setup, cleaning up settings.\n"); + net_capture_cleanup(capture_dev); + capture_dev = NULL; + } + + ret = net_capture_setup(remote, local, peer, &capture_dev); + if (ret < 0) { + PR_WARNING("Capture cannot be setup (%d)\n", ret); + return -ENOEXEC; + } + + PR_INFO("Capture setup done, next enable it by " + "\"net capture enable \"\n"); +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_CAPTURE", "network packet capture"); +#endif + + return 0; +} + +static int cmd_net_capture_cleanup(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_CAPTURE) + int ret; + + if (capture_dev == NULL) { + return 0; + } + + ret = net_capture_cleanup(capture_dev); + if (ret < 0) { + PR_WARNING("Capture %s failed (%d)\n", "cleanup", ret); + return -ENOEXEC; + } + + capture_dev = NULL; +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_CAPTURE", "network packet capture"); +#endif + + return 0; +} + +static int cmd_net_capture_enable(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_CAPTURE) + int ret, arg = 1, if_index; + struct net_if *iface; + + if (capture_dev == NULL) { + return 0; + } + + if (argv[arg] == NULL) { + PR_WARNING("Interface index is missing. Please give interface " + "what you want to monitor\n"); + return -ENOEXEC; + } + + if_index = atoi(argv[arg++]); + if (if_index == 0) { + PR_WARNING("Interface index %d is invalid.\n", if_index); + return -ENOEXEC; + } + + iface = net_if_get_by_index(if_index); + if (iface == NULL) { + PR_WARNING("No such interface with index %d\n", if_index); + return -ENOEXEC; + } + + ret = net_capture_enable(capture_dev, iface); + if (ret < 0) { + PR_WARNING("Capture %s failed (%d)\n", "enable", ret); + return -ENOEXEC; + } +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_CAPTURE", "network packet capture"); +#endif + + return 0; +} + +static int cmd_net_capture_disable(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_CAPTURE) + int ret; + + if (capture_dev == NULL) { + return 0; + } + + ret = net_capture_disable(capture_dev); + if (ret < 0) { + PR_WARNING("Capture %s failed (%d)\n", "disable", ret); + return -ENOEXEC; + } +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_CAPTURE", "network packet capture"); +#endif + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_capture, + SHELL_CMD(setup, NULL, "Setup network packet capture.\n" + "'net capture setup '\n" + " is the (outer) endpoint IP address,\n" + " is the (inner) local IP address,\n" + " is the (inner) peer IP address\n" + "Local and Peer addresses can have UDP port number in them (optional)\n" + "like 198.0.51.2:9000 or [2001:db8:100::2]:4242", + cmd_net_capture_setup), + SHELL_CMD(cleanup, NULL, "Cleanup network packet capture.", + cmd_net_capture_cleanup), + SHELL_CMD(enable, NULL, "Enable network packet capture for a given " + "network interface.\n" + "'net capture enable '", + cmd_net_capture_enable), + SHELL_CMD(disable, NULL, "Disable network packet capture.", + cmd_net_capture_disable), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), capture, &net_cmd_capture, + "Configure network packet capture.", cmd_net_capture, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 0352ec1caf4..f1f079ed166 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -63,8 +63,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #endif -#include - #if defined(CONFIG_NET_GPTP) #include #include "ethernet/gptp/gptp_messages.h" @@ -1623,241 +1621,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_CAPTURE) -static const struct device *capture_dev; - -static void get_address_str(const struct sockaddr *addr, - char *str, int str_len) -{ - if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6) { - snprintk(str, str_len, "[%s]:%u", - net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), - ntohs(net_sin6(addr)->sin6_port)); - - } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) { - snprintk(str, str_len, "%s:%d", - net_sprint_ipv4_addr(&net_sin(addr)->sin_addr), - ntohs(net_sin(addr)->sin_port)); - - } else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && - addr->sa_family == AF_PACKET) { - snprintk(str, str_len, "AF_PACKET"); - } else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && - addr->sa_family == AF_CAN) { - snprintk(str, str_len, "AF_CAN"); - } else if (addr->sa_family == AF_UNSPEC) { - snprintk(str, str_len, "AF_UNSPEC"); - } else { - snprintk(str, str_len, "AF_UNK(%d)", addr->sa_family); - } -} - -static void capture_cb(struct net_capture_info *info, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - char addr_local[ADDR_LEN + 7]; - char addr_peer[ADDR_LEN + 7]; - - if (*count == 0) { - PR(" \t\tCapture Tunnel\n"); - PR("Device\t\tiface iface Local\t\t\tPeer\n"); - } - - get_address_str(info->local, addr_local, sizeof(addr_local)); - get_address_str(info->peer, addr_peer, sizeof(addr_peer)); - - PR("%s\t%c %d %s\t%s\n", info->capture_dev->name, - info->is_enabled ? - (net_if_get_by_iface(info->capture_iface) + '0') : '-', - net_if_get_by_iface(info->tunnel_iface), - addr_local, addr_peer); - - (*count)++; -} -#endif - -static int cmd_net_capture(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_CAPTURE) - bool ret; - - if (capture_dev == NULL) { - PR_INFO("Network packet capture %s\n", "not configured"); - } else { - struct net_shell_user_data user_data; - int count = 0; - - ret = net_capture_is_enabled(capture_dev); - PR_INFO("Network packet capture %s\n", - ret ? "enabled" : "disabled"); - - user_data.sh = sh; - user_data.user_data = &count; - - net_capture_foreach(capture_cb, &user_data); - } -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_CAPTURE", "network packet capture"); -#endif - return 0; -} - -static int cmd_net_capture_setup(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_CAPTURE) - int ret, arg = 1; - const char *remote, *local, *peer; - - remote = argv[arg++]; - if (!remote) { - PR_WARNING("Remote IP address not specified.\n"); - return -ENOEXEC; - } - - local = argv[arg++]; - if (!local) { - PR_WARNING("Local IP address not specified.\n"); - return -ENOEXEC; - } - - peer = argv[arg]; - if (!peer) { - PR_WARNING("Peer IP address not specified.\n"); - return -ENOEXEC; - } - - if (capture_dev != NULL) { - PR_INFO("Capture already setup, cleaning up settings.\n"); - net_capture_cleanup(capture_dev); - capture_dev = NULL; - } - - ret = net_capture_setup(remote, local, peer, &capture_dev); - if (ret < 0) { - PR_WARNING("Capture cannot be setup (%d)\n", ret); - return -ENOEXEC; - } - - PR_INFO("Capture setup done, next enable it by " - "\"net capture enable \"\n"); -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_CAPTURE", "network packet capture"); -#endif - - return 0; -} - -static int cmd_net_capture_cleanup(const struct shell *sh, size_t argc, - char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_CAPTURE) - int ret; - - if (capture_dev == NULL) { - return 0; - } - - ret = net_capture_cleanup(capture_dev); - if (ret < 0) { - PR_WARNING("Capture %s failed (%d)\n", "cleanup", ret); - return -ENOEXEC; - } - - capture_dev = NULL; -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_CAPTURE", "network packet capture"); -#endif - - return 0; -} - -static int cmd_net_capture_enable(const struct shell *sh, size_t argc, - char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_CAPTURE) - int ret, arg = 1, if_index; - struct net_if *iface; - - if (capture_dev == NULL) { - return 0; - } - - if (argv[arg] == NULL) { - PR_WARNING("Interface index is missing. Please give interface " - "what you want to monitor\n"); - return -ENOEXEC; - } - - if_index = atoi(argv[arg++]); - if (if_index == 0) { - PR_WARNING("Interface index %d is invalid.\n", if_index); - return -ENOEXEC; - } - - iface = net_if_get_by_index(if_index); - if (iface == NULL) { - PR_WARNING("No such interface with index %d\n", if_index); - return -ENOEXEC; - } - - ret = net_capture_enable(capture_dev, iface); - if (ret < 0) { - PR_WARNING("Capture %s failed (%d)\n", "enable", ret); - return -ENOEXEC; - } -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_CAPTURE", "network packet capture"); -#endif - - return 0; -} - -static int cmd_net_capture_disable(const struct shell *sh, size_t argc, - char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_CAPTURE) - int ret; - - if (capture_dev == NULL) { - return 0; - } - - ret = net_capture_disable(capture_dev); - if (ret < 0) { - PR_WARNING("Capture %s failed (%d)\n", "disable", ret); - return -ENOEXEC; - } -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_CAPTURE", "network packet capture"); -#endif - - return 0; -} - static int cmd_net_conn(const struct shell *sh, size_t argc, char *argv[]) { ARG_UNUSED(argc); @@ -6110,26 +5873,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_capture, - SHELL_CMD(setup, NULL, "Setup network packet capture.\n" - "'net capture setup '\n" - " is the (outer) endpoint IP address,\n" - " is the (inner) local IP address,\n" - " is the (inner) peer IP address\n" - "Local and Peer addresses can have UDP port number in them (optional)\n" - "like 198.0.51.2:9000 or [2001:db8:100::2]:4242", - cmd_net_capture_setup), - SHELL_CMD(cleanup, NULL, "Cleanup network packet capture.", - cmd_net_capture_cleanup), - SHELL_CMD(enable, NULL, "Enable network packet capture for a given " - "network interface.\n" - "'net capture enable '", - cmd_net_capture_enable), - SHELL_CMD(disable, NULL, "Disable network packet capture.", - cmd_net_capture_disable), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dns, SHELL_CMD(cancel, NULL, "Cancel all pending requests.", cmd_net_dns_cancel), @@ -6477,8 +6220,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(capture, &net_cmd_capture, - "Configure network packet capture.", cmd_net_capture), SHELL_CMD(conn, NULL, "Print information about network connections.", cmd_net_conn), SHELL_CMD(dns, &net_cmd_dns, "Show how DNS is configured.", From 5a7fd25e97fc34c282ff4bc3e7db330069c0fe8e Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:50:42 +0300 Subject: [PATCH 2362/4498] net: shell: Add conn command Move "conn" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/common.h | 6 + subsys/net/lib/shell/conn.c | 301 ++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 370 +++------------------------- 4 files changed, 348 insertions(+), 330 deletions(-) create mode 100644 subsys/net/lib/shell/conn.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index c4725548148..432e438a1f4 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) zephyr_library_sources(allocs.c) zephyr_library_sources(arp.c) zephyr_library_sources(capture.c) +zephyr_library_sources(conn.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h index bf8f1eb63e8..d137468160d 100644 --- a/subsys/net/lib/shell/common.h +++ b/subsys/net/lib/shell/common.h @@ -29,3 +29,9 @@ struct net_shell_user_data { const struct shell *sh; void *user_data; }; + +const char *addrtype2str(enum net_addr_type addr_type); +const char *addrstate2str(enum net_addr_state addr_state); +void get_addresses(struct net_context *context, + char addr_local[], int local_len, + char addr_remote[], int remote_len); diff --git a/subsys/net/lib/shell/conn.c b/subsys/net/lib/shell/conn.c new file mode 100644 index 00000000000..36831809eb8 --- /dev/null +++ b/subsys/net/lib/shell/conn.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +#if defined(CONFIG_NET_TCP) +#include "tcp_internal.h" +#include +#endif + +#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) +static void context_cb(struct net_context *context, void *user_data) +{ +#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) +#define ADDR_LEN NET_IPV6_ADDR_LEN +#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) +#define ADDR_LEN NET_IPV4_ADDR_LEN +#else +#define ADDR_LEN NET_IPV6_ADDR_LEN +#endif + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + /* +7 for []:port */ + char addr_local[ADDR_LEN + 7]; + char addr_remote[ADDR_LEN + 7] = ""; + + get_addresses(context, addr_local, sizeof(addr_local), + addr_remote, sizeof(addr_remote)); + + PR("[%2d] %p\t%d %c%c%c %16s\t%16s\n", + (*count) + 1, context, + net_if_get_by_iface(net_context_get_iface(context)), + net_context_get_family(context) == AF_INET6 ? '6' : + (net_context_get_family(context) == AF_INET ? '4' : ' '), + net_context_get_type(context) == SOCK_DGRAM ? 'D' : + (net_context_get_type(context) == SOCK_STREAM ? 'S' : + (net_context_get_type(context) == SOCK_RAW ? 'R' : ' ')), + net_context_get_proto(context) == IPPROTO_UDP ? 'U' : + (net_context_get_proto(context) == IPPROTO_TCP ? 'T' : ' '), + addr_local, addr_remote); + + (*count)++; +} +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ + +#if CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG +static void conn_handler_cb(struct net_conn *conn, void *user_data) +{ +#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) +#define ADDR_LEN NET_IPV6_ADDR_LEN +#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) +#define ADDR_LEN NET_IPV4_ADDR_LEN +#else +#define ADDR_LEN NET_IPV6_ADDR_LEN +#endif + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + /* +7 for []:port */ + char addr_local[ADDR_LEN + 7]; + char addr_remote[ADDR_LEN + 7] = ""; + + if (IS_ENABLED(CONFIG_NET_IPV6) && conn->local_addr.sa_family == AF_INET6) { + snprintk(addr_local, sizeof(addr_local), "[%s]:%u", + net_sprint_ipv6_addr( + &net_sin6(&conn->local_addr)->sin6_addr), + ntohs(net_sin6(&conn->local_addr)->sin6_port)); + snprintk(addr_remote, sizeof(addr_remote), "[%s]:%u", + net_sprint_ipv6_addr( + &net_sin6(&conn->remote_addr)->sin6_addr), + ntohs(net_sin6(&conn->remote_addr)->sin6_port)); + + } else if (IS_ENABLED(CONFIG_NET_IPV4) && conn->local_addr.sa_family == AF_INET) { + snprintk(addr_local, sizeof(addr_local), "%s:%d", + net_sprint_ipv4_addr( + &net_sin(&conn->local_addr)->sin_addr), + ntohs(net_sin(&conn->local_addr)->sin_port)); + snprintk(addr_remote, sizeof(addr_remote), "%s:%d", + net_sprint_ipv4_addr( + &net_sin(&conn->remote_addr)->sin_addr), + ntohs(net_sin(&conn->remote_addr)->sin_port)); + + } else if (conn->local_addr.sa_family == AF_UNSPEC) { + snprintk(addr_local, sizeof(addr_local), "AF_UNSPEC"); + } else { + snprintk(addr_local, sizeof(addr_local), "AF_UNK(%d)", + conn->local_addr.sa_family); + } + + PR("[%2d] %p %p\t%s\t%16s\t%16s\n", + (*count) + 1, conn, conn->cb, + net_proto2str(conn->local_addr.sa_family, conn->proto), + addr_local, addr_remote); + + (*count)++; +} +#endif /* CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG */ + +#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG +struct tcp_detail_info { + int printed_send_queue_header; + int printed_details; + int count; +}; +#endif + +#if defined(CONFIG_NET_TCP) && \ + (defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)) +static void tcp_cb(struct tcp *conn, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + uint16_t recv_mss = net_tcp_get_supported_mss(conn); + + PR("%p %p %5u %5u %10u %10u %5u %s\n", + conn, conn->context, + ntohs(net_sin6_ptr(&conn->context->local)->sin6_port), + ntohs(net_sin6(&conn->context->remote)->sin6_port), + conn->seq, conn->ack, recv_mss, + net_tcp_state_str(net_tcp_get_state(conn))); + + (*count)++; +} + +#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG +static void tcp_sent_list_cb(struct tcp *conn, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct tcp_detail_info *details = data->user_data; + struct net_pkt *pkt; + sys_snode_t *node; + + if (conn->state != TCP_LISTEN) { + if (!details->printed_details) { + PR("\nTCP Ref Recv_win Send_win Pending " + "Unacked Flags Queue\n"); + details->printed_details = true; + } + + PR("%p %ld %u\t %u\t %zd\t %d\t %d/%d/%d %s\n", + conn, atomic_get(&conn->ref_count), conn->recv_win, + conn->send_win, conn->send_data_total, conn->unacked_len, + conn->in_retransmission, conn->in_connect, conn->in_close, + sys_slist_is_empty(&conn->send_queue) ? "empty" : "data"); + + details->count++; + } + + if (sys_slist_is_empty(&conn->send_queue)) { + return; + } + + if (!details->printed_send_queue_header) { + PR("\nTCP packets waiting ACK:\n"); + PR("TCP net_pkt[ref/totlen]->net_buf[ref/len]..." + "\n"); + } + + PR("%p ", conn); + + node = sys_slist_peek_head(&conn->send_queue); + if (node) { + pkt = CONTAINER_OF(node, struct net_pkt, next); + if (pkt) { + struct net_buf *frag = pkt->frags; + + if (!details->printed_send_queue_header) { + PR("%p[%ld/%zd]", pkt, + atomic_get(&pkt->atomic_ref), + net_pkt_get_len(pkt)); + details->printed_send_queue_header = true; + } else { + PR(" %p[%ld/%zd]", + pkt, atomic_get(&pkt->atomic_ref), + net_pkt_get_len(pkt)); + } + + if (frag) { + PR("->"); + } + + while (frag) { + PR("%p[%d/%d]", frag, frag->ref, frag->len); + + frag = frag->frags; + if (frag) { + PR("->"); + } + } + + PR("\n"); + } + } + + details->printed_send_queue_header = true; +} +#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */ +#endif /* TCP */ + +static int cmd_net_conn(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) + struct net_shell_user_data user_data; + int count = 0; + + PR(" Context \tIface Flags Local Remote\n"); + + user_data.sh = sh; + user_data.user_data = &count; + + net_context_foreach(context_cb, &user_data); + + if (count == 0) { + PR("No connections\n"); + } + +#if CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG + PR("\n Handler Callback \tProto\tLocal \tRemote\n"); + + count = 0; + + net_conn_foreach(conn_handler_cb, &user_data); + + if (count == 0) { + PR("No connection handlers found.\n"); + } +#endif + +#if defined(CONFIG_NET_TCP) + PR("\nTCP Context Src port Dst port " + "Send-Seq Send-Ack MSS State\n"); + + count = 0; + + net_tcp_foreach(tcp_cb, &user_data); + + if (count == 0) { + PR("No TCP connections\n"); + } else { +#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG + /* Print information about pending packets */ + struct tcp_detail_info details; + + count = 0; + + if (IS_ENABLED(CONFIG_NET_TCP)) { + memset(&details, 0, sizeof(details)); + user_data.user_data = &details; + } + + net_tcp_foreach(tcp_sent_list_cb, &user_data); + + if (IS_ENABLED(CONFIG_NET_TCP)) { + if (details.count == 0) { + PR("No active connections.\n"); + } + } +#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */ + } + +#if CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_TCP_LOG_LEVEL_DBG", "TCP debugging"); +#endif /* CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG */ + +#endif + +#if defined(CONFIG_NET_IPV6_FRAGMENT) + count = 0; + + net_ipv6_frag_foreach(ipv6_frag_cb, &user_data); + + /* Do not print anything if no fragments are pending atm */ +#endif + +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_OFFLOAD or CONFIG_NET_NATIVE", + "connection information"); + +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ + + return 0; +} + + +SHELL_SUBCMD_ADD((net), conn, NULL, "Print information about network connections.", + cmd_net_conn, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index f1f079ed166..9b55fdd0631 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -40,11 +40,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "icmpv4.h" #include "connection.h" -#if defined(CONFIG_NET_TCP) -#include "tcp_internal.h" -#include -#endif - #include "ipv6.h" #if defined(CONFIG_NET_L2_ETHERNET) @@ -83,7 +78,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include "websocket/websocket_internal.h" -static inline const char *addrtype2str(enum net_addr_type addr_type) +const char *addrtype2str(enum net_addr_type addr_type) { switch (addr_type) { case NET_ADDR_ANY: @@ -101,7 +96,7 @@ static inline const char *addrtype2str(enum net_addr_type addr_type) return ""; } -static inline const char *addrstate2str(enum net_addr_state addr_state) +const char *addrstate2str(enum net_addr_state addr_state) { switch (addr_state) { case NET_ADDR_ANY_STATE: @@ -117,6 +112,44 @@ static inline const char *addrstate2str(enum net_addr_state addr_state) return ""; } +#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) +void get_addresses(struct net_context *context, + char addr_local[], int local_len, + char addr_remote[], int remote_len) +{ + if (IS_ENABLED(CONFIG_NET_IPV6) && context->local.family == AF_INET6) { + snprintk(addr_local, local_len, "[%s]:%u", + net_sprint_ipv6_addr( + net_sin6_ptr(&context->local)->sin6_addr), + ntohs(net_sin6_ptr(&context->local)->sin6_port)); + snprintk(addr_remote, remote_len, "[%s]:%u", + net_sprint_ipv6_addr( + &net_sin6(&context->remote)->sin6_addr), + ntohs(net_sin6(&context->remote)->sin6_port)); + + } else if (IS_ENABLED(CONFIG_NET_IPV4) && context->local.family == AF_INET) { + snprintk(addr_local, local_len, "%s:%d", + net_sprint_ipv4_addr( + net_sin_ptr(&context->local)->sin_addr), + ntohs(net_sin_ptr(&context->local)->sin_port)); + snprintk(addr_remote, remote_len, "%s:%d", + net_sprint_ipv4_addr( + &net_sin(&context->remote)->sin_addr), + ntohs(net_sin(&context->remote)->sin_port)); + + } else if (context->local.family == AF_UNSPEC) { + snprintk(addr_local, local_len, "AF_UNSPEC"); + } else if (context->local.family == AF_PACKET) { + snprintk(addr_local, local_len, "AF_PACKET"); + } else if (context->local.family == AF_CAN) { + snprintk(addr_local, local_len, "AF_CAN"); + } else { + snprintk(addr_local, local_len, "AF_UNK(%d)", + context->local.family); + } +} +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ + static const char *iface2str(struct net_if *iface, const char **extra) { #ifdef CONFIG_NET_L2_IEEE802154 @@ -1345,238 +1378,6 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data) } #endif /* CONFIG_NET_STATISTICS */ -#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) -static void get_addresses(struct net_context *context, - char addr_local[], int local_len, - char addr_remote[], int remote_len) -{ - if (IS_ENABLED(CONFIG_NET_IPV6) && context->local.family == AF_INET6) { - snprintk(addr_local, local_len, "[%s]:%u", - net_sprint_ipv6_addr( - net_sin6_ptr(&context->local)->sin6_addr), - ntohs(net_sin6_ptr(&context->local)->sin6_port)); - snprintk(addr_remote, remote_len, "[%s]:%u", - net_sprint_ipv6_addr( - &net_sin6(&context->remote)->sin6_addr), - ntohs(net_sin6(&context->remote)->sin6_port)); - - } else if (IS_ENABLED(CONFIG_NET_IPV4) && context->local.family == AF_INET) { - snprintk(addr_local, local_len, "%s:%d", - net_sprint_ipv4_addr( - net_sin_ptr(&context->local)->sin_addr), - ntohs(net_sin_ptr(&context->local)->sin_port)); - snprintk(addr_remote, remote_len, "%s:%d", - net_sprint_ipv4_addr( - &net_sin(&context->remote)->sin_addr), - ntohs(net_sin(&context->remote)->sin_port)); - - } else if (context->local.family == AF_UNSPEC) { - snprintk(addr_local, local_len, "AF_UNSPEC"); - } else if (context->local.family == AF_PACKET) { - snprintk(addr_local, local_len, "AF_PACKET"); - } else if (context->local.family == AF_CAN) { - snprintk(addr_local, local_len, "AF_CAN"); - } else { - snprintk(addr_local, local_len, "AF_UNK(%d)", - context->local.family); - } -} - -static void context_cb(struct net_context *context, void *user_data) -{ -#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) -#define ADDR_LEN NET_IPV6_ADDR_LEN -#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) -#define ADDR_LEN NET_IPV4_ADDR_LEN -#else -#define ADDR_LEN NET_IPV6_ADDR_LEN -#endif - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - /* +7 for []:port */ - char addr_local[ADDR_LEN + 7]; - char addr_remote[ADDR_LEN + 7] = ""; - - get_addresses(context, addr_local, sizeof(addr_local), - addr_remote, sizeof(addr_remote)); - - PR("[%2d] %p\t%d %c%c%c %16s\t%16s\n", - (*count) + 1, context, - net_if_get_by_iface(net_context_get_iface(context)), - net_context_get_family(context) == AF_INET6 ? '6' : - (net_context_get_family(context) == AF_INET ? '4' : ' '), - net_context_get_type(context) == SOCK_DGRAM ? 'D' : - (net_context_get_type(context) == SOCK_STREAM ? 'S' : - (net_context_get_type(context) == SOCK_RAW ? 'R' : ' ')), - net_context_get_proto(context) == IPPROTO_UDP ? 'U' : - (net_context_get_proto(context) == IPPROTO_TCP ? 'T' : ' '), - addr_local, addr_remote); - - (*count)++; -} -#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ - -#if CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG -static void conn_handler_cb(struct net_conn *conn, void *user_data) -{ -#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) -#define ADDR_LEN NET_IPV6_ADDR_LEN -#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) -#define ADDR_LEN NET_IPV4_ADDR_LEN -#else -#define ADDR_LEN NET_IPV6_ADDR_LEN -#endif - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - /* +7 for []:port */ - char addr_local[ADDR_LEN + 7]; - char addr_remote[ADDR_LEN + 7] = ""; - -#if defined(CONFIG_NET_IPV6) - if (conn->local_addr.sa_family == AF_INET6) { - snprintk(addr_local, sizeof(addr_local), "[%s]:%u", - net_sprint_ipv6_addr( - &net_sin6(&conn->local_addr)->sin6_addr), - ntohs(net_sin6(&conn->local_addr)->sin6_port)); - snprintk(addr_remote, sizeof(addr_remote), "[%s]:%u", - net_sprint_ipv6_addr( - &net_sin6(&conn->remote_addr)->sin6_addr), - ntohs(net_sin6(&conn->remote_addr)->sin6_port)); - } else -#endif -#if defined(CONFIG_NET_IPV4) - if (conn->local_addr.sa_family == AF_INET) { - snprintk(addr_local, sizeof(addr_local), "%s:%d", - net_sprint_ipv4_addr( - &net_sin(&conn->local_addr)->sin_addr), - ntohs(net_sin(&conn->local_addr)->sin_port)); - snprintk(addr_remote, sizeof(addr_remote), "%s:%d", - net_sprint_ipv4_addr( - &net_sin(&conn->remote_addr)->sin_addr), - ntohs(net_sin(&conn->remote_addr)->sin_port)); - } else -#endif - if (conn->local_addr.sa_family == AF_UNSPEC) { - snprintk(addr_local, sizeof(addr_local), "AF_UNSPEC"); - } else { - snprintk(addr_local, sizeof(addr_local), "AF_UNK(%d)", - conn->local_addr.sa_family); - } - - PR("[%2d] %p %p\t%s\t%16s\t%16s\n", - (*count) + 1, conn, conn->cb, - net_proto2str(conn->local_addr.sa_family, conn->proto), - addr_local, addr_remote); - - (*count)++; -} -#endif /* CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG */ - -#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG -struct tcp_detail_info { - int printed_send_queue_header; - int printed_details; - int count; -}; -#endif - -#if defined(CONFIG_NET_TCP) && \ - (defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)) -static void tcp_cb(struct tcp *conn, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - uint16_t recv_mss = net_tcp_get_supported_mss(conn); - - PR("%p %p %5u %5u %10u %10u %5u %s\n", - conn, conn->context, - ntohs(net_sin6_ptr(&conn->context->local)->sin6_port), - ntohs(net_sin6(&conn->context->remote)->sin6_port), - conn->seq, conn->ack, recv_mss, - net_tcp_state_str(net_tcp_get_state(conn))); - - (*count)++; -} - -#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG -static void tcp_sent_list_cb(struct tcp *conn, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct tcp_detail_info *details = data->user_data; - struct net_pkt *pkt; - sys_snode_t *node; - - if (conn->state != TCP_LISTEN) { - if (!details->printed_details) { - PR("\nTCP Ref Recv_win Send_win Pending " - "Unacked Flags Queue\n"); - details->printed_details = true; - } - - PR("%p %ld %u\t %u\t %zd\t %d\t %d/%d/%d %s\n", - conn, atomic_get(&conn->ref_count), conn->recv_win, - conn->send_win, conn->send_data_total, conn->unacked_len, - conn->in_retransmission, conn->in_connect, conn->in_close, - sys_slist_is_empty(&conn->send_queue) ? "empty" : "data"); - - details->count++; - } - - if (sys_slist_is_empty(&conn->send_queue)) { - return; - } - - if (!details->printed_send_queue_header) { - PR("\nTCP packets waiting ACK:\n"); - PR("TCP net_pkt[ref/totlen]->net_buf[ref/len]..." - "\n"); - } - - PR("%p ", conn); - - node = sys_slist_peek_head(&conn->send_queue); - if (node) { - pkt = CONTAINER_OF(node, struct net_pkt, next); - if (pkt) { - struct net_buf *frag = pkt->frags; - - if (!details->printed_send_queue_header) { - PR("%p[%ld/%zd]", pkt, - atomic_get(&pkt->atomic_ref), - net_pkt_get_len(pkt)); - details->printed_send_queue_header = true; - } else { - PR(" %p[%ld/%zd]", - pkt, atomic_get(&pkt->atomic_ref), - net_pkt_get_len(pkt)); - } - - if (frag) { - PR("->"); - } - - while (frag) { - PR("%p[%d/%d]", frag, frag->ref, frag->len); - - frag = frag->frags; - if (frag) { - PR("->"); - } - } - - PR("\n"); - } - } - - details->printed_send_queue_header = true; -} -#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */ -#endif /* TCP */ - #if defined(CONFIG_NET_IPV6_FRAGMENT) static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data) @@ -1621,95 +1422,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -static int cmd_net_conn(const struct shell *sh, size_t argc, char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) - struct net_shell_user_data user_data; - int count = 0; - - PR(" Context \tIface Flags Local Remote\n"); - - user_data.sh = sh; - user_data.user_data = &count; - - net_context_foreach(context_cb, &user_data); - - if (count == 0) { - PR("No connections\n"); - } - -#if CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG - PR("\n Handler Callback \tProto\tLocal \tRemote\n"); - - count = 0; - - net_conn_foreach(conn_handler_cb, &user_data); - - if (count == 0) { - PR("No connection handlers found.\n"); - } -#endif - -#if defined(CONFIG_NET_TCP) - PR("\nTCP Context Src port Dst port " - "Send-Seq Send-Ack MSS State\n"); - - count = 0; - - net_tcp_foreach(tcp_cb, &user_data); - - if (count == 0) { - PR("No TCP connections\n"); - } else { -#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG - /* Print information about pending packets */ - struct tcp_detail_info details; - - count = 0; - - if (IS_ENABLED(CONFIG_NET_TCP)) { - memset(&details, 0, sizeof(details)); - user_data.user_data = &details; - } - - net_tcp_foreach(tcp_sent_list_cb, &user_data); - - if (IS_ENABLED(CONFIG_NET_TCP)) { - if (details.count == 0) { - PR("No active connections.\n"); - } - } -#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */ - } - -#if CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_TCP_LOG_LEVEL_DBG", "TCP debugging"); -#endif /* CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG */ - -#endif - -#if defined(CONFIG_NET_IPV6_FRAGMENT) - count = 0; - - net_ipv6_frag_foreach(ipv6_frag_cb, &user_data); - - /* Do not print anything if no fragments are pending atm */ -#endif - -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_OFFLOAD or CONFIG_NET_NATIVE", - "connection information"); - -#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ - - return 0; -} - #if defined(CONFIG_DNS_RESOLVER) static void dns_result_cb(enum dns_resolve_status status, struct dns_addrinfo *info, @@ -6220,8 +5932,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(conn, NULL, "Print information about network connections.", - cmd_net_conn), SHELL_CMD(dns, &net_cmd_dns, "Show how DNS is configured.", cmd_net_dns), SHELL_CMD(events, &net_cmd_events, "Monitor network management events.", From fea700167842ad8642f4286d05d60d3d4c019c80 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 10:57:35 +0300 Subject: [PATCH 2363/4498] net: shell: Add dns command Move "dns" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/dns.c | 244 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 232 -------------------------- 3 files changed, 245 insertions(+), 232 deletions(-) create mode 100644 subsys/net/lib/shell/dns.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 432e438a1f4..0071cd05178 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources(allocs.c) zephyr_library_sources(arp.c) zephyr_library_sources(capture.c) zephyr_library_sources(conn.c) +zephyr_library_sources(dns.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/dns.c b/subsys/net/lib/shell/dns.c new file mode 100644 index 00000000000..24a52f5e8a2 --- /dev/null +++ b/subsys/net/lib/shell/dns.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#if defined(CONFIG_DNS_RESOLVER) +static void dns_result_cb(enum dns_resolve_status status, + struct dns_addrinfo *info, + void *user_data) +{ + const struct shell *sh = user_data; + + if (status == DNS_EAI_CANCELED) { + PR_WARNING("dns: Timeout while resolving name.\n"); + return; + } + + if (status == DNS_EAI_INPROGRESS && info) { + char addr[NET_IPV6_ADDR_LEN]; + + if (info->ai_family == AF_INET) { + net_addr_ntop(AF_INET, + &net_sin(&info->ai_addr)->sin_addr, + addr, NET_IPV4_ADDR_LEN); + } else if (info->ai_family == AF_INET6) { + net_addr_ntop(AF_INET6, + &net_sin6(&info->ai_addr)->sin6_addr, + addr, NET_IPV6_ADDR_LEN); + } else { + strncpy(addr, "Invalid protocol family", + sizeof(addr)); + /* strncpy() doesn't guarantee NUL byte at the end. */ + addr[sizeof(addr) - 1] = 0; + } + + PR("dns: %s\n", addr); + return; + } + + if (status == DNS_EAI_ALLDONE) { + PR("dns: All results received\n"); + return; + } + + if (status == DNS_EAI_FAIL) { + PR_WARNING("dns: No such name found.\n"); + return; + } + + PR_WARNING("dns: Unhandled status %d received\n", status); +} + +static void print_dns_info(const struct shell *sh, + struct dns_resolve_context *ctx) +{ + int i; + + PR("DNS servers:\n"); + + for (i = 0; i < CONFIG_DNS_RESOLVER_MAX_SERVERS + + DNS_MAX_MCAST_SERVERS; i++) { + if (ctx->servers[i].dns_server.sa_family == AF_INET) { + PR("\t%s:%u\n", + net_sprint_ipv4_addr( + &net_sin(&ctx->servers[i].dns_server)-> + sin_addr), + ntohs(net_sin( + &ctx->servers[i].dns_server)->sin_port)); + } else if (ctx->servers[i].dns_server.sa_family == AF_INET6) { + PR("\t[%s]:%u\n", + net_sprint_ipv6_addr( + &net_sin6(&ctx->servers[i].dns_server)-> + sin6_addr), + ntohs(net_sin6( + &ctx->servers[i].dns_server)->sin6_port)); + } + } + + PR("Pending queries:\n"); + + for (i = 0; i < CONFIG_DNS_NUM_CONCUR_QUERIES; i++) { + int32_t remaining; + + if (!ctx->queries[i].cb || !ctx->queries[i].query) { + continue; + } + + remaining = k_ticks_to_ms_ceil32( + k_work_delayable_remaining_get(&ctx->queries[i].timer)); + + if (ctx->queries[i].query_type == DNS_QUERY_TYPE_A) { + PR("\tIPv4[%u]: %s remaining %d\n", + ctx->queries[i].id, + ctx->queries[i].query, + remaining); + } else if (ctx->queries[i].query_type == DNS_QUERY_TYPE_AAAA) { + PR("\tIPv6[%u]: %s remaining %d\n", + ctx->queries[i].id, + ctx->queries[i].query, + remaining); + } + } +} +#endif + +static int cmd_net_dns_cancel(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_DNS_RESOLVER) + struct dns_resolve_context *ctx; + int ret, i; +#endif + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_DNS_RESOLVER) + ctx = dns_resolve_get_default(); + if (!ctx) { + PR_WARNING("No default DNS context found.\n"); + return -ENOEXEC; + } + + for (ret = 0, i = 0; i < CONFIG_DNS_NUM_CONCUR_QUERIES; i++) { + if (!ctx->queries[i].cb) { + continue; + } + + if (!dns_resolve_cancel(ctx, ctx->queries[i].id)) { + ret++; + } + } + + if (ret) { + PR("Cancelled %d pending requests.\n", ret); + } else { + PR("No pending DNS requests.\n"); + } +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_DNS_RESOLVER", + "DNS resolver"); +#endif + + return 0; +} + +static int cmd_net_dns_query(const struct shell *sh, size_t argc, char *argv[]) +{ + +#if defined(CONFIG_DNS_RESOLVER) +#define DNS_TIMEOUT (MSEC_PER_SEC * 2) /* ms */ + enum dns_query_type qtype = DNS_QUERY_TYPE_A; + char *host, *type = NULL; + int ret, arg = 1; + + host = argv[arg++]; + if (!host) { + PR_WARNING("Hostname not specified.\n"); + return -ENOEXEC; + } + + if (argv[arg]) { + type = argv[arg]; + } + + if (type) { + if (strcmp(type, "A") == 0) { + qtype = DNS_QUERY_TYPE_A; + PR("IPv4 address type\n"); + } else if (strcmp(type, "AAAA") == 0) { + qtype = DNS_QUERY_TYPE_AAAA; + PR("IPv6 address type\n"); + } else { + PR_WARNING("Unknown query type, specify either " + "A or AAAA\n"); + return -ENOEXEC; + } + } + + ret = dns_get_addr_info(host, qtype, NULL, dns_result_cb, + (void *)sh, DNS_TIMEOUT); + if (ret < 0) { + PR_WARNING("Cannot resolve '%s' (%d)\n", host, ret); + } else { + PR("Query for '%s' sent.\n", host); + } +#else + PR_INFO("DNS resolver not supported. Set CONFIG_DNS_RESOLVER to " + "enable it.\n"); +#endif + + return 0; +} + +static int cmd_net_dns(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_DNS_RESOLVER) + struct dns_resolve_context *ctx; +#endif + +#if defined(CONFIG_DNS_RESOLVER) + if (argv[1]) { + /* So this is a query then */ + cmd_net_dns_query(sh, argc, argv); + return 0; + } + + /* DNS status */ + ctx = dns_resolve_get_default(); + if (!ctx) { + PR_WARNING("No default DNS context found.\n"); + return -ENOEXEC; + } + + print_dns_info(sh, ctx); +#else + PR_INFO("DNS resolver not supported. Set CONFIG_DNS_RESOLVER to " + "enable it.\n"); +#endif + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dns, + SHELL_CMD(cancel, NULL, "Cancel all pending requests.", + cmd_net_dns_cancel), + SHELL_CMD(query, NULL, + "'net dns [A or AAAA]' queries IPv4 address " + "(default) or IPv6 address for a host name.", + cmd_net_dns_query), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), dns, &net_cmd_dns, + "Show how DNS is configured. Optionally do a query using a given name.", + cmd_net_dns, 1, 2); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 9b55fdd0631..63d2ae31f77 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -24,7 +24,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include -#include #include #include #include @@ -1422,225 +1421,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_DNS_RESOLVER) -static void dns_result_cb(enum dns_resolve_status status, - struct dns_addrinfo *info, - void *user_data) -{ - const struct shell *sh = user_data; - - if (status == DNS_EAI_CANCELED) { - PR_WARNING("dns: Timeout while resolving name.\n"); - return; - } - - if (status == DNS_EAI_INPROGRESS && info) { - char addr[NET_IPV6_ADDR_LEN]; - - if (info->ai_family == AF_INET) { - net_addr_ntop(AF_INET, - &net_sin(&info->ai_addr)->sin_addr, - addr, NET_IPV4_ADDR_LEN); - } else if (info->ai_family == AF_INET6) { - net_addr_ntop(AF_INET6, - &net_sin6(&info->ai_addr)->sin6_addr, - addr, NET_IPV6_ADDR_LEN); - } else { - strncpy(addr, "Invalid protocol family", - sizeof(addr)); - /* strncpy() doesn't guarantee NUL byte at the end. */ - addr[sizeof(addr) - 1] = 0; - } - - PR("dns: %s\n", addr); - return; - } - - if (status == DNS_EAI_ALLDONE) { - PR("dns: All results received\n"); - return; - } - - if (status == DNS_EAI_FAIL) { - PR_WARNING("dns: No such name found.\n"); - return; - } - - PR_WARNING("dns: Unhandled status %d received\n", status); -} - -static void print_dns_info(const struct shell *sh, - struct dns_resolve_context *ctx) -{ - int i; - - PR("DNS servers:\n"); - - for (i = 0; i < CONFIG_DNS_RESOLVER_MAX_SERVERS + - DNS_MAX_MCAST_SERVERS; i++) { - if (ctx->servers[i].dns_server.sa_family == AF_INET) { - PR("\t%s:%u\n", - net_sprint_ipv4_addr( - &net_sin(&ctx->servers[i].dns_server)-> - sin_addr), - ntohs(net_sin( - &ctx->servers[i].dns_server)->sin_port)); - } else if (ctx->servers[i].dns_server.sa_family == AF_INET6) { - PR("\t[%s]:%u\n", - net_sprint_ipv6_addr( - &net_sin6(&ctx->servers[i].dns_server)-> - sin6_addr), - ntohs(net_sin6( - &ctx->servers[i].dns_server)->sin6_port)); - } - } - - PR("Pending queries:\n"); - - for (i = 0; i < CONFIG_DNS_NUM_CONCUR_QUERIES; i++) { - int32_t remaining; - - if (!ctx->queries[i].cb || !ctx->queries[i].query) { - continue; - } - - remaining = k_ticks_to_ms_ceil32( - k_work_delayable_remaining_get(&ctx->queries[i].timer)); - - if (ctx->queries[i].query_type == DNS_QUERY_TYPE_A) { - PR("\tIPv4[%u]: %s remaining %d\n", - ctx->queries[i].id, - ctx->queries[i].query, - remaining); - } else if (ctx->queries[i].query_type == DNS_QUERY_TYPE_AAAA) { - PR("\tIPv6[%u]: %s remaining %d\n", - ctx->queries[i].id, - ctx->queries[i].query, - remaining); - } - } -} -#endif - -static int cmd_net_dns_cancel(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_DNS_RESOLVER) - struct dns_resolve_context *ctx; - int ret, i; -#endif - - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_DNS_RESOLVER) - ctx = dns_resolve_get_default(); - if (!ctx) { - PR_WARNING("No default DNS context found.\n"); - return -ENOEXEC; - } - - for (ret = 0, i = 0; i < CONFIG_DNS_NUM_CONCUR_QUERIES; i++) { - if (!ctx->queries[i].cb) { - continue; - } - - if (!dns_resolve_cancel(ctx, ctx->queries[i].id)) { - ret++; - } - } - - if (ret) { - PR("Cancelled %d pending requests.\n", ret); - } else { - PR("No pending DNS requests.\n"); - } -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_DNS_RESOLVER", - "DNS resolver"); -#endif - - return 0; -} - -static int cmd_net_dns_query(const struct shell *sh, size_t argc, - char *argv[]) -{ - -#if defined(CONFIG_DNS_RESOLVER) -#define DNS_TIMEOUT (MSEC_PER_SEC * 2) /* ms */ - enum dns_query_type qtype = DNS_QUERY_TYPE_A; - char *host, *type = NULL; - int ret, arg = 1; - - host = argv[arg++]; - if (!host) { - PR_WARNING("Hostname not specified.\n"); - return -ENOEXEC; - } - - if (argv[arg]) { - type = argv[arg]; - } - - if (type) { - if (strcmp(type, "A") == 0) { - qtype = DNS_QUERY_TYPE_A; - PR("IPv4 address type\n"); - } else if (strcmp(type, "AAAA") == 0) { - qtype = DNS_QUERY_TYPE_AAAA; - PR("IPv6 address type\n"); - } else { - PR_WARNING("Unknown query type, specify either " - "A or AAAA\n"); - return -ENOEXEC; - } - } - - ret = dns_get_addr_info(host, qtype, NULL, dns_result_cb, - (void *)sh, DNS_TIMEOUT); - if (ret < 0) { - PR_WARNING("Cannot resolve '%s' (%d)\n", host, ret); - } else { - PR("Query for '%s' sent.\n", host); - } -#else - PR_INFO("DNS resolver not supported. Set CONFIG_DNS_RESOLVER to " - "enable it.\n"); -#endif - - return 0; -} - -static int cmd_net_dns(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_DNS_RESOLVER) - struct dns_resolve_context *ctx; -#endif - -#if defined(CONFIG_DNS_RESOLVER) - if (argv[1]) { - /* So this is a query then */ - cmd_net_dns_query(sh, argc, argv); - return 0; - } - - /* DNS status */ - ctx = dns_resolve_get_default(); - if (!ctx) { - PR_WARNING("No default DNS context found.\n"); - return -ENOEXEC; - } - - print_dns_info(sh, ctx); -#else - PR_INFO("DNS resolver not supported. Set CONFIG_DNS_RESOLVER to " - "enable it.\n"); -#endif - - return 0; -} - #if defined(CONFIG_NET_MGMT_EVENT_MONITOR) #define EVENT_MON_STACK_SIZE 1024 #define THREAD_PRIORITY K_PRIO_COOP(2) @@ -5585,16 +5365,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dns, - SHELL_CMD(cancel, NULL, "Cancel all pending requests.", - cmd_net_dns_cancel), - SHELL_CMD(query, NULL, - "'net dns [A or AAAA]' queries IPv4 address " - "(default) or IPv6 address for a host name.", - cmd_net_dns_query), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_events, SHELL_CMD(on, NULL, "Turn on network event monitoring.", cmd_net_events_on), @@ -5932,8 +5702,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(dns, &net_cmd_dns, "Show how DNS is configured.", - cmd_net_dns), SHELL_CMD(events, &net_cmd_events, "Monitor network management events.", cmd_net_events), SHELL_CMD(gptp, &net_cmd_gptp, "Print information about gPTP support.", From 97e0609dd9b1a88f3e1cac88c129f6b75f84fae8 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 11:05:44 +0300 Subject: [PATCH 2364/4498] net: shell: Add events command Move "events" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/common.h | 1 + subsys/net/lib/shell/events.c | 430 +++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 439 +--------------------------- 4 files changed, 435 insertions(+), 436 deletions(-) create mode 100644 subsys/net/lib/shell/events.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 0071cd05178..bc65199567d 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources(arp.c) zephyr_library_sources(capture.c) zephyr_library_sources(conn.c) zephyr_library_sources(dns.c) +zephyr_library_sources(events.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h index d137468160d..160d1f3ccbf 100644 --- a/subsys/net/lib/shell/common.h +++ b/subsys/net/lib/shell/common.h @@ -35,3 +35,4 @@ const char *addrstate2str(enum net_addr_state addr_state); void get_addresses(struct net_context *context, char addr_local[], int local_len, char addr_remote[], int remote_len); +void events_enable(void); diff --git a/subsys/net/lib/shell/events.c b/subsys/net/lib/shell/events.c new file mode 100644 index 00000000000..047fd1e2186 --- /dev/null +++ b/subsys/net/lib/shell/events.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include +#include +#include +#include + +#include "common.h" + +#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) +#define EVENT_MON_STACK_SIZE 1024 +#define THREAD_PRIORITY K_PRIO_COOP(2) +#define MAX_EVENT_INFO_SIZE NET_EVENT_INFO_MAX_SIZE +#define MONITOR_L2_MASK (_NET_EVENT_IF_BASE) +#define MONITOR_L3_IPV4_MASK (_NET_EVENT_IPV4_BASE) +#define MONITOR_L3_IPV6_MASK (_NET_EVENT_IPV6_BASE) +#define MONITOR_L4_MASK (_NET_EVENT_L4_BASE) + +static bool net_event_monitoring; +static bool net_event_shutting_down; +static struct net_mgmt_event_callback l2_cb; +static struct net_mgmt_event_callback l3_ipv4_cb; +static struct net_mgmt_event_callback l3_ipv6_cb; +static struct net_mgmt_event_callback l4_cb; +static struct k_thread event_mon; +static K_THREAD_STACK_DEFINE(event_mon_stack, EVENT_MON_STACK_SIZE); + +struct event_msg { + struct net_if *iface; + size_t len; + uint32_t event; + uint8_t data[MAX_EVENT_INFO_SIZE]; +}; + +K_MSGQ_DEFINE(event_mon_msgq, sizeof(struct event_msg), + CONFIG_NET_MGMT_EVENT_QUEUE_SIZE, sizeof(intptr_t)); + +static void event_handler(struct net_mgmt_event_callback *cb, + uint32_t mgmt_event, struct net_if *iface) +{ + struct event_msg msg; + int ret; + + memset(&msg, 0, sizeof(msg)); + + msg.len = MIN(sizeof(msg.data), cb->info_length); + msg.event = mgmt_event; + msg.iface = iface; + + if (cb->info_length > 0) { + memcpy(msg.data, cb->info, msg.len); + } + + ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(10)); + if (ret < 0) { + NET_ERR("Cannot write to msgq (%d)\n", ret); + } +} + +static const char *get_l2_desc(uint32_t event) +{ + static const char *desc = ""; + + switch (event) { + case NET_EVENT_IF_DOWN: + desc = "down"; + break; + case NET_EVENT_IF_UP: + desc = "up"; + break; + } + + return desc; +} + +static char *get_l3_desc(struct event_msg *msg, + const char **desc, const char **desc2, + char *extra_info, size_t extra_info_len) +{ + static const char *desc_unknown = ""; + char *info = NULL; + + *desc = desc_unknown; + + switch (msg->event) { + case NET_EVENT_IPV6_ADDR_ADD: + *desc = "IPv6 address"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_ADDR_DEL: + *desc = "IPv6 address"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_MADDR_ADD: + *desc = "IPv6 mcast address"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_MADDR_DEL: + *desc = "IPv6 mcast address"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_PREFIX_ADD: + *desc = "IPv6 prefix"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_PREFIX_DEL: + *desc = "IPv6 prefix"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_MCAST_JOIN: + *desc = "IPv6 mcast"; + *desc2 = "join"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_MCAST_LEAVE: + *desc = "IPv6 mcast"; + *desc2 = "leave"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_ROUTER_ADD: + *desc = "IPv6 router"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_ROUTER_DEL: + *desc = "IPv6 router"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_ROUTE_ADD: + *desc = "IPv6 route"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_ROUTE_DEL: + *desc = "IPv6 route"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_DAD_SUCCEED: + *desc = "IPv6 DAD"; + *desc2 = "ok"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_DAD_FAILED: + *desc = "IPv6 DAD"; + *desc2 = "fail"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_NBR_ADD: + *desc = "IPv6 neighbor"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV6_NBR_DEL: + *desc = "IPv6 neighbor"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET6, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV4_ADDR_ADD: + *desc = "IPv4 address"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV4_ADDR_DEL: + *desc = "IPv4 address"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV4_ROUTER_ADD: + *desc = "IPv4 router"; + *desc2 = "add"; + info = net_addr_ntop(AF_INET, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV4_ROUTER_DEL: + *desc = "IPv4 router"; + *desc2 = "del"; + info = net_addr_ntop(AF_INET, msg->data, extra_info, + extra_info_len); + break; + case NET_EVENT_IPV4_DHCP_START: + *desc = "DHCPv4"; + *desc2 = "start"; + break; + case NET_EVENT_IPV4_DHCP_BOUND: + *desc = "DHCPv4"; + *desc2 = "bound"; +#if defined(CONFIG_NET_DHCPV4) + struct net_if_dhcpv4 *data = (struct net_if_dhcpv4 *)msg->data; + + info = net_addr_ntop(AF_INET, &data->requested_ip, extra_info, + extra_info_len); +#endif + break; + case NET_EVENT_IPV4_DHCP_STOP: + *desc = "DHCPv4"; + *desc2 = "stop"; + break; + } + + return info; +} + +static const char *get_l4_desc(uint32_t event) +{ + static const char *desc = ""; + + switch (event) { + case NET_EVENT_L4_CONNECTED: + desc = "connected"; + break; + case NET_EVENT_L4_DISCONNECTED: + desc = "disconnected"; + break; + case NET_EVENT_DNS_SERVER_ADD: + desc = "DNS server add"; + break; + case NET_EVENT_DNS_SERVER_DEL: + desc = "DNS server del"; + break; + } + + return desc; +} + +/* We use a separate thread in order not to do any shell printing from + * event handler callback (to avoid stack size issues). + */ +static void event_mon_handler(const struct shell *sh) +{ + char extra_info[NET_IPV6_ADDR_LEN]; + struct event_msg msg; + + net_mgmt_init_event_callback(&l2_cb, event_handler, + MONITOR_L2_MASK); + net_mgmt_add_event_callback(&l2_cb); + + net_mgmt_init_event_callback(&l3_ipv4_cb, event_handler, + MONITOR_L3_IPV4_MASK); + net_mgmt_add_event_callback(&l3_ipv4_cb); + + net_mgmt_init_event_callback(&l3_ipv6_cb, event_handler, + MONITOR_L3_IPV6_MASK); + net_mgmt_add_event_callback(&l3_ipv6_cb); + + net_mgmt_init_event_callback(&l4_cb, event_handler, + MONITOR_L4_MASK); + net_mgmt_add_event_callback(&l4_cb); + + while (net_event_shutting_down == false) { + const char *layer_str = ""; + const char *desc = "", *desc2 = ""; + char *info = NULL; + uint32_t layer; + + (void)k_msgq_get(&event_mon_msgq, &msg, K_FOREVER); + + if (msg.iface == NULL && msg.event == 0 && msg.len == 0) { + /* This is the stop message */ + continue; + } + + layer = NET_MGMT_GET_LAYER(msg.event); + if (layer == NET_MGMT_LAYER_L2) { + layer_str = "L2"; + desc = get_l2_desc(msg.event); + } else if (layer == NET_MGMT_LAYER_L3) { + layer_str = "L3"; + info = get_l3_desc(&msg, &desc, &desc2, + extra_info, NET_IPV6_ADDR_LEN); + } else if (layer == NET_MGMT_LAYER_L4) { + layer_str = "L4"; + desc = get_l4_desc(msg.event); + } + + PR_INFO("EVENT: %s [%d] %s%s%s%s%s\n", layer_str, + net_if_get_by_iface(msg.iface), desc, + desc2 ? " " : "", desc2 ? desc2 : "", + info ? " " : "", info ? info : ""); + } + + net_mgmt_del_event_callback(&l2_cb); + net_mgmt_del_event_callback(&l3_ipv4_cb); + net_mgmt_del_event_callback(&l3_ipv6_cb); + net_mgmt_del_event_callback(&l4_cb); + + k_msgq_purge(&event_mon_msgq); + + net_event_monitoring = false; + net_event_shutting_down = false; + + PR_INFO("Network event monitoring %s.\n", "disabled"); +} +#endif + +static int cmd_net_events_on(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) + k_tid_t tid; + + if (net_event_monitoring) { + PR_INFO("Network event monitoring is already %s.\n", + "enabled"); + return -ENOEXEC; + } + + tid = k_thread_create(&event_mon, event_mon_stack, + K_THREAD_STACK_SIZEOF(event_mon_stack), + (k_thread_entry_t)event_mon_handler, + (void *)sh, NULL, NULL, THREAD_PRIORITY, 0, + K_FOREVER); + if (!tid) { + PR_ERROR("Cannot create network event monitor thread!"); + return -ENOEXEC; + } + + k_thread_name_set(tid, "event_mon"); + + PR_INFO("Network event monitoring %s.\n", "enabled"); + + net_event_monitoring = true; + net_event_shutting_down = false; + + k_thread_start(tid); +#else + PR_INFO("Network management events are not supported. " + "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); +#endif + + return 0; +} + +static int cmd_net_events_off(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) + static const struct event_msg msg; + int ret; + + if (!net_event_monitoring) { + PR_INFO("Network event monitoring is already %s.\n", + "disabled"); + return -ENOEXEC; + } + + net_event_shutting_down = true; + + ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(100)); + if (ret < 0) { + PR_ERROR("Cannot write to msgq (%d)\n", ret); + return -ENOEXEC; + } +#else + PR_INFO("Network management events are not supported. " + "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); +#endif + + return 0; +} + +static int cmd_net_events(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) + PR("Network event monitoring is %s.\n", + net_event_monitoring ? "enabled" : "disabled"); + + if (!argv[1]) { + PR_INFO("Give 'on' to enable event monitoring and " + "'off' to disable it.\n"); + } +#else + PR_INFO("Network management events are not supported. " + "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); +#endif + + return 0; +} + +void events_enable(void) +{ + static const char * const argv[] = { + "on", + NULL + }; + + (void)cmd_net_events_on(shell_backend_uart_get_ptr(), 1, (char **)argv); +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_events, + SHELL_CMD(on, NULL, "Turn on network event monitoring.", + cmd_net_events_on), + SHELL_CMD(off, NULL, "Turn off network event monitoring.", + cmd_net_events_off), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), events, &net_cmd_events, "Monitor network management events.", + cmd_net_events, 1, 1); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 63d2ae31f77..3ad41388f0e 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -1421,424 +1421,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) -#define EVENT_MON_STACK_SIZE 1024 -#define THREAD_PRIORITY K_PRIO_COOP(2) -#define MAX_EVENT_INFO_SIZE NET_EVENT_INFO_MAX_SIZE -#define MONITOR_L2_MASK (_NET_EVENT_IF_BASE) -#define MONITOR_L3_IPV4_MASK (_NET_EVENT_IPV4_BASE) -#define MONITOR_L3_IPV6_MASK (_NET_EVENT_IPV6_BASE) -#define MONITOR_L4_MASK (_NET_EVENT_L4_BASE) - -static bool net_event_monitoring; -static bool net_event_shutting_down; -static struct net_mgmt_event_callback l2_cb; -static struct net_mgmt_event_callback l3_ipv4_cb; -static struct net_mgmt_event_callback l3_ipv6_cb; -static struct net_mgmt_event_callback l4_cb; -static struct k_thread event_mon; -static K_THREAD_STACK_DEFINE(event_mon_stack, EVENT_MON_STACK_SIZE); - -struct event_msg { - struct net_if *iface; - size_t len; - uint32_t event; - uint8_t data[MAX_EVENT_INFO_SIZE]; -}; - -K_MSGQ_DEFINE(event_mon_msgq, sizeof(struct event_msg), - CONFIG_NET_MGMT_EVENT_QUEUE_SIZE, sizeof(intptr_t)); - -static void event_handler(struct net_mgmt_event_callback *cb, - uint32_t mgmt_event, struct net_if *iface) -{ - struct event_msg msg; - int ret; - - memset(&msg, 0, sizeof(msg)); - - msg.len = MIN(sizeof(msg.data), cb->info_length); - msg.event = mgmt_event; - msg.iface = iface; - - if (cb->info_length > 0) { - memcpy(msg.data, cb->info, msg.len); - } - - ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(10)); - if (ret < 0) { - NET_ERR("Cannot write to msgq (%d)\n", ret); - } -} - -static const char *get_l2_desc(uint32_t event) -{ - static const char *desc = ""; - - switch (event) { - case NET_EVENT_IF_DOWN: - desc = "down"; - break; - case NET_EVENT_IF_UP: - desc = "up"; - break; - } - - return desc; -} - -static char *get_l3_desc(struct event_msg *msg, - const char **desc, const char **desc2, - char *extra_info, size_t extra_info_len) -{ - static const char *desc_unknown = ""; - char *info = NULL; - - *desc = desc_unknown; - - switch (msg->event) { - case NET_EVENT_IPV6_ADDR_ADD: - *desc = "IPv6 address"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_ADDR_DEL: - *desc = "IPv6 address"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_MADDR_ADD: - *desc = "IPv6 mcast address"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_MADDR_DEL: - *desc = "IPv6 mcast address"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_PREFIX_ADD: - *desc = "IPv6 prefix"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_PREFIX_DEL: - *desc = "IPv6 prefix"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_MCAST_JOIN: - *desc = "IPv6 mcast"; - *desc2 = "join"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_MCAST_LEAVE: - *desc = "IPv6 mcast"; - *desc2 = "leave"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_ROUTER_ADD: - *desc = "IPv6 router"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_ROUTER_DEL: - *desc = "IPv6 router"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_ROUTE_ADD: - *desc = "IPv6 route"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_ROUTE_DEL: - *desc = "IPv6 route"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_DAD_SUCCEED: - *desc = "IPv6 DAD"; - *desc2 = "ok"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_DAD_FAILED: - *desc = "IPv6 DAD"; - *desc2 = "fail"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_NBR_ADD: - *desc = "IPv6 neighbor"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_NBR_DEL: - *desc = "IPv6 neighbor"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET6, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV6_DHCP_START: - *desc = "DHCPv6"; - *desc2 = "start"; - break; - case NET_EVENT_IPV6_DHCP_BOUND: - *desc = "DHCPv6"; - *desc2 = "bound"; -#if defined(CONFIG_NET_DHCPV6) - struct net_if_dhcpv6 *data = (struct net_if_dhcpv6 *)msg->data; - - if (data->params.request_addr) { - info = net_addr_ntop(AF_INET6, &data->addr, extra_info, - extra_info_len); - } else if (data->params.request_prefix) { - info = net_addr_ntop(AF_INET6, &data->prefix, extra_info, - extra_info_len); - } -#endif - break; - case NET_EVENT_IPV6_DHCP_STOP: - *desc = "DHCPv6"; - *desc2 = "stop"; - break; - case NET_EVENT_IPV4_ADDR_ADD: - *desc = "IPv4 address"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV4_ADDR_DEL: - *desc = "IPv4 address"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV4_ROUTER_ADD: - *desc = "IPv4 router"; - *desc2 = "add"; - info = net_addr_ntop(AF_INET, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV4_ROUTER_DEL: - *desc = "IPv4 router"; - *desc2 = "del"; - info = net_addr_ntop(AF_INET, msg->data, extra_info, - extra_info_len); - break; - case NET_EVENT_IPV4_DHCP_START: - *desc = "DHCPv4"; - *desc2 = "start"; - break; - case NET_EVENT_IPV4_DHCP_BOUND: - *desc = "DHCPv4"; - *desc2 = "bound"; -#if defined(CONFIG_NET_DHCPV4) - struct net_if_dhcpv4 *data = (struct net_if_dhcpv4 *)msg->data; - - info = net_addr_ntop(AF_INET, &data->requested_ip, extra_info, - extra_info_len); -#endif - break; - case NET_EVENT_IPV4_DHCP_STOP: - *desc = "DHCPv4"; - *desc2 = "stop"; - break; - } - - return info; -} - -static const char *get_l4_desc(uint32_t event) -{ - static const char *desc = ""; - - switch (event) { - case NET_EVENT_L4_CONNECTED: - desc = "connected"; - break; - case NET_EVENT_L4_DISCONNECTED: - desc = "disconnected"; - break; - case NET_EVENT_DNS_SERVER_ADD: - desc = "DNS server add"; - break; - case NET_EVENT_DNS_SERVER_DEL: - desc = "DNS server del"; - break; - } - - return desc; -} - -/* We use a separate thread in order not to do any shell printing from - * event handler callback (to avoid stack size issues). - */ -static void event_mon_handler(const struct shell *sh) -{ - char extra_info[NET_IPV6_ADDR_LEN]; - struct event_msg msg; - - net_mgmt_init_event_callback(&l2_cb, event_handler, - MONITOR_L2_MASK); - net_mgmt_add_event_callback(&l2_cb); - - net_mgmt_init_event_callback(&l3_ipv4_cb, event_handler, - MONITOR_L3_IPV4_MASK); - net_mgmt_add_event_callback(&l3_ipv4_cb); - - net_mgmt_init_event_callback(&l3_ipv6_cb, event_handler, - MONITOR_L3_IPV6_MASK); - net_mgmt_add_event_callback(&l3_ipv6_cb); - - net_mgmt_init_event_callback(&l4_cb, event_handler, - MONITOR_L4_MASK); - net_mgmt_add_event_callback(&l4_cb); - - while (net_event_shutting_down == false) { - const char *layer_str = ""; - const char *desc = "", *desc2 = ""; - char *info = NULL; - uint32_t layer; - - (void)k_msgq_get(&event_mon_msgq, &msg, K_FOREVER); - - if (msg.iface == NULL && msg.event == 0 && msg.len == 0) { - /* This is the stop message */ - continue; - } - - layer = NET_MGMT_GET_LAYER(msg.event); - if (layer == NET_MGMT_LAYER_L2) { - layer_str = "L2"; - desc = get_l2_desc(msg.event); - } else if (layer == NET_MGMT_LAYER_L3) { - layer_str = "L3"; - info = get_l3_desc(&msg, &desc, &desc2, - extra_info, NET_IPV6_ADDR_LEN); - } else if (layer == NET_MGMT_LAYER_L4) { - layer_str = "L4"; - desc = get_l4_desc(msg.event); - } - - PR_INFO("EVENT: %s [%d] %s%s%s%s%s\n", layer_str, - net_if_get_by_iface(msg.iface), desc, - desc2 ? " " : "", desc2 ? desc2 : "", - info ? " " : "", info ? info : ""); - } - - net_mgmt_del_event_callback(&l2_cb); - net_mgmt_del_event_callback(&l3_ipv4_cb); - net_mgmt_del_event_callback(&l3_ipv6_cb); - net_mgmt_del_event_callback(&l4_cb); - - k_msgq_purge(&event_mon_msgq); - - net_event_monitoring = false; - net_event_shutting_down = false; - - PR_INFO("Network event monitoring %s.\n", "disabled"); -} -#endif - -static int cmd_net_events_on(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) - k_tid_t tid; - - if (net_event_monitoring) { - PR_INFO("Network event monitoring is already %s.\n", - "enabled"); - return -ENOEXEC; - } - - tid = k_thread_create(&event_mon, event_mon_stack, - K_THREAD_STACK_SIZEOF(event_mon_stack), - (k_thread_entry_t)event_mon_handler, - (void *)sh, NULL, NULL, THREAD_PRIORITY, 0, - K_FOREVER); - if (!tid) { - PR_ERROR("Cannot create network event monitor thread!"); - return -ENOEXEC; - } - - k_thread_name_set(tid, "event_mon"); - - PR_INFO("Network event monitoring %s.\n", "enabled"); - - net_event_monitoring = true; - net_event_shutting_down = false; - - k_thread_start(tid); -#else - PR_INFO("Network management events are not supported. " - "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); -#endif - - return 0; -} - -static int cmd_net_events_off(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) - static const struct event_msg msg; - int ret; - - if (!net_event_monitoring) { - PR_INFO("Network event monitoring is already %s.\n", - "disabled"); - return -ENOEXEC; - } - - net_event_shutting_down = true; - - ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(100)); - if (ret < 0) { - PR_ERROR("Cannot write to msgq (%d)\n", ret); - return -ENOEXEC; - } -#else - PR_INFO("Network management events are not supported. " - "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); -#endif - - return 0; -} - -static int cmd_net_events(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_MGMT_EVENT_MONITOR) - PR("Network event monitoring is %s.\n", - net_event_monitoring ? "enabled" : "disabled"); - - if (!argv[1]) { - PR_INFO("Give 'on' to enable event monitoring and " - "'off' to disable it.\n"); - } -#else - PR_INFO("Network management events are not supported. " - "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n"); -#endif - - return 0; -} - #if defined(CONFIG_NET_GPTP) static const char *selected_role_str(int port); @@ -5365,14 +4947,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_events, - SHELL_CMD(on, NULL, "Turn on network event monitoring.", - cmd_net_events_on), - SHELL_CMD(off, NULL, "Turn off network event monitoring.", - cmd_net_events_off), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_gptp, SHELL_CMD(port, NULL, "'net gptp []' prints detailed information about " @@ -5702,8 +5276,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(events, &net_cmd_events, "Monitor network management events.", - cmd_net_events), SHELL_CMD(gptp, &net_cmd_gptp, "Print information about gPTP support.", cmd_net_gptp), SHELL_CMD(iface, &net_cmd_iface, @@ -5753,14 +5325,9 @@ SHELL_CMD_REGISTER(net, &net_cmds, "Networking commands", NULL); int net_shell_init(void) { -#if defined(CONFIG_NET_MGMT_EVENT_MONITOR_AUTO_START) - static const char * const argv[] = { - "on", - NULL - }; - - (void)cmd_net_events_on(shell_backend_uart_get_ptr(), 1, argv); -#endif + if (IS_ENABLED(CONFIG_NET_MGMT_EVENT_MONITOR_AUTO_START)) { + events_enable(); + } return 0; } From 55eb526d0a562bd6b4c84da745be206cc707d0c4 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 11:13:21 +0300 Subject: [PATCH 2365/4498] net: shell: Add gptp command Move "gptp" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/gptp.c | 652 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 637 --------------------------- 3 files changed, 653 insertions(+), 637 deletions(-) create mode 100644 subsys/net/lib/shell/gptp.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index bc65199567d..ea973a6cec2 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources(capture.c) zephyr_library_sources(conn.c) zephyr_library_sources(dns.c) zephyr_library_sources(events.c) +zephyr_library_sources(gptp.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/gptp.c b/subsys/net/lib/shell/gptp.c new file mode 100644 index 00000000000..a156637e3af --- /dev/null +++ b/subsys/net/lib/shell/gptp.c @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#if defined(CONFIG_NET_GPTP) +#include +#include "ethernet/gptp/gptp_messages.h" +#include "ethernet/gptp/gptp_md.h" +#include "ethernet/gptp/gptp_state.h" +#include "ethernet/gptp/gptp_data_set.h" +#include "ethernet/gptp/gptp_private.h" +#endif + +#include "common.h" + +#if defined(CONFIG_NET_GPTP) +static const char *selected_role_str(int port); + +static void gptp_port_cb(int port, struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + + if (*count == 0) { + PR("Port Interface \tRole\n"); + } + + (*count)++; + + PR("%2d %p [%d] \t%s\n", port, iface, net_if_get_by_iface(iface), + selected_role_str(port)); +} + +static const char *pdelay_req2str(enum gptp_pdelay_req_states state) +{ + switch (state) { + case GPTP_PDELAY_REQ_NOT_ENABLED: + return "REQ_NOT_ENABLED"; + case GPTP_PDELAY_REQ_INITIAL_SEND_REQ: + return "INITIAL_SEND_REQ"; + case GPTP_PDELAY_REQ_RESET: + return "REQ_RESET"; + case GPTP_PDELAY_REQ_SEND_REQ: + return "SEND_REQ"; + case GPTP_PDELAY_REQ_WAIT_RESP: + return "WAIT_RESP"; + case GPTP_PDELAY_REQ_WAIT_FOLLOW_UP: + return "WAIT_FOLLOW_UP"; + case GPTP_PDELAY_REQ_WAIT_ITV_TIMER: + return "WAIT_ITV_TIMER"; + } + + return ""; +}; + +static const char *pdelay_resp2str(enum gptp_pdelay_resp_states state) +{ + switch (state) { + case GPTP_PDELAY_RESP_NOT_ENABLED: + return "RESP_NOT_ENABLED"; + case GPTP_PDELAY_RESP_INITIAL_WAIT_REQ: + return "INITIAL_WAIT_REQ"; + case GPTP_PDELAY_RESP_WAIT_REQ: + return "WAIT_REQ"; + case GPTP_PDELAY_RESP_WAIT_TSTAMP: + return "WAIT_TSTAMP"; + } + + return ""; +} + +static const char *sync_rcv2str(enum gptp_sync_rcv_states state) +{ + switch (state) { + case GPTP_SYNC_RCV_DISCARD: + return "DISCARD"; + case GPTP_SYNC_RCV_WAIT_SYNC: + return "WAIT_SYNC"; + case GPTP_SYNC_RCV_WAIT_FOLLOW_UP: + return "WAIT_FOLLOW_UP"; + } + + return ""; +} + +static const char *sync_send2str(enum gptp_sync_send_states state) +{ + switch (state) { + case GPTP_SYNC_SEND_INITIALIZING: + return "INITIALIZING"; + case GPTP_SYNC_SEND_SEND_SYNC: + return "SEND_SYNC"; + case GPTP_SYNC_SEND_SEND_FUP: + return "SEND_FUP"; + } + + return ""; +} + +static const char *pss_rcv2str(enum gptp_pss_rcv_states state) +{ + switch (state) { + case GPTP_PSS_RCV_DISCARD: + return "DISCARD"; + case GPTP_PSS_RCV_RECEIVED_SYNC: + return "RECEIVED_SYNC"; + } + + return ""; +} + +static const char *pss_send2str(enum gptp_pss_send_states state) +{ + switch (state) { + case GPTP_PSS_SEND_TRANSMIT_INIT: + return "TRANSMIT_INIT"; + case GPTP_PSS_SEND_SYNC_RECEIPT_TIMEOUT: + return "SYNC_RECEIPT_TIMEOUT"; + case GPTP_PSS_SEND_SEND_MD_SYNC: + return "SEND_MD_SYNC"; + case GPTP_PSS_SEND_SET_SYNC_RECEIPT_TIMEOUT: + return "SET_SYNC_RECEIPT_TIMEOUT"; + } + + return ""; +} + +static const char *pa_rcv2str(enum gptp_pa_rcv_states state) +{ + switch (state) { + case GPTP_PA_RCV_DISCARD: + return "DISCARD"; + case GPTP_PA_RCV_RECEIVE: + return "RECEIVE"; + } + + return ""; +}; + +static const char *pa_info2str(enum gptp_pa_info_states state) +{ + switch (state) { + case GPTP_PA_INFO_DISABLED: + return "DISABLED"; + case GPTP_PA_INFO_POST_DISABLED: + return "POST_DISABLED"; + case GPTP_PA_INFO_AGED: + return "AGED"; + case GPTP_PA_INFO_UPDATE: + return "UPDATE"; + case GPTP_PA_INFO_CURRENT: + return "CURRENT"; + case GPTP_PA_INFO_RECEIVE: + return "RECEIVE"; + case GPTP_PA_INFO_SUPERIOR_MASTER_PORT: + return "SUPERIOR_MASTER_PORT"; + case GPTP_PA_INFO_REPEATED_MASTER_PORT: + return "REPEATED_MASTER_PORT"; + case GPTP_PA_INFO_INFERIOR_MASTER_OR_OTHER_PORT: + return "INFERIOR_MASTER_OR_OTHER_PORT"; + } + + return ""; +}; + +static const char *pa_transmit2str(enum gptp_pa_transmit_states state) +{ + switch (state) { + case GPTP_PA_TRANSMIT_INIT: + return "INIT"; + case GPTP_PA_TRANSMIT_PERIODIC: + return "PERIODIC"; + case GPTP_PA_TRANSMIT_IDLE: + return "IDLE"; + case GPTP_PA_TRANSMIT_POST_IDLE: + return "POST_IDLE"; + } + + return ""; +}; + +static const char *site_sync2str(enum gptp_site_sync_sync_states state) +{ + switch (state) { + case GPTP_SSS_INITIALIZING: + return "INITIALIZING"; + case GPTP_SSS_RECEIVING_SYNC: + return "RECEIVING_SYNC"; + } + + return ""; +} + +static const char *clk_slave2str(enum gptp_clk_slave_sync_states state) +{ + switch (state) { + case GPTP_CLK_SLAVE_SYNC_INITIALIZING: + return "INITIALIZING"; + case GPTP_CLK_SLAVE_SYNC_SEND_SYNC_IND: + return "SEND_SYNC_IND"; + } + + return ""; +}; + +static const char *pr_selection2str(enum gptp_pr_selection_states state) +{ + switch (state) { + case GPTP_PR_SELECTION_INIT_BRIDGE: + return "INIT_BRIDGE"; + case GPTP_PR_SELECTION_ROLE_SELECTION: + return "ROLE_SELECTION"; + } + + return ""; +}; + +static const char *cms_rcv2str(enum gptp_cms_rcv_states state) +{ + switch (state) { + case GPTP_CMS_RCV_INITIALIZING: + return "INITIALIZING"; + case GPTP_CMS_RCV_WAITING: + return "WAITING"; + case GPTP_CMS_RCV_SOURCE_TIME: + return "SOURCE_TIME"; + } + + return ""; +}; + +#if !defined(USCALED_NS_TO_NS) +#define USCALED_NS_TO_NS(val) (val >> 16) +#endif + +static const char *selected_role_str(int port) +{ + switch (GPTP_GLOBAL_DS()->selected_role[port]) { + case GPTP_PORT_INITIALIZING: + return "INITIALIZING"; + case GPTP_PORT_FAULTY: + return "FAULTY"; + case GPTP_PORT_DISABLED: + return "DISABLED"; + case GPTP_PORT_LISTENING: + return "LISTENING"; + case GPTP_PORT_PRE_MASTER: + return "PRE-MASTER"; + case GPTP_PORT_MASTER: + return "MASTER"; + case GPTP_PORT_PASSIVE: + return "PASSIVE"; + case GPTP_PORT_UNCALIBRATED: + return "UNCALIBRATED"; + case GPTP_PORT_SLAVE: + return "SLAVE"; + } + + return ""; +} + +static void gptp_print_port_info(const struct shell *sh, int port) +{ + struct gptp_port_bmca_data *port_bmca_data; + struct gptp_port_param_ds *port_param_ds; + struct gptp_port_states *port_state; + struct gptp_domain *domain; + struct gptp_port_ds *port_ds; + struct net_if *iface; + int ret, i; + + domain = gptp_get_domain(); + + ret = gptp_get_port_data(domain, + port, + &port_ds, + &port_param_ds, + &port_state, + &port_bmca_data, + &iface); + if (ret < 0) { + PR_WARNING("Cannot get gPTP information for port %d (%d)\n", + port, ret); + return; + } + + NET_ASSERT(port == port_ds->port_id.port_number, + "Port number mismatch! (%d vs %d)", port, + port_ds->port_id.port_number); + + PR("Port id : %d (%s)\n", port_ds->port_id.port_number, + selected_role_str(port_ds->port_id.port_number)); + PR("Interface : %p [%d]\n", iface, net_if_get_by_iface(iface)); + PR("Clock id : "); + for (i = 0; i < sizeof(port_ds->port_id.clk_id); i++) { + PR("%02x", port_ds->port_id.clk_id[i]); + + if (i != (sizeof(port_ds->port_id.clk_id) - 1)) { + PR(":"); + } + } + PR("\n"); + + PR("Version : %d\n", port_ds->version); + PR("AS capable : %s\n", port_ds->as_capable ? "yes" : "no"); + + PR("\nConfiguration:\n"); + PR("Time synchronization and Best Master Selection enabled " + ": %s\n", port_ds->ptt_port_enabled ? "yes" : "no"); + PR("The port is measuring the path delay " + ": %s\n", port_ds->is_measuring_delay ? "yes" : "no"); + PR("One way propagation time on %s : %u ns\n", + "the link attached to this port", + (uint32_t)port_ds->neighbor_prop_delay); + PR("Propagation time threshold for %s : %u ns\n", + "the link attached to this port", + (uint32_t)port_ds->neighbor_prop_delay_thresh); + PR("Estimate of the ratio of the frequency with the peer " + ": %u\n", (uint32_t)port_ds->neighbor_rate_ratio); + PR("Asymmetry on the link relative to the grand master time base " + ": %" PRId64 "\n", port_ds->delay_asymmetry); + PR("Maximum interval between sync %s " + ": %" PRIu64 "\n", "messages", + port_ds->sync_receipt_timeout_time_itv); + PR("Maximum number of Path Delay Requests without a response " + ": %d\n", port_ds->allowed_lost_responses); + PR("Current Sync %s : %d\n", + "sequence id for this port", port_ds->sync_seq_id); + PR("Current Path Delay Request %s : %d\n", + "sequence id for this port", port_ds->pdelay_req_seq_id); + PR("Current Announce %s : %d\n", + "sequence id for this port", port_ds->announce_seq_id); + PR("Current Signaling %s : %d\n", + "sequence id for this port", port_ds->signaling_seq_id); + PR("Whether neighborRateRatio %s : %s\n", + "needs to be computed for this port", + port_ds->compute_neighbor_rate_ratio ? "yes" : "no"); + PR("Whether neighborPropDelay %s : %s\n", + "needs to be computed for this port", + port_ds->compute_neighbor_prop_delay ? "yes" : "no"); + PR("Initial Announce Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->ini_log_announce_itv); + PR("Current Announce Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->cur_log_announce_itv); + PR("Initial Sync Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->ini_log_half_sync_itv); + PR("Current Sync Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->cur_log_half_sync_itv); + PR("Initial Path Delay Request Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->ini_log_pdelay_req_itv); + PR("Current Path Delay Request Interval %s : %d\n", + "as a Logarithm to base 2", port_ds->cur_log_pdelay_req_itv); + PR("Time without receiving announce %s %s : %d ms (%d)\n", + "messages", "before running BMCA", + gptp_uscaled_ns_to_timer_ms( + &port_bmca_data->ann_rcpt_timeout_time_interval), + port_ds->announce_receipt_timeout); + PR("Time without receiving sync %s %s : %" PRIu64 " ms (%d)\n", + "messages", "before running BMCA", + (port_ds->sync_receipt_timeout_time_itv >> 16) / + (NSEC_PER_SEC / MSEC_PER_SEC), + port_ds->sync_receipt_timeout); + PR("Sync event %s : %" PRIu64 " ms\n", + "transmission interval for the port", + USCALED_NS_TO_NS(port_ds->half_sync_itv.low) / + (NSEC_PER_USEC * USEC_PER_MSEC)); + PR("Path Delay Request %s : %" PRIu64 " ms\n", + "transmission interval for the port", + USCALED_NS_TO_NS(port_ds->pdelay_req_itv.low) / + (NSEC_PER_USEC * USEC_PER_MSEC)); + PR("BMCA %s %s%d%s: %d\n", "default", "priority", 1, + " ", + domain->default_ds.priority1); + PR("BMCA %s %s%d%s: %d\n", "default", "priority", 2, + " ", + domain->default_ds.priority2); + + PR("\nRuntime status:\n"); + PR("Current global port state " + " : %s\n", selected_role_str(port)); + PR("Path Delay Request state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pdelay_req2str(port_state->pdelay_req.state)); + PR("\tInitial Path Delay Response Peer Timestamp " + ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_evt_tstamp); + PR("\tInitial Path Delay Response Ingress Timestamp " + ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_ingress_tstamp); + PR("\tPath Delay Response %s %s : %u\n", + "messages", "received", + port_state->pdelay_req.rcvd_pdelay_resp); + PR("\tPath Delay Follow Up %s %s : %u\n", + "messages", "received", + port_state->pdelay_req.rcvd_pdelay_follow_up); + PR("\tNumber of lost Path Delay Responses " + ": %u\n", port_state->pdelay_req.lost_responses); + PR("\tTimer expired send a new Path Delay Request " + ": %u\n", port_state->pdelay_req.pdelay_timer_expired); + PR("\tNeighborRateRatio has been computed successfully " + ": %u\n", port_state->pdelay_req.neighbor_rate_ratio_valid); + PR("\tPath Delay has already been computed after init " + ": %u\n", port_state->pdelay_req.init_pdelay_compute); + PR("\tCount consecutive reqs with multiple responses " + ": %u\n", port_state->pdelay_req.multiple_resp_count); + + PR("Path Delay Response state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pdelay_resp2str(port_state->pdelay_resp.state)); + + PR("SyncReceive state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", sync_rcv2str(port_state->sync_rcv.state)); + PR("\tA Sync %s %s : %s\n", + "Message", "has been received", + port_state->sync_rcv.rcvd_sync ? "yes" : "no"); + PR("\tA Follow Up %s %s : %s\n", + "Message", "has been received", + port_state->sync_rcv.rcvd_follow_up ? "yes" : "no"); + PR("\tA Follow Up %s %s : %s\n", + "Message", "timeout", + port_state->sync_rcv.follow_up_timeout_expired ? "yes" : "no"); + PR("\tTime at which a Sync %s without Follow Up\n" + "\t will be discarded " + ": %" PRIu64 "\n", "Message", + port_state->sync_rcv.follow_up_receipt_timeout); + + PR("SyncSend state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", sync_send2str(port_state->sync_send.state)); + PR("\tA MDSyncSend structure %s : %s\n", + "has been received", + port_state->sync_send.rcvd_md_sync ? "yes" : "no"); + PR("\tThe timestamp for the sync msg %s : %s\n", + "has been received", + port_state->sync_send.md_sync_timestamp_avail ? "yes" : "no"); + + PR("PortSyncSyncReceive state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pss_rcv2str(port_state->pss_rcv.state)); + PR("\tGrand Master / Local Clock frequency ratio " + ": %f\n", port_state->pss_rcv.rate_ratio); + PR("\tA MDSyncReceive struct is ready to be processed " + ": %s\n", port_state->pss_rcv.rcvd_md_sync ? "yes" : "no"); + PR("\tExpiry of SyncReceiptTimeoutTimer : %s\n", + port_state->pss_rcv.rcv_sync_receipt_timeout_timer_expired ? + "yes" : "no"); + + PR("PortSyncSyncSend state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pss_send2str(port_state->pss_send.state)); + PR("\tFollow Up Correction Field of last recv PSS " + ": %" PRId64 "\n", + port_state->pss_send.last_follow_up_correction_field); + PR("\tUpstream Tx Time of the last recv PortSyncSync " + ": %" PRIu64 "\n", port_state->pss_send.last_upstream_tx_time); + PR("\tRate Ratio of the last received PortSyncSync " + ": %f\n", + port_state->pss_send.last_rate_ratio); + PR("\tGM Freq Change of the last received PortSyncSync " + ": %f\n", port_state->pss_send.last_gm_freq_change); + PR("\tGM Time Base Indicator of last recv PortSyncSync " + ": %d\n", port_state->pss_send.last_gm_time_base_indicator); + PR("\tReceived Port Number of last recv PortSyncSync " + ": %d\n", + port_state->pss_send.last_rcvd_port_num); + PR("\tPortSyncSync structure is ready to be processed " + ": %s\n", port_state->pss_send.rcvd_pss_sync ? "yes" : "no"); + PR("\tFlag when the %s has expired : %s\n", + "half_sync_itv_timer", + port_state->pss_send.half_sync_itv_timer_expired ? "yes" : "no"); + PR("\tHas %s expired twice : %s\n", + "half_sync_itv_timer", + port_state->pss_send.sync_itv_timer_expired ? "yes" : "no"); + PR("\tHas syncReceiptTimeoutTime expired " + ": %s\n", + port_state->pss_send.send_sync_receipt_timeout_timer_expired ? + "yes" : "no"); + + PR("PortAnnounceReceive state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pa_rcv2str(port_state->pa_rcv.state)); + PR("\tAn announce message is ready to be processed " + ": %s\n", + port_state->pa_rcv.rcvd_announce ? "yes" : "no"); + + PR("PortAnnounceInformation state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pa_info2str(port_state->pa_info.state)); + PR("\tExpired announce information " + ": %s\n", port_state->pa_info.ann_expired ? "yes" : "no"); + + PR("PortAnnounceTransmit state machine variables:\n"); + PR("\tCurrent state " + ": %s\n", pa_transmit2str(port_state->pa_transmit.state)); + PR("\tTrigger announce information " + ": %s\n", port_state->pa_transmit.ann_trigger ? "yes" : "no"); + +#if defined(CONFIG_NET_GPTP_STATISTICS) + PR("\nStatistics:\n"); + PR("Sync %s %s : %u\n", + "messages", "received", port_param_ds->rx_sync_count); + PR("Follow Up %s %s : %u\n", + "messages", "received", port_param_ds->rx_fup_count); + PR("Path Delay Request %s %s : %u\n", + "messages", "received", port_param_ds->rx_pdelay_req_count); + PR("Path Delay Response %s %s : %u\n", + "messages", "received", port_param_ds->rx_pdelay_resp_count); + PR("Path Delay %s threshold %s : %u\n", + "messages", "exceeded", + port_param_ds->neighbor_prop_delay_exceeded); + PR("Path Delay Follow Up %s %s : %u\n", + "messages", "received", port_param_ds->rx_pdelay_resp_fup_count); + PR("Announce %s %s : %u\n", + "messages", "received", port_param_ds->rx_announce_count); + PR("ptp %s discarded : %u\n", + "messages", port_param_ds->rx_ptp_packet_discard_count); + PR("Sync %s %s : %u\n", + "reception", "timeout", + port_param_ds->sync_receipt_timeout_count); + PR("Announce %s %s : %u\n", + "reception", "timeout", + port_param_ds->announce_receipt_timeout_count); + PR("Path Delay Requests without a response " + ": %u\n", + port_param_ds->pdelay_allowed_lost_resp_exceed_count); + PR("Sync %s %s : %u\n", + "messages", "sent", port_param_ds->tx_sync_count); + PR("Follow Up %s %s : %u\n", + "messages", "sent", port_param_ds->tx_fup_count); + PR("Path Delay Request %s %s : %u\n", + "messages", "sent", port_param_ds->tx_pdelay_req_count); + PR("Path Delay Response %s %s : %u\n", + "messages", "sent", port_param_ds->tx_pdelay_resp_count); + PR("Path Delay Response FUP %s %s : %u\n", + "messages", "sent", port_param_ds->tx_pdelay_resp_fup_count); + PR("Announce %s %s : %u\n", + "messages", "sent", port_param_ds->tx_announce_count); +#endif /* CONFIG_NET_GPTP_STATISTICS */ +} +#endif /* CONFIG_NET_GPTP */ + +static int cmd_net_gptp_port(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_GPTP) + int arg = 1; + char *endptr; + int port; +#endif + +#if defined(CONFIG_NET_GPTP) + if (!argv[arg]) { + PR_WARNING("Port number must be given.\n"); + return -ENOEXEC; + } + + port = strtol(argv[arg], &endptr, 10); + + if (*endptr == '\0') { + gptp_print_port_info(sh, port); + } else { + PR_WARNING("Not a valid gPTP port number: %s\n", argv[arg]); + } +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP"); +#endif + + return 0; +} + +static int cmd_net_gptp(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_GPTP) + /* gPTP status */ + struct gptp_domain *domain = gptp_get_domain(); + int count = 0; + int arg = 1; +#endif + +#if defined(CONFIG_NET_GPTP) + if (argv[arg]) { + cmd_net_gptp_port(sh, argc, argv); + } else { + struct net_shell_user_data user_data; + + user_data.sh = sh; + user_data.user_data = &count; + + gptp_foreach_port(gptp_port_cb, &user_data); + + PR("\n"); + + PR("SiteSyncSync state machine variables:\n"); + PR("\tCurrent state : %s\n", + site_sync2str(domain->state.site_ss.state)); + PR("\tA PortSyncSync struct is ready : %s\n", + domain->state.site_ss.rcvd_pss ? "yes" : "no"); + + PR("ClockSlaveSync state machine variables:\n"); + PR("\tCurrent state : %s\n", + clk_slave2str(domain->state.clk_slave_sync.state)); + PR("\tA PortSyncSync struct is ready : %s\n", + domain->state.clk_slave_sync.rcvd_pss ? "yes" : "no"); + PR("\tThe local clock has expired : %s\n", + domain->state.clk_slave_sync.rcvd_local_clk_tick ? + "yes" : "no"); + + PR("PortRoleSelection state machine variables:\n"); + PR("\tCurrent state : %s\n", + pr_selection2str(domain->state.pr_sel.state)); + + PR("ClockMasterSyncReceive state machine variables:\n"); + PR("\tCurrent state : %s\n", + cms_rcv2str(domain->state.clk_master_sync_receive.state)); + PR("\tA ClockSourceTime : %s\n", + domain->state.clk_master_sync_receive.rcvd_clock_source_req + ? "yes" : "no"); + PR("\tThe local clock has expired : %s\n", + domain->state.clk_master_sync_receive.rcvd_local_clock_tick + ? "yes" : "no"); + } +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP"); +#endif + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_gptp, + SHELL_CMD(port, NULL, + "'net gptp []' prints detailed information about " + "gPTP port.", + cmd_net_gptp_port), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), gptp, &net_cmd_gptp, + "Print information about gPTP support.", + cmd_net_gptp, 1, 1); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 3ad41388f0e..f9a79ffce82 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -57,15 +57,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #endif -#if defined(CONFIG_NET_GPTP) -#include -#include "ethernet/gptp/gptp_messages.h" -#include "ethernet/gptp/gptp_md.h" -#include "ethernet/gptp/gptp_state.h" -#include "ethernet/gptp/gptp_data_set.h" -#include "ethernet/gptp/gptp_private.h" -#endif - #if defined(CONFIG_NET_L2_PPP) #include #include "ppp/ppp_internal.h" @@ -1421,624 +1412,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_GPTP) -static const char *selected_role_str(int port); - -static void gptp_port_cb(int port, struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - - if (*count == 0) { - PR("Port Interface \tRole\n"); - } - - (*count)++; - - PR("%2d %p [%d] \t%s\n", port, iface, net_if_get_by_iface(iface), - selected_role_str(port)); -} - -static const char *pdelay_req2str(enum gptp_pdelay_req_states state) -{ - switch (state) { - case GPTP_PDELAY_REQ_NOT_ENABLED: - return "REQ_NOT_ENABLED"; - case GPTP_PDELAY_REQ_INITIAL_SEND_REQ: - return "INITIAL_SEND_REQ"; - case GPTP_PDELAY_REQ_RESET: - return "REQ_RESET"; - case GPTP_PDELAY_REQ_SEND_REQ: - return "SEND_REQ"; - case GPTP_PDELAY_REQ_WAIT_RESP: - return "WAIT_RESP"; - case GPTP_PDELAY_REQ_WAIT_FOLLOW_UP: - return "WAIT_FOLLOW_UP"; - case GPTP_PDELAY_REQ_WAIT_ITV_TIMER: - return "WAIT_ITV_TIMER"; - } - - return ""; -}; - -static const char *pdelay_resp2str(enum gptp_pdelay_resp_states state) -{ - switch (state) { - case GPTP_PDELAY_RESP_NOT_ENABLED: - return "RESP_NOT_ENABLED"; - case GPTP_PDELAY_RESP_INITIAL_WAIT_REQ: - return "INITIAL_WAIT_REQ"; - case GPTP_PDELAY_RESP_WAIT_REQ: - return "WAIT_REQ"; - case GPTP_PDELAY_RESP_WAIT_TSTAMP: - return "WAIT_TSTAMP"; - } - - return ""; -} - -static const char *sync_rcv2str(enum gptp_sync_rcv_states state) -{ - switch (state) { - case GPTP_SYNC_RCV_DISCARD: - return "DISCARD"; - case GPTP_SYNC_RCV_WAIT_SYNC: - return "WAIT_SYNC"; - case GPTP_SYNC_RCV_WAIT_FOLLOW_UP: - return "WAIT_FOLLOW_UP"; - } - - return ""; -} - -static const char *sync_send2str(enum gptp_sync_send_states state) -{ - switch (state) { - case GPTP_SYNC_SEND_INITIALIZING: - return "INITIALIZING"; - case GPTP_SYNC_SEND_SEND_SYNC: - return "SEND_SYNC"; - case GPTP_SYNC_SEND_SEND_FUP: - return "SEND_FUP"; - } - - return ""; -} - -static const char *pss_rcv2str(enum gptp_pss_rcv_states state) -{ - switch (state) { - case GPTP_PSS_RCV_DISCARD: - return "DISCARD"; - case GPTP_PSS_RCV_RECEIVED_SYNC: - return "RECEIVED_SYNC"; - } - - return ""; -} - -static const char *pss_send2str(enum gptp_pss_send_states state) -{ - switch (state) { - case GPTP_PSS_SEND_TRANSMIT_INIT: - return "TRANSMIT_INIT"; - case GPTP_PSS_SEND_SYNC_RECEIPT_TIMEOUT: - return "SYNC_RECEIPT_TIMEOUT"; - case GPTP_PSS_SEND_SEND_MD_SYNC: - return "SEND_MD_SYNC"; - case GPTP_PSS_SEND_SET_SYNC_RECEIPT_TIMEOUT: - return "SET_SYNC_RECEIPT_TIMEOUT"; - } - - return ""; -} - -static const char *pa_rcv2str(enum gptp_pa_rcv_states state) -{ - switch (state) { - case GPTP_PA_RCV_DISCARD: - return "DISCARD"; - case GPTP_PA_RCV_RECEIVE: - return "RECEIVE"; - } - - return ""; -}; - -static const char *pa_info2str(enum gptp_pa_info_states state) -{ - switch (state) { - case GPTP_PA_INFO_DISABLED: - return "DISABLED"; - case GPTP_PA_INFO_POST_DISABLED: - return "POST_DISABLED"; - case GPTP_PA_INFO_AGED: - return "AGED"; - case GPTP_PA_INFO_UPDATE: - return "UPDATE"; - case GPTP_PA_INFO_CURRENT: - return "CURRENT"; - case GPTP_PA_INFO_RECEIVE: - return "RECEIVE"; - case GPTP_PA_INFO_SUPERIOR_MASTER_PORT: - return "SUPERIOR_MASTER_PORT"; - case GPTP_PA_INFO_REPEATED_MASTER_PORT: - return "REPEATED_MASTER_PORT"; - case GPTP_PA_INFO_INFERIOR_MASTER_OR_OTHER_PORT: - return "INFERIOR_MASTER_OR_OTHER_PORT"; - } - - return ""; -}; - -static const char *pa_transmit2str(enum gptp_pa_transmit_states state) -{ - switch (state) { - case GPTP_PA_TRANSMIT_INIT: - return "INIT"; - case GPTP_PA_TRANSMIT_PERIODIC: - return "PERIODIC"; - case GPTP_PA_TRANSMIT_IDLE: - return "IDLE"; - case GPTP_PA_TRANSMIT_POST_IDLE: - return "POST_IDLE"; - } - - return ""; -}; - -static const char *site_sync2str(enum gptp_site_sync_sync_states state) -{ - switch (state) { - case GPTP_SSS_INITIALIZING: - return "INITIALIZING"; - case GPTP_SSS_RECEIVING_SYNC: - return "RECEIVING_SYNC"; - } - - return ""; -} - -static const char *clk_slave2str(enum gptp_clk_slave_sync_states state) -{ - switch (state) { - case GPTP_CLK_SLAVE_SYNC_INITIALIZING: - return "INITIALIZING"; - case GPTP_CLK_SLAVE_SYNC_SEND_SYNC_IND: - return "SEND_SYNC_IND"; - } - - return ""; -}; - -static const char *pr_selection2str(enum gptp_pr_selection_states state) -{ - switch (state) { - case GPTP_PR_SELECTION_INIT_BRIDGE: - return "INIT_BRIDGE"; - case GPTP_PR_SELECTION_ROLE_SELECTION: - return "ROLE_SELECTION"; - } - - return ""; -}; - -static const char *cms_rcv2str(enum gptp_cms_rcv_states state) -{ - switch (state) { - case GPTP_CMS_RCV_INITIALIZING: - return "INITIALIZING"; - case GPTP_CMS_RCV_WAITING: - return "WAITING"; - case GPTP_CMS_RCV_SOURCE_TIME: - return "SOURCE_TIME"; - } - - return ""; -}; - -#if !defined(USCALED_NS_TO_NS) -#define USCALED_NS_TO_NS(val) (val >> 16) -#endif - -static const char *selected_role_str(int port) -{ - switch (GPTP_GLOBAL_DS()->selected_role[port]) { - case GPTP_PORT_INITIALIZING: - return "INITIALIZING"; - case GPTP_PORT_FAULTY: - return "FAULTY"; - case GPTP_PORT_DISABLED: - return "DISABLED"; - case GPTP_PORT_LISTENING: - return "LISTENING"; - case GPTP_PORT_PRE_MASTER: - return "PRE-MASTER"; - case GPTP_PORT_MASTER: - return "MASTER"; - case GPTP_PORT_PASSIVE: - return "PASSIVE"; - case GPTP_PORT_UNCALIBRATED: - return "UNCALIBRATED"; - case GPTP_PORT_SLAVE: - return "SLAVE"; - } - - return ""; -} - -static void gptp_print_port_info(const struct shell *sh, int port) -{ - struct gptp_port_bmca_data *port_bmca_data; - struct gptp_port_param_ds *port_param_ds; - struct gptp_port_states *port_state; - struct gptp_domain *domain; - struct gptp_port_ds *port_ds; - struct net_if *iface; - int ret, i; - - domain = gptp_get_domain(); - - ret = gptp_get_port_data(domain, - port, - &port_ds, - &port_param_ds, - &port_state, - &port_bmca_data, - &iface); - if (ret < 0) { - PR_WARNING("Cannot get gPTP information for port %d (%d)\n", - port, ret); - return; - } - - NET_ASSERT(port == port_ds->port_id.port_number, - "Port number mismatch! (%d vs %d)", port, - port_ds->port_id.port_number); - - PR("Port id : %d (%s)\n", port_ds->port_id.port_number, - selected_role_str(port_ds->port_id.port_number)); - PR("Interface : %p [%d]\n", iface, net_if_get_by_iface(iface)); - PR("Clock id : "); - for (i = 0; i < sizeof(port_ds->port_id.clk_id); i++) { - PR("%02x", port_ds->port_id.clk_id[i]); - - if (i != (sizeof(port_ds->port_id.clk_id) - 1)) { - PR(":"); - } - } - PR("\n"); - - PR("Version : %d\n", port_ds->version); - PR("AS capable : %s\n", port_ds->as_capable ? "yes" : "no"); - - PR("\nConfiguration:\n"); - PR("Time synchronization and Best Master Selection enabled " - ": %s\n", port_ds->ptt_port_enabled ? "yes" : "no"); - PR("The port is measuring the path delay " - ": %s\n", port_ds->is_measuring_delay ? "yes" : "no"); - PR("One way propagation time on %s : %u ns\n", - "the link attached to this port", - (uint32_t)port_ds->neighbor_prop_delay); - PR("Propagation time threshold for %s : %u ns\n", - "the link attached to this port", - (uint32_t)port_ds->neighbor_prop_delay_thresh); - PR("Estimate of the ratio of the frequency with the peer " - ": %u\n", (uint32_t)port_ds->neighbor_rate_ratio); - PR("Asymmetry on the link relative to the grand master time base " - ": %" PRId64 "\n", port_ds->delay_asymmetry); - PR("Maximum interval between sync %s " - ": %" PRIu64 "\n", "messages", - port_ds->sync_receipt_timeout_time_itv); - PR("Maximum number of Path Delay Requests without a response " - ": %d\n", port_ds->allowed_lost_responses); - PR("Current Sync %s : %d\n", - "sequence id for this port", port_ds->sync_seq_id); - PR("Current Path Delay Request %s : %d\n", - "sequence id for this port", port_ds->pdelay_req_seq_id); - PR("Current Announce %s : %d\n", - "sequence id for this port", port_ds->announce_seq_id); - PR("Current Signaling %s : %d\n", - "sequence id for this port", port_ds->signaling_seq_id); - PR("Whether neighborRateRatio %s : %s\n", - "needs to be computed for this port", - port_ds->compute_neighbor_rate_ratio ? "yes" : "no"); - PR("Whether neighborPropDelay %s : %s\n", - "needs to be computed for this port", - port_ds->compute_neighbor_prop_delay ? "yes" : "no"); - PR("Initial Announce Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->ini_log_announce_itv); - PR("Current Announce Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->cur_log_announce_itv); - PR("Initial Sync Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->ini_log_half_sync_itv); - PR("Current Sync Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->cur_log_half_sync_itv); - PR("Initial Path Delay Request Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->ini_log_pdelay_req_itv); - PR("Current Path Delay Request Interval %s : %d\n", - "as a Logarithm to base 2", port_ds->cur_log_pdelay_req_itv); - PR("Time without receiving announce %s %s : %d ms (%d)\n", - "messages", "before running BMCA", - gptp_uscaled_ns_to_timer_ms( - &port_bmca_data->ann_rcpt_timeout_time_interval), - port_ds->announce_receipt_timeout); - PR("Time without receiving sync %s %s : %" PRIu64 " ms (%d)\n", - "messages", "before running BMCA", - (port_ds->sync_receipt_timeout_time_itv >> 16) / - (NSEC_PER_SEC / MSEC_PER_SEC), - port_ds->sync_receipt_timeout); - PR("Sync event %s : %" PRIu64 " ms\n", - "transmission interval for the port", - USCALED_NS_TO_NS(port_ds->half_sync_itv.low) / - (NSEC_PER_USEC * USEC_PER_MSEC)); - PR("Path Delay Request %s : %" PRIu64 " ms\n", - "transmission interval for the port", - USCALED_NS_TO_NS(port_ds->pdelay_req_itv.low) / - (NSEC_PER_USEC * USEC_PER_MSEC)); - PR("BMCA %s %s%d%s: %d\n", "default", "priority", 1, - " ", - domain->default_ds.priority1); - PR("BMCA %s %s%d%s: %d\n", "default", "priority", 2, - " ", - domain->default_ds.priority2); - - PR("\nRuntime status:\n"); - PR("Current global port state " - " : %s\n", selected_role_str(port)); - PR("Path Delay Request state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pdelay_req2str(port_state->pdelay_req.state)); - PR("\tInitial Path Delay Response Peer Timestamp " - ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_evt_tstamp); - PR("\tInitial Path Delay Response Ingress Timestamp " - ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_ingress_tstamp); - PR("\tPath Delay Response %s %s : %u\n", - "messages", "received", - port_state->pdelay_req.rcvd_pdelay_resp); - PR("\tPath Delay Follow Up %s %s : %u\n", - "messages", "received", - port_state->pdelay_req.rcvd_pdelay_follow_up); - PR("\tNumber of lost Path Delay Responses " - ": %u\n", port_state->pdelay_req.lost_responses); - PR("\tTimer expired send a new Path Delay Request " - ": %u\n", port_state->pdelay_req.pdelay_timer_expired); - PR("\tNeighborRateRatio has been computed successfully " - ": %u\n", port_state->pdelay_req.neighbor_rate_ratio_valid); - PR("\tPath Delay has already been computed after init " - ": %u\n", port_state->pdelay_req.init_pdelay_compute); - PR("\tCount consecutive reqs with multiple responses " - ": %u\n", port_state->pdelay_req.multiple_resp_count); - - PR("Path Delay Response state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pdelay_resp2str(port_state->pdelay_resp.state)); - - PR("SyncReceive state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", sync_rcv2str(port_state->sync_rcv.state)); - PR("\tA Sync %s %s : %s\n", - "Message", "has been received", - port_state->sync_rcv.rcvd_sync ? "yes" : "no"); - PR("\tA Follow Up %s %s : %s\n", - "Message", "has been received", - port_state->sync_rcv.rcvd_follow_up ? "yes" : "no"); - PR("\tA Follow Up %s %s : %s\n", - "Message", "timeout", - port_state->sync_rcv.follow_up_timeout_expired ? "yes" : "no"); - PR("\tTime at which a Sync %s without Follow Up\n" - "\t will be discarded " - ": %" PRIu64 "\n", "Message", - port_state->sync_rcv.follow_up_receipt_timeout); - - PR("SyncSend state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", sync_send2str(port_state->sync_send.state)); - PR("\tA MDSyncSend structure %s : %s\n", - "has been received", - port_state->sync_send.rcvd_md_sync ? "yes" : "no"); - PR("\tThe timestamp for the sync msg %s : %s\n", - "has been received", - port_state->sync_send.md_sync_timestamp_avail ? "yes" : "no"); - - PR("PortSyncSyncReceive state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pss_rcv2str(port_state->pss_rcv.state)); - PR("\tGrand Master / Local Clock frequency ratio " - ": %f\n", port_state->pss_rcv.rate_ratio); - PR("\tA MDSyncReceive struct is ready to be processed " - ": %s\n", port_state->pss_rcv.rcvd_md_sync ? "yes" : "no"); - PR("\tExpiry of SyncReceiptTimeoutTimer : %s\n", - port_state->pss_rcv.rcv_sync_receipt_timeout_timer_expired ? - "yes" : "no"); - - PR("PortSyncSyncSend state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pss_send2str(port_state->pss_send.state)); - PR("\tFollow Up Correction Field of last recv PSS " - ": %" PRId64 "\n", - port_state->pss_send.last_follow_up_correction_field); - PR("\tUpstream Tx Time of the last recv PortSyncSync " - ": %" PRIu64 "\n", port_state->pss_send.last_upstream_tx_time); - PR("\tRate Ratio of the last received PortSyncSync " - ": %f\n", - port_state->pss_send.last_rate_ratio); - PR("\tGM Freq Change of the last received PortSyncSync " - ": %f\n", port_state->pss_send.last_gm_freq_change); - PR("\tGM Time Base Indicator of last recv PortSyncSync " - ": %d\n", port_state->pss_send.last_gm_time_base_indicator); - PR("\tReceived Port Number of last recv PortSyncSync " - ": %d\n", - port_state->pss_send.last_rcvd_port_num); - PR("\tPortSyncSync structure is ready to be processed " - ": %s\n", port_state->pss_send.rcvd_pss_sync ? "yes" : "no"); - PR("\tFlag when the %s has expired : %s\n", - "half_sync_itv_timer", - port_state->pss_send.half_sync_itv_timer_expired ? "yes" : "no"); - PR("\tHas %s expired twice : %s\n", - "half_sync_itv_timer", - port_state->pss_send.sync_itv_timer_expired ? "yes" : "no"); - PR("\tHas syncReceiptTimeoutTime expired " - ": %s\n", - port_state->pss_send.send_sync_receipt_timeout_timer_expired ? - "yes" : "no"); - - PR("PortAnnounceReceive state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pa_rcv2str(port_state->pa_rcv.state)); - PR("\tAn announce message is ready to be processed " - ": %s\n", - port_state->pa_rcv.rcvd_announce ? "yes" : "no"); - - PR("PortAnnounceInformation state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pa_info2str(port_state->pa_info.state)); - PR("\tExpired announce information " - ": %s\n", port_state->pa_info.ann_expired ? "yes" : "no"); - - PR("PortAnnounceTransmit state machine variables:\n"); - PR("\tCurrent state " - ": %s\n", pa_transmit2str(port_state->pa_transmit.state)); - PR("\tTrigger announce information " - ": %s\n", port_state->pa_transmit.ann_trigger ? "yes" : "no"); - -#if defined(CONFIG_NET_GPTP_STATISTICS) - PR("\nStatistics:\n"); - PR("Sync %s %s : %u\n", - "messages", "received", port_param_ds->rx_sync_count); - PR("Follow Up %s %s : %u\n", - "messages", "received", port_param_ds->rx_fup_count); - PR("Path Delay Request %s %s : %u\n", - "messages", "received", port_param_ds->rx_pdelay_req_count); - PR("Path Delay Response %s %s : %u\n", - "messages", "received", port_param_ds->rx_pdelay_resp_count); - PR("Path Delay %s threshold %s : %u\n", - "messages", "exceeded", - port_param_ds->neighbor_prop_delay_exceeded); - PR("Path Delay Follow Up %s %s : %u\n", - "messages", "received", port_param_ds->rx_pdelay_resp_fup_count); - PR("Announce %s %s : %u\n", - "messages", "received", port_param_ds->rx_announce_count); - PR("ptp %s discarded : %u\n", - "messages", port_param_ds->rx_ptp_packet_discard_count); - PR("Sync %s %s : %u\n", - "reception", "timeout", - port_param_ds->sync_receipt_timeout_count); - PR("Announce %s %s : %u\n", - "reception", "timeout", - port_param_ds->announce_receipt_timeout_count); - PR("Path Delay Requests without a response " - ": %u\n", - port_param_ds->pdelay_allowed_lost_resp_exceed_count); - PR("Sync %s %s : %u\n", - "messages", "sent", port_param_ds->tx_sync_count); - PR("Follow Up %s %s : %u\n", - "messages", "sent", port_param_ds->tx_fup_count); - PR("Path Delay Request %s %s : %u\n", - "messages", "sent", port_param_ds->tx_pdelay_req_count); - PR("Path Delay Response %s %s : %u\n", - "messages", "sent", port_param_ds->tx_pdelay_resp_count); - PR("Path Delay Response FUP %s %s : %u\n", - "messages", "sent", port_param_ds->tx_pdelay_resp_fup_count); - PR("Announce %s %s : %u\n", - "messages", "sent", port_param_ds->tx_announce_count); -#endif /* CONFIG_NET_GPTP_STATISTICS */ -} -#endif /* CONFIG_NET_GPTP */ - -static int cmd_net_gptp_port(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_GPTP) - int arg = 1; - char *endptr; - int port; -#endif - -#if defined(CONFIG_NET_GPTP) - if (!argv[arg]) { - PR_WARNING("Port number must be given.\n"); - return -ENOEXEC; - } - - port = strtol(argv[arg], &endptr, 10); - - if (*endptr == '\0') { - gptp_print_port_info(sh, port); - } else { - PR_WARNING("Not a valid gPTP port number: %s\n", argv[arg]); - } -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP"); -#endif - - return 0; -} - -static int cmd_net_gptp(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_GPTP) - /* gPTP status */ - struct gptp_domain *domain = gptp_get_domain(); - int count = 0; - int arg = 1; -#endif - -#if defined(CONFIG_NET_GPTP) - if (argv[arg]) { - cmd_net_gptp_port(sh, argc, argv); - } else { - struct net_shell_user_data user_data; - - user_data.sh = sh; - user_data.user_data = &count; - - gptp_foreach_port(gptp_port_cb, &user_data); - - PR("\n"); - - PR("SiteSyncSync state machine variables:\n"); - PR("\tCurrent state : %s\n", - site_sync2str(domain->state.site_ss.state)); - PR("\tA PortSyncSync struct is ready : %s\n", - domain->state.site_ss.rcvd_pss ? "yes" : "no"); - - PR("ClockSlaveSync state machine variables:\n"); - PR("\tCurrent state : %s\n", - clk_slave2str(domain->state.clk_slave_sync.state)); - PR("\tA PortSyncSync struct is ready : %s\n", - domain->state.clk_slave_sync.rcvd_pss ? "yes" : "no"); - PR("\tThe local clock has expired : %s\n", - domain->state.clk_slave_sync.rcvd_local_clk_tick ? - "yes" : "no"); - - PR("PortRoleSelection state machine variables:\n"); - PR("\tCurrent state : %s\n", - pr_selection2str(domain->state.pr_sel.state)); - - PR("ClockMasterSyncReceive state machine variables:\n"); - PR("\tCurrent state : %s\n", - cms_rcv2str(domain->state.clk_master_sync_receive.state)); - PR("\tA ClockSourceTime : %s\n", - domain->state.clk_master_sync_receive.rcvd_clock_source_req - ? "yes" : "no"); - PR("\tThe local clock has expired : %s\n", - domain->state.clk_master_sync_receive.rcvd_local_clock_tick - ? "yes" : "no"); - } -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP"); -#endif - - return 0; -} static int get_iface_idx(const struct shell *sh, char *index_str) { @@ -4947,14 +4320,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_gptp, - SHELL_CMD(port, NULL, - "'net gptp []' prints detailed information about " - "gPTP port.", - cmd_net_gptp_port), - SHELL_SUBCMD_SET_END -); - #if !defined(NET_VLAN_MAX_COUNT) #define MAX_IFACE_COUNT NET_IF_MAX_CONFIGS #else @@ -5276,8 +4641,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(gptp, &net_cmd_gptp, "Print information about gPTP support.", - cmd_net_gptp), SHELL_CMD(iface, &net_cmd_iface, "Print information about network interfaces.", cmd_net_iface), From 49012a5c6b42c0c00c53d0368268a877df9de41a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 11:54:27 +0300 Subject: [PATCH 2366/4498] net: shell: Add iface command Move "iface" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/common.h | 19 + subsys/net/lib/shell/iface.c | 721 ++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 775 +--------------------------- 4 files changed, 766 insertions(+), 750 deletions(-) create mode 100644 subsys/net/lib/shell/iface.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index ea973a6cec2..c6b62271825 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_sources(conn.c) zephyr_library_sources(dns.c) zephyr_library_sources(events.c) zephyr_library_sources(gptp.c) +zephyr_library_sources(iface.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h index 160d1f3ccbf..4953d7cfec0 100644 --- a/subsys/net/lib/shell/common.h +++ b/subsys/net/lib/shell/common.h @@ -30,9 +30,28 @@ struct net_shell_user_data { void *user_data; }; +#if !defined(NET_VLAN_MAX_COUNT) +#define MAX_IFACE_COUNT NET_IF_MAX_CONFIGS +#else +#define MAX_IFACE_COUNT NET_VLAN_MAX_COUNT +#endif + +#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") +#define MAX_IFACE_STR_LEN sizeof("xxx") + +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) +#define IFACE_DYN_CMD &iface_index + +void iface_index_get(size_t idx, struct shell_static_entry *entry); +#else +#define IFACE_DYN_CMD NULL +#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + const char *addrtype2str(enum net_addr_type addr_type); const char *addrstate2str(enum net_addr_state addr_state); void get_addresses(struct net_context *context, char addr_local[], int local_len, char addr_remote[], int remote_len); void events_enable(void); +int get_iface_idx(const struct shell *sh, char *index_str); +const char *iface2str(struct net_if *iface, const char **extra); diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c new file mode 100644 index 00000000000..e024bdc1194 --- /dev/null +++ b/subsys/net/lib/shell/iface.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#if defined(CONFIG_NET_L2_ETHERNET) +#include +#endif +#if defined(CONFIG_NET_L2_ETHERNET_MGMT) +#include +#endif +#if defined(CONFIG_NET_L2_VIRTUAL) +#include +#endif + +#include "common.h" + +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) + +static char iface_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; +static char iface_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; + +SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); + +static char *set_iface_index_buffer(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + if (!iface) { + return NULL; + } + + snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); + + return iface_index_buffer[idx]; +} + +static char *set_iface_index_help(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + if (!iface) { + return NULL; + } + + snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "%s (%p)", iface2str(iface, NULL), iface); + + return iface_help_buffer[idx]; +} + +void iface_index_get(size_t idx, struct shell_static_entry *entry) +{ + entry->handler = NULL; + entry->help = set_iface_index_help(idx); + entry->subcmd = &iface_index; + entry->syntax = set_iface_index_buffer(idx); +} + +#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + +#if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_NATIVE) +struct ethernet_capabilities { + enum ethernet_hw_caps capability; + const char * const description; +}; + +#define EC(cap, desc) { .capability = cap, .description = desc } + +static struct ethernet_capabilities eth_hw_caps[] = { + EC(ETHERNET_HW_TX_CHKSUM_OFFLOAD, "TX checksum offload"), + EC(ETHERNET_HW_RX_CHKSUM_OFFLOAD, "RX checksum offload"), + EC(ETHERNET_HW_VLAN, "Virtual LAN"), + EC(ETHERNET_HW_VLAN_TAG_STRIP, "VLAN Tag stripping"), + EC(ETHERNET_AUTO_NEGOTIATION_SET, "Auto negotiation"), + EC(ETHERNET_LINK_10BASE_T, "10 Mbits"), + EC(ETHERNET_LINK_100BASE_T, "100 Mbits"), + EC(ETHERNET_LINK_1000BASE_T, "1 Gbits"), + EC(ETHERNET_DUPLEX_SET, "Half/full duplex"), + EC(ETHERNET_PTP, "IEEE 802.1AS gPTP clock"), + EC(ETHERNET_QAV, "IEEE 802.1Qav (credit shaping)"), + EC(ETHERNET_QBV, "IEEE 802.1Qbv (scheduled traffic)"), + EC(ETHERNET_QBU, "IEEE 802.1Qbu (frame preemption)"), + EC(ETHERNET_TXTIME, "TXTIME"), + EC(ETHERNET_PROMISC_MODE, "Promiscuous mode"), + EC(ETHERNET_PRIORITY_QUEUES, "Priority queues"), + EC(ETHERNET_HW_FILTERING, "MAC address filtering"), + EC(ETHERNET_DSA_SLAVE_PORT, "DSA slave port"), + EC(ETHERNET_DSA_MASTER_PORT, "DSA master port"), +}; + +static void print_supported_ethernet_capabilities( + const struct shell *sh, struct net_if *iface) +{ + enum ethernet_hw_caps caps = net_eth_get_hw_capabilities(iface); + int i; + + for (i = 0; i < ARRAY_SIZE(eth_hw_caps); i++) { + if (caps & eth_hw_caps[i].capability) { + PR("\t%s\n", eth_hw_caps[i].description); + } + } +} +#endif /* CONFIG_NET_L2_ETHERNET */ + +#if defined(CONFIG_NET_NATIVE) +static const char *iface_flags2str(struct net_if *iface) +{ + static char str[sizeof("POINTOPOINT") + sizeof("PROMISC") + + sizeof("NO_AUTO_START") + sizeof("SUSPENDED") + + sizeof("MCAST_FORWARD") + sizeof("IPv4") + + sizeof("IPv6") + sizeof("NO_ND") + sizeof("NO_MLD")]; + int pos = 0; + + if (net_if_flag_is_set(iface, NET_IF_POINTOPOINT)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "POINTOPOINT,"); + } + + if (net_if_flag_is_set(iface, NET_IF_PROMISC)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "PROMISC,"); + } + + if (net_if_flag_is_set(iface, NET_IF_NO_AUTO_START)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "NO_AUTO_START,"); + } else { + pos += snprintk(str + pos, sizeof(str) - pos, + "AUTO_START,"); + } + + if (net_if_flag_is_set(iface, NET_IF_FORWARD_MULTICASTS)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "MCAST_FORWARD,"); + } + + if (net_if_flag_is_set(iface, NET_IF_IPV4)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "IPv4,"); + } + + if (net_if_flag_is_set(iface, NET_IF_IPV6)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "IPv6,"); + } + + if (net_if_flag_is_set(iface, NET_IF_IPV6_NO_ND)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "NO_ND,"); + } + + if (net_if_flag_is_set(iface, NET_IF_IPV6_NO_MLD)) { + pos += snprintk(str + pos, sizeof(str) - pos, + "NO_MLD,"); + } + + /* get rid of last ',' character */ + str[pos - 1] = '\0'; + + return str; +} +#endif + +static void iface_cb(struct net_if *iface, void *user_data) +{ +#if defined(CONFIG_NET_NATIVE) + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + +#if defined(CONFIG_NET_IPV6) + struct net_if_ipv6_prefix *prefix; + struct net_if_router *router; + struct net_if_ipv6 *ipv6; +#endif +#if defined(CONFIG_NET_IPV4) + struct net_if_ipv4 *ipv4; +#endif +#if defined(CONFIG_NET_VLAN) + struct ethernet_context *eth_ctx; +#endif +#if defined(CONFIG_NET_IP) + struct net_if_addr *unicast; + struct net_if_mcast_addr *mcast; +#endif +#if defined(CONFIG_NET_L2_ETHERNET_MGMT) + struct ethernet_req_params params; + int ret; +#endif + const char *extra; +#if defined(CONFIG_NET_IP) + int i, count; +#endif + + if (data->user_data && data->user_data != iface) { + return; + } + +#if defined(CONFIG_NET_INTERFACE_NAME) + char ifname[CONFIG_NET_INTERFACE_NAME_LEN + 1] = { 0 }; + int ret_name; + + ret_name = net_if_get_name(iface, ifname, sizeof(ifname) - 1); + if (ret_name < 1 || ifname[0] == '\0') { + snprintk(ifname, sizeof(ifname), "?"); + } + + PR("\nInterface %s (%p) (%s) [%d]\n", ifname, iface, iface2str(iface, &extra), + net_if_get_by_iface(iface)); +#else + PR("\nInterface %p (%s) [%d]\n", iface, iface2str(iface, &extra), + net_if_get_by_iface(iface)); +#endif + PR("===========================%s\n", extra); + + if (!net_if_is_up(iface)) { + PR_INFO("Interface is down.\n"); + + /* Show detailed information only when user asks information + * about one specific network interface. + */ + if (data->user_data == NULL) { + return; + } + } + +#ifdef CONFIG_NET_POWER_MANAGEMENT + if (net_if_is_suspended(iface)) { + PR_INFO("Interface is suspended, thus not able to tx/rx.\n"); + } +#endif + +#if defined(CONFIG_NET_L2_VIRTUAL) + if (!sys_slist_is_empty(&iface->config.virtual_interfaces)) { + struct virtual_interface_context *ctx, *tmp; + + PR("Virtual interfaces attached to this : "); + SYS_SLIST_FOR_EACH_CONTAINER_SAFE( + &iface->config.virtual_interfaces, + ctx, tmp, node) { + if (ctx->virtual_iface == iface) { + continue; + } + + PR("%d ", net_if_get_by_iface(ctx->virtual_iface)); + } + + PR("\n"); + } + + if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) { + struct net_if *orig_iface; + char *name, buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; + + name = net_virtual_get_name(iface, buf, sizeof(buf)); + if (!(name && name[0])) { + name = ""; + } + + PR("Name : %s\n", name); + + orig_iface = net_virtual_get_iface(iface); + if (orig_iface == NULL) { + PR("No attached network interface.\n"); + } else { + PR("Attached : %d (%s / %p)\n", + net_if_get_by_iface(orig_iface), + iface2str(orig_iface, NULL), + orig_iface); + } + } +#endif /* CONFIG_NET_L2_VIRTUAL */ + + net_if_lock(iface); + if (net_if_get_link_addr(iface) && + net_if_get_link_addr(iface)->addr) { + PR("Link addr : %s\n", + net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, + net_if_get_link_addr(iface)->len)); + } + net_if_unlock(iface); + + PR("MTU : %d\n", net_if_get_mtu(iface)); + PR("Flags : %s\n", iface_flags2str(iface)); + +#if defined(CONFIG_NET_L2_ETHERNET_MGMT) + if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + count = 0; + ret = net_mgmt(NET_REQUEST_ETHERNET_GET_PRIORITY_QUEUES_NUM, + iface, ¶ms, + sizeof(struct ethernet_req_params)); + + if (!ret && params.priority_queues_num) { + count = params.priority_queues_num; + PR("Priority queues:\n"); + for (i = 0; i < count; ++i) { + params.qav_param.queue_id = i; + params.qav_param.type = + ETHERNET_QAV_PARAM_TYPE_STATUS; + ret = net_mgmt( + NET_REQUEST_ETHERNET_GET_QAV_PARAM, + iface, ¶ms, + sizeof(struct ethernet_req_params)); + + PR("\t%d: Qav ", i); + if (ret) { + PR("not supported\n"); + } else { + PR("%s\n", + params.qav_param.enabled ? + "enabled" : + "disabled"); + } + } + } + } +#endif + +#if defined(CONFIG_NET_PROMISCUOUS_MODE) + PR("Promiscuous mode : %s\n", + net_if_is_promisc(iface) ? "enabled" : "disabled"); +#endif + +#if defined(CONFIG_NET_VLAN) + if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + eth_ctx = net_if_l2_data(iface); + + if (eth_ctx->vlan_enabled) { + for (i = 0; i < CONFIG_NET_VLAN_COUNT; i++) { + if (eth_ctx->vlan[i].iface != iface || + eth_ctx->vlan[i].tag == + NET_VLAN_TAG_UNSPEC) { + continue; + } + + PR("VLAN tag : %d (0x%x)\n", + eth_ctx->vlan[i].tag, + eth_ctx->vlan[i].tag); + } + } else { + PR("VLAN not enabled\n"); + } + } +#endif + +#ifdef CONFIG_NET_L2_ETHERNET + if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + PR("Ethernet capabilities supported:\n"); + print_supported_ethernet_capabilities(sh, iface); + } +#endif /* CONFIG_NET_L2_ETHERNET */ + +#if defined(CONFIG_NET_IPV6) + count = 0; + + if (!net_if_flag_is_set(iface, NET_IF_IPV6)) { + PR("%s not %s for this interface.\n", "IPv6", "enabled"); + ipv6 = NULL; + goto skip_ipv6; + } + + ipv6 = iface->config.ip.ipv6; + + PR("IPv6 unicast addresses (max %d):\n", NET_IF_MAX_IPV6_ADDR); + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_ADDR; i++) { + unicast = &ipv6->unicast[i]; + + if (!unicast->is_used) { + continue; + } + + PR("\t%s %s %s%s%s\n", + net_sprint_ipv6_addr(&unicast->address.in6_addr), + addrtype2str(unicast->addr_type), + addrstate2str(unicast->addr_state), + unicast->is_infinite ? " infinite" : "", + unicast->is_mesh_local ? " meshlocal" : ""); + count++; + } + + if (count == 0) { + PR("\t\n"); + } + + count = 0; + + PR("IPv6 multicast addresses (max %d):\n", NET_IF_MAX_IPV6_MADDR); + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_MADDR; i++) { + mcast = &ipv6->mcast[i]; + + if (!mcast->is_used) { + continue; + } + + PR("\t%s\n", net_sprint_ipv6_addr(&mcast->address.in6_addr)); + + count++; + } + + if (count == 0) { + PR("\t\n"); + } + + count = 0; + + PR("IPv6 prefixes (max %d):\n", NET_IF_MAX_IPV6_PREFIX); + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_PREFIX; i++) { + prefix = &ipv6->prefix[i]; + + if (!prefix->is_used) { + continue; + } + + PR("\t%s/%d%s\n", + net_sprint_ipv6_addr(&prefix->prefix), + prefix->len, prefix->is_infinite ? " infinite" : ""); + + count++; + } + + if (count == 0) { + PR("\t\n"); + } + + router = net_if_ipv6_router_find_default(iface, NULL); + if (router) { + PR("IPv6 default router :\n"); + PR("\t%s%s\n", + net_sprint_ipv6_addr(&router->address.in6_addr), + router->is_infinite ? " infinite" : ""); + } + +skip_ipv6: + + if (ipv6) { + PR("IPv6 hop limit : %d\n", + ipv6->hop_limit); + PR("IPv6 base reachable time : %d\n", + ipv6->base_reachable_time); + PR("IPv6 reachable time : %d\n", + ipv6->reachable_time); + PR("IPv6 retransmit timer : %d\n", + ipv6->retrans_timer); + } +#endif /* CONFIG_NET_IPV6 */ + +#if defined(CONFIG_NET_IPV4) + /* No need to print IPv4 information for interface that does not + * support that protocol. + */ + if ( +#if defined(CONFIG_NET_L2_IEEE802154) + (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) || +#endif +#if defined(CONFIG_NET_L2_BT) + (net_if_l2(iface) == &NET_L2_GET_NAME(BLUETOOTH)) || +#endif + 0) { + PR_WARNING("%s not %s for this interface.\n", "IPv4", + "supported"); + return; + } + + count = 0; + + if (!net_if_flag_is_set(iface, NET_IF_IPV4)) { + PR("%s not %s for this interface.\n", "IPv4", "enabled"); + ipv4 = NULL; + goto skip_ipv4; + } + + ipv4 = iface->config.ip.ipv4; + + PR("IPv4 unicast addresses (max %d):\n", NET_IF_MAX_IPV4_ADDR); + for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) { + unicast = &ipv4->unicast[i]; + + if (!unicast->is_used) { + continue; + } + + PR("\t%s %s %s%s\n", + net_sprint_ipv4_addr(&unicast->address.in_addr), + addrtype2str(unicast->addr_type), + addrstate2str(unicast->addr_state), + unicast->is_infinite ? " infinite" : ""); + + count++; + } + + if (count == 0) { + PR("\t\n"); + } + + count = 0; + + PR("IPv4 multicast addresses (max %d):\n", NET_IF_MAX_IPV4_MADDR); + for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_MADDR; i++) { + mcast = &ipv4->mcast[i]; + + if (!mcast->is_used) { + continue; + } + + PR("\t%s\n", net_sprint_ipv4_addr(&mcast->address.in_addr)); + + count++; + } + + if (count == 0) { + PR("\t\n"); + } + +skip_ipv4: + + if (ipv4) { + PR("IPv4 gateway : %s\n", + net_sprint_ipv4_addr(&ipv4->gw)); + PR("IPv4 netmask : %s\n", + net_sprint_ipv4_addr(&ipv4->netmask)); + } +#endif /* CONFIG_NET_IPV4 */ + +#if defined(CONFIG_NET_DHCPV4) + PR("DHCPv4 lease time : %u\n", + iface->config.dhcpv4.lease_time); + PR("DHCPv4 renew time : %u\n", + iface->config.dhcpv4.renewal_time); + PR("DHCPv4 server : %s\n", + net_sprint_ipv4_addr(&iface->config.dhcpv4.server_id)); + PR("DHCPv4 requested : %s\n", + net_sprint_ipv4_addr(&iface->config.dhcpv4.requested_ip)); + PR("DHCPv4 state : %s\n", + net_dhcpv4_state_name(iface->config.dhcpv4.state)); + PR("DHCPv4 attempts : %d\n", + iface->config.dhcpv4.attempts); +#endif /* CONFIG_NET_DHCPV4 */ + +#else + ARG_UNUSED(iface); + ARG_UNUSED(user_data); + +#endif /* CONFIG_NET_NATIVE */ +} + +static int cmd_net_set_mac(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_NET_L2_ETHERNET) || !defined(CONFIG_NET_L2_ETHERNET_MGMT) + PR_WARNING("Unsupported command, please enable CONFIG_NET_L2_ETHERNET " + "and CONFIG_NET_L2_ETHERNET_MGMT\n"); + return -ENOEXEC; +#else + struct net_if *iface; + struct ethernet_req_params params; + char *mac_addr = params.mac_address.addr; + int idx; + int ret; + + if (argc < 3) { + PR_WARNING("Missing interface index and/or MAC address\n"); + goto err; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + goto err; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + goto err; + } + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + PR_WARNING("MAC address can be set only for Ethernet\n"); + goto err; + } + + if ((net_bytes_from_str(mac_addr, sizeof(params.mac_address), argv[2]) < 0) || + !net_eth_is_addr_valid(¶ms.mac_address)) { + PR_WARNING("Invalid MAC address: %s\n", argv[2]); + goto err; + } + + ret = net_mgmt(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, iface, ¶ms, sizeof(params)); + if (ret < 0) { + if (ret == -EACCES) { + PR_WARNING("MAC address cannot be set when interface is operational\n"); + goto err; + } + PR_WARNING("Failed to set MAC address (%d)\n", ret); + goto err; + } + + PR_INFO("MAC address set to %s\n", + net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, + net_if_get_link_addr(iface)->len)); + + return 0; +err: + return -ENOEXEC; +#endif /* CONFIG_NET_L2_ETHERNET */ +} + +static int cmd_net_iface_up(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + int idx, ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_if_is_up(iface)) { + PR_WARNING("Interface %d is already up.\n", idx); + return -ENOEXEC; + } + + ret = net_if_up(iface); + if (ret) { + PR_WARNING("Cannot take interface %d up (%d)\n", idx, ret); + return -ENOEXEC; + } + + PR("Interface %d is up\n", idx); + + return 0; +} + +static int cmd_net_iface_down(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + int idx, ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + ret = net_if_down(iface); + if (ret) { + PR_WARNING("Cannot take interface %d down (%d)\n", idx, ret); + return -ENOEXEC; + } + + PR("Interface %d is down\n", idx); + + return 0; +} + +static int cmd_net_iface(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = NULL; + struct net_shell_user_data user_data; + int idx; + + if (argv[1]) { + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + } + +#if defined(CONFIG_NET_HOSTNAME_ENABLE) + PR("Hostname: %s\n\n", net_hostname_get()); +#endif + + user_data.sh = sh; + user_data.user_data = iface; + + net_if_foreach(iface_cb, &user_data); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface, + SHELL_CMD(up, IFACE_DYN_CMD, + "'net iface up ' takes network interface up.", + cmd_net_iface_up), + SHELL_CMD(down, IFACE_DYN_CMD, + "'net iface down ' takes network interface " + "down.", + cmd_net_iface_down), + SHELL_CMD(show, IFACE_DYN_CMD, + "'net iface ' shows network interface " + "information.", + cmd_net_iface), + SHELL_CMD(set_mac, IFACE_DYN_CMD, + "'net iface set_mac ' sets MAC address for the network interface.", + cmd_net_set_mac), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), iface, &net_cmd_iface, + "Print information about network interfaces.", + cmd_net_iface, 1, 1); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index f9a79ffce82..4f60deaa231 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -41,10 +41,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "ipv6.h" -#if defined(CONFIG_NET_L2_ETHERNET) -#include -#endif - #if defined(CONFIG_NET_L2_ETHERNET_MGMT) #include #endif @@ -68,6 +64,30 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include "websocket/websocket_internal.h" +int get_iface_idx(const struct shell *sh, char *index_str) +{ + char *endptr; + int idx; + + if (!index_str) { + PR_WARNING("Interface index is missing.\n"); + return -EINVAL; + } + + idx = strtol(index_str, &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid index %s\n", index_str); + return -ENOENT; + } + + if (idx < 0 || idx > 255) { + PR_WARNING("Invalid index %d\n", idx); + return -ERANGE; + } + + return idx; +} + const char *addrtype2str(enum net_addr_type addr_type) { switch (addr_type) { @@ -140,7 +160,7 @@ void get_addresses(struct net_context *context, } #endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ -static const char *iface2str(struct net_if *iface, const char **extra) +const char *iface2str(struct net_if *iface, const char **extra) { #ifdef CONFIG_NET_L2_IEEE802154 if (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) { @@ -239,503 +259,6 @@ static const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_NATIVE) -struct ethernet_capabilities { - enum ethernet_hw_caps capability; - const char * const description; -}; - -#define EC(cap, desc) { .capability = cap, .description = desc } - -static struct ethernet_capabilities eth_hw_caps[] = { - EC(ETHERNET_HW_TX_CHKSUM_OFFLOAD, "TX checksum offload"), - EC(ETHERNET_HW_RX_CHKSUM_OFFLOAD, "RX checksum offload"), - EC(ETHERNET_HW_VLAN, "Virtual LAN"), - EC(ETHERNET_HW_VLAN_TAG_STRIP, "VLAN Tag stripping"), - EC(ETHERNET_AUTO_NEGOTIATION_SET, "Auto negotiation"), - EC(ETHERNET_LINK_10BASE_T, "10 Mbits"), - EC(ETHERNET_LINK_100BASE_T, "100 Mbits"), - EC(ETHERNET_LINK_1000BASE_T, "1 Gbits"), - EC(ETHERNET_DUPLEX_SET, "Half/full duplex"), - EC(ETHERNET_PTP, "IEEE 802.1AS gPTP clock"), - EC(ETHERNET_QAV, "IEEE 802.1Qav (credit shaping)"), - EC(ETHERNET_QBV, "IEEE 802.1Qbv (scheduled traffic)"), - EC(ETHERNET_QBU, "IEEE 802.1Qbu (frame preemption)"), - EC(ETHERNET_TXTIME, "TXTIME"), - EC(ETHERNET_PROMISC_MODE, "Promiscuous mode"), - EC(ETHERNET_PRIORITY_QUEUES, "Priority queues"), - EC(ETHERNET_HW_FILTERING, "MAC address filtering"), - EC(ETHERNET_DSA_SLAVE_PORT, "DSA slave port"), - EC(ETHERNET_DSA_MASTER_PORT, "DSA master port"), -}; - -static void print_supported_ethernet_capabilities( - const struct shell *sh, struct net_if *iface) -{ - enum ethernet_hw_caps caps = net_eth_get_hw_capabilities(iface); - int i; - - for (i = 0; i < ARRAY_SIZE(eth_hw_caps); i++) { - if (caps & eth_hw_caps[i].capability) { - PR("\t%s\n", eth_hw_caps[i].description); - } - } -} -#endif /* CONFIG_NET_L2_ETHERNET */ - -#if defined(CONFIG_NET_NATIVE) -static const char *iface_flags2str(struct net_if *iface) -{ - static char str[sizeof("POINTOPOINT") + sizeof("PROMISC") + - sizeof("NO_AUTO_START") + sizeof("SUSPENDED") + - sizeof("MCAST_FORWARD") + sizeof("IPv4") + - sizeof("IPv6") + sizeof("NO_ND") + sizeof("NO_MLD")]; - int pos = 0; - - if (net_if_flag_is_set(iface, NET_IF_POINTOPOINT)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "POINTOPOINT,"); - } - - if (net_if_flag_is_set(iface, NET_IF_PROMISC)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "PROMISC,"); - } - - if (net_if_flag_is_set(iface, NET_IF_NO_AUTO_START)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "NO_AUTO_START,"); - } else { - pos += snprintk(str + pos, sizeof(str) - pos, - "AUTO_START,"); - } - - if (net_if_flag_is_set(iface, NET_IF_FORWARD_MULTICASTS)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "MCAST_FORWARD,"); - } - - if (net_if_flag_is_set(iface, NET_IF_IPV4)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "IPv4,"); - } - - if (net_if_flag_is_set(iface, NET_IF_IPV6)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "IPv6,"); - } - - if (net_if_flag_is_set(iface, NET_IF_IPV6_NO_ND)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "NO_ND,"); - } - - if (net_if_flag_is_set(iface, NET_IF_IPV6_NO_MLD)) { - pos += snprintk(str + pos, sizeof(str) - pos, - "NO_MLD,"); - } - - /* get rid of last ',' character */ - str[pos - 1] = '\0'; - - return str; -} -#endif - -static void iface_cb(struct net_if *iface, void *user_data) -{ -#if defined(CONFIG_NET_NATIVE) - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - -#if defined(CONFIG_NET_IPV6) - struct net_if_ipv6_prefix *prefix; - struct net_if_router *router; - struct net_if_ipv6 *ipv6; -#endif -#if defined(CONFIG_NET_IPV4) - struct net_if_ipv4 *ipv4; -#endif -#if defined(CONFIG_NET_VLAN) - struct ethernet_context *eth_ctx; -#endif -#if defined(CONFIG_NET_IP) - struct net_if_addr *unicast; - struct net_if_mcast_addr *mcast; -#endif -#if defined(CONFIG_NET_L2_ETHERNET_MGMT) - struct ethernet_req_params params; - int ret; -#endif - const char *extra; -#if defined(CONFIG_NET_IP) - int i, count; -#endif - - if (data->user_data && data->user_data != iface) { - return; - } - -#if defined(CONFIG_NET_INTERFACE_NAME) - char ifname[CONFIG_NET_INTERFACE_NAME_LEN + 1] = { 0 }; - int ret_name; - - ret_name = net_if_get_name(iface, ifname, sizeof(ifname) - 1); - if (ret_name < 1 || ifname[0] == '\0') { - snprintk(ifname, sizeof(ifname), "?"); - } - - PR("\nInterface %s (%p) (%s) [%d]\n", ifname, iface, iface2str(iface, &extra), - net_if_get_by_iface(iface)); -#else - PR("\nInterface %p (%s) [%d]\n", iface, iface2str(iface, &extra), - net_if_get_by_iface(iface)); -#endif - PR("===========================%s\n", extra); - - if (!net_if_is_up(iface)) { - PR_INFO("Interface is down.\n"); - - /* Show detailed information only when user asks information - * about one specific network interface. - */ - if (data->user_data == NULL) { - return; - } - } - -#ifdef CONFIG_NET_POWER_MANAGEMENT - if (net_if_is_suspended(iface)) { - PR_INFO("Interface is suspended, thus not able to tx/rx.\n"); - } -#endif - -#if defined(CONFIG_NET_L2_VIRTUAL) - if (!sys_slist_is_empty(&iface->config.virtual_interfaces)) { - struct virtual_interface_context *ctx, *tmp; - - PR("Virtual interfaces attached to this : "); - SYS_SLIST_FOR_EACH_CONTAINER_SAFE( - &iface->config.virtual_interfaces, - ctx, tmp, node) { - if (ctx->virtual_iface == iface) { - continue; - } - - PR("%d ", net_if_get_by_iface(ctx->virtual_iface)); - } - - PR("\n"); - } - - if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) { - struct net_if *orig_iface; - char *name, buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; - - name = net_virtual_get_name(iface, buf, sizeof(buf)); - if (!(name && name[0])) { - name = ""; - } - - PR("Name : %s\n", name); - - orig_iface = net_virtual_get_iface(iface); - if (orig_iface == NULL) { - PR("No attached network interface.\n"); - } else { - PR("Attached : %d (%s / %p)\n", - net_if_get_by_iface(orig_iface), - iface2str(orig_iface, NULL), - orig_iface); - } - } -#endif /* CONFIG_NET_L2_VIRTUAL */ - - net_if_lock(iface); - if (net_if_get_link_addr(iface) && - net_if_get_link_addr(iface)->addr) { - PR("Link addr : %s\n", - net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, - net_if_get_link_addr(iface)->len)); - } - net_if_unlock(iface); - - PR("MTU : %d\n", net_if_get_mtu(iface)); - PR("Flags : %s\n", iface_flags2str(iface)); - -#if defined(CONFIG_NET_L2_ETHERNET_MGMT) - if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { - count = 0; - ret = net_mgmt(NET_REQUEST_ETHERNET_GET_PRIORITY_QUEUES_NUM, - iface, ¶ms, - sizeof(struct ethernet_req_params)); - - if (!ret && params.priority_queues_num) { - count = params.priority_queues_num; - PR("Priority queues:\n"); - for (i = 0; i < count; ++i) { - params.qav_param.queue_id = i; - params.qav_param.type = - ETHERNET_QAV_PARAM_TYPE_STATUS; - ret = net_mgmt( - NET_REQUEST_ETHERNET_GET_QAV_PARAM, - iface, ¶ms, - sizeof(struct ethernet_req_params)); - - PR("\t%d: Qav ", i); - if (ret) { - PR("not supported\n"); - } else { - PR("%s\n", - params.qav_param.enabled ? - "enabled" : - "disabled"); - } - } - } - } -#endif - -#if defined(CONFIG_NET_PROMISCUOUS_MODE) - PR("Promiscuous mode : %s\n", - net_if_is_promisc(iface) ? "enabled" : "disabled"); -#endif - -#if defined(CONFIG_NET_VLAN) - if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { - eth_ctx = net_if_l2_data(iface); - - if (eth_ctx->vlan_enabled) { - for (i = 0; i < CONFIG_NET_VLAN_COUNT; i++) { - if (eth_ctx->vlan[i].iface != iface || - eth_ctx->vlan[i].tag == - NET_VLAN_TAG_UNSPEC) { - continue; - } - - PR("VLAN tag : %d (0x%x)\n", - eth_ctx->vlan[i].tag, - eth_ctx->vlan[i].tag); - } - } else { - PR("VLAN not enabled\n"); - } - } -#endif - -#ifdef CONFIG_NET_L2_ETHERNET - if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { - PR("Ethernet capabilities supported:\n"); - print_supported_ethernet_capabilities(sh, iface); - } -#endif /* CONFIG_NET_L2_ETHERNET */ - -#if defined(CONFIG_NET_IPV6) - count = 0; - - if (!net_if_flag_is_set(iface, NET_IF_IPV6)) { - PR("%s not %s for this interface.\n", "IPv6", "enabled"); - ipv6 = NULL; - goto skip_ipv6; - } - - ipv6 = iface->config.ip.ipv6; - - PR("IPv6 unicast addresses (max %d):\n", NET_IF_MAX_IPV6_ADDR); - for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_ADDR; i++) { - unicast = &ipv6->unicast[i]; - - if (!unicast->is_used) { - continue; - } - - PR("\t%s %s %s%s%s\n", - net_sprint_ipv6_addr(&unicast->address.in6_addr), - addrtype2str(unicast->addr_type), - addrstate2str(unicast->addr_state), - unicast->is_infinite ? " infinite" : "", - unicast->is_mesh_local ? " meshlocal" : ""); - count++; - } - - if (count == 0) { - PR("\t\n"); - } - - count = 0; - - PR("IPv6 multicast addresses (max %d):\n", NET_IF_MAX_IPV6_MADDR); - for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_MADDR; i++) { - mcast = &ipv6->mcast[i]; - - if (!mcast->is_used) { - continue; - } - - PR("\t%s\n", net_sprint_ipv6_addr(&mcast->address.in6_addr)); - - count++; - } - - if (count == 0) { - PR("\t\n"); - } - - count = 0; - - PR("IPv6 prefixes (max %d):\n", NET_IF_MAX_IPV6_PREFIX); - for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_PREFIX; i++) { - prefix = &ipv6->prefix[i]; - - if (!prefix->is_used) { - continue; - } - - PR("\t%s/%d%s\n", - net_sprint_ipv6_addr(&prefix->prefix), - prefix->len, prefix->is_infinite ? " infinite" : ""); - - count++; - } - - if (count == 0) { - PR("\t\n"); - } - - router = net_if_ipv6_router_find_default(iface, NULL); - if (router) { - PR("IPv6 default router :\n"); - PR("\t%s%s\n", - net_sprint_ipv6_addr(&router->address.in6_addr), - router->is_infinite ? " infinite" : ""); - } - -skip_ipv6: - - if (ipv6) { - PR("IPv6 hop limit : %d\n", - ipv6->hop_limit); - PR("IPv6 base reachable time : %d\n", - ipv6->base_reachable_time); - PR("IPv6 reachable time : %d\n", - ipv6->reachable_time); - PR("IPv6 retransmit timer : %d\n", - ipv6->retrans_timer); - } -#endif /* CONFIG_NET_IPV6 */ - -#if defined(CONFIG_NET_IPV4) - /* No need to print IPv4 information for interface that does not - * support that protocol. - */ - if ( -#if defined(CONFIG_NET_L2_IEEE802154) - (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) || -#endif -#if defined(CONFIG_NET_L2_BT) - (net_if_l2(iface) == &NET_L2_GET_NAME(BLUETOOTH)) || -#endif - 0) { - PR_WARNING("%s not %s for this interface.\n", "IPv4", - "supported"); - return; - } - - count = 0; - - if (!net_if_flag_is_set(iface, NET_IF_IPV4)) { - PR("%s not %s for this interface.\n", "IPv4", "enabled"); - ipv4 = NULL; - goto skip_ipv4; - } - - ipv4 = iface->config.ip.ipv4; - - PR("IPv4 unicast addresses (max %d):\n", NET_IF_MAX_IPV4_ADDR); - for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) { - unicast = &ipv4->unicast[i]; - - if (!unicast->is_used) { - continue; - } - - PR("\t%s %s %s%s\n", - net_sprint_ipv4_addr(&unicast->address.in_addr), - addrtype2str(unicast->addr_type), - addrstate2str(unicast->addr_state), - unicast->is_infinite ? " infinite" : ""); - - count++; - } - - if (count == 0) { - PR("\t\n"); - } - - count = 0; - - PR("IPv4 multicast addresses (max %d):\n", NET_IF_MAX_IPV4_MADDR); - for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_MADDR; i++) { - mcast = &ipv4->mcast[i]; - - if (!mcast->is_used) { - continue; - } - - PR("\t%s\n", net_sprint_ipv4_addr(&mcast->address.in_addr)); - - count++; - } - - if (count == 0) { - PR("\t\n"); - } - -skip_ipv4: - - if (ipv4) { - PR("IPv4 gateway : %s\n", - net_sprint_ipv4_addr(&ipv4->gw)); - PR("IPv4 netmask : %s\n", - net_sprint_ipv4_addr(&ipv4->netmask)); - } -#endif /* CONFIG_NET_IPV4 */ - -#if defined(CONFIG_NET_DHCPV4) - PR("DHCPv4 lease time : %u\n", - iface->config.dhcpv4.lease_time); - PR("DHCPv4 renew time : %u\n", - iface->config.dhcpv4.renewal_time); - PR("DHCPv4 server : %s\n", - net_sprint_ipv4_addr(&iface->config.dhcpv4.server_id)); - PR("DHCPv4 requested : %s\n", - net_sprint_ipv4_addr(&iface->config.dhcpv4.requested_ip)); - PR("DHCPv4 state : %s\n", - net_dhcpv4_state_name(iface->config.dhcpv4.state)); - PR("DHCPv4 attempts : %d\n", - iface->config.dhcpv4.attempts); -#endif /* CONFIG_NET_DHCPV4 */ - -#if defined(CONFIG_NET_DHCPV6) - PR("DHCPv6 address requested : %s\n", - iface->config.dhcpv6.params.request_addr ? - net_sprint_ipv6_addr(&iface->config.dhcpv6.addr) : "none"); - PR("DHCPv6 prefix requested : %s\n", - iface->config.dhcpv6.params.request_prefix ? - net_sprint_ipv6_addr(&iface->config.dhcpv6.prefix) : "none"); - PR("DHCPv6 state : %s\n", - net_dhcpv6_state_name(iface->config.dhcpv6.state)); - PR("DHCPv6 attempts : %d\n", - iface->config.dhcpv6.retransmissions + 1); -#endif /* CONFIG_NET_DHCPV6 */ - -#else - ARG_UNUSED(iface); - ARG_UNUSED(user_data); - -#endif /* CONFIG_NET_NATIVE */ -} - #if defined(CONFIG_NET_ROUTE) && defined(CONFIG_NET_NATIVE) static void route_cb(struct net_route_entry *entry, void *user_data) { @@ -1412,92 +935,6 @@ static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ - -static int get_iface_idx(const struct shell *sh, char *index_str) -{ - char *endptr; - int idx; - - if (!index_str) { - PR_WARNING("Interface index is missing.\n"); - return -EINVAL; - } - - idx = strtol(index_str, &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid index %s\n", index_str); - return -ENOENT; - } - - if (idx < 0 || idx > 255) { - PR_WARNING("Invalid index %d\n", idx); - return -ERANGE; - } - - return idx; -} - -static int cmd_net_iface_up(const struct shell *sh, size_t argc, - char *argv[]) -{ - struct net_if *iface; - int idx, ret; - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_if_is_up(iface)) { - PR_WARNING("Interface %d is already up.\n", idx); - return -ENOEXEC; - } - - ret = net_if_up(iface); - if (ret) { - PR_WARNING("Cannot take interface %d up (%d)\n", idx, ret); - return -ENOEXEC; - } else { - PR("Interface %d is up\n", idx); - } - - return 0; -} - -static int cmd_net_iface_down(const struct shell *sh, size_t argc, - char *argv[]) -{ - struct net_if *iface; - int idx, ret; - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - ret = net_if_down(iface); - if (ret) { - PR_WARNING("Cannot take interface %d down (%d)\n", idx, ret); - return -ENOEXEC; - } else { - PR("Interface %d is down\n", idx); - } - - return 0; -} - #if defined(CONFIG_NET_NATIVE_IPV6) static void address_lifetime_cb(struct net_if *iface, void *user_data) @@ -1956,96 +1393,7 @@ static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) return 0; } -static int cmd_net_iface(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface = NULL; - struct net_shell_user_data user_data; - int idx; - - if (argv[1]) { - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - } - -#if defined(CONFIG_NET_HOSTNAME_ENABLE) - PR("Hostname: %s\n\n", net_hostname_get()); -#endif - - user_data.sh = sh; - user_data.user_data = iface; - - net_if_foreach(iface_cb, &user_data); - - return 0; -} - -static int cmd_net_set_mac(const struct shell *sh, size_t argc, char *argv[]) -{ -#if !defined(CONFIG_NET_L2_ETHERNET) || !defined(CONFIG_NET_L2_ETHERNET_MGMT) - PR_WARNING("Unsupported command, please enable CONFIG_NET_L2_ETHERNET " - "and CONFIG_NET_L2_ETHERNET_MGMT\n"); - return -ENOEXEC; -#else - struct net_if *iface; - struct ethernet_req_params params; - char *mac_addr = params.mac_address.addr; - int idx; - int ret; - - if (argc < 3) { - PR_WARNING("Missing interface index and/or MAC address\n"); - goto err; - } - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - goto err; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - goto err; - } - - if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { - PR_WARNING("MAC address can be set only for Ethernet\n"); - goto err; - } - - if ((net_bytes_from_str(mac_addr, sizeof(params.mac_address), argv[2]) < 0) || - !net_eth_is_addr_valid(¶ms.mac_address)) { - PR_WARNING("Invalid MAC address: %s\n", argv[2]); - goto err; - } - - ret = net_mgmt(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, iface, ¶ms, sizeof(params)); - if (ret < 0) { - if (ret == -EACCES) { - PR_WARNING("MAC address cannot be set when interface is operational\n"); - goto err; - } - PR_WARNING("Failed to set MAC address (%d)\n", ret); - goto err; - } - - PR_INFO("MAC address set to %s\n", - net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, - net_if_get_link_addr(iface)->len)); - - return 0; -err: - return -ENOEXEC; -#endif /* CONFIG_NET_L2_ETHERNET */ -} struct ctx_info { int pos; @@ -4320,61 +3668,10 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, return 0; } -#if !defined(NET_VLAN_MAX_COUNT) -#define MAX_IFACE_COUNT NET_IF_MAX_CONFIGS -#else -#define MAX_IFACE_COUNT NET_VLAN_MAX_COUNT -#endif - #if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") -#define MAX_IFACE_STR_LEN sizeof("xxx") - -static char iface_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; -static char iface_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; - -static char *set_iface_index_buffer(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); - - return iface_index_buffer[idx]; -} - -static char *set_iface_index_help(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, - "%s (%p)", iface2str(iface, NULL), iface); - - return iface_help_buffer[idx]; -} - -static void iface_index_get(size_t idx, struct shell_static_entry *entry); - SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); -static void iface_index_get(size_t idx, struct shell_static_entry *entry) -{ - entry->handler = NULL; - entry->help = set_iface_index_help(idx); - entry->subcmd = &iface_index; - entry->syntax = set_iface_index_buffer(idx); -} - -#define IFACE_DYN_CMD &iface_index - #if defined(CONFIG_NET_PPP) static char *set_iface_ppp_index_buffer(size_t idx) { @@ -4429,28 +3726,9 @@ static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry) #endif /* CONFIG_NET_PPP */ #else -#define IFACE_DYN_CMD NULL #define IFACE_PPP_DYN_CMD NULL #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface, - SHELL_CMD(up, IFACE_DYN_CMD, - "'net iface up ' takes network interface up.", - cmd_net_iface_up), - SHELL_CMD(down, IFACE_DYN_CMD, - "'net iface down ' takes network interface " - "down.", - cmd_net_iface_down), - SHELL_CMD(show, IFACE_DYN_CMD, - "'net iface ' shows network interface " - "information.", - cmd_net_iface), - SHELL_CMD(set_mac, IFACE_DYN_CMD, - "'net iface set_mac ' sets MAC address for the network interface.", - cmd_net_set_mac), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, SHELL_CMD(add, NULL, "'net ipv4 add

' adds the address to the interface.", @@ -4641,9 +3919,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(iface, &net_cmd_iface, - "Print information about network interfaces.", - cmd_net_iface), SHELL_CMD(ipv6, &net_cmd_ip6, "Print information about IPv6 specific information and " "configuration.", From 36db200c15cec21e69ad34184e7b7c6e73d25806 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 12:03:47 +0300 Subject: [PATCH 2367/4498] net: shell: Add ipv6 command Move "ipv6" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/common.h | 10 + subsys/net/lib/shell/ipv6.c | 278 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 276 --------------------------- 4 files changed, 289 insertions(+), 276 deletions(-) create mode 100644 subsys/net/lib/shell/ipv6.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index c6b62271825..820569016a2 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources(dns.c) zephyr_library_sources(events.c) zephyr_library_sources(gptp.c) zephyr_library_sources(iface.c) +zephyr_library_sources(ipv6.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h index 4953d7cfec0..3d0f1b58396 100644 --- a/subsys/net/lib/shell/common.h +++ b/subsys/net/lib/shell/common.h @@ -24,6 +24,7 @@ shell_fprintf(sh, SHELL_WARNING, fmt, ##__VA_ARGS__) #include "net_private.h" +#include "../ip/ipv6.h" struct net_shell_user_data { const struct shell *sh; @@ -36,6 +37,14 @@ struct net_shell_user_data { #define MAX_IFACE_COUNT NET_VLAN_MAX_COUNT #endif +#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) +#define ADDR_LEN NET_IPV6_ADDR_LEN +#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) +#define ADDR_LEN NET_IPV4_ADDR_LEN +#else +#define ADDR_LEN NET_IPV6_ADDR_LEN +#endif + #define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") #define MAX_IFACE_STR_LEN sizeof("xxx") @@ -55,3 +64,4 @@ void get_addresses(struct net_context *context, void events_enable(void); int get_iface_idx(const struct shell *sh, char *index_str); const char *iface2str(struct net_if *iface, const char **extra); +void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data); diff --git a/subsys/net/lib/shell/ipv6.c b/subsys/net/lib/shell/ipv6.c new file mode 100644 index 00000000000..f4b3214861a --- /dev/null +++ b/subsys/net/lib/shell/ipv6.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +#if defined(CONFIG_NET_IPV6_FRAGMENT) +void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char src[ADDR_LEN]; + int i; + + if (!*count) { + PR("\nIPv6 reassembly Id Remain " + "Src \tDst\n"); + } + + snprintk(src, ADDR_LEN, "%s", net_sprint_ipv6_addr(&reass->src)); + + PR("%p 0x%08x %5d %16s\t%16s\n", reass, reass->id, + k_ticks_to_ms_ceil32(k_work_delayable_remaining_get(&reass->timer)), + src, net_sprint_ipv6_addr(&reass->dst)); + + for (i = 0; i < CONFIG_NET_IPV6_FRAGMENT_MAX_PKT; i++) { + if (reass->pkt[i]) { + struct net_buf *frag = reass->pkt[i]->frags; + + PR("[%d] pkt %p->", i, reass->pkt[i]); + + while (frag) { + PR("%p", frag); + + frag = frag->frags; + if (frag) { + PR("->"); + } + } + + PR("\n"); + } + } + + (*count)++; +} +#endif /* CONFIG_NET_IPV6_FRAGMENT */ + +#if defined(CONFIG_NET_NATIVE_IPV6) + +static void address_lifetime_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; + const char *extra; + int i; + + ARG_UNUSED(user_data); + + PR("\nIPv6 addresses for interface %d (%p) (%s)\n", + net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); + PR("============================================%s\n", extra); + + if (!ipv6) { + PR("No IPv6 config found for this interface.\n"); + return; + } + + PR("Type \tState \tLifetime (sec)\tAddress\n"); + + for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { + struct net_if_ipv6_prefix *prefix; + char remaining_str[sizeof("01234567890")]; + uint64_t remaining; + uint8_t prefix_len; + + if (!ipv6->unicast[i].is_used || + ipv6->unicast[i].address.family != AF_INET6) { + continue; + } + + remaining = net_timeout_remaining(&ipv6->unicast[i].lifetime, + k_uptime_get_32()); + + prefix = net_if_ipv6_prefix_get(iface, + &ipv6->unicast[i].address.in6_addr); + if (prefix) { + prefix_len = prefix->len; + } else { + prefix_len = 128U; + } + + if (ipv6->unicast[i].is_infinite) { + snprintk(remaining_str, sizeof(remaining_str) - 1, + "infinite"); + } else { + snprintk(remaining_str, sizeof(remaining_str) - 1, + "%u", (uint32_t)(remaining / 1000U)); + } + + PR("%s \t%s\t%s \t%s/%d\n", + addrtype2str(ipv6->unicast[i].addr_type), + addrstate2str(ipv6->unicast[i].addr_state), + remaining_str, + net_sprint_ipv6_addr( + &ipv6->unicast[i].address.in6_addr), + prefix_len); + } +} +#endif /* CONFIG_NET_NATIVE_IPV6 */ + +static int cmd_net_ipv6(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV6) + struct net_shell_user_data user_data; +#endif + + PR("IPv6 support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6) ? + "enabled" : "disabled"); + if (!IS_ENABLED(CONFIG_NET_IPV6)) { + return -ENOEXEC; + } + +#if defined(CONFIG_NET_NATIVE_IPV6) + PR("IPv6 fragmentation support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT) ? "enabled" : + "disabled"); + PR("Multicast Listener Discovery support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_MLD) ? "enabled" : + "disabled"); + PR("Neighbor cache support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_NBR_CACHE) ? "enabled" : + "disabled"); + PR("Neighbor discovery support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_ND) ? "enabled" : + "disabled"); + PR("Duplicate address detection (DAD) support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_DAD) ? "enabled" : + "disabled"); + PR("Router advertisement RDNSS option support : %s\n", + IS_ENABLED(CONFIG_NET_IPV6_RA_RDNSS) ? "enabled" : + "disabled"); + PR("6lo header compression support : %s\n", + IS_ENABLED(CONFIG_NET_6LO) ? "enabled" : + "disabled"); + + if (IS_ENABLED(CONFIG_NET_6LO_CONTEXT)) { + PR("6lo context based compression " + "support : %s\n", + IS_ENABLED(CONFIG_NET_6LO_CONTEXT) ? "enabled" : + "disabled"); + } + + PR("Max number of IPv6 network interfaces " + "in the system : %d\n", + CONFIG_NET_IF_MAX_IPV6_COUNT); + PR("Max number of unicast IPv6 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT); + PR("Max number of multicast IPv6 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT); + PR("Max number of IPv6 prefixes per network " + "interface : %d\n", + CONFIG_NET_IF_IPV6_PREFIX_COUNT); + + user_data.sh = sh; + user_data.user_data = NULL; + + /* Print information about address lifetime */ + net_if_foreach(address_lifetime_cb, &user_data); +#endif + + return 0; +} + +static int cmd_net_ip6_add(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV6) + struct net_if *iface = NULL; + int idx; + struct in6_addr addr; + + if (argc != 3) { + PR_ERROR("Correct usage: net ipv6 add
\n"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOENT; + } + + if (net_addr_pton(AF_INET6, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + if (!net_if_ipv6_addr_add(iface, &addr, NET_ADDR_MANUAL, 0)) { + PR_ERROR("Failed to add %s address to interface %p\n", argv[2], iface); + } + +#else /* CONFIG_NET_NATIVE_IPV6 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); +#endif /* CONFIG_NET_NATIVE_IPV6 */ + return 0; +} + +static int cmd_net_ip6_del(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV6) + struct net_if *iface = NULL; + int idx; + struct in6_addr addr; + + if (argc != 3) { + PR_ERROR("Correct usage: net ipv6 del
\n"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET6, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + if (!net_if_ipv6_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -1; + } + +#else /* CONFIG_NET_NATIVE_IPV6 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); +#endif /* CONFIG_NET_NATIVE_IPV6 */ + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip6, + SHELL_CMD(add, NULL, + "'net ipv6 add
' adds the address to the interface.", + cmd_net_ip6_add), + SHELL_CMD(del, NULL, + "'net ipv6 del
' deletes the address from the interface.", + cmd_net_ip6_del), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), ipv6, &net_cmd_ip6, + "Print information about IPv6 specific information and " + "configuration.", + cmd_net_ipv6, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 4f60deaa231..a8cf1b37324 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -39,8 +39,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "icmpv4.h" #include "connection.h" -#include "ipv6.h" - #if defined(CONFIG_NET_L2_ETHERNET_MGMT) #include #endif @@ -891,259 +889,6 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data) } #endif /* CONFIG_NET_STATISTICS */ -#if defined(CONFIG_NET_IPV6_FRAGMENT) -static void ipv6_frag_cb(struct net_ipv6_reassembly *reass, - void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - char src[ADDR_LEN]; - int i; - - if (!*count) { - PR("\nIPv6 reassembly Id Remain " - "Src \tDst\n"); - } - - snprintk(src, ADDR_LEN, "%s", net_sprint_ipv6_addr(&reass->src)); - - PR("%p 0x%08x %5d %16s\t%16s\n", reass, reass->id, - k_ticks_to_ms_ceil32(k_work_delayable_remaining_get(&reass->timer)), - src, net_sprint_ipv6_addr(&reass->dst)); - - for (i = 0; i < CONFIG_NET_IPV6_FRAGMENT_MAX_PKT; i++) { - if (reass->pkt[i]) { - struct net_buf *frag = reass->pkt[i]->frags; - - PR("[%d] pkt %p->", i, reass->pkt[i]); - - while (frag) { - PR("%p", frag); - - frag = frag->frags; - if (frag) { - PR("->"); - } - } - - PR("\n"); - } - } - - (*count)++; -} -#endif /* CONFIG_NET_IPV6_FRAGMENT */ - -#if defined(CONFIG_NET_NATIVE_IPV6) - -static void address_lifetime_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; - const char *extra; - int i; - - ARG_UNUSED(user_data); - - PR("\nIPv6 addresses for interface %d (%p) (%s)\n", - net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); - PR("============================================%s\n", extra); - - if (!ipv6) { - PR("No IPv6 config found for this interface.\n"); - return; - } - - PR("Type \tState \tLifetime (sec)\tAddress\n"); - - for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - struct net_if_ipv6_prefix *prefix; - char remaining_str[sizeof("01234567890")]; - uint64_t remaining; - uint8_t prefix_len; - - if (!ipv6->unicast[i].is_used || - ipv6->unicast[i].address.family != AF_INET6) { - continue; - } - - remaining = net_timeout_remaining(&ipv6->unicast[i].lifetime, - k_uptime_get_32()); - - prefix = net_if_ipv6_prefix_get(iface, - &ipv6->unicast[i].address.in6_addr); - if (prefix) { - prefix_len = prefix->len; - } else { - prefix_len = 128U; - } - - if (ipv6->unicast[i].is_infinite) { - snprintk(remaining_str, sizeof(remaining_str) - 1, - "infinite"); - } else { - snprintk(remaining_str, sizeof(remaining_str) - 1, - "%u", (uint32_t)(remaining / 1000U)); - } - - PR("%s \t%s\t%s \t%s/%d\n", - addrtype2str(ipv6->unicast[i].addr_type), - addrstate2str(ipv6->unicast[i].addr_state), - remaining_str, - net_sprint_ipv6_addr( - &ipv6->unicast[i].address.in6_addr), - prefix_len); - } -} -#endif /* CONFIG_NET_NATIVE_IPV6 */ - -static int cmd_net_ipv6(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV6) - struct net_shell_user_data user_data; -#endif - - PR("IPv6 support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6) ? - "enabled" : "disabled"); - if (!IS_ENABLED(CONFIG_NET_IPV6)) { - return -ENOEXEC; - } - -#if defined(CONFIG_NET_NATIVE_IPV6) - PR("IPv6 fragmentation support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT) ? "enabled" : - "disabled"); - PR("Multicast Listener Discovery support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_MLD) ? "enabled" : - "disabled"); - PR("Neighbor cache support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_NBR_CACHE) ? "enabled" : - "disabled"); - PR("Neighbor discovery support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_ND) ? "enabled" : - "disabled"); - PR("Duplicate address detection (DAD) support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_DAD) ? "enabled" : - "disabled"); - PR("Router advertisement RDNSS option support : %s\n", - IS_ENABLED(CONFIG_NET_IPV6_RA_RDNSS) ? "enabled" : - "disabled"); - PR("6lo header compression support : %s\n", - IS_ENABLED(CONFIG_NET_6LO) ? "enabled" : - "disabled"); - - if (IS_ENABLED(CONFIG_NET_6LO_CONTEXT)) { - PR("6lo context based compression " - "support : %s\n", - IS_ENABLED(CONFIG_NET_6LO_CONTEXT) ? "enabled" : - "disabled"); - } - - PR("Max number of IPv6 network interfaces " - "in the system : %d\n", - CONFIG_NET_IF_MAX_IPV6_COUNT); - PR("Max number of unicast IPv6 addresses " - "per network interface : %d\n", - CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT); - PR("Max number of multicast IPv6 addresses " - "per network interface : %d\n", - CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT); - PR("Max number of IPv6 prefixes per network " - "interface : %d\n", - CONFIG_NET_IF_IPV6_PREFIX_COUNT); - - user_data.sh = sh; - user_data.user_data = NULL; - - /* Print information about address lifetime */ - net_if_foreach(address_lifetime_cb, &user_data); -#endif - - return 0; -} - -static int cmd_net_ip6_add(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV6) - struct net_if *iface = NULL; - int idx; - struct in6_addr addr; - - if (argc != 3) { - PR_ERROR("Correct usage: net ipv6 add
\n"); - return -EINVAL; - } - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOENT; - } - - if (net_addr_pton(AF_INET6, argv[2], &addr)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - if (!net_if_ipv6_addr_add(iface, &addr, NET_ADDR_MANUAL, 0)) { - PR_ERROR("Failed to add %s address to interface %p\n", argv[2], iface); - } - -#else /* CONFIG_NET_NATIVE_IPV6 */ - PR_INFO("Set %s and %s to enable native %s support.\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); -#endif /* CONFIG_NET_NATIVE_IPV6 */ - return 0; -} - -static int cmd_net_ip6_del(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV6) - struct net_if *iface = NULL; - int idx; - struct in6_addr addr; - - if (argc != 3) { - PR_ERROR("Correct usage: net ipv6 del
\n"); - return -EINVAL; - } - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_addr_pton(AF_INET6, argv[2], &addr)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - if (!net_if_ipv6_addr_rm(iface, &addr)) { - PR_ERROR("Failed to delete %s\n", argv[2]); - return -1; - } - -#else /* CONFIG_NET_NATIVE_IPV6 */ - PR_INFO("Set %s and %s to enable native %s support.\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); -#endif /* CONFIG_NET_NATIVE_IPV6 */ - return 0; -} - static int cmd_net_ip6_route_add(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_NATIVE_IPV6) && (CONFIG_NET_ROUTE) @@ -3606,13 +3351,6 @@ static int cmd_net_resume(const struct shell *sh, size_t argc, static void websocket_context_cb(struct websocket_context *context, void *user_data) { -#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4) -#define ADDR_LEN NET_IPV6_ADDR_LEN -#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) -#define ADDR_LEN NET_IPV4_ADDR_LEN -#else -#define ADDR_LEN NET_IPV6_ADDR_LEN -#endif struct net_shell_user_data *data = user_data; const struct shell *sh = data->sh; struct net_context *net_ctx; @@ -3739,16 +3477,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip6, - SHELL_CMD(add, NULL, - "'net ipv6 add
' adds the address to the interface.", - cmd_net_ip6_add), - SHELL_CMD(del, NULL, - "'net ipv6 del
' deletes the address from the interface.", - cmd_net_ip6_del), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, SHELL_CMD(add, NULL, "'net route add '" @@ -3919,10 +3647,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(ipv6, &net_cmd_ip6, - "Print information about IPv6 specific information and " - "configuration.", - cmd_net_ipv6), SHELL_CMD(ipv4, &net_cmd_ip, "Print information about IPv4 specific information and " "configuration.", From e0c30bc2b63e3bd73e4d497a31c5718d5cb1c737 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:12:54 +0300 Subject: [PATCH 2368/4498] net: shell: Add ipv4 command Move "ipv4" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/ipv4.c | 184 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 170 ------------------------- 3 files changed, 185 insertions(+), 170 deletions(-) create mode 100644 subsys/net/lib/shell/ipv4.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 820569016a2..fdc4f3b14b5 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources(dns.c) zephyr_library_sources(events.c) zephyr_library_sources(gptp.c) zephyr_library_sources(iface.c) +zephyr_library_sources(ipv4.c) zephyr_library_sources(ipv6.c) zephyr_library_include_directories( diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c new file mode 100644 index 00000000000..81526dc7807 --- /dev/null +++ b/subsys/net/lib/shell/ipv4.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" +#include "../ip/ipv4.h" + +#if defined(CONFIG_NET_NATIVE_IPV4) +static void ip_address_lifetime_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; + const char *extra; + int i; + + ARG_UNUSED(user_data); + + PR("\nIPv4 addresses for interface %d (%p) (%s)\n", + net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); + PR("============================================%s\n", extra); + + if (!ipv4) { + PR("No IPv4 config found for this interface.\n"); + return; + } + + PR("Type \tState \tLifetime (sec)\tAddress\n"); + + for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].is_used || + ipv4->unicast[i].address.family != AF_INET) { + continue; + } + + PR("%s \t%s \t%12s/%12s\n", + addrtype2str(ipv4->unicast[i].addr_type), + addrstate2str(ipv4->unicast[i].addr_state), + net_sprint_ipv4_addr( + &ipv4->unicast[i].address.in_addr), + net_sprint_ipv4_addr( + &ipv4->netmask)); + } +} +#endif /* CONFIG_NET_NATIVE_IPV4 */ + +static int cmd_net_ipv4(const struct shell *sh, size_t argc, char *argv[]) +{ + PR("IPv4 support : %s\n", + IS_ENABLED(CONFIG_NET_IPV4) ? + "enabled" : "disabled"); + if (!IS_ENABLED(CONFIG_NET_IPV4)) { + return -ENOEXEC; + } + +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_shell_user_data user_data; + + PR("IPv4 fragmentation support : %s\n", + IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) ? "enabled" : + "disabled"); + PR("Max number of IPv4 network interfaces " + "in the system : %d\n", + CONFIG_NET_IF_MAX_IPV4_COUNT); + PR("Max number of unicast IPv4 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT); + PR("Max number of multicast IPv4 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT); + + user_data.sh = sh; + user_data.user_data = NULL; + + /* Print information about address lifetime */ + net_if_foreach(ip_address_lifetime_cb, &user_data); +#endif + + return 0; +} + +static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_if *iface = NULL; + int idx; + struct in_addr addr; + + if (argc != 4) { + PR_ERROR("Correct usage: net ipv4 add
\n"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + + if (net_addr_pton(AF_INET, argv[3], &addr)) { + PR_ERROR("Invalid netmask: %s", argv[3]); + return -EINVAL; + } + + net_if_ipv4_set_netmask(iface, &addr); + +#else /* CONFIG_NET_NATIVE_IPV4 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); +#endif /* CONFIG_NET_NATIVE_IPV4 */ + return 0; +} + +static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_if *iface = NULL; + int idx; + struct in_addr addr; + + if (argc != 3) { + PR_ERROR("Correct usage: net ipv4 del
"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + if (!net_if_ipv4_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -ENOEXEC; + } +#else /* CONFIG_NET_NATIVE_IPV4 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); +#endif /* CONFIG_NET_NATIVE_IPV4 */ + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, + SHELL_CMD(add, NULL, + "'net ipv4 add
' adds the address to the interface.", + cmd_net_ip_add), + SHELL_CMD(del, NULL, + "'net ipv4 del
' deletes the address from the interface.", + cmd_net_ip_del), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), ipv4, &net_cmd_ip, + "Print information about IPv4 specific information and " + "configuration.", + cmd_net_ipv4, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index a8cf1b37324..3996314be87 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -981,162 +981,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv return 0; } -#if defined(CONFIG_NET_NATIVE_IPV4) -static void ip_address_lifetime_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; - const char *extra; - int i; - - ARG_UNUSED(user_data); - - PR("\nIPv4 addresses for interface %d (%p) (%s)\n", - net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); - PR("============================================%s\n", extra); - - if (!ipv4) { - PR("No IPv4 config found for this interface.\n"); - return; - } - - PR("Type \tState \tLifetime (sec)\tAddress\n"); - - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used || - ipv4->unicast[i].address.family != AF_INET) { - continue; - } - - PR("%s \t%s \t%12s/%12s\n", - addrtype2str(ipv4->unicast[i].addr_type), - addrstate2str(ipv4->unicast[i].addr_state), - net_sprint_ipv4_addr( - &ipv4->unicast[i].address.in_addr), - net_sprint_ipv4_addr( - &ipv4->netmask)); - } -} -#endif /* CONFIG_NET_NATIVE_IPV4 */ - -static int cmd_net_ipv4(const struct shell *sh, size_t argc, char *argv[]) -{ - PR("IPv4 support : %s\n", - IS_ENABLED(CONFIG_NET_IPV4) ? - "enabled" : "disabled"); - if (!IS_ENABLED(CONFIG_NET_IPV4)) { - return -ENOEXEC; - } - -#if defined(CONFIG_NET_NATIVE_IPV4) - struct net_shell_user_data user_data; - - PR("IPv4 fragmentation support : %s\n", - IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) ? "enabled" : - "disabled"); - PR("Max number of IPv4 network interfaces " - "in the system : %d\n", - CONFIG_NET_IF_MAX_IPV4_COUNT); - PR("Max number of unicast IPv4 addresses " - "per network interface : %d\n", - CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT); - PR("Max number of multicast IPv4 addresses " - "per network interface : %d\n", - CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT); - - user_data.sh = sh; - user_data.user_data = NULL; - - /* Print information about address lifetime */ - net_if_foreach(ip_address_lifetime_cb, &user_data); -#endif - - return 0; -} - -static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV4) - struct net_if *iface = NULL; - int idx; - struct in_addr addr; - - if (argc != 4) { - PR_ERROR("Correct usage: net ipv4 add
\n"); - return -EINVAL; - } - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_addr_pton(AF_INET, argv[2], &addr)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); - - if (net_addr_pton(AF_INET, argv[3], &addr)) { - PR_ERROR("Invalid netmask: %s", argv[3]); - return -EINVAL; - } - - net_if_ipv4_set_netmask(iface, &addr); - -#else /* CONFIG_NET_NATIVE_IPV4 */ - PR_INFO("Set %s and %s to enable native %s support.\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); -#endif /* CONFIG_NET_NATIVE_IPV4 */ - return 0; -} - -static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV4) - struct net_if *iface = NULL; - int idx; - struct in_addr addr; - - if (argc != 3) { - PR_ERROR("Correct usage: net ipv4 del
"); - return -EINVAL; - } - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_addr_pton(AF_INET, argv[2], &addr)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - if (!net_if_ipv4_addr_rm(iface, &addr)) { - PR_ERROR("Failed to delete %s\n", argv[2]); - return -ENOEXEC; - } -#else /* CONFIG_NET_NATIVE_IPV4 */ - PR_INFO("Set %s and %s to enable native %s support.\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); -#endif /* CONFIG_NET_NATIVE_IPV4 */ - return 0; -} @@ -3467,16 +3311,6 @@ static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry) #define IFACE_PPP_DYN_CMD NULL #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, - SHELL_CMD(add, NULL, - "'net ipv4 add
' adds the address to the interface.", - cmd_net_ip_add), - SHELL_CMD(del, NULL, - "'net ipv4 del
' deletes the address from the interface.", - cmd_net_ip_del), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, SHELL_CMD(add, NULL, "'net route add '" @@ -3647,10 +3481,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(ipv4, &net_cmd_ip, - "Print information about IPv4 specific information and " - "configuration.", - cmd_net_ipv4), SHELL_CMD(mem, NULL, "Print information about network memory usage.", cmd_net_mem), SHELL_CMD(nbr, &net_cmd_nbr, "Print neighbor information.", From 5b6423dd2f47d5962603c263be5515101670d932 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:20:11 +0300 Subject: [PATCH 2369/4498] net: shell: Add mem command Move "mem" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/mem.c | 165 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 152 ------------------------- 3 files changed, 166 insertions(+), 152 deletions(-) create mode 100644 subsys/net/lib/shell/mem.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index fdc4f3b14b5..25e9626a436 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -16,6 +16,7 @@ zephyr_library_sources(gptp.c) zephyr_library_sources(iface.c) zephyr_library_sources(ipv4.c) zephyr_library_sources(ipv6.c) +zephyr_library_sources(mem.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/mem.c b/subsys/net/lib/shell/mem.c new file mode 100644 index 00000000000..cf58cda6bd6 --- /dev/null +++ b/subsys/net/lib/shell/mem.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +struct ctx_info { + int pos; + bool are_external_pools; + struct k_mem_slab *tx_slabs[CONFIG_NET_MAX_CONTEXTS]; + struct net_buf_pool *data_pools[CONFIG_NET_MAX_CONTEXTS]; +}; + +#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) +#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) +static bool slab_pool_found_already(struct ctx_info *info, + struct k_mem_slab *slab, + struct net_buf_pool *pool) +{ + int i; + + for (i = 0; i < CONFIG_NET_MAX_CONTEXTS; i++) { + if (slab) { + if (info->tx_slabs[i] == slab) { + return true; + } + } else { + if (info->data_pools[i] == pool) { + return true; + } + } + } + + return false; +} +#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ + +static void context_info(struct net_context *context, void *user_data) +{ +#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct ctx_info *info = data->user_data; + struct k_mem_slab *slab; + struct net_buf_pool *pool; + + if (!net_context_is_used(context)) { + return; + } + + if (context->tx_slab) { + slab = context->tx_slab(); + + if (slab_pool_found_already(info, slab, NULL)) { + return; + } + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + PR("%p\t%u\t%u\tETX\n", + slab, slab->info.num_blocks, k_mem_slab_num_free_get(slab)); +#else + PR("%p\t%d\tETX\n", slab, slab->info.num_blocks); +#endif + info->are_external_pools = true; + info->tx_slabs[info->pos] = slab; + } + + if (context->data_pool) { + pool = context->data_pool(); + + if (slab_pool_found_already(info, NULL, pool)) { + return; + } + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + PR("%p\t%d\t%ld\tEDATA (%s)\n", pool, pool->buf_count, + atomic_get(&pool->avail_count), pool->name); +#else + PR("%p\t%d\tEDATA\n", pool, pool->buf_count); +#endif + info->are_external_pools = true; + info->data_pools[info->pos] = pool; + } + + info->pos++; +#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ +} +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ + +static int cmd_net_mem(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) + struct k_mem_slab *rx, *tx; + struct net_buf_pool *rx_data, *tx_data; + + net_pkt_get_info(&rx, &tx, &rx_data, &tx_data); + +#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE) + PR("Fragment length %d bytes\n", CONFIG_NET_BUF_DATA_SIZE); +#else + PR("Fragment data pool size %d bytes\n", CONFIG_NET_BUF_DATA_POOL_SIZE); +#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */ + + PR("Network buffer pools:\n"); + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + PR("Address\t\tTotal\tAvail\tName\n"); + + PR("%p\t%d\t%u\tRX\n", + rx, rx->info.num_blocks, k_mem_slab_num_free_get(rx)); + + PR("%p\t%d\t%u\tTX\n", + tx, tx->info.num_blocks, k_mem_slab_num_free_get(tx)); + + PR("%p\t%d\t%ld\tRX DATA (%s)\n", rx_data, rx_data->buf_count, + atomic_get(&rx_data->avail_count), rx_data->name); + + PR("%p\t%d\t%ld\tTX DATA (%s)\n", tx_data, tx_data->buf_count, + atomic_get(&tx_data->avail_count), tx_data->name); +#else + PR("Address\t\tTotal\tName\n"); + + PR("%p\t%d\tRX\n", rx, rx->info.num_blocks); + PR("%p\t%d\tTX\n", tx, tx->info.num_blocks); + PR("%p\t%d\tRX DATA\n", rx_data, rx_data->buf_count); + PR("%p\t%d\tTX DATA\n", tx_data, tx_data->buf_count); + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_BUF_POOL_USAGE", "net_buf allocation"); +#endif /* CONFIG_NET_BUF_POOL_USAGE */ + + if (IS_ENABLED(CONFIG_NET_CONTEXT_NET_PKT_POOL)) { + struct net_shell_user_data user_data; + struct ctx_info info; + + (void)memset(&info, 0, sizeof(info)); + + user_data.sh = sh; + user_data.user_data = &info; + + net_context_foreach(context_info, &user_data); + + if (!info.are_external_pools) { + PR("No external memory pools found.\n"); + } + } +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_OFFLOAD or CONFIG_NET_NATIVE", "memory usage"); +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ + + return 0; +} + +SHELL_SUBCMD_ADD((net), mem, NULL, + "Print information about network memory usage.", + cmd_net_mem, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 3996314be87..c1cc82e3ab6 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -984,156 +984,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv -struct ctx_info { - int pos; - bool are_external_pools; - struct k_mem_slab *tx_slabs[CONFIG_NET_MAX_CONTEXTS]; - struct net_buf_pool *data_pools[CONFIG_NET_MAX_CONTEXTS]; -}; - -#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) -#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) -static bool slab_pool_found_already(struct ctx_info *info, - struct k_mem_slab *slab, - struct net_buf_pool *pool) -{ - int i; - - for (i = 0; i < CONFIG_NET_MAX_CONTEXTS; i++) { - if (slab) { - if (info->tx_slabs[i] == slab) { - return true; - } - } else { - if (info->data_pools[i] == pool) { - return true; - } - } - } - - return false; -} -#endif - -static void context_info(struct net_context *context, void *user_data) -{ -#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct ctx_info *info = data->user_data; - struct k_mem_slab *slab; - struct net_buf_pool *pool; - - if (!net_context_is_used(context)) { - return; - } - - if (context->tx_slab) { - slab = context->tx_slab(); - - if (slab_pool_found_already(info, slab, NULL)) { - return; - } - -#if defined(CONFIG_NET_BUF_POOL_USAGE) - PR("%p\t%u\t%u\tETX\n", - slab, slab->info.num_blocks, k_mem_slab_num_free_get(slab)); -#else - PR("%p\t%d\tETX\n", slab, slab->info.num_blocks); -#endif - info->are_external_pools = true; - info->tx_slabs[info->pos] = slab; - } - - if (context->data_pool) { - pool = context->data_pool(); - - if (slab_pool_found_already(info, NULL, pool)) { - return; - } - -#if defined(CONFIG_NET_BUF_POOL_USAGE) - PR("%p\t%d\t%ld\tEDATA (%s)\n", pool, pool->buf_count, - atomic_get(&pool->avail_count), pool->name); -#else - PR("%p\t%d\tEDATA\n", pool, pool->buf_count); -#endif - info->are_external_pools = true; - info->data_pools[info->pos] = pool; - } - - info->pos++; -#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ -} -#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ - -static int cmd_net_mem(const struct shell *sh, size_t argc, char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE) - struct k_mem_slab *rx, *tx; - struct net_buf_pool *rx_data, *tx_data; - - net_pkt_get_info(&rx, &tx, &rx_data, &tx_data); - -#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE) - PR("Fragment length %d bytes\n", CONFIG_NET_BUF_DATA_SIZE); -#else - PR("Fragment data pool size %d bytes\n", CONFIG_NET_BUF_DATA_POOL_SIZE); -#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */ - - PR("Network buffer pools:\n"); - -#if defined(CONFIG_NET_BUF_POOL_USAGE) - PR("Address\t\tTotal\tAvail\tName\n"); - - PR("%p\t%d\t%u\tRX\n", - rx, rx->info.num_blocks, k_mem_slab_num_free_get(rx)); - - PR("%p\t%d\t%u\tTX\n", - tx, tx->info.num_blocks, k_mem_slab_num_free_get(tx)); - - PR("%p\t%d\t%ld\tRX DATA (%s)\n", rx_data, rx_data->buf_count, - atomic_get(&rx_data->avail_count), rx_data->name); - - PR("%p\t%d\t%ld\tTX DATA (%s)\n", tx_data, tx_data->buf_count, - atomic_get(&tx_data->avail_count), tx_data->name); -#else - PR("Address\t\tTotal\tName\n"); - - PR("%p\t%d\tRX\n", rx, rx->info.num_blocks); - PR("%p\t%d\tTX\n", tx, tx->info.num_blocks); - PR("%p\t%d\tRX DATA\n", rx_data, rx_data->buf_count); - PR("%p\t%d\tTX DATA\n", tx_data, tx_data->buf_count); - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_BUF_POOL_USAGE", "net_buf allocation"); -#endif /* CONFIG_NET_BUF_POOL_USAGE */ - - if (IS_ENABLED(CONFIG_NET_CONTEXT_NET_PKT_POOL)) { - struct net_shell_user_data user_data; - struct ctx_info info; - - (void)memset(&info, 0, sizeof(info)); - - user_data.sh = sh; - user_data.user_data = &info; - - net_context_foreach(context_info, &user_data); - - if (!info.are_external_pools) { - PR("No external memory pools found.\n"); - } - } -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_OFFLOAD or CONFIG_NET_NATIVE", "memory usage"); -#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */ - - return 0; -} - static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, char *argv[]) { @@ -3481,8 +3331,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(mem, NULL, "Print information about network memory usage.", - cmd_net_mem), SHELL_CMD(nbr, &net_cmd_nbr, "Print neighbor information.", cmd_net_nbr), SHELL_CMD(ping, &net_cmd_ping, "Ping a network host.", cmd_net_ping), From 0c9fd96604fda9b8a130d3e814e165ea8e502518 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:31:00 +0300 Subject: [PATCH 2370/4498] net: shell: Add nbr command Move "nbr" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/nbr.c | 207 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 195 -------------------------- 3 files changed, 208 insertions(+), 195 deletions(-) create mode 100644 subsys/net/lib/shell/nbr.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 25e9626a436..cd3c2c9be47 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources(iface.c) zephyr_library_sources(ipv4.c) zephyr_library_sources(ipv6.c) zephyr_library_sources(mem.c) +zephyr_library_sources(nbr.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/nbr.c b/subsys/net/lib/shell/nbr.c new file mode 100644 index 00000000000..fd420b818ae --- /dev/null +++ b/subsys/net/lib/shell/nbr.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_IPV6) + struct in6_addr addr; + int ret; +#endif + +#if defined(CONFIG_NET_IPV6) + if (!argv[1]) { + PR_WARNING("Neighbor IPv6 address missing.\n"); + return -ENOEXEC; + } + + ret = net_addr_pton(AF_INET6, argv[1], &addr); + if (ret < 0) { + PR_WARNING("Cannot parse '%s'\n", argv[1]); + return -ENOEXEC; + } + + if (!net_ipv6_nbr_rm(NULL, &addr)) { + PR_WARNING("Cannot remove neighbor %s\n", + net_sprint_ipv6_addr(&addr)); + return -ENOEXEC; + } + + PR("Neighbor %s removed.\n", net_sprint_ipv6_addr(&addr)); +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("IPv6 not enabled.\n"); +#endif + + return 0; +} + +#if defined(CONFIG_NET_IPV6) +static void nbr_cb(struct net_nbr *nbr, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char *padding = ""; + char *state_pad = ""; + const char *state_str; +#if defined(CONFIG_NET_IPV6_ND) + int64_t remaining; +#endif + +#if defined(CONFIG_NET_L2_IEEE802154) + padding = " "; +#endif + + if (*count == 0) { + PR(" Neighbor Interface Flags State " + "Remain Link %sAddress\n", padding); + } + + (*count)++; + + state_str = net_ipv6_nbr_state2str(net_ipv6_nbr_data(nbr)->state); + + /* This is not a proper way but the minimal libc does not honor + * string lengths in %s modifier so in order the output to look + * nice, do it like this. + */ + if (strlen(state_str) == 5) { + state_pad = " "; + } + +#if defined(CONFIG_NET_IPV6_ND) + remaining = net_ipv6_nbr_data(nbr)->reachable + + net_ipv6_nbr_data(nbr)->reachable_timeout - + k_uptime_get(); +#endif + + PR("[%2d] %p %d %5d/%d/%d/%d %s%s %6d %17s%s %s\n", + *count, nbr, net_if_get_by_iface(nbr->iface), + net_ipv6_nbr_data(nbr)->link_metric, + nbr->ref, + net_ipv6_nbr_data(nbr)->ns_count, + net_ipv6_nbr_data(nbr)->is_router, + state_str, + state_pad, +#if defined(CONFIG_NET_IPV6_ND) + (int)(remaining > 0 ? remaining : 0), +#else + 0, +#endif + nbr->idx == NET_NBR_LLADDR_UNKNOWN ? "?" : + net_sprint_ll_addr( + net_nbr_get_lladdr(nbr->idx)->addr, + net_nbr_get_lladdr(nbr->idx)->len), + nbr->idx == NET_NBR_LLADDR_UNKNOWN ? "" : + (net_nbr_get_lladdr(nbr->idx)->len == 8U ? "" : padding), + net_sprint_ipv6_addr(&net_ipv6_nbr_data(nbr)->addr)); +} +#endif + +static int cmd_net_nbr(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_IPV6) + int count = 0; + struct net_shell_user_data user_data; +#endif + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_IPV6) + user_data.sh = sh; + user_data.user_data = &count; + + net_ipv6_nbr_foreach(nbr_cb, &user_data); + + if (count == 0) { + PR("No neighbors.\n"); + } +#else + PR_INFO("IPv6 not enabled.\n"); +#endif /* CONFIG_NET_IPV6 */ + + return 0; +} + +#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) +static char nbr_address_buffer[CONFIG_NET_IPV6_MAX_NEIGHBORS][NET_IPV6_ADDR_LEN]; + +static void nbr_address_cb(struct net_nbr *nbr, void *user_data) +{ + int *count = user_data; + + if (*count >= CONFIG_NET_IPV6_MAX_NEIGHBORS) { + return; + } + + snprintk(nbr_address_buffer[*count], NET_IPV6_ADDR_LEN, + "%s", net_sprint_ipv6_addr(&net_ipv6_nbr_data(nbr)->addr)); + + (*count)++; +} + +static void nbr_populate_addresses(void) +{ + int count = 0; + + net_ipv6_nbr_foreach(nbr_address_cb, &count); +} + +static char *set_nbr_address(size_t idx) +{ + if (idx == 0) { + memset(nbr_address_buffer, 0, sizeof(nbr_address_buffer)); + nbr_populate_addresses(); + } + + if (idx >= CONFIG_NET_IPV6_MAX_NEIGHBORS) { + return NULL; + } + + if (!nbr_address_buffer[idx][0]) { + return NULL; + } + + return nbr_address_buffer[idx]; +} + +static void nbr_address_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(nbr_address, nbr_address_get); + +#define NBR_ADDRESS_CMD &nbr_address + +static void nbr_address_get(size_t idx, struct shell_static_entry *entry) +{ + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = &nbr_address; + entry->syntax = set_nbr_address(idx); +} + +#else +#define NBR_ADDRESS_CMD NULL +#endif /* CONFIG_NET_IPV6 && CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_nbr, + SHELL_CMD(rm, NBR_ADDRESS_CMD, + "'net nbr rm
' removes neighbor from cache.", + cmd_net_nbr_rm), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), nbr, &net_cmd_nbr, + "Print neighbor information.", + cmd_net_nbr, 1, 0); diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index c1cc82e3ab6..df3e7e33c0d 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -984,131 +984,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv -static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_IPV6) - struct in6_addr addr; - int ret; -#endif - -#if defined(CONFIG_NET_IPV6) - if (!argv[1]) { - PR_WARNING("Neighbor IPv6 address missing.\n"); - return -ENOEXEC; - } - - ret = net_addr_pton(AF_INET6, argv[1], &addr); - if (ret < 0) { - PR_WARNING("Cannot parse '%s'\n", argv[1]); - return -ENOEXEC; - } - - if (!net_ipv6_nbr_rm(NULL, &addr)) { - PR_WARNING("Cannot remove neighbor %s\n", - net_sprint_ipv6_addr(&addr)); - return -ENOEXEC; - } else { - PR("Neighbor %s removed.\n", net_sprint_ipv6_addr(&addr)); - } -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("IPv6 not enabled.\n"); -#endif - - return 0; -} - -#if defined(CONFIG_NET_IPV6) -static void nbr_cb(struct net_nbr *nbr, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - char *padding = ""; - char *state_pad = ""; - const char *state_str; -#if defined(CONFIG_NET_IPV6_ND) - int64_t remaining; -#endif - -#if defined(CONFIG_NET_L2_IEEE802154) - padding = " "; -#endif - - if (*count == 0) { - PR(" Neighbor Interface Flags State " - "Remain Link %sAddress\n", padding); - } - - (*count)++; - - state_str = net_ipv6_nbr_state2str(net_ipv6_nbr_data(nbr)->state); - - /* This is not a proper way but the minimal libc does not honor - * string lengths in %s modifier so in order the output to look - * nice, do it like this. - */ - if (strlen(state_str) == 5) { - state_pad = " "; - } - -#if defined(CONFIG_NET_IPV6_ND) - remaining = net_ipv6_nbr_data(nbr)->reachable + - net_ipv6_nbr_data(nbr)->reachable_timeout - - k_uptime_get(); -#endif - - PR("[%2d] %p %d %5d/%d/%d/%d %s%s %6d %17s%s %s\n", - *count, nbr, net_if_get_by_iface(nbr->iface), - net_ipv6_nbr_data(nbr)->link_metric, - nbr->ref, - net_ipv6_nbr_data(nbr)->ns_count, - net_ipv6_nbr_data(nbr)->is_router, - state_str, - state_pad, -#if defined(CONFIG_NET_IPV6_ND) - (int)(remaining > 0 ? remaining : 0), -#else - 0, -#endif - nbr->idx == NET_NBR_LLADDR_UNKNOWN ? "?" : - net_sprint_ll_addr( - net_nbr_get_lladdr(nbr->idx)->addr, - net_nbr_get_lladdr(nbr->idx)->len), - nbr->idx == NET_NBR_LLADDR_UNKNOWN ? "" : - (net_nbr_get_lladdr(nbr->idx)->len == 8U ? "" : padding), - net_sprint_ipv6_addr(&net_ipv6_nbr_data(nbr)->addr)); -} -#endif - -static int cmd_net_nbr(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_IPV6) - int count = 0; - struct net_shell_user_data user_data; -#endif - - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_IPV6) - user_data.sh = sh; - user_data.user_data = &count; - - net_ipv6_nbr_foreach(nbr_cb, &user_data); - - if (count == 0) { - PR("No neighbors.\n"); - } -#else - PR_INFO("IPv6 not enabled.\n"); -#endif /* CONFIG_NET_IPV6 */ - - return 0; -} #if defined(CONFIG_NET_IP) @@ -3183,74 +3058,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp, SHELL_SUBCMD_SET_END ); -#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -static -char nbr_address_buffer[CONFIG_NET_IPV6_MAX_NEIGHBORS][NET_IPV6_ADDR_LEN]; - -static void nbr_address_cb(struct net_nbr *nbr, void *user_data) -{ - int *count = user_data; - - if (*count >= CONFIG_NET_IPV6_MAX_NEIGHBORS) { - return; - } - - snprintk(nbr_address_buffer[*count], NET_IPV6_ADDR_LEN, - "%s", net_sprint_ipv6_addr(&net_ipv6_nbr_data(nbr)->addr)); - - (*count)++; -} - -static void nbr_populate_addresses(void) -{ - int count = 0; - - net_ipv6_nbr_foreach(nbr_address_cb, &count); -} - -static char *set_nbr_address(size_t idx) -{ - if (idx == 0) { - memset(nbr_address_buffer, 0, sizeof(nbr_address_buffer)); - nbr_populate_addresses(); - } - - if (idx >= CONFIG_NET_IPV6_MAX_NEIGHBORS) { - return NULL; - } - - if (!nbr_address_buffer[idx][0]) { - return NULL; - } - - return nbr_address_buffer[idx]; -} - -static void nbr_address_get(size_t idx, struct shell_static_entry *entry); - -SHELL_DYNAMIC_CMD_CREATE(nbr_address, nbr_address_get); - -#define NBR_ADDRESS_CMD &nbr_address - -static void nbr_address_get(size_t idx, struct shell_static_entry *entry) -{ - entry->handler = NULL; - entry->help = NULL; - entry->subcmd = &nbr_address; - entry->syntax = set_nbr_address(idx); -} - -#else -#define NBR_ADDRESS_CMD NULL -#endif /* CONFIG_NET_IPV6 && CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ - -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_nbr, - SHELL_CMD(rm, NBR_ADDRESS_CMD, - "'net nbr rm
' removes neighbor from cache.", - cmd_net_nbr_rm), - SHELL_SUBCMD_SET_END -); - #if defined(CONFIG_NET_STATISTICS) && \ defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) @@ -3331,8 +3138,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(nbr, &net_cmd_nbr, "Print neighbor information.", - cmd_net_nbr), SHELL_CMD(ping, &net_cmd_ping, "Ping a network host.", cmd_net_ping), SHELL_CMD(pkt, &net_cmd_pkt, "net_pkt information.", cmd_net_pkt), SHELL_CMD(ppp, &net_cmd_ppp, "PPP information.", cmd_net_ppp_status), From a669d4aba36db09228b3de8275a457b1e60b2185 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:37:05 +0300 Subject: [PATCH 2371/4498] net: shell: Add ping command Move "ping" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 483 -------------------------- subsys/net/lib/shell/ping.c | 502 ++++++++++++++++++++++++++++ 3 files changed, 503 insertions(+), 483 deletions(-) create mode 100644 subsys/net/lib/shell/ping.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index cd3c2c9be47..b5a68f74145 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources(ipv4.c) zephyr_library_sources(ipv6.c) zephyr_library_sources(mem.c) zephyr_library_sources(nbr.c) +zephyr_library_sources(ping.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index df3e7e33c0d..0308fe1ac06 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -35,8 +35,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "common.h" #include "route.h" -#include "icmpv6.h" -#include "icmpv4.h" #include "connection.h" #if defined(CONFIG_NET_L2_ETHERNET_MGMT) @@ -981,477 +979,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv return 0; } - - - - -#if defined(CONFIG_NET_IP) - -static struct ping_context { - struct k_work_delayable work; - struct net_icmp_ctx icmp; - union { - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - struct sockaddr addr; - }; - struct net_if *iface; - const struct shell *sh; - - /* Ping parameters */ - uint32_t count; - uint32_t interval; - uint32_t sequence; - uint16_t payload_size; - uint8_t tos; - int priority; -} ping_ctx; - -static void ping_done(struct ping_context *ctx); - -#if defined(CONFIG_NET_NATIVE_IPV6) - -static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, - struct net_pkt *pkt, - struct net_icmp_ip_hdr *hdr, - struct net_icmp_hdr *icmp_hdr, - void *user_data) -{ - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, - struct net_icmpv6_echo_req); - struct net_ipv6_hdr *ip_hdr = hdr->ipv6; - struct net_icmpv6_echo_req *icmp_echo; - uint32_t cycles; - char time_buf[16] = { 0 }; - - icmp_echo = (struct net_icmpv6_echo_req *)net_pkt_get_data(pkt, - &icmp_access); - if (icmp_echo == NULL) { - return -EIO; - } - - net_pkt_skip(pkt, sizeof(*icmp_echo)); - - if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { - if (net_pkt_read_be32(pkt, &cycles)) { - return -EIO; - } - - cycles = k_cycle_get_32() - cycles; - - snprintf(time_buf, sizeof(time_buf), -#ifdef CONFIG_FPU - "time=%.2f ms", - (double)((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000.f) -#else - "time=%d ms", - ((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000) -#endif - ); - } - - PR_SHELL(ping_ctx.sh, "%d bytes from %s to %s: icmp_seq=%d ttl=%d " -#ifdef CONFIG_IEEE802154 - "rssi=%d " -#endif - "%s\n", - ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - - NET_ICMPH_LEN, - net_sprint_ipv6_addr(&ip_hdr->src), - net_sprint_ipv6_addr(&ip_hdr->dst), - ntohs(icmp_echo->sequence), - ip_hdr->hop_limit, -#ifdef CONFIG_IEEE802154 - net_pkt_ieee802154_rssi_dbm(pkt), -#endif - time_buf); - - if (ntohs(icmp_echo->sequence) == ping_ctx.count) { - ping_done(&ping_ctx); - } - - return 0; -} -#else -static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, - struct net_pkt *pkt, - struct net_icmp_ip_hdr *hdr, - struct net_icmp_hdr *icmp_hdr, - void *user_data) -{ - ARG_UNUSED(ctx); - ARG_UNUSED(pkt); - ARG_UNUSED(hdr); - ARG_UNUSED(icmp_hdr); - ARG_UNUSED(user_data); - - return -ENOTSUP; -} -#endif /* CONFIG_NET_IPV6 */ - -#if defined(CONFIG_NET_NATIVE_IPV4) - -static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, - struct net_pkt *pkt, - struct net_icmp_ip_hdr *hdr, - struct net_icmp_hdr *icmp_hdr, - void *user_data) -{ - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, - struct net_icmpv4_echo_req); - struct net_ipv4_hdr *ip_hdr = hdr->ipv4; - uint32_t cycles; - struct net_icmpv4_echo_req *icmp_echo; - char time_buf[16] = { 0 }; - - icmp_echo = (struct net_icmpv4_echo_req *)net_pkt_get_data(pkt, - &icmp_access); - if (icmp_echo == NULL) { - return -EIO; - } - - net_pkt_skip(pkt, sizeof(*icmp_echo)); - - if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { - if (net_pkt_read_be32(pkt, &cycles)) { - return -EIO; - } - - cycles = k_cycle_get_32() - cycles; - - snprintf(time_buf, sizeof(time_buf), -#ifdef CONFIG_FPU - "time=%.2f ms", - (double)((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000.f) -#else - "time=%d ms", - ((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000) -#endif - ); - } - - PR_SHELL(ping_ctx.sh, "%d bytes from %s to %s: icmp_seq=%d ttl=%d " - "%s\n", - ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - - NET_ICMPH_LEN, - net_sprint_ipv4_addr(&ip_hdr->src), - net_sprint_ipv4_addr(&ip_hdr->dst), - ntohs(icmp_echo->sequence), - ip_hdr->ttl, - time_buf); - - if (ntohs(icmp_echo->sequence) == ping_ctx.count) { - ping_done(&ping_ctx); - } - - return 0; -} -#else -static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, - struct net_pkt *pkt, - struct net_icmp_ip_hdr *hdr, - struct net_icmp_hdr *icmp_hdr, - void *user_data) -{ - ARG_UNUSED(ctx); - ARG_UNUSED(pkt); - ARG_UNUSED(hdr); - ARG_UNUSED(icmp_hdr); - ARG_UNUSED(user_data); - - return -ENOTSUP; -} -#endif /* CONFIG_NET_IPV4 */ - -static int parse_arg(size_t *i, size_t argc, char *argv[]) -{ - int res = -1; - const char *str = argv[*i] + 2; - char *endptr; - - if (*str == 0) { - if (*i + 1 >= argc) { - return -1; - } - - *i += 1; - str = argv[*i]; - } - - errno = 0; - if (strncmp(str, "0x", 2) == 0) { - res = strtol(str, &endptr, 16); - } else { - res = strtol(str, &endptr, 10); - } - - if (errno || (endptr == str)) { - return -1; - } - - return res; -} - -static void ping_cleanup(struct ping_context *ctx) -{ - (void)net_icmp_cleanup_ctx(&ctx->icmp); - shell_set_bypass(ctx->sh, NULL); -} - -static void ping_done(struct ping_context *ctx) -{ - k_work_cancel_delayable(&ctx->work); - ping_cleanup(ctx); - /* Dummy write to refresh the prompt. */ - shell_fprintf(ctx->sh, SHELL_NORMAL, ""); -} - -static void ping_work(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct ping_context *ctx = - CONTAINER_OF(dwork, struct ping_context, work); - const struct shell *sh = ctx->sh; - struct net_icmp_ping_params params; - int ret; - - ctx->sequence++; - - if (ctx->sequence > ctx->count) { - PR_INFO("Ping timeout\n"); - ping_done(ctx); - return; - } - - params.identifier = sys_rand32_get(); - params.sequence = ctx->sequence; - params.tc_tos = ctx->tos; - params.priority = ctx->priority; - params.data = NULL; - params.data_size = ctx->payload_size; - - ret = net_icmp_send_echo_request(&ctx->icmp, - ctx->iface, - &ctx->addr, - ¶ms, - ctx); - if (ret != 0) { - PR_WARNING("Failed to send ping, err: %d", ret); - ping_done(ctx); - return; - } - - if (ctx->sequence < ctx->count) { - k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); - } else { - k_work_reschedule(&ctx->work, K_SECONDS(2)); - } -} - -#define ASCII_CTRL_C 0x03 - -static void ping_bypass(const struct shell *sh, uint8_t *data, size_t len) -{ - ARG_UNUSED(sh); - - for (size_t i = 0; i < len; i++) { - if (data[i] == ASCII_CTRL_C) { - k_work_cancel_delayable(&ping_ctx.work); - ping_cleanup(&ping_ctx); - break; - } - } -} - -static struct net_if *ping_select_iface(int id, struct sockaddr *target) -{ - struct net_if *iface = net_if_get_by_index(id); - - if (iface != NULL) { - goto out; - } - - if (IS_ENABLED(CONFIG_NET_IPV4) && target->sa_family == AF_INET) { - iface = net_if_ipv4_select_src_iface(&net_sin(target)->sin_addr); - if (iface != NULL) { - goto out; - } - - iface = net_if_get_default(); - goto out; - } - - if (IS_ENABLED(CONFIG_NET_IPV6) && target->sa_family == AF_INET6) { - struct net_nbr *nbr; -#if defined(CONFIG_NET_ROUTE) - struct net_route_entry *route; -#endif - - iface = net_if_ipv6_select_src_iface(&net_sin6(target)->sin6_addr); - if (iface != NULL) { - goto out; - } - - nbr = net_ipv6_nbr_lookup(NULL, &net_sin6(target)->sin6_addr); - if (nbr) { - iface = nbr->iface; - goto out; - } - -#if defined(CONFIG_NET_ROUTE) - route = net_route_lookup(NULL, &net_sin6(target)->sin6_addr); - if (route) { - iface = route->iface; - goto out; - } -#endif - - iface = net_if_get_default(); - } - -out: - return iface; -} - -#endif /* CONFIG_NET_IP */ - -static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) -{ -#if !defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) - ARG_UNUSED(sh); - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return -EOPNOTSUPP; -#else - char *host = NULL; - - int count = 3; - int interval = 1000; - int iface_idx = -1; - int tos = 0; - int payload_size = 4; - int priority = -1; - int ret; - - for (size_t i = 1; i < argc; ++i) { - - if (*argv[i] != '-') { - host = argv[i]; - continue; - } - - switch (argv[i][1]) { - case 'c': - count = parse_arg(&i, argc, argv); - if (count < 0) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - - - break; - case 'i': - interval = parse_arg(&i, argc, argv); - if (interval < 0) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - - break; - - case 'I': - iface_idx = parse_arg(&i, argc, argv); - if (iface_idx < 0 || !net_if_get_by_index(iface_idx)) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - break; - - case 'p': - priority = parse_arg(&i, argc, argv); - if (priority < 0 || priority > UINT8_MAX) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - break; - - case 'Q': - tos = parse_arg(&i, argc, argv); - if (tos < 0 || tos > UINT8_MAX) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - - break; - - case 's': - payload_size = parse_arg(&i, argc, argv); - if (payload_size < 0 || payload_size > UINT16_MAX) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - - break; - - default: - PR_WARNING("Unrecognized argument: %s\n", argv[i]); - return -ENOEXEC; - } - } - - if (!host) { - PR_WARNING("Target host missing\n"); - return -ENOEXEC; - } - - memset(&ping_ctx, 0, sizeof(ping_ctx)); - - k_work_init_delayable(&ping_ctx.work, ping_work); - - ping_ctx.sh = sh; - ping_ctx.count = count; - ping_ctx.interval = interval; - ping_ctx.priority = priority; - ping_ctx.tos = tos; - ping_ctx.payload_size = payload_size; - - if (IS_ENABLED(CONFIG_NET_IPV6) && - net_addr_pton(AF_INET6, host, &ping_ctx.addr6.sin6_addr) == 0) { - ping_ctx.addr6.sin6_family = AF_INET6; - - ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV6_ECHO_REPLY, 0, - handle_ipv6_echo_reply); - if (ret < 0) { - PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv6"); - return 0; - } - } else if (IS_ENABLED(CONFIG_NET_IPV4) && - net_addr_pton(AF_INET, host, &ping_ctx.addr4.sin_addr) == 0) { - ping_ctx.addr4.sin_family = AF_INET; - - ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV4_ECHO_REPLY, 0, - handle_ipv4_echo_reply); - if (ret < 0) { - PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv4"); - return 0; - } - } else { - PR_WARNING("Invalid IP address\n"); - return 0; - } - - ping_ctx.iface = ping_select_iface(iface_idx, &ping_ctx.addr); - - PR("PING %s\n", host); - - shell_set_bypass(sh, ping_bypass); - k_work_reschedule(&ping_ctx.work, K_NO_WAIT); - - return 0; -#endif -} - static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) { size_t last_offset = (slab->info.num_blocks - 1) * slab->info.block_size; @@ -3106,15 +2633,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ping, - SHELL_CMD(--help, NULL, - "'net ping [-c count] [-i interval ms] [-I ] " - "[-Q tos] [-s payload size] [-p priority] ' " - "Send ICMPv4 or ICMPv6 Echo-Request to a network host.", - cmd_net_ping), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_pkt, SHELL_CMD(--help, NULL, "'net pkt [ptr in hex]' " @@ -3138,7 +2656,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(ping, &net_cmd_ping, "Ping a network host.", cmd_net_ping), SHELL_CMD(pkt, &net_cmd_pkt, "net_pkt information.", cmd_net_pkt), SHELL_CMD(ppp, &net_cmd_ppp, "PPP information.", cmd_net_ppp_status), SHELL_CMD(resume, NULL, "Resume a network interface", cmd_net_resume), diff --git a/subsys/net/lib/shell/ping.c b/subsys/net/lib/shell/ping.c new file mode 100644 index 00000000000..5556140cff5 --- /dev/null +++ b/subsys/net/lib/shell/ping.c @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include +#include +#include +#include + +#include "common.h" + +#include "../ip/icmpv6.h" +#include "../ip/icmpv4.h" +#include "../ip/route.h" + +#if defined(CONFIG_NET_IP) + +static struct ping_context { + struct k_work_delayable work; + struct net_icmp_ctx icmp; + union { + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + struct sockaddr addr; + }; + struct net_if *iface; + const struct shell *sh; + + /* Ping parameters */ + uint32_t count; + uint32_t interval; + uint32_t sequence; + uint16_t payload_size; + uint8_t tos; + int priority; +} ping_ctx; + +static void ping_done(struct ping_context *ctx); + +#if defined(CONFIG_NET_NATIVE_IPV6) + +static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, + struct net_icmpv6_echo_req); + struct net_ipv6_hdr *ip_hdr = hdr->ipv6; + struct net_icmpv6_echo_req *icmp_echo; + uint32_t cycles; + char time_buf[16] = { 0 }; + + icmp_echo = (struct net_icmpv6_echo_req *)net_pkt_get_data(pkt, + &icmp_access); + if (icmp_echo == NULL) { + return -EIO; + } + + net_pkt_skip(pkt, sizeof(*icmp_echo)); + + if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { + if (net_pkt_read_be32(pkt, &cycles)) { + return -EIO; + } + + cycles = k_cycle_get_32() - cycles; + + snprintf(time_buf, sizeof(time_buf), +#ifdef CONFIG_FPU + "time=%.2f ms", + (double)((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000.f) +#else + "time=%d ms", + ((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000) +#endif + ); + } + + PR_SHELL(ping_ctx.sh, "%d bytes from %s to %s: icmp_seq=%d ttl=%d " +#ifdef CONFIG_IEEE802154 + "rssi=%d " +#endif + "%s\n", + ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - + NET_ICMPH_LEN, + net_sprint_ipv6_addr(&ip_hdr->src), + net_sprint_ipv6_addr(&ip_hdr->dst), + ntohs(icmp_echo->sequence), + ip_hdr->hop_limit, +#ifdef CONFIG_IEEE802154 + net_pkt_ieee802154_rssi_dbm(pkt), +#endif + time_buf); + + if (ntohs(icmp_echo->sequence) == ping_ctx.count) { + ping_done(&ping_ctx); + } + + net_pkt_unref(pkt); + return 0; +} +#else +static int handle_ipv6_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + + return -ENOTSUP; +} +#endif /* CONFIG_NET_IPV6 */ + +#if defined(CONFIG_NET_NATIVE_IPV4) + +static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, + struct net_icmpv4_echo_req); + struct net_ipv4_hdr *ip_hdr = hdr->ipv4; + uint32_t cycles; + struct net_icmpv4_echo_req *icmp_echo; + char time_buf[16] = { 0 }; + + icmp_echo = (struct net_icmpv4_echo_req *)net_pkt_get_data(pkt, + &icmp_access); + if (icmp_echo == NULL) { + return -EIO; + } + + net_pkt_skip(pkt, sizeof(*icmp_echo)); + + if (net_pkt_remaining_data(pkt) >= sizeof(uint32_t)) { + if (net_pkt_read_be32(pkt, &cycles)) { + return -EIO; + } + + cycles = k_cycle_get_32() - cycles; + + snprintf(time_buf, sizeof(time_buf), +#ifdef CONFIG_FPU + "time=%.2f ms", + (double)((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000.f) +#else + "time=%d ms", + ((uint32_t)k_cyc_to_ns_floor64(cycles) / 1000000) +#endif + ); + } + + PR_SHELL(ping_ctx.sh, "%d bytes from %s to %s: icmp_seq=%d ttl=%d " + "%s\n", + ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - + NET_ICMPH_LEN, + net_sprint_ipv4_addr(&ip_hdr->src), + net_sprint_ipv4_addr(&ip_hdr->dst), + ntohs(icmp_echo->sequence), + ip_hdr->ttl, + time_buf); + + if (ntohs(icmp_echo->sequence) == ping_ctx.count) { + ping_done(&ping_ctx); + } + + net_pkt_unref(pkt); + return 0; +} +#else +static int handle_ipv4_echo_reply(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + + return -ENOTSUP; +} +#endif /* CONFIG_NET_IPV4 */ + +static int parse_arg(size_t *i, size_t argc, char *argv[]) +{ + int res = -1; + const char *str = argv[*i] + 2; + char *endptr; + + if (*str == 0) { + if (*i + 1 >= argc) { + return -1; + } + + *i += 1; + str = argv[*i]; + } + + errno = 0; + if (strncmp(str, "0x", 2) == 0) { + res = strtol(str, &endptr, 16); + } else { + res = strtol(str, &endptr, 10); + } + + if (errno || (endptr == str)) { + return -1; + } + + return res; +} + +static void ping_cleanup(struct ping_context *ctx) +{ + (void)net_icmp_cleanup_ctx(&ctx->icmp); + shell_set_bypass(ctx->sh, NULL); +} + +static void ping_done(struct ping_context *ctx) +{ + k_work_cancel_delayable(&ctx->work); + ping_cleanup(ctx); + /* Dummy write to refresh the prompt. */ + shell_fprintf(ctx->sh, SHELL_NORMAL, ""); +} + +static void ping_work(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct ping_context *ctx = + CONTAINER_OF(dwork, struct ping_context, work); + const struct shell *sh = ctx->sh; + struct net_icmp_ping_params params; + int ret; + + ctx->sequence++; + + if (ctx->sequence > ctx->count) { + PR_INFO("Ping timeout\n"); + ping_done(ctx); + return; + } + + params.identifier = sys_rand32_get(); + params.sequence = ctx->sequence; + params.tc_tos = ctx->tos; + params.priority = ctx->priority; + params.data = NULL; + params.data_size = ctx->payload_size; + + ret = net_icmp_send_echo_request(&ctx->icmp, + ctx->iface, + &ctx->addr, + ¶ms, + ctx); + if (ret != 0) { + PR_WARNING("Failed to send ping, err: %d", ret); + ping_done(ctx); + return; + } + + if (ctx->sequence < ctx->count) { + k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); + } else { + k_work_reschedule(&ctx->work, K_SECONDS(2)); + } +} + +#define ASCII_CTRL_C 0x03 + +static void ping_bypass(const struct shell *sh, uint8_t *data, size_t len) +{ + ARG_UNUSED(sh); + + for (size_t i = 0; i < len; i++) { + if (data[i] == ASCII_CTRL_C) { + k_work_cancel_delayable(&ping_ctx.work); + ping_cleanup(&ping_ctx); + break; + } + } +} + +static struct net_if *ping_select_iface(int id, struct sockaddr *target) +{ + struct net_if *iface = net_if_get_by_index(id); + + if (iface != NULL) { + goto out; + } + + if (IS_ENABLED(CONFIG_NET_IPV4) && target->sa_family == AF_INET) { + iface = net_if_ipv4_select_src_iface(&net_sin(target)->sin_addr); + if (iface != NULL) { + goto out; + } + + iface = net_if_get_default(); + goto out; + } + + if (IS_ENABLED(CONFIG_NET_IPV6) && target->sa_family == AF_INET6) { + struct net_nbr *nbr; +#if defined(CONFIG_NET_ROUTE) + struct net_route_entry *route; +#endif + + iface = net_if_ipv6_select_src_iface(&net_sin6(target)->sin6_addr); + if (iface != NULL) { + goto out; + } + + nbr = net_ipv6_nbr_lookup(NULL, &net_sin6(target)->sin6_addr); + if (nbr) { + iface = nbr->iface; + goto out; + } + +#if defined(CONFIG_NET_ROUTE) + route = net_route_lookup(NULL, &net_sin6(target)->sin6_addr); + if (route) { + iface = route->iface; + goto out; + } +#endif + + iface = net_if_get_default(); + } + +out: + return iface; +} + +#endif /* CONFIG_NET_IP */ + +static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6) + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return -EOPNOTSUPP; +#else + char *host = NULL; + + int count = 3; + int interval = 1000; + int iface_idx = -1; + int tos = 0; + int payload_size = 4; + int priority = -1; + int ret; + + for (size_t i = 1; i < argc; ++i) { + + if (*argv[i] != '-') { + host = argv[i]; + continue; + } + + switch (argv[i][1]) { + case 'c': + count = parse_arg(&i, argc, argv); + if (count < 0) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + + + break; + case 'i': + interval = parse_arg(&i, argc, argv); + if (interval < 0) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + + break; + + case 'I': + iface_idx = parse_arg(&i, argc, argv); + if (iface_idx < 0 || !net_if_get_by_index(iface_idx)) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + break; + + case 'p': + priority = parse_arg(&i, argc, argv); + if (priority < 0 || priority > UINT8_MAX) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + break; + + case 'Q': + tos = parse_arg(&i, argc, argv); + if (tos < 0 || tos > UINT8_MAX) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + + break; + + case 's': + payload_size = parse_arg(&i, argc, argv); + if (payload_size < 0 || payload_size > UINT16_MAX) { + PR_WARNING("Parse error: %s\n", argv[i]); + return -ENOEXEC; + } + + break; + + default: + PR_WARNING("Unrecognized argument: %s\n", argv[i]); + return -ENOEXEC; + } + } + + if (!host) { + PR_WARNING("Target host missing\n"); + return -ENOEXEC; + } + + memset(&ping_ctx, 0, sizeof(ping_ctx)); + + k_work_init_delayable(&ping_ctx.work, ping_work); + + ping_ctx.sh = sh; + ping_ctx.count = count; + ping_ctx.interval = interval; + ping_ctx.priority = priority; + ping_ctx.tos = tos; + ping_ctx.payload_size = payload_size; + + if (IS_ENABLED(CONFIG_NET_IPV6) && + net_addr_pton(AF_INET6, host, &ping_ctx.addr6.sin6_addr) == 0) { + ping_ctx.addr6.sin6_family = AF_INET6; + + ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV6_ECHO_REPLY, 0, + handle_ipv6_echo_reply); + if (ret < 0) { + PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv6"); + return 0; + } + } else if (IS_ENABLED(CONFIG_NET_IPV4) && + net_addr_pton(AF_INET, host, &ping_ctx.addr4.sin_addr) == 0) { + ping_ctx.addr4.sin_family = AF_INET; + + ret = net_icmp_init_ctx(&ping_ctx.icmp, NET_ICMPV4_ECHO_REPLY, 0, + handle_ipv4_echo_reply); + if (ret < 0) { + PR_WARNING("Cannot initialize ICMP context for %s\n", "IPv4"); + return 0; + } + } else { + PR_WARNING("Invalid IP address\n"); + return 0; + } + + ping_ctx.iface = ping_select_iface(iface_idx, &ping_ctx.addr); + + PR("PING %s\n", host); + + shell_set_bypass(sh, ping_bypass); + k_work_reschedule(&ping_ctx.work, K_NO_WAIT); + + return 0; +#endif +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ping, + SHELL_CMD(--help, NULL, + "'net ping [-c count] [-i interval ms] [-I ] " + "[-Q tos] [-s payload size] [-p priority] ' " + "Send ICMPv4 or ICMPv6 Echo-Request to a network host.", + cmd_net_ping), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), ping, &net_cmd_ping, + "Ping a network host.", + cmd_net_ping, 1, 13); From 58ad0a5c13be4622cdde3e7cf6baae1d94e22a5a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:43:10 +0300 Subject: [PATCH 2372/4498] net: shell: Add pkt command Move "pkt" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 174 -------------------------- subsys/net/lib/shell/pkt.c | 183 ++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 174 deletions(-) create mode 100644 subsys/net/lib/shell/pkt.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index b5a68f74145..9226da4bce0 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -19,6 +19,7 @@ zephyr_library_sources(ipv6.c) zephyr_library_sources(mem.c) zephyr_library_sources(nbr.c) zephyr_library_sources(ping.c) +zephyr_library_sources(pkt.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 0308fe1ac06..0a0f7ec3131 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -979,171 +979,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv return 0; } -static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) -{ - size_t last_offset = (slab->info.num_blocks - 1) * slab->info.block_size; - size_t ptr_offset; - - /* Check if pointer fits into slab buffer area. */ - if ((ptr < slab->buffer) || (ptr > slab->buffer + last_offset)) { - return false; - } - - /* Check if pointer offset is correct. */ - ptr_offset = ptr - slab->buffer; - if (ptr_offset % slab->info.block_size != 0) { - return false; - } - - return true; -} - -struct ctx_pkt_slab_info { - const void *ptr; - bool pkt_source_found; -}; - -static void check_context_pool(struct net_context *context, void *user_data) -{ -#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) - if (!net_context_is_used(context)) { - return; - } - - if (context->tx_slab) { - struct ctx_pkt_slab_info *info = user_data; - struct k_mem_slab *slab = context->tx_slab(); - - if (is_pkt_part_of_slab(slab, info->ptr)) { - info->pkt_source_found = true; - } - } -#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ -} - -static bool is_pkt_ptr_valid(const void *ptr) -{ - struct k_mem_slab *rx, *tx; - - net_pkt_get_info(&rx, &tx, NULL, NULL); - - if (is_pkt_part_of_slab(rx, ptr) || is_pkt_part_of_slab(tx, ptr)) { - return true; - } - - if (IS_ENABLED(CONFIG_NET_CONTEXT_NET_PKT_POOL)) { - struct ctx_pkt_slab_info info; - - info.ptr = ptr; - info.pkt_source_found = false; - - net_context_foreach(check_context_pool, &info); - - if (info.pkt_source_found) { - return true; - } - } - - return false; -} - -static struct net_pkt *get_net_pkt(const char *ptr_str) -{ - uint8_t buf[sizeof(intptr_t)]; - intptr_t ptr = 0; - size_t len; - int i; - - if (ptr_str[0] == '0' && ptr_str[1] == 'x') { - ptr_str += 2; - } - - len = hex2bin(ptr_str, strlen(ptr_str), buf, sizeof(buf)); - if (!len) { - return NULL; - } - - for (i = len - 1; i >= 0; i--) { - ptr |= buf[i] << 8 * (len - 1 - i); - } - - return (struct net_pkt *)ptr; -} - -static void net_pkt_buffer_info(const struct shell *sh, struct net_pkt *pkt) -{ - struct net_buf *buf = pkt->buffer; - - PR("net_pkt %p buffer chain:\n", pkt); - PR("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref)); - - if (buf) { - PR("->"); - } - - while (buf) { - PR("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref), - buf->len, net_buf_max_len(buf), buf->size); - - buf = buf->frags; - if (buf) { - PR("->"); - } - } - - PR("\n"); -} - -static void net_pkt_buffer_hexdump(const struct shell *sh, - struct net_pkt *pkt) -{ - struct net_buf *buf = pkt->buffer; - int i = 0; - - if (!buf || buf->ref == 0) { - return; - } - - PR("net_pkt %p buffer chain hexdump:\n", pkt); - - while (buf) { - PR("net_buf[%d] %p\n", i++, buf); - shell_hexdump(sh, buf->data, buf->len); - buf = buf->frags; - } -} - -static int cmd_net_pkt(const struct shell *sh, size_t argc, char *argv[]) -{ - if (argv[1]) { - struct net_pkt *pkt; - - pkt = get_net_pkt(argv[1]); - if (!pkt) { - PR_ERROR("Invalid ptr value (%s). " - "Example: 0x01020304\n", argv[1]); - - return -ENOEXEC; - } - - if (!is_pkt_ptr_valid(pkt)) { - PR_ERROR("Pointer is not recognized as net_pkt (%s).\n", - argv[1]); - - return -ENOEXEC; - } - - net_pkt_buffer_info(sh, pkt); - PR("\n"); - net_pkt_buffer_hexdump(sh, pkt); - } else { - PR_INFO("Pointer value must be given.\n"); - return -ENOEXEC; - } - - return 0; -} - static int cmd_net_ppp_ping(const struct shell *sh, size_t argc, char *argv[]) { @@ -2633,14 +2468,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_pkt, - SHELL_CMD(--help, NULL, - "'net pkt [ptr in hex]' " - "Print information about given net_pkt", - cmd_net_pkt), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, SHELL_CMD(bind, NULL, "'net udp bind ' binds to UDP local port.", @@ -2656,7 +2483,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(pkt, &net_cmd_pkt, "net_pkt information.", cmd_net_pkt), SHELL_CMD(ppp, &net_cmd_ppp, "PPP information.", cmd_net_ppp_status), SHELL_CMD(resume, NULL, "Resume a network interface", cmd_net_resume), SHELL_CMD(route, &net_cmd_route, "Show network route.", cmd_net_route), diff --git a/subsys/net/lib/shell/pkt.c b/subsys/net/lib/shell/pkt.c new file mode 100644 index 00000000000..09d7ae6738a --- /dev/null +++ b/subsys/net/lib/shell/pkt.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) +{ + size_t last_offset = (slab->info.num_blocks - 1) * slab->info.block_size; + size_t ptr_offset; + + /* Check if pointer fits into slab buffer area. */ + if ((ptr < slab->buffer) || (ptr > slab->buffer + last_offset)) { + return false; + } + + /* Check if pointer offset is correct. */ + ptr_offset = ptr - slab->buffer; + if (ptr_offset % slab->info.block_size != 0) { + return false; + } + + return true; +} + +struct ctx_pkt_slab_info { + const void *ptr; + bool pkt_source_found; +}; + +static void check_context_pool(struct net_context *context, void *user_data) +{ +#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) + if (!net_context_is_used(context)) { + return; + } + + if (context->tx_slab) { + struct ctx_pkt_slab_info *info = user_data; + struct k_mem_slab *slab = context->tx_slab(); + + if (is_pkt_part_of_slab(slab, info->ptr)) { + info->pkt_source_found = true; + } + } +#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ +} + +static bool is_pkt_ptr_valid(const void *ptr) +{ + struct k_mem_slab *rx, *tx; + + net_pkt_get_info(&rx, &tx, NULL, NULL); + + if (is_pkt_part_of_slab(rx, ptr) || is_pkt_part_of_slab(tx, ptr)) { + return true; + } + + if (IS_ENABLED(CONFIG_NET_CONTEXT_NET_PKT_POOL)) { + struct ctx_pkt_slab_info info; + + info.ptr = ptr; + info.pkt_source_found = false; + + net_context_foreach(check_context_pool, &info); + + if (info.pkt_source_found) { + return true; + } + } + + return false; +} + +static struct net_pkt *get_net_pkt(const char *ptr_str) +{ + uint8_t buf[sizeof(intptr_t)]; + intptr_t ptr = 0; + size_t len; + int i; + + if (ptr_str[0] == '0' && ptr_str[1] == 'x') { + ptr_str += 2; + } + + len = hex2bin(ptr_str, strlen(ptr_str), buf, sizeof(buf)); + if (!len) { + return NULL; + } + + for (i = len - 1; i >= 0; i--) { + ptr |= buf[i] << 8 * (len - 1 - i); + } + + return (struct net_pkt *)ptr; +} + +static void net_pkt_buffer_info(const struct shell *sh, struct net_pkt *pkt) +{ + struct net_buf *buf = pkt->buffer; + + PR("net_pkt %p buffer chain:\n", pkt); + PR("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref)); + + if (buf) { + PR("->"); + } + + while (buf) { + PR("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref), + buf->len, net_buf_max_len(buf), buf->size); + + buf = buf->frags; + if (buf) { + PR("->"); + } + } + + PR("\n"); +} + +static void net_pkt_buffer_hexdump(const struct shell *sh, + struct net_pkt *pkt) +{ + struct net_buf *buf = pkt->buffer; + int i = 0; + + if (!buf || buf->ref == 0) { + return; + } + + PR("net_pkt %p buffer chain hexdump:\n", pkt); + + while (buf) { + PR("net_buf[%d] %p\n", i++, buf); + shell_hexdump(sh, buf->data, buf->len); + buf = buf->frags; + } +} + +static int cmd_net_pkt(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_pkt *pkt; + + pkt = get_net_pkt(argv[1]); + if (!pkt) { + PR_ERROR("Invalid ptr value (%s). " + "Example: 0x01020304\n", argv[1]); + + return -ENOEXEC; + } + + if (!is_pkt_ptr_valid(pkt)) { + PR_ERROR("Pointer is not recognized as net_pkt (%s).\n", + argv[1]); + + return -ENOEXEC; + } + + net_pkt_buffer_info(sh, pkt); + PR("\n"); + net_pkt_buffer_hexdump(sh, pkt); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_pkt, + SHELL_CMD(--help, NULL, + "'net pkt ' " + "Print information about given net_pkt", + cmd_net_pkt), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), pkt, &net_cmd_pkt, + "net_pkt information.", + cmd_net_pkt, 2, 0); From e5534b5262b89a89f260ea599df747950f24f90d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 13:56:06 +0300 Subject: [PATCH 2373/4498] net: shell: Add ppp command Move "ppp" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 178 ---------------------- subsys/net/lib/shell/ppp.c | 226 ++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 178 deletions(-) create mode 100644 subsys/net/lib/shell/ppp.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 9226da4bce0..02b7ee56316 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources(mem.c) zephyr_library_sources(nbr.c) zephyr_library_sources(ping.c) zephyr_library_sources(pkt.c) +zephyr_library_sources(ppp.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 0a0f7ec3131..62bb4a39395 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -24,7 +24,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include -#include #include #include #if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_L2_ETHERNET_MGMT) @@ -979,117 +978,6 @@ static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv return 0; } -static int cmd_net_ppp_ping(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_PPP) - if (argv[1]) { - int ret, idx = get_iface_idx(sh, argv[1]); - - if (idx < 0) { - return -ENOEXEC; - } - - ret = net_ppp_ping(idx, MSEC_PER_SEC * 1); - if (ret < 0) { - if (ret == -EAGAIN) { - PR_INFO("PPP Echo-Req timeout.\n"); - } else if (ret == -ENODEV || ret == -ENOENT) { - PR_INFO("Not a PPP interface (%d)\n", idx); - } else { - PR_INFO("PPP Echo-Req failed (%d)\n", ret); - } - } else { - if (ret > 1000) { - PR_INFO("%s%d msec\n", - "Received PPP Echo-Reply in ", - ret / 1000); - } else { - PR_INFO("%s%d usec\n", - "Received PPP Echo-Reply in ", ret); - } - } - } else { - PR_INFO("PPP network interface must be given.\n"); - return -ENOEXEC; - } -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_PPP", "PPP"); -#endif - return 0; -} - -static int cmd_net_ppp_status(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_PPP) - int idx = 0; - struct ppp_context *ctx; - - if (argv[1]) { - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - } - - ctx = net_ppp_context_get(idx); - if (!ctx) { - PR_INFO("PPP context not found.\n"); - return -ENOEXEC; - } - - PR("PPP phase : %s (%d)\n", ppp_phase_str(ctx->phase), - ctx->phase); - PR("LCP state : %s (%d)\n", - ppp_state_str(ctx->lcp.fsm.state), ctx->lcp.fsm.state); - PR("LCP retransmits : %u\n", ctx->lcp.fsm.retransmits); - PR("LCP NACK loops : %u\n", ctx->lcp.fsm.nack_loops); - PR("LCP NACKs recv : %u\n", ctx->lcp.fsm.recv_nack_loops); - PR("LCP current id : %d\n", ctx->lcp.fsm.id); - PR("LCP ACK received : %s\n", ctx->lcp.fsm.ack_received ? - "yes" : "no"); - -#if defined(CONFIG_NET_IPV4) - PR("IPCP state : %s (%d)\n", - ppp_state_str(ctx->ipcp.fsm.state), ctx->ipcp.fsm.state); - PR("IPCP retransmits : %u\n", ctx->ipcp.fsm.retransmits); - PR("IPCP NACK loops : %u\n", ctx->ipcp.fsm.nack_loops); - PR("IPCP NACKs recv : %u\n", ctx->ipcp.fsm.recv_nack_loops); - PR("IPCP current id : %d\n", ctx->ipcp.fsm.id); - PR("IPCP ACK received : %s\n", ctx->ipcp.fsm.ack_received ? - "yes" : "no"); -#endif /* CONFIG_NET_IPV4 */ - -#if defined(CONFIG_NET_IPV6) - PR("IPv6CP state : %s (%d)\n", - ppp_state_str(ctx->ipv6cp.fsm.state), ctx->ipv6cp.fsm.state); - PR("IPv6CP retransmits : %u\n", ctx->ipv6cp.fsm.retransmits); - PR("IPv6CP NACK loops : %u\n", ctx->ipv6cp.fsm.nack_loops); - PR("IPv6CP NACKs recv : %u\n", ctx->ipv6cp.fsm.recv_nack_loops); - PR("IPv6CP current id : %d\n", ctx->ipv6cp.fsm.id); - PR("IPv6CP ACK received : %s\n", ctx->ipv6cp.fsm.ack_received ? - "yes" : "no"); -#endif /* CONFIG_NET_IPV6 */ - -#if defined(CONFIG_NET_L2_PPP_PAP) - PR("PAP state : %s (%d)\n", - ppp_state_str(ctx->pap.fsm.state), ctx->pap.fsm.state); - PR("PAP retransmits : %u\n", ctx->pap.fsm.retransmits); - PR("PAP NACK loops : %u\n", ctx->pap.fsm.nack_loops); - PR("PAP NACKs recv : %u\n", ctx->pap.fsm.recv_nack_loops); - PR("PAP current id : %d\n", ctx->pap.fsm.id); - PR("PAP ACK received : %s\n", ctx->pap.fsm.ack_received ? - "yes" : "no"); -#endif /* CONFIG_NET_L2_PPP_PAP */ - -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_L2_PPP and CONFIG_NET_PPP", "PPP"); -#endif - return 0; -} - static int cmd_net_route(const struct shell *sh, size_t argc, char *argv[]) { ARG_UNUSED(argc); @@ -2341,61 +2229,6 @@ static int cmd_net_websocket(const struct shell *sh, size_t argc, SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); -#if defined(CONFIG_NET_PPP) -static char *set_iface_ppp_index_buffer(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) { - return NULL; - } - - snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); - - return iface_index_buffer[idx]; -} - -static char *set_iface_ppp_index_help(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) { - return NULL; - } - - snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, - "%s (%p)", iface2str(iface, NULL), iface); - - return iface_help_buffer[idx]; -} - -static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry); - -SHELL_DYNAMIC_CMD_CREATE(iface_ppp_index, iface_ppp_index_get); - -static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry) -{ - entry->handler = NULL; - entry->help = set_iface_ppp_index_help(idx); - entry->subcmd = &iface_ppp_index; - entry->syntax = set_iface_ppp_index_buffer(idx); -} - -#define IFACE_PPP_DYN_CMD &iface_ppp_index -#else -#define IFACE_PPP_DYN_CMD NULL -#endif /* CONFIG_NET_PPP */ - -#else -#define IFACE_PPP_DYN_CMD NULL #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, @@ -2410,16 +2243,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp, - SHELL_CMD(ping, IFACE_PPP_DYN_CMD, - "'net ppp ping ' sends Echo-request to PPP interface.", - cmd_net_ppp_ping), - SHELL_CMD(status, NULL, - "'net ppp status' prints information about PPP.", - cmd_net_ppp_status), - SHELL_SUBCMD_SET_END -); - #if defined(CONFIG_NET_STATISTICS) && \ defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) @@ -2483,7 +2306,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(ppp, &net_cmd_ppp, "PPP information.", cmd_net_ppp_status), SHELL_CMD(resume, NULL, "Resume a network interface", cmd_net_resume), SHELL_CMD(route, &net_cmd_route, "Show network route.", cmd_net_route), SHELL_CMD(stacks, NULL, "Show network stacks information.", diff --git a/subsys/net/lib/shell/ppp.c b/subsys/net/lib/shell/ppp.c new file mode 100644 index 00000000000..9b5f8355d47 --- /dev/null +++ b/subsys/net/lib/shell/ppp.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#if defined(CONFIG_NET_L2_PPP) +#include +#include "ppp/ppp_internal.h" +#endif + +static int cmd_net_ppp_ping(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_PPP) + if (argv[1]) { + int ret, idx = get_iface_idx(sh, argv[1]); + + if (idx < 0) { + return -ENOEXEC; + } + + ret = net_ppp_ping(idx, MSEC_PER_SEC * 1); + if (ret < 0) { + if (ret == -EAGAIN) { + PR_INFO("PPP Echo-Req timeout.\n"); + } else if (ret == -ENODEV || ret == -ENOENT) { + PR_INFO("Not a PPP interface (%d)\n", idx); + } else { + PR_INFO("PPP Echo-Req failed (%d)\n", ret); + } + } else { + if (ret > 1000) { + PR_INFO("%s%d msec\n", + "Received PPP Echo-Reply in ", + ret / 1000); + } else { + PR_INFO("%s%d usec\n", + "Received PPP Echo-Reply in ", ret); + } + } + } else { + PR_INFO("PPP network interface must be given.\n"); + return -ENOEXEC; + } +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_PPP", "PPP"); +#endif + return 0; +} + +static int cmd_net_ppp_status(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_PPP) + int idx = 0; + struct ppp_context *ctx; + + if (argv[1]) { + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + } + + ctx = net_ppp_context_get(idx); + if (!ctx) { + PR_INFO("PPP context not found.\n"); + return -ENOEXEC; + } + + PR("PPP phase : %s (%d)\n", ppp_phase_str(ctx->phase), + ctx->phase); + PR("LCP state : %s (%d)\n", + ppp_state_str(ctx->lcp.fsm.state), ctx->lcp.fsm.state); + PR("LCP retransmits : %u\n", ctx->lcp.fsm.retransmits); + PR("LCP NACK loops : %u\n", ctx->lcp.fsm.nack_loops); + PR("LCP NACKs recv : %u\n", ctx->lcp.fsm.recv_nack_loops); + PR("LCP current id : %d\n", ctx->lcp.fsm.id); + PR("LCP ACK received : %s\n", ctx->lcp.fsm.ack_received ? + "yes" : "no"); + +#if defined(CONFIG_NET_IPV4) + PR("IPCP state : %s (%d)\n", + ppp_state_str(ctx->ipcp.fsm.state), ctx->ipcp.fsm.state); + PR("IPCP retransmits : %u\n", ctx->ipcp.fsm.retransmits); + PR("IPCP NACK loops : %u\n", ctx->ipcp.fsm.nack_loops); + PR("IPCP NACKs recv : %u\n", ctx->ipcp.fsm.recv_nack_loops); + PR("IPCP current id : %d\n", ctx->ipcp.fsm.id); + PR("IPCP ACK received : %s\n", ctx->ipcp.fsm.ack_received ? + "yes" : "no"); +#endif /* CONFIG_NET_IPV4 */ + +#if defined(CONFIG_NET_IPV6) + PR("IPv6CP state : %s (%d)\n", + ppp_state_str(ctx->ipv6cp.fsm.state), ctx->ipv6cp.fsm.state); + PR("IPv6CP retransmits : %u\n", ctx->ipv6cp.fsm.retransmits); + PR("IPv6CP NACK loops : %u\n", ctx->ipv6cp.fsm.nack_loops); + PR("IPv6CP NACKs recv : %u\n", ctx->ipv6cp.fsm.recv_nack_loops); + PR("IPv6CP current id : %d\n", ctx->ipv6cp.fsm.id); + PR("IPv6CP ACK received : %s\n", ctx->ipv6cp.fsm.ack_received ? + "yes" : "no"); +#endif /* CONFIG_NET_IPV6 */ + +#if defined(CONFIG_NET_L2_PPP_PAP) + PR("PAP state : %s (%d)\n", + ppp_state_str(ctx->pap.fsm.state), ctx->pap.fsm.state); + PR("PAP retransmits : %u\n", ctx->pap.fsm.retransmits); + PR("PAP NACK loops : %u\n", ctx->pap.fsm.nack_loops); + PR("PAP NACKs recv : %u\n", ctx->pap.fsm.recv_nack_loops); + PR("PAP current id : %d\n", ctx->pap.fsm.id); + PR("PAP ACK received : %s\n", ctx->pap.fsm.ack_received ? + "yes" : "no"); +#endif /* CONFIG_NET_L2_PPP_PAP */ + +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_L2_PPP and CONFIG_NET_PPP", "PPP"); +#endif + return 0; +} + +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) + +#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") +#define MAX_IFACE_STR_LEN sizeof("xxx") + +#if defined(CONFIG_NET_PPP) +static char iface_ppp_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; +static char iface_ppp_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; + +static char *set_iface_ppp_index_buffer(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + /* Network interfaces start at 1 */ + if (idx == 0) { + return ""; + } + + if (!iface) { + return NULL; + } + + if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) { + return NULL; + } + + snprintk(iface_ppp_index_buffer[idx], MAX_IFACE_STR_LEN, "%d", (uint8_t)idx); + + return iface_ppp_index_buffer[idx]; +} + +static char *set_iface_ppp_index_help(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + /* Network interfaces start at 1 */ + if (idx == 0) { + return ""; + } + + if (!iface) { + return NULL; + } + + if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) { + return NULL; + } + +#if defined(CONFIG_NET_INTERFACE_NAME) + char name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + + net_if_get_name(iface, name, CONFIG_NET_INTERFACE_NAME_LEN); + name[CONFIG_NET_INTERFACE_NAME_LEN] = '\0'; + + snprintk(iface_ppp_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "%s [%s] (%p)", name, iface2str(iface, NULL), iface); +#else + snprintk(iface_ppp_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "%s (%p)", iface2str(iface, NULL), iface); +#endif + + return iface_ppp_help_buffer[idx]; +} + +static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(iface_ppp_index, iface_ppp_index_get); + +static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry) +{ + entry->handler = NULL; + entry->help = set_iface_ppp_index_help(idx); + entry->subcmd = &iface_ppp_index; + entry->syntax = set_iface_ppp_index_buffer(idx); +} + +#define IFACE_PPP_DYN_CMD &iface_ppp_index +#else +#define IFACE_PPP_DYN_CMD NULL +#endif /* CONFIG_NET_PPP */ + +#else +#define IFACE_PPP_DYN_CMD NULL +#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp, + SHELL_CMD(ping, IFACE_PPP_DYN_CMD, + "'net ppp ping ' sends Echo-request to PPP interface.", + cmd_net_ppp_ping), + SHELL_CMD(status, NULL, + "'net ppp status' prints information about PPP.", + cmd_net_ppp_status), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), ppp, &net_cmd_ppp, + "PPP information.", + cmd_net_ppp_status, 1, 0); From cb46113df42b769f68556651c8f9f5ad66c182b1 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 14:33:36 +0300 Subject: [PATCH 2374/4498] net: shell: Add resume command Move "resume" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 40 ---------------------- subsys/net/lib/shell/resume.c | 53 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 subsys/net/lib/shell/resume.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 02b7ee56316..5509284e354 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources(nbr.c) zephyr_library_sources(ping.c) zephyr_library_sources(pkt.c) zephyr_library_sources(ppp.c) +zephyr_library_sources(resume.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 62bb4a39395..371c8686db0 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -2127,45 +2127,6 @@ static int cmd_net_suspend(const struct shell *sh, size_t argc, return 0; } -static int cmd_net_resume(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_POWER_MANAGEMENT) - if (argv[1]) { - struct net_if *iface = NULL; - const struct device *dev; - int idx; - int ret; - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - dev = net_if_get_device(iface); - - ret = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME); - if (ret != 0) { - PR_INFO("Iface could not be resumed\n"); - } - - } else { - PR("Usage:\n"); - PR("\tresume \n"); - } -#else - PR_INFO("You need a network driver supporting Power Management.\n"); -#endif /* CONFIG_NET_POWER_MANAGEMENT */ - - return 0; -} - #if defined(CONFIG_WEBSOCKET_CLIENT) static void websocket_context_cb(struct websocket_context *context, void *user_data) @@ -2306,7 +2267,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(resume, NULL, "Resume a network interface", cmd_net_resume), SHELL_CMD(route, &net_cmd_route, "Show network route.", cmd_net_route), SHELL_CMD(stacks, NULL, "Show network stacks information.", cmd_net_stacks), diff --git a/subsys/net/lib/shell/resume.c b/subsys/net/lib/shell/resume.c new file mode 100644 index 00000000000..76c448c7148 --- /dev/null +++ b/subsys/net/lib/shell/resume.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +static int cmd_net_resume(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_POWER_MANAGEMENT) + if (argv[1]) { + struct net_if *iface = NULL; + const struct device *dev; + int idx; + int ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + dev = net_if_get_device(iface); + + ret = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME); + if (ret != 0) { + PR_INFO("Iface could not be resumed\n"); + } + + } else { + PR("Usage:\n"); + PR("\tresume \n"); + } +#else + PR_INFO("You need a network driver supporting Power Management.\n"); +#endif /* CONFIG_NET_POWER_MANAGEMENT */ + + return 0; +} + +SHELL_SUBCMD_ADD((net), resume, NULL, + "Resume a network interface", + cmd_net_resume, 1, 0); From 8b4b064a850576f6e20773dd9429e82445bfa596 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 14:34:31 +0300 Subject: [PATCH 2375/4498] net: shell: Add route command Move "route" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 241 -------------------------- subsys/net/lib/shell/route.c | 257 ++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 241 deletions(-) create mode 100644 subsys/net/lib/shell/route.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 5509284e354..077c7f63dba 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_library_sources(ping.c) zephyr_library_sources(pkt.c) zephyr_library_sources(ppp.c) zephyr_library_sources(resume.c) +zephyr_library_sources(route.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 371c8686db0..c434cad792e 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -33,7 +33,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "common.h" -#include "route.h" #include "connection.h" #if defined(CONFIG_NET_L2_ETHERNET_MGMT) @@ -254,113 +253,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_ROUTE) && defined(CONFIG_NET_NATIVE) -static void route_cb(struct net_route_entry *entry, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct net_if *iface = data->user_data; - struct net_route_nexthop *nexthop_route; - int count; - uint32_t now = k_uptime_get_32(); - - if (entry->iface != iface) { - return; - } - - PR("IPv6 prefix : %s/%d\n", net_sprint_ipv6_addr(&entry->addr), - entry->prefix_len); - - count = 0; - - SYS_SLIST_FOR_EACH_CONTAINER(&entry->nexthop, nexthop_route, node) { - struct net_linkaddr_storage *lladdr; - char remaining_str[sizeof("01234567890 sec")]; - uint32_t remaining; - - if (!nexthop_route->nbr) { - continue; - } - - PR("\tneighbor : %p\t", nexthop_route->nbr); - - if (nexthop_route->nbr->idx == NET_NBR_LLADDR_UNKNOWN) { - PR("addr : \t"); - } else { - lladdr = net_nbr_get_lladdr(nexthop_route->nbr->idx); - - PR("addr : %s\t", net_sprint_ll_addr(lladdr->addr, - lladdr->len)); - } - - if (entry->is_infinite) { - snprintk(remaining_str, sizeof(remaining_str) - 1, - "infinite"); - } else { - remaining = net_timeout_remaining(&entry->lifetime, now); - snprintk(remaining_str, sizeof(remaining_str) - 1, - "%u sec", remaining); - } - - PR("lifetime : %s\n", remaining_str); - - count++; - } - - if (count == 0) { - PR("\t\n"); - } -} - -static void iface_per_route_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - const char *extra; - - PR("\nIPv6 routes for interface %d (%p) (%s)\n", - net_if_get_by_iface(iface), iface, - iface2str(iface, &extra)); - PR("=========================================%s\n", extra); - - data->user_data = iface; - - net_route_foreach(route_cb, data); -} -#endif /* CONFIG_NET_ROUTE */ - -#if defined(CONFIG_NET_ROUTE_MCAST) && defined(CONFIG_NET_NATIVE) -static void route_mcast_cb(struct net_route_entry_mcast *entry, - void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct net_if *iface = data->user_data; - const char *extra; - - if (entry->iface != iface) { - return; - } - - PR("IPv6 multicast route %p for interface %d (%p) (%s)\n", entry, - net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); - PR("===========================================================" - "%s\n", extra); - - PR("IPv6 group : %s\n", net_sprint_ipv6_addr(&entry->group)); - PR("IPv6 group len : %d\n", entry->prefix_len); - PR("Lifetime : %u\n", entry->lifetime); -} - -static void iface_per_mcast_route_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - - data->user_data = iface; - - net_route_mcast_foreach(route_mcast_cb, NULL, data); -} -#endif /* CONFIG_NET_ROUTE_MCAST */ #if defined(CONFIG_NET_STATISTICS) @@ -886,126 +778,6 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data) } #endif /* CONFIG_NET_STATISTICS */ -static int cmd_net_ip6_route_add(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV6) && (CONFIG_NET_ROUTE) - struct net_if *iface = NULL; - int idx; - struct net_route_entry *route; - struct in6_addr gw = {0}; - struct in6_addr prefix = {0}; - - if (argc != 4) { - PR_ERROR("Correct usage: net route add " - " \n"); - return -EINVAL; - } - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_addr_pton(AF_INET6, argv[2], &prefix)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - if (net_addr_pton(AF_INET6, argv[3], &gw)) { - PR_ERROR("Invalid gateway: %s\n", argv[3]); - return -EINVAL; - } - - route = net_route_add(iface, &prefix, NET_IPV6_DEFAULT_PREFIX_LEN, - &gw, NET_IPV6_ND_INFINITE_LIFETIME, - NET_ROUTE_PREFERENCE_MEDIUM); - if (route == NULL) { - PR_ERROR("Failed to add route\n"); - return -ENOEXEC; - } - -#else /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ - PR_INFO("Set %s and %s to enable native %s support." - " And enable CONFIG_NET_ROUTE.\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); -#endif /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ - return 0; -} - -static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_NATIVE_IPV6) && (CONFIG_NET_ROUTE) - struct net_if *iface = NULL; - int idx; - struct net_route_entry *route; - struct in6_addr prefix = { 0 }; - - if (argc != 3) { - PR_ERROR("Correct usage: net route del \n"); - return -EINVAL; - } - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - if (net_addr_pton(AF_INET6, argv[2], &prefix)) { - PR_ERROR("Invalid address: %s\n", argv[2]); - return -EINVAL; - } - - route = net_route_lookup(iface, &prefix); - if (route) { - net_route_del(route); - } -#else /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ - PR_INFO("Set %s and %s to enable native %s support." - " And enable CONFIG_NET_ROUTE\n", - "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); -#endif /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ - return 0; -} - -static int cmd_net_route(const struct shell *sh, size_t argc, char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_NATIVE) -#if defined(CONFIG_NET_ROUTE) || defined(CONFIG_NET_ROUTE_MCAST) - struct net_shell_user_data user_data; -#endif - -#if defined(CONFIG_NET_ROUTE) || defined(CONFIG_NET_ROUTE_MCAST) - user_data.sh = sh; -#endif - -#if defined(CONFIG_NET_ROUTE) - net_if_foreach(iface_per_route_cb, &user_data); -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_ROUTE", - "network route"); -#endif - -#if defined(CONFIG_NET_ROUTE_MCAST) - net_if_foreach(iface_per_mcast_route_cb, &user_data); -#endif -#endif - return 0; -} - static int cmd_net_stacks(const struct shell *sh, size_t argc, char *argv[]) { @@ -2192,18 +1964,6 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, - SHELL_CMD(add, NULL, - "'net route add '" - " adds the route to the destination.", - cmd_net_ip6_route_add), - SHELL_CMD(del, NULL, - "'net route del '" - " deletes the route to the destination.", - cmd_net_ip6_route_del), - SHELL_SUBCMD_SET_END -); - #if defined(CONFIG_NET_STATISTICS) && \ defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) @@ -2267,7 +2027,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(route, &net_cmd_route, "Show network route.", cmd_net_route), SHELL_CMD(stacks, NULL, "Show network stacks information.", cmd_net_stacks), SHELL_CMD(stats, &net_cmd_stats, "Show network statistics.", diff --git a/subsys/net/lib/shell/route.c b/subsys/net/lib/shell/route.c new file mode 100644 index 00000000000..d48c442ed41 --- /dev/null +++ b/subsys/net/lib/shell/route.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +#include "../ip/route.h" + +#if defined(CONFIG_NET_ROUTE) && defined(CONFIG_NET_NATIVE) +static void route_cb(struct net_route_entry *entry, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_if *iface = data->user_data; + struct net_route_nexthop *nexthop_route; + int count; + uint32_t now = k_uptime_get_32(); + + if (entry->iface != iface) { + return; + } + + PR("IPv6 prefix : %s/%d\n", net_sprint_ipv6_addr(&entry->addr), + entry->prefix_len); + + count = 0; + + SYS_SLIST_FOR_EACH_CONTAINER(&entry->nexthop, nexthop_route, node) { + struct net_linkaddr_storage *lladdr; + char remaining_str[sizeof("01234567890 sec")]; + uint32_t remaining; + + if (!nexthop_route->nbr) { + continue; + } + + PR("\tneighbor : %p\t", nexthop_route->nbr); + + if (nexthop_route->nbr->idx == NET_NBR_LLADDR_UNKNOWN) { + PR("addr : \t"); + } else { + lladdr = net_nbr_get_lladdr(nexthop_route->nbr->idx); + + PR("addr : %s\t", net_sprint_ll_addr(lladdr->addr, + lladdr->len)); + } + + if (entry->is_infinite) { + snprintk(remaining_str, sizeof(remaining_str) - 1, + "infinite"); + } else { + remaining = net_timeout_remaining(&entry->lifetime, now); + snprintk(remaining_str, sizeof(remaining_str) - 1, + "%u sec", remaining); + } + + PR("lifetime : %s\n", remaining_str); + + count++; + } + + if (count == 0) { + PR("\t\n"); + } +} + +static void iface_per_route_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + const char *extra; + + PR("\nIPv6 routes for interface %d (%p) (%s)\n", + net_if_get_by_iface(iface), iface, + iface2str(iface, &extra)); + PR("=========================================%s\n", extra); + + data->user_data = iface; + + net_route_foreach(route_cb, data); +} +#endif /* CONFIG_NET_ROUTE */ + +#if defined(CONFIG_NET_ROUTE_MCAST) && defined(CONFIG_NET_NATIVE) +static void route_mcast_cb(struct net_route_entry_mcast *entry, + void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_if *iface = data->user_data; + const char *extra; + + if (entry->iface != iface) { + return; + } + + PR("IPv6 multicast route %p for interface %d (%p) (%s)\n", entry, + net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); + PR("===========================================================" + "%s\n", extra); + + PR("IPv6 group : %s\n", net_sprint_ipv6_addr(&entry->group)); + PR("IPv6 group len : %d\n", entry->prefix_len); + PR("Lifetime : %u\n", entry->lifetime); +} + +static void iface_per_mcast_route_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + + data->user_data = iface; + + net_route_mcast_foreach(route_mcast_cb, NULL, data); +} +#endif /* CONFIG_NET_ROUTE_MCAST */ + +static int cmd_net_ip6_route_add(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV6) && (CONFIG_NET_ROUTE) + struct net_if *iface = NULL; + int idx; + struct net_route_entry *route; + struct in6_addr gw = {0}; + struct in6_addr prefix = {0}; + + if (argc != 4) { + PR_ERROR("Correct usage: net route add " + " \n"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET6, argv[2], &prefix)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + if (net_addr_pton(AF_INET6, argv[3], &gw)) { + PR_ERROR("Invalid gateway: %s\n", argv[3]); + return -EINVAL; + } + + route = net_route_add(iface, &prefix, NET_IPV6_DEFAULT_PREFIX_LEN, + &gw, NET_IPV6_ND_INFINITE_LIFETIME, + NET_ROUTE_PREFERENCE_MEDIUM); + if (route == NULL) { + PR_ERROR("Failed to add route\n"); + return -ENOEXEC; + } + +#else /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ + PR_INFO("Set %s and %s to enable native %s support." + " And enable CONFIG_NET_ROUTE.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); +#endif /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ + return 0; +} + +static int cmd_net_ip6_route_del(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV6) && (CONFIG_NET_ROUTE) + struct net_if *iface = NULL; + int idx; + struct net_route_entry *route; + struct in6_addr prefix = { 0 }; + + if (argc != 3) { + PR_ERROR("Correct usage: net route del \n"); + return -EINVAL; + } + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET6, argv[2], &prefix)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + route = net_route_lookup(iface, &prefix); + if (route) { + net_route_del(route); + } +#else /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ + PR_INFO("Set %s and %s to enable native %s support." + " And enable CONFIG_NET_ROUTE\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV6", "IPv6"); +#endif /* CONFIG_NET_NATIVE_IPV6 && CONFIG_NET_ROUTE */ + return 0; +} + +static int cmd_net_route(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_NATIVE) +#if defined(CONFIG_NET_ROUTE) || defined(CONFIG_NET_ROUTE_MCAST) + struct net_shell_user_data user_data; +#endif + +#if defined(CONFIG_NET_ROUTE) || defined(CONFIG_NET_ROUTE_MCAST) + user_data.sh = sh; +#endif + +#if defined(CONFIG_NET_ROUTE) + net_if_foreach(iface_per_route_cb, &user_data); +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_ROUTE", + "network route"); +#endif + +#if defined(CONFIG_NET_ROUTE_MCAST) + net_if_foreach(iface_per_mcast_route_cb, &user_data); +#endif +#endif + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_route, + SHELL_CMD(add, NULL, + "'net route add '" + " adds the route to the destination.", + cmd_net_ip6_route_add), + SHELL_CMD(del, NULL, + "'net route del '" + " deletes the route to the destination.", + cmd_net_ip6_route_del), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), route, &net_cmd_route, + "Show network route.", + cmd_net_route, 1, 0); From 76eab4e4407722dcf01bd1829e454aaf614816f7 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 14:39:37 +0300 Subject: [PATCH 2376/4498] net: shell: Add stacks command Move "stacks" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 13 ------------- subsys/net/lib/shell/stacks.c | 25 +++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 subsys/net/lib/shell/stacks.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 077c7f63dba..773379a3362 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -23,6 +23,7 @@ zephyr_library_sources(pkt.c) zephyr_library_sources(ppp.c) zephyr_library_sources(resume.c) zephyr_library_sources(route.c) +zephyr_library_sources(stacks.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index c434cad792e..90e319116fd 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -778,17 +778,6 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data) } #endif /* CONFIG_NET_STATISTICS */ -static int cmd_net_stacks(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if !defined(CONFIG_KERNEL_SHELL) - PR("Enable CONFIG_KERNEL_SHELL and type \"kernel stacks\" to see stack information.\n"); -#else - PR("Type \"kernel stacks\" to see stack information.\n"); -#endif - return 0; -} - #if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) static void net_shell_print_statistics_all(struct net_shell_user_data *data) { @@ -2027,8 +2016,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(stacks, NULL, "Show network stacks information.", - cmd_net_stacks), SHELL_CMD(stats, &net_cmd_stats, "Show network statistics.", cmd_net_stats), SHELL_CMD(suspend, NULL, "Suspend a network interface", diff --git a/subsys/net/lib/shell/stacks.c b/subsys/net/lib/shell/stacks.c new file mode 100644 index 00000000000..5bce2b34954 --- /dev/null +++ b/subsys/net/lib/shell/stacks.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +static int cmd_net_stacks(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_KERNEL_SHELL) + PR("Enable CONFIG_KERNEL_SHELL and type \"kernel stacks\" to see stack information.\n"); +#else + PR("Type \"kernel stacks\" to see stack information.\n"); +#endif + return 0; +} + +SHELL_SUBCMD_ADD((net), stacks, NULL, + "Show network stacks information.", + cmd_net_stacks, 1, 0); From fdb86e89a6838f656095142efb50a11945a807f2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 15:11:47 +0300 Subject: [PATCH 2377/4498] net: shell: Add stats command Move "stats" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 653 ------------------------- subsys/net/lib/shell/stats.c | 709 ++++++++++++++++++++++++++++ 3 files changed, 710 insertions(+), 653 deletions(-) create mode 100644 subsys/net/lib/shell/stats.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 773379a3362..17b15e4bec4 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources(ppp.c) zephyr_library_sources(resume.c) zephyr_library_sources(route.c) zephyr_library_sources(stacks.c) +zephyr_library_sources(stats.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 90e319116fd..2d325aa85a2 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -24,7 +24,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include -#include #include #if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_L2_ETHERNET_MGMT) #include @@ -53,7 +52,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #endif #include "net_shell.h" -#include "net_stats.h" #include #include "websocket/websocket_internal.h" @@ -253,634 +251,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } - -#if defined(CONFIG_NET_STATISTICS) - -#if NET_TC_COUNT > 1 -static const char *priority2str(enum net_priority priority) -{ - switch (priority) { - case NET_PRIORITY_BK: - return "BK"; /* Background */ - case NET_PRIORITY_BE: - return "BE"; /* Best effort */ - case NET_PRIORITY_EE: - return "EE"; /* Excellent effort */ - case NET_PRIORITY_CA: - return "CA"; /* Critical applications */ - case NET_PRIORITY_VI: - return "VI"; /* Video, < 100 ms latency and jitter */ - case NET_PRIORITY_VO: - return "VO"; /* Voice, < 10 ms latency and jitter */ - case NET_PRIORITY_IC: - return "IC"; /* Internetwork control */ - case NET_PRIORITY_NC: - return "NC"; /* Network control */ - } - - return "??"; -} -#endif - -#if defined(CONFIG_NET_STATISTICS_ETHERNET) && \ - defined(CONFIG_NET_STATISTICS_USER_API) -static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data, - const struct shell *sh) -{ - PR("Statistics for Ethernet interface %p [%d]\n", iface, - net_if_get_by_iface(iface)); - - PR("Bytes received : %u\n", data->bytes.received); - PR("Bytes sent : %u\n", data->bytes.sent); - PR("Packets received : %u\n", data->pkts.rx); - PR("Packets sent : %u\n", data->pkts.tx); - PR("Bcast received : %u\n", data->broadcast.rx); - PR("Bcast sent : %u\n", data->broadcast.tx); - PR("Mcast received : %u\n", data->multicast.rx); - PR("Mcast sent : %u\n", data->multicast.tx); - - PR("Send errors : %u\n", data->errors.tx); - PR("Receive errors : %u\n", data->errors.rx); - PR("Collisions : %u\n", data->collisions); - PR("Send Drops : %u\n", data->tx_dropped); - PR("Send timeouts : %u\n", data->tx_timeout_count); - PR("Send restarts : %u\n", data->tx_restart_queue); - PR("Unknown protocol : %u\n", data->unknown_protocol); - -#if defined(CONFIG_NET_STATISTICS_ETHERNET_VENDOR) - if (data->vendor) { - PR("Vendor specific statistics for Ethernet " - "interface %p [%d]:\n", - iface, net_if_get_by_iface(iface)); - size_t i = 0; - - do { - PR("%s : %u\n", data->vendor[i].key, - data->vendor[i].value); - i++; - } while (data->vendor[i].key); - } -#endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */ -} -#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */ - -#if defined(CONFIG_NET_STATISTICS_PPP) && \ - defined(CONFIG_NET_STATISTICS_USER_API) -static void print_ppp_stats(struct net_if *iface, struct net_stats_ppp *data, - const struct shell *sh) -{ - PR("Frames recv %u\n", data->pkts.rx); - PR("Frames sent %u\n", data->pkts.tx); - PR("Frames dropped %u\n", data->drop); - PR("Bad FCS %u\n", data->chkerr); -} -#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */ - -#if !defined(CONFIG_NET_NATIVE) -#define GET_STAT(a, b) 0 -#endif - -#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \ - defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) -#if (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) -static char *get_net_pkt_tc_stats_detail(struct net_if *iface, int i, - bool is_tx) -{ - static char extra_stats[sizeof("\t[0=xxxx us]") + - sizeof("->xxxx") * - NET_PKT_DETAIL_STATS_COUNT]; - int j, total = 0, pos = 0; - - pos += snprintk(extra_stats, sizeof(extra_stats), "\t[0"); - - for (j = 0; j < NET_PKT_DETAIL_STATS_COUNT; j++) { - net_stats_t count = 0; - uint32_t avg; - - if (is_tx) { -#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) && (NET_TC_TX_COUNT > 1) - count = GET_STAT(iface, - tc.sent[i].tx_time_detail[j].count); -#endif - } else { -#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) && (NET_TC_RX_COUNT > 1) - count = GET_STAT(iface, - tc.recv[i].rx_time_detail[j].count); -#endif - } - - if (count == 0) { - break; - } - - if (is_tx) { -#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) && (NET_TC_TX_COUNT > 1) - avg = (uint32_t)(GET_STAT(iface, - tc.sent[i].tx_time_detail[j].sum) / - (uint64_t)count); -#endif - } else { -#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) && (NET_TC_RX_COUNT > 1) - avg = (uint32_t)(GET_STAT(iface, - tc.recv[i].rx_time_detail[j].sum) / - (uint64_t)count); -#endif - } - - if (avg == 0) { - continue; - } - - total += avg; - - pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, - "->%u", avg); - } - - if (total == 0U) { - return "\0"; - } - - pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, - "=%u us]", total); - - return extra_stats; -} -#endif /* (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) */ - -#if (NET_TC_TX_COUNT <= 1) || (NET_TC_RX_COUNT <= 1) -static char *get_net_pkt_stats_detail(struct net_if *iface, bool is_tx) -{ - static char extra_stats[sizeof("\t[0=xxxx us]") + sizeof("->xxxx") * - NET_PKT_DETAIL_STATS_COUNT]; - int j, total = 0, pos = 0; - - pos += snprintk(extra_stats, sizeof(extra_stats), "\t[0"); - - for (j = 0; j < NET_PKT_DETAIL_STATS_COUNT; j++) { - net_stats_t count; - uint32_t avg; - - if (is_tx) { -#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) - count = GET_STAT(iface, tx_time_detail[j].count); -#endif - } else { -#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) - count = GET_STAT(iface, rx_time_detail[j].count); -#endif - } - - if (count == 0) { - break; - } - - if (is_tx) { -#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) - avg = (uint32_t)(GET_STAT(iface, - tx_time_detail[j].sum) / - (uint64_t)count); -#endif - } else { -#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) - avg = (uint32_t)(GET_STAT(iface, - rx_time_detail[j].sum) / - (uint64_t)count); -#endif - } - - if (avg == 0) { - continue; - } - - total += avg; - - pos += snprintk(extra_stats + pos, - sizeof(extra_stats) - pos, - "->%u", avg); - } - - if (total == 0U) { - return "\0"; - } - - pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, - "=%u us]", total); - - return extra_stats; -} -#endif /* (NET_TC_TX_COUNT == 1) || (NET_TC_RX_COUNT == 1) */ - -#else /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL || - CONFIG_NET_PKT_RXTIME_STATS_DETAIL */ - -#if defined(CONFIG_NET_PKT_TXTIME_STATS) || \ - defined(CONFIG_NET_PKT_RXTIME_STATS) - -#if (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) -static char *get_net_pkt_tc_stats_detail(struct net_if *iface, int i, - bool is_tx) -{ - ARG_UNUSED(iface); - ARG_UNUSED(i); - ARG_UNUSED(is_tx); - - return "\0"; -} -#endif - -#if (NET_TC_TX_COUNT == 1) || (NET_TC_RX_COUNT == 1) -static char *get_net_pkt_stats_detail(struct net_if *iface, bool is_tx) -{ - ARG_UNUSED(iface); - ARG_UNUSED(is_tx); - - return "\0"; -} -#endif -#endif /* CONFIG_NET_PKT_TXTIME_STATS) || CONFIG_NET_PKT_RXTIME_STATS */ -#endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL || - CONFIG_NET_PKT_RXTIME_STATS_DETAIL */ - -static void print_tc_tx_stats(const struct shell *sh, struct net_if *iface) -{ -#if NET_TC_TX_COUNT > 1 - int i; - - PR("TX traffic class statistics:\n"); - -#if defined(CONFIG_NET_PKT_TXTIME_STATS) - PR("TC Priority\tSent pkts\tbytes\ttime\n"); - - for (i = 0; i < NET_TC_TX_COUNT; i++) { - net_stats_t count = GET_STAT(iface, - tc.sent[i].tx_time.count); - if (count == 0) { - PR("[%d] %s (%d)\t%d\t\t%d\t-\n", i, - priority2str(GET_STAT(iface, tc.sent[i].priority)), - GET_STAT(iface, tc.sent[i].priority), - GET_STAT(iface, tc.sent[i].pkts), - GET_STAT(iface, tc.sent[i].bytes)); - } else { - PR("[%d] %s (%d)\t%d\t\t%d\t%u us%s\n", i, - priority2str(GET_STAT(iface, tc.sent[i].priority)), - GET_STAT(iface, tc.sent[i].priority), - GET_STAT(iface, tc.sent[i].pkts), - GET_STAT(iface, tc.sent[i].bytes), - (uint32_t)(GET_STAT(iface, - tc.sent[i].tx_time.sum) / - (uint64_t)count), - get_net_pkt_tc_stats_detail(iface, i, true)); - } - } -#else - PR("TC Priority\tSent pkts\tbytes\n"); - - for (i = 0; i < NET_TC_TX_COUNT; i++) { - PR("[%d] %s (%d)\t%d\t\t%d\n", i, - priority2str(GET_STAT(iface, tc.sent[i].priority)), - GET_STAT(iface, tc.sent[i].priority), - GET_STAT(iface, tc.sent[i].pkts), - GET_STAT(iface, tc.sent[i].bytes)); - } -#endif /* CONFIG_NET_PKT_TXTIME_STATS */ -#else - ARG_UNUSED(sh); - -#if defined(CONFIG_NET_PKT_TXTIME_STATS) - net_stats_t count = GET_STAT(iface, tx_time.count); - - if (count != 0) { - PR("Avg %s net_pkt (%u) time %lu us%s\n", "TX", count, - (uint32_t)(GET_STAT(iface, tx_time.sum) / (uint64_t)count), - get_net_pkt_stats_detail(iface, true)); - } -#else - ARG_UNUSED(iface); -#endif /* CONFIG_NET_PKT_TXTIME_STATS */ -#endif /* NET_TC_TX_COUNT > 1 */ -} - -static void print_tc_rx_stats(const struct shell *sh, struct net_if *iface) -{ -#if NET_TC_RX_COUNT > 1 - int i; - - PR("RX traffic class statistics:\n"); - -#if defined(CONFIG_NET_PKT_RXTIME_STATS) - PR("TC Priority\tRecv pkts\tbytes\ttime\n"); - - for (i = 0; i < NET_TC_RX_COUNT; i++) { - net_stats_t count = GET_STAT(iface, - tc.recv[i].rx_time.count); - if (count == 0) { - PR("[%d] %s (%d)\t%d\t\t%d\t-\n", i, - priority2str(GET_STAT(iface, tc.recv[i].priority)), - GET_STAT(iface, tc.recv[i].priority), - GET_STAT(iface, tc.recv[i].pkts), - GET_STAT(iface, tc.recv[i].bytes)); - } else { - PR("[%d] %s (%d)\t%d\t\t%d\t%u us%s\n", i, - priority2str(GET_STAT(iface, tc.recv[i].priority)), - GET_STAT(iface, tc.recv[i].priority), - GET_STAT(iface, tc.recv[i].pkts), - GET_STAT(iface, tc.recv[i].bytes), - (uint32_t)(GET_STAT(iface, - tc.recv[i].rx_time.sum) / - (uint64_t)count), - get_net_pkt_tc_stats_detail(iface, i, false)); - } - } -#else - PR("TC Priority\tRecv pkts\tbytes\n"); - - for (i = 0; i < NET_TC_RX_COUNT; i++) { - PR("[%d] %s (%d)\t%d\t\t%d\n", i, - priority2str(GET_STAT(iface, tc.recv[i].priority)), - GET_STAT(iface, tc.recv[i].priority), - GET_STAT(iface, tc.recv[i].pkts), - GET_STAT(iface, tc.recv[i].bytes)); - } -#endif /* CONFIG_NET_PKT_RXTIME_STATS */ -#else - ARG_UNUSED(sh); - -#if defined(CONFIG_NET_PKT_RXTIME_STATS) - net_stats_t count = GET_STAT(iface, rx_time.count); - - if (count != 0) { - PR("Avg %s net_pkt (%u) time %lu us%s\n", "RX", count, - (uint32_t)(GET_STAT(iface, rx_time.sum) / (uint64_t)count), - get_net_pkt_stats_detail(iface, false)); - } -#else - ARG_UNUSED(iface); -#endif /* CONFIG_NET_PKT_RXTIME_STATS */ - -#endif /* NET_TC_RX_COUNT > 1 */ -} - -static void print_net_pm_stats(const struct shell *sh, struct net_if *iface) -{ -#if defined(CONFIG_NET_STATISTICS_POWER_MANAGEMENT) - PR("PM suspend stats:\n"); - PR("\tLast time : %u ms\n", - GET_STAT(iface, pm.last_suspend_time)); - PR("\tAverage time : %u ms\n", - (uint32_t)(GET_STAT(iface, pm.overall_suspend_time) / - GET_STAT(iface, pm.suspend_count))); - PR("\tTotal time : %" PRIu64 " ms\n", - GET_STAT(iface, pm.overall_suspend_time)); - PR("\tHow many times: %u\n", - GET_STAT(iface, pm.suspend_count)); -#else - ARG_UNUSED(sh); - ARG_UNUSED(iface); -#endif -} - -static void net_shell_print_statistics(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - - if (iface) { - const char *extra; - - PR("\nInterface %p (%s) [%d]\n", iface, - iface2str(iface, &extra), net_if_get_by_iface(iface)); - PR("===========================%s\n", extra); - } else { - PR("\nGlobal statistics\n"); - PR("=================\n"); - } - -#if defined(CONFIG_NET_STATISTICS_IPV6) && defined(CONFIG_NET_NATIVE_IPV6) - PR("IPv6 recv %d\tsent\t%d\tdrop\t%d\tforwarded\t%d\n", - GET_STAT(iface, ipv6.recv), - GET_STAT(iface, ipv6.sent), - GET_STAT(iface, ipv6.drop), - GET_STAT(iface, ipv6.forwarded)); -#if defined(CONFIG_NET_STATISTICS_IPV6_ND) - PR("IPv6 ND recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, ipv6_nd.recv), - GET_STAT(iface, ipv6_nd.sent), - GET_STAT(iface, ipv6_nd.drop)); -#endif /* CONFIG_NET_STATISTICS_IPV6_ND */ -#if defined(CONFIG_NET_STATISTICS_MLD) - PR("IPv6 MLD recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, ipv6_mld.recv), - GET_STAT(iface, ipv6_mld.sent), - GET_STAT(iface, ipv6_mld.drop)); -#endif /* CONFIG_NET_STATISTICS_MLD */ -#endif /* CONFIG_NET_STATISTICS_IPV6 */ - -#if defined(CONFIG_NET_STATISTICS_IPV4) && defined(CONFIG_NET_NATIVE_IPV4) - PR("IPv4 recv %d\tsent\t%d\tdrop\t%d\tforwarded\t%d\n", - GET_STAT(iface, ipv4.recv), - GET_STAT(iface, ipv4.sent), - GET_STAT(iface, ipv4.drop), - GET_STAT(iface, ipv4.forwarded)); -#endif /* CONFIG_NET_STATISTICS_IPV4 */ - - PR("IP vhlerr %d\thblener\t%d\tlblener\t%d\n", - GET_STAT(iface, ip_errors.vhlerr), - GET_STAT(iface, ip_errors.hblenerr), - GET_STAT(iface, ip_errors.lblenerr)); - PR("IP fragerr %d\tchkerr\t%d\tprotoer\t%d\n", - GET_STAT(iface, ip_errors.fragerr), - GET_STAT(iface, ip_errors.chkerr), - GET_STAT(iface, ip_errors.protoerr)); - -#if defined(CONFIG_NET_STATISTICS_ICMP) && defined(CONFIG_NET_NATIVE_IPV4) - PR("ICMP recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, icmp.recv), - GET_STAT(iface, icmp.sent), - GET_STAT(iface, icmp.drop)); - PR("ICMP typeer %d\tchkerr\t%d\n", - GET_STAT(iface, icmp.typeerr), - GET_STAT(iface, icmp.chkerr)); -#endif -#if defined(CONFIG_NET_STATISTICS_IGMP) - PR("IGMP recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, ipv4_igmp.recv), - GET_STAT(iface, ipv4_igmp.sent), - GET_STAT(iface, ipv4_igmp.drop)); -#endif /* CONFIG_NET_STATISTICS_IGMP */ -#if defined(CONFIG_NET_STATISTICS_UDP) && defined(CONFIG_NET_NATIVE_UDP) - PR("UDP recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, udp.recv), - GET_STAT(iface, udp.sent), - GET_STAT(iface, udp.drop)); - PR("UDP chkerr %d\n", - GET_STAT(iface, udp.chkerr)); -#endif - -#if defined(CONFIG_NET_STATISTICS_TCP) && defined(CONFIG_NET_NATIVE_TCP) - PR("TCP bytes recv %u\tsent\t%d\tresent\t%d\n", - GET_STAT(iface, tcp.bytes.received), - GET_STAT(iface, tcp.bytes.sent), - GET_STAT(iface, tcp.resent)); - PR("TCP seg recv %d\tsent\t%d\tdrop\t%d\n", - GET_STAT(iface, tcp.recv), - GET_STAT(iface, tcp.sent), - GET_STAT(iface, tcp.seg_drop)); - PR("TCP seg resent %d\tchkerr\t%d\tackerr\t%d\n", - GET_STAT(iface, tcp.rexmit), - GET_STAT(iface, tcp.chkerr), - GET_STAT(iface, tcp.ackerr)); - PR("TCP seg rsterr %d\trst\t%d\n", - GET_STAT(iface, tcp.rsterr), - GET_STAT(iface, tcp.rst)); - PR("TCP conn drop %d\tconnrst\t%d\n", - GET_STAT(iface, tcp.conndrop), - GET_STAT(iface, tcp.connrst)); - PR("TCP pkt drop %d\n", GET_STAT(iface, tcp.drop)); -#endif - - PR("Bytes received %u\n", GET_STAT(iface, bytes.received)); - PR("Bytes sent %u\n", GET_STAT(iface, bytes.sent)); - PR("Processing err %d\n", GET_STAT(iface, processing_error)); - - print_tc_tx_stats(sh, iface); - print_tc_rx_stats(sh, iface); - -#if defined(CONFIG_NET_STATISTICS_ETHERNET) && \ - defined(CONFIG_NET_STATISTICS_USER_API) - if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { - struct net_stats_eth eth_data; - int ret; - - ret = net_mgmt(NET_REQUEST_STATS_GET_ETHERNET, iface, - ð_data, sizeof(eth_data)); - if (!ret) { - print_eth_stats(iface, ð_data, sh); - } - } -#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */ - -#if defined(CONFIG_NET_STATISTICS_PPP) && \ - defined(CONFIG_NET_STATISTICS_USER_API) - if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) { - struct net_stats_ppp ppp_data; - int ret; - - ret = net_mgmt(NET_REQUEST_STATS_GET_PPP, iface, - &ppp_data, sizeof(ppp_data)); - if (!ret) { - print_ppp_stats(iface, &ppp_data, sh); - } - } -#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */ - - print_net_pm_stats(sh, iface); -} -#endif /* CONFIG_NET_STATISTICS */ - -#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) -static void net_shell_print_statistics_all(struct net_shell_user_data *data) -{ - net_if_foreach(net_shell_print_statistics, data); -} -#endif - -static int cmd_net_stats_all(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_STATISTICS) - struct net_shell_user_data user_data; -#endif - -#if defined(CONFIG_NET_STATISTICS) - user_data.sh = sh; - - /* Print global network statistics */ - net_shell_print_statistics_all(&user_data); -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", - "statistics"); -#endif - - return 0; -} - -static int cmd_net_stats_iface(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_STATISTICS) -#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) - struct net_shell_user_data data; - struct net_if *iface; - char *endptr; - int idx; -#endif -#endif - -#if defined(CONFIG_NET_STATISTICS) -#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) - if (argv[1] == NULL) { - PR_WARNING("Network interface index missing!\n"); - return -ENOEXEC; - } - - idx = strtol(argv[1], &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid index %s\n", argv[1]); - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - data.sh = sh; - - net_shell_print_statistics(iface, &data); -#else - PR_INFO("Per network interface statistics not collected.\n"); - PR_INFO("Please enable CONFIG_NET_STATISTICS_PER_INTERFACE\n"); -#endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */ -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", - "statistics"); -#endif - - return 0; -} - -static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_STATISTICS) - if (!argv[1]) { - cmd_net_stats_all(sh, argc, argv); - return 0; - } - - if (strcmp(argv[1], "reset") == 0) { - net_stats_reset(NULL); - } else { - cmd_net_stats_iface(sh, argc, argv); - } -#else - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", - "statistics"); -#endif - - return 0; -} - #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) static struct net_context *tcp_ctx; static const struct shell *tcp_shell; @@ -1953,27 +1323,6 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -#if defined(CONFIG_NET_STATISTICS) && \ - defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ - defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -#define STATS_IFACE_CMD &iface_index -#else -#define STATS_IFACE_CMD NULL -#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_STATISTICS_PER_INTERFACE && - * CONFIG_NET_SHELL_DYN_CMD_COMPLETION - */ - -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_stats, - SHELL_CMD(all, NULL, - "Show network statistics for all network interfaces.", - cmd_net_stats_all), - SHELL_CMD(iface, STATS_IFACE_CMD, - "'net stats ' shows network statistics for " - "one specific network interface.", - cmd_net_stats_iface), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_tcp, SHELL_CMD(connect, NULL, "'net tcp connect
' connects to TCP peer.", @@ -2016,8 +1365,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(stats, &net_cmd_stats, "Show network statistics.", - cmd_net_stats), SHELL_CMD(suspend, NULL, "Suspend a network interface", cmd_net_suspend), SHELL_CMD(tcp, &net_cmd_tcp, "Connect/send/close TCP connection.", diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c new file mode 100644 index 00000000000..ad5671cde63 --- /dev/null +++ b/subsys/net/lib/shell/stats.c @@ -0,0 +1,709 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#include "../ip/net_stats.h" + +#if defined(CONFIG_NET_STATISTICS) + +#if NET_TC_COUNT > 1 +static const char *priority2str(enum net_priority priority) +{ + switch (priority) { + case NET_PRIORITY_BK: + return "BK"; /* Background */ + case NET_PRIORITY_BE: + return "BE"; /* Best effort */ + case NET_PRIORITY_EE: + return "EE"; /* Excellent effort */ + case NET_PRIORITY_CA: + return "CA"; /* Critical applications */ + case NET_PRIORITY_VI: + return "VI"; /* Video, < 100 ms latency and jitter */ + case NET_PRIORITY_VO: + return "VO"; /* Voice, < 10 ms latency and jitter */ + case NET_PRIORITY_IC: + return "IC"; /* Internetwork control */ + case NET_PRIORITY_NC: + return "NC"; /* Network control */ + } + + return "??"; +} +#endif + +#if defined(CONFIG_NET_STATISTICS_ETHERNET) && \ + defined(CONFIG_NET_STATISTICS_USER_API) +static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data, + const struct shell *sh) +{ + PR("Statistics for Ethernet interface %p [%d]\n", iface, + net_if_get_by_iface(iface)); + + PR("Bytes received : %u\n", data->bytes.received); + PR("Bytes sent : %u\n", data->bytes.sent); + PR("Packets received : %u\n", data->pkts.rx); + PR("Packets sent : %u\n", data->pkts.tx); + PR("Bcast received : %u\n", data->broadcast.rx); + PR("Bcast sent : %u\n", data->broadcast.tx); + PR("Mcast received : %u\n", data->multicast.rx); + PR("Mcast sent : %u\n", data->multicast.tx); + + PR("Send errors : %u\n", data->errors.tx); + PR("Receive errors : %u\n", data->errors.rx); + PR("Collisions : %u\n", data->collisions); + PR("Send Drops : %u\n", data->tx_dropped); + PR("Send timeouts : %u\n", data->tx_timeout_count); + PR("Send restarts : %u\n", data->tx_restart_queue); + PR("Unknown protocol : %u\n", data->unknown_protocol); + +#if defined(CONFIG_NET_STATISTICS_ETHERNET_VENDOR) + if (data->vendor) { + PR("Vendor specific statistics for Ethernet " + "interface %p [%d]:\n", + iface, net_if_get_by_iface(iface)); + size_t i = 0; + + do { + PR("%s : %u\n", data->vendor[i].key, + data->vendor[i].value); + i++; + } while (data->vendor[i].key); + } +#endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */ +} +#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */ + +#if defined(CONFIG_NET_STATISTICS_PPP) && \ + defined(CONFIG_NET_STATISTICS_USER_API) +static void print_ppp_stats(struct net_if *iface, struct net_stats_ppp *data, + const struct shell *sh) +{ + PR("Frames recv %u\n", data->pkts.rx); + PR("Frames sent %u\n", data->pkts.tx); + PR("Frames dropped %u\n", data->drop); + PR("Bad FCS %u\n", data->chkerr); +} +#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */ + +#if !defined(CONFIG_NET_NATIVE) +#define GET_STAT(a, b) 0 +#endif + +#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \ + defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) +#if (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) +static char *get_net_pkt_tc_stats_detail(struct net_if *iface, int i, + bool is_tx) +{ + static char extra_stats[sizeof("\t[0=xxxx us]") + + sizeof("->xxxx") * + NET_PKT_DETAIL_STATS_COUNT]; + int j, total = 0, pos = 0; + + pos += snprintk(extra_stats, sizeof(extra_stats), "\t[0"); + + for (j = 0; j < NET_PKT_DETAIL_STATS_COUNT; j++) { + net_stats_t count = 0; + uint32_t avg; + + if (is_tx) { +#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) && (NET_TC_TX_COUNT > 1) + count = GET_STAT(iface, + tc.sent[i].tx_time_detail[j].count); +#endif + } else { +#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) && (NET_TC_RX_COUNT > 1) + count = GET_STAT(iface, + tc.recv[i].rx_time_detail[j].count); +#endif + } + + if (count == 0) { + break; + } + + if (is_tx) { +#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) && (NET_TC_TX_COUNT > 1) + avg = (uint32_t)(GET_STAT(iface, + tc.sent[i].tx_time_detail[j].sum) / + (uint64_t)count); +#endif + } else { +#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) && (NET_TC_RX_COUNT > 1) + avg = (uint32_t)(GET_STAT(iface, + tc.recv[i].rx_time_detail[j].sum) / + (uint64_t)count); +#endif + } + + if (avg == 0) { + continue; + } + + total += avg; + + pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, + "->%u", avg); + } + + if (total == 0U) { + return "\0"; + } + + pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, + "=%u us]", total); + + return extra_stats; +} +#endif /* (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) */ + +#if (NET_TC_TX_COUNT <= 1) || (NET_TC_RX_COUNT <= 1) +static char *get_net_pkt_stats_detail(struct net_if *iface, bool is_tx) +{ + static char extra_stats[sizeof("\t[0=xxxx us]") + sizeof("->xxxx") * + NET_PKT_DETAIL_STATS_COUNT]; + int j, total = 0, pos = 0; + + pos += snprintk(extra_stats, sizeof(extra_stats), "\t[0"); + + for (j = 0; j < NET_PKT_DETAIL_STATS_COUNT; j++) { + net_stats_t count; + uint32_t avg; + + if (is_tx) { +#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) + count = GET_STAT(iface, tx_time_detail[j].count); +#endif + } else { +#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) + count = GET_STAT(iface, rx_time_detail[j].count); +#endif + } + + if (count == 0) { + break; + } + + if (is_tx) { +#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) + avg = (uint32_t)(GET_STAT(iface, + tx_time_detail[j].sum) / + (uint64_t)count); +#endif + } else { +#if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) + avg = (uint32_t)(GET_STAT(iface, + rx_time_detail[j].sum) / + (uint64_t)count); +#endif + } + + if (avg == 0) { + continue; + } + + total += avg; + + pos += snprintk(extra_stats + pos, + sizeof(extra_stats) - pos, + "->%u", avg); + } + + if (total == 0U) { + return "\0"; + } + + pos += snprintk(extra_stats + pos, sizeof(extra_stats) - pos, + "=%u us]", total); + + return extra_stats; +} +#endif /* (NET_TC_TX_COUNT == 1) || (NET_TC_RX_COUNT == 1) */ + +#else /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL || CONFIG_NET_PKT_RXTIME_STATS_DETAIL */ + +#if defined(CONFIG_NET_PKT_TXTIME_STATS) || \ + defined(CONFIG_NET_PKT_RXTIME_STATS) + +#if (NET_TC_TX_COUNT > 1) || (NET_TC_RX_COUNT > 1) +static char *get_net_pkt_tc_stats_detail(struct net_if *iface, int i, + bool is_tx) +{ + ARG_UNUSED(iface); + ARG_UNUSED(i); + ARG_UNUSED(is_tx); + + return "\0"; +} +#endif + +#if (NET_TC_TX_COUNT == 1) || (NET_TC_RX_COUNT == 1) +static char *get_net_pkt_stats_detail(struct net_if *iface, bool is_tx) +{ + ARG_UNUSED(iface); + ARG_UNUSED(is_tx); + + return "\0"; +} +#endif +#endif /* CONFIG_NET_PKT_TXTIME_STATS) || CONFIG_NET_PKT_RXTIME_STATS */ +#endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL || CONFIG_NET_PKT_RXTIME_STATS_DETAIL */ + +static void print_tc_tx_stats(const struct shell *sh, struct net_if *iface) +{ +#if NET_TC_TX_COUNT > 1 + int i; + + PR("TX traffic class statistics:\n"); + +#if defined(CONFIG_NET_PKT_TXTIME_STATS) + PR("TC Priority\tSent pkts\tbytes\ttime\n"); + + for (i = 0; i < NET_TC_TX_COUNT; i++) { + net_stats_t count = GET_STAT(iface, + tc.sent[i].tx_time.count); + if (count == 0) { + PR("[%d] %s (%d)\t%d\t\t%d\t-\n", i, + priority2str(GET_STAT(iface, tc.sent[i].priority)), + GET_STAT(iface, tc.sent[i].priority), + GET_STAT(iface, tc.sent[i].pkts), + GET_STAT(iface, tc.sent[i].bytes)); + } else { + PR("[%d] %s (%d)\t%d\t\t%d\t%u us%s\n", i, + priority2str(GET_STAT(iface, tc.sent[i].priority)), + GET_STAT(iface, tc.sent[i].priority), + GET_STAT(iface, tc.sent[i].pkts), + GET_STAT(iface, tc.sent[i].bytes), + (uint32_t)(GET_STAT(iface, + tc.sent[i].tx_time.sum) / + (uint64_t)count), + get_net_pkt_tc_stats_detail(iface, i, true)); + } + } +#else + PR("TC Priority\tSent pkts\tbytes\n"); + + for (i = 0; i < NET_TC_TX_COUNT; i++) { + PR("[%d] %s (%d)\t%d\t\t%d\n", i, + priority2str(GET_STAT(iface, tc.sent[i].priority)), + GET_STAT(iface, tc.sent[i].priority), + GET_STAT(iface, tc.sent[i].pkts), + GET_STAT(iface, tc.sent[i].bytes)); + } +#endif /* CONFIG_NET_PKT_TXTIME_STATS */ +#else + ARG_UNUSED(sh); + +#if defined(CONFIG_NET_PKT_TXTIME_STATS) + net_stats_t count = GET_STAT(iface, tx_time.count); + + if (count != 0) { + PR("Avg %s net_pkt (%u) time %" PRIu32 " us%s\n", "TX", count, + (uint32_t)(GET_STAT(iface, tx_time.sum) / (uint64_t)count), + get_net_pkt_stats_detail(iface, true)); + } +#else + ARG_UNUSED(iface); +#endif /* CONFIG_NET_PKT_TXTIME_STATS */ +#endif /* NET_TC_TX_COUNT > 1 */ +} + +static void print_tc_rx_stats(const struct shell *sh, struct net_if *iface) +{ +#if NET_TC_RX_COUNT > 1 + int i; + + PR("RX traffic class statistics:\n"); + +#if defined(CONFIG_NET_PKT_RXTIME_STATS) + PR("TC Priority\tRecv pkts\tbytes\ttime\n"); + + for (i = 0; i < NET_TC_RX_COUNT; i++) { + net_stats_t count = GET_STAT(iface, + tc.recv[i].rx_time.count); + if (count == 0) { + PR("[%d] %s (%d)\t%d\t\t%d\t-\n", i, + priority2str(GET_STAT(iface, tc.recv[i].priority)), + GET_STAT(iface, tc.recv[i].priority), + GET_STAT(iface, tc.recv[i].pkts), + GET_STAT(iface, tc.recv[i].bytes)); + } else { + PR("[%d] %s (%d)\t%d\t\t%d\t%u us%s\n", i, + priority2str(GET_STAT(iface, tc.recv[i].priority)), + GET_STAT(iface, tc.recv[i].priority), + GET_STAT(iface, tc.recv[i].pkts), + GET_STAT(iface, tc.recv[i].bytes), + (uint32_t)(GET_STAT(iface, + tc.recv[i].rx_time.sum) / + (uint64_t)count), + get_net_pkt_tc_stats_detail(iface, i, false)); + } + } +#else + PR("TC Priority\tRecv pkts\tbytes\n"); + + for (i = 0; i < NET_TC_RX_COUNT; i++) { + PR("[%d] %s (%d)\t%d\t\t%d\n", i, + priority2str(GET_STAT(iface, tc.recv[i].priority)), + GET_STAT(iface, tc.recv[i].priority), + GET_STAT(iface, tc.recv[i].pkts), + GET_STAT(iface, tc.recv[i].bytes)); + } +#endif /* CONFIG_NET_PKT_RXTIME_STATS */ +#else + ARG_UNUSED(sh); + +#if defined(CONFIG_NET_PKT_RXTIME_STATS) + net_stats_t count = GET_STAT(iface, rx_time.count); + + if (count != 0) { + PR("Avg %s net_pkt (%u) time %" PRIu32 " us%s\n", "RX", count, + (uint32_t)(GET_STAT(iface, rx_time.sum) / (uint64_t)count), + get_net_pkt_stats_detail(iface, false)); + } +#else + ARG_UNUSED(iface); +#endif /* CONFIG_NET_PKT_RXTIME_STATS */ + +#endif /* NET_TC_RX_COUNT > 1 */ +} + +static void print_net_pm_stats(const struct shell *sh, struct net_if *iface) +{ +#if defined(CONFIG_NET_STATISTICS_POWER_MANAGEMENT) + PR("PM suspend stats:\n"); + PR("\tLast time : %u ms\n", + GET_STAT(iface, pm.last_suspend_time)); + PR("\tAverage time : %u ms\n", + (uint32_t)(GET_STAT(iface, pm.overall_suspend_time) / + GET_STAT(iface, pm.suspend_count))); + PR("\tTotal time : %" PRIu64 " ms\n", + GET_STAT(iface, pm.overall_suspend_time)); + PR("\tHow many times: %u\n", + GET_STAT(iface, pm.suspend_count)); +#else + ARG_UNUSED(sh); + ARG_UNUSED(iface); +#endif +} + +static void net_shell_print_statistics(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + + if (iface) { + const char *extra; + + PR("\nInterface %p (%s) [%d]\n", iface, + iface2str(iface, &extra), net_if_get_by_iface(iface)); + PR("===========================%s\n", extra); + } else { + PR("\nGlobal statistics\n"); + PR("=================\n"); + } + +#if defined(CONFIG_NET_STATISTICS_IPV6) && defined(CONFIG_NET_NATIVE_IPV6) + PR("IPv6 recv %d\tsent\t%d\tdrop\t%d\tforwarded\t%d\n", + GET_STAT(iface, ipv6.recv), + GET_STAT(iface, ipv6.sent), + GET_STAT(iface, ipv6.drop), + GET_STAT(iface, ipv6.forwarded)); +#if defined(CONFIG_NET_STATISTICS_IPV6_ND) + PR("IPv6 ND recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, ipv6_nd.recv), + GET_STAT(iface, ipv6_nd.sent), + GET_STAT(iface, ipv6_nd.drop)); +#endif /* CONFIG_NET_STATISTICS_IPV6_ND */ +#if defined(CONFIG_NET_STATISTICS_MLD) + PR("IPv6 MLD recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, ipv6_mld.recv), + GET_STAT(iface, ipv6_mld.sent), + GET_STAT(iface, ipv6_mld.drop)); +#endif /* CONFIG_NET_STATISTICS_MLD */ +#endif /* CONFIG_NET_STATISTICS_IPV6 */ + +#if defined(CONFIG_NET_STATISTICS_IPV4) && defined(CONFIG_NET_NATIVE_IPV4) + PR("IPv4 recv %d\tsent\t%d\tdrop\t%d\tforwarded\t%d\n", + GET_STAT(iface, ipv4.recv), + GET_STAT(iface, ipv4.sent), + GET_STAT(iface, ipv4.drop), + GET_STAT(iface, ipv4.forwarded)); +#endif /* CONFIG_NET_STATISTICS_IPV4 */ + + PR("IP vhlerr %d\thblener\t%d\tlblener\t%d\n", + GET_STAT(iface, ip_errors.vhlerr), + GET_STAT(iface, ip_errors.hblenerr), + GET_STAT(iface, ip_errors.lblenerr)); + PR("IP fragerr %d\tchkerr\t%d\tprotoer\t%d\n", + GET_STAT(iface, ip_errors.fragerr), + GET_STAT(iface, ip_errors.chkerr), + GET_STAT(iface, ip_errors.protoerr)); + +#if defined(CONFIG_NET_STATISTICS_ICMP) && defined(CONFIG_NET_NATIVE_IPV4) + PR("ICMP recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, icmp.recv), + GET_STAT(iface, icmp.sent), + GET_STAT(iface, icmp.drop)); + PR("ICMP typeer %d\tchkerr\t%d\n", + GET_STAT(iface, icmp.typeerr), + GET_STAT(iface, icmp.chkerr)); +#endif +#if defined(CONFIG_NET_STATISTICS_IGMP) + PR("IGMP recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, ipv4_igmp.recv), + GET_STAT(iface, ipv4_igmp.sent), + GET_STAT(iface, ipv4_igmp.drop)); +#endif /* CONFIG_NET_STATISTICS_IGMP */ +#if defined(CONFIG_NET_STATISTICS_UDP) && defined(CONFIG_NET_NATIVE_UDP) + PR("UDP recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, udp.recv), + GET_STAT(iface, udp.sent), + GET_STAT(iface, udp.drop)); + PR("UDP chkerr %d\n", + GET_STAT(iface, udp.chkerr)); +#endif + +#if defined(CONFIG_NET_STATISTICS_TCP) && defined(CONFIG_NET_NATIVE_TCP) + PR("TCP bytes recv %u\tsent\t%d\tresent\t%d\n", + GET_STAT(iface, tcp.bytes.received), + GET_STAT(iface, tcp.bytes.sent), + GET_STAT(iface, tcp.resent)); + PR("TCP seg recv %d\tsent\t%d\tdrop\t%d\n", + GET_STAT(iface, tcp.recv), + GET_STAT(iface, tcp.sent), + GET_STAT(iface, tcp.seg_drop)); + PR("TCP seg resent %d\tchkerr\t%d\tackerr\t%d\n", + GET_STAT(iface, tcp.rexmit), + GET_STAT(iface, tcp.chkerr), + GET_STAT(iface, tcp.ackerr)); + PR("TCP seg rsterr %d\trst\t%d\n", + GET_STAT(iface, tcp.rsterr), + GET_STAT(iface, tcp.rst)); + PR("TCP conn drop %d\tconnrst\t%d\n", + GET_STAT(iface, tcp.conndrop), + GET_STAT(iface, tcp.connrst)); + PR("TCP pkt drop %d\n", GET_STAT(iface, tcp.drop)); +#endif + + PR("Bytes received %u\n", GET_STAT(iface, bytes.received)); + PR("Bytes sent %u\n", GET_STAT(iface, bytes.sent)); + PR("Processing err %d\n", GET_STAT(iface, processing_error)); + + print_tc_tx_stats(sh, iface); + print_tc_rx_stats(sh, iface); + +#if defined(CONFIG_NET_STATISTICS_ETHERNET) && \ + defined(CONFIG_NET_STATISTICS_USER_API) + if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + struct net_stats_eth eth_data; + int ret; + + ret = net_mgmt(NET_REQUEST_STATS_GET_ETHERNET, iface, + ð_data, sizeof(eth_data)); + if (!ret) { + print_eth_stats(iface, ð_data, sh); + } + } +#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */ + +#if defined(CONFIG_NET_STATISTICS_PPP) && \ + defined(CONFIG_NET_STATISTICS_USER_API) + if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) { + struct net_stats_ppp ppp_data; + int ret; + + ret = net_mgmt(NET_REQUEST_STATS_GET_PPP, iface, + &ppp_data, sizeof(ppp_data)); + if (!ret) { + print_ppp_stats(iface, &ppp_data, sh); + } + } +#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */ + + print_net_pm_stats(sh, iface); +} +#endif /* CONFIG_NET_STATISTICS */ + +#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) +static void net_shell_print_statistics_all(struct net_shell_user_data *data) +{ + net_if_foreach(net_shell_print_statistics, data); +} +#endif + +int cmd_net_stats_all(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_STATISTICS) + struct net_shell_user_data user_data; +#endif + +#if defined(CONFIG_NET_STATISTICS) + user_data.sh = sh; + + /* Print global network statistics */ + net_shell_print_statistics_all(&user_data); +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", + "statistics"); +#endif + + return 0; +} + +int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_STATISTICS) +#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) + struct net_shell_user_data data; + struct net_if *iface; + char *endptr; + int idx; +#endif +#endif + +#if defined(CONFIG_NET_STATISTICS) +#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) + if (argv[1] == NULL) { + PR_WARNING("Network interface index missing!\n"); + return -ENOEXEC; + } + + idx = strtol(argv[1], &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid index %s\n", argv[1]); + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + data.sh = sh; + + net_shell_print_statistics(iface, &data); +#else + PR_INFO("Per network interface statistics not collected.\n"); + PR_INFO("Please enable CONFIG_NET_STATISTICS_PER_INTERFACE\n"); +#endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */ +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", + "statistics"); +#endif + + return 0; +} + +static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_STATISTICS) + if (!argv[1]) { + cmd_net_stats_all(sh, argc, argv); + return 0; + } + + if (strcmp(argv[1], "reset") == 0) { + net_stats_reset(NULL); + } else { + cmd_net_stats_iface(sh, argc, argv); + } +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS", + "statistics"); +#endif + + return 0; +} + +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) + +static char iface_stats_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; +static char iface_stats_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; + +static void iface_stats_index_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(iface_stats_index, iface_stats_index_get); + +static char *set_iface_stats_index_buffer(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + if (!iface) { + return NULL; + } + + snprintk(iface_stats_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); + + return iface_stats_index_buffer[idx]; +} + +static char *set_iface_stats_index_help(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + if (!iface) { + return NULL; + } + + snprintk(iface_stats_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "%s (%p)", iface2str(iface, NULL), iface); + + return iface_stats_help_buffer[idx]; +} + +static void iface_stats_index_get(size_t idx, struct shell_static_entry *entry) +{ + entry->handler = NULL; + entry->help = set_iface_stats_index_help(idx); + entry->subcmd = &iface_stats_index; + entry->syntax = set_iface_stats_index_buffer(idx); +} + +#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + +#if defined(CONFIG_NET_STATISTICS) && \ + defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ + defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) +#define STATS_IFACE_CMD &iface_stats_index +#else +#define STATS_IFACE_CMD NULL +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_STATISTICS_PER_INTERFACE && + * CONFIG_NET_SHELL_DYN_CMD_COMPLETION + */ + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_stats, + SHELL_CMD(all, NULL, + "Show network statistics for all network interfaces.", + cmd_net_stats_all), + SHELL_CMD(iface, STATS_IFACE_CMD, + "'net stats ' shows network statistics for " + "one specific network interface.", + cmd_net_stats_iface), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), stats, &net_cmd_stats, + "Show network statistics.", + cmd_net_stats, 1, 1); From 7cdc235ff53a358681c2279d020717909432993c Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 15:18:36 +0300 Subject: [PATCH 2378/4498] net: shell: Add suspend command Move "suspend" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 45 ---------------------- subsys/net/lib/shell/suspend.c | 58 +++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 45 deletions(-) create mode 100644 subsys/net/lib/shell/suspend.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 17b15e4bec4..64184a73bad 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -25,6 +25,7 @@ zephyr_library_sources(resume.c) zephyr_library_sources(route.c) zephyr_library_sources(stacks.c) zephyr_library_sources(stats.c) +zephyr_library_sources(suspend.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 2d325aa85a2..332e64bdd40 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -1214,49 +1214,6 @@ static int cmd_net_vlan_del(const struct shell *sh, size_t argc, return 0; } -static int cmd_net_suspend(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_POWER_MANAGEMENT) - if (argv[1]) { - struct net_if *iface = NULL; - const struct device *dev; - int idx; - int ret; - - idx = get_iface_idx(sh, argv[1]); - if (idx < 0) { - return -ENOEXEC; - } - - iface = net_if_get_by_index(idx); - if (!iface) { - PR_WARNING("No such interface in index %d\n", idx); - return -ENOEXEC; - } - - dev = net_if_get_device(iface); - - ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); - if (ret != 0) { - PR_INFO("Iface could not be suspended: "); - - if (ret == -EBUSY) { - PR_INFO("device is busy\n"); - } else if (ret == -EALREADY) { - PR_INFO("dehive is already suspended\n"); - } - } - } else { - PR("Usage:\n"); - PR("\tsuspend \n"); - } -#else - PR_INFO("You need a network driver supporting Power Management.\n"); -#endif /* CONFIG_NET_POWER_MANAGEMENT */ - - return 0; -} #if defined(CONFIG_WEBSOCKET_CLIENT) static void websocket_context_cb(struct websocket_context *context, @@ -1365,8 +1322,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(suspend, NULL, "Suspend a network interface", - cmd_net_suspend), SHELL_CMD(tcp, &net_cmd_tcp, "Connect/send/close TCP connection.", cmd_net_tcp), SHELL_CMD(udp, &net_cmd_udp, "Send/recv UDP packet", cmd_net_udp), diff --git a/subsys/net/lib/shell/suspend.c b/subsys/net/lib/shell/suspend.c new file mode 100644 index 00000000000..fc4ae28eefb --- /dev/null +++ b/subsys/net/lib/shell/suspend.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" + +static int cmd_net_suspend(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_POWER_MANAGEMENT) + if (argv[1]) { + struct net_if *iface = NULL; + const struct device *dev; + int idx; + int ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + dev = net_if_get_device(iface); + + ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + if (ret != 0) { + PR_INFO("Iface could not be suspended: "); + + if (ret == -EBUSY) { + PR_INFO("device is busy\n"); + } else if (ret == -EALREADY) { + PR_INFO("dehive is already suspended\n"); + } + } + } else { + PR("Usage:\n"); + PR("\tsuspend \n"); + } +#else + PR_INFO("You need a network driver supporting Power Management.\n"); +#endif /* CONFIG_NET_POWER_MANAGEMENT */ + + return 0; +} + +SHELL_SUBCMD_ADD((net), suspend, NULL, + "Suspend a network interface", + cmd_net_suspend, 1, 0); From 5afeade2fc9c02db832a1acb409a85ab6f94bd9d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 15:25:33 +0300 Subject: [PATCH 2379/4498] net: shell: Add tcp command Move "tcp" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 403 --------------------------- subsys/net/lib/shell/tcp.c | 414 ++++++++++++++++++++++++++++ 3 files changed, 415 insertions(+), 403 deletions(-) create mode 100644 subsys/net/lib/shell/tcp.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 64184a73bad..87f61363023 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources(route.c) zephyr_library_sources(stacks.c) zephyr_library_sources(stats.c) zephyr_library_sources(suspend.c) +zephyr_library_sources(tcp.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 332e64bdd40..65dff9c05f2 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -251,392 +251,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) -static struct net_context *tcp_ctx; -static const struct shell *tcp_shell; - -#define TCP_CONNECT_TIMEOUT K_SECONDS(5) /* ms */ -#define TCP_TIMEOUT K_SECONDS(2) /* ms */ - -static void tcp_connected(struct net_context *context, - int status, - void *user_data) -{ - if (status < 0) { - PR_SHELL(tcp_shell, "TCP connection failed (%d)\n", status); - - net_context_put(context); - - tcp_ctx = NULL; - } else { - PR_SHELL(tcp_shell, "TCP connected\n"); - } -} - -static void get_my_ipv6_addr(struct net_if *iface, - struct sockaddr *myaddr) -{ -#if defined(CONFIG_NET_IPV6) - const struct in6_addr *my6addr; - - my6addr = net_if_ipv6_select_src_addr(iface, - &net_sin6(myaddr)->sin6_addr); - - memcpy(&net_sin6(myaddr)->sin6_addr, my6addr, sizeof(struct in6_addr)); - - net_sin6(myaddr)->sin6_port = 0U; /* let the IP stack to select */ -#endif -} - -static void get_my_ipv4_addr(struct net_if *iface, - struct sockaddr *myaddr) -{ -#if defined(CONFIG_NET_NATIVE_IPV4) - /* Just take the first IPv4 address of an interface. */ - memcpy(&net_sin(myaddr)->sin_addr, - &iface->config.ip.ipv4->unicast[0].address.in_addr, - sizeof(struct in_addr)); - - net_sin(myaddr)->sin_port = 0U; /* let the IP stack to select */ -#endif -} - -static void print_connect_info(const struct shell *sh, - int family, - struct sockaddr *myaddr, - struct sockaddr *addr) -{ - switch (family) { - case AF_INET: - if (IS_ENABLED(CONFIG_NET_IPV4)) { - PR("Connecting from %s:%u ", - net_sprint_ipv4_addr(&net_sin(myaddr)->sin_addr), - ntohs(net_sin(myaddr)->sin_port)); - PR("to %s:%u\n", - net_sprint_ipv4_addr(&net_sin(addr)->sin_addr), - ntohs(net_sin(addr)->sin_port)); - } else { - PR_INFO("IPv4 not supported\n"); - } - - break; - - case AF_INET6: - if (IS_ENABLED(CONFIG_NET_IPV6)) { - PR("Connecting from [%s]:%u ", - net_sprint_ipv6_addr(&net_sin6(myaddr)->sin6_addr), - ntohs(net_sin6(myaddr)->sin6_port)); - PR("to [%s]:%u\n", - net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), - ntohs(net_sin6(addr)->sin6_port)); - } else { - PR_INFO("IPv6 not supported\n"); - } - - break; - - default: - PR_WARNING("Unknown protocol family (%d)\n", family); - break; - } -} - -static void tcp_connect(const struct shell *sh, char *host, uint16_t port, - struct net_context **ctx) -{ - struct net_if *iface = net_if_get_default(); - struct sockaddr myaddr; - struct sockaddr addr; - struct net_nbr *nbr; - int addrlen; - int family; - int ret; - - if (IS_ENABLED(CONFIG_NET_IPV6) && !IS_ENABLED(CONFIG_NET_IPV4)) { - ret = net_addr_pton(AF_INET6, host, - &net_sin6(&addr)->sin6_addr); - if (ret < 0) { - PR_WARNING("Invalid IPv6 address\n"); - return; - } - - net_sin6(&addr)->sin6_port = htons(port); - addrlen = sizeof(struct sockaddr_in6); - - nbr = net_ipv6_nbr_lookup(NULL, &net_sin6(&addr)->sin6_addr); - if (nbr) { - iface = nbr->iface; - } - - get_my_ipv6_addr(iface, &myaddr); - family = addr.sa_family = myaddr.sa_family = AF_INET6; - - } else if (IS_ENABLED(CONFIG_NET_IPV4) && - !IS_ENABLED(CONFIG_NET_IPV6)) { - ARG_UNUSED(nbr); - - ret = net_addr_pton(AF_INET, host, &net_sin(&addr)->sin_addr); - if (ret < 0) { - PR_WARNING("Invalid IPv4 address\n"); - return; - } - - get_my_ipv4_addr(iface, &myaddr); - net_sin(&addr)->sin_port = htons(port); - addrlen = sizeof(struct sockaddr_in); - family = addr.sa_family = myaddr.sa_family = AF_INET; - } else if (IS_ENABLED(CONFIG_NET_IPV6) && - IS_ENABLED(CONFIG_NET_IPV4)) { - ret = net_addr_pton(AF_INET6, host, - &net_sin6(&addr)->sin6_addr); - if (ret < 0) { - ret = net_addr_pton(AF_INET, host, - &net_sin(&addr)->sin_addr); - if (ret < 0) { - PR_WARNING("Invalid IP address\n"); - return; - } - - net_sin(&addr)->sin_port = htons(port); - addrlen = sizeof(struct sockaddr_in); - - get_my_ipv4_addr(iface, &myaddr); - family = addr.sa_family = myaddr.sa_family = AF_INET; - } else { - net_sin6(&addr)->sin6_port = htons(port); - addrlen = sizeof(struct sockaddr_in6); - - nbr = net_ipv6_nbr_lookup(NULL, - &net_sin6(&addr)->sin6_addr); - if (nbr) { - iface = nbr->iface; - } - - get_my_ipv6_addr(iface, &myaddr); - family = addr.sa_family = myaddr.sa_family = AF_INET6; - } - } else { - PR_WARNING("No IPv6 nor IPv4 is enabled\n"); - return; - } - - print_connect_info(sh, family, &myaddr, &addr); - - ret = net_context_get(family, SOCK_STREAM, IPPROTO_TCP, ctx); - if (ret < 0) { - PR_WARNING("Cannot get TCP context (%d)\n", ret); - return; - } - - ret = net_context_bind(*ctx, &myaddr, addrlen); - if (ret < 0) { - PR_WARNING("Cannot bind TCP (%d)\n", ret); - return; - } - - /* Note that we cannot put shell as a user_data when connecting - * because the tcp_connected() will be called much later and - * all local stack variables are lost at that point. - */ - tcp_shell = sh; - -#if defined(CONFIG_NET_SOCKETS_CONNECT_TIMEOUT) -#define CONNECT_TIMEOUT K_MSEC(CONFIG_NET_SOCKETS_CONNECT_TIMEOUT) -#else -#define CONNECT_TIMEOUT K_SECONDS(3) -#endif - - net_context_connect(*ctx, &addr, addrlen, tcp_connected, - CONNECT_TIMEOUT, NULL); -} - -static void tcp_sent_cb(struct net_context *context, - int status, void *user_data) -{ - PR_SHELL(tcp_shell, "Message sent\n"); -} - -static void tcp_recv_cb(struct net_context *context, struct net_pkt *pkt, - union net_ip_header *ip_hdr, - union net_proto_header *proto_hdr, - int status, void *user_data) -{ - int ret, len; - - if (pkt == NULL) { - if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { - return; - } - - ret = net_context_put(tcp_ctx); - if (ret < 0) { - PR_SHELL(tcp_shell, - "Cannot close the connection (%d)\n", ret); - return; - } - - PR_SHELL(tcp_shell, "Connection closed by remote peer.\n"); - tcp_ctx = NULL; - - return; - } - - len = net_pkt_remaining_data(pkt); - - (void)net_context_update_recv_wnd(context, len); - - PR_SHELL(tcp_shell, "%zu bytes received\n", net_pkt_get_len(pkt)); - - net_pkt_unref(pkt); -} -#endif - -static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int arg = 0; - - /* tcp connect port */ - char *endptr; - char *ip; - uint16_t port; - - /* tcp connect port */ - if (tcp_ctx && net_context_is_used(tcp_ctx)) { - PR("Already connected\n"); - return -ENOEXEC; - } - - if (!argv[++arg]) { - PR_WARNING("Peer IP address missing.\n"); - return -ENOEXEC; - } - - ip = argv[arg]; - - if (!argv[++arg]) { - PR_WARNING("Peer port missing.\n"); - return -ENOEXEC; - } - - port = strtol(argv[arg], &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid port %s\n", argv[arg]); - return -ENOEXEC; - } - - tcp_connect(sh, ip, port, &tcp_ctx); -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); -#endif /* CONFIG_NET_NATIVE_TCP */ - - return 0; -} - -static int cmd_net_tcp_send(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int arg = 0; - int ret; - struct net_shell_user_data user_data; - - /* tcp send */ - if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { - PR_WARNING("Not connected\n"); - return -ENOEXEC; - } - - if (!argv[++arg]) { - PR_WARNING("No data to send.\n"); - return -ENOEXEC; - } - - user_data.sh = sh; - - ret = net_context_send(tcp_ctx, (uint8_t *)argv[arg], - strlen(argv[arg]), tcp_sent_cb, - TCP_TIMEOUT, &user_data); - if (ret < 0) { - PR_WARNING("Cannot send msg (%d)\n", ret); - return -ENOEXEC; - } - -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); -#endif /* CONFIG_NET_NATIVE_TCP */ - - return 0; -} - -static int cmd_net_tcp_recv(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int ret; - struct net_shell_user_data user_data; - - /* tcp recv */ - if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { - PR_WARNING("Not connected\n"); - return -ENOEXEC; - } - - user_data.sh = sh; - - ret = net_context_recv(tcp_ctx, tcp_recv_cb, K_NO_WAIT, &user_data); - if (ret < 0) { - PR_WARNING("Cannot recv data (%d)\n", ret); - return -ENOEXEC; - } - -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); -#endif /* CONFIG_NET_NATIVE_TCP */ - - return 0; -} - -static int cmd_net_tcp_close(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int ret; - - /* tcp close */ - if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { - PR_WARNING("Not connected\n"); - return -ENOEXEC; - } - - ret = net_context_put(tcp_ctx); - if (ret < 0) { - PR_WARNING("Cannot close the connection (%d)\n", ret); - return -ENOEXEC; - } - - PR("Connection closed.\n"); - tcp_ctx = NULL; -#else - PR_INFO("Set %s to enable %s support.\n", - "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); -#endif /* CONFIG_NET_TCP */ - - return 0; -} - -static int cmd_net_tcp(const struct shell *sh, size_t argc, char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return 0; -} - #if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_NATIVE_UDP) static struct net_context *udp_ctx; static const struct shell *udp_shell; @@ -1280,21 +894,6 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_tcp, - SHELL_CMD(connect, NULL, - "'net tcp connect
' connects to TCP peer.", - cmd_net_tcp_connect), - SHELL_CMD(send, NULL, - "'net tcp send ' sends data to peer using TCP.", - cmd_net_tcp_send), - SHELL_CMD(recv, NULL, - "'net tcp recv' receives data using TCP.", - cmd_net_tcp_recv), - SHELL_CMD(close, NULL, - "'net tcp close' closes TCP connection.", cmd_net_tcp_close), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_CMD(add, NULL, "'net vlan add ' adds VLAN tag to the " @@ -1322,8 +921,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, ); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(tcp, &net_cmd_tcp, "Connect/send/close TCP connection.", - cmd_net_tcp), SHELL_CMD(udp, &net_cmd_udp, "Send/recv UDP packet", cmd_net_udp), SHELL_CMD(virtual, NULL, "Show virtual network interfaces.", cmd_net_virtual), diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c new file mode 100644 index 00000000000..c8e8f24454e --- /dev/null +++ b/subsys/net/lib/shell/tcp.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) +static struct net_context *tcp_ctx; +static const struct shell *tcp_shell; + +#define TCP_CONNECT_TIMEOUT K_SECONDS(5) /* ms */ +#define TCP_TIMEOUT K_SECONDS(2) /* ms */ + +static void tcp_connected(struct net_context *context, + int status, + void *user_data) +{ + if (status < 0) { + PR_SHELL(tcp_shell, "TCP connection failed (%d)\n", status); + + net_context_put(context); + + tcp_ctx = NULL; + } else { + PR_SHELL(tcp_shell, "TCP connected\n"); + } +} + +static void get_my_ipv6_addr(struct net_if *iface, + struct sockaddr *myaddr) +{ +#if defined(CONFIG_NET_IPV6) + const struct in6_addr *my6addr; + + my6addr = net_if_ipv6_select_src_addr(iface, + &net_sin6(myaddr)->sin6_addr); + + memcpy(&net_sin6(myaddr)->sin6_addr, my6addr, sizeof(struct in6_addr)); + + net_sin6(myaddr)->sin6_port = 0U; /* let the IP stack to select */ +#endif +} + +static void get_my_ipv4_addr(struct net_if *iface, + struct sockaddr *myaddr) +{ +#if defined(CONFIG_NET_NATIVE_IPV4) + /* Just take the first IPv4 address of an interface. */ + memcpy(&net_sin(myaddr)->sin_addr, + &iface->config.ip.ipv4->unicast[0].address.in_addr, + sizeof(struct in_addr)); + + net_sin(myaddr)->sin_port = 0U; /* let the IP stack to select */ +#endif +} + +static void print_connect_info(const struct shell *sh, + int family, + struct sockaddr *myaddr, + struct sockaddr *addr) +{ + switch (family) { + case AF_INET: + if (IS_ENABLED(CONFIG_NET_IPV4)) { + PR("Connecting from %s:%u ", + net_sprint_ipv4_addr(&net_sin(myaddr)->sin_addr), + ntohs(net_sin(myaddr)->sin_port)); + PR("to %s:%u\n", + net_sprint_ipv4_addr(&net_sin(addr)->sin_addr), + ntohs(net_sin(addr)->sin_port)); + } else { + PR_INFO("IPv4 not supported\n"); + } + + break; + + case AF_INET6: + if (IS_ENABLED(CONFIG_NET_IPV6)) { + PR("Connecting from [%s]:%u ", + net_sprint_ipv6_addr(&net_sin6(myaddr)->sin6_addr), + ntohs(net_sin6(myaddr)->sin6_port)); + PR("to [%s]:%u\n", + net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), + ntohs(net_sin6(addr)->sin6_port)); + } else { + PR_INFO("IPv6 not supported\n"); + } + + break; + + default: + PR_WARNING("Unknown protocol family (%d)\n", family); + break; + } +} + +static void tcp_connect(const struct shell *sh, char *host, uint16_t port, + struct net_context **ctx) +{ + struct net_if *iface = net_if_get_default(); + struct sockaddr myaddr; + struct sockaddr addr; + struct net_nbr *nbr; + int addrlen; + int family; + int ret; + + if (IS_ENABLED(CONFIG_NET_IPV6) && !IS_ENABLED(CONFIG_NET_IPV4)) { + ret = net_addr_pton(AF_INET6, host, + &net_sin6(&addr)->sin6_addr); + if (ret < 0) { + PR_WARNING("Invalid IPv6 address\n"); + return; + } + + net_sin6(&addr)->sin6_port = htons(port); + addrlen = sizeof(struct sockaddr_in6); + + nbr = net_ipv6_nbr_lookup(NULL, &net_sin6(&addr)->sin6_addr); + if (nbr) { + iface = nbr->iface; + } + + get_my_ipv6_addr(iface, &myaddr); + family = addr.sa_family = myaddr.sa_family = AF_INET6; + + } else if (IS_ENABLED(CONFIG_NET_IPV4) && + !IS_ENABLED(CONFIG_NET_IPV6)) { + ARG_UNUSED(nbr); + + ret = net_addr_pton(AF_INET, host, &net_sin(&addr)->sin_addr); + if (ret < 0) { + PR_WARNING("Invalid IPv4 address\n"); + return; + } + + get_my_ipv4_addr(iface, &myaddr); + net_sin(&addr)->sin_port = htons(port); + addrlen = sizeof(struct sockaddr_in); + family = addr.sa_family = myaddr.sa_family = AF_INET; + } else if (IS_ENABLED(CONFIG_NET_IPV6) && + IS_ENABLED(CONFIG_NET_IPV4)) { + ret = net_addr_pton(AF_INET6, host, + &net_sin6(&addr)->sin6_addr); + if (ret < 0) { + ret = net_addr_pton(AF_INET, host, + &net_sin(&addr)->sin_addr); + if (ret < 0) { + PR_WARNING("Invalid IP address\n"); + return; + } + + net_sin(&addr)->sin_port = htons(port); + addrlen = sizeof(struct sockaddr_in); + + get_my_ipv4_addr(iface, &myaddr); + family = addr.sa_family = myaddr.sa_family = AF_INET; + } else { + net_sin6(&addr)->sin6_port = htons(port); + addrlen = sizeof(struct sockaddr_in6); + + nbr = net_ipv6_nbr_lookup(NULL, + &net_sin6(&addr)->sin6_addr); + if (nbr) { + iface = nbr->iface; + } + + get_my_ipv6_addr(iface, &myaddr); + family = addr.sa_family = myaddr.sa_family = AF_INET6; + } + } else { + PR_WARNING("No IPv6 nor IPv4 is enabled\n"); + return; + } + + print_connect_info(sh, family, &myaddr, &addr); + + ret = net_context_get(family, SOCK_STREAM, IPPROTO_TCP, ctx); + if (ret < 0) { + PR_WARNING("Cannot get TCP context (%d)\n", ret); + return; + } + + ret = net_context_bind(*ctx, &myaddr, addrlen); + if (ret < 0) { + PR_WARNING("Cannot bind TCP (%d)\n", ret); + return; + } + + /* Note that we cannot put shell as a user_data when connecting + * because the tcp_connected() will be called much later and + * all local stack variables are lost at that point. + */ + tcp_shell = sh; + +#if defined(CONFIG_NET_SOCKETS_CONNECT_TIMEOUT) +#define CONNECT_TIMEOUT K_MSEC(CONFIG_NET_SOCKETS_CONNECT_TIMEOUT) +#else +#define CONNECT_TIMEOUT K_SECONDS(3) +#endif + + net_context_connect(*ctx, &addr, addrlen, tcp_connected, + CONNECT_TIMEOUT, NULL); +} + +static void tcp_sent_cb(struct net_context *context, + int status, void *user_data) +{ + PR_SHELL(tcp_shell, "Message sent\n"); +} + +static void tcp_recv_cb(struct net_context *context, struct net_pkt *pkt, + union net_ip_header *ip_hdr, + union net_proto_header *proto_hdr, + int status, void *user_data) +{ + int ret, len; + + if (pkt == NULL) { + if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { + return; + } + + ret = net_context_put(tcp_ctx); + if (ret < 0) { + PR_SHELL(tcp_shell, + "Cannot close the connection (%d)\n", ret); + return; + } + + PR_SHELL(tcp_shell, "Connection closed by remote peer.\n"); + tcp_ctx = NULL; + + return; + } + + len = net_pkt_remaining_data(pkt); + + (void)net_context_update_recv_wnd(context, len); + + PR_SHELL(tcp_shell, "%zu bytes received\n", net_pkt_get_len(pkt)); + + net_pkt_unref(pkt); +} +#endif + +static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) + int arg = 0; + + /* tcp connect port */ + char *endptr; + char *ip; + uint16_t port; + + /* tcp connect port */ + if (tcp_ctx && net_context_is_used(tcp_ctx)) { + PR("Already connected\n"); + return -ENOEXEC; + } + + if (!argv[++arg]) { + PR_WARNING("Peer IP address missing.\n"); + return -ENOEXEC; + } + + ip = argv[arg]; + + if (!argv[++arg]) { + PR_WARNING("Peer port missing.\n"); + return -ENOEXEC; + } + + port = strtol(argv[arg], &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid port %s\n", argv[arg]); + return -ENOEXEC; + } + + tcp_connect(sh, ip, port, &tcp_ctx); +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); +#endif /* CONFIG_NET_NATIVE_TCP */ + + return 0; +} + +static int cmd_net_tcp_send(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) + int arg = 0; + int ret; + struct net_shell_user_data user_data; + + /* tcp send */ + if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { + PR_WARNING("Not connected\n"); + return -ENOEXEC; + } + + if (!argv[++arg]) { + PR_WARNING("No data to send.\n"); + return -ENOEXEC; + } + + user_data.sh = sh; + + ret = net_context_send(tcp_ctx, (uint8_t *)argv[arg], + strlen(argv[arg]), tcp_sent_cb, + TCP_TIMEOUT, &user_data); + if (ret < 0) { + PR_WARNING("Cannot send msg (%d)\n", ret); + return -ENOEXEC; + } + +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); +#endif /* CONFIG_NET_NATIVE_TCP */ + + return 0; +} + +static int cmd_net_tcp_recv(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) + int ret; + struct net_shell_user_data user_data; + + /* tcp recv */ + if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { + PR_WARNING("Not connected\n"); + return -ENOEXEC; + } + + user_data.sh = sh; + + ret = net_context_recv(tcp_ctx, tcp_recv_cb, K_NO_WAIT, &user_data); + if (ret < 0) { + PR_WARNING("Cannot recv data (%d)\n", ret); + return -ENOEXEC; + } + +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); +#endif /* CONFIG_NET_NATIVE_TCP */ + + return 0; +} + +static int cmd_net_tcp_close(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) + int ret; + + /* tcp close */ + if (!tcp_ctx || !net_context_is_used(tcp_ctx)) { + PR_WARNING("Not connected\n"); + return -ENOEXEC; + } + + ret = net_context_put(tcp_ctx); + if (ret < 0) { + PR_WARNING("Cannot close the connection (%d)\n", ret); + return -ENOEXEC; + } + + PR("Connection closed.\n"); + tcp_ctx = NULL; +#else + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_TCP and CONFIG_NET_NATIVE", "TCP"); +#endif /* CONFIG_NET_TCP */ + + return 0; +} + +static int cmd_net_tcp(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_tcp, + SHELL_CMD(connect, NULL, + "'net tcp connect
' connects to TCP peer.", + cmd_net_tcp_connect), + SHELL_CMD(send, NULL, + "'net tcp send ' sends data to peer using TCP.", + cmd_net_tcp_send), + SHELL_CMD(recv, NULL, + "'net tcp recv' receives data using TCP.", + cmd_net_tcp_recv), + SHELL_CMD(close, NULL, + "'net tcp close' closes TCP connection.", cmd_net_tcp_close), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), tcp, &net_cmd_tcp, + "Connect/send/close TCP connection.", + cmd_net_tcp, 1, 0); From 7a167648eb47926cfedb944d715f2b79a5df7620 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 15:30:05 +0300 Subject: [PATCH 2380/4498] net: shell: Add udp command Move "udp" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 294 -------------------------- subsys/net/lib/shell/udp.c | 308 ++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+), 294 deletions(-) create mode 100644 subsys/net/lib/shell/udp.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 87f61363023..335c2588b28 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -27,6 +27,7 @@ zephyr_library_sources(stacks.c) zephyr_library_sources(stats.c) zephyr_library_sources(suspend.c) zephyr_library_sources(tcp.c) +zephyr_library_sources(udp.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 65dff9c05f2..030d0487ed6 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -251,286 +251,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_NATIVE_UDP) -static struct net_context *udp_ctx; -static const struct shell *udp_shell; -K_SEM_DEFINE(udp_send_wait, 0, 1); - -static void udp_rcvd(struct net_context *context, struct net_pkt *pkt, - union net_ip_header *ip_hdr, - union net_proto_header *proto_hdr, int status, - void *user_data) -{ - if (pkt) { - size_t len = net_pkt_remaining_data(pkt); - uint8_t byte; - - PR_SHELL(udp_shell, "Received UDP packet: "); - for (size_t i = 0; i < len; ++i) { - net_pkt_read_u8(pkt, &byte); - PR_SHELL(udp_shell, "%02x ", byte); - } - PR_SHELL(udp_shell, "\n"); - - net_pkt_unref(pkt); - } -} - -static void udp_sent(struct net_context *context, int status, void *user_data) -{ - ARG_UNUSED(context); - ARG_UNUSED(status); - ARG_UNUSED(user_data); - - PR_SHELL(udp_shell, "Message sent\n"); - k_sem_give(&udp_send_wait); -} -#endif - -static int cmd_net_udp_bind(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) - ARG_UNUSED(sh); - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return -EOPNOTSUPP; -#else - char *addr_str = NULL; - char *endptr = NULL; - uint16_t port; - int ret; - - struct net_if *iface; - struct sockaddr addr; - int addrlen; - - if (argc < 3) { - PR_WARNING("Not enough arguments given for udp bind command\n"); - return -EINVAL; - } - - addr_str = argv[1]; - port = strtol(argv[2], &endptr, 0); - - if (endptr == argv[2]) { - PR_WARNING("Invalid port number\n"); - return -EINVAL; - } - - if (udp_ctx && net_context_is_used(udp_ctx)) { - PR_WARNING("Network context already in use\n"); - return -EALREADY; - } - - memset(&addr, 0, sizeof(addr)); - - ret = net_ipaddr_parse(addr_str, strlen(addr_str), &addr); - if (ret < 0) { - PR_WARNING("Cannot parse address \"%s\"\n", addr_str); - return ret; - } - - ret = net_context_get(addr.sa_family, SOCK_DGRAM, IPPROTO_UDP, - &udp_ctx); - if (ret < 0) { - PR_WARNING("Cannot get UDP context (%d)\n", ret); - return ret; - } - - udp_shell = sh; - - if (IS_ENABLED(CONFIG_NET_IPV6) && addr.sa_family == AF_INET6) { - net_sin6(&addr)->sin6_port = htons(port); - addrlen = sizeof(struct sockaddr_in6); - - iface = net_if_ipv6_select_src_iface( - &net_sin6(&addr)->sin6_addr); - } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr.sa_family == AF_INET) { - net_sin(&addr)->sin_port = htons(port); - addrlen = sizeof(struct sockaddr_in); - - iface = net_if_ipv4_select_src_iface( - &net_sin(&addr)->sin_addr); - } else { - PR_WARNING("IPv6 and IPv4 are disabled, cannot %s.\n", "bind"); - goto release_ctx; - } - - if (!iface) { - PR_WARNING("No interface to send to given host\n"); - goto release_ctx; - } - - net_context_set_iface(udp_ctx, iface); - - ret = net_context_bind(udp_ctx, &addr, addrlen); - if (ret < 0) { - PR_WARNING("Binding to UDP port failed (%d)\n", ret); - goto release_ctx; - } - - ret = net_context_recv(udp_ctx, udp_rcvd, K_NO_WAIT, NULL); - if (ret < 0) { - PR_WARNING("Receiving from UDP port failed (%d)\n", ret); - goto release_ctx; - } - - return 0; - -release_ctx: - ret = net_context_put(udp_ctx); - if (ret < 0) { - PR_WARNING("Cannot put UDP context (%d)\n", ret); - } - - return 0; -#endif -} - -static int cmd_net_udp_close(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) - ARG_UNUSED(sh); - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return -EOPNOTSUPP; -#else - int ret; - - if (!udp_ctx || !net_context_is_used(udp_ctx)) { - PR_WARNING("Network context is not used. Cannot close.\n"); - return -EINVAL; - } - - ret = net_context_put(udp_ctx); - if (ret < 0) { - PR_WARNING("Cannot close UDP port (%d)\n", ret); - } - - return 0; -#endif -} - -static int cmd_net_udp_send(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) - ARG_UNUSED(sh); - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return -EOPNOTSUPP; -#else - char *host = NULL; - char *endptr = NULL; - uint16_t port; - uint8_t *payload = NULL; - int ret; - - struct net_if *iface; - struct sockaddr addr; - int addrlen; - - if (argc < 4) { - PR_WARNING("Not enough arguments given for udp send command\n"); - return -EINVAL; - } - - host = argv[1]; - port = strtol(argv[2], &endptr, 0); - payload = argv[3]; - - if (endptr == argv[2]) { - PR_WARNING("Invalid port number\n"); - return -EINVAL; - } - - if (udp_ctx && net_context_is_used(udp_ctx)) { - PR_WARNING("Network context already in use\n"); - return -EALREADY; - } - - memset(&addr, 0, sizeof(addr)); - ret = net_ipaddr_parse(host, strlen(host), &addr); - if (ret < 0) { - PR_WARNING("Cannot parse address \"%s\"\n", host); - return ret; - } - - ret = net_context_get(addr.sa_family, SOCK_DGRAM, IPPROTO_UDP, - &udp_ctx); - if (ret < 0) { - PR_WARNING("Cannot get UDP context (%d)\n", ret); - return ret; - } - - udp_shell = sh; - - if (IS_ENABLED(CONFIG_NET_IPV6) && addr.sa_family == AF_INET6) { - net_sin6(&addr)->sin6_port = htons(port); - addrlen = sizeof(struct sockaddr_in6); - - iface = net_if_ipv6_select_src_iface( - &net_sin6(&addr)->sin6_addr); - } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr.sa_family == AF_INET) { - net_sin(&addr)->sin_port = htons(port); - addrlen = sizeof(struct sockaddr_in); - - iface = net_if_ipv4_select_src_iface( - &net_sin(&addr)->sin_addr); - } else { - PR_WARNING("IPv6 and IPv4 are disabled, cannot %s.\n", "send"); - goto release_ctx; - } - - if (!iface) { - PR_WARNING("No interface to send to given host\n"); - goto release_ctx; - } - - net_context_set_iface(udp_ctx, iface); - - ret = net_context_recv(udp_ctx, udp_rcvd, K_NO_WAIT, NULL); - if (ret < 0) { - PR_WARNING("Setting rcv callback failed (%d)\n", ret); - goto release_ctx; - } - - ret = net_context_sendto(udp_ctx, payload, strlen(payload), &addr, - addrlen, udp_sent, K_FOREVER, NULL); - if (ret < 0) { - PR_WARNING("Sending packet failed (%d)\n", ret); - goto release_ctx; - } - - ret = k_sem_take(&udp_send_wait, K_SECONDS(2)); - if (ret == -EAGAIN) { - PR_WARNING("UDP packet sending failed\n"); - } - -release_ctx: - ret = net_context_put(udp_ctx); - if (ret < 0) { - PR_WARNING("Cannot put UDP context (%d)\n", ret); - } - - return 0; -#endif -} - -static int cmd_net_udp(const struct shell *sh, size_t argc, char *argv[]) -{ - ARG_UNUSED(sh); - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - return 0; -} - #if defined(CONFIG_NET_L2_VIRTUAL) static void virtual_iface_cb(struct net_if *iface, void *user_data) { @@ -906,22 +626,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, - SHELL_CMD(bind, NULL, - "'net udp bind ' binds to UDP local port.", - cmd_net_udp_bind), - SHELL_CMD(close, NULL, - "'net udp close' closes previously bound port.", - cmd_net_udp_close), - SHELL_CMD(send, NULL, - "'net udp send ' " - "sends UDP packet to a network host.", - cmd_net_udp_send), - SHELL_SUBCMD_SET_END -); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(udp, &net_cmd_udp, "Send/recv UDP packet", cmd_net_udp), SHELL_CMD(virtual, NULL, "Show virtual network interfaces.", cmd_net_virtual), SHELL_CMD(vlan, &net_cmd_vlan, "Show VLAN information.", cmd_net_vlan), diff --git a/subsys/net/lib/shell/udp.c b/subsys/net/lib/shell/udp.c new file mode 100644 index 00000000000..9eaf3254514 --- /dev/null +++ b/subsys/net/lib/shell/udp.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include + +#include "common.h" + +#if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_NATIVE_UDP) +static struct net_context *udp_ctx; +static const struct shell *udp_shell; +K_SEM_DEFINE(udp_send_wait, 0, 1); + +static void udp_rcvd(struct net_context *context, struct net_pkt *pkt, + union net_ip_header *ip_hdr, + union net_proto_header *proto_hdr, int status, + void *user_data) +{ + if (pkt) { + size_t len = net_pkt_remaining_data(pkt); + uint8_t byte; + + PR_SHELL(udp_shell, "Received UDP packet: "); + for (size_t i = 0; i < len; ++i) { + net_pkt_read_u8(pkt, &byte); + PR_SHELL(udp_shell, "%02x ", byte); + } + PR_SHELL(udp_shell, "\n"); + + net_pkt_unref(pkt); + } +} + +static void udp_sent(struct net_context *context, int status, void *user_data) +{ + ARG_UNUSED(context); + ARG_UNUSED(status); + ARG_UNUSED(user_data); + + PR_SHELL(udp_shell, "Message sent\n"); + k_sem_give(&udp_send_wait); +} +#endif + +static int cmd_net_udp_bind(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return -EOPNOTSUPP; +#else + char *addr_str = NULL; + char *endptr = NULL; + uint16_t port; + int ret; + + struct net_if *iface; + struct sockaddr addr; + int addrlen; + + if (argc < 3) { + PR_WARNING("Not enough arguments given for udp bind command\n"); + return -EINVAL; + } + + addr_str = argv[1]; + port = strtol(argv[2], &endptr, 0); + + if (endptr == argv[2]) { + PR_WARNING("Invalid port number\n"); + return -EINVAL; + } + + if (udp_ctx && net_context_is_used(udp_ctx)) { + PR_WARNING("Network context already in use\n"); + return -EALREADY; + } + + memset(&addr, 0, sizeof(addr)); + + ret = net_ipaddr_parse(addr_str, strlen(addr_str), &addr); + if (ret < 0) { + PR_WARNING("Cannot parse address \"%s\"\n", addr_str); + return ret; + } + + ret = net_context_get(addr.sa_family, SOCK_DGRAM, IPPROTO_UDP, + &udp_ctx); + if (ret < 0) { + PR_WARNING("Cannot get UDP context (%d)\n", ret); + return ret; + } + + udp_shell = sh; + + if (IS_ENABLED(CONFIG_NET_IPV6) && addr.sa_family == AF_INET6) { + net_sin6(&addr)->sin6_port = htons(port); + addrlen = sizeof(struct sockaddr_in6); + + iface = net_if_ipv6_select_src_iface( + &net_sin6(&addr)->sin6_addr); + } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr.sa_family == AF_INET) { + net_sin(&addr)->sin_port = htons(port); + addrlen = sizeof(struct sockaddr_in); + + iface = net_if_ipv4_select_src_iface( + &net_sin(&addr)->sin_addr); + } else { + PR_WARNING("IPv6 and IPv4 are disabled, cannot %s.\n", "bind"); + goto release_ctx; + } + + if (!iface) { + PR_WARNING("No interface to send to given host\n"); + goto release_ctx; + } + + net_context_set_iface(udp_ctx, iface); + + ret = net_context_bind(udp_ctx, &addr, addrlen); + if (ret < 0) { + PR_WARNING("Binding to UDP port failed (%d)\n", ret); + goto release_ctx; + } + + ret = net_context_recv(udp_ctx, udp_rcvd, K_NO_WAIT, NULL); + if (ret < 0) { + PR_WARNING("Receiving from UDP port failed (%d)\n", ret); + goto release_ctx; + } + + return 0; + +release_ctx: + ret = net_context_put(udp_ctx); + if (ret < 0) { + PR_WARNING("Cannot put UDP context (%d)\n", ret); + } + + return 0; +#endif +} + +static int cmd_net_udp_close(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return -EOPNOTSUPP; +#else + int ret; + + if (!udp_ctx || !net_context_is_used(udp_ctx)) { + PR_WARNING("Network context is not used. Cannot close.\n"); + return -EINVAL; + } + + ret = net_context_put(udp_ctx); + if (ret < 0) { + PR_WARNING("Cannot close UDP port (%d)\n", ret); + } + + return 0; +#endif +} + +static int cmd_net_udp_send(const struct shell *sh, size_t argc, char *argv[]) +{ +#if !defined(CONFIG_NET_UDP) || !defined(CONFIG_NET_NATIVE_UDP) + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return -EOPNOTSUPP; +#else + char *host = NULL; + char *endptr = NULL; + uint16_t port; + uint8_t *payload = NULL; + int ret; + + struct net_if *iface; + struct sockaddr addr; + int addrlen; + + if (argc < 4) { + PR_WARNING("Not enough arguments given for udp send command\n"); + return -EINVAL; + } + + host = argv[1]; + port = strtol(argv[2], &endptr, 0); + payload = argv[3]; + + if (endptr == argv[2]) { + PR_WARNING("Invalid port number\n"); + return -EINVAL; + } + + if (udp_ctx && net_context_is_used(udp_ctx)) { + PR_WARNING("Network context already in use\n"); + return -EALREADY; + } + + memset(&addr, 0, sizeof(addr)); + ret = net_ipaddr_parse(host, strlen(host), &addr); + if (ret < 0) { + PR_WARNING("Cannot parse address \"%s\"\n", host); + return ret; + } + + ret = net_context_get(addr.sa_family, SOCK_DGRAM, IPPROTO_UDP, + &udp_ctx); + if (ret < 0) { + PR_WARNING("Cannot get UDP context (%d)\n", ret); + return ret; + } + + udp_shell = sh; + + if (IS_ENABLED(CONFIG_NET_IPV6) && addr.sa_family == AF_INET6) { + net_sin6(&addr)->sin6_port = htons(port); + addrlen = sizeof(struct sockaddr_in6); + + iface = net_if_ipv6_select_src_iface( + &net_sin6(&addr)->sin6_addr); + } else if (IS_ENABLED(CONFIG_NET_IPV4) && addr.sa_family == AF_INET) { + net_sin(&addr)->sin_port = htons(port); + addrlen = sizeof(struct sockaddr_in); + + iface = net_if_ipv4_select_src_iface( + &net_sin(&addr)->sin_addr); + } else { + PR_WARNING("IPv6 and IPv4 are disabled, cannot %s.\n", "send"); + goto release_ctx; + } + + if (!iface) { + PR_WARNING("No interface to send to given host\n"); + goto release_ctx; + } + + net_context_set_iface(udp_ctx, iface); + + ret = net_context_recv(udp_ctx, udp_rcvd, K_NO_WAIT, NULL); + if (ret < 0) { + PR_WARNING("Setting rcv callback failed (%d)\n", ret); + goto release_ctx; + } + + ret = net_context_sendto(udp_ctx, payload, strlen(payload), &addr, + addrlen, udp_sent, K_FOREVER, NULL); + if (ret < 0) { + PR_WARNING("Sending packet failed (%d)\n", ret); + goto release_ctx; + } + + ret = k_sem_take(&udp_send_wait, K_SECONDS(2)); + if (ret == -EAGAIN) { + PR_WARNING("UDP packet sending failed\n"); + } + +release_ctx: + ret = net_context_put(udp_ctx); + if (ret < 0) { + PR_WARNING("Cannot put UDP context (%d)\n", ret); + } + + return 0; +#endif +} + +static int cmd_net_udp(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(sh); + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_udp, + SHELL_CMD(bind, NULL, + "'net udp bind ' binds to UDP local port.", + cmd_net_udp_bind), + SHELL_CMD(close, NULL, + "'net udp close' closes previously bound port.", + cmd_net_udp_close), + SHELL_CMD(send, NULL, + "'net udp send ' " + "sends UDP packet to a network host.", + cmd_net_udp_send), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), udp, &net_cmd_udp, + "Send/recv UDP packet", + cmd_net_udp, 1, 0); From 82a57b9789966849b220e29fffbd6bacf5eed379 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 15:44:54 +0300 Subject: [PATCH 2381/4498] net: shell: Add virtual command Move "virtual" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 102 ------------------------ subsys/net/lib/shell/virtual.c | 118 ++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 102 deletions(-) create mode 100644 subsys/net/lib/shell/virtual.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 335c2588b28..85c4668b26c 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -28,6 +28,7 @@ zephyr_library_sources(stats.c) zephyr_library_sources(suspend.c) zephyr_library_sources(tcp.c) zephyr_library_sources(udp.c) +zephyr_library_sources(virtual.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 030d0487ed6..2b3d9b3739b 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -38,10 +38,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #endif -#if defined(CONFIG_NET_L2_VIRTUAL) -#include -#endif - #if defined(CONFIG_NET_L2_VIRTUAL_MGMT) #include #endif @@ -251,102 +247,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_L2_VIRTUAL) -static void virtual_iface_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - char *name, buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; - struct net_if *orig_iface; - - if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) { - return; - } - - if (*count == 0) { - PR("Interface Attached-To Description\n"); - (*count)++; - } - - orig_iface = net_virtual_get_iface(iface); - - name = net_virtual_get_name(iface, buf, sizeof(buf)); - - PR("%d %c %s\n", - net_if_get_by_iface(iface), - orig_iface ? net_if_get_by_iface(orig_iface) + '0' : '-', - name); - - (*count)++; -} - -static void attached_iface_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - char buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; - const char *name; - struct virtual_interface_context *ctx, *tmp; - - if (sys_slist_is_empty(&iface->config.virtual_interfaces)) { - return; - } - - if (*count == 0) { - PR("Interface Below-of Description\n"); - (*count)++; - } - - PR("%d ", net_if_get_by_iface(iface)); - - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&iface->config.virtual_interfaces, - ctx, tmp, node) { - if (ctx->virtual_iface == iface) { - continue; - } - - PR("%d ", net_if_get_by_iface(ctx->virtual_iface)); - } - - name = net_virtual_get_name(iface, buf, sizeof(buf)); - if (name == NULL) { - name = iface2str(iface, NULL); - } - - PR(" %s\n", name); - - (*count)++; -} -#endif /* CONFIG_NET_L2_VIRTUAL */ - -static int cmd_net_virtual(const struct shell *sh, size_t argc, - char *argv[]) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - -#if defined(CONFIG_NET_L2_VIRTUAL) - struct net_shell_user_data user_data; - int count = 0; - - user_data.sh = sh; - user_data.user_data = &count; - - net_if_foreach(virtual_iface_cb, &user_data); - - count = 0; - PR("\n"); - - net_if_foreach(attached_iface_cb, &user_data); -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_VIRTUAL", - "virtual network interface"); -#endif - return 0; -} - #if defined(CONFIG_NET_VLAN) static void iface_vlan_del_cb(struct net_if *iface, void *user_data) { @@ -628,8 +528,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(virtual, NULL, "Show virtual network interfaces.", - cmd_net_virtual), SHELL_CMD(vlan, &net_cmd_vlan, "Show VLAN information.", cmd_net_vlan), SHELL_CMD(websocket, NULL, "Print information about WebSocket " "connections.", diff --git a/subsys/net/lib/shell/virtual.c b/subsys/net/lib/shell/virtual.c new file mode 100644 index 00000000000..19c9b1c1b0e --- /dev/null +++ b/subsys/net/lib/shell/virtual.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#if defined(CONFIG_NET_L2_VIRTUAL) +#include +#endif + +#include "common.h" + +#if defined(CONFIG_NET_L2_VIRTUAL) +static void virtual_iface_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char *name, buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; + struct net_if *orig_iface; + + if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) { + return; + } + + if (*count == 0) { + PR("Interface Attached-To Description\n"); + (*count)++; + } + + orig_iface = net_virtual_get_iface(iface); + + name = net_virtual_get_name(iface, buf, sizeof(buf)); + + PR("%d %c %s\n", + net_if_get_by_iface(iface), + orig_iface ? net_if_get_by_iface(orig_iface) + '0' : '-', + name); + + (*count)++; +} + +static void attached_iface_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN]; + const char *name; + struct virtual_interface_context *ctx, *tmp; + + if (sys_slist_is_empty(&iface->config.virtual_interfaces)) { + return; + } + + if (*count == 0) { + PR("Interface Below-of Description\n"); + (*count)++; + } + + PR("%d ", net_if_get_by_iface(iface)); + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&iface->config.virtual_interfaces, + ctx, tmp, node) { + if (ctx->virtual_iface == iface) { + continue; + } + + PR("%d ", net_if_get_by_iface(ctx->virtual_iface)); + } + + name = net_virtual_get_name(iface, buf, sizeof(buf)); + if (name == NULL) { + name = iface2str(iface, NULL); + } + + PR(" %s\n", name); + + (*count)++; +} +#endif /* CONFIG_NET_L2_VIRTUAL */ + +static int cmd_net_virtual(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + +#if defined(CONFIG_NET_L2_VIRTUAL) + struct net_shell_user_data user_data; + int count = 0; + + user_data.sh = sh; + user_data.user_data = &count; + + net_if_foreach(virtual_iface_cb, &user_data); + + if (count == 0) { + PR("No virtual interfaces found."); + } + + count = 0; + PR("\n"); + + net_if_foreach(attached_iface_cb, &user_data); +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_VIRTUAL", + "virtual network interface"); +#endif + return 0; +} + +SHELL_SUBCMD_ADD((net), virtual, NULL, + "Show virtual network interfaces.", + cmd_net_virtual, 1, 0); From d84c2572ec23402a6b4d697c9a2a41ee909687d2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 16:16:14 +0300 Subject: [PATCH 2382/4498] net: shell: Add vlan command Move "vlan" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 218 --------------------------- subsys/net/lib/shell/vlan.c | 225 ++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 218 deletions(-) create mode 100644 subsys/net/lib/shell/vlan.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 85c4668b26c..8bec854805f 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -29,6 +29,7 @@ zephyr_library_sources(suspend.c) zephyr_library_sources(tcp.c) zephyr_library_sources(udp.c) zephyr_library_sources(virtual.c) +zephyr_library_sources(vlan.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 2b3d9b3739b..6e1efc03d3c 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -25,10 +25,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include -#if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_L2_ETHERNET_MGMT) -#include -#include -#endif /* CONFIG_NET_L2_ETHERNET */ #include "common.h" @@ -247,208 +243,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_VLAN) -static void iface_vlan_del_cb(struct net_if *iface, void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - uint16_t vlan_tag = POINTER_TO_UINT(data->user_data); - int ret; - - ret = net_eth_vlan_disable(iface, vlan_tag); - if (ret < 0) { - if (ret != -ESRCH) { - PR_WARNING("Cannot delete VLAN tag %d from " - "interface %d (%p)\n", - vlan_tag, - net_if_get_by_iface(iface), - iface); - } - - return; - } - - PR("VLAN tag %d removed from interface %d (%p)\n", vlan_tag, - net_if_get_by_iface(iface), iface); -} - -static void iface_vlan_cb(struct net_if *iface, void *user_data) -{ - struct ethernet_context *ctx = net_if_l2_data(iface); - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - int *count = data->user_data; - int i; - - if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { - return; - } - - if (*count == 0) { - PR(" Interface Type Tag\n"); - } - - if (!ctx->vlan_enabled) { - PR_WARNING("VLAN tag(s) not set\n"); - return; - } - - for (i = 0; i < NET_VLAN_MAX_COUNT; i++) { - if (!ctx->vlan[i].iface || ctx->vlan[i].iface != iface) { - continue; - } - - if (ctx->vlan[i].tag == NET_VLAN_TAG_UNSPEC) { - continue; - } - - PR("[%d] %p %s %d\n", net_if_get_by_iface(iface), iface, - iface2str(iface, NULL), ctx->vlan[i].tag); - - break; - } - - (*count)++; -} -#endif /* CONFIG_NET_VLAN */ - -static int cmd_net_vlan(const struct shell *sh, size_t argc, char *argv[]) -{ -#if defined(CONFIG_NET_VLAN) - struct net_shell_user_data user_data; - int count; -#endif - -#if defined(CONFIG_NET_VLAN) - count = 0; - - user_data.sh = sh; - user_data.user_data = &count; - - net_if_foreach(iface_vlan_cb, &user_data); -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); -#endif /* CONFIG_NET_VLAN */ - - return 0; -} - -static int cmd_net_vlan_add(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_VLAN) - int arg = 0; - int ret; - uint16_t tag; - struct net_if *iface; - char *endptr; - uint32_t iface_idx; -#endif - -#if defined(CONFIG_NET_VLAN) - /* vlan add */ - if (!argv[++arg]) { - PR_WARNING("VLAN tag missing.\n"); - goto usage; - } - - tag = strtol(argv[arg], &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid tag %s\n", argv[arg]); - return -ENOEXEC; - } - - if (!argv[++arg]) { - PR_WARNING("Network interface index missing.\n"); - goto usage; - } - - iface_idx = strtol(argv[arg], &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid index %s\n", argv[arg]); - goto usage; - } - - iface = net_if_get_by_index(iface_idx); - if (!iface) { - PR_WARNING("Network interface index %d is invalid.\n", - iface_idx); - goto usage; - } - - if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { - PR_WARNING("Network interface %d (%p) is not ethernet interface\n", - net_if_get_by_iface(iface), iface); - return -ENOEXEC; - } - - ret = net_eth_vlan_enable(iface, tag); - if (ret < 0) { - if (ret == -ENOENT) { - PR_WARNING("No IP address configured.\n"); - } - - PR_WARNING("Cannot set VLAN tag (%d)\n", ret); - - return -ENOEXEC; - } - - PR("VLAN tag %d set to interface %d (%p)\n", tag, - net_if_get_by_iface(iface), iface); - - return 0; - -usage: - PR("Usage:\n"); - PR("\tvlan add \n"); -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); -#endif /* CONFIG_NET_VLAN */ - - return 0; -} - -static int cmd_net_vlan_del(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_NET_VLAN) - int arg = 0; - struct net_shell_user_data user_data; - char *endptr; - uint16_t tag; -#endif - -#if defined(CONFIG_NET_VLAN) - /* vlan del */ - if (!argv[++arg]) { - PR_WARNING("VLAN tag missing.\n"); - goto usage; - } - - tag = strtol(argv[arg], &endptr, 10); - if (*endptr != '\0') { - PR_WARNING("Invalid tag %s\n", argv[arg]); - return -ENOEXEC; - } - - user_data.sh = sh; - user_data.user_data = UINT_TO_POINTER((uint32_t)tag); - - net_if_foreach(iface_vlan_del_cb, &user_data); - - return 0; - -usage: - PR("Usage:\n"); - PR("\tvlan del \n"); -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); -#endif /* CONFIG_NET_VLAN */ - - return 0; -} - - #if defined(CONFIG_WEBSOCKET_CLIENT) static void websocket_context_cb(struct websocket_context *context, void *user_data) @@ -514,21 +308,9 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, - SHELL_CMD(add, NULL, - "'net vlan add ' adds VLAN tag to the " - "network interface.", - cmd_net_vlan_add), - SHELL_CMD(del, NULL, - "'net vlan del ' deletes VLAN tag from the network " - "interface.", - cmd_net_vlan_del), - SHELL_SUBCMD_SET_END -); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(vlan, &net_cmd_vlan, "Show VLAN information.", cmd_net_vlan), SHELL_CMD(websocket, NULL, "Print information about WebSocket " "connections.", cmd_net_websocket), diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c new file mode 100644 index 00000000000..44c9016317c --- /dev/null +++ b/subsys/net/lib/shell/vlan.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#if defined(CONFIG_NET_L2_VIRTUAL) +#include +#endif +#include + +#include + +#include "common.h" + +#if defined(CONFIG_NET_VLAN) +static void iface_vlan_del_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + uint16_t vlan_tag = POINTER_TO_UINT(data->user_data); + int ret; + + ret = net_eth_vlan_disable(iface, vlan_tag); + if (ret < 0) { + if (ret != -ESRCH) { + PR_WARNING("Cannot delete VLAN tag %d from " + "interface %d (%p)\n", + vlan_tag, + net_if_get_by_iface(iface), + iface); + } + + return; + } + + PR("VLAN tag %d removed from interface %d (%p)\n", vlan_tag, + net_if_get_by_iface(iface), iface); +} + +static void iface_vlan_cb(struct net_if *iface, void *user_data) +{ + struct ethernet_context *ctx = net_if_l2_data(iface); + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + int i; + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + return; + } + + if (*count == 0) { + PR(" Interface Type Tag\n"); + } + + if (!ctx->vlan_enabled) { + PR_WARNING("VLAN tag(s) not set\n"); + return; + } + + for (i = 0; i < NET_VLAN_MAX_COUNT; i++) { + if (!ctx->vlan[i].iface || ctx->vlan[i].iface != iface) { + continue; + } + + if (ctx->vlan[i].tag == NET_VLAN_TAG_UNSPEC) { + continue; + } + + PR("[%d] %p %s %d\n", net_if_get_by_iface(iface), iface, + iface2str(iface, NULL), ctx->vlan[i].tag); + + break; + } + + (*count)++; +} +#endif /* CONFIG_NET_VLAN */ + +static int cmd_net_vlan(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_VLAN) + struct net_shell_user_data user_data; + int count = 0; + + user_data.sh = sh; + user_data.user_data = &count; + + net_if_foreach(iface_vlan_cb, &user_data); +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); +#endif /* CONFIG_NET_VLAN */ + + return 0; +} + +static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_VLAN) + int arg = 0; + int ret; + uint16_t tag; + struct net_if *iface; + char *endptr; + uint32_t iface_idx; + + /* vlan add */ + if (!argv[++arg]) { + PR_WARNING("VLAN tag missing.\n"); + goto usage; + } + + tag = strtol(argv[arg], &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid tag %s\n", argv[arg]); + return -ENOEXEC; + } + + if (!argv[++arg]) { + PR_WARNING("Network interface index missing.\n"); + goto usage; + } + + iface_idx = strtol(argv[arg], &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid index %s\n", argv[arg]); + goto usage; + } + + iface = net_if_get_by_index(iface_idx); + if (!iface) { + PR_WARNING("Network interface index %d is invalid.\n", + iface_idx); + goto usage; + } + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + PR_WARNING("Network interface %d (%p) is not ethernet interface\n", + net_if_get_by_iface(iface), iface); + return -ENOEXEC; + } + + ret = net_eth_vlan_enable(iface, tag); + if (ret < 0) { + if (ret == -ENOENT) { + PR_WARNING("No IP address configured.\n"); + } + + PR_WARNING("Cannot set VLAN tag (%d)\n", ret); + + return -ENOEXEC; + } + + PR("VLAN tag %d set to interface %d (%p)\n", tag, + net_if_get_by_iface(iface), iface); + + return 0; + +usage: + PR("Usage:\n"); + PR("\tvlan add \n"); +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); +#endif /* CONFIG_NET_VLAN */ + + return 0; +} + +static int cmd_net_vlan_del(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_VLAN) + int arg = 0; + struct net_shell_user_data user_data; + char *endptr; + uint16_t tag; + + /* vlan del */ + if (!argv[++arg]) { + PR_WARNING("VLAN tag missing.\n"); + goto usage; + } + + tag = strtol(argv[arg], &endptr, 10); + if (*endptr != '\0') { + PR_WARNING("Invalid tag %s\n", argv[arg]); + return -ENOEXEC; + } + + user_data.sh = sh; + user_data.user_data = UINT_TO_POINTER((uint32_t)tag); + + net_if_foreach(iface_vlan_del_cb, &user_data); + + return 0; + +usage: + PR("Usage:\n"); + PR("\tvlan del \n"); +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN"); +#endif /* CONFIG_NET_VLAN */ + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, + SHELL_CMD(add, NULL, + "'net vlan add ' adds VLAN tag to the " + "network interface.", + cmd_net_vlan_add), + SHELL_CMD(del, NULL, + "'net vlan del ' deletes VLAN tag from the network " + "interface.", + cmd_net_vlan_del), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), vlan, &net_cmd_vlan, + "Show VLAN information.", + cmd_net_vlan, 1, 0); From aab371364cff2e81655ad8f1d0e18dc3fc2ad61a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 16:52:30 +0300 Subject: [PATCH 2383/4498] net: shell: Add websocket command Move "websocket" command to a separate file. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/net_shell.c | 63 ---------------------- subsys/net/lib/shell/websocket.c | 83 +++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 63 deletions(-) create mode 100644 subsys/net/lib/shell/websocket.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 8bec854805f..54c12e87b87 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -30,6 +30,7 @@ zephyr_library_sources(tcp.c) zephyr_library_sources(udp.c) zephyr_library_sources(virtual.c) zephyr_library_sources(vlan.c) +zephyr_library_sources(websocket.c) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 6e1efc03d3c..55f48faea5f 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -46,7 +46,6 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include "net_shell.h" #include -#include "websocket/websocket_internal.h" int get_iface_idx(const struct shell *sh, char *index_str) { @@ -243,65 +242,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_WEBSOCKET_CLIENT) -static void websocket_context_cb(struct websocket_context *context, - void *user_data) -{ - struct net_shell_user_data *data = user_data; - const struct shell *sh = data->sh; - struct net_context *net_ctx; - int *count = data->user_data; - /* +7 for []:port */ - char addr_local[ADDR_LEN + 7]; - char addr_remote[ADDR_LEN + 7] = ""; - - net_ctx = z_get_fd_obj(context->real_sock, NULL, 0); - if (net_ctx == NULL) { - PR_ERROR("Invalid fd %d", context->real_sock); - return; - } - - get_addresses(net_ctx, addr_local, sizeof(addr_local), - addr_remote, sizeof(addr_remote)); - - PR("[%2d] %p/%p\t%p %16s\t%16s\n", - (*count) + 1, context, net_ctx, - net_context_get_iface(net_ctx), - addr_local, addr_remote); - - (*count)++; -} -#endif /* CONFIG_WEBSOCKET_CLIENT */ - -static int cmd_net_websocket(const struct shell *sh, size_t argc, - char *argv[]) -{ -#if defined(CONFIG_WEBSOCKET_CLIENT) - struct net_shell_user_data user_data; - int count = 0; - - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - PR(" websocket/net_ctx\tIface " - "Local \tRemote\n"); - - user_data.sh = sh; - user_data.user_data = &count; - - websocket_context_foreach(websocket_context_cb, &user_data); - - if (count == 0) { - PR("No connections\n"); - } -#else - PR_INFO("Set %s to enable %s support.\n", "CONFIG_WEBSOCKET_CLIENT", - "Websocket"); -#endif /* CONFIG_WEBSOCKET_CLIENT */ - - return 0; -} - #if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); @@ -311,9 +251,6 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_CMD(websocket, NULL, "Print information about WebSocket " - "connections.", - cmd_net_websocket), SHELL_SUBCMD_SET_END ); diff --git a/subsys/net/lib/shell/websocket.c b/subsys/net/lib/shell/websocket.c new file mode 100644 index 00000000000..f3e77187627 --- /dev/null +++ b/subsys/net/lib/shell/websocket.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#if defined(CONFIG_NET_L2_VIRTUAL) +#include +#endif + +#include "common.h" + +#include "websocket/websocket_internal.h" + +#include + +#if defined(CONFIG_WEBSOCKET_CLIENT) +static void websocket_context_cb(struct websocket_context *context, + void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_context *net_ctx; + int *count = data->user_data; + /* +7 for []:port */ + char addr_local[ADDR_LEN + 7]; + char addr_remote[ADDR_LEN + 7] = ""; + + net_ctx = z_get_fd_obj(context->real_sock, NULL, 0); + if (net_ctx == NULL) { + PR_ERROR("Invalid fd %d", context->real_sock); + return; + } + + if ((*count) == 0) { + PR(" websocket/net_ctx\tIface " + "Local \tRemote\n"); + } + + get_addresses(net_ctx, addr_local, sizeof(addr_local), + addr_remote, sizeof(addr_remote)); + + PR("[%2d] %p/%p\t%p %16s\t%16s\n", + (*count) + 1, context, net_ctx, + net_context_get_iface(net_ctx), + addr_local, addr_remote); + + (*count)++; +} +#endif /* CONFIG_WEBSOCKET_CLIENT */ + +static int cmd_net_websocket(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_WEBSOCKET_CLIENT) + struct net_shell_user_data user_data; + int count = 0; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + user_data.sh = sh; + user_data.user_data = &count; + + websocket_context_foreach(websocket_context_cb, &user_data); + + if (count == 0) { + PR("No connections\n"); + } +#else + PR_INFO("Set %s to enable %s support.\n", "CONFIG_WEBSOCKET_CLIENT", + "Websocket"); +#endif /* CONFIG_WEBSOCKET_CLIENT */ + + return 0; +} + +SHELL_SUBCMD_ADD((net), websocket, NULL, + "Print information about WebSocket connections.", + cmd_net_websocket, 1, 0); From 34cd82e80b12f5a76378b0feb94910ed7cbbff47 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 27 Sep 2023 17:14:11 +0300 Subject: [PATCH 2384/4498] net: shell: Removing extra stuff that is not needed The remaining stuff that is not used in net_shell.c can be removed. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 5 ----- subsys/net/lib/shell/net_shell.c | 34 ----------------------------- 2 files changed, 39 deletions(-) diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 54c12e87b87..461a4b757b4 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -31,8 +31,3 @@ zephyr_library_sources(udp.c) zephyr_library_sources(virtual.c) zephyr_library_sources(vlan.c) zephyr_library_sources(websocket.c) - -zephyr_library_include_directories( - ${ZEPHYR_BASE}/kernel/include - ${ARCH_DIR}/${ARCH}/include - ) diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 55f48faea5f..20f869d356f 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -15,38 +15,12 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include -#include -#include #include #include -#include -#include -#include - -#include -#include #include "common.h" - -#include "connection.h" - -#if defined(CONFIG_NET_L2_ETHERNET_MGMT) -#include -#endif - -#if defined(CONFIG_NET_L2_VIRTUAL_MGMT) -#include -#endif - -#if defined(CONFIG_NET_L2_PPP) -#include -#include "ppp/ppp_internal.h" -#endif - #include "net_shell.h" -#include - int get_iface_idx(const struct shell *sh, char *index_str) { char *endptr; @@ -248,14 +222,6 @@ SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ - - -SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, - SHELL_SUBCMD_SET_END -); - -SHELL_CMD_REGISTER(net_old, &net_commands, "Networking commands", NULL); - /* Placeholder for net commands that are configured in the rest of the .c files */ SHELL_SUBCMD_SET_CREATE(net_cmds, (net)); From 5bad9680a5cd161c26da1dae4b63209589443cb6 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 28 Sep 2023 11:24:43 +0300 Subject: [PATCH 2385/4498] net: shell: Remove the stacks command The "net stacks" has been obsolete for a long time already so remove it for good. It is replaced by "kernel stacks" cmd. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/CMakeLists.txt | 1 - subsys/net/lib/shell/stacks.c | 25 ------------------------- 2 files changed, 26 deletions(-) delete mode 100644 subsys/net/lib/shell/stacks.c diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 461a4b757b4..ddf2b3c93fa 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -23,7 +23,6 @@ zephyr_library_sources(pkt.c) zephyr_library_sources(ppp.c) zephyr_library_sources(resume.c) zephyr_library_sources(route.c) -zephyr_library_sources(stacks.c) zephyr_library_sources(stats.c) zephyr_library_sources(suspend.c) zephyr_library_sources(tcp.c) diff --git a/subsys/net/lib/shell/stacks.c b/subsys/net/lib/shell/stacks.c deleted file mode 100644 index 5bce2b34954..00000000000 --- a/subsys/net/lib/shell/stacks.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_DECLARE(net_shell); - -#include "common.h" - -static int cmd_net_stacks(const struct shell *sh, size_t argc, char *argv[]) -{ -#if !defined(CONFIG_KERNEL_SHELL) - PR("Enable CONFIG_KERNEL_SHELL and type \"kernel stacks\" to see stack information.\n"); -#else - PR("Type \"kernel stacks\" to see stack information.\n"); -#endif - return 0; -} - -SHELL_SUBCMD_ADD((net), stacks, NULL, - "Show network stacks information.", - cmd_net_stacks, 1, 0); From 10def6cac544b69a8cc9bca161e89522d927a37e Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 28 Sep 2023 11:49:13 +0300 Subject: [PATCH 2386/4498] net: shell: Allow dynamic interface name expansion Allow multiple commands use the same dynamic shell command completion when expecting network interface index. For example "net iface" and "net stats" are such commands. The network interface expansion cannot be used in "net ipv6 add", "net ipv4 add" and "net route" commands as they require more data after the network interface index argument. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/common.h | 5 -- subsys/net/lib/shell/iface.c | 44 ---------------- subsys/net/lib/shell/iface_dynamic.h | 75 ++++++++++++++++++++++++++++ subsys/net/lib/shell/net_shell.c | 2 +- 4 files changed, 76 insertions(+), 50 deletions(-) create mode 100644 subsys/net/lib/shell/iface_dynamic.h diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/common.h index 3d0f1b58396..8b5566022d9 100644 --- a/subsys/net/lib/shell/common.h +++ b/subsys/net/lib/shell/common.h @@ -45,13 +45,8 @@ struct net_shell_user_data { #define ADDR_LEN NET_IPV6_ADDR_LEN #endif -#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") -#define MAX_IFACE_STR_LEN sizeof("xxx") - #if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) #define IFACE_DYN_CMD &iface_index - -void iface_index_get(size_t idx, struct shell_static_entry *entry); #else #define IFACE_DYN_CMD NULL #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index e024bdc1194..607c91de795 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -20,50 +20,6 @@ LOG_MODULE_DECLARE(net_shell); #include "common.h" -#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) - -static char iface_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; -static char iface_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; - -SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); - -static char *set_iface_index_buffer(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); - - return iface_index_buffer[idx]; -} - -static char *set_iface_index_help(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, - "%s (%p)", iface2str(iface, NULL), iface); - - return iface_help_buffer[idx]; -} - -void iface_index_get(size_t idx, struct shell_static_entry *entry) -{ - entry->handler = NULL; - entry->help = set_iface_index_help(idx); - entry->subcmd = &iface_index; - entry->syntax = set_iface_index_buffer(idx); -} - -#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ - #if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_NATIVE) struct ethernet_capabilities { enum ethernet_hw_caps capability; diff --git a/subsys/net/lib/shell/iface_dynamic.h b/subsys/net/lib/shell/iface_dynamic.h new file mode 100644 index 00000000000..df62ad1eb36 --- /dev/null +++ b/subsys/net/lib/shell/iface_dynamic.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Dynamic shell command completion for network interface. + * This is be used by multiple commands. + */ + +#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)") +#define MAX_IFACE_STR_LEN sizeof("xxx") + +static char iface_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; +static char iface_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; + +static void iface_index_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); + +static char *set_iface_index_buffer(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + /* Network interfaces start at 1 */ + if (idx == 0) { + return ""; + } + + if (!iface) { + return NULL; + } + + snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%d", (uint8_t)idx); + + return iface_index_buffer[idx]; +} + +static char *set_iface_index_help(size_t idx) +{ + struct net_if *iface = net_if_get_by_index(idx); + + /* Network interfaces start at 1 */ + if (idx == 0) { + return ""; + } + + if (!iface) { + return NULL; + } + +#if defined(CONFIG_NET_INTERFACE_NAME) + char name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + + net_if_get_name(iface, name, CONFIG_NET_INTERFACE_NAME_LEN); + name[CONFIG_NET_INTERFACE_NAME_LEN] = '\0'; + + snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "%s [%s] (%p)", name, iface2str(iface, NULL), iface); +#else + snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + "[%s] (%p)", iface2str(iface, NULL), iface); +#endif + + return iface_help_buffer[idx]; +} + +static void iface_index_get(size_t idx, struct shell_static_entry *entry) +{ + entry->handler = NULL; + entry->help = set_iface_index_help(idx); + entry->subcmd = &iface_index; + entry->syntax = set_iface_index_buffer(idx); +} diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 20f869d356f..ef62de5d72e 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -218,7 +218,7 @@ const char *iface2str(struct net_if *iface, const char **extra) #if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -SHELL_DYNAMIC_CMD_CREATE(iface_index, iface_index_get); +#include "iface_dynamic.h" #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ From 4265fe7a9392b70ccb3c1c722fe3613088b0e604 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 28 Sep 2023 11:59:42 +0300 Subject: [PATCH 2387/4498] net: shell: stats: Use generic iface idx dynamic completion The interface number is generated automatically if one presses when expecting the interface. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/iface.c | 6 ++++ subsys/net/lib/shell/net_shell.c | 6 ---- subsys/net/lib/shell/stats.c | 54 ++------------------------------ 3 files changed, 8 insertions(+), 58 deletions(-) diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index 607c91de795..a072a715b1c 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -654,6 +654,12 @@ static int cmd_net_iface(const struct shell *sh, size_t argc, char *argv[]) return 0; } +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) + +#include "iface_dynamic.h" + +#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ + SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface, SHELL_CMD(up, IFACE_DYN_CMD, "'net iface up ' takes network interface up.", diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index ef62de5d72e..38dac80a436 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -216,12 +216,6 @@ const char *iface2str(struct net_if *iface, const char **extra) return ""; } -#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) - -#include "iface_dynamic.h" - -#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ - /* Placeholder for net commands that are configured in the rest of the .c files */ SHELL_SUBCMD_SET_CREATE(net_cmds, (net)); diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c index ad5671cde63..455f5d7decd 100644 --- a/subsys/net/lib/shell/stats.c +++ b/subsys/net/lib/shell/stats.c @@ -639,65 +639,15 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -static char iface_stats_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN]; -static char iface_stats_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN]; - -static void iface_stats_index_get(size_t idx, struct shell_static_entry *entry); - -SHELL_DYNAMIC_CMD_CREATE(iface_stats_index, iface_stats_index_get); - -static char *set_iface_stats_index_buffer(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_stats_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx); - - return iface_stats_index_buffer[idx]; -} - -static char *set_iface_stats_index_help(size_t idx) -{ - struct net_if *iface = net_if_get_by_index(idx); - - if (!iface) { - return NULL; - } - - snprintk(iface_stats_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, - "%s (%p)", iface2str(iface, NULL), iface); - - return iface_stats_help_buffer[idx]; -} - -static void iface_stats_index_get(size_t idx, struct shell_static_entry *entry) -{ - entry->handler = NULL; - entry->help = set_iface_stats_index_help(idx); - entry->subcmd = &iface_stats_index; - entry->syntax = set_iface_stats_index_buffer(idx); -} +#include "iface_dynamic.h" #endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */ -#if defined(CONFIG_NET_STATISTICS) && \ - defined(CONFIG_NET_STATISTICS_PER_INTERFACE) && \ - defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -#define STATS_IFACE_CMD &iface_stats_index -#else -#define STATS_IFACE_CMD NULL -#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_STATISTICS_PER_INTERFACE && - * CONFIG_NET_SHELL_DYN_CMD_COMPLETION - */ - SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_stats, SHELL_CMD(all, NULL, "Show network statistics for all network interfaces.", cmd_net_stats_all), - SHELL_CMD(iface, STATS_IFACE_CMD, + SHELL_CMD(iface, IFACE_DYN_CMD, "'net stats ' shows network statistics for " "one specific network interface.", cmd_net_stats_iface), From 046f00244c969e6c41a6c99f2ba23a5b915185bf Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 28 Sep 2023 12:18:34 +0300 Subject: [PATCH 2388/4498] net: shell: vlan: Enforce arg count via shell macro Use the SHELL_CMD_ARG() to enforce the minimum parameter count in vlan command. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/vlan.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c index 44c9016317c..0a980caa11f 100644 --- a/subsys/net/lib/shell/vlan.c +++ b/subsys/net/lib/shell/vlan.c @@ -209,14 +209,14 @@ static int cmd_net_vlan_del(const struct shell *sh, size_t argc, char *argv[]) } SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, - SHELL_CMD(add, NULL, - "'net vlan add ' adds VLAN tag to the " - "network interface.", - cmd_net_vlan_add), - SHELL_CMD(del, NULL, - "'net vlan del ' deletes VLAN tag from the network " - "interface.", - cmd_net_vlan_del), + SHELL_CMD_ARG(add, NULL, + "'net vlan add ' adds VLAN tag to the " + "network interface.", + cmd_net_vlan_add, 3, 0), + SHELL_CMD_ARG(del, NULL, + "'net vlan del ' deletes VLAN tag from the network " + "interface.", + cmd_net_vlan_del, 2, 0), SHELL_SUBCMD_SET_END ); From 9f42c92e2638f0658d169ccb9a50721b74152462 Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Mon, 18 Sep 2023 17:26:25 +0200 Subject: [PATCH 2389/4498] Bluetooth: Host: Fix GATT Long Read for EATT When EATT is established, the value returned from `bt_att_get_mtu` is not useful to determine the ATT_MTU that applies to a ATT response. This is because `bt_att_get_mtu` may return the value for a different bearer than the request is serviced on. To fix this, the params struct for the GATT read operation is given a new field that will record the ATT_MTU that applies to this ATT operation. This value is then used to determine if the GATT long read operation is concluded. Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/61741 Signed-off-by: Aleksander Wasaznik --- include/zephyr/bluetooth/gatt.h | 20 +- subsys/bluetooth/host/att.c | 7 + subsys/bluetooth/host/att_internal.h | 2 + subsys/bluetooth/host/gatt.c | 25 +- .../host/att/long_read/CMakeLists.txt | 24 ++ .../bluetooth/host/att/long_read/_build.sh | 14 + .../bsim/bluetooth/host/att/long_read/main.c | 232 +++++++++++ .../bluetooth/host/att/long_read/prj.conf | 26 ++ .../bsim/bluetooth/host/att/long_read/run.sh | 26 ++ .../host/att/long_read/testlib/adv.c | 83 ++++ .../host/att/long_read/testlib/adv.h | 7 + .../host/att/long_read/testlib/att_read.c | 387 ++++++++++++++++++ .../host/att/long_read/testlib/att_read.h | 39 ++ .../host/att/long_read/testlib/att_write.c | 74 ++++ .../host/att/long_read/testlib/att_write.h | 9 + .../host/att/long_read/testlib/bs_macro.h | 23 ++ .../host/att/long_read/testlib/bs_main.c | 31 ++ .../host/att/long_read/testlib/bs_sync.c | 107 +++++ .../host/att/long_read/testlib/bs_sync.h | 5 + .../host/att/long_read/testlib/conn_ref.h | 37 ++ .../host/att/long_read/testlib/conn_wait.c | 66 +++ .../host/att/long_read/testlib/conn_wait.h | 4 + .../host/att/long_read/testlib/connect.c | 85 ++++ .../host/att/long_read/testlib/connect.h | 7 + .../host/att/long_read/testlib/log_utils.h | 36 ++ .../host/att/long_read/testlib/scan.c | 98 +++++ .../host/att/long_read/testlib/scan.h | 7 + .../host/att/long_read/testlib/security.c | 108 +++++ .../host/att/long_read/testlib/security.h | 7 + tests/bsim/bluetooth/host/compile.sh | 1 + 30 files changed, 1593 insertions(+), 4 deletions(-) create mode 100644 tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt create mode 100755 tests/bsim/bluetooth/host/att/long_read/_build.sh create mode 100644 tests/bsim/bluetooth/host/att/long_read/main.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/prj.conf create mode 100755 tests/bsim/bluetooth/host/att/long_read/run.sh create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/adv.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/adv.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/connect.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/connect.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/scan.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/scan.h create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/security.c create mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/security.h diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 7d4ac72495b..6b31e5dc92b 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -1572,6 +1572,8 @@ struct bt_gatt_read_params { #if defined(CONFIG_BT_EATT) enum bt_att_chan_opt chan_opt; #endif /* CONFIG_BT_EATT */ + /** Internal */ + uint16_t _att_mtu; }; /** @brief Read Attribute Value by handle @@ -1582,9 +1584,21 @@ struct bt_gatt_read_params { * depending on how many instances of given the UUID exists with the * start_handle being updated for each instance. * - * If an instance does contain a long value which cannot be read entirely the - * caller will need to read the remaining data separately using the handle and - * offset. + * To perform a GATT Long Read procedure, start with a Characteristic Value + * Read (by setting @c offset @c 0 and @c handle_count @c 1) and then return + * @ref BT_GATT_ITER_CONTINUE from the callback. This is equivalent to calling + * @ref bt_gatt_read again, but with the correct offset to continue the read. + * This may be repeated until the procedure is complete, which is signaled by + * the callback being called with @p data set to @c NULL. + * + * Note that returning @ref BT_GATT_ITER_CONTINUE is really starting a new ATT + * operation, so this can fail to allocate resources. However, all API errors + * are reported as if the server returned @ref BT_ATT_ERR_UNLIKELY. There is no + * way to distinguish between this condition and a @ref BT_ATT_ERR_UNLIKELY + * response from the server itself. + * + * Note that the effect of returning @ref BT_GATT_ITER_CONTINUE from the + * callback varies depending on the type of read operation. * * The Response comes in callback @p params->func. The callback is run from * the context specified by 'config BT_RECV_CONTEXT'. diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 18d22f5e98f..dd953115c5c 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -447,12 +447,19 @@ static int chan_req_send(struct bt_att_chan *chan, struct bt_att_req *req) buf = req->buf; req->buf = NULL; + /* This lock makes sure the value of `bt_att_mtu(chan)` does not + * change. + */ + k_sched_lock(); err = bt_att_chan_send(chan, buf); if (err) { /* We still have the ownership of the buffer */ req->buf = buf; chan->req = NULL; + } else { + bt_gatt_req_set_mtu(req, bt_att_mtu(chan)); } + k_sched_unlock(); return err; } diff --git a/subsys/bluetooth/host/att_internal.h b/subsys/bluetooth/host/att_internal.h index 2910c018e85..a45184a59c7 100644 --- a/subsys/bluetooth/host/att_internal.h +++ b/subsys/bluetooth/host/att_internal.h @@ -347,3 +347,5 @@ bool bt_att_tx_meta_data_match(const struct net_buf *buf, bt_gatt_complete_func_ #endif /* CONFIG_BT_EATT */ bool bt_att_chan_opt_valid(struct bt_conn *conn, enum bt_att_chan_opt chan_opt); + +void bt_gatt_req_set_mtu(struct bt_att_req *req, uint16_t mtu); diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 069082ec67b..8266fe36dae 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -4621,8 +4622,11 @@ static void gatt_read_rsp(struct bt_conn *conn, uint8_t err, const void *pdu, * If the Characteristic Value is greater than (ATT_MTU - 1) octets * in length, the Read Long Characteristic Value procedure may be used * if the rest of the Characteristic Value is required. + * + * Note: Both BT_ATT_OP_READ_RSP and BT_ATT_OP_READ_BLOB_RSP + * have an overhead of one octet. */ - if (length < (bt_att_get_mtu(conn) - 1)) { + if (length < (params->_att_mtu - 1)) { params->func(conn, 0, params, NULL, 0); return; } @@ -6277,3 +6281,22 @@ void bt_gatt_disconnected(struct bt_conn *conn) remove_cf_cfg(conn); #endif } + +void bt_gatt_req_set_mtu(struct bt_att_req *req, uint16_t mtu) +{ + IF_ENABLED(CONFIG_BT_GATT_CLIENT, ({ + if (req->func == gatt_read_rsp) { + struct bt_gatt_read_params *params = req->user_data; + + __ASSERT_NO_MSG(params); + params->_att_mtu = mtu; + return; + } + })); + + /* Otherwise: This request type does not have an `_att_mtu` + * params field or any other method to get this value, so we can + * just drop it here. Feel free to add this capability to other + * request types if needed. + */ +} diff --git a/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt b/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt new file mode 100644 index 00000000000..04bd6641153 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(app) + +target_sources(app PRIVATE + testlib/bs_main.c + testlib/adv.c + testlib/connect.c + testlib/scan.c + testlib/security.c + testlib/att_read.c + testlib/att_write.c + testlib/bs_sync.c + testlib/conn_wait.c + main.c +) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ +) diff --git a/tests/bsim/bluetooth/host/att/long_read/_build.sh b/tests/bsim/bluetooth/host/att/long_read/_build.sh new file mode 100755 index 00000000000..637512b3826 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/_build.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -eu +dotslash="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" +bin_dir="${BSIM_OUT_PATH}/bin" +BOARD="${BOARD:-nrf52_bsim}" + +cd "${dotslash}" + +compile_path="${bin_dir}/bs_${BOARD}_" +compile_path+="$(realpath --relative-to "$(west topdir)"/zephyr prj.conf | tr /. _)" + +west build -b nrf52_bsim +cp -v build/zephyr/zephyr.exe "${compile_path}" diff --git a/tests/bsim/bluetooth/host/att/long_read/main.c b/tests/bsim/bluetooth/host/att/long_read/main.c new file mode 100644 index 00000000000..ad99d298a56 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/main.c @@ -0,0 +1,232 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "testlib/adv.h" +#include "testlib/att_read.h" +#include "testlib/att_write.h" +#include "testlib/bs_macro.h" +#include "testlib/bs_sync.h" +#include "testlib/conn_ref.h" +#include "testlib/conn_wait.h" +#include "testlib/connect.h" +#include "testlib/log_utils.h" +#include "testlib/scan.h" +#include "testlib/security.h" + +/* This test uses system asserts to fail tests. */ +BUILD_ASSERT(__ASSERT_ON); + +#define CENTRAL_DEVICE_NBR 0 +#define PERIPHERAL_DEVICE_NBR 1 + +LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); + +#define UUID_1 \ + BT_UUID_DECLARE_128(0xdb, 0x1f, 0xe2, 0x52, 0xf3, 0xc6, 0x43, 0x66, 0xb3, 0x92, 0x5d, \ + 0xc6, 0xe7, 0xc9, 0x59, 0x9d) + +#define UUID_2 \ + BT_UUID_DECLARE_128(0x3f, 0xa4, 0x7f, 0x44, 0x2e, 0x2a, 0x43, 0x05, 0xab, 0x38, 0x07, \ + 0x8d, 0x16, 0xbf, 0x99, 0xf1) + +static ssize_t read_mtu_validation_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t buf_len, uint16_t offset) +{ + ssize_t read_len; + + LOG_INF("Server side buf_len %u", buf_len); + + /* Note: We assume `buf_len` is equal to the usable payload + * capacity of the response PDU. I.e. `(ATT_MTU - 1)` for + * BT_ATT_OP_READ_RSP and BT_ATT_OP_READ_BLOB_RSP. + */ + + /* Send back a full PDU on the first read (on offset 0). Then an + * not full one for the second read to conlude the long read.. + */ + read_len = buf_len; + if (offset > 0) { + __ASSERT_NO_MSG(read_len > 0); + /* The second PDU is one-less-than-full to test for off + * by one errors. + */ + read_len -= 1; + } + + /* If the ATT_MTU is too large, sending a one-less-than-full + * response would exeed the max attribute length limit. + */ + __ASSERT(buf_len < (BT_ATT_MAX_ATTRIBUTE_LEN / 2), + "The EATT buffer is too large for this test."); + + /* Ensure the padding bytes (that are not overwritten later in + * this function) are initialized. + */ + memset(buf, 0, read_len); + + /* Echo back the requested read size in the first two bytes of + * each read. + */ + __ASSERT_NO_MSG(read_len >= 2); + sys_put_le16(read_len, buf); + + return read_len; +} + +static struct bt_gatt_attr attrs[] = { + BT_GATT_PRIMARY_SERVICE(UUID_1), + BT_GATT_CHARACTERISTIC(UUID_2, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_mtu_validation_chrc, NULL, NULL), +}; + +static struct bt_gatt_service svc = { + .attrs = attrs, + .attr_count = ARRAY_SIZE(attrs), +}; + +static void find_the_chrc(struct bt_conn *conn, uint16_t *chrc_value_handle) +{ + uint16_t svc_handle; + uint16_t svc_end_handle; + uint16_t chrc_end_handle; + + EXPECT_ZERO(bt_testlib_gatt_discover_primary(&svc_handle, &svc_end_handle, conn, UUID_1, 1, + 0xffff)); + + LOG_INF("svc_handle: %u, svc_end_handle: %u", svc_handle, svc_end_handle); + + EXPECT_ZERO(bt_testlib_gatt_discover_characteristic(chrc_value_handle, &chrc_end_handle, + NULL, conn, UUID_2, (svc_handle + 1), + svc_end_handle)); + + LOG_INF("chrc_value_handle: %u, chrc_end_handle: %u", *chrc_value_handle, chrc_end_handle); +} + +static void bs_sync_all_log(char *log_msg) +{ + /* Everyone meets here. */ + bt_testlib_bs_sync_all(); + + if (get_device_nbr() == 0) { + LOG_WRN("Sync point: %s", log_msg); + } + + /* Everyone waits for d0 to finish logging. */ + bt_testlib_bs_sync_all(); +} + +static inline void bt_enable_quiet(void) +{ + bt_testlib_log_level_set("bt_hci_core", LOG_LEVEL_ERR); + bt_testlib_log_level_set("bt_id", LOG_LEVEL_ERR); + + EXPECT_ZERO(bt_enable(NULL)); + + bt_testlib_log_level_set("bt_hci_core", LOG_LEVEL_INF); + bt_testlib_log_level_set("bt_id", LOG_LEVEL_INF); +} + +static void test_long_read(enum bt_att_chan_opt bearer, uint16_t chrc_value_handle, + struct bt_conn *conn) +{ + bool central = (get_device_nbr() == CENTRAL_DEVICE_NBR); + + if (central) { + size_t read_count; + + NET_BUF_SIMPLE_DEFINE(attr_value_buf, BT_ATT_MAX_ATTRIBUTE_LEN); + + /* Perform the whole long read operation. */ + EXPECT_ZERO(btt_gatt_long_read(&attr_value_buf, NULL, conn, bearer, + chrc_value_handle, 0)); + + /* Parse the read attribute value to verify the + * integrity of the transfer. + * + * Each response starts with the length of the whole + * response and the rest is zero-padded. + */ + for (read_count = 0; attr_value_buf.len; read_count++) { + uint16_t encoded_len; + uint16_t padding_size; + + LOG_INF("Verifying read %u", read_count); + + __ASSERT(attr_value_buf.len >= sizeof(encoded_len), + "Incomplete encoded length"); + encoded_len = net_buf_simple_pull_le16(&attr_value_buf); + + padding_size = (encoded_len - sizeof(uint16_t)); + LOG_INF("Padding size %u", padding_size); + + /* Check and discard padding. */ + for (uint16_t i = 0; i < padding_size; i++) { + __ASSERT(attr_value_buf.len, "Unexpected end of buffer"); + __ASSERT(net_buf_simple_pull_u8(&attr_value_buf) == 0, + "Expected a padding byte at %u", i); + } + } + LOG_INF("Verified %u reads", read_count); + __ASSERT(read_count > 1, "Expected at least two reads"); + } +} + +void the_test(void) +{ + bool central = (get_device_nbr() == CENTRAL_DEVICE_NBR); + bool peripheral = (get_device_nbr() == PERIPHERAL_DEVICE_NBR); + bt_addr_le_t adva; + struct bt_conn *conn = NULL; + uint16_t chrc_value_handle = 0; + + if (peripheral) { + EXPECT_ZERO(bt_gatt_service_register(&svc)); + } + + bt_enable_quiet(); + + if (peripheral) { + EXPECT_ZERO(bt_set_name("peripheral")); + EXPECT_ZERO(bt_testlib_adv_conn( + &conn, BT_ID_DEFAULT, + (BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_FORCE_NAME_IN_AD))); + } + + if (central) { + EXPECT_ZERO(bt_testlib_scan_find_name(&adva, "peripheral")); + EXPECT_ZERO(bt_testlib_connect(&adva, &conn)); + + /* Establish EATT bearers. */ + EXPECT_ZERO(bt_testlib_secure(conn, BT_SECURITY_L2)); + + while (bt_eatt_count(conn) == 0) { + k_msleep(100); + }; + } + + bs_sync_all_log("Connected"); + + /* Perform discovery. */ + if (central) { + find_the_chrc(conn, &chrc_value_handle); + } + + bs_sync_all_log("Testing UATT"); + test_long_read(BT_ATT_CHAN_OPT_UNENHANCED_ONLY, chrc_value_handle, conn); + + bs_sync_all_log("Testing EATT"); + test_long_read(BT_ATT_CHAN_OPT_ENHANCED_ONLY, chrc_value_handle, conn); + + bs_sync_all_log("Test Complete"); + + PASS("Test complete\n"); +} diff --git a/tests/bsim/bluetooth/host/att/long_read/prj.conf b/tests/bsim/bluetooth/host/att/long_read/prj.conf new file mode 100644 index 00000000000..1e5e8dc8b41 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/prj.conf @@ -0,0 +1,26 @@ +CONFIG_ASSERT=y +CONFIG_BOOT_BANNER=n +CONFIG_BT_BUF_ACL_RX_SIZE=204 +CONFIG_BT_CENTRAL=y +CONFIG_BT_DEVICE_NAME_DYNAMIC=y +CONFIG_BT_EATT=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_DYNAMIC_DB=y +CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y +CONFIG_BT_L2CAP_ECRED=y +CONFIG_BT_L2CAP_TX_MTU=200 +CONFIG_BT_MAX_CONN=3 +CONFIG_BT_MAX_PAIRED=2 +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_PRIVACY=n +CONFIG_BT_SMP=y +CONFIG_BT_TESTING=y +CONFIG_BT=y +CONFIG_FLASH_MAP=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH=y +CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP=n +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_TAG_MAX_LEN=20 +CONFIG_LOG=y diff --git a/tests/bsim/bluetooth/host/att/long_read/run.sh b/tests/bsim/bluetooth/host/att/long_read/run.sh new file mode 100755 index 00000000000..b1b7a5c6eb0 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/run.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -eu +dotslash="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" +bin_dir="${BSIM_OUT_PATH}/bin" +BOARD="${BOARD:-nrf52_bsim}" + +cd "${dotslash}" + +compile_path="${bin_dir}/bs_${BOARD}_" +compile_path+="$(realpath --relative-to "$(west topdir)"/zephyr prj.conf | tr /. _)" + +args_all=(-s=long_read -D=2) +args_dev=(-v=2 -RealEncryption=1 -testid=the_test) +sim_seconds=60 + +echo "Simulation time: $sim_seconds seconds" + +# bs_2G4_phy_v1 requires pwd to at its location +cd "${BSIM_OUT_PATH}/bin" + +("${compile_path}" "${args_all[@]}" "${args_dev[@]}" -d=0 || echo d0 $?) & +("${compile_path}" "${args_all[@]}" "${args_dev[@]}" -d=1 || echo d1 $?) & +(./bs_2G4_phy_v1 "${args_all[@]}" -v=6 -sim_length=$((sim_seconds * 10 ** 6)) || echo phy $?) & + +wait diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/adv.c b/tests/bsim/bluetooth/host/att/long_read/testlib/adv.c new file mode 100644 index 00000000000..e67d3bb6fe8 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/adv.c @@ -0,0 +1,83 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bt_testlib_adv_ctx { + struct bt_conn **result; + struct k_condvar done; +}; + +/* Context pool (with capacity of one). */ +static K_SEM_DEFINE(g_ctx_free, 1, 1); +static K_MUTEX_DEFINE(g_ctx_lock); +static struct bt_testlib_adv_ctx *g_ctx; + +static void connected_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_connected_info *info) +{ + k_mutex_lock(&g_ctx_lock, K_FOREVER); + + if (g_ctx->result) { + *g_ctx->result = bt_conn_ref(info->conn); + } + k_condvar_signal(&g_ctx->done); + + k_mutex_unlock(&g_ctx_lock); +} + +int bt_testlib_adv_conn(struct bt_conn **conn, int id, uint32_t adv_options) +{ + int api_err; + struct bt_le_ext_adv *adv = NULL; + struct bt_le_adv_param param = {}; + struct bt_testlib_adv_ctx ctx = { + .result = conn, + }; + static const struct bt_le_ext_adv_cb cb = { + .connected = connected_cb, + }; + + param.id = id; + param.interval_min = BT_GAP_ADV_FAST_INT_MIN_1; + param.interval_max = BT_GAP_ADV_FAST_INT_MAX_1; + param.options |= BT_LE_ADV_OPT_CONNECTABLE; + param.options |= adv_options; + + k_condvar_init(&ctx.done); + + k_sem_take(&g_ctx_free, K_FOREVER); + k_mutex_lock(&g_ctx_lock, K_FOREVER); + g_ctx = &ctx; + + api_err = bt_le_ext_adv_create(¶m, &cb, &adv); + if (!api_err) { + api_err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + } + + if (!api_err) { + k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER); + } + + /* Delete adv before giving semaphore so that it's potentially available + * for the next taker of the semaphore. + */ + if (adv) { + bt_le_ext_adv_delete(adv); + } + + g_ctx = NULL; + k_mutex_unlock(&g_ctx_lock); + k_sem_give(&g_ctx_free); + + return api_err; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h b/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h new file mode 100644 index 00000000000..a9d429d5ad2 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h @@ -0,0 +1,7 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int bt_testlib_adv_conn(struct bt_conn **conn, int id, uint32_t adv_options); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c b/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c new file mode 100644 index 00000000000..b418aed440a --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c @@ -0,0 +1,387 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "att_read.h" +#include + +LOG_MODULE_REGISTER(att_read, LOG_LEVEL_DBG); + +struct bt_testlib_att_read_closure { + uint8_t att_err; + struct bt_conn *conn; + struct bt_gatt_read_params params; + uint16_t *result_size; + uint16_t *result_handle; + struct net_buf_simple *result_data; + struct k_mutex lock; + struct k_condvar done; + uint16_t *att_mtu; + bool long_read; +}; + +static uint8_t att_read_cb(struct bt_conn *conn, uint8_t att_err, + struct bt_gatt_read_params *params, const void *read_data, + uint16_t read_len) +{ + struct bt_testlib_att_read_closure *ctx = + CONTAINER_OF(params, struct bt_testlib_att_read_closure, params); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + if (read_data == NULL) { + __ASSERT_NO_MSG(ctx->long_read); + k_condvar_signal(&ctx->done); + k_mutex_unlock(&ctx->lock); + return BT_GATT_ITER_STOP; + } + + ctx->att_err = att_err; + + if (!att_err && ctx->result_handle) { + *ctx->result_handle = params->by_uuid.start_handle; + } + + if (!att_err && ctx->result_size) { + LOG_DBG("Adding %u bytes to result", read_len); + *ctx->result_size += read_len; + if (*ctx->result_size > BT_ATT_MAX_ATTRIBUTE_LEN) { + LOG_ERR("result_size > 512"); + } + } + + if (!att_err && ctx->result_data) { + uint16_t result_data_size = + MIN(read_len, net_buf_simple_tailroom(ctx->result_data)); + + net_buf_simple_add_mem(ctx->result_data, read_data, result_data_size); + } + + if (!att_err && ctx->att_mtu) { + *ctx->att_mtu = params->_att_mtu; + } + + if (ctx->long_read) { + /* Don't signal `&ctx->done` */ + k_mutex_unlock(&ctx->lock); + return BT_GATT_ITER_CONTINUE; + } + + k_condvar_signal(&ctx->done); + k_mutex_unlock(&ctx->lock); + return BT_GATT_ITER_STOP; +} + +static int bt_testlib_sync_bt_gatt_read(struct bt_testlib_att_read_closure *ctx) +{ + int api_err; + + ctx->params.func = att_read_cb; + + k_mutex_init(&ctx->lock); + k_condvar_init(&ctx->done); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + api_err = bt_gatt_read(ctx->conn, &ctx->params); + + if (!api_err) { + k_condvar_wait(&ctx->done, &ctx->lock, K_FOREVER); + } + + k_mutex_unlock(&ctx->lock); + + if (api_err) { + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + + __ASSERT_NO_MSG(ctx->att_err >= 0); + return ctx->att_err; +} + +int bt_testlib_att_read_by_type_sync(struct net_buf_simple *result_data, uint16_t *result_size, + uint16_t *result_handle, uint16_t *result_att_mtu, + struct bt_conn *conn, enum bt_att_chan_opt bearer, + const struct bt_uuid *type, uint16_t start_handle, + uint16_t end_handle) +{ + struct bt_testlib_att_read_closure ctx = {.result_handle = result_handle, + .result_size = result_size, + .conn = conn, + .result_data = result_data, + .att_mtu = result_att_mtu, + .params = { + .by_uuid = {.uuid = type, + .start_handle = start_handle, + .end_handle = end_handle}, + }}; + + IF_ENABLED(CONFIG_BT_EATT, ({ ctx.params.chan_opt = bearer; })) + + if (bearer == BT_ATT_CHAN_OPT_ENHANCED_ONLY) { + __ASSERT(IS_ENABLED(CONFIG_BT_EATT), "EATT not complied in"); + } + + return bt_testlib_sync_bt_gatt_read(&ctx); +} + +int bt_testlib_att_read_by_handle_sync(struct net_buf_simple *result_data, uint16_t *result_size, + uint16_t *result_att_mtu, struct bt_conn *conn, + enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset) +{ + struct bt_testlib_att_read_closure ctx = { + .result_size = result_size, + .conn = conn, + .att_mtu = result_att_mtu, + .result_data = result_data, + .params = { + .handle_count = 1, + .single = {.handle = handle, .offset = offset}, + IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer)), + }}; + + if (bearer == BT_ATT_CHAN_OPT_ENHANCED_ONLY) { + __ASSERT(IS_ENABLED(CONFIG_BT_EATT), "EATT not complied in"); + } + + *result_size = 0; + + return bt_testlib_sync_bt_gatt_read(&ctx); +} + +int btt_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, + struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset) +{ + int err; + uint16_t _result_data_size = 0; + + struct bt_testlib_att_read_closure ctx = { + .long_read = true, + .result_size = &_result_data_size, + .conn = conn, + .result_data = result_data, + .params = { + .handle_count = 1, + .single = {.handle = handle, .offset = offset}, + IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer)), + }}; + + if (bearer == BT_ATT_CHAN_OPT_ENHANCED_ONLY) { + __ASSERT(IS_ENABLED(CONFIG_BT_EATT), "EATT not complied in"); + } + + err = bt_testlib_sync_bt_gatt_read(&ctx); + + if (result_size) { + *result_size = _result_data_size; + } + + return err; +} + +struct bt_testlib_gatt_discover_service_closure { + struct bt_gatt_discover_params params; + uint8_t att_err; + uint16_t *const result_handle; + uint16_t *const result_end_handle; + struct k_mutex lock; + struct k_condvar done; +}; + +static uint8_t gatt_discover_service_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_testlib_gatt_discover_service_closure *ctx = + CONTAINER_OF(params, struct bt_testlib_gatt_discover_service_closure, params); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + ctx->att_err = attr ? BT_ATT_ERR_SUCCESS : BT_ATT_ERR_ATTRIBUTE_NOT_FOUND; + + if (!ctx->att_err) { + if (ctx->result_handle) { + *ctx->result_handle = attr->handle; + } + + if (ctx->result_end_handle) { + *ctx->result_end_handle = 0; + /* Output 'group end handle'. */ + if (params->type == BT_GATT_DISCOVER_PRIMARY || + params->type == BT_GATT_DISCOVER_SECONDARY) { + *ctx->result_end_handle = + ((struct bt_gatt_service_val *)attr->user_data)->end_handle; + } + } + } + + k_condvar_signal(&ctx->done); + k_mutex_unlock(&ctx->lock); + return BT_GATT_ITER_STOP; +} + +/** AKA Service discovery by UUID. + */ +int bt_testlib_gatt_discover_primary(uint16_t *result_handle, uint16_t *result_end_handle, + struct bt_conn *conn, const struct bt_uuid *uuid, + uint16_t start_handle, uint16_t end_handle) +{ + int api_err; + + struct bt_testlib_gatt_discover_service_closure ctx_val = { + .result_handle = result_handle, + .result_end_handle = result_end_handle, + .params = { + .type = BT_GATT_DISCOVER_PRIMARY, + .start_handle = start_handle, + .end_handle = end_handle, + .func = gatt_discover_service_cb, + .uuid = uuid, + }}; + struct bt_testlib_gatt_discover_service_closure *const ctx = &ctx_val; + + k_mutex_init(&ctx->lock); + k_condvar_init(&ctx->done); + + __ASSERT_NO_MSG(conn); + __ASSERT_NO_MSG(IN_RANGE(start_handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, + BT_ATT_LAST_ATTRIBUTE_HANDLE)); + __ASSERT_NO_MSG( + IN_RANGE(end_handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE)); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + api_err = bt_gatt_discover(conn, &ctx->params); + + if (!api_err) { + k_condvar_wait(&ctx->done, &ctx->lock, K_FOREVER); + } + + k_mutex_unlock(&ctx->lock); + + if (api_err) { + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + __ASSERT_NO_MSG(ctx->att_err >= 0); + return ctx->att_err; +} + +struct bt_testlib_gatt_discover_char_closure { + struct bt_gatt_discover_params params; + uint8_t att_err; + uint16_t *const result_def_handle; + uint16_t *const result_value_handle; + uint16_t *const result_end_handle; + uint16_t svc_end_handle; + struct k_mutex lock; + struct k_condvar done; +}; + +static uint8_t gatt_discover_char_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_testlib_gatt_discover_char_closure *ctx = + CONTAINER_OF(params, struct bt_testlib_gatt_discover_char_closure, params); + bool read_more = false; + + k_mutex_lock(&ctx->lock, K_FOREVER); + + if (ctx->att_err == BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) { + /* The start of the charachteristic was not found yet. + * This is the start of the characteristic. + */ + if (attr) { + ctx->att_err = BT_ATT_ERR_SUCCESS; + if (ctx->result_def_handle) { + *ctx->result_def_handle = attr->handle; + } + if (ctx->result_value_handle) { + *ctx->result_value_handle = + ((struct bt_gatt_chrc *)attr->user_data)->value_handle; + } + if (ctx->result_end_handle) { + read_more = true; + } + } + } else { + /* This is the end of the characteristic. + */ + if (attr) { + __ASSERT_NO_MSG(ctx->result_end_handle); + *ctx->result_end_handle = (attr->handle - 1); + } + }; + + if (!read_more) { + k_condvar_signal(&ctx->done); + } + k_mutex_unlock(&ctx->lock); + return read_more ? BT_GATT_ITER_CONTINUE : BT_GATT_ITER_STOP; +} + +int bt_testlib_gatt_discover_characteristic(uint16_t *const result_value_handle, + uint16_t *const result_end_handle, + uint16_t *const result_def_handle, struct bt_conn *conn, + const struct bt_uuid *uuid, uint16_t start_handle, + uint16_t svc_end_handle) +{ + int api_err; + + if (result_end_handle) { + /* If there is no second result, the end_handle is the svc_end. */ + *result_end_handle = svc_end_handle; + } + + struct bt_testlib_gatt_discover_char_closure ctx_val = { + .att_err = BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, + .result_value_handle = result_value_handle, + .result_def_handle = result_def_handle, + .result_end_handle = result_end_handle, + .params = { + .type = BT_GATT_DISCOVER_CHARACTERISTIC, + .start_handle = start_handle, + .end_handle = svc_end_handle, + .func = gatt_discover_char_cb, + .uuid = uuid, + }}; + struct bt_testlib_gatt_discover_char_closure *const ctx = &ctx_val; + + k_mutex_init(&ctx->lock); + k_condvar_init(&ctx->done); + + __ASSERT_NO_MSG(conn); + __ASSERT_NO_MSG(IN_RANGE(start_handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, + BT_ATT_LAST_ATTRIBUTE_HANDLE)); + __ASSERT_NO_MSG(IN_RANGE(svc_end_handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, + BT_ATT_LAST_ATTRIBUTE_HANDLE)); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + api_err = bt_gatt_discover(conn, &ctx->params); + + if (!api_err) { + k_condvar_wait(&ctx->done, &ctx->lock, K_FOREVER); + } + + k_mutex_unlock(&ctx->lock); + + if (api_err) { + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + __ASSERT_NO_MSG(ctx->att_err >= 0); + return ctx->att_err; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h b/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h new file mode 100644 index 00000000000..ced1265289d --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** Perform a single ATT_READ_BY_TYPE_REQ. */ +int bt_testlib_att_read_by_type_sync(struct net_buf_simple *result_data, uint16_t *result_size, + uint16_t *result_handle, uint16_t *result_att_mtu, + struct bt_conn *conn, enum bt_att_chan_opt bearer, + const struct bt_uuid *type, uint16_t start_handle, + uint16_t end_handle); + +/** If offset == 0, perform a single ATT_READ_REQ. + * If offset > 0, perform a signle ATT_READ_BLOB_REQ. + */ +int bt_testlib_att_read_by_handle_sync(struct net_buf_simple *result_data, uint16_t *result_size, + uint16_t *result_att_mtu, struct bt_conn *conn, + enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset); + +int btt_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, + struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset); + +int bt_testlib_gatt_discover_primary(uint16_t *result_handle, uint16_t *result_end_handle, + struct bt_conn *conn, const struct bt_uuid *uuid, + uint16_t start_handle, uint16_t end_handle); + +/* Note: svc_end_handle must be the service end handle. (The discovery + * algorithm requires it to recognize the last characteristic in a + * service and deduce its end handle.) + */ +int bt_testlib_gatt_discover_characteristic(uint16_t *const result_value_handle, + uint16_t *const result_end_handle, + uint16_t *const result_def_handle, struct bt_conn *conn, + const struct bt_uuid *uuid, uint16_t start_handle, + uint16_t svc_end_handle); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c b/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c new file mode 100644 index 00000000000..a82269e1301 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c @@ -0,0 +1,74 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(att_write, LOG_LEVEL_DBG); + +struct bt_testlib_att_write_closure { + uint8_t att_err; + struct bt_gatt_write_params params; + struct k_mutex lock; + struct k_condvar done; +}; + +static void att_write_cb(struct bt_conn *conn, uint8_t att_err, struct bt_gatt_write_params *params) +{ + struct bt_testlib_att_write_closure *ctx = + CONTAINER_OF(params, struct bt_testlib_att_write_closure, params); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + ctx->att_err = att_err; + + k_condvar_signal(&ctx->done); + k_mutex_unlock(&ctx->lock); +} + +int bt_testlib_att_write(struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + uint8_t *data, uint16_t size) +{ + int api_err; + struct bt_testlib_att_write_closure ctx_val = {.params = { + .handle = handle, + .offset = 0, + .func = att_write_cb, + .data = data, + .length = size, + }}; + struct bt_testlib_att_write_closure *const ctx = &ctx_val; + + k_mutex_init(&ctx->lock); + k_condvar_init(&ctx->done); + + __ASSERT_NO_MSG(conn); + __ASSERT_NO_MSG( + IN_RANGE(handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE)); + + k_mutex_lock(&ctx->lock, K_FOREVER); + + api_err = bt_gatt_write(conn, &ctx->params); + + if (!api_err) { + k_condvar_wait(&ctx->done, &ctx->lock, K_FOREVER); + } + + k_mutex_unlock(&ctx->lock); + + if (api_err) { + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + __ASSERT_NO_MSG(ctx->att_err >= 0); + return ctx->att_err; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h b/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h new file mode 100644 index 00000000000..9bf063d3bd4 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h @@ -0,0 +1,9 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int bt_testlib_att_write(struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + const uint8_t *data, uint16_t size); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h new file mode 100644 index 00000000000..b9e52beea6c --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define PASS(...) \ + do { \ + extern enum bst_result_t bst_result; \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +static inline void bt_testlib_expect_zero(int err, char *where_file, int where_line) +{ + if (err) { + bs_trace_print(BS_TRACE_ERROR, where_file, where_line, 0, BS_TRACE_AUTOTIME, 0, + "err %d\n", err); + } +} + +#define EXPECT_ZERO(expr) bt_testlib_expect_zero((expr), __FILE__, __LINE__) diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c new file mode 100644 index 00000000000..26985a8d415 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c @@ -0,0 +1,31 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +void the_test(void); + +static const struct bst_test_instance test_to_add[] = { + { + .test_id = "the_test", + .test_main_f = the_test, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_to_add); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c new file mode 100644 index 00000000000..c7c432c74b7 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c @@ -0,0 +1,107 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +LOG_MODULE_REGISTER(bs_sync, LOG_LEVEL_INF); + +static int n_devs; + +static void register_more_cmd_args(void) +{ + static bs_args_struct_t args_struct_toadd[] = { + { + .option = "D", + .name = "number_devices", + .type = 'i', + .dest = (void *)&n_devs, + .descript = "Number of devices which will connect in this phy", + .is_mandatory = true, + }, + ARG_TABLE_ENDMARKER, + }; + + bs_add_extra_dynargs(args_struct_toadd); +} +NATIVE_TASK(register_more_cmd_args, PRE_BOOT_1, 100); + +static uint *backchannels; +static void setup_backchannels(void) +{ + __ASSERT_NO_MSG(n_devs > 0); + uint self = get_device_nbr(); + uint device_nbrs[n_devs]; + uint channel_numbers[n_devs]; + + for (int i = 0; i < n_devs; i++) { + device_nbrs[i] = i; + channel_numbers[i] = 0; + } + + backchannels = + bs_open_back_channel(self, device_nbrs, channel_numbers, ARRAY_SIZE(device_nbrs)); + __ASSERT_NO_MSG(backchannels != NULL); +} +NATIVE_TASK(setup_backchannels, PRE_BOOT_3, 100); + +void bs_bc_receive_msg_sync(uint ch, size_t size, uint8_t *data) +{ + while (bs_bc_is_msg_received(ch) < size) { + k_msleep(1); + } + bs_bc_receive_msg(ch, data, size); +} + +void bs_bc_send_uint(uint ch, uint64_t data) +{ + uint8_t data_bytes[sizeof(data)]; + + sys_put_le64(data, data_bytes); + bs_bc_send_msg(ch, data_bytes, sizeof(data_bytes)); +} + +uint64_t bs_bc_recv_uint(uint ch) +{ + uint8_t data[sizeof(uint64_t)]; + + bs_bc_receive_msg_sync(ch, sizeof(data), data); + return sys_get_le64(data); +} + +void bt_testlib_bs_sync_all(void) +{ + static uint64_t counter; + + LOG_DBG("%llu d%u enter", counter, get_device_nbr()); + + /* Device 0 acts as hub. */ + if (get_device_nbr() == 0) { + for (int i = 1; i < n_devs; i++) { + uint64_t counter_cfm; + + counter_cfm = bs_bc_recv_uint(backchannels[i]); + __ASSERT(counter_cfm == counter, "%luu %luu", counter_cfm, counter); + } + for (int i = 1; i < n_devs; i++) { + bs_bc_send_uint(backchannels[i], counter); + } + } else { + uint64_t counter_cfm; + + bs_bc_send_uint(backchannels[0], counter); + counter_cfm = bs_bc_recv_uint(backchannels[0]); + __ASSERT(counter_cfm == counter, "%luu %luu", counter_cfm, counter); + } + + LOG_DBG("%llu d%u exit", counter, get_device_nbr()); + + counter++; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h new file mode 100644 index 00000000000..f69336cb1c2 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h @@ -0,0 +1,5 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_testlib_bs_sync_all(void); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h new file mode 100644 index 00000000000..c9978b635dc --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** + * @file + * @brief Reified connection reference counting. + * @ingroup testlib conn ref + * + * This file provides functions to reify the moving and cloning of @ref + * bt_conn references for increased safety. + * + * Reifying means that the existence of a reference is always tied + * one-to-one with a non-NULL value in a owning pointer variable. + * + * The functions in this file will trigger an assert if they attempt to + * overwrite a non-NULL value in a owning pointer variable. This is to + * prevent leaking the reference that presumable is tied the value that + * would be overwritten. + * + * The functions in this file are intended to guard against undefined + * behavor due to NULL pointer dereferencing. They will assert on any + * relevant pointers. + */ + +void bt_testlib_conn_unref(struct bt_conn **connp) +{ + struct bt_conn *conn; + + __ASSERT_NO_MSG(connp); + conn = atomic_ptr_set((void **)connp, NULL); + __ASSERT_NO_MSG(conn); + bt_conn_unref(conn); +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c new file mode 100644 index 00000000000..7edd12a699b --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(conn_wait, LOG_LEVEL_DBG); + +static K_MUTEX_DEFINE(conn_wait_mutex); +static K_CONDVAR_DEFINE(something_changed); + +void on_change(struct bt_conn *conn, uint8_t err) +{ + k_mutex_lock(&conn_wait_mutex, K_FOREVER); + k_condvar_broadcast(&something_changed); + k_mutex_unlock(&conn_wait_mutex); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = on_change, + .disconnected = on_change, +}; + +enum bt_conn_state bt_conn_state(struct bt_conn *conn) +{ + int err; + struct bt_conn_info info; + + __ASSERT(conn != NULL, "Invalid connection"); + err = bt_conn_get_info(conn, &info); + __ASSERT(err == 0, "Failed to get connection info"); + + return info.state; +} + +int bt_testlib_wait_connected(struct bt_conn *conn) +{ + __ASSERT_NO_MSG(conn != NULL); + k_mutex_lock(&conn_wait_mutex, K_FOREVER); + while (bt_conn_state(conn) != BT_CONN_STATE_CONNECTED) { + k_condvar_wait(&something_changed, &conn_wait_mutex, K_FOREVER); + } + k_mutex_unlock(&conn_wait_mutex); + return 0; +} + +int bt_testlib_wait_disconnected(struct bt_conn *conn) +{ + __ASSERT_NO_MSG(conn != NULL); + k_mutex_lock(&conn_wait_mutex, K_FOREVER); + while (bt_conn_state(conn) != BT_CONN_STATE_DISCONNECTED) { + k_condvar_wait(&something_changed, &conn_wait_mutex, K_FOREVER); + } + k_mutex_unlock(&conn_wait_mutex); + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h new file mode 100644 index 00000000000..d28b150aebc --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h @@ -0,0 +1,4 @@ +#include + +int bt_testlib_wait_connected(struct bt_conn *conn); +int bt_testlib_wait_disconnected(struct bt_conn *conn); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.c b/tests/bsim/bluetooth/host/att/long_read/testlib/connect.c new file mode 100644 index 00000000000..ddfa81de9ce --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/connect.c @@ -0,0 +1,85 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "connect.h" + +LOG_MODULE_REGISTER(testlib_connect, LOG_LEVEL_INF); + +struct bt_testlib_connect_closure { + uint8_t conn_err; + struct bt_conn **conn; + struct k_mutex lock; + struct k_condvar done; +}; + +/* Context pool (with capacity of one). */ +static K_SEM_DEFINE(g_ctx_free, 1, 1); +static K_MUTEX_DEFINE(g_ctx_lock); +static struct bt_testlib_connect_closure *g_ctx; + +static void connected_cb(struct bt_conn *conn, uint8_t conn_err) +{ + /* Loop over each (allocated) item in pool. */ + + k_mutex_lock(&g_ctx_lock, K_FOREVER); + + if (g_ctx && conn == *g_ctx->conn) { + g_ctx->conn_err = conn_err; + k_condvar_signal(&g_ctx->done); + } + + k_mutex_unlock(&g_ctx_lock); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected_cb, +}; + +int bt_testlib_connect(const bt_addr_le_t *peer, struct bt_conn **conn) +{ + int api_err; + struct bt_testlib_connect_closure ctx = { + .conn = conn, + }; + + __ASSERT_NO_MSG(conn); + __ASSERT_NO_MSG(*conn == NULL); + + k_condvar_init(&ctx.done); + + k_sem_take(&g_ctx_free, K_FOREVER); + k_mutex_lock(&g_ctx_lock, K_FOREVER); + g_ctx = &ctx; + + api_err = bt_conn_le_create(peer, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, conn); + + if (!api_err) { + LOG_INF("Connecting.. conn %u", bt_conn_index(*conn)); + k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER); + LOG_INF("Connect complete"); + } + + g_ctx = NULL; + k_mutex_unlock(&g_ctx_lock); + k_sem_give(&g_ctx_free); + + if (api_err) { + LOG_ERR("bt_conn_le_create err %d", api_err); + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + + if (ctx.conn_err) { + LOG_ERR("Connect HCI err %d", ctx.conn_err); + __ASSERT_NO_MSG(ctx.conn_err >= 0); + return ctx.conn_err; + } + + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h b/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h new file mode 100644 index 00000000000..e8da223849a --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h @@ -0,0 +1,7 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int bt_testlib_connect(const bt_addr_le_t *peer, struct bt_conn **conn); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h b/tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h new file mode 100644 index 00000000000..c3825246bb9 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static inline void bt_testlib_log_level_set(char *module, uint32_t new_level) +{ + int source_id; + uint32_t result_level; + + __ASSERT_NO_MSG(IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)); + + source_id = log_source_id_get(module); + __ASSERT(source_id >= 0, "%d", source_id); + + result_level = log_filter_set(NULL, Z_LOG_LOCAL_DOMAIN_ID, source_id, new_level); + __ASSERT(result_level == new_level, "%u %u", result_level, new_level); +} + +static inline void bt_testlib_log_level_set_all(uint32_t new_level) +{ + uint32_t source_count; + + __ASSERT_NO_MSG(IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)); + + source_count = log_src_cnt_get(Z_LOG_LOCAL_DOMAIN_ID); + + for (uint32_t source_id = 0; source_id < source_count; source_id++) { + uint32_t result_level; + + result_level = log_filter_set(NULL, Z_LOG_LOCAL_DOMAIN_ID, source_id, new_level); + __ASSERT(result_level == new_level, "%u %u", result_level, new_level); + } +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.c b/tests/bsim/bluetooth/host/att/long_read/testlib/scan.c new file mode 100644 index 00000000000..337dfef15ca --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/scan.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "scan.h" + +LOG_MODULE_REGISTER(testlib_scan, LOG_LEVEL_INF); + +struct bt_scan_find_name_closure { + char *wanted_name; + bt_addr_le_t *result; + struct k_condvar done; +}; + +/* Context pool (with capacity of one). */ +static K_SEM_DEFINE(g_ctx_free, 1, 1); +static K_MUTEX_DEFINE(g_ctx_lock); +static struct bt_scan_find_name_closure *g_ctx; + +static bool bt_scan_find_name_cb_data_cb(struct bt_data *data, void *user_data) +{ + char **wanted = user_data; + + if (data->type == BT_DATA_NAME_COMPLETE) { + if (data->data_len == strlen(*wanted) && + !memcmp(*wanted, data->data, data->data_len)) { + *wanted = NULL; + /* Stop bt_data_parse. */ + return false; + } + } + + /* Continue with next ad data. */ + return true; +} + +static void bt_scan_find_name_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, + struct net_buf_simple *buf) +{ + char *wanted; + + k_mutex_lock(&g_ctx_lock, K_FOREVER); + + __ASSERT_NO_MSG(g_ctx); + __ASSERT_NO_MSG(g_ctx->wanted_name); + + wanted = g_ctx->wanted_name; + + bt_data_parse(buf, bt_scan_find_name_cb_data_cb, &wanted); + + if (!wanted) { + (void)bt_le_scan_stop(); + *g_ctx->result = *addr; + k_condvar_signal(&g_ctx->done); + } + + k_mutex_unlock(&g_ctx_lock); +} + +int bt_testlib_scan_find_name(bt_addr_le_t *result, char name[]) +{ + int api_err; + struct bt_scan_find_name_closure ctx = { + .wanted_name = name, + .result = result, + }; + + k_condvar_init(&ctx.done); + + k_sem_take(&g_ctx_free, K_FOREVER); + k_mutex_lock(&g_ctx_lock, K_FOREVER); + g_ctx = &ctx; + + api_err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, bt_scan_find_name_cb); + if (!api_err) { + k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER); + } + + g_ctx = NULL; + k_mutex_unlock(&g_ctx_lock); + k_sem_give(&g_ctx_free); + + if (!api_err) { + char str[BT_ADDR_LE_STR_LEN]; + (void)bt_addr_le_to_str(result, str, ARRAY_SIZE(str)); + LOG_INF("Scan match: %s", str); + } else { + LOG_ERR("Scan error: %d", api_err); + } + + return api_err; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h b/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h new file mode 100644 index 00000000000..58c887c21c9 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h @@ -0,0 +1,7 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int bt_testlib_scan_find_name(bt_addr_le_t *result, char name[]); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/security.c b/tests/bsim/bluetooth/host/att/long_read/testlib/security.c new file mode 100644 index 00000000000..e7de704acee --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/security.c @@ -0,0 +1,108 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(testlib_security, LOG_LEVEL_INF); + +struct testlib_security_ctx { + enum bt_security_err result; + struct bt_conn *conn; + bt_security_t new_minimum; + struct k_condvar done; +}; + +/* Context pool (with capacity of one). */ +static K_SEM_DEFINE(g_ctx_free, 1, 1); +static K_MUTEX_DEFINE(g_ctx_lock); +static struct testlib_security_ctx *g_ctx; + +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + LOG_INF("conn %u level %d err %d", bt_conn_index(conn), level, err); + + /* Mutex operations establish a happens-before relationship. This + * ensures variables have the expected values despite non-atomic + * accesses. + */ + k_mutex_lock(&g_ctx_lock, K_FOREVER); + + if (g_ctx && (g_ctx->conn == conn)) { + g_ctx->result = err; + /* Assumption: A security error means there will be further + * security changes for this connection. + */ + if (err || level >= g_ctx->new_minimum) { + k_condvar_signal(&g_ctx->done); + } + } + + k_mutex_unlock(&g_ctx_lock); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .security_changed = security_changed, +}; + +int bt_testlib_secure(struct bt_conn *conn, bt_security_t new_minimum) +{ + int api_err = 0; + struct testlib_security_ctx ctx = { + .conn = conn, + .new_minimum = new_minimum, + }; + + k_condvar_init(&ctx.done); + + /* The semaphore allocates `g_ctx` to this invocation of + * `bt_testlib_secure`, in case this function is called from multiple + * threads in parallel. + */ + k_sem_take(&g_ctx_free, K_FOREVER); + /* The mutex synchronizes this function with `security_changed()`. */ + k_mutex_lock(&g_ctx_lock, K_FOREVER); + + /* Do the thing. */ + api_err = bt_conn_set_security(conn, new_minimum); + + /* Holding the mutex will pause any thread entering + * `security_changed_cb`, delaying it until `k_condvar_wait`. This + * ensures that the condition variable is signaled while this thread is + * in `k_condvar_wait`, even if the event happens before, e.g. between + * `bt_conn_get_security` and `k_condvar_wait`. + * + * If the security level is already satisfied, there is no point in + * waiting, and it would deadlock if security was already satisfied + * before the mutex was taken, `bt_conn_set_security` will result in no + * operation. + */ + if (!api_err && bt_conn_get_security(conn) < new_minimum) { + /* Waiting on a condvar releases the mutex and waits for a + * signal on the condvar, atomically, without a gap between the + * release and wait. The mutex is locked again before returning. + */ + g_ctx = &ctx; + k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER); + g_ctx = NULL; + } + + k_mutex_unlock(&g_ctx_lock); + k_sem_give(&g_ctx_free); + + if (api_err) { + __ASSERT_NO_MSG(api_err < 0); + return api_err; + } + + __ASSERT_NO_MSG(ctx.result >= 0); + return ctx.result; +} diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/security.h b/tests/bsim/bluetooth/host/att/long_read/testlib/security.h new file mode 100644 index 00000000000..8b7dd46423c --- /dev/null +++ b/tests/bsim/bluetooth/host/att/long_read/testlib/security.h @@ -0,0 +1,7 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int bt_testlib_secure(struct bt_conn *conn, bt_security_t new_minimum); diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index e52408a089a..7a9757e3e4a 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -37,6 +37,7 @@ app=tests/bsim/bluetooth/host/att/read_fill_buf/client compile app=tests/bsim/bluetooth/host/att/read_fill_buf/server compile app=tests/bsim/bluetooth/host/att/sequential/dut compile app=tests/bsim/bluetooth/host/att/sequential/tester compile +app=tests/bsim/bluetooth/host/att/long_read compile app=tests/bsim/bluetooth/host/gatt/caching compile app=tests/bsim/bluetooth/host/gatt/general compile From e8bbb033ef3f4cf7510edc48570d878b742ee70d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Oct 2023 10:58:15 +0100 Subject: [PATCH 2390/4498] mgmt: mcumgr: grp: img_mgmt: Fix erase returning unknown error Fixes an issue whereby the erase function would return an unknown error, which would happen when the slot was already erased. Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index addde1e9a2c..0af1f19ba88 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -298,6 +298,11 @@ int img_mgmt_erase_slot(int slot) LOG_ERR("Failed to erase flash area: %d", rc); rc = IMG_MGMT_ERR_FLASH_ERASE_FAILED; } + } else if (rc == 1) { + /* A return value of 1 indicates that the slot is already erased, thus + * return a success code to the client + */ + rc = 0; } flash_area_close(fa); From 4b41f9f24612f16ce8590876baa5a243aece96f6 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Sat, 21 Oct 2023 16:55:14 +0300 Subject: [PATCH 2391/4498] net: wifi: Fix compile error when -Werror -Wextra are set The warning which became error looks like this error: type qualifiers ignored on function return type [-Werror=ignored-qualifiers] 219 | const char * const wifi_ps_txt(enum wifi_ps ps_name); It is pointless to add a const qualifier to a return value. So remove the const pointer to avoid this warning. Fixes #64197 Signed-off-by: Jukka Rissanen --- include/zephyr/net/wifi.h | 24 ++++++++++++------------ subsys/net/l2/wifi/wifi_mgmt.c | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 75cf4cf5f92..5c7d5b493fa 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -56,7 +56,7 @@ enum wifi_security_type { }; /** Helper function to get user-friendly security type name. */ -const char * const wifi_security_txt(enum wifi_security_type security); +const char *wifi_security_txt(enum wifi_security_type security); /** IEEE 802.11w - Management frame protection. */ enum wifi_mfp_options { @@ -73,7 +73,7 @@ enum wifi_mfp_options { }; /** Helper function to get user-friendly MFP name.*/ -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp); +const char *wifi_mfp_txt(enum wifi_mfp_options mfp); /** * @brief IEEE 802.11 operational frequency bands (not exhaustive). @@ -95,7 +95,7 @@ enum wifi_frequency_bands { }; /** Helper function to get user-friendly frequency band name. */ -const char * const wifi_band_txt(enum wifi_frequency_bands band); +const char *wifi_band_txt(enum wifi_frequency_bands band); #define WIFI_SSID_MAX_LEN 32 #define WIFI_PSK_MIN_LEN 8 @@ -139,7 +139,7 @@ enum wifi_iface_state { }; /** Helper function to get user-friendly interface state name. */ -const char * const wifi_state_txt(enum wifi_iface_state state); +const char *wifi_state_txt(enum wifi_iface_state state); /** Wi-Fi interface modes. * @@ -165,7 +165,7 @@ enum wifi_iface_mode { }; /** Helper function to get user-friendly interface mode name. */ -const char * const wifi_mode_txt(enum wifi_iface_mode mode); +const char *wifi_mode_txt(enum wifi_iface_mode mode); /** Wi-Fi link operating modes * @@ -197,7 +197,7 @@ enum wifi_link_mode { }; /** Helper function to get user-friendly link mode name. */ -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode); +const char *wifi_link_mode_txt(enum wifi_link_mode link_mode); /** Wi-Fi scanning types. */ enum wifi_scan_type { @@ -216,7 +216,7 @@ enum wifi_ps { }; /** Helper function to get user-friendly ps name. */ -const char * const wifi_ps_txt(enum wifi_ps ps_name); +const char *wifi_ps_txt(enum wifi_ps ps_name); /** Wi-Fi power save modes. */ enum wifi_ps_mode { @@ -230,7 +230,7 @@ enum wifi_ps_mode { }; /** Helper function to get user-friendly ps mode name. */ -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode); +const char *wifi_ps_mode_txt(enum wifi_ps_mode ps_mode); /* Interface index Min and Max values */ #define WIFI_INTERFACE_INDEX_MIN 1 @@ -273,7 +273,7 @@ enum wifi_twt_operation { }; /** Helper function to get user-friendly twt operation name. */ -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation); +const char *wifi_twt_operation_txt(enum wifi_twt_operation twt_operation); /** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { @@ -286,7 +286,7 @@ enum wifi_twt_negotiation_type { }; /** Helper function to get user-friendly twt negotiation type name. */ -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation); +const char *wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation); /** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { @@ -309,7 +309,7 @@ enum wifi_twt_setup_cmd { }; /** Helper function to get user-friendly twt setup cmd name. */ -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup); +const char *wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup); /** Wi-Fi Target Wake Time (TWT) negotiation status. */ enum wifi_twt_setup_resp_status { @@ -401,7 +401,7 @@ enum wifi_ps_wakeup_mode { }; /** Helper function to get user-friendly ps wakeup mode name. */ -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode); +const char *wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode); /** Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index fd8fb3f865f..6eb8a6682c2 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #endif /* CONFIG_WIFI_NM */ -const char * const wifi_security_txt(enum wifi_security_type security) +const char *wifi_security_txt(enum wifi_security_type security) { switch (security) { case WIFI_SECURITY_TYPE_NONE: @@ -42,7 +42,7 @@ const char * const wifi_security_txt(enum wifi_security_type security) } } -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) +const char *wifi_mfp_txt(enum wifi_mfp_options mfp) { switch (mfp) { case WIFI_MFP_DISABLE: @@ -57,7 +57,7 @@ const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) } } -const char * const wifi_band_txt(enum wifi_frequency_bands band) +const char *wifi_band_txt(enum wifi_frequency_bands band) { switch (band) { case WIFI_FREQ_BAND_2_4_GHZ: @@ -72,7 +72,7 @@ const char * const wifi_band_txt(enum wifi_frequency_bands band) } } -const char * const wifi_state_txt(enum wifi_iface_state state) +const char *wifi_state_txt(enum wifi_iface_state state) { switch (state) { case WIFI_STATE_DISCONNECTED: @@ -101,7 +101,7 @@ const char * const wifi_state_txt(enum wifi_iface_state state) } } -const char * const wifi_mode_txt(enum wifi_iface_mode mode) +const char *wifi_mode_txt(enum wifi_iface_mode mode) { switch (mode) { case WIFI_MODE_INFRA: @@ -122,7 +122,7 @@ const char * const wifi_mode_txt(enum wifi_iface_mode mode) } } -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) +const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) { switch (link_mode) { case WIFI_0: @@ -149,7 +149,7 @@ const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) } } -const char * const wifi_ps_txt(enum wifi_ps ps_name) +const char *wifi_ps_txt(enum wifi_ps ps_name) { switch (ps_name) { case WIFI_PS_DISABLED: @@ -161,7 +161,7 @@ const char * const wifi_ps_txt(enum wifi_ps ps_name) } } -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) +const char *wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) { switch (ps_mode) { case WIFI_PS_MODE_LEGACY: @@ -173,7 +173,7 @@ const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) } } -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) +const char *wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) { switch (twt_operation) { case WIFI_TWT_SETUP: @@ -185,7 +185,7 @@ const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) } } -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) +const char *wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) { switch (twt_negotiation) { case WIFI_TWT_INDIVIDUAL: @@ -199,7 +199,7 @@ const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type } } -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) +const char *wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) { switch (twt_setup) { case WIFI_TWT_SETUP_CMD_REQUEST: @@ -223,7 +223,7 @@ const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) } } -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) +const char *wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) { switch (ps_wakeup_mode) { case WIFI_PS_WAKEUP_MODE_DTIM: From 64058f875361d237ac7edce35e91ed293a963b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 20 Oct 2023 15:49:33 +0200 Subject: [PATCH 2392/4498] MAINTAINERS: add myself as maintainer for Samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding myself as maintainer and Anas as collaborator on code samples, for which an area already exists in Github Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 58c351f5b8a..564ff040d7f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2145,6 +2145,17 @@ Retention: labels: - "area: Retention" +Samples: + status: maintained + maintainers: + - kartben + collaborators: + - nashif + files: + - samples/ + labels: + - "area: Samples" + Sensor Subsystem: status: maintained maintainers: From b483c9251c0dab96812d06e706451b961b86719b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 18 Oct 2023 10:50:00 -0700 Subject: [PATCH 2393/4498] drivers: adc: Fix misuse of const and k_tid_t "const k_tid_t" is "struct k_thread * const" and not "const struct k_thread *" as the code may be assuming. Just drop it. Signed-off-by: Flavio Ceolin --- drivers/adc/adc_ads1119.c | 2 +- drivers/adc/adc_ads114s0x.c | 2 +- drivers/adc/adc_ads1x1x.c | 2 +- drivers/adc/adc_max11102_17.c | 2 +- drivers/adc/adc_max1125x.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/adc/adc_ads1119.c b/drivers/adc/adc_ads1119.c index 23f71ded75b..45146b389d7 100644 --- a/drivers/adc/adc_ads1119.c +++ b/drivers/adc/adc_ads1119.c @@ -463,7 +463,7 @@ static int ads1119_init(const struct device *dev) } #if CONFIG_ADC_ASYNC - const k_tid_t tid = + k_tid_t tid = k_thread_create(&data->thread, config->stack, CONFIG_ADC_ADS1119_ACQUISITION_THREAD_STACK_SIZE, (k_thread_entry_t)ads1119_acquisition_thread, diff --git a/drivers/adc/adc_ads114s0x.c b/drivers/adc/adc_ads114s0x.c index 3b050e4e613..b8d0d661d18 100644 --- a/drivers/adc/adc_ads114s0x.c +++ b/drivers/adc/adc_ads114s0x.c @@ -1352,7 +1352,7 @@ static int ads114s0x_init(const struct device *dev) } #if CONFIG_ADC_ASYNC - const k_tid_t tid = k_thread_create( + k_tid_t tid = k_thread_create( &data->thread, config->stack, CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE, (k_thread_entry_t)ads114s0x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_ADS114S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_ads1x1x.c b/drivers/adc/adc_ads1x1x.c index a448eb6bf72..fee15e38d01 100644 --- a/drivers/adc/adc_ads1x1x.c +++ b/drivers/adc/adc_ads1x1x.c @@ -570,7 +570,7 @@ static int ads1x1x_init(const struct device *dev) return -ENODEV; } - const k_tid_t tid = + k_tid_t tid = k_thread_create(&data->thread, data->stack, K_THREAD_STACK_SIZEOF(data->stack), (k_thread_entry_t)ads1x1x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_ADS1X1X_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_max11102_17.c b/drivers/adc/adc_max11102_17.c index fa87ce7c55e..8476776c8c3 100644 --- a/drivers/adc/adc_max11102_17.c +++ b/drivers/adc/adc_max11102_17.c @@ -366,7 +366,7 @@ static int max11102_17_init(const struct device *dev) data->current_channel_id = 0; #if CONFIG_ADC_ASYNC - const k_tid_t tid = k_thread_create( + k_tid_t tid = k_thread_create( &data->thread, data->stack, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_STACK_SIZE, (k_thread_entry_t)max11102_17_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_INIT_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_max1125x.c b/drivers/adc/adc_max1125x.c index 7a9bf0ed026..11f69ac09e7 100644 --- a/drivers/adc/adc_max1125x.c +++ b/drivers/adc/adc_max1125x.c @@ -750,7 +750,7 @@ static int max1125x_init(const struct device *dev) return -EIO; } - const k_tid_t tid = k_thread_create( + k_tid_t tid = k_thread_create( &data->thread, data->stack, K_THREAD_STACK_SIZEOF(data->stack), (k_thread_entry_t)max1125x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_MAX1125X_ACQUISITION_THREAD_PRIORITY, 0, K_NO_WAIT); From 64aa25a8a49b7080557945a67f87831796194c3e Mon Sep 17 00:00:00 2001 From: Lingutla Chandrasekhar Date: Tue, 3 May 2022 14:36:28 -0700 Subject: [PATCH 2394/4498] RISCV: Support pm cpu ops for SMP Add pm cpu ops to call the platform specific implementations for bringing up secondary cores. Signed-off-by: Lingutla Chandrasekhar --- arch/riscv/core/smp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 0815920e8e6..7bcfff6828e 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -9,6 +9,7 @@ #include #include #include +#include volatile struct { arch_cpustart_t fn; @@ -18,6 +19,8 @@ volatile struct { volatile uintptr_t riscv_cpu_wake_flag; volatile void *riscv_cpu_sp; +extern void __start(void); + void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) { @@ -27,6 +30,13 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, riscv_cpu_sp = Z_KERNEL_STACK_BUFFER(stack) + sz; riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid; +#ifdef CONFIG_PM_CPU_OPS + if (pm_cpu_on(cpu_num, (uintptr_t)&__start)) { + printk("Failed to boot secondary CPU %d\n", cpu_num); + return; + } +#endif + while (riscv_cpu_wake_flag != 0U) { ; } From 3ec58ff749b6ed7f4817902d77f512b93f88e256 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Thu, 21 Sep 2023 16:17:35 +0200 Subject: [PATCH 2395/4498] libc/newlib: Add support for LLVM toolchain When Zephyr is compiled using LLVM toolchain, we don't need to link with libgcc to resolve libc dependencies. With this patch, the trick will be applied only when the GNU compiler is used. Otherwise, we will just link libc, which works for LLVM. Signed-off-by: Patryk Duda --- lib/libc/newlib/CMakeLists.txt | 64 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/lib/libc/newlib/CMakeLists.txt b/lib/libc/newlib/CMakeLists.txt index 856befd3811..6556a3e814c 100644 --- a/lib/libc/newlib/CMakeLists.txt +++ b/lib/libc/newlib/CMakeLists.txt @@ -37,39 +37,41 @@ zephyr_compile_definitions(_ANSI_SOURCE) # used by the network stack zephyr_compile_definitions(__LINUX_ERRNO_EXTENSIONS__) -# We are using -# - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}c -# - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}gcc -# - c -# in code below. -# This is needed because when linking with newlib on aarch64, then libgcc has a -# link dependency to libc (strchr), but libc also has dependencies to libgcc. -# -# CMake is capable of handling circular link dependencies for CMake defined -# static libraries, which can be further controlled using LINK_INTERFACE_MULTIPLICITY. -# However, libc and libgcc are not regular CMake libraries, and is seen as linker -# flags by CMake, and thus symbol de-duplications will be performed. -# CMake link options cannot be used, as that will place those libs first on the -# linker invocation. -Wl,--start-group is problematic as the placement of -lc -# and -lgcc is not guaranteed in case later libraries are also using -# -lc / -libbgcc as interface linker flags. -# -# Thus, we resort to use `${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}` -# as this ensures the uniqueness and thus avoids symbol de-duplication which means -# libc will be followed by libgcc, which is finally followed by libc again. +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + # We are using + # - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}c + # - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}gcc + # - c + # in code below. + # This is needed because when linking with newlib on aarch64, then libgcc has a + # link dependency to libc (strchr), but libc also has dependencies to libgcc. + # + # CMake is capable of handling circular link dependencies for CMake defined + # static libraries, which can be further controlled using LINK_INTERFACE_MULTIPLICITY. + # However, libc and libgcc are not regular CMake libraries, and is seen as linker + # flags by CMake, and thus symbol de-duplications will be performed. + # CMake link options cannot be used, as that will place those libs first on the + # linker invocation. -Wl,--start-group is problematic as the placement of -lc + # and -lgcc is not guaranteed in case later libraries are also using + # -lc / -libbgcc as interface linker flags. + # + # Thus, we resort to use `${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}` + # as this ensures the uniqueness and thus avoids symbol de-duplication which means + # libc will be followed by libgcc, which is finally followed by libc again. -list(JOIN CMAKE_C_LINKER_WRAPPER_FLAG "" linker_wrapper_string) + list(JOIN CMAKE_C_LINKER_WRAPPER_FLAG "" linker_wrapper_string) -zephyr_link_libraries( - m - "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}c" - ${LIBC_LIBRARY_DIR_FLAG} # NB: Optional - $<$:-u_printf_float> - $<$:-u_scanf_float> - # Lib C depends on libgcc. e.g. libc.a(lib_a-fvwrite.o) references __aeabi_idiv - "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}gcc" - c - ) + zephyr_link_libraries( + m + "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}c" + ${LIBC_LIBRARY_DIR_FLAG} # NB: Optional + $<$:-u_printf_float> + $<$:-u_scanf_float> + # Lib C depends on libgcc. e.g. libc.a(lib_a-fvwrite.o) references __aeabi_idiv + "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}gcc" + ) +endif() +zephyr_link_libraries(c) if(CONFIG_NEWLIB_LIBC_NANO) zephyr_link_libraries( From 9112c7e0ff166aa1167c25d8dae5eff111a9c386 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 29 Sep 2023 23:07:53 +0200 Subject: [PATCH 2396/4498] usb: device: cdc_acm: restart OUT transfer in only configured state When a usb_transfer is cancelled, the callback is finally invoked. Silly, there is no transfer status passed, and in the callback we can only check the size and device status. Reported-by: Alex Kaiser Signed-off-by: Johann Fischer --- subsys/usb/device/class/cdc_acm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/usb/device/class/cdc_acm.c b/subsys/usb/device/class/cdc_acm.c index 874e363711a..ed976750153 100644 --- a/subsys/usb/device/class/cdc_acm.c +++ b/subsys/usb/device/class/cdc_acm.c @@ -301,8 +301,10 @@ static void cdc_acm_read_cb(uint8_t ep, int size, void *priv) } done: - usb_transfer(ep, dev_data->rx_buf, sizeof(dev_data->rx_buf), - USB_TRANS_READ, cdc_acm_read_cb, dev_data); + if (dev_data->configured) { + usb_transfer(ep, dev_data->rx_buf, sizeof(dev_data->rx_buf), + USB_TRANS_READ, cdc_acm_read_cb, dev_data); + } } /** @@ -366,9 +368,9 @@ static void cdc_acm_do_cb(struct cdc_acm_dev_data_t *dev_data, case USB_DC_CONFIGURED: LOG_INF("Device configured"); if (!dev_data->configured) { + dev_data->configured = true; cdc_acm_read_cb(cfg->endpoint[ACM_OUT_EP_IDX].ep_addr, 0, dev_data); - dev_data->configured = true; } if (!dev_data->tx_ready) { dev_data->tx_ready = true; From c152e0980cf6ae45a1922c7ba2a59ebdcc419664 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Sat, 30 Sep 2023 00:12:48 +0200 Subject: [PATCH 2397/4498] usb: device: cdc_acm: block in uart_poll_out() routine According to the UART API documentation, implementation must block when the transceiver is full. For CDC ACM UART, TX ringbuffer can be considered as transceiver buffer/FIFO. Blocking when the USB subsystem is not ready is considered highly undesirable behavior. Blocking may also be undesirable when CDC ACM UART is used as a logging backend. Change the behavior of CDC ACM poll out to: - Block if the TX ring buffer is full, hw_flow_control property is enabled, and called from a non-ISR context. - Do not block if the USB subsystem is not ready, poll out implementation is called from an ISR context, or hw_flow_control property is disabled. Signed-off-by: Johann Fischer --- doc/connectivity/usb/device/usb_device.rst | 3 ++ subsys/usb/device/class/cdc_acm.c | 62 +++++++++++++--------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index 5e394a20457..c770c57bc79 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -82,6 +82,9 @@ But there are two important differences in behavior to a real UART controller: initialized and started, until then any data is discarded * If device is connected to the host, it still needs an application on the host side which requests the data +* The CDC ACM poll out implementation follows the API and blocks when the TX + ring buffer is full only if the hw-flow-control property is enabled and + called from a non-ISR context. The devicetree compatible property for CDC ACM UART is :dtcompatible:`zephyr,cdc-acm-uart`. diff --git a/subsys/usb/device/class/cdc_acm.c b/subsys/usb/device/class/cdc_acm.c index ed976750153..1530813ab47 100644 --- a/subsys/usb/device/class/cdc_acm.c +++ b/subsys/usb/device/class/cdc_acm.c @@ -126,6 +126,10 @@ struct cdc_acm_dev_data_t { bool suspended; /* CDC ACM paused flag */ bool rx_paused; + /* When flow_ctrl is set, poll out is blocked when the buffer is full, + * roughly emulating flow control. + */ + bool flow_ctrl; struct usb_dev_data common; }; @@ -899,17 +903,18 @@ static int cdc_acm_line_ctrl_get(const struct device *dev, static int cdc_acm_configure(const struct device *dev, const struct uart_config *cfg) { - ARG_UNUSED(dev); - ARG_UNUSED(cfg); - /* - * We cannot implement configure API because there is - * no notification of configuration changes provided - * for the Abstract Control Model and the UART controller - * is only emulated. - * However, it allows us to use CDC ACM UART together with - * subsystems like Modbus which require configure API for - * real controllers. - */ + struct cdc_acm_dev_data_t * const dev_data = dev->data; + + switch (cfg->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + dev_data->flow_ctrl = false; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + dev_data->flow_ctrl = true; + break; + default: + return -ENOTSUP; + } return 0; } @@ -969,8 +974,8 @@ static int cdc_acm_config_get(const struct device *dev, break; }; - /* USB CDC has no notion of flow control */ - cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE; + cfg->flow_ctrl = dev_data->flow_ctrl ? UART_CFG_FLOW_CTRL_RTS_CTS : + UART_CFG_FLOW_CTRL_NONE; return 0; } @@ -991,13 +996,17 @@ static int cdc_acm_poll_in(const struct device *dev, unsigned char *c) /* * @brief Output a character in polled mode. * - * The poll function looks similar to cdc_acm_fifo_fill() and - * tries to do the best to mimic behavior of a hardware UART controller - * without flow control. - * This function does not block, if the USB subsystem - * is not ready, no data is transferred to the buffer, that is, c is dropped. - * If the USB subsystem is ready and the buffer is full, the first character - * from the tx_ringbuf is removed to make room for the new character. + * According to the UART API, the implementation of this routine should block + * if the transmitter is full. But blocking when the USB subsystem is not ready + * is considered highly undesirable behavior. Blocking may also be undesirable + * when CDC ACM UART is used as a logging backend. + * + * The behavior of CDC ACM poll out is: + * - Block if the TX ring buffer is full, hw_flow_control property is enabled, + * and called from a non-ISR context. + * - Do not block if the USB subsystem is not ready, poll out implementation + * is called from an ISR context, or hw_flow_control property is disabled. + * */ static void cdc_acm_poll_out(const struct device *dev, unsigned char c) { @@ -1010,13 +1019,13 @@ static void cdc_acm_poll_out(const struct device *dev, unsigned char c) dev_data->tx_ready = false; - if (!ring_buf_put(dev_data->tx_ringbuf, &c, 1)) { - LOG_INF("Ring buffer full, drain buffer"); - if (!ring_buf_get(dev_data->tx_ringbuf, NULL, 1) || - !ring_buf_put(dev_data->tx_ringbuf, &c, 1)) { - LOG_ERR("Failed to drain buffer"); - return; + while (!ring_buf_put(dev_data->tx_ringbuf, &c, 1)) { + if (k_is_in_isr() || !dev_data->flow_ctrl) { + LOG_INF("Ring buffer full, discard %c", c); + break; } + + k_msleep(1); } /* Schedule with minimal timeout to make it possible to send more than @@ -1183,6 +1192,7 @@ static const struct uart_driver_api cdc_acm_driver_api = { .line_coding = CDC_ACM_DEFAULT_BAUDRATE, \ .rx_ringbuf = &cdc_acm_rx_rb_##x, \ .tx_ringbuf = &cdc_acm_tx_rb_##x, \ + .flow_ctrl = DT_INST_PROP_OR(x, hw_flow_control, false),\ }; #define DT_DRV_COMPAT zephyr_cdc_acm_uart From f41ca50ef3edcdecd0afb45c94f73cc2a585e78c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sun, 15 Oct 2023 21:03:53 +0200 Subject: [PATCH 2398/4498] dts: atmel: Add rtc device to atmel sam dtsi This commit adds the RTC device to the following atmel sam devicetrees: - sam3x.dtsi - sam4e.dtsi - sam4s.dtsi - same70.dtsi Signed-off-by: Bjarki Arge Andreasen --- dts/arm/atmel/sam3x.dtsi | 9 +++++++++ dts/arm/atmel/sam4e.dtsi | 9 +++++++++ dts/arm/atmel/sam4s.dtsi | 9 +++++++++ dts/arm/atmel/same70.dtsi | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/dts/arm/atmel/sam3x.dtsi b/dts/arm/atmel/sam3x.dtsi index f9dc33e458a..065c8920e17 100644 --- a/dts/arm/atmel/sam3x.dtsi +++ b/dts/arm/atmel/sam3x.dtsi @@ -246,6 +246,15 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 1>; user-nrst; }; + + rtc: rtc@400e1a60 { + compatible = "atmel,sam-rtc"; + reg = <0x400e1a60 0x100>; + interrupts = <2 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; + alarms-count = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/atmel/sam4e.dtsi b/dts/arm/atmel/sam4e.dtsi index ede65163ed0..122d904b899 100644 --- a/dts/arm/atmel/sam4e.dtsi +++ b/dts/arm/atmel/sam4e.dtsi @@ -303,6 +303,15 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 16>; status = "disabled"; }; + + rtc: rtc@400e1860 { + compatible = "atmel,sam-rtc"; + reg = <0x400e1860 0x100>; + interrupts = <2 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; + alarms-count = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/atmel/sam4s.dtsi b/dts/arm/atmel/sam4s.dtsi index bbbc05e8f7f..7c86d5a0475 100644 --- a/dts/arm/atmel/sam4s.dtsi +++ b/dts/arm/atmel/sam4s.dtsi @@ -240,6 +240,15 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 10>; status = "disabled"; }; + + rtc: rtc@400e1460 { + compatible = "atmel,sam-rtc"; + reg = <0x400e1460 0x100>; + interrupts = <2 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; + alarms-count = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 02fae555c25..56f0ba2c6ec 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -443,6 +443,15 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 1>; user-nrst; }; + + rtc: rtc@400e1860 { + compatible = "atmel,sam-rtc"; + reg = <0x400e1860 0x100>; + interrupts = <2 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; + alarms-count = <1>; + status = "disabled"; + }; }; }; From 99ce7d071fe63e47f9f6352e236987c47fe5b5e8 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sun, 15 Oct 2023 20:34:17 +0200 Subject: [PATCH 2399/4498] drivers: rtc: Add atmel sam series RTC driver This commit adds an RTC device driver for the atmel SAM series chips. Signed-off-by: Bjarki Arge Andreasen --- drivers/rtc/CMakeLists.txt | 1 + drivers/rtc/Kconfig | 1 + drivers/rtc/Kconfig.sam | 9 + drivers/rtc/rtc_sam.c | 712 ++++++++++++++++++++++++++++ dts/bindings/rtc/atmel,sam-rtc.yaml | 18 + 5 files changed, 741 insertions(+) create mode 100644 drivers/rtc/Kconfig.sam create mode 100644 drivers/rtc/rtc_sam.c create mode 100644 dts/bindings/rtc/atmel,sam-rtc.yaml diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index 2475174ac68..5addee4faed 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -15,3 +15,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_STM32 rtc_ll_stm32.c) zephyr_library_sources_ifdef(CONFIG_RTC_SHELL rtc_shell.c) zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c) zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c) +zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e480aae0388..f9da0c293d7 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -47,6 +47,7 @@ source "drivers/rtc/Kconfig.fake" source "drivers/rtc/Kconfig.pcf8523" source "drivers/rtc/Kconfig.pcf8563" source "drivers/rtc/Kconfig.mc146818" +source "drivers/rtc/Kconfig.sam" source "drivers/rtc/Kconfig.stm32" source "drivers/rtc/Kconfig.smartbond" diff --git a/drivers/rtc/Kconfig.sam b/drivers/rtc/Kconfig.sam new file mode 100644 index 00000000000..5968f66bc42 --- /dev/null +++ b/drivers/rtc/Kconfig.sam @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +config RTC_ATMEL_SAM + bool "Atmel SAM RTC driver" + default y + depends on DT_HAS_ATMEL_SAM_RTC_ENABLED + help + Atmel Real-Time Clock (RTC) driver used on SAM SoC series. diff --git a/drivers/rtc/rtc_sam.c b/drivers/rtc/rtc_sam.c new file mode 100644 index 00000000000..059a2b1b33e --- /dev/null +++ b/drivers/rtc/rtc_sam.c @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT atmel_sam_rtc + +#include +#include +#include +#include +#include + +#include +#include + +#define RTC_SAM_REG_GET_FIELD(value, field) \ + ((RTC_##field##_Msk & value) >> RTC_##field##_Pos) + +#define RTC_SAM_WPMR_DISABLE 0x52544300 +#define RTC_SAM_WPMR_ENABLE 0x52544301 + +#define RTC_SAM_CALIBRATE_PPB_MAX (1950000) +#define RTC_SAM_CALIBRATE_PPB_MIN (-1950000) +#define RTC_SAM_CALIBRATE_PPB_QUANTA (1500) +#define RTC_SAM_CALIBRATE_PPB_LOW_SCALE (30500) + +typedef void (*rtc_sam_irq_init_fn_ptr)(void); + +struct rtc_sam_config { + Rtc *regs; + uint16_t irq_num; + rtc_sam_irq_init_fn_ptr irq_init_fn_ptr; +}; + +struct rtc_sam_data { +#ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_callback; + void *alarm_user_data; +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + rtc_update_callback update_callback; + void *update_user_data; +#endif /* CONFIG_RTC_UPDATE */ + struct k_spinlock lock; + struct k_sem cr_sec_evt_sem; + struct k_sem cr_upd_ack_sem; +}; + +static void rtc_sam_disable_wp(void) +{ + REG_RTC_WPMR = RTC_SAM_WPMR_DISABLE; +} + +static void rtc_sam_enable_wp(void) +{ + REG_RTC_WPMR = RTC_SAM_WPMR_ENABLE; +} + +static bool rtc_sam_validate_tm(const struct rtc_time *timeptr, uint32_t mask) +{ + if ((mask & RTC_ALARM_TIME_MASK_SECOND) && + (timeptr->tm_sec < 0 || timeptr->tm_sec > 59)) { + return false; + } + + if ((mask & RTC_ALARM_TIME_MASK_MINUTE) && + (timeptr->tm_min < 0 || timeptr->tm_min > 59)) { + return false; + } + + if ((mask & RTC_ALARM_TIME_MASK_HOUR) && + (timeptr->tm_hour < 0 || timeptr->tm_hour > 23)) { + return false; + } + + if ((mask & RTC_ALARM_TIME_MASK_MONTH) && + (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)) { + return false; + } + + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && + (timeptr->tm_mday < 1 || timeptr->tm_mday > 31)) { + return false; + } + + if ((mask & RTC_ALARM_TIME_MASK_YEAR) && + (timeptr->tm_year < 0 || timeptr->tm_year > 199)) { + return false; + } + + return true; +} + +static uint32_t rtc_sam_timr_from_tm(const struct rtc_time *timeptr) +{ + uint32_t timr; + + timr = RTC_TIMR_SEC(bin2bcd(timeptr->tm_sec)); + timr |= RTC_TIMR_MIN(bin2bcd(timeptr->tm_min)); + timr |= RTC_TIMR_HOUR(bin2bcd(timeptr->tm_hour)); + + return timr; +} + +static uint32_t rtc_sam_calr_from_tm(const struct rtc_time *timeptr) +{ + uint32_t calr; + uint8_t centuries; + uint8_t years; + + calr = RTC_CALR_DATE(bin2bcd(timeptr->tm_mday)); + calr |= RTC_CALR_MONTH(bin2bcd(timeptr->tm_mon + 1)); + centuries = (uint8_t)((timeptr->tm_year / 100) + 19); + years = (uint8_t)((timeptr->tm_year % 100)); + calr |= RTC_CALR_CENT(bin2bcd(centuries)); + calr |= RTC_CALR_YEAR(bin2bcd(years)); + calr |= RTC_CALR_DAY(bin2bcd(timeptr->tm_wday + 1)); + return calr; +} + +static int rtc_sam_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + if (rtc_sam_validate_tm(timeptr, UINT32_MAX) == false) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + k_sem_reset(&data->cr_sec_evt_sem); + k_sem_take(&data->cr_sec_evt_sem, K_MSEC(1100)); + k_sem_reset(&data->cr_upd_ack_sem); + + /* Enable update acknowledge interrupt */ + regs->RTC_IER = RTC_IER_ACKEN; + + rtc_sam_disable_wp(); + + /* Request update */ + regs->RTC_CR = (RTC_CR_UPDTIM | RTC_CR_UPDCAL); + + /* Await update acknowledge */ + if (k_sem_take(&data->cr_upd_ack_sem, K_MSEC(1100)) < 0) { + regs->RTC_CR = 0; + + rtc_sam_enable_wp(); + + /* Disable update acknowledge interrupt */ + regs->RTC_IDR = RTC_IDR_ACKDIS; + + k_spin_unlock(&data->lock, key); + return -EAGAIN; + } + + regs->RTC_TIMR = rtc_sam_timr_from_tm(timeptr); + regs->RTC_CALR = rtc_sam_calr_from_tm(timeptr); + regs->RTC_CR = 0; + rtc_sam_enable_wp(); + regs->RTC_IDR = RTC_IDR_ACKDIS; + k_spin_unlock(&data->lock, key); + return 0; +} + +static int rtc_sam_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + uint32_t timr0; + uint32_t calr0; + uint32_t timr1; + uint32_t calr1; + + /* Validate time and date */ + if (regs->RTC_VER & (RTC_VER_NVTIM | RTC_VER_NVCAL)) { + return -ENODATA; + } + + /* Read until synchronized (registers updated async) */ + while (1) { + timr0 = regs->RTC_TIMR; + calr0 = regs->RTC_CALR; + timr1 = regs->RTC_TIMR; + calr1 = regs->RTC_CALR; + + if ((timr0 == timr1) && (calr0 == calr1)) { + break; + } + } + + timeptr->tm_sec = bcd2bin(RTC_SAM_REG_GET_FIELD(timr0, TIMR_SEC)); + timeptr->tm_min = bcd2bin(RTC_SAM_REG_GET_FIELD(timr0, TIMR_MIN)); + timeptr->tm_hour = bcd2bin(RTC_SAM_REG_GET_FIELD(timr0, TIMR_HOUR)); + timeptr->tm_mday = bcd2bin(RTC_SAM_REG_GET_FIELD(calr0, CALR_DATE)); + timeptr->tm_mon = bcd2bin(RTC_SAM_REG_GET_FIELD(calr0, CALR_MONTH)) - 1; + + timeptr->tm_year = bcd2bin(RTC_SAM_REG_GET_FIELD(calr0, CALR_YEAR)); + timeptr->tm_year += ((int)bcd2bin(RTC_SAM_REG_GET_FIELD(calr0, CALR_CENT))) * 100; + timeptr->tm_year -= 1900; + + timeptr->tm_wday = bcd2bin(RTC_SAM_REG_GET_FIELD(calr0, CALR_DAY)) - 1; + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + timeptr->tm_nsec = 0; + return 0; +} + +static void rtc_sam_isr(const struct device *dev) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + uint32_t sr = regs->RTC_SR; + + if (sr & RTC_SR_ACKUPD) { + regs->RTC_SCCR = RTC_SCCR_ACKCLR; + k_sem_give(&data->cr_upd_ack_sem); + } + +#ifdef CONFIG_RTC_ALARM + if (sr & RTC_SR_ALARM) { + regs->RTC_SCCR = RTC_SCCR_ALRCLR; + if (data->alarm_callback != NULL) { + data->alarm_callback(dev, 0, data->alarm_user_data); + } + } +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE + if (sr & RTC_SR_SEC) { + regs->RTC_SCCR = RTC_SCCR_SECCLR; + if (data->update_callback != NULL) { + data->update_callback(dev, data->update_user_data); + } + + k_sem_give(&data->cr_sec_evt_sem); + } +#endif /* CONFIG_RTC_UPDATE */ +} + +#ifdef CONFIG_RTC_ALARM +static uint16_t rtc_sam_alarm_get_supported_mask(void) +{ + return (RTC_ALARM_TIME_MASK_SECOND + | RTC_ALARM_TIME_MASK_MINUTE + | RTC_ALARM_TIME_MASK_HOUR + | RTC_ALARM_TIME_MASK_MONTHDAY + | RTC_ALARM_TIME_MASK_MONTH); +} + +static uint32_t rtc_atmel_timalr_from_tm(const struct rtc_time *timeptr, uint32_t mask) +{ + uint32_t timalr = 0; + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + timalr |= RTC_TIMALR_SECEN; + timalr |= RTC_TIMALR_SEC(bin2bcd(timeptr->tm_sec)); + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + timalr |= RTC_TIMALR_MINEN; + timalr |= RTC_TIMALR_MIN(bin2bcd(timeptr->tm_min)); + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + timalr |= RTC_TIMALR_HOUREN; + timalr |= RTC_TIMALR_HOUR(bin2bcd(timeptr->tm_hour)); + } + + return timalr; +} + +static uint32_t rtc_atmel_calalr_from_tm(const struct rtc_time *timeptr, uint32_t mask) +{ + uint32_t calalr = RTC_CALALR_MONTH(1) | RTC_CALALR_DATE(1); + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + calalr |= RTC_CALALR_MTHEN; + calalr |= RTC_CALALR_MONTH(bin2bcd(timeptr->tm_mon + 1)); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + calalr |= RTC_CALALR_DATEEN; + calalr |= RTC_CALALR_DATE(bin2bcd(timeptr->tm_mday)); + } + + return calalr; +} + +static uint32_t rtc_sam_alarm_mask_from_timalr(uint32_t timalr) +{ + uint32_t mask = 0; + + if (timalr & RTC_TIMALR_SECEN) { + mask |= RTC_ALARM_TIME_MASK_SECOND; + } + + if (timalr & RTC_TIMALR_MINEN) { + mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + + if (timalr & RTC_TIMALR_HOUREN) { + mask |= RTC_ALARM_TIME_MASK_HOUR; + } + + return mask; +} + +static uint32_t rtc_sam_alarm_mask_from_calalr(uint32_t calalr) +{ + uint32_t mask = 0; + + if (calalr & RTC_CALALR_MTHEN) { + mask |= RTC_ALARM_TIME_MASK_MONTH; + } + + if (calalr & RTC_CALALR_DATEEN) { + mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + + return mask; +} + +static void rtc_sam_tm_from_timalr_calalr(struct rtc_time *timeptr, uint32_t mask, + uint32_t timalr, uint32_t calalr) +{ + memset(timeptr, 0x00, sizeof(*timeptr)); + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + timeptr->tm_sec = bcd2bin(RTC_SAM_REG_GET_FIELD(timalr, TIMALR_SEC)); + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + timeptr->tm_min = bcd2bin(RTC_SAM_REG_GET_FIELD(timalr, TIMALR_MIN)); + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + timeptr->tm_hour = bcd2bin(RTC_SAM_REG_GET_FIELD(timalr, TIMALR_HOUR)); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + timeptr->tm_mday = bcd2bin(RTC_SAM_REG_GET_FIELD(calalr, CALALR_DATE)); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + timeptr->tm_mon = bcd2bin(RTC_SAM_REG_GET_FIELD(calalr, CALALR_MONTH)) - 1; + } +} + +static int rtc_sam_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + ARG_UNUSED(dev); + ARG_UNUSED(id); + + *mask = rtc_sam_alarm_get_supported_mask(); + return 0; +} + +static int rtc_sam_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + uint32_t timalr; + uint32_t calalr; + uint32_t mask_supported; + + mask_supported = rtc_sam_alarm_get_supported_mask(); + + if ((id != 0)) { + return -EINVAL; + } + + if ((mask > 0) && (timeptr == NULL)) { + return -EINVAL; + } + + if (mask & ~mask_supported) { + return -EINVAL; + } + + if (rtc_sam_validate_tm(timeptr, mask) == false) { + return -EINVAL; + } + + timalr = rtc_atmel_timalr_from_tm(timeptr, mask); + calalr = rtc_atmel_calalr_from_tm(timeptr, mask); + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_disable(config->irq_num); + rtc_sam_disable_wp(); + + /* Set RTC alarm time */ + regs->RTC_TIMALR = timalr; + regs->RTC_CALALR = calalr; + + rtc_sam_enable_wp(); + + /* Clear alarm pending status */ + regs->RTC_SCCR = RTC_SCCR_ALRCLR; + + irq_enable(config->irq_num); + k_spin_unlock(&data->lock, key); + return 0; +} + +static int rtc_sam_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + uint32_t timalr; + uint32_t calalr; + + if ((id != 0) || (mask == NULL) || (timeptr == NULL)) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + timalr = regs->RTC_TIMALR; + calalr = regs->RTC_CALALR; + + k_spin_unlock(&data->lock, key); + + *mask = rtc_sam_alarm_mask_from_timalr(timalr); + *mask |= rtc_sam_alarm_mask_from_calalr(calalr); + + rtc_sam_tm_from_timalr_calalr(timeptr, *mask, timalr, calalr); + return 0; +} + +static int rtc_sam_alarm_is_pending(const struct device *dev, uint16_t id) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + if (id != 0) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if ((regs->RTC_SR & RTC_SR_ALARM) == 0) { + k_spin_unlock(&data->lock, key); + + return 0; + } + + regs->RTC_SCCR = RTC_SCCR_ALRCLR; + k_spin_unlock(&data->lock, key); + return 1; +} + +static int rtc_sam_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + if (id != 0) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_disable(config->irq_num); + data->alarm_callback = callback; + data->alarm_user_data = user_data; + + if (data->alarm_callback) { + regs->RTC_IER = RTC_IER_ALREN; + } else { + regs->RTC_IDR = RTC_IDR_ALRDIS; + } + + irq_enable(config->irq_num); + k_spin_unlock(&data->lock, key); + return 0; +} +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE +static int rtc_sam_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_disable(config->irq_num); + + data->update_callback = callback; + data->update_user_data = user_data; + + if (data->update_callback) { + regs->RTC_IER = RTC_IER_SECEN; + } else { + regs->RTC_IDR = RTC_IDR_SECDIS; + } + + irq_enable(config->irq_num); + + k_spin_unlock(&data->lock, key); + + return 0; +} +#endif /* CONFIG_RTC_UPDATE */ + +#ifdef CONFIG_RTC_CALIBRATION +static int rtc_sam_set_calibration(const struct device *dev, int32_t calibration) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + bool negative_calibration; + bool high_calibration; + uint32_t slow_clock_calibration; + uint32_t mr; + + if ((calibration < RTC_SAM_CALIBRATE_PPB_MIN) || + (calibration > RTC_SAM_CALIBRATE_PPB_MAX)) { + return -EINVAL; + } + + /* The value written to the register is absolute */ + if (calibration < 0) { + negative_calibration = true; + calibration = -calibration; + } else { + negative_calibration = false; + } + + /* + * Formula adapted from + * Atmel-11157-32-bit-Cortex-M4-Microcontroller-SAM4E16-SAM4E8_Datasheet.pdf + * section 15.6.2 + * + * Formula if RTC_MR_HIGHPPM is 0 + * + * RTC_MR_CORRECTION = (3906 / (20 * ppm)) - 1 + * + * Formula if RTC_MR_HIGHPPM is 1 + * + * RTC_MR_CORRECTION = (3906 / ppm) - 1 + * + * Since we are working with ppb, we adapt the formula by increasing the + * terms of the fraction by 1000, turning the ppm into ppb + * + * Adapted formula if RTC_MR_HIGHPPM is 0 + * + * RTC_MR_CORRECTION = (3906000 / (20 * ppb)) - 1 + * + * Adapted formula if RTC_MR_HIGHPPM is 1 + * + * RTC_MR_CORRECTION = (3906000 / ppb) - 1 + */ + if (calibration < RTC_SAM_CALIBRATE_PPB_QUANTA) { + high_calibration = false; + slow_clock_calibration = 0; + } else if (calibration < RTC_SAM_CALIBRATE_PPB_LOW_SCALE) { + high_calibration = false; + slow_clock_calibration = (uint32_t)((3906000 / (20 * calibration)) - 1); + } else { + high_calibration = true; + slow_clock_calibration = (uint32_t)((3906000 / calibration) - 1); + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + rtc_sam_disable_wp(); + + mr = regs->RTC_MR; + + if (negative_calibration == true) { + mr |= RTC_MR_NEGPPM; + } else { + mr &= ~RTC_MR_NEGPPM; + } + + mr &= ~RTC_MR_CORRECTION_Msk; + mr |= RTC_MR_CORRECTION(slow_clock_calibration); + + if (high_calibration == true) { + mr |= RTC_MR_HIGHPPM; + } else { + mr &= ~RTC_MR_HIGHPPM; + } + + regs->RTC_MR = mr; + + rtc_sam_enable_wp(); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int rtc_sam_get_calibration(const struct device *dev, int32_t *calibration) +{ + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + uint32_t mr; + int32_t correction; + + if (calibration == NULL) { + return -EINVAL; + } + + mr = regs->RTC_MR; + + correction = (int32_t)RTC_SAM_REG_GET_FIELD(mr, MR_CORRECTION); + + /* Formula documented in rtc_sam_set_calibration() */ + if (correction == 0) { + *calibration = 0; + } else if (mr & RTC_MR_HIGHPPM) { + *calibration = 3906000 / (correction + 1); + } else { + *calibration = 3906000 / ((correction + 1) * 20); + } + + if (mr & RTC_MR_NEGPPM) { + *calibration = -*calibration; + } + + return 0; +} +#endif /* CONFIG_RTC_CALIBRATION */ + +static struct rtc_driver_api rtc_sam_driver_api = { + .set_time = rtc_sam_set_time, + .get_time = rtc_sam_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rtc_sam_alarm_get_supported_fields, + .alarm_set_time = rtc_sam_alarm_set_time, + .alarm_get_time = rtc_sam_alarm_get_time, + .alarm_is_pending = rtc_sam_alarm_is_pending, + .alarm_set_callback = rtc_sam_alarm_set_callback, +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + .update_set_callback = rtc_sam_update_set_callback, +#endif /* CONFIG_RTC_UPDATE */ +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rtc_sam_set_calibration, + .get_calibration = rtc_sam_get_calibration, +#endif /* CONFIG_RTC_CALIBRATION */ +}; + +static int rtc_sam_init(const struct device *dev) +{ + struct rtc_sam_data *data = dev->data; + const struct rtc_sam_config *config = dev->config; + Rtc *regs = config->regs; + + rtc_sam_disable_wp(); + regs->RTC_MR &= ~(RTC_MR_HRMOD | RTC_MR_PERSIAN); + regs->RTC_CR = 0; + rtc_sam_enable_wp(); + regs->RTC_IDR = (RTC_IDR_ACKDIS + | RTC_IDR_ALRDIS + | RTC_IDR_SECDIS + | RTC_IDR_TIMDIS + | RTC_IDR_CALDIS + | RTC_IDR_TDERRDIS); + + k_sem_init(&data->cr_sec_evt_sem, 0, 1); + k_sem_init(&data->cr_upd_ack_sem, 0, 1); + config->irq_init_fn_ptr(); + irq_enable(config->irq_num); + return 0; +} + +#define RTC_SAM_DEVICE(id) \ + static void rtc_sam_irq_init_##id(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), \ + rtc_sam_isr, DEVICE_DT_INST_GET(id), 0); \ + } \ + \ + static const struct rtc_sam_config rtc_sam_config_##id = { \ + .regs = (Rtc *)DT_INST_REG_ADDR(id), \ + .irq_num = DT_INST_IRQN(id), \ + .irq_init_fn_ptr = rtc_sam_irq_init_##id, \ + }; \ + \ + static struct rtc_sam_data rtc_sam_data_##id; \ + \ + DEVICE_DT_INST_DEFINE(id, rtc_sam_init, NULL, \ + &rtc_sam_data_##id, \ + &rtc_sam_config_##id, POST_KERNEL, \ + CONFIG_RTC_INIT_PRIORITY, \ + &rtc_sam_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RTC_SAM_DEVICE); diff --git a/dts/bindings/rtc/atmel,sam-rtc.yaml b/dts/bindings/rtc/atmel,sam-rtc.yaml new file mode 100644 index 00000000000..7e787ebaf10 --- /dev/null +++ b/dts/bindings/rtc/atmel,sam-rtc.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM family RTC device + +compatible: "atmel,sam-rtc" + +include: rtc-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true From 26a403d629f0d756b5af8732a690f1408ea6391d Mon Sep 17 00:00:00 2001 From: Steffen Jahnke Date: Tue, 26 Sep 2023 11:55:18 +0000 Subject: [PATCH 2400/4498] boards: arm: Add PAN1783 evaluation board The PAN1783 evaluation board is a development tool for the nRF5340 from Nordic Semiconductor. Signed-off-by: Steffen Jahnke --- boards/arm/pan1783_evb/CMakeLists.txt | 7 + boards/arm/pan1783_evb/Kconfig | 53 ++++ boards/arm/pan1783_evb/Kconfig.board | 12 + boards/arm/pan1783_evb/Kconfig.defconfig | 31 ++ boards/arm/pan1783_evb/board.cmake | 12 + .../arm/pan1783_evb/doc/img/pan1783_evb.jpg | Bin 0 -> 57564 bytes boards/arm/pan1783_evb/doc/index.rst | 55 ++++ boards/arm/pan1783_evb/pan1783_evb_cpuapp.dts | 21 ++ .../arm/pan1783_evb/pan1783_evb_cpuapp.yaml | 21 ++ .../pan1783_evb_cpuapp_common-pinctrl.dtsi | 120 +++++++ .../pan1783_evb_cpuapp_common.dtsi | 300 ++++++++++++++++++ .../pan1783_evb/pan1783_evb_cpuapp_defconfig | 25 ++ .../pan1783_evb_cpuapp_partition_conf.dtsi | 38 +++ .../pan1783_evb_cpunet-pinctrl.dtsi | 61 ++++ boards/arm/pan1783_evb/pan1783_evb_cpunet.dts | 215 +++++++++++++ .../arm/pan1783_evb/pan1783_evb_cpunet.yaml | 14 + .../pan1783_evb/pan1783_evb_cpunet_defconfig | 18 ++ .../pan1783_evb/pan1783_evb_cpunet_reset.c | 44 +++ ...pan1783_evb_shared_sram_planning_conf.dtsi | 30 ++ boards/arm/pan1783_evb/pre_dt_board.cmake | 8 + 20 files changed, 1085 insertions(+) create mode 100644 boards/arm/pan1783_evb/CMakeLists.txt create mode 100644 boards/arm/pan1783_evb/Kconfig create mode 100644 boards/arm/pan1783_evb/Kconfig.board create mode 100644 boards/arm/pan1783_evb/Kconfig.defconfig create mode 100644 boards/arm/pan1783_evb/board.cmake create mode 100644 boards/arm/pan1783_evb/doc/img/pan1783_evb.jpg create mode 100644 boards/arm/pan1783_evb/doc/index.rst create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp.dts create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp.yaml create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp_common-pinctrl.dtsi create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp_defconfig create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpuapp_partition_conf.dtsi create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpunet-pinctrl.dtsi create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpunet.dts create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpunet.yaml create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpunet_defconfig create mode 100644 boards/arm/pan1783_evb/pan1783_evb_cpunet_reset.c create mode 100644 boards/arm/pan1783_evb/pan1783_evb_shared_sram_planning_conf.dtsi create mode 100644 boards/arm/pan1783_evb/pre_dt_board.cmake diff --git a/boards/arm/pan1783_evb/CMakeLists.txt b/boards/arm/pan1783_evb/CMakeLists.txt new file mode 100644 index 00000000000..f8bc359b603 --- /dev/null +++ b/boards/arm/pan1783_evb/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +if ((CONFIG_BOARD_PAN1783_EVB_CPUAPP) AND (CONFIG_BOARD_ENABLE_CPUNET)) +zephyr_library() +zephyr_library_sources(pan1783_evb_cpunet_reset.c) +endif() diff --git a/boards/arm/pan1783_evb/Kconfig b/boards/arm/pan1783_evb/Kconfig new file mode 100644 index 00000000000..1e4045b7798 --- /dev/null +++ b/boards/arm/pan1783_evb/Kconfig @@ -0,0 +1,53 @@ +# PAN1783 EVB board configuration + +# Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PAN1783_EVB_CPUAPP + +config BOARD_ENABLE_DCDC_APP + bool "Application MCU DCDC converter" + select SOC_DCDC_NRF53X_APP + default y + +config BOARD_ENABLE_DCDC_NET + bool "Network MCU DCDC converter" + select SOC_DCDC_NRF53X_NET + default y + +config BOARD_ENABLE_DCDC_HV + bool "High Voltage DCDC converter" + select SOC_DCDC_NRF53X_HV + default y + +config BOARD_ENABLE_CPUNET + bool "NRF53 Network MCU" + select SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 if \ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GPIO_FORWARDER)) + help + This option enables releasing the Network 'force off' signal, which + as a consequence will power up the Network MCU during system boot. + Additionally, the option allocates GPIO pins that will be used by UARTE + of the Network MCU. + default y if (BT || NRF_802154_SER_HOST) + +config DOMAIN_CPUNET_BOARD + string + default "pan1783_evb_cpunet" + depends on BOARD_ENABLE_CPUNET + help + The board which will be used for CPUNET domain when creating a multi + image application where one or more images should be located on + another board. For example hci_rpmsg on the nRF5340_cpunet for + Bluetooth applications. + +endif # BOARD_PAN1783_EVB_CPUAPP + +config DOMAIN_CPUAPP_BOARD + string + default "pan1783_evb_cpuapp" + depends on BOARD_PAN1783_EVB_CPUNET + help + The board which will be used for CPUAPP domain when creating a multi + image application where one or more images should be located on + another board. diff --git a/boards/arm/pan1783_evb/Kconfig.board b/boards/arm/pan1783_evb/Kconfig.board new file mode 100644 index 00000000000..d66c99aac36 --- /dev/null +++ b/boards/arm/pan1783_evb/Kconfig.board @@ -0,0 +1,12 @@ +# PAN1783 EVB board configuration + +# Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PAN1783_EVB_CPUAPP + bool "PAN1783 EVB (nRF5340) Application MCU" + depends on SOC_NRF5340_CPUAPP_QKAA + +config BOARD_PAN1783_EVB_CPUNET + bool "PAN1783 EVB (NRF5340) Network MCU" + depends on SOC_NRF5340_CPUNET_QKAA diff --git a/boards/arm/pan1783_evb/Kconfig.defconfig b/boards/arm/pan1783_evb/Kconfig.defconfig new file mode 100644 index 00000000000..b3d7195199d --- /dev/null +++ b/boards/arm/pan1783_evb/Kconfig.defconfig @@ -0,0 +1,31 @@ +# PAN1783 EVB board configuration + +# Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "pan1783_evb_cpuapp" if BOARD_PAN1783_EVB_CPUAPP + +config BOARD + default "pan1783_evb_cpunet" if BOARD_PAN1783_EVB_CPUNET + +config MBOX_NRFX_IPC + default MBOX + +if BOARD_PAN1783_EVB_CPUAPP + +choice BT_HCI_BUS_TYPE + default BT_RPMSG if BT +endchoice + +config HEAP_MEM_POOL_SIZE + default 4096 if BT_RPMSG + +endif # BOARD_PAN1783_EVB_CPUAPP + +if BOARD_PAN1783_EVB_CPUNET + +config BT_CTLR + default y if BT + +endif # BOARD_PAN1783_EVB_CPUNET diff --git a/boards/arm/pan1783_evb/board.cmake b/boards/arm/pan1783_evb/board.cmake new file mode 100644 index 00000000000..f75151ecb94 --- /dev/null +++ b/boards/arm/pan1783_evb/board.cmake @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_PAN1783_EVB_CPUAPP) +board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") +endif() + +if(CONFIG_BOARD_PAN1783_EVB_CPUNET) +board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/pan1783_evb/doc/img/pan1783_evb.jpg b/boards/arm/pan1783_evb/doc/img/pan1783_evb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..273253cfcf95df400908654c03accc1f7336bc33 GIT binary patch literal 57564 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

q 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 +#include "pan1783_evb_cpuapp_common.dtsi" + +/ { + model = "Panasonic PAN1783 EVB (NRF5340) Application"; + compatible = "panasonic,pan1783-evb-cpuapp"; + + chosen { + zephyr,sram = &sram0_image; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + }; +}; diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp.yaml b/boards/arm/pan1783_evb/pan1783_evb_cpuapp.yaml new file mode 100644 index 00000000000..a0242b83252 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp.yaml @@ -0,0 +1,21 @@ +identifier: pan1783_evb_cpuapp +name: PAN1783-EVB-application-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 448 +flash: 1024 +supported: + - gpio + - i2c + - i2s + - pwm + - watchdog + - usb_cdc + - usb_device + - netif:openthread + - gpio +vendor: panasonic diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common-pinctrl.dtsi b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common-pinctrl.dtsi new file mode 100644 index 00000000000..cdafbaf2cdc --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common-pinctrl.dtsi @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c1_default: i2c1_default { + group1 { + psels = , + ; + }; + }; + + i2c1_sleep: i2c1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = ; + }; + }; + + pwm0_sleep: pwm0_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; + + qspi_default: qspi_default { + group1 { + psels = , + , + , + , + , + ; + nordic,drive-mode = ; + }; + }; + + qspi_sleep: qspi_sleep { + group1 { + psels = , + , + , + , + ; + low-power-enable; + }; + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; + }; + + uart1_default: uart1_default { + group1 { + psels = ; + }; + group2 { + psels = ; + bias-pull-up; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + spi4_default: spi4_default { + group1 { + psels = , + , + ; + }; + }; + + spi4_sleep: spi4_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi new file mode 100644 index 00000000000..217dd0782a2 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "pan1783_evb_cpuapp_common-pinctrl.dtsi" +#include + +/ { + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + evb_led1: evb_led_1 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "LED1 on EVB"; + }; + evb_led2: evb_led_2 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "LED2 on EVB"; + }; + evb_led3: evb_led_3 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "LED3 on EVB"; + }; + evb_led4: evb_led_4 { + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + label = "LED4 on EVB"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_evb_led1: pwm_evb_led_1 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; + + buttons { + compatible = "gpio-keys"; + evb_sw1: evb_sw_1 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1 on EVB"; + zephyr,code = ; + }; + evb_sw2: evb_sw_2 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2 on EVB"; + zephyr,code = ; + }; + evb_sw3: evb_sw_3 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3 on EVB"; + zephyr,code = ; + }; + evb_sw4: evb_sw_4 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW4 on EVB"; + zephyr,code = ; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 4 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio1 12 0>, /* CS */ + <3 0 &gpio1 15 0>, /* SCK */ + <4 0 &gpio1 14 0>, /* MISO */ + <5 0 &gpio1 13 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 7 0>, /* PWM */ + <7 0 &gpio1 4 0>, /* INT */ + <8 0 &gpio1 0 0>, /* RX */ + <9 0 &gpio1 1 0>, /* TX */ + <10 0 &gpio1 3 0>, /* SCL */ + <11 0 &gpio1 2 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 4 0>, /* A0 */ + <1 0 &gpio0 5 0>, /* A1 */ + <2 0 &gpio0 6 0>, /* A2 */ + <3 0 &gpio0 7 0>, /* A3 */ + <4 0 &gpio0 25 0>, /* A4 */ + <5 0 &gpio0 26 0>, /* A5 */ + <6 0 &gpio1 0 0>, /* D0 */ + <7 0 &gpio1 1 0>, /* D1 */ + <8 0 &gpio1 4 0>, /* D2 */ + <9 0 &gpio1 5 0>, /* D3 */ + <10 0 &gpio1 6 0>, /* D4 */ + <11 0 &gpio1 7 0>, /* D5 */ + <12 0 &gpio1 8 0>, /* D6 */ + <13 0 &gpio1 9 0>, /* D7 */ + <14 0 &gpio1 10 0>, /* D8 */ + <15 0 &gpio1 11 0>, /* D9 */ + <16 0 &gpio1 12 0>, /* D10 */ + <17 0 &gpio1 13 0>, /* D11 */ + <18 0 &gpio1 14 0>, /* D12 */ + <19 0 &gpio1 15 0>, /* D13 */ + <20 0 &gpio1 2 0>, /* D14 */ + <21 0 &gpio1 3 0>; /* D15 */ + }; + + arduino_adc: analog-connector { + compatible = "arduino,uno-adc"; + #io-channel-cells = <1>; + io-channel-map = <0 &adc 0>, /* A0 = P0.4 = AIN0 */ + <1 &adc 1>, /* A1 = P0.5 = AIN1 */ + <2 &adc 2>, /* A2 = P0.6 = AIN2 */ + <3 &adc 3>, /* A3 = P0.7 = AIN3 */ + <4 &adc 4>, /* A4 = P0.25 = AIN4 */ + <5 &adc 5>; /* A5 = P0.26 = AIN5 */ + }; + + gpio_fwd: nrf-gpio-forwarder { + compatible = "nordic,nrf-gpio-forwarder"; + status = "disabled"; + uart { + gpios = <&gpio0 20 0>, <&gpio0 22 0>, <&gpio0 11 0>, <&gpio0 10 0>; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &evb_led1; + led1 = &evb_led2; + led2 = &evb_led3; + led3 = &evb_led4; + pwm-led0 = &pwm_evb_led1; + sw0 = &evb_sw1; + sw1 = &evb_sw2; + sw2 = &evb_sw3; + sw3 = &evb_sw4; + bootloader-led0 = &evb_led1; + mcuboot-button0 = &evb_sw1; + mcuboot-led0 = &evb_led1; + watchdog0 = &wdt0; + spi-flash0 = &mx25r64; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c1 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&qspi { + status = "okay"; + pinctrl-0 = <&qspi_default>; + pinctrl-1 = <&qspi_sleep>; + pinctrl-names = "default", "sleep"; + mx25r64: mx25r6435f@0 { + compatible = "nordic,qspi-nor"; + reg = <0>; + /* MX25R64 supports only pp and pp4io */ + writeoc = "pp4io"; + /* MX25R64 supports all readoc options */ + readoc = "read4io"; + sck-frequency = <8000000>; + jedec-id = [ c2 28 17 ]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + size = <67108864>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + }; +}; + +arduino_serial: &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_i2c: &i2c1 {}; + +arduino_spi: &spi4 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + pinctrl-0 = <&spi4_default>; + pinctrl-1 = <&spi4_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot1_partition: partition@80000 { + label = "image-1"; + }; + /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&ieee802154 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_image: image@20000000 { + /* Zephyr image(s) memory */ + }; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "pan1783_evb_cpuapp_partition_conf.dtsi" diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_defconfig b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_defconfig new file mode 100644 index 00000000000..b709d16dc54 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_defconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_PAN1783_EVB_CPUAPP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# clock config +CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y +CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_partition_conf.dtsi b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_partition_conf.dtsi new file mode 100644 index 00000000000..50e32748bec --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_partition_conf.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for pan1783_evb CPUAPP (Application MCU). + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot1_partition { + reg = <0x00080000 0x40000>; +}; + +/* Default SRAM planning when building for nRF5340 + * - Lowest 448 kB SRAM allocated to Secure image (sram0_s) + * - Upper 64 kB SRAM allocated as Shared memory (sram0_shared) + * (see pan1783_evb_shared_sram_planning_conf.dts) + */ +&sram0_image { + reg = <0x20000000 DT_SIZE_K(448)>; +}; + +&sram0_s { + reg = <0x20000000 0x70000>; +}; + +/* Include shared RAM configuration file */ +#include "pan1783_evb_shared_sram_planning_conf.dtsi" diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet-pinctrl.dtsi b/boards/arm/pan1783_evb/pan1783_evb_cpunet-pinctrl.dtsi new file mode 100644 index 00000000000..8a82e07406e --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet-pinctrl.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + psels = , + ; + }; + }; + + i2c0_sleep: i2c0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + spi0_default: spi0_default { + group1 { + psels = , + , + ; + }; + }; + + spi0_sleep: spi0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts b/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts new file mode 100644 index 00000000000..03671c306d6 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "pan1783_evb_cpunet-pinctrl.dtsi" +#include + +/ { + model = "Panasonic PAN1783 EVB (NRF5340) Network"; + compatible = "panasonic,pan1783-evb-cpunet"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; + zephyr,sram = &sram1; + zephyr,flash = &flash1; + zephyr,code-partition = &slot0_partition; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + evb_led1: evb_led_1 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "LED1 on EVB"; + }; + evb_led2: evb_led_2 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "LED2 on EVB"; + }; + evb_led3: evb_led_3 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "LED3 on EVB"; + }; + evb_led4: evb_led_4 { + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + label = "LED4 on EVB"; + }; + }; + + buttons { + compatible = "gpio-keys"; + evb_sw1: evb_sw_1 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1 on EVB"; + zephyr,code = ; + }; + evb_sw2: evb_sw_2 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2 on EVB"; + zephyr,code = ; + }; + evb_sw3: evb_sw_3 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3 on EVB"; + zephyr,code = ; + }; + evb_sw4: evb_sw_4 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW4 on EVB"; + zephyr,code = ; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 4 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio1 12 0>, /* CS */ + <3 0 &gpio1 15 0>, /* SCK */ + <4 0 &gpio1 14 0>, /* MISO */ + <5 0 &gpio1 13 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 7 0>, /* PWM */ + <7 0 &gpio1 4 0>, /* INT */ + <8 0 &gpio1 0 0>, /* RX */ + <9 0 &gpio1 1 0>, /* TX */ + <10 0 &gpio1 3 0>, /* SCL */ + <11 0 &gpio1 2 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 4 0>, /* A0 */ + <1 0 &gpio0 5 0>, /* A1 */ + <2 0 &gpio0 6 0>, /* A2 */ + <3 0 &gpio0 7 0>, /* A3 */ + <4 0 &gpio0 25 0>, /* A4 */ + <5 0 &gpio0 26 0>, /* A5 */ + <6 0 &gpio1 0 0>, /* D0 */ + <7 0 &gpio1 1 0>, /* D1 */ + <8 0 &gpio1 4 0>, /* D2 */ + <9 0 &gpio1 5 0>, /* D3 */ + <10 0 &gpio1 6 0>, /* D4 */ + <11 0 &gpio1 7 0>, /* D5 */ + <12 0 &gpio1 8 0>, /* D6 */ + <13 0 &gpio1 9 0>, /* D7 */ + <14 0 &gpio1 10 0>, /* D8 */ + <15 0 &gpio1 11 0>, /* D9 */ + <16 0 &gpio1 12 0>, /* D10 */ + <17 0 &gpio1 13 0>, /* D11 */ + <18 0 &gpio1 14 0>, /* D12 */ + <19 0 &gpio1 15 0>, /* D13 */ + <20 0 &gpio1 2 0>, /* D14 */ + <21 0 &gpio1 3 0>; /* D15 */ + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &evb_led1; + led1 = &evb_led2; + led2 = &evb_led3; + led3 = &evb_led4; + sw0 = &evb_sw1; + sw1 = &evb_sw2; + sw2 = &evb_sw3; + sw3 = &evb_sw4; + bootloader-led0 = &evb_led1; + mcuboot-button0 = &evb_sw1; + mcuboot-led0 = &evb_led1; + watchdog0 = &wdt0; + }; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + status = "disabled"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_serial: &uart0{}; + +arduino_i2c: &i2c0 { + compatible = "nordic,nrf-twim"; + /* Cannot be used together with uart0. */ + /* status = "okay"; */ + pinctrl-0 = <&i2c0_default>; + pinctrl-1 = <&i2c0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_spi: &spi0 { + compatible = "nordic,nrf-spim"; + /* Cannot be used together with uart0. */ + /* status = "okay"; */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + pinctrl-0 = <&spi0_default>; + pinctrl-1 = <&spi0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&flash1 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x17000>; + }; + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 0x17000>; + }; + storage_partition: partition@3a000 { + label = "storage"; + reg = <0x0003a000 0x6000>; + }; + }; +}; + +&ieee802154 { + status = "okay"; +}; + +/* Include shared RAM configuration file */ +#include "pan1783_evb_shared_sram_planning_conf.dtsi" diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet.yaml b/boards/arm/pan1783_evb/pan1783_evb_cpunet.yaml new file mode 100644 index 00000000000..725fae94cc5 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet.yaml @@ -0,0 +1,14 @@ +identifier: pan1783_evb_cpunet +name: PAN1783-EVB-network-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - watchdog + - gpio +vendor: panasonic diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet_defconfig b/boards/arm/pan1783_evb/pan1783_evb_cpunet_defconfig new file mode 100644 index 00000000000..f83ea000455 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet_defconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUNET_QKAA=y +CONFIG_BOARD_PAN1783_EVB_CPUNET=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# clock config +CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y +CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet_reset.c b/boards/arm/pan1783_evb/pan1783_evb_cpunet_reset.c new file mode 100644 index 00000000000..5b30492a1f9 --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet_reset.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(pan1783_evb_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); + +#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) +#include <../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h> +#else +#define DEBUG_SETUP() +#endif + +static void remoteproc_mgr_config(void) +{ + /* Route Bluetooth Controller Debug Pins */ + DEBUG_SETUP(); + + /* Retain nRF5340 Network MCU */ + NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; +} + +static int remoteproc_mgr_boot(void) +{ + /* Configure permissions for the Network MCU. */ + remoteproc_mgr_config(); + + /* Release the Network MCU, 'Release force off signal' */ + nrf_reset_network_force_off(NRF_RESET, false); + + LOG_DBG("Network MCU released."); + + return 0; +} + +SYS_INIT(remoteproc_mgr_boot, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/pan1783_evb/pan1783_evb_shared_sram_planning_conf.dtsi b/boards/arm/pan1783_evb/pan1783_evb_shared_sram_planning_conf.dtsi new file mode 100644 index 00000000000..9e2b673f84a --- /dev/null +++ b/boards/arm/pan1783_evb/pan1783_evb_shared_sram_planning_conf.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default shared SRAM planning when building for PAN1783 EVB. + * This file is included by both nRF5340 CPUAPP (Application MCU) + * and nRF5340 CPUNET (Network MCU). + * - 64 kB SRAM allocated as Shared memory (sram0_shared) + * - Region defined after the image SRAM of Application MCU + */ + +/ { + chosen { + /* shared memory reserved for the inter-processor communication */ + zephyr,ipc_shm = &sram0_shared; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_shared: memory@20070000 { + /* SRAM allocated to shared memory */ + reg = <0x20070000 0x10000>; + }; + }; +}; diff --git a/boards/arm/pan1783_evb/pre_dt_board.cmake b/boards/arm/pan1783_evb/pre_dt_board.cmake new file mode 100644 index 00000000000..b84665fcf51 --- /dev/null +++ b/boards/arm/pan1783_evb/pre_dt_board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - flash-controller@39000 & kmu@39000 +# - power@5000 & clock@5000 +# - /reserved-memory/image@20000000 & /reserved-memory/image_s@20000000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") From afc034e29438cafbe0a4032e364f2a508fa364e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 13 Oct 2023 13:36:53 +0200 Subject: [PATCH 2401/4498] samples: cdc_acm: Throttle RX when ringbuf is full MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent infinite loop inside interrupt handler when there is incoming data available and ring buffer is full. Signed-off-by: Tomasz Moń --- samples/subsys/usb/cdc_acm/src/main.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/samples/subsys/usb/cdc_acm/src/main.c b/samples/subsys/usb/cdc_acm/src/main.c index 4276bb2a12e..6847ed8d11e 100644 --- a/samples/subsys/usb/cdc_acm/src/main.c +++ b/samples/subsys/usb/cdc_acm/src/main.c @@ -29,6 +29,8 @@ uint8_t ring_buffer[RING_BUF_SIZE]; struct ring_buf ringbuf; +static bool rx_throttled; + #if defined(CONFIG_USB_DEVICE_STACK_NEXT) USBD_CONFIGURATION_DEFINE(config_1, USB_SCD_SELF_POWERED, @@ -106,12 +108,19 @@ static void interrupt_handler(const struct device *dev, void *user_data) ARG_UNUSED(user_data); while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { - if (uart_irq_rx_ready(dev)) { + if (!rx_throttled && uart_irq_rx_ready(dev)) { int recv_len, rb_len; uint8_t buffer[64]; size_t len = MIN(ring_buf_space_get(&ringbuf), sizeof(buffer)); + if (len == 0) { + /* Throttle because ring buffer is full */ + uart_irq_rx_disable(dev); + rx_throttled = true; + continue; + } + recv_len = uart_fifo_read(dev, buffer, len); if (recv_len < 0) { LOG_ERR("Failed to read UART FIFO"); @@ -140,6 +149,11 @@ static void interrupt_handler(const struct device *dev, void *user_data) continue; } + if (rx_throttled) { + uart_irq_rx_enable(dev); + rx_throttled = false; + } + send_len = uart_fifo_fill(dev, buffer, rb_len); if (send_len < rb_len) { LOG_ERR("Drop %d bytes", rb_len - send_len); From 4207f4add8ffe3e027844c36fe26b7d727e1542e Mon Sep 17 00:00:00 2001 From: Pedro Sousa Date: Tue, 3 Oct 2023 22:35:05 +0100 Subject: [PATCH 2402/4498] kernel: timer: Fix race condition in k_timer_start The documentation suggests that k_timer_start can be invoked from ISR and preemptive contexts, however, an assertion failure occurs if one k_timer_start call preempts another for the same timer instance. This commit mitigates the issue by implementing a spinlock throughout the k_timer_start function, ensuring thread-safety. Fixes: #62908 Signed-off-by: Pedro Sousa --- kernel/timer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/timer.c b/kernel/timer.c index 24fe71c7f67..9994ae49b64 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -141,7 +141,15 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration, { SYS_PORT_TRACING_OBJ_FUNC(k_timer, start, timer, duration, period); + /* Acquire spinlock to ensure safety during concurrent calls to + * k_timer_start for scheduling or rescheduling. This is necessary + * since k_timer_start can be preempted, especially for the same + * timer instance. + */ + k_spinlock_key_t key = k_spin_lock(&lock); + if (K_TIMEOUT_EQ(duration, K_FOREVER)) { + k_spin_unlock(&lock, key); return; } @@ -168,6 +176,8 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration, z_add_timeout(&timer->timeout, z_timer_expiration_handler, duration); + + k_spin_unlock(&lock, key); } #ifdef CONFIG_USERSPACE From 0c1d968581aa92f346b0a3021a9d68098cbbbafa Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Oct 2023 13:39:14 +0100 Subject: [PATCH 2403/4498] mgmt: mcumgr: transport: shell/uart: Require CRC to use SMP over console uses a checksum, therefore it is required in order to enable these transports Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/transport/Kconfig.shell | 1 + subsys/mgmt/mcumgr/transport/Kconfig.uart | 1 + 2 files changed, 2 insertions(+) diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.shell b/subsys/mgmt/mcumgr/transport/Kconfig.shell index 1dea00d4156..8198b0ebda6 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.shell +++ b/subsys/mgmt/mcumgr/transport/Kconfig.shell @@ -13,6 +13,7 @@ menuconfig MCUMGR_TRANSPORT_SHELL bool "Shell mcumgr SMP transport" depends on SHELL depends on BASE64 + depends on CRC help Enables handling of SMP commands received over shell. This allows the shell to be use for both mcumgr commands and shell commands. diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.uart b/subsys/mgmt/mcumgr/transport/Kconfig.uart index 4421edce4ce..e5d2bd697cc 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.uart +++ b/subsys/mgmt/mcumgr/transport/Kconfig.uart @@ -13,6 +13,7 @@ menuconfig MCUMGR_TRANSPORT_UART bool "UART mcumgr SMP transport" depends on CONSOLE depends on BASE64 + depends on CRC select UART_MCUMGR help Enables handling of SMP commands received over UART. This is a From a2b22cbe82b985c3fe68ffcd36714ab4f2f2d397 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Oct 2023 13:41:58 +0100 Subject: [PATCH 2404/4498] samples: mgmt: mcumgr: smp_svr: Select CRC for SMP over console CRC support is needed for SMP over console support, therefore enable it Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/overlay-bt.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/overlay-cdc.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial-console.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell-mgmt.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell.conf | 1 + 6 files changed, 6 insertions(+) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-bt.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-bt.conf index b2db245ddd4..8942068beb4 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-bt.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-bt.conf @@ -14,6 +14,7 @@ CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y # Enable the Shell mcumgr transport. CONFIG_BASE64=y +CONFIG_CRC=y CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_MCUMGR_TRANSPORT_SHELL=y diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-cdc.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-cdc.conf index 6fb996b0e5d..1d98bc9899d 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-cdc.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-cdc.conf @@ -7,3 +7,4 @@ CONFIG_CONSOLE=y # USB backend is serial device CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_BASE64=y +CONFIG_CRC=y diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial-console.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial-console.conf index 24e15c9d092..ec2fadf3cfe 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial-console.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial-console.conf @@ -1,5 +1,6 @@ # Enable console with MCUmgr pass through CONFIG_BASE64=y +CONFIG_CRC=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_UART_CONSOLE_MCUMGR=y diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial.conf index cf542238a48..47d4e8d0b85 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-serial.conf @@ -1,4 +1,5 @@ # Enable the serial MCUmgr transport. CONFIG_BASE64=y +CONFIG_CRC=y CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_CONSOLE=y diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell-mgmt.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell-mgmt.conf index 235cd04b32d..01156e341ec 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell-mgmt.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell-mgmt.conf @@ -1,5 +1,6 @@ # Enable shell commands. CONFIG_BASE64=y +CONFIG_CRC=y CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=n CONFIG_MCUMGR_GRP_SHELL=y diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell.conf b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell.conf index 8021768c12d..59c8b18ed9e 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/overlay-shell.conf @@ -1,5 +1,6 @@ # Enable the shell MCUmgr transport. CONFIG_BASE64=y +CONFIG_CRC=y CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_MCUMGR_TRANSPORT_SHELL=y From 8f5925c6dea1d74925bae38b7fc63e0e4212bb3a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Oct 2023 13:42:40 +0100 Subject: [PATCH 2405/4498] mgmt: mcumgr: Do not imply CRC Only SMP over console transports need CRC support, therefore do not imply CRC support for MCUmgr entirely because only 2 optional transports require it Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index 8af4ffe2738..49bd17f4669 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -6,7 +6,6 @@ menuconfig MCUMGR bool "mcumgr Support" depends on NET_BUF depends on ZCBOR - imply CRC help This option enables the mcumgr management library. From b032d0bc00489fc855e637fa86117ed284dec115 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 18 Oct 2023 13:44:22 +0100 Subject: [PATCH 2406/4498] mgmt: mcumgr: grp: fs_mgmt: Select CRC if hash/checksum is enabled Since CRC32 hash/checksum support is enabled by default, make it select the CRC Kconfig symbol Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig index 063aadbf61b..95e8a1c2658 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig @@ -118,6 +118,7 @@ config MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE config MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32 bool "IEEE CRC32 checksum support" + select CRC default y help Enable IEEE CRC32 checksum support for MCUmgr. From 15515f4c7e7e1e2e2ec2a5cff2a805a8ebc37e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 6 Oct 2023 13:56:32 +0200 Subject: [PATCH 2407/4498] doc: samples: exclude CodeSample children during transformation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeSample node is meant to be a temporary node that's transformed into standard docutils nodes. While the node might contain children useful for the transformation, they're not meant to be included in the result of the transform. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 46451e1f682..64c191e693d 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -98,9 +98,6 @@ def convert_node(self, node): new_section = nodes.section(ids=[node["id"]]) new_section += nodes.title(text=node["name"]) - # Move existing content from the custom node to the new section - new_section.extend(node.children) - # Move the sibling nodes under the new section new_section.extend(siblings_to_move) From 234df4391252a859769a31fd3c655cf8e38d0fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 6 Oct 2023 09:47:10 +0200 Subject: [PATCH 2408/4498] doc: samples: expose JSON-LD markup & meta description for code samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since samples are starting to leverage the new :zephyr:code-sample directive, let's use the available meta data to expose that structured information to search engines. This commit adds JSON-LD markup to the HTML output of code sample pages and sets the meta description to the samples' description. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 64c191e693d..688f2c9efa3 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -59,6 +59,9 @@ from sphinx.transforms.post_transforms import SphinxPostTransform from sphinx.util import logging from sphinx.util.nodes import NodeMatcher, make_refnode +from zephyr.vcs_link import vcs_link_get_url + +import json __version__ = "0.1.0" @@ -108,6 +111,30 @@ def convert_node(self, node): for sibling in siblings_to_move: parent.remove(sibling) + # Set sample description as the meta description of the document for improved SEO + meta_description = nodes.meta() + meta_description["name"] = "description" + meta_description["content"] = node.children[0].astext() + node.document += meta_description + + # Similarly, add a node with JSON-LD markup (only renders in HTML output) describing + # the code sample. + json_ld = nodes.raw( + "", + f"""""", + format="html", + ) + node.document += json_ld + class ProcessRelatedCodeSamplesNode(SphinxPostTransform): default_priority = 5 # before ReferencesResolver @@ -200,6 +227,7 @@ def run(self): code_sample_node = CodeSampleNode() code_sample_node["id"] = code_sample_id code_sample_node["name"] = name + code_sample_node += description_node return [code_sample_node] From 32bdb24a92b5c6bb65185bbe3e6d4b88e647cf17 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Fri, 20 Oct 2023 10:53:00 -0300 Subject: [PATCH 2409/4498] doc: zbus: fix VDED notification sequence figure The figure and table related to the VDED notification sequence were wrong. It fixes that by changing the image and adjusting the table content. Signed-off-by: Rodrigo Peixoto --- .../zbus_publishing_process_example.svg | 107 +++++++++--------- doc/services/zbus/index.rst | 21 ++-- 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/doc/services/zbus/images/zbus_publishing_process_example.svg b/doc/services/zbus/images/zbus_publishing_process_example.svg index 72d7430a163..84fbbdd6b1f 100644 --- a/doc/services/zbus/images/zbus_publishing_process_example.svg +++ b/doc/services/zbus/images/zbus_publishing_process_example.svg @@ -1,70 +1,71 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + - - - - - - - - + + + + + + + + - - - - + + + + diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 45e9e0ea69a..ca8ab6142a8 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -235,17 +235,22 @@ priority. it cannot access the channel since it is still locked. * - i - - VDED finishes the publishing by unlocking channel A. + - VDED finishes the publishing by unlocking channel A. The MS1 leaves the pending state and + starts executing. - * - j, k, l + * - j + - MS1 finishes execution. The MS2 leaves the pending state and starts executing. + + * - k + - MS2 finishes execution. The S1 leaves the pending state and starts executing. + + * - l, m, n - The S1 leaves the pending state since channel A is not locked. It gets in the CPU again and - starts executing. As it did receive a notification from channel A, it performs a channel read - (as simple as lock, memory copy, unlock), continues its execution, and goes out the CPU. - * - m - - S1 goes out of the MCU. + starts executing. As it did receive a notification from channel A, it performed a channel read + (as simple as lock, memory copy, unlock), continues its execution and goes out of the CPU. - * - n, o - - MS2 and MS1 execute and finish their workload. + * - o + - S1 finishes its workload. The figure below illustrates the actions performed during the VDED execution when T1 publishes to From 49d7910aa4753d2c2d938380fb6e8da9069f6f1a Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 23 Oct 2023 15:07:11 +0800 Subject: [PATCH 2410/4498] shell: Update doc to include MQTT transport The Shell MQTT transport was added in #38107, but isn't mentioned in the Shell documentation. Signed-off-by: Yong Cong Sin --- doc/services/shell/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 15213954200..b9c88822cd3 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -43,6 +43,7 @@ interaction is required. This module is a Unix-like shell with these features: The module can be connected to any transport for command input and output. At this point, the following transport layers are implemented: +* MQTT * Segger RTT * SMP * Telnet From 201a48889c1abf75dfc7e621ad65674ec289b761 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 11:28:29 +0200 Subject: [PATCH 2411/4498] doc: samples net mqtt_sn_publisher fix west invokation Fix the west invokation. "-t" is added automatically to the run goal, otherwise we get a "-t -t" command. Signed-off-by: Alberto Escolar Piedras --- samples/net/mqtt_sn_publisher/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/mqtt_sn_publisher/README.rst b/samples/net/mqtt_sn_publisher/README.rst index e7831487650..425160e8892 100644 --- a/samples/net/mqtt_sn_publisher/README.rst +++ b/samples/net/mqtt_sn_publisher/README.rst @@ -68,7 +68,7 @@ Then, locate your zephyr directory and type: .. zephyr-app-commands:: :zephyr-app: samples/net/mqtt_sn_publisher :board: native_posix_64 - :goals: build -t run + :goals: run :compact: Optionally, use any MQTT explorer to connect to your broker. From 421693b5749608d1c0bb208d297248cba98f1ea9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 12:05:05 +0200 Subject: [PATCH 2412/4498] doc: extend application sphinx extension to support flash arguments Passing arguments to west flash is needed in many cases but there was no way to properly generate documentation with such examples. With this new "flash-args" option we can now. Signed-off-by: Alberto Escolar Piedras --- doc/_extensions/zephyr/application.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/_extensions/zephyr/application.py b/doc/_extensions/zephyr/application.py index 5d2b17f2f33..e24d1bf7647 100644 --- a/doc/_extensions/zephyr/application.py +++ b/doc/_extensions/zephyr/application.py @@ -92,6 +92,9 @@ class ZephyrAppCommandsDirective(Directive): \:west-args: if set, additional arguments to the west invocation (ignored for CMake) + \:flash-args: + if set, additional arguments to the flash invocation + ''' has_content = False required_arguments = 0 @@ -114,6 +117,7 @@ class ZephyrAppCommandsDirective(Directive): 'maybe-skip-config': directives.flag, 'compact': directives.flag, 'west-args': directives.unchanged, + 'flash-args': directives.unchanged, } TOOLS = ['cmake', 'west', 'all'] @@ -143,6 +147,7 @@ def run(self): skip_config = 'maybe-skip-config' in self.options compact = 'compact' in self.options west_args = self.options.get('west-args', None) + flash_args = self.options.get('flash-args', None) if tool not in self.TOOLS: raise self.error('Unknown tool {}; choose from: {}'.format( @@ -194,7 +199,8 @@ def run(self): 'compact': compact, 'skip_config': skip_config, 'generator': generator, - 'west_args': west_args + 'west_args': west_args, + 'flash_args': flash_args, } if 'west' in tools: @@ -244,12 +250,14 @@ def _generate_west(self, **kwargs): build_dir = kwargs['build_dir'] compact = kwargs['compact'] west_args = kwargs['west_args'] + flash_args = kwargs['flash_args'] kwargs['board'] = None # west always defaults to ninja gen_arg = ' -G\'Unix Makefiles\'' if generator == 'make' else '' cmake_args = gen_arg + self._cmake_args(**kwargs) cmake_args = ' --{}'.format(cmake_args) if cmake_args != '' else '' west_args = ' {}'.format(west_args) if west_args else '' + flash_args = ' {}'.format(flash_args) if flash_args else '' # ignore zephyr_app since west needs to run within # the installation. Instead rely on relative path. src = ' {}'.format(app) if app and not cd_into else '' @@ -284,7 +292,7 @@ def _generate_west(self, **kwargs): if goal in {'build', 'sign'}: continue elif goal == 'flash': - content.append('west flash{}'.format(dst)) + content.append('west flash{}{}'.format(flash_args, dst)) elif goal == 'debug': content.append('west debug{}'.format(dst)) elif goal == 'debugserver': From d0aec24e4568f4c1798a0818ddf2a1b26bb31ddc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 12:06:20 +0200 Subject: [PATCH 2413/4498] doc: boards adafruit_itsybitsy_m4_express: Fix flash command Fix the west flash command example using the new flash-args option. Signed-off-by: Alberto Escolar Piedras --- boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst index aca89603ff5..401e28d6669 100644 --- a/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst +++ b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst @@ -179,7 +179,8 @@ debugged using a SWD probe such as the Segger J-Link. .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: adafruit_itsybitsy_m4_express - :goals: flash -r openocd + :goals: flash + :flash-args: -r openocd :compact: #. Start debugging: From 8b844024444085d41e071c38bc52a8b6aa1d92be Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 12:07:09 +0200 Subject: [PATCH 2414/4498] doc: boards wio_terminal: Fix flash command Fix the west flash command example using the new flash-args option. Signed-off-by: Alberto Escolar Piedras --- boards/arm/wio_terminal/doc/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/arm/wio_terminal/doc/index.rst b/boards/arm/wio_terminal/doc/index.rst index 56a13748ac6..4b11a461323 100644 --- a/boards/arm/wio_terminal/doc/index.rst +++ b/boards/arm/wio_terminal/doc/index.rst @@ -180,7 +180,8 @@ debugged using an SWD probe such as the Segger J-Link. .. zephyr-app-commands:: :zephyr-app: samples/basic/button :board: wio_terminal - :goals: flash -r openocd + :goals: flash + :flash-args: -r openocd :compact: #. Start debugging: From e1de3068541f00380f06b2d4d75f819aaacf454d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 20 Oct 2023 12:07:50 +0200 Subject: [PATCH 2415/4498] doc: samples nrf53_sync_rtc: Fix flash command Fix the west flash command example using the new flash-args option. Signed-off-by: Alberto Escolar Piedras --- samples/boards/nrf/nrf53_sync_rtc/README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/README.rst b/samples/boards/nrf/nrf53_sync_rtc/README.rst index a1224ab9482..36e04a0e2cb 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/README.rst +++ b/samples/boards/nrf/nrf53_sync_rtc/README.rst @@ -28,7 +28,8 @@ Building the application for nrf5340dk_nrf5340_cpuapp .. zephyr-app-commands:: :zephyr-app: samples/boards/nrf/nrf53_sync_rtc :board: nrf5340dk_nrf5340_cpuapp - :goals: flash "flash --hex-file build/sync_rtc_net-prefix/src/sync_rtc_net-build/zephyr/zephyr.hex" + :goals: flash + :flash-args: --hex-file build/sync_rtc_net-prefix/src/sync_rtc_net-build/zephyr/zephyr.hex Open a serial terminals (for example Minicom or PuTTY) and connect the board with the following settings: From 733834851db2778e4085ee0565c24308e0005e50 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Wed, 11 Oct 2023 13:09:37 +0100 Subject: [PATCH 2416/4498] drivers: mfd: npm1300: Added shiphold button release event Added event for detecting release of shiphold button Signed-off-by: Andy Sinclair --- drivers/mfd/mfd_npm1300.c | 1 + include/zephyr/drivers/mfd/npm1300.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/mfd/mfd_npm1300.c b/drivers/mfd/mfd_npm1300.c index d0632422556..c100b7e915a 100644 --- a/drivers/mfd/mfd_npm1300.c +++ b/drivers/mfd/mfd_npm1300.c @@ -64,6 +64,7 @@ static const struct event_reg_t event_reg[NPM1300_EVENT_MAX] = { [NPM1300_EVENT_BATTERY_DETECTED] = {0x0EU, 0x01U}, [NPM1300_EVENT_BATTERY_REMOVED] = {0x0EU, 0x02U}, [NPM1300_EVENT_SHIPHOLD_PRESS] = {0x12U, 0x01U}, + [NPM1300_EVENT_SHIPHOLD_RELEASE] = {0x12U, 0x02U}, [NPM1300_EVENT_WATCHDOG_WARN] = {0x12U, 0x08U}, [NPM1300_EVENT_VBUS_DETECTED] = {0x16U, 0x01U}, [NPM1300_EVENT_VBUS_REMOVED] = {0x16U, 0x02U}}; diff --git a/include/zephyr/drivers/mfd/npm1300.h b/include/zephyr/drivers/mfd/npm1300.h index 13f6ee84365..b86f2f31c8f 100644 --- a/include/zephyr/drivers/mfd/npm1300.h +++ b/include/zephyr/drivers/mfd/npm1300.h @@ -28,6 +28,7 @@ enum mfd_npm1300_event_t { NPM1300_EVENT_BATTERY_DETECTED, NPM1300_EVENT_BATTERY_REMOVED, NPM1300_EVENT_SHIPHOLD_PRESS, + NPM1300_EVENT_SHIPHOLD_RELEASE, NPM1300_EVENT_WATCHDOG_WARN, NPM1300_EVENT_VBUS_DETECTED, NPM1300_EVENT_VBUS_REMOVED, From 7cf4eff731410a8a26b27835324de1465fa3bb94 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Wed, 11 Oct 2023 13:42:30 +0100 Subject: [PATCH 2417/4498] drivers: mfd: npm1300: Fixed race condition in event callback If an event occurs between the status registers being read and the event being cleared, the interrupt line will remain active. As the interrupt is edge triggered, all future interrupts will being ignored. This problem will also occur if an I2C transation fails in the callback. The state of the interrupt pin is now checked at the end of the callback, and a retry is attempted if the interrupt has not been cleared. Signed-off-by: Andy Sinclair --- drivers/mfd/mfd_npm1300.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/mfd_npm1300.c b/drivers/mfd/mfd_npm1300.c index c100b7e915a..678d3572a24 100644 --- a/drivers/mfd/mfd_npm1300.c +++ b/drivers/mfd/mfd_npm1300.c @@ -79,12 +79,14 @@ static void gpio_callback(const struct device *dev, struct gpio_callback *cb, ui static void work_callback(struct k_work *work) { struct mfd_npm1300_data *data = CONTAINER_OF(work, struct mfd_npm1300_data, work); + const struct mfd_npm1300_config *config = data->dev->config; uint8_t buf[MAIN_SIZE]; int ret; /* Read all MAIN registers into temporary buffer */ ret = mfd_npm1300_reg_read_burst(data->dev, MAIN_BASE, 0U, buf, sizeof(buf)); if (ret < 0) { + k_work_submit(&data->work); return; } @@ -97,10 +99,16 @@ static void work_callback(struct k_work *work) ret = mfd_npm1300_reg_write(data->dev, MAIN_BASE, offset, event_reg[i].mask); if (ret < 0) { + k_work_submit(&data->work); return; } } } + + /* Resubmit handler to queue if interrupt is still active */ + if (gpio_pin_get_dt(&config->host_int_gpios) != 0) { + k_work_submit(&data->work); + } } static int mfd_npm1300_init(const struct device *dev) From 7e02a0379f73f8948ea9e10fe30f4ca9bc8f8a3c Mon Sep 17 00:00:00 2001 From: Jason Wright Date: Thu, 12 Oct 2023 22:47:18 -0400 Subject: [PATCH 2418/4498] drivers: counter native: Add top value conf and multi channel support The counter_native_posix driver currently does not support top value configuration, i.e. `ctr_set_top_value` returns `-ENOTSUP`. This commit adds support for top value configuration, and with the counter API now fully implemented, adds `counter` to `supported` peripherals for native_posix target. It also resolves an existing bug in which the counter ISR did not reset upon reaching `TOP_VALUE`. And adds support for multiple channels Signed-off-by: Jason Wright Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_posix/hw_counter.c | 27 +++- boards/posix/native_posix/hw_counter.h | 3 + boards/posix/native_posix/native_posix.yaml | 1 + .../posix/native_posix/native_posix_64.yaml | 1 + boards/posix/native_sim/native_sim.yaml | 1 + boards/posix/native_sim/native_sim_64.yaml | 1 + drivers/counter/Kconfig.native_posix | 5 + drivers/counter/counter_native_posix.c | 145 ++++++++++++++---- 8 files changed, 157 insertions(+), 27 deletions(-) diff --git a/boards/posix/native_posix/hw_counter.c b/boards/posix/native_posix/hw_counter.c index 77218a7ada4..eb02fd00807 100644 --- a/boards/posix/native_posix/hw_counter.c +++ b/boards/posix/native_posix/hw_counter.c @@ -17,6 +17,7 @@ static bool counter_running; static uint64_t counter_value; static uint64_t counter_target; static uint64_t counter_period; +static uint64_t counter_wrap; /** * Initialize the counter with prescaler of HW @@ -28,6 +29,7 @@ void hw_counter_init(void) counter_value = 0; counter_running = false; counter_period = NEVER; + counter_wrap = NEVER; } void hw_counter_triggered(void) @@ -38,7 +40,7 @@ void hw_counter_triggered(void) } hw_counter_timer = hwm_get_time() + counter_period; - counter_value = counter_value + 1; + counter_value = (counter_value + 1) % counter_wrap; if (counter_value == counter_target) { hw_irq_ctrl_set_irq(COUNTER_EVENT_IRQ); @@ -54,6 +56,16 @@ void hw_counter_set_period(uint64_t period) counter_period = period; } +/* + * Set the count value at which the counter will wrap + * The counter will count up to (counter_wrap-1), i.e.: + * 0, 1, 2,.., (counter_wrap - 1), 0 + */ +void hw_counter_set_wrap_value(uint64_t wrap_value) +{ + counter_wrap = wrap_value; +} + /** * Starts the counter. It must be previously configured with * hw_counter_set_period() and hw_counter_set_target(). @@ -82,6 +94,11 @@ void hw_counter_stop(void) hwm_find_next_timer(); } +bool hw_counter_is_started(void) +{ + return counter_running; +} + /** * Returns the current counter value. */ @@ -90,6 +107,14 @@ uint64_t hw_counter_get_value(void) return counter_value; } +/** + * Resets the counter value. + */ +void hw_counter_reset(void) +{ + counter_value = 0; +} + /** * Configures the counter to generate an interrupt * when its count value reaches target. diff --git a/boards/posix/native_posix/hw_counter.h b/boards/posix/native_posix/hw_counter.h index 5cd6dd2e577..efbb7e39e29 100644 --- a/boards/posix/native_posix/hw_counter.h +++ b/boards/posix/native_posix/hw_counter.h @@ -18,9 +18,12 @@ void hw_counter_triggered(void); void hw_counter_set_period(uint64_t period); void hw_counter_set_target(uint64_t counter_target); +void hw_counter_set_wrap_value(uint64_t wrap_value); void hw_counter_start(void); void hw_counter_stop(void); +bool hw_counter_is_started(void); uint64_t hw_counter_get_value(void); +void hw_counter_reset(void); #ifdef __cplusplus } diff --git a/boards/posix/native_posix/native_posix.yaml b/boards/posix/native_posix/native_posix.yaml index 7d10c080474..a1fb897eb75 100644 --- a/boards/posix/native_posix/native_posix.yaml +++ b/boards/posix/native_posix/native_posix.yaml @@ -10,6 +10,7 @@ toolchain: - llvm supported: - can + - counter - eeprom - netif:eth - usb_device diff --git a/boards/posix/native_posix/native_posix_64.yaml b/boards/posix/native_posix/native_posix_64.yaml index 62d3b168497..56ad340f176 100644 --- a/boards/posix/native_posix/native_posix_64.yaml +++ b/boards/posix/native_posix/native_posix_64.yaml @@ -10,6 +10,7 @@ toolchain: - llvm supported: - can + - counter - eeprom - netif:eth - usb_device diff --git a/boards/posix/native_sim/native_sim.yaml b/boards/posix/native_sim/native_sim.yaml index daa76cdab92..e2defe1ce40 100644 --- a/boards/posix/native_sim/native_sim.yaml +++ b/boards/posix/native_sim/native_sim.yaml @@ -10,6 +10,7 @@ toolchain: - llvm supported: - can + - counter - eeprom - netif:eth - usb_device diff --git a/boards/posix/native_sim/native_sim_64.yaml b/boards/posix/native_sim/native_sim_64.yaml index 487f623894d..52841d23b2b 100644 --- a/boards/posix/native_sim/native_sim_64.yaml +++ b/boards/posix/native_sim/native_sim_64.yaml @@ -10,6 +10,7 @@ toolchain: - llvm supported: - can + - counter - eeprom - netif:eth - usb_device diff --git a/drivers/counter/Kconfig.native_posix b/drivers/counter/Kconfig.native_posix index 362eb00da1c..a342ed07a30 100644 --- a/drivers/counter/Kconfig.native_posix +++ b/drivers/counter/Kconfig.native_posix @@ -10,3 +10,8 @@ config COUNTER_NATIVE_POSIX_FREQUENCY int "native_posix counter frequency in Hz" default 1000 depends on COUNTER_NATIVE_POSIX + +config COUNTER_NATIVE_POSIX_NBR_CHANNELS + int "native counter, number of channels" + default 4 + depends on COUNTER_NATIVE_POSIX diff --git a/drivers/counter/counter_native_posix.c b/drivers/counter/counter_native_posix.c index aa221a11fdc..d03517b1b86 100644 --- a/drivers/counter/counter_native_posix.c +++ b/drivers/counter/counter_native_posix.c @@ -6,6 +6,7 @@ #define DT_DRV_COMPAT zephyr_native_posix_counter +#include #include #include #include @@ -14,38 +15,80 @@ #include #define DRIVER_CONFIG_INFO_FLAGS (COUNTER_CONFIG_INFO_COUNT_UP) -#define DRIVER_CONFIG_INFO_CHANNELS 1 +#define DRIVER_CONFIG_INFO_CHANNELS CONFIG_COUNTER_NATIVE_POSIX_NBR_CHANNELS #define COUNTER_NATIVE_POSIX_IRQ_FLAGS (0) #define COUNTER_NATIVE_POSIX_IRQ_PRIORITY (2) #define COUNTER_PERIOD (USEC_PER_SEC / CONFIG_COUNTER_NATIVE_POSIX_FREQUENCY) #define TOP_VALUE (UINT_MAX) -static struct counter_alarm_cfg pending_alarm; -static bool is_alarm_pending; +static struct counter_alarm_cfg pending_alarm[DRIVER_CONFIG_INFO_CHANNELS]; +static bool is_alarm_pending[DRIVER_CONFIG_INFO_CHANNELS]; +static struct counter_top_cfg top; +static bool is_top_set; static const struct device *device; +static void schedule_next_isr(void) +{ + int64_t current_value = hw_counter_get_value(); + uint32_t next_time = top.ticks; /* top.ticks is TOP_VALUE if is_top_set == false */ + + if (current_value == top.ticks) { + current_value = -1; + } + + for (int i = 0; i < DRIVER_CONFIG_INFO_CHANNELS; i++) { + if (is_alarm_pending[i]) { + if (pending_alarm[i].ticks > current_value) { + /* If the alarm is not after a wrap */ + next_time = MIN(pending_alarm[i].ticks, next_time); + } + } + } + + /* We will at least get an interrupt at top.ticks even if is_top_set == false, + * which is fine. We may use that to set the next alarm if needed + */ + hw_counter_set_target(next_time); +} + static void counter_isr(const void *arg) { ARG_UNUSED(arg); uint32_t current_value = hw_counter_get_value(); - if (is_alarm_pending) { - is_alarm_pending = false; - pending_alarm.callback(device, 0, current_value, - pending_alarm.user_data); + for (int i = 0; i < DRIVER_CONFIG_INFO_CHANNELS; i++) { + if (is_alarm_pending[i] && (current_value == pending_alarm[i].ticks)) { + is_alarm_pending[i] = false; + if (pending_alarm[i].callback) { + pending_alarm[i].callback(device, i, current_value, + pending_alarm[i].user_data); + } + } + } + + if (is_top_set && (current_value == top.ticks)) { + if (top.callback) { + top.callback(device, top.user_data); + } } + + schedule_next_isr(); } static int ctr_init(const struct device *dev) { device = dev; - is_alarm_pending = false; + memset(is_alarm_pending, 0, sizeof(is_alarm_pending)); + is_top_set = false; + top.ticks = TOP_VALUE; IRQ_CONNECT(COUNTER_EVENT_IRQ, COUNTER_NATIVE_POSIX_IRQ_PRIORITY, counter_isr, NULL, COUNTER_NATIVE_POSIX_IRQ_FLAGS); + irq_enable(COUNTER_EVENT_IRQ); hw_counter_set_period(COUNTER_PERIOD); - hw_counter_set_target(TOP_VALUE); + hw_counter_set_wrap_value((uint64_t)top.ticks + 1); + hw_counter_reset(); return 0; } @@ -54,6 +97,7 @@ static int ctr_start(const struct device *dev) { ARG_UNUSED(dev); + schedule_next_isr(); hw_counter_start(); return 0; } @@ -80,19 +124,56 @@ static uint32_t ctr_get_pending_int(const struct device *dev) return 0; } +static bool is_any_alarm_pending(void) +{ + for (int i = 0; i < DRIVER_CONFIG_INFO_CHANNELS; i++) { + if (is_alarm_pending[i]) { + return true; + } + } + return false; +} + static int ctr_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) { ARG_UNUSED(dev); - ARG_UNUSED(cfg); - posix_print_warning("%s not supported\n", __func__); - return -ENOTSUP; + if (is_any_alarm_pending()) { + posix_print_warning("Can't set top value while alarm is active\n"); + return -EBUSY; + } + + uint32_t current_value = hw_counter_get_value(); + + if (cfg->flags & COUNTER_TOP_CFG_DONT_RESET) { + if (current_value >= cfg->ticks) { + if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) { + hw_counter_reset(); + } + return -ETIME; + } + } else { + hw_counter_reset(); + } + + top = *cfg; + hw_counter_set_wrap_value((uint64_t)top.ticks + 1); + + if ((cfg->ticks == TOP_VALUE) && !cfg->callback) { + is_top_set = false; + } else { + is_top_set = true; + } + + schedule_next_isr(); + + return 0; } static uint32_t ctr_get_top_value(const struct device *dev) { - return TOP_VALUE; + return top.ticks; } static int ctr_set_alarm(const struct device *dev, uint8_t chan_id, @@ -100,21 +181,31 @@ static int ctr_set_alarm(const struct device *dev, uint8_t chan_id, { ARG_UNUSED(dev); - if (chan_id >= DRIVER_CONFIG_INFO_CHANNELS) { - posix_print_warning("channel %u is not supported\n", chan_id); - return -ENOTSUP; - } + if (is_alarm_pending[chan_id]) + return -EBUSY; - pending_alarm = *alarm_cfg; - is_alarm_pending = true; + uint32_t ticks = alarm_cfg->ticks; + + if (ticks > top.ticks) { + posix_print_warning("Alarm ticks %u exceed top ticks %u\n", ticks, + top.ticks); + return -EINVAL; + } if (!(alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE)) { - pending_alarm.ticks = - hw_counter_get_value() + pending_alarm.ticks; + uint32_t current_value = hw_counter_get_value(); + + ticks += current_value; + if (ticks > top.ticks) { /* Handle wrap arounds */ + ticks -= (top.ticks + 1); /* The count period is top.ticks + 1 */ + } } - hw_counter_set_target(pending_alarm.ticks); - irq_enable(COUNTER_EVENT_IRQ); + pending_alarm[chan_id] = *alarm_cfg; + pending_alarm[chan_id].ticks = ticks; + is_alarm_pending[chan_id] = true; + + schedule_next_isr(); return 0; } @@ -123,12 +214,14 @@ static int ctr_cancel_alarm(const struct device *dev, uint8_t chan_id) { ARG_UNUSED(dev); - if (chan_id >= DRIVER_CONFIG_INFO_CHANNELS) { - posix_print_warning("channel %u is not supported\n", chan_id); + if (!hw_counter_is_started()) { + posix_print_warning("Counter not started\n"); return -ENOTSUP; } - is_alarm_pending = false; + is_alarm_pending[chan_id] = false; + + schedule_next_isr(); return 0; } From 677219ff1a86c1d4e213f734a99bc7f30be7d83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 23 Oct 2023 12:38:18 +0200 Subject: [PATCH 2419/4498] doc: Allow to control wrapping behavior per table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport a useful CSS rule from Godot that allows to have *all* cells of a table to wrap. This can be useful for list-tables in particular, where otherwise the first column don't wrap. Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 711edd9936f..edd7f24629b 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -306,6 +306,12 @@ a.icon-home:visited { white-space: normal; } +/* Allow to control wrapping behavior per table */ +.wy-table-responsive table.wrap-normal td, +.wy-table-responsive table.wrap-normal th { + white-space: normal; +} + /* Make sure not to wrap keyboard shortcuts */ .wy-table-responsive table td kbd { white-space: nowrap; From f2b080b5d609245ab5ce84f8ddb4cba541597841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 20 Oct 2023 18:46:25 +0200 Subject: [PATCH 2420/4498] doc: Set default language for syntax highlighting to "none" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force code blocks with no 'language' explicitly set to render with no highlighting. The current default was to use python (bad), and there would also be an option to set it to "guess" but this doesn't work all so well (ex. some C blocks would be detected as Transact-SQL!). Signed-off-by: Benjamin Cabé --- doc/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/conf.py b/doc/conf.py index 6ff43b07f2b..9a3e337d36b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -105,6 +105,7 @@ exclude_patterns.append("**/*west-not-found*") pygments_style = "sphinx" +highlight_language = "none" todo_include_todos = False From 92045a021ed3f98716529a7f041923a662ce04b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 20 Oct 2023 19:34:42 +0200 Subject: [PATCH 2421/4498] doc: guidelines: Clarify how code-block directive should be used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct a previous mistake indicating syntax highlighting is autoguessed. Add recommendations and samples around languages that documentation authors are encouraged to use. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/guidelines.rst | 101 ++++++++++++++++++-- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index 307356492e1..2fd7d82785d 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -417,10 +417,93 @@ This would be rendered as: } __packed; -You can specify other languages for the ``code-block`` directive, -including ``c``, ``python``, and ``rst``, and also ``console``, -``bash``, or ``shell``. If you want no syntax highlighting, use the -language ``none``, for example:: +Other languages are of course supported (see `languages supported by Pygments`_), and in particular, +you are encouraged to make use of the following when appropriate: + +.. _`languages supported by Pygments`: http://pygments.org/languages/ + +* ``c`` for C code +* ``cpp`` for C++ code +* ``python`` for Python code +* ``console`` for console output, i.e. interactive shell sessions where commands are prefixed by a + prompt (ex. ``$`` for Linux, or ``uart:~$`` for Zephyr's shell), and where the output is also + shown. The commands will be highlighted, and the output will not. What's more, copying code block + using the "copy" button will automatically copy just the commands, excluding the prompt and the + outputs of the commands. +* ``shell`` or ``bash`` for shell commands. Both languages get highlighted the same but you may use + ``bash`` for conveying that the commands are bash-specific, and ``shell`` for generic shell + commands. + + .. note:: + + Do not use ``bash`` or ``shell`` if your code block includes a prompt, use ``console`` instead. + + Reciprocally, do not use ``console`` if your code block does not include a prompt and is not + showcasing an interactive session with command(s) and their output. + + .. list-table:: When to use ``bash``/``shell`` vs. ``console`` + :class: wrap-normal + :header-rows: 1 + :widths: 20,40,40 + + * - Use case + - ``code-block`` snippet + - Expected output + + * - One or several commands, no output + + - .. code-block:: rst + + .. code-block:: shell + + echo "Hello World!" + + - .. code-block:: shell + + echo "Hello World!" + + * - An interactive shell session with command(s) and their output + + - .. code-block:: rst + + .. code-block:: console + + $ echo "Hello World!" + Hello World! + + - .. code-block:: console + + $ echo "Hello World!" + Hello World! + + * - An interactive Zephyr shell session, with commands and their outputs + + - .. code-block:: rst + + .. code-block:: console + + uart:~$ version + Zephyr version 3.5.99 + uart:~$ kernel uptime + Uptime: 20970 ms + + - .. code-block:: console + + uart:~$ version + Zephyr version 3.5.99 + uart:~$ kernel uptime + Uptime: 20970 ms + +* ``bat`` for Windows batch files +* ``cfg`` for config files with "KEY=value" entries (ex. Kconfig ``.conf`` files) +* ``cmake`` for CMake +* ``devicetree`` for Devicetree +* ``kconfig`` for Kconfig +* ``yaml`` for YAML +* ``rst`` for reStructuredText + +When no language is specified, the language is set to ``none`` and the code block is not +highlighted. You may also use ``none`` explicitly to achieve the same result; for example:: .. code-block:: none @@ -434,11 +517,11 @@ Would display as: This would be a block of text styled with a background and box, but with no syntax highlighting. -There's a shorthand for writing code blocks too: end the introductory -paragraph with a double colon (``::``) and indent the code block content -by three spaces. On output, only one colon will be shown. The -highlighting package makes a best guess at the type of content in the -block and highlighting purposes. +There's a shorthand for writing code blocks too: end the introductory paragraph with a double colon +(``::``) and indent the code block content that follows it by three spaces. On output, only one +colon will be shown. The code block will have no highlighting (i.e. ``none``). You may however use +the ``.. highlight::`` directive to customize the default language used in your document (see for +example how this is done at the beginning of this very document). Images ****** From 1f60c1379e83c94e444df8dd603ac68de9033e25 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 23 Oct 2023 18:53:24 +0800 Subject: [PATCH 2422/4498] net: shell: fix compilation errors `suspend.c` and `resume.c` are missing the `zephyr/pm/device.h` add that to fix compilation warning Signed-off-by: Yong Cong Sin --- subsys/net/lib/shell/resume.c | 1 + subsys/net/lib/shell/suspend.c | 1 + 2 files changed, 2 insertions(+) diff --git a/subsys/net/lib/shell/resume.c b/subsys/net/lib/shell/resume.c index 76c448c7148..585d421efab 100644 --- a/subsys/net/lib/shell/resume.c +++ b/subsys/net/lib/shell/resume.c @@ -6,6 +6,7 @@ */ #include +#include LOG_MODULE_DECLARE(net_shell); #include "common.h" diff --git a/subsys/net/lib/shell/suspend.c b/subsys/net/lib/shell/suspend.c index fc4ae28eefb..326eb602077 100644 --- a/subsys/net/lib/shell/suspend.c +++ b/subsys/net/lib/shell/suspend.c @@ -6,6 +6,7 @@ */ #include +#include LOG_MODULE_DECLARE(net_shell); #include "common.h" From 8b3b8cf2ad3086549cb6776d95eea6897d1e578a Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Thu, 12 Oct 2023 08:52:14 +0200 Subject: [PATCH 2423/4498] Bluetooth: ISO: extend API for setting SDU interval The BT Core Spec v5.4 allows separate SDU_Interval to be set on C_To_P and P_To_C directions, but this is not possible with the existing interface. This PR splits the interval parameter in the call to bt_iso_sig_create into one for C_To_P and one for P_To_C It also splits the latency parameter into one for C_To_P and one for P_To_C Signed-off-by: Andries Kruithof Bluetooth: ISO: update UI for extended API The API for setting the SDU interval and latency have been updated. This PR also updates the setting of these by the user in the shell and the iso_connected_benchmark sample Signed-off-by: Andries Kruithof --- include/zephyr/bluetooth/iso.h | 22 ++- samples/bluetooth/central_iso/src/main.c | 7 +- .../iso_connected_benchmark/src/main.c | 87 ++++++++--- subsys/bluetooth/audio/bap_unicast_client.c | 6 +- subsys/bluetooth/host/iso.c | 52 ++++--- subsys/bluetooth/shell/iso.c | 143 +++++++++++++----- .../bluetooth/host/iso/cis/src/cis_central.c | 114 +++++++++++--- tests/bsim/bluetooth/ll/cis/src/main.c | 9 +- 8 files changed, 323 insertions(+), 117 deletions(-) diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index ad89b62ee77..68ceec3ac3d 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -335,19 +335,33 @@ struct bt_iso_cig_param { */ uint8_t num_cis; - /** @brief Channel interval in us. + /** @brief Channel interval in us for SDUs sent from Central to Peripheral. * * Value range BT_ISO_SDU_INTERVAL_MIN - BT_ISO_SDU_INTERVAL_MAX. */ - uint32_t interval; + uint32_t c_to_p_interval; - /** @brief Channel Latency in ms. + /** @brief Channel interval in us for SDUs sent from Peripheral to Central. + * + * Value range BT_ISO_SDU_INTERVAL_MIN - BT_ISO_SDU_INTERVAL_MAX. + */ + uint32_t p_to_c_interval; + + /** @brief Channel Latency in ms for SDUs sent from Central to Peripheral * * Value range BT_ISO_LATENCY_MIN - BT_ISO_LATENCY_MAX. * * This value is ignored if any advanced ISO parameters are set. */ - uint16_t latency; + uint16_t c_to_p_latency; + + /** @brief Channel Latency in ms for SDUs sent from Peripheral to Central + * + * Value range BT_ISO_LATENCY_MIN - BT_ISO_LATENCY_MAX. + * + * This value is ignored if any advanced ISO parameters are set. + */ + uint16_t p_to_c_latency; /** @brief Channel peripherals sleep clock accuracy Only for CIS * diff --git a/samples/bluetooth/central_iso/src/main.c b/samples/bluetooth/central_iso/src/main.c index c5da26373b1..a0062fcfa73 100644 --- a/samples/bluetooth/central_iso/src/main.c +++ b/samples/bluetooth/central_iso/src/main.c @@ -25,6 +25,7 @@ static struct bt_conn *default_conn; static struct k_work_delayable iso_send_work; static struct bt_iso_chan iso_chan; static uint16_t seq_num; +static uint16_t latency_ms = 10U; /* 10ms */ static uint32_t interval_us = 10U * USEC_PER_MSEC; /* 10 ms */ NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); @@ -251,8 +252,10 @@ int main(void) param.sca = BT_GAP_SCA_UNKNOWN; param.packing = 0; param.framing = 0; - param.latency = 10; /* ms */ - param.interval = interval_us; /* us */ + param.c_to_p_latency = latency_ms; /* ms */ + param.p_to_c_latency = latency_ms; /* ms */ + param.c_to_p_interval = interval_us; /* us */ + param.p_to_c_interval = interval_us; /* us */ err = bt_iso_cig_create(¶m, &cig); diff --git a/samples/bluetooth/iso_connected_benchmark/src/main.c b/samples/bluetooth/iso_connected_benchmark/src/main.c index 3b4cd46f63d..9d387ed8806 100644 --- a/samples/bluetooth/iso_connected_benchmark/src/main.c +++ b/samples/bluetooth/iso_connected_benchmark/src/main.c @@ -28,6 +28,11 @@ enum benchmark_role { ROLE_QUIT }; +enum sdu_dir { + DIR_C_TO_P, + DIR_P_TO_C +}; + #define DEFAULT_CIS_RTN 2 #define DEFAULT_CIS_INTERVAL_US 7500 #define DEFAULT_CIS_LATENCY_MS 40 @@ -116,8 +121,10 @@ static struct bt_iso_chan_qos iso_qos = { }; static struct bt_iso_cig_param cig_create_param = { - .interval = DEFAULT_CIS_INTERVAL_US, /* in microseconds */ - .latency = DEFAULT_CIS_LATENCY_MS, /* milliseconds */ + .c_to_p_interval = DEFAULT_CIS_INTERVAL_US, /* in microseconds */ + .p_to_c_interval = DEFAULT_CIS_INTERVAL_US, /* in microseconds */ + .c_to_p_latency = DEFAULT_CIS_LATENCY_MS, /* milliseconds */ + .p_to_c_latency = DEFAULT_CIS_LATENCY_MS, /* milliseconds */ .sca = BT_GAP_SCA_UNKNOWN, .packing = DEFAULT_CIS_PACKING, .framing = DEFAULT_CIS_FRAMING, @@ -179,6 +186,7 @@ static void iso_send(struct bt_iso_chan *chan) int ret; struct net_buf *buf; struct iso_chan_work *chan_work; + uint32_t interval; chan_work = CONTAINER_OF(chan, struct iso_chan_work, chan); @@ -186,10 +194,13 @@ static void iso_send(struct bt_iso_chan *chan) return; } + interval = (role == ROLE_CENTRAL) ? + cig_create_param.c_to_p_interval : cig_create_param.p_to_c_interval; + buf = net_buf_alloc(&tx_pool, K_FOREVER); if (buf == NULL) { LOG_ERR("Could not allocate buffer"); - k_work_reschedule(&chan_work->send_work, K_USEC(cig_create_param.interval)); + k_work_reschedule(&chan_work->send_work, K_USEC(interval)); return; } @@ -201,7 +212,7 @@ static void iso_send(struct bt_iso_chan *chan) if (ret < 0) { LOG_ERR("Unable to send data: %d", ret); net_buf_unref(buf); - k_work_reschedule(&chan_work->send_work, K_USEC(cig_create_param.interval)); + k_work_reschedule(&chan_work->send_work, K_USEC(interval)); return; } @@ -535,14 +546,18 @@ static int parse_rtn_arg(struct bt_iso_chan_io_qos *qos) return (int)rtn; } -static int parse_interval_arg(void) +static int parse_interval_arg(enum sdu_dir direction) { char buffer[9]; size_t char_count; uint64_t interval; - printk("Set interval (us) (current %u, default %u)\n", - cig_create_param.interval, DEFAULT_CIS_INTERVAL_US); + interval = (direction == DIR_C_TO_P) ? + cig_create_param.c_to_p_interval : cig_create_param.p_to_c_interval; + + printk("Set %s interval (us) (current %llu, default %u)\n", + (direction == DIR_C_TO_P) ? "C to P" : "P to C", + interval, DEFAULT_CIS_INTERVAL_US); char_count = get_chars(buffer, sizeof(buffer) - 1); if (char_count == 0) { @@ -550,7 +565,6 @@ static int parse_interval_arg(void) } interval = strtoul(buffer, NULL, 0); - /* TODO: Replace literal ints with a #define once it has been created */ if (interval < BT_ISO_SDU_INTERVAL_MIN || interval > BT_ISO_SDU_INTERVAL_MAX) { printk("Invalid interval %llu", interval); return -EINVAL; @@ -559,14 +573,18 @@ static int parse_interval_arg(void) return (int)interval; } -static int parse_latency_arg(void) +static int parse_latency_arg(enum sdu_dir direction) { char buffer[6]; size_t char_count; uint64_t latency; - printk("Set latency (ms) (current %u, default %u)\n", - cig_create_param.latency, DEFAULT_CIS_LATENCY_MS); + latency = (direction == DIR_C_TO_P) ? + cig_create_param.c_to_p_latency : cig_create_param.p_to_c_latency; + + printk("Set %s latency (ms) (current %llu, default %u)\n", + (direction == DIR_C_TO_P) ? "C to P" : "P to C", + latency, DEFAULT_CIS_LATENCY_MS); char_count = get_chars(buffer, sizeof(buffer) - 1); if (char_count == 0) { @@ -805,8 +823,10 @@ static int parse_cis_count_arg(void) static int parse_cig_args(void) { - int interval; - int latency; + int c_to_p_interval; + int p_to_c_interval; + int c_to_p_latency; + int p_to_c_latency; int cis_count; #if defined(CONFIG_BT_ISO_TEST_PARAMS) int c_to_p_ft; @@ -822,13 +842,23 @@ static int parse_cig_args(void) return -EINVAL; } - interval = parse_interval_arg(); - if (interval < 0) { + c_to_p_interval = parse_interval_arg(DIR_C_TO_P); + if (c_to_p_interval < 0) { + return -EINVAL; + } + + p_to_c_interval = parse_interval_arg(DIR_P_TO_C); + if (p_to_c_interval < 0) { + return -EINVAL; + } + + c_to_p_latency = parse_latency_arg(DIR_C_TO_P); + if (c_to_p_latency < 0) { return -EINVAL; } - latency = parse_latency_arg(); - if (latency < 0) { + p_to_c_latency = parse_latency_arg(DIR_P_TO_C); + if (p_to_c_latency < 0) { return -EINVAL; } @@ -854,8 +884,10 @@ static int parse_cig_args(void) } #endif /* CONFIG_BT_ISO_TEST_PARAMS */ - cig_create_param.interval = interval; - cig_create_param.latency = latency; + cig_create_param.c_to_p_interval = c_to_p_interval; + cig_create_param.p_to_c_interval = p_to_c_interval; + cig_create_param.c_to_p_latency = c_to_p_latency; + cig_create_param.p_to_c_latency = p_to_c_latency; cig_create_param.num_cis = cis_count; #if defined(CONFIG_BT_ISO_TEST_PARAMS) cig_create_param.c_to_p_ft = c_to_p_ft; @@ -923,9 +955,11 @@ static int change_central_settings(void) int err; printk("Change CIG settings (y/N)? (Current settings: cis_count=%u, " - "interval=%u, latency=%u)\n", - cig_create_param.num_cis, cig_create_param.interval, - cig_create_param.latency); + "C to P interval=%u, P to C interval=%u " + "C to P latency=%u, P to C latency=%u)\n", + cig_create_param.num_cis, cig_create_param.c_to_p_interval, + cig_create_param.p_to_c_interval, cig_create_param.c_to_p_latency, + cig_create_param.p_to_c_latency); c = tolower(console_getchar()); if (c == 'y') { @@ -934,9 +968,12 @@ static int change_central_settings(void) return err; } - printk("New settings: cis_count=%u, inteval=%u, latency=%u\n", - cig_create_param.num_cis, cig_create_param.interval, - cig_create_param.latency); + printk("New settings: cis_count=%u, C to P interval=%u, " + "P TO C interval=%u, C to P latency=%u " + "P TO C latency=%u\n", + cig_create_param.num_cis, cig_create_param.c_to_p_interval, + cig_create_param.p_to_c_interval, cig_create_param.c_to_p_latency, + cig_create_param.p_to_c_latency); } printk("Change TX settings (y/N)? (Current settings: rtn=%u, " diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 09d1eb1203b..933db93ec72 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -2090,8 +2090,10 @@ static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param, { cig_param->framing = qos->framing; cig_param->packing = BT_ISO_PACKING_SEQUENTIAL; /* TODO: Add to QoS struct */ - cig_param->interval = qos->interval; - cig_param->latency = qos->latency; + cig_param->c_to_p_interval = qos->interval; + cig_param->p_to_c_interval = qos->interval; + cig_param->c_to_p_latency = qos->latency; + cig_param->p_to_c_latency = qos->latency; cig_param->sca = BT_GAP_SCA_UNKNOWN; if (group_param != NULL) { diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 2422574e3bb..45c1f91b599 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -1524,18 +1524,22 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, memset(req, 0, sizeof(*req)); req->cig_id = cig->id; - req->c_latency = sys_cpu_to_le16(param->latency); - req->p_latency = sys_cpu_to_le16(param->latency); - sys_put_le24(param->interval, req->c_interval); - sys_put_le24(param->interval, req->p_interval); + req->c_latency = sys_cpu_to_le16(param->c_to_p_latency); + req->p_latency = sys_cpu_to_le16(param->p_to_c_latency); + sys_put_le24(param->c_to_p_interval, req->c_interval); + sys_put_le24(param->p_to_c_interval, req->p_interval); req->sca = param->sca; req->packing = param->packing; req->framing = param->framing; req->num_cis = param->num_cis; - LOG_DBG("id %u, latency %u, interval %u, sca %u, packing %u, framing %u, num_cis %u", - cig->id, param->latency, param->interval, param->sca, param->packing, + LOG_DBG("id %u, latency C to P %u, latency P to C %u, " + "interval C to P %u, interval P to C %u, " + "sca %u, packing %u, framing %u, num_cis %u", + cig->id, param->c_to_p_latency, param->p_to_c_latency, + param->c_to_p_interval, param->p_to_c_interval, + param->sca, param->packing, param->framing, param->num_cis); /* Program the cis parameters */ @@ -1611,8 +1615,8 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, memset(req, 0, sizeof(*req)); req->cig_id = cig->id; - sys_put_le24(param->interval, req->c_interval); - sys_put_le24(param->interval, req->p_interval); + sys_put_le24(param->c_to_p_interval, req->c_interval); + sys_put_le24(param->p_to_c_interval, req->p_interval); req->c_ft = param->c_to_p_ft; req->p_ft = param->p_to_c_ft; @@ -1622,10 +1626,10 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, req->framing = param->framing; req->num_cis = param->num_cis; - LOG_DBG("id %u, SDU interval %u, c_ft %u, p_ft %u, iso_interval %u, " - "sca %u, packing %u, framing %u, num_cis %u", - cig->id, param->interval, param->c_to_p_ft, param->p_to_c_ft, - param->iso_interval, param->sca, param->packing, + LOG_DBG("id %u, SDU interval C to P %u, SDU interval P to C %u, c_ft %u, p_ft %u, " + "iso_interval %u, sca %u, packing %u, framing %u, num_cis %u", + cig->id, param->c_to_p_interval, param->p_to_c_interval, param->c_to_p_ft, + param->p_to_c_ft, param->iso_interval, param->sca, param->packing, param->framing, param->num_cis); /* Program the cis parameters */ @@ -1859,16 +1863,28 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, return false; } - if (param->interval < BT_ISO_SDU_INTERVAL_MIN || - param->interval > BT_ISO_SDU_INTERVAL_MAX) { - LOG_DBG("Invalid interval: %u", param->interval); + if (param->c_to_p_interval < BT_ISO_SDU_INTERVAL_MIN || + param->c_to_p_interval > BT_ISO_SDU_INTERVAL_MAX) { + LOG_DBG("Invalid C to P interval: %u", param->c_to_p_interval); + return false; + } + + if (param->p_to_c_interval < BT_ISO_SDU_INTERVAL_MIN || + param->p_to_c_interval > BT_ISO_SDU_INTERVAL_MAX) { + LOG_DBG("Invalid P to C interval: %u", param->p_to_c_interval); return false; } if (!advanced && - (param->latency < BT_ISO_LATENCY_MIN || - param->latency > BT_ISO_LATENCY_MAX)) { - LOG_DBG("Invalid latency: %u", param->latency); + (param->c_to_p_latency < BT_ISO_LATENCY_MIN || + param->c_to_p_latency > BT_ISO_LATENCY_MAX)) { + LOG_DBG("Invalid C to P latency: %u", param->c_to_p_latency); + return false; + } + if (!advanced && + (param->p_to_c_latency < BT_ISO_LATENCY_MIN || + param->p_to_c_latency > BT_ISO_LATENCY_MAX)) { + LOG_DBG("Invalid P to C latency: %u", param->p_to_c_latency); return false; } diff --git a/subsys/bluetooth/shell/iso.c b/subsys/bluetooth/shell/iso.c index dcfdcfa9cb7..89fb273efd7 100644 --- a/subsys/bluetooth/shell/iso.c +++ b/subsys/bluetooth/shell/iso.c @@ -136,6 +136,56 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), #if defined(CONFIG_BT_ISO_CENTRAL) static struct bt_iso_cig *cig; +static long parse_interval(const struct shell *sh, const char *interval_str) +{ + unsigned long interval; + int err; + + err = 0; + interval = shell_strtoul(interval_str, 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse interval: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(interval, + BT_ISO_SDU_INTERVAL_MIN, + BT_ISO_SDU_INTERVAL_MAX)) { + shell_error(sh, "Invalid interval %lu", interval); + + return -ENOEXEC; + } + + return interval; +} + +static long parse_latency(const struct shell *sh, const char *latency_str) +{ + unsigned long latency; + int err; + + err = 0; + latency = shell_strtoul(latency_str, 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse latency: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(latency, + BT_ISO_LATENCY_MIN, + BT_ISO_LATENCY_MAX)) { + shell_error(sh, "Invalid latency %lu", latency); + + return -ENOEXEC; + } + + return latency; +} + + + static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) { int err; @@ -164,33 +214,44 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) err = 0; if (argc > 2) { - unsigned long interval; + long interval; interval = shell_strtoul(argv[2], 0, &err); - if (err != 0) { - shell_error(sh, "Could not parse interval: %d", err); - - return -ENOEXEC; + interval = parse_interval(sh, argv[2]); + if (interval < 0) { + return interval; } - if (!IN_RANGE(interval, - BT_ISO_SDU_INTERVAL_MIN, - BT_ISO_SDU_INTERVAL_MAX)) { - shell_error(sh, "Invalid interval %lu", interval); + param.c_to_p_interval = interval; + } else { + param.c_to_p_interval = 10000; + } - return -ENOEXEC; + if (argc > 3) { + long interval; + + interval = parse_interval(sh, argv[3]); + if (interval < 0) { + return interval; } - param.interval = interval; + param.p_to_c_interval = interval; } else { - param.interval = 10000; + param.p_to_c_interval = param.c_to_p_interval; } - cis_sdu_interval_us = param.interval; - if (argc > 3) { + /* cis_sdu_interval_us is used to increase the sequence number. + * cig_create can be called before an ACL is created, so the role + * information may not be available. + * Since we are central however we can safely set the cis_sdu_interval + * to the Central to Peer interval + */ + cis_sdu_interval_us = param.c_to_p_interval; + + if (argc > 4) { unsigned long packing; - packing = shell_strtoul(argv[3], 0, &err); + packing = shell_strtoul(argv[4], 0, &err); if (err != 0) { shell_error(sh, "Could not parse packing: %d", err); @@ -208,10 +269,10 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) param.packing = 0; } - if (argc > 4) { + if (argc > 5) { unsigned long framing; - framing = shell_strtoul(argv[4], 0, &err); + framing = shell_strtoul(argv[5], 0, &err); if (err != 0) { shell_error(sh, "Could not parse framing: %d", err); @@ -229,33 +290,38 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) param.framing = 0; } - if (argc > 5) { - unsigned long latency; + if (argc > 6) { + long latency; - latency = shell_strtoul(argv[5], 0, &err); - if (err != 0) { - shell_error(sh, "Could not parse latency: %d", err); + latency = parse_latency(sh, argv[6]); - return -ENOEXEC; + if (latency < 0) { + return latency; } - if (!IN_RANGE(latency, - BT_ISO_LATENCY_MIN, - BT_ISO_LATENCY_MAX)) { - shell_error(sh, "Invalid latency %lu", latency); + param.c_to_p_latency = latency; + } else { + param.c_to_p_latency = 10; + } - return -ENOEXEC; + if (argc > 7) { + long latency; + + latency = parse_latency(sh, argv[7]); + + if (latency < 0) { + return latency; } - param.latency = latency; + param.p_to_c_latency = latency; } else { - param.latency = 10; + param.p_to_c_latency = param.c_to_p_latency; } - if (argc > 6) { + if (argc > 7) { unsigned long sdu; - sdu = shell_strtoul(argv[6], 0, &err); + sdu = shell_strtoul(argv[7], 0, &err); if (err != 0) { shell_error(sh, "Could not parse sdu: %d", err); @@ -277,10 +343,10 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) } } - if (argc > 7) { + if (argc > 8) { unsigned long phy; - phy = shell_strtoul(argv[7], 0, &err); + phy = shell_strtoul(argv[8], 0, &err); if (err != 0) { shell_error(sh, "Could not parse phy: %d", err); @@ -304,10 +370,10 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) } } - if (argc > 8) { + if (argc > 9) { unsigned long rtn; - rtn = shell_strtoul(argv[8], 0, &err); + rtn = shell_strtoul(argv[9], 0, &err); if (err != 0) { shell_error(sh, "Could not parse rtn: %d", err); @@ -860,8 +926,9 @@ static int cmd_big_term(const struct shell *sh, size_t argc, char *argv[]) SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds, #if defined(CONFIG_BT_ISO_UNICAST) #if defined(CONFIG_BT_ISO_CENTRAL) - SHELL_CMD_ARG(cig_create, NULL, "[dir=tx,rx,txrx] [interval] [packing] [framing] " - "[latency] [sdu] [phy] [rtn]", cmd_cig_create, 1, 8), + SHELL_CMD_ARG(cig_create, NULL, "[dir=tx,rx,txrx] [C to P interval] [P to C interval] " + "[packing] [framing] [C to P latency] [P to C latency] [sdu] [phy] [rtn]", + cmd_cig_create, 1, 10), SHELL_CMD_ARG(cig_term, NULL, "Terminate the CIG", cmd_cig_term, 1, 0), #if defined(CONFIG_BT_SMP) SHELL_CMD_ARG(connect, NULL, "Connect ISO Channel [security level]", cmd_connect, 1, 1), diff --git a/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c index 2c16bb110f4..c86741bcaf3 100644 --- a/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c +++ b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c @@ -18,6 +18,7 @@ static struct bt_iso_chan *default_chan = &iso_chans[0]; static struct bt_iso_cig *cig; static uint16_t seq_num; static volatile size_t enqueue_cnt; +static uint32_t latency_ms = 10U; /* 10ms */ static uint32_t interval_us = 10U * USEC_PER_MSEC; /* 10 ms */ NET_BUF_POOL_FIXED_DEFINE(tx_pool, ENQUEUE_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); @@ -173,18 +174,26 @@ static void init(void) } } +static void set_cig_defaults(struct bt_iso_cig_param *param) +{ + param->cis_channels = &default_chan; + param->num_cis = 1U; + param->sca = BT_GAP_SCA_UNKNOWN; + param->packing = BT_ISO_PACKING_SEQUENTIAL; + param->framing = BT_ISO_FRAMING_UNFRAMED; + param->c_to_p_latency = latency_ms; /* ms */ + param->p_to_c_latency = latency_ms; /* ms */ + param->c_to_p_interval = interval_us; /* us */ + param->p_to_c_interval = interval_us; /* us */ + +} + static void create_cig(void) { struct bt_iso_cig_param param; int err; - param.cis_channels = &default_chan; - param.num_cis = 1U; - param.sca = BT_GAP_SCA_UNKNOWN; - param.packing = BT_ISO_PACKING_SEQUENTIAL; - param.framing = BT_ISO_FRAMING_UNFRAMED; - param.latency = 10U; /* ms */ - param.interval = interval_us; /* us */ + set_cig_defaults(¶m); err = bt_iso_cig_create(¶m, &cig); if (err != 0) { @@ -194,6 +203,68 @@ static void create_cig(void) } } +static int reconfigure_cig_interval(struct bt_iso_cig_param *param) +{ + int err; + + /* Test modifying CIG parameter without any CIS */ + param->num_cis = 0U; + param->c_to_p_interval = 7500; /* us */ + param->p_to_c_interval = param->c_to_p_interval; + err = bt_iso_cig_reconfigure(cig, param); + if (err != 0) { + FAIL("Failed to reconfigure CIG to new interval (%d)\n", err); + + return err; + } + + err = bt_iso_cig_reconfigure(cig, param); + if (err != 0) { + FAIL("Failed to reconfigure CIG to same interval (%d)\n", err); + + return err; + } + + /* Test modifying to different values for both intervals */ + param->c_to_p_interval = 5000; /* us */ + param->p_to_c_interval = 2500; /* us */ + err = bt_iso_cig_reconfigure(cig, param); + if (err != 0) { + FAIL("Failed to reconfigure CIG to new interval (%d)\n", err); + + return err; + } + + return 0; +} + +static int reconfigure_cig_latency(struct bt_iso_cig_param *param) +{ + int err; + + /* Test modifying CIG latency without any CIS */ + param->num_cis = 0U; + param->c_to_p_latency = 20; /* ms */ + param->p_to_c_latency = param->c_to_p_latency; + err = bt_iso_cig_reconfigure(cig, param); + if (err != 0) { + FAIL("Failed to reconfigure CIG latency (%d)\n", err); + + return err; + } + + param->c_to_p_latency = 30; /* ms */ + param->p_to_c_latency = 40; /* ms */ + err = bt_iso_cig_reconfigure(cig, param); + if (err != 0) { + FAIL("Failed to reconfigure CIG for different latencies (%d)\n", err); + + return err; + } + + return 0; +} + static void reconfigure_cig(void) { struct bt_iso_chan *channels[2]; @@ -204,14 +275,7 @@ static void reconfigure_cig(void) channels[i] = &iso_chans[i]; } - /* Set parameters to same as the ones used to create the CIG */ - param.cis_channels = &default_chan; - param.num_cis = 1U; - param.sca = BT_GAP_SCA_UNKNOWN; - param.packing = BT_ISO_PACKING_SEQUENTIAL; - param.framing = BT_ISO_FRAMING_UNFRAMED; - param.latency = 10U; /* ms */ - param.interval = interval_us; /* us */ + set_cig_defaults(¶m); /* Test modifying existing CIS */ default_chan->qos->tx->rtn++; @@ -223,25 +287,25 @@ static void reconfigure_cig(void) return; } - /* Test modifying CIG parameter without any CIS */ - param.num_cis = 0U; - param.interval = 7500U; /* us */ - - err = bt_iso_cig_reconfigure(cig, ¶m); + /* Test modifying interval parameter */ + err = reconfigure_cig_interval(¶m); if (err != 0) { - FAIL("Failed to reconfigure CIG to new interval (%d)\n", err); + return; + } + /* Test modifying latency parameter */ + err = reconfigure_cig_latency(¶m); + if (err != 0) { return; } - /* Add CIS to the CIG and restore interval to 10ms */ + /* Add CIS to the CIG and restore all other parameters */ + set_cig_defaults(¶m); param.cis_channels = &channels[1]; - param.num_cis = 1U; - param.interval = interval_us; /* us */ err = bt_iso_cig_reconfigure(cig, ¶m); if (err != 0) { - FAIL("Failed to reconfigure CIG with new CIS and original interval (%d)\n", err); + FAIL("Failed to reconfigure CIG with new CIS and original parameters (%d)\n", err); return; } diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index dc4f455df8c..fe0530eba05 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -413,11 +413,14 @@ static void test_cis_central(void) cig_param.sca = BT_GAP_SCA_UNKNOWN; cig_param.packing = 0U; cig_param.framing = 0U; - cig_param.interval = ISO_INTERVAL_US; + cig_param.c_to_p_interval = ISO_INTERVAL_US; + cig_param.p_to_c_interval = ISO_INTERVAL_US; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { - cig_param.latency = ISO_LATENCY_FT_MS; + cig_param.c_to_p_latency = ISO_LATENCY_FT_MS; + cig_param.p_to_c_latency = ISO_LATENCY_FT_MS; } else { - cig_param.latency = ISO_LATENCY_MS; + cig_param.c_to_p_latency = ISO_LATENCY_MS; + cig_param.p_to_c_latency = ISO_LATENCY_MS; } printk("Create CIG..."); From e3d6aac5c00551353798ae995822bd12ece496d7 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Wed, 18 Oct 2023 13:18:24 +0200 Subject: [PATCH 2424/4498] Bluetooth: ISO: use IN_RANGE for CIG create parameters Use IN_RANGE instead of explicitly checking that a value is in between two other values Signed-off-by: Andries Kruithof --- subsys/bluetooth/host/iso.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 45c1f91b599..42e9c877a9a 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -1863,27 +1863,23 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, return false; } - if (param->c_to_p_interval < BT_ISO_SDU_INTERVAL_MIN || - param->c_to_p_interval > BT_ISO_SDU_INTERVAL_MAX) { + if (!IN_RANGE(param->c_to_p_interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) { LOG_DBG("Invalid C to P interval: %u", param->c_to_p_interval); return false; } - if (param->p_to_c_interval < BT_ISO_SDU_INTERVAL_MIN || - param->p_to_c_interval > BT_ISO_SDU_INTERVAL_MAX) { + if (!IN_RANGE(param->p_to_c_interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) { LOG_DBG("Invalid P to C interval: %u", param->p_to_c_interval); return false; } if (!advanced && - (param->c_to_p_latency < BT_ISO_LATENCY_MIN || - param->c_to_p_latency > BT_ISO_LATENCY_MAX)) { + !IN_RANGE(param->c_to_p_latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) { LOG_DBG("Invalid C to P latency: %u", param->c_to_p_latency); return false; } if (!advanced && - (param->p_to_c_latency < BT_ISO_LATENCY_MIN || - param->p_to_c_latency > BT_ISO_LATENCY_MAX)) { + !IN_RANGE(param->p_to_c_latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) { LOG_DBG("Invalid P to C latency: %u", param->p_to_c_latency); return false; } From 9ddca0bfc62e4b177d36d8625fdc8911bc8d1d7f Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Sat, 21 Oct 2023 18:23:00 +0800 Subject: [PATCH 2425/4498] debug: coredump: add name for backend and dump options This makes the backend and dump options more easily configurable via Kconfig. Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com> --- subsys/debug/coredump/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/debug/coredump/Kconfig b/subsys/debug/coredump/Kconfig index 5d31913dd7e..abeb0d3bda2 100644 --- a/subsys/debug/coredump/Kconfig +++ b/subsys/debug/coredump/Kconfig @@ -9,7 +9,7 @@ menuconfig DEBUG_COREDUMP if DEBUG_COREDUMP -choice +choice DEBUG_COREDUMP_BACKEND prompt "Coredump backend" default DEBUG_COREDUMP_BACKEND_LOGGING if LOG @@ -42,7 +42,7 @@ config DEBUG_COREDUMP_BACKEND_OTHER endchoice -choice +choice DEBUG_COREDUMP_MEMORY_DUMP prompt "Memory dump" default DEBUG_COREDUMP_MEMORY_DUMP_LINKER_RAM From ad1b1cf9784c527c46e9878d9e9c4a20a3b3fd78 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Fri, 13 Oct 2023 12:30:06 +0200 Subject: [PATCH 2426/4498] clang: target: Include gcc-m-fpu.cmake file File gcc-m-fpu.cmake is responsible for determining what should be passed to -mfpu option. Fortunately GCC and Clang options are compatible so we can use the file for clang. The list of supported -mfpu options can be found at https://github.com/llvm/llvm-project in llvm/include/llvm/TargetParser/ARMTargetParser.def file. Signed-off-by: Patryk Duda --- cmake/compiler/clang/target.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index 2289856941f..8dd1460280b 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -20,6 +20,7 @@ find_program(CMAKE_CXX_COMPILER clang++ ${find_program_clang_args}) if(NOT "${ARCH}" STREQUAL "posix") include(${ZEPHYR_BASE}/cmake/gcc-m-cpu.cmake) + include(${ZEPHYR_BASE}/cmake/gcc-m-fpu.cmake) if("${ARCH}" STREQUAL "arm") list(APPEND TOOLCHAIN_C_FLAGS From 05361edb1b32dea2e757509980a7b21025144c39 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 12 Oct 2023 18:23:04 +0200 Subject: [PATCH 2427/4498] net: shell: Fix TCP connect behavior Fix two issues with net tcp command: * The `net tcp` commands are still based on net_context API. For TCP, the API caller (net shell) should add one extra reference to the allocated net context, to prevent premature context release in case of connection teardown. Currently that was not the case, and the context was released too early, resulting in missing final ACK from the Zephyr side on connection close. * The net context API should not be called from the registered connect callback, as this creates a temporary deadlock situation. The net_context_connect() function blocks until the connection is established, or an error or timeout occurs. For that time the net_context mutex is being locked. In case of connection error (for example after receiving RST packet) the connect callback is called, indicating an error. If we try to call net_context API from within, a deadlock situation takes place, as the context mutex is still locked by the net_context_connect() (called from the shell thread). This blocks the further execution of the TCP stack and can result in an unexpected behavior (like for example retransmitting the SYN packet, which takes place from yet another thread, TCP work queue). Fix this, by releasing the net context not from the callback directly, but based on the return value from net_context_connect(). Signed-off-by: Robert Lubos --- subsys/net/lib/shell/tcp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index c8e8f24454e..f90e16b3b66 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -25,10 +25,6 @@ static void tcp_connected(struct net_context *context, { if (status < 0) { PR_SHELL(tcp_shell, "TCP connection failed (%d)\n", status); - - net_context_put(context); - - tcp_ctx = NULL; } else { PR_SHELL(tcp_shell, "TCP connected\n"); } @@ -207,8 +203,15 @@ static void tcp_connect(const struct shell *sh, char *host, uint16_t port, #define CONNECT_TIMEOUT K_SECONDS(3) #endif - net_context_connect(*ctx, &addr, addrlen, tcp_connected, - CONNECT_TIMEOUT, NULL); + net_context_ref(*ctx); + + ret = net_context_connect(*ctx, &addr, addrlen, tcp_connected, + CONNECT_TIMEOUT, NULL); + if (ret < 0) { + PR_WARNING("Connect failed!\n"); + net_context_put(*ctx); + tcp_ctx = NULL; + } } static void tcp_sent_cb(struct net_context *context, From e51c0442162e83dc14f07a45e5ad9287ad9f7094 Mon Sep 17 00:00:00 2001 From: Markus Becker Date: Wed, 2 Aug 2023 16:01:21 +0200 Subject: [PATCH 2428/4498] sensor: ltrf215a: LiteOn LTR-F216A New driver for I2C illuminance sensor LiteOn LTR-F216A. Datasheet: https://optoelectronics.liteon.com/upload/download/DS86-2019-0016/LTR-F216A_Final_DS_V1.4.PDF * Applied suggestions from code review * Removed retry mechanism Signed-off-by: Markus Becker Co-authored-by: Andy Sinclair --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/ltrf216a/CMakeLists.txt | 5 + drivers/sensor/ltrf216a/Kconfig | 12 ++ drivers/sensor/ltrf216a/ltrf216a.c | 176 ++++++++++++++++++++++++ dts/bindings/sensor/ltrf216a.yaml | 8 ++ dts/bindings/vendor-prefixes.txt | 1 + tests/drivers/build_all/sensor/i2c.dtsi | 7 +- 8 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 drivers/sensor/ltrf216a/CMakeLists.txt create mode 100644 drivers/sensor/ltrf216a/Kconfig create mode 100644 drivers/sensor/ltrf216a/ltrf216a.c create mode 100644 dts/bindings/sensor/ltrf216a.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index f6a57278943..613414069eb 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -81,6 +81,7 @@ add_subdirectory_ifdef(CONFIG_LSM6DSO16IS lsm6dso16is) add_subdirectory_ifdef(CONFIG_LSM6DSV16X lsm6dsv16x) add_subdirectory_ifdef(CONFIG_LSM9DS0_GYRO lsm9ds0_gyro) add_subdirectory_ifdef(CONFIG_LSM9DS0_MFD lsm9ds0_mfd) +add_subdirectory_ifdef(CONFIG_LTR_F216A ltrf216a) add_subdirectory_ifdef(CONFIG_MAX17055 max17055) add_subdirectory_ifdef(CONFIG_MAX17262 max17262) add_subdirectory_ifdef(CONFIG_MAX30101 max30101) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 2180d801df5..55bb4464607 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -137,6 +137,7 @@ source "drivers/sensor/lsm6dso16is/Kconfig" source "drivers/sensor/lsm6dsv16x/Kconfig" source "drivers/sensor/lsm9ds0_gyro/Kconfig" source "drivers/sensor/lsm9ds0_mfd/Kconfig" +source "drivers/sensor/ltrf216a/Kconfig" source "drivers/sensor/max17055/Kconfig" source "drivers/sensor/max17262/Kconfig" source "drivers/sensor/max30101/Kconfig" diff --git a/drivers/sensor/ltrf216a/CMakeLists.txt b/drivers/sensor/ltrf216a/CMakeLists.txt new file mode 100644 index 00000000000..f15dcc346b8 --- /dev/null +++ b/drivers/sensor/ltrf216a/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(ltrf216a.c) diff --git a/drivers/sensor/ltrf216a/Kconfig b/drivers/sensor/ltrf216a/Kconfig new file mode 100644 index 00000000000..fa9cfe9fdbf --- /dev/null +++ b/drivers/sensor/ltrf216a/Kconfig @@ -0,0 +1,12 @@ +# LTR-F216A light sensor configuration options + +# Copyright (c) 2023 Tridonic +# SPDX-License-Identifier: Apache-2.0 + +config LTR_F216A + bool "LiteOn LTR-F216A Light Sensor" + default y + depends on DT_HAS_LTR_F216A_ENABLED + select I2C + help + Enable driver for LiteOn LTR-F216A light sensors. diff --git a/drivers/sensor/ltrf216a/ltrf216a.c b/drivers/sensor/ltrf216a/ltrf216a.c new file mode 100644 index 00000000000..5f6f9282c75 --- /dev/null +++ b/drivers/sensor/ltrf216a/ltrf216a.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Tridonic + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ltr_f216a + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ltrf216a, CONFIG_SENSOR_LOG_LEVEL); + +/* + * Driver for I2C illuminance sensor LiteOn LTR-F216A. + * + * Datasheet: + * + + * 7bit Address 0x53 + * 8bit Address 0xA6 read + * 8bit Address 0xA7 write + + * NOT IMPLEMENTED: + * - Interrupt + * - Modifying Gain (using default x3) + * - Modifying Resolution (using default 100ms) + * - Modifying Measurement Rate (using default 100ms) + * - Modifying Window Factor (using default 1) + */ + +#define LTRF216A_ALS_RESET_MASK BIT(4) +#define LTRF216A_ALS_ENABLE_MASK BIT(1) + +#define LTRF216A_ALS_DATA_STATUS BIT(3) + +/* Part Number ID 7:4 0b1011 = 0xB */ +/* Revision ID 3:0 0b0001 = 0x1*/ +#define LTRF216A_PART_ID_VALUE 0xB1 + +#define LTRF216A_MAIN_CTRL 0x00 +#define LTRF216A_ALS_MEAS_RES 0x04 +#define LTRF216A_ALS_GAIN 0x05 +#define LTRF216A_PART_ID 0x06 +#define LTRF216A_MAIN_STATUS 0x07 +#define LTRF216A_ALS_CLEAR_DATA_0 0x0a +#define LTRF216A_ALS_CLEAR_DATA_1 0x0b +#define LTRF216A_ALS_CLEAR_DATA_2 0x0c +#define LTRF216A_ALS_DATA_0 0x0d +#define LTRF216A_ALS_DATA_1 0x0e +#define LTRF216A_ALS_DATA_2 0x0f +#define LTRF216A_INT_CFG 0x19 +#define LTRF216A_INT_PST 0x1a +#define LTRF216A_ALS_THRES_UP_0 0x21 +#define LTRF216A_ALS_THRES_UP_1 0x22 +#define LTRF216A_ALS_THRES_UP_2 0x23 +#define LTRF216A_ALS_THRES_LOW_0 0x24 +#define LTRF216A_ALS_THRES_LOW_1 0x25 +#define LTRF216A_ALS_THRES_LOW_2 0x26 + +#define LTRF216A_WIN_FAC 1 + +#define LTRF216A_NUMBER_DATA_REGISTERS 3 + +struct ltrf216a_data { + uint8_t sample[3]; +}; + +struct ltrf216a_config { + struct i2c_dt_spec i2c; +}; + +static int ltrf216a_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct ltrf216a_data *drv_data = dev->data; + const struct ltrf216a_config *config = dev->config; + uint8_t status; + int result; + uint8_t value; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_LIGHT); + + value = LTRF216A_ALS_ENABLE_MASK; + result = i2c_reg_write_byte_dt(&config->i2c, LTRF216A_MAIN_CTRL, LTRF216A_ALS_ENABLE_MASK); + if (result != 0) { + LOG_ERR("ltfr216a: enable failed"); + return result; + } + + result = i2c_reg_read_byte_dt(&config->i2c, LTRF216A_MAIN_STATUS, &status); + if (result != 0) { + LOG_ERR("ltfr216a: read main status failed"); + return -EIO; + } + + if ((status & LTRF216A_ALS_DATA_STATUS) == 0) { + LOG_WRN("ltfr216a: main status not ready"); + return -EBUSY; + } + + if (i2c_burst_read_dt(&config->i2c, LTRF216A_ALS_DATA_0, drv_data->sample, + LTRF216A_NUMBER_DATA_REGISTERS) != 0) { + LOG_ERR("ltfr216a: reading samples failed"); + return -EIO; + } + + return 0; +} + +static int ltrf216a_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct ltrf216a_data *drv_data = dev->data; + + if (chan != SENSOR_CHAN_LIGHT) { + return -ENOTSUP; + } + + uint32_t greendata = sys_get_le24(drv_data->sample); + + /* + * 0.45 -> 45 / 100, multiplied by 1000000 for millilux + * gain 3 (default), integration time 100ms=1 + */ + uint64_t microlux = (greendata * 45000 * LTRF216A_WIN_FAC * 10) / (3 * 1); + + val->val1 = microlux / 1000000; + val->val2 = microlux % 1000000; + + return 0; +} + +static const struct sensor_driver_api ltrf216a_driver_api = { + .sample_fetch = ltrf216a_sample_fetch, + .channel_get = ltrf216a_channel_get, +}; + +static int ltrf216a_chip_init(const struct device *dev) +{ + const struct ltrf216a_config *config = dev->config; + uint8_t value; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + if (i2c_reg_read_byte_dt(&config->i2c, LTRF216A_PART_ID, &value) != 0) { + return -EIO; + } + + if (value != LTRF216A_PART_ID_VALUE) { + LOG_ERR("Bad manufacturer id 0x%x", value); + return -ENOTSUP; + } + + return 0; +} + +#define LTRF216A_DEFINE(inst) \ + static struct ltrf216a_data ltrf216a_data_##inst; \ + \ + static const struct ltrf216a_config ltrf216a_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, ltrf216a_chip_init, NULL, <rf216a_data_##inst, \ + <rf216a_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, <rf216a_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(LTRF216A_DEFINE) diff --git a/dts/bindings/sensor/ltrf216a.yaml b/dts/bindings/sensor/ltrf216a.yaml new file mode 100644 index 00000000000..fdbd7304be0 --- /dev/null +++ b/dts/bindings/sensor/ltrf216a.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023, Trridonic +# SPDX-License-Identifier: Apache-2.0 + +description: LiteOn F216A ambient light sensor + +compatible: "ltr,f216a" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index f47aa335a33..aa514077e4d 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -352,6 +352,7 @@ lontium Lontium Semiconductor Corporation loongson Loongson Technology Corporation Limited lowrisc lowRISC Community Interest Company lsi LSI Corp. (LSI Logic) +ltr LiteOn OptoElectronics lwn Liebherr-Werk Nenzing GmbH lxa Linux Automation GmbH m5stack M5Stack diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 3fe5eee59e7..b0450a27f90 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -121,7 +121,7 @@ test_i2c_mpu9250: mpu9250@12 { gyro-dlpf = <5>; gyro-fs = <250>; accel-fs = <2>; - accel-dlpf="5.05"; + accel-dlpf = "5.05"; }; test_i2c_ina219: ina219@13 { @@ -782,3 +782,8 @@ test_i2c_mc3419: mc3419@75 { reg = <0x75>; int-gpios = <&test_gpio 0 0>; }; + +test_i2c_ltrf216a0: ltrf216a@76 { + compatible = "ltr,f216a"; + reg = <0x76>; +}; From 67309968cbec438abf21165eefc1c281ec87d8c4 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 11:20:21 +0300 Subject: [PATCH 2429/4498] net: utils: Add helpers for manipulating IPv4 mapped address Create a function that can create IPv4 mapped to IPv6 address. Create a function that can check if the IPv6 address is a mapped IPv4 one. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_ip.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/include/zephyr/net/net_ip.h b/include/zephyr/net/net_ip.h index a1c4294bd61..b392184a815 100644 --- a/include/zephyr/net/net_ip.h +++ b/include/zephyr/net/net_ip.h @@ -1239,6 +1239,39 @@ static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *add net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002); } +/** + * @brief Create IPv4 mapped IPv6 address + * + * @param addr4 IPv4 address + * @param addr6 IPv6 address to be created + */ +static inline void net_ipv6_addr_create_v4_mapped(const struct in_addr *addr4, + struct in6_addr *addr6) +{ + net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff, + ntohs(addr4->s4_addr16[0]), + ntohs(addr4->s4_addr16[1])); +} + +/** + * @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses + * look like \::ffff:a.b.c.d + * + * @param addr IPv6 address + * + * @return True if IPv6 address is a IPv4 mapped address, False otherwise. + */ +static inline bool net_ipv6_addr_is_v4_mapped(const struct in6_addr *addr) +{ + if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 && + UNALIGNED_GET(&addr->s6_addr32[1]) == 0 && + UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) { + return true; + } + + return false; +} + /** * @brief Create IPv6 address interface identifier * From 256d5fac4fc37031c663e18c8cdd9a418bd143b3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 11:43:29 +0300 Subject: [PATCH 2430/4498] net: utils: Print IPv4 mapped IPv6 addresses properly Add support for IPv4 mapped IPv6 addresses when converting IP address to a string in inet_ntop() function. Signed-off-by: Jukka Rissanen --- subsys/net/ip/utils.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index f71aa65936e..688784f5421 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -150,9 +150,9 @@ static int net_value_to_udec(char *buf, uint32_t value, int precision) char *z_impl_net_addr_ntop(sa_family_t family, const void *src, char *dst, size_t size) { - struct in_addr *addr; - struct in6_addr *addr6; - uint16_t *w; + struct in_addr *addr = NULL; + struct in6_addr *addr6 = NULL; + uint16_t *w = NULL; uint8_t i, bl, bh, longest = 1U; int8_t pos = -1; char delim = ':'; @@ -161,12 +161,17 @@ char *z_impl_net_addr_ntop(sa_family_t family, const void *src, int len = -1; uint16_t value; bool needcolon = false; + bool mapped = false; if (family == AF_INET6) { addr6 = (struct in6_addr *)src; w = (uint16_t *)addr6->s6_addr16; len = 8; + if (net_ipv6_addr_is_v4_mapped(addr6)) { + mapped = true; + } + for (i = 0U; i < 8; i++) { uint8_t j; @@ -198,6 +203,7 @@ char *z_impl_net_addr_ntop(sa_family_t family, const void *src, return NULL; } +print_mapped: for (i = 0U; i < len; i++) { /* IPv4 address a.b.c.d */ if (len == 4) { @@ -220,6 +226,15 @@ char *z_impl_net_addr_ntop(sa_family_t family, const void *src, continue; } + if (mapped && (i > 5)) { + delim = '.'; + len = 4; + addr = (struct in_addr *)(&addr6->s6_addr32[3]); + *ptr++ = ':'; + family = AF_INET; + goto print_mapped; + } + /* IPv6 address */ if (i == pos) { if (needcolon || i == 0U) { From 4f37d63ed198ae9887dafead89a683101942ca18 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 5 Oct 2023 10:43:01 +0300 Subject: [PATCH 2431/4498] net: Add support for v4-mapping-to-v6 sockets This allows IPv4 and IPv6 share the same port space. User can still control the behavior of the v4-mapping-to-v6 by using the IPV6_V6ONLY socket option at runtime. Currently the IPv4 mapping to IPv6 is turned off by default, and also the IPV6_V6ONLY is true by default which means that IPv4 and IPv6 do not share the port space. Only way to use v4-mapping-to-v6 is to enable the Kconfig option and turn off the v6only socket option. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_context.h | 4 ++ subsys/net/ip/Kconfig | 12 ++++ subsys/net/ip/connection.c | 35 ++++++++++- subsys/net/ip/connection.h | 3 + subsys/net/ip/net_context.c | 104 +++++++++++++++++++++++++++++-- subsys/net/ip/net_private.h | 1 + subsys/net/ip/tcp.c | 30 +++++++++ subsys/net/lib/sockets/sockets.c | 30 ++++++++- 8 files changed, 209 insertions(+), 10 deletions(-) diff --git a/include/zephyr/net/net_context.h b/include/zephyr/net/net_context.h index 78a88aec0fe..6c0453a3d2b 100644 --- a/include/zephyr/net/net_context.h +++ b/include/zephyr/net/net_context.h @@ -328,6 +328,9 @@ __net_socket struct net_context { #endif #if defined(CONFIG_NET_CONTEXT_REUSEPORT) bool reuseport; +#endif +#if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) + bool ipv6_v6only; #endif } options; @@ -1081,6 +1084,7 @@ enum net_context_option { NET_OPT_DSCP_ECN = 8, NET_OPT_REUSEADDR = 9, NET_OPT_REUSEPORT = 10, + NET_OPT_IPV6_V6ONLY = 11, }; /** diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index af69f68f522..2683f52117c 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -143,6 +143,18 @@ source "subsys/net/ip/Kconfig.ipv6" source "subsys/net/ip/Kconfig.ipv4" +config NET_IPV4_MAPPING_TO_IPV6 + bool "Support IPv4 mapped on IPv6 addresses" + depends on NET_NATIVE_IPV6 + help + Support v4-mapped-on-v6 address type. This allows IPv4 and IPv6 + to share a local port space. When the application gets an IPv4 + connection or packet to an IPv6 socket, its source address will + be mapped to IPv6. This is turned off by default which means + that IPV6_V6ONLY socket option is always on. If you enable this + option, then you can still control the behaviour of the socket + via the IPV6_V6ONLY option at runtime. + config NET_SHELL bool "Network shell utilities" select SHELL diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 272cf1c5d84..b698a8775f5 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -380,6 +380,8 @@ int net_conn_register(uint16_t proto, uint8_t family, conn_set_used(conn); + conn->v6only = net_context_is_v6only_set(context); + conn_register_debug(conn, remote_port, local_port); return 0; @@ -668,7 +670,17 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, raw_pkt_continue = true; } } - continue; /* wrong protocol family */ + + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + if (!(conn->family == AF_INET6 && pkt_family == AF_INET && + !conn->v6only)) { + continue; + } + } else { + continue; /* wrong protocol family */ + } + + /* We might have a match for v4-to-v6 mapping, check more */ } /* Is the candidate connection matching the packet's protocol wihin the family? */ @@ -740,7 +752,26 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, if ((conn->flags & NET_CONN_LOCAL_ADDR_SET) && !conn_addr_cmp(pkt, ip_hdr, &conn->local_addr, false)) { - continue; /* wrong local address */ + + /* Check if we could do a v4-mapping-to-v6 and the IPv6 socket + * has no IPV6_V6ONLY option set and if the local IPV6 address + * is unspecified, then we could accept a connection from IPv4 + * address by mapping it to IPv6 address. + */ + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + if (!(conn->family == AF_INET6 && pkt_family == AF_INET && + !conn->v6only && + net_ipv6_is_addr_unspecified( + &net_sin6(&conn->local_addr)->sin6_addr))) { + continue; /* wrong local address */ + } + } else { + continue; /* wrong local address */ + } + + /* We might have a match for v4-to-v6 mapping, + * continue with rank checking. + */ } if (best_rank < NET_CONN_RANK(conn->flags)) { diff --git a/subsys/net/ip/connection.h b/subsys/net/ip/connection.h index 8269feb91a1..ee7ee0efc7d 100644 --- a/subsys/net/ip/connection.h +++ b/subsys/net/ip/connection.h @@ -79,6 +79,9 @@ struct net_conn { /** Flags for the connection */ uint8_t flags; + + /** Is v4-mapping-to-v6 enabled for this connection */ + uint8_t v6only : 1; }; /** diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index fc9e3b172d1..ef9fc640f08 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -78,6 +78,17 @@ bool net_context_is_reuseport_set(struct net_context *context) #endif } +bool net_context_is_v6only_set(struct net_context *context) +{ +#if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) + return context->options.ipv6_v6only; +#else + ARG_UNUSED(context); + + return true; +#endif +} + #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) static inline bool is_in_tcp_listen_state(struct net_context *context) { @@ -115,7 +126,6 @@ static int check_used_port(enum net_ip_protocol proto, const struct sockaddr *local_addr, bool reuseaddr_set, bool reuseport_set) - { int i; @@ -188,8 +198,14 @@ static int check_used_port(enum net_ip_protocol proto, } } else if (IS_ENABLED(CONFIG_NET_IPV4) && local_addr->sa_family == AF_INET) { + /* If there is an IPv6 socket already bound and + * if v6only option is enabled, then it is possible to + * bind IPv4 address to it. + */ if (net_sin_ptr(&contexts[i].local)->sin_addr == NULL || - net_sin_ptr(&contexts[i].local)->sin_family != AF_INET) { + ((IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) ? + net_context_is_v6only_set(&contexts[i]) : true) && + net_sin_ptr(&contexts[i].local)->sin_family != AF_INET)) { continue; } @@ -416,7 +432,10 @@ int net_context_get(sa_family_t family, enum net_sock_type type, uint16_t proto, #if defined(CONFIG_NET_CONTEXT_SNDTIMEO) contexts[i].options.sndtimeo = K_FOREVER; #endif - +#if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) + /* By default IPv4 and IPv6 are in different port spaces */ + contexts[i].options.ipv6_v6only = true; +#endif if (IS_ENABLED(CONFIG_NET_IP)) { (void)memset(&contexts[i].remote, 0, sizeof(struct sockaddr)); (void)memset(&contexts[i].local, 0, sizeof(struct sockaddr_ptr)); @@ -1496,6 +1515,36 @@ static int get_context_reuseport(struct net_context *context, #endif } +static int get_context_ipv6_v6only(struct net_context *context, + void *value, size_t *len) +{ +#if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) + if (!value || !len) { + return -EINVAL; + } + + if (*len != sizeof(int)) { + return -EINVAL; + } + + if (context->options.ipv6_v6only == true) { + *((int *)value) = (int) true; + } else { + *((int *)value) = (int) false; + } + + *len = sizeof(int); + + return 0; +#else + ARG_UNUSED(context); + ARG_UNUSED(value); + ARG_UNUSED(len); + + return -ENOTSUP; +#endif +} + /* If buf is not NULL, then use it. Otherwise read the data to be written * to net_pkt from msghdr. */ @@ -1726,8 +1775,21 @@ static int context_sendto(struct net_context *context, } else if (IS_ENABLED(CONFIG_NET_IPV4) && net_context_get_family(context) == AF_INET) { - const struct sockaddr_in *addr4 = - (const struct sockaddr_in *)dst_addr; + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)dst_addr; + struct sockaddr_in mapped; + + /* Get the destination address from the mapped IPv6 address */ + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) && + addr4->sin_family == AF_INET6 && + net_ipv6_addr_is_v4_mapped(&net_sin6(dst_addr)->sin6_addr)) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)dst_addr; + + mapped.sin_port = addr6->sin6_port; + mapped.sin_family = AF_INET; + net_ipaddr_copy(&mapped.sin_addr, + (struct in_addr *)(&addr6->sin6_addr.s6_addr32[3])); + addr4 = &mapped; + } if (msghdr) { addr4 = msghdr->msg_name; @@ -2591,6 +2653,32 @@ static int set_context_reuseport(struct net_context *context, #endif } +static int set_context_ipv6_v6only(struct net_context *context, + const void *value, size_t len) +{ +#if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) + bool v6only = false; + + if (len != sizeof(int)) { + return -EINVAL; + } + + if (*((int *) value) != 0) { + v6only = true; + } + + context->options.ipv6_v6only = v6only; + + return 0; +#else + ARG_UNUSED(context); + ARG_UNUSED(value); + ARG_UNUSED(len); + + return -ENOTSUP; +#endif +} + int net_context_set_option(struct net_context *context, enum net_context_option option, const void *value, size_t len) @@ -2636,6 +2724,9 @@ int net_context_set_option(struct net_context *context, case NET_OPT_REUSEPORT: ret = set_context_reuseport(context, value, len); break; + case NET_OPT_IPV6_V6ONLY: + ret = set_context_ipv6_v6only(context, value, len); + break; } k_mutex_unlock(&context->lock); @@ -2688,6 +2779,9 @@ int net_context_get_option(struct net_context *context, case NET_OPT_REUSEPORT: ret = get_context_reuseport(context, value, len); break; + case NET_OPT_IPV6_V6ONLY: + ret = get_context_ipv6_v6only(context, value, len); + break; } k_mutex_unlock(&context->lock); diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index d8d57a6bdc7..64c206cb042 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -71,6 +71,7 @@ extern void net_context_init(void); extern const char *net_context_state(struct net_context *context); extern bool net_context_is_reuseaddr_set(struct net_context *context); extern bool net_context_is_reuseport_set(struct net_context *context); +extern bool net_context_is_v6only_set(struct net_context *context); extern void net_pkt_init(void); extern void net_tc_tx_init(void); extern void net_tc_rx_init(void); diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 878cdca38a1..01da8662535 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2532,6 +2532,36 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) break; } + net_ipaddr_copy(&conn->context->remote, &conn->dst.sa); + + /* Check if v4-mapping-to-v6 needs to be done for + * the accepted socket. + */ + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) && + net_context_get_family(conn->context) == AF_INET && + net_context_get_family(context) == AF_INET6 && + !net_context_is_v6only_set(context)) { + struct in6_addr mapped; + + net_ipv6_addr_create_v4_mapped( + &net_sin(&conn->context->remote)->sin_addr, + &mapped); + net_ipaddr_copy(&net_sin6(&conn->context->remote)->sin6_addr, + &mapped); + + net_sin6(&conn->context->remote)->sin6_family = AF_INET6; + + NET_DBG("Setting v4 mapped address %s", + net_sprint_ipv6_addr(&mapped)); + + /* Note that we cannot set the local address to IPv6 one + * as that is used to match the connection, and not just + * for printing. The remote address is only used for + * passing it to accept() and printing it by "net conn" + * command. + */ + } + accept_cb(conn->context, &context->remote, sizeof(struct sockaddr), 0, context); diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 14d00581c97..dfa0b3e2c43 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2070,6 +2070,22 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname, case IPPROTO_IPV6: switch (optname) { + case IPV6_V6ONLY: + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + ret = net_context_get_option(ctx, + NET_OPT_IPV6_V6ONLY, + optval, + optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + + break; + case IPV6_TCLASS: if (IS_ENABLED(CONFIG_NET_CONTEXT_DSCP_ECN)) { ret = net_context_get_option(ctx, @@ -2407,9 +2423,17 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, case IPPROTO_IPV6: switch (optname) { case IPV6_V6ONLY: - /* Ignore for now. Provided to let port - * existing apps. - */ + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + ret = net_context_set_option(ctx, + NET_OPT_IPV6_V6ONLY, + optval, + optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + } + return 0; case IPV6_TCLASS: From 83aaeadddd09c20e9647e66f44b2df2165249a2e Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 5 Oct 2023 14:03:27 +0300 Subject: [PATCH 2432/4498] tests: net: socket: Add tests for IPV6_V6ONLY option The IPV6_V6ONLY option is only checked if CONFIG_NET_IPV4_MAPPED_TO_IPV6 option is set. By default the IPV6_V6ONLY option is set. Signed-off-by: Jukka Rissanen --- tests/net/socket/misc/CMakeLists.txt | 1 + tests/net/socket/misc/src/main.c | 276 ++++++++++++++++++++++++++- tests/net/socket/misc/testcase.yaml | 6 + 3 files changed, 282 insertions(+), 1 deletion(-) diff --git a/tests/net/socket/misc/CMakeLists.txt b/tests/net/socket/misc/CMakeLists.txt index 00b96b355a3..80fbd4a769d 100644 --- a/tests/net/socket/misc/CMakeLists.txt +++ b/tests/net/socket/misc/CMakeLists.txt @@ -4,5 +4,6 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(socket-misc) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/socket/misc/src/main.c b/tests/net/socket/misc/src/main.c index 384eafe6126..8e0dfa40224 100644 --- a/tests/net/socket/misc/src/main.c +++ b/tests/net/socket/misc/src/main.c @@ -14,6 +14,8 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include +#include "net_private.h" + #include "../../socket_helpers.h" ZTEST_USER(socket_misc_test_suite, test_gethostname) @@ -96,7 +98,7 @@ static int dummy_send(const struct device *dev, struct net_pkt *pkt) ARG_UNUSED(dev); ARG_UNUSED(pkt); - NET_DBG("Sending data (%zd bytes) to iface %d\n", + NET_DBG("Sending data (%zd bytes) to iface %d", net_pkt_get_len(pkt), net_if_get_by_iface(net_pkt_iface(pkt))); current_dev = dev; @@ -572,6 +574,263 @@ void test_getsockname_udp(int family) zassert_equal(ret, 0, "close failed, %d", errno); } +#define MAPPING_PORT 4244 + +void test_ipv4_mapped_to_ipv6_disabled(void) +{ + int ret; + int sock_s4, sock_s6; + struct sockaddr srv_addr4 = { 0 }; + struct sockaddr srv_addr6 = { 0 }; + + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + return; + } + + srv_addr4.sa_family = AF_INET; + net_sin(&srv_addr4)->sin_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET, TEST_MY_IPV4_ADDR, + &net_sin(&srv_addr4)->sin_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + srv_addr6.sa_family = AF_INET6; + net_sin6(&srv_addr6)->sin6_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET6, TEST_MY_IPV6_ADDR, + &net_sin6(&srv_addr6)->sin6_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + sock_s4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s4 >= 0, "socket open failed"); + + ret = bind(sock_s4, &srv_addr4, ADDR_SIZE(AF_INET)); + zassert_equal(ret, 0, "bind failed, %d", errno); + + ret = listen(sock_s4, 1); + zassert_equal(ret, 0, "listen failed, %d", errno); + + sock_s6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s6 >= 0, "socket open failed"); + + ret = bind(sock_s6, &srv_addr6, ADDR_SIZE(AF_INET6)); + zassert_equal(ret, 0, "bind failed, %d", errno); + + ret = close(sock_s4); + zassert_equal(ret, 0, "close failed, %d", errno); + ret = close(sock_s6); + zassert_equal(ret, 0, "close failed, %d", errno); +} + +void test_ipv4_mapped_to_ipv6_enabled(void) +{ + int off = 0, optlen = sizeof(int); + int ret; + int sock_s4, sock_s6; + struct sockaddr srv_addr4 = { 0 }; + struct sockaddr srv_addr6 = { 0 }; + + if (!IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + return; + } + + /* We must have bound to ANY address so that the + * v4-mapping-to-v6 works as expected. + */ + srv_addr4.sa_family = AF_INET; + net_sin(&srv_addr4)->sin_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET, "0.0.0.0", + &net_sin(&srv_addr4)->sin_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + srv_addr6.sa_family = AF_INET6; + net_sin6(&srv_addr6)->sin6_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET6, "::", + &net_sin6(&srv_addr6)->sin6_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + /* First create IPv6 socket */ + sock_s6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s6 >= 0, "socket open failed"); + + ret = bind(sock_s6, &srv_addr6, ADDR_SIZE(AF_INET6)); + zassert_equal(ret, 0, "bind failed, %d", errno); + + ret = listen(sock_s6, 1); + zassert_equal(ret, 0, "listen failed, %d", errno); + + /* Then try to create IPv4 socket to the same port */ + sock_s4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s4 >= 0, "socket open failed"); + + /* Initially the IPV6_V6ONLY is set so the next bind is ok */ + ret = bind(sock_s4, &srv_addr4, ADDR_SIZE(AF_INET)); + zassert_equal(ret, 0, "bind failed, %d", errno); + + ret = close(sock_s4); + zassert_equal(ret, 0, "close failed, %d", errno); + + /* Then we turn off IPV6_V6ONLY which means that IPv4 and IPv6 + * will have same port space and the next bind should fail. + */ + ret = setsockopt(sock_s6, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)); + zassert_equal(ret, 0, "setsockopt failed, %d", errno); + + ret = getsockopt(sock_s6, IPPROTO_IPV6, IPV6_V6ONLY, &off, &optlen); + zassert_equal(ret, 0, "getsockopt failed, %d", errno); + zassert_equal(off, 0, "IPV6_V6ONLY option setting failed"); + + sock_s4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s4 >= 0, "socket open failed"); + + /* Now v4 bind should fail */ + ret = bind(sock_s4, &srv_addr4, ADDR_SIZE(AF_INET)); + zassert_equal(ret, -1, "bind failed, %d", errno); + zassert_equal(errno, EADDRINUSE, "bind failed"); + + ret = close(sock_s4); + zassert_equal(ret, 0, "close failed, %d", errno); + ret = close(sock_s6); + zassert_equal(ret, 0, "close failed, %d", errno); +} + +void test_ipv4_mapped_to_ipv6_server(void) +{ + int off, optlen = sizeof(int); + int ret, len; + int sock_c4, sock_c6, sock_s6, new_sock; + struct sockaddr srv_addr6 = { 0 }; + struct sockaddr srv_addr = { 0 }; + struct sockaddr connect_addr6 = { 0 }; + struct sockaddr addr = { 0 }; + socklen_t addrlen = sizeof(addr); + struct sockaddr_in6 mapped; + +#define MAX_BUF_SIZE 16 + char buf[MAX_BUF_SIZE]; + + if (!IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) { + return; + } + + len = strlen("foobar"); + + /* Create a server socket and try to connect IPv4 + * socket to it. If v4-mapping-to-v6 is enabled, + * this will work and we should be bound internally + * to ::ffff:a.b.c.d IPv6 address. + */ + srv_addr.sa_family = AF_INET; + net_sin(&srv_addr)->sin_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET, "192.0.2.1", + &net_sin(&srv_addr)->sin_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + connect_addr6.sa_family = AF_INET6; + net_sin6(&connect_addr6)->sin6_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET6, TEST_PEER_IPV6_ADDR, + &net_sin6(&connect_addr6)->sin6_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + net_ipv6_addr_create_v4_mapped(&net_sin(&srv_addr)->sin_addr, + &mapped.sin6_addr); + + /* We must have bound to ANY address so that the + * v4-mapping-to-v6 works as expected. + */ + srv_addr6.sa_family = AF_INET6; + net_sin6(&srv_addr6)->sin6_port = htons(MAPPING_PORT); + ret = inet_pton(AF_INET6, "::", + &net_sin6(&srv_addr6)->sin6_addr); + zassert_equal(ret, 1, "inet_pton failed"); + + /* First create IPv6 socket */ + sock_s6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_s6 >= 0, "socket open failed"); + + /* Verify that by default the IPV6_V6ONLY option is set */ + ret = getsockopt(sock_s6, IPPROTO_IPV6, IPV6_V6ONLY, &off, &optlen); + zassert_equal(ret, 0, "getsockopt failed, %d", errno); + zassert_not_equal(off, 0, "IPV6_V6ONLY option setting failed"); + + /* Then we turn off IPV6_V6ONLY which means that IPv4 and IPv6 + * will have same port space. + */ + off = 0; + ret = setsockopt(sock_s6, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)); + zassert_equal(ret, 0, "setsockopt failed, %d", errno); + + ret = getsockopt(sock_s6, IPPROTO_IPV6, IPV6_V6ONLY, &off, &optlen); + zassert_equal(ret, 0, "getsockopt failed, %d", errno); + zassert_equal(off, 0, "IPV6_V6ONLY option setting failed, %d", off); + + ret = bind(sock_s6, &srv_addr6, ADDR_SIZE(AF_INET6)); + zassert_equal(ret, 0, "bind failed, %d", errno); + + ret = listen(sock_s6, 1); + zassert_equal(ret, 0, "listen failed, %d", errno); + + /* Then create IPv4 socket and connect to the IPv6 port */ + sock_c4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_c4 >= 0, "socket open failed"); + + ret = connect(sock_c4, &srv_addr, ADDR_SIZE(AF_INET)); + zassert_equal(ret, 0, "connect failed"); + + new_sock = accept(sock_s6, &addr, &addrlen); + zassert_true(new_sock >= 0, "accept failed, %d", errno); + + /* Note that we should get IPv6 address here (mapped from IPv4) */ + zassert_equal(addr.sa_family, AF_INET6, "wrong family"); + zassert_equal(addrlen, sizeof(struct sockaddr_in6), + "wrong addrlen (%d, expecting %d)", addrlen, + sizeof(struct sockaddr_in6)); + zassert_mem_equal(&mapped.sin6_addr, &net_sin6(&addr)->sin6_addr, + sizeof(struct in6_addr), + "wrong address (%s, expecting %s)", + net_sprint_ipv6_addr(&mapped.sin6_addr), + net_sprint_ipv6_addr(&net_sin6(&addr)->sin6_addr)); + + /* Send data back to IPv4 client from IPv6 socket */ + ret = send(new_sock, "foobar", len, 0); + zassert_equal(ret, len, "cannot send (%d vs %d), errno %d", ret, len, errno); + + addrlen = sizeof(struct sockaddr_in); + ret = recv(sock_c4, buf, sizeof(buf), 0); + zassert_equal(ret, strlen("foobar"), "cannot recv"); + + ret = close(sock_c4); + zassert_equal(ret, 0, "close failed, %d", errno); + + (void)close(new_sock); + + /* Let the system stabilize and cleanup itself */ + k_sleep(K_MSEC(200)); + + /* Then create IPv6 socket and make sure it works ok too */ + sock_c6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + zassert_true(sock_c6 >= 0, "socket open failed"); + + ret = connect(sock_c6, &connect_addr6, ADDR_SIZE(AF_INET6)); + zassert_equal(ret, 0, "connect failed, %d", errno); + + new_sock = accept(sock_s6, &addr, &addrlen); + zassert_true(new_sock >= 0, "accept failed, %d", errno); + + ret = send(new_sock, "foobar", len, 0); + zassert_equal(ret, len, "cannot send (%d vs %d), errno %d", ret, len, errno); + + addrlen = sizeof(struct sockaddr_in); + ret = recv(sock_c6, buf, sizeof(buf), 0); + zassert_equal(ret, strlen("foobar"), "cannot recv"); + + ret = close(sock_c6); + zassert_equal(ret, 0, "close failed, %d", errno); + + ret = close(sock_s6); + zassert_equal(ret, 0, "close failed, %d", errno); + ret = close(new_sock); + zassert_equal(ret, 0, "close failed, %d", errno); +} + ZTEST_USER(socket_misc_test_suite, test_ipv4_getsockname_tcp) { test_getsockname_tcp(AF_INET); @@ -610,4 +869,19 @@ ZTEST_USER(socket_misc_test_suite, test_ipv6) test_ipv6_getpeername(); } +ZTEST_USER(socket_misc_test_suite, test_ipv4_mapped_to_ipv6_disabled) +{ + test_ipv4_mapped_to_ipv6_disabled(); +} + +ZTEST_USER(socket_misc_test_suite, test_ipv4_mapped_to_ipv6_enabled) +{ + test_ipv4_mapped_to_ipv6_enabled(); +} + +ZTEST(socket_misc_test_suite, test_ipv4_mapped_to_ipv6_server) +{ + test_ipv4_mapped_to_ipv6_server(); +} + ZTEST_SUITE(socket_misc_test_suite, NULL, setup, NULL, NULL, NULL); diff --git a/tests/net/socket/misc/testcase.yaml b/tests/net/socket/misc/testcase.yaml index 0cb289659f9..49ae9b6bbe7 100644 --- a/tests/net/socket/misc/testcase.yaml +++ b/tests/net/socket/misc/testcase.yaml @@ -13,3 +13,9 @@ tests: net.socket.misc.userspace: extra_configs: - CONFIG_TEST_USERSPACE=y + net.socket.misc.v4_mapping_to_v6_enabled: + extra_configs: + - CONFIG_NET_IPV4_MAPPING_TO_IPV6=y + net.socket.misc.v4_mapping_to_v6_disabled: + extra_configs: + - CONFIG_NET_IPV4_MAPPING_TO_IPV6=n From dea896f6e7fc2ec315da798df006895efa988c00 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 11:18:09 +0300 Subject: [PATCH 2433/4498] net: tcp: Set address len properly when accepting a socket The address length of the accepted socket must reflect the size of the address struct, so it should either be sizeof(struct sockaddr_in) for IPv4 or sizeof(struct sockaddr_in6) for IPv6 socket. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 01da8662535..2f5a8759970 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2563,7 +2563,9 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) } accept_cb(conn->context, &context->remote, - sizeof(struct sockaddr), 0, context); + net_context_get_family(context) == AF_INET6 ? + sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in), + 0, context); next = TCP_ESTABLISHED; From 1b4a76cc3699564f81f5f76e490569843a9b64ce Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 13:32:18 +0300 Subject: [PATCH 2434/4498] net: tcp: Fix the accepted socket address The socket address passed in accept() call should point to the new connection address and not the old one. Fortunately this only affects things after the v4-mapping-to-v6 support so older code than this works fine. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 2f5a8759970..b709f6c7a04 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2562,7 +2562,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) */ } - accept_cb(conn->context, &context->remote, + accept_cb(conn->context, &conn->context->remote, net_context_get_family(context) == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in), 0, context); From 8a4ef3e67ace74699a8cc4a29ca5ae05d9be8ca0 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 14:11:09 +0300 Subject: [PATCH 2435/4498] samples: net: sockets: echo: Convert to work both IPv6 and IPv4 The sample enables CONFIG_NET_IPV4_MAPPING_TO_IPV6 and then turns off IPV6_V6ONLY option which allows it to support both IPv6 and IPv4 using the same socket. Signed-off-by: Jukka Rissanen --- samples/net/sockets/echo/README.rst | 11 +++---- samples/net/sockets/echo/prj.conf | 7 +++-- samples/net/sockets/echo/src/socket_echo.c | 34 ++++++++++++++++------ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/samples/net/sockets/echo/README.rst b/samples/net/sockets/echo/README.rst index 8a409b9e8f1..ca49115fd5d 100644 --- a/samples/net/sockets/echo/README.rst +++ b/samples/net/sockets/echo/README.rst @@ -2,15 +2,16 @@ :name: Echo server (simple) :relevant-api: bsd_sockets - Implements a simple IPv4 TCP echo server using BSD sockets. + Implements a simple IPv4/IPv6 TCP echo server using BSD sockets. Overview ******** -The sockets/echo sample application for Zephyr implements an IPv4 TCP echo -server using a BSD Sockets compatible API. The purpose of this sample is to -show how it's possible to develop a sockets application portable to both -POSIX and Zephyr. As such, it is kept minimal and supports only IPv4 and TCP. +The sockets/echo sample application for Zephyr implements a TCP echo +server supporting both IPv4 and IPv6 and using a BSD Sockets compatible API. +The purpose of this sample is to show how it's possible to develop a sockets +application portable to both POSIX and Zephyr. As such, it is kept minimal +and supports only IPv4, IPv6 and TCP. The source code for this sample application can be found at: :zephyr_file:`samples/net/sockets/echo`. diff --git a/samples/net/sockets/echo/prj.conf b/samples/net/sockets/echo/prj.conf index 6526148e0a1..3d25caa2924 100644 --- a/samples/net/sockets/echo/prj.conf +++ b/samples/net/sockets/echo/prj.conf @@ -1,14 +1,14 @@ # General config -CONFIG_NEWLIB_LIBC=y CONFIG_MAIN_STACK_SIZE=1200 # Networking config CONFIG_NETWORKING=y CONFIG_NET_IPV4=y -CONFIG_NET_IPV6=n +CONFIG_NET_IPV6=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_POSIX_NAMES=y +CONFIG_NET_IPV4_MAPPING_TO_IPV6=y # Network driver config CONFIG_TEST_RANDOM_GENERATOR=y @@ -16,5 +16,8 @@ CONFIG_TEST_RANDOM_GENERATOR=y # Network address config CONFIG_NET_CONFIG_SETTINGS=y CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_NEED_IPV6=y CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" diff --git a/samples/net/sockets/echo/src/socket_echo.c b/samples/net/sockets/echo/src/socket_echo.c index cf4d05f5780..5ebf954ff49 100644 --- a/samples/net/sockets/echo/src/socket_echo.c +++ b/samples/net/sockets/echo/src/socket_echo.c @@ -26,20 +26,36 @@ int main(void) { - int serv; - struct sockaddr_in bind_addr; + int opt, optlen = sizeof(int); + int serv, ret; + struct sockaddr_in6 bind_addr = { + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_ANY_INIT, + .sin6_port = htons(BIND_PORT), + }; static int counter; - serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - + serv = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (serv < 0) { printf("error: socket: %d\n", errno); exit(1); } - bind_addr.sin_family = AF_INET; - bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind_addr.sin_port = htons(BIND_PORT); + ret = getsockopt(serv, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &optlen); + if (ret == 0) { + if (opt) { + printf("IPV6_V6ONLY option is on, turning it off.\n"); + + opt = 0; + ret = setsockopt(serv, IPPROTO_IPV6, IPV6_V6ONLY, + &opt, optlen); + if (ret < 0) { + printf("Cannot turn off IPV6_V6ONLY option\n"); + } else { + printf("Sharing same socket between IPv6 and IPv4\n"); + } + } + } if (bind(serv, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) < 0) { printf("error: bind: %d\n", errno); @@ -55,7 +71,7 @@ int main(void) "port %d...\n", BIND_PORT); while (1) { - struct sockaddr_in client_addr; + struct sockaddr_in6 client_addr; socklen_t client_addr_len = sizeof(client_addr); char addr_str[32]; int client = accept(serv, (struct sockaddr *)&client_addr, @@ -66,7 +82,7 @@ int main(void) continue; } - inet_ntop(client_addr.sin_family, &client_addr.sin_addr, + inet_ntop(client_addr.sin6_family, &client_addr.sin6_addr, addr_str, sizeof(addr_str)); printf("Connection #%d from %s\n", counter++, addr_str); From e3f664dfe2f5279185c38bce8eafef3669a1123b Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 16:50:04 +0300 Subject: [PATCH 2436/4498] net: conn: Fix the rank value print We should use the NET_CONN_RANK() macro when printing the current rank value as that macro masks the rank values properly. Signed-off-by: Jukka Rissanen --- subsys/net/ip/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index b698a8775f5..35ef208a609 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -843,7 +843,7 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, if (best_match) { NET_DBG("[%p] match found cb %p ud %p rank 0x%02x", best_match, best_match->cb, - best_match->user_data, best_match->flags); + best_match->user_data, NET_CONN_RANK(best_match->flags)); if (best_match->cb(best_match, pkt, ip_hdr, proto_hdr, best_match->user_data) == NET_DROP) { From bc41d03e28b507fcfa288773466778b16f597559 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 6 Oct 2023 16:53:55 +0300 Subject: [PATCH 2437/4498] tests: net: socket: misc: Fix memory leak The sent pkt must be removed after we have cloned it in the simulated driver otherwise there is a memory leak. Signed-off-by: Jukka Rissanen --- tests/net/socket/misc/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/net/socket/misc/src/main.c b/tests/net/socket/misc/src/main.c index 8e0dfa40224..23060219815 100644 --- a/tests/net/socket/misc/src/main.c +++ b/tests/net/socket/misc/src/main.c @@ -96,7 +96,6 @@ static int dummy_send(const struct device *dev, struct net_pkt *pkt) int ret; ARG_UNUSED(dev); - ARG_UNUSED(pkt); NET_DBG("Sending data (%zd bytes) to iface %d", net_pkt_get_len(pkt), net_if_get_by_iface(net_pkt_iface(pkt))); @@ -114,6 +113,8 @@ static int dummy_send(const struct device *dev, struct net_pkt *pkt) ret = net_recv_data(net_pkt_iface(recv_pkt), recv_pkt); zassert_equal(ret, 0, "Cannot receive data (%d)", ret); + net_pkt_unref(pkt); + return 0; } From 2238baa83109019f34aefbbae8a1b9fb17b1ede8 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 9 Oct 2023 16:21:45 +0300 Subject: [PATCH 2438/4498] net: tcp: Do not overwrite remote address in new conn When a new incoming connection is accepted, do not overwrite the listening remote address. The remote address for the listening socket is the any address (like :: for IPv6) and not the accepted socket remote address. This only affects the "net conn" shell command which prints the remote address incorrectly. There is no problem accepting new connections in this case. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index b709f6c7a04..648a3720076 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1852,8 +1852,6 @@ static enum net_verdict tcp_recv(struct net_conn *net_conn, goto in; } - net_ipaddr_copy(&conn_old->context->remote, &conn->dst.sa); - conn->accepted_conn = conn_old; } in: From 63d9c8fa06ded8857cebb1ee99578a4acc3a8010 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 9 Oct 2023 17:18:34 +0300 Subject: [PATCH 2439/4498] net: shell: Print v4-mapping-to-v6 address properly The remote address of the connection is checked whether it is v4-mapping-to-v6 address in which case we should print it such. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/net_shell.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 38dac80a436..81191c77c20 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -99,10 +99,21 @@ void get_addresses(struct net_context *context, net_sprint_ipv4_addr( net_sin_ptr(&context->local)->sin_addr), ntohs(net_sin_ptr(&context->local)->sin_port)); - snprintk(addr_remote, remote_len, "%s:%d", - net_sprint_ipv4_addr( - &net_sin(&context->remote)->sin_addr), - ntohs(net_sin(&context->remote)->sin_port)); + + /* Check if we need to print the v4-mapping-to-v6 address */ + if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) && + net_sin(&context->remote)->sin_family == AF_INET6 && + net_ipv6_addr_is_v4_mapped(&net_sin6(&context->remote)->sin6_addr)) { + snprintk(addr_remote, remote_len, "[%s]:%d", + net_sprint_ipv6_addr( + &net_sin6(&context->remote)->sin6_addr), + ntohs(net_sin6(&context->remote)->sin6_port)); + } else { + snprintk(addr_remote, remote_len, "%s:%d", + net_sprint_ipv4_addr( + &net_sin(&context->remote)->sin_addr), + ntohs(net_sin(&context->remote)->sin_port)); + } } else if (context->local.family == AF_UNSPEC) { snprintk(addr_local, local_len, "AF_UNSPEC"); From f0326f72498cc572aa8692d7c6e875249cf35f06 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Tue, 17 Oct 2023 14:54:57 -0500 Subject: [PATCH 2440/4498] tests: dma_loopback: Intel ADSP ACE15 disable PM Disable power management for this particular test case as it expects a particular pattern of pm get/puts that isn't matched by the driver and usage in SoF. Signed-off-by: Tom Burdick --- drivers/dma/dma_intel_adsp_gpdma.c | 4 +++- drivers/power_domain/power_domain_intel_adsp.c | 3 +++ .../dma/loop_transfer/boards/intel_adsp_ace15_mtpm.conf | 7 ++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/dma/dma_intel_adsp_gpdma.c b/drivers/dma/dma_intel_adsp_gpdma.c index 1601d9af6ac..50e1fdae50e 100644 --- a/drivers/dma/dma_intel_adsp_gpdma.c +++ b/drivers/dma/dma_intel_adsp_gpdma.c @@ -320,6 +320,7 @@ static int intel_adsp_gpdma_enable(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE static int intel_adsp_gpdma_disable(const struct device *dev) { const struct intel_adsp_gpdma_cfg *const dev_cfg = dev->config; @@ -328,7 +329,8 @@ static int intel_adsp_gpdma_disable(const struct device *dev) sys_write32(sys_read32(reg) & ~SHIM_CLKCTL_LPGPDMA_SPA, reg); return 0; } -#endif +#endif /* CONFIG_PM_DEVICE */ +#endif /* CONFIG_SOC_SERIES_INTEL_ACE */ static int intel_adsp_gpdma_power_on(const struct device *dev) { diff --git a/drivers/power_domain/power_domain_intel_adsp.c b/drivers/power_domain/power_domain_intel_adsp.c index 21df893b127..c0ca87b652e 100644 --- a/drivers/power_domain/power_domain_intel_adsp.c +++ b/drivers/power_domain/power_domain_intel_adsp.c @@ -17,6 +17,7 @@ struct pg_bits { uint32_t CPA_bit; }; +#ifdef CONFIG_PM_DEVICE static int pd_intel_adsp_set_power_enable(struct pg_bits *bits, bool power_enable) { uint16_t SPA_bit_mask = BIT(bits->SPA_bit); @@ -65,6 +66,8 @@ static int pd_intel_adsp_pm_action(const struct device *dev, enum pm_device_acti return ret; } +#endif /* CONFIG_PM_DEVICE */ + static int pd_intel_adsp_init(const struct device *dev) { pm_device_init_suspended(dev); diff --git a/tests/drivers/dma/loop_transfer/boards/intel_adsp_ace15_mtpm.conf b/tests/drivers/dma/loop_transfer/boards/intel_adsp_ace15_mtpm.conf index 3707e852fcc..8c916f1ef93 100644 --- a/tests/drivers/dma/loop_transfer/boards/intel_adsp_ace15_mtpm.conf +++ b/tests/drivers/dma/loop_transfer/boards/intel_adsp_ace15_mtpm.conf @@ -1,5 +1,6 @@ -CONFIG_PM_DEVICE=y -CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_PM_DEVICE_POWER_DOMAIN=y +CONFIG_PM=n +CONFIG_PM_DEVICE=n +CONFIG_PM_DEVICE_RUNTIME=n +CONFIG_PM_DEVICE_POWER_DOMAIN=n CONFIG_POWER_DOMAIN=y CONFIG_POWER_DOMAIN_INTEL_ADSP=y From 99bb4b9581e27c4c2517025852208e29107c54f9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 31 Aug 2023 10:40:55 +0000 Subject: [PATCH 2441/4498] ci: testplan: fix include path Add zephyr to the include path detection. Signed-off-by: Anas Nashif --- scripts/ci/test_plan.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 8f2f24b0825..2d5e4dedce8 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -167,7 +167,7 @@ def find_modules(self): def find_archs(self): - # we match both arch//* and include/arch/ and skip common. + # we match both arch//* and include/zephyr/arch/ and skip common. # Some architectures like riscv require special handling, i.e. riscv # directory covers 2 architectures known to twister: riscv32 and riscv64. archs = set() @@ -175,7 +175,7 @@ def find_archs(self): for f in self.modified_files: p = re.match(r"^arch\/([^/]+)\/", f) if not p: - p = re.match(r"^include\/arch\/([^/]+)\/", f) + p = re.match(r"^include\/zephyr\/arch\/([^/]+)\/", f) if p: if p.group(1) != 'common': if p.group(1) == 'riscv': From b643692fa5dc7941411df9d52ea570187ecf1a96 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 31 Aug 2023 10:48:08 +0000 Subject: [PATCH 2442/4498] ci: test_plan: use integration mode for architectures Reduce the scope to integration only. Signed-off-by: Anas Nashif --- scripts/ci/test_plan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 2d5e4dedce8..19e5f893ca7 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -196,7 +196,7 @@ def find_archs(self): self.get_plan(_options, True) else: - self.get_plan(_options, False) + self.get_plan(_options, True) def find_boards(self): boards = set() From 96ed3a68a977a0dc8cbc3b08bc0dd77cf78a7de0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 23 Oct 2023 14:51:52 +0000 Subject: [PATCH 2443/4498] dts: mec1727nsz: fix few build issues This files has been changed as part of a refactoring in 13a87081b9. Unfortunately the refactoring introduced few issues: - usage of devicetree macros before their definition - usage of pinctrl label before the definition of the corresponding node - removal of few node overrides that are causing build errors Unfortunately there's no board usptream using this specific dts file, so the issue has not been caught in CI and was only found downstream. Signed-off-by: Fabio Baltieri --- dts/arm/microchip/mec1727nsz.dtsi | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dts/arm/microchip/mec1727nsz.dtsi b/dts/arm/microchip/mec1727nsz.dtsi index 62d4d0985d5..a7484a335bb 100644 --- a/dts/arm/microchip/mec1727nsz.dtsi +++ b/dts/arm/microchip/mec1727nsz.dtsi @@ -12,7 +12,9 @@ #include #include "mec172x/mec172x-vw-routing.dtsi" -#include "mec172x/mec172xnsz-pinctrl.dtsi" + +#include +#include / { cpus { @@ -83,6 +85,16 @@ }; }; +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&systick { + status = "disabled"; +}; + +#include "mec172x/mec172xnsz-pinctrl.dtsi" + &gpspi_wp_n_gpio076 { output-high; }; From 00e67753aca829bf615d94e909dd8e9ddd8e746f Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 18 Oct 2023 14:34:45 +1000 Subject: [PATCH 2444/4498] bluetooth: hci: spi: extract message handling to func Extract the HCI message handling out to a dedicated function to simplify the main thread function. This also solves a bug as a side effect. Previously `discardable` and `timeout` were never being reset after an advertising report was received, resulting in ALL events after the first advertising report being treated as discardable. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/spi.c | 116 ++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index b86f9ba35fb..558eb871e33 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -285,17 +285,72 @@ static int bt_spi_send_aci_config_data_controller_mode(void) } #endif /* CONFIG_BT_BLUENRG_ACI */ -static void bt_spi_rx_thread(void) +static struct net_buf *bt_spi_rx_buf_construct(uint8_t *msg) { bool discardable = false; k_timeout_t timeout = K_FOREVER; + struct bt_hci_acl_hdr acl_hdr; struct net_buf *buf; + int len; + + switch (msg[PACKET_TYPE]) { + case HCI_EVT: + switch (msg[EVT_HEADER_EVENT]) { + case BT_HCI_EVT_VENDOR: + /* Run event through interface handler */ + if (bt_spi_handle_vendor_evt(msg)) { + return NULL; + } + /* Event has not yet been handled */ + __fallthrough; + default: + if (msg[1] == BT_HCI_EVT_LE_META_EVENT && + (msg[3] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { + discardable = true; + timeout = K_NO_WAIT; + } + buf = bt_buf_get_evt(msg[EVT_HEADER_EVENT], + discardable, timeout); + if (!buf) { + LOG_DBG("Discard adv report due to insufficient buf"); + return NULL; + } + } + + len = sizeof(struct bt_hci_evt_hdr) + msg[EVT_HEADER_SIZE]; + if (len > net_buf_tailroom(buf)) { + LOG_ERR("Event too long: %d", len); + net_buf_unref(buf); + return NULL; + } + net_buf_add_mem(buf, &msg[1], len); + break; + case HCI_ACL: + buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); + memcpy(&acl_hdr, &msg[1], sizeof(acl_hdr)); + len = sizeof(acl_hdr) + sys_le16_to_cpu(acl_hdr.len); + if (len > net_buf_tailroom(buf)) { + LOG_ERR("ACL too long: %d", len); + net_buf_unref(buf); + return NULL; + } + net_buf_add_mem(buf, &msg[1], len); + break; + default: + LOG_ERR("Unknown BT buf type %d", msg[0]); + return NULL; + } + + return buf; +} + +static void bt_spi_rx_thread(void) +{ uint8_t header_master[5] = { SPI_READ, 0x00, 0x00, 0x00, 0x00 }; uint8_t header_slave[5]; - struct bt_hci_acl_hdr acl_hdr; + struct net_buf *buf; uint8_t size = 0U; int ret; - int len; (void)memset(&txmsg, 0xFF, SPI_MAX_MSG_LEN); while (true) { @@ -347,58 +402,13 @@ static void bt_spi_rx_thread(void) spi_dump_message("RX:ed", rxmsg, size); - switch (rxmsg[PACKET_TYPE]) { - case HCI_EVT: - switch (rxmsg[EVT_HEADER_EVENT]) { - case BT_HCI_EVT_VENDOR: - /* Run event through interface handler */ - if (bt_spi_handle_vendor_evt(rxmsg)) { - continue; - }; - /* Event has not yet been handled */ - __fallthrough; - default: - if (rxmsg[1] == BT_HCI_EVT_LE_META_EVENT && - (rxmsg[3] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { - discardable = true; - timeout = K_NO_WAIT; - } - - buf = bt_buf_get_evt(rxmsg[EVT_HEADER_EVENT], - discardable, timeout); - if (!buf) { - LOG_DBG("Discard adv report due to insufficient " - "buf"); - continue; - } - } - - len = sizeof(struct bt_hci_evt_hdr) + rxmsg[EVT_HEADER_SIZE]; - if (len > net_buf_tailroom(buf)) { - LOG_ERR("Event too long: %d", len); - net_buf_unref(buf); - continue; - } - net_buf_add_mem(buf, &rxmsg[1], len); - break; - case HCI_ACL: - buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); - memcpy(&acl_hdr, &rxmsg[1], sizeof(acl_hdr)); - len = sizeof(acl_hdr) + sys_le16_to_cpu(acl_hdr.len); - if (len > net_buf_tailroom(buf)) { - LOG_ERR("ACL too long: %d", len); - net_buf_unref(buf); - continue; - } - net_buf_add_mem(buf, &rxmsg[1], len); - break; - default: - LOG_ERR("Unknown BT buf type %d", rxmsg[0]); - continue; + /* Construct net_buf from SPI data */ + buf = bt_spi_rx_buf_construct(rxmsg); + if (buf) { + /* Handle the received HCI data */ + bt_recv(buf); } - bt_recv(buf); - /* On BlueNRG-MS, host is expected to read */ /* as long as IRQ pin is high */ } while (irq_pin_high()); From 322d4c1f98b0e6878a85825f67ee28cb294fe6c2 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 19 Oct 2023 15:47:47 +1000 Subject: [PATCH 2445/4498] bluetooth: hci: spi: avoid `rxmsg` re-use Don't re-use the `rxmsg` buffer in the `bt_spi_send` function. This buffer is still used by the RX thread after releasing the SPI semaphore. The current re-use can result in buffer corruption if the RX thread is swapped out as a result of the `k_sem_give`. Moving the semaphore release later can result in deadlocks due to buffer allocation being performed while holding the semaphore, so instead just eliminate the re-use entirely. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/spi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 558eb871e33..8f5656a70a0 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -417,7 +417,9 @@ static void bt_spi_rx_thread(void) static int bt_spi_send(struct net_buf *buf) { - uint8_t header[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 }; + uint8_t header_tx[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 }; + uint8_t header_rx[5]; + uint8_t rx_first[1]; int ret; LOG_DBG(""); @@ -447,22 +449,22 @@ static int bt_spi_send(struct net_buf *buf) /* Poll sanity values until device has woken-up */ do { kick_cs(); - ret = bt_spi_transceive(header, 5, rxmsg, 5); + ret = bt_spi_transceive(header_tx, 5, header_rx, 5); /* - * RX Header (rxmsg) must contain a sanity check Byte and size + * RX Header must contain a sanity check Byte and size * information. If it does not contain BOTH then it is * sleeping or still in the initialisation stage (waking-up). */ - } while ((rxmsg[STATUS_HEADER_READY] != READY_NOW || - (rxmsg[1] | rxmsg[2] | rxmsg[3] | rxmsg[4]) == 0U) && !ret); + } while ((header_rx[STATUS_HEADER_READY] != READY_NOW || + (header_rx[1] | header_rx[2] | header_rx[3] | header_rx[4]) == 0U) && !ret); if (!ret) { /* Transmit the message */ do { ret = bt_spi_transceive(buf->data, buf->len, - rxmsg, buf->len); - } while (rxmsg[0] == 0U && !ret); + rx_first, 1); + } while (rx_first[0] == 0U && !ret); } release_cs(); From 40ad8c87114a5a9b8b72a24c8db57a60cf1a82f9 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 Oct 2023 13:19:55 +0200 Subject: [PATCH 2446/4498] drivers: can: add bit error counter The bit error counter is incremented when the CAN controller is unable to transmit either a dominant or a recessive bit. This new error counter should only be incremented directly if the CAN controller is unable to distinquish between failure to transmit a dominant versus failure to transmit a recessive bit. If the CAN controller supports distinguishing between the two, either the `bit0` or `bit1` error counter shall be incremented instead. Incrementing one of these will automatically increment the bit error count as well. Typically, a CAN controller driver will either use this new bit error counter or the discrete bit0 and bit1 error counters depending on the features supported by the hardware. Mixing the two on driver level should not be required. Signed-off-by: Henrik Brix Andersen --- include/zephyr/drivers/can.h | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 4f2b2c1f2fb..e0cde5524ba 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -461,6 +461,7 @@ __subsystem struct can_driver_api { /** @cond INTERNAL_HIDDEN */ STATS_SECT_START(can) +STATS_SECT_ENTRY32(bit_error) STATS_SECT_ENTRY32(bit0_error) STATS_SECT_ENTRY32(bit1_error) STATS_SECT_ENTRY32(stuff_error) @@ -471,6 +472,7 @@ STATS_SECT_ENTRY32(rx_overrun) STATS_SECT_END; STATS_NAME_START(can) +STATS_NAME(can, bit_error) STATS_NAME(can, bit0_error) STATS_NAME(can, bit1_error) STATS_NAME(can, stuff_error) @@ -501,16 +503,41 @@ struct can_device_state { /** @endcond */ +/** + * @brief Increment the bit error counter for a CAN device + * + * The bit error counter is incremented when the CAN controller is unable to + * transmit either a dominant or a recessive bit. + * + * @note This error counter should only be incremented if the CAN controller is unable to + * distinquish between failure to transmit a dominant versus failure to transmit a recessive bit. If + * the CAN controller supports distinguishing between the two, the `bit0` or `bit1` error counter + * shall be incremented instead. + * + * @see CAN_STATS_BIT0_ERROR_INC() + * @see CAN_STATS_BIT1_ERROR_INC() + * + * @param dev_ Pointer to the device structure for the driver instance. + */ +#define CAN_STATS_BIT_ERROR_INC(dev_) \ + STATS_INC(Z_CAN_GET_STATS(dev_), bit_error) + /** * @brief Increment the bit0 error counter for a CAN device * * The bit0 error counter is incremented when the CAN controller is unable to * transmit a dominant bit. * + * Incrementing this counter will automatically increment the bit error counter. + * @see CAN_STATS_BIT_ERROR_INC() + * * @param dev_ Pointer to the device structure for the driver instance. */ -#define CAN_STATS_BIT0_ERROR_INC(dev_) \ - STATS_INC(Z_CAN_GET_STATS(dev_), bit0_error) +#define CAN_STATS_BIT0_ERROR_INC(dev_) \ + do { \ + STATS_INC(Z_CAN_GET_STATS(dev_), bit0_error); \ + CAN_STATS_BIT_ERROR_INC(dev_); \ + } while (0) /** * @brief Increment the bit1 (recessive) error counter for a CAN device @@ -518,10 +545,16 @@ struct can_device_state { * The bit1 error counter is incremented when the CAN controller is unable to * transmit a recessive bit. * + * Incrementing this counter will automatically increment the bit error counter. + * @see CAN_STATS_BIT_ERROR_INC() + * * @param dev_ Pointer to the device structure for the driver instance. */ -#define CAN_STATS_BIT1_ERROR_INC(dev_) \ - STATS_INC(Z_CAN_GET_STATS(dev_), bit1_error) +#define CAN_STATS_BIT1_ERROR_INC(dev_) \ + do { \ + STATS_INC(Z_CAN_GET_STATS(dev_), bit1_error); \ + CAN_STATS_BIT_ERROR_INC(dev_); \ + } while (0) /** * @brief Increment the stuffing error counter for a CAN device @@ -610,7 +643,7 @@ struct can_device_state { { \ struct can_device_state *state = \ CONTAINER_OF(dev->state, struct can_device_state, devstate); \ - stats_init(&state->stats.s_hdr, STATS_SIZE_32, 7, \ + stats_init(&state->stats.s_hdr, STATS_SIZE_32, 8, \ STATS_NAME_INIT_PARMS(can)); \ stats_register(dev->name, &(state->stats.s_hdr)); \ if (init_fn != NULL) { \ @@ -655,6 +688,7 @@ struct can_device_state { #else /* CONFIG_CAN_STATS */ +#define CAN_STATS_BIT_ERROR_INC(dev_) #define CAN_STATS_BIT0_ERROR_INC(dev_) #define CAN_STATS_BIT1_ERROR_INC(dev_) #define CAN_STATS_STUFF_ERROR_INC(dev_) From 473770679496d0f323c18897aa5cb9313351e67b Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 Oct 2023 13:27:37 +0200 Subject: [PATCH 2447/4498] drivers: can: sja1000: add CAN statistics support Add support for CAN statistics to the SJA1000 CAN controller driver. The hardware does not support distinguishing between being unable to transmit dominant versus being unable to transmit recessive bits. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_sja1000.c | 67 ++++++++++++++++++++++++++++++++++ drivers/can/can_sja1000_priv.h | 30 ++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index 9212778ad9d..571fc2fb040 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -163,6 +163,7 @@ int can_sja1000_start(const struct device *dev) } can_sja1000_clear_errors(dev); + CAN_STATS_RESET(dev); err = can_sja1000_leave_reset_mode(dev); if (err != 0) { @@ -599,6 +600,59 @@ static void can_sja1000_handle_transmit_irq(const struct device *dev) can_sja1000_tx_done(dev, status); } +#ifdef CONFIG_CAN_STATS +static void can_sja1000_handle_data_overrun_irq(const struct device *dev) +{ + /* See NXP SJA1000 Application Note AN97076 (figure 18) for data overrun details */ + + CAN_STATS_RX_OVERRUN_INC(dev); + + can_sja1000_write_reg(dev, CAN_SJA1000_CMR, CAN_SJA1000_CMR_CDO); +} + +static void can_sja1000_handle_bus_error_irq(const struct device *dev) +{ + /* See NXP SJA1000 Application Note AN97076 (tables 6 and 7) for ECC details */ + uint8_t ecc; + + /* Read the Error Code Capture register to re-activate it */ + ecc = can_sja1000_read_reg(dev, CAN_SJA1000_ECC); + + if (ecc == (CAN_SJA1000_ECC_ERRC_OTHER_ERROR | CAN_SJA1000_ECC_DIR_TX | + CAN_SJA1000_ECC_SEG_ACK_SLOT)) { + /* Missing ACK is reported as a TX "other" error in the ACK slot */ + CAN_STATS_ACK_ERROR_INC(dev); + return; + } + + if (ecc == (CAN_SJA1000_ECC_ERRC_FORM_ERROR | CAN_SJA1000_ECC_DIR_RX | + CAN_SJA1000_ECC_SEG_ACK_DELIM)) { + /* CRC error is reported as a RX "form" error in the ACK delimiter */ + CAN_STATS_CRC_ERROR_INC(dev); + return; + } + + switch (ecc & CAN_SJA1000_ECC_ERRC_MASK) { + case CAN_SJA1000_ECC_ERRC_BIT_ERROR: + CAN_STATS_BIT_ERROR_INC(dev); + break; + + case CAN_SJA1000_ECC_ERRC_FORM_ERROR: + CAN_STATS_FORM_ERROR_INC(dev); + break; + case CAN_SJA1000_ECC_ERRC_STUFF_ERROR: + CAN_STATS_STUFF_ERROR_INC(dev); + break; + + case CAN_SJA1000_ECC_ERRC_OTHER_ERROR: + __fallthrough; + default: + /* Other error not currently reported in CAN statistics */ + break; + } +} +#endif /* CONFIG_CAN_STATS */ + static void can_sja1000_handle_error_warning_irq(const struct device *dev) { struct can_sja1000_data *data = dev->data; @@ -650,6 +704,16 @@ void can_sja1000_isr(const struct device *dev) can_sja1000_handle_receive_irq(dev); } +#ifdef CONFIG_CAN_STATS + if ((ir & CAN_SJA1000_IR_DOI) != 0) { + can_sja1000_handle_data_overrun_irq(dev); + } + + if ((ir & CAN_SJA1000_IR_BEI) != 0) { + can_sja1000_handle_bus_error_irq(dev); + } +#endif /* CONFIG_CAN_STATS */ + if ((ir & CAN_SJA1000_IR_EI) != 0) { can_sja1000_handle_error_warning_irq(dev); } @@ -754,6 +818,9 @@ int can_sja1000_init(const struct device *dev) /* Enable interrupts */ can_sja1000_write_reg(dev, CAN_SJA1000_IER, +#ifdef CONFIG_CAN_STATS + CAN_SJA1000_IER_BEIE | CAN_SJA1000_IER_DOIE | +#endif /* CONFIG_CAN_STATS */ CAN_SJA1000_IER_RIE | CAN_SJA1000_IER_TIE | CAN_SJA1000_IER_EIE | CAN_SJA1000_IER_EPIE); diff --git a/drivers/can/can_sja1000_priv.h b/drivers/can/can_sja1000_priv.h index 03d5dbf0f0d..4a02b734a82 100644 --- a/drivers/can/can_sja1000_priv.h +++ b/drivers/can/can_sja1000_priv.h @@ -108,9 +108,37 @@ /* Error Code Capture register (ECC) bits */ #define CAN_SJA1000_ECC_SEG_MASK GENMASK(4, 0) -#define CAN_SJA1000_ECC_DIR BIT(5) +#define CAN_SJA1000_ECC_DIR_MASK BIT(5) #define CAN_SJA1000_ECC_ERRC_MASK GENMASK(7, 6) +#define CAN_SJA1000_ECC_SEG_SOF FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 3U) +#define CAN_SJA1000_ECC_SEG_ID28_TO_ID21 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 2U) +#define CAN_SJA1000_ECC_SEG_ID20_TO_ID18 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 6U) +#define CAN_SJA1000_ECC_SEG_SRTR FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 4U) +#define CAN_SJA1000_ECC_SEG_IDE FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 5U) +#define CAN_SJA1000_ECC_SEG_ID17_TO_ID13 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 7U) +#define CAN_SJA1000_ECC_SEG_ID12_TO_ID5 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 15U) +#define CAN_SJA1000_ECC_SEG_ID4_TO_ID0 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 14U) +#define CAN_SJA1000_ECC_SEG_RTR FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 12U) +#define CAN_SJA1000_ECC_SEG_RES1 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 13U) +#define CAN_SJA1000_ECC_SEG_RES0 FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 9U) +#define CAN_SJA1000_ECC_SEG_DLC FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 11U) +#define CAN_SJA1000_ECC_SEG_DATA FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 10U) +#define CAN_SJA1000_ECC_SEG_CRC_SEQ FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 8U) +#define CAN_SJA1000_ECC_SEG_CRC_DELIM FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 24U) +#define CAN_SJA1000_ECC_SEG_ACK_SLOT FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 25U) +#define CAN_SJA1000_ECC_SEG_ACK_DELIM FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 27U) +#define CAN_SJA1000_ECC_SEG_EOF FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 26U) +#define CAN_SJA1000_ECC_SEG_INTERMISSION FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 18U) +#define CAN_SJA1000_ECC_SEG_ACTIVE_ERROR_FLAG FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 17U) +#define CAN_SJA1000_ECC_SEG_PASSIVE_ERROR_FLAG FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 22U) +#define CAN_SJA1000_ECC_SEG_TOLERATE_DOM_BITS FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 19U) +#define CAN_SJA1000_ECC_SEG_ERROR_DELIM FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 23U) +#define CAN_SJA1000_ECC_SEG_OVERLOAD_FLAG FIELD_PREP(CAN_SJA1000_ECC_SEG_MASK, 28U) + +#define CAN_SJA1000_ECC_DIR_TX FIELD_PREP(CAN_SJA1000_ECC_DIR_MASK, 0U) +#define CAN_SJA1000_ECC_DIR_RX FIELD_PREP(CAN_SJA1000_ECC_DIR_MASK, 1U) + #define CAN_SJA1000_ECC_ERRC_BIT_ERROR FIELD_PREP(CAN_SJA1000_ECC_ERRC_MASK, 0U) #define CAN_SJA1000_ECC_ERRC_FORM_ERROR FIELD_PREP(CAN_SJA1000_ECC_ERRC_MASK, 1U) #define CAN_SJA1000_ECC_ERRC_STUFF_ERROR FIELD_PREP(CAN_SJA1000_ECC_ERRC_MASK, 2U) From 70cb934959a7383f8823c58364be7ad3e796afa6 Mon Sep 17 00:00:00 2001 From: Sophie 'Tyalie' Friedrich Date: Sun, 22 Oct 2023 18:10:58 +0200 Subject: [PATCH 2448/4498] boards: xiao_esp32s3: Fix connector definition Previously the seed connector was defined incorrectly and as such D6 and D7 weren't usable as i.e. inputs. Zephyr distinguishes GPIO pins in blocks of 32, a distinction the ESP32 reference manual doesn't do. As such one needs to write `&gpio1 11` in order to access `GPIO43`. Signed-off-by: Sophie 'Tyalie' Friedrich --- boards/xtensa/xiao_esp32s3/seeed_xiao_connector.dtsi | 4 ++-- boards/xtensa/xiao_esp32s3/xiao_esp32s3.dts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/boards/xtensa/xiao_esp32s3/seeed_xiao_connector.dtsi b/boards/xtensa/xiao_esp32s3/seeed_xiao_connector.dtsi index 2251ed92015..73fe66d28dc 100644 --- a/boards/xtensa/xiao_esp32s3/seeed_xiao_connector.dtsi +++ b/boards/xtensa/xiao_esp32s3/seeed_xiao_connector.dtsi @@ -16,8 +16,8 @@ <3 0 &gpio0 4 0>, /* D3 */ <4 0 &gpio0 5 0>, /* D4 */ <5 0 &gpio0 6 0>, /* D5 */ - <6 0 &gpio0 43 0>, /* D6 */ - <7 0 &gpio0 44 0>, /* D7 */ + <6 0 &gpio1 11 0>, /* D6 */ + <7 0 &gpio1 12 0>, /* D7 */ <8 0 &gpio0 7 0>, /* D8 */ <9 0 &gpio0 8 0>, /* D9 */ <10 0 &gpio0 9 0>; /* D10 */ diff --git a/boards/xtensa/xiao_esp32s3/xiao_esp32s3.dts b/boards/xtensa/xiao_esp32s3/xiao_esp32s3.dts index 3090f9ff5af..ecd7814bb6b 100644 --- a/boards/xtensa/xiao_esp32s3/xiao_esp32s3.dts +++ b/boards/xtensa/xiao_esp32s3/xiao_esp32s3.dts @@ -79,6 +79,10 @@ status = "okay"; }; +&gpio1 { + status = "okay"; +}; + &wdt0 { status = "okay"; }; From 7857996e90278ff5908107576addc142f53bf1ec Mon Sep 17 00:00:00 2001 From: Sophie 'Tyalie' Friedrich Date: Sun, 22 Oct 2023 18:22:01 +0200 Subject: [PATCH 2449/4498] boards: esp23: m5stack_core2: Fix i2c1 pin definitions For GPIO pins above 31, one needs to use the `&gpio1` (or similar) definition, as zephyr seperates GPIOs into chunks of 32. Signed-off-by: Sophie 'Tyalie' Friedrich --- boards/xtensa/m5stack_core2/m5stack_core2.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index 35ed29ae32f..f9417815330 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -167,8 +167,8 @@ &i2c1 { status = "disabled"; clock-frequency = ; - sda-gpios = <&gpio0 32 GPIO_OPEN_DRAIN>; - scl-gpios = <&gpio0 33 GPIO_OPEN_DRAIN>; + sda-gpios = <&gpio1 0 GPIO_OPEN_DRAIN>; + scl-gpios = <&gpio1 1 GPIO_OPEN_DRAIN>; pinctrl-0 = <&i2c1_default>; pinctrl-names = "default"; }; From 0b01671fe9cf2f8004593d4ce8f4cd23a7ab5e1e Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 19 Oct 2023 11:15:09 -0700 Subject: [PATCH 2450/4498] tests: pm: Test pm_state_cpu_get_all Add test for pm_state_cpu_get_all API Signed-off-by: Flavio Ceolin --- tests/subsys/pm/power_states_api/Kconfig | 11 +++++++++ tests/subsys/pm/power_states_api/prj.conf | 1 + tests/subsys/pm/power_states_api/src/main.c | 25 +++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/subsys/pm/power_states_api/Kconfig diff --git a/tests/subsys/pm/power_states_api/Kconfig b/tests/subsys/pm/power_states_api/Kconfig new file mode 100644 index 00000000000..71c7b510f4d --- /dev/null +++ b/tests/subsys/pm/power_states_api/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_PROVIDE_PM_HOOKS + bool "Provide PM hooks for test purposes" + default y + select HAS_PM diff --git a/tests/subsys/pm/power_states_api/prj.conf b/tests/subsys/pm/power_states_api/prj.conf index 9467c292689..e623494111a 100644 --- a/tests/subsys/pm/power_states_api/prj.conf +++ b/tests/subsys/pm/power_states_api/prj.conf @@ -1 +1,2 @@ +CONFIG_PM=y CONFIG_ZTEST=y diff --git a/tests/subsys/pm/power_states_api/src/main.c b/tests/subsys/pm/power_states_api/src/main.c index a7e76117815..3699bc0d3ff 100644 --- a/tests/subsys/pm/power_states_api/src/main.c +++ b/tests/subsys/pm/power_states_api/src/main.c @@ -18,8 +18,24 @@ static enum pm_state states[] = {PM_STATE_SUSPEND_TO_IDLE, static enum pm_state wrong_states[] = {PM_STATE_SUSPEND_TO_DISK, PM_STATE_SUSPEND_TO_RAM, PM_STATE_SUSPEND_TO_RAM}; +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + ARG_UNUSED(state); +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(state); + ARG_UNUSED(substate_id); + + irq_unlock(0); +} + ZTEST(power_states_1cpu, test_power_states) { + uint8_t ret; + const struct pm_state_info *cpu_states; enum pm_state dts_states[] = PM_STATE_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0)); struct pm_state_info dts_infos[] = @@ -36,6 +52,15 @@ ZTEST(power_states_1cpu, test_power_states) zassert_false(memcmp(wrong_states, dts_states, sizeof(dts_states)) == 0, "Invalid pm-states array"); + + ret = pm_state_cpu_get_all(CONFIG_MP_MAX_NUM_CPUS + 1, &cpu_states); + zassert_true(ret == 0, "Invalid pm_state_cpu_get_all return"); + + ret = pm_state_cpu_get_all(0U, &cpu_states); + zassert_true(ret == dts_states_len, + "Invalid number of pm states"); + zassert_true(memcmp(cpu_states, dts_infos, sizeof(dts_infos)) == 0, + "Invalid pm_state_info array"); } ZTEST_SUITE(power_states_1cpu, NULL, NULL, ztest_simple_1cpu_before, From 9a7a22a68b09729fd41de2bdb3129845f5e42119 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 19 Oct 2023 12:50:22 -0700 Subject: [PATCH 2451/4498] pm: Fix possible undefined reference Function pm_state_cpu_get_all is declared in state.h but it is only implemented if CONFIG_PM is set. Add an inline implementation for when CONFIG_PM is not set. Signed-off-by: Flavio Ceolin --- include/zephyr/pm/state.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/zephyr/pm/state.h b/include/zephyr/pm/state.h index 1d21ffd997a..cc387879411 100644 --- a/include/zephyr/pm/state.h +++ b/include/zephyr/pm/state.h @@ -329,6 +329,7 @@ struct pm_state_info { } +#if defined(CONFIG_PM) || defined(__DOXYGEN__) /** * Obtain information about all supported states by a CPU. * @@ -343,6 +344,18 @@ uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states); * @} */ +#else /* CONFIG_PM */ + +static inline uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states) +{ + ARG_UNUSED(cpu); + ARG_UNUSED(states); + + return 0; +} + +#endif /* CONFIG_PM */ + #ifdef __cplusplus } #endif From aa2879a3972bd6887ce101ac37b0d108d32f653c Mon Sep 17 00:00:00 2001 From: Aron Lander Date: Mon, 23 Oct 2023 14:22:42 +0200 Subject: [PATCH 2452/4498] modules: Updated the Percepio module to v4.8.1.hotfix1 This synchronizes the percepio module with the upstreams repository. Signed-off-by: Aron Lander --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 28882981459..239c2cf6d69 100644 --- a/west.yml +++ b/west.yml @@ -304,7 +304,7 @@ manifest: path: modules/lib/openthread - name: percepio path: modules/debug/percepio - revision: a3728efccc47dd372f40e6313589ca4c5cc7d5e9 + revision: 0fbc5b72aeab8a6434523a3a7bc8111c17f0bc73 groups: - debug - name: picolibc From f9178926a983acd507c183910721138456e3794b Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Mon, 24 Jul 2023 13:24:51 +0200 Subject: [PATCH 2453/4498] scripts: Add --no-detailed-test-id arg to test_plan.py script An option --no-detailed-test-id was added to twister to help align names for test outside of zephyr tree. This commit add this arg to test_plan.py script which is then propagated to twister. Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 19e5f893ca7..3655339eb7d 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -86,7 +86,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, pull_request=False, platforms=[]): + def __init__(self, modified_files, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -95,6 +95,7 @@ def __init__(self, modified_files, pull_request=False, platforms=[]): self.pull_request = pull_request self.platforms = platforms self.default_run = False + self.detailed_test_id = detailed_test_id def process(self): self.find_modules() @@ -112,6 +113,8 @@ def process(self): def get_plan(self, options, integration=False): fname = "_test_plan_partial.json" cmd = ["scripts/twister", "-c"] + options + ["--save-tests", fname ] + if not self.detailed_test_id: + cmd += ["--no-detailed-test-id"] if integration: cmd.append("--integration") @@ -353,6 +356,13 @@ def parse_args(): help="Number of tests per builder") parser.add_argument('-n', '--default-matrix', default=10, type=int, help="Number of tests per builder") + parser.add_argument('--detailed-test-id', action='store_true', + help="Include paths to tests' locations in tests' names.") + parser.add_argument("--no-detailed-test-id", dest='detailed_test_id', action="store_false", + help="Don't put paths into tests' names.") + + # Include paths in names by default. + parser.set_defaults(detailed_test_id=True) return parser.parse_args() @@ -375,8 +385,7 @@ def parse_args(): print("\n".join(files)) print("=========") - - f = Filters(files, args.pull_request, args.platform) + f = Filters(files, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From f7c4d5f9d44b7cec85427235cb508a77bdbd898a Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Mon, 31 Jul 2023 13:05:35 +0200 Subject: [PATCH 2454/4498] scripts: Allow test_plan.py to work with other than zephyr repos The test_plan.py script has a path to repository to be scanned for changes hard coded to zephyr. This patch separates zephyr path from such repository's path and adds an arg to pass repo to scan Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 3655339eb7d..1a60370031b 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -19,10 +19,17 @@ if "ZEPHYR_BASE" not in os.environ: exit("$ZEPHYR_BASE environment variable undefined.") -repository_path = Path(os.environ['ZEPHYR_BASE']) +# These are globaly used variables. They are assigned in __main__ and are visible in further methods +# however, pylint complains that it doesn't recognized them when used (used-before-assignment). +zephyr_base = Path(os.environ['ZEPHYR_BASE']) +repository_path = zephyr_base +repo_to_scan = zephyr_base +args = None + + logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) -sys.path.append(os.path.join(repository_path, 'scripts')) +sys.path.append(os.path.join(zephyr_base, 'scripts')) import list_boards def _get_match_fn(globs, regexes): @@ -112,7 +119,7 @@ def process(self): def get_plan(self, options, integration=False): fname = "_test_plan_partial.json" - cmd = ["scripts/twister", "-c"] + options + ["--save-tests", fname ] + cmd = [f"{zephyr_base}/scripts/twister", "-c"] + options + ["--save-tests", fname ] if not self.detailed_test_id: cmd += ["--no-detailed-test-id"] if integration: @@ -131,7 +138,7 @@ def find_modules(self): if 'west.yml' in self.modified_files: print(f"Manifest file 'west.yml' changed") print("=========") - old_manifest_content = repo.git.show(f"{args.commits[:-2]}:west.yml") + old_manifest_content = repo_to_scan.git.show(f"{args.commits[:-2]}:west.yml") with open("west_old.yml", "w") as manifest: manifest.write(old_manifest_content) old_manifest = Manifest.from_file("west_old.yml") @@ -212,8 +219,12 @@ def find_boards(self): if p and p.groups(): boards.add(p.group(1)) - # Limit search to $ZEPHYR_BASE since this is where the changed files are - lb_args = argparse.Namespace(**{ 'arch_roots': [repository_path], 'board_roots': [repository_path] }) + roots = [zephyr_base] + if repository_path != zephyr_base: + roots.append(repository_path) + + # Look for boards in monitored repositories + lb_args = argparse.Namespace(**{ 'arch_roots': roots, 'board_roots': roots}) known_boards = list_boards.find_boards(lb_args) for b in boards: name_re = re.compile(b) @@ -268,7 +279,7 @@ def find_tests(self): def find_tags(self): - tag_cfg_file = os.path.join(repository_path, 'scripts', 'ci', 'tags.yaml') + tag_cfg_file = os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml') with open(tag_cfg_file, 'r') as ymlfile: tags_config = yaml.safe_load(ymlfile) @@ -360,6 +371,8 @@ def parse_args(): help="Include paths to tests' locations in tests' names.") parser.add_argument("--no-detailed-test-id", dest='detailed_test_id', action="store_false", help="Don't put paths into tests' names.") + parser.add_argument('-r', '--repo-to-scan', default=None, + help="Repo to scan") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -372,9 +385,11 @@ def parse_args(): args = parse_args() files = [] errors = 0 + if args.repo_to_scan: + repository_path = Path(args.repo_to_scan) if args.commits: - repo = Repo(repository_path) - commit = repo.git.diff("--name-only", args.commits) + repo_to_scan = Repo(repository_path) + commit = repo_to_scan.git.diff("--name-only", args.commits) files = commit.split("\n") elif args.modified_files: with open(args.modified_files, "r") as fp: From 47405a114ad676abde2ac2e0d987aba916686576 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Tue, 25 Jul 2023 16:45:55 +0200 Subject: [PATCH 2455/4498] scripts: Allow using alternative ignore-patters in test_plan.py Expand test_plan.py args with --ignore-path. This allows to provide an alternative lists of patterns for the script. Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 1a60370031b..81f9dfbaa81 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,7 +93,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -103,6 +103,7 @@ def __init__(self, modified_files, pull_request=False, platforms=[], detailed_te self.platforms = platforms self.default_run = False self.detailed_test_id = detailed_test_id + self.ignore_path = ignore_path def process(self): self.find_modules() @@ -317,7 +318,7 @@ def find_tags(self): logging.info(f'Potential tag based filters: {exclude_tags}') def find_excludes(self, skip=[]): - with open("scripts/ci/twister_ignore.txt", "r") as twister_ignore: + with open(self.ignore_path, "r") as twister_ignore: ignores = twister_ignore.read().splitlines() ignores = filter(lambda x: not x.startswith("#"), ignores) @@ -373,6 +374,9 @@ def parse_args(): help="Don't put paths into tests' names.") parser.add_argument('-r', '--repo-to-scan', default=None, help="Repo to scan") + parser.add_argument('--ignore-path', + default=os.path.join(zephyr_base, 'scripts', 'ci', 'twister_ignore.txt'), + help="Path to a text file with patterns of files to be matched against changed files") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -400,7 +404,7 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.ignore_path, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From 76926100048082cc559c85114f89dde2faa3ec3e Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Wed, 2 Aug 2023 14:36:03 +0200 Subject: [PATCH 2456/4498] scripts: Add arg to set_plan.py for alternative tag relation list Add --alt-tag arg for test_plan.py script. User can use it and point to an alternative file with tag-directories relations. If so, such file will be used instead of the default one. Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 81f9dfbaa81..637254975a0 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,7 +93,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, ignore_path, alt_tags, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -104,6 +104,7 @@ def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[] self.default_run = False self.detailed_test_id = detailed_test_id self.ignore_path = ignore_path + self.tag_cfg_file = alt_tags def process(self): self.find_modules() @@ -280,8 +281,7 @@ def find_tests(self): def find_tags(self): - tag_cfg_file = os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml') - with open(tag_cfg_file, 'r') as ymlfile: + with open(self.tag_cfg_file, 'r') as ymlfile: tags_config = yaml.safe_load(ymlfile) tags = {} @@ -377,6 +377,9 @@ def parse_args(): parser.add_argument('--ignore-path', default=os.path.join(zephyr_base, 'scripts', 'ci', 'twister_ignore.txt'), help="Path to a text file with patterns of files to be matched against changed files") + parser.add_argument('--alt-tags', + default=os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml'), + help="Path to a file describing relations between directories and tags") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -404,7 +407,7 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.ignore_path, args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.ignore_path, args.alt_tags, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From 0752d604430b2c77b535a51ad30735fb9f61ccbc Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Wed, 2 Aug 2023 16:43:54 +0200 Subject: [PATCH 2457/4498] scripts: Add arg to test_plan.py for alternative test locations The arg --testsuite-root was copied from twister. When it is used for test_plan.py it will be propagated to twister calls. This allows to make alternative test locations (e.g. from another repo) to work with test_plan.py Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 637254975a0..0c4f05c0ca9 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,8 +93,10 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, ignore_path, alt_tags, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, + pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files + self.testsuite_root = testsuite_root self.twister_options = [] self.full_twister = False self.all_tests = [] @@ -119,11 +121,14 @@ def process(self): else: self.find_excludes() - def get_plan(self, options, integration=False): + def get_plan(self, options, integration=False, use_testsuite_root=True): fname = "_test_plan_partial.json" cmd = [f"{zephyr_base}/scripts/twister", "-c"] + options + ["--save-tests", fname ] if not self.detailed_test_id: cmd += ["--no-detailed-test-id"] + if self.testsuite_root and use_testsuite_root: + for root in self.testsuite_root: + cmd+=["-T", root] if integration: cmd.append("--integration") @@ -277,7 +282,7 @@ def find_tests(self): _options.extend(["-p", platform]) else: _options.append("--all") - self.get_plan(_options) + self.get_plan(_options, use_testsuite_root=False) def find_tags(self): @@ -380,6 +385,12 @@ def parse_args(): parser.add_argument('--alt-tags', default=os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml'), help="Path to a file describing relations between directories and tags") + parser.add_argument( + "-T", "--testsuite-root", action="append", default=[], + help="Base directory to recursively search for test cases. All " + "testcase.yaml files under here will be processed. May be " + "called multiple times. Defaults to the 'samples/' and " + "'tests/' directories at the base of the Zephyr tree.") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -407,7 +418,8 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.ignore_path, args.alt_tags, args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.ignore_path, args.alt_tags, args.testsuite_root, + args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From 7ec0be76aed9d84087f1b3970211f8bbfca94da2 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 13 Oct 2023 11:19:32 +0200 Subject: [PATCH 2458/4498] samples: Bluetooth: Add missing reset of sems in iso_receive In the iso_receive sample, the semaphores were not reset in each iteration. This caused the ISO receiver to act incorrectly and cause issues with some controllers. Signed-off-by: Emil Gydesen --- samples/bluetooth/iso_receive/src/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/bluetooth/iso_receive/src/main.c b/samples/bluetooth/iso_receive/src/main.c index 90fdf767dc5..a746a2f2fd0 100644 --- a/samples/bluetooth/iso_receive/src/main.c +++ b/samples/bluetooth/iso_receive/src/main.c @@ -281,6 +281,16 @@ static struct bt_iso_big_sync_param big_sync_param = { .sync_timeout = 100, /* in 10 ms units */ }; +static void reset_semaphores(void) +{ + k_sem_reset(&sem_per_adv); + k_sem_reset(&sem_per_sync); + k_sem_reset(&sem_per_sync_lost); + k_sem_reset(&sem_per_big_info); + k_sem_reset(&sem_big_sync); + k_sem_reset(&sem_big_sync_lost); +} + int main(void) { struct bt_le_per_adv_sync_param sync_create_param; @@ -328,6 +338,7 @@ int main(void) printk("Success.\n"); do { + reset_semaphores(); per_adv_lost = false; printk("Start scanning..."); From 564adad952fcd7171fbeb8d5292094e87c4b09f8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 19 Oct 2023 16:06:28 -0700 Subject: [PATCH 2459/4498] treewide: Add CODE_UNREACHABLE after k_thread_abort(current) Compiler can't tell that k_thread_abort() won't return and issues a warning unless we tell it that control never gets this far. Signed-off-by: Flavio Ceolin --- lib/posix/pthread.c | 2 ++ samples/modules/tflite-micro/tflm_ethosu/src/main.cpp | 2 ++ subsys/shell/shell.c | 2 ++ subsys/testsuite/ztest/src/ztest.c | 2 ++ subsys/testsuite/ztest/src/ztest_error_hook.c | 2 ++ subsys/testsuite/ztest/src/ztest_new.c | 2 ++ tests/kernel/sched/deadline/src/main.c | 2 ++ .../kernel/threads/thread_apis/src/test_threads_cancel_abort.c | 1 + 8 files changed, 15 insertions(+) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 7377f2b133d..f2bbc07ae9a 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -628,6 +628,8 @@ void pthread_exit(void *retval) /* not a valid posix_thread */ LOG_DBG("Aborting non-pthread %p", k_current_get()); k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } /* Make a thread as cancelable before exiting */ diff --git a/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp b/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp index 19a4afad9c2..5671b0a0718 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp +++ b/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp @@ -149,6 +149,8 @@ void inferenceProcessTask(void *_name, void *heap, void *_params) } k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } /* inferenceSenderTask - Creates NUM_INFERENCE_JOBS jobs, queues them, and then diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 34ed7daa755..1a803d73339 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1307,6 +1307,8 @@ static void kill_handler(const struct shell *sh) sh->ctx->tid = NULL; k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } void shell_thread(void *shell_handle, void *arg_log_backend, diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index b100921ab21..4215ec77c89 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -440,6 +440,8 @@ static void test_finalize(void) if (IS_ENABLED(CONFIG_MULTITHREADING)) { k_thread_abort(&ztest_thread); k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } } diff --git a/subsys/testsuite/ztest/src/ztest_error_hook.c b/subsys/testsuite/ztest/src/ztest_error_hook.c index e0a92077b0e..64dede71533 100644 --- a/subsys/testsuite/ztest/src/ztest_error_hook.c +++ b/subsys/testsuite/ztest/src/ztest_error_hook.c @@ -106,6 +106,8 @@ static inline void z_vrfy_ztest_set_assert_valid(bool valid) __weak void ztest_post_assert_fail_hook(void) { k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } #ifdef CONFIG_ASSERT_NO_FILE_INFO diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index b100921ab21..4215ec77c89 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -440,6 +440,8 @@ static void test_finalize(void) if (IS_ENABLED(CONFIG_MULTITHREADING)) { k_thread_abort(&ztest_thread); k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } } diff --git a/tests/kernel/sched/deadline/src/main.c b/tests/kernel/sched/deadline/src/main.c index a3fd777a779..7e1cf7a63c8 100644 --- a/tests/kernel/sched/deadline/src/main.c +++ b/tests/kernel/sched/deadline/src/main.c @@ -125,6 +125,8 @@ void yield_worker(void *p1, void *p2, void *p3) zassert_true(n_exec == NUM_THREADS, ""); k_thread_abort(k_current_get()); + + CODE_UNREACHABLE; } ZTEST(suite_deadline, test_yield) diff --git a/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c b/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c index 481aeac676d..cfe4fab24b7 100644 --- a/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c +++ b/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c @@ -25,6 +25,7 @@ static void thread_entry_abort(void *p1, void *p2, void *p3) /**TESTPOINT: abort current thread*/ execute_flag = 1; k_thread_abort(k_current_get()); + CODE_UNREACHABLE; /*unreachable*/ execute_flag = 2; zassert_true(1 == 0); From c166685fcfeb9a11157c8d5aba8b2806df2aaf7c Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 19 Oct 2023 22:27:15 -0700 Subject: [PATCH 2460/4498] ztest: Do not abort k_current_get from ISR Do not abort k_current_get() from ISR. Signed-off-by: Flavio Ceolin --- subsys/testsuite/ztest/src/ztest.c | 5 ++++- subsys/testsuite/ztest/src/ztest_new.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 4215ec77c89..12271e61eb9 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -439,8 +439,11 @@ static void test_finalize(void) { if (IS_ENABLED(CONFIG_MULTITHREADING)) { k_thread_abort(&ztest_thread); - k_thread_abort(k_current_get()); + if (k_is_in_isr()) { + return; + } + k_thread_abort(k_current_get()); CODE_UNREACHABLE; } } diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index 4215ec77c89..12271e61eb9 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -439,8 +439,11 @@ static void test_finalize(void) { if (IS_ENABLED(CONFIG_MULTITHREADING)) { k_thread_abort(&ztest_thread); - k_thread_abort(k_current_get()); + if (k_is_in_isr()) { + return; + } + k_thread_abort(k_current_get()); CODE_UNREACHABLE; } } From 73896eef6c3dfa8c6c57438e924d3271999a5d6e Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 20 Oct 2023 13:44:56 +0300 Subject: [PATCH 2461/4498] net: Set Dummy net_if as default one for tests If we run network tests under tests/net, then set the Dummy network interface as a default one so that it will be picked up first. This should solve the issue if the DUT is having a real network interfaces like onboard Ethernet interface which could cause the test to fail. The test might fail in this case because the network tests assume that only simulated network interfaces are used by the tests. Signed-off-by: Jukka Rissanen --- subsys/net/ip/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 2683f52117c..1831816ab25 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -858,8 +858,12 @@ config NET_HEADERS_ALWAYS_CONTIGUOUS NET_BUF_FIXED_DATA_SIZE enabled and NET_BUF_DATA_SIZE of 128 for instance. +# If we are running network tests found in tests/net, then the NET_TEST is +# set and in that case we default to Dummy L2 layer as typically the tests +# use that by default. choice prompt "Default Network Interface" + default NET_DEFAULT_IF_DUMMY if NET_TEST default NET_DEFAULT_IF_FIRST help If system has multiple interfaces enabled, then user shall be able From 1005fbe16cb4f7a0e8bd9b89c86b078f46fbbf0f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 23 Oct 2023 16:00:11 +0300 Subject: [PATCH 2462/4498] tests: net: iface: Do not use eth0 name in the test If the first Ethernet interface is not the first network interface, then there might be two interfaces with the same name. The test does not like that. Signed-off-by: Jukka Rissanen --- tests/net/iface/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/net/iface/src/main.c b/tests/net/iface/src/main.c index 80042ff84bd..89abd22d5d7 100644 --- a/tests/net/iface/src/main.c +++ b/tests/net/iface/src/main.c @@ -1157,7 +1157,7 @@ ZTEST(net_iface, test_interface_name) ret = net_if_set_name(iface, name); zassert_equal(ret, -ENAMETOOLONG, "Unexpected value (%d) returned", ret); - name = "eth0"; + name = "abc0"; ret = net_if_set_name(iface, name); zassert_equal(ret, 0, "Unexpected value (%d) returned", ret); From d72159d28841642fbff7fa0941ffa84186a9e1da Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Mon, 23 Oct 2023 08:13:56 +0200 Subject: [PATCH 2463/4498] samples: modules: lvgl: demo: Add widgets entry to README Adds a short description and build command for the widgets demo to the README. Signed-off-by: Fabian Blatz --- samples/modules/lvgl/demos/README.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst index c27c71fa04d..1e12b8d77f8 100644 --- a/samples/modules/lvgl/demos/README.rst +++ b/samples/modules/lvgl/demos/README.rst @@ -15,6 +15,8 @@ A sample showcasing upstream LVGL demos. The benchmark demo tests the performance in various cases. For example rectangle, border, shadow, text, image blending, image transformation, blending modes, etc. * Stress A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks. +* Widgets + Shows how the widgets look like out of the box using the built-in material theme. Requirements ************ @@ -49,3 +51,11 @@ These demos can be built as follows: :gen-args: -DCONFIG_LV_Z_DEMO_STRESS=y :goals: run :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_posix + :gen-args: -DCONFIG_LV_Z_DEMO_WIDGETS=y + :goals: run + :compact: From dcf7b1905b9e2e3c4b277f6984d3fc166436d233 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 19 Oct 2023 10:59:03 +0200 Subject: [PATCH 2464/4498] net: core: Set LL address on loopback packet In case packet is looped back to the stack, set LL address information on the packet, using the LL address set on the corresponding network interface, so that the information can be interpreted by the SOCK_DGRAM packet socket. Signed-off-by: Robert Lubos --- subsys/net/ip/net_core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index c3b8f5f8c1c..3d37743a39d 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -211,6 +211,15 @@ static void init_rx_queues(void) /* Check if the IPv{4|6} addresses are proper. As this can be expensive, * make this optional. */ + +static inline void copy_ll_addr(struct net_pkt *pkt) +{ + memcpy(net_pkt_lladdr_src(pkt), net_pkt_lladdr_if(pkt), + sizeof(struct net_linkaddr)); + memcpy(net_pkt_lladdr_dst(pkt), net_pkt_lladdr_if(pkt), + sizeof(struct net_linkaddr)); +} + static inline int check_ip_addr(struct net_pkt *pkt) { uint8_t family = net_pkt_family(pkt); @@ -239,6 +248,9 @@ static inline int check_ip_addr(struct net_pkt *pkt) NET_IPV6_HDR(pkt)->dst); net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr); + net_pkt_set_ll_proto_type(pkt, ETH_P_IPV6); + copy_ll_addr(pkt); + return 1; } @@ -286,6 +298,9 @@ static inline int check_ip_addr(struct net_pkt *pkt) NET_IPV4_HDR(pkt)->dst); net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr); + net_pkt_set_ll_proto_type(pkt, ETH_P_IP); + copy_ll_addr(pkt); + return 1; } From c6fd2b2d4492241a8e84421092f15d59db147d9e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 19 Oct 2023 11:38:58 +0200 Subject: [PATCH 2465/4498] net: shell: Fix unexpected timeout on loopback ping In case ping is sent to own address, the request is looped back to the stack and served before ping work had a chance to reschedule. In result, when the final ping reply has been server, and ping operation finalized with `ping_done()`, the work was rescheduled one last time, causing the ping timeout to be reported. Fix this by rescheduling the work before sending the actual request, so that the reply handler can cancel the work properly in such case. Signed-off-by: Robert Lubos --- subsys/net/lib/shell/ping.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/shell/ping.c b/subsys/net/lib/shell/ping.c index 5556140cff5..8b52df110be 100644 --- a/subsys/net/lib/shell/ping.c +++ b/subsys/net/lib/shell/ping.c @@ -259,6 +259,12 @@ static void ping_work(struct k_work *work) return; } + if (ctx->sequence < ctx->count) { + k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); + } else { + k_work_reschedule(&ctx->work, K_SECONDS(2)); + } + params.identifier = sys_rand32_get(); params.sequence = ctx->sequence; params.tc_tos = ctx->tos; @@ -276,12 +282,6 @@ static void ping_work(struct k_work *work) ping_done(ctx); return; } - - if (ctx->sequence < ctx->count) { - k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); - } else { - k_work_reschedule(&ctx->work, K_SECONDS(2)); - } } #define ASCII_CTRL_C 0x03 From befc96f22e9b1c1632a5c6f5d4e9ecb9c0f792ed Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 11:34:55 +0200 Subject: [PATCH 2466/4498] userspace tests/samples: Exclude in posix arch These samples & tests cannot be run in this architecture as it does not support userspace. Today they are filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- samples/userspace/hello_world_user/sample.yaml | 2 ++ samples/userspace/prod_consumer/sample.yaml | 2 ++ samples/userspace/shared_mem/sample.yaml | 2 ++ tests/benchmarks/sched_userspace/testcase.yaml | 2 ++ 4 files changed, 8 insertions(+) diff --git a/samples/userspace/hello_world_user/sample.yaml b/samples/userspace/hello_world_user/sample.yaml index 1a0a407e893..f782f36cad4 100644 --- a/samples/userspace/hello_world_user/sample.yaml +++ b/samples/userspace/hello_world_user/sample.yaml @@ -14,4 +14,6 @@ common: tests: sample.helloworld: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: introduction diff --git a/samples/userspace/prod_consumer/sample.yaml b/samples/userspace/prod_consumer/sample.yaml index 791f103b6ef..cc4aaa5d118 100644 --- a/samples/userspace/prod_consumer/sample.yaml +++ b/samples/userspace/prod_consumer/sample.yaml @@ -13,3 +13,5 @@ common: tests: sample.userspace.prod_consumer: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix diff --git a/samples/userspace/shared_mem/sample.yaml b/samples/userspace/shared_mem/sample.yaml index 3e45ba1bbd6..954b6a9d3d6 100644 --- a/samples/userspace/shared_mem/sample.yaml +++ b/samples/userspace/shared_mem/sample.yaml @@ -14,6 +14,8 @@ common: tests: sample.kernel.memory_protection.shared_mem: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix platform_exclude: - twr_ke18f - cy8cproto_062_4343w diff --git a/tests/benchmarks/sched_userspace/testcase.yaml b/tests/benchmarks/sched_userspace/testcase.yaml index e4da7bc1bcf..60b6f2f3808 100644 --- a/tests/benchmarks/sched_userspace/testcase.yaml +++ b/tests/benchmarks/sched_userspace/testcase.yaml @@ -7,6 +7,8 @@ tests: - userspace slow: true filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix harness: console harness_config: type: multi_line From 886d6a9f1fddda2b9521cf50747da9fcb005a06d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 11:36:52 +0200 Subject: [PATCH 2467/4498] samples subsys logger: Exclude some subtests from posix arch Two substests (userspace and rtt) cannot be run in the posix architecture. Today they are filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/logging/logger/sample.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/subsys/logging/logger/sample.yaml b/samples/subsys/logging/logger/sample.yaml index 5dca694782a..131c9ea9fb5 100644 --- a/samples/subsys/logging/logger/sample.yaml +++ b/samples/subsys/logging/logger/sample.yaml @@ -22,6 +22,8 @@ tests: - frdm_k64f tags: logging filter: CONFIG_HAS_SEGGER_RTT + arch_exclude: + - posix harness: keyboard extra_configs: - CONFIG_LOG_BACKEND_RTT=y @@ -30,6 +32,8 @@ tests: sample.logger.usermode: integration_platforms: - mps2_an385 + arch_exclude: + - posix tags: - logging - usermode From df15fcb9fb62107d3d595695a9e60b2bbadea685 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 11:43:08 +0200 Subject: [PATCH 2468/4498] tests/benchmarks/cmsis_dsp/basicmath: Filter by arch Add a filter by (arm) architecture, as the filter as it is faster than filtering by kconfig. Signed-off-by: Alberto Escolar Piedras --- .../cmsis_dsp/basicmath/testcase.yaml | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml b/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml index df3ab65a9c7..674cba76dde 100644 --- a/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml +++ b/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml @@ -1,27 +1,24 @@ +common: + arch_allow: arm + filter: (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB + == 1 + tags: + - benchmark + - cmsis_dsp + min_flash: 128 + min_ram: 64 tests: benchmark.cmsis_dsp.basicmath: - filter: (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1 integration_platforms: - frdm_k64f - sam_e70_xplained - mps2_an521 - tags: - - benchmark - - cmsis_dsp - min_flash: 128 - min_ram: 64 benchmark.cmsis_dsp.basicmath.fpu: - filter: (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_CPU_HAS_FPU integration_platforms: - mps2_an521_remote - mps3_an547 tags: - - benchmark - - cmsis_dsp - fpu extra_configs: - CONFIG_FPU=y - min_flash: 128 - min_ram: 64 From 4060f1d390b0142739b51f52c07b818e8e5e57e3 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 11:58:09 +0200 Subject: [PATCH 2469/4498] tests newlib: Exclude in posix architecture These tests cannot be run in this architecture as it does not support this toolchain. Today they are filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/lib/newlib/heap_listener/testcase.yaml | 1 + tests/lib/newlib/thread_safety/testcase.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/lib/newlib/heap_listener/testcase.yaml b/tests/lib/newlib/heap_listener/testcase.yaml index f0aebfe29c8..a4620e464cc 100644 --- a/tests/lib/newlib/heap_listener/testcase.yaml +++ b/tests/lib/newlib/heap_listener/testcase.yaml @@ -4,6 +4,7 @@ tests: - clib - newlib filter: TOOLCHAIN_HAS_NEWLIB == 1 + arch_exclude: posix integration_platforms: - mps2_an385 - qemu_x86 diff --git a/tests/lib/newlib/thread_safety/testcase.yaml b/tests/lib/newlib/thread_safety/testcase.yaml index a798336ec49..91b5d650083 100644 --- a/tests/lib/newlib/thread_safety/testcase.yaml +++ b/tests/lib/newlib/thread_safety/testcase.yaml @@ -1,5 +1,6 @@ common: filter: TOOLCHAIN_HAS_NEWLIB == 1 + arch_exclude: posix tags: - clib - newlib From fb38b904812a79c9ddb6024ae387080f9a57a8e8 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 12:01:58 +0200 Subject: [PATCH 2470/4498] tests kernel: Exclude posix arch for userspace tests These tests cannot be run in this architecture as it does not support userspace. Today they are filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/kernel/events/sys_event/testcase.yaml | 2 ++ tests/kernel/fatal/exception/testcase.yaml | 3 +++ tests/kernel/mem_protect/futex/testcase.yaml | 2 ++ tests/kernel/mem_protect/mem_protect/testcase.yaml | 2 ++ tests/kernel/mem_protect/obj_validation/testcase.yaml | 2 ++ tests/kernel/mem_protect/stack_random/testcase.yaml | 3 ++- tests/kernel/mem_protect/sys_sem/testcase.yaml | 2 ++ tests/kernel/mem_protect/syscalls/testcase.yaml | 2 ++ tests/kernel/mem_protect/userspace/testcase.yaml | 2 ++ tests/kernel/mutex/mutex_error_case/testcase.yaml | 2 ++ tests/kernel/mutex/sys_mutex/testcase.yaml | 3 ++- tests/kernel/semaphore/sys_sem/testcase.yaml | 2 ++ tests/kernel/threads/dynamic_thread/testcase.yaml | 2 ++ tests/kernel/threads/tls/testcase.yaml | 2 ++ tests/kernel/workq/user_work/testcase.yaml | 2 ++ 15 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tests/kernel/events/sys_event/testcase.yaml b/tests/kernel/events/sys_event/testcase.yaml index ebbc06427b6..32e6f91a519 100644 --- a/tests/kernel/events/sys_event/testcase.yaml +++ b/tests/kernel/events/sys_event/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.events.usage: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace diff --git a/tests/kernel/fatal/exception/testcase.yaml b/tests/kernel/fatal/exception/testcase.yaml index c325a84166b..0d5b9e46100 100644 --- a/tests/kernel/fatal/exception/testcase.yaml +++ b/tests/kernel/fatal/exception/testcase.yaml @@ -5,6 +5,8 @@ tests: extra_args: CONF_FILE=prj.conf platform_exclude: twr_ke18f filter: CONFIG_ARCH_HAS_STACK_PROTECTION + arch_exclude: + - posix tags: - kernel - userspace @@ -18,6 +20,7 @@ tests: kernel.common.stack_protection_arm_fpu_sharing: extra_args: CONF_FILE=prj_arm_fpu_sharing.conf platform_exclude: twr_ke18f + arch_allow: arm filter: CONFIG_ARCH_HAS_STACK_PROTECTION and CONFIG_ARMV7_M_ARMV8_M_FP tags: - fpu diff --git a/tests/kernel/mem_protect/futex/testcase.yaml b/tests/kernel/mem_protect/futex/testcase.yaml index 8961283d526..6efaf0e66aa 100644 --- a/tests/kernel/mem_protect/futex/testcase.yaml +++ b/tests/kernel/mem_protect/futex/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.futex: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace diff --git a/tests/kernel/mem_protect/mem_protect/testcase.yaml b/tests/kernel/mem_protect/mem_protect/testcase.yaml index 5d46e54fcd0..20a9e8f7ac8 100644 --- a/tests/kernel/mem_protect/mem_protect/testcase.yaml +++ b/tests/kernel/mem_protect/mem_protect/testcase.yaml @@ -7,6 +7,8 @@ common: tests: kernel.memory_protection: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix platform_exclude: twr_ke18f extra_args: - CONFIG_TEST_HW_STACK_PROTECTION=n diff --git a/tests/kernel/mem_protect/obj_validation/testcase.yaml b/tests/kernel/mem_protect/obj_validation/testcase.yaml index fd4b04a4222..7b6c3e8a457 100644 --- a/tests/kernel/mem_protect/obj_validation/testcase.yaml +++ b/tests/kernel/mem_protect/obj_validation/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.memory_protection.obj_validation: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - security diff --git a/tests/kernel/mem_protect/stack_random/testcase.yaml b/tests/kernel/mem_protect/stack_random/testcase.yaml index 73ed615bac6..b809f2875b9 100644 --- a/tests/kernel/mem_protect/stack_random/testcase.yaml +++ b/tests/kernel/mem_protect/stack_random/testcase.yaml @@ -1,6 +1,7 @@ tests: kernel.memory_protection.stack_random: - arch_exclude: posix + arch_exclude: + - posix tags: - kernel - memory_protection diff --git a/tests/kernel/mem_protect/sys_sem/testcase.yaml b/tests/kernel/mem_protect/sys_sem/testcase.yaml index f20f04894de..58d505de475 100644 --- a/tests/kernel/mem_protect/sys_sem/testcase.yaml +++ b/tests/kernel/mem_protect/sys_sem/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.memory_protection.sys_sem: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace diff --git a/tests/kernel/mem_protect/syscalls/testcase.yaml b/tests/kernel/mem_protect/syscalls/testcase.yaml index 41d222b0893..0f2587f3859 100644 --- a/tests/kernel/mem_protect/syscalls/testcase.yaml +++ b/tests/kernel/mem_protect/syscalls/testcase.yaml @@ -2,6 +2,8 @@ tests: kernel.memory_protection.syscalls: platform_exclude: qemu_arc_em filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - security diff --git a/tests/kernel/mem_protect/userspace/testcase.yaml b/tests/kernel/mem_protect/userspace/testcase.yaml index 8be32fbae47..b098883c05f 100644 --- a/tests/kernel/mem_protect/userspace/testcase.yaml +++ b/tests/kernel/mem_protect/userspace/testcase.yaml @@ -4,6 +4,8 @@ common: - kernel - security - userspace + arch_exclude: + - posix tests: kernel.memory_protection.userspace: filter: CONFIG_ARCH_HAS_USERSPACE diff --git a/tests/kernel/mutex/mutex_error_case/testcase.yaml b/tests/kernel/mutex/mutex_error_case/testcase.yaml index ac89d216fbe..16d8252b6e9 100644 --- a/tests/kernel/mutex/mutex_error_case/testcase.yaml +++ b/tests/kernel/mutex/mutex_error_case/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.mutex.error: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace diff --git a/tests/kernel/mutex/sys_mutex/testcase.yaml b/tests/kernel/mutex/sys_mutex/testcase.yaml index c3669a6cfef..031c56cc2a4 100644 --- a/tests/kernel/mutex/sys_mutex/testcase.yaml +++ b/tests/kernel/mutex/sys_mutex/testcase.yaml @@ -1,11 +1,12 @@ tests: kernel.mutex.system: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace - mutex - kernel.mutex.system.nouser: tags: - kernel diff --git a/tests/kernel/semaphore/sys_sem/testcase.yaml b/tests/kernel/semaphore/sys_sem/testcase.yaml index c434ad3c798..35441e11bca 100644 --- a/tests/kernel/semaphore/sys_sem/testcase.yaml +++ b/tests/kernel/semaphore/sys_sem/testcase.yaml @@ -1,6 +1,8 @@ tests: kernel.semaphore.usage: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace diff --git a/tests/kernel/threads/dynamic_thread/testcase.yaml b/tests/kernel/threads/dynamic_thread/testcase.yaml index c97f6bce8a5..d4c6c4a09d4 100644 --- a/tests/kernel/threads/dynamic_thread/testcase.yaml +++ b/tests/kernel/threads/dynamic_thread/testcase.yaml @@ -6,5 +6,7 @@ tests: - userspace ignore_faults: true filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix integration_platforms: - qemu_x86 diff --git a/tests/kernel/threads/tls/testcase.yaml b/tests/kernel/threads/tls/testcase.yaml index 1eb12ec1036..4206ecdeff2 100644 --- a/tests/kernel/threads/tls/testcase.yaml +++ b/tests/kernel/threads/tls/testcase.yaml @@ -14,6 +14,8 @@ tests: - userspace filter: CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE and CONFIG_ARCH_HAS_USERSPACE and CONFIG_TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + arch_exclude: + - posix # ARCMWDT can't handle THREAD_LOCAL_STORAGE with USERSPACE, see #52570 for details toolchain_exclude: arcmwdt extra_configs: diff --git a/tests/kernel/workq/user_work/testcase.yaml b/tests/kernel/workq/user_work/testcase.yaml index e57d1221461..65356aaa316 100644 --- a/tests/kernel/workq/user_work/testcase.yaml +++ b/tests/kernel/workq/user_work/testcase.yaml @@ -2,6 +2,8 @@ tests: kernel.workqueue.user: min_flash: 34 filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - kernel - userspace From 5f57275a656a1b656b7d18f3b1fd20817ad7d45f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 12:03:39 +0200 Subject: [PATCH 2471/4498] tests drivers coredump: Exclude posix arch for userspace tests This test cannot be run in this architecture as it does not support userspace. Today it is filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/coredump/coredump_api/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/coredump/coredump_api/testcase.yaml b/tests/drivers/coredump/coredump_api/testcase.yaml index 3f18bedd22e..bece8efb2b2 100644 --- a/tests/drivers/coredump/coredump_api/testcase.yaml +++ b/tests/drivers/coredump/coredump_api/testcase.yaml @@ -33,6 +33,8 @@ tests: debug.coredump.drivers.api: filter: CONFIG_ARCH_SUPPORTS_COREDUMP platform_exclude: qemu_riscv32 + arch_exclude: + - posix harness: console integration_platforms: - qemu_x86 From 4c98a091fba6e4dba95157f6457ad48aaa4e114f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 12:41:13 +0200 Subject: [PATCH 2472/4498] tests subsys coredump: Exclude in posix architecture These tests cannot be run in this architecture as it does not support coredump. Today it is filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/subsys/debug/coredump/testcase.yaml | 2 ++ tests/subsys/debug/coredump_backends/testcase.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/subsys/debug/coredump/testcase.yaml b/tests/subsys/debug/coredump/testcase.yaml index 55e181216e0..db407b3d774 100644 --- a/tests/subsys/debug/coredump/testcase.yaml +++ b/tests/subsys/debug/coredump/testcase.yaml @@ -5,6 +5,8 @@ tests: ignore_qemu_crash: true filter: CONFIG_ARCH_SUPPORTS_COREDUMP platform_exclude: acrn_ehl_crb + arch_exclude: + - posix integration_platforms: - qemu_x86 harness: console diff --git a/tests/subsys/debug/coredump_backends/testcase.yaml b/tests/subsys/debug/coredump_backends/testcase.yaml index d7c8fccdaa9..6055c52906e 100644 --- a/tests/subsys/debug/coredump_backends/testcase.yaml +++ b/tests/subsys/debug/coredump_backends/testcase.yaml @@ -2,6 +2,8 @@ common: tags: coredump ignore_faults: true ignore_qemu_crash: true + arch_exclude: + - posix integration_platforms: - qemu_x86 tests: From 4e55c482ba9c3f40c10a75f41ebed4dc15612a55 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 13:14:08 +0200 Subject: [PATCH 2473/4498] tests/subsys/rtio: Exclude some subtests from posix arch Two substests cannot be run in the posix architecture as they require userspace. Today they are filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/subsys/rtio/rtio_api/testcase.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/subsys/rtio/rtio_api/testcase.yaml b/tests/subsys/rtio/rtio_api/testcase.yaml index 7f9f7b9028f..2eb29026efa 100644 --- a/tests/subsys/rtio/rtio_api/testcase.yaml +++ b/tests/subsys/rtio/rtio_api/testcase.yaml @@ -20,6 +20,8 @@ tests: filter: CONFIG_ARCH_HAS_USERSPACE extra_configs: - CONFIG_USERSPACE=y + arch_exclude: + - posix tags: - rtio - userspace @@ -30,6 +32,8 @@ tests: extra_configs: - CONFIG_USERSPACE=y - CONFIG_RTIO_SUBMIT_SEM=y + arch_exclude: + - posix tags: - rtio - userspace From af984c57e574cc6233b47ebfc3ff31a5fbe7ccb7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 13:16:41 +0200 Subject: [PATCH 2474/4498] tests/ztest/error_hook: Exclude posix arch for userspace test This test cannot be run in this architecture as it does not support userspace. Today it is filtered by kconfig, which works but spends time running cmake. As native_posix is a default test platform it is better to filter it alltogether by arch, which saves quite a lot of time. Signed-off-by: Alberto Escolar Piedras --- tests/ztest/error_hook/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ztest/error_hook/testcase.yaml b/tests/ztest/error_hook/testcase.yaml index 13619ba99ca..db0f60f1714 100644 --- a/tests/ztest/error_hook/testcase.yaml +++ b/tests/ztest/error_hook/testcase.yaml @@ -4,6 +4,8 @@ common: tests: testing.ztest.error_hook: filter: CONFIG_ARCH_HAS_USERSPACE + arch_exclude: + - posix tags: - userspace ignore_faults: true From ae26f1ef9d27d0706d51a463b4bf4c847fc90e91 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 23 Oct 2023 13:57:51 +0200 Subject: [PATCH 2475/4498] samples: modules: nanopb: Update requirements Add installation instruction for adding nanopb to the west workspace. This is required because it is optional and not installed by default. Signed-off-by: Pieter De Gendt --- samples/modules/nanopb/README.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/samples/modules/nanopb/README.rst b/samples/modules/nanopb/README.rst index 071498668a4..6e6d567f29c 100644 --- a/samples/modules/nanopb/README.rst +++ b/samples/modules/nanopb/README.rst @@ -22,7 +22,7 @@ make sure the ``protoc`` executable is installed and available. Use ``apt`` to install dependency: - .. code-block:: bash + .. code-block:: shell sudo apt install protobuf-compiler @@ -30,7 +30,7 @@ make sure the ``protoc`` executable is installed and available. Use ``brew`` to install dependency: - .. code-block:: bash + .. code-block:: shell brew install protobuf @@ -38,10 +38,19 @@ make sure the ``protoc`` executable is installed and available. Use ``choco`` to install dependency: - .. code-block:: console + .. code-block:: shell choco install protoc + +Additionally Nanopb is an optional module and needs to be added explicitly to the workspace: + +.. code-block:: shell + + west config manifest.project-filter -- +nanopb + west update + + Building and Running ******************** From 3de98643ed24072e5ec2156922495bc4c26680cc Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Mon, 23 Oct 2023 14:07:48 +0200 Subject: [PATCH 2476/4498] Bluetooth: Mesh: FU Server should not update internal state on error According to conditions in the DFU spec section 6.1.3.7 (Sending a Firmware Update Status message) and in 'Idempotency' part of section 6.1.3.4 (Receiving a Firmware Update Start message), the FU Server should not update internal state when 'Wrong Phase' error condition is triggered. Signed-off-by: Omkar Kulkarni --- subsys/bluetooth/mesh/dfu_srv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/dfu_srv.c b/subsys/bluetooth/mesh/dfu_srv.c index 282a40074c9..462a777b46c 100644 --- a/subsys/bluetooth/mesh/dfu_srv.c +++ b/subsys/bluetooth/mesh/dfu_srv.c @@ -302,10 +302,10 @@ static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, status = BT_MESH_DFU_ERR_WRONG_PHASE; } else { status = BT_MESH_DFU_SUCCESS; + srv->update.ttl = ttl; + srv->blob.state.xfer.id = blob_id; } - srv->update.ttl = ttl; - srv->blob.state.xfer.id = blob_id; LOG_WRN("Busy. Phase: %u", srv->update.phase); goto rsp; } From 7a216d2a69e9fb8c8d08cd941e09b6db321e6ca5 Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Mon, 23 Oct 2023 16:26:16 +0100 Subject: [PATCH 2477/4498] arch: arm: cortex_m: Revert "enable armv8m.baseline to use BASEPRI" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 0781a868625cb390d34f7ee51206185b15cc3bbf. BASEPRI is only functionnal if mainline extension is present. If not, it is "RES0". See: Arm®v8-M Architecture Reference Manual D1.2.5. Signed-off-by: Wilfried Chauveau --- include/zephyr/arch/arm/asm_inline_gcc.h | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/include/zephyr/arch/arm/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h index 63a118e97e6..61f8a9f088d 100644 --- a/include/zephyr/arch/arm/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -43,8 +43,8 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) { unsigned int key; -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE) -#if CONFIG_MP_MAX_NUM_CPUS == 1 +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#if CONFIG_MP_MAX_NUM_CPUS == 1 || defined(CONFIG_ARMV8_M_BASELINE) __asm__ volatile("mrs %0, PRIMASK;" "cpsid i" : "=r" (key) @@ -53,7 +53,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) #else #error "Cortex-M0 and Cortex-M0+ require SoC specific support for cross core synchronisation." #endif -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) unsigned int tmp; __asm__ volatile( @@ -61,15 +61,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) "mrs %0, BASEPRI;" "msr BASEPRI_MAX, %1;" "isb;" - : "=r"(key), -#if defined(CONFIG_ARMV8_M_BASELINE) - /* armv8-m.baseline's mov is limited to registers r0-r7. - * Let the compiler know we have this constraint on tmp. - */ - "=l"(tmp) -#else - "=r"(tmp) -#endif + : "=r"(key), "=r"(tmp) : "i"(_EXC_IRQ_DEFAULT_PRIO) : "memory"); #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ @@ -95,7 +87,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) { -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) if (key != 0U) { return; } @@ -103,7 +95,7 @@ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) "cpsie i;" "isb" : : : "memory"); -#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __asm__ volatile( "msr BASEPRI, %0;" "isb;" From 33a44d0ed8acf805782df8c9a4b47b752ea68e8f Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 3 Oct 2023 16:59:14 +0200 Subject: [PATCH 2478/4498] tfm: nordic_nrf: Add generic SoC support for nordic SoCs Add generic SoC support for the supported nordic SoCs: - nrf5340 - nrf9160 - nrf9120 Add generic SoC support by taking board specific configurations from zephyr devicetree and kconfig. Signed-off-by: Joakim Andersson --- modules/trusted-firmware-m/Kconfig.tfm | 6 +- .../nordic_nrf/CMakeLists.txt | 67 +++++++++++++++++++ .../nordic_nrf/include/RTE_Device.h | 52 ++++++++++++++ .../nordic_nrf/include/device_cfg.h | 32 +++++++++ .../nordic_nrf/include/tfm_ioctl_api.h | 32 +++++++++ .../include/tfm_peripherals_config.h | 40 +++++++++++ .../nordic_nrf/include/tfm_read_ranges.h | 60 +++++++++++++++++ .../nordic_nrf/include/util/array.h | 20 ++++++ .../nordic_nrf/nrf5340_cpuapp/CMakeLists.txt | 12 ++++ .../nordic_nrf/nrf5340_cpuapp/config.cmake | 8 +++ .../nordic_nrf/nrf5340_cpuapp/preload.cmake | 7 ++ .../nordic_nrf/nrf9120/CMakeLists.txt | 12 ++++ .../nordic_nrf/nrf9120/config.cmake | 8 +++ .../nordic_nrf/nrf9120/preload.cmake | 7 ++ .../nordic_nrf/nrf9160/CMakeLists.txt | 12 ++++ .../nordic_nrf/nrf9160/config.cmake | 8 +++ .../nordic_nrf/nrf9160/preload.cmake | 7 ++ .../nordic_nrf/src/tfm_hal_platform.c | 13 ++++ .../nordic_nrf/src/tfm_platform_system.c | 38 +++++++++++ soc/arm/nordic_nrf/CMakeLists.txt | 4 ++ soc/arm/nordic_nrf/Kconfig | 7 ++ west.yml | 2 +- 22 files changed, 450 insertions(+), 4 deletions(-) create mode 100644 modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/include/util/array.h create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake create mode 100644 modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c create mode 100644 modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index a9980819589..17f48e9fb03 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -9,9 +9,6 @@ config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE config TFM_BOARD string - default "nordic_nrf/nrf9160dk_nrf9160" if BOARD_NRF9160DK_NRF9160_NS - default "nordic_nrf/nrf9161dk_nrf9161" if BOARD_NRF9161DK_NRF9161_NS - default "nordic_nrf/nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP_NS default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_CPU0 default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS default "arm/mps3/an547" if BOARD_MPS3_AN547 @@ -21,6 +18,9 @@ config TFM_BOARD default "arm/musca_b1" if BOARD_MUSCA_B1 default "arm/musca_s1" if BOARD_MUSCA_S1 default "lairdconnectivity/bl5340_dvk_cpuapp" if BOARD_BL5340_DVK_CPUAPP_NS + default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf9160" if SOC_NRF9160 + default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf9120" if SOC_NRF9120 + default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp" if SOC_NRF5340_CPUAPP help The board name used for building TFM. Building with TFM requires that TFM has been ported to the given board/SoC. diff --git a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt new file mode 100644 index 00000000000..41dca2f15a9 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(partition_includes + ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/${NRF_SOC_VARIANT}/partition + ${CMAKE_BINARY_DIR}/../zephyr/include/generated +) + +set(board_includes + ${CMAKE_BINARY_DIR}/../zephyr/misc/generated/syscalls_links/include + ${ZEPHYR_BASE}/include +) + +target_include_directories(platform_region_defs + INTERFACE + ${partition_includes} +) + + +target_sources(platform_s + PRIVATE + $<$:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_platform_system.c> +) + +target_include_directories(platform_s + PUBLIC + services/include + include + ${partition_includes} + ${board_includes} +) + +target_include_directories(platform_ns + PUBLIC + include + include/util + ${partition_includes} + ${board_includes} +) + +if(BL2) + target_include_directories(platform_bl2 + PUBLIC + include + include/util + ${partition_includes} + ${board_includes} + ) +endif() + +if (TFM_PARTITION_PLATFORM) +install(FILES include/tfm_ioctl_api.h + DESTINATION ${TFM_INSTALL_PATH}/interface/include) +endif() + +#========================= tfm_spm ============================================# + +target_sources(tfm_spm + PRIVATE + src/tfm_hal_platform.c +) diff --git a/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h b/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h new file mode 100644 index 00000000000..ca886583fa9 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RTE_DEVICE_H +#define __RTE_DEVICE_H + +#include + +/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */ +#undef ARRAY_SIZE +#include + +#define UART_PIN_INIT(node_id, prop, idx) \ + DT_PROP_BY_IDX(node_id, prop, idx), + +/* Configuration settings for Driver_USART0. */ +#if DOMAIN_NS == 1U + +#define RTE_USART0 1 + +#define RTE_USART0_PINS \ +{ \ + DT_FOREACH_CHILD_VARGS( \ + DT_PINCTRL_BY_NAME(DT_NODELABEL(uart0), default, 0), \ + DT_FOREACH_PROP_ELEM, psels, UART_PIN_INIT \ + ) \ +} + +#endif + +/* Configuration settings for Driver_USART1. */ +#if DT_PINCTRL_HAS_NAME(DT_NODELABEL(uart1), default) && DOMAIN_NS != 1U + +#define RTE_USART1 1 + +#define RTE_USART1_PINS \ +{ \ + DT_FOREACH_CHILD_VARGS( \ + DT_PINCTRL_BY_NAME(DT_NODELABEL(uart1), default, 0), \ + DT_FOREACH_PROP_ELEM, psels, UART_PIN_INIT \ + ) \ +} + +#endif + +/* Configuration settings for Driver_FLASH0. */ +#define RTE_FLASH0 1 + +#endif /* __RTE_DEVICE_H */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h b/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h new file mode 100644 index 00000000000..9b766a35eb9 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DEVICE_CFG_H__ +#define DEVICE_CFG_H__ + +#include + +/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */ +#undef ARRAY_SIZE +#include + +#if DOMAIN_NS == 1U +#define TFM_UART uart0 +#endif + +#if DOMAIN_NS != 1U +#define TFM_UART uart1 +#endif + +#define DEFAULT_UART_BAUDRATE DT_PROP_OR(DT_NODELABEL(TFM_UART), current_speed, 115200) + +#if DT_PROP(DT_NODELABEL(TFM_UART), hw_flow_control) +#define DEFAULT_UART_CONTROL ARM_USART_FLOW_CONTROL_RTS_CTS +#else +#define DEFAULT_UART_CONTROL 0 +#endif + +#endif /* DEVICE_CFG_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h new file mode 100644 index 00000000000..c6c36ee927f --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TFM_IOCTL_API_H__ +#define TFM_IOCTL_API_H__ + +#include +#include +#include +#include + +/* Include core IOCTL services */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Board specific IOCTL services can be added here */ + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* TFM_IOCTL_API_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h new file mode 100644 index 00000000000..577b583ad03 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TFM_PERIPHERALS_CONFIG_H__ +#define TFM_PERIPHERALS_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SECURE_UART1 +#define TFM_PERIPHERAL_UARTE1_SECURE 1 +#endif + +#if TEST_NS_SLIH_IRQ || TEST_NS_FLIH_IRQ +#define TFM_PERIPHERAL_TIMER0_SECURE 1 +#endif + +#ifdef PSA_API_TEST_IPC +#define TFM_PERIPHERAL_EGU5_SECURE 1 + +#define TFM_PERIPHERAL_WDT_SECURE 1 +#endif + +#if defined(NRF91_SERIES) + #include +#elif defined(NRF5340_XXAA_APPLICATION) + #include +#else + #error "Unknown device." +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* TFM_PERIPHERAL_CONFIG_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h new file mode 100644 index 00000000000..43468c7fa31 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TFM_READ_RANGES_H__ +#define TFM_READ_RANGES_H__ + +#include + +#include + +#ifdef NRF_FICR_S_BASE + +#define FICR_BASE NRF_FICR_S_BASE + +#define FICR_INFO_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, INFO)) +#define FICR_INFO_SIZE (sizeof(FICR_INFO_Type)) + +#if defined(FICR_NFC_TAGHEADER0_MFGID_Msk) +#define FICR_NFC_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, NFC)) +#define FICR_NFC_SIZE (sizeof(FICR_NFC_Type)) +#endif + +#if defined(FICR_XOSC32MTRIM_SLOPE_Msk) +#define FICR_XOSC32MTRIM_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, XOSC32MTRIM)) +#define FICR_XOSC32MTRIM_SIZE (sizeof(uint32_t)) +#endif + +/* Used by nrf_erratas.h */ +#define FICR_RESTRICTED_ADDR (FICR_BASE + 0x130) +#define FICR_RESTRICTED_SIZE 0x8 + +#if defined(FICR_SIPINFO_PARTNO_PARTNO_Pos) +#define FICR_SIPINFO_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, SIPINFO)) +#define FICR_SIPINFO_SIZE (sizeof(FICR_SIPINFO_Type)) +#endif + +#endif /* NRF_FICR_S_BASE */ + +static const struct tfm_read_service_range ranges[] = { +#if defined(FICR_INFO_ADDR) + { .start = FICR_INFO_ADDR, .size = FICR_INFO_SIZE }, +#endif +#if defined(FICR_NFC_ADDR) + { .start = FICR_NFC_ADDR, .size = FICR_NFC_SIZE }, +#endif +#if defined(FICR_RESTRICTED_ADDR) + { .start = FICR_RESTRICTED_ADDR, .size = FICR_RESTRICTED_SIZE }, +#endif +#if defined(FICR_XOSC32MTRIM_ADDR) + { .start = FICR_XOSC32MTRIM_ADDR, .size = FICR_XOSC32MTRIM_SIZE }, +#endif +#if defined(FICR_SIPINFO_ADDR) + { .start = FICR_SIPINFO_ADDR, .size = FICR_SIPINFO_SIZE }, +#endif +}; + +#endif /* TFM_READ_RANGES_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/util/array.h b/modules/trusted-firmware-m/nordic_nrf/include/util/array.h new file mode 100644 index 00000000000..dc9a1f3dddf --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/include/util/array.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ARRAY_H__ +#define __ARRAY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* __ARRAY_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt new file mode 100644 index 00000000000..279ea385996 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_BOARD_SELECTED True) +set(NRF_SOC_VARIANT nrf5340) + +add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf5340 nrf5340) + +add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake new file mode 100644 index 00000000000..b3e5d74181c --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +include(${PLATFORM_PATH}/common/nrf5340/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake new file mode 100644 index 00000000000..d9bd226eb65 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake @@ -0,0 +1,7 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +include(platform/ext/target/nordic_nrf/common/nrf5340/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt new file mode 100644 index 00000000000..a84c6fd9fd5 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_BOARD_SELECTED True) +set(NRF_SOC_VARIANT nrf91) + +add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) + +add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake new file mode 100644 index 00000000000..3f58e7b89eb --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake new file mode 100644 index 00000000000..4b3c6ee79ab --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake @@ -0,0 +1,7 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +include(platform/ext/target/nordic_nrf/common/nrf9120/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt new file mode 100644 index 00000000000..a84c6fd9fd5 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_BOARD_SELECTED True) +set(NRF_SOC_VARIANT nrf91) + +add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) + +add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake new file mode 100644 index 00000000000..3f58e7b89eb --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake new file mode 100644 index 00000000000..364480a6f7f --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake @@ -0,0 +1,7 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +include(platform/ext/target/nordic_nrf/common/nrf9160/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c b/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c new file mode 100644 index 00000000000..508c1945910 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tfm_hal_defs.h" +#include "tfm_hal_platform_common.h" + +enum tfm_hal_status_t tfm_hal_platform_init(void) +{ + return tfm_hal_platform_common_init(); +} diff --git a/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c b/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c new file mode 100644 index 00000000000..b96e1fe1188 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "platform/include/tfm_platform_system.h" +#include "cmsis.h" +#include "tfm_platform_hal_ioctl.h" +#include "tfm_ioctl_core_api.h" + +void tfm_platform_hal_system_reset(void) +{ + /* Reset the system */ + NVIC_SystemReset(); +} + +enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *in_vec, + psa_outvec *out_vec) +{ + /* Core IOCTL services */ + switch (request) { + case TFM_PLATFORM_IOCTL_READ_SERVICE: + return tfm_platform_hal_read_service(in_vec, out_vec); +#if defined(GPIO_PIN_CNF_MCUSEL_Msk) + case TFM_PLATFORM_IOCTL_GPIO_SERVICE: + return tfm_platform_hal_gpio_service(in_vec, out_vec); +#endif /* defined(GPIO_PIN_CNF_MCUSEL_Msk) */ + + + /* Board specific IOCTL services */ + + /* Not a supported IOCTL service.*/ + default: + return TFM_PLATFORM_ERR_NOT_SUPPORTED; + } +} diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 4cfc162f7fd..47364b35ffb 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -21,4 +21,8 @@ if(CONFIG_BUILD_WITH_TFM) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DHAL_NORDIC_PATH=${ZEPHYR_HAL_NORDIC_MODULE_DIR} ) + + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} + ) endif() diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index c2129db64b3..0e3b3e4ee6d 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -25,6 +25,13 @@ config NRF_SOC_SECURE_SUPPORTED For non-secure the functions must redirect to secure services exposed by the secure firmware. +config TFM_LOG_LEVEL_SILENCE + default y if !$(dt_nodelabel_has_prop,uart1,pinctrl-names) + depends on BUILD_WITH_TFM + help + Disable TF-M secure output if the uart1 node has not assigned GPIO + pins using pinctrl. + config NRF_MPU_FLASH_REGION_SIZE hex default 0x1000 diff --git a/west.yml b/west.yml index 239c2cf6d69..868570bb833 100644 --- a/west.yml +++ b/west.yml @@ -321,7 +321,7 @@ manifest: groups: - crypto - name: trusted-firmware-m - revision: b168d92c7ed3c77c94d7ce3362bdde5dbffe8424 + revision: 696b09568c6b30cbcbe5b8764f703c90a48825eb path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 32a1c89e2e1accf24aa4df93d1b4e7e988a3df5c Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 5 Oct 2023 13:11:13 +0200 Subject: [PATCH 2479/4498] boards: Add uart1 pinctrl assignment to nrf5340 Audio DK Add uart1 pinctrl assignment to nrf5340 Audio DK. Assigned according to Schematic for this board. Uart1 pins needed by TF-M when using the NS board variant. Signed-off-by: Joakim Andersson --- ...udio_dk_nrf5340_cpuapp_common-pinctrl.dtsi | 22 +++++++++++++++++++ ...rf5340_audio_dk_nrf5340_cpuapp_common.dtsi | 8 +++++++ 2 files changed, 30 insertions(+) diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi index 46359082edd..5247c04429b 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi @@ -51,6 +51,28 @@ }; }; + uart1_default: uart1_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + i2c1_default: i2c1_default { group1 { psels = , diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi index f529f16fbe8..df028fb75a2 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi @@ -141,6 +141,14 @@ pinctrl-names = "default", "sleep"; }; +arduino_serial: &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + &i2c1 { compatible = "nordic,nrf-twim"; status = "okay"; From 17fd1f8fba3bd862c53ca98f618ac574efef58dd Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 5 May 2022 12:04:26 +0200 Subject: [PATCH 2480/4498] boards: Enable TF-M by default for nordic SoC NS boards Enable TF-M by default for nordic nRF5340 and nrf9160 SoC boards. Signed-off-by: Joakim Andersson --- boards/arm/bl5340_dvk/Kconfig.defconfig | 15 --------------- boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig | 15 --------------- boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig | 15 --------------- boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig | 15 --------------- .../Kconfig.defconfig | 15 --------------- .../Kconfig.defconfig | 14 -------------- soc/arm/nordic_nrf/Kconfig | 18 +++++++++++++++++- 7 files changed, 17 insertions(+), 90 deletions(-) diff --git a/boards/arm/bl5340_dvk/Kconfig.defconfig b/boards/arm/bl5340_dvk/Kconfig.defconfig index 38a06c8b91d..e033f718dba 100644 --- a/boards/arm/bl5340_dvk/Kconfig.defconfig +++ b/boards/arm/bl5340_dvk/Kconfig.defconfig @@ -13,21 +13,6 @@ config BOARD config I2C default GPIO || DAC -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_BL5340_DVK_CPUAPP_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # Code Partition: # # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig index d337e2f1a1c..09ebfbf50ba 100644 --- a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig @@ -8,21 +8,6 @@ if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS config BOARD default "nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_NRF5340DK_NRF5340_CPUAPP_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # Code Partition: # # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig b/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig index cd052dc7a20..7d9046f63b5 100644 --- a/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig +++ b/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig @@ -8,21 +8,6 @@ if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS config BOARD default "nrf9160dk_nrf9160" -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_NRF9160DK_NRF9160_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig index 2674e87cad4..ea7150ede5f 100644 --- a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig +++ b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig @@ -8,21 +8,6 @@ if BOARD_NRF9161DK_NRF9161 || BOARD_NRF9161DK_NRF9161_NS config BOARD default "nrf9161dk_nrf9161" -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_NRF9161DK_NRF9161_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig index a0a59dc13ab..103bc77168e 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig @@ -8,21 +8,6 @@ if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF534 config BOARD default "raytac_mdbt53_db_40_nrf5340_cpuapp" -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default n if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default n - -endif # BUILD_WITH_TFM - # Code Partition: # # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig index 54c3d6cccf0..1639553b37e 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig @@ -7,20 +7,6 @@ if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5 config BOARD default "raytac_mdbt53v_db_40_nrf5340_cpuapp" if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default n if BOARD_BL5340_DVK_CPUAPP_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default n - -endif # BUILD_WITH_TFM # Code Partition: # diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 0e3b3e4ee6d..19e49c05454 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -25,13 +25,29 @@ config NRF_SOC_SECURE_SUPPORTED For non-secure the functions must redirect to secure services exposed by the secure firmware. +config BUILD_WITH_TFM + default y if TRUSTED_EXECUTION_NONSECURE + help + By default, if we build for a Non-Secure version of the board, + enable building with TF-M as the Secure Execution Environment. + +if BUILD_WITH_TFM + +config TFM_FLASH_MERGED_BINARY + default y + help + By default, if we build with TF-M, instruct build system to + flash the combined TF-M (Secure) & Zephyr (Non Secure) image + config TFM_LOG_LEVEL_SILENCE default y if !$(dt_nodelabel_has_prop,uart1,pinctrl-names) - depends on BUILD_WITH_TFM help Disable TF-M secure output if the uart1 node has not assigned GPIO pins using pinctrl. +endif # BUILD_WITH_TFM + + config NRF_MPU_FLASH_REGION_SIZE hex default 0x1000 From 142dd9fb138d5156b2befe9bff340ffe975e8530 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 4 Oct 2023 12:33:04 +0200 Subject: [PATCH 2481/4498] doc: Remove note for missing tf-m/ns target support All nRF91 and nRF5340 boards (except the DKs) should support TF-M/_ns now. Signed-off-by: Joakim Andersson --- boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst | 3 --- boards/arm/nrf9160_innblue21/doc/index.rst | 3 --- boards/arm/nrf9160_innblue22/doc/index.rst | 3 --- boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst | 3 --- boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst | 3 --- boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst | 3 --- boards/arm/thingy53_nrf5340/doc/index.rst | 3 --- 7 files changed, 21 deletions(-) diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst b/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst index 7718258eec2..3d8d2413e91 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst +++ b/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst @@ -53,9 +53,6 @@ The nrf5340_audio_dk_nrf5340_cpuapp build target provides support for the applic core on the nRF5340 SoC. The nrf5340_audio_dk_nrf5340_cpunet build target provides support for the network core on the nRF5340 SoC. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. diff --git a/boards/arm/nrf9160_innblue21/doc/index.rst b/boards/arm/nrf9160_innblue21/doc/index.rst index 628166c409c..9ded085dc6f 100644 --- a/boards/arm/nrf9160_innblue21/doc/index.rst +++ b/boards/arm/nrf9160_innblue21/doc/index.rst @@ -104,9 +104,6 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - Building a Secure only application ================================== diff --git a/boards/arm/nrf9160_innblue22/doc/index.rst b/boards/arm/nrf9160_innblue22/doc/index.rst index ce3eb35d60f..06f6b6326f8 100644 --- a/boards/arm/nrf9160_innblue22/doc/index.rst +++ b/boards/arm/nrf9160_innblue22/doc/index.rst @@ -104,9 +104,6 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - Building a Secure only application ================================== diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst b/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst index a63714a5349..bcff494f91b 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst @@ -24,9 +24,6 @@ The raytac_mdbt53_db_40_nrf5340_cpuapp build target provides support for the app core on the nRF5340 SoC. The raytac_mdbt53_db_40_nrf5340_cpuapp build target provides support for the network core on the nRF5340 SoC. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - nRF5340 SoC provides support for the following devices: * :abbr:`ADC (Analog to Digital Converter)` diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst b/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst index cc2285f1484..ca38f03a781 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst @@ -24,9 +24,6 @@ The raytac_mdbt53v_db_40_nrf5340_cpuapp build target provides support for the ap core on the nRF5340 SoC. The raytac_mdbt53v_db_40_nrf5340_cpuapp build target provides support for the network core on the nRF5340 SoC. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - nRF5340 SoC provides support for the following devices: * :abbr:`ADC (Analog to Digital Converter)` diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst index 72dac6a8900..8ee7a38cb33 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst +++ b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst @@ -91,9 +91,6 @@ Building an application In most cases you'll want to use the ``ns`` target with any of the Zephyr or Nordic based examples. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - Some of the examples do not use secure mode, so they do not required the ``ns`` suffix. A great example of this is the `hello_world` below. diff --git a/boards/arm/thingy53_nrf5340/doc/index.rst b/boards/arm/thingy53_nrf5340/doc/index.rst index 3a77deee968..4544ea7ed79 100644 --- a/boards/arm/thingy53_nrf5340/doc/index.rst +++ b/boards/arm/thingy53_nrf5340/doc/index.rst @@ -22,9 +22,6 @@ The nrf5340dk_nrf5340_cpuapp build target provides support for the application core on the nRF5340 SoC. The nrf5340dk_nrf5340_cpunet build target provides support for the network core on the nRF5340 SoC. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. From ddf5c4374e264e9355e8ae50b6f417196c95b4e5 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 10 Oct 2023 09:24:51 +0200 Subject: [PATCH 2482/4498] boards: raytac_mdbt53_db_40_nrf5340: Add HW flow control pins Add HW flow control pins for raytac_mdbt53_db_40_nrf5340 board. Use the same pins as the cpunet has been assigned, as the RX / TX lines was also using the same as cpunet. Remove bias-pull-up as uart1 using same pins on cpunet does not have this either. Signed-off-by: Joakim Andersson --- ..._mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi index dabb02cc3c4..3a3e39f824f 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi @@ -41,18 +41,19 @@ uart1_default: uart1_default { group1 { - psels = ; - }; - group2 { - psels = ; - bias-pull-up; + psels = , + , + , + ; }; }; uart1_sleep: uart1_sleep { group1 { psels = , - ; + , + , + ; low-power-enable; }; }; From 023d4838fbb8513f9d9ff6f26b065591131c347d Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 10 Oct 2023 09:26:26 +0200 Subject: [PATCH 2483/4498] boards: raytac_mdbt53v_db_40_nrf5340: Add uart1 pin assignment Add uart1 pin assignment for the raytac_mdbt53v_db_40_nrf5340 board. This is required in order to support building TF-M for the NS variant. Signed-off-by: Joakim Andersson --- ...v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi | 19 +++++++++++++++++++ ...ac_mdbt53v_db_40_nrf5340_cpuapp_common.dts | 8 ++++++++ ..._mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi index 0839492b156..0574b5b3892 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi @@ -39,6 +39,25 @@ }; }; + uart1_default: uart1_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + pwm0_default: pwm0_default { group1 { psels = ; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts index 79887dba909..032678e7526 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts @@ -107,6 +107,14 @@ pinctrl-names = "default", "sleep"; }; +&uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi index 15e96ef213e..51197c008bb 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi @@ -9,7 +9,7 @@ group1 { psels = , , - , + , ; }; }; From fd1c226cd806ec8c8250bddc5def11a114d712be Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 16 Oct 2023 14:46:51 +0300 Subject: [PATCH 2484/4498] net: tcp: Increment ref count in initial SYN Increase reference count already when initial SYN is sent. This way the tcp pointer in net_context is fully valid for the duration of the connection. Fixes #63952 Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 648a3720076..050cc81a8dc 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2497,6 +2497,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) conn->send_options.mss_found = false; conn_seq(conn, + 1); next = TCP_SYN_SENT; + tcp_conn_ref(conn); } break; case TCP_SYN_RECEIVED: @@ -2604,7 +2605,6 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) } next = TCP_ESTABLISHED; - tcp_conn_ref(conn); net_context_set_state(conn->context, NET_CONTEXT_CONNECTED); tcp_ca_init(conn); From b864880000087fb3aee1ef7f386cc105c52a9158 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 18 Oct 2023 13:30:10 +0300 Subject: [PATCH 2485/4498] net: sockets: Add SO_ERROR socket option to SOL_SOCKET level Return the last socket error to user. Signed-off-by: Jukka Rissanen --- subsys/net/lib/sockets/sockets.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index dfa0b3e2c43..2ad891139ae 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -1938,6 +1938,17 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname, switch (level) { case SOL_SOCKET: switch (optname) { + case SO_ERROR: { + if (*optlen != sizeof(int)) { + errno = EINVAL; + return -1; + } + + *(int *)optval = POINTER_TO_INT(ctx->user_data); + + return 0; + } + case SO_TYPE: { int type = (int)net_context_get_type(ctx); From ec4973dd156f3fb8e56fc90c09484d914d43a3df Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 18 Oct 2023 14:19:45 +0300 Subject: [PATCH 2486/4498] net: tcp: Set errno properly if connecting to non listening port If we try to connect to a port which no socket is listening to, we will get a packet with "ACK | RST" flags set. In this case the errno should be ECONNREFUSED instead of ETIMEDOUT like we used to return earlier. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 050cc81a8dc..18da61f5812 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2417,6 +2417,18 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) net_stats_update_tcp_seg_rst(net_pkt_iface(pkt)); do_close = true; close_status = -ECONNRESET; + + /* If we receive RST and ACK for the sent SYN, it means + * that there is no socket listening the port we are trying + * to connect to. Set the errno properly in this case. + */ + if (conn->in_connect) { + fl = th_flags(th); + if (FL(&fl, ==, RST | ACK)) { + close_status = -ECONNREFUSED; + } + } + goto out; } From 5bf18e39add393f492e7e7de9cb578c8dc78860f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 18 Oct 2023 14:21:53 +0300 Subject: [PATCH 2487/4498] net: sockets: Set writefds in case of error in select() The writefds is typically set if there is an error while waiting for example the connect() to finish. So check if the user supplied the writefds and update it accordingly. Signed-off-by: Jukka Rissanen --- subsys/net/lib/sockets/sockets_select.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_select.c b/subsys/net/lib/sockets/sockets_select.c index c6d110bad07..31c98416b81 100644 --- a/subsys/net/lib/sockets/sockets_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -196,6 +196,11 @@ int z_impl_zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, ZSOCK_FD_SET(fd, exceptfds); num_selects++; } + + if (writefds != NULL) { + ZSOCK_FD_SET(fd, writefds); + num_selects++; + } } res--; From b510073db3c4537ba0dce882b8a522692cf00cd9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 16 Oct 2023 14:50:45 +0300 Subject: [PATCH 2488/4498] tests: net: tcp: Add test case for connect timeout This checks that if connect() timeouts, we check TCP pointer properly in select() and poll() in order to catch the situation. Signed-off-by: Jukka Rissanen --- tests/net/socket/tcp/src/main.c | 141 +++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/tests/net/socket/tcp/src/main.c b/tests/net/socket/tcp/src/main.c index 5095e6512a7..c96ecb029a2 100644 --- a/tests/net/socket/tcp/src/main.c +++ b/tests/net/socket/tcp/src/main.c @@ -933,11 +933,18 @@ ZTEST(net_socket_tcp, test_connect_timeout) test_close(c_sock); + /* If we have preemptive option set, then sleep here in order to allow + * other part of the system to run and update itself. + */ + if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) { + k_sleep(K_MSEC(10)); + } + /* After the client socket closing, the context count should be 0 */ net_context_foreach(calc_net_context, &count_after); zassert_equal(count_after, 0, - "net_context still in use"); + "net_context %d still in use", count_after); restore_packet_loss_ratio(); } @@ -2068,6 +2075,138 @@ ZTEST(net_socket_tcp, test_ioctl_fionread_v6) test_ioctl_fionread_common(AF_INET6); } +/* Connect to peer which is not listening the test port and + * make sure select() returns proper error for the closed + * connection. + */ +ZTEST(net_socket_tcp, test_connect_and_wait_for_v4_select) +{ + struct sockaddr_in addr = { 0 }; + struct in_addr v4addr; + int fd, flags, ret, optval; + socklen_t optlen = sizeof(optval); + + fd = socket(AF_INET, SOCK_STREAM, 0); + + flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + + inet_pton(AF_INET, "127.0.0.1", (void *)&v4addr); + + addr.sin_family = AF_INET; + net_ipaddr_copy(&addr.sin_addr, &v4addr); + + /* There should be nobody serving this port */ + addr.sin_port = htons(8088); + + ret = connect(fd, (const struct sockaddr *)&addr, sizeof(addr)); + zassert_equal(ret, -1, "connect succeed, %d", errno); + zassert_equal(errno, EINPROGRESS, "connect succeed, %d", errno); + + /* Wait for the connection (this should fail eventually) */ + while (1) { + fd_set wfds; + struct timeval tv = { + .tv_sec = 1, + .tv_usec = 0 + }; + + FD_ZERO(&wfds); + FD_SET(fd, &wfds); + + /* Check if the connection is there, this should timeout */ + ret = select(fd + 1, NULL, &wfds, NULL, &tv); + if (ret < 0) { + break; + } + + if (ret > 0) { + if (FD_ISSET(fd, &wfds)) { + break; + } + } + } + + zassert_true(ret > 0, "select failed, %d", errno); + + /* Get the reason for the connect */ + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); + zassert_equal(ret, 0, "getsockopt failed, %d", errno); + + /* If SO_ERROR is 0, then it means that connect succeed. Any + * other value (errno) means that it failed. + */ + zassert_equal(optval, ECONNREFUSED, "unexpected connect status, %d", optval); + + ret = close(fd); + zassert_equal(ret, 0, "close failed, %d", errno); +} + +/* Connect to peer which is not listening the test port and + * make sure poll() returns proper error for the closed + * connection. + */ +ZTEST(net_socket_tcp, test_connect_and_wait_for_v4_poll) +{ + struct sockaddr_in addr = { 0 }; + struct pollfd fds[1]; + struct in_addr v4addr; + int fd, flags, ret, optval; + bool closed = false; + socklen_t optlen = sizeof(optval); + + fd = socket(AF_INET, SOCK_STREAM, 0); + + flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + + inet_pton(AF_INET, "127.0.0.1", (void *)&v4addr); + + addr.sin_family = AF_INET; + net_ipaddr_copy(&addr.sin_addr, &v4addr); + + /* There should be nobody serving this port */ + addr.sin_port = htons(8088); + + ret = connect(fd, (const struct sockaddr *)&addr, sizeof(addr)); + zassert_equal(ret, -1, "connect succeed, %d", errno); + zassert_equal(errno, EINPROGRESS, "connect succeed, %d", errno); + + /* Wait for the connection (this should fail eventually) */ + while (1) { + memset(fds, 0, sizeof(fds)); + fds[0].fd = fd; + fds[0].events = POLLOUT; + + /* Check if the connection is there, this should timeout */ + ret = poll(fds, 1, 10); + if (ret < 0) { + break; + } + + if (fds[0].revents > 0) { + if (fds[0].revents & POLLERR) { + closed = true; + break; + } + } + } + + zassert_true(closed, "poll failed, %d", errno); + + /* Get the reason for the connect */ + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); + zassert_equal(ret, 0, "getsockopt failed, %d", errno); + + /* If SO_ERROR is 0, then it means that connect succeed. Any + * other value (errno) means that it failed. + */ + zassert_equal(optval, ECONNREFUSED, "unexpected connect status, %d", optval); + + ret = close(fd); + zassert_equal(ret, 0, "close failed, %d", errno); +} + static void after(void *arg) { ARG_UNUSED(arg); From 2e5c37142c3b5fb8782a7a736adc09771f14eae0 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 21:40:04 +0000 Subject: [PATCH 2489/4498] scripts: kconfig: Always generate ZEPHYR_*_MODULE Define the ZEPHYR_{MODULE_NAM}_MODULE option for all available modules. Right now only modules defined as 'kconfig-ext' has this symbol defined which may cause problem if the build wants to check if a module not using this options is available. This allow us to do something like: comment "mbedTLS module not available." depends on !ZEPHYR_MBEDTLS_MODULE or make a feature depends on the module be present. Signed-off-by: Flavio Ceolin --- scripts/zephyr_module.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/zephyr_module.py b/scripts/zephyr_module.py index db58bcea23c..ab27eaa5706 100755 --- a/scripts/zephyr_module.py +++ b/scripts/zephyr_module.py @@ -350,7 +350,10 @@ def process_kconfig(module, meta): return kconfig_snippet(meta, module_path, Path(kconfig_file), blobs=taint_blobs) else: - return "" + name_sanitized = meta['name-sanitized'] + return (f'config ZEPHYR_{name_sanitized.upper()}_MODULE\n' + f' bool\n' + f' default y\n') def process_sysbuildkconfig(module, meta): From 761a3039bbb2dc8f2d43494fc00b1fce63ea10fb Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 6 Sep 2023 15:57:06 +0000 Subject: [PATCH 2490/4498] modules: Remove legacy comment Module's Kconfig depends now in the presence of the module itself. Signed-off-by: Flavio Ceolin --- modules/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/Kconfig b/modules/Kconfig index 687ce19da81..e1d5065158b 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -12,8 +12,6 @@ comment "Available modules." osource "$(KCONFIG_BINARY_DIR)/Kconfig.modules" -comment "Optional modules. Make sure they're installed, via the project manifest." - source "modules/Kconfig.altera" source "modules/Kconfig.atmel" source "modules/Kconfig.chre" From 713ca15224c3223e99bf045b1ab50a6917bf60ea Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 21:48:59 +0000 Subject: [PATCH 2491/4498] modules: tinycrypt: Options only when module is available Only show tinycrypt menu options when the module is available. Signed-off-by: Flavio Ceolin --- modules/Kconfig.tinycrypt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/Kconfig.tinycrypt b/modules/Kconfig.tinycrypt index 7f279fbc59a..168e05ed799 100644 --- a/modules/Kconfig.tinycrypt +++ b/modules/Kconfig.tinycrypt @@ -3,8 +3,12 @@ # Copyright (c) 2015 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_TINYCRYPT_MODULE + bool + config TINYCRYPT bool "TinyCrypt Support" + depends on ZEPHYR_TINYCRYPT_MODULE help This option enables the TinyCrypt cryptography library. From 9eff0ca521c79f8151fbcc462fb2e57e373f9dc3 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 21:53:33 +0000 Subject: [PATCH 2492/4498] modules: libmetal: Options only when module is available Only show libmetal menu options when the module is available. Signed-off-by: Flavio Ceolin --- modules/Kconfig.libmetal | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/Kconfig.libmetal b/modules/Kconfig.libmetal index dd01125e14e..b1575c82902 100644 --- a/modules/Kconfig.libmetal +++ b/modules/Kconfig.libmetal @@ -1,8 +1,12 @@ # Copyright (c) 2018 Linaro Limited # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_LIBMETAL_MODULE + bool + menuconfig LIBMETAL bool "libmetal Support" + depends on ZEPHYR_LIBMETAL_MODULE help This option enables the libmetal HAL abstraction layer From f4cb487b79f9c071351fdabdd3ded30cbb1c7513 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 22:10:43 +0000 Subject: [PATCH 2493/4498] modules: sof: Options only when module is available Only show sof menu options when the module is available. Signed-off-by: Flavio Ceolin --- modules/Kconfig.sof | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/Kconfig.sof b/modules/Kconfig.sof index 17e40df34b5..4a0b9418660 100644 --- a/modules/Kconfig.sof +++ b/modules/Kconfig.sof @@ -1,7 +1,11 @@ # Copyright (c) 2020 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_SOF_MODULE + bool + config SOF bool "Sound Open Firmware (SOF)" + depends on ZEPHYR_SOF_MODULE help Build Sound Open Firmware (SOF) support. From 2e6871a46fb5e78b6f8bd5c7b71f687dfb409d51 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 22:13:13 +0000 Subject: [PATCH 2494/4498] modules: openamp: Options only when module is available Only show openamp menu options when the module is available. Signed-off-by: Flavio Ceolin --- modules/Kconfig.open-amp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/Kconfig.open-amp b/modules/Kconfig.open-amp index 5db32041bca..71d2885e5a7 100644 --- a/modules/Kconfig.open-amp +++ b/modules/Kconfig.open-amp @@ -1,8 +1,12 @@ # Copyright (c) 2018 Linaro Limited # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_OPEN_AMP_MODULE + bool + config OPENAMP bool "OpenAMP Support" + depends on ZEPHYR_OPEN_AMP_MODULE select LIBMETAL help This option enables the OpenAMP IPC library From ffe128534370de1de9f5a6ff60a11cf7f411c26b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 10 May 2023 22:16:31 +0000 Subject: [PATCH 2495/4498] modules: zcbor: Options only when module is available Only show zcbor menu options when the module is available. Signed-off-by: Flavio Ceolin --- modules/zcbor/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/zcbor/Kconfig b/modules/zcbor/Kconfig index 5b71f8f45ae..1b3fd15d5e3 100644 --- a/modules/zcbor/Kconfig +++ b/modules/zcbor/Kconfig @@ -6,6 +6,7 @@ config ZEPHYR_ZCBOR_MODULE config ZCBOR bool "zcbor CBOR library" + depends on ZEPHYR_ZCBOR_MODULE help zcbor CBOR encoder/decoder library From aa46254708a303a44d19173ab0f5a22d7c2e4c91 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Fri, 29 Sep 2023 16:57:13 +0800 Subject: [PATCH 2496/4498] boards: arm64: rpi_4b: Fix doc * defconfig is located under `boards/arm64/` instead of `boards/arm/` * 64-bit mode (`arm_64bit=1`) is required to boot Signed-off-by: Chen Xingyu --- boards/arm64/rpi_4b/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/arm64/rpi_4b/doc/index.rst b/boards/arm64/rpi_4b/doc/index.rst index cdc9d9cc148..2083b7cdb10 100644 --- a/boards/arm64/rpi_4b/doc/index.rst +++ b/boards/arm64/rpi_4b/doc/index.rst @@ -28,7 +28,7 @@ Other hardware features have not been enabled yet for this board. The default configuration can be found in the defconfig file: - ``boards/arm/rpi_4b/rpi_4b_defconfig`` + ``boards/arm64/rpi_4b/rpi_4b_defconfig`` Programming and Debugging ************************* @@ -38,7 +38,7 @@ Flashing 1. Install Raspberry Pi OS using Raspberry Pi Imager. see . -2. add `kernel=zephyr.bin` in `config.txt`. see +2. Add `kernel=zephyr.bin` and `arm_64bit=1` in `config.txt`. see .. code-block:: console From f2b3d704d7d23bfa817f24e00ece60191e661569 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Sat, 14 Oct 2023 10:08:20 +0800 Subject: [PATCH 2497/4498] boards: arm64: rpi_4b: Convert to `list-table` syntax Keep aligned with `rpi_pico` board. Signed-off-by: Chen Xingyu --- boards/arm64/rpi_4b/doc/index.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/boards/arm64/rpi_4b/doc/index.rst b/boards/arm64/rpi_4b/doc/index.rst index 2083b7cdb10..3a5cd625616 100644 --- a/boards/arm64/rpi_4b/doc/index.rst +++ b/boards/arm64/rpi_4b/doc/index.rst @@ -16,13 +16,18 @@ Supported Features The Raspberry Pi 4 Model B board configuration supports the following hardware features: -+-----------+------------+--------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+======================================+ -| GIC-400 | on-chip | GICv2 interrupt controller | -+-----------+------------+--------------------------------------+ -| UART | on-chip | Mini uart serial port | -+-----------+------------+--------------------------------------+ +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - GIC-400 + - N/A + - :dtcompatible:`arm,gic-v2` + * - UART (Mini UART) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`brcm,bcm2711-aux-uart` Other hardware features have not been enabled yet for this board. From 58f8b7a07519785ea700e42d404f743b0727ce6a Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Tue, 3 Oct 2023 14:18:12 +0800 Subject: [PATCH 2498/4498] dts: arm64: bcm2711: Move `interrupt-parent` property to `soc {}` No reason to declare it per node, as it is almostly shared by all peripherals. Also introduced `DT_FREQ_M` macro for better readability. Signed-off-by: Chen Xingyu --- dts/arm64/broadcom/bcm2711.dtsi | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dts/arm64/broadcom/bcm2711.dtsi b/dts/arm64/broadcom/bcm2711.dtsi index 716e29006e7..dd577e289f0 100644 --- a/dts/arm64/broadcom/bcm2711.dtsi +++ b/dts/arm64/broadcom/bcm2711.dtsi @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + #include #include @@ -19,9 +22,10 @@ }; }; + interrupt-parent = <&gic>; + timer { compatible = "arm,armv8-timer"; - interrupt-parent = <&gic>; interrupts = , ; - clock-frequency = <500000000>; - interrupt-parent = <&gic>; + clock-frequency = ; interrupts = ; + IRQ_DEFAULT_PRIORITY>; status = "disabled"; }; }; From a2ef2f7605391706e1b6f7e3c1a3ab8ebc7845c5 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Fri, 29 Sep 2023 21:35:32 +0800 Subject: [PATCH 2499/4498] drivers: gpio: Add GPIO driver for BCM2711 The BCM2711 SoC exposes 58 GPIOs. The first 28 (bank 0) are accessible to users via the 40-pin header, while the others (bank 1) are used for controlling on-board peripherals. This also update doc of `rpi_4b` board. Signed-off-by: Chen Xingyu --- boards/arm64/rpi_4b/doc/index.rst | 3 + drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.bcm2711 | 9 + drivers/gpio/gpio_bcm2711.c | 355 +++++++++++++++++++++++ dts/arm64/broadcom/bcm2711.dtsi | 31 ++ dts/bindings/gpio/brcm,bcm2711-gpio.yaml | 22 ++ 7 files changed, 423 insertions(+) create mode 100644 drivers/gpio/Kconfig.bcm2711 create mode 100644 drivers/gpio/gpio_bcm2711.c create mode 100644 dts/bindings/gpio/brcm,bcm2711-gpio.yaml diff --git a/boards/arm64/rpi_4b/doc/index.rst b/boards/arm64/rpi_4b/doc/index.rst index 3a5cd625616..bae95e466d8 100644 --- a/boards/arm64/rpi_4b/doc/index.rst +++ b/boards/arm64/rpi_4b/doc/index.rst @@ -25,6 +25,9 @@ hardware features: * - GIC-400 - N/A - :dtcompatible:`arm,gic-v2` + * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`brcm,bcm2711-gpio` * - UART (Mini UART) - :kconfig:option:`CONFIG_SERIAL` - :dtcompatible:`brcm,bcm2711-aux-uart` diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index b168aa38a5e..a5974e20902 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -84,6 +84,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b008da0bd32..cce660403b4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -208,4 +208,6 @@ source "drivers/gpio/Kconfig.sedi" source "drivers/gpio/Kconfig.altera" +source "drivers/gpio/Kconfig.bcm2711" + endif # GPIO diff --git a/drivers/gpio/Kconfig.bcm2711 b/drivers/gpio/Kconfig.bcm2711 new file mode 100644 index 00000000000..ad7c3c11b13 --- /dev/null +++ b/drivers/gpio/Kconfig.bcm2711 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_BCM2711 + bool "BCM2711 GPIO driver" + default y + depends on DT_HAS_BRCM_BCM2711_GPIO_ENABLED + help + Enable BCM2711 GPIO driver. diff --git a/drivers/gpio/gpio_bcm2711.c b/drivers/gpio/gpio_bcm2711.c new file mode 100644 index 00000000000..a4e4a31e7c9 --- /dev/null +++ b/drivers/gpio/gpio_bcm2711.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2023 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT brcm_bcm2711_gpio + +#include +#include +#include +#include +#include + +#define GPIO_REG_GROUP(n, cnt) (n / cnt) +#define GPIO_REG_SHIFT(n, cnt, bits) ((n % cnt) * bits) + +#define GPFSEL(base, n) (base + 0x00 + 0x04 * n) +#define GPSET(base, n) (base + 0x1C + 0x04 * n) +#define GPCLR(base, n) (base + 0x28 + 0x04 * n) +#define GPLEV(base, n) (base + 0x34 + 0x04 * n) +#define GPEDS(base, n) (base + 0x40 + 0x04 * n) +#define GPREN(base, n) (base + 0x4C + 0x04 * n) +#define GPFEN(base, n) (base + 0x58 + 0x04 * n) +#define GPHEN(base, n) (base + 0x64 + 0x04 * n) +#define GPLEN(base, n) (base + 0x70 + 0x04 * n) +#define GPAREN(base, n) (base + 0x7C + 0x04 * n) +#define GPAFEN(base, n) (base + 0x88 + 0x04 * n) +#define GPPULL(base, n) (base + 0xE4 + 0x04 * n) + +#define FSEL_GROUPS (10) +#define FSEL_BITS (3) +#define FSEL_OUTPUT (0x1) + +#define IO_GROUPS (32) +#define IO_BITS (1) + +#define PULL_GROUPS (16) +#define PULL_BITS (2) +#define PULL_UP (0x1) +#define PULL_DOWN (0x2) + +#define DEV_CFG(dev) ((const struct gpio_bcm2711_config *const)(dev)->config) +#define DEV_DATA(dev) ((struct gpio_bcm2711_data *const)(dev)->data) + +#define RPI_PIN_NUM(dev, n) (DEV_CFG(dev)->offset + n) + +#define FROM_U64(val, idx) ((uint32_t)((val >> (idx * 32)) & UINT32_MAX)) + +struct gpio_bcm2711_config { + struct gpio_driver_config common; + + DEVICE_MMIO_NAMED_ROM(reg_base); + + void (*irq_config_func)(void); + + uint8_t offset; + uint8_t ngpios; +}; + +struct gpio_bcm2711_data { + struct gpio_driver_data common; + + DEVICE_MMIO_NAMED_RAM(reg_base); + mem_addr_t base; + + sys_slist_t cb; +}; + +static int gpio_bcm2711_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint32_t group; + uint32_t shift; + uint32_t regval; + + if (flags & GPIO_OPEN_DRAIN) { + return -ENOTSUP; + } + + /* Set direction */ + { + group = GPIO_REG_GROUP(RPI_PIN_NUM(port, pin), FSEL_GROUPS); + shift = GPIO_REG_SHIFT(RPI_PIN_NUM(port, pin), FSEL_GROUPS, FSEL_BITS); + + regval = sys_read32(GPFSEL(data->base, group)); + regval &= ~(BIT_MASK(FSEL_BITS) << shift); + if (flags & GPIO_OUTPUT) { + regval |= (FSEL_OUTPUT << shift); + } + sys_write32(regval, GPFSEL(data->base, group)); + } + + /* Set output level */ + if (flags & GPIO_OUTPUT) { + group = GPIO_REG_GROUP(RPI_PIN_NUM(port, pin), IO_GROUPS); + shift = GPIO_REG_SHIFT(RPI_PIN_NUM(port, pin), IO_GROUPS, IO_BITS); + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + regval = sys_read32(GPSET(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPSET(data->base, group)); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + regval = sys_read32(GPCLR(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPCLR(data->base, group)); + } + } + + /* Set pull */ + { + group = GPIO_REG_GROUP(RPI_PIN_NUM(port, pin), PULL_GROUPS); + shift = GPIO_REG_SHIFT(RPI_PIN_NUM(port, pin), PULL_GROUPS, PULL_BITS); + + regval = sys_read32(GPPULL(data->base, group)); + regval &= ~(BIT_MASK(PULL_BITS) << shift); + if (flags & GPIO_PULL_UP) { + regval |= (PULL_UP << shift); + } else if (flags & GPIO_PULL_DOWN) { + regval |= (PULL_DOWN << shift); + } + sys_write32(regval, GPPULL(data->base, group)); + } + + return 0; +} + +static int gpio_bcm2711_port_get_raw(const struct device *port, gpio_port_value_t *value) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval; + + regval = ((uint64_t)sys_read32(GPLEV(data->base, 0))) | + ((uint64_t)sys_read32(GPLEV(data->base, 1)) << 32); + + *value = (regval >> cfg->offset) & BIT_MASK(cfg->ngpios); + + return 0; +} + +static int gpio_bcm2711_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval, regmask; + uint64_t set, clr; + + value &= BIT_MASK(cfg->ngpios); + mask &= BIT_MASK(cfg->ngpios); + + regval = (uint64_t)value << cfg->offset; + regmask = (uint64_t)mask << cfg->offset; + + set = regval & regmask; + clr = regval ^ regmask; + + sys_write32(FROM_U64(set, 0), GPSET(data->base, 0)); + sys_write32(FROM_U64(clr, 0), GPCLR(data->base, 0)); + sys_write32(FROM_U64(set, 1), GPSET(data->base, 1)); + sys_write32(FROM_U64(clr, 1), GPCLR(data->base, 1)); + + return 0; +} + +static int gpio_bcm2711_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval; + + regval = ((uint64_t)pins & BIT_MASK(cfg->ngpios)) << cfg->offset; + + sys_write32(FROM_U64(regval, 0), GPSET(data->base, 0)); + sys_write32(FROM_U64(regval, 1), GPSET(data->base, 1)); + + return 0; +} + +static int gpio_bcm2711_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval; + + regval = ((uint64_t)pins & BIT_MASK(cfg->ngpios)) << cfg->offset; + + sys_write32(FROM_U64(regval, 0), GPCLR(data->base, 0)); + sys_write32(FROM_U64(regval, 1), GPCLR(data->base, 1)); + + return 0; +} + +static int gpio_bcm2711_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval, regmask; + uint64_t set, clr; + + regval = ((uint64_t)sys_read32(GPLEV(data->base, 0))) | + ((uint64_t)sys_read32(GPLEV(data->base, 1)) << 32); + + regmask = ((uint64_t)pins & BIT_MASK(cfg->ngpios)) << cfg->offset; + + set = regval ^ regmask; + clr = regval & regmask; + + sys_write32(FROM_U64(set, 0), GPSET(data->base, 0)); + sys_write32(FROM_U64(clr, 0), GPCLR(data->base, 0)); + sys_write32(FROM_U64(set, 1), GPSET(data->base, 1)); + sys_write32(FROM_U64(clr, 1), GPCLR(data->base, 1)); + + return 0; +} + +static int gpio_bcm2711_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint32_t group; + uint32_t shift; + uint32_t regval; + + group = GPIO_REG_GROUP(RPI_PIN_NUM(port, pin), IO_GROUPS); + shift = GPIO_REG_SHIFT(RPI_PIN_NUM(port, pin), IO_GROUPS, IO_BITS); + + /* Clear all detections first */ + + regval = sys_read32(GPREN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPREN(data->base, group)); + + regval = sys_read32(GPFEN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPFEN(data->base, group)); + + regval = sys_read32(GPHEN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPHEN(data->base, group)); + + regval = sys_read32(GPLEN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPLEN(data->base, group)); + + regval = sys_read32(GPAREN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPAREN(data->base, group)); + + regval = sys_read32(GPAFEN(data->base, group)); + regval &= ~BIT(shift); + sys_write32(regval, GPAFEN(data->base, group)); + + if (mode == GPIO_INT_MODE_LEVEL) { + if (trig & GPIO_INT_LOW_0) { + regval = sys_read32(GPLEN(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPLEN(data->base, group)); + } + if (trig & GPIO_INT_HIGH_1) { + regval = sys_read32(GPHEN(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPHEN(data->base, group)); + } + } else if (mode == GPIO_INT_MODE_EDGE) { + if (trig & GPIO_INT_LOW_0) { + regval = sys_read32(GPAFEN(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPAFEN(data->base, group)); + } + if (trig & GPIO_INT_HIGH_1) { + regval = sys_read32(GPAREN(data->base, group)); + regval |= BIT(shift); + sys_write32(regval, GPAREN(data->base, group)); + } + } + + return 0; +} + +static int gpio_bcm2711_manage_callback(const struct device *port, struct gpio_callback *cb, + bool set) +{ + struct gpio_bcm2711_data *data = DEV_DATA(port); + + return gpio_manage_callback(&data->cb, cb, set); +} + +static void gpio_bcm2711_isr(const struct device *port) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + uint64_t regval; + uint32_t pins; + + regval = ((uint64_t)sys_read32(GPEDS(data->base, 0))) | + ((uint64_t)sys_read32(GPEDS(data->base, 1)) << 32); + + regval &= BIT_MASK(cfg->ngpios) << cfg->offset; + + pins = (uint32_t)(regval >> cfg->offset); + gpio_fire_callbacks(&data->cb, port, pins); + + /* Write to clear */ + sys_write32(FROM_U64(regval, 0), GPEDS(data->base, 0)); + sys_write32(FROM_U64(regval, 1), GPEDS(data->base, 1)); +} + +int gpio_bcm2711_init(const struct device *port) +{ + const struct gpio_bcm2711_config *cfg = DEV_CFG(port); + struct gpio_bcm2711_data *data = DEV_DATA(port); + + DEVICE_MMIO_NAMED_MAP(port, reg_base, K_MEM_CACHE_NONE); + data->base = DEVICE_MMIO_NAMED_GET(port, reg_base); + + cfg->irq_config_func(); + + return 0; +} + +static const struct gpio_driver_api gpio_bcm2711_api = { + .pin_configure = gpio_bcm2711_pin_configure, + .port_get_raw = gpio_bcm2711_port_get_raw, + .port_set_masked_raw = gpio_bcm2711_port_set_masked_raw, + .port_set_bits_raw = gpio_bcm2711_port_set_bits_raw, + .port_clear_bits_raw = gpio_bcm2711_port_clear_bits_raw, + .port_toggle_bits = gpio_bcm2711_port_toggle_bits, + .pin_interrupt_configure = gpio_bcm2711_pin_interrupt_configure, + .manage_callback = gpio_bcm2711_manage_callback, +}; + +#define GPIO_BCM2711_INST(n) \ + static struct gpio_bcm2711_data gpio_bcm2711_data_##n; \ + \ + static void gpio_bcm2711_irq_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_bcm2711_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + static const struct gpio_bcm2711_config gpio_bcm2711_cfg_##n = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}, \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_INST_PARENT(n)), \ + .irq_config_func = gpio_bcm2711_irq_config_func_##n, \ + .offset = DT_INST_REG_ADDR(n), \ + .ngpios = DT_INST_PROP(n, ngpios), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_bcm2711_init, NULL, &gpio_bcm2711_data_##n, \ + &gpio_bcm2711_cfg_##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_bcm2711_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_BCM2711_INST) diff --git a/dts/arm64/broadcom/bcm2711.dtsi b/dts/arm64/broadcom/bcm2711.dtsi index dd577e289f0..038d8dc4d6c 100644 --- a/dts/arm64/broadcom/bcm2711.dtsi +++ b/dts/arm64/broadcom/bcm2711.dtsi @@ -52,6 +52,37 @@ status = "okay"; }; + gpio: gpio@fe200000 { + compatible = "simple-bus"; + reg = <0xfe200000 0xf4>; + #address-cells = <1>; + #size-cells = <0>; + + /* GPIO 0 ~ 27 */ + gpio0: gpio@0 { + compatible = "brcm,bcm2711-gpio"; + reg = <0>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <28>; + status = "disabled"; + }; + + /* GPIO 28 ~ 45 */ + gpio1: gpio@1c { + compatible = "brcm,bcm2711-gpio"; + reg = <28>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <18>; + status = "disabled"; + }; + }; + uart1: uart@fe215040 { compatible = "brcm,bcm2711-aux-uart"; reg = <0xfe215040 0x40>; diff --git a/dts/bindings/gpio/brcm,bcm2711-gpio.yaml b/dts/bindings/gpio/brcm,bcm2711-gpio.yaml new file mode 100644 index 00000000000..9237ee6dfc5 --- /dev/null +++ b/dts/bindings/gpio/brcm,bcm2711-gpio.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2023 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +description: BCM2711 GPIO + +compatible: "brcm,bcm2711-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags From 67390638478ac1ca091f95c2a62191fbc31c03a7 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Fri, 29 Sep 2023 20:46:16 +0800 Subject: [PATCH 2500/4498] boards: arm64: rpi_4b: Add DTS node for LED_ACT LED_ACT is the green LED at the top left corner of the RPi 4B board. Signed-off-by: Chen Xingyu --- boards/arm64/rpi_4b/rpi_4b.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/boards/arm64/rpi_4b/rpi_4b.dts b/boards/arm64/rpi_4b/rpi_4b.dts index 371ca3c09e8..e7e1faad435 100644 --- a/boards/arm64/rpi_4b/rpi_4b.dts +++ b/boards/arm64/rpi_4b/rpi_4b.dts @@ -7,17 +7,36 @@ /dts-v1/; #include +#include + / { model = "Raspberry Pi 4 Model B"; compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; #address-cells = <1>; #size-cells = <1>; + aliases { + led0 = &led_act; + }; + chosen { zephyr,console = &uart1; zephyr,shell-uart = &uart1; zephyr,sram = &sram0; }; + + leds { + compatible = "gpio-leds"; + + led_act: led-act { + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; /* GPIO 42 */ + label = "ACT"; + }; + }; +}; + +&gpio1 { + status = "okay"; }; &uart1 { From 03e2b6aee2a5ffce87079270269fac6dc4669215 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Mon, 16 Oct 2023 14:21:01 +0800 Subject: [PATCH 2501/4498] boards: arm64: rpi_4b: Update doc for programming with TF cards Rewrote with a more detailed procedure. Signed-off-by: Chen Xingyu --- boards/arm64/rpi_4b/doc/index.rst | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/boards/arm64/rpi_4b/doc/index.rst b/boards/arm64/rpi_4b/doc/index.rst index bae95e466d8..a3222f368b7 100644 --- a/boards/arm64/rpi_4b/doc/index.rst +++ b/boards/arm64/rpi_4b/doc/index.rst @@ -41,14 +41,31 @@ The default configuration can be found in the defconfig file: Programming and Debugging ************************* -Flashing -======== +TF Card +======= -1. Install Raspberry Pi OS using Raspberry Pi Imager. see . +Prepare a TF card with MBR and FAT32. In the root directory of the TF card: -2. Add `kernel=zephyr.bin` and `arm_64bit=1` in `config.txt`. see +1. Download and place these firmware files: -.. code-block:: console + * `bcm2711-rpi-4-b.dtb `_ + * `bootcode.bin `_ + * `start4.elf `_ - *** Booting Zephyr OS build XXXXXXXXXXXX *** - Hello World! Raspberry Pi 4 Model B! +2. Copy ``build/zephyr/zephyr.bin`` +3. Create a ``config.txt``: + + .. code-block:: text + + kernel=zephyr.bin + arm_64bit=1 + enable_uart=1 + uart_2ndstage=1 + +Insert the card and power on the board. You should see the following output on +the serial console (GPIO 14/15): + +.. code-block:: text + + *** Booting Zephyr OS build XXXXXXXXXXXX *** + Hello World! Raspberry Pi 4 Model B! From 7d9f2ad2caa09112949dba8d7a9ead87ca3a9e02 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 13 Sep 2023 15:09:28 +0300 Subject: [PATCH 2502/4498] net: sockets: Add object core support to sockets Use the generic object core support to track network sockets and their statistics. Signed-off-by: Jukka Rissanen --- include/zephyr/net/socket.h | 16 ++ subsys/net/ip/net_private.h | 18 ++ subsys/net/lib/sockets/CMakeLists.txt | 1 + subsys/net/lib/sockets/Kconfig | 11 + subsys/net/lib/sockets/socket_obj_core.c | 244 ++++++++++++++++++++++ subsys/net/lib/sockets/sockets.c | 63 ++++-- subsys/net/lib/sockets/sockets_internal.h | 52 +++++ 7 files changed, 390 insertions(+), 15 deletions(-) create mode 100644 subsys/net/lib/sockets/socket_obj_core.c diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index f12622e5df5..91f9193bbf8 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -1105,6 +1105,12 @@ struct net_socket_register { bool is_offloaded; bool (*is_supported)(int family, int type, int proto); int (*handler)(int family, int type, int proto); +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) + /* Store also the name of the socket type in order to be able to + * print it later. + */ + const char * const name; +#endif }; #define NET_SOCKET_DEFAULT_PRIO CONFIG_NET_SOCKETS_PRIORITY_DEFAULT @@ -1112,6 +1118,15 @@ struct net_socket_register { #define NET_SOCKET_GET_NAME(socket_name, prio) \ __net_socket_register_##prio##_##socket_name +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) +#define K_OBJ_TYPE_SOCK K_OBJ_TYPE_ID_GEN("SOCK") + +#define NET_SOCKET_REGISTER_NAME(_name) \ + .name = STRINGIFY(_name), +#else +#define NET_SOCKET_REGISTER_NAME(_name) +#endif + #define _NET_SOCKET_REGISTER(socket_name, prio, _family, _is_supported, _handler, _is_offloaded) \ static const STRUCT_SECTION_ITERABLE(net_socket_register, \ NET_SOCKET_GET_NAME(socket_name, prio)) = { \ @@ -1119,6 +1134,7 @@ struct net_socket_register { .is_offloaded = _is_offloaded, \ .is_supported = _is_supported, \ .handler = _handler, \ + NET_SOCKET_REGISTER_NAME(socket_name) \ } #define NET_SOCKET_REGISTER(socket_name, prio, _family, _is_supported, _handler) \ diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 64c206cb042..0906a7a28b1 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -141,7 +141,25 @@ static inline void net_coap_init(void) } #endif +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) +struct sock_obj_type_raw_stats { + uint64_t sent; + uint64_t received; +}; +struct sock_obj { + struct net_socket_register *reg; + uint64_t create_time; /* in ticks */ + k_tid_t creator; + int fd; + int socket_family; + int socket_type; + int socket_proto; + bool init_done; + struct k_obj_core obj_core; + struct sock_obj_type_raw_stats stats; +}; +#endif /* CONFIG_NET_SOCKETS_OBJ_CORE */ #if defined(CONFIG_NET_GPTP) /** diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 14f4f241183..2a87ef1c449 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -25,6 +25,7 @@ zephyr_sources_ifdef(CONFIG_NET_SOCKETS_PACKET sockets_packet.c) zephyr_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c) zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c) zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER socket_dispatcher.c) +zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OBJ_CORE socket_obj_core.c) if(CONFIG_NET_SOCKETS_NET_MGMT) zephyr_sources(sockets_net_mgmt.c) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 80f2e94ceec..b47fb91ab06 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -311,4 +311,15 @@ module-str = Log level for BSD sockets compatible API calls module-help = Enables logging for sockets code. source "subsys/net/Kconfig.template.log_config.net" +config NET_SOCKETS_OBJ_CORE + bool "Object core socket support [EXPERIMENTAL]" + depends on OBJ_CORE + select OBJ_CORE_STATS + select EXPERIMENTAL + help + Select this if you want to use object core with socket API to get + network socket information and statistics via object core. + The net-shell "net sockets" command will use this functionality + to show the socket information. + endif # NET_SOCKETS diff --git a/subsys/net/lib/sockets/socket_obj_core.c b/subsys/net/lib/sockets/socket_obj_core.c new file mode 100644 index 00000000000..4133c5cef2e --- /dev/null +++ b/subsys/net/lib/sockets/socket_obj_core.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Object core support for sockets */ + +#include +LOG_MODULE_DECLARE(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include + +#include "sockets_internal.h" +#include "../../ip/net_private.h" + +static struct k_obj_type sock_obj_type; +static K_MUTEX_DEFINE(sock_obj_mutex); + +/* Allocate some extra socket objects so that we can track + * closed sockets and get some historical statistics. + */ +static struct sock_obj sock_objects[CONFIG_POSIX_MAX_FDS * 2] = { + [0 ... ((CONFIG_POSIX_MAX_FDS * 2) - 1)] = { + .fd = -1, + .init_done = false, + } +}; + +static void sock_obj_core_init_and_link(struct sock_obj *sock); +static int sock_obj_core_stats_reset(struct k_obj_core *obj); +static int sock_obj_stats_raw(struct k_obj_core *obj_core, void *stats); +static int sock_obj_core_get_reg_and_proto(int sock, + struct net_socket_register **reg); + +struct k_obj_core_stats_desc sock_obj_type_stats_desc = { + .raw_size = sizeof(struct sock_obj_type_raw_stats), + .raw = sock_obj_stats_raw, + .reset = sock_obj_core_stats_reset, + .disable = NULL, /* Stats gathering is always on */ + .enable = NULL, /* Stats gathering is always on */ +}; + +static void set_fields(struct sock_obj *obj, int fd, + struct net_socket_register *reg, + int family, int type, int proto) +{ + obj->fd = fd; + obj->socket_family = family; + obj->socket_type = type; + obj->socket_proto = proto; + obj->reg = reg; + obj->creator = k_current_get(); + obj->create_time = sys_clock_tick_get(); +} + +static void sock_obj_core_init_and_link(struct sock_obj *sock) +{ + static bool type_init_done; + + if (!type_init_done) { + z_obj_type_init(&sock_obj_type, K_OBJ_TYPE_SOCK, + offsetof(struct sock_obj, obj_core)); + k_obj_type_stats_init(&sock_obj_type, &sock_obj_type_stats_desc); + + type_init_done = true; + } + + k_obj_core_init_and_link(K_OBJ_CORE(sock), &sock_obj_type); + k_obj_core_stats_register(K_OBJ_CORE(sock), &sock->stats, + sizeof(struct sock_obj_type_raw_stats)); + + /* If the socket was closed and we re-opened it again, then clear + * the statistics. + */ + if (sock->init_done) { + k_obj_core_stats_reset(K_OBJ_CORE(sock)); + } + + sock->init_done = true; +} + +static int sock_obj_stats_raw(struct k_obj_core *obj_core, void *stats) +{ + memcpy(stats, obj_core->stats, sizeof(struct sock_obj_type_raw_stats)); + + return 0; +} + +static int sock_obj_core_stats_reset(struct k_obj_core *obj_core) +{ + memset(obj_core->stats, 0, sizeof(struct sock_obj_type_raw_stats)); + + return 0; +} + +static int sock_obj_core_get_reg_and_proto(int sock, struct net_socket_register **reg) +{ + int i, ret; + + k_mutex_lock(&sock_obj_mutex, K_FOREVER); + + for (i = 0; i < ARRAY_SIZE(sock_objects); i++) { + if (sock_objects[i].fd == sock) { + *reg = sock_objects[i].reg; + ret = sock_objects[i].socket_proto; + goto out; + } + } + + ret = -ENOENT; + +out: + k_mutex_unlock(&sock_obj_mutex); + + return ret; +} + +int sock_obj_core_alloc(int sock, struct net_socket_register *reg, + int family, int type, int proto) +{ + struct sock_obj *obj = NULL; + int ret, i; + + if (sock < 0) { + return -EINVAL; + } + + k_mutex_lock(&sock_obj_mutex, K_FOREVER); + + /* Try not to allocate already closed sockets so that we + * can see historical data. + */ + for (i = 0; i < ARRAY_SIZE(sock_objects); i++) { + if (sock_objects[i].fd < 0) { + if (sock_objects[i].init_done == false) { + obj = &sock_objects[i]; + break; + } else if (obj == NULL) { + obj = &sock_objects[i]; + } + } + } + + if (obj == NULL) { + ret = -ENOENT; + goto out; + } + + set_fields(obj, sock, reg, family, type, proto); + sock_obj_core_init_and_link(obj); + + ret = 0; + +out: + k_mutex_unlock(&sock_obj_mutex); + + return ret; +} + +int sock_obj_core_alloc_find(int sock, int new_sock, int family, int type) +{ + struct net_socket_register *reg = NULL; + int ret; + + if (new_sock < 0) { + return -EINVAL; + } + + ret = sock_obj_core_get_reg_and_proto(sock, ®); + if (ret < 0) { + goto out; + } + + ret = sock_obj_core_alloc(new_sock, reg, family, type, ret); + if (ret < 0) { + NET_ERR("Cannot allocate core object for socket %d (%d)", + new_sock, ret); + } + +out: + return ret; +} + +int sock_obj_core_dealloc(int fd) +{ + int ret; + + k_mutex_lock(&sock_obj_mutex, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(sock_objects); i++) { + if (sock_objects[i].fd == fd) { + sock_objects[i].fd = -1; + + /* Calculate the lifetime of the socket so that + * net-shell can print it for the closed sockets. + */ + sock_objects[i].create_time = + k_ticks_to_ms_ceil32(sys_clock_tick_get() - + sock_objects[i].create_time); + ret = 0; + goto out; + } + } + + ret = -ENOENT; + +out: + k_mutex_unlock(&sock_obj_mutex); + + return ret; +} + +void sock_obj_core_update_send_stats(int fd, int bytes) +{ + if (bytes > 0) { + k_mutex_lock(&sock_obj_mutex, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(sock_objects); i++) { + if (sock_objects[i].fd == fd) { + sock_objects[i].stats.sent += bytes; + break; + } + } + + k_mutex_unlock(&sock_obj_mutex); + } +} + +void sock_obj_core_update_recv_stats(int fd, int bytes) +{ + if (bytes > 0) { + k_mutex_lock(&sock_obj_mutex, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(sock_objects); i++) { + if (sock_objects[i].fd == fd) { + sock_objects[i].stats.received += bytes; + break; + } + } + + k_mutex_unlock(&sock_obj_mutex); + } +} diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 2ad891139ae..ba59cc98d9e 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -33,12 +33,13 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "sockets_internal.h" #include "../../ip/tcp_internal.h" +#include "../../ip/net_private.h" #define SET_ERRNO(x) \ { int _err = x; if (_err < 0) { errno = -_err; return -1; } } #define VTABLE_CALL(fn, sock, ...) \ - do { \ + ({ \ const struct socket_op_vtable *vtable; \ struct k_mutex *lock; \ void *obj; \ @@ -61,8 +62,8 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); \ k_mutex_unlock(lock); \ \ - return ret; \ - } while (0) + ret; \ + }) const struct socket_op_vtable sock_fd_op_vtable; @@ -217,6 +218,8 @@ static int zsock_socket_internal(int family, int type, int proto) int z_impl_zsock_socket(int family, int type, int proto) { STRUCT_SECTION_FOREACH(net_socket_register, sock_family) { + int ret; + if (sock_family->family != family && sock_family->family != AF_UNSPEC) { continue; @@ -228,7 +231,11 @@ int z_impl_zsock_socket(int family, int type, int proto) continue; } - return sock_family->handler(family, type, proto); + ret = sock_family->handler(family, type, proto); + + (void)sock_obj_core_alloc(ret, sock_family, family, type, proto); + + return ret; } errno = EAFNOSUPPORT; @@ -292,6 +299,8 @@ int z_impl_zsock_close(int sock) z_free_fd(sock); + (void)sock_obj_core_dealloc(sock); + return ret; } @@ -464,7 +473,7 @@ int zsock_bind_ctx(struct net_context *ctx, const struct sockaddr *addr, int z_impl_zsock_bind(int sock, const struct sockaddr *addr, socklen_t addrlen) { - VTABLE_CALL(bind, sock, addr, addrlen); + return VTABLE_CALL(bind, sock, addr, addrlen); } #ifdef CONFIG_USERSPACE @@ -543,7 +552,7 @@ int zsock_connect_ctx(struct net_context *ctx, const struct sockaddr *addr, int z_impl_zsock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen) { - VTABLE_CALL(connect, sock, addr, addrlen); + return VTABLE_CALL(connect, sock, addr, addrlen); } #ifdef CONFIG_USERSPACE @@ -571,7 +580,7 @@ int zsock_listen_ctx(struct net_context *ctx, int backlog) int z_impl_zsock_listen(int sock, int backlog) { - VTABLE_CALL(listen, sock, backlog); + return VTABLE_CALL(listen, sock, backlog); } #ifdef CONFIG_USERSPACE @@ -668,7 +677,13 @@ int zsock_accept_ctx(struct net_context *parent, struct sockaddr *addr, int z_impl_zsock_accept(int sock, struct sockaddr *addr, socklen_t *addrlen) { - VTABLE_CALL(accept, sock, addr, addrlen); + int new_sock; + + new_sock = VTABLE_CALL(accept, sock, addr, addrlen); + + (void)sock_obj_core_alloc_find(sock, new_sock, addr->sa_family, SOCK_STREAM); + + return new_sock; } #ifdef CONFIG_USERSPACE @@ -832,7 +847,13 @@ ssize_t zsock_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, ssize_t z_impl_zsock_sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { - VTABLE_CALL(sendto, sock, buf, len, flags, dest_addr, addrlen); + int ret; + + ret = VTABLE_CALL(sendto, sock, buf, len, flags, dest_addr, addrlen); + + sock_obj_core_update_send_stats(sock, ret); + + return ret; } #ifdef CONFIG_USERSPACE @@ -911,7 +932,13 @@ ssize_t zsock_sendmsg_ctx(struct net_context *ctx, const struct msghdr *msg, ssize_t z_impl_zsock_sendmsg(int sock, const struct msghdr *msg, int flags) { - VTABLE_CALL(sendmsg, sock, msg, flags); + int ret; + + ret = VTABLE_CALL(sendmsg, sock, msg, flags); + + sock_obj_core_update_send_stats(sock, ret); + + return ret; } #ifdef CONFIG_USERSPACE @@ -1471,7 +1498,13 @@ ssize_t zsock_recvfrom_ctx(struct net_context *ctx, void *buf, size_t max_len, ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { - VTABLE_CALL(recvfrom, sock, buf, max_len, flags, src_addr, addrlen); + int ret; + + ret = VTABLE_CALL(recvfrom, sock, buf, max_len, flags, src_addr, addrlen); + + sock_obj_core_update_recv_stats(sock, ret); + + return ret; } #ifdef CONFIG_USERSPACE @@ -2124,7 +2157,7 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname, int z_impl_zsock_getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen) { - VTABLE_CALL(getsockopt, sock, level, optname, optval, optlen); + return VTABLE_CALL(getsockopt, sock, level, optname, optval, optlen); } #ifdef CONFIG_USERSPACE @@ -2474,7 +2507,7 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, int z_impl_zsock_setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen) { - VTABLE_CALL(setsockopt, sock, level, optname, optval, optlen); + return VTABLE_CALL(setsockopt, sock, level, optname, optval, optlen); } #ifdef CONFIG_USERSPACE @@ -2548,7 +2581,7 @@ int zsock_getpeername_ctx(struct net_context *ctx, struct sockaddr *addr, int z_impl_zsock_getpeername(int sock, struct sockaddr *addr, socklen_t *addrlen) { - VTABLE_CALL(getpeername, sock, addr, addrlen); + return VTABLE_CALL(getpeername, sock, addr, addrlen); } #ifdef CONFIG_USERSPACE @@ -2627,7 +2660,7 @@ int zsock_getsockname_ctx(struct net_context *ctx, struct sockaddr *addr, int z_impl_zsock_getsockname(int sock, struct sockaddr *addr, socklen_t *addrlen) { - VTABLE_CALL(getsockname, sock, addr, addrlen); + return VTABLE_CALL(getsockname, sock, addr, addrlen); } #ifdef CONFIG_USERSPACE diff --git a/subsys/net/lib/sockets/sockets_internal.h b/subsys/net/lib/sockets/sockets_internal.h index 12bf1f518e3..9398608b4d0 100644 --- a/subsys/net/lib/sockets/sockets_internal.h +++ b/subsys/net/lib/sockets/sockets_internal.h @@ -78,4 +78,56 @@ struct socket_op_vtable { size_t msghdr_non_empty_iov_count(const struct msghdr *msg); +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) +int sock_obj_core_alloc(int sock, struct net_socket_register *reg, + int family, int type, int proto); +int sock_obj_core_alloc_find(int sock, int new_sock, int family, int type); +int sock_obj_core_dealloc(int sock); +void sock_obj_core_update_send_stats(int sock, int bytes); +void sock_obj_core_update_recv_stats(int sock, int bytes); +#else +static inline int sock_obj_core_alloc(int sock, + struct net_socket_register *reg, + int family, int type, int proto) +{ + ARG_UNUSED(sock); + ARG_UNUSED(reg); + ARG_UNUSED(family); + ARG_UNUSED(type); + ARG_UNUSED(proto); + + return -ENOTSUP; +} + +static inline int sock_obj_core_alloc_find(int sock, int new_sock, + int family, int type) +{ + ARG_UNUSED(sock); + ARG_UNUSED(new_sock); + ARG_UNUSED(family); + ARG_UNUSED(type); + + return -ENOTSUP; +} + +static inline int sock_obj_core_dealloc(int sock) +{ + ARG_UNUSED(sock); + + return -ENOTSUP; +} + +static inline void sock_obj_core_update_send_stats(int sock, int bytes) +{ + ARG_UNUSED(sock); + ARG_UNUSED(bytes); +} + +static inline void sock_obj_core_update_recv_stats(int sock, int bytes) +{ + ARG_UNUSED(sock); + ARG_UNUSED(bytes); +} +#endif /* CONFIG_NET_SOCKETS_OBJ_CORE */ + #endif /* _SOCKETS_INTERNAL_H_ */ From 8a581043965e05e5663afe7f078bd760452697a2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 13 Sep 2023 15:10:50 +0300 Subject: [PATCH 2503/4498] net: shell: Add net-sockets command The new "net sockets" command will utilize the object core support to track and show information about BSD sockets that are created in the system. This command is able to show info for all network sockets (native, offloaded etc) in the system. Example of the output of the new command: uart:~$ net sockets Creator Name Flags FD Lifetime (ms) Sent Received main af_inet46 6ST 0 3260 819 498 main af_inet46 4ST 1 2110 469 142 main af_inet46 6DU 2 2110 9941 9941 main af_inet46 4DU 3 2110 1375 621 4 active sockets found. Signed-off-by: Jukka Rissanen --- doc/connectivity/networking/api/net_shell.rst | 3 + subsys/net/lib/shell/CMakeLists.txt | 1 + subsys/net/lib/shell/sockets.c | 130 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 subsys/net/lib/shell/sockets.c diff --git a/doc/connectivity/networking/api/net_shell.rst b/doc/connectivity/networking/api/net_shell.rst index cf51291d0c9..710b544eb7b 100644 --- a/doc/connectivity/networking/api/net_shell.rst +++ b/doc/connectivity/networking/api/net_shell.rst @@ -38,6 +38,9 @@ The following net-shell commands are implemented: "net ping", "Ping a network host." "net route", "Show IPv6 network routes. Only available if :kconfig:option:`CONFIG_NET_ROUTE` is set." + "net sockets", "Show network socket information and statistics. Only available if + :kconfig:option:`CONFIG_NET_SOCKETS_OBJ_CORE` and :kconfig:option:`CONFIG_OBJ_CORE` + are set." "net stats", "Show network statistics." "net tcp", "Connect/send data/close TCP connection. Only available if :kconfig:option:`CONFIG_NET_TCP` is set." diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index ddf2b3c93fa..2c5c0757505 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -23,6 +23,7 @@ zephyr_library_sources(pkt.c) zephyr_library_sources(ppp.c) zephyr_library_sources(resume.c) zephyr_library_sources(route.c) +zephyr_library_sources(sockets.c) zephyr_library_sources(stats.c) zephyr_library_sources(suspend.c) zephyr_library_sources(tcp.c) diff --git a/subsys/net/lib/shell/sockets.c b/subsys/net/lib/shell/sockets.c new file mode 100644 index 00000000000..792e34efc21 --- /dev/null +++ b/subsys/net/lib/shell/sockets.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include "common.h" +#include + +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) +struct socket_info { + int opened; + int closed; +}; + +int walk_sockets(struct k_obj_core *obj_core, void *user_data) +{ +#if defined(CONFIG_THREAD_NAME) +#define THREAD_NAME_LEN CONFIG_THREAD_MAX_NAME_LEN +#else +#define THREAD_NAME_LEN 16 +#endif + struct sock_obj_type_raw_stats stats = { 0 }; + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct socket_info *count = data->user_data; + char thread_name[THREAD_NAME_LEN + 1]; + char fd[5] = { 0 }; + struct sock_obj *obj; + int lifetime; + int ret; + + obj = CONTAINER_OF(obj_core, struct sock_obj, obj_core); + + if (k_thread_name_copy(obj->creator, thread_name, + sizeof(thread_name) - 1) < 0) { + snprintk(thread_name, sizeof(thread_name) - 1, "%p", + obj->creator); + } + + thread_name[sizeof(thread_name) - 1] = '\0'; + + ret = k_obj_core_stats_raw(K_OBJ_CORE(obj), + &stats, sizeof(stats)); + if (ret != 0) { + PR_INFO("Failed to get statistics (%d)\n", ret); + } + + if (obj->fd < 0) { + /* Already closed socket. The create time contains the + * actual lifetime as calculated in close() + */ + lifetime = obj->create_time; + strncat(fd, "C", 1); + count->closed++; + } else { + lifetime = k_ticks_to_ms_ceil32(sys_clock_tick_get() - + obj->create_time); + snprintk(fd, sizeof(fd), "%d", obj->fd); + count->opened++; + } + + PR("%16s %-12s %c%c%c\t%-5s%-13d %-10" PRId64 "%-10" PRId64 "\n", + thread_name, obj->reg->name, + obj->socket_family == AF_INET6 ? '6' : + (obj->socket_family ? '4' : ' '), + obj->socket_type == SOCK_DGRAM ? 'D' : + (obj->socket_type == SOCK_STREAM ? 'S' : + (obj->socket_type == SOCK_RAW ? 'R' : ' ')), + obj->socket_proto == IPPROTO_UDP ? 'U' : + (obj->socket_proto == IPPROTO_TCP ? 'T' : ' '), + fd, lifetime, stats.sent, stats.received); + + return 0; +} +#endif /* CONFIG_NET_SOCKETS_OBJ_CORE */ + +static int cmd_net_sockets(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_SOCKETS_OBJ_CORE) + struct net_shell_user_data user_data; + struct k_obj_type *obj_type; + struct socket_info count = { 0 }; + + user_data.sh = sh; + user_data.user_data = &count; + + PR("%16s %-12s %-5s\t%-5s%-14s %-10s%-10s\n", + "Creator", "Name", "Flags", "FD", "Lifetime (ms)", "Sent", + "Received"); + PR("\n"); + + obj_type = k_obj_type_find(K_OBJ_TYPE_SOCK); + k_obj_type_walk_unlocked(obj_type, walk_sockets, (void *)&user_data); + + if (count.opened == 0 && count.closed == 0) { + PR("No sockets found.\n"); + } else { + if (count.opened > 0) { + PR("\n%d active socket%s found.\n", count.opened, + count.opened == 1 ? "" : "s"); + } + + if (count.closed > 0) { + if (count.opened == 0) { + PR("\n"); + } + + PR("%d closed socket%s found.\n", count.closed, + count.closed == 1 ? "" : "s"); + } + } +#else + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_OBJ_CORE and CONFIG_NET_SOCKETS_OBJ_CORE", + "socket information"); +#endif + + return 0; +} + +SHELL_SUBCMD_ADD((net), sockets, NULL, + "Show network sockets.", + cmd_net_sockets, 1, 0); From ec978348c5ea8e5a2a0f071cc6e6ca8e12fa8889 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 3 Oct 2023 16:04:43 +0200 Subject: [PATCH 2504/4498] manifest: hal_nordic: Update hal_nordic revision Pull in nrfx 3.2.0 release Signed-off-by: Nikodem Kastelik --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 868570bb833..a77d85c40ff 100644 --- a/west.yml +++ b/west.yml @@ -186,7 +186,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 275548e2dca9e855a134d67f82375ba17b285b5d + revision: 2ff8ce6e6ca131d87699dba260f3c0cc4a6cc365 path: modules/hal/nordic groups: - hal From f4fcc1dc4c6303b21b7fb8c3f2a346aeef8ebcaf Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 3 Oct 2023 17:17:22 +0200 Subject: [PATCH 2505/4498] manifest: tf-m: update revision to have atomics defined for nrfx port Refactored nrfx_uarte driver uses atomic types internally, so glue layer in TF-M needs to include them. Signed-off-by: Nikodem Kastelik --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a77d85c40ff..50fee2aae60 100644 --- a/west.yml +++ b/west.yml @@ -321,7 +321,7 @@ manifest: groups: - crypto - name: trusted-firmware-m - revision: 696b09568c6b30cbcbe5b8764f703c90a48825eb + revision: 33c0f47bcb19721a5c33e6fe1eee9225d00bb5bc path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 6a315a4b17c523f101a01fccde50967c02294650 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 3 Oct 2023 16:52:55 +0200 Subject: [PATCH 2506/4498] drivers: sensor: qdec_nrfx: Revert spurious samplerdy evt workaround Underlying nrfx driver was modified so now it forwards the event to the user callback only if it was enabled. Signed-off-by: Nikodem Kastelik --- drivers/sensor/qdec_nrfx/qdec_nrfx.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/sensor/qdec_nrfx/qdec_nrfx.c b/drivers/sensor/qdec_nrfx/qdec_nrfx.c index 81c3614fc05..b11ce70fb9c 100644 --- a/drivers/sensor/qdec_nrfx/qdec_nrfx.c +++ b/drivers/sensor/qdec_nrfx/qdec_nrfx.c @@ -135,13 +135,6 @@ static void qdec_nrfx_event_handler(nrfx_qdec_event_t event, void *p_context) unsigned int key; switch (event.type) { - case NRF_QDEC_EVENT_SAMPLERDY: - /* The underlying HAL driver may improperly forward an samplerdy event even if it's - * disabled in the configuration. Ignore the event to prevent error logs until the - * issue is fixed in HAL. - */ - break; - case NRF_QDEC_EVENT_REPORTRDY: accumulate(dev_data, event.data.report.acc); From f3f2c113d1323fa0a82d30a9f1cb957b87fd185a Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 3 Oct 2023 16:59:20 +0200 Subject: [PATCH 2507/4498] soc: arm: nordic_nrf: nrf53: align nrf_regulators calls to new scheme Now more generic regulators API is available. Signed-off-by: Nikodem Kastelik --- soc/arm/nordic_nrf/nrf53/soc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 39d64d72cc2..3542ef3e914 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -554,13 +554,13 @@ static int nordicsemi_nrf53_init(void) #endif #if defined(CONFIG_SOC_DCDC_NRF53X_APP) - nrf_regulators_dcdcen_set(NRF_REGULATORS, true); + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MAIN, true); #endif #if defined(CONFIG_SOC_DCDC_NRF53X_NET) - nrf_regulators_dcdcen_radio_set(NRF_REGULATORS, true); + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_RADIO, true); #endif #if defined(CONFIG_SOC_DCDC_NRF53X_HV) - nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS, true); + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_HIGH, true); #endif #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) From c0ff691a3ca66a6eae56e7d03c2382f27e4b0281 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 3 Oct 2023 17:00:20 +0200 Subject: [PATCH 2508/4498] samples: boards: nrf: nrfx_prs: align to new nrfx_uarte struct member One of the nrfx_uarte event structure members was renamed, so the sample code has to be aligned. Signed-off-by: Nikodem Kastelik --- samples/boards/nrf/nrfx_prs/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/nrf/nrfx_prs/src/main.c b/samples/boards/nrf/nrfx_prs/src/main.c index 618c0718143..934bbbe834d 100644 --- a/samples/boards/nrf/nrfx_prs/src/main.c +++ b/samples/boards/nrf/nrfx_prs/src/main.c @@ -191,7 +191,7 @@ static bool spim_transfer(const uint8_t *tx_data, size_t tx_data_len, static void uarte_handler(const nrfx_uarte_event_t *p_event, void *p_context) { if (p_event->type == NRFX_UARTE_EVT_RX_DONE) { - received = p_event->data.rx.bytes; + received = p_event->data.rx.length; k_sem_give(&transfer_finished); } else if (p_event->type == NRFX_UARTE_EVT_ERROR) { received = 0; From 70db8cd12a794fa6f966c1e08a622ad5590a6880 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Fri, 6 Oct 2023 09:55:58 +0200 Subject: [PATCH 2509/4498] modules: hal_nordic: nrfx: enable NRFX_GPIOTE1 for non-secure builds Now it is needed to explicitly use NRF_GPIOTE1 instance in nrfx_gpiote driver for non-secure builds. Signed-off-by: Nikodem Kastelik --- modules/hal_nordic/nrfx/nrfx_config.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 3236daa12b4..ce4a6214f7d 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -117,6 +117,12 @@ #ifdef CONFIG_NRFX_GPIOTE #define NRFX_GPIOTE_ENABLED 1 +#if (defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_SERIES_NRF53X)) \ + && defined(NRF_TRUSTZONE_NONSECURE) +#define NRFX_GPIOTE1_ENABLED 1 +#else +#define NRFX_GPIOTE0_ENABLED 1 +#endif #endif #ifdef CONFIG_NRFX_GPIOTE_LOG #define NRFX_GPIOTE_CONFIG_LOG_ENABLED 1 From a4cbe9e9c6f9efe37dcca13083b040172205a716 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Mon, 9 Oct 2023 11:18:17 +0200 Subject: [PATCH 2510/4498] soc: arm: nordic_nrf: align nrf_power calls to new scheme Now the API to manage GPREGRET register is unified for all devices having one or more GPREGRET entries. Signed-off-by: Nikodem Kastelik --- soc/arm/nordic_nrf/nrf51/soc.c | 2 +- soc/arm/nordic_nrf/nrf52/soc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf51/soc.c b/soc/arm/nordic_nrf/nrf51/soc.c index 078a422c06b..2b22c95679f 100644 --- a/soc/arm/nordic_nrf/nrf51/soc.c +++ b/soc/arm/nordic_nrf/nrf51/soc.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(soc); */ void sys_arch_reboot(int type) { - nrf_power_gpregret_set(NRF_POWER, (uint8_t)type); + nrf_power_gpregret_set(NRF_POWER, 0, (uint8_t)type); NVIC_SystemReset(); } #endif diff --git a/soc/arm/nordic_nrf/nrf52/soc.c b/soc/arm/nordic_nrf/nrf52/soc.c index 52b97164e72..5f310e5f945 100644 --- a/soc/arm/nordic_nrf/nrf52/soc.c +++ b/soc/arm/nordic_nrf/nrf52/soc.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(soc); */ void sys_arch_reboot(int type) { - nrf_power_gpregret_set(NRF_POWER, (uint8_t)type); + nrf_power_gpregret_set(NRF_POWER, 0, (uint8_t)type); NVIC_SystemReset(); } #endif From 12c8d11ee5c815425c9b36b2e4e981133d257614 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 23 Oct 2023 11:24:39 +0200 Subject: [PATCH 2511/4498] cmake: extra_flags: Use zephyr_get This allows users to set `EXTRA_*FLAGS` variables when using sysbuild. If these flags are provided in both local and global sysbuild scopes, then only the local ones will be used for a given image. This is to circumvent issues with mixing space-separated and `;`-separated lists. Signed-off-by: Grzegorz Swiderski --- cmake/extra_flags.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/extra_flags.cmake b/cmake/extra_flags.cmake index 2e41720991d..138262afb1f 100644 --- a/cmake/extra_flags.cmake +++ b/cmake/extra_flags.cmake @@ -1,6 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 foreach(extra_flags EXTRA_CPPFLAGS EXTRA_LDFLAGS EXTRA_CFLAGS EXTRA_CXXFLAGS EXTRA_AFLAGS) + # Note: zephyr_get MERGE should not be used until issue #43959 is resolved. + zephyr_get(${extra_flags}) list(LENGTH ${extra_flags} flags_length) if(flags_length LESS_EQUAL 1) # A length of zero means no argument. From 312c8b193060767be3e8297baf1ea2132065a9be Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 20 Oct 2023 00:21:18 +0200 Subject: [PATCH 2512/4498] soc: sam: Add SUPC driver and dts model This commit adds a driver and dts model for the ATMEL SAM SUPC component. Signed-off-by: Bjarki Arge Andreasen --- dts/bindings/power/atmel,sam-supc.yaml | 47 +++++++++++++++++++ include/zephyr/drivers/power/atmel_sam_supc.h | 18 +++++++ .../zephyr/dt-bindings/power/atmel_sam_supc.h | 15 ++++++ soc/arm/atmel_sam/common/CMakeLists.txt | 1 + soc/arm/atmel_sam/common/soc_supc.c | 32 +++++++++++++ soc/arm/atmel_sam/common/soc_supc.h | 26 ++++++++++ soc/arm/atmel_sam/sam3x/soc.h | 1 + soc/arm/atmel_sam/sam4e/soc.h | 1 + soc/arm/atmel_sam/sam4s/soc.h | 1 + soc/arm/atmel_sam/same70/soc.h | 1 + soc/arm/atmel_sam/samv71/soc.h | 1 + 11 files changed, 144 insertions(+) create mode 100644 dts/bindings/power/atmel,sam-supc.yaml create mode 100644 include/zephyr/drivers/power/atmel_sam_supc.h create mode 100644 include/zephyr/dt-bindings/power/atmel_sam_supc.h create mode 100644 soc/arm/atmel_sam/common/soc_supc.c create mode 100644 soc/arm/atmel_sam/common/soc_supc.h diff --git a/dts/bindings/power/atmel,sam-supc.yaml b/dts/bindings/power/atmel,sam-supc.yaml new file mode 100644 index 00000000000..fdba03f87cf --- /dev/null +++ b/dts/bindings/power/atmel,sam-supc.yaml @@ -0,0 +1,47 @@ +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: | + Atmel SAM SUPC (Supply-Controller) controller + + The supply controller manages the voltage reference, power supply and supply + monitoring of the device. It have a special feature that it can wake-up the + device from a low-power state using special peripherals as wake-up sources. + + The dedicated peripherals that can wake-up the core supply domain are: RTC, + RTT, Supply Monitor and GPIOs. In the first three peripherals it is necessary + inform the wakeup-source-id property on their respective nodes. + + rtc: rtc@xxx { + ... + wakeup-source-id = <&supc SUPC_WAKEUP_SOURCE_RTC>; + ... + }; + + The special peripheral will wake-up the device only when the standard property + wakeup-source is defined, e.g.: + + &rtc { + ... + wakeup-source; + ... + }; + + The SUPC wakeup source ids that can be enabled are defined in the + zephyr/include/zephyr/dt-bindings/power/atmel_sam_supc.h header file. + +compatible: "atmel,sam-supc" + +include: + - name: base.yaml + +properties: + reg: + required: true + + "#wakeup-source-id-cells": + type: int + const: 1 + +wakeup-source-id-cells: + - wakeup-source-id diff --git a/include/zephyr/drivers/power/atmel_sam_supc.h b/include/zephyr/drivers/power/atmel_sam_supc.h new file mode 100644 index 00000000000..e31e3d7565f --- /dev/null +++ b/include/zephyr/drivers/power/atmel_sam_supc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ + +#define SAM_DT_SUPC_CONTROLLER DEVICE_DT_GET(DT_NODELABEL(supc)) + +#define SAM_DT_SUPC_WAKEUP_SOURCE_ID(node_id) \ + DT_PROP_BY_IDX(node_id, wakeup_source_id wakeup_source_id) + +#define SAM_DT_INST_SUPC_WAKEUP_SOURCE_ID(inst) \ + SAM_DT_SUPC_WAKEUP_SOURCE_ID(DT_DRV_INST(inst)) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ */ diff --git a/include/zephyr/dt-bindings/power/atmel_sam_supc.h b/include/zephyr/dt-bindings/power/atmel_sam_supc.h new file mode 100644 index 00000000000..547a97ef704 --- /dev/null +++ b/include/zephyr/dt-bindings/power/atmel_sam_supc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ + +#define SUPC_WAKEUP_SOURCE_FWUP 0 +#define SUPC_WAKEUP_SOURCE_SM 1 +#define SUPC_WAKEUP_SOURCE_RTT 2 +#define SUPC_WAKEUP_SOURCE_RTC 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ */ diff --git a/soc/arm/atmel_sam/common/CMakeLists.txt b/soc/arm/atmel_sam/common/CMakeLists.txt index 7b57af36217..0c8602d1a35 100644 --- a/soc/arm/atmel_sam/common/CMakeLists.txt +++ b/soc/arm/atmel_sam/common/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_include_directories(.) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_pmc.c) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_gpio.c) +zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_supc.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_pm.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_gpio.c) diff --git a/soc/arm/atmel_sam/common/soc_supc.c b/soc/arm/atmel_sam/common/soc_supc.c new file mode 100644 index 00000000000..cf6ce80ab2c --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_supc.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define SOC_SUPC_WAKEUP_SOURCE_IDS (3) + +void soc_supc_core_voltage_regulator_off(void) +{ + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; +} + +void soc_supc_slow_clock_select_crystal_osc(void) +{ + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL; + + /* Wait for oscillator to be stabilized. */ + while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL)) { + } +} + +void soc_supc_enable_wakeup_source(uint32_t wakeup_source_id) +{ + __ASSERT(wakeup_source_id <= SOC_SUPC_WAKEUP_SOURCE_IDS, + "Wakeup source channel is invalid"); + + SUPC->SUPC_WUMR |= 1 << wakeup_source_id; +} diff --git a/soc/arm/atmel_sam/common/soc_supc.h b/soc/arm/atmel_sam/common/soc_supc.h new file mode 100644 index 00000000000..b925eb5f18c --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_supc.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ATMEL_SAM_SOC_SUPC_H_ +#define _ATMEL_SAM_SOC_SUPC_H_ + +#include + +/** + * @brief Enable the clock of specified peripheral module. + */ +void soc_supc_core_voltage_regulator_off(void); + +/** + * @brief Switch slow clock source to external crystal oscillator + */ +void soc_supc_slow_clock_select_crystal_osc(void); + +/** + * @brief Enable wakeup source + */ +void soc_supc_enable_wakeup_source(uint32_t wakeup_source_id); + +#endif /* _ATMEL_SAM_SOC_SUPC_H_ */ diff --git a/soc/arm/atmel_sam/sam3x/soc.h b/soc/arm/atmel_sam/sam3x/soc.h index 0d7842fac1c..3fe78a7e6ba 100644 --- a/soc/arm/atmel_sam/sam3x/soc.h +++ b/soc/arm/atmel_sam/sam3x/soc.h @@ -38,6 +38,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/sam4e/soc.h b/soc/arm/atmel_sam/sam4e/soc.h index 523c5487748..290653e148a 100644 --- a/soc/arm/atmel_sam/sam4e/soc.h +++ b/soc/arm/atmel_sam/sam4e/soc.h @@ -38,6 +38,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/sam4s/soc.h b/soc/arm/atmel_sam/sam4s/soc.h index e469c3ac19a..ec3ab20471e 100644 --- a/soc/arm/atmel_sam/sam4s/soc.h +++ b/soc/arm/atmel_sam/sam4s/soc.h @@ -52,6 +52,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/same70/soc.h b/soc/arm/atmel_sam/same70/soc.h index 37f10e2792a..ad72b4d2ef0 100644 --- a/soc/arm/atmel_sam/same70/soc.h +++ b/soc/arm/atmel_sam/same70/soc.h @@ -64,6 +64,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/samv71/soc.h b/soc/arm/atmel_sam/samv71/soc.h index 264f92c5172..4c85be42136 100644 --- a/soc/arm/atmel_sam/samv71/soc.h +++ b/soc/arm/atmel_sam/samv71/soc.h @@ -65,6 +65,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ From 278d029f4f9642ec9af8694587f28f34b2b73ba3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 20 Oct 2023 00:23:59 +0200 Subject: [PATCH 2513/4498] dts: soc: atmel: sam: Add SUPC component to soc dtsi This commit adds the new SUPC devicetree instance to the soc dtsi files. Signed-off-by: Bjarki Arge Andreasen --- dts/arm/atmel/sam3x.dtsi | 7 +++++++ dts/arm/atmel/sam4e.dtsi | 7 +++++++ dts/arm/atmel/sam4s.dtsi | 7 +++++++ dts/arm/atmel/same70.dtsi | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/dts/arm/atmel/sam3x.dtsi b/dts/arm/atmel/sam3x.dtsi index 065c8920e17..1fc5dbe9733 100644 --- a/dts/arm/atmel/sam3x.dtsi +++ b/dts/arm/atmel/sam3x.dtsi @@ -37,6 +37,13 @@ status = "okay"; }; + supc: supc@400e1a10 { + compatible = "atmel,sam-supc"; + reg = <0x400e1a10 0x20>; + #wakeup-source-id-cells = <1>; + status = "okay"; + }; + sram0: memory@20070000 { compatible = "mmio-sram"; reg = <0x20070000 0x18000>; diff --git a/dts/arm/atmel/sam4e.dtsi b/dts/arm/atmel/sam4e.dtsi index 122d904b899..00212c4eaa3 100644 --- a/dts/arm/atmel/sam4e.dtsi +++ b/dts/arm/atmel/sam4e.dtsi @@ -47,6 +47,13 @@ status = "okay"; }; + supc: supc@400e1810 { + compatible = "atmel,sam-supc"; + reg = <0x400e1810 0x20>; + #wakeup-source-id-cells = <1>; + status = "okay"; + }; + sram0: memory@20000000 { compatible = "mmio-sram"; }; diff --git a/dts/arm/atmel/sam4s.dtsi b/dts/arm/atmel/sam4s.dtsi index 7c86d5a0475..8c7cf1acc2a 100644 --- a/dts/arm/atmel/sam4s.dtsi +++ b/dts/arm/atmel/sam4s.dtsi @@ -49,6 +49,13 @@ status = "okay"; }; + supc: supc@400e1410 { + compatible = "atmel,sam-supc"; + reg = <0x400e1410 0x20>; + #wakeup-source-id-cells = <1>; + status = "okay"; + }; + sram0: memory@20100000 { compatible = "mmio-sram"; }; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 56f0ba2c6ec..002f0969ebb 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -57,6 +57,13 @@ status = "okay"; }; + supc: supc@400e1810 { + compatible = "atmel,sam-supc"; + reg = <0x400e1810 0x20>; + #wakeup-source-id-cells = <1>; + status = "okay"; + }; + eefc: flash-controller@400e0c00 { compatible = "atmel,sam-flash-controller"; reg = <0x400e0c00 0x200>; From 9b21d4d36618929df28f322159392cfdf1c75739 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 20 Oct 2023 00:26:08 +0200 Subject: [PATCH 2514/4498] soc: sam: Add poweroff implementation This commit adds an implementation of poweroff, which first uses SUPC to enable all defined wakeup sources (except for sam4l), followed by entering backup mode. Signed-off-by: Bjarki Arge Andreasen --- soc/arm/atmel_sam/common/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/common/soc_poweroff.c | 33 +++++++++++++++++++ soc/arm/atmel_sam/common/soc_sam4l_poweroff.c | 33 +++++++++++++++++++ soc/arm/atmel_sam/sam3x/Kconfig.series | 1 + soc/arm/atmel_sam/sam4e/Kconfig.series | 1 + soc/arm/atmel_sam/sam4l/Kconfig.series | 1 + soc/arm/atmel_sam/sam4s/Kconfig.series | 1 + soc/arm/atmel_sam/same70/Kconfig.series | 1 + soc/arm/atmel_sam/samv71/Kconfig.series | 1 + 9 files changed, 74 insertions(+) create mode 100644 soc/arm/atmel_sam/common/soc_poweroff.c create mode 100644 soc/arm/atmel_sam/common/soc_sam4l_poweroff.c diff --git a/soc/arm/atmel_sam/common/CMakeLists.txt b/soc/arm/atmel_sam/common/CMakeLists.txt index 0c8602d1a35..2d5a6c35a33 100644 --- a/soc/arm/atmel_sam/common/CMakeLists.txt +++ b/soc/arm/atmel_sam/common/CMakeLists.txt @@ -4,6 +4,8 @@ zephyr_include_directories(.) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_pmc.c) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_gpio.c) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_supc.c) +zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_poweroff.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_pm.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_gpio.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_poweroff.c) diff --git a/soc/arm/atmel_sam/common/soc_poweroff.c b/soc/arm/atmel_sam/common/soc_poweroff.c new file mode 100644 index 00000000000..7cc17f02018 --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_poweroff.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * Poweroff will make the chip enter the backup low-power mode, which + * achieves the lowest possible power consumption. Wakeup from this mode + * requires enabling a wakeup source or input, or power cycling the device. + */ + +static void soc_core_sleepdeep_enable(void) +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +} + +static void soc_core_sleepdeep_wait(void) +{ + __WFE(); + __WFI(); +} + +void z_sys_poweroff(void) +{ + soc_core_sleepdeep_enable(); + soc_supc_core_voltage_regulator_off(); + soc_core_sleepdeep_wait(); + + CODE_UNREACHABLE; +} diff --git a/soc/arm/atmel_sam/common/soc_sam4l_poweroff.c b/soc/arm/atmel_sam/common/soc_sam4l_poweroff.c new file mode 100644 index 00000000000..ecadfe2d8f0 --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_sam4l_poweroff.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * Poweroff will make the chip enter the backup low-power mode, which + * achieves the lowest possible power consumption. Wakeup from this mode + * requires enabling a wakeup source or input, or power cycling the device. + */ + +static void soc_core_sleepdeep_enable(void) +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +} + +static void soc_core_sleepdeep_wait(void) +{ + __WFE(); + __WFI(); +} + +void z_sys_poweroff(void) +{ + soc_core_sleepdeep_enable(); + BPM->PMCON |= BPM_PMCON_BKUP; + soc_core_sleepdeep_wait(); + + CODE_UNREACHABLE; +} diff --git a/soc/arm/atmel_sam/sam3x/Kconfig.series b/soc/arm/atmel_sam/sam3x/Kconfig.series index 911eab6b1cc..08a3781b6d3 100644 --- a/soc/arm/atmel_sam/sam3x/Kconfig.series +++ b/soc/arm/atmel_sam/sam3x/Kconfig.series @@ -15,6 +15,7 @@ config SOC_SERIES_SAM3X select SOC_FAMILY_SAM select PLATFORM_SPECIFIC_INIT select ASF + select HAS_POWEROFF help Enable support for Atmel SAM3X Cortex-M3 microcontrollers. Part No.: SAM3X8E diff --git a/soc/arm/atmel_sam/sam4e/Kconfig.series b/soc/arm/atmel_sam/sam4e/Kconfig.series index 612e1d20bd6..93cc0e20a48 100644 --- a/soc/arm/atmel_sam/sam4e/Kconfig.series +++ b/soc/arm/atmel_sam/sam4e/Kconfig.series @@ -15,6 +15,7 @@ config SOC_SERIES_SAM4E select SOC_FAMILY_SAM select PLATFORM_SPECIFIC_INIT select ASF + select HAS_POWEROFF help Enable support for Atmel SAM4E Cortex-M4 microcontrollers. Part No.: SAM4E16E, SAM4E16C, SAM4E8E, SAM4E8C diff --git a/soc/arm/atmel_sam/sam4l/Kconfig.series b/soc/arm/atmel_sam/sam4l/Kconfig.series index 7a41ba2ff24..0a8192f5bd9 100644 --- a/soc/arm/atmel_sam/sam4l/Kconfig.series +++ b/soc/arm/atmel_sam/sam4l/Kconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES_SAM4L select SOC_FAMILY_SAM select PLATFORM_SPECIFIC_INIT select ASF + select HAS_POWEROFF help Enable support for Atmel SAM4L Cortex-M4 microcontrollers. Part No.: SAM4LS8C, SAM4LS8B, SAM4LS8A, SAM4LS4C, SAM4LS4B, diff --git a/soc/arm/atmel_sam/sam4s/Kconfig.series b/soc/arm/atmel_sam/sam4s/Kconfig.series index 34fe0ce55f2..f591d96ba88 100644 --- a/soc/arm/atmel_sam/sam4s/Kconfig.series +++ b/soc/arm/atmel_sam/sam4s/Kconfig.series @@ -14,6 +14,7 @@ config SOC_SERIES_SAM4S select SOC_FAMILY_SAM select PLATFORM_SPECIFIC_INIT select ASF + select HAS_POWEROFF help Enable support for Atmel SAM4S Cortex-M4 microcontrollers. Part No.: SAM4S16C, SAM4S16B, SAM4S8C, SAM4S8B, diff --git a/soc/arm/atmel_sam/same70/Kconfig.series b/soc/arm/atmel_sam/same70/Kconfig.series index f8955bd4a76..0e19a2197ba 100644 --- a/soc/arm/atmel_sam/same70/Kconfig.series +++ b/soc/arm/atmel_sam/same70/Kconfig.series @@ -16,6 +16,7 @@ config SOC_SERIES_SAME70 select ASF select HAS_SWO select XIP + select HAS_POWEROFF help Enable support for Atmel SAM E70 ARM Cortex-M7 Microcontrollers. Part No.: SAME70J19, SAME70J20, SAME70J21, SAME70N19, SAME70N20, diff --git a/soc/arm/atmel_sam/samv71/Kconfig.series b/soc/arm/atmel_sam/samv71/Kconfig.series index 75072eec1ee..49de040aff8 100644 --- a/soc/arm/atmel_sam/samv71/Kconfig.series +++ b/soc/arm/atmel_sam/samv71/Kconfig.series @@ -16,6 +16,7 @@ config SOC_SERIES_SAMV71 select ASF select HAS_SWO select XIP + select HAS_POWEROFF help Enable support for Atmel SAM V71 ARM Cortex-M7 Microcontrollers. Part No.: SAMV71J19, SAMV71J20, SAMV71J21, SAMV71N19, SAMV71N20, From 1e6866ed0be698419453dce1f9d6a7b3a3e6cbc5 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Fri, 6 Oct 2023 12:12:34 -0700 Subject: [PATCH 2515/4498] drivers: mipi_dsi: dsi_mcux_2l set SMARDMA slot from dev pixfmt Previous version hardcoded the SMARTDMA slot to either RGB565 or RGB565_SWAP, but that would be incorrect if the pixfmt was RGB888. Use the mipi device pixfmt to set the slot. Signed-off-by: Mike J. Chen --- drivers/mipi_dsi/dsi_mcux_2l.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 05d56f9b6a1..934f267e188 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -45,6 +45,9 @@ struct mcux_mipi_dsi_config { struct mcux_mipi_dsi_data { dsi_handle_t mipi_handle; struct k_sem transfer_sem; +#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA + uint8_t dma_slot; +#endif }; @@ -105,11 +108,7 @@ static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel, dma_cfg.user_data = (struct device *)dev; dma_cfg.head_block = █ dma_cfg.block_count = 1; - if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) { - dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP; - } else { - dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA; - } + dma_cfg.dma_slot = data->dma_slot; dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; ret = dma_config(config->smart_dma, 0, &dma_cfg); if (ret < 0) { @@ -241,6 +240,25 @@ static int dsi_mcux_attach(const struct device *dev, if (!device_is_ready(config->smart_dma)) { return -ENODEV; } + + struct mcux_mipi_dsi_data *data = dev->data; + + switch (mdev->pixfmt) { + case MIPI_DSI_PIXFMT_RGB888: + data->dma_slot = DMA_SMARTDMA_MIPI_RGB888_DMA; + break; + case MIPI_DSI_PIXFMT_RGB565: + if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) { + data->dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP; + } else { + data->dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA; + } + break; + default: + LOG_ERR("SMARTDMA does not support pixel_format %u", + mdev->pixfmt); + return -ENODEV; + } #else struct mcux_mipi_dsi_data *data = dev->data; From 4844d015a4dbca4fe9314c531240826250b60142 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Fri, 6 Oct 2023 12:23:04 -0700 Subject: [PATCH 2516/4498] drivers: mipi_dsi: dsi_mcux_2l add msg flag for low power mode Previous version of dsi_mcux_2l hardcoded some MIPI DSI transfers to use high speed mode but others used low power mode. Now dsi_mcux_2l will use high speed mode by default for all transfers unless a new msg flag is set to indicate the transfer must use low power mode. Note that the new flag is different than the existing MIPI_DSI_MODE_LPM flag, which so far only applied to cmd messages sent in video mode, or could be interpreted as for all messages, but would not allow per message mode control. This new message flag allows client to control transfer mode per message transfer. Signed-off-by: Mike J. Chen --- drivers/mipi_dsi/dsi_mcux_2l.c | 6 ++++-- include/zephyr/drivers/mipi_dsi.h | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 934f267e188..3c51eb4d8c4 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -162,7 +162,8 @@ static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel, .sendDscCmd = true, .dscCmd = msg->cmd, .txDataType = kDSI_TxDataDcsLongWr, - .flags = kDSI_TransferUseHighSpeed, + /* default to high speed unless told to use low power */ + .flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : kDSI_TransferUseHighSpeed, }; /* @@ -354,6 +355,8 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, dsi_xfer.txData = msg->tx_buf; dsi_xfer.rxDataSize = msg->rx_len; dsi_xfer.rxData = msg->rx_buf; + /* default to high speed unless told to use low power */ + dsi_xfer.flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : kDSI_TransferUseHighSpeed; switch (msg->type) { case MIPI_DSI_DCS_READ: @@ -373,7 +376,6 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, dsi_xfer.sendDscCmd = true; dsi_xfer.dscCmd = msg->cmd; dsi_xfer.txDataType = kDSI_TxDataDcsLongWr; - dsi_xfer.flags = kDSI_TransferUseHighSpeed; if (msg->flags & MCUX_DSI_2L_FB_DATA) { /* * Special case- transfer framebuffer data using diff --git a/include/zephyr/drivers/mipi_dsi.h b/include/zephyr/drivers/mipi_dsi.h index 6373c1010f0..d26854fc1a6 100644 --- a/include/zephyr/drivers/mipi_dsi.h +++ b/include/zephyr/drivers/mipi_dsi.h @@ -217,6 +217,12 @@ struct mipi_dsi_device { uint32_t mode_flags; }; +/* + * Per message flag to indicate the message must be sent + * using Low Power Mode instead of controller default. + */ +#define MIPI_DSI_MSG_USE_LPM BIT(0x0) + /** MIPI-DSI read/write message. */ struct mipi_dsi_msg { /** Payload data type. */ From 01aa8004644b3cbc291ad9ad3b59e504c289a926 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Wed, 11 Oct 2023 17:57:25 -0700 Subject: [PATCH 2517/4498] drivers: mipi_dsi: dsi_mcux_2l add property to enable non-continuous hs clk Allows device tree to enable usage of the controller feature where HS clock is disabled when not in use, which is good for reducing power consumption if MIPI DSI is mostly idle. Signed-off-by: Mike J. Chen --- drivers/mipi_dsi/dsi_mcux_2l.c | 3 +++ dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 3c51eb4d8c4..de73d10e8ac 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -28,6 +28,7 @@ struct mcux_mipi_dsi_config { MIPI_DSI_HOST_Type *base; dsi_dpi_config_t dpi_config; bool auto_insert_eotp; + bool noncontinuous_hs_clk; const struct device *bit_clk_dev; clock_control_subsys_t bit_clk_subsys; const struct device *esc_clk_dev; @@ -224,6 +225,7 @@ static int dsi_mcux_attach(const struct device *dev, DSI_GetDefaultConfig(&dsi_config); dsi_config.numLanes = mdev->data_lanes; dsi_config.autoInsertEoTp = config->auto_insert_eotp; + dsi_config.enableNonContinuousHsClk = config->noncontinuous_hs_clk; /* Init the DSI module. */ DSI_Init(config->base, &dsi_config); @@ -502,6 +504,7 @@ static int mcux_mipi_dsi_init(const struct device *dev) (.irq_config_func = mipi_dsi_##n##_irq_config_func,)) \ .base = (MIPI_DSI_HOST_Type *)DT_INST_REG_ADDR(id), \ .auto_insert_eotp = DT_INST_PROP(id, autoinsert_eotp), \ + .noncontinuous_hs_clk = DT_INST_PROP(id, noncontinuous_hs_clk), \ .dphy_ref_freq = DT_INST_PROP_OR(id, dphy_ref_frequency, 0), \ .bit_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, dphy)), \ .bit_clk_subsys = \ diff --git a/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml b/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml index fc0a69870c5..02871f29641 100644 --- a/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml +++ b/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml @@ -70,3 +70,9 @@ properties: description: Maximum clock speed supported by the device, in Hz. Leave at default if no DPHY PLL is present + + noncontinuous-hs-clk: + type: boolean + description: + Enable non-contiuous high speed clock. Saves power but introduces latency + when transitioning to high speed mode. From 05c85ddbcf8e09cd5cbfdae2adbdbbf6ddcc612b Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 17 Oct 2023 22:11:04 +0200 Subject: [PATCH 2518/4498] Bluetooth: Controller: Fix periodic advertising sync window Fix periodic advertising sync window calculation to include the scheduling resolution margin, i.e. be double as with the event jitter value. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index ecdfdd60d07..9a86a473b02 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -646,8 +646,8 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) window_widening_us = SCA_DRIFT_500_PPM_US(aux_offset_us); } - lll_aux->window_size_us += (EVENT_TICKER_RES_MARGIN_US + - ((EVENT_JITTER_US + window_widening_us) << 1)); + lll_aux->window_size_us += ((EVENT_TICKER_RES_MARGIN_US + EVENT_JITTER_US + + window_widening_us) << 1); ready_delay_us = lll_radio_rx_ready_delay_get(lll_aux->phy, PHY_FLAGS_S8); From f64d123a3d7495632dfb64733c2e22a5c7990517 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 23 Oct 2023 19:44:37 +0200 Subject: [PATCH 2519/4498] Bluetooth: Controller: Fix missing ext adv terminate event Fix missing Extended Advertising terminate event and advertising scheduling not being stopped. Under race conditions, auxiliary event is aborted without the generation of done extra event which is suppose to stop the scheduling when max events count is used. The fix now generates the done extra event. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_adv_aux.c | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c index 6fa0204fb56..6b61c3b559f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c @@ -49,6 +49,9 @@ static int init_reset(void); static int prepare_cb(struct lll_prepare_param *p); +#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) +static void isr_early_abort(void *param); +#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ static void isr_done(void *param); #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK) static void isr_tx_chain(void *param); @@ -188,7 +191,7 @@ static int prepare_cb(struct lll_prepare_param *p) /* Abort if no aux_ptr filled */ if (unlikely(!pri_hdr->aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr))) { - radio_isr_set(lll_isr_early_abort, lll); + radio_isr_set(isr_early_abort, lll); radio_disable(); return 0; @@ -325,7 +328,7 @@ static int prepare_cb(struct lll_prepare_param *p) if (overhead) { LL_ASSERT_OVERHEAD(overhead); - radio_isr_set(lll_isr_abort, lll); + radio_isr_set(isr_done, lll); radio_disable(); return -ECANCELED; @@ -347,6 +350,33 @@ static int prepare_cb(struct lll_prepare_param *p) return 0; } +#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) +static void isr_race(void *param) +{ + radio_status_reset(); +} + +static void isr_early_abort(void *param) +{ + struct event_done_extra *extra; + int err; + + /* Generate auxiliary radio event done */ + extra = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_AUX); + LL_ASSERT(extra); + + radio_isr_set(isr_race, param); + if (!radio_is_idle()) { + radio_disable(); + } + + err = lll_hfclock_off(); + LL_ASSERT(err >= 0); + + lll_done(NULL); +} +#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ + static void isr_done(void *param) { struct event_done_extra *extra; From 413a349264cab91c9a2bb322c32968344ee663df Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 11:40:03 +0200 Subject: [PATCH 2520/4498] nrf_bsim: Only connect once to Bsim Phy Each MCU initialization hooks will attempt to call into the API to connect to the bsim phy and, if the user requested it thru command line, delay its boot. Doing this for all MCUs is best to ensure it is done even if there is no image for the other MCU, but results in the calls being done twice if there is 2 MCUs images, which results in the simulator API giving a warning about it being likely an error in the app. To avoid this problem, let's have this be called only once. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/common/phy_sync_ctrl.c | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/boards/posix/nrf_bsim/common/phy_sync_ctrl.c b/boards/posix/nrf_bsim/common/phy_sync_ctrl.c index fc4a7992837..b7b6c507d4f 100644 --- a/boards/posix/nrf_bsim/common/phy_sync_ctrl.c +++ b/boards/posix/nrf_bsim/common/phy_sync_ctrl.c @@ -214,6 +214,13 @@ NSI_TASK(phy_sync_ctrl_register_args, PRE_BOOT_1, 10); void phy_sync_ctrl_connect_to_2G4_phy(void) { + static bool ever_run; + + if (ever_run) { + return; + } + ever_run = true; + bs_trace_raw(9, "%s: Connecting to phy...\n", __func__); hwll_connect_to_phy(bsim_args_get_2G4_device_nbr(), bsim_args_get_simid(), @@ -223,6 +230,13 @@ void phy_sync_ctrl_connect_to_2G4_phy(void) void phy_sync_ctrl_pre_boot2(void) { + static bool ever_run; + + if (ever_run) { + return; + } + ever_run = true; + if (((sync_args.start_offset > 0) && (sync_args.delay_init)) || sync_args.sync_preinit) { /* Delay the next steps until the simulation time has @@ -235,6 +249,13 @@ void phy_sync_ctrl_pre_boot2(void) void phy_sync_ctrl_pre_boot3(void) { + static bool ever_run; + + if (ever_run) { + return; + } + ever_run = true; + /* * If sync_preboot was set, we sync with the phy * right before booting the CPU From 214178ab4b26bdf2dc68c53ce12af8bf577281d9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 12:12:13 +0200 Subject: [PATCH 2521/4498] manifest: Update nrf hw models to latest * Update the HW models module to f7842d717c73aaeb0354f9e70e6d5ad275106f52 Including the following: * f7842d7 INT CNTLR: Bugfix for more than 32 interrupts * 903f643 MUTEX: Add nrf5340 MUTEX peripheral model * e84fca4 IPC: Add nrf5340 IPC peripheral model * dacbaa0 EGU: Minor: Use new irq ctrl API * 9a4e0ba Templates: Add intenset/clr template for multi instance per * c77ba72 nrf_dppi_hack: Add extra nrf like APIs meant for simulation * 99ae791 RTC: Fix subscribe prototypes and calls from HAL * ca554e9 FICR (53): Fix links to documentation * d3758a2 docs: Fix links to HW sources * 693a36c doc: Implementation status: Change checkmarks Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 50fee2aae60..91b11593612 100644 --- a/west.yml +++ b/west.yml @@ -294,7 +294,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: f4595802d32d103718bf50b3d390b7a450895843 + revision: f7842d717c73aaeb0354f9e70e6d5ad275106f52 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 From a04220311786ba87b5bf150134ec69611252f993 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 13:48:37 +0200 Subject: [PATCH 2522/4498] manifest: Update libmetal to latest including POSIX arch support Update libmetal to the latest version which includes support for the POSIX architecture. Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 91b11593612..2df3454d3a7 100644 --- a/west.yml +++ b/west.yml @@ -257,7 +257,7 @@ manifest: groups: - hal - name: libmetal - revision: b91611a6f47dd29fb24c46e5621e797557f80ec6 + revision: 03140d7f4bd9ba474ebfbb6256e84a9089248e67 path: modules/hal/libmetal groups: - hal From f8e8083ab321b15e930dd82eb7f66f32bab84cc9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 10:57:19 +0200 Subject: [PATCH 2523/4498] nrf53_bsim: Provide shared memory buffer for IPC rpmsg backend Provide the actual shared memory buffer for the IPC rpmsg backend in this platform. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/CMakeLists.txt | 6 ++++++ boards/posix/nrf_bsim/ipc_backend.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 boards/posix/nrf_bsim/ipc_backend.c diff --git a/boards/posix/nrf_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt index a9c8f684171..c55df7d0095 100644 --- a/boards/posix/nrf_bsim/CMakeLists.txt +++ b/boards/posix/nrf_bsim/CMakeLists.txt @@ -35,6 +35,12 @@ target_sources(native_simulator INTERFACE common/trace_hook.c ) +if (CONFIG_IPC_SERVICE) + target_sources(native_simulator INTERFACE + ipc_backend.c + ) +endif() + zephyr_include_directories( soc common diff --git a/boards/posix/nrf_bsim/ipc_backend.c b/boards/posix/nrf_bsim/ipc_backend.c new file mode 100644 index 00000000000..1619f449b79 --- /dev/null +++ b/boards/posix/nrf_bsim/ipc_backend.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This buffer is the shared memory buffer for the RPMSG IPC backed + * in simulation. + * It must be at last as large as the size defined in device tree, but as it will be compiled in + * the native simulator runner context we cannot refer to DT itself to size it. + * The default buffer for this target is defined in + * boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dtsi + */ +char IPC0_shm_buffer[65536]; From 7ea95b007143fb904344368163930912528443f5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 9 Oct 2023 15:49:47 +0200 Subject: [PATCH 2524/4498] nrf5x_bsim: Add support for IPC/OpenAMP and split BT stack For the 5340 simulated boards: * Now that the HW models include the IPC and MUTEX peripherals we can enable them in DT. * Also enable the DT mbox definition and allocate its shared memory * Set the default kconfiguration for the HEAD, IPC, MBOX and split BT stack as in the equivalent real targets. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/Kconfig.defconfig | 23 +++++++++++++++++++ .../nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts | 9 +++++--- .../nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts | 8 +++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 5dc75661117..a03b8b1d384 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -42,6 +42,29 @@ config BT_CTLR default y if BOARD_NRF52_BSIM || BOARD_NRF5340BSIM_NRF5340_CPUNET depends on BT +config HEAP_MEM_POOL_SIZE + default 4096 if BT_RPMSG + default 4096 if NRF_802154_SER_HOST && BOARD_NRF5340BSIM_NRF5340_CPUAPP + default 4096 if NRF_802154_SER_RADIO && BOARD_NRF5340BSIM_NRF5340_CPUNET + +if BOARD_NRF5340BSIM_NRF5340_CPUAPP || BOARD_NRF5340BSIM_NRF5340_CPUNET + +config MBOX_NRFX_IPC + default MBOX + +endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP || BOARD_NRF5340BSIM_NRF5340_CPUNET + +if BOARD_NRF5340BSIM_NRF5340_CPUAPP + +config IPC_SERVICE_BACKEND_RPMSG_SHMEM_RESET + default y if IPC_SERVICE_BACKEND_RPMSG + +choice BT_HCI_BUS_TYPE + default BT_RPMSG +endchoice + +endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP + # The 15.4 driver Tx encryption is currently not functional with this # simulated board => we disable it by default. With this Openthread will normally # default to encrypt packets on its own. diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index b967c010653..0800dfc0f45 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -46,6 +46,7 @@ chosen { zephyr,flash = &flash0; + zephyr,bt-hci-rpmsg-ipc = &ipc0; }; soc { @@ -78,10 +79,8 @@ /delete-node/ pwm@24000; /delete-node/ pdm@26000; /delete-node/ i2s@28000; - /delete-node/ mbox@2a000; /delete-node/ qspi@2b000; /delete-node/ nfct@2d000; - /delete-node/ mutex@30000; /delete-node/ qdec@33000; /delete-node/ qdec@34000; /delete-node/ usbd@36000; @@ -97,7 +96,6 @@ }; /delete-node/ cpus; - /delete-node/ ipc; /delete-node/ sw-pwm; }; @@ -118,3 +116,8 @@ }; }; }; + +/* We re-use the IPC shared buffer definition from the real HW. But note the start address of the + * buffer won't be used. + */ +#include <../boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dtsi> diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts index 138cde81ef1..903e16db685 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts @@ -27,6 +27,7 @@ }; chosen { + zephyr,bt-hci-rpmsg-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; /delete-property/ zephyr,flash-controller; zephyr,flash = &flash1; @@ -37,7 +38,6 @@ /delete-node/ memory@21000000; /delete-node/ gpiote@4100a000; /delete-node/ watchdog@4100b000; - /delete-node/ mbox@41012000; /delete-node/ i2c@41013000; /delete-node/ spi@41013000; /delete-node/ uart@41013000; @@ -48,7 +48,6 @@ }; /delete-node/ cpus; - /delete-node/ ipc; /delete-node/ sw-pwm; }; @@ -75,3 +74,8 @@ }; }; }; + +/* We re-use the IPC shared buffer definition from the real HW. But note the start address of the + * buffer won't be used. + */ +#include <../boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dtsi> From 7fe491c05021e7175ecf1097b6dc95275c21e538 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 08:35:20 +0200 Subject: [PATCH 2525/4498] modem: modem_cmux: Make async connect/disconnect stateful This commit adds a check to the async connect and disconnect functions to validate the CMUX is not already connected or disconnected respectively. This was already part of the sync connect and disconnect functions, so the sync functions now simply wrap the async functions to avoid duplicate code. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index a73241a7a46..35813f2b2fa 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -941,14 +941,11 @@ int modem_cmux_attach(struct modem_cmux *cmux, struct modem_pipe *pipe) int modem_cmux_connect(struct modem_cmux *cmux) { - __ASSERT_NO_MSG(cmux->pipe != NULL); - - if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT, false, K_NO_WAIT)) { - return -EALREADY; - } + int ret; - if (k_work_delayable_is_pending(&cmux->connect_work) == false) { - k_work_schedule(&cmux->connect_work, K_NO_WAIT); + ret = modem_cmux_connect_async(cmux); + if (ret < 0) { + return ret; } if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT, false, @@ -963,22 +960,24 @@ int modem_cmux_connect_async(struct modem_cmux *cmux) { __ASSERT_NO_MSG(cmux->pipe != NULL); - if (k_work_delayable_is_pending(&cmux->connect_work) == true) { - return -EBUSY; + if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT, false, K_NO_WAIT)) { + return -EALREADY; + } + + if (k_work_delayable_is_pending(&cmux->connect_work) == false) { + k_work_schedule(&cmux->connect_work, K_NO_WAIT); } - k_work_schedule(&cmux->connect_work, K_NO_WAIT); return 0; } int modem_cmux_disconnect(struct modem_cmux *cmux) { - if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT, false, K_NO_WAIT)) { - return -EALREADY; - } + int ret; - if (k_work_delayable_is_pending(&cmux->disconnect_work) == false) { - k_work_schedule(&cmux->disconnect_work, K_NO_WAIT); + ret = modem_cmux_disconnect_async(cmux); + if (ret < 0) { + return ret; } if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT, false, @@ -991,11 +990,16 @@ int modem_cmux_disconnect(struct modem_cmux *cmux) int modem_cmux_disconnect_async(struct modem_cmux *cmux) { - if (k_work_delayable_is_pending(&cmux->disconnect_work) == true) { - return -EBUSY; + __ASSERT_NO_MSG(cmux->pipe != NULL); + + if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT, false, K_NO_WAIT)) { + return -EALREADY; + } + + if (k_work_delayable_is_pending(&cmux->disconnect_work) == false) { + k_work_schedule(&cmux->disconnect_work, K_NO_WAIT); } - k_work_schedule(&cmux->disconnect_work, K_NO_WAIT); return 0; } From 79e6c8411f07bc73e8b51335476bf799dbf4e5c6 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 12:17:40 +0200 Subject: [PATCH 2526/4498] modem: modem_cmux: Reset CMUX events on release This commit resets the CMUX events to match the initial value of disconnected. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 35813f2b2fa..d2e183cfcae 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -1023,4 +1023,8 @@ void modem_cmux_release(struct modem_cmux *cmux) /* Unreference pipe */ cmux->pipe = NULL; + + /* Reset events */ + k_event_clear(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT); + k_event_post(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT); } From 92ad351e2a145386eda1ca274df4312af6f7ae0c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 12:22:42 +0200 Subject: [PATCH 2527/4498] modem: modem_cmux: Use k_event_test instead of K_NO_WAIT This commit replaces the k_event_wait calls using K_NO_WAIT with k_event_test. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index d2e183cfcae..4a1e272feeb 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -960,7 +960,7 @@ int modem_cmux_connect_async(struct modem_cmux *cmux) { __ASSERT_NO_MSG(cmux->pipe != NULL); - if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT, false, K_NO_WAIT)) { + if (k_event_test(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT)) { return -EALREADY; } @@ -992,7 +992,7 @@ int modem_cmux_disconnect_async(struct modem_cmux *cmux) { __ASSERT_NO_MSG(cmux->pipe != NULL); - if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT, false, K_NO_WAIT)) { + if (k_event_test(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT)) { return -EALREADY; } From 0f3813643113ae70133814a3fb6d8c687aeb84f8 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 13:08:54 +0200 Subject: [PATCH 2528/4498] modem: modem_cmux: Clear DLCI pipes on open This commit resets the receive ring buffer for each DLCI pipe when they are opened. They may have old data stored from last time they where opened. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 4a1e272feeb..d645f58eeeb 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -401,6 +401,9 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci) dlci->state = MODEM_CMUX_DLCI_STATE_OPEN; modem_pipe_notify_opened(&dlci->pipe); k_work_cancel_delayable(&dlci->open_work); + k_mutex_lock(&dlci->receive_rb_lock, K_FOREVER); + ring_buf_reset(&dlci->receive_rb); + k_mutex_unlock(&dlci->receive_rb_lock); break; case MODEM_CMUX_DLCI_STATE_CLOSING: From b495fda6a197754ffde0cfcaab85f9c12c7023d2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 13:56:48 +0200 Subject: [PATCH 2529/4498] modem: modem_cmux: Improve logging This commit adds logging for CMUX frames and commands and their data, for both transmit and receive. It also removes the superseded LOG_DBG() lines like "Received frame". Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/Kconfig | 8 +++ subsys/modem/modem_cmux.c | 112 ++++++++++++++++++++++++++++++++------ 2 files changed, 102 insertions(+), 18 deletions(-) diff --git a/subsys/modem/Kconfig b/subsys/modem/Kconfig index 7ad98d2b718..da992bf3760 100644 --- a/subsys/modem/Kconfig +++ b/subsys/modem/Kconfig @@ -26,6 +26,14 @@ config MODEM_CMUX select EVENTS select CRC +if MODEM_CMUX + +module = MODEM_CMUX +module-str = modem_cmux +source "subsys/logging/Kconfig.template.log_config" + +endif + config MODEM_PIPE bool "Modem pipe module" diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index d645f58eeeb..33818cc308d 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -5,7 +5,7 @@ */ #include -LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_MODULES_LOG_LEVEL); +LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_CMUX_LOG_LEVEL); #include #include @@ -96,26 +96,91 @@ static int modem_cmux_wrap_command(struct modem_cmux_command **command, const ui return 0; } -static struct modem_cmux_command *modem_cmux_command_wrap(uint8_t *data) +static struct modem_cmux_command *modem_cmux_command_wrap(const uint8_t *data) { return (struct modem_cmux_command *)data; } -static void modem_cmux_log_unknown_frame(struct modem_cmux *cmux) +static const char *modem_cmux_frame_type_to_str(enum modem_cmux_frame_types frame_type) { - char data[24]; - uint8_t data_cnt = (cmux->frame.data_len < 8) ? cmux->frame.data_len : 8; - - for (uint8_t i = 0; i < data_cnt; i++) { - snprintk(&data[i * 3], sizeof(data) - (i * 3), "%02X,", cmux->frame.data[i]); + switch (frame_type) { + case MODEM_CMUX_FRAME_TYPE_RR: + return "RR"; + case MODEM_CMUX_FRAME_TYPE_UI: + return "UI"; + case MODEM_CMUX_FRAME_TYPE_RNR: + return "RNR"; + case MODEM_CMUX_FRAME_TYPE_REJ: + return "REJ"; + case MODEM_CMUX_FRAME_TYPE_DM: + return "DM"; + case MODEM_CMUX_FRAME_TYPE_SABM: + return "SABM"; + case MODEM_CMUX_FRAME_TYPE_DISC: + return "DISC"; + case MODEM_CMUX_FRAME_TYPE_UA: + return "UA"; + case MODEM_CMUX_FRAME_TYPE_UIH: + return "UIH"; } + return ""; +} + +static void modem_cmux_log_transmit_frame(const struct modem_cmux_frame *frame) +{ + LOG_DBG("ch:%u,cr:%u,pf:%u,type:%s", frame->dlci_address, frame->cr, frame->pf, + modem_cmux_frame_type_to_str(frame->type)); + LOG_HEXDUMP_DBG(frame->data, frame->data_len, "data:"); +} - /* Remove trailing */ - if (data_cnt > 0) { - data[(data_cnt * 3) - 1] = '\0'; +static void modem_cmux_log_received_frame(const struct modem_cmux_frame *frame) +{ + LOG_DBG("ch:%u,cr:%u,pf:%u,type:%s", frame->dlci_address, frame->cr, frame->pf, + modem_cmux_frame_type_to_str(frame->type)); + LOG_HEXDUMP_DBG(frame->data, frame->data_len, "data:"); +} + +static const char *modem_cmux_command_type_to_str(enum modem_cmux_command_types command_type) +{ + switch (command_type) { + case MODEM_CMUX_COMMAND_NSC: + return "NSC"; + case MODEM_CMUX_COMMAND_TEST: + return "TEST"; + case MODEM_CMUX_COMMAND_PSC: + return "PSC"; + case MODEM_CMUX_COMMAND_RLS: + return "RLS"; + case MODEM_CMUX_COMMAND_FCOFF: + return "FCOFF"; + case MODEM_CMUX_COMMAND_PN: + return "PN"; + case MODEM_CMUX_COMMAND_RPN: + return "RPN"; + case MODEM_CMUX_COMMAND_FCON: + return "FCON"; + case MODEM_CMUX_COMMAND_CLD: + return "CLD"; + case MODEM_CMUX_COMMAND_SNC: + return "SNC"; + case MODEM_CMUX_COMMAND_MSC: + return "MSC"; } + return ""; +} - LOG_DBG("ch:%u, type:%u, data:%s", cmux->frame.dlci_address, cmux->frame.type, data); +static void modem_cmux_log_transmit_command(const struct modem_cmux_command *command) +{ + LOG_DBG("ea:%u,cr:%u,type:%s", command->type.ea, command->type.cr, + modem_cmux_command_type_to_str(command->type.value)); + LOG_HEXDUMP_DBG(command->value, command->length.value, "data:"); +} + +static void modem_cmux_log_received_command(const struct modem_cmux_command *command) +{ + LOG_DBG("ea:%u,cr:%u,type:%s", command->type.ea, command->type.cr, + modem_cmux_command_type_to_str(command->type.value)); + LOG_HEXDUMP_DBG(command->value, command->length.value, "data:"); } static void modem_cmux_raise_event(struct modem_cmux *cmux, enum modem_cmux_event event) @@ -199,6 +264,7 @@ static bool modem_cmux_transmit_cmd_frame(struct modem_cmux *cmux, const struct modem_cmux_frame *frame) { uint16_t space; + struct modem_cmux_command *command; k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); space = ring_buf_space_get(&cmux->transmit_rb); @@ -208,6 +274,11 @@ static bool modem_cmux_transmit_cmd_frame(struct modem_cmux *cmux, return false; } + modem_cmux_log_transmit_frame(frame); + if (modem_cmux_wrap_command(&command, frame->data, frame->data_len) == 0) { + modem_cmux_log_transmit_command(command); + } + modem_cmux_transmit_frame(cmux, frame); k_mutex_unlock(&cmux->transmit_rb_lock); return true; @@ -240,6 +311,7 @@ static int16_t modem_cmux_transmit_data_frame(struct modem_cmux *cmux, return -ENOMEM; } + modem_cmux_log_transmit_frame(frame); ret = modem_cmux_transmit_frame(cmux, frame); k_mutex_unlock(&cmux->transmit_rb_lock); return ret; @@ -338,6 +410,8 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux) return; } + modem_cmux_log_received_command(command); + switch (command->type.value) { case MODEM_CMUX_COMMAND_CLD: modem_cmux_on_cld_command(cmux); @@ -356,13 +430,15 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux) break; default: - LOG_DBG("Unknown command"); + LOG_DBG("Unknown control command"); break; } } static void modem_cmux_on_control_frame(struct modem_cmux *cmux) { + modem_cmux_log_received_frame(&cmux->frame); + switch (cmux->frame.type) { case MODEM_CMUX_FRAME_TYPE_UA: modem_cmux_on_control_frame_ua(cmux); @@ -373,7 +449,7 @@ static void modem_cmux_on_control_frame(struct modem_cmux *cmux) break; default: - modem_cmux_log_unknown_frame(cmux); + LOG_WRN("Unknown control frame type"); break; } } @@ -445,6 +521,8 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) return; } + modem_cmux_log_received_frame(&cmux->frame); + switch (cmux->frame.type) { case MODEM_CMUX_FRAME_TYPE_UA: modem_cmux_on_dlci_frame_ua(dlci); @@ -455,7 +533,7 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) break; default: - modem_cmux_log_unknown_frame(cmux); + LOG_WRN("Unknown DLCI frame type"); break; } } @@ -605,7 +683,7 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by /* Check if receive buffer overrun */ if (cmux->receive_buf_len == cmux->receive_buf_size) { - LOG_DBG("Receive buf overrun"); + LOG_WRN("Receive buf overrun"); /* Drop frame */ cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_EOF; @@ -653,8 +731,6 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by break; } - LOG_DBG("Received frame"); - /* Process frame */ cmux->frame.data = cmux->receive_buf; modem_cmux_on_frame(cmux); From ee44357cfb373c8845fdc671eba51e0ec059757b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 9 Oct 2023 15:58:00 +0200 Subject: [PATCH 2530/4498] modem: modem_cellular: Reset receive state on attach This commit resets the state of the CMUX receive state machine when the CMUX instance is attached to a pipe. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 33818cc308d..bc0db3eacc1 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -1014,6 +1014,7 @@ int modem_cmux_attach(struct modem_cmux *cmux, struct modem_pipe *pipe) { cmux->pipe = pipe; ring_buf_reset(&cmux->transmit_rb); + cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_SOF; modem_pipe_attach(cmux->pipe, modem_cmux_bus_callback, cmux); return 0; } From b4f3150592321a724093f7929a84f67cfe7ceb95 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 23 Oct 2023 20:57:46 +0200 Subject: [PATCH 2531/4498] modem: cmux: Optimize log message to save ROM This commit reuses the string "Unknown %s frame type" for two log messages, as suggested by ycsin. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index bc0db3eacc1..19df0509d6c 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -449,7 +449,7 @@ static void modem_cmux_on_control_frame(struct modem_cmux *cmux) break; default: - LOG_WRN("Unknown control frame type"); + LOG_WRN("Unknown %s frame type", "control"); break; } } @@ -533,7 +533,7 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) break; default: - LOG_WRN("Unknown DLCI frame type"); + LOG_WRN("Unknown %s frame type", "DLCI"); break; } } From b59810650ddf361cc0d4aaafe0282a55ec459b7a Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Tue, 24 Oct 2023 19:01:32 +0800 Subject: [PATCH 2532/4498] drivers: can: support for Nuvoton numaker series Add Nuvoton numaker series can-fd controller based on mcan. Signed-off-by: cyliang tw --- .../numaker_pfm_m467-pinctrl.dtsi | 8 + .../arm/numaker_pfm_m467/numaker_pfm_m467.dts | 9 + drivers/can/CMakeLists.txt | 1 + drivers/can/Kconfig | 1 + drivers/can/Kconfig.numaker | 13 + drivers/can/can_numaker.c | 299 ++++++++++++++++++ dts/arm/nuvoton/m46x.dtsi | 64 ++++ dts/bindings/can/nuvoton,numaker-canfd.yaml | 21 ++ 8 files changed, 416 insertions(+) create mode 100644 drivers/can/Kconfig.numaker create mode 100644 drivers/can/can_numaker.c create mode 100644 dts/bindings/can/nuvoton,numaker-canfd.yaml diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi b/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi index 8aff684b1a9..190e4262cad 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi @@ -24,4 +24,12 @@ ; }; }; + + /* CAN TX/RX --> PJ10/PJ11 */ + canfd0_default: canfd0_default { + group0 { + pinmux = , + ; + }; + }; }; diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts index 860ca7579f1..f6e7a4eb799 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts @@ -29,6 +29,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,canbus = &canfd0; }; @@ -108,3 +109,11 @@ pinctrl-names = "default"; status = "okay"; }; + +&canfd0 { + bus-speed = <125000>; + bus-speed-data = <1000000>; + pinctrl-0 = <&canfd0_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index e0420efe784..c7d9de93f2e 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -19,6 +19,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_STM32_FDCAN can_stm32_fdcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32H7_FDCAN can_stm32h7_fdcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_TCAN4X5X can_tcan4x5x.c) zephyr_library_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) +zephyr_library_sources_ifdef(CONFIG_CAN_NUMAKER can_numaker.c) if(CONFIG_CAN_NATIVE_POSIX_LINUX) if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Linux) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index 30381b09780..37d9a93f170 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -92,6 +92,7 @@ source "drivers/can/Kconfig.mcux" source "drivers/can/Kconfig.mcp2515" source "drivers/can/Kconfig.mcan" source "drivers/can/Kconfig.rcar" +source "drivers/can/Kconfig.numaker" source "drivers/can/Kconfig.loopback" source "drivers/can/Kconfig.native_posix_linux" source "drivers/can/Kconfig.sja1000" diff --git a/drivers/can/Kconfig.numaker b/drivers/can/Kconfig.numaker new file mode 100644 index 00000000000..c700853c554 --- /dev/null +++ b/drivers/can/Kconfig.numaker @@ -0,0 +1,13 @@ +# NuMaker CAN(-FD) driver configuration options + +# Copyright (c) 2023 Nuvoton Technology Corporation +# SPDX-License-Identifier: Apache-2.0 + +config CAN_NUMAKER + bool "Nuvoton NuMaker CAN-FD driver" + default y + select CAN_MCAN + depends on DT_HAS_NUVOTON_NUMAKER_CANFD_ENABLED + depends on SOC_SERIES_M46X + help + Enables Nuvoton NuMaker CAN-FD driver, using Bosch M_CAN diff --git a/drivers/can/can_numaker.c b/drivers/can/can_numaker.c new file mode 100644 index 00000000000..0bb47d78a04 --- /dev/null +++ b/drivers/can/can_numaker.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_numaker_canfd + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(can_numaker, CONFIG_CAN_LOG_LEVEL); + +/* CANFD Clock Source Selection */ +#define NUMAKER_CANFD_CLKSEL_HXT 0 +#define NUMAKER_CANFD_CLKSEL_PLL_DIV2 1 +#define NUMAKER_CANFD_CLKSEL_HCLK 2 +#define NUMAKER_CANFD_CLKSEL_HIRC 3 + +/* Implementation notes + * 1. Use Bosch M_CAN driver (m_can) as backend + * 2. Need to modify can_numaker_get_core_clock() for new SOC support + */ + +struct can_numaker_config { + mm_reg_t canfd_base; + mem_addr_t mrba; + mem_addr_t mram; + const struct reset_dt_spec reset; + uint32_t clk_modidx; + uint32_t clk_src; + uint32_t clk_div; + const struct device *clk_dev; + void (*irq_config_func)(const struct device *dev); + const struct pinctrl_dev_config *pincfg; +}; + +static int can_numaker_get_core_clock(const struct device *dev, uint32_t *rate) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_numaker_config *config = mcan_config->custom; + uint32_t clksrc_rate_idx; + uint32_t clkdiv_divider; + + /* Module clock source rate */ + clksrc_rate_idx = CLK_GetModuleClockSource(config->clk_modidx); + /* Module clock divider */ + clkdiv_divider = CLK_GetModuleClockDivider(config->clk_modidx) + 1; + + switch (clksrc_rate_idx) { + case NUMAKER_CANFD_CLKSEL_HXT: + *rate = __HXT / clkdiv_divider; + break; + case NUMAKER_CANFD_CLKSEL_PLL_DIV2: + *rate = (CLK_GetPLLClockFreq() / 2) / clkdiv_divider; + break; + case NUMAKER_CANFD_CLKSEL_HCLK: + *rate = CLK_GetHCLKFreq() / clkdiv_divider; + break; + case NUMAKER_CANFD_CLKSEL_HIRC: + *rate = __HIRC / clkdiv_divider; + break; + default: + LOG_ERR("Invalid clock source rate index"); + return -EIO; + } + + LOG_DBG("Clock rate index/divider: %d/%d", clksrc_rate_idx, clkdiv_divider); + + return 0; +} + +static inline int can_numaker_init_unlocked(const struct device *dev) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_numaker_config *config = mcan_config->custom; + struct numaker_scc_subsys scc_subsys; + int rc; + + memset(&scc_subsys, 0x00, sizeof(scc_subsys)); + scc_subsys.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC; + scc_subsys.pcc.clk_modidx = config->clk_modidx; + scc_subsys.pcc.clk_src = config->clk_src; + scc_subsys.pcc.clk_div = config->clk_div; + + /* To enable clock */ + rc = clock_control_on(config->clk_dev, (clock_control_subsys_t) &scc_subsys); + if (rc < 0) { + return rc; + } + /* To set module clock */ + rc = clock_control_configure(config->clk_dev, (clock_control_subsys_t)&scc_subsys, NULL); + if (rc < 0) { + return rc; + } + + /* Configure pinmux (NuMaker's SYS MFP) */ + rc = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; + } + + /* Reset CAN to default state, same as BSP's SYS_ResetModule(id_rst) */ + reset_line_toggle_dt(&config->reset); + + config->irq_config_func(dev); + + rc = can_mcan_configure_mram(dev, config->mrba, config->mram); + if (rc != 0) { + return rc; + } + + rc = can_mcan_init(dev); + if (rc < 0) { + LOG_ERR("Failed to initialize mcan: %d", rc); + return rc; + } + +#if CONFIG_CAN_LOG_LEVEL >= LOG_LEVEL_DBG + uint32_t rate; + + rc = can_numaker_get_core_clock(dev, &rate); + if (rc < 0) { + return rc; + } + + LOG_DBG("CAN core clock: %d", rate); +#endif + + return rc; +} + +static int can_numaker_init(const struct device *dev) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_numaker_config *config = mcan_config->custom; + int rc; + + if (!device_is_ready(config->reset.dev)) { + LOG_ERR("reset controller not ready"); + return -ENODEV; + } + + if (!device_is_ready(config->clk_dev)) { + LOG_ERR("clock controller not ready"); + return -ENODEV; + } + + SYS_UnlockReg(); + rc = can_numaker_init_unlocked(dev); + SYS_LockReg(); + + return rc; +} + +static const struct can_driver_api can_numaker_driver_api = { + .get_capabilities = can_mcan_get_capabilities, + .start = can_mcan_start, + .stop = can_mcan_stop, + .set_mode = can_mcan_set_mode, + .set_timing = can_mcan_set_timing, + .send = can_mcan_send, + .add_rx_filter = can_mcan_add_rx_filter, + .remove_rx_filter = can_mcan_remove_rx_filter, +#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY + .recover = can_mcan_recover, +#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */ + .get_state = can_mcan_get_state, + .set_state_change_callback = can_mcan_set_state_change_callback, + .get_core_clock = can_numaker_get_core_clock, + .get_max_filters = can_mcan_get_max_filters, + .get_max_bitrate = can_mcan_get_max_bitrate, + .timing_min = CAN_MCAN_TIMING_MIN_INITIALIZER, + .timing_max = CAN_MCAN_TIMING_MAX_INITIALIZER, +#ifdef CONFIG_CAN_FD_MODE + .set_timing_data = can_mcan_set_timing_data, + .timing_data_min = CAN_MCAN_TIMING_DATA_MIN_INITIALIZER, + .timing_data_max = CAN_MCAN_TIMING_DATA_MAX_INITIALIZER, +#endif /* CONFIG_CAN_FD_MODE */ +}; + +static int can_numaker_read_reg(const struct device *dev, uint16_t reg, uint32_t *val) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_numaker_config *numaker_cfg = mcan_cfg->custom; + + return can_mcan_sys_read_reg(numaker_cfg->canfd_base, reg, val); +} + +static int can_numaker_write_reg(const struct device *dev, uint16_t reg, uint32_t val) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_numaker_config *numaker_cfg = mcan_cfg->custom; + + return can_mcan_sys_write_reg(numaker_cfg->canfd_base, reg, val); +} + +static int can_numaker_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_numaker_config *numaker_cfg = mcan_cfg->custom; + + return can_mcan_sys_read_mram(numaker_cfg->mram, offset, dst, len); +} + +static int can_numaker_write_mram(const struct device *dev, uint16_t offset, const void *src, + size_t len) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_numaker_config *numaker_cfg = mcan_cfg->custom; + + return can_mcan_sys_write_mram(numaker_cfg->mram, offset, src, len); +} + +static int can_numaker_clear_mram(const struct device *dev, uint16_t offset, size_t len) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_numaker_config *numaker_cfg = mcan_cfg->custom; + + return can_mcan_sys_clear_mram(numaker_cfg->mram, offset, len); +} + +static const struct can_mcan_ops can_numaker_ops = { + .read_reg = can_numaker_read_reg, + .write_reg = can_numaker_write_reg, + .read_mram = can_numaker_read_mram, + .write_mram = can_numaker_write_mram, + .clear_mram = can_numaker_clear_mram, +}; + +#define NUMAKER_CLKCTRL_DEV_INIT(inst) \ + .clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))), + +#define NUMAKER_PINCTRL_DEFINE(inst) \ + PINCTRL_DT_INST_DEFINE(inst); +#define NUMAKER_PINCTRL_INIT(inst) \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), + +#define CAN_NUMAKER_INIT(inst) \ + NUMAKER_PINCTRL_DEFINE(inst); \ + CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_numaker_cbs_##inst); \ + \ + static void can_numaker_irq_config_func_##inst(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 0, irq), \ + DT_INST_IRQ_BY_IDX(inst, 0, priority), \ + can_mcan_line_0_isr, \ + DEVICE_DT_INST_GET(inst), \ + 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 0, irq)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 1, irq), \ + DT_INST_IRQ_BY_IDX(inst, 1, priority), \ + can_mcan_line_1_isr, \ + DEVICE_DT_INST_GET(inst), \ + 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 1, irq)); \ + } \ + \ + static const struct can_numaker_config can_numaker_config_##inst = { \ + .canfd_base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \ + .mrba = CAN_MCAN_DT_INST_MRBA(inst), \ + .mram = CAN_MCAN_DT_INST_MRAM_ADDR(inst), \ + .reset = RESET_DT_SPEC_INST_GET(inst), \ + .clk_modidx = DT_INST_CLOCKS_CELL(inst, clock_module_index), \ + .clk_src = DT_INST_CLOCKS_CELL(inst, clock_source), \ + .clk_div = DT_INST_CLOCKS_CELL(inst, clock_divider), \ + NUMAKER_CLKCTRL_DEV_INIT(inst) \ + .irq_config_func = can_numaker_irq_config_func_##inst, \ + NUMAKER_PINCTRL_INIT(inst) \ + }; \ + \ + static const struct can_mcan_config can_mcan_config_##inst = \ + CAN_MCAN_DT_CONFIG_INST_GET(inst, \ + &can_numaker_config_##inst, \ + &can_numaker_ops, \ + &can_numaker_cbs_##inst); \ + \ + static uint32_t can_numaker_data_##inst; \ + \ + static struct can_mcan_data can_mcan_data_##inst = \ + CAN_MCAN_DATA_INITIALIZER(&can_numaker_data_ ## inst); \ + \ + CAN_DEVICE_DT_INST_DEFINE(inst, \ + &can_numaker_init, \ + NULL, \ + &can_mcan_data_##inst, \ + &can_mcan_config_##inst, \ + POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, \ + &can_numaker_driver_api); \ + +DT_INST_FOREACH_STATUS_OKAY(CAN_NUMAKER_INIT); diff --git a/dts/arm/nuvoton/m46x.dtsi b/dts/arm/nuvoton/m46x.dtsi index 2355a6fd82a..ea0db8bac45 100644 --- a/dts/arm/nuvoton/m46x.dtsi +++ b/dts/arm/nuvoton/m46x.dtsi @@ -428,6 +428,70 @@ #pwm-cells = <3>; status = "disabled"; }; + + canfd0: canfd@40020000 { + compatible = "nuvoton,numaker-canfd"; + reg = <0x40020000 0x200>, <0x40020200 0x1800>; + reg-names = "m_can", "message_ram"; + interrupts = <112 0>, <113 0>; + interrupt-names = "LINE_0", "LINE_1"; + resets = <&rst NUMAKER_CANFD0_RST>; + clocks = <&pcc NUMAKER_CANFD0_MODULE + NUMAKER_CLK_CLKSEL0_CANFD0SEL_HCLK + NUMAKER_CLK_CLKDIV5_CANFD0(1)>; + bosch,mram-cfg = <0x0 12 10 3 3 3 3 3>; + status = "disabled"; + sample-point = <875>; + sample-point-data = <875>; + }; + + canfd1: canfd@40024000 { + compatible = "nuvoton,numaker-canfd"; + reg = <0x40024000 0x200>, <0x40024200 0x1800>; + reg-names = "m_can", "message_ram"; + interrupts = <114 0>, <115 0>; + interrupt-names = "LINE_0", "LINE_1"; + resets = <&rst NUMAKER_CANFD1_RST>; + clocks = <&pcc NUMAKER_CANFD1_MODULE + NUMAKER_CLK_CLKSEL0_CANFD1SEL_HCLK + NUMAKER_CLK_CLKDIV5_CANFD1(1)>; + bosch,mram-cfg = <0x0 12 10 3 3 3 3 3>; + status = "disabled"; + sample-point = <875>; + sample-point-data = <875>; + }; + + canfd2: canfd@40028000 { + compatible = "nuvoton,numaker-canfd"; + reg = <0x40028000 0x200>, <0x40028200 0x1800>; + reg-names = "m_can", "message_ram"; + interrupts = <120 0>, <121 0>; + interrupt-names = "LINE_0", "LINE_1"; + resets = <&rst NUMAKER_CANFD2_RST>; + clocks = <&pcc NUMAKER_CANFD2_MODULE + NUMAKER_CLK_CLKSEL0_CANFD2SEL_HCLK + NUMAKER_CLK_CLKDIV5_CANFD2(1)>; + bosch,mram-cfg = <0x0 12 10 3 3 3 3 3>; + status = "disabled"; + sample-point = <875>; + sample-point-data = <875>; + }; + + canfd3: canfd@4002c000 { + compatible = "nuvoton,numaker-canfd"; + reg = <0x4002c000 0x200>, <0x4002c200 0x1800>; + reg-names = "m_can", "message_ram"; + interrupts = <122 0>, <123 0>; + interrupt-names = "LINE_0", "LINE_1"; + resets = <&rst NUMAKER_CANFD3_RST>; + clocks = <&pcc NUMAKER_CANFD3_MODULE + NUMAKER_CLK_CLKSEL0_CANFD3SEL_HCLK + NUMAKER_CLK_CLKDIV5_CANFD3(1)>; + bosch,mram-cfg = <0x0 12 10 3 3 3 3 3>; + status = "disabled"; + sample-point = <875>; + sample-point-data = <875>; + }; }; }; diff --git a/dts/bindings/can/nuvoton,numaker-canfd.yaml b/dts/bindings/can/nuvoton,numaker-canfd.yaml new file mode 100644 index 00000000000..dbfa39259c0 --- /dev/null +++ b/dts/bindings/can/nuvoton,numaker-canfd.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Nuvoton Technology Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Nuvoton NuMaker CAN-FD controller, using Bosch M_CAN IP + +compatible: "nuvoton,numaker-canfd" + +include: ["bosch,m_can-base.yaml", reset-device.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + resets: + required: true + + clocks: + required: true From 4974bc01370d779ad67c082491d4ceecb47b20b8 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Mon, 23 Oct 2023 18:48:50 +0300 Subject: [PATCH 2533/4498] linker: common-rom: Keep z_shared_isr regardless of dynamic interrupts Currently, the z_shared_isr symbol is only kept if CONFIG_DYNAMIC_INTERRUPTS=n. Whenever CONFG_DYNAMIC_INTERRUPTS is set to 'y', said symbol gets dropped when zephyr_pre0.elf is created. This is wrong because dropping/keeping z_shared_isr shouldn't be influenced by enabling/disabling support for the dynamic interrupts. This commit fixes the aforementioned issue by removing the dependency on CONFIG_DYNAMIC_INTERRUPTS. Signed-off-by: Laurentiu Mihalcea --- .../common-rom/common-rom-kernel-devices.ld | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 8adcaf5b1fb..cd5c610d3f6 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -22,6 +22,26 @@ ITERABLE_SECTION_ROM_NUMERIC(device, 4) +#if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_SHARED_INTERRUPTS) + /* since z_shared_isr() is not referenced anywhere when + * zephyr_pre0.elf is built, the linker will end up dropping it. + * Later on, during the second linking stage (when zephyr.elf is + * built), the symbol will be added to the text section since it's + * now being referenced (thanks to isr_tables.c). This is very + * problematic because adding the z_shared_isr symbol between + * the linking stages will end up shifting the addresses of the + * functions, which, in turn, will end up messing the ISR table + * (as the entries from _sw_isr_table will end up pointing to + * old addresses of the registered ISRs). To prevent this from + * happening, instruct the linker to avoid dropping z_shared_isr + * if it's not being referenced anywhere. + */ + SECTION_PROLOGUE(.text.z_shared_isr,,) + { + KEEP(*(.text.z_shared_isr)) + } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif + #if defined(CONFIG_GEN_SW_ISR_TABLE) && !defined(CONFIG_DYNAMIC_INTERRUPTS) SECTION_PROLOGUE(sw_isr_table,,) { @@ -40,11 +60,6 @@ /* TODO: does this section require alignment? */ KEEP(*(_SHARED_SW_ISR_TABLE_SECTION_SYMS)) } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - - SECTION_PROLOGUE(.text.z_shared_isr,,) - { - KEEP(*(.text.z_shared_isr)) - } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) #endif #endif From 31a92fc5e3b0ea7fb4e91c28aa414bc915086d36 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 24 Oct 2023 10:09:28 -0700 Subject: [PATCH 2534/4498] doc: vuln: Add information about CVE-2023-5753 Information about CVE-2023-5753 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 669383e7d0f..956a4aee569 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1547,3 +1547,17 @@ This has been fixed in main for v3.5.0 - `PR 63717 fix for 3.3 `_ + +CVE-2023-5753 +------------- + +Potential buffer overflow vulnerabilities in the Zephyr Bluetooth +subsystem source code when asserts are disabled. + +- `Zephyr project bug tracker GHSA-hmpr-px56-rvww + `_ + +This has been fixed in main for v3.5.0 + +- `PR 63605 fix for main + `_ From 27dedec4cc251b0e5ce9b99969e3b8755e0155e8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 24 Oct 2023 10:13:06 -0700 Subject: [PATCH 2535/4498] doc: release: 3.5: Add info about CVE-2023-5753 Update 3.5 release notes with published CVE Signed-off-by: Flavio Ceolin --- doc/releases/release-notes-3.5.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index eddebb7bc74..d7993bd7804 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -68,6 +68,9 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2023-5563 `Zephyr project bug tracker GHSA-98mc-rj7w-7rpv `_ +* CVE-2023-5753 `Zephyr project bug tracker GHSA-hmpr-px56-rvww + `_ + Kernel ****** From 88b05b3b91ce3e7491c54544a083dd26ce2aff98 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 2 Oct 2023 11:18:07 -0700 Subject: [PATCH 2536/4498] kernel: disable THREAD_USERSPACE_LOCAL_DATA if LIBC_ERRNO Thread userspace local data is to be used with storing errno per thread without thread local storage support. However, if the C library has native errno support, there is no need to enable thread userspace local data to store errno per thread. Therefore, amend the default for CONFIG_THREAD_USERSPACE_LOCAL_DATA so that it is not enabled if the C library has native errno support. Signed-off-by: Daniel Leung --- kernel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/Kconfig b/kernel/Kconfig index 2178b041cfd..211830cfe86 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -201,7 +201,7 @@ config THREAD_CUSTOM_DATA config THREAD_USERSPACE_LOCAL_DATA bool depends on USERSPACE - default y if ERRNO && !ERRNO_IN_TLS + default y if ERRNO && !ERRNO_IN_TLS && !LIBC_ERRNO config DYNAMIC_THREAD bool "Support for dynamic threads [EXPERIMENTAL]" From 1e40199c8dd97c47c7177fc7a6b3ac2bfbe4113f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Sep 2023 15:14:09 -0700 Subject: [PATCH 2537/4498] libc: Add REQUIRES_FLOAT_PRINTF to indirectly set printf support Instead of making applications use C library specific settings to enable floating point support in printf, provide this indirect symbol which then detects which C library is in use and selects the correct configuration for each. Signed-off-by: Keith Packard --- lib/libc/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 1ee19062e38..7c5f92f7e97 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -10,6 +10,15 @@ config REQUIRES_FULL_LIBC Select a C library implementation that provides a complete C library implementation, rather than the subset provided by MINIMAL_LIBC. +config REQUIRES_FLOAT_PRINTF + bool "Requires floating point support in printf" + select PICOLIBC_IO_FLOAT if PICOLIBC + select CBPRINTF_FP_SUPPORT if MINIMAL_LIBC + select NEWLIB_LIBC_FLOAT_PRINTF if NEWLIB_LIBC + help + Select a printf implementation that provides a complete + implementation including floating point support. + config FULL_LIBC_SUPPORTED bool help From be4b76fea259283dccd7c1d27640ccc708daf787 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 12 Oct 2023 11:55:04 -0700 Subject: [PATCH 2538/4498] Kconfig.zephyr: Add NATIVE_LIBC and NATIVE_LIBCPP These are set when building against the host C or C++ libraries. This allows filtering tests that require use of a C library that sits atop Zephyr OS APIs. Signed-off-by: Keith Packard --- Kconfig.zephyr | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 4b6976a503f..4710cc82149 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -316,10 +316,22 @@ config CODING_GUIDELINE_CHECK Use available compiler flags to check coding guideline rules during the build. -config NATIVE_BUILD +config NATIVE_LIBC bool select FULL_LIBC_SUPPORTED - select FULL_LIBCPP_SUPPORTED if CPP + help + Zephyr will use the host system C library. + +config NATIVE_LIBCPP + bool + select FULL_LIBCPP_SUPPORTED + help + Zephyr will use the host system C++ library + +config NATIVE_BUILD + bool + select NATIVE_LIBC if EXTERNAL_LIBC + select NATIVE_LIBCPP if EXTERNAL_LIBCPP help Zephyr will be built targeting the host system for debug and development purposes. From 565c9376f1a6da4d67cae08126fcb342c0c27658 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Sep 2023 16:26:48 -0700 Subject: [PATCH 2539/4498] tests: Switch from NEWLIB_LIBC to REQUIRES_FULL_LIBC Instead of forcing use of NEWLIB_LIBC, select any available complete C library implementation. Add CONFIG_REQUIRES_FLOAT_PRINTF where needed. Signed-off-by: Keith Packard --- tests/benchmarks/cmsis_dsp/basicmath/prj.conf | 2 +- .../cmsis_dsp/basicmath/testcase.yaml | 2 +- .../bluetooth/shell/boards/native_posix.conf | 4 +- .../nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 +- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 +- .../net/sockets/echo_test/overlay-ot.conf | 2 +- tests/lib/cmsis_dsp/bayes/prj.conf | 2 +- tests/lib/cmsis_dsp/bayes/testcase.yaml | 6 +- tests/lib/cmsis_dsp/complexmath/prj.conf | 2 +- tests/lib/cmsis_dsp/complexmath/testcase.yaml | 6 +- tests/lib/cmsis_dsp/distance/prj.conf | 2 +- tests/lib/cmsis_dsp/distance/testcase.yaml | 6 +- tests/lib/cmsis_dsp/fastmath/prj.conf | 2 +- tests/lib/cmsis_dsp/fastmath/testcase.yaml | 6 +- tests/lib/cmsis_dsp/filtering/prj.conf | 2 +- tests/lib/cmsis_dsp/filtering/prj_base.conf | 2 +- tests/lib/cmsis_dsp/filtering/testcase.yaml | 28 ++++---- tests/lib/cmsis_dsp/interpolation/prj.conf | 2 +- .../lib/cmsis_dsp/interpolation/testcase.yaml | 6 +- tests/lib/cmsis_dsp/matrix/prj.conf | 2 +- tests/lib/cmsis_dsp/matrix/prj_base.conf | 2 +- tests/lib/cmsis_dsp/matrix/testcase.yaml | 72 +++++++++---------- tests/lib/cmsis_dsp/quaternionmath/prj.conf | 2 +- .../cmsis_dsp/quaternionmath/testcase.yaml | 6 +- tests/lib/cmsis_dsp/statistics/prj.conf | 2 +- tests/lib/cmsis_dsp/statistics/testcase.yaml | 9 +-- tests/lib/cmsis_dsp/support/prj.conf | 2 +- tests/lib/cmsis_dsp/support/testcase.yaml | 6 +- tests/lib/cmsis_dsp/svm/prj.conf | 2 +- tests/lib/cmsis_dsp/svm/testcase.yaml | 6 +- tests/lib/cmsis_dsp/transform/prj.conf | 2 +- tests/lib/cmsis_dsp/transform/prj_base.conf | 2 +- tests/lib/cmsis_dsp/transform/testcase.yaml | 60 ++++++++-------- tests/lib/cmsis_nn/prj.conf | 2 +- tests/lib/cmsis_nn/testcase.yaml | 2 +- tests/lib/gui/lvgl/testcase.yaml | 4 +- tests/lib/hash_map/testcase.yaml | 5 +- tests/lib/thrift/ThriftTest/prj.conf | 4 +- tests/lib/thrift/ThriftTest/testcase.yaml | 3 +- tests/net/lib/coap/testcase.yaml | 2 - tests/net/socket/getaddrinfo/prj.conf | 4 +- tests/net/socket/getaddrinfo/testcase.yaml | 2 +- tests/net/socket/getnameinfo/prj.conf | 2 +- tests/net/socket/getnameinfo/testcase.yaml | 2 +- tests/net/socket/misc/prj.conf | 2 +- tests/net/socket/misc/testcase.yaml | 2 +- tests/net/socket/reuseaddr_reuseport/prj.conf | 2 +- .../socket/reuseaddr_reuseport/testcase.yaml | 2 +- tests/net/socket/select/prj.conf | 2 +- tests/net/socket/select/testcase.yaml | 2 +- tests/net/socket/socketpair/testcase.yaml | 4 +- tests/net/socket/tcp/prj.conf | 2 +- tests/net/socket/tcp/testcase.yaml | 2 +- tests/net/socket/tls/prj.conf | 2 +- tests/net/socket/tls/testcase.yaml | 2 +- tests/net/socket/udp/prj.conf | 2 +- tests/net/socket/udp/testcase.yaml | 2 +- tests/subsys/dsp/basicmath/prj.conf | 2 +- tests/subsys/dsp/basicmath/testcase.yaml | 4 +- tests/subsys/dsp/print_format/prj.conf | 2 +- tests/subsys/dsp/print_format/testcase.yaml | 2 +- tests/subsys/jwt/prj.conf | 2 +- tests/subsys/jwt/testcase.yaml | 2 +- 63 files changed, 167 insertions(+), 172 deletions(-) diff --git a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/benchmarks/cmsis_dsp/basicmath/prj.conf +++ b/tests/benchmarks/cmsis_dsp/basicmath/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml b/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml index 674cba76dde..c2527111322 100644 --- a/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml +++ b/tests/benchmarks/cmsis_dsp/basicmath/testcase.yaml @@ -1,6 +1,6 @@ common: arch_allow: arm - filter: (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB + filter: (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED == 1 tags: - benchmark diff --git a/tests/bluetooth/shell/boards/native_posix.conf b/tests/bluetooth/shell/boards/native_posix.conf index f35bf051edc..64bcdc82d29 100644 --- a/tests/bluetooth/shell/boards/native_posix.conf +++ b/tests/bluetooth/shell/boards/native_posix.conf @@ -14,5 +14,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf b/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bsim/net/sockets/echo_test/overlay-ot.conf b/tests/bsim/net/sockets/echo_test/overlay-ot.conf index 83ead1cf289..fb74b5f12d2 100644 --- a/tests/bsim/net/sockets/echo_test/overlay-ot.conf +++ b/tests/bsim/net/sockets/echo_test/overlay-ot.conf @@ -1,6 +1,6 @@ # This file content is just a copy of the echo client overlay-ot.conf -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Disable TCP and IPv4 (TCP disabled to avoid heavy traffic) CONFIG_NET_TCP=n diff --git a/tests/lib/cmsis_dsp/bayes/prj.conf b/tests/lib/cmsis_dsp/bayes/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/bayes/prj.conf +++ b/tests/lib/cmsis_dsp/bayes/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/bayes/testcase.yaml b/tests/lib/cmsis_dsp/bayes/testcase.yaml index 97582355f73..8bc620caac7 100644 --- a/tests/lib/cmsis_dsp/bayes/testcase.yaml +++ b/tests/lib/cmsis_dsp/bayes/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.bayes: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 32 libraries.cmsis_dsp.bayes.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/complexmath/prj.conf b/tests/lib/cmsis_dsp/complexmath/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/complexmath/prj.conf +++ b/tests/lib/cmsis_dsp/complexmath/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/complexmath/testcase.yaml b/tests/lib/cmsis_dsp/complexmath/testcase.yaml index d03cd223a08..13f98d88b2b 100644 --- a/tests/lib/cmsis_dsp/complexmath/testcase.yaml +++ b/tests/lib/cmsis_dsp/complexmath/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.complexmath: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 144 libraries.cmsis_dsp.complexmath.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/distance/prj.conf b/tests/lib/cmsis_dsp/distance/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/distance/prj.conf +++ b/tests/lib/cmsis_dsp/distance/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/distance/testcase.yaml b/tests/lib/cmsis_dsp/distance/testcase.yaml index e0feb91dd32..cbc956055fb 100644 --- a/tests/lib/cmsis_dsp/distance/testcase.yaml +++ b/tests/lib/cmsis_dsp/distance/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.distance: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 32 libraries.cmsis_dsp.distance.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/fastmath/prj.conf b/tests/lib/cmsis_dsp/fastmath/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/fastmath/prj.conf +++ b/tests/lib/cmsis_dsp/fastmath/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/fastmath/testcase.yaml b/tests/lib/cmsis_dsp/fastmath/testcase.yaml index 3c363bdda3a..d63115edc42 100644 --- a/tests/lib/cmsis_dsp/fastmath/testcase.yaml +++ b/tests/lib/cmsis_dsp/fastmath/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.fastmath: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 64 libraries.cmsis_dsp.fastmath.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/filtering/prj.conf b/tests/lib/cmsis_dsp/filtering/prj.conf index e9e39e0e354..4b0e8a8121d 100644 --- a/tests/lib/cmsis_dsp/filtering/prj.conf +++ b/tests/lib/cmsis_dsp/filtering/prj.conf @@ -1,5 +1,5 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y # Test Options diff --git a/tests/lib/cmsis_dsp/filtering/prj_base.conf b/tests/lib/cmsis_dsp/filtering/prj_base.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/filtering/prj_base.conf +++ b/tests/lib/cmsis_dsp/filtering/prj_base.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/filtering/testcase.yaml b/tests/lib/cmsis_dsp/filtering/testcase.yaml index 80705309a45..15b42c278ee 100644 --- a/tests/lib/cmsis_dsp/filtering/testcase.yaml +++ b/tests/lib/cmsis_dsp/filtering/testcase.yaml @@ -3,13 +3,13 @@ common: tests: libraries.cmsis_dsp.filtering: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX tags: cmsis_dsp skip: true libraries.cmsis_dsp.filtering.biquad: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -23,7 +23,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_BIQUAD=y libraries.cmsis_dsp.filtering.biquad.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -37,8 +37,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_BIQUAD=y - CONFIG_FPU=y libraries.cmsis_dsp.filtering.decim: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -52,7 +52,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_DECIM=y libraries.cmsis_dsp.filtering.decim.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -66,8 +66,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_DECIM=y - CONFIG_FPU=y libraries.cmsis_dsp.filtering.fir: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -81,7 +81,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_FIR=y libraries.cmsis_dsp.filtering.fir.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -95,8 +95,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_FIR=y - CONFIG_FPU=y libraries.cmsis_dsp.filtering.misc: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -110,7 +110,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_FILTERING_MISC=y libraries.cmsis_dsp.filtering.misc.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/interpolation/prj.conf b/tests/lib/cmsis_dsp/interpolation/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/interpolation/prj.conf +++ b/tests/lib/cmsis_dsp/interpolation/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/interpolation/testcase.yaml b/tests/lib/cmsis_dsp/interpolation/testcase.yaml index ef4b94ff3a6..358a683c7ce 100644 --- a/tests/lib/cmsis_dsp/interpolation/testcase.yaml +++ b/tests/lib/cmsis_dsp/interpolation/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.interpolation: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 64 libraries.cmsis_dsp.interpolation.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/matrix/prj.conf b/tests/lib/cmsis_dsp/matrix/prj.conf index 40ed01f715e..e6cfe7a6774 100644 --- a/tests/lib/cmsis_dsp/matrix/prj.conf +++ b/tests/lib/cmsis_dsp/matrix/prj.conf @@ -1,5 +1,5 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y # Test Options diff --git a/tests/lib/cmsis_dsp/matrix/prj_base.conf b/tests/lib/cmsis_dsp/matrix/prj_base.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/matrix/prj_base.conf +++ b/tests/lib/cmsis_dsp/matrix/prj_base.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/matrix/testcase.yaml b/tests/lib/cmsis_dsp/matrix/testcase.yaml index cf3365fc923..4a6912505e0 100644 --- a/tests/lib/cmsis_dsp/matrix/testcase.yaml +++ b/tests/lib/cmsis_dsp/matrix/testcase.yaml @@ -1,12 +1,12 @@ tests: libraries.cmsis_dsp.matrix: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX tags: cmsis_dsp skip: true libraries.cmsis_dsp.matrix.unary_q7: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -20,7 +20,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q7=y libraries.cmsis_dsp.matrix.unary_q7.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -34,8 +34,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q7=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.unary_q15: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -49,7 +49,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q15=y libraries.cmsis_dsp.matrix.unary_q15.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -63,8 +63,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q15=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.unary_q31: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -78,7 +78,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_Q31=y libraries.cmsis_dsp.matrix.unary_q31.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -93,7 +93,7 @@ tests: - CONFIG_FPU=y libraries.cmsis_dsp.matrix.unary_f16: filter: (CONFIG_CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - frdm_k64f - sam_e70_xplained @@ -106,7 +106,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F16=y libraries.cmsis_dsp.matrix.unary_f16.fpu: filter: (CONFIG_CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_CPU_HAS_FPU and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - mps2_an521_remote - mps3_an547 @@ -120,8 +120,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F16=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.unary_f32: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -135,7 +135,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F32=y libraries.cmsis_dsp.matrix.unary_f32.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -149,8 +149,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F32=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.unary_f64: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -164,7 +164,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F64=y libraries.cmsis_dsp.matrix.unary_f64.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -178,8 +178,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_UNARY_F64=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_q7: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -194,7 +194,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_Q7=y libraries.cmsis_dsp.matrix.binary_q7.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -209,8 +209,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_Q7=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_q15: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -225,7 +225,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_Q15=y libraries.cmsis_dsp.matrix.binary_q15.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -240,8 +240,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_Q15=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_q31: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -256,7 +256,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_Q31=y libraries.cmsis_dsp.matrix.binary_q31.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -272,7 +272,7 @@ tests: - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_f16: filter: (CONFIG_CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - frdm_k64f - sam_e70_xplained @@ -285,7 +285,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_F16=y libraries.cmsis_dsp.matrix.binary_f16.fpu: filter: (CONFIG_CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_CPU_HAS_FPU and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - mps2_an521_remote - mps3_an547 @@ -299,8 +299,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_F16=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_f32: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -315,7 +315,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_F32=y libraries.cmsis_dsp.matrix.binary_f32.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 @@ -330,8 +330,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_F32=y - CONFIG_FPU=y libraries.cmsis_dsp.matrix.binary_f64: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -346,7 +346,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_MATRIX_BINARY_F64=y libraries.cmsis_dsp.matrix.binary_f64.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/quaternionmath/prj.conf b/tests/lib/cmsis_dsp/quaternionmath/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/quaternionmath/prj.conf +++ b/tests/lib/cmsis_dsp/quaternionmath/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/quaternionmath/testcase.yaml b/tests/lib/cmsis_dsp/quaternionmath/testcase.yaml index 9c2ebb958dc..3d005e8a343 100644 --- a/tests/lib/cmsis_dsp/quaternionmath/testcase.yaml +++ b/tests/lib/cmsis_dsp/quaternionmath/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.quaternionmath: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 64 libraries.cmsis_dsp.quaternionmath.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/statistics/prj.conf b/tests/lib/cmsis_dsp/statistics/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/statistics/prj.conf +++ b/tests/lib/cmsis_dsp/statistics/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/statistics/testcase.yaml b/tests/lib/cmsis_dsp/statistics/testcase.yaml index 7d23dd7155d..9082e8edf5f 100644 --- a/tests/lib/cmsis_dsp/statistics/testcase.yaml +++ b/tests/lib/cmsis_dsp/statistics/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.statistics: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -11,8 +11,9 @@ tests: min_flash: 128 min_ram: 64 libraries.cmsis_dsp.statistics.fpu: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) + and CONFIG_CPU_HAS_FPU + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/support/prj.conf b/tests/lib/cmsis_dsp/support/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/support/prj.conf +++ b/tests/lib/cmsis_dsp/support/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/support/testcase.yaml b/tests/lib/cmsis_dsp/support/testcase.yaml index 87839c923f0..1fed8894b42 100644 --- a/tests/lib/cmsis_dsp/support/testcase.yaml +++ b/tests/lib/cmsis_dsp/support/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.support: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 128 libraries.cmsis_dsp.support.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/svm/prj.conf b/tests/lib/cmsis_dsp/svm/prj.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/svm/prj.conf +++ b/tests/lib/cmsis_dsp/svm/prj.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/svm/testcase.yaml b/tests/lib/cmsis_dsp/svm/testcase.yaml index 61d14b9777f..c107678e449 100644 --- a/tests/lib/cmsis_dsp/svm/testcase.yaml +++ b/tests/lib/cmsis_dsp/svm/testcase.yaml @@ -1,7 +1,7 @@ tests: libraries.cmsis_dsp.svm: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -12,7 +12,7 @@ tests: min_ram: 64 libraries.cmsis_dsp.svm.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/lib/cmsis_dsp/transform/prj.conf b/tests/lib/cmsis_dsp/transform/prj.conf index 6a515162015..5eaeb1a352f 100644 --- a/tests/lib/cmsis_dsp/transform/prj.conf +++ b/tests/lib/cmsis_dsp/transform/prj.conf @@ -1,5 +1,5 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y # Test Options diff --git a/tests/lib/cmsis_dsp/transform/prj_base.conf b/tests/lib/cmsis_dsp/transform/prj_base.conf index 7a253195e00..b2e3d9799b8 100644 --- a/tests/lib/cmsis_dsp/transform/prj_base.conf +++ b/tests/lib/cmsis_dsp/transform/prj_base.conf @@ -1,3 +1,3 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y diff --git a/tests/lib/cmsis_dsp/transform/testcase.yaml b/tests/lib/cmsis_dsp/transform/testcase.yaml index 3c0904ea875..030eb5b2f77 100644 --- a/tests/lib/cmsis_dsp/transform/testcase.yaml +++ b/tests/lib/cmsis_dsp/transform/testcase.yaml @@ -1,12 +1,12 @@ tests: libraries.cmsis_dsp.transform: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX tags: cmsis_dsp skip: true libraries.cmsis_dsp.transform.cq15: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -20,7 +20,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CQ15=y libraries.cmsis_dsp.transform.cq15.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps3_an547 tags: @@ -33,8 +33,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CQ15=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.rq15: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -48,7 +48,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RQ15=y libraries.cmsis_dsp.transform.rq15.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps3_an547 tags: @@ -61,8 +61,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RQ15=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.cq31: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -76,7 +76,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CQ31=y libraries.cmsis_dsp.transform.cq31.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX tags: - cmsis_dsp - fpu @@ -87,8 +87,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CQ31=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.rq31: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -102,7 +102,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RQ31=y libraries.cmsis_dsp.transform.rq31.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX tags: - cmsis_dsp - fpu @@ -114,7 +114,7 @@ tests: - CONFIG_FPU=y libraries.cmsis_dsp.transform.cf16: filter: (CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - frdm_k64f - sam_e70_xplained @@ -127,7 +127,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CF16=y libraries.cmsis_dsp.transform.cf16.fpu: filter: (CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_CPU_HAS_FPU and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - mps3_an547 tags: @@ -141,7 +141,7 @@ tests: - CONFIG_FPU=y libraries.cmsis_dsp.transform.rf16: filter: (CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - frdm_k64f - sam_e70_xplained @@ -154,7 +154,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RF16=y libraries.cmsis_dsp.transform.rf16.fpu: filter: (CMSIS_DSP_FLOAT16 and (CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) - and CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) + and CONFIG_CPU_HAS_FPU and CONFIG_FULL_LIBC_SUPPORTED) integration_platforms: - mps3_an547 tags: @@ -167,8 +167,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RF16=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.cf32: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -182,7 +182,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CF32=y libraries.cmsis_dsp.transform.cf32.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX tags: - cmsis_dsp - fpu @@ -193,8 +193,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CF32=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.rf32: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -208,7 +208,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RF32=y libraries.cmsis_dsp.transform.rf32.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps3_an547 tags: @@ -221,8 +221,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RF32=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.cf64: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -236,7 +236,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CF64=y libraries.cmsis_dsp.transform.cf64.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX tags: - cmsis_dsp - fpu @@ -247,8 +247,8 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_CF64=y - CONFIG_FPU=y libraries.cmsis_dsp.transform.rf64: - filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and TOOLCHAIN_HAS_NEWLIB - == 1) or CONFIG_ARCH_POSIX + filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_FULL_LIBC_SUPPORTED + ) or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -262,7 +262,7 @@ tests: - CONFIG_CMSIS_DSP_TEST_TRANSFORM_RF64=y libraries.cmsis_dsp.transform.rf64.fpu: filter: ((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and CONFIG_CPU_HAS_FPU - and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX tags: - cmsis_dsp - fpu diff --git a/tests/lib/cmsis_nn/prj.conf b/tests/lib/cmsis_nn/prj.conf index b8dea680868..557435173ad 100644 --- a/tests/lib/cmsis_nn/prj.conf +++ b/tests/lib/cmsis_nn/prj.conf @@ -1,5 +1,5 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_CMSIS_DSP=y CONFIG_CMSIS_NN=y CONFIG_CMSIS_NN_ACTIVATION=y diff --git a/tests/lib/cmsis_nn/testcase.yaml b/tests/lib/cmsis_nn/testcase.yaml index 0cb8036b186..438c267ef5c 100644 --- a/tests/lib/cmsis_nn/testcase.yaml +++ b/tests/lib/cmsis_nn/testcase.yaml @@ -1,6 +1,6 @@ tests: libraries.cmsis_nn: - filter: CONFIG_CPU_CORTEX_M and TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_CPU_CORTEX_M and CONFIG_FULL_LIBC_SUPPORTED integration_platforms: - frdm_k64f - sam_e70_xplained diff --git a/tests/lib/gui/lvgl/testcase.yaml b/tests/lib/gui/lvgl/testcase.yaml index 898c6d58806..4b35bcb7d10 100644 --- a/tests/lib/gui/lvgl/testcase.yaml +++ b/tests/lib/gui/lvgl/testcase.yaml @@ -5,13 +5,13 @@ tests: - gui platform_allow: native_posix_64 libraries.gui.lvgl.dynamic.heap.libc: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED tags: - display - gui platform_allow: native_posix_64 extra_configs: - - CONFIG_NEWLIB_LIBC=y + - CONFIG_REQUIRES_FULL_LIBC=y - CONFIG_LV_Z_BUFFER_ALLOC_DYNAMIC=y - CONFIG_LV_Z_MEM_POOL_HEAP_LIB_C=y libraries.gui.lvgl.dynamic.pool.sys_heap: diff --git a/tests/lib/hash_map/testcase.yaml b/tests/lib/hash_map/testcase.yaml index 06f3ce5bfca..d952bb28887 100644 --- a/tests/lib/hash_map/testcase.yaml +++ b/tests/lib/hash_map/testcase.yaml @@ -19,9 +19,8 @@ tests: - CONFIG_SYS_HASH_MAP_CHOICE_OA_LP=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.cxx.djb2: - # need newlib for the c++ runtime - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBCPP_SUPPORTED extra_configs: - - CONFIG_NEWLIB_LIBC=y - CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_CXX=y diff --git a/tests/lib/thrift/ThriftTest/prj.conf b/tests/lib/thrift/ThriftTest/prj.conf index afc07a9d8e0..6619fb8295d 100755 --- a/tests/lib/thrift/ThriftTest/prj.conf +++ b/tests/lib/thrift/ThriftTest/prj.conf @@ -1,5 +1,5 @@ -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_NANO=n +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=65536 # CONFIG_THRIFT Dependencies CONFIG_CPP=y diff --git a/tests/lib/thrift/ThriftTest/testcase.yaml b/tests/lib/thrift/ThriftTest/testcase.yaml index 642f76a92e2..cc92bef771e 100644 --- a/tests/lib/thrift/ThriftTest/testcase.yaml +++ b/tests/lib/thrift/ThriftTest/testcase.yaml @@ -2,10 +2,9 @@ common: tags: - thrift - cpp - - newlib modules: - thrift - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED # qemu_x86 exluded due to missing long double functions in SDK # See https://github.com/zephyrproject-rtos/sdk-ng/issues/603 platform_allow: diff --git a/tests/net/lib/coap/testcase.yaml b/tests/net/lib/coap/testcase.yaml index d3d4d6162b9..add02ecf992 100644 --- a/tests/net/lib/coap/testcase.yaml +++ b/tests/net/lib/coap/testcase.yaml @@ -1,5 +1,3 @@ -common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 tests: net.coap.simple: min_ram: 16 diff --git a/tests/net/socket/getaddrinfo/prj.conf b/tests/net/socket/getaddrinfo/prj.conf index 0de25de2f00..e0430061b1e 100644 --- a/tests/net/socket/getaddrinfo/prj.conf +++ b/tests/net/socket/getaddrinfo/prj.conf @@ -1,6 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_NANO=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y @@ -30,7 +29,6 @@ CONFIG_ZTEST=y # User mode requirements CONFIG_TEST_USERSPACE=y CONFIG_HEAP_MEM_POOL_SIZE=128 -CONFIG_NEWLIB_LIBC_ALIGNED_HEAP_SIZE=2048 # We do not need neighbor discovery etc for this test CONFIG_NET_IPV6_DAD=n diff --git a/tests/net/socket/getaddrinfo/testcase.yaml b/tests/net/socket/getaddrinfo/testcase.yaml index 6cecbe452bf..b22bc2a1661 100644 --- a/tests/net/socket/getaddrinfo/testcase.yaml +++ b/tests/net/socket/getaddrinfo/testcase.yaml @@ -1,6 +1,6 @@ common: depends_on: netif - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED tests: net.socket.get_addr_info: min_ram: 21 diff --git a/tests/net/socket/getnameinfo/prj.conf b/tests/net/socket/getnameinfo/prj.conf index 3b7eb423f45..adc83076810 100644 --- a/tests/net/socket/getnameinfo/prj.conf +++ b/tests/net/socket/getnameinfo/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/getnameinfo/testcase.yaml b/tests/net/socket/getnameinfo/testcase.yaml index 2a8522d79ce..9edc6b2502e 100644 --- a/tests/net/socket/getnameinfo/testcase.yaml +++ b/tests/net/socket/getnameinfo/testcase.yaml @@ -1,6 +1,6 @@ common: depends_on: netif - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED tests: net.socket.get_name_info: min_ram: 21 diff --git a/tests/net/socket/misc/prj.conf b/tests/net/socket/misc/prj.conf index 5d83f5013be..16329ade1c4 100644 --- a/tests/net/socket/misc/prj.conf +++ b/tests/net/socket/misc/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/misc/testcase.yaml b/tests/net/socket/misc/testcase.yaml index 49ae9b6bbe7..db8acadcd62 100644 --- a/tests/net/socket/misc/testcase.yaml +++ b/tests/net/socket/misc/testcase.yaml @@ -1,6 +1,6 @@ common: depends_on: netif - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED min_ram: 21 tags: - net diff --git a/tests/net/socket/reuseaddr_reuseport/prj.conf b/tests/net/socket/reuseaddr_reuseport/prj.conf index 4d852d52e46..f78a1bea312 100644 --- a/tests/net/socket/reuseaddr_reuseport/prj.conf +++ b/tests/net/socket/reuseaddr_reuseport/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/reuseaddr_reuseport/testcase.yaml b/tests/net/socket/reuseaddr_reuseport/testcase.yaml index dc3b15ca139..c1a4808d1d3 100644 --- a/tests/net/socket/reuseaddr_reuseport/testcase.yaml +++ b/tests/net/socket/reuseaddr_reuseport/testcase.yaml @@ -1,6 +1,6 @@ common: depends_on: netif - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED min_ram: 31 tags: - net diff --git a/tests/net/socket/select/prj.conf b/tests/net/socket/select/prj.conf index 7e962eee423..cd642566971 100644 --- a/tests/net/socket/select/prj.conf +++ b/tests/net/socket/select/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/select/testcase.yaml b/tests/net/socket/select/testcase.yaml index af82a6ae51c..eaae57ab9ef 100644 --- a/tests/net/socket/select/testcase.yaml +++ b/tests/net/socket/select/testcase.yaml @@ -5,7 +5,7 @@ common: - net - socket - userspace - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED # FIXME: This test fails very frequently on mps2_an385 due to the system # timer stability issues, so keep it disabled until the root cause # is fixed (GitHub issue zephyrproject-rtos/zephyr#48608). diff --git a/tests/net/socket/socketpair/testcase.yaml b/tests/net/socket/socketpair/testcase.yaml index d2b4462ce2d..5410f938376 100644 --- a/tests/net/socket/socketpair/testcase.yaml +++ b/tests/net/socket/socketpair/testcase.yaml @@ -9,9 +9,9 @@ tests: net.socket.socketpair: platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 net.socket.socketpair.newlib: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - - CONFIG_NEWLIB_LIBC=y + - CONFIG_REQUIRES_FULL_LIBC=y platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 net.socket.socketpair.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED diff --git a/tests/net/socket/tcp/prj.conf b/tests/net/socket/tcp/prj.conf index 9ef9b310916..9f9534aec4c 100644 --- a/tests/net/socket/tcp/prj.conf +++ b/tests/net/socket/tcp/prj.conf @@ -2,7 +2,7 @@ CONFIG_NET_TEST=y # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/tcp/testcase.yaml b/tests/net/socket/tcp/testcase.yaml index 37158751cae..cff7591d938 100644 --- a/tests/net/socket/tcp/testcase.yaml +++ b/tests/net/socket/tcp/testcase.yaml @@ -5,7 +5,7 @@ common: - net - socket - userspace - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED timeout: 180 # FIXME: This test fails very frequently on mps2_an385 due to the system # timer stability issues, so keep it disabled until the root cause diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 842079fabb9..4db53b1442b 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -3,7 +3,7 @@ CONFIG_SMP=n CONFIG_NET_TEST=y # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/tls/testcase.yaml b/tests/net/socket/tls/testcase.yaml index 6554fed5cb5..fd9d615335d 100644 --- a/tests/net/socket/tls/testcase.yaml +++ b/tests/net/socket/tls/testcase.yaml @@ -6,7 +6,7 @@ common: - net - socket - tls - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED integration_platforms: - qemu_x86 tests: diff --git a/tests/net/socket/udp/prj.conf b/tests/net/socket/udp/prj.conf index 35289493288..4f7779fd049 100644 --- a/tests/net/socket/udp/prj.conf +++ b/tests/net/socket/udp/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/tests/net/socket/udp/testcase.yaml b/tests/net/socket/udp/testcase.yaml index 16b3ec9cdb2..253d5698b21 100644 --- a/tests/net/socket/udp/testcase.yaml +++ b/tests/net/socket/udp/testcase.yaml @@ -5,7 +5,7 @@ common: - socket - udp min_ram: 21 - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED tests: net.socket.udp: extra_configs: diff --git a/tests/subsys/dsp/basicmath/prj.conf b/tests/subsys/dsp/basicmath/prj.conf index e2b18830aa0..11333398dee 100644 --- a/tests/subsys/dsp/basicmath/prj.conf +++ b/tests/subsys/dsp/basicmath/prj.conf @@ -1,5 +1,5 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y CONFIG_DSP_BACKEND_CMSIS=y diff --git a/tests/subsys/dsp/basicmath/testcase.yaml b/tests/subsys/dsp/basicmath/testcase.yaml index e99c6d09a0c..ef0996a4b38 100644 --- a/tests/subsys/dsp/basicmath/testcase.yaml +++ b/tests/subsys/dsp/basicmath/testcase.yaml @@ -1,6 +1,6 @@ tests: zdsp.basicmath: - filter: TOOLCHAIN_HAS_NEWLIB == 1 or CONFIG_ARCH_POSIX + filter: CONFIG_FULL_LIBC_SUPPORTED or CONFIG_ARCH_POSIX integration_platforms: - frdm_k64f - sam_e70_xplained @@ -10,7 +10,7 @@ tests: min_flash: 128 min_ram: 64 zdsp.basicmath.fpu: - filter: (CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX + filter: (CONFIG_CPU_HAS_FPU and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote - mps3_an547 diff --git a/tests/subsys/dsp/print_format/prj.conf b/tests/subsys/dsp/print_format/prj.conf index d675ac84890..a957f807430 100644 --- a/tests/subsys/dsp/print_format/prj.conf +++ b/tests/subsys/dsp/print_format/prj.conf @@ -1,4 +1,4 @@ CONFIG_ZTEST=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_DSP=y CONFIG_CMSIS_DSP=y diff --git a/tests/subsys/dsp/print_format/testcase.yaml b/tests/subsys/dsp/print_format/testcase.yaml index 0c45be47262..910e92119b0 100644 --- a/tests/subsys/dsp/print_format/testcase.yaml +++ b/tests/subsys/dsp/print_format/testcase.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 tests: zdsp.print_format: - filter: TOOLCHAIN_HAS_NEWLIB == 1 or CONFIG_ARCH_POSIX + filter: CONFIG_FULL_LIBC_SUPPORTED or CONFIG_ARCH_POSIX tags: zdsp min_flash: 128 min_ram: 64 diff --git a/tests/subsys/jwt/prj.conf b/tests/subsys/jwt/prj.conf index 046cc9ac429..6ac5548143d 100644 --- a/tests/subsys/jwt/prj.conf +++ b/tests/subsys/jwt/prj.conf @@ -19,4 +19,4 @@ CONFIG_MBEDTLS_USER_CONFIG_FILE="user-tls-conf.h" CONFIG_NET_SOCKETS=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/subsys/jwt/testcase.yaml b/tests/subsys/jwt/testcase.yaml index a09a34a898c..f31beee498a 100644 --- a/tests/subsys/jwt/testcase.yaml +++ b/tests/subsys/jwt/testcase.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED tests: libraries.encoding.jwt: min_ram: 96 From 1e5c46df3df8e28c12e965ca4524af7cbdb53805 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Sep 2023 15:27:11 -0700 Subject: [PATCH 2540/4498] samples: Switch from NEWLIB_LIBC to REQUIRES_FULL_LIBC Instead of forcing use of NEWLIB_LIBC, select any available complete C library implementation. Add CONFIG_REQUIRES_FLOAT_PRINTF and adjust CONFIG_LIBC_MALLOC_ARENA_SIZE as needed. Signed-off-by: Keith Packard --- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ++-- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++-- samples/boards/nrf/clock_skew/prj.conf | 4 ++-- samples/compression/lz4/prj.conf | 3 ++- samples/compression/lz4/sample.yaml | 2 +- samples/drivers/counter/maxim_ds3231/prj.conf | 2 +- samples/drivers/counter/maxim_ds3231/sample.yaml | 2 +- samples/modules/tflite-micro/hello_world/README.rst | 2 +- samples/modules/tflite-micro/hello_world/sample.yaml | 2 +- samples/modules/tflite-micro/magic_wand/README.rst | 2 +- samples/modules/tflite-micro/magic_wand/prj.conf | 2 +- samples/net/cloud/aws_iot_mqtt/prj.conf | 2 +- samples/net/cloud/aws_iot_mqtt/sample.yaml | 2 +- samples/net/cloud/mqtt_azure/prj.conf | 2 +- samples/net/cloud/mqtt_azure/sample.yaml | 2 +- samples/net/dsa/prj.conf | 2 +- samples/net/gptp/boards/mimxrt1050_evk.conf | 4 ++-- samples/net/gptp/boards/mimxrt1060_evk.conf | 4 ++-- samples/net/lwm2m_client/overlay-ot.conf | 2 +- samples/net/sockets/big_http_download/prj.conf | 2 +- samples/net/sockets/big_http_download/sample.yaml | 2 +- samples/net/sockets/coap_client/prj.conf | 2 +- samples/net/sockets/coap_client/sample.yaml | 2 +- samples/net/sockets/coap_server/prj.conf | 2 +- samples/net/sockets/coap_server/sample.yaml | 2 +- samples/net/sockets/dumb_http_server/prj.conf | 2 +- samples/net/sockets/dumb_http_server/sample.yaml | 2 +- samples/net/sockets/echo/sample.yaml | 2 +- samples/net/sockets/echo_async/prj.conf | 2 +- samples/net/sockets/echo_async/sample.yaml | 2 +- samples/net/sockets/echo_async_select/prj.conf | 2 +- samples/net/sockets/echo_async_select/sample.yaml | 2 +- samples/net/sockets/echo_client/overlay-ot.conf | 2 +- samples/net/sockets/echo_client/sample.yaml | 6 +++--- samples/net/sockets/echo_server/overlay-ot.conf | 2 +- samples/net/sockets/echo_server/sample.yaml | 6 +++--- samples/net/sockets/http_get/prj.conf | 2 +- samples/net/sockets/http_get/sample.yaml | 2 +- samples/net/sockets/sntp_client/prj.conf | 2 +- samples/net/sockets/tcp/prj.conf | 2 +- samples/net/sockets/tcp/sample.yaml | 2 +- samples/net/syslog_net/prj.conf | 2 +- samples/net/syslog_net/sample.yaml | 12 ++++++------ samples/posix/eventfd/prj.conf | 2 +- samples/posix/eventfd/sample.yaml | 2 +- samples/posix/gettimeofday/prj.conf | 2 +- samples/posix/gettimeofday/sample.yaml | 3 ++- samples/sensor/dht/prj.conf | 4 ++-- samples/sensor/dht/sample.yaml | 2 +- .../die_temp_polling/boards/esp32c3_devkitm.conf | 2 +- .../die_temp_polling/boards/esp32c3_luatos_core.conf | 2 +- .../boards/esp32c3_luatos_core_usb.conf | 2 +- .../die_temp_polling/boards/esp32s2_saola.conf | 2 +- .../die_temp_polling/boards/mimxrt1050_evk.conf | 2 +- samples/sensor/fdc2x1x/prj.conf | 4 ++-- samples/sensor/grove_light/prj.conf | 4 ++-- samples/sensor/grove_light/sample.yaml | 2 +- samples/sensor/grove_temperature/prj.conf | 4 ++-- samples/sensor/grove_temperature/sample.yaml | 2 +- samples/sensor/grove_temperature/src/main.c | 4 ++-- samples/subsys/mgmt/hawkbit/prj.conf | 2 +- samples/subsys/mgmt/hawkbit/sample.yaml | 2 +- samples/tfm_integration/psa_crypto/prj.conf | 2 +- 73 files changed, 104 insertions(+), 102 deletions(-) diff --git a/samples/bluetooth/tmap_bmr/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bmr/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..af60fb49fbd 100644 --- a/samples/bluetooth/tmap_bmr/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bmr/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf index f7c6bbfd3db..fee662d6bab 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/boards/nrf/clock_skew/prj.conf b/samples/boards/nrf/clock_skew/prj.conf index 8ef0d31e37a..957f0d60648 100644 --- a/samples/boards/nrf/clock_skew/prj.conf +++ b/samples/boards/nrf/clock_skew/prj.conf @@ -1,3 +1,3 @@ CONFIG_COUNTER=y -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y diff --git a/samples/compression/lz4/prj.conf b/samples/compression/lz4/prj.conf index 34e20dad07d..a3228945546 100644 --- a/samples/compression/lz4/prj.conf +++ b/samples/compression/lz4/prj.conf @@ -1,3 +1,4 @@ CONFIG_LZ4=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=65536 diff --git a/samples/compression/lz4/sample.yaml b/samples/compression/lz4/sample.yaml index 733646979d5..f9758f26984 100644 --- a/samples/compression/lz4/sample.yaml +++ b/samples/compression/lz4/sample.yaml @@ -6,7 +6,7 @@ common: - compression - lz4 min_ram: 64 - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED harness: console harness_config: type: one_line diff --git a/samples/drivers/counter/maxim_ds3231/prj.conf b/samples/drivers/counter/maxim_ds3231/prj.conf index e858ebb2441..26421607393 100644 --- a/samples/drivers/counter/maxim_ds3231/prj.conf +++ b/samples/drivers/counter/maxim_ds3231/prj.conf @@ -6,7 +6,7 @@ CONFIG_COUNTER_MAXIM_DS3231=y CONFIG_COUNTER_INIT_PRIORITY=65 # Minimal libc doesn't have strftime() -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Optional step that syncs RTC and local clock. Don't enable this if # your RTC has already been synchronized and you want to keep its diff --git a/samples/drivers/counter/maxim_ds3231/sample.yaml b/samples/drivers/counter/maxim_ds3231/sample.yaml index 6e244d62da0..4e9c209047c 100644 --- a/samples/drivers/counter/maxim_ds3231/sample.yaml +++ b/samples/drivers/counter/maxim_ds3231/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: name: Maxim DS3231 RTC tests: diff --git a/samples/modules/tflite-micro/hello_world/README.rst b/samples/modules/tflite-micro/hello_world/README.rst index 6ab9bcbbc2b..9d6fff4db93 100644 --- a/samples/modules/tflite-micro/hello_world/README.rst +++ b/samples/modules/tflite-micro/hello_world/README.rst @@ -94,7 +94,7 @@ TensorFlow, you must enable the below Kconfig options in your :file:`prj.conf`: .. code-block:: kconfig CONFIG_CPP=y - CONFIG_NEWLIB_LIBC=y + CONFIG_REQUIRES_FULL_LIBC=y CONFIG_TENSORFLOW_LITE_MICRO=y Note that the CMSIS-NN kernel sample demonstrates how to use CMSIS-NN optimized kernels with diff --git a/samples/modules/tflite-micro/hello_world/sample.yaml b/samples/modules/tflite-micro/hello_world/sample.yaml index ed70d085631..bfd142f6702 100644 --- a/samples/modules/tflite-micro/hello_world/sample.yaml +++ b/samples/modules/tflite-micro/hello_world/sample.yaml @@ -20,7 +20,7 @@ tests: integration_platforms: - qemu_x86 tags: tensorflow - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample.tensorflow.helloworld.cmsis_nn: tags: tensorflow platform_allow: mps3_an547 diff --git a/samples/modules/tflite-micro/magic_wand/README.rst b/samples/modules/tflite-micro/magic_wand/README.rst index b020f23d9b1..4a3dadbf7c4 100644 --- a/samples/modules/tflite-micro/magic_wand/README.rst +++ b/samples/modules/tflite-micro/magic_wand/README.rst @@ -107,7 +107,7 @@ TensorFlow, you must enable the below Kconfig options in your :file:`prj.conf`: .. code-block:: kconfig CONFIG_CPP=y - CONFIG_NEWLIB_LIBC=y + CONFIG_REQUIRES_FULL_LIBC=y CONFIG_TENSORFLOW_LITE_MICRO=y Training diff --git a/samples/modules/tflite-micro/magic_wand/prj.conf b/samples/modules/tflite-micro/magic_wand/prj.conf index ff2119e62b8..2774abb66e2 100644 --- a/samples/modules/tflite-micro/magic_wand/prj.conf +++ b/samples/modules/tflite-micro/magic_wand/prj.conf @@ -14,7 +14,7 @@ # ============================================================================== CONFIG_CPP=y CONFIG_STD_CPP17=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_SENSOR=y CONFIG_NETWORKING=n CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/net/cloud/aws_iot_mqtt/prj.conf b/samples/net/cloud/aws_iot_mqtt/prj.conf index 8f6bbb82c6b..6738212e44c 100644 --- a/samples/net/cloud/aws_iot_mqtt/prj.conf +++ b/samples/net/cloud/aws_iot_mqtt/prj.conf @@ -9,7 +9,7 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y CONFIG_HW_STACK_PROTECTION=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_SNTP=y CONFIG_JSON_LIBRARY=y CONFIG_POSIX_CLOCK=y diff --git a/samples/net/cloud/aws_iot_mqtt/sample.yaml b/samples/net/cloud/aws_iot_mqtt/sample.yaml index 4dc5c5153ac..c7251fdb305 100644 --- a/samples/net/cloud/aws_iot_mqtt/sample.yaml +++ b/samples/net/cloud/aws_iot_mqtt/sample.yaml @@ -4,7 +4,7 @@ sample: common: tags: net mqtt cloud harness: net - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED && !CONFIG_NATIVE_LIBC extra_args: USE_DUMMY_CREDS=1 tests: sample.net.cloud.aws_iot_mqtt: diff --git a/samples/net/cloud/mqtt_azure/prj.conf b/samples/net/cloud/mqtt_azure/prj.conf index e3b8ac83edb..27b703bf585 100644 --- a/samples/net/cloud/mqtt_azure/prj.conf +++ b/samples/net/cloud/mqtt_azure/prj.conf @@ -47,7 +47,7 @@ CONFIG_DNS_RESOLVER=y CONFIG_DNS_SERVER_IP_ADDRESSES=y CONFIG_DNS_SERVER1="8.8.8.8" CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2 -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_INIT_STACKS=y CONFIG_NET_SHELL=y diff --git a/samples/net/cloud/mqtt_azure/sample.yaml b/samples/net/cloud/mqtt_azure/sample.yaml index 2f234d39481..ffa3e866895 100644 --- a/samples/net/cloud/mqtt_azure/sample.yaml +++ b/samples/net/cloud/mqtt_azure/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: description: MQTT sample app to Azure cloud name: mqtt-azure diff --git a/samples/net/dsa/prj.conf b/samples/net/dsa/prj.conf index 952aa9d272f..6309976db06 100644 --- a/samples/net/dsa/prj.conf +++ b/samples/net/dsa/prj.conf @@ -49,7 +49,7 @@ CONFIG_NET_TC_TX_COUNT=6 CONFIG_NET_TC_RX_COUNT=4 CONFIG_NET_CONFIG_INIT_TIMEOUT=10 -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NET_IF_MAX_IPV4_COUNT=4 CONFIG_NET_IF_MAX_IPV6_COUNT=4 diff --git a/samples/net/gptp/boards/mimxrt1050_evk.conf b/samples/net/gptp/boards/mimxrt1050_evk.conf index eeef6eaba02..2819d3afd66 100644 --- a/samples/net/gptp/boards/mimxrt1050_evk.conf +++ b/samples/net/gptp/boards/mimxrt1050_evk.conf @@ -7,5 +7,5 @@ CONFIG_ETH_MCUX_PTP_CLOCK_SRC_HZ=25000000 CONFIG_ETH_MCUX_RX_BUFFERS=6 CONFIG_ETH_MCUX_TX_BUFFERS=4 CONFIG_NET_GPTP_STATISTICS=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y diff --git a/samples/net/gptp/boards/mimxrt1060_evk.conf b/samples/net/gptp/boards/mimxrt1060_evk.conf index f12f5ebf34d..114cebd8fe8 100644 --- a/samples/net/gptp/boards/mimxrt1060_evk.conf +++ b/samples/net/gptp/boards/mimxrt1060_evk.conf @@ -6,6 +6,6 @@ CONFIG_NET_GPTP_CLOCK_ACCURACY_25MS=y #CONFIG_ETH_MCUX_RX_BUFFERS=6 #CONFIG_ETH_MCUX_TX_BUFFERS=8 CONFIG_NET_GPTP_STATISTICS=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NET_GPTP_INIT_LOG_PDELAY_REQ_ITV=-3 diff --git a/samples/net/lwm2m_client/overlay-ot.conf b/samples/net/lwm2m_client/overlay-ot.conf index 38960970f58..0e73d874597 100644 --- a/samples/net/lwm2m_client/overlay-ot.conf +++ b/samples/net/lwm2m_client/overlay-ot.conf @@ -1,7 +1,7 @@ # Main CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Disable TCP and IPv4 (TCP disabled to avoid heavy traffic) CONFIG_NET_TCP=n diff --git a/samples/net/sockets/big_http_download/prj.conf b/samples/net/sockets/big_http_download/prj.conf index 02b7e11d39e..324eb765af2 100644 --- a/samples/net/sockets/big_http_download/prj.conf +++ b/samples/net/sockets/big_http_download/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MAIN_STACK_SIZE=2536 diff --git a/samples/net/sockets/big_http_download/sample.yaml b/samples/net/sockets/big_http_download/sample.yaml index 019f390d298..313d0a135c7 100644 --- a/samples/net/sockets/big_http_download/sample.yaml +++ b/samples/net/sockets/big_http_download/sample.yaml @@ -2,7 +2,7 @@ sample: description: BSD Sockets big HTTP download example name: big_http_download common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net min_ram: 32 min_flash: 128 diff --git a/samples/net/sockets/coap_client/prj.conf b/samples/net/sockets/coap_client/prj.conf index 8a513d82a45..b0df3759b22 100644 --- a/samples/net/sockets/coap_client/prj.conf +++ b/samples/net/sockets/coap_client/prj.conf @@ -1,6 +1,6 @@ # Generic networking options CONFIG_NETWORKING=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NET_IPV6=y CONFIG_NET_UDP=y diff --git a/samples/net/sockets/coap_client/sample.yaml b/samples/net/sockets/coap_client/sample.yaml index a1fc20ff391..8c822c7604e 100644 --- a/samples/net/sockets/coap_client/sample.yaml +++ b/samples/net/sockets/coap_client/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample: description: TBD name: TBD diff --git a/samples/net/sockets/coap_server/prj.conf b/samples/net/sockets/coap_server/prj.conf index cbe61178b2a..6a8b972b069 100644 --- a/samples/net/sockets/coap_server/prj.conf +++ b/samples/net/sockets/coap_server/prj.conf @@ -1,6 +1,6 @@ # Generic networking options CONFIG_NETWORKING=y -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NET_UDP=y # Socket diff --git a/samples/net/sockets/coap_server/sample.yaml b/samples/net/sockets/coap_server/sample.yaml index dacc6e02ab0..8b6ab35ab6a 100644 --- a/samples/net/sockets/coap_server/sample.yaml +++ b/samples/net/sockets/coap_server/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample: description: TBD name: TBD diff --git a/samples/net/sockets/dumb_http_server/prj.conf b/samples/net/sockets/dumb_http_server/prj.conf index 62dcbde44b8..1c826c38f9d 100644 --- a/samples/net/sockets/dumb_http_server/prj.conf +++ b/samples/net/sockets/dumb_http_server/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/samples/net/sockets/dumb_http_server/sample.yaml b/samples/net/sockets/dumb_http_server/sample.yaml index d586551bdb7..13fd552b8aa 100644 --- a/samples/net/sockets/dumb_http_server/sample.yaml +++ b/samples/net/sockets/dumb_http_server/sample.yaml @@ -2,7 +2,7 @@ sample: description: BSD Sockets API dumb HTTP server example name: socket_dumb_http_server common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net min_ram: 32 min_flash: 96 diff --git a/samples/net/sockets/echo/sample.yaml b/samples/net/sockets/echo/sample.yaml index 300c13a4a6f..00a8e4e56bd 100644 --- a/samples/net/sockets/echo/sample.yaml +++ b/samples/net/sockets/echo/sample.yaml @@ -4,7 +4,7 @@ sample: common: harness: net depends_on: netif - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC tests: sample.net.sockets.echo: tags: diff --git a/samples/net/sockets/echo_async/prj.conf b/samples/net/sockets/echo_async/prj.conf index 3cfb5a6d4fc..21291009557 100644 --- a/samples/net/sockets/echo_async/prj.conf +++ b/samples/net/sockets/echo_async/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_MAIN_STACK_SIZE=1200 # Networking config diff --git a/samples/net/sockets/echo_async/sample.yaml b/samples/net/sockets/echo_async/sample.yaml index d3097a30775..9c88a2d5ea5 100644 --- a/samples/net/sockets/echo_async/sample.yaml +++ b/samples/net/sockets/echo_async/sample.yaml @@ -2,7 +2,7 @@ sample: description: BSD Sockets API TCP echo server sample using non-blocking sockets name: socket_echo_async common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net platform_allow: qemu_x86 tags: diff --git a/samples/net/sockets/echo_async_select/prj.conf b/samples/net/sockets/echo_async_select/prj.conf index 0a6e0c049b6..377b2eef8af 100644 --- a/samples/net/sockets/echo_async_select/prj.conf +++ b/samples/net/sockets/echo_async_select/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_MAIN_STACK_SIZE=1200 CONFIG_POSIX_API=y diff --git a/samples/net/sockets/echo_async_select/sample.yaml b/samples/net/sockets/echo_async_select/sample.yaml index b052c0d1c9d..3353773ec0b 100644 --- a/samples/net/sockets/echo_async_select/sample.yaml +++ b/samples/net/sockets/echo_async_select/sample.yaml @@ -7,7 +7,7 @@ common: tags: - net - socket - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC tests: sample.net.sockets.echo_async_select: extra_configs: diff --git a/samples/net/sockets/echo_client/overlay-ot.conf b/samples/net/sockets/echo_client/overlay-ot.conf index 58c70682478..0eb39c24d43 100644 --- a/samples/net/sockets/echo_client/overlay-ot.conf +++ b/samples/net/sockets/echo_client/overlay-ot.conf @@ -1,4 +1,4 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Disable TCP and IPv4 (TCP disabled to avoid heavy traffic) CONFIG_NET_TCP=n diff --git a/samples/net/sockets/echo_client/sample.yaml b/samples/net/sockets/echo_client/sample.yaml index bbc7d3c10e1..7c37257e420 100644 --- a/samples/net/sockets/echo_client/sample.yaml +++ b/samples/net/sockets/echo_client/sample.yaml @@ -81,7 +81,7 @@ tests: - net - openthread platform_allow: nrf52840dk_nrf52840 - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_client.b91_802154: extra_args: OVERLAY_CONFIG="overlay-802154.conf" platform_allow: tlsr9518adk80d @@ -92,7 +92,7 @@ tests: - net - openthread platform_allow: tlsr9518adk80d - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_client.kw41z_openthread: extra_args: OVERLAY_CONFIG="overlay-ot.conf" slow: true @@ -100,7 +100,7 @@ tests: - net - openthread platform_allow: frdm_kw41z - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_client.userspace: extra_args: - CONFIG_USERSPACE=y diff --git a/samples/net/sockets/echo_server/overlay-ot.conf b/samples/net/sockets/echo_server/overlay-ot.conf index 2158020d621..5d4563fdfa1 100644 --- a/samples/net/sockets/echo_server/overlay-ot.conf +++ b/samples/net/sockets/echo_server/overlay-ot.conf @@ -1,4 +1,4 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Disable TCP and IPv4 (TCP disabled to avoid heavy traffic) CONFIG_NET_TCP=n diff --git a/samples/net/sockets/echo_server/sample.yaml b/samples/net/sockets/echo_server/sample.yaml index 10255905402..1174797d04a 100644 --- a/samples/net/sockets/echo_server/sample.yaml +++ b/samples/net/sockets/echo_server/sample.yaml @@ -92,7 +92,7 @@ tests: - net - openthread platform_allow: nrf52840dk_nrf52840 - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_server.b91_openthread: extra_args: OVERLAY_CONFIG="overlay-ot.conf" slow: true @@ -100,7 +100,7 @@ tests: - net - openthread platform_allow: tlsr9518adk80d - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_server.kw41z_openthread: extra_args: OVERLAY_CONFIG="overlay-ot.conf" slow: true @@ -108,7 +108,7 @@ tests: - net - openthread platform_allow: frdm_kw41z - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_server.e1000: extra_args: OVERLAY_CONFIG="overlay-e1000.conf" tags: net diff --git a/samples/net/sockets/http_get/prj.conf b/samples/net/sockets/http_get/prj.conf index 64bb4bc52f8..57d4d4c55c0 100644 --- a/samples/net/sockets/http_get/prj.conf +++ b/samples/net/sockets/http_get/prj.conf @@ -1,6 +1,6 @@ # General config CONFIG_MAIN_STACK_SIZE=1536 -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/samples/net/sockets/http_get/sample.yaml b/samples/net/sockets/http_get/sample.yaml index f8fb27104c3..999c7ba97d6 100644 --- a/samples/net/sockets/http_get/sample.yaml +++ b/samples/net/sockets/http_get/sample.yaml @@ -2,7 +2,7 @@ sample: description: BSD Sockets API HTTP GET example name: socket_http_get common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net min_ram: 32 min_flash: 80 diff --git a/samples/net/sockets/sntp_client/prj.conf b/samples/net/sockets/sntp_client/prj.conf index d641240c25e..bfcd3092ac6 100644 --- a/samples/net/sockets/sntp_client/prj.conf +++ b/samples/net/sockets/sntp_client/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y # Networking config CONFIG_NETWORKING=y diff --git a/samples/net/sockets/tcp/prj.conf b/samples/net/sockets/tcp/prj.conf index be1af897fe2..a442918f337 100644 --- a/samples/net/sockets/tcp/prj.conf +++ b/samples/net/sockets/tcp/prj.conf @@ -1,4 +1,4 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NETWORKING=y diff --git a/samples/net/sockets/tcp/sample.yaml b/samples/net/sockets/tcp/sample.yaml index b636044bca3..895e519a360 100644 --- a/samples/net/sockets/tcp/sample.yaml +++ b/samples/net/sockets/tcp/sample.yaml @@ -3,7 +3,7 @@ sample: name: tcp tests: sample.net.socket.tcp: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net platform_allow: qemu_x86 tags: diff --git a/samples/net/syslog_net/prj.conf b/samples/net/syslog_net/prj.conf index d4fb024b448..b0ae6043cef 100644 --- a/samples/net/syslog_net/prj.conf +++ b/samples/net/syslog_net/prj.conf @@ -37,4 +37,4 @@ CONFIG_LOG_BACKEND_NET=y CONFIG_LOG_BACKEND_NET_SERVER="[2001:db8::2]:514" # Get newlib by default as it has proper time function support -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/net/syslog_net/sample.yaml b/samples/net/syslog_net/sample.yaml index 6a84d7d51cd..4fe99e593ff 100644 --- a/samples/net/syslog_net/sample.yaml +++ b/samples/net/syslog_net/sample.yaml @@ -9,11 +9,11 @@ sample: name: syslog_net tests: sample.net.syslog.with_timefuncs: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - - CONFIG_NEWLIB_LIBC=y + - CONFIG_REQUIRES_FULL_LIBC=y sample.net.syslog.ipv4_only: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_NET_IPV6=n - CONFIG_NET_CONFIG_NEED_IPV6=n @@ -21,18 +21,18 @@ tests: - CONFIG_NET_CONFIG_PEER_IPV6_ADDR="" - CONFIG_LOG_BACKEND_NET_SERVER="192.0.2.1:514" sample.net.syslog.ipv6_only: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_NET_IPV4=n - CONFIG_NET_CONFIG_NEED_IPV4=n - CONFIG_NET_CONFIG_MY_IPV4_ADDR="" - CONFIG_NET_CONFIG_PEER_IPV4_ADDR="" sample.net.syslog.no_autostart: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_LOG_BACKEND_NET_AUTOSTART=n sample.net.syslog.runtime_srv_addr: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED extra_configs: - CONFIG_LOG_BACKEND_NET_AUTOSTART=n - CONFIG_LOG_BACKEND_NET_SERVER="" diff --git a/samples/posix/eventfd/prj.conf b/samples/posix/eventfd/prj.conf index 7ff74543b2f..4fb4280b874 100644 --- a/samples/posix/eventfd/prj.conf +++ b/samples/posix/eventfd/prj.conf @@ -1,5 +1,5 @@ # General config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_POSIX_API=y CONFIG_EVENTFD=y diff --git a/samples/posix/eventfd/sample.yaml b/samples/posix/eventfd/sample.yaml index d1384095ae8..8e1e16b4eb7 100644 --- a/samples/posix/eventfd/sample.yaml +++ b/samples/posix/eventfd/sample.yaml @@ -2,7 +2,7 @@ sample: description: Extended POSIX (Linux) API eventfd() example name: eventfd common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC tags: posix platform_exclude: m2gl025_miv integration_platforms: diff --git a/samples/posix/gettimeofday/prj.conf b/samples/posix/gettimeofday/prj.conf index 033db203f16..ee748221ce5 100644 --- a/samples/posix/gettimeofday/prj.conf +++ b/samples/posix/gettimeofday/prj.conf @@ -1,6 +1,6 @@ # General config CONFIG_MAIN_STACK_SIZE=1088 -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_POSIX_API=y CONFIG_SNTP=y CONFIG_NET_CONFIG_CLOCK_SNTP_INIT=y diff --git a/samples/posix/gettimeofday/sample.yaml b/samples/posix/gettimeofday/sample.yaml index 2e21ce21457..a71d29f09c5 100644 --- a/samples/posix/gettimeofday/sample.yaml +++ b/samples/posix/gettimeofday/sample.yaml @@ -2,7 +2,8 @@ sample: description: POSIX API gettimeofday() example (with SNTP) name: gettimeofday common: - filter: ( TOOLCHAIN_HAS_NEWLIB == 1 and not CONFIG_SOC_FAMILY_INTEL_ADSP ) + filter: ( CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC + and not CONFIG_SOC_FAMILY_INTEL_ADSP ) harness: net min_ram: 32 min_flash: 96 diff --git a/samples/sensor/dht/prj.conf b/samples/sensor/dht/prj.conf index 9555c352793..33811ecb171 100644 --- a/samples/sensor/dht/prj.conf +++ b/samples/sensor/dht/prj.conf @@ -8,6 +8,6 @@ CONFIG_SENSOR=y CONFIG_GPIO=y # Need float format support -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/sensor/dht/sample.yaml b/samples/sensor/dht/sample.yaml index 74f346bd31d..ad74cb83d9c 100644 --- a/samples/sensor/dht/sample.yaml +++ b/samples/sensor/dht/sample.yaml @@ -5,7 +5,7 @@ # common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: name: DHT Sensor Sample tests: diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_devkitm.conf b/samples/sensor/die_temp_polling/boards/esp32c3_devkitm.conf index 13ed95d4291..5ab7306afeb 100644 --- a/samples/sensor/die_temp_polling/boards/esp32c3_devkitm.conf +++ b/samples/sensor/die_temp_polling/boards/esp32c3_devkitm.conf @@ -1 +1 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf index 13ed95d4291..5ab7306afeb 100644 --- a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core.conf @@ -1 +1 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf index 13ed95d4291..5ab7306afeb 100644 --- a/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf +++ b/samples/sensor/die_temp_polling/boards/esp32c3_luatos_core_usb.conf @@ -1 +1 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/esp32s2_saola.conf b/samples/sensor/die_temp_polling/boards/esp32s2_saola.conf index 13ed95d4291..5ab7306afeb 100644 --- a/samples/sensor/die_temp_polling/boards/esp32s2_saola.conf +++ b/samples/sensor/die_temp_polling/boards/esp32s2_saola.conf @@ -1 +1 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf b/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf index 13ed95d4291..5ab7306afeb 100644 --- a/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf +++ b/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf @@ -1 +1 @@ -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/fdc2x1x/prj.conf b/samples/sensor/fdc2x1x/prj.conf index f0275d2e97e..2b9602b1fc8 100644 --- a/samples/sensor/fdc2x1x/prj.conf +++ b/samples/sensor/fdc2x1x/prj.conf @@ -2,7 +2,7 @@ CONFIG_LOG=y CONFIG_I2C=y CONFIG_SENSOR=y CONFIG_PM_DEVICE=n -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD=n diff --git a/samples/sensor/grove_light/prj.conf b/samples/sensor/grove_light/prj.conf index 7aafd383084..dc1d0ec2139 100644 --- a/samples/sensor/grove_light/prj.conf +++ b/samples/sensor/grove_light/prj.conf @@ -1,5 +1,5 @@ CONFIG_ADC=y CONFIG_SENSOR=y -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/sensor/grove_light/sample.yaml b/samples/sensor/grove_light/sample.yaml index df34be19f7a..3eb1083a883 100644 --- a/samples/sensor/grove_light/sample.yaml +++ b/samples/sensor/grove_light/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: name: Grove Light Sensor tests: diff --git a/samples/sensor/grove_temperature/prj.conf b/samples/sensor/grove_temperature/prj.conf index 7aafd383084..dc1d0ec2139 100644 --- a/samples/sensor/grove_temperature/prj.conf +++ b/samples/sensor/grove_temperature/prj.conf @@ -1,5 +1,5 @@ CONFIG_ADC=y CONFIG_SENSOR=y -CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/sensor/grove_temperature/sample.yaml b/samples/sensor/grove_temperature/sample.yaml index 0076845543e..83035b9b9fb 100644 --- a/samples/sensor/grove_temperature/sample.yaml +++ b/samples/sensor/grove_temperature/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: name: Grove Temperature Sensor tests: diff --git a/samples/sensor/grove_temperature/src/main.c b/samples/sensor/grove_temperature/src/main.c index 643ae4707e2..c49137f6018 100644 --- a/samples/sensor/grove_temperature/src/main.c +++ b/samples/sensor/grove_temperature/src/main.c @@ -63,7 +63,7 @@ int main(void) /* display temperature on LCD */ glcd_cursor_pos_set(glcd, 0, 0); -#ifdef CONFIG_NEWLIB_LIBC_FLOAT_PRINTF +#ifdef CONFIG_REQUIRES_FLOAT_PRINTF sprintf(row, "T:%.2f%cC", sensor_value_to_double(&temp), 223 /* degree symbol */); @@ -75,7 +75,7 @@ int main(void) #endif -#ifdef CONFIG_NEWLIB_LIBC_FLOAT_PRINTF +#ifdef CONFIG_REQUIRES_FLOAT_PRINTF printf("Temperature: %.2f C\n", sensor_value_to_double(&temp)); #else printk("Temperature: %d\n", temp.val1); diff --git a/samples/subsys/mgmt/hawkbit/prj.conf b/samples/subsys/mgmt/hawkbit/prj.conf index a96c9461a83..e8539c7a120 100644 --- a/samples/subsys/mgmt/hawkbit/prj.conf +++ b/samples/subsys/mgmt/hawkbit/prj.conf @@ -53,7 +53,7 @@ CONFIG_LOG=y CONFIG_HAWKBIT_LOG_LEVEL_INF=n #General Config -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y CONFIG_LOG_BUFFER_SIZE=4096 #Generate HEX output diff --git a/samples/subsys/mgmt/hawkbit/sample.yaml b/samples/subsys/mgmt/hawkbit/sample.yaml index 4df4c6d3f69..6a60360e423 100644 --- a/samples/subsys/mgmt/hawkbit/sample.yaml +++ b/samples/subsys/mgmt/hawkbit/sample.yaml @@ -1,5 +1,5 @@ common: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + filter: CONFIG_FULL_LIBC_SUPPORTED sample: description: Hawkbit Firmware Over-the-Air (FOTA) name: hawkbit diff --git a/samples/tfm_integration/psa_crypto/prj.conf b/samples/tfm_integration/psa_crypto/prj.conf index a5f38632d51..97df0796411 100644 --- a/samples/tfm_integration/psa_crypto/prj.conf +++ b/samples/tfm_integration/psa_crypto/prj.conf @@ -35,4 +35,4 @@ CONFIG_JSON_LIBRARY=y CONFIG_TFM_PARTITION_INITIAL_ATTESTATION=y CONFIG_TFM_QCBOR_PATH="DOWNLOAD" -CONFIG_NEWLIB_LIBC=y +CONFIG_REQUIRES_FULL_LIBC=y From a282f6a92b60597949514c31467a79b8fd7a041e Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Thu, 5 Oct 2023 13:39:27 +0300 Subject: [PATCH 2541/4498] dts: bindings: add adxl367 support Add bindings for the adxl367 accelerometer. Signed-off-by: Antoniu Miclaus --- dts/bindings/sensor/adi,adxl367-common.yaml | 24 +++++++++++++++++++++ dts/bindings/sensor/adi,adxl367-i2c.yaml | 8 +++++++ dts/bindings/sensor/adi,adxl367-spi.yaml | 8 +++++++ 3 files changed, 40 insertions(+) create mode 100644 dts/bindings/sensor/adi,adxl367-common.yaml create mode 100644 dts/bindings/sensor/adi,adxl367-i2c.yaml create mode 100644 dts/bindings/sensor/adi,adxl367-spi.yaml diff --git a/dts/bindings/sensor/adi,adxl367-common.yaml b/dts/bindings/sensor/adi,adxl367-common.yaml new file mode 100644 index 00000000000..07ffc8ba440 --- /dev/null +++ b/dts/bindings/sensor/adi,adxl367-common.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 + +include: sensor-device.yaml + +properties: + odr: + type: int + default: 0 + description: | + Accelerometer sampling frequency (ODR). Default is power on reset value. + 0 # 12.5Hz + 1 # 25Hz + 2 # 50Hz + 3 # 100Hz + 4 # 200Hz + 5 # 400Hz + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 diff --git a/dts/bindings/sensor/adi,adxl367-i2c.yaml b/dts/bindings/sensor/adi,adxl367-i2c.yaml new file mode 100644 index 00000000000..faab9e577b9 --- /dev/null +++ b/dts/bindings/sensor/adi,adxl367-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: ADXL367 3-axis nanopower accelerometer, accessed through I2C bus + +compatible: "adi,adxl367" + +include: ["i2c-device.yaml", "adi,adxl367-common.yaml"] diff --git a/dts/bindings/sensor/adi,adxl367-spi.yaml b/dts/bindings/sensor/adi,adxl367-spi.yaml new file mode 100644 index 00000000000..86d825f781c --- /dev/null +++ b/dts/bindings/sensor/adi,adxl367-spi.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: ADXL367 3-axis nanopower accelerometer, accessed through SPI bus + +compatible: "adi,adxl367" + +include: ["spi-device.yaml", "adi,adxl367-common.yaml"] From 89be1e948d2c9ee146148923767cbdc395279326 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Thu, 5 Oct 2023 13:39:59 +0300 Subject: [PATCH 2542/4498] drivers: adxl367: add support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add driver support for adxl367 accelerometer. The ADXL367 is an ultralow power, 3-axis microelectromechanical systems (MEMS) accelerometer that consumes only 0.89 μA at a 100 Hz output data rate and 180 nA when in motion-triggered wake-up mode. Unlike accelerometers that use power duty cycling to achieve low power consumption, the ADXL367 does not alias input signals by undersampling, but samples the full bandwidth of the sensor at all data rates. Signed-off-by: Antoniu Miclaus --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/adxl367/CMakeLists.txt | 10 + drivers/sensor/adxl367/Kconfig | 95 +++ drivers/sensor/adxl367/adxl367.c | 1048 +++++++++++++++++++++++++ drivers/sensor/adxl367/adxl367.h | 315 ++++++++ drivers/sensor/adxl367/adxl367_i2c.c | 103 +++ drivers/sensor/adxl367/adxl367_spi.c | 131 ++++ 8 files changed, 1704 insertions(+) create mode 100644 drivers/sensor/adxl367/CMakeLists.txt create mode 100644 drivers/sensor/adxl367/Kconfig create mode 100644 drivers/sensor/adxl367/adxl367.c create mode 100644 drivers/sensor/adxl367/adxl367.h create mode 100644 drivers/sensor/adxl367/adxl367_i2c.c create mode 100644 drivers/sensor/adxl367/adxl367_spi.c diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 613414069eb..a50b1c55657 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory_ifdef(CONFIG_ADT7310 adt7310) add_subdirectory_ifdef(CONFIG_ADT7420 adt7420) add_subdirectory_ifdef(CONFIG_ADXL345 adxl345) add_subdirectory_ifdef(CONFIG_ADXL362 adxl362) +add_subdirectory_ifdef(CONFIG_ADXL367 adxl367) add_subdirectory_ifdef(CONFIG_ADXL372 adxl372) add_subdirectory_ifdef(CONFIG_AK8975 ak8975) add_subdirectory_ifdef(CONFIG_AKM09918C akm09918c) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 55bb4464607..585bc7dc2db 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -63,6 +63,7 @@ source "drivers/sensor/adt7310/Kconfig" source "drivers/sensor/adt7420/Kconfig" source "drivers/sensor/adxl345/Kconfig" source "drivers/sensor/adxl362/Kconfig" +source "drivers/sensor/adxl367/Kconfig" source "drivers/sensor/adxl372/Kconfig" source "drivers/sensor/ak8975/Kconfig" source "drivers/sensor/akm09918c/Kconfig" diff --git a/drivers/sensor/adxl367/CMakeLists.txt b/drivers/sensor/adxl367/CMakeLists.txt new file mode 100644 index 00000000000..3dafe9fffbf --- /dev/null +++ b/drivers/sensor/adxl367/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023 Analog Devices Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +zephyr_library() + +zephyr_library_sources(adxl367.c) +zephyr_library_sources(adxl367_spi.c) +zephyr_library_sources(adxl367_i2c.c) diff --git a/drivers/sensor/adxl367/Kconfig b/drivers/sensor/adxl367/Kconfig new file mode 100644 index 00000000000..af77a9e12cb --- /dev/null +++ b/drivers/sensor/adxl367/Kconfig @@ -0,0 +1,95 @@ +# Micropower, 3-Axis, +/-200g Digital Accelerometer + +# Copyright (c) 2023 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ADXL367 + bool "ADXL367 Three Axis High-g I2C/SPI accelerometer" + default y + depends on DT_HAS_ADI_ADXL367_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ADI_ADXL367),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ADI_ADXL367),spi) + help + Enable driver for ADXL367 Three-Axis Digital Accelerometers. + +if ADXL367 + +choice ADXL367_OP_MODE + prompt "Operating mode" + default ADXL367_MEASUREMENT_MODE + +config ADXL367_MEASUREMENT_MODE + bool "Measurement Mode" + help + In this mode, acceleration data is provided continuously at the + output data rate (ODR). + +endchoice + +config ADXL367_ACTIVITY_THRESHOLD + int "Activity threshold in raw value" + range 0 8191 + default 100 + help + Threshold for activity detection. + +config ADXL367_INACTIVITY_THRESHOLD + int "In-activity threshold in raw value" + range 0 8191 + default 100 + help + Threshold for in-activity detection. + +config ADXL367_ACTIVITY_TIME + int "Activity time" + range 0 255 + default 100 + help + The activity timer implements a robust activity detection that + minimizes false positive motion triggers. When the timer is used, + only sustained motion can trigger activity detection. Value is the + number of samples. For example, at 100Hz ODR, 100 value translates + to 1 second. + +config ADXL367_INACTIVITY_TIME + int "In-activity time" + range 0 65535 + default 100 + help + The time that all enabled axes must be lower than the inactivity + threshold for an inactivity event to be detected. Value is the + number of samples. For example, at 100Hz ODR, 100 value translates + to 1 second. + +config ADXL367_ACTIVITY_DETECTION_MODE + bool "Use activity detection" + default y + help + Enable Activity detection. + +config ADXL367_INACTIVITY_DETECTION_MODE + bool "Use inactivity detection" + default y + help + Enable Inactivity detection. + + +config ADXL367_REFERENCED_ACTIVITY_DETECTION_MODE + bool "Use referenced activity detection" + default y + help + Activity detection can be configured as referenced or absolute. + When using absolute activity detection, acceleration samples are + compared directly to a user set threshold to determine whether + motion is present. + +config ADXL367_REFERENCED_INACTIVITY_DETECTION_MODE + bool "Use referenced inactivity detection" + default y + help + Inactivity detection can be configured as referenced or absolute. + When using absolute inactivity detection, acceleration samples are + compared directly to a user set threshold to determine whether + motion is present. + +endif # ADXL367 diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c new file mode 100644 index 00000000000..44eecf1c975 --- /dev/null +++ b/drivers/sensor/adxl367/adxl367.c @@ -0,0 +1,1048 @@ +/* + * Copyright (c) 2023 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adxl367 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "adxl367.h" + +LOG_MODULE_REGISTER(ADXL367, CONFIG_SENSOR_LOG_LEVEL); + +static const uint8_t adxl367_scale_mul[3] = {1, 2, 4}; +static uint8_t samples_per_set; + +/** + * @brief Configures activity detection. + * + * @param dev - The device structure. + * @param th - Structure holding the activity threshold information: + * Enable/Disable Activity detection + * Enable/Disable Referenced Activity detection + * Set Threshold value + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_setup_activity_detection(const struct device *dev, + const struct adxl367_activity_threshold *th) +{ + struct adxl367_data *data = dev->data; + int ret; + + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_ACT_INACT_CTL, + ADXL367_ACT_INACT_CTL_ACT_EN_MSK | + ADXL367_ACT_INACT_CTL_ACT_REF_MSK, + FIELD_PREP(ADXL367_ACT_INACT_CTL_ACT_EN_MSK, th->enable) | + FIELD_PREP(ADXL367_ACT_INACT_CTL_ACT_REF_MSK, + th->referenced)); + if (ret) { + return ret; + } + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_ACT_H, ADXL367_THRESH_H_MSK, + FIELD_PREP(ADXL367_THRESH_H_MSK, th->value >> 6)); + if (ret) { + return ret; + } + + return data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_ACT_L, ADXL367_THRESH_L_MSK, + FIELD_PREP(ADXL367_THRESH_L_MSK, th->value & 0x3F)); +} + +/** + * @brief Configures activity detection. + * + * @param dev - The device structure. + * @param th - Structure holding the inactivity threshold information: + * Enable/Disable inactivity detection + * Enable/Disable Referenced inactivity detection + * Set Threshold value + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_setup_inactivity_detection(const struct device *dev, + const struct adxl367_activity_threshold *th) +{ + struct adxl367_data *data = dev->data; + int ret; + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_ACT_INACT_CTL, + ADXL367_ACT_INACT_CTL_INACT_EN_MSK | + ADXL367_ACT_INACT_CTL_INACT_REF_MSK, + FIELD_PREP(ADXL367_ACT_INACT_CTL_INACT_EN_MSK, + th->enable) | + FIELD_PREP(ADXL367_ACT_INACT_CTL_INACT_REF_MSK, + th->referenced)); + if (ret) { + return ret; + } + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_INACT_H, ADXL367_THRESH_H_MSK, + FIELD_PREP(ADXL367_THRESH_H_MSK, th->value >> 6)); + if (ret) { + return ret; + } + + return data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_INACT_L, ADXL367_THRESH_L_MSK, + FIELD_PREP(ADXL367_THRESH_L_MSK, th->value & 0x3F)); +} + +/** + * @brief Set the mode of operation. + * + * @param dev - The device structure. + * @param op_mode - Mode of operation. + * Accepted values: ADXL367_STANDBY + * ADXL367_MEASURE + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_op_mode(const struct device *dev, + enum adxl367_op_mode op_mode) +{ + struct adxl367_data *data = dev->data; + int ret; + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_POWER_CTL, + ADXL367_POWER_CTL_MEASURE_MSK, + FIELD_PREP(ADXL367_POWER_CTL_MEASURE_MSK, op_mode)); + if (ret) { + return ret; + } + + if (op_mode == ADXL367_MEASURE) + /* Wait 100 ms to allow the acceleration outputs to settle */ + k_sleep(K_MSEC(100)); + + return 0; +} + +/** + * @brief Autosleep. When set to 1, autosleep is enabled, and the device enters + * wake-up mode automatically upon detection of inactivity. + * + * @param dev - The device structure. + * @param enable - Accepted values: true + * false + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_autosleep(const struct device *dev, bool enable) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, ADXL367_POWER_CTL, + ADXL367_POWER_CTL_AUTOSLEEP_MSK, + FIELD_PREP(ADXL367_POWER_CTL_AUTOSLEEP_MSK, enable)); +} + +/** + * @brief Noise Mode. When set to 1, low noise mode is enabled + * + * @param dev - The device structure. + * @param enable - Accepted values: true + * false + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_low_noise(const struct device *dev, bool enable) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, ADXL367_POWER_CTL, + ADXL367_POWER_CTL_NOISE_MSK, + FIELD_PREP(ADXL367_POWER_CTL_NOISE_MSK, enable)); +} + +/** + * @brief Link/Loop Activity Processing. + * + * @param dev - The device structure. + * @param mode - Mode of operation. + * Accepted values: ADXL367_DEFAULT + * ADXL367_LINKED + * ADXL367_LOOPED + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_act_proc_mode(const struct device *dev, + enum adxl367_act_proc_mode mode) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, ADXL367_ACT_INACT_CTL, + ADXL367_ACT_INACT_CTL_LINKLOOP_MSK, + FIELD_PREP(ADXL367_ACT_INACT_CTL_LINKLOOP_MSK, mode)); +} + + +/** + * @brief Selects the Output Data Rate of the device. + * @param dev - The device structure. + * @param odr - Output Data Rate option. + * Accepted values: ADXL367_ODR_12P5HZ, + * ADXL367_ODR_25HZ, + * ADXL367_ODR_50HZ, + * ADXL367_ODR_100HZ, + * ADXL367_ODR_200HZ, + * ADXL367_ODR_400HZ + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_output_rate(const struct device *dev, enum adxl367_odr odr) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, + ADXL367_FILTER_CTL, + ADXL367_FILTER_CTL_ODR_MSK, + FIELD_PREP(ADXL367_FILTER_CTL_ODR_MSK, odr)); +} + +/** + * @brief Selects the measurement range. + * + * @param dev - The device structure. + * @param range - Range option. + * Accepted values: ADXL367_2G_RANGE, +/- 2g + * ADXL367_4G_RANGE, +/- 4g + * ADXL367_8G_RANGE +/- 8g + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_range(const struct device *dev, enum adxl367_range range) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, + ADXL367_FILTER_CTL, + ADXL367_FILTER_CTL_RANGE_MSK, + FIELD_PREP(ADXL367_FILTER_CTL_RANGE_MSK, range)); +} + +/** + * @brief Set the activity timer + * + * @param dev - The device structure. + * @param time - The value set in this register. + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_activity_time(const struct device *dev, uint8_t time) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg(dev, ADXL367_TIME_ACT, time); +} + +/** + * Set the inactivity timer + * @param dev - The device structure. + * @param time - is the 16-bit value set by the TIME_INACT_L register + * (eight LSBs) and the TIME_INACT_H register (eight MSBs). + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_set_inactivity_time(const struct device *dev, + uint16_t time) +{ + int ret; + struct adxl367_data *data = dev->data; + + ret = data->hw_tf->write_reg(dev, ADXL367_TIME_INACT_H, time >> 8); + if (ret) { + return ret; + } + + return data->hw_tf->write_reg(dev, ADXL367_TIME_INACT_L, time & 0xFF); +} + +/** + * @brief Performs self test. + * + * @param dev - The device structure. + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_self_test(const struct device *dev) +{ + int ret; + struct adxl367_data *data = dev->data; + int16_t x_axis_1, x_axis_2, dif, min, max; + uint8_t read_val[2]; + + ret = adxl367_set_op_mode(dev, ADXL367_MEASURE); + if (ret) { + return ret; + } + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_SELF_TEST, ADXL367_SELF_TEST_ST_MSK, + FIELD_PREP(ADXL367_SELF_TEST_ST_MSK, 1)); + if (ret) { + return ret; + } + + /* 4 / default ODR = 40ms */ + k_sleep(K_MSEC(40)); + + ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); + if (ret) { + return ret; + } + + x_axis_1 = ((int16_t)read_val[0] << 6) + (read_val[1] >> 2); + + /* extend sign to 16 bits */ + if (x_axis_1 & BIT(13)) { + x_axis_1 |= GENMASK(15, 14); + } + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_SELF_TEST, + ADXL367_SELF_TEST_ST_FORCE_MSK, + FIELD_PREP(ADXL367_SELF_TEST_ST_FORCE_MSK, 1)); + if (ret) { + return ret; + } + + /* 4 / default ODR = 40ms */ + k_sleep(K_MSEC(40)); + + ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); + if (ret) { + return ret; + } + + x_axis_2 = ((int16_t)read_val[0] << 6) + (read_val[1] >> 2); + + /* extend sign to 16 bits */ + if (x_axis_2 & BIT(13)) + x_axis_2 |= GENMASK(15, 14); + + ret = adxl367_set_op_mode(dev, ADXL367_STANDBY); + if (ret) { + return ret; + } + + ret = data->hw_tf->write_reg_mask(dev, ADXL367_SELF_TEST, ADXL367_SELF_TEST_ST_FORCE_MSK | + ADXL367_SELF_TEST_ST_MSK, + FIELD_PREP(ADXL367_SELF_TEST_ST_FORCE_MSK, 0) | + FIELD_PREP(ADXL367_SELF_TEST_ST_MSK, 0)); + if (ret) { + return ret; + } + + dif = x_axis_2 - x_axis_1; + min = ADXL367_SELF_TEST_MIN * adxl367_scale_mul[data->range]; + max = ADXL367_SELF_TEST_MAX * adxl367_scale_mul[data->range]; + + if ((dif >= min) && (dif <= max)) { + LOG_INF("ADXL367 passed self-test\n"); + ret = 0; + } else { + LOG_ERR("ADXL367 failed self-test\n"); + ret = -EINVAL; + } + + return ret; +} + +/** + * @brief Enables temperature reading. + * + * @param dev - The device structure. + * @param enable - 1 - ENABLE + * 2 - DISABLE + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_temp_read_en(const struct device *dev, bool enable) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, + ADXL367_TEMP_CTL, + ADXL367_TEMP_EN_MSK, + FIELD_PREP(ADXL367_TEMP_EN_MSK, enable)); +} + +/** + * @brief Sets the number of FIFO sample sets. + * + * @param dev - The device structure. + * @param sets_nb - Sample sets number. For example, if ADXL367_FIFO_FORMAT_XYZ + * is selected, a value of 2 will represent 6 entries. + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_fifo_sample_sets_nb(const struct device *dev, + uint16_t sets_nb) +{ + struct adxl367_data *data = dev->data; + int ret; + uint8_t fifo_samples_msb = sets_nb & BIT(9) ? 1U : 0U; + + /* bit 9 goes to FIFO_SAMPLES from ADXL367_FIFO_CONTROL */ + ret = data->hw_tf->write_reg_mask(dev, ADXL367_FIFO_CONTROL, + ADXL367_FIFO_CONTROL_FIFO_SAMPLES_MSK, + FIELD_PREP(ADXL367_FIFO_CONTROL_FIFO_SAMPLES_MSK, + fifo_samples_msb)); + if (ret) { + return ret; + } + + /* write last 8 bits to ADXL367_FIFO_SAMPLES */ + return data->hw_tf->write_reg(dev, ADXL367_FIFO_SAMPLES, sets_nb & 0xFF); +} + +/** + * @brief Sets FIFO mode. + * + * @param dev - The device structure. + * @param mode - FIFO mode. + * Accepted values: ADXL367_FIFO_DISABLED, + * ADXL367_OLDEST_SAVED, + * ADXL367_STREAM_MODE, + * ADXL367_TRIGGERED_MODE + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_fifo_mode(const struct device *dev, + enum adxl367_fifo_mode mode) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, + ADXL367_FIFO_CONTROL, + ADXL367_FIFO_CONTROL_FIFO_MODE_MSK, + FIELD_PREP(ADXL367_FIFO_CONTROL_FIFO_MODE_MSK, mode)); +} + +/** + * @brief Sets FIFO read mode. + * + * @param dev - The device structure. + * @param read_mode - FIFO read mode. + * Accepted values: ADXL367_12B_CHID, + * ADXL367_8B, + * ADXL367_12B, + * ADXL367_14B_CHID + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_fifo_read_mode(const struct device *dev, + enum adxl367_fifo_read_mode read_mode) +{ + struct adxl367_data *data = dev->data; + + return data->hw_tf->write_reg_mask(dev, ADXL367_ADC_CTL, + ADXL367_FIFO_8_12BIT_MSK, + FIELD_PREP(ADXL367_FIFO_8_12BIT_MSK, read_mode)); +} + +/** + * @brief Sets FIFO format. + * + * @param dev - The device structure. + * @param format - FIFO format. + * Accepted values: ADXL367_FIFO_FORMAT_XYZ, + * ADXL367_FIFO_FORMAT_X, + * ADXL367_FIFO_FORMAT_Y, + * ADXL367_FIFO_FORMAT_Z, + * ADXL367_FIFO_FORMAT_XYZT, + * ADXL367_FIFO_FORMAT_XT, + * ADXL367_FIFO_FORMAT_YT, + * ADXL367_FIFO_FORMAT_ZT, + * ADXL367_FIFO_FORMAT_XYZA, + * ADXL367_FIFO_FORMAT_XA, + * ADXL367_FIFO_FORMAT_YA, + * ADXL367_FIFO_FORMAT_ZA + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_set_fifo_format(const struct device *dev, + enum adxl367_fifo_format format) +{ + int ret; + struct adxl367_data *data = dev->data; + + ret = data->hw_tf->write_reg_mask(dev, + ADXL367_FIFO_CONTROL, + ADXL367_FIFO_CONTROL_FIFO_CHANNEL_MSK, + FIELD_PREP(ADXL367_FIFO_CONTROL_FIFO_CHANNEL_MSK, format)); + if (ret) { + return ret; + } + + switch (format) { + case ADXL367_FIFO_FORMAT_XYZ: + samples_per_set = 3; + break; + case ADXL367_FIFO_FORMAT_X: + case ADXL367_FIFO_FORMAT_Y: + case ADXL367_FIFO_FORMAT_Z: + samples_per_set = 1; + break; + case ADXL367_FIFO_FORMAT_XYZT: + case ADXL367_FIFO_FORMAT_XYZA: + samples_per_set = 4; + break; + case ADXL367_FIFO_FORMAT_XT: + case ADXL367_FIFO_FORMAT_YT: + case ADXL367_FIFO_FORMAT_ZT: + case ADXL367_FIFO_FORMAT_XA: + case ADXL367_FIFO_FORMAT_YA: + case ADXL367_FIFO_FORMAT_ZA: + samples_per_set = 2; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * @brief Configures the FIFO feature. Uses ADXL367_14B_CHID read mode as + * default. + * + * @param dev - The device structure. + * @param mode - FIFO mode selection. + * Example: ADXL367_FIFO_DISABLED, + * ADXL367_OLDEST_SAVED, + * ADXL367_STREAM_MODE, + * ADXL367_TRIGGERED_MODE + * @param format - FIFO format selection. + * Example: ADXL367_FIFO_FORMAT_XYZ, + * ADXL367_FIFO_FORMAT_X, + * ADXL367_FIFO_FORMAT_Y, + * ADXL367_FIFO_FORMAT_Z, + * ADXL367_FIFO_FORMAT_XYZT, + * ADXL367_FIFO_FORMAT_XT, + * ADXL367_FIFO_FORMAT_YT, + * ADXL367_FIFO_FORMAT_ZT, + * ADXL367_FIFO_FORMAT_XYZA, + * ADXL367_FIFO_FORMAT_XA, + * ADXL367_FIFO_FORMAT_YA, + * ADXL367_FIFO_FORMAT_ZA + * @param read_mode - FIFO read mode. + * Accepted values: ADXL367_12B_CHID, + * ADXL367_8B, + * ADXL367_12B, + * ADXL367_14B_CHID + * @param sets_nb - Specifies the number of samples sets to store in the FIFO. + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_fifo_setup(const struct device *dev, + enum adxl367_fifo_mode mode, + enum adxl367_fifo_format format, + enum adxl367_fifo_read_mode read_mode, + uint8_t sets_nb) +{ + int ret; + + ret = adxl367_set_fifo_mode(dev, mode); + if (ret) { + return ret; + } + + ret = adxl367_set_fifo_format(dev, format); + if (ret) { + return ret; + } + + ret = adxl367_set_fifo_sample_sets_nb(dev, sets_nb); + if (ret) { + return ret; + } + + return adxl367_set_fifo_read_mode(dev, read_mode); +} + +/** + * @brief Software reset. + * + * @param dev - The device structure. + * + * @return 0 in case of success, negative error code otherwise. + */ +static int adxl367_reset(const struct device *dev) +{ + int ret; + struct adxl367_data *data = dev->data; + + ret = adxl367_set_op_mode(dev, ADXL367_STANDBY); + if (ret) { + return ret; + } + + /* Writing code 0x52 resets the device */ + ret = data->hw_tf->write_reg(dev, ADXL367_SOFT_RESET, ADXL367_RESET_CODE); + if (ret) { + return ret; + } + + /* Delay required after performing software reset */ + k_sleep(K_MSEC(8)); + + return ret; +} + + +/** + * @brief Reads the 3-axis raw data from the accelerometer. + * + * @param dev - The device structure. + * @param accel_data - store the XYZ axis accelerometer data. + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_get_accel_data(const struct device *dev, + struct adxl367_xyz_accel_data *accel_data) +{ + int ret; + uint8_t xyz_values[6] = { 0 }; + uint8_t reg_data, nready = 1U; + struct adxl367_data *data = dev->data; + + while (nready) { + ret = data->hw_tf->read_reg(dev, ADXL367_STATUS, ®_data); + if (ret) { + return ret; + } + + if (reg_data & ADXL367_STATUS_DATA_RDY) { + nready = 0U; + } + } + + ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, xyz_values, 6); + if (ret) { + return ret; + } + + /* result is 14 bits long, ignore last 2 bits from low byte */ + accel_data->x = ((int16_t)xyz_values[0] << 6) + (xyz_values[1] >> 2); + accel_data->y = ((int16_t)xyz_values[2] << 6) + (xyz_values[3] >> 2); + accel_data->z = ((int16_t)xyz_values[4] << 6) + (xyz_values[5] >> 2); + + /* extend sign to 16 bits */ + if (accel_data->x & BIT(13)) { + accel_data->x |= GENMASK(15, 14); + } + + if (accel_data->y & BIT(13)) { + accel_data->y |= GENMASK(15, 14); + } + + if (accel_data->z & BIT(13)) { + accel_data->z |= GENMASK(15, 14); + } + + return 0; +} + +/** + * @brief Reads the raw temperature of the device. If ADXL367_TEMP_EN is not + * set, use adxl367_temp_read_en() first to enable temperature reading. + * + * @param dev - The device structure. + * @param raw_temp - Raw value of temperature. + * + * @return 0 in case of success, negative error code otherwise. + */ +int adxl367_get_temp_data(const struct device *dev, int16_t *raw_temp) +{ + int ret; + uint8_t temp[2] = { 0 }; + uint8_t reg_data, nready = 1U; + struct adxl367_data *data = dev->data; + + while (nready) { + ret = data->hw_tf->read_reg(dev, ADXL367_STATUS, ®_data); + if (ret) { + return ret; + } + + if (reg_data & ADXL367_STATUS_DATA_RDY) { + nready = 0U; + } + } + + ret = data->hw_tf->read_reg_multiple(dev, ADXL367_TEMP_H, temp, 2); + if (ret) { + return ret; + } + + *raw_temp = ((int16_t)temp[0] << 6) + (temp[1] >> 2); + /* extend sign to 16 bits */ + if (*raw_temp & BIT(13)) { + *raw_temp |= GENMASK(15, 14); + } + + return 0; +} + +static int adxl367_attr_set_thresh(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + const struct adxl367_dev_config *cfg = dev->config; + struct adxl367_activity_threshold threshold; + int64_t llvalue; + int32_t value; + int64_t micro_ms2 = val->val1 * 1000000LL + val->val2; + + llvalue = llabs((micro_ms2 * 10) / SENSOR_G); + + value = (int32_t) llvalue; + + threshold.value = value; + threshold.enable = cfg->activity_th.enable; + threshold.referenced = cfg->activity_th.referenced; + + switch (chan) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + if (attr == SENSOR_ATTR_UPPER_THRESH) { + return adxl367_setup_activity_detection(dev, &threshold); + } else { + return adxl367_setup_inactivity_detection(dev, &threshold); + } + + default: + LOG_ERR("attr_set() not supported on this channel"); + return -ENOTSUP; + } +} + +static int adxl367_attr_set_odr(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + enum adxl367_odr odr; + + switch (val->val1) { + case 12: + case 13: + odr = ADXL367_ODR_12P5HZ; + break; + case 25: + odr = ADXL367_ODR_25HZ; + break; + case 50: + odr = ADXL367_ODR_50HZ; + break; + case 100: + odr = ADXL367_ODR_100HZ; + break; + case 200: + odr = ADXL367_ODR_200HZ; + break; + case 400: + odr = ADXL367_ODR_400HZ; + break; + default: + return -EINVAL; + } + + return adxl367_set_output_rate(dev, odr); +} + +static int adxl367_attr_set(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + switch (attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return adxl367_attr_set_odr(dev, chan, attr, val); + case SENSOR_ATTR_UPPER_THRESH: + case SENSOR_ATTR_LOWER_THRESH: + return adxl367_attr_set_thresh(dev, chan, attr, val); + default: + return -ENOTSUP; + } +} + +static int adxl367_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct adxl367_data *data = dev->data; + int ret; + + ret = adxl367_get_accel_data(dev, &data->sample); + if (ret) { + return ret; + } + + return adxl367_get_temp_data(dev, &data->temp_val); +} + +static void adxl367_accel_convert(const struct device *dev, + struct sensor_value *val, int16_t value) +{ + struct adxl367_data *data = dev->data; + + int64_t micro_ms2 = value * (SENSOR_G * 250 / 10000 * + adxl367_scale_mul[data->range] / 1000); + + val->val1 = micro_ms2 / 1000000; + val->val2 = micro_ms2 % 1000000; +} + +static void adxl367_temp_convert(struct sensor_value *val, int16_t value) +{ + int64_t temp_data = (value + ADXL367_TEMP_OFFSET) * ADXL367_TEMP_SCALE; + + val->val1 = temp_data / ADXL367_TEMP_SCALE_DIV; + val->val2 = temp_data % ADXL367_TEMP_SCALE_DIV; +} + +static int adxl367_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct adxl367_data *data = dev->data; + + switch (chan) { + case SENSOR_CHAN_ACCEL_X: + adxl367_accel_convert(dev, val, data->sample.x); + break; + case SENSOR_CHAN_ACCEL_Y: + adxl367_accel_convert(dev, val, data->sample.y); + break; + case SENSOR_CHAN_ACCEL_Z: + adxl367_accel_convert(dev, val, data->sample.z); + break; + case SENSOR_CHAN_ACCEL_XYZ: + adxl367_accel_convert(dev, val++, data->sample.x); + adxl367_accel_convert(dev, val++, data->sample.y); + adxl367_accel_convert(dev, val, data->sample.z); + break; + case SENSOR_CHAN_DIE_TEMP: + adxl367_temp_convert(val, data->temp_val); + default: + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api adxl367_api_funcs = { + .attr_set = adxl367_attr_set, + .sample_fetch = adxl367_sample_fetch, + .channel_get = adxl367_channel_get, +}; + +static int adxl367_probe(const struct device *dev) +{ + const struct adxl367_dev_config *cfg = dev->config; + struct adxl367_data *data = dev->data; + uint8_t dev_id, part_id; + int ret; + + ret = adxl367_reset(dev); + if (ret) { + return ret; + } + + ret = data->hw_tf->read_reg(dev, ADXL367_DEVID, &dev_id); + if (ret) { + return ret; + } + ret = data->hw_tf->read_reg(dev, ADXL367_PART_ID, &part_id); + if (ret) { + return ret; + } + + if (dev_id != ADXL367_DEVID_VAL || part_id != ADXL367_PARTID_VAL) { + LOG_ERR("failed to read id (0x%X:0x%X)\n", dev_id, part_id); + return -ENODEV; + } + + data->range = cfg->range; + + data->act_proc_mode = ADXL367_LOOPED; + + ret = adxl367_self_test(dev); + if (ret) { + return ret; + } + + ret = adxl367_temp_read_en(dev, cfg->temp_en); + if (ret) { + return ret; + } + + ret = adxl367_set_autosleep(dev, cfg->autosleep); + if (ret) { + return ret; + } + + ret = adxl367_set_low_noise(dev, cfg->low_noise); + if (ret) { + return ret; + } + + ret = adxl367_setup_activity_detection(dev, &cfg->activity_th); + if (ret) { + return ret; + } + + ret = adxl367_setup_inactivity_detection(dev, &cfg->inactivity_th); + if (ret) { + return ret; + } + + ret = adxl367_set_activity_time(dev, cfg->activity_time); + if (ret) { + return ret; + } + + ret = adxl367_set_inactivity_time(dev, cfg->inactivity_time); + if (ret) { + return ret; + } + + ret = adxl367_set_output_rate(dev, cfg->odr); + if (ret) { + return ret; + } + + ret = adxl367_fifo_setup(dev, cfg->fifo_config.fifo_mode, + cfg->fifo_config.fifo_format, + cfg->fifo_config.fifo_read_mode, + cfg->fifo_config.fifo_samples); + if (ret) { + return ret; + } + + ret = adxl367_set_op_mode(dev, cfg->op_mode); + if (ret) { + return ret; + } + + ret = adxl367_set_range(dev, data->range); + if (ret) { + return ret; + } + + return adxl367_set_act_proc_mode(dev, data->act_proc_mode); +} + +static int adxl367_init(const struct device *dev) +{ + int ret; + const struct adxl367_dev_config *cfg = dev->config; + + ret = cfg->bus_init(dev); + if (ret) { + LOG_ERR("Failed to initialize sensor bus\n"); + return ret; + } + + return adxl367_probe(dev); +} + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "ADXL367 driver enabled without any devices" +#endif + +/* + * Device creation macro, shared by ADXL367_DEFINE_SPI() and + * ADXL367_DEFINE_I2C(). + */ + +#define ADXL367_DEVICE_INIT(inst) \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, \ + adxl367_init, \ + NULL, \ + &adxl367_data_##inst, \ + &adxl367_config_##inst, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &adxl367_api_funcs); + +#define ADXL367_CONFIG(inst) \ + .odr = DT_INST_PROP(inst, odr), \ + .autosleep = false, \ + .low_noise = false, \ + .temp_en = true, \ + .range = ADXL367_2G_RANGE, \ + .activity_th.value = CONFIG_ADXL367_ACTIVITY_THRESHOLD, \ + .activity_th.referenced = \ + IS_ENABLED(CONFIG_ADXL367_REFERENCED_ACTIVITY_DETECTION_MODE), \ + .activity_th.enable = \ + IS_ENABLED(CONFIG_ADXL367_ACTIVITY_DETECTION_MODE), \ + .activity_time = CONFIG_ADXL367_ACTIVITY_TIME, \ + .inactivity_th.value = CONFIG_ADXL367_INACTIVITY_THRESHOLD, \ + .inactivity_th.referenced = \ + IS_ENABLED(CONFIG_ADXL367_REFERENCED_INACTIVITY_DETECTION_MODE),\ + .inactivity_th.enable = \ + IS_ENABLED(CONFIG_ADXL367_INACTIVITY_DETECTION_MODE), \ + .inactivity_time = CONFIG_ADXL367_INACTIVITY_TIME, \ + .fifo_config.fifo_mode = ADXL367_FIFO_DISABLED, \ + .fifo_config.fifo_format = ADXL367_FIFO_FORMAT_XYZ, \ + .fifo_config.fifo_samples = 128, \ + .fifo_config.fifo_read_mode = ADXL367_14B_CHID, \ + .op_mode = ADXL367_MEASURE, + +/* + * Instantiation macros used when a device is on a SPI bus. + */ + +#define ADXL367_CONFIG_SPI(inst) \ + { \ + .bus_init = adxl367_spi_init, \ + .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8) | \ + SPI_TRANSFER_MSB, 0), \ + ADXL367_CONFIG(inst) \ + } + +#define ADXL367_DEFINE_SPI(inst) \ + static struct adxl367_data adxl367_data_##inst; \ + static const struct adxl367_dev_config adxl367_config_##inst = \ + ADXL367_CONFIG_SPI(inst); \ + ADXL367_DEVICE_INIT(inst) + +/* + * Instantiation macros used when a device is on an I2C bus. + */ + +#define ADXL367_CONFIG_I2C(inst) \ + { \ + .bus_init = adxl367_i2c_init, \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + ADXL367_CONFIG(inst) \ + } + +#define ADXL367_DEFINE_I2C(inst) \ + static struct adxl367_data adxl367_data_##inst; \ + static const struct adxl367_dev_config adxl367_config_##inst = \ + ADXL367_CONFIG_I2C(inst); \ + ADXL367_DEVICE_INIT(inst) +/* + * Main instantiation macro. Use of COND_CODE_1() selects the right + * bus-specific macro at preprocessor time. + */ + +#define ADXL367_DEFINE(inst) \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (ADXL367_DEFINE_SPI(inst)), \ + (ADXL367_DEFINE_I2C(inst))) + +DT_INST_FOREACH_STATUS_OKAY(ADXL367_DEFINE) diff --git a/drivers/sensor/adxl367/adxl367.h b/drivers/sensor/adxl367/adxl367.h new file mode 100644 index 00000000000..0b7b44faea4 --- /dev/null +++ b/drivers/sensor/adxl367/adxl367.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2023 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ADXL367_ADXL367_H_ +#define ZEPHYR_DRIVERS_SENSOR_ADXL367_ADXL367_H_ + +#include +#include +#include +#include +#include +#include + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ + +/* + * ADXL367 registers definition + */ +#define ADXL367_DEVID 0x00u /* Analog Devices accelerometer ID */ +#define ADXL367_DEVID_MST 0x01u /* Analog Devices MEMS device ID */ +#define ADXL367_PART_ID 0x02u /* Device ID */ +#define ADXL367_REV_ID 0x03u /* product revision ID*/ +#define ADXL367_SERIAL_NR_3 0x04u /* Serial Number 3 */ +#define ADXL367_SERIAL_NR_2 0x05u /* Serial Number 2 */ +#define ADXL367_SERIAL_NR_1 0x06u /* Serial Number 1 */ +#define ADXL367_SERIAL_NR_0 0x07u /* Serial Number 0 */ +#define ADXL367_XDATA 0x08u /* X-axis acceleration data [13:6] */ +#define ADXL367_YDATA 0x09u /* Y-axis acceleration data [13:6] */ +#define ADXL367_ZDATA 0x0Au /* Z-axis acceleration data [13:6] */ +#define ADXL367_STATUS 0x0Bu /* Status */ +#define ADXL367_FIFO_ENTRIES_L 0x0Cu /* FIFO Entries Low */ +#define ADXL367_FIFO_ENTRIES_H 0x0Du /* FIFO Entries High */ +#define ADXL367_X_DATA_H 0x0Eu /* X-axis acceleration data [13:6] */ +#define ADXL367_X_DATA_L 0x0Fu /* X-axis acceleration data [5:0] */ +#define ADXL367_Y_DATA_H 0x10u /* Y-axis acceleration data [13:6] */ +#define ADXL367_Y_DATA_L 0x11u /* Y-axis acceleration data [5:0] */ +#define ADXL367_Z_DATA_H 0x12u /* Z-axis acceleration data [13:6] */ +#define ADXL367_Z_DATA_L 0x13u /* Z-axis acceleration data [5:0] */ +#define ADXL367_TEMP_H 0x14u /* Temperate data [13:6] */ +#define ADXL367_TEMP_L 0x15u /* Temperate data [5:0] */ +#define ADXL367_EX_ADC_H 0x16u /* Extended ADC data [13:6] */ +#define ADXL367_EX_ADC_L 0x17u /* Extended ADC data [5:0] */ +#define ADXL367_I2C_FIFO_DATA 0x18u /* I2C FIFO Data address */ +#define ADXL367_SOFT_RESET 0x1Fu /* Software reset register */ +#define ADXL367_THRESH_ACT_H 0x20u /* Activity Threshold [12:6] */ +#define ADXL367_THRESH_ACT_L 0x21u /* Activity Threshold [5:0] */ +#define ADXL367_TIME_ACT 0x22u /* Activity Time */ +#define ADXL367_THRESH_INACT_H 0x23u /* Inactivity Threshold [12:6] */ +#define ADXL367_THRESH_INACT_L 0x24u /* Inactivity Threshold [5:0] */ +#define ADXL367_TIME_INACT_H 0x25u /* Inactivity Time [12:6] */ +#define ADXL367_TIME_INACT_L 0x26u /* Inactivity Time [5:0] */ +#define ADXL367_ACT_INACT_CTL 0x27u /* Activity Inactivity Control */ +#define ADXL367_FIFO_CONTROL 0x28u /* FIFO Control */ +#define ADXL367_FIFO_SAMPLES 0x29u /* FIFO Samples */ +#define ADXL367_INTMAP1_LOWER 0x2Au /* Interrupt 1 mapping control lower */ +#define ADXL367_INTMAP2_LOWER 0x2Bu /* Interrupt 2 mapping control lower */ +#define ADXL367_FILTER_CTL 0x2Cu /* Filter Control register */ +#define ADXL367_POWER_CTL 0x2Du /* Power Control register */ +#define ADXL367_SELF_TEST 0x2Eu /* Self Test */ +#define ADXL367_TAP_THRESH 0x2Fu /* Tap Threshold */ +#define ADXL367_TAP_DUR 0x30u /* Tap Duration */ +#define ADXL367_TAP_LATENT 0x31u /* Tap Latency */ +#define ADXL367_TAP_WINDOW 0x32u /* Tap Window */ +#define ADXL367_X_OFFSET 0x33u /* X-axis offset */ +#define ADXL367_Y_OFFSET 0x34u /* Y-axis offset */ +#define ADXL367_Z_OFFSET 0x35u /* Z-axis offset */ +#define ADXL367_X_SENS 0x36u /* X-axis user sensitivity */ +#define ADXL367_Y_SENS 0x37u /* Y-axis user sensitivity */ +#define ADXL367_Z_SENS 0x38u /* Z-axis user sensitivity */ +#define ADXL367_TIMER_CTL 0x39u /* Timer Control */ +#define ADXL367_INTMAP1_UPPER 0x3Au /* Interrupt 1 mapping control upper */ +#define ADXL367_INTMAP2_UPPER 0x3Bu /* Interrupt 2 mapping control upper */ +#define ADXL367_ADC_CTL 0x3Cu /* ADC Control Register */ +#define ADXL367_TEMP_CTL 0x3Du /* Temperature Control Register */ +#define ADXL367_TEMP_ADC_OTH_H 0x3Eu /* Temperature ADC Over Threshold [12:6]*/ +#define ADXL367_TEMP_ADC_OTH_L 0x3Fu /* Temperature ADC Over Threshold [5:0]*/ +#define ADXL367_TEMP_ADC_UTH_H 0x40u /* Temperature ADC Under Threshold [12:6]*/ +#define ADXL367_TEMP_ADC_UTH_L 0x41u /* Temperature ADC Under Threshold [5:0]*/ +#define ADXL367_TEMP_ADC_TIMER 0x42u /* Temperature Activiy Inactivity Timer */ +#define ADXL367_AXIS_MASK 0x43u /* Axis Mask Register */ +#define ADXL367_STATUS_COPY 0x44u /* Status Copy Register */ +#define ADXL367_STATUS2 0x45u /* Status 2 Register */ + +#define ADXL367_DEVID_VAL 0xADu /* Analog Devices accelerometer ID */ +#define ADXL367_MST_DEVID_VAL 0x1Du /* Analog Devices MEMS device ID */ +#define ADXL367_PARTID_VAL 0xF7u /* Device ID */ +#define ADXL367_REVID_VAL 0x03u /* product revision ID*/ +#define ADXL367_RESET_CODE 0x52u /* Writing code 0x52 resets the device */ + +#define ADXL367_READ 0x01u +#define ADXL367_REG_READ(x) (((x & 0xFF) << 1) | ADXL367_READ) +#define ADXL367_REG_WRITE(x) ((x & 0xFF) << 1) +#define ADXL367_TO_REG(x) ((x) >> 1) +#define ADXL367_SPI_WRITE_REG 0x0Au +#define ADXL367_SPI_READ_REG 0x0Bu + +#define ADXL367_ABSOLUTE 0x00 +#define ADXL367_REFERENCED 0x01 + +/* ADXL367_POWER_CTL */ +#define ADXL367_POWER_CTL_EXT_CLK_MSK BIT(6) +#define ADXL367_POWER_CTL_NOISE_MSK GENMASK(5, 4) +#define ADXL367_POWER_CTL_WAKEUP_MSK BIT(3) +#define ADXL367_POWER_CTL_AUTOSLEEP_MSK BIT(2) +#define ADXL367_POWER_CTL_MEASURE_MSK GENMASK(1, 0) + +/* ADXL367_ACT_INACT_CTL */ +#define ADXL367_ACT_INACT_CTL_LINKLOOP_MSK GENMASK(5, 4) +#define ADXL367_ACT_INACT_CTL_INACT_REF_MSK BIT(3) +#define ADXL367_ACT_INACT_CTL_INACT_EN_MSK BIT(2) +#define ADXL367_ACT_INACT_CTL_ACT_REF_MSK BIT(1) +#define ADXL367_ACT_INACT_CTL_ACT_EN_MSK BIT(0) + +/* ADXL367_ACT_INACT_CTL_INACT_EN options */ +#define ADXL367_NO_INACTIVITY_DETECTION_ENABLED 0x0 +#define ADXL367_INACTIVITY_ENABLE 0x1 +#define ADXL367_NO_INACTIVITY_DETECTION_ENABLED_2 0x2 +#define ADXL367_REFERENCED_INACTIVITY_ENABLE 0x3 + +/* ADXL367_ACT_INACT_CTL_ACT_EN options */ +#define ADXL367_NO_ACTIVITY_DETECTION 0x0 +#define ADXL367_ACTIVITY_ENABLE 0x1 +#define ADXL367_NO_ACTIVITY_DETECTION_2 0x2 +#define ADXL367_REFERENCED_ACTIVITY_ENABLE 0x3 + +#define ADXL367_TEMP_OFFSET 1185 +#define ADXL367_TEMP_25C 165 +#define ADXL367_TEMP_SCALE 18518518LL +#define ADXL367_TEMP_SCALE_DIV 1000000000 + +#define ADXL367_THRESH_H_MSK GENMASK(6, 0) +#define ADXL367_THRESH_L_MSK GENMASK(7, 2) + +/* ADXL367_REG_TEMP_CTL definitions. */ +#define ADXL367_TEMP_INACT_EN_MSK BIT(3) +#define ADXL367_TEMP_ACT_EN_MSK BIT(1) +#define ADXL367_TEMP_EN_MSK BIT(0) + +/* ADXL367_SELF_TEST */ +#define ADXL367_SELF_TEST_ST_FORCE_MSK BIT(1) +#define ADXL367_SELF_TEST_ST_MSK BIT(0) + +/* ADXL367_REG_FILTER_CTL definitions */ +#define ADXL367_FILTER_CTL_RANGE_MSK GENMASK(7, 6) +#define ADXL367_FILTER_I2C_HS BIT(5) +#define ADXL367_FILTER_CTL_RES BIT(4) +#define ADXL367_FILTER_CTL_EXT_SAMPLE BIT(3) +#define ADXL367_FILTER_CTL_ODR_MSK GENMASK(2, 0) + +/* ADXL367_REG_FIFO_CONTROL */ +#define ADXL367_FIFO_CONTROL_FIFO_CHANNEL_MSK GENMASK(6, 3) +#define ADXL367_FIFO_CONTROL_FIFO_SAMPLES_MSK BIT(2) +#define ADXL367_FIFO_CONTROL_FIFO_MODE_MSK GENMASK(1, 0) + +/* ADXL367_REG_ADC_CTL definitions. */ +#define ADXL367_FIFO_8_12BIT_MSK GENMASK(7, 6) +#define ADXL367_ADC_INACT_EN BIT(3) +#define ADXL367_ADC_ACT_EN BIT(1) +#define ADXL367_ADC_EN BIT(0) + +/* ADXL367_REG_STATUS definitions */ +#define ADXL367_STATUS_ERR_USER_REGS BIT(7) +#define ADXL367_STATUS_AWAKE BIT(6) +#define ADXL367_STATUS_INACT BIT(5) +#define ADXL367_STATUS_ACT BIT(4) +#define ADXL367_STATUS_FIFO_OVERRUN BIT(3) +#define ADXL367_STATUS_FIFO_WATERMARK BIT(2) +#define ADXL367_STATUS_FIFO_RDY BIT(1) +#define ADXL367_STATUS_DATA_RDY BIT(0) + +/* Min change = 90mg. Sensitivity = 4LSB / mg */ +#define ADXL367_SELF_TEST_MIN (90 * 100 / 25) +/* Max change = 270mg. Sensitivity = 4LSB / mg */ +#define ADXL367_SELF_TEST_MAX (270 * 100 / 25) + +enum adxl367_axis { + ADXL367_X_AXIS, + ADXL367_Y_AXIS, + ADXL367_Z_AXIS +}; + +enum adxl367_op_mode { + ADXL367_STANDBY = 0, + ADXL367_MEASURE = 2, +}; + +enum adxl367_range { + ADXL367_2G_RANGE, + ADXL367_4G_RANGE, + ADXL367_8G_RANGE, +}; + +enum adxl367_act_proc_mode { + ADXL367_DEFAULT = 0, + ADXL367_LINKED = 1, + ADXL367_LOOPED = 3, +}; + +enum adxl367_odr { + ADXL367_ODR_12P5HZ, + ADXL367_ODR_25HZ, + ADXL367_ODR_50HZ, + ADXL367_ODR_100HZ, + ADXL367_ODR_200HZ, + ADXL367_ODR_400HZ, +}; + +enum adxl367_fifo_format { + ADXL367_FIFO_FORMAT_XYZ, + ADXL367_FIFO_FORMAT_X, + ADXL367_FIFO_FORMAT_Y, + ADXL367_FIFO_FORMAT_Z, + ADXL367_FIFO_FORMAT_XYZT, + ADXL367_FIFO_FORMAT_XT, + ADXL367_FIFO_FORMAT_YT, + ADXL367_FIFO_FORMAT_ZT, + ADXL367_FIFO_FORMAT_XYZA, + ADXL367_FIFO_FORMAT_XA, + ADXL367_FIFO_FORMAT_YA, + ADXL367_FIFO_FORMAT_ZA +}; + +enum adxl367_fifo_mode { + ADXL367_FIFO_DISABLED, + ADXL367_OLDEST_SAVED, + ADXL367_STREAM_MODE, + ADXL367_TRIGGERED_MODE +}; + +enum adxl367_fifo_read_mode { + ADXL367_12B_CHID, + ADXL367_8B, + ADXL367_12B, + ADXL367_14B_CHID +}; + +struct adxl367_fifo_config { + enum adxl367_fifo_mode fifo_mode; + enum adxl367_fifo_format fifo_format; + enum adxl367_fifo_read_mode fifo_read_mode; + uint16_t fifo_samples; +}; + +struct adxl367_activity_threshold { + uint16_t value; + bool referenced; + bool enable; +}; + +struct adxl367_xyz_accel_data { + int16_t x; + int16_t y; + int16_t z; +}; + +struct adxl367_transfer_function { + int (*read_reg_multiple)(const struct device *dev, uint8_t reg_addr, + uint8_t *value, uint16_t len); + int (*write_reg)(const struct device *dev, uint8_t reg_addr, + uint8_t value); + int (*read_reg)(const struct device *dev, uint8_t reg_addr, + uint8_t *value); + int (*write_reg_mask)(const struct device *dev, uint8_t reg_addr, + uint32_t mask, uint8_t value); +}; + +struct adxl367_data { + struct adxl367_xyz_accel_data sample; + int16_t temp_val; + const struct adxl367_transfer_function *hw_tf; + struct adxl367_fifo_config fifo_config; + enum adxl367_act_proc_mode act_proc_mode; + enum adxl367_range range; +}; + +struct adxl367_dev_config { +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + struct i2c_dt_spec i2c; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) + struct spi_dt_spec spi; +#endif + int (*bus_init)(const struct device *dev); + + enum adxl367_odr odr; + + /* Device Settings */ + bool autosleep; + bool low_noise; + bool temp_en; + + struct adxl367_activity_threshold activity_th; + struct adxl367_activity_threshold inactivity_th; + struct adxl367_fifo_config fifo_config; + + enum adxl367_range range; + enum adxl367_op_mode op_mode; + + uint16_t inactivity_time; + uint8_t activity_time; +}; + +int adxl367_spi_init(const struct device *dev); +int adxl367_i2c_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ADXL367_ADXL367_H_ */ diff --git a/drivers/sensor/adxl367/adxl367_i2c.c b/drivers/sensor/adxl367/adxl367_i2c.c new file mode 100644 index 00000000000..2c7d168c224 --- /dev/null +++ b/drivers/sensor/adxl367/adxl367_i2c.c @@ -0,0 +1,103 @@ +/* adxl367_i2c.c - I2C routines for ADXL367 driver + */ + +/* + * Copyright (c) 2023 Analog Devices + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adxl367 + +#include +#include + +#include "adxl367.h" + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + +LOG_MODULE_DECLARE(ADXL367, CONFIG_SENSOR_LOG_LEVEL); + +static int adxl367_bus_access(const struct device *dev, uint8_t reg, + void *data, size_t length) +{ + const struct adxl367_dev_config *config = dev->config; + + if (reg & ADXL367_READ) { + return i2c_burst_read_dt(&config->i2c, + ADXL367_TO_REG(reg), + (uint8_t *) data, length); + } else { + if (length != 1) + return -EINVAL; + + return i2c_reg_write_byte_dt(&config->i2c, + ADXL367_TO_REG(reg), + *(uint8_t *)data); + } +} + +static int adxl367_i2c_reg_read(const struct device *dev, uint8_t reg_addr, + uint8_t *reg_data) +{ + return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr), reg_data, 1); +} + +static int adxl367_i2c_reg_read_multiple(const struct device *dev, + uint8_t reg_addr, + uint8_t *reg_data, + uint16_t count) +{ + return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr), + reg_data, count); +} + +static int adxl367_i2c_reg_write(const struct device *dev, + uint8_t reg_addr, + uint8_t reg_data) +{ + return adxl367_bus_access(dev, ADXL367_REG_WRITE(reg_addr), + ®_data, 1); +} + + +int adxl367_i2c_reg_write_mask(const struct device *dev, + uint8_t reg_addr, + uint32_t mask, + uint8_t data) +{ + int ret; + uint8_t tmp; + + ret = adxl367_i2c_reg_read(dev, reg_addr, &tmp); + if (ret) { + return ret; + } + + tmp &= ~mask; + tmp |= data; + + return adxl367_i2c_reg_write(dev, reg_addr, tmp); +} + +static const struct adxl367_transfer_function adxl367_i2c_transfer_fn = { + .read_reg_multiple = adxl367_i2c_reg_read_multiple, + .write_reg = adxl367_i2c_reg_write, + .read_reg = adxl367_i2c_reg_read, + .write_reg_mask = adxl367_i2c_reg_write_mask, +}; + +int adxl367_i2c_init(const struct device *dev) +{ + struct adxl367_data *data = dev->data; + const struct adxl367_dev_config *config = dev->config; + + data->hw_tf = &adxl367_i2c_transfer_fn; + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + + return 0; +} +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ diff --git a/drivers/sensor/adxl367/adxl367_spi.c b/drivers/sensor/adxl367/adxl367_spi.c new file mode 100644 index 00000000000..174fcf0bf0a --- /dev/null +++ b/drivers/sensor/adxl367/adxl367_spi.c @@ -0,0 +1,131 @@ +/* adxl367_spi.c - SPI routines for ADXL367 driver + */ + +/* + * Copyright (c) 2023 Analog Devices + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adxl367 + +#include +#include + +#include "adxl367.h" + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) + +LOG_MODULE_DECLARE(ADXL367, CONFIG_SENSOR_LOG_LEVEL); + +static int adxl367_bus_access(const struct device *dev, uint8_t reg, + void *data, size_t length) +{ + const struct adxl367_dev_config *config = dev->config; + uint8_t rw_reg, addr_reg; + + if (reg & ADXL367_READ) { + rw_reg = ADXL367_SPI_READ_REG; + } else { + rw_reg = ADXL367_SPI_WRITE_REG; + } + + addr_reg = ADXL367_TO_REG(reg); + + const struct spi_buf buf[3] = { + { + .buf = &rw_reg, + .len = 1 + }, { + .buf = &addr_reg, + .len = 1 + }, { + .buf = data, + .len = length + } + }; + + struct spi_buf_set tx = { + .buffers = buf, + }; + + if (reg & ADXL367_READ) { + const struct spi_buf_set rx = { + .buffers = buf, + .count = 3 + }; + + tx.count = 2; + + return spi_transceive_dt(&config->spi, &tx, &rx); + } + + tx.count = 3; + + return spi_write_dt(&config->spi, &tx); +} + +static int adxl367_spi_reg_read(const struct device *dev, uint8_t reg_addr, + uint8_t *reg_data) +{ + return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr), reg_data, 1); +} + +static int adxl367_spi_reg_read_multiple(const struct device *dev, + uint8_t reg_addr, + uint8_t *reg_data, + uint16_t count) +{ + return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr), + reg_data, count); +} + +static int adxl367_spi_reg_write(const struct device *dev, + uint8_t reg_addr, + uint8_t reg_data) +{ + return adxl367_bus_access(dev, ADXL367_REG_WRITE(reg_addr), + ®_data, 1); +} + +int adxl367_spi_reg_write_mask(const struct device *dev, + uint8_t reg_addr, + uint32_t mask, + uint8_t data) +{ + int ret; + uint8_t tmp; + + ret = adxl367_spi_reg_read(dev, reg_addr, &tmp); + if (ret) { + return ret; + } + + tmp &= ~mask; + tmp |= data; + + return adxl367_spi_reg_write(dev, reg_addr, tmp); +} + +static const struct adxl367_transfer_function adxl367_spi_transfer_fn = { + .read_reg_multiple = adxl367_spi_reg_read_multiple, + .write_reg = adxl367_spi_reg_write, + .read_reg = adxl367_spi_reg_read, + .write_reg_mask = adxl367_spi_reg_write_mask, +}; + +int adxl367_spi_init(const struct device *dev) +{ + struct adxl367_data *data = dev->data; + const struct adxl367_dev_config *config = dev->config; + + data->hw_tf = &adxl367_spi_transfer_fn; + + if (!spi_is_ready_dt(&config->spi)) { + return -ENODEV; + } + + return 0; +} + +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ From cecfb3e120bbf2a735df8d2c239f0a3c2100527d Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 17 Oct 2023 17:15:31 +0300 Subject: [PATCH 2543/4498] tests: build_all: sensor: spi: add adxl367 Add adxl367 spi node in the build_all tests. Signed-off-by: Antoniu Miclaus --- tests/drivers/build_all/sensor/app.overlay | 3 ++- tests/drivers/build_all/sensor/spi.dtsi | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 506cc1848b2..23b732e9db4 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -120,7 +120,8 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, - <&test_gpio 0 0>; /* 0x25 */ + <&test_gpio 0 0>, /* 0x25 */ + <&test_gpio 0 0>; /* 0x26 */ #include "spi.dtsi" }; diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index 513ffbf4e37..172510894ee 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -295,3 +295,10 @@ test_spi_tmag5170: tmag5170@25 { int-gpios = <&test_gpio 0 0>; operating-mode = <1>; }; + +test_spi_adxl367: adxl367@26 { + compatible = "adi,adxl367"; + reg = <0x26>; + spi-max-frequency = <0>; + odr = <4>; +}; From b5bc088529269dd70210d42366f5d20e24658fc3 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 17 Oct 2023 17:22:02 +0300 Subject: [PATCH 2544/4498] tests: build_all: sensor: i2c: add adxl367 Add adxl367 i2c node in the build_all tests. Signed-off-by: Antoniu Miclaus --- tests/drivers/build_all/sensor/i2c.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b0450a27f90..ae04cc44112 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -787,3 +787,9 @@ test_i2c_ltrf216a0: ltrf216a@76 { compatible = "ltr,f216a"; reg = <0x76>; }; + +test_i2c_adxl367: adxl367@77 { + compatible = "adi,adxl367"; + reg = <0x77>; + odr = <4>; +}; From bc8b7dd6dd36e0ae6b256353bf967c3568b907a7 Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Wed, 11 Oct 2023 21:04:15 +0200 Subject: [PATCH 2545/4498] testsuite: coverage: allow gcov data dump directly on console When there is no buffer for gcov hex data, dump them directly to console. This saves RAM which can be used to hold more gcov data. Reduce number of gcov hex data send by console - do not send space between every two digits. Signed-off-by: Piotr Kosycarz --- subsys/testsuite/Kconfig | 12 ++- subsys/testsuite/coverage/coverage.c | 149 ++++++++++++++++----------- 2 files changed, 100 insertions(+), 61 deletions(-) diff --git a/subsys/testsuite/Kconfig b/subsys/testsuite/Kconfig index e2e7fba764e..eff533a9da2 100644 --- a/subsys/testsuite/Kconfig +++ b/subsys/testsuite/Kconfig @@ -78,7 +78,8 @@ config COVERAGE_GCOV_HEAP_SIZE default 16384 help This option configures the heap size allocated for gcov coverage - data to be dumped over serial. + data to be dumped over serial. If the value is 0, no buffer will be used, + data will be dumped directly over serial. config COVERAGE_DUMP bool "Dump coverage data on exit" @@ -86,6 +87,15 @@ config COVERAGE_DUMP help Dump collected coverage information to console on exit. +config FORCE_COVERAGE + bool "Force coverage" + select HAS_COVERAGE_SUPPORT + help + Regardless of platform support, it will enable coverage data production. + If the platform does not support coverage by default, setting this config + does not guarantee that coverage data will be gathered. + Application may not fit memory or crash at runtime. + config TEST_USERSPACE bool "Indicate that this test exercises user mode" help diff --git a/subsys/testsuite/coverage/coverage.c b/subsys/testsuite/coverage/coverage.c index e787135ffdc..dc120c14605 100644 --- a/subsys/testsuite/coverage/coverage.c +++ b/subsys/testsuite/coverage/coverage.c @@ -36,25 +36,54 @@ void __gcov_exit(void) } /** - * buff_write_u64 - Store 64 bit data on a buffer and return the size + * print_u8 - Print 8 bit of gcov data + */ +static inline void print_u8(uint8_t v) +{ + printk("%02x", v); +} + +/** + * print_u32 - Print 32 bit of gcov data + */ +static inline void print_u32(uint32_t v) +{ + uint8_t *ptr = (uint8_t *)&v; + + print_u8(*ptr); + print_u8(*(ptr+1)); + print_u8(*(ptr+2)); + print_u8(*(ptr+3)); +} + +/** + * write_u64 - Store 64 bit data on a buffer and return the size */ -static inline void buff_write_u64(void *buffer, size_t *off, uint64_t v) +static inline void write_u64(void *buffer, size_t *off, uint64_t v) { - memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v)); + if (buffer != NULL) { + memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v)); + } else { + print_u32(*((uint32_t *)&v)); + print_u32(*(((uint32_t *)&v) + 1)); + } *off = *off + sizeof(uint64_t); } /** - * buff_write_u32 - Store 32 bit data on a buffer and return the size + * write_u32 - Store 32 bit data on a buffer and return the size */ -static inline void buff_write_u32(void *buffer, size_t *off, uint32_t v) +static inline void write_u32(void *buffer, size_t *off, uint32_t v) { - memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v)); + if (buffer != NULL) { + memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v)); + } else { + print_u32(v); + } *off = *off + sizeof(uint32_t); } - size_t calculate_buff_size(struct gcov_info *info) { uint32_t iter; @@ -102,14 +131,13 @@ size_t calculate_buff_size(struct gcov_info *info) return size; } - /** - * populate_buffer - convert from gcov data set (info) to + * gcov_to_gcda - convert from gcov data set (info) to * .gcda file format. * This buffer will now have info similar to a regular gcda * format. */ -size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) +size_t gcov_to_gcda(uint8_t *buffer, struct gcov_info *info) { struct gcov_fn_info *functions; struct gcov_ctr_info *counters_per_func; @@ -119,22 +147,22 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) size_t buffer_write_position = 0; /* File header. */ - buff_write_u32(buffer, - &buffer_write_position, - GCOV_DATA_MAGIC); + write_u32(buffer, + &buffer_write_position, + GCOV_DATA_MAGIC); - buff_write_u32(buffer, - &buffer_write_position, - info->version); + write_u32(buffer, + &buffer_write_position, + info->version); - buff_write_u32(buffer, - &buffer_write_position, - info->stamp); + write_u32(buffer, + &buffer_write_position, + info->stamp); #ifdef GCOV_12_FORMAT - buff_write_u32(buffer, - &buffer_write_position, - info->checksum); + write_u32(buffer, + &buffer_write_position, + info->checksum); #endif for (iter_functions = 0U; @@ -144,25 +172,25 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) functions = info->functions[iter_functions]; - buff_write_u32(buffer, - &buffer_write_position, - GCOV_TAG_FUNCTION); + write_u32(buffer, + &buffer_write_position, + GCOV_TAG_FUNCTION); - buff_write_u32(buffer, - &buffer_write_position, - GCOV_TAG_FUNCTION_LENGTH); + write_u32(buffer, + &buffer_write_position, + GCOV_TAG_FUNCTION_LENGTH); - buff_write_u32(buffer, - &buffer_write_position, - functions->ident); + write_u32(buffer, + &buffer_write_position, + functions->ident); - buff_write_u32(buffer, - &buffer_write_position, - functions->lineno_checksum); + write_u32(buffer, + &buffer_write_position, + functions->lineno_checksum); - buff_write_u32(buffer, - &buffer_write_position, - functions->cfg_checksum); + write_u32(buffer, + &buffer_write_position, + functions->cfg_checksum); counters_per_func = functions->ctrs; @@ -174,29 +202,28 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) continue; } - buff_write_u32(buffer, - &buffer_write_position, - GCOV_TAG_FOR_COUNTER(iter_counts)); + write_u32(buffer, + &buffer_write_position, + GCOV_TAG_FOR_COUNTER(iter_counts)); #ifdef GCOV_12_FORMAT /* GCOV 12 counts the length by bytes */ - buff_write_u32(buffer, - &buffer_write_position, - counters_per_func->num * 2U * 4); + write_u32(buffer, + &buffer_write_position, + counters_per_func->num * 2U * 4); #else - buff_write_u32(buffer, - &buffer_write_position, - counters_per_func->num * 2U); + write_u32(buffer, + &buffer_write_position, + counters_per_func->num * 2U); #endif for (iter_counter_values = 0U; iter_counter_values < counters_per_func->num; iter_counter_values++) { - buff_write_u64(buffer, - &buffer_write_position, - counters_per_func->\ - values[iter_counter_values]); + write_u64(buffer, + &buffer_write_position, + counters_per_func->values[iter_counter_values]); } counters_per_func++; @@ -205,20 +232,21 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) return buffer_write_position; } -void dump_on_console(const char *filename, char *ptr, size_t len) +void dump_on_console_start(const char *filename) { - uint32_t iter; - printk("\n%c", FILE_START_INDICATOR); while (*filename != '\0') { printk("%c", *filename++); } printk("%c", GCOV_DUMP_SEPARATOR); +} - /* Data dump */ - - for (iter = 0U; iter < len; iter++) { - printk(" %02x", (uint8_t)*ptr++); +void dump_on_console_data(char *ptr, size_t len) +{ + if (ptr != NULL) { + for (size_t iter = 0U; iter < len; iter++) { + print_u8((uint8_t)*ptr++); + } } } @@ -237,21 +265,22 @@ void gcov_coverage_dump(void) printk("\nGCOV_COVERAGE_DUMP_START"); while (gcov_list) { + dump_on_console_start(gcov_list->filename); size = calculate_buff_size(gcov_list); buffer = k_heap_alloc(&gcov_heap, size, K_NO_WAIT); - if (!buffer) { + if (CONFIG_COVERAGE_GCOV_HEAP_SIZE > 0 && !buffer) { printk("No Mem available to continue dump\n"); goto coverage_dump_end; } - written_size = populate_buffer(buffer, gcov_list); + written_size = gcov_to_gcda(buffer, gcov_list); if (written_size != size) { printk("Write Error on buff\n"); goto coverage_dump_end; } - dump_on_console(gcov_list->filename, buffer, size); + dump_on_console_data(buffer, size); k_heap_free(&gcov_heap, buffer); gcov_list = gcov_list->next; From 861cab4a2a7aeea12bf6785eb1fe0f34f1908410 Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Wed, 11 Oct 2023 21:11:14 +0200 Subject: [PATCH 2546/4498] scripts: twister: extend test timeout to get gcov data When coverage is enabled, gather console logs longer to receive gcov data which are send after test output. Signed-off-by: Piotr Kosycarz --- scripts/pylib/twister/twisterlib/handlers.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index e4a0d9f5a1a..2ffeb4bfc19 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -358,6 +358,13 @@ def __init__(self, instance, type_str): """ super().__init__(instance, type_str) + def get_test_timeout(self): + timeout = super().get_test_timeout() + if self.options.coverage: + # wait more for gcov data to be dumped on console + timeout += 120 + return timeout + def monitor_serial(self, ser, halt_event, harness): log_out_fp = open(self.log, "wb") From 8c5a15aac4436849e603d171c1070dcf4ab306e4 Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Wed, 11 Oct 2023 21:14:12 +0200 Subject: [PATCH 2547/4498] scripts: twister: get status of coverage data processing Do not break processing when incorrect coverage data are received. Instead, report failures but still process valid data. Include coverage processing status within twister retrun code. Signed-off-by: Piotr Kosycarz --- scripts/pylib/twister/twisterlib/coverage.py | 30 +++++++++++++++---- .../pylib/twister/twisterlib/twister_main.py | 4 ++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/coverage.py b/scripts/pylib/twister/twisterlib/coverage.py index 067dcfbcca7..c215ae5bd83 100644 --- a/scripts/pylib/twister/twisterlib/coverage.py +++ b/scripts/pylib/twister/twisterlib/coverage.py @@ -71,6 +71,7 @@ def retrieve_gcov_data(input_file): @staticmethod def create_gcda_files(extracted_coverage_info): + gcda_created = True logger.debug("Generating gcda files") for filename, hexdump_val in extracted_coverage_info.items(): # if kobject_hash is given for coverage gcovr fails @@ -83,19 +84,33 @@ def create_gcda_files(extracted_coverage_info): pass continue - with open(filename, 'wb') as fp: - fp.write(bytes.fromhex(hexdump_val)) + try: + with open(filename, 'wb') as fp: + fp.write(bytes.fromhex(hexdump_val)) + except ValueError: + logger.exception("Unable to convert hex data for file: {}".format(filename)) + gcda_created = False + except FileNotFoundError: + logger.exception("Unable to create gcda file: {}".format(filename)) + gcda_created = False + return gcda_created def generate(self, outdir): + coverage_completed = True for filename in glob.glob("%s/**/handler.log" % outdir, recursive=True): gcov_data = self.__class__.retrieve_gcov_data(filename) capture_complete = gcov_data['complete'] extracted_coverage_info = gcov_data['data'] if capture_complete: - self.__class__.create_gcda_files(extracted_coverage_info) - logger.debug("Gcov data captured: {}".format(filename)) + gcda_created = self.__class__.create_gcda_files(extracted_coverage_info) + if gcda_created: + logger.debug("Gcov data captured: {}".format(filename)) + else: + logger.error("Gcov data invalid for: {}".format(filename)) + coverage_completed = False else: logger.error("Gcov data capture incomplete: {}".format(filename)) + coverage_completed = False with open(os.path.join(outdir, "coverage.log"), "a") as coveragelog: ret = self._generate(outdir, coveragelog) @@ -111,6 +126,10 @@ def generate(self, outdir): } for r in self.output_formats.split(','): logger.info(report_log[r]) + else: + coverage_completed = False + logger.debug("All coverage data processed: {}".format(coverage_completed)) + return coverage_completed class Lcov(CoverageTool): @@ -280,4 +299,5 @@ def run_coverage(testplan, options): coverage_tool.add_ignore_file('generated') coverage_tool.add_ignore_directory('tests') coverage_tool.add_ignore_directory('samples') - coverage_tool.generate(options.outdir) + coverage_completed = coverage_tool.generate(options.outdir) + return coverage_completed diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index 336c95f3609..8f4b4f64893 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -207,9 +207,10 @@ def main(options): report.summary(runner.results, options.disable_unrecognized_section_test, duration) + coverage_completed = True if options.coverage: if not options.build_only: - run_coverage(tplan, options) + coverage_completed = run_coverage(tplan, options) else: logger.info("Skipping coverage report generation due to --build-only.") @@ -235,6 +236,7 @@ def main(options): runner.results.failed or runner.results.error or (tplan.warnings and options.warnings_as_errors) + or (options.coverage and not coverage_completed) ): return 1 From dd154406baff84b691c6c8f4c220221dec27833c Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 20 Oct 2023 19:52:32 +0800 Subject: [PATCH 2548/4498] shell: make the backend thread name variable generic Rename the shell backend `thread_name` variable to just `name`, to be used for other things not specific to thread later. Signed-off-by: Yong Cong Sin --- include/zephyr/shell/shell.h | 4 ++-- subsys/shell/shell.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index d75814e08b9..22841392d70 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -863,7 +863,7 @@ struct shell { LOG_INSTANCE_PTR_DECLARE(log); - const char *thread_name; + const char *name; struct k_thread *thread; k_thread_stack_t *stack; }; @@ -910,7 +910,7 @@ extern void z_shell_print_stream(const void *user_ctx, const char *data, .stats = Z_SHELL_STATS_PTR(_name), \ .log_backend = Z_SHELL_LOG_BACKEND_PTR(_name), \ LOG_INSTANCE_PTR_INIT(log, shell, _name) \ - .thread_name = STRINGIFY(_name), \ + .name = STRINGIFY(_name), \ .thread = &_name##_thread, \ .stack = _name##_stack \ } diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 1a803d73339..ace9e50d56e 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1392,7 +1392,7 @@ int shell_init(const struct shell *sh, const void *transport_config, SHELL_THREAD_PRIORITY, 0, K_NO_WAIT); sh->ctx->tid = tid; - k_thread_name_set(tid, sh->thread_name); + k_thread_name_set(tid, sh->name); return 0; } From a0682880910e066adb070fbd19ba19abb8d995e6 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 20 Oct 2023 19:58:00 +0800 Subject: [PATCH 2549/4498] shell: add new APIs to get the backend instances Added some new APIs to get the backend instances more easily, so that dev does not need to rely on `shell_backend_*_get_ptr`, which looks more like a hack to access a local variable. These APIs are basically copied from the log backend implementation. Added testcase for the APIs. Signed-off-by: Yong Cong Sin --- include/zephyr/shell/shell_backend.h | 61 +++++++++++++++++++ subsys/shell/shell.c | 11 ++++ .../subsys/shell/shell_backend/CMakeLists.txt | 8 +++ tests/subsys/shell/shell_backend/prj.conf | 8 +++ .../shell_backend/src/shell_backend_test.c | 41 +++++++++++++ .../subsys/shell/shell_backend/testcase.yaml | 10 +++ 6 files changed, 139 insertions(+) create mode 100644 include/zephyr/shell/shell_backend.h create mode 100644 tests/subsys/shell/shell_backend/CMakeLists.txt create mode 100644 tests/subsys/shell/shell_backend/prj.conf create mode 100644 tests/subsys/shell/shell_backend/src/shell_backend_test.c create mode 100644 tests/subsys/shell/shell_backend/testcase.yaml diff --git a/include/zephyr/shell/shell_backend.h b/include/zephyr/shell/shell_backend.h new file mode 100644 index 00000000000..ae8f8a5afc3 --- /dev/null +++ b/include/zephyr/shell/shell_backend.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SHELL_BACKEND_H__ +#define SHELL_BACKEND_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get backend. + * + * @param[in] idx Pointer to the backend instance. + * + * @return Pointer to the backend instance. + */ +static inline const struct shell *shell_backend_get(uint32_t idx) +{ + const struct shell *backend; + + STRUCT_SECTION_GET(shell, idx, &backend); + + return backend; +} + +/** + * @brief Get number of backends. + * + * @return Number of backends. + */ +static inline int shell_backend_count_get(void) +{ + int cnt; + + STRUCT_SECTION_COUNT(shell, &cnt); + + return cnt; +} + +/** + * @brief Get backend by name. + * + * @param[in] backend_name Name of the backend as defined by the SHELL_DEFINE. + * + * @retval Pointer to the backend instance if found, NULL if backend is not found. + */ +const struct shell *shell_backend_get_by_name(const char *backend_name); + +#ifdef __cplusplus +} +#endif + +#endif /* SHELL_BACKEND_H__ */ diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index ace9e50d56e..efff35e2631 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1488,6 +1488,17 @@ void shell_process(const struct shell *sh) z_flag_processing_set(sh, false); } +const struct shell *shell_backend_get_by_name(const char *backend_name) +{ + STRUCT_SECTION_FOREACH(shell, backend) { + if (strcmp(backend_name, backend->name) == 0) { + return backend; + } + } + + return NULL; +} + /* This function mustn't be used from shell context to avoid deadlock. * However it can be used in shell command handlers. */ diff --git a/tests/subsys/shell/shell_backend/CMakeLists.txt b/tests/subsys/shell/shell_backend/CMakeLists.txt new file mode 100644 index 00000000000..a8fae2b9931 --- /dev/null +++ b/tests/subsys/shell/shell_backend/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(shell) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/shell/shell_backend/prj.conf b/tests/subsys/shell/shell_backend/prj.conf new file mode 100644 index 00000000000..ccaddfdeb1e --- /dev/null +++ b/tests/subsys/shell/shell_backend/prj.conf @@ -0,0 +1,8 @@ +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_DUMMY=y +CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_SHELL_CMD_BUFF_SIZE=90 +CONFIG_SHELL_PRINTF_BUFF_SIZE=15 +CONFIG_SHELL_METAKEYS=n +CONFIG_LOG=n +CONFIG_ZTEST=y diff --git a/tests/subsys/shell/shell_backend/src/shell_backend_test.c b/tests/subsys/shell/shell_backend/src/shell_backend_test.c new file mode 100644 index 00000000000..935c0902088 --- /dev/null +++ b/tests/subsys/shell/shell_backend/src/shell_backend_test.c @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include + +ZTEST(shell_backend, test_backend_apis) +{ + const struct shell *sh_dummy = shell_backend_get_by_name("shell_dummy"); + const struct shell *sh_uart = shell_backend_get_by_name("shell_uart"); + + zassert_equal(shell_backend_count_get(), 2, "Expecting 2, got %d", + shell_backend_count_get()); + + zassert_equal_ptr(sh_dummy, shell_backend_dummy_get_ptr(), + "Unexpected shell_dummy backend"); + zassert_equal_ptr(sh_uart, shell_backend_uart_get_ptr(), "Unexpected shell_uart backend"); + zassert_equal_ptr(shell_backend_get_by_name("blah"), NULL, "Should be NULL if not found"); + + zassert_equal_ptr(shell_backend_get(0), sh_dummy < sh_uart ? sh_dummy : sh_uart, + "Unexpected backend at index 0"); + zassert_equal_ptr(shell_backend_get(1), sh_dummy < sh_uart ? sh_uart : sh_dummy, + "Unexpected backend at index 1"); +} + +static void *shell_setup(void) +{ + /* Let the shell backend initialize. */ + k_usleep(10); + return NULL; +} + +ZTEST_SUITE(shell_backend, NULL, shell_setup, NULL, NULL, NULL); diff --git a/tests/subsys/shell/shell_backend/testcase.yaml b/tests/subsys/shell/shell_backend/testcase.yaml new file mode 100644 index 00000000000..eb9e9d2a314 --- /dev/null +++ b/tests/subsys/shell/shell_backend/testcase.yaml @@ -0,0 +1,10 @@ +tests: + shell.backend: + min_flash: 64 + min_ram: 32 + tags: + - shell + filter: ( CONFIG_SHELL ) + platform_allow: + - qemu_x86 + - qemu_riscv32 From 0e2f5c2dbbcbd01855f20579f22daf7e094baf44 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 23 Oct 2023 15:27:57 +0800 Subject: [PATCH 2550/4498] shell: print name and prompt when listing backends The shell name defined with `SHELL_DEFINE` is implicitly guaranteed to be unique while it is possible that more than one shell backends can have the same prompt. Print the name of the shell backend alongside with its prompt to differentiate between the backends. Signed-off-by: Yong Cong Sin --- subsys/shell/shell_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/shell/shell_cmds.c b/subsys/shell/shell_cmds.c index 10a9d6f418f..0932cd4adfc 100644 --- a/subsys/shell/shell_cmds.c +++ b/subsys/shell/shell_cmds.c @@ -231,7 +231,7 @@ static int cmd_backends(const struct shell *sh, size_t argc, char **argv) shell_print(sh, "Active shell backends:"); STRUCT_SECTION_FOREACH(shell, obj) { - shell_print(sh, " %2d. :%s", cnt++, obj->ctx->prompt); + shell_print(sh, " %2d. :%s (%s)", cnt++, obj->ctx->prompt, sh->name); } return 0; From 38f8a4db286c11ff7b7d26dc37581f0b131ff3ae Mon Sep 17 00:00:00 2001 From: Jason Murphy Date: Sun, 22 Oct 2023 17:22:42 +0100 Subject: [PATCH 2551/4498] drivers: ethernet: fix adin2111 devicetree init to work with adin1110 The initialisation of the device data struct was giving a build error when using the adi,adin1110 devicetree compatible. Fixed to allow both adi,adin2111 and adi,adin1110 devices to be defined. Signed-off-by: Jason Murphy --- drivers/ethernet/eth_adin2111.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index c26671b0e3f..e7cdcedc0c6 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -972,8 +972,8 @@ static const struct ethernet_api adin2111_port_api = { static struct adin2111_data name##_data_##inst = { \ .ifaces_left_to_init = ifaces, \ .port = {}, \ - .offload_sem = Z_SEM_INITIALIZER(adin2111_data_##inst.offload_sem, 0, 1), \ - .lock = Z_MUTEX_INITIALIZER(adin2111_data_##inst.lock), \ + .offload_sem = Z_SEM_INITIALIZER(name##_data_##inst.offload_sem, 0, 1), \ + .lock = Z_MUTEX_INITIALIZER(name##_data_##inst.lock), \ .buf = name##_buffer_##inst, \ }; \ /* adin */ \ From 3f5ea785f2287a5a863d08cd2c583928b64339b0 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 17 Oct 2023 05:49:39 -0300 Subject: [PATCH 2552/4498] linker: esp32: fix linker to enable proper MMU usage ESP32 flash_mmap() function requires `_rodata_reserved_start` address to be at the beginning of RODATA. This allows adding memory-mapped flash areas. Fixes #52764 Signed-off-by: Sylvio Alves --- soc/riscv/espressif_esp32/esp32c3/default.ld | 4 ++-- soc/xtensa/espressif_esp32/esp32s2/default.ld | 3 ++- soc/xtensa/espressif_esp32/esp32s3/default.ld | 4 ++-- west.yml | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/soc/riscv/espressif_esp32/esp32c3/default.ld b/soc/riscv/espressif_esp32/esp32c3/default.ld index 0965036fb42..0884e3d7d3a 100644 --- a/soc/riscv/espressif_esp32/esp32c3/default.ld +++ b/soc/riscv/espressif_esp32/esp32c3/default.ld @@ -130,6 +130,7 @@ SECTIONS SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { + _rodata_reserved_start = ABSOLUTE(.); _rodata_start = ABSOLUTE(.); *(.rodata_desc .rodata_desc.*) @@ -186,7 +187,6 @@ SECTIONS *(.rodata_wlog) *(.rodata_wlog*) _thread_local_end = ABSOLUTE(.); - _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) @@ -203,6 +203,7 @@ SECTIONS * This is used to calculate the size of the _image_drom_size variable */ SECTION_PROLOGUE(_RODATA_SECTION_END,,) { + _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) @@ -402,7 +403,6 @@ SECTIONS { . = SIZEOF(_RODATA_SECTION_NAME); . = ALIGN(0x10000) + 0x20; - _rodata_reserved_start = .; } GROUP_LINK_IN(FLASH_CODE_REGION) .flash.text : ALIGN(IROM_SEG_ALIGN) diff --git a/soc/xtensa/espressif_esp32/esp32s2/default.ld b/soc/xtensa/espressif_esp32/esp32s2/default.ld index 4ef27a6384c..15f654d4b99 100644 --- a/soc/xtensa/espressif_esp32/esp32s2/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s2/default.ld @@ -135,6 +135,7 @@ SECTIONS */ SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(4)) { + _rodata_reserved_start = ABSOLUTE(.); __rodata_region_start = ABSOLUTE(.); . = ALIGN(4); @@ -182,7 +183,6 @@ SECTIONS *(.rodata_wlog) *(.rodata_wlog*) _thread_local_end = ABSOLUTE(.); - _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) @@ -198,6 +198,7 @@ SECTIONS * This is used to calculate the size of the _image_drom_size variable */ SECTION_PROLOGUE(_RODATA_SECTION_END,,ALIGN(0x10)) { + _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index 36944d69c60..90b6c89ada2 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -167,6 +167,7 @@ SECTIONS */ SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(0x10)) { + _rodata_reserved_start = ABSOLUTE(.); _rodata_start = ABSOLUTE(.); *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ @@ -218,7 +219,6 @@ SECTIONS *(.rodata_wlog) *(.rodata_wlog*) _thread_local_end = ABSOLUTE(.); - _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) @@ -235,6 +235,7 @@ SECTIONS * This is used to calculate the size of the _image_drom_size variable */ SECTION_PROLOGUE(_RODATA_SECTION_END,,ALIGN(0x10)) { + _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(16); _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) @@ -494,7 +495,6 @@ SECTIONS { . = SIZEOF(_RODATA_SECTION_NAME); . = ALIGN(IROM_SEG_ALIGN) + 0x20; - _rodata_reserved_start = .; } GROUP_LINK_IN(FLASH_CODE_REGION) .flash.text : ALIGN(IROM_SEG_ALIGN) diff --git a/west.yml b/west.yml index 2df3454d3a7..6bc05b1e8a7 100644 --- a/west.yml +++ b/west.yml @@ -155,7 +155,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 31fc5758f3507f8f0af00b1dea1a0df7af99bfc0 + revision: b3cb13f06586543ae1d156dc3e84b2fd3dc2f1fb path: modules/hal/espressif west-commands: west/west-commands.yml groups: From c179f17836b4a6460f6b643cf76f3e3891ec7f7e Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Thu, 19 Oct 2023 09:06:53 -0300 Subject: [PATCH 2553/4498] samples: boards: esp32: add memory-mapped sample code This sample shows how to use flash_mmap() call to enable custom flash area to be mapped into data region. Signed-off-by: Sylvio Alves --- .../esp32/flash_memory_mapped/CMakeLists.txt | 8 +++ .../esp32/flash_memory_mapped/README.rst | 66 +++++++++++++++++++ .../boards/esp32/flash_memory_mapped/prj.conf | 3 + .../esp32/flash_memory_mapped/sample.yaml | 10 +++ .../esp32/flash_memory_mapped/src/main.c | 60 +++++++++++++++++ 5 files changed, 147 insertions(+) create mode 100644 samples/boards/esp32/flash_memory_mapped/CMakeLists.txt create mode 100644 samples/boards/esp32/flash_memory_mapped/README.rst create mode 100644 samples/boards/esp32/flash_memory_mapped/prj.conf create mode 100644 samples/boards/esp32/flash_memory_mapped/sample.yaml create mode 100644 samples/boards/esp32/flash_memory_mapped/src/main.c diff --git a/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt b/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt new file mode 100644 index 00000000000..3cdbfb0e0b1 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(flash_memory_mapped) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/esp32/flash_memory_mapped/README.rst b/samples/boards/esp32/flash_memory_mapped/README.rst new file mode 100644 index 00000000000..17940504fc0 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/README.rst @@ -0,0 +1,66 @@ +.. _flash_memory_mapped: + +Espressif ESP32 Flash Memory-Mapped +################################### + +Overview +******** + +ESP32 features memory hardware which allows regions of flash memory to be mapped into instruction +and data address spaces. This mapping works only for read operations. It is not possible to modify +contents of flash memory by writing to a mapped memory region. + +Mapping happens in 64 KB pages. Memory mapping hardware can map flash into the data address space +and the instruction address space. See the technical reference manual for more details and +limitations about memory mapping hardware. For more information, check `_ESP32 Flash Memory-Mapping`. + +Supported SoCs +************** + +All ESP32 SoCs support flash memory-mapped feature. + +Building and Running +******************** + +Make sure you have your board connected over USB port. + +.. code-block:: console + + west build -b esp32s3_devkitm samples/boards/esp32/flash_memory_mapped + west flash + +Sample Output +============= + +To check the output of this sample, run ``west espressif monitor`` or any other serial +console program (e.g., minicom, putty, screen, etc). +This example uses ``west espressif monitor``, which automatically detects the serial +port at ``/dev/ttyUSB0``: + +.. code-block:: console + + $ west espressif monitor + +The sample code erases the scratch area defined in DTS file and writes a 32-bytes data buffer in it. +Next, it prints that region content using flash API read and also using memory-mapped pointer. +Both readings should return the same value. Important to notice that writing using memory-mapped pointer +is not allowed. + + +.. code-block:: console + + *** Booting Zephyr OS build v3.5.0-rc3-10-g3118724fa268 *** + [00:00:00.255,000] flash_memory_mapped: memory-mapped pointer address: 0x3c040000 + [00:00:01.122,000] flash_memory_mapped: flash read using memory-mapped pointer + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........ + [00:00:01.122,000] flash_memory_mapped: writing 32-bytes data using flash API + [00:00:01.122,000] flash_memory_mapped: flash read using flash API + 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |........ ........ + 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |........ ........ + [00:00:01.122,000] flash_memory_mapped: flash read using memory-mapped pointer + 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |........ ........ + 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |........ ........ + +.. _ESP32 Flash Memory-Mapping: + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_flash/index.html#memory-mapping-api diff --git a/samples/boards/esp32/flash_memory_mapped/prj.conf b/samples/boards/esp32/flash_memory_mapped/prj.conf new file mode 100644 index 00000000000..83a00f200cf --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/prj.conf @@ -0,0 +1,3 @@ +CONFIG_LOG=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y diff --git a/samples/boards/esp32/flash_memory_mapped/sample.yaml b/samples/boards/esp32/flash_memory_mapped/sample.yaml new file mode 100644 index 00000000000..c8601961d94 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/sample.yaml @@ -0,0 +1,10 @@ +sample: + description: Sample application to test memory-mapped flash region + name: flash_memory_mapped +tests: + sample.board.esp32.flash_memory_mapped: + platform_allow: + - esp32_devkitc_wroom + - esp32c3_devkitm + - esp32s3_devkitm + tags: esp32 diff --git a/samples/boards/esp32/flash_memory_mapped/src/main.c b/samples/boards/esp32/flash_memory_mapped/src/main.c new file mode 100644 index 00000000000..a29d6db08ec --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/src/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(flash_memory_mapped, CONFIG_LOG_DEFAULT_LEVEL); + +int main(void) +{ + uint8_t buffer[32]; + const struct device *flash_device; + const void *mem_ptr; + spi_flash_mmap_handle_t handle; + off_t address = FIXED_PARTITION_OFFSET(scratch_partition); + size_t size = FIXED_PARTITION_SIZE(scratch_partition); + + flash_device = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); + if (!device_is_ready(flash_device)) { + printk("%s: device not ready.\n", flash_device->name); + return 0; + } + + /* map selected region */ + spi_flash_mmap(address, size, SPI_FLASH_MMAP_DATA, &mem_ptr, &handle); + LOG_INF("memory-mapped pointer address: %p", mem_ptr); + + /* erase and read flash */ + flash_erase(flash_device, address, size); + LOG_HEXDUMP_INF(mem_ptr, 32, "flash read using memory-mapped pointer"); + + LOG_INF("writing 32-bytes data using flash API"); + memset(buffer, 0, sizeof(buffer)); + for (int k = 0; k < 32; k++) { + buffer[k] = k; + } + flash_write(flash_device, address, buffer, 32); + + /* read using flash API */ + memset(buffer, 0, sizeof(buffer)); + flash_read(flash_device, address, buffer, 32); + LOG_HEXDUMP_INF(buffer, 32, "flash read using flash API"); + + LOG_HEXDUMP_INF(mem_ptr, 32, "flash read using memory-mapped pointer"); + + /* unmap mapped region */ + spi_flash_munmap(handle); + + return 0; +} From 715952259782826e9be5b8ba5ce86209d2777ee4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 11:16:39 +0200 Subject: [PATCH 2554/4498] samples posix uname: Fix sample yaml filtering The sample was at the same time filtered for the whole posix architecture and had native_posix as its integration platform. This is selfcontradictory. In any case, this sample cannot run in native_posix but can run in native_sim. So let's fix the filtering. Signed-off-by: Alberto Escolar Piedras --- samples/posix/uname/sample.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/posix/uname/sample.yaml b/samples/posix/uname/sample.yaml index cfe990eb127..f4b8b82abac 100644 --- a/samples/posix/uname/sample.yaml +++ b/samples/posix/uname/sample.yaml @@ -3,9 +3,11 @@ sample: name: posix uname common: tags: posix - filter: not CONFIG_ARCH_POSIX - integration_platforms: + platform_exclude: + - native_posix - native_posix_64 + integration_platforms: + - native_sim - qemu_riscv64 harness: console harness_config: From f8c202ec1c910e6755ed7cf764142c82013893e7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 12:30:00 +0200 Subject: [PATCH 2555/4498] lib/posix clock: Add missing kconfig dependency POSIX clock cannot be used with the host libC when building with the POSIX architecture. Let's ensure it via kconfig. Signed-off-by: Alberto Escolar Piedras --- lib/posix/Kconfig.clock | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/posix/Kconfig.clock b/lib/posix/Kconfig.clock index d9767bb3910..95c88769d73 100644 --- a/lib/posix/Kconfig.clock +++ b/lib/posix/Kconfig.clock @@ -5,6 +5,7 @@ config POSIX_CLOCK bool "POSIX clock, timer, and sleep APIs" default y if POSIX_API + depends on !(ARCH_POSIX && EXTERNAL_LIBC) help This enables POSIX clock\_\*(), timer\_\*(), and \*sleep() functions. From c83c8df26a9e99fc21c2fa596b97db5fe2cb2bd6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 12:31:10 +0200 Subject: [PATCH 2556/4498] tests/lib/time: Fix for posix architecture * Select always PICOLIBC. This is anyhow the default for all but the posix architecture. And for the posix architecture we need it as POSIX_CLOCK does not work with the host C library. * Fix the testcase filtering. This sample works fine in native_sim (when not using the host libC), but does not work for native_posix(_64), as those can only be built with the host libC, and in that case, the POSIX_CLOCK provided functions will not be properly linked to. Signed-off-by: Alberto Escolar Piedras --- tests/lib/time/prj.conf | 1 + tests/lib/time/testcase.yaml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/lib/time/prj.conf b/tests/lib/time/prj.conf index 786d6bc705e..aac2e48e364 100644 --- a/tests/lib/time/prj.conf +++ b/tests/lib/time/prj.conf @@ -1,2 +1,3 @@ CONFIG_ZTEST=y CONFIG_POSIX_CLOCK=y +CONFIG_PICOLIBC=y diff --git a/tests/lib/time/testcase.yaml b/tests/lib/time/testcase.yaml index d70430fe987..f4e8d91ec1b 100644 --- a/tests/lib/time/testcase.yaml +++ b/tests/lib/time/testcase.yaml @@ -1,7 +1,9 @@ tests: libraries.libc.time: tags: libc - filter: not CONFIG_ARCH_POSIX or CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME timeout: 180 integration_platforms: - mps2_an385 + platform_exclude: + - native_posix + - native_posix_64 From 6b739a7684dc8f50bd3c7575050ad34f9594df34 Mon Sep 17 00:00:00 2001 From: ingram weeks Date: Mon, 23 Oct 2023 15:37:17 +0100 Subject: [PATCH 2557/4498] doc: README added to lora send sample README added to lora send sample Signed-off-by: ingram weeks --- samples/drivers/lora/send/README.rst | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 samples/drivers/lora/send/README.rst diff --git a/samples/drivers/lora/send/README.rst b/samples/drivers/lora/send/README.rst new file mode 100644 index 00000000000..ce73aa09585 --- /dev/null +++ b/samples/drivers/lora/send/README.rst @@ -0,0 +1,36 @@ +.. zephyr:code-sample:: lora-send + :name: LoRa send + :relevant-api: lora_api + + Transmit a preconfigured payload every second using the LoRa radio. + +Overview +******** + +This sample demonstrates how to use the LoRa radio driver to configure +the encoding settings and send data over the radio. + +Transmitted messages can be received by building and flashing the accompanying +LoRa receive sample on another board. + +Building and Running +******************** + +Build and flash the sample as follows, changing ``b_l072z_lrwan1`` for +your board, where your board has a ``lora0`` alias in the devicetree. + +.. zephyr-app-commands:: + :zephyr-app: zephyr/samples/drivers/lora/send + :host-os: unix + :board: b_l072z_lrwan1 + :goals: build flash + :compact: + +Sample Output +============= + +.. code-block:: console + + [00:00:00.531,000] lora_send: Data sent! + [00:00:01.828,000] lora_send: Data sent! + [00:00:03.125,000] lora_send: Data sent! From 7c25a7562b3bcf1cb3f939346d8efb86464286a5 Mon Sep 17 00:00:00 2001 From: Rick Tsao Date: Tue, 24 Oct 2023 11:16:34 +0800 Subject: [PATCH 2558/4498] riscv: pmp: Fix assertion for PMP misaligned start address and size Fix assertion to check whether the start address and size align with PMP granularity. Signed-off-by: Rick Tsao --- arch/riscv/core/pmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index 7a3cb02cf52..bfeb1c025cd 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -161,8 +161,8 @@ static bool set_pmp_entry(unsigned int *index_p, uint8_t perm, unsigned int index = *index_p; bool ok = true; - __ASSERT((start & 0x3) == 0, "misaligned start address"); - __ASSERT((size & 0x3) == 0, "misaligned size"); + __ASSERT((start & (CONFIG_PMP_GRANULARITY - 1)) == 0, "misaligned start address"); + __ASSERT((size & (CONFIG_PMP_GRANULARITY - 1)) == 0, "misaligned size"); if (index >= index_limit) { LOG_ERR("out of PMP slots"); From f2b3a5ea3a43bda6cab05a72e1c897580644cad5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 24 Oct 2023 12:13:32 +0100 Subject: [PATCH 2559/4498] samples: mgmt: mcumgr: smp_svr: Fix start if USB already init Fixes an issue whereby the application init will stall if USB init failed if it's already been setup, this is likely due to USB CDC being enabled in which case the failure can be ignored Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/src/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c b/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c index 2e4f206502e..8b0c0b44a88 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c +++ b/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c @@ -73,7 +73,9 @@ int main(void) if (IS_ENABLED(CONFIG_USB_DEVICE_STACK)) { rc = usb_enable(NULL); - if (rc) { + + /* Ignore EALREADY error as USB CDC is likely already initialised */ + if (rc != 0 && rc != -EALREADY) { LOG_ERR("Failed to enable USB"); return 0; } From efebb1841f7257801a14751bdbd9025f3a659e29 Mon Sep 17 00:00:00 2001 From: romain pelletant Date: Tue, 24 Oct 2023 14:05:57 +0200 Subject: [PATCH 2560/4498] modem_chat: fix hard fault on script stop Fix fault on modem_cellular disconnection/reconnection Issue #64291 Signed-off-by: romain pelletant --- subsys/modem/modem_chat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index fb934f7732c..0ab1175f980 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -60,6 +60,10 @@ static void modem_chat_log_received_command(struct modem_chat *chat) static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_script_result result) { + if (!chat || !chat->script) { + return; + } + /* Handle result */ if (result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) { LOG_DBG("%s: complete", chat->script->name); From 9f7244ee047772431ebab2be688aef31bc2926e5 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 24 Oct 2023 15:33:28 -0400 Subject: [PATCH 2561/4498] tests: obj_core: Increase stack sizes Increase the size of the thread stacks used by the obj_core tests by CONFIG_TEST_EXTRA_STACK_SIZE bytes. This is useful to prevent stack overflow/corruption when options such such as "--coverage --gcov-tool gcov" are applied to twister runs. Signed-off-by: Peter Mitsis --- tests/kernel/obj_core/obj_core/src/main.c | 5 +++-- tests/kernel/obj_core/obj_core_stats/src/main.c | 6 ++++-- tests/kernel/obj_core/obj_core_stats_api/src/main.c | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/kernel/obj_core/obj_core/src/main.c b/tests/kernel/obj_core/obj_core/src/main.c index 94f4e9fa648..9ec5eefb324 100644 --- a/tests/kernel/obj_core/obj_core/src/main.c +++ b/tests/kernel/obj_core/obj_core/src/main.c @@ -50,10 +50,11 @@ static K_SEM_DEFINE(sem1, 0, 1); static struct k_sem sem2; static void thread_entry(void *, void *, void *); -K_THREAD_DEFINE(thread1, 512, thread_entry, NULL, NULL, NULL, +K_THREAD_DEFINE(thread1, 512 + CONFIG_TEST_EXTRA_STACK_SIZE, + thread_entry, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, 0); static struct k_thread thread2; -K_THREAD_STACK_DEFINE(thread2_stack, 512); +K_THREAD_STACK_DEFINE(thread2_stack, 512 + CONFIG_TEST_EXTRA_STACK_SIZE); struct obj_core_find_data { struct k_obj_core *obj_core; /* Object core to search for */ diff --git a/tests/kernel/obj_core/obj_core_stats/src/main.c b/tests/kernel/obj_core/obj_core_stats/src/main.c index 24d649e363a..e46ecf510bb 100644 --- a/tests/kernel/obj_core/obj_core_stats/src/main.c +++ b/tests/kernel/obj_core/obj_core_stats/src/main.c @@ -13,7 +13,8 @@ K_MEM_SLAB_DEFINE(mem_slab, 32, 4, 16); /* Four 32 byte blocks */ #if !defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_SPARC) && !defined(CONFIG_MIPS) static void test_thread_entry(void *, void *, void *); -K_THREAD_DEFINE(test_thread, 1024, test_thread_entry, NULL, NULL, NULL, +K_THREAD_DEFINE(test_thread, 1024 + CONFIG_TEST_EXTRA_STACK_SIZE, + test_thread_entry, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, 0); K_SEM_DEFINE(wake_main_thread, 0, 1); @@ -21,7 +22,8 @@ K_SEM_DEFINE(wake_test_thread, 0, 1); #endif /* !CONFIG_ARCH_POSIX && !CONFIG_SPARC && !CONFIG_MIPS */ #if CONFIG_MP_MAX_NUM_CPUS > 1 -K_THREAD_STACK_ARRAY_DEFINE(busy_thread_stack, CONFIG_MP_MAX_NUM_CPUS - 1, 512); +K_THREAD_STACK_ARRAY_DEFINE(busy_thread_stack, CONFIG_MP_MAX_NUM_CPUS - 1, + 512 + CONFIG_TEST_EXTRA_STACK_SIZE); struct k_thread busy_thread[CONFIG_MP_MAX_NUM_CPUS - 1]; diff --git a/tests/kernel/obj_core/obj_core_stats_api/src/main.c b/tests/kernel/obj_core/obj_core_stats_api/src/main.c index 253ebdd7302..bfd9e881779 100644 --- a/tests/kernel/obj_core/obj_core_stats_api/src/main.c +++ b/tests/kernel/obj_core/obj_core_stats_api/src/main.c @@ -10,7 +10,8 @@ K_SEM_DEFINE(test_sem, 0, 1); static void test_thread_entry(void *, void *, void *); -K_THREAD_DEFINE(test_thread, 512, test_thread_entry, NULL, NULL, NULL, +K_THREAD_DEFINE(test_thread, 512 + CONFIG_TEST_EXTRA_STACK_SIZE, + test_thread_entry, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, 0); /* From 9a7671e521021e58a9b7cde5af0d67a5da4c1778 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 24 Oct 2023 22:47:47 +0200 Subject: [PATCH 2562/4498] ci: test using Python 3.11 as well Run CI tests against Python v3.11 as well. Signed-off-by: Henrik Brix Andersen --- .github/workflows/devicetree_checks.yml | 2 +- .github/workflows/pylib_tests.yml | 2 +- .github/workflows/scripts_tests.yml | 2 +- .github/workflows/twister_tests.yml | 2 +- .github/workflows/twister_tests_blackbox.yml | 2 +- .github/workflows/west_cmds.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index 465a8673149..ac94b532070 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -26,7 +26,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-22.04, macos-11, windows-2022] exclude: - os: macos-11 diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml index 06f61f32c24..79d83b64df5 100644 --- a/.github/workflows/pylib_tests.yml +++ b/.github/workflows/pylib_tests.yml @@ -25,7 +25,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-22.04] steps: - name: checkout diff --git a/.github/workflows/scripts_tests.yml b/.github/workflows/scripts_tests.yml index 132d8f357c8..9804c388f1c 100644 --- a/.github/workflows/scripts_tests.yml +++ b/.github/workflows/scripts_tests.yml @@ -25,7 +25,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-20.04] steps: - name: checkout diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index 05ea87dfd42..570d5efcb97 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -29,7 +29,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-22.04] steps: - name: checkout diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index abf8b324356..a35f571e80c 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-22.04] container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index 0d30209831d..c2502469541 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -27,7 +27,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11'] os: [ubuntu-22.04, macos-11, windows-2022] exclude: - os: macos-11 From 572491ab950034e3a12427d6a0b1ef23bcb1eca1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 09:03:07 +0200 Subject: [PATCH 2563/4498] Revert "modules: tinycrypt: Options only when module is available" This reverts commit 713ca15224c3223e99bf045b1ab50a6917bf60ea. This change broken several BT unit tests breaking CI in the main branch. Let's revert it. Fixes https://github.com/zephyrproject-rtos/zephyr/issues/64344 Signed-off-by: Alberto Escolar Piedras --- modules/Kconfig.tinycrypt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/Kconfig.tinycrypt b/modules/Kconfig.tinycrypt index 168e05ed799..7f279fbc59a 100644 --- a/modules/Kconfig.tinycrypt +++ b/modules/Kconfig.tinycrypt @@ -3,12 +3,8 @@ # Copyright (c) 2015 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -config ZEPHYR_TINYCRYPT_MODULE - bool - config TINYCRYPT bool "TinyCrypt Support" - depends on ZEPHYR_TINYCRYPT_MODULE help This option enables the TinyCrypt cryptography library. From dc431a7397a629c9fb7e3a27a803d11bf1103389 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 24 Oct 2023 13:30:50 +0200 Subject: [PATCH 2564/4498] boards: Fix nrf9160 NS flash partition layout Fix secure and non-secure images overlapping because of incompatible flash layout configurations. Align the board configurations to match the nRF9160 DK default partition layout. This enforces that the SPU alignment requirement is satisfied for the nrf9160 MCU. Signed-off-by: Joakim Andersson --- .../circuitdojo_feather_nrf9160_common.dtsi | 13 +++++-------- .../circuitdojo_feather_nrf9160_ns.yaml | 2 +- ...itdojo_feather_nrf9160_partition_conf.dtsi | 8 ++++---- .../nrf9160_innblue21_common.dtsi | 18 +++++++----------- .../nrf9160_innblue21_ns.yaml | 2 +- .../nrf9160_innblue21_partition_conf.dtsi | 8 ++++---- .../nrf9160_innblue22_common.dtsi | 19 ++++++++----------- .../nrf9160_innblue22_ns.yaml | 2 +- .../nrf9160_innblue22_partition_conf.dtsi | 8 ++++---- .../sparkfun_thing_plus_nrf9160_common.dtsi | 13 +++++-------- .../sparkfun_thing_plus_nrf9160_ns.yaml | 2 +- ...fun_thing_plus_nrf9160_partition_conf.dtsi | 8 ++++---- 12 files changed, 45 insertions(+), 58 deletions(-) diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi index 33fdba4d865..00ce5dcf6c0 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi @@ -187,22 +187,19 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; - storage_partition: partition@fa000 { + /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ + storage_partition: partition@f8000 { label = "storage"; - reg = <0x000fa000 0x00006000>; + reg = <0x000f8000 0x00008000>; }; }; }; diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml index c358a1d87fe..56905972e9f 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi index e8cb6fc586e..007975132d6 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi @@ -23,19 +23,19 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi index 0abfd4d6b9c..0ec5de5dfb1 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi @@ -168,27 +168,23 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0xc000>; + reg = <0x00000000 0x10000>; }; - slot0_partition: partition@c000 { + slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@3e000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@7e000 { + slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; - storage_partition: partition@fa000 { + storage_partition: partition@f8000 { label = "storage"; - reg = <0x000fa000 0x00006000>; + reg = <0x000f8000 0x00008000>; }; }; }; diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml index 096821d8364..4584ad0e6a4 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi index d3a30abdc76..2c64ba67a8a 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi @@ -22,19 +22,19 @@ */ &slot0_partition { - reg = <0x0000c000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x0003e000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x0007e000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi index 4582f975f5d..4738dd84a63 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi @@ -171,27 +171,24 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0xc000>; + reg = <0x00000000 0x10000>; }; - slot0_partition: partition@c000 { + slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@3e000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@7e000 { + slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; - storage_partition: partition@fa000 { + /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ + storage_partition: partition@f8000 { label = "storage"; - reg = <0x000fa000 0x00006000>; + reg = <0x000f8000 0x00008000>; }; }; }; diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml index 2ce0d6e3db2..0186c26a377 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi index 3588a6a7ce1..b14640a02ec 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi @@ -22,19 +22,19 @@ */ &slot0_partition { - reg = <0x0000c000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x0003e000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x0007e000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi index b85c00ea5b2..2658ee5eaa4 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi @@ -185,22 +185,19 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; - storage_partition: partition@fa000 { + /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ + storage_partition: partition@f8000 { label = "storage"; - reg = <0x000fa000 0x00006000>; + reg = <0x000f8000 0x00008000>; }; }; }; diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml index 438b2df7392..65f9eaad326 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi index 2422b2fdc52..64591fbf900 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi @@ -23,19 +23,19 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with From a2d1e979ef24ee69db667b24af6a2012fb6e673b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 16:27:47 +0200 Subject: [PATCH 2565/4498] tests posix timer: Fix timer check The timer check does not work properly for platforms which have a system tick timer with a period that does not properly divide the configured time interval. In those, depending on when the timer is started and stopped, one signal less may be received. This is for example the case for nrf5x platforms, where the system tick timer is driven by a 32.768KHz clock. => Correct the test, to accept receiving 1 signal too little during the wait. Signed-off-by: Alberto Escolar Piedras --- tests/posix/common/src/timer.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/posix/common/src/timer.c b/tests/posix/common/src/timer.c index 6a5d10dd863..1a1f7e718de 100644 --- a/tests/posix/common/src/timer.c +++ b/tests/posix/common/src/timer.c @@ -30,7 +30,7 @@ void test_timer(int sigev_notify) timer_t timerid; struct itimerspec value, ovalue; struct timespec ts, te; - int64_t nsecs_elapsed, secs_elapsed, total_secs_timer; + int64_t nsecs_elapsed, secs_elapsed; exp_count = 0; sig.sigev_notify = sigev_notify; @@ -84,15 +84,15 @@ void test_timer(int sigev_notify) secs_elapsed = (te.tv_sec - ts.tv_sec - 1); } - total_secs_timer = (value.it_value.tv_sec * NSEC_PER_SEC + - value.it_value.tv_nsec + (uint64_t) exp_count * - (value.it_interval.tv_sec * NSEC_PER_SEC + - value.it_interval.tv_nsec)) / NSEC_PER_SEC; - + uint64_t elapsed = secs_elapsed*NSEC_PER_SEC + nsecs_elapsed; + uint64_t first_sig = value.it_value.tv_sec * NSEC_PER_SEC + value.it_value.tv_nsec; + uint64_t sig_interval = value.it_interval.tv_sec * NSEC_PER_SEC + value.it_interval.tv_nsec; + int expected_signal_count = (elapsed - first_sig) / sig_interval + 1; /*TESTPOINT: Check if POSIX timer test passed*/ - zassert_equal(total_secs_timer, secs_elapsed, - "POSIX timer test has failed"); + zassert_within(exp_count, expected_signal_count, 1, + "POSIX timer test has failed %i != %i", + exp_count, expected_signal_count); } ZTEST(posix_apis, test_timer) From 32ea1566db004af72967e3a1edf53bc9f2c5b69f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 13:25:40 +0200 Subject: [PATCH 2566/4498] tests/posix/fs: Improve filtering around posix arch These tests cannot be run on the native_posix(_64) targets, so let's filter them explicitly. Before they were filtered due to the "filter", but using platform_exclude is faster. Also the tests that depend on newlib cannot be run in this architecture at all, so let's filter them by architecture too. Signed-off-by: Alberto Escolar Piedras --- tests/posix/fs/testcase.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/posix/fs/testcase.yaml b/tests/posix/fs/testcase.yaml index 9f3dec62cba..5274053dad4 100644 --- a/tests/posix/fs/testcase.yaml +++ b/tests/posix/fs/testcase.yaml @@ -2,6 +2,9 @@ common: filter: not (CONFIG_NATIVE_BUILD and CONFIG_EXTERNAL_LIBC) arch_exclude: - nios2 + platform_exclude: + - native_posix + - native_posix_64 tags: - posix - filesystem @@ -17,6 +20,8 @@ tests: - qemu_x86 portability.posix.fs.newlib: filter: TOOLCHAIN_HAS_NEWLIB == 1 + arch_exclude: + - posix extra_configs: - CONFIG_NEWLIB_LIBC=y integration_platforms: @@ -31,6 +36,8 @@ tests: portability.posix.fs.tls.newlib: filter: TOOLCHAIN_HAS_NEWLIB == 1 and CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE and CONFIG_TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + arch_exclude: + - posix extra_configs: - CONFIG_NEWLIB_LIBC=y - CONFIG_THREAD_LOCAL_STORAGE=y From 587c43a60266a924a4e858a52acc58fb395f4bd7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 23 Oct 2023 13:27:37 +0200 Subject: [PATCH 2567/4498] tests/posix/common: Fix filtering for POSIX arch All these tests where filtered for the whole POSIX architecture, but quite a few of them can be run in native_sim. So let's filter out native_posix(_64) in general, (allowing other native simulator based targes), and filter for thsi arch out explicitly the 2 tests which need NEWLIB as this arch does not provide it. Signed-off-by: Alberto Escolar Piedras --- tests/posix/common/testcase.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/posix/common/testcase.yaml b/tests/posix/common/testcase.yaml index 3d54e6c55d9..cb48095c67c 100644 --- a/tests/posix/common/testcase.yaml +++ b/tests/posix/common/testcase.yaml @@ -2,8 +2,10 @@ common: filter: not (CONFIG_NATIVE_BUILD and CONFIG_EXTERNAL_LIBC) # FIXME: qemu_leon3 is excluded because of the alignment-related failure # reported in the GitHub issue zephyrproject-rtos/zephyr#48992. - arch_exclude: posix - platform_exclude: qemu_leon3 + platform_exclude: + - qemu_leon3 + - native_posix + - native_posix_64 tags: posix min_ram: 64 timeout: 240 @@ -24,6 +26,8 @@ tests: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_NEWLIB_LIBC=y + arch_exclude: + - posix integration_platforms: - qemu_x86 portability.posix.common.armclang_std_libc: @@ -51,6 +55,8 @@ tests: - lpcxpresso55s06 filter: TOOLCHAIN_HAS_NEWLIB == 1 and CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE and CONFIG_TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + arch_exclude: + - posix integration_platforms: - qemu_x86 extra_configs: From c51bb9c13b3c698a8f49d0b9c53f2be4884af8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Fri, 20 Oct 2023 08:58:06 +0200 Subject: [PATCH 2568/4498] Bluetooth: Mesh: Update spec ref 1.0.1->1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates Bluetooth mesh specification references: - Change "Profile" to "Protocol" since the main specification has changed its name. - Update/align formating of specification references. This will make it easier to find spec references in the future. - Change some section references to point to the correct section of the newest version of the specification (v1.1). Signed-off-by: Anders Storrø --- doc/connectivity/bluetooth/api/mesh.rst | 2 +- .../bluetooth/api/mesh/provisioning.rst | 2 +- include/zephyr/bluetooth/mesh/dfu_metadata.h | 2 +- include/zephyr/bluetooth/mesh/main.h | 2 +- subsys/bluetooth/mesh/access.c | 6 +++--- subsys/bluetooth/mesh/app_keys.c | 4 ++-- subsys/bluetooth/mesh/blob.h | 2 +- subsys/bluetooth/mesh/blob_cli.c | 4 ++-- subsys/bluetooth/mesh/cfg_srv.c | 2 +- subsys/bluetooth/mesh/net.c | 9 ++++----- subsys/bluetooth/mesh/pb_adv.c | 2 +- subsys/bluetooth/mesh/prov.c | 13 ++++--------- subsys/bluetooth/mesh/prov_device.c | 5 ++--- subsys/bluetooth/mesh/provisioner.c | 2 +- subsys/bluetooth/mesh/proxy_msg.c | 2 +- subsys/bluetooth/mesh/proxy_srv.c | 12 ++++++------ subsys/bluetooth/mesh/rpr_srv.c | 4 ++-- subsys/bluetooth/mesh/subnet.c | 10 +++++----- subsys/bluetooth/mesh/transport.c | 14 ++++++-------- subsys/bluetooth/mesh/transport_legacy.c | 12 +++++------- 20 files changed, 50 insertions(+), 61 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 6e2fca1b111..457aa5b6895 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -7,7 +7,7 @@ The Bluetooth mesh profile adds secure wireless multi-hop communication for Bluetooth Low Energy. This module implements the `Bluetooth Mesh Profile Specification v1.0.1 `_. -Implementation of the `Bluetooth Mesh Protocol Specification v1.1 `_ +Implementation of the `Bluetooth Mesh Protocol Specification v1.1 `_ is in experimental state. Read more about Bluetooth mesh on the diff --git a/doc/connectivity/bluetooth/api/mesh/provisioning.rst b/doc/connectivity/bluetooth/api/mesh/provisioning.rst index 0985234b86c..36fa38927a3 100644 --- a/doc/connectivity/bluetooth/api/mesh/provisioning.rst +++ b/doc/connectivity/bluetooth/api/mesh/provisioning.rst @@ -180,7 +180,7 @@ a set of vulnerabilities in the Bluetooth mesh provisioning protocol that showca how the low entropy provided by the Blink, Vibrate, Push, Twist and Input/Output numeric OOB methods could be exploited in impersonation and MITM attacks. In response, the Bluetooth SIG has reclassified these OOB methods as -insecure in the Mesh Profile specification `erratum 16350 `_, +insecure in the Bluetooth Mesh Profile Specification v1.0.1 `erratum 16350 `_, as AuthValue may be brute forced in real time. To ensure secure provisioning, applications should use a static OOB value and OOB public key transfer. diff --git a/include/zephyr/bluetooth/mesh/dfu_metadata.h b/include/zephyr/bluetooth/mesh/dfu_metadata.h index 8aea661ede7..bec65897ac7 100644 --- a/include/zephyr/bluetooth/mesh/dfu_metadata.h +++ b/include/zephyr/bluetooth/mesh/dfu_metadata.h @@ -87,7 +87,7 @@ int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata, /** @brief Compute hash of the Composition Data state. * - * The format of the Composition Data is defined in MshPRFv1.0.1, section 4.2.1.1. + * The format of the Composition Data is defined in MshPRTv1.1: 4.2.2.1. * * @param buf Pointer to buffer holding Composition Data. * @param key 128-bit key to be used in the hash computation. diff --git a/include/zephyr/bluetooth/mesh/main.h b/include/zephyr/bluetooth/mesh/main.h index ab274729cf8..a4e98b97f8c 100644 --- a/include/zephyr/bluetooth/mesh/main.h +++ b/include/zephyr/bluetooth/mesh/main.h @@ -1,5 +1,5 @@ /** @file - * @brief Bluetooth mesh Profile APIs. + * @brief Bluetooth mesh Protocol APIs. */ /* diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 583652d4fbb..4f1941a9e66 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -377,7 +377,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, if (net_buf_simple_tailroom(buf) < ((elem_size - *offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { - /* Mesh Profile 1.1 Section 4.4.1.2.2: + /* MshPRTv1.1: 4.4.1.2.2: * If the complete list of models does not fit in the Data field, * the element shall not be reported. */ @@ -611,7 +611,7 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { - /* Mesh Profile 1.1 Section 4.4.1.2.2: + /* MshPRTv1.1: 4.4.1.2.2: * If the complete list of models does not fit in the Data field, * the element shall not be reported. */ @@ -669,7 +669,7 @@ static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offse if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { - /* Mesh Profile 1.1 Section 4.4.1.2.2: + /* MshPRTv1.1: 4.4.1.2.2: * If the complete list of models does not fit in the Data field, * the element shall not be reported. */ diff --git a/subsys/bluetooth/mesh/app_keys.c b/subsys/bluetooth/mesh/app_keys.c index 64677a3386e..a47d31447c5 100644 --- a/subsys/bluetooth/mesh/app_keys.c +++ b/subsys/bluetooth/mesh/app_keys.c @@ -556,7 +556,7 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid, } } - /** Bluetooth Mesh Specification v1.0.1, section 3.4.3: + /** MshPRTv1.1: 3.4.3: * The Device key is only valid for unicast addresses. */ if (BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) { @@ -569,7 +569,7 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid, if (atomic_test_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) { err = cb(rx, &bt_mesh.dev_key_cand, cb_data); if (!err) { - /* Bluetooth Mesh Specification v1.1.0, section 3.6.4.2: + /* MshPRTv1.1: 3.6.4.2: * If a message is successfully decrypted using the device * key candidate, the device key candidate should * permanently replace the original devkey. diff --git a/subsys/bluetooth/mesh/blob.h b/subsys/bluetooth/mesh/blob.h index d7552934ecb..2898dcd030c 100644 --- a/subsys/bluetooth/mesh/blob.h +++ b/subsys/bluetooth/mesh/blob.h @@ -33,7 +33,7 @@ * * The macros expand to a series of ternary expressions, effectively * searching through power of twos until a match is found. - * According to the specification, the block size cannot be larger than 2^20, + * According to MshMBTv1.0, the block size cannot be larger than 2^20, * so we'll stop the search at 20. */ #define _BLOB_LOG_2_CEIL(l, x) ((x) <= (1U << l)) ? l : diff --git a/subsys/bluetooth/mesh/blob_cli.c b/subsys/bluetooth/mesh/blob_cli.c index e2b0fc68a70..0effbf61be7 100644 --- a/subsys/bluetooth/mesh/blob_cli.c +++ b/subsys/bluetooth/mesh/blob_cli.c @@ -1375,8 +1375,8 @@ static int handle_block_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx LOG_DBG("Missing: %s", bt_hex(status.block.missing, len)); break; case BT_MESH_BLOB_CHUNKS_MISSING_ENCODED: - /** An empty Missing Chunks field entails that there are no - * missing chunks for this block (Spec 5.3.8) + /** MshMBTv1.0: 5.3.8: An empty Missing Chunks field entails that there are no + * missing chunks for this block. */ if (!buf->len) { status.missing = BT_MESH_BLOB_CHUNKS_MISSING_NONE; diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index f65d2cba3c7..c45b627d194 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -2305,7 +2305,7 @@ static int heartbeat_pub_set(struct bt_mesh_model *model, pub.dst = sys_le16_to_cpu(param->dst); if (param->count_log == 0x11) { - /* Special case defined in Mesh Profile Errata 11737 */ + /* Special case defined in MshPRFv1.1 Errata 11737 */ pub.count = 0xfffe; } else { pub.count = bt_mesh_hb_pwr2(param->count_log); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 61efaeb2c81..6a9f29b4064 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -95,9 +95,8 @@ struct bt_mesh_net bt_mesh = { #endif }; -/* Mesh Profile Specification 3.10.6 - * The node shall not execute more than one IV Index Recovery within a period of - * 192 hours. +/* MshPRTv1.1: 3.11.5: + * "A node shall not start an IV Update procedure more often than once every 192 hours." * * Mark that the IV Index Recovery has been done to prevent two recoveries to be * done before a normal IV Index update has been completed within 96h+96h. @@ -293,7 +292,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) return false; } - /* The Mesh profile specification allows to initiate an + /* MshPRTv1.1 allows to initiate an * IV Index Recovery procedure if previous IV update has * been missed. This allows the node to remain * functional. @@ -560,7 +559,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, } } - /* Mesh spec 3.4.5.2: "The output filter of the interface connected to + /* MshPRTv1.1: 3.4.5.2: "The output filter of the interface connected to * advertising or GATT bearers shall drop all messages with TTL value * set to 1." If a TTL=1 packet wasn't for a local interface, it is * invalid. diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index cb5f53f32b7..e273739ed72 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -929,7 +929,7 @@ static void prov_link_close(enum prov_bearer_link_status status) } /* - * According to mesh profile spec (5.3.1.4.3), the close message should + * According to MshPRTv1.1: 5.3.1.4.3, the close message should * be restransmitted at least three times. Retransmit the LINK_CLOSE * message until CLOSING_TIMEOUT has elapsed. */ diff --git a/subsys/bluetooth/mesh/prov.c b/subsys/bluetooth/mesh/prov.c index fbbcde58185..ba177bf1981 100644 --- a/subsys/bluetooth/mesh/prov.c +++ b/subsys/bluetooth/mesh/prov.c @@ -153,15 +153,10 @@ static uint32_t get_auth_number(bt_mesh_output_action_t output, bt_rand(&num, sizeof(num)); - if (output == BT_MESH_BLINK || - output == BT_MESH_BEEP || - output == BT_MESH_VIBRATE || - input == BT_MESH_PUSH || - input == BT_MESH_TWIST) { - /* According to the Bluetooth Mesh Profile - * Specification Section 5.4.2.4, blink, beep - * vibrate, push and twist should be a random integer - * between 0 and 10^size, *exclusive*: + if (output == BT_MESH_BLINK || output == BT_MESH_BEEP || output == BT_MESH_VIBRATE || + input == BT_MESH_PUSH || input == BT_MESH_TWIST) { + /* According to MshPRTv1.1: 5.4.2.4, blink, beep vibrate, push and twist should be + * a random integer between 0 and 10^size, *exclusive*: */ num = (num % (divider[size - 1] - 1)) + 1; } else { diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 6e56519eefb..af890396ac7 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -57,9 +57,8 @@ static void prov_send_fail_msg(uint8_t err) static void prov_fail(uint8_t reason) { - /* According to Bluetooth Mesh Specification v1.0.1, Section 5.4.4, the - * provisioner just closes the link when something fails, while the - * provisionee sends the fail message, and waits for the provisioner to + /* According to MshPRTv1.1: 5.4.4, the provisioner just closes the link when something + * fails, while the provisionee sends the fail message, and waits for the provisioner to * close the link. */ prov_send_fail_msg(reason); diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index a65bd25ab53..aba2449892f 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -72,7 +72,7 @@ static void prov_link_close(enum prov_bearer_link_status status) static void prov_fail(uint8_t reason) { - /* According to Bluetooth Mesh Specification v1.0.1, Section 5.4.4, the + /* According to MshPRTv1.1: 5.4.4, the * provisioner just closes the link when something fails, while the * provisionee sends the fail message, and waits for the provisioner to * close the link. diff --git a/subsys/bluetooth/mesh/proxy_msg.c b/subsys/bluetooth/mesh/proxy_msg.c index b9dfb8f7e16..025909e0503 100644 --- a/subsys/bluetooth/mesh/proxy_msg.c +++ b/subsys/bluetooth/mesh/proxy_msg.c @@ -38,7 +38,7 @@ LOG_MODULE_REGISTER(bt_mesh_proxy); #define PDU_SAR(data) (data[0] >> 6) -/* Mesh Profile 1.0 Section 6.6: +/* MshPRTv1.1: 6.3.2.2: * "The timeout for the SAR transfer is 20 seconds. When the timeout * expires, the Proxy Server shall disconnect." */ diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 4e260f8e937..2943afdca93 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -518,7 +518,7 @@ static int enc_id_adv(struct bt_mesh_subnet *sub, uint8_t type, return err; } - /* Section 7.2.2.2.4: The AdvA field shall be regenerated whenever the Random field is + /* MshPRTv1.1: 7.2.2.2.4: The AdvA field shall be regenerated whenever the Random field is * regenerated. */ err = randomize_bt_addr(); @@ -785,14 +785,14 @@ static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) } } - /* Mesh Profile Specification v1.0.1, section 7.2.2.2.1 - * A node that does not support the Proxy feature or - * has the GATT Proxy state disabled shall not advertise with Network ID. + /* MshPRTv1.1: section 7.2.2.2.1: + * "A node that does not support the Proxy feature or + * has the GATT Proxy state disabled shall not advertise with Network ID." */ if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { if (IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS) && (bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED)) { - /* Bluetooth mesh specification v1.1, section 7.2.2.2.4: The Random + /* MshPRTv1.1: 7.2.2.2.4: The Random * field should be updated every 10 minutes. Limit advertising to * 10 minutes to ensure regeneration of a new random value at least * that often. @@ -1078,7 +1078,7 @@ static void gatt_connected(struct bt_conn *conn, uint8_t err) proxy_msg_recv); #if defined(CONFIG_BT_MESH_PRIV_BEACONS) - /* Binding from section 7.2.2.2.6 of MshPRTv1.1. */ + /* Binding from MshPRTv1.1: 7.2.2.2.6. */ enum bt_mesh_subnets_node_id_state cur_node_id = bt_mesh_subnets_node_id_state_get(); if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED || diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index df63b1166c5..fb2b57fad2e 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -423,7 +423,7 @@ static void subnet_evt_handler(struct bt_mesh_subnet *subnet, link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER, PROV_BEARER_LINK_STATUS_FAIL); /* Skip the link closing stage, as specified in the Bluetooth - * Mesh Profile specification, section 4.4.5.4. + * MshPRTv1.1: 4.4.5.4. */ srv.link.state = BT_MESH_RPR_LINK_IDLE; } else if (atomic_test_bit(srv.flags, SCANNING) && @@ -634,7 +634,7 @@ static int handle_extended_scan_start(struct bt_mesh_model *mod, struct bt_mesh_ uint8_t timeout; int i; - /* According to the Bluetooth Mesh specification, section 4.4.5.5.1.7, scan reports shall be + /* According to MshPRTv1.1: 4.4.5.5.1.7, scan reports shall be * sent as segmented messages. */ ctx->send_rel = true; diff --git a/subsys/bluetooth/mesh/subnet.c b/subsys/bluetooth/mesh/subnet.c index e697d985c24..ef90ff8f725 100644 --- a/subsys/bluetooth/mesh/subnet.c +++ b/subsys/bluetooth/mesh/subnet.c @@ -252,7 +252,7 @@ void bt_mesh_kr_update(struct bt_mesh_subnet *sub, bool kr_flag, bool new_key) } if (sub->kr_phase == BT_MESH_KR_PHASE_1) { - /* Bluetooth Mesh Profile Specification Section 3.10.4.1: + /* MshPRTv1.1: 3.11.4.1: * Can skip phase 2 if we get KR=0 on new key. */ key_refresh(sub, (kr_flag ? BT_MESH_KR_PHASE_2 : @@ -511,7 +511,7 @@ void bt_mesh_friend_cred_destroy(struct bt_mesh_net_cred *cred) uint8_t bt_mesh_subnet_kr_phase_set(uint16_t net_idx, uint8_t *phase) { - /* Table in Bluetooth Mesh Profile Specification Section 4.2.14: */ + /* Table in MshPRTv1.1: 4.2.15: */ const uint8_t valid_transitions[] = { BIT(BT_MESH_KR_PHASE_3), /* Normal phase: KR is started by key update */ BIT(BT_MESH_KR_PHASE_2) | BIT(BT_MESH_KR_PHASE_3), /* Phase 1 */ @@ -582,7 +582,7 @@ uint8_t bt_mesh_subnet_node_id_set(uint16_t net_idx, } #if defined(CONFIG_BT_MESH_PRIV_BEACONS) - /* Implements binding from section 4.2.46.1 of MshPRTv1.1. When enabling non-private node + /* Implements binding from MshPRTv1.1: 4.2.46.1. When enabling non-private node * identity state, disable its private counterpart. */ for (int i = 0; i < ARRAY_SIZE(subnets); i++) { @@ -645,8 +645,8 @@ uint8_t bt_mesh_subnet_priv_node_id_set(uint16_t net_idx, } #if defined(CONFIG_BT_MESH_PRIV_BEACONS) - /* Reverse binding from section 4.2.46.1 doesn't allow to set private state if non-private - * state is enabled. + /* Reverse binding from MshPRTv1.1: 4.2.46.1 doesn't + * allow to set private state if non-private state is enabled. */ for (int i = 0; i < ARRAY_SIZE(subnets); i++) { if (subnets[i].net_idx != BT_MESH_KEY_UNUSED && diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index f4c49aa6856..94c1f698e91 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -934,12 +934,10 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, uint32_t delta_ms = (uint32_t)(k_uptime_get() - tx->adv_start_timestamp); - /* According to the Bluetooth Mesh Profile specification, - * section 3.5.3.3, we should reset the retransmit timer and - * retransmit immediately when receiving a valid ack message - * while Retransmisison timer is running. However, transport should - * still keep segment transmission interval time between - * transmission of each segment. + /* According to MshPRTv1.1: 3.5.3.3.2, we should reset the retransmit timer + * and retransmit immediately when receiving a valid ack message while + * Retransmisison timer is running. However, transport should still keep + * segment transmission interval time between transmission of each segment. */ if (delta_ms < BT_MESH_SAR_TX_SEG_INT_MS) { timeout = K_MSEC(BT_MESH_SAR_TX_SEG_INT_MS - delta_ms); @@ -1370,7 +1368,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, return -EBADMSG; } - /* According to Mesh 1.0 specification: + /* According to MshPRTv1.1: * "The SeqAuth is composed of the IV Index and the sequence number * (SEQ) of the first segment" * @@ -1466,7 +1464,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, /* Keep track of the received SeqAuth values received from this address * and discard segmented messages that are not newer, as described in - * the Bluetooth Mesh specification section 3.5.3.4. + * MshPRTv1.1: 3.5.3.4. * * The logic on the first segmented receive is a bit special, since the * initial value of rpl->seg is 0, which would normally fail the diff --git a/subsys/bluetooth/mesh/transport_legacy.c b/subsys/bluetooth/mesh/transport_legacy.c index 23e103b4370..da0c1830f73 100644 --- a/subsys/bluetooth/mesh/transport_legacy.c +++ b/subsys/bluetooth/mesh/transport_legacy.c @@ -870,11 +870,9 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, } if (tx->nack_count) { - /* According to the Bluetooth Mesh Profile specification, - * section 3.5.3.3, we should reset the retransmit timer and - * retransmit immediately when receiving a valid ack message. - * Don't reset the retransmit timer if we didn't finish sending - * segments. + /* According to MshPRFv1.0.1: 3.5.3.3, we should reset the retransmit timer and + * retransmit immediately when receiving a valid ack message. Don't reset the + * retransmit timer if we didn't finish sending segments. */ if (tx->seg_o == 0) { k_work_reschedule(&tx->retransmit, K_NO_WAIT); @@ -1314,7 +1312,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, return -EINVAL; } - /* According to Mesh 1.0 specification: + /* According to MshPRFv1.0.1: * "The SeqAuth is composed of the IV Index and the sequence number * (SEQ) of the first segment" * @@ -1401,7 +1399,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, /* Keep track of the received SeqAuth values received from this address * and discard segmented messages that are not newer, as described in - * the Bluetooth Mesh specification section 3.5.3.4. + * MshPRFv1.0.1: 3.5.3.4. * * The logic on the first segmented receive is a bit special, since the * initial value of rpl->seg is 0, which would normally fail the From 46d9c979912e62a34209a98541408a406aee8803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 25 Oct 2023 11:08:21 +0200 Subject: [PATCH 2569/4498] Bluetooth: Mesh: HB pub status for unassigned addr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue where Heartbeat Publication Status message sends garbage data when destination field is set to the unassigned address. MshPRTv1.1, section 4.4.1.2.15: "When the Destination field is set to the unassigned address, the values of the CountLog, PeriodLog, TTL, and Features fields shall be set to 0x00 and NetKeyIndex field shall be set to 0x0000." Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg_srv.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index c45b627d194..d9df5550720 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -2267,11 +2267,15 @@ static int hb_pub_send_status(struct bt_mesh_model *model, net_buf_simple_add_u8(&msg, status); net_buf_simple_add_le16(&msg, pub->dst); - net_buf_simple_add_u8(&msg, hb_pub_count_log(pub->count)); - net_buf_simple_add_u8(&msg, bt_mesh_hb_log(pub->period)); - net_buf_simple_add_u8(&msg, pub->ttl); - net_buf_simple_add_le16(&msg, pub->feat); - net_buf_simple_add_le16(&msg, pub->net_idx); + if (pub->dst == BT_MESH_ADDR_UNASSIGNED) { + (void)memset(net_buf_simple_add(&msg, 7), 0, 7); + } else { + net_buf_simple_add_u8(&msg, hb_pub_count_log(pub->count)); + net_buf_simple_add_u8(&msg, bt_mesh_hb_log(pub->period)); + net_buf_simple_add_u8(&msg, pub->ttl); + net_buf_simple_add_le16(&msg, pub->feat); + net_buf_simple_add_le16(&msg, pub->net_idx); + } if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { LOG_ERR("Unable to send Heartbeat Publication Status"); From 05774c5d76ef92a14f892d3e35a2ce7afcaf2493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 25 Oct 2023 11:08:21 +0200 Subject: [PATCH 2570/4498] Bluetooth: Mesh: Fix unpacking of hb_pub status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes incorrect unpacking of Heartbeat Publication status messages on the Configuration client. Reference to packing format: MshPRTv1.1 section 4.3.2.63 Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg_cli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index c9f4f98f39d..7ee3a590cd0 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -950,8 +950,8 @@ static int hb_pub_status(struct bt_mesh_model *model, pub.count = net_buf_simple_pull_u8(buf); pub.period = net_buf_simple_pull_u8(buf); pub.ttl = net_buf_simple_pull_u8(buf); - pub.feat = net_buf_simple_pull_u8(buf); - pub.net_idx = net_buf_simple_pull_u8(buf); + pub.feat = net_buf_simple_pull_le16(buf); + pub.net_idx = net_buf_simple_pull_le16(buf) & 0xfff; if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_PUB_STATUS, ctx->addr, (void **)¶m)) { From d4037ce6a10c14dd3d27e10e825b8a82f98150fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 25 Oct 2023 11:08:21 +0200 Subject: [PATCH 2571/4498] Bluetooth: Mesh: Correct pack of net idx hb_status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures correct packing of net idx in Heartbeat Publication Status messages on the Configuration Server. Reference to net idx packing format: MshPRTv1.1 section 4.3.1.1 Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index d9df5550720..1684748ba83 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -2274,7 +2274,7 @@ static int hb_pub_send_status(struct bt_mesh_model *model, net_buf_simple_add_u8(&msg, bt_mesh_hb_log(pub->period)); net_buf_simple_add_u8(&msg, pub->ttl); net_buf_simple_add_le16(&msg, pub->feat); - net_buf_simple_add_le16(&msg, pub->net_idx); + net_buf_simple_add_le16(&msg, pub->net_idx & 0xfff); } if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { From 0ae68a3857c9705774599d24f46c06f3e679aa2c Mon Sep 17 00:00:00 2001 From: Dmitry Lukyantsev Date: Thu, 17 Aug 2023 17:01:33 -0700 Subject: [PATCH 2572/4498] soc: nxp_adsp: Refactor imx8/imx8m Kconfig In preparation for RT500 ADSP enablement, consolidate common Xtensa configuration parameters in top level Kconfig.defconfig. Signed-off-by: Dmitry Lukyantsev --- soc/xtensa/nxp_adsp/Kconfig.defconfig | 24 +++++++++++++++++-- .../nxp_adsp/imx8/Kconfig.defconfig.series | 20 ---------------- .../nxp_adsp/imx8m/Kconfig.defconfig.series | 20 ---------------- 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/soc/xtensa/nxp_adsp/Kconfig.defconfig b/soc/xtensa/nxp_adsp/Kconfig.defconfig index 4c8e3f9c83c..0dc331f8834 100644 --- a/soc/xtensa/nxp_adsp/Kconfig.defconfig +++ b/soc/xtensa/nxp_adsp/Kconfig.defconfig @@ -1,4 +1,4 @@ -# NXP i.MX8 SoC family default configuration options +# NXP i.MX8/RT SoC family default configuration options # # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 @@ -6,4 +6,24 @@ source "soc/xtensa/nxp_adsp/*/Kconfig.defconfig.series" config CACHE_MANAGEMENT - def_bool y + default y + +config SMP + default n + +config XTENSA_TIMER + default y + +config KERNEL_ENTRY + default "__start" + +config MULTI_LEVEL_INTERRUPTS + default n + +config 2ND_LEVEL_INTERRUPTS + default n + +# To prevent test uses TEST_LOGGING_MINIMAL +config TEST_LOGGING_DEFAULTS + default n + depends on TEST diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series index 7431522e867..1976bc11912 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series @@ -15,36 +15,16 @@ config SOC string default "nxp_imx8" -config SMP - default n - -config XTENSA_TIMER - default y - config SYS_CLOCK_HW_CYCLES_PER_SEC default 666000000 if XTENSA_TIMER config SYS_CLOCK_TICKS_PER_SEC default 50000 -config KERNEL_ENTRY - default "__start" - -config MULTI_LEVEL_INTERRUPTS - default n - -config 2ND_LEVEL_INTERRUPTS - default n - config DYNAMIC_INTERRUPTS default y config LOG default y -# To prevent test uses TEST_LOGGING_MINIMAL -config TEST_LOGGING_DEFAULTS - default n - depends on TEST - endif # SOC_SERIES_NXP_IMX8 diff --git a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series index 03967cb74e4..d0fc446b4b0 100644 --- a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series @@ -17,38 +17,18 @@ config SOC string default "mimx8ml8" -config SMP - default n - -config XTENSA_TIMER - default y - config SYS_CLOCK_HW_CYCLES_PER_SEC default 800000000 if XTENSA_TIMER config SYS_CLOCK_TICKS_PER_SEC default 50000 -config KERNEL_ENTRY - default "__start" - -config MULTI_LEVEL_INTERRUPTS - default n - -config 2ND_LEVEL_INTERRUPTS - default n - config DYNAMIC_INTERRUPTS default y config LOG default y -# To prevent test uses TEST_LOGGING_MINIMAL -config TEST_LOGGING_DEFAULTS - default n - depends on TEST - # endif # SOC_MIMX8M_ADSP endif # SOC_SERIES_NXP_IMX8M From 357d6cec45ff039646a3db2a19eba063c25a1a71 Mon Sep 17 00:00:00 2001 From: Dmitry Lukyantsev Date: Thu, 10 Aug 2023 12:02:35 -0700 Subject: [PATCH 2573/4498] boards: Add support for the NXP MIMXRT595 DSP core Add board and soc files for the NXP MIMXRT595 DSP core. Signed-off-by: Dmitry Lukyantsev --- boards/arm/mimxrt595_evk/doc/index.rst | 17 + boards/xtensa/nxp_adsp_rt595/Kconfig | 41 ++ boards/xtensa/nxp_adsp_rt595/Kconfig.board | 6 + .../xtensa/nxp_adsp_rt595/Kconfig.defconfig | 9 + .../xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts | 51 ++ .../xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml | 9 + .../nxp_adsp_rt595/nxp_adsp_rt595_defconfig | 7 + soc/xtensa/nxp_adsp/CMakeLists.txt | 6 +- .../nxp_adsp/rt5xx/Kconfig.defconfig.series | 46 ++ soc/xtensa/nxp_adsp/rt5xx/Kconfig.series | 12 + soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc | 10 + .../nxp_adsp/rt5xx/include/_soc_inthandlers.h | 188 +++++++ .../nxp_adsp/rt5xx/include/soc/memory.h | 46 ++ soc/xtensa/nxp_adsp/rt5xx/linker.ld | 464 ++++++++++++++++++ 14 files changed, 911 insertions(+), 1 deletion(-) create mode 100644 boards/xtensa/nxp_adsp_rt595/Kconfig create mode 100644 boards/xtensa/nxp_adsp_rt595/Kconfig.board create mode 100644 boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig create mode 100644 boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts create mode 100644 boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml create mode 100644 boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig create mode 100644 soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series create mode 100644 soc/xtensa/nxp_adsp/rt5xx/Kconfig.series create mode 100644 soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc create mode 100644 soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h create mode 100644 soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h create mode 100644 soc/xtensa/nxp_adsp/rt5xx/linker.ld diff --git a/boards/arm/mimxrt595_evk/doc/index.rst b/boards/arm/mimxrt595_evk/doc/index.rst index 61ed427858a..a82735ba278 100644 --- a/boards/arm/mimxrt595_evk/doc/index.rst +++ b/boards/arm/mimxrt595_evk/doc/index.rst @@ -174,6 +174,20 @@ Serial Port The MIMXRT595 SoC has 13 FLEXCOMM interfaces for serial communication. One is configured as USART for the console and the remaining are not used. +Fusion F1 DSP Core +================== + +You can build a Zephyr application for the RT500 DSP core using nxp_adsp_rt595 +board. Xtensa toolchain supporting RT500 DSP core is included in Zephyr SDK. +To build the hello_world sample for the RT500 DSP core: + +.. code-block:: shell + + $ west build -b nxp_adsp_rt595 samples/hello_world + +For detailed instructions on how to debug DSP firmware, please refer to +this document: `Getting Started with Xplorer for EVK-MIMXRT595`_ + Programming and Debugging ************************* @@ -313,3 +327,6 @@ steps: .. _i.MX RT595 Reference Manual: https://www.nxp.com/webapp/Download?colCode=IMXRT500RM + +.. _Getting Started with Xplorer for EVK-MIMXRT595: + https://www.nxp.com/docs/en/supporting-information/GSXEVKMIMXRT595.pdf diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig b/boards/xtensa/nxp_adsp_rt595/Kconfig new file mode 100644 index 00000000000..3c787188a9b --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig @@ -0,0 +1,41 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +DT_ADSP_RESET_MEM := $(dt_nodelabel_path,adsp_reset) +DT_ADSP_DATA_MEM := $(dt_nodelabel_path,adsp_data) +DT_ADSP_TEXT_MEM := $(dt_nodelabel_path,adsp_text) + +if BOARD_NXP_ADSP_RT595 + +config RT595_ADSP_STACK_SIZE + hex "Boot time stack size" + default 0x1000 + help + Stack space is reserved at the end of the RT595_ADSP_DATA_MEM + region, starting at RT595_ADSP_DATA_MEM_ADDR - RT595_ADSP_STACK_SIZE + +config RT595_ADSP_RESET_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_RESET_MEM)) + +config RT595_ADSP_RESET_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_RESET_MEM)) + +config RT595_ADSP_DATA_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_DATA_MEM)) + +config RT595_ADSP_DATA_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_DATA_MEM)) + +config RT595_ADSP_TEXT_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_TEXT_MEM)) + +config RT595_ADSP_TEXT_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_TEXT_MEM)) + +endif # BOARD_NXP_ADSP_RT595 diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig.board b/boards/xtensa/nxp_adsp_rt595/Kconfig.board new file mode 100644 index 00000000000..a88eb58638f --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NXP_ADSP_RT595 + bool "NXP ADSP RT595" + depends on SOC_SERIES_NXP_RT5XX diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig b/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig new file mode 100644 index 00000000000..7ffe782d28b --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NXP_ADSP_RT595 + +config BOARD + default "nxp_adsp_rt595" + +endif # BOARD_NXP_ADSP_RT595 diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts new file mode 100644 index 00000000000..dc546c8db24 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "nxp_adsp_rt595"; + compatible = "nxp"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx6"; + reg = <0>; + }; + }; + + sram0: memory@0 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "memory"; + compatible = "mmio-sram"; + /* Reserve first 512kB of shared memory for ADSP. */ + reg = <0x0 DT_SIZE_K(512)>; + /* Reset section must always be at 0 and at least 1kB. */ + adsp_reset: memory@0 { + reg = <0x0 DT_SIZE_K(1)>; + }; + /* Code and data sections can be moved around and resized if needed. */ + adsp_text: memory@400 { + reg = <0x400 DT_SIZE_K(255)>; + }; + /* On RT595 ADSP shared RAM is mapped at offset 0 on the code bus and at + * offset 0x800000 on the data bus. + */ + adsp_data: memory@840000 { + reg = <0x840000 DT_SIZE_K(256)>; + }; + }; + + chosen { + zephyr,sram = &adsp_data; + }; +}; diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml new file mode 100644 index 00000000000..ca3e0c21252 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml @@ -0,0 +1,9 @@ +identifier: nxp_adsp_rt595 +name: i.MXRT595 DSP +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig new file mode 100644 index 00000000000..0e80f8a41a6 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig @@ -0,0 +1,7 @@ +CONFIG_SOC_SERIES_NXP_RT5XX=y +CONFIG_SOC_NXP_RT595=y +CONFIG_BOARD_NXP_ADSP_RT595=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n +CONFIG_XTENSA_SMALL_VECTOR_TABLE_ENTRY=y diff --git a/soc/xtensa/nxp_adsp/CMakeLists.txt b/soc/xtensa/nxp_adsp/CMakeLists.txt index f317b0b7054..f306839ac2a 100644 --- a/soc/xtensa/nxp_adsp/CMakeLists.txt +++ b/soc/xtensa/nxp_adsp/CMakeLists.txt @@ -1,8 +1,12 @@ -# NXP i.MX8 SoC family CMake file +# NXP i.MX8/RT SoC family CMake file # # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 +if(CONFIG_SOC_NXP_RT595) + zephyr_compile_definitions(CPU_MIMXRT595SFFOC_dsp) +endif() + add_subdirectory(common) # west sign diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series new file mode 100644 index 00000000000..b5a56658c7d --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series @@ -0,0 +1,46 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NXP_RT5XX + +config SOC_SERIES + string + default "rt5xx" + +config SOC_TOOLCHAIN_NAME + string + default "nxp_rt500_adsp" + +config SOC + string + default "nxp_rt5xx" + +config SOC_PART_NUMBER + string + default "MIMXRT595SFFOC_dsp" if SOC_NXP_RT595 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 198000000 + +config XTENSA_CCOUNT_HZ + default SYS_CLOCK_HW_CYCLES_PER_SEC + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config DYNAMIC_INTERRUPTS + default n + +config CACHE + default n + +config DCACHE + default n + +config CACHE_MANAGEMENT + default n + +config LOG + default n + +endif # SOC_SERIES_NXP_RT5XX diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series new file mode 100644 index 00000000000..5135b881638 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NXP_RT5XX + bool "NXP RT5xx Series" + select SOC_FAMILY_NXP_ADSP + select XTENSA + select XTENSA_HAL if ("$(ZEPHYR_TOOLCHAIN_VARIANT)" != "xcc" && "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "xt-clang") + select XTENSA_RESET_VECTOR + select XTENSA_USE_CORE_CRT1 + help + NXP RT5xx ADSP Series diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc new file mode 100644 index 00000000000..e5b598c4f57 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "NXP RT5xx ADSP SoC Selection" + + config SOC_NXP_RT595 + bool "NXP RT595" + depends on SOC_SERIES_NXP_RT5XX +endchoice diff --git a/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h b/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h new file mode 100644 index 00000000000..0919a03d9ce --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 5 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT22_LEVEL) || XCHAL_INT22_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT23_LEVEL) || XCHAL_INT23_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT24_LEVEL) || XCHAL_INT24_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT25_LEVEL) || XCHAL_INT25_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT26_LEVEL) || XCHAL_INT26_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT27_LEVEL) || XCHAL_INT27_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT28_LEVEL) || XCHAL_INT28_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT29_LEVEL) || XCHAL_INT29_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT30_LEVEL) || XCHAL_INT30_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT31_LEVEL) || XCHAL_INT31_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif + +/* + * Interrupt masks for every level (RT595 ADSP): + * XCHAL_INTLEVEL1_MASK: 0x0000FFE0 + * XCHAL_INTLEVEL2_MASK: 0x00FF0006 + * XCHAL_INTLEVEL3_MASK: 0xFF000018 + * XCHAL_INTLEVEL4_MASK: 0x00000000 + * XCHAL_INTLEVEL5_MASK: 0x00000001 + */ + +static inline int _xtensa_handle_one_int1(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL1_MASK; + for (int i = 5; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int2(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL2_MASK; + for (int i = 1; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int3(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL3_MASK; + for (int i = 3; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int4(unsigned int mask) +{ + return 0; +} + +static inline int _xtensa_handle_one_int5(unsigned int mask) +{ + int irq; + + if (mask & BIT(0)) { + mask = BIT(0); + irq = 0; + goto handle_irq; + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} diff --git a/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h b/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h new file mode 100644 index 00000000000..af9e1888e1c --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#define IRAM_BASE (CONFIG_RT595_ADSP_TEXT_MEM_ADDR) +#define IRAM_SIZE (CONFIG_RT595_ADSP_TEXT_MEM_SIZE) + +#define SDRAM0_BASE (CONFIG_RT595_ADSP_DATA_MEM_ADDR) +#define SDRAM0_SIZE (CONFIG_RT595_ADSP_DATA_MEM_SIZE - CONFIG_RT595_ADSP_STACK_SIZE) + +/* The reset vector address in SRAM and its size. */ +#define XCHAL_RESET_VECTOR0_PADDR_IRAM (CONFIG_RT595_ADSP_RESET_MEM_ADDR) +#define MEM_RESET_TEXT_SIZE (0x2e0) +#define MEM_RESET_LIT_SIZE (0x120) + +/* Base address of all interrupt vectors in IRAM. */ +#define XCHAL_VECBASE_RESET_PADDR_IRAM (IRAM_BASE) +#define MEM_VECBASE_LIT_SIZE (0x178) + +/* Vector and literal sizes. */ +#define MEM_VECT_LIT_SIZE (0x4) +#define MEM_VECT_TEXT_SIZE (0x1C) + +/* Addresses of the interrupt vectors. */ +#define XCHAL_INT_VECTOR_ADDR(x) (XCHAL_VECBASE_RESET_PADDR_IRAM + (x)) +#define XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x17C)) +#define XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x19C)) +#define XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1BC)) +#define XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1DC)) +#define XCHAL_KERNEL_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1FC)) +#define XCHAL_USER_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x21C)) +#define XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x23C)) + +/* Location for the intList section which is later used to construct the + * Interrupt Descriptor Table (IDT). This is a bogus address as this + * section will be stripped off in the final image. + */ +#define IDT_BASE (IRAM_BASE + IRAM_SIZE) + +/* Size of the Interrupt Descriptor Table (IDT). */ +#define IDT_SIZE (0x2000) diff --git a/soc/xtensa/nxp_adsp/rt5xx/linker.ld b/soc/xtensa/nxp_adsp/rt5xx/linker.ld new file mode 100644 index 00000000000..27be7215194 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/linker.ld @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2021 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +OUTPUT_ARCH(xtensa) + +#include +#include + +#include +#include +#include + +#define RAMABLE_REGION sdram0 :sdram0_phdr +#define ROMABLE_REGION sdram0 :sdram0_phdr + +MEMORY +{ + vector_reset_text : + org = XCHAL_RESET_VECTOR0_PADDR_IRAM, + len = MEM_RESET_TEXT_SIZE + vector_reset_lit : + org = XCHAL_RESET_VECTOR0_PADDR_IRAM + MEM_RESET_TEXT_SIZE, + len = MEM_RESET_LIT_SIZE + vector_base_text : + org = XCHAL_VECBASE_RESET_PADDR_IRAM, + len = MEM_VECBASE_LIT_SIZE + vector_int2_lit : + org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int2_text : + org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int3_lit : + org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int3_text : + org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int4_lit : + org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int4_text : + org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int5_lit : + org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int5_text : + org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_kernel_lit : + org = XCHAL_KERNEL_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_kernel_text : + org = XCHAL_KERNEL_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_user_lit : + org = XCHAL_USER_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_user_text : + org = XCHAL_USER_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_double_lit : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_double_text : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + iram_text_start : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM + MEM_VECT_TEXT_SIZE, + len = (IRAM_BASE + IRAM_SIZE) - (XCHAL_DOUBLEEXC_VECTOR_PADDR + MEM_VECT_TEXT_SIZE) + sdram0 : + org = SDRAM0_BASE, + len = SDRAM0_SIZE +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST : + org = IDT_BASE, + len = IDT_SIZE +#endif +} + +PHDRS +{ + vector_reset_text_phdr PT_LOAD; + vector_reset_lit_phdr PT_LOAD; + vector_base_text_phdr PT_LOAD; + vector_base_lit_phdr PT_LOAD; + vector_int2_text_phdr PT_LOAD; + vector_int2_lit_phdr PT_LOAD; + vector_int3_text_phdr PT_LOAD; + vector_int3_lit_phdr PT_LOAD; + vector_int4_text_phdr PT_LOAD; + vector_int4_lit_phdr PT_LOAD; + vector_int5_text_phdr PT_LOAD; + vector_int5_lit_phdr PT_LOAD; + vector_kernel_text_phdr PT_LOAD; + vector_kernel_lit_phdr PT_LOAD; + vector_user_text_phdr PT_LOAD; + vector_user_lit_phdr PT_LOAD; + vector_double_text_phdr PT_LOAD; + vector_double_lit_phdr PT_LOAD; + iram_text_start_phdr PT_LOAD; + sdram0_phdr PT_LOAD; +} + +PROVIDE(_memmap_reset_vector = XCHAL_RESET_VECTOR0_PADDR_IRAM); +PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR_IRAM); + +ENTRY(CONFIG_KERNEL_ENTRY) + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x00000012; +_memmap_cacheattr_wt_base = 0x00000012; +_memmap_cacheattr_bp_base = 0x00000022; +_memmap_cacheattr_unused_mask = 0xFFFFFF00; +_memmap_cacheattr_wb_trapnull = 0x22222212; +_memmap_cacheattr_wba_trapnull = 0x22222212; +_memmap_cacheattr_wbna_trapnull = 0x22222212; +_memmap_cacheattr_wt_trapnull = 0x22222212; +_memmap_cacheattr_bp_trapnull = 0x22222222; +_memmap_cacheattr_wb_strict = 0xFFFFFF12; +_memmap_cacheattr_wt_strict = 0xFFFFFF12; +_memmap_cacheattr_bp_strict = 0xFFFFFF22; +_memmap_cacheattr_wb_allvalid = 0x22222212; +_memmap_cacheattr_wt_allvalid = 0x22222212; +_memmap_cacheattr_bp_allvalid = 0x22222222; +_memmap_region_map = 0x00000003; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); + +SECTIONS +{ + +#include + .ResetVector.text : ALIGN(4) + { + _ResetVector_text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + _ResetVector_text_end = ABSOLUTE(.); + } >vector_reset_text :vector_reset_text_phdr + + .ResetVector.literal : ALIGN(4) + { + _ResetVector_literal_start = ABSOLUTE(.); + *(.ResetVector.literal) + _ResetVector_literal_end = ABSOLUTE(.); + } >vector_reset_lit :vector_reset_lit_phdr + + .WindowVectors.text : ALIGN(4) + { + _WindowVectors_text_start = ABSOLUTE(.); + KEEP (*(.WindowVectors.text)) + _WindowVectors_text_end = ABSOLUTE(.); + } >vector_base_text :vector_base_text_phdr + + .Level2InterruptVector.literal : ALIGN(4) + { + _Level2InterruptVector_literal_start = ABSOLUTE(.); + *(.Level2InterruptVector.literal) + _Level2InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int2_lit :vector_int2_lit_phdr + + .Level2InterruptVector.text : ALIGN(4) + { + _Level2InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level2InterruptVector.text)) + _Level2InterruptVector_text_end = ABSOLUTE(.); + } >vector_int2_text :vector_int2_text_phdr + + .Level3InterruptVector.literal : ALIGN(4) + { + _Level3InterruptVector_literal_start = ABSOLUTE(.); + *(.Level3InterruptVector.literal) + _Level3InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int3_lit :vector_int3_lit_phdr + + .Level3InterruptVector.text : ALIGN(4) + { + _Level3InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level3InterruptVector.text)) + _Level3InterruptVector_text_end = ABSOLUTE(.); + } >vector_int3_text :vector_int3_text_phdr + + .DebugExceptionVector.literal : ALIGN(4) + { + _DebugExceptionVector_literal_start = ABSOLUTE(.); + *(.DebugExceptionVector.literal) + _DebugExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int4_lit :vector_int4_lit_phdr + + .DebugExceptionVector.text : ALIGN(4) + { + _DebugExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DebugExceptionVector.text)) + _DebugExceptionVector_text_end = ABSOLUTE(.); + } >vector_int4_text :vector_int4_text_phdr + + .NMIExceptionVector.literal : ALIGN(4) + { + _NMIExceptionVector_literal_start = ABSOLUTE(.); + *(.NMIExceptionVector.literal) + _NMIExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int5_lit :vector_int5_lit_phdr + + .NMIExceptionVector.text : ALIGN(4) + { + _NMIExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.NMIExceptionVector.text)) + _NMIExceptionVector_text_end = ABSOLUTE(.); + } >vector_int5_text :vector_int5_text_phdr + + .KernelExceptionVector.literal : ALIGN(4) + { + _KernelExceptionVector_literal_start = ABSOLUTE(.); + *(.KernelExceptionVector.literal) + _KernelExceptionVector_literal_end = ABSOLUTE(.); + } >vector_kernel_lit :vector_kernel_lit_phdr + + .KernelExceptionVector.text : ALIGN(4) + { + _KernelExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.KernelExceptionVector.text)) + _KernelExceptionVector_text_end = ABSOLUTE(.); + } >vector_kernel_text :vector_kernel_text_phdr + + .UserExceptionVector.literal : ALIGN(4) + { + _UserExceptionVector_literal_start = ABSOLUTE(.); + *(.UserExceptionVector.literal) + _UserExceptionVector_literal_end = ABSOLUTE(.); + } >vector_user_lit :vector_user_lit_phdr + + .UserExceptionVector.text : ALIGN(4) + { + _UserExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.UserExceptionVector.text)) + _UserExceptionVector_text_end = ABSOLUTE(.); + } >vector_user_text :vector_user_text_phdr + + .DoubleExceptionVector.literal : ALIGN(4) + { + _DoubleExceptionVector_literal_start = ABSOLUTE(.); + *(.DoubleExceptionVector.literal) + _DoubleExceptionVector_literal_end = ABSOLUTE(.); + } >vector_double_lit :vector_double_lit_phdr + + .DoubleExceptionVector.text : ALIGN(4) + { + _DoubleExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DoubleExceptionVector.text)) + _DoubleExceptionVector_text_end = ABSOLUTE(.); + } >vector_double_text :vector_double_text_phdr + + .iram.text : ALIGN(4) + { + _stext = .; + _iram_text_start = ABSOLUTE(.); + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + _iram_text_end = ABSOLUTE(.); + } >iram_text_start :iram_text_start_phdr + + .rodata : ALIGN(4) + { + __rodata_region_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + KEEP (*(.xt_except_table)) + KEEP (*(.gcc_except_table .gcc_except_table.*)) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + KEEP (*(.eh_frame)) + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + __rodata_region_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .module_init : ALIGN(4) + { + _module_init_start = ABSOLUTE(.); + *(*.initcall) + _module_init_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + *(.ResetVector.literal) + *(.entry.text) + *(.init.literal) + KEEP(*(.init)) + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + KEEP(*(.fini)) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >iram_text_start :iram_text_start_phdr + +#include + + .fw_ready : ALIGN(4) + { + KEEP(*(".fw_ready")); + KEEP (*(.fw_ready_metadata)) + } >sdram0 :sdram0_phdr + + .noinit : ALIGN(4) + { + *(.noinit) + *(.noinit.*) + } >sdram0 :sdram0_phdr + + .data : ALIGN(4) + { + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + KEEP(*(.gnu.linkonce.d.*personality*)) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + KEEP(*(.jcr)) + _trace_ctx_start = ABSOLUTE(.); + *(.trace_ctx) + _trace_ctx_end = ABSOLUTE(.); + . = ALIGN(4); + *(.gna_model) + __data_end = ABSOLUTE(.); + . = ALIGN(4096); + } >sdram0 :sdram0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + +#include + + .bss (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .heap_mem (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _heap_mem_start = ABSOLUTE(.); + *(*.heap_mem) + _heap_mem_end = ABSOLUTE(.); + + } >sdram0 :sdram0_phdr + + /* stack */ + _end = ALIGN (8); + + /DISCARD/ : { *(.note.GNU-stack) } + _heap_sentry = SDRAM0_BASE + SDRAM0_SIZE; + __stack = SDRAM0_BASE + SDRAM0_SIZE + CONFIG_RT595_ADSP_STACK_SIZE; + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .debug_ranges 0 : { *(.debug_ranges) } + .xtensa.info 0 : { *(.xtensa.info) } + .xt.insn 0 : + { + KEEP (*(.xt.insn)) + KEEP (*(.gnu.linkonce.x.*)) + } + .xt.prop 0 : + { + KEEP (*(.xt.prop)) + KEEP (*(.xt.prop.*)) + KEEP (*(.gnu.linkonce.prop.*)) + } + .xt.lit 0 : + { + KEEP (*(.xt.lit)) + KEEP (*(.xt.lit.*)) + KEEP (*(.gnu.linkonce.p.*)) + } + .xt.profile_range 0 : + { + KEEP (*(.xt.profile_range)) + KEEP (*(.gnu.linkonce.profile_range.*)) + } + .xt.profile_ranges 0 : + { + KEEP (*(.xt.profile_ranges)) + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) + } + .xt.profile_files 0 : + { + KEEP (*(.xt.profile_files)) + KEEP (*(.gnu.linkonce.xt.profile_files.*)) + } +#ifdef CONFIG_GEN_ISR_TABLES +#include +#endif +} From 433f47ee57ed27c4980146a03310d294b33f8a93 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 24 Oct 2023 15:57:39 +0200 Subject: [PATCH 2574/4498] samples ipc icmsg_me: Convert to sysbuild Convert this sample application build to sysbuild. Signed-off-by: Alberto Escolar Piedras --- .../ipc/ipc_service/icmsg_me/CMakeLists.txt | 17 ++--------------- .../ipc/ipc_service/icmsg_me/Kconfig.sysbuild | 9 +++++++++ .../ipc/ipc_service/icmsg_me/remote/sample.yaml | 9 --------- .../subsys/ipc/ipc_service/icmsg_me/sample.yaml | 1 + .../ipc/ipc_service/icmsg_me/sysbuild.cmake | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild delete mode 100644 samples/subsys/ipc/ipc_service/icmsg_me/remote/sample.yaml create mode 100644 samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt b/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt index 5317f899424..18a138548cf 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt @@ -6,27 +6,14 @@ cmake_minimum_required(VERSION 3.20.0) -set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/ipc_service_remote-prefix/src/ipc_service_remote-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -else() +if(NOT ("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp")) message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(ipc_service) target_sources(app PRIVATE src/main.c) include(ExternalProject) - -ExternalProject_Add( - ipc_service_remote - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - BUILD_BYPRODUCTS "${REMOTE_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - # NB: Do we need to pass on more CMake variables? - BUILD_ALWAYS True -) diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild new file mode 100644 index 00000000000..47884745130 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg_me/remote/sample.yaml deleted file mode 100644 index baf92ccc3da..00000000000 --- a/samples/subsys/ipc/ipc_service/icmsg_me/remote/sample.yaml +++ /dev/null @@ -1,9 +0,0 @@ -sample: - name: IPC Service example integration (icmsg multi endpoint follower backend) (remote) -tests: - sample.ipc.icmsg_me_follower: - platform_allow: nrf5340dk_nrf5340_cpunet - integration_platforms: - - nrf5340dk_nrf5340_cpunet - tags: ipc - harness: remote diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml index 8a6443de1fa..2fe7f79ef40 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml @@ -6,4 +6,5 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: ipc + sysbuild: true harness: remote diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake b/samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake new file mode 100644 index 00000000000..d0d79b8f240 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_NET_CORE_BOARD} +) From 19cc0fe099d2f252d7410aaa29cb4569f18917e2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 09:46:00 +0200 Subject: [PATCH 2575/4498] samples ipc icmsg: Convert to sysbuild Convert this sample application build to sysbuild. Signed-off-by: Alberto Escolar Piedras --- .../subsys/ipc/ipc_service/icmsg/CMakeLists.txt | 17 ++--------------- .../ipc/ipc_service/icmsg/Kconfig.sysbuild | 9 +++++++++ samples/subsys/ipc/ipc_service/icmsg/README.rst | 1 + .../ipc/ipc_service/icmsg/remote/sample.yaml | 9 --------- .../subsys/ipc/ipc_service/icmsg/sample.yaml | 1 + .../subsys/ipc/ipc_service/icmsg/sysbuild.cmake | 14 ++++++++++++++ 6 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild delete mode 100644 samples/subsys/ipc/ipc_service/icmsg/remote/sample.yaml create mode 100644 samples/subsys/ipc/ipc_service/icmsg/sysbuild.cmake diff --git a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt index 31bc4418c9d..2d9d62bdf23 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt @@ -6,15 +6,12 @@ cmake_minimum_required(VERSION 3.20.0) -set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/ipc_service_remote-prefix/src/ipc_service_remote-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -else() +if(NOT ("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp")) message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(ipc_service_host) target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) @@ -22,13 +19,3 @@ target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) target_sources(app PRIVATE src/main.c) include(ExternalProject) - -ExternalProject_Add( - ipc_service_remote - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - BUILD_BYPRODUCTS "${REMOTE_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - # NB: Do we need to pass on more CMake variables? - BUILD_ALWAYS True -) diff --git a/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild new file mode 100644 index 00000000000..47884745130 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" diff --git a/samples/subsys/ipc/ipc_service/icmsg/README.rst b/samples/subsys/ipc/ipc_service/icmsg/README.rst index 81426ee9353..c12c4107075 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/README.rst +++ b/samples/subsys/ipc/ipc_service/icmsg/README.rst @@ -18,6 +18,7 @@ Building the application for nrf5340dk_nrf5340_cpuapp :zephyr-app: samples/subsys/ipc/ipc_service/icmsg :board: nrf5340dk_nrf5340_cpuapp :goals: debug + :west-args: --sysbuild Open a serial terminal (minicom, putty, etc.) and connect the board with the following settings: diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/remote/sample.yaml deleted file mode 100644 index 3b927c11f37..00000000000 --- a/samples/subsys/ipc/ipc_service/icmsg/remote/sample.yaml +++ /dev/null @@ -1,9 +0,0 @@ -sample: - name: IPC Service example integration (icmsg backend) (remote) -tests: - sample.ipc.icmsg_remote: - platform_allow: nrf5340dk_nrf5340_cpunet - integration_platforms: - - nrf5340dk_nrf5340_cpunet - tags: ipc - harness: remote diff --git a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml index 582f277ce7a..b54fc7f8962 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml @@ -6,4 +6,5 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: ipc + sysbuild: true harness: remote diff --git a/samples/subsys/ipc/ipc_service/icmsg/sysbuild.cmake b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.cmake new file mode 100644 index 00000000000..d0d79b8f240 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_NET_CORE_BOARD} +) From adf9e4000f3f8abd4e32e5036451e2f9861207b7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 09:51:02 +0200 Subject: [PATCH 2576/4498] samples ipc static_vrings: Convert to sysbuild Convert this sample application build to sysbuild. Signed-off-by: Alberto Escolar Piedras --- .../ipc_service/static_vrings/CMakeLists.txt | 17 ++--------------- .../ipc_service/static_vrings/Kconfig.sysbuild | 9 +++++++++ .../ipc/ipc_service/static_vrings/README.rst | 1 + .../static_vrings/remote/sample.yaml | 9 --------- .../ipc/ipc_service/static_vrings/sample.yaml | 1 + .../ipc_service/static_vrings/sysbuild.cmake | 14 ++++++++++++++ 6 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild delete mode 100644 samples/subsys/ipc/ipc_service/static_vrings/remote/sample.yaml create mode 100644 samples/subsys/ipc/ipc_service/static_vrings/sysbuild.cmake diff --git a/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt b/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt index c5ae1a2f8d9..6af69691e1e 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt @@ -6,27 +6,14 @@ cmake_minimum_required(VERSION 3.20.0) -set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/ipc_service_remote-prefix/src/ipc_service_remote-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -else() +if(NOT ("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp")) message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(ipc_service) target_sources(app PRIVATE src/main.c) include(ExternalProject) - -ExternalProject_Add( - ipc_service_remote - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - BUILD_BYPRODUCTS "${REMOTE_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - # NB: Do we need to pass on more CMake variables? - BUILD_ALWAYS True -) diff --git a/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild new file mode 100644 index 00000000000..47884745130 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" diff --git a/samples/subsys/ipc/ipc_service/static_vrings/README.rst b/samples/subsys/ipc/ipc_service/static_vrings/README.rst index e9633ad63d6..7fbed84cad8 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/README.rst +++ b/samples/subsys/ipc/ipc_service/static_vrings/README.rst @@ -18,6 +18,7 @@ Building the application for nrf5340dk_nrf5340_cpuapp :zephyr-app: samples/subsys/ipc/ipc_service/static_vrings :board: nrf5340dk_nrf5340_cpuapp :goals: debug + :west-args: --sysbuild Open a serial terminal (minicom, putty, etc.) and connect the board with the following settings: diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/sample.yaml b/samples/subsys/ipc/ipc_service/static_vrings/remote/sample.yaml deleted file mode 100644 index ab70e115c9a..00000000000 --- a/samples/subsys/ipc/ipc_service/static_vrings/remote/sample.yaml +++ /dev/null @@ -1,9 +0,0 @@ -sample: - name: IPC Service example integration (OpenAMP static_vrings backend) (remote) -tests: - sample.ipc.static_vrings_remote: - platform_allow: nrf5340dk_nrf5340_cpunet - integration_platforms: - - nrf5340dk_nrf5340_cpunet - tags: ipc - harness: remote diff --git a/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml b/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml index 42e487503ba..3e57abf32eb 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml +++ b/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml @@ -6,4 +6,5 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: ipc + sysbuild: true harness: remote diff --git a/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.cmake b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.cmake new file mode 100644 index 00000000000..d0d79b8f240 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_NET_CORE_BOARD} +) From 3f1eed17f83a93e6dcd731d2a3b77b48f985d68c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 24 Oct 2023 15:16:27 +0200 Subject: [PATCH 2577/4498] nrf53_bsim: Get IPC shared memory buffer size from DT Before we were defining the buffer in the runner context which is simpler and less error prone, but it had a hardcoded size decoupled from DT as it could not be based on DT information. Instead, let's allocate the buffer in the application core image. This allows us to size it based on the device tree configuration. Note that this then requires the application core image to be present during link time of the final executable when the IPC subsystem is used. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/CMakeLists.txt | 4 ++-- boards/posix/nrf_bsim/Kconfig.defconfig | 4 +++- boards/posix/nrf_bsim/ipc_backend.c | 26 ++++++++++++++++++------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/boards/posix/nrf_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt index c55df7d0095..66dec22ac57 100644 --- a/boards/posix/nrf_bsim/CMakeLists.txt +++ b/boards/posix/nrf_bsim/CMakeLists.txt @@ -35,8 +35,8 @@ target_sources(native_simulator INTERFACE common/trace_hook.c ) -if (CONFIG_IPC_SERVICE) - target_sources(native_simulator INTERFACE +if (CONFIG_IPC_SERVICE AND CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP) + zephyr_library_sources( ipc_backend.c ) endif() diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index a03b8b1d384..0c69364b147 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -6,7 +6,9 @@ config BUILD_OUTPUT_BIN default n config BUILD_OUTPUT_EXE - default y + # When the IPC service is used, the net core image requires the application core image, as it needs + # access to its IPC buffer. Without it, the executable cannot be built. + default y if !(BOARD_NRF5340BSIM_NRF5340_CPUNET && IPC_SERVICE && (NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS = "")) config OUTPUT_PRINT_MEMORY_USAGE default n diff --git a/boards/posix/nrf_bsim/ipc_backend.c b/boards/posix/nrf_bsim/ipc_backend.c index 1619f449b79..4f14924a44a 100644 --- a/boards/posix/nrf_bsim/ipc_backend.c +++ b/boards/posix/nrf_bsim/ipc_backend.c @@ -5,11 +5,23 @@ */ /* - * This buffer is the shared memory buffer for the RPMSG IPC backed - * in simulation. - * It must be at last as large as the size defined in device tree, but as it will be compiled in - * the native simulator runner context we cannot refer to DT itself to size it. - * The default buffer for this target is defined in - * boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dtsi + * Here we define the shared memory buffers for the RPMSG IPC back-end in simulation. + * In real HW, these are booked in RAM thru device tree configuration. + * In this simulated target, we just define them at build time to have the size defined + * in device tree. + * + * Note that this file is only compiled as part of the application core image, and therefore + * when the network core is built with the IPC service, we cannot produce an executable + * with the network core image alone, as we would lack this buffer during linking. */ -char IPC0_shm_buffer[65536]; + +#include "nsi_cpu_if.h" +#include + +#define DT_DRV_COMPAT zephyr_ipc_openamp_static_vrings + +#define DEFINE_BACKEND_BUFFER(i) \ + NATIVE_SIMULATOR_IF \ + char IPC##i##_shm_buffer[DT_REG_SIZE(DT_INST_PHANDLE(i, memory_region))]; + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_BUFFER) From fd4e66499cdcf4db30c42b53ec4ea076de253f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Tue, 17 Oct 2023 15:24:25 +0200 Subject: [PATCH 2578/4498] SPARC: Update the Flush windows software trap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit re-implements the SPARC V8 ABI "Flush windows" software trap. The trap is generated by C++ compilers for exceptions and also by the C standard library function longjmp(). There were two issues with the previous implementation: 1. It did reads and writes via the stack pointer of the trap window, which is not defined. 2. It executed with traps enabled but without the processor run-time state set to safely handle traps. In particular there was no valid stack for trap processing. Even though interrupt priority was set to highest level, the behavior at other traps was not deterministic. For example non-maskable interrupt (15) trap or bus error trap for instruction fetch. This new implementation does not store backup copies of CPU registers to the stack, and it executes with traps disabled. Fixes #63901 Signed-off-by: Martin Åberg --- arch/sparc/core/window_trap.S | 111 +++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/arch/sparc/core/window_trap.S b/arch/sparc/core/window_trap.S index ea810e1d6dd..5a9edfd37c2 100644 --- a/arch/sparc/core/window_trap.S +++ b/arch/sparc/core/window_trap.S @@ -83,60 +83,85 @@ SECTION_FUNC(TEXT, __sparc_trap_window_underflow) * "By executing a type 3 trap, a process asks the system to flush all its * register windows to the stack." * - * This implementation uses the window overflow trap handler to perform the - * actual window flush. - * * On entry: * %l0: psr * %l1: pc * %l2: npc */ SECTION_FUNC(TEXT, __sparc_trap_flush_windows) - /* push a few registers which are needed later to the stack */ - sub %sp, 0x10, %sp - std %l0, [%sp + 0x40 + 0x00] - st %l2, [%sp + 0x40 + 0x08] - st %g2, [%sp + 0x40 + 0x0c] - - restore - /* In window where we trapped from. This window will not be flushed. */ - - /* Set highest processor interrupt level and enable traps. */ - rd %psr, %g2 - or %g2, PSR_PIL, %g2 - wr %g2, PSR_ET, %psr - nop - nop + /* Save global registers used by the routine */ + mov %g3, %l3 + mov %g4, %l4 + mov %g5, %l5 + mov %g1, %l6 + mov %g2, %l7 - /* Execute "save" NWINDOWS-1 times. */ - set CONFIG_SPARC_NWIN-2, %g2 -1: - save - cmp %g2, %g0 - bne 1b - sub %g2, 1, %g2 + /* Uses g3=psr, g4=1, g2=wim, g1,g5=scratch */ + mov %l0, %g3 + set 1, %g4 + rd %wim, %g2 - /* Execute "restore" NWINDOWS-1 times. */ - set CONFIG_SPARC_NWIN-2, %g2 -2: - restore - cmp %g2, %g0 - bne 2b - sub %g2, 1, %g2 + /* + * We can always restore the previous window. Check if we can restore + * the window after that. + */ + and %l0, PSR_CWP, %g1 + add %g1, 2, %g1 + ba .LcheckNextWindow + restore - save + /* Flush window to stack */ +.LflushWindow: + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] - /* pop registers from stack which are used for the trap return */ - ldd [%sp + 0x40 + 0x00], %l0 - ld [%sp + 0x40 + 0x08], %l2 - ld [%sp + 0x40 + 0x0c], %g2 - add %sp, 0x10, %sp + /* + * Check if next window is invalid by comparing + * (1 << ((cwp + 1) % NWIN)) with WIM + */ +.LcheckNextWindow: + set CONFIG_SPARC_NWIN, %g5 + cmp %g1, %g5 + bge,a .Lnowrap + sub %g1, %g5, %g1 +.Lnowrap: + sll %g4, %g1, %g5 + cmp %g5, %g2 + be .LflushWindowDone + inc %g1 - /* Restore %psr as it was on trap entry. */ - wr %l0, %psr - nop - nop - nop + /* We need to flush the next window */ + ba .LflushWindow + restore + /* + * All used windows have been flushed. Set WIM to cause trap for CWP+2. + * When we return from this trap it will be CWP+1 that will trap, that + * is, the next restore or rett. + */ +.LflushWindowDone: + /* We can not restore %psr from %l0 because we may be in any window. */ + wr %g3, %psr + and %g3, PSR_CWP, %g1 + add %g1, 2, %g1 + set CONFIG_SPARC_NWIN, %g5 + /* We are now back in the trap window. */ + cmp %g1, %g5 + bge,a .Lnowrap2 + sub %g1, %g5, %g1 +.Lnowrap2: + sll %g4, %g1, %g1 + wr %g1, %wim + mov %l3, %g3 + mov %l4, %g4 + mov %l5, %g5 + mov %l6, %g1 + mov %l7, %g2 jmp %l2 rett %l2 + 4 From d8b153e00f06d8b9943da3d477afc2c5d8fad250 Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 15 Oct 2023 22:44:16 +0300 Subject: [PATCH 2579/4498] drivers: eth: eth_stm32_hal: Add DSA support This commit adds DSA functionality support to the Ethernet driver for the STM32 SoC. Signed-off-by: Aleksandr Senin --- drivers/ethernet/Kconfig.dsa | 4 ++-- drivers/ethernet/eth_stm32_hal.c | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/ethernet/Kconfig.dsa b/drivers/ethernet/Kconfig.dsa index 3683a539759..c6b78f0a463 100644 --- a/drivers/ethernet/Kconfig.dsa +++ b/drivers/ethernet/Kconfig.dsa @@ -6,10 +6,10 @@ menuconfig NET_DSA bool "Distributed Switch Architecture support" - depends on ETH_MCUX || ETH_SAM_GMAC + depends on ETH_MCUX || ETH_SAM_GMAC || ETH_STM32_HAL help Enable Distributed Switch Architecture support. For now it - only supports Kinetics ENET driver. + only supports Kinetics and STM32 ENET drivers. if NET_DSA diff --git a/drivers/ethernet/eth_stm32_hal.c b/drivers/ethernet/eth_stm32_hal.c index 755134359eb..40760171e9d 100644 --- a/drivers/ethernet/eth_stm32_hal.c +++ b/drivers/ethernet/eth_stm32_hal.c @@ -33,6 +33,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include +#if defined(CONFIG_NET_DSA) +#include +#endif + #if defined(CONFIG_PTP_CLOCK_STM32_HAL) #include #endif /* CONFIG_PTP_CLOCK_STM32_HAL */ @@ -867,6 +871,7 @@ static void rx_thread(void *arg1, void *unused1, void *unused2) uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC; const struct device *dev; struct eth_stm32_hal_dev_data *dev_data; + struct net_if *iface; struct net_pkt *pkt; int res; uint32_t status; @@ -892,7 +897,11 @@ static void rx_thread(void *arg1, void *unused1, void *unused2) vlan_tag)); } while ((pkt = eth_rx(dev, &vlan_tag)) != NULL) { - res = net_recv_data(net_pkt_iface(pkt), pkt); + iface = net_pkt_iface(pkt); +#if defined(CONFIG_NET_DSA) + iface = dsa_net_recv(iface, &pkt); +#endif + res = net_recv_data(iface, pkt); if (res < 0) { eth_stats_update_errors_rx( net_pkt_iface(pkt)); @@ -1516,6 +1525,10 @@ static void eth_iface_init(struct net_if *iface) sizeof(dev_data->mac_addr), NET_LINK_ETHERNET); +#if defined(CONFIG_NET_DSA) + dsa_register_master_tx(iface, ð_tx); +#endif + ethernet_init(iface); net_if_carrier_off(iface); @@ -1559,6 +1572,9 @@ static enum ethernet_hw_caps eth_stm32_hal_get_capabilities(const struct device #if defined(CONFIG_ETH_STM32_HW_CHECKSUM) | ETHERNET_HW_RX_CHKSUM_OFFLOAD | ETHERNET_HW_TX_CHKSUM_OFFLOAD +#endif +#if defined(CONFIG_NET_DSA) + | ETHERNET_DSA_MASTER_PORT #endif ; } @@ -1638,7 +1654,11 @@ static const struct ethernet_api eth_api = { #endif /* CONFIG_PTP_CLOCK_STM32_HAL */ .get_capabilities = eth_stm32_hal_get_capabilities, .set_config = eth_stm32_hal_set_config, +#if defined(CONFIG_NET_DSA) + .send = dsa_tx, +#else .send = eth_tx, +#endif #if defined(CONFIG_NET_STATISTICS_ETHERNET) .get_stats = eth_stm32_hal_get_stats, #endif /* CONFIG_NET_STATISTICS_ETHERNET */ From a169f581d3bbd82427a35b0eb2ea257d78d49bc0 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Sat, 9 Sep 2023 15:28:13 +0200 Subject: [PATCH 2580/4498] gpios: shields: Add definition for M5Stack M-Bus port This commit adds basic support for m5stacks M-Bus extenions port that is support my core and core2 module. Signed-off-by: Martin Kiepfer --- dts/bindings/gpio/m5stack,mbus-header.yaml | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 dts/bindings/gpio/m5stack,mbus-header.yaml diff --git a/dts/bindings/gpio/m5stack,mbus-header.yaml b/dts/bindings/gpio/m5stack,mbus-header.yaml new file mode 100644 index 00000000000..2ad85dd7a64 --- /dev/null +++ b/dts/bindings/gpio/m5stack,mbus-header.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2023 Martin Kiepfer +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on M5Stack M-Bus headers. + + This binding provides a nexus mapping for 30 pins as depicted below. + + 0 GND 1 ADC0 + 2 GND 3 ADC1 + 4 GND 5 RESET + 6 MOSI 7 DAC0 + 8 MISO 9 DAC1 + 10 SCK 11 3.3V + 12 RXD0 13 TXD0 + 14 RXD1 15 TXD1 + 16 intSDA 17 intSCL + 18 SDA 19 SCL + 20 GPIO 21 GPIO + 22 GPIO 23 GPIO + 24 NC 25 GPIO + 26 NC 27 5V + 28 NC 29 BAT + + +compatible: "m5stack,mbus-header" + +include: [gpio-nexus.yaml, base.yaml] From bc5f78d9baa34adbc57c8e7d3e09449bae835a18 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Sat, 16 Sep 2023 14:30:22 +0200 Subject: [PATCH 2581/4498] boards: m5stack_core2: Add support for mbus connector This commit adds basic support for the mbus connection port to m5stack_core2 board. Signed-off-by: Martin Kiepfer --- .../m5stack_core2/m5stack_core2-pinctrl.dtsi | 8 +++ boards/xtensa/m5stack_core2/m5stack_core2.dts | 1 + .../m5stack_mbus_connectors.dtsi | 49 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 boards/xtensa/m5stack_core2/m5stack_mbus_connectors.dtsi diff --git a/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi index dce82fde545..ac0908ac62a 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi +++ b/boards/xtensa/m5stack_core2/m5stack_core2-pinctrl.dtsi @@ -24,6 +24,14 @@ pinmux = ; }; + uart2_rx_gpio13: uart2_rx_gpio13 { + pinmux = ; + }; + + uart2_tx_gpio14: uart2_rx_gpio14 { + pinmux = ; + }; + uart1_tx_gpio32: uart1_tx_gpio32 { pinmux = ; }; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index f9417815330..5fb6f0cc495 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -8,6 +8,7 @@ #include #include "m5stack_core2-pinctrl.dtsi" #include "grove_connectors.dtsi" +#include "m5stack_mbus_connectors.dtsi" #include #include diff --git a/boards/xtensa/m5stack_core2/m5stack_mbus_connectors.dtsi b/boards/xtensa/m5stack_core2/m5stack_mbus_connectors.dtsi new file mode 100644 index 00000000000..9929b8dc879 --- /dev/null +++ b/boards/xtensa/m5stack_core2/m5stack_mbus_connectors.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Martin Kiepfer + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + m5stack_mbus_header: m5stack_mbus_connector { + compatible = "m5stack,mbus-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = /* 0 GND */ + <1 0 &gpio1 4 0>, /* ADC0 */ + /* 2 GND */ + <3 0 &gpio1 5 0>, /* ADC1 */ + /* 4 GND */ + /* 5 RESET */ + <6 0 &gpio0 23 0>, /* MOSI */ + <7 0 &gpio0 25 0>, /* DAC0 */ + <8 0 &gpio1 7 0>, /* MISO */ + <9 0 &gpio0 26 0>, /* DAC1 */ + <10 0 &gpio0 18 0>, /* SCK */ + /* 11 3.3V */ + <12 0 &gpio0 3 0>, /* RXD0 */ + <13 0 &gpio0 1 0>, /* TXD0 */ + <14 0 &gpio0 13 0>, /* RXD1 */ + <15 0 &gpio0 14 0>, /* TXD1 */ + <16 0 &gpio0 21 0>, /* intSDA */ + <17 0 &gpio0 22 0>, /* intSCL */ + <18 0 &gpio1 0 0>, /* SDA */ + <19 0 &gpio1 1 0>, /* SCL */ + <20 0 &gpio0 27 0>, /* GPIO */ + <21 0 &gpio0 19 0>, /* GPIO */ + <22 0 &gpio0 2 0>, /* GPIO */ + <23 0 &gpio0 0 0>, /* GPIO */ + /* 24 NC */ + <25 0 &gpio1 3 0>; /* GPIO */ + /* 26 NC */ + /* 27 5V */ + /* 28 NC */ + /* 29 BAT */ + }; +}; + +m5stack_mbus_i2c0: &i2c0 {}; +m5stack_mbus_i2c1: &i2c1 {}; +m5stack_mbus_uart0: &uart1 {}; +m5stack_mbus_uart1: &uart2 {}; +m5stack_mbus_spi: &spi3 {}; From aef1611e1f0cd798c909b2dfe5af9d6d0346ce1c Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Sat, 9 Sep 2023 15:45:26 +0200 Subject: [PATCH 2582/4498] sensors: mpu6050: Add support for variant mpu6886 This commit adds support for mpu6886, which has compatible register layout. Signed-off-by: Martin Kiepfer --- drivers/sensor/mpu6050/mpu6050.c | 2 +- drivers/sensor/mpu6050/mpu6050.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/sensor/mpu6050/mpu6050.c b/drivers/sensor/mpu6050/mpu6050.c index 34ce2d7d260..f00ca138c78 100644 --- a/drivers/sensor/mpu6050/mpu6050.c +++ b/drivers/sensor/mpu6050/mpu6050.c @@ -161,7 +161,7 @@ int mpu6050_init(const struct device *dev) return -EIO; } - if (id != MPU6050_CHIP_ID && id != MPU9250_CHIP_ID) { + if ((id != MPU6050_CHIP_ID) && (id != MPU9250_CHIP_ID) && (id != MPU6880_CHIP_ID)) { LOG_ERR("Invalid chip ID."); return -EINVAL; } diff --git a/drivers/sensor/mpu6050/mpu6050.h b/drivers/sensor/mpu6050/mpu6050.h index 305704a4596..0bc20a5c070 100644 --- a/drivers/sensor/mpu6050/mpu6050.h +++ b/drivers/sensor/mpu6050/mpu6050.h @@ -17,6 +17,7 @@ #define MPU6050_REG_CHIP_ID 0x75 #define MPU6050_CHIP_ID 0x68 #define MPU9250_CHIP_ID 0x71 +#define MPU6880_CHIP_ID 0x19 #define MPU6050_REG_GYRO_CFG 0x1B #define MPU6050_GYRO_FS_SHIFT 3 From 82b1df21cf2cbc085b7ad8fbff72dcd65ef10181 Mon Sep 17 00:00:00 2001 From: Martin Kiepfer Date: Tue, 5 Sep 2023 21:38:20 +0200 Subject: [PATCH 2583/4498] shields: Add support for M5Stack-Core2 base shield. M5Stack-Core2 comes with a base shield that is connected to the M5Stack extention connector. It features a MPU6886 6-axis motion tracker and a SPM1423 microphone. Signed-off-by: Martin Kiepfer --- .../shields/m5stack_core2_ext/Kconfig.shield | 5 ++ .../doc/img/m5stack_core2_ext.webp | Bin 0 -> 58022 bytes .../shields/m5stack_core2_ext/doc/index.rst | 56 ++++++++++++++++++ .../m5stack_core2_ext.overlay | 21 +++++++ boards/xtensa/m5stack_core2/doc/index.rst | 5 +- 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 boards/shields/m5stack_core2_ext/Kconfig.shield create mode 100644 boards/shields/m5stack_core2_ext/doc/img/m5stack_core2_ext.webp create mode 100644 boards/shields/m5stack_core2_ext/doc/index.rst create mode 100644 boards/shields/m5stack_core2_ext/m5stack_core2_ext.overlay diff --git a/boards/shields/m5stack_core2_ext/Kconfig.shield b/boards/shields/m5stack_core2_ext/Kconfig.shield new file mode 100644 index 00000000000..2710087cd1e --- /dev/null +++ b/boards/shields/m5stack_core2_ext/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Martin Kiepfer +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_M5STACK_CORE2_EXT + def_bool $(shields_list_contains,m5stack_core2_ext) diff --git a/boards/shields/m5stack_core2_ext/doc/img/m5stack_core2_ext.webp b/boards/shields/m5stack_core2_ext/doc/img/m5stack_core2_ext.webp new file mode 100644 index 0000000000000000000000000000000000000000..f0de7a3d5bf10557c823d3085020f6a3aa897e16 GIT binary patch literal 58022 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 + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + accel0 = &mpu6886_m5stack_core2_ext; + }; +}; + +&m5stack_mbus_i2c0 { + status = "okay"; + + mpu6886_m5stack_core2_ext: mbus_mpu6886@68 { + status = "okay"; + compatible = "invensense,mpu6050"; + reg = <0x68>; + }; +}; diff --git a/boards/xtensa/m5stack_core2/doc/index.rst b/boards/xtensa/m5stack_core2/doc/index.rst index 2a5c25f7deb..4ca27c546f5 100644 --- a/boards/xtensa/m5stack_core2/doc/index.rst +++ b/boards/xtensa/m5stack_core2/doc/index.rst @@ -72,8 +72,9 @@ of the M5Stack Core2 board. || LCD screen || Built-in LCD TFT display \(`LCD-ILI9342C`_, 2", 320x240 px\) | || || controlled via SPI interface | +------------------+--------------------------------------------------------------------------+ -|| 3-axis || The `MPU-6886`_ is a 6-axis MotionTracking device that combines a | -|| gyrosopce || 3-axis gyroscope and a 3-axis accelerometer. | +|| 6-axis IMU || The `MPU-6886`_ is a 6-axis motion tracker (6DOF IMU) device that | +|| MPU6886 || combines a 3-axis gyroscope and a 3-axis accelerometer. | +|| || For details please refer to :ref:`m5stack_core2_ext` | +------------------+--------------------------------------------------------------------------+ || Built-in || The `SPM-1423`_ I2S driven microphone. | || microphone || | From b9b3e91dba361396d1077499638392146b9e112e Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 11 May 2023 11:22:41 +0200 Subject: [PATCH 2584/4498] boards: nucleo_wba52cg: Enable flash and debug using OpenOCD OpenOCD can now be used to flash and debug nucleo_wba52cg. However, today, it requires use of recent upstream OpenOCD. Add instructions on how to proceed. Signed-off-by: Erwan Gouriou --- .../arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst | 44 +++++++++++++++++-- boards/arm/nucleo_wba52cg/support/openocd.cfg | 26 +++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 boards/arm/nucleo_wba52cg/support/openocd.cfg diff --git a/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst b/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst index 5f13e9fd0b8..db45d48a7fa 100644 --- a/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst +++ b/boards/arm/nucleo_wba52cg/doc/nucleo_wba52cg.rst @@ -222,12 +222,32 @@ Default settings are 115200 8N1. Programming and Debugging ************************* +Nucleo WBA52CG board includes an ST-LINK/V3 embedded debug tool interface. +It could be used for flash and debug using either OpenOCD or STM32Cube ecosystem tools. + +OpenOCD Support +=============== + +For now, openocd support is available only on upstream OpenOCD. You can check +`OpenOCD official Github mirror`_. +In order to use it, you should clone and compile it following usual README +guidelines. +Once it is done, you can set the OPENOCD and OPENOCD_DEFAULT_PATH variables in +:zephyr_file:`boards/arm/nucleo_wba52cg/board.cmake` to point the build +to the paths of the OpenOCD binary and its scripts, before +including the common openocd.board.cmake file: + + .. code-block:: none + + set(OPENOCD "/src/openocd" CACHE FILEPATH "" FORCE) + set(OPENOCD_DEFAULT_PATH /tcl) + include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + Flashing ======== -Nucleo WBA52CG board includes an ST-LINK/V3 embedded debug tool interface. -For now, only STM32CubeProgrammer is available for flashing. It is configured -as flashing tool by default. +STM32CubeProgrammer is configured as flashing tool by default. +If available OpenOCD could be used. Same process applies with both tools. Flashing an application to Nucleo WBA52CG ----------------------------------------- @@ -244,6 +264,21 @@ You will see the LED blinking every second. Debugging ========= +Debugging using OpenOCD +----------------------- + +You can debug an application in the usual way using OpenOCD. Here is an example for the +:zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_wba52cg + :maybe-skip-config: + :goals: debug + +Debugging using STM32CubeIDE +---------------------------- + You can debug an application using a STM32WBA compatible version of STM32CubeIDE. For that: - Create an empty STM32WBA project by going to File > New > STM32 project @@ -265,3 +300,6 @@ For that: .. _STM32WBA52CG reference manual: https://www.st.com/resource/en/reference_manual/rm0493-multiprotocol-wireless-bluetooth-lowenergy-armbased-32bit-mcu-stmicroelectronics.pdf + +.. _OpenOCD official Github mirror: + https://github.com/openocd-org/openocd/commit/870769b0ba9f4dae6ada9d8b1a40d75bd83aaa06 diff --git a/boards/arm/nucleo_wba52cg/support/openocd.cfg b/boards/arm/nucleo_wba52cg/support/openocd.cfg new file mode 100644 index 00000000000..10647e20ad8 --- /dev/null +++ b/boards/arm/nucleo_wba52cg/support/openocd.cfg @@ -0,0 +1,26 @@ +# Note: Using OpenOCD using nucloe_wba52cg requires using STMicroelectronics +# openocd fork. See board documentation for more information + +source [find interface/stlink-dap.cfg] + +set WORKAREASIZE 0x8000 + +transport select "dapdirect_swd" + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# STlink Debug clock frequency +set CLOCK_FREQ 8000 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +reset_config srst_only srst_nogate + +source [find target/stm32wbax.cfg] + +gdb_memory_map disable From 85fb82e1d655eb31893afc71a18c3d80c8b7ed3c Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 25 Sep 2023 16:19:42 +0200 Subject: [PATCH 2585/4498] drivers: stm32: Don't use pm_device_busy for configure During i2c_configure API execution, there is no way core can go in low power mode. Hence, call to pm_device_busy_set/get API is useless. Signed-off-by: Erwan Gouriou --- drivers/i2c/i2c_ll_stm32.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 0ee35f69134..b94234dd33a 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -74,8 +74,6 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) #ifdef CONFIG_PM_DEVICE_RUNTIME (void)pm_device_runtime_get(dev); -#else - pm_device_busy_set(dev); #endif LL_I2C_Disable(i2c); @@ -84,8 +82,6 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) #ifdef CONFIG_PM_DEVICE_RUNTIME (void)pm_device_runtime_put(dev); -#else - pm_device_busy_clear(dev); #endif k_sem_give(&data->bus_mutex); From b6fa34f1d3adc090d0913ace56a81d8438209c37 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 25 Sep 2023 16:29:47 +0200 Subject: [PATCH 2586/4498] drivers: i2c: stm32: Simplify device init pm_device_runtime_enable() will call i2c_stm32_suspend() if pm_device_init_suspended() isn't called. Since the aim is to perform suspension, just need to call pm_device_runtime_enable(). Signed-off-by: Erwan Gouriou --- drivers/i2c/i2c_ll_stm32.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index b94234dd33a..81374c66199 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -387,8 +387,6 @@ static int i2c_stm32_init(const struct device *dev) } #ifdef CONFIG_PM_DEVICE_RUNTIME - i2c_stm32_suspend(dev); - pm_device_init_suspended(dev); (void)pm_device_runtime_enable(dev); #endif From c2715b1fa56bdc4ceb83f80621c01e4527b4b618 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 25 Sep 2023 16:44:55 +0200 Subject: [PATCH 2587/4498] drivers: i2c: stm32: Don't abuse of pm_device_runtime_get/put In driver runtime configuration function, calling calling pm_device_runtime_get/put() will have the effect of performing pinctrl change from sleep to default and back from default to sleep which is useless and in turn enables and disables GPIO clocks two times. Stop this crazyness and purely enable/disable clock, which might be superfluous in some cases but which remains much more reasonable than than the previous implementation. Signed-off-by: Erwan Gouriou --- drivers/i2c/i2c_ll_stm32.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 81374c66199..791c84fcb9e 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -73,7 +73,11 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) k_sem_take(&data->bus_mutex, K_FOREVER); #ifdef CONFIG_PM_DEVICE_RUNTIME - (void)pm_device_runtime_get(dev); + ret = clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken[0]); + if (ret < 0) { + LOG_ERR("failure Enabling I2C clock"); + return ret; + } #endif LL_I2C_Disable(i2c); @@ -81,7 +85,11 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) ret = stm32_i2c_configure_timing(dev, clock); #ifdef CONFIG_PM_DEVICE_RUNTIME - (void)pm_device_runtime_put(dev); + ret = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken[0]); + if (ret < 0) { + LOG_ERR("failure disabling I2C clock"); + return ret; + } #endif k_sem_give(&data->bus_mutex); From 3d4208d19114f0fe5b7f13f1a0ca482f0c622ecf Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Mon, 2 Oct 2023 09:40:48 +0100 Subject: [PATCH 2588/4498] boards/arm/stm32h735g_disco: Enable L2 Ethernet The stm32h735g_disco board support Ethernet but the L2 Ethernet driver was not being enabled. The L2 Ethernet driver is now enabled along with Networking. Signed-off-by: Ben Marsh --- boards/arm/stm32h735g_disco/Kconfig.defconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/stm32h735g_disco/Kconfig.defconfig b/boards/arm/stm32h735g_disco/Kconfig.defconfig index 42de4573d83..72308958d7b 100644 --- a/boards/arm/stm32h735g_disco/Kconfig.defconfig +++ b/boards/arm/stm32h735g_disco/Kconfig.defconfig @@ -8,6 +8,13 @@ if BOARD_STM32H735G_DISCO config BOARD default "stm32h735g_disco" +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + config SPI_STM32_INTERRUPT default y depends on SPI From 40a0d3c1a2f98d29842e0b00feeb2ebf78323346 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 5 Oct 2023 11:21:07 +0200 Subject: [PATCH 2589/4498] boards: stm32 boards with LPTIM node has CONFIG_STM32_LPTIM_CLOCK defined Define the CONFIG_STM32_LPTIM_CLOCK_LSE when the board DTS has STM32_SRC_LSE has lptim clock source. CONFIG_STM32_LPTIM_CLOCK_LSI is defined by default. The CONFIG_SYS_CLOCK_TICKS_PER_SEC is set by soc/arm/st_stm32/common/ Kconfig.defconfig.series. Signed-off-by: Francois Ramu --- boards/arm/b_u585i_iot02a/Kconfig.defconfig | 4 ---- boards/arm/b_u585i_iot02a/b_u585i_iot02a_defconfig | 3 +++ boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns_defconfig | 3 +++ boards/arm/disco_l475_iot1/Kconfig.defconfig | 4 ---- boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig | 3 +++ boards/arm/nucleo_g431rb/Kconfig.defconfig | 4 ---- boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig | 3 +++ boards/arm/nucleo_l073rz/Kconfig.defconfig | 4 ---- boards/arm/nucleo_wb55rg/Kconfig.defconfig | 4 ---- boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig | 3 +++ boards/arm/nucleo_wba52cg/Kconfig.defconfig | 4 ---- boards/arm/nucleo_wba52cg/nucleo_wba52cg_defconfig | 3 +++ boards/arm/nucleo_wl55jc/Kconfig.defconfig | 3 --- boards/arm/stm32l562e_dk/Kconfig.defconfig | 4 ---- boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig | 3 +++ boards/arm/stm32l562e_dk/stm32l562e_dk_ns_defconfig | 3 +++ 16 files changed, 24 insertions(+), 31 deletions(-) diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index 93748d0dcf2..ae1e57aba8e 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -16,8 +16,4 @@ config SPI_STM32_INTERRUPT config USE_DT_CODE_PARTITION default y if TRUSTED_EXECUTION_NONSECURE -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - endif # BOARD_B_U585I_IOT02A diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_defconfig b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_defconfig index c034f717771..d84deca3fe0 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_defconfig +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_defconfig @@ -18,3 +18,6 @@ CONFIG_UART_CONSOLE=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns_defconfig b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns_defconfig index 4b6f6ba7f5c..473e6e2fbb0 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns_defconfig +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a_ns_defconfig @@ -22,3 +22,6 @@ CONFIG_PINCTRL=y CONFIG_ARM_TRUSTZONE_M=y CONFIG_RUNTIME_NMI=y CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/disco_l475_iot1/Kconfig.defconfig b/boards/arm/disco_l475_iot1/Kconfig.defconfig index 8bf75fa6f7c..847c9ec0878 100644 --- a/boards/arm/disco_l475_iot1/Kconfig.defconfig +++ b/boards/arm/disco_l475_iot1/Kconfig.defconfig @@ -8,10 +8,6 @@ if BOARD_DISCO_L475_IOT1 config BOARD default "disco_l475_iot1" -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - config SPI_STM32_INTERRUPT default y depends on SPI diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig index a25b1eff645..072929abda8 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig @@ -26,3 +26,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/nucleo_g431rb/Kconfig.defconfig b/boards/arm/nucleo_g431rb/Kconfig.defconfig index 993bee2f796..62c8e061965 100644 --- a/boards/arm/nucleo_g431rb/Kconfig.defconfig +++ b/boards/arm/nucleo_g431rb/Kconfig.defconfig @@ -12,8 +12,4 @@ config SPI_STM32_INTERRUPT default y depends on SPI -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - endif # BOARD_NUCLEO_G431RB diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig b/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig index 92c2363d2d8..25dcaf3dfb7 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig @@ -24,3 +24,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/nucleo_l073rz/Kconfig.defconfig b/boards/arm/nucleo_l073rz/Kconfig.defconfig index 66c2d366181..6a73209134a 100644 --- a/boards/arm/nucleo_l073rz/Kconfig.defconfig +++ b/boards/arm/nucleo_l073rz/Kconfig.defconfig @@ -12,8 +12,4 @@ config SPI_STM32_INTERRUPT default y depends on SPI -# LPTIM clocked by LSI, force tick freq to 4000 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4000 if STM32_LPTIM_TIMER - endif # BOARD_NUCLEO_L073RZ diff --git a/boards/arm/nucleo_wb55rg/Kconfig.defconfig b/boards/arm/nucleo_wb55rg/Kconfig.defconfig index 1a7ffcff0ef..66c77220d3a 100644 --- a/boards/arm/nucleo_wb55rg/Kconfig.defconfig +++ b/boards/arm/nucleo_wb55rg/Kconfig.defconfig @@ -13,8 +13,4 @@ choice BT_HCI_BUS_TYPE depends on BT endchoice -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - endif # BOARD_NUCLEO_WB55RG diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig b/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig index 9fdd732848e..88f9da2ff18 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig @@ -22,3 +22,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/nucleo_wba52cg/Kconfig.defconfig b/boards/arm/nucleo_wba52cg/Kconfig.defconfig index 36f0e77818b..dfdac1bba98 100644 --- a/boards/arm/nucleo_wba52cg/Kconfig.defconfig +++ b/boards/arm/nucleo_wba52cg/Kconfig.defconfig @@ -13,8 +13,4 @@ config SPI_STM32_INTERRUPT default y depends on SPI -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - endif # BOARD_NUCLEO_WBA52CG diff --git a/boards/arm/nucleo_wba52cg/nucleo_wba52cg_defconfig b/boards/arm/nucleo_wba52cg/nucleo_wba52cg_defconfig index 9b917b0fc69..ffadf13e845 100644 --- a/boards/arm/nucleo_wba52cg/nucleo_wba52cg_defconfig +++ b/boards/arm/nucleo_wba52cg/nucleo_wba52cg_defconfig @@ -24,3 +24,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/nucleo_wl55jc/Kconfig.defconfig b/boards/arm/nucleo_wl55jc/Kconfig.defconfig index 197453cc03e..981e20f0306 100644 --- a/boards/arm/nucleo_wl55jc/Kconfig.defconfig +++ b/boards/arm/nucleo_wl55jc/Kconfig.defconfig @@ -8,7 +8,4 @@ if BOARD_NUCLEO_WL55JC config BOARD default "nucleo_wl55jc" -config SYS_CLOCK_TICKS_PER_SEC - default 4000 if STM32_LPTIM_TIMER - endif # BOARD_NUCLEO_WL55JC diff --git a/boards/arm/stm32l562e_dk/Kconfig.defconfig b/boards/arm/stm32l562e_dk/Kconfig.defconfig index 1fe37f3e0a4..bec20b338f5 100644 --- a/boards/arm/stm32l562e_dk/Kconfig.defconfig +++ b/boards/arm/stm32l562e_dk/Kconfig.defconfig @@ -8,10 +8,6 @@ if BOARD_STM32L562E_DK config BOARD default "stm32l562e_dk" -# LPTIM clocked by LSE, force tick freq to 4096 for tick accuracy -config SYS_CLOCK_TICKS_PER_SEC - default 4096 if STM32_LPTIM_TIMER - if BT config SPI diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig b/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig index 6646832e7ef..c5537972912 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig @@ -24,3 +24,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_ns_defconfig b/boards/arm/stm32l562e_dk/stm32l562e_dk_ns_defconfig index c28424d306a..289f8d82131 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk_ns_defconfig +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_ns_defconfig @@ -25,3 +25,6 @@ CONFIG_TRUSTED_EXECUTION_NONSECURE=y # enable pin controller CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y From aa08d5cc5c7d7a89b9de5a4d8e36d73bd4850c58 Mon Sep 17 00:00:00 2001 From: Michael Arnold Date: Wed, 8 Feb 2023 08:17:20 +0000 Subject: [PATCH 2590/4498] arch: Enable ramfunc support for other arch than arm long_call is not supported on risc-v. Enable long_call only on supported arm architecture. Signed-off-by: Michael Arnold --- include/zephyr/toolchain/gcc.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index a0e325cfa28..a15e8c0a580 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -200,8 +200,13 @@ do { \ #if !defined(CONFIG_XIP) #define __ramfunc #elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) +#if defined(CONFIG_ARM) #define __ramfunc __attribute__((noinline)) \ __attribute__((long_call, section(".ramfunc"))) +#else +#define __ramfunc __attribute__((noinline)) \ + __attribute__((section(".ramfunc"))) +#endif #endif /* !CONFIG_XIP */ #ifndef __fallthrough From f67c11cb2a2d94d1c8e178814ea6a7cb87496405 Mon Sep 17 00:00:00 2001 From: Michael Arnold Date: Mon, 23 Oct 2023 10:21:06 +0200 Subject: [PATCH 2591/4498] tests: arch: Move ramfunc test from arm specific to common The feature ramfunc is generic and can be reused for other architectures. Signed-off-by: Michael Arnold --- tests/arch/{arm/arm_ramfunc => common/ramfunc}/CMakeLists.txt | 0 tests/arch/{arm/arm_ramfunc => common/ramfunc}/README.txt | 0 .../ramfunc}/boards/arty_a7_arm_designstart_m1.overlay | 0 tests/arch/{arm/arm_ramfunc => common/ramfunc}/prj.conf | 0 tests/arch/{arm/arm_ramfunc => common/ramfunc}/src/arm_ramfunc.c | 0 tests/arch/{arm/arm_ramfunc => common/ramfunc}/src/main.c | 0 tests/arch/{arm/arm_ramfunc => common/ramfunc}/testcase.yaml | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/CMakeLists.txt (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/README.txt (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/boards/arty_a7_arm_designstart_m1.overlay (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/prj.conf (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/src/arm_ramfunc.c (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/src/main.c (100%) rename tests/arch/{arm/arm_ramfunc => common/ramfunc}/testcase.yaml (100%) diff --git a/tests/arch/arm/arm_ramfunc/CMakeLists.txt b/tests/arch/common/ramfunc/CMakeLists.txt similarity index 100% rename from tests/arch/arm/arm_ramfunc/CMakeLists.txt rename to tests/arch/common/ramfunc/CMakeLists.txt diff --git a/tests/arch/arm/arm_ramfunc/README.txt b/tests/arch/common/ramfunc/README.txt similarity index 100% rename from tests/arch/arm/arm_ramfunc/README.txt rename to tests/arch/common/ramfunc/README.txt diff --git a/tests/arch/arm/arm_ramfunc/boards/arty_a7_arm_designstart_m1.overlay b/tests/arch/common/ramfunc/boards/arty_a7_arm_designstart_m1.overlay similarity index 100% rename from tests/arch/arm/arm_ramfunc/boards/arty_a7_arm_designstart_m1.overlay rename to tests/arch/common/ramfunc/boards/arty_a7_arm_designstart_m1.overlay diff --git a/tests/arch/arm/arm_ramfunc/prj.conf b/tests/arch/common/ramfunc/prj.conf similarity index 100% rename from tests/arch/arm/arm_ramfunc/prj.conf rename to tests/arch/common/ramfunc/prj.conf diff --git a/tests/arch/arm/arm_ramfunc/src/arm_ramfunc.c b/tests/arch/common/ramfunc/src/arm_ramfunc.c similarity index 100% rename from tests/arch/arm/arm_ramfunc/src/arm_ramfunc.c rename to tests/arch/common/ramfunc/src/arm_ramfunc.c diff --git a/tests/arch/arm/arm_ramfunc/src/main.c b/tests/arch/common/ramfunc/src/main.c similarity index 100% rename from tests/arch/arm/arm_ramfunc/src/main.c rename to tests/arch/common/ramfunc/src/main.c diff --git a/tests/arch/arm/arm_ramfunc/testcase.yaml b/tests/arch/common/ramfunc/testcase.yaml similarity index 100% rename from tests/arch/arm/arm_ramfunc/testcase.yaml rename to tests/arch/common/ramfunc/testcase.yaml From 9e4a403d213b67905536a7939b993b8779bbc319 Mon Sep 17 00:00:00 2001 From: Michael Arnold Date: Mon, 23 Oct 2023 11:17:10 +0200 Subject: [PATCH 2592/4498] tests: arch: Make ramfunc test generic and enable test for riscv arch The ramfunc test can be reused for multiple architectures. Signed-off-by: Michael Arnold --- tests/arch/common/ramfunc/CMakeLists.txt | 2 +- tests/arch/common/ramfunc/README.txt | 26 ++++++++++++------- tests/arch/common/ramfunc/src/main.c | 10 +++---- .../ramfunc/src/{arm_ramfunc.c => ramfunc.c} | 18 ++++++------- tests/arch/common/ramfunc/testcase.yaml | 7 +++-- 5 files changed, 37 insertions(+), 26 deletions(-) rename tests/arch/common/ramfunc/src/{arm_ramfunc.c => ramfunc.c} (73%) diff --git a/tests/arch/common/ramfunc/CMakeLists.txt b/tests/arch/common/ramfunc/CMakeLists.txt index 8aa6ed15e73..972d08e7e75 100644 --- a/tests/arch/common/ramfunc/CMakeLists.txt +++ b/tests/arch/common/ramfunc/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(arm_zero_latency_irqs) +project(zero_latency_irqs) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) diff --git a/tests/arch/common/ramfunc/README.txt b/tests/arch/common/ramfunc/README.txt index ba68130faf8..f5f2b7949f1 100644 --- a/tests/arch/common/ramfunc/README.txt +++ b/tests/arch/common/ramfunc/README.txt @@ -1,12 +1,12 @@ -Title: Test to verify code execution from SRAM for XIP images (ARM Only) +Title: Test to verify code execution from SRAM for XIP images (only on supported architectures with CONFIG_ARCH_HAS_RAMFUNC_SUPPORT=y) Description: This test verifies that we can define functions in SRAM (and -successfully execute them from SRAM) in ARM XIP images. It +successfully execute them from SRAM) in XIP images. It also verifies that the .ramfunc section is accessible by -nPRIV code when building with support for user mode -(CONFIG_TEST_USERSPACE=y). Only for ARM Cortex-M targets. +user space code when building with support for user mode +(CONFIG_TEST_USERSPACE=y). --------------------------------------------------------------------------- @@ -34,12 +34,20 @@ or Sample Output: -***** Booting Zephyr OS build zephyr-v1.14.0-1726-gb95a71960622 ***** -Running test suite arm_ramfunc +*** Booting Zephyr OS build zephyr-v3.4.0-4114-gadfd4017979f *** +Running TESTSUITE ramfunc =================================================================== -starting test - test_arm_ramfunc -PASS - test_arm_ramfunc +START - test_ramfunc + PASS - test_ramfunc in 0.229 seconds =================================================================== -Test suite arm_ramfunc succeeded +TESTSUITE ramfunc succeeded + +------ TESTSUITE SUMMARY START ------ + +SUITE PASS - 100.00% [ramfunc]: pass = 1, fail = 0, skip = 0, total = 1 duration = 0.229 seconds + - PASS - [ramfunc.test_ramfunc] duration = 0.229 seconds + +------ TESTSUITE SUMMARY END ------ + =================================================================== PROJECT EXECUTION SUCCESSFUL diff --git a/tests/arch/common/ramfunc/src/main.c b/tests/arch/common/ramfunc/src/main.c index a75dc004b7e..f136c3ba992 100644 --- a/tests/arch/common/ramfunc/src/main.c +++ b/tests/arch/common/ramfunc/src/main.c @@ -4,10 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if !defined(CONFIG_CPU_CORTEX_M) - #error test can only run on Cortex-M MCUs -#endif - #include -ZTEST_SUITE(arm_ramfunc, NULL, NULL, NULL, NULL, NULL); +#if !defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) + #error test can only run on Cortex-M MCUs and RISC-V +#endif + +ZTEST_SUITE(ramfunc, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/common/ramfunc/src/arm_ramfunc.c b/tests/arch/common/ramfunc/src/ramfunc.c similarity index 73% rename from tests/arch/common/ramfunc/src/arm_ramfunc.c rename to tests/arch/common/ramfunc/src/ramfunc.c index 10790b556d0..7f7bb28c0ce 100644 --- a/tests/arch/common/ramfunc/src/arm_ramfunc.c +++ b/tests/arch/common/ramfunc/src/ramfunc.c @@ -10,12 +10,12 @@ static volatile int test_flag; -__ramfunc static void arm_ram_function(void) +__ramfunc static void ram_function(void) { test_flag = 1; } -ZTEST(arm_ramfunc, test_arm_ramfunc) +ZTEST(ramfunc, test_ramfunc) { int init_flag, post_flag; @@ -23,7 +23,7 @@ ZTEST(arm_ramfunc, test_arm_ramfunc) zassert_true(init_flag == 0, "Test flag not initialized to zero"); /* Verify that the .ramfunc section is not empty, it is located - * inside SRAM, and that arm_ram_function(.) is located inside + * inside SRAM, and that ram_function(.) is located inside * the .ramfunc section. */ zassert_true((uint32_t)&__ramfunc_size != 0, @@ -32,12 +32,12 @@ ZTEST(arm_ramfunc, test_arm_ramfunc) && ((uint32_t)&__ramfunc_end < (uint32_t)&_image_ram_end), ".ramfunc linker section not in RAM"); zassert_true( - (((uint32_t)&__ramfunc_start) <= (uint32_t)arm_ram_function) && - (((uint32_t)&__ramfunc_end) > (uint32_t)arm_ram_function), - "arm_ram_function not loaded into .ramfunc"); + (((uint32_t)&__ramfunc_start) <= (uint32_t)ram_function) && + (((uint32_t)&__ramfunc_end) > (uint32_t)ram_function), + "ram_function not loaded into .ramfunc"); /* If we build with User Mode support, verify that the - * arm_ram_function(.) is user (read) accessible. + * ram_function(.) is user (read) accessible. */ #if defined(CONFIG_USERSPACE) zassert_true(arch_buffer_validate((void *)&__ramfunc_start, @@ -46,12 +46,12 @@ ZTEST(arm_ramfunc, test_arm_ramfunc) #endif /* CONFIG_USERSPACE */ /* Execute the function from SRAM. */ - arm_ram_function(); + ram_function(); /* Verify that the function is executed successfully. */ post_flag = test_flag; zassert_true(post_flag == 1, - "arm_ram_function() execution failed."); + "ram_function() execution failed."); } /** * @} diff --git a/tests/arch/common/ramfunc/testcase.yaml b/tests/arch/common/ramfunc/testcase.yaml index 49e97deaf58..542926dc21b 100644 --- a/tests/arch/common/ramfunc/testcase.yaml +++ b/tests/arch/common/ramfunc/testcase.yaml @@ -1,9 +1,12 @@ tests: - arch.arm.ramfunc: + arch.common.ramfunc: filter: CONFIG_ARCH_HAS_RAMFUNC_SUPPORT tags: - arm - userspace - arch_allow: arm + arch_allow: + - arm + - riscv32 + - riscv64 extra_configs: - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=0 From 973e226bfd467cc791de018457378a1ce1c6e263 Mon Sep 17 00:00:00 2001 From: Michael Arnold Date: Mon, 23 Oct 2023 10:33:44 +0200 Subject: [PATCH 2593/4498] arch: Enable ramfunc feature on RISC-V PRIVILEGE SOC family Allow to place functions in ram. Signed-off-by: Michael Arnold --- soc/riscv/riscv-privileged/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/riscv/riscv-privileged/Kconfig b/soc/riscv/riscv-privileged/Kconfig index f94eabd96a7..abbeeac242b 100644 --- a/soc/riscv/riscv-privileged/Kconfig +++ b/soc/riscv/riscv-privileged/Kconfig @@ -10,6 +10,7 @@ config SOC_FAMILY_RISCV_PRIVILEGE config SOC_FAMILY_RISCV_PRIVILEGED bool + select ARCH_HAS_RAMFUNC_SUPPORT if XIP config SOC_FAMILY string From 34058146a52f44c74320b54a2d7a082e10b83801 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 24 Oct 2023 13:59:36 +0200 Subject: [PATCH 2594/4498] Bluetooth: BAP: Shell: Remove unused variable stream_frame_duration_us The variable was unsused and caused compiler warnings. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/bap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index aa6561f6795..b83237f9798 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -2617,7 +2617,6 @@ static int cmd_send(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_LIBLC3) static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream) { - int stream_frame_duration_us; struct bt_bap_ep_info info; int err; From cf513451eb160cc141ba306e308fb4ec1f521715 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 24 Oct 2023 15:34:51 +0300 Subject: [PATCH 2595/4498] net: lwm2m: Keep user_data between blocks CoAP reply structure user_data should be kept between ongoing blocks, so that callbacks for LwM2M send continue to work on blockwise transfers. Fixes #64290 Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index a7d4492b981..ed5f28aabdb 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -304,6 +304,9 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu } msg->cpkt.hdr_len = msg->body_encode_buffer.hdr_len; } else { + /* Keep user data between blocks */ + void *user_data = msg->reply ? msg->reply->user_data : NULL; + /* reuse message for next block. Copy token from the new query to allow * CoAP clients to use new token for every query of ongoing transaction */ @@ -323,6 +326,9 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu LOG_ERR("Unable to init lwm2m message for next block!"); return ret; } + if (msg->reply) { + msg->reply->user_data = user_data; + } } /* copy the options */ From e364f29bffdfb122fead4b7dad082428f2f6969c Mon Sep 17 00:00:00 2001 From: Georgij Cernysiov Date: Wed, 25 Oct 2023 09:15:10 +0200 Subject: [PATCH 2596/4498] drivers: ethernet: fix adin set_config Corrects set_config to allow MAC config at runtime. * Add missing device lock * Use correct mac argument Signed-off-by: Georgij Cernysiov --- drivers/ethernet/eth_adin2111.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index e7cdcedc0c6..3ee08f30b75 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -696,19 +696,23 @@ static int adin2111_port_set_config(const struct device *dev, const struct device *adin = cfg->adin; int ret = -ENOTSUP; + (void)eth_adin2111_lock(dev, K_FOREVER); + if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { - ret = adin2111_filter_unicast(adin, data->mac_addr, cfg->port_idx); + ret = adin2111_filter_unicast(adin, (uint8_t *)&config->mac_address.addr[0], + cfg->port_idx); if (ret < 0) { - return ret; + goto end_unlock; } - memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr)); + (void)memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr)); - net_if_set_link_addr(data->iface, data->mac_addr, - sizeof(data->mac_addr), - NET_LINK_ETHERNET); + (void)net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr), + NET_LINK_ETHERNET); } +end_unlock: + (void)eth_adin2111_unlock(dev); return ret; } From 467ce8945823b351b97b00aba32aa5d88013b5cf Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 24 Oct 2023 11:44:05 -0400 Subject: [PATCH 2597/4498] cmsis: resolve undefined reference to k_calloc() When no heap has been configured, osMessageQueueNew() will no longer include a call to k_calloc() (which needs the heap). In such a configuration, if osMessageQueueNew() indicates that the buffer must be allocated, it will fail and return NULL. Fixes #61196 Signed-off-by: Peter Mitsis --- subsys/portability/cmsis_rtos_v2/msgq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/portability/cmsis_rtos_v2/msgq.c b/subsys/portability/cmsis_rtos_v2/msgq.c index 05103f35539..d23a5569031 100644 --- a/subsys/portability/cmsis_rtos_v2/msgq.c +++ b/subsys/portability/cmsis_rtos_v2/msgq.c @@ -55,12 +55,17 @@ osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, CONFIG_CMSIS_V2_MSGQ_MAX_DYNAMIC_SIZE, "message queue size exceeds dynamic maximum"); +#if (CONFIG_HEAP_MEM_POOL_SIZE > 0) msgq->pool = k_calloc(msg_count, msg_size); if (msgq->pool == NULL) { k_mem_slab_free(&cv2_msgq_slab, (void *)msgq); return NULL; } msgq->is_dynamic_allocation = TRUE; +#else + k_mem_slab_free(&cv2_msgq_slab, (void *)msgq); + return NULL; +#endif } else { msgq->pool = attr->mq_mem; msgq->is_dynamic_allocation = FALSE; From c35d024b8d4b818e9bf09aee2afc7fa3caa4a0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:35 +0700 Subject: [PATCH 2598/4498] west: core: add search path argument to require() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow the runners to override the default search path, e.g. when provided through command line. The default is to search for the program binary on the system PATH. This is useful when the runner allows to optionally override the search path of the tool, in the case there are multiple versions or installations, and not necessarily the tools path are present in the system PATH environment variable. For example: `tool = self.require(tool_name, path=args.tool_path_override)` Signed-off-by: Manuel Argüelles --- scripts/west_commands/runners/core.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index fa697fa66cf..fd21af0db5e 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -658,19 +658,21 @@ def tool_opt_help(cls) -> str: in the order they appear on the command line.''' @staticmethod - def require(program: str) -> str: + def require(program: str, path: Optional[str] = None) -> str: '''Require that a program is installed before proceeding. :param program: name of the program that is required, or path to a program binary. + :param path: PATH where to search for the program binary. + By default check on the system PATH. If ``program`` is an absolute path to an existing program binary, this call succeeds. Otherwise, try to find the program - by name on the system PATH. + by name on the system PATH or in the given PATH, if provided. If the program can be found, its path is returned. Otherwise, raises MissingProgram.''' - ret = shutil.which(program) + ret = shutil.which(program, path=path) if ret is None: raise MissingProgram(program) return ret From 1bc53ff84d2647793c04f14ff108d7eca27ed7f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:42 +0700 Subject: [PATCH 2599/4498] west: core: allow to pass keywords args to server and client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow the runners to pass extra keywords arguments to both the server and client subprocesses calls, as can be useful for instance to set a specific execution environment. ZephyrBinaryRunner.check_call() already supports passing kwargs to the inner subprocess call but this is currently not possible when starting server/client processes. So pass through the kwargs to each of the client/server subprocess calls. Signed-off-by: Manuel Argüelles --- scripts/west_commands/runners/core.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index fd21af0db5e..9b3ca51d900 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -677,7 +677,7 @@ def require(program: str, path: Optional[str] = None) -> str: raise MissingProgram(program) return ret - def run_server_and_client(self, server, client): + def run_server_and_client(self, server, client, **kwargs): '''Run a server that ignores SIGINT, and a client that handles it. This routine portably: @@ -686,20 +686,22 @@ def run_server_and_client(self, server, client): SIGINT - runs ``client`` in a subprocess while temporarily ignoring SIGINT - cleans up the server after the client exits. + - the keyword arguments, if any, will be passed down to both server and + client subprocess calls It's useful to e.g. open a GDB server and client.''' - server_proc = self.popen_ignore_int(server) + server_proc = self.popen_ignore_int(server, **kwargs) try: - self.run_client(client) + self.run_client(client, **kwargs) finally: server_proc.terminate() server_proc.wait() - def run_client(self, client): + def run_client(self, client, **kwargs): '''Run a client that handles SIGINT.''' previous = signal.signal(signal.SIGINT, signal.SIG_IGN) try: - self.check_call(client) + self.check_call(client, **kwargs) finally: signal.signal(signal.SIGINT, previous) From e938a5a31a9e71da83fda7ff5c4febe2c7134001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:46 +0700 Subject: [PATCH 2600/4498] west: add NXP S32 Debug Probe runner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NXP S32 Debug Probe is a JTAG-based probe that enables debugging on NXP S32 devices. This probe is designed to work in conjunction with NXP S32 Design Studio and this runner offers a wrapper to launch a debug session from cli. `flash` command is not implemented at the moment because presently there are no zephyr boards that can make use of it and test it. Signed-off-by: Manuel Argüelles --- boards/common/nxp_s32dbg.board.cmake | 6 + scripts/west_commands/runners/__init__.py | 1 + scripts/west_commands/runners/nxp_s32dbg.py | 334 ++++++++++++++++++++ scripts/west_commands/tests/test_imports.py | 1 + 4 files changed, 342 insertions(+) create mode 100644 boards/common/nxp_s32dbg.board.cmake create mode 100644 scripts/west_commands/runners/nxp_s32dbg.py diff --git a/boards/common/nxp_s32dbg.board.cmake b/boards/common/nxp_s32dbg.board.cmake new file mode 100644 index 00000000000..edd49ea305f --- /dev/null +++ b/boards/common/nxp_s32dbg.board.cmake @@ -0,0 +1,6 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(nxp_s32dbg) +board_set_debugger_ifnset(nxp_s32dbg) +board_finalize_runner_args(nxp_s32dbg) diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index f4340bc19b0..850efcd5668 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -45,6 +45,7 @@ def _import_runner_module(runner_name): 'nrfjprog', 'nrfutil', 'nsim', + 'nxp_s32dbg', 'openocd', 'pyocd', 'qemu', diff --git a/scripts/west_commands/runners/nxp_s32dbg.py b/scripts/west_commands/runners/nxp_s32dbg.py new file mode 100644 index 00000000000..e2065f3980f --- /dev/null +++ b/scripts/west_commands/runners/nxp_s32dbg.py @@ -0,0 +1,334 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 +""" +Runner for NXP S32 Debug Probe. +""" + +import argparse +import os +import platform +import re +import shlex +import subprocess +import sys +import tempfile +from dataclasses import dataclass +from pathlib import Path +from typing import Dict, List, Optional, Union + +from runners.core import (BuildConfiguration, RunnerCaps, RunnerConfig, + ZephyrBinaryRunner) + +NXP_S32DBG_USB_CLASS = 'NXP Probes' +NXP_S32DBG_USB_VID = 0x15a2 +NXP_S32DBG_USB_PID = 0x0067 + + +@dataclass +class NXPS32DebugProbeConfig: + """NXP S32 Debug Probe configuration parameters.""" + conn_str: str = 's32dbg' + server_port: int = 45000 + speed: int = 16000 + remote_timeout: int = 30 + reset_type: Optional[str] = 'default' + reset_delay: int = 0 + + +class NXPS32DebugProbeRunner(ZephyrBinaryRunner): + """Runner front-end for NXP S32 Debug Probe.""" + + def __init__(self, + runner_cfg: RunnerConfig, + probe_cfg: NXPS32DebugProbeConfig, + core_name: str, + soc_name: str, + soc_family_name: str, + start_all_cores: bool, + s32ds_path: Optional[str] = None, + tool_opt: Optional[List[str]] = None) -> None: + super(NXPS32DebugProbeRunner, self).__init__(runner_cfg) + self.elf_file: str = runner_cfg.elf_file or '' + self.probe_cfg: NXPS32DebugProbeConfig = probe_cfg + self.core_name: str = core_name + self.soc_name: str = soc_name + self.soc_family_name: str = soc_family_name + self.start_all_cores: bool = start_all_cores + self.s32ds_path_override: Optional[str] = s32ds_path + + self.tool_opt: List[str] = [] + if tool_opt: + for opt in tool_opt: + self.tool_opt.extend(shlex.split(opt)) + + build_cfg = BuildConfiguration(runner_cfg.build_dir) + self.arch = build_cfg.get('CONFIG_ARCH').replace('"', '') + + @classmethod + def name(cls) -> str: + return 'nxp_s32dbg' + + @classmethod + def capabilities(cls) -> RunnerCaps: + return RunnerCaps(commands={'debug', 'debugserver', 'attach'}, + dev_id=True, tool_opt=True) + + @classmethod + def dev_id_help(cls) -> str: + return '''Debug probe connection string as in "s32dbg[:

]" + where
can be the IP address if TAP is available via Ethernet, + the serial ID of the probe or empty if TAP is available via USB.''' + + @classmethod + def tool_opt_help(cls) -> str: + return '''Additional options for GDB client when used with "debug" or "attach" commands + or for GTA server when used with "debugserver" command.''' + + @classmethod + def do_add_parser(cls, parser: argparse.ArgumentParser) -> None: + parser.add_argument('--core-name', + required=True, + help='Core name as supported by the debug probe (e.g. "R52_0_0")') + parser.add_argument('--soc-name', + required=True, + help='SoC name as supported by the debug probe (e.g. "S32Z270")') + parser.add_argument('--soc-family-name', + required=True, + help='SoC family name as supported by the debug probe (e.g. "s32z2e2")') + parser.add_argument('--start-all-cores', + action='store_true', + help='Start all SoC cores and not just the one being debugged. ' + 'Use together with "debug" command.') + parser.add_argument('--s32ds-path', + help='Override the path to NXP S32 Design Studio installation. ' + 'By default, this runner will try to obtain it from the system ' + 'path, if available.') + parser.add_argument('--server-port', + default=NXPS32DebugProbeConfig.server_port, + type=int, + help='GTA server port') + parser.add_argument('--speed', + default=NXPS32DebugProbeConfig.speed, + type=int, + help='JTAG interface speed') + parser.add_argument('--remote-timeout', + default=NXPS32DebugProbeConfig.remote_timeout, + type=int, + help='Number of seconds to wait for the remote target responses') + + @classmethod + def do_create(cls, cfg: RunnerConfig, args: argparse.Namespace) -> 'NXPS32DebugProbeRunner': + probe_cfg = NXPS32DebugProbeConfig(args.dev_id, + server_port=args.server_port, + speed=args.speed, + remote_timeout=args.remote_timeout) + + return NXPS32DebugProbeRunner(cfg, probe_cfg, args.core_name, args.soc_name, + args.soc_family_name, args.start_all_cores, + s32ds_path=args.s32ds_path, tool_opt=args.tool_opt) + + @staticmethod + def find_usb_probes() -> List[str]: + """Return a list of debug probe serial numbers connected via USB to this host.""" + # use system's native commands to enumerate and retrieve the USB serial ID + # to avoid bloating this runner with third-party dependencies that often + # require priviledged permissions to access the device info + macaddr_pattern = r'(?:[0-9a-f]{2}[:]){5}[0-9a-f]{2}' + if platform.system() == 'Windows': + cmd = f'pnputil /enum-devices /connected /class "{NXP_S32DBG_USB_CLASS}"' + serialid_pattern = f'instance id: +usb\\\\.*\\\\({macaddr_pattern})' + else: + cmd = f'lsusb -v -d {NXP_S32DBG_USB_VID:x}:{NXP_S32DBG_USB_PID:x}' + serialid_pattern = f'iserial +.*({macaddr_pattern})' + + try: + outb = subprocess.check_output(shlex.split(cmd), stderr=subprocess.DEVNULL) + out = outb.decode('utf-8').strip().lower() + except subprocess.CalledProcessError: + raise RuntimeError('error while looking for debug probes connected') + + devices: List[str] = [] + if out and 'no devices were found' not in out: + devices = re.findall(serialid_pattern, out) + + return sorted(devices) + + @classmethod + def select_probe(cls) -> str: + """ + Find debugger probes connected and return the serial number of the one selected. + + If there are multiple debugger probes connected and this runner is being executed + in a interactive prompt, ask the user to select one of the probes. + """ + probes_snr = cls.find_usb_probes() + if not probes_snr: + raise RuntimeError('there are no debug probes connected') + elif len(probes_snr) == 1: + return probes_snr[0] + else: + if not sys.stdin.isatty(): + raise RuntimeError( + f'refusing to guess which of {len(probes_snr)} connected probes to use ' + '(Interactive prompts disabled since standard input is not a terminal). ' + 'Please specify a device ID on the command line.') + + print('There are multiple debug probes connected') + for i, probe in enumerate(probes_snr, 1): + print(f'{i}. {probe}') + + prompt = f'Please select one with desired serial number (1-{len(probes_snr)}): ' + while True: + try: + value: int = int(input(prompt)) + except EOFError: + sys.exit(0) + except ValueError: + continue + if 1 <= value <= len(probes_snr): + break + return probes_snr[value - 1] + + @property + def runtime_environment(self) -> Optional[Dict[str, str]]: + """Execution environment used for the client process.""" + if platform.system() == 'Windows': + python_lib = (self.s32ds_path / 'S32DS' / 'build_tools' / 'msys32' + / 'mingw32' / 'lib' / 'python2.7') + return { + **os.environ, + 'PYTHONPATH': f'{python_lib}{os.pathsep}{python_lib / "site-packages"}' + } + + return None + + @property + def script_globals(self) -> Dict[str, Optional[Union[str, int]]]: + """Global variables required by the debugger scripts.""" + return { + '_PROBE_IP': self.probe_cfg.conn_str, + '_JTAG_SPEED': self.probe_cfg.speed, + '_GDB_SERVER_PORT': self.probe_cfg.server_port, + '_RESET_TYPE': self.probe_cfg.reset_type, + '_RESET_DELAY': self.probe_cfg.reset_delay, + '_REMOTE_TIMEOUT': self.probe_cfg.remote_timeout, + '_CORE_NAME': f'{self.soc_name}_{self.core_name}', + '_SOC_NAME': self.soc_name, + '_IS_LOGGING_ENABLED': False, + '_FLASH_NAME': None, # not supported + '_SECURE_TYPE': None, # not supported + '_SECURE_KEY': None, # not supported + } + + def server_commands(self) -> List[str]: + """Get launch commands to start the GTA server.""" + server_exec = str(self.s32ds_path / 'S32DS' / 'tools' / 'S32Debugger' + / 'Debugger' / 'Server' / 'gta' / 'gta') + cmd = [server_exec, '-p', str(self.probe_cfg.server_port)] + return cmd + + def client_commands(self) -> List[str]: + """Get launch commands to start the GDB client.""" + if self.arch == 'arm': + client_exec_name = 'arm-none-eabi-gdb-py' + elif self.arch == 'arm64': + client_exec_name = 'aarch64-none-elf-gdb-py' + else: + raise RuntimeError(f'architecture {self.arch} not supported') + + client_exec = str(self.s32ds_path / 'S32DS' / 'tools' / 'gdb-arm' + / 'arm32-eabi' / 'bin' / client_exec_name) + cmd = [client_exec] + return cmd + + def get_script(self, name: str) -> Path: + """ + Get the file path of a debugger script with the given name. + + :param name: name of the script, without the SoC family name prefix + :returns: path to the script + :raises RuntimeError: if file does not exist + """ + script = (self.s32ds_path / 'S32DS' / 'tools' / 'S32Debugger' / 'Debugger' / 'scripts' + / self.soc_family_name / f'{self.soc_family_name}_{name}.py') + if not script.exists(): + raise RuntimeError(f'script not found: {script}') + return script + + def do_run(self, command: str, **kwargs) -> None: + """ + Execute the given command. + + :param command: command name to execute + :raises RuntimeError: if target architecture or host OS is not supported + :raises MissingProgram: if required tools are not found in the host + """ + if platform.system() not in ('Windows', 'Linux'): + raise RuntimeError(f'runner not supported on {platform.system()} systems') + + if self.arch not in ('arm', 'arm64'): + raise RuntimeError(f'architecture {self.arch} not supported') + + app_name = 's32ds' if platform.system() == 'Windows' else 's32ds.sh' + self.s32ds_path = Path(self.require(app_name, path=self.s32ds_path_override)).parent + + if not self.probe_cfg.conn_str: + self.probe_cfg.conn_str = f's32dbg:{self.select_probe()}' + self.logger.info(f'using debug probe {self.probe_cfg.conn_str}') + + if command in ('attach', 'debug'): + self.ensure_output('elf') + self.do_attach_debug(command, **kwargs) + else: + self.do_debugserver(**kwargs) + + def do_attach_debug(self, command: str, **kwargs) -> None: + """ + Launch the GTA server and GDB client to start a debugging session. + + :param command: command name to execute + """ + gdb_script: List[str] = [] + + # setup global variables required for the scripts before sourcing them + for name, val in self.script_globals.items(): + gdb_script.append(f'py {name} = {repr(val)}') + + # load platform-specific debugger script + if command == 'debug': + if self.start_all_cores: + startup_script = self.get_script('generic_bareboard_all_cores') + else: + startup_script = self.get_script('generic_bareboard') + else: + startup_script = self.get_script('attach') + gdb_script.append(f'source {startup_script}') + + # executes the SoC and board initialization sequence + if command == 'debug': + gdb_script.append('py board_init()') + + # initializes the debugger connection to the core specified + gdb_script.append('py core_init()') + + gdb_script.append(f'file {Path(self.elf_file).as_posix()}') + if command == 'debug': + gdb_script.append('load') + + with tempfile.TemporaryDirectory(suffix='nxp_s32dbg') as tmpdir: + gdb_cmds = Path(tmpdir) / 'runner.nxp_s32dbg' + gdb_cmds.write_text('\n'.join(gdb_script), encoding='utf-8') + self.logger.debug(gdb_cmds.read_text(encoding='utf-8')) + + server_cmd = self.server_commands() + client_cmd = self.client_commands() + client_cmd.extend(['-x', gdb_cmds.as_posix()]) + client_cmd.extend(self.tool_opt) + + self.run_server_and_client(server_cmd, client_cmd, env=self.runtime_environment) + + def do_debugserver(self, **kwargs) -> None: + """Start the GTA server on a given port with the given extra parameters from cli.""" + server_cmd = self.server_commands() + server_cmd.extend(self.tool_opt) + self.check_call(server_cmd) diff --git a/scripts/west_commands/tests/test_imports.py b/scripts/west_commands/tests/test_imports.py index 774d4f7d722..274840f8cbf 100644 --- a/scripts/west_commands/tests/test_imports.py +++ b/scripts/west_commands/tests/test_imports.py @@ -35,6 +35,7 @@ def test_runner_imports(): 'nios2', 'nrfjprog', 'nrfutil', + 'nxp_s32dbg', 'openocd', 'pyocd', 'qemu', From 52e9671fa8efa3bed9f0995fe698383ca6d2ef3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:50 +0700 Subject: [PATCH 2601/4498] west: add tests for NXP S32 Debug Probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add minimal set of tests to verify behavior of supported commands. Signed-off-by: Manuel Argüelles --- .../west_commands/tests/test_nxp_s32dbg.py | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 scripts/west_commands/tests/test_nxp_s32dbg.py diff --git a/scripts/west_commands/tests/test_nxp_s32dbg.py b/scripts/west_commands/tests/test_nxp_s32dbg.py new file mode 100644 index 00000000000..a0d982cdfe8 --- /dev/null +++ b/scripts/west_commands/tests/test_nxp_s32dbg.py @@ -0,0 +1,247 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os +from pathlib import Path +from unittest.mock import patch + +import pytest +from conftest import RC_KERNEL_ELF +from runners.nxp_s32dbg import NXPS32DebugProbeConfig, NXPS32DebugProbeRunner + +TEST_DEVICE = 's32dbg' +TEST_SPEED = 16000 +TEST_SERVER_PORT = 45000 +TEST_REMOTE_TIMEOUT = 30 +TEST_CORE_NAME = 'R52_0_0' +TEST_SOC_NAME = 'S32Z270' +TEST_SOC_FAMILY_NAME = 's32e2z2' +TEST_START_ALL_CORES = True +TEST_S32DS_PATH_OVERRIDE = None +TEST_TOOL_OPT = ['--test-opt-1', '--test-opt-2'] +TEST_RESET_TYPE = 'default' +TEST_RESET_DELAY = 0 + +TEST_S32DS_CMD = 's32ds' +TEST_SERVER_CMD = Path('S32DS') / 'tools' / 'S32Debugger' / 'Debugger' / 'Server' / 'gta' / 'gta' +TEST_ARM_GDB_CMD = Path('S32DS') / 'tools' / 'gdb-arm' / 'arm32-eabi' / 'bin' / 'arm-none-eabi-gdb-py' + +TEST_S32DS_PYTHON_LIB = Path('S32DS') / 'build_tools' / 'msys32' / 'mingw32' / 'lib' / 'python2.7' +TEST_S32DS_RUNTIME_ENV = { + 'PYTHONPATH': f'{TEST_S32DS_PYTHON_LIB}{os.pathsep}{TEST_S32DS_PYTHON_LIB / "site-packages"}' +} + +TEST_ALL_KWARGS = { + 'NXPS32DebugProbeConfig': { + 'conn_str': TEST_DEVICE, + 'server_port': TEST_SERVER_PORT, + 'speed': TEST_SPEED, + 'remote_timeout': TEST_REMOTE_TIMEOUT, + }, + 'NXPS32DebugProbeRunner': { + 'core_name': TEST_CORE_NAME, + 'soc_name': TEST_SOC_NAME, + 'soc_family_name': TEST_SOC_FAMILY_NAME, + 'start_all_cores': TEST_START_ALL_CORES, + 's32ds_path': TEST_S32DS_PATH_OVERRIDE, + 'tool_opt': TEST_TOOL_OPT + } +} + +TEST_ALL_PARAMS = [ + # generic + '--dev-id', TEST_DEVICE, + *[f'--tool-opt={o}' for o in TEST_TOOL_OPT], + # from runner + '--s32ds-path', TEST_S32DS_PATH_OVERRIDE, + '--core-name', TEST_CORE_NAME, + '--soc-name', TEST_SOC_NAME, + '--soc-family-name', TEST_SOC_FAMILY_NAME, + '--server-port', TEST_SERVER_PORT, + '--speed', TEST_SPEED, + '--remote-timeout', TEST_REMOTE_TIMEOUT, + '--start-all-cores', +] + +TEST_ALL_S32DBG_PY_VARS = [ + f'py _PROBE_IP = {repr(TEST_DEVICE)}', + f'py _JTAG_SPEED = {repr(TEST_SPEED)}', + f'py _GDB_SERVER_PORT = {repr(TEST_SERVER_PORT)}', + f"py _RESET_TYPE = {repr(TEST_RESET_TYPE)}", + f'py _RESET_DELAY = {repr(TEST_RESET_DELAY)}', + f'py _REMOTE_TIMEOUT = {repr(TEST_REMOTE_TIMEOUT)}', + f'py _CORE_NAME = {repr(f"{TEST_SOC_NAME}_{TEST_CORE_NAME}")}', + f'py _SOC_NAME = {repr(TEST_SOC_NAME)}', + 'py _IS_LOGGING_ENABLED = False', + 'py _FLASH_NAME = None', + 'py _SECURE_TYPE = None', + 'py _SECURE_KEY = None', +] + +DEBUGSERVER_ALL_EXPECTED_CALL = [ + str(TEST_SERVER_CMD), + '-p', str(TEST_SERVER_PORT), + *TEST_TOOL_OPT, +] + +DEBUG_ALL_EXPECTED_CALL = { + 'client': [ + str(TEST_ARM_GDB_CMD), + '-x', 'TEST_GDB_SCRIPT', + *TEST_TOOL_OPT, + ], + 'server': [ + str(TEST_SERVER_CMD), + '-p', str(TEST_SERVER_PORT), + ], + 'gdb_script': [ + *TEST_ALL_S32DBG_PY_VARS, + f'source generic_bareboard{"_all_cores" if TEST_START_ALL_CORES else ""}.py', + 'py board_init()', + 'py core_init()', + f'file {RC_KERNEL_ELF}', + 'load', + ] +} + +ATTACH_ALL_EXPECTED_CALL = { + **DEBUG_ALL_EXPECTED_CALL, + 'gdb_script': [ + *TEST_ALL_S32DBG_PY_VARS, + f'source attach.py', + 'py core_init()', + f'file {RC_KERNEL_ELF}', + ] +} + + +@pytest.fixture +def s32dbg(runner_config, tmp_path): + '''NXPS32DebugProbeRunner from constructor kwargs or command line parameters''' + def _factory(args): + # create empty files to ensure kernel binaries exist + (tmp_path / RC_KERNEL_ELF).touch() + os.chdir(tmp_path) + + runner_config_patched = fix_up_runner_config(runner_config, tmp_path) + + if isinstance(args, dict): + probe_cfg = NXPS32DebugProbeConfig(**args['NXPS32DebugProbeConfig']) + return NXPS32DebugProbeRunner(runner_config_patched, probe_cfg, + **args['NXPS32DebugProbeRunner']) + elif isinstance(args, list): + parser = argparse.ArgumentParser(allow_abbrev=False) + NXPS32DebugProbeRunner.add_parser(parser) + arg_namespace = parser.parse_args(str(x) for x in args) + return NXPS32DebugProbeRunner.create(runner_config_patched, arg_namespace) + return _factory + + +def fix_up_runner_config(runner_config, tmp_path): + to_replace = {} + + zephyr = tmp_path / 'zephyr' + zephyr.mkdir() + dotconfig = zephyr / '.config' + dotconfig.write_text('CONFIG_ARCH="arm"') + to_replace['build_dir'] = tmp_path + + return runner_config._replace(**to_replace) + + +def require_patch(program, path=None): + assert Path(program).stem == TEST_S32DS_CMD + return program + + +def s32dbg_get_script(name): + return Path(f'{name}.py') + + +@pytest.mark.parametrize('s32dbg_args,expected,osname', [ + (TEST_ALL_KWARGS, DEBUGSERVER_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_PARAMS, DEBUGSERVER_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_KWARGS, DEBUGSERVER_ALL_EXPECTED_CALL, 'Linux'), + (TEST_ALL_PARAMS, DEBUGSERVER_ALL_EXPECTED_CALL, 'Linux'), +]) +@patch('platform.system') +@patch('runners.core.ZephyrBinaryRunner.check_call') +@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) +def test_debugserver(require, check_call, system, + s32dbg_args, expected, osname, s32dbg): + system.return_value = osname + + runner = s32dbg(s32dbg_args) + runner.run('debugserver') + + assert require.called + check_call.assert_called_once_with(expected) + + +@pytest.mark.parametrize('s32dbg_args,expected,osname', [ + (TEST_ALL_KWARGS, DEBUG_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_PARAMS, DEBUG_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_KWARGS, DEBUG_ALL_EXPECTED_CALL, 'Linux'), + (TEST_ALL_PARAMS, DEBUG_ALL_EXPECTED_CALL, 'Linux'), +]) +@patch.dict(os.environ, TEST_S32DS_RUNTIME_ENV, clear=True) +@patch('platform.system') +@patch('tempfile.TemporaryDirectory') +@patch('runners.nxp_s32dbg.NXPS32DebugProbeRunner.get_script', side_effect=s32dbg_get_script) +@patch('runners.core.ZephyrBinaryRunner.popen_ignore_int') +@patch('runners.core.ZephyrBinaryRunner.check_call') +@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) +def test_debug(require, check_call, popen_ignore_int, get_script, temporary_dir, system, + s32dbg_args, expected, osname, s32dbg, tmp_path): + + # mock tempfile.TemporaryDirectory to return `tmp_path` and create gdb init script there + temporary_dir.return_value.__enter__.return_value = tmp_path + gdb_script = tmp_path / 'runner.nxp_s32dbg' + expected_client = [e.replace('TEST_GDB_SCRIPT', gdb_script.as_posix()) + for e in expected['client']] + + system.return_value = osname + expected_env = TEST_S32DS_RUNTIME_ENV if osname == 'Windows' else None + + runner = s32dbg(s32dbg_args) + runner.run('debug') + + assert require.called + assert gdb_script.read_text().splitlines() == expected['gdb_script'] + popen_ignore_int.assert_called_once_with(expected['server'], env=expected_env) + check_call.assert_called_once_with(expected_client, env=expected_env) + + +@pytest.mark.parametrize('s32dbg_args,expected,osname', [ + (TEST_ALL_KWARGS, ATTACH_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_PARAMS, ATTACH_ALL_EXPECTED_CALL, 'Windows'), + (TEST_ALL_KWARGS, ATTACH_ALL_EXPECTED_CALL, 'Linux'), + (TEST_ALL_PARAMS, ATTACH_ALL_EXPECTED_CALL, 'Linux'), +]) +@patch.dict(os.environ, TEST_S32DS_RUNTIME_ENV, clear=True) +@patch('platform.system') +@patch('tempfile.TemporaryDirectory') +@patch('runners.nxp_s32dbg.NXPS32DebugProbeRunner.get_script', side_effect=s32dbg_get_script) +@patch('runners.core.ZephyrBinaryRunner.popen_ignore_int') +@patch('runners.core.ZephyrBinaryRunner.check_call') +@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) +def test_attach(require, check_call, popen_ignore_int, get_script, temporary_dir, system, + s32dbg_args, expected, osname, s32dbg, tmp_path): + + # mock tempfile.TemporaryDirectory to return `tmp_path` and create gdb init script there + temporary_dir.return_value.__enter__.return_value = tmp_path + gdb_script = tmp_path / 'runner.nxp_s32dbg' + expected_client = [e.replace('TEST_GDB_SCRIPT', gdb_script.as_posix()) + for e in expected['client']] + + system.return_value = osname + expected_env = TEST_S32DS_RUNTIME_ENV if osname == 'Windows' else None + + runner = s32dbg(s32dbg_args) + runner.run('attach') + + assert require.called + assert gdb_script.read_text().splitlines() == expected['gdb_script'] + popen_ignore_int.assert_called_once_with(expected['server'], env=expected_env) + check_call.assert_called_once_with(expected_client, env=expected_env) From 006a65069081440fc4899f560707f654d6bcdb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:54 +0700 Subject: [PATCH 2602/4498] doc: flash_debug: add NXP S32 debug probe docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document needed steps to download, install and setup the debug host tools for NXP S32 Debug Probe. Signed-off-by: Manuel Argüelles --- doc/develop/flash_debug/host-tools.rst | 68 ++++++++++++++++++++++++++ doc/develop/flash_debug/probes.rst | 49 +++++++++++++------ 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/doc/develop/flash_debug/host-tools.rst b/doc/develop/flash_debug/host-tools.rst index 981c89ce686..cf349d5d29d 100644 --- a/doc/develop/flash_debug/host-tools.rst +++ b/doc/develop/flash_debug/host-tools.rst @@ -377,6 +377,68 @@ Zephyr RTOS Awareness To enable Zephyr RTOS awareness follow the steps described in `Lauterbach TRACE32 Zephyr OS Awareness Manual`_. +.. _nxp-s32-debug-host-tools: + +NXP S32 Debug Probe Host Tools +****************************** + +:ref:`nxp-s32-debug-probe` is designed to work in conjunction with +`NXP S32 Design Studio for S32 Platform`_. + +Download (registration required) NXP S32 Design Studio for S32 Platform and +follow the `S32 Design Studio for S32 Platform Installation User Guide`_ to get +the necessary debug host tools and associated USB device drivers. + +Note that Zephyr RTOS-awareness support for the NXP S32 GDB server depends on +the target device. Consult the product release notes for more information. + +Supported west commands: + +1. debug +#. debugserver +#. attach + +Basic usage +----------- + +Before starting, add NXP S32 Design Studio installation directory to the system +:ref:`PATH environment variable `. Alternatively, it can be passed to +the runner on each invocation via ``--s32ds-path`` as shown below: + +.. tabs:: + + .. group-tab:: Linux + + .. code-block:: console + + west debug --s32ds-path=/opt/NXP/S32DS.3.5 + + .. group-tab:: Windows + + .. code-block:: console + + west debug --s32ds-path=C:\NXP\S32DS.3.5 + +If multiple S32 debug probes are connected to the host via USB, the runner will +ask the user to select one via command line prompt before continuing. The +connection string for the probe can be also specified when invoking the runner +via ``--dev-id=``. Consult NXP S32 debug probe user manual +for details on how to construct the connection string. For example, if using a +probe with serial ID ``00:04:9f:00:ca:fe``: + +.. code-block:: console + + west debug --dev-id='s32dbg:00:04:9f:00:ca:fe' + +It is possible to pass extra options to the debug host tools via ``--tool-opt``. +When executing ``debug`` or ``attach`` commands, the tool options will be passed +to the GDB client only. When executing ``debugserver``, the tool options will be +passed to the GDB server. For example, to load a Zephyr application to SRAM and +afterwards detach the debug session: + +.. code-block:: console + + west debug --tool-opt='--batch' .. _J-Link Software and Documentation Pack: https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack @@ -416,3 +478,9 @@ To enable Zephyr RTOS awareness follow the steps described in .. _MCUXpresso Installer: https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe + +.. _NXP S32 Design Studio for S32 Platform: + https://www.nxp.com/design/software/development-software/s32-design-studio-ide/s32-design-studio-for-s32-platform:S32DS-S32PLATFORM + +.. _S32 Design Studio for S32 Platform Installation User Guide: + https://www.nxp.com/webapp/Download?colCode=S32DSIG diff --git a/doc/develop/flash_debug/probes.rst b/doc/develop/flash_debug/probes.rst index 83f355aadba..0e237a6fcf6 100644 --- a/doc/develop/flash_debug/probes.rst +++ b/doc/develop/flash_debug/probes.rst @@ -33,21 +33,23 @@ host tools, or with J-Link firmware to communicate with J-Link debug host tools. -+---------------------------------------+---------------------------------------------------------------+ -|| *Debug Probes & Host Tools* | Host Tools | -+| *Compatibility Chart* +--------------------+--------------------+---------------------+ -| | **J-Link Debug** | **OpenOCD** | **pyOCD** | -+----------------+----------------------+--------------------+--------------------+---------------------+ -| | **LPC-Link2 J-Link** | ✓ | | | -| +----------------------+--------------------+--------------------+---------------------+ -| | **OpenSDA DAPLink** | | ✓ | ✓ | -| +----------------------+--------------------+--------------------+---------------------+ -| Debug Probes | **OpenSDA J-Link** | ✓ | | | -| +----------------------+--------------------+--------------------+---------------------+ -| | **J-Link External** | ✓ | ✓ | | -| +----------------------+--------------------+--------------------+---------------------+ -| | **ST-LINK/V2-1** | ✓ | ✓ | *some STM32 boards* | -+----------------+----------------------+--------------------+--------------------+---------------------+ ++------------------------------------------+------------------------------------------------------------------------------------+ +|| *Debug Probes & Host Tools* | Host Tools | ++| *Compatibility Chart* +--------------------+--------------------+---------------------+--------------------+ +| | **J-Link Debug** | **OpenOCD** | **pyOCD** | **NXP S32DS** | ++----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+ +| | **LPC-Link2 J-Link** | ✓ | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+ +| | **OpenSDA DAPLink** | | ✓ | ✓ | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+ +| Debug Probes | **OpenSDA J-Link** | ✓ | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+ +| | **J-Link External** | ✓ | ✓ | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+ +| | **ST-LINK/V2-1** | ✓ | ✓ | *some STM32 boards* | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+ +| | **NXP S32 Debug Probe** | | | | ✓ | ++----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+ Some supported boards in Zephyr do not include an onboard debug probe and @@ -373,6 +375,20 @@ Where board_uid can be obtained using twister's generate-hardware-map option. For more information about twister and available options, see :ref:`twister_script`. +.. _nxp-s32-debug-probe: + +NXP S32 Debug Probe +******************* + +`NXP S32 Debug Probe`_ enables NXP S32 target system debugging via a standard +debug port while connected to a developer's workstation via USB or remotely via +Ethernet. + +NXP S32 Debug Probe is designed to work in conjunction with NXP S32 Design Studio +(S32DS) and NXP Automotive microcontrollers and processors. Install the debug +host tools as in indicated in :ref:`nxp-s32-debug-host-tools` before you program +the firmware. + .. _LPCScrypt: https://www.nxp.com/lpcscrypt @@ -402,3 +418,6 @@ option. For more information about twister and available options, see .. _MCUXpresso Installer: https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe + +.. _NXP S32 Debug Probe: + https://www.nxp.com/design/software/automotive-software-and-tools/s32-debug-probe:S32-DP From a7bda0896054c3ac043a2d5819612c478fd97a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 28 Sep 2023 16:38:12 +0700 Subject: [PATCH 2603/4498] nxp: s32ze: take exceptions in Arm mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cortex-R52 supports both Arm and Thumb-2 mode, but Zephyr's ASM code for Armv-8 Aarch32 is written for Arm mode only. This Soc has a general purpose register that can set the core TEINIT signal to change the mode exceptions are taken before booting up the core. The debugger startup scripts or firmware booting up the core may configure this bit to Thumb mode, as is the case of the NXP S32 debug probe startup scripts for S32ZE. Due to above reason, clear SCTLR.TE bit at reset so that TEINIT value is ignored and exceptions are always taken into Arm mode, compatible with current Zephyr ASM code. At least until taking execeptions in Thumb mode is supported in Zephyr. Signed-off-by: Manuel Argüelles --- soc/arm/nxp_s32/s32ze/soc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/soc/arm/nxp_s32/s32ze/soc.c b/soc/arm/nxp_s32/s32ze/soc.c index 36acfbf9dc8..871536a26c6 100644 --- a/soc/arm/nxp_s32/s32ze/soc.c +++ b/soc/arm/nxp_s32/s32ze/soc.c @@ -21,6 +21,12 @@ void z_arm_platform_init(void) barrier_dsync_fence_full(); barrier_isync_fence_full(); + /* + * Take exceptions in Arm mode because Zephyr ASM code for Cortex-R Aarch32 + * is written for Arm + */ + __set_SCTLR(__get_SCTLR() & ~SCTLR_TE_Msk); + if (IS_ENABLED(CONFIG_ICACHE)) { if (!(__get_SCTLR() & SCTLR_I_Msk)) { L1C_InvalidateICacheAll(); From 339cd5a45fd2ebba064ef462b71c657336ca0dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 5 Sep 2023 10:43:59 +0700 Subject: [PATCH 2604/4498] s32z270dc2_r52: make nxp_s32dbg the default runner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make NXP S32 Debug Probe runner the default on this board and keep Lauterbach TRACE32 runner as an alternative. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/board.cmake | 25 +++--- boards/arm/s32z270dc2_r52/doc/index.rst | 114 +++++++++++++++--------- 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/board.cmake b/boards/arm/s32z270dc2_r52/board.cmake index c7da302041a..31a4fe20d42 100644 --- a/boards/arm/s32z270dc2_r52/board.cmake +++ b/boards/arm/s32z270dc2_r52/board.cmake @@ -1,19 +1,24 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 -board_set_flasher_ifnset(trace32) -board_set_debugger_ifnset(trace32) - board_runner_args(trace32 "--startup-args" - "elfFile=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" - "thumb=no" + "elfFile=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" + "rtu=${CONFIG_NXP_S32_RTU_INDEX}" +) + +board_runner_args(nxp_s32dbg + "--soc-family-name" "s32z2e2" + "--soc-name" "S32Z270" ) -if(CONFIG_BOARD_S32Z270DC2_RTU0_R52) -board_runner_args(trace32 "rtu=0") -elseif(CONFIG_BOARD_S32Z270DC2_RTU1_R52) -board_runner_args(trace32 "rtu=1") +if(CONFIG_DCLS) + board_runner_args(trace32 "lockstep=yes") + board_runner_args(nxp_s32dbg "--core-name" "R52_${CONFIG_NXP_S32_RTU_INDEX}_0_LS") +else() + board_runner_args(trace32 "lockstep=no") + board_runner_args(nxp_s32dbg "--core-name" "R52_${CONFIG_NXP_S32_RTU_INDEX}_0") endif() +include(${ZEPHYR_BASE}/boards/common/nxp_s32dbg.board.cmake) include(${ZEPHYR_BASE}/boards/common/trace32.board.cmake) diff --git a/boards/arm/s32z270dc2_r52/doc/index.rst b/boards/arm/s32z270dc2_r52/doc/index.rst index 60b465cc940..e940a144f1f 100644 --- a/boards/arm/s32z270dc2_r52/doc/index.rst +++ b/boards/arm/s32z270dc2_r52/doc/index.rst @@ -146,26 +146,21 @@ Applications for the ``s32z270dc2_rtu0_r52`` and ``s32z270dc2_rtu1_r52`` boards can be built in the usual way as documented in :ref:`build_an_application`. Currently is only possible to load and execute a Zephyr application binary on -this board from the internal SRAM, using `Lauterbach TRACE32`_ development -tools and debuggers. +this board from the core internal SRAM. -.. note:: - Currently, the start-up scripts executed with ``west flash`` and - ``west debug`` commands perform the same steps to initialize the SoC and - load the application to SRAM. The difference is that ``west flash`` hide the - Lauterbach TRACE32 interface, executes the application and exits. +This board supports West runners for the following debug tools: -Install Lauterbach TRACE32 Software -=================================== +- :ref:`NXP S32 Debug Probe ` (default) +- :ref:`Lauterbach TRACE32 ` -Follow the steps described in :ref:`lauterbach-trace32-debug-host-tools` to -install and set-up Lauterbach TRACE32 software. +Follow the installation steps of the debug tool you plan to use before loading +your firmware. Set-up the Board ================ -Connect the Lauterbach TRACE32 debugger to the board's JTAG connector (``J134``) -and to the host computer. +Connect the external debugger probe to the board's JTAG connector (``J134``) +and to the host computer via USB or Ethernet, as supported by the probe. For visualizing the serial output, connect the board's USB/UART port (``J119``) to the host computer and run your favorite terminal program to listen for output. @@ -178,16 +173,16 @@ For example, using the cross-platform `pySerial miniterm`_ terminal: Replace ```` with the port where the board can be found. For example, under Linux, ``/dev/ttyUSB0``. -Flashing -======== +Debugging +========= -For example, you can build and run the :ref:`hello_world` sample for the board +You can build and debug the :ref:`hello_world` sample for the board ``s32z270dc2_rtu0_r52`` with: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: s32z270dc2_rtu0_r52 - :goals: build flash + :goals: build debug In case you are using a newer PCB revision, you have to use an adapted board definition as the default PCB revision is B. For example, if using revision D: @@ -195,30 +190,53 @@ definition as the default PCB revision is B. For example, if using revision D: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: s32z270dc2_rtu0_r52@D - :goals: build flash + :goals: build debug + :compact: -You should see the following message in the terminal: +At this point you can do your normal debug session. Set breakpoints and then +:kbd:`c` to continue into the program. You should see the following message in +the terminal: .. code-block:: console Hello World! s32z270dc2_rtu0_r52 -Debugging -========= +To debug with Lauterbach TRACE32 softare run instead: -To enable debugging using Lauterbach TRACE32 software, run instead: +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: s32z270dc2_rtu0_r52 + :goals: build debug -r trace32 + :compact: + +Flashing +======== + +Follow these steps if you just want to download the application to the board +SRAM and run. + +``flash`` command is supported only by the Lauterbach TRACE32 runner: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: s32z270dc2_rtu0_r52 - :goals: build debug + :goals: build flash -r trace32 + :compact: -Step through the application in your debugger, and you should see the following -message in the terminal: +.. note:: + Currently, the Lauterbach start-up scripts executed with ``flash`` and + ``debug`` commands perform the same steps to initialize the SoC and + load the application to SRAM. The difference is that ``flash`` hides the + Lauterbach TRACE32 interface, executes the application and exits. -.. code-block:: console +To imitate a similar behavior using NXP S32 Debug Probe runner, you can run the +``debug`` command with GDB in batch mode: - Hello World! s32z270dc2_rtu0_r52 +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: s32z270dc2_rtu0_r52 + :goals: build debug --tool-opt='--batch' + :compact: RTU and Core Configuration ========================== @@ -231,26 +249,29 @@ configuration). To build for split-lock mode, the :kconfig:option:`CONFIG_DCLS` must be disabled from your application Kconfig file. -Additionally, to run in a different core or with a different core -configuration than the default, extra parameters must be provided to the runner -as follows: +By default the board configuration will set the runner arguments according to +the build configuration. To debug for a core different than the default use: -.. code-block:: console +.. tabs:: + + .. group-tab:: lockstep configuration + + .. code-block:: console - west --startup-args elfFile= rtu= \ - core= lockstep= + west debug --core-name='R52___LS' + + .. group-tab:: split-lock configuration + + .. code-block:: console + + west debug --core-name='R52__' Where: -- ```` is ``flash`` or ``debug`` -- ```` is the path to the Zephyr application ELF in the output - directory - ```` is the zero-based RTU index (0 for ``s32z270dc2_rtu0_r52`` and 1 for ``s32z270dc2_rtu1_r52``) - ```` is the zero-based core index relative to the RTU on which to run the Zephyr application (0, 1, 2 or 3) -- ```` can be ``yes`` to run in lock-step, or ``no`` to run in - split-lock. For example, to build the :ref:`hello_world` sample for the board ``s32z270dc2_rtu0_r52`` with split-lock core configuration: @@ -260,13 +281,23 @@ For example, to build the :ref:`hello_world` sample for the board :board: s32z270dc2_rtu0_r52 :goals: build :gen-args: -DCONFIG_DCLS=n + :compact: To execute this sample in the second core of RTU0 in split-lock mode: .. code-block:: console - west flash --startup-args elfFile=build/zephyr/zephyr.elf \ - rtu=0 core=1 lockstep=no + west debug --core-name='R52_0_1' + +If using Lauterbach TRACE32, all runner parameters must be overridden from command +line: + +.. code-block:: console + + west debug --startup-args elfFile= rtu= core= lockstep= + +Where ```` is the path to the Zephyr application ELF in the output +directory. References ********** @@ -276,8 +307,5 @@ References .. _NXP S32Z2 Real-Time Processors website: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32z-and-s32e-real-time-processors/s32z2-safe-and-secure-high-performance-real-time-processors:S32Z2 -.. _Lauterbach TRACE32: - https://www.lauterbach.com - .. _pySerial miniterm: https://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.miniterm From eb2f5ceb196b51e9a465b905c20a99ce1de4fd2b Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Wed, 25 Oct 2023 11:02:20 +0200 Subject: [PATCH 2605/4498] dts: bindings: spi: add support to set CPOL, CPHA, and HOLD_CS in dts file Add support to set SPI clock polarity (CPOL), clock phase (CPHA), and hold-on-cs in a dts file to get rid of using related macros in spi.c driver since each board may work on a different SPI mode rather than the default one (based on CPOL and CPHA). Signed-off-by: Ali Hozhabri --- dts/bindings/spi/spi-device.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dts/bindings/spi/spi-device.yaml b/dts/bindings/spi/spi-device.yaml index f820863b30d..6915b664890 100644 --- a/dts/bindings/spi/spi-device.yaml +++ b/dts/bindings/spi/spi-device.yaml @@ -40,3 +40,21 @@ properties: enum: - 0 - 32768 + spi-cpol: + type: boolean + description: | + SPI clock polarity which indicates the clock idle state. + If it is used, the clock idle state is logic high; otherwise, low. + spi-cpha: + type: boolean + description: | + SPI clock phase that indicates on which edge data is sampled. + If it is used, data is sampled on the second edge; otherwise, on the first edge. + spi-hold-cs: + type: boolean + description: | + In some cases, it is necessary for the master to manage SPI chip select + under software control, so that multiple spi transactions can be performed + without releasing it. A typical use case is variable length SPI packets + where the first spi transaction reads the length and the second spi transaction + reads length bytes. From e2c0cb979fead154704e07a43e379878dc4c9322 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Mon, 16 Oct 2023 18:22:25 +0200 Subject: [PATCH 2606/4498] include: zephyr: drivers: modify SPI_CONFIG_DT to add CPOL, CPHA, HOLD_CS Modify SPI_CONFIG_DT macro to config SPI clock polarity (CPOL), clock phase (CPHA), and hold-cs. Signed-off-by: Ali Hozhabri --- include/zephyr/drivers/spi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 671040de6a3..fa3b8834c9e 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -332,7 +332,10 @@ struct spi_config { .frequency = DT_PROP(node_id, spi_max_frequency), \ .operation = (operation_) | \ DT_PROP(node_id, duplex) | \ - DT_PROP(node_id, frame_format), \ + DT_PROP(node_id, frame_format) | \ + COND_CODE_1(DT_PROP(node_id, spi_cpol), SPI_MODE_CPOL, (0)) | \ + COND_CODE_1(DT_PROP(node_id, spi_cpha), SPI_MODE_CPHA, (0)) | \ + COND_CODE_1(DT_PROP(node_id, spi_hold_cs), SPI_HOLD_ON_CS, (0)), \ .slave = DT_REG_ADDR(node_id), \ .cs = SPI_CS_CONTROL_INIT(node_id, delay_), \ } From 154023f754f5b8a6e4de9e804e8724d23cd9efdc Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Thu, 5 Oct 2023 16:11:52 +0200 Subject: [PATCH 2607/4498] drivers: spi: update drivers that were using spi cpol and cpha Modified files (yaml, dts, overlay, and c) which were using spi-cpol and spi-cpha to be compatible with the new structure. Signed-off-by: Ali Hozhabri --- drivers/ethernet/dsa_ksz8xxx.c | 2 -- drivers/led_strip/ws2812_spi.c | 2 -- dts/bindings/dsa/microchip_dsa.yaml | 10 ---------- dts/bindings/led_strip/worldsemi,ws2812-spi.yaml | 8 -------- 4 files changed, 22 deletions(-) diff --git a/drivers/ethernet/dsa_ksz8xxx.c b/drivers/ethernet/dsa_ksz8xxx.c index 0a6bb0adffe..964cd3505d3 100644 --- a/drivers/ethernet/dsa_ksz8xxx.c +++ b/drivers/ethernet/dsa_ksz8xxx.c @@ -1091,8 +1091,6 @@ static struct dsa_api dsa_api_f = { #if defined(CONFIG_DSA_SPI) #define DSA_SPI_BUS_CONFIGURATION(n) \ .spi = SPI_DT_SPEC_INST_GET(n, \ - COND_CODE_1(DT_INST_PROP(n, spi_cpol), (SPI_MODE_CPOL), ()) | \ - COND_CODE_1(DT_INST_PROP(n, spi_cpha), (SPI_MODE_CPHA), ()) | \ SPI_WORD_SET(8), \ 0U) #else diff --git a/drivers/led_strip/ws2812_spi.c b/drivers/led_strip/ws2812_spi.c index c562d5c3dad..44cfecebc9e 100644 --- a/drivers/led_strip/ws2812_spi.c +++ b/drivers/led_strip/ws2812_spi.c @@ -34,8 +34,6 @@ LOG_MODULE_REGISTER(ws2812_spi); * isn't an EEPROM) */ #define SPI_OPER(idx) (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ - COND_CODE_1(DT_INST_PROP(idx, spi_cpol), (SPI_MODE_CPOL), (0)) | \ - COND_CODE_1(DT_INST_PROP(idx, spi_cpha), (SPI_MODE_CPHA), (0)) | \ SPI_WORD_SET(SPI_FRAME_BITS)) struct ws2812_spi_cfg { diff --git a/dts/bindings/dsa/microchip_dsa.yaml b/dts/bindings/dsa/microchip_dsa.yaml index 8762fec748c..4a607b11ae4 100644 --- a/dts/bindings/dsa/microchip_dsa.yaml +++ b/dts/bindings/dsa/microchip_dsa.yaml @@ -12,16 +12,6 @@ properties: dsa-slave-ports: type: int description: Number of slave ports on the switch - spi-cpha: - type: boolean - description: | - Set to indicate phase starts with asserted half-phase (CPHA=1). - For this driver using this property requires also using cpol. - spi-cpol: - type: boolean - description: | - Set to indicate clock leading edge is falling (CPOL=1). - For this driver using this property requires also using cpha. reset-gpios: type: phandle-array description: | diff --git a/dts/bindings/led_strip/worldsemi,ws2812-spi.yaml b/dts/bindings/led_strip/worldsemi,ws2812-spi.yaml index 0eafd37fde7..3c8626c1ec3 100644 --- a/dts/bindings/led_strip/worldsemi,ws2812-spi.yaml +++ b/dts/bindings/led_strip/worldsemi,ws2812-spi.yaml @@ -24,14 +24,6 @@ include: [spi-device.yaml, ws2812.yaml] properties: - spi-cpol: - type: boolean - description: Set SPI clock polarity. - - spi-cpha: - type: boolean - description: Set SPI clock phase. - spi-one-frame: type: int required: true From d36e42c97506b95ff6ca6a2878edf44e50f26541 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 11 Oct 2023 22:59:38 +0100 Subject: [PATCH 2608/4498] usbc: Use a DT alias to identify USB-C port Samples sometimes need to identify a default USB-C port. Instead of hard-coding a node label, use the usbc-port0 alias to point to the correct node. Signed-off-by: Andreas Sandberg --- .../usb_c/sink/boards/b_g474e_dpow1.overlay | 4 ++++ .../usb_c/sink/boards/stm32g081b_eval.overlay | 4 ++++ samples/subsys/usb_c/sink/src/main.c | 14 +++++++------- .../usb_c/source/boards/stm32g081b_eval.overlay | 3 +++ samples/subsys/usb_c/source/src/main.c | 16 ++++++++-------- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay b/samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay index 8a68e092b7c..de70e938992 100644 --- a/samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay +++ b/samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay @@ -8,6 +8,10 @@ #include / { + aliases { + usbc-port0 = &port1; + }; + /* usbc.rst vbus-voltage-divider-adc start */ vbus1: vbus { compatible = "zephyr,usb-c-vbus-adc"; diff --git a/samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay b/samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay index 2ff32caba68..ca6e32206c6 100644 --- a/samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay +++ b/samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay @@ -8,6 +8,10 @@ #include / { + aliases { + usbc-port0 = &port1; + }; + vbus1: vbus { compatible = "zephyr,usb-c-vbus-adc"; io-channels = <&adc1 9>; diff --git a/samples/subsys/usb_c/sink/src/main.c b/samples/subsys/usb_c/sink/src/main.c index 87ed5114838..a87f19c7e8a 100644 --- a/samples/subsys/usb_c/sink/src/main.c +++ b/samples/subsys/usb_c/sink/src/main.c @@ -13,10 +13,10 @@ #include LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); -#define PORT1_NODE DT_NODELABEL(port1) -#define PORT1_POWER_ROLE DT_ENUM_IDX(DT_NODELABEL(port1), power_role) +#define USBC_PORT0_NODE DT_ALIAS(usbc_port0) +#define USBC_PORT0_POWER_ROLE DT_ENUM_IDX(USBC_PORT0_NODE, power_role) -#if (PORT1_POWER_ROLE != TC_ROLE_SINK) +#if (USBC_PORT0_POWER_ROLE != TC_ROLE_SINK) #error "Unsupported board: Only Sink device supported" #endif @@ -28,7 +28,7 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); */ static struct port1_data_t { /** Sink Capabilities */ - uint32_t snk_caps[DT_PROP_LEN(DT_NODELABEL(port1), sink_pdos)]; + uint32_t snk_caps[DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos)]; /** Number of Sink Capabilities */ int snk_cap_cnt; /** Source Capabilities */ @@ -38,8 +38,8 @@ static struct port1_data_t { /* Power Supply Ready flag */ atomic_t ps_ready; } port1_data = { - .snk_caps = {DT_FOREACH_PROP_ELEM(DT_NODELABEL(port1), sink_pdos, SINK_PDO)}, - .snk_cap_cnt = DT_PROP_LEN(DT_NODELABEL(port1), sink_pdos), + .snk_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, sink_pdos, SINK_PDO)}, + .snk_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos), .src_caps = {0}, .src_cap_cnt = 0, .ps_ready = 0 @@ -298,7 +298,7 @@ int main(void) const struct device *usbc_port1; /* Get the device for this port */ - usbc_port1 = DEVICE_DT_GET(PORT1_NODE); + usbc_port1 = DEVICE_DT_GET(USBC_PORT0_NODE); if (!device_is_ready(usbc_port1)) { LOG_ERR("PORT1 device not ready"); return 0; diff --git a/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay b/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay index 9e56510ee6b..d81b3d9dbee 100644 --- a/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay +++ b/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay @@ -8,6 +8,9 @@ #include / { + aliases { + usbc-port0 = &port1; + }; pwmleds { compatible = "pwm-leds"; diff --git a/samples/subsys/usb_c/source/src/main.c b/samples/subsys/usb_c/source/src/main.c index 416c717a3ed..144607d74d9 100644 --- a/samples/subsys/usb_c/source/src/main.c +++ b/samples/subsys/usb_c/source/src/main.c @@ -15,11 +15,11 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); #include "power_ctrl.h" -#define PORT1_NODE DT_NODELABEL(port1) -#define PORT1_POWER_ROLE DT_ENUM_IDX(DT_NODELABEL(port1), power_role) +#define USBC_PORT0_NODE DT_ALIAS(usbc_port0) +#define USBC_PORT0_POWER_ROLE DT_ENUM_IDX(USBC_PORT0_NODE, power_role) /* A Source power role evauates to 1. See usbc_tc.h: TC_ROLE_SOURCE */ -#if (PORT1_POWER_ROLE != 1) +#if (USBC_PORT0_POWER_ROLE != 1) #error "Unsupported board: Only Source device supported" #endif @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); */ static struct port1_data_t { /** Source Capabilities */ - uint32_t src_caps[DT_PROP_LEN(DT_NODELABEL(port1), source_pdos)]; + uint32_t src_caps[DT_PROP_LEN(USBC_PORT0_NODE, source_pdos)]; /** Number of Source Capabilities */ int src_cap_cnt; /** CC Rp value */ @@ -49,9 +49,9 @@ static struct port1_data_t { /** Log Sink Requested RDO to console */ atomic_t show_sink_request; } port1_data = { - .rp = DT_ENUM_IDX(DT_NODELABEL(port1), typec_power_opmode), - .src_caps = {DT_FOREACH_PROP_ELEM(DT_NODELABEL(port1), source_pdos, SOURCE_PDO)}, - .src_cap_cnt = DT_PROP_LEN(DT_NODELABEL(port1), source_pdos), + .rp = DT_ENUM_IDX(USBC_PORT0_NODE, typec_power_opmode), + .src_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, source_pdos, SOURCE_PDO)}, + .src_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, source_pdos), }; /* usbc.rst port data object end */ @@ -318,7 +318,7 @@ int main(void) const struct device *usbc_port1; /* Get the device for this port */ - usbc_port1 = DEVICE_DT_GET(PORT1_NODE); + usbc_port1 = DEVICE_DT_GET(USBC_PORT0_NODE); if (!device_is_ready(usbc_port1)) { LOG_ERR("PORT1 device not ready"); return 0; From b41853127f1a241058c6531913da1141cb6b4be1 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 17 Oct 2023 19:30:13 +0100 Subject: [PATCH 2609/4498] samples: usb_c: Rename port1 to port0 for consistency Aliases, including usbc_port0, start counting from zero. This meant that the DT alias is inconsistent with the port numbering in the samples. Change the numbering scheme to start from zero to make this consistent. Signed-off-by: Andreas Sandberg --- samples/subsys/usb_c/sink/src/main.c | 54 +++++++-------- samples/subsys/usb_c/source/src/main.c | 92 +++++++++++++------------- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/samples/subsys/usb_c/sink/src/main.c b/samples/subsys/usb_c/sink/src/main.c index a87f19c7e8a..fb6407a0309 100644 --- a/samples/subsys/usb_c/sink/src/main.c +++ b/samples/subsys/usb_c/sink/src/main.c @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); /** * @brief A structure that encapsulates Port data. */ -static struct port1_data_t { +static struct port0_data_t { /** Sink Capabilities */ uint32_t snk_caps[DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos)]; /** Number of Sink Capabilities */ @@ -37,7 +37,7 @@ static struct port1_data_t { int src_cap_cnt; /* Power Supply Ready flag */ atomic_t ps_ready; -} port1_data = { +} port0_data = { .snk_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, sink_pdos, SINK_PDO)}, .snk_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos), .src_caps = {0}, @@ -61,7 +61,7 @@ static struct port1_data_t { * @note Generally a sink application would build an RDO from the * Source Capabilities stored in the dpm_data object */ -static uint32_t build_rdo(const struct port1_data_t *dpm_data) +static uint32_t build_rdo(const struct port0_data_t *dpm_data) { union pd_rdo rdo; @@ -161,7 +161,7 @@ static void display_pdo(const int idx, static void display_source_caps(const struct device *dev) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); LOG_INF("Source Caps:"); for (int i = 0; i < dpm_data->src_cap_cnt; i++) { @@ -171,11 +171,11 @@ static void display_source_caps(const struct device *dev) } /* usbc.rst callbacks start */ -static int port1_policy_cb_get_snk_cap(const struct device *dev, +static int port0_policy_cb_get_snk_cap(const struct device *dev, uint32_t **pdos, int *num_pdos) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); *pdos = dpm_data->snk_caps; *num_pdos = dpm_data->snk_cap_cnt; @@ -183,11 +183,11 @@ static int port1_policy_cb_get_snk_cap(const struct device *dev, return 0; } -static void port1_policy_cb_set_src_cap(const struct device *dev, +static void port0_policy_cb_set_src_cap(const struct device *dev, const uint32_t *pdos, const int num_pdos) { - struct port1_data_t *dpm_data; + struct port0_data_t *dpm_data; int num; int i; @@ -205,19 +205,19 @@ static void port1_policy_cb_set_src_cap(const struct device *dev, dpm_data->src_cap_cnt = num; } -static uint32_t port1_policy_cb_get_rdo(const struct device *dev) +static uint32_t port0_policy_cb_get_rdo(const struct device *dev) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); return build_rdo(dpm_data); } /* usbc.rst callbacks end */ /* usbc.rst notify start */ -static void port1_notify(const struct device *dev, +static void port0_notify(const struct device *dev, const enum usbc_policy_notify_t policy_notify) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); switch (policy_notify) { case PROTOCOL_ERROR: @@ -269,7 +269,7 @@ static void port1_notify(const struct device *dev, /* usbc.rst notify end */ /* usbc.rst check start */ -bool port1_policy_check(const struct device *dev, +bool port0_policy_check(const struct device *dev, const enum usbc_policy_check_t policy_check) { switch (policy_check) { @@ -295,12 +295,12 @@ bool port1_policy_check(const struct device *dev, int main(void) { - const struct device *usbc_port1; + const struct device *usbc_port0; /* Get the device for this port */ - usbc_port1 = DEVICE_DT_GET(USBC_PORT0_NODE); - if (!device_is_ready(usbc_port1)) { - LOG_ERR("PORT1 device not ready"); + usbc_port0 = DEVICE_DT_GET(USBC_PORT0_NODE); + if (!device_is_ready(usbc_port0)) { + LOG_ERR("PORT0 device not ready"); return 0; } @@ -308,33 +308,33 @@ int main(void) /* Register USB-C Callbacks */ /* Register Policy Check callback */ - usbc_set_policy_cb_check(usbc_port1, port1_policy_check); + usbc_set_policy_cb_check(usbc_port0, port0_policy_check); /* Register Policy Notify callback */ - usbc_set_policy_cb_notify(usbc_port1, port1_notify); + usbc_set_policy_cb_notify(usbc_port0, port0_notify); /* Register Policy Get Sink Capabilities callback */ - usbc_set_policy_cb_get_snk_cap(usbc_port1, port1_policy_cb_get_snk_cap); + usbc_set_policy_cb_get_snk_cap(usbc_port0, port0_policy_cb_get_snk_cap); /* Register Policy Set Source Capabilities callback */ - usbc_set_policy_cb_set_src_cap(usbc_port1, port1_policy_cb_set_src_cap); + usbc_set_policy_cb_set_src_cap(usbc_port0, port0_policy_cb_set_src_cap); /* Register Policy Get Request Data Object callback */ - usbc_set_policy_cb_get_rdo(usbc_port1, port1_policy_cb_get_rdo); + usbc_set_policy_cb_get_rdo(usbc_port0, port0_policy_cb_get_rdo); /* usbc.rst register end */ /* usbc.rst user data start */ /* Set Application port data object. This object is passed to the policy callbacks */ - port1_data.ps_ready = ATOMIC_INIT(0); - usbc_set_dpm_data(usbc_port1, &port1_data); + port0_data.ps_ready = ATOMIC_INIT(0); + usbc_set_dpm_data(usbc_port0, &port0_data); /* usbc.rst user data end */ /* usbc.rst usbc start */ /* Start the USB-C Subsystem */ - usbc_start(usbc_port1); + usbc_start(usbc_port0); /* usbc.rst usbc end */ while (1) { /* Perform Application Specific functions */ - if (atomic_test_and_clear_bit(&port1_data.ps_ready, 0)) { + if (atomic_test_and_clear_bit(&port0_data.ps_ready, 0)) { /* Display the Source Capabilities */ - display_source_caps(usbc_port1); + display_source_caps(usbc_port0); } /* Arbitrary delay */ diff --git a/samples/subsys/usb_c/source/src/main.c b/samples/subsys/usb_c/source/src/main.c index 144607d74d9..1e7018c2748 100644 --- a/samples/subsys/usb_c/source/src/main.c +++ b/samples/subsys/usb_c/source/src/main.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); /** * @brief A structure that encapsulates Port data. */ -static struct port1_data_t { +static struct port0_data_t { /** Source Capabilities */ uint32_t src_caps[DT_PROP_LEN(USBC_PORT0_NODE, source_pdos)]; /** Number of Source Capabilities */ @@ -48,7 +48,7 @@ static struct port1_data_t { bool ps_tran_start; /** Log Sink Requested RDO to console */ atomic_t show_sink_request; -} port1_data = { +} port0_data = { .rp = DT_ENUM_IDX(USBC_PORT0_NODE, typec_power_opmode), .src_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, source_pdos, SOURCE_PDO)}, .src_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, source_pdos), @@ -84,10 +84,10 @@ static void dump_sink_request_rdo(const uint32_t rdo) /** * @brief PE calls this function when it needs to set the Rp on CC */ -int port1_policy_cb_get_src_rp(const struct device *dev, +int port0_policy_cb_get_src_rp(const struct device *dev, enum tc_rp_value *rp) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); *rp = dpm_data->rp; @@ -98,7 +98,7 @@ int port1_policy_cb_get_src_rp(const struct device *dev, * @brief PE calls this function to Enable (5V) or Disable (0V) the * Power Supply */ -int port1_policy_cb_src_en(const struct device *dev, bool en) +int port0_policy_cb_src_en(const struct device *dev, bool en) { source_ctrl_set(en ? SOURCE_5V : SOURCE_0V); @@ -108,9 +108,9 @@ int port1_policy_cb_src_en(const struct device *dev, bool en) /** * @brief PE calls this function to Enable or Disable VCONN */ -int port1_policy_cb_vconn_en(const struct device *dev, enum tc_cc_polarity pol, bool en) +int port0_policy_cb_vconn_en(const struct device *dev, enum tc_cc_polarity pol, bool en) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); dpm_data->vconn_pol = pol; @@ -132,10 +132,10 @@ int port1_policy_cb_vconn_en(const struct device *dev, enum tc_cc_polarity pol, * @brief PE calls this function to get the Source Caps that will be sent * to the Sink */ -int port1_policy_cb_get_src_caps(const struct device *dev, +int port0_policy_cb_get_src_caps(const struct device *dev, const uint32_t **pdos, uint32_t *num_pdos) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); *pdos = dpm_data->src_caps; *num_pdos = dpm_data->src_cap_cnt; @@ -146,10 +146,10 @@ int port1_policy_cb_get_src_caps(const struct device *dev, /** * @brief PE calls this function to verify that a Sink's request if valid */ -static enum usbc_snk_req_reply_t port1_policy_cb_check_sink_request(const struct device *dev, +static enum usbc_snk_req_reply_t port0_policy_cb_check_sink_request(const struct device *dev, const uint32_t request_msg) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); union pd_fixed_supply_pdo_source pdo; uint32_t obj_pos; uint32_t op_current; @@ -171,13 +171,13 @@ static enum usbc_snk_req_reply_t port1_policy_cb_check_sink_request(const struct dpm_data->obj_pos = obj_pos; - atomic_set_bit(&port1_data.show_sink_request, 0); + atomic_set_bit(&port0_data.show_sink_request, 0); /* * Clear PS ready. This will be set to true after PS is ready after * it transitions to the new level. */ - port1_data.ps_ready = false; + port0_data.ps_ready = false; return SNK_REQUEST_VALID; } @@ -186,9 +186,9 @@ static enum usbc_snk_req_reply_t port1_policy_cb_check_sink_request(const struct * @brief PE calls this function to check if the Power Supply is at the requested * level */ -static bool port1_policy_cb_is_ps_ready(const struct device *dev) +static bool port0_policy_cb_is_ps_ready(const struct device *dev) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); /* Return true to inform that the Power Supply is ready */ @@ -199,10 +199,10 @@ static bool port1_policy_cb_is_ps_ready(const struct device *dev) * @brief PE calls this function to check if the Present Contract is still * valid */ -static bool port1_policy_cb_present_contract_is_valid(const struct device *dev, +static bool port0_policy_cb_present_contract_is_valid(const struct device *dev, const uint32_t present_contract) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); union pd_fixed_supply_pdo_source pdo; union pd_rdo request; uint32_t obj_pos; @@ -228,10 +228,10 @@ static bool port1_policy_cb_present_contract_is_valid(const struct device *dev, /* usbc.rst callbacks end */ /* usbc.rst notify start */ -static void port1_notify(const struct device *dev, +static void port0_notify(const struct device *dev, const enum usbc_policy_notify_t policy_notify) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); switch (policy_notify) { case PROTOCOL_ERROR: @@ -277,10 +277,10 @@ static void port1_notify(const struct device *dev, /* usbc.rst notify end */ /* usbc.rst check start */ -bool port1_policy_check(const struct device *dev, +bool port0_policy_check(const struct device *dev, const enum usbc_policy_check_t policy_check) { - struct port1_data_t *dpm_data = usbc_get_dpm_data(dev); + struct port0_data_t *dpm_data = usbc_get_dpm_data(dev); switch (policy_check) { case CHECK_POWER_ROLE_SWAP: @@ -315,12 +315,12 @@ bool port1_policy_check(const struct device *dev, int main(void) { - const struct device *usbc_port1; + const struct device *usbc_port0; /* Get the device for this port */ - usbc_port1 = DEVICE_DT_GET(USBC_PORT0_NODE); - if (!device_is_ready(usbc_port1)) { - LOG_ERR("PORT1 device not ready"); + usbc_port0 = DEVICE_DT_GET(USBC_PORT0_NODE); + if (!device_is_ready(usbc_port0)) { + LOG_ERR("PORT0 device not ready"); return 0; } @@ -328,63 +328,63 @@ int main(void) /* Register USB-C Callbacks */ /* Register Policy Check callback */ - usbc_set_policy_cb_check(usbc_port1, port1_policy_check); + usbc_set_policy_cb_check(usbc_port0, port0_policy_check); /* Register Policy Notify callback */ - usbc_set_policy_cb_notify(usbc_port1, port1_notify); + usbc_set_policy_cb_notify(usbc_port0, port0_notify); /* Register Policy callback to set the Rp on CC lines */ - usbc_set_policy_cb_get_src_rp(usbc_port1, port1_policy_cb_get_src_rp); + usbc_set_policy_cb_get_src_rp(usbc_port0, port0_policy_cb_get_src_rp); /* Register Policy callback to enable or disable power supply */ - usbc_set_policy_cb_src_en(usbc_port1, port1_policy_cb_src_en); + usbc_set_policy_cb_src_en(usbc_port0, port0_policy_cb_src_en); /* Register Policy callback to enable or disable vconn */ - usbc_set_vconn_control_cb(usbc_port1, port1_policy_cb_vconn_en); + usbc_set_vconn_control_cb(usbc_port0, port0_policy_cb_vconn_en); /* Register Policy callback to send the source caps to the sink */ - usbc_set_policy_cb_get_src_caps(usbc_port1, port1_policy_cb_get_src_caps); + usbc_set_policy_cb_get_src_caps(usbc_port0, port0_policy_cb_get_src_caps); /* Register Policy callback to check if the sink request is valid */ - usbc_set_policy_cb_check_sink_request(usbc_port1, port1_policy_cb_check_sink_request); + usbc_set_policy_cb_check_sink_request(usbc_port0, port0_policy_cb_check_sink_request); /* Register Policy callback to check if the power supply is ready */ - usbc_set_policy_cb_is_ps_ready(usbc_port1, port1_policy_cb_is_ps_ready); + usbc_set_policy_cb_is_ps_ready(usbc_port0, port0_policy_cb_is_ps_ready); /* Register Policy callback to check if Present Contract is still valid */ - usbc_set_policy_cb_present_contract_is_valid(usbc_port1, - port1_policy_cb_present_contract_is_valid); + usbc_set_policy_cb_present_contract_is_valid(usbc_port0, + port0_policy_cb_present_contract_is_valid); /* usbc.rst register end */ /* usbc.rst user data start */ /* Set Application port data object. This object is passed to the policy callbacks */ - usbc_set_dpm_data(usbc_port1, &port1_data); + usbc_set_dpm_data(usbc_port0, &port0_data); /* usbc.rst user data end */ /* Flag to show sink request */ - port1_data.show_sink_request = ATOMIC_INIT(0); + port0_data.show_sink_request = ATOMIC_INIT(0); /* Init power supply transition start */ - port1_data.ps_tran_start = false; + port0_data.ps_tran_start = false; /* Init power supply ready */ - port1_data.ps_ready = false; + port0_data.ps_ready = false; /* usbc.rst usbc start */ /* Start the USB-C Subsystem */ - usbc_start(usbc_port1); + usbc_start(usbc_port0); /* usbc.rst usbc end */ while (1) { /* Perform Application Specific functions */ /* Transition PS to new level */ - if (port1_data.ps_tran_start) { + if (port0_data.ps_tran_start) { /* * Transition Power Supply to new voltage. * Okay if this blocks. */ - source_ctrl_set(port1_data.obj_pos); - port1_data.ps_ready = true; - port1_data.ps_tran_start = false; + source_ctrl_set(port0_data.obj_pos); + port0_data.ps_ready = true; + port0_data.ps_tran_start = false; } /* Display Sink Requests */ - if (atomic_test_and_clear_bit(&port1_data.show_sink_request, 0)) { + if (atomic_test_and_clear_bit(&port0_data.show_sink_request, 0)) { /* Display the Sink request */ - dump_sink_request_rdo(port1_data.sink_request.raw_value); + dump_sink_request_rdo(port0_data.sink_request.raw_value); } /* Arbitrary delay */ k_msleep(10); From bd5ea8d552a59812d33c89db6196e43983837af5 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 6 Sep 2023 16:42:25 +0000 Subject: [PATCH 2610/4498] dts: ite: move pinctrl subdevices up a node Refactor the pinctrl nodes slightly so that the port devices are not child of the main pinctrl node. This is because the pinctrl node is being used as parent for pinctrl setting nodes itself, and having the port nodes as child end up creating a circular depdency with the edt child enumeration patch. Signed-off-by: Fabio Baltieri --- dts/riscv/ite/it81xx2.dtsi | 554 ++++++++++++++++++------------------- dts/riscv/ite/it82xx2.dtsi | 546 ++++++++++++++++++------------------ 2 files changed, 550 insertions(+), 550 deletions(-) diff --git a/dts/riscv/ite/it81xx2.dtsi b/dts/riscv/ite/it81xx2.dtsi index e8975c4c496..939e1672bfc 100644 --- a/dts/riscv/ite/it81xx2.dtsi +++ b/dts/riscv/ite/it81xx2.dtsi @@ -57,284 +57,284 @@ #address-cells = <1>; #size-cells = <1>; status = "okay"; + }; + + pinctrla: pinctrl@f01610 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01610 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0x02 0x02 0x10 0x0C >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = ; + volt-sel-mask = <0 0 0 0 + 0x1 0x02 0x20 0x40 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlb: pinctrl@f01618 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01618 8>; /* GPCR */ + func3-gcr = <0xf016f5 0xf016f5 NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC 0xf01600>; + func3-en-mask = <0x01 0x02 0 0 + 0 0 0 0x02 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0x40 >; + volt-sel = ; + volt-sel-mask = <0 0 0 0x02 + 0x01 0x80 0x40 0x10 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlc: pinctrl@f01620 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01620 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0x10 + 0 0x10 0 0x02 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0x80 >; + volt-sel = <0xf016e7 0xf016e4 0xf016e4 NO_FUNC + 0xf016e9 NO_FUNC 0xf016e9 0xf016e4>; + volt-sel-mask = <0x80 0x20 0x10 0 + 0x04 0 0x08 0x08 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrld: pinctrl@f01628 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01628 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x02 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e4 0xf016e4 0xf016e4 0xf016e5 + 0xf016e5 0xf016e7 0xf016e7 0xf016e7>; + volt-sel-mask = <0x04 0x02 0x01 0x80 + 0x40 0x10 0x20 0x40 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrle: pinctrl@f01630 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01630 8>; /* GPCR */ + func3-gcr = <0xf02032 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC 0xf016f0 NO_FUNC 0xf02032>; + func3-en-mask = <0x01 0 0 0 + 0 0x08 0 0x01 >; + func4-gcr = <0xf016f3 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC NO_FUNC >; + func4-en-mask = <0x01 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e5 0xf016d4 0xf016d4 NO_FUNC + 0xf016e7 0xf016e7 0xf016e5 0xf016e5>; + volt-sel-mask = <0x20 0x40 0x80 0 + 0x04 0x08 0x10 0x08 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlf: pinctrl@f01638 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01638 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0x02 0x02 + 0 0 0x10 0x10 >; + func4-gcr = ; + func4-en-mask = <0 0 0x40 0x40 + 0 0 0 0 >; + volt-sel = <0xf016d4 0xf016d4 0xf016e5 0xf016e5 + 0xf016e5 0xf016e6 0xf016e6 0xf016e6>; + volt-sel-mask = <0x10 0x20 0x04 0x02 + 0x01 0x80 0x40 0x20 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlg: pinctrl@f01640 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01640 8>; /* GPCR */ + func3-gcr = <0xf016f0 0xf016f0 0xf016f0 NO_FUNC + NO_FUNC NO_FUNC 0xf016f0 NO_FUNC>; + func3-en-mask = <0x20 0x08 0x10 0 + 0 0 0x02 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d4 0xf016e6 0xf016d4 NO_FUNC + NO_FUNC NO_FUNC 0xf016e6 NO_FUNC>; + volt-sel-mask = <0x04 0x10 0x08 0 + 0 0 0x08 0 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlh: pinctrl@f01648 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01648 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0x20 0x20 0 + 0 0x04 0x08 0 >; + func3-ext = ; + func3-ext-mask = <0 0 0 0 + 0 0x01 0x01 0 >; + func4-gcr = ; + func4-en-mask = <0 0x04 0x08 0 + 0 0 0 0 >; + volt-sel = <0xf016e6 0xf016e6 0xf016e6 NO_FUNC + NO_FUNC 0xf016d3 0xf016d4 NO_FUNC>; + volt-sel-mask = <0x04 0x02 0x01 0 + 0 0x80 0x01 0 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrli: pinctrl@f01650 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01650 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x08 0x08 0x08 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d3 0xf016e8 0xf016e8 0xf016e8 + 0xf016e8 0xf016d3 0xf016d3 0xf016d3>; + volt-sel-mask = <0x08 0x10 0x20 0x40 + 0x80 0x10 0x20 0x40 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlj: pinctrl@f01658 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01658 8>; /* GPCR */ + func3-gcr = <0xf016f4 NO_FUNC 0xf016f4 0xf016f4 + 0xf016f0 0xf016f0 NO_FUNC NO_FUNC>; + func3-en-mask = <0x01 0 0x01 0x02 + 0x02 0x03 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e8 0xf016e8 0xf016e8 0xf016e8 + 0xf016d3 0xf016d3 0xf016d3 0xf016d7>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x01 0x02 0x04 0x04 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlk: pinctrl@f01690 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01690 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d2 0xf016d2 0xf016d2 0xf016d2 + 0xf016d2 0xf016d2 0xf016d2 0xf016d2>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x10 0x20 0x40 0x80 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrll: pinctrl@f01698 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01698 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d1 0xf016d1 0xf016d1 0xf016d1 + 0xf016d1 0xf016d1 0xf016d1 0xf016d1>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x10 0x20 0x40 0x80 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlm: pinctrl@f016a0 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016a0 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016ed 0xf016ed 0xf016ed 0xf016ed + 0xf016ed 0xf016ed 0xf016ed NO_FUNC >; + volt-sel-mask = <0x10 0x10 0x10 0x10 + 0x10 0x10 0x10 0 >; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlksi: pinctrl@f01d06 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d06 1 /* KSIGCTRL */ + 0x00f01d05 1>; /* KSICTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; + }; + + pinctrlksoh: pinctrl@f01d0a { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d0a 1 /* KSOHGCTRL */ + 0x00f01d02 1>; /* KSOCTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; + }; - pinctrla: pinctrl@f01610 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01610 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0x02 0x02 0x10 0x0C >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = ; - volt-sel-mask = <0 0 0 0 - 0x1 0x02 0x20 0x40 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlb: pinctrl@f01618 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01618 8>; /* GPCR */ - func3-gcr = <0xf016f5 0xf016f5 NO_FUNC NO_FUNC - NO_FUNC NO_FUNC NO_FUNC 0xf01600>; - func3-en-mask = <0x01 0x02 0 0 - 0 0 0 0x02 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0x40 >; - volt-sel = ; - volt-sel-mask = <0 0 0 0x02 - 0x01 0x80 0x40 0x10 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlc: pinctrl@f01620 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01620 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0x10 - 0 0x10 0 0x02 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0x80 >; - volt-sel = <0xf016e7 0xf016e4 0xf016e4 NO_FUNC - 0xf016e9 NO_FUNC 0xf016e9 0xf016e4>; - volt-sel-mask = <0x80 0x20 0x10 0 - 0x04 0 0x08 0x08 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrld: pinctrl@f01628 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01628 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0x02 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016e4 0xf016e4 0xf016e4 0xf016e5 - 0xf016e5 0xf016e7 0xf016e7 0xf016e7>; - volt-sel-mask = <0x04 0x02 0x01 0x80 - 0x40 0x10 0x20 0x40 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrle: pinctrl@f01630 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01630 8>; /* GPCR */ - func3-gcr = <0xf02032 NO_FUNC NO_FUNC NO_FUNC - NO_FUNC 0xf016f0 NO_FUNC 0xf02032>; - func3-en-mask = <0x01 0 0 0 - 0 0x08 0 0x01 >; - func4-gcr = <0xf016f3 NO_FUNC NO_FUNC NO_FUNC - NO_FUNC NO_FUNC NO_FUNC NO_FUNC >; - func4-en-mask = <0x01 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016e5 0xf016d4 0xf016d4 NO_FUNC - 0xf016e7 0xf016e7 0xf016e5 0xf016e5>; - volt-sel-mask = <0x20 0x40 0x80 0 - 0x04 0x08 0x10 0x08 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlf: pinctrl@f01638 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01638 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0x02 0x02 - 0 0 0x10 0x10 >; - func4-gcr = ; - func4-en-mask = <0 0 0x40 0x40 - 0 0 0 0 >; - volt-sel = <0xf016d4 0xf016d4 0xf016e5 0xf016e5 - 0xf016e5 0xf016e6 0xf016e6 0xf016e6>; - volt-sel-mask = <0x10 0x20 0x04 0x02 - 0x01 0x80 0x40 0x20 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlg: pinctrl@f01640 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01640 8>; /* GPCR */ - func3-gcr = <0xf016f0 0xf016f0 0xf016f0 NO_FUNC - NO_FUNC NO_FUNC 0xf016f0 NO_FUNC>; - func3-en-mask = <0x20 0x08 0x10 0 - 0 0 0x02 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016d4 0xf016e6 0xf016d4 NO_FUNC - NO_FUNC NO_FUNC 0xf016e6 NO_FUNC>; - volt-sel-mask = <0x04 0x10 0x08 0 - 0 0 0x08 0 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlh: pinctrl@f01648 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01648 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0x20 0x20 0 - 0 0x04 0x08 0 >; - func3-ext = ; - func3-ext-mask = <0 0 0 0 - 0 0x01 0x01 0 >; - func4-gcr = ; - func4-en-mask = <0 0x04 0x08 0 - 0 0 0 0 >; - volt-sel = <0xf016e6 0xf016e6 0xf016e6 NO_FUNC - NO_FUNC 0xf016d3 0xf016d4 NO_FUNC>; - volt-sel-mask = <0x04 0x02 0x01 0 - 0 0x80 0x01 0 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrli: pinctrl@f01650 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01650 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0x08 0x08 0x08 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016d3 0xf016e8 0xf016e8 0xf016e8 - 0xf016e8 0xf016d3 0xf016d3 0xf016d3>; - volt-sel-mask = <0x08 0x10 0x20 0x40 - 0x80 0x10 0x20 0x40 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlj: pinctrl@f01658 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01658 8>; /* GPCR */ - func3-gcr = <0xf016f4 NO_FUNC 0xf016f4 0xf016f4 - 0xf016f0 0xf016f0 NO_FUNC NO_FUNC>; - func3-en-mask = <0x01 0 0x01 0x02 - 0x02 0x03 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016e8 0xf016e8 0xf016e8 0xf016e8 - 0xf016d3 0xf016d3 0xf016d3 0xf016d7>; - volt-sel-mask = <0x01 0x02 0x04 0x08 - 0x01 0x02 0x04 0x04 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlk: pinctrl@f01690 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01690 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016d2 0xf016d2 0xf016d2 0xf016d2 - 0xf016d2 0xf016d2 0xf016d2 0xf016d2>; - volt-sel-mask = <0x01 0x02 0x04 0x08 - 0x10 0x20 0x40 0x80 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrll: pinctrl@f01698 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01698 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016d1 0xf016d1 0xf016d1 0xf016d1 - 0xf016d1 0xf016d1 0xf016d1 0xf016d1>; - volt-sel-mask = <0x01 0x02 0x04 0x08 - 0x10 0x20 0x40 0x80 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlm: pinctrl@f016a0 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a0 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf016ed 0xf016ed 0xf016ed 0xf016ed - 0xf016ed 0xf016ed 0xf016ed NO_FUNC >; - volt-sel-mask = <0x10 0x10 0x10 0x10 - 0x10 0x10 0x10 0 >; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlksi: pinctrl@f01d06 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d06 1 /* KSIGCTRL */ - 0x00f01d05 1>; /* KSICTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; - - pinctrlksoh: pinctrl@f01d0a { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d0a 1 /* KSOHGCTRL */ - 0x00f01d02 1>; /* KSOCTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; - - pinctrlksol: pinctrl@f01d0d { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d0d 1 /* KSOLGCTRL */ - 0x00f01d02 1>; /* KSOCTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; + pinctrlksol: pinctrl@f01d0d { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d0d 1 /* KSOLGCTRL */ + 0x00f01d02 1>; /* KSOCTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; }; i2c0: i2c@f01c40 { diff --git a/dts/riscv/ite/it82xx2.dtsi b/dts/riscv/ite/it82xx2.dtsi index 7d9089005aa..810b77f8d8a 100644 --- a/dts/riscv/ite/it82xx2.dtsi +++ b/dts/riscv/ite/it82xx2.dtsi @@ -440,280 +440,280 @@ #address-cells = <1>; #size-cells = <1>; status = "okay"; + }; - pinctrla: pinctrl@f01660 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01660 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0x02 0x02 0x10 0x0C >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01648 0xf01648 0xf01648 0xf01648 - 0xf01648 0xf01648 0xf01648 0xf01648>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlb: pinctrl@f01668 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01668 8>; /* GPCR */ - func3-gcr = <0xf03e15 0xf03e15 0xf03e16 NO_FUNC - NO_FUNC 0xf03e16 NO_FUNC NO_FUNC>; - func3-en-mask = <0x01 0x02 0x40 0 - 0 0x40 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01649 0xf01649 0xf01649 0xf01649 - 0xf01649 0xf01649 0xf01649 NO_FUNC>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlc: pinctrl@f01670 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01670 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0x10 - 0 0x10 0 0x02 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0x80 >; - volt-sel = <0xf0164a 0xf0164a 0xf0164a 0xf0164a - 0xf0164a 0xf0164a 0xf0164a 0xf0164a>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrld: pinctrl@f01678 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01678 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0x02 0 0 >; - func4-gcr = <0xf03e16 NO_FUNC NO_FUNC NO_FUNC - NO_FUNC NO_FUNC NO_FUNC NO_FUNC>; - func4-en-mask = <0x80 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf0164b 0xf0164b 0xf0164b 0xf0164b - 0xf0164b 0xf0164b 0xf0164b 0xf0164b>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrle: pinctrl@f01680 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01680 8>; /* GPCR */ - func3-gcr = <0xf02032 0xf03e16 0xf03e16 NO_FUNC - NO_FUNC 0xf03e10 NO_FUNC 0xf02032>; - func3-en-mask = <0x01 0x20 0x20 0 - 0 0x08 0 0x01 >; - func4-gcr = <0xf03e13 NO_FUNC NO_FUNC NO_FUNC - NO_FUNC NO_FUNC NO_FUNC NO_FUNC >; - func4-en-mask = <0x01 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf0164c 0xf0164c 0xf0164c 0xf0164c - 0xf0164c 0xf0164c 0xf0164c 0xf0164c>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlf: pinctrl@f01688 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01688 8>; /* GPCR */ - func3-gcr = <0xf03e15 0xf03e15 0xf03e10 0xf03e10 - NO_FUNC NO_FUNC 0xf03e11 NO_FUNC>; - func3-en-mask = <0x04 0x08 0x02 0x02 - 0 0 0x10 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf0164d 0xf0164d 0xf0164d 0xf0164d - 0xf0164d 0xf0164d 0xf0164d 0xf0164d>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlg: pinctrl@f01690 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01690 8>; /* GPCR */ - func3-gcr = <0xf03e10 0xf03e10 0xf03e10 NO_FUNC - NO_FUNC NO_FUNC 0xf03e10 NO_FUNC>; - func3-en-mask = <0x20 0x08 0x10 0 - 0 0 0x02 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf0164e 0xf0164e 0xf0164e NO_FUNC - NO_FUNC NO_FUNC 0xf0164e NO_FUNC >; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlh: pinctrl@f01698 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01698 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0x20 0x20 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf0164f 0xf0164f 0xf0164f 0xf0164f - 0xf0164f 0xf0164f 0xf0164f NO_FUNC>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrli: pinctrl@f016a0 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a0 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0x08 0x08 0x08 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01650 0xf01650 0xf01650 0xf01650 - 0xf01650 0xf01650 0xf01650 0xf01650>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlj: pinctrl@f016a8 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a8 8>; /* GPCR */ - func3-gcr = <0xf03e14 NO_FUNC 0xf03e14 0xf03e14 - 0xf03e10 0xf03e10 NO_FUNC NO_FUNC>; - func3-en-mask = <0x01 0 0x01 0x02 - 0x02 0x03 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01651 0xf01651 0xf01651 0xf01651 - 0xf01651 0xf01651 NO_FUNC NO_FUNC >; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlk: pinctrl@f016b0 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016b0 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01652 0xf01652 0xf01652 0xf01652 - 0xf01652 0xf01652 0xf01652 0xf01652>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrll: pinctrl@f016b8 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016b8 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf01653 0xf01653 0xf01653 0xf01653 - 0xf01653 0xf01653 0xf01653 0xf01653>; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlm: pinctrl@f016c0 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016c0 8>; /* GPCR */ - func3-gcr = ; - func3-en-mask = <0 0 0 0 - 0 0 0 0 >; - func4-gcr = ; - func4-en-mask = <0 0 0 0 - 0 0 0 0 >; - volt-sel = <0xf03e2d 0xf03e2d 0xf03e2d 0xf03e2d - 0xf03e2d 0xf03e2d 0xf03e2d NO_FUNC >; - volt-sel-mask = ; - #pinmux-cells = <2>; - gpio-group; - }; - - pinctrlksi: pinctrl@f01d40 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d40 8 /* KSIGCTRL */ - 0x00f01d05 1>; /* KSICTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; - - pinctrlksol: pinctrl@f01d48 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d48 8 /* KSOLGCTRL */ - 0x00f01d02 1>; /* KSOCTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; - - pinctrlksoh: pinctrl@f01d50 { - compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01d50 8 /* KSOHGCTRL */ - 0x00f01d02 1>; /* KSOCTRL */ - pp-od-mask = ; - pullup-mask = ; - #pinmux-cells = <2>; - }; + pinctrla: pinctrl@f01660 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01660 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0x02 0x02 0x10 0x0C >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01648 0xf01648 0xf01648 0xf01648 + 0xf01648 0xf01648 0xf01648 0xf01648>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlb: pinctrl@f01668 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01668 8>; /* GPCR */ + func3-gcr = <0xf03e15 0xf03e15 0xf03e16 NO_FUNC + NO_FUNC 0xf03e16 NO_FUNC NO_FUNC>; + func3-en-mask = <0x01 0x02 0x40 0 + 0 0x40 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01649 0xf01649 0xf01649 0xf01649 + 0xf01649 0xf01649 0xf01649 NO_FUNC>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlc: pinctrl@f01670 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01670 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0x10 + 0 0x10 0 0x02 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0x80 >; + volt-sel = <0xf0164a 0xf0164a 0xf0164a 0xf0164a + 0xf0164a 0xf0164a 0xf0164a 0xf0164a>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrld: pinctrl@f01678 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01678 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x02 0 0 >; + func4-gcr = <0xf03e16 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC NO_FUNC>; + func4-en-mask = <0x80 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf0164b 0xf0164b 0xf0164b 0xf0164b + 0xf0164b 0xf0164b 0xf0164b 0xf0164b>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrle: pinctrl@f01680 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01680 8>; /* GPCR */ + func3-gcr = <0xf02032 0xf03e16 0xf03e16 NO_FUNC + NO_FUNC 0xf03e10 NO_FUNC 0xf02032>; + func3-en-mask = <0x01 0x20 0x20 0 + 0 0x08 0 0x01 >; + func4-gcr = <0xf03e13 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC NO_FUNC >; + func4-en-mask = <0x01 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf0164c 0xf0164c 0xf0164c 0xf0164c + 0xf0164c 0xf0164c 0xf0164c 0xf0164c>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlf: pinctrl@f01688 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01688 8>; /* GPCR */ + func3-gcr = <0xf03e15 0xf03e15 0xf03e10 0xf03e10 + NO_FUNC NO_FUNC 0xf03e11 NO_FUNC>; + func3-en-mask = <0x04 0x08 0x02 0x02 + 0 0 0x10 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf0164d 0xf0164d 0xf0164d 0xf0164d + 0xf0164d 0xf0164d 0xf0164d 0xf0164d>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlg: pinctrl@f01690 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01690 8>; /* GPCR */ + func3-gcr = <0xf03e10 0xf03e10 0xf03e10 NO_FUNC + NO_FUNC NO_FUNC 0xf03e10 NO_FUNC>; + func3-en-mask = <0x20 0x08 0x10 0 + 0 0 0x02 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf0164e 0xf0164e 0xf0164e NO_FUNC + NO_FUNC NO_FUNC 0xf0164e NO_FUNC >; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlh: pinctrl@f01698 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01698 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0x20 0x20 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf0164f 0xf0164f 0xf0164f 0xf0164f + 0xf0164f 0xf0164f 0xf0164f NO_FUNC>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrli: pinctrl@f016a0 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016a0 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x08 0x08 0x08 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01650 0xf01650 0xf01650 0xf01650 + 0xf01650 0xf01650 0xf01650 0xf01650>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlj: pinctrl@f016a8 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016a8 8>; /* GPCR */ + func3-gcr = <0xf03e14 NO_FUNC 0xf03e14 0xf03e14 + 0xf03e10 0xf03e10 NO_FUNC NO_FUNC>; + func3-en-mask = <0x01 0 0x01 0x02 + 0x02 0x03 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01651 0xf01651 0xf01651 0xf01651 + 0xf01651 0xf01651 NO_FUNC NO_FUNC >; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlk: pinctrl@f016b0 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016b0 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01652 0xf01652 0xf01652 0xf01652 + 0xf01652 0xf01652 0xf01652 0xf01652>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrll: pinctrl@f016b8 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016b8 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf01653 0xf01653 0xf01653 0xf01653 + 0xf01653 0xf01653 0xf01653 0xf01653>; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlm: pinctrl@f016c0 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016c0 8>; /* GPCR */ + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf03e2d 0xf03e2d 0xf03e2d 0xf03e2d + 0xf03e2d 0xf03e2d 0xf03e2d NO_FUNC >; + volt-sel-mask = ; + #pinmux-cells = <2>; + gpio-group; + }; + + pinctrlksi: pinctrl@f01d40 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d40 8 /* KSIGCTRL */ + 0x00f01d05 1>; /* KSICTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; + }; + + pinctrlksol: pinctrl@f01d48 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d48 8 /* KSOLGCTRL */ + 0x00f01d02 1>; /* KSOCTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; + }; + + pinctrlksoh: pinctrl@f01d50 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01d50 8 /* KSOHGCTRL */ + 0x00f01d02 1>; /* KSOCTRL */ + pp-od-mask = ; + pullup-mask = ; + #pinmux-cells = <2>; }; wuc1: wakeup-controller@f01b00 { From 55ae7267976c93200450860d50a8288c0329dd13 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 22:45:02 +0000 Subject: [PATCH 2611/4498] dts: psoc6: move pinctrl subdevices up a node Refactor the pinctrl nodes slightly so that the port devices are not child of the main pinctrl node. This is because the pinctrl node is being used as parent for pinctrl setting nodes itself, and having the port nodes as child end up creating a circular depdency with the edt child enumeration patch. Signed-off-by: Fabio Baltieri --- dts/arm/cypress/psoc6.dtsi | 312 +++++++++--------- dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi | 283 ++++++++-------- 2 files changed, 298 insertions(+), 297 deletions(-) diff --git a/dts/arm/cypress/psoc6.dtsi b/dts/arm/cypress/psoc6.dtsi index 4fc63f4b46f..a6ab61e9949 100644 --- a/dts/arm/cypress/psoc6.dtsi +++ b/dts/arm/cypress/psoc6.dtsi @@ -71,164 +71,164 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x40310000 0x40310000 0x2024>; + }; - hsiom: hsiom@40310000 { - compatible = "cypress,psoc6-hsiom"; - reg = <0x40310000 0x2024>; - interrupts = <15 1>, <16 1>; - status = "disabled"; - }; + hsiom: hsiom@40310000 { + compatible = "cypress,psoc6-hsiom"; + reg = <0x40310000 0x2024>; + interrupts = <15 1>, <16 1>; + status = "disabled"; + }; - gpio_prt0: gpio@40320000 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320000 0x80>; - interrupts = <0 1>; - gpio-controller; - ngpios = <6>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt1: gpio@40320080 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320080 0x80>; - interrupts = <1 1>; - gpio-controller; - ngpios = <6>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt2: gpio@40320100 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320100 0x80>; - interrupts = <2 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt3: gpio@40320180 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320180 0x80>; - interrupts = <3 1>; - gpio-controller; - ngpios = <6>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt4: gpio@40320200 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320200 0x80>; - interrupts = <4 1>; - gpio-controller; - ngpios = <4>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt5: gpio@40320280 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320280 0x80>; - interrupts = <5 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt6: gpio@40320300 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320300 0x80>; - interrupts = <6 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt7: gpio@40320380 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320380 0x80>; - interrupts = <7 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt8: gpio@40320400 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320400 0x80>; - interrupts = <8 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt9: gpio@40320480 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320480 0x80>; - interrupts = <9 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt10: gpio@40320500 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320500 0x80>; - interrupts = <10 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt11: gpio@40320580 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320580 0x80>; - interrupts = <11 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt12: gpio@40320600 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320600 0x80>; - interrupts = <12 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt13: gpio@40320680 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320680 0x80>; - interrupts = <13 1>; - gpio-controller; - ngpios = <8>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; - gpio_prt14: gpio@40320700 { - compatible = "cypress,psoc6-gpio"; - reg = <0x40320700 0x80>; - interrupts = <14 1>; - gpio-controller; - ngpios = <2>; - #gpio-cells = <2>; - #cypress,pin-cells = <2>; - status = "disabled"; - }; + gpio_prt0: gpio@40320000 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320000 0x80>; + interrupts = <0 1>; + gpio-controller; + ngpios = <6>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt1: gpio@40320080 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320080 0x80>; + interrupts = <1 1>; + gpio-controller; + ngpios = <6>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt2: gpio@40320100 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320100 0x80>; + interrupts = <2 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt3: gpio@40320180 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320180 0x80>; + interrupts = <3 1>; + gpio-controller; + ngpios = <6>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt4: gpio@40320200 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320200 0x80>; + interrupts = <4 1>; + gpio-controller; + ngpios = <4>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt5: gpio@40320280 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320280 0x80>; + interrupts = <5 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt6: gpio@40320300 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320300 0x80>; + interrupts = <6 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt7: gpio@40320380 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320380 0x80>; + interrupts = <7 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt8: gpio@40320400 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320400 0x80>; + interrupts = <8 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt9: gpio@40320480 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320480 0x80>; + interrupts = <9 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt10: gpio@40320500 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320500 0x80>; + interrupts = <10 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt11: gpio@40320580 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320580 0x80>; + interrupts = <11 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt12: gpio@40320600 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320600 0x80>; + interrupts = <12 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt13: gpio@40320680 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320680 0x80>; + interrupts = <13 1>; + gpio-controller; + ngpios = <8>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; + }; + gpio_prt14: gpio@40320700 { + compatible = "cypress,psoc6-gpio"; + reg = <0x40320700 0x80>; + interrupts = <14 1>; + gpio-controller; + ngpios = <2>; + #gpio-cells = <2>; + #cypress,pin-cells = <2>; + status = "disabled"; }; spi0: spi@40610000 { diff --git a/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi b/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi index 0a97178cfad..4f3b420d3e5 100644 --- a/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi +++ b/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi @@ -55,150 +55,151 @@ reg = <0x40310000 0x20000>; #address-cells = <1>; #size-cells = <0>; + }; - hsiom: hsiom@40310000 { - compatible = "infineon,cat1-hsiom"; - reg = <0x40310000 0x4000>; - interrupts = <15 6>, <16 6>; - status = "disabled"; - }; + hsiom: hsiom@40310000 { + compatible = "infineon,cat1-hsiom"; + reg = <0x40310000 0x4000>; + interrupts = <15 6>, <16 6>; + status = "disabled"; + }; - gpio_prt0: gpio@40320000 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320000 0x80>; - interrupts = <0 6>; - gpio-controller; - ngpios = <6>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt1: gpio@40320080 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320080 0x80>; - interrupts = <1 6>; - gpio-controller; - ngpios = <6>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt2: gpio@40320100 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320100 0x80>; - interrupts = <2 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt3: gpio@40320180 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320180 0x80>; - interrupts = <3 6>; - gpio-controller; - ngpios = <6>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt4: gpio@40320200 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320200 0x80>; - interrupts = <4 6>; - gpio-controller; - ngpios = <2>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt5: gpio@40320280 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320280 0x80>; - interrupts = <5 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt6: gpio@40320300 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320300 0x80>; - interrupts = <6 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt7: gpio@40320380 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320380 0x80>; - interrupts = <7 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt8: gpio@40320400 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320400 0x80>; - interrupts = <8 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt9: gpio@40320480 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320480 0x80>; - interrupts = <9 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt10: gpio@40320500 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320500 0x80>; - interrupts = <10 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt11: gpio@40320580 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320580 0x80>; - interrupts = <11 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt12: gpio@40320600 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320600 0x80>; - interrupts = <12 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt13: gpio@40320680 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320680 0x80>; - interrupts = <13 6>; - gpio-controller; - ngpios = <8>; - status = "disabled"; - #gpio-cells = <2>; - }; - gpio_prt14: gpio@40320700 { - compatible = "infineon,cat1-gpio"; - reg = <0x40320700 0x80>; - interrupts = <14 6>; - gpio-controller; - ngpios = <2>; - status = "disabled"; - #gpio-cells = <2>; - }; + gpio_prt0: gpio@40320000 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320000 0x80>; + interrupts = <0 6>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt1: gpio@40320080 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320080 0x80>; + interrupts = <1 6>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt2: gpio@40320100 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320100 0x80>; + interrupts = <2 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt3: gpio@40320180 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320180 0x80>; + interrupts = <3 6>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt4: gpio@40320200 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320200 0x80>; + interrupts = <4 6>; + gpio-controller; + ngpios = <2>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt5: gpio@40320280 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320280 0x80>; + interrupts = <5 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt6: gpio@40320300 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320300 0x80>; + interrupts = <6 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt7: gpio@40320380 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320380 0x80>; + interrupts = <7 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt8: gpio@40320400 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320400 0x80>; + interrupts = <8 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt9: gpio@40320480 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320480 0x80>; + interrupts = <9 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt10: gpio@40320500 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320500 0x80>; + interrupts = <10 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt11: gpio@40320580 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320580 0x80>; + interrupts = <11 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt12: gpio@40320600 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320600 0x80>; + interrupts = <12 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt13: gpio@40320680 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320680 0x80>; + interrupts = <13 6>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + gpio_prt14: gpio@40320700 { + compatible = "infineon,cat1-gpio"; + reg = <0x40320700 0x80>; + interrupts = <14 6>; + gpio-controller; + ngpios = <2>; + status = "disabled"; + #gpio-cells = <2>; }; + uid: device_uid@16000600 { compatible = "infineon,cat1-uid"; reg = <0x16000600 0xb>; From 403640b75e838741ee408147c77c2c47a35f036b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 6 Sep 2023 15:22:43 +0000 Subject: [PATCH 2612/4498] edtlib: link child nodes to parent for nodes with child-bindings The current EDT graph logic only use properties directly under a specific node to add dependencies. For nodes properties in child-bindings, this means that the child phandles are only linked by the child node itself, which does have an ordinal but no corresponding "sturct device" in the code, causing those dependencies to be silently ignored by gen_handles.py. Fix that by adding the recursive logic to visit child bindings when present, which causes all child node property handles to be linked to the parent node. Signed-off-by: Fabio Baltieri --- .../src/devicetree/edtlib.py | 75 +++++++++++++------ .../tests/test-bindings/child-binding.yaml | 4 + scripts/dts/python-devicetree/tests/test.dts | 5 ++ .../python-devicetree/tests/test_edtlib.py | 14 ++++ 4 files changed, 74 insertions(+), 24 deletions(-) diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 0eb8dd832d1..851706790b9 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -2052,6 +2052,56 @@ def scc_order(self) -> List[List[Node]]: except Exception as e: raise EDTError(e) + def _process_properties_r(self, root_node, props_node): + """ + Process props_node properties for dependencies, and add those as + dependencies of root_node. Then walk through all the props_node + children and do the same recursively, maintaining the same root_node. + + This ensures that on a node with child nodes, the parent node includes + the dependencies of all the child nodes as well as its own. + """ + # A Node depends on any Nodes present in 'phandle', + # 'phandles', or 'phandle-array' property values. + for prop in props_node.props.values(): + if prop.type == 'phandle': + self._graph.add_edge(root_node, prop.val) + elif prop.type == 'phandles': + if TYPE_CHECKING: + assert isinstance(prop.val, list) + for phandle_node in prop.val: + self._graph.add_edge(root_node, phandle_node) + elif prop.type == 'phandle-array': + if TYPE_CHECKING: + assert isinstance(prop.val, list) + for cd in prop.val: + if cd is None: + continue + if TYPE_CHECKING: + assert isinstance(cd, ControllerAndData) + self._graph.add_edge(root_node, cd.controller) + + # A Node depends on whatever supports the interrupts it + # generates. + for intr in props_node.interrupts: + self._graph.add_edge(root_node, intr.controller) + + # If the binding defines child bindings, link the child properties to + # the root_node as well. + if props_node._binding and props_node._binding.child_binding: + for child in props_node.children.values(): + if "compatible" in child.props: + # Not a child node, normal node on a different binding. + continue + self._process_properties_r(root_node, child) + + def _process_properties(self, node): + """ + Add node dependencies based on own as well as child node properties, + start from the node itself. + """ + self._process_properties_r(node, node) + def _init_graph(self) -> None: # Constructs a graph of dependencies between Node instances, # which is usable for computing a partial order over the dependencies. @@ -2069,30 +2119,7 @@ def _init_graph(self) -> None: for child in node.children.values(): self._graph.add_edge(child, node) - # A Node depends on any Nodes present in 'phandle', - # 'phandles', or 'phandle-array' property values. - for prop in node.props.values(): - if prop.type == 'phandle': - self._graph.add_edge(node, prop.val) - elif prop.type == 'phandles': - if TYPE_CHECKING: - assert isinstance(prop.val, list) - for phandle_node in prop.val: - self._graph.add_edge(node, phandle_node) - elif prop.type == 'phandle-array': - if TYPE_CHECKING: - assert isinstance(prop.val, list) - for cd in prop.val: - if cd is None: - continue - if TYPE_CHECKING: - assert isinstance(cd, ControllerAndData) - self._graph.add_edge(node, cd.controller) - - # A Node depends on whatever supports the interrupts it - # generates. - for intr in node.interrupts: - self._graph.add_edge(node, intr.controller) + self._process_properties(node) def _init_compat2binding(self) -> None: # Creates self._compat2binding, a dictionary that maps diff --git a/scripts/dts/python-devicetree/tests/test-bindings/child-binding.yaml b/scripts/dts/python-devicetree/tests/test-bindings/child-binding.yaml index e0af091b10e..7b1334954ee 100644 --- a/scripts/dts/python-devicetree/tests/test-bindings/child-binding.yaml +++ b/scripts/dts/python-devicetree/tests/test-bindings/child-binding.yaml @@ -10,6 +10,8 @@ child-binding: child-prop: type: int required: true + child-ref: + type: phandle child-binding: description: grandchild node @@ -17,3 +19,5 @@ child-binding: grandchild-prop: type: int required: true + grandchild-ref: + type: phandle diff --git a/scripts/dts/python-devicetree/tests/test.dts b/scripts/dts/python-devicetree/tests/test.dts index 35f0f253ce7..213d5d45dfe 100644 --- a/scripts/dts/python-devicetree/tests/test.dts +++ b/scripts/dts/python-devicetree/tests/test.dts @@ -470,16 +470,21 @@ // 'child-binding:') // + child-binding-dep { + }; + child-binding { compatible = "top-binding"; child-1 { child-prop = <1>; grandchild { grandchild-prop = <2>; + grandchild-ref = < &{/child-binding-dep} >; }; }; child-2 { child-prop = <3>; + child-ref = < &{/child-binding-dep} >; }; }; diff --git a/scripts/dts/python-devicetree/tests/test_edtlib.py b/scripts/dts/python-devicetree/tests/test_edtlib.py index 9983e1caf01..ca97fbcb9c2 100644 --- a/scripts/dts/python-devicetree/tests/test_edtlib.py +++ b/scripts/dts/python-devicetree/tests/test_edtlib.py @@ -627,6 +627,20 @@ def test_dependencies(): assert edt.get_node("/") in edt.get_node("/in-dir-1").depends_on assert edt.get_node("/in-dir-1") in edt.get_node("/").required_by +def test_child_dependencies(): + '''Test dependencies relashionship with child nodes propagated to parent''' + with from_here(): + edt = edtlib.EDT("test.dts", ["test-bindings"]) + + dep_node = edt.get_node("/child-binding-dep") + + assert dep_node in edt.get_node("/child-binding").depends_on + assert dep_node in edt.get_node("/child-binding/child-1/grandchild").depends_on + assert dep_node in edt.get_node("/child-binding/child-2").depends_on + assert edt.get_node("/child-binding") in dep_node.required_by + assert edt.get_node("/child-binding/child-1/grandchild") in dep_node.required_by + assert edt.get_node("/child-binding/child-2") in dep_node.required_by + def test_slice_errs(tmp_path): '''Test error messages from the internal _slice() helper''' From 73d5ecc0c5f5dbb4f237b9eeeae84aabfd0dbbb8 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 7 Sep 2023 16:27:32 +0000 Subject: [PATCH 2613/4498] scripts: check_init_priorities: drop recursive child parsing Now that child nodes are handled by edtlib there's no need to parse child nodes in check_init_priorities anymore. Signed-off-by: Fabio Baltieri --- scripts/build/check_init_priorities.py | 15 +------ scripts/build/check_init_priorities_test.py | 48 ++++++--------------- 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 582d7dd0e88..88f7f310040 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -286,23 +286,12 @@ def _check_dep(self, dev_ord, dep_ord): self.log.info( f"{dev_node.path} {dev_prio} > {dep_node.path} {dep_prio}") - def _check_edt_r(self, dev_ord, dev): - """Recursively check for dependencies of a device.""" - for dep in dev.depends_on: - self._check_dep(dev_ord, dep.dep_ordinal) - if dev._binding and dev._binding.child_binding: - for child in dev.children.values(): - if "compatible" in child.props: - continue - if dev._binding.path != child._binding.path: - continue - self._check_edt_r(dev_ord, child) - def check_edt(self): """Scan through all known devices and validate the init priorities.""" for dev_ord in self._obj.devices: dev = self._ord2node[dev_ord] - self._check_edt_r(dev_ord, dev) + for dep in dev.depends_on: + self._check_dep(dev_ord, dep.dep_ordinal) def print_initlevels(self): for level, calls in self._obj.initlevels.items(): diff --git a/scripts/build/check_init_priorities_test.py b/scripts/build/check_init_priorities_test.py index 6e404221194..9783e5d828e 100755 --- a/scripts/build/check_init_priorities_test.py +++ b/scripts/build/check_init_priorities_test.py @@ -381,52 +381,32 @@ def test_check_ignored(self, mock_vinit): @mock.patch("check_init_priorities.Validator._check_dep") @mock.patch("check_init_priorities.Validator.__init__", return_value=None) - def test_check_edt_r(self, mock_vinit, mock_cd): - validator = check_init_priorities.Validator("", "", None) - + def test_check_edt(self, mock_vinit, mock_cd): d0 = mock.Mock() d0.dep_ordinal = 1 d1 = mock.Mock() d1.dep_ordinal = 2 + d2 = mock.Mock() + d2.dep_ordinal = 3 - c0 = mock.Mock() - c0.props = {"compatible": "c"} - c1 = mock.Mock() - c1.props = {} - c1._binding.path = "another-binding-path.yaml" - c2 = mock.Mock() - c2.props = {} - c2._binding.path = "binding-path.yaml" - c2._binding.child_binding = None - c2.depends_on = [d1] - - dev = mock.Mock() - dev.depends_on = [d0] - dev._binding.child_binding = "child-binding" - dev._binding.path = "binding-path.yaml" - dev.children.values.return_value = [c0, c1, c2] - - validator._check_edt_r(0, dev) - - self.assertListEqual(mock_cd.call_args_list, [ - mock.call(0, 1), - mock.call(0, 2), - ]) + dev0 = mock.Mock() + dev0.depends_on = [d0] + dev1 = mock.Mock() + dev1.depends_on = [d1] + dev2 = mock.Mock() + dev2.depends_on = [d2] - @mock.patch("check_init_priorities.Validator._check_edt_r") - @mock.patch("check_init_priorities.Validator.__init__", return_value=None) - def test_check_edt(self, mock_vinit, mock_cer): validator = check_init_priorities.Validator("", "", None) - validator._ord2node = {1: mock.Mock(), 2: mock.Mock(), 3: mock.Mock()} + validator._ord2node = {1: dev0, 2: dev1, 3: dev2} validator._obj = mock.Mock() validator._obj.devices = {1: 10, 2: 10, 3: 20} validator.check_edt() - self.assertListEqual(mock_cer.call_args_list, [ - mock.call(1, validator._ord2node[1]), - mock.call(2, validator._ord2node[2]), - mock.call(3, validator._ord2node[3]), + self.assertListEqual(mock_cd.call_args_list, [ + mock.call(1, 1), + mock.call(2, 2), + mock.call(3, 3), ]) if __name__ == "__main__": From 3be5732a68365ee3f301a8a9bb489141d814cf6a Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 23 Oct 2023 15:24:31 -0700 Subject: [PATCH 2614/4498] west: sign/rimage: skip extended manifest when !SOF Non-SOF build does not have extended manifest data for rimage to process, which might result in rimage error. So do not do extended manifest during signing when not doing SOF builds. Signed-off-by: Daniel Leung --- scripts/west_commands/sign.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/west_commands/sign.py b/scripts/west_commands/sign.py index 2c2692c55d2..87b8346884f 100644 --- a/scripts/west_commands/sign.py +++ b/scripts/west_commands/sign.py @@ -517,6 +517,13 @@ def sign(self, command, build_dir, build_conf, formats): else: no_manifest = False + # Non-SOF build does not have extended manifest data for + # rimage to process, which might result in rimage error. + # So skip it when not doing SOF builds. + is_sof_build = build_conf.getboolean('CONFIG_SOF') + if not is_sof_build: + no_manifest = True + if no_manifest: extra_ri_args = [ ] else: From 4201978f3494f26b73849502370883b4d6c92d55 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 23 Oct 2023 15:26:22 -0700 Subject: [PATCH 2615/4498] manifest: sof: update to commit e7cb489d4 This updates SOF modules to commit e7cb489d430dc2181e4a5f7f953ed1eaeec6668d. This includes a change where rimage is pulled into the tree and is no longer a submodule. So update the rimage config path so signing still works. Signed-off-by: Daniel Leung --- scripts/west_commands/runners/intel_adsp.py | 2 +- scripts/west_commands/sign.py | 2 +- submanifests/optional.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/west_commands/runners/intel_adsp.py b/scripts/west_commands/runners/intel_adsp.py index 4a0c83c2f2c..cbaa106020d 100644 --- a/scripts/west_commands/runners/intel_adsp.py +++ b/scripts/west_commands/runners/intel_adsp.py @@ -16,7 +16,7 @@ DEFAULT_CAVSTOOL='soc/xtensa/intel_adsp/tools/cavstool_client.py' DEFAULT_SOF_MOD_DIR=os.path.join(ZEPHYR_BASE, '../modules/audio/sof') DEFAULT_RIMAGE_TOOL=shutil.which('rimage') -DEFAULT_CONFIG_DIR=os.path.join(DEFAULT_SOF_MOD_DIR, 'rimage/config') +DEFAULT_CONFIG_DIR=os.path.join(DEFAULT_SOF_MOD_DIR, 'tools/rimage/config') DEFAULT_KEY_DIR=os.path.join(DEFAULT_SOF_MOD_DIR, 'keys') diff --git a/scripts/west_commands/sign.py b/scripts/west_commands/sign.py index 87b8346884f..bdf9d353685 100644 --- a/scripts/west_commands/sign.py +++ b/scripts/west_commands/sign.py @@ -502,7 +502,7 @@ def sign(self, command, build_dir, build_conf, formats): elif cache.get('RIMAGE_CONFIG_PATH'): conf_dir = pathlib.Path(cache['RIMAGE_CONFIG_PATH']) else: - conf_dir = sof_src_dir / 'rimage' / 'config' + conf_dir = sof_src_dir / 'tools' / 'rimage' / 'config' conf_path_cmd = ['-c', str(conf_dir / cmake_toml)] if conf_dir else [] diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index b6a913c41ac..dbcfc363737 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -28,7 +28,7 @@ manifest: groups: - optional - name: sof - revision: c0f20b69daa44e3563f970b366e49ccfcfa1b71c + revision: e7cb489d430dc2181e4a5f7f953ed1eaeec6668d path: modules/audio/sof remote: upstream groups: From bf598848b13a9957bc8e037a4efc7b37b4b97ddd Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 25 Oct 2023 12:39:42 +0200 Subject: [PATCH 2616/4498] scripts: west: commands: tests: dfu_util: fix test under Python 3.12 Use "call_args_list" from unittest.mock instead of "called_with" for verifying the arguments supplied to the dfu-util west runner. This aligns the assert with the rest of the test case and fixes the dfu-util west runner test when running under Python 3.12. Signed-off-by: Henrik Brix Andersen --- scripts/west_commands/tests/test_dfu_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/tests/test_dfu_util.py b/scripts/west_commands/tests/test_dfu_util.py index 9ae4b1ce99b..a28522cd81b 100644 --- a/scripts/west_commands/tests/test_dfu_util.py +++ b/scripts/west_commands/tests/test_dfu_util.py @@ -86,7 +86,7 @@ def test_dfu_util_init(cc, req, find_device, tc, runner_config): with patch('os.path.isfile', side_effect=os_path_isfile_patch): runner.run('flash') assert find_device.called - assert req.called_with(exe) + assert req.call_args_list == [call(exe)] assert cc.call_args_list == [call(EXPECTED_COMMAND[tc])] def get_flash_address_patch(args, bcfg): @@ -141,5 +141,5 @@ def test_dfu_util_create(cc, req, gfa, find_device, tc, runner_config, tmpdir): cfg = None map_tc = (exe or DFU_UTIL, alt, cfg, img or RC_KERNEL_BIN) assert find_device.called - assert req.called_with(exe) + assert req.call_args_list == [call(exe or DFU_UTIL)] assert cc.call_args_list == [call(EXPECTED_COMMAND[map_tc])] From 9b851b2ab813b0bca588f0afeff7d5e878c0e789 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 25 Oct 2023 10:20:27 +0200 Subject: [PATCH 2617/4498] ci: test using Python 3.12 as well Run CI tests against Python v3.12 as well. Signed-off-by: Henrik Brix Andersen --- .github/workflows/devicetree_checks.yml | 2 +- .github/workflows/pylib_tests.yml | 2 +- .github/workflows/scripts_tests.yml | 2 +- .github/workflows/twister_tests.yml | 2 +- .github/workflows/twister_tests_blackbox.yml | 2 +- .github/workflows/west_cmds.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index ac94b532070..b2d73453b28 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -26,7 +26,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-22.04, macos-11, windows-2022] exclude: - os: macos-11 diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml index 79d83b64df5..4368a66d04f 100644 --- a/.github/workflows/pylib_tests.yml +++ b/.github/workflows/pylib_tests.yml @@ -25,7 +25,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-22.04] steps: - name: checkout diff --git a/.github/workflows/scripts_tests.yml b/.github/workflows/scripts_tests.yml index 9804c388f1c..7c1a2887ae6 100644 --- a/.github/workflows/scripts_tests.yml +++ b/.github/workflows/scripts_tests.yml @@ -25,7 +25,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-20.04] steps: - name: checkout diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index 570d5efcb97..db26f055e18 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -29,7 +29,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-22.04] steps: - name: checkout diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index a35f571e80c..a18f79ae455 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-22.04] container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index c2502469541..4a3c1964643 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -27,7 +27,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] os: [ubuntu-22.04, macos-11, windows-2022] exclude: - os: macos-11 From c8df08d681fe3529c509daa4af84ac572e46dd84 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 20 Sep 2023 20:32:36 +1000 Subject: [PATCH 2618/4498] scripts: kconfig: kconfiglib: cleanup pylint errors Cleanup pylint errors that otherwise cause future commits to fail. Signed-off-by: Jordan Yates --- scripts/kconfig/kconfiglib.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/kconfig/kconfiglib.py b/scripts/kconfig/kconfiglib.py index 75ff3c1ee9a..1f52fc700aa 100644 --- a/scripts/kconfig/kconfiglib.py +++ b/scripts/kconfig/kconfiglib.py @@ -2928,7 +2928,7 @@ def _parse_block(self, end_token, parent, prev): node = MenuNode() node.kconfig = self node.item = sym - node.is_menuconfig = (t0 is _T_MENUCONFIG) + node.is_menuconfig = t0 is _T_MENUCONFIG node.prompt = node.help = node.list = None node.parent = parent node.filename = self.filename @@ -4307,7 +4307,7 @@ def str_value(self): # function call (property magic) vis = self.visibility - self._write_to_conf = (vis != 0) + self._write_to_conf = vis != 0 if self.orig_type in _INT_HEX: # The C implementation checks the user value against the range in a @@ -4445,7 +4445,7 @@ def tri_value(self): # Warning: See Symbol._rec_invalidate(), and note that this is a hidden # function call (property magic) vis = self.visibility - self._write_to_conf = (vis != 0) + self._write_to_conf = vis != 0 val = 0 From 79e467c92af38af545fb218bc5de7ab8bd4659ca Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 16 Oct 2022 14:18:34 +1000 Subject: [PATCH 2619/4498] scripts: kconfig: kconfiglib: introduce `configdefault` Introduce the `configdefault` keyword as a Kconfig extension. This new keyword allows `default` values to be applied to externally defined symbols without needing to respecify dependencies, or weakening the existing dependencies. This is primarily useful in downstream repositories that wish to define default configurations such as: ``` config MY_COMPANY_APPS bool "Apply defaults for internal applications" configdefault BT default y if MY_COMPANY_APPS configdefault MCUMGR default y if MY_COMPANY_APPS && BT ``` Obtaining the same functionality with `config` (without weakening the symbol dependencies) requires finding the original definition and duplicating any `depends on` and surrounding `if` statements. This is a non-trivial exercise that needs to be manually rechecked on each Zephyr update. `configdefault` simplifies this process by acting as if the `default` statement was present at any one of the original definitions of the symbol. Signed-off-by: Jordan Yates --- scripts/kconfig/kconfiglib.py | 55 ++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/scripts/kconfig/kconfiglib.py b/scripts/kconfig/kconfiglib.py index 1f52fc700aa..bd541d07b42 100644 --- a/scripts/kconfig/kconfiglib.py +++ b/scripts/kconfig/kconfiglib.py @@ -1096,6 +1096,8 @@ def _init(self, filename, warn, warn_to_stderr, encoding): # Do various menu tree post-processing self._finalize_node(self.top_node, self.y) + for s in self.syms.values(): + self._finalize_sym(s) self.unique_defined_syms = _ordered_unique(self.defined_syms) self.unique_choices = _ordered_unique(self.choices) @@ -2305,6 +2307,7 @@ def _lookup_sym(self, name): sym.kconfig = self sym.name = name sym.is_constant = False + sym.configdefaults = [] sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n if self._parsing_kconfigs: @@ -2324,6 +2327,7 @@ def _lookup_const_sym(self, name): sym.kconfig = self sym.name = name sym.is_constant = True + sym.configdefaults = [] sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n if self._parsing_kconfigs: @@ -2913,7 +2917,7 @@ def _parse_block(self, end_token, parent, prev): while self._next_line(): t0 = self._tokens[0] - if t0 is _T_CONFIG or t0 is _T_MENUCONFIG: + if t0 in [_T_CONFIG, _T_MENUCONFIG, _T_CONFIGDEFAULT]: # The tokenizer allocates Symbol objects for us sym = self._tokens[1] @@ -2929,6 +2933,7 @@ def _parse_block(self, end_token, parent, prev): node.kconfig = self node.item = sym node.is_menuconfig = t0 is _T_MENUCONFIG + node.is_configdefault = t0 is _T_CONFIGDEFAULT node.prompt = node.help = node.list = None node.parent = parent node.filename = self.filename @@ -2939,6 +2944,14 @@ def _parse_block(self, end_token, parent, prev): self._parse_props(node) + if node.is_configdefault: + if (node.prompt or + node.dep != self.y or + len(node.ranges) > 0 or + len(node.selects) > 0 or + len(node.implies) > 0): + self._parse_error("configdefault can only contain `default`") + if node.is_menuconfig and not node.prompt: self._warn("the menuconfig symbol {} has no prompt" .format(sym.name_and_loc)) @@ -3551,6 +3564,23 @@ def _invalidate_all(self): # Post-parsing menu tree processing, including dependency propagation and # implicit submenu creation # + def _finalize_sym(self, sym): + # Finalizes symbol definitions + # + # - Applies configdefault node defaults to final symbols + # + # sym: + # The symbol to finalize. + + inserted = 0 + for (idx, defaults) in sym.configdefaults: + for d in defaults: + # Add the defaults to the node, with the requirement that + # direct dependencies are respected. The original order + # of the default statements between nodes is preserved. + default = (d[0], self._make_and(sym.direct_dep, d[1])) + sym.defaults.insert(inserted + idx, default) + inserted += 1 def _finalize_node(self, node, visible_if): # Finalizes a menu node and its children: @@ -3697,6 +3727,14 @@ def _add_props_to_sym(self, node): sym = node.item + if node.is_configdefault: + # Store any defaults for later application after the complete tree + # is known. The current length of of the default array is stored so + # the configdefaults can be inserted in the order they originally + # appeared. + sym.configdefaults.append((len(sym.defaults), node.defaults)) + return + # See the Symbol class docstring sym.direct_dep = self._make_or(sym.direct_dep, node.dep) @@ -4249,6 +4287,7 @@ class Symbol(object): "_write_to_conf", "choice", "defaults", + "configdefaults", "direct_dep", "env_var", "implies", @@ -5613,6 +5652,7 @@ class MenuNode(object): "help", "include_path", "is_menuconfig", + "is_configdefault", "item", "kconfig", "linenr", @@ -5814,8 +5854,13 @@ def indent_add_cond(s, cond): sc = self.item if sc.__class__ is Symbol: - lines = [("menuconfig " if self.is_menuconfig else "config ") - + sc.name] + if self.is_menuconfig: + t = "menuconfig " + elif self.is_configdefault: + t = "configdefault " + else: + t = "config " + lines = [t + sc.name] else: lines = ["choice " + sc.name if sc.name else "choice"] @@ -6860,6 +6905,7 @@ def _shell_fn(kconf, _, command): _T_CLOSE_PAREN, _T_COMMENT, _T_CONFIG, + _T_CONFIGDEFAULT, _T_DEFAULT, _T_DEFCONFIG_LIST, _T_DEF_BOOL, @@ -6903,7 +6949,7 @@ def _shell_fn(kconf, _, command): _T_TRISTATE, _T_UNEQUAL, _T_VISIBLE, -) = range(1, 51) +) = range(1, 52) # Keyword to token map, with the get() method assigned directly as a small # optimization @@ -6915,6 +6961,7 @@ def _shell_fn(kconf, _, command): "choice": _T_CHOICE, "comment": _T_COMMENT, "config": _T_CONFIG, + "configdefault": _T_CONFIGDEFAULT, "def_bool": _T_DEF_BOOL, "def_hex": _T_DEF_HEX, "def_int": _T_DEF_INT, From cea39d4383bbe4fb32b51b21735af33267666ce0 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 16 Oct 2022 14:47:50 +1000 Subject: [PATCH 2620/4498] tests: kconfig: test configdefault extension Test the behaviour of the `configdefault` kconfig extension. Signed-off-by: Jordan Yates --- tests/kconfig/configdefault/CMakeLists.txt | 8 + tests/kconfig/configdefault/Kconfig | 259 +++++++++++++++++++++ tests/kconfig/configdefault/prj.conf | 2 + tests/kconfig/configdefault/src/main.c | 52 +++++ tests/kconfig/configdefault/testcase.yaml | 3 + 5 files changed, 324 insertions(+) create mode 100644 tests/kconfig/configdefault/CMakeLists.txt create mode 100644 tests/kconfig/configdefault/Kconfig create mode 100644 tests/kconfig/configdefault/prj.conf create mode 100644 tests/kconfig/configdefault/src/main.c create mode 100644 tests/kconfig/configdefault/testcase.yaml diff --git a/tests/kconfig/configdefault/CMakeLists.txt b/tests/kconfig/configdefault/CMakeLists.txt new file mode 100644 index 00000000000..93e45bf9ce9 --- /dev/null +++ b/tests/kconfig/configdefault/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(kconfig_configdefault) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kconfig/configdefault/Kconfig b/tests/kconfig/configdefault/Kconfig new file mode 100644 index 00000000000..7c19c642bbe --- /dev/null +++ b/tests/kconfig/configdefault/Kconfig @@ -0,0 +1,259 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2022 CSIRO + +config DEP_Y + bool "Dependency that evaluates to enabled" + default y + +config DEP_N + bool "Dependency that evaluates to disabled" + default n + +# configdefault after main def +config SYM_Y_1 + bool "SYM Y 1" + +configdefault SYM_Y_1 + default y if DEP_Y + +config SYM_N_1 + bool "SYM N 1" + +configdefault SYM_N_1 + default y if DEP_N + +# configdefault before main def +configdefault SYM_Y_2 + default y if DEP_Y + +config SYM_Y_2 + bool "SYM Y 2" + +configdefault SYM_N_2 + default y if DEP_N + +config SYM_N_2 + bool "SYM N 2" + +# configdefaults with multiple defaults +configdefault SYM_Y_3 + default y if DEP_Y + default y if DEP_N + +config SYM_Y_3 + bool "SYM Y 3" + +configdefault SYM_N_3 + default y if DEP_N + default y if DEP_N + +config SYM_N_3 + bool "SYM N 3" + +# multiple configdefaults +configdefault SYM_Y_4 + default y if DEP_Y +configdefault SYM_Y_4 + default y if DEP_N + +config SYM_Y_4 + bool "SYM Y 4" + +configdefault SYM_N_4 + default y if DEP_N +configdefault SYM_N_4 + default y if DEP_N + +config SYM_N_4 + bool "SYM N 4" + +# if surrounding configdefault +config SYM_Y_5 + bool "SYM Y 5" +if DEP_Y +configdefault SYM_Y_5 + default y +endif + +config SYM_N_5 + bool "SYM N 5" +if DEP_N +configdefault SYM_N_5 + default y +endif + +# if surrounding definition +if DEP_Y +config SYM_Y_6 + bool "SYM Y 6" +endif + +configdefault SYM_Y_6 + default y + +if DEP_N +config SYM_N_6 + bool "SYM N 6" +endif + +configdefault SYM_N_6 + default y + +# if surrounding complete +if DEP_Y +config SYM_Y_7 + bool "SYM Y 7" +configdefault SYM_Y_7 + default y +endif + +if DEP_N +config SYM_N_7 + bool "SYM N 7" +configdefault SYM_N_7 + default y +endif + +# configdefault default symbol +config SYM_Y_8 + bool "SYM Y 8" + +configdefault SYM_Y_8 + default DEP_Y + +config SYM_N_8 + bool "SYM N 8" + +configdefault SYM_N_8 + default DEP_N + +# configdefault with "prompt if " +configdefault SYM_Y_9 + default y + +config SYM_Y_9 + bool "SYM Y 9" if DEP_Y + default y if DEP_N + +configdefault SYM_N_9 + default n if DEP_Y + +config SYM_N_9 + bool "SYM N 9" if DEP_Y + default y + +# configdefault with "prompt if " +configdefault SYM_Y_10 + default y if DEP_Y + +config SYM_Y_10 + bool "SYM Y 10" if DEP_N + +configdefault SYM_N_10 + default n if DEP_Y + +config SYM_N_10 + bool "SYM N 10" if DEP_N + default y + +# configdefault with "prompt if " and surrounding 'if' +configdefault SYM_Y_11 + default y + +if DEP_Y +config SYM_Y_11 + bool "SYM Y 11" if DEP_Y + default y if DEP_N +endif + +configdefault SYM_N_11 + default y + +if DEP_N +config SYM_N_11 + bool "SYM N 11" if DEP_Y + default n if DEP_N +endif + +# Multiple symbols, no configdefault effect +configdefault SYM_Y_12 + default y if DEP_N + +config SYM_Y_12 + bool "SYM Y 12" + default y if DEP_N + depends on DEP_N + +config SYM_Y_12 + default y + +configdefault SYM_N_12 + default y if DEP_N + +config SYM_N_12 + bool "SYM N 12" + default y if DEP_N + +config SYM_N_12 + default n + +# configdefault does not define integer +config SYM_INT_UNDEF + int "Undefined integer" + default 0 + depends on DEP_N + +configdefault SYM_INT_UNDEF + default 1 + +# Integer default +config SYM_INT_1 + int "Int 1" + depends on DEP_Y + +configdefault SYM_INT_1 + default 1 + +# configdefault doesn't overwrite ordering +config SYM_INT_2 + int "Int 2" + default 2 + +configdefault SYM_INT_2 + default 3 + +configdefault SYM_INT_3 + default 3 + +configdefault SYM_INT_3 + default 4 + +config SYM_INT_3 + int "Int 3" + default 2 + +configdefault SYM_INT_4 + default 3 if DEP_N + +configdefault SYM_INT_4 + default 4 + +config SYM_INT_4 + int "Int 4" + default 2 + +# Hex value +configdefault SYM_HEX_20 + default 0x20 + +config SYM_HEX_20 + hex "Hex 0x20" + +# String value +configdefault SYM_STRING + default "TEST" + +config SYM_STRING + string "Hex 0x20" + +source "Kconfig.zephyr" diff --git a/tests/kconfig/configdefault/prj.conf b/tests/kconfig/configdefault/prj.conf new file mode 100644 index 00000000000..9228251051e --- /dev/null +++ b/tests/kconfig/configdefault/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y diff --git a/tests/kconfig/configdefault/src/main.c b/tests/kconfig/configdefault/src/main.c new file mode 100644 index 00000000000..abff0c54671 --- /dev/null +++ b/tests/kconfig/configdefault/src/main.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 CSIRO + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +ZTEST_SUITE(test_configdefault, NULL, NULL, NULL, NULL, NULL); + +ZTEST(test_configdefault, test_expectedvalues) +{ + zassert_true(IS_ENABLED(CONFIG_DEP_Y), ""); + zassert_false(IS_ENABLED(CONFIG_DEP_N), ""); + + zassert_true(IS_ENABLED(CONFIG_SYM_Y_1), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_2), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_3), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_4), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_5), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_6), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_7), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_8), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_9), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_10), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_11), ""); + zassert_true(IS_ENABLED(CONFIG_SYM_Y_12), ""); + + zassert_false(IS_ENABLED(CONFIG_SYM_N_1), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_2), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_3), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_4), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_5), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_6), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_7), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_8), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_9), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_10), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_11), ""); + zassert_false(IS_ENABLED(CONFIG_SYM_N_12), ""); + + zassert_false(IS_ENABLED(CONFIG_SYM_INT_UNDEF), ""); + zassert_equal(1, CONFIG_SYM_INT_1, ""); + zassert_equal(2, CONFIG_SYM_INT_2, ""); + zassert_equal(3, CONFIG_SYM_INT_3, ""); + zassert_equal(4, CONFIG_SYM_INT_4, ""); + + zassert_equal(0x20, CONFIG_SYM_HEX_20, ""); + zassert_mem_equal("TEST", CONFIG_SYM_STRING, strlen("TEST"), ""); +} diff --git a/tests/kconfig/configdefault/testcase.yaml b/tests/kconfig/configdefault/testcase.yaml new file mode 100644 index 00000000000..dcf193ec001 --- /dev/null +++ b/tests/kconfig/configdefault/testcase.yaml @@ -0,0 +1,3 @@ +tests: + kconfig.configdefault: + tags: kconfig From ee1acd8ae512afa82181261f530a3a932a87dc5c Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 16 Oct 2022 16:34:55 +1000 Subject: [PATCH 2621/4498] doc: build: kconfig: expand on multiple symbols Convert the warning about multiple symbol definitions to a dedicated section. This allows the warning to be restricted to the information that is non-intuitive, with a note for actions that should be taken when working with multiple definitions. Signed-off-by: Jordan Yates --- doc/build/kconfig/setting.rst | 40 ++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 147549c0503..b59c13ef52e 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -246,25 +246,45 @@ Note that conditions from surrounding top-level ``if``\ s are propagated to symbol properties, so the above ``default`` is equivalent to ``default 32 if BOARD_MY_BOARD``. -.. warning:: +Multiple symbol definitions +--------------------------- + +When a symbol is defined in multiple locations, each definition acts as an +independent symbol that happens to share the same name. This means that +properties are not appended to previous definitions. If the conditions +for **ANY** definition result in the symbol resolving to ``y``, the symbol +will be ``y``. It is therefore not possible to make the dependencies of a +symbol more restrictive by defining it in multiple locations. + +For example, the dependencies of the symbol ``FOO`` below are satisfied if +either ``DEP1`` **OR** ``DEP2`` are true, it does not require both: + +.. code-block:: none - When defining a symbol in multiple locations, dependencies are ORed together - rather than ANDed together. It is not possible to make the dependencies of a - symbol more restrictive by defining it in multiple locations. + config FOO + ... + depends on DEP1 - For example, the direct dependencies of the symbol below becomes - ``DEP1 || DEP2``: + config FOO + ... + depends on DEP2 + +.. warning:: + Symbols without explicit dependencies still follow the above rule. A + symbol without any dependencies will result in the symbol always being + assignable. The definition below will result in ``FOO`` always being + enabled by default, regardless of the value of ``DEP1``. .. code-block:: kconfig config FOO - ... - depends on DEP1 + bool "FOO" + depends on DEP1 config FOO - ... - depends on DEP2 + default y +.. note:: When making changes to :file:`Kconfig.defconfig` files, always check the symbol's direct dependencies in one of the :ref:`interactive configuration interfaces ` afterwards. It is often necessary to repeat From 7aae40e8440e6c41f6f23b77c49a593121fbcd96 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 16 Oct 2022 16:45:24 +1000 Subject: [PATCH 2622/4498] doc: build: kconfig: document `configdefault` Document the new `configdefault` Kconfig extension. Signed-off-by: Jordan Yates --- doc/build/kconfig/extensions.rst | 36 ++++++++++++++++++++++++++++++++ doc/build/kconfig/setting.rst | 6 ++++++ 2 files changed, 42 insertions(+) diff --git a/doc/build/kconfig/extensions.rst b/doc/build/kconfig/extensions.rst index efa0ee18ffa..9ee8b33c85f 100644 --- a/doc/build/kconfig/extensions.rst +++ b/doc/build/kconfig/extensions.rst @@ -8,6 +8,42 @@ implementation of `Kconfig `__, which includes some Kconfig extensions: +- Default values can be applied to existing symbols without + :ref:`weakening ` the symbols dependencies + through the use of ``configdefault``. + + .. code-block:: none + + config FOO + bool "FOO" + depends on BAR + + configdefault FOO + default y if FIZZ + + The statement above is equivalent to: + + .. code-block:: none + + config FOO + bool "Foo" + default y if FIZZ + depends on BAR + + ``configdefault`` symbols cannot contain any fields other than ``default``, + however they can be wrapped in ``if`` statements. The two statements below + are equivalent: + + .. code-block:: none + + configdefault FOO + default y if BAR + + if BAR + configdefault FOO + default y + endif # BAR + - Environment variables in ``source`` statements are expanded directly, meaning no "bounce" symbols with ``option env="ENV_VAR"`` need to be defined. diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index b59c13ef52e..041aed5fc36 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -246,6 +246,8 @@ Note that conditions from surrounding top-level ``if``\ s are propagated to symbol properties, so the above ``default`` is equivalent to ``default 32 if BOARD_MY_BOARD``. +.. _multiple_symbol_definitions: + Multiple symbol definitions --------------------------- @@ -284,6 +286,10 @@ either ``DEP1`` **OR** ``DEP2`` are true, it does not require both: config FOO default y + This dependency weakening can be avoided with the :ref:`configdefault + ` extension if the desire is only to add a new default + without modifying any other behaviour of the symbol. + .. note:: When making changes to :file:`Kconfig.defconfig` files, always check the symbol's direct dependencies in one of the :ref:`interactive configuration From 40620e1ce46e64c8091bc1f71a7334678a809f06 Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Mon, 9 Oct 2023 11:28:28 +0300 Subject: [PATCH 2623/4498] west.yml: Update hal_renesas revision Adds new HAL to be used by existing and upcoming drivers. Signed-off-by: Ioannis Karachalios --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 6bc05b1e8a7..cb2e33ef59b 100644 --- a/west.yml +++ b/west.yml @@ -213,7 +213,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: a6cf2af9140e014fbbc48d2b6deb802231dd369f + revision: 1471ed3cbf501434a5f3df2f9df520c3bd8e0258 groups: - hal - name: hal_rpi_pico From 6f6066cdf1636f0e8a1176a8f43684227bc231bf Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Tue, 13 Jun 2023 06:57:44 -0700 Subject: [PATCH 2624/4498] drivers: crypto: smartbond: Support crypto accelerator Add support for the crypto engine. Signed-off-by: Ioannis Karachalios --- drivers/crypto/CMakeLists.txt | 1 + drivers/crypto/Kconfig | 1 + drivers/crypto/Kconfig.smartbond | 17 + drivers/crypto/crypto_smartbond.c | 956 ++++++++++++++++++ .../crypto/renesas,smartbond-crypto.yaml | 15 + 5 files changed, 990 insertions(+) create mode 100644 drivers/crypto/Kconfig.smartbond create mode 100644 drivers/crypto/crypto_smartbond.c create mode 100644 dts/bindings/crypto/renesas,smartbond-crypto.yaml diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 07eb8a414ec..68b63aef6ee 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_TINYCRYPT_SHIM crypto_tc_shim.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_ATAES132A crypto_ataes132a.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MBEDTLS_SHIM crypto_mtls_shim.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_STM32 crypto_stm32.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_SMARTBOND crypto_smartbond.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_NRF_ECB crypto_nrf_ecb.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_INTEL_SHA crypto_intel_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index c209ed226f7..5342441038e 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -80,5 +80,6 @@ source "drivers/crypto/Kconfig.npcx" source "drivers/crypto/Kconfig.xec" source "drivers/crypto/Kconfig.it8xxx2" source "drivers/crypto/Kconfig.mcux_dcp" +source "drivers/crypto/Kconfig.smartbond" endif # CRYPTO diff --git a/drivers/crypto/Kconfig.smartbond b/drivers/crypto/Kconfig.smartbond new file mode 100644 index 00000000000..6c2077c3a42 --- /dev/null +++ b/drivers/crypto/Kconfig.smartbond @@ -0,0 +1,17 @@ +# Smartbond Cryptographic Accelerator configuration options + +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig CRYPTO_SMARTBOND + bool "Smartbond Cryptographic Accelerator driver" + depends on DT_HAS_RENESAS_SMARTBOND_CRYPTO_ENABLED + default y + help + Enable Smartbond Cryptographic Accelerator driver. + +config CRYPTO_ASYNC + bool "Support ASYNC crypto operations." + depends on CRYPTO_SMARTBOND + help + Enable ASYNC crypto operations. diff --git a/drivers/crypto/crypto_smartbond.c b/drivers/crypto/crypto_smartbond.c new file mode 100644 index 00000000000..5b003875b93 --- /dev/null +++ b/drivers/crypto/crypto_smartbond.c @@ -0,0 +1,956 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(crypto_smartbond_crypto, CONFIG_CRYPTO_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_smartbond_crypto + +#define SMARTBOND_IRQN DT_INST_IRQN(0) +#define SMARTBOND_IRQ_PRIO DT_INST_IRQ(0, priority) + +#if defined(CONFIG_CRYPTO_ASYNC) +#define CRYPTO_HW_CAPS (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_ASYNC_OPS | CAP_NO_IV_PREFIX) +#else +#define CRYPTO_HW_CAPS (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_NO_IV_PREFIX) +#endif + +#define SWAP32(_w) __builtin_bswap32(_w) + +#define CRYPTO_CTRL_REG_SET(_field, _val) \ + AES_HASH->CRYPTO_CTRL_REG = \ + (AES_HASH->CRYPTO_CTRL_REG & ~AES_HASH_CRYPTO_CTRL_REG_ ## _field ## _Msk) | \ + ((_val) << AES_HASH_CRYPTO_CTRL_REG_ ## _field ## _Pos) + +#define CRYPTO_CTRL_REG_GET(_field) \ + ((AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_ ## _field ## _Msk) >> \ + AES_HASH_CRYPTO_CTRL_REG_ ## _field ## _Pos) + + +struct crypto_smartbond_data { + /* + * Semaphore to provide mutual exlusion when a crypto session is requested. + */ + struct k_sem session_sem; + + /* + * Semaphore to provide mutual exlusion when a cryptographic task is requested. + * (a session should be requested at this point). + */ + struct k_sem device_sem; +#if defined(CONFIG_CRYPTO_ASYNC) + /* + * User-defined callbacks to be called upon completion of asynchronous + * cryptographic operations. Note that the AES and HASH modes can work + * complementary to each other. + */ + union { + cipher_completion_cb cipher_user_cb; + hash_completion_cb hash_user_cb; + }; + + /* + * Packet context should be stored during a session so that can be rertieved + * from within the crypto engine ISR context. + */ + union { + struct cipher_pkt *cipher_pkt; + struct hash_pkt *hash_pkt; + }; +#else + /* + * Semaphore used to block for as long as a synchronous cryptographic operation + * is in progress. + */ + struct k_sem sync_sem; +#endif +}; + +/* + * Status flag to indicate if the crypto engine resources have been granted. Note that the + * device integrates a single crypto engine instance. + */ +static bool in_use; + +static void crypto_smartbond_set_status(bool enable); + +static void smartbond_crypto_isr(const void *arg) +{ + struct crypto_smartbond_data *data = ((const struct device *)arg)->data; + uint32_t status = AES_HASH->CRYPTO_STATUS_REG; + + if (status & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Msk) { + /* Clear interrupt source. Otherwise the handler will be fire constantly! */ + AES_HASH->CRYPTO_CLRIRQ_REG = 0x1; + +#if defined(CONFIG_CRYPTO_ASYNC) + /* Define the slected crypto mode (AES/HASH). */ + if (AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk) { + if (data->hash_user_cb) { + data->hash_user_cb(data->hash_pkt, status); + } + } else { + if (data->cipher_user_cb) { + data->cipher_user_cb(data->cipher_pkt, status); + } + } +#else + /* Designate the requested cryptographic tasks is finished. */ + k_sem_give(&data->sync_sem); +#endif + } +} + +static bool crypto_smartbond_lock_session(const struct device *dev) +{ + bool lock = false; + struct crypto_smartbond_data *data = dev->data; + + k_sem_take(&data->session_sem, K_FOREVER); + + if (!in_use) { + in_use = true; + crypto_smartbond_set_status(true); + lock = true; + } + + k_sem_give(&data->session_sem); + + return lock; +} + +static void crypto_smartbond_unlock_session(const struct device *dev) +{ + struct crypto_smartbond_data *data = dev->data; + + k_sem_take(&data->session_sem, K_FOREVER); + + if (in_use) { + in_use = false; + crypto_smartbond_set_status(false); + } + + k_sem_give(&data->session_sem); +} + +/* + * Input vector should comply with the following restrictions: + * + * mode | CRYPTO_MORE_IN = true | CRYPTO_MORE_IN = false + * ------------| -----------------------| ---------------------- + * ECB | multiple of 16 (bytes) | multiple of 16 (bytes) + * CBC | multiple of 16 | no restrictions + * CTR | multiple of 16 | no restrictions + * MD5 | multiple of 8 | no restrictions + * SHA_1 | multiple of 8 | no restrictions + * SHA_256_224 | multiple of 8 | no restrictions + * SHA_256 | multiple of 8 | no restrictions + * SHA_384 | multiple of 8 | no restrictions + * SHA_512 | multiple of 8 | no restrictions + * SHA_512_224 | multiple of 8 | no restrictions + * SHA_512_256 | multiple of 8 | no restrictions + */ +static int crypto_smartbond_check_in_restrictions(uint16_t in_len) +{ +#define CRYPTO_ALG_MD_ECB_MAGIC_0 0x00 +#define CRYPTO_ALG_MD_ECB_MAGIC_1 0x01 + + bool not_last_in_block = !!(AES_HASH->CRYPTO_CTRL_REG & + AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk); + + /* Define the slected crypto mode (AES/HASH). */ + if (AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk) { + if (not_last_in_block && (in_len & 0x7)) { + return -EINVAL; + } + } else { + if (in_len & 0xF) { + if (not_last_in_block) { + return -EINVAL; + } + + uint32_t crypto_mode = CRYPTO_CTRL_REG_GET(CRYPTO_ALG_MD); + + /* Check if AES mode is ECB */ + if (crypto_mode == CRYPTO_ALG_MD_ECB_MAGIC_0 || + crypto_mode == CRYPTO_ALG_MD_ECB_MAGIC_1) { + return -EINVAL; + } + } + } + + return 0; +} + +/* + * The driver model does not define the max. output length. As such, the max supported length + * per mode is applied. + */ +static int crypto_smartbond_hash_set_out_len(void) +{ + uint32_t hash_algo = (AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Msk); + + if (AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk) { + /* 64-bit HASH operations */ + switch (hash_algo) { + case 0x0: + /* SHA-384: 0..47 --> 1..48 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 47); + break; + case 0x1: + /* SHA-512: 0..63 --> 1..64 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 63); + break; + case 0x2: + /* SHA-512/224: 0..27 --> 1..28 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 27); + break; + case 0x3: + /* SHA-512/256: 0..31 --> 1..32 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 31); + break; + default: + break; + } + } else { + /* 32-bit HASH operations */ + switch (hash_algo) { + case 0x0: + /* MD5: 0..15 --> 1..16 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 15); + break; + case 0x1: + /* SHA-1: 0..19 --> 1..20 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 19); + break; + case 0x2: + /* SHA-256/224: 0..27 --> 1..28 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 27); + break; + case 0x3: + /* SHA-256: 0..31 --> 1..32 bytes */ + CRYPTO_CTRL_REG_SET(CRYPTO_HASH_OUT_LEN, 31); + break; + default: + break; + } + } + + /* Return the OUT size applied. */ + return CRYPTO_CTRL_REG_GET(CRYPTO_HASH_OUT_LEN) + 1; +} + +static uint32_t crypto_smartbond_swap_word(uint8_t *data) +{ + /* Check word boundaries of given address and if possible accellerate swapping */ + if ((uint32_t)data & 0x3) { + sys_mem_swap(data, sizeof(uint32_t)); + + return (*(uint32_t *)data); + } else { + return SWAP32(*(uint32_t *)data); + } +} + +static int crypto_smartbond_cipher_key_load(uint8_t *key, uint16_t key_len) +{ + if (key == NULL) { + return -EIO; + } + + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Msk); + + if (key_len == 32) { + AES_HASH->CRYPTO_CTRL_REG |= + (0x2 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Pos); + } else if (key_len == 24) { + AES_HASH->CRYPTO_CTRL_REG |= + (0x1 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Pos); + } else if (key_len == 16) { + /* Nothing to do */ + } else { + return -EINVAL; + } + + /* Key expansion is performed by the crypto engine */ + AES_HASH->CRYPTO_CTRL_REG |= AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Msk; + + /* Check whether the cipher key is located in OTP (user keys segment) */ + if (IS_ADDRESS_USER_DATA_KEYS_SEGMENT((uint32_t)key)) { + + /* User keys segmnet can be accessed if not locked (stick bits are not set) */ + if (CRG_TOP->SECURE_BOOT_REG & CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Msk) { + return -EIO; + } + + uint32_t cell_offset = da1469x_otp_address_to_cell_offset((uint32_t)key); + + da1469x_otp_read(cell_offset, + (void *)&AES_HASH->CRYPTO_KEYS_START, (uint32_t)key_len); + } else { + volatile uint32_t *kmem_ptr = &AES_HASH->CRYPTO_KEYS_START; + + do { + *(kmem_ptr++) = crypto_smartbond_swap_word(key); + key += 4; + key_len -= 4; + } while (key_len); + } + + return 0; +} + +static int crypto_smartbond_cipher_set_mode(enum cipher_mode mode) +{ + /* Select AES mode */ + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk | + AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Msk | + AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk); + switch (mode) { + case CRYPTO_CIPHER_MODE_ECB: + /* Already done; CRYPTO_ALG_MD = 0x0 or 0x1 defines ECB. */ + break; + case CRYPTO_CIPHER_MODE_CTR: + AES_HASH->CRYPTO_CTRL_REG |= (0x2 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Pos); + break; + case CRYPTO_CIPHER_MODE_CBC: + AES_HASH->CRYPTO_CTRL_REG |= (0x3 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Pos); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int crypto_smartbond_hash_set_algo(enum hash_algo algo) +{ + /* Select HASH mode and reset to 32-bit mode */ + AES_HASH->CRYPTO_CTRL_REG = + (AES_HASH->CRYPTO_CTRL_REG & ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Msk | + AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk)) | + AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk; + + switch (algo) { + case CRYPTO_HASH_ALGO_SHA224: + /* CRYPTO_ALG_MD = 0x0 defines 32-bit operations */ + AES_HASH->CRYPTO_CTRL_REG |= (0x2 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Pos); + break; + case CRYPTO_HASH_ALGO_SHA256: + /* CRYPTO_ALG_MD = 0x0 defines 32-bit operations */ + AES_HASH->CRYPTO_CTRL_REG |= (0x3 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Pos); + break; + case CRYPTO_HASH_ALGO_SHA384: + /* CRYPTO_ALG_MD = 0x1 defines 64-bit operations */ + AES_HASH->CRYPTO_CLRIRQ_REG |= AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk; + break; + case CRYPTO_HASH_ALGO_SHA512: + /* CRYPTO_ALG_MD = 0x1 defines 64-bit operations */ + AES_HASH->CRYPTO_CTRL_REG |= (AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk | + (0x1 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Pos)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int crypto_smartbond_set_in_out_buf(uint8_t *in_buf, uint8_t *out_buf, int len) +{ + if (in_buf == NULL) { + return -EIO; + } + + /* + * Input data can reside in any address space. Cryto DMA can only access physical addresses + * (not remapped). + */ + uint32_t phy_addr = black_orca_phy_addr((uint32_t)in_buf); + + if (IS_QSPIF_CACHED_ADDRESS(phy_addr)) { + /* + * To achiebe max. perfomance, peripherals should not access the Flash memory + * through the instruction cache controller (avoid cache misses). + */ + phy_addr += (MCU_QSPIF_M_BASE - MCU_QSPIF_M_CACHED_BASE); + } else if (IS_OTP_ADDRESS(phy_addr)) { + /* Peripherals should access the OTP memory through its peripheral address space. */ + phy_addr += (MCU_OTP_M_P_BASE - MCU_OTP_M_BASE); + } + + AES_HASH->CRYPTO_FETCH_ADDR_REG = phy_addr; + + /* + * OUT buffer can be NULL in case of fregmented data processing. CRYPTO_DEST_ADDR and + * CRYPTO_FETCH_ADDR are being updated as calculations prceed and OUT data are written + * into memory. + */ + if (out_buf) { + uint32_t remap_adr0 = CRG_TOP->SYS_CTRL_REG & CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Msk; + + /* + * OUT data can only be written in SYSRAM, non-cached remapped SYSRAM and + * cached non-remapped SYSRAM. + */ + if (IS_SYSRAM_ADDRESS(out_buf) || + (IS_REMAPPED_ADDRESS(out_buf) && remap_adr0 == 3)) { + AES_HASH->CRYPTO_DEST_ADDR_REG = black_orca_phy_addr((uint32_t)out_buf); + } else { + return -EIO; + } + } + + AES_HASH->CRYPTO_LEN_REG = len; + + return 0; +} + +static inline void crypto_smartbond_cipher_store_dep_data(uint32_t *words, uint32_t len_words) +{ + volatile uint32_t *mreg3 = &AES_HASH->CRYPTO_MREG3_REG; + + for (int i = 0; i < len_words; i++) { + *(mreg3--) = crypto_smartbond_swap_word((uint8_t *)(words++)); + } +} + +static int crypto_smartbond_cipher_set_mreg(uint8_t *mreg, uint32_t len_words) +{ + if (mreg == NULL || len_words == 0 || len_words > 4) { + return -EINVAL; + } + + AES_HASH->CRYPTO_MREG0_REG = 0; + AES_HASH->CRYPTO_MREG1_REG = 0; + AES_HASH->CRYPTO_MREG2_REG = 0; + AES_HASH->CRYPTO_MREG3_REG = 0; + + crypto_smartbond_cipher_store_dep_data((uint32_t *)mreg, len_words); + + return 0; +} + +static void crypto_smartbond_set_status(bool enable) +{ + unsigned int key; + + key = irq_lock(); + + if (enable) { + CRG_TOP->CLK_AMBA_REG |= (CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk); + + AES_HASH->CRYPTO_CLRIRQ_REG = 0x1; + AES_HASH->CRYPTO_CTRL_REG |= (AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Msk); + + irq_enable(SMARTBOND_IRQN); + } else { + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Msk); + AES_HASH->CRYPTO_CLRIRQ_REG = 0x1; + + irq_disable(SMARTBOND_IRQN); + + CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk); + } + + irq_unlock(key); +} + +static int crypto_smartbond_query_hw_caps(const struct device *dev) +{ + return CRYPTO_HW_CAPS; +} + +static int crypto_smartbond_cipher_ecb_handler(struct cipher_ctx *ctx, struct cipher_pkt *pkt) +{ + int ret; + struct crypto_smartbond_data *data = ctx->device->data; + + if ((AES_HASH->CRYPTO_STATUS_REG & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk) == 0) { + LOG_ERR("Crypto engine is already employed"); + return -EINVAL; + } + + if (pkt->out_buf_max < pkt->in_len) { + LOG_ERR("OUT buffer cannot be less that IN buffer"); + return -EINVAL; + } + + if (pkt->in_buf == NULL || pkt->out_buf == NULL) { + LOG_ERR("Missing IN or OUT buffer declaration"); + return -EIO; + } + + if (pkt->in_len > 16) { + LOG_ERR("For security reasons, do not operate on more than 16 bytes"); + return -EINVAL; + } + + k_sem_take(&data->device_sem, K_FOREVER); + + ret = crypto_smartbond_check_in_restrictions(pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN buffer size"); + k_sem_give(&data->device_sem); + return ret; + } + + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf, pkt->out_buf, pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN or OUT buffer location"); + k_sem_give(&data->device_sem); + return ret; + } + +#if defined(CONFIG_CRYPTO_ASYNC) + data->cipher_pkt = pkt; +#endif + + /* Start crypto processing */ + AES_HASH->CRYPTO_START_REG = 1; + +#if !defined(CONFIG_CRYPTO_ASYNC) + /* Wait for crypto to finish its task */ + k_sem_take(&data->sync_sem, K_FOREVER); +#endif + + /* Report that number of bytes operated upon. */ + pkt->out_len = pkt->in_len; + + k_sem_give(&data->device_sem); + + return 0; +} + +static int +crypto_smartbond_cipher_cbc_handler(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *iv) +{ + int ret; + int offset = 0; + struct crypto_smartbond_data *data = ctx->device->data; + bool is_op_encryption = + !!(AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Msk); + + if ((AES_HASH->CRYPTO_STATUS_REG & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk) == 0) { + LOG_ERR("Crypto engine is already employed"); + return -EINVAL; + } + + if ((is_op_encryption && pkt->out_buf_max < (pkt->in_len + 16)) || + pkt->out_buf_max < (pkt->in_len - 16)) { + LOG_ERR("Invalid OUT buffer size"); + return -EINVAL; + } + + if (pkt->in_buf == NULL || pkt->out_buf == NULL) { + LOG_ERR("Missing IN or OUT buffer declaration"); + return -EIO; + } + + if ((ctx->flags & CAP_NO_IV_PREFIX) == 0) { + offset = 16; + if (is_op_encryption) { + /* Prefix IV to ciphertet unless CAP_NO_IV_PREFIX is set. */ + memcpy(pkt->out_buf, iv, offset); + } + } + + k_sem_take(&data->device_sem, K_FOREVER); + + ret = crypto_smartbond_check_in_restrictions(pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN buffer size"); + k_sem_give(&data->device_sem); + return ret; + } + + ret = crypto_smartbond_cipher_set_mreg(iv, 4); + if (ret < 0) { + LOG_ERR("Missing Initialization Vector (IV)"); + k_sem_give(&data->device_sem); + return ret; + } + + if (is_op_encryption) { + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf, + pkt->out_buf + offset, pkt->in_len); + } else { + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf + offset, + pkt->out_buf, pkt->in_len - offset); + } + + if (ret < 0) { + LOG_ERR("Unsupported IN or OUT buffer location"); + k_sem_give(&data->device_sem); + return ret; + } + +#if defined(CONFIG_CRYPTO_ASYNC) + data->cipher_pkt = pkt; +#endif + + /* Start crypto processing */ + AES_HASH->CRYPTO_START_REG = 1; + +#if !defined(CONFIG_CRYPTO_ASYNC) + /* Wait for crypto to finish its task */ + k_sem_take(&data->sync_sem, K_FOREVER); +#endif + + /* Report that number of bytes operated upon. */ + if (is_op_encryption) { + pkt->out_len = pkt->in_len + offset; + } else { + pkt->out_len = pkt->in_len - offset; + } + + k_sem_give(&data->device_sem); + + return 0; +} + +static int crypto_smartbond_cipher_ctr_handler(struct cipher_ctx *ctx, + struct cipher_pkt *pkt, uint8_t *ic) +{ + int ret; + /* ivlen + ctrlen = keylen, ctrl_len is expressed in bits */ + uint32_t iv_len = ctx->keylen - (ctx->mode_params.ctr_info.ctr_len >> 3); + struct crypto_smartbond_data *data = ctx->device->data; + + if ((AES_HASH->CRYPTO_STATUS_REG & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk) == 0) { + LOG_ERR("Crypto engine is already employed"); + return -EINVAL; + } + + if (pkt->out_buf_max < pkt->in_len) { + LOG_ERR("OUT buffer cannot be less that IN buffer"); + return -EINVAL; + } + + if (pkt->in_buf == NULL || pkt->out_buf == NULL) { + LOG_ERR("Missing IN or OUT buffer declaration"); + return -EIO; + } + + k_sem_take(&data->device_sem, K_FOREVER); + + ret = crypto_smartbond_check_in_restrictions(pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN buffer size"); + k_sem_give(&data->device_sem); + return ret; + } + + ret = crypto_smartbond_cipher_set_mreg(ic, iv_len >> 2); + if (ret < 0) { + LOG_ERR("Missing Initialization Counter (IC)"); + k_sem_give(&data->device_sem); + return ret; + } + + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf, pkt->out_buf, pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN or OUT buffer location"); + k_sem_give(&data->device_sem); + return ret; + } + +#if defined(CONFIG_CRYPTO_ASYNC) + data->cipher_pkt = pkt; +#endif + + /* Start crypto processing */ + AES_HASH->CRYPTO_START_REG = 1; + +#if !defined(CONFIG_CRYPTO_ASYNC) + /* Wait for crypto to finish its task */ + k_sem_take(&data->sync_sem, K_FOREVER); +#endif + + /* Report that number of bytes operated upon. */ + pkt->out_len = pkt->in_len; + + k_sem_give(&data->device_sem); + + return 0; +} + +static int crypto_smartbond_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) +{ + int ret; + struct crypto_smartbond_data *data = ctx->device->data; + /* + * In case of framgemented data processing crypto status should be visible as busy for + * as long as the last block is to be processed. + */ + bool is_multipart_started = + (AES_HASH->CRYPTO_STATUS_REG & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_WAIT_FOR_IN_Msk) && + !(AES_HASH->CRYPTO_STATUS_REG & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk); + + if (pkt->in_buf == NULL || (pkt->out_buf == NULL)) { + LOG_ERR("Missing IN or OUT buffer declaration"); + return -EIO; + } + + k_sem_take(&data->device_sem, K_FOREVER); + + /* Check if this is the last block to process or more blocks will follow */ + if (finish) { + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk); + } else { + AES_HASH->CRYPTO_CTRL_REG |= AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk; + } + + /* CRYPTO_MORE_IN should be updated prior to checking for IN restrictions! */ + ret = crypto_smartbond_check_in_restrictions(pkt->in_len); + if (ret < 0) { + LOG_ERR("Unsupported IN buffer size"); + k_sem_give(&data->device_sem); + return ret; + } + + if (!is_multipart_started) { + ret = crypto_smartbond_hash_set_out_len(); + if (ret < 0) { + LOG_ERR("Invalid OUT buffer size"); + k_sem_give(&data->device_sem); + return ret; + } + } + + if (!is_multipart_started) { + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf, pkt->out_buf, pkt->in_len); + } else { + /* Destination buffer is being updated as fragmented input is being processed. */ + ret = crypto_smartbond_set_in_out_buf(pkt->in_buf, NULL, pkt->in_len); + } + + if (ret < 0) { + LOG_ERR("Unsupported IN or OUT buffer location"); + k_sem_give(&data->device_sem); + return ret; + } + +#if defined(CONFIG_CRYPTO_ASYNC) + data->hash_pkt = pkt; +#endif + + /* Start hash processing */ + AES_HASH->CRYPTO_START_REG = 1; + +#if !defined(CONFIG_CRYPTO_ASYNC) + k_sem_take(&data->sync_sem, K_FOREVER); +#endif + + k_sem_give(&data->device_sem); + + return 0; +} + +static int +crypto_smartbond_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, + enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) +{ + int ret; + + if (ctx->flags & ~(CRYPTO_HW_CAPS)) { + LOG_ERR("Unsupported flag"); + return -EINVAL; + } + + if (algo != CRYPTO_CIPHER_ALGO_AES) { + LOG_ERR("Unsupported cipher algo"); + return -EINVAL; + } + + if (!crypto_smartbond_lock_session(dev)) { + LOG_ERR("No free session for now"); + return -ENOSPC; + } + + ret = crypto_smartbond_cipher_key_load(ctx->key.bit_stream, ctx->keylen); + if (ret < 0) { + LOG_ERR("Invalid key length or key cannot be accessed"); + crypto_smartbond_unlock_session(dev); + return ret; + } + + ret = crypto_smartbond_cipher_set_mode(mode); + if (ret < 0) { + LOG_ERR("Unsupported cipher mode"); + crypto_smartbond_unlock_session(dev); + return ret; + } + + if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) { + AES_HASH->CRYPTO_CTRL_REG |= AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Msk; + } else { + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Msk); + } + + /* IN buffer fragmentation is not supported by the driver model */ + AES_HASH->CRYPTO_CTRL_REG &= ~(AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk); + + switch (mode) { + case CRYPTO_CIPHER_MODE_ECB: + ctx->ops.block_crypt_hndlr = crypto_smartbond_cipher_ecb_handler; + break; + case CRYPTO_CIPHER_MODE_CBC: + ctx->ops.cbc_crypt_hndlr = crypto_smartbond_cipher_cbc_handler; + break; + case CRYPTO_CIPHER_MODE_CTR: + ctx->ops.ctr_crypt_hndlr = crypto_smartbond_cipher_ctr_handler; + break; + default: + break; + } + + ctx->drv_sessn_state = NULL; + + return 0; +} + +static int crypto_smartbond_cipher_free_session(const struct device *dev, struct cipher_ctx *ctx) +{ + ARG_UNUSED(ctx); + crypto_smartbond_unlock_session(dev); + + return 0; +} + +#if defined(CONFIG_CRYPTO_ASYNC) +static int +crypto_smartbond_cipher_set_async_callback(const struct device *dev, cipher_completion_cb cb) +{ + struct crypto_smartbond_data *data = dev->data; + + data->cipher_user_cb = cb; + + return 0; +} +#endif + +static int +crypto_smartbond_hash_begin_session(const struct device *dev, + struct hash_ctx *ctx, enum hash_algo algo) +{ + int ret; + + if (ctx->flags & ~(CRYPTO_HW_CAPS)) { + LOG_ERR("Unsupported flag"); + return -EINVAL; + } + + if (!crypto_smartbond_lock_session(dev)) { + LOG_ERR("No free session for now"); + return -ENOSPC; + } + + /* + * Crypto should be disabled only if not used in other sessions. In case of failure, + * developer should next free the current session. + */ + crypto_smartbond_set_status(true); + + ret = crypto_smartbond_hash_set_algo(algo); + if (ret < 0) { + LOG_ERR("Unsupported HASH algo"); + crypto_smartbond_unlock_session(dev); + return ret; + } + + ctx->hash_hndlr = crypto_smartbond_hash_handler; + + ctx->drv_sessn_state = NULL; + + return 0; +} + +static int crypto_smartbond_hash_free_session(const struct device *dev, struct hash_ctx *ctx) +{ + ARG_UNUSED(ctx); + crypto_smartbond_unlock_session(dev); + + return 0; +} + +#if defined(CONFIG_CRYPTO_ASYNC) +static int +crypto_smartbond_hash_set_async_callback(const struct device *dev, hash_completion_cb cb) +{ + struct crypto_smartbond_data *data = dev->data; + + data->hash_user_cb = cb; + + return 0; +} +#endif + +static struct crypto_driver_api crypto_smartbond_driver_api = { + .cipher_begin_session = crypto_smartbond_cipher_begin_session, + .cipher_free_session = crypto_smartbond_cipher_free_session, +#if defined(CONFIG_CRYPTO_ASYNC) + .cipher_async_callback_set = crypto_smartbond_cipher_set_async_callback, +#endif + .hash_begin_session = crypto_smartbond_hash_begin_session, + .hash_free_session = crypto_smartbond_hash_free_session, +#if defined(CONFIG_CRYPTO_ASYNC) + .hash_async_callback_set = crypto_smartbond_hash_set_async_callback, +#endif + .query_hw_caps = crypto_smartbond_query_hw_caps +}; + +static int crypto_smartbond_init(const struct device *dev) +{ + struct crypto_smartbond_data *data = dev->data; + + /* Semaphore used during sessions (begin/free) */ + k_sem_init(&data->session_sem, 1, 1); + + /* Semaphore used to employ the crypto device */ + k_sem_init(&data->device_sem, 1, 1); + +#if !defined(CONFIG_CRYPTO_ASYNC) + /* Sempahore used when sync operations are enabled */ + k_sem_init(&data->sync_sem, 0, 1); +#endif + + IRQ_CONNECT(SMARTBOND_IRQN, SMARTBOND_IRQ_PRIO, smartbond_crypto_isr, + DEVICE_DT_INST_GET(0), 0); + + crypto_smartbond_set_status(false); + + return 0; +} + +/* + * There is only one instance integrated on the SoC. Just in case that assumption becomes invalid + * in the future, we use a BUILD_ASSERT(). + */ +#define SMARTBOND_CRYPTO_INIT(inst) \ + BUILD_ASSERT((inst) == 0, \ + "multiple instances are not supported"); \ + \ + static struct crypto_smartbond_data crypto_smartbond_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(0, \ + crypto_smartbond_init, NULL, \ + &crypto_smartbond_data_##inst, NULL, \ + POST_KERNEL, \ + CONFIG_CRYPTO_INIT_PRIORITY, \ + &crypto_smartbond_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SMARTBOND_CRYPTO_INIT) diff --git a/dts/bindings/crypto/renesas,smartbond-crypto.yaml b/dts/bindings/crypto/renesas,smartbond-crypto.yaml new file mode 100644 index 00000000000..7bee8dd4f9b --- /dev/null +++ b/dts/bindings/crypto/renesas,smartbond-crypto.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +include: base.yaml + +description: Renesas SmartBond(tm) CRYPTO + +compatible: "renesas,smartbond-crypto" + +properties: + reg: + required: true + + interrupts: + required: true From 112c395d4575cc31698fcf87fb2d17395e2053c1 Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Fri, 29 Sep 2023 02:38:45 +0300 Subject: [PATCH 2625/4498] dts: renesas: smartbond: Support crypto peripheral Update DTS and board configurations to support the crypto engine. Signed-off-by: Ioannis Karachalios --- boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml | 1 + dts/arm/renesas/smartbond/da1469x.dtsi | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml index d1d78c56055..edfaff84876 100644 --- a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml +++ b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml @@ -16,4 +16,5 @@ supported: - spi - usb_device - rtc + - crypto vendor: renesas diff --git a/dts/arm/renesas/smartbond/da1469x.dtsi b/dts/arm/renesas/smartbond/da1469x.dtsi index 9d9a106bfb7..ecf2f4df63a 100644 --- a/dts/arm/renesas/smartbond/da1469x.dtsi +++ b/dts/arm/renesas/smartbond/da1469x.dtsi @@ -231,7 +231,6 @@ #io-channel-cells = <1>; }; - sdadc: sdadc@50020800 { compatible = "renesas,smartbond-sdadc"; reg = <0x50020800 0x1C>; @@ -241,6 +240,13 @@ #io-channel-cells = <1>; }; + crypto: crypto@30040000 { + compatible = "renesas,smartbond-crypto"; + reg = <0x30040000 0x200>; + interrupts = <29 0>; + status = "disabled"; + }; + trng: trng@50040c00 { compatible = "renesas,smartbond-trng"; reg = <0x50040c00 0x0C>; From 2a310e86e1dd15ce363f2c996459803a4860afc5 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Fri, 4 Aug 2023 17:46:52 -0700 Subject: [PATCH 2626/4498] drivers/gpio: Make MCHP XEC pin configure closer to XEC V2 To avoid glitches when configuring GPIO output, make logic closer to that of V2 after 79ee5a876fce82e4bd22f865032567ba2cab9327. Signed-off-by: Ederson de Souza --- drivers/gpio/gpio_mchp_xec.c | 63 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/drivers/gpio/gpio_mchp_xec.c b/drivers/gpio/gpio_mchp_xec.c index f01aefd6d2d..86d9f2a5d7a 100644 --- a/drivers/gpio/gpio_mchp_xec.c +++ b/drivers/gpio/gpio_mchp_xec.c @@ -66,7 +66,6 @@ static int gpio_xec_configure(const struct device *dev, __IO uint32_t *current_pcr1; uint32_t pcr1 = 0U; uint32_t mask = 0U; - __IO uint32_t *gpio_out_reg = GPIO_OUT_BASE(config); /* Validate pin number range in terms of current port */ if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0U) { @@ -88,7 +87,22 @@ static int gpio_xec_configure(const struct device *dev, mask |= MCHP_GPIO_CTRL_DIR_MASK; mask |= MCHP_GPIO_CTRL_INPAD_DIS_MASK; mask |= MCHP_GPIO_CTRL_PWRG_MASK; - pcr1 |= MCHP_GPIO_CTRL_DIR_INPUT; + mask |= MCHP_GPIO_CTRL_AOD_MASK; + + current_pcr1 = config->pcr1_base + pin; + + if (flags == GPIO_DISCONNECTED) { + pcr1 |= MCHP_GPIO_CTRL_PWRG_OFF; + *current_pcr1 = (*current_pcr1 & ~mask) | pcr1; + return 0; + } + + pcr1 = MCHP_GPIO_CTRL_PWRG_VTR_IO; + + /* Always enable input pad */ + if (*current_pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS)) { + *current_pcr1 &= ~BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS); + } /* Figure out the pullup/pulldown configuration and keep it in the * pcr1 variable @@ -114,38 +128,33 @@ static int gpio_xec_configure(const struct device *dev, pcr1 |= MCHP_GPIO_CTRL_BUFT_PUSHPULL; } - /* Use GPIO output register to control pin output, instead of - * using the control register (=> alternate output disable). - */ - mask |= MCHP_GPIO_CTRL_AOD_MASK; - pcr1 |= MCHP_GPIO_CTRL_AOD_DIS; - - /* Make sure disconnected on first control register write */ - if (flags == GPIO_DISCONNECTED) { - pcr1 |= MCHP_GPIO_CTRL_PWRG_OFF; - } - - /* Now write contents of pcr1 variable to the PCR1 register that - * corresponds to the GPIO being configured. - * AOD is 1 and direction is input. HW will allow use to set the - * GPIO parallel output bit for this pin and with the pin direction - * as input no glitch will occur. - */ - current_pcr1 = config->pcr1_base + pin; - *current_pcr1 = (*current_pcr1 & ~mask) | pcr1; - if ((flags & GPIO_OUTPUT) != 0U) { + mask |= MCHP_GPIO_CTRL_OUTV_HI; if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) { - *gpio_out_reg |= BIT(pin); + pcr1 |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS); } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) { - *gpio_out_reg &= ~BIT(pin); + pcr1 &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS); + } else { /* Copy current input state to output state */ + if ((*current_pcr1 & MCHP_GPIO_CTRL_PWRG_MASK) == + MCHP_GPIO_CTRL_PWRG_OFF) { + *current_pcr1 = (*current_pcr1 & + ~MCHP_GPIO_CTRL_PWRG_MASK) | + MCHP_GPIO_CTRL_PWRG_VTR_IO; + } + if (*current_pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_VAL_POS)) { + pcr1 |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS); + } else { + pcr1 &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS); + } } - mask = MCHP_GPIO_CTRL_DIR_MASK; - pcr1 = MCHP_GPIO_CTRL_DIR_OUTPUT; - *current_pcr1 = (*current_pcr1 & ~mask) | pcr1; + pcr1 |= MCHP_GPIO_CTRL_DIR_OUTPUT; } + *current_pcr1 = (*current_pcr1 & ~mask) | pcr1; + /* Control output bit becomes ready only and parallel output r/w */ + *current_pcr1 = *current_pcr1 | BIT(MCHP_GPIO_CTRL_AOD_POS); + return 0; } From a1920f25f739d93d06a09c7c85f31ea7c4f9ec0c Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Fri, 28 Jul 2023 16:00:21 -0700 Subject: [PATCH 2627/4498] tests/drivers/gpio/gpio_basic_api: Add tests for configuration glitches Add a few tests that expect at most one interrupt being triggered when configuring a GPIO output in two scenarios: 1. From just after booting 2. After another configuration of the same values Due 1., this patch adds the tests to run before any other tests in the gpio_basic_api test suite. Signed-off-by: Ederson de Souza --- tests/drivers/gpio/gpio_basic_api/src/main.c | 6 + .../gpio_basic_api/src/test_config_trigger.c | 110 ++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c diff --git a/tests/drivers/gpio/gpio_basic_api/src/main.c b/tests/drivers/gpio/gpio_basic_api/src/main.c index 11c5da9671d..143be7d314d 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/main.c +++ b/tests/drivers/gpio/gpio_basic_api/src/main.c @@ -115,3 +115,9 @@ ZTEST_SUITE(gpio_port_cb_mgmt, NULL, gpio_basic_setup, NULL, NULL, NULL); /* Test GPIO callbacks */ ZTEST_SUITE(gpio_port_cb_vari, NULL, gpio_basic_setup, NULL, NULL, NULL); + +/* Test GPIO port configuration influence on callbacks. Want to run just + * after flash, hence the name starting in 'a' + */ +ZTEST_SUITE(after_flash_gpio_config_trigger, NULL, gpio_basic_setup, NULL, NULL, + NULL); diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c b/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c new file mode 100644 index 00000000000..869e550aba4 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include "test_gpio.h" + +static struct drv_data data; +static int cb_cnt; + +static void callback(const struct device *dev, + struct gpio_callback *gpio_cb, uint32_t pins) +{ + /*= checkpoint: pins should be marked with correct pin number bit =*/ + zassert_equal(pins, BIT(PIN_IN), + "unexpected pins %x", pins); + + ++cb_cnt; +} + +ZTEST(after_flash_gpio_config_trigger, test_gpio_config_twice_trigger) +{ + const struct device *const dev = DEVICE_DT_GET(DEV); + struct drv_data *drv_data = &data; + int ret; + + cb_cnt = 0; + + ret = gpio_pin_configure(dev, PIN_OUT, GPIO_DISCONNECTED); + + /* 1. Configure PIN_IN callback */ + ret = gpio_pin_configure(dev, PIN_IN, GPIO_INPUT); + zassert_ok(ret, "config PIN_IN failed"); + + gpio_init_callback(&drv_data->gpio_cb, callback, BIT(PIN_IN)); + ret = gpio_add_callback(dev, &drv_data->gpio_cb); + zassert_ok(ret, "add callback failed"); + + /* 2. Enable PIN callback as both edges */ + ret = gpio_pin_interrupt_configure(dev, PIN_IN, GPIO_INT_EDGE_BOTH); + zassert_ok(ret, "enable callback failed"); + + /* 3. Configure PIN_OUT as open drain, internal pull-up (may trigger + * callback) + */ + ret = gpio_pin_configure(dev, PIN_OUT, + GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP); + if (ret == -ENOTSUP) { + TC_PRINT("Open drain not supported.\n"); + gpio_remove_callback(dev, &drv_data->gpio_cb); + ztest_test_skip(); + return; + } + zassert_ok(ret, "config PIN_OUT failed"); + + /* 4. Configure PIN_OUT again (should not trigger callback) */ + ret = gpio_pin_configure(dev, PIN_OUT, + GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP); + zassert_ok(ret, "config PIN_OUT twice failed"); + + /* 5. Wait a bit and ensure that interrupt happened at most once */ + k_sleep(K_MSEC(10)); + zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt); + + gpio_remove_callback(dev, &drv_data->gpio_cb); +} + +ZTEST(after_flash_gpio_config_trigger, test_gpio_config_trigger) +{ + const struct device *const dev = DEVICE_DT_GET(DEV); + struct drv_data *drv_data = &data; + int ret; + + cb_cnt = 0; + + ret = gpio_pin_configure(dev, PIN_OUT, GPIO_DISCONNECTED); + + /* 1. Configure PIN_IN callback */ + ret = gpio_pin_configure(dev, PIN_IN, GPIO_INPUT); + zassert_ok(ret, "config PIN_IN failed"); + + gpio_init_callback(&drv_data->gpio_cb, callback, BIT(PIN_IN)); + ret = gpio_add_callback(dev, &drv_data->gpio_cb); + zassert_ok(ret, "add callback failed"); + + /* 2. Enable PIN callback as both edges */ + ret = gpio_pin_interrupt_configure(dev, PIN_IN, GPIO_INT_EDGE_BOTH); + zassert_ok(ret, "enable callback failed"); + + /* 3. Configure PIN_OUT as open drain, internal pull-up (may trigger + * callback) + */ + ret = gpio_pin_configure(dev, PIN_OUT, + GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP); + if (ret == -ENOTSUP) { + TC_PRINT("Open drain not supported.\n"); + gpio_remove_callback(dev, &drv_data->gpio_cb); + ztest_test_skip(); + return; + } + zassert_ok(ret, "config PIN_OUT failed"); + + /* 4. Wait a bit and ensure that interrupt happened at most once */ + k_sleep(K_MSEC(10)); + zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt); + + gpio_remove_callback(dev, &drv_data->gpio_cb); +} From 72aee4b90b1b9d2cf7d315488571dccda5ce6447 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Tue, 26 Sep 2023 15:38:47 +0200 Subject: [PATCH 2628/4498] drivers: clock_control: stm32: add an option to enable CRS for HSI48 for nucleo_stm32g0b1 board. the HSI48 clock is the clock used by default for the USB controller, however its default tolerance is not enough for the USB specification, leading to some random errors depending on many factors, including the upstream HUB or host. this commit adds an option in the device tree to enable the STM32 Clock recovery system (CRS) using USB SOF packet reception as a reference, which brings the HSI48 within the required accuracy for USB transfers. Signed-off-by: Aurelien Jarno Signed-off-by: Marc Desvaux --- boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts | 1 + drivers/clock_control/clock_stm32g0.c | 15 +++++++++++++++ dts/arm/st/g0/stm32g0b1.dtsi | 2 +- dts/bindings/clock/st,stm32-hsi48-clock.yaml | 16 ++++++++++++++++ .../drivers/clock_control/stm32_clock_control.h | 4 ++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/clock/st,stm32-hsi48-clock.yaml diff --git a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts index e74550e497f..17d22e5e9d4 100644 --- a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts +++ b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts @@ -61,6 +61,7 @@ &clk_hsi48 { status = "okay"; + crs-usb-sof; }; &pll { diff --git a/drivers/clock_control/clock_stm32g0.c b/drivers/clock_control/clock_stm32g0.c index 50558350141..5f7a3bfb1ad 100644 --- a/drivers/clock_control/clock_stm32g0.c +++ b/drivers/clock_control/clock_stm32g0.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -74,4 +75,18 @@ void config_enable_default_clocks(void) { /* Enable the power interface clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); + +#if defined(CRS) + if (IS_ENABLED(STM32_HSI48_CRS_USB_SOF)) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_CRS); + /* + * After reset the CRS configuration register + * (CRS_CFGR) value corresponds to an USB SOF + * synchronization. FIXME: write it anyway. + */ + LL_CRS_EnableAutoTrimming(); + LL_CRS_EnableFreqErrorCounter(); + } +#endif /* defined(CRS) */ + } diff --git a/dts/arm/st/g0/stm32g0b1.dtsi b/dts/arm/st/g0/stm32g0b1.dtsi index 621214b080c..b99063d67b8 100644 --- a/dts/arm/st/g0/stm32g0b1.dtsi +++ b/dts/arm/st/g0/stm32g0b1.dtsi @@ -14,7 +14,7 @@ clocks { clk_hsi48: clk-hsi48 { #clock-cells = <0>; - compatible = "fixed-clock"; + compatible = "st,stm32-hsi48-clock"; clock-frequency = ; status = "disabled"; }; diff --git a/dts/bindings/clock/st,stm32-hsi48-clock.yaml b/dts/bindings/clock/st,stm32-hsi48-clock.yaml new file mode 100644 index 00000000000..f8bcc88691b --- /dev/null +++ b/dts/bindings/clock/st,stm32-hsi48-clock.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2023, Aurelien Jarno +# SPDX-License-Identifier: Apache-2.0 + +description: STM32 HSI48 Clock + +compatible: "st,stm32-hsi48-clock" + +include: [fixed-clock.yaml] + +properties: + crs-usb-sof: + type: boolean + description: | + Clock Recovery System using USB SOF packet reception + Set the property to enable clock recovery of the HSI48 oscillator using + the USB SOF packet reception as a reference. diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 36df690220b..f18c351c0d5 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -385,6 +385,10 @@ #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi48), fixed_clock, okay) #define STM32_HSI48_ENABLED 1 #define STM32_HSI48_FREQ DT_PROP(DT_NODELABEL(clk_hsi48), clock_frequency) +#elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi48), st_stm32_hsi48_clock, okay) +#define STM32_HSI48_ENABLED 1 +#define STM32_HSI48_FREQ DT_PROP(DT_NODELABEL(clk_hsi48), clock_frequency) +#define STM32_HSI48_CRS_USB_SOF DT_PROP(DT_NODELABEL(clk_hsi48), crs_usb_sof) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(perck), st_stm32_clock_mux, okay) From 316c617f2cec3c643182387e5426e188925e1f4f Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Sat, 14 Oct 2023 14:38:17 +0200 Subject: [PATCH 2629/4498] sensors: emul: adi: add ltc2990 emulator This commit adds emulator for adi_ltc2990 Signed-off-by: Jilay Pandya --- drivers/sensor/adltc2990/CMakeLists.txt | 2 + drivers/sensor/adltc2990/Kconfig | 8 ++ drivers/sensor/adltc2990/adltc2990_emul.c | 136 ++++++++++++++++++++++ drivers/sensor/adltc2990/adltc2990_emul.h | 18 +++ 4 files changed, 164 insertions(+) create mode 100644 drivers/sensor/adltc2990/adltc2990_emul.c create mode 100644 drivers/sensor/adltc2990/adltc2990_emul.h diff --git a/drivers/sensor/adltc2990/CMakeLists.txt b/drivers/sensor/adltc2990/CMakeLists.txt index 45ca5eb803b..d71bf940a69 100644 --- a/drivers/sensor/adltc2990/CMakeLists.txt +++ b/drivers/sensor/adltc2990/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_library() zephyr_library_sources(adltc2990.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_ADLTC2990 adltc2990_emul.c) +zephyr_include_directories_ifdef(CONFIG_EMUL_ADLTC2990 .) diff --git a/drivers/sensor/adltc2990/Kconfig b/drivers/sensor/adltc2990/Kconfig index 260ae6af66b..75ac62b25f5 100644 --- a/drivers/sensor/adltc2990/Kconfig +++ b/drivers/sensor/adltc2990/Kconfig @@ -11,3 +11,11 @@ config ADLTC2990 help Enable the driver for Analog Devices LTC2990 Quad I2C Voltage, Current and Temperature Monitor. + +config EMUL_ADLTC2990 + bool "Emulator for ADLTC2990" + default y + depends on ADLTC2990 + depends on EMUL + help + Enable ADLTC2990 emulator. diff --git a/drivers/sensor/adltc2990/adltc2990_emul.c b/drivers/sensor/adltc2990/adltc2990_emul.c new file mode 100644 index 00000000000..664edbd8245 --- /dev/null +++ b/drivers/sensor/adltc2990/adltc2990_emul.c @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adltc2990 + +#include +#include +#include +#include +#include +#include +#include + +#include "adltc2990.h" +#include "adltc2990_reg.h" +#include "adltc2990_emul.h" + +LOG_MODULE_DECLARE(adltc2990, CONFIG_SENSOR_LOG_LEVEL); + +#define ADLTC2990_NUM_REGS ADLTC2990_REG_VCC_LSB + +struct adltc2990_emul_data { + uint8_t reg[ADLTC2990_NUM_REGS]; +}; + +struct adltc2990_emul_cfg { +}; + +void adltc2990_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *val) +{ + struct adltc2990_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg_addr <= ADLTC2990_NUM_REGS); + memcpy(data->reg + reg_addr, val, 1); +} + +void adltc2990_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *val) +{ + struct adltc2990_emul_data *data = target->data; + + __ASSERT_NO_MSG(reg_addr <= ADLTC2990_NUM_REGS); + memcpy(val, data->reg + reg_addr, 1); +} + +void adltc2990_emul_reset(const struct emul *target) +{ + struct adltc2990_emul_data *data = target->data; + + memset(data->reg, 0, ADLTC2990_NUM_REGS); +} + +static int adltc2990_emul_handle_write(const struct emul *target, uint8_t regn, uint8_t value) +{ + struct adltc2990_emul_data *data = target->data; + + switch (regn) { + case ADLTC2990_REG_CONTROL: + data->reg[ADLTC2990_REG_CONTROL] = value; + break; + + case ADLTC2990_REG_TRIGGER: + data->reg[ADLTC2990_REG_TRIGGER] = value; + break; + + default: + break; + } + return 0; +} + +static int adltc2990_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, + int num_msgs, int addr) +{ + struct adltc2990_emul_data *data = target->data; + + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); + + if (num_msgs < 1) { + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + if (FIELD_GET(I2C_MSG_READ, msgs->flags)) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len < 1) { + LOG_ERR("Unexpected msg0 length %s", msgs->len); + return -EIO; + } + + uint8_t regn = msgs->buf[0]; + bool is_read = FIELD_GET(I2C_MSG_READ, msgs->flags) == 1; + bool is_stop = FIELD_GET(I2C_MSG_STOP, msgs->flags) == 1; + + if (!is_stop && !is_read) { + /* First message was a write with the register number, check next message */ + msgs++; + is_read = FIELD_GET(I2C_MSG_READ, msgs->flags) == 1; + is_stop = FIELD_GET(I2C_MSG_STOP, msgs->flags) == 1; + } + + if (is_read) { + for (int i = 0; i < msgs->len; ++i) { + msgs->buf[i] = data->reg[regn + i]; + } + } else { + int rc = adltc2990_emul_handle_write(target, regn, msgs->buf[1]); + + if (rc != 0) { + return rc; + } + } + return 0; +}; + +static int adltc2990_emul_init(const struct emul *target, const struct device *parent) +{ + ARG_UNUSED(parent); + adltc2990_emul_reset(target); + + return 0; +} + +static const struct i2c_emul_api adltc2990_emul_api_i2c = { + .transfer = adltc2990_emul_transfer_i2c, +}; + +#define ADLTC2990_EMUL(n) \ + const struct adltc2990_emul_cfg adltc2990_emul_cfg_##n; \ + struct adltc2990_emul_data adltc2990_emul_data_##n; \ + EMUL_DT_INST_DEFINE(n, adltc2990_emul_init, &adltc2990_emul_data_##n, \ + &adltc2990_emul_cfg_##n, &adltc2990_emul_api_i2c, NULL) + +DT_INST_FOREACH_STATUS_OKAY(ADLTC2990_EMUL) diff --git a/drivers/sensor/adltc2990/adltc2990_emul.h b/drivers/sensor/adltc2990/adltc2990_emul.h new file mode 100644 index 00000000000..1085d7dea70 --- /dev/null +++ b/drivers/sensor/adltc2990/adltc2990_emul.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ADLTC2990_ADLTC2990_EMUL_H +#define ZEPHYR_DRIVERS_SENSOR_ADLTC2990_ADLTC2990_EMUL_H + +#include +#include + +void adltc2990_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *val); + +void adltc2990_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *val); + +void adltc2990_emul_reset(const struct emul *target); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_ADLTC2990_EMUL_H */ From 0804466b32d5c4cef60432acb82d648b2d19bfa8 Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Tue, 17 Oct 2023 17:25:29 +0200 Subject: [PATCH 2630/4498] sensors: refactor: adi: refactor adltc2990 This commit refactors adltc2990 sensor without any functional change Signed-off-by: Jilay Pandya --- drivers/sensor/adltc2990/adltc2990.c | 71 +++++++++++------------- drivers/sensor/adltc2990/adltc2990.h | 5 +- drivers/sensor/adltc2990/adltc2990_reg.h | 5 +- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/drivers/sensor/adltc2990/adltc2990.c b/drivers/sensor/adltc2990/adltc2990.c index 2e410505136..29d181a4211 100644 --- a/drivers/sensor/adltc2990/adltc2990.c +++ b/drivers/sensor/adltc2990/adltc2990.c @@ -1,6 +1,5 @@ /* * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG - * * SPDX-License-Identifier: Apache-2.0 */ @@ -135,9 +134,9 @@ static int adltc2990_trigger_measurement(const struct device *dev) return i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_TRIGGER, 0x1); } -static int32_t adltc2990_get_property_value(const struct device *dev, - enum adltc2990_monitoring_type type, - enum adltc2990_monitor_pins pin) +static int32_t adltc2990_fetch_property_value(const struct device *dev, + enum adltc2990_monitoring_type type, + enum adltc2990_monitor_pins pin) { const struct adltc2990_config *cfg = dev->config; @@ -200,9 +199,9 @@ static int32_t adltc2990_get_property_value(const struct device *dev, return -EINVAL; } - int16_t value = (msb_value<<8)+lsb_value; + int16_t value = (msb_value << 8) + lsb_value; - int32_t voltage_value = (value << (31-negative_bit_index))>>(31-negative_bit_index); + int32_t voltage_value = (value << (31 - negative_bit_index)) >> (31 - negative_bit_index); return (voltage_value * conversion_factor) / 100; } @@ -244,7 +243,7 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel switch (chan) { case SENSOR_CHAN_DIE_TEMP: { data->internal_temperature = - adltc2990_get_property_value(dev, TEMPERATURE, INTERNAL_TEMPERATURE); + adltc2990_fetch_property_value(dev, TEMPERATURE, INTERNAL_TEMPERATURE); break; } case SENSOR_CHAN_CURRENT: { @@ -254,13 +253,13 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { data->pins_v1_v2_values[0] = - (adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V1) * + (adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1) * ADLTC2990_MICROOHM_CONVERSION_FACTOR) / cfg->pins_v1_v2.pins_current_resistor; } if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { data->pins_v3_v4_values[0] = - (adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V3) * + (adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3) * ADLTC2990_MICROOHM_CONVERSION_FACTOR) / cfg->pins_v3_v4.pins_current_resistor; } @@ -268,52 +267,44 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } case SENSOR_CHAN_VOLTAGE: { data->supply_voltage = - adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, SUPPLY_VOLTAGE) + + adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, SUPPLY_VOLTAGE) + 2500000; if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { data->pins_v1_v2_values[0] = - adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V1); + adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1); } else if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { - uint32_t v1_r1 = - cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; - uint32_t v1_r2 = - cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; + uint32_t v1_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; + uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; voltage_divider_ratio = DIV_ROUND_CLOSEST(v1_r1 + v1_r2, v1_r2); data->pins_v1_v2_values[0] = - adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V1) * + adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V1) * voltage_divider_ratio; - uint32_t v2_r1 = - cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; - uint32_t v2_r2 = - cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; + uint32_t v2_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; + uint32_t v2_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; voltage_divider_ratio = DIV_ROUND_CLOSEST(v2_r1 + v2_r2, v2_r2); data->pins_v1_v2_values[1] = - adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V2) * + adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V2) * voltage_divider_ratio; } if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { data->pins_v3_v4_values[0] = - adltc2990_get_property_value(dev, VOLTAGE_DIFFERENTIAL, V3); + adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3); } else if (mode_v3_v4 == VOLTAGE_SINGLEENDED) { - uint32_t v3_r1 = - cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; - uint32_t v3_r2 = - cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; + uint32_t v3_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; + uint32_t v3_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; voltage_divider_ratio = DIV_ROUND_CLOSEST(v3_r1 + v3_r2, v3_r2); data->pins_v3_v4_values[0] = - adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V3) * + adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V3) * voltage_divider_ratio; - uint32_t v4_r1 = - cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; - uint32_t v4_r2 = - cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; + uint32_t v4_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; + uint32_t v4_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; voltage_divider_ratio = DIV_ROUND_CLOSEST((v4_r1 + v4_r2), v4_r2); data->pins_v3_v4_values[1] = - adltc2990_get_property_value(dev, VOLTAGE_SINGLEENDED, V4) * + adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V4) * voltage_divider_ratio; } break; @@ -325,11 +316,11 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } if (mode_v1_v2 == TEMPERATURE) { data->pins_v1_v2_values[0] = - adltc2990_get_property_value(dev, TEMPERATURE, V1); + adltc2990_fetch_property_value(dev, TEMPERATURE, V1); } if (mode_v3_v4 == TEMPERATURE) { data->pins_v3_v4_values[1] = - adltc2990_get_property_value(dev, TEMPERATURE, V3); + adltc2990_fetch_property_value(dev, TEMPERATURE, V3); } break; } @@ -450,17 +441,17 @@ static const struct sensor_driver_api adltc2990_driver_api = { .temp_format = DT_INST_PROP(inst, temperature_format), \ .acq_format = DT_INST_PROP(inst, acquistion_format), \ .measurement_mode = DT_INST_PROP(inst, measurement_mode), \ - .pins_v1_v2.pins_current_resistor = \ + .pins_v1_v2.pins_current_resistor = \ DT_INST_PROP_OR(inst, pins_v1_v2_current_resistor, 1), \ - .pins_v1_v2.voltage_divider_resistors.v1_r1_r2 = \ + .pins_v1_v2.voltage_divider_resistors.v1_r1_r2 = \ DT_INST_PROP_OR(inst, pin_v1_voltage_divider_resistors, NULL), \ - .pins_v1_v2.voltage_divider_resistors.v2_r1_r2 = \ + .pins_v1_v2.voltage_divider_resistors.v2_r1_r2 = \ DT_INST_PROP_OR(inst, pin_v2_voltage_divider_resistors, NULL), \ - .pins_v3_v4.pins_current_resistor = \ + .pins_v3_v4.pins_current_resistor = \ DT_INST_PROP_OR(inst, pins_v3_v4_current_resistor, 1), \ - .pins_v3_v4.voltage_divider_resistors.v3_r1_r2 = \ + .pins_v3_v4.voltage_divider_resistors.v3_r1_r2 = \ DT_INST_PROP_OR(inst, pin_v3_voltage_divider_resistors, NULL), \ - .pins_v3_v4.voltage_divider_resistors.v4_r1_r2 = \ + .pins_v3_v4.voltage_divider_resistors.v4_r1_r2 = \ DT_INST_PROP_OR(inst, pin_v4_voltage_divider_resistors, NULL)}; \ \ SENSOR_DEVICE_DT_INST_DEFINE(inst, adltc2990_init, NULL, &adltc2990_data_##inst, \ diff --git a/drivers/sensor/adltc2990/adltc2990.h b/drivers/sensor/adltc2990/adltc2990.h index f1c20d33b23..73acab32110 100644 --- a/drivers/sensor/adltc2990/adltc2990.h +++ b/drivers/sensor/adltc2990/adltc2990.h @@ -1,6 +1,5 @@ /* * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG - * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,14 +18,14 @@ enum adltc2990_monitor_pins { V4, INTERNAL_TEMPERATURE, SUPPLY_VOLTAGE -} adltc2990_monitor_pins; +}; enum adltc2990_monitoring_type { NOTHING, VOLTAGE_DIFFERENTIAL, VOLTAGE_SINGLEENDED, TEMPERATURE -} adltc2990_monitoring_type; +}; union voltage_divider_resistors { struct { diff --git a/drivers/sensor/adltc2990/adltc2990_reg.h b/drivers/sensor/adltc2990/adltc2990_reg.h index 3b23b8b066f..57ff3ba25fd 100644 --- a/drivers/sensor/adltc2990/adltc2990_reg.h +++ b/drivers/sensor/adltc2990/adltc2990_reg.h @@ -1,6 +1,5 @@ /* * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG - * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,9 +43,9 @@ #define ADLTC2990_MEASURE_PINS_V3_V4_ONLY 2U #define ADLTC2990_MEASURE_ALL_PINS_PER_MODE_2_0 3U -#define ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR 30518 +#define ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR 30518 #define ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR 1942 -#define ADLTC2990_TEMPERATURE_CONVERSION_FACTOR 62500 +#define ADLTC2990_TEMPERATURE_CONVERSION_FACTOR 62500 #define ADLTC2990_MODE_2_0_MAX_VALUE 7U #define ADLTC2990_MODE_4_3_MAX_VALUE 3U From 9681a2abca7c3b5430a90f54b05d7b939693bd6f Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Tue, 17 Oct 2023 17:28:33 +0200 Subject: [PATCH 2631/4498] sensors: bugfix: adi: minor bugfixes in adltc2990 This commit fixes minor bugs in adltc2990 sensor Signed-off-by: Jilay Pandya --- drivers/sensor/adltc2990/adltc2990.c | 48 ++++++++++++++---------- drivers/sensor/adltc2990/adltc2990.h | 1 + drivers/sensor/adltc2990/adltc2990_reg.h | 8 ++-- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/drivers/sensor/adltc2990/adltc2990.c b/drivers/sensor/adltc2990/adltc2990.c index 29d181a4211..d9ac1643306 100644 --- a/drivers/sensor/adltc2990/adltc2990.c +++ b/drivers/sensor/adltc2990/adltc2990.c @@ -183,17 +183,18 @@ static int32_t adltc2990_fetch_property_value(const struct device *dev, i2c_reg_read_byte_dt(&cfg->bus, msb_address, &msb_value); i2c_reg_read_byte_dt(&cfg->bus, lsb_address, &lsb_value); uint16_t conversion_factor; - uint8_t negative_bit_index; + uint8_t negative_bit_index = 14U, sensor_val_divisor = 100U; if (type == VOLTAGE_SINGLEENDED) { conversion_factor = ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR; - negative_bit_index = 14; } else if (type == VOLTAGE_DIFFERENTIAL) { conversion_factor = ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR; - negative_bit_index = 14; } else if (type == TEMPERATURE) { conversion_factor = ADLTC2990_TEMPERATURE_CONVERSION_FACTOR; - negative_bit_index = 12; + if (cfg->temp_format == ADLTC2990_TEMPERATURE_FORMAT_CELSIUS) { + negative_bit_index = 12U; + } + sensor_val_divisor = 1U; } else { LOG_ERR("unknown type"); return -EINVAL; @@ -203,7 +204,7 @@ static int32_t adltc2990_fetch_property_value(const struct device *dev, int32_t voltage_value = (value << (31 - negative_bit_index)) >> (31 - negative_bit_index); - return (voltage_value * conversion_factor) / 100; + return (voltage_value * conversion_factor) / sensor_val_divisor; } static int adltc2990_init(const struct device *dev) @@ -253,15 +254,15 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { data->pins_v1_v2_values[0] = - (adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1) * - ADLTC2990_MICROOHM_CONVERSION_FACTOR) / - cfg->pins_v1_v2.pins_current_resistor; + adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1) * + (ADLTC2990_MICROOHM_CONVERSION_FACTOR / + (float)cfg->pins_v1_v2.pins_current_resistor); } if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { data->pins_v3_v4_values[0] = - (adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3) * - ADLTC2990_MICROOHM_CONVERSION_FACTOR) / - cfg->pins_v3_v4.pins_current_resistor; + adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3) * + (ADLTC2990_MICROOHM_CONVERSION_FACTOR / + (float)cfg->pins_v3_v4.pins_current_resistor); } break; } @@ -275,15 +276,19 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1); } else if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { uint32_t v1_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; - uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; - voltage_divider_ratio = DIV_ROUND_CLOSEST(v1_r1 + v1_r2, v1_r2); + + uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[1]; + + voltage_divider_ratio = (v1_r1 + v1_r2) / (float)v1_r2; data->pins_v1_v2_values[0] = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V1) * voltage_divider_ratio; uint32_t v2_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; + uint32_t v2_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; - voltage_divider_ratio = DIV_ROUND_CLOSEST(v2_r1 + v2_r2, v2_r2); + + voltage_divider_ratio = (v2_r1 + v2_r2) / (float)v2_r2; data->pins_v1_v2_values[1] = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V2) * voltage_divider_ratio; @@ -294,15 +299,19 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3); } else if (mode_v3_v4 == VOLTAGE_SINGLEENDED) { uint32_t v3_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; + uint32_t v3_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; - voltage_divider_ratio = DIV_ROUND_CLOSEST(v3_r1 + v3_r2, v3_r2); + + voltage_divider_ratio = (v3_r1 + v3_r2) / (float)v3_r2; data->pins_v3_v4_values[0] = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V3) * voltage_divider_ratio; uint32_t v4_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; + uint32_t v4_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; - voltage_divider_ratio = DIV_ROUND_CLOSEST((v4_r1 + v4_r2), v4_r2); + + voltage_divider_ratio = (v4_r1 + v4_r2) / (float)v4_r2; data->pins_v3_v4_values[1] = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V4) * voltage_divider_ratio; @@ -319,7 +328,7 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel adltc2990_fetch_property_value(dev, TEMPERATURE, V1); } if (mode_v3_v4 == TEMPERATURE) { - data->pins_v3_v4_values[1] = + data->pins_v3_v4_values[0] = adltc2990_fetch_property_value(dev, TEMPERATURE, V3); } break; @@ -359,8 +368,8 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c switch (chan) { case SENSOR_CHAN_DIE_TEMP: { - val->val1 = data->internal_temperature / 10000; - val->val2 = data->internal_temperature % 10000; + val->val1 = (data->internal_temperature) / 1000000; + val->val2 = (data->internal_temperature) % 1000000; LOG_DBG("Internal Temperature Value is:%d.%d", val->val1, val->val2); break; } @@ -379,6 +388,7 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c LOG_DBG("Getting V3-V4"); num_values_v3_v4 = ADLTC2990_VOLTAGE_DIFF_VALUES; } + /* Add VCC to the last index */ val[num_values_v1_v2 + num_values_v3_v4].val1 = data->supply_voltage / 1000000; val[num_values_v1_v2 + num_values_v3_v4].val2 = data->supply_voltage % 1000000; break; diff --git a/drivers/sensor/adltc2990/adltc2990.h b/drivers/sensor/adltc2990/adltc2990.h index 73acab32110..af2d1995531 100644 --- a/drivers/sensor/adltc2990/adltc2990.h +++ b/drivers/sensor/adltc2990/adltc2990.h @@ -9,6 +9,7 @@ #include #include #include +#include #include enum adltc2990_monitor_pins { diff --git a/drivers/sensor/adltc2990/adltc2990_reg.h b/drivers/sensor/adltc2990/adltc2990_reg.h index 57ff3ba25fd..7f5a82bebac 100644 --- a/drivers/sensor/adltc2990/adltc2990_reg.h +++ b/drivers/sensor/adltc2990/adltc2990_reg.h @@ -43,11 +43,13 @@ #define ADLTC2990_MEASURE_PINS_V3_V4_ONLY 2U #define ADLTC2990_MEASURE_ALL_PINS_PER_MODE_2_0 3U -#define ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR 30518 -#define ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR 1942 -#define ADLTC2990_TEMPERATURE_CONVERSION_FACTOR 62500 +#define ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR 30518U +#define ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR 1942U +#define ADLTC2990_TEMPERATURE_CONVERSION_FACTOR 62500U #define ADLTC2990_MODE_2_0_MAX_VALUE 7U #define ADLTC2990_MODE_4_3_MAX_VALUE 3U +#define ADLTC2990_TEMPERATURE_FORMAT_CELSIUS 0U + #endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_REG_H */ From ba8240802bac123ab7068fddd62d80e65d6bab5f Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Tue, 17 Oct 2023 17:31:12 +0200 Subject: [PATCH 2632/4498] sensors: tests: adi: add tests for adltc2990 This commit adds tests for various configurations of adltc2990 Signed-off-by: Jilay Pandya --- tests/drivers/sensor/adltc2990/CMakeLists.txt | 8 + .../adltc2990/boards/native_posix.overlay | 62 +++ tests/drivers/sensor/adltc2990/prj.conf | 18 + tests/drivers/sensor/adltc2990/src/main.c | 374 ++++++++++++++++++ tests/drivers/sensor/adltc2990/testcase.yaml | 10 + 5 files changed, 472 insertions(+) create mode 100644 tests/drivers/sensor/adltc2990/CMakeLists.txt create mode 100644 tests/drivers/sensor/adltc2990/boards/native_posix.overlay create mode 100644 tests/drivers/sensor/adltc2990/prj.conf create mode 100644 tests/drivers/sensor/adltc2990/src/main.c create mode 100644 tests/drivers/sensor/adltc2990/testcase.yaml diff --git a/tests/drivers/sensor/adltc2990/CMakeLists.txt b/tests/drivers/sensor/adltc2990/CMakeLists.txt new file mode 100644 index 00000000000..5ef69b69d50 --- /dev/null +++ b/tests/drivers/sensor/adltc2990/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/sensor/adltc2990/boards/native_posix.overlay b/tests/drivers/sensor/adltc2990/boards/native_posix.overlay new file mode 100644 index 00000000000..9497214ad44 --- /dev/null +++ b/tests/drivers/sensor/adltc2990/boards/native_posix.overlay @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-License-Identifier: Apache-2.0 + */ + +&i2c0 { + adltc2990_1_3: adltc2990_1_3@c { + compatible = "adi,adltc2990"; + reg = <0xc>; + temperature-format = <0>; + acquistion-format = <1>; + measurement-mode = <1 3>; + pins-v1-v2-current-resistor = <1000000>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <0 1>; + pin-v2-voltage-divider-resistors = <0 1>; + pin-v3-voltage-divider-resistors = <0 1>; + pin-v4-voltage-divider-resistors = <0 1>; + }; + + adltc2990_5_3: adltc2990_5_3@d { + compatible = "adi,adltc2990"; + reg = <0xd>; + temperature-format = <1>; + acquistion-format = <1>; + measurement-mode = <5 3>; + pins-v1-v2-current-resistor = <1000000>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <0 1>; + pin-v2-voltage-divider-resistors = <0 1>; + pin-v3-voltage-divider-resistors = <0 1>; + pin-v4-voltage-divider-resistors = <0 1>; + }; + + adltc2990_6_3: adltc2990_6_3@e { + compatible = "adi,adltc2990"; + reg = <0xe>; + temperature-format = <1>; + acquistion-format = <1>; + measurement-mode = <6 3>; + pins-v1-v2-current-resistor = <10000>; + pins-v3-v4-current-resistor = <100000>; + pin-v1-voltage-divider-resistors = <500 1000>; + pin-v2-voltage-divider-resistors = <110000 100000>; + pin-v3-voltage-divider-resistors = <7000 1000>; + pin-v4-voltage-divider-resistors = <500 1000>; + }; + + adltc2990_7_3: adltc2990_7_3@f { + compatible = "adi,adltc2990"; + reg = <0xf>; + temperature-format = <1>; + acquistion-format = <1>; + measurement-mode = <7 3>; + pins-v1-v2-current-resistor = <0>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <500 1000>; + pin-v2-voltage-divider-resistors = <110000 100000>; + pin-v3-voltage-divider-resistors = <7000 1000>; + pin-v4-voltage-divider-resistors = <500 1000>; + }; +}; diff --git a/tests/drivers/sensor/adltc2990/prj.conf b/tests/drivers/sensor/adltc2990/prj.conf new file mode 100644 index 00000000000..a77a941df29 --- /dev/null +++ b/tests/drivers/sensor/adltc2990/prj.conf @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +# Set log levels +CONFIG_I2C_LOG_LEVEL_WRN=y +CONFIG_SENSOR_LOG_LEVEL_WRN=y + +# Enable sensors +CONFIG_SENSOR=y + +# Enable emulation +CONFIG_EMUL=y + +# Enable Floating Point +CONFIG_FPU=y diff --git a/tests/drivers/sensor/adltc2990/src/main.c b/tests/drivers/sensor/adltc2990/src/main.c new file mode 100644 index 00000000000..2f55ed38489 --- /dev/null +++ b/tests/drivers/sensor/adltc2990/src/main.c @@ -0,0 +1,374 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "adltc2990.h" +#include "adltc2990_emul.h" +#include "adltc2990_reg.h" + +/* Colllection of common assertion macros */ +#define CHECK_SINGLE_ENDED_VOLTAGE(sensor_val, index, pin_voltage, r1, r2) \ + zassert_ok(sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE)); \ + zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_VOLTAGE, sensor_val)); \ + zassert_between_inclusive( \ + sensor_val[index].val1 + (double)sensor_val[index].val2 / 1000000, \ + (pin_voltage - 0.01f) * ((r1 + r2) / (float)r2), \ + (pin_voltage + 0.01f) * ((r1 + r2) / (float)r2), \ + "%f Out of Range [%f,%f] input %f, [%dmΩ, %dmΩ] " \ + "\nCheck if the sensor node is configured correctly", \ + sensor_val[index].val1 + (double)sensor_val[index].val2 / 1000000, \ + (pin_voltage - 0.01f) * ((r1 + r2) / (float)r2), \ + (pin_voltage + 0.01f) * ((r1 + r2) / (float)r2), pin_voltage, r1, r2); + +#define CHECK_CURRENT(sensor_val, index, pin_voltage, r_microohms) \ + zassert_ok(sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT)); \ + zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_CURRENT, sensor_val)); \ + zassert_between_inclusive( \ + sensor_val[index].val1 + (double)sensor_val[index].val2 / 1000000, \ + (pin_voltage - 0.01f) * ADLTC2990_MICROOHM_CONVERSION_FACTOR / r_microohms, \ + (pin_voltage + 0.01f) * ADLTC2990_MICROOHM_CONVERSION_FACTOR / r_microohms, \ + "%f Out of Range [%f,%f] input %f, current-resistor: %dµΩ\nCheck if the sensor " \ + "node is configured correctly", \ + sensor_val[index].val1 + (double)sensor_val[index].val2 / 1000000, \ + (pin_voltage - 0.001f) * ADLTC2990_MICROOHM_CONVERSION_FACTOR / r_microohms, \ + (pin_voltage + 0.001f) * ADLTC2990_MICROOHM_CONVERSION_FACTOR / r_microohms, \ + pin_voltage, r_microohms); + +#define CHECK_TEMPERATURE(sensor_val, index, expected_temperature, temperature_type) \ + zassert_ok(sensor_sample_fetch_chan(fixture->dev, temperature_type)); \ + zassert_ok(sensor_channel_get(fixture->dev, temperature_type, sensor_val)); \ + zassert_equal(expected_temperature, \ + sensor_val[index].val1 + (float)sensor_val[index].val2 / 1000000, \ + "expected %f, got %f", expected_temperature, \ + sensor_val[index].val1 + (float)sensor_val[index].val2 / 1000000); + +/*** TEST-SUITE: ADLTC2990 Measurement Mode 1 3***/ + +struct adltc2990_1_3_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_1_3_setup(void) +{ + static struct adltc2990_1_3_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_1_3)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_1_3)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_1_3_before(void *f) +{ + struct adltc2990_1_3_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_1_3, NULL, adltc2990_1_3_setup, adltc2990_1_3_before, NULL, NULL); + +ZTEST_F(adltc2990_1_3, test_die_temperature) +{ + /* The following values are taken from datasheet and should translate to 125°c */ + uint8_t msb = 0b00000111, lsb = 0b11010000; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_LSB, &lsb); + + struct sensor_value temp_value[1]; + + CHECK_TEMPERATURE(temp_value, 0, 125.00, SENSOR_CHAN_DIE_TEMP); + + /*0b00011101 0b10000000 –40.0000*/ + msb = 0b00011101; + lsb = 0b10000000; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_LSB, &lsb); + + CHECK_TEMPERATURE(temp_value, 0, -40.00, SENSOR_CHAN_DIE_TEMP); +} +ZTEST_F(adltc2990_1_3, test_ambient_temperature) +{ + /* 0b00000001 0b10010001 +25.0625 */ + uint8_t msb = 0b00000001, lsb = 0b10010001; + struct sensor_value temp_ambient[1]; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_LSB, &lsb); + + CHECK_TEMPERATURE(temp_ambient, 0, 25.06250, SENSOR_CHAN_AMBIENT_TEMP); +} + +ZTEST_F(adltc2990_1_3, test_current) +{ + /* 0b00111100 0b01011000 +0.300 */ + uint8_t msb_reg_value = 0b00111100, lsb_reg_value = 0b01011000; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb_reg_value); + + struct sensor_value current_values[1]; + const struct adltc2990_config *dev_config = fixture->target->dev->config; + + CHECK_CURRENT(current_values, 0, 0.3, dev_config->pins_v1_v2.pins_current_resistor); + + /* 0b00100000 0b00000000 +0.159 */ + msb_reg_value = 0b00100000, lsb_reg_value = 0b00000000; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb_reg_value); + CHECK_CURRENT(current_values, 0, 0.159, dev_config->pins_v1_v2.pins_current_resistor); +} + +ZTEST_F(adltc2990_1_3, test_V1_MINUS_V2_VCC) +{ + uint8_t msb = 0b01100000, lsb = 0b00000000; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb); + + msb = 0b00000010; + lsb = 0b10001111; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_VCC_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_VCC_LSB, &lsb); + + zassert_ok(sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE)); + + struct sensor_value voltage_values[2]; + + zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_VOLTAGE, voltage_values)); + + float test_value = voltage_values[0].val1 + (float)voltage_values[0].val2 / 1000000; + + zassert_between_inclusive(test_value, -0.16, -0.159, "Out of Range [-0.16,-0.159]%.6f", + test_value); + + test_value = voltage_values[1].val1 + (double)voltage_values[1].val2 / 1000000; + zassert_between_inclusive(test_value, 2.69, 2.7, "Out of Range [2.69, 2.7]%.6f", + test_value); +} + +/*** TEST-SUITE: ADLTC2990 Measurement Mode 5 3***/ + +struct adltc2990_5_3_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_5_3_setup(void) +{ + static struct adltc2990_5_3_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_5_3)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_5_3)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_5_3_before(void *f) +{ + struct adltc2990_5_3_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_5_3, NULL, adltc2990_5_3_setup, adltc2990_5_3_before, NULL, NULL); + +ZTEST_F(adltc2990_5_3, test_ambient_temperature) +{ + /*Kelvin 0b00010001 0b00010010 273.1250*/ + uint8_t msb = 0b00010001, lsb = 0b00010010; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb); + + struct sensor_value temp_value[2]; + + CHECK_TEMPERATURE(temp_value, 0, 273.1250, SENSOR_CHAN_AMBIENT_TEMP); + + /*Kelvin 0b00001110 0b10010010 233.125*/ + msb = 0b00001110; + lsb = 0b10010010; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_LSB, &lsb); + CHECK_TEMPERATURE(temp_value, 1, 233.1250, SENSOR_CHAN_AMBIENT_TEMP); +} + +ZTEST_F(adltc2990_5_3, test_die_temperature) +{ + /*0b00011000 0b11100010 398.1250*/ + uint8_t msb = 0b00011000, lsb = 0b11100010; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_LSB, &lsb); + + struct sensor_value temp_value[1]; + + CHECK_TEMPERATURE(temp_value, 0, 398.1250, SENSOR_CHAN_DIE_TEMP); +} + +/*** TEST-SUITE: ADLTC2990 Measurement Mode 7 3***/ + +struct adltc2990_6_3_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_6_3_setup(void) +{ + static struct adltc2990_6_3_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_6_3)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_6_3)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_6_3_before(void *f) +{ + struct adltc2990_6_3_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_6_3, NULL, adltc2990_6_3_setup, adltc2990_6_3_before, NULL, NULL); + +ZTEST_F(adltc2990_6_3, test_current) +{ + /* 0b00111100 0b01011000 +0.300 */ + uint8_t msb_reg_value = 0b00111100, lsb_reg_value = 0b01011000; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb_reg_value); + + struct sensor_value current_values[2]; + const struct adltc2990_config *dev_config = fixture->target->dev->config; + + CHECK_CURRENT(current_values, 0, 0.3, dev_config->pins_v1_v2.pins_current_resistor); + + /* 0b00100000 0b00000000 +0.159 */ + msb_reg_value = 0b00100000, lsb_reg_value = 0b00000000; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_LSB, &lsb_reg_value); + CHECK_CURRENT(current_values, 1, 0.159, dev_config->pins_v3_v4.pins_current_resistor); +} + +/*** TEST-SUITE: ADLTC2990 Measurement Mode 7 3***/ +struct adltc2990_7_3_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_7_3_setup(void) +{ + static struct adltc2990_7_3_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_7_3)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_7_3)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_7_3_before(void *f) +{ + struct adltc2990_7_3_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_7_3, NULL, adltc2990_7_3_setup, adltc2990_7_3_before, NULL, NULL); + +ZTEST_F(adltc2990_7_3, test_available_channels) +{ + zassert_equal(-EINVAL, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP)); + zassert_equal(-EINVAL, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT)); +} + +ZTEST_F(adltc2990_7_3, test_die_temperature) +{ + /* The following values are taken from datasheet and should translate to 398.1250K */ + + uint8_t msb = 0b00011000, lsb = 0b11100010; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_MSB, &msb); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_LSB, &lsb); + + struct sensor_value die_temp_value[1]; + + CHECK_TEMPERATURE(die_temp_value, 0, 398.1250, SENSOR_CHAN_DIE_TEMP); +} + +ZTEST_F(adltc2990_7_3, test_V1_V2_V3_V4_VCC) +{ + /* 0b00111111 0b11111111 >5 */ + uint8_t msb_reg_value = 0b00111111, lsb_reg_value = 0b11111111; + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V1_LSB, &lsb_reg_value); + + /* 0b00101100 0b11001101 3.500 */ + msb_reg_value = 0b00101100; + lsb_reg_value = 0b11001101; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V2_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V2_LSB, &lsb_reg_value); + + /* 0b00011111 0b11111111 2.500 */ + msb_reg_value = 0b00011111; + lsb_reg_value = 0b11111111; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V3_LSB, &lsb_reg_value); + + /* 0b01111100 0b00101001 –0.300 */ + msb_reg_value = 0b01111100; + lsb_reg_value = 0b00101001; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V4_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_V4_LSB, &lsb_reg_value); + + /* VCC = 6V */ + msb_reg_value = 0b00101100; + lsb_reg_value = 0b11001101; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_VCC_MSB, &msb_reg_value); + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_VCC_LSB, &lsb_reg_value); + + struct sensor_value voltage_values[5]; + + const struct adltc2990_config *dev_config = fixture->dev->config; + + CHECK_SINGLE_ENDED_VOLTAGE(voltage_values, 0, 5.0, + dev_config->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0], + dev_config->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[1]); + + CHECK_SINGLE_ENDED_VOLTAGE(voltage_values, 1, 3.5, + dev_config->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0], + dev_config->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]); + + CHECK_SINGLE_ENDED_VOLTAGE(voltage_values, 2, 2.5, + dev_config->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0], + dev_config->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]); + + CHECK_SINGLE_ENDED_VOLTAGE(voltage_values, 3, -0.3, + dev_config->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0], + dev_config->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]); + + float test_value = voltage_values[4].val1 + (double)voltage_values[4].val2 / 1000000; + + zassert_between_inclusive(test_value, 6.0, 6.1, "Out of Range [6.0,6.1] %.6f", test_value); + + zassert_equal(6, voltage_values[4].val1); +} diff --git a/tests/drivers/sensor/adltc2990/testcase.yaml b/tests/drivers/sensor/adltc2990/testcase.yaml new file mode 100644 index 00000000000..09b0519416d --- /dev/null +++ b/tests/drivers/sensor/adltc2990/testcase.yaml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.sensor.adltc2990: + tags: + - drivers + - sensor + - subsys + platform_allow: native_posix From 7579eadaaf2eb5f0fe0f9585b09ceefa666e733c Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 19 Oct 2023 16:39:48 +0200 Subject: [PATCH 2633/4498] modules: canopennode: make the CANopenNode module optional Make the CANopenNode module, which provides a CANopen protocol implementation, optional. Signed-off-by: Henrik Brix Andersen --- samples/modules/canopennode/README.rst | 7 +++++++ submanifests/optional.yaml | 6 ++++++ west.yml | 3 --- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/samples/modules/canopennode/README.rst b/samples/modules/canopennode/README.rst index ae6f135ae30..8d0a3f00854 100644 --- a/samples/modules/canopennode/README.rst +++ b/samples/modules/canopennode/README.rst @@ -26,6 +26,13 @@ Requirements Building and Running ******************** +First, ensure the optional CANopenNode module is enabled and available: + + .. code-block:: console + + west config manifest.group-filter +optional + west update canopennode + Building and Running for TWR-KE18F ================================== The :ref:`twr_ke18f` board is equipped with an onboard CAN diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index dbcfc363737..54b3d77c0cb 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -3,6 +3,12 @@ manifest: - name: upstream url-base: https://github.com/zephyrproject-rtos projects: + - name: canopennode + revision: dec12fa3f0d790cafa8414a4c2930ea71ab72ffd + path: modules/lib/canopennode + remote: upstream + groups: + - optional - name: chre revision: 3b32c76efee705af146124fb4190f71be5a4e36e path: modules/lib/chre diff --git a/west.yml b/west.yml index cb2e33ef59b..69f933336ee 100644 --- a/west.yml +++ b/west.yml @@ -115,9 +115,6 @@ manifest: revision: eed6d7038e839153e340bd333bc43541cb90ba64 groups: - babblesim - - name: canopennode - revision: dec12fa3f0d790cafa8414a4c2930ea71ab72ffd - path: modules/lib/canopennode - name: cmsis revision: 5a00331455dd74e31e80efa383a489faea0590e3 path: modules/hal/cmsis From f9035a24fcb76b8a0ff2d596f0aad3872db84675 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 10 Oct 2023 15:51:30 +0300 Subject: [PATCH 2634/4498] manifest: Add hostap module Add new hostap module that will support Wi-Fi supplicant functionality. Signed-off-by: Jukka Rissanen --- west.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/west.yml b/west.yml index 69f933336ee..080ee476ef0 100644 --- a/west.yml +++ b/west.yml @@ -253,6 +253,10 @@ manifest: path: modules/hal/xtensa groups: - hal + - name: hostap + repo-path: hostap + path: modules/lib/hostap + revision: 7adaff26baa48e26a32c576125e0a749a5239b12 - name: libmetal revision: 03140d7f4bd9ba474ebfbb6256e84a9089248e67 path: modules/hal/libmetal From ab5821a8c8b7897fed3d6046bf885f4d4d1d6f47 Mon Sep 17 00:00:00 2001 From: Sridhar Nuvusetty Date: Thu, 7 Jul 2022 12:36:27 +0530 Subject: [PATCH 2635/4498] hostap: Add build support for Zephyr Only adds basic build support using Zephyr. Crypto support is disabled till the MbedTLS integration is complete. Signed-off-by: Sridhar Nuvusetty Signed-off-by: Sachin Kulkarni Signed-off-by: Ravi Dondaputi Signed-off-by: Krishna T --- MAINTAINERS.yml | 10 ++++ modules/Kconfig | 1 + modules/hostap/CMakeLists.txt | 84 +++++++++++++++++++++++++++ modules/hostap/Kconfig | 104 ++++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 modules/hostap/CMakeLists.txt create mode 100644 modules/hostap/Kconfig diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 564ff040d7f..15580833acb 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3608,6 +3608,16 @@ West: labels: - "area: Sensors" +"West project: hostap": + status: maintained + maintainers: + - krish2718 + - jukkar + files: + - modules/hostap/ + labels: + - "area: Wi-Fi" + Xtensa arch: status: maintained maintainers: diff --git a/modules/Kconfig b/modules/Kconfig index e1d5065158b..0c1b240efec 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -43,6 +43,7 @@ source "modules/Kconfig.xtensa" source "modules/zcbor/Kconfig" source "modules/Kconfig.mcuboot" source "modules/Kconfig.intel" +source "modules/hostap/Kconfig" comment "Unavailable modules, please install those via the project manifest." diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt new file mode 100644 index 00000000000..ed6b8185873 --- /dev/null +++ b/modules/hostap/CMakeLists.txt @@ -0,0 +1,84 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_WIFI_NM_WPA_SUPPLICANT) + +zephyr_library() + +set(HOSTAP_BASE ${ZEPHYR_HOSTAP_MODULE_DIR}) +set(WIFI_NM_WPA_SUPPLICANT_BASE ${HOSTAP_BASE}/wpa_supplicant) +set(HOSTAP_SRC_BASE ${HOSTAP_BASE}/src) + +set(CMAKE_EXE_LINKER_FLAGS "--specs=nosys.specs -lnosys") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMISSING_SYSCALL_NAMES") + +zephyr_compile_definitions( + CONFIG_ZEPHYR +) + +zephyr_include_directories( + ${HOSTAP_BASE}/ + ${WIFI_NM_WPA_SUPPLICANT_BASE}/ + ${HOSTAP_SRC_BASE}/ +) + +zephyr_library_compile_definitions( + TLS_DEFAULT_CIPHERS=\""DEFAULT:!EXP:!LOW"\" + CONFIG_SME + CONFIG_NO_CONFIG_WRITE + CONFIG_NO_CONFIG_BLOBS + CONFIG_CTRL_IFACE + CONFIG_NO_RANDOM_POOL + CONFIG_NO_WPA + CONFIG_NO_PBKDF2 + ) + +zephyr_library_include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${HOSTAP_BASE}/ + ${HOSTAP_SRC_BASE}/utils + ${HOSTAP_SRC_BASE}/drivers + ${HOSTAP_BASE}/src + ${ZEPHYR_BASE}/include + ${ZEPHYR_BASE}/include/net +) + +zephyr_library_sources( + ${HOSTAP_SRC_BASE}/common/wpa_common.c + ${HOSTAP_SRC_BASE}/common/ieee802_11_common.c + ${HOSTAP_SRC_BASE}/common/hw_features_common.c + ${HOSTAP_SRC_BASE}/common/wpa_ctrl.c + ${HOSTAP_SRC_BASE}/common/cli.c + + ${HOSTAP_SRC_BASE}/drivers/driver_common.c + ${HOSTAP_SRC_BASE}/drivers/drivers.c + ${HOSTAP_SRC_BASE}/utils/base64.c + ${HOSTAP_SRC_BASE}/utils/common.c + ${HOSTAP_SRC_BASE}/utils/wpabuf.c + ${HOSTAP_SRC_BASE}/utils/bitfield.c + ${HOSTAP_SRC_BASE}/utils/eloop.c + ${HOSTAP_SRC_BASE}/utils/os_zephyr.c + ${HOSTAP_SRC_BASE}/utils/wpa_debug_zephyr.c + ${HOSTAP_SRC_BASE}/crypto/crypto_none.c + ${HOSTAP_SRC_BASE}/crypto/tls_none.c + + ${WIFI_NM_WPA_SUPPLICANT_BASE}/config.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/notify.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/eap_register.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/op_classes.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/rrm.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/wmm_ac.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/config_none.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/bssid_ignore.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/wpas_glue.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/scan.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/ctrl_iface.c + + # Zephyr specific files (glue code) + # TBD +) + +endif() diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig new file mode 100644 index 00000000000..ae340bef0ad --- /dev/null +++ b/modules/hostap/Kconfig @@ -0,0 +1,104 @@ +# WPA Supplicant configuration options +# +# Copyright (c) 2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +config WIFI_NM_WPA_SUPPLICANT + bool "WPA Suplicant from hostap project [EXPERIMENTAL]" + select POSIX_CLOCK + select NET_SOCKETS + select NET_SOCKETS_PACKET + select NET_SOCKETPAIR + select NET_L2_WIFI_MGMT + select WIFI_NM + select EXPERIMENTAL + help + WPA supplicant as a network management backend for WIFI_NM. + +config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE + int "Stack size for wpa_supplicant thread" + default 8192 + +config NET_SOCKETPAIR_BUFFER_SIZE + default 4096 + +config POSIX_MAX_FDS + # l2_packet - 1 + # ctrl_iface - 2 * socketpairs = 4(local and global) + # z_wpa_event_sock - 1 socketpair = 2 + # Remaining left for the applications running in default configuration + default 16 if !POSIX_API + +# Control interface is stack heavy (buffers + snprintfs) +# Making calls to RPU from net_mgmt callbacks (status - RSSI) +config NET_MGMT_EVENT_STACK_SIZE + default 4096 + +config NET_SOCKETS_POLL_MAX + default 6 + + +# Supplicant API is stack heavy (buffers + snprintfs) and control interface +# uses socketpair which pushes the stack usage causing overflow for 2048 bytes. +config SYSTEM_WORKQUEUE_STACK_SIZE + default 2560 + +module = WIFI_NM_WPA_SUPPLICANT +module-str = WPA supplicant +source "subsys/logging/Kconfig.template.log_config" + +config WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL + int "Min compiled-in debug message level for WPA supplicant" + default 0 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DBG # MSG_EXCESSIVE + default 3 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF # MSG_INFO + default 4 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_WRN # MSG_WARNING + default 5 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_ERR # MSG_ERROR + default 6 + help + Minimum priority level of a debug message emitted by WPA supplicant that + is compiled-in the firmware. See wpa_debug.h file of the supplicant for + available levels and functions for emitting the messages. Note that + runtime filtering can also be configured in addition to the compile-time + filtering. + +if WIFI_NM_WPA_SUPPLICANT + +# Create hidden config options that are used in hostap. This way we do not need +# to mark them as allowed for CI checks, and also someone else cannot use the +# same name options. + +config SME + bool + default y + +config NO_CONFIG_WRITE + bool + default y + +config NO_CONFIG_BLOBS + bool + default y + +config CTRL_IFACE + bool + default y + +config NO_RANDOM_POOL + bool + default y + +config NO_WPA + bool + default y + +config NO_PBKDF2 + bool + default y + +config ZEPHYR + bool + default y + +endif # WIFI_NM_WPA_SUPPLICANT From 83c875adabcc94f04c6feccc17735a8094649ec4 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 20 Oct 2023 15:36:56 +0300 Subject: [PATCH 2636/4498] hostap: Move the relevant config options away from hostap Moving the Zephyr specific config options from modules/hostap/Kconfig to corresponding Kconfig where the option is specified. Signed-off-by: Jukka Rissanen --- kernel/Kconfig | 1 + lib/posix/Kconfig | 1 + modules/hostap/Kconfig | 26 ++++++-------------------- subsys/net/ip/Kconfig.mgmt | 1 + subsys/net/lib/sockets/Kconfig | 2 ++ 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/kernel/Kconfig b/kernel/Kconfig index 211830cfe86..41e97e1809a 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -651,6 +651,7 @@ menu "Work Queue Options" config SYSTEM_WORKQUEUE_STACK_SIZE int "System workqueue stack size" default 4096 if COVERAGE_GCOV + default 2560 if WIFI_NM_WPA_SUPPLICANT default 1024 config SYSTEM_WORKQUEUE_PRIORITY diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index 199ed956af2..3fd01313474 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -5,6 +5,7 @@ config POSIX_MAX_FDS int "Maximum number of open file descriptors" + default 16 if WIFI_NM_WPA_SUPPLICANT default 16 if POSIX_API default 4 help diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index ae340bef0ad..5ff3c13a494 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -21,29 +21,15 @@ config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" default 8192 -config NET_SOCKETPAIR_BUFFER_SIZE - default 4096 - -config POSIX_MAX_FDS - # l2_packet - 1 - # ctrl_iface - 2 * socketpairs = 4(local and global) - # z_wpa_event_sock - 1 socketpair = 2 - # Remaining left for the applications running in default configuration - default 16 if !POSIX_API - -# Control interface is stack heavy (buffers + snprintfs) -# Making calls to RPU from net_mgmt callbacks (status - RSSI) -config NET_MGMT_EVENT_STACK_SIZE - default 4096 - -config NET_SOCKETS_POLL_MAX - default 6 - +# Currently we default POSIX_MAX_FDS to 16 in lib/posix/Kconfig +# l2_packet - 1 +# ctrl_iface - 2 * socketpairs = 4(local and global) +# z_wpa_event_sock - 1 socketpair = 2 +# Remaining left for the applications running in default configuration # Supplicant API is stack heavy (buffers + snprintfs) and control interface # uses socketpair which pushes the stack usage causing overflow for 2048 bytes. -config SYSTEM_WORKQUEUE_STACK_SIZE - default 2560 +# So we set SYSTEM_WORKQUEUE_STACK_SIZE default to 2560 in kernel/Kconfig module = WIFI_NM_WPA_SUPPLICANT module-str = WPA supplicant diff --git a/subsys/net/ip/Kconfig.mgmt b/subsys/net/ip/Kconfig.mgmt index 2ecfc9d028c..cc5c514afde 100644 --- a/subsys/net/ip/Kconfig.mgmt +++ b/subsys/net/ip/Kconfig.mgmt @@ -21,6 +21,7 @@ if NET_MGMT_EVENT config NET_MGMT_EVENT_STACK_SIZE int "Stack size for the inner thread handling event callbacks" + default 4096 if WIFI_NM_WPA_SUPPLICANT default 2048 if COVERAGE_GCOV default 840 if X86 default 800 if THREAD_LOCAL_STORAGE diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index b47fb91ab06..b2da30c1e48 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -42,6 +42,7 @@ config NET_SOCKETS_POSIX_NAMES config NET_SOCKETS_POLL_MAX int "Max number of supported poll() entries" + default 6 if WIFI_NM_WPA_SUPPLICANT default 3 help Maximum number of entries supported for poll() call. @@ -261,6 +262,7 @@ if NET_SOCKETPAIR config NET_SOCKETPAIR_BUFFER_SIZE int "Size of the intermediate buffer, in bytes" + default 4096 if WIFI_NM_WPA_SUPPLICANT default 64 range 1 4096 help From 6aea1864c14c0719f2c54ed4ae9cd7148da395a5 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 23 Oct 2023 12:00:18 +0200 Subject: [PATCH 2637/4498] Bluetooth: ISO: Minor fixes for ISO shell If CONFIG_BT_ISO_TEST_PARAMS=y then the CIG and BIG create params was not properly initialized. Modified the TX for BIS and CIS to be more similar Added a timeout on the buffer to avoid any potentional deadlocks. Signed-off-by: Emil Gydesen --- subsys/bluetooth/shell/iso.c | 45 +++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/shell/iso.c b/subsys/bluetooth/shell/iso.c index 89fb273efd7..17b53bb9922 100644 --- a/subsys/bluetooth/shell/iso.c +++ b/subsys/bluetooth/shell/iso.c @@ -24,6 +24,8 @@ #include "bt.h" +#define TX_BUF_TIMEOUT K_SECONDS(1) + static uint32_t cis_sn_last; static uint32_t bis_sn_last; static int64_t cis_sn_last_updated_ticks; @@ -131,7 +133,7 @@ struct bt_iso_chan iso_chan = { }; NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), - 8, NULL); + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); #if defined(CONFIG_BT_ISO_CENTRAL) static struct bt_iso_cig *cig; @@ -189,7 +191,7 @@ static long parse_latency(const struct shell *sh, const char *latency_str) static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) { int err; - struct bt_iso_cig_param param; + struct bt_iso_cig_param param = {0}; struct bt_iso_chan *chans[CIS_ISO_CHAN_COUNT]; if (cig != NULL) { @@ -570,11 +572,16 @@ static int cmd_send(const struct shell *sh, size_t argc, char *argv[]) cis_sdu_interval_us); while (count--) { - buf = net_buf_alloc(&tx_pool, K_FOREVER); + buf = net_buf_alloc(&tx_pool, TX_BUF_TIMEOUT); + if (buf == NULL) { + shell_error(sh, "Failed to get buffer..."); + return -ENOEXEC; + } + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); net_buf_add_mem(buf, buf_data, len); - shell_info(sh, "send: %d bytes of data", len); + shell_info(sh, "send: %d bytes of data with PSN %u", len, cis_sn_last); ret = bt_iso_chan_send(&iso_chan, buf, cis_sn_last, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { @@ -678,23 +685,25 @@ static int cmd_broadcast(const struct shell *sh, size_t argc, char *argv[]) } len = MIN(bis_iso_chan.qos->tx->sdu, CONFIG_BT_ISO_TX_MTU); - bis_sn_last = get_next_sn(bis_sn_last, &bis_sn_last_updated_ticks, bis_sdu_interval_us); while (count--) { - for (int i = 0; i < BIS_ISO_CHAN_COUNT; i++) { - buf = net_buf_alloc(&bis_tx_pool, K_FOREVER); - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - - net_buf_add_mem(buf, buf_data, len); - ret = bt_iso_chan_send(&bis_iso_chan, buf, bis_sn_last, - BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - shell_print(sh, "[%i]: Unable to broadcast: %d", i, -ret); - net_buf_unref(buf); - return -ENOEXEC; - } + buf = net_buf_alloc(&bis_tx_pool, TX_BUF_TIMEOUT); + if (buf == NULL) { + shell_error(sh, "Failed to get buffer..."); + return -ENOEXEC; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + + net_buf_add_mem(buf, buf_data, len); + shell_info(sh, "send: %d bytes of data with PSN %u", len, bis_sn_last); + ret = bt_iso_chan_send(&bis_iso_chan, buf, bis_sn_last, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + shell_print(sh, "Unable to broadcast: %d", -ret); + net_buf_unref(buf); + return -ENOEXEC; } } @@ -706,7 +715,7 @@ static int cmd_broadcast(const struct shell *sh, size_t argc, char *argv[]) static int cmd_big_create(const struct shell *sh, size_t argc, char *argv[]) { int err; - struct bt_iso_big_create_param param; + struct bt_iso_big_create_param param = {0}; struct bt_le_ext_adv *adv = adv_sets[selected_adv]; if (!adv) { From de5e2cc5a28e5137b1d6ac1f87f860e28353d0c5 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Thu, 12 Oct 2023 11:27:39 +0200 Subject: [PATCH 2638/4498] boards: nucleo_wl55jc: add ST Morpho connector nexus node Add a new GPIO nexus node for the ST Morpho connector in the board. Signed-off-by: Marcin Niestroj --- boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts | 1 + .../nucleo_wl55jc/st_morpho_connector.dtsi | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 boards/arm/nucleo_wl55jc/st_morpho_connector.dtsi diff --git a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts index 48822f2fe13..deff3a96cdc 100644 --- a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts +++ b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts @@ -8,6 +8,7 @@ #include #include #include "arduino_r3_connector.dtsi" +#include "st_morpho_connector.dtsi" #include / { diff --git a/boards/arm/nucleo_wl55jc/st_morpho_connector.dtsi b/boards/arm/nucleo_wl55jc/st_morpho_connector.dtsi new file mode 100644 index 00000000000..c2e2a06bb3e --- /dev/null +++ b/boards/arm/nucleo_wl55jc/st_morpho_connector.dtsi @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Marcin Niestroj + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + st_morpho_header: st-morpho-header { + compatible = "st-morpho-header"; + #gpio-cells = <2>; + gpio-map-mask = ; + gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; + gpio-map = , + , /* shared with SWD connected to STLINK */ + , /* shared with SWD connected to STLINK */ + , + , + , + , + , + , + , + , + , + , + + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB7=ON, SB2=OFF, SB6=OFF */ + , + , /* SB9=ON, SB4=OFF, SB10=OFF */ + ; + }; +}; From f2a1038dd2d66c761d7156d53ae21819ad1b296e Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 25 Oct 2023 15:00:21 +0800 Subject: [PATCH 2639/4498] boards: riscv: adp_xc7k_ae350: doc: index.rst Update the supporting driver for adp_xc7k_ae350. Signed-off-by: Kevin Wang --- boards/riscv/adp_xc7k_ae350/doc/index.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boards/riscv/adp_xc7k_ae350/doc/index.rst b/boards/riscv/adp_xc7k_ae350/doc/index.rst index 8c6d7fc14f8..62cae957f11 100644 --- a/boards/riscv/adp_xc7k_ae350/doc/index.rst +++ b/boards/riscv/adp_xc7k_ae350/doc/index.rst @@ -66,6 +66,24 @@ The ``adp_xc7k_ae350`` board configuration supports the following hardware featu +----------------+------------+----------------------+ | UART | on-chip | serial | +----------------+------------+----------------------+ +| COUNTER | on-chip | counter | ++----------------+------------+----------------------+ +| SPI | on-chip | spi | ++----------------+------------+----------------------+ +| I2C | on-chip | i2c | ++----------------+------------+----------------------+ +| EEPROM | on-chip | eeprom | ++----------------+------------+----------------------+ +| FLASH | on-chip | flash | ++----------------+------------+----------------------+ +| HWINFO | on-chip | syscon | ++----------------+------------+----------------------+ +| MAILBOX | on-chip | mbox | ++----------------+------------+----------------------+ +| DMA | on-chip | dma | ++----------------+------------+----------------------+ +| WATCHDOG | on-chip | wdt | ++----------------+------------+----------------------+ Other hardware features are not supported yet. From 8b1a7f88ddacdc29c8679902d67382bdab4057f8 Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Wed, 25 Oct 2023 14:40:55 +0300 Subject: [PATCH 2640/4498] tests: coap_client: Add test case for resending request Add case 'test_resend_request' to test that coap_client resends the message if no response received. Add response code check to case 'test_no_response'. Initialize messages_needing_response[] in test setup. Lower CONFIG_COAP_INIT_ACK_TIMEOUT_MS and decrease delays. Signed-off-by: Juha Ylinen --- tests/net/lib/coap_client/CMakeLists.txt | 2 +- tests/net/lib/coap_client/src/main.c | 88 ++++++++++++++++++++---- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/tests/net/lib/coap_client/CMakeLists.txt b/tests/net/lib/coap_client/CMakeLists.txt index 9486b914706..2e94112f0b0 100644 --- a/tests/net/lib/coap_client/CMakeLists.txt +++ b/tests/net/lib/coap_client/CMakeLists.txt @@ -24,6 +24,6 @@ add_compile_definitions(CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE=48) add_compile_definitions(CONFIG_COAP_CLIENT_STACK_SIZE=1024) add_compile_definitions(CONFIG_COAP_CLIENT_THREAD_PRIORITY=10) add_compile_definitions(CONFIG_COAP_LOG_LEVEL=4) -add_compile_definitions(CONFIG_COAP_INIT_ACK_TIMEOUT_MS=2000) +add_compile_definitions(CONFIG_COAP_INIT_ACK_TIMEOUT_MS=200) add_compile_definitions(CONFIG_COAP_CLIENT_MAX_REQUESTS=2) add_compile_definitions(CONFIG_COAP_CLIENT_MAX_INSTANCES=2) diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index 1a6fd2d88bc..e1240c5e2ed 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(coap_client_test); DEFINE_FFF_GLOBALS; #define FFF_FAKES_LIST(FAKE) -static uint8_t last_response_code; +static int16_t last_response_code; static const char *test_path = "test"; static uint16_t messages_needing_response[2]; @@ -187,6 +187,34 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_response(int sock, void *buf, s return sizeof(ack_data); } +static ssize_t z_impl_zsock_recvfrom_custom_fake_delayed_response(int sock, void *buf, + size_t max_len, int flags, + struct sockaddr *src_addr, + socklen_t *addrlen) +{ + uint16_t last_message_id = 0; + + static uint8_t ack_data[] = { + 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (messages_needing_response[0] != 0) { + last_message_id = messages_needing_response[0]; + messages_needing_response[0] = 0; + } else { + last_message_id = messages_needing_response[1]; + messages_needing_response[1] = 0; + } + + ack_data[2] = (uint8_t) (last_message_id >> 8); + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + k_sleep(K_MSEC(10)); + + return sizeof(ack_data); +} + static ssize_t z_impl_zsock_recvfrom_custom_fake_empty_ack(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) @@ -317,6 +345,8 @@ static void test_setup(void *data) z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake; z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; + messages_needing_response[0] = 0; + messages_needing_response[1] = 0; } void coap_callback(int16_t code, size_t offset, const uint8_t *payload, size_t len, bool last_block, @@ -353,8 +383,40 @@ ZTEST(coap_client, test_get_request) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_resend_request) +{ + int ret = 0; + struct sockaddr address = {0}; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_delayed_response; + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + k_sleep(K_MSEC(300)); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); + zassert_equal(z_impl_zsock_sendto_fake.call_count, 2); } ZTEST(coap_client, test_echo_option) @@ -384,7 +446,7 @@ ZTEST(coap_client, test_echo_option) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } @@ -415,7 +477,7 @@ ZTEST(coap_client, test_echo_option_next_req) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); char *payload = "echo testing"; @@ -430,7 +492,7 @@ ZTEST(coap_client, test_echo_option_next_req) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } @@ -484,7 +546,7 @@ ZTEST(coap_client, test_send_large_data) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } @@ -512,7 +574,9 @@ ZTEST(coap_client, test_no_response) ret = coap_client_req(&client, 0, &address, &client_request, 0); zassert_true(ret >= 0, "Sending request failed, %d", ret); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(300)); + + zassert_equal(last_response_code, -ETIMEDOUT, "Unexpected response"); } ZTEST(coap_client, test_separate_response) @@ -542,9 +606,7 @@ ZTEST(coap_client, test_separate_response) set_socket_events(ZSOCK_POLLIN); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } @@ -577,11 +639,11 @@ ZTEST(coap_client, test_multiple_requests) zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); } @@ -612,5 +674,5 @@ ZTEST(coap_client, test_unmatching_tokens) k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1)); clear_socket_events(); - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(500)); } From b3f3d902628560ececee2922d1cdd50c434dc438 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 25 Oct 2023 13:45:34 +0100 Subject: [PATCH 2641/4498] drivers: regulator: fixed/gpio: Add non-multithreading support Adds support for using the fixed and GPIO regulator drivers when multithreading is disabled, such as in MCUboot. Signed-off-by: Jamie McCrae --- drivers/regulator/regulator_fixed.c | 4 ++++ drivers/regulator/regulator_gpio.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/regulator/regulator_fixed.c b/drivers/regulator/regulator_fixed.c index 390f925cde6..4526b6d2378 100644 --- a/drivers/regulator/regulator_fixed.c +++ b/drivers/regulator/regulator_fixed.c @@ -42,7 +42,11 @@ static int regulator_fixed_enable(const struct device *dev) } if (cfg->off_on_delay_us > 0U) { +#ifdef CONFIG_MULTITHREADING k_sleep(K_USEC(cfg->off_on_delay_us)); +#else + k_busy_wait(cfg->off_on_delay_us); +#endif } return 0; diff --git a/drivers/regulator/regulator_gpio.c b/drivers/regulator/regulator_gpio.c index 93d6ebddff8..e752a9ad457 100644 --- a/drivers/regulator/regulator_gpio.c +++ b/drivers/regulator/regulator_gpio.c @@ -74,7 +74,11 @@ static int regulator_gpio_enable(const struct device *dev) } if (cfg->startup_delay_us > 0U) { +#ifdef CONFIG_MULTITHREADING k_sleep(K_USEC(cfg->startup_delay_us)); +#else + k_busy_wait(cfg->startup_delay_us); +#endif } return 0; From 54fa6f30b8f244d860941ccc0be15714b655c116 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 25 Oct 2023 14:36:43 +0200 Subject: [PATCH 2642/4498] soc: stm32: Enable Debug in stop mode when ZTEST is used Force STM32_ENABLE_DEBUG_SLEEP_STOP option when running tests. This option enables Debug in Sleep/stop states and disables it when disabled (default state). When disabled, it may be impossible to flash the device with runner such as openocd. It's generally working using cubeprogrammer, but it might fail as well with fault configuration. Instead of fixing each test or breaking CI each time a new test is created with CONFIG_PM=y, force this option to be enabled when ZTEST=y (as it was already the case when DEBUG=y). Signed-off-by: Erwan Gouriou --- soc/arm/st_stm32/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/st_stm32/Kconfig b/soc/arm/st_stm32/Kconfig index c644b50a5ff..dcdb22ca26b 100644 --- a/soc/arm/st_stm32/Kconfig +++ b/soc/arm/st_stm32/Kconfig @@ -6,7 +6,7 @@ config SOC_FAMILY_STM32 bool select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE - select STM32_ENABLE_DEBUG_SLEEP_STOP if DEBUG + select STM32_ENABLE_DEBUG_SLEEP_STOP if DEBUG || ZTEST select BUILD_OUTPUT_HEX if SOC_FAMILY_STM32 From 88de0d15a64f32dc82be36a018acad887058d926 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 25 Oct 2023 15:07:10 +0200 Subject: [PATCH 2643/4498] samples: stm32: pm_ble: Enable DEBUG when run with twister Make sure DEBUG is enabled if this test is run in CI. Also re-instantiate CONFIG_PM=y which was abusively removed in a previous change. Signed-off-by: Erwan Gouriou --- samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf | 3 +-- samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf b/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf index 583df4e6ee7..1dff53f1da7 100644 --- a/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf @@ -1,5 +1,4 @@ CONFIG_BT=y CONFIG_BT_DEVICE_NAME="Test beacon" CONFIG_POWEROFF=y - -#CONFIG_DEBUG=y +CONFIG_PM=y diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml b/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml index 3c00f4ef856..0e8e975d19a 100644 --- a/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml @@ -7,3 +7,4 @@ tests: tags: - bluetooth - pm + extra_args: "CONFIG_DEBUG=y" From 6c5400d2e1dbc6fc278dad8cce396208fbecc59a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 24 Oct 2023 22:16:11 +0200 Subject: [PATCH 2644/4498] drivers: can: be consistent in filter_id checks when removing rx filters Change the CAN controller driver implementations for the can_remove_rx_filter() API call to be consistent in their validation of the supplied filter_id. Fixes: #64398 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_loopback.c | 2 +- drivers/can/can_mcan.c | 7 ++++++- drivers/can/can_mcp2515.c | 5 +++++ drivers/can/can_mcux_flexcan.c | 5 ++--- drivers/can/can_native_posix_linux.c | 1 + drivers/can/can_nxp_s32_canxl.c | 5 ++++- drivers/can/can_rcar.c | 3 ++- drivers/can/can_stm32_bxcan.c | 5 ++++- 8 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_loopback.c b/drivers/can/can_loopback.c index 8eb4074cc45..863bf3a69ac 100644 --- a/drivers/can/can_loopback.c +++ b/drivers/can/can_loopback.c @@ -211,7 +211,7 @@ static void can_loopback_remove_rx_filter(const struct device *dev, int filter_i { struct can_loopback_data *data = dev->data; - if (filter_id >= ARRAY_SIZE(data->filters)) { + if (filter_id < 0 || filter_id >= ARRAY_SIZE(data->filters)) { LOG_ERR("filter ID %d out-of-bounds", filter_id); return; } diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index 550f29b2334..9b9fec79ace 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -1149,12 +1149,17 @@ void can_mcan_remove_rx_filter(const struct device *dev, int filter_id) struct can_mcan_data *data = dev->data; int err; + if (filter_id < 0) { + LOG_ERR("filter ID %d out of bounds", filter_id); + return; + } + k_mutex_lock(&data->lock, K_FOREVER); if (filter_id >= cbs->num_std) { filter_id -= cbs->num_std; if (filter_id >= cbs->num_ext) { - LOG_ERR("Wrong filter id"); + LOG_ERR("filter ID %d out of bounds", filter_id); k_mutex_unlock(&data->lock); return; } diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index df403dfac62..4009718e2ba 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -663,6 +663,11 @@ static void mcp2515_remove_rx_filter(const struct device *dev, int filter_id) { struct mcp2515_data *dev_data = dev->data; + if (filter_id < 0 || filter_id >= CONFIG_CAN_MAX_FILTER) { + LOG_ERR("filter ID %d out of bounds", filter_id); + return; + } + k_mutex_lock(&dev_data->mutex, K_FOREVER); dev_data->filter_usage &= ~BIT(filter_id); k_mutex_unlock(&dev_data->mutex); diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index a80204e28c5..84b6bb67c1d 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -922,9 +922,8 @@ static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_i { struct mcux_flexcan_data *data = dev->data; - if (filter_id >= MCUX_FLEXCAN_MAX_RX) { - LOG_ERR("Detach: Filter id >= MAX_RX (%d >= %d)", filter_id, - MCUX_FLEXCAN_MAX_RX); + if (filter_id < 0 || filter_id >= MCUX_FLEXCAN_MAX_RX) { + LOG_ERR("filter ID %d out of bounds", filter_id); return; } diff --git a/drivers/can/can_native_posix_linux.c b/drivers/can/can_native_posix_linux.c index d03ca78841e..7f8a0ea494f 100644 --- a/drivers/can/can_native_posix_linux.c +++ b/drivers/can/can_native_posix_linux.c @@ -239,6 +239,7 @@ static void can_npl_remove_rx_filter(const struct device *dev, int filter_id) struct can_npl_data *data = dev->data; if (filter_id < 0 || filter_id >= ARRAY_SIZE(data->filters)) { + LOG_ERR("filter ID %d out of bounds"); return; } diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index a4ab50838cb..ca6961d27e2 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -396,7 +396,10 @@ static void can_nxp_s32_remove_rx_filter(const struct device *dev, int filter_id struct can_nxp_s32_data *data = dev->data; int mb_indx = ALLOC_IDX_TO_RXMB_IDX(filter_id); - __ASSERT_NO_MSG(filter_id >= 0 && filter_id < CONFIG_CAN_NXP_S32_MAX_RX); + if (filter_id < 0 || filter_id >= CONFIG_CAN_NXP_S32_MAX_RX) { + LOG_ERR("filter ID %d out of bounds", filter_id); + return; + } k_mutex_lock(&data->rx_mutex, K_FOREVER); diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index 1dfaf715414..f015407c22f 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -975,7 +975,8 @@ static void can_rcar_remove_rx_filter(const struct device *dev, int filter_id) { struct can_rcar_data *data = dev->data; - if (filter_id >= CONFIG_CAN_RCAR_MAX_FILTER) { + if (filter_id < 0 || filter_id >= CONFIG_CAN_RCAR_MAX_FILTER) { + LOG_ERR("filter ID %d out of bounds", filter_id); return; } diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index d7eab7aea35..58df8f1db5d 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -1035,7 +1035,10 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id) int bank_num; bool bank_unused; - __ASSERT_NO_MSG(filter_id >= 0 && filter_id < CAN_STM32_MAX_FILTER_ID); + if (filter_id < 0 || filter_id >= CAN_STM32_MAX_FILTER_ID) { + LOG_ERR("filter ID %d out of bounds", filter_id); + return; + } k_mutex_lock(&filter_mutex, K_FOREVER); k_mutex_lock(&data->inst_mutex, K_FOREVER); From 66f5fce68fa1c982df1b2639c49446e3e7bf0df9 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Wed, 18 Oct 2023 13:46:15 +0200 Subject: [PATCH 2645/4498] drivers: mfd: gpio: adjust init priority Take into account the SPI bus init priorirty that can be used for MFD drivers. Signed-off-by: Bartosz Bilas --- drivers/gpio/Kconfig.axp192 | 2 +- drivers/gpio/Kconfig.nct38xx | 6 +++--- drivers/gpio/Kconfig.npm1300 | 2 +- drivers/gpio/Kconfig.npm6001 | 2 +- drivers/mfd/Kconfig | 2 +- drivers/regulator/Kconfig.npm1300 | 4 ++-- drivers/regulator/Kconfig.npm6001 | 2 +- drivers/watchdog/Kconfig.npm1300 | 2 +- drivers/watchdog/Kconfig.npm6001 | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/Kconfig.axp192 b/drivers/gpio/Kconfig.axp192 index a9e648309fb..c81c02d895c 100644 --- a/drivers/gpio/Kconfig.axp192 +++ b/drivers/gpio/Kconfig.axp192 @@ -14,7 +14,7 @@ config GPIO_AXP192 config GPIO_AXP192_INIT_PRIORITY int "AXP192 GPIO driver initialization priority" depends on GPIO_AXP192 - default 80 + default 81 help Initialization priority for the AXP192 GPIO driver. It must be greater than the I2C controller init priority and the mfd driver diff --git a/drivers/gpio/Kconfig.nct38xx b/drivers/gpio/Kconfig.nct38xx index 25e91e3cf09..dfa5cbf9c38 100644 --- a/drivers/gpio/Kconfig.nct38xx +++ b/drivers/gpio/Kconfig.nct38xx @@ -16,14 +16,14 @@ if GPIO_NCT38XX config GPIO_NCT38XX_INIT_PRIORITY int "NCT38XX GPIO init priority" - default 62 + default 82 help NCT38xx GPIO driver initialization priority. The priority must be lower than MFD_INIT_PRIORITY. config GPIO_NCT38XX_PORT_INIT_PRIORITY int "NCT38XX GPIO port init priority" - default 64 + default 84 help NCT38xx GPIO port device driver initialization priority. The priority must be lower than GPIO_NCT38XX_INIT_PRIORITY device. @@ -37,7 +37,7 @@ config GPIO_NCT38XX_ALERT config GPIO_NCT38XX_ALERT_INIT_PRIORITY int "NCT38XX GPIO alert handler init priority" - default 64 + default 84 depends on GPIO_NCT38XX_ALERT help NCT38XX alert handler initialization priority. This initialization diff --git a/drivers/gpio/Kconfig.npm1300 b/drivers/gpio/Kconfig.npm1300 index c3cbf53d6e2..65cb81a3686 100644 --- a/drivers/gpio/Kconfig.npm1300 +++ b/drivers/gpio/Kconfig.npm1300 @@ -13,7 +13,7 @@ config GPIO_NPM1300 config GPIO_NPM1300_INIT_PRIORITY int "nPM1300 GPIO driver initialization priority" depends on GPIO_NPM1300 - default 70 + default 85 help Initialization priority for the nPM1300 GPIO driver. It must be greater than the I2C controller init priority. diff --git a/drivers/gpio/Kconfig.npm6001 b/drivers/gpio/Kconfig.npm6001 index 81fc4cb4a60..b138b101a72 100644 --- a/drivers/gpio/Kconfig.npm6001 +++ b/drivers/gpio/Kconfig.npm6001 @@ -13,6 +13,6 @@ config GPIO_NPM6001 config GPIO_NPM6001_INIT_PRIORITY int "nPM6001 GPIO driver initialization priority" depends on GPIO_NPM6001 - default 65 + default 85 help Initialization priority for the nPM6001 GPIO driver. diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index be84e348c04..3edbbab1fc4 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -14,7 +14,7 @@ source "subsys/logging/Kconfig.template.log_config" config MFD_INIT_PRIORITY int "Initialization priority" - default 60 + default 80 help Multi-function devices initialization priority. diff --git a/drivers/regulator/Kconfig.npm1300 b/drivers/regulator/Kconfig.npm1300 index a003f90f7a9..997934cabb7 100644 --- a/drivers/regulator/Kconfig.npm1300 +++ b/drivers/regulator/Kconfig.npm1300 @@ -14,14 +14,14 @@ if REGULATOR_NPM1300 config REGULATOR_NPM1300_COMMON_INIT_PRIORITY int "nPM1300 regulator driver init priority (common part)" - default 75 + default 85 help Init priority for the Nordic nPM1300 regulator driver (common part). It must be greater than I2C init priority. config REGULATOR_NPM1300_INIT_PRIORITY int "nPM1300 regulator driver init priority" - default 76 + default 86 help Init priority for the Nordic nPM1300 regulator driver. It must be greater than REGULATOR_NPM1300_COMMON_INIT_PRIORITY. diff --git a/drivers/regulator/Kconfig.npm6001 b/drivers/regulator/Kconfig.npm6001 index d4e361876ae..a9c290475de 100644 --- a/drivers/regulator/Kconfig.npm6001 +++ b/drivers/regulator/Kconfig.npm6001 @@ -12,7 +12,7 @@ config REGULATOR_NPM6001 config REGULATOR_NPM6001_INIT_PRIORITY int "nPM6001 regulator driver init priority" - default 76 + default 86 depends on REGULATOR_NPM6001 help Init priority for the Nordic nPM6001 regulator driver. diff --git a/drivers/watchdog/Kconfig.npm1300 b/drivers/watchdog/Kconfig.npm1300 index 8e9cd65024d..b18e4b69b13 100644 --- a/drivers/watchdog/Kconfig.npm1300 +++ b/drivers/watchdog/Kconfig.npm1300 @@ -13,7 +13,7 @@ config WDT_NPM1300 config WDT_NPM1300_INIT_PRIORITY int "nPM1300 Watchdog driver initialization priority" depends on WDT_NPM1300 - default 75 + default 85 help Initialization priority for the nPM1300 Watchdog driver. It must be greater than GPIO_NPM1300_INIT_PRIORITY. diff --git a/drivers/watchdog/Kconfig.npm6001 b/drivers/watchdog/Kconfig.npm6001 index 3230deffc26..0d3f864e5cf 100644 --- a/drivers/watchdog/Kconfig.npm6001 +++ b/drivers/watchdog/Kconfig.npm6001 @@ -13,6 +13,6 @@ config WDT_NPM6001 config WDT_NPM6001_INIT_PRIORITY int "nPM6001 Watchdog driver initialization priority" depends on WDT_NPM6001 - default 65 + default 85 help Initialization priority for the nPM6001 Watchdog driver. From 03a7dfbaa80c7ec96461ab40ca226dae97184f57 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 26 Oct 2023 10:17:19 +0200 Subject: [PATCH 2646/4498] tests: Remove stray uses of CONFIG_ZTEST_NEW_API Commit 345735d0a844d20549c0ce7bc2675ffb3f482804 removed all uses of the now obsolete CONFIG_ZTEST_NEW_API Kconfig option. A couple of stray ones are still remaining in the tree, remove them. Signed-off-by: Carles Cufi --- tests/drivers/sensor/adltc2990/prj.conf | 1 - tests/kconfig/configdefault/prj.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/drivers/sensor/adltc2990/prj.conf b/tests/drivers/sensor/adltc2990/prj.conf index a77a941df29..5a97fffa465 100644 --- a/tests/drivers/sensor/adltc2990/prj.conf +++ b/tests/drivers/sensor/adltc2990/prj.conf @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y # Set log levels CONFIG_I2C_LOG_LEVEL_WRN=y diff --git a/tests/kconfig/configdefault/prj.conf b/tests/kconfig/configdefault/prj.conf index 9228251051e..9467c292689 100644 --- a/tests/kconfig/configdefault/prj.conf +++ b/tests/kconfig/configdefault/prj.conf @@ -1,2 +1 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y From 972e3bce0f6cd177b5be08894dbb678731469788 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 13 Sep 2023 09:52:42 +0200 Subject: [PATCH 2647/4498] MAINTAINERS: add `dts/riscv` to the `RISCV arch` area of maintenance This commit adds the `dts/riscv` directory to the `RISCV arch` area of maintenance. Right now, RISC-V devicetrees are covered only by platform-specific areas (Espressif, ITE). When other RISC-V platform devicetrees are affected in a PR, it is left unassigned. Signed-off-by: Filip Kokosinski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 15580833acb..cb0cdee48bd 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2127,6 +2127,7 @@ RISCV arch: - arch/riscv/ - boards/riscv/ - dts/bindings/riscv/ + - dts/riscv/ - include/zephyr/arch/riscv/ - soc/riscv/ - tests/arch/riscv/ From adda1e65312fc7262258ee92371257a5dd2df267 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Thu, 28 Sep 2023 10:16:41 +0200 Subject: [PATCH 2648/4498] dts: arm: nxp: Move includes to proper place The header file defines macros that are not used in the boards dts but on the SoC level. They should be include where they are used. Signed-off-by: Franciszek Zdobylak --- boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts | 1 - boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts | 1 - dts/arm/nxp/nxp_s32z27x_r52.dtsi | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts index ebaf1658f3b..a8650758089 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.dts @@ -5,7 +5,6 @@ */ /dts-v1/; -#include #include #include "s32z270dc2_r52.dtsi" diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts index 06cf6b25844..1f74fe4a3a9 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.dts @@ -5,7 +5,6 @@ */ /dts-v1/; -#include #include #include "s32z270dc2_r52.dtsi" diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 56677ed2865..e26ae436860 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { From baad781195ac1777bd5a9d9b61c7beaf4913aa2b Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Thu, 28 Sep 2023 10:18:25 +0200 Subject: [PATCH 2649/4498] dts: arm64: nxp: Remove undefined chosen labels The labels used in chosen node are not defined in dtsi file. They are defined on board level and also chosen is already set there to proper values. Signed-off-by: Franciszek Zdobylak --- dts/arm64/nxp/nxp_mimx8mm_a53.dtsi | 1 - dts/arm64/nxp/nxp_mimx8mn_a53.dtsi | 1 - dts/arm64/nxp/nxp_mimx93_a55.dtsi | 6 ------ 3 files changed, 8 deletions(-) diff --git a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi index 605729969db..b7d80992d8e 100644 --- a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi @@ -17,7 +17,6 @@ chosen { zephyr,console = &uart2; zephyr,shell-uart = &uart2; - zephyr,sram = &sram0; }; cpus { diff --git a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi index d76cc40438e..8902380f46a 100644 --- a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi @@ -17,7 +17,6 @@ chosen { zephyr,console = &uart2; zephyr,shell-uart = &uart2; - zephyr,sram = &sram0; }; cpus { diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index 1e73bff224f..e064233e46f 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -14,12 +14,6 @@ #address-cells = <1>; #size-cells = <1>; - chosen { - zephyr,console = &uart2; - zephyr,shell-uart = &uart2; - zephyr,sram = &sram0; - }; - cpus { #address-cells = <1>; #size-cells = <0>; From 96c5052733be0eb73da2c47eb2c85e18ec54fca9 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 26 Oct 2023 10:57:30 +0200 Subject: [PATCH 2650/4498] tfm: Add BL2 log level configuration and disable it with TFM silent conf Add choice for BL2 log level configuration. Silence TF-M BL2 logging when TF-M is configured to be silent. Signed-off-by: Joakim Andersson --- modules/trusted-firmware-m/CMakeLists.txt | 19 +++++++++++++++++++ modules/trusted-firmware-m/Kconfig.tfm | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 0c01858f34d..f00116cda2c 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -101,6 +101,25 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=OFF) endif() + if (CONFIG_TFM_BL2) + if (CONFIG_TFM_BL2_LOG_LEVEL_DEBUG) + set(TFM_BL2_LOG_LEVEL "DEBUG") + elseif (CONFIG_TFM_BL2_LOG_LEVEL_INFO) + set(TFM_BL2_LOG_LEVEL "INFO") + elseif (CONFIG_TFM_BL2_LOG_LEVEL_WARNING) + set(TFM_BL2_LOG_LEVEL "WARNING") + elseif (CONFIG_TFM_BL2_LOG_LEVEL_ERROR) + set(TFM_BL2_LOG_LEVEL "ERROR") + elseif (CONFIG_TFM_BL2_LOG_LEVEL_OFF OR CONFIG_TFM_LOG_LEVEL_SILENCE) + set(TFM_BL2_LOG_LEVEL "OFF") + endif() + + if (DEFINED TFM_BL2_LOG_LEVEL) + # BL2 uses MCUBOOT_LOG_LEVEL configuration + list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_LOG_LEVEL=${TFM_BL2_LOG_LEVEL}) + endif() + endif() + if (CONFIG_TFM_PARTITION_LOG_LEVEL_DEBUG) set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_DEBUG") elseif (CONFIG_TFM_PARTITION_LOG_LEVEL_INFO) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 17f48e9fb03..2a5edb64343 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -397,6 +397,21 @@ config ROM_START_OFFSET needs to be updated if TF-M switches to use a different header size for BL2. +choice TFM_BL2_LOG_LEVEL + prompt "BL2 Log Level" if !TFM_LOG_LEVEL_SILENCE + default TFM_BL2_LOG_LEVEL_INFO + config TFM_BL2_LOG_LEVEL_DEBUG + bool "Debug" + config TFM_BL2_LOG_LEVEL_INFO + bool "Info" + config TFM_BL2_LOG_LEVEL_WARNING + bool "Warning" + config TFM_BL2_LOG_LEVEL_ERROR + bool "Error" + config TFM_BL2_LOG_LEVEL_OFF + bool "Off" +endchoice + endif # !TFM_BL2 # Option to instruct flashing a merged binary consisting of BL2 (optionally), From b3de6432069dafa680c0c712bf53d51809ee961b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 10:15:55 +0200 Subject: [PATCH 2651/4498] tests cmsis_dsp filtering: Do not run filtering.misc.fpu on mps3_an547 Merging 565c9376f1a6da4d67cae08126fcb342c0c27658 exposed an issue in this test, which causes an assert in the mps3_an547. For more information check https://github.com/zephyrproject-rtos/zephyr/issues/64387 The issue needs further analysis. With this platform being an integration platform for this test, it gets triggered in CI by unrelated PRs, causing CI failures and blocking development. As an interim measure, to unblock development in the main branch, let's exclude this platform from this test. This commit should be reverted once the underlaying issue is indentified and addressed. Signed-off-by: Alberto Escolar Piedras --- tests/lib/cmsis_dsp/filtering/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/cmsis_dsp/filtering/testcase.yaml b/tests/lib/cmsis_dsp/filtering/testcase.yaml index 15b42c278ee..115367cdfc4 100644 --- a/tests/lib/cmsis_dsp/filtering/testcase.yaml +++ b/tests/lib/cmsis_dsp/filtering/testcase.yaml @@ -113,6 +113,7 @@ tests: and CONFIG_FULL_LIBC_SUPPORTED) or CONFIG_ARCH_POSIX integration_platforms: - mps2_an521_remote + platform_exclude: - mps3_an547 tags: - cmsis_dsp From 08bd1c5ec26ce2fd1640d60dd2ca070b75de1f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 26 Oct 2023 09:17:46 +0200 Subject: [PATCH 2652/4498] usb: device: Fix ZLP write race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ZLP packet has to be read and acknowledged by host just like any other DATA packet. Do not end transfer until the host actually acknowledged the trailing ZLP. This fixes the race condition between host and Zephyr application where the next transfer could be lost if host did not issue IN token (that would read read ZLP) before the application tried to start new transfer. Signed-off-by: Tomasz Moń --- subsys/usb/device/usb_transfer.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/subsys/usb/device/usb_transfer.c b/subsys/usb/device/usb_transfer.c index 7a75d87fd0c..95cf3198ab6 100644 --- a/subsys/usb/device/usb_transfer.c +++ b/subsys/usb/device/usb_transfer.c @@ -86,12 +86,17 @@ static void usb_transfer_work(struct k_work *item) if (trans->flags & USB_TRANS_WRITE) { if (!trans->bsize) { - if (!(trans->flags & USB_TRANS_NO_ZLP)) { - LOG_DBG("Transfer ZLP"); - usb_write(ep, NULL, 0, NULL); + if (trans->flags & USB_TRANS_NO_ZLP) { + trans->status = 0; + goto done; } - trans->status = 0; - goto done; + + /* Host have to read the ZLP just like any other DATA + * packet. Set USB_TRANS_NO_ZLP flag so the transfer + * will end next time we get ACK from host. + */ + LOG_DBG("Transfer ZLP"); + trans->flags |= USB_TRANS_NO_ZLP; } ret = usb_write(ep, trans->buffer, trans->bsize, &bytes); From 530a3092feef04bc9038f00ac088125b8514aba3 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Wed, 25 Oct 2023 11:39:10 +0200 Subject: [PATCH 2653/4498] debug: coredump: flash backend: print error if write fails The loop in `coredump_flash_backend_buffer_output` might fail without any alerts. This could be due to e.g. a too small coredump-partion. Add a LOG_ERR if an error occurs. Signed-off-by: Jeppe Odgaard --- subsys/debug/coredump/coredump_backend_flash_partition.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/debug/coredump/coredump_backend_flash_partition.c b/subsys/debug/coredump/coredump_backend_flash_partition.c index d7ce6a02cc2..434cd4774a1 100644 --- a/subsys/debug/coredump/coredump_backend_flash_partition.c +++ b/subsys/debug/coredump/coredump_backend_flash_partition.c @@ -527,6 +527,7 @@ static void coredump_flash_backend_buffer_output(uint8_t *buf, size_t buflen) &backend_ctx.stream_ctx, tmp_buf, copy_sz, false); if (backend_ctx.error != 0) { + LOG_ERR("Flash write error: %d", backend_ctx.error); break; } From 8283f8ca09fd057d4916ede78c9dbae327a94884 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:24:01 -0700 Subject: [PATCH 2654/4498] test/c_lib: Skip 'exit' test for EXTERNAL_LIBC The native C library exit function does not do what we want. Signed-off-by: Keith Packard --- tests/lib/c_lib/src/main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index 6b3e96cbf99..13ab6c1da7b 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -46,9 +46,6 @@ #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) #define LIST_LEN 2 -static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); -static struct k_thread tdata; - /* Recent GCC's are issuing a warning for the truncated strncpy() * below (the static source string is longer than the locally-defined * destination array). That's exactly the case we're testing, so turn @@ -1221,13 +1218,22 @@ ZTEST(test_c_lib, test_abort) * @brief test exit functions * */ +#ifndef CONFIG_EXTERNAL_LIBC static void exit_program(void *p1, void *p2, void *p3) { exit(1); } +static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); +static struct k_thread tdata; + +#endif + ZTEST(test_c_lib, test_exit) { +#ifdef CONFIG_EXTERNAL_LIBC + ztest_test_skip(); +#else int a = 0; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, exit_program, @@ -1235,4 +1241,5 @@ ZTEST(test_c_lib, test_exit) k_sleep(K_MSEC(10)); k_thread_abort(tid); zassert_equal(a, 0, "exit failed"); +#endif } From dfd584204c45192fb3b1414347f97a0c6c6f74e0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:25:50 -0700 Subject: [PATCH 2655/4498] test/c_lib: Skip 'abort' test for EXTERNAL_LIBC The native C library abort function isn't trapped within Zephyr. Signed-off-by: Keith Packard --- tests/lib/c_lib/src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index 13ab6c1da7b..0ba85ead4d2 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -1206,11 +1206,15 @@ ZTEST(test_c_lib, test_rand_reproducibility) */ ZTEST(test_c_lib, test_abort) { +#ifdef CONFIG_EXTERNAL_LIBC + ztest_test_skip(); +#else int a = 0; ztest_set_fault_valid(true); abort(); zassert_equal(a, 0, "abort failed"); +#endif } /** From e4681a0634f882a33a1ec59675a4df92e2578486 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:26:27 -0700 Subject: [PATCH 2656/4498] test/c_lib: Don't fail to compile tests with 32-bit time_t The native library may use a 32-bit time_t, so we need to avoid having the compiler generate an error during compilation. Signed-off-by: Keith Packard --- tests/lib/c_lib/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index 0ba85ead4d2..1d04159d265 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -1067,7 +1067,7 @@ ZTEST(test_c_lib, test_time) { time_t tests1 = 0; time_t tests2 = -5; - time_t tests3 = -214748364800; + time_t tests3 = (time_t) -214748364800; time_t tests4 = 951868800; struct tm tp; From 83db6ee7f582ea64036a9460e02257bb31f76812 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:28:24 -0700 Subject: [PATCH 2657/4498] test/c_lib: Skip strerror invalid input test for EXTERNAL_LIBC Passing an invalid errno value to strerror is undefined behavior in POSIX. While all Zephyr-specific C libraries may be required to return a specific value, we can't hold an external C library to that standard. Signed-off-by: Keith Packard --- tests/lib/c_lib/src/test_strerror.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lib/c_lib/src/test_strerror.c b/tests/lib/c_lib/src/test_strerror.c index 25a31df0624..9b7dde334d8 100644 --- a/tests/lib/c_lib/src/test_strerror.c +++ b/tests/lib/c_lib/src/test_strerror.c @@ -32,6 +32,7 @@ ZTEST(test_c_lib, test_strerror) /* do not change errno on success */ zassert_equal(4242, errno, ""); +#ifndef CONFIG_EXTERNAL_LIBC /* consistent behaviour w.r.t. errno with invalid input */ errno = 0; expected = ""; @@ -43,6 +44,7 @@ ZTEST(test_c_lib, test_strerror) expected, actual); /* do not change errno on failure (for consistence) */ zassert_equal(0, errno, ""); +#endif /* consistent behaviour for "Success" */ if (!IS_ENABLED(CONFIG_MINIMAL_LIBC_DISABLE_STRING_ERROR_TABLE)) { From 8780bd2b70e4aab540b57e7aa3819644135a0b42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:32:53 -0700 Subject: [PATCH 2658/4498] test/c_lib: Make sure time_t is at least 64-bits Check to ensure that the C library doesn't have obvious 2038 issues. Signed-off-by: Keith Packard --- tests/lib/c_lib/src/main.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index 1d04159d265..2347dfebce1 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -157,6 +157,20 @@ ZTEST(test_c_lib, test_stdint) #endif } +/** + * + * @brief Test time_t to make sure it is at least 64 bits + * + */ +ZTEST(test_c_lib, test_time_t) +{ +#ifdef CONFIG_EXTERNAL_LIBC + ztest_test_skip(); +#else + zassert_true(sizeof(time_t) >= sizeof(uint64_t)); +#endif +} + /* * variables used during string library testing */ From 51fee431223379d32bb9ff8374e91bc4159b4088 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2023 17:34:14 -0700 Subject: [PATCH 2659/4498] tests/c_lib: Run tests on native/posix targets With a few minor adjustments, these tests now run fine on native targets. Signed-off-by: Keith Packard --- tests/lib/c_lib/testcase.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib/c_lib/testcase.yaml b/tests/lib/c_lib/testcase.yaml index 7bc5833a96a..90313614d10 100644 --- a/tests/lib/c_lib/testcase.yaml +++ b/tests/lib/c_lib/testcase.yaml @@ -1,13 +1,11 @@ common: tags: - clib - filter: not CONFIG_NATIVE_APPLICATION integration_platforms: - mps2_an385 tests: libraries.libc: ignore_faults: true - filter: not (CONFIG_ARCH_POSIX and CONFIG_EXTERNAL_LIBC) libraries.libc.picolibc: filter: CONFIG_PICOLIBC_SUPPORTED tags: picolibc @@ -29,11 +27,13 @@ tests: - CONFIG_NEWLIB_LIBC=y - CONFIG_NEWLIB_LIBC_NANO=y libraries.libc.minimal.strerror_table: + filter: CONFIG_MINIMAL_LIBC_SUPPORTED tags: minimal_libc extra_configs: - CONFIG_MINIMAL_LIBC=y - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=y libraries.libc.minimal.no_strerror_table: + filter: CONFIG_MINIMAL_LIBC_SUPPORTED tags: minimal_libc extra_configs: - CONFIG_MINIMAL_LIBC=y From bad87f1684e7fe8be11a39290d688d9585549184 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 28 Sep 2023 18:57:02 +0000 Subject: [PATCH 2660/4498] ci: publish api docs and coverage as well Also API coverage reports to both PRs and main documentation site. Signed-off-by: Anas Nashif --- .github/workflows/doc-build.yml | 22 ++++++++++++++++++++-- .github/workflows/doc-publish-pr.yml | 4 ++++ .github/workflows/doc-publish.yml | 2 ++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index c1fed2dc333..f4cad6bfa0d 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -63,7 +63,7 @@ jobs: - name: install-pkgs run: | sudo apt-get update - sudo apt-get install -y ninja-build graphviz + sudo apt-get install -y ninja-build graphviz lcov wget --no-verbose "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz" tar xf doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz echo "${PWD}/doxygen-${DOXYGEN_VERSION}/bin" >> $GITHUB_PATH @@ -80,6 +80,7 @@ jobs: pip3 install -r doc/requirements.txt pip3 install west==${WEST_VERSION} pip3 install cmake==${CMAKE_VERSION} + pip3 install coverxygen - name: west setup run: | @@ -99,12 +100,19 @@ jobs: else DOC_TARGET="html" fi - DOC_TAG=${DOC_TAG} SPHINXOPTS_EXTRA="-q -t publish" make -C doc ${DOC_TARGET} + # API documentation coverage + python3 -m coverxygen --xml-dir doc/_build/html/doxygen/xml/ --src-dir include/ --output doc-coverage.info + # deprecated page causing issues + lcov --remove doc-coverage.info \*/deprecated > new.info + genhtml --no-function-coverage --no-branch-coverage new.info -o coverage-report + - name: compress-docs run: | tar cfJ html-output.tar.xz --directory=doc/_build html + tar cfJ api-output.tar.xz --directory=doc/_build html/doxygen/html + tar cfJ api-coverage.tar.xz coverage-report - name: upload-build uses: actions/upload-artifact@v3 @@ -112,15 +120,25 @@ jobs: name: html-output path: html-output.tar.xz + - name: upload-api-coverage + uses: actions/upload-artifact@v3 + with: + name: api-coverage + path: api-coverage.tar.xz + - name: process-pr if: github.event_name == 'pull_request' run: | REPO_NAME="${{ github.event.repository.name }}" PR_NUM="${{ github.event.pull_request.number }}" DOC_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/docs/" + API_DOC_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/docs/doxygen/html/" + API_COVERAGE_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/api-coverage/" echo "${PR_NUM}" > pr_num echo "Documentation will be available shortly at: ${DOC_URL}" >> $GITHUB_STEP_SUMMARY + echo "API Documentation will be available shortly at: ${API_DOC_URL}" >> $GITHUB_STEP_SUMMARY + echo "API Coverage Report will be available shortly at: ${API_COVERAGE_URL}" >> $GITHUB_STEP_SUMMARY - name: upload-pr-number uses: actions/upload-artifact@v3 diff --git a/.github/workflows/doc-publish-pr.yml b/.github/workflows/doc-publish-pr.yml index 6db566d4e1f..07ee0c10604 100644 --- a/.github/workflows/doc-publish-pr.yml +++ b/.github/workflows/doc-publish-pr.yml @@ -46,6 +46,7 @@ jobs: - name: Uncompress HTML docs run: | tar xf html-output/html-output.tar.xz -C html-output + tar xf api-coverage/api-coverage.tar.xz -C api-coverage - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v2 @@ -61,3 +62,6 @@ jobs: aws s3 sync --quiet html-output/html \ s3://builds.zephyrproject.org/${{ github.event.repository.name }}/pr/${PR_NUM}/docs \ --delete + aws s3 sync --quiet api-coverage/coverage-report/ \ + s3://builds.zephyrproject.org/${{ github.event.repository.name }}/pr/${PR_NUM}/api-coverage \ + --delete diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 5262d9db67e..c15313bb087 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -32,6 +32,7 @@ jobs: - name: Uncompress HTML docs run: | tar xf html-output/html-output.tar.xz -C html-output + tar xf api-coverage/api-coverage.tar.xz -C api-coverage - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v2 @@ -52,4 +53,5 @@ jobs: aws s3 sync --quiet html-output/html s3://docs.zephyrproject.org/${VERSION} --delete aws s3 sync --quiet html-output/html/doxygen/html s3://docs.zephyrproject.org/apidoc/${VERSION} --delete + aws s3 sync --quiet api-coverage/coverage-report/ s3://docs.zephyrproject.org/api-coverage/${VERSION} --delete aws s3 cp --quiet pdf-output/zephyr.pdf s3://docs.zephyrproject.org/${VERSION}/zephyr.pdf From 3fab7624eb4b31dd6caa33ad50adb18b51cc9a60 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 24 Oct 2023 11:44:56 +0200 Subject: [PATCH 2661/4498] doc: pipes: Fix the pipe read example. Replaces sizeof(header) which is equal to the size of the pointer, by sizeof (*header), which is equal to the size of struct message_header. Signed-off-by: Andrej Butok --- doc/kernel/services/data_passing/pipes.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/kernel/services/data_passing/pipes.rst b/doc/kernel/services/data_passing/pipes.rst index 62c4f8f0223..bdeec48f011 100644 --- a/doc/kernel/services/data_passing/pipes.rst +++ b/doc/kernel/services/data_passing/pipes.rst @@ -150,12 +150,12 @@ process data items generated by one or more producing threads. while (1) { rc = k_pipe_get(&my_pipe, buffer, sizeof(buffer), &bytes_read, - sizeof(header), K_MSEC(100)); + sizeof(*header), K_MSEC(100)); - if ((rc < 0) || (bytes_read < sizeof (header))) { + if ((rc < 0) || (bytes_read < sizeof (*header))) { /* Incomplete message header received */ ... - } else if (header->num_data_bytes + sizeof(header) > bytes_read) { + } else if (header->num_data_bytes + sizeof(*header) > bytes_read) { /* Only some data was received */ ... } else { From daa739a4105a9ec7cf8b1822346ec59385ed9b4e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 25 Oct 2023 12:51:08 +0300 Subject: [PATCH 2662/4498] tests: spinlock: Clear test globals before each test Clear test global variables before each test execution. Signed-off-by: Andrei Emeltchenko --- tests/kernel/spinlock/src/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/kernel/spinlock/src/main.c b/tests/kernel/spinlock/src/main.c index 49652537bab..ddd53eca4e2 100644 --- a/tests/kernel/spinlock/src/main.c +++ b/tests/kernel/spinlock/src/main.c @@ -233,6 +233,9 @@ static void before(void *ctx) ARG_UNUSED(ctx); bounce_done = 0; + bounce_owner = 0; + trylock_failures = 0; + trylock_successes = 0; } ZTEST_SUITE(spinlock, NULL, NULL, before, NULL, NULL); From 55918e74546d9d439da279d8107ce7bd733c9e27 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Thu, 26 Oct 2023 13:17:41 +0200 Subject: [PATCH 2663/4498] MAINTAINERS: add OpenThread collaborator Add `edmont` as collaborator for OpenThread related repos. Signed-off-by: Eduardo Montoya --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index cb0cdee48bd..e0e2156fdad 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2029,6 +2029,7 @@ Networking: - pdgendt - canisLupus1313 - mariuszpos + - edmont files: - subsys/net/l2/openthread/ - samples/net/openthread/ @@ -3456,6 +3457,7 @@ West: - pdgendt - canisLupus1313 - mariuszpos + - edmont files: - modules/openthread/ labels: From 85e3a4ca6ae1993be975317515ee431dca02aae1 Mon Sep 17 00:00:00 2001 From: Krishna T Date: Tue, 21 Mar 2023 21:25:45 +0530 Subject: [PATCH 2664/4498] scripts: ci: Fix for compliance with multi-user machine If in a server multiple users are running compliance then it throws errors as the filename "Kconfig.modules" and "Kconfig.dts" is owned by someone else. Fix this by creating a randomized Kconfig file and delete after use. Signed-off-by: Krishna T --- scripts/ci/check_compliance.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 22406b6734a..779da01f2c5 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -16,6 +16,7 @@ import tempfile import traceback import shlex +import shutil from yamllint import config, linter @@ -356,6 +357,8 @@ def parse_kconfig(self): if not os.path.exists(kconfig_path): self.error(kconfig_path + " not found") + kconfiglib_dir = tempfile.mkdtemp(prefix="kconfiglib_") + sys.path.insert(0, kconfig_path) # Import globally so that e.g. kconfiglib.Symbol can be referenced in # tests @@ -370,7 +373,7 @@ def parse_kconfig(self): os.environ["ARCH_DIR"] = "arch/" os.environ["BOARD_DIR"] = "boards/*/*" os.environ["ARCH"] = "*" - os.environ["KCONFIG_BINARY_DIR"] = tempfile.gettempdir() + os.environ["KCONFIG_BINARY_DIR"] = kconfiglib_dir os.environ['DEVICETREE_CONF'] = "dummy" os.environ['TOOLCHAIN_HAS_NEWLIB'] = "y" @@ -379,10 +382,9 @@ def parse_kconfig(self): os.environ["GENERATED_DTS_BOARD_CONF"] = "dummy" # For multi repo support - self.get_modules(os.path.join(tempfile.gettempdir(), "Kconfig.modules")) - + self.get_modules(os.path.join(kconfiglib_dir, "Kconfig.modules")) # For Kconfig.dts support - self.get_kconfig_dts(os.path.join(tempfile.gettempdir(), "Kconfig.dts")) + self.get_kconfig_dts(os.path.join(kconfiglib_dir, "Kconfig.dts")) # Tells Kconfiglib to generate warnings for all references to undefined # symbols within Kconfig files @@ -397,6 +399,9 @@ def parse_kconfig(self): except kconfiglib.KconfigError as e: self.failure(str(e)) raise EndTest + finally: + # Clean up the temporary directory + shutil.rmtree(kconfiglib_dir) def get_defined_syms(self, kconf): # Returns a set() with the names of all defined Kconfig symbols (with no From 9b200410d00602602cfc9623e455f13a1a2852b4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 17 Oct 2023 17:51:40 +0000 Subject: [PATCH 2665/4498] modules: mbedtls: Bump to 3.4.1 Bump mbedTLS to the 3.4.1 Signed-off-by: Flavio Ceolin --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 080ee476ef0..d8c23c80ffb 100644 --- a/west.yml +++ b/west.yml @@ -277,7 +277,7 @@ manifest: revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd path: modules/lib/gui/lvgl - name: mbedtls - revision: c38dc78d9a8dcbe43b898cc1171ab33ba3e6fc26 + revision: 7053083b0cff8462464e3cbb826e87852fc03da6 path: modules/crypto/mbedtls groups: - crypto From 4b88aa9dc178a7901dc4c09f922a5f915608e317 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 11 Oct 2023 12:12:13 +0200 Subject: [PATCH 2666/4498] manifest: Update nrf hw models to latest * Update the HW models module to 90f4484cbaec986ed253b4fe9649aa75e632de15 Including the following: * 90f4484 nrf_dppi & dppi_hack: Add support for NRF_DPPI_ENDPOINT_ Note: This update requires hal_nordic/nrfx release 3.2 Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d8c23c80ffb..639d10361a8 100644 --- a/west.yml +++ b/west.yml @@ -295,7 +295,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: f7842d717c73aaeb0354f9e70e6d5ad275106f52 + revision: 90f4484cbaec986ed253b4fe9649aa75e632de15 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 From 9dabc55c3e332b28ad01c7f7cf73782a95777621 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 17 Oct 2023 17:11:44 +0200 Subject: [PATCH 2667/4498] nrf5340bsim: Add support for NRF53_SYNC_RTC & ENABLE_CPUNET Add support for these two options in the simulated board. Before these options were otherwise defined in the real BOARD/SOC kconfig files, which meant samples/tests which used them would not be able to build due to a kconfig error. With this change they can both be selected, and the right functionality is built in. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/CMakeLists.txt | 5 +++++ boards/posix/nrf_bsim/Kconfig | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/boards/posix/nrf_bsim/CMakeLists.txt b/boards/posix/nrf_bsim/CMakeLists.txt index 66dec22ac57..dfa6248f7dc 100644 --- a/boards/posix/nrf_bsim/CMakeLists.txt +++ b/boards/posix/nrf_bsim/CMakeLists.txt @@ -26,6 +26,11 @@ zephyr_library_sources( common/trace_hook.c ) +# Include sync_rtc from real SOC code if enabled +zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC + ${ZEPHYR_BASE}/soc/arm/nordic_nrf/nrf53/sync_rtc.c + ) + target_sources(native_simulator INTERFACE common/bsim_args_runner.c common/bsim_extra_cpu_if_stubs.c diff --git a/boards/posix/nrf_bsim/Kconfig b/boards/posix/nrf_bsim/Kconfig index 20620317521..7d67c44d284 100644 --- a/boards/posix/nrf_bsim/Kconfig +++ b/boards/posix/nrf_bsim/Kconfig @@ -32,3 +32,19 @@ config SOC_SERIES_BSIM_NRF53X depends on SOC_SERIES_BSIM_NRFXX help Any NRF53 simulated SOC with BabbleSim, based on the POSIX arch + +if BOARD_NRF5340BSIM_NRF5340_CPUAPP + +# Replica of the option provided by the BOARD_NRF5340DK_NRF5340_CPUAPP board so samples can be +# reused as is +config BOARD_ENABLE_CPUNET + bool "NRF53 Network MCU" + +endif # BOARD_NRF5340BSIM_NRF5340_CPUNET + +if SOC_SERIES_BSIM_NRF53X + +# Let's reuse the RTC sync options so applications which use it can be reused as is +source "soc/arm/nordic_nrf/nrf53/Kconfig.sync_rtc" + +endif # SOC_SERIES_BSIM_NRF53X From 851e5cdbe2ea7be306b80552bf72d705ec60ccba Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 17 Oct 2023 17:16:52 +0200 Subject: [PATCH 2668/4498] samples: nrf53_sync_rtc: Add support in nrf5340bsim Add support for this sample in the simulated nrf5340 Signed-off-by: Alberto Escolar Piedras --- samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt | 13 +++++++++++++ .../boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt | 3 ++- samples/boards/nrf/nrf53_sync_rtc/net/src/main.c | 8 +++++++- samples/boards/nrf/nrf53_sync_rtc/src/main.c | 13 ++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt index da1ce866e87..3989c0b4981 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt @@ -9,6 +9,8 @@ set(NET_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/sync_rtc_net-prefix/src/sync_rtc_ if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") +elseif("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + set(BOARD_REMOTE "nrf5340bsim_nrf5340_cpunet") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() @@ -22,6 +24,15 @@ enable_language(C ASM) target_sources(app PRIVATE src/main.c) +set(EXTRA_CMAKE_ARGS "") + +if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + set(EXTRA_CMAKE_ARGS + "-DCONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME}\"") + message(NOTICE "\nFinal executable including both CPU's images will be:\n" + "${NET_ZEPHYR_DIR}/${KERNEL_EXE_NAME}\n") +endif() + include(ExternalProject) ExternalProject_Add( @@ -31,7 +42,9 @@ ExternalProject_Add( CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} CMAKE_CACHE_ARGS -DDTC_OVERLAY_FILE:STRING=${NET_DTC_OVERLAY_FILE} CMAKE_CACHE_ARGS -DEXTRA_CONF_FILE:STRING=${NET_OVERLAY_CONF} + CMAKE_ARGS "${EXTRA_CMAKE_ARGS}" BUILD_BYPRODUCTS "${NET_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" # NB: Do we need to pass on more CMake variables? BUILD_ALWAYS True + DEPENDS ${logical_target_for_zephyr_elf} ) diff --git a/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt index 7612c9a9cec..bb4cb17e00d 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt @@ -5,7 +5,8 @@ cmake_minimum_required(VERSION 3.20.0) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") +if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") OR + ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpunet")) message(INFO " ${BOARD} compile as slave in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") diff --git a/samples/boards/nrf/nrf53_sync_rtc/net/src/main.c b/samples/boards/nrf/nrf53_sync_rtc/net/src/main.c index 55bbcfd2e88..17cf5cb67ea 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/net/src/main.c +++ b/samples/boards/nrf/nrf53_sync_rtc/net/src/main.c @@ -13,6 +13,13 @@ #include LOG_MODULE_REGISTER(main); +#if (CONFIG_SOC_SERIES_BSIM_NRFXX) +extern uint32_t shared_cell_buffer; +static uint32_t shared_cell = (uintptr_t)&shared_cell_buffer; +#else +static uint32_t shared_cell = 0x20070000; +#endif + static void sync_callback(void) { int32_t offset = z_nrf_rtc_timer_nrf53net_offset_get(); @@ -20,7 +27,6 @@ static void sync_callback(void) __ASSERT(offset >= 0, "Synchronization should be completed"); uint32_t timestamp = sys_clock_tick_get_32() + offset; - uint32_t shared_cell = 0x20070000; uint32_t app_timestamp = *(volatile uint32_t *)shared_cell; LOG_INF("Local timestamp: %u, application core timestamp: %u", diff --git a/samples/boards/nrf/nrf53_sync_rtc/src/main.c b/samples/boards/nrf/nrf53_sync_rtc/src/main.c index 0498fe7b502..9c150fd1d46 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/src/main.c +++ b/samples/boards/nrf/nrf53_sync_rtc/src/main.c @@ -11,11 +11,22 @@ #include LOG_MODULE_REGISTER(main); +#if (CONFIG_SOC_SERIES_BSIM_NRFXX) +#include "nsi_cpu_if.h" + +/* For simulation, we can define shared memory variables linkable from + * other MCUs just by using NATIVE_SIMULATOR_IF + */ +NATIVE_SIMULATOR_IF uint32_t shared_cell_buffer; +static uint32_t shared_cell = (uintptr_t)&shared_cell_buffer; +#else +static uint32_t shared_cell = 0x20070000; +#endif + static void timeout_handler(struct k_timer *timer) { nrf_ipc_task_t task = offsetof(NRF_IPC_Type, TASKS_SEND[2]); uint32_t now = sys_clock_tick_get_32(); - uint32_t shared_cell = 0x20070000; *(volatile uint32_t *)shared_cell = now; nrf_ipc_task_trigger(NRF_IPC, task); From 4b90dec91fd3381c9e7d8b8f82ed1ea99206b74d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 19 Oct 2023 14:47:47 +0200 Subject: [PATCH 2669/4498] samples: nrf53_sync_rtc: Convert to sysbuild Convert this sample application build to sysbuild, and update documentation. Signed-off-by: Alberto Escolar Piedras --- .../boards/nrf/nrf53_sync_rtc/CMakeLists.txt | 39 +++---------------- .../nrf/nrf53_sync_rtc/Kconfig.sysbuild | 10 +++++ samples/boards/nrf/nrf53_sync_rtc/README.rst | 22 ++++++++++- .../nrf/nrf53_sync_rtc/net/CMakeLists.txt | 5 ++- .../boards/nrf5340bsim_nrf5340_cpunet.conf | 1 + .../boards/nrf/nrf53_sync_rtc/net/sample.yaml | 11 ------ samples/boards/nrf/nrf53_sync_rtc/sample.yaml | 5 ++- .../boards/nrf/nrf53_sync_rtc/sysbuild.cmake | 38 ++++++++++++++++++ 8 files changed, 82 insertions(+), 49 deletions(-) create mode 100644 samples/boards/nrf/nrf53_sync_rtc/Kconfig.sysbuild create mode 100644 samples/boards/nrf/nrf53_sync_rtc/net/boards/nrf5340bsim_nrf5340_cpunet.conf delete mode 100644 samples/boards/nrf/nrf53_sync_rtc/net/sample.yaml create mode 100644 samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake diff --git a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt index 3989c0b4981..432f5497009 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt @@ -5,46 +5,17 @@ cmake_minimum_required(VERSION 3.20.0) -set(NET_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/sync_rtc_net-prefix/src/sync_rtc_net-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -elseif("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340bsim_nrf5340_cpunet") +if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") OR + ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp")) + message(INFO " ${BOARD} used for Application Core") else() - message(FATAL_ERROR "${BOARD} is not supported for this sample") + message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -message(INFO " ${BOARD} compile as Master in this sample") - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(sync_rtc) enable_language(C ASM) target_sources(app PRIVATE src/main.c) - -set(EXTRA_CMAKE_ARGS "") - -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - set(EXTRA_CMAKE_ARGS - "-DCONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME}\"") - message(NOTICE "\nFinal executable including both CPU's images will be:\n" - "${NET_ZEPHYR_DIR}/${KERNEL_EXE_NAME}\n") -endif() - -include(ExternalProject) - -ExternalProject_Add( - sync_rtc_net - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/net - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - CMAKE_CACHE_ARGS -DDTC_OVERLAY_FILE:STRING=${NET_DTC_OVERLAY_FILE} - CMAKE_CACHE_ARGS -DEXTRA_CONF_FILE:STRING=${NET_OVERLAY_CONF} - CMAKE_ARGS "${EXTRA_CMAKE_ARGS}" - BUILD_BYPRODUCTS "${NET_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - # NB: Do we need to pass on more CMake variables? - BUILD_ALWAYS True - DEPENDS ${logical_target_for_zephyr_elf} -) diff --git a/samples/boards/nrf/nrf53_sync_rtc/Kconfig.sysbuild b/samples/boards/nrf/nrf53_sync_rtc/Kconfig.sysbuild new file mode 100644 index 00000000000..b6dc3d0a6d0 --- /dev/null +++ b/samples/boards/nrf/nrf53_sync_rtc/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/boards/nrf/nrf53_sync_rtc/README.rst b/samples/boards/nrf/nrf53_sync_rtc/README.rst index 36e04a0e2cb..476f37b8ea0 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/README.rst +++ b/samples/boards/nrf/nrf53_sync_rtc/README.rst @@ -29,7 +29,8 @@ Building the application for nrf5340dk_nrf5340_cpuapp :zephyr-app: samples/boards/nrf/nrf53_sync_rtc :board: nrf5340dk_nrf5340_cpuapp :goals: flash - :flash-args: --hex-file build/sync_rtc_net-prefix/src/sync_rtc_net-build/zephyr/zephyr.hex + :flash-args: --hex-file build/nrf53_sync_rtc/zephyr/zephyr.hex + :west-args: --sysbuild Open a serial terminals (for example Minicom or PuTTY) and connect the board with the following settings: @@ -74,3 +75,22 @@ When you reset the development kit, the following messages (one for master and o Observe that initially logging timestamps for the corresponding events on both cores do not match. Same with local and remote timestamps reported on network core. After RTC synchronization is completed they start to match. + +Building the application for the simulated nrf5340bsim +****************************************************** + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/nrf/nrf53_sync_rtc + :host-os: unix + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +Then you can execute your application using: + +.. code-block:: console + + $ ./build/zephyr/zephyr.exe -nosim + # Press Ctrl+C to exit + +You can expect a similar output as in the real HW in the invoking console. diff --git a/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt index bb4cb17e00d..feced555bc7 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/net/CMakeLists.txt @@ -5,14 +5,15 @@ cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") OR ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpunet")) - message(INFO " ${BOARD} compile as slave in this sample") + message(INFO " ${BOARD} used for Network Core") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(sync_rtc_net) target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/nrf/nrf53_sync_rtc/net/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/boards/nrf/nrf53_sync_rtc/net/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..e57e7e2174f --- /dev/null +++ b/samples/boards/nrf/nrf53_sync_rtc/net/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1 @@ +CONFIG_BUILD_OUTPUT_EXE=n diff --git a/samples/boards/nrf/nrf53_sync_rtc/net/sample.yaml b/samples/boards/nrf/nrf53_sync_rtc/net/sample.yaml deleted file mode 100644 index f6b337dac24..00000000000 --- a/samples/boards/nrf/nrf53_sync_rtc/net/sample.yaml +++ /dev/null @@ -1,11 +0,0 @@ -sample: - description: This app shows how RTCs are synchronized - on nrf53 cores. - name: nRF53 Synchronized RTC sample (net) -common: - harness: remote -tests: - sample.boards.nrf.nrf53_sync_rtc.net: - platform_allow: nrf5340dk_nrf5340_cpunet - integration_platforms: - - nrf5340dk_nrf5340_cpunet diff --git a/samples/boards/nrf/nrf53_sync_rtc/sample.yaml b/samples/boards/nrf/nrf53_sync_rtc/sample.yaml index 54c63eb56e1..8f12f88f81e 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/sample.yaml +++ b/samples/boards/nrf/nrf53_sync_rtc/sample.yaml @@ -4,8 +4,11 @@ sample: name: nRF53 Synchronized RTC sample common: harness: remote + sysbuild: true tests: sample.boards.nrf.nrf53_sync_rtc: - platform_allow: nrf5340dk_nrf5340_cpuapp + platform_allow: + - nrf5340dk_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpuapp integration_platforms: - nrf5340dk_nrf5340_cpuapp diff --git a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake new file mode 100644 index 00000000000..a5d1eb9874f --- /dev/null +++ b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +set(REMOTE_APP net) + +ExternalZephyrProject_Add( + APPLICATION ${REMOTE_APP} + SOURCE_DIR ${APP_DIR}/${REMOTE_APP} + BOARD ${SB_CONFIG_NET_CORE_BOARD} +) + +if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) + + # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From 13c0657bdc84a7d6e40a4eb724a0d265881b4bfa Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 24 Oct 2023 09:45:36 +0200 Subject: [PATCH 2670/4498] samples: nrf53_sync_rtc: Add run test for simulated target Add a runtest for the simulated target. Signed-off-by: Alberto Escolar Piedras --- samples/boards/nrf/nrf53_sync_rtc/sample.yaml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/sample.yaml b/samples/boards/nrf/nrf53_sync_rtc/sample.yaml index 8f12f88f81e..d1905e0cc47 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/sample.yaml +++ b/samples/boards/nrf/nrf53_sync_rtc/sample.yaml @@ -3,12 +3,23 @@ sample: on nrf53 cores. name: nRF53 Synchronized RTC sample common: - harness: remote sysbuild: true tests: - sample.boards.nrf.nrf53_sync_rtc: + sample.boards.nrf.nrf53_sync_rtc.real_hw: platform_allow: - nrf5340dk_nrf5340_cpuapp - - nrf5340bsim_nrf5340_cpuapp integration_platforms: - nrf5340dk_nrf5340_cpuapp + harness: remote + sample.boards.nrf.nrf53_sync_rtc.simu: + platform_allow: + - nrf5340bsim_nrf5340_cpuapp + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "main: Synchronization using mbox driver" + - "sync_rtc: Updated timestamp to synchronized RTC by .* ticks" + - "main: IPC send at .* ticks" + - "main: Local timestamp: .*, application core timestamp:" From 7f43b00e231efb5a74136f19327844940f3f5871 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 19 Oct 2023 15:19:20 +0200 Subject: [PATCH 2671/4498] nrf53_bsim doc: Add paragraph about using sysbuild And a link to an example sample and its sysbuild.cmake file Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/doc/nrf5340bsim.rst | 5 +++++ samples/boards/nrf/nrf53_sync_rtc/README.rst | 2 ++ 2 files changed, 7 insertions(+) diff --git a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst index 5364cd0a307..e2976beee70 100644 --- a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst +++ b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst @@ -96,6 +96,11 @@ built with either Zephyr's build system or another native simulator compatible b you can provide that image to the Zephyr build of the second image using :kconfig:option:`CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS`. +You can also use :ref:`System build (sysbuild) ` to build your dual MCU executable. +The best way to understand how, may be to look into how this is done in one of the examples +in the tree. For example, for :ref:`the nrf53_sync_rtc sample `, +:zephyr_file:`samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake`. + .. note:: diff --git a/samples/boards/nrf/nrf53_sync_rtc/README.rst b/samples/boards/nrf/nrf53_sync_rtc/README.rst index 476f37b8ea0..0b2fd2a22fa 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/README.rst +++ b/samples/boards/nrf/nrf53_sync_rtc/README.rst @@ -76,6 +76,8 @@ Observe that initially logging timestamps for the corresponding events on both c do not match. Same with local and remote timestamps reported on network core. After RTC synchronization is completed they start to match. +.. _nrf53_sync_rtc_sample_build_bsim: + Building the application for the simulated nrf5340bsim ****************************************************** From f7f800c95749754c718ce5f70df8d09998833b0b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 19 Oct 2023 15:04:02 +0200 Subject: [PATCH 2672/4498] doc: nrf53 bsim: OpenAMP is now supported Let's delete the note which says OpenAMP is not supported as it is now. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/doc/nrf5340bsim.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst index e2976beee70..36dbf1d2adc 100644 --- a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst +++ b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst @@ -107,10 +107,6 @@ in the tree. For example, for :ref:`the nrf53_sync_rtc sample Date: Wed, 25 Oct 2023 12:05:21 +0000 Subject: [PATCH 2673/4498] soc: microchip_mec: do not enable PM in soc PM should not be enabled by default at the soc level. This is an application decision and not a platform decision whether to enable or disable PM features. Enabling PM by default will result in descripencies and test scope and failures in tests that do not account for PM being enabled. Fixes #60359 Signed-off-by: Anas Nashif --- samples/drivers/ps2/prj.conf | 1 + soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/samples/drivers/ps2/prj.conf b/samples/drivers/ps2/prj.conf index 743787bd855..182a536650f 100644 --- a/samples/drivers/ps2/prj.conf +++ b/samples/drivers/ps2/prj.conf @@ -2,3 +2,4 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_PRINTK=y CONFIG_PS2=y CONFIG_PM_DEVICE=y +CONFIG_PM=y diff --git a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series index afee2b8a59b..d23de11262d 100644 --- a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series +++ b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series @@ -33,10 +33,4 @@ config PS2_XEC default y depends on PS2 -config PM - default y if SYS_CLOCK_EXISTS - -config PM_DEVICE - default n - endif # SOC_SERIES_MEC172X From 4963f049c5b674448b80928830abbb812d8b8e69 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 16:48:57 +0200 Subject: [PATCH 2674/4498] nrf53bsim: Add support for split 15.4 builds Add the required chosen DT properties to enable split 15.4 builds. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts | 1 + boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index 0800dfc0f45..2429134df67 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -47,6 +47,7 @@ chosen { zephyr,flash = &flash0; zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; }; soc { diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts index 903e16db685..3ae862566a2 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts @@ -28,6 +28,7 @@ chosen { zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; /delete-property/ zephyr,flash-controller; zephyr,flash = &flash1; From f871bf9a0228bf637ec71badbbe2a6a63f3f2631 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 16:49:53 +0200 Subject: [PATCH 2675/4498] samples 802154_rpmsg: Enablel on simulated nrf5340 Enable building this sample on the simulated nrf5340 net core. Note that this sample does nothing on its own, as it requires a companion application core sample to driver it. Signed-off-by: Alberto Escolar Piedras --- samples/boards/nrf/ieee802154/802154_rpmsg/sample.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/boards/nrf/ieee802154/802154_rpmsg/sample.yaml b/samples/boards/nrf/ieee802154/802154_rpmsg/sample.yaml index fe31e48ff84..d99dcceaa32 100644 --- a/samples/boards/nrf/ieee802154/802154_rpmsg/sample.yaml +++ b/samples/boards/nrf/ieee802154/802154_rpmsg/sample.yaml @@ -5,4 +5,6 @@ sample: tests: sample.boards.nrf.802154_rpmsg: build_only: true - platform_allow: nrf5340dk_nrf5340_cpunet + platform_allow: + - nrf5340dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet From eab2d89f537226f25873bb40c323622e11c360ab Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 24 Oct 2023 10:24:55 +0200 Subject: [PATCH 2676/4498] samples/drivers/mbox: Convert to sysbuild and add support for nrf5340bsim Convert this sample application build to sysbuild, and add support for the nrf5340bsim target. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/mbox/CMakeLists.txt | 28 +++----------- samples/drivers/mbox/Kconfig.sysbuild | 12 ++++++ samples/drivers/mbox/README.rst | 21 ++++++++++ samples/drivers/mbox/remote/CMakeLists.txt | 9 +++-- .../boards/nrf5340bsim_nrf5340_cpunet.conf | 2 + samples/drivers/mbox/remote/sample.yaml | 9 ----- samples/drivers/mbox/sample.yaml | 3 ++ samples/drivers/mbox/sysbuild.cmake | 38 +++++++++++++++++++ 8 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 samples/drivers/mbox/Kconfig.sysbuild create mode 100644 samples/drivers/mbox/remote/boards/nrf5340bsim_nrf5340_cpunet.conf delete mode 100644 samples/drivers/mbox/remote/sample.yaml create mode 100644 samples/drivers/mbox/sysbuild.cmake diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index d94fdffbfb1..e65d44f0048 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -6,35 +6,19 @@ cmake_minimum_required(VERSION 3.20.0) -set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/mbox_ipc_remote-prefix/src/mbox_ipc_remote-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -elseif("${BOARD}" STREQUAL "adp_xc7k_ae350") - set(BOARD_REMOTE "adp_xc7k_ae350") -elseif("${BOARD}" STREQUAL "mimxrt595_evk_cm33") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") +if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") OR + ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") OR + ("${BOARD}" STREQUAL "adp_xc7k_ae350") OR + ("${BOARD}" STREQUAL "mimxrt595_evk_cm33")) + message(STATUS "${BOARD} compile as Main in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -message(STATUS "${BOARD} compile as Main in this sample") - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(mbox_ipc) enable_language(C ASM) target_sources(app PRIVATE src/main.c) - -include(ExternalProject) - -ExternalProject_Add( - mbox_ipc_remote - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - BUILD_BYPRODUCTS "${REMOTE_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - # NB: Do we need to pass on more CMake variables? - BUILD_ALWAYS True -) diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild new file mode 100644 index 00000000000..46ffe3e12ae --- /dev/null +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -0,0 +1,12 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config REMOTE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + default "adp_xc7k_ae350" if $(BOARD) = "adp_xc7k_ae350" + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "mimxrt595_evk_cm33" diff --git a/samples/drivers/mbox/README.rst b/samples/drivers/mbox/README.rst index 35c421335f9..cee903710f7 100644 --- a/samples/drivers/mbox/README.rst +++ b/samples/drivers/mbox/README.rst @@ -21,6 +21,7 @@ Building the application for nrf5340dk_nrf5340_cpuapp :zephyr-app: samples/drivers/mbox/ :board: nrf5340dk_nrf5340_cpuapp :goals: debug + :west-args: --sysbuild Open a serial terminal (minicom, putty, etc.) and connect the board with the following settings: @@ -58,3 +59,23 @@ core: Pong (on channel 1) Ping (on channel 0) Pong (on channel 1) + + +Building the application for the simulated nrf5340bsim +****************************************************** + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox/ + :host-os: unix + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +Then you can execute your application using: + +.. code-block:: console + + $ ./build/zephyr/zephyr.exe -nosim + # Press Ctrl+C to exit + +You can expect a similar output as in the real HW in the invoking console. diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index a2efccf2227..3aee2d96482 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -6,15 +6,16 @@ cmake_minimum_required(VERSION 3.20.0) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") - message(STATUS "${BOARD} compile as remote in this sample") -elseif("${BOARD}" STREQUAL "adp_xc7k_ae350") +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") OR + ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpunet") OR + ("${BOARD}" STREQUAL "adp_xc7k_ae350")) message(STATUS "${BOARD} compile as remote in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(mbox_ipc_remote) target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/mbox/remote/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/drivers/mbox/remote/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..665e456f504 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1,2 @@ +CONFIG_MBOX_NRFX_IPC=y +CONFIG_BUILD_OUTPUT_EXE=n diff --git a/samples/drivers/mbox/remote/sample.yaml b/samples/drivers/mbox/remote/sample.yaml deleted file mode 100644 index 014ad53a126..00000000000 --- a/samples/drivers/mbox/remote/sample.yaml +++ /dev/null @@ -1,9 +0,0 @@ -sample: - name: MBOX IPC sample (remote) -tests: - sample.drivers.mbox_remote: - platform_allow: nrf5340dk_nrf5340_cpunet adp_xc7k_ae350 - integration_platforms: - - nrf5340dk_nrf5340_cpunet - tags: mbox - harness: remote diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index eb5e5ac1a5d..01f894832fc 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -1,9 +1,12 @@ sample: name: MBOX IPC sample tests: + common: + sysbuild: true sample.drivers.mbox: platform_allow: - nrf5340dk_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpuapp - adp_xc7k_ae350 - mimxrt595_evk_cm33 integration_platforms: diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake new file mode 100644 index 00000000000..1bd6a00ae9e --- /dev/null +++ b/samples/drivers/mbox/sysbuild.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +set(REMOTE_APP remote) + +ExternalZephyrProject_Add( + APPLICATION ${REMOTE_APP} + SOURCE_DIR ${APP_DIR}/${REMOTE_APP} + BOARD ${SB_CONFIG_REMOTE_BOARD} +) + +if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) + + # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From 6196acf1d0ceb77091abcd70a81559c689a1285e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 24 Oct 2023 14:03:43 +0200 Subject: [PATCH 2677/4498] samples/drivers/mbox: Add run test for simulated target Add a runtest for the simulated target. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/mbox/sample.yaml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 01f894832fc..f7aa8953ea1 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -1,15 +1,26 @@ sample: name: MBOX IPC sample +common: + sysbuild: true + tags: mbox tests: - common: - sysbuild: true - sample.drivers.mbox: + sample.drivers.mbox.real_hw: platform_allow: - nrf5340dk_nrf5340_cpuapp - - nrf5340bsim_nrf5340_cpuapp - adp_xc7k_ae350 - mimxrt595_evk_cm33 integration_platforms: - nrf5340dk_nrf5340_cpuapp - tags: mbox harness: remote + sample.drivers.mbox.simu: + platform_allow: + - nrf5340bsim_nrf5340_cpuapp + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Ping \\(on channel 0\\)" + - "Pong \\(on channel 0\\)" + - "Ping \\(on channel 1\\)" + - "Pong \\(on channel 1\\)" From f64d09040bdfc874317cbb73b32c2e3d34ea2235 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 26 Oct 2023 10:56:41 +0200 Subject: [PATCH 2678/4498] tests: net: socket: misc: Increase stack size Recently added tests require more stack on certain platforms (nrf52840dk_nrf52840 in this case), hence increase the ZTEST stack size. Signed-off-by: Robert Lubos --- tests/net/socket/misc/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/net/socket/misc/prj.conf b/tests/net/socket/misc/prj.conf index 16329ade1c4..8e7bd8459cd 100644 --- a/tests/net/socket/misc/prj.conf +++ b/tests/net/socket/misc/prj.conf @@ -28,6 +28,7 @@ CONFIG_NET_IF_MAX_IPV6_COUNT=3 CONFIG_NET_IF_MAX_IPV4_COUNT=3 CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_ZTEST=y # TCP handshake requires more packets From 9d3306b22f11fc54f0cdd744a99183b1e1b5c276 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 26 Oct 2023 12:51:06 +0200 Subject: [PATCH 2679/4498] tests: net: socket: misc: Fix optlen type The optlen parameter passed to getsockopt() should be of (socklen_t *) type. Using int produced build errors on 64 bit platforms. Signed-off-by: Robert Lubos --- tests/net/socket/misc/src/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/net/socket/misc/src/main.c b/tests/net/socket/misc/src/main.c index 23060219815..06a9d8e625d 100644 --- a/tests/net/socket/misc/src/main.c +++ b/tests/net/socket/misc/src/main.c @@ -623,7 +623,8 @@ void test_ipv4_mapped_to_ipv6_disabled(void) void test_ipv4_mapped_to_ipv6_enabled(void) { - int off = 0, optlen = sizeof(int); + socklen_t optlen = sizeof(int); + int off = 0; int ret; int sock_s4, sock_s6; struct sockaddr srv_addr4 = { 0 }; @@ -695,7 +696,8 @@ void test_ipv4_mapped_to_ipv6_enabled(void) void test_ipv4_mapped_to_ipv6_server(void) { - int off, optlen = sizeof(int); + socklen_t optlen = sizeof(int); + int off; int ret, len; int sock_c4, sock_c6, sock_s6, new_sock; struct sockaddr srv_addr6 = { 0 }; From 36720dbf9c63d19f77c467727188e7c646809697 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Thu, 26 Oct 2023 11:58:36 -0500 Subject: [PATCH 2680/4498] MAINTAINERS: Add entry for multi-function devices (MFD) Adds a new entry for multi-function device (mfd) drivers to ensure that incoming PRs to this area get labeled appropriately and have reviews requested. Signed-off-by: Maureen Helm --- MAINTAINERS.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index e0e2156fdad..caa7e7654ab 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1139,6 +1139,19 @@ Release Notes: labels: - "area: LED" +"Drivers: MFD": + status: odd fixes + collaborators: + - gmarull + - aasinclair + files: + - drivers/mfd/ + - include/zephyr/drivers/mfd/ + - dts/bindings/mfd/ + - tests/drivers/build_all/mfd/ + labels: + - "area: MFD" + "Drivers: Modem": status: maintained maintainers: From 1fac5ed2a60b5365953e74c6dbc1ba3640b728ad Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 26 Oct 2023 12:09:48 -0700 Subject: [PATCH 2681/4498] soc: xtensa/nxp_adsp: put guard in Kconfig.defconfig This adds a if CONFIG_SOC_FAMILY_NXP_ADSP guard in Kconfig.defconfig for nxp_adsp. Or else all of its default get applied everywhere. For example, qemu_xtensa fails kernel.logging.message_capture tests because CONFIG_TEST_LOGGING_DEFAULTS is disabled in nxp_adsp/Kconfig.defconfig which should not have applied to qemu_xtensa at all. So put a guard in there. Signed-off-by: Daniel Leung --- soc/xtensa/nxp_adsp/Kconfig.defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/xtensa/nxp_adsp/Kconfig.defconfig b/soc/xtensa/nxp_adsp/Kconfig.defconfig index 0dc331f8834..cdee20c75f5 100644 --- a/soc/xtensa/nxp_adsp/Kconfig.defconfig +++ b/soc/xtensa/nxp_adsp/Kconfig.defconfig @@ -3,6 +3,8 @@ # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 +if SOC_FAMILY_NXP_ADSP + source "soc/xtensa/nxp_adsp/*/Kconfig.defconfig.series" config CACHE_MANAGEMENT @@ -27,3 +29,5 @@ config 2ND_LEVEL_INTERRUPTS config TEST_LOGGING_DEFAULTS default n depends on TEST + +endif From 7ca296c0164344d53c049c65ac90fa71b58fa608 Mon Sep 17 00:00:00 2001 From: Jan Henke Date: Sat, 12 Aug 2023 15:32:01 +0200 Subject: [PATCH 2682/4498] auxdisplay: Add SerLCD auxdisplay driver SerLCD is an interface for several lcd character display sold by sparkfun. Signed-off-by: Jan Henke --- drivers/auxdisplay/CMakeLists.txt | 1 + drivers/auxdisplay/Kconfig | 1 + drivers/auxdisplay/Kconfig.serlcd | 10 + drivers/auxdisplay/auxdisplay_serlcd.c | 436 +++++++++++++++++++ dts/bindings/auxdisplay/sparkfun,serlcd.yaml | 34 ++ 5 files changed, 482 insertions(+) create mode 100644 drivers/auxdisplay/Kconfig.serlcd create mode 100644 drivers/auxdisplay/auxdisplay_serlcd.c create mode 100644 dts/bindings/auxdisplay/sparkfun,serlcd.yaml diff --git a/drivers/auxdisplay/CMakeLists.txt b/drivers/auxdisplay/CMakeLists.txt index 91a86610526..ce53a06713b 100644 --- a/drivers/auxdisplay/CMakeLists.txt +++ b/drivers/auxdisplay/CMakeLists.txt @@ -8,3 +8,4 @@ zephyr_library_sources_ifdef(CONFIG_AUXDISPLAY_HD44780 auxdisplay_hd44780.c) zephyr_library_sources_ifdef(CONFIG_AUXDISPLAY_ITRON auxdisplay_itron.c) zephyr_library_sources_ifdef(CONFIG_AUXDISPLAY_JHD1313 auxdisplay_jhd1313.c) zephyr_library_sources_ifdef(CONFIG_AUXDISPLAY_PT6314 auxdisplay_pt6314.c) +zephyr_library_sources_ifdef(CONFIG_AUXDISPLAY_SERLCD auxdisplay_serlcd.c) diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index f28b463a633..908ceab1796 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -24,5 +24,6 @@ source "drivers/auxdisplay/Kconfig.hd44780" source "drivers/auxdisplay/Kconfig.itron" source "drivers/auxdisplay/Kconfig.jhd1313" source "drivers/auxdisplay/Kconfig.pt6314" +source "drivers/auxdisplay/Kconfig.serlcd" endif # AUXDISPLAY diff --git a/drivers/auxdisplay/Kconfig.serlcd b/drivers/auxdisplay/Kconfig.serlcd new file mode 100644 index 00000000000..d90acfe78d4 --- /dev/null +++ b/drivers/auxdisplay/Kconfig.serlcd @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Jan Henke +# SPDX-License-Identifier: Apache-2.0 + +config AUXDISPLAY_SERLCD + bool "SparkFun SerLCD dot character LCD driver" + default y + select I2C + depends on DT_HAS_SPARKFUN_SERLCD_ENABLED + help + Enable driver for SparkFun SerLCD. diff --git a/drivers/auxdisplay/auxdisplay_serlcd.c b/drivers/auxdisplay/auxdisplay_serlcd.c new file mode 100644 index 00000000000..f3c0e764869 --- /dev/null +++ b/drivers/auxdisplay/auxdisplay_serlcd.c @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2023 Jan Henke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sparkfun_serlcd + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(auxdisplay_serlcd, CONFIG_AUXDISPLAY_LOG_LEVEL); + +/* + * | in ASCII, used to begin a display command + */ +#define SERLCD_BEGIN_COMMAND 0x7C + +/* + * special command for the underlying display controller + */ +#define SERLCD_BEGIN_SPECIAL_COMMAND 0xFE + +/* + * delay in milliseconds after a normal command was sent + */ +#define SERLCD_COMMAND_DELAY_MS 10 + +/* + * delay in milliseconds after a special command was sent + */ +#define SERLCD_SPECIAL_COMMAND_DELAY_MS 50 + +/* + * maximum amount of custom chars the display supports + */ +#define SERLCD_CUSTOM_CHAR_MAX_COUNT 8 + +/* + * height of a custom char in bits + */ +#define SERLCD_CUSTOM_CHAR_HEIGHT 8 + +/* + * width of a custom char in bits + */ +#define SERLCD_CUSTOM_CHAR_WIDTH 5 + +/* + * char code for the first custom char + */ +#define SERLCD_CUSTOM_CHAR_INDEX_BASE 0x08 + +/* + * bitmask for custom character detection + */ +#define SERLCD_CUSTOM_CHAR_BITMASK 0xf8 + +/* + * bit to set in the display control special command to indicate the display should be powered on + */ +#define SERLCD_DISPLAY_CONTROL_POWER_BIT BIT(2) + +/* + * bit to set in the display control special command to indicate the cursor should be displayed + */ +#define SERLCD_DISPLAY_CONTROL_CURSOR_BIT BIT(1) + +/* + * bit to set in the display control special command to indicate the cursor should be blinking + */ +#define SERLCD_DISPLAY_CONTROL_BLINKING_BIT BIT(0) + +struct auxdisplay_serlcd_data { + bool power; + bool cursor; + bool blinking; + uint16_t cursor_x; + uint16_t cursor_y; +}; + +struct auxdisplay_serlcd_config { + struct auxdisplay_capabilities capabilities; + struct i2c_dt_spec bus; +}; + +enum auxdisplay_serlcd_command { + SERLCD_COMMAND_SET_CUSTOM_CHAR = 0x1B, + SERLCD_COMMAND_WRITE_CUSTOM_CHAR = 0x23, + SERLCD_COMMAND_CLEAR = 0x2D, +}; + +enum auxdisplay_serlcd_special_command { + SERLCD_SPECIAL_RETURN_HOME = 0x02, + SERLCD_SPECIAL_DISPLAY_CONTROL = 0x08, + SERLCD_SPECIAL_SET_DD_RAM_ADDRESS = 0x80, +}; + +static int auxdisplay_serlcd_send_command(const struct device *dev, + const enum auxdisplay_serlcd_command command) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + const uint8_t buffer[2] = {SERLCD_BEGIN_COMMAND, command}; + + int rc = i2c_write_dt(&config->bus, buffer, sizeof(buffer)); + + k_sleep(K_MSEC(SERLCD_COMMAND_DELAY_MS)); + return rc; +} + +static int +auxdisplay_serlcd_send_special_command(const struct device *dev, + const enum auxdisplay_serlcd_special_command command) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + const uint8_t buffer[2] = {SERLCD_BEGIN_SPECIAL_COMMAND, command}; + + int rc = i2c_write_dt(&config->bus, buffer, sizeof(buffer)); + + k_sleep(K_MSEC(SERLCD_SPECIAL_COMMAND_DELAY_MS)); + return rc; +} + +static int auxdisplay_serlcd_send_display_state(const struct device *dev, + const struct auxdisplay_serlcd_data *data) +{ + uint8_t command = SERLCD_SPECIAL_DISPLAY_CONTROL; + + if (data->power) { + command |= SERLCD_DISPLAY_CONTROL_POWER_BIT; + } + if (data->cursor) { + command |= SERLCD_DISPLAY_CONTROL_CURSOR_BIT; + } + if (data->blinking) { + command |= SERLCD_DISPLAY_CONTROL_BLINKING_BIT; + } + + return auxdisplay_serlcd_send_special_command(dev, command); +} + +static int auxdisplay_serlcd_display_on(const struct device *dev) +{ + struct auxdisplay_serlcd_data *data = dev->data; + + data->power = true; + + return auxdisplay_serlcd_send_display_state(dev, data); +} + +static int auxdisplay_serlcd_display_off(const struct device *dev) +{ + struct auxdisplay_serlcd_data *data = dev->data; + + data->power = false; + + return auxdisplay_serlcd_send_display_state(dev, data); +} + +static int auxdisplay_serlcd_cursor_set_enabled(const struct device *dev, bool enable) +{ + struct auxdisplay_serlcd_data *data = dev->data; + + data->cursor = enable; + + return auxdisplay_serlcd_send_display_state(dev, data); +} + +static int auxdisplay_serlcd_position_blinking_set_enabled(const struct device *dev, bool enable) +{ + struct auxdisplay_serlcd_data *data = dev->data; + + data->blinking = enable; + + return auxdisplay_serlcd_send_display_state(dev, data); +} + +static int auxdisplay_serlcd_cursor_position_set(const struct device *dev, + enum auxdisplay_position type, int16_t x, + int16_t y) +{ + static const uint8_t row_offsets[] = {0x00, 0x40, 0x14, 0x54}; + + const struct auxdisplay_serlcd_config *config = dev->config; + const struct auxdisplay_capabilities capabilities = config->capabilities; + const uint16_t columns = capabilities.columns; + const uint16_t rows = capabilities.rows; + struct auxdisplay_serlcd_data *data = dev->data; + + if (type == AUXDISPLAY_POSITION_ABSOLUTE) { + /* + * shortcut for (0,0) position + */ + if (x == 0 && y == 0) { + data->cursor_x = x; + data->cursor_y = y; + return auxdisplay_serlcd_send_special_command(dev, + SERLCD_SPECIAL_RETURN_HOME); + } + + /* + * bounds checking + */ + if (x < 0 || x >= columns) { + return -EINVAL; + } + if (y < 0 || y >= rows) { + return -EINVAL; + } + + data->cursor_x = x; + data->cursor_y = y; + + const uint8_t cursor_address = x + row_offsets[y]; + + return auxdisplay_serlcd_send_special_command( + dev, SERLCD_SPECIAL_SET_DD_RAM_ADDRESS | cursor_address); + + } else if (type == AUXDISPLAY_POSITION_RELATIVE) { + /* + * clip relative move to display dimensions + */ + const int new_x = (data->cursor_x + x) % columns; + const int new_y = (data->cursor_y + y + x / columns) % rows; + const uint16_t column = new_x < 0 ? new_x + columns : new_x; + const uint16_t row = new_y < 0 ? new_y + rows : new_y; + + data->cursor_x = column; + data->cursor_y = row; + + const uint8_t cursor_address = column + row_offsets[row]; + + return auxdisplay_serlcd_send_special_command( + dev, SERLCD_SPECIAL_SET_DD_RAM_ADDRESS | cursor_address); + } + + /* + * other types of movement are not implemented/supported + */ + return -ENOSYS; +} + +static int auxdisplay_serlcd_cursor_position_get(const struct device *dev, int16_t *x, int16_t *y) +{ + const struct auxdisplay_serlcd_data *data = dev->data; + + *x = (int16_t)data->cursor_x; + *y = (int16_t)data->cursor_y; + + return 0; +} + +static int auxdisplay_serlcd_capabilities_get(const struct device *dev, + struct auxdisplay_capabilities *capabilities) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + + memcpy(capabilities, &config->capabilities, sizeof(struct auxdisplay_capabilities)); + + return 0; +} + +static int auxdisplay_serlcd_clear(const struct device *dev) +{ + int rc = auxdisplay_serlcd_send_command(dev, SERLCD_COMMAND_CLEAR); + + k_sleep(K_MSEC(SERLCD_COMMAND_DELAY_MS)); + return rc; +} + +static int auxdisplay_serlcd_custom_character_set(const struct device *dev, + struct auxdisplay_character *character) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + int rc; + + /* + * only indexes 0..7 are supported + */ + const uint8_t char_index = character->index; + + if (char_index > (SERLCD_CUSTOM_CHAR_MAX_COUNT - 1)) { + return -EINVAL; + } + + /* + * custom characters are accessible via char codes 0x08..0x0f + */ + character->character_code = SERLCD_CUSTOM_CHAR_INDEX_BASE | char_index; + + rc = auxdisplay_serlcd_send_command(dev, SERLCD_COMMAND_SET_CUSTOM_CHAR + char_index); + if (!rc) { + return rc; + } + + /* + * the display expects the custom character as 8 lines of 5 bit each, shades are not + * supported + */ + for (int l = 0; l < SERLCD_CUSTOM_CHAR_HEIGHT; ++l) { + uint8_t buffer = 0; + + for (int i = 0; i < SERLCD_CUSTOM_CHAR_WIDTH; ++i) { + if (character->data[(l * 5) + i]) { + buffer |= BIT(4 - i); + } + } + rc = i2c_write_dt(&config->bus, &buffer, sizeof(buffer)); + if (!rc) { + return rc; + } + } + + return rc; +} + +static void auxdisplay_serlcd_advance_current_position(const struct device *dev) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + struct auxdisplay_serlcd_data *data = dev->data; + + ++(data->cursor_x); + if (data->cursor_x >= config->capabilities.columns) { + data->cursor_x = 0; + ++(data->cursor_y); + } + if (data->cursor_y >= config->capabilities.rows) { + data->cursor_y = 0; + } +} + +static int auxdisplay_serlcd_write(const struct device *dev, const uint8_t *text, uint16_t len) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + + int rc = 0; + + /* + * the display wraps around by itself, just write the text and update the position data + */ + for (int i = 0; i < len; ++i) { + uint8_t character = text[i]; + + /* + * customer characters require a special command, so check for custom char + */ + if ((character & SERLCD_CUSTOM_CHAR_BITMASK) == SERLCD_CUSTOM_CHAR_INDEX_BASE) { + const uint8_t command = SERLCD_COMMAND_WRITE_CUSTOM_CHAR + + (character & ~SERLCD_CUSTOM_CHAR_BITMASK); + + rc = auxdisplay_serlcd_send_command(dev, command); + if (!rc) { + return rc; + } + auxdisplay_serlcd_advance_current_position(dev); + } else if (character == SERLCD_BEGIN_COMMAND || + character == SERLCD_BEGIN_SPECIAL_COMMAND) { + /* + * skip these characters in text, as they have a special meaning, if + * required a custom character can be used as replacement + */ + continue; + } else { + rc = i2c_write_dt(&config->bus, text, len); + if (!rc) { + return rc; + } + auxdisplay_serlcd_advance_current_position(dev); + } + } + + return rc; +} + +static int auxdisplay_serlcd_init(const struct device *dev) +{ + const struct auxdisplay_serlcd_config *config = dev->config; + struct auxdisplay_serlcd_data *data = dev->data; + + /* + * Initialize our data structure + */ + data->power = true; + + if (!device_is_ready(config->bus.bus)) { + return -ENODEV; + } + + auxdisplay_serlcd_clear(dev); + + return 0; +} + +static const struct auxdisplay_driver_api auxdisplay_serlcd_auxdisplay_api = { + .display_on = auxdisplay_serlcd_display_on, + .display_off = auxdisplay_serlcd_display_off, + .cursor_set_enabled = auxdisplay_serlcd_cursor_set_enabled, + .position_blinking_set_enabled = auxdisplay_serlcd_position_blinking_set_enabled, + .cursor_position_set = auxdisplay_serlcd_cursor_position_set, + .cursor_position_get = auxdisplay_serlcd_cursor_position_get, + .capabilities_get = auxdisplay_serlcd_capabilities_get, + .clear = auxdisplay_serlcd_clear, + .custom_character_set = auxdisplay_serlcd_custom_character_set, + .write = auxdisplay_serlcd_write, +}; + +#define AUXDISPLAY_SERLCD_INST(inst) \ + static const struct auxdisplay_serlcd_config auxdisplay_serlcd_config_##inst = { \ + .capabilities = { \ + .columns = DT_INST_PROP(inst, columns), \ + .rows = DT_INST_PROP(inst, rows), \ + .mode = 0, \ + .brightness.minimum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \ + .brightness.maximum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \ + .backlight.minimum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \ + .backlight.maximum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \ + .custom_characters = SERLCD_CUSTOM_CHAR_MAX_COUNT, \ + .custom_character_width = SERLCD_CUSTOM_CHAR_WIDTH, \ + .custom_character_height = SERLCD_CUSTOM_CHAR_HEIGHT, \ + }, \ + .bus = I2C_DT_SPEC_INST_GET(inst)}; \ + \ + static struct auxdisplay_serlcd_data auxdisplay_serlcd_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, &auxdisplay_serlcd_init, NULL, &auxdisplay_serlcd_data_##inst, \ + &auxdisplay_serlcd_config_##inst, POST_KERNEL, \ + CONFIG_AUXDISPLAY_INIT_PRIORITY, &auxdisplay_serlcd_auxdisplay_api); + +DT_INST_FOREACH_STATUS_OKAY(AUXDISPLAY_SERLCD_INST) diff --git a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml new file mode 100644 index 00000000000..1a4d5734f36 --- /dev/null +++ b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2023 Jan Henke +# SPDX-License-Identifier: Apache-2.0 + +description: | + SparkFun SerLCD Dot Character VFD Controller/Driver IC + + Example: + &i2c1 { + serlcd@72 { + compatible = "sparkfun,serlcd"; + reg = <0x72>; + columns = <16>; + rows = <2>; + }; + }; + +compatible: "sparkfun,serlcd" + +include: [auxdisplay-device.yaml, i2c-device.yaml] + +properties: + columns: + type: int + default: 16 + enum: + - 16 + - 20 + + rows: + type: int + default: 2 + enum: + - 2 + - 4 From eb1968fa10b814f4d8447d6e02eabbbce4a70170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 25 Sep 2023 11:26:08 +0200 Subject: [PATCH 2683/4498] doc: extensions: Add ability to edit doc page on GitHub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the vcs_link extension to also support generating "edit" URL vcs_link_version is also now a Sphinx config making its value available to extensions. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/vcs_link.py | 15 ++++++++++++--- doc/_templates/breadcrumbs.html | 6 +++--- doc/conf.py | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/_extensions/zephyr/vcs_link.py b/doc/_extensions/zephyr/vcs_link.py index 23aedb5ef33..06cd5de073f 100644 --- a/doc/_extensions/zephyr/vcs_link.py +++ b/doc/_extensions/zephyr/vcs_link.py @@ -16,6 +16,7 @@ Configuration options ===================== +- ``vcs_link_version``: VCS version to use in the URL (e.g. "main") - ``vcs_link_base_url``: Base URL used as a prefix for generated URLs. - ``vcs_link_prefixes``: Mapping of pages (regex) <> VCS prefix. - ``vcs_link_exclude``: List of pages (regex) that will not report a URL. Useful @@ -33,11 +34,12 @@ __version__ = "0.1.0" -def vcs_link_get_url(app: Sphinx, pagename: str) -> Optional[str]: +def vcs_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[str]: """Obtain VCS URL for the given page. Args: app: Sphinx instance. + mode: Typically "edit", or "blob". pagename: Page name (path). Returns: @@ -60,6 +62,8 @@ def vcs_link_get_url(app: Sphinx, pagename: str) -> Optional[str]: return "/".join( [ app.config.vcs_link_base_url, + mode, + app.config.vcs_link_version, found_prefix, app.env.project.doc2path(pagename, basedir=False), ] @@ -70,12 +74,17 @@ def add_jinja_filter(app: Sphinx): if app.builder.name != "html": return - app.builder.templates.environment.filters["vcs_link_get_url"] = partial( - vcs_link_get_url, app + app.builder.templates.environment.filters["vcs_link_get_blob_url"] = partial( + vcs_link_get_url, app, mode="blob" + ) + + app.builder.templates.environment.filters["vcs_link_get_edit_url"] = partial( + vcs_link_get_url, app, mode="edit" ) def setup(app: Sphinx): + app.add_config_value("vcs_link_version", "", "") app.add_config_value("vcs_link_base_url", "", "") app.add_config_value("vcs_link_prefixes", {}, "") app.add_config_value("vcs_link_exclude", [], "") diff --git a/doc/_templates/breadcrumbs.html b/doc/_templates/breadcrumbs.html index c0052e0ce53..6e66ae50495 100644 --- a/doc/_templates/breadcrumbs.html +++ b/doc/_templates/breadcrumbs.html @@ -19,9 +19,9 @@
  • {%- if display_vcs_link %} - {% set vcs_url = pagename | vcs_link_get_url %} - {% if vcs_url %} - {{ _('Open on GitHub') }} + {% set vcs_blob_url = pagename | vcs_link_get_blob_url %} + {% if vcs_blob_url %} + {{ _('Open on GitHub') }} {% endif %} {% endif %}
  • diff --git a/doc/conf.py b/doc/conf.py index 9a3e337d36b..59285769e29 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -264,7 +264,7 @@ # -- Options for zephyr.vcs_link ------------------------------------------ vcs_link_version = f"v{version}" if is_release else "main" -vcs_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr/blob/{vcs_link_version}" +vcs_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr" vcs_link_prefixes = { "samples/.*": "", "boards/.*": "", From 32cd631a1b1eff1985bc0c2cfc9857b917cb8fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 25 Sep 2023 14:13:20 +0200 Subject: [PATCH 2684/4498] doc: extensions: Add method to get vcs link to report issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a vcs_link_get_open_issue_url Jinja filter to craft the URL allowing to report an issue for a given Sphinx page Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/vcs_link.py | 50 ++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/doc/_extensions/zephyr/vcs_link.py b/doc/_extensions/zephyr/vcs_link.py index 06cd5de073f..819296e4c12 100644 --- a/doc/_extensions/zephyr/vcs_link.py +++ b/doc/_extensions/zephyr/vcs_link.py @@ -8,10 +8,14 @@ Introduction ============ -This Sphinx extension can be used to obtain the VCS URL for a given Sphinx page. +This Sphinx extension can be used to obtain various VCS URLs for a given Sphinx page. This is useful, for example, when adding features like "Open on GitHub" on top -of pages. The extension installs a Jinja filter which can be used on the -template to obtain VCS page URLs. +of pages. +The extension installs the following Jinja filter: + +* ``vcs_link_get_blob_url``: Returns a URL to the source of a page in the VCS. +* ``vcs_link_get_edit_url``: Returns a URL to edit the given page in the VCS. +* ``vcs_link_get_open_issue_url``: Returns a URL to open a new issue regarding the given page. Configuration options ===================== @@ -26,7 +30,9 @@ from functools import partial import os import re +from textwrap import dedent from typing import Optional +from urllib.parse import quote from sphinx.application import Sphinx @@ -70,6 +76,40 @@ def vcs_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional ) +def vcs_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optional[str]: + """Link to open a new Github issue regarding "pagename" with title, body, and + labels already pre-filled with useful information. + + Args: + app: Sphinx instance. + pagename: Page name (path). + + Returns: + URL to open a new issue if applicable, None otherwise. + """ + + if not os.path.isfile(app.env.project.doc2path(pagename)): + return None + + title = quote(f"[doc] Issue with {pagename}") + labels = quote("area: Documentation") + body = quote( + dedent( + f"""\ + << Please describe the issue here >> + + **Environment** + + * Page: `{pagename}` + * Version: {app.config.vcs_link_version} + * SHA-1: {sha1} + """ + ) + ) + + return f"{app.config.vcs_link_base_url}/issues/new?title={title}&labels={labels}&body={body}" + + def add_jinja_filter(app: Sphinx): if app.builder.name != "html": return @@ -82,6 +122,10 @@ def add_jinja_filter(app: Sphinx): vcs_link_get_url, app, mode="edit" ) + app.builder.templates.environment.filters["vcs_link_get_open_issue_url"] = partial( + vcs_link_get_open_issue_url, app + ) + def setup(app: Sphinx): app.add_config_value("vcs_link_version", "", "") From 701f59ee1e68a26d11e69a5c861c2053793d96c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 17 Aug 2023 15:42:07 +0200 Subject: [PATCH 2685/4498] doc: Make it easier to report issues in the documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add extension to get git metadata (date, SHA-1, ...) regarding the latest update made to a page - Add date of last "actual" update to each manually authored doc page - Add admonition inviting to report issues - Add button in breadcrumb to report issue Fixes #60622. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/git_info.py | 103 +++++++++++++++++++++++++++++ doc/_extensions/zephyr/vcs_link.py | 5 +- doc/_templates/breadcrumbs.html | 6 ++ doc/_templates/footer.html | 30 +++++++++ doc/conf.py | 1 + 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 doc/_extensions/zephyr/git_info.py create mode 100644 doc/_templates/footer.html diff --git a/doc/_extensions/zephyr/git_info.py b/doc/_extensions/zephyr/git_info.py new file mode 100644 index 00000000000..b405cd119a4 --- /dev/null +++ b/doc/_extensions/zephyr/git_info.py @@ -0,0 +1,103 @@ +""" +Git Info Extension +################## + +Copyright (c) 2023 The Linux Foundation +SPDX-License-Identifier: Apache-2.0 + +Introduction +============ + +This extension adds a new Jinja filter, ``git_info``, that returns the date and SHA1 of the last +commit made to a page if this page is managed by Git. +""" + +import os +import re +import subprocess +from datetime import datetime +from functools import partial +from pathlib import Path +from typing import Optional +from typing import Tuple + +from sphinx.application import Sphinx +from sphinx.util.i18n import format_date + +__version__ = "0.1.0" + + +def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: + """Return a tuple with the date and SHA1 of the last commit made to a page. + + Arguments: + app {Sphinx} -- Sphinx application object + pagename {str} -- Page name + + Returns: + Optional[Tuple[str, str]] -- Tuple with the date and SHA1 of the last commit made to the + page, or None if the page is not in the repo. + """ + + if not os.path.isfile(app.env.project.doc2path(pagename)): + return None + + for exclude in app.config.vcs_link_exclude: + if re.match(exclude, pagename): + return None + + found_prefix = "" + for pattern, prefix in app.config.vcs_link_prefixes.items(): + if re.match(pattern, pagename): + found_prefix = prefix + break + + orig_path = os.path.join( + app.config.ZEPHYR_BASE, + found_prefix, + app.env.project.doc2path(pagename, basedir=False), + ) + + try: + date_and_sha1 = ( + subprocess.check_output( + [ + "git", + "log", + "-1", + "--format=%ad %H", + "--date=unix", + orig_path, + ], + stderr=subprocess.STDOUT, + ) + .decode("utf-8") + .strip() + ) + date, sha1 = date_and_sha1.split(" ", 1) + date_object = datetime.fromtimestamp(int(date)) + last_update_fmt = app.config.html_last_updated_fmt + if last_update_fmt is not None: + date = format_date(last_update_fmt, date=date_object, language=app.config.language) + + return (date, sha1) + except subprocess.CalledProcessError: + return None + + +def add_jinja_filter(app: Sphinx): + if app.builder.name != "html": + return + + app.builder.templates.environment.filters["git_info"] = partial(git_info_filter, app) + + +def setup(app: Sphinx): + app.add_config_value("ZEPHYR_BASE", Path(__file__).resolve().parents[3], "html") + app.connect("builder-inited", add_jinja_filter) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/doc/_extensions/zephyr/vcs_link.py b/doc/_extensions/zephyr/vcs_link.py index 819296e4c12..5cdc42bb812 100644 --- a/doc/_extensions/zephyr/vcs_link.py +++ b/doc/_extensions/zephyr/vcs_link.py @@ -91,12 +91,15 @@ def vcs_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Option if not os.path.isfile(app.env.project.doc2path(pagename)): return None - title = quote(f"[doc] Issue with {pagename}") + title = quote(f"[doc] Documentation issue in '{pagename}'") labels = quote("area: Documentation") body = quote( dedent( f"""\ + **Describe the bug** + << Please describe the issue here >> + << You may also want to update the automatically generated issue title above. >> **Environment** diff --git a/doc/_templates/breadcrumbs.html b/doc/_templates/breadcrumbs.html index 6e66ae50495..e3c10ab78d1 100644 --- a/doc/_templates/breadcrumbs.html +++ b/doc/_templates/breadcrumbs.html @@ -23,6 +23,12 @@ {% if vcs_blob_url %} {{ _('Open on GitHub') }} {% endif %} + {%- set git_last_updated, sha1 = pagename | git_info | default((None, None), true) %} + {%- if sha1 %} + + {{ _('Report an issue')}} + + {% endif %} {% endif %} {%- endblock %} diff --git a/doc/_templates/footer.html b/doc/_templates/footer.html new file mode 100644 index 00000000000..778fbc4b6bb --- /dev/null +++ b/doc/_templates/footer.html @@ -0,0 +1,30 @@ +{% extends "!footer.html" %} +{% block contentinfo %} +

    + {%- if show_copyright %} + © Copyright {{ copyright }}. + {%- endif %} + + {%- if last_updated %} + + Last generated on {{ last_updated }}. + + {%- endif -%} +

    +{%- set git_last_updated, sha1 = pagename | git_info | default((None, None), true) %} +{%- if git_last_updated %} +
    +

    + Help us keep our technical documentation accurate and up-to-date! +

    +

    + The human-authored contents on this page was last updated on {{ git_last_updated }}. +

    +

    + If you find any errors on this page, outdated information, or have any other suggestion for + improving its contents, please consider + opening an issue. +

    +
    +{%- endif %} +{% endblock %} diff --git a/doc/conf.py b/doc/conf.py index 59285769e29..82bd6304001 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -84,6 +84,7 @@ "zephyr.doxyrunner", "zephyr.vcs_link", "zephyr.manifest_projects_table", + "zephyr.git_info", "notfound.extension", "sphinx_copybutton", "sphinx_togglebutton", From 353f42d8bdb59086a05365ca3f8bed4eb1d82b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 25 Oct 2023 12:12:02 +0200 Subject: [PATCH 2686/4498] doc: refactor vcs_link and git_info extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor all git/github related extensions into one file, as they are working hand in hand. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 4 +- doc/_extensions/zephyr/gh_utils.py | 215 +++++++++++++++++++++++++++++ doc/_extensions/zephyr/git_info.py | 103 -------------- doc/_extensions/zephyr/vcs_link.py | 145 ------------------- doc/_templates/breadcrumbs.html | 10 +- doc/_templates/footer.html | 2 +- doc/conf.py | 15 +- 7 files changed, 230 insertions(+), 264 deletions(-) create mode 100644 doc/_extensions/zephyr/gh_utils.py delete mode 100644 doc/_extensions/zephyr/git_info.py delete mode 100644 doc/_extensions/zephyr/vcs_link.py diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 688f2c9efa3..19168df7a9e 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -59,7 +59,7 @@ from sphinx.transforms.post_transforms import SphinxPostTransform from sphinx.util import logging from sphinx.util.nodes import NodeMatcher, make_refnode -from zephyr.vcs_link import vcs_link_get_url +from zephyr.gh_utils import gh_link_get_url import json @@ -128,7 +128,7 @@ def convert_node(self, node): "name": node['name'], "description": node.children[0].astext(), "codeSampleType": "full", - "codeRepository": vcs_link_get_url(self.app, self.env.docname) + "codeRepository": gh_link_get_url(self.app, self.env.docname) })} """, format="html", diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py new file mode 100644 index 00000000000..4d2127756b4 --- /dev/null +++ b/doc/_extensions/zephyr/gh_utils.py @@ -0,0 +1,215 @@ +""" +Git/GitHub utilities for Sphinx +############################### + +Copyright (c) 2021 Nordic Semiconductor ASA +Copyright (c) 2023 The Linux Foundation + +SPDX-License-Identifier: Apache-2.0 + +Introduction +============ + +This Sphinx extension can be used to obtain various Git and GitHub related metadata for a page. +This is useful, for example, when adding features like "Open on GitHub" on top +of pages, direct links to open a GitHub issue regarding a page, or date of the most recent commit +to a page. + +The extension installs the following Jinja filter: + +* ``gh_link_get_blob_url``: Returns a URL to the source of a page on GitHub. +* ``gh_link_get_edit_url``: Returns a URL to edit the given page on GitHub. +* ``gh_link_get_open_issue_url``: Returns a URL to open a new issue regarding the given page. +* ``git_info``: Returns the date and SHA1 of the last commit made to a page (if this page is + managed by Git). + +Configuration options +===================== + +- ``gh_link_version``: GitHub version to use in the URL (e.g. "main") +- ``gh_link_base_url``: Base URL used as a prefix for generated URLs. +- ``gh_link_prefixes``: Mapping of pages (regex) <> GitHub prefix. +- ``gh_link_exclude``: List of pages (regex) that will not report a URL. Useful + for, e.g., auto-generated pages not in Git. +""" + +from functools import partial +import os +import re +import subprocess +from datetime import datetime +from pathlib import Path +from textwrap import dedent +from typing import Optional, Tuple +from urllib.parse import quote + +from sphinx.application import Sphinx +from sphinx.util.i18n import format_date + + +__version__ = "0.1.0" + + +def get_page_prefix(app: Sphinx, pagename: str) -> str: + if not os.path.isfile(app.env.project.doc2path(pagename)): + return None + + for exclude in app.config.gh_link_exclude: + if re.match(exclude, pagename): + return None + + found_prefix = "" + for pattern, prefix in app.config.gh_link_prefixes.items(): + if re.match(pattern, pagename): + found_prefix = prefix + break + + return found_prefix + + +def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[str]: + """Obtain GitHub URL for the given page. + + Args: + app: Sphinx instance. + mode: Typically "edit", or "blob". + pagename: Page name (path). + + Returns: + GitHub URL if applicable, None otherwise. + """ + + page_prefix = get_page_prefix(app, pagename) + if not page_prefix: + return None + + return "/".join( + [ + app.config.gh_link_base_url, + mode, + app.config.gh_link_version, + page_prefix, + app.env.project.doc2path(pagename, basedir=False), + ] + ) + + +def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optional[str]: + """Link to open a new Github issue regarding "pagename" with title, body, and + labels already pre-filled with useful information. + + Args: + app: Sphinx instance. + pagename: Page name (path). + + Returns: + URL to open a new issue if applicable, None otherwise. + """ + + if not os.path.isfile(app.env.project.doc2path(pagename)): + return None + + title = quote(f"[doc] Documentation issue in '{pagename}'") + labels = quote("area: Documentation") + body = quote( + dedent( + f"""\ + **Describe the bug** + + << Please describe the issue here >> + << You may also want to update the automatically generated issue title above. >> + + **Environment** + + * Page: `{pagename}` + * Version: {app.config.gh_link_version} + * SHA-1: {sha1} + """ + ) + ) + + return f"{app.config.gh_link_base_url}/issues/new?title={title}&labels={labels}&body={body}" + + +def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: + """Return a tuple with the date and SHA1 of the last commit made to a page. + + Arguments: + app {Sphinx} -- Sphinx application object + pagename {str} -- Page name + + Returns: + Optional[Tuple[str, str]] -- Tuple with the date and SHA1 of the last commit made to the + page, or None if the page is not in the repo. + """ + + page_prefix = get_page_prefix(app, pagename) + if not page_prefix: + return None + + orig_path = os.path.join( + app.config.ZEPHYR_BASE, + page_prefix, + app.env.project.doc2path(pagename, basedir=False), + ) + + try: + date_and_sha1 = ( + subprocess.check_output( + [ + "git", + "log", + "-1", + "--format=%ad %H", + "--date=unix", + orig_path, + ], + stderr=subprocess.STDOUT, + ) + .decode("utf-8") + .strip() + ) + date, sha1 = date_and_sha1.split(" ", 1) + date_object = datetime.fromtimestamp(int(date)) + last_update_fmt = app.config.html_last_updated_fmt + if last_update_fmt is not None: + date = format_date(last_update_fmt, date=date_object, language=app.config.language) + + return (date, sha1) + except subprocess.CalledProcessError: + return None + + +def add_jinja_filter(app: Sphinx): + if app.builder.format != "html": + return + + app.builder.templates.environment.filters["gh_link_get_blob_url"] = partial( + gh_link_get_url, app, mode="blob" + ) + + app.builder.templates.environment.filters["gh_link_get_edit_url"] = partial( + gh_link_get_url, app, mode="edit" + ) + + app.builder.templates.environment.filters["gh_link_get_open_issue_url"] = partial( + gh_link_get_open_issue_url, app + ) + + app.builder.templates.environment.filters["git_info"] = partial(git_info_filter, app) + + +def setup(app: Sphinx): + app.add_config_value("ZEPHYR_BASE", Path(__file__).resolve().parents[3], "html") + app.add_config_value("gh_link_version", "", "") + app.add_config_value("gh_link_base_url", "", "") + app.add_config_value("gh_link_prefixes", {}, "") + app.add_config_value("gh_link_exclude", [], "") + + app.connect("builder-inited", add_jinja_filter) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/doc/_extensions/zephyr/git_info.py b/doc/_extensions/zephyr/git_info.py deleted file mode 100644 index b405cd119a4..00000000000 --- a/doc/_extensions/zephyr/git_info.py +++ /dev/null @@ -1,103 +0,0 @@ -""" -Git Info Extension -################## - -Copyright (c) 2023 The Linux Foundation -SPDX-License-Identifier: Apache-2.0 - -Introduction -============ - -This extension adds a new Jinja filter, ``git_info``, that returns the date and SHA1 of the last -commit made to a page if this page is managed by Git. -""" - -import os -import re -import subprocess -from datetime import datetime -from functools import partial -from pathlib import Path -from typing import Optional -from typing import Tuple - -from sphinx.application import Sphinx -from sphinx.util.i18n import format_date - -__version__ = "0.1.0" - - -def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: - """Return a tuple with the date and SHA1 of the last commit made to a page. - - Arguments: - app {Sphinx} -- Sphinx application object - pagename {str} -- Page name - - Returns: - Optional[Tuple[str, str]] -- Tuple with the date and SHA1 of the last commit made to the - page, or None if the page is not in the repo. - """ - - if not os.path.isfile(app.env.project.doc2path(pagename)): - return None - - for exclude in app.config.vcs_link_exclude: - if re.match(exclude, pagename): - return None - - found_prefix = "" - for pattern, prefix in app.config.vcs_link_prefixes.items(): - if re.match(pattern, pagename): - found_prefix = prefix - break - - orig_path = os.path.join( - app.config.ZEPHYR_BASE, - found_prefix, - app.env.project.doc2path(pagename, basedir=False), - ) - - try: - date_and_sha1 = ( - subprocess.check_output( - [ - "git", - "log", - "-1", - "--format=%ad %H", - "--date=unix", - orig_path, - ], - stderr=subprocess.STDOUT, - ) - .decode("utf-8") - .strip() - ) - date, sha1 = date_and_sha1.split(" ", 1) - date_object = datetime.fromtimestamp(int(date)) - last_update_fmt = app.config.html_last_updated_fmt - if last_update_fmt is not None: - date = format_date(last_update_fmt, date=date_object, language=app.config.language) - - return (date, sha1) - except subprocess.CalledProcessError: - return None - - -def add_jinja_filter(app: Sphinx): - if app.builder.name != "html": - return - - app.builder.templates.environment.filters["git_info"] = partial(git_info_filter, app) - - -def setup(app: Sphinx): - app.add_config_value("ZEPHYR_BASE", Path(__file__).resolve().parents[3], "html") - app.connect("builder-inited", add_jinja_filter) - - return { - "version": __version__, - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/doc/_extensions/zephyr/vcs_link.py b/doc/_extensions/zephyr/vcs_link.py deleted file mode 100644 index 5cdc42bb812..00000000000 --- a/doc/_extensions/zephyr/vcs_link.py +++ /dev/null @@ -1,145 +0,0 @@ -""" -VCS Link -######## - -Copyright (c) 2021 Nordic Semiconductor ASA -SPDX-License-Identifier: Apache-2.0 - -Introduction -============ - -This Sphinx extension can be used to obtain various VCS URLs for a given Sphinx page. -This is useful, for example, when adding features like "Open on GitHub" on top -of pages. -The extension installs the following Jinja filter: - -* ``vcs_link_get_blob_url``: Returns a URL to the source of a page in the VCS. -* ``vcs_link_get_edit_url``: Returns a URL to edit the given page in the VCS. -* ``vcs_link_get_open_issue_url``: Returns a URL to open a new issue regarding the given page. - -Configuration options -===================== - -- ``vcs_link_version``: VCS version to use in the URL (e.g. "main") -- ``vcs_link_base_url``: Base URL used as a prefix for generated URLs. -- ``vcs_link_prefixes``: Mapping of pages (regex) <> VCS prefix. -- ``vcs_link_exclude``: List of pages (regex) that will not report a URL. Useful - for, e.g., auto-generated pages not in VCS. -""" - -from functools import partial -import os -import re -from textwrap import dedent -from typing import Optional -from urllib.parse import quote - -from sphinx.application import Sphinx - - -__version__ = "0.1.0" - - -def vcs_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[str]: - """Obtain VCS URL for the given page. - - Args: - app: Sphinx instance. - mode: Typically "edit", or "blob". - pagename: Page name (path). - - Returns: - VCS URL if applicable, None otherwise. - """ - - if not os.path.isfile(app.env.project.doc2path(pagename)): - return None - - for exclude in app.config.vcs_link_exclude: - if re.match(exclude, pagename): - return None - - found_prefix = "" - for pattern, prefix in app.config.vcs_link_prefixes.items(): - if re.match(pattern, pagename): - found_prefix = prefix - break - - return "/".join( - [ - app.config.vcs_link_base_url, - mode, - app.config.vcs_link_version, - found_prefix, - app.env.project.doc2path(pagename, basedir=False), - ] - ) - - -def vcs_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optional[str]: - """Link to open a new Github issue regarding "pagename" with title, body, and - labels already pre-filled with useful information. - - Args: - app: Sphinx instance. - pagename: Page name (path). - - Returns: - URL to open a new issue if applicable, None otherwise. - """ - - if not os.path.isfile(app.env.project.doc2path(pagename)): - return None - - title = quote(f"[doc] Documentation issue in '{pagename}'") - labels = quote("area: Documentation") - body = quote( - dedent( - f"""\ - **Describe the bug** - - << Please describe the issue here >> - << You may also want to update the automatically generated issue title above. >> - - **Environment** - - * Page: `{pagename}` - * Version: {app.config.vcs_link_version} - * SHA-1: {sha1} - """ - ) - ) - - return f"{app.config.vcs_link_base_url}/issues/new?title={title}&labels={labels}&body={body}" - - -def add_jinja_filter(app: Sphinx): - if app.builder.name != "html": - return - - app.builder.templates.environment.filters["vcs_link_get_blob_url"] = partial( - vcs_link_get_url, app, mode="blob" - ) - - app.builder.templates.environment.filters["vcs_link_get_edit_url"] = partial( - vcs_link_get_url, app, mode="edit" - ) - - app.builder.templates.environment.filters["vcs_link_get_open_issue_url"] = partial( - vcs_link_get_open_issue_url, app - ) - - -def setup(app: Sphinx): - app.add_config_value("vcs_link_version", "", "") - app.add_config_value("vcs_link_base_url", "", "") - app.add_config_value("vcs_link_prefixes", {}, "") - app.add_config_value("vcs_link_exclude", [], "") - - app.connect("builder-inited", add_jinja_filter) - - return { - "version": __version__, - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/doc/_templates/breadcrumbs.html b/doc/_templates/breadcrumbs.html index e3c10ab78d1..4f974503da4 100644 --- a/doc/_templates/breadcrumbs.html +++ b/doc/_templates/breadcrumbs.html @@ -18,14 +18,14 @@
  • - {%- if display_vcs_link %} - {% set vcs_blob_url = pagename | vcs_link_get_blob_url %} - {% if vcs_blob_url %} - {{ _('Open on GitHub') }} + {%- if display_gh_links %} + {% set gh_blob_url = pagename | gh_link_get_blob_url %} + {% if gh_blob_url %} + {{ _('Open on GitHub') }} {% endif %} {%- set git_last_updated, sha1 = pagename | git_info | default((None, None), true) %} {%- if sha1 %} - + {{ _('Report an issue')}} {% endif %} diff --git a/doc/_templates/footer.html b/doc/_templates/footer.html index 778fbc4b6bb..54ba724acb3 100644 --- a/doc/_templates/footer.html +++ b/doc/_templates/footer.html @@ -23,7 +23,7 @@

    If you find any errors on this page, outdated information, or have any other suggestion for improving its contents, please consider - opening an issue. + opening an issue.

    {%- endif %} diff --git a/doc/conf.py b/doc/conf.py index 82bd6304001..4c153e7a2e7 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -82,9 +82,8 @@ "sphinx_tabs.tabs", "zephyr.warnings_filter", "zephyr.doxyrunner", - "zephyr.vcs_link", + "zephyr.gh_utils", "zephyr.manifest_projects_table", - "zephyr.git_info", "notfound.extension", "sphinx_copybutton", "sphinx_togglebutton", @@ -171,7 +170,7 @@ ("3.3.0", "/3.3.0/"), ("2.7.5 (LTS)", "/2.7.5/"), ), - "display_vcs_link": True, + "display_gh_links": True, "reference_links": { "API": f"{reference_prefix}/doxygen/html/index.html", "Kconfig Options": f"{reference_prefix}/kconfig.html", @@ -262,17 +261,17 @@ notfound_urls_prefix = f"/{version}/" if is_release else "/latest/" -# -- Options for zephyr.vcs_link ------------------------------------------ +# -- Options for zephyr.gh_utils ------------------------------------------ -vcs_link_version = f"v{version}" if is_release else "main" -vcs_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr" -vcs_link_prefixes = { +gh_link_version = f"v{version}" if is_release else "main" +gh_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr" +gh_link_prefixes = { "samples/.*": "", "boards/.*": "", "snippets/.*": "", ".*": "doc", } -vcs_link_exclude = [ +gh_link_exclude = [ "reference/kconfig.*", "build/dts/api/bindings.*", "build/dts/api/compatibles.*", From 2e848d835727773ec1ab39d8051ec0ac86ebc28e Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 15 Sep 2023 22:40:07 +0900 Subject: [PATCH 2687/4498] drivers: adc: rpi_pico: Fix pinctrl doesn't apply in initialization. Fix the problem not apply pinctrl eventhough the config is defined. In practice, the setting is equals to soc default. So, there is no apparent change in behavior. Signed-off-by: TOKITA Hiroshi --- drivers/adc/adc_rpi_pico.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/adc/adc_rpi_pico.c b/drivers/adc/adc_rpi_pico.c index 0c7f525ec0c..ec13b0d7b6d 100644 --- a/drivers/adc/adc_rpi_pico.c +++ b/drivers/adc/adc_rpi_pico.c @@ -8,6 +8,7 @@ #define DT_DRV_COMPAT raspberrypi_pico_adc #include +#include #include #include @@ -31,6 +32,8 @@ LOG_MODULE_REGISTER(adc_rpi, CONFIG_ADC_LOG_LEVEL); struct adc_rpi_config { /** Number of supported channels */ uint8_t num_channels; + /** pinctrl configs */ + const struct pinctrl_dev_config *pcfg; /** function pointer to irq setup */ void (*irq_configure)(void); }; @@ -289,6 +292,12 @@ static int adc_rpi_init(const struct device *dev) { const struct adc_rpi_config *config = dev->config; struct adc_rpi_data *data = dev->data; + int ret; + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } config->irq_configure(); @@ -325,6 +334,7 @@ static int adc_rpi_init(const struct device *dev) #define ADC_RPI_INIT(idx) \ IRQ_CONFIGURE_FUNC(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ static struct adc_driver_api adc_rpi_api_##idx = { \ .channel_setup = adc_rpi_channel_setup, \ .read = adc_rpi_read, \ @@ -333,6 +343,7 @@ static int adc_rpi_init(const struct device *dev) }; \ static const struct adc_rpi_config adc_rpi_config_##idx = { \ .num_channels = ADC_RPI_CHANNEL_NUM, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ IRQ_CONFIGURE_DEFINE(idx), \ }; \ static struct adc_rpi_data adc_rpi_data_##idx = { \ From fe9b23070ce17ff29345263f473db504d1fcc39a Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Sat, 23 Sep 2023 14:07:46 +0200 Subject: [PATCH 2688/4498] boards: arm: xiao_ble: add blackmagicprobe runner Enable using a BlackMagicProbe for flashing and debugging XIAO BLE boards. Tested successfully with BMP 1.9.2 running on ST-Link/v2 against a `xiao_ble` board. Signed-off-by: Augusto Zanellato --- boards/arm/xiao_ble/board.cmake | 1 + boards/arm/xiao_ble/doc/index.rst | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/boards/arm/xiao_ble/board.cmake b/boards/arm/xiao_ble/board.cmake index 67f5aee98e4..a6aa2ac40a7 100644 --- a/boards/arm/xiao_ble/board.cmake +++ b/boards/arm/xiao_ble/board.cmake @@ -9,3 +9,4 @@ include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/arm/xiao_ble/doc/index.rst b/boards/arm/xiao_ble/doc/index.rst index 9966f913644..d4d4266311b 100644 --- a/boards/arm/xiao_ble/doc/index.rst +++ b/boards/arm/xiao_ble/doc/index.rst @@ -112,8 +112,8 @@ necessary software. Flashing -------- -Follow the instructions in the :ref:`jlink-external-debug-probe` page to install -and configure all the necessary software. Then build and flash applications as +Setup and connect a supported debug probe (JLink, instructions at :ref:`jlink-external-debug-probe` or +BlackMagic Probe). Then build and flash applications as usual (see :ref:`build_an_application` and :ref:`application_run` for more details). @@ -156,6 +156,8 @@ Debugging Refer to the :ref:`jlink-external-debug-probe` page to learn about debugging boards with a Segger IC. +Debugging using a BlackMagic Probe is also supported. + Testing the LEDs in the XIAO BLE (Sense) **************************************** From d8709301a26154b48293cc1b629b2ba167334ee9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 5 Oct 2023 09:27:32 -0700 Subject: [PATCH 2689/4498] doc: update technical escalation proccess Update process for technical PR escalation. Signed-off-by: Anas Nashif --- doc/contribute/contributor_expectations.rst | 43 ++++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/contribute/contributor_expectations.rst b/doc/contribute/contributor_expectations.rst index dfe6b5ff0e2..b3870102467 100644 --- a/doc/contribute/contributor_expectations.rst +++ b/doc/contribute/contributor_expectations.rst @@ -209,21 +209,46 @@ PR Technical Escalation In cases where a contributor objects to change requests from reviewers, Zephyr defines the following escalation process for resolving technical disagreements. +Before escalation of technical disagreements, follow the steps below: + - Resolve in the PR among assignee, maintainers and reviewer. - Assignee to act as moderator if applicable. -- Optionally resolve in the next `Zephyr Dev Meeting`_ or `Architecture Working - Group`_ meeting with more Maintainers and project stakeholders. +- Optionally resolve in the next `Zephyr Dev Meeting`_ meeting with more + Maintainers and project stakeholders. + + - The involved parties and the Assignee to be present when the issue is + discussed. + +- If no progress is made, the assignee (maintainer) has the right to dismiss + stale, unrelated or irrelevant change requests by reviewers giving the + reviewers a minimum of 1 business day to respond and revisit their initial + change requests or start the escalation process. + + The assignee has the responsibility to document the reasoning for dismissing + any reviews in the PR and should notify the reviewer about their review being + dismissed. - - The involved parties and the Assignee to be present when - the (escalated) issue is discussed. + To give the reviewers time to respond and escalate, the assignee is + expected to block the PR from being merged either by not + approving the PR or by setting the *DNM* label. -- TSC: Assignees can escalate to the TSC voting members and get a binding - resolution in the TSC by adding the `tsc`_ label on the PR. +Escalation can be triggered by any party participating in the review +process (assignee, reviewers or the original author of the change) following +the steps below: -- Assignee to ensure the resolution of the escalation is reflected in the PR - review. +- Escalate to the `Architecture Working Group`_ by adding the `Architecture + Review` label on the PR. Beside the weekly meeting where such escalations are + processed, the `Architecture Working Group`_ shall facilitate an offline + review of the escalation if requested, especially if any of the parties can't + attend the meeting. + +- If issues are not resolved, assignees can escalate to the TSC and get a + binding resolution in the TSC by adding the *TSC* label on the PR. + +- The Assignee is expected to ensure the resolution of the escalation and the + outcome is documented in the related pull request or issues on Github. .. _#pr-help: https://discord.com/channels/720317445772017664/997527108844798012 @@ -235,8 +260,6 @@ defines the following escalation process for resolving technical disagreements. .. _Architecture Working Group: https://github.com/zephyrproject-rtos/zephyr/wiki/Architecture-Working-Group -.. _tsc: https://github.com/zephyrproject-rtos/zephyr/labels/tsc - Reviewer Expectations ##################### From 866344905572e62d6993c0534245257f2577e87a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 10 Oct 2023 12:48:15 +0000 Subject: [PATCH 2690/4498] doc: reviewer expectations: minor optimizations Minor layout and language optimization to the review expectations document. Signed-off-by: Anas Nashif --- doc/contribute/contributor_expectations.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/contribute/contributor_expectations.rst b/doc/contribute/contributor_expectations.rst index b3870102467..460f4ef570f 100644 --- a/doc/contribute/contributor_expectations.rst +++ b/doc/contribute/contributor_expectations.rst @@ -235,7 +235,7 @@ Before escalation of technical disagreements, follow the steps below: approving the PR or by setting the *DNM* label. Escalation can be triggered by any party participating in the review -process (assignee, reviewers or the original author of the change) following +process (assignee, reviewers or the original author of the change) following the steps below: - Escalate to the `Architecture Working Group`_ by adding the `Architecture @@ -244,8 +244,9 @@ the steps below: review of the escalation if requested, especially if any of the parties can't attend the meeting. -- If issues are not resolved, assignees can escalate to the TSC and get a - binding resolution in the TSC by adding the *TSC* label on the PR. +- If all avenues of resolution and escalation have failed, assignees can escalate + to the TSC and get a binding resolution in the TSC by adding the *TSC* label + on the PR. - The Assignee is expected to ensure the resolution of the escalation and the outcome is documented in the related pull request or issues on Github. @@ -267,10 +268,11 @@ Reviewer Expectations for more details. - The Zephyr Project recognizes that reviewers and maintainers have limited - bandwidth. Prioritize review requests in the following order: + bandwidth. As a reviewer, prioritize review requests in the following order: - #. PRs related to items in the `Zephyr Release Plan`_. - #. PRs that the reviewer has requested blocking changes. + #. PRs related to items in the `Zephyr Release Plan`_ or those targetting + the next release during the stabilization period (after RC1). + #. PRs where the reviewer has requested blocking changes. #. PRs assigned to the reviewer as the area maintainer. #. All other PRs. From a6bfbedbf5b76b05fb2a2899330cb64b1f9cf06c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 11 Oct 2023 19:50:24 +0000 Subject: [PATCH 2691/4498] doc: project roles: Further finetune language More details about roles and responsibilities and reviewer expectations. Signed-off-by: Anas Nashif --- doc/contribute/contributor_expectations.rst | 10 +++++++- doc/project/project_roles.rst | 26 ++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/doc/contribute/contributor_expectations.rst b/doc/contribute/contributor_expectations.rst index 460f4ef570f..aeb90c33d68 100644 --- a/doc/contribute/contributor_expectations.rst +++ b/doc/contribute/contributor_expectations.rst @@ -261,6 +261,9 @@ the steps below: .. _Architecture Working Group: https://github.com/zephyrproject-rtos/zephyr/wiki/Architecture-Working-Group + +.. _reviewer-expectations: + Reviewer Expectations ##################### @@ -270,7 +273,7 @@ Reviewer Expectations - The Zephyr Project recognizes that reviewers and maintainers have limited bandwidth. As a reviewer, prioritize review requests in the following order: - #. PRs related to items in the `Zephyr Release Plan`_ or those targetting + #. PRs related to items in the `Zephyr Release Plan`_ or those targeting the next release during the stabilization period (after RC1). #. PRs where the reviewer has requested blocking changes. #. PRs assigned to the reviewer as the area maintainer. @@ -300,6 +303,11 @@ Reviewer Expectations they address all non-blocking comments. PR authors should acknowledge every review comment in some way, even if it's just with an emoticon. +- Reviewers shall be *clear* and *concise* what changes they are requesting when the + "Request Changes" option is used. Requested changes shall be in the scope of + the PR in question and following the contribution and style guidelines of the + project. + .. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md .. _Zephyr Release Plan: https://github.com/orgs/zephyrproject-rtos/projects/13 diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index c2b970c77f7..2d1a74b573f 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -67,9 +67,9 @@ template ` and the guidelines +of the project or in cases of disagreement, it is the responsibility of the +assignee to advance the review process and resolve any disagreements. + +Collaborator approval of pull requests are counted toward the minimum required +approvals needed to merge a PR. Other criteria for merging may apply. Maintainer ++++++++++ @@ -121,7 +128,8 @@ Contributors or Collaborators are promoted to the Maintainer role by adding the GitHub user name to one or more ``maintainers`` sections of the :ref:`maintainers_file` in the Zephyr repository. -Maintainer votes on pull requests can block or approve the pull request. +Maintainer approval of pull requests are counted toward the minimum +required approvals needed to merge a PR. Other criteria for merging may apply. Role Retirement ############### @@ -149,9 +157,11 @@ Assignees are set either automatically based on the code being changed or set by the other Maintainers, the Release Engineering team can set an assignee when the latter is not possible. -* Right to dismiss stale reviews and seek reviews from additional maintainers, - developers and contributors -* Right to block pull requests from being merged +* Right to dismiss stale and unrelated reviews or reviews not following + :ref:`expectations ` from reviewers and seek reviews + from additional maintainers, developers and contributors +* Right to block pull requests from being merged until issues or changes + requested are addressed * Responsibility to re-assign a pull request if they are the original submitter of the code * Responsibility to drive the pull request to a mergeable state From 51d579438712db629f02e515845514bfdcfaca1c Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Tue, 24 Oct 2023 16:17:12 +0800 Subject: [PATCH 2692/4498] drivers: flash: Add Ambiq flash controller driver. This commit adds flash controller driver for Ambiq Apollo4 SoCs. Signed-off-by: Aaron Ye --- drivers/flash/CMakeLists.txt | 1 + drivers/flash/Kconfig | 2 + drivers/flash/Kconfig.ambiq | 12 ++ drivers/flash/flash_ambiq.c | 191 ++++++++++++++++++ .../ambiq,flash-controller.yaml | 8 + 5 files changed, 214 insertions(+) create mode 100644 drivers/flash/Kconfig.ambiq create mode 100644 drivers/flash/flash_ambiq.c create mode 100644 dts/bindings/flash_controller/ambiq,flash-controller.yaml diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index e937d3ee5a9..4a02268a2b4 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -51,6 +51,7 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_CAD_QSPI_NOR flash_cadence_qspi_nor.c zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_XMC4XXX soc_flash_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_FLASH_RPI_PICO flash_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_FLASH_ANDES_QSPI flash_andes_qspi.c) +zephyr_library_sources_ifdef(CONFIG_FLASH_AMBIQ flash_ambiq.c) if(CONFIG_FLASH_MCUX_FLEXSPI_XIP) dt_chosen(chosen_flash PROPERTY "zephyr,flash") diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index ce7f92dd94a..5b47c75c20e 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -159,4 +159,6 @@ source "drivers/flash/Kconfig.nxp_s32" source "drivers/flash/Kconfig.andes" +source "drivers/flash/Kconfig.ambiq" + endif # FLASH diff --git a/drivers/flash/Kconfig.ambiq b/drivers/flash/Kconfig.ambiq new file mode 100644 index 00000000000..cc84c0faf39 --- /dev/null +++ b/drivers/flash/Kconfig.ambiq @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +config FLASH_AMBIQ + bool "Ambiq flash driver on MRAM" + default y + depends on DT_HAS_AMBIQ_FLASH_CONTROLLER_ENABLED + select AMBIQ_HAL + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_DRIVER_ENABLED + help + Enables Ambiq flash driver on MRAM. diff --git a/drivers/flash/flash_ambiq.c b/drivers/flash/flash_ambiq.c new file mode 100644 index 00000000000..fdc852c04ca --- /dev/null +++ b/drivers/flash/flash_ambiq.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023 Ambiq Micro Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ambiq_flash_controller + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(flash_ambiq, CONFIG_FLASH_LOG_LEVEL); + +#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) +#define SOC_NV_FLASH_ADDR DT_REG_ADDR(SOC_NV_FLASH_NODE) +#define SOC_NV_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) +#define MIN_WRITE_SIZE 16 +#define FLASH_WRITE_BLOCK_SIZE MAX(DT_PROP(SOC_NV_FLASH_NODE, write_block_size), MIN_WRITE_SIZE) +#define FLASH_ERASE_BLOCK_SIZE DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) + +BUILD_ASSERT((FLASH_WRITE_BLOCK_SIZE & (MIN_WRITE_SIZE - 1)) == 0, + "The flash write block size must be a multiple of 16!"); + +#define FLASH_ERASE_BYTE 0xFF +#define FLASH_ERASE_WORD \ + (((uint32_t)(FLASH_ERASE_BYTE << 24)) | ((uint32_t)(FLASH_ERASE_BYTE << 16)) | \ + ((uint32_t)(FLASH_ERASE_BYTE << 8)) | ((uint32_t)FLASH_ERASE_BYTE)) + +#if defined(CONFIG_MULTITHREADING) +static struct k_sem flash_ambiq_sem; +#define FLASH_SEM_INIT() k_sem_init(&flash_ambiq_sem, 1, 1) +#define FLASH_SEM_TAKE() k_sem_take(&flash_ambiq_sem, K_FOREVER) +#define FLASH_SEM_GIVE() k_sem_give(&flash_ambiq_sem) +#else +#define FLASH_SEM_INIT() +#define FLASH_SEM_TAKE() +#define FLASH_SEM_GIVE() +#endif /* CONFIG_MULTITHREADING */ + +static const struct flash_parameters flash_ambiq_parameters = { + .write_block_size = FLASH_WRITE_BLOCK_SIZE, + .erase_value = FLASH_ERASE_BYTE, +}; + +static bool flash_ambiq_valid_range(off_t offset, size_t len) +{ + if ((offset < 0) || offset >= SOC_NV_FLASH_SIZE || (SOC_NV_FLASH_SIZE - offset) < len) { + return false; + } + + return true; +} + +static int flash_ambiq_read(const struct device *dev, off_t offset, void *data, size_t len) +{ + ARG_UNUSED(dev); + + if (!flash_ambiq_valid_range(offset, len)) { + return -EINVAL; + } + + if (len == 0) { + return 0; + } + + memcpy(data, (uint8_t *)(SOC_NV_FLASH_ADDR + offset), len); + + return 0; +} + +static int flash_ambiq_write(const struct device *dev, off_t offset, const void *data, size_t len) +{ + ARG_UNUSED(dev); + + int ret = 0; + uint32_t critical = 0; + uint32_t aligned[FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t)] = {0}; + uint32_t *src = (uint32_t *)data; + + /* write address must be block size aligned and the write length must be multiple of block + * size. + */ + if (!flash_ambiq_valid_range(offset, len) || + ((uint32_t)offset & (FLASH_WRITE_BLOCK_SIZE - 1)) || + (len & (FLASH_WRITE_BLOCK_SIZE - 1))) { + return -EINVAL; + } + + if (len == 0) { + return 0; + } + + FLASH_SEM_TAKE(); + + critical = am_hal_interrupt_master_disable(); + for (int i = 0; i < len / FLASH_WRITE_BLOCK_SIZE; i++) { + for (int j = 0; j < FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t); j++) { + /* Make sure the source data is 4-byte aligned. */ + aligned[j] = UNALIGNED_GET((uint32_t *)src); + src++; + } + ret = am_hal_mram_main_program( + AM_HAL_MRAM_PROGRAM_KEY, aligned, + (uint32_t *)(SOC_NV_FLASH_ADDR + offset + i * FLASH_WRITE_BLOCK_SIZE), + FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t)); + if (ret) { + break; + } + } + am_hal_interrupt_master_set(critical); + + FLASH_SEM_GIVE(); + + return ret; +} + +static int flash_ambiq_erase(const struct device *dev, off_t offset, size_t len) +{ + ARG_UNUSED(dev); + + int ret = 0; + + if (!flash_ambiq_valid_range(offset, len)) { + return -EINVAL; + } + + /* The erase address and length alignment check will be done in HAL.*/ + + if (len == 0) { + return 0; + } + + FLASH_SEM_TAKE(); + + ret = am_hal_mram_main_fill(AM_HAL_MRAM_PROGRAM_KEY, FLASH_ERASE_WORD, + (uint32_t *)(SOC_NV_FLASH_ADDR + offset), + (len / sizeof(uint32_t))); + + FLASH_SEM_GIVE(); + + return ret; +} + +static const struct flash_parameters *flash_ambiq_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_ambiq_parameters; +} + +#if CONFIG_FLASH_PAGE_LAYOUT +static const struct flash_pages_layout pages_layout = { + .pages_count = SOC_NV_FLASH_SIZE / FLASH_ERASE_BLOCK_SIZE, + .pages_size = FLASH_ERASE_BLOCK_SIZE, +}; + +static void flash_ambiq_pages_layout(const struct device *dev, + const struct flash_pages_layout **layout, size_t *layout_size) +{ + ARG_UNUSED(dev); + + *layout = &pages_layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +static const struct flash_driver_api flash_ambiq_driver_api = { + .read = flash_ambiq_read, + .write = flash_ambiq_write, + .erase = flash_ambiq_erase, + .get_parameters = flash_ambiq_get_parameters, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_ambiq_pages_layout, +#endif +}; + +static int flash_ambiq_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + FLASH_SEM_INIT(); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, flash_ambiq_init, NULL, NULL, NULL, POST_KERNEL, + CONFIG_FLASH_INIT_PRIORITY, &flash_ambiq_driver_api); diff --git a/dts/bindings/flash_controller/ambiq,flash-controller.yaml b/dts/bindings/flash_controller/ambiq,flash-controller.yaml new file mode 100644 index 00000000000..60cb1dee81b --- /dev/null +++ b/dts/bindings/flash_controller/ambiq,flash-controller.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023, Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq flash controller + +compatible: "ambiq,flash-controller" + +include: flash-controller.yaml From c2601e88064c62ae173af919d214a2c6576deb30 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Tue, 10 Oct 2023 17:56:57 +0800 Subject: [PATCH 2693/4498] dts: arm: ambiq: Add flash controller instance to Apollo4 Blue Plus SoC. This commit instantiates the flash controller. Signed-off-by: Aaron Ye --- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 80b004c84af..86bd5937eb2 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -23,12 +23,6 @@ }; }; - /* MRAM region */ - flash0: flash@18000 { - compatible = "soc-nv-flash"; - reg = <0x00018000 0x1e8000>; - }; - /* TCM */ tcm: tcm@10000000 { compatible = "zephyr,memory-region"; @@ -43,6 +37,20 @@ }; soc { + flash: flash-controller@18000 { + compatible = "ambiq,flash-controller"; + reg = <0x00018000 0x1e8000>; + + #address-cells = <1>; + #size-cells = <1>; + + /* MRAM region */ + flash0: flash@18000 { + compatible = "soc-nv-flash"; + reg = <0x00018000 0x1e8000>; + }; + }; + pwrcfg: pwrcfg@40021000 { compatible = "ambiq,pwrctrl"; reg = <0x40021000 0x400>; From 0d1e4684b767a42079990cd28e8918d2903fb85a Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Thu, 12 Oct 2023 12:44:50 +0800 Subject: [PATCH 2694/4498] boards: arm: apollo4p_blue_kxr_evb: Enable flash controller. This commit enables flash controller instance for apollo4p_blue_kxr_evb. Signed-off-by: Aaron Ye --- .../apollo4p_blue_kxr_evb.dts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index 1eca9ae225e..add81097c40 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -13,6 +13,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,uart-pipe = &uart0; + zephyr,flash-controller = &flash; }; aliases { watchdog0 = &wdt0; @@ -56,3 +57,20 @@ pinctrl-names = "default"; status = "okay"; }; + +&flash0 { + erase-block-size = <2048>; + write-block-size = <16>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Set 16KB of storage at the end of the 1952KB of flash */ + storage_partition: partition@1e4000 { + label = "storage"; + reg = <0x001e4000 0x4000>; + }; + }; +}; From 16f486174160a5623d981e0dc1af3741270510c5 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 16 Oct 2023 17:04:20 -0700 Subject: [PATCH 2695/4498] drivers: i3c: mcux: fix config_get to return last config set mcux_i3c_configure() was saving values to a ctrl_config_hal struct, but config_get() was not returning the values in that struct. Remove that struct from the static data of the driver and instead just have it on the stack. We init that struct as needed just before calling the SDK API I3C_MasterInit(). There's no reason to keep it around. Change mcux_i3c_configure() to save a copy of the configuration in the static data common.ctrl_config, which is what is returned by config_get(). Signed-off-by: Mike J. Chen --- drivers/i3c/i3c_mcux.c | 46 +++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index c1ef9d9392e..a864905a39a 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -87,9 +87,6 @@ struct mcux_i3c_data { /** Common I3C Driver Data */ struct i3c_driver_data common; - /** Configuration parameter to be used with HAL. */ - i3c_master_config_t ctrl_config_hal; - /** Semaphore to serialize access for applications. */ struct k_sem lock; @@ -1806,7 +1803,7 @@ static int mcux_i3c_configure(const struct device *dev, const struct mcux_i3c_config *dev_cfg = dev->config; struct mcux_i3c_data *dev_data = dev->data; I3C_Type *base = dev_cfg->base; - i3c_master_config_t *ctrl_config_hal = &dev_data->ctrl_config_hal; + i3c_master_config_t master_config; struct i3c_config_controller *ctrl_cfg = config; uint32_t clock_freq; int ret = 0; @@ -1835,11 +1832,23 @@ static int mcux_i3c_configure(const struct device *dev, goto out_configure; } - ctrl_config_hal->baudRate_Hz.i2cBaud = ctrl_cfg->scl.i2c; - ctrl_config_hal->baudRate_Hz.i3cPushPullBaud = ctrl_cfg->scl.i3c; + /* + * Save requested config so next config_get() call returns the + * correct values. + */ + (void)memcpy(&dev_data->common.ctrl_config, ctrl_cfg, sizeof(*ctrl_cfg)); + + I3C_MasterGetDefaultConfig(&master_config); + + master_config.baudRate_Hz.i2cBaud = ctrl_cfg->scl.i2c; + master_config.baudRate_Hz.i3cPushPullBaud = ctrl_cfg->scl.i3c; + + if (dev_data->clocks.i3c_od_scl_hz) { + master_config.baudRate_Hz.i3cOpenDrainBaud = dev_data->clocks.i3c_od_scl_hz; + } /* Initialize hardware */ - I3C_MasterInit(base, ctrl_config_hal, clock_freq); + I3C_MasterInit(base, &master_config, clock_freq); out_configure: return ret; @@ -1912,30 +1921,11 @@ static int mcux_i3c_init(const struct device *dev) k_sem_init(&data->lock, 1, 1); k_sem_init(&data->ibi_lock, 1, 1); - /* - * Default controller configuration to act as the primary - * and active controller. - */ - I3C_MasterGetDefaultConfig(&data->ctrl_config_hal); - - /* Set default SCL clock rate (in Hz) */ - if (ctrl_config->scl.i2c == 0U) { - ctrl_config->scl.i2c = data->ctrl_config_hal.baudRate_Hz.i2cBaud; - } - - if (ctrl_config->scl.i3c == 0U) { - ctrl_config->scl.i3c = data->ctrl_config_hal.baudRate_Hz.i3cPushPullBaud; - } - - if (data->clocks.i3c_od_scl_hz != 0U) { - data->ctrl_config_hal.baudRate_Hz.i3cOpenDrainBaud = data->clocks.i3c_od_scl_hz; - } - /* Currently can only act as primary controller. */ - data->common.ctrl_config.is_secondary = false; + ctrl_config->is_secondary = false; /* HDR mode not supported at the moment. */ - data->common.ctrl_config.supported_hdr = 0U; + ctrl_config->supported_hdr = 0U; ret = mcux_i3c_configure(dev, I3C_CONFIG_CONTROLLER, ctrl_config); if (ret != 0) { From 7c1884ae9b84176f86cbe7e994bd6261ecacdbb3 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 16 Oct 2023 17:09:52 -0700 Subject: [PATCH 2696/4498] drivers: i3c: mcux: send 7h7e on first transfer or after stop Makes the i3c_mcux driver consistent with the i3c_cdns driver. Signed-off-by: Mike J. Chen --- drivers/i3c/i3c_mcux.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index a864905a39a..820e6b4a3a3 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -1071,6 +1071,7 @@ static int mcux_i3c_transfer(const struct device *dev, I3C_Type *base = config->base; uint32_t intmask; int ret; + bool send_broadcast = true; if (target->dynamic_addr == 0U) { ret = -EINVAL; @@ -1121,12 +1122,32 @@ static int mcux_i3c_transfer(const struct device *dev, } } + /* + * Send broadcast header on first transfer or after a STOP, + * unless flag is set not to. + */ + if (!(msgs[i].flags & I3C_MSG_NBCH) && (send_broadcast)) { + ret = mcux_i3c_request_emit_start(base, I3C_BROADCAST_ADDR, + false, false, 0); + if (ret < 0) { + LOG_ERR("emit start of broadcast addr failed, error (%d)", + ret); + goto out_xfer_i3c_stop_unlock; + } + send_broadcast = false; + } + ret = mcux_i3c_do_one_xfer(base, dev_data, target->dynamic_addr, false, msgs[i].buf, msgs[i].len, is_read, emit_start, emit_stop, no_ending); if (ret < 0) { goto out_xfer_i3c_stop_unlock; } + + if (emit_stop) { + /* After a STOP, send broadcast header before next msg */ + send_broadcast = true; + } } ret = 0; From 1193049c0a1737e7037817235c93eb4961cc402a Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 16 Oct 2023 17:19:36 -0700 Subject: [PATCH 2697/4498] drivers: i3c: mcux: tighten the FIFO read At high i3c rates, the mcux_i3c_do_one_xfer_read() could get into an infinite loop where the rx_count kept returning 0 but the complete status bit was never set. I believe the problem was that the function was not emptying the FIFO fast enough, so tighten the loop that processes the FIFO. Signed-off-by: Mike J. Chen --- drivers/i3c/i3c_mcux.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 820e6b4a3a3..30bf5f8c885 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -879,9 +879,7 @@ static int mcux_i3c_recover_bus(const struct device *dev) */ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, uint8_t *buf, uint8_t buf_sz) { - int rx_count; bool completed = false; - bool overflow = false; int ret = 0; int offset = 0; @@ -908,28 +906,19 @@ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, uint8_t *buf, uint8_t buf_s } /* - * Transfer data from FIFO into buffer. + * Transfer data from FIFO into buffer. Read + * in a tight loop to reduce chance of losing + * FIFO data when the i3c speed is high. */ - rx_count = mcux_i3c_fifo_rx_count_get(base); - while (rx_count > 0) { - uint8_t data = (uint8_t)base->MRDATAB; - - if (offset < buf_sz) { - buf[offset] = data; - offset += 1; - } else { - overflow = true; + while (offset < buf_sz) { + if (mcux_i3c_fifo_rx_count_get(base) == 0) { + break; } - - rx_count -= 1; + buf[offset++] = (uint8_t)base->MRDATAB; } } - if (overflow) { - ret = -EINVAL; - } else { - ret = offset; - } + ret = offset; one_xfer_read_out: return ret; From f344019f2d3dcda94947bb07beb0fc29fbe39a38 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Tue, 17 Oct 2023 14:19:59 -0700 Subject: [PATCH 2698/4498] drivers: i3c: mcux: Remove infinite wait for MCTRLDONE in auto-IBI Remove the MCTRLDONE wait in mcux_i3c_request_auto_ibi(). I've seen this code getting stuck where the MCTRLDONE bit is never set in the MSTATUS register by the controller and this function spins forever. Documentaiton of the MCTRLDONE bit only mentions it being set for EmitStartAddr and ProcessDAA, but not for AutoIBI requests. All the calls to this function do completion checks afterwards, and with a timeout, so I believe the MCTRLDONE check is not needed (and may not even be correct). Signed-off-by: Mike J. Chen --- drivers/i3c/i3c_mcux.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 30bf5f8c885..1c579ba83f2 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -539,9 +539,6 @@ static inline void mcux_i3c_request_daa(I3C_Type *base) /** * @brief Tell controller to start auto IBI. * - * This also waits for the controller to indicate auto IBI - * has started before returning. - * * @param base Pointer to controller registers. */ static inline void mcux_i3c_request_auto_ibi(I3C_Type *base) @@ -549,8 +546,6 @@ static inline void mcux_i3c_request_auto_ibi(I3C_Type *base) reg32_update(&base->MCTRL, I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK | I3C_MCTRL_RDTERM_MASK, I3C_MCTRL_REQUEST_AUTO_IBI | I3C_MCTRL_IBIRESP_ACK_AUTO); - - mcux_i3c_status_wait_clear(base, I3C_MSTATUS_MCTRLDONE_MASK); } /** From b0a5492026b0f882a5e9b4968b7ae5c763b3f90a Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Wed, 25 Oct 2023 14:24:00 -0700 Subject: [PATCH 2699/4498] drivers: i3c: mcux: Add dt property disable-open-drain-high-pp The default is that the high time for open-drain clk is one PPBAUD, which is typically very short. Some device require a longer high time during the open-drain address phase so add a property to allow device tree to override the default. Signed-off-by: Mike J. Chen --- drivers/i3c/i3c_mcux.c | 6 ++++++ dts/bindings/i3c/nxp,mcux-i3c.yaml | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 1c579ba83f2..d996639dab0 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -81,6 +81,9 @@ struct mcux_i3c_config { /** Interrupt configuration function. */ void (*irq_config_func)(const struct device *dev); + + /** Disable open drain high push pull */ + bool disable_open_drain_high_pp; }; struct mcux_i3c_data { @@ -1847,6 +1850,7 @@ static int mcux_i3c_configure(const struct device *dev, master_config.baudRate_Hz.i2cBaud = ctrl_cfg->scl.i2c; master_config.baudRate_Hz.i3cPushPullBaud = ctrl_cfg->scl.i3c; + master_config.enableOpenDrainHigh = dev_cfg->disable_open_drain_high_pp ? false : true; if (dev_data->clocks.i3c_od_scl_hz) { master_config.baudRate_Hz.i3cOpenDrainBaud = dev_data->clocks.i3c_od_scl_hz; @@ -2090,6 +2094,8 @@ static const struct i3c_driver_api mcux_i3c_driver_api = { .common.dev_list.i2c = mcux_i3c_i2c_device_array_##id, \ .common.dev_list.num_i2c = ARRAY_SIZE(mcux_i3c_i2c_device_array_##id), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ + .disable_open_drain_high_pp = \ + DT_INST_PROP_OR(id, disable_open_drain_high_pp, false), \ }; \ static struct mcux_i3c_data mcux_i3c_data_##id = { \ .clocks.i3c_od_scl_hz = DT_INST_PROP_OR(id, i3c_od_scl_hz, 0), \ diff --git a/dts/bindings/i3c/nxp,mcux-i3c.yaml b/dts/bindings/i3c/nxp,mcux-i3c.yaml index a31d61d6a85..2fd62be9694 100644 --- a/dts/bindings/i3c/nxp,mcux-i3c.yaml +++ b/dts/bindings/i3c/nxp,mcux-i3c.yaml @@ -36,3 +36,12 @@ properties: type: int description: Slow clock divider for I3C required: true + + disable-open-drain-high-pp: + type: boolean + description: | + If false, open drain high time is 1 PPBAUD count, + which is short high and long low. + If true, open drain high time is same as ODBAUD + so that open drain clock is 50% duty cycle. + Default is false. From ac3a6d3721a4c5283067455c4c554aff774565a1 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 23 Oct 2023 11:10:14 +0200 Subject: [PATCH 2700/4498] tests: Bluetooth: tester: Fix missing net_buf_unref This fixes missing unreference of network buffer allocated when there is no data to send in the ring buffer. The code have been refactored, so that we check whether there is anything to send first, and if there is, the TX buffer is allocated. Signed-off-by: Mariusz Skamra --- tests/bluetooth/tester/src/btp_bap.c | 49 ++++++++++++---------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 7d457810007..a35950b9cc5 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -1085,41 +1085,32 @@ static void audio_send_timeout(struct k_work *work) /* TODO: Synchronize the Host clock with the Controller clock */ } - buf = net_buf_alloc(&tx_pool, K_NO_WAIT); - if (!buf) { - LOG_ERR("Cannot allocate net_buf. Dropping data."); - k_work_schedule_for_queue(&iso_data_work_q, dwork, - K_USEC(stream->stream.qos->interval)); - return; - } - - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - /* Get buffer within a ring buffer memory */ size = ring_buf_get_claim(&audio_ring_buf, &data, stream->stream.qos->sdu); - if (size != 0) { - net_buf_add_mem(buf, data, size); - } else { - k_work_schedule_for_queue(&iso_data_work_q, dwork, - K_USEC(stream->stream.qos->interval)); - return; - } + if (size > 0) { + buf = net_buf_alloc(&tx_pool, K_NO_WAIT); + if (!buf) { + LOG_ERR("Cannot allocate net_buf. Dropping data."); + } else { + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + net_buf_add_mem(buf, data, size); - /* Because the seq_num field of the audio_stream struct is atomic_val_t (4 bytes), - * let's allow an overflow and just cast it to uint16_t. - */ - stream->last_req_seq_num = (uint16_t)atomic_get(&stream->seq_num); + /* Because the seq_num field of the audio_stream struct is atomic_val_t + * (4 bytes), let's allow an overflow and just cast it to uint16_t. + */ + stream->last_req_seq_num = (uint16_t)atomic_get(&stream->seq_num); - LOG_DBG("Sending data to stream %p len %d seq %d", &stream->stream, size, - stream->last_req_seq_num); + LOG_DBG("Sending data to stream %p len %d seq %d", &stream->stream, size, + stream->last_req_seq_num); - err = bt_bap_stream_send(&stream->stream, buf, 0, BT_ISO_TIMESTAMP_NONE); - if (err != 0) { - LOG_ERR("Failed to send audio data to stream %p, err %d", &stream->stream, err); - net_buf_unref(buf); - } + err = bt_bap_stream_send(&stream->stream, buf, 0, BT_ISO_TIMESTAMP_NONE); + if (err != 0) { + LOG_ERR("Failed to send audio data to stream %p, err %d", + &stream->stream, err); + net_buf_unref(buf); + } + } - if (size != 0) { /* Free ring buffer memory */ err = ring_buf_get_finish(&audio_ring_buf, size); if (err != 0) { From 1a0e8d6f9e1c10180bb14d60d7a48959cbd1f7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 14:33:17 +0200 Subject: [PATCH 2701/4498] logging: log_msg: Add functions for handling simple log messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for new feature which optimizes handling of the most common log messages (0-2 32 bit word arguments) add functions dedicated for that purpose. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_msg.h | 32 ++++++- subsys/logging/log_msg.c | 149 +++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index 0279fb0d2cd..95b4dc6e5b9 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -503,7 +503,37 @@ struct log_msg *z_log_msg_alloc(uint32_t wlen); void z_log_msg_finalize(struct log_msg *msg, const void *source, const struct log_msg_desc desc, const void *data); -/** @brief Create simple message from message details and string package. +/** @brief Create log message using simplified method for string with no arguments. + * + * @param source Pointer to the source structure. + * @param level Severity level. + * @param fmt String pointer. + */ +__syscall void z_log_msg_simple_create_0(const void *source, uint32_t level, + const char *fmt); + +/** @brief Create log message using simplified method for string with a one argument. + * + * @param source Pointer to the source structure. + * @param level Severity level. + * @param fmt String pointer. + * @param arg String argument. + */ +__syscall void z_log_msg_simple_create_1(const void *source, uint32_t level, + const char *fmt, uint32_t arg); + +/** @brief Create log message using simplified method for string with two arguments. + * + * @param source Pointer to the source structure. + * @param level Severity level. + * @param fmt String pointer. + * @param arg0 String argument. + * @param arg1 String argument. + */ +__syscall void z_log_msg_simple_create_2(const void *source, uint32_t level, + const char *fmt, uint32_t arg0, uint32_t arg1); + +/** @brief Create a logging message from message details and string package. * * @param source Source. * diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 3756d52480d..528f0d8a726 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -20,6 +20,8 @@ BUILD_ASSERT(sizeof(struct log_msg_desc) == sizeof(uint32_t), !(IS_ENABLED(CONFIG_LOG_FRONTEND) && \ (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY) || log_backend_count_get() == 0)) +#define CBPRINTF_DESC_SIZE32 (sizeof(struct cbprintf_package_desc) / sizeof(uint32_t)) + void z_log_msg_finalize(struct log_msg *msg, const void *source, const struct log_msg_desc desc, const void *data) { @@ -43,6 +45,153 @@ void z_log_msg_finalize(struct log_msg *msg, const void *source, z_log_msg_commit(msg); } +/** @brief Create a log message using simplified method. + * + * Simple log message has 0-2 32 bit word arguments so creating cbprintf package + * is straightforward as there is no padding or alignment to concern about. + * This function takes input data which is fmt pointer + 0-2 arguments, creates + * package header which is very simple as it only contain non-zero length field. + * Then space is allocated and message is committed. Such simple approach can + * be applied because it is known that input string does not have any arguments + * which complicate things (string pointers, floating numbers). Simple method is + * also limited to 32 bit arch. + * + * @param source Source. + * @param level Severity level. + * @param data Package content (without header). + * @param len Package content length in words. + */ +static void z_log_msg_simple_create(const void *source, uint32_t level, uint32_t *data, size_t len) +{ + /* Package length (in words) is increased by the header. */ + size_t plen32 = len + CBPRINTF_DESC_SIZE32; + /* Package length in bytes. */ + size_t plen8 = sizeof(uint32_t) * plen32; + struct log_msg *msg = z_log_msg_alloc(Z_LOG_MSG_ALIGNED_WLEN(plen8, 0)); + union cbprintf_package_hdr package_hdr = { + .desc = { + .len = plen32 + } + }; + + if (msg) { + uint32_t *package = (uint32_t *)msg->data; + + *package++ = (uint32_t)(uintptr_t)package_hdr.raw; + for (size_t i = 0; i < len; i++) { + *package++ = data[i]; + } + } + + struct log_msg_desc desc = { + .level = level, + .package_len = plen8, + .data_len = 0, + }; + + z_log_msg_finalize(msg, source, desc, NULL); + +} + +void z_impl_z_log_msg_simple_create_0(const void *source, uint32_t level, const char *fmt) +{ + + if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 1; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + (uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } + + if (!BACKENDS_IN_USE()) { + return; + } + + uint32_t data[] = {(uint32_t)(uintptr_t)fmt}; + + z_log_msg_simple_create(source, level, data, ARRAY_SIZE(data)); +} + +void z_impl_z_log_msg_simple_create_1(const void *source, uint32_t level, + const char *fmt, uint32_t arg) +{ + if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 2; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + (uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + arg + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } + + if (!BACKENDS_IN_USE()) { + return; + } + + uint32_t data[] = {(uint32_t)(uintptr_t)fmt, arg}; + + z_log_msg_simple_create(source, level, data, ARRAY_SIZE(data)); +} + +void z_impl_z_log_msg_simple_create_2(const void *source, uint32_t level, + const char *fmt, uint32_t arg0, uint32_t arg1) +{ + if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 3; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + [0](uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + arg0, + arg1 + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } + + if (!BACKENDS_IN_USE()) { + return; + } + + uint32_t data[] = {(uint32_t)(uintptr_t)fmt, arg0, arg1}; + + z_log_msg_simple_create(source, level, data, ARRAY_SIZE(data)); +} + void z_impl_z_log_msg_static_create(const void *source, const struct log_msg_desc desc, uint8_t *package, const void *data) From 900f9c3b242f60d1672f3554cd6af5017f5f190b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 14:40:16 +0200 Subject: [PATCH 2702/4498] logging: log_frontend: Add optional API for common messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend frontend API with optional set of functions which can be used when simplified log message handling is enabled. If this mode is enabled then there are dedicated macros for processing the most common messages (string + 0-2 word arguments). Using this API can speed up the processing of messages that are the most common. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_frontend.h | 48 +++++++++- subsys/logging/Kconfig.mode | 6 ++ subsys/logging/log_msg.c | 129 +++++++++++++++----------- 3 files changed, 128 insertions(+), 55 deletions(-) diff --git a/include/zephyr/logging/log_frontend.h b/include/zephyr/logging/log_frontend.h index 058afa1f576..132a78eb748 100644 --- a/include/zephyr/logging/log_frontend.h +++ b/include/zephyr/logging/log_frontend.h @@ -12,7 +12,7 @@ */ void log_frontend_init(void); -/** @brief Log message. +/** @brief Log generic message. * * Message details does not contain timestamp. Since function is called in the * context of log message call, implementation can use its own timestamping scheme. @@ -32,6 +32,52 @@ void log_frontend_msg(const void *source, const struct log_msg_desc desc, uint8_t *package, const void *data); +/** @brief Log message with 0 arguments. + * + * Optimized version for log message which does not have arguments (only string). + * This API is optional and is used only if optimizing common log messages is enabled. + * + * @param source Pointer to a structure associated with given source. It points to + * static structure or dynamic structure if runtime filtering is enabled. + * @ref log_const_source_id or @ref log_dynamic_source_id can be used to determine + * source id. + * @param level Severity level. + * @param fmt String. + */ +void log_frontend_simple_0(const void *source, uint32_t level, const char *fmt); + +/** @brief Log message with 1 argument. + * + * Optimized version for log message which has one argument that fits in a 32 bit word. + * This API is optional and is used only if optimizing common log messages is enabled. + * + * @param source Pointer to a structure associated with given source. It points to + * static structure or dynamic structure if runtime filtering is enabled. + * @ref log_const_source_id or @ref log_dynamic_source_id can be used to determine + * source id. + * @param level Severity level. + * @param fmt String. + * @param arg Argument passed to the string. + */ +void log_frontend_simple_1(const void *source, uint32_t level, const char *fmt, uint32_t arg); + +/** @brief Log message with 2 arguments. + * + * Optimized version for log message which has two arguments that fit in a 32 bit word. + * This API is optional and is used only if optimizing common log messages is enabled. + * + * @param source Pointer to a structure associated with given source. It points to + * static structure or dynamic structure if runtime filtering is enabled. + * @ref log_const_source_id or @ref log_dynamic_source_id can be used to determine + * source id. + * @param level Severity level. + * @param fmt String. + * @param arg0 First argument passed to the string. + * @param arg1 Second argument passed to the string. + */ +void log_frontend_simple_2(const void *source, uint32_t level, + const char *fmt, uint32_t arg0, uint32_t arg1); + /** @brief Panic state notification. */ void log_frontend_panic(void); diff --git a/subsys/logging/Kconfig.mode b/subsys/logging/Kconfig.mode index 93758b81fb6..61c304ad0b5 100644 --- a/subsys/logging/Kconfig.mode +++ b/subsys/logging/Kconfig.mode @@ -53,6 +53,12 @@ config LOG_FRONTEND_ONLY Option indicates that there are no backends intended to be used. Code asserts if any backend is enabled. +config LOG_FRONTEND_OPT_API + bool "Frontend optimized API" + help + When enabled, frontend implements functions which are optimized versions + used for the most common log messages. + config LOG_CUSTOM_HEADER bool "Include Custom Log Header" help diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 528f0d8a726..69388f6b5e4 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -97,23 +97,30 @@ void z_impl_z_log_msg_simple_create_0(const void *source, uint32_t level, const { if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { - uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 1; - union cbprintf_package_hdr hdr = { - .desc = { - .len = plen32 - } - }; - uint32_t package[] = { - (uint32_t)(uintptr_t)hdr.raw, - (uint32_t)(uintptr_t)fmt, - }; - struct log_msg_desc desc = { - .level = level, - .package_len = plen32 * sizeof(uint32_t), - .data_len = 0, - }; - - log_frontend_msg(source, desc, (uint8_t *)package, NULL); + if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) { + log_frontend_simple_0(source, level, fmt); + } else { + /* If frontend does not support optimized API prepare data for + * the generic call. + */ + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 1; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + (uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } } if (!BACKENDS_IN_USE()) { @@ -129,24 +136,31 @@ void z_impl_z_log_msg_simple_create_1(const void *source, uint32_t level, const char *fmt, uint32_t arg) { if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { - uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 2; - union cbprintf_package_hdr hdr = { - .desc = { - .len = plen32 - } - }; - uint32_t package[] = { - (uint32_t)(uintptr_t)hdr.raw, - (uint32_t)(uintptr_t)fmt, - arg - }; - struct log_msg_desc desc = { - .level = level, - .package_len = plen32 * sizeof(uint32_t), - .data_len = 0, - }; - - log_frontend_msg(source, desc, (uint8_t *)package, NULL); + if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) { + log_frontend_simple_1(source, level, fmt, arg); + } else { + /* If frontend does not support optimized API prepare data for + * the generic call. + */ + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 2; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + (uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + arg + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } } if (!BACKENDS_IN_USE()) { @@ -162,25 +176,32 @@ void z_impl_z_log_msg_simple_create_2(const void *source, uint32_t level, const char *fmt, uint32_t arg0, uint32_t arg1) { if (IS_ENABLED(CONFIG_LOG_FRONTEND)) { - uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 3; - union cbprintf_package_hdr hdr = { - .desc = { - .len = plen32 - } - }; - uint32_t package[] = { - [0](uint32_t)(uintptr_t)hdr.raw, - (uint32_t)(uintptr_t)fmt, - arg0, - arg1 - }; - struct log_msg_desc desc = { - .level = level, - .package_len = plen32 * sizeof(uint32_t), - .data_len = 0, - }; - - log_frontend_msg(source, desc, (uint8_t *)package, NULL); + if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) { + log_frontend_simple_2(source, level, fmt, arg0, arg1); + } else { + /* If frontend does not support optimized API prepare data for + * the generic call. + */ + uint32_t plen32 = CBPRINTF_DESC_SIZE32 + 3; + union cbprintf_package_hdr hdr = { + .desc = { + .len = plen32 + } + }; + uint32_t package[] = { + [0](uint32_t)(uintptr_t)hdr.raw, + (uint32_t)(uintptr_t)fmt, + arg0, + arg1 + }; + struct log_msg_desc desc = { + .level = level, + .package_len = plen32 * sizeof(uint32_t), + .data_len = 0, + }; + + log_frontend_msg(source, desc, (uint8_t *)package, NULL); + } } if (!BACKENDS_IN_USE()) { From 182555b3df2c60c5d16e76415c8e2ad6b3c73c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 15:08:55 +0200 Subject: [PATCH 2703/4498] sys: cbprintf: Add macro for determining if argument fit in 32 bit word MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Z_CBPRINTF_IS_WORD_NUM(x) which determines if argument is a number that can fit in 32 bit word. It is used by logging macros optimized for handling strings with numeric arguments. Signed-off-by: Krzysztof Chruściński --- include/zephyr/sys/cbprintf_cxx.h | 51 ++++++++++++++++++++++++++ include/zephyr/sys/cbprintf_internal.h | 25 +++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/zephyr/sys/cbprintf_cxx.h b/include/zephyr/sys/cbprintf_cxx.h index a1e8c963285..3b65b229517 100644 --- a/include/zephyr/sys/cbprintf_cxx.h +++ b/include/zephyr/sys/cbprintf_cxx.h @@ -88,6 +88,57 @@ static inline int z_cbprintf_cxx_is_pchar(T arg, bool const_as_fixed) _Pragma("GCC diagnostic pop") } +/* C++ version for determining if variable type is numeric and fits in 32 bit word. */ +static inline int z_cbprintf_cxx_is_word_num(char) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(unsigned char) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(short) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(unsigned short) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(int) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(unsigned int) +{ + return 1; +} + +static inline int z_cbprintf_cxx_is_word_num(long) +{ + return (sizeof(long) <= sizeof(uint32_t)) ? 1 : 0; +} + +static inline int z_cbprintf_cxx_is_word_num(unsigned long) +{ + return (sizeof(long) <= sizeof(uint32_t)) ? 1 : 0; +} + +template < typename T > +static inline int z_cbprintf_cxx_is_word_num(T arg) +{ + ARG_UNUSED(arg); + _Pragma("GCC diagnostic push") + _Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") + return 0; + _Pragma("GCC diagnostic pop") +} + /* C++ version for calculating argument size. */ static inline size_t z_cbprintf_cxx_arg_size(float f) { diff --git a/include/zephyr/sys/cbprintf_internal.h b/include/zephyr/sys/cbprintf_internal.h index 61bd250a30c..eed2bbc3944 100644 --- a/include/zephyr/sys/cbprintf_internal.h +++ b/include/zephyr/sys/cbprintf_internal.h @@ -113,6 +113,31 @@ extern "C" { 0) #endif +/** @brief Check if argument fits in 32 bit word. + * + * @param x Input argument. + * + * @retval 1 if variable is of type that fits in 32 bit word. + * @retval 0 if variable is of different type. + */ +#ifdef __cplusplus +#define Z_CBPRINTF_IS_WORD_NUM(x) \ + z_cbprintf_cxx_is_word_num(x) +#else +#define Z_CBPRINTF_IS_WORD_NUM(x) \ + _Generic(x, \ + char : 1, \ + unsigned char : 1, \ + short : 1, \ + unsigned short : 1, \ + int : 1, \ + unsigned int : 1, \ + long : sizeof(long) <= 4, \ + unsigned long : sizeof(long) <= 4, \ + default : \ + 0) +#endif + /* @brief Check if argument is a certain type of char pointer. What exectly is checked * depends on @p flags. If flags is 0 then 1 is returned if @p x is a char pointer. * From a68cdb0558a4d369316a24c931ed1eff29f0cda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 15:14:50 +0200 Subject: [PATCH 2704/4498] logging: Optimize handling of simple and common log messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some compilers (e.g. riscv32) does not handle well complex macros for logging. Generated code is bigger than expected (e.g. riscv32 code is almost twice bigger than cortex-m code). Use of logging can lead to unexpected code increase. To handle that an analysis of the zephyr code base was performed and it shown that 75-80% of logs are simple strings with 0 arguments (~45%), one 32 bit argument (~26%) or two 32 bit arguments (~6%). Given that a set of dedicated macro were created which are applied to those 3 cases which on 32 bit platform create very simple log messages without padding or alignment needed. Such dedicated macros save up to 40% of code (riscv32) and also executes 30% faster (arm cortex and riscv32). Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_core.h | 2 +- include/zephyr/logging/log_msg.h | 113 +++++++++++++++++++++++++++++- subsys/logging/Kconfig.misc | 10 +++ subsys/logging/log_msg.c | 5 ++ 4 files changed, 128 insertions(+), 2 deletions(-) diff --git a/include/zephyr/logging/log_core.h b/include/zephyr/logging/log_core.h index 58ab5445d81..bc4cb2d8f36 100644 --- a/include/zephyr/logging/log_core.h +++ b/include/zephyr/logging/log_core.h @@ -413,7 +413,7 @@ TYPE_SECTION_END_EXTERN(struct log_source_const_data, log_const); z_log_printf_arg_checker(__VA_ARGS__); \ } \ Z_LOG_MSG_CREATE(!IS_ENABLED(CONFIG_USERSPACE), _mode, \ - Z_LOG_LOCAL_DOMAIN_ID, (uintptr_t)_is_raw, \ + Z_LOG_LOCAL_DOMAIN_ID, (const void *)(uintptr_t)_is_raw, \ LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0, __VA_ARGS__);\ } while (0) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index 95b4dc6e5b9..432442f0429 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -83,7 +83,6 @@ struct log_msg_hdr { void *tid; #endif }; - /* Messages are aligned to alignment required by cbprintf package. */ #define Z_LOG_MSG_ALIGNMENT CBPRINTF_PACKAGE_ALIGNMENT @@ -141,6 +140,9 @@ enum z_log_msg_mode { * more code size. */ Z_LOG_MSG_MODE_ZERO_COPY, + + /* Mode optimized for simple messages with 0 to 2 32 bit word arguments.*/ + Z_LOG_MSG_MODE_SIMPLE, }; #define Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, _plen, _dlen) \ @@ -227,6 +229,102 @@ enum z_log_msg_mode { #define Z_LOG_ARM64_VLA_PROTECT() compiler_barrier() +#define _LOG_MSG_SIMPLE_XXXX0 1 +#define _LOG_MSG_SIMPLE_XXXX1 1 +#define _LOG_MSG_SIMPLE_XXXX2 1 + +/* Determine if amount of arguments (less than 3) qualifies to simple message. */ +#define LOG_MSG_SIMPLE_ARG_CNT_CHECK(...) \ + COND_CODE_1(UTIL_CAT(_LOG_MSG_SIMPLE_XXXX, NUM_VA_ARGS_LESS_1(__VA_ARGS__)), (1), (0)) + +/* Set of marcos used to determine if arguments type allows simplified message creation mode. */ +#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_0(fmt) 1 +#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_1(fmt, arg) Z_CBPRINTF_IS_WORD_NUM(arg) +#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_2(fmt, arg0, arg1) \ + Z_CBPRINTF_IS_WORD_NUM(arg0) || Z_CBPRINTF_IS_WORD_NUM(arg1) + +/** brief Determine if string arguments types allow to use simplified message creation mode. + * + * @param ... String with arguments. + */ +#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK(...) \ + UTIL_CAT(LOG_MSG_SIMPLE_ARG_TYPE_CHECK_, NUM_VA_ARGS_LESS_1(__VA_ARGS__))(__VA_ARGS__) + +/** @brief Check if message can be handled using simplified method. + * + * Following conditions must be met: + * - 32 bit platform + * - Number of arguments from 0 to 2 + * - Type of an argument must be a numeric value that fits in 32 bit word. + * + * @param ... String with arguments. + * + * @retval 1 if message qualifies. + * @retval 0 if message does not qualify. + */ +#define LOG_MSG_SIMPLE_CHECK(...) \ + COND_CODE_1(CONFIG_64BIT, (0), (\ + COND_CODE_1(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), ( \ + LOG_MSG_SIMPLE_ARG_TYPE_CHECK(__VA_ARGS__)), (0)))) + +/* Helper macro for handing log with one argument. Macro casts the first argument to uint32_t. */ +#define Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, ...) \ + z_log_msg_simple_create_1(_source, _level, GET_ARG_N(1, __VA_ARGS__), \ + (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__)) + +/* Helper macro for handing log with two arguments. Macro casts arguments to uint32_t. + */ +#define Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, ...) \ + z_log_msg_simple_create_2(_source, _level, GET_ARG_N(1, __VA_ARGS__), \ + (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__), \ + (uint32_t)(uintptr_t)GET_ARG_N(3, __VA_ARGS__)) + +/* Call specific function based on the number of arguments. + * Since up 2 to arguments are supported COND_CODE_0 and COND_CODE_1 can be used to + * handle all cases (0, 1 and 2 arguments). When tracing is enable then for each + * function a macro is create. The difference between function and macro is that + * macro is applied to any input arguments so we need to make sure that it is + * always called with proper number of arguments. For that it is wrapped around + * into another macro and dummy arguments to cover for cases when there is less + * arguments in a log call. + */ +#define Z_LOG_MSG_SIMPLE_FUNC2(arg_cnt, _source, _level, ...) \ + COND_CODE_0(arg_cnt, \ + (z_log_msg_simple_create_0(_source, _level, GET_ARG_N(1, __VA_ARGS__))), \ + (COND_CODE_1(arg_cnt, ( \ + Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, __VA_ARGS__, dummy) \ + ), ( \ + Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, __VA_ARGS__, dummy, dummy) \ + ) \ + ))) + +/** @brief Call specific function to create a log message. + * + * Macro picks matching function (based on number of arguments) and calls it. + * String arguments are casted to uint32_t. + * + * @param _source Source. + * @param _level Severity level. + * @param ... String with arguments. + */ +#define LOG_MSG_SIMPLE_FUNC(_source, _level, ...) \ + Z_LOG_MSG_SIMPLE_FUNC2(NUM_VA_ARGS_LESS_1(__VA_ARGS__), _source, _level, __VA_ARGS__) + +/** @brief Create log message using simplified method. + * + * Macro is gated by the argument count check to run @ref LOG_MSG_SIMPLE_FUNC only + * on entries with 2 or less arguments. + * + * @param _domain_id Domain ID. + * @param _source Pointer to the source structure. + * @param _level Severity level. + * @param ... String with arguments. + */ +#define Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, ...) \ + IF_ENABLED(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), (\ + LOG_MSG_SIMPLE_FUNC(_source, _level, __VA_ARGS__); \ + )) + #define Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, _dlen, ...) \ do { \ int _plen; \ @@ -430,6 +528,19 @@ do { \ _level, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \ _mode = Z_LOG_MSG_MODE_ZERO_COPY; \ } else { \ + IF_ENABLED(UTIL_AND(IS_ENABLED(CONFIG_LOG_SIMPLE_MSG_OPTIMIZE), \ + UTIL_AND(UTIL_NOT(_domain_id), UTIL_NOT(_cstr_cnt))), \ + ( \ + bool can_simple = LOG_MSG_SIMPLE_CHECK(__VA_ARGS__); \ + if (can_simple && ((_dlen) == 0)) { \ + LOG_MSG_DBG("create fast message\n");\ + Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, \ + Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \ + _mode = Z_LOG_MSG_MODE_SIMPLE; \ + break; \ + } \ + ) \ + ) \ LOG_MSG_DBG("create on stack message\n");\ Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, \ _dlen, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \ diff --git a/subsys/logging/Kconfig.misc b/subsys/logging/Kconfig.misc index d425f9b628b..74b629f54ae 100644 --- a/subsys/logging/Kconfig.misc +++ b/subsys/logging/Kconfig.misc @@ -33,6 +33,16 @@ config LOG_USE_VLA supported. Note that VLA are used for arrays which size is resolved at compile time so at runtime arrays have fixed size. +config LOG_SIMPLE_MSG_OPTIMIZE + bool "Optimize simple messages for size" + depends on !64BIT && !CBPRINTF_PACKAGE_HEADER_STORE_CREATION_FLAGS + default y + help + Dedicated code for handling simple log messages (0-2 32 bit word arguments). + Approximately, 70%-80% log messages in the application fit into that category. + Depending on the architecture code size reduction is from 0-40% (highest seen on + RISCV32) and execution time also up to 40%. + config LOG_ALWAYS_RUNTIME bool "Always use runtime message creation (v2)" default y if NO_OPTIMIZATIONS diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 69388f6b5e4..891fc2ef898 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -22,6 +22,11 @@ BUILD_ASSERT(sizeof(struct log_msg_desc) == sizeof(uint32_t), #define CBPRINTF_DESC_SIZE32 (sizeof(struct cbprintf_package_desc) / sizeof(uint32_t)) +/* For simplified message handling cprintf package must have only 1 word. */ +BUILD_ASSERT(!IS_ENABLED(CONFIG_LOG_SIMPLE_MSG_OPTIMIZE) || + (IS_ENABLED(CONFIG_LOG_SIMPLE_MSG_OPTIMIZE) && (CBPRINTF_DESC_SIZE32 == 1))); + + void z_log_msg_finalize(struct log_msg *msg, const void *source, const struct log_msg_desc desc, const void *data) { From 503422b91e7bb3826231cea55602c7efe47ed4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 19 Oct 2023 15:54:42 +0200 Subject: [PATCH 2705/4498] doc: logging: Add new Kconfig options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CONFIG_LOG_SIMPLE_MSG_OPTIMIZE and CONFIG_LOG_FRONTEND_OPT_API Signed-off-by: Krzysztof Chruściński --- doc/services/logging/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/services/logging/index.rst b/doc/services/logging/index.rst index 8201e728b9a..2b9fe9a707a 100644 --- a/doc/services/logging/index.rst +++ b/doc/services/logging/index.rst @@ -142,10 +142,16 @@ packet buffer. :kconfig:option:`CONFIG_LOG_FRONTEND_ONLY`: No backends are used when messages goes to frontend. +:kconfig:option:`CONFIG_LOG_FRONTEND_OPT_API`: Optional API optimized for the most common +simple messages. + :kconfig:option:`CONFIG_LOG_CUSTOM_HEADER`: Injects an application provided header into log.h :kconfig:option:`CONFIG_LOG_TIMESTAMP_64BIT`: 64 bit timestamp. +:kconfig:option:`CONFIG_LOG_SIMPLE_MSG_OPTIMIZE`: Optimizes simple log messages for size +and performance. Option available only for 32 bit architectures. + Formatting options: :kconfig:option:`CONFIG_LOG_FUNC_NAME_PREFIX_ERR`: Prepend standard ERROR log messages From e9ecc83eea5c5d1d52d2dc7d3f8803c04657db24 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Mon, 16 Oct 2023 18:26:37 +0530 Subject: [PATCH 2706/4498] drivers: rtc: new maxim ds1307 rtc driver Added rtc driver for ds1307. It allows to read and set the date and time Signed-off-by: Arunmani Alagarsamy --- drivers/rtc/CMakeLists.txt | 1 + drivers/rtc/Kconfig | 1 + drivers/rtc/Kconfig.ds1307 | 11 ++ drivers/rtc/rtc_ds1307.c | 160 +++++++++++++++++++++++++++++ dts/bindings/rtc/maxim,ds1307.yaml | 11 ++ 5 files changed, 184 insertions(+) create mode 100644 drivers/rtc/Kconfig.ds1307 create mode 100644 drivers/rtc/rtc_ds1307.c create mode 100644 dts/bindings/rtc/maxim,ds1307.yaml diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index 5addee4faed..65d822dbe6e 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/rtc.h) zephyr_library() zephyr_library_sources_ifdef(CONFIG_RTC_AM1805 rtc_am1805.c) +zephyr_library_sources_ifdef(CONFIG_RTC_DS1307 rtc_ds1307.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE rtc_handlers.c) zephyr_library_sources_ifdef(CONFIG_RTC_EMUL rtc_emul.c) zephyr_library_sources_ifdef(CONFIG_RTC_PCF8523 rtc_pcf8523.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f9da0c293d7..10b228ceeab 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -42,6 +42,7 @@ config RTC_SHELL RTC Shell commands source "drivers/rtc/Kconfig.am1805" +source "drivers/rtc/Kconfig.ds1307" source "drivers/rtc/Kconfig.emul" source "drivers/rtc/Kconfig.fake" source "drivers/rtc/Kconfig.pcf8523" diff --git a/drivers/rtc/Kconfig.ds1307 b/drivers/rtc/Kconfig.ds1307 new file mode 100644 index 00000000000..b350846f58e --- /dev/null +++ b/drivers/rtc/Kconfig.ds1307 @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Arunmani Alagarsamy +# Author: Arunmani Alagarsamy + +config RTC_DS1307 + bool "MAXIM DS1307 RTC driver" + default y + depends on DT_HAS_MAXIM_DS1307_ENABLED + select I2C + help + Enable the MAXIM DS1307 RTC driver. diff --git a/drivers/rtc/rtc_ds1307.c b/drivers/rtc/rtc_ds1307.c new file mode 100644 index 00000000000..bfbe0abe255 --- /dev/null +++ b/drivers/rtc/rtc_ds1307.c @@ -0,0 +1,160 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Arunmani Alagarsamy + * Author: Arunmani Alagarsamy + */ + +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT maxim_ds1307 + +LOG_MODULE_REGISTER(ds1307, CONFIG_RTC_LOG_LEVEL); + +/* DS1307 registers */ +#define DS1307_REG_SECONDS 0x00 +#define DS1307_REG_MINUTES 0x01 +#define DS1307_REG_HOURS 0x02 +#define DS1307_REG_DAY 0x03 +#define DS1307_REG_DATE 0x04 +#define DS1307_REG_MONTH 0x05 +#define DS1307_REG_YEAR 0x06 +#define DS1307_REG_CTRL 0x07 + +#define SECONDS_BITS GENMASK(6, 0) +#define MINUTES_BITS GENMASK(7, 0) +#define HOURS_BITS GENMASK(5, 0) +#define DATE_BITS GENMASK(5, 0) +#define MONTHS_BITS GENMASK(4, 0) +#define WEEKDAY_BITS GENMASK(2, 0) +#define YEAR_BITS GENMASK(7, 0) +#define VALIDATE_24HR BIT(6) + +struct ds1307_config { + struct i2c_dt_spec i2c_bus; +}; + +struct ds1307_data { + struct k_spinlock lock; +}; + +static int ds1307_set_time(const struct device *dev, const struct rtc_time *tm) +{ + int err; + uint8_t regs[7]; + + struct ds1307_data *data = dev->data; + const struct ds1307_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + LOG_DBG("set time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + regs[0] = bin2bcd(tm->tm_sec) & SECONDS_BITS; + regs[1] = bin2bcd(tm->tm_min); + regs[2] = bin2bcd(tm->tm_hour); + regs[3] = bin2bcd(tm->tm_wday); + regs[4] = bin2bcd(tm->tm_mday); + regs[5] = bin2bcd(tm->tm_mon); + regs[6] = bin2bcd((tm->tm_year % 100)); + + err = i2c_burst_write_dt(&config->i2c_bus, DS1307_REG_SECONDS, regs, sizeof(regs)); + + k_spin_unlock(&data->lock, key); + + return err; +} + +static int ds1307_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + int err; + uint8_t regs[7]; + + struct ds1307_data *data = dev->data; + const struct ds1307_config *config = dev->config; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + err = i2c_burst_read_dt(&config->i2c_bus, DS1307_REG_SECONDS, regs, sizeof(regs)); + if (err != 0) { + goto unlock; + } + + timeptr->tm_sec = bcd2bin(regs[0] & SECONDS_BITS); + timeptr->tm_min = bcd2bin(regs[1] & MINUTES_BITS); + timeptr->tm_hour = bcd2bin(regs[2] & HOURS_BITS); /* 24hr mode */ + timeptr->tm_wday = bcd2bin(regs[3] & WEEKDAY_BITS); + timeptr->tm_mday = bcd2bin(regs[4] & DATE_BITS); + timeptr->tm_mon = bcd2bin(regs[5] & MONTHS_BITS); + timeptr->tm_year = bcd2bin(regs[6] & YEAR_BITS); + timeptr->tm_year = timeptr->tm_year + 100; + + /* Not used */ + timeptr->tm_nsec = 0; + timeptr->tm_isdst = -1; + timeptr->tm_yday = -1; + + /* Validate the chip in 24hr mode */ + if (regs[2] & VALIDATE_24HR) { + err = -ENODATA; + goto unlock; + } + + LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + +unlock: + k_spin_unlock(&data->lock, key); + + return err; +} + +static const struct rtc_driver_api ds1307_driver_api = { + .set_time = ds1307_set_time, + .get_time = ds1307_get_time, +}; + +static int ds1307_init(const struct device *dev) +{ + int err; + const struct ds1307_config *config = dev->config; + + if (!i2c_is_ready_dt(&config->i2c_bus)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + /* Disable squarewave output */ + err = i2c_reg_write_byte_dt(&config->i2c_bus, DS1307_REG_CTRL, 0x00); + if (err < 0) { + LOG_ERR("Error: SQW:%d\n", err); + } + + /* Make clock halt = 0 */ + err = i2c_reg_write_byte_dt(&config->i2c_bus, DS1307_REG_SECONDS, 0x00); + if (err < 0) { + LOG_ERR("Error: Set clock halt bit:%d\n", err); + } + + return 0; +} + +#define DS1307_DEFINE(inst) \ + static struct ds1307_data ds1307_data_##inst; \ + static const struct ds1307_config ds1307_config_##inst = { \ + .i2c_bus = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &ds1307_init, NULL, &ds1307_data_##inst, \ + &ds1307_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &ds1307_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DS1307_DEFINE) diff --git a/dts/bindings/rtc/maxim,ds1307.yaml b/dts/bindings/rtc/maxim,ds1307.yaml new file mode 100644 index 00000000000..fc81e803cb4 --- /dev/null +++ b/dts/bindings/rtc/maxim,ds1307.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 Arunmani Alagarsamy +# Author: Arunmani Alagarsamy + +description: Maxim DS1307 RTC + +compatible: "maxim,ds1307" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml From d05e274735d50bffebc157a298336dac3c365c4c Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Mon, 23 Oct 2023 18:05:16 +0800 Subject: [PATCH 2707/4498] test: test_mcuboot: enable test on NXP MCUX platforms NXP MCUX has no issue with #58080, so enable tests for NXP Signed-off-by: Hake Huang --- tests/boot/test_mcuboot/testcase.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/boot/test_mcuboot/testcase.yaml b/tests/boot/test_mcuboot/testcase.yaml index 91b5919759e..c5622139386 100644 --- a/tests/boot/test_mcuboot/testcase.yaml +++ b/tests/boot/test_mcuboot/testcase.yaml @@ -12,10 +12,17 @@ common: tests: bootloader.mcuboot: tags: mcuboot - skip: true # disabled due to issue #58080 platform_allow: - frdm_k64f + - mimxrt1020_evk + - mimxrt1024_evk + - mimxrt1050_evk - mimxrt1060_evk + - mimxrt1064_evk + - mimxrt1160_evk_cm7 + - mimxrt1170_evk_cm7 + - mimxrt595_evk_cm33 + - mimxrt685_evk_cm33 - nrf52840dk_nrf52840 integration_platforms: - frdm_k64f From 9e404d12d07a715b5ce4c4ba11156436ff32124b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 24 Oct 2023 14:09:07 -0700 Subject: [PATCH 2708/4498] intc: intc_loapic: Remove unnecessary header is being included twice. Remove one of them. Signed-off-by: Flavio Ceolin --- drivers/interrupt_controller/intc_loapic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/interrupt_controller/intc_loapic.c b/drivers/interrupt_controller/intc_loapic.c index 742ae530596..c7faaa39cdb 100644 --- a/drivers/interrupt_controller/intc_loapic.c +++ b/drivers/interrupt_controller/intc_loapic.c @@ -65,7 +65,6 @@ #define LOAPIC_SSPND_BITS_PER_IRQ 1 /* Just the one for enable disable*/ #define LOAPIC_SUSPEND_BITS_REQD (ROUND_UP((LOAPIC_IRQ_COUNT * LOAPIC_SSPND_BITS_PER_IRQ), 32)) #ifdef CONFIG_PM_DEVICE -#include __pinned_bss uint32_t loapic_suspend_buf[LOAPIC_SUSPEND_BITS_REQD / 32] = {0}; #endif From 78274416818b282032242422ff21f63d2784a69c Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 24 Oct 2023 14:21:12 -0700 Subject: [PATCH 2709/4498] intc: intc_ioapic: Remove unnecessary header is being included twice. Remove one of them. Signed-off-by: Flavio Ceolin --- drivers/interrupt_controller/intc_ioapic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/interrupt_controller/intc_ioapic.c b/drivers/interrupt_controller/intc_ioapic.c index 41a6266a699..22e9ecaf374 100644 --- a/drivers/interrupt_controller/intc_ioapic.c +++ b/drivers/interrupt_controller/intc_ioapic.c @@ -89,7 +89,6 @@ DEVICE_MMIO_TOPLEVEL_STATIC(ioapic_regs, DT_DRV_INST(0)); static __pinned_bss uint32_t ioapic_rtes; #ifdef CONFIG_PM_DEVICE -#include #define BITS_PER_IRQ 4 #define IOAPIC_BITFIELD_HI_LO 0 From 76cb2a54f51f3507108c317c9b52d67fd51f71b1 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 24 Oct 2023 14:22:15 -0700 Subject: [PATCH 2710/4498] intel_adsp: Do not include device_runtime header Device runtime header is not needed in intel_adsp_ipc header. Signed-off-by: Flavio Ceolin --- soc/xtensa/intel_adsp/common/include/intel_adsp_ipc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/soc/xtensa/intel_adsp/common/include/intel_adsp_ipc.h b/soc/xtensa/intel_adsp/common/include/intel_adsp_ipc.h index 2bca8c9c5b8..ca1ddfb573b 100644 --- a/soc/xtensa/intel_adsp/common/include/intel_adsp_ipc.h +++ b/soc/xtensa/intel_adsp/common/include/intel_adsp_ipc.h @@ -7,10 +7,7 @@ #include #include #include -#ifdef CONFIG_PM_DEVICE_RUNTIME #include -#include -#endif struct intel_adsp_ipc_config { volatile struct intel_adsp_ipc *regs; From ca19b407335048328102b4a73b3fb2fa122358dc Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Tue, 24 Oct 2023 16:18:02 -0700 Subject: [PATCH 2711/4498] soc: arm: nxp_imx: rt5xx: make some clock init functions weak Allows a board to provide their own functions if they wish to init clocks differently. Signed-off-by: Mike J. Chen --- soc/arm/nxp_imx/rt5xx/soc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/soc/arm/nxp_imx/rt5xx/soc.c b/soc/arm/nxp_imx/rt5xx/soc.c index c216f63890d..72684393959 100644 --- a/soc/arm/nxp_imx/rt5xx/soc.c +++ b/soc/arm/nxp_imx/rt5xx/soc.c @@ -216,7 +216,8 @@ void z_arm_platform_init(void) SystemInit(); } -static void clock_init(void) +/* Weak so that board can override with their own clock init routine. */ +void __weak rt5xx_clock_init(void) { /* Configure LPOSC 1M */ /* Power on LPOSC (1MHz) */ @@ -426,7 +427,8 @@ static void clock_init(void) } #if CONFIG_MIPI_DSI -void imxrt_pre_init_display_interface(void) +/* Weak so board can override this function */ +void __weak imxrt_pre_init_display_interface(void) { /* Assert MIPI DPHY reset. */ RESET_SetPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn); @@ -462,7 +464,7 @@ void imxrt_pre_init_display_interface(void) RESET_ClearPeripheralReset(kMIPI_DSI_CTRL_RST_SHIFT_RSTn); } -void imxrt_post_init_display_interface(void) +void __weak imxrt_post_init_display_interface(void) { /* Deassert MIPI DPHY reset. */ RESET_ClearPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn); @@ -481,7 +483,7 @@ void imxrt_post_init_display_interface(void) static int nxp_rt500_init(void) { /* Initialize clocks with tool generated code */ - clock_init(); + rt5xx_clock_init(); #ifndef CONFIG_IMXRT5XX_CODE_CACHE CACHE64_DisableCache(CACHE64_CTRL0); From ee7e6d47d1e50fd3d76416488de62929c730bb88 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 12:27:07 +0200 Subject: [PATCH 2712/4498] samples logger multidomain: Convert to sysbuild Convert this sample application build to sysbuild. Signed-off-by: Alberto Escolar Piedras --- .../subsys/logging/multidomain/CMakeLists.txt | 18 ++---------------- .../logging/multidomain/Kconfig.sysbuild | 9 +++++++++ samples/subsys/logging/multidomain/sample.yaml | 2 ++ .../subsys/logging/multidomain/sysbuild.cmake | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 samples/subsys/logging/multidomain/Kconfig.sysbuild create mode 100644 samples/subsys/logging/multidomain/sysbuild.cmake diff --git a/samples/subsys/logging/multidomain/CMakeLists.txt b/samples/subsys/logging/multidomain/CMakeLists.txt index 378ff66c7d8..30a375cb764 100644 --- a/samples/subsys/logging/multidomain/CMakeLists.txt +++ b/samples/subsys/logging/multidomain/CMakeLists.txt @@ -6,15 +6,12 @@ cmake_minimum_required(VERSION 3.20.0) -set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/log_multidomain_remote-prefix/src/log_multidomain_remote-build/zephyr) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") - set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") -else() +if(NOT("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp")) message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(log_multidomain) target_sources(app PRIVATE src/main.c) @@ -22,14 +19,3 @@ target_sources(app PRIVATE src/main.c) if (CONFIG_IPC_SERVICE) target_sources(app PRIVATE src/ipc_service.c) endif() - -include(ExternalProject) - -ExternalProject_Add( - log_multidomain_remote - SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote - INSTALL_COMMAND "" # This particular build system has no install command - CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} - BUILD_BYPRODUCTS "${REMOTE_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" - BUILD_ALWAYS True -) diff --git a/samples/subsys/logging/multidomain/Kconfig.sysbuild b/samples/subsys/logging/multidomain/Kconfig.sysbuild new file mode 100644 index 00000000000..47884745130 --- /dev/null +++ b/samples/subsys/logging/multidomain/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD +string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" diff --git a/samples/subsys/logging/multidomain/sample.yaml b/samples/subsys/logging/multidomain/sample.yaml index 737a44ffded..fed97773b0f 100644 --- a/samples/subsys/logging/multidomain/sample.yaml +++ b/samples/subsys/logging/multidomain/sample.yaml @@ -1,5 +1,7 @@ sample: name: Logging in multi-domain environment +common: + sysbuild: true tests: sample.logging.multidomain.ipc_static_vrings: platform_allow: nrf5340dk_nrf5340_cpuapp diff --git a/samples/subsys/logging/multidomain/sysbuild.cmake b/samples/subsys/logging/multidomain/sysbuild.cmake new file mode 100644 index 00000000000..d0d79b8f240 --- /dev/null +++ b/samples/subsys/logging/multidomain/sysbuild.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") + message(FATAL_ERROR + "Target ${BOARD} not supported for this sample. " + "There is no remote board selected in Kconfig.sysbuild") +endif() + +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_NET_CORE_BOARD} +) From b9023d38857486ee89e15e71c44b260d6187a4ef Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 12:34:43 +0200 Subject: [PATCH 2713/4498] samples logger multidomain: Add support for nrf5340bsim Add support for this sample on the simulated nrf5340 Signed-off-by: Alberto Escolar Piedras --- .../subsys/logging/multidomain/CMakeLists.txt | 3 +- .../logging/multidomain/Kconfig.sysbuild | 1 + .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 4 +++ .../boards/nrf5340bsim_nrf5340_cpuapp.overlay | 7 +++++ .../boards/nrf5340bsim_nrf5340_cpunet.conf | 5 ++++ .../boards/nrf5340bsim_nrf5340_cpunet.overlay | 7 +++++ .../boards/nrf5340dk_nrf5340_cpunet.conf | 1 + .../logging/multidomain/remote/prj.conf | 1 - .../subsys/logging/multidomain/sample.yaml | 4 ++- .../subsys/logging/multidomain/sysbuild.cmake | 28 +++++++++++++++++-- 10 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.conf create mode 100644 samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.overlay create mode 100644 samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.conf create mode 100644 samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.overlay diff --git a/samples/subsys/logging/multidomain/CMakeLists.txt b/samples/subsys/logging/multidomain/CMakeLists.txt index 30a375cb764..a0cc842a6a8 100644 --- a/samples/subsys/logging/multidomain/CMakeLists.txt +++ b/samples/subsys/logging/multidomain/CMakeLists.txt @@ -8,7 +8,8 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -if(NOT("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp")) +if(NOT(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") + OR ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp"))) message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() diff --git a/samples/subsys/logging/multidomain/Kconfig.sysbuild b/samples/subsys/logging/multidomain/Kconfig.sysbuild index 47884745130..b6dc3d0a6d0 100644 --- a/samples/subsys/logging/multidomain/Kconfig.sysbuild +++ b/samples/subsys/logging/multidomain/Kconfig.sysbuild @@ -7,3 +7,4 @@ source "share/sysbuild/Kconfig" config NET_CORE_BOARD string default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..f14ca9ebc20 --- /dev/null +++ b/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NRFX_IPC=y +# For the mailbox to be initialized logger initialization is delayed like in real HW +CONFIG_LOG_PROCESS_THREAD=y +CONFIG_LOG_MODE_DEFERRED=y diff --git a/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.overlay b/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..fbcced93153 --- /dev/null +++ b/samples/subsys/logging/multidomain/boards/nrf5340bsim_nrf5340_cpuapp.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf5340dk_nrf5340_cpuapp.overlay" diff --git a/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..2d6de6e7c7c --- /dev/null +++ b/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1,5 @@ +CONFIG_MBOX_NRFX_IPC=y +CONFIG_BUILD_OUTPUT_EXE=n +# For the mailbox to be initialized logger initialization is delayed like in real HW +CONFIG_LOG_PROCESS_THREAD=y +CONFIG_LOG_MODE_DEFERRED=y diff --git a/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.overlay b/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.overlay new file mode 100644 index 00000000000..ccb145fa34b --- /dev/null +++ b/samples/subsys/logging/multidomain/remote/boards/nrf5340bsim_nrf5340_cpunet.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf5340dk_nrf5340_cpunet.overlay" diff --git a/samples/subsys/logging/multidomain/remote/boards/nrf5340dk_nrf5340_cpunet.conf b/samples/subsys/logging/multidomain/remote/boards/nrf5340dk_nrf5340_cpunet.conf index a1ab15fae14..cb04b37b233 100644 --- a/samples/subsys/logging/multidomain/remote/boards/nrf5340dk_nrf5340_cpunet.conf +++ b/samples/subsys/logging/multidomain/remote/boards/nrf5340dk_nrf5340_cpunet.conf @@ -1 +1,2 @@ CONFIG_MBOX_NRFX_IPC=y +CONFIG_MPU_STACK_GUARD=y diff --git a/samples/subsys/logging/multidomain/remote/prj.conf b/samples/subsys/logging/multidomain/remote/prj.conf index 65d5bc08f58..11cddd823fb 100644 --- a/samples/subsys/logging/multidomain/remote/prj.conf +++ b/samples/subsys/logging/multidomain/remote/prj.conf @@ -15,6 +15,5 @@ CONFIG_LOG_PRINTK=n CONFIG_LOG_BUFFER_SIZE=4096 CONFIG_ASSERT=y -CONFIG_MPU_STACK_GUARD=y CONFIG_LOG_BACKEND_UART=n CONFIG_LOG_BACKEND_RTT=n diff --git a/samples/subsys/logging/multidomain/sample.yaml b/samples/subsys/logging/multidomain/sample.yaml index fed97773b0f..5070b42e03f 100644 --- a/samples/subsys/logging/multidomain/sample.yaml +++ b/samples/subsys/logging/multidomain/sample.yaml @@ -4,7 +4,9 @@ common: sysbuild: true tests: sample.logging.multidomain.ipc_static_vrings: - platform_allow: nrf5340dk_nrf5340_cpuapp + platform_allow: + - nrf5340dk_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpuapp integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: ipc diff --git a/samples/subsys/logging/multidomain/sysbuild.cmake b/samples/subsys/logging/multidomain/sysbuild.cmake index d0d79b8f240..e50f47b6db1 100644 --- a/samples/subsys/logging/multidomain/sysbuild.cmake +++ b/samples/subsys/logging/multidomain/sysbuild.cmake @@ -7,8 +7,32 @@ if("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "") "There is no remote board selected in Kconfig.sysbuild") endif() +set(NET_APP remote) + ExternalZephyrProject_Add( - APPLICATION remote - SOURCE_DIR ${APP_DIR}/remote + APPLICATION ${NET_APP} + SOURCE_DIR ${APP_DIR}/${NET_APP} BOARD ${SB_CONFIG_NET_CORE_BOARD} ) + +if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + + # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From c6fab4ac77db74b3569b4dbb7d66b43779e9092d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 14:00:13 +0200 Subject: [PATCH 2714/4498] samples logger multidomain: Add run test for simulated target Add a runtest for the simulated target. Signed-off-by: Alberto Escolar Piedras --- .../subsys/logging/multidomain/sample.yaml | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/samples/subsys/logging/multidomain/sample.yaml b/samples/subsys/logging/multidomain/sample.yaml index 5070b42e03f..79523c9951a 100644 --- a/samples/subsys/logging/multidomain/sample.yaml +++ b/samples/subsys/logging/multidomain/sample.yaml @@ -2,12 +2,30 @@ sample: name: Logging in multi-domain environment common: sysbuild: true + tags: ipc tests: - sample.logging.multidomain.ipc_static_vrings: + sample.logging.multidomain.ipc_static_vrings.hw: platform_allow: - nrf5340dk_nrf5340_cpuapp - - nrf5340bsim_nrf5340_cpuapp integration_platforms: - nrf5340dk_nrf5340_cpuapp - tags: ipc build_only: true + sample.logging.multidomain.ipc_static_vrings.simu: + platform_allow: + - nrf5340bsim_nrf5340_cpuapp + integration_platforms: + - nrf5340bsim_nrf5340_cpuapp + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "IPC-service REMOTE \\[INST 1\\] demo started" + - "app: loop: 0" + - "app: ipc open" + - "app: wait for bound" + - "app: bounded" + - "app: REMOTE \\[1\\]: 0" + - "app: HOST \\[1\\]: 1" + - "IPC-service REMOTE \\[INST 1\\] demo ended." + - "app: IPC-service HOST \\[INST 1\\] demo ended." From 23472509d36d45b8938f5f64e48fd9ac6a24a8fa Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 25 Oct 2023 15:19:00 +0200 Subject: [PATCH 2715/4498] llext: refactor section copying Instead of first allocating all sections and then copying then, create a helper function to allocate and copy a single section and call it for all appropriate sections. We need to call this function from another location when copying string sections. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 70 +++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index a6bb7f57801..e7838e7233f 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -236,54 +236,51 @@ static inline enum llext_section llext_sect_from_mem(enum llext_mem m) return s; } -static int llext_allocate_mem(struct llext_loader *ldr, struct llext *ext) +static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, + enum llext_mem mem_idx) { - int ret = 0; - enum llext_section sect_idx; + enum llext_section sect_idx = llext_sect_from_mem(mem_idx); + int ret; - for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { - sect_idx = llext_sect_from_mem(mem_idx); + if (!ldr->sects[sect_idx].sh_size) { + return 0; + } - if (ldr->sects[sect_idx].sh_size > 0) { - ext->mem[mem_idx] = - k_heap_aligned_alloc(&llext_heap, sizeof(uintptr_t), - ldr->sects[sect_idx].sh_size, - K_NO_WAIT); + ext->mem[mem_idx] = k_heap_aligned_alloc(&llext_heap, sizeof(uintptr_t), + ldr->sects[sect_idx].sh_size, + K_NO_WAIT); + if (!ext->mem[mem_idx]) { + return -ENOMEM; + } - if (ext->mem[mem_idx] == NULL) { - ret = -ENOMEM; - goto out; - } - } + ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); + if (ret != 0) { + goto err; } -out: + ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size); + if (ret != 0) { + goto err; + } + + return 0; + +err: + k_heap_free(&llext_heap, ext->mem[mem_idx]); return ret; } static int llext_copy_sections(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; - enum llext_section sect_idx; - for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { - sect_idx = llext_sect_from_mem(mem_idx); - - if (ldr->sects[sect_idx].sh_size > 0) { - ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); - if (ret != 0) { - goto out; - } + int ret = llext_copy_section(ldr, ext, mem_idx); - ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size); - if (ret != 0) { - goto out; - } + if (ret < 0) { + return ret; } } -out: - return ret; + return 0; } static int llext_count_export_syms(struct llext_loader *ldr) @@ -593,14 +590,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) goto out; } - LOG_DBG("Allocation memory for ELF sections..."); - ret = llext_allocate_mem(ldr, ext); - if (ret != 0) { - LOG_ERR("Failed to map memory for ELF sections, ret %d", ret); - goto out; - } - - LOG_DBG("Copying sections..."); + LOG_DBG("Allocate and copy sections..."); ret = llext_copy_sections(ldr, ext); if (ret != 0) { LOG_ERR("Failed to copy ELF sections, ret %d", ret); From 5064df0500f262a0666961ecfc18ca01b770dba5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 25 Oct 2023 15:58:15 +0200 Subject: [PATCH 2716/4498] llext: copy complete string sections while parsing ELF This has several advantages: 1. we don't need any hard assumptions about symbol length. The current hard-coded limit of 32 characters might well be not true. 2. replaces a lot of code for reading those names with a single call to a 1-line function to calculate string location. 3. eliminates the need to allocate buffers for exported symbol names by replacing them with a simple pointer assignment. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 2 + include/zephyr/llext/symbol.h | 2 +- subsys/llext/llext.c | 141 ++++++++++++++-------------------- 3 files changed, 61 insertions(+), 84 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 56ad0eefea5..6afb48682be 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -32,6 +32,8 @@ enum llext_mem { LLEXT_MEM_DATA, LLEXT_MEM_RODATA, LLEXT_MEM_BSS, + LLEXT_MEM_STRTAB, + LLEXT_MEM_SHSTRTAB, LLEXT_MEM_COUNT, }; diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index f4b69ef5010..c7f7b829902 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -44,7 +44,7 @@ struct llext_const_symbol { */ struct llext_symbol { /** Name of symbol */ - char *name; + const char *name; /** Address of symbol */ void *addr; diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index e7838e7233f..b94d6ae1183 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -150,15 +150,21 @@ static int llext_find_tables(struct llext_loader *ldr) return ret; } +static const char *llext_string(struct llext_loader *ldr, struct llext *ext, + enum llext_mem mem_idx, unsigned int idx) +{ + return (char *)ext->mem[mem_idx] + idx; +} + /* * Maps the section indexes and copies special section headers for easier use */ -static int llext_map_sections(struct llext_loader *ldr) +static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) { int ret = 0; size_t pos = ldr->hdr.e_shoff; elf_shdr_t shdr; - char name[32]; + const char *name; for (int i = 0; i < ldr->hdr.e_shnum; i++) { ret = llext_seek(ldr, pos); @@ -173,31 +179,19 @@ static int llext_map_sections(struct llext_loader *ldr) pos += ldr->hdr.e_shentsize; - elf_word str_idx = shdr.sh_name; - - ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SHSTRTAB].sh_offset + str_idx); - if (ret != 0) { - goto out; - } - - ret = llext_read(ldr, name, sizeof(name)); - if (ret != 0) { - goto out; - } - - name[sizeof(name) - 1] = '\0'; + name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr.sh_name); LOG_DBG("section %d name %s", i, name); enum llext_section sect_idx; - if (strncmp(name, ".text", sizeof(name)) == 0) { + if (strcmp(name, ".text") == 0) { sect_idx = LLEXT_SECT_TEXT; - } else if (strncmp(name, ".data", sizeof(name)) == 0) { + } else if (strcmp(name, ".data") == 0) { sect_idx = LLEXT_SECT_DATA; - } else if (strncmp(name, ".rodata", sizeof(name)) == 0) { + } else if (strcmp(name, ".rodata") == 0) { sect_idx = LLEXT_SECT_RODATA; - } else if (strncmp(name, ".bss", sizeof(name)) == 0) { + } else if (strcmp(name, ".bss") == 0) { sect_idx = LLEXT_SECT_BSS; } else { LOG_DBG("Not copied section %s", name); @@ -229,6 +223,12 @@ static inline enum llext_section llext_sect_from_mem(enum llext_mem m) case LLEXT_MEM_TEXT: s = LLEXT_SECT_TEXT; break; + case LLEXT_MEM_STRTAB: + s = LLEXT_SECT_STRTAB; + break; + case LLEXT_MEM_SHSTRTAB: + s = LLEXT_SECT_SHSTRTAB; + break; default: CODE_UNREACHABLE; } @@ -270,9 +270,25 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, return ret; } +static int llext_copy_strings(struct llext_loader *ldr, struct llext *ext) +{ + int ret = llext_copy_section(ldr, ext, LLEXT_MEM_SHSTRTAB); + + if (!ret) { + ret = llext_copy_section(ldr, ext, LLEXT_MEM_STRTAB); + } + + return ret; +} + static int llext_copy_sections(struct llext_loader *ldr, struct llext *ext) { for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { + /* strings have already been copied */ + if (ext->mem[mem_idx]) { + continue; + } + int ret = llext_copy_section(ldr, ext, mem_idx); if (ret < 0) { @@ -283,7 +299,7 @@ static int llext_copy_sections(struct llext_loader *ldr, struct llext *ext) return 0; } -static int llext_count_export_syms(struct llext_loader *ldr) +static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) { int ret = 0; elf_sym_t sym; @@ -291,7 +307,7 @@ static int llext_count_export_syms(struct llext_loader *ldr) size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; size_t sym_cnt = syms_size / sizeof(elf_sym_t); - char name[32]; + const char *name; LOG_DBG("symbol count %u", sym_cnt); @@ -312,17 +328,7 @@ static int llext_count_export_syms(struct llext_loader *ldr) uint32_t stb = ELF_ST_BIND(sym.st_info); uint32_t sect = sym.st_shndx; - ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + sym.st_name); - if (ret != 0) { - goto out; - } - - ret = llext_read(ldr, name, sizeof(name)); - if (ret != 0) { - goto out; - } - - name[sizeof(name) - 1] = '\0'; + name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); if (stt == STT_FUNC && stb == STB_GLOBAL) { LOG_DBG("function symbol %d, name %s, type tag %d, bind %d, sect %d", @@ -358,7 +364,6 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; size_t sym_cnt = syms_size / sizeof(elf_sym_t); - char name[32]; int i, j = 0; for (i = 0; i < sym_cnt; i++) { @@ -378,21 +383,10 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext uint32_t stb = ELF_ST_BIND(sym.st_info); uint32_t sect = sym.st_shndx; - ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + sym.st_name); - if (ret != 0) { - goto out; - } - - ret = llext_read(ldr, name, sizeof(name)); - if (ret != 0) { - goto out; - } - if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) { - ext->sym_tab.syms[j].name = k_heap_alloc(&llext_heap, - sizeof(name), - K_NO_WAIT); - strcpy(ext->sym_tab.syms[j].name, name); + const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); + + ext->sym_tab.syms[j].name = name; ext->sym_tab.syms[j].addr = (void *)((uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]] + sym.st_value); @@ -415,7 +409,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) elf_sym_t sym; size_t pos = ldr->hdr.e_shoff; elf_word rel_cnt = 0; - char name[32]; + const char *name; for (int i = 0; i < ldr->hdr.e_shnum - 1; i++) { ret = llext_seek(ldr, pos); @@ -437,25 +431,16 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) rel_cnt = shdr.sh_size / sizeof(elf_rel_t); + name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr.sh_name); - ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SHSTRTAB].sh_offset + shdr.sh_name); - if (ret != 0) { - goto out; - } - - ret = llext_read(ldr, name, sizeof(name)); - if (ret != 0) { - goto out; - } - - if (strncmp(name, ".rel.text", sizeof(name)) == 0 || - strncmp(name, ".rela.text", sizeof(name)) == 0) { + if (strcmp(name, ".rel.text") == 0 || + strcmp(name, ".rela.text") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_TEXT]; - } else if (strncmp(name, ".rel.bss", sizeof(name)) == 0) { + } else if (strcmp(name, ".rel.bss") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_BSS]; - } else if (strncmp(name, ".rel.rodata", sizeof(name)) == 0) { + } else if (strcmp(name, ".rel.rodata") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_RODATA]; - } else if (strncmp(name, ".rel.data", sizeof(name)) == 0) { + } else if (strcmp(name, ".rel.data") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_DATA]; } @@ -486,16 +471,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) goto out; } - ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_STRTAB].sh_offset + - sym.st_name); - if (ret != 0) { - goto out; - } - - ret = llext_read(ldr, name, sizeof(name)); - if (ret != 0) { - goto out; - } + name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); LOG_DBG("relocation %d:%d info %x (type %d, sym %d) offset %d sym_name " "%s sym_type %d sym_bind %d sym_ndx %d", @@ -583,8 +559,15 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) goto out; } + LOG_DBG("Allocate and copy strings..."); + ret = llext_copy_strings(ldr, ext); + if (ret != 0) { + LOG_ERR("Failed to copy ELF string sections, ret %d", ret); + goto out; + } + LOG_DBG("Mapping ELF sections..."); - ret = llext_map_sections(ldr); + ret = llext_map_sections(ldr, ext); if (ret != 0) { LOG_ERR("Failed to map ELF sections, ret %d", ret); goto out; @@ -598,7 +581,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) } LOG_DBG("Counting exported symbols..."); - ret = llext_count_export_syms(ldr); + ret = llext_count_export_syms(ldr, ext); if (ret != 0) { LOG_ERR("Failed to count exported ELF symbols, ret %d", ret); goto out; @@ -637,11 +620,6 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) k_heap_free(&llext_heap, ext->mem[mem_idx]); } } - for (int i = 0; i < ext->sym_tab.sym_cnt; i++) { - if (ext->sym_tab.syms[i].name != NULL) { - k_heap_free(&llext_heap, ext->sym_tab.syms[i].name); - } - } k_heap_free(&llext_heap, ext->sym_tab.syms); } else { LOG_DBG("loaded module, .text at %p, .rodata at %p", ext->mem[LLEXT_MEM_TEXT], @@ -727,9 +705,6 @@ void llext_unload(struct llext *ext) } if (ext->sym_tab.syms != NULL) { - for (int i = 0; i < ext->sym_tab.sym_cnt; i++) { - k_heap_free(&llext_heap, ext->sym_tab.syms[i].name); - } k_heap_free(&llext_heap, ext->sym_tab.syms); } From e75e04d2d2181f3c30af6dbfe64c60c10a86a2cb Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 25 Oct 2023 17:07:40 +0200 Subject: [PATCH 2717/4498] samples/bluetooth/hci_rpmsg: Allow building for simulated nrf5340 Allow building these samples for the simulted nrf5340 net core. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/hci_rpmsg/sample.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/samples/bluetooth/hci_rpmsg/sample.yaml b/samples/bluetooth/hci_rpmsg/sample.yaml index 7cecb12be67..2ca7ce52b63 100644 --- a/samples/bluetooth/hci_rpmsg/sample.yaml +++ b/samples/bluetooth/hci_rpmsg/sample.yaml @@ -8,6 +8,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet @@ -18,6 +19,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet @@ -28,6 +30,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.bis.bt_ll_sw_split: @@ -37,6 +40,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.iso_central.bt_ll_sw_split: @@ -46,6 +50,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.iso_peripheral.bt_ll_sw_split: @@ -55,6 +60,7 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.cis.bt_ll_sw_split: @@ -64,13 +70,16 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.iso.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso-bt_ll_sw_split.conf" - platform_allow: nrf5340dk_nrf5340_cpunet + platform_allow: + - nrf5340dk_nrf5340_cpunet + - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.df.bt_ll_sw_split: From 6bd47ffb10cef4f5733e9a7849ccb48988e61d4b Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 25 Oct 2023 22:12:33 +0530 Subject: [PATCH 2718/4498] net: zperf: Distinguish between IPv4 and IPv6 address set failures Using a generic IP for address set failures is confusing, esp. two same prints (one for v4 and the other for v6), so, use explicit version. Signed-off-by: Chaitanya Tata --- subsys/net/lib/zperf/zperf_shell.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index d2b2fb92f7c..94811721927 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -224,7 +224,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv6_addr(argv[start + 1], argv[start + 2], &shell_ipv6) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set IP\n"); + "Unable to set %s address (%s disabled)\n", "IPv6", "IPv4"); return 0; } @@ -241,7 +241,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv4_addr(argv[start + 1], &shell_ipv4) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set IP\n"); + "Unable to set %s address (%s disabled)\n", "IPv4", "IPv6"); return -ENOEXEC; } @@ -260,7 +260,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv4_addr(argv[start + 1], &shell_ipv4) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set IP\n"); + "Unable to set %s address\n", "IPv4"); return -ENOEXEC; } @@ -276,7 +276,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv6_addr(argv[start + 1], argv[start + 2], &shell_ipv6) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set IP\n"); + "Unable to set %s address\n", "IPv6"); return -ENOEXEC; } @@ -1199,7 +1199,7 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { - NET_WARN("Unable to set IP"); + NET_WARN("Unable to set %s address\n", "IPv6"); } else { NET_INFO("Setting IP address %s", net_sprint_ipv6_addr(&in6_addr_my.sin6_addr)); @@ -1208,9 +1208,10 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET6, DST_IP6ADDR, &in6_addr_dst.sin6_addr); if (ret < 0) { - NET_WARN("Unable to set IP %s", + NET_WARN("Unable to set destination %s address %s", + "IPv6", DST_IP6ADDR ? DST_IP6ADDR - : "(Default IPv6 destination address not set)"); + : "(not set)"); } else { NET_INFO("Setting destination IP address %s", net_sprint_ipv6_addr(&in6_addr_dst.sin6_addr)); @@ -1221,7 +1222,7 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET, MY_IP4ADDR, &in4_addr_my.sin_addr); if (ret < 0) { - NET_WARN("Unable to set IP"); + NET_WARN("Unable to set %s address\n", "IPv4"); } else { NET_INFO("Setting IP address %s", net_sprint_ipv4_addr(&in4_addr_my.sin_addr)); @@ -1230,9 +1231,10 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET, DST_IP4ADDR, &in4_addr_dst.sin_addr); if (ret < 0) { - NET_WARN("Unable to set IP %s", + NET_WARN("Unable to set destination %s address %s", + "IPv4", DST_IP4ADDR ? DST_IP4ADDR - : "(Default IPv4 destination address not set)"); + : "(not set)"); } else { NET_INFO("Setting destination IP address %s", net_sprint_ipv4_addr(&in4_addr_dst.sin_addr)); From dee1f2deaa71ae2595c4121500a95f06f8ce1c48 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 25 Oct 2023 22:14:26 +0530 Subject: [PATCH 2719/4498] net: zperf: Set default IP addresses only if configured If the user has not configured then we see the error prints for the defaults always. Signed-off-by: Chaitanya Tata --- subsys/net/lib/zperf/zperf_shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 94811721927..a553bb46c8d 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -1195,7 +1195,7 @@ void zperf_shell_init(void) { int ret; - if (IS_ENABLED(CONFIG_NET_IPV6) && MY_IP6ADDR) { + if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP6ADDR) { ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { @@ -1218,7 +1218,7 @@ void zperf_shell_init(void) } } - if (IS_ENABLED(CONFIG_NET_IPV4) && MY_IP4ADDR) { + if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP4ADDR) { ret = net_addr_pton(AF_INET, MY_IP4ADDR, &in4_addr_my.sin_addr); if (ret < 0) { From a1024f6aebd90b1a218bf003c8b97e5e7c9b0472 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 25 Oct 2023 23:18:50 +0530 Subject: [PATCH 2720/4498] net: zperf: By default bind to any IP address Default behaviour should only bind to port independent of IP, this allows even multicast/broadcast L4 traffic to be received. User can always specify a specific address to bind using shell or Kconfig or API. Signed-off-by: Chaitanya Tata --- subsys/net/lib/zperf/zperf_common.c | 21 ----------------- subsys/net/lib/zperf/zperf_internal.h | 3 --- subsys/net/lib/zperf/zperf_tcp_receiver.c | 27 ++++++---------------- subsys/net/lib/zperf/zperf_udp_receiver.c | 28 +++++++---------------- 4 files changed, 15 insertions(+), 64 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index 18c296cf508..4bc675ed45e 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -109,27 +109,6 @@ int zperf_get_ipv4_addr(char *host, struct in_addr *addr) return 0; } - -const struct in_addr *zperf_get_default_if_in4_addr(void) -{ -#if CONFIG_NET_IPV4 - return net_if_ipv4_select_src_addr(NULL, - net_ipv4_unspecified_address()); -#else - return NULL; -#endif -} - -const struct in6_addr *zperf_get_default_if_in6_addr(void) -{ -#if CONFIG_NET_IPV6 - return net_if_ipv6_select_src_addr(NULL, - net_ipv6_unspecified_address()); -#else - return NULL; -#endif -} - int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, int priority, int proto) { diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 96dd9ea9123..592424a9446 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -95,9 +95,6 @@ struct sockaddr_in *zperf_get_sin(void); extern void connect_ap(char *ssid); -const struct in_addr *zperf_get_default_if_in4_addr(void); -const struct in6_addr *zperf_get_default_if_in6_addr(void); - int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, int priority, int proto); diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index cd0add89cd9..344d34fe98c 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -171,18 +171,11 @@ static void tcp_server_session(void) &in4_addr->sin_addr); if (ret < 0) { NET_WARN("Unable to set IPv4"); - goto use_existing_ipv4; + goto use_any_ipv4; } } else { -use_existing_ipv4: - /* Use existing IP */ - addr = zperf_get_default_if_in4_addr(); - if (!addr) { - NET_ERR("Unable to get IPv4 by default"); - goto error; - } - memcpy(&in4_addr->sin_addr, addr, - sizeof(struct in_addr)); +use_any_ipv4: + in4_addr->sin_addr.s_addr = INADDR_ANY; } in4_addr->sin_port = htons(tcp_server_port); @@ -224,18 +217,12 @@ static void tcp_server_session(void) &in6_addr->sin6_addr); if (ret < 0) { NET_WARN("Unable to set IPv6"); - goto use_existing_ipv6; + goto use_any_ipv6; } } else { -use_existing_ipv6: - /* Use existing IP */ - addr = zperf_get_default_if_in6_addr(); - if (!addr) { - NET_ERR("Unable to get IPv6 by default"); - goto error; - } - memcpy(&in6_addr->sin6_addr, addr, - sizeof(struct in6_addr)); +use_any_ipv6: + memcpy(&in6_addr->sin6_addr, net_ipv6_unspecified_address(), + sizeof(struct in6_addr)); } in6_addr->sin6_port = htons(tcp_server_port); diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index 0b6997e401e..75a0b35b234 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -263,18 +263,11 @@ static void udp_server_session(void) &in4_addr_my->sin_addr); if (ret < 0) { NET_WARN("Unable to set IPv4"); - goto use_existing_ipv4; + goto use_any_ipv4; } } else { - use_existing_ipv4: - /* Use existing IP */ - in4_addr = zperf_get_default_if_in4_addr(); - if (!in4_addr) { - NET_ERR("Unable to get IPv4 by default"); - goto error; - } - memcpy(&in4_addr_my->sin_addr, in4_addr, - sizeof(struct in_addr)); +use_any_ipv4: + in4_addr_my->sin_addr.s_addr = INADDR_ANY; } NET_INFO("Binding to %s", @@ -319,18 +312,13 @@ static void udp_server_session(void) &in6_addr_my->sin6_addr); if (ret < 0) { NET_WARN("Unable to set IPv6"); - goto use_existing_ipv6; + goto use_any_ipv6; } } else { - use_existing_ipv6: - /* Use existing IP */ - in6_addr = zperf_get_default_if_in6_addr(); - if (!in6_addr) { - NET_ERR("Unable to get IPv4 by default"); - goto error; - } - memcpy(&in6_addr_my->sin6_addr, in6_addr, - sizeof(struct in6_addr)); +use_any_ipv6: + memcpy(&in6_addr_my->sin6_addr, + net_ipv6_unspecified_address(), + sizeof(struct in6_addr)); } NET_INFO("Binding to %s", From 253e266fc53a13f707fb9b9d82ea05f8833375f9 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 21:41:33 -0700 Subject: [PATCH 2721/4498] doc: vuln: Disclose information about CVE-2023-5139 Information about CVE-2023-5139 Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 956a4aee569..61d0d25f618 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1511,7 +1511,15 @@ Under embargo until 2023/11/01 CVE-2023-5139 ------------- -Under embargo until 2023/10/25 +Potential buffer overflow vulnerability in the Zephyr STM32 Crypto driver. + +- `Zephyr project bug tracker GHSA-rhrc-pcxp-4453 + `_ + +This has been fixed in main for v3.5.0 + +- `PR 61839 fix for main + `_ CVE-2023-5184 ------------- From 6949c61d982bad1f23c592b548ca2633673dfeda Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Thu, 26 Oct 2023 19:06:13 +0800 Subject: [PATCH 2722/4498] MAINTAINERS: add Nuvoton Numaker into maintainers To expand existing Nuvoton Numicro area to include Numaker. Signed-off-by: cyliang tw --- MAINTAINERS.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index caa7e7654ab..9e4884f4091 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2361,18 +2361,24 @@ Nuvoton NPCX Platforms: labels: - "platform: Nuvoton NPCX" -Nuvoton Numicro Platforms: - status: odd fixes +Nuvoton Numicro Numaker Platforms: + status: maintained + maintainers: + - cyliangtw collaborators: - ssekar15 files: - soc/arm/nuvoton_numicro/ + - soc/arm/nuvoton_numaker/ - boards/arm/nuvoton_pfm*/ + - boards/arm/numaker_*/ - dts/arm/nuvoton/ - dts/bindings/*/*numicro* + - dts/bindings/*/*numaker* - drivers/*/*_numicro* + - drivers/*/*_numaker* labels: - - "platform: Nuvoton Numicro" + - "platform: Nuvoton Numicro Numaker" Raspberry Pi Pico Platforms: status: maintained From 1467d7fa7b0ecd288c1de97db5cb0303ed8795e6 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 26 Oct 2023 10:34:53 +0300 Subject: [PATCH 2723/4498] net: shell: Join IPv4 mcast group if needed If user adds IPv4 address to the network interface, check if the address is a multicast one and add it to multicast group if it is. Fixes #64389 Signed-off-by: Jukka Rissanen --- subsys/net/ip/Kconfig | 1 + subsys/net/lib/shell/ipv4.c | 60 +++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 1831816ab25..41960201b39 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -158,6 +158,7 @@ config NET_IPV4_MAPPING_TO_IPV6 config NET_SHELL bool "Network shell utilities" select SHELL + select NET_IPV4_IGMP if NET_IPV4 help Activate shell module that provides network commands like ping to the console. diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index 81526dc7807..8fc88168c9a 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -8,6 +8,8 @@ #include LOG_MODULE_DECLARE(net_shell); +#include + #include "common.h" #include "../ip/ipv4.h" @@ -92,8 +94,8 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) int idx; struct in_addr addr; - if (argc != 4) { - PR_ERROR("Correct usage: net ipv4 add
    \n"); + if (argc < 3) { + PR_ERROR("Correct usage: net ipv4 add
    []\n"); return -EINVAL; } @@ -113,14 +115,37 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + if (net_ipv4_is_addr_mcast(&addr)) { + int ret; - if (net_addr_pton(AF_INET, argv[3], &addr)) { - PR_ERROR("Invalid netmask: %s", argv[3]); - return -EINVAL; - } + ret = net_ipv4_igmp_join(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "join", net_sprint_ipv4_addr(&addr), idx, ret); + return ret; + } + } else { + struct net_if_addr *ifaddr; - net_if_ipv4_set_netmask(iface, &addr); + if (argc < 4) { + PR_ERROR("Netmask is missing.\n"); + return -EINVAL; + } + + ifaddr = net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + if (ifaddr == NULL) { + PR_ERROR("Cannot add address %s to interface %d\n", + net_sprint_ipv4_addr(&addr), idx); + return -ENOMEM; + } + + if (net_addr_pton(AF_INET, argv[3], &addr)) { + PR_ERROR("Invalid netmask: %s", argv[3]); + return -EINVAL; + } + + net_if_ipv4_set_netmask(iface, &addr); + } #else /* CONFIG_NET_NATIVE_IPV4 */ PR_INFO("Set %s and %s to enable native %s support.\n", @@ -157,9 +182,20 @@ static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - if (!net_if_ipv4_addr_rm(iface, &addr)) { - PR_ERROR("Failed to delete %s\n", argv[2]); - return -ENOEXEC; + if (net_ipv4_is_addr_mcast(&addr)) { + int ret; + + ret = net_ipv4_igmp_leave(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "leave", net_sprint_ipv4_addr(&addr), idx, ret); + return ret; + } + } else { + if (!net_if_ipv4_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -ENOEXEC; + } } #else /* CONFIG_NET_NATIVE_IPV4 */ PR_INFO("Set %s and %s to enable native %s support.\n", @@ -170,7 +206,7 @@ static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, SHELL_CMD(add, NULL, - "'net ipv4 add
    ' adds the address to the interface.", + "'net ipv4 add
    []' adds the address to the interface.", cmd_net_ip_add), SHELL_CMD(del, NULL, "'net ipv4 del
    ' deletes the address from the interface.", From e44de3e381744900f7cd997d2c2d96f4b54b09bf Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 26 Oct 2023 10:46:51 +0300 Subject: [PATCH 2724/4498] net: shell: Join IPv6 mcast group if needed If user adds IPv6 address to the network interface, check if the address is a multicast one and add it to multicast group if it is. Signed-off-by: Jukka Rissanen --- subsys/net/ip/Kconfig | 1 + subsys/net/lib/shell/ipv6.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 41960201b39..dd057d46760 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -159,6 +159,7 @@ config NET_SHELL bool "Network shell utilities" select SHELL select NET_IPV4_IGMP if NET_IPV4 + select NET_IPV6_MLD if NET_IPV6 help Activate shell module that provides network commands like ping to the console. diff --git a/subsys/net/lib/shell/ipv6.c b/subsys/net/lib/shell/ipv6.c index f4b3214861a..f81b8dcae23 100644 --- a/subsys/net/lib/shell/ipv6.c +++ b/subsys/net/lib/shell/ipv6.c @@ -9,6 +9,7 @@ LOG_MODULE_DECLARE(net_shell); #include "common.h" +#include "../ip/ipv6.h" #if defined(CONFIG_NET_IPV6_FRAGMENT) void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data) @@ -211,8 +212,19 @@ static int cmd_net_ip6_add(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - if (!net_if_ipv6_addr_add(iface, &addr, NET_ADDR_MANUAL, 0)) { - PR_ERROR("Failed to add %s address to interface %p\n", argv[2], iface); + if (net_ipv6_is_addr_mcast(&addr)) { + int ret; + + ret = net_ipv6_mld_join(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "join", net_sprint_ipv6_addr(&addr), idx, ret); + return ret; + } + } else { + if (!net_if_ipv6_addr_add(iface, &addr, NET_ADDR_MANUAL, 0)) { + PR_ERROR("Failed to add %s address to interface %p\n", argv[2], iface); + } } #else /* CONFIG_NET_NATIVE_IPV6 */ @@ -250,9 +262,20 @@ static int cmd_net_ip6_del(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - if (!net_if_ipv6_addr_rm(iface, &addr)) { - PR_ERROR("Failed to delete %s\n", argv[2]); - return -1; + if (net_ipv6_is_addr_mcast(&addr)) { + int ret; + + ret = net_ipv6_mld_leave(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "leave", net_sprint_ipv6_addr(&addr), idx, ret); + return ret; + } + } else { + if (!net_if_ipv6_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -1; + } } #else /* CONFIG_NET_NATIVE_IPV6 */ From b2fec758b3d970e046c57daa1285563640d2c85e Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Thu, 26 Oct 2023 12:08:39 +0200 Subject: [PATCH 2725/4498] net: openthread: Fix dependency on openthread max ip addr. Fixes discrepancy between FTD and MTD in amount of ipaddr in `ChildUpdateRequest`. Signed-off-by: Przemyslaw Bida --- modules/openthread/Kconfig.thread | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index 73c547919a7..891365b4672 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -68,7 +68,6 @@ config OPENTHREAD_MAX_IP_ADDR_PER_CHILD int "The maximum number of IPv6 address registrations per child" range 4 255 default 6 - depends on OPENTHREAD_FTD config OPENTHREAD_CONFIG_PLATFORM_INFO string "The platform-specific string to insert into the OpenThread version string" From ee74ea26f3bdf3e706d08ffc9cfec8f229ea20e7 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 26 Oct 2023 14:16:03 +0300 Subject: [PATCH 2726/4498] doc: x86: Use start-after to include after right part In the documentation recently started to appear ':orphan:', which is marking for orphaned page. Use start-after to include after marking. Signed-off-by: Andrei Emeltchenko --- boards/x86/common/efi_boot.rst | 2 ++ boards/x86/common/net_boot.rst | 2 ++ boards/x86/intel_adl/doc/index.rst | 1 + boards/x86/intel_ehl/doc/index.rst | 2 ++ boards/x86/intel_rpl/doc/index.rst | 1 + boards/x86/up_squared/doc/index.rst | 3 ++- 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/boards/x86/common/efi_boot.rst b/boards/x86/common/efi_boot.rst index bfd88d276f5..54a08386d5d 100644 --- a/boards/x86/common/efi_boot.rst +++ b/boards/x86/common/efi_boot.rst @@ -1,5 +1,7 @@ :orphan: +.. start_include_here + Preparing the Boot Device ------------------------- diff --git a/boards/x86/common/net_boot.rst b/boards/x86/common/net_boot.rst index 20e2de0f45b..ae301bea0c4 100644 --- a/boards/x86/common/net_boot.rst +++ b/boards/x86/common/net_boot.rst @@ -1,5 +1,7 @@ :orphan: +.. start_include_here + Prepare Linux host ------------------ diff --git a/boards/x86/intel_adl/doc/index.rst b/boards/x86/intel_adl/doc/index.rst index f009c1c2268..63a518248b8 100644 --- a/boards/x86/intel_adl/doc/index.rst +++ b/boards/x86/intel_adl/doc/index.rst @@ -60,5 +60,6 @@ Booting the Alder Lake N CRB Board using UEFI ============================================= .. include:: ../../common/efi_boot.rst + :start-after: start_include_here .. _INTEL_ADL: https://edc.intel.com/content/www/us/en/design/products/platforms/processor-and-core-i3-n-series-datasheet-volume-1-of-2/ diff --git a/boards/x86/intel_ehl/doc/index.rst b/boards/x86/intel_ehl/doc/index.rst index 76661961c97..1aa8f530155 100644 --- a/boards/x86/intel_ehl/doc/index.rst +++ b/boards/x86/intel_ehl/doc/index.rst @@ -56,11 +56,13 @@ Booting the Elkhart Lake CRB Board using UEFI ============================================= .. include:: ../../common/efi_boot.rst + :start-after: start_include_here Booting the Elkhart Lake CRB Board over network =============================================== .. include:: ../../common/net_boot.rst + :start-after: start_include_here .. note:: To enable PXE boot for Elkhart Lake CRB board do the following: diff --git a/boards/x86/intel_rpl/doc/index.rst b/boards/x86/intel_rpl/doc/index.rst index c9db4c0fe3f..b9c64ded19e 100644 --- a/boards/x86/intel_rpl/doc/index.rst +++ b/boards/x86/intel_rpl/doc/index.rst @@ -56,5 +56,6 @@ Booting the Raptor Lake S CRB Board using UEFI ============================================== .. include:: ../../common/efi_boot.rst + :start-after: start_include_here .. _RPL: https://www.intel.com/content/www/us/en/newsroom/resources/13th-gen-core.html#gs.glf2fn diff --git a/boards/x86/up_squared/doc/index.rst b/boards/x86/up_squared/doc/index.rst index 35dc68ac533..bf40fa16ba2 100644 --- a/boards/x86/up_squared/doc/index.rst +++ b/boards/x86/up_squared/doc/index.rst @@ -80,7 +80,7 @@ Booting the UP Squared Board using UEFI ======================================= .. include:: ../../common/efi_boot.rst - + :start-after: start_include_here .. note:: Refer to the `UP Squared Serial Console Wiki page @@ -98,6 +98,7 @@ Booting the UP Squared Board over network ========================================= .. include:: ../../common/net_boot.rst + :start-after: start_include_here .. note:: Refer to the `UP Squared Serial Console Wiki page From a0b9d018b4b486a98d86d94142cf48ff27ca5c7d Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 26 Oct 2023 14:09:41 +0200 Subject: [PATCH 2727/4498] tests: rtc_api: Update y2k test to allow unknown values Some RTCs don't support the tm_yday and/or tm_wday fields of the struct rtc_time structure. These RTCs must set the values of the fields to -1 if they are not supported, and the test must be able to handle this correctly. This commit adds an exception to the tm_yday and tm_wday fields allowing them to be set to -1. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/rtc/rtc_api/src/test_y2k.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/drivers/rtc/rtc_api/src/test_y2k.c b/tests/drivers/rtc/rtc_api/src/test_y2k.c index 2d7e95aeb1b..d702a2d008b 100644 --- a/tests/drivers/rtc/rtc_api/src/test_y2k.c +++ b/tests/drivers/rtc/rtc_api/src/test_y2k.c @@ -50,8 +50,10 @@ ZTEST(rtc_api, test_y2k) zassert_equal(rtm[Y2K].tm_year + 1900, 2000, "wrong year: %d", rtm[Y2K].tm_year + 1900); zassert_equal(rtm[Y2K].tm_mon, 0, "wrong month: %d", rtm[Y2K].tm_mon); zassert_equal(rtm[Y2K].tm_mday, 1, "wrong day-of-month: %d", rtm[Y2K].tm_mday); - zassert_equal(rtm[Y2K].tm_yday, 0, "wrong day-of-year: %d", rtm[Y2K].tm_yday); - zassert_equal(rtm[Y2K].tm_wday, 6, "wrong day-of-week: %d", rtm[Y2K].tm_wday); + zassert_true(rtm[Y2K].tm_yday == 0 || rtm[Y2K].tm_yday == -1, "wrong day-of-year: %d", + rtm[Y2K].tm_yday); + zassert_true(rtm[Y2K].tm_wday == 6 || rtm[Y2K].tm_wday == -1, "wrong day-of-week: %d", + rtm[Y2K].tm_wday); zassert_equal(rtm[Y2K].tm_hour, 0, "wrong hour: %d", rtm[Y2K].tm_hour); zassert_equal(rtm[Y2K].tm_min, 0, "wrong minute: %d", rtm[Y2K].tm_min); zassert_equal(rtm[Y2K].tm_sec, SECONDS_AFTER, "wrong second: %d", rtm[Y2K].tm_sec); From 8c1513c837706c5e75158ed5d477de3bdb380fea Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Wed, 25 Oct 2023 15:48:25 +0200 Subject: [PATCH 2728/4498] Bluetooth: shell: make behaviour of iso cmd same as bt cmd When no parameters are given to the 'bt' command it prints the help message. The 'iso' command responds with 'missing subcommand'. This commit updates the behaviour of the iso command so that it behaves the same as the bt command, i.e. prints a help message Signed-off-by: Andries Kruithof --- subsys/bluetooth/shell/iso.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/shell/iso.c b/subsys/bluetooth/shell/iso.c index 17b53bb9922..e11d1d011f6 100644 --- a/subsys/bluetooth/shell/iso.c +++ b/subsys/bluetooth/shell/iso.c @@ -976,14 +976,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds, static int cmd_iso(const struct shell *sh, size_t argc, char **argv) { - if (argc > 1) { - shell_error(sh, "%s unknown parameter: %s", - argv[0], argv[1]); - } else { - shell_error(sh, "%s Missing subcommand", argv[0]); + if (argc == 1) { + shell_help(sh); + + return SHELL_CMD_HELP_PRINTED; } - return -ENOEXEC; + shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]); + + return -EINVAL; } SHELL_CMD_ARG_REGISTER(iso, &iso_cmds, "Bluetooth ISO shell commands", From 9ff60803c411781c4e5ad2d4dd433d8c2aca969f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 26 Oct 2023 15:42:26 +0200 Subject: [PATCH 2729/4498] debug: coredump: logging backend should always select LOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DEBUG_COREDUMP_BACKEND_LOGGING option should automatically select LOG Kconfig instead of just depending on it. Signed-off-by: Benjamin Cabé --- subsys/debug/coredump/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/debug/coredump/Kconfig b/subsys/debug/coredump/Kconfig index abeb0d3bda2..7031fc61651 100644 --- a/subsys/debug/coredump/Kconfig +++ b/subsys/debug/coredump/Kconfig @@ -11,11 +11,11 @@ if DEBUG_COREDUMP choice DEBUG_COREDUMP_BACKEND prompt "Coredump backend" - default DEBUG_COREDUMP_BACKEND_LOGGING if LOG + default DEBUG_COREDUMP_BACKEND_LOGGING config DEBUG_COREDUMP_BACKEND_LOGGING bool "Use Logging subsystem for coredump" - depends on LOG + select LOG help Core dump is done via logging subsystem. From 0fe6c72d40c7314c3d4b82b665432cf158fb6f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 26 Oct 2023 16:45:26 +0200 Subject: [PATCH 2730/4498] debug: coredump: guard selection of ADSP memory window backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabling the core dump via memory window backend only makes sense on Intel ADSP platform wtih memory windows enabled. Signed-off-by: Benjamin Cabé --- subsys/debug/coredump/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/debug/coredump/Kconfig b/subsys/debug/coredump/Kconfig index 7031fc61651..7b7de222784 100644 --- a/subsys/debug/coredump/Kconfig +++ b/subsys/debug/coredump/Kconfig @@ -30,6 +30,7 @@ config DEBUG_COREDUMP_BACKEND_FLASH_PARTITION config DEBUG_COREDUMP_BACKEND_INTEL_ADSP_MEM_WINDOW bool "Use memory window for coredump on Intel ADSP" + depends on DT_HAS_INTEL_ADSP_MEM_WINDOW_ENABLED help Core dump is done via memory window slot[1]. It is Intel ADSP memory region shared with xtensa DSP. From dfb3674c4cb49ffa2dbdaf812dfe785bc171b025 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Fri, 22 Apr 2022 11:36:05 +0200 Subject: [PATCH 2731/4498] linker: Add devnull memory for cortex_m and riscv32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added memory region which is intended to be removed from the final binary but may be using in byproduct to extract data used by the host tools (e.g. strings used by logging). Add devnull region to Cortex-M and RISCV linker scripts. Signed-off-by: Krzysztof Chruściński --- Kconfig.zephyr | 18 +++++ .../arch/arm/cortex_m/scripts/linker.ld | 7 +- include/zephyr/arch/riscv/common/linker.ld | 6 ++ include/zephyr/linker/linker-devnull.h | 78 +++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 include/zephyr/linker/linker-devnull.h diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 4710cc82149..0edb610d677 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -306,6 +306,24 @@ config LINKER_USE_RELAX endmenu # "Linker Sections" +config LINKER_DEVNULL_SUPPORT + bool + default y if CPU_CORTEX_M || (RISCV && !64BIT) + +config LINKER_DEVNULL_MEMORY + bool "Devnull region" + depends on LINKER_DEVNULL_SUPPORT + help + Devnull region is created. It is stripped from final binary but remains + in byproduct elf file. + +config LINKER_DEVNULL_MEMORY_SIZE + int "Devnull region size" + depends on LINKER_DEVNULL_MEMORY + default 262144 + help + Size can be adjusted so it fits all data placed in that region. + endmenu menu "Compiler Options" diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 92b6f02d029..13c2747f5a3 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -35,7 +35,7 @@ #if CONFIG_FLASH_LOAD_SIZE > 0 #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE #else -#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET) +#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - CONFIG_FLASH_LOAD_OFFSET) #endif #if defined(CONFIG_XIP) @@ -75,10 +75,15 @@ _region_min_align = 4; . = ALIGN(_region_min_align) #endif +#include + MEMORY { FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE +#endif LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index 5bed82439d6..eb5c4782441 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -72,6 +72,8 @@ #define MPU_ALIGN(region_size) . = ALIGN(4) #endif +#include + MEMORY { #ifdef CONFIG_XIP @@ -79,6 +81,10 @@ MEMORY #endif RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE +#endif + LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ diff --git a/include/zephyr/linker/linker-devnull.h b/include/zephyr/linker/linker-devnull.h new file mode 100644 index 00000000000..0545da7c8a5 --- /dev/null +++ b/include/zephyr/linker/linker-devnull.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * DESCRIPTION + * Platform independent set of macros for creating a memory segment for + * aggregating data that shall be kept in the elf file but not in the binary. + */ + +#ifndef ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ + +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + +#if defined(CONFIG_XIP) +#if (!defined(ROM_ADDR) && !defined(ROM_BASE)) || !defined(ROM_SIZE) +#error "ROM_SIZE, ROM_ADDR or ROM_BASE not defined" +#endif +#endif /* CONFIG_XIP */ + +#if (!defined(RAM_ADDR) && !defined(RAM_BASE)) || !defined(RAM_SIZE) +#error "RAM_SIZE, RAM_ADDR or RAM_BASE not defined" +#endif + +#if defined(CONFIG_XIP) && !defined(ROM_ADDR) +#define ROM_ADDR ROM_BASE +#endif + +#if !defined(RAM_ADDR) +#define RAM_ADDR RAM_BASE +#endif + +#define ROM_END_ADDR (ROM_ADDR + ROM_SIZE) +#define DEVNULL_SIZE CONFIG_LINKER_DEVNULL_MEMORY_SIZE +#define ROM_DEVNULL_END_ADDR (ROM_END_ADDR + DEVNULL_SIZE) +#define MAX_ADDR UINT32_MAX + +/* Determine where to put the devnull region. It should be adjacent to the ROM + * region. If ROM starts after RAM or the distance between ROM and RAM is big + * enough to fit the devnull region then devnull region is placed just after + * the ROM region. If it cannot be done then the devnull region is placed before + * the ROM region. It is possible that the devnull region cannot be placed + * adjacent to the ROM (e.g. ROM starts at 0 and RAM follows ROM). In that + * case compilation fails and the devnull region is not supported in that + * configuration. + */ +#if !defined(CONFIG_XIP) + +#if RAM_ADDR >= DEVNULL_SIZE +#define DEVNULL_ADDR (RAM_ADDR - DEVNULL_SIZE) +#else +#define DEVNULL_ADDR (RAM_ADDR + RAM_SIZE) +#endif + +#else /* CONFIG_XIP */ + +#if ((ROM_ADDR > RAM_ADDR) && ((MAX_ADDR - ROM_END_ADDR) >= DEVNULL_SIZE)) || \ + ((ROM_END_ADDR + DEVNULL_SIZE) <= RAM_ADDR) +#define DEVNULL_ADDR ROM_END_ADDR +#elif ROM_ADDR > DEVNULL_SIZE +#define DEVNULL_ADDR (ROM_ADDR - DEVNULL_SIZE) +#else +#error "Cannot place devnull segment adjacent to ROM region." +#endif + +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) +#define DEVNULL_REGION DEVNULL_ROM +#else +#define DEVNULL_REGION ROMABLE_REGION +#endif + +#endif /* CONFIG_XIP */ + +#endif /* CONFIG_LINKER_DEVNULL_MEMORY */ + +#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ */ From f172a1a5ee51b7830c1bbd93fc49aab08b3b2d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 25 Oct 2023 15:25:18 +0200 Subject: [PATCH 2732/4498] scripts: logging: dictionary: Handle string stripping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for getting strings from section which is not part of the binary. Signed-off-by: Krzysztof Chruściński --- scripts/logging/dictionary/database_gen.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/logging/dictionary/database_gen.py b/scripts/logging/dictionary/database_gen.py index 1737186793d..663adb3a365 100755 --- a/scripts/logging/dictionary/database_gen.py +++ b/scripts/logging/dictionary/database_gen.py @@ -49,6 +49,11 @@ 'pinned.rodata', ] +# Sections that contains static strings but are not part of the binary (allocable). +REMOVED_STRING_SECTIONS = [ + 'log_strings' +] + # Regulation expression to match DWARF location DT_LOCATION_REGEX = re.compile(r"\(DW_OP_addr: ([0-9a-f]+)") @@ -94,7 +99,7 @@ def parse_args(): return argparser.parse_args() -def extract_elf_code_data_sections(elf): +def extract_elf_code_data_sections(elf, wildcards = None): """Find all sections in ELF file""" sections = {} @@ -103,9 +108,9 @@ def extract_elf_code_data_sections(elf): # since they actually have code/data. # # On contrary, BSS is allocated but NOBITS. - if ( - (sect['sh_flags'] & SH_FLAGS.SHF_ALLOC) == SH_FLAGS.SHF_ALLOC - and sect['sh_type'] == 'SHT_PROGBITS' + if (((wildcards is not None) and (sect.name in wildcards)) or + ((sect['sh_flags'] & SH_FLAGS.SHF_ALLOC) == SH_FLAGS.SHF_ALLOC + and sect['sh_type'] == 'SHT_PROGBITS') ): sections[sect.name] = { 'name' : sect.name, @@ -453,7 +458,7 @@ def extract_static_strings(elf, database, section_extraction=False): """ string_mappings = {} - elf_sections = extract_elf_code_data_sections(elf) + elf_sections = extract_elf_code_data_sections(elf, REMOVED_STRING_SECTIONS) # Extract strings using ELF DWARF information str_vars = extract_string_variables(elf) From 59abf921c10f0e153189dea0396235658dd721fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 25 Oct 2023 11:08:13 +0200 Subject: [PATCH 2733/4498] logging: Add option to remove strings from binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add option to remove string literals which are constant and never touched by the firmware. It can save significant amount of RO memory. Signed-off-by: Krzysztof Chruściński --- include/zephyr/linker/common-rom/common-rom-logging.ld | 7 +++++++ subsys/logging/Kconfig.misc | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/include/zephyr/linker/common-rom/common-rom-logging.ld b/include/zephyr/linker/common-rom/common-rom-logging.ld index f39fed01b21..4e146375b43 100644 --- a/include/zephyr/linker/common-rom/common-rom-logging.ld +++ b/include/zephyr/linker/common-rom/common-rom-logging.ld @@ -2,7 +2,14 @@ #include +#ifdef CONFIG_LOG_FMT_SECTION_STRIP + SECTION_PROLOGUE(log_strings,(COPY),SUBALIGN(4)) + { + Z_LINK_ITERABLE(log_strings); + } GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) +#else ITERABLE_SECTION_ROM(log_strings, 4) +#endif ITERABLE_SECTION_ROM(log_const, 4) diff --git a/subsys/logging/Kconfig.misc b/subsys/logging/Kconfig.misc index 74b629f54ae..0dc5831e528 100644 --- a/subsys/logging/Kconfig.misc +++ b/subsys/logging/Kconfig.misc @@ -65,6 +65,13 @@ config LOG_FMT_SECTION removing strings from final binary and should be used for dictionary logging. +config LOG_FMT_SECTION_STRIP + bool "Strip log strings from binary" + depends on !LOG_OUTPUT + depends on LOG_FMT_SECTION + depends on LINKER_DEVNULL_SUPPORT + imply LINKER_DEVNULL_MEMORY + config LOG_USE_TAGGED_ARGUMENTS bool "Using tagged arguments for packaging" depends on !PICOLIBC From 9470e3d129a364f280285293c7e4034de833978c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 26 Oct 2023 08:24:23 +0200 Subject: [PATCH 2734/4498] logging: Imply strings stripping if dictionary frontend is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When UART dictionary frontend is used strings can be removed from the binary. Signed-off-by: Krzysztof Chruściński --- subsys/logging/Kconfig.frontends | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/logging/Kconfig.frontends b/subsys/logging/Kconfig.frontends index 1dffe73de59..7a725421fb9 100644 --- a/subsys/logging/Kconfig.frontends +++ b/subsys/logging/Kconfig.frontends @@ -8,6 +8,8 @@ config LOG_FRONTEND_DICT_UART select LOG_DICTIONARY_DB select MPSC_PBUF depends on UART_ASYNC_API || UART_INTERRUPT_DRIVEN + imply LOG_FMT_SECTION + imply LOG_FMT_SECTION_STRIP help Frontend sends data in binary dictionary mode. From 78bf8ebf757e39e1ab23d6504f54209eb52056ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 26 Oct 2023 09:29:34 +0200 Subject: [PATCH 2735/4498] logging: Allow keeping module names in dedicated section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_LOG_FMT_SECTION is enabled then module name strings are also placed in the dedicated section used for all logging strings. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/include/zephyr/logging/log.h b/include/zephyr/logging/log.h index e6db645c742..d04f5b1ab82 100644 --- a/include/zephyr/logging/log.h +++ b/include/zephyr/logging/log.h @@ -298,14 +298,19 @@ void z_log_vprintk(const char *fmt, va_list ap); /* Return first argument */ #define _LOG_ARG1(arg1, ...) arg1 -#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \ - IF_ENABLED(LOG_IN_CPLUSPLUS, (extern)) \ - const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, \ - log_source_const_data, \ - Z_LOG_ITEM_CONST_DATA(_name)) = \ - { \ - .name = STRINGIFY(_name), \ - .level = _level \ +#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \ + IF_ENABLED(CONFIG_LOG_FMT_SECTION, ( \ + static const char UTIL_CAT(_name, _str)[] \ + __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \ + STRINGIFY(_name);)) \ + IF_ENABLED(LOG_IN_CPLUSPLUS, (extern)) \ + const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, \ + log_source_const_data, \ + Z_LOG_ITEM_CONST_DATA(_name)) = \ + { \ + .name = COND_CODE_1(CONFIG_LOG_FMT_SECTION, \ + (UTIL_CAT(_name, _str)), (STRINGIFY(_name))), \ + .level = _level \ } #define _LOG_MODULE_DYNAMIC_DATA_CREATE(_name) \ From 2e2de9e5c230425d6f93a4b1e4be4f45856bcde1 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 27 Oct 2023 10:40:01 +0200 Subject: [PATCH 2736/4498] drivers: eeprom: add missing documentation to eeprom.h Add missing doxygen documentation to the eeprom.h header file. Signed-off-by: Henrik Brix Andersen --- include/zephyr/drivers/eeprom.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/zephyr/drivers/eeprom.h b/include/zephyr/drivers/eeprom.h index 2494d3e6754..7da3d2a079d 100644 --- a/include/zephyr/drivers/eeprom.h +++ b/include/zephyr/drivers/eeprom.h @@ -32,11 +32,31 @@ extern "C" { #endif +/** + * @cond INTERNAL_HIDDEN + * + * For internal driver use only, skip these in public documentation. + */ + +/** + * @brief Callback API upon reading from the EEPROM. + * See @a eeprom_read() for argument description + */ typedef int (*eeprom_api_read)(const struct device *dev, off_t offset, void *data, size_t len); + +/** + * @brief Callback API upon writing to the EEPROM. + * See @a eeprom_write() for argument description + */ typedef int (*eeprom_api_write)(const struct device *dev, off_t offset, const void *data, size_t len); + +/** + * @brief Callback API upon getting the EEPROM size. + * See @a eeprom_get_size() for argument description + */ typedef size_t (*eeprom_api_size)(const struct device *dev); __subsystem struct eeprom_driver_api { @@ -45,6 +65,8 @@ __subsystem struct eeprom_driver_api { eeprom_api_size size; }; +/** @endcond */ + /** * @brief Read data from EEPROM * From 6ddde16bdb63ed307278900fcced1a61b496318a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 27 Oct 2023 10:33:49 +0200 Subject: [PATCH 2737/4498] drivers: can: add missing documentation to can.h Add missing doxygen documentation to the can.h header file. Signed-off-by: Henrik Brix Andersen --- include/zephyr/drivers/can.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index e0cde5524ba..a09a7cdf97b 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -6,6 +6,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Controller Area Network (CAN) driver API. + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_H_ #define ZEPHYR_INCLUDE_DRIVERS_CAN_H_ @@ -181,7 +186,9 @@ struct can_frame { #endif /** The frame payload data. */ union { + /** Payload data accessed as unsigned 8 bit values. */ uint8_t data[CAN_MAX_DLEN]; + /** Payload data accessed as unsigned 32 bit values. */ uint32_t data_32[DIV_ROUND_UP(CAN_MAX_DLEN, sizeof(uint32_t))]; }; }; @@ -489,7 +496,9 @@ STATS_NAME_END(can); * additions */ struct can_device_state { + /** Common device state. */ struct device_state devstate; + /** CAN device statistics */ struct stats_can stats; }; From 8487aad003666ded82ec70e901926bd94ba4ca9d Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Thu, 26 Oct 2023 12:11:56 +0200 Subject: [PATCH 2738/4498] drivers: i2c: i2c_nrfx_twi*: don't print errors in case of transfer failure Let the caller decide what should be done in case of the transfer failure. It will reduce the number of error log prints when the i2c scan is called for the bus where nothing is connected. Signed-off-by: Bartosz Bilas --- drivers/i2c/i2c_nrfx_twi.c | 2 -- drivers/i2c/i2c_nrfx_twim.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/i2c/i2c_nrfx_twi.c b/drivers/i2c/i2c_nrfx_twi.c index bbb070e7e0c..8af5fe4ddee 100644 --- a/drivers/i2c/i2c_nrfx_twi.c +++ b/drivers/i2c/i2c_nrfx_twi.c @@ -126,7 +126,6 @@ static int i2c_nrfx_twi_transfer(const struct device *dev, * to make sure everything has been done to restore the * bus from this error. */ - LOG_ERR("Error on I2C line occurred for message %d", i); nrfx_twi_disable(&config->twi); (void)i2c_nrfx_twi_recover_bus(dev); ret = -EIO; @@ -135,7 +134,6 @@ static int i2c_nrfx_twi_transfer(const struct device *dev, res = data->res; if (res != NRFX_SUCCESS) { - LOG_ERR("Error 0x%08X occurred for message %d", res, i); ret = -EIO; break; } diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 55160a44c72..90e1fcfb109 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -166,7 +166,6 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, * to make sure everything has been done to restore the * bus from this error. */ - LOG_ERR("Error on I2C line occurred for message %d", i); (void)i2c_nrfx_twim_recover_bus(dev); ret = -EIO; break; @@ -175,7 +174,6 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, res = dev_data->res; if (res != NRFX_SUCCESS) { - LOG_ERR("Error 0x%08X occurred for message %d", res, i); ret = -EIO; break; } From df1897c122a15a7a18ad3c01009d267a5302a0cd Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Tue, 24 Oct 2023 16:53:20 +0100 Subject: [PATCH 2739/4498] drivers: flash: Add RDP (readout protection) support for STM32G4x flash Add support for Flash readout protection on the STM32G4x series Signed-off-by: Adam Mitchell --- drivers/flash/Kconfig.stm32 | 2 +- drivers/flash/flash_stm32g4x.c | 150 +++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index 602c3792392..5344d818322 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -38,7 +38,7 @@ config FLASH_STM32_WRITE_PROTECT_DISABLE_PREVENTION config FLASH_STM32_READOUT_PROTECTION bool "Extended operation for flash readout protection control" - depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32L4X + depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32G4X select FLASH_HAS_EX_OP default n help diff --git a/drivers/flash/flash_stm32g4x.c b/drivers/flash/flash_stm32g4x.c index e1f012c254b..8f11e21c20e 100644 --- a/drivers/flash/flash_stm32g4x.c +++ b/drivers/flash/flash_stm32g4x.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #include #include #include +#include #include #include #include @@ -254,6 +255,155 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } +static __unused int write_optb(const struct device *dev, uint32_t mask, + uint32_t value) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + int rc; + + if (regs->CR & FLASH_CR_OPTLOCK) { + return -EIO; + } + + if ((regs->OPTR & mask) == value) { + return 0; + } + + rc = flash_stm32_wait_flash_idle(dev); + if (rc < 0) { + return rc; + } + + regs->OPTR = (regs->OPTR & ~mask) | value; + regs->CR |= FLASH_CR_OPTSTRT; + + /* Make sure previous write is completed. */ + barrier_dsync_fence_full(); + + rc = flash_stm32_wait_flash_idle(dev); + if (rc < 0) { + return rc; + } + + return 0; +} + +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) + +/* + * Remark for future development implementing Write Protection for the L4 parts: + * + * STM32L4 allows for 2 write protected memory areas, c.f. FLASH_WEP1AR, FLASH_WRP1BR + * which are defined by their start and end pages. + * + * Other STM32 parts (i.e. F4 series) uses bitmask to select sectors. + * + * To implement Write Protection for L4 one should thus add a new EX_OP like + * FLASH_STM32_EX_OP_SECTOR_WP_RANGED in stm32_flash_api_extensions.h + */ + +#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ + +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) +int flash_stm32_update_rdp(const struct device *dev, bool enable, + bool permanent) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uint8_t current_level, target_level; + + current_level = + (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos; + target_level = current_level; + + /* + * 0xAA = RDP level 0 (no protection) + * 0xCC = RDP level 2 (permanent protection) + * others = RDP level 1 (protection active) + */ + switch (current_level) { + case FLASH_STM32_RDP2: + if (!enable || !permanent) { + LOG_ERR("RDP level 2 is permanent and can't be changed!"); + return -ENOTSUP; + } + break; + case FLASH_STM32_RDP0: + if (enable) { + target_level = FLASH_STM32_RDP1; + if (permanent) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) + target_level = FLASH_STM32_RDP2; +#else + LOG_ERR("Permanent readout protection (RDP " + "level 0 -> 2) not allowed"); + return -ENOTSUP; +#endif + } + } + break; + default: /* FLASH_STM32_RDP1 */ + if (enable && permanent) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW) + target_level = FLASH_STM32_RDP2; +#else + LOG_ERR("Permanent readout protection (RDP " + "level 1 -> 2) not allowed"); + return -ENOTSUP; +#endif + } + if (!enable) { +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW) + target_level = FLASH_STM32_RDP0; +#else + LOG_ERR("Disabling readout protection (RDP " + "level 1 -> 0) not allowed"); + return -EACCES; +#endif + } + } + + /* Update RDP level if needed */ + if (current_level != target_level) { + LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level, + target_level); + + write_optb(dev, FLASH_OPTR_RDP_Msk, + (uint32_t)target_level << FLASH_OPTR_RDP_Pos); + } + return 0; +} + +int flash_stm32_get_rdp(const struct device *dev, bool *enabled, + bool *permanent) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uint8_t current_level; + + current_level = + (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos; + + /* + * 0xAA = RDP level 0 (no protection) + * 0xCC = RDP level 2 (permanent protection) + * others = RDP level 1 (protection active) + */ + switch (current_level) { + case FLASH_STM32_RDP2: + *enabled = true; + *permanent = true; + break; + case FLASH_STM32_RDP0: + *enabled = false; + *permanent = false; + break; + default: /* FLASH_STM32_RDP1 */ + *enabled = true; + *permanent = false; + } + return 0; +} +#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ + void flash_stm32_page_layout(const struct device *dev, const struct flash_pages_layout **layout, size_t *layout_size) From 2f43b0b69649f5d7c9919fa8475567c05ce88a6a Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Wed, 25 Oct 2023 10:37:38 +0100 Subject: [PATCH 2740/4498] drivers: flash: Add RDP (readout protection) support for STM32G4x flash Add support (and tests) for flash readout protection on the STM32G4x series Signed-off-by: Adam Mitchell --- tests/drivers/flash/stm32/testcase.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/drivers/flash/stm32/testcase.yaml b/tests/drivers/flash/stm32/testcase.yaml index 50014898591..f3346c96052 100644 --- a/tests/drivers/flash/stm32/testcase.yaml +++ b/tests/drivers/flash/stm32/testcase.yaml @@ -20,3 +20,10 @@ tests: - CONFIG_FLASH_STM32_READOUT_PROTECTION=y filter: dt_compat_enabled("st,stm32l4-flash-controller") and dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions") + drivers.flash.stm32.g4: + platform_allow: + - nucleo_g474re + extra_configs: + - CONFIG_FLASH_STM32_READOUT_PROTECTION=y + filter: dt_compat_enabled("st,stm32g4-flash-controller") and + dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions") From 9f850010612f18925ea09fad3d99cadbd7c4b33f Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Thu, 17 Aug 2023 14:34:31 +0200 Subject: [PATCH 2741/4498] scripts: Make workflow of test_plan.py script more robust The script was not resolving all detected changes uniformly: find_excludes() could skip or not certain patterns based on required testing scope. The idea was to not include files that were already handled by find_test() and find_boards() workflows. However, only boards and tests folders could be removed but not samples. This also led to blind spots: changes in some files were not triggering any tests. E.g. change in a test/common, where no corresponding yaml can be found by find_tests() which is also ignored by find_excludes(). In the new workflow a list of resolved files (for which find_arch(), find_tests() or find_boards() found scope) is created. Instead of using skip in find_excludes, files are excluded only if they were resolved. Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 39 +++++++++++++++++++++-------------- scripts/ci/twister_ignore.txt | 19 ----------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 0c4f05c0ca9..f14e2a25eb1 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -97,13 +97,13 @@ def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.testsuite_root = testsuite_root + self.resolved_files = [] self.twister_options = [] self.full_twister = False self.all_tests = [] self.tag_options = [] self.pull_request = pull_request self.platforms = platforms - self.default_run = False self.detailed_test_id = detailed_test_id self.ignore_path = ignore_path self.tag_cfg_file = alt_tags @@ -115,11 +115,7 @@ def process(self): if not self.platforms: self.find_archs() self.find_boards() - - if self.default_run: - self.find_excludes(skip=["tests/*", "boards/*/*/*"]) - else: - self.find_excludes() + self.find_excludes() def get_plan(self, options, integration=False, use_testsuite_root=True): fname = "_test_plan_partial.json" @@ -200,6 +196,8 @@ def find_archs(self): archs.add('riscv64') else: archs.add(p.group(1)) + # Modified file is treated as resolved, since a matching scope was found + self.resolved_files.append(f) _options = [] for arch in archs: @@ -218,6 +216,7 @@ def find_archs(self): def find_boards(self): boards = set() all_boards = set() + resolved = [] for f in self.modified_files: if f.endswith(".rst") or f.endswith(".png") or f.endswith(".jpg"): @@ -225,6 +224,7 @@ def find_boards(self): p = re.match(r"^boards\/[^/]+\/([^/]+)\/", f) if p and p.groups(): boards.add(p.group(1)) + resolved.append(f) roots = [zephyr_base] if repository_path != zephyr_base: @@ -239,10 +239,16 @@ def find_boards(self): if name_re.search(kb.name): all_boards.add(kb.name) + # If modified file is catched by "find_boards" workflow (change in "boards" dir AND board recognized) + # it means a proper testing scope for this file was found and this file can be removed + # from further consideration + for board in all_boards: + self.resolved_files.extend(list(filter(lambda f: board in f, resolved))) + _options = [] if len(all_boards) > 20: logging.warning(f"{len(boards)} boards changed, this looks like a global change, skipping test handling, revert to default.") - self.default_run = True + self.full_twister = True return for board in all_boards: @@ -262,6 +268,8 @@ def find_tests(self): if os.path.exists(os.path.join(d, "testcase.yaml")) or \ os.path.exists(os.path.join(d, "sample.yaml")): tests.add(d) + # Modified file is treated as resolved, since a matching scope was found + self.resolved_files.append(f) break else: d = os.path.dirname(d) @@ -272,7 +280,7 @@ def find_tests(self): if len(tests) > 20: logging.warning(f"{len(tests)} tests changed, this looks like a global change, skipping test handling, revert to default") - self.default_run = True + self.full_twister = True return if _options: @@ -328,21 +336,22 @@ def find_excludes(self, skip=[]): ignores = filter(lambda x: not x.startswith("#"), ignores) found = set() - files = list(filter(lambda x: x, self.modified_files)) + files_not_resolved = list(filter(lambda x: x not in self.resolved_files, self.modified_files)) for pattern in ignores: - if pattern in skip: - continue if pattern: - found.update(fnmatch.filter(files, pattern)) + found.update(fnmatch.filter(files_not_resolved, pattern)) logging.debug(found) - logging.debug(files) + logging.debug(files_not_resolved) - if sorted(files) != sorted(found): + # Full twister run can be ordered by detecting great number of tests/boards changed + # or if not all modified files were resolved (corresponding scope found) + self.full_twister = self.full_twister or sorted(files_not_resolved) != sorted(found) + + if self.full_twister: _options = [] logging.info(f'Need to run full or partial twister...') - self.full_twister = True if self.platforms: for platform in self.platforms: _options.extend(["-p", platform]) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index 0ee6e93ea32..c1dfb0a98f8 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -17,25 +17,6 @@ CODEOWNERS MAINTAINERS.yml LICENSE Makefile -tests/* -samples/* -boards/*/*/* -arch/xtensa/* -arch/x86/* -arch/posix/* -arch/arc/* -arch/sparc/* -arch/arm/* -arch/nios2/* -arch/riscv/* -include/arch/xtensa/* -include/arch/x86/* -include/arch/posix/* -include/arch/arc/* -include/arch/sparc/* -include/arch/arm/* -include/arch/nios2/* -include/arch/riscv/* doc/* # GH action have no impact on code .github/* From 72f416f382f061199900096f50315608b75aae8b Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 18 Aug 2023 16:02:12 +0200 Subject: [PATCH 2742/4498] scripts: Add workflow for "common" directories in find_tests() Some tests use a "common" directory to store pieces of code which are reused by different scenarios. In those cases, no test yaml is found within such director nor within its parents. If no test yaml is found in a directory, and the directory is called common, also look in collocated directories if they have test yamls. If so, add all those locations to the scope. E.g. tests/bluetooth/controller/common Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index f14e2a25eb1..e1fc51a59d1 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -12,6 +12,7 @@ import json import logging import sys +import glob from pathlib import Path from git import Repo from west.manifest import Manifest @@ -264,13 +265,25 @@ def find_tests(self): if f.endswith(".rst"): continue d = os.path.dirname(f) - while d: + scope_found = False + while not scope_found and d: + head, tail = os.path.split(d) if os.path.exists(os.path.join(d, "testcase.yaml")) or \ os.path.exists(os.path.join(d, "sample.yaml")): tests.add(d) # Modified file is treated as resolved, since a matching scope was found self.resolved_files.append(f) - break + scope_found = True + elif tail == "common": + # Look for yamls in directories collocated with common + + yamls_found = [yaml for yaml in glob.iglob(head + '/**/testcase.yaml', recursive=True)] + yamls_found.extend([yaml for yaml in glob.iglob(head + '/**/sample.yaml', recursive=True)]) + if yamls_found: + for yaml in yamls_found: + tests.add(os.path.dirname(yaml)) + self.resolved_files.append(f) + scope_found = True else: d = os.path.dirname(d) From c294b7d2701230d7e66aaeeb541d7997f880023e Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 27 Oct 2023 10:25:10 +0200 Subject: [PATCH 2743/4498] lib/acpi: Fix the behavior to fit with how it used to be z_acpi_get_cpu() used to retrieve the local apic on enabled CPU, where n was about the n'th enabled CPU, not just the n'th local apic. The system indeed keeps local apic info also about non-enabled CPU, and we don't care about these as there is nothing to do about it. This issue exists on up_squared board for instance, but it's a common one anyway. Signed-off-by: Tomasz Bursztyka --- include/zephyr/acpi/acpi.h | 6 +++--- lib/acpi/acpi.c | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/zephyr/acpi/acpi.h b/include/zephyr/acpi/acpi.h index 77a1f2e9527..c66f55acbb8 100644 --- a/include/zephyr/acpi/acpi.h +++ b/include/zephyr/acpi/acpi.h @@ -175,10 +175,10 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d union acpi_dmar_id *dmar_id, int *num_inst, int max_inst); /** - * @brief Retrieve lapic info for a specific cpu. + * @brief Retrieve the 'n'th enabled local apic info. * * @param cpu_num the cpu number - * @return lapic info on success or NULL + * @return local apic info on success or NULL otherwise */ -struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num); +struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num); #endif diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index d8f91d01ce8..dca6e81cc3e 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -791,10 +791,13 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d return 0; } -struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num) +#define ACPI_CPU_FLAGS_ENABLED 0x01u + +struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num) { struct acpi_madt_local_apic *lapic; int cpu_cnt; + int idx; if (acpi_madt_entry_get(ACPI_MADT_TYPE_LOCAL_APIC, (ACPI_SUBTABLE_HEADER **)&lapic, &cpu_cnt)) { @@ -802,10 +805,15 @@ struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num) return NULL; } - if ((cpu_num >= cpu_cnt) || !(lapic[cpu_num].LapicFlags & 1u)) { - /* Proccessor not enabled. */ - return NULL; + for (idx = 0; cpu_num >= 0 && idx < cpu_cnt; idx++) { + if (lapic[idx].LapicFlags & ACPI_CPU_FLAGS_ENABLED) { + if (cpu_num == 0) { + return &lapic[idx]; + } + + cpu_num--; + } } - return &lapic[cpu_num]; + return NULL; } From f5ce4ddc79c3c05f9065429489828a0d9692cc93 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 27 Oct 2023 10:33:39 +0200 Subject: [PATCH 2744/4498] arch/x86: Remove useless legacy ACPI code ACPI is now being handled through ACPICA. Signed-off-by: Tomasz Bursztyka --- arch/x86/core/acpi.c | 448 ------------------------------------------- 1 file changed, 448 deletions(-) delete mode 100644 arch/x86/core/acpi.c diff --git a/arch/x86/core/acpi.c b/arch/x86/core/acpi.c deleted file mode 100644 index e304a54627f..00000000000 --- a/arch/x86/core/acpi.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include - -static struct acpi_rsdp *rsdp; -static bool is_rsdp_searched; - -static struct acpi_dmar *dmar; -static bool is_dmar_searched; - -static bool check_sum(struct acpi_sdt *t) -{ - uint8_t sum = 0U, *p = (uint8_t *)t; - - for (int i = 0; i < t->length; i++) { - sum += p[i]; - } - - return sum == 0U; -} - -static void find_rsdp(void) -{ - uint8_t *bda_seg, *zero_page_base; - uint64_t *search; - uintptr_t search_phys, rsdp_phys; - size_t search_length = 0U, rsdp_length; - - if (is_rsdp_searched) { - /* Looking up for RSDP has already been done */ - return; - } - - /* Let's first get it from EFI, if enabled */ - if (IS_ENABLED(CONFIG_X86_EFI)) { - rsdp_phys = (uintptr_t)efi_get_acpi_rsdp(); - if (rsdp_phys != 0UL) { - /* See at found label why this is required */ - search_length = sizeof(struct acpi_rsdp); - z_phys_map((uint8_t **)&search, rsdp_phys, search_length, 0); - rsdp = (struct acpi_rsdp *)search; - - goto found; - } - } - - /* We never identity map the NULL page, so need to map it before - * it can be accessed. - */ - z_phys_map(&zero_page_base, 0, 4096, 0); - - /* Physical (real mode!) address 0000:040e stores a (real - * mode!!) segment descriptor pointing to the 1kb Extended - * BIOS Data Area. - * - * We had to memory map this segment descriptor since it is in - * the NULL page. The remaining structures (EBDA etc) are identity - * mapped somewhere within the minefield of reserved regions in the - * first megabyte and are directly accessible. - */ - bda_seg = 0x040e + zero_page_base; - search_phys = (long)(((int)*(uint16_t *)bda_seg) << 4); - - /* Unmap after use */ - z_phys_unmap(zero_page_base, 4096); - - /* Might be nothing there, check before we inspect. - * Note that EBDA usually is in 0x80000 to 0x100000. - */ - if ((POINTER_TO_UINT(search_phys) >= 0x80000UL) && - (POINTER_TO_UINT(search_phys) < 0x100000UL)) { - search_length = 1024; - z_phys_map((uint8_t **)&search, search_phys, search_length, 0); - - for (int i = 0; i < 1024/8; i++) { - if (search[i] == ACPI_RSDP_SIGNATURE) { - rsdp_phys = search_phys + i * 8; - rsdp = (void *)&search[i]; - goto found; - } - } - - z_phys_unmap((uint8_t *)search, search_length); - } - - /* If it's not there, then look for it in the last 128kb of - * real mode memory. - */ - search_phys = 0xe0000; - search_length = 128 * 1024; - z_phys_map((uint8_t **)&search, search_phys, search_length, 0); - - for (int i = 0; i < 128*1024/8; i++) { - if (search[i] == ACPI_RSDP_SIGNATURE) { - rsdp_phys = search_phys + i * 8; - rsdp = (void *)&search[i]; - goto found; - } - } - - z_phys_unmap((uint8_t *)search, search_length); - - rsdp = NULL; - - is_rsdp_searched = true; - - return; - -found: - /* Determine length of RSDP table. - * ACPI v2 and above uses the length field. - * Otherwise, just the size of struct itself. - */ - if (rsdp->revision < 2) { - rsdp_length = sizeof(*rsdp); - } else { - rsdp_length = rsdp->length; - } - - /* Need to unmap search since it is still mapped */ - if (search_length != 0U) { - z_phys_unmap((uint8_t *)search, search_length); - } - - /* Now map the RSDP */ - z_phys_map((uint8_t **)&rsdp, rsdp_phys, rsdp_length, 0); - - is_rsdp_searched = true; -} - -void *z_acpi_find_table(uint32_t signature) -{ - uint8_t *mapped_tbl; - uint32_t length; - struct acpi_rsdt *rsdt; - struct acpi_xsdt *xsdt; - struct acpi_sdt *t; - uintptr_t t_phys; - bool tbl_found; - - find_rsdp(); - - if (!rsdp) { - return NULL; - } - - if (rsdp->rsdt_ptr != 0U) { - z_phys_map((uint8_t **)&rsdt, rsdp->rsdt_ptr, sizeof(*rsdt), 0); - tbl_found = false; - - if (check_sum(&rsdt->sdt)) { - /* Remap the memory to the indicated length of RSDT */ - length = rsdt->sdt.length; - z_phys_unmap((uint8_t *)rsdt, sizeof(*rsdt)); - z_phys_map((uint8_t **)&rsdt, rsdp->rsdt_ptr, length, 0); - - uint32_t *end = (uint32_t *)((char *)rsdt + rsdt->sdt.length); - - /* Extra indirection required to avoid - * -Waddress-of-packed-member - */ - void *table_ptrs = &rsdt->table_ptrs[0]; - - for (uint32_t *tp = table_ptrs; tp < end; tp++) { - t_phys = (long)*tp; - z_phys_map(&mapped_tbl, t_phys, sizeof(*t), 0); - t = (void *)mapped_tbl; - - if (t->signature == signature && check_sum(t)) { - tbl_found = true; - break; - } - - z_phys_unmap(mapped_tbl, sizeof(*t)); - } - } - - z_phys_unmap((uint8_t *)rsdt, sizeof(*rsdt)); - - if (tbl_found) { - goto found; - } - } - - if (rsdp->revision < 2) { - return NULL; - } - - if (rsdp->xsdt_ptr != 0ULL) { - z_phys_map((uint8_t **)&xsdt, rsdp->xsdt_ptr, sizeof(*xsdt), 0); - - tbl_found = false; - if (check_sum(&xsdt->sdt)) { - /* Remap the memory to the indicated length of RSDT */ - length = xsdt->sdt.length; - z_phys_unmap((uint8_t *)xsdt, sizeof(*xsdt)); - z_phys_map((uint8_t **)&xsdt, rsdp->xsdt_ptr, length, 0); - - uint64_t *end = (uint64_t *)((char *)xsdt + xsdt->sdt.length); - - /* Extra indirection required to avoid - * -Waddress-of-packed-member - */ - void *table_ptrs = &xsdt->table_ptrs[0]; - - for (uint64_t *tp = table_ptrs; tp < end; tp++) { - t_phys = (long)*tp; - z_phys_map(&mapped_tbl, t_phys, sizeof(*t), 0); - t = (void *)mapped_tbl; - - if (t->signature == signature && check_sum(t)) { - tbl_found = true; - break; - } - - z_phys_unmap(mapped_tbl, sizeof(*t)); - } - } - - z_phys_unmap((uint8_t *)xsdt, sizeof(*xsdt)); - - if (tbl_found) { - goto found; - } - } - - return NULL; - -found: - /* Remap to indicated length of the table */ - length = t->length; - z_phys_unmap(mapped_tbl, sizeof(*t)); - z_phys_map(&mapped_tbl, t_phys, length, 0); - t = (void *)mapped_tbl; - - return t; -} - -/* - * Return the 'n'th CPU entry from the ACPI MADT, or NULL if not available. - */ - -struct acpi_cpu *z_acpi_get_cpu(int n) -{ - struct acpi_madt *madt = z_acpi_find_table(ACPI_MADT_SIGNATURE); - uintptr_t base = POINTER_TO_UINT(madt); - uintptr_t offset; - - if (!madt) { - return NULL; - } - - offset = POINTER_TO_UINT(madt->entries) - base; - - while (offset < madt->sdt.length) { - struct acpi_madt_entry *entry; - - entry = (struct acpi_madt_entry *)(offset + base); - if (entry->type == ACPI_MADT_ENTRY_CPU) { - struct acpi_cpu *cpu = (struct acpi_cpu *)entry; - - if ((cpu->flags & ACPI_CPU_FLAGS_ENABLED) != 0) { - if (n == 0) { - return cpu; - } - - --n; - } - } - - offset += entry->length; - } - - return NULL; -} - -static void find_dmar(void) -{ - if (is_dmar_searched) { - return; - } - - dmar = z_acpi_find_table(ACPI_DMAR_SIGNATURE); - is_dmar_searched = true; -} - -struct acpi_dmar *z_acpi_find_dmar(void) -{ - find_dmar(); - return dmar; -} - -struct acpi_drhd *z_acpi_find_drhds(int *n) -{ - struct acpi_drhd *drhds = NULL; - uintptr_t offset; - uintptr_t base; - - find_dmar(); - - if (dmar == NULL) { - return NULL; - } - - *n = 0; - base = POINTER_TO_UINT(dmar); - - offset = POINTER_TO_UINT(dmar->remap_entries) - base; - while (offset < dmar->sdt.length) { - struct acpi_dmar_entry *entry; - - entry = (struct acpi_dmar_entry *)(offset + base); - if (entry->type == ACPI_DMAR_TYPE_DRHD) { - if (*n == 0) { - drhds = (struct acpi_drhd *)entry; - } - - (*n)++; - } else { - /* DMAR entries are found packed by type so - * if type is not DRHD, we will not encounter one, - * anymore. - */ - break; - } - - offset += entry->length; - } - - return drhds; -} - -struct acpi_dmar_dev_scope *z_acpi_get_drhd_dev_scopes(struct acpi_drhd *drhd, - int *n) -{ - uintptr_t offset; - uintptr_t base; - - if (drhd->entry.length <= ACPI_DRHD_MIN_SIZE) { - return NULL; - } - - *n = 0; - base = POINTER_TO_UINT(drhd); - - offset = POINTER_TO_UINT(drhd->device_scope) - base; - while (offset < drhd->entry.length) { - struct acpi_dmar_dev_scope *dev_scope; - - dev_scope = (struct acpi_dmar_dev_scope *)(offset + base); - - (*n)++; - - offset += dev_scope->length; - } - - return (*n == 0) ? NULL : drhd->device_scope; -} - -struct acpi_dmar_dev_path * -z_acpi_get_dev_scope_paths(struct acpi_dmar_dev_scope *dev_scope, int *n) -{ - switch (dev_scope->type) { - case ACPI_DRHD_DEV_SCOPE_PCI_EPD: - /* Fall through */ - case ACPI_DRHD_DEV_SCOPE_PCI_SUB_H: - /* Fall through */ - case ACPI_DRHD_DEV_SCOPE_IOAPIC: - if (dev_scope->length < (ACPI_DMAR_DEV_SCOPE_MIN_SIZE + - ACPI_DMAR_DEV_PATH_SIZE)) { - return NULL; - } - - break; - case ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET: - /* Fall through */ - case ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV: - if (dev_scope->length != (ACPI_DMAR_DEV_SCOPE_MIN_SIZE + - ACPI_DMAR_DEV_PATH_SIZE)) { - return NULL; - } - - break; - default: - return NULL; - } - - *n = (dev_scope->length - ACPI_DMAR_DEV_SCOPE_MIN_SIZE) / - ACPI_DMAR_DEV_PATH_SIZE; - - return dev_scope->path; -} - -uint16_t z_acpi_get_dev_id_from_dmar(uint8_t dev_scope_type) -{ - struct acpi_drhd *drhd; - int n_drhd; - - find_dmar(); - - if (dmar == NULL) { - return USHRT_MAX; - } - - drhd = z_acpi_find_drhds(&n_drhd); - - for (; n_drhd > 0; n_drhd--) { - struct acpi_dmar_dev_scope *dev_scope; - int n_ds; - - dev_scope = z_acpi_get_drhd_dev_scopes(drhd, &n_ds); - for (; n_ds > 0; n_ds--) { - if (dev_scope->type == dev_scope_type) { - struct acpi_dmar_dev_path *path; - int n_path; - - path = z_acpi_get_dev_scope_paths(dev_scope, - &n_path); - if (n_path > 0) { - union acpi_dmar_id id; - - /* Let's over simplify for now: - * we don't look for secondary bus - * and extra paths. We just stop here. - */ - - id.bits.bus = dev_scope->start_bus_num; - id.bits.device = path->device; - id.bits.function = path->function; - - return id.raw; - } - } - - dev_scope = (struct acpi_dmar_dev_scope *)( - POINTER_TO_UINT(dev_scope) + dev_scope->length); - } - - drhd = (struct acpi_drhd *)(POINTER_TO_UINT(drhd) + - drhd->entry.length); - } - - return USHRT_MAX; -} From 7b2cb95cd5c73045a5b5efe645afa293db836b2c Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 27 Oct 2023 12:47:00 +0200 Subject: [PATCH 2745/4498] tests/x86: Reverting back to old logic It was simpler, and it worked: it counted the cpu number correctly. Signed-off-by: Tomasz Bursztyka --- tests/arch/x86/info/src/acpi.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/arch/x86/info/src/acpi.c b/tests/arch/x86/info/src/acpi.c index 4271710ba22..eae7d560c7d 100644 --- a/tests/arch/x86/info/src/acpi.c +++ b/tests/arch/x86/info/src/acpi.c @@ -120,29 +120,21 @@ static void vtd_info(void) void acpi(void) { - int nr_cpus = 0, i, inst_cnt; - struct acpi_madt_local_apic *lapic; + int nr_cpus; - if (acpi_madt_entry_get(ACPI_MADT_TYPE_LOCAL_APIC, (ACPI_SUBTABLE_HEADER **)&lapic, - &inst_cnt)) { - printk("error on get MAD table\n"); - return; - } - - /* count number of CPUs present which are enabled*/ - for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { - if (lapic[i].LapicFlags & 1u) { - nr_cpus++; - } + for (nr_cpus = 0; acpi_local_apic_get(nr_cpus); ++nr_cpus) { + /* count number of CPUs present */ } if (nr_cpus == 0) { printk("ACPI: no RSDT/MADT found\n\n"); } else { - printk("ACPI: %d CPUs found\n", nr_cpus); + printk("ACPI: %d CPU%s found\n", nr_cpus, nr_cpus == 1 ? "" : "s"); + + for (int i = 0; i < nr_cpus; ++i) { + struct acpi_madt_local_apic *cpu = acpi_local_apic_get(i); - for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; ++i) { - printk("\tCPU #%d: APIC ID 0x%02x\n", i, lapic[i].Id); + printk("\tCPU #%d: APIC ID 0x%02x\n", i, cpu[i].Id); } } From 3e4c50b0ef6118646fc8704ef94078f309444e4d Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 26 Oct 2023 19:46:06 +0300 Subject: [PATCH 2746/4498] Revert "drivers: intel: ssp: Revise receive FIFO draining" This reverts commit 97bb67d66cd7461b8cbc7fb72c4b6773013d6dd4. The revised FIFO draining seems to cause failures due to channel shift with Intel MTL platform. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/ssp/ssp.c | 89 +++++++++++-------------------------- 1 file changed, 25 insertions(+), 64 deletions(-) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index b39442b0011..809cc9833eb 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -837,73 +837,36 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) } } -static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) -{ - uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; - uint32_t i, sssr; - - sssr = sys_read32(dai_base(dp) + SSSR); - - if (sssr & SSSR_ROR) { - /* The RX FIFO is in overflow condition, empty it */ - for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++) - sys_read32(dai_base(dp) + SSDR); - - /* Clear the overflow status */ - dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); - /* Re-read the SSSR register */ - sssr = sys_read32(dai_base(dp) + SSSR); - } - - while ((sssr & SSSR_RNE) && retry--) { - uint32_t entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); - - /* Empty the RX FIFO (the DMA is not running at this point) */ - for (i = 0; i < entries + 1; i++) - sys_read32(dai_base(dp) + SSDR); - - sssr = sys_read32(dai_base(dp) + SSSR); - } -} - -static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) +/* empty SSP receive FIFO */ +static void dai_ssp_empty_rx_fifo(struct dai_intel_ssp *dp) { struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp); - uint64_t sample_ticks = ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0; uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; - uint32_t entries[2]; - uint32_t i, sssr; + uint32_t entries; + uint32_t i; - sssr = sys_read32(dai_base(dp) + SSSR); - entries[0] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); - - while ((sssr & SSSR_RNE) && retry--) { - /* Wait one sample time */ - k_busy_wait(sample_ticks); - - entries[1] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); - sssr = sys_read32(dai_base(dp) + SSSR); - - if (entries[0] > entries[1]) { - /* - * The DMA is reading the FIFO, check the status in the - * next loop - */ - entries[0] = entries[1]; - } else if (!(sssr & SSSR_RFS)) { - /* - * The DMA request is not asserted, read the FIFO - * directly, otherwise let the next loop iteration to - * check the status - */ - for (i = 0; i < entries[1] + 1; i++) - sys_read32(dai_base(dp) + SSDR); + /* + * To make sure all the RX FIFO entries are read out for the flushing, + * we need to wait a minimal SSP port delay after entries are all read, + * and then re-check to see if there is any subsequent entries written + * to the FIFO. This will help to make sure there is no sample mismatched + * issue for the next run with the SSP RX. + */ + while ((sys_read32(dai_base(dp) + SSSR) & SSSR_RNE) && retry--) { + entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); + LOG_DBG("%s before flushing, entries %d", __func__, entries); + for (i = 0; i < entries + 1; i++) { + /* read to try empty fifo */ + sys_read32(dai_base(dp) + SSDR); } - sssr = sys_read32(dai_base(dp) + SSSR); + /* wait to get valid fifo status and re-check */ + k_busy_wait(ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0); + entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); + LOG_DBG("%s after flushing, entries %d", __func__, entries); } - /* Just in case clear the overflow status */ + /* clear interrupt */ dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); } @@ -1938,10 +1901,6 @@ static void dai_ssp_early_start(struct dai_intel_ssp *dp, int direction) key = k_spin_lock(&dp->lock); - /* RX fifo must be cleared before start */ - if (direction == DAI_DIR_CAPTURE) - ssp_empty_rx_fifo_on_start(dp); - /* request mclk/bclk */ dai_ssp_pre_start(dp); @@ -2022,7 +1981,7 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_CAPTURE && ssp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0); - ssp_empty_rx_fifo_on_stop(dp); + dai_ssp_empty_rx_fifo(dp); ssp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; LOG_INF("%s RX stop", __func__); } @@ -2200,6 +2159,8 @@ static int dai_ssp_probe(struct dai_intel_ssp *dp) /* Disable dynamic clock gating before touching any register */ dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, dp->index); + dai_ssp_empty_rx_fifo(dp); + return 0; } From 460c2167e4f3f6489ff0d3f519466a5682d8146b Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 26 Oct 2023 19:46:14 +0300 Subject: [PATCH 2747/4498] Revert "drivers: intel: ssp: Correct FIFO depth value for CAVS25 platforms" This reverts commit d75127caa4ae1db13ed5111b0327216cc94501e2. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/ssp/ssp.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index 4f08553c91f..1d37b9a3335 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -29,11 +29,7 @@ #define DAI_INTEL_SSP_DEFAULT_IDX 1 /* the SSP port fifo depth */ -#if (CONFIG_BOARD_INTEL_ADSP_CAVS25 || CONFIG_BOARD_INTEL_ADSP_CAVS25_TGPH) -#define DAI_INTEL_SSP_FIFO_DEPTH 32 -#else #define DAI_INTEL_SSP_FIFO_DEPTH 16 -#endif /* the watermark for the SSP fifo depth setting */ #define DAI_INTEL_SSP_FIFO_WATERMARK 8 From d0961756a62aa45b6f630f7e0a10fdf458360572 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Thu, 21 Sep 2023 15:47:13 -0400 Subject: [PATCH 2748/4498] drivers: watchdog: Add xmc4xxx support Adds watchdog support for Infineon xmc4xxx MCUs. Signed-off-by: Andriy Gelman --- boards/arm/xmc45_relax_kit/doc/index.rst | 2 + .../arm/xmc45_relax_kit/xmc45_relax_kit.dts | 1 + .../arm/xmc45_relax_kit/xmc45_relax_kit.yaml | 1 + boards/arm/xmc47_relax_kit/doc/index.rst | 2 + .../arm/xmc47_relax_kit/xmc47_relax_kit.dts | 1 + .../arm/xmc47_relax_kit/xmc47_relax_kit.yaml | 1 + drivers/watchdog/CMakeLists.txt | 1 + drivers/watchdog/Kconfig | 2 + drivers/watchdog/Kconfig.xmc4xxx | 22 +++ drivers/watchdog/wdt_xmc4xxx.c | 184 ++++++++++++++++++ dts/arm/infineon/xmc4xxx.dtsi | 7 + .../watchdog/infineon,xmc4xxx-watchdog.yaml | 15 ++ modules/Kconfig.infineon | 5 + .../watchdog/boards/xmc45_relax_kit.overlay | 9 + .../watchdog/boards/xmc47_relax_kit.overlay | 9 + soc/arm/infineon_xmc/4xxx/Kconfig.series | 1 + .../boards/xmc45_relax_kit.overlay | 9 + .../boards/xmc47_relax_kit.overlay | 9 + 18 files changed, 281 insertions(+) create mode 100644 drivers/watchdog/Kconfig.xmc4xxx create mode 100644 drivers/watchdog/wdt_xmc4xxx.c create mode 100644 dts/bindings/watchdog/infineon,xmc4xxx-watchdog.yaml create mode 100644 samples/drivers/watchdog/boards/xmc45_relax_kit.overlay create mode 100644 samples/drivers/watchdog/boards/xmc47_relax_kit.overlay create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/xmc45_relax_kit.overlay create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/xmc47_relax_kit.overlay diff --git a/boards/arm/xmc45_relax_kit/doc/index.rst b/boards/arm/xmc45_relax_kit/doc/index.rst index 17669cedcbe..7a54abfe37a 100644 --- a/boards/arm/xmc45_relax_kit/doc/index.rst +++ b/boards/arm/xmc45_relax_kit/doc/index.rst @@ -55,6 +55,8 @@ The Relax Kit development board configuration supports the following hardware fe +-----------+------------+-----------------------+ | PWM | on-chip | pwm | +-----------+------------+-----------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-----------------------+ More details about the supported peripherals are available in `XMC4500 TRM`_ Other hardware features are not currently supported by the Zephyr kernel. diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts index ec05ae1aa78..cebeb2deffe 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts @@ -22,6 +22,7 @@ led0 = &led1; die-temp0 = &die_temp; pwm-led0 = &pwm_led1; + watchdog0 = &wdt0; }; leds { diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml index 520632af5c6..b84e29973a7 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.yaml @@ -12,6 +12,7 @@ supported: - gpio - spi - uart + - watchdog ram: 160 flash: 1024 vendor: infineon diff --git a/boards/arm/xmc47_relax_kit/doc/index.rst b/boards/arm/xmc47_relax_kit/doc/index.rst index fea191f4c30..cbf5eb7a5f3 100644 --- a/boards/arm/xmc47_relax_kit/doc/index.rst +++ b/boards/arm/xmc47_relax_kit/doc/index.rst @@ -58,6 +58,8 @@ The Relax Kit development board configuration supports the following hardware fe +-----------+------------+-----------------------+ | PWM | on-chip | pwm | +-----------+------------+-----------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-----------------------+ More details about the supported peripherals are available in `XMC4700 TRM`_ Other hardware features are not currently supported by the Zephyr kernel. diff --git a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts index 71f6ce2d536..7f1b8f68a38 100644 --- a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts +++ b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts @@ -21,6 +21,7 @@ led0 = &led1; die-temp0 = &die_temp; pwm-led0 = &pwm_led1; + watchdog0 = &wdt0; }; leds { diff --git a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml index 61ab8ca25c4..d88826ab4ef 100644 --- a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml +++ b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.yaml @@ -14,6 +14,7 @@ supported: - uart - arduino_spi - arduino_serial + - watchdog ram: 352 flash: 2048 vendor: infineon diff --git a/drivers/watchdog/CMakeLists.txt b/drivers/watchdog/CMakeLists.txt index e72f3683c06..7f58a5461a9 100644 --- a/drivers/watchdog/CMakeLists.txt +++ b/drivers/watchdog/CMakeLists.txt @@ -39,6 +39,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_XILINX_AXI wdt_xilinx_axi.c) zephyr_library_sources_ifdef(CONFIG_WDT_INFINEON_CAT1 wdt_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_WDT_OPENTITAN wdt_opentitan.c) zephyr_library_sources_ifdef(CONFIG_WDT_AMBIQ wdt_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_WDT_XMC4XXX wdt_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c wdt_dw_common.c) zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 2049d78faa0..2ee5545f39e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -120,4 +120,6 @@ source "drivers/watchdog/Kconfig.ambiq" source "drivers/watchdog/Kconfig.shell" +source "drivers/watchdog/Kconfig.xmc4xxx" + endif # WATCHDOG diff --git a/drivers/watchdog/Kconfig.xmc4xxx b/drivers/watchdog/Kconfig.xmc4xxx new file mode 100644 index 00000000000..8c18d06da0d --- /dev/null +++ b/drivers/watchdog/Kconfig.xmc4xxx @@ -0,0 +1,22 @@ +# Infineon XMC4xxx WDT configuration + +# Copyright (C) 2023 SLB +# SPDX-License-Identifier: Apache-2.0 + +config WDT_XMC4XXX + bool "Infineon XMC4xxx MCU Family Watchdog (WDT) Driver" + default y + depends on DT_HAS_INFINEON_XMC4XXX_WATCHDOG_ENABLED + help + Enable WDT driver for Infineon XMC4xxx MCUs. + +if WDT_XMC4XXX && !WDT_DISABLE_AT_BOOT + +config WDT_XMC4XXX_DEFAULT_TIMEOUT_MAX_MS + int "Default watchdog timeout to use at startup" + default 20000 + help + Default watchdog timeout to use if the watchdog is not disabled + at startup. + +endif diff --git a/drivers/watchdog/wdt_xmc4xxx.c b/drivers/watchdog/wdt_xmc4xxx.c new file mode 100644 index 00000000000..e038bb0d4d5 --- /dev/null +++ b/drivers/watchdog/wdt_xmc4xxx.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_xmc4xxx_watchdog + +#include +#include + +#include +#include +#include + +#include +#include + +struct wdt_xmc4xxx_dev_data { + wdt_callback_t cb; + uint8_t mode; + bool timeout_valid; + bool is_serviced; +}; + +/* When the watchdog counter rolls over, the SCU will generate a */ +/* pre-warning event which gets routed to the ISR below. If the */ +/* watchdog is not serviced, the SCU will only reset the MCU */ +/* after the second time the counter rolls over. */ +/* Hence the reset will only happen after 2*cfg->window.max have elapsed. */ +/* We could potentially manually reset the MCU, but this way the context */ +/* information (i.e. that reset happened because of a watchdog) is lost. */ + +static void wdt_xmc4xxx_isr(const struct device *dev) +{ + struct wdt_xmc4xxx_dev_data *data = dev->data; + uint32_t event = XMC_SCU_INTERUPT_GetEventStatus(); + + /* todo add interrupt controller? */ + if ((event & XMC_SCU_INTERRUPT_EVENT_WDT_WARN) == 0) { + return; + } + + /* this is a level triggered interrupt. the event must be cleared */ + XMC_SCU_INTERRUPT_ClearEventStatus(XMC_SCU_INTERRUPT_EVENT_WDT_WARN); + + data->is_serviced = false; + + if (data->cb) { + data->cb(dev, 0); + } + + /* Ensure that watchdog is serviced if RESET_NONE mode is used */ + if (data->mode == WDT_FLAG_RESET_NONE && !data->is_serviced) { + XMC_WDT_Service(); + } + + XMC_WDT_ClearAlarm(); +} + +static int wdt_xmc4xxx_disable(const struct device *dev) +{ + struct wdt_xmc4xxx_dev_data *data = dev->data; + + XMC_WDT_Stop(); + XMC_WDT_Disable(); + + data->timeout_valid = false; + + return 0; +} + +static int wdt_xmc4xxx_setup(const struct device *dev, uint8_t options) +{ + struct wdt_xmc4xxx_dev_data *data = dev->data; + + if (!data->timeout_valid) { + return -EINVAL; + } + + if ((options & WDT_OPT_PAUSE_IN_SLEEP) != 0) { + SCU_CLK->SLEEPCR &= ~XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_ENABLE_WDT; + } else { + SCU_CLK->SLEEPCR |= XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_ENABLE_WDT; + } + + if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) != 0) { + XMC_WDT_SetDebugMode(XMC_WDT_DEBUG_MODE_STOP); + } else { + XMC_WDT_SetDebugMode(XMC_WDT_DEBUG_MODE_RUN); + } + + XMC_WDT_Start(); + + return 0; +} + +static int wdt_xmc4xxx_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) +{ + XMC_WDT_CONFIG_t wdt_config = {0}; + struct wdt_xmc4xxx_dev_data *data = dev->data; + uint32_t wdt_clock; + + /* disable the watchdog if timeout was already installed */ + if (data->timeout_valid) { + wdt_xmc4xxx_disable(dev); + data->timeout_valid = false; + } + + if (cfg->window.min != 0 || cfg->window.max == 0) { + return -EINVAL; + } + + wdt_clock = XMC_SCU_CLOCK_GetWdtClockFrequency(); + + if ((uint64_t)cfg->window.max * wdt_clock / 1000 > UINT32_MAX) { + return -EINVAL; + } + + wdt_config.window_upper_bound = (uint64_t)cfg->window.max * wdt_clock / 1000; + + XMC_WDT_Init(&wdt_config); + XMC_WDT_SetDebugMode(XMC_WDT_MODE_PREWARNING); + XMC_SCU_INTERRUPT_EnableEvent(XMC_SCU_INTERRUPT_EVENT_WDT_WARN); + + if (cfg->flags == WDT_FLAG_RESET_NONE && cfg->callback == NULL) { + return -EINVAL; + } + + data->cb = cfg->callback; + data->mode = cfg->flags; + data->timeout_valid = true; + + return 0; +} + +static int wdt_xmc4xxx_feed(const struct device *dev, int channel_id) +{ + ARG_UNUSED(channel_id); + struct wdt_xmc4xxx_dev_data *data = dev->data; + + XMC_WDT_Service(); + data->is_serviced = true; + + return 0; +} + +static const struct wdt_driver_api wdt_xmc4xxx_api = { + .setup = wdt_xmc4xxx_setup, + .disable = wdt_xmc4xxx_disable, + .install_timeout = wdt_xmc4xxx_install_timeout, + .feed = wdt_xmc4xxx_feed, +}; + +static struct wdt_xmc4xxx_dev_data wdt_xmc4xxx_data; + +static void wdt_xmc4xxx_irq_config(void) +{ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), wdt_xmc4xxx_isr, + DEVICE_DT_INST_GET(0), 0); + irq_enable(DT_INST_IRQN(0)); +} + +static int wdt_xmc4xxx_init(const struct device *dev) +{ + wdt_xmc4xxx_irq_config(); + +#ifdef CONFIG_WDT_DISABLE_AT_BOOT + return 0; +#else + int ret; + const struct wdt_timeout_cfg cfg = {.window.max = CONFIG_WDT_XMC4XXX_DEFAULT_TIMEOUT_MAX_MS, + .flags = WDT_FLAG_RESET_SOC}; + + ret = wdt_xmc4xxx_install_timeout(dev, &cfg); + if (ret < 0) { + return ret; + } + + return wdt_xmc4xxx_setup(dev, WDT_OPT_PAUSE_HALTED_BY_DBG); +#endif +} +DEVICE_DT_INST_DEFINE(0, wdt_xmc4xxx_init, NULL, &wdt_xmc4xxx_data, NULL, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_xmc4xxx_api); diff --git a/dts/arm/infineon/xmc4xxx.dtsi b/dts/arm/infineon/xmc4xxx.dtsi index 54a5744be15..82845683fc6 100644 --- a/dts/arm/infineon/xmc4xxx.dtsi +++ b/dts/arm/infineon/xmc4xxx.dtsi @@ -229,6 +229,13 @@ #pwm-cells = <3>; status = "disabled"; }; + + wdt0: watchdog@50008000 { + compatible = "infineon,xmc4xxx-watchdog"; + reg = <0x50008000 0x4000>; + interrupts = <0 1>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/watchdog/infineon,xmc4xxx-watchdog.yaml b/dts/bindings/watchdog/infineon,xmc4xxx-watchdog.yaml new file mode 100644 index 00000000000..66afaa53e68 --- /dev/null +++ b/dts/bindings/watchdog/infineon,xmc4xxx-watchdog.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023, SLB +# SPDX-License-Identifier: Apache-2.0 + +description: Infineon XMC4xxx watchdog + +compatible: "infineon,xmc4xxx-watchdog" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/modules/Kconfig.infineon b/modules/Kconfig.infineon index 348305ccbf7..4147d138de3 100644 --- a/modules/Kconfig.infineon +++ b/modules/Kconfig.infineon @@ -50,4 +50,9 @@ config HAS_XMCLIB_CCU help Enable XMCLIB CCU4/CCU8 +config HAS_XMCLIB_WDT + bool + help + Enable XMCLIB WDT + endif # HAS_XMCLIB diff --git a/samples/drivers/watchdog/boards/xmc45_relax_kit.overlay b/samples/drivers/watchdog/boards/xmc45_relax_kit.overlay new file mode 100644 index 00000000000..44cc7a91cda --- /dev/null +++ b/samples/drivers/watchdog/boards/xmc45_relax_kit.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt0 { + status = "okay"; +}; diff --git a/samples/drivers/watchdog/boards/xmc47_relax_kit.overlay b/samples/drivers/watchdog/boards/xmc47_relax_kit.overlay new file mode 100644 index 00000000000..44cc7a91cda --- /dev/null +++ b/samples/drivers/watchdog/boards/xmc47_relax_kit.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt0 { + status = "okay"; +}; diff --git a/soc/arm/infineon_xmc/4xxx/Kconfig.series b/soc/arm/infineon_xmc/4xxx/Kconfig.series index 5bfdb994fe4..53312dfaf7b 100644 --- a/soc/arm/infineon_xmc/4xxx/Kconfig.series +++ b/soc/arm/infineon_xmc/4xxx/Kconfig.series @@ -20,5 +20,6 @@ config SOC_SERIES_XMC_4XXX select HAS_XMCLIB_SPI select HAS_XMCLIB_I2C select HAS_XMCLIB_CCU + select HAS_XMCLIB_WDT help Enable support for XMC 4xxx MCU series diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/xmc45_relax_kit.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/xmc45_relax_kit.overlay new file mode 100644 index 00000000000..44cc7a91cda --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/xmc45_relax_kit.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt0 { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/xmc47_relax_kit.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/xmc47_relax_kit.overlay new file mode 100644 index 00000000000..44cc7a91cda --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/xmc47_relax_kit.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt0 { + status = "okay"; +}; From 0aed42f2eeb8628f10eb8a8f7491bc3873ede5f3 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Wed, 25 Oct 2023 12:22:04 +0200 Subject: [PATCH 2749/4498] mgmt: ec_host_cmd: improve handling buffer sizes Add the len_max rx structure member to indicate maximum number of bytes possible to receive. It is needed to send information about our protocol parameters to host. Also, limit the maximum size of request/responses for backends that uses buffers provided by the handler. Signed-off-by: Dawid Niedzwiecki --- include/zephyr/mgmt/ec_host_cmd/backend.h | 7 +++++-- .../backends/ec_host_cmd_backend_espi.c | 4 ++++ .../backends/ec_host_cmd_backend_shi_ite.c | 3 ++- .../backends/ec_host_cmd_backend_shi_npcx.c | 1 + .../backends/ec_host_cmd_backend_spi_stm32.c | 16 ++++++++++++++++ .../backends/ec_host_cmd_backend_uart.c | 18 +++++++++++++++++- subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c | 2 ++ 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/zephyr/mgmt/ec_host_cmd/backend.h b/include/zephyr/mgmt/ec_host_cmd/backend.h index fe0581b092e..ed61e0e33c2 100644 --- a/include/zephyr/mgmt/ec_host_cmd/backend.h +++ b/include/zephyr/mgmt/ec_host_cmd/backend.h @@ -43,11 +43,14 @@ struct ec_host_cmd_rx_ctx { /** * Buffer to hold received data. The buffer is provided by the handler if * CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE > 0. Otherwise, the backend should provide - * the buffer on its own and overwrites @a buf pointer in the init function. + * the buffer on its own and overwrites @a buf pointer and @a len_max + * in the init function. */ uint8_t *buf; /** Number of bytes written to @a buf by backend. */ size_t len; + /** Maximum number of bytes to receive with one request packet. */ + size_t len_max; }; /** @@ -63,7 +66,7 @@ struct ec_host_cmd_tx_buf { void *buf; /** Number of bytes to write from @a buf. */ size_t len; - /** Size of @a buf. */ + /** Maximum number of bytes to send with one response packet. */ size_t len_max; }; diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_espi.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_espi.c index dd7dfa9099c..09224ffdac2 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_espi.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_espi.c @@ -114,6 +114,10 @@ static int ec_host_cmd_espi_init(const struct ec_host_cmd_backend *backend, espi_read_lpc_request(hc_espi->espi_dev, ECUSTOM_HOST_CMD_GET_PARAM_MEMORY_SIZE, &tx->len_max); + /* Set the max len for RX as the min of buffer to store data and shared memory. */ + hc_espi->rx_ctx->len_max = + MIN(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE, hc_espi->tx->len_max); + hc_espi->state = ESPI_STATE_READY_TO_RECV; return 0; diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_ite.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_ite.c index e84b7d351e3..8c11765ee82 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_ite.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_ite.c @@ -455,8 +455,9 @@ static int shi_ite_backend_init(const struct ec_host_cmd_backend *backend, data->tx = tx; rx_ctx->buf = data->in_msg; + rx_ctx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_REQUEST; tx->buf = data->out_msg + sizeof(out_preamble); - data->tx->len_max = sizeof(data->out_msg) - EC_SHI_PREAMBLE_LENGTH - EC_SHI_PAST_END_LENGTH; + data->tx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_RESPONSE; return 0; } diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_npcx.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_npcx.c index 9e4c6b08dd2..f98f3bf7584 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_npcx.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_shi_npcx.c @@ -882,6 +882,7 @@ static int shi_npcx_backend_init(const struct ec_host_cmd_backend *backend, data->tx = tx; rx_ctx->buf = data->in_msg; + rx_ctx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_REQUEST; tx->buf = data->out_msg_padded + SHI_OUT_START_PAD; tx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_RESPONSE; diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c index c4e045ac800..52ee12ea0fd 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_spi_stm32.c @@ -96,6 +96,14 @@ BUILD_ASSERT(DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_host_cmd_spi_backend), #define EC_HOST_CMD_ST_STM32_FIFO #endif /* st_stm32_spi_fifo */ +/* + * Max data size for a version 3 request/response packet. This is big enough + * to handle a request/response header, flash write offset/size, and 512 bytes + * of flash data. + */ +#define SPI_MAX_REQ_SIZE 0x220 +#define SPI_MAX_RESP_SIZE 0x220 + /* Enumeration to maintain different states of incoming request from * host */ @@ -667,6 +675,14 @@ static int ec_host_cmd_spi_init(const struct ec_host_cmd_backend *backend, hc_spi->tx->buf = (uint8_t *)hc_spi->tx->buf + sizeof(out_preamble); hc_spi->tx->len_max = hc_spi->tx->len_max - sizeof(out_preamble) - EC_SPI_PAST_END_LENGTH; + /* Limit the requset/response max sizes */ + if (hc_spi->rx_ctx->len_max > SPI_MAX_REQ_SIZE) { + hc_spi->rx_ctx->len_max = SPI_MAX_REQ_SIZE; + } + if (hc_spi->tx->len_max > SPI_MAX_RESP_SIZE) { + hc_spi->tx->len_max = SPI_MAX_RESP_SIZE; + } + ret = spi_init(hc_spi); if (ret) { return ret; diff --git a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c index 0d43c9ccd79..2e77d3f0ccd 100644 --- a/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c +++ b/subsys/mgmt/ec_host_cmd/backends/ec_host_cmd_backend_uart.c @@ -101,7 +101,15 @@ static int request_expected_size(const struct ec_host_cmd_request_header *r) } /* Timeout after receiving first byte */ -#define UART_REQ_RX_TIMEOUT K_MSEC(150) +#define UART_REQ_RX_TIMEOUT K_MSEC(150) + +/* + * Max data size for a version 3 request/response packet. This is big enough + * to handle a request/response header, flash write offset/size and 512 bytes + * of request payload or 224 bytes of response payload. + */ +#define UART_MAX_REQ_SIZE 0x220 +#define UART_MAX_RESP_SIZE 0x100 static void rx_timeout(struct k_work *work) { @@ -242,6 +250,14 @@ static int ec_host_cmd_uart_init(const struct ec_host_cmd_backend *backend, hc_uart->rx_ctx = rx_ctx; hc_uart->tx_buf = tx; + /* Limit the requset/response max sizes */ + if (hc_uart->rx_ctx->len_max > UART_MAX_REQ_SIZE) { + hc_uart->rx_ctx->len_max = UART_MAX_REQ_SIZE; + } + if (hc_uart->tx_buf->len_max > UART_MAX_RESP_SIZE) { + hc_uart->tx_buf->len_max = UART_MAX_RESP_SIZE; + } + k_work_init_delayable(&hc_uart->timeout_work, rx_timeout); uart_callback_set(hc_uart->uart_dev, uart_callback, hc_uart); ret = uart_rx_enable(hc_uart->uart_dev, hc_uart->rx_ctx->buf, hc_uart->rx_buf_size, 0); diff --git a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c index c8f471411e7..b8bf8cfbe6a 100644 --- a/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c +++ b/subsys/mgmt/ec_host_cmd/ec_host_cmd_handler.c @@ -47,6 +47,8 @@ static struct ec_host_cmd ec_host_cmd = { .rx_ctx = { .buf = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF, (hc_rx_buffer), (NULL)), + .len_max = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF, + (CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE), (0)), }, .tx = { .buf = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_DEF, (hc_tx_buffer), From 49f0c9f221384c50f0cecc0cc059732a82cf3b77 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 27 Oct 2023 14:13:02 +0200 Subject: [PATCH 2750/4498] samples: modules: canopennode: suggest using manifest.project-filter Suggest users to use "west config manifest.project-filter +canopennode" instead of "west config manifest.group-filter +optional" in the sample documentation to avoid pulling in unrelated, optional modules. Signed-off-by: Henrik Brix Andersen --- samples/modules/canopennode/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/modules/canopennode/README.rst b/samples/modules/canopennode/README.rst index 8d0a3f00854..50b53aab99f 100644 --- a/samples/modules/canopennode/README.rst +++ b/samples/modules/canopennode/README.rst @@ -30,7 +30,7 @@ First, ensure the optional CANopenNode module is enabled and available: .. code-block:: console - west config manifest.group-filter +optional + west config manifest.project-filter +canopennode west update canopennode Building and Running for TWR-KE18F From a6c3230b740040fa34bbc92a2524178d14ac90ae Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 14:53:02 -0700 Subject: [PATCH 2751/4498] unittest: Generate symbol for existent modules Generate ZEPHYR_{MODULE_NAME}_MODULE for existent modules for unittests as well since they may be using Zephyr modules. Fixes: 64348 Signed-off-by: Flavio Ceolin --- cmake/modules/unittest.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/unittest.cmake b/cmake/modules/unittest.cmake index 306cc879585..8853f5a5b0c 100644 --- a/cmake/modules/unittest.cmake +++ b/cmake/modules/unittest.cmake @@ -6,6 +6,9 @@ include(root) include(boards) include(arch) include(configuration_files) + +include(west) +include(zephyr_module) include(kconfig) find_package(TargetTools) From e57e7f28a94b4f5553620238c38dced5d9ee7994 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 14:55:36 -0700 Subject: [PATCH 2752/4498] Revert "Revert "modules: tinycrypt: Options only when module is available"" This reverts commit 572491ab950034e3a12427d6a0b1ef23bcb1eca1. Signed-off-by: Flavio Ceolin --- modules/Kconfig.tinycrypt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/Kconfig.tinycrypt b/modules/Kconfig.tinycrypt index 7f279fbc59a..168e05ed799 100644 --- a/modules/Kconfig.tinycrypt +++ b/modules/Kconfig.tinycrypt @@ -3,8 +3,12 @@ # Copyright (c) 2015 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_TINYCRYPT_MODULE + bool + config TINYCRYPT bool "TinyCrypt Support" + depends on ZEPHYR_TINYCRYPT_MODULE help This option enables the TinyCrypt cryptography library. From fffe0b9fadd6271b932fd8e382eff7be3c9b3c13 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Wed, 25 Oct 2023 12:33:23 +0200 Subject: [PATCH 2753/4498] twister: pytest: Parametrize scope of the dut fixture Added pytest_dut_scope keyword under harness_config section. New keyword is used to determine the scope of dut and shell fixtures in pytest-twister-harness plugin. Signed-off-by: Grzegorz Chwierut --- doc/develop/test/pytest.rst | 9 +++++++-- doc/develop/test/twister.rst | 5 +++++ .../src/twister_harness/fixtures.py | 13 +++++++++---- .../src/twister_harness/plugin.py | 5 +++++ scripts/pylib/twister/twisterlib/harness.py | 5 ++++- scripts/schemas/twister/testsuite-schema.yaml | 8 ++++++++ .../pytest_integration/test_harness_pytest.py | 19 +++++++++++++++++++ 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index d0fad4d6be6..087c45bcce8 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -69,6 +69,9 @@ DUT (initialize logging, flash device, connect serial etc). This fixture yields a device prepared according to the requested type (native posix, qemu, hardware, etc.). All types of devices share the same API. This allows for writing tests which are device-type-agnostic. +Scope of this fixture is determined by the ``pytest_dut_scope`` +keyword placed under ``harness_config`` section. + .. code-block:: python @@ -81,8 +84,10 @@ shell ----- Provide an object with methods used to interact with shell application. -It calls `wait_for_promt` method, to not start scenario until DUT is ready. -Note that it uses `dut` fixture, so `dut` can be skipped when `shell` is used. +It calls ``wait_for_promt`` method, to not start scenario until DUT is ready. +Note that it uses ``dut`` fixture, so ``dut`` can be skipped when ``shell`` is used. +Scope of this fixture is determined by the ``pytest_dut_scope`` +keyword placed under ``harness_config`` section. .. code-block:: python diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index ddccee908eb..14cffac9e50 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -514,6 +514,11 @@ harness_config: pytest_args: (default empty) Specify a list of additional arguments to pass to ``pytest``. + pytest_dut_scope: (default function) + The scope for which ``dut`` and ``shell`` pytest fixtures are shared. + If the scope is set to ``function``, DUT is launched for every test case + in python script. For ``session`` scope, DUT is launched only once. + robot_test_path: (default empty) Specify a path to a file containing a Robot Framework test suite to be run. diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py index e2e82674ada..f2b1b53706c 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py @@ -36,11 +36,16 @@ def device_object(twister_harness_config: TwisterHarnessConfig) -> Generator[Dev device_object.close() -@pytest.fixture(scope='function') +def determine_scope(fixture_name, config): + if dut_scope := config.getoption("--dut-scope", None): + return dut_scope + return 'function' + + +@pytest.fixture(scope=determine_scope) def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generator[DeviceAdapter, None, None]: """Return launched device - with run application.""" - test_name = request.node.name - device_object.initialize_log_files(test_name) + device_object.initialize_log_files(request.node.name) try: device_object.launch() yield device_object @@ -48,7 +53,7 @@ def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generat device_object.close() -@pytest.fixture(scope='function') +@pytest.fixture(scope=determine_scope) def shell(dut: DeviceAdapter) -> Shell: """Return ready to use shell interface""" shell = Shell(dut, timeout=20.0) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index 076d36d4cc9..dbd3465aba1 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -100,6 +100,11 @@ def pytest_addoption(parser: pytest.Parser): metavar='PATH', help='Script executed after closing serial connection.' ) + twister_harness_group.addoption( + '--dut-scope', + choices=('function', 'class', 'module', 'package', 'session'), + help='The scope for which `dut` and `shell` fixtures are shared.' + ) def pytest_configure(config: pytest.Config): diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 55525076f8f..f5079f62c1f 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -268,6 +268,7 @@ def generate_command(self): config = self.instance.testsuite.harness_config pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] pytest_args = config.get('pytest_args', []) if config else [] + pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None command = [ 'pytest', '--twister-harness', @@ -281,6 +282,8 @@ def generate_command(self): command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) command.extend(pytest_args) + if pytest_dut_scope: + command.append(f'--dut-scope={pytest_dut_scope}') handler: Handler = self.instance.handler @@ -427,7 +430,7 @@ def _parse_report_file(self, report): self.instance.execution_time = float(elem_ts.get('time')) for elem_tc in elem_ts.findall('testcase'): - tc = self.instance.get_case_or_create(f"{self.id}.{elem_tc.get('name')}") + tc = self.instance.add_testcase(f"{self.id}.{elem_tc.get('name')}") tc.duration = float(elem_tc.get('time')) elem = elem_tc.find('*') if elem is None: diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 96a121767a5..1e198173c72 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -104,6 +104,10 @@ mapping: required: false sequence: - type: str + "pytest_dut_scope": + type: str + enum: ["function", "class", "module", "package", "session"] + required: false "regex": type: seq required: false @@ -304,6 +308,10 @@ mapping: required: false sequence: - type: str + "pytest_dut_scope": + type: str + enum: ["function", "class", "module", "package", "session"] + required: false "regex": type: seq required: false diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index e1b27a0cf02..ab4baf88656 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -48,6 +48,25 @@ def test_pytest_command(testinstance: TestInstance, device_type): assert c in command +def test_pytest_command_dut_scope(testinstance: TestInstance): + pytest_harness = Pytest() + dut_scope = 'session' + testinstance.testsuite.harness_config['pytest_dut_scope'] = dut_scope + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + assert f'--dut-scope={dut_scope}' in command + + +def test_pytest_command_extra_args(testinstance: TestInstance): + pytest_harness = Pytest() + pytest_args = ['-k test1', '-m mark1'] + testinstance.testsuite.harness_config['pytest_args'] = pytest_args + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + for c in pytest_args: + assert c in command + + @pytest.mark.parametrize( ('pytest_root', 'expected'), [ From 2235a8253bdda4642e863849351576701931fac4 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Thu, 5 Oct 2023 11:47:11 +0200 Subject: [PATCH 2754/4498] scripts: tests: twister: runner test expansion Creates a few dozen new tests that cover every runner.py method. 99% coverage (All statements save for one) is achieved. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_runner.py | 2512 +++++++++++++++++++++++++- 1 file changed, 2510 insertions(+), 2 deletions(-) diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 37c02b6d17b..b008793ef77 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -6,19 +6,34 @@ Tests for runner.py classes """ +import errno import mock import os +import pathlib import pytest +import queue +import re +import subprocess import sys import yaml +from contextlib import nullcontext +from elftools.elf.sections import SymbolTableSection from typing import List ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) -from twisterlib.runner import ProjectBuilder +from twisterlib.error import BuildError +from twisterlib.harness import Pytest +from twisterlib.runner import ( + CMake, + ExecutionCounter, + FilterBuilder, + ProjectBuilder, + TwisterRunner +) @pytest.fixture def mocked_instance(tmp_path): @@ -78,7 +93,7 @@ def runners(project_builder: ProjectBuilder) -> dict: @mock.patch("os.path.exists") -def test_projectbuilder_cmake_assemble_args(m): +def test_projectbuilder_cmake_assemble_args_single(m): # Causes the additional_overlay_path to be appended m.return_value = True @@ -164,3 +179,2496 @@ def test_if_zephyr_base_is_sanitized_properly(project_builder: ProjectBuilder): with open(cmakecache_file_path, 'r') as file: sanitized_path = file.read() assert sanitized_path == sanitized_path_expected + + +def test_executioncounter(capfd): + ec = ExecutionCounter(total=12) + + ec.cases = 25 + ec.skipped_cases = 6 + ec.error = 2 + ec.iteration = 2 + ec.done = 9 + ec.passed = 6 + ec.skipped_configs = 3 + ec.skipped_runtime = 1 + ec.skipped_filter = 2 + ec.failed = 1 + + ec.summary() + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert ( + f'--------------------------------\n' + f'Total test suites: 12\n' + f'Total test cases: 25\n' + f'Executed test cases: 19\n' + f'Skipped test cases: 6\n' + f'Completed test suites: 9\n' + f'Passing test suites: 6\n' + f'Failing test suites: 1\n' + f'Skipped test suites: 3\n' + f'Skipped test suites (runtime): 1\n' + f'Skipped test suites (filter): 2\n' + f'Errors: 2\n' + f'--------------------------------' + ) in out + + assert ec.cases == 25 + assert ec.skipped_cases == 6 + assert ec.error == 2 + assert ec.iteration == 2 + assert ec.done == 9 + assert ec.passed == 6 + assert ec.skipped_configs == 3 + assert ec.skipped_runtime == 1 + assert ec.skipped_filter == 2 + assert ec.failed == 1 + + +def test_cmake_parse_generated(mocked_jobserver): + testsuite_mock = mock.Mock() + platform_mock = mock.Mock() + source_dir = os.path.join('source', 'dir') + build_dir = os.path.join('build', 'dir') + + cmake = CMake(testsuite_mock, platform_mock, source_dir, build_dir, + mocked_jobserver) + + result = cmake.parse_generated() + + assert cmake.defconfig == {} + assert result == {} + + +TESTDATA_1_1 = [ + ('linux'), + ('nt') +] +TESTDATA_1_2 = [ + (0, False, 'dummy out', + True, True, True, True, 'passed', None, False, True), + (0, True, '', + False, False, False, False, 'passed', None, False, False), + (1, True, 'ERROR: region `FLASH\' overflowed by 123 MB', + False, True, True, True, 'skipped', 'FLASH overflow', True, False), + (1, True, 'Error: Image size (99 B) + trailer (1 B) exceeds requested size', + False, True, True, True, 'skipped', 'imgtool overflow', True, False), + (1, True, 'mock.ANY', + False, True, True, True, 'error', 'Build failure', False, False) +] + +@pytest.mark.parametrize( + 'return_code, is_instance_run, p_out, expect_msg, expect_returncode,' \ + ' expect_instance, expect_writes, expected_status, expected_reason,' \ + ' expected_change_skip, expected_add_missing', + TESTDATA_1_2, + ids=['no error, no instance run', 'no error, instance run', + 'error - region overflow', 'error - image size exceed', 'error'] +) +@pytest.mark.parametrize('sys_platform', TESTDATA_1_1) +def test_cmake_run_build( + sys_platform, + return_code, + is_instance_run, + p_out, + expect_msg, + expect_returncode, + expect_instance, + expect_writes, + expected_status, + expected_reason, + expected_change_skip, + expected_add_missing +): + process_mock = mock.Mock( + returncode=return_code, + communicate=mock.Mock( + return_value=(p_out.encode(sys.getdefaultencoding()), None) + ) + ) + + def mock_popen(*args, **kwargs): + return process_mock + + testsuite_mock = mock.Mock() + platform_mock = mock.Mock() + platform_mock.name = '' + source_dir = os.path.join('source', 'dir') + build_dir = os.path.join('build', 'dir') + jobserver_mock = mock.Mock( + popen=mock.Mock(side_effect=mock_popen) + ) + instance_mock = mock.Mock(add_missing_case_status=mock.Mock()) + instance_mock.run = is_instance_run + instance_mock.status = None + instance_mock.reason = None + + cmake = CMake(testsuite_mock, platform_mock, source_dir, build_dir, + jobserver_mock) + cmake.cwd = os.path.join('dummy', 'working', 'dir') + cmake.instance = instance_mock + cmake.options = mock.Mock() + cmake.options.overflow_as_errors = False + + cmake_path = os.path.join('dummy', 'cmake') + + popen_mock = mock.Mock(side_effect=mock_popen) + change_mock = mock.Mock() + + with mock.patch('sys.platform', sys_platform), \ + mock.patch('shutil.which', return_value=cmake_path), \ + mock.patch('twisterlib.runner.change_skip_to_error_if_integration', + change_mock), \ + mock.patch('builtins.open', mock.mock_open()), \ + mock.patch('subprocess.Popen', popen_mock): + result = cmake.run_build(args=['arg1', 'arg2']) + + expected_results = {} + if expect_msg: + expected_results['msg'] = 'Finished building %s for %s' % \ + (os.path.join('source', 'dir'), \ + '') + if expect_returncode: + expected_results['returncode'] = return_code + if expect_instance: + expected_results['instance'] = instance_mock + if expected_results == {}: + expected_results = None + + assert expected_results == result + + popen_caller = cmake.jobserver.popen if sys_platform == 'linux' else \ + popen_mock + popen_caller.assert_called_once_with( + [os.path.join('dummy', 'cmake'), 'arg1', 'arg2'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=os.path.join('dummy', 'working', 'dir') + ) + + assert cmake.instance.status == expected_status + assert cmake.instance.reason == expected_reason + + if expected_change_skip: + change_mock.assert_called_once() + + if expected_add_missing: + cmake.instance.add_missing_case_status.assert_called_once_with( + 'skipped', 'Test was built only' + ) + + +TESTDATA_2_1 = [ + ('linux'), + ('nt') +] +TESTDATA_2_2 = [ + (True, ['dummy_stage_1', 'ds2'], + 0, False, '', + True, False, True, False, + None, None, + [os.path.join('dummy', 'cmake'), + '-B' + os.path.join('build', 'dir'), '-DTC_RUNID=1', + '-DCONFIG_COMPILER_WARNINGS_AS_ERRORS=y', + '-DEXTRA_GEN_DEFINES_ARGS=--edtlib-Werror', '-Gdummy_generator', + '-S' + os.path.join('source', 'dir'), + 'arg1', 'arg2', + '-DBOARD=', + '-DSNIPPET=dummy snippet 1;ds2', + '-DMODULES=dummy_stage_1,ds2', + '-Pzephyr_base/cmake/package_helper.cmake']), + (False, [], + 1, True, 'ERROR: region `FLASH\' overflowed by 123 MB', + False, True, False, True, + 'error', 'Cmake build failure', + [os.path.join('dummy', 'cmake'), + '-B' + os.path.join('build', 'dir'), '-DTC_RUNID=1', + '-DCONFIG_COMPILER_WARNINGS_AS_ERRORS=n', + '-DEXTRA_GEN_DEFINES_ARGS=', '-Gdummy_generator', + '-Szephyr_base/share/sysbuild', + '-DAPP_DIR=' + os.path.join('source', 'dir'), + 'arg1', 'arg2', + '-DBOARD=', + '-DSNIPPET=dummy snippet 1;ds2']), +] + +@pytest.mark.parametrize( + 'error_warns, f_stages,' \ + ' return_code, is_instance_run, p_out, expect_msg, expect_returncode,' \ + ' expect_filter, expect_writes, expected_status, expected_reason,' \ + ' expected_cmd', + TESTDATA_2_2, + ids=['filter_stages with success', 'no stages with error'] +) +@pytest.mark.parametrize('sys_platform', TESTDATA_2_1) +def test_cmake_run_cmake( + sys_platform, + error_warns, + f_stages, + return_code, + is_instance_run, + p_out, + expect_msg, + expect_returncode, + expect_filter, + expect_writes, + expected_status, + expected_reason, + expected_cmd +): + process_mock = mock.Mock( + returncode=return_code, + communicate=mock.Mock( + return_value=(p_out.encode(sys.getdefaultencoding()), None) + ) + ) + + def mock_popen(*args, **kwargs): + return process_mock + + testsuite_mock = mock.Mock() + testsuite_mock.sysbuild = True + platform_mock = mock.Mock() + platform_mock.name = '' + source_dir = os.path.join('source', 'dir') + build_dir = os.path.join('build', 'dir') + jobserver_mock = mock.Mock( + popen=mock.Mock(side_effect=mock_popen) + ) + instance_mock = mock.Mock(add_missing_case_status=mock.Mock()) + instance_mock.run = is_instance_run + instance_mock.run_id = 1 + instance_mock.status = None + instance_mock.reason = None + instance_mock.testsuite = mock.Mock() + instance_mock.testsuite.required_snippets = ['dummy snippet 1', 'ds2'] + instance_mock.testcases = [mock.Mock(), mock.Mock()] + instance_mock.testcases[0].status = None + instance_mock.testcases[1].status = None + + cmake = CMake(testsuite_mock, platform_mock, source_dir, build_dir, + jobserver_mock) + cmake.cwd = os.path.join('dummy', 'working', 'dir') + cmake.instance = instance_mock + cmake.options = mock.Mock() + cmake.options.disable_warnings_as_errors = not error_warns + cmake.options.overflow_as_errors = False + cmake.env = mock.Mock() + cmake.env.generator = 'dummy_generator' + + cmake_path = os.path.join('dummy', 'cmake') + + popen_mock = mock.Mock(side_effect=mock_popen) + change_mock = mock.Mock() + + with mock.patch('sys.platform', sys_platform), \ + mock.patch('shutil.which', return_value=cmake_path), \ + mock.patch('twisterlib.runner.change_skip_to_error_if_integration', + change_mock), \ + mock.patch('twisterlib.runner.canonical_zephyr_base', + 'zephyr_base'), \ + mock.patch('builtins.open', mock.mock_open()), \ + mock.patch('subprocess.Popen', popen_mock): + result = cmake.run_cmake(args=['arg1', 'arg2'], filter_stages=f_stages) + + expected_results = {} + if expect_msg: + expected_results['msg'] = 'Finished building %s for %s' % \ + (os.path.join('source', 'dir'), \ + '') + if expect_returncode: + expected_results['returncode'] = return_code + if expect_filter: + expected_results['filter'] = {} + if expected_results == {}: + expected_results = None + + assert expected_results == result + + popen_caller = cmake.jobserver.popen if sys_platform == 'linux' else \ + popen_mock + popen_caller.assert_called_once_with( + expected_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=os.path.join('dummy', 'working', 'dir') + ) + + assert cmake.instance.status == expected_status + assert cmake.instance.reason == expected_reason + + for tc in cmake.instance.testcases: + assert tc.status == cmake.instance.status + + +TESTDATA_3 = [ + ('unit_testing', [], False, True, None, True, None, True, + None, None, {}, {}, None, None, [], {}), + ( + 'other', [], True, + True, ['dummy', 'west', 'options'], True, + None, True, + os.path.join('domain', 'build', 'dir', 'zephyr', '.config'), + os.path.join('domain', 'build', 'dir', 'zephyr', 'edt.pickle'), + {'CONFIG_FOO': 'no'}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'CONFIG_FOO': 'no', 'dummy cache elem': 1}, + b'dummy edt pickle contents', + [f'Loaded sysbuild domain data from' \ + f' {os.path.join("build", "dir", "domains.yaml")}'], + {os.path.join('other', 'dummy.testsuite.name'): True} + ), + ( + 'other', ['kconfig'], True, + True, ['dummy', 'west', 'options'], True, + 'Dummy parse results', True, + os.path.join('build', 'dir', 'zephyr', '.config'), + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {'CONFIG_FOO': 'no'}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'CONFIG_FOO': 'no', 'dummy cache elem': 1}, + b'dummy edt pickle contents', + [], + {os.path.join('other', 'dummy.testsuite.name'): False} + ), + ( + 'other', ['other'], False, + False, None, True, + 'Dummy parse results', True, + None, + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {}, + {}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True}, + b'dummy edt pickle contents', + [], + {os.path.join('other', 'dummy.testsuite.name'): False} + ), + ( + 'other', ['other'], True, + False, None, True, + 'Dummy parse results', True, + None, + None, + {}, + {}, + {}, + None, + ['Sysbuild test will be skipped. West must be used for flashing.'], + {os.path.join('other', 'dummy.testsuite.name'): True} + ), + ( + 'other', ['other'], True, + False, ['--erase'], True, + 'Dummy parse results', True, + None, + None, + {}, + {}, + None, + b'dummy edt pickle contents', + ['Sysbuild test will be skipped,' \ + ' --erase is not supported with --west-flash'], + {os.path.join('other', 'dummy.testsuite.name'): True} + ), + ( + 'other', ['other'], False, + True, None, False, + 'Dummy parse results', True, + None, + None, + {}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1}, + None, + [], + {os.path.join('other', 'dummy.testsuite.name'): False} + ), + ( + 'other', ['other'], False, + True, None, True, + 'Dummy parse results', True, + None, + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1}, + b'dummy edt pickle contents', + [], + {os.path.join('other', 'dummy.testsuite.name'): False} + ), + ( + 'other', ['other'], False, + True, None, True, + None, True, + None, + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1}, + b'dummy edt pickle contents', + [], + {os.path.join('other', 'dummy.testsuite.name'): True} + ), + ( + 'other', ['other'], False, + True, None, True, + 'Dummy parse results', False, + None, + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1}, + b'dummy edt pickle contents', + [], + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1} + ), + ( + 'other', ['other'], False, + True, None, True, + SyntaxError, True, + None, + os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), + {}, + {'dummy cache elem': 1}, + {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, + 'dummy cache elem': 1}, + b'dummy edt pickle contents', + ['Failed processing testsuite.yaml'], + SyntaxError + ), +] + +@pytest.mark.parametrize( + 'platform_name, filter_stages, sysbuild,' \ + ' do_find_cache, west_flash_options, edt_exists,' \ + ' parse_results, testsuite_filter,' \ + ' expected_defconfig_path, expected_edt_pickle_path,' \ + ' expected_defconfig, expected_cmakecache, expected_filter_data,' \ + ' expected_edt,' \ + ' expected_logs, expected_return', + TESTDATA_3, + ids=['unit testing', 'domain', 'kconfig', 'no cache', + 'no west options', 'erase west flash option', 'no edt', + 'parse result', 'no parse result', 'no testsuite filter', 'parse err'] +) +def test_filterbuilder_parse_generated( + caplog, + mocked_jobserver, + platform_name, + filter_stages, + sysbuild, + do_find_cache, + west_flash_options, + edt_exists, + parse_results, + testsuite_filter, + expected_defconfig_path, + expected_edt_pickle_path, + expected_defconfig, + expected_cmakecache, + expected_filter_data, + expected_edt, + expected_logs, + expected_return +): + def mock_domains_from_file(*args, **kwargs): + dom = mock.Mock() + dom.build_dir = os.path.join('domain', 'build', 'dir') + res = mock.Mock(get_default_domain=mock.Mock(return_value=dom)) + return res + + def mock_cmakecache_from_file(*args, **kwargs): + if not do_find_cache: + raise FileNotFoundError(errno.ENOENT, 'Cache not found') + cache_elem = mock.Mock() + cache_elem.name = 'dummy cache elem' + cache_elem.value = 1 + cache = [cache_elem] + return cache + + def mock_open(filepath, type, *args, **kwargs): + if filepath == expected_defconfig_path: + rd = 'I am not a proper line\n' \ + 'CONFIG_FOO="no"' + elif filepath == expected_edt_pickle_path: + rd = b'dummy edt pickle contents' + else: + raise FileNotFoundError(errno.ENOENT, + f'File {filepath} not mocked.') + return mock.mock_open(read_data=rd)() + + def mock_parser(filter, filter_data, edt): + assert filter_data == expected_filter_data + if isinstance(parse_results, type) and \ + issubclass(parse_results, Exception): + raise parse_results + return parse_results + + def mock_pickle(datafile): + assert datafile.read() == expected_edt + return mock.Mock() + + testsuite_mock = mock.Mock() + testsuite_mock.sysbuild = 'sysbuild' if sysbuild else None + testsuite_mock.name = 'dummy.testsuite.name' + testsuite_mock.filter = testsuite_filter + platform_mock = mock.Mock() + platform_mock.name = platform_name + platform_mock.arch = 'dummy arch' + source_dir = os.path.join('source', 'dir') + build_dir = os.path.join('build', 'dir') + + fb = FilterBuilder(testsuite_mock, platform_mock, source_dir, build_dir, + mocked_jobserver) + instance_mock = mock.Mock() + fb.instance = instance_mock + fb.env = mock.Mock() + fb.env.options = mock.Mock() + fb.env.options.west_flash = west_flash_options + fb.env.options.device_testing = True + + environ_mock = {'env_dummy': True} + + with mock.patch('twisterlib.runner.Domains.from_file', + mock_domains_from_file), \ + mock.patch('twisterlib.runner.CMakeCache.from_file', + mock_cmakecache_from_file), \ + mock.patch('builtins.open', mock_open), \ + mock.patch('expr_parser.parse', mock_parser), \ + mock.patch('pickle.load', mock_pickle), \ + mock.patch('os.path.exists', return_value=edt_exists), \ + mock.patch('os.environ', environ_mock), \ + pytest.raises(expected_return) if \ + isinstance(parse_results, type) and \ + issubclass(parse_results, Exception) else nullcontext() as err: + result = fb.parse_generated(filter_stages) + + if err: + assert True + return + + assert all([log in caplog.text for log in expected_logs]) + + assert fb.defconfig == expected_defconfig + + assert fb.cmake_cache == expected_cmakecache + + assert result == expected_return + + +TESTDATA_4 = [ + (False, False, [f"see: {os.path.join('dummy', 'path', 'dummy_file.log')}"]), + (True, False, [os.path.join('dummy', 'path', 'dummy_file.log'), + 'file contents', + os.path.join('dummy', 'path', 'dummy_file.log')]), + (True, True, [os.path.join('dummy', 'path', 'dummy_file.log'), + 'Unable to read log data ([Errno 2] ERROR: dummy_file.log)', + os.path.join('dummy', 'path', 'dummy_file.log')]), +] + +@pytest.mark.parametrize( + 'inline_logs, read_exception, expected_logs', + TESTDATA_4, + ids=['basic', 'inline logs', 'inline logs+read_exception'] +) +def test_projectbuilder_log_info( + caplog, + inline_logs, + read_exception, + expected_logs +): + def mock_open(filename, *args, **kwargs): + if read_exception: + raise OSError(errno.ENOENT, f'ERROR: {os.path.basename(filename)}') + return mock.mock_open(read_data='file contents')() + + def mock_realpath(filename, *args, **kwargs): + return os.path.join('path', filename) + + def mock_abspath(filename, *args, **kwargs): + return os.path.join('dummy', filename) + + filename = 'dummy_file.log' + + with mock.patch('builtins.open', mock_open), \ + mock.patch('os.path.realpath', mock_realpath), \ + mock.patch('os.path.abspath', mock_abspath): + ProjectBuilder.log_info(filename, inline_logs) + + assert all([log in caplog.text for log in expected_logs]) + + +TESTDATA_5 = [ + (True, False, False, "Valgrind error", 0, 0, 'build_dir/valgrind.log'), + (True, False, False, "Error", 0, 0, 'build_dir/build.log'), + (False, True, False, None, 1024, 0, 'build_dir/handler.log'), + (False, True, False, None, 0, 0, 'build_dir/build.log'), + (False, False, True, None, 0, 1024, 'build_dir/device.log'), + (False, False, True, None, 0, 0, 'build_dir/build.log'), + (False, False, False, None, 0, 0, 'build_dir/build.log'), +] + +@pytest.mark.parametrize( + 'valgrind_log_exists, handler_log_exists, device_log_exists,' \ + ' instance_reason, handler_log_getsize, device_log_getsize, expected_log', + TESTDATA_5, + ids=['valgrind log', 'valgrind log unused', + 'handler log', 'handler log unused', + 'device log', 'device log unused', + 'no logs'] +) +def test_projectbuilder_log_info_file( + caplog, + mocked_jobserver, + valgrind_log_exists, + handler_log_exists, + device_log_exists, + instance_reason, + handler_log_getsize, + device_log_getsize, + expected_log +): + def mock_exists(filename, *args, **kwargs): + if filename == 'build_dir/handler.log': + return handler_log_exists + if filename == 'build_dir/valgrind.log': + return valgrind_log_exists + if filename == 'build_dir/device.log': + return device_log_exists + return False + + def mock_getsize(filename, *args, **kwargs): + if filename == 'build_dir/handler.log': + return handler_log_getsize + if filename == 'build_dir/device.log': + return device_log_getsize + return 0 + + env_mock = mock.Mock() + instance_mock = mock.Mock() + instance_mock.reason = instance_reason + instance_mock.build_dir = 'build_dir' + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + log_info_mock = mock.Mock() + + with mock.patch('os.path.exists', mock_exists), \ + mock.patch('os.path.getsize', mock_getsize), \ + mock.patch('twisterlib.runner.ProjectBuilder.log_info', log_info_mock): + pb.log_info_file(None) + + log_info_mock.assert_called_with(expected_log, mock.ANY) + + +TESTDATA_6 = [ + ( + {'op': 'filter'}, + 'failed', + 'Failed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'report', 'test': mock.ANY}, + 'failed', + 'Failed', + 0, + None + ), + ( + {'op': 'filter'}, + 'passed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'filter': { 'dummy instance name': True }}, + mock.ANY, + mock.ANY, + mock.ANY, + ['filtering dummy instance name'], + {'op': 'report', 'test': mock.ANY}, + 'filtered', + 'runtime filter', + 1, + ('skipped',) + ), + ( + {'op': 'filter'}, + 'passed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'filter': { 'another dummy instance name': True }}, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'cmake', 'test': mock.ANY}, + 'passed', + mock.ANY, + 0, + None + ), + ( + {'op': 'cmake'}, + 'error', + 'dummy error', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'report', 'test': mock.ANY}, + 'error', + 'dummy error', + 0, + None + ), + ( + {'op': 'cmake'}, + None, + mock.ANY, + mock.ANY, + mock.ANY, + True, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'report', 'test': mock.ANY}, + 'passed', + mock.ANY, + 0, + None + ), + ( + {'op': 'cmake'}, + 'success', + mock.ANY, + mock.ANY, + mock.ANY, + True, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'report', 'test': mock.ANY}, + 'success', + mock.ANY, + 0, + None + ), + ( + {'op': 'cmake'}, + 'success', + mock.ANY, + mock.ANY, + mock.ANY, + False, + mock.ANY, + mock.ANY, + mock.ANY, + {'filter': {'dummy instance name': True}}, + mock.ANY, + mock.ANY, + mock.ANY, + ['filtering dummy instance name'], + {'op': 'report', 'test': mock.ANY}, + 'filtered', + 'runtime filter', + 1, + ('skipped',) + ), + ( + {'op': 'cmake'}, + 'success', + mock.ANY, + mock.ANY, + mock.ANY, + False, + mock.ANY, + mock.ANY, + mock.ANY, + {'filter': {}}, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'build', 'test': mock.ANY}, + 'success', + mock.ANY, + 0, + None + ), + ( + {'op': 'build'}, + mock.ANY, + None, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + None, + mock.ANY, + mock.ANY, + ['build test: dummy instance name'], + {'op': 'report', 'test': mock.ANY}, + 'error', + 'Build Failure', + 0, + None + ), + ( + {'op': 'build'}, + 'skipped', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'returncode': 0}, + mock.ANY, + mock.ANY, + ['build test: dummy instance name', + 'Determine test cases for test instance: dummy instance name'], + {'op': 'gather_metrics', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 1, + ('skipped', mock.ANY) + ), + ( + {'op': 'build'}, + 'passed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'dummy': 'dummy'}, + mock.ANY, + mock.ANY, + ['build test: dummy instance name'], + {'op': 'report', 'test': mock.ANY}, + 'passed', + mock.ANY, + 0, + ('blocked', mock.ANY) + ), + ( + {'op': 'build'}, + 'success', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'returncode': 0}, + mock.ANY, + mock.ANY, + ['build test: dummy instance name', + 'Determine test cases for test instance: dummy instance name'], + {'op': 'gather_metrics', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'build'}, + 'success', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + {'returncode': 0}, + mock.ANY, + BuildError, + ['build test: dummy instance name', + 'Determine test cases for test instance: dummy instance name'], + {'op': 'report', 'test': mock.ANY}, + 'error', + 'Determine Testcases Error!', + 0, + None + ), + ( + {'op': 'gather_metrics'}, + mock.ANY, + mock.ANY, + True, + True, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'run', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'gather_metrics'}, + mock.ANY, + mock.ANY, + False, + True, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'report', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'run'}, + 'success', + 'OK', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + None, + mock.ANY, + ['run test: dummy instance name', + 'run status: dummy instance name success'], + {'op': 'report', 'test': mock.ANY, 'status': 'success', 'reason': 'OK'}, + 'success', + 'OK', + 0, + None + ), + ( + {'op': 'run'}, + 'failed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + RuntimeError, + mock.ANY, + ['run test: dummy instance name', + 'run status: dummy instance name failed', + 'RuntimeError: Pipeline Error!'], + None, + 'failed', + mock.ANY, + 0, + None + ), + ( + {'op': 'report'}, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + False, + True, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'cleanup', 'mode': 'device', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'report'}, + 'passed', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + False, + False, + 'pass', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'cleanup', 'mode': 'passed', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'report'}, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + False, + False, + 'all', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + {'op': 'cleanup', 'mode': 'all', 'test': mock.ANY}, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'report'}, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + False, + False, + 'other', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + None, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'cleanup', 'mode': 'device'}, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + None, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'cleanup', 'mode': 'passed'}, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + None, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'cleanup', 'mode': 'all'}, + mock.ANY, + 'Valgrind error', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + None, + mock.ANY, + mock.ANY, + 0, + None + ), + ( + {'op': 'cleanup', 'mode': 'all'}, + mock.ANY, + 'Cmake build failure', + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + mock.ANY, + [], + None, + mock.ANY, + mock.ANY, + 0, + None + ), +] + +@pytest.mark.parametrize( + 'message,' \ + ' instance_status, instance_reason, instance_run, instance_handler_ready,' \ + ' options_cmake_only,' \ + ' options_coverage, options_prep_artifacts, options_runtime_artifacts,' \ + ' cmake_res, build_res,' \ + ' pipeline_runtime_error, determine_testcases_build_error,' \ + ' expected_logs, resulting_message,' \ + ' expected_status, expected_reason, expected_skipped, expected_missing', + TESTDATA_6, + ids=[ + 'filter, failed', 'filter, cmake res', 'filter, no cmake res', + 'cmake, failed', 'cmake, cmake_only, no status', 'cmake, cmake_only', + 'cmake, no cmake_only, cmake res', 'cmake, no cmake_only, no cmake res', + 'build, no build res', 'build, skipped', 'build, blocked', + 'build, determine testcases', 'build, determine testcases Error', + 'gather metrics, run and ready handler', 'gather metrics', + 'run', 'run, Pipeline Runtime Error', + 'report, prep artifacts for testing', + 'report, runtime artifact cleanup pass, status passed', + 'report, runtime artifact cleanup all', 'report, no message put', + 'cleanup, device', 'cleanup, mode passed', 'cleanup, mode all', + 'cleanup, mode all, cmake build failure' + ] +) +def test_projectbuilder_process( + caplog, + mocked_jobserver, + message, + instance_status, + instance_reason, + instance_run, + instance_handler_ready, + options_cmake_only, + options_coverage, + options_prep_artifacts, + options_runtime_artifacts, + cmake_res, + build_res, + pipeline_runtime_error, + determine_testcases_build_error, + expected_logs, + resulting_message, + expected_status, + expected_reason, + expected_skipped, + expected_missing +): + def mock_pipeline_put(msg): + if isinstance(pipeline_runtime_error, type) and \ + issubclass(pipeline_runtime_error, Exception): + raise RuntimeError('Pipeline Error!') + + def mock_determine_testcases(res): + if isinstance(determine_testcases_build_error, type) and \ + issubclass(determine_testcases_build_error, Exception): + raise BuildError('Determine Testcases Error!') + + instance_mock = mock.Mock() + instance_mock.name = 'dummy instance name' + instance_mock.status = instance_status + instance_mock.reason = instance_reason + instance_mock.run = instance_run + instance_mock.handler = mock.Mock() + instance_mock.handler.ready = instance_handler_ready + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.options = mock.Mock() + pb.options.coverage = options_coverage + pb.options.prep_artifacts_for_testing = options_prep_artifacts + pb.options.runtime_artifact_cleanup = options_runtime_artifacts + pb.options.cmake_only = options_cmake_only + + pb.cmake = mock.Mock(return_value=cmake_res) + pb.build = mock.Mock(return_value=build_res) + pb.determine_testcases = mock.Mock(side_effect=mock_determine_testcases) + + pb.report_out = mock.Mock() + pb.cleanup_artifacts = mock.Mock() + pb.cleanup_device_testing_artifacts = mock.Mock() + pb.run = mock.Mock() + pb.gather_metrics = mock.Mock() + + pipeline_mock = mock.Mock(put=mock.Mock(side_effect=mock_pipeline_put)) + done_mock = mock.Mock() + lock_mock = mock.Mock( + __enter__=mock.Mock(return_value=(mock.Mock(), mock.Mock())), + __exit__=mock.Mock(return_value=None) + ) + results_mock = mock.Mock() + results_mock.skipped_runtime = 0 + + pb.process(pipeline_mock, done_mock, message, lock_mock, results_mock) + + assert all([log in caplog.text for log in expected_logs]) + + if resulting_message: + pipeline_mock.put.assert_called_with(resulting_message) + + assert pb.instance.status == expected_status + assert pb.instance.reason == expected_reason + assert results_mock.skipped_runtime == expected_skipped + + if expected_missing: + pb.instance.add_missing_case_status.assert_called_with(*expected_missing) + + +TESTDATA_7 = [ + ( + [ + 'z_ztest_unit_test__dummy_suite_name__dummy_test_name', + 'z_ztest_unit_test__dummy_suite_name__test_dummy_name', + 'no match' + ], + ['dummy_id.dummy_name', 'dummy_id.dummy_name'] + ), + ( + ['no match'], + [] + ), +] + +@pytest.mark.parametrize( + 'symbols_names, added_tcs', + TESTDATA_7, + ids=['two hits, one miss', 'nothing'] +) +def test_projectbuilder_determine_testcases( + mocked_jobserver, + symbols_names, + added_tcs +): + symbols_mock = [mock.Mock(n=name) for name in symbols_names] + for m in symbols_mock: + m.configure_mock(name=m.n) + + sections_mock = [mock.Mock(spec=SymbolTableSection)] + sections_mock[0].iter_symbols = mock.Mock(return_value=symbols_mock) + + elf_mock = mock.Mock() + elf_mock().iter_sections = mock.Mock(return_value=sections_mock) + + results_mock = mock.Mock() + + instance_mock = mock.Mock() + instance_mock.testcases = [] + instance_mock.testsuite.id = 'dummy_id' + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + with mock.patch('twisterlib.runner.ELFFile', elf_mock), \ + mock.patch('builtins.open', mock.mock_open()): + pb.determine_testcases(results_mock) + + pb.instance.add_testcase.assert_has_calls( + [mock.call(name=x) for x in added_tcs] + ) + pb.instance.testsuite.add_testcase.assert_has_calls( + [mock.call(name=x) for x in added_tcs] + ) + + +TESTDATA_8 = [ + ( + ['addition.al'], + 'dummy', + ['addition.al', '.config', 'zephyr'] + ), + ( + [], + 'all', + ['.config', 'zephyr', 'testsuite_extra.conf', 'twister'] + ), +] + +@pytest.mark.parametrize( + 'additional_keep, runtime_artifact_cleanup, expected_files', + TESTDATA_8, + ids=['additional keep', 'all cleanup'] +) +def test_projectbuilder_cleanup_artifacts( + tmpdir, + mocked_jobserver, + additional_keep, + runtime_artifact_cleanup, + expected_files +): + # tmpdir + # ┣ twister + # ┃ ┗ testsuite_extra.conf + # ┣ dummy_dir + # ┃ ┗ dummy.del + # ┣ dummy_link_dir -> zephyr + # ┣ zephyr + # ┃ ┗ .config + # ┗ addition.al + twister_dir = tmpdir.mkdir('twister') + testsuite_extra_conf = twister_dir.join('testsuite_extra.conf') + testsuite_extra_conf.write_text('dummy', 'utf-8') + + dummy_dir = tmpdir.mkdir('dummy_dir') + dummy_del = dummy_dir.join('dummy.del') + dummy_del.write_text('dummy', 'utf-8') + + zephyr = tmpdir.mkdir('zephyr') + config = zephyr.join('.config') + config.write_text('dummy', 'utf-8') + + dummy_link_dir = tmpdir.join('dummy_link_dir') + os.symlink(zephyr, dummy_link_dir) + + addition_al = tmpdir.join('addition.al') + addition_al.write_text('dummy', 'utf-8') + + instance_mock = mock.Mock() + instance_mock.build_dir = tmpdir + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.options = mock.Mock(runtime_artifact_cleanup=runtime_artifact_cleanup) + + pb.cleanup_artifacts(additional_keep) + + files_left = [p.name for p in list(pathlib.Path(tmpdir).glob('**/*'))] + + assert sorted(files_left) == sorted(expected_files) + + +def test_projectbuilder_cleanup_device_testing_artifacts( + caplog, + mocked_jobserver +): + bins = [os.path.join('zephyr', 'file.bin')] + + instance_mock = mock.Mock() + build_dir = os.path.join('build', 'dir') + instance_mock.build_dir = build_dir + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb._get_binaries = mock.Mock(return_value=bins) + pb.cleanup_artifacts = mock.Mock() + pb._sanitize_files = mock.Mock() + + pb.cleanup_device_testing_artifacts() + + assert f'Cleaning up for Device Testing {build_dir}' in caplog.text + + pb.cleanup_artifacts.assert_called_once_with( + [os.path.join('zephyr', 'file.bin'), + os.path.join('zephyr', 'runners.yaml')] + ) + pb._sanitize_files.assert_called_once() + + +TESTDATA_9 = [ + ( + None, + [], + [os.path.join('zephyr', 'zephyr.hex'), + os.path.join('zephyr', 'zephyr.bin'), + os.path.join('zephyr', 'zephyr.elf'), + os.path.join('zephyr', 'zephyr.exe')] + ), + ( + [os.path.join('dummy.bin'), os.path.join('dummy.hex')], + [os.path.join('dir2', 'dummy.elf')], + [os.path.join('zephyr', 'dummy.bin'), + os.path.join('zephyr', 'dummy.hex'), + os.path.join('dir2', 'dummy.elf')] + ), +] + +@pytest.mark.parametrize( + 'platform_binaries, runner_binaries, expected_binaries', + TESTDATA_9, + ids=['default', 'valid'] +) +def test_projectbuilder_get_binaries( + mocked_jobserver, + platform_binaries, + runner_binaries, + expected_binaries +): + instance_mock = mock.Mock() + instance_mock.platform = mock.Mock() + instance_mock.platform.binaries = platform_binaries + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb._get_binaries_from_runners = mock.Mock(return_value=runner_binaries) + + bins = pb._get_binaries() + + assert all(bin in expected_binaries for bin in bins) + assert all(bin in bins for bin in expected_binaries) + + +TESTDATA_10 = [ + (None, []), + ({'dummy': 'dummy'}, []), + ( + { + 'config': { + 'elf_file': '/absolute/path/dummy.elf', + 'bin_file': 'path/dummy.bin' + } + }, + ['/absolute/path/dummy.elf', os.path.join('zephyr', 'path/dummy.bin')] + ), +] + +@pytest.mark.parametrize( + 'runners_content, expected_binaries', + TESTDATA_10, + ids=['no file', 'no config', 'valid'] +) +def test_projectbuilder_get_binaries_from_runners( + mocked_jobserver, + runners_content, + expected_binaries +): + def mock_exists(fname): + assert fname == os.path.join('build', 'dir', 'zephyr', 'runners.yaml') + return runners_content is not None + + instance_mock = mock.Mock() + instance_mock.build_dir = os.path.join('build', 'dir') + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + with mock.patch('os.path.exists', mock_exists), \ + mock.patch('builtins.open', mock.mock_open()), \ + mock.patch('yaml.safe_load', return_value=runners_content): + bins = pb._get_binaries_from_runners() + + assert all(bin in expected_binaries for bin in bins) + assert all(bin in bins for bin in expected_binaries) + + +def test_projectbuilder_sanitize_files(mocked_jobserver): + instance_mock = mock.Mock() + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb._sanitize_runners_file = mock.Mock() + pb._sanitize_zephyr_base_from_files = mock.Mock() + + pb._sanitize_files() + + pb._sanitize_runners_file.assert_called_once() + pb._sanitize_zephyr_base_from_files.assert_called_once() + + + +TESTDATA_11 = [ + (None, None), + ('dummy: []', None), + ( +""" +config: + elf_file: relative/path/dummy.elf + hex_file: /absolute/path/build_dir/zephyr/dummy.hex +""", +""" +config: + elf_file: relative/path/dummy.elf + hex_file: dummy.hex +""" + ), +] + +@pytest.mark.parametrize( + 'runners_text, expected_write_text', + TESTDATA_11, + ids=['no file', 'no config', 'valid'] +) +def test_projectbuilder_sanitize_runners_file( + mocked_jobserver, + runners_text, + expected_write_text +): + def mock_exists(fname): + return runners_text is not None + + instance_mock = mock.Mock() + instance_mock.build_dir = '/absolute/path/build_dir' + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + with mock.patch('os.path.exists', mock_exists), \ + mock.patch('builtins.open', + mock.mock_open(read_data=runners_text)) as f: + pb._sanitize_runners_file() + + if expected_write_text is not None: + f().write.assert_called_with(expected_write_text) + else: + f().write.assert_not_called() + + +TESTDATA_12 = [ + ( + { + 'CMakeCache.txt': mock.mock_open( + read_data='canonical/zephyr/base/dummy.file: ERROR' + ) + }, + { + 'CMakeCache.txt': 'dummy.file: ERROR' + } + ), + ( + { + os.path.join('zephyr', 'runners.yaml'): mock.mock_open( + read_data='There was canonical/zephyr/base/dummy.file here' + ) + }, + { + os.path.join('zephyr', 'runners.yaml'): 'There was dummy.file here' + } + ), +] + +@pytest.mark.parametrize( + 'text_mocks, expected_write_texts', + TESTDATA_12, + ids=['CMakeCache file', 'runners.yaml file'] +) +def test_projectbuilder_sanitize_zephyr_base_from_files( + mocked_jobserver, + text_mocks, + expected_write_texts +): + build_dir_path = 'canonical/zephyr/base/build_dir/' + + def mock_exists(fname): + if not fname.startswith(build_dir_path): + return False + return fname[len(build_dir_path):] in text_mocks + + def mock_open(fname, *args, **kwargs): + if not fname.startswith(build_dir_path): + raise FileNotFoundError(errno.ENOENT, f'File {fname} not found.') + return text_mocks[fname[len(build_dir_path):]]() + + instance_mock = mock.Mock() + instance_mock.build_dir = build_dir_path + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + with mock.patch('os.path.exists', mock_exists), \ + mock.patch('builtins.open', mock_open), \ + mock.patch('twisterlib.runner.canonical_zephyr_base', + 'canonical/zephyr/base'): + pb._sanitize_zephyr_base_from_files() + + for fname, fhandler in text_mocks.items(): + fhandler().write.assert_called_with(expected_write_texts[fname]) + + +TESTDATA_13 = [ + ( + 'error', True, True, False, + ['INFO twister:runner.py:950 20/25 dummy platform' \ + ' dummy.testsuite.name' \ + ' ERROR dummy reason (cmake)'], + None + ), + ( + 'failed', False, False, False, + ['ERROR twister:runner.py:904 dummy platform' \ + ' dummy.testsuite.name' \ + ' FAILED : dummy reason'], + 'INFO - Total complete: 20/ 25 80% skipped: 3,' \ + ' failed: 3, error: 1' + ), + ( + 'skipped', True, False, False, + ['INFO twister:runner.py:950 20/25 dummy platform' \ + ' dummy.testsuite.name' \ + ' SKIPPED (dummy reason)'], + None + ), + ( + 'filtered', False, False, False, + [], + 'INFO - Total complete: 20/ 25 80% skipped: 4,' \ + ' failed: 2, error: 1' + ), + ( + 'passed', True, False, True, + ['INFO twister:runner.py:950 20/25 dummy platform' \ + ' dummy.testsuite.name' \ + ' PASSED' \ + ' (dummy handler type: dummy dut, 60.000s)'], + None + ), + ( + 'passed', True, False, False, + ['INFO twister:runner.py:950 20/25 dummy platform' \ + ' dummy.testsuite.name' \ + ' PASSED (build)'], + None + ), + ( + 'unknown status', False, False, False, + ['Unknown status = unknown status'], + 'INFO - Total complete: 20/ 25 80% skipped: 3,' \ + ' failed: 2, error: 1\r' + ), + ( + 'timeout', True, False, True, + ['INFO twister:runner.py:950 20/25 dummy platform' \ + ' dummy.testsuite.name' \ + ' UNKNOWN' \ + ' (dummy handler type: dummy dut, 60.000s/seed: 123)'], + None + ), +] + +@pytest.mark.parametrize( + 'status, verbose, cmake_only, ready_run, expected_logs, expected_out', + TESTDATA_13, + ids=['verbose error cmake only', 'failed', 'verbose skipped', 'filtered', + 'verbose passed ready run', 'verbose passed', 'unknown status', + 'timeout'] +) +def test_projectbuilder_report_out( + capfd, + caplog, + mocked_jobserver, + status, + verbose, + cmake_only, + ready_run, + expected_logs, + expected_out +): + instance_mock = mock.Mock() + instance_mock.handler.type_str = 'dummy handler type' + instance_mock.handler.seed = 123 + instance_mock.handler.ready = ready_run + instance_mock.run = ready_run + instance_mock.dut = 'dummy dut' + instance_mock.execution_time = 60 + instance_mock.platform.name = 'dummy platform' + instance_mock.status = status + instance_mock.reason = 'dummy reason' + instance_mock.testsuite.name = 'dummy.testsuite.name' + instance_mock.testsuite.testcases = [mock.Mock() for _ in range(25)] + instance_mock.testcases = [mock.Mock() for _ in range(24)] + \ + [mock.Mock(status='skipped')] + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.options.verbose = verbose + pb.options.cmake_only = cmake_only + pb.options.seed = 123 + pb.log_info_file = mock.Mock() + + results_mock = mock.Mock() + results_mock.iteration = 1 + results_mock.total = 25 + results_mock.done = 19 + results_mock.passed = 17 + results_mock.skipped_configs = 3 + results_mock.skipped_cases = 4 + results_mock.failed = 2 + results_mock.error = 1 + results_mock.cases = 0 + + pb.report_out(results_mock) + + assert results_mock.cases == 25 + + assert all([log in re.sub( + r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])', + '', + caplog.text + ) for log in expected_logs]) + + if expected_out: + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + # Remove 7b ANSI C1 escape sequences (colours) + out = re.sub( + r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])', + '', + out + ) + + assert expected_out in out + + +def test_projectbuilder_cmake_assemble_args(): + extra_args = ['CONFIG_FOO=y', 'DUMMY_EXTRA="yes"'] + handler = mock.Mock(ready=True, args=['dummy_handler']) + extra_conf_files = ['extrafile1.conf', 'extrafile2.conf'] + extra_overlay_confs = ['extra_overlay_conf'] + extra_dtc_overlay_files = ['overlay1.dtc', 'overlay2.dtc'] + cmake_extra_args = ['CMAKE1="yes"', 'CMAKE2=n'] + build_dir = os.path.join('build', 'dir') + + with mock.patch('os.path.exists', return_value=True): + results = ProjectBuilder.cmake_assemble_args(extra_args, handler, + extra_conf_files, + extra_overlay_confs, + extra_dtc_overlay_files, + cmake_extra_args, + build_dir) + + expected_results = [ + '-DCONFIG_FOO=y', + '-DCMAKE1=\"yes\"', + '-DCMAKE2=n', + '-DDUMMY_EXTRA=yes', + '-Ddummy_handler', + '-DCONF_FILE=extrafile1.conf;extrafile2.conf', + '-DDTC_OVERLAY_FILE=overlay1.dtc;overlay2.dtc', + f'-DOVERLAY_CONFIG=extra_overlay_conf ' \ + f'{os.path.join("build", "dir", "twister", "testsuite_extra.conf")}' + ] + + assert results == expected_results + + +def test_projectbuilder_cmake(): + instance_mock = mock.Mock() + instance_mock.handler = 'dummy handler' + instance_mock.build_dir = os.path.join('build', 'dir') + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.build_dir = 'build_dir' + pb.testsuite.extra_args = ['some', 'args'] + pb.testsuite.extra_conf_files = ['some', 'files1'] + pb.testsuite.extra_overlay_confs = ['some', 'files2'] + pb.testsuite.extra_dtc_overlay_files = ['some', 'files3'] + pb.options.extra_args = ['other', 'args'] + pb.cmake_assemble_args = mock.Mock(return_value=['dummy']) + cmake_res_mock = mock.Mock() + pb.run_cmake = mock.Mock(return_value=cmake_res_mock) + + res = pb.cmake(['dummy filter']) + + assert res == cmake_res_mock + pb.cmake_assemble_args.assert_called_once_with( + pb.testsuite.extra_args, + pb.instance.handler, + pb.testsuite.extra_conf_files, + pb.testsuite.extra_overlay_confs, + pb.testsuite.extra_dtc_overlay_files, + pb.options.extra_args, + pb.instance.build_dir + ) + pb.run_cmake.assert_called_once_with(['dummy'], ['dummy filter']) + + +def test_projectbuilder_build(mocked_jobserver): + instance_mock = mock.Mock() + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + + pb.build_dir = 'build_dir' + pb.run_build = mock.Mock(return_value={'dummy': 'dummy'}) + + res = pb.build() + + pb.run_build.assert_called_once_with(['--build', 'build_dir']) + assert res == {'dummy': 'dummy'} + + +TESTDATA_14 = [ + ( + True, + 'device', + 234, + 'native_posix', + 'posix', + {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, + 'pytest', + True, + True, + True, + True, + True, + False + ), + ( + True, + 'not device', + None, + 'native_posix', + 'not posix', + {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, + 'not pytest', + False, + False, + False, + False, + False, + True + ), + ( + False, + 'device', + 234, + 'native_posix', + 'posix', + {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, + 'pytest', + False, + False, + False, + False, + False, + False + ), +] + +@pytest.mark.parametrize( + 'ready, type_str, seed, platform_name, platform_arch, defconfig, harness,' \ + ' expect_duts, expect_parse_generated, expect_seed,' \ + ' expect_extra_test_args, expect_pytest, expect_handle', + TESTDATA_14, + ids=['pytest full', 'not pytest minimal', 'not ready'] +) +def test_projectbuilder_run( + mocked_jobserver, + ready, + type_str, + seed, + platform_name, + platform_arch, + defconfig, + harness, + expect_duts, + expect_parse_generated, + expect_seed, + expect_extra_test_args, + expect_pytest, + expect_handle +): + pytest_mock = mock.Mock(spec=Pytest) + harness_mock = mock.Mock() + + def mock_harness(name): + if name == 'Pytest': + return pytest_mock + else: + return harness_mock + + instance_mock = mock.Mock() + instance_mock.handler.get_test_timeout = mock.Mock(return_value=60) + instance_mock.handler.seed = 123 + instance_mock.handler.ready = ready + instance_mock.handler.type_str = type_str + instance_mock.handler.duts = [mock.Mock(name='dummy dut')] + instance_mock.platform.name = platform_name + instance_mock.platform.arch = platform_arch + instance_mock.testsuite.harness = harness + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.options.extra_test_args = ['dummy_arg1', 'dummy_arg2'] + pb.duts = ['another dut'] + pb.options.seed = seed + pb.defconfig = defconfig + pb.parse_generated = mock.Mock() + + with mock.patch('twisterlib.runner.HarnessImporter.get_harness', + mock_harness): + pb.run() + + if expect_duts: + assert pb.instance.handler.duts == ['another dut'] + + if expect_parse_generated: + pb.parse_generated.assert_called_once() + + if expect_seed: + assert pb.instance.handler.seed == seed + + if expect_extra_test_args: + assert pb.instance.handler.extra_test_args == ['dummy_arg1', + 'dummy_arg2'] + + if expect_pytest: + pytest_mock.pytest_run.assert_called_once_with(60) + + if expect_handle: + pb.instance.handler.handle.assert_called_once_with(harness_mock) + + +TESTDATA_15 = [ + (False, False, False, True), + (True, False, True, False), + (False, True, False, True), + (True, True, False, True), +] + +@pytest.mark.parametrize( + 'enable_size_report, cmake_only, expect_calc_size, expect_zeroes', + TESTDATA_15, + ids=['none', 'size_report', 'cmake', 'size_report+cmake'] +) +def test_projectbuilder_gather_metrics( + mocked_jobserver, + enable_size_report, + cmake_only, + expect_calc_size, + expect_zeroes +): + instance_mock = mock.Mock() + instance_mock.metrics = {} + env_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) + pb.options.enable_size_report = enable_size_report + pb.options.cmake_only = cmake_only + pb.calc_size = mock.Mock() + + pb.gather_metrics(instance_mock) + + if expect_calc_size: + pb.calc_size.assert_called_once() + + if expect_zeroes: + assert instance_mock.metrics['used_ram'] == 0 + assert instance_mock.metrics['used_rom'] == 0 + assert instance_mock.metrics['available_rom'] == 0 + assert instance_mock.metrics['available_ram'] == 0 + assert instance_mock.metrics['unrecognized'] == [] + + +TESTDATA_16 = [ + ('error', mock.ANY, False, False, False), + ('failed', mock.ANY, False, False, False), + ('skipped', mock.ANY, False, False, False), + ('filtered', 'native', False, False, True), + ('passed', 'qemu', False, False, True), + ('filtered', 'unit', False, False, True), + ('filtered', 'mcu', True, True, False), + ('passed', 'frdm_k64f', False, True, False), +] + +@pytest.mark.parametrize( + 'status, platform_type, expect_warnings, expect_calcs, expect_zeroes', + TESTDATA_16, + ids=[x[0] + (', ' + x[1]) if x[1] != mock.ANY else '' for x in TESTDATA_16] +) +def test_projectbuilder_calc_size( + status, + platform_type, + expect_warnings, + expect_calcs, + expect_zeroes +): + size_calc_mock = mock.Mock() + + instance_mock = mock.Mock() + instance_mock.status = status + instance_mock.platform.type = platform_type + instance_mock.metrics = {} + instance_mock.calculate_sizes = mock.Mock(return_value=size_calc_mock) + + from_buildlog = True + + ProjectBuilder.calc_size(instance_mock, from_buildlog) + + if expect_calcs: + instance_mock.calculate_sizes.assert_called_once_with( + from_buildlog=from_buildlog, + generate_warning=expect_warnings + ) + + assert instance_mock.metrics['used_ram'] == \ + size_calc_mock.get_used_ram() + assert instance_mock.metrics['used_rom'] == \ + size_calc_mock.get_used_rom() + assert instance_mock.metrics['available_rom'] == \ + size_calc_mock.get_available_rom() + assert instance_mock.metrics['available_ram'] == \ + size_calc_mock.get_available_ram() + assert instance_mock.metrics['unrecognized'] == \ + size_calc_mock.unrecognized_sections() + + if expect_zeroes: + assert instance_mock.metrics['used_ram'] == 0 + assert instance_mock.metrics['used_rom'] == 0 + assert instance_mock.metrics['available_rom'] == 0 + assert instance_mock.metrics['available_ram'] == 0 + assert instance_mock.metrics['unrecognized'] == [] + + if expect_calcs or expect_zeroes: + assert instance_mock.metrics['handler_time'] == \ + instance_mock.execution_time + else: + assert instance_mock.metrics == {} + + +TESTDATA_17 = [ + ('linux', 'posix', {'jobs': 4}, True, 32, 'GNUMakeJobClient'), + ('linux', 'posix', {'build_only': True}, False, 16, 'GNUMakeJobServer'), + ('linux', '???', {}, False, 8, 'JobClient'), + ('linux', '???', {'jobs': 4}, False, 4, 'JobClient'), +] + +@pytest.mark.parametrize( + 'platform, os_name, options, jobclient_from_environ, expected_jobs,' \ + ' expected_jobserver', + TESTDATA_17, + ids=['GNUMakeJobClient', 'GNUMakeJobServer', + 'JobClient', 'Jobclient+options'] +) +def test_twisterrunner_run( + caplog, + platform, + os_name, + options, + jobclient_from_environ, + expected_jobs, + expected_jobserver +): + def mock_client_from_environ(jobs): + if jobclient_from_environ: + jobclient_mock = mock.Mock(jobs=32) + jobclient_mock.name = 'GNUMakeJobClient' + return jobclient_mock + return None + + instances = {'dummy instance': mock.Mock(metrics={'k': 'v'})} + suites = [mock.Mock()] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.options.retry_failed = 2 + tr.options.retry_interval = 10 + tr.options.retry_build_errors = True + tr.options.jobs = None + tr.options.build_only = None + for k, v in options.items(): + setattr(tr.options, k, v) + tr.update_counting_before_pipeline = mock.Mock() + tr.execute = mock.Mock() + tr.show_brief = mock.Mock() + + gnumakejobserver_mock = mock.Mock() + gnumakejobserver_mock().name='GNUMakeJobServer' + jobclient_mock = mock.Mock() + jobclient_mock().name='JobClient' + + pipeline_q = queue.LifoQueue() + done_q = queue.LifoQueue() + done_instance = mock.Mock( + metrics={'k2': 'v2'}, + execution_time=30 + ) + done_instance.name='dummy instance' + done_q.put(done_instance) + manager_mock = mock.Mock() + manager_mock().LifoQueue = mock.Mock( + side_effect=iter([pipeline_q, done_q]) + ) + + results_mock = mock.Mock() + results_mock().error = 1 + results_mock().iteration = 0 + results_mock().failed = 2 + results_mock().total = 9 + + with mock.patch('twisterlib.runner.ExecutionCounter', results_mock), \ + mock.patch('twisterlib.runner.BaseManager', manager_mock), \ + mock.patch('twisterlib.runner.GNUMakeJobClient.from_environ', + mock_client_from_environ), \ + mock.patch('twisterlib.runner.GNUMakeJobServer', + gnumakejobserver_mock), \ + mock.patch('twisterlib.runner.JobClient', jobclient_mock), \ + mock.patch('multiprocessing.cpu_count', return_value=8), \ + mock.patch('sys.platform', platform), \ + mock.patch('time.sleep', mock.Mock()), \ + mock.patch('os.name', os_name): + tr.run() + + assert f'JOBS: {expected_jobs}' in caplog.text + + assert tr.jobserver.name == expected_jobserver + + assert tr.instances['dummy instance'].metrics == { + 'k': 'v', + 'k2': 'v2', + 'handler_time': 30, + 'unrecognized': [] + } + + assert results_mock().error == 0 + + +def test_twisterrunner_update_counting_before_pipeline(): + instances = { + 'dummy1': mock.Mock( + status='filtered', + reason='runtime filter', + testsuite=mock.Mock( + testcases=[mock.Mock()] + ) + ), + 'dummy2': mock.Mock( + status='filtered', + reason='static filter', + testsuite=mock.Mock( + testcases=[mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock()] + ) + ), + 'dummy3': mock.Mock( + status='error', + reason='error', + testsuite=mock.Mock( + testcases=[mock.Mock()] + ) + ), + 'dummy4': mock.Mock( + status='passed', + reason='OK', + testsuite=mock.Mock( + testcases=[mock.Mock()] + ) + ), + 'dummy5': mock.Mock( + status='skipped', + reason=None, + testsuite=mock.Mock( + testcases=[mock.Mock()] + ) + ) + } + suites = [mock.Mock()] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.results = mock.Mock( + skipped_filter = 0, + skipped_configs = 0, + skipped_cases = 0, + cases = 0, + error = 0 + ) + + tr.update_counting_before_pipeline() + + assert tr.results.skipped_filter == 1 + assert tr.results.skipped_configs == 1 + assert tr.results.skipped_cases == 4 + assert tr.results.cases == 4 + assert tr.results.error == 1 + + +def test_twisterrunner_show_brief(caplog): + instances = { + 'dummy1': mock.Mock(), + 'dummy2': mock.Mock(), + 'dummy3': mock.Mock(), + 'dummy4': mock.Mock(), + 'dummy5': mock.Mock() + } + suites = [mock.Mock(), mock.Mock()] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.results = mock.Mock( + skipped_filter = 3, + skipped_configs = 4, + skipped_cases = 0, + cases = 0, + error = 0 + ) + + tr.show_brief() + + log = '2 test scenarios (5 test instances) selected,' \ + ' 4 configurations skipped (3 by static filter, 1 at runtime).' + + assert log in caplog.text + + +TESTDATA_18 = [ + (False, False, False, [{'op': 'cmake', 'test': mock.ANY}]), + (False, False, True, [{'op': 'filter', 'test': mock.ANY}, + {'op': 'cmake', 'test': mock.ANY}]), + (False, True, True, [{'op': 'run', 'test': mock.ANY}, + {'op': 'run', 'test': mock.ANY}]), + (False, True, False, [{'op': 'run', 'test': mock.ANY}]), + (True, True, False, [{'op': 'cmake', 'test': mock.ANY}]), + (True, True, True, [{'op': 'filter', 'test': mock.ANY}, + {'op': 'cmake', 'test': mock.ANY}]), + (True, False, True, [{'op': 'filter', 'test': mock.ANY}, + {'op': 'cmake', 'test': mock.ANY}]), + (True, False, False, [{'op': 'cmake', 'test': mock.ANY}]), +] + +@pytest.mark.parametrize( + 'build_only, test_only, retry_build_errors, expected_pipeline_elements', + TESTDATA_18, + ids=['none', 'retry', 'test+retry', 'test', 'build+test', + 'build+test+retry', 'build+retry', 'build'] +) +def test_twisterrunner_add_tasks_to_queue( + build_only, + test_only, + retry_build_errors, + expected_pipeline_elements +): + def mock_get_cmake_filter_stages(filter, keys): + return [filter] + + instances = { + 'dummy1': mock.Mock(run=True, retries=0, status='passed'), + 'dummy2': mock.Mock(run=True, retries=0, status='skipped'), + 'dummy3': mock.Mock(run=True, retries=0, status='filtered'), + 'dummy4': mock.Mock(run=True, retries=0, status='error'), + 'dummy5': mock.Mock(run=True, retries=0, status='failed') + } + instances['dummy4'].testsuite.filter = 'some' + instances['dummy5'].testsuite.filter = 'full' + suites = [mock.Mock(), mock.Mock()] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.get_cmake_filter_stages = mock.Mock( + side_effect=mock_get_cmake_filter_stages + ) + + pipeline_mock = mock.Mock() + + tr.add_tasks_to_queue( + pipeline_mock, + build_only, + test_only, + retry_build_errors + ) + + assert all( + [build_only != instance.run for instance in instances.values()] + ) + + tr.get_cmake_filter_stages.assert_any_call('full', mock.ANY) + if retry_build_errors: + tr.get_cmake_filter_stages.assert_any_call('some', mock.ANY) + + print(pipeline_mock.put.call_args_list) + print([mock.call(el) for el in expected_pipeline_elements]) + + assert pipeline_mock.put.call_args_list == \ + [mock.call(el) for el in expected_pipeline_elements] + + +TESTDATA_19 = [ + ('linux'), + ('nt') +] + +@pytest.mark.parametrize( + 'platform', + TESTDATA_19, +) +def test_twisterrunner_pipeline_mgr(mocked_jobserver, platform): + counter = 0 + def mock_get_nowait(): + nonlocal counter + counter += 1 + if counter > 5: + raise queue.Empty() + return {'test': 'dummy'} + + instances = {} + suites = [] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.jobserver = mock.Mock( + get_job=mock.Mock( + return_value=nullcontext() + ) + ) + + pipeline_mock = mock.Mock() + pipeline_mock.get_nowait = mock.Mock(side_effect=mock_get_nowait) + done_queue_mock = mock.Mock() + lock_mock = mock.Mock() + results_mock = mock.Mock() + + with mock.patch('sys.platform', platform), \ + mock.patch('twisterlib.runner.ProjectBuilder',\ + return_value=mock.Mock()) as pb: + tr.pipeline_mgr(pipeline_mock, done_queue_mock, lock_mock, results_mock) + + assert len(pb().process.call_args_list) == 5 + + if platform == 'linux': + tr.jobserver.get_job.assert_called_once() + + +def test_twisterrunner_execute(caplog): + counter = 0 + def mock_join(): + nonlocal counter + counter += 1 + if counter > 3: + raise KeyboardInterrupt() + + instances = {} + suites = [] + env_mock = mock.Mock() + + tr = TwisterRunner(instances, suites, env=env_mock) + tr.add_tasks_to_queue = mock.Mock() + tr.jobs = 5 + + process_mock = mock.Mock() + process_mock().join = mock.Mock(side_effect=mock_join) + pipeline_mock = mock.Mock() + done_mock = mock.Mock() + + with mock.patch('twisterlib.runner.Process', process_mock): + tr.execute(pipeline_mock, done_mock) + + assert 'Launch process 0' in caplog.text + assert 'Launch process 1' in caplog.text + assert 'Launch process 2' in caplog.text + assert 'Launch process 3' in caplog.text + assert 'Launch process 4' in caplog.text + assert 'Execution interrupted' in caplog.text + + assert len(process_mock().start.call_args_list) == 5 + assert len(process_mock().join.call_args_list) == 4 + assert len(process_mock().terminate.call_args_list) == 5 + + + +TESTDATA_20 = [ + ('', []), + ('not ARCH in ["x86", "arc"]', ['full']), + ('dt_dummy(x, y)', ['dts']), + ('not CONFIG_FOO', ['kconfig']), + ('dt_dummy and CONFIG_FOO', ['dts', 'kconfig']), +] + +@pytest.mark.parametrize( + 'filter, expected_result', + TESTDATA_20, + ids=['none', 'full', 'dts', 'kconfig', 'dts+kconfig'] +) +def test_twisterrunner_get_cmake_filter_stages(filter, expected_result): + result = TwisterRunner.get_cmake_filter_stages(filter, ['not', 'and']) + + assert sorted(result) == sorted(expected_result) From ad6d8f28115aec03e97657fba1808a97477749b5 Mon Sep 17 00:00:00 2001 From: Tom Keddie Date: Thu, 26 Oct 2023 20:18:00 -0700 Subject: [PATCH 2755/4498] boards/arm/serpente: fix system clock rate Serpente schematic has the same clocking arrangement as boards/arm/adafruit_trinket_m0. This fix copies the clocking config from the trinket. Fixes https://github.com/zephyrproject-rtos/zephyr/issues/64470 Signed-off-by: Tom Keddie --- boards/arm/serpente/serpente_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arm/serpente/serpente_defconfig b/boards/arm/serpente/serpente_defconfig index a2c3ac7def2..b670a7b0476 100644 --- a/boards/arm/serpente/serpente_defconfig +++ b/boards/arm/serpente/serpente_defconfig @@ -3,6 +3,8 @@ CONFIG_SOC_SERIES_SAMD21=y CONFIG_SOC_PART_NUMBER_SAMD21E18A=y CONFIG_BOARD_SERPENTE=y +CONFIG_SOC_ATMEL_SAMD_OSC8M=y +CONFIG_SOC_ATMEL_SAMD_OSC8M_AS_MAIN=y CONFIG_CONSOLE=y CONFIG_GPIO=y CONFIG_UART_CONSOLE=y From b2eade6bcb630050bdb15d6c3cb920f44af30690 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Wed, 25 Oct 2023 14:33:28 +0300 Subject: [PATCH 2756/4498] west: update open-amp repo Update open-amp repository with new sha. Signed-off-by: Iuliana Prodan --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 639d10361a8..10676e94849 100644 --- a/west.yml +++ b/west.yml @@ -298,7 +298,7 @@ manifest: revision: 90f4484cbaec986ed253b4fe9649aa75e632de15 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp - revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 + revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread revision: d62167ee34b091e7025c9ec2820aae71e17a3944 From e7340282a7950d4cb071e77faafc249aaa569a8b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 26 Oct 2023 23:30:36 -0700 Subject: [PATCH 2757/4498] west.yml: update hal_intel Update hal_intel to include a power management fix. Signed-off-by: Flavio Ceolin --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 10676e94849..40d5c4a684f 100644 --- a/west.yml +++ b/west.yml @@ -173,7 +173,7 @@ manifest: groups: - hal - name: hal_intel - revision: b3b43d4e3da7ba483611bbbea7ef8af92c69df31 + revision: 11feb65898253ac6f715bf12bd04b869e4c1d577 path: modules/hal/intel groups: - hal From 09f6800d1fb7b9f2a4d89ef6835980fd0faff8fa Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 27 Oct 2023 15:41:37 +0200 Subject: [PATCH 2758/4498] actions: manifest: Update the revision of the manifest action Pull in https://github.com/zephyrproject-rtos/action-manifest/pull/10. Signed-off-by: Carles Cufi --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index eeee77e61a6..61ab2e42157 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -26,7 +26,7 @@ jobs: west init -l . || true - name: Manifest - uses: zephyrproject-rtos/action-manifest@v1.2.0 + uses: zephyrproject-rtos/action-manifest@v1.2.1 with: github-token: ${{ secrets.ZB_GITHUB_TOKEN }} manifest-path: 'west.yml' From dbf385bb080ef21c158f9c4602df9f54c6ab8424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 27 Oct 2023 21:05:39 +0200 Subject: [PATCH 2759/4498] boards: bl653_dvk: Fix incorrect definition of cs-gpios in spi1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `cs-gpios = <&gpio1 23 0>;` is incorrect, since pin P1.23 does not even exist in nRF52833. According to schematic, it should be P0.23 and this CS line should be configured as active low. Signed-off-by: Andrzej Głąbek --- boards/arm/bl653_dvk/bl653_dvk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/bl653_dvk/bl653_dvk.dts b/boards/arm/bl653_dvk/bl653_dvk.dts index ba8fa3658d2..4c536eb4512 100644 --- a/boards/arm/bl653_dvk/bl653_dvk.dts +++ b/boards/arm/bl653_dvk/bl653_dvk.dts @@ -148,7 +148,7 @@ &spi1 { compatible = "nordic,nrf-spi"; status = "okay"; - cs-gpios = <&gpio1 23 0>; + cs-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; From bc43e890fd7a6035438a47b8853b6fe652472da2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 27 Oct 2023 09:00:40 +0000 Subject: [PATCH 2760/4498] doc: drivers: add a paragraph mentioning the initlevels target Add a paragraph mentioning the initlevels target for inspecting the DEVICE_DEFINE and SYS_INIT sequence. Signed-off-by: Fabio Baltieri --- doc/kernel/drivers/index.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/kernel/drivers/index.rst b/doc/kernel/drivers/index.rst index 33e1027c07e..e835759d7ae 100644 --- a/doc/kernel/drivers/index.rst +++ b/doc/kernel/drivers/index.rst @@ -394,6 +394,18 @@ In some cases you may just need to run a function at boot. For such cases, the data structures and there isn't a way to later get a device pointer by name. The same device policies for initialization level and priority apply. +Inspecting the initialization sequence +************************************** + +Device drivers declared with :c:macro:`DEVICE_DEFINE` (or any variations of it) +and :c:macro:`SYS_INIT` are processed at boot time and the corresponding +initialization functions are called sequentially according to their specified +level and priority. + +Sometimes it's useful to inspect the final sequence of initialization function +call as produced by the linker. To do that, use the ``initlevels`` CMake +target, for example ``west build -t initlevels``. + Error handling ************** From eddfba487d5a81b2a81c0a8ee6c17f146cd88f01 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 27 Oct 2023 16:18:23 +0200 Subject: [PATCH 2761/4498] doc: can: move the documention for high-level protocols to connectivity Move the documentation for high-level CAN protocols (for now only covering ISO-TP) from the peripherals section to the connectivity section. This matches the layout in code, where the CAN controllers are under the drivers/can directory and the protocols are under the subsys/canbus/ directory. Signed-off-by: Henrik Brix Andersen --- MAINTAINERS.yml | 3 ++- doc/connectivity/canbus/index.rst | 9 +++++++++ .../peripherals => connectivity}/canbus/isotp.rst | 0 .../canbus/isotp_sequence.svg | 0 doc/connectivity/index.rst | 1 + doc/hardware/peripherals/{canbus => can}/controller.rst | 0 doc/hardware/peripherals/{canbus => can}/index.rst | 3 +-- doc/hardware/peripherals/{canbus => can}/timing.svg | 0 doc/hardware/peripherals/{canbus => can}/transceiver.svg | 0 doc/hardware/peripherals/index.rst | 2 +- 10 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 doc/connectivity/canbus/index.rst rename doc/{hardware/peripherals => connectivity}/canbus/isotp.rst (100%) rename doc/{hardware/peripherals => connectivity}/canbus/isotp_sequence.svg (100%) rename doc/hardware/peripherals/{canbus => can}/controller.rst (100%) rename doc/hardware/peripherals/{canbus => can}/index.rst (81%) rename doc/hardware/peripherals/{canbus => can}/timing.svg (100%) rename doc/hardware/peripherals/{canbus => can}/transceiver.svg (100%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 9e4884f4091..5d2e91df8f4 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -732,7 +732,8 @@ Release Notes: files: - boards/shields/mcp2515/ - boards/shields/tcan4550evm/ - - doc/hardware/peripherals/canbus/ + - doc/connectivity/canbus/ + - doc/hardware/peripherals/can/ - drivers/can/ - drivers/net/canbus.c - dts/bindings/can/ diff --git a/doc/connectivity/canbus/index.rst b/doc/connectivity/canbus/index.rst new file mode 100644 index 00000000000..78271d4181e --- /dev/null +++ b/doc/connectivity/canbus/index.rst @@ -0,0 +1,9 @@ +.. _canbus: + +Controller Area Network (CAN) Bus Protocols +########################################### + +.. toctree:: + :maxdepth: 2 + + isotp.rst diff --git a/doc/hardware/peripherals/canbus/isotp.rst b/doc/connectivity/canbus/isotp.rst similarity index 100% rename from doc/hardware/peripherals/canbus/isotp.rst rename to doc/connectivity/canbus/isotp.rst diff --git a/doc/hardware/peripherals/canbus/isotp_sequence.svg b/doc/connectivity/canbus/isotp_sequence.svg similarity index 100% rename from doc/hardware/peripherals/canbus/isotp_sequence.svg rename to doc/connectivity/canbus/isotp_sequence.svg diff --git a/doc/connectivity/index.rst b/doc/connectivity/index.rst index c135ed410bb..be81417d0ba 100644 --- a/doc/connectivity/index.rst +++ b/doc/connectivity/index.rst @@ -7,6 +7,7 @@ Connectivity :maxdepth: 1 bluetooth/index.rst + canbus/index.rst networking/index.rst lora_lorawan/index.rst usb/index.rst diff --git a/doc/hardware/peripherals/canbus/controller.rst b/doc/hardware/peripherals/can/controller.rst similarity index 100% rename from doc/hardware/peripherals/canbus/controller.rst rename to doc/hardware/peripherals/can/controller.rst diff --git a/doc/hardware/peripherals/canbus/index.rst b/doc/hardware/peripherals/can/index.rst similarity index 81% rename from doc/hardware/peripherals/canbus/index.rst rename to doc/hardware/peripherals/can/index.rst index 844ab945ff9..c21d75eb523 100644 --- a/doc/hardware/peripherals/canbus/index.rst +++ b/doc/hardware/peripherals/can/index.rst @@ -1,4 +1,4 @@ -.. _canbus: +.. _can: Controller Area Network (CAN) ############################# @@ -7,4 +7,3 @@ Controller Area Network (CAN) :maxdepth: 2 controller.rst - isotp.rst diff --git a/doc/hardware/peripherals/canbus/timing.svg b/doc/hardware/peripherals/can/timing.svg similarity index 100% rename from doc/hardware/peripherals/canbus/timing.svg rename to doc/hardware/peripherals/can/timing.svg diff --git a/doc/hardware/peripherals/canbus/transceiver.svg b/doc/hardware/peripherals/can/transceiver.svg similarity index 100% rename from doc/hardware/peripherals/canbus/transceiver.svg rename to doc/hardware/peripherals/can/transceiver.svg diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index ff80c0e9eb5..26500623d13 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -16,7 +16,7 @@ Peripherals bbram.rst bc12.rst clock_control.rst - canbus/index.rst + can/index.rst charger.rst coredump.rst counter.rst From 9e0c46f81bf4ecfc0db191f2f39ef95262be8ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 27 Oct 2023 16:16:36 +0200 Subject: [PATCH 2762/4498] doc: fix Doxygen light theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per Doxygen Awesome documentation: "HTML_COLORSTYLE must be set to LIGHT since Doxygen 1.9.5!" Fixes #64505 Signed-off-by: Benjamin Cabé --- doc/zephyr.doxyfile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 4ab6a73a894..84f31433208 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -1368,7 +1368,7 @@ HTML_EXTRA_FILES = @ZEPHYR_BASE@/doc/_doxygen/doxygen-awesome-darkmode-tog # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE = AUTO_LIGHT +HTML_COLORSTYLE = LIGHT # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to From b12785f86dbc3609ea0cdc288f77c974db65df74 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 12:27:15 +0200 Subject: [PATCH 2763/4498] tests/bsim/bt bis: Do not call into controller in split builds Use the HCI layer to update the channel map instead of calling directly into the controller. Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/64441 Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/ll/bis/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/ll/bis/src/main.c b/tests/bsim/bluetooth/ll/bis/src/main.c index d15de7ff196..6cc425953ed 100644 --- a/tests/bsim/bluetooth/ll/bis/src/main.c +++ b/tests/bsim/bluetooth/ll/bis/src/main.c @@ -441,7 +441,7 @@ static void test_iso_main(void) k_sleep(K_MSEC(2500)); printk("Periodic Advertising and ISO Channel Map Update..."); - err = ll_chm_update(chan_map); + err = bt_le_set_chan_map(chan_map); if (err) { FAIL("Channel Map Update failed.\n"); } From 08d1bb2c9216ee478395c8c677590e06ea7280fe Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 26 Oct 2023 14:44:54 +0200 Subject: [PATCH 2764/4498] tests: net: checksum_offload: Cleanup and fixes for the test suite When working on new test cases for checksum_offload test suite it turned out that some existing test cases were already broken and not testing what expected. This commit fixes the broken functionality: * Despite having two separate interfaces for offloaded and non-offloaded checksum scenario, all packets ended up in a single interface anyway due to src address matching. Therefore use different destination address, depending on tests. * Add separate semaphores for offloaded and non-offloaded case, to ensure that the packet ended up on the correct interface. * The packet loopback in RX cases was broken, the LL address, IP address and UDP port swap written data in wrong places. * The receive path was not tested in the offloaded case. Additionally, do a small cleanup before adding more tests: * Fix net_context leak. * Configure IPv6 neighbor once, during setup. * Add before function to cleanup the flags before tests execute. * Split tests into separate test cases, as they're not really dependent on each other. Signed-off-by: Robert Lubos --- tests/net/checksum_offload/src/main.c | 342 ++++++++++++++------------ 1 file changed, 178 insertions(+), 164 deletions(-) diff --git a/tests/net/checksum_offload/src/main.c b/tests/net/checksum_offload/src/main.c index bd248632151..52b8add0fb0 100644 --- a/tests/net/checksum_offload/src/main.c +++ b/tests/net/checksum_offload/src/main.c @@ -52,9 +52,13 @@ static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, static struct in6_addr my_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }; -/* Destination address for test packets */ -static struct in6_addr dst_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2 } } }; +/* Destination address for test packets (interface 1) */ +static struct in6_addr dst_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x2 } } }; + +/* Destination address for test packets (interface 2) */ +static struct in6_addr dst_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x2 } } }; /* Extra address is assigned to ll_addr */ static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0, @@ -62,8 +66,9 @@ static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0, 0x04 } } }; static struct in_addr in4addr_my = { { { 192, 0, 2, 1 } } }; -static struct in_addr in4addr_dst = { { { 192, 168, 1, 1 } } }; +static struct in_addr in4addr_dst = { { { 192, 0, 2, 2 } } }; static struct in_addr in4addr_my2 = { { { 192, 0, 42, 1 } } }; +static struct in_addr in4addr_dst2 = { { { 192, 0, 42, 2 } } }; /* Keep track of all ethernet interfaces. For native_posix board, we need * to increase the count as it has one extra network interface defined in @@ -71,18 +76,14 @@ static struct in_addr in4addr_my2 = { { { 192, 0, 42, 1 } } }; */ static struct net_if *eth_interfaces[2 + IS_ENABLED(CONFIG_ETH_NATIVE_POSIX)]; -static struct net_context *udp_v6_ctx_1; -static struct net_context *udp_v6_ctx_2; -static struct net_context *udp_v4_ctx_1; -static struct net_context *udp_v4_ctx_2; - static bool test_failed; static bool test_started; static bool start_receiving; -static K_SEM_DEFINE(wait_data, 0, UINT_MAX); +static K_SEM_DEFINE(wait_data_off, 0, UINT_MAX); +static K_SEM_DEFINE(wait_data_nonoff, 0, UINT_MAX); -#define WAIT_TIME K_SECONDS(1) +#define WAIT_TIME K_MSEC(100) struct eth_context { struct net_if *iface; @@ -136,6 +137,73 @@ static uint16_t get_udp_chksum(struct net_pkt *pkt) return udp_hdr->chksum; } +static void test_receiving(struct net_pkt *pkt) +{ + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(udp_access, struct net_udp_hdr); + struct net_udp_hdr *udp_hdr; + uint16_t port; + uint8_t lladdr[6]; + + DBG("Packet %p received\n", pkt); + + memcpy(lladdr, ((struct net_eth_hdr *)net_pkt_data(pkt))->src.addr, + sizeof(lladdr)); + memcpy(((struct net_eth_hdr *)net_pkt_data(pkt))->src.addr, + ((struct net_eth_hdr *)net_pkt_data(pkt))->dst.addr, + sizeof(lladdr)); + memcpy(((struct net_eth_hdr *)net_pkt_data(pkt))->dst.addr, + lladdr, sizeof(lladdr)); + + net_pkt_skip(pkt, sizeof(struct net_eth_hdr)); + + /* Swap IP src and destination address so that we can receive + * the packet and the stack will not reject it. + */ + if (net_pkt_family(pkt) == AF_INET6) { + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, + struct net_ipv6_hdr); + struct net_ipv6_hdr *ipv6_hdr; + struct in6_addr addr; + + ipv6_hdr = (struct net_ipv6_hdr *) + net_pkt_get_data(pkt, &ipv6_access); + zassert_not_null(ipv6_hdr, "Can't access IPv6 header"); + + net_ipv6_addr_copy_raw((uint8_t *)&addr, ipv6_hdr->src); + net_ipv6_addr_copy_raw(ipv6_hdr->src, ipv6_hdr->dst); + net_ipv6_addr_copy_raw(ipv6_hdr->dst, (uint8_t *)&addr); + } else { + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv4_access, + struct net_ipv4_hdr); + struct net_ipv4_hdr *ipv4_hdr; + struct in_addr addr; + + ipv4_hdr = (struct net_ipv4_hdr *) + net_pkt_get_data(pkt, &ipv4_access); + zassert_not_null(ipv4_hdr, "Can't access IPv4 header"); + + net_ipv4_addr_copy_raw((uint8_t *)&addr, ipv4_hdr->src); + net_ipv4_addr_copy_raw(ipv4_hdr->src, ipv4_hdr->dst); + net_ipv4_addr_copy_raw(ipv4_hdr->dst, (uint8_t *)&addr); + } + + net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ip_opts_len(pkt)); + udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access); + zassert_not_null(udp_hdr, "Can't access UDP header"); + + port = udp_hdr->src_port; + udp_hdr->src_port = udp_hdr->dst_port; + udp_hdr->dst_port = port; + + net_pkt_cursor_init(pkt); + + if (net_recv_data(net_pkt_iface(pkt), + net_pkt_rx_clone(pkt, K_NO_WAIT)) < 0) { + test_failed = true; + zassert_true(false, "Packet %p receive failed\n", pkt); + } +} + static int eth_tx_offloading_disabled(const struct device *dev, struct net_pkt *pkt) { @@ -151,53 +219,7 @@ static int eth_tx_offloading_disabled(const struct device *dev, } if (start_receiving) { - struct net_udp_hdr hdr, *udp_hdr; - uint16_t port; - uint8_t lladdr[6]; - - DBG("Packet %p received\n", pkt); - - /* Swap IP src and destination address so that we can receive - * the packet and the stack will not reject it. - */ - if (net_pkt_family(pkt) == AF_INET6) { - struct in6_addr addr; - - net_ipv6_addr_copy_raw((uint8_t *)&addr, NET_IPV6_HDR(pkt)->src); - net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->src, - NET_IPV6_HDR(pkt)->dst); - net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr); - } else { - struct in_addr addr; - - net_ipv4_addr_copy_raw((uint8_t *)&addr, NET_IPV4_HDR(pkt)->src); - net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->src, - NET_IPV4_HDR(pkt)->dst); - net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr); - } - - udp_hdr = net_udp_get_hdr(pkt, &hdr); - zassert_not_null(udp_hdr, "UDP header missing"); - - port = udp_hdr->src_port; - udp_hdr->src_port = udp_hdr->dst_port; - udp_hdr->dst_port = port; - - memcpy(lladdr, - ((struct net_eth_hdr *)net_pkt_data(pkt))->src.addr, - sizeof(lladdr)); - memcpy(((struct net_eth_hdr *)net_pkt_data(pkt))->src.addr, - ((struct net_eth_hdr *)net_pkt_data(pkt))->dst.addr, - sizeof(lladdr)); - memcpy(((struct net_eth_hdr *)net_pkt_data(pkt))->dst.addr, - lladdr, sizeof(lladdr)); - - if (net_recv_data(net_pkt_iface(pkt), - net_pkt_clone(pkt, K_NO_WAIT)) < 0) { - test_failed = true; - zassert_true(false, "Packet %p receive failed\n", pkt); - } - + test_receiving(pkt); return 0; } @@ -210,7 +232,7 @@ static int eth_tx_offloading_disabled(const struct device *dev, zassert_not_equal(chksum, 0, "Checksum calculated"); - k_sem_give(&wait_data); + k_sem_give(&wait_data_nonoff); } return 0; @@ -230,6 +252,11 @@ static int eth_tx_offloading_enabled(const struct device *dev, return -ENODATA; } + if (start_receiving) { + test_receiving(pkt); + return 0; + } + if (test_started) { uint16_t chksum; @@ -239,7 +266,7 @@ static int eth_tx_offloading_enabled(const struct device *dev, zassert_equal(chksum, 0, "Checksum calculated"); - k_sem_give(&wait_data); + k_sem_give(&wait_data_off); } return 0; @@ -375,6 +402,7 @@ static void test_eth_setup(void) static void test_address_setup(void) { + struct in_addr netmask = { { { 255, 255, 255, 0 } } }; struct net_if_addr *ifaddr; struct net_if *iface1, *iface2; @@ -409,6 +437,8 @@ static void test_address_setup(void) NET_ADDR_MANUAL, 0); zassert_not_null(ifaddr, "Cannot add IPv4 address"); + net_if_ipv4_set_netmask(iface1, &netmask); + ifaddr = net_if_ipv6_addr_add(iface2, &my_addr2, NET_ADDR_MANUAL, 0); if (!ifaddr) { @@ -423,6 +453,8 @@ static void test_address_setup(void) NET_ADDR_MANUAL, 0); zassert_not_null(ifaddr, "Cannot add IPv4 address"); + net_if_ipv4_set_netmask(iface2, &netmask); + net_if_up(iface1); net_if_up(iface2); @@ -433,7 +465,7 @@ static void test_address_setup(void) test_failed = false; } -static bool add_neighbor(struct net_if *iface, struct in6_addr *addr) +static void add_neighbor(struct net_if *iface, struct in6_addr *addr) { struct net_linkaddr_storage llstorage; struct net_linkaddr lladdr; @@ -455,14 +487,12 @@ static bool add_neighbor(struct net_if *iface, struct in6_addr *addr) if (!nbr) { DBG("Cannot add dst %s to neighbor cache\n", net_sprint_ipv6_addr(addr)); - return false; } - - return true; } -static void test_tx_chksum_offload_disabled_test_v6(void) +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -475,14 +505,13 @@ static void test_tx_chksum_offload_disabled_test_v6(void) .sin6_port = 0, }; - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, - &udp_v6_ctx_1); + ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv6 UDP context failed"); memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr)); + memcpy(&dst_addr6.sin6_addr, &dst_addr1, sizeof(struct in6_addr)); - ret = net_context_bind(udp_v6_ctx_1, (struct sockaddr *)&src_addr6, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, sizeof(struct sockaddr_in6)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -493,27 +522,25 @@ static void test_tx_chksum_offload_disabled_test_v6(void) test_started = true; - ret = add_neighbor(iface, &dst_addr); - zassert_true(ret, "Cannot add neighbor"); - len = strlen(test_data); - ret = net_context_sendto(udp_v6_ctx_1, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr6, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } - net_context_unref(udp_v6_ctx_1); + net_context_unref(net_ctx); } -static void test_tx_chksum_offload_disabled_test_v4(void) +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -526,14 +553,13 @@ static void test_tx_chksum_offload_disabled_test_v4(void) .sin_port = 0, }; - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - &udp_v4_ctx_1); + ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv4 UDP context failed"); memcpy(&src_addr4.sin_addr, &in4addr_my, sizeof(struct in_addr)); memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); - ret = net_context_bind(udp_v4_ctx_1, (struct sockaddr *)&src_addr4, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, sizeof(struct sockaddr_in)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -546,25 +572,23 @@ static void test_tx_chksum_offload_disabled_test_v4(void) test_started = true; - ret = add_neighbor(iface, &dst_addr); - zassert_true(ret, "Cannot add neighbor"); - - ret = net_context_sendto(udp_v4_ctx_1, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr4, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } - net_context_unref(udp_v4_ctx_1); + net_context_unref(net_ctx); } -static void test_tx_chksum_offload_enabled_test_v6(void) +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -577,14 +601,13 @@ static void test_tx_chksum_offload_enabled_test_v6(void) .sin6_port = 0, }; - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, - &udp_v6_ctx_2); + ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv6 UDP context failed"); memcpy(&src_addr6.sin6_addr, &my_addr2, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr)); + memcpy(&dst_addr6.sin6_addr, &dst_addr2, sizeof(struct in6_addr)); - ret = net_context_bind(udp_v6_ctx_2, (struct sockaddr *)&src_addr6, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, sizeof(struct sockaddr_in6)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -597,25 +620,23 @@ static void test_tx_chksum_offload_enabled_test_v6(void) test_started = true; - ret = add_neighbor(iface, &dst_addr); - zassert_true(ret, "Cannot add neighbor"); - - ret = net_context_sendto(udp_v6_ctx_2, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr6, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_off, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } - net_context_unref(udp_v6_ctx_2); + net_context_unref(net_ctx); } -static void test_tx_chksum_offload_enabled_test_v4(void) +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -628,14 +649,13 @@ static void test_tx_chksum_offload_enabled_test_v4(void) .sin_port = 0, }; - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - &udp_v4_ctx_2); + ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv4 UDP context failed"); memcpy(&src_addr4.sin_addr, &in4addr_my2, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); + memcpy(&dst_addr4.sin_addr, &in4addr_dst2, sizeof(struct in_addr)); - ret = net_context_bind(udp_v4_ctx_2, (struct sockaddr *)&src_addr4, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, sizeof(struct sockaddr_in)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -648,21 +668,18 @@ static void test_tx_chksum_offload_enabled_test_v4(void) test_started = true; - ret = add_neighbor(iface, &dst_addr); - zassert_true(ret, "Cannot add neighbor"); - - ret = net_context_sendto(udp_v4_ctx_2, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr4, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_off, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } - net_context_unref(udp_v4_ctx_2); + net_context_unref(net_ctx); } static void recv_cb_offload_disabled(struct net_context *context, @@ -682,7 +699,7 @@ static void recv_cb_offload_disabled(struct net_context *context, "IPv4 checksum is not set"); } - k_sem_give(&wait_data); + k_sem_give(&wait_data_nonoff); net_pkt_unref(pkt); } @@ -703,13 +720,14 @@ static void recv_cb_offload_enabled(struct net_context *context, zassert_equal(ipv4->chksum, 0, "IPv4 checksum is set"); } - k_sem_give(&wait_data); + k_sem_give(&wait_data_off); net_pkt_unref(pkt); } -static void test_rx_chksum_offload_disabled_test_v6(void) +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -722,14 +740,13 @@ static void test_rx_chksum_offload_disabled_test_v6(void) .sin6_port = 0, }; - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, - &udp_v6_ctx_1); + ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv6 UDP context failed"); memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr)); + memcpy(&dst_addr6.sin6_addr, &dst_addr1, sizeof(struct in6_addr)); - ret = net_context_bind(udp_v6_ctx_1, (struct sockaddr *)&src_addr6, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, sizeof(struct sockaddr_in6)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -743,29 +760,30 @@ static void test_rx_chksum_offload_disabled_test_v6(void) test_started = true; start_receiving = true; - ret = net_context_recv(udp_v6_ctx_1, recv_cb_offload_disabled, + ret = net_context_recv(net_ctx, recv_cb_offload_disabled, K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - start_receiving = false; - - ret = net_context_sendto(udp_v6_ctx_1, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr6, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } /* Let the receiver to receive the packets */ k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); } -static void test_rx_chksum_offload_disabled_test_v4(void) +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -778,14 +796,13 @@ static void test_rx_chksum_offload_disabled_test_v4(void) .sin_port = 0, }; - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - &udp_v4_ctx_1); + ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv4 UDP context failed"); memcpy(&src_addr4.sin_addr, &in4addr_my, sizeof(struct in_addr)); memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); - ret = net_context_bind(udp_v4_ctx_1, (struct sockaddr *)&src_addr4, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, sizeof(struct sockaddr_in)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -799,29 +816,30 @@ static void test_rx_chksum_offload_disabled_test_v4(void) test_started = true; start_receiving = true; - ret = net_context_recv(udp_v4_ctx_1, recv_cb_offload_disabled, + ret = net_context_recv(net_ctx, recv_cb_offload_disabled, K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - start_receiving = false; - - ret = net_context_sendto(udp_v4_ctx_1, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr4, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } /* Let the receiver to receive the packets */ k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); } -static void test_rx_chksum_offload_enabled_test_v6(void) +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -834,14 +852,13 @@ static void test_rx_chksum_offload_enabled_test_v6(void) .sin6_port = 0, }; - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, - &udp_v6_ctx_2); + ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv6 UDP context failed"); memcpy(&src_addr6.sin6_addr, &my_addr2, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr)); + memcpy(&dst_addr6.sin6_addr, &dst_addr2, sizeof(struct in6_addr)); - ret = net_context_bind(udp_v6_ctx_2, (struct sockaddr *)&src_addr6, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, sizeof(struct sockaddr_in6)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -855,27 +872,30 @@ static void test_rx_chksum_offload_enabled_test_v6(void) test_started = true; start_receiving = true; - ret = net_context_recv(udp_v6_ctx_2, recv_cb_offload_enabled, + ret = net_context_recv(net_ctx, recv_cb_offload_enabled, K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - ret = net_context_sendto(udp_v6_ctx_2, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr6, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_off, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } /* Let the receiver to receive the packets */ k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); } -static void test_rx_chksum_offload_enabled_test_v4(void) +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4) { + struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ struct net_if *iface; int ret, len; @@ -888,14 +908,13 @@ static void test_rx_chksum_offload_enabled_test_v4(void) .sin_port = 0, }; - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - &udp_v4_ctx_2); + ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); zassert_equal(ret, 0, "Create IPv4 UDP context failed"); memcpy(&src_addr4.sin_addr, &in4addr_my2, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); + memcpy(&dst_addr4.sin_addr, &in4addr_dst2, sizeof(struct in_addr)); - ret = net_context_bind(udp_v4_ctx_2, (struct sockaddr *)&src_addr4, + ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, sizeof(struct sockaddr_in)); zassert_equal(ret, 0, "Context bind failure test failed"); @@ -909,54 +928,49 @@ static void test_rx_chksum_offload_enabled_test_v4(void) test_started = true; start_receiving = true; - ret = net_context_recv(udp_v4_ctx_2, recv_cb_offload_enabled, + ret = net_context_recv(net_ctx, recv_cb_offload_enabled, K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - ret = net_context_sendto(udp_v4_ctx_2, test_data, len, + ret = net_context_sendto(net_ctx, test_data, len, (struct sockaddr *)&dst_addr4, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data, WAIT_TIME)) { + if (k_sem_take(&wait_data_off, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } /* Let the receiver to receive the packets */ k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); } static void *net_chksum_offload_tests_setup(void) { test_eth_setup(); test_address_setup(); - return NULL; -} -ZTEST(net_chksum_offload, test_chksum_offload_disabled_v4) -{ - test_tx_chksum_offload_disabled_test_v4(); - test_rx_chksum_offload_disabled_test_v4(); -} + add_neighbor(eth_interfaces[0], &dst_addr1); + add_neighbor(eth_interfaces[1], &dst_addr2); -ZTEST(net_chksum_offload, test_chksum_offload_enabled_v4) -{ - test_tx_chksum_offload_enabled_test_v4(); - test_rx_chksum_offload_enabled_test_v4(); + return NULL; } -ZTEST(net_chksum_offload, test_chksum_offload_disabled_v6) +static void net_chksum_offload_tests_before(void *fixture) { - test_tx_chksum_offload_disabled_test_v6(); - test_rx_chksum_offload_disabled_test_v6(); -} + ARG_UNUSED(fixture); -ZTEST(net_chksum_offload, test_chksum_offload_enabled_v6) -{ - test_tx_chksum_offload_enabled_test_v6(); - test_rx_chksum_offload_enabled_test_v6(); + k_sem_reset(&wait_data_off); + k_sem_reset(&wait_data_nonoff); + + test_failed = false; + test_started = false; + start_receiving = false; } -ZTEST_SUITE(net_chksum_offload, NULL, net_chksum_offload_tests_setup, NULL, NULL, NULL); +ZTEST_SUITE(net_chksum_offload, NULL, net_chksum_offload_tests_setup, + net_chksum_offload_tests_before, NULL, NULL); From 2dcb1280a57575621063308063b62e50b369e151 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 26 Oct 2023 17:27:15 +0100 Subject: [PATCH 2765/4498] ci: compliance: fetch only the last revision and skip tags Add some west update flags to do a shallow fetch of the modules and skip the tags. That data is not needed anyway, should make the compliance check initialization a bit faster. Signed-off-by: Fabio Baltieri --- .github/workflows/compliance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index 59cfc40c264..cb4e1c00f77 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -45,7 +45,7 @@ jobs: git log --pretty=oneline | head -n 10 west init -l . || true west config manifest.group-filter -- +ci,+optional - west update 2>&1 1> west.update.log || west update 2>&1 1> west.update2.log + west update -o=--depth=1 -n 2>&1 1> west.update.log || west update -o=--depth=1 -n 2>&1 1> west.update2.log - name: Run Compliance Tests continue-on-error: true From f0728ce0aaba73d1c5d28ba90c90b9319ff0e1a3 Mon Sep 17 00:00:00 2001 From: Ping Wang Date: Mon, 2 Oct 2023 14:40:52 +0200 Subject: [PATCH 2766/4498] samples: Bluetooth: Add LC3 to broadcast audio samples The broadcast audio samples (broadcast_audio_sink and broadcast_audio_source) are sending mock data, the apps are improved by using the LC3 module as the unicast audio samples do. Signed-off-by: Ping Wang --- .../nrf5340_audio_dk_nrf5340_cpuapp.conf | 10 ++ .../bluetooth/broadcast_audio_sink/prj.conf | 2 + .../bluetooth/broadcast_audio_sink/src/main.c | 140 +++++++++++++++++- .../nrf5340_audio_dk_nrf5340_cpuapp.conf | 12 ++ .../broadcast_audio_source/src/main.c | 106 ++++++++++++- 5 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf create mode 100644 samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf diff --git a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..6850b72e7d0 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -0,0 +1,10 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence +# inctease stack size for that thread. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. +CONFIG_NEWLIB_LIBC=y +# Enable encryption. +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_sink/prj.conf b/samples/bluetooth/broadcast_audio_sink/prj.conf index 11e0971638a..29a479933d6 100644 --- a/samples/bluetooth/broadcast_audio_sink/prj.conf +++ b/samples/bluetooth/broadcast_audio_sink/prj.conf @@ -10,5 +10,7 @@ CONFIG_BT_ISO_MAX_CHAN=2 CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS=2 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_DEVICE_NAME="Broadcast Audio Sink" diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index 763647b688c..fa776bf5430 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -56,12 +56,17 @@ static struct broadcast_sink_stream { size_t loss_cnt; size_t error_cnt; size_t valid_cnt; +#if defined(CONFIG_LIBLC3) + struct net_buf *in_buf; + struct k_work_delayable lc3_decode_work; +/* Internal lock for protecting net_buf from multiple access */ + struct k_mutex lc3_decoder_mutex; +#endif /* defined(CONFIG_LIBLC3) */ } streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)]; static struct bt_conn *broadcast_assistant_conn; static struct bt_le_ext_adv *ext_adv; - static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_24KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 60u, 1u, @@ -76,6 +81,100 @@ static uint32_t requested_bis_sync; static uint32_t bis_index_bitfield; static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +#if defined(CONFIG_LIBLC3) + +#include "lc3.h" + +#define MAX_SAMPLE_RATE 16000 +#define MAX_FRAME_DURATION_US 10000 +#define MAX_NUM_SAMPLES ((MAX_FRAME_DURATION_US * MAX_SAMPLE_RATE) / USEC_PER_SEC) + +static int16_t audio_buf[MAX_NUM_SAMPLES]; +static lc3_decoder_t lc3_decoder; +static lc3_decoder_mem_16k_t lc3_decoder_mem; +static int frames_per_sdu; + +static int lc3_enable(const struct bt_audio_codec_cfg *codec_cfg) +{ + int ret; + int freq_hz; + int frame_duration_us; + + printk("Enable: stream with codec %p\n", codec_cfg); + + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); + } else { + printk("Error: Codec frequency not set, cannot start codec."); + return -1; + } + + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { + printk("Error: Frame duration not set, cannot start codec."); + return ret; + } + + frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); + + lc3_decoder = lc3_setup_decoder(frame_duration_us, freq_hz, 0, /* No resampling */ + &lc3_decoder_mem); + + if (lc3_decoder == NULL) { + printk("ERROR: Failed to setup LC3 decoder - wrong parameters?\n"); + return -1; + } + + return 0; +} + +static void lc3_decode_handler(struct k_work *work) +{ + int err = 0; + int offset = 0; + uint8_t *buf_data; + struct net_buf *ptr_net_buf; + int octets_per_frame; + struct broadcast_sink_stream *sink_stream = CONTAINER_OF( + k_work_delayable_from_work(work), struct broadcast_sink_stream, lc3_decode_work); + + k_mutex_lock(&sink_stream->lc3_decoder_mutex, K_FOREVER); + + if (sink_stream->in_buf == NULL) { + printk("buf data is NULL, nothing to be docoded\n"); + k_mutex_unlock(&sink_stream->lc3_decoder_mutex); + return; + } + + ptr_net_buf = net_buf_ref(sink_stream->in_buf); + net_buf_unref(sink_stream->in_buf); + sink_stream->in_buf = NULL; + k_mutex_unlock(&sink_stream->lc3_decoder_mutex); + + buf_data = ptr_net_buf->data; + octets_per_frame = ptr_net_buf->len / frames_per_sdu; + + for (int i = 0; i < frames_per_sdu; i++) { + err = lc3_decode(lc3_decoder, buf_data + offset, octets_per_frame, + LC3_PCM_FORMAT_S16, audio_buf, 1); + + if (err == 1) { + printk(" decoder performed PLC\n"); + } else if (err < 0) { + printk(" decoder failed - wrong parameters?\n"); + } + + offset += octets_per_frame; + } + + net_buf_unref(ptr_net_buf); +} + +#endif /* defined(CONFIG_LIBLC3) */ + static void stream_started_cb(struct bt_bap_stream *stream) { struct broadcast_sink_stream *sink_stream = @@ -88,6 +187,9 @@ static void stream_started_cb(struct bt_bap_stream *stream) sink_stream->valid_cnt = 0U; sink_stream->error_cnt = 0U; +#if defined(CONFIG_LIBLC3) + k_work_init_delayable(&sink_stream->lc3_decode_work, lc3_decode_handler); +#endif /* defined(CONFIG_LIBLC3) */ k_sem_give(&sem_bis_synced); } @@ -103,8 +205,7 @@ static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) } } -static void stream_recv_cb(struct bt_bap_stream *stream, - const struct bt_iso_recv_info *info, +static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { struct broadcast_sink_stream *sink_stream = @@ -120,6 +221,17 @@ static void stream_recv_cb(struct bt_bap_stream *stream, if (info->flags & BT_ISO_FLAGS_VALID) { sink_stream->valid_cnt++; +#if defined(CONFIG_LIBLC3) + k_mutex_lock(&sink_stream->lc3_decoder_mutex, K_FOREVER); + if (sink_stream->in_buf != NULL) { + net_buf_unref(sink_stream->in_buf); + sink_stream->in_buf = NULL; + } + + sink_stream->in_buf = net_buf_ref(buf); + k_mutex_unlock(&sink_stream->lc3_decoder_mutex); + k_work_schedule(&sink_stream->lc3_decode_work, K_NO_WAIT); +#endif /* defined(CONFIG_LIBLC3) */ } sink_stream->recv_cnt++; @@ -133,7 +245,7 @@ static void stream_recv_cb(struct bt_bap_stream *stream, static struct bt_bap_stream_ops stream_ops = { .started = stream_started_cb, .stopped = stream_stopped_cb, - .recv = stream_recv_cb + .recv = stream_recv_cb, }; static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base) @@ -151,6 +263,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap const size_t bis_count = base->subgroups[i].bis_count; printk("Subgroup[%zu] has %zu streams\n", i, bis_count); + for (size_t j = 0U; j < bis_count; j++) { const uint8_t index = base->subgroups[i].bis_data[j].index; @@ -158,6 +271,21 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap base_bis_index_bitfield |= BIT(index); } +#if defined(CONFIG_LIBLC3) + int ret; + const struct bt_audio_codec_cfg *codec_cfg = &base->subgroups[i].codec_cfg; + + if (codec_cfg->id != BT_HCI_CODING_FORMAT_LC3) { + printk("unsupported codec 0x%02x", codec_cfg->id); + return; + } + + ret = lc3_enable(codec_cfg); + if (ret < 0) { + printk("Error: cannot enable LC3 codec: %d", ret); + return; + } +#endif /* defined(CONFIG_LIBLC3) */ } bis_index_bitfield = base_bis_index_bitfield & bis_index_mask; @@ -652,7 +780,6 @@ static int reset(void) k_sem_reset(&sem_broadcast_code_received); k_sem_reset(&sem_bis_sync_requested); k_sem_reset(&sem_bis_synced); - return 0; } @@ -739,6 +866,9 @@ int main(void) for (size_t i = 0U; i < ARRAY_SIZE(streams_p); i++) { streams_p[i] = &streams[i].stream; +#if defined(CONFIG_LIBLC3) + k_mutex_init(&streams[i].lc3_decoder_mutex); +#endif /* defined(CONFIG_LIBLC3) */ } while (true) { diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..9a48e919ab6 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -0,0 +1,12 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# When Host is fixed, CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE can inherit the CONFIG_BT_ISO_TX_MTU value. +CONFIG_BT_ISO_TX_MTU=40 +# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence +# inctease stack size for that thread. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. +CONFIG_NEWLIB_LIBC=y +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/src/main.c b/samples/bluetooth/broadcast_audio_source/src/main.c index e30243791b5..6dc853f2d6d 100644 --- a/samples/bluetooth/broadcast_audio_source/src/main.c +++ b/samples/bluetooth/broadcast_audio_source/src/main.c @@ -9,11 +9,24 @@ #include #include +/* Zephyr Controller works best while Extended Advertising interval to be a multiple + * of the ISO Interval minus 10 ms (max. advertising random delay). This is + * required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the + * Broadcast ISO radio events. + * + * I.e. for a 7.5 ms ISO interval use 90 ms minus 10 ms ==> 80 ms advertising + * interval. + * And, for 10 ms ISO interval, can use 90 ms minus 10 ms ==> 80 ms advertising + * interval. + */ +#define BT_LE_EXT_ADV_CUSTOM \ + BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_USE_NAME, 0x0080, 0x0080, NULL) + /* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that * the controller is never idle */ #define BROADCAST_ENQUEUE_COUNT 2U -#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT) +#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT) BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED, "CONFIG_BT_ISO_TX_BUF_COUNT should be at least " @@ -32,7 +45,10 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); -static uint8_t mock_data[CONFIG_BT_ISO_TX_MTU]; +#define MAX_SAMPLE_RATE 16000 +#define MAX_FRAME_DURATION_US 10000 +#define MAX_NUM_SAMPLES ((MAX_FRAME_DURATION_US * MAX_SAMPLE_RATE) / USEC_PER_SEC) +static int16_t mock_data[MAX_NUM_SAMPLES]; static uint16_t seq_num; static bool stopping; @@ -41,6 +57,65 @@ static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); #define BROADCAST_SOURCE_LIFETIME 120U /* seconds */ +#if defined(CONFIG_LIBLC3) + +#include "lc3.h" + +static lc3_encoder_t lc3_encoder; +static lc3_encoder_mem_16k_t lc3_encoder_mem; +static int freq_hz; +static int frame_duration_us; +static int frames_per_sdu; +static int octets_per_frame; + +static void init_lc3(void) +{ + const struct bt_audio_codec_cfg *codec_cfg = &preset_16_2_1.codec_cfg; + int ret; + + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret > 0) { + freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); + } else { + return; + } + + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { + printk("Error: Frame duration not set, cannot start codec."); + return; + } + + octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); + frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); + + if (freq_hz < 0) { + printk("Error: Codec frequency not set, cannot start codec."); + return; + } + + if (frame_duration_us < 0) { + printk("Error: Frame duration not set, cannot start codec."); + return; + } + + if (octets_per_frame < 0) { + printk("Error: Octets per frame not set, cannot start codec."); + return; + } + + /* Create the encoder instance. This shall complete before stream_started() is called. */ + lc3_encoder = lc3_setup_encoder(frame_duration_us, freq_hz, 0, /* No resampling */ + &lc3_encoder_mem); + + if (lc3_encoder == NULL) { + printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); + } +} +#endif /* defined(CONFIG_LIBLC3) */ + static void stream_started_cb(struct bt_bap_stream *stream) { struct broadcast_source_stream *source_stream = @@ -75,7 +150,28 @@ static void stream_sent_cb(struct bt_bap_stream *stream) } net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); +#if defined(CONFIG_LIBLC3) + int lc3_ret; + uint8_t lc3_encoder_buffer[preset_16_2_1.qos.sdu]; + + if (lc3_encoder == NULL) { + printk("LC3 encoder not setup, cannot encode data.\n"); + return; + } + + lc3_ret = lc3_encode(lc3_encoder, LC3_PCM_FORMAT_S16, mock_data, 1, octets_per_frame, + lc3_encoder_buffer); + + if (lc3_ret == -1) { + printk("LC3 encoder failed - wrong parameters?: %d", lc3_ret); + return; + } + + net_buf_add_mem(buf, lc3_encoder_buffer, preset_16_2_1.qos.sdu); +#else net_buf_add_mem(buf, mock_data, preset_16_2_1.qos.sdu); +#endif /* defined(CONFIG_LIBLC3) */ + ret = bt_bap_stream_send(stream, buf, source_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { /* This will end broadcasting on this stream. */ @@ -157,6 +253,10 @@ int main(void) mock_data[i] = i; } +#if defined(CONFIG_LIBLC3) + init_lc3(); +#endif /* defined(CONFIG_LIBLC3) */ + while (true) { /* Broadcast Audio Streaming Endpoint advertising data */ NET_BUF_SIMPLE_DEFINE(ad_buf, @@ -167,7 +267,7 @@ int main(void) uint32_t broadcast_id; /* Create a non-connectable non-scannable advertising set */ - err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, &adv); + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CUSTOM, NULL, &adv); if (err != 0) { printk("Unable to create extended advertising set: %d\n", err); From 18167754665b6ce3a1b80d9c07d4e4008a3eb298 Mon Sep 17 00:00:00 2001 From: Deepti Deshatty Date: Tue, 1 Aug 2023 09:44:55 +0530 Subject: [PATCH 2767/4498] drivers: flash: provide api to reset the flash registers changes enable flash driver to provide api interface to send reset memory spi command to the spi flash. The reset memory command would bring the spi flash to its default power-on state and loose all the volatile register settings. Flash reset is needed when more than one controller access the flash chip in a shared mode. Signed-off-by: Deepti Deshatty --- drivers/flash/Kconfig.nor | 1 + drivers/flash/spi_nor.c | 31 +++++++++++++++++++++++++++++++ include/zephyr/drivers/flash.h | 10 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/drivers/flash/Kconfig.nor b/drivers/flash/Kconfig.nor index 622ded42258..28bbfd5c66e 100644 --- a/drivers/flash/Kconfig.nor +++ b/drivers/flash/Kconfig.nor @@ -8,6 +8,7 @@ menuconfig SPI_NOR select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_JESD216 + select FLASH_HAS_EX_OP select SPI if SPI_NOR diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 631ee6a15ab..c8438fc847d 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -702,6 +702,34 @@ static int spi_nor_read(const struct device *dev, off_t addr, void *dest, return ret; } +#if defined(CONFIG_FLASH_EX_OP_ENABLED) +static int flash_spi_nor_ex_op(const struct device *dev, uint16_t code, + const uintptr_t in, void *out) +{ + int ret; + + ARG_UNUSED(in); + ARG_UNUSED(out); + + acquire_device(dev); + + switch (code) { + case FLASH_EX_OP_RESET: + ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_RESET_EN); + if (ret == 0) { + ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_RESET_MEM); + } + break; + default: + ret = -ENOTSUP; + break; + } + + release_device(dev); + return ret; +} +#endif + static int spi_nor_write(const struct device *dev, off_t addr, const void *src, size_t size) @@ -1427,6 +1455,9 @@ static const struct flash_driver_api spi_nor_api = { .sfdp_read = spi_nor_sfdp_read, .read_jedec_id = spi_nor_read_jedec_id, #endif +#if defined(CONFIG_FLASH_EX_OP_ENABLED) + .ex_op = flash_spi_nor_ex_op, +#endif }; #ifndef CONFIG_SPI_NOR_SFDP_RUNTIME diff --git a/include/zephyr/drivers/flash.h b/include/zephyr/drivers/flash.h index de5e7c2116e..ae24ac96a75 100644 --- a/include/zephyr/drivers/flash.h +++ b/include/zephyr/drivers/flash.h @@ -471,6 +471,16 @@ __syscall int flash_ex_op(const struct device *dev, uint16_t code, #define FLASH_EX_OP_VENDOR_BASE 0x8000 #define FLASH_EX_OP_IS_VENDOR(c) ((c) & FLASH_EX_OP_VENDOR_BASE) +/** + * @brief Enumeration for extra flash operations + */ +enum flash_ex_op_types { + /* + * Reset flash device. + */ + FLASH_EX_OP_RESET = 0, +}; + static inline int z_impl_flash_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out) { From 55c59e041e4528b0b48dadcf08f36059d5ad3d5c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 27 Oct 2023 10:57:39 +0200 Subject: [PATCH 2768/4498] Bluetooth: Controller: Avoid division by 0 with BT_CTLR_THROUGHPUT With very fast HCI interfaces (for ex. in the simulated nrf5340) the tx_rate calculation can do a division by 0 (if to packets are enqueued in the same 32KHz clock period). Let's avoid it. Signed-off-by: Alberto Escolar Piedras --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 1640c00e87e..193483b6379 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -273,6 +273,9 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx) pdu = (void *)((struct node_tx *)tx)->pdu; tx_len += pdu->len; + if (delta == 0) { /* Let's avoid a division by 0 if we happen to have a really fast HCI IF*/ + delta = 1; + } tx_rate = ((uint64_t)tx_len << 3) * BT_CTLR_THROUGHPUT_PERIOD / delta; tx_cnt++; #endif /* CONFIG_BT_CTLR_THROUGHPUT */ From e934e49aa92d8adcd0447082ac4167d17084362d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 10:57:21 +0100 Subject: [PATCH 2769/4498] tests bsim cis: Fix sim_id collision This test was reusing the sim_id from an l2cap test, which was colliding with the corresponding l2cap test when they were run in parallel. Fix it. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh index 258da046f70..5cf55fde8e3 100755 --- a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh +++ b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis.sh @@ -4,7 +4,7 @@ source ${ZEPHYR_BASE}/tests/bsim/sh_common.source -simulation_id="l2cap_send_on_connect" +simulation_id="iso_cis" verbosity_level=2 EXECUTE_TIMEOUT=120 From 49ce05420059f8cb41e8bc933449880a48663525 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:21:55 +0200 Subject: [PATCH 2770/4498] drivers: adc: fix thread function signatures Fix the data acquisition thread function signatures to avoid a stack corruption on thread exit. Fixes #62637 Signed-off-by: Benedikt Schmidt --- drivers/adc/adc_ads1119.c | 8 ++++++-- drivers/adc/adc_ads114s0x.c | 8 ++++++-- drivers/adc/adc_ads1x1x.c | 8 ++++++-- drivers/adc/adc_ads7052.c | 8 ++++++-- drivers/adc/adc_b91.c | 8 ++++++-- drivers/adc/adc_emul.c | 8 ++++++-- drivers/adc/adc_lmp90xxx.c | 8 ++++++-- drivers/adc/adc_max11102_17.c | 8 ++++++-- drivers/adc/adc_max1125x.c | 8 ++++++-- drivers/adc/adc_mcp320x.c | 8 ++++++-- drivers/wifi/eswifi/eswifi_bus_spi.c | 7 +++++-- 11 files changed, 65 insertions(+), 22 deletions(-) diff --git a/drivers/adc/adc_ads1119.c b/drivers/adc/adc_ads1119.c index 45146b389d7..1abdcaad720 100644 --- a/drivers/adc/adc_ads1119.c +++ b/drivers/adc/adc_ads1119.c @@ -433,8 +433,12 @@ static int ads1119_read(const struct device *dev, #endif #if CONFIG_ADC_ASYNC -static void ads1119_acquisition_thread(struct device *dev) +static void ads1119_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; while (true) { ads1119_adc_perform_read(dev); } @@ -466,7 +470,7 @@ static int ads1119_init(const struct device *dev) k_tid_t tid = k_thread_create(&data->thread, config->stack, CONFIG_ADC_ADS1119_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)ads1119_acquisition_thread, + ads1119_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_ADS1119_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_ads114s0x.c b/drivers/adc/adc_ads114s0x.c index b8d0d661d18..4ad78c7246a 100644 --- a/drivers/adc/adc_ads114s0x.c +++ b/drivers/adc/adc_ads114s0x.c @@ -1063,8 +1063,12 @@ static int ads114s0x_read(const struct device *dev, const struct adc_sequence *s #endif #if CONFIG_ADC_ASYNC -static void ads114s0x_acquisition_thread(struct device *dev) +static void ads114s0x_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; while (true) { ads114s0x_adc_perform_read(dev); } @@ -1354,7 +1358,7 @@ static int ads114s0x_init(const struct device *dev) #if CONFIG_ADC_ASYNC k_tid_t tid = k_thread_create( &data->thread, config->stack, CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)ads114s0x_acquisition_thread, (void *)dev, NULL, NULL, + ads114s0x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_ADS114S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT); k_thread_name_set(tid, "adc_ads114s0x"); #endif diff --git a/drivers/adc/adc_ads1x1x.c b/drivers/adc/adc_ads1x1x.c index fee15e38d01..6b2a476f24b 100644 --- a/drivers/adc/adc_ads1x1x.c +++ b/drivers/adc/adc_ads1x1x.c @@ -537,8 +537,12 @@ static int ads1x1x_read(const struct device *dev, const struct adc_sequence *seq return ads1x1x_adc_read_async(dev, sequence, NULL); } -static void ads1x1x_acquisition_thread(const struct device *dev) +static void ads1x1x_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct ads1x1x_data *data = dev->data; int rc; @@ -572,7 +576,7 @@ static int ads1x1x_init(const struct device *dev) k_tid_t tid = k_thread_create(&data->thread, data->stack, K_THREAD_STACK_SIZEOF(data->stack), - (k_thread_entry_t)ads1x1x_acquisition_thread, (void *)dev, NULL, + ads1x1x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_ADS1X1X_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); k_thread_name_set(tid, "adc_ads1x1x"); diff --git a/drivers/adc/adc_ads7052.c b/drivers/adc/adc_ads7052.c index 14b79459505..735c73a1bf0 100644 --- a/drivers/adc/adc_ads7052.c +++ b/drivers/adc/adc_ads7052.c @@ -219,8 +219,12 @@ static int ads7052_read_channel(const struct device *dev, uint8_t channel, uint1 return 0; } -static void ads7052_acquisition_thread(struct ads7052_data *data) +static void ads7052_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct ads7052_data *data = p1; uint16_t result = 0; uint8_t channel; int err = 0; @@ -272,7 +276,7 @@ static int adc_ads7052_init(const struct device *dev) k_thread_create(&data->thread, data->stack, CONFIG_ADC_ADS7052_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)ads7052_acquisition_thread, data, NULL, NULL, + ads7052_acquisition_thread, data, NULL, NULL, CONFIG_ADC_ADS7052_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); adc_context_unlock_unconditionally(&data->ctx); diff --git a/drivers/adc/adc_b91.c b/drivers/adc/adc_b91.c index 4b1d4abba26..30e76c88a76 100644 --- a/drivers/adc/adc_b91.c +++ b/drivers/adc/adc_b91.c @@ -216,8 +216,12 @@ static int adc_b91_adc_start_read(const struct device *dev, const struct adc_seq } /* Main ADC Acquisition thread */ -static void adc_b91_acquisition_thread(const struct device *dev) +static void adc_b91_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; int16_t adc_code; struct b91_adc_data *data = dev->data; @@ -260,7 +264,7 @@ static int adc_b91_init(const struct device *dev) k_thread_create(&data->thread, data->stack, CONFIG_ADC_B91_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)adc_b91_acquisition_thread, + adc_b91_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_B91_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_emul.c b/drivers/adc/adc_emul.c index 4ef7a869390..20b9764fd5f 100644 --- a/drivers/adc/adc_emul.c +++ b/drivers/adc/adc_emul.c @@ -470,8 +470,12 @@ static int adc_emul_get_chan_value(struct adc_emul_data *data, * * @return This thread should not end */ -static void adc_emul_acquisition_thread(struct adc_emul_data *data) +static void adc_emul_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct adc_emul_data *data = p1; int err; while (true) { @@ -533,7 +537,7 @@ static int adc_emul_init(const struct device *dev) k_thread_create(&data->thread, data->stack, CONFIG_ADC_EMUL_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)adc_emul_acquisition_thread, + adc_emul_acquisition_thread, data, NULL, NULL, CONFIG_ADC_EMUL_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_lmp90xxx.c b/drivers/adc/adc_lmp90xxx.c index 7ecb2c6cfa6..2dc23a792f3 100644 --- a/drivers/adc/adc_lmp90xxx.c +++ b/drivers/adc/adc_lmp90xxx.c @@ -650,8 +650,12 @@ static int lmp90xxx_adc_read_channel(const struct device *dev, return 0; } -static void lmp90xxx_acquisition_thread(struct lmp90xxx_data *data) +static void lmp90xxx_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lmp90xxx_data *data = p1; uint8_t bgcalcn = LMP90XXX_BGCALN(0x3); /* Default to BgCalMode3 */ int32_t result = 0; uint8_t channel; @@ -1014,7 +1018,7 @@ static int lmp90xxx_init(const struct device *dev) tid = k_thread_create(&data->thread, data->stack, CONFIG_ADC_LMP90XXX_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)lmp90xxx_acquisition_thread, + lmp90xxx_acquisition_thread, data, NULL, NULL, CONFIG_ADC_LMP90XXX_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); diff --git a/drivers/adc/adc_max11102_17.c b/drivers/adc/adc_max11102_17.c index 8476776c8c3..5443de03753 100644 --- a/drivers/adc/adc_max11102_17.c +++ b/drivers/adc/adc_max11102_17.c @@ -315,8 +315,12 @@ static int max11102_17_read(const struct device *dev, const struct adc_sequence #endif #if CONFIG_ADC_ASYNC -static void max11102_17_acquisition_thread(const struct device *dev) +static void max11102_17_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; while (true) { max11102_17_adc_perform_read(dev); } @@ -368,7 +372,7 @@ static int max11102_17_init(const struct device *dev) #if CONFIG_ADC_ASYNC k_tid_t tid = k_thread_create( &data->thread, data->stack, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)max11102_17_acquisition_thread, (void *)dev, NULL, NULL, + max11102_17_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_MAX11102_17_ACQUISITION_THREAD_INIT_PRIO, 0, K_NO_WAIT); k_thread_name_set(tid, "adc_max11102_17"); #endif diff --git a/drivers/adc/adc_max1125x.c b/drivers/adc/adc_max1125x.c index 11f69ac09e7..a6e005defff 100644 --- a/drivers/adc/adc_max1125x.c +++ b/drivers/adc/adc_max1125x.c @@ -690,8 +690,12 @@ static int max1125x_read(const struct device *dev, const struct adc_sequence *se return max1125x_adc_read_async(dev, sequence, NULL); } -static void max1125x_acquisition_thread(const struct device *dev) +static void max1125x_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct max1125x_data *data = dev->data; int rc; @@ -752,7 +756,7 @@ static int max1125x_init(const struct device *dev) k_tid_t tid = k_thread_create( &data->thread, data->stack, K_THREAD_STACK_SIZEOF(data->stack), - (k_thread_entry_t)max1125x_acquisition_thread, (void *)dev, NULL, NULL, + max1125x_acquisition_thread, (void *)dev, NULL, NULL, CONFIG_ADC_MAX1125X_ACQUISITION_THREAD_PRIORITY, 0, K_NO_WAIT); k_thread_name_set(tid, "adc_max1125x"); diff --git a/drivers/adc/adc_mcp320x.c b/drivers/adc/adc_mcp320x.c index b5ff94a105f..dff4e579c5f 100644 --- a/drivers/adc/adc_mcp320x.c +++ b/drivers/adc/adc_mcp320x.c @@ -232,8 +232,12 @@ static int mcp320x_read_channel(const struct device *dev, uint8_t channel, return 0; } -static void mcp320x_acquisition_thread(struct mcp320x_data *data) +static void mcp320x_acquisition_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct mcp320x_data *data = p1; uint16_t result = 0; uint8_t channel; int err; @@ -281,7 +285,7 @@ static int mcp320x_init(const struct device *dev) k_thread_create(&data->thread, data->stack, CONFIG_ADC_MCP320X_ACQUISITION_THREAD_STACK_SIZE, - (k_thread_entry_t)mcp320x_acquisition_thread, + mcp320x_acquisition_thread, data, NULL, NULL, CONFIG_ADC_MCP320X_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); diff --git a/drivers/wifi/eswifi/eswifi_bus_spi.c b/drivers/wifi/eswifi/eswifi_bus_spi.c index edade1ffdf8..9fb24dda907 100644 --- a/drivers/wifi/eswifi/eswifi_bus_spi.c +++ b/drivers/wifi/eswifi/eswifi_bus_spi.c @@ -219,8 +219,11 @@ static void eswifi_spi_read_msg(struct eswifi_dev *eswifi) eswifi_unlock(eswifi); } -static void eswifi_spi_poll_thread(void *p1) +static void eswifi_spi_poll_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct eswifi_dev *eswifi = p1; while (1) { @@ -255,7 +258,7 @@ int eswifi_spi_init(struct eswifi_dev *eswifi) k_thread_create(&spi->poll_thread, eswifi_spi_poll_stack, ESWIFI_SPI_THREAD_STACK_SIZE, - (k_thread_entry_t)eswifi_spi_poll_thread, eswifi, NULL, + eswifi_spi_poll_thread, eswifi, NULL, NULL, K_PRIO_COOP(CONFIG_WIFI_ESWIFI_THREAD_PRIO), 0, K_NO_WAIT); From c5339243701ac9e0b2469210e5c74b47d2f3963c Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:23:49 +0200 Subject: [PATCH 2771/4498] drivers: can: fix thread function signatures Fix thread function signatures to avoid a stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/can/can_mcp2515.c | 8 ++++++-- drivers/can/can_tcan4x5x.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 4009718e2ba..0a610fba601 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -889,8 +889,12 @@ static void mcp2515_handle_interrupts(const struct device *dev) } } -static void mcp2515_int_thread(const struct device *dev) +static void mcp2515_int_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct mcp2515_data *dev_data = dev->data; while (1) { @@ -998,7 +1002,7 @@ static int mcp2515_init(const struct device *dev) tid = k_thread_create(&dev_data->int_thread, dev_data->int_thread_stack, dev_cfg->int_thread_stack_size, - (k_thread_entry_t) mcp2515_int_thread, (void *)dev, + mcp2515_int_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(dev_cfg->int_thread_priority), 0, K_NO_WAIT); (void)k_thread_name_set(tid, "mcp2515"); diff --git a/drivers/can/can_tcan4x5x.c b/drivers/can/can_tcan4x5x.c index 2d77ce746c3..d80f8e77526 100644 --- a/drivers/can/can_tcan4x5x.c +++ b/drivers/can/can_tcan4x5x.c @@ -408,8 +408,12 @@ static void tcan4x5x_int_gpio_callback_handler(const struct device *port, struct k_sem_give(&tcan_data->int_sem); } -static void tcan4x5x_int_thread(const struct device *dev) +static void tcan4x5x_int_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct can_mcan_data *mcan_data = dev->data; struct tcan4x5x_data *tcan_data = mcan_data->custom; uint32_t status; @@ -637,7 +641,7 @@ static int tcan4x5x_init(const struct device *dev) tid = k_thread_create(&tcan_data->int_thread, tcan_data->int_stack, K_KERNEL_STACK_SIZEOF(tcan_data->int_stack), - (k_thread_entry_t)tcan4x5x_int_thread, (void *)dev, NULL, NULL, + tcan4x5x_int_thread, (void *)dev, NULL, NULL, CONFIG_CAN_TCAN4X5X_THREAD_PRIO, 0, K_NO_WAIT); k_thread_name_set(tid, "tcan4x5x"); From 9247f0e07b23d84c0142c30b8bddae43a4fdbfd3 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:29:41 +0200 Subject: [PATCH 2772/4498] drivers: bluetooth: fix thread function signatures Fix thread function signatures to avoid a stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/bluetooth/hci/h5.c | 16 ++++++++++++---- drivers/bluetooth/hci/ipm_stm32wb.c | 8 ++++++-- drivers/bluetooth/hci/slz_hci.c | 11 ++++++++++- drivers/bluetooth/hci/spi.c | 8 ++++++-- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index c9395509248..25a3b3e28f6 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -607,8 +607,12 @@ static int h5_queue(struct net_buf *buf) return 0; } -static void tx_thread(void) +static void tx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG(""); /* FIXME: make periodic sending */ @@ -653,8 +657,12 @@ static void h5_set_txwin(uint8_t *conf) conf[2] = h5.tx_win & 0x07; } -static void rx_thread(void) +static void rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG(""); while (true) { @@ -721,7 +729,7 @@ static void h5_init(void) k_fifo_init(&h5.tx_queue); k_thread_create(&tx_thread_data, tx_stack, K_KERNEL_STACK_SIZEOF(tx_stack), - (k_thread_entry_t)tx_thread, NULL, NULL, NULL, + tx_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_HCI_TX_PRIO), 0, K_NO_WAIT); k_thread_name_set(&tx_thread_data, "tx_thread"); @@ -729,7 +737,7 @@ static void h5_init(void) k_fifo_init(&h5.rx_queue); k_thread_create(&rx_thread_data, rx_stack, K_KERNEL_STACK_SIZEOF(rx_stack), - (k_thread_entry_t)rx_thread, NULL, NULL, NULL, + rx_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT); k_thread_name_set(&rx_thread_data, "rx_thread"); diff --git a/drivers/bluetooth/hci/ipm_stm32wb.c b/drivers/bluetooth/hci/ipm_stm32wb.c index 9ee261ae3d5..59fef02b2c1 100644 --- a/drivers/bluetooth/hci/ipm_stm32wb.c +++ b/drivers/bluetooth/hci/ipm_stm32wb.c @@ -159,8 +159,12 @@ void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt) k_fifo_put(&ipm_rx_events_fifo, hcievt); } -static void bt_ipm_rx_thread(void) +static void bt_ipm_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { bool discardable = false; k_timeout_t timeout = K_FOREVER; @@ -554,7 +558,7 @@ static int bt_ipm_open(void) /* Start RX thread */ k_thread_create(&ipm_rx_thread_data, ipm_rx_stack, K_KERNEL_STACK_SIZEOF(ipm_rx_stack), - (k_thread_entry_t)bt_ipm_rx_thread, NULL, NULL, NULL, + bt_ipm_rx_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); diff --git a/drivers/bluetooth/hci/slz_hci.c b/drivers/bluetooth/hci/slz_hci.c index 9fe5cb5981c..0526cb02c40 100644 --- a/drivers/bluetooth/hci/slz_hci.c +++ b/drivers/bluetooth/hci/slz_hci.c @@ -117,6 +117,15 @@ static int slz_bt_send(struct net_buf *buf) return rv; } +static void slz_thread_func(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + slz_ll_thread_func(); +} + static int slz_bt_open(void) { int ret; @@ -124,7 +133,7 @@ static int slz_bt_open(void) /* Start RX thread */ k_thread_create(&slz_ll_thread, slz_ll_stack, K_KERNEL_STACK_SIZEOF(slz_ll_stack), - (k_thread_entry_t)slz_ll_thread_func, NULL, NULL, NULL, + slz_thread_func, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 8f5656a70a0..18a5ae10d5f 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -344,8 +344,12 @@ static struct net_buf *bt_spi_rx_buf_construct(uint8_t *msg) return buf; } -static void bt_spi_rx_thread(void) +static void bt_spi_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + uint8_t header_master[5] = { SPI_READ, 0x00, 0x00, 0x00, 0x00 }; uint8_t header_slave[5]; struct net_buf *buf; @@ -528,7 +532,7 @@ static int bt_spi_open(void) /* Start RX thread */ k_thread_create(&spi_rx_thread_data, spi_rx_stack, K_KERNEL_STACK_SIZEOF(spi_rx_stack), - (k_thread_entry_t)bt_spi_rx_thread, NULL, NULL, NULL, + bt_spi_rx_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); From fbef0edb99715f34a283de640b9cfd2505ea88fa Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:32:23 +0200 Subject: [PATCH 2773/4498] drivers: ethernet: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/ethernet/eth_adin2111.c | 8 ++++++-- drivers/ethernet/eth_enc28j60.c | 8 ++++++-- drivers/ethernet/eth_enc424j600.c | 8 ++++++-- drivers/ethernet/eth_native_posix.c | 8 ++++++-- drivers/ethernet/eth_w5500.c | 8 ++++++-- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index 3ee08f30b75..070b8698c10 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -264,8 +264,12 @@ static inline void adin2111_port_on_phyint(const struct device *dev) } } -static void adin2111_offload_thread(const struct device *dev) +static void adin2111_offload_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct adin2111_data *ctx = dev->data; const struct adin2111_config *adin_cfg = dev->config; bool is_adin2111 = (adin_cfg->id == ADIN2111_MAC); @@ -669,7 +673,7 @@ static void adin2111_port_iface_init(struct net_if *iface) /* all ifaces are done, start INT processing */ k_thread_create(&ctx->rx_thread, ctx->rx_thread_stack, CONFIG_ETH_ADIN2111_IRQ_THREAD_STACK_SIZE, - (k_thread_entry_t)adin2111_offload_thread, + adin2111_offload_thread, (void *)adin, NULL, NULL, CONFIG_ETH_ADIN2111_IRQ_THREAD_PRIO, K_ESSENTIAL, K_NO_WAIT); diff --git a/drivers/ethernet/eth_enc28j60.c b/drivers/ethernet/eth_enc28j60.c index 35aacd8753a..502d0cc1199 100644 --- a/drivers/ethernet/eth_enc28j60.c +++ b/drivers/ethernet/eth_enc28j60.c @@ -708,8 +708,12 @@ static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag) return 0; } -static void eth_enc28j60_rx_thread(const struct device *dev) +static void eth_enc28j60_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct eth_enc28j60_runtime *context = dev->data; uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC; uint8_t int_stat; @@ -850,7 +854,7 @@ static int eth_enc28j60_init(const struct device *dev) /* Start interruption-poll thread */ k_thread_create(&context->thread, context->thread_stack, CONFIG_ETH_ENC28J60_RX_THREAD_STACK_SIZE, - (k_thread_entry_t)eth_enc28j60_rx_thread, + eth_enc28j60_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_ETH_ENC28J60_RX_THREAD_PRIO), 0, K_NO_WAIT); diff --git a/drivers/ethernet/eth_enc424j600.c b/drivers/ethernet/eth_enc424j600.c index c4ab7440058..b2b645652ce 100644 --- a/drivers/ethernet/eth_enc424j600.c +++ b/drivers/ethernet/eth_enc424j600.c @@ -442,8 +442,12 @@ static int enc424j600_rx(const struct device *dev) return 0; } -static void enc424j600_rx_thread(struct enc424j600_runtime *context) +static void enc424j600_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct enc424j600_runtime *context = p1; uint16_t eir; uint16_t estat; uint8_t counter; @@ -767,7 +771,7 @@ static int enc424j600_init(const struct device *dev) /* Start interruption-poll thread */ k_thread_create(&context->thread, context->thread_stack, CONFIG_ETH_ENC424J600_RX_THREAD_STACK_SIZE, - (k_thread_entry_t)enc424j600_rx_thread, + enc424j600_rx_thread, context, NULL, NULL, K_PRIO_COOP(CONFIG_ETH_ENC424J600_RX_THREAD_PRIO), 0, K_NO_WAIT); diff --git a/drivers/ethernet/eth_native_posix.c b/drivers/ethernet/eth_native_posix.c index 83697642f77..4c0a9b0a7f1 100644 --- a/drivers/ethernet/eth_native_posix.c +++ b/drivers/ethernet/eth_native_posix.c @@ -364,8 +364,12 @@ static int read_data(struct eth_context *ctx, int fd) return 0; } -static void eth_rx(struct eth_context *ctx) +static void eth_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct eth_context *ctx = p1; LOG_DBG("Starting ZETH RX thread"); while (1) { @@ -391,7 +395,7 @@ static void create_rx_handler(struct eth_context *ctx) k_thread_create(ctx->rx_thread, ctx->rx_stack, ctx->rx_stack_size, - (k_thread_entry_t)eth_rx, + eth_rx, ctx, NULL, NULL, K_PRIO_COOP(14), 0, K_NO_WAIT); diff --git a/drivers/ethernet/eth_w5500.c b/drivers/ethernet/eth_w5500.c index 03b5cb752d1..88a2d710b72 100644 --- a/drivers/ethernet/eth_w5500.c +++ b/drivers/ethernet/eth_w5500.c @@ -275,8 +275,12 @@ static void w5500_rx(const struct device *dev) w5500_command(dev, S0_CR_RECV); } -static void w5500_thread(const struct device *dev) +static void w5500_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; uint8_t ir; struct w5500_runtime *ctx = dev->data; const struct w5500_config *config = dev->config; @@ -557,7 +561,7 @@ static int w5500_init(const struct device *dev) k_thread_create(&ctx->thread, ctx->thread_stack, CONFIG_ETH_W5500_RX_THREAD_STACK_SIZE, - (k_thread_entry_t)w5500_thread, + w5500_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_ETH_W5500_RX_THREAD_PRIO), 0, K_NO_WAIT); From 9eb993c063a6839a2a70bbe9ed1bf7c8f04d70ff Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:35:29 +0200 Subject: [PATCH 2774/4498] drivers: ieee802154: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/ieee802154/ieee802154_cc1200.c | 9 ++++++--- drivers/ieee802154/ieee802154_cc2520.c | 9 ++++++--- drivers/ieee802154/ieee802154_mcr20a.c | 9 ++++++--- drivers/ieee802154/ieee802154_rf2xx.c | 9 ++++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc1200.c b/drivers/ieee802154/ieee802154_cc1200.c index 0c7901dfda3..e5f8ea36670 100644 --- a/drivers/ieee802154/ieee802154_cc1200.c +++ b/drivers/ieee802154/ieee802154_cc1200.c @@ -446,9 +446,12 @@ static inline bool verify_crc(const struct device *dev, struct net_pkt *pkt) return true; } -static void cc1200_rx(void *arg) +static void cc1200_rx(void *p1, void *p2, void *p3) { - const struct device *dev = arg; + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct cc1200_context *cc1200 = dev->data; struct net_pkt *pkt; uint8_t pkt_len; @@ -779,7 +782,7 @@ static int cc1200_init(const struct device *dev) k_thread_create(&cc1200->rx_thread, cc1200->rx_stack, CONFIG_IEEE802154_CC1200_RX_STACK_SIZE, - (k_thread_entry_t)cc1200_rx, + cc1200_rx, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&cc1200->rx_thread, "cc1200_rx"); diff --git a/drivers/ieee802154/ieee802154_cc2520.c b/drivers/ieee802154/ieee802154_cc2520.c index 05404314d1f..cf7c1091661 100644 --- a/drivers/ieee802154/ieee802154_cc2520.c +++ b/drivers/ieee802154/ieee802154_cc2520.c @@ -591,9 +591,12 @@ static inline bool verify_rxfifo_validity(const struct device *dev, return true; } -static void cc2520_rx(void *arg) +static void cc2520_rx(void *p1, void *p2, void *p3) { - const struct device *dev = arg; + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct cc2520_context *cc2520 = dev->data; struct net_pkt *pkt; uint8_t pkt_len; @@ -1020,7 +1023,7 @@ static int cc2520_init(const struct device *dev) k_thread_create(&cc2520->cc2520_rx_thread, cc2520->cc2520_rx_stack, CONFIG_IEEE802154_CC2520_RX_STACK_SIZE, - (k_thread_entry_t)cc2520_rx, + cc2520_rx, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&cc2520->cc2520_rx_thread, "cc2520_rx"); diff --git a/drivers/ieee802154/ieee802154_mcr20a.c b/drivers/ieee802154/ieee802154_mcr20a.c index 5ba4e844a95..6a1e5a99727 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.c +++ b/drivers/ieee802154/ieee802154_mcr20a.c @@ -730,9 +730,12 @@ static inline bool irqsts3_event(const struct device *dev, return retval; } -static void mcr20a_thread_main(void *arg) +static void mcr20a_thread_main(void *p1, void *p2, void *p3) { - const struct device *dev = arg; + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct mcr20a_context *mcr20a = dev->data; uint8_t dregs[MCR20A_PHY_CTRL4 + 1]; bool set_new_seq; @@ -1419,7 +1422,7 @@ static int mcr20a_init(const struct device *dev) k_thread_create(&mcr20a->mcr20a_rx_thread, mcr20a->mcr20a_rx_stack, CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE, - (k_thread_entry_t)mcr20a_thread_main, + mcr20a_thread_main, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&mcr20a->mcr20a_rx_thread, "mcr20a_rx"); diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index 870eb8a2f70..ac7f13580d0 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -291,9 +291,12 @@ static void rf2xx_process_trx_end(const struct device *dev) } } -static void rf2xx_thread_main(void *arg) +static void rf2xx_thread_main(void *p1, void *p2, void *p3) { - struct rf2xx_context *ctx = arg; + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct rf2xx_context *ctx = p1; uint8_t isr_status; while (true) { @@ -1036,7 +1039,7 @@ static int rf2xx_init(const struct device *dev) k_thread_create(&ctx->trx_thread, ctx->trx_stack, CONFIG_IEEE802154_RF2XX_RX_STACK_SIZE, - (k_thread_entry_t) rf2xx_thread_main, + rf2xx_thread_main, ctx, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); From ba49cb81f13274078e7b6b3eb6dec8f90e4818e3 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:37:47 +0200 Subject: [PATCH 2775/4498] drivers: modem: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/modem/gsm_ppp.c | 8 ++++++-- drivers/modem/hl7800.c | 8 ++++++-- drivers/modem/quectel-bg9x.c | 8 ++++++-- drivers/modem/simcom-sim7080.c | 8 ++++++-- drivers/modem/ublox-sara-r4.c | 8 ++++++-- drivers/modem/wncm14a2a.c | 8 ++++++-- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/modem/gsm_ppp.c b/drivers/modem/gsm_ppp.c index 34eb0bbb550..154092ac356 100644 --- a/drivers/modem/gsm_ppp.c +++ b/drivers/modem/gsm_ppp.c @@ -169,8 +169,12 @@ static int modem_atoi(const char *s, const int err_value, } #endif -static void gsm_rx(struct gsm_modem *gsm) +static void gsm_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct gsm_modem *gsm = p1; LOG_DBG("starting"); while (true) { @@ -1323,7 +1327,7 @@ static int gsm_init(const struct device *dev) (void)k_thread_create(&gsm->rx_thread, gsm_rx_stack, K_KERNEL_STACK_SIZEOF(gsm_rx_stack), - (k_thread_entry_t) gsm_rx, + gsm_rx, gsm, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); (void)k_thread_name_set(&gsm->rx_thread, "gsm_rx"); diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c index 291856a01ff..c635016197e 100644 --- a/drivers/modem/hl7800.c +++ b/drivers/modem/hl7800.c @@ -4482,8 +4482,12 @@ static void process_fw_update_rx(struct net_buf **rx_buf) #endif /* CONFIG_MODEM_HL7800_FW_UPDATE */ /* RX thread */ -static void hl7800_rx(void) +static void hl7800_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct net_buf *rx_buf = NULL; struct net_buf *frag = NULL; int i, cmp_res; @@ -6426,7 +6430,7 @@ static int hl7800_init(const struct device *dev) k_thread_name_set( k_thread_create(&hl7800_rx_thread, hl7800_rx_stack, K_THREAD_STACK_SIZEOF(hl7800_rx_stack), - (k_thread_entry_t)hl7800_rx, NULL, NULL, NULL, + hl7800_rx, NULL, NULL, NULL, RX_THREAD_PRIORITY, 0, K_NO_WAIT), "hl7800 rx"); diff --git a/drivers/modem/quectel-bg9x.c b/drivers/modem/quectel-bg9x.c index 04bb08d665e..714a7606ab6 100644 --- a/drivers/modem/quectel-bg9x.c +++ b/drivers/modem/quectel-bg9x.c @@ -846,8 +846,12 @@ static ssize_t offload_sendmsg(void *obj, const struct msghdr *msg, int flags) /* Func: modem_rx * Desc: Thread to process all messages received from the Modem. */ -static void modem_rx(void) +static void modem_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { /* Wait for incoming data */ @@ -1264,7 +1268,7 @@ static int modem_init(const struct device *dev) /* start RX thread */ k_thread_create(&modem_rx_thread, modem_rx_stack, K_KERNEL_STACK_SIZEOF(modem_rx_stack), - (k_thread_entry_t) modem_rx, + modem_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); /* Init RSSI query */ diff --git a/drivers/modem/simcom-sim7080.c b/drivers/modem/simcom-sim7080.c index 39fb66b6aa1..b6a159e519d 100644 --- a/drivers/modem/simcom-sim7080.c +++ b/drivers/modem/simcom-sim7080.c @@ -802,8 +802,12 @@ static int offload_socket(int family, int type, int proto) /* * Process all messages received from the modem. */ -static void modem_rx(void) +static void modem_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { /* Wait for incoming data */ modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER); @@ -2414,7 +2418,7 @@ static int modem_init(const struct device *dev) } k_thread_create(&modem_rx_thread, modem_rx_stack, K_KERNEL_STACK_SIZEOF(modem_rx_stack), - (k_thread_entry_t)modem_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + modem_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); /* Init RSSI query */ k_work_init_delayable(&mdata.rssi_query_work, modem_rssi_query_work); diff --git a/drivers/modem/ublox-sara-r4.c b/drivers/modem/ublox-sara-r4.c index ca70b1465e0..a3fe3c45f83 100644 --- a/drivers/modem/ublox-sara-r4.c +++ b/drivers/modem/ublox-sara-r4.c @@ -936,8 +936,12 @@ MODEM_CMD_DEFINE(on_cmd_socknotifycreg) } /* RX thread */ -static void modem_rx(void) +static void modem_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { /* wait for incoming data */ modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER); @@ -2220,7 +2224,7 @@ static int modem_init(const struct device *dev) /* start RX thread */ k_thread_create(&modem_rx_thread, modem_rx_stack, K_KERNEL_STACK_SIZEOF(modem_rx_stack), - (k_thread_entry_t) modem_rx, + modem_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); #if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK) diff --git a/drivers/modem/wncm14a2a.c b/drivers/modem/wncm14a2a.c index 520c4312580..5b60d0aaff5 100644 --- a/drivers/modem/wncm14a2a.c +++ b/drivers/modem/wncm14a2a.c @@ -1057,8 +1057,12 @@ static void wncm14a2a_read_rx(struct net_buf **buf) } /* RX thread */ -static void wncm14a2a_rx(void) +static void wncm14a2a_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct net_buf *rx_buf = NULL; struct net_buf *frag = NULL; int i; @@ -1430,7 +1434,7 @@ static int wncm14a2a_init(const struct device *dev) /* start RX thread */ k_thread_create(&wncm14a2a_rx_thread, wncm14a2a_rx_stack, K_KERNEL_STACK_SIZEOF(wncm14a2a_rx_stack), - (k_thread_entry_t) wncm14a2a_rx, + wncm14a2a_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); /* init RSSI query */ From 191865b51c06660f3a559e7776b49688008f4411 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:53:22 +0200 Subject: [PATCH 2776/4498] drivers: sensor: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/sensor/adt7310/adt7310_trigger.c | 9 +++++++-- drivers/sensor/adt7420/adt7420_trigger.c | 9 +++++++-- drivers/sensor/adxl362/adxl362_trigger.c | 9 +++++++-- drivers/sensor/adxl372/adxl372_trigger.c | 9 +++++++-- drivers/sensor/amg88xx/amg88xx_trigger.c | 9 +++++++-- drivers/sensor/bma280/bma280_trigger.c | 9 +++++++-- drivers/sensor/bmc150_magn/bmc150_magn_trigger.c | 8 ++++++-- drivers/sensor/bmg160/bmg160_trigger.c | 9 +++++++-- drivers/sensor/bmi160/bmi160_trigger.c | 6 ++++-- drivers/sensor/bmi270/bmi270_trigger.c | 9 +++++++-- drivers/sensor/bq274xx/bq274xx_trigger.c | 9 +++++++-- drivers/sensor/ccs811/ccs811_trigger.c | 9 +++++++-- drivers/sensor/fdc2x1x/fdc2x1x_trigger.c | 9 +++++++-- drivers/sensor/fxas21002/fxas21002_trigger.c | 9 +++++++-- drivers/sensor/fxos8700/fxos8700_trigger.c | 9 +++++++-- drivers/sensor/grow_r502a/grow_r502a_trigger.c | 9 +++++++-- drivers/sensor/hmc5883l/hmc5883l_trigger.c | 9 +++++++-- drivers/sensor/hts221/hts221_trigger.c | 9 +++++++-- drivers/sensor/iis2dh/iis2dh_trigger.c | 9 +++++++-- drivers/sensor/iis2dlpc/iis2dlpc_trigger.c | 9 +++++++-- drivers/sensor/iis2iclx/iis2iclx_trigger.c | 9 +++++++-- drivers/sensor/iis2mdc/iis2mdc_trigger.c | 9 +++++++-- drivers/sensor/iis3dhhc/iis3dhhc_trigger.c | 9 +++++++-- drivers/sensor/isl29035/isl29035_trigger.c | 8 ++++++-- drivers/sensor/ism330dhcx/ism330dhcx_trigger.c | 9 +++++++-- drivers/sensor/lis2dh/lis2dh_trigger.c | 9 +++++++-- drivers/sensor/lis2ds12/lis2ds12_trigger.c | 9 +++++++-- drivers/sensor/lis2dw12/lis2dw12_trigger.c | 9 +++++++-- drivers/sensor/lis2mdl/lis2mdl_trigger.c | 9 +++++++-- drivers/sensor/lis3mdl/lis3mdl_trigger.c | 9 +++++++-- drivers/sensor/lps22hh/lps22hh_trigger.c | 9 +++++++-- drivers/sensor/lsm6dsl/lsm6dsl_trigger.c | 8 ++++++-- drivers/sensor/lsm6dso/lsm6dso_trigger.c | 9 +++++++-- drivers/sensor/lsm6dso16is/lsm6dso16is_trigger.c | 9 +++++++-- drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c | 9 +++++++-- drivers/sensor/lsm9ds0_gyro/lsm9ds0_gyro_trigger.c | 8 ++++++-- drivers/sensor/mcp9808/mcp9808_trigger.c | 9 +++++++-- drivers/sensor/mpu6050/mpu6050_trigger.c | 9 +++++++-- drivers/sensor/mpu9250/mpu9250_trigger.c | 9 +++++++-- drivers/sensor/sht3xd/sht3xd_trigger.c | 9 +++++++-- drivers/sensor/sm351lt/sm351lt.c | 2 +- drivers/sensor/stts751/stts751_trigger.c | 9 +++++++-- drivers/sensor/sx9500/sx9500_trigger.c | 9 +++++++-- drivers/sensor/tcn75a/tcn75a_trigger.c | 9 +++++++-- drivers/sensor/tmp007/tmp007_trigger.c | 9 +++++++-- drivers/sensor/tsl2540/tsl2540_trigger.c | 9 +++++++-- drivers/sensor/vcnl4040/vcnl4040_trigger.c | 9 +++++++-- drivers/sensor/wsen_hids/wsen_hids_trigger.c | 9 +++++++-- drivers/sensor/wsen_pads/wsen_pads_trigger.c | 9 +++++++-- drivers/sensor/wsen_tids/wsen_tids_trigger.c | 9 +++++++-- 50 files changed, 337 insertions(+), 99 deletions(-) diff --git a/drivers/sensor/adt7310/adt7310_trigger.c b/drivers/sensor/adt7310/adt7310_trigger.c index 25d264f5768..be989a69910 100644 --- a/drivers/sensor/adt7310/adt7310_trigger.c +++ b/drivers/sensor/adt7310/adt7310_trigger.c @@ -30,8 +30,13 @@ static void adt7310_gpio_callback(const struct device *dev, struct gpio_callback } #if defined(CONFIG_ADT7310_TRIGGER_OWN_THREAD) -static void adt7310_thread(struct adt7310_data *drv_data) +static void adt7310_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct adt7310_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); if (drv_data->th_handler != NULL) { @@ -125,7 +130,7 @@ int adt7310_init_interrupt(const struct device *dev) k_sem_init(&drv_data->gpio_sem, 0, 1); k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_ADT7310_THREAD_STACK_SIZE, - (k_thread_entry_t)adt7310_thread, drv_data, + adt7310_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_ADT7310_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_ADT7310_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/adt7420/adt7420_trigger.c b/drivers/sensor/adt7420/adt7420_trigger.c index 00065eab586..1a26903adc7 100644 --- a/drivers/sensor/adt7420/adt7420_trigger.c +++ b/drivers/sensor/adt7420/adt7420_trigger.c @@ -76,8 +76,13 @@ static void adt7420_gpio_callback(const struct device *dev, } #if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) -static void adt7420_thread(struct adt7420_data *drv_data) +static void adt7420_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct adt7420_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); process_int(drv_data->dev); @@ -162,7 +167,7 @@ int adt7420_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_ADT7420_THREAD_STACK_SIZE, - (k_thread_entry_t)adt7420_thread, drv_data, + adt7420_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_ADT7420_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/adxl362/adxl362_trigger.c b/drivers/sensor/adxl362/adxl362_trigger.c index ba30c0a1826..341e6dad04d 100644 --- a/drivers/sensor/adxl362/adxl362_trigger.c +++ b/drivers/sensor/adxl362/adxl362_trigger.c @@ -62,8 +62,13 @@ static void adxl362_gpio_callback(const struct device *dev, } #if defined(CONFIG_ADXL362_TRIGGER_OWN_THREAD) -static void adxl362_thread(struct adxl362_data *drv_data) +static void adxl362_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct adxl362_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); adxl362_thread_cb(drv_data->dev); @@ -171,7 +176,7 @@ int adxl362_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_ADXL362_THREAD_STACK_SIZE, - (k_thread_entry_t)adxl362_thread, drv_data, + adxl362_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_ADXL362_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/adxl372/adxl372_trigger.c b/drivers/sensor/adxl372/adxl372_trigger.c index adc3d0ba1f7..2d9cca6cfd8 100644 --- a/drivers/sensor/adxl372/adxl372_trigger.c +++ b/drivers/sensor/adxl372/adxl372_trigger.c @@ -69,8 +69,13 @@ static void adxl372_gpio_callback(const struct device *dev, } #if defined(CONFIG_ADXL372_TRIGGER_OWN_THREAD) -static void adxl372_thread(struct adxl372_data *drv_data) +static void adxl372_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct adxl372_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); adxl372_thread_cb(drv_data->dev); @@ -177,7 +182,7 @@ int adxl372_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_ADXL372_THREAD_STACK_SIZE, - (k_thread_entry_t)adxl372_thread, drv_data, + adxl372_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_ADXL372_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/amg88xx/amg88xx_trigger.c b/drivers/sensor/amg88xx/amg88xx_trigger.c index fa1e237edab..7b8d4979ec8 100644 --- a/drivers/sensor/amg88xx/amg88xx_trigger.c +++ b/drivers/sensor/amg88xx/amg88xx_trigger.c @@ -113,8 +113,13 @@ static void amg88xx_thread_cb(const struct device *dev) } #ifdef CONFIG_AMG88XX_TRIGGER_OWN_THREAD -static void amg88xx_thread(struct amg88xx_data *drv_data) +static void amg88xx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct amg88xx_data *drv_data = p1; + while (42) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); amg88xx_thread_cb(drv_data->dev); @@ -196,7 +201,7 @@ int amg88xx_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_AMG88XX_THREAD_STACK_SIZE, - (k_thread_entry_t)amg88xx_thread, drv_data, + amg88xx_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_AMG88XX_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/bma280/bma280_trigger.c b/drivers/sensor/bma280/bma280_trigger.c index a20ce6dc853..5c39950b49f 100644 --- a/drivers/sensor/bma280/bma280_trigger.c +++ b/drivers/sensor/bma280/bma280_trigger.c @@ -127,8 +127,13 @@ static void bma280_thread_cb(const struct device *dev) } #ifdef CONFIG_BMA280_TRIGGER_OWN_THREAD -static void bma280_thread(struct bma280_data *drv_data) +static void bma280_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct bma280_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); bma280_thread_cb(drv_data->dev); @@ -281,7 +286,7 @@ int bma280_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_BMA280_THREAD_STACK_SIZE, - (k_thread_entry_t)bma280_thread, drv_data, + bma280_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_BMA280_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_BMA280_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/bmc150_magn/bmc150_magn_trigger.c b/drivers/sensor/bmc150_magn/bmc150_magn_trigger.c index c51d965bc51..230b5daa8ae 100644 --- a/drivers/sensor/bmc150_magn/bmc150_magn_trigger.c +++ b/drivers/sensor/bmc150_magn/bmc150_magn_trigger.c @@ -81,8 +81,12 @@ static void bmc150_magn_gpio_drdy_callback(const struct device *dev, k_sem_give(&data->sem); } -static void bmc150_magn_thread_main(struct bmc150_magn_data *data) +static void bmc150_magn_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct bmc150_magn_data *data = p1; const struct bmc150_magn_config *config = data->dev->config; uint8_t reg_val; @@ -145,7 +149,7 @@ int bmc150_magn_init_interrupt(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_BMC150_MAGN_TRIGGER_THREAD_STACK, - (k_thread_entry_t)bmc150_magn_thread_main, + bmc150_magn_thread_main, data, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); diff --git a/drivers/sensor/bmg160/bmg160_trigger.c b/drivers/sensor/bmg160/bmg160_trigger.c index c4c7696cf3e..dc6946e7ee9 100644 --- a/drivers/sensor/bmg160/bmg160_trigger.c +++ b/drivers/sensor/bmg160/bmg160_trigger.c @@ -181,8 +181,13 @@ static void bmg160_handle_int(const struct device *dev) static K_KERNEL_STACK_DEFINE(bmg160_thread_stack, CONFIG_BMG160_THREAD_STACK_SIZE); static struct k_thread bmg160_thread; -static void bmg160_thread_main(struct bmg160_device_data *bmg160) +static void bmg160_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct bmg160_device_data *bmg160 = p1; + while (true) { k_sem_take(&bmg160->trig_sem, K_FOREVER); @@ -245,7 +250,7 @@ int bmg160_trigger_init(const struct device *dev) k_sem_init(&bmg160->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&bmg160_thread, bmg160_thread_stack, CONFIG_BMG160_THREAD_STACK_SIZE, - (k_thread_entry_t)bmg160_thread_main, + bmg160_thread_main, bmg160, NULL, NULL, K_PRIO_COOP(CONFIG_BMG160_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/bmi160/bmi160_trigger.c b/drivers/sensor/bmi160/bmi160_trigger.c index 3110977427e..3cb870f1285 100644 --- a/drivers/sensor/bmi160/bmi160_trigger.c +++ b/drivers/sensor/bmi160/bmi160_trigger.c @@ -71,8 +71,10 @@ static void bmi160_handle_interrupts(const struct device *dev) static K_KERNEL_STACK_DEFINE(bmi160_thread_stack, CONFIG_BMI160_THREAD_STACK_SIZE); static struct k_thread bmi160_thread; -static void bmi160_thread_main(struct bmi160_data *data) +static void bmi160_thread_main(void *p1, void *p2, void *p3) { + struct bmi160_data *data = p1; + while (1) { k_sem_take(&data->sem, K_FOREVER); bmi160_handle_interrupts(data->dev); @@ -276,7 +278,7 @@ int bmi160_trigger_mode_init(const struct device *dev) k_thread_create(&bmi160_thread, bmi160_thread_stack, CONFIG_BMI160_THREAD_STACK_SIZE, - (k_thread_entry_t)bmi160_thread_main, + bmi160_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_BMI160_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/bmi270/bmi270_trigger.c b/drivers/sensor/bmi270/bmi270_trigger.c index 1fc21b14251..656b5d23d16 100644 --- a/drivers/sensor/bmi270/bmi270_trigger.c +++ b/drivers/sensor/bmi270/bmi270_trigger.c @@ -85,8 +85,13 @@ static void bmi270_thread_cb(const struct device *dev) } #ifdef CONFIG_BMI270_TRIGGER_OWN_THREAD -static void bmi270_thread(struct bmi270_data *data) +static void bmi270_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct bmi270_data *data = p1; + while (1) { k_sem_take(&data->trig_sem, K_FOREVER); bmi270_thread_cb(data->dev); @@ -173,7 +178,7 @@ int bmi270_init_interrupts(const struct device *dev) #if CONFIG_BMI270_TRIGGER_OWN_THREAD k_sem_init(&data->trig_sem, 0, 1); k_thread_create(&data->thread, data->thread_stack, CONFIG_BMI270_THREAD_STACK_SIZE, - (k_thread_entry_t)bmi270_thread, data, NULL, NULL, + bmi270_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_BMI270_THREAD_PRIORITY), 0, K_NO_WAIT); #elif CONFIG_BMI270_TRIGGER_GLOBAL_THREAD k_work_init(&data->trig_work, bmi270_trig_work_cb); diff --git a/drivers/sensor/bq274xx/bq274xx_trigger.c b/drivers/sensor/bq274xx/bq274xx_trigger.c index 9b276f3b5ff..40f20e8b955 100644 --- a/drivers/sensor/bq274xx/bq274xx_trigger.c +++ b/drivers/sensor/bq274xx/bq274xx_trigger.c @@ -31,8 +31,13 @@ static void bq274xx_handle_interrupts(const struct device *dev) static K_KERNEL_STACK_DEFINE(bq274xx_thread_stack, CONFIG_BQ274XX_THREAD_STACK_SIZE); static struct k_thread bq274xx_thread; -static void bq274xx_thread_main(struct bq274xx_data *data) +static void bq274xx_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct bq274xx_data *data = p1; + while (1) { k_sem_take(&data->sem, K_FOREVER); bq274xx_handle_interrupts(data->dev); @@ -79,7 +84,7 @@ int bq274xx_trigger_mode_init(const struct device *dev) k_thread_create(&bq274xx_thread, bq274xx_thread_stack, CONFIG_BQ274XX_THREAD_STACK_SIZE, - (k_thread_entry_t)bq274xx_thread_main, + bq274xx_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_BQ274XX_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/ccs811/ccs811_trigger.c b/drivers/sensor/ccs811/ccs811_trigger.c index 29750bd6bb3..5a7ef006d01 100644 --- a/drivers/sensor/ccs811/ccs811_trigger.c +++ b/drivers/sensor/ccs811/ccs811_trigger.c @@ -98,8 +98,13 @@ static void gpio_callback(const struct device *dev, } #ifdef CONFIG_CCS811_TRIGGER_OWN_THREAD -static void irq_thread(struct ccs811_data *drv_data) +static void irq_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct ccs811_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); process_irq(drv_data->dev); @@ -192,7 +197,7 @@ int ccs811_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_CCS811_THREAD_STACK_SIZE, - (k_thread_entry_t)irq_thread, drv_data, + irq_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_CCS811_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_CCS811_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/fdc2x1x/fdc2x1x_trigger.c b/drivers/sensor/fdc2x1x/fdc2x1x_trigger.c index 61697d24605..519d5af0d61 100644 --- a/drivers/sensor/fdc2x1x/fdc2x1x_trigger.c +++ b/drivers/sensor/fdc2x1x/fdc2x1x_trigger.c @@ -60,8 +60,13 @@ static void fdc2x1x_gpio_callback(const struct device *dev, } #ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD -static void fdc2x1x_thread(struct fdc2x1x_data *drv_data) +static void fdc2x1x_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct fdc2x1x_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); fdc2x1x_thread_cb(drv_data->dev); @@ -158,7 +163,7 @@ int fdc2x1x_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_FDC2X1X_THREAD_STACK_SIZE, - (k_thread_entry_t)fdc2x1x_thread, + fdc2x1x_thread, drv_data, 0, NULL, K_PRIO_COOP(CONFIG_FDC2X1X_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/fxas21002/fxas21002_trigger.c b/drivers/sensor/fxas21002/fxas21002_trigger.c index 966ed5e2cba..b32d2f5f7d0 100644 --- a/drivers/sensor/fxas21002/fxas21002_trigger.c +++ b/drivers/sensor/fxas21002/fxas21002_trigger.c @@ -68,8 +68,13 @@ static void fxas21002_handle_int(const struct device *dev) } #ifdef CONFIG_FXAS21002_TRIGGER_OWN_THREAD -static void fxas21002_thread_main(struct fxas21002_data *data) +static void fxas21002_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct fxas21002_data *data = p1; + while (true) { k_sem_take(&data->trig_sem, K_FOREVER); fxas21002_handle_int(data->dev); @@ -173,7 +178,7 @@ int fxas21002_trigger_init(const struct device *dev) k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_FXAS21002_THREAD_STACK_SIZE, - (k_thread_entry_t)fxas21002_thread_main, data, 0, NULL, + fxas21002_thread_main, data, 0, NULL, K_PRIO_COOP(CONFIG_FXAS21002_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_FXAS21002_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/fxos8700/fxos8700_trigger.c b/drivers/sensor/fxos8700/fxos8700_trigger.c index d9adaf8d38f..53d493ac44d 100644 --- a/drivers/sensor/fxos8700/fxos8700_trigger.c +++ b/drivers/sensor/fxos8700/fxos8700_trigger.c @@ -168,8 +168,13 @@ static void fxos8700_handle_int(const struct device *dev) } #ifdef CONFIG_FXOS8700_TRIGGER_OWN_THREAD -static void fxos8700_thread_main(struct fxos8700_data *data) +static void fxos8700_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct fxos8700_data *data = p1; + while (true) { k_sem_take(&data->trig_sem, K_FOREVER); fxos8700_handle_int(data->dev); @@ -395,7 +400,7 @@ int fxos8700_trigger_init(const struct device *dev) k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_FXOS8700_THREAD_STACK_SIZE, - (k_thread_entry_t)fxos8700_thread_main, + fxos8700_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_FXOS8700_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/grow_r502a/grow_r502a_trigger.c b/drivers/sensor/grow_r502a/grow_r502a_trigger.c index 7f4e97874bd..1513b896d94 100644 --- a/drivers/sensor/grow_r502a/grow_r502a_trigger.c +++ b/drivers/sensor/grow_r502a/grow_r502a_trigger.c @@ -71,8 +71,13 @@ static void grow_r502a_gpio_callback(const struct device *dev, } #if defined(CONFIG_GROW_R502A_TRIGGER_OWN_THREAD) -static void grow_r502a_thread(struct grow_r502a_data *drv_data) +static void grow_r502a_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct grow_r502a_data *drv_data = p1; + while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); process_int(drv_data->gpio_dev); @@ -111,7 +116,7 @@ int grow_r502a_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_GROW_R502A_THREAD_STACK_SIZE, - (k_thread_entry_t)grow_r502a_thread, drv_data, NULL, + grow_r502a_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_GROW_R502A_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_GROW_R502A_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/hmc5883l/hmc5883l_trigger.c b/drivers/sensor/hmc5883l/hmc5883l_trigger.c index da73a10807c..c3a1d00891c 100644 --- a/drivers/sensor/hmc5883l/hmc5883l_trigger.c +++ b/drivers/sensor/hmc5883l/hmc5883l_trigger.c @@ -78,8 +78,13 @@ static void hmc5883l_thread_cb(const struct device *dev) } #ifdef CONFIG_HMC5883L_TRIGGER_OWN_THREAD -static void hmc5883l_thread(struct hmc5883l_data *drv_data) +static void hmc5883l_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct hmc5883l_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); hmc5883l_thread_cb(drv_data->dev); @@ -124,7 +129,7 @@ int hmc5883l_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_HMC5883L_THREAD_STACK_SIZE, - (k_thread_entry_t)hmc5883l_thread, + hmc5883l_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_HMC5883L_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/hts221/hts221_trigger.c b/drivers/sensor/hts221/hts221_trigger.c index 9019706a34b..1ebccb2a3c5 100644 --- a/drivers/sensor/hts221/hts221_trigger.c +++ b/drivers/sensor/hts221/hts221_trigger.c @@ -95,8 +95,13 @@ static void hts221_drdy_callback(const struct device *dev, } #ifdef CONFIG_HTS221_TRIGGER_OWN_THREAD -static void hts221_thread(struct hts221_data *data) +static void hts221_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct hts221_data *data = p1; + while (1) { k_sem_take(&data->drdy_sem, K_FOREVER); process_drdy(data->dev); @@ -163,7 +168,7 @@ int hts221_init_interrupt(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_HTS221_THREAD_STACK_SIZE, - (k_thread_entry_t)hts221_thread, data, + hts221_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_HTS221_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/iis2dh/iis2dh_trigger.c b/drivers/sensor/iis2dh/iis2dh_trigger.c index edbcf01493b..d108c52c398 100644 --- a/drivers/sensor/iis2dh/iis2dh_trigger.c +++ b/drivers/sensor/iis2dh/iis2dh_trigger.c @@ -112,8 +112,13 @@ static void iis2dh_gpio_callback(const struct device *dev, } #ifdef CONFIG_IIS2DH_TRIGGER_OWN_THREAD -static void iis2dh_thread(struct iis2dh_data *iis2dh) +static void iis2dh_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct iis2dh_data *iis2dh = p1; + while (1) { k_sem_take(&iis2dh->gpio_sem, K_FOREVER); iis2dh_handle_interrupt(iis2dh->dev); @@ -149,7 +154,7 @@ int iis2dh_init_interrupt(const struct device *dev) k_thread_create(&iis2dh->thread, iis2dh->thread_stack, CONFIG_IIS2DH_THREAD_STACK_SIZE, - (k_thread_entry_t)iis2dh_thread, iis2dh, + iis2dh_thread, iis2dh, 0, NULL, K_PRIO_COOP(CONFIG_IIS2DH_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_IIS2DH_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/iis2dlpc/iis2dlpc_trigger.c b/drivers/sensor/iis2dlpc/iis2dlpc_trigger.c index 381e3318aa5..90cdb4b857f 100644 --- a/drivers/sensor/iis2dlpc/iis2dlpc_trigger.c +++ b/drivers/sensor/iis2dlpc/iis2dlpc_trigger.c @@ -233,8 +233,13 @@ static void iis2dlpc_gpio_callback(const struct device *dev, } #ifdef CONFIG_IIS2DLPC_TRIGGER_OWN_THREAD -static void iis2dlpc_thread(struct iis2dlpc_data *iis2dlpc) +static void iis2dlpc_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct iis2dlpc_data *iis2dlpc = p1; + while (1) { k_sem_take(&iis2dlpc->gpio_sem, K_FOREVER); iis2dlpc_handle_interrupt(iis2dlpc->dev); @@ -270,7 +275,7 @@ int iis2dlpc_init_interrupt(const struct device *dev) k_thread_create(&iis2dlpc->thread, iis2dlpc->thread_stack, CONFIG_IIS2DLPC_THREAD_STACK_SIZE, - (k_thread_entry_t)iis2dlpc_thread, iis2dlpc, + iis2dlpc_thread, iis2dlpc, NULL, NULL, K_PRIO_COOP(CONFIG_IIS2DLPC_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_IIS2DLPC_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/iis2iclx/iis2iclx_trigger.c b/drivers/sensor/iis2iclx/iis2iclx_trigger.c index 6360ab69d72..174583c75e7 100644 --- a/drivers/sensor/iis2iclx/iis2iclx_trigger.c +++ b/drivers/sensor/iis2iclx/iis2iclx_trigger.c @@ -182,8 +182,13 @@ static void iis2iclx_gpio_callback(const struct device *dev, } #ifdef CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD -static void iis2iclx_thread(struct iis2iclx_data *iis2iclx) +static void iis2iclx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct iis2iclx_data *iis2iclx = p1; + while (1) { k_sem_take(&iis2iclx->gpio_sem, K_FOREVER); iis2iclx_handle_interrupt(iis2iclx->dev); @@ -218,7 +223,7 @@ int iis2iclx_init_interrupt(const struct device *dev) k_thread_create(&iis2iclx->thread, iis2iclx->thread_stack, CONFIG_IIS2ICLX_THREAD_STACK_SIZE, - (k_thread_entry_t)iis2iclx_thread, + iis2iclx_thread, iis2iclx, NULL, NULL, K_PRIO_COOP(CONFIG_IIS2ICLX_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/iis2mdc/iis2mdc_trigger.c b/drivers/sensor/iis2mdc/iis2mdc_trigger.c index 049cc5c3b95..fc9f203b033 100644 --- a/drivers/sensor/iis2mdc/iis2mdc_trigger.c +++ b/drivers/sensor/iis2mdc/iis2mdc_trigger.c @@ -83,8 +83,13 @@ static void iis2mdc_gpio_callback(const struct device *dev, } #ifdef CONFIG_IIS2MDC_TRIGGER_OWN_THREAD -static void iis2mdc_thread(struct iis2mdc_data *iis2mdc) +static void iis2mdc_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct iis2mdc_data *iis2mdc = p1; + while (1) { k_sem_take(&iis2mdc->gpio_sem, K_FOREVER); iis2mdc_handle_interrupt(iis2mdc->dev); @@ -118,7 +123,7 @@ int iis2mdc_init_interrupt(const struct device *dev) k_sem_init(&iis2mdc->gpio_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&iis2mdc->thread, iis2mdc->thread_stack, CONFIG_IIS2MDC_THREAD_STACK_SIZE, - (k_thread_entry_t)iis2mdc_thread, iis2mdc, + iis2mdc_thread, iis2mdc, NULL, NULL, K_PRIO_COOP(CONFIG_IIS2MDC_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_IIS2MDC_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/iis3dhhc/iis3dhhc_trigger.c b/drivers/sensor/iis3dhhc/iis3dhhc_trigger.c index ff964e30efc..0ce2df490b3 100644 --- a/drivers/sensor/iis3dhhc/iis3dhhc_trigger.c +++ b/drivers/sensor/iis3dhhc/iis3dhhc_trigger.c @@ -99,8 +99,13 @@ static void iis3dhhc_gpio_callback(const struct device *dev, } #ifdef CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD -static void iis3dhhc_thread(struct iis3dhhc_data *iis3dhhc) +static void iis3dhhc_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct iis3dhhc_data *iis3dhhc = p1; + while (1) { k_sem_take(&iis3dhhc->gpio_sem, K_FOREVER); iis3dhhc_handle_interrupt(iis3dhhc->dev); @@ -136,7 +141,7 @@ int iis3dhhc_init_interrupt(const struct device *dev) k_thread_create(&iis3dhhc->thread, iis3dhhc->thread_stack, CONFIG_IIS3DHHC_THREAD_STACK_SIZE, - (k_thread_entry_t)iis3dhhc_thread, iis3dhhc, + iis3dhhc_thread, iis3dhhc, NULL, NULL, K_PRIO_COOP(CONFIG_IIS3DHHC_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/isl29035/isl29035_trigger.c b/drivers/sensor/isl29035/isl29035_trigger.c index db4857917c6..a0a5d2af21f 100644 --- a/drivers/sensor/isl29035/isl29035_trigger.c +++ b/drivers/sensor/isl29035/isl29035_trigger.c @@ -121,8 +121,12 @@ static void isl29035_thread_cb(const struct device *dev) } #ifdef CONFIG_ISL29035_TRIGGER_OWN_THREAD -static void isl29035_thread(const struct device *dev) +static void isl29035_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct isl29035_driver_data *drv_data = dev->data; while (1) { @@ -205,7 +209,7 @@ int isl29035_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_ISL29035_THREAD_STACK_SIZE, - (k_thread_entry_t)isl29035_thread, + isl29035_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_ISL29035_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/ism330dhcx/ism330dhcx_trigger.c b/drivers/sensor/ism330dhcx/ism330dhcx_trigger.c index 788313b85c5..ac4c16b9506 100644 --- a/drivers/sensor/ism330dhcx/ism330dhcx_trigger.c +++ b/drivers/sensor/ism330dhcx/ism330dhcx_trigger.c @@ -226,8 +226,13 @@ static void ism330dhcx_gpio_callback(const struct device *dev, } #ifdef CONFIG_ISM330DHCX_TRIGGER_OWN_THREAD -static void ism330dhcx_thread(struct ism330dhcx_data *ism330dhcx) +static void ism330dhcx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct ism330dhcx_data *ism330dhcx = p1; + while (1) { k_sem_take(&ism330dhcx->gpio_sem, K_FOREVER); ism330dhcx_handle_interrupt(ism330dhcx->dev); @@ -261,7 +266,7 @@ int ism330dhcx_init_interrupt(const struct device *dev) k_thread_create(&ism330dhcx->thread, ism330dhcx->thread_stack, CONFIG_ISM330DHCX_THREAD_STACK_SIZE, - (k_thread_entry_t)ism330dhcx_thread, + ism330dhcx_thread, ism330dhcx, NULL, NULL, K_PRIO_COOP(CONFIG_ISM330DHCX_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/lis2dh/lis2dh_trigger.c b/drivers/sensor/lis2dh/lis2dh_trigger.c index 2b773b2aef8..d0d3ad38dab 100644 --- a/drivers/sensor/lis2dh/lis2dh_trigger.c +++ b/drivers/sensor/lis2dh/lis2dh_trigger.c @@ -506,8 +506,13 @@ static void lis2dh_thread_cb(const struct device *dev) } #ifdef CONFIG_LIS2DH_TRIGGER_OWN_THREAD -static void lis2dh_thread(struct lis2dh_data *lis2dh) +static void lis2dh_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lis2dh_data *lis2dh = p1; + while (1) { k_sem_take(&lis2dh->gpio_sem, K_FOREVER); lis2dh_thread_cb(lis2dh->dev); @@ -538,7 +543,7 @@ int lis2dh_init_interrupt(const struct device *dev) k_sem_init(&lis2dh->gpio_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&lis2dh->thread, lis2dh->thread_stack, CONFIG_LIS2DH_THREAD_STACK_SIZE, - (k_thread_entry_t)lis2dh_thread, lis2dh, NULL, NULL, + lis2dh_thread, lis2dh, NULL, NULL, K_PRIO_COOP(CONFIG_LIS2DH_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD) lis2dh->work.handler = lis2dh_work_cb; diff --git a/drivers/sensor/lis2ds12/lis2ds12_trigger.c b/drivers/sensor/lis2ds12/lis2ds12_trigger.c index 96069419907..d3494913315 100644 --- a/drivers/sensor/lis2ds12/lis2ds12_trigger.c +++ b/drivers/sensor/lis2ds12/lis2ds12_trigger.c @@ -67,8 +67,13 @@ static void lis2ds12_handle_int(const struct device *dev) } #ifdef CONFIG_LIS2DS12_TRIGGER_OWN_THREAD -static void lis2ds12_thread(struct lis2ds12_data *data) +static void lis2ds12_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lis2ds12_data *data = p1; + while (1) { k_sem_take(&data->trig_sem, K_FOREVER); lis2ds12_handle_int(data->dev); @@ -159,7 +164,7 @@ int lis2ds12_trigger_init(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_LIS2DS12_THREAD_STACK_SIZE, - (k_thread_entry_t)lis2ds12_thread, + lis2ds12_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_LIS2DS12_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/lis2dw12/lis2dw12_trigger.c b/drivers/sensor/lis2dw12/lis2dw12_trigger.c index 08030c993b6..e30d6d4c167 100644 --- a/drivers/sensor/lis2dw12/lis2dw12_trigger.c +++ b/drivers/sensor/lis2dw12/lis2dw12_trigger.c @@ -301,8 +301,13 @@ static void lis2dw12_gpio_callback(const struct device *dev, } #ifdef CONFIG_LIS2DW12_TRIGGER_OWN_THREAD -static void lis2dw12_thread(struct lis2dw12_data *lis2dw12) +static void lis2dw12_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lis2dw12_data *lis2dw12 = p1; + while (1) { k_sem_take(&lis2dw12->gpio_sem, K_FOREVER); lis2dw12_handle_interrupt(lis2dw12->dev); @@ -451,7 +456,7 @@ int lis2dw12_init_interrupt(const struct device *dev) k_thread_create(&lis2dw12->thread, lis2dw12->thread_stack, CONFIG_LIS2DW12_THREAD_STACK_SIZE, - (k_thread_entry_t)lis2dw12_thread, lis2dw12, + lis2dw12_thread, lis2dw12, NULL, NULL, K_PRIO_COOP(CONFIG_LIS2DW12_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LIS2DW12_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/lis2mdl/lis2mdl_trigger.c b/drivers/sensor/lis2mdl/lis2mdl_trigger.c index 4a77e2fa432..19930174ea0 100644 --- a/drivers/sensor/lis2mdl/lis2mdl_trigger.c +++ b/drivers/sensor/lis2mdl/lis2mdl_trigger.c @@ -96,8 +96,13 @@ static void lis2mdl_gpio_callback(const struct device *dev, } #ifdef CONFIG_LIS2MDL_TRIGGER_OWN_THREAD -static void lis2mdl_thread(struct lis2mdl_data *lis2mdl) +static void lis2mdl_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lis2mdl_data *lis2mdl = p1; + while (1) { k_sem_take(&lis2mdl->gpio_sem, K_FOREVER); lis2mdl_handle_interrupt(lis2mdl->dev); @@ -131,7 +136,7 @@ int lis2mdl_init_interrupt(const struct device *dev) k_sem_init(&lis2mdl->gpio_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&lis2mdl->thread, lis2mdl->thread_stack, CONFIG_LIS2MDL_THREAD_STACK_SIZE, - (k_thread_entry_t)lis2mdl_thread, lis2mdl, + lis2mdl_thread, lis2mdl, NULL, NULL, K_PRIO_COOP(CONFIG_LIS2MDL_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LIS2MDL_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/lis3mdl/lis3mdl_trigger.c b/drivers/sensor/lis3mdl/lis3mdl_trigger.c index 05993e1ceda..ba94076bd14 100644 --- a/drivers/sensor/lis3mdl/lis3mdl_trigger.c +++ b/drivers/sensor/lis3mdl/lis3mdl_trigger.c @@ -87,8 +87,13 @@ static void lis3mdl_thread_cb(const struct device *dev) } #ifdef CONFIG_LIS3MDL_TRIGGER_OWN_THREAD -static void lis3mdl_thread(struct lis3mdl_data *drv_data) +static void lis3mdl_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lis3mdl_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); lis3mdl_thread_cb(drv_data->dev); @@ -140,7 +145,7 @@ int lis3mdl_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_LIS3MDL_THREAD_STACK_SIZE, - (k_thread_entry_t)lis3mdl_thread, drv_data, + lis3mdl_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_LIS3MDL_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LIS3MDL_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/lps22hh/lps22hh_trigger.c b/drivers/sensor/lps22hh/lps22hh_trigger.c index bb8c7f406ef..e08a0259ee2 100644 --- a/drivers/sensor/lps22hh/lps22hh_trigger.c +++ b/drivers/sensor/lps22hh/lps22hh_trigger.c @@ -123,8 +123,13 @@ static void lps22hh_gpio_callback(const struct device *dev, } #ifdef CONFIG_LPS22HH_TRIGGER_OWN_THREAD -static void lps22hh_thread(struct lps22hh_data *lps22hh) +static void lps22hh_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lps22hh_data *lps22hh = p1; + while (1) { k_sem_take(&lps22hh->intr_sem, K_FOREVER); lps22hh_handle_interrupt(lps22hh->dev); @@ -187,7 +192,7 @@ int lps22hh_init_interrupt(const struct device *dev) k_thread_create(&lps22hh->thread, lps22hh->thread_stack, CONFIG_LPS22HH_THREAD_STACK_SIZE, - (k_thread_entry_t)lps22hh_thread, lps22hh, + lps22hh_thread, lps22hh, NULL, NULL, K_PRIO_COOP(CONFIG_LPS22HH_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LPS22HH_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/lsm6dsl/lsm6dsl_trigger.c b/drivers/sensor/lsm6dsl/lsm6dsl_trigger.c index b84464cb396..989d322678e 100644 --- a/drivers/sensor/lsm6dsl/lsm6dsl_trigger.c +++ b/drivers/sensor/lsm6dsl/lsm6dsl_trigger.c @@ -97,8 +97,12 @@ static void lsm6dsl_thread_cb(const struct device *dev) } #ifdef CONFIG_LSM6DSL_TRIGGER_OWN_THREAD -static void lsm6dsl_thread(const struct device *dev) +static void lsm6dsl_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct lsm6dsl_data *drv_data = dev->data; while (1) { @@ -156,7 +160,7 @@ int lsm6dsl_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_LSM6DSL_THREAD_STACK_SIZE, - (k_thread_entry_t)lsm6dsl_thread, (void *)dev, + lsm6dsl_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_LSM6DSL_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_LSM6DSL_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/lsm6dso/lsm6dso_trigger.c b/drivers/sensor/lsm6dso/lsm6dso_trigger.c index 8181c91c604..8f8bc527282 100644 --- a/drivers/sensor/lsm6dso/lsm6dso_trigger.c +++ b/drivers/sensor/lsm6dso/lsm6dso_trigger.c @@ -228,8 +228,13 @@ static void lsm6dso_gpio_callback(const struct device *dev, } #ifdef CONFIG_LSM6DSO_TRIGGER_OWN_THREAD -static void lsm6dso_thread(struct lsm6dso_data *lsm6dso) +static void lsm6dso_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lsm6dso_data *lsm6dso = p1; + while (1) { k_sem_take(&lsm6dso->gpio_sem, K_FOREVER); lsm6dso_handle_interrupt(lsm6dso->dev); @@ -265,7 +270,7 @@ int lsm6dso_init_interrupt(const struct device *dev) k_thread_create(&lsm6dso->thread, lsm6dso->thread_stack, CONFIG_LSM6DSO_THREAD_STACK_SIZE, - (k_thread_entry_t)lsm6dso_thread, lsm6dso, + lsm6dso_thread, lsm6dso, NULL, NULL, K_PRIO_COOP(CONFIG_LSM6DSO_THREAD_PRIORITY), 0, K_NO_WAIT); k_thread_name_set(&lsm6dso->thread, "lsm6dso"); diff --git a/drivers/sensor/lsm6dso16is/lsm6dso16is_trigger.c b/drivers/sensor/lsm6dso16is/lsm6dso16is_trigger.c index c9bcc313bad..93ce4f6c0b0 100644 --- a/drivers/sensor/lsm6dso16is/lsm6dso16is_trigger.c +++ b/drivers/sensor/lsm6dso16is/lsm6dso16is_trigger.c @@ -256,8 +256,13 @@ static void lsm6dso16is_gpio_callback(const struct device *dev, } #ifdef CONFIG_LSM6DSO16IS_TRIGGER_OWN_THREAD -static void lsm6dso16is_thread(struct lsm6dso16is_data *lsm6dso16is) +static void lsm6dso16is_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lsm6dso16is_data *lsm6dso16is = p1; + while (1) { k_sem_take(&lsm6dso16is->gpio_sem, K_FOREVER); lsm6dso16is_handle_interrupt(lsm6dso16is->dev); @@ -293,7 +298,7 @@ int lsm6dso16is_init_interrupt(const struct device *dev) k_thread_create(&lsm6dso16is->thread, lsm6dso16is->thread_stack, CONFIG_LSM6DSO16IS_THREAD_STACK_SIZE, - (k_thread_entry_t)lsm6dso16is_thread, lsm6dso16is, + lsm6dso16is_thread, lsm6dso16is, NULL, NULL, K_PRIO_COOP(CONFIG_LSM6DSO16IS_THREAD_PRIORITY), 0, K_NO_WAIT); k_thread_name_set(&lsm6dso16is->thread, "lsm6dso16is"); diff --git a/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c b/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c index b82e371bc9c..a6ab65a550f 100644 --- a/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c +++ b/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c @@ -256,8 +256,13 @@ static void lsm6dsv16x_gpio_callback(const struct device *dev, } #ifdef CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD -static void lsm6dsv16x_thread(struct lsm6dsv16x_data *lsm6dsv16x) +static void lsm6dsv16x_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lsm6dsv16x_data *lsm6dsv16x = p1; + while (1) { k_sem_take(&lsm6dsv16x->gpio_sem, K_FOREVER); lsm6dsv16x_handle_interrupt(lsm6dsv16x->dev); @@ -293,7 +298,7 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) k_thread_create(&lsm6dsv16x->thread, lsm6dsv16x->thread_stack, CONFIG_LSM6DSV16X_THREAD_STACK_SIZE, - (k_thread_entry_t)lsm6dsv16x_thread, lsm6dsv16x, + lsm6dsv16x_thread, lsm6dsv16x, NULL, NULL, K_PRIO_COOP(CONFIG_LSM6DSV16X_THREAD_PRIORITY), 0, K_NO_WAIT); k_thread_name_set(&lsm6dsv16x->thread, "lsm6dsv16x"); diff --git a/drivers/sensor/lsm9ds0_gyro/lsm9ds0_gyro_trigger.c b/drivers/sensor/lsm9ds0_gyro/lsm9ds0_gyro_trigger.c index 35a46032406..08441deff79 100644 --- a/drivers/sensor/lsm9ds0_gyro/lsm9ds0_gyro_trigger.c +++ b/drivers/sensor/lsm9ds0_gyro/lsm9ds0_gyro_trigger.c @@ -80,8 +80,12 @@ static void lsm9ds0_gyro_gpio_drdy_callback(const struct device *dev, k_sem_give(&data->sem); } -static void lsm9ds0_gyro_thread_main(const struct device *dev) +static void lsm9ds0_gyro_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct lsm9ds0_gyro_data *data = dev->data; while (1) { @@ -106,7 +110,7 @@ int lsm9ds0_gyro_init_interrupt(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_LSM9DS0_GYRO_THREAD_STACK_SIZE, - (k_thread_entry_t)lsm9ds0_gyro_thread_main, + lsm9ds0_gyro_thread_main, (void *)dev, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); if (!gpio_is_ready_dt(&config->int_gpio)) { diff --git a/drivers/sensor/mcp9808/mcp9808_trigger.c b/drivers/sensor/mcp9808/mcp9808_trigger.c index 627f77f04b5..6c42661d073 100644 --- a/drivers/sensor/mcp9808/mcp9808_trigger.c +++ b/drivers/sensor/mcp9808/mcp9808_trigger.c @@ -129,8 +129,13 @@ static void alert_cb(const struct device *dev, struct gpio_callback *cb, #ifdef CONFIG_MCP9808_TRIGGER_OWN_THREAD -static void mcp9808_thread_main(struct mcp9808_data *data) +static void mcp9808_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct mcp9808_data *data = p1; + while (true) { k_sem_take(&data->sem, K_FOREVER); process_int(data->dev); @@ -169,7 +174,7 @@ int mcp9808_setup_interrupt(const struct device *dev) k_thread_create(&mcp9808_thread, mcp9808_thread_stack, CONFIG_MCP9808_THREAD_STACK_SIZE, - (k_thread_entry_t)mcp9808_thread_main, data, NULL, NULL, + mcp9808_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_MCP9808_THREAD_PRIORITY), 0, K_NO_WAIT); #else /* CONFIG_MCP9808_TRIGGER_GLOBAL_THREAD */ diff --git a/drivers/sensor/mpu6050/mpu6050_trigger.c b/drivers/sensor/mpu6050/mpu6050_trigger.c index 5415dbe1f41..69d45ea0182 100644 --- a/drivers/sensor/mpu6050/mpu6050_trigger.c +++ b/drivers/sensor/mpu6050/mpu6050_trigger.c @@ -77,8 +77,13 @@ static void mpu6050_thread_cb(const struct device *dev) } #ifdef CONFIG_MPU6050_TRIGGER_OWN_THREAD -static void mpu6050_thread(struct mpu6050_data *drv_data) +static void mpu6050_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct mpu6050_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); mpu6050_thread_cb(drv_data->dev); @@ -131,7 +136,7 @@ int mpu6050_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_MPU6050_THREAD_STACK_SIZE, - (k_thread_entry_t)mpu6050_thread, drv_data, + mpu6050_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_MPU6050_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_MPU6050_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/mpu9250/mpu9250_trigger.c b/drivers/sensor/mpu9250/mpu9250_trigger.c index fdfeb016b19..5619bfb50dc 100644 --- a/drivers/sensor/mpu9250/mpu9250_trigger.c +++ b/drivers/sensor/mpu9250/mpu9250_trigger.c @@ -94,8 +94,13 @@ static void mpu9250_thread_cb(const struct device *dev) } #ifdef CONFIG_MPU9250_TRIGGER_OWN_THREAD -static void mpu9250_thread(struct mpu9250_data *drv_data) +static void mpu9250_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct mpu9250_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); mpu9250_thread_cb(drv_data->dev); @@ -160,7 +165,7 @@ int mpu9250_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_MPU9250_THREAD_STACK_SIZE, - (k_thread_entry_t)mpu9250_thread, drv_data, + mpu9250_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_MPU9250_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_MPU9250_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/sht3xd/sht3xd_trigger.c b/drivers/sensor/sht3xd/sht3xd_trigger.c index 03b2bffaea4..b6b398c5166 100644 --- a/drivers/sensor/sht3xd/sht3xd_trigger.c +++ b/drivers/sensor/sht3xd/sht3xd_trigger.c @@ -162,8 +162,13 @@ static void sht3xd_thread_cb(const struct device *dev) } #ifdef CONFIG_SHT3XD_TRIGGER_OWN_THREAD -static void sht3xd_thread(struct sht3xd_data *data) +static void sht3xd_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct sht3xd_data *data = p1; + while (1) { k_sem_take(&data->gpio_sem, K_FOREVER); sht3xd_thread_cb(data->dev); @@ -238,7 +243,7 @@ int sht3xd_init_interrupt(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_SHT3XD_THREAD_STACK_SIZE, - (k_thread_entry_t)sht3xd_thread, data, + sht3xd_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_SHT3XD_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_SHT3XD_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/sm351lt/sm351lt.c b/drivers/sensor/sm351lt/sm351lt.c index 0663079ca89..7ec83253152 100644 --- a/drivers/sensor/sm351lt/sm351lt.c +++ b/drivers/sensor/sm351lt/sm351lt.c @@ -212,7 +212,7 @@ static int sm351lt_init(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_SM351LT_THREAD_STACK_SIZE, - (k_thread_entry_t)sm351lt_thread, data, NULL, + sm351lt_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_SM351LT_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/stts751/stts751_trigger.c b/drivers/sensor/stts751/stts751_trigger.c index ec463370c56..5d827d4f1b1 100644 --- a/drivers/sensor/stts751/stts751_trigger.c +++ b/drivers/sensor/stts751/stts751_trigger.c @@ -96,8 +96,13 @@ static void stts751_gpio_callback(const struct device *dev, } #ifdef CONFIG_STTS751_TRIGGER_OWN_THREAD -static void stts751_thread(struct stts751_data *stts751) +static void stts751_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct stts751_data *stts751 = p1; + while (1) { k_sem_take(&stts751->gpio_sem, K_FOREVER); stts751_handle_interrupt(stts751->dev); @@ -131,7 +136,7 @@ int stts751_init_interrupt(const struct device *dev) k_thread_create(&stts751->thread, stts751->thread_stack, CONFIG_STTS751_THREAD_STACK_SIZE, - (k_thread_entry_t)stts751_thread, stts751, + stts751_thread, stts751, NULL, NULL, K_PRIO_COOP(CONFIG_STTS751_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_STTS751_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/sx9500/sx9500_trigger.c b/drivers/sensor/sx9500/sx9500_trigger.c index 127291b2a91..146e6753ef9 100644 --- a/drivers/sensor/sx9500/sx9500_trigger.c +++ b/drivers/sensor/sx9500/sx9500_trigger.c @@ -98,8 +98,13 @@ static void sx9500_gpio_cb(const struct device *port, k_sem_give(&data->sem); } -static void sx9500_thread_main(struct sx9500_data *data) +static void sx9500_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct sx9500_data *data = p1; + while (1) { k_sem_take(&data->sem, K_FOREVER); sx9500_gpio_thread_cb(data->dev); @@ -170,7 +175,7 @@ int sx9500_setup_interrupt(const struct device *dev) #ifdef CONFIG_SX9500_TRIGGER_OWN_THREAD k_thread_create(&sx9500_thread, sx9500_thread_stack, CONFIG_SX9500_THREAD_STACK_SIZE, - (k_thread_entry_t)sx9500_thread_main, data, 0, NULL, + sx9500_thread_main, data, 0, NULL, K_PRIO_COOP(CONFIG_SX9500_THREAD_PRIORITY), 0, K_NO_WAIT); #endif diff --git a/drivers/sensor/tcn75a/tcn75a_trigger.c b/drivers/sensor/tcn75a/tcn75a_trigger.c index 90f6932a9e0..12635eb00c2 100644 --- a/drivers/sensor/tcn75a/tcn75a_trigger.c +++ b/drivers/sensor/tcn75a/tcn75a_trigger.c @@ -149,8 +149,13 @@ static void tcn75a_gpio_callback(const struct device *dev, struct gpio_callback } #ifdef CONFIG_TCN75A_TRIGGER_OWN_THREAD -static void tcn75a_thread_main(struct tcn75a_data *data) +static void tcn75a_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct tcn75a_data *data = p1; + while (true) { k_sem_take(&data->trig_sem, K_FOREVER); tcn75a_handle_int(data->dev); @@ -193,7 +198,7 @@ int tcn75a_trigger_init(const struct device *dev) #if defined(CONFIG_TCN75A_TRIGGER_OWN_THREAD) k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_TCN75A_THREAD_STACK_SIZE, - (k_thread_entry_t)tcn75a_thread_main, data, NULL, NULL, + tcn75a_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_TCN75A_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD) data->work.handler = tcn75a_work_handler; diff --git a/drivers/sensor/tmp007/tmp007_trigger.c b/drivers/sensor/tmp007/tmp007_trigger.c index d123a68aabc..a3eb0b07303 100644 --- a/drivers/sensor/tmp007/tmp007_trigger.c +++ b/drivers/sensor/tmp007/tmp007_trigger.c @@ -105,8 +105,13 @@ static void tmp007_thread_cb(const struct device *dev) } #ifdef CONFIG_TMP007_TRIGGER_OWN_THREAD -static void tmp007_thread(struct tmp007_data *drv_data) +static void tmp007_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct tmp007_data *drv_data = p1; + while (1) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); tmp007_thread_cb(drv_data->dev); @@ -185,7 +190,7 @@ int tmp007_init_interrupt(const struct device *dev) k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_TMP007_THREAD_STACK_SIZE, - (k_thread_entry_t)tmp007_thread, drv_data, + tmp007_thread, drv_data, NULL, NULL, K_PRIO_COOP(CONFIG_TMP007_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_TMP007_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/tsl2540/tsl2540_trigger.c b/drivers/sensor/tsl2540/tsl2540_trigger.c index c383186e77c..3251c3a45c9 100644 --- a/drivers/sensor/tsl2540/tsl2540_trigger.c +++ b/drivers/sensor/tsl2540/tsl2540_trigger.c @@ -81,8 +81,13 @@ static void tsl2540_process_int(const struct device *dev) } #ifdef CONFIG_TSL2540_TRIGGER_OWN_THREAD -static void tsl2540_thread_main(struct tsl2540_data *data) +static void tsl2540_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct tsl2540_data *data = p1; + while (true) { k_sem_take(&data->trig_sem, K_FOREVER); tsl2540_process_int(data->dev); @@ -189,7 +194,7 @@ int tsl2540_trigger_init(const struct device *dev) #if defined(CONFIG_TSL2540_TRIGGER_OWN_THREAD) k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_TSL2540_THREAD_STACK_SIZE, - (k_thread_entry_t)tsl2540_thread_main, data, NULL, NULL, + tsl2540_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_TSL2540_THREAD_PRIORITY), 0, K_NO_WAIT); k_thread_name_set(&data->thread, "TSL2540 trigger"); #elif defined(CONFIG_TSL2540_TRIGGER_GLOBAL_THREAD) diff --git a/drivers/sensor/vcnl4040/vcnl4040_trigger.c b/drivers/sensor/vcnl4040/vcnl4040_trigger.c index f47d70d0b39..f2680b0b8be 100644 --- a/drivers/sensor/vcnl4040/vcnl4040_trigger.c +++ b/drivers/sensor/vcnl4040/vcnl4040_trigger.c @@ -86,8 +86,13 @@ static void vcnl4040_handle_int(const struct device *dev) } #ifdef CONFIG_VCNL4040_TRIGGER_OWN_THREAD -static void vcnl4040_thread_main(struct vcnl4040_data *data) +static void vcnl4040_thread_main(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct vcnl4040_data *data = p1; + while (true) { k_sem_take(&data->trig_sem, K_FOREVER); vcnl4040_handle_int(data->dev); @@ -266,7 +271,7 @@ int vcnl4040_trigger_init(const struct device *dev) k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_VCNL4040_THREAD_STACK_SIZE, - (k_thread_entry_t)vcnl4040_thread_main, + vcnl4040_thread_main, data, NULL, NULL, K_PRIO_COOP(CONFIG_VCNL4040_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/sensor/wsen_hids/wsen_hids_trigger.c b/drivers/sensor/wsen_hids/wsen_hids_trigger.c index 2de3b04c821..e8c9472f5cd 100644 --- a/drivers/sensor/wsen_hids/wsen_hids_trigger.c +++ b/drivers/sensor/wsen_hids/wsen_hids_trigger.c @@ -89,8 +89,13 @@ static void hids_drdy_callback(const struct device *dev, struct gpio_callback *c } #ifdef CONFIG_WSEN_HIDS_TRIGGER_OWN_THREAD -static void hids_thread(struct hids_data *data) +static void hids_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct hids_data *data = p1; + while (true) { k_sem_take(&data->drdy_sem, K_FOREVER); hids_process_drdy_interrupt(data->dev); @@ -151,7 +156,7 @@ int hids_init_interrupt(const struct device *dev) k_sem_init(&data->drdy_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_WSEN_HIDS_THREAD_STACK_SIZE, - (k_thread_entry_t)hids_thread, data, NULL, NULL, + hids_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_WSEN_HIDS_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_WSEN_HIDS_TRIGGER_GLOBAL_THREAD) data->work.handler = hids_work_cb; diff --git a/drivers/sensor/wsen_pads/wsen_pads_trigger.c b/drivers/sensor/wsen_pads/wsen_pads_trigger.c index a00fae8de16..13394e23d9a 100644 --- a/drivers/sensor/wsen_pads/wsen_pads_trigger.c +++ b/drivers/sensor/wsen_pads/wsen_pads_trigger.c @@ -112,8 +112,13 @@ static void pads_drdy_callback(const struct device *dev, struct gpio_callback *c } #ifdef CONFIG_WSEN_PADS_TRIGGER_OWN_THREAD -static void pads_thread(struct pads_data *data) +static void pads_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct pads_data *data = p1; + while (true) { k_sem_take(&data->drdy_sem, K_FOREVER); pads_process_drdy_interrupt(data->dev); @@ -168,7 +173,7 @@ int pads_init_interrupt(const struct device *dev) k_sem_init(&data->drdy_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_WSEN_PADS_THREAD_STACK_SIZE, - (k_thread_entry_t)pads_thread, data, NULL, NULL, + pads_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_WSEN_PADS_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_WSEN_PADS_TRIGGER_GLOBAL_THREAD) data->work.handler = pads_work_cb; diff --git a/drivers/sensor/wsen_tids/wsen_tids_trigger.c b/drivers/sensor/wsen_tids/wsen_tids_trigger.c index 9b7837d2a9a..d2ed4d91fef 100644 --- a/drivers/sensor/wsen_tids/wsen_tids_trigger.c +++ b/drivers/sensor/wsen_tids/wsen_tids_trigger.c @@ -118,8 +118,13 @@ static void tids_threshold_callback(const struct device *dev, struct gpio_callba } #ifdef CONFIG_WSEN_TIDS_TRIGGER_OWN_THREAD -static void tids_thread(struct tids_data *tids) +static void tids_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct tids_data *tids = p1; + while (true) { k_sem_take(&tids->threshold_sem, K_FOREVER); tids_process_threshold_interrupt(tids->dev); @@ -226,7 +231,7 @@ int tids_init_interrupt(const struct device *dev) k_sem_init(&data->threshold_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&data->thread, data->thread_stack, CONFIG_WSEN_TIDS_THREAD_STACK_SIZE, - (k_thread_entry_t)tids_thread, data, NULL, NULL, + tids_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_WSEN_TIDS_THREAD_PRIORITY), 0, K_NO_WAIT); #elif defined(CONFIG_WSEN_TIDS_TRIGGER_GLOBAL_THREAD) data->work.handler = tids_work_cb; From a03f1010b8d4601462ee6ec9f436b5d8898f765e Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 21 Sep 2023 09:57:38 +0200 Subject: [PATCH 2777/4498] drivers: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- drivers/input/input_npcx_kbd.c | 5 +++-- drivers/ipm/ipm_ivshmem.c | 2 +- drivers/led/ht16k33.c | 8 ++++++-- drivers/rtc/rtc_pcf8523.c | 8 ++++++-- drivers/usb/udc/udc_nrf.c | 9 +++++++-- drivers/usb/uhc/uhc_max3421e.c | 8 ++++++-- drivers/virtualization/virt_ivshmem_shell.c | 9 +++++++-- drivers/watchdog/wdt_nxp_fs26.c | 8 ++++++-- drivers/wifi/esp32/src/esp_wifi_drv.c | 7 +++++-- drivers/wifi/esp_at/esp.c | 9 +++++++-- drivers/wifi/winc1500/wifi_winc1500.c | 8 ++++++-- 11 files changed, 60 insertions(+), 21 deletions(-) diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index ff6f08e1676..86dff1979b3 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -367,8 +367,9 @@ static void kbd_matrix_poll(const struct device *dev) } } -static void kbd_matrix_polling_thread(const struct device *dev, void *dummy2, void *dummy3) +static void kbd_matrix_polling_thread(void *dummy1, void *dummy2, void *dummy3) { + const struct device *dev = dummy1; struct input_npcx_kbd_data *const data = dev->data; ARG_UNUSED(dummy2); @@ -475,7 +476,7 @@ static int input_npcx_kbd_init(const struct device *dev) k_thread_create(&data->thread, data->thread_stack, CONFIG_INPUT_NPCX_KBD_THREAD_STACK_SIZE, - (k_thread_entry_t)kbd_matrix_polling_thread, (void *)dev, NULL, NULL, + kbd_matrix_polling_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(4), 0, K_NO_WAIT); k_thread_name_set(&data->thread, "npcx-kbd"); diff --git a/drivers/ipm/ipm_ivshmem.c b/drivers/ipm/ipm_ivshmem.c index deda3f51950..46e009fb634 100644 --- a/drivers/ipm/ipm_ivshmem.c +++ b/drivers/ipm/ipm_ivshmem.c @@ -102,7 +102,7 @@ static int ivshmem_ipm_init(const struct device *dev) k_thread_create(&ivshmem_ev_loop_thread, ivshmem_ev_loop_stack, CONFIG_IPM_IVSHMEM_EVENT_LOOP_STACK_SIZE, - (k_thread_entry_t)ivshmem_ipm_event_loop_thread, + ivshmem_ipm_event_loop_thread, (void *)dev, NULL, NULL, CONFIG_IPM_IVSHMEM_EVENT_LOOP_PRIO, 0, K_NO_WAIT); diff --git a/drivers/led/ht16k33.c b/drivers/led/ht16k33.c index 0db398e55ff..8df5b7553f6 100644 --- a/drivers/led/ht16k33.c +++ b/drivers/led/ht16k33.c @@ -247,8 +247,12 @@ static bool ht16k33_process_keyscan_data(const struct device *dev) return pressed; } -static void ht16k33_irq_thread(struct ht16k33_data *data) +static void ht16k33_irq_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct ht16k33_data *data = p1; bool pressed; while (true) { @@ -420,7 +424,7 @@ static int ht16k33_init(const struct device *dev) k_thread_create(&data->irq_thread, data->irq_thread_stack, CONFIG_HT16K33_KEYSCAN_IRQ_THREAD_STACK_SIZE, - (k_thread_entry_t)ht16k33_irq_thread, data, NULL, NULL, + ht16k33_irq_thread, data, NULL, NULL, K_PRIO_COOP(CONFIG_HT16K33_KEYSCAN_IRQ_THREAD_PRIO), 0, K_NO_WAIT); #endif /* CONFIG_HT16K33_KEYSCAN */ diff --git a/drivers/rtc/rtc_pcf8523.c b/drivers/rtc/rtc_pcf8523.c index 1e1a7a1ddfa..b6be011d61b 100644 --- a/drivers/rtc/rtc_pcf8523.c +++ b/drivers/rtc/rtc_pcf8523.c @@ -254,8 +254,12 @@ static int pcf8523_int1_enable_unlocked(const struct device *dev, bool enable) return 0; } -static void pcf8523_int1_thread(const struct device *dev) +static void pcf8523_int1_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct pcf8523_data *data = dev->data; rtc_alarm_callback alarm_callback = NULL; void *alarm_user_data = NULL; @@ -791,7 +795,7 @@ static int pcf8523_init(const struct device *dev) tid = k_thread_create(&data->int1_thread, data->int1_stack, K_THREAD_STACK_SIZEOF(data->int1_stack), - (k_thread_entry_t)pcf8523_int1_thread, (void *)dev, NULL, + pcf8523_int1_thread, (void *)dev, NULL, NULL, CONFIG_RTC_PCF8523_THREAD_PRIO, 0, K_NO_WAIT); k_thread_name_set(tid, "pcf8523"); diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index 4610aff19f8..64fae5dae21 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -348,8 +348,13 @@ static int udc_event_xfer_setup(const struct device *dev) return err; } -static void udc_nrf_thread(const struct device *dev) +static void udc_nrf_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; + while (true) { bool start_xfer = false; struct udc_nrf_evt evt; @@ -733,7 +738,7 @@ static int udc_nrf_driver_init(const struct device *dev) k_mutex_init(&data->mutex); k_thread_create(&drv_stack_data, drv_stack, K_KERNEL_STACK_SIZEOF(drv_stack), - (k_thread_entry_t)udc_nrf_thread, + udc_nrf_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); diff --git a/drivers/usb/uhc/uhc_max3421e.c b/drivers/usb/uhc/uhc_max3421e.c index a7955631fb9..ac9aa2a526d 100644 --- a/drivers/usb/uhc/uhc_max3421e.c +++ b/drivers/usb/uhc/uhc_max3421e.c @@ -652,8 +652,12 @@ static int max3421e_handle_bus_irq(const struct device *dev) return ret; } -static void uhc_max3421e_thread(const struct device *dev) +static void uhc_max3421e_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct max3421e_data *priv = uhc_get_private(dev); LOG_DBG("MAX3421E thread started"); @@ -1076,7 +1080,7 @@ static int max3421e_driver_init(const struct device *dev) k_mutex_init(&data->mutex); k_thread_create(&drv_stack_data, drv_stack, K_KERNEL_STACK_SIZEOF(drv_stack), - (k_thread_entry_t)uhc_max3421e_thread, + uhc_max3421e_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&drv_stack_data, "uhc_max3421e"); diff --git a/drivers/virtualization/virt_ivshmem_shell.c b/drivers/virtualization/virt_ivshmem_shell.c index ebf92578597..6c9dc9631a5 100644 --- a/drivers/virtualization/virt_ivshmem_shell.c +++ b/drivers/virtualization/virt_ivshmem_shell.c @@ -23,8 +23,13 @@ K_THREAD_STACK_DEFINE(doorbell_stack, STACK_SIZE); static bool doorbell_started; static struct k_thread doorbell_thread; -static void doorbell_notification_thread(const struct shell *sh) +static void doorbell_notification_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct shell *sh = p1; + while (1) { unsigned int signaled; int vector; @@ -174,7 +179,7 @@ static int cmd_ivshmem_get_notified(const struct shell *sh, tid = k_thread_create( &doorbell_thread, doorbell_stack, STACK_SIZE, - (k_thread_entry_t)doorbell_notification_thread, + doorbell_notification_thread, (void *)sh, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); if (!tid) { diff --git a/drivers/watchdog/wdt_nxp_fs26.c b/drivers/watchdog/wdt_nxp_fs26.c index 07cddc1bd3b..b821d01df96 100644 --- a/drivers/watchdog/wdt_nxp_fs26.c +++ b/drivers/watchdog/wdt_nxp_fs26.c @@ -580,8 +580,12 @@ static int wdt_nxp_fs26_disable(const struct device *dev) return 0; } -static void wdt_nxp_fs26_int_thread(const struct device *dev) +static void wdt_nxp_fs26_int_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; const struct wdt_nxp_fs26_config *config = dev->config; struct wdt_nxp_fs26_data *data = dev->data; struct fs26_spi_rx_frame rx_frame; @@ -661,7 +665,7 @@ static int wdt_nxp_fs26_init(const struct device *dev) k_thread_create(&data->int_thread, data->int_thread_stack, CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE, - (k_thread_entry_t)wdt_nxp_fs26_int_thread, + wdt_nxp_fs26_int_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO), 0, K_NO_WAIT); diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index cb343159854..ba6717ad634 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -262,8 +262,11 @@ static void esp_wifi_handle_disconnect_event(void) } } -static void esp_wifi_event_task(void) +static void esp_wifi_event_task(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + system_event_t evt; uint8_t s_con_cnt = 0; @@ -615,7 +618,7 @@ static int esp32_wifi_dev_init(const struct device *dev) k_tid_t tid = k_thread_create(&esp_wifi_event_thread, esp_wifi_event_stack, CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE, - (k_thread_entry_t)esp_wifi_event_task, NULL, NULL, NULL, + esp_wifi_event_task, NULL, NULL, NULL, CONFIG_ESP32_WIFI_EVENT_TASK_PRIO, K_INHERIT_PERMS, K_NO_WAIT); diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index df20caae5b6..1ac21abc560 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -199,8 +199,13 @@ MODEM_CMD_DEFINE(on_cmd_error) } /* RX thread */ -static void esp_rx(struct esp_data *data) +static void esp_rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct esp_data *data = p1; + while (true) { /* wait for incoming data */ modem_iface_uart_rx_wait(&data->mctx.iface, K_FOREVER); @@ -1366,7 +1371,7 @@ static int esp_init(const struct device *dev) /* start RX thread */ k_thread_create(&esp_rx_thread, esp_rx_stack, K_KERNEL_STACK_SIZEOF(esp_rx_stack), - (k_thread_entry_t)esp_rx, + esp_rx, data, NULL, NULL, K_PRIO_COOP(CONFIG_WIFI_ESP_AT_RX_THREAD_PRIORITY), 0, K_NO_WAIT); diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 758e776bf7c..0a93ef0fa27 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -966,8 +966,12 @@ static void winc1500_socket_cb(SOCKET sock, uint8 message, void *pvMsg) #endif /* LOG_LEVEL > LOG_LEVEL_OFF */ } -static void winc1500_thread(void) +static void winc1500_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (1) { while (m2m_wifi_handle_events(NULL) != 0) { } @@ -1168,7 +1172,7 @@ static int winc1500_init(const struct device *dev) /* monitoring thread for winc wifi callbacks */ k_thread_create(&winc1500_thread_data, winc1500_stack, CONFIG_WIFI_WINC1500_THREAD_STACK_SIZE, - (k_thread_entry_t)winc1500_thread, NULL, NULL, NULL, + winc1500_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_WIFI_WINC1500_THREAD_PRIO), 0, K_NO_WAIT); k_thread_name_set(&winc1500_thread_data, "WINC1500"); From 6202459d9fe65fcffd69448590a0bf9a2da1acaf Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 08:58:03 +0200 Subject: [PATCH 2778/4498] samples: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- samples/arch/smp/pi/src/main.c | 2 +- samples/arch/smp/pktqueue/src/main.c | 5 ++--- samples/bluetooth/ipsp/src/main.c | 8 +++++-- samples/net/mqtt_sn_publisher/src/common.h | 2 +- samples/net/mqtt_sn_publisher/src/main.c | 12 +++++++---- samples/net/mqtt_sn_publisher/src/udp.c | 13 ++++++++---- samples/net/sockets/can/src/main.c | 16 +++++++++----- .../sockets/dumb_http_server_mt/src/main.c | 4 ++-- .../net/sockets/echo_client/src/echo-client.c | 13 ++++++------ samples/net/sockets/echo_client/src/udp.c | 8 +++++-- samples/net/sockets/echo_server/src/tcp.c | 4 ++-- samples/net/sockets/net_mgmt/src/main.c | 10 ++++++--- samples/net/sockets/txtime/src/main.c | 16 ++++++++++---- samples/net/wpan_serial/src/main.c | 16 ++++++++++---- samples/net/wpanusb/src/wpanusb.c | 8 +++++-- samples/subsys/ipc/openamp/remote/src/main.c | 3 ++- samples/subsys/ipc/openamp/src/main.c | 3 ++- .../ipc/openamp_rsc_table/src/main_remote.c | 9 +++++--- .../ipc/rpmsg_service/remote/src/main.c | 3 ++- samples/subsys/ipc/rpmsg_service/src/main.c | 3 ++- samples/userspace/shared_mem/src/main.c | 21 +++++++++++++------ samples/userspace/shared_mem/src/main.h | 6 +++--- 22 files changed, 124 insertions(+), 61 deletions(-) diff --git a/samples/arch/smp/pi/src/main.c b/samples/arch/smp/pi/src/main.c index e141f8f5f1b..f5797c43f79 100644 --- a/samples/arch/smp/pi/src/main.c +++ b/samples/arch/smp/pi/src/main.c @@ -90,7 +90,7 @@ int main(void) for (i = 0; i < THREADS_NUM; i++) { k_thread_create(&tthread[i], tstack[i], STACK_SIZE, - (k_thread_entry_t)test_thread, + test_thread, (void *)&th_counter, (void *)th_buffer[i], NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); } diff --git a/samples/arch/smp/pktqueue/src/main.c b/samples/arch/smp/pktqueue/src/main.c index 11d3ea36c73..07363a8d234 100644 --- a/samples/arch/smp/pktqueue/src/main.c +++ b/samples/arch/smp/pktqueue/src/main.c @@ -101,7 +101,6 @@ void test_thread(void *arg1, void *arg2, void *arg3) /* Thread that processes one pair of sender/receiver queue */ void queue_thread(void *arg1, void *arg2, void *arg3) { - ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); @@ -117,7 +116,7 @@ void queue_thread(void *arg1, void *arg2, void *arg3) for (int i = 0; i < THREADS_NUM; i++) k_thread_create(&tthread[i+THREADS_NUM*queue_num], tstack[i+THREADS_NUM*queue_num], STACK_SIZE, - (k_thread_entry_t)test_thread, + test_thread, (void *)&sender[queue_num], (void *)&receiver[queue_num], (void *)&queue_num, K_PRIO_PREEMPT(10), 0, K_NO_WAIT); @@ -156,7 +155,7 @@ int main(void) for (int i = 0; i < QUEUE_NUM; i++) k_thread_create(&qthread[i], qstack[i], STACK_SIZE, - (k_thread_entry_t)queue_thread, + queue_thread, (void *)&sender[i], (void *)&receiver[i], (void *)&i, K_PRIO_PREEMPT(11), 0, K_NO_WAIT); diff --git a/samples/bluetooth/ipsp/src/main.c b/samples/bluetooth/ipsp/src/main.c index c4f1f87c169..a8c017140c3 100644 --- a/samples/bluetooth/ipsp/src/main.c +++ b/samples/bluetooth/ipsp/src/main.c @@ -285,8 +285,12 @@ static void setup_tcp_accept(struct net_context *tcp_recv6) } } -static void listen(void) +static void listen(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct net_context *udp_recv6 = { 0 }; struct net_context *tcp_recv6 = { 0 }; @@ -313,7 +317,7 @@ int main(void) init_app(); k_thread_create(&thread_data, thread_stack, STACKSIZE, - (k_thread_entry_t)listen, + listen, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); return 0; } diff --git a/samples/net/mqtt_sn_publisher/src/common.h b/samples/net/mqtt_sn_publisher/src/common.h index 4b0fef32698..1cfbbc10450 100644 --- a/samples/net/mqtt_sn_publisher/src/common.h +++ b/samples/net/mqtt_sn_publisher/src/common.h @@ -23,4 +23,4 @@ extern struct k_mem_domain app_domain; #define THREAD_PRIORITY K_PRIO_PREEMPT(8) #endif -int start_thread(void); +void start_thread(void); diff --git a/samples/net/mqtt_sn_publisher/src/main.c b/samples/net/mqtt_sn_publisher/src/main.c index 665919ef50a..65436daea4d 100644 --- a/samples/net/mqtt_sn_publisher/src/main.c +++ b/samples/net/mqtt_sn_publisher/src/main.c @@ -83,12 +83,16 @@ static void init_app(void) } } -static int start_client(void) +static void start_client(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* Wait for connection */ k_sem_take(&run_app, K_FOREVER); - return start_thread(); + start_thread(); } int main(void) @@ -107,9 +111,9 @@ int main(void) k_thread_access_grant(k_current_get(), &run_app); k_mem_domain_add_thread(&app_domain, k_current_get()); - k_thread_user_mode_enter((k_thread_entry_t)start_client, NULL, NULL, NULL); + k_thread_user_mode_enter(start_client, NULL, NULL, NULL); #else - exit(start_client()); + start_client(NULL, NULL, NULL); #endif return 0; } diff --git a/samples/net/mqtt_sn_publisher/src/udp.c b/samples/net/mqtt_sn_publisher/src/udp.c index 32a64fbccbd..70a09bdb89d 100644 --- a/samples/net/mqtt_sn_publisher/src/udp.c +++ b/samples/net/mqtt_sn_publisher/src/udp.c @@ -141,23 +141,28 @@ static void process_thread(void) LOG_ERR("Exiting thread: %d", err); } -int start_thread(void) +void start_thread(void) { int rc; #if defined(CONFIG_USERSPACE) rc = k_mem_domain_add_thread(&app_domain, udp_thread_id); if (rc < 0) { - return rc; + LOG_ERR("Failed: k_mem_domain_add_thread() %d", rc); + return; } #endif rc = k_thread_name_set(udp_thread_id, "udp"); if (rc < 0 && rc != -ENOSYS) { LOG_ERR("Failed: k_thread_name_set() %d", rc); - return rc; + return; } k_thread_start(udp_thread_id); - return k_thread_join(udp_thread_id, K_FOREVER); + rc = k_thread_join(udp_thread_id, K_FOREVER); + + if (rc != 0) { + LOG_ERR("Failed: k_thread_join() %d", rc); + } } diff --git a/samples/net/sockets/can/src/main.c b/samples/net/sockets/can/src/main.c index 2f86b63eaf1..506157c6afe 100644 --- a/samples/net/sockets/can/src/main.c +++ b/samples/net/sockets/can/src/main.c @@ -39,8 +39,12 @@ static const struct can_filter zfilter = { static struct socketcan_filter sock_filter; -static void tx(int *can_fd) +static void tx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + int *can_fd = p1; int fd = POINTER_TO_INT(can_fd); struct can_frame zframe = {0}; struct socketcan_frame sframe = {0}; @@ -95,9 +99,11 @@ static int create_socket(const struct socketcan_filter *sfilter) return fd; } -static void rx(int *can_fd, int *do_close_period, - const struct socketcan_filter *sfilter) +static void rx(void *p1, void *p2, void *p3) { + int *can_fd = p1; + int *do_close_period = p2; + const struct socketcan_filter *sfilter = p3; int close_period = POINTER_TO_INT(do_close_period); int fd = POINTER_TO_INT(can_fd); struct sockaddr_can can_addr; @@ -205,7 +211,7 @@ static int setup_socket(void) /* Delay TX startup so that RX is ready to receive */ tx_tid = k_thread_create(&tx_data, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), - (k_thread_entry_t)tx, INT_TO_POINTER(fd), + tx, INT_TO_POINTER(fd), NULL, NULL, PRIORITY, 0, K_SECONDS(1)); if (!tx_tid) { ret = -ENOENT; @@ -225,7 +231,7 @@ static int setup_socket(void) if (fd >= 0) { rx_tid = k_thread_create(&rx_data, rx_stack, K_THREAD_STACK_SIZEOF(rx_stack), - (k_thread_entry_t)rx, + rx, INT_TO_POINTER(fd), INT_TO_POINTER(CLOSE_PERIOD), &sock_filter, PRIORITY, 0, K_NO_WAIT); diff --git a/samples/net/sockets/dumb_http_server_mt/src/main.c b/samples/net/sockets/dumb_http_server_mt/src/main.c index 714bbc5a67b..baa295b7f50 100644 --- a/samples/net/sockets/dumb_http_server_mt/src/main.c +++ b/samples/net/sockets/dumb_http_server_mt/src/main.c @@ -287,7 +287,7 @@ static int process_tcp(int *sock, int *accepted) &tcp6_handler_thread[slot], tcp6_handler_stack[slot], K_THREAD_STACK_SIZEOF(tcp6_handler_stack[slot]), - (k_thread_entry_t)client_conn_handler, + client_conn_handler, INT_TO_POINTER(slot), &accepted[slot], &tcp6_handler_tid[slot], @@ -302,7 +302,7 @@ static int process_tcp(int *sock, int *accepted) &tcp4_handler_thread[slot], tcp4_handler_stack[slot], K_THREAD_STACK_SIZEOF(tcp4_handler_stack[slot]), - (k_thread_entry_t)client_conn_handler, + client_conn_handler, INT_TO_POINTER(slot), &accepted[slot], &tcp4_handler_tid[slot], diff --git a/samples/net/sockets/echo_client/src/echo-client.c b/samples/net/sockets/echo_client/src/echo-client.c index 3738c758b15..c78b14952e6 100644 --- a/samples/net/sockets/echo_client/src/echo-client.c +++ b/samples/net/sockets/echo_client/src/echo-client.c @@ -279,8 +279,12 @@ static void init_app(void) init_udp(); } -static int start_client(void) +static void start_client(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int iterations = CONFIG_NET_SAMPLE_SEND_ITERATIONS; int i = 0; int ret; @@ -305,8 +309,6 @@ static int start_client(void) stop_udp_and_tcp(); } - - return ret; } int main(void) @@ -327,10 +329,9 @@ int main(void) k_thread_access_grant(k_current_get(), &run_app); k_mem_domain_add_thread(&app_domain, k_current_get()); - k_thread_user_mode_enter((k_thread_entry_t)start_client, NULL, NULL, - NULL); + k_thread_user_mode_enter(start_client, NULL, NULL, NULL); #else - exit(start_client()); + start_client(NULL, NULL, NULL); #endif return 0; } diff --git a/samples/net/sockets/echo_client/src/udp.c b/samples/net/sockets/echo_client/src/udp.c index 1889fdb591d..e5b7ea1dae0 100644 --- a/samples/net/sockets/echo_client/src/udp.c +++ b/samples/net/sockets/echo_client/src/udp.c @@ -40,8 +40,12 @@ static int send_udp_data(struct data *data); static void wait_reply(struct k_timer *timer); static void wait_transmit(struct k_timer *timer); -static void process_udp_tx(void) +static void process_udp_tx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct k_poll_event events[] = { K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, @@ -317,7 +321,7 @@ int start_udp(void) k_thread_create(&udp_tx_thread, udp_tx_thread_stack, K_THREAD_STACK_SIZEOF(udp_tx_thread_stack), - (k_thread_entry_t)process_udp_tx, + process_udp_tx, NULL, NULL, NULL, THREAD_PRIORITY, IS_ENABLED(CONFIG_USERSPACE) ? K_USER | K_INHERIT_PERMS : 0, diff --git a/samples/net/sockets/echo_server/src/tcp.c b/samples/net/sockets/echo_server/src/tcp.c index ffc6d69bc36..1a6555d43c3 100644 --- a/samples/net/sockets/echo_server/src/tcp.c +++ b/samples/net/sockets/echo_server/src/tcp.c @@ -243,7 +243,7 @@ static int process_tcp(struct data *data) &tcp6_handler_thread[slot], tcp6_handler_stack[slot], K_THREAD_STACK_SIZEOF(tcp6_handler_stack[slot]), - (k_thread_entry_t)handle_data, + handle_data, INT_TO_POINTER(slot), data, &tcp6_handler_in_use[slot], THREAD_PRIORITY, IS_ENABLED(CONFIG_USERSPACE) ? K_USER | @@ -267,7 +267,7 @@ static int process_tcp(struct data *data) &tcp4_handler_thread[slot], tcp4_handler_stack[slot], K_THREAD_STACK_SIZEOF(tcp4_handler_stack[slot]), - (k_thread_entry_t)handle_data, + handle_data, INT_TO_POINTER(slot), data, &tcp4_handler_in_use[slot], THREAD_PRIORITY, IS_ENABLED(CONFIG_USERSPACE) ? K_USER | diff --git a/samples/net/sockets/net_mgmt/src/main.c b/samples/net/sockets/net_mgmt/src/main.c index 2e6813b54cd..877e5e41d5c 100644 --- a/samples/net/sockets/net_mgmt/src/main.c +++ b/samples/net/sockets/net_mgmt/src/main.c @@ -82,8 +82,12 @@ static char *get_ip_addr(char *ipaddr, size_t len, sa_family_t family, return buf; } -static void listener(void) +static void listener(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct sockaddr_nm sockaddr; struct sockaddr_nm event_addr; socklen_t event_addr_len; @@ -163,10 +167,10 @@ int main(void) k_thread_start(trigger_events_thread_id); if (IS_ENABLED(CONFIG_USERSPACE)) { - k_thread_user_mode_enter((k_thread_entry_t)listener, + k_thread_user_mode_enter(listener, NULL, NULL, NULL); } else { - listener(); + listener(NULL, NULL, NULL); } return 0; } diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index a4a63732398..481312d1afe 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -127,8 +127,12 @@ static void event_handler(struct net_mgmt_event_callback *cb, } } -static void rx(struct app_data *data) +static void rx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct app_data *data = p1; static uint8_t recv_buf[sizeof(txtime_str)]; struct sockaddr src; socklen_t addr_len = data->peer_addr_len; @@ -143,8 +147,12 @@ static void rx(struct app_data *data) } } -static void tx(struct app_data *data) +static void tx(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct app_data *data = p1; struct net_ptp_time time; struct msghdr msg; struct cmsghdr *cmsg; @@ -620,7 +628,7 @@ int main(void) tx_tid = k_thread_create(&tx_thread, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), - (k_thread_entry_t)tx, &peer_data, + tx, &peer_data, NULL, NULL, THREAD_PRIORITY, 0, K_FOREVER); if (!tx_tid) { @@ -632,7 +640,7 @@ int main(void) rx_tid = k_thread_create(&rx_thread, rx_stack, K_THREAD_STACK_SIZEOF(rx_stack), - (k_thread_entry_t)rx, &peer_data, + rx, &peer_data, NULL, NULL, THREAD_PRIORITY, 0, K_FOREVER); if (!rx_tid) { diff --git a/samples/net/wpan_serial/src/main.c b/samples/net/wpan_serial/src/main.c index 1e702dc9590..04b98a449bb 100644 --- a/samples/net/wpan_serial/src/main.c +++ b/samples/net/wpan_serial/src/main.c @@ -299,8 +299,12 @@ static void process_config(struct net_pkt *pkt) } } -static void rx_thread(void) +static void rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG("RX thread started"); while (true) { @@ -386,8 +390,12 @@ static int try_write(uint8_t *data, uint16_t len) /** * TX - transmit to SLIP interface */ -static void tx_thread(void) +static void tx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG("TX thread started"); while (true) { @@ -421,7 +429,7 @@ static void init_rx_queue(void) k_thread_create(&rx_thread_data, rx_stack, K_THREAD_STACK_SIZEOF(rx_stack), - (k_thread_entry_t)rx_thread, + rx_thread, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); } @@ -431,7 +439,7 @@ static void init_tx_queue(void) k_thread_create(&tx_thread_data, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), - (k_thread_entry_t)tx_thread, + tx_thread, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); } diff --git a/samples/net/wpanusb/src/wpanusb.c b/samples/net/wpanusb/src/wpanusb.c index a4e1f88403f..7cee37340c3 100644 --- a/samples/net/wpanusb/src/wpanusb.c +++ b/samples/net/wpanusb/src/wpanusb.c @@ -295,8 +295,12 @@ static int tx(struct net_pkt *pkt) return ret; } -static void tx_thread(void) +static void tx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG("Tx thread started"); while (1) { @@ -353,7 +357,7 @@ static void init_tx_queue(void) k_thread_create(&tx_thread_data, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), - (k_thread_entry_t)tx_thread, + tx_thread, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); } diff --git a/samples/subsys/ipc/openamp/remote/src/main.c b/samples/subsys/ipc/openamp/remote/src/main.c index 337d0114531..06622d49e44 100644 --- a/samples/subsys/ipc/openamp/remote/src/main.c +++ b/samples/subsys/ipc/openamp/remote/src/main.c @@ -144,6 +144,7 @@ void app_task(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + int status = 0; unsigned int message = 0U; struct metal_device *device; @@ -259,7 +260,7 @@ int main(void) { printk("Starting application thread!\n"); k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)app_task, + app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); return 0; } diff --git a/samples/subsys/ipc/openamp/src/main.c b/samples/subsys/ipc/openamp/src/main.c index b2a06ec8a8c..5b2ce5fddbb 100644 --- a/samples/subsys/ipc/openamp/src/main.c +++ b/samples/subsys/ipc/openamp/src/main.c @@ -168,6 +168,7 @@ void app_task(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + int status = 0; unsigned int message = 0U; struct metal_device *device; @@ -284,7 +285,7 @@ int main(void) { printk("Starting application thread!\n"); k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)app_task, + app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); #if defined(CONFIG_SOC_MPS2_AN521) || \ diff --git a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c index a5bd2e9c76c..ebee382cdf8 100644 --- a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c +++ b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c @@ -276,6 +276,7 @@ void app_rpmsg_client_sample(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + unsigned int msg_cnt = 0; int ret = 0; @@ -302,6 +303,7 @@ void app_rpmsg_tty(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + unsigned char tx_buff[512]; int ret = 0; @@ -335,6 +337,7 @@ void rpmsg_mng_task(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + unsigned char *msg; unsigned int len; int ret = 0; @@ -375,13 +378,13 @@ int main(void) { printk("Starting application threads!\n"); k_thread_create(&thread_mng_data, thread_mng_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)rpmsg_mng_task, + rpmsg_mng_task, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_create(&thread_rp__client_data, thread_rp__client_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)app_rpmsg_client_sample, + app_rpmsg_client_sample, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); k_thread_create(&thread_tty_data, thread_tty_stack, APP_TTY_TASK_STACK_SIZE, - (k_thread_entry_t)app_rpmsg_tty, + app_rpmsg_tty, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); return 0; } diff --git a/samples/subsys/ipc/rpmsg_service/remote/src/main.c b/samples/subsys/ipc/rpmsg_service/remote/src/main.c index 9960a113267..de6de636ff5 100644 --- a/samples/subsys/ipc/rpmsg_service/remote/src/main.c +++ b/samples/subsys/ipc/rpmsg_service/remote/src/main.c @@ -54,6 +54,7 @@ void app_task(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + int status = 0; unsigned int message = 0U; @@ -79,7 +80,7 @@ int main(void) { printk("Starting application thread!\n"); k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)app_task, + app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); return 0; } diff --git a/samples/subsys/ipc/rpmsg_service/src/main.c b/samples/subsys/ipc/rpmsg_service/src/main.c index f849bb3ee96..f90df936565 100644 --- a/samples/subsys/ipc/rpmsg_service/src/main.c +++ b/samples/subsys/ipc/rpmsg_service/src/main.c @@ -55,6 +55,7 @@ void app_task(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + int status = 0; unsigned int message = 0U; @@ -88,7 +89,7 @@ int main(void) { printk("Starting application thread!\n"); k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE, - (k_thread_entry_t)app_task, + app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); #if defined(CONFIG_SOC_MPS2_AN521) || \ diff --git a/samples/userspace/shared_mem/src/main.c b/samples/userspace/shared_mem/src/main.c index 7eaecfc254a..c8b9adbae1b 100644 --- a/samples/userspace/shared_mem/src/main.c +++ b/samples/userspace/shared_mem/src/main.c @@ -133,7 +133,7 @@ int main(void) * then add the thread to the domain. */ tENC = k_thread_create(&enc_thread, enc_stack, STACKSIZE, - (k_thread_entry_t)enc, NULL, NULL, NULL, + enc, NULL, NULL, NULL, -1, K_USER, K_FOREVER); k_thread_access_grant(tENC, &allforone); @@ -150,7 +150,7 @@ int main(void) tPT = k_thread_create(&pt_thread, pt_stack, STACKSIZE, - (k_thread_entry_t)pt, NULL, NULL, NULL, + pt, NULL, NULL, NULL, -1, K_USER, K_FOREVER); k_thread_access_grant(tPT, &allforone); @@ -163,7 +163,7 @@ int main(void) printk("pt_domain Created\n"); tCT = k_thread_create(&ct_thread, ct_stack, STACKSIZE, - (k_thread_entry_t)ct, NULL, NULL, NULL, + ct, NULL, NULL, NULL, -1, K_USER, K_FOREVER); k_thread_access_grant(tCT, &allforone); @@ -204,8 +204,11 @@ int main(void) * Copy memory from pt thread and encrypt to a local buffer * then copy to the ct thread. */ -void enc(void) +void enc(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); int index, index_out; @@ -252,8 +255,11 @@ void enc(void) * It can be extended to receive data from a serial port * and pass the data to enc */ -void pt(void) +void pt(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); k_sleep(K_MSEC(20)); while (1) { @@ -282,8 +288,11 @@ void pt(void) * CT waits for fBUFOUT = 1 then copies * the message clears the flag and prints */ -void ct(void) +void ct(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); char tbuf[60]; diff --git a/samples/userspace/shared_mem/src/main.h b/samples/userspace/shared_mem/src/main.h index 3fa72b5df1f..40c18364c96 100644 --- a/samples/userspace/shared_mem/src/main.h +++ b/samples/userspace/shared_mem/src/main.h @@ -20,9 +20,9 @@ #include #endif -void enc(void); -void pt(void); -void ct(void); +void enc(void *p1, void *p2, void *p3); +void pt(void *p1, void *p2, void *p3); +void ct(void *p1, void *p2, void *p3); #define _app_user_d K_APP_DMEM(user_part) #define _app_user_b K_APP_BMEM(user_part) From aa25e212d194fbaa6080a567da53a1f711050a65 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 09:50:39 +0200 Subject: [PATCH 2779/4498] tests: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- .../arm/arm_interrupt/src/arm_interrupt.c | 8 ++- .../arm/arm_thread_swap/src/arm_syscalls.c | 8 ++- .../arm/arm_thread_swap/src/arm_thread_arch.c | 8 ++- .../latency_measure/src/coop_ctx_switch.c | 16 +++-- .../latency_measure/src/int_to_thread_evt.c | 8 ++- tests/drivers/spi/spi_loopback/src/spi.c | 14 +++-- tests/drivers/udc/src/main.c | 8 ++- .../ivshmem/plain/src/ivshmem.c | 8 ++- tests/kernel/condvar/condvar_api/src/main.c | 24 +++++-- .../float_disable/src/k_float_disable.c | 24 +++++-- .../kernel/interrupt/src/interrupt_offload.c | 6 +- .../mem_protect/mem_protect/src/kobject.c | 11 +++- .../mem_protect/stack_random/src/main.c | 8 ++- tests/kernel/mem_protect/stackprot/src/main.c | 7 ++- tests/kernel/mem_protect/userspace/src/main.c | 15 +++-- .../mutex/mutex_api/src/test_mutex_apis.c | 27 +++++--- .../mutex_error_case/src/test_mutex_error.c | 5 +- tests/kernel/mutex/sys_mutex/src/main.c | 4 +- tests/kernel/mutex/sys_mutex/src/thread_12.c | 6 +- tests/kernel/sched/metairq/src/main.c | 2 +- .../src/test_sched_timeslice_and_lock.c | 6 +- .../kernel/sched/schedule_api/src/user_api.c | 42 ++++++++++--- tests/kernel/semaphore/semaphore/src/main.c | 30 +++++++-- tests/kernel/sleep/src/main.c | 16 +++-- tests/kernel/smp/src/main.c | 33 +++++++--- tests/kernel/threads/thread_apis/src/main.c | 2 +- .../thread_apis/src/test_essential_thread.c | 12 +++- .../thread_apis/src/test_kthread_for_each.c | 10 ++- .../src/test_threads_cancel_abort.c | 6 +- .../src/test_threads_set_priority.c | 8 ++- .../threads/thread_error_case/src/main.c | 5 +- .../kernel/timer/timer_error_case/src/main.c | 48 +++++++++++--- tests/kernel/workq/work_queue/src/main.c | 31 +++++----- tests/lib/fdtable/src/main.c | 9 ++- tests/net/buf/src/main.c | 4 +- tests/net/context/src/main.c | 11 ++-- tests/net/iface/src/main.c | 62 ++++++++++++++----- tests/net/mgmt/src/mgmt.c | 8 ++- tests/subsys/edac/ibecc/src/ibecc.c | 8 +-- .../subsys/rtio/rtio_api/src/test_rtio_mpsc.c | 12 +++- .../subsys/rtio/rtio_api/src/test_rtio_spsc.c | 10 ++- tests/ztest/error_hook/src/main.c | 5 +- 42 files changed, 447 insertions(+), 148 deletions(-) diff --git a/tests/arch/arm/arm_interrupt/src/arm_interrupt.c b/tests/arch/arm/arm_interrupt/src/arm_interrupt.c index 6ef95fb0185..cf9e34109dc 100644 --- a/tests/arch/arm/arm_interrupt/src/arm_interrupt.c +++ b/tests/arch/arm/arm_interrupt/src/arm_interrupt.c @@ -125,8 +125,12 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf) * In k_sys_fatal_error_handler above we will check that the ESF provided * as a parameter matches these expectations. */ -void set_regs_with_known_pattern(void) +void set_regs_with_known_pattern(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + __asm__ volatile( "mov r1, #1\n" "mov r2, #2\n" @@ -178,7 +182,7 @@ ZTEST(arm_interrupt, test_arm_esf_collection) TC_PRINT("Testing ESF Reporting\n"); k_thread_create(&esf_collection_thread, esf_collection_stack, K_THREAD_STACK_SIZEOF(esf_collection_stack), - (k_thread_entry_t)set_regs_with_known_pattern, + set_regs_with_known_pattern, NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0, K_NO_WAIT); diff --git a/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c b/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c index ec642909573..71fd8fcf456 100644 --- a/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c +++ b/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c @@ -119,8 +119,12 @@ void arm_isr_handler(const void *args) } } -static void user_thread_entry(uint32_t irq_line) +static void user_thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + uint32_t irq_line = POINTER_TO_INT(p1); /* User Thread */ #if !defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) ARG_UNUSED(irq_line); @@ -234,7 +238,7 @@ ZTEST(arm_thread_swap, test_arm_syscalls) k_thread_create(&user_thread, user_thread_stack, K_THREAD_STACK_SIZEOF(user_thread_stack), - (k_thread_entry_t)user_thread_entry, + user_thread_entry, (uint32_t *)i, NULL, NULL, K_PRIO_COOP(PRIORITY), K_USER, K_NO_WAIT); diff --git a/tests/arch/arm/arm_thread_swap/src/arm_thread_arch.c b/tests/arch/arm/arm_thread_swap/src/arm_thread_arch.c index 0c98869bbed..f299ce4c4a0 100644 --- a/tests/arch/arm/arm_thread_swap/src/arm_thread_arch.c +++ b/tests/arch/arm/arm_thread_swap/src/arm_thread_arch.c @@ -221,8 +221,12 @@ static void verify_fp_callee_saved(const struct _preempt_float *src, #define ALT_THREAD_OPTIONS 0 #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ -static void alt_thread_entry(void) +static void alt_thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int init_flag, post_flag; /* Lock interrupts to make sure we get preempted only when @@ -530,7 +534,7 @@ ZTEST(arm_thread_swap, test_arm_thread_swap) k_thread_create(&alt_thread, alt_thread_stack, K_THREAD_STACK_SIZEOF(alt_thread_stack), - (k_thread_entry_t)alt_thread_entry, + alt_thread_entry, NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), ALT_THREAD_OPTIONS, K_NO_WAIT); diff --git a/tests/benchmarks/latency_measure/src/coop_ctx_switch.c b/tests/benchmarks/latency_measure/src/coop_ctx_switch.c index 1cecda1358c..ad888c96a64 100644 --- a/tests/benchmarks/latency_measure/src/coop_ctx_switch.c +++ b/tests/benchmarks/latency_measure/src/coop_ctx_switch.c @@ -51,8 +51,12 @@ K_SEM_DEFINE(sync_sema, 0, 1); * gets the first timestamp and invokes the software interrupt. * */ -static void thread_one(void) +static void thread_one(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_take(&sync_sema, K_FOREVER); timestamp_start = timing_counter_get(); @@ -75,8 +79,12 @@ static void thread_one(void) * * @return 0 on success */ -static void thread_two(void) +static void thread_two(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_give(&sync_sema); while (ctx_switch_counter < NCTXSWITCH) { k_yield(); @@ -104,10 +112,10 @@ int coop_ctx_switch(void) bench_test_start(); k_thread_create(&thread_one_data, thread_one_stack, STACKSIZE, - (k_thread_entry_t)thread_one, NULL, NULL, NULL, + thread_one, NULL, NULL, NULL, K_PRIO_COOP(6), 0, K_NO_WAIT); k_thread_create(&thread_two_data, thread_two_stack, STACKSIZE, - (k_thread_entry_t)thread_two, NULL, NULL, NULL, + thread_two, NULL, NULL, NULL, K_PRIO_COOP(6), 0, K_NO_WAIT); end = bench_test_end(); diff --git a/tests/benchmarks/latency_measure/src/int_to_thread_evt.c b/tests/benchmarks/latency_measure/src/int_to_thread_evt.c index 35ba280df3b..b774309f7d5 100644 --- a/tests/benchmarks/latency_measure/src/int_to_thread_evt.c +++ b/tests/benchmarks/latency_measure/src/int_to_thread_evt.c @@ -60,14 +60,18 @@ static void worker(struct k_work *item) * * @return 0 on success */ -void int_thread(void) +void int_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_take(&INTSEMA, K_FOREVER); irq_offload(latency_test_isr, NULL); k_thread_suspend(k_current_get()); } -K_THREAD_DEFINE(int_thread_id, 512, (k_thread_entry_t)int_thread, NULL, NULL, +K_THREAD_DEFINE(int_thread_id, 512, int_thread, NULL, NULL, NULL, 11, 0, 0); /** diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index d044c9a3fb4..1b950e8a571 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -527,10 +527,16 @@ static K_SEM_DEFINE(caller, 0, 1); K_THREAD_STACK_DEFINE(spi_async_stack, STACK_SIZE); static int result = 1; -static void spi_async_call_cb(struct k_poll_event *evt, - struct k_sem *caller_sem, - void *unused) +static void spi_async_call_cb(void *p1, + void *p2, + void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct k_poll_event *evt = p1; + struct k_sem *caller_sem = p2; int ret; LOG_DBG("Polling..."); @@ -636,7 +642,7 @@ ZTEST(spi_loopback, test_spi_loopback) #if (CONFIG_SPI_ASYNC) async_thread_id = k_thread_create(&async_thread, spi_async_stack, STACK_SIZE, - (k_thread_entry_t)spi_async_call_cb, + spi_async_call_cb, &async_evt, &caller, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); #endif diff --git a/tests/drivers/udc/src/main.c b/tests/drivers/udc/src/main.c index 43ff416f2aa..24e1eb4d1f2 100644 --- a/tests/drivers/udc/src/main.c +++ b/tests/drivers/udc/src/main.c @@ -46,8 +46,12 @@ static void event_ep_request(const struct device *dev, struct udc_event event) } } -static void test_udc_thread(const struct device *dev) +static void test_udc_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; struct udc_event event; while (true) { @@ -423,7 +427,7 @@ static void *test_udc_device_get(void) k_thread_create(&test_udc_thread_data, test_udc_stack, K_KERNEL_STACK_SIZEOF(test_udc_stack), - (k_thread_entry_t)test_udc_thread, + test_udc_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(9), 0, K_NO_WAIT); diff --git a/tests/drivers/virtualization/ivshmem/plain/src/ivshmem.c b/tests/drivers/virtualization/ivshmem/plain/src/ivshmem.c index f2da2d0b803..97c540012f6 100644 --- a/tests/drivers/virtualization/ivshmem/plain/src/ivshmem.c +++ b/tests/drivers/virtualization/ivshmem/plain/src/ivshmem.c @@ -48,15 +48,19 @@ ZTEST(ivshmem, test_ivshmem_plain) "registering handlers should not be supported"); } -static void test_is_usermode(void) +static void test_is_usermode(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + zassert_true(k_is_user_context(), "thread left in kernel mode"); } ZTEST(ivshmem, test_quit_kernel) { #ifdef CONFIG_USERSPACE - k_thread_user_mode_enter((k_thread_entry_t)test_is_usermode, + k_thread_user_mode_enter(test_is_usermode, NULL, NULL, NULL); #else ztest_test_skip(); diff --git a/tests/kernel/condvar/condvar_api/src/main.c b/tests/kernel/condvar/condvar_api/src/main.c index 0ce6f36d630..3b422f7d1a6 100644 --- a/tests/kernel/condvar/condvar_api/src/main.c +++ b/tests/kernel/condvar/condvar_api/src/main.c @@ -393,6 +393,10 @@ ZTEST_USER(condvar_tests, test_multiple_condvar_wait_wake) #ifdef CONFIG_USERSPACE static void cond_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_condvar_init(NULL); @@ -403,7 +407,7 @@ static void cond_init_null(void *p1, void *p2, void *p3) ZTEST_USER(condvar_tests, test_condvar_init_null) { k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE, - (k_thread_entry_t)cond_init_null, + cond_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -420,6 +424,10 @@ ZTEST_USER(condvar_tests, test_condvar_init_null) #ifdef CONFIG_USERSPACE static void cond_signal_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_condvar_signal(NULL); @@ -429,6 +437,10 @@ static void cond_signal_null(void *p1, void *p2, void *p3) static void cond_broadcast_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_condvar_broadcast(NULL); @@ -438,6 +450,10 @@ static void cond_broadcast_null(void *p1, void *p2, void *p3) static void cond_wait_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_condvar_wait(NULL, NULL, K_FOREVER); @@ -448,7 +464,7 @@ static void cond_wait_null(void *p1, void *p2, void *p3) ZTEST_USER(condvar_tests, test_condvar_signal_null) { k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE, - (k_thread_entry_t)cond_signal_null, + cond_signal_null, NULL, NULL, NULL, K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -457,7 +473,7 @@ ZTEST_USER(condvar_tests, test_condvar_signal_null) ZTEST_USER(condvar_tests, test_condvar_broadcast_null) { k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE, - (k_thread_entry_t)cond_broadcast_null, + cond_broadcast_null, NULL, NULL, NULL, K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -467,7 +483,7 @@ ZTEST_USER(condvar_tests, test_condvar_broadcast_null) ZTEST_USER(condvar_tests, test_condvar_wait_null) { k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE, - (k_thread_entry_t)cond_wait_null, + cond_wait_null, NULL, NULL, NULL, K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/fpu_sharing/float_disable/src/k_float_disable.c b/tests/kernel/fpu_sharing/float_disable/src/k_float_disable.c index fbf02f2682b..c6b4acff46d 100644 --- a/tests/kernel/fpu_sharing/float_disable/src/k_float_disable.c +++ b/tests/kernel/fpu_sharing/float_disable/src/k_float_disable.c @@ -28,8 +28,12 @@ K_THREAD_STACK_DEFINE(usr_fp_thread_stack, STACKSIZE); ZTEST_BMEM static volatile int test_ret = TC_PASS; -static void usr_fp_thread_entry_1(void) +static void usr_fp_thread_entry_1(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_yield(); } @@ -39,8 +43,12 @@ static void usr_fp_thread_entry_1(void) #define K_FLOAT_DISABLE_SYSCALL_RETVAL -ENOTSUP #endif -static void usr_fp_thread_entry_2(void) +static void usr_fp_thread_entry_2(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_yield(); /* System call to disable FP mode */ @@ -65,7 +73,7 @@ ZTEST(k_float_disable, test_k_float_disable_common) * priority as the current thread. */ k_thread_create(&usr_fp_thread, usr_fp_thread_stack, STACKSIZE, - (k_thread_entry_t)usr_fp_thread_entry_1, NULL, NULL, NULL, + usr_fp_thread_entry_1, NULL, NULL, NULL, PRIORITY, K_USER | K_FP_OPTS, K_NO_WAIT); @@ -114,7 +122,7 @@ ZTEST(k_float_disable, test_k_float_disable_syscall) * FP mode. */ k_thread_create(&usr_fp_thread, usr_fp_thread_stack, STACKSIZE, - (k_thread_entry_t)usr_fp_thread_entry_2, NULL, NULL, NULL, + usr_fp_thread_entry_2, NULL, NULL, NULL, PRIORITY, K_INHERIT_PERMS | K_USER | K_FP_OPTS, K_NO_WAIT); @@ -171,8 +179,12 @@ void arm_test_isr_handler(const void *args) } } -static void sup_fp_thread_entry(void) +static void sup_fp_thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* Verify K_FP_REGS flag is set */ if ((sup_fp_thread.base.user_options & K_FP_REGS) == 0) { @@ -249,7 +261,7 @@ ZTEST(k_float_disable, test_k_float_disable_irq) * priority as the current thread. */ k_thread_create(&sup_fp_thread, sup_fp_thread_stack, STACKSIZE, - (k_thread_entry_t)sup_fp_thread_entry, NULL, NULL, NULL, + sup_fp_thread_entry, NULL, NULL, NULL, PRIORITY, K_FP_REGS, K_NO_WAIT); diff --git a/tests/kernel/interrupt/src/interrupt_offload.c b/tests/kernel/interrupt/src/interrupt_offload.c index f0aa0f54c7c..b2ac007c14f 100644 --- a/tests/kernel/interrupt/src/interrupt_offload.c +++ b/tests/kernel/interrupt/src/interrupt_offload.c @@ -135,6 +135,10 @@ static void trigger_offload_interrupt(const bool real_irq, void *work) static void t_running(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_give(&sync_sem); while (wait_for_end == false) { @@ -189,7 +193,7 @@ static void run_test_offload(int case_type, int real_irq) } k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)t_running, + t_running, NULL, NULL, NULL, thread_prio, K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 589cbf52720..3b566da4457 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -1084,6 +1084,10 @@ ZTEST(mem_protect_kobj, test_mark_thread_exit_uninitialized) static void tThread_object_free_error(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* a K_ERR_CPU_EXCEPTION expected */ set_fault_valid(true); k_object_free(NULL); @@ -1108,7 +1112,7 @@ ZTEST(mem_protect_kobj, test_kobject_free_error) k_tid_t tid = k_thread_create(&child_thread, child_stack, K_THREAD_STACK_SIZEOF(child_stack), - (k_thread_entry_t)&tThread_object_free_error, + tThread_object_free_error, (void *)&tid, NULL, NULL, K_PRIO_PREEMPT(1), perm, K_NO_WAIT); @@ -1325,6 +1329,9 @@ struct k_condvar condvar; static void entry_error_perm(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + set_fault_valid(true); k_object_access_grant(p1, k_current_get()); } @@ -1364,7 +1371,7 @@ ZTEST(mem_protect_kobj, test_kobject_perm_error) k_tid_t tid = k_thread_create(&child_thread, child_stack, K_THREAD_STACK_SIZEOF(child_stack), - (k_thread_entry_t)entry_error_perm, + entry_error_perm, kobj[i], NULL, NULL, 1, K_USER, K_NO_WAIT); diff --git a/tests/kernel/mem_protect/stack_random/src/main.c b/tests/kernel/mem_protect/stack_random/src/main.c index b659db5d683..12caf4a333d 100644 --- a/tests/kernel/mem_protect/stack_random/src/main.c +++ b/tests/kernel/mem_protect/stack_random/src/main.c @@ -24,8 +24,12 @@ volatile unsigned int changed; #pragma GCC diagnostic ignored "-Wdangling-pointer" #endif -void alternate_thread(void) +void alternate_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int i; void *sp_val; @@ -68,7 +72,7 @@ ZTEST(stack_pointer_randomness, test_stack_pt_randomization) /* Start thread */ for (i = 0; i < THREAD_COUNT; i++) { k_thread_create(&alt_thread_data, alt_thread_stack_area, - STACKSIZE, (k_thread_entry_t)alternate_thread, + STACKSIZE, alternate_thread, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); k_sleep(K_MSEC(10)); diff --git a/tests/kernel/mem_protect/stackprot/src/main.c b/tests/kernel/mem_protect/stackprot/src/main.c index 695142881f5..6477f6ecf4f 100644 --- a/tests/kernel/mem_protect/stackprot/src/main.c +++ b/tests/kernel/mem_protect/stackprot/src/main.c @@ -129,7 +129,7 @@ ZTEST(stackprot, test_create_alt_thread) { /* Start thread */ k_thread_create(&alt_thread_data, alt_thread_stack_area, STACKSIZE, - (k_thread_entry_t)alternate_thread, NULL, NULL, NULL, + alternate_thread, NULL, NULL, NULL, K_PRIO_COOP(1), K_USER, K_NO_WAIT); /* Note that this sleep is required on SMP platforms where @@ -152,6 +152,9 @@ extern volatile uintptr_t __stack_chk_guard; */ void alternate_thread_canary(void *arg1, void *arg2, void *arg3) { + ARG_UNUSED(arg2); + ARG_UNUSED(arg3); + TC_PRINT("Starts %s\n", __func__); #ifdef CONFIG_STACK_CANARIES_TLS @@ -173,7 +176,7 @@ ZTEST(stackprot, test_canary_value) { /* Start thread */ k_thread_create(&alt_thread_data, alt_thread_stack_area, STACKSIZE, - (k_thread_entry_t)alternate_thread_canary, + alternate_thread_canary, (void *)__stack_chk_guard, NULL, NULL, K_PRIO_COOP(1), K_USER, K_NO_WAIT); diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 8d5cf9ec4bc..2e63638a4d6 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -451,8 +451,11 @@ ZTEST_USER(userspace, test_pass_noperms_object) } -void thread_body(void) +void thread_body(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); } /** @@ -465,7 +468,7 @@ ZTEST_USER(userspace, test_start_kernel_thread) /* Try to start a kernel thread from a usermode thread */ set_fault(K_ERR_KERNEL_OOPS); k_thread_create(&test_thread, test_stack, STACKSIZE, - (k_thread_entry_t)thread_body, NULL, NULL, NULL, + thread_body, NULL, NULL, NULL, K_PRIO_PREEMPT(1), K_INHERIT_PERMS, K_NO_WAIT); zassert_unreachable("Create a kernel thread did not fault"); @@ -568,8 +571,12 @@ ZTEST_USER(userspace, test_access_after_revoke) zassert_unreachable("Using revoked object did not fault"); } -static void umode_enter_func(void) +static void umode_enter_func(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + zassert_true(k_is_user_context(), "Thread did not enter user mode"); } @@ -586,7 +593,7 @@ ZTEST(userspace, test_user_mode_enter) { clear_fault(); - k_thread_user_mode_enter((k_thread_entry_t)umode_enter_func, + k_thread_user_mode_enter(umode_enter_func, NULL, NULL, NULL); } diff --git a/tests/kernel/mutex/mutex_api/src/test_mutex_apis.c b/tests/kernel/mutex/mutex_api/src/test_mutex_apis.c index e141e57222c..2f45e684001 100644 --- a/tests/kernel/mutex/mutex_api/src/test_mutex_apis.c +++ b/tests/kernel/mutex/mutex_api/src/test_mutex_apis.c @@ -104,6 +104,8 @@ static void tmutex_test_lock_unlock(struct k_mutex *pmutex) static void tThread_T1_priority_inheritance(void *p1, void *p2, void *p3) { + ARG_UNUSED(p3); + /* t1 will get mutex first */ zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0, "access locked resource from spawn thread T1"); @@ -150,6 +152,9 @@ static void tThread_T1_priority_inheritance(void *p1, void *p2, void *p3) static void tThread_T2_priority_inheritance(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + if (case_type == 1) { zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0, "access locked resource from spawn thread T2"); @@ -166,6 +171,9 @@ static void tThread_T2_priority_inheritance(void *p1, void *p2, void *p3) static void tThread_lock_with_time_period(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0, "access locked resource from spawn thread"); @@ -177,6 +185,9 @@ static void tThread_lock_with_time_period(void *p1, void *p2, void *p3) static void tThread_waiter(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* This thread participates in recursive locking tests */ /* Wait for mutex to be released */ zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0, @@ -261,7 +272,7 @@ ZTEST_USER(mutex_api, test_mutex_recursive) thread_ret = TC_FAIL; /* Spawn a waiter thread */ k_thread_create(&tdata3, tstack3, STACK_SIZE, - (k_thread_entry_t)tThread_waiter, &tmutex, NULL, NULL, + tThread_waiter, &tmutex, NULL, NULL, K_PRIO_PREEMPT(12), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -305,7 +316,7 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a lower priority thread t1 for holding the mutex */ k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_T1_priority_inheritance, + tThread_T1_priority_inheritance, &tmutex, &tdata, NULL, K_PRIO_PREEMPT(THREAD_LOW_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -319,7 +330,7 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a higher priority thread t2 for holding the mutex */ k_thread_create(&tdata2, tstack2, STACK_SIZE, - (k_thread_entry_t)tThread_T2_priority_inheritance, + tThread_T2_priority_inheritance, &tmutex, &tdata2, NULL, K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -335,7 +346,7 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a lower priority thread t1 for holding the mutex */ k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_T1_priority_inheritance, + tThread_T1_priority_inheritance, &tmutex, &tdata, NULL, K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -345,7 +356,7 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a higher priority thread t2 for holding the mutex */ k_thread_create(&tdata2, tstack2, STACK_SIZE, - (k_thread_entry_t)tThread_T2_priority_inheritance, + tThread_T2_priority_inheritance, &tmutex, &tdata2, NULL, K_PRIO_PREEMPT(THREAD_LOW_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -361,7 +372,7 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a lower priority thread t1 for holding the mutex */ k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_T1_priority_inheritance, + tThread_T1_priority_inheritance, &tmutex, &tdata, NULL, K_PRIO_PREEMPT(THREAD_LOW_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -371,14 +382,14 @@ ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance) /* spawn a higher priority thread t2 for holding the mutex */ k_thread_create(&tdata2, tstack2, STACK_SIZE, - (k_thread_entry_t)tThread_T2_priority_inheritance, + tThread_T2_priority_inheritance, &tmutex, &tdata2, NULL, K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); /* spawn a higher priority thread t3 for holding the mutex */ k_thread_create(&tdata3, tstack3, STACK_SIZE, - (k_thread_entry_t)tThread_lock_with_time_period, + tThread_lock_with_time_period, &tmutex, &tdata3, NULL, K_PRIO_PREEMPT(THREAD_MID_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/mutex/mutex_error_case/src/test_mutex_error.c b/tests/kernel/mutex/mutex_error_case/src/test_mutex_error.c index 955af138b7d..d1ba0557727 100644 --- a/tests/kernel/mutex/mutex_error_case/src/test_mutex_error.c +++ b/tests/kernel/mutex/mutex_error_case/src/test_mutex_error.c @@ -47,6 +47,9 @@ void ztest_post_fatal_error_hook(unsigned int reason, static void tThread_entry_negative(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p3); + int choice = *((int *)p2); TC_PRINT("current case is %d\n", choice); @@ -102,7 +105,7 @@ static int create_negative_test_thread(int choice) case_type = choice; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_entry_negative, + tThread_entry_negative, &mutex, (void *)&case_type, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), perm, K_NO_WAIT); diff --git a/tests/kernel/mutex/sys_mutex/src/main.c b/tests/kernel/mutex/sys_mutex/src/main.c index b335e80f53e..d916a56dd9c 100644 --- a/tests/kernel/mutex/sys_mutex/src/main.c +++ b/tests/kernel/mutex/sys_mutex/src/main.c @@ -88,7 +88,7 @@ static ZTEST_BMEM SYS_MUTEX_DEFINE(bad_count_mutex); #define CREATE_PARTICIPANT_THREAD(id, pri) \ k_thread_create(&thread_##id##_thread_data, thread_##id##_stack_area, \ K_THREAD_STACK_SIZEOF(thread_##id##_stack_area), \ - (k_thread_entry_t)thread_##id, \ + thread_##id, \ NULL, NULL, NULL, \ pri, PARTICIPANT_THREAD_OPTIONS, K_FOREVER); #define START_PARTICIPANT_THREAD(id) k_thread_start(&(thread_##id##_thread_data)); @@ -395,7 +395,7 @@ ZTEST_USER_OR_NOT(mutex_complex, test_mutex) /* Start thread */ k_thread_create(&thread_12_thread_data, thread_12_stack_area, STACKSIZE, - (k_thread_entry_t)thread_12, NULL, NULL, NULL, + thread_12, NULL, NULL, NULL, K_PRIO_PREEMPT(12), PARTICIPANT_THREAD_OPTIONS, K_NO_WAIT); k_sleep(K_MSEC(5)); /* Give thread_12 a chance to block on the mutex */ diff --git a/tests/kernel/mutex/sys_mutex/src/thread_12.c b/tests/kernel/mutex/sys_mutex/src/thread_12.c index f70b654f4b5..fcf548fb645 100644 --- a/tests/kernel/mutex/sys_mutex/src/thread_12.c +++ b/tests/kernel/mutex/sys_mutex/src/thread_12.c @@ -29,8 +29,12 @@ extern struct sys_mutex private_mutex; * */ -void thread_12(void) +void thread_12(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; /* Wait for private mutex to be released */ diff --git a/tests/kernel/sched/metairq/src/main.c b/tests/kernel/sched/metairq/src/main.c index 89b54f7ba77..c7e3af99079 100644 --- a/tests/kernel/sched/metairq/src/main.c +++ b/tests/kernel/sched/metairq/src/main.c @@ -40,7 +40,7 @@ #define CREATE_PARTICIPANT_THREAD(id, pri, entry) \ k_thread_create(&thread_##id##_thread_data, thread_##id##_stack_area, \ K_THREAD_STACK_SIZEOF(thread_##id##_stack_area), \ - (k_thread_entry_t)entry, \ + entry, \ NULL, NULL, NULL, \ pri, PARTICIPANT_THREAD_OPTIONS, K_FOREVER); #define START_PARTICIPANT_THREAD(id) k_thread_start(&(thread_##id##_thread_data)); diff --git a/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c b/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c index 2039d3af509..e3307735f11 100644 --- a/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c +++ b/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c @@ -189,6 +189,10 @@ ZTEST(threads_scheduling, test_sleep_wakeup_preemptible) static int executed; static void coop_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_take(&pend_sema, K_MSEC(100)); executed = 1; } @@ -211,7 +215,7 @@ ZTEST(threads_scheduling, test_pending_thread_wakeup) /* Create a thread which waits for semaphore */ k_tid_t tid = k_thread_create(&t, tstack, STACK_SIZE, - (k_thread_entry_t)coop_thread, + coop_thread, NULL, NULL, NULL, K_PRIO_COOP(1), 0, K_NO_WAIT); diff --git a/tests/kernel/sched/schedule_api/src/user_api.c b/tests/kernel/sched/schedule_api/src/user_api.c index f113de5b4ee..e18eb378e32 100644 --- a/tests/kernel/sched/schedule_api/src/user_api.c +++ b/tests/kernel/sched/schedule_api/src/user_api.c @@ -96,6 +96,10 @@ ZTEST_USER(threads_scheduling, test_user_k_is_preempt) #ifdef CONFIG_USERSPACE static void thread_suspend_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_thread_suspend(NULL); @@ -116,7 +120,7 @@ static void thread_suspend_init_null(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_suspend_init_null) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_suspend_init_null, + thread_suspend_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -133,6 +137,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_suspend_init_null) #ifdef CONFIG_USERSPACE static void thread_resume_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_thread_resume(NULL); @@ -153,7 +161,7 @@ static void thread_resume_init_null(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_resume_init_null) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_resume_init_null, + thread_resume_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -170,6 +178,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_resume_init_null) #ifdef CONFIG_USERSPACE static void thread_priority_get_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_thread_priority_get(NULL); @@ -190,7 +202,7 @@ static void thread_priority_get_init_null(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_priority_get_init_null) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_priority_get_init_null, + thread_priority_get_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -207,6 +219,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_priority_get_init_null) #ifdef CONFIG_USERSPACE static void thread_priority_set_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_thread_priority_set(NULL, 0); @@ -227,7 +243,7 @@ static void thread_priority_set_init_null(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_priority_set_init_null) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_priority_set_init_null, + thread_priority_set_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -244,6 +260,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_priority_set_init_null) #ifdef CONFIG_USERSPACE static void thread_priority_set_overmax(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); /* set valid priority value outside the priority range will invoke fatal error */ @@ -265,7 +285,7 @@ static void thread_priority_set_overmax(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_priority_set_overmax) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_priority_set_overmax, + thread_priority_set_overmax, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -282,6 +302,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_priority_set_overmax) #ifdef CONFIG_USERSPACE static void thread_priority_set_upgrade(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); /* at first, set an valid priority */ @@ -305,7 +329,7 @@ static void thread_priority_set_upgrade(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_thread_priority_set_upgrade) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_priority_set_upgrade, + thread_priority_set_upgrade, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -322,6 +346,10 @@ ZTEST_USER(threads_scheduling, test_k_thread_priority_set_upgrade) #ifdef CONFIG_USERSPACE static void thread_wakeup_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_wakeup(NULL); @@ -342,7 +370,7 @@ static void thread_wakeup_init_null(void *p1, void *p2, void *p3) ZTEST_USER(threads_scheduling, test_k_wakeup_init_null) { k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, - (k_thread_entry_t)thread_wakeup_init_null, + thread_wakeup_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/semaphore/semaphore/src/main.c b/tests/kernel/semaphore/semaphore/src/main.c index 3d146559607..c1efcb8889c 100644 --- a/tests/kernel/semaphore/semaphore/src/main.c +++ b/tests/kernel/semaphore/semaphore/src/main.c @@ -1150,6 +1150,10 @@ ZTEST(semaphore_1cpu, test_sem_queue_mutual_exclusion) #ifdef CONFIG_USERSPACE static void thread_sem_give_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_sem_give(NULL); @@ -1169,7 +1173,7 @@ static void thread_sem_give_null(void *p1, void *p2, void *p3) ZTEST_USER(semaphore_null_case, test_sem_give_null) { k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_sem_give_null, + thread_sem_give_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -1181,6 +1185,10 @@ ZTEST_USER(semaphore_null_case, test_sem_give_null) #ifdef CONFIG_USERSPACE static void thread_sem_init_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_sem_init(NULL, 0, 1); @@ -1200,7 +1208,7 @@ static void thread_sem_init_null(void *p1, void *p2, void *p3) ZTEST_USER(semaphore_null_case, test_sem_init_null) { k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_sem_init_null, + thread_sem_init_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -1212,6 +1220,10 @@ ZTEST_USER(semaphore_null_case, test_sem_init_null) #ifdef CONFIG_USERSPACE static void thread_sem_take_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_sem_take(NULL, K_MSEC(1)); @@ -1231,7 +1243,7 @@ static void thread_sem_take_null(void *p1, void *p2, void *p3) ZTEST_USER(semaphore_null_case, test_sem_take_null) { k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_sem_take_null, + thread_sem_take_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -1243,6 +1255,10 @@ ZTEST_USER(semaphore_null_case, test_sem_take_null) #ifdef CONFIG_USERSPACE static void thread_sem_reset_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_sem_reset(NULL); @@ -1262,7 +1278,7 @@ static void thread_sem_reset_null(void *p1, void *p2, void *p3) ZTEST_USER(semaphore_null_case, test_sem_reset_null) { k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_sem_reset_null, + thread_sem_reset_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -1274,6 +1290,10 @@ ZTEST_USER(semaphore_null_case, test_sem_reset_null) #ifdef CONFIG_USERSPACE static void thread_sem_count_get_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_sem_count_get(NULL); @@ -1293,7 +1313,7 @@ static void thread_sem_count_get_null(void *p1, void *p2, void *p3) ZTEST_USER(semaphore_null_case, test_sem_count_get_null) { k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_sem_count_get_null, + thread_sem_count_get_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/sleep/src/main.c b/tests/kernel/sleep/src/main.c index 28168c1e61e..f380200a6d9 100644 --- a/tests/kernel/sleep/src/main.c +++ b/tests/kernel/sleep/src/main.c @@ -100,8 +100,12 @@ static int sleep_time_valid(uint32_t start, uint32_t end, uint32_t dur) return dt >= dur && dt <= (dur + TICK_MARGIN); } -static void test_thread(int arg1, int arg2) +static void test_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p3); + + int arg1 = POINTER_TO_INT(p1); + int arg2 = POINTER_TO_INT(p2); uint32_t start_tick; uint32_t end_tick; @@ -171,8 +175,12 @@ static void irq_offload_isr(const void *arg) k_wakeup((k_tid_t) arg); } -static void helper_thread(int arg1, int arg2) +static void helper_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p3); + + int arg1 = POINTER_TO_INT(p1); + int arg2 = POINTER_TO_INT(p2); k_sem_take(&helper_thread_sem, K_FOREVER); /* Wake the test thread */ @@ -205,7 +213,7 @@ ZTEST(sleep, test_sleep) test_thread_id = k_thread_create(&test_thread_data, test_thread_stack, THREAD_STACK, - (k_thread_entry_t) test_thread, + test_thread, 0, 0, NULL, TEST_THREAD_PRIORITY, 0, K_NO_WAIT); @@ -213,7 +221,7 @@ ZTEST(sleep, test_sleep) helper_thread_id = k_thread_create(&helper_thread_data, helper_thread_stack, THREAD_STACK, - (k_thread_entry_t) helper_thread, + helper_thread, 0, 0, NULL, HELPER_THREAD_PRIORITY, 0, K_NO_WAIT); diff --git a/tests/kernel/smp/src/main.c b/tests/kernel/smp/src/main.c index 794ad88027e..033df7839a4 100644 --- a/tests/kernel/smp/src/main.c +++ b/tests/kernel/smp/src/main.c @@ -575,6 +575,10 @@ ZTEST(smp, test_wakeup_threads) /* a thread for testing get current cpu */ static void thread_get_cpu_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int bsp_id = *(int *)p1; int cpu_id = -1; @@ -660,7 +664,7 @@ ZTEST(smp, test_get_cpu) _cpu_id = arch_curr_cpu()->id; thread_id = k_thread_create(&t2, t2_stack, T2_STACK_SIZE, - (k_thread_entry_t)thread_get_cpu_entry, + thread_get_cpu_entry, &_cpu_id, NULL, NULL, K_PRIO_COOP(2), K_INHERIT_PERMS, K_NO_WAIT); @@ -849,6 +853,9 @@ ZTEST(smp, test_workq_on_smp) static void t1_mutex_lock(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* t1 will get mutex first */ k_mutex_lock((struct k_mutex *)p1, K_FOREVER); @@ -859,6 +866,9 @@ static void t1_mutex_lock(void *p1, void *p2, void *p3) static void t2_mutex_lock(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + zassert_equal(_current->base.global_lock_count, 0, "thread global lock cnt %d is incorrect", _current->base.global_lock_count); @@ -894,14 +904,14 @@ ZTEST(smp, test_smp_release_global_lock) tinfo[0].tid = k_thread_create(&tthread[0], tstack[0], STACK_SIZE, - (k_thread_entry_t)t1_mutex_lock, + t1_mutex_lock, &smutex, NULL, NULL, K_PRIO_PREEMPT(5), K_INHERIT_PERMS, K_NO_WAIT); tinfo[1].tid = k_thread_create(&tthread[1], tstack[1], STACK_SIZE, - (k_thread_entry_t)t2_mutex_lock, + t2_mutex_lock, &smutex, NULL, NULL, K_PRIO_PREEMPT(3), K_INHERIT_PERMS, K_MSEC(1)); @@ -1004,8 +1014,12 @@ static void inc_global_cnt(void *a, void *b, void *c) } } -static int run_concurrency(int type, void *func) +static int run_concurrency(void *p1, void *p2, void *p3) { + ARG_UNUSED(p3); + + int type = POINTER_TO_INT(p1); + k_thread_entry_t func = p2; uint32_t start_t, end_t; sync_init(type); @@ -1014,21 +1028,21 @@ static int run_concurrency(int type, void *func) tinfo[0].tid = k_thread_create(&tthread[0], tstack[0], STACK_SIZE, - (k_thread_entry_t)func, + func, NULL, NULL, NULL, K_PRIO_PREEMPT(1), K_INHERIT_PERMS, K_NO_WAIT); tinfo[1].tid = k_thread_create(&tthread[1], tstack[1], STACK_SIZE, - (k_thread_entry_t)func, + func, NULL, NULL, NULL, K_PRIO_PREEMPT(1), K_INHERIT_PERMS, K_NO_WAIT); k_tid_t tid = k_thread_create(&t2, t2_stack, T2_STACK_SIZE, - (k_thread_entry_t)func, + func, NULL, NULL, NULL, K_PRIO_PREEMPT(1), K_INHERIT_PERMS, K_NO_WAIT); @@ -1087,6 +1101,9 @@ ZTEST(smp, test_inc_concurrency) */ static void process_events(void *arg0, void *arg1, void *arg2) { + ARG_UNUSED(arg1); + ARG_UNUSED(arg2); + uintptr_t id = (uintptr_t) arg0; while (1) { @@ -1137,7 +1154,7 @@ ZTEST(smp, test_smp_switch_torture) K_POLL_MODE_NOTIFY_ONLY, &tsignal[i]); k_thread_create(&tthread[i], tstack[i], STACK_SIZE, - (k_thread_entry_t) process_events, + process_events, (void *) i, NULL, NULL, K_PRIO_PREEMPT(i + 1), K_INHERIT_PERMS, K_NO_WAIT); } diff --git a/tests/kernel/threads/thread_apis/src/main.c b/tests/kernel/threads/thread_apis/src/main.c index f287ec8daa6..a71dd28f900 100644 --- a/tests/kernel/threads/thread_apis/src/main.c +++ b/tests/kernel/threads/thread_apis/src/main.c @@ -248,7 +248,7 @@ static void enter_user_mode_entry(void *p1, void *p2, void *p3) zassert_true(z_is_thread_essential(), "Thread isn't set" " as essential\n"); - k_thread_user_mode_enter((k_thread_entry_t)umode_entry, + k_thread_user_mode_enter(umode_entry, k_current_get(), NULL, NULL); } diff --git a/tests/kernel/threads/thread_apis/src/test_essential_thread.c b/tests/kernel/threads/thread_apis/src/test_essential_thread.c index 9dae2829549..7cebccf4776 100644 --- a/tests/kernel/threads/thread_apis/src/test_essential_thread.c +++ b/tests/kernel/threads/thread_apis/src/test_essential_thread.c @@ -22,6 +22,10 @@ static bool fatal_error_signaled; static void thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + z_thread_essential_set(); if (z_is_thread_essential()) { @@ -47,7 +51,7 @@ static void thread_entry(void *p1, void *p2, void *p3) ZTEST(threads_lifecycle, test_essential_thread_operation) { k_tid_t tid = k_thread_create(&kthread_thread, kthread_stack, - STACKSIZE, (k_thread_entry_t)thread_entry, NULL, + STACKSIZE, thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); @@ -68,6 +72,10 @@ void k_sys_fatal_error_handler(unsigned int reason, static void abort_thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + z_thread_essential_set(); if (z_is_thread_essential()) { @@ -94,7 +102,7 @@ static void abort_thread_entry(void *p1, void *p2, void *p3) ZTEST(threads_lifecycle, test_essential_thread_abort) { k_tid_t tid = k_thread_create(&kthread_thread1, kthread_stack, STACKSIZE, - (k_thread_entry_t)abort_thread_entry, + abort_thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); diff --git a/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c b/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c index 76c10d96656..654e2224d57 100644 --- a/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c +++ b/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c @@ -24,6 +24,10 @@ K_THREAD_STACK_DEFINE(tstack1, STACK_SIZE); static void thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_msleep(SLEEP_MS); } @@ -48,7 +52,7 @@ void thread_callback_unlocked(const struct k_thread *thread, void *user_data) if (create_thread) { in_callback_tid = k_thread_create(&tdata1, tstack1, STACK_SIZE, - (k_thread_entry_t)thread_entry, + thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); create_thread = false; @@ -98,7 +102,7 @@ ZTEST(threads_lifecycle_1cpu, test_k_thread_foreach) /* Create new thread which should add a new entry to the thread list */ k_tid_t tid = k_thread_create(&tdata, tstack, - STACK_SIZE, (k_thread_entry_t)thread_entry, NULL, + STACK_SIZE, thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); k_msleep(1); @@ -147,7 +151,7 @@ ZTEST(threads_lifecycle_1cpu, test_k_thread_foreach_unlocked) /* Create new thread which should add a new entry to the thread list */ k_tid_t tid = k_thread_create(&tdata, tstack, - STACK_SIZE, (k_thread_entry_t)thread_entry, NULL, + STACK_SIZE, thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT); k_msleep(1); diff --git a/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c b/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c index cfe4fab24b7..aad8842a11e 100644 --- a/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c +++ b/tests/kernel/threads/thread_apis/src/test_threads_cancel_abort.c @@ -110,6 +110,10 @@ void *block; static void delayed_thread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + execute_flag = 1; zassert_unreachable("Delayed thread shouldn't be executed"); @@ -134,7 +138,7 @@ ZTEST(threads_lifecycle_1cpu, test_delayed_thread_abort) * current thread */ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)delayed_thread_entry, NULL, NULL, NULL, + delayed_thread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(1), 0, K_MSEC(100)); /* Give up CPU */ diff --git a/tests/kernel/threads/thread_apis/src/test_threads_set_priority.c b/tests/kernel/threads/thread_apis/src/test_threads_set_priority.c index ec70c043cb4..e43487704f0 100644 --- a/tests/kernel/threads/thread_apis/src/test_threads_set_priority.c +++ b/tests/kernel/threads/thread_apis/src/test_threads_set_priority.c @@ -18,8 +18,12 @@ K_SEM_DEFINE(sem_thread1, 0, 1); * @brief thread2 portion to test setting the priority * */ -void thread2_set_prio_test(void) +void thread2_set_prio_test(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* lower thread2 priority by 5 */ k_sem_take(&sem_thread2, K_FOREVER); thread2_data = k_thread_priority_get(k_current_get()); @@ -72,7 +76,7 @@ ZTEST(threads_lifecycle, test_threads_priority_set) int thread2_prio = prio + 1; k_tid_t thread2_id = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread2_set_prio_test, + thread2_set_prio_test, NULL, NULL, NULL, thread2_prio, 0, K_NO_WAIT); diff --git a/tests/kernel/threads/thread_error_case/src/main.c b/tests/kernel/threads/thread_error_case/src/main.c index a986fb7eac4..b4df5a899a7 100644 --- a/tests/kernel/threads/thread_error_case/src/main.c +++ b/tests/kernel/threads/thread_error_case/src/main.c @@ -35,6 +35,9 @@ static void test_thread(void *p1, void *p2, void *p3) static void tThread_entry_negative(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int choice = *((int *)p1); uint32_t perm = K_INHERIT_PERMS; @@ -114,7 +117,7 @@ static void create_negative_test_thread(int choice) case_type = choice; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_entry_negative, + tThread_entry_negative, (void *)&case_type, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), perm, K_NO_WAIT); diff --git a/tests/kernel/timer/timer_error_case/src/main.c b/tests/kernel/timer/timer_error_case/src/main.c index 770253677f3..e6ffe75330c 100644 --- a/tests/kernel/timer/timer_error_case/src/main.c +++ b/tests/kernel/timer/timer_error_case/src/main.c @@ -22,6 +22,10 @@ static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); static void thread_timer_start_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_start(NULL, K_MSEC(DURATION), K_NO_WAIT); @@ -47,7 +51,7 @@ ZTEST_USER(timer_api_error, test_timer_start_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_start_null, + thread_timer_start_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -57,6 +61,10 @@ ZTEST_USER(timer_api_error, test_timer_start_null) static void thread_timer_stop_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_stop(NULL); @@ -81,7 +89,7 @@ ZTEST_USER(timer_api_error, test_timer_stop_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_stop_null, + thread_timer_stop_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -91,6 +99,10 @@ ZTEST_USER(timer_api_error, test_timer_stop_null) static void thread_timer_status_get_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_status_get(NULL); @@ -115,7 +127,7 @@ ZTEST_USER(timer_api_error, test_timer_status_get_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_status_get_null, + thread_timer_status_get_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -125,6 +137,10 @@ ZTEST_USER(timer_api_error, test_timer_status_get_null) static void thread_timer_status_sync_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_status_sync(NULL); @@ -149,7 +165,7 @@ ZTEST_USER(timer_api_error, test_timer_status_sync_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_status_sync_null, + thread_timer_status_sync_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -159,6 +175,10 @@ ZTEST_USER(timer_api_error, test_timer_status_sync_null) static void thread_timer_remaining_ticks_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_remaining_ticks(NULL); @@ -183,7 +203,7 @@ ZTEST_USER(timer_api_error, test_timer_remaining_ticks_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_remaining_ticks_null, + thread_timer_remaining_ticks_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -193,6 +213,10 @@ ZTEST_USER(timer_api_error, test_timer_remaining_ticks_null) static void thread_timer_expires_ticks_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_expires_ticks(NULL); @@ -216,7 +240,7 @@ ZTEST_USER(timer_api_error, test_timer_expires_ticks_null) ztest_test_skip(); #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_expires_ticks_null, + thread_timer_expires_ticks_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -226,6 +250,10 @@ ZTEST_USER(timer_api_error, test_timer_expires_ticks_null) static void thread_timer_user_data_get_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + ztest_set_fault_valid(true); k_timer_user_data_get(NULL); @@ -249,7 +277,7 @@ ZTEST_USER(timer_api_error, test_timer_user_data_get_null) ztest_test_skip(); #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_user_data_get_null, + thread_timer_user_data_get_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -259,6 +287,10 @@ ZTEST_USER(timer_api_error, test_timer_user_data_get_null) static void thread_timer_user_data_set_null(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int user_data = 1; ztest_set_fault_valid(true); @@ -285,7 +317,7 @@ ZTEST_USER(timer_api_error, test_timer_user_data_set_null) #endif k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)thread_timer_user_data_set_null, + thread_timer_user_data_set_null, NULL, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), K_USER | K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/kernel/workq/work_queue/src/main.c b/tests/kernel/workq/work_queue/src/main.c index 70d186cae6a..5d653c728c0 100644 --- a/tests/kernel/workq/work_queue/src/main.c +++ b/tests/kernel/workq/work_queue/src/main.c @@ -124,12 +124,13 @@ static void reset_results(void) num_results = 0; } -static void coop_work_main(int arg1, int arg2) +static void coop_work_main(void *p1, void *p2, void *p3) { - int i; + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); - ARG_UNUSED(arg1); - ARG_UNUSED(arg2); + int i; /* Let the preempt thread submit the first work item. */ k_msleep(SUBMIT_WAIT / 2); @@ -150,7 +151,7 @@ static void delayed_test_items_submit(void) int i; k_thread_create(&co_op_data, co_op_stack, STACK_SIZE, - (k_thread_entry_t)coop_work_main, + coop_work_main, NULL, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); for (i = 0; i < NUM_TEST_ITEMS; i += 2) { @@ -271,12 +272,13 @@ static void test_delayed_init(void) } } -static void coop_delayed_work_main(int arg1, int arg2) +static void coop_delayed_work_main(void *p1, void *p2, void *p3) { - int i; + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); - ARG_UNUSED(arg1); - ARG_UNUSED(arg2); + int i; /* Let the preempt thread submit the first work item. */ k_msleep(SUBMIT_WAIT / 2); @@ -301,7 +303,7 @@ static void test_delayed_submit(void) int i; k_thread_create(&co_op_data, co_op_stack, STACK_SIZE, - (k_thread_entry_t)coop_delayed_work_main, + coop_delayed_work_main, NULL, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); for (i = 0; i < NUM_TEST_ITEMS; i += 2) { @@ -313,10 +315,11 @@ static void test_delayed_submit(void) } -static void coop_delayed_work_cancel_main(int arg1, int arg2) +static void coop_delayed_work_cancel_main(void *p1, void *p2, void *p3) { - ARG_UNUSED(arg1); - ARG_UNUSED(arg2); + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); k_work_schedule(&delayed_tests[1].work, K_MSEC(WORK_ITEM_WAIT)); @@ -342,7 +345,7 @@ ZTEST(workqueue_delayed, test_delayed_cancel) k_work_cancel_delayable(&delayed_tests[0].work); k_thread_create(&co_op_data, co_op_stack, STACK_SIZE, - (k_thread_entry_t)coop_delayed_work_cancel_main, + coop_delayed_work_cancel_main, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); TC_PRINT(" - Waiting for work to finish\n"); diff --git a/tests/lib/fdtable/src/main.c b/tests/lib/fdtable/src/main.c index 8a43bd84a3d..f10a4ef115a 100644 --- a/tests/lib/fdtable/src/main.c +++ b/tests/lib/fdtable/src/main.c @@ -133,9 +133,12 @@ ZTEST(fdtable, test_z_free_fd) zassert_equal_ptr(obj, NULL, "obj is not NULL after freeing"); } -static void test_cb(void *fd_ptr) +static void test_cb(void *p1, void *p2, void *p3) { - int fd = POINTER_TO_INT(fd_ptr); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + int fd = POINTER_TO_INT(p1); const struct fd_op_vtable *vtable; int *obj; @@ -163,7 +166,7 @@ ZTEST(fdtable, test_z_fd_multiple_access) k_thread_create(&fd_thread, fd_thread_stack, K_THREAD_STACK_SIZEOF(fd_thread_stack), - (k_thread_entry_t)test_cb, + test_cb, INT_TO_POINTER(shared_fd), NULL, NULL, CONFIG_ZTEST_THREAD_PRIORITY, 0, K_NO_WAIT); diff --git a/tests/net/buf/src/main.c b/tests/net/buf/src/main.c index 88ec644d4e6..a96c6fe83e2 100644 --- a/tests/net/buf/src/main.c +++ b/tests/net/buf/src/main.c @@ -150,6 +150,8 @@ ZTEST(net_buf_tests, test_net_buf_2) static void test_3_thread(void *arg1, void *arg2, void *arg3) { + ARG_UNUSED(arg3); + struct k_fifo *fifo = (struct k_fifo *)arg1; struct k_sem *sema = (struct k_sem *)arg2; struct net_buf *buf; @@ -192,7 +194,7 @@ ZTEST(net_buf_tests, test_net_buf_3) k_thread_create(&test_3_thread_data, test_3_thread_stack, K_THREAD_STACK_SIZEOF(test_3_thread_stack), - (k_thread_entry_t) test_3_thread, &fifo, &sema, NULL, + test_3_thread, &fifo, &sema, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); zassert_true(k_sem_take(&sema, TEST_TIMEOUT) == 0, diff --git a/tests/net/context/src/main.c b/tests/net/context/src/main.c index bad60738629..e3596f236c8 100644 --- a/tests/net/context/src/main.c +++ b/tests/net/context/src/main.c @@ -789,10 +789,11 @@ static void recv_cb_timeout(struct net_context *context, net_pkt_unref(pkt); } -void timeout_thread(struct net_context *ctx, void *param2, void *param3) +void timeout_thread(void *p1, void *p2, void *p3) { - int family = POINTER_TO_INT(param2); - int32_t timeout = POINTER_TO_INT(param3); + struct net_context *ctx = p1; + int family = POINTER_TO_INT(p2); + int32_t timeout = POINTER_TO_INT(p3); int ret; ret = net_context_recv(ctx, recv_cb_timeout, K_MSEC(timeout), @@ -818,7 +819,7 @@ void timeout_thread(struct net_context *ctx, void *param2, void *param3) static k_tid_t start_timeout_v6_thread(int32_t timeout) { return k_thread_create(&thread_data, thread_stack, STACKSIZE, - (k_thread_entry_t)timeout_thread, + timeout_thread, udp_v6_ctx, INT_TO_POINTER(AF_INET6), INT_TO_POINTER(timeout), K_PRIO_COOP(7), 0, K_NO_WAIT); @@ -827,7 +828,7 @@ static k_tid_t start_timeout_v6_thread(int32_t timeout) static k_tid_t start_timeout_v4_thread(int32_t timeout) { return k_thread_create(&thread_data, thread_stack, STACKSIZE, - (k_thread_entry_t)timeout_thread, + timeout_thread, udp_v4_ctx, INT_TO_POINTER(AF_INET), INT_TO_POINTER(timeout), K_PRIO_COOP(7), 0, K_NO_WAIT); diff --git a/tests/net/iface/src/main.c b/tests/net/iface/src/main.c index 89abd22d5d7..b33845608d6 100644 --- a/tests/net/iface/src/main.c +++ b/tests/net/iface/src/main.c @@ -776,8 +776,12 @@ ZTEST(net_iface, test_v4_addr_add_rm) #define MY_ADDR_V4_USER { { { 10, 0, 0, 2 } } } #define UNKNOWN_ADDR_V4_USER { { { 5, 6, 7, 8 } } } -static void v4_addr_add_user(void) +static void v4_addr_add_user(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in_addr my_addr = MY_ADDR_V4_USER; bool ret; @@ -788,7 +792,7 @@ static void v4_addr_add_user(void) static void v4_addr_add_user_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)v4_addr_add_user, NULL, + k_thread_user_mode_enter(v4_addr_add_user, NULL, NULL, NULL); } @@ -805,8 +809,12 @@ static void v4_addr_lookup_user(void) zassert_equal(ret, 0, "IPv4 address found"); } -static void v4_addr_rm_user(void) +static void v4_addr_rm_user(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in_addr my_addr = MY_ADDR_V4_USER; bool ret; @@ -817,7 +825,7 @@ static void v4_addr_rm_user(void) static void v4_addr_rm_user_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)v4_addr_rm_user, NULL, + k_thread_user_mode_enter(v4_addr_rm_user, NULL, NULL, NULL); } @@ -940,8 +948,12 @@ ZTEST(net_iface, test_v6_addr_add_rm_solicited) #define UNKNOWN_ADDR_V6_USER { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0x66 } } } -static void v6_addr_add_user(void) +static void v6_addr_add_user(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in6_addr my_addr = MY_ADDR_V6_USER; bool ret; @@ -952,7 +964,7 @@ static void v6_addr_add_user(void) static void v6_addr_add_user_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)v6_addr_add_user, NULL, + k_thread_user_mode_enter(v6_addr_add_user, NULL, NULL, NULL); } @@ -969,8 +981,12 @@ static void v6_addr_lookup_user(void) zassert_equal(ret, 0, "IPv6 address found"); } -static void v6_addr_rm_user(void) +static void v6_addr_rm_user(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in6_addr my_addr = MY_ADDR_V6_USER; bool ret; @@ -984,7 +1000,7 @@ static void v6_addr_rm_user(void) static void v6_addr_rm_user_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)v6_addr_rm_user, NULL, + k_thread_user_mode_enter(v6_addr_rm_user, NULL, NULL, NULL); } @@ -995,8 +1011,12 @@ ZTEST(net_iface, test_v6_addr_add_rm_user_from_userspace) v6_addr_rm_user_from_userspace(); } -static void netmask_addr_add(void) +static void netmask_addr_add(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in_addr my_netmask = { { { 255, 255, 255, 0 } } }; bool ret; @@ -1006,13 +1026,13 @@ static void netmask_addr_add(void) ZTEST(net_iface, test_netmask_addr_add) { - netmask_addr_add(); + netmask_addr_add(NULL, NULL, NULL); } static void netmask_addr_add_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)netmask_addr_add, NULL, + k_thread_user_mode_enter(netmask_addr_add, NULL, NULL, NULL); } @@ -1021,8 +1041,12 @@ ZTEST(net_iface, test_netmask_addr_add_from_userspace) netmask_addr_add_from_userspace(); } -static void gw_addr_add(void) +static void gw_addr_add(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct in_addr my_gw = { { { 192, 0, 2, 254 } } }; bool ret; @@ -1032,13 +1056,13 @@ static void gw_addr_add(void) ZTEST(net_iface, test_gw_addr_add) { - gw_addr_add(); + gw_addr_add(NULL, NULL, NULL); } static void gw_addr_add_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)gw_addr_add, NULL, + k_thread_user_mode_enter(gw_addr_add, NULL, NULL, NULL); } @@ -1047,21 +1071,25 @@ ZTEST(net_iface, test_gw_addr_add_from_userspace) gw_addr_add_from_userspace(); } -static void get_by_index(void) +static void get_by_index(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + zassert_not_null(net_if_get_by_index(1), "Cannot get interface at index 1"); } ZTEST(net_iface, test_get_by_index) { - get_by_index(); + get_by_index(NULL, NULL, NULL); } static void get_by_index_from_userspace(void) { k_thread_access_grant(k_current_get(), net_if_get_by_index(1)); - k_thread_user_mode_enter((k_thread_entry_t)get_by_index, NULL, + k_thread_user_mode_enter(get_by_index, NULL, NULL, NULL); } diff --git a/tests/net/mgmt/src/mgmt.c b/tests/net/mgmt/src/mgmt.c index 23edc1a6a69..52be33eb3dc 100644 --- a/tests/net/mgmt/src/mgmt.c +++ b/tests/net/mgmt/src/mgmt.c @@ -105,8 +105,12 @@ void test_requesting_nm(void) "Requesting Net MGMT failed"); } -static void thrower_thread(void) +static void thrower_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (1) { k_sem_take(&thrower_lock, K_FOREVER); @@ -253,7 +257,7 @@ static void initialize_event_tests(void) k_thread_create(&thrower_thread_data, thrower_stack, K_THREAD_STACK_SIZEOF(thrower_stack), - (k_thread_entry_t)thrower_thread, + thrower_thread, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); } diff --git a/tests/subsys/edac/ibecc/src/ibecc.c b/tests/subsys/edac/ibecc/src/ibecc.c index 3b6c3c347f6..57e12ee5d1a 100644 --- a/tests/subsys/edac/ibecc/src/ibecc.c +++ b/tests/subsys/edac/ibecc/src/ibecc.c @@ -262,8 +262,10 @@ static void test_inject(const struct device *dev, uint64_t addr, uint64_t mask, zassert_equal(ret, 0, "Error setting ctrl"); } -static int check_values(void *p1, void *p2, void *p3) +static void check_values(void *p1, void *p2, void *p3) { + ARG_UNUSED(p3); + intptr_t address = (intptr_t)p1; intptr_t type = (intptr_t)p2; intptr_t addr, errtype; @@ -280,8 +282,6 @@ static int check_values(void *p1, void *p2, void *p3) /* Verify page address and error type */ zassert_equal(addr, address, "Error address wrong"); zassert_equal(errtype, type, "Error type wrong"); - - return 0; } static void ibecc_error_inject_test(uint64_t addr, uint64_t mask, uint64_t type) @@ -299,7 +299,7 @@ static void ibecc_error_inject_test(uint64_t addr, uint64_t mask, uint64_t type) test_inject(dev, addr, mask, type); #if defined(CONFIG_USERSPACE) - k_thread_user_mode_enter((k_thread_entry_t)check_values, + k_thread_user_mode_enter(check_values, (void *)addr, (void *)type, NULL); diff --git a/tests/subsys/rtio/rtio_api/src/test_rtio_mpsc.c b/tests/subsys/rtio/rtio_api/src/test_rtio_mpsc.c index 705170798c8..a656c119b9e 100644 --- a/tests/subsys/rtio/rtio_api/src/test_rtio_mpsc.c +++ b/tests/subsys/rtio/rtio_api/src/test_rtio_mpsc.c @@ -102,6 +102,10 @@ static struct rtio_mpsc mpsc_q; static void mpsc_consumer(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct rtio_mpsc_node *n; struct mpsc_node *nn; @@ -124,6 +128,10 @@ static void mpsc_consumer(void *p1, void *p2, void *p3) static void mpsc_producer(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct mpsc_node *n; uint32_t id = (uint32_t)(uintptr_t)p1; @@ -163,7 +171,7 @@ ZTEST(rtio_mpsc, test_mpsc_threaded) TC_PRINT("starting consumer\n"); mpsc_tinfo[0].tid = k_thread_create(&mpsc_thread[0], mpsc_stack[0], MPSC_STACK_SIZE, - (k_thread_entry_t)mpsc_consumer, + mpsc_consumer, NULL, NULL, NULL, K_PRIO_PREEMPT(5), K_INHERIT_PERMS, K_NO_WAIT); @@ -172,7 +180,7 @@ ZTEST(rtio_mpsc, test_mpsc_threaded) TC_PRINT("starting producer %i\n", i); mpsc_tinfo[i].tid = k_thread_create(&mpsc_thread[i], mpsc_stack[i], MPSC_STACK_SIZE, - (k_thread_entry_t)mpsc_producer, + mpsc_producer, (void *)(uintptr_t)i, NULL, NULL, K_PRIO_PREEMPT(5), K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/subsys/rtio/rtio_api/src/test_rtio_spsc.c b/tests/subsys/rtio/rtio_api/src/test_rtio_spsc.c index a161b9fab07..12fe9476f3f 100644 --- a/tests/subsys/rtio/rtio_api/src/test_rtio_spsc.c +++ b/tests/subsys/rtio/rtio_api/src/test_rtio_spsc.c @@ -141,6 +141,9 @@ RTIO_SPSC_DEFINE(spsc, uint32_t, 4); static void t1_consume(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct rtio_spsc_spsc *ezspsc = p1; uint32_t retries = 0; uint32_t *val = NULL; @@ -162,6 +165,9 @@ static void t1_consume(void *p1, void *p2, void *p3) static void t2_produce(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct rtio_spsc_spsc *ezspsc = p1; uint32_t retries = 0; uint32_t *val = NULL; @@ -201,13 +207,13 @@ ZTEST(rtio_spsc, test_spsc_threaded) tinfo[0].tid = k_thread_create(&tthread[0], tstack[0], STACK_SIZE, - (k_thread_entry_t)t1_consume, + t1_consume, &spsc, NULL, NULL, K_PRIO_PREEMPT(5), K_INHERIT_PERMS, K_NO_WAIT); tinfo[1].tid = k_thread_create(&tthread[1], tstack[1], STACK_SIZE, - (k_thread_entry_t)t2_produce, + t2_produce, &spsc, NULL, NULL, K_PRIO_PREEMPT(5), K_INHERIT_PERMS, K_NO_WAIT); diff --git a/tests/ztest/error_hook/src/main.c b/tests/ztest/error_hook/src/main.c index cde770e5f9f..560171ac365 100644 --- a/tests/ztest/error_hook/src/main.c +++ b/tests/ztest/error_hook/src/main.c @@ -201,6 +201,9 @@ void ztest_post_assert_fail_hook(void) static void tThread_entry(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int sub_type = *(int *)p1; printk("case type is %d\n", case_type); @@ -249,7 +252,7 @@ static int run_trigger_thread(int i) } k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, - (k_thread_entry_t)tThread_entry, + tThread_entry, (void *)&case_type, NULL, NULL, K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), perm, K_NO_WAIT); From d7f0da1c78f68a56a19d4e5540f7e63a99fca86f Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 10:01:46 +0200 Subject: [PATCH 2780/4498] net: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- subsys/net/conn_mgr/conn_mgr_monitor.c | 8 ++++++-- subsys/net/ip/net_if.c | 8 ++++++-- subsys/net/ip/net_mgmt.c | 8 ++++++-- subsys/net/ip/net_tc.c | 16 ++++++++++++---- subsys/net/l2/ethernet/gptp/gptp.c | 8 ++++++-- subsys/net/l2/ppp/ppp_l2.c | 10 +++++++--- subsys/net/lib/lwm2m/lwm2m_engine.c | 8 ++++++-- 7 files changed, 49 insertions(+), 17 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr_monitor.c b/subsys/net/conn_mgr/conn_mgr_monitor.c index 7396b06dc54..69c21f75b2c 100644 --- a/subsys/net/conn_mgr/conn_mgr_monitor.c +++ b/subsys/net/conn_mgr/conn_mgr_monitor.c @@ -193,8 +193,12 @@ static void conn_mgr_mon_init_cb(struct net_if *iface, void *user_data) conn_mgr_mon_initial_state(iface); } -static void conn_mgr_mon_thread_fn(void) +static void conn_mgr_mon_thread_fn(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_mutex_lock(&conn_mgr_mon_lock, K_FOREVER); conn_mgr_conn_init(); @@ -332,7 +336,7 @@ static int conn_mgr_mon_init(void) k_thread_create(&conn_mgr_mon_thread, conn_mgr_mon_stack, CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE, - (k_thread_entry_t)conn_mgr_mon_thread_fn, + conn_mgr_mon_thread_fn, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); return 0; diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 66ee02252dc..b77c3ad3269 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4618,8 +4618,12 @@ bool net_if_is_suspended(struct net_if *iface) #endif /* CONFIG_NET_POWER_MANAGEMENT */ #if defined(CONFIG_NET_PKT_TIMESTAMP_THREAD) -static void net_tx_ts_thread(void) +static void net_tx_ts_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct net_pkt *pkt; NET_DBG("Starting TX timestamp callback thread"); @@ -4880,7 +4884,7 @@ void net_if_init(void) #if defined(CONFIG_NET_PKT_TIMESTAMP_THREAD) k_thread_create(&tx_thread_ts, tx_ts_stack, K_KERNEL_STACK_SIZEOF(tx_ts_stack), - (k_thread_entry_t)net_tx_ts_thread, + net_tx_ts_thread, NULL, NULL, NULL, K_PRIO_COOP(1), 0, K_NO_WAIT); k_thread_name_set(&tx_thread_ts, "tx_tstamp"); #endif /* CONFIG_NET_PKT_TIMESTAMP_THREAD */ diff --git a/subsys/net/ip/net_mgmt.c b/subsys/net/ip/net_mgmt.c index 4ae67a8aeda..d26503b2858 100644 --- a/subsys/net/ip/net_mgmt.c +++ b/subsys/net/ip/net_mgmt.c @@ -189,8 +189,12 @@ static inline void mgmt_run_callbacks(const struct mgmt_event_entry * const mgmt #endif } -static void mgmt_thread(void) +static void mgmt_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct mgmt_event_entry mgmt_event; while (1) { @@ -343,7 +347,7 @@ void net_mgmt_event_init(void) k_thread_create(&mgmt_thread_data, mgmt_stack, K_KERNEL_STACK_SIZEOF(mgmt_stack), - (k_thread_entry_t)mgmt_thread, NULL, NULL, NULL, + mgmt_thread, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); k_thread_name_set(&mgmt_thread_data, "net_mgmt"); diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index b9e21ba79e4..d789232b582 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -237,8 +237,12 @@ static void net_tc_rx_stats_priority_setup(struct net_if *iface, #endif #if NET_TC_RX_COUNT > 0 -static void tc_rx_handler(struct k_fifo *fifo) +static void tc_rx_handler(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct k_fifo *fifo = p1; struct net_pkt *pkt; while (1) { @@ -253,8 +257,12 @@ static void tc_rx_handler(struct k_fifo *fifo) #endif #if NET_TC_TX_COUNT > 0 -static void tc_tx_handler(struct k_fifo *fifo) +static void tc_tx_handler(void *p1, void *p2, void *p3) { + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct k_fifo *fifo = p1; struct net_pkt *pkt; while (1) { @@ -309,7 +317,7 @@ void net_tc_tx_init(void) tid = k_thread_create(&tx_classes[i].handler, tx_stack[i], K_KERNEL_STACK_SIZEOF(tx_stack[i]), - (k_thread_entry_t)tc_tx_handler, + tc_tx_handler, &tx_classes[i].fifo, NULL, NULL, priority, 0, K_FOREVER); if (!tid) { @@ -367,7 +375,7 @@ void net_tc_rx_init(void) tid = k_thread_create(&rx_classes[i].handler, rx_stack[i], K_KERNEL_STACK_SIZEOF(rx_stack[i]), - (k_thread_entry_t)tc_rx_handler, + tc_rx_handler, &rx_classes[i].fifo, NULL, NULL, priority, 0, K_FOREVER); if (!tid) { diff --git a/subsys/net/l2/ethernet/gptp/gptp.c b/subsys/net/l2/ethernet/gptp/gptp.c index 3f822ad548c..2cb128d26c2 100644 --- a/subsys/net/l2/ethernet/gptp/gptp.c +++ b/subsys/net/l2/ethernet/gptp/gptp.c @@ -540,8 +540,12 @@ static void gptp_state_machine(void) gptp_mi_state_machines(); } -static void gptp_thread(void) +static void gptp_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int port; NET_DBG("Starting PTP thread"); @@ -917,7 +921,7 @@ static void init_ports(void) tid = k_thread_create(&gptp_thread_data, gptp_stack, K_KERNEL_STACK_SIZEOF(gptp_stack), - (k_thread_entry_t)gptp_thread, + gptp_thread, NULL, NULL, NULL, K_PRIO_COOP(5), 0, K_NO_WAIT); k_thread_name_set(&gptp_thread_data, "gptp"); } diff --git a/subsys/net/l2/ppp/ppp_l2.c b/subsys/net/l2/ppp/ppp_l2.c index b949c491406..e2bf29274cc 100644 --- a/subsys/net/l2/ppp/ppp_l2.c +++ b/subsys/net/l2/ppp/ppp_l2.c @@ -30,10 +30,10 @@ static K_FIFO_DEFINE(tx_queue); #define THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NET_L2_PPP_THREAD_PRIO) #endif -static void tx_handler(void); +static void tx_handler(void *p1, void *p2, void *p3); static K_THREAD_DEFINE(tx_handler_thread, CONFIG_NET_L2_PPP_TX_STACK_SIZE, - (k_thread_entry_t)tx_handler, NULL, NULL, NULL, + tx_handler, NULL, NULL, NULL, THREAD_PRIORITY, 0, 0); static const struct ppp_protocol_handler *ppp_lcp; @@ -344,8 +344,12 @@ void ppp_queue_pkt(struct net_pkt *pkt) k_fifo_put(&tx_queue, pkt); } -static void tx_handler(void) +static void tx_handler(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct net_pkt *pkt; int ret; diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index d4ebf2d62a2..befc8826e0c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -696,8 +696,12 @@ static void socket_reset_pollfd_events(void) } /* LwM2M main work loop */ -static void socket_loop(void) +static void socket_loop(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int i, rc; int64_t now, next; int64_t timeout, next_retransmit; @@ -1245,7 +1249,7 @@ static int lwm2m_engine_init(void) /* start sock receive thread */ engine_thread_id = k_thread_create(&engine_thread_data, &engine_thread_stack[0], - K_KERNEL_STACK_SIZEOF(engine_thread_stack), (k_thread_entry_t)socket_loop, + K_KERNEL_STACK_SIZEOF(engine_thread_stack), socket_loop, NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); k_thread_name_set(&engine_thread_data, "lwm2m-sock-recv"); LOG_DBG("LWM2M engine socket receive thread started"); From 24de37898635fb7df648e046eb051326854c22fe Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 10:02:36 +0200 Subject: [PATCH 2781/4498] portability: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- subsys/portability/cmsis_rtos_v1/cmsis_thread.c | 4 +++- subsys/portability/cmsis_rtos_v2/thread.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/portability/cmsis_rtos_v1/cmsis_thread.c b/subsys/portability/cmsis_rtos_v1/cmsis_thread.c index 72570f840b6..9887e560afb 100644 --- a/subsys/portability/cmsis_rtos_v1/cmsis_thread.c +++ b/subsys/portability/cmsis_rtos_v1/cmsis_thread.c @@ -29,6 +29,8 @@ static inline uint32_t cmsis_to_zephyr_priority(int32_t c_prio) static void zephyr_thread_wrapper(void *arg1, void *arg2, void *arg3) { + ARG_UNUSED(arg2); + void * (*fun_ptr)(void *) = arg3; fun_ptr(arg1); @@ -109,7 +111,7 @@ osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *arg) tid = k_thread_create(&cm_thread[instance], stk_ptr[instance], stacksz, - (k_thread_entry_t)zephyr_thread_wrapper, + zephyr_thread_wrapper, (void *)arg, NULL, thread_def->pthread, prio, 0, K_NO_WAIT); diff --git a/subsys/portability/cmsis_rtos_v2/thread.c b/subsys/portability/cmsis_rtos_v2/thread.c index 22bd693612a..f5e9cd67027 100644 --- a/subsys/portability/cmsis_rtos_v2/thread.c +++ b/subsys/portability/cmsis_rtos_v2/thread.c @@ -198,7 +198,7 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg, (void)k_thread_create(&tid->z_thread, stack, stack_size, - (k_thread_entry_t)zephyr_thread_wrapper, + zephyr_thread_wrapper, (void *)arg, tid, threadfunc, prio, 0, K_NO_WAIT); From c5b252d8f1a457ac8a64158879dde794cec1b3e2 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 10:02:55 +0200 Subject: [PATCH 2782/4498] testssuite: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- subsys/testsuite/ztest/src/ztest.c | 5 +++-- subsys/testsuite/ztest/src/ztest_new.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 12271e61eb9..d49a1ef9c11 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -113,6 +113,7 @@ static void cpu_hold(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + unsigned int key = arch_irq_lock(); uint32_t dt, start_ms = k_uptime_get_32(); @@ -159,7 +160,7 @@ void z_impl_z_test_1cpu_start(void) */ for (int i = 0; i < num_cpus - 1; i++) { k_thread_create(&cpuhold_threads[i], cpuhold_stacks[i], CPUHOLD_STACK_SZ, - (k_thread_entry_t)cpu_hold, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, + cpu_hold, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); if (IS_ENABLED(CONFIG_THREAD_NAME)) { snprintk(tname, CONFIG_THREAD_MAX_NAME_LEN, "cpuhold%02d", i); @@ -558,7 +559,7 @@ static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test get_start_time_cyc(); k_thread_create(&ztest_thread, ztest_thread_stack, K_THREAD_STACK_SIZEOF(ztest_thread_stack), - (k_thread_entry_t)test_cb, suite, test, data, + test_cb, suite, test, data, CONFIG_ZTEST_THREAD_PRIORITY, K_INHERIT_PERMS, K_FOREVER); diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index 12271e61eb9..d49a1ef9c11 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -113,6 +113,7 @@ static void cpu_hold(void *arg1, void *arg2, void *arg3) ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); + unsigned int key = arch_irq_lock(); uint32_t dt, start_ms = k_uptime_get_32(); @@ -159,7 +160,7 @@ void z_impl_z_test_1cpu_start(void) */ for (int i = 0; i < num_cpus - 1; i++) { k_thread_create(&cpuhold_threads[i], cpuhold_stacks[i], CPUHOLD_STACK_SZ, - (k_thread_entry_t)cpu_hold, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, + cpu_hold, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); if (IS_ENABLED(CONFIG_THREAD_NAME)) { snprintk(tname, CONFIG_THREAD_MAX_NAME_LEN, "cpuhold%02d", i); @@ -558,7 +559,7 @@ static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test get_start_time_cyc(); k_thread_create(&ztest_thread, ztest_thread_stack, K_THREAD_STACK_SIZEOF(ztest_thread_stack), - (k_thread_entry_t)test_cb, suite, test, data, + test_cb, suite, test, data, CONFIG_ZTEST_THREAD_PRIORITY, K_INHERIT_PERMS, K_FOREVER); From be8408cbac4da5b2dc5365cf750b29d4d26a17f1 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Wed, 4 Oct 2023 10:03:09 +0200 Subject: [PATCH 2783/4498] usb: fix thread function signatures Fix thread function signatures to avoid stack corruption on thread exit. Signed-off-by: Benedikt Schmidt --- subsys/usb/device/class/bluetooth.c | 16 ++++++++++++---- subsys/usb/device/class/bt_h4.c | 16 ++++++++++++---- subsys/usb/device/class/msc.c | 9 +++++---- subsys/usb/device/class/netusb/function_rndis.c | 8 ++++++-- subsys/usb/device_next/usbd_core.c | 8 ++++++-- subsys/usb/host/usbh_core.c | 8 ++++++-- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/subsys/usb/device/class/bluetooth.c b/subsys/usb/device/class/bluetooth.c index 776c787120f..63b85238f5a 100644 --- a/subsys/usb/device/class/bluetooth.c +++ b/subsys/usb/device/class/bluetooth.c @@ -122,8 +122,12 @@ static struct usb_ep_cfg_data bluetooth_ep_data[] = { }, }; -static void hci_tx_thread(void) +static void hci_tx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG("Start USB Bluetooth thread"); while (true) { @@ -174,8 +178,12 @@ static void hci_tx_thread(void) } } -static void hci_rx_thread(void) +static void hci_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { struct net_buf *buf; int err; @@ -467,14 +475,14 @@ static int bluetooth_init(void) k_thread_create(&rx_thread_data, rx_thread_stack, K_KERNEL_STACK_SIZEOF(rx_thread_stack), - (k_thread_entry_t)hci_rx_thread, NULL, NULL, NULL, + hci_rx_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_name_set(&rx_thread_data, "usb_bt_rx"); k_thread_create(&tx_thread_data, tx_thread_stack, K_KERNEL_STACK_SIZEOF(tx_thread_stack), - (k_thread_entry_t)hci_tx_thread, NULL, NULL, NULL, + hci_tx_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_name_set(&tx_thread_data, "usb_bt_tx"); diff --git a/subsys/usb/device/class/bt_h4.c b/subsys/usb/device/class/bt_h4.c index 7ef72b2759e..d4004a82ac8 100644 --- a/subsys/usb/device/class/bt_h4.c +++ b/subsys/usb/device/class/bt_h4.c @@ -113,8 +113,12 @@ static void bt_h4_read(uint8_t ep, int size, void *priv) USB_MAX_FS_BULK_MPS, USB_TRANS_READ, bt_h4_read, NULL); } -static void hci_tx_thread(void) +static void hci_tx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_DBG("Start USB Bluetooth thread"); while (true) { @@ -129,8 +133,12 @@ static void hci_tx_thread(void) } } -static void hci_rx_thread(void) +static void hci_rx_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + while (true) { struct net_buf *buf; @@ -235,14 +243,14 @@ static int bt_h4_init(void) k_thread_create(&rx_thread_data, rx_thread_stack, K_KERNEL_STACK_SIZEOF(rx_thread_stack), - (k_thread_entry_t)hci_rx_thread, NULL, NULL, NULL, + hci_rx_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_name_set(&rx_thread_data, "usb_bt_h4_rx"); k_thread_create(&tx_thread_data, tx_thread_stack, K_KERNEL_STACK_SIZEOF(tx_thread_stack), - (k_thread_entry_t)hci_tx_thread, NULL, NULL, NULL, + hci_tx_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_name_set(&tx_thread_data, "usb_bt_h4_tx"); diff --git a/subsys/usb/device/class/msc.c b/subsys/usb/device/class/msc.c index 37871ffdc31..1971c942af8 100644 --- a/subsys/usb/device/class/msc.c +++ b/subsys/usb/device/class/msc.c @@ -972,10 +972,11 @@ USBD_DEFINE_CFG_DATA(mass_storage_config) = { .endpoint = mass_ep_data }; -static void mass_thread_main(int arg1, int unused) +static void mass_thread_main(void *p1, void *p2, void *p3) { - ARG_UNUSED(unused); - ARG_UNUSED(arg1); + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); while (1) { k_sem_take(&disk_wait_sem, K_FOREVER); @@ -1057,7 +1058,7 @@ static int mass_storage_init(void) /* Start a thread to offload disk ops */ k_thread_create(&mass_thread_data, mass_thread_stack, CONFIG_MASS_STORAGE_STACK_SIZE, - (k_thread_entry_t)mass_thread_main, NULL, NULL, NULL, + mass_thread_main, NULL, NULL, NULL, DISK_THREAD_PRIO, 0, K_NO_WAIT); k_thread_name_set(&mass_thread_data, "usb_mass"); diff --git a/subsys/usb/device/class/netusb/function_rndis.c b/subsys/usb/device/class/netusb/function_rndis.c index c58f236f866..bbdfa7513b2 100644 --- a/subsys/usb/device/class/netusb/function_rndis.c +++ b/subsys/usb/device/class/netusb/function_rndis.c @@ -883,8 +883,12 @@ static int rndis_class_handler(struct usb_setup_packet *setup, int32_t *len, return -ENOTSUP; } -static void cmd_thread(void) +static void cmd_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + LOG_INF("Command thread started"); while (true) { @@ -1051,7 +1055,7 @@ static int rndis_init(void) k_thread_create(&cmd_thread_data, cmd_stack, K_KERNEL_STACK_SIZEOF(cmd_stack), - (k_thread_entry_t)cmd_thread, + cmd_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_name_set(&cmd_thread_data, "usb_rndis"); diff --git a/subsys/usb/device_next/usbd_core.c b/subsys/usb/device_next/usbd_core.c index e025397cc85..655f86cb4b2 100644 --- a/subsys/usb/device_next/usbd_core.c +++ b/subsys/usb/device_next/usbd_core.c @@ -163,8 +163,12 @@ static ALWAYS_INLINE int usbd_event_handler(struct usbd_contex *const uds_ctx, return ret; } -static void usbd_thread(void) +static void usbd_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct udc_event event; while (true) { @@ -226,7 +230,7 @@ static int usbd_pre_init(void) { k_thread_create(&usbd_thread_data, usbd_stack, K_KERNEL_STACK_SIZEOF(usbd_stack), - (k_thread_entry_t)usbd_thread, + usbd_thread, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index ac4976b6556..ea624d0305a 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -90,8 +90,12 @@ static ALWAYS_INLINE int usbh_event_handler(struct usbh_contex *const ctx, return ret; } -static void usbh_thread(const struct device *dev) +static void usbh_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct uhc_event event; while (true) { @@ -130,7 +134,7 @@ static int uhs_pre_init(void) { k_thread_create(&usbh_thread_data, usbh_stack, K_KERNEL_STACK_SIZEOF(usbh_stack), - (k_thread_entry_t)usbh_thread, + usbh_thread, NULL, NULL, NULL, K_PRIO_COOP(9), 0, K_NO_WAIT); From cf1fdc3ea82b21154ec418fb9ad56c0c06e8fe6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Sun, 10 Sep 2023 21:34:03 +0200 Subject: [PATCH 2784/4498] doc: samples: Use definition list for code samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using an UL with "manually" formatted text was probably an oversight. Show related samples as a "definition list", with sample name as the "term" and the description as the "definition". Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 19168df7a9e..bce9436ba34 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -157,9 +157,11 @@ def run(self, **kwargs: Any) -> None: admonition["collapsible"] = "" # used by sphinx-immaterial theme admonition["classes"].append("related-code-samples") admonition["classes"].append("dropdown") # used by sphinx-togglebutton extension - sample_ul = nodes.bullet_list() + sample_dl = nodes.definition_list() + for code_sample in sorted(code_samples, key=lambda x: x["name"]): - sample_para = nodes.paragraph() + term = nodes.term() + sample_xref = addnodes.pending_xref( "", refdomain="zephyr", @@ -168,13 +170,14 @@ def run(self, **kwargs: Any) -> None: refwarn=True, ) sample_xref += nodes.inline(text=code_sample["name"]) - sample_para += sample_xref - sample_para += nodes.inline(text=" - ") - sample_para += nodes.inline(text=code_sample["description"].astext()) - sample_li = nodes.list_item() - sample_li += sample_para - sample_ul += sample_li - admonition += sample_ul + term += sample_xref + definition = nodes.definition() + definition += nodes.paragraph(text=code_sample["description"].astext()) + sample_dli = nodes.definition_list_item() + sample_dli += term + sample_dli += definition + sample_dl += sample_dli + admonition += sample_dl # replace node with the newly created admonition node.replace_self(admonition) From 26d7c613700dfb6624e9eed264682ce88be0bba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 27 Oct 2023 11:03:54 +0200 Subject: [PATCH 2785/4498] doc: samples: Show related code samples contents by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add required class so that sphinx-togglebutton admonition is expanded by default. Also remove sphinx-immaterial code that should not be there. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/domain.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index bce9436ba34..8c395142818 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -154,9 +154,10 @@ def run(self, **kwargs: Any) -> None: if len(code_samples) > 0: admonition = nodes.admonition() admonition += nodes.title(text="Related code samples") - admonition["collapsible"] = "" # used by sphinx-immaterial theme admonition["classes"].append("related-code-samples") admonition["classes"].append("dropdown") # used by sphinx-togglebutton extension + admonition["classes"].append("toggle-shown") # show the content by default + sample_dl = nodes.definition_list() for code_sample in sorted(code_samples, key=lambda x: x["name"]): From 3c7968172eb69e9936919e6e36d758be08de634b Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Wed, 25 Oct 2023 14:29:13 +0200 Subject: [PATCH 2786/4498] scripts: tests: twister: Add error testing Errors did not have their dedicated test file. This change adds it to the repo and checks the only non-def statement there. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_errors.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 scripts/tests/twister/test_errors.py diff --git a/scripts/tests/twister/test_errors.py b/scripts/tests/twister/test_errors.py new file mode 100644 index 00000000000..426258f4cb8 --- /dev/null +++ b/scripts/tests/twister/test_errors.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for the error classes +""" + +import os +import pytest + +from pathlib import Path +from twisterlib.error import ConfigurationError + +def test_configurationerror(): + cfile = Path('some') / 'path' + message = 'dummy message' + + expected_err = f'{os.path.join("some", "path")}: dummy message' + + with pytest.raises(ConfigurationError, match=expected_err): + raise ConfigurationError(cfile, message) From 471cff50e857c77273b2ea3fcc7dda9599135915 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Thu, 26 Oct 2023 17:14:59 +0200 Subject: [PATCH 2787/4498] scripts: tests: twister: Jobserver tests Jobserver module was not covered by unit tests. This change brings its coverage to 100%. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_jobserver.py | 457 ++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 scripts/tests/twister/test_jobserver.py diff --git a/scripts/tests/twister/test_jobserver.py b/scripts/tests/twister/test_jobserver.py new file mode 100644 index 00000000000..c97e9320447 --- /dev/null +++ b/scripts/tests/twister/test_jobserver.py @@ -0,0 +1,457 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for jobserver.py classes' methods +""" + +import functools +import mock +import os +import pytest +import sys + +from contextlib import nullcontext +from errno import ENOENT +from fcntl import F_GETFL +from selectors import EVENT_READ + +from twisterlib.jobserver import ( + JobHandle, + JobClient, + GNUMakeJobClient, + GNUMakeJobServer +) + + +def test_jobhandle(capfd): + def f(a, b, c=None, d=None): + print(f'{a}, {b}, {c}, {d}') + + def exiter(): + with JobHandle(f, 1, 2, c='three', d=4): + return + + exiter() + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert '1, 2, three, 4' in out + + +def test_jobclient_get_job(): + jc = JobClient() + + job = jc.get_job() + + assert isinstance(job, JobHandle) + assert job.release_func is None + + +def test_jobclient_env(): + env = JobClient.env() + + assert env == {} + + +def test_jobclient_pass_fds(): + fds = JobClient.pass_fds() + + assert fds == [] + + +TESTDATA_1 = [ + ({}, {'env': {'k': 'v'}, 'pass_fds': []}), + ({'env': {}, 'pass_fds': ['fd']}, {'env': {}, 'pass_fds': ['fd']}), +] + +@pytest.mark.parametrize( + 'kwargs, expected_kwargs', + TESTDATA_1, + ids=['no values', 'preexisting values'] +) +def test_jobclient_popen(kwargs, expected_kwargs): + jc = JobClient() + + argv = ['cmd', 'and', 'some', 'args'] + proc_mock = mock.Mock() + popen_mock = mock.Mock(return_value=proc_mock) + env_mock = {'k': 'v'} + + with mock.patch('subprocess.Popen', popen_mock), \ + mock.patch('os.environ', env_mock): + proc = jc.popen(argv, **kwargs) + + popen_mock.assert_called_once_with(argv, **expected_kwargs) + assert proc == proc_mock + + +TESTDATA_2 = [ + (False, 0), + (True, 0), + (False, 4), + (True, 16), +] + + +@pytest.mark.parametrize( + 'inheritable, internal_jobs', + TESTDATA_2, + ids=['no inheritable, no internal', 'inheritable, no internal', + 'no inheritable, internal', 'inheritable, internal'] +) +def test_gnumakejobclient_dunders(inheritable, internal_jobs): + inherit_read_fd = mock.Mock() + inherit_write_fd = mock.Mock() + inheritable_pipe = (inherit_read_fd, inherit_write_fd) if inheritable else \ + None + + internal_read_fd = mock.Mock() + internal_write_fd = mock.Mock() + + def mock_pipe(): + return (internal_read_fd, internal_write_fd) + + close_mock = mock.Mock() + write_mock = mock.Mock() + set_blocking_mock = mock.Mock() + selector_mock = mock.Mock() + + def deleter(): + jobs = mock.Mock() + makeflags = mock.Mock() + + gmjc = GNUMakeJobClient( + inheritable_pipe, + jobs, + internal_jobs=internal_jobs, + makeflags=makeflags + ) + + assert gmjc.jobs == jobs + if internal_jobs: + write_mock.assert_called_once_with(internal_write_fd, + b'+' * internal_jobs) + set_blocking_mock.assert_any_call(internal_read_fd, False) + selector_mock().register.assert_any_call(internal_read_fd, + EVENT_READ, + internal_write_fd) + if inheritable: + set_blocking_mock.assert_any_call(inherit_read_fd, False) + selector_mock().register.assert_any_call(inherit_read_fd, + EVENT_READ, + inherit_write_fd) + + with mock.patch('os.close', close_mock), \ + mock.patch('os.write', write_mock), \ + mock.patch('os.set_blocking', set_blocking_mock), \ + mock.patch('os.pipe', mock_pipe), \ + mock.patch('selectors.DefaultSelector', selector_mock): + deleter() + + if internal_jobs: + close_mock.assert_any_call(internal_read_fd) + close_mock.assert_any_call(internal_write_fd) + if inheritable: + close_mock.assert_any_call(inherit_read_fd) + close_mock.assert_any_call(inherit_write_fd) + + +TESTDATA_3 = [ + ( + {'MAKEFLAGS': '-j1'}, + 0, + (False, False), + ['Running in sequential mode (-j1)'], + None, + [None, 1], + {'internal_jobs': 1, 'makeflags': '-j1'} + ), + ( + {'MAKEFLAGS': 'n--jobserver-auth=0,1'}, + 1, + (True, True), + [ + '-jN forced on command line; ignoring GNU make jobserver', + 'MAKEFLAGS contained dry-run flag' + ], + 0, + None, + None + ), + ( + {'MAKEFLAGS': '--jobserver-auth=0,1'}, + 0, + (True, True), + ['using GNU make jobserver'], + None, + [[0, 1], 0], + {'internal_jobs': 1, 'makeflags': '--jobserver-auth=0,1'} + ), + ( + {'MAKEFLAGS': '--jobserver-auth=123,321'}, + 0, + (False, False), + ['No file descriptors; ignoring GNU make jobserver'], + None, + [None, 0], + {'internal_jobs': 1, 'makeflags': '--jobserver-auth=123,321'} + ), + ( + {'MAKEFLAGS': '--jobserver-auth=0,1'}, + 0, + (False, True), + [f'FD 0 is not readable (flags=2); ignoring GNU make jobserver'], + None, + [None, 0], + {'internal_jobs': 1, 'makeflags': '--jobserver-auth=0,1'} + ), + ( + {'MAKEFLAGS': '--jobserver-auth=0,1'}, + 0, + (True, False), + [f'FD 1 is not writable (flags=2); ignoring GNU make jobserver'], + None, + [None, 0], + {'internal_jobs': 1, 'makeflags': '--jobserver-auth=0,1'} + ), + (None, 0, (False, False), [], None, None, None), +] + +@pytest.mark.parametrize( + 'env, jobs, fcntl_ok_per_pipe, expected_logs,' \ + ' exit_code, expected_args, expected_kwargs', + TESTDATA_3, + ids=['env, no jobserver-auth', 'env, jobs, dry run', 'env, no jobs', + 'env, no jobs, oserror', 'env, no jobs, wrong read pipe', + 'env, no jobs, wrong write pipe', 'environ, no makeflags'] +) +def test_gnumakejobclient_from_environ( + caplog, + env, + jobs, + fcntl_ok_per_pipe, + expected_logs, + exit_code, + expected_args, + expected_kwargs +): + def mock_fcntl(fd, flag): + if flag == F_GETFL: + if fd == 0: + if fcntl_ok_per_pipe[0]: + return os.O_RDONLY + else: + return 2 + elif fd == 1: + if fcntl_ok_per_pipe[1]: + return os.O_WRONLY + else: + return 2 + raise OSError(ENOENT, 'dummy error') + + gmjc_init_mock = mock.Mock(return_value=None) + + with mock.patch('fcntl.fcntl', mock_fcntl), \ + mock.patch('os.close', mock.Mock()), \ + mock.patch('twisterlib.jobserver.GNUMakeJobClient.__init__', + gmjc_init_mock), \ + pytest.raises(SystemExit) if exit_code is not None else \ + nullcontext() as se: + gmjc = GNUMakeJobClient.from_environ(env=env, jobs=jobs) + + # As patching __del__ is hard to do, we'll instead + # cover possible exceptions and mock os calls + if gmjc: + gmjc._inheritable_pipe = getattr(gmjc, '_inheritable_pipe', None) + if gmjc: + gmjc._internal_pipe = getattr(gmjc, '_internal_pipe', None) + + assert all([log in caplog.text for log in expected_logs]) + + if se: + assert str(se.value) == str(exit_code) + return + + if expected_args is None and expected_kwargs is None: + assert gmjc is None + else: + gmjc_init_mock.assert_called_once_with(*expected_args, + **expected_kwargs) + + +def test_gnumakejobclient_get_job(): + inherit_read_fd = mock.Mock() + inherit_write_fd = mock.Mock() + inheritable_pipe = (inherit_read_fd, inherit_write_fd) + + internal_read_fd = mock.Mock() + internal_write_fd = mock.Mock() + + def mock_pipe(): + return (internal_read_fd, internal_write_fd) + + selected = [[mock.Mock(fd=0, data=1)], [mock.Mock(fd=1, data=0)]] + + def mock_select(): + nonlocal selected + return selected + + def mock_read(fd, length): + nonlocal selected + if fd == 0: + selected = selected[1:] + raise BlockingIOError + return b'?' * length + + close_mock = mock.Mock() + write_mock = mock.Mock() + set_blocking_mock = mock.Mock() + selector_mock = mock.Mock() + selector_mock().select = mock.Mock(side_effect=mock_select) + + def deleter(): + jobs = mock.Mock() + + gmjc = GNUMakeJobClient( + inheritable_pipe, + jobs + ) + + with mock.patch('os.read', side_effect=mock_read): + job = gmjc.get_job() + with job: + expected_func = functools.partial(os.write, 0, b'?') + + assert job.release_func.func == expected_func.func + assert job.release_func.args == expected_func.args + assert job.release_func.keywords == expected_func.keywords + + with mock.patch('os.close', close_mock), \ + mock.patch('os.write', write_mock), \ + mock.patch('os.set_blocking', set_blocking_mock), \ + mock.patch('os.pipe', mock_pipe), \ + mock.patch('selectors.DefaultSelector', selector_mock): + deleter() + + write_mock.assert_any_call(0, b'?') + + +TESTDATA_4 = [ + ('dummy makeflags', mock.ANY, mock.ANY, {'MAKEFLAGS': 'dummy makeflags'}), + (None, 0, False, {'MAKEFLAGS': ''}), + (None, 1, True, {'MAKEFLAGS': ' -j1'}), + (None, 2, True, {'MAKEFLAGS': ' -j2 --jobserver-auth=0,1'}), + (None, 0, True, {'MAKEFLAGS': ' --jobserver-auth=0,1'}), +] + +@pytest.mark.parametrize( + 'makeflags, jobs, use_inheritable_pipe, expected_makeflags', + TESTDATA_4, + ids=['preexisting makeflags', 'no jobs, no pipe', 'one job', + ' multiple jobs', 'no jobs'] +) +def test_gnumakejobclient_env( + makeflags, + jobs, + use_inheritable_pipe, + expected_makeflags +): + inheritable_pipe = (0, 1) if use_inheritable_pipe else None + + selector_mock = mock.Mock() + + env = None + + def deleter(): + gmjc = GNUMakeJobClient(None, None) + gmjc.jobs = jobs + gmjc._makeflags = makeflags + gmjc._inheritable_pipe = inheritable_pipe + + nonlocal env + env = gmjc.env() + + with mock.patch.object(GNUMakeJobClient, '__del__', mock.Mock()), \ + mock.patch('selectors.DefaultSelector', selector_mock): + deleter() + + assert env == expected_makeflags + + +TESTDATA_5 = [ + (2, False, []), + (1, True, []), + (2, True, (0, 1)), + (0, True, (0, 1)), +] + +@pytest.mark.parametrize( + 'jobs, use_inheritable_pipe, expected_fds', + TESTDATA_5, + ids=['no pipe', 'one job', ' multiple jobs', 'no jobs'] +) +def test_gnumakejobclient_pass_fds(jobs, use_inheritable_pipe, expected_fds): + inheritable_pipe = (0, 1) if use_inheritable_pipe else None + + selector_mock = mock.Mock() + + fds = None + + def deleter(): + gmjc = GNUMakeJobClient(None, None) + gmjc.jobs = jobs + gmjc._inheritable_pipe = inheritable_pipe + + nonlocal fds + fds = gmjc.pass_fds() + + with mock.patch('twisterlib.jobserver.GNUMakeJobClient.__del__', + mock.Mock()), \ + mock.patch('selectors.DefaultSelector', selector_mock): + deleter() + + assert fds == expected_fds + + +TESTDATA_6 = [ + (0, 8), + (32, 16), + (4, 4), +] + +@pytest.mark.parametrize( + 'jobs, expected_jobs', + TESTDATA_6, + ids=['no jobs', 'too many jobs', 'valid jobs'] +) +def test_gnumakejobserver(jobs, expected_jobs): + def mock_init(self, p, j): + self._inheritable_pipe = p + self._internal_pipe = None + self.jobs = j + + pipe = (0, 1) + cpu_count = 8 + pipe_buf = 16 + + selector_mock = mock.Mock() + write_mock = mock.Mock() + del_mock = mock.Mock() + + def deleter(): + GNUMakeJobServer(jobs=jobs) + + with mock.patch.object(GNUMakeJobClient, '__del__', del_mock), \ + mock.patch.object(GNUMakeJobClient, '__init__', mock_init), \ + mock.patch('os.pipe', return_value=pipe), \ + mock.patch('os.write', write_mock), \ + mock.patch('multiprocessing.cpu_count', return_value=cpu_count), \ + mock.patch('select.PIPE_BUF', pipe_buf), \ + mock.patch('selectors.DefaultSelector', selector_mock): + deleter() + + write_mock.assert_called_once_with(pipe[1], b'+' * expected_jobs) From a36c016dff2ce6a56bbe1684d032091864de66d7 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 26 Oct 2023 22:28:11 +0000 Subject: [PATCH 2788/4498] kernel: mmu: Fix possible null de-reference virt_page_phys_get can be called with phy parameter NULL when the intention is just checking if a virtual address is mapped. This function is generally overwritten by a an arch API that checks if phys is null before using it but this default implementation doesn't. Signed-off-by: Flavio Ceolin --- kernel/mmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/mmu.c b/kernel/mmu.c index 8f6a811bc4f..8c742bc36ae 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -469,7 +469,9 @@ static int virt_to_page_frame(void *virt, uintptr_t *phys) if (z_page_frame_is_mapped(pf)) { if (virt == pf->addr) { ret = 0; - *phys = z_page_frame_to_phys(pf); + if (phys != NULL) { + *phys = z_page_frame_to_phys(pf); + } break; } } From c243991000be2711854bf7d66c91f5bf160c0078 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 24 Oct 2023 14:04:16 +0300 Subject: [PATCH 2789/4498] tests: work_queue: Change TC_PRINT to LOG_DBG There are many TC_PRINT()'s in the work_queue test and it make sense to change them to LOG_DBG() which are disabled by default. Other issue is that some of TC_PRINT() are inside works for which execution time is measured. Signed-off-by: Andrei Emeltchenko --- tests/kernel/workq/work_queue/src/main.c | 150 ++++++++++++----------- 1 file changed, 76 insertions(+), 74 deletions(-) diff --git a/tests/kernel/workq/work_queue/src/main.c b/tests/kernel/workq/work_queue/src/main.c index 5d653c728c0..b14d2878717 100644 --- a/tests/kernel/workq/work_queue/src/main.c +++ b/tests/kernel/workq/work_queue/src/main.c @@ -20,6 +20,9 @@ #include #include +#include +LOG_MODULE_REGISTER(test); + #define NUM_TEST_ITEMS 6 /* Each work item takes 100ms by default. */ @@ -93,7 +96,7 @@ static void work_handler(struct k_work *work) struct delayed_test_item *ti = CONTAINER_OF(dwork, struct delayed_test_item, work); - TC_PRINT(" - Running test item %d\n", ti->key); + LOG_DBG(" - Running test item %d", ti->key); k_msleep(WORK_ITEM_WAIT); results[num_results++] = ti->key; @@ -136,7 +139,7 @@ static void coop_work_main(void *p1, void *p2, void *p3) k_msleep(SUBMIT_WAIT / 2); for (i = 1; i < NUM_TEST_ITEMS; i += 2) { - TC_PRINT(" - Submitting work %d from coop thread\n", i + 1); + LOG_DBG(" - Submitting work %d from coop thread", i + 1); k_work_schedule(&delayed_tests[i].work, K_NO_WAIT); k_msleep(SUBMIT_WAIT); } @@ -155,7 +158,7 @@ static void delayed_test_items_submit(void) NULL, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); for (i = 0; i < NUM_TEST_ITEMS; i += 2) { - TC_PRINT(" - Submitting work %d from preempt thread\n", i + 1); + LOG_DBG(" - Submitting work %d from preempt thread", i + 1); k_work_schedule(&delayed_tests[i].work, K_NO_WAIT); k_msleep(SUBMIT_WAIT); } @@ -187,13 +190,13 @@ static void check_results(int num_tests) */ static void test_sequence(void) { - TC_PRINT(" - Initializing test items\n"); + LOG_DBG(" - Initializing test items"); delayed_test_items_init(); - TC_PRINT(" - Submitting test items\n"); + LOG_DBG(" - Submitting test items"); delayed_test_items_submit(); - TC_PRINT(" - Waiting for work to finish\n"); + LOG_DBG(" - Waiting for work to finish"); k_msleep(CHECK_WAIT); check_results(NUM_TEST_ITEMS); @@ -214,7 +217,7 @@ static void resubmit_work_handler(struct k_work *work) if (ti->key < NUM_TEST_ITEMS) { ti->key++; - TC_PRINT(" - Resubmitting work\n"); + LOG_DBG(" - Resubmitting work"); k_work_submit(work); } } @@ -227,18 +230,18 @@ static void resubmit_work_handler(struct k_work *work) */ ZTEST(workqueue_triggered, test_resubmit) { - TC_PRINT("Starting resubmit test\n"); + LOG_DBG("Starting resubmit test"); delayed_tests[0].key = 1; k_work_init_delayable(&delayed_tests[0].work, resubmit_work_handler); - TC_PRINT(" - Submitting work\n"); + LOG_DBG(" - Submitting work"); k_work_schedule(&delayed_tests[0].work, K_NO_WAIT); - TC_PRINT(" - Waiting for work to finish\n"); + LOG_DBG(" - Waiting for work to finish"); k_msleep(CHECK_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -249,7 +252,7 @@ static void delayed_work_handler(struct k_work *work) struct delayed_test_item *ti = CONTAINER_OF(dwork, struct delayed_test_item, work); - TC_PRINT(" - Running delayed test item %d\n", ti->key); + LOG_DBG(" - Running delayed test item %d", ti->key); results[num_results++] = ti->key; } @@ -284,8 +287,8 @@ static void coop_delayed_work_main(void *p1, void *p2, void *p3) k_msleep(SUBMIT_WAIT / 2); for (i = 1; i < NUM_TEST_ITEMS; i += 2) { - TC_PRINT(" - Submitting delayed work %d from" - " coop thread\n", i + 1); + LOG_DBG(" - Submitting delayed work %d from" + " coop thread", i + 1); k_work_schedule(&delayed_tests[i].work, K_MSEC((i + 1) * WORK_ITEM_WAIT)); } @@ -307,8 +310,8 @@ static void test_delayed_submit(void) NULL, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT); for (i = 0; i < NUM_TEST_ITEMS; i += 2) { - TC_PRINT(" - Submitting delayed work %d from" - " preempt thread\n", i + 1); + LOG_DBG(" - Submitting delayed work %d from" + " preempt thread", i + 1); zassert_true(k_work_reschedule(&delayed_tests[i].work, K_MSEC((i + 1) * WORK_ITEM_WAIT)) >= 0, NULL); } @@ -323,7 +326,7 @@ static void coop_delayed_work_cancel_main(void *p1, void *p2, void *p3) k_work_schedule(&delayed_tests[1].work, K_MSEC(WORK_ITEM_WAIT)); - TC_PRINT(" - Cancel delayed work from coop thread\n"); + LOG_DBG(" - Cancel delayed work from coop thread"); k_work_cancel_delayable(&delayed_tests[1].work); } @@ -337,52 +340,52 @@ static void coop_delayed_work_cancel_main(void *p1, void *p2, void *p3) */ ZTEST(workqueue_delayed, test_delayed_cancel) { - TC_PRINT("Starting delayed cancel test\n"); + LOG_DBG("Starting delayed cancel test"); k_work_schedule(&delayed_tests[0].work, K_MSEC(WORK_ITEM_WAIT)); - TC_PRINT(" - Cancel delayed work from preempt thread\n"); + LOG_DBG(" - Cancel delayed work from preempt thread"); k_work_cancel_delayable(&delayed_tests[0].work); k_thread_create(&co_op_data, co_op_stack, STACK_SIZE, coop_delayed_work_cancel_main, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT); - TC_PRINT(" - Waiting for work to finish\n"); + LOG_DBG(" - Waiting for work to finish"); k_msleep(WORK_ITEM_WAIT_ALIGNED); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(0); reset_results(); } ZTEST(workqueue_delayed, test_delayed_pending) { - TC_PRINT("Starting delayed pending test\n"); + LOG_DBG("Starting delayed pending test"); k_work_init_delayable(&delayed_tests[0].work, delayed_work_handler); zassert_false(k_work_delayable_is_pending(&delayed_tests[0].work)); - TC_PRINT(" - Check pending delayed work when in workqueue\n"); + LOG_DBG(" - Check pending delayed work when in workqueue"); k_work_schedule(&delayed_tests[0].work, K_NO_WAIT); zassert_true(k_work_delayable_is_pending(&delayed_tests[0].work)); k_msleep(1); zassert_false(k_work_delayable_is_pending(&delayed_tests[0].work)); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(1); reset_results(); - TC_PRINT(" - Check pending delayed work with timeout\n"); + LOG_DBG(" - Check pending delayed work with timeout"); k_work_schedule(&delayed_tests[0].work, K_MSEC(WORK_ITEM_WAIT)); zassert_true(k_work_delayable_is_pending(&delayed_tests[0].work)); k_msleep(WORK_ITEM_WAIT_ALIGNED); zassert_false(k_work_delayable_is_pending(&delayed_tests[0].work)); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(1); reset_results(); } @@ -396,18 +399,18 @@ ZTEST(workqueue_delayed, test_delayed_pending) */ ZTEST(workqueue_delayed, test_delayed) { - TC_PRINT("Starting delayed test\n"); + LOG_DBG("Starting delayed test"); - TC_PRINT(" - Initializing delayed test items\n"); + LOG_DBG(" - Initializing delayed test items"); test_delayed_init(); - TC_PRINT(" - Submitting delayed test items\n"); + LOG_DBG(" - Submitting delayed test items"); test_delayed_submit(); - TC_PRINT(" - Waiting for delayed work to finish\n"); + LOG_DBG(" - Waiting for delayed work to finish"); k_msleep(CHECK_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -418,7 +421,7 @@ static void triggered_work_handler(struct k_work *work) struct triggered_test_item *ti = CONTAINER_OF(pwork, struct triggered_test_item, work); - TC_PRINT(" - Running triggered test item %d\n", ti->key); + LOG_DBG(" - Running triggered test item %d", ti->key); zassert_equal(ti->work.poll_result, expected_poll_result, "res %d expect %d", ti->work.poll_result, expected_poll_result); @@ -462,7 +465,7 @@ static void test_triggered_submit(k_timeout_t timeout) int i; for (i = 0; i < NUM_TEST_ITEMS; i++) { - TC_PRINT(" - Submitting triggered work %d\n", i + 1); + LOG_DBG(" - Submitting triggered work %d", i + 1); zassert_true(k_work_poll_submit(&triggered_tests[i].work, &triggered_tests[i].event, 1, timeout) == 0, NULL); @@ -479,7 +482,7 @@ static void test_triggered_trigger(void) int i; for (i = 0; i < NUM_TEST_ITEMS; i++) { - TC_PRINT(" - Triggering work %d\n", i + 1); + LOG_DBG(" - Triggering work %d", i + 1); zassert_true(k_poll_signal_raise(&triggered_tests[i].signal, 1) == 0, NULL); } @@ -494,24 +497,24 @@ static void test_triggered_trigger(void) */ ZTEST(workqueue_triggered, test_triggered) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_FOREVER); - TC_PRINT(" - Triggering test items execution\n"); + LOG_DBG(" - Triggering test items execution"); test_triggered_trigger(); /* Items should be executed when we will be sleeping. */ k_msleep(WORK_ITEM_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -525,24 +528,24 @@ ZTEST(workqueue_triggered, test_triggered) */ ZTEST(workqueue_triggered, test_already_triggered) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Triggering test items execution\n"); + LOG_DBG(" - Triggering test items execution"); test_triggered_trigger(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_FOREVER); /* Items should be executed when we will be sleeping. */ k_msleep(WORK_ITEM_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -557,7 +560,7 @@ static void triggered_resubmit_work_handler(struct k_work *work) if (ti->key < NUM_TEST_ITEMS) { ti->key++; - TC_PRINT(" - Resubmitting triggered work\n"); + LOG_DBG(" - Resubmitting triggered work"); k_poll_signal_reset(&triggered_tests[0].signal); zassert_true(k_work_poll_submit(&triggered_tests[0].work, @@ -577,7 +580,7 @@ ZTEST(workqueue_triggered, test_triggered_resubmit) { int i; - TC_PRINT("Starting triggered resubmit test\n"); + LOG_DBG("Starting triggered resubmit test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; @@ -592,20 +595,19 @@ ZTEST(workqueue_triggered, test_triggered_resubmit) K_POLL_MODE_NOTIFY_ONLY, &triggered_tests[0].signal); - TC_PRINT(" - Submitting triggered work\n"); + LOG_DBG(" - Submitting triggered work"); zassert_true(k_work_poll_submit(&triggered_tests[0].work, &triggered_tests[0].event, 1, K_FOREVER) == 0, NULL); for (i = 0; i < NUM_TEST_ITEMS; i++) { - TC_PRINT(" - Triggering test item execution (iteration: %d)\n", - i + 1); + LOG_DBG(" - Triggering test item execution (iteration: %d)", i + 1); zassert_true(k_poll_signal_raise(&triggered_tests[0].signal, 1) == 0, NULL); k_msleep(WORK_ITEM_WAIT); } - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -619,24 +621,24 @@ ZTEST(workqueue_triggered, test_triggered_resubmit) */ ZTEST(workqueue_triggered, test_triggered_no_wait) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Triggering test items execution\n"); + LOG_DBG(" - Triggering test items execution"); test_triggered_trigger(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_NO_WAIT); /* Items should be executed when we will be sleeping. */ k_msleep(WORK_ITEM_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -650,21 +652,21 @@ ZTEST(workqueue_triggered, test_triggered_no_wait) */ ZTEST(workqueue_triggered, test_triggered_no_wait_expired) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are not triggered, they should be marked as expired. */ expected_poll_result = -EAGAIN; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_NO_WAIT); /* Items should be executed when we will be sleeping. */ k_msleep(WORK_ITEM_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -678,24 +680,24 @@ ZTEST(workqueue_triggered, test_triggered_no_wait_expired) */ ZTEST(workqueue_triggered, test_triggered_wait) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Triggering test items execution\n"); + LOG_DBG(" - Triggering test items execution"); test_triggered_trigger(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_MSEC(2 * SUBMIT_WAIT)); /* Items should be executed when we will be sleeping. */ k_msleep(SUBMIT_WAIT); - TC_PRINT(" - Checking results\n"); + LOG_DBG(" - Checking results"); check_results(NUM_TEST_ITEMS); reset_results(); } @@ -709,25 +711,25 @@ ZTEST(workqueue_triggered, test_triggered_wait) */ ZTEST(workqueue_triggered, test_triggered_wait_expired) { - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are not triggered, they should time out. */ expected_poll_result = -EAGAIN; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); - TC_PRINT(" - Submitting triggered test items\n"); + LOG_DBG(" - Submitting triggered test items"); test_triggered_submit(K_MSEC(2 * SUBMIT_WAIT)); /* Items should not be executed when we will be sleeping here. */ k_msleep(SUBMIT_WAIT); - TC_PRINT(" - Checking results (before timeout)\n"); + LOG_DBG(" - Checking results (before timeout)"); check_results(0); /* Items should be executed when we will be sleeping here. */ k_msleep(SUBMIT_WAIT * 2); - TC_PRINT(" - Checking results (after timeout)\n"); + LOG_DBG(" - Checking results (after timeout)"); check_results(NUM_TEST_ITEMS); reset_results(); @@ -799,12 +801,12 @@ static void test_triggered_from_msgq_start(void) */ ZTEST(workqueue_triggered, test_triggered_from_msgq) { - TC_PRINT("Starting triggered from msgq test\n"); + LOG_DBG("Starting triggered from msgq test"); - TC_PRINT(" - Initializing kernel objects\n"); + LOG_DBG(" - Initializing kernel objects"); test_triggered_from_msgq_init(); - TC_PRINT(" - Starting the thread\n"); + LOG_DBG(" - Starting the thread"); test_triggered_from_msgq_start(); reset_results(); @@ -843,12 +845,12 @@ ZTEST(workqueue_triggered, test_triggered_cancel) { int ret; - TC_PRINT("Starting triggered test\n"); + LOG_DBG("Starting triggered test"); /* As work items are triggered, they should indicate an event. */ expected_poll_result = 0; - TC_PRINT(" - Initializing triggered test items\n"); + LOG_DBG(" - Initializing triggered test items"); test_triggered_init(); test_triggered_submit(K_FOREVER); From a33fff38ae1fb02129422cf0fe91690455f857d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 30 Oct 2023 15:19:40 +0100 Subject: [PATCH 2790/4498] tests: logging: log_benchmark: Fix integration platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userspace test was using native_posix which does not support userspace. Change to qemu_x86. Signed-off-by: Krzysztof Chruściński --- tests/subsys/logging/log_benchmark/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/logging/log_benchmark/testcase.yaml b/tests/subsys/logging/log_benchmark/testcase.yaml index bbb2a66826f..b530895ba54 100644 --- a/tests/subsys/logging/log_benchmark/testcase.yaml +++ b/tests/subsys/logging/log_benchmark/testcase.yaml @@ -18,7 +18,7 @@ tests: logging.benchmark_user: integration_platforms: - - native_posix + - qemu_x86 tags: logging platform_allow: - qemu_x86 From b1c207b2573cfb184c3476136f840476160b3156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 30 Oct 2023 15:20:35 +0100 Subject: [PATCH 2791/4498] logging: Use optimization for simple messages only in kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optimized version of logging for simple messages can work only in kernel space. Do not use it in user space. Signed-off-by: Krzysztof Chruściński --- include/zephyr/logging/log_msg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index 432442f0429..c04b00cdd98 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -532,7 +532,7 @@ do { \ UTIL_AND(UTIL_NOT(_domain_id), UTIL_NOT(_cstr_cnt))), \ ( \ bool can_simple = LOG_MSG_SIMPLE_CHECK(__VA_ARGS__); \ - if (can_simple && ((_dlen) == 0)) { \ + if (can_simple && ((_dlen) == 0) && !k_is_user_context()) { \ LOG_MSG_DBG("create fast message\n");\ Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, \ Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \ From 3314b8e0c3fd8c8d717b5b718fb86acc7d1c9022 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Mon, 30 Oct 2023 15:24:09 +0100 Subject: [PATCH 2792/4498] twister: bugfix: Fix infinite loop in test_plan.py script Commit 72f416f382f061199900096f50315608b75aae8b added a horizontal scan for .yaml files when a modification was made in "common" folder. If yamls were found in such way, the loop ended. However, the implementation didn't address what happens if such yamls are not found. This made the script going into an infinite loop. If yamls are not found next to "common", the script should proceed as before, i.e. go to the directory above an start looking there. Signed-off-by: Maciej Perkowski --- scripts/ci/test_plan.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index e1fc51a59d1..a2ba406d8ce 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -284,6 +284,8 @@ def find_tests(self): tests.add(os.path.dirname(yaml)) self.resolved_files.append(f) scope_found = True + else: + d = os.path.dirname(d) else: d = os.path.dirname(d) From ed92612689fa52689e84bd40718328d9205d4d72 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 1 Aug 2023 18:49:30 +0200 Subject: [PATCH 2793/4498] data: Add navigation utils header This commit adds the initial navigation data type and tools which will lay the foundation to share and process navigation data between the application and navigation systems like GNSS and similar triangulation technologies. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/data/navigation.h | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 include/zephyr/data/navigation.h diff --git a/include/zephyr/data/navigation.h b/include/zephyr/data/navigation.h new file mode 100644 index 00000000000..0759df984ea --- /dev/null +++ b/include/zephyr/data/navigation.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DATA_NAVIGATION_H_ +#define ZEPHYR_INCLUDE_DATA_NAVIGATION_H_ + +#include + +/** + * @brief Navigation utilities + * @defgroup navigation Navigation + * @ingroup utilities + * @{ + */ + +/** + * @brief Navigation data structure + * + * @details The structure describes the momentary navigation details of a + * point relative to a sphere (commonly Earth) + */ +struct navigation_data { + /** Latitudal position in nanodegrees (0 to +-180E9) */ + int64_t latitude; + /** Longitudal position in nanodegrees (0 to +-180E9) */ + int64_t longitude; + /** Bearing angle in millidegrees (0 to 360E3) */ + uint32_t bearing; + /** Speed in millimeters per second */ + uint32_t speed; + /** Altitude in millimeters */ + int32_t altitude; +}; + +/** + * @brief Calculate the distance between two navigation points along the + * surface of the sphere they are relative to. + * + * @param distance Destination for calculated distance in millimeters + * @param p1 First navigation point + * @param p2 Second navigation point + * + * @return 0 if successful + * @return -EINVAL if either navigation point is invalid + */ +int navigation_distance(uint64_t *distance, const struct navigation_data *p1, + const struct navigation_data *p2); + +/** + * @brief Calculate the bearing from one navigation point to another + * + * @param bearing Destination for calculated bearing angle in millidegrees + * @param from First navigation point + * @param to Second navigation point + * + * @return 0 if successful + * @return -EINVAL if either navigation point is invalid + */ +int navigation_bearing(uint32_t *bearing, const struct navigation_data *from, + const struct navigation_data *to); + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DATA_NAVIGATION_H_ */ From 28f5f2d1eddbd9c6ae0210aa23fce4e57cce6cda Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Aug 2023 13:54:19 +0200 Subject: [PATCH 2794/4498] drivers: Add GNSS API public header This commit adds the public header for the GNSS API, along with the initial GNSS Kconfig file and an entry in the common linker file for registered GNSS data callbacks. A very naive implementation of the GNSS data callback is provided as well in drivers/gnss/gnss_publish.c Signed-off-by: Bjarki Arge Andreasen --- cmake/linker_script/common/common-rom.cmake | 8 + drivers/CMakeLists.txt | 1 + drivers/Kconfig | 1 + drivers/gnss/CMakeLists.txt | 5 + drivers/gnss/Kconfig | 21 + drivers/gnss/gnss_publish.c | 36 ++ drivers/gnss/gnss_publish.h | 19 + include/zephyr/drivers/gnss.h | 496 ++++++++++++++++++ .../linker/common-rom/common-rom-misc.ld | 8 + 9 files changed, 595 insertions(+) create mode 100644 drivers/gnss/CMakeLists.txt create mode 100644 drivers/gnss/Kconfig create mode 100644 drivers/gnss/gnss_publish.c create mode 100644 drivers/gnss/gnss_publish.h create mode 100644 include/zephyr/drivers/gnss.h diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index d81b215facc..35c023e72e4 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -218,3 +218,11 @@ if(CONFIG_ZBUS) zephyr_iterable_section(NAME zbus_channel KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME zbus_channel_observation KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) endif() + +if(CONFIG_GNSS) + zephyr_iterable_section(NAME gnss_data_callback KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) +endif() + +if(CONFIG_GNSS_SATELLITES) + zephyr_iterable_section(NAME gnss_satellites_callback KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) +endif() diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index e9a1603f8cc..b7fcdbed373 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -37,6 +37,7 @@ add_subdirectory_ifdef(CONFIG_ESPI espi) add_subdirectory_ifdef(CONFIG_FLASH flash) add_subdirectory_ifdef(CONFIG_FPGA fpga) add_subdirectory_ifdef(CONFIG_FUEL_GAUGE fuel_gauge) +add_subdirectory_ifdef(CONFIG_GNSS gnss) add_subdirectory_ifdef(CONFIG_GPIO gpio) add_subdirectory_ifdef(CONFIG_HWINFO hwinfo) add_subdirectory_ifdef(CONFIG_I2C i2c) diff --git a/drivers/Kconfig b/drivers/Kconfig index f486badbb38..1eca764fce2 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -31,6 +31,7 @@ source "drivers/ethernet/Kconfig" source "drivers/flash/Kconfig" source "drivers/fpga/Kconfig" source "drivers/fuel_gauge/Kconfig" +source "drivers/gnss/Kconfig" source "drivers/gpio/Kconfig" source "drivers/hwinfo/Kconfig" source "drivers/i2c/Kconfig" diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt new file mode 100644 index 00000000000..71a4d9d4831 --- /dev/null +++ b/drivers/gnss/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(gnss_publish.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig new file mode 100644 index 00000000000..4afb167f930 --- /dev/null +++ b/drivers/gnss/Kconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GNSS + bool "GNSS drivers" + select EXPERIMENTAL + help + Enable GNSS drivers and configuration. + +if GNSS + +config GNSS_SATELLITES + bool "GNSS satellites support" + help + Enable GNSS sattelites callback. + +module = GNSS +module-str = gnss +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/drivers/gnss/gnss_publish.c b/drivers/gnss/gnss_publish.c new file mode 100644 index 00000000000..98e3a2e5e19 --- /dev/null +++ b/drivers/gnss/gnss_publish.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "gnss_publish.h" +#include +#include + +static struct k_spinlock lock; + +void gnss_publish_data(const struct device *dev, const struct gnss_data *data) +{ + K_SPINLOCK(&lock) { + STRUCT_SECTION_FOREACH(gnss_data_callback, callback) { + if (callback->dev == NULL || callback->dev == dev) { + callback->callback(dev, data); + } + } + } +} + +#if CONFIG_GNSS_SATELLITES +void gnss_publish_satellites(const struct device *dev, const struct gnss_satellite *satellites, + uint16_t size) +{ + K_SPINLOCK(&lock) { + STRUCT_SECTION_FOREACH(gnss_satellites_callback, callback) { + if (callback->dev == NULL || callback->dev == dev) { + callback->callback(dev, satellites, size); + } + } + } +} +#endif diff --git a/drivers/gnss/gnss_publish.h b/drivers/gnss/gnss_publish.h new file mode 100644 index 00000000000..b686c7eaed1 --- /dev/null +++ b/drivers/gnss/gnss_publish.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_H_ + +#include + +/** Internal function used by GNSS drivers to publish GNSS data */ +void gnss_publish_data(const struct device *dev, const struct gnss_data *data); + +/** Internal function used by GNSS drivers to publish GNSS satellites */ +void gnss_publish_satellites(const struct device *dev, const struct gnss_satellite *satellites, + uint16_t size); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_H_ */ diff --git a/include/zephyr/drivers/gnss.h b/include/zephyr/drivers/gnss.h new file mode 100644 index 00000000000..4c25bd84a43 --- /dev/null +++ b/include/zephyr/drivers/gnss.h @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file gnss.h + * @brief Public GNSS API. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_GNSS_H_ +#define ZEPHYR_INCLUDE_DRIVERS_GNSS_H_ + +/** + * @brief GNSS Interface + * @defgroup gnss_interface GNSS Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** GNSS PPS modes */ +enum gnss_pps_mode { + /** PPS output disabled */ + GNSS_PPS_MODE_DISABLED = 0, + /** PPS output always enabled */ + GNSS_PPS_MODE_ENABLED = 1, + /** PPS output enabled from first lock */ + GNSS_PPS_MODE_ENABLED_AFTER_LOCK = 2, + /** PPS output enabled while locked */ + GNSS_PPS_MODE_ENABLED_WHILE_LOCKED = 3 +}; + +/** API for setting fix rate */ +typedef int (*gnss_set_fix_rate_t)(const struct device *dev, uint32_t fix_interval_ms); + +/** API for getting fix rate */ +typedef int (*gnss_get_fix_rate_t)(const struct device *dev, uint32_t *fix_interval_ms); + +/** + * @brief GNSS periodic tracking configuration + * + * @note Setting either active_time or inactive_time to 0 will disable periodic + * function. + */ +struct gnss_periodic_config { + /** The time the GNSS will spend in the active state in ms */ + uint32_t active_time_ms; + /** The time the GNSS will spend in the inactive state in ms */ + uint32_t inactive_time_ms; +}; + +/** API for setting periodic tracking configuration */ +typedef int (*gnss_set_periodic_config_t)(const struct device *dev, + const struct gnss_periodic_config *periodic_config); + +/** API for setting periodic tracking configuration */ +typedef int (*gnss_get_periodic_config_t)(const struct device *dev, + struct gnss_periodic_config *periodic_config); + +/** GNSS navigation modes */ +enum gnss_navigation_mode { + /** Dynamics have no impact on tracking */ + GNSS_NAVIGATION_MODE_ZERO_DYNAMICS = 0, + /** Low dynamics have higher impact on tracking */ + GNSS_NAVIGATION_MODE_LOW_DYNAMICS = 1, + /** Low and high dynamics have equal impact on tracking */ + GNSS_NAVIGATION_MODE_BALANCED_DYNAMICS = 2, + /** High dynamics have higher impact on tracking */ + GNSS_NAVIGATION_MODE_HIGH_DYNAMICS = 3 +}; + +/** API for setting navigation mode */ +typedef int (*gnss_set_navigation_mode_t)(const struct device *dev, + enum gnss_navigation_mode mode); + +/** API for getting navigation mode */ +typedef int (*gnss_get_navigation_mode_t)(const struct device *dev, + enum gnss_navigation_mode *mode); + +/** Systems contained in gnss_systems_t */ +enum gnss_system { + /** Global Positioning System (GPS) */ + GNSS_SYSTEM_GPS = BIT(0), + /** GLObal NAvigation Satellite System (GLONASS) */ + GNSS_SYSTEM_GLONASS = BIT(1), + /** Galileo */ + GNSS_SYSTEM_GALILEO = BIT(2), + /** BeiDou Navigation Satellite System */ + GNSS_SYSTEM_BEIDOU = BIT(3), + /** Quasi-Zenith Satellite System (QZSS) */ + GNSS_SYSTEM_QZSS = BIT(4), + /** Indian Regional Navigation Satellite System (IRNSS) */ + GNSS_SYSTEM_IRNSS = BIT(5), + /** Satellite-Based Augmentation System (SBAS) */ + GNSS_SYSTEM_SBAS = BIT(6), + /** Indoor Messaging System (IMES) */ + GNSS_SYSTEM_IMES = BIT(7), +}; + +/** Type storing bitmask of GNSS systems */ +typedef uint32_t gnss_systems_t; + +/** API for enabling systems */ +typedef int (*gnss_set_enabled_systems_t)(const struct device *dev, gnss_systems_t systems); + +/** API for getting enabled systems */ +typedef int (*gnss_get_enabled_systems_t)(const struct device *dev, gnss_systems_t *systems); + +/** API for getting enabled systems */ +typedef int (*gnss_get_supported_systems_t)(const struct device *dev, gnss_systems_t *systems); + +/** GNSS fix status */ +enum gnss_fix_status { + /** No GNSS fix aqcuired */ + GNSS_FIX_STATUS_NO_FIX = 0, + /** GNSS fix aqcuired */ + GNSS_FIX_STATUS_GNSS_FIX = 1, + /** Differential GNSS fix acquired */ + GNSS_FIX_STATUS_DGNSS_FIX = 2, + /** Estimated fix acquired */ + GNSS_FIX_STATUS_ESTIMATED_FIX = 3, +}; + +/** GNSS fix quality */ +enum gnss_fix_quality { + /** Invalid fix */ + GNSS_FIX_QUALITY_INVALID = 0, + /** Standard positioning service */ + GNSS_FIX_QUALITY_GNSS_SPS = 1, + /** Differential GNSS */ + GNSS_FIX_QUALITY_DGNSS = 2, + /** Precise positioning service */ + GNSS_FIX_QUALITY_GNSS_PPS = 3, + /** Real-time kinematic */ + GNSS_FIX_QUALITY_RTK = 4, + /** Floating real-time kinematic */ + GNSS_FIX_QUALITY_FLOAT_RTK = 5, + /** Estimated fix */ + GNSS_FIX_QUALITY_ESTIMATED = 6, +}; + +/** GNSS info data structure */ +struct gnss_info { + /** Number of satellites being tracked */ + uint16_t satellites_cnt; + /** Horizontal dilution of precision in 1/1000 */ + uint16_t hdop; + /** The fix status */ + enum gnss_fix_status fix_status; + /** The fix quality */ + enum gnss_fix_quality fix_quality; +}; + +/** GNSS time data structure */ +struct gnss_time { + /** Hour [0, 23] */ + uint8_t hour; + /** Minute [0, 59] */ + uint8_t minute; + /** Millisecond [0, 59999] */ + uint16_t millisecond; + /** Day of month [1, 31] */ + uint8_t month_day; + /** Month [1, 12] */ + uint8_t month; + /** Year [0, 99] */ + uint8_t century_year; +}; + +/** GNSS API structure */ +__subsystem struct gnss_driver_api { + gnss_set_fix_rate_t set_fix_rate; + gnss_get_fix_rate_t get_fix_rate; + gnss_set_periodic_config_t set_periodic_config; + gnss_get_periodic_config_t get_periodic_config; + gnss_set_navigation_mode_t set_navigation_mode; + gnss_get_navigation_mode_t get_navigation_mode; + gnss_set_enabled_systems_t set_enabled_systems; + gnss_get_enabled_systems_t get_enabled_systems; + gnss_get_supported_systems_t get_supported_systems; +}; + +/** GNSS data structure */ +struct gnss_data { + /** Navigation data acquired */ + struct navigation_data nav_data; + /** GNSS info when navigation data was acquired */ + struct gnss_info info; + /** UTC time when data was acquired */ + struct gnss_time utc; +}; + +/** Template for GNSS data callback */ +typedef void (*gnss_data_callback_t)(const struct device *dev, const struct gnss_data *data); + +/** GNSS callback structure */ +struct gnss_data_callback { + /** Filter callback to GNSS data from this device if not NULL */ + const struct device *dev; + /** Callback called when GNSS data is published */ + gnss_data_callback_t callback; +}; + +/** GNSS satellite structure */ +struct gnss_satellite { + /** Pseudo-random noise sequence */ + uint8_t prn; + /** Signal-to-noise ratio in dB */ + uint8_t snr; + /** Elevation in degrees [0, 90] */ + uint8_t elevation; + /** Azimuth relative to True North in degrees [0, 359] */ + uint16_t azimuth; + /** System of satellite */ + enum gnss_system system; + /** True if satellite is being tracked */ + uint8_t is_tracked : 1; +}; + +/** Template for GNSS satellites callback */ +typedef void (*gnss_satellites_callback_t)(const struct device *dev, + const struct gnss_satellite *satellites, + uint16_t size); + +/** GNSS callback structure */ +struct gnss_satellites_callback { + /** Filter callback to GNSS data from this device if not NULL */ + const struct device *dev; + /** Callback called when GNSS satellites is published */ + gnss_satellites_callback_t callback; +}; + +/** + * @brief Set the GNSS fix rate + * + * @param dev Device instance + * @param fix_interval_ms Fix interval to set in milliseconds + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms); + +static inline int z_impl_gnss_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->set_fix_rate == NULL) { + return -ENOSYS; + } + + return api->set_fix_rate(dev, fix_interval_ms); +} + +/** + * @brief Get the GNSS fix rate + * + * @param dev Device instance + * @param fix_interval_ms Destination for fix interval in milliseconds + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms); + +static inline int z_impl_gnss_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->get_fix_rate == NULL) { + return -ENOSYS; + } + + return api->get_fix_rate(dev, fix_interval_ms); +} + +/** + * @brief Set the GNSS periodic tracking configuration + * + * @param dev Device instance + * @param config Periodic tracking configuration to set + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_set_periodic_config(const struct device *dev, + const struct gnss_periodic_config *config); + +static inline int z_impl_gnss_set_periodic_config(const struct device *dev, + const struct gnss_periodic_config *config) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->set_periodic_config == NULL) { + return -ENOSYS; + } + + return api->set_periodic_config(dev, config); +} + +/** + * @brief Get the GNSS periodic tracking configuration + * + * @param dev Device instance + * @param config Destination for periodic tracking configuration + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_get_periodic_config(const struct device *dev, + struct gnss_periodic_config *config); + +static inline int z_impl_gnss_get_periodic_config(const struct device *dev, + struct gnss_periodic_config *config) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->get_periodic_config == NULL) { + return -ENOSYS; + } + + return api->get_periodic_config(dev, config); +} + +/** + * @brief Set the GNSS navigation mode + * + * @param dev Device instance + * @param mode Navigation mode to set + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_set_navigation_mode(const struct device *dev, + enum gnss_navigation_mode mode); + +static inline int z_impl_gnss_set_navigation_mode(const struct device *dev, + enum gnss_navigation_mode mode) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->set_navigation_mode == NULL) { + return -ENOSYS; + } + + return api->set_navigation_mode(dev, mode); +} + +/** + * @brief Get the GNSS navigation mode + * + * @param dev Device instance + * @param mode Destination for navigation mode + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_get_navigation_mode(const struct device *dev, + enum gnss_navigation_mode *mode); + +static inline int z_impl_gnss_get_navigation_mode(const struct device *dev, + enum gnss_navigation_mode *mode) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->get_navigation_mode == NULL) { + return -ENOSYS; + } + + return api->get_navigation_mode(dev, mode); +} + +/** + * @brief Set enabled GNSS systems + * + * @param dev Device instance + * @param systems Systems to enable + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_set_enabled_systems(const struct device *dev, gnss_systems_t systems); + +static inline int z_impl_gnss_set_enabled_systems(const struct device *dev, + gnss_systems_t systems) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->set_enabled_systems == NULL) { + return -ENOSYS; + } + + return api->set_enabled_systems(dev, systems); +} + +/** + * @brief Get enabled GNSS systems + * + * @param dev Device instance + * @param systems Destination for enabled systems + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_get_enabled_systems(const struct device *dev, gnss_systems_t *systems); + +static inline int z_impl_gnss_get_enabled_systems(const struct device *dev, + gnss_systems_t *systems) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->get_enabled_systems == NULL) { + return -ENOSYS; + } + + return api->get_enabled_systems(dev, systems); +} + +/** + * @brief Get supported GNSS systems + * + * @param dev Device instance + * @param systems Destination for supported systems + * + * @return 0 if successful + * @return -errno negative errno code on failure + */ +__syscall int gnss_get_supported_systems(const struct device *dev, gnss_systems_t *systems); + +static inline int z_impl_gnss_get_supported_systems(const struct device *dev, + gnss_systems_t *systems) +{ + const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api; + + if (api->get_supported_systems == NULL) { + return -ENOSYS; + } + + return api->get_supported_systems(dev, systems); +} + +/** + * @brief Register a callback structure for GNSS data published + * + * @param _dev Device pointer + * @param _callback The callback function + */ +#if CONFIG_GNSS +#define GNSS_DATA_CALLBACK_DEFINE(_dev, _callback) \ + static const STRUCT_SECTION_ITERABLE(gnss_data_callback, \ + _gnss_data_callback__##_callback) = { \ + .dev = _dev, \ + .callback = _callback, \ + } +#else +#define GNSS_DATA_CALLBACK_DEFINE(_dev, _callback) +#endif + +/** + * @brief Register a callback structure for GNSS satellites published + * + * @param _dev Device pointer + * @param _callback The callback function + */ +#if CONFIG_GNSS_SATELLITES +#define GNSS_SATELLITES_CALLBACK_DEFINE(_dev, _callback) \ + static const STRUCT_SECTION_ITERABLE(gnss_satellites_callback, \ + _gnss_satellites_callback__##_callback) = { \ + .dev = _dev, \ + .callback = _callback, \ + } +#else +#define GNSS_SATELLITES_CALLBACK_DEFINE(_dev, _callback) +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_GNSS_H_ */ diff --git a/include/zephyr/linker/common-rom/common-rom-misc.ld b/include/zephyr/linker/common-rom/common-rom-misc.ld index 5da776a6aaf..1fbf777ba55 100644 --- a/include/zephyr/linker/common-rom/common-rom-misc.ld +++ b/include/zephyr/linker/common-rom/common-rom-misc.ld @@ -59,3 +59,11 @@ ITERABLE_SECTION_ROM(shell_dynamic_subcmds, 4) ITERABLE_SECTION_ROM(cfb_font, 4) + +#if defined(CONFIG_GNSS) + ITERABLE_SECTION_ROM(gnss_data_callback, 4) +#endif + +#if defined(CONFIG_GNSS_SATELLITES) + ITERABLE_SECTION_ROM(gnss_satellites_callback, 4) +#endif From 2a81c2248902f73c76c922a8b18cd55bab740c4b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 3 Oct 2023 11:41:03 +0200 Subject: [PATCH 2795/4498] drivers: gnss: Add gnss_dump library This commit adds a library which dumps the contents of the gnss structures gnss_info, navigation_data, gnss_time and gnss_satellite as a string. Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/CMakeLists.txt | 1 + drivers/gnss/Kconfig | 6 ++ drivers/gnss/gnss_dump.c | 134 ++++++++++++++++++++++++++++++++++++ drivers/gnss/gnss_dump.h | 60 ++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 drivers/gnss/gnss_dump.c create mode 100644 drivers/gnss/gnss_dump.h diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index 71a4d9d4831..eeaf40721b5 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources(gnss_publish.c) +zephyr_library_sources_ifdef(CONFIG_GNSS_DUMP gnss_dump.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index 4afb167f930..beed7ca523e 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -14,6 +14,12 @@ config GNSS_SATELLITES help Enable GNSS sattelites callback. +config GNSS_DUMP + bool "GNSS dump support" + depends on LOG + help + Enable GNSS dump library + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/gnss/gnss_dump.c b/drivers/gnss/gnss_dump.c new file mode 100644 index 00000000000..b70a271e2fa --- /dev/null +++ b/drivers/gnss/gnss_dump.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "gnss_dump.h" +#include +#include + +static const char *gnss_fix_status_to_str(enum gnss_fix_status fix_status) +{ + switch (fix_status) { + case GNSS_FIX_STATUS_NO_FIX: + return "NO_FIX"; + case GNSS_FIX_STATUS_GNSS_FIX: + return "GNSS_FIX"; + case GNSS_FIX_STATUS_DGNSS_FIX: + return "DGNSS_FIX"; + case GNSS_FIX_STATUS_ESTIMATED_FIX: + return "ESTIMATED_FIX"; + } + + return "unknown"; +} + +static const char *gnss_fix_quality_to_str(enum gnss_fix_quality fix_quality) +{ + switch (fix_quality) { + case GNSS_FIX_QUALITY_INVALID: + return "INVALID"; + case GNSS_FIX_QUALITY_GNSS_SPS: + return "GNSS_SPS"; + case GNSS_FIX_QUALITY_DGNSS: + return "DGNSS"; + case GNSS_FIX_QUALITY_GNSS_PPS: + return "GNSS_PPS"; + case GNSS_FIX_QUALITY_RTK: + return "RTK"; + case GNSS_FIX_QUALITY_FLOAT_RTK: + return "FLOAT_RTK"; + case GNSS_FIX_QUALITY_ESTIMATED: + return "ESTIMATED"; + } + + return "unknown"; +} + +#if CONFIG_GNSS_SATELLITES +static const char *gnss_system_to_str(enum gnss_system system) +{ + switch (system) { + case GNSS_SYSTEM_GPS: + return "GPS"; + case GNSS_SYSTEM_GLONASS: + return "GLONASS"; + case GNSS_SYSTEM_GALILEO: + return "GALILEO"; + case GNSS_SYSTEM_BEIDOU: + return "BEIDOU"; + case GNSS_SYSTEM_QZSS: + return "QZSS"; + case GNSS_SYSTEM_IRNSS: + return "IRNSS"; + case GNSS_SYSTEM_SBAS: + return "SBAS"; + case GNSS_SYSTEM_IMES: + return "IMES"; + } + + return "unknown"; +} +#endif + +int gnss_dump_info(char *str, uint16_t strsize, const struct gnss_info *info) +{ + int ret; + const char *fmt = "gnss_info: {satellites_cnt: %u, hdop: %u.%u, fix_status: %s, " + "fix_quality: %s}"; + + ret = snprintk(str, strsize, fmt, info->satellites_cnt, info->hdop / 1000, + info->hdop % 1000, gnss_fix_status_to_str(info->fix_status), + gnss_fix_quality_to_str(info->fix_quality)); + + return (strsize < ret) ? -ENOMEM : 0; +} + +int gnss_dump_nav_data(char *str, uint16_t strsize, const struct navigation_data *nav_data) +{ + int ret; + int32_t altitude_int; + int32_t altitude_fraction; + const char *fmt = "navigation_data: {latitude: %lli.%lli, longitude : %lli.%lli, " + "bearing %u.%u, speed %u.%u, altitude: %i.%i}"; + + altitude_int = nav_data->altitude / 1000; + altitude_fraction = nav_data->altitude % 1000; + altitude_fraction = (altitude_fraction < 0) ? -altitude_fraction : altitude_fraction; + + ret = snprintk(str, strsize, fmt, nav_data->latitude / 1000000000, + nav_data->latitude % 1000000000, nav_data->longitude / 1000000000, + nav_data->longitude % 1000000000, nav_data->bearing / 1000, + nav_data->bearing % 1000, nav_data->speed / 1000, nav_data->speed % 1000, + altitude_int, altitude_fraction); + + return (strsize < ret) ? -ENOMEM : 0; +} + +int gnss_dump_time(char *str, uint16_t strsize, const struct gnss_time *utc) +{ + int ret; + const char *fmt = "gnss_time: {hour: %u, minute: %u, millisecond %u, month_day %u, " + "month: %u, century_year: %u}"; + + ret = snprintk(str, strsize, fmt, utc->hour, utc->minute, utc->millisecond, + utc->month_day, utc->month, utc->century_year); + + return (strsize < ret) ? -ENOMEM : 0; +} + +#if CONFIG_GNSS_SATELLITES +int gnss_dump_satellite(char *str, uint16_t strsize, const struct gnss_satellite *satellite) +{ + int ret; + const char *fmt = "gnss_satellite: {prn: %u, snr: %u, elevation %u, azimuth %u, " + "system: %s, is_tracked: %u}"; + + ret = snprintk(str, strsize, fmt, satellite->prn, satellite->snr, satellite->elevation, + satellite->azimuth, gnss_system_to_str(satellite->system), + satellite->is_tracked); + + return (strsize < ret) ? -ENOMEM : 0; +} +#endif diff --git a/drivers/gnss/gnss_dump.h b/drivers/gnss/gnss_dump.h new file mode 100644 index 00000000000..ba02b085cd2 --- /dev/null +++ b/drivers/gnss/gnss_dump.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_DUMP_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_DUMP_H_ + +#include + +/** + * @brief Dump struct gnss_info as string + * + * @param str Destination for dumped GNSS info + * @param strsize Size of str + * @param info GNSS info to dump + * + * @retval 0 if GNSS info successfully dumped + * @retval -ENOMEM if strsize too small + */ +int gnss_dump_info(char *str, uint16_t strsize, const struct gnss_info *info); + +/** + * @brief Dump struct navigation_data as string + * + * @param str Destination for dumped navigation data + * @param strsize Size of str + * @param nav_data Navigation data to dump + * + * @retval 0 if navigation data successfully dumped + * @retval -ENOMEM if strsize too small + */ +int gnss_dump_nav_data(char *str, uint16_t strsize, const struct navigation_data *nav_data); + +/** + * @brief Dump struct gnss_time as string + * + * @param str Destination for dumped GNSS time + * @param strsize Size of str + * @param utc GNSS time to dump + * + * @retval 0 if GNSS time successfully dumped + * @retval -ENOMEM if strsize too small + */ +int gnss_dump_time(char *str, uint16_t strsize, const struct gnss_time *utc); + +/** + * @brief Dump struct gnss_satellite as string + * + * @param str Destination for dumped GNSS satellite + * @param strsize Size of str + * @param utc GNSS satellite to dump + * + * @retval 0 if GNSS satellite successfully dumped + * @retval -ENOMEM if strsize too small + */ +int gnss_dump_satellite(char *str, uint16_t strsize, const struct gnss_satellite *satellite); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_DUMP_H_ */ From 03d2671ddd6fa0b3b48309072db929de3edd25d9 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 3 Oct 2023 17:09:15 +0200 Subject: [PATCH 2796/4498] drivers: gnss: Add GNSS dump to log feature This commit adds dumping of GNSS data and satellites to the log if CONFIG_GNSS_DUMP_TO_LOG is selected Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/Kconfig | 16 ++++++++++++++ drivers/gnss/gnss_dump.c | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index beed7ca523e..2bde6428bec 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -20,6 +20,22 @@ config GNSS_DUMP help Enable GNSS dump library +config GNSS_DUMP_TO_LOG + bool "Dump GNSS events to log" + select GNSS_DUMP + help + Enable GNSS dump to log. + +if GNSS_DUMP_TO_LOG + +config GNSS_DUMP_TO_LOG_BUF_SIZE + int "GNSS log dump buffer size" + default 128 + help + Size of GNSS log dump buffer + +endif + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/gnss/gnss_dump.c b/drivers/gnss/gnss_dump.c index b70a271e2fa..1946d65ea2e 100644 --- a/drivers/gnss/gnss_dump.c +++ b/drivers/gnss/gnss_dump.c @@ -6,8 +6,14 @@ #include "gnss_dump.h" #include +#include + #include +#if CONFIG_GNSS_DUMP_TO_LOG +static char dump_buf[CONFIG_GNSS_DUMP_TO_LOG_BUF_SIZE]; +#endif /* CONFIG_GNSS_DUMP_TO_LOG */ + static const char *gnss_fix_status_to_str(enum gnss_fix_status fix_status) { switch (fix_status) { @@ -132,3 +138,44 @@ int gnss_dump_satellite(char *str, uint16_t strsize, const struct gnss_satellite return (strsize < ret) ? -ENOMEM : 0; } #endif + +#if CONFIG_GNSS_DUMP_TO_LOG +static void gnss_dump_data_to_log(const struct device *dev, const struct gnss_data *data) +{ + if (gnss_dump_info(dump_buf, sizeof(dump_buf), &data->info) < 0) { + return; + } + + LOG_PRINTK("%s: %s\r\n", dev->name, dump_buf); + + if (gnss_dump_nav_data(dump_buf, sizeof(dump_buf), &data->nav_data) < 0) { + return; + } + + LOG_PRINTK("%s: %s\r\n", dev->name, dump_buf); + + if (gnss_dump_time(dump_buf, sizeof(dump_buf), &data->utc) < 0) { + return; + } + + LOG_PRINTK("%s: %s\r\n", dev->name, dump_buf); +} + +GNSS_DATA_CALLBACK_DEFINE(NULL, gnss_dump_data_to_log); +#endif + +#if defined(CONFIG_GNSS_DUMP_TO_LOG) && defined(CONFIG_GNSS_SATELLITES) +static void gnss_dump_satellites_to_log(const struct device *dev, + const struct gnss_satellite *satellites, uint16_t size) +{ + for (uint16_t i = 0; i < size; i++) { + if (gnss_dump_satellite(dump_buf, sizeof(dump_buf), &satellites[i]) < 0) { + return; + } + + LOG_PRINTK("%s: %s\r\n", dev->name, dump_buf); + } +} + +GNSS_SATELLITES_CALLBACK_DEFINE(NULL, gnss_dump_satellites_to_log); +#endif From 4cfea4a520278fd712dd8cb3444f1c4e70cd1153 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 25 Aug 2023 12:45:00 +0200 Subject: [PATCH 2797/4498] drivers: gnss: Add GNSS parsing utilities This commit adds parsing utilites for common string representations of values contained in GNSS messages. These utilites both parse and validate the integrity of the data. Unit tests are also added to validate the parsing utilities. Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/CMakeLists.txt | 1 + drivers/gnss/Kconfig | 5 + drivers/gnss/gnss_parse.c | 149 +++++++++++++++++++ drivers/gnss/gnss_parse.h | 65 ++++++++ tests/drivers/gnss/gnss_parse/CMakeLists.txt | 14 ++ tests/drivers/gnss/gnss_parse/prj.conf | 7 + tests/drivers/gnss/gnss_parse/src/main.c | 99 ++++++++++++ tests/drivers/gnss/gnss_parse/testcase.yaml | 9 ++ 8 files changed, 349 insertions(+) create mode 100644 drivers/gnss/gnss_parse.c create mode 100644 drivers/gnss/gnss_parse.h create mode 100644 tests/drivers/gnss/gnss_parse/CMakeLists.txt create mode 100644 tests/drivers/gnss/gnss_parse/prj.conf create mode 100644 tests/drivers/gnss/gnss_parse/src/main.c create mode 100644 tests/drivers/gnss/gnss_parse/testcase.yaml diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index eeaf40721b5..f19be7c0055 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -4,3 +4,4 @@ zephyr_library() zephyr_library_sources(gnss_publish.c) zephyr_library_sources_ifdef(CONFIG_GNSS_DUMP gnss_dump.c) +zephyr_library_sources_ifdef(CONFIG_GNSS_PARSE gnss_parse.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index 2bde6428bec..f07145a934a 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -36,6 +36,11 @@ config GNSS_DUMP_TO_LOG_BUF_SIZE endif +config GNSS_PARSE + bool "GNSS parsing utilities" + help + Enable GNSS parsing utilities. + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/gnss/gnss_parse.c b/drivers/gnss/gnss_parse.c new file mode 100644 index 00000000000..5cde6a630a9 --- /dev/null +++ b/drivers/gnss/gnss_parse.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include "gnss_parse.h" + +#define GNSS_PARSE_NANO_KNOTS_IN_MMS (1943840LL) +#define GNSS_PARSE_NANO (1000000000LL) +#define GNSS_PARSE_MICRO (1000000LL) +#define GNSS_PARSE_MILLI (1000LL) + +int gnss_parse_dec_to_nano(const char *str, int64_t *nano) +{ + int64_t sum = 0; + int8_t decimal = -1; + int8_t pos = 0; + int8_t start = 0; + int64_t increment; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(str != NULL, "nano argument must be provided"); + + /* Find decimal */ + while (str[pos] != '\0') { + /* Verify if char is decimal */ + if (str[pos] == '.') { + decimal = pos; + break; + } + + /* Advance position */ + pos++; + } + + /* Determine starting position based on decimal location */ + pos = decimal < 0 ? pos - 1 : decimal - 1; + + /* Skip sign if it exists */ + start = str[0] == '-' ? 1 : 0; + + /* Add whole value to sum */ + increment = GNSS_PARSE_NANO; + while (start <= pos) { + /* Verify char is decimal */ + if (str[pos] < '0' || str[pos] > '9') { + return -EINVAL; + } + + /* Add value to sum */ + sum += (str[pos] - '0') * increment; + + /* Update increment */ + increment *= 10; + + /* Degrement position */ + pos--; + } + + /* Check if decimal was found */ + if (decimal < 0) { + /* Set sign of sum */ + sum = start == 1 ? -sum : sum; + + *nano = sum; + return 0; + } + + /* Convert decimal part to nano fractions and add it to sum */ + pos = decimal + 1; + increment = GNSS_PARSE_NANO / 10LL; + while (str[pos] != '\0') { + /* Verify char is decimal */ + if (str[pos] < '0' || str[pos] > '9') { + return -EINVAL; + } + + /* Add value to micro_degrees */ + sum += (str[pos] - '0') * increment; + + /* Update unit */ + increment /= 10; + + /* Increment position */ + pos++; + } + + /* Set sign of sum */ + sum = start == 1 ? -sum : sum; + + *nano = sum; + return 0; +} + +int gnss_parse_dec_to_micro(const char *str, uint64_t *micro) +{ + int ret; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(micro != NULL, "micro argument must be provided"); + + ret = gnss_parse_dec_to_nano(str, micro); + if (ret < 0) { + return ret; + } + + *micro = (*micro) / GNSS_PARSE_MILLI; + return 0; +} + + +int gnss_parse_dec_to_milli(const char *str, int64_t *milli) +{ + int ret; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(milli != NULL, "milli argument must be provided"); + + ret = gnss_parse_dec_to_nano(str, milli); + if (ret < 0) { + return ret; + } + + (*milli) = (*milli) / GNSS_PARSE_MICRO; + return 0; +} + +int gnss_parse_atoi(const char *str, uint8_t base, int32_t *integer) +{ + char *end; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(integer != NULL, "integer argument must be provided"); + + *integer = (int32_t)strtol(str, &end, (int)base); + + if ('\0' != (*end)) { + return -EINVAL; + } + + return 0; +} diff --git a/drivers/gnss/gnss_parse.h b/drivers/gnss/gnss_parse.h new file mode 100644 index 00000000000..443363cfa6e --- /dev/null +++ b/drivers/gnss/gnss_parse.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_PARSE_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_PARSE_H_ + +#include + +/** + * @brief Parse decimal string to nano parts + * + * @example "-1231.3512" -> -1231351200000 + * + * @param str The decimal string to be parsed + * @param nano Destination for parsed decimal + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if str successfully parsed + */ +int gnss_parse_dec_to_nano(const char *str, int64_t *nano); + +/** + * @brief Parse decimal string to micro parts + * + * @example "-1231.3512" -> -1231351200 + * + * @param str The decimal string to be parsed + * @param milli Destination for parsed decimal + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if str successfully parsed + */ +int gnss_parse_dec_to_micro(const char *str, uint64_t *micro); + +/** + * @brief Parse decimal string to milli parts + * + * @example "-1231.3512" -> -1231351 + * + * @param str The decimal string to be parsed + * @param milli Destination for parsed decimal + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if str successfully parsed + */ +int gnss_parse_dec_to_milli(const char *str, int64_t *milli); + +/** + * @brief Parse integer string of configurable base to integer + * + * @example "-1231" -> -1231 + * + * @param str Decimal string to be parsed + * @param base Base of decimal string to be parsed + * @param integer Destination for parsed integer + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if str successfully parsed + */ +int gnss_parse_atoi(const char *str, uint8_t base, int32_t *integer); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_PARSE_H_ */ diff --git a/tests/drivers/gnss/gnss_parse/CMakeLists.txt b/tests/drivers/gnss/gnss_parse/CMakeLists.txt new file mode 100644 index 00000000000..ec07dff7dc1 --- /dev/null +++ b/tests/drivers/gnss/gnss_parse/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(gnss_parse) + +target_sources(app PRIVATE + src/main.c +) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers/gnss) diff --git a/tests/drivers/gnss/gnss_parse/prj.conf b/tests/drivers/gnss/gnss_parse/prj.conf new file mode 100644 index 00000000000..78ac36dd3db --- /dev/null +++ b/tests/drivers/gnss/gnss_parse/prj.conf @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GNSS=y +CONFIG_GNSS_PARSE=y +CONFIG_ZTEST=y +CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/drivers/gnss/gnss_parse/src/main.c b/tests/drivers/gnss/gnss_parse/src/main.c new file mode 100644 index 00000000000..9bf1c0e4eb6 --- /dev/null +++ b/tests/drivers/gnss/gnss_parse/src/main.c @@ -0,0 +1,99 @@ +/* + * Copyright 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "gnss_parse.h" + +struct test_atoi_sample { + const char *str; + uint8_t base; + int32_t value; +}; + +static const struct test_atoi_sample atoi_samples[] = { + {.str = "10", .base = 10, .value = 10}, + {.str = "1", .base = 10, .value = 1}, + {.str = "002", .base = 10, .value = 2}, + {.str = "-10", .base = 10, .value = -10}, + {.str = "-1", .base = 10, .value = -1}, + {.str = "-002", .base = 10, .value = -2}, + {.str = "30000000", .base = 10, .value = 30000000}, + {.str = "-30000000", .base = 10, .value = -30000000}, + {.str = "00", .base = 16, .value = 0}, + {.str = "20", .base = 16, .value = 32}, + {.str = "42", .base = 16, .value = 66}, + {.str = "122", .base = 16, .value = 290}, + {.str = "0122", .base = 16, .value = 290}, +}; + +ZTEST(gnss_parse, test_atoi) +{ + int32_t value; + + for (size_t i = 0; i < ARRAY_SIZE(atoi_samples); i++) { + zassert_ok(gnss_parse_atoi(atoi_samples[i].str, atoi_samples[i].base, &value), + "Parse failed"); + + zassert_equal(atoi_samples[i].value, value, "Parsed value is incorrect"); + } + + zassert_equal(gnss_parse_atoi("a10", 10, &value), -EINVAL, + "Parse should fail due to invalid base 10 chars"); + + zassert_equal(gnss_parse_atoi("h#1c", 16, &value), -EINVAL, + "Parse should fail due to invalid base 16 chars"); +} + +struct test_dec_sample { + const char *str; + int64_t value; +}; + +static const struct test_dec_sample dec_to_nano_samples[] = { + {.str = "10", .value = 10000000000}, + {.str = "1", .value = 1000000000}, + {.str = "002", .value = 2000000000}, + {.str = "-10", .value = -10000000000}, + {.str = "-1", .value = -1000000000}, + {.str = "-002", .value = -2000000000}, + {.str = "30000000", .value = 30000000000000000}, + {.str = "-30000000", .value = -30000000000000000}, + {.str = "0.10", .value = 100000000}, + {.str = "-0.10", .value = -100000000}, + {.str = "1", .value = 1000000000}, + {.str = "002.000", .value = 2000000000}, + {.str = "-002.000", .value = -2000000000}, + {.str = "0.989812343", .value = 989812343}, + {.str = "-0.989812343", .value = -989812343}, + {.str = "0.112211", .value = 112211000}, + {.str = "-0.112211", .value = -112211000}, + {.str = "000000000.112211000000000000", .value = 112211000}, + {.str = "-000000000.11221100000000000", .value = -112211000}, +}; + +ZTEST(gnss_parse, test_dec_to_nano) +{ + int64_t value; + + for (volatile size_t i = 0; i < ARRAY_SIZE(dec_to_nano_samples); i++) { + zassert_ok(gnss_parse_dec_to_nano(dec_to_nano_samples[i].str, &value), + "Parse failed"); + + zassert_equal(dec_to_nano_samples[i].value, value, "Parsed value is incorrect"); + } + + zassert_equal(gnss_parse_dec_to_nano("-0s02..000", &value), -EINVAL, + "Parse should fail due to double dot"); + + zassert_equal(gnss_parse_dec_to_nano("--002.000", &value), -EINVAL, + "Parse should fail due to double -"); + + zassert_equal(gnss_parse_dec_to_nano("-00s2.000", &value), -EINVAL, + "Parse should fail due to invalid char"); +} + +ZTEST_SUITE(gnss_parse, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/gnss/gnss_parse/testcase.yaml b/tests/drivers/gnss/gnss_parse/testcase.yaml new file mode 100644 index 00000000000..82939ba446a --- /dev/null +++ b/tests/drivers/gnss/gnss_parse/testcase.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.gnss.gnss_parse: + tags: + - drivers + - gnss + - parse From d8bb7c87cf48aa68ca6ce213ba62eaa40ad21485 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 31 Aug 2023 18:23:13 +0200 Subject: [PATCH 2798/4498] drivers: gnss: Add parsing utils for NMEA0183 This commit adds utilites to parse the RMC and GGA NMEA0183 messages, which contain all data which shall be published using the struct gnss_data. It also adds a test suite for the added utilities. Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/CMakeLists.txt | 1 + drivers/gnss/Kconfig | 6 + drivers/gnss/gnss_nmea0183.c | 678 ++++++++++++++++ drivers/gnss/gnss_nmea0183.h | 178 +++++ .../drivers/gnss/gnss_nmea0183/CMakeLists.txt | 14 + tests/drivers/gnss/gnss_nmea0183/prj.conf | 7 + tests/drivers/gnss/gnss_nmea0183/src/main.c | 739 ++++++++++++++++++ .../drivers/gnss/gnss_nmea0183/testcase.yaml | 10 + 8 files changed, 1633 insertions(+) create mode 100644 drivers/gnss/gnss_nmea0183.c create mode 100644 drivers/gnss/gnss_nmea0183.h create mode 100644 tests/drivers/gnss/gnss_nmea0183/CMakeLists.txt create mode 100644 tests/drivers/gnss/gnss_nmea0183/prj.conf create mode 100644 tests/drivers/gnss/gnss_nmea0183/src/main.c create mode 100644 tests/drivers/gnss/gnss_nmea0183/testcase.yaml diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index f19be7c0055..d30723c1915 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -5,3 +5,4 @@ zephyr_library() zephyr_library_sources(gnss_publish.c) zephyr_library_sources_ifdef(CONFIG_GNSS_DUMP gnss_dump.c) zephyr_library_sources_ifdef(CONFIG_GNSS_PARSE gnss_parse.c) +zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183 gnss_nmea0183.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index f07145a934a..fcb45122aa4 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -41,6 +41,12 @@ config GNSS_PARSE help Enable GNSS parsing utilities. +config GNSS_NMEA0183 + bool "NMEA0183 parsing utilities" + select GNSS_PARSE + help + Enable NMEA0183 parsing utilities. + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/gnss/gnss_nmea0183.c b/drivers/gnss/gnss_nmea0183.c new file mode 100644 index 00000000000..f69dd347a9f --- /dev/null +++ b/drivers/gnss/gnss_nmea0183.c @@ -0,0 +1,678 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include "gnss_nmea0183.h" +#include "gnss_parse.h" + +#define GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE (1000000000000ULL) +#define GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE (GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE / 60ULL) +#define GNSS_NMEA0183_PICO_DEGREES_IN_NANO_DEGREE (1000ULL) +#define GNSS_NMEA0183_NANO_KNOTS_IN_MMS (1943861LL) + +#define GNSS_NMEA0183_MESSAGE_SIZE_MIN (6) +#define GNSS_NMEA0183_MESSAGE_CHECKSUM_SIZE (3) + +#define GNSS_NMEA0183_GSV_HDR_ARG_CNT (4) +#define GNSS_NMEA0183_GSV_SV_ARG_CNT (4) + +#define GNSS_NMEA0183_GSV_PRN_GPS_RANGE (32) +#define GNSS_NMEA0183_GSV_PRN_SBAS_OFFSET (87) +#define GNSS_NMEA0183_GSV_PRN_GLONASS_OFFSET (64) +#define GNSS_NMEA0183_GSV_PRN_BEIDOU_OFFSET (100) + +struct gsv_header_args { + const char *message_id; + const char *number_of_messages; + const char *message_number; + const char *numver_of_svs; +}; + +struct gsv_sv_args { + const char *prn; + const char *elevation; + const char *azimuth; + const char *snr; +}; + +static int gnss_system_from_gsv_header_args(const struct gsv_header_args *args, + enum gnss_system *sv_system) +{ + switch (args->message_id[2]) { + case 'A': + *sv_system = GNSS_SYSTEM_GALILEO; + break; + case 'B': + *sv_system = GNSS_SYSTEM_BEIDOU; + break; + case 'P': + *sv_system = GNSS_SYSTEM_GPS; + break; + case 'L': + *sv_system = GNSS_SYSTEM_GLONASS; + break; + case 'Q': + *sv_system = GNSS_SYSTEM_QZSS; + break; + default: + return -EINVAL; + } + + return 0; +} + +static void align_satellite_with_gnss_system(enum gnss_system sv_system, + struct gnss_satellite *satellite) +{ + switch (sv_system) { + case GNSS_SYSTEM_GPS: + if (satellite->prn > GNSS_NMEA0183_GSV_PRN_GPS_RANGE) { + satellite->system = GNSS_SYSTEM_SBAS; + satellite->prn += GNSS_NMEA0183_GSV_PRN_SBAS_OFFSET; + break; + } + + satellite->system = GNSS_SYSTEM_GPS; + break; + + case GNSS_SYSTEM_GLONASS: + satellite->system = GNSS_SYSTEM_GLONASS; + satellite->prn -= GNSS_NMEA0183_GSV_PRN_GLONASS_OFFSET; + break; + + case GNSS_SYSTEM_GALILEO: + satellite->system = GNSS_SYSTEM_GALILEO; + break; + + case GNSS_SYSTEM_BEIDOU: + satellite->system = GNSS_SYSTEM_BEIDOU; + satellite->prn -= GNSS_NMEA0183_GSV_PRN_BEIDOU_OFFSET; + break; + + case GNSS_SYSTEM_QZSS: + satellite->system = GNSS_SYSTEM_QZSS; + break; + + case GNSS_SYSTEM_IRNSS: + case GNSS_SYSTEM_IMES: + case GNSS_SYSTEM_SBAS: + break; + } +} + +uint8_t gnss_nmea0183_checksum(const char *str) +{ + uint8_t checksum = 0; + size_t end; + + __ASSERT(str != NULL, "str argument must be provided"); + + end = strlen(str); + for (size_t i = 0; i < end; i++) { + checksum = checksum ^ str[i]; + } + + return checksum; +} + +int gnss_nmea0183_snprintk(char *str, size_t size, const char *fmt, ...) +{ + va_list ap; + uint8_t checksum; + int pos; + int len; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(fmt != NULL, "fmt argument must be provided"); + + if (size < GNSS_NMEA0183_MESSAGE_SIZE_MIN) { + return -ENOMEM; + } + + str[0] = '$'; + + va_start(ap, fmt); + pos = vsnprintk(&str[1], size - 1, fmt, ap) + 1; + va_end(ap); + + if (pos < 0) { + return -EINVAL; + } + + len = pos + GNSS_NMEA0183_MESSAGE_CHECKSUM_SIZE; + + if ((size - 1) < len) { + return -ENOMEM; + } + + checksum = gnss_nmea0183_checksum(&str[1]); + pos = snprintk(&str[pos], size - pos, "*%02X", checksum); + if (pos != 3) { + return -EINVAL; + } + + str[len] = '\0'; + return len; +} + +int gnss_nmea0183_ddmm_mmmm_to_ndeg(const char *ddmm_mmmm, int64_t *ndeg) +{ + uint64_t pico_degrees = 0; + int8_t decimal = -1; + int8_t pos = 0; + uint64_t increment; + + __ASSERT(ddmm_mmmm != NULL, "ddmm_mmmm argument must be provided"); + __ASSERT(ndeg != NULL, "ndeg argument must be provided"); + + /* Find decimal */ + while (ddmm_mmmm[pos] != '\0') { + /* Verify if char is decimal */ + if (ddmm_mmmm[pos] == '.') { + decimal = pos; + break; + } + + /* Advance position */ + pos++; + } + + /* Verify decimal was found and placed correctly */ + if (decimal < 1) { + return -EINVAL; + } + + /* Validate potential degree fraction is within bounds */ + if (decimal > 1 && ddmm_mmmm[decimal - 2] > '5') { + return -EINVAL; + } + + /* Convert minute fraction to pico degrees and add it to pico_degrees */ + pos = decimal + 1; + increment = (GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE / 10); + while (ddmm_mmmm[pos] != '\0') { + /* Verify char is decimal */ + if (ddmm_mmmm[pos] < '0' || ddmm_mmmm[pos] > '9') { + return -EINVAL; + } + + /* Add increment to pico_degrees */ + pico_degrees += (ddmm_mmmm[pos] - '0') * increment; + + /* Update unit */ + increment /= 10; + + /* Increment position */ + pos++; + } + + /* Convert minutes and degrees to pico_degrees */ + pos = decimal - 1; + increment = GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE; + while (pos >= 0) { + /* Check if digit switched from minutes to degrees */ + if ((decimal - pos) == 3) { + /* Reset increment to degrees */ + increment = GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE; + } + + /* Verify char is decimal */ + if (ddmm_mmmm[pos] < '0' || ddmm_mmmm[pos] > '9') { + return -EINVAL; + } + + /* Add increment to pico_degrees */ + pico_degrees += (ddmm_mmmm[pos] - '0') * increment; + + /* Update unit */ + increment *= 10; + + /* Decrement position */ + pos--; + } + + /* Convert to nano degrees */ + *ndeg = (int64_t)(pico_degrees / GNSS_NMEA0183_PICO_DEGREES_IN_NANO_DEGREE); + return 0; +} + +bool gnss_nmea0183_validate_message(char **argv, uint16_t argc) +{ + int32_t tmp = 0; + uint8_t checksum = 0; + size_t len; + + __ASSERT(argv != NULL, "argv argument must be provided"); + + /* Message must contain message id and checksum */ + if (argc < 2) { + return false; + } + + /* First argument should start with '$' which is not covered by checksum */ + if ((argc < 1) || (argv[0][0] != '$')) { + return false; + } + + len = strlen(argv[0]); + for (uint16_t u = 1; u < len; u++) { + checksum ^= argv[0][u]; + } + checksum ^= ','; + + /* Cover all except last argument which contains the checksum*/ + for (uint16_t i = 1; i < (argc - 1); i++) { + len = strlen(argv[i]); + for (uint16_t u = 0; u < len; u++) { + checksum ^= argv[i][u]; + } + checksum ^= ','; + } + + if ((gnss_parse_atoi(argv[argc - 1], 16, &tmp) < 0) || + (tmp > UINT8_MAX) || + (tmp < 0)) { + return false; + } + + return checksum == (uint8_t)tmp; +} + +int gnss_nmea0183_knots_to_mms(const char *str, int64_t *mms) +{ + int ret; + + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(mms != NULL, "mms argument must be provided"); + + ret = gnss_parse_dec_to_nano(str, mms); + if (ret < 0) { + return ret; + } + + *mms = (*mms) / GNSS_NMEA0183_NANO_KNOTS_IN_MMS; + return 0; +} + +int gnss_nmea0183_parse_hhmmss(const char *hhmmss, struct gnss_time *utc) +{ + int64_t i64; + int32_t i32; + char part[3] = {0}; + + __ASSERT(hhmmss != NULL, "hhmmss argument must be provided"); + __ASSERT(utc != NULL, "utc argument must be provided"); + + if (strlen(hhmmss) < 6) { + return -EINVAL; + } + + memcpy(part, hhmmss, 2); + if ((gnss_parse_atoi(part, 10, &i32) < 0) || + (i32 < 0) || + (i32 > 23)) { + return -EINVAL; + } + + utc->hour = (uint8_t)i32; + + memcpy(part, &hhmmss[2], 2); + if ((gnss_parse_atoi(part, 10, &i32) < 0) || + (i32 < 0) || + (i32 > 59)) { + return -EINVAL; + } + + utc->minute = (uint8_t)i32; + + if ((gnss_parse_dec_to_milli(&hhmmss[4], &i64) < 0) || + (i64 < 0) || + (i64 > 59999)) { + return -EINVAL; + } + + utc->millisecond = (uint16_t)i64; + return 0; +} + +int gnss_nmea0183_parse_ddmmyy(const char *ddmmyy, struct gnss_time *utc) +{ + int32_t i32; + char part[3] = {0}; + + __ASSERT(ddmmyy != NULL, "ddmmyy argument must be provided"); + __ASSERT(utc != NULL, "utc argument must be provided"); + + if (strlen(ddmmyy) != 6) { + return -EINVAL; + } + + memcpy(part, ddmmyy, 2); + if ((gnss_parse_atoi(part, 10, &i32) < 0) || + (i32 < 1) || + (i32 > 31)) { + return -EINVAL; + } + + utc->month_day = (uint8_t)i32; + + memcpy(part, &ddmmyy[2], 2); + if ((gnss_parse_atoi(part, 10, &i32) < 0) || + (i32 < 1) || + (i32 > 12)) { + return -EINVAL; + } + + utc->month = (uint8_t)i32; + + memcpy(part, &ddmmyy[4], 2); + if ((gnss_parse_atoi(part, 10, &i32) < 0) || + (i32 < 0) || + (i32 > 99)) { + return -EINVAL; + } + + utc->century_year = (uint8_t)i32; + return 0; +} + +int gnss_nmea0183_parse_rmc(const char **argv, uint16_t argc, struct gnss_data *data) +{ + int64_t tmp; + + __ASSERT(argv != NULL, "argv argument must be provided"); + __ASSERT(data != NULL, "data argument must be provided"); + + if (argc < 10) { + return -EINVAL; + } + + /* Validate GNSS has fix */ + if (argv[2][0] == 'V') { + return 0; + } + + if (argv[2][0] != 'A') { + return -EINVAL; + } + + /* Parse UTC time */ + if ((gnss_nmea0183_parse_hhmmss(argv[1], &data->utc) < 0)) { + return -EINVAL; + } + + /* Validate cardinal directions */ + if (((argv[4][0] != 'N') && (argv[4][0] != 'S')) || + ((argv[6][0] != 'E') && (argv[6][0] != 'W'))) { + return -EINVAL; + } + + /* Parse coordinates */ + if ((gnss_nmea0183_ddmm_mmmm_to_ndeg(argv[3], &data->nav_data.latitude) < 0) || + (gnss_nmea0183_ddmm_mmmm_to_ndeg(argv[5], &data->nav_data.longitude) < 0)) { + return -EINVAL; + } + + /* Align sign of coordinates with cardinal directions */ + data->nav_data.latitude = argv[4][0] == 'N' + ? data->nav_data.latitude + : -data->nav_data.latitude; + + data->nav_data.longitude = argv[6][0] == 'E' + ? data->nav_data.longitude + : -data->nav_data.longitude; + + /* Parse speed */ + if ((gnss_nmea0183_knots_to_mms(argv[7], &tmp) < 0) || + (tmp > UINT32_MAX)) { + return -EINVAL; + } + + data->nav_data.speed = (uint32_t)tmp; + + /* Parse bearing */ + if ((gnss_parse_dec_to_milli(argv[8], &tmp) < 0) || + (tmp > 359999) || + (tmp < 0)) { + return -EINVAL; + } + + data->nav_data.bearing = (uint32_t)tmp; + + /* Parse UTC date */ + if ((gnss_nmea0183_parse_ddmmyy(argv[9], &data->utc) < 0)) { + return -EINVAL; + } + + return 0; +} + +static int parse_gga_fix_quality(const char *str, enum gnss_fix_quality *fix_quality) +{ + __ASSERT(str != NULL, "str argument must be provided"); + __ASSERT(fix_quality != NULL, "fix_quality argument must be provided"); + + if ((str[1] != ((char)'\0')) || (str[0] < ((char)'0')) || (((char)'6') < str[0])) { + return -EINVAL; + } + + (*fix_quality) = (enum gnss_fix_quality)(str[0] - ((char)'0')); + return 0; +} + +static enum gnss_fix_status fix_status_from_fix_quality(enum gnss_fix_quality fix_quality) +{ + enum gnss_fix_status fix_status = GNSS_FIX_STATUS_NO_FIX; + + switch (fix_quality) { + case GNSS_FIX_QUALITY_GNSS_SPS: + case GNSS_FIX_QUALITY_GNSS_PPS: + fix_status = GNSS_FIX_STATUS_GNSS_FIX; + break; + + case GNSS_FIX_QUALITY_DGNSS: + case GNSS_FIX_QUALITY_RTK: + case GNSS_FIX_QUALITY_FLOAT_RTK: + fix_status = GNSS_FIX_STATUS_DGNSS_FIX; + break; + + case GNSS_FIX_QUALITY_ESTIMATED: + fix_status = GNSS_FIX_STATUS_ESTIMATED_FIX; + break; + + default: + break; + } + + return fix_status; +} + +int gnss_nmea0183_parse_gga(const char **argv, uint16_t argc, struct gnss_data *data) +{ + int32_t tmp32; + int64_t tmp64; + + __ASSERT(argv != NULL, "argv argument must be provided"); + __ASSERT(data != NULL, "data argument must be provided"); + + if (argc < 12) { + return -EINVAL; + } + + /* Parse fix quality and status */ + if (parse_gga_fix_quality(argv[6], &data->info.fix_quality) < 0) { + return -EINVAL; + } + + data->info.fix_status = fix_status_from_fix_quality(data->info.fix_quality); + + /* Validate GNSS has fix */ + if (data->info.fix_status == GNSS_FIX_STATUS_NO_FIX) { + return 0; + } + + /* Parse number of satellites */ + if ((gnss_parse_atoi(argv[7], 10, &tmp32) < 0) || + (tmp32 > UINT16_MAX) || + (tmp32 < 0)) { + return -EINVAL; + } + + data->info.satellites_cnt = (uint16_t)tmp32; + + /* Parse HDOP */ + if ((gnss_parse_dec_to_milli(argv[8], &tmp64) < 0) || + (tmp64 > UINT16_MAX) || + (tmp64 < 0)) { + return -EINVAL; + } + + data->info.hdop = (uint16_t)tmp64; + + /* Parse altitude */ + if ((gnss_parse_dec_to_milli(argv[11], &tmp64) < 0) || + (tmp64 > INT32_MAX) || + (tmp64 < INT32_MIN)) { + return -EINVAL; + } + + data->nav_data.altitude = (int32_t)tmp64; + return 0; +} + +static int parse_gsv_svs(struct gnss_satellite *satellites, const struct gsv_sv_args *svs, + uint16_t svs_size) +{ + int32_t i32; + + for (uint16_t i = 0; i < svs_size; i++) { + /* Parse PRN */ + if ((gnss_parse_atoi(svs[i].prn, 10, &i32) < 0) || + (i32 < 0) || (i32 > UINT16_MAX)) { + return -EINVAL; + } + + satellites[i].prn = (uint16_t)i32; + + /* Parse elevation */ + if ((gnss_parse_atoi(svs[i].elevation, 10, &i32) < 0) || + (i32 < 0) || (i32 > 90)) { + return -EINVAL; + } + + satellites[i].elevation = (uint8_t)i32; + + /* Parse azimuth */ + if ((gnss_parse_atoi(svs[i].azimuth, 10, &i32) < 0) || + (i32 < 0) || (i32 > 359)) { + return -EINVAL; + } + + satellites[i].azimuth = (uint16_t)i32; + + /* Parse SNR */ + if (strlen(svs[i].snr) == 0) { + satellites[i].snr = 0; + satellites[i].is_tracked = false; + continue; + } + + if ((gnss_parse_atoi(svs[i].snr, 10, &i32) < 0) || + (i32 < 0) || (i32 > 99)) { + return -EINVAL; + } + + satellites[i].snr = (uint16_t)i32; + satellites[i].is_tracked = true; + } + + return 0; +} + +int gnss_nmea0183_parse_gsv_header(const char **argv, uint16_t argc, + struct gnss_nmea0183_gsv_header *header) +{ + const struct gsv_header_args *args = (const struct gsv_header_args *)argv; + int i32; + + __ASSERT(argv != NULL, "argv argument must be provided"); + __ASSERT(header != NULL, "header argument must be provided"); + + if (argc < 4) { + return -EINVAL; + } + + /* Parse GNSS sv_system */ + if (gnss_system_from_gsv_header_args(args, &header->system) < 0) { + return -EINVAL; + } + + /* Parse number of messages */ + if ((gnss_parse_atoi(args->number_of_messages, 10, &i32) < 0) || + (i32 < 0) || (i32 > UINT16_MAX)) { + return -EINVAL; + } + + header->number_of_messages = (uint16_t)i32; + + /* Parse message number */ + if ((gnss_parse_atoi(args->message_number, 10, &i32) < 0) || + (i32 < 0) || (i32 > UINT16_MAX)) { + return -EINVAL; + } + + header->message_number = (uint16_t)i32; + + /* Parse message number */ + if ((gnss_parse_atoi(args->numver_of_svs, 10, &i32) < 0) || + (i32 < 0) || (i32 > UINT16_MAX)) { + return -EINVAL; + } + + header->number_of_svs = (uint16_t)i32; + return 0; +} + +int gnss_nmea0183_parse_gsv_svs(const char **argv, uint16_t argc, + struct gnss_satellite *satellites, uint16_t size) +{ + const struct gsv_header_args *header_args = (const struct gsv_header_args *)argv; + const struct gsv_sv_args *sv_args = (const struct gsv_sv_args *)(argv + 4); + uint16_t sv_args_size; + enum gnss_system sv_system; + + __ASSERT(argv != NULL, "argv argument must be provided"); + __ASSERT(satellites != NULL, "satellites argument must be provided"); + + if (argc < 9) { + return 0; + } + + sv_args_size = (argc - GNSS_NMEA0183_GSV_HDR_ARG_CNT) / GNSS_NMEA0183_GSV_SV_ARG_CNT; + + if (size < sv_args_size) { + return -ENOMEM; + } + + if (parse_gsv_svs(satellites, sv_args, sv_args_size) < 0) { + return -EINVAL; + } + + if (gnss_system_from_gsv_header_args(header_args, &sv_system) < 0) { + return -EINVAL; + } + + for (uint16_t i = 0; i < sv_args_size; i++) { + align_satellite_with_gnss_system(sv_system, &satellites[i]); + } + + return (int)sv_args_size; +} diff --git a/drivers/gnss/gnss_nmea0183.h b/drivers/gnss/gnss_nmea0183.h new file mode 100644 index 00000000000..6a3fa177f44 --- /dev/null +++ b/drivers/gnss/gnss_nmea0183.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_H_ + +#include + +/** + * @brief Compute NMEA0183 checksum + * + * @example "PAIR002" -> 0x38 + * + * @param str String from which checksum is computed + * + * @retval checksum + */ +uint8_t gnss_nmea0183_checksum(const char *str); + +/** + * @brief Encapsulate str in NMEA0183 message format + * + * @example "PAIR%03u", 2 -> "$PAIR002*38" + * + * @param str Destination for encapsulated string + * @param size Size of destination for encapsulated string + * @param fmt Format of string to encapsulate + * @param ... Arguments + * + * @retval checksum + */ +int gnss_nmea0183_snprintk(char *str, size_t size, const char *fmt, ...); + +/** + * @brief Computes and validates checksum + * + * @param argv Array of arguments split by ',' including message id and checksum + * @param argc Number of arguments in argv + * + * @retval true if message is intact + * @retval false if message is corrupted + */ +bool gnss_nmea0183_validate_message(char **argv, uint16_t argc); + +/** + * @brief Parse a ddmm.mmmm formatted angle to nano degrees + * + * @example "5610.9928" -> 56183214000 + * + * @param ddmm_mmmm String representation of angle in ddmm.mmmm format + * @param ndeg Result in nano degrees + * + * @retval -EINVAL if ddmm_mmmm argument is invalid + * @retval 0 if parsed successfully + */ +int gnss_nmea0183_ddmm_mmmm_to_ndeg(const char *ddmm_mmmm, int64_t *ndeg); + +/** + * @brief Parse knots to millimeters pr second + * + * @example "15.231" -> 7835 + * + * @param str String representation of speed in knots + * @param mms Destination for speed in millimeters pr second + * + * @retval -EINVAL if str could not be parsed or if speed is negative + * @retval 0 if parsed successfully + */ +int gnss_nmea0183_knots_to_mms(const char *str, int64_t *mms); + +/** + * @brief Parse hhmmss.sss to struct gnss_time + * + * @example "133243.012" -> { .hour = 13, .minute = 32, .ms = 43012 } + * @example "133243" -> { .hour = 13, .minute = 32, .ms = 43000 } + * + * @param str String representation of hours, minutes, seconds and subseconds + * @param utc Destination for parsed time + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if parsed successfully + */ +int gnss_nmea0183_parse_hhmmss(const char *hhmmss, struct gnss_time *utc); + +/** + * @brief Parse ddmmyy to unsigned integers + * + * @example "041122" -> { .mday = 4, .month = 11, .year = 22 } + * + * @param str String representation of speed in knots + * @param utc Destination for parsed time + * + * @retval -EINVAL if str could not be parsed + * @retval 0 if parsed successfully + */ +int gnss_nmea0183_parse_ddmmyy(const char *ddmmyy, struct gnss_time *utc); + +/** + * @brief Parses NMEA0183 RMC message + * + * @details Parses the time, date, latitude, longitude, speed, and bearing + * from the NMEA0183 RMC message provided as an array of strings split by ',' + * + * @param argv Array of arguments split by ',' including message id and checksum + * @param argc Number of arguments in argv' + * @param data Destination for data parsed from NMEA0183 RMC message + * + * @retval 0 if successful + * @retval -EINVAL if input is invalid + */ +int gnss_nmea0183_parse_rmc(const char **argv, uint16_t argc, struct gnss_data *data); + +/** + * @brief Parses NMEA0183 GGA message + * + * @details Parses the GNSS fix quality and status, number of satellites used for + * fix, HDOP, and altitude (geoid separation) from the NMEA0183 GGA message provided + * as an array of strings split by ',' + * + * @param argv Array of arguments split by ',' including message id and checksum + * @param argc Number of arguments in argv' + * @param data Destination for data parsed from NMEA0183 GGA message + * + * @retval 0 if successful + * @retval -EINVAL if input is invalid + */ +int gnss_nmea0183_parse_gga(const char **argv, uint16_t argc, struct gnss_data *data); + +/** GSV header structure */ +struct gnss_nmea0183_gsv_header { + /** Indicates the system of the space-vehicles contained in the message */ + enum gnss_system system; + /** Number of GSV messages in total */ + uint16_t number_of_messages; + /** Number of this GSV message */ + uint16_t message_number; + /** Number of visible space-vehicles */ + uint16_t number_of_svs; +}; + +/** + * @brief Parses header of NMEA0183 GSV message + * + * @details The GSV messages are part of a list of messages sent in ascending + * order, split by GNSS system. + * + * @param argv Array of arguments split by ',' including message id and checksum + * @param argc Number of arguments in argv + * @param header Destination for parsed NMEA0183 GGA message header + * + * @retval 0 if successful + * @retval -EINVAL if input is invalid + */ +int gnss_nmea0183_parse_gsv_header(const char **argv, uint16_t argc, + struct gnss_nmea0183_gsv_header *header); + +/** + * @brief Parses space-vehicles in NMEA0183 GSV message + * + * @details The NMEA0183 GSV message contains up to 4 space-vehicles which follow + * the header. + * + * @param argv Array of arguments split by ',' including message id and checksum + * @param argc Number of arguments in argv + * @param satellites Destination for parsed satellites from NMEA0183 GGA message + * @param size Size of destination for parsed satellites from NMEA0183 GGA message + * + * @retval Number of parsed space-vehicles stored at destination if successful + * @retval -ENOMEM if all space-vehicles in message could not be stored at destination + * @retval -EINVAL if input is invalid + */ +int gnss_nmea0183_parse_gsv_svs(const char **argv, uint16_t argc, + struct gnss_satellite *satellites, uint16_t size); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_H_ */ diff --git a/tests/drivers/gnss/gnss_nmea0183/CMakeLists.txt b/tests/drivers/gnss/gnss_nmea0183/CMakeLists.txt new file mode 100644 index 00000000000..73183c90acc --- /dev/null +++ b/tests/drivers/gnss/gnss_nmea0183/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(gnss_nmea0183) + +target_sources(app PRIVATE + src/main.c +) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers/gnss) diff --git a/tests/drivers/gnss/gnss_nmea0183/prj.conf b/tests/drivers/gnss/gnss_nmea0183/prj.conf new file mode 100644 index 00000000000..d2cc9d2b645 --- /dev/null +++ b/tests/drivers/gnss/gnss_nmea0183/prj.conf @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GNSS=y +CONFIG_GNSS_NMEA0183=y +CONFIG_ZTEST=y +CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/drivers/gnss/gnss_nmea0183/src/main.c b/tests/drivers/gnss/gnss_nmea0183/src/main.c new file mode 100644 index 00000000000..680382f7dbc --- /dev/null +++ b/tests/drivers/gnss/gnss_nmea0183/src/main.c @@ -0,0 +1,739 @@ +/* + * Copyright 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "gnss_nmea0183.h" + +#define TEST_DDMM_MMMM_MAX_ROUNDING_ERROR_NDEG (1) + +struct test_ddmm_mmmm_sample { + const char *ddmm_mmmm; + int64_t ndeg; +}; + +/* + * The conversion from ddmm.mmmm to decimal nano degree is + * ((1/60) * mm.mmmm * 1E9) + (dd * 1E9) + */ +static const struct test_ddmm_mmmm_sample ddmm_mmmm_samples[] = { + {.ddmm_mmmm = "00.0", .ndeg = 0}, + {.ddmm_mmmm = "000.0", .ndeg = 0}, + {.ddmm_mmmm = "9000.0000", .ndeg = 90000000000}, + {.ddmm_mmmm = "4530.0000", .ndeg = 45500000000}, + {.ddmm_mmmm = "4530.3000", .ndeg = 45505000000}, + {.ddmm_mmmm = "4530.3001", .ndeg = 45505001667}, + {.ddmm_mmmm = "4530.9999", .ndeg = 45516665000}, + {.ddmm_mmmm = "18000.0000", .ndeg = 180000000000} +}; + +ZTEST(gnss_nmea0183, test_ddmm_mmmm) +{ + int64_t min_ndeg; + int64_t max_ndeg; + int64_t ndeg; + + for (size_t i = 0; i < ARRAY_SIZE(ddmm_mmmm_samples); i++) { + zassert_ok(gnss_nmea0183_ddmm_mmmm_to_ndeg(ddmm_mmmm_samples[i].ddmm_mmmm, &ndeg), + "Parse failed"); + + min_ndeg = ddmm_mmmm_samples[i].ndeg - TEST_DDMM_MMMM_MAX_ROUNDING_ERROR_NDEG; + max_ndeg = ddmm_mmmm_samples[i].ndeg + TEST_DDMM_MMMM_MAX_ROUNDING_ERROR_NDEG; + zassert_true(ndeg >= min_ndeg, "Parsed value falls below max rounding error"); + zassert_true(ndeg <= max_ndeg, "Parsed value is above max rounding error"); + } + + /* Minutes can only go from 0 to 59.9999 */ + zassert_equal(gnss_nmea0183_ddmm_mmmm_to_ndeg("99.0000", &ndeg), -EINVAL, + "Parse should fail"); + + zassert_equal(gnss_nmea0183_ddmm_mmmm_to_ndeg("60.0000", &ndeg), -EINVAL, + "Parse should fail"); + + /* Missing dot */ + zassert_equal(gnss_nmea0183_ddmm_mmmm_to_ndeg("18000", &ndeg), -EINVAL, + "Parse should fail"); + + /* Invalid chars */ + zassert_equal(gnss_nmea0183_ddmm_mmmm_to_ndeg("900#.0a000", &ndeg), -EINVAL, + "Parse should fail"); + + /* Negative angle */ + zassert_equal(gnss_nmea0183_ddmm_mmmm_to_ndeg("-18000.0", &ndeg), -EINVAL, + "Parse should fail"); +} + +struct test_knots_to_mms_sample { + const char *str; + int64_t value; +}; + +static const struct test_knots_to_mms_sample knots_to_mms_samples[] = { + {.str = "1", .value = 514}, + {.str = "2.2", .value = 1131}, + {.str = "003241.12543", .value = 1667364} +}; + +ZTEST(gnss_nmea0183, test_knots_to_mms) +{ + int64_t mms; + + for (size_t i = 0; i < ARRAY_SIZE(knots_to_mms_samples); i++) { + zassert_ok(gnss_nmea0183_knots_to_mms(knots_to_mms_samples[i].str, &mms), + "Parse failed"); + + zassert_equal(knots_to_mms_samples[i].value, mms, + "Parsed value falls below max rounding error"); + } +} + +struct test_hhmmss_sample { + const char *str; + uint8_t hour; + uint8_t minute; + uint16_t millisecond; +}; + +static const struct test_hhmmss_sample hhmmss_samples[] = { + {.str = "000102", .hour = 0, .minute = 1, .millisecond = 2000}, + {.str = "235959.999", .hour = 23, .minute = 59, .millisecond = 59999}, + {.str = "000000.0", .hour = 0, .minute = 0, .millisecond = 0} +}; + +ZTEST(gnss_nmea0183, test_hhmmss) +{ + struct gnss_time utc; + int ret; + + for (size_t i = 0; i < ARRAY_SIZE(hhmmss_samples); i++) { + zassert_ok(gnss_nmea0183_parse_hhmmss(hhmmss_samples[i].str, &utc), + "Parse failed"); + + zassert_equal(hhmmss_samples[i].hour, utc.hour, "Failed to parse hour"); + zassert_equal(hhmmss_samples[i].minute, utc.minute, "Failed to parse minute"); + zassert_equal(hhmmss_samples[i].millisecond, utc.millisecond, + "Failed to parse millisecond"); + } + + ret = gnss_nmea0183_parse_hhmmss("-101010", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_hhmmss("01010", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_hhmmss("246060.999", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_hhmmss("99a9c9", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_hhmmss("12121212", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); +} + +struct test_ddmmyy_sample { + const char *str; + uint8_t month_day; + uint8_t month; + uint16_t century_year; +}; + +static const struct test_ddmmyy_sample ddmmyy_samples[] = { + {.str = "010203", .month_day = 1, .month = 2, .century_year = 3}, + {.str = "311299", .month_day = 31, .month = 12, .century_year = 99}, + {.str = "010100", .month_day = 1, .month = 1, .century_year = 0} +}; + +ZTEST(gnss_nmea0183, test_ddmmyy) +{ + struct gnss_time utc; + int ret; + + for (size_t i = 0; i < ARRAY_SIZE(ddmmyy_samples); i++) { + zassert_ok(gnss_nmea0183_parse_ddmmyy(ddmmyy_samples[i].str, &utc), + "Parse failed"); + + zassert_equal(ddmmyy_samples[i].month_day, utc.month_day, + "Failed to parse monthday"); + + zassert_equal(ddmmyy_samples[i].month, utc.month, "Failed to parse month"); + zassert_equal(ddmmyy_samples[i].century_year, utc.century_year, + "Failed to parse year"); + } + + ret = gnss_nmea0183_parse_ddmmyy("000000", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_ddmmyy("-12123", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_ddmmyy("01010", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_ddmmyy("999999", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_ddmmyy("99a9c9", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); + + ret = gnss_nmea0183_parse_ddmmyy("12121212", &utc); + zassert_equal(ret, -EINVAL, "Should fail to parse invalid value"); +} + +/* "$GNRMC,160833.099,V,,,,,,,090923,,,N,V*27" */ +const char *rmc_argv_no_fix[15] = { + "$GNRMC", + "160833.099", + "V", + "", + "", + "", + "", + "", + "", + "090923", + "", + "", + "N", + "V", + "27" +}; + +static struct gnss_data data; + +ZTEST(gnss_nmea0183, test_parse_rmc_no_fix) +{ + int ret; + + /* Corrupt data */ + memset(&data, 0xFF, sizeof(data)); + + ret = gnss_nmea0183_parse_rmc(rmc_argv_no_fix, ARRAY_SIZE(rmc_argv_no_fix), &data); + zassert_ok(ret, "NMEA0183 RMC message parse should succeed"); +} + +/* "$GNGGA,160834.099,,,,,0,0,,,M,,M,,*5E" */ +const char *gga_argv_no_fix[16] = { + "$GNGGA", + "160834.099", + "", + "", + "", + "", + "0", + "0", + "", + "", + "M", + "", + "M", + "", + "5E" +}; + +ZTEST(gnss_nmea0183, test_parse_gga_no_fix) +{ + int ret; + + /* Corrupt data */ + memset(&data, 0xFF, sizeof(data)); + + ret = gnss_nmea0183_parse_gga(gga_argv_no_fix, ARRAY_SIZE(gga_argv_no_fix), &data); + zassert_ok(ret, "NMEA0183 GGA message parse should succeed"); + zassert_equal(data.info.fix_quality, GNSS_FIX_QUALITY_INVALID, + "Incorrectly parsed fix quality"); + + zassert_equal(data.info.fix_status, GNSS_FIX_STATUS_NO_FIX, + "Incorrectly parsed fix status"); +} + +/* "$GNRMC,160849.000,A,5709.736602,N,00957.660738,E,0.33,0.00,090923,,,A,V*03" */ +const char *rmc_argv_fix[15] = { + "$GNRMC", + "160849.000", + "A", + "5709.736602", + "N", + "00957.660738", + "E", + "0.33", + "33.31", + "090923", + "", + "", + "A", + "V", + "03", +}; + +ZTEST(gnss_nmea0183, test_parse_rmc_fix) +{ + int ret; + + /* Corrupt data */ + memset(&data, 0xFF, sizeof(data)); + + ret = gnss_nmea0183_parse_rmc(rmc_argv_fix, ARRAY_SIZE(rmc_argv_fix), &data); + zassert_ok(ret, "NMEA0183 RMC message parse should succeed"); + zassert_equal(data.nav_data.latitude, 57162276699, "Incorrectly parsed latitude"); + zassert_equal(data.nav_data.longitude, 9961012299, "Incorrectly parsed longitude"); + zassert_equal(data.nav_data.speed, 169, "Incorrectly parsed speed"); + zassert_equal(data.nav_data.bearing, 33310, "Incorrectly parsed speed"); + zassert_equal(data.utc.hour, 16, "Incorrectly parsed hour"); + zassert_equal(data.utc.minute, 8, "Incorrectly parsed minute"); + zassert_equal(data.utc.millisecond, 49000, "Incorrectly parsed millisecond"); + zassert_equal(data.utc.month_day, 9, "Incorrectly parsed month day"); + zassert_equal(data.utc.month, 9, "Incorrectly parsed month"); + zassert_equal(data.utc.century_year, 23, "Incorrectly parsed century year"); +} + +/* "$GNGGA,160858.000,5709.734778,N,00957.659514,E,1,6,1.41,15.234,M,42.371,M,,*72" */ +const char *gga_argv_fix[16] = { + "$GNGGA", + "160858.000", + "5709.734778", + "N", + "00957.659514", + "E", + "1", + "6", + "1.41", + "15.234", + "M", + "42.371", + "M", + "", + "", + "72", +}; + +ZTEST(gnss_nmea0183, test_parse_gga_fix) +{ + int ret; + + /* Corrupt data */ + memset(&data, 0xFF, sizeof(data)); + + ret = gnss_nmea0183_parse_gga(gga_argv_fix, ARRAY_SIZE(gga_argv_fix), &data); + zassert_ok(ret, "NMEA0183 GGA message parse should succeed"); + zassert_equal(data.info.fix_quality, GNSS_FIX_QUALITY_GNSS_SPS, + "Incorrectly parsed fix quality"); + + zassert_equal(data.info.fix_status, GNSS_FIX_STATUS_GNSS_FIX, + "Incorrectly parsed fix status"); + + zassert_equal(data.info.satellites_cnt, 6, + "Incorrectly parsed number of satelites"); + + zassert_equal(data.info.hdop, 1410, "Incorrectly parsed HDOP"); + zassert_equal(data.nav_data.altitude, 42371, "Incorrectly parsed altitude"); +} + +ZTEST(gnss_nmea0183, test_snprintk) +{ + int ret; + char buf[sizeof("$PAIR002,3*27")]; + + ret = gnss_nmea0183_snprintk(buf, sizeof(buf), "PAIR%03u,%u", 2, 3); + zassert_equal(ret, (sizeof("$PAIR002,3*27") - 1), "Failed to format NMEA0183 message"); + zassert_ok(strcmp(buf, "$PAIR002,3*27"), "Incorrectly formatted NMEA0183 message"); + + ret = gnss_nmea0183_snprintk(buf, sizeof(buf) - 1, "PAIR%03u,%u", 2, 3); + zassert_equal(ret, -ENOMEM, "Should fail with -ENOMEM as buffer is too small"); +} + +/* $GPGSV,8,1,25,21,44,141,47,15,14,049,44,6,31,255,46,3,25,280,44*75 */ +const char *gpgsv_8_1_25[21] = { + "$GPGSV", + "8", + "1", + "25", + "21", + "44", + "141", + "47", + "15", + "14", + "049", + "44", + "6", + "31", + "255", + "46", + "3", + "25", + "280", + "44", + "75", +}; + +static const struct gnss_nmea0183_gsv_header gpgsv_8_1_25_header = { + .system = GNSS_SYSTEM_GPS, + .number_of_messages = 8, + .message_number = 1, + .number_of_svs = 25 +}; + +static const struct gnss_satellite gpgsv_8_1_25_sats[] = { + {.prn = 21, .elevation = 44, .azimuth = 141, .snr = 47, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 15, .elevation = 14, .azimuth = 49, .snr = 44, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 6, .elevation = 31, .azimuth = 255, .snr = 46, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 3, .elevation = 25, .azimuth = 280, .snr = 44, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, +}; + +/* $GPGSV,8,2,25,18,61,057,48,22,68,320,52,27,34,268,47,24,32,076,45*76 */ +const char *gpgsv_8_2_25[21] = { + "$GPGSV", + "8", + "2", + "25", + "18", + "61", + "057", + "48", + "22", + "68", + "320", + "52", + "27", + "34", + "268", + "47", + "24", + "32", + "076", + "45", + "76", +}; + +static const struct gnss_nmea0183_gsv_header gpgsv_8_2_25_header = { + .system = GNSS_SYSTEM_GPS, + .number_of_messages = 8, + .message_number = 2, + .number_of_svs = 25 +}; + +static const struct gnss_satellite gpgsv_8_2_25_sats[] = { + {.prn = 18, .elevation = 61, .azimuth = 57, .snr = 48, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 22, .elevation = 68, .azimuth = 320, .snr = 52, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 27, .elevation = 34, .azimuth = 268, .snr = 47, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 24, .elevation = 32, .azimuth = 76, .snr = 45, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, +}; + +/* $GPGSV,8,3,25,14,51,214,49,19,23,308,46*7E */ +const char *gpgsv_8_3_25[13] = { + "$GPGSV", + "8", + "3", + "25", + "14", + "51", + "214", + "49", + "19", + "23", + "308", + "46", + "7E", +}; + +static const struct gnss_nmea0183_gsv_header gpgsv_8_3_25_header = { + .system = GNSS_SYSTEM_GPS, + .number_of_messages = 8, + .message_number = 3, + .number_of_svs = 25 +}; + +static const struct gnss_satellite gpgsv_8_3_25_sats[] = { + {.prn = 14, .elevation = 51, .azimuth = 214, .snr = 49, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, + {.prn = 19, .elevation = 23, .azimuth = 308, .snr = 46, + .system = GNSS_SYSTEM_GPS, .is_tracked = true}, +}; + +/* $GPGSV,8,4,25,51,44,183,49,46,41,169,43,48,36,220,45*47 */ +const char *gpgsv_8_4_25[17] = { + "$GPGSV", + "8", + "4", + "25", + "51", + "44", + "183", + "49", + "46", + "41", + "169", + "43", + "48", + "36", + "220", + "45", + "47", +}; + +static const struct gnss_nmea0183_gsv_header gpgsv_8_4_25_header = { + .system = GNSS_SYSTEM_GPS, + .number_of_messages = 8, + .message_number = 4, + .number_of_svs = 25 +}; + +static const struct gnss_satellite gpgsv_8_4_25_sats[] = { + {.prn = (51 + 87), .elevation = 44, .azimuth = 183, .snr = 49, + .system = GNSS_SYSTEM_SBAS, .is_tracked = true}, + {.prn = (46 + 87), .elevation = 41, .azimuth = 169, .snr = 43, + .system = GNSS_SYSTEM_SBAS, .is_tracked = true}, + {.prn = (48 + 87), .elevation = 36, .azimuth = 220, .snr = 45, + .system = GNSS_SYSTEM_SBAS, .is_tracked = true}, +}; + +/* $GLGSV,8,5,25,82,49,219,52,76,22,051,41,83,37,316,51,67,57,010,51*6C */ +const char *glgsv_8_5_25[21] = { + "$GLGSV", + "8", + "5", + "25", + "82", + "49", + "219", + "52", + "76", + "22", + "051", + "41", + "83", + "37", + "316", + "51", + "67", + "57", + "010", + "51", + "6C", +}; + +static const struct gnss_nmea0183_gsv_header glgsv_8_5_25_header = { + .system = GNSS_SYSTEM_GLONASS, + .number_of_messages = 8, + .message_number = 5, + .number_of_svs = 25 +}; + +static const struct gnss_satellite glgsv_8_5_25_sats[] = { + {.prn = (82 - 64), .elevation = 49, .azimuth = 219, .snr = 52, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (76 - 64), .elevation = 22, .azimuth = 51, .snr = 41, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (83 - 64), .elevation = 37, .azimuth = 316, .snr = 51, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (67 - 64), .elevation = 57, .azimuth = 10, .snr = 51, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, +}; + +/* $GLGSV,8,6,25,77,24,108,44,81,10,181,46,78,1,152,34,66,18,060,45*50 */ +const char *glgsv_8_6_25[21] = { + "$GLGSV", + "8", + "6", + "25", + "77", + "24", + "108", + "44", + "81", + "10", + "181", + "46", + "78", + "1", + "152", + "34", + "66", + "18", + "060", + "45", + "50", +}; + +static const struct gnss_nmea0183_gsv_header glgsv_8_6_25_header = { + .system = GNSS_SYSTEM_GLONASS, + .number_of_messages = 8, + .message_number = 6, + .number_of_svs = 25 +}; + +static const struct gnss_satellite glgsv_8_6_25_sats[] = { + {.prn = (77 - 64), .elevation = 24, .azimuth = 108, .snr = 44, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (81 - 64), .elevation = 10, .azimuth = 181, .snr = 46, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (78 - 64), .elevation = 1, .azimuth = 152, .snr = 34, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, + {.prn = (66 - 64), .elevation = 18, .azimuth = 60, .snr = 45, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, +}; + +/* $GLGSV,8,7,25,68,37,284,50*5C */ +const char *glgsv_8_7_25[9] = { + "$GLGSV", + "8", + "7", + "25", + "68", + "37", + "284", + "50", + "5C", +}; + +static const struct gnss_nmea0183_gsv_header glgsv_8_7_25_header = { + .system = GNSS_SYSTEM_GLONASS, + .number_of_messages = 8, + .message_number = 7, + .number_of_svs = 25 +}; + +static const struct gnss_satellite glgsv_8_7_25_sats[] = { + {.prn = (68 - 64), .elevation = 37, .azimuth = 284, .snr = 50, + .system = GNSS_SYSTEM_GLONASS, .is_tracked = true}, +}; + +/* $GBGSV,8,8,25,111,35,221,47,112,4,179,39,114,48,290,48*11 */ +const char *gbgsv_8_8_25[17] = { + "$GBGSV", + "8", + "8", + "25", + "111", + "35", + "221", + "47", + "112", + "4", + "179", + "39", + "114", + "48", + "290", + "48", + "11", +}; + +static const struct gnss_nmea0183_gsv_header gbgsv_8_8_25_header = { + .system = GNSS_SYSTEM_BEIDOU, + .number_of_messages = 8, + .message_number = 8, + .number_of_svs = 25 +}; + +static const struct gnss_satellite gbgsv_8_8_25_sats[] = { + {.prn = (111 - 100), .elevation = 35, .azimuth = 221, .snr = 47, + .system = GNSS_SYSTEM_BEIDOU, .is_tracked = true}, + {.prn = (112 - 100), .elevation = 4, .azimuth = 179, .snr = 39, + .system = GNSS_SYSTEM_BEIDOU, .is_tracked = true}, + {.prn = (114 - 100), .elevation = 48, .azimuth = 290, .snr = 48, + .system = GNSS_SYSTEM_BEIDOU, .is_tracked = true}, +}; + +struct test_gsv_sample { + const char **argv; + uint16_t argc; + const struct gnss_nmea0183_gsv_header *header; + const struct gnss_satellite *satellites; + uint16_t number_of_svs; +}; + +static const struct test_gsv_sample gsv_samples[] = { + {.argv = gpgsv_8_1_25, .argc = ARRAY_SIZE(gpgsv_8_1_25), .header = &gpgsv_8_1_25_header, + .satellites = gpgsv_8_1_25_sats, .number_of_svs = ARRAY_SIZE(gpgsv_8_1_25_sats)}, + {.argv = gpgsv_8_2_25, .argc = ARRAY_SIZE(gpgsv_8_2_25), .header = &gpgsv_8_2_25_header, + .satellites = gpgsv_8_2_25_sats, .number_of_svs = ARRAY_SIZE(gpgsv_8_2_25_sats)}, + {.argv = gpgsv_8_3_25, .argc = ARRAY_SIZE(gpgsv_8_3_25), .header = &gpgsv_8_3_25_header, + .satellites = gpgsv_8_3_25_sats, .number_of_svs = ARRAY_SIZE(gpgsv_8_3_25_sats)}, + {.argv = gpgsv_8_4_25, .argc = ARRAY_SIZE(gpgsv_8_4_25), .header = &gpgsv_8_4_25_header, + .satellites = gpgsv_8_4_25_sats, .number_of_svs = ARRAY_SIZE(gpgsv_8_4_25_sats)}, + {.argv = glgsv_8_5_25, .argc = ARRAY_SIZE(glgsv_8_5_25), .header = &glgsv_8_5_25_header, + .satellites = glgsv_8_5_25_sats, .number_of_svs = ARRAY_SIZE(glgsv_8_5_25_sats)}, + {.argv = glgsv_8_6_25, .argc = ARRAY_SIZE(glgsv_8_6_25), .header = &glgsv_8_6_25_header, + .satellites = glgsv_8_6_25_sats, .number_of_svs = ARRAY_SIZE(glgsv_8_6_25_sats)}, + {.argv = glgsv_8_7_25, .argc = ARRAY_SIZE(glgsv_8_7_25), .header = &glgsv_8_7_25_header, + .satellites = glgsv_8_7_25_sats, .number_of_svs = ARRAY_SIZE(glgsv_8_7_25_sats)}, + {.argv = gbgsv_8_8_25, .argc = ARRAY_SIZE(gbgsv_8_8_25), .header = &gbgsv_8_8_25_header, + .satellites = gbgsv_8_8_25_sats, .number_of_svs = ARRAY_SIZE(gbgsv_8_8_25_sats)}, +}; + +ZTEST(gnss_nmea0183, test_gsv_parse_headers) +{ + struct gnss_nmea0183_gsv_header header; + int ret; + + for (uint16_t i = 0; i < ARRAY_SIZE(gsv_samples); i++) { + ret = gnss_nmea0183_parse_gsv_header(gsv_samples[i].argv, gsv_samples[i].argc, + &header); + + zassert_ok(ret, "Failed to parse GSV header"); + + zassert_equal(header.system, gsv_samples[i].header->system, + "Failed to parse GNSS system"); + + zassert_equal(header.number_of_messages, + gsv_samples[i].header->number_of_messages, + "Failed to parse number of messages"); + + zassert_equal(header.message_number, gsv_samples[i].header->message_number, + "Failed to parse message number"); + + zassert_equal(header.number_of_svs, gsv_samples[i].header->number_of_svs, + "Failed to parse number of space vehicles"); + } +} + +ZTEST(gnss_nmea0183, test_gsv_parse_satellites) +{ + struct gnss_satellite satellites[4]; + int ret; + + for (uint16_t i = 0; i < ARRAY_SIZE(gsv_samples); i++) { + ret = gnss_nmea0183_parse_gsv_svs(gsv_samples[i].argv, gsv_samples[i].argc, + satellites, ARRAY_SIZE(satellites)); + + zassert_equal(ret, gsv_samples[i].number_of_svs, + "Incorrect number of satellites parsed"); + + for (uint16_t u = 0; u < gsv_samples[i].number_of_svs; u++) { + zassert_equal(gsv_samples[i].satellites[u].prn, + satellites[u].prn, + "Failed to parse satellite prn"); + zassert_equal(gsv_samples[i].satellites[u].snr, + satellites[u].snr, + "Failed to parse satellite snr"); + zassert_equal(gsv_samples[i].satellites[u].elevation, + satellites[u].elevation, + "Failed to parse satellite elevation"); + zassert_equal(gsv_samples[i].satellites[u].azimuth, + satellites[u].azimuth, + "Failed to parse satellite azimuth"); + zassert_equal(gsv_samples[i].satellites[u].system, + satellites[u].system, + "Failed to parse satellite system"); + zassert_equal(gsv_samples[i].satellites[u].is_tracked, + satellites[u].is_tracked, + "Failed to parse satellite is_tracked"); + } + } +} + +ZTEST_SUITE(gnss_nmea0183, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/gnss/gnss_nmea0183/testcase.yaml b/tests/drivers/gnss/gnss_nmea0183/testcase.yaml new file mode 100644 index 00000000000..b63e7f24dbf --- /dev/null +++ b/tests/drivers/gnss/gnss_nmea0183/testcase.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.gnss.gnss_nmea0183: + tags: + - drivers + - gnss + - parse + - nmea0183 From 2b14e5d84a5bef85183f17582ef0f8bce760fb03 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 21 Sep 2023 21:07:25 +0200 Subject: [PATCH 2799/4498] drivers: gnss: Add nmea0183 match utilities This commit adds generic matches and handlers for the RMC, GGA and GSV messages to be implemented as part of all NMEA0183 based GNSS modems. NMEA0183 based GNSS modems must place the struct gnss_nmea0183_match_data struct as the first struct in their data struct. Their data struct shall then be set as the user_data for the modem_chat instance. Lastly, the gnss_nmea0183_match callbacks must be included in the unsolicited matches for the modem_chat instance. The GNSS modems will initialize the NMEA0183 match instance using gnss_nmea0183_match_init. Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/CMakeLists.txt | 1 + drivers/gnss/Kconfig | 6 ++ drivers/gnss/gnss_nmea0183_match.c | 137 +++++++++++++++++++++++++++++ drivers/gnss/gnss_nmea0183_match.h | 106 ++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 drivers/gnss/gnss_nmea0183_match.c create mode 100644 drivers/gnss/gnss_nmea0183_match.h diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index d30723c1915..105d24c386c 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -6,3 +6,4 @@ zephyr_library_sources(gnss_publish.c) zephyr_library_sources_ifdef(CONFIG_GNSS_DUMP gnss_dump.c) zephyr_library_sources_ifdef(CONFIG_GNSS_PARSE gnss_parse.c) zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183 gnss_nmea0183.c) +zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183_MATCH gnss_nmea0183_match.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index fcb45122aa4..e3c3c96f417 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -47,6 +47,12 @@ config GNSS_NMEA0183 help Enable NMEA0183 parsing utilities. +config GNSS_NMEA0183_MATCH + bool "GNSS NMEA0183 match utilities" + select GNSS_NMEA0183 + help + Enable NMEA0183 match utilities. + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/gnss/gnss_nmea0183_match.c b/drivers/gnss/gnss_nmea0183_match.c new file mode 100644 index 00000000000..3fe3b159fdb --- /dev/null +++ b/drivers/gnss/gnss_nmea0183_match.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include "gnss_nmea0183.h" +#include "gnss_nmea0183_match.h" +#include "gnss_publish.h" + +static bool gnss_nmea0183_match_timed_out(struct gnss_nmea0183_match_data *data) +{ + int64_t delta; + + delta = k_uptime_delta(&data->timestamp); + data->timestamp = k_uptime_get(); + return ((uint16_t)delta) > data->timeout_ms; +} + +#if CONFIG_GNSS_SATELLITES +static void gnss_nmea0183_match_reset_gsv(struct gnss_nmea0183_match_data *data) +{ + data->satellites_length = 0; + data->gsv_message_number = 1; +} +#endif + +static void gnss_nmea0183_match_reset(struct gnss_nmea0183_match_data *data) +{ + data->gga_received = false; + data->rmc_received = false; +} + +void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct gnss_nmea0183_match_data *data = user_data; + + if (gnss_nmea0183_match_timed_out(data)) { + gnss_nmea0183_match_reset(data); + } + + if (gnss_nmea0183_parse_gga((const char **)argv, argc, &data->data) < 0) { + return; + } + + data->gga_received = true; + + if (data->gga_received && data->rmc_received) { + gnss_publish_data(data->gnss, &data->data); + } +} + +void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct gnss_nmea0183_match_data *data = user_data; + + if (gnss_nmea0183_match_timed_out(data)) { + gnss_nmea0183_match_reset(data); + } + + if (gnss_nmea0183_parse_rmc((const char **)argv, argc, &data->data) < 0) { + return; + } + + data->rmc_received = true; + + if (data->gga_received && data->rmc_received) { + gnss_publish_data(data->gnss, &data->data); + } +} + +#if CONFIG_GNSS_SATELLITES +void gnss_nmea0183_match_gsv_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct gnss_nmea0183_match_data *data = user_data; + struct gnss_nmea0183_gsv_header header; + int ret; + + if (gnss_nmea0183_match_timed_out(data)) { + gnss_nmea0183_match_reset(data); + } + + if (gnss_nmea0183_parse_gsv_header((const char **)argv, argc, &header) < 0) { + return; + } + + if (header.number_of_svs == 0) { + return; + } + + if (header.message_number != data->gsv_message_number) { + gnss_nmea0183_match_reset_gsv(data); + return; + } + + data->gsv_message_number++; + + ret = gnss_nmea0183_parse_gsv_svs((const char **)argv, argc, + &data->satellites[data->satellites_length], + data->satellites_size - data->satellites_length); + if (ret < 0) { + gnss_nmea0183_match_reset_gsv(data); + return; + } + + data->satellites_length += (uint16_t)ret; + + if (data->satellites_length == header.number_of_svs) { + gnss_publish_satellites(data->gnss, data->satellites, data->satellites_length); + gnss_nmea0183_match_reset_gsv(data); + } +} +#endif + +int gnss_nmea0183_match_init(struct gnss_nmea0183_match_data *data, + const struct gnss_nmea0183_match_config *config) +{ + __ASSERT(data != NULL, "data argument must be provided"); + __ASSERT(config != NULL, "data argument must be provided"); + + memset(data, 0, sizeof(struct gnss_nmea0183_match_data)); + data->gnss = config->gnss; +#if CONFIG_GNSS_SATELLITES + data->satellites = config->satellites; + data->satellites_size = config->satellites_size; +#endif + data->timeout_ms = config->timeout_ms; + return 0; +} diff --git a/drivers/gnss/gnss_nmea0183_match.h b/drivers/gnss/gnss_nmea0183_match.h new file mode 100644 index 00000000000..65104e1dc8a --- /dev/null +++ b/drivers/gnss/gnss_nmea0183_match.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The GNSS NMEA0183 match is a set of modem_chat match handlers and a context to be + * passed to said handlers, to parse the NMEA0183 messages received from a NMEA0183 + * based GNSS device. + * + * The context struct gnss_nmea0183_match_data *data is placed as the first member + * of the data structure which is passed to the modem_chat instance through the + * user_data member. + * + * struct my_gnss_nmea0183_driver { + * gnss_nmea0183_match_data match_data; + * ... + * }; + * + * The struct gnss_nmea0183_match_data context must be initialized using + * gnss_nmea0183_match_init(). + * + * When initializing the modem_chat instance, the three match callbacks must be added + * as part of the unsolicited matches. + * + * MODEM_CHAT_MATCHES_DEFINE(unsol_matches, + * MODEM_CHAT_MATCH_WILDCARD("$??GGA,", ",*", gnss_nmea0183_match_gga_callback), + * MODEM_CHAT_MATCH_WILDCARD("$??RMC,", ",*", gnss_nmea0183_match_rmc_callback), + * #if CONFIG_GNSS_SATELLITES + * MODEM_CHAT_MATCH_WILDCARD("$??GSV,", ",*", gnss_nmea0183_match_gsv_callback), + * #endif + * + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_MATCH_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_MATCH_H_ + +#include +#include +#include +#include + +struct gnss_nmea0183_match_data { + const struct device *gnss; + struct gnss_data data; +#if CONFIG_GNSS_SATELLITES + struct gnss_satellite *satellites; + uint16_t satellites_size; + uint16_t satellites_length; +#endif + int64_t timestamp; + uint16_t timeout_ms; + uint8_t gga_received : 1; + uint8_t rmc_received : 1; + uint8_t gsv_message_number : 6; +}; + +/** GNSS NMEA0183 match configuration structure */ +struct gnss_nmea0183_match_config { + /** The GNSS device from which the data is published */ + const struct device *gnss; +#if CONFIG_GNSS_SATELLITES + /** Buffer for parsed satellites */ + struct gnss_satellite *satellites; + /** Number of elements in buffer for parsed satellites */ + uint16_t satellites_size; +#endif + /** The maximum time from the first to the last NMEA0183 message of a fix */ + uint16_t timeout_ms; +}; + +/** + * @brief Match callback for the NMEA GGA NMEA0183 message + * + * @details Should be used as the callback of a modem_chat match which matches "$??GGA," + */ +void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data); + +/** + * @brief Match callback for the NMEA RMC NMEA0183 message + * + * @details Should be used as the callback of a modem_chat match which matches "$??RMC," + */ +void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data); + +/** + * @brief Match callback for the NMEA GSV NMEA0183 message + * + * @details Should be used as the callback of a modem_chat match which matches "$??GSV," + */ +void gnss_nmea0183_match_gsv_callback(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data); + +/** + * @brief Initialize a GNSS NMEA0183 match instance + * + * @param data GNSS NMEA0183 match instance to initialize + * @param config Configuration to apply to GNSS NMEA0183 match instance + */ +int gnss_nmea0183_match_init(struct gnss_nmea0183_match_data *data, + const struct gnss_nmea0183_match_config *config); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_NMEA0183_MATCH_H_ */ From b60eb1881b2a2de3e727394f5fa8947f5650a4b9 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sun, 10 Sep 2023 14:26:17 +0200 Subject: [PATCH 2800/4498] drivers: gnss: Add GNSS driver for Quectel LCX6G This commit adds a GNSS driver for the Quectel LCX6G series of GNSS modems (LC26G, LC76G, LC86G). It is based on the modem subsystem, and the GNSS utilities added in the two previous commits. Signed-off-by: Bjarki Arge Andreasen --- drivers/gnss/CMakeLists.txt | 1 + drivers/gnss/Kconfig | 9 + drivers/gnss/Kconfig.quectel_lcx6g | 17 + drivers/gnss/gnss_quectel_lcx6g.c | 784 +++++++++++++++++++++++++++ dts/bindings/gnss/gnss-pps.yaml | 23 + dts/bindings/gnss/quectel,lc26g.yaml | 11 + dts/bindings/gnss/quectel,lc86g.yaml | 11 + dts/bindings/gnss/quectel-lc76g.yaml | 11 + 8 files changed, 867 insertions(+) create mode 100644 drivers/gnss/Kconfig.quectel_lcx6g create mode 100644 drivers/gnss/gnss_quectel_lcx6g.c create mode 100644 dts/bindings/gnss/gnss-pps.yaml create mode 100644 dts/bindings/gnss/quectel,lc26g.yaml create mode 100644 dts/bindings/gnss/quectel,lc86g.yaml create mode 100644 dts/bindings/gnss/quectel-lc76g.yaml diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index 105d24c386c..6c24df4903e 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_GNSS_DUMP gnss_dump.c) zephyr_library_sources_ifdef(CONFIG_GNSS_PARSE gnss_parse.c) zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183 gnss_nmea0183.c) zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183_MATCH gnss_nmea0183_match.c) +zephyr_library_sources_ifdef(CONFIG_GNSS_QUECTEL_LCX6G gnss_quectel_lcx6g.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index e3c3c96f417..5bdc0f530d8 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -53,8 +53,17 @@ config GNSS_NMEA0183_MATCH help Enable NMEA0183 match utilities. +config GNSS_INIT_PRIORITY + int "GNSS driver initialization priority" + default 80 + range 0 99 + help + Driver initialization priority for GNSS drivers. + module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" +rsource "Kconfig.quectel_lcx6g" + endif diff --git a/drivers/gnss/Kconfig.quectel_lcx6g b/drivers/gnss/Kconfig.quectel_lcx6g new file mode 100644 index 00000000000..6736015aed7 --- /dev/null +++ b/drivers/gnss/Kconfig.quectel_lcx6g @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Trackunit Corporation +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +config GNSS_QUECTEL_LCX6G + bool "Quectel LCX6G GNSS modem driver" + default y + depends on GNSS + depends on DT_HAS_QUECTEL_LC26G_ENABLED || DT_HAS_QUECTEL_LC76G_ENABLED || DT_HAS_QUECTEL_LC86G_ENABLED + select MODEM_MODULES + select MODEM_BACKEND_UART + select MODEM_CHAT + select GNSS_PARSE + select GNSS_NMEA0183 + select GNSS_NMEA0183_MATCH + help + Enable quectel LCX6G series GNSS modem driver. diff --git a/drivers/gnss/gnss_quectel_lcx6g.c b/drivers/gnss/gnss_quectel_lcx6g.c new file mode 100644 index 00000000000..0ca7f5203ac --- /dev/null +++ b/drivers/gnss/gnss_quectel_lcx6g.c @@ -0,0 +1,784 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gnss_publish.h" +#include "gnss_nmea0183.h" +#include "gnss_nmea0183_match.h" +#include "gnss_parse.h" + +#include +LOG_MODULE_REGISTER(quectel_lcx6g, CONFIG_GNSS_LOG_LEVEL); + +#define QUECTEL_LCX6G_STARTUP_DELAY (K_MSEC(300U)) +#define QUECTEL_LCX6G_STATE_CHANGE_DELAY_MSEC (300LL) +#define QUECTEL_LCX6G_PAIR_TIMEOUT (K_SECONDS(11)) +#define QUECTEL_LCX6G_SCRIPT_TIMEOUT_S (10U) + +#define QUECTEL_LCX6G_PAIR_NAV_MODE_STATIONARY (4) +#define QUECTEL_LCX6G_PAIR_NAV_MODE_FITNESS (1) +#define QUECTEL_LCX6G_PAIR_NAV_MODE_NORMAL (0) +#define QUECTEL_LCX6G_PAIR_NAV_MODE_DRONE (5) + +#define QUECTEL_LCX6G_PAIR_PPS_MODE_DISABLED (0) +#define QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED (4) +#define QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED_AFTER_LOCK (1) +#define QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED_WHILE_LOCKED (2) + +struct quectel_lcx6g_config { + const struct device *uart; + const enum gnss_pps_mode pps_mode; + const uint16_t pps_pulse_width; +}; + +struct quectel_lcx6g_data { + struct gnss_nmea0183_match_data match_data; +#if CONFIG_GNSS_SATELLITES + struct gnss_satellite satellites[24]; +#endif + + /* UART backend */ + struct modem_pipe *uart_pipe; + struct modem_backend_uart uart_backend; + uint8_t uart_backend_receive_buf[128]; + uint8_t uart_backend_transmit_buf[64]; + + /* Modem chat */ + struct modem_chat chat; + uint8_t chat_receive_buf[256]; + uint8_t chat_delimiter[2]; + uint8_t *chat_argv[32]; + + /* Dynamic chat script */ + uint8_t dynamic_match_buf[32]; + uint8_t dynamic_separators_buf[2]; + uint8_t dynamic_request_buf[32]; + struct modem_chat_match dynamic_match; + struct modem_chat_script_chat dynamic_script_chat; + struct modem_chat_script dynamic_script; + + /* Allocation for responses from GNSS modem */ + union { + uint16_t fix_rate_response; + gnss_systems_t enabled_systems_response; + enum gnss_navigation_mode navigation_mode_response; + }; + + struct k_spinlock lock; +}; + +#define MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(_sym, _script_chats, _callback, _timeout) \ + static struct modem_chat_script _sym = { \ + .name = #_sym, \ + .script_chats = _script_chats, \ + .script_chats_size = ARRAY_SIZE(_script_chats), \ + .abort_matches = NULL, \ + .abort_matches_size = 0, \ + .callback = _callback, \ + .timeout = _timeout, \ + } + +#ifdef CONFIG_PM_DEVICE +MODEM_CHAT_MATCH_DEFINE(pair003_success_match, "$PAIR001,003,0*38", "", NULL); +MODEM_CHAT_SCRIPT_CMDS_DEFINE( + suspend_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR003*39", pair003_success_match) +); + +MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(suspend_script, suspend_script_cmds, + NULL, QUECTEL_LCX6G_SCRIPT_TIMEOUT_S); +#endif /* CONFIG_PM_DEVICE */ + +MODEM_CHAT_MATCH_DEFINE(any_match, "", "", NULL); +MODEM_CHAT_MATCH_DEFINE(pair062_ack_match, "$PAIR001,062,0*3F", "", NULL); +MODEM_CHAT_SCRIPT_CMDS_DEFINE( + resume_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR002*38", any_match), + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,0,1*3F", pair062_ack_match), + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,1,0*3F", pair062_ack_match), + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,2,0*3C", pair062_ack_match), +#if CONFIG_GNSS_SATELLITES + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,3,5*38", pair062_ack_match), +#else + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,3,0*3D", pair062_ack_match), +#endif + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,4,1*3B", pair062_ack_match), + MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,5,0*3B", pair062_ack_match), +); + +MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(resume_script, resume_script_cmds, + NULL, QUECTEL_LCX6G_SCRIPT_TIMEOUT_S); + +MODEM_CHAT_MATCHES_DEFINE(unsol_matches, + MODEM_CHAT_MATCH_WILDCARD("$??GGA,", ",*", gnss_nmea0183_match_gga_callback), + MODEM_CHAT_MATCH_WILDCARD("$??RMC,", ",*", gnss_nmea0183_match_rmc_callback), +#if CONFIG_GNSS_SATELLITES + MODEM_CHAT_MATCH_WILDCARD("$??GSV,", ",*", gnss_nmea0183_match_gsv_callback), +#endif +); + +static int quectel_lcx6g_configure_pps(const struct device *dev) +{ + const struct quectel_lcx6g_config *config = dev->config; + struct quectel_lcx6g_data *data = dev->data; + uint8_t pps_mode = 0; + int ret; + + switch (config->pps_mode) { + case GNSS_PPS_MODE_DISABLED: + pps_mode = QUECTEL_LCX6G_PAIR_PPS_MODE_DISABLED; + break; + + case GNSS_PPS_MODE_ENABLED: + pps_mode = QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED; + break; + + case GNSS_PPS_MODE_ENABLED_AFTER_LOCK: + pps_mode = QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED_AFTER_LOCK; + break; + + case GNSS_PPS_MODE_ENABLED_WHILE_LOCKED: + pps_mode = QUECTEL_LCX6G_PAIR_PPS_MODE_ENABLED_WHILE_LOCKED; + break; + } + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR752,%u,%u", pps_mode, config->pps_pulse_width); + if (ret < 0) { + return ret; + } + + data->dynamic_script_chat.request_size = ret; + + ret = gnss_nmea0183_snprintk(data->dynamic_match_buf, sizeof(data->dynamic_match_buf), + "PAIR001,752,0"); + if (ret < 0) { + return ret; + } + + data->dynamic_match.match_size = ret; + + return modem_chat_run_script(&data->chat, &data->dynamic_script); +} + +static int quectel_lcx6g_resume(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + int ret; + + ret = modem_pipe_open(data->uart_pipe); + if (ret < 0) { + return ret; + } + + ret = modem_chat_attach(&data->chat, data->uart_pipe); + if (ret < 0) { + modem_pipe_close(data->uart_pipe); + return ret; + } + + ret = modem_chat_run_script(&data->chat, &resume_script); + if (ret < 0) { + modem_pipe_close(data->uart_pipe); + return ret; + } + + k_msleep(1000); + + ret = quectel_lcx6g_configure_pps(dev); + if (ret < 0) { + modem_pipe_close(data->uart_pipe); + } + + return ret; +} + +#ifdef CONFIG_PM_DEVICE +static int quectel_lcx6g_suspend(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + int ret; + + ret = modem_chat_run_script_run(&data->chat, &suspend_script); + if (ret < 0) { + modem_pipe_close(data->uart_pipe); + } + + return ret; +} + +static int quectel_lcx6g_turn_off(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + + return modem_pipe_close(data->uart_pipe); +} + +static int quectel_lcx6g_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + int ret = -ENOTSUP; + + key = k_spin_lock(&data->lock); + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = quectel_lcx6g_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + ret = quectel_lcx6g_resume(dev); + break; + + case PM_DEVICE_ACTION_TURN_ON: + ret = 0; + break; + + case PM_DEVICE_ACTION_TURN_OFF: + ret = quectel_lcx6g_turn_off(dev); + break; + + default: + break; + } + + k_spin_unlock(&data->lock, key); + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +static int quectel_lcx6g_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + int ret; + + if (fix_interval_ms < 100 || fix_interval_ms > 1000) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR050,%u", fix_interval_ms); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + ret = gnss_nmea0183_snprintk(data->dynamic_match_buf, sizeof(data->dynamic_match_buf), + "PAIR001,050,0"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_match.match_size = ret; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + if (ret < 0) { + goto unlock_return; + } + +unlock_return: + k_spin_unlock(&data->lock, key); + return ret; +} + +static void quectel_lcx6g_get_fix_rate_callback(struct modem_chat *chat, char **argv, + uint16_t argc, void *user_data) +{ + struct quectel_lcx6g_data *data = user_data; + int32_t tmp; + + if (argc != 3) { + return; + } + + if ((gnss_parse_atoi(argv[1], 10, &tmp) < 0) || (tmp < 0) || (tmp > 1000)) { + return; + } + + data->fix_rate_response = (uint16_t)tmp; +} + +static int quectel_lcx6g_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + int ret; + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR051"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + strncpy(data->dynamic_match_buf, "$PAIR051,", sizeof(data->dynamic_match_buf)); + data->dynamic_match.match_size = sizeof("$PAIR051,") - 1; + data->dynamic_match.callback = quectel_lcx6g_get_fix_rate_callback; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + data->dynamic_match.callback = NULL; + if (ret < 0) { + goto unlock_return; + } + + *fix_interval_ms = data->fix_rate_response; + +unlock_return: + k_spin_unlock(&data->lock, key); + return 0; +} + +static int quectel_lcx6g_set_navigation_mode(const struct device *dev, + enum gnss_navigation_mode mode) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + uint8_t navigation_mode = 0; + int ret; + + switch (mode) { + case GNSS_NAVIGATION_MODE_ZERO_DYNAMICS: + navigation_mode = QUECTEL_LCX6G_PAIR_NAV_MODE_STATIONARY; + break; + + case GNSS_NAVIGATION_MODE_LOW_DYNAMICS: + navigation_mode = QUECTEL_LCX6G_PAIR_NAV_MODE_FITNESS; + break; + + case GNSS_NAVIGATION_MODE_BALANCED_DYNAMICS: + navigation_mode = QUECTEL_LCX6G_PAIR_NAV_MODE_NORMAL; + break; + + case GNSS_NAVIGATION_MODE_HIGH_DYNAMICS: + navigation_mode = QUECTEL_LCX6G_PAIR_NAV_MODE_DRONE; + break; + } + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR080,%u", navigation_mode); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + ret = gnss_nmea0183_snprintk(data->dynamic_match_buf, sizeof(data->dynamic_match_buf), + "PAIR001,080,0"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_match.match_size = ret; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + if (ret < 0) { + goto unlock_return; + } + +unlock_return: + k_spin_unlock(&data->lock, key); + return ret; +} + +static void quectel_lcx6g_get_navigation_mode_callback(struct modem_chat *chat, char **argv, + uint16_t argc, void *user_data) +{ + struct quectel_lcx6g_data *data = user_data; + int32_t tmp; + + if (argc != 3) { + return; + } + + if ((gnss_parse_atoi(argv[1], 10, &tmp) < 0) || (tmp < 0) || (tmp > 7)) { + return; + } + + switch (tmp) { + case QUECTEL_LCX6G_PAIR_NAV_MODE_FITNESS: + data->navigation_mode_response = GNSS_NAVIGATION_MODE_LOW_DYNAMICS; + break; + + case QUECTEL_LCX6G_PAIR_NAV_MODE_STATIONARY: + data->navigation_mode_response = GNSS_NAVIGATION_MODE_ZERO_DYNAMICS; + break; + + case QUECTEL_LCX6G_PAIR_NAV_MODE_DRONE: + data->navigation_mode_response = GNSS_NAVIGATION_MODE_HIGH_DYNAMICS; + break; + + default: + data->navigation_mode_response = GNSS_NAVIGATION_MODE_BALANCED_DYNAMICS; + break; + } +} + +static int quectel_lcx6g_get_navigation_mode(const struct device *dev, + enum gnss_navigation_mode *mode) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + int ret; + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR081"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + strncpy(data->dynamic_match_buf, "$PAIR081,", sizeof(data->dynamic_match_buf)); + data->dynamic_match.match_size = sizeof("$PAIR081,") - 1; + data->dynamic_match.callback = quectel_lcx6g_get_navigation_mode_callback; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + data->dynamic_match.callback = NULL; + if (ret < 0) { + goto unlock_return; + } + + *mode = data->navigation_mode_response; + +unlock_return: + k_spin_unlock(&data->lock, key); + return ret; +} + +static int quectel_lcx6g_set_enabled_systems(const struct device *dev, gnss_systems_t systems) +{ + struct quectel_lcx6g_data *data = dev->data; + gnss_systems_t supported_systems; + k_spinlock_key_t key; + int ret; + + supported_systems = (GNSS_SYSTEM_GPS | GNSS_SYSTEM_GLONASS | GNSS_SYSTEM_GALILEO | + GNSS_SYSTEM_BEIDOU | GNSS_SYSTEM_QZSS | GNSS_SYSTEM_SBAS); + + if ((~supported_systems) & systems) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR066,%u,%u,%u,%u,%u,0", + (0 < (systems & GNSS_SYSTEM_GPS)), + (0 < (systems & GNSS_SYSTEM_GLONASS)), + (0 < (systems & GNSS_SYSTEM_GALILEO)), + (0 < (systems & GNSS_SYSTEM_BEIDOU)), + (0 < (systems & GNSS_SYSTEM_QZSS))); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + ret = gnss_nmea0183_snprintk(data->dynamic_match_buf, sizeof(data->dynamic_match_buf), + "PAIR001,066,0"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_match.match_size = ret; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + if (ret < 0) { + goto unlock_return; + } + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR410,%u", (0 < (systems & GNSS_SYSTEM_SBAS))); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + ret = gnss_nmea0183_snprintk(data->dynamic_match_buf, sizeof(data->dynamic_match_buf), + "PAIR001,410,0"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_match.match_size = ret; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + if (ret < 0) { + goto unlock_return; + } + +unlock_return: + k_spin_unlock(&data->lock, key); + return ret; +} + +static inline bool search_mode_enabled(const char *arg) +{ + return arg[0] == '1'; +} + +static void quectel_lcx6g_get_search_mode_callback(struct modem_chat *chat, char **argv, + uint16_t argc, void *user_data) +{ + struct quectel_lcx6g_data *data = user_data; + + if (argc != 8) { + return; + } + + data->enabled_systems_response = search_mode_enabled(argv[1]) ? GNSS_SYSTEM_GPS : 0; + data->enabled_systems_response |= search_mode_enabled(argv[2]) ? GNSS_SYSTEM_GLONASS : 0; + data->enabled_systems_response |= search_mode_enabled(argv[3]) ? GNSS_SYSTEM_GALILEO : 0; + data->enabled_systems_response |= search_mode_enabled(argv[4]) ? GNSS_SYSTEM_BEIDOU : 0; + data->enabled_systems_response |= search_mode_enabled(argv[5]) ? GNSS_SYSTEM_QZSS : 0; +} + +static void quectel_lcx6g_get_sbas_status_callback(struct modem_chat *chat, char **argv, + uint16_t argc, void *user_data) +{ + struct quectel_lcx6g_data *data = user_data; + + if (argc != 3) { + return; + } + + data->enabled_systems_response |= ('1' == argv[1][0]) ? GNSS_SYSTEM_SBAS : 0; +} + + +static int quectel_lcx6g_get_enabled_systems(const struct device *dev, gnss_systems_t *systems) +{ + struct quectel_lcx6g_data *data = dev->data; + k_spinlock_key_t key; + int ret; + + key = k_spin_lock(&data->lock); + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR067"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + strncpy(data->dynamic_match_buf, "$PAIR067,", sizeof(data->dynamic_match_buf)); + data->dynamic_match.match_size = sizeof("$PAIR067,") - 1; + data->dynamic_match.callback = quectel_lcx6g_get_search_mode_callback; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + data->dynamic_match.callback = NULL; + if (ret < 0) { + goto unlock_return; + } + + ret = gnss_nmea0183_snprintk(data->dynamic_request_buf, sizeof(data->dynamic_request_buf), + "PAIR411"); + if (ret < 0) { + goto unlock_return; + } + + data->dynamic_script_chat.request_size = ret; + + strncpy(data->dynamic_match_buf, "$PAIR411,", sizeof(data->dynamic_match_buf)); + data->dynamic_match.match_size = sizeof("$PAIR411,") - 1; + data->dynamic_match.callback = quectel_lcx6g_get_sbas_status_callback; + + ret = modem_chat_run_script(&data->chat, &data->dynamic_script); + data->dynamic_match.callback = NULL; + if (ret < 0) { + goto unlock_return; + } + + *systems = data->enabled_systems_response; + +unlock_return: + k_spin_unlock(&data->lock, key); + return ret; +} + +static int quectel_lcx6g_get_supported_systems(const struct device *dev, gnss_systems_t *systems) +{ + *systems = (GNSS_SYSTEM_GPS | GNSS_SYSTEM_GLONASS | GNSS_SYSTEM_GALILEO | + GNSS_SYSTEM_BEIDOU | GNSS_SYSTEM_QZSS | GNSS_SYSTEM_SBAS); + return 0; +} + +static struct gnss_driver_api gnss_api = { + .set_fix_rate = quectel_lcx6g_set_fix_rate, + .get_fix_rate = quectel_lcx6g_get_fix_rate, + .set_navigation_mode = quectel_lcx6g_set_navigation_mode, + .get_navigation_mode = quectel_lcx6g_get_navigation_mode, + .set_enabled_systems = quectel_lcx6g_set_enabled_systems, + .get_enabled_systems = quectel_lcx6g_get_enabled_systems, + .get_supported_systems = quectel_lcx6g_get_supported_systems, +}; + +static int quectel_lcx6g_init_nmea0183_match(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + + const struct gnss_nmea0183_match_config config = { + .gnss = dev, +#if CONFIG_GNSS_SATELLITES + .satellites = data->satellites, + .satellites_size = ARRAY_SIZE(data->satellites), +#endif + .timeout_ms = 50, + }; + + return gnss_nmea0183_match_init(&data->match_data, &config); +} + +static void quectel_lcx6g_init_pipe(const struct device *dev) +{ + const struct quectel_lcx6g_config *config = dev->config; + struct quectel_lcx6g_data *data = dev->data; + + const struct modem_backend_uart_config uart_backend_config = { + .uart = config->uart, + .receive_buf = data->uart_backend_receive_buf, + .receive_buf_size = ARRAY_SIZE(data->uart_backend_receive_buf), + .transmit_buf = data->uart_backend_transmit_buf, + .transmit_buf_size = ARRAY_SIZE(data->uart_backend_transmit_buf), + }; + + data->uart_pipe = modem_backend_uart_init(&data->uart_backend, &uart_backend_config); +} + +static int quectel_lcx6g_init_chat(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + + const struct modem_chat_config chat_config = { + .user_data = data, + .receive_buf = data->chat_receive_buf, + .receive_buf_size = ARRAY_SIZE(data->chat_receive_buf), + .delimiter = data->chat_delimiter, + .delimiter_size = ARRAY_SIZE(data->chat_delimiter), + .filter = NULL, + .filter_size = 0, + .argv = data->chat_argv, + .argv_size = ARRAY_SIZE(data->chat_argv), + .unsol_matches = unsol_matches, + .unsol_matches_size = ARRAY_SIZE(unsol_matches), + .process_timeout = K_MSEC(2), + }; + + return modem_chat_init(&data->chat, &chat_config); +} + +static void quectel_lcx6g_init_dynamic_script(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + + data->dynamic_match.match = data->dynamic_match_buf; + data->dynamic_match.separators = data->dynamic_separators_buf; + data->dynamic_match.separators_size = sizeof(data->dynamic_separators_buf); + data->dynamic_match.wildcards = false; + data->dynamic_match.partial = false; + + data->dynamic_script_chat.request = data->dynamic_request_buf; + data->dynamic_script_chat.response_matches = &data->dynamic_match; + data->dynamic_script_chat.response_matches_size = 1; + data->dynamic_script_chat.timeout = 0; + + data->dynamic_script.name = "pair"; + data->dynamic_script.script_chats = &data->dynamic_script_chat; + data->dynamic_script.script_chats_size = 1; + data->dynamic_script.abort_matches = NULL; + data->dynamic_script.abort_matches_size = 0; + data->dynamic_script.callback = NULL; + data->dynamic_script.timeout = 10; +} + +static int quectel_lcx6g_init(const struct device *dev) +{ + int ret; + + LOG_INF("Initializing Quectel LCX6G"); + ret = quectel_lcx6g_init_nmea0183_match(dev); + if (ret < 0) { + return ret; + } + + quectel_lcx6g_init_pipe(dev); + + ret = quectel_lcx6g_init_chat(dev); + if (ret < 0) { + return ret; + } + + quectel_lcx6g_init_dynamic_script(dev); + +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_init_suspended(dev); +#else + LOG_INF("Resuming Quectel LCX6G"); + ret = quectel_lcx6g_resume(dev); + if (ret < 0) { + LOG_ERR("Failed to resume Quectel LCX6G"); + return ret; + } +#endif + LOG_INF("Quectel LCX6G initialized"); + return 0; +} + +#define LCX6G_INST_NAME(inst, name) \ + _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) + +#define LCX6G_DEVICE(inst) \ + static struct quectel_lcx6g_config LCX6G_INST_NAME(inst, config) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .pps_mode = DT_INST_STRING_UPPER_TOKEN(inst, pps_mode), \ + .pps_pulse_width = DT_INST_PROP(inst, pps_pulse_width), \ + }; \ + \ + static struct quectel_lcx6g_data LCX6G_INST_NAME(inst, data) = { \ + .chat_delimiter = {'\r', '\n'}, \ + .dynamic_separators_buf = {',', '*'}, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, quectel_lcx6g_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, quectel_lcx6g_init, PM_DEVICE_DT_INST_GET(inst), \ + &LCX6G_INST_NAME(inst, data), &LCX6G_INST_NAME(inst, config), \ + POST_KERNEL, CONFIG_GNSS_INIT_PRIORITY, &gnss_api); + +#define DT_DRV_COMPAT quectel_lc26g +DT_INST_FOREACH_STATUS_OKAY(LCX6G_DEVICE) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT quectel_lc76g +DT_INST_FOREACH_STATUS_OKAY(LCX6G_DEVICE) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT quectel_lc86g +DT_INST_FOREACH_STATUS_OKAY(LCX6G_DEVICE) +#undef DT_DRV_COMPAT diff --git a/dts/bindings/gnss/gnss-pps.yaml b/dts/bindings/gnss/gnss-pps.yaml new file mode 100644 index 00000000000..5ec554b69e2 --- /dev/null +++ b/dts/bindings/gnss/gnss-pps.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +properties: + pps-mode: + type: string + required: true + description: | + PPS output mode: + - GNSS_PPS_MODE_DISABLED: Output disabled + - GNSS_PPS_MODE_ENABLED: Output always enabled + - GNSS_PPS_MODE_ENABLED_AFTER_LOCK: Output enabled from first lock + - GNSS_PPS_MODE_ENABLED_WHILE_LOCKED: Output enabled only while locked + enum: + - GNSS_PPS_MODE_DISABLED + - GNSS_PPS_MODE_ENABLED + - GNSS_PPS_MODE_ENABLED_AFTER_LOCK + - GNSS_PPS_MODE_ENABLED_WHILE_LOCKED + + pps-pulse-width: + type: int + description: 1PPS pulse width + default: 100 diff --git a/dts/bindings/gnss/quectel,lc26g.yaml b/dts/bindings/gnss/quectel,lc26g.yaml new file mode 100644 index 00000000000..bfb278147c6 --- /dev/null +++ b/dts/bindings/gnss/quectel,lc26g.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Trackunit Corporation +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: Quectel LC26G GNSS modem + +compatible: "quectel,lc26g" + +include: + - uart-device.yaml + - gnss-pps.yaml diff --git a/dts/bindings/gnss/quectel,lc86g.yaml b/dts/bindings/gnss/quectel,lc86g.yaml new file mode 100644 index 00000000000..a3b762149d9 --- /dev/null +++ b/dts/bindings/gnss/quectel,lc86g.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Trackunit Corporation +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: Quectel LC86G GNSS modem + +compatible: "quectel,lc86g" + +include: + - uart-device.yaml + - gnss-pps.yaml diff --git a/dts/bindings/gnss/quectel-lc76g.yaml b/dts/bindings/gnss/quectel-lc76g.yaml new file mode 100644 index 00000000000..45c1da2fbae --- /dev/null +++ b/dts/bindings/gnss/quectel-lc76g.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Trackunit Corporation +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: Quectel LC76G GNSS modem + +compatible: "quectel,lc76g" + +include: + - uart-device.yaml + - gnss-pps.yaml From b6a8424e959f250d5eec4b13f2cd363c10918860 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 19 Sep 2023 21:23:07 +0200 Subject: [PATCH 2801/4498] samples: gnss: Add GNSS sample application This commit adds a sample which configures a GNSS modem to enable all available systems, registers callbacks to the GNSS data and satellites callbacks, and prints the GNSS data and satellites from the callbacks when invoked using printk. Signed-off-by: Bjarki Arge Andreasen --- samples/drivers/gnss/CMakeLists.txt | 8 +++++++ samples/drivers/gnss/README.rst | 29 +++++++++++++++++++++++++ samples/drivers/gnss/prj.conf | 9 ++++++++ samples/drivers/gnss/sample.yaml | 12 +++++++++++ samples/drivers/gnss/src/main.c | 33 +++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 samples/drivers/gnss/CMakeLists.txt create mode 100644 samples/drivers/gnss/README.rst create mode 100644 samples/drivers/gnss/prj.conf create mode 100644 samples/drivers/gnss/sample.yaml create mode 100644 samples/drivers/gnss/src/main.c diff --git a/samples/drivers/gnss/CMakeLists.txt b/samples/drivers/gnss/CMakeLists.txt new file mode 100644 index 00000000000..929f1b4da27 --- /dev/null +++ b/samples/drivers/gnss/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(gnss_sample) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/gnss/README.rst b/samples/drivers/gnss/README.rst new file mode 100644 index 00000000000..8d4749cd410 --- /dev/null +++ b/samples/drivers/gnss/README.rst @@ -0,0 +1,29 @@ +.. zephyr:code-sample:: gnss + :name: GNSS + :relevant-api: gnss_interface navigation + + Connect to a GNSS device to obtain time, navigation data, and satellite information. + +Overview +******** +This sample demonstrates how to use a GNSS device implementing the +GNSS device driver API. + +Requirements +************ + +This sample requires a board with a GNSS device present and enabled +in the devicetree. + +Sample Output +************* + +.. code-block:: console + + gnss: gnss_info: {satellites_cnt: 14, hdop: 0.850, fix_status: GNSS_FIX, fix_quality: GNSS_SPS} + gnss: navigation_data: {latitude: 57.162331699, longitude : 9.961104199, bearing 12.530, speed 0.25, altitude: 42.372} + gnss: gnss_time: {hour: 16, minute: 17, millisecond 36000, month_day 3, month: 10, century_year: 23} + gnss has fix! + gnss: gnss_satellite: {prn: 1, snr: 30, elevation 71, azimuth 276, system: GLONASS, is_tracked: 1} + gnss: gnss_satellite: {prn: 11, snr: 31, elevation 62, azimuth 221, system: GLONASS, is_tracked: 1} + gnss reported 2 satellites! diff --git a/samples/drivers/gnss/prj.conf b/samples/drivers/gnss/prj.conf new file mode 100644 index 00000000000..5ed72c140c2 --- /dev/null +++ b/samples/drivers/gnss/prj.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GNSS=y +CONFIG_GNSS_SATELLITES=y +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=8192 +CONFIG_GNSS_DUMP_TO_LOG=y +CONFIG_GNSS_LOG_LEVEL_DBG=y diff --git a/samples/drivers/gnss/sample.yaml b/samples/drivers/gnss/sample.yaml new file mode 100644 index 00000000000..385a4ca0b67 --- /dev/null +++ b/samples/drivers/gnss/sample.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +sample: + name: GNSS sample +tests: + sample.drivers.gnss: + tags: + - drivers + - gnss + filter: dt_alias_exists("gnss") + depends_on: gnss diff --git a/samples/drivers/gnss/src/main.c b/samples/drivers/gnss/src/main.c new file mode 100644 index 00000000000..16b812f3f84 --- /dev/null +++ b/samples/drivers/gnss/src/main.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static void gnss_data_cb(const struct device *dev, const struct gnss_data *data) +{ + if (data->info.fix_status != GNSS_FIX_STATUS_NO_FIX) { + printf("%s has fix!\r\n", dev->name); + } +} + +GNSS_DATA_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)), gnss_data_cb); + +#if CONFIG_GNSS_SATELLITES +static void gnss_satellites_cb(const struct device *dev, const struct gnss_satellite *satellites, + uint16_t size) +{ + printf("%s reported %u satellites!\r\n", dev->name, size); +} +#endif + +GNSS_SATELLITES_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)), gnss_satellites_cb); + +int main(void) +{ + return 0; +} From 42676e322b865e17538f2368ab24e6aec41a2159 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 25 Oct 2023 19:52:09 +0200 Subject: [PATCH 2802/4498] doc: gnss: Add GNSS documentation - Added GNSS documentation entry to peripherals - Added GNSS API entry to the API overview as 3.6 experimental Signed-off-by: Bjarki Arge Andreasen --- doc/develop/api/overview.rst | 4 +++ doc/hardware/peripherals/gnss.rst | 50 ++++++++++++++++++++++++++++++ doc/hardware/peripherals/index.rst | 1 + 3 files changed, 55 insertions(+) create mode 100644 doc/hardware/peripherals/gnss.rst diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 9295ee57b5f..1998f3a67aa 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -137,6 +137,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Stable - 1.11 + * - :ref:`gnss_api` + - Experimental + - 3.6 + * - :ref:`gpio_api` - Stable - 1.0 diff --git a/doc/hardware/peripherals/gnss.rst b/doc/hardware/peripherals/gnss.rst new file mode 100644 index 00000000000..fb750358dc3 --- /dev/null +++ b/doc/hardware/peripherals/gnss.rst @@ -0,0 +1,50 @@ +.. _gnss_api: + +GNSS (Global Navigation Satellite System) +######################################### + +Overview +******** + +GNSS is a general term which covers satellite systems used for +navigation, like GPS (Global Positioning System). GNSS services +are usually accessed through GNSS modems which receive and +process GNSS signals to determine their position, or more +specifically, their antennas position. They usually +additionally provide a precise time synchronization mechanism, +commonly named PPS (Pulse-Per-Second). + +Subsystem support +***************** + +The GNSS subsystem is based on the :ref:`modem`. The GNSS +subsystem covers everything from sending and receiving commands +to and from the modem, to parsing, creating and processing +NMEA0183 messages. + +Adding support for additional NMEA0183 based GNSS modems +requires little more than implementing power management +and configuration for the specific GNSS modem. + +Adding support for GNSS modems which use other protocols and/or +busses than the usual NMEA0183 over UART is possible, but will +require a bit more work from the driver developer. + +Configuration Options +********************* + +Related configuration options: + +* :kconfig:option:`CONFIG_GNSS` +* :kconfig:option:`CONFIG_GNSS_SATELLITES` +* :kconfig:option:`CONFIG_GNSS_DUMP_TO_LOG` + +Navigation Reference +******************** + +.. doxygengroup:: navigation + +GNSS API Reference +****************** + +.. doxygengroup:: gnss_interface diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 26500623d13..19461b6c9f4 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -29,6 +29,7 @@ Peripherals edac/index.rst flash.rst fuel_gauge.rst + gnss.rst gpio.rst hwinfo.rst i2c_eeprom_target.rst From d7302f417ed6e6603941d54029d315f42be12541 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 16 Oct 2023 13:30:53 +0800 Subject: [PATCH 2803/4498] irq: relocate multi-level irq out of irq.h Relocate multi-level interrupts APIs out of `irq.h` into a new file named `irq_multilevel.h` to provide cleaner separation between typical irq & multilevel ones. Added preprocessor versions of `irq_to_level_x` as `IRQ_TO_Lx`. Signed-off-by: Yong Cong Sin --- arch/common/sw_isr_common.c | 1 + arch/riscv/core/irq_manage.c | 1 + drivers/gpio/gpio_sifive.c | 1 + .../interrupt_controller/intc_nuclei_eclic.c | 1 + include/zephyr/irq.h | 131 ------------- include/zephyr/irq_multilevel.h | 176 ++++++++++++++++++ .../riscv-privileged/common/soc_common_irq.c | 1 + tests/kernel/gen_isr_table/src/main.c | 1 + 8 files changed, 182 insertions(+), 131 deletions(-) create mode 100644 include/zephyr/irq_multilevel.h diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index a5262e7fa83..a9c0a6df3d2 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -7,6 +7,7 @@ #include #include #include +#include #include /* * Common code for arches that use software ISR tables (CONFIG_GEN_ISR_TABLES) diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index 88fafd34904..f0a0eae2cd0 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -8,6 +8,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/drivers/gpio/gpio_sifive.c b/drivers/gpio/gpio_sifive.c index 440ad3f78ab..6288e60dd09 100644 --- a/drivers/gpio/gpio_sifive.c +++ b/drivers/gpio/gpio_sifive.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/drivers/interrupt_controller/intc_nuclei_eclic.c b/drivers/interrupt_controller/intc_nuclei_eclic.c index 9f831e56530..7c112c1a63f 100644 --- a/drivers/interrupt_controller/intc_nuclei_eclic.c +++ b/drivers/interrupt_controller/intc_nuclei_eclic.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/include/zephyr/irq.h b/include/zephyr/irq.h index 1a94a732bbc..1fa559edccd 100644 --- a/include/zephyr/irq.h +++ b/include/zephyr/irq.h @@ -280,137 +280,6 @@ void z_smp_global_unlock(unsigned int key); #define irq_unlock(key) arch_irq_unlock(key) #endif -/** - * @brief Return IRQ level - * This routine returns the interrupt level number of the provided interrupt. - * - * @param irq IRQ number in its zephyr format - * - * @return 1 if IRQ level 1, 2 if IRQ level 2, 3 if IRQ level 3 - */ -static inline unsigned int irq_get_level(unsigned int irq) -{ - const uint32_t mask2 = BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS) << - CONFIG_1ST_LEVEL_INTERRUPT_BITS; - const uint32_t mask3 = BIT_MASK(CONFIG_3RD_LEVEL_INTERRUPT_BITS) << - (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS); - - if (IS_ENABLED(CONFIG_3RD_LEVEL_INTERRUPTS) && (irq & mask3) != 0) { - return 3; - } - - if (IS_ENABLED(CONFIG_2ND_LEVEL_INTERRUPTS) && (irq & mask2) != 0) { - return 2; - } - - return 1; -} - -#if defined(CONFIG_2ND_LEVEL_INTERRUPTS) -/** - * @brief Return the 2nd level interrupt number - * - * This routine returns the second level irq number of the zephyr irq - * number passed in - * - * @param irq IRQ number in its zephyr format - * - * @return 2nd level IRQ number - */ -static inline unsigned int irq_from_level_2(unsigned int irq) -{ -#if defined(CONFIG_3RD_LEVEL_INTERRUPTS) - return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & - BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; -#else - return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) - 1; -#endif -} - -/** - * @brief Converts irq from level 1 to level 2 format - * - * - * This routine converts the input into the level 2 irq number format - * - * @note Values >= 0xFF are invalid - * - * @param irq IRQ number in its zephyr format - * - * @return 2nd level IRQ number - */ -static inline unsigned int irq_to_level_2(unsigned int irq) -{ - return (irq + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS; -} - -/** - * @brief Returns the parent IRQ of the level 2 raw IRQ number - * - * - * The parent of a 2nd level interrupt is in the 1st byte - * - * @param irq IRQ number in its zephyr format - * - * @return 2nd level IRQ parent - */ -static inline unsigned int irq_parent_level_2(unsigned int irq) -{ - return irq & BIT_MASK(CONFIG_1ST_LEVEL_INTERRUPT_BITS); -} -#endif - -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS -/** - * @brief Return the 3rd level interrupt number - * - * - * This routine returns the third level irq number of the zephyr irq - * number passed in - * - * @param irq IRQ number in its zephyr format - * - * @return 3rd level IRQ number - */ -static inline unsigned int irq_from_level_3(unsigned int irq) -{ - return (irq >> (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; -} - -/** - * @brief Converts irq from level 1 to level 3 format - * - * - * This routine converts the input into the level 3 irq number format - * - * @note Values >= 0xFF are invalid - * - * @param irq IRQ number in its zephyr format - * - * @return 3rd level IRQ number - */ -static inline unsigned int irq_to_level_3(unsigned int irq) -{ - return (irq + 1) << (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS); -} - -/** - * @brief Returns the parent IRQ of the level 3 raw IRQ number - * - * - * The parent of a 3rd level interrupt is in the 2nd byte - * - * @param irq IRQ number in its zephyr format - * - * @return 3rd level IRQ parent - */ -static inline unsigned int irq_parent_level_3(unsigned int irq) -{ - return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & - BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS); -} -#endif - /** * @brief Enable an IRQ. * diff --git a/include/zephyr/irq_multilevel.h b/include/zephyr/irq_multilevel.h new file mode 100644 index 00000000000..f9f082d46ad --- /dev/null +++ b/include/zephyr/irq_multilevel.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public interface for multi-level interrupts + */ +#ifndef ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_ +#define ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Return IRQ level + * This routine returns the interrupt level number of the provided interrupt. + * + * @param irq IRQ number in its zephyr format + * + * @return 1 if IRQ level 1, 2 if IRQ level 2, 3 if IRQ level 3 + */ +static inline unsigned int irq_get_level(unsigned int irq) +{ + const uint32_t mask2 = BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS) << + CONFIG_1ST_LEVEL_INTERRUPT_BITS; + const uint32_t mask3 = BIT_MASK(CONFIG_3RD_LEVEL_INTERRUPT_BITS) << + (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS); + + if (IS_ENABLED(CONFIG_3RD_LEVEL_INTERRUPTS) && (irq & mask3) != 0) { + return 3; + } + + if (IS_ENABLED(CONFIG_2ND_LEVEL_INTERRUPTS) && (irq & mask2) != 0) { + return 2; + } + + return 1; +} + +#if defined(CONFIG_2ND_LEVEL_INTERRUPTS) +/** + * @brief Return the 2nd level interrupt number + * + * This routine returns the second level irq number of the zephyr irq + * number passed in + * + * @param irq IRQ number in its zephyr format + * + * @return 2nd level IRQ number + */ +static inline unsigned int irq_from_level_2(unsigned int irq) +{ +#if defined(CONFIG_3RD_LEVEL_INTERRUPTS) + return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & + BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; +#else + return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) - 1; +#endif +} + +/** + * @brief Preprocessor macro to convert `irq` from level 1 to level 2 format + * + * @param irq IRQ number in its zephyr format + * + * @return 2nd level IRQ number + */ +#define IRQ_TO_L2(irq) ((irq + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) + +/** + * @brief Converts irq from level 1 to level 2 format + * + * + * This routine converts the input into the level 2 irq number format + * + * @note Values >= 0xFF are invalid + * + * @param irq IRQ number in its zephyr format + * + * @return 2nd level IRQ number + */ +static inline unsigned int irq_to_level_2(unsigned int irq) +{ + return IRQ_TO_L2(irq); +} + +/** + * @brief Returns the parent IRQ of the level 2 raw IRQ number + * + * + * The parent of a 2nd level interrupt is in the 1st byte + * + * @param irq IRQ number in its zephyr format + * + * @return 2nd level IRQ parent + */ +static inline unsigned int irq_parent_level_2(unsigned int irq) +{ + return irq & BIT_MASK(CONFIG_1ST_LEVEL_INTERRUPT_BITS); +} +#endif + +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS +/** + * @brief Return the 3rd level interrupt number + * + * + * This routine returns the third level irq number of the zephyr irq + * number passed in + * + * @param irq IRQ number in its zephyr format + * + * @return 3rd level IRQ number + */ +static inline unsigned int irq_from_level_3(unsigned int irq) +{ + return (irq >> (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; +} + +/** + * @brief Preprocessor macro to convert `irq` from level 1 to level 3 format + * + * @param irq IRQ number in its zephyr format + * + * @return 3rd level IRQ number + */ +#define IRQ_TO_L3(irq) \ + ((irq + 1) << (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS)) + +/** + * @brief Converts irq from level 1 to level 3 format + * + * + * This routine converts the input into the level 3 irq number format + * + * @note Values >= 0xFF are invalid + * + * @param irq IRQ number in its zephyr format + * + * @return 3rd level IRQ number + */ +static inline unsigned int irq_to_level_3(unsigned int irq) +{ + return IRQ_TO_L3(irq); +} + +/** + * @brief Returns the parent IRQ of the level 3 raw IRQ number + * + * + * The parent of a 3rd level interrupt is in the 2nd byte + * + * @param irq IRQ number in its zephyr format + * + * @return 3rd level IRQ parent + */ +static inline unsigned int irq_parent_level_3(unsigned int irq) +{ + return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & + BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ +#endif /* ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_ */ diff --git a/soc/riscv/riscv-privileged/common/soc_common_irq.c b/soc/riscv/riscv-privileged/common/soc_common_irq.c index c407bc8e20c..f33e4dceeef 100644 --- a/soc/riscv/riscv-privileged/common/soc_common_irq.c +++ b/soc/riscv/riscv-privileged/common/soc_common_irq.c @@ -10,6 +10,7 @@ privileged architecture specification */ #include +#include #include #include diff --git a/tests/kernel/gen_isr_table/src/main.c b/tests/kernel/gen_isr_table/src/main.c index bdb63d69ec0..c58b866a92e 100644 --- a/tests/kernel/gen_isr_table/src/main.c +++ b/tests/kernel/gen_isr_table/src/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include From df2c0681d3f44a1ff7ffd7b93edb1aac91aa6732 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 2 Oct 2023 12:42:24 +0800 Subject: [PATCH 2804/4498] devicetree: encode multi-level interrupt number in C devicetree magic The multi-level encoding of the interrupt number currently happens in the `gen_defines.py`, which is called in the `dts.cmake` module after `kconfig.cmake`. However, the number of bits used by each level is defined in Kconfig and this means that `gen_defines.py` will not be able to get that information during build. To fix this, do the multi-level encoding in C devicetree macro magic instead of the python script. This ticks one of a long-standing TODO item from the `gen_defines.py`. Signed-off-by: Yong Cong Sin --- drivers/gpio/gpio_sifive.c | 2 +- include/zephyr/devicetree.h | 84 ++++++++++++++++++++++++++++++++- include/zephyr/irq_multilevel.h | 1 + scripts/dts/gen_defines.py | 19 +------- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/drivers/gpio/gpio_sifive.c b/drivers/gpio/gpio_sifive.c index 6288e60dd09..77703f25707 100644 --- a/drivers/gpio/gpio_sifive.c +++ b/drivers/gpio/gpio_sifive.c @@ -377,7 +377,7 @@ DEVICE_DT_INST_DEFINE(0, &gpio_sifive_driver); #define IRQ_INIT(n) \ -IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, n, irq), \ +IRQ_CONNECT(DT_INST_IRQN_BY_IDX(0, n), \ DT_INST_IRQ_BY_IDX(0, n, priority), \ gpio_sifive_irq_handler, \ DEVICE_DT_INST_GET(0), \ diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index c249ad371e2..017bcab442a 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -17,6 +17,7 @@ #define DEVICETREE_H #include +#include #if !defined(_LINKER) && !defined(_ASMLANGUAGE) #include @@ -2409,6 +2410,77 @@ */ #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell) +/** + * @cond INTERNAL_HIDDEN + */ + +/* DT helper macro to get interrupt-parent node */ +#define DT_PARENT_INTC_INTERNAL(node_id) DT_PROP(node_id, interrupt_parent) +/* DT helper macro to get the node's interrupt grandparent node */ +#define DT_GPARENT_INTC_INTERNAL(node_id) DT_PARENT_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id)) +/* DT helper macro to check if a node is an interrupt controller */ +#define DT_IS_INTC_INTERNAL(node_id) DT_NODE_HAS_PROP(node_id, interrupt_controller) +/* DT helper macro to check if the node has a parent interrupt controller */ +#define DT_HAS_PARENT_INTC_INTERNAL(node_id) \ + /* node has `interrupt-parent`? */ \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_parent), \ + /* `interrupt-parent` node is an interrupt controller? */ \ + (IF_ENABLED(DT_IS_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id)), \ + /* `interrupt-parent` node has interrupt cell(s) ? 1 : 0 */ \ + (COND_CODE_0(DT_NUM_IRQS(DT_PARENT_INTC_INTERNAL(node_id)), (0), \ + (1)))))) +/* DT helper macro to check if the node has a grandparent interrupt controller */ +#define DT_HAS_GPARENT_INTC_INTERNAL(node_id) \ + IF_ENABLED(DT_HAS_PARENT_INTC_INTERNAL(node_id), \ + (DT_HAS_PARENT_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id)))) + +/** + * DT helper macro to get the as-seen interrupt number in devicetree, + * or ARM GIC IRQ encoded output from `gen_defines.py` + */ +#define DT_IRQN_BY_IDX_INTERNAL(node_id, idx) DT_IRQ_BY_IDX(node_id, idx, irq) + +/* DT helper macro to get the node's parent intc's (only) irq number */ +#define DT_PARENT_INTC_IRQN_INTERNAL(node_id) DT_IRQ(DT_PARENT_INTC_INTERNAL(node_id), irq) +/* DT helper macro to get the node's grandparent intc's (only) irq number */ +#define DT_GPARENT_INTC_IRQN_INTERNAL(node_id) DT_IRQ(DT_GPARENT_INTC_INTERNAL(node_id), irq) + +/* DT helper macro to encode a node's IRQN to level 2 according to the multi-level scheme */ +#define DT_IRQN_L2_INTERNAL(node_id, idx) \ + (IRQ_TO_L2(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)) | \ + DT_PARENT_INTC_IRQN_INTERNAL(node_id)) +/* DT helper macro to encode a node's IRQN to level 3 according to the multi-level scheme */ +#define DT_IRQN_L3_INTERNAL(node_id, idx) \ + (IRQ_TO_L3(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)) | \ + IRQ_TO_L2(DT_PARENT_INTC_IRQN_INTERNAL(node_id)) | \ + DT_GPARENT_INTC_IRQN_INTERNAL(node_id)) +/** + * DT helper macro to encode a node's interrupt number according to the Zephyr's multi-level scheme + * See doc/kernel/services/interrupts.rst for details + */ +#define DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx) \ + COND_CODE_1(DT_HAS_GPARENT_INTC_INTERNAL(node_id), (DT_IRQN_L3_INTERNAL(node_id, idx)), \ + (COND_CODE_1(DT_HAS_PARENT_INTC_INTERNAL(node_id), \ + (DT_IRQN_L2_INTERNAL(node_id, idx)), \ + (DT_IRQN_BY_IDX_INTERNAL(node_id, idx))))) + +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @brief Get the node's Zephyr interrupt number at index + * If @kconfig{CONFIG_MULTI_LEVEL_INTERRUPTS} is enabled, the interrupt number at index will be + * multi-level encoded + * @param node_id node identifier + * @param idx logical index into the interrupt specifier array + * @return the Zephyr interrupt number + */ +#define DT_IRQN_BY_IDX(node_id, idx) \ + COND_CODE_1(IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS), \ + (DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx)), \ + (DT_IRQN_BY_IDX_INTERNAL(node_id, idx))) + /** * @brief Get a node's (only) irq number * @@ -2419,7 +2491,7 @@ * @param node_id node identifier * @return the interrupt number for the node's only interrupt */ -#define DT_IRQN(node_id) DT_IRQ(node_id, irq) +#define DT_IRQN(node_id) DT_IRQN_BY_IDX(node_id, 0) /** * @} @@ -3825,7 +3897,15 @@ * @param inst instance number * @return the interrupt number for the node's only interrupt */ -#define DT_INST_IRQN(inst) DT_INST_IRQ(inst, irq) +#define DT_INST_IRQN(inst) DT_IRQN(DT_DRV_INST(inst)) + +/** + * @brief Get a `DT_DRV_COMPAT`'s irq number at index + * @param inst instance number + * @param idx logical index into the interrupt specifier array + * @return the interrupt number for the node's idx-th interrupt + */ +#define DT_INST_IRQN_BY_IDX(inst, idx) DT_IRQN_BY_IDX(DT_DRV_INST(inst), idx) /** * @brief Get a `DT_DRV_COMPAT`'s bus node identifier diff --git a/include/zephyr/irq_multilevel.h b/include/zephyr/irq_multilevel.h index f9f082d46ad..7d320ca1419 100644 --- a/include/zephyr/irq_multilevel.h +++ b/include/zephyr/irq_multilevel.h @@ -13,6 +13,7 @@ #ifndef _ASMLANGUAGE #include +#include #ifdef __cplusplus extern "C" { diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index d21fdc75646..7721b5b4fe8 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -436,8 +436,7 @@ def write_interrupts(node): # interrupts property: we have some hard-coded logic for interrupt # mapping here. # - # TODO: can we push map_arm_gic_irq_type() and - # encode_zephyr_multi_level_irq() out of Python and into C with + # TODO: can we push map_arm_gic_irq_type() out of Python and into C with # macro magic in devicetree.h? def map_arm_gic_irq_type(irq, irq_num): @@ -453,21 +452,6 @@ def map_arm_gic_irq_type(irq, irq_num): return irq_num + 16 err(f"Invalid interrupt type specified for {irq!r}") - def encode_zephyr_multi_level_irq(irq, irq_num): - # See doc/kernel/services/interrupts.rst for details - # on how this encoding works - - irq_ctrl = irq.controller - # Look for interrupt controller parent until we have none - while irq_ctrl.interrupts: - irq_num = (irq_num + 1) << 8 - if "irq" not in irq_ctrl.interrupts[0].data: - err(f"Expected binding for {irq_ctrl!r} to have 'irq' in " - "interrupt-cells") - irq_num |= irq_ctrl.interrupts[0].data["irq"] - irq_ctrl = irq_ctrl.interrupts[0].controller - return irq_num - idx_vals = [] name_vals = [] path_id = node.z_path_id @@ -482,7 +466,6 @@ def encode_zephyr_multi_level_irq(irq, irq_num): if cell_name == "irq": if "arm,gic" in irq.controller.compats: cell_value = map_arm_gic_irq_type(irq, cell_value) - cell_value = encode_zephyr_multi_level_irq(irq, cell_value) idx_vals.append((f"{path_id}_IRQ_IDX_{i}_EXISTS", 1)) idx_macro = f"{path_id}_IRQ_IDX_{i}_VAL_{name}" From 1782011d2c954015b5273c3670e9752409e70a7c Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 4 Oct 2023 21:59:13 +0800 Subject: [PATCH 2805/4498] tests: devicetree: api: add tests for new DT APIs Add tests for new DT APIs added in the previous commit: - `DT_IRQN_BY_IDX` - `DT_INST_IRQN_BY_IDX` Added additional tests for the following existing DT APIs when `CONFIG_MULTI_LEVEL_INTERRUPTS` is enabled: - `DT_IRQN` - `DT_INST_IRQN` Added `qemu_riscv32` for the multi-level interrupt tests. Signed-off-by: Yong Cong Sin --- tests/lib/devicetree/api/app.overlay | 2 ++ tests/lib/devicetree/api/src/main.c | 38 ++++++++++++++++++++++++++ tests/lib/devicetree/api/testcase.yaml | 1 + 3 files changed, 41 insertions(+) diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 585008a8837..64010f0c8ef 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -415,6 +415,7 @@ reg = <0xbbbbcccc 0x1000>; interrupt-controller; #interrupt-cells = <2>; + interrupts = <11 0>; }; /* there should only be one of these */ @@ -422,6 +423,7 @@ compatible = "vnd,interrupt-holder"; status = "okay"; interrupts = <30 3 40 5 60 7>; + interrupt-parent = <&test_intc>; interrupt-names = "err", "stat", "done"; }; diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 255357e85e8..019f5845a38 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -707,6 +707,26 @@ ZTEST(devicetree_api, test_irq) /* DT_IRQN */ zassert_equal(DT_IRQN(TEST_I2C_BUS), 6, ""); + #ifndef CONFIG_MULTI_LEVEL_INTERRUPTS + zassert_equal(DT_IRQN(DT_INST(0, DT_DRV_COMPAT)), 30, ""); + #else + zassert_equal(DT_IRQN(DT_INST(0, DT_DRV_COMPAT)), + ((30 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); + #endif + + /* DT_IRQN_BY_IDX */ +#ifndef CONFIG_MULTI_LEVEL_INTERRUPTS + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 0), 30, ""); + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 1), 40, ""); + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 2), 60, ""); +#else + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 0), + ((30 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 1), + ((40 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); + zassert_equal(DT_IRQN_BY_IDX(DT_INST(0, DT_DRV_COMPAT), 2), + ((60 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); +#endif /* DT_INST */ zassert_equal(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT), 1, ""); @@ -738,7 +758,25 @@ ZTEST(devicetree_api, test_irq) zassert_equal(DT_INST_IRQ(0, priority), 3, ""); /* DT_INST_IRQN */ +#ifndef CONFIG_MULTI_LEVEL_INTERRUPTS zassert_equal(DT_INST_IRQN(0), 30, ""); +#else + zassert_equal(DT_INST_IRQN(0), ((30 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); +#endif + + /* DT_INST_IRQN_BY_IDX */ +#ifndef CONFIG_MULTI_LEVEL_INTERRUPTS + zassert_equal(DT_INST_IRQN_BY_IDX(0, 0), 30, ""); + zassert_equal(DT_INST_IRQN_BY_IDX(0, 1), 40, ""); + zassert_equal(DT_INST_IRQN_BY_IDX(0, 2), 60, ""); +#else + zassert_equal(DT_INST_IRQN_BY_IDX(0, 0), + ((30 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); + zassert_equal(DT_INST_IRQN_BY_IDX(0, 1), + ((40 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); + zassert_equal(DT_INST_IRQN_BY_IDX(0, 2), + ((60 + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS) | 11, ""); +#endif /* DT_INST_IRQ_HAS_CELL_AT_IDX */ zassert_true(DT_INST_IRQ_HAS_CELL_AT_IDX(0, 0, irq), ""); diff --git a/tests/lib/devicetree/api/testcase.yaml b/tests/lib/devicetree/api/testcase.yaml index d8418201cc4..105f7c73ebf 100644 --- a/tests/lib/devicetree/api/testcase.yaml +++ b/tests/lib/devicetree/api/testcase.yaml @@ -8,5 +8,6 @@ tests: - qemu_x86 - qemu_x86_64 - qemu_cortex_m3 + - qemu_riscv32 integration_platforms: - native_posix From f289c3149b913d7947a64bc4869eeaf0e721c0db Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Mon, 30 Oct 2023 15:26:47 +0100 Subject: [PATCH 2806/4498] doc: kernel: Fix double "the" for k_thread_deadline_set() Fix double "the" in the k_thread_deadline_set() description. Signed-off-by: Andrej Butok --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 607f08320d6..81ee52e2446 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -879,7 +879,7 @@ __syscall void k_thread_priority_set(k_tid_t thread, int prio); * may result in scheduled threads running in an incorrect deadline * order. * - * @note Despite the API naming, the scheduler makes no guarantees the + * @note Despite the API naming, the scheduler makes no guarantees * the thread WILL be scheduled within that deadline, nor does it take * extra metadata (like e.g. the "runtime" and "period" parameters in * Linux sched_setattr()) that allows the kernel to validate the From bbab631021f79508fa6ffbbb9e1da1fdff445d54 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 26 Oct 2023 11:53:24 +0200 Subject: [PATCH 2807/4498] twister: unittests: Use mock for os.name in unittests Use mock.patch instead of monkeypatch for os.name in unittests to fix error when executing tests under VSCode Signed-off-by: Grzegorz Chwierut --- scripts/tests/twister/test_testinstance.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/tests/twister/test_testinstance.py b/scripts/tests/twister/test_testinstance.py index 823eaeb3393..73a3c8f7dfb 100644 --- a/scripts/tests/twister/test_testinstance.py +++ b/scripts/tests/twister/test_testinstance.py @@ -11,6 +11,8 @@ import sys import pytest +from unittest import mock + ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) from twisterlib.testinstance import TestInstance @@ -29,7 +31,7 @@ (False, True, "sensor", "native", "", True, [], (True, False)), ] @pytest.mark.parametrize("build_only, slow, harness, platform_type, platform_sim, device_testing,fixture, expected", TESTDATA_1) -def test_check_build_or_run(class_testplan, monkeypatch, all_testsuites_dict, platforms_list, build_only, slow, harness, platform_type, platform_sim, device_testing, fixture, expected): +def test_check_build_or_run(class_testplan, all_testsuites_dict, platforms_list, build_only, slow, harness, platform_type, platform_sim, device_testing, fixture, expected): """" Test to check the conditions for build_only and run scenarios Scenario 1: Test when different parameters are passed, build_only and run are set correctly Scenario 2: Test if build_only is enabled when the OS is Windows""" @@ -51,9 +53,9 @@ def test_check_build_or_run(class_testplan, monkeypatch, all_testsuites_dict, pl _, r = expected assert run == r - monkeypatch.setattr("os.name", "nt") - run = testinstance.check_runnable() - assert not run + with mock.patch('os.name', 'nt'): + run = testinstance.check_runnable() + assert not run TESTDATA_2 = [ (True, True, True, ["demo_board_2"], "native", None, '\nCONFIG_COVERAGE=y\nCONFIG_COVERAGE_DUMP=y\nCONFIG_ASAN=y\nCONFIG_UBSAN=y'), From 01d61ba18b5a5b817d3ede733a30c22e87c436f8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:35:27 -0700 Subject: [PATCH 2808/4498] headers: kernel: Drop extern attr from functions Using extern attribute in function signatures is not necessary and it is not consistently across Zephyr headers. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel.h | 84 ++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 81ee52e2446..b1b643df4a2 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -118,7 +118,7 @@ typedef void (*k_thread_user_cb_t)(const struct k_thread *thread, * list which means creation of new threads and terminations of existing * threads are blocked until this API returns. */ -extern void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data); +void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data); /** * @brief Iterate over all the threads in the system without locking. @@ -147,7 +147,7 @@ extern void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data); * Do not reuse the memory that was occupied by k_thread structure of aborted * task if it was aborted after this function was called in any context. */ -extern void k_thread_foreach_unlocked( +void k_thread_foreach_unlocked( k_thread_user_cb_t user_cb, void *user_data); /** @} */ @@ -371,7 +371,7 @@ __syscall k_tid_t k_thread_create(struct k_thread *new_thread, * @param p2 2nd entry point parameter * @param p3 3rd entry point parameter */ -extern FUNC_NORETURN void k_thread_user_mode_enter(k_thread_entry_t entry, +FUNC_NORETURN void k_thread_user_mode_enter(k_thread_entry_t entry, void *p1, void *p2, void *p3); @@ -643,8 +643,8 @@ __syscall void k_thread_abort(k_tid_t thread); */ __syscall void k_thread_start(k_tid_t thread); -extern k_ticks_t z_timeout_expires(const struct _timeout *timeout); -extern k_ticks_t z_timeout_remaining(const struct _timeout *timeout); +k_ticks_t z_timeout_expires(const struct _timeout *timeout); +k_ticks_t z_timeout_remaining(const struct _timeout *timeout); #ifdef CONFIG_SYS_CLOCK_EXISTS @@ -1022,7 +1022,7 @@ __syscall void k_thread_resume(k_tid_t thread); * @param slice Maximum time slice length (in milliseconds). * @param prio Highest thread priority level eligible for time slicing. */ -extern void k_sched_time_slice_set(int32_t slice, int prio); +void k_sched_time_slice_set(int32_t slice, int prio); /** * @brief Set thread time slice @@ -1083,7 +1083,7 @@ void k_thread_time_slice_set(struct k_thread *th, int32_t slice_ticks, * @return false if invoked by a thread. * @return true if invoked by an ISR. */ -extern bool k_is_in_isr(void); +bool k_is_in_isr(void); /** * @brief Determine if code is running in a preemptible thread. @@ -1155,7 +1155,7 @@ static inline bool k_is_pre_kernel(void) * In general this is a historical API not well-suited to modern * applications, use with care. */ -extern void k_sched_lock(void); +void k_sched_lock(void); /** * @brief Unlock the scheduler. @@ -1164,7 +1164,7 @@ extern void k_sched_lock(void); * A thread must call the routine once for each time it called k_sched_lock() * before the thread becomes preemptible. */ -extern void k_sched_unlock(void); +void k_sched_unlock(void); /** * @brief Set current thread's custom data. @@ -1561,7 +1561,7 @@ typedef void (*k_timer_stop_t)(struct k_timer *timer); * @param expiry_fn Function to invoke each time the timer expires. * @param stop_fn Function to invoke if the timer is stopped while running. */ -extern void k_timer_init(struct k_timer *timer, +void k_timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn, k_timer_stop_t stop_fn); @@ -1911,7 +1911,7 @@ __syscall void k_queue_cancel_wait(struct k_queue *queue); * @param queue Address of the queue. * @param data Address of the data item. */ -extern void k_queue_append(struct k_queue *queue, void *data); +void k_queue_append(struct k_queue *queue, void *data); /** * @brief Append an element to a queue. @@ -1943,7 +1943,7 @@ __syscall int32_t k_queue_alloc_append(struct k_queue *queue, void *data); * @param queue Address of the queue. * @param data Address of the data item. */ -extern void k_queue_prepend(struct k_queue *queue, void *data); +void k_queue_prepend(struct k_queue *queue, void *data); /** * @brief Prepend an element to a queue. @@ -1976,7 +1976,7 @@ __syscall int32_t k_queue_alloc_prepend(struct k_queue *queue, void *data); * @param prev Address of the previous data item. * @param data Address of the data item. */ -extern void k_queue_insert(struct k_queue *queue, void *prev, void *data); +void k_queue_insert(struct k_queue *queue, void *prev, void *data); /** * @brief Atomically append a list of elements to a queue. @@ -1996,7 +1996,7 @@ extern void k_queue_insert(struct k_queue *queue, void *prev, void *data); * @retval -EINVAL on invalid supplied data * */ -extern int k_queue_append_list(struct k_queue *queue, void *head, void *tail); +int k_queue_append_list(struct k_queue *queue, void *head, void *tail); /** * @brief Atomically add a list of elements to a queue. @@ -2013,7 +2013,7 @@ extern int k_queue_append_list(struct k_queue *queue, void *head, void *tail); * @retval 0 on success * @retval -EINVAL on invalid data */ -extern int k_queue_merge_slist(struct k_queue *queue, sys_slist_t *list); +int k_queue_merge_slist(struct k_queue *queue, sys_slist_t *list); /** * @brief Get an element from a queue. @@ -3350,7 +3350,7 @@ int k_work_submit_to_queue(struct k_work_q *queue, * * @return as with k_work_submit_to_queue(). */ -extern int k_work_submit(struct k_work *work); +int k_work_submit(struct k_work *work); /** @brief Wait for last-submitted instance to complete. * @@ -3653,7 +3653,7 @@ int k_work_schedule_for_queue(struct k_work_q *queue, * * @return as with k_work_schedule_for_queue(). */ -extern int k_work_schedule(struct k_work_delayable *dwork, +int k_work_schedule(struct k_work_delayable *dwork, k_timeout_t delay); /** @brief Reschedule a work item to a queue after a delay. @@ -3707,7 +3707,7 @@ int k_work_reschedule_for_queue(struct k_work_q *queue, * * @return as with k_work_reschedule_for_queue(). */ -extern int k_work_reschedule(struct k_work_delayable *dwork, +int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay); /** @brief Flush delayable work. @@ -4228,7 +4228,7 @@ static inline int k_work_user_submit_to_queue(struct k_work_user_q *work_q, * @param name optional thread name. If not null a copy is made into the * thread's name buffer. */ -extern void k_work_user_queue_start(struct k_work_user_q *work_q, +void k_work_user_queue_start(struct k_work_user_q *work_q, k_thread_stack_t *stack, size_t stack_size, int prio, const char *name); @@ -4297,7 +4297,7 @@ struct k_work_poll { * @param work Address of triggered work item. * @param handler Function to invoke each time work item is processed. */ -extern void k_work_poll_init(struct k_work_poll *work, +void k_work_poll_init(struct k_work_poll *work, k_work_handler_t handler); /** @@ -4334,7 +4334,7 @@ extern void k_work_poll_init(struct k_work_poll *work, * @retval -EINVAL Work item is being processed or has completed its work. * @retval -EADDRINUSE Work item is pending on a different workqueue. */ -extern int k_work_poll_submit_to_queue(struct k_work_q *work_q, +int k_work_poll_submit_to_queue(struct k_work_q *work_q, struct k_work_poll *work, struct k_poll_event *events, int num_events, @@ -4371,7 +4371,7 @@ extern int k_work_poll_submit_to_queue(struct k_work_q *work_q, * @retval -EINVAL Work item is being processed or has completed its work. * @retval -EADDRINUSE Work item is pending on a different workqueue. */ -extern int k_work_poll_submit(struct k_work_poll *work, +int k_work_poll_submit(struct k_work_poll *work, struct k_poll_event *events, int num_events, k_timeout_t timeout); @@ -4390,7 +4390,7 @@ extern int k_work_poll_submit(struct k_work_poll *work, * @retval 0 Work item canceled. * @retval -EINVAL Work item is being processed or has completed its work. */ -extern int k_work_poll_cancel(struct k_work_poll *work); +int k_work_poll_cancel(struct k_work_poll *work); /** @} */ @@ -4766,7 +4766,7 @@ struct k_mbox { * * @param mbox Address of the mailbox. */ -extern void k_mbox_init(struct k_mbox *mbox); +void k_mbox_init(struct k_mbox *mbox); /** * @brief Send a mailbox message in a synchronous manner. @@ -4787,7 +4787,7 @@ extern void k_mbox_init(struct k_mbox *mbox); * @retval -ENOMSG Returned without waiting. * @retval -EAGAIN Waiting period timed out. */ -extern int k_mbox_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, +int k_mbox_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, k_timeout_t timeout); /** @@ -4803,7 +4803,7 @@ extern int k_mbox_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, * @param tx_msg Address of the transmit message descriptor. * @param sem Address of a semaphore, or NULL if none is needed. */ -extern void k_mbox_async_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, +void k_mbox_async_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, struct k_sem *sem); /** @@ -4823,7 +4823,7 @@ extern void k_mbox_async_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, * @retval -ENOMSG Returned without waiting. * @retval -EAGAIN Waiting period timed out. */ -extern int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, +int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer, k_timeout_t timeout); /** @@ -4839,7 +4839,7 @@ extern int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, * @param buffer Address of the buffer to receive data, or NULL to discard * the data. */ -extern void k_mbox_data_get(struct k_mbox_msg *rx_msg, void *buffer); +void k_mbox_data_get(struct k_mbox_msg *rx_msg, void *buffer); /** @} */ @@ -5175,7 +5175,7 @@ struct k_mem_slab { * @retval -EINVAL invalid data supplied * */ -extern int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, +int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, size_t block_size, uint32_t num_blocks); /** @@ -5200,7 +5200,7 @@ extern int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, * @retval -EAGAIN Waiting period timed out. * @retval -EINVAL Invalid data supplied */ -extern int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, +int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout); /** @@ -5212,7 +5212,7 @@ extern int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, * @param slab Address of the memory slab. * @param mem Pointer to the memory block (as returned by k_mem_slab_alloc()). */ -extern void k_mem_slab_free(struct k_mem_slab *slab, void *mem); +void k_mem_slab_free(struct k_mem_slab *slab, void *mem); /** * @brief Get the number of used blocks in a memory slab. @@ -5474,7 +5474,7 @@ void k_heap_free(struct k_heap *h, void *mem); * * @return Address of the allocated memory if successful; otherwise NULL. */ -extern void *k_aligned_alloc(size_t align, size_t size); +void *k_aligned_alloc(size_t align, size_t size); /** * @brief Allocate memory from the heap. @@ -5487,7 +5487,7 @@ extern void *k_aligned_alloc(size_t align, size_t size); * * @return Address of the allocated memory if successful; otherwise NULL. */ -extern void *k_malloc(size_t size); +void *k_malloc(size_t size); /** * @brief Free memory allocated from heap. @@ -5499,7 +5499,7 @@ extern void *k_malloc(size_t size); * * @param ptr Pointer to previously allocated memory. */ -extern void k_free(void *ptr); +void k_free(void *ptr); /** * @brief Allocate memory from heap, array style @@ -5512,7 +5512,7 @@ extern void k_free(void *ptr); * * @return Address of the allocated memory if successful; otherwise NULL. */ -extern void *k_calloc(size_t nmemb, size_t size); +void *k_calloc(size_t nmemb, size_t size); /** @} */ @@ -5724,7 +5724,7 @@ struct k_poll_event { * @param obj Kernel object or poll signal. */ -extern void k_poll_event_init(struct k_poll_event *event, uint32_t type, +void k_poll_event_init(struct k_poll_event *event, uint32_t type, int mode, void *obj); /** @@ -5947,7 +5947,7 @@ static inline void k_cpu_atomic_idle(unsigned int key) /** * @internal */ -extern void z_init_static_threads(void); +void z_init_static_threads(void); #else /** * @internal @@ -5958,7 +5958,7 @@ extern void z_init_static_threads(void); /** * @internal */ -extern void z_timer_expiration_handler(struct _timeout *t); +void z_timer_expiration_handler(struct _timeout *t); /** * INTERNAL_HIDDEN @endcond */ @@ -6063,7 +6063,7 @@ int k_thread_runtime_stats_all_get(k_thread_runtime_stats_t *stats); * @param thread ID of thread * @return -EINVAL if invalid thread ID, otherwise 0 */ -extern int k_thread_runtime_stats_enable(k_tid_t thread); +int k_thread_runtime_stats_enable(k_tid_t thread); /** * @brief Disable gathering of runtime statistics for specified thread @@ -6074,7 +6074,7 @@ extern int k_thread_runtime_stats_enable(k_tid_t thread); * @param thread ID of thread * @return -EINVAL if invalid thread ID, otherwise 0 */ -extern int k_thread_runtime_stats_disable(k_tid_t thread); +int k_thread_runtime_stats_disable(k_tid_t thread); /** * @brief Enable gathering of system runtime statistics @@ -6083,7 +6083,7 @@ extern int k_thread_runtime_stats_disable(k_tid_t thread); * it does not affect the gathering of similar statistics for individual * threads. */ -extern void k_sys_runtime_stats_enable(void); +void k_sys_runtime_stats_enable(void); /** * @brief Disable gathering of system runtime statistics @@ -6092,7 +6092,7 @@ extern void k_sys_runtime_stats_enable(void); * it does not affect the gathering of similar statistics for individual * threads. */ -extern void k_sys_runtime_stats_disable(void); +void k_sys_runtime_stats_disable(void); #ifdef __cplusplus } From 1f86454d1a9ca7e8652b3a091fb2a5e9c14eace5 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:37:55 -0700 Subject: [PATCH 2809/4498] headers: sys/reboot: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/sys/reboot.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/sys/reboot.h b/include/zephyr/sys/reboot.h index 50d68870683..293a5875451 100644 --- a/include/zephyr/sys/reboot.h +++ b/include/zephyr/sys/reboot.h @@ -32,7 +32,7 @@ extern "C" { * * When successful, this routine does not return. */ -extern FUNC_NORETURN void sys_reboot(int type); +FUNC_NORETURN void sys_reboot(int type); #ifdef __cplusplus } From a077079f4566d267e4b5f0a5f387a3a6a5430e69 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:39:12 -0700 Subject: [PATCH 2810/4498] headers: sys/atomic: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/sys/atomic_c.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sys/atomic_c.h b/include/zephyr/sys/atomic_c.h index ee368c28f42..0ea6e6dfa34 100644 --- a/include/zephyr/sys/atomic_c.h +++ b/include/zephyr/sys/atomic_c.h @@ -39,9 +39,9 @@ static inline atomic_val_t atomic_dec(atomic_t *target) } -extern atomic_val_t atomic_get(const atomic_t *target); +atomic_val_t atomic_get(const atomic_t *target); -extern atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target); +atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target); __syscall atomic_val_t atomic_set(atomic_t *target, atomic_val_t value); From 51754e3a53561af94be6265481067ef54cc821ba Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:45:26 -0700 Subject: [PATCH 2811/4498] headers: sys/atomic_arch: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/sys/atomic_arch.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/zephyr/sys/atomic_arch.h b/include/zephyr/sys/atomic_arch.h index fad339bf933..7305743c4fb 100644 --- a/include/zephyr/sys/atomic_arch.h +++ b/include/zephyr/sys/atomic_arch.h @@ -11,39 +11,39 @@ /* Arch specific atomic primitives */ -extern bool atomic_cas(atomic_t *target, atomic_val_t old_value, +bool atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value); -extern bool atomic_ptr_cas(atomic_ptr_t *target, void *old_value, +bool atomic_ptr_cas(atomic_ptr_t *target, void *old_value, void *new_value); -extern atomic_val_t atomic_add(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_add(atomic_t *target, atomic_val_t value); -extern atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value); -extern atomic_val_t atomic_inc(atomic_t *target); +atomic_val_t atomic_inc(atomic_t *target); -extern atomic_val_t atomic_dec(atomic_t *target); +atomic_val_t atomic_dec(atomic_t *target); -extern atomic_val_t atomic_get(const atomic_t *target); +atomic_val_t atomic_get(const atomic_t *target); -extern void *atomic_ptr_get(const atomic_ptr_t *target); +void *atomic_ptr_get(const atomic_ptr_t *target); -extern atomic_val_t atomic_set(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_set(atomic_t *target, atomic_val_t value); -extern void *atomic_ptr_set(atomic_ptr_t *target, void *value); +void *atomic_ptr_set(atomic_ptr_t *target, void *value); -extern atomic_val_t atomic_clear(atomic_t *target); +atomic_val_t atomic_clear(atomic_t *target); -extern void *atomic_ptr_clear(atomic_ptr_t *target); +void *atomic_ptr_clear(atomic_ptr_t *target); -extern atomic_val_t atomic_or(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_or(atomic_t *target, atomic_val_t value); -extern atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value); -extern atomic_val_t atomic_and(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_and(atomic_t *target, atomic_val_t value); -extern atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value); +atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value); #endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_ARCH_H_ */ From a629ac5fac80716a97f27c1cc931c365759eb1cd Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:47:13 -0700 Subject: [PATCH 2812/4498] headers: posix/unistd: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/posix/unistd.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/zephyr/posix/unistd.h b/include/zephyr/posix/unistd.h index ec8bf7e6adb..b55cf702fec 100644 --- a/include/zephyr/posix/unistd.h +++ b/include/zephyr/posix/unistd.h @@ -23,16 +23,16 @@ extern "C" { #ifdef CONFIG_POSIX_API /* File related operations */ -extern int close(int file); -extern ssize_t write(int file, const void *buffer, size_t count); -extern ssize_t read(int file, void *buffer, size_t count); -extern off_t lseek(int file, off_t offset, int whence); +int close(int file); +ssize_t write(int file, const void *buffer, size_t count); +ssize_t read(int file, void *buffer, size_t count); +off_t lseek(int file, off_t offset, int whence); /* File System related operations */ -extern int rename(const char *old, const char *newp); -extern int unlink(const char *path); -extern int stat(const char *path, struct stat *buf); -extern int mkdir(const char *path, mode_t mode); +int rename(const char *old, const char *newp); +int unlink(const char *path); +int stat(const char *path, struct stat *buf); +int mkdir(const char *path, mode_t mode); FUNC_NORETURN void _exit(int status); From 49a2ff75d39f0f44a1a2f9dd3c2adfa444142bc4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:48:15 -0700 Subject: [PATCH 2813/4498] headers: kernel_version: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel_version.h b/include/zephyr/kernel_version.h index 6d3109fed30..7a21b437768 100644 --- a/include/zephyr/kernel_version.h +++ b/include/zephyr/kernel_version.h @@ -44,7 +44,7 @@ extern "C" { * * @return kernel version */ -extern uint32_t sys_kernel_version_get(void); +uint32_t sys_kernel_version_get(void); /** * @} From b7c3965991efca80d6045036cca53de56728f73b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:48:48 -0700 Subject: [PATCH 2814/4498] headers: kernel_structs: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel_structs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index d066db620ce..692d8229403 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -232,7 +232,7 @@ typedef struct { struct _priq_rb waitq; } _wait_q_t; -extern bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); +bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); #define Z_WAIT_Q_INIT(wait_q) { { { .lessthan_fn = z_priq_rb_lessthan } } } From 079a83d7f18d6fdb8299683e0871517acf6f0fdc Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:50:07 -0700 Subject: [PATCH 2815/4498] headers: sys/printk: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/sys/printk.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/sys/printk.h b/include/zephyr/sys/printk.h index b5821ed971e..795018ae4f8 100644 --- a/include/zephyr/sys/printk.h +++ b/include/zephyr/sys/printk.h @@ -44,8 +44,8 @@ extern "C" { */ #ifdef CONFIG_PRINTK -extern __printf_like(1, 2) void printk(const char *fmt, ...); -extern __printf_like(1, 0) void vprintk(const char *fmt, va_list ap); +__printf_like(1, 2) void printk(const char *fmt, ...); +__printf_like(1, 0) void vprintk(const char *fmt, va_list ap); #else static inline __printf_like(1, 2) void printk(const char *fmt, ...) @@ -69,9 +69,9 @@ static inline __printf_like(1, 0) void vprintk(const char *fmt, va_list ap) #else -extern __printf_like(3, 4) int snprintk(char *str, size_t size, +__printf_like(3, 4) int snprintk(char *str, size_t size, const char *fmt, ...); -extern __printf_like(3, 0) int vsnprintk(char *str, size_t size, +__printf_like(3, 0) int vsnprintk(char *str, size_t size, const char *fmt, va_list ap); #endif From f1482c18c24cde44ad9e2eefa9961d2009d94a78 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 12:50:51 -0700 Subject: [PATCH 2816/4498] headers: posix/dirent: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/posix/dirent.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/posix/dirent.h b/include/zephyr/posix/dirent.h index 31c2a2cee4c..43c68983ebb 100644 --- a/include/zephyr/posix/dirent.h +++ b/include/zephyr/posix/dirent.h @@ -24,9 +24,9 @@ struct dirent { }; /* Directory related operations */ -extern DIR *opendir(const char *dirname); -extern int closedir(DIR *dirp); -extern struct dirent *readdir(DIR *dirp); +DIR *opendir(const char *dirname); +int closedir(DIR *dirp); +struct dirent *readdir(DIR *dirp); #ifdef __cplusplus } From 991070237843432167027ab8789324cb01a00d45 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 13:05:57 -0700 Subject: [PATCH 2817/4498] headers: sw_isr_table: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/sw_isr_table.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index 9508e60e24c..7db7381422b 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -23,10 +23,10 @@ extern "C" { #endif /* Default vector for the IRQ vector table */ -extern void _isr_wrapper(void); +void _isr_wrapper(void); /* Spurious interrupt handler. Throws an error if called */ -extern void z_irq_spurious(const void *unused); +void z_irq_spurious(const void *unused); /* * Note the order: arg first, then ISR. This allows a table entry to be From 8aa215ff4576081de9581076c1fcd778c8d2c4c4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 13:07:54 -0700 Subject: [PATCH 2818/4498] headers: syscall_handler: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/syscall_handler.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/zephyr/syscall_handler.h b/include/zephyr/syscall_handler.h index 7e06c5a7a54..ac6d47a23a4 100644 --- a/include/zephyr/syscall_handler.h +++ b/include/zephyr/syscall_handler.h @@ -89,8 +89,8 @@ int z_object_validate(struct z_object *ko, enum k_objects otype, * @param ko If retval=-EPERM, struct z_object * that was looked up, or NULL * @param otype Expected type of the kernel object */ -extern void z_dump_object_error(int retval, const void *obj, - struct z_object *ko, enum k_objects otype); +void z_dump_object_error(int retval, const void *obj, + struct z_object *ko, enum k_objects otype); /** * Kernel object validation function @@ -102,7 +102,7 @@ extern void z_dump_object_error(int retval, const void *obj, * @return Kernel object's metadata, or NULL if the parameter wasn't the * memory address of a kernel object */ -extern struct z_object *z_object_find(const void *obj); +struct z_object *z_object_find(const void *obj); typedef void (*_wordlist_cb_func_t)(struct z_object *ko, void *context); @@ -112,7 +112,7 @@ typedef void (*_wordlist_cb_func_t)(struct z_object *ko, void *context); * @param func function to run on each struct z_object * @param context Context pointer to pass to each invocation */ -extern void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); +void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); /** * Copy all kernel object permissions from the parent to the child @@ -120,7 +120,7 @@ extern void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); * @param parent Parent thread, to get permissions from * @param child Child thread, to copy permissions to */ -extern void z_thread_perms_inherit(struct k_thread *parent, +void z_thread_perms_inherit(struct k_thread *parent, struct k_thread *child); /** @@ -129,7 +129,7 @@ extern void z_thread_perms_inherit(struct k_thread *parent, * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -extern void z_thread_perms_set(struct z_object *ko, struct k_thread *thread); +void z_thread_perms_set(struct z_object *ko, struct k_thread *thread); /** * Revoke a thread's permission to a kernel object @@ -137,7 +137,7 @@ extern void z_thread_perms_set(struct z_object *ko, struct k_thread *thread); * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -extern void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread); +void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread); /* * Revoke access to all objects for the provided thread @@ -147,7 +147,7 @@ extern void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread); * * @param thread Thread object to revoke access */ -extern void z_thread_perms_all_clear(struct k_thread *thread); +void z_thread_perms_all_clear(struct k_thread *thread); /** * Clear initialization state of a kernel object @@ -222,7 +222,7 @@ static inline size_t z_user_string_nlen(const char *src, size_t maxlen, * @return An allocated buffer with the data copied within it, or NULL * if some error condition occurred */ -extern void *z_user_alloc_from_copy(const void *src, size_t size); +void *z_user_alloc_from_copy(const void *src, size_t size); /** * @brief Copy data from user mode @@ -237,7 +237,7 @@ extern void *z_user_alloc_from_copy(const void *src, size_t size); * @retval 0 On success * @retval EFAULT On memory access error */ -extern int z_user_from_copy(void *dst, const void *src, size_t size); +int z_user_from_copy(void *dst, const void *src, size_t size); /** * @brief Copy data to user mode @@ -252,7 +252,7 @@ extern int z_user_from_copy(void *dst, const void *src, size_t size); * @retval 0 On success * @retval EFAULT On memory access error */ -extern int z_user_to_copy(void *dst, const void *src, size_t size); +int z_user_to_copy(void *dst, const void *src, size_t size); /** * @brief Copy a C string from userspace into a resource pool allocation @@ -268,7 +268,7 @@ extern int z_user_to_copy(void *dst, const void *src, size_t size); * @param maxlen Maximum size of the string including trailing NULL * @return The duplicated string, or NULL if an error occurred. */ -extern char *z_user_string_alloc_copy(const char *src, size_t maxlen); +char *z_user_string_alloc_copy(const char *src, size_t maxlen); /** * @brief Copy a C string from userspace into a provided buffer @@ -286,7 +286,7 @@ extern char *z_user_string_alloc_copy(const char *src, size_t maxlen); * to maxlen * @retval EFAULT On memory access error */ -extern int z_user_string_copy(char *dst, const char *src, size_t maxlen); +int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_OOPS(expr) \ do { \ From ecc544d69f045e218b1e33530712ec5f7cb250d6 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 13:09:21 -0700 Subject: [PATCH 2819/4498] headers: arch/cache: Drop extern attr from functions Drop extern attribute from function signature. Signed-off-by: Flavio Ceolin --- include/zephyr/arch/cache.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/zephyr/arch/cache.h b/include/zephyr/arch/cache.h index 59bdf61e0d0..8cbef3d2b9d 100644 --- a/include/zephyr/arch/cache.h +++ b/include/zephyr/arch/cache.h @@ -32,7 +32,7 @@ * * Enable the data cache. */ -extern void arch_dcache_enable(void); +void arch_dcache_enable(void); #define cache_data_enable arch_dcache_enable @@ -41,7 +41,7 @@ extern void arch_dcache_enable(void); * * Disable the data cache. */ -extern void arch_dcache_disable(void); +void arch_dcache_disable(void); #define cache_data_disable arch_dcache_disable @@ -54,7 +54,7 @@ extern void arch_dcache_disable(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_flush_all(void); +int arch_dcache_flush_all(void); #define cache_data_flush_all arch_dcache_flush_all @@ -67,7 +67,7 @@ extern int arch_dcache_flush_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_invd_all(void); +int arch_dcache_invd_all(void); #define cache_data_invd_all arch_dcache_invd_all @@ -80,7 +80,7 @@ extern int arch_dcache_invd_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_flush_and_invd_all(void); +int arch_dcache_flush_and_invd_all(void); #define cache_data_flush_and_invd_all arch_dcache_flush_and_invd_all @@ -103,7 +103,7 @@ extern int arch_dcache_flush_and_invd_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_flush_range(void *addr, size_t size); +int arch_dcache_flush_range(void *addr, size_t size); #define cache_data_flush_range(addr, size) arch_dcache_flush_range(addr, size) @@ -127,7 +127,7 @@ extern int arch_dcache_flush_range(void *addr, size_t size); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_invd_range(void *addr, size_t size); +int arch_dcache_invd_range(void *addr, size_t size); #define cache_data_invd_range(addr, size) arch_dcache_invd_range(addr, size) @@ -152,7 +152,7 @@ extern int arch_dcache_invd_range(void *addr, size_t size); * @retval -errno Negative errno for other failures. */ -extern int arch_dcache_flush_and_invd_range(void *addr, size_t size); +int arch_dcache_flush_and_invd_range(void *addr, size_t size); #define cache_data_flush_and_invd_range(addr, size) \ arch_dcache_flush_and_invd_range(addr, size) @@ -172,7 +172,7 @@ extern int arch_dcache_flush_and_invd_range(void *addr, size_t size); * @retval size Size of the d-cache line. * @retval 0 If the d-cache is not enabled. */ -extern size_t arch_dcache_line_size_get(void); +size_t arch_dcache_line_size_get(void); #define cache_data_line_size_get arch_dcache_line_size_get @@ -187,7 +187,7 @@ extern size_t arch_dcache_line_size_get(void); * * Enable the instruction cache. */ -extern void arch_icache_enable(void); +void arch_icache_enable(void); #define cache_instr_enable arch_icache_enable @@ -196,7 +196,7 @@ extern void arch_icache_enable(void); * * Disable the instruction cache. */ -extern void arch_icache_disable(void); +void arch_icache_disable(void); #define cache_instr_disable arch_icache_disable @@ -209,7 +209,7 @@ extern void arch_icache_disable(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_flush_all(void); +int arch_icache_flush_all(void); #define cache_instr_flush_all arch_icache_flush_all @@ -222,7 +222,7 @@ extern int arch_icache_flush_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_invd_all(void); +int arch_icache_invd_all(void); #define cache_instr_invd_all arch_icache_invd_all @@ -235,7 +235,7 @@ extern int arch_icache_invd_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_flush_and_invd_all(void); +int arch_icache_flush_and_invd_all(void); #define cache_instr_flush_and_invd_all arch_icache_flush_and_invd_all @@ -258,7 +258,7 @@ extern int arch_icache_flush_and_invd_all(void); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_flush_range(void *addr, size_t size); +int arch_icache_flush_range(void *addr, size_t size); #define cache_instr_flush_range(addr, size) arch_icache_flush_range(addr, size) @@ -282,7 +282,7 @@ extern int arch_icache_flush_range(void *addr, size_t size); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_invd_range(void *addr, size_t size); +int arch_icache_invd_range(void *addr, size_t size); #define cache_instr_invd_range(addr, size) arch_icache_invd_range(addr, size) @@ -306,7 +306,7 @@ extern int arch_icache_invd_range(void *addr, size_t size); * @retval -ENOTSUP If not supported. * @retval -errno Negative errno for other failures. */ -extern int arch_icache_flush_and_invd_range(void *addr, size_t size); +int arch_icache_flush_and_invd_range(void *addr, size_t size); #define cache_instr_flush_and_invd_range(addr, size) \ arch_icache_flush_and_invd_range(addr, size) @@ -327,7 +327,7 @@ extern int arch_icache_flush_and_invd_range(void *addr, size_t size); * @retval 0 If the d-cache is not enabled. */ -extern size_t arch_icache_line_size_get(void); +size_t arch_icache_line_size_get(void); #define cache_instr_line_size_get arch_icache_line_size_get From 0249f1576741e95de765d617500746dc17b8bda6 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 10 Oct 2023 14:45:11 +0200 Subject: [PATCH 2820/4498] tests: drivers: Fix adc labels in sensors test Fix the labels used in io-channels to be consistent in whole tests/drivers/build_all/sensor/adc.dtsi file. Signed-off-by: Franciszek Zdobylak --- tests/drivers/build_all/sensor/adc.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/drivers/build_all/sensor/adc.dtsi b/tests/drivers/build_all/sensor/adc.dtsi index e6e14ea0979..e05c9bd0368 100644 --- a/tests/drivers/build_all/sensor/adc.dtsi +++ b/tests/drivers/build_all/sensor/adc.dtsi @@ -45,7 +45,7 @@ test_adc_emul: adc-emul { test_adc_ntc_thermistor_generic: ntc-thermistor-generic { compatible = "ntc-thermistor-generic"; - io-channels = <&adc0 0>; + io-channels = <&test_adc 0>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; @@ -55,7 +55,7 @@ test_adc_ntc_thermistor_generic: ntc-thermistor-generic { test_adc_epcos_b57861s0103a039: epcos-b57861s0103a039 { compatible = "epcos,b57861s0103a039"; - io-channels = <&adc0 0>; + io-channels = <&test_adc 0>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; @@ -64,7 +64,7 @@ test_adc_epcos_b57861s0103a039: epcos-b57861s0103a039 { test_murata_ncp15wb473: murata-ncp15wb473 { compatible = "murata,ncp15wb473"; - io-channels = <&adc0 0>; + io-channels = <&test_adc 0>; pullup-uv = <3300000>; pullup-ohm = <0>; pulldown-ohm = <10000>; From 08f6532b67385523de186d9827eb10e8bfdea31f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 27 Oct 2023 13:00:43 +0200 Subject: [PATCH 2821/4498] Bluetooth: Controller: Fix corruption during BIG_CHANNEL_MAP_IND radio_pkt_big_ctrl_get() returns a statically allocated buffer of type pdu_big_ctrl, but the callers expect a buffer where a whole PDU for a BIG control packet can fit (not just space for the payload), and use it as such, overflowing this statically allocated buffer, and smashing other variables after. Let's fix it by allocating a buffer of the correct size to fit a BIG control PDU. Fixes https://github.com/zephyrproject-rtos/zephyr/issues/64497 Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 739c2d06962..90d75650439 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -671,9 +671,9 @@ void *radio_pkt_decrypt_get(void) #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) /* Dedicated Rx PDU Buffer for Control PDU independent of node_rx with BIS Data - * PDU buffer + * PDU buffer. Note this buffer will be used to store whole PDUs, not just the BIG control payload. */ -static uint8_t pkt_big_ctrl[sizeof(struct pdu_big_ctrl)]; +static uint8_t pkt_big_ctrl[offsetof(struct pdu_bis, payload) + sizeof(struct pdu_big_ctrl)]; void *radio_pkt_big_ctrl_get(void) { From d28262905e32802c51c4e8301b5c8b916bf16f96 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Mon, 30 Oct 2023 16:43:45 +0100 Subject: [PATCH 2822/4498] tests: kernel: fix thread function signatures Fix thread function signatures to avoid stack corruption on exit. Fixes #64578 Signed-off-by: Benedikt Schmidt --- tests/kernel/mem_protect/stackprot/src/main.c | 6 ++- tests/kernel/mutex/sys_mutex/src/main.c | 38 +++++++++++++++---- tests/kernel/sched/metairq/src/main.c | 18 +++++++-- tests/kernel/sleep/src/main.c | 9 ++--- tests/kernel/smp/src/main.c | 6 +-- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/tests/kernel/mem_protect/stackprot/src/main.c b/tests/kernel/mem_protect/stackprot/src/main.c index 6477f6ecf4f..94877687c46 100644 --- a/tests/kernel/mem_protect/stackprot/src/main.c +++ b/tests/kernel/mem_protect/stackprot/src/main.c @@ -78,8 +78,12 @@ void __attribute__((noinline)) check_input(const char *name, const char *input) * and will not set ret to TC_FAIL. * */ -void alternate_thread(void) +void alternate_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + TC_PRINT("Starts %s\n", __func__); check_input(__func__, "Input string is too long and stack overflowed!\n"); diff --git a/tests/kernel/mutex/sys_mutex/src/main.c b/tests/kernel/mutex/sys_mutex/src/main.c index d916a56dd9c..9da45b0bebe 100644 --- a/tests/kernel/mutex/sys_mutex/src/main.c +++ b/tests/kernel/mutex/sys_mutex/src/main.c @@ -100,8 +100,12 @@ static ZTEST_BMEM SYS_MUTEX_DEFINE(bad_count_mutex); * */ -void thread_05(void) +void thread_05(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(3500)); @@ -122,8 +126,12 @@ void thread_05(void) * */ -void thread_06(void) +void thread_06(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(3750)); @@ -153,8 +161,12 @@ void thread_06(void) * */ -void thread_07(void) +void thread_07(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(2500)); @@ -182,8 +194,12 @@ void thread_07(void) * */ -void thread_08(void) +void thread_08(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(1500)); @@ -205,8 +221,12 @@ void thread_08(void) * */ -void thread_09(void) +void thread_09(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(500)); /* Allow lower priority thread to run */ @@ -237,8 +257,12 @@ void thread_09(void) * */ -void thread_11(void) +void thread_11(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int rv; k_sleep(K_MSEC(3500)); @@ -253,7 +277,7 @@ void thread_11(void) K_THREAD_STACK_DEFINE(thread_12_stack_area, STACKSIZE); struct k_thread thread_12_thread_data; -extern void thread_12(void); +extern void thread_12(void *p1, void *p2, void *p3); diff --git a/tests/kernel/sched/metairq/src/main.c b/tests/kernel/sched/metairq/src/main.c index c7e3af99079..be8985413f2 100644 --- a/tests/kernel/sched/metairq/src/main.c +++ b/tests/kernel/sched/metairq/src/main.c @@ -59,8 +59,12 @@ volatile int coop_cnt2; #define LOOP_CNT 4 /* Number of times low priority thread waits */ /* Meta-IRQ thread */ -void metairq_thread(void) +void metairq_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + k_sem_take(&metairq_sem, K_FOREVER); printk("metairq start\n"); @@ -82,8 +86,12 @@ void metairq_thread(void) } /* High-priority cooperative thread */ -void coop_thread1(void) +void coop_thread1(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int cnt1, cnt2; printk("thread1 take sem\n"); @@ -109,8 +117,12 @@ void coop_thread1(void) } /* Low-priority cooperative thread */ -void coop_thread2(void) +void coop_thread2(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + int cnt1, cnt2; printk("thread2 take sem\n"); diff --git a/tests/kernel/sleep/src/main.c b/tests/kernel/sleep/src/main.c index f380200a6d9..89da43b82ca 100644 --- a/tests/kernel/sleep/src/main.c +++ b/tests/kernel/sleep/src/main.c @@ -102,10 +102,10 @@ static int sleep_time_valid(uint32_t start, uint32_t end, uint32_t dur) static void test_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); ARG_UNUSED(p3); - int arg1 = POINTER_TO_INT(p1); - int arg2 = POINTER_TO_INT(p2); uint32_t start_tick; uint32_t end_tick; @@ -177,11 +177,10 @@ static void irq_offload_isr(const void *arg) static void helper_thread(void *p1, void *p2, void *p3) { + ARG_UNUSED(p1); + ARG_UNUSED(p2); ARG_UNUSED(p3); - int arg1 = POINTER_TO_INT(p1); - int arg2 = POINTER_TO_INT(p2); - k_sem_take(&helper_thread_sem, K_FOREVER); /* Wake the test thread */ k_wakeup(test_thread_id); diff --git a/tests/kernel/smp/src/main.c b/tests/kernel/smp/src/main.c index 033df7839a4..698acb16af5 100644 --- a/tests/kernel/smp/src/main.c +++ b/tests/kernel/smp/src/main.c @@ -1079,15 +1079,15 @@ static int run_concurrency(void *p1, void *p2, void *p3) ZTEST(smp, test_inc_concurrency) { /* increasing global var with irq lock */ - zassert_true(run_concurrency(LOCK_IRQ, inc_global_cnt), + zassert_true(run_concurrency(INT_TO_POINTER(LOCK_IRQ), inc_global_cnt, NULL), "total count %d is wrong(i)", global_cnt); /* increasing global var with irq lock */ - zassert_true(run_concurrency(LOCK_SEM, inc_global_cnt), + zassert_true(run_concurrency(INT_TO_POINTER(LOCK_SEM), inc_global_cnt, NULL), "total count %d is wrong(s)", global_cnt); /* increasing global var with irq lock */ - zassert_true(run_concurrency(LOCK_MUTEX, inc_global_cnt), + zassert_true(run_concurrency(INT_TO_POINTER(LOCK_MUTEX), inc_global_cnt, NULL), "total count %d is wrong(M)", global_cnt); } From 169de2c0ee85dfce7a61da3164e5093a3d07ac73 Mon Sep 17 00:00:00 2001 From: Simon Hein Date: Tue, 25 Jul 2023 10:35:11 +0200 Subject: [PATCH 2823/4498] scripts: utils: add guidelines converter script Add a guidelines rst converter script to convert the rst document written coding guidelines into another format. First supported format is the format for cppcheck Signed-off-by: Simon Hein --- scripts/utils/convert_guidelines.py | 144 ++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100755 scripts/utils/convert_guidelines.py diff --git a/scripts/utils/convert_guidelines.py b/scripts/utils/convert_guidelines.py new file mode 100755 index 00000000000..a0530b9c7b4 --- /dev/null +++ b/scripts/utils/convert_guidelines.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023 Baumer (www.baumer.com) +# SPDX-License-Identifier: Apache-2.0 + +"""This script converting the Zephyr coding guideline rst file to a output file, +or print the output to the console. Which than can be used by a tool which +needs to have that information in a specific format (e.g. for cppcheck). +Or simply use the rule list to generate a filter to suppress all other rules +used by default from such a tool. +""" + +import sys +import re +import argparse +from pathlib import Path + +class RuleFormatter: + """ + Base class for the different output formats + """ + def table_start_print(self, outputfile): + pass + def severity_print(self, outputfile, guideline_number, severity): + pass + def description_print(self, outputfile, guideline_number, description): + pass + def closing_print(self, outputfile): + pass + +class CppCheckFormatter(RuleFormatter): + """ + Formatter class to print the rules in a format which can be used by cppcheck + """ + def table_start_print(self, outputfile): + # Start search by cppcheck misra addon + print('Appendix A Summary of guidelines', file=outputfile) + + def severity_print(self, outputfile, guideline_number, severity): + print('Rule ' + guideline_number + ' ' + severity, file=outputfile) + + def description_print(self, outputfile, guideline_number, description): + print(description + '(Misra rule ' + guideline_number + ')', file=outputfile) + + def closing_print(self, outputfile): + # Make cppcheck happy by starting the appendix + print('Appendix B', file=outputfile) + print('', file=outputfile) + +def convert_guidelines(args): + inputfile = args.input + outputfile = sys.stdout + formatter = None + + # If the output is not empty, open the given file for writing + if args.output is not None: + outputfile = open(args.output, "w") + + try: + file_stream = open(inputfile, 'rt', errors='ignore') + except Exception: + print('Error opening ' + inputfile +'.') + sys.exit() + + # Set formatter according to the used format + if args.format == 'cppcheck': + formatter = CppCheckFormatter() + + # Search for table named Main rules + pattern_table_start = re.compile(r'.*list-table:: Main rules') + # Each Rule is a new table column so start with '[tab]* - Rule' + # Ignore directives here + pattern_new_line = re.compile(r'^ \* - Rule ([0-9]+.[0-9]+).*$') + # Each table column start with '[tab]- ' + pattern_new_col = re.compile(r'^ - (.*)$') + + table_start = False + guideline_number = '' + guideline_state = 0 + guideline_list = [] + + for line in file_stream: + + line = line.replace('\r', '').replace('\n', '') + + # Done if we find the Additional rules table start + if line.find('Additional rules') >= 0: + break + + if len(line) == 0: + continue + + if not table_start: + res = pattern_table_start.match(line) + if res: + table_start = True + formatter.table_start_print(outputfile) + continue + + res = pattern_new_line.match(line) + if res: + guideline_state = "severity" + guideline_number = res.group(1) + guideline_list.append(guideline_number) + continue + elif guideline_number == '': + continue + + res = pattern_new_col.match(line) + if res: + if guideline_state == "severity": + # Severity + formatter.severity_print(outputfile, guideline_number, res.group(1)) + guideline_state = "description" + continue + if guideline_state == "description": + # Description + formatter.description_print(outputfile, guideline_number, res.group(1)) + guideline_state = "None" + # We stop here for now, we do not handle the CERT C col + guideline_number = '' + continue + + formatter.closing_print(outputfile) + +if __name__ == "__main__": + supported_formats = ['cppcheck'] + + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument( + "-i", "--input", metavar="RST_FILE", type=Path, required=True, + help="Path to rst input source file, where the guidelines are written down." + ) + parser.add_argument( + "-f", "--format", metavar="FORMAT", choices=supported_formats, required=True, + help="Format to convert guidlines to. Supported formats are: " + str(supported_formats) + ) + parser.add_argument( + "-o", "--output", metavar="OUTPUT_FILE", type=Path, required=False, + help="Path to output file, where the converted guidelines are written to. If outputfile is not specified, print to stdout." + ) + args = parser.parse_args() + + convert_guidelines(args) From 56903874628a8b625ded21a0c57dae5afa407dbc Mon Sep 17 00:00:00 2001 From: Benjamin Lemouzy Date: Fri, 1 Sep 2023 14:13:33 +0200 Subject: [PATCH 2824/4498] drivers: audio: add errors management Add audio_codec_clear_errors and audio_codec_register_errors_callback functions to manage audio codec errors. Callback has to be called from dedicated thread to allow I2C or SPI operations. Signed-off-by: Benjamin Lemouzy --- include/zephyr/audio/codec.h | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/include/zephyr/audio/codec.h b/include/zephyr/audio/codec.h index 18a26a01adb..082fd3e4ae3 100644 --- a/include/zephyr/audio/codec.h +++ b/include/zephyr/audio/codec.h @@ -111,6 +111,35 @@ typedef union { bool mute; /**< Mute if @a true, unmute if @a false */ } audio_property_value_t; +/** + * @brief Codec error type + */ +enum audio_codec_error_type { + /** Output over-current */ + AUDIO_CODEC_ERROR_OVERCURRENT = BIT(0), + + /** Codec over-temperature */ + AUDIO_CODEC_ERROR_OVERTEMPERATURE = BIT(1), + + /** Power low voltage */ + AUDIO_CODEC_ERROR_UNDERVOLTAGE = BIT(2), + + /** Power high voltage */ + AUDIO_CODEC_ERROR_OVERVOLTAGE = BIT(3), + + /** Output direct-current */ + AUDIO_CODEC_ERROR_DC = BIT(4), +}; + +/** + * @typedef audio_codec_error_callback_t + * @brief Callback for error interrupt + * + * @param dev Pointer to the codec device + * @param errors Device errors (bitmask of @ref audio_codec_error_type values) + */ +typedef void (*audio_codec_error_callback_t)(const struct device *dev, uint32_t errors); + /** * @cond INTERNAL_HIDDEN * @@ -126,6 +155,9 @@ struct audio_codec_api { audio_channel_t channel, audio_property_value_t val); int (*apply_properties)(const struct device *dev); + int (*clear_errors)(const struct device *dev); + int (*register_error_callback)(const struct device *dev, + audio_codec_error_callback_t cb); }; /** * @endcond @@ -223,6 +255,55 @@ static inline int audio_codec_apply_properties(const struct device *dev) return api->apply_properties(dev); } +/** + * @brief Clear any codec errors + * + * Clear all codec errors. + * If an error interrupt exists, it will be de-asserted. + * + * @param dev Pointer to the device structure for codec driver instance. + * + * @return 0 on success, negative error code on failure + */ +static inline int audio_codec_clear_errors(const struct device *dev) +{ + const struct audio_codec_api *api = + (const struct audio_codec_api *)dev->api; + + if (api->clear_errors == NULL) { + return -ENOSYS; + } + + return api->clear_errors(dev); +} + +/** + * @brief Register a callback function for codec error + * + * The callback will be called from a thread, so I2C or SPI operations are + * safe. However, the thread's stack is limited and defined by the + * driver. It is currently up to the caller to ensure that the callback + * does not overflow the stack. + * + * @param dev Pointer to the audio codec device + * @param cb The function that should be called when an error is detected + * fires + * + * @return 0 if successful, negative errno code if failure. + */ +static inline int audio_codec_register_error_callback(const struct device *dev, + audio_codec_error_callback_t cb) +{ + const struct audio_codec_api *api = + (const struct audio_codec_api *)dev->api; + + if (api->register_error_callback == NULL) { + return -ENOSYS; + } + + return api->register_error_callback(dev, cb); +} + #ifdef __cplusplus } #endif From 9fd0185c3b40239d1144b0a484445b10d05ce7b2 Mon Sep 17 00:00:00 2001 From: Benjamin Lemouzy Date: Fri, 5 May 2023 08:56:09 +0200 Subject: [PATCH 2825/4498] drivers: audio: add Audio Codec shell commands Add shell commands to start, stop and set properties of an Audio Codec device. Signed-off-by: Benjamin Lemouzy --- drivers/audio/CMakeLists.txt | 1 + drivers/audio/Kconfig | 7 ++ drivers/audio/codec_shell.c | 197 +++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 drivers/audio/codec_shell.c diff --git a/drivers/audio/CMakeLists.txt b/drivers/audio/CMakeLists.txt index b1802f9cf26..98544d6218c 100644 --- a/drivers/audio/CMakeLists.txt +++ b/drivers/audio/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy-i2s.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_NRFX_PDM dmic_nrfx_pdm.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_TAS6422DAC tas6422dac.c) +zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_SHELL codec_shell.c) diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index a45e003f80a..308bbb3172a 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -25,6 +25,13 @@ config AUDIO_CODEC_INIT_PRIORITY help Audio codec device driver initialization priority. +config AUDIO_CODEC_SHELL + bool "Audio Codec shell" + default y + depends on SHELL + help + Enable the Audio Codec shell with Audio Codec related commands. + module = AUDIO_CODEC module-str = audio codec source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/audio/codec_shell.c b/drivers/audio/codec_shell.c new file mode 100644 index 00000000000..6fb47d11184 --- /dev/null +++ b/drivers/audio/codec_shell.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2023 Centralp + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define CODEC_START_HELP \ + "Start output audio playback. Syntax:\n" \ + "" + +#define CODEC_STOP_HELP \ + "Stop output audio playback. Syntax:\n" \ + "" + +#define CODEC_SET_PROP_HELP \ + "Set a codec property. Syntax:\n" \ + " " + +#define CODEC_APPLY_PROP_HELP \ + "Apply any cached properties. Syntax:\n" \ + "" + +static const char *const codec_property_name[] = { + [AUDIO_PROPERTY_OUTPUT_VOLUME] = "volume", + [AUDIO_PROPERTY_OUTPUT_MUTE] = "mute", +}; + +static const char *const codec_channel_name[] = { + [AUDIO_CHANNEL_FRONT_LEFT] = "front_left", + [AUDIO_CHANNEL_FRONT_RIGHT] = "front_right", + [AUDIO_CHANNEL_LFE] = "lfe", + [AUDIO_CHANNEL_FRONT_CENTER] = "front_center", + [AUDIO_CHANNEL_REAR_LEFT] = "rear_left", + [AUDIO_CHANNEL_REAR_RIGHT] = "rear_right", + [AUDIO_CHANNEL_REAR_CENTER] = "rear_center", + [AUDIO_CHANNEL_SIDE_LEFT] = "side_left", + [AUDIO_CHANNEL_SIDE_RIGHT] = "side_right", + [AUDIO_CHANNEL_ALL] = "all", +}; + +struct args_index { + uint8_t device; + uint8_t property; + uint8_t channel; + uint8_t value; +}; + +static const struct args_index args_indx = { + .device = 1, + .property = 2, + .channel = 3, + .value = 4, +}; + +static int parse_named_int(const char *name, const char *keystack[], size_t count) +{ + char *endptr; + int i; + + /* Attempt to parse name as a number first */ + i = strtoul(name, &endptr, 0); + if (*endptr == '\0') { + return i; + } + + /* Name is not a number, look it up */ + for (i = 0; i < count; i++) { + if (strcmp(name, keystack[i]) == 0) { + return i; + } + } + + return -ENOTSUP; +} + +static int cmd_start(const struct shell *sh, size_t argc, char *argv[]) +{ + const struct device *dev; + + dev = device_get_binding(argv[args_indx.device]); + if (!dev) { + shell_error(sh, "Audio Codec device not found"); + return -ENODEV; + } + audio_codec_start_output(dev); + + return 0; +} + +static int cmd_stop(const struct shell *sh, size_t argc, char *argv[]) +{ + const struct device *dev; + + dev = device_get_binding(argv[args_indx.device]); + if (!dev) { + shell_error(sh, "Audio Codec device not found"); + return -ENODEV; + } + audio_codec_stop_output(dev); + + return 0; +} + +static int cmd_set_prop(const struct shell *sh, size_t argc, char *argv[]) +{ + const struct device *dev; + int property; + int channel; + long value; + char *endptr; + audio_property_value_t property_value; + + dev = device_get_binding(argv[args_indx.device]); + if (!dev) { + shell_error(sh, "Audio Codec device not found"); + return -ENODEV; + } + + property = parse_named_int(argv[args_indx.property], codec_property_name, + ARRAY_SIZE(codec_property_name)); + if (property < 0) { + shell_error(sh, "Property '%s' unknown", argv[args_indx.property]); + return -EINVAL; + } + + channel = parse_named_int(argv[args_indx.channel], codec_channel_name, + ARRAY_SIZE(codec_channel_name)); + if (channel < 0) { + shell_error(sh, "Channel '%s' unknown", argv[args_indx.channel]); + return -EINVAL; + } + + value = strtol(argv[args_indx.value], &endptr, 0); + if (*endptr != '\0') { + return -EINVAL; + } + if (value > INT32_MAX || value < INT32_MIN) { + return -EINVAL; + } + switch (property) { + case AUDIO_PROPERTY_OUTPUT_VOLUME: + property_value.vol = value; + break; + case AUDIO_PROPERTY_OUTPUT_MUTE: + property_value.mute = value; + break; + default: + return -EINVAL; + } + + return audio_codec_set_property(dev, property, channel, property_value); +} + +static int cmd_apply_prop(const struct shell *sh, size_t argc, char *argv[]) +{ + const struct device *dev; + + dev = device_get_binding(argv[args_indx.device]); + if (!dev) { + shell_error(sh, "Audio Codec device not found"); + return -ENODEV; + } + + return audio_codec_apply_properties(dev); +} + +/* Device name autocompletion support */ +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_lookup(idx, NULL); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + +/* clang-format off */ +SHELL_STATIC_SUBCMD_SET_CREATE(sub_codec, + SHELL_CMD_ARG(start, &dsub_device_name, CODEC_START_HELP, cmd_start, + 2, 0), + SHELL_CMD_ARG(stop, &dsub_device_name, CODEC_STOP_HELP, cmd_stop, + 2, 0), + SHELL_CMD_ARG(set_prop, &dsub_device_name, CODEC_SET_PROP_HELP, cmd_set_prop, + 5, 0), + SHELL_CMD_ARG(apply_prop, &dsub_device_name, CODEC_APPLY_PROP_HELP, cmd_apply_prop, + 2, 0), + SHELL_SUBCMD_SET_END +); +/* clang-format on */ + +SHELL_CMD_REGISTER(codec, &sub_codec, "Audio Codec commands", NULL); From 9c323d685bfb0e16b0ac7de32bc23cf21ed86ecf Mon Sep 17 00:00:00 2001 From: Benjamin Lucke Date: Mon, 30 Oct 2023 14:23:46 +0100 Subject: [PATCH 2826/4498] Bluetooth: BAP: Shell: Fixed some bap shell cmds Added missing initialization for cmd_stream_qos and cmd_sync_broadcast. Signed-off-by: Benjamin Lucke --- subsys/bluetooth/audio/shell/bap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index b83237f9798..bbddb0d3ee6 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -1163,7 +1163,7 @@ static int cmd_stream_qos(const struct shell *sh, size_t argc, char *argv[]) { struct bt_audio_codec_qos *qos; unsigned long interval; - int err; + int err = 0; if (default_stream == NULL) { shell_print(sh, "No stream selected"); @@ -2282,7 +2282,7 @@ static int cmd_sync_broadcast(const struct shell *sh, size_t argc, char *argv[]) struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)]; uint32_t bis_bitfield; size_t stream_cnt; - int err; + int err = 0; bis_bitfield = 0; stream_cnt = 0U; From e3c06c5d8f6b3cb004a8521b3e063649228c61e8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 26 Oct 2023 08:20:13 +0100 Subject: [PATCH 2827/4498] mgmt: mcumgr: transport: Fix UDP user data buffer overflow Fixes a buffer overflow issue if UDP is enabled for IPv4 only but IPv6 networking is enabled Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/transport/Kconfig | 15 +++++++++++---- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/subsys/mgmt/mcumgr/transport/Kconfig b/subsys/mgmt/mcumgr/transport/Kconfig index a966b943a9c..3d99fb33ccf 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig +++ b/subsys/mgmt/mcumgr/transport/Kconfig @@ -48,19 +48,26 @@ config MCUMGR_TRANSPORT_NETBUF_SIZE In case when MCUMGR_TRANSPORT_SHELL is enabled this value should be set to at least MCUMGR_GRP_SHELL_BACKEND_DUMMY_BUF_SIZE + 32. -config MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE - int "Size of mcumgr buffer user data" - default 24 if MCUMGR_TRANSPORT_UDP && MCUMGR_TRANSPORT_UDP_IPV6 +config MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE + int + default 24 if MCUMGR_TRANSPORT_UDP && NET_IPV6 default 8 if MCUMGR_TRANSPORT_UDP && MCUMGR_TRANSPORT_UDP_IPV4 default 8 if MCUMGR_TRANSPORT_BT default 4 + help + Hidden option to determine minimum user data size. + +config MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE + int "Size of mcumgr buffer user data" + range MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE 128 + default MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE help The size, in bytes, of user data to allocate for each mcumgr buffer. Different mcumgr transports impose different requirements for this setting. A value of 4 is sufficient for UART and shell, a value of 8 is sufficient for Bluetooth. For UDP, the userdata must be large - enough to hold a IPv4/IPv6 address. + enough to hold IPv4/IPv6 addresses. module = MCUMGR_TRANSPORT module-str = mcumgr_transport diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index 2da48563672..f59ca884cd0 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -42,6 +42,9 @@ BUILD_ASSERT(0, "Either IPv4 or IPv6 SMP must be enabled for the MCUmgr UDP SMP "CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 or CONFIG_MCUMGR_TRANSPORT_UDP_IPV6"); #endif +BUILD_ASSERT(sizeof(struct sockaddr) <= CONFIG_MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE, + "CONFIG_MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE must be >= sizeof(struct sockaddr)"); + #define IS_THREAD_RUNNING(thread) \ (thread.base.thread_state & (_THREAD_PENDING | \ _THREAD_PRESTART | \ From 7db93097daaa8a843529c2c4f97e5c97736c8e12 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 10 Oct 2023 13:21:38 +0200 Subject: [PATCH 2828/4498] boards: arm: lpcxpresso55s16/06: add boot and slot1 flash partitions. Add boot_partition and slot1_partition to the lpcxpresso55s16 and lpcxpresso55s06 dts. Signed-off-by: Andrej Butok --- .../lpcxpresso55s06_common.dtsi | 27 ++++++++++--------- .../lpcxpresso55s16_common.dtsi | 26 +++++++++++------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/boards/arm/lpcxpresso55s06/lpcxpresso55s06_common.dtsi b/boards/arm/lpcxpresso55s06/lpcxpresso55s06_common.dtsi index 03633b468dc..aa2373b829c 100644 --- a/boards/arm/lpcxpresso55s06/lpcxpresso55s06_common.dtsi +++ b/boards/arm/lpcxpresso55s06/lpcxpresso55s06_common.dtsi @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 metraTec - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,12 +12,11 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &sramx; + zephyr,code-partition = &slot0_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,entropy = &rng; zephyr,flash-controller = &iap; - zephyr,code-partition = &slot0_partition; zephyr,canbus = &can0; }; @@ -118,23 +117,27 @@ }; &flash0 { - /* - * LPC flash controller requires minimum 512 byte - * write to flash, so MCUBoot is not supported. Just - * provide storage and code partition. - */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - slot0_partition: partition@0 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(32)>; + }; + slot0_partition: partition@8000 { label = "image-0"; - reg = <0x00000000 DT_SIZE_K(196)>; + reg = <0x00008000 DT_SIZE_K(96)>; + }; + slot1_partition: partition@20000 { + label = "image-1"; + reg = <0x00020000 DT_SIZE_K(96)>; }; - storage_partition: partition@30000 { + storage_partition: partition@38000 { label = "storage"; - reg = <0x00030000 DT_SIZE_K(64)>; + reg = <0x00038000 DT_SIZE_K(20)>; }; + /* The last 12KB are reserved for PFR on the 256KB flash. */ }; }; diff --git a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi index b1e152e74c9..1b68d976f3e 100644 --- a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi +++ b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Henrik Brix Andersen + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,11 +12,12 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &sramx; + zephyr,code-partition = &slot0_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,entropy = &rng; zephyr,canbus = &can0; + zephyr,flash-controller = &iap; }; aliases{ @@ -162,23 +164,27 @@ }; &flash0 { - /* - * LPC flash controller requires minimum 512 byte - * write to flash, so MCUBoot is not supported. Just - * provide storage and code partition. - */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - slot0_partition: partition@0 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(32)>; + }; + slot0_partition: partition@8000 { label = "image-0"; - reg = <0x00000000 DT_SIZE_K(196)>; + reg = <0x00008000 DT_SIZE_K(96)>; + }; + slot1_partition: partition@20000 { + label = "image-1"; + reg = <0x00020000 DT_SIZE_K(96)>; }; - storage_partition: partition@30000 { + storage_partition: partition@38000 { label = "storage"; - reg = <0x00030000 DT_SIZE_K(64)>; + reg = <0x00038000 DT_SIZE_K(20)>; }; + /* The last 12KB are reserved for PFR on the 256KB flash. */ }; }; From 6e02f02464362e31a982266ac5ce73c84c2f9fd8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 27 Oct 2023 10:36:17 -0700 Subject: [PATCH 2829/4498] kernel: Fix k_thread_name_get signature k_thread_name_get has inconsistent signature. In the function declaration it uses k_tid_t but in the implementation it is using struct k_thread *. Change the implementation to use k_tid_t. Signed-off-by: Flavio Ceolin --- kernel/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/thread.c b/kernel/thread.c index 2703116aca5..8e477b1f7dc 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -278,7 +278,7 @@ static inline int z_vrfy_k_thread_name_set(struct k_thread *thread, const char * #include #endif /* CONFIG_USERSPACE */ -const char *k_thread_name_get(struct k_thread *thread) +const char *k_thread_name_get(k_tid_t thread) { #ifdef CONFIG_THREAD_NAME return (const char *)thread->name; From 6304e9a302eb464479019c1f73696f9293aab57b Mon Sep 17 00:00:00 2001 From: Arkadiusz Cholewinski Date: Thu, 5 Oct 2023 13:54:18 +0200 Subject: [PATCH 2830/4498] PM: add device_on_power_domian testcase. Add test case to increase code coverage of device.c file. Signed-off-by: Arkadiusz Cholewinski --- tests/subsys/pm/power_domain/src/main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/subsys/pm/power_domain/src/main.c b/tests/subsys/pm/power_domain/src/main.c index aab61a57f1c..5088d1b37bf 100644 --- a/tests/subsys/pm/power_domain/src/main.c +++ b/tests/subsys/pm/power_domain/src/main.c @@ -279,5 +279,23 @@ ZTEST(power_domain_1cpu, test_power_domain_device_balanced) zassert_equal(state, PM_DEVICE_STATE_ACTIVE); } +ZTEST(power_domain_1cpu, test_on_power_domain) +{ + zassert_true(device_is_ready(domain), "Device is not ready!"); + zassert_true(device_is_ready(deva), "Device is not ready!"); + devc = DEVICE_GET(devc); + zassert_true(device_is_ready(devc), "Device is not ready!"); + + pm_device_power_domain_remove(deva, domain); + zassert_false(pm_device_on_power_domain(deva), "deva is in the power domain."); + pm_device_power_domain_add(deva, domain); + zassert_true(pm_device_on_power_domain(deva), "deva is not in the power domain."); + + pm_device_power_domain_add(devc, domain); + zassert_true(pm_device_on_power_domain(devc), "devc is not in the power domain."); + pm_device_power_domain_remove(devc, domain); + zassert_false(pm_device_on_power_domain(devc), "devc in in the power domain."); +} + ZTEST_SUITE(power_domain_1cpu, NULL, NULL, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); From 8c80bbb96ef3245881f5a650a27464138b668765 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 1 Sep 2023 14:27:33 -0400 Subject: [PATCH 2831/4498] tests: latency_measure: Update context switch Updates both the preemptive and cooperative thread context switch benchmark tests so that not only will they share the same infrastructure, but they can both get the context switch times when switching from ... 1. Kernel thread to kernel thread 2. Kernel thread to user thread 3. User thread to kernel thread 4. User thread to user thread Signed-off-by: Peter Mitsis --- .../latency_measure/src/coop_ctx_switch.c | 143 ------------ tests/benchmarks/latency_measure/src/main.c | 52 ++++- .../latency_measure/src/thread_switch_yield.c | 217 +++++++++++------- tests/benchmarks/latency_measure/src/utils.h | 21 +- 4 files changed, 198 insertions(+), 235 deletions(-) delete mode 100644 tests/benchmarks/latency_measure/src/coop_ctx_switch.c diff --git a/tests/benchmarks/latency_measure/src/coop_ctx_switch.c b/tests/benchmarks/latency_measure/src/coop_ctx_switch.c deleted file mode 100644 index ad888c96a64..00000000000 --- a/tests/benchmarks/latency_measure/src/coop_ctx_switch.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2012-2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * @brief Measure context switch time between cooperative threads - * - * This file contains thread (coop) context switch time measurement. - * The thread starts two cooperative thread. One thread waits on a semaphore. The other, - * after starting, releases a semaphore which enable the first thread to run. - * Each thread increases a common global counter and context switch back and - * forth by yielding the cpu. When counter reaches the maximal value, threads - * stop and the average time of context switch is displayed. - */ -#include -#include -#include "utils.h" - -/* number of context switches */ -#define NCTXSWITCH 10000 -#ifndef STACKSIZE -#define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) -#endif - -/* stack used by the threads */ -static K_THREAD_STACK_DEFINE(thread_one_stack, STACKSIZE); -static K_THREAD_STACK_DEFINE(thread_two_stack, STACKSIZE); -static struct k_thread thread_one_data; -static struct k_thread thread_two_data; - -static timing_t timestamp_start; -static timing_t timestamp_end; - -/* context switches counter */ -static volatile uint32_t ctx_switch_counter; - -/* context switch balancer. Incremented by one thread, decremented by another*/ -static volatile int ctx_switch_balancer; - -K_SEM_DEFINE(sync_sema, 0, 1); - -/** - * - * thread_one - * - * Fiber makes all the test preparations: registers the interrupt handler, - * gets the first timestamp and invokes the software interrupt. - * - */ -static void thread_one(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p1); - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - k_sem_take(&sync_sema, K_FOREVER); - - timestamp_start = timing_counter_get(); - - while (ctx_switch_counter < NCTXSWITCH) { - k_yield(); - ctx_switch_counter++; - ctx_switch_balancer--; - } - - timestamp_end = timing_counter_get(); -} - -/** - * - * @brief Check the time when it gets executed after the semaphore - * - * Fiber starts, waits on semaphore. When the interrupt handler releases - * the semaphore, thread measures the time. - * - * @return 0 on success - */ -static void thread_two(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p1); - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - k_sem_give(&sync_sema); - while (ctx_switch_counter < NCTXSWITCH) { - k_yield(); - ctx_switch_counter++; - ctx_switch_balancer++; - } -} - -/** - * - * @brief The test main function - * - * @return 0 on success - */ -int coop_ctx_switch(void) -{ - ctx_switch_counter = 0U; - ctx_switch_balancer = 0; - char error_string[80]; - const char *notes = ""; - bool failed = false; - int end; - - timing_start(); - bench_test_start(); - - k_thread_create(&thread_one_data, thread_one_stack, STACKSIZE, - thread_one, NULL, NULL, NULL, - K_PRIO_COOP(6), 0, K_NO_WAIT); - k_thread_create(&thread_two_data, thread_two_stack, STACKSIZE, - thread_two, NULL, NULL, NULL, - K_PRIO_COOP(6), 0, K_NO_WAIT); - - end = bench_test_end(); - - if (ctx_switch_balancer > 3 || ctx_switch_balancer < -3) { - error_count++; - snprintk(error_string, 78, " Balance is %d", - ctx_switch_balancer); - notes = error_string; - failed = true; - } else if (end != 0) { - error_count++; - notes = TICK_OCCURRENCE_ERROR; - } - - uint32_t diff; - - diff = timing_cycles_get(×tamp_start, ×tamp_end); - PRINT_STATS_AVG("Average context switch time between threads (coop)", - diff, ctx_switch_counter, failed, notes); - - timing_stop(); - - return 0; -} diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index 3940184404a..8cfe2cc7793 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2015 Wind River Systems, Inc. + * Copyright (c) 2023 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,30 +10,62 @@ * This file contains the main testing module that invokes all the tests. */ +#include #include +#include #include "utils.h" #include +#define NUM_ITERATIONS 10000 + #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) -uint32_t tm_off; /* time necessary to read the time */ +#ifdef CONFIG_USERSPACE +#define BENCH_BMEM K_APP_BMEM(bench_mem_partition) +#else +#define BENCH_BMEM +#endif + +uint32_t tm_off; + +BENCH_BMEM struct timestamp_data timestamp; + +#ifdef CONFIG_USERSPACE +K_APPMEM_PARTITION_DEFINE(bench_mem_partition); +#endif + +K_THREAD_STACK_DEFINE(start_stack, START_STACK_SIZE); +K_THREAD_STACK_DEFINE(alt_stack, START_STACK_SIZE); + +K_SEM_DEFINE(pause_sem, 0, 1); + +struct k_thread start_thread; +struct k_thread alt_thread; + int error_count; /* track number of errors */ -extern void thread_switch_yield(void); +extern void thread_switch_yield(uint32_t num_iterations, bool is_cooperative); extern void int_to_thread(void); extern void int_to_thread_evt(void); extern void sema_test_signal(void); extern void mutex_lock_unlock(void); -extern int coop_ctx_switch(void); -extern int sema_test(void); extern int sema_context_switch(void); extern int suspend_resume(void); extern void heap_malloc_free(void); -void test_thread(void *arg1, void *arg2, void *arg3) +static void test_thread(void *arg1, void *arg2, void *arg3) { uint32_t freq; + ARG_UNUSED(arg1); + ARG_UNUSED(arg2); + ARG_UNUSED(arg3); + +#ifdef CONFIG_USERSPACE + k_mem_domain_add_partition(&k_mem_domain_default, + &bench_mem_partition); +#endif + timing_init(); bench_test_init(); @@ -42,9 +75,11 @@ void test_thread(void *arg1, void *arg2, void *arg3) TC_START("Time Measurement"); TC_PRINT("Timing results: Clock frequency: %u MHz\n", freq); - thread_switch_yield(); + /* Preemptive threads context switching */ + thread_switch_yield(NUM_ITERATIONS, false); - coop_ctx_switch(); + /* Cooperative threads context switching */ + thread_switch_yield(NUM_ITERATIONS, true); int_to_thread(); @@ -63,7 +98,8 @@ void test_thread(void *arg1, void *arg2, void *arg3) TC_END_REPORT(error_count); } -K_THREAD_DEFINE(test_thread_id, STACK_SIZE, test_thread, NULL, NULL, NULL, K_PRIO_PREEMPT(10), 0, 0); +K_THREAD_DEFINE(test_thread_id, STACK_SIZE, test_thread, NULL, NULL, NULL, + K_PRIO_PREEMPT(10), 0, 0); int main(void) { diff --git a/tests/benchmarks/latency_measure/src/thread_switch_yield.c b/tests/benchmarks/latency_measure/src/thread_switch_yield.c index 4df75a16884..14bd157d720 100644 --- a/tests/benchmarks/latency_measure/src/thread_switch_yield.c +++ b/tests/benchmarks/latency_measure/src/thread_switch_yield.c @@ -1,113 +1,168 @@ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. + * Copyright (c) 2023 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file - * This file contains the benchmark that measure the average time it takes to - * do context switches between threads using k_yield () to force - * context switch. + * This file contains the benchmarking code that measures the average time it + * takes to perform context switches between threads using k_yield(). + * + * When user threads are supported, there are four cases to consider. These are + * 1. Kernel thread -> Kernel thread + * 2. User thread -> User thread + * 3. Kernel thread -> User thread + * 4. User thread -> Kernel thread */ #include #include #include #include -#include "utils.h" /* PRINT () and other macros */ -/* context switch enough time so our measurement is precise */ -#define NB_OF_YIELD 1000 +#include "utils.h" -static uint32_t helper_thread_iterations; +static void alt_thread_entry(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations; -#define Y_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) -#define Y_PRIORITY K_PRIO_PREEMPT(10) + ARG_UNUSED(p2); + ARG_UNUSED(p2); -K_THREAD_STACK_DEFINE(y_stack_area, Y_STACK_SIZE); -static struct k_thread y_thread; + num_iterations = (uint32_t)(uintptr_t)p1; + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* 3. Obtain the 'finish' timestamp */ + + timestamp.sample = timing_counter_get(); + + /* 4. Switch to */ -/** - * @brief Helper thread for measuring thread switch latency using yield - */ -void yielding_thread(void *arg1, void *arg2, void *arg3) -{ - while (helper_thread_iterations < NB_OF_YIELD) { k_yield(); - helper_thread_iterations++; } + } -/** - * @brief Entry point for thread context switch using yield test - */ -void thread_switch_yield(void) +static void start_thread_entry(void *p1, void *p2, void *p3) { - uint32_t iterations = 0U; - int32_t delta; - timing_t timestamp_start; - timing_t timestamp_end; - uint32_t ts_diff; - const char *notes = ""; - char error_string[80]; - bool failed = false; - int end; - - timing_start(); - bench_test_start(); - - /* launch helper thread of the same priority as the thread - * of routine - */ - k_thread_create(&y_thread, y_stack_area, Y_STACK_SIZE, yielding_thread, - NULL, NULL, NULL, Y_PRIORITY, 0, K_NO_WAIT); - - /* get initial timestamp */ - timestamp_start = timing_counter_get(); - - /* loop until either helper or this routine reaches number of yields */ - while (iterations < NB_OF_YIELD && - helper_thread_iterations < NB_OF_YIELD) { + uint64_t sum = 0ull; + uint32_t num_iterations; + timing_t start; + timing_t finish; + + ARG_UNUSED(p2); + ARG_UNUSED(p2); + + num_iterations = (uint32_t)(uintptr_t)p1; + + k_thread_start(&alt_thread); + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* 1. Get 'start' timestamp */ + + start = timing_counter_get(); + + /* 2. Switch to */ + k_yield(); - iterations++; + + /* 5. Get the 'finish' timestamp obtained in */ + + finish = timestamp.sample; + + /* 6. Track the sum of elapsed times */ + + sum += timing_cycles_get(&start, &finish); } - /* get the number of cycles it took to do the test */ - timestamp_end = timing_counter_get(); - end = bench_test_end(); - - /* Ensure both helper and this routine were context switching back & - * forth. - * For execution to reach the line below, either this routine or helper - * routine reached NB_OF_YIELD. The other loop must be at most one - * iteration away from reaching NB_OF_YIELD if execute was switching - * back and forth. - */ - delta = iterations - helper_thread_iterations; - if (abs(delta) > 1) { - /* expecting even alternating context switch, seems one routine - * called yield without the other having chance to execute - */ - error_count++; - snprintk(error_string, 78, - "Error: iteration:%u : helper iteration:%u", - iterations, helper_thread_iterations); - notes = error_string; - failed = true; - } else if (end != 0) { - error_count++; - notes = TICK_OCCURRENCE_ERROR; + /* Wait for to complete */ + + k_thread_join(&alt_thread, K_FOREVER); + + /* Record the number of cycles for use by the main thread */ + + timestamp.cycles = sum; +} + +static void thread_switch_yield_common(const char *description, + uint32_t num_iterations, + uint32_t start_options, + uint32_t alt_options, + int priority) +{ + uint64_t sum; + char summary[80]; + + /* Create the two threads */ + + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, start_options, K_FOREVER); + + k_thread_create(&alt_thread, alt_stack, + K_THREAD_STACK_SIZEOF(alt_stack), + alt_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, alt_options, K_FOREVER); + + /* Grant access rights if necessary */ + + if ((start_options & K_USER) == K_USER) { + k_thread_access_grant(&start_thread, &alt_thread); } - /* - * thread_yield is called (iterations + helper_thread_iterations) - * times in total. - */ + k_thread_start(&start_thread); + + /* Wait until finishes */ + + k_thread_join(&start_thread, K_FOREVER); + + /* Get the sum total of measured cycles */ + + sum = timestamp.cycles; + + snprintf(summary, sizeof(summary), + "%s (%c -> %c)", + description, + (start_options & K_USER) == K_USER ? 'U' : 'K', + (alt_options & K_USER) == K_USER ? 'U' : 'K'); + + PRINT_STATS_AVG(summary, (uint32_t)sum, num_iterations, 0, ""); +} + +void thread_switch_yield(uint32_t num_iterations, bool is_cooperative) +{ + int priority; + char description[60]; + + priority = is_cooperative ? K_PRIO_COOP(6) + : k_thread_priority_get(k_current_get()) - 1; + + snprintf(description, sizeof(description), + "%s threads ctx switch via k_yield", + is_cooperative ? "Cooperative" : "Preemptive"); + + /* Kernel -> Kernel */ + thread_switch_yield_common(description, num_iterations, 0, 0, + priority); + +#if CONFIG_USERSPACE + /* User -> User */ + thread_switch_yield_common(description, num_iterations, K_USER, K_USER, + priority); - ts_diff = timing_cycles_get(×tamp_start, ×tamp_end); - PRINT_STATS_AVG("Average thread context switch using yield", ts_diff, - (iterations + helper_thread_iterations), failed, notes); + /* Kernel -> User */ + thread_switch_yield_common(description, num_iterations, 0, K_USER, + priority); - timing_stop(); + /* User -> Kernel */ + thread_switch_yield_common(description, num_iterations, K_USER, 0, + priority); +#endif } diff --git a/tests/benchmarks/latency_measure/src/utils.h b/tests/benchmarks/latency_measure/src/utils.h index 56027b1c850..a946e38a38b 100644 --- a/tests/benchmarks/latency_measure/src/utils.h +++ b/tests/benchmarks/latency_measure/src/utils.h @@ -7,7 +7,7 @@ #ifndef _LATENCY_MEASURE_UNIT_H #define _LATENCY_MEASURE_UNIT_H /* - * @brief This file contains function declarations, macroses and inline functions + * @brief This file contains function declarations, macros and inline functions * used in latency measurement. */ @@ -16,8 +16,23 @@ #include #include -#define INT_IMM8_OFFSET 1 -#define IRQ_PRIORITY 3 +#define START_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) +#define ALT_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) + +struct timestamp_data { + uint64_t cycles; + timing_t sample; +}; + +K_THREAD_STACK_DECLARE(start_stack, START_STACK_SIZE); +K_THREAD_STACK_DECLARE(alt_stack, ALT_STACK_SIZE); + +extern struct k_thread start_thread; +extern struct k_thread alt_thread; + +extern struct k_sem pause_sem; + +extern struct timestamp_data timestamp; extern int error_count; From 4e7bb482b1bcf915da003b23c468dbb6d3162b82 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 11 Sep 2023 12:12:48 -0400 Subject: [PATCH 2832/4498] tests: latency_measure: Update interrupt latency Updates the interrupt to thread benchmark tests to address a number of items. 1. Updates descriptions to correctly indicate that it is not interrupt latency being measured, but the time to leave the interrupt and return to a thread. 2. Repeats the test numerous times instead of just once to get an average. 3. Overhead from obtaining timestamps is now accounted for. 4. Adds support for returning to a user thread. Signed-off-by: Peter Mitsis --- .../latency_measure/src/int_to_thread.c | 186 ++++++++++++++---- .../latency_measure/src/int_to_thread_evt.c | 101 ---------- tests/benchmarks/latency_measure/src/main.c | 7 +- 3 files changed, 151 insertions(+), 143 deletions(-) delete mode 100644 tests/benchmarks/latency_measure/src/int_to_thread_evt.c diff --git a/tests/benchmarks/latency_measure/src/int_to_thread.c b/tests/benchmarks/latency_measure/src/int_to_thread.c index 50c4c56555b..608d3b30893 100644 --- a/tests/benchmarks/latency_measure/src/int_to_thread.c +++ b/tests/benchmarks/latency_measure/src/int_to_thread.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. - * Copyright (c) 2017 Intel Corporation. + * Copyright (c) 2017, 2023 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +10,16 @@ * * @brief Measure time from ISR back to interrupted thread * - * This file contains test that measures time to switch from the interrupt - * handler back to the interrupted thread. + * This file covers three interrupt to threads scenarios: + * 1. ISR returning to the interrupted kernel thread + * 2. ISR returning to a different (kernel) thread + * 3. ISR returning to a different (user) thread + * + * In all three scenarios, the source of the ISR is a software generated + * interrupt originating from a kernel thread. Ideally, these tests would + * also cover the scenarios where the interrupted thread is a user thread. + * However, some implementations of the irq_offload() routine lock interrupts, + * which is not allowed in userspace. */ #include @@ -19,39 +27,133 @@ #include -static volatile int flag_var; - -static timing_t timestamp_start; -static timing_t timestamp_end; +static K_SEM_DEFINE(isr_sem, 0, 1); /** + * @brief Test ISR used to measure time to return to thread * - * @brief Test ISR used to measure best case interrupt latency - * - * The interrupt handler gets the second timestamp. - * + * The interrupt handler gets the first timestamp used in the test. + * It then copies the timetsamp into a message queue and returns. */ -static void latency_test_isr(const void *unused) +static void test_isr(const void *arg) { - ARG_UNUSED(unused); - flag_var = 1; + struct k_sem *sem = (struct k_sem *)arg; - timestamp_start = timing_counter_get(); + if (arg != NULL) { + k_sem_give(sem); + } + + timestamp.sample = timing_counter_get(); } /** + * @brief Measure time to return from interrupt * - * @brief Interrupt preparation function - * - * Function makes all the test preparations: registers the interrupt handler, - * gets the first timestamp and invokes the software interrupt. - * + * This function is used to measure the time it takes to return from an + * interrupt. */ -static void make_int(void) +static void int_to_interrupted_thread(uint32_t num_iterations, uint64_t *sum) { - flag_var = 0; - irq_offload(latency_test_isr, NULL); - timestamp_end = timing_counter_get(); + timing_t start; + timing_t finish; + + *sum = 0ull; + + for (uint32_t i = 0; i < num_iterations; i++) { + irq_offload(test_isr, NULL); + finish = timing_counter_get(); + start = timestamp.sample; + + *sum += timing_cycles_get(&start, &finish); + } +} + +static void start_thread_entry(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + struct k_sem *sem = p2; + + ARG_UNUSED(p3); + + uint64_t sum = 0ull; + timing_t start; + timing_t finish; + + /* Ensure that is unavailable */ + + (void) k_sem_take(sem, K_NO_WAIT); + k_thread_start(&alt_thread); + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* 1. Wait on an unavailable semaphore */ + + k_sem_take(sem, K_FOREVER); + + /* 3. Obtain the start and finish timestamps */ + + finish = timing_counter_get(); + start = timestamp.sample; + + sum += timing_cycles_get(&start, &finish); + } + + timestamp.cycles = sum; +} + +static void alt_thread_entry(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + struct k_sem *sem = p2; + + ARG_UNUSED(p3); + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* 2. Trigger the test_isr() to execute */ + + irq_offload(test_isr, sem); + + /* + * ISR expected to have awakened higher priority start_thread + * thereby preempting alt_thread. + */ + } + + k_thread_join(&start_thread, K_FOREVER); +} + +static void int_to_another_thread(uint32_t num_iterations, uint64_t *sum, + uint32_t options) +{ + int priority; + *sum = 0ull; + + priority = k_thread_priority_get(k_current_get()); + + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_thread_entry, + (void *)(uintptr_t)num_iterations, &isr_sem, NULL, + priority - 2, options, K_FOREVER); + + k_thread_create(&alt_thread, alt_stack, + K_THREAD_STACK_SIZEOF(alt_stack), + alt_thread_entry, + (void *)(uintptr_t)num_iterations, &isr_sem, NULL, + priority - 1, 0, K_FOREVER); + +#if CONFIG_USERSPACE + if (options != 0) { + k_thread_access_grant(&start_thread, &isr_sem, &alt_thread); + } +#endif + + k_thread_start(&start_thread); + + k_thread_join(&alt_thread, K_FOREVER); + + *sum = timestamp.cycles; } /** @@ -60,24 +162,34 @@ static void make_int(void) * * @return 0 on success */ -int int_to_thread(void) +int int_to_thread(uint32_t num_iterations) { - uint32_t diff; - bool failed = false; - const char *notes = ""; + uint64_t sum; timing_start(); TICK_SYNCH(); - make_int(); - if (flag_var != 1) { - error_count++; - notes = "Flag variable did not change"; - failed = true; - } - diff = timing_cycles_get(×tamp_start, ×tamp_end); - PRINT_STATS("Switch from ISR back to interrupted thread", - diff, failed, notes); + int_to_interrupted_thread(num_iterations, &sum); + + PRINT_STATS_AVG("Switch from ISR back to interrupted thread", + (uint32_t)sum, num_iterations, false, ""); + + /* ************** */ + + int_to_another_thread(num_iterations, &sum, 0); + + PRINT_STATS_AVG("Switch from ISR to another thread (kernel)", + (uint32_t)sum, num_iterations, false, ""); + + /* ************** */ + +#if CONFIG_USERSPACE + int_to_another_thread(num_iterations, &sum, K_USER); + + PRINT_STATS_AVG("Switch from ISR to another thread (user)", + (uint32_t)sum, num_iterations, false, ""); +#endif + timing_stop(); return 0; } diff --git a/tests/benchmarks/latency_measure/src/int_to_thread_evt.c b/tests/benchmarks/latency_measure/src/int_to_thread_evt.c deleted file mode 100644 index b774309f7d5..00000000000 --- a/tests/benchmarks/latency_measure/src/int_to_thread_evt.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012-2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * @brief measure time from ISR to a rescheduled thread - * - * This file contains test that measures time to switch from an interrupt - * handler to executing a thread after rescheduling. In other words, execution - * after interrupt handler resume in a different thread than the one which got - * interrupted. - */ - -#include -#include - -#include "utils.h" - -static timing_t timestamp_start; -static timing_t timestamp_end; -static struct k_work work; - -K_SEM_DEFINE(INTSEMA, 0, 1); -K_SEM_DEFINE(WORKSEMA, 0, 1); - -/** - * - * @brief Test ISR used to measure best case interrupt latency - * - * The interrupt handler gets the second timestamp. - * - */ -static void latency_test_isr(const void *unused) -{ - ARG_UNUSED(unused); - - k_work_submit(&work); - timestamp_start = timing_counter_get(); -} - -static void worker(struct k_work *item) -{ - (void)item; - - timestamp_end = timing_counter_get(); - k_sem_give(&WORKSEMA); -} - -/** - * - * @brief Software interrupt generating thread - * - * Lower priority thread that, when it starts, it waits for a semaphore. When - * it gets it, released by the main thread, sets up the interrupt handler and - * generates the software interrupt - * - * @return 0 on success - */ -void int_thread(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p1); - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - k_sem_take(&INTSEMA, K_FOREVER); - irq_offload(latency_test_isr, NULL); - k_thread_suspend(k_current_get()); -} - -K_THREAD_DEFINE(int_thread_id, 512, int_thread, NULL, NULL, - NULL, 11, 0, 0); - -/** - * - * @brief The test main function - * - * @return 0 on success - */ -int int_to_thread_evt(void) -{ - uint32_t diff; - - k_work_init(&work, worker); - - timing_start(); - TICK_SYNCH(); - k_sem_give(&INTSEMA); - k_sem_take(&WORKSEMA, K_FOREVER); - timing_stop(); - - diff = timing_cycles_get(×tamp_start, ×tamp_end); - - PRINT_STATS("Time from ISR to executing a different thread", - diff, false, ""); - - return 0; -} diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index 8cfe2cc7793..7e9584b35e7 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -45,8 +45,7 @@ struct k_thread alt_thread; int error_count; /* track number of errors */ extern void thread_switch_yield(uint32_t num_iterations, bool is_cooperative); -extern void int_to_thread(void); -extern void int_to_thread_evt(void); +extern void int_to_thread(uint32_t num_iterations); extern void sema_test_signal(void); extern void mutex_lock_unlock(void); extern int sema_context_switch(void); @@ -81,9 +80,7 @@ static void test_thread(void *arg1, void *arg2, void *arg3) /* Cooperative threads context switching */ thread_switch_yield(NUM_ITERATIONS, true); - int_to_thread(); - - int_to_thread_evt(); + int_to_thread(NUM_ITERATIONS); suspend_resume(); From 13ac14f2bbd1e69eac703494a27dbfed7fdd1aa2 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 13 Sep 2023 10:56:18 -0400 Subject: [PATCH 2833/4498] tests: latency_measure: Update thread ops Update the thread ops (create/start/suspend/resume/abort) to include support for userspace. Signed-off-by: Peter Mitsis --- tests/benchmarks/latency_measure/src/main.c | 12 +- tests/benchmarks/latency_measure/src/thread.c | 316 +++++++++++++++--- 2 files changed, 276 insertions(+), 52 deletions(-) diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index 7e9584b35e7..a338fbb00bc 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -49,7 +49,8 @@ extern void int_to_thread(uint32_t num_iterations); extern void sema_test_signal(void); extern void mutex_lock_unlock(void); extern int sema_context_switch(void); -extern int suspend_resume(void); +extern int thread_ops(uint32_t num_iterations, uint32_t start_options, + uint32_t alt_options); extern void heap_malloc_free(void); static void test_thread(void *arg1, void *arg2, void *arg3) @@ -82,7 +83,14 @@ static void test_thread(void *arg1, void *arg2, void *arg3) int_to_thread(NUM_ITERATIONS); - suspend_resume(); + /* Thread creation, starting, suspending, resuming and aborting. */ + + thread_ops(NUM_ITERATIONS, 0, 0); +#ifdef CONFIG_USERSPACE + thread_ops(NUM_ITERATIONS, 0, K_USER); + thread_ops(NUM_ITERATIONS, K_USER, K_USER); + thread_ops(NUM_ITERATIONS, K_USER, 0); +#endif sema_test_signal(); diff --git a/tests/benchmarks/latency_measure/src/thread.c b/tests/benchmarks/latency_measure/src/thread.c index 5178eef784c..db4da3e685f 100644 --- a/tests/benchmarks/latency_measure/src/thread.c +++ b/tests/benchmarks/latency_measure/src/thread.c @@ -1,86 +1,302 @@ /* - * Copyright (c) 2020 Intel Corporation + * Copyright (c) 2020, 2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ + +/* + * @file measure time for various thread operations + * + * This file contains the tests that measures the times for the following + * thread operations from both kernel threads and user threads: + * 1. Creating a thread + * 2. Starting a thread + * 3. Suspending a thread + * 4. Resuming a thread + * 5. Aborting a thread + * + * It is worthwhile to note that there is no measurement for creating a kernel + * thread from a user thread as that is an invalid operation. + */ + #include #include #include "utils.h" #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) -/* stack used by the threads */ -static K_THREAD_STACK_DEFINE(t1_stack, STACK_SIZE); -static struct k_thread t1; +#define START_ALT 0x01 +#define ALT_USER 0x02 + +static void alt_thread_entry(void *p1, void *p2, void *p3) +{ + int priority; + + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); -timing_t timestamp_start_create_c; -timing_t timestamp_end_create_c; -timing_t timestamp_start_start_c; -timing_t timestamp_end_start_c; -timing_t timestamp_start_suspend_c; -timing_t timestamp_end_suspend_c; -timing_t timestamp_start_resume_c; -timing_t timestamp_end_resume_c; + /* 3. Finish measuring time to start */ -timing_t timestamp_start_abort_1; -timing_t timestamp_end_abort_1; + timestamp.sample = timing_counter_get(); -void thread_suspend_resume(void *p1, void *p2, void *p3) + /* 4. Let process the time measurement. */ + + k_sem_take(&pause_sem, K_FOREVER); /* Let 'start_thread' execute */ + + /* 7. Begin measuring time to suspend active thread (self/alt_thread) */ + + timestamp.sample = timing_counter_get(); + k_thread_suspend(&alt_thread); + + /* 10. Finish measuring time to resume (self) */ + + timestamp.sample = timing_counter_get(); + + /* 11. Lower the priority so can terminate us. */ + + priority = k_thread_priority_get(&alt_thread); + k_thread_priority_set(&alt_thread, priority + 2); +} + +static void start_thread_entry(void *p1, void *p2, void *p3) { - timestamp_start_suspend_c = timing_counter_get(); - k_thread_suspend(_current); + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + uint32_t bit_options = (uint32_t)(uintptr_t)p2; + timing_t start; + timing_t finish; + uint64_t thread_create_sum = 0ull; + uint64_t thread_start_sum = 0ull; + uint64_t thread_suspend_sum = 0ull; + uint64_t thread_resume_sum = 0ull; + uint64_t thread_abort_sum = 0ull; + int priority; + + ARG_UNUSED(p3); + + priority = k_thread_priority_get(&start_thread); + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* 1. Measure time to create, but not start */ + + if ((bit_options & START_ALT) == START_ALT) { + start = timing_counter_get(); + k_thread_create(&alt_thread, alt_stack, + K_THREAD_STACK_SIZEOF(alt_stack), + alt_thread_entry, NULL, NULL, NULL, + priority, + (bit_options & ALT_USER) == ALT_USER ? + K_USER : 0, K_FOREVER); + finish = timing_counter_get(); + + thread_create_sum += timing_cycles_get(&start, &finish); + } else { + + /* + * Wait for the "main" thread to create + * as this thread can not do it. + */ + + k_sem_take(&pause_sem, K_FOREVER); + } + + if ((bit_options & ALT_USER) == ALT_USER) { + k_thread_access_grant(&alt_thread, &pause_sem); + } + + /* + * Let the main thread change the priority of + * to a higher priority level as user threads may not create + * a thread of higher priority than itself. + */ + + k_sem_take(&pause_sem, K_FOREVER); + + + /* 2. Begin measuring time to start */ + + start = timing_counter_get(); + k_thread_start(&alt_thread); + + /* 5. Process the time to start */ - /* comes to this line once its resumed*/ - timestamp_start_resume_c = timing_counter_get(); + finish = timestamp.sample; + thread_start_sum += timing_cycles_get(&start, &finish); + /* 6. Allow to continue */ + + k_sem_give(&pause_sem); + + /* 8. Finish measuring time to suspend */ + + start = timestamp.sample; + finish = timing_counter_get(); + thread_suspend_sum += timing_cycles_get(&start, &finish); + + /* 9. Being measuring time to resume */ + + start = timing_counter_get(); + k_thread_resume(&alt_thread); + + /* 12. Process the time it took to resume */ + + finish = timestamp.sample; + thread_resume_sum += timing_cycles_get(&start, &finish); + + /* 13. Process the time to terminate */ + + start = timing_counter_get(); + k_thread_abort(&alt_thread); + finish = timing_counter_get(); + thread_abort_sum += timing_cycles_get(&start, &finish); + } + + timestamp.cycles = thread_create_sum; + k_sem_take(&pause_sem, K_FOREVER); + + timestamp.cycles = thread_start_sum; + k_sem_take(&pause_sem, K_FOREVER); + + timestamp.cycles = thread_suspend_sum; + k_sem_take(&pause_sem, K_FOREVER); + + timestamp.cycles = thread_resume_sum; + k_sem_take(&pause_sem, K_FOREVER); + + timestamp.cycles = thread_abort_sum; + k_sem_take(&pause_sem, K_FOREVER); } -int suspend_resume(void) +int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_options) { - uint32_t diff; + int priority; + uint64_t cycles; + uint32_t bit_options = START_ALT; + char description[80]; + + priority = k_thread_priority_get(k_current_get()); timing_start(); - timestamp_start_create_c = timing_counter_get(); + /* + * Determine if is allowed to start . + * If it can not, then can not create as it + * would be a user thread trying to create a kernel + * thread. Instead, create here. + */ + + k_thread_create(&alt_thread, alt_stack, + K_THREAD_STACK_SIZEOF(alt_stack), + alt_thread_entry, + NULL, NULL, NULL, + priority - 1, alt_options, K_FOREVER); + + /* Give sends us back to */ + + k_sem_give(&pause_sem); + } + + /* + * needs to be of higher priority than + * , which can not always be done in + * as sometimes it is a user thread. + */ + + k_thread_priority_set(&alt_thread, priority - 2); + k_sem_give(&pause_sem); + } + + cycles = timestamp.cycles; + k_sem_give(&pause_sem); + + if ((bit_options & START_ALT) == START_ALT) { + + /* Only report stats if created */ + + snprintf(description, sizeof(description), + "Create %s thread from %s thread", + (alt_options & K_USER) != 0 ? "user" : "kernel", + (start_options & K_USER) != 0 ? "user" : "kernel"); + + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); + } + + cycles = timestamp.cycles; + k_sem_give(&pause_sem); - k_tid_t t1_tid = k_thread_create(&t1, t1_stack, STACK_SIZE, - thread_suspend_resume, NULL, NULL, - NULL, K_PRIO_PREEMPT(6), 0, K_FOREVER); + snprintf(description, sizeof(description), + "Start %s thread from %s thread", + (alt_options & K_USER) != 0 ? "user" : "kernel", + (start_options & K_USER) != 0 ? "user" : "kernel"); - timestamp_end_create_c = timing_counter_get(); - k_thread_name_set(t1_tid, "t1"); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); - timestamp_start_start_c = timing_counter_get(); - k_thread_start(t1_tid); + cycles = timestamp.cycles; + k_sem_give(&pause_sem); - timestamp_end_suspend_c = timing_counter_get(); - k_thread_resume(t1_tid); - timestamp_end_resume_c = timing_counter_get(); + snprintf(description, sizeof(description), + "Suspend %s thread from %s thread", + (alt_options & K_USER) != 0 ? "user" : "kernel", + (start_options & K_USER) != 0 ? "user" : "kernel"); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); - diff = timing_cycles_get(×tamp_start_create_c, - ×tamp_end_create_c); - PRINT_STATS("Time to create a thread (without start)", diff, false, ""); + cycles = timestamp.cycles; + k_sem_give(&pause_sem); - diff = timing_cycles_get(×tamp_start_start_c, - ×tamp_start_suspend_c); - PRINT_STATS("Time to start a thread", diff, false, ""); + snprintf(description, sizeof(description), + "Resume %s thread from %s thread", + (alt_options & K_USER) != 0 ? "user" : "kernel", + (start_options & K_USER) != 0 ? "user" : "kernel"); - diff = timing_cycles_get(×tamp_start_suspend_c, - ×tamp_end_suspend_c); - PRINT_STATS("Time to suspend a thread", diff, false, ""); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); - diff = timing_cycles_get(×tamp_start_resume_c, - ×tamp_end_resume_c); - PRINT_STATS("Time to resume a thread", diff, false, ""); + cycles = timestamp.cycles; + k_sem_give(&pause_sem); - timestamp_start_abort_1 = timing_counter_get(); - k_thread_abort(t1_tid); - timestamp_end_abort_1 = timing_counter_get(); + snprintf(description, sizeof(description), + "Abort %s thread from %s thread", + (alt_options & K_USER) != 0 ? "user" : "kernel", + (start_options & K_USER) != 0 ? "user" : "kernel"); - diff = timing_cycles_get(×tamp_start_abort_1, - ×tamp_end_abort_1); - PRINT_STATS("Time to abort a thread (not running)", diff, false, ""); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); timing_stop(); return 0; From 4c4453d697c97645b8b73902bd7f418dd5673e1f Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 15 Sep 2023 13:43:54 -0400 Subject: [PATCH 2834/4498] tests: latency_measure: Update semaphores Updates the semaphore benchmarking in the latency_benchmark code to support user threads. Signed-off-by: Peter Mitsis --- tests/benchmarks/latency_measure/src/main.c | 17 +- .../src/sema_test_signal_release.c | 296 +++++++++++++----- 2 files changed, 235 insertions(+), 78 deletions(-) diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index a338fbb00bc..8081191b6c2 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -46,9 +46,10 @@ int error_count; /* track number of errors */ extern void thread_switch_yield(uint32_t num_iterations, bool is_cooperative); extern void int_to_thread(uint32_t num_iterations); -extern void sema_test_signal(void); +extern void sema_test_signal(uint32_t num_iterations, uint32_t options); extern void mutex_lock_unlock(void); -extern int sema_context_switch(void); +extern void sema_context_switch(uint32_t num_iterations, + uint32_t start_options, uint32_t alt_options); extern int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_options); extern void heap_malloc_free(void); @@ -92,9 +93,17 @@ static void test_thread(void *arg1, void *arg2, void *arg3) thread_ops(NUM_ITERATIONS, K_USER, 0); #endif - sema_test_signal(); + sema_test_signal(NUM_ITERATIONS, 0); +#ifdef CONFIG_USERSPACE + sema_test_signal(NUM_ITERATIONS, K_USER); +#endif - sema_context_switch(); + sema_context_switch(NUM_ITERATIONS, 0, 0); +#ifdef CONFIG_USERSPACE + sema_context_switch(NUM_ITERATIONS, 0, K_USER); + sema_context_switch(NUM_ITERATIONS, K_USER, 0); + sema_context_switch(NUM_ITERATIONS, K_USER, K_USER); +#endif mutex_lock_unlock(); diff --git a/tests/benchmarks/latency_measure/src/sema_test_signal_release.c b/tests/benchmarks/latency_measure/src/sema_test_signal_release.c index f5d2d4a8332..4e36f534ba1 100644 --- a/tests/benchmarks/latency_measure/src/sema_test_signal_release.c +++ b/tests/benchmarks/latency_measure/src/sema_test_signal_release.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2015 Wind River Systems, Inc. + * Copyright (c) 2023 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,68 +8,215 @@ /* * @file measure time for sema lock and release * - * This file contains the test that measures semaphore and mutex lock and - * release time in the kernel. There is no contention on the sema nor the - * mutex being tested. + * This file contains the test that measures semaphore give and take time + * in the kernel. There is no contention on the semaphore being tested. */ #include #include #include "utils.h" -/* the number of semaphore give/take cycles */ -#define N_TEST_SEMA 1000 +static struct k_sem sem; -#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) -/* stack used by the threads */ -static K_THREAD_STACK_DEFINE(thread_one_stack, STACK_SIZE); +static void alt_thread_entry(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + timing_t mid; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + for (uint32_t i = 0; i < num_iterations; i++) { + + /* + * 2. Give the semaphore, thereby forcing a context switch back + * to . + */ + + mid = timing_counter_get(); + k_sem_give(&sem); -static struct k_thread thread_one_data; + /* 5. Share the timestamp. */ -K_SEM_DEFINE(lock_unlock_sema, 0, N_TEST_SEMA); + timestamp.sample = mid; -K_SEM_DEFINE(sem_bench, 0, 1); + /* 6. Give so resumes execution */ -timing_t timestamp_start_sema_t_c; -timing_t timestamp_end_sema_t_c; -timing_t timestamp_start_sema_g_c; -timing_t timestamp_end_sema_g_c; + k_sem_give(&sem); + } +} -void thread_sema_test1(void *p1, void *p2, void *p3) +static void start_thread_entry(void *p1, void *p2, void *p3) { - timestamp_start_sema_t_c = timing_counter_get(); - k_sem_take(&sem_bench, K_FOREVER); - timestamp_end_sema_g_c = timing_counter_get(); + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + timing_t start; + timing_t mid; + timing_t finish; + uint32_t i; + uint64_t take_sum = 0ull; + uint64_t give_sum = 0ull; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + k_thread_start(&alt_thread); + + for (i = 0; i < num_iterations; i++) { + + /* + * 1. Block on taking the semaphore and force a context switch + * to . + */ + + start = timing_counter_get(); + k_sem_take(&sem, K_FOREVER); + + /* 3. Get the timestamp. */ + + finish = timing_counter_get(); + + /* + * 4. Let run so it can share its + * timestamp. + */ + + k_sem_take(&sem, K_FOREVER); + + /* 7. Retrieve the timestamp */ + + mid = timestamp.sample; + + take_sum += timing_cycles_get(&start, &mid); + give_sum += timing_cycles_get(&mid, &finish); + } + + k_thread_join(&alt_thread, K_FOREVER); + + /* Share the totals with the main thread */ + + timestamp.cycles = take_sum; + + k_sem_take(&sem, K_FOREVER); + + timestamp.cycles = give_sum; } -int sema_context_switch(void) +void sema_context_switch(uint32_t num_iterations, + uint32_t start_options, uint32_t alt_options) { - uint32_t diff; + uint64_t cycles; + char description[80]; + int priority; timing_start(); - k_thread_create(&thread_one_data, thread_one_stack, - STACK_SIZE, thread_sema_test1, - NULL, NULL, NULL, - K_PRIO_PREEMPT(3), 0, K_FOREVER); - k_thread_name_set(&thread_one_data, "sema_test1"); - k_thread_start(&thread_one_data); + priority = k_thread_priority_get(k_current_get()); + + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 2, start_options, K_FOREVER); + + k_thread_create(&alt_thread, alt_stack, + K_THREAD_STACK_SIZEOF(alt_stack), + alt_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, alt_options, K_FOREVER); + + k_thread_access_grant(&start_thread, &sem, &alt_thread); + + k_thread_access_grant(&alt_thread, &sem); - timestamp_end_sema_t_c = timing_counter_get(); - diff = timing_cycles_get(×tamp_start_sema_t_c, ×tamp_end_sema_t_c); - PRINT_STATS("Semaphore take time (context switch)", diff, false, ""); + /* Start the test threads */ + k_thread_start(&start_thread); - timestamp_start_sema_g_c = timing_counter_get(); - k_sem_give(&sem_bench); - diff = timing_cycles_get(×tamp_start_sema_g_c, ×tamp_end_sema_g_c); - PRINT_STATS("Semaphore give time (context switch)", diff, false, ""); + /* Retrieve the number of cycles spent taking the semaphore */ + + cycles = timestamp.cycles; + + snprintf(description, sizeof(description), + "Take a semaphore (context switch %c -> %c)", + ((start_options & K_USER) == K_USER) ? 'U' : 'K', + ((alt_options & K_USER) == K_USER) ? 'U' : 'K'); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); + + /* Unblock */ + + k_sem_give(&sem); + + /* Retrieve the number of cycles spent taking the semaphore */ + + cycles = timestamp.cycles; + + snprintf(description, sizeof(description), + "Give a semaphore (context switch %c -> %c)", + ((alt_options & K_USER) == K_USER) ? 'U' : 'K', + ((start_options & K_USER) == K_USER) ? 'U' : 'K'); + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); + + k_thread_join(&start_thread, K_FOREVER); timing_stop(); - return 0; + return; } +/** + * This is the entry point for the test that performs uncontested operations + * on the semaphore. It gives the semaphore many times, takes the semaphore + * many times and then sends the results back to the main thread. + */ +static void immediate_give_take(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + timing_t start; + timing_t finish; + uint64_t give_cycles; + uint64_t take_cycles; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + /* 1. Give a semaphore. No threads are waiting on it */ + + start = timing_counter_get(); + + for (uint32_t i = 0; i < num_iterations; i++) { + k_sem_give(&sem); + } + + finish = timing_counter_get(); + give_cycles = timing_cycles_get(&start, &finish); + + /* 2. Take a semaphore--no contention */ + + start = timing_counter_get(); + + for (uint32_t i = 0; i < num_iterations; i++) { + k_sem_take(&sem, K_NO_WAIT); + } + + finish = timing_counter_get(); + take_cycles = timing_cycles_get(&start, &finish); + + /* 3. Post the number of cycles spent giving the semaphore */ + + timestamp.cycles = give_cycles; + + /* 4. Wait for the main thread to retrieve the data */ + + k_sem_take(&sem, K_FOREVER); + + /* 7. Post the number of cycles spent taking the semaphore */ + + timestamp.cycles = take_cycles; +} + + /** * * @brief The function tests semaphore test/signal time @@ -78,58 +226,58 @@ int sema_context_switch(void) * * @return 0 on success */ -int sema_test_signal(void) +int sema_test_signal(uint32_t num_iterations, uint32_t options) { - int i; - uint32_t diff; - timing_t timestamp_start; - timing_t timestamp_end; - const char *notes = ""; - int end; - - bench_test_start(); + uint64_t cycles; + int priority; + char description[80]; + timing_start(); - timestamp_start = timing_counter_get(); + k_sem_init(&sem, 0, num_iterations); - for (i = 0; i < N_TEST_SEMA; i++) { - k_sem_give(&lock_unlock_sema); - } + priority = k_thread_priority_get(k_current_get()); - timestamp_end = timing_counter_get(); - end = bench_test_end(); - timing_stop(); + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + immediate_give_take, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, options, K_FOREVER); - if (end != 0) { - error_count++; - notes = TICK_OCCURRENCE_ERROR; - } + k_thread_access_grant(&start_thread, &sem); + k_thread_start(&start_thread); - diff = timing_cycles_get(×tamp_start, ×tamp_end); - PRINT_STATS_AVG("Average semaphore signal time", diff, N_TEST_SEMA, - false, notes); + /* 5. Retrieve the number of cycles spent giving the semaphore */ - bench_test_start(); - timing_start(); + cycles = timestamp.cycles; - timestamp_start = timing_counter_get(); + snprintf(description, sizeof(description), + "Give a semaphore (no waiters) from %s thread", + (options & K_USER) == K_USER ? "user" : "kernel"); - for (i = 0; i < N_TEST_SEMA; i++) { - k_sem_take(&lock_unlock_sema, K_FOREVER); - } + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); - timestamp_end = timing_counter_get(); - end = bench_test_end(); - timing_stop(); + /* 6. Unblock */ - if (end != 0) { - error_count++; - notes = TICK_OCCURRENCE_ERROR; - } + k_sem_give(&sem); + + /* 8. Wait for to finish */ + + k_thread_join(&start_thread, K_FOREVER); + + /* 9. Retrieve the number of cycles spent taking the semaphore */ - diff = timing_cycles_get(×tamp_start, ×tamp_end); - PRINT_STATS_AVG("Average semaphore test time", diff, N_TEST_SEMA, - false, notes); + cycles = timestamp.cycles; + + snprintf(description, sizeof(description), + "Take a semaphore (no blocking) from %s thread", + (options & K_USER) == K_USER ? "user" : "kernel"); + + PRINT_STATS_AVG(description, (uint32_t)cycles, + num_iterations, false, ""); + + timing_stop(); return 0; } From 9b38aec366ac190b0a6f4bd3ea443bd76344140b Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 18 Sep 2023 14:21:30 -0400 Subject: [PATCH 2835/4498] tests: latency_measure: Update mutexes Updates the mutex benchmark tests to support user threads. Signed-off-by: Peter Mitsis --- tests/benchmarks/latency_measure/src/main.c | 7 +- .../latency_measure/src/mutex_lock_unlock.c | 118 +++++++++++------- 2 files changed, 80 insertions(+), 45 deletions(-) diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index 8081191b6c2..ca44f164bad 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -47,7 +47,7 @@ int error_count; /* track number of errors */ extern void thread_switch_yield(uint32_t num_iterations, bool is_cooperative); extern void int_to_thread(uint32_t num_iterations); extern void sema_test_signal(uint32_t num_iterations, uint32_t options); -extern void mutex_lock_unlock(void); +extern void mutex_lock_unlock(uint32_t num_iterations, uint32_t options); extern void sema_context_switch(uint32_t num_iterations, uint32_t start_options, uint32_t alt_options); extern int thread_ops(uint32_t num_iterations, uint32_t start_options, @@ -105,7 +105,10 @@ static void test_thread(void *arg1, void *arg2, void *arg3) sema_context_switch(NUM_ITERATIONS, K_USER, K_USER); #endif - mutex_lock_unlock(); + mutex_lock_unlock(NUM_ITERATIONS, 0); +#ifdef CONFIG_USERSPACE + mutex_lock_unlock(NUM_ITERATIONS, K_USER); +#endif heap_malloc_free(); diff --git a/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c b/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c index cfc8ae2118b..4b74a1cfd35 100644 --- a/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c +++ b/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c @@ -1,18 +1,64 @@ /* * Copyright (c) 2012-2015 Wind River Systems, Inc. - * Copyright (c) 2020 Intel Corporation + * Copyright (c) 2020,2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ +/* + * @file measure time for mutex lock and unlock + * + * This file contains the test that measures mutex lock and unlock times + * in the kernel. There is no contention on the mutex being tested. + */ + #include #include #include "utils.h" -/* the number of mutex lock/unlock cycles */ -#define N_TEST_MUTEX 1000 +static K_MUTEX_DEFINE(test_mutex); + +static void start_lock_unlock(void *p1, void *p2, void *p3) +{ + uint32_t i; + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + timing_t start; + timing_t finish; + uint64_t lock_cycles; + uint64_t unlock_cycles; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + start = timing_counter_get(); -K_MUTEX_DEFINE(test_mutex); + /* Recursively lock take the mutex */ + + for (i = 0; i < num_iterations; i++) { + k_mutex_lock(&test_mutex, K_NO_WAIT); + } + + finish = timing_counter_get(); + + lock_cycles = timing_cycles_get(&start, &finish); + + start = timing_counter_get(); + + /* Recursively unlock the mutex */ + + for (i = 0; i < num_iterations; i++) { + k_mutex_unlock(&test_mutex); + } + + finish = timing_counter_get(); + + unlock_cycles = timing_cycles_get(&start, &finish); + + timestamp.cycles = lock_cycles; + k_sem_take(&pause_sem, K_FOREVER); + + timestamp.cycles = unlock_cycles; +} /** @@ -24,55 +70,41 @@ K_MUTEX_DEFINE(test_mutex); * * @return 0 on success */ -int mutex_lock_unlock(void) +int mutex_lock_unlock(uint32_t num_iterations, uint32_t options) { - int i; - uint32_t diff; - timing_t timestamp_start; - timing_t timestamp_end; - const char *notes = ""; - int end; + char description[80]; + int priority; + uint64_t cycles; timing_start(); - bench_test_start(); - timestamp_start = timing_counter_get(); + priority = k_thread_priority_get(k_current_get()); - for (i = 0; i < N_TEST_MUTEX; i++) { - k_mutex_lock(&test_mutex, K_FOREVER); - } + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_lock_unlock, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, options, K_FOREVER); - timestamp_end = timing_counter_get(); - end = bench_test_end(); + k_thread_access_grant(&start_thread, &test_mutex, &pause_sem); + k_thread_start(&start_thread); - diff = timing_cycles_get(×tamp_start, ×tamp_end); + cycles = timestamp.cycles; + k_sem_give(&pause_sem); - if (end != 0) { - notes = TICK_OCCURRENCE_ERROR; - error_count++; - } + snprintf(description, sizeof(description), + "Lock a mutex from %s thread", + (options & K_USER) == K_USER ? "user" : "kernel"); + PRINT_STATS_AVG(description, (uint32_t)cycles, num_iterations, + false, ""); - PRINT_STATS_AVG("Average time to lock a mutex", diff, N_TEST_MUTEX, - false, notes); - - bench_test_start(); - timestamp_start = timing_counter_get(); - - for (i = 0; i < N_TEST_MUTEX; i++) { - k_mutex_unlock(&test_mutex); - } - - timestamp_end = timing_counter_get(); - end = bench_test_end(); - diff = timing_cycles_get(×tamp_start, ×tamp_end); - - if (end != 0) { - notes = TICK_OCCURRENCE_ERROR; - error_count++; - } + cycles = timestamp.cycles; - PRINT_STATS_AVG("Average time to unlock a mutex", diff, N_TEST_MUTEX, - false, notes); + snprintf(description, sizeof(description), + "Unlock a mutex from %s thread", + (options & K_USER) == K_USER ? "user" : "kernel"); + PRINT_STATS_AVG(description, (uint32_t)cycles, num_iterations, + false, ""); timing_stop(); return 0; From 1a7e5c6c8d25665c77fc150f70476fd5cb59e97f Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 5 Oct 2023 10:30:43 -0400 Subject: [PATCH 2836/4498] tests: latency_measure: Use syscall to get timestamp Many architectures and platforms can not directly read a timestamp from userspace as the relevant MMIO registers are inaccessible. This necessitates that the timestamp be obtained by a system call. The additional overhead from these system calls can be taken into account and the recorded times adjusted depending upon whether the test occurred entirely within kernel space, entirely within user space, or a mix between the two. It is worth noting that when the test requires a mix of both user and kernel space threads, the overhead is estimated as the mean average of purely kernel threads and purely user threads overhead times. This might not be technically correct, but it ought to provide a reasonable enough approximation. Signed-off-by: Peter Mitsis --- tests/benchmarks/latency_measure/prj.conf | 1 + .../latency_measure/src/int_to_thread.c | 13 +- tests/benchmarks/latency_measure/src/main.c | 9 +- .../latency_measure/src/mutex_lock_unlock.c | 11 +- .../src/sema_test_signal_release.c | 19 +-- tests/benchmarks/latency_measure/src/thread.c | 26 ++-- .../latency_measure/src/thread_switch_yield.c | 7 +- .../latency_measure/src/timing_sc.c | 112 ++++++++++++++++++ .../latency_measure/src/timing_sc.h | 21 ++++ tests/benchmarks/latency_measure/src/utils.h | 10 ++ 10 files changed, 197 insertions(+), 32 deletions(-) create mode 100644 tests/benchmarks/latency_measure/src/timing_sc.c create mode 100644 tests/benchmarks/latency_measure/src/timing_sc.h diff --git a/tests/benchmarks/latency_measure/prj.conf b/tests/benchmarks/latency_measure/prj.conf index 4a786177bbc..03621afb14e 100644 --- a/tests/benchmarks/latency_measure/prj.conf +++ b/tests/benchmarks/latency_measure/prj.conf @@ -24,3 +24,4 @@ CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_TIMING_FUNCTIONS=y CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_APPLICATION_DEFINED_SYSCALL=y diff --git a/tests/benchmarks/latency_measure/src/int_to_thread.c b/tests/benchmarks/latency_measure/src/int_to_thread.c index 608d3b30893..ad3cf70fad7 100644 --- a/tests/benchmarks/latency_measure/src/int_to_thread.c +++ b/tests/benchmarks/latency_measure/src/int_to_thread.c @@ -24,6 +24,7 @@ #include #include "utils.h" +#include "timing_sc.h" #include @@ -43,7 +44,7 @@ static void test_isr(const void *arg) k_sem_give(sem); } - timestamp.sample = timing_counter_get(); + timestamp.sample = timing_timestamp_get(); } /** @@ -61,7 +62,7 @@ static void int_to_interrupted_thread(uint32_t num_iterations, uint64_t *sum) for (uint32_t i = 0; i < num_iterations; i++) { irq_offload(test_isr, NULL); - finish = timing_counter_get(); + finish = timing_timestamp_get(); start = timestamp.sample; *sum += timing_cycles_get(&start, &finish); @@ -92,7 +93,7 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 3. Obtain the start and finish timestamps */ - finish = timing_counter_get(); + finish = timing_timestamp_get(); start = timestamp.sample; sum += timing_cycles_get(&start, &finish); @@ -171,6 +172,8 @@ int int_to_thread(uint32_t num_iterations) int_to_interrupted_thread(num_iterations, &sum); + sum -= timestamp_overhead_adjustment(0, 0); + PRINT_STATS_AVG("Switch from ISR back to interrupted thread", (uint32_t)sum, num_iterations, false, ""); @@ -178,6 +181,8 @@ int int_to_thread(uint32_t num_iterations) int_to_another_thread(num_iterations, &sum, 0); + sum -= timestamp_overhead_adjustment(0, 0); + PRINT_STATS_AVG("Switch from ISR to another thread (kernel)", (uint32_t)sum, num_iterations, false, ""); @@ -186,6 +191,8 @@ int int_to_thread(uint32_t num_iterations) #if CONFIG_USERSPACE int_to_another_thread(num_iterations, &sum, K_USER); + sum -= timestamp_overhead_adjustment(0, K_USER); + PRINT_STATS_AVG("Switch from ISR to another thread (user)", (uint32_t)sum, num_iterations, false, ""); #endif diff --git a/tests/benchmarks/latency_measure/src/main.c b/tests/benchmarks/latency_measure/src/main.c index ca44f164bad..499ce1273f1 100644 --- a/tests/benchmarks/latency_measure/src/main.c +++ b/tests/benchmarks/latency_measure/src/main.c @@ -14,18 +14,13 @@ #include #include #include "utils.h" +#include "timing_sc.h" #include #define NUM_ITERATIONS 10000 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) -#ifdef CONFIG_USERSPACE -#define BENCH_BMEM K_APP_BMEM(bench_mem_partition) -#else -#define BENCH_BMEM -#endif - uint32_t tm_off; BENCH_BMEM struct timestamp_data timestamp; @@ -76,6 +71,8 @@ static void test_thread(void *arg1, void *arg2, void *arg3) TC_START("Time Measurement"); TC_PRINT("Timing results: Clock frequency: %u MHz\n", freq); + timestamp_overhead_init(NUM_ITERATIONS); + /* Preemptive threads context switching */ thread_switch_yield(NUM_ITERATIONS, false); diff --git a/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c b/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c index 4b74a1cfd35..5ab52b43dcd 100644 --- a/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c +++ b/tests/benchmarks/latency_measure/src/mutex_lock_unlock.c @@ -15,6 +15,7 @@ #include #include #include "utils.h" +#include "timing_sc.h" static K_MUTEX_DEFINE(test_mutex); @@ -30,7 +31,7 @@ static void start_lock_unlock(void *p1, void *p2, void *p3) ARG_UNUSED(p2); ARG_UNUSED(p3); - start = timing_counter_get(); + start = timing_timestamp_get(); /* Recursively lock take the mutex */ @@ -38,11 +39,11 @@ static void start_lock_unlock(void *p1, void *p2, void *p3) k_mutex_lock(&test_mutex, K_NO_WAIT); } - finish = timing_counter_get(); + finish = timing_timestamp_get(); lock_cycles = timing_cycles_get(&start, &finish); - start = timing_counter_get(); + start = timing_timestamp_get(); /* Recursively unlock the mutex */ @@ -50,7 +51,7 @@ static void start_lock_unlock(void *p1, void *p2, void *p3) k_mutex_unlock(&test_mutex); } - finish = timing_counter_get(); + finish = timing_timestamp_get(); unlock_cycles = timing_cycles_get(&start, &finish); @@ -90,6 +91,7 @@ int mutex_lock_unlock(uint32_t num_iterations, uint32_t options) k_thread_start(&start_thread); cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(options, options); k_sem_give(&pause_sem); snprintf(description, sizeof(description), @@ -99,6 +101,7 @@ int mutex_lock_unlock(uint32_t num_iterations, uint32_t options) false, ""); cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(options, options); snprintf(description, sizeof(description), "Unlock a mutex from %s thread", diff --git a/tests/benchmarks/latency_measure/src/sema_test_signal_release.c b/tests/benchmarks/latency_measure/src/sema_test_signal_release.c index 4e36f534ba1..e5ea2b72992 100644 --- a/tests/benchmarks/latency_measure/src/sema_test_signal_release.c +++ b/tests/benchmarks/latency_measure/src/sema_test_signal_release.c @@ -15,6 +15,7 @@ #include #include #include "utils.h" +#include "timing_sc.h" static struct k_sem sem; @@ -33,7 +34,7 @@ static void alt_thread_entry(void *p1, void *p2, void *p3) * to . */ - mid = timing_counter_get(); + mid = timing_timestamp_get(); k_sem_give(&sem); /* 5. Share the timestamp. */ @@ -68,12 +69,12 @@ static void start_thread_entry(void *p1, void *p2, void *p3) * to . */ - start = timing_counter_get(); + start = timing_timestamp_get(); k_sem_take(&sem, K_FOREVER); /* 3. Get the timestamp. */ - finish = timing_counter_get(); + finish = timing_timestamp_get(); /* * 4. Let run so it can share its @@ -135,6 +136,7 @@ void sema_context_switch(uint32_t num_iterations, /* Retrieve the number of cycles spent taking the semaphore */ cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); snprintf(description, sizeof(description), "Take a semaphore (context switch %c -> %c)", @@ -150,6 +152,7 @@ void sema_context_switch(uint32_t num_iterations, /* Retrieve the number of cycles spent taking the semaphore */ cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); snprintf(description, sizeof(description), "Give a semaphore (context switch %c -> %c)", @@ -183,24 +186,24 @@ static void immediate_give_take(void *p1, void *p2, void *p3) /* 1. Give a semaphore. No threads are waiting on it */ - start = timing_counter_get(); + start = timing_timestamp_get(); for (uint32_t i = 0; i < num_iterations; i++) { k_sem_give(&sem); } - finish = timing_counter_get(); + finish = timing_timestamp_get(); give_cycles = timing_cycles_get(&start, &finish); /* 2. Take a semaphore--no contention */ - start = timing_counter_get(); + start = timing_timestamp_get(); for (uint32_t i = 0; i < num_iterations; i++) { k_sem_take(&sem, K_NO_WAIT); } - finish = timing_counter_get(); + finish = timing_timestamp_get(); take_cycles = timing_cycles_get(&start, &finish); /* 3. Post the number of cycles spent giving the semaphore */ @@ -250,6 +253,7 @@ int sema_test_signal(uint32_t num_iterations, uint32_t options) /* 5. Retrieve the number of cycles spent giving the semaphore */ cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(options, options); snprintf(description, sizeof(description), "Give a semaphore (no waiters) from %s thread", @@ -269,6 +273,7 @@ int sema_test_signal(uint32_t num_iterations, uint32_t options) /* 9. Retrieve the number of cycles spent taking the semaphore */ cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(options, options); snprintf(description, sizeof(description), "Take a semaphore (no blocking) from %s thread", diff --git a/tests/benchmarks/latency_measure/src/thread.c b/tests/benchmarks/latency_measure/src/thread.c index db4da3e685f..4448b0e2304 100644 --- a/tests/benchmarks/latency_measure/src/thread.c +++ b/tests/benchmarks/latency_measure/src/thread.c @@ -22,6 +22,7 @@ #include #include #include "utils.h" +#include "timing_sc.h" #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) @@ -38,7 +39,7 @@ static void alt_thread_entry(void *p1, void *p2, void *p3) /* 3. Finish measuring time to start */ - timestamp.sample = timing_counter_get(); + timestamp.sample = timing_timestamp_get(); /* 4. Let process the time measurement. */ @@ -46,12 +47,12 @@ static void alt_thread_entry(void *p1, void *p2, void *p3) /* 7. Begin measuring time to suspend active thread (self/alt_thread) */ - timestamp.sample = timing_counter_get(); + timestamp.sample = timing_timestamp_get(); k_thread_suspend(&alt_thread); /* 10. Finish measuring time to resume (self) */ - timestamp.sample = timing_counter_get(); + timestamp.sample = timing_timestamp_get(); /* 11. Lower the priority so can terminate us. */ @@ -81,14 +82,14 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 1. Measure time to create, but not start */ if ((bit_options & START_ALT) == START_ALT) { - start = timing_counter_get(); + start = timing_timestamp_get(); k_thread_create(&alt_thread, alt_stack, K_THREAD_STACK_SIZEOF(alt_stack), alt_thread_entry, NULL, NULL, NULL, priority, (bit_options & ALT_USER) == ALT_USER ? K_USER : 0, K_FOREVER); - finish = timing_counter_get(); + finish = timing_timestamp_get(); thread_create_sum += timing_cycles_get(&start, &finish); } else { @@ -116,7 +117,7 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 2. Begin measuring time to start */ - start = timing_counter_get(); + start = timing_timestamp_get(); k_thread_start(&alt_thread); /* 5. Process the time to start */ @@ -131,12 +132,12 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 8. Finish measuring time to suspend */ start = timestamp.sample; - finish = timing_counter_get(); + finish = timing_timestamp_get(); thread_suspend_sum += timing_cycles_get(&start, &finish); /* 9. Being measuring time to resume */ - start = timing_counter_get(); + start = timing_timestamp_get(); k_thread_resume(&alt_thread); /* 12. Process the time it took to resume */ @@ -146,9 +147,9 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 13. Process the time to terminate */ - start = timing_counter_get(); + start = timing_timestamp_get(); k_thread_abort(&alt_thread); - finish = timing_counter_get(); + finish = timing_timestamp_get(); thread_abort_sum += timing_cycles_get(&start, &finish); } @@ -239,6 +240,7 @@ int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_opt } cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); k_sem_give(&pause_sem); if ((bit_options & START_ALT) == START_ALT) { @@ -255,6 +257,7 @@ int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_opt } cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); k_sem_give(&pause_sem); snprintf(description, sizeof(description), @@ -266,6 +269,7 @@ int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_opt num_iterations, false, ""); cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); k_sem_give(&pause_sem); snprintf(description, sizeof(description), @@ -277,6 +281,7 @@ int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_opt num_iterations, false, ""); cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); k_sem_give(&pause_sem); snprintf(description, sizeof(description), @@ -288,6 +293,7 @@ int thread_ops(uint32_t num_iterations, uint32_t start_options, uint32_t alt_opt num_iterations, false, ""); cycles = timestamp.cycles; + cycles -= timestamp_overhead_adjustment(start_options, alt_options); k_sem_give(&pause_sem); snprintf(description, sizeof(description), diff --git a/tests/benchmarks/latency_measure/src/thread_switch_yield.c b/tests/benchmarks/latency_measure/src/thread_switch_yield.c index 14bd157d720..44ccc5932c5 100644 --- a/tests/benchmarks/latency_measure/src/thread_switch_yield.c +++ b/tests/benchmarks/latency_measure/src/thread_switch_yield.c @@ -23,6 +23,7 @@ #include #include "utils.h" +#include "timing_sc.h" static void alt_thread_entry(void *p1, void *p2, void *p3) { @@ -37,7 +38,7 @@ static void alt_thread_entry(void *p1, void *p2, void *p3) /* 3. Obtain the 'finish' timestamp */ - timestamp.sample = timing_counter_get(); + timestamp.sample = timing_timestamp_get(); /* 4. Switch to */ @@ -64,7 +65,7 @@ static void start_thread_entry(void *p1, void *p2, void *p3) /* 1. Get 'start' timestamp */ - start = timing_counter_get(); + start = timing_timestamp_get(); /* 2. Switch to */ @@ -127,6 +128,8 @@ static void thread_switch_yield_common(const char *description, sum = timestamp.cycles; + sum -= timestamp_overhead_adjustment(start_options, alt_options); + snprintf(summary, sizeof(summary), "%s (%c -> %c)", description, diff --git a/tests/benchmarks/latency_measure/src/timing_sc.c b/tests/benchmarks/latency_measure/src/timing_sc.c new file mode 100644 index 00000000000..051b9d1810b --- /dev/null +++ b/tests/benchmarks/latency_measure/src/timing_sc.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @file + * This file contains routines for implementing a timestamp system call + * as well as routines for determining the overhead associated with it. + */ + +#include +#include +#include "utils.h" +#include "timing_sc.h" + +BENCH_BMEM uint64_t timestamp_overhead; +#ifdef CONFIG_USERSPACE +BENCH_BMEM uint64_t user_timestamp_overhead; +#endif + +timing_t z_impl_timing_timestamp_get(void) +{ + return timing_counter_get(); +} + +#ifdef CONFIG_USERSPACE +timing_t z_vrfy_timing_timestamp_get(void) +{ + return z_impl_timing_timestamp_get(); +} +#include +#endif + +static void start_thread_entry(void *p1, void *p2, void *p3) +{ + uint32_t num_iterations = (uint32_t)(uintptr_t)p1; + timing_t start; + timing_t finish; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + start = timing_timestamp_get(); + for (uint32_t i = 0; i < num_iterations; i++) { + timing_timestamp_get(); + } + finish = timing_timestamp_get(); + + timestamp.cycles = timing_cycles_get(&start, &finish); +} + +void timestamp_overhead_init(uint32_t num_iterations) +{ + int priority; + + priority = k_thread_priority_get(k_current_get()); + + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, 0, K_FOREVER); + + k_thread_start(&start_thread); + + k_thread_join(&start_thread, K_FOREVER); + + timestamp_overhead = timestamp.cycles; + +#ifdef CONFIG_USERSPACE + k_thread_create(&start_thread, start_stack, + K_THREAD_STACK_SIZEOF(start_stack), + start_thread_entry, + (void *)(uintptr_t)num_iterations, NULL, NULL, + priority - 1, K_USER, K_FOREVER); + + k_thread_start(&start_thread); + + k_thread_join(&start_thread, K_FOREVER); + + user_timestamp_overhead = timestamp.cycles; +#endif +} + +uint64_t timestamp_overhead_adjustment(uint32_t options1, uint32_t options2) +{ +#ifdef CONFIG_USERSPACE + if (((options1 | options2) & K_USER) == K_USER) { + if (((options1 & options2) & K_USER) == K_USER) { + /* + * Both start and finish timestamps were obtained + * from userspace. + */ + return user_timestamp_overhead; + } + /* + * One timestamp came from userspace, and the other came + * from kernel space. Estimate the overhead as the mean + * between the two. + */ + return (timestamp_overhead + user_timestamp_overhead) / 2; + } +#endif + + /* + * Both start and finish timestamps were obtained + * from kernel space. + */ + return timestamp_overhead; +} diff --git a/tests/benchmarks/latency_measure/src/timing_sc.h b/tests/benchmarks/latency_measure/src/timing_sc.h new file mode 100644 index 00000000000..265d71f5048 --- /dev/null +++ b/tests/benchmarks/latency_measure/src/timing_sc.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _LATENCY_MEASURE_TIMING_SC_H +#define _LATENCY_MEASURE_TIMING_SC_H + +#include +#include +#include + +__syscall timing_t timing_timestamp_get(void); + +void timestamp_overhead_init(uint32_t num_iterations); +uint64_t timestamp_overhead_adjustment(uint32_t options1, uint32_t options2); + +#include + +#endif diff --git a/tests/benchmarks/latency_measure/src/utils.h b/tests/benchmarks/latency_measure/src/utils.h index a946e38a38b..62d2fb7259e 100644 --- a/tests/benchmarks/latency_measure/src/utils.h +++ b/tests/benchmarks/latency_measure/src/utils.h @@ -19,6 +19,12 @@ #define START_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) #define ALT_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) +#ifdef CONFIG_USERSPACE +#define BENCH_BMEM K_APP_BMEM(bench_mem_partition) +#else +#define BENCH_BMEM +#endif + struct timestamp_data { uint64_t cycles; timing_t sample; @@ -33,6 +39,10 @@ extern struct k_thread alt_thread; extern struct k_sem pause_sem; extern struct timestamp_data timestamp; +#ifdef CONFIG_USERSPACE +extern uint64_t user_timestamp_overhead; +#endif +extern uint64_t timestamp_overhead; extern int error_count; From 6899c0d73abda6ac8e574cfca4db6fd92f6cd3fd Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 6 Oct 2023 10:36:23 -0400 Subject: [PATCH 2837/4498] tests: latency_measure: Misc updates Adds userspace configuration to testcase.yaml. Updates the README.rst with output from runs on a frdm_k64f board as not only have the descriptions changed, but there is now additional output for userspace configurations. Signed-off-by: Peter Mitsis --- tests/benchmarks/latency_measure/README.rst | 127 +++++++++++++----- tests/benchmarks/latency_measure/prj.conf | 1 - .../benchmarks/latency_measure/prj_user.conf | 27 ++++ .../benchmarks/latency_measure/testcase.yaml | 17 +++ 4 files changed, 140 insertions(+), 32 deletions(-) create mode 100644 tests/benchmarks/latency_measure/prj_user.conf diff --git a/tests/benchmarks/latency_measure/README.rst b/tests/benchmarks/latency_measure/README.rst index 160dc184e40..7f17e979697 100644 --- a/tests/benchmarks/latency_measure/README.rst +++ b/tests/benchmarks/latency_measure/README.rst @@ -1,44 +1,109 @@ Latency Measurements #################### -This benchmark measures the latency of selected kernel capabilities, including: +This benchmark measures the average latency of selected kernel capabilities, +including: - -* Measure time to switch from ISR back to interrupted thread -* Measure time from ISR to executing a different thread (rescheduled) -* Measure average time to signal a semaphore then test that semaphore -* Measure average time to signal a semaphore then test that semaphore with a context switch -* Measure average time to lock a mutex then unlock that mutex -* Measure average context switch time between threads using (k_yield) -* Measure average context switch time between threads (coop) -* Time it takes to suspend a thread -* Time it takes to resume a suspended thread +* Context switch time between preemptive threads using k_yield +* Context switch time between cooperative threads using k_yield +* Time to switch from ISR back to interrupted thread +* Time from ISR to executing a different thread (rescheduled) +* Times to signal a semaphore then test that semaphore +* Times to signal a semaphore then test that semaphore with a context switch +* Times to lock a mutex then unlock that mutex * Time it takes to create a new thread (without starting it) * Time it takes to start a newly created thread +* Time it takes to suspend a thread +* Time it takes to resume a suspended thread +* Time it takes to abort a thread * Measure average time to alloc memory from heap then free that memory +When userspace is enabled using the prj_user.conf configuration file, this benchmark will +where possible, also test the above capabilities using various configurations involving user +threads: + +* Kernel thread to kernel thread +* Kernel thread to user thread +* User thread to kernel thread +* User thread to user thread + +Sample output of the benchmark (without userspace enabled):: + + *** Booting Zephyr OS build v3.5.0-rc1-139-gdab69aeed11d *** + START - Time Measurement + Timing results: Clock frequency: 120 MHz + Preemptive threads ctx switch via k_yield (K -> K) : 519 cycles , 4325 ns : + Cooperative threads ctx switch via k_yield (K -> K) : 519 cycles , 4325 ns : + Switch from ISR back to interrupted thread : 508 cycles , 4241 ns : + Switch from ISR to another thread (kernel) : 554 cycles , 4616 ns : + Create kernel thread from kernel thread : 396 cycles , 3308 ns : + Start kernel thread from kernel thread : 603 cycles , 5033 ns : + Suspend kernel thread from kernel thread : 599 cycles , 4992 ns : + Resume kernel thread from kernel thread : 547 cycles , 4558 ns : + Abort kernel thread from kernel thread : 339 cycles , 2825 ns : + Give a semaphore (no waiters) from kernel thread : 134 cycles , 1116 ns : + Take a semaphore (no blocking) from kernel thread : 53 cycles , 441 ns : + Take a semaphore (context switch K -> K) : 689 cycles , 5742 ns : + Give a semaphore (context switch K -> K) : 789 cycles , 6575 ns : + Lock a mutex from kernel thread : 94 cycles , 783 ns : + Unlock a mutex from kernel thread : 24 cycles , 200 ns : + Average time for heap malloc : 620 cycles , 5166 ns : + Average time for heap free : 431 cycles , 3591 ns : + =================================================================== + PROJECT EXECUTION SUCCESSFUL -Sample output of the benchmark:: +Sample output of the benchmark (with userspace enabled):: - *** Booting Zephyr OS build zephyr-v2.6.0-1119-g378a1e082ac5 *** + *** Booting Zephyr OS build v3.5.0-rc1-139-gdab69aeed11d *** START - Time Measurement - Timing results: Clock frequency: 1000 MHz - Average thread context switch using yield : 9060 cycles , 9060 ns - Average context switch time between threads (coop) : 9503 cycles , 9503 ns - Switch from ISR back to interrupted thread : 14208 cycles , 14208 ns - Time from ISR to executing a different thread : 9664 cycles , 9664 ns - Time to create a thread (without start) : 3968 cycles , 3968 ns - Time to start a thread : 12064 cycles , 12064 ns - Time to suspend a thread : 12640 cycles , 12640 ns - Time to resume a thread : 12096 cycles , 12096 ns - Time to abort a thread (not running) : 2208 cycles , 2208 ns - Average semaphore signal time : 8928 cycles , 8928 ns - Average semaphore test time : 2048 cycles , 2048 ns - Semaphore take time (context switch) : 13472 cycles , 13472 ns - Semaphore give time (context switch) : 18400 cycles , 18400 ns - Average time to lock a mutex : 3072 cycles , 3072 ns - Average time to unlock a mutex : 9251 cycles , 9251 ns - Average time for heap malloc : 13056 cycles , 13056 ns - Average time for heap free : 7776 cycles , 7776 ns + Timing results: Clock frequency: 120 MHz + Preemptive threads ctx switch via k_yield (K -> K) : 1195 cycles , 9958 ns : + Preemptive threads ctx switch via k_yield (U -> U) : 1485 cycles , 12379 ns : + Preemptive threads ctx switch via k_yield (K -> U) : 1390 cycles , 11587 ns : + Preemptive threads ctx switch via k_yield (U -> K) : 1289 cycles , 10749 ns : + Cooperative threads ctx switch via k_yield (K -> K) : 1185 cycles , 9875 ns : + Cooperative threads ctx switch via k_yield (U -> U) : 1475 cycles , 12295 ns : + Cooperative threads ctx switch via k_yield (K -> U) : 1380 cycles , 11504 ns : + Cooperative threads ctx switch via k_yield (U -> K) : 1280 cycles , 10666 ns : + Switch from ISR back to interrupted thread : 1130 cycles , 9416 ns : + Switch from ISR to another thread (kernel) : 1184 cycles , 9874 ns : + Switch from ISR to another thread (user) : 1390 cycles , 11583 ns : + Create kernel thread from kernel thread : 985 cycles , 8208 ns : + Start kernel thread from kernel thread : 1275 cycles , 10625 ns : + Suspend kernel thread from kernel thread : 1220 cycles , 10167 ns : + Resume kernel thread from kernel thread : 1193 cycles , 9942 ns : + Abort kernel thread from kernel thread : 2555 cycles , 21292 ns : + Create user thread from kernel thread : 849 cycles , 7083 ns : + Start user thread from kernel thread : 6715 cycles , 55960 ns : + Suspend user thread from kernel thread : 1585 cycles , 13208 ns : + Resume user thread from kernel thread : 1383 cycles , 11525 ns : + Abort user thread from kernel thread : 2420 cycles , 20167 ns : + Create user thread from user thread : 2110 cycles , 17584 ns : + Start user thread from user thread : 7070 cycles , 58919 ns : + Suspend user thread from user thread : 1784 cycles , 14874 ns : + Resume user thread from user thread : 1740 cycles , 14502 ns : + Abort user thread from user thread : 3000 cycles , 25000 ns : + Start kernel thread from user thread : 1630 cycles , 13583 ns : + Suspend kernel thread from user thread : 1420 cycles , 11833 ns : + Resume kernel thread from user thread : 1550 cycles , 12917 ns : + Abort kernel thread from user thread : 3135 cycles , 26125 ns : + Give a semaphore (no waiters) from kernel thread : 160 cycles , 1333 ns : + Take a semaphore (no blocking) from kernel thread : 95 cycles , 791 ns : + Give a semaphore (no waiters) from user thread : 380 cycles , 3166 ns : + Take a semaphore (no blocking) from user thread : 315 cycles , 2625 ns : + Take a semaphore (context switch K -> K) : 1340 cycles , 11167 ns : + Give a semaphore (context switch K -> K) : 1460 cycles , 12167 ns : + Take a semaphore (context switch K -> U) : 1540 cycles , 12838 ns : + Give a semaphore (context switch U -> K) : 1800 cycles , 15000 ns : + Take a semaphore (context switch U -> K) : 1690 cycles , 14084 ns : + Give a semaphore (context switch K -> U) : 1650 cycles , 13750 ns : + Take a semaphore (context switch U -> U) : 1890 cycles , 15756 ns : + Give a semaphore (context switch U -> U) : 1990 cycles , 16583 ns : + Lock a mutex from kernel thread : 105 cycles , 875 ns : + Unlock a mutex from kernel thread : 17 cycles , 141 ns : + Lock a mutex from user thread : 330 cycles , 2750 ns : + Unlock a mutex from user thread : 255 cycles , 2125 ns : + Average time for heap malloc : 606 cycles , 5058 ns : + Average time for heap free : 422 cycles , 3516 ns : =================================================================== PROJECT EXECUTION SUCCESSFUL diff --git a/tests/benchmarks/latency_measure/prj.conf b/tests/benchmarks/latency_measure/prj.conf index 03621afb14e..d1bc5fbaa17 100644 --- a/tests/benchmarks/latency_measure/prj.conf +++ b/tests/benchmarks/latency_measure/prj.conf @@ -2,7 +2,6 @@ CONFIG_TEST=y # eliminate timer interrupts during the benchmark CONFIG_SYS_CLOCK_TICKS_PER_SEC=1 -CONFIG_TICKLESS_KERNEL=n # We use irq_offload(), enable it CONFIG_IRQ_OFFLOAD=y diff --git a/tests/benchmarks/latency_measure/prj_user.conf b/tests/benchmarks/latency_measure/prj_user.conf new file mode 100644 index 00000000000..92ca89a3bea --- /dev/null +++ b/tests/benchmarks/latency_measure/prj_user.conf @@ -0,0 +1,27 @@ +CONFIG_TEST=y + +# eliminate timer interrupts during the benchmark +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1 + +# We use irq_offload(), enable it +CONFIG_IRQ_OFFLOAD=y + +# Reduce memory/code footprint +CONFIG_BT=n +CONFIG_FORCE_NO_ASSERT=y + +CONFIG_TEST_HW_STACK_PROTECTION=n +# Disable HW Stack Protection (see #28664) +CONFIG_HW_STACK_PROTECTION=n +CONFIG_COVERAGE=n + +# Disable system power management +CONFIG_PM=n + +# Can only run under 1 CPU +CONFIG_MP_MAX_NUM_CPUS=1 +CONFIG_TIMING_FUNCTIONS=y + +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_APPLICATION_DEFINED_SYSCALL=y +CONFIG_USERSPACE=y diff --git a/tests/benchmarks/latency_measure/testcase.yaml b/tests/benchmarks/latency_measure/testcase.yaml index 694a4138130..eb63c107d86 100644 --- a/tests/benchmarks/latency_measure/testcase.yaml +++ b/tests/benchmarks/latency_measure/testcase.yaml @@ -36,3 +36,20 @@ tests: regex: "(?P.*):(?P.*) cycles ,(?P.*) ns" regex: - "PROJECT EXECUTION SUCCESSFUL" + + # Obtain the benchmark results for various user thread / kernel thread + # configurations on platforms that support user space. + benchmark.user.latency: + filter: CONFIG_ARCH_HAS_USERSPACE + timeout: 300 + extra_args: CONF_FILE=prj_user.conf + harness: console + integration_platforms: + - qemu_x86 + - qemu_cortex_a53 + harness_config: + type: one_line + record: + regex: "(?P.*):(?P.*) cycles ,(?P.*) ns" + regex: + - "PROJECT EXECUTION SUCCESSFUL" From 56011222a42b7a2ea1b1908b93247515f00b5670 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 13 Oct 2023 17:05:00 -0400 Subject: [PATCH 2838/4498] tests: app_kernel: Remove unused symbols Begin cleaning the the app_kernel benchmark project by removing unused symbols. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/config.h | 24 -------- tests/benchmarks/app_kernel/src/fifo_b.c | 6 -- tests/benchmarks/app_kernel/src/fifo_r.c | 8 +-- tests/benchmarks/app_kernel/src/mailbox_b.c | 32 ----------- tests/benchmarks/app_kernel/src/mailbox_r.c | 7 --- tests/benchmarks/app_kernel/src/master.c | 22 +------- tests/benchmarks/app_kernel/src/master.h | 61 +-------------------- tests/benchmarks/app_kernel/src/memmap_b.c | 7 --- tests/benchmarks/app_kernel/src/mutex_b.c | 6 -- tests/benchmarks/app_kernel/src/pipe_b.c | 40 -------------- tests/benchmarks/app_kernel/src/pipe_r.c | 8 --- tests/benchmarks/app_kernel/src/receiver.c | 14 ++--- tests/benchmarks/app_kernel/src/sema_b.c | 5 -- tests/benchmarks/app_kernel/src/sema_r.c | 4 -- 14 files changed, 11 insertions(+), 233 deletions(-) diff --git a/tests/benchmarks/app_kernel/src/config.h b/tests/benchmarks/app_kernel/src/config.h index cce54d2852b..f6cd002a315 100644 --- a/tests/benchmarks/app_kernel/src/config.h +++ b/tests/benchmarks/app_kernel/src/config.h @@ -12,28 +12,4 @@ /* Max size of a message string */ #define MAX_MSG 256 -/* flag for performing the Mailbox benchmark */ -#define MAILBOX_BENCH - -/* flag for performing the Sema benchmark */ -#define SEMA_BENCH - -/* flag for performing the FIFO benchmark */ -#define FIFO_BENCH - -/* flag for performing the Mutex benchmark */ -#define MUTEX_BENCH - -/* flag for performing the Memory Map benchmark */ -#define MEMMAP_BENCH - -/* flag for performing the Memory Pool benchmark*/ -#define MEMPOOL_BENCH - -/* flag for performing the Pipes benchmark */ -#define PIPE_BENCH - -/* flag for performing the Event benchmark */ -#define EVENT_BENCH - #endif /* _CONFIG_H */ diff --git a/tests/benchmarks/app_kernel/src/fifo_b.c b/tests/benchmarks/app_kernel/src/fifo_b.c index 650454a483e..0ff5faf60d8 100644 --- a/tests/benchmarks/app_kernel/src/fifo_b.c +++ b/tests/benchmarks/app_kernel/src/fifo_b.c @@ -8,12 +8,8 @@ #include "master.h" -#ifdef FIFO_BENCH - /** - * * @brief Queue transfer speed test - * */ void queue_test(void) { @@ -84,5 +80,3 @@ void queue_test(void) "enqueue 4 bytes in FIFO to a waiting higher priority task", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); } - -#endif /* FIFO_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/fifo_r.c b/tests/benchmarks/app_kernel/src/fifo_r.c index 1580ef114ca..42f17f1201c 100644 --- a/tests/benchmarks/app_kernel/src/fifo_r.c +++ b/tests/benchmarks/app_kernel/src/fifo_r.c @@ -9,13 +9,10 @@ #include "receiver.h" #include "master.h" -#ifdef FIFO_BENCH - /* queue transfer speed test */ + /** - * * @brief Data receive task - * */ void dequtask(void) { @@ -29,6 +26,3 @@ void dequtask(void) k_msgq_get(&DEMOQX4, &x, K_FOREVER); } } - - -#endif /* FIFO_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/mailbox_b.c b/tests/benchmarks/app_kernel/src/mailbox_b.c index 508cb10369a..c15f3e8a7b3 100644 --- a/tests/benchmarks/app_kernel/src/mailbox_b.c +++ b/tests/benchmarks/app_kernel/src/mailbox_b.c @@ -8,31 +8,8 @@ #include "master.h" -#ifdef MAILBOX_BENCH - static struct k_mbox_msg message; -#ifdef FLOAT -#define PRINT_HEADER() \ - (PRINT_STRING \ - ("| size(B) | time/packet (usec) | MB/sec" \ - " |\n")) -#define PRINT_ONE_RESULT() \ - PRINT_F("|%11u|%32.3f|%32f|\n", putsize, puttime / 1000.0, \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime)) - -#define PRINT_OVERHEAD() \ - PRINT_F("| message overhead: %10.3f usec/packet " \ - " |\n", empty_msg_put_time / 1000.0) - -#define PRINT_XFER_RATE() \ - double netto_transfer_rate; \ - netto_transfer_rate = 1000.0 * \ - (putsize >> 1) / SAFE_DIVISOR(puttime - empty_msg_put_time); \ - PRINT_F("| raw transfer rate: %10.3f MB/sec (without" \ - " overhead) |\n", netto_transfer_rate) - -#else #define PRINT_HEADER() \ (PRINT_STRING \ ("| size(B) | time/packet (nsec) | KB/sec" \ @@ -53,9 +30,6 @@ static struct k_mbox_msg message; (uint32_t)((uint64_t)(putsize >> 1) * 1000000U / \ SAFE_DIVISOR(puttime - empty_msg_put_time))) -#endif - - /* * Function prototypes. */ @@ -66,9 +40,7 @@ void mailbox_put(uint32_t size, int count, uint32_t *time); */ /** - * * @brief Mailbox transfer speed test - * */ void mailbox_test(void) { @@ -115,13 +87,11 @@ void mailbox_test(void) /** - * * @brief Write the number of data chunks into the mailbox * * @param size The size of the data chunk. * @param count Number of data chunks. * @param time The total time. - * */ void mailbox_put(uint32_t size, int count, uint32_t *time) { @@ -141,5 +111,3 @@ void mailbox_put(uint32_t size, int count, uint32_t *time) *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); check_result(); } - -#endif /* MAILBOX_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/mailbox_r.c b/tests/benchmarks/app_kernel/src/mailbox_r.c index f0b5e9f87bf..a0dabfa509a 100644 --- a/tests/benchmarks/app_kernel/src/mailbox_r.c +++ b/tests/benchmarks/app_kernel/src/mailbox_r.c @@ -9,8 +9,6 @@ #include "receiver.h" #include "master.h" -#ifdef MAILBOX_BENCH - /* * Function prototypes. */ @@ -26,9 +24,7 @@ void mailbox_get(struct k_mbox *mailbox, /* mailbox transfer speed test */ /** - * * @brief Receive task - * */ void mailrecvtask(void) { @@ -59,7 +55,6 @@ void mailrecvtask(void) /** - * * @brief Receive data portions from the specified mailbox * * @return 0 @@ -101,5 +96,3 @@ void mailbox_get(struct k_mbox *mailbox, k_panic(); } } - -#endif /* MAILBOX_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index 64109778149..8f4098ebde7 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -7,8 +7,8 @@ */ /* - *File Naming information. - * ------------------------ + * File Naming information. + * ------------------------ * Files that end with: * _B : Is a file that contains a benchmark function * _R : Is a file that contains the receiver task @@ -20,11 +20,8 @@ char msg[MAX_MSG]; char data_bench[MESSAGE_SIZE]; -#ifdef PIPE_BENCH struct k_pipe *test_pipes[] = {&PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF}; -#endif char sline[SLINE_LEN + 1]; -const char newline[] = "\n"; /* * Time in timer cycles necessary to read time. @@ -60,7 +57,6 @@ K_PIPE_DEFINE(PIPE_SMALLBUFF, 256, 4); K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4); /** - * * @brief Check for keypress * * @return 1 when a keyboard key is pressed, or 0 if no keyboard support @@ -71,7 +67,6 @@ int kbhit(void) } /** - * * @brief Close output for the test * */ @@ -84,7 +79,6 @@ void output_close(void) /** - * * @brief Perform all selected benchmarks * see config.h to select or to unselect * @@ -95,7 +89,7 @@ int main(void) bench_test_init(); - PRINT_STRING(newline); + PRINT_STRING("\n"); do { PRINT_STRING(dashline); PRINT_STRING("| S I M P L E S E R V I C E " @@ -121,13 +115,3 @@ int main(void) output_close(); return 0; } - - -/** - * - * @brief Dummy test - * - */ -void dummy_test(void) -{ -} diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index c0ff7709eb1..213e8a24c60 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -21,36 +21,25 @@ #include - -/* uncomment the define below to use floating point arithmetic */ -/* #define FLOAT */ - /* printf format defines. */ #define FORMAT "| %-65s|%10u|\n" /* length of the output line */ #define SLINE_LEN 256 -#define SLEEP_TIME ((CONFIG_SYS_CLOCK_TICKS_PER_SEC / 4) > 0 ? \ - CONFIG_SYS_CLOCK_TICKS_PER_SEC / 4 : 1) -#define WAIT_TIME ((CONFIG_SYS_CLOCK_TICKS_PER_SEC / 10) > 0 ? \ - CONFIG_SYS_CLOCK_TICKS_PER_SEC / 10 : 1) -#define NR_OF_NOP_RUNS 10000 #define NR_OF_FIFO_RUNS 500 #define NR_OF_SEMA_RUNS 500 #define NR_OF_MUTEX_RUNS 1000 -#define NR_OF_POOL_RUNS 1000 #define NR_OF_MAP_RUNS 1000 -#define NR_OF_EVENT_RUNS 1000 #define NR_OF_MBOX_RUNS 128 #define NR_OF_PIPE_RUNS 256 -/* #define SEMA_WAIT_TIME (5 * CONFIG_SYS_CLOCK_TICKS_PER_SEC) */ #define SEMA_WAIT_TIME (5000) + /* global data */ + extern char msg[MAX_MSG]; extern char data_bench[MESSAGE_SIZE]; extern struct k_pipe *test_pipes[]; -extern const char newline[]; extern char sline[]; #define dashline \ @@ -60,7 +49,7 @@ extern char sline[]; /* * To avoid divisions by 0 faults, wrap the divisor with this macro */ -#define SAFE_DIVISOR(a) (((a) != 0)?(a):1) +#define SAFE_DIVISOR(a) (((a) != 0) ? (a) : 1) /* pipe amount of content to receive (0+, 1+, all) */ @@ -70,56 +59,16 @@ enum pipe_options { _ALL_N = 0x2, }; -/* dummy_test is a function that is mapped when we */ -/* do not want to test a specific Benchmark */ -extern void dummy_test(void); - /* other external functions */ -extern void bench_task(void *p1, void *p2, void *p3); extern void recvtask(void *p1, void *p2, void *p3); -#ifdef MAILBOX_BENCH extern void mailbox_test(void); -#else -#define mailbox_test dummy_test -#endif - -#ifdef SEMA_BENCH extern void sema_test(void); -#else -#define sema_test dummy_test -#endif - -#ifdef FIFO_BENCH extern void queue_test(void); -#else -#define queue_test dummy_test -#endif - -#ifdef MUTEX_BENCH extern void mutex_test(void); -#else -#define mutex_test dummy_test -#endif - -#ifdef MEMMAP_BENCH extern void memorymap_test(void); -#else -#define memorymap_test dummy_test -#endif - -#ifdef MEMPOOL_BENCH -extern void mempool_test(void); -#else -#define mempool_test dummy_test -#endif - -#ifdef PIPE_BENCH extern void pipe_test(void); -#else -#define pipe_test dummy_test -#endif /* kernel objects needed for benchmarking */ extern struct k_mutex DEMO_MUTEX; @@ -138,7 +87,6 @@ extern struct k_msgq CH_COMM; extern struct k_mbox MAILB1; - extern struct k_pipe PIPE_NOBUFF; extern struct k_pipe PIPE_SMALLBUFF; extern struct k_pipe PIPE_BIGBUFF; @@ -146,8 +94,6 @@ extern struct k_pipe PIPE_BIGBUFF; extern struct k_mem_slab MAP1; - - /* PRINT_STRING * Macro to print an ASCII NULL terminated string. */ @@ -181,7 +127,6 @@ static inline void check_result(void) { if (bench_test_end() < 0) { PRINT_OVERFLOW_ERROR(); - return; /* error */ } } diff --git a/tests/benchmarks/app_kernel/src/memmap_b.c b/tests/benchmarks/app_kernel/src/memmap_b.c index a32385a7c68..9535e4ef8e8 100644 --- a/tests/benchmarks/app_kernel/src/memmap_b.c +++ b/tests/benchmarks/app_kernel/src/memmap_b.c @@ -9,13 +9,8 @@ #include "master.h" #include -#ifdef MEMMAP_BENCH - - /** - * * @brief Memory map get/free test - * */ void memorymap_test(void) { @@ -41,5 +36,3 @@ void memorymap_test(void) PRINT_F(FORMAT, "average alloc and dealloc memory page", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, (2 * NR_OF_MAP_RUNS))); } - -#endif /* MEMMAP_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/mutex_b.c b/tests/benchmarks/app_kernel/src/mutex_b.c index 9ad987dbd50..8a02b76bc42 100644 --- a/tests/benchmarks/app_kernel/src/mutex_b.c +++ b/tests/benchmarks/app_kernel/src/mutex_b.c @@ -8,12 +8,8 @@ #include "master.h" -#ifdef MUTEX_BENCH - /** - * * @brief Mutex lock/unlock test - * */ void mutex_test(void) { @@ -32,5 +28,3 @@ void mutex_test(void) PRINT_F(FORMAT, "average lock and unlock mutex", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, (2 * NR_OF_MUTEX_RUNS))); } - -#endif /* MUTEX_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/pipe_b.c b/tests/benchmarks/app_kernel/src/pipe_b.c index e0c8b9aa83f..117d9d4902b 100644 --- a/tests/benchmarks/app_kernel/src/pipe_b.c +++ b/tests/benchmarks/app_kernel/src/pipe_b.c @@ -8,40 +8,6 @@ #include "master.h" -#ifdef PIPE_BENCH - -#ifdef FLOAT -#define PRINT_ALL_TO_N_HEADER_UNIT() \ - PRINT_STRING("| size(B) | time/packet (usec) | " \ - " MB/sec |\n") - -#define PRINT_ALL_TO_N() \ - PRINT_F("|%5u|%5u|%10.3f|%10.3f|%10.3f|%10.3f|%10.3f|%10.3f|\n", \ - putsize, putsize, puttime[0] / 1000.0, puttime[1] / 1000.0, \ - puttime[2] / 1000.0, \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[0]), \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[1]), \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[2])) - -#define PRINT_1_TO_N_HEADER() \ - do { \ - PRINT_STRING("| size(B) | time/packet (usec) |" \ - " MB/sec |\n"); \ - PRINT_STRING(dashline); \ - } while (0) - -#define PRINT_1_TO_N() \ - PRINT_F("|%5u|%5d|%10.3f|%10.3f|%10.3f|%10.3f|%10.3f|%10.3f|\n", \ - putsize, \ - getsize, \ - puttime[0] / 1000.0, \ - puttime[1] / 1000.0, \ - puttime[2] / 1000.0, \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[0]), \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[1]), \ - (1000.0 * putsize) / SAFE_DIVISOR(puttime[2])) - -#else #define PRINT_ALL_TO_N_HEADER_UNIT() \ PRINT_STRING("| size(B) | time/packet (nsec) | " \ " KB/sec |\n") @@ -74,7 +40,6 @@ SAFE_DIVISOR(puttime[1])), \ (uint32_t)(((uint64_t)putsize * 1000000U) / \ SAFE_DIVISOR(puttime[2]))) -#endif /* FLOAT */ /* * Function prototypes. @@ -87,9 +52,7 @@ int pipeput(struct k_pipe *pipe, enum pipe_options */ /** - * * @brief Test the pipes transfer speed - * */ void pipe_test(void) { @@ -179,7 +142,6 @@ void pipe_test(void) /** - * * @brief Write a data portion to the pipe and measure time * * @return 0 on success, 1 on error @@ -245,5 +207,3 @@ int pipeput(struct k_pipe *pipe, } return 0; } - -#endif /* PIPE_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/pipe_r.c b/tests/benchmarks/app_kernel/src/pipe_r.c index bda40114efd..95238e01574 100644 --- a/tests/benchmarks/app_kernel/src/pipe_r.c +++ b/tests/benchmarks/app_kernel/src/pipe_r.c @@ -9,9 +9,6 @@ #include "receiver.h" #include "master.h" -#ifdef PIPE_BENCH - - /* * Function prototypes. */ @@ -25,9 +22,7 @@ int pipeget(struct k_pipe *pipe, enum pipe_options option, /* pipes transfer speed test */ /** - * * @brief Receive task - * */ void piperecvtask(void) { @@ -74,7 +69,6 @@ void piperecvtask(void) /** - * * @brief Read a data portion from the pipe and measure time * * @return 0 on success, 1 on error @@ -136,5 +130,3 @@ int pipeget(struct k_pipe *pipe, enum pipe_options option, int size, int count, } return 0; } - -#endif /* PIPE_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/receiver.c b/tests/benchmarks/app_kernel/src/receiver.c index cd8d8964a36..1a2737b4324 100644 --- a/tests/benchmarks/app_kernel/src/receiver.c +++ b/tests/benchmarks/app_kernel/src/receiver.c @@ -25,27 +25,21 @@ void mailrecvtask(void); void piperecvtask(void); /** - * * @brief Main function of the task that receives data in the test - * */ void recvtask(void *p1, void *p2, void *p3) { /* order must be compatible with master.c ! */ -#ifdef FIFO_BENCH + k_sem_take(&STARTRCV, K_FOREVER); dequtask(); -#endif -#ifdef SEMA_BENCH + k_sem_take(&STARTRCV, K_FOREVER); waittask(); -#endif -#ifdef MAILBOX_BENCH + k_sem_take(&STARTRCV, K_FOREVER); mailrecvtask(); -#endif -#ifdef PIPE_BENCH + k_sem_take(&STARTRCV, K_FOREVER); piperecvtask(); -#endif } diff --git a/tests/benchmarks/app_kernel/src/sema_b.c b/tests/benchmarks/app_kernel/src/sema_b.c index 2b3942a01ab..acda722856f 100644 --- a/tests/benchmarks/app_kernel/src/sema_b.c +++ b/tests/benchmarks/app_kernel/src/sema_b.c @@ -8,9 +8,6 @@ #include "master.h" -#ifdef SEMA_BENCH - - /** * * @brief Semaphore signal speed test @@ -56,5 +53,3 @@ void sema_test(void) SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); } - -#endif /* SEMA_BENCH */ diff --git a/tests/benchmarks/app_kernel/src/sema_r.c b/tests/benchmarks/app_kernel/src/sema_r.c index 21f16e0eed0..24b0745044e 100644 --- a/tests/benchmarks/app_kernel/src/sema_r.c +++ b/tests/benchmarks/app_kernel/src/sema_r.c @@ -9,8 +9,6 @@ #include "receiver.h" #include "master.h" -#ifdef SEMA_BENCH - /* semaphore signal speed test */ /** @@ -30,5 +28,3 @@ void waittask(void) } } - -#endif /* SEMA_BENCH */ From 8d663558d68bcf6441925e5011b49451ded06ece Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 18 Oct 2023 13:10:41 -0400 Subject: [PATCH 2839/4498] tests: app_kernel: Remove FP configurations As nothing in the app_kernel uses floating point, there is no reason to enable it. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/prj_fp.conf | 22 ------------ tests/benchmarks/app_kernel/testcase.yaml | 41 ----------------------- 2 files changed, 63 deletions(-) delete mode 100644 tests/benchmarks/app_kernel/prj_fp.conf diff --git a/tests/benchmarks/app_kernel/prj_fp.conf b/tests/benchmarks/app_kernel/prj_fp.conf deleted file mode 100644 index b8eeacab557..00000000000 --- a/tests/benchmarks/app_kernel/prj_fp.conf +++ /dev/null @@ -1,22 +0,0 @@ -CONFIG_TEST=y -# all printf, fprintf to stdout go to console -CONFIG_STDOUT_CONSOLE=y -CONFIG_MAIN_THREAD_PRIORITY=6 - -CONFIG_FPU=y -CONFIG_FPU_SHARING=y - -# eliminate timer interrupts during the benchmark -CONFIG_SYS_CLOCK_TICKS_PER_SEC=1 -CONFIG_TICKLESS_KERNEL=n - -CONFIG_FORCE_NO_ASSERT=y - -# Disable HW Stack Protection (see #28664) -CONFIG_TEST_HW_STACK_PROTECTION=n -CONFIG_HW_STACK_PROTECTION=n - -CONFIG_MP_MAX_NUM_CPUS=1 - -# Enable pipes -CONFIG_PIPES=y diff --git a/tests/benchmarks/app_kernel/testcase.yaml b/tests/benchmarks/app_kernel/testcase.yaml index 085ec0a32dc..b34c9af5347 100644 --- a/tests/benchmarks/app_kernel/testcase.yaml +++ b/tests/benchmarks/app_kernel/testcase.yaml @@ -9,44 +9,3 @@ tests: integration_platforms: - mps2_an385 - qemu_x86 - benchmark.kernel.application.fp: - extra_args: CONF_FILE=prj_fp.conf - extra_configs: - - arch:x86:CONFIG_X86_SSE=y - - arch:x86:CONFIG_X86_SSE_FP_MATH=n - arch_allow: - - x86 - - arm - filter: CONFIG_CPU_HAS_FPU or CONFIG_ARMV7_M_ARMV8_M_FP - min_flash: 34 - min_ram: 32 - slow: true - toolchain_exclude: - - llvm - - oneApi - integration_platforms: - - qemu_x86 - benchmark.kernel.application.fp.x86.no_sse: - extra_args: CONF_FILE=prj_fp.conf - extra_configs: - - CONFIG_X86_SSE=n - - CONFIG_X86_SSE_FP_MATH=n - arch_allow: x86 - filter: CONFIG_CPU_HAS_FPU - min_flash: 34 - min_ram: 32 - slow: true - integration_platforms: - - qemu_x86 - benchmark.kernel.application.fp.x86.sse: - extra_args: CONF_FILE=prj_fp.conf - extra_configs: - - CONFIG_X86_SSE=y - - CONFIG_X86_SSE_FP_MATH=y - arch_allow: x86 - filter: CONFIG_CPU_HAS_FPU - min_flash: 34 - min_ram: 32 - slow: true - integration_platforms: - - qemu_x86 From 77cedbf6305ed1bc3f723f9671c5d4ffde6fbea1 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 17 Oct 2023 17:54:50 -0400 Subject: [PATCH 2840/4498] tests: app_kernel: Simplify benchmark control loop Eliminates the loop surrounding the execution of the benchmark components as it was not doing anything. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/master.c | 63 ++++++------------------ 1 file changed, 16 insertions(+), 47 deletions(-) diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index 8f4098ebde7..d09d3528bb3 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -57,61 +57,30 @@ K_PIPE_DEFINE(PIPE_SMALLBUFF, 256, 4); K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4); /** - * @brief Check for keypress - * - * @return 1 when a keyboard key is pressed, or 0 if no keyboard support - */ -int kbhit(void) -{ - return 0; -} - -/** - * @brief Close output for the test - * - */ -void output_close(void) -{ -} - -/* no need to wait for user key press when using console */ -#define WAIT_FOR_USER() {} - - -/** - * @brief Perform all selected benchmarks - * see config.h to select or to unselect - * + * @brief Perform all benchmarks */ int main(void) { - int continuously = 0; - bench_test_init(); PRINT_STRING("\n"); - do { - PRINT_STRING(dashline); - PRINT_STRING("| S I M P L E S E R V I C E " - "M E A S U R E M E N T S | nsec |\n"); - PRINT_STRING(dashline); - queue_test(); - sema_test(); - mutex_test(); - memorymap_test(); - mailbox_test(); - pipe_test(); - PRINT_STRING("| END OF TESTS " - " |\n"); - PRINT_STRING(dashline); - PRINT_STRING("PROJECT EXECUTION SUCCESSFUL\n"); - TC_PRINT_RUNID; - } while (continuously && !kbhit()); - - WAIT_FOR_USER(); + PRINT_STRING(dashline); + PRINT_STRING("| S I M P L E S E R V I C E " + "M E A S U R E M E N T S | nsec |\n"); + PRINT_STRING(dashline); + queue_test(); + sema_test(); + mutex_test(); + memorymap_test(); + mailbox_test(); + pipe_test(); + PRINT_STRING("| END OF TESTS " + " |\n"); + PRINT_STRING(dashline); + PRINT_STRING("PROJECT EXECUTION SUCCESSFUL\n"); + TC_PRINT_RUNID; k_thread_abort(RECVTASK); - output_close(); return 0; } From 32341456696b90eeab3a55c409172e2b51c53343 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 18 Oct 2023 11:57:47 -0400 Subject: [PATCH 2841/4498] tests: app_kernel: Rename fifo to msgq Changed references of fifo to msgq as the fifo name was a remnant of the old microkernel. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/master.c | 2 +- tests/benchmarks/app_kernel/src/master.h | 4 +- .../app_kernel/src/{fifo_b.c => msgq_b.c} | 42 +++++++++---------- .../app_kernel/src/{fifo_r.c => msgq_r.c} | 8 ++-- 4 files changed, 28 insertions(+), 28 deletions(-) rename tests/benchmarks/app_kernel/src/{fifo_b.c => msgq_b.c} (50%) rename tests/benchmarks/app_kernel/src/{fifo_r.c => msgq_r.c} (69%) diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index d09d3528bb3..4344d3e5766 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -68,7 +68,7 @@ int main(void) PRINT_STRING("| S I M P L E S E R V I C E " "M E A S U R E M E N T S | nsec |\n"); PRINT_STRING(dashline); - queue_test(); + message_queue_test(); sema_test(); mutex_test(); memorymap_test(); diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index 213e8a24c60..cc007905230 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -27,7 +27,7 @@ /* length of the output line */ #define SLINE_LEN 256 -#define NR_OF_FIFO_RUNS 500 +#define NR_OF_MSGQ_RUNS 500 #define NR_OF_SEMA_RUNS 500 #define NR_OF_MUTEX_RUNS 1000 #define NR_OF_MAP_RUNS 1000 @@ -65,7 +65,7 @@ extern void recvtask(void *p1, void *p2, void *p3); extern void mailbox_test(void); extern void sema_test(void); -extern void queue_test(void); +extern void message_queue_test(void); extern void mutex_test(void); extern void memorymap_test(void); extern void pipe_test(void); diff --git a/tests/benchmarks/app_kernel/src/fifo_b.c b/tests/benchmarks/app_kernel/src/msgq_b.c similarity index 50% rename from tests/benchmarks/app_kernel/src/fifo_b.c rename to tests/benchmarks/app_kernel/src/msgq_b.c index 0ff5faf60d8..e79734242be 100644 --- a/tests/benchmarks/app_kernel/src/fifo_b.c +++ b/tests/benchmarks/app_kernel/src/msgq_b.c @@ -1,4 +1,4 @@ -/* fifo_b.c */ +/* msgq_b.c */ /* * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc. @@ -9,74 +9,74 @@ #include "master.h" /** - * @brief Queue transfer speed test + * @brief Message queue transfer speed test */ -void queue_test(void) +void message_queue_test(void) { uint32_t et; /* elapsed time */ int i; PRINT_STRING(dashline); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX1, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); - PRINT_F(FORMAT, "enqueue 1 byte msg in FIFO", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + PRINT_F(FORMAT, "enqueue 1 byte msg in MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX1, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); check_result(); - PRINT_F(FORMAT, "dequeue 1 byte msg in FIFO", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + PRINT_F(FORMAT, "dequeue 1 byte msg from MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX4, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); check_result(); - PRINT_F(FORMAT, "enqueue 4 bytes msg in FIFO", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + PRINT_F(FORMAT, "enqueue 4 bytes msg in MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX4, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); check_result(); - PRINT_F(FORMAT, "dequeue 4 bytes msg in FIFO", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + PRINT_F(FORMAT, "dequeue 4 bytes msg in MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); k_sem_give(&STARTRCV); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX1, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(FORMAT, - "enqueue 1 byte msg in FIFO to a waiting higher priority task", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + "enqueue 1 byte msg in MSGQ to a waiting higher priority task", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); et = BENCH_START(); - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX4, data_bench, K_FOREVER); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(FORMAT, - "enqueue 4 bytes in FIFO to a waiting higher priority task", - SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_FIFO_RUNS)); + "enqueue 4 bytes in MSGQ to a waiting higher priority task", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); } diff --git a/tests/benchmarks/app_kernel/src/fifo_r.c b/tests/benchmarks/app_kernel/src/msgq_r.c similarity index 69% rename from tests/benchmarks/app_kernel/src/fifo_r.c rename to tests/benchmarks/app_kernel/src/msgq_r.c index 42f17f1201c..91722ee364d 100644 --- a/tests/benchmarks/app_kernel/src/fifo_r.c +++ b/tests/benchmarks/app_kernel/src/msgq_r.c @@ -1,4 +1,4 @@ -/* fifo_r.c */ +/* msgq_r.c */ /* * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc. @@ -9,7 +9,7 @@ #include "receiver.h" #include "master.h" -/* queue transfer speed test */ +/* message queue transfer speed test */ /** * @brief Data receive task @@ -18,11 +18,11 @@ void dequtask(void) { int x, i; - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX1, &x, K_FOREVER); } - for (i = 0; i < NR_OF_FIFO_RUNS; i++) { + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX4, &x, K_FOREVER); } } From 5479090c91a76a2a47fb415d57d43b1561528042 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 18 Oct 2023 10:17:52 -0400 Subject: [PATCH 2842/4498] tests: app_kernel: Use dynamic threads Use dynamic threads instead of statically defined threads. This will make it easier to add support for user threads to this test. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/master.c | 55 ++++++++++++++++++++---- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index 4344d3e5766..d39152a8f60 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -17,6 +17,9 @@ #include #include "master.h" +#define RECV_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) +#define TEST_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) + char msg[MAX_MSG]; char data_bench[MESSAGE_SIZE]; @@ -32,7 +35,11 @@ uint32_t tm_off; /********************************************************************/ /* static allocation */ -K_THREAD_DEFINE(RECVTASK, 1024, recvtask, NULL, NULL, NULL, 5, 0, 0); + +static struct k_thread test_thread; +static struct k_thread recv_thread; +K_THREAD_STACK_DEFINE(test_stack, TEST_STACK_SIZE); +K_THREAD_STACK_DEFINE(recv_stack, RECV_STACK_SIZE); K_MSGQ_DEFINE(DEMOQX1, 1, 500, 4); K_MSGQ_DEFINE(DEMOQX4, 4, 500, 4); @@ -56,11 +63,32 @@ K_PIPE_DEFINE(PIPE_NOBUFF, 0, 4); K_PIPE_DEFINE(PIPE_SMALLBUFF, 256, 4); K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4); +/** + * @brief Entry point for test thread + */ +static void test_thread_entry(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + message_queue_test(); + sema_test(); + mutex_test(); + memorymap_test(); + mailbox_test(); + pipe_test(); +} + /** * @brief Perform all benchmarks */ int main(void) { + int priority; + + priority = k_thread_priority_get(k_current_get()); + bench_test_init(); PRINT_STRING("\n"); @@ -68,19 +96,28 @@ int main(void) PRINT_STRING("| S I M P L E S E R V I C E " "M E A S U R E M E N T S | nsec |\n"); PRINT_STRING(dashline); - message_queue_test(); - sema_test(); - mutex_test(); - memorymap_test(); - mailbox_test(); - pipe_test(); + + k_thread_create(&test_thread, test_stack, + K_THREAD_STACK_SIZEOF(test_stack), + test_thread_entry, NULL, NULL, NULL, + priority, 0, K_FOREVER); + + k_thread_create(&recv_thread, recv_stack, + K_THREAD_STACK_SIZEOF(recv_stack), + recvtask, NULL, NULL, NULL, + 5, 0, K_FOREVER); + + k_thread_start(&recv_thread); + k_thread_start(&test_thread); + + k_thread_join(&test_thread, K_FOREVER); + k_thread_abort(&recv_thread); + PRINT_STRING("| END OF TESTS " " |\n"); PRINT_STRING(dashline); PRINT_STRING("PROJECT EXECUTION SUCCESSFUL\n"); TC_PRINT_RUNID; - k_thread_abort(RECVTASK); - return 0; } From bf2ab9be60f4c42fd6d4b801ff5e186e71575f35 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 18 Oct 2023 09:49:20 -0400 Subject: [PATCH 2843/4498] tests: app_kernel: Add bench_mem_partition Adds macros for placing variables into bench_mem_partition. This partition will be used to place global data in the test that will need to be accessed from user threads. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/master.c | 20 +++++++++++++------- tests/benchmarks/app_kernel/src/master.h | 10 ++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index d39152a8f60..aacac292477 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -32,7 +32,6 @@ char sline[SLINE_LEN + 1]; */ uint32_t tm_off; - /********************************************************************/ /* static allocation */ @@ -41,6 +40,10 @@ static struct k_thread recv_thread; K_THREAD_STACK_DEFINE(test_stack, TEST_STACK_SIZE); K_THREAD_STACK_DEFINE(recv_stack, RECV_STACK_SIZE); +#ifdef CONFIG_USERSPACE +K_APPMEM_PARTITION_DEFINE(bench_mem_partition); +#endif + K_MSGQ_DEFINE(DEMOQX1, 1, 500, 4); K_MSGQ_DEFINE(DEMOQX4, 4, 500, 4); K_MSGQ_DEFINE(MB_COMM, 12, 1, 4); @@ -72,6 +75,15 @@ static void test_thread_entry(void *p1, void *p2, void *p3) ARG_UNUSED(p2); ARG_UNUSED(p3); + PRINT_STRING("\n"); + PRINT_STRING(dashline); + PRINT_STRING("| S I M P L E S E R V I C E " + "M E A S U R E M E N T S | nsec |\n"); +#ifdef CONFIG_USERSPACE + PRINT_STRING((const char *)arg1); +#endif + PRINT_STRING(dashline); + message_queue_test(); sema_test(); mutex_test(); @@ -91,12 +103,6 @@ int main(void) bench_test_init(); - PRINT_STRING("\n"); - PRINT_STRING(dashline); - PRINT_STRING("| S I M P L E S E R V I C E " - "M E A S U R E M E N T S | nsec |\n"); - PRINT_STRING(dashline); - k_thread_create(&test_thread, test_stack, K_THREAD_STACK_SIZEOF(test_stack), test_thread_entry, NULL, NULL, NULL, diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index cc007905230..ca741c6e9bc 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -21,6 +21,8 @@ #include +#include + /* printf format defines. */ #define FORMAT "| %-65s|%10u|\n" @@ -35,6 +37,14 @@ #define NR_OF_PIPE_RUNS 256 #define SEMA_WAIT_TIME (5000) +#ifdef CONFIG_USERSPACE +#define BENCH_BMEM K_APP_BMEM(bench_mem_partition) +#define BENCH_DMEM K_APP_DMEM(bench_mem_partition) +#else +#define BENCH_BMEM +#define BENCH_DMEM +#endif + /* global data */ extern char msg[MAX_MSG]; From f9cf48313b821555dac1b78c9e8d967b01635142 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 19 Oct 2023 15:53:53 -0400 Subject: [PATCH 2844/4498] tests: app_kernel: Add custom syscalls Adds two custom syscalls. The first allows a user thread to change its priority to a higher priority level. The second is used to obtain a timestamp from a user thread. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/prj.conf | 3 ++ tests/benchmarks/app_kernel/src/master.c | 51 ++++++++++++++++++++++++ tests/benchmarks/app_kernel/src/master.h | 6 +++ 3 files changed, 60 insertions(+) diff --git a/tests/benchmarks/app_kernel/prj.conf b/tests/benchmarks/app_kernel/prj.conf index 8390369dc1a..56fa539c609 100644 --- a/tests/benchmarks/app_kernel/prj.conf +++ b/tests/benchmarks/app_kernel/prj.conf @@ -19,3 +19,6 @@ CONFIG_MP_MAX_NUM_CPUS=1 # Enable pipes CONFIG_PIPES=y + +CONFIG_APPLICATION_DEFINED_SYSCALL=y +CONFIG_TIMING_FUNCTIONS=y diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index aacac292477..53b8915df67 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -66,6 +66,57 @@ K_PIPE_DEFINE(PIPE_NOBUFF, 0, 4); K_PIPE_DEFINE(PIPE_SMALLBUFF, 256, 4); K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4); +/* + * Custom syscalls + */ + +/** + * @brief Change a thread's priority + * + * Unlike the normal k_thread_priority_set(), this custom syscall allows + * a user thread to raise its priority. + */ +void z_impl_test_thread_priority_set(k_tid_t thread, int prio) +{ + extern void z_thread_priority_set(struct k_thread *thread, int prio); + + z_thread_priority_set((struct k_thread *)thread, prio); +} + + +#ifdef CONFIG_USERSPACE +static void z_vrfy_test_thread_priority_set(k_tid_t thread, int prio) +{ + z_impl_test_thread_priority_set(thread, prio); +} + +#include +#endif + +/** + * @brief Obtain a timestamp + * + * Architecture timestamp routines often require MMIO that is not mapped to + * the user threads. Use a custom system call to get the timestamp. + */ +timing_t z_impl_timing_timestamp_get(void) +{ + return timing_counter_get(); +} + +#ifdef CONFIG_USERSPACE +static timing_t z_vrfy_timing_timestamp_get(void) +{ + return z_impl_timing_timestamp_get(); +} + +#include +#endif + +/* + * Main test + */ + /** * @brief Entry point for test thread */ diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index ca741c6e9bc..5b95a949c3d 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -22,6 +22,7 @@ #include #include +#include /* printf format defines. */ #define FORMAT "| %-65s|%10u|\n" @@ -140,4 +141,9 @@ static inline void check_result(void) } } +__syscall void test_thread_priority_set(k_tid_t thread, int prio); +__syscall timing_t timing_timestamp_get(void); + +#include + #endif /* _MASTER_H */ From fa33147bf96d0a94189259606048cefcfc51f882 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 18 Oct 2023 13:23:59 -0400 Subject: [PATCH 2845/4498] tests: app_kernel: Add user support Add user thread support to message queue, semaphore, mutex and pipe tests. Mailbox and memory map tests are restricted from executing from user threads. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/prj.conf | 3 +- tests/benchmarks/app_kernel/prj_user.conf | 24 ++++ tests/benchmarks/app_kernel/src/mailbox_b.c | 8 +- tests/benchmarks/app_kernel/src/mailbox_r.c | 12 +- tests/benchmarks/app_kernel/src/master.c | 125 ++++++++++++++++++-- tests/benchmarks/app_kernel/src/master.h | 19 --- tests/benchmarks/app_kernel/src/memmap_b.c | 8 +- tests/benchmarks/app_kernel/src/msgq_b.c | 38 +++--- tests/benchmarks/app_kernel/src/mutex_b.c | 8 +- tests/benchmarks/app_kernel/src/pipe_b.c | 21 ++-- tests/benchmarks/app_kernel/src/pipe_r.c | 42 +++---- tests/benchmarks/app_kernel/src/receiver.c | 13 +- tests/benchmarks/app_kernel/src/sema_b.c | 23 ++-- tests/benchmarks/app_kernel/src/sema_r.c | 3 +- 14 files changed, 228 insertions(+), 119 deletions(-) create mode 100644 tests/benchmarks/app_kernel/prj_user.conf diff --git a/tests/benchmarks/app_kernel/prj.conf b/tests/benchmarks/app_kernel/prj.conf index 56fa539c609..a01e0835a81 100644 --- a/tests/benchmarks/app_kernel/prj.conf +++ b/tests/benchmarks/app_kernel/prj.conf @@ -3,8 +3,7 @@ CONFIG_TEST=y CONFIG_STDOUT_CONSOLE=y # eliminate timer interrupts during the benchmark -CONFIG_SYS_CLOCK_TICKS_PER_SEC=2 -CONFIG_TICKLESS_KERNEL=n +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1 CONFIG_MAIN_THREAD_PRIORITY=6 CONFIG_FORCE_NO_ASSERT=y diff --git a/tests/benchmarks/app_kernel/prj_user.conf b/tests/benchmarks/app_kernel/prj_user.conf new file mode 100644 index 00000000000..b0438e6b34c --- /dev/null +++ b/tests/benchmarks/app_kernel/prj_user.conf @@ -0,0 +1,24 @@ +CONFIG_TEST=y +# all printf, fprintf to stdout go to console +CONFIG_STDOUT_CONSOLE=y + +# eliminate timer interrupts during the benchmark +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1 + +CONFIG_MAIN_THREAD_PRIORITY=6 +CONFIG_FORCE_NO_ASSERT=y + +# Disable HW Stack Protection (see #28664) +CONFIG_TEST_HW_STACK_PROTECTION=n +CONFIG_HW_STACK_PROTECTION=n +CONFIG_CBPRINTF_FP_SUPPORT=y + +# Can only run under 1 CPU +CONFIG_MP_MAX_NUM_CPUS=1 + +# Enable pipes +CONFIG_PIPES=y + +CONFIG_APPLICATION_DEFINED_SYSCALL=y +CONFIG_TIMING_FUNCTIONS=y +CONFIG_USERSPACE=y diff --git a/tests/benchmarks/app_kernel/src/mailbox_b.c b/tests/benchmarks/app_kernel/src/mailbox_b.c index c15f3e8a7b3..d46b7675ef7 100644 --- a/tests/benchmarks/app_kernel/src/mailbox_b.c +++ b/tests/benchmarks/app_kernel/src/mailbox_b.c @@ -97,17 +97,19 @@ void mailbox_put(uint32_t size, int count, uint32_t *time) { int i; unsigned int t; + timing_t start; + timing_t end; message.rx_source_thread = K_ANY; message.tx_target_thread = K_ANY; /* first sync with the receiver */ k_sem_give(&SEM0); - t = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < count; i++) { k_mbox_put(&MAILB1, &message, K_FOREVER); } - t = TIME_STAMP_DELTA_GET(t); + end = timing_timestamp_get(); + t = (unsigned int)timing_cycles_get(&start, &end); *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); - check_result(); } diff --git a/tests/benchmarks/app_kernel/src/mailbox_r.c b/tests/benchmarks/app_kernel/src/mailbox_r.c index a0dabfa509a..b686da80f08 100644 --- a/tests/benchmarks/app_kernel/src/mailbox_r.c +++ b/tests/benchmarks/app_kernel/src/mailbox_r.c @@ -70,7 +70,8 @@ void mailbox_get(struct k_mbox *mailbox, unsigned int *time) { int i; - unsigned int t; + timing_t start; + timing_t end; int32_t return_value = 0; struct k_mbox_msg Message; @@ -79,19 +80,16 @@ void mailbox_get(struct k_mbox *mailbox, /* sync with the sender */ k_sem_take(&SEM0, K_FOREVER); - t = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < count; i++) { return_value |= k_mbox_get(mailbox, &Message, &data_recv, K_FOREVER); } + end = timing_timestamp_get(); + *time = timing_cycles_get(&start, &end); - t = TIME_STAMP_DELTA_GET(t); - *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); - if (bench_test_end() < 0) { - PRINT_OVERFLOW_ERROR(); - } if (return_value != 0) { k_panic(); } diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index 53b8915df67..c8110479f59 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -20,11 +20,11 @@ #define RECV_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) #define TEST_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) -char msg[MAX_MSG]; -char data_bench[MESSAGE_SIZE]; +BENCH_BMEM char msg[MAX_MSG]; +BENCH_BMEM char data_bench[MESSAGE_SIZE]; -struct k_pipe *test_pipes[] = {&PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF}; -char sline[SLINE_LEN + 1]; +BENCH_DMEM struct k_pipe *test_pipes[] = {&PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF}; +BENCH_BMEM char sline[SLINE_LEN + 1]; /* * Time in timer cycles necessary to read time. @@ -32,6 +32,13 @@ char sline[SLINE_LEN + 1]; */ uint32_t tm_off; +static BENCH_DMEM char *test_type_str[] = { + "| K E R N E L - - > K E R N E L | |\n", + "| K E R N E L - - > U S E R | |\n", + "| U S E R - - > K E R N E L | |\n", + "| U S E R - - > U S E R | |\n" +}; + /********************************************************************/ /* static allocation */ @@ -122,8 +129,8 @@ static timing_t z_vrfy_timing_timestamp_get(void) */ static void test_thread_entry(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); - ARG_UNUSED(p2); + bool skip_mem_and_mbox = (bool)(uintptr_t)(p2); + ARG_UNUSED(p3); PRINT_STRING("\n"); @@ -131,15 +138,19 @@ static void test_thread_entry(void *p1, void *p2, void *p3) PRINT_STRING("| S I M P L E S E R V I C E " "M E A S U R E M E N T S | nsec |\n"); #ifdef CONFIG_USERSPACE - PRINT_STRING((const char *)arg1); + PRINT_STRING((const char *)p1); #endif PRINT_STRING(dashline); message_queue_test(); sema_test(); mutex_test(); - memorymap_test(); - mailbox_test(); + + if (!skip_mem_and_mbox) { + memorymap_test(); + mailbox_test(); + } + pipe_test(); } @@ -152,16 +163,28 @@ int main(void) priority = k_thread_priority_get(k_current_get()); +#ifdef CONFIG_USERSPACE + k_mem_domain_add_partition(&k_mem_domain_default, + &bench_mem_partition); +#endif + bench_test_init(); + timing_init(); + + timing_start(); + + /* ********* All threads are kernel threads ********** */ + k_thread_create(&test_thread, test_stack, K_THREAD_STACK_SIZEOF(test_stack), - test_thread_entry, NULL, NULL, NULL, + test_thread_entry, + test_type_str[0], (void *)(uintptr_t)false, NULL, priority, 0, K_FOREVER); k_thread_create(&recv_thread, recv_stack, K_THREAD_STACK_SIZEOF(recv_stack), - recvtask, NULL, NULL, NULL, + recvtask, (void *)(uintptr_t)false, NULL, NULL, 5, 0, K_FOREVER); k_thread_start(&recv_thread); @@ -170,6 +193,86 @@ int main(void) k_thread_join(&test_thread, K_FOREVER); k_thread_abort(&recv_thread); +#ifdef CONFIG_USERSPACE + /* ****** Main thread is kernel, receiver is user thread ******* */ + + k_thread_create(&test_thread, test_stack, + K_THREAD_STACK_SIZEOF(test_stack), + test_thread_entry, + test_type_str[1], (void *)(uintptr_t)true, NULL, + priority, 0, K_FOREVER); + + k_thread_create(&recv_thread, recv_stack, + K_THREAD_STACK_SIZEOF(recv_stack), + recvtask, (void *)(uintptr_t)true, NULL, NULL, + 5, K_USER, K_FOREVER); + + k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, + &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, + &STARTRCV, &DEMO_MUTEX, + &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); + + k_thread_start(&recv_thread); + k_thread_start(&test_thread); + + k_thread_join(&test_thread, K_FOREVER); + k_thread_abort(&recv_thread); + + /* ****** Main thread is user, receiver is kernel thread ******* */ + + k_thread_create(&test_thread, test_stack, + K_THREAD_STACK_SIZEOF(test_stack), + test_thread_entry, + test_type_str[2], (void *)(uintptr_t)true, NULL, + priority, K_USER, K_FOREVER); + + k_thread_create(&recv_thread, recv_stack, + K_THREAD_STACK_SIZEOF(recv_stack), + recvtask, (void *)(uintptr_t)true, NULL, NULL, + 5, 0, K_FOREVER); + + k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, + &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, + &STARTRCV, &DEMO_MUTEX, + &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); + + k_thread_start(&recv_thread); + k_thread_start(&test_thread); + + k_thread_join(&test_thread, K_FOREVER); + k_thread_abort(&recv_thread); + + /* ********* All threads are user threads ********** */ + + k_thread_create(&test_thread, test_stack, + K_THREAD_STACK_SIZEOF(test_stack), + test_thread_entry, + test_type_str[3], (void *)(uintptr_t)true, NULL, + priority, K_USER, K_FOREVER); + + k_thread_create(&recv_thread, recv_stack, + K_THREAD_STACK_SIZEOF(recv_stack), + recvtask, (void *)(uintptr_t)true, NULL, NULL, + 5, K_USER, K_FOREVER); + + k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, + &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, + &STARTRCV, &DEMO_MUTEX, + &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); + k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, + &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, + &STARTRCV, &DEMO_MUTEX, + &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); + + k_thread_start(&recv_thread); + k_thread_start(&test_thread); + + k_thread_join(&test_thread, K_FOREVER); + k_thread_abort(&recv_thread); +#endif /* CONFIG_USERSPACE */ + + timing_stop(); + PRINT_STRING("| END OF TESTS " " |\n"); PRINT_STRING(dashline); diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index 5b95a949c3d..18b1e9f63ed 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -122,25 +122,6 @@ extern struct k_mem_slab MAP1; PRINT_STRING(sline); \ } -#define PRINT_OVERFLOW_ERROR() \ - PRINT_F(__FILE__":%d Error: tick occurred\n", __LINE__) - -static inline uint32_t BENCH_START(void) -{ - uint32_t et; - - bench_test_start(); - et = TIME_STAMP_DELTA_GET(0); - return et; -} - -static inline void check_result(void) -{ - if (bench_test_end() < 0) { - PRINT_OVERFLOW_ERROR(); - } -} - __syscall void test_thread_priority_set(k_tid_t thread, int prio); __syscall timing_t timing_timestamp_get(void); diff --git a/tests/benchmarks/app_kernel/src/memmap_b.c b/tests/benchmarks/app_kernel/src/memmap_b.c index 9535e4ef8e8..a6451b4f930 100644 --- a/tests/benchmarks/app_kernel/src/memmap_b.c +++ b/tests/benchmarks/app_kernel/src/memmap_b.c @@ -15,12 +15,14 @@ void memorymap_test(void) { uint32_t et; /* elapsed time */ + timing_t start; + timing_t end; int i; void *p; int alloc_status; PRINT_STRING(dashline); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MAP_RUNS; i++) { alloc_status = k_mem_slab_alloc(&MAP1, &p, K_FOREVER); if (alloc_status != 0) { @@ -30,8 +32,8 @@ void memorymap_test(void) } k_mem_slab_free(&MAP1, p); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "average alloc and dealloc memory page", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, (2 * NR_OF_MAP_RUNS))); diff --git a/tests/benchmarks/app_kernel/src/msgq_b.c b/tests/benchmarks/app_kernel/src/msgq_b.c index e79734242be..09bde6a4dc9 100644 --- a/tests/benchmarks/app_kernel/src/msgq_b.c +++ b/tests/benchmarks/app_kernel/src/msgq_b.c @@ -15,66 +15,68 @@ void message_queue_test(void) { uint32_t et; /* elapsed time */ int i; + timing_t start; + timing_t end; PRINT_STRING(dashline); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX1, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "enqueue 1 byte msg in MSGQ", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX1, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "dequeue 1 byte msg from MSGQ", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX4, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "enqueue 4 bytes msg in MSGQ", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_get(&DEMOQX4, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "dequeue 4 bytes msg in MSGQ", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); k_sem_give(&STARTRCV); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX1, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "enqueue 1 byte msg in MSGQ to a waiting higher priority task", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { k_msgq_put(&DEMOQX4, data_bench, K_FOREVER); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "enqueue 4 bytes in MSGQ to a waiting higher priority task", diff --git a/tests/benchmarks/app_kernel/src/mutex_b.c b/tests/benchmarks/app_kernel/src/mutex_b.c index 8a02b76bc42..ce93acea121 100644 --- a/tests/benchmarks/app_kernel/src/mutex_b.c +++ b/tests/benchmarks/app_kernel/src/mutex_b.c @@ -15,15 +15,17 @@ void mutex_test(void) { uint32_t et; /* elapsed time */ int i; + timing_t start; + timing_t end; PRINT_STRING(dashline); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_MUTEX_RUNS; i++) { k_mutex_lock(&DEMO_MUTEX, K_FOREVER); k_mutex_unlock(&DEMO_MUTEX); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "average lock and unlock mutex", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, (2 * NR_OF_MUTEX_RUNS))); diff --git a/tests/benchmarks/app_kernel/src/pipe_b.c b/tests/benchmarks/app_kernel/src/pipe_b.c index 117d9d4902b..921f217b638 100644 --- a/tests/benchmarks/app_kernel/src/pipe_b.c +++ b/tests/benchmarks/app_kernel/src/pipe_b.c @@ -115,7 +115,7 @@ void pipe_test(void) PRINT_STRING("| " "non-matching sizes (1_TO_N) to lower priority" " |\n"); - k_thread_priority_set(k_current_get(), TaskPrio - 2); + test_thread_priority_set(k_current_get(), TaskPrio - 2); } PRINT_STRING(dashline); PRINT_1_TO_N_HEADER(); @@ -136,7 +136,7 @@ void pipe_test(void) PRINT_1_TO_N(); } PRINT_STRING(dashline); - k_thread_priority_set(k_current_get(), TaskPrio); + test_thread_priority_set(k_current_get(), TaskPrio); } } @@ -160,12 +160,14 @@ int pipeput(struct k_pipe *pipe, { int i; unsigned int t; + timing_t start; + timing_t end; size_t sizexferd_total = 0; size_t size2xfer_total = size * count; /* first sync with the receiver */ k_sem_give(&SEM0); - t = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; option == _1_TO_N || (i < count); i++) { size_t sizexferd = 0; size_t size2xfer = MIN(size, size2xfer_total - sizexferd_total); @@ -195,15 +197,10 @@ int pipeput(struct k_pipe *pipe, } } - t = TIME_STAMP_DELTA_GET(t); + end = timing_timestamp_get(); + t = (unsigned int)timing_cycles_get(&start, &end); + *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); - if (bench_test_end() < 0) { - if (high_timer_overflow()) { - PRINT_STRING("| Timer overflow. Results are invalid "); - } else { - PRINT_STRING("| Tick occurred. Results may be inaccurate "); - } - PRINT_STRING(" |\n"); - } + return 0; } diff --git a/tests/benchmarks/app_kernel/src/pipe_r.c b/tests/benchmarks/app_kernel/src/pipe_r.c index 95238e01574..653e66491fa 100644 --- a/tests/benchmarks/app_kernel/src/pipe_r.c +++ b/tests/benchmarks/app_kernel/src/pipe_r.c @@ -50,20 +50,20 @@ void piperecvtask(void) for (prio = 0; prio < 2; prio++) { /* non-matching (1_TO_N) */ - for (getsize = (MESSAGE_SIZE_PIPE); getsize >= 8; getsize >>= 1) { - getcount = MESSAGE_SIZE_PIPE / getsize; - for (pipe = 0; pipe < 3; pipe++) { - /* size*count == MESSAGE_SIZE_PIPE */ - pipeget(test_pipes[pipe], _1_TO_N, - getsize, getcount, &gettime); - getinfo.time = gettime; - getinfo.size = getsize; - getinfo.count = getcount; - /* acknowledge to master */ - k_msgq_put(&CH_COMM, &getinfo, K_FOREVER); + for (getsize = (MESSAGE_SIZE_PIPE); getsize >= 8; getsize >>= 1) { + getcount = MESSAGE_SIZE_PIPE / getsize; + for (pipe = 0; pipe < 3; pipe++) { + /* size*count == MESSAGE_SIZE_PIPE */ + pipeget(test_pipes[pipe], _1_TO_N, + getsize, getcount, &gettime); + getinfo.time = gettime; + getinfo.size = getsize; + getinfo.count = getcount; + /* acknowledge to master */ + k_msgq_put(&CH_COMM, &getinfo, K_FOREVER); + } } } - } } @@ -84,12 +84,14 @@ int pipeget(struct k_pipe *pipe, enum pipe_options option, int size, int count, { int i; unsigned int t; + timing_t start; + timing_t end; size_t sizexferd_total = 0; size_t size2xfer_total = size * count; /* sync with the sender */ k_sem_take(&SEM0, K_FOREVER); - t = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; option == _1_TO_N || (i < count); i++) { size_t sizexferd = 0; size_t size2xfer = MIN(size, size2xfer_total - sizexferd_total); @@ -116,17 +118,9 @@ int pipeget(struct k_pipe *pipe, enum pipe_options option, int size, int count, } } - t = TIME_STAMP_DELTA_GET(t); + end = timing_timestamp_get(); + t = (unsigned int) timing_cycles_get(&start, &end); *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); - if (bench_test_end() < 0) { - if (high_timer_overflow()) { - PRINT_STRING("| Timer overflow. " - "Results are invalid "); - } else { - PRINT_STRING("| Tick occurred. " - "Results may be inaccurate "); - } - PRINT_STRING(" |\n"); - } + return 0; } diff --git a/tests/benchmarks/app_kernel/src/receiver.c b/tests/benchmarks/app_kernel/src/receiver.c index 1a2737b4324..5d5f74f45da 100644 --- a/tests/benchmarks/app_kernel/src/receiver.c +++ b/tests/benchmarks/app_kernel/src/receiver.c @@ -17,7 +17,7 @@ #include "receiver.h" -char data_recv[MESSAGE_SIZE] = { 0 }; +BENCH_DMEM char data_recv[MESSAGE_SIZE] = { 0 }; void dequtask(void); void waittask(void); @@ -29,6 +29,11 @@ void piperecvtask(void); */ void recvtask(void *p1, void *p2, void *p3) { + bool skip_mbox = (bool)(uintptr_t)(p1); + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + /* order must be compatible with master.c ! */ k_sem_take(&STARTRCV, K_FOREVER); @@ -37,8 +42,10 @@ void recvtask(void *p1, void *p2, void *p3) k_sem_take(&STARTRCV, K_FOREVER); waittask(); - k_sem_take(&STARTRCV, K_FOREVER); - mailrecvtask(); + if (!skip_mbox) { + k_sem_take(&STARTRCV, K_FOREVER); + mailrecvtask(); + } k_sem_take(&STARTRCV, K_FOREVER); piperecvtask(); diff --git a/tests/benchmarks/app_kernel/src/sema_b.c b/tests/benchmarks/app_kernel/src/sema_b.c index acda722856f..36c2451978f 100644 --- a/tests/benchmarks/app_kernel/src/sema_b.c +++ b/tests/benchmarks/app_kernel/src/sema_b.c @@ -9,22 +9,22 @@ #include "master.h" /** - * * @brief Semaphore signal speed test - * */ void sema_test(void) { uint32_t et; /* elapsed Time */ int i; + timing_t start; + timing_t end; PRINT_STRING(dashline); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { k_sem_give(&SEM0); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "signal semaphore", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); @@ -32,24 +32,23 @@ void sema_test(void) k_sem_reset(&SEM1); k_sem_give(&STARTRCV); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { k_sem_give(&SEM1); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "signal to waiting high pri task", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); - et = BENCH_START(); + start = timing_timestamp_get(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { k_sem_give(&SEM1); } - et = TIME_STAMP_DELTA_GET(et); - check_result(); + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); PRINT_F(FORMAT, "signal to waiting high pri task, with timeout", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); - } diff --git a/tests/benchmarks/app_kernel/src/sema_r.c b/tests/benchmarks/app_kernel/src/sema_r.c index 24b0745044e..df968b5a14c 100644 --- a/tests/benchmarks/app_kernel/src/sema_r.c +++ b/tests/benchmarks/app_kernel/src/sema_r.c @@ -12,9 +12,7 @@ /* semaphore signal speed test */ /** - * * @brief Receive task (Wait task) - * */ void waittask(void) { @@ -23,6 +21,7 @@ void waittask(void) for (i = 0; i < NR_OF_SEMA_RUNS; i++) { k_sem_take(&SEM1, K_FOREVER); } + for (i = 0; i < NR_OF_SEMA_RUNS; i++) { k_sem_take(&SEM1, K_MSEC(SEMA_WAIT_TIME)); } From 4e426fbfa15fee650df2473671ae5dcb18c2e6cf Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 20 Oct 2023 11:23:09 -0400 Subject: [PATCH 2846/4498] tests: app_kernel: extend msgq test Extends the msgq benchmark test to obtain data for larger message queues (messages of size 192 bytes). This allows for a better indication of what the impact of data size is on message queue performance. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/src/master.c | 25 ++++++++++--------- tests/benchmarks/app_kernel/src/master.h | 1 + tests/benchmarks/app_kernel/src/msgq_b.c | 31 ++++++++++++++++++++++++ tests/benchmarks/app_kernel/src/msgq_r.c | 12 ++++++--- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/tests/benchmarks/app_kernel/src/master.c b/tests/benchmarks/app_kernel/src/master.c index c8110479f59..0b5c8976910 100644 --- a/tests/benchmarks/app_kernel/src/master.c +++ b/tests/benchmarks/app_kernel/src/master.c @@ -53,6 +53,7 @@ K_APPMEM_PARTITION_DEFINE(bench_mem_partition); K_MSGQ_DEFINE(DEMOQX1, 1, 500, 4); K_MSGQ_DEFINE(DEMOQX4, 4, 500, 4); +K_MSGQ_DEFINE(DEMOQX192, 192, 500, 4); K_MSGQ_DEFINE(MB_COMM, 12, 1, 4); K_MSGQ_DEFINE(CH_COMM, 12, 1, 4); @@ -207,9 +208,9 @@ int main(void) recvtask, (void *)(uintptr_t)true, NULL, NULL, 5, K_USER, K_FOREVER); - k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, - &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, - &STARTRCV, &DEMO_MUTEX, + k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192, + &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, + &SEM4, &STARTRCV, &DEMO_MUTEX, &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); k_thread_start(&recv_thread); @@ -231,9 +232,9 @@ int main(void) recvtask, (void *)(uintptr_t)true, NULL, NULL, 5, 0, K_FOREVER); - k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, - &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, - &STARTRCV, &DEMO_MUTEX, + k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192, + &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, + &SEM4, &STARTRCV, &DEMO_MUTEX, &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); k_thread_start(&recv_thread); @@ -255,13 +256,13 @@ int main(void) recvtask, (void *)(uintptr_t)true, NULL, NULL, 5, K_USER, K_FOREVER); - k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, - &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, - &STARTRCV, &DEMO_MUTEX, + k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192, + &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, + &SEM4, &STARTRCV, &DEMO_MUTEX, &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); - k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &MB_COMM, - &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, &SEM4, - &STARTRCV, &DEMO_MUTEX, + k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192, + &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3, + &SEM4, &STARTRCV, &DEMO_MUTEX, &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF); k_thread_start(&recv_thread); diff --git a/tests/benchmarks/app_kernel/src/master.h b/tests/benchmarks/app_kernel/src/master.h index 18b1e9f63ed..9f9c902afa9 100644 --- a/tests/benchmarks/app_kernel/src/master.h +++ b/tests/benchmarks/app_kernel/src/master.h @@ -93,6 +93,7 @@ extern struct k_sem STARTRCV; extern struct k_msgq DEMOQX1; extern struct k_msgq DEMOQX4; +extern struct k_msgq DEMOQX192; extern struct k_msgq MB_COMM; extern struct k_msgq CH_COMM; diff --git a/tests/benchmarks/app_kernel/src/msgq_b.c b/tests/benchmarks/app_kernel/src/msgq_b.c index 09bde6a4dc9..a542fdf7355 100644 --- a/tests/benchmarks/app_kernel/src/msgq_b.c +++ b/tests/benchmarks/app_kernel/src/msgq_b.c @@ -58,6 +58,26 @@ void message_queue_test(void) PRINT_F(FORMAT, "dequeue 4 bytes msg in MSGQ", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); + start = timing_timestamp_get(); + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { + k_msgq_put(&DEMOQX192, data_bench, K_FOREVER); + } + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); + + PRINT_F(FORMAT, "enqueue 192 bytes msg in MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); + + start = timing_timestamp_get(); + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { + k_msgq_get(&DEMOQX192, data_bench, K_FOREVER); + } + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); + + PRINT_F(FORMAT, "dequeue 192 bytes msg in MSGQ", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); + k_sem_give(&STARTRCV); start = timing_timestamp_get(); @@ -81,4 +101,15 @@ void message_queue_test(void) PRINT_F(FORMAT, "enqueue 4 bytes in MSGQ to a waiting higher priority task", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); + + start = timing_timestamp_get(); + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { + k_msgq_put(&DEMOQX192, data_bench, K_FOREVER); + } + end = timing_timestamp_get(); + et = (uint32_t)timing_cycles_get(&start, &end); + + PRINT_F(FORMAT, + "enqueue 192 bytes in MSGQ to a waiting higher priority task", + SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_MSGQ_RUNS)); } diff --git a/tests/benchmarks/app_kernel/src/msgq_r.c b/tests/benchmarks/app_kernel/src/msgq_r.c index 91722ee364d..dcef1be80ff 100644 --- a/tests/benchmarks/app_kernel/src/msgq_r.c +++ b/tests/benchmarks/app_kernel/src/msgq_r.c @@ -11,18 +11,24 @@ /* message queue transfer speed test */ +static BENCH_BMEM char buffer[192]; + /** * @brief Data receive task */ void dequtask(void) { - int x, i; + int i; + + for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { + k_msgq_get(&DEMOQX1, buffer, K_FOREVER); + } for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { - k_msgq_get(&DEMOQX1, &x, K_FOREVER); + k_msgq_get(&DEMOQX4, buffer, K_FOREVER); } for (i = 0; i < NR_OF_MSGQ_RUNS; i++) { - k_msgq_get(&DEMOQX4, &x, K_FOREVER); + k_msgq_get(&DEMOQX192, buffer, K_FOREVER); } } From 1bc0b1bc4614c364da06f5960f181304f7955439 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 20 Oct 2023 18:43:48 -0400 Subject: [PATCH 2847/4498] tests: app_kernel: Add user case to testcase.yaml Updates the testcase.yaml to support a version that employs user threads. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/testcase.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/app_kernel/testcase.yaml b/tests/benchmarks/app_kernel/testcase.yaml index b34c9af5347..19aeb6fbe52 100644 --- a/tests/benchmarks/app_kernel/testcase.yaml +++ b/tests/benchmarks/app_kernel/testcase.yaml @@ -3,9 +3,16 @@ common: - benchmark - kernel timeout: 420 + min_flash: 34 + min_ram: 128 tests: benchmark.kernel.application: - min_flash: 34 integration_platforms: - mps2_an385 - qemu_x86 + benchmark.kernel.application.user: + extra_args: CONF_FILE=prj_user.conf + filter: CONFIG_ARCH_HAS_USERSPACE + integration_platforms: + - qemu_x86 + - qemu_cortex_a53 From 7e8243b6af4d540abf2bd8bab4971749d72a9881 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 20 Oct 2023 19:03:15 -0400 Subject: [PATCH 2848/4498] tests: app_kernel: Update README Updates the README.txt to add some notes about user thread configurations. Signed-off-by: Peter Mitsis --- tests/benchmarks/app_kernel/README.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/app_kernel/README.txt b/tests/benchmarks/app_kernel/README.txt index e4057c87de6..29fefad2992 100644 --- a/tests/benchmarks/app_kernel/README.txt +++ b/tests/benchmarks/app_kernel/README.txt @@ -5,6 +5,11 @@ Description: The app_kernel test is used to measure the performance of the following kernel objects: message queues, semaphores, memory slabs, mailboxes and pipes. +When the userspace version is selected (CONF_FILE=prj_user.conf), this +benchmark will execute with four configurations (kernel/kernel, kernel/user, +user/kernel and user/user). However, any configuration involving user threads +will omit both the memory slabs and mailbox tests. + -------------------------------------------------------------------------------- Sample Output: @@ -17,8 +22,11 @@ Sample Output: | dequeue 1 byte msg in FIFO | NNNNNN| | enqueue 4 bytes msg in FIFO | NNNNNN| | dequeue 4 bytes msg in FIFO | NNNNNN| -| enqueue 1 byte msg in FIFO to a waiting higher priority task | NNNNNN| -| enqueue 4 bytes in FIFO to a waiting higher priority task | NNNNNN| +| enqueue 192 bytes msg in MSGQ | NNNNNN| +| dequeue 192 bytes msg in MSGQ | NNNNNN| +| enqueue 1 byte msg in MSGQ to a waiting higher priority task | NNNNNN| +| enqueue 4 bytes in MSGQ to a waiting higher priority task | NNNNNN| +| enqueue 192 bytes in MSGQ to a waiting higher priority task | NNNNNN| |-----------------------------------------------------------------------------| | signal semaphore | NNNNNN| | signal to waiting high pri task | NNNNNN| From 32d7b3645a0265c3b3c74900ca6ae3172cc420d0 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 15:52:50 -0700 Subject: [PATCH 2849/4498] toolchain: Add nonnull attribute Add a new macro for __attribute__((nonnull))). This attribute allows functions to declare which parameters shouldn't be null. This helps to catch errors like: void test(void *a, void *b, void *c) __attribute_nonnull(1, 3); /zephyrproject/zephyr/samples/hello_world/src/main.c:28:9: warning: argument 3 null where non-null expected [-Wnonnull] 28 | test(a, NULL, NULL); | ^~~~ Signed-off-by: Flavio Ceolin --- doc/zephyr.doxyfile.in | 1 + include/zephyr/toolchain/gcc.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 84f31433208..1f8a6af46c4 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -2397,6 +2397,7 @@ PREDEFINED = __DOXYGEN__ \ __deprecated= \ __packed= \ __aligned(x)= \ + __attribute_nonnull(...)= \ "__printf_like(x, y)=" \ __attribute__(x)= \ __syscall= \ diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index a15e8c0a580..d3dce3b253f 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -274,6 +274,10 @@ do { \ #define __weak __attribute__((__weak__)) #endif +#ifndef __attribute_nonnull +#define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) +#endif + /* Builtins with availability that depend on the compiler version. */ #if __GNUC__ >= 5 #define HAS_BUILTIN___builtin_add_overflow 1 From ade41376a51d572e02cbdd4b67a625b704dcabcb Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 15:57:21 -0700 Subject: [PATCH 2850/4498] kernel: heap in k_heap_free is nonnull Mark the parameter h as nonnull in k_heap_free. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index b1b643df4a2..fb5389ef206 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5377,7 +5377,7 @@ void *k_heap_alloc(struct k_heap *h, size_t bytes, * @param h Heap to which to return the memory * @param mem A valid memory block, or NULL */ -void k_heap_free(struct k_heap *h, void *mem); +void k_heap_free(struct k_heap *h, void *mem) __attribute_nonnull(1); /* Hand-calculated minimum heap sizes needed to return a successful * 1-byte allocation. See details in lib/os/heap.[ch] From d8ef78d7af2bb61a86823c1c174500f8935783de Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 16:00:52 -0700 Subject: [PATCH 2851/4498] kernel: heap in k_heap_aligned_alloc is nonnull Mark the parameter h as nonnull in k_heap_aligned_alloc. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index fb5389ef206..7325faee316 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5341,7 +5341,7 @@ void k_heap_init(struct k_heap *h, void *mem, size_t bytes); * @return Pointer to memory the caller can now use */ void *k_heap_aligned_alloc(struct k_heap *h, size_t align, size_t bytes, - k_timeout_t timeout); + k_timeout_t timeout) __attribute_nonnull(1); /** * @brief Allocate memory from a k_heap From 1701eea20f90064cb4a8a5a860159c2074f0a65e Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 16:11:32 -0700 Subject: [PATCH 2852/4498] kernel: heap in k_heap_alloc is nonnull Mark the parameter h as nonnull in k_heap_alloc. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 7325faee316..4935ca6333e 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5365,7 +5365,7 @@ void *k_heap_aligned_alloc(struct k_heap *h, size_t align, size_t bytes, * @return A pointer to valid heap memory, or NULL */ void *k_heap_alloc(struct k_heap *h, size_t bytes, - k_timeout_t timeout); + k_timeout_t timeout) __attribute_nonnull(1); /** * @brief Free memory allocated by k_heap_alloc() From 3d9b6bb9b2da3562309d0ee35b943f78bd3fb4b3 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 25 Oct 2023 16:12:12 -0700 Subject: [PATCH 2853/4498] kernel: heap in k_heap_init is nonnull Mark the parameter h as nonnull in k_heap_init. Signed-off-by: Flavio Ceolin --- include/zephyr/kernel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 4935ca6333e..a62e55f72c3 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5319,7 +5319,8 @@ struct k_heap { * @param mem Pointer to memory. * @param bytes Size of memory region, in bytes */ -void k_heap_init(struct k_heap *h, void *mem, size_t bytes); +void k_heap_init(struct k_heap *h, void *mem, + size_t bytes) __attribute_nonnull(1); /** @brief Allocate aligned memory from a k_heap * From c79c0d7cf2c49c7d5a9445d65ac8090affcf25d4 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 2 Oct 2023 16:22:52 +0200 Subject: [PATCH 2854/4498] drivers: i2c: stm32 driver has get_config api Add the get_config API to the stm32 I2C driver. It will return the value of the Clock Control register for i2C V1 bus or the TIMING register for the I2C V2 bus. This is hold by a i2c_config_timing structure of the device data Add a bool to check if the I2C is configured or not. Signed-off-by: Francois Ramu --- drivers/i2c/i2c_ll_stm32.c | 27 +++++++++++++++++++++++---- drivers/i2c/i2c_ll_stm32.h | 2 ++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 791c84fcb9e..2fcb1f8e931 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -44,25 +44,39 @@ LOG_MODULE_REGISTER(i2c_ll_stm32); #define STM32_I2C_DOMAIN_CLOCK_SUPPORT 0 #endif +int i2c_stm32_get_config(const struct device *dev, uint32_t *config) +{ + struct i2c_stm32_data *data = dev->data; + + if (!data->is_configured) { + LOG_ERR("I2C controller not configured"); + return -EIO; + } + + *config = data->dev_config; + + return 0; +} + int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) { const struct i2c_stm32_config *cfg = dev->config; struct i2c_stm32_data *data = dev->data; I2C_TypeDef *i2c = cfg->i2c; - uint32_t clock = 0U; + uint32_t i2c_clock = 0U; int ret; if (IS_ENABLED(STM32_I2C_DOMAIN_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken[1], - &clock) < 0) { + &i2c_clock) < 0) { LOG_ERR("Failed call clock_control_get_rate(pclken[1])"); return -EIO; } } else { if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t) &cfg->pclken[0], - &clock) < 0) { + &i2c_clock) < 0) { LOG_ERR("Failed call clock_control_get_rate(pclken[0])"); return -EIO; } @@ -82,7 +96,7 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) LL_I2C_Disable(i2c); LL_I2C_SetMode(i2c, LL_I2C_MODE_I2C); - ret = stm32_i2c_configure_timing(dev, clock); + ret = stm32_i2c_configure_timing(dev, i2c_clock); #ifdef CONFIG_PM_DEVICE_RUNTIME ret = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken[0]); @@ -276,6 +290,7 @@ static int i2c_stm32_recover_bus(const struct device *dev) static const struct i2c_driver_api api_funcs = { .configure = i2c_stm32_runtime_configure, .transfer = i2c_stm32_transfer, + .get_config = i2c_stm32_get_config, #if CONFIG_I2C_STM32_BUS_RECOVERY .recover_bus = i2c_stm32_recover_bus, #endif /* CONFIG_I2C_STM32_BUS_RECOVERY */ @@ -350,6 +365,8 @@ static int i2c_stm32_init(const struct device *dev) cfg->irq_config_func(dev); #endif + data->is_configured = false; + /* * initialize mutex used when multiple transfers * are taking place to guarantee that each one is @@ -398,6 +415,8 @@ static int i2c_stm32_init(const struct device *dev) (void)pm_device_runtime_enable(dev); #endif + data->is_configured = true; + return 0; } diff --git a/drivers/i2c/i2c_ll_stm32.h b/drivers/i2c/i2c_ll_stm32.h index 1db22236043..c77b687038d 100644 --- a/drivers/i2c/i2c_ll_stm32.h +++ b/drivers/i2c/i2c_ll_stm32.h @@ -78,6 +78,7 @@ struct i2c_stm32_data { #endif bool slave_attached; #endif + bool is_configured; }; int32_t stm32_i2c_transaction(const struct device *dev, @@ -85,6 +86,7 @@ int32_t stm32_i2c_transaction(const struct device *dev, uint16_t periph); int32_t stm32_i2c_configure_timing(const struct device *dev, uint32_t clk); int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config); +int i2c_stm32_get_config(const struct device *dev, uint32_t *config); void stm32_i2c_event_isr(void *arg); void stm32_i2c_error_isr(void *arg); From d3d484c473ba38db0bafd66f0fc221bbb75cebc7 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 24 Oct 2023 14:45:33 +0000 Subject: [PATCH 2855/4498] input: add some initial keyboard matrix library stubs We currently have three keyboard scanning drivers in the code base (npcx, it8xxx2 and mchp_xec, last two yet to be converted to input). These have been largely copy pasted from each other and share a lot of the same structure and code. This PR lays a foundation to start decoupling feature from those drivers into a common code base, and it is heavily inspired by the current regulator common data/config one. Feature wise this only moves the thread struct, stack and initialization to the common code and declares the thread callback as the only API, but the intent is to move as much code as possible in there an only abstract device specific callbacks in the api structures. Signed-off-by: Fabio Baltieri --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.kbd_matrix | 17 +++++ drivers/input/Kconfig.npcx | 7 +- drivers/input/input_kbd_matrix.c | 26 ++++++++ drivers/input/input_kbd_matrix.h | 80 +++++++++++++++++++++++ drivers/input/input_npcx_kbd.c | 22 +++---- dts/bindings/input/kbd-matrix-common.yaml | 6 ++ dts/bindings/input/nuvoton,npcx-kbd.yaml | 2 +- 9 files changed, 144 insertions(+), 18 deletions(-) create mode 100644 drivers/input/Kconfig.kbd_matrix create mode 100644 drivers/input/input_kbd_matrix.c create mode 100644 drivers/input/input_kbd_matrix.h create mode 100644 dts/bindings/input/kbd-matrix-common.yaml diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 683a3de9f12..23da1afa2db 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KEYS input_gpio_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_QDEC input_gpio_qdec.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GT911 input_gt911.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_KBD_MATRIX input_kbd_matrix.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 0e33eef6607..e10aed70e8b 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -11,6 +11,7 @@ source "drivers/input/Kconfig.ft5336" source "drivers/input/Kconfig.gpio_keys" source "drivers/input/Kconfig.gpio_qdec" source "drivers/input/Kconfig.gt911" +source "drivers/input/Kconfig.kbd_matrix" source "drivers/input/Kconfig.npcx" source "drivers/input/Kconfig.sdl" source "drivers/input/Kconfig.stmpe811" diff --git a/drivers/input/Kconfig.kbd_matrix b/drivers/input/Kconfig.kbd_matrix new file mode 100644 index 00000000000..5d1328a227f --- /dev/null +++ b/drivers/input/Kconfig.kbd_matrix @@ -0,0 +1,17 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_KBD_MATRIX + bool + help + Enable library used for keyboard matrix drivers. + +if INPUT_KBD_MATRIX + +config INPUT_KBD_MATRIX_THREAD_STACK_SIZE + int "Stack size for the keyboard matrix thread" + default 1024 + help + Size of the stack used for the keyboard matrix thread. + +endif # INPUT_KBD_MATRIX diff --git a/drivers/input/Kconfig.npcx b/drivers/input/Kconfig.npcx index e6936aeb2ee..ad738ac6563 100644 --- a/drivers/input/Kconfig.npcx +++ b/drivers/input/Kconfig.npcx @@ -7,6 +7,7 @@ menuconfig INPUT_NPCX_KBD bool "Nuvoton NPCX embedded controller (EC) keyboard scan driver" default y depends on DT_HAS_NUVOTON_NPCX_KBD_ENABLED + select INPUT_KBD_MATRIX select MULTITHREADING help This option enables the keyboard scan driver for NPCX family of @@ -34,10 +35,4 @@ config INPUT_NPCX_KBD_POLL_COL_OUTPUT_SETTLE_TIME_US Delay (us) between setting column output and waiting for it to settle -config INPUT_NPCX_KBD_THREAD_STACK_SIZE - int "Stack size for the kscan thread" - default 1024 - help - Size of the stack used for the kscan thread. - endif # INPUT_NPCX_KBD diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c new file mode 100644 index 00000000000..0ac6d4b1777 --- /dev/null +++ b/drivers/input/input_kbd_matrix.c @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "input_kbd_matrix.h" + +int input_kbd_matrix_common_init(const struct device *dev) +{ + const struct input_kbd_matrix_common_config *cfg = dev->config; + const struct input_kbd_matrix_api *api = &cfg->api; + struct input_kbd_matrix_common_data *const data = dev->data; + + k_thread_create(&data->thread, data->thread_stack, + CONFIG_INPUT_KBD_MATRIX_THREAD_STACK_SIZE, + api->polling_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(4), 0, K_NO_WAIT); + + k_thread_name_set(&data->thread, dev->name); + + return 0; +} diff --git a/drivers/input/input_kbd_matrix.h b/drivers/input/input_kbd_matrix.h new file mode 100644 index 00000000000..b70e0d5c4d1 --- /dev/null +++ b/drivers/input/input_kbd_matrix.h @@ -0,0 +1,80 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/** + * @brief Keyboard matrix internal APIs. + */ +struct input_kbd_matrix_api { + k_thread_entry_t polling_thread; +}; + +/** + * @brief Common keyboard matrix config. + * + * This structure **must** be placed first in the driver's config structure. + */ +struct input_kbd_matrix_common_config { + struct input_kbd_matrix_api api; +}; + +/** + * @brief Initialize common keyboard matrix config from devicetree. + * + * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + */ +#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, _api) \ + { \ + .api = _api, \ + } + +/** + * @brief Initialize common keyboard matrix config from devicetree instance. + * + * @param inst Instance. + * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + */ +#define INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(inst, api) \ + INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst), api) + +/** + * @brief Common keyboard matrix data. + * + * This structure **must** be placed first in the driver's data structure. + */ +struct input_kbd_matrix_common_data { + struct k_thread thread; + + K_KERNEL_STACK_MEMBER(thread_stack, + CONFIG_INPUT_KBD_MATRIX_THREAD_STACK_SIZE); +}; + +/** + * @brief Validate the offset of the common data structures. + * + * @param config Name of the config structure. + * @param data Name of the data structure. + */ +#define INPUT_KBD_STRUCT_CHECK(config, data) \ + BUILD_ASSERT(offsetof(config, common) == 0, \ + "struct input_kbd_matrix_common_config must be placed first"); \ + BUILD_ASSERT(offsetof(data, common) == 0, \ + "struct input_kbd_matrix_common_data must be placed first") + +/** + * @brief Common function to initialize a keyboard matrix device at init time. + * + * This function must be called at the end of the device init function. + * + * @param dev Keyboard matrix device instance. + * + * @retval 0 If initialized successfully. + * @retval -errno Negative errno in case of failure. + */ +int input_kbd_matrix_common_init(const struct device *dev); diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index 86dff1979b3..2b3284e6d9c 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -8,6 +8,7 @@ #define DT_DRV_COMPAT nuvoton_npcx_kbd #include "soc_miwu.h" +#include "input_kbd_matrix.h" #include #include @@ -32,6 +33,7 @@ LOG_MODULE_REGISTER(input_npcx_kbd); /* Driver config */ struct input_npcx_kbd_config { + struct input_kbd_matrix_common_config common; /* Keyboard scan controller base address */ struct kbs_reg *base; /* Clock configuration */ @@ -51,6 +53,7 @@ struct input_npcx_kbd_config { }; struct input_npcx_kbd_data { + struct input_kbd_matrix_common_data common; int64_t poll_timeout_us; uint32_t poll_period_us; uint8_t matrix_stable_state[KSCAN_COL_SIZE]; @@ -66,11 +69,10 @@ struct input_npcx_kbd_data { uint8_t scan_clk_cycle[SCAN_OCURRENCES]; struct k_sem poll_lock; uint8_t scan_cycles_idx; - struct k_thread thread; - - K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_INPUT_NPCX_KBD_THREAD_STACK_SIZE); }; +INPUT_KBD_STRUCT_CHECK(struct input_npcx_kbd_config, struct input_npcx_kbd_data); + /* Keyboard scan local functions */ static void input_npcx_kbd_ksi_isr(const struct device *dev, struct npcx_wui *wui) { @@ -474,19 +476,17 @@ static int input_npcx_kbd_init(const struct device *dev) data->poll_period_us = (uint32_t)(CONFIG_INPUT_NPCX_KBD_POLL_PERIOD_MS * USEC_PER_MSEC); data->poll_timeout_us = 100 * USEC_PER_MSEC; - k_thread_create(&data->thread, data->thread_stack, - CONFIG_INPUT_NPCX_KBD_THREAD_STACK_SIZE, - kbd_matrix_polling_thread, (void *)dev, NULL, NULL, - K_PRIO_COOP(4), 0, K_NO_WAIT); - - k_thread_name_set(&data->thread, "npcx-kbd"); - - return 0; + return input_kbd_matrix_common_init(dev); } PINCTRL_DT_INST_DEFINE(0); +static const struct input_kbd_matrix_api npcx_kbd_api = { + .polling_thread = kbd_matrix_polling_thread, +}; + static const struct input_npcx_kbd_config npcx_kbd_cfg = { + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, npcx_kbd_api), .base = (struct kbs_reg *)DT_INST_REG_ADDR(0), .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .clk_cfg = NPCX_DT_CLK_CFG_ITEM(0), diff --git a/dts/bindings/input/kbd-matrix-common.yaml b/dts/bindings/input/kbd-matrix-common.yaml new file mode 100644 index 00000000000..87dbec147b4 --- /dev/null +++ b/dts/bindings/input/kbd-matrix-common.yaml @@ -0,0 +1,6 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: Keyboard matrix device + +include: base.yaml diff --git a/dts/bindings/input/nuvoton,npcx-kbd.yaml b/dts/bindings/input/nuvoton,npcx-kbd.yaml index 9ba33d31aa1..130a003d1a4 100644 --- a/dts/bindings/input/nuvoton,npcx-kbd.yaml +++ b/dts/bindings/input/nuvoton,npcx-kbd.yaml @@ -5,7 +5,7 @@ description: Nuvoton NPCX keyboard scan controller compatible: "nuvoton,npcx-kbd" -include: [base.yaml, pinctrl-device.yaml] +include: [kbd-matrix-common.yaml, pinctrl-device.yaml] properties: reg: From 0ca5fdc6e89f596da5356a5f5059b0ed2c74fa96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 30 Oct 2023 09:08:18 +0100 Subject: [PATCH 2856/4498] lib: os: cbprintf: Add option to enable pointer checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CONFIG_CBPRINTF_CONVERT_CHECK_PTR which enables support for checking if string candidate pointer is not %p. It is by default disabled when logging strings are removed from the binary. Option is added to save code. Signed-off-by: Krzysztof Chruściński --- lib/os/Kconfig.cbprintf | 8 ++++++++ lib/os/cbprintf_packaged.c | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/os/Kconfig.cbprintf b/lib/os/Kconfig.cbprintf index 0e4984b1559..0180c745dc3 100644 --- a/lib/os/Kconfig.cbprintf +++ b/lib/os/Kconfig.cbprintf @@ -159,3 +159,11 @@ config CBPRINTF_PACKAGE_SUPPORT_TAGGED_ARGUMENTS to determine the types of arguments, but instead, each argument is tagged with a type by preceding it with another argument as type (integer). + +config CBPRINTF_CONVERT_CHECK_PTR + bool + default y if !LOG_FMT_SECTION_STRIP + help + If enabled, cbprintf_package_convert() supports checking if string + candidate is used for %p format specifier. Check cannot be performed + if string is not present in the memory. diff --git a/lib/os/cbprintf_packaged.c b/lib/os/cbprintf_packaged.c index 58076e9320a..3e71034f316 100644 --- a/lib/os/cbprintf_packaged.c +++ b/lib/os/cbprintf_packaged.c @@ -999,7 +999,8 @@ int cbprintf_package_convert(void *in_packaged, bool is_ro = ptr_in_rodata(str); int len; - if (fmt_present && is_ptr(fmt, arg_idx)) { + if (IS_ENABLED(CONFIG_CBPRINTF_CONVERT_CHECK_PTR) && + fmt_present && is_ptr(fmt, arg_idx)) { LOG_WRN("(unsigned) char * used for %%p argument. " "It's recommended to cast it to void * because " "it may cause misbehavior in certain " @@ -1077,7 +1078,8 @@ int cbprintf_package_convert(void *in_packaged, const char *str = *(const char **)&buf32[arg_pos]; bool is_ro = ptr_in_rodata(str); - if (fmt_present && is_ptr(fmt, arg_idx)) { + if (IS_ENABLED(CONFIG_CBPRINTF_CONVERT_CHECK_PTR) && + fmt_present && is_ptr(fmt, arg_idx)) { continue; } From 01cf78ad397bac58e40a859a9fb9f0240be9eb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 30 Oct 2023 09:09:28 +0100 Subject: [PATCH 2857/4498] logging: Do not check pointers when strings are stripped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When logging strings are stripped from the binary prevent performing check of pointers which requires access to the string. Signed-off-by: Krzysztof Chruściński --- subsys/logging/log_msg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 891fc2ef898..12ca9883d8b 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -236,7 +236,8 @@ void z_impl_z_log_msg_static_create(const void *source, if (inlen > 0) { uint32_t flags = CBPRINTF_PACKAGE_CONVERT_RW_STR | - CBPRINTF_PACKAGE_CONVERT_PTR_CHECK; + (IS_ENABLED(CONFIG_LOG_FMT_SECTION_STRIP) ? + 0 : CBPRINTF_PACKAGE_CONVERT_PTR_CHECK); uint16_t strl[4]; int len; From c92c7ab8735dc35ce4dbf2d5ecc324e6f71ee076 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 30 Oct 2023 09:06:56 +0200 Subject: [PATCH 2858/4498] manifest: Update to latest ACPICA Zephyr fixes There are a couple of important fixes without which ACPICA doesn't work on all supported platforms. Signed-off-by: Johan Hedberg --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 40d5c4a684f..797315f7455 100644 --- a/west.yml +++ b/west.yml @@ -30,7 +30,7 @@ manifest: # Please add items below based on alphabetical order projects: - name: acpica - revision: 0333c2af13179f9b33d495cf7cb9a509f751cbb1 + revision: 10ae1038e51eb9306f73c3bbcfc4fde954bb9625 path: modules/lib/acpica - name: bsim repo-path: babblesim-manifest From 542f95b811c6918a93fa5058cc1d9d34e92119fb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 28 Oct 2023 22:23:45 +0300 Subject: [PATCH 2859/4498] boards: x86: Increase minimum system heap size for ACPI ACPICA initialization takes considerably more than 32k. E.g. on up_squared the utilization is 400-500k, qemu_x86_64 about 120k and on EHL about 1.5M. Increase the default on these platforms to be big enough if ACPI is enabled. Signed-off-by: Johan Hedberg --- boards/x86/intel_ehl/Kconfig.defconfig | 2 +- boards/x86/qemu_x86/Kconfig.defconfig | 4 ++-- boards/x86/up_squared/Kconfig.defconfig | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/x86/intel_ehl/Kconfig.defconfig b/boards/x86/intel_ehl/Kconfig.defconfig index d0a9aa7093b..2b981234970 100644 --- a/boards/x86/intel_ehl/Kconfig.defconfig +++ b/boards/x86/intel_ehl/Kconfig.defconfig @@ -20,7 +20,7 @@ config SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN endif config HEAP_MEM_POOL_SIZE - default 32768 if ACPI + default 2097152 if ACPI depends on KERNEL_MEM_POOL # TSC on this board is 1.9 GHz, HPET and APIC are 19.2 MHz diff --git a/boards/x86/qemu_x86/Kconfig.defconfig b/boards/x86/qemu_x86/Kconfig.defconfig index 4ed71964aa3..84f66e32004 100644 --- a/boards/x86/qemu_x86/Kconfig.defconfig +++ b/boards/x86/qemu_x86/Kconfig.defconfig @@ -25,7 +25,7 @@ config KERNEL_VM_SIZE default 0x10000000 if ACPI config HEAP_MEM_POOL_SIZE - default 32768 if ACPI + default 1048576 if ACPI depends on KERNEL_MEM_POOL config MULTIBOOT @@ -54,7 +54,7 @@ config KERNEL_VM_SIZE default 0x10000000 if ACPI config HEAP_MEM_POOL_SIZE - default 32768 if ACPI + default 1048576 if ACPI depends on KERNEL_MEM_POOL endif # BOARD_QEMU_X86_64 diff --git a/boards/x86/up_squared/Kconfig.defconfig b/boards/x86/up_squared/Kconfig.defconfig index cf1128a7d26..33cf546edfc 100644 --- a/boards/x86/up_squared/Kconfig.defconfig +++ b/boards/x86/up_squared/Kconfig.defconfig @@ -9,7 +9,7 @@ config MP_MAX_NUM_CPUS default 2 if BOARD_UP_SQUARED config HEAP_MEM_POOL_SIZE - default 32768 if ACPI + default 1048576 if ACPI depends on KERNEL_MEM_POOL config BUILD_OUTPUT_STRIPPED From a0203d1b20f368e160ec27500fdf1d2df9d0ffc5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 28 Oct 2023 22:25:18 +0300 Subject: [PATCH 2860/4498] acpi: Fix trying to register a system memory handler ACPICA itself already registers its own handler (which works perfectly fine for our purposes). Furthermore, ACPICA will always fail trying to register another handler, unless the previous one is explicitly cleared (which is something the Zephyr code didn't do). Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index dca6e81cc3e..9ae1e47371b 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -52,24 +52,6 @@ static void notify_handler(ACPI_HANDLE device, UINT32 value, void *ctx) ACPI_INFO(("Received a notify 0x%X", value)); } -static ACPI_STATUS region_handler(UINT32 Function, ACPI_PHYSICAL_ADDRESS address, UINT32 bit_width, - UINT64 *value, void *handler_ctx, void *region_ctx) -{ - return AE_OK; -} - -static ACPI_STATUS region_init(ACPI_HANDLE RegionHandle, UINT32 Function, void *handler_ctx, - void **region_ctx) -{ - if (Function == ACPI_REGION_DEACTIVATE) { - *region_ctx = NULL; - } else { - *region_ctx = RegionHandle; - } - - return AE_OK; -} - static ACPI_STATUS install_handlers(void) { ACPI_STATUS status; @@ -82,13 +64,7 @@ static ACPI_STATUS install_handlers(void) goto exit; } - status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, - region_handler, region_init, NULL); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "While installing an OpRegion handler")); - } exit: - return status; } From ab46cef69f18f19d7cd97d5ef24b1fe2d7b33977 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 28 Oct 2023 23:19:56 +0300 Subject: [PATCH 2861/4498] acpi: Fix ACPICA initialization routine order The upstream ACPICA example initialization order does AcpiLoadTables() before calling AcpiEnableSubsystem(), so use this order in Zephyr too. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 9ae1e47371b..b1dcd64a136 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -91,10 +91,10 @@ static ACPI_STATUS initialize_acpica(void) goto exit; } - /* Initialize the ACPI hardware */ - status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); + /* Create the ACPI namespace from ACPI tables */ + status = AcpiLoadTables(); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "While enabling ACPI")); + ACPI_EXCEPTION((AE_INFO, status, "While loading ACPI tables")); goto exit; } @@ -105,10 +105,10 @@ static ACPI_STATUS initialize_acpica(void) goto exit; } - /* Create the ACPI namespace from ACPI tables */ - status = AcpiLoadTables(); + /* Initialize the ACPI hardware */ + status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "While loading ACPI tables")); + ACPI_EXCEPTION((AE_INFO, status, "While enabling ACPI")); goto exit; } From b95931859e1bad84235d17df2b59d6a524c976df Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 28 Oct 2023 23:16:41 +0300 Subject: [PATCH 2862/4498] acpi: Fix using correct buffer length for irq rt_table We should use the given rt_size variable to indicate the size of rt_table. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index b1dcd64a136..bd862b82218 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -215,7 +215,7 @@ static int acpi_get_irq_table(struct acpi *bus, char *bus_name, } rt_buffer.Pointer = rt_table; - rt_buffer.Length = ACPI_DEBUG_BUFFER_SIZE; + rt_buffer.Length = rt_size; status = AcpiGetIrqRoutingTable(node, &rt_buffer); if (ACPI_FAILURE(status)) { From ff0b803334b775fa9ad6ad79c0b0f76d0378f0cc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 28 Oct 2023 23:11:26 +0300 Subject: [PATCH 2863/4498] acpi: Fix ACPI PCI bus handle The PRT bus name for most (especially older) platforms is _SB.PCI0. Only newer platforms use something else (like _SB.PC00). Signed-off-by: Johan Hedberg --- boards/x86/intel_adl/Kconfig.defconfig | 2 ++ boards/x86/intel_ehl/Kconfig.defconfig | 4 ++++ boards/x86/intel_rpl/Kconfig.defconfig | 4 ++++ lib/acpi/Kconfig | 6 ++++++ lib/acpi/acpi.c | 3 ++- 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/boards/x86/intel_adl/Kconfig.defconfig b/boards/x86/intel_adl/Kconfig.defconfig index 9e2255a7471..247b8f7a0cb 100644 --- a/boards/x86/intel_adl/Kconfig.defconfig +++ b/boards/x86/intel_adl/Kconfig.defconfig @@ -36,6 +36,8 @@ config HEAP_MEM_POOL_SIZE default 64000000 config MAIN_STACK_SIZE default 320000 +config ACPI_PRT_BUS_NAME + default "_SB.PC00" if SHELL config SHELL_STACK_SIZE diff --git a/boards/x86/intel_ehl/Kconfig.defconfig b/boards/x86/intel_ehl/Kconfig.defconfig index 2b981234970..7d6667a6cec 100644 --- a/boards/x86/intel_ehl/Kconfig.defconfig +++ b/boards/x86/intel_ehl/Kconfig.defconfig @@ -19,6 +19,10 @@ config SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN default n endif +config ACPI_PRT_BUS_NAME + depends on ACPI + default "_SB.PC00" + config HEAP_MEM_POOL_SIZE default 2097152 if ACPI depends on KERNEL_MEM_POOL diff --git a/boards/x86/intel_rpl/Kconfig.defconfig b/boards/x86/intel_rpl/Kconfig.defconfig index 99d9f8d08f2..e90e33b1583 100644 --- a/boards/x86/intel_rpl/Kconfig.defconfig +++ b/boards/x86/intel_rpl/Kconfig.defconfig @@ -29,6 +29,10 @@ endif config ACPI default y +config ACPI_PRT_BUS_NAME + depends on ACPI + default "_SB.PC00" + if DMA config DMA_64BIT default y diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index 022eb083c84..10414338c21 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -14,6 +14,12 @@ module = ACPI module-str = acpi source "subsys/logging/Kconfig.template.log_config" +config ACPI_PRT_BUS_NAME + string "ACPI name of PCI bus" + default "_SB.PCI0" + help + ACPI name of PCI bus. + config ACPI_MAX_PRT_ENTRY int "Size of PRT buffer" default 4096 diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index bd862b82218..f84accb7af9 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -239,7 +239,8 @@ static int acpi_get_irq_table(struct acpi *bus, char *bus_name, static int acpi_retrieve_legacy_irq(struct acpi *bus) { /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ - return acpi_get_irq_table(bus, "_SB.PC00", bus->pci_prt_table, sizeof(bus->pci_prt_table)); + return acpi_get_irq_table(bus, CONFIG_ACPI_PRT_BUS_NAME, + bus->pci_prt_table, sizeof(bus->pci_prt_table)); } static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 level, void *ctx, From 435b8a25d672e53e5dcd93b9dd248b3f434cfd4f Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sat, 28 Oct 2023 20:15:36 +0200 Subject: [PATCH 2864/4498] doc: hardware: peripherals: can: split CAN transceiver from controller Split out the CAN transceiver API documentation from the CAN controller API documentation. The CAN transceiver API was introduced in Zephyr v3.1.0. Signed-off-by: Henrik Brix Andersen --- doc/develop/api/overview.rst | 4 +++ doc/hardware/peripherals/can/controller.rst | 28 --------------- doc/hardware/peripherals/can/index.rst | 1 + doc/hardware/peripherals/can/transceiver.rst | 37 ++++++++++++++++++++ 4 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 doc/hardware/peripherals/can/transceiver.rst diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 1998f3a67aa..642d7b807c3 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -61,6 +61,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Stable - 1.14 + * - :ref:`can_transceiver_api` + - Experimental + - 3.1 + * - :ref:`charger_api` - Experimental - 3.5 diff --git a/doc/hardware/peripherals/can/controller.rst b/doc/hardware/peripherals/can/controller.rst index 8724b96515a..fd9c6d8df69 100644 --- a/doc/hardware/peripherals/can/controller.rst +++ b/doc/hardware/peripherals/can/controller.rst @@ -16,22 +16,6 @@ ISO 11898-1:2003 standard. CAN is mostly known for its application in the automotive domain. However, it is also used in home and industrial automation and other products. -A CAN transceiver is an external device that converts the logic level signals -from the CAN controller to the bus-levels. The bus lines are called -CAN High (CAN H) and CAN Low (CAN L). -The transmit wire from the controller to the transceiver is called CAN TX, -and the receive wire is called CAN RX. -These wires use the logic levels whereas the bus-level is interpreted -differentially between CAN H and CAN L. -The bus can be either in the recessive (logical one) or dominant (logical zero) -state. The recessive state is when both lines, CAN H and CAN L, at roughly at -the same voltage level. This state is also the idle state. -To write a dominant bit to the bus, open-drain transistors tie CAN H to Vdd -and CAN L to ground. -The first and last node use a 120-ohm resistor between CAN H and CAN L to -terminate the bus. The dominant state always overrides the recessive state. -This structure is called a wired-AND. - .. warning:: CAN controllers can only initialize when the bus is in the idle (recessive) @@ -39,12 +23,6 @@ This structure is called a wired-AND. CAN RX is high, at least for a short time. This is also necessary for loopback mode. -.. image:: transceiver.svg - :width: 70% - :align: center - :alt: CAN Transceiver - - The bit-timing as defined in ISO 11898-1:2003 looks as following: .. image:: timing.svg @@ -340,9 +318,3 @@ CAN Controller API Reference **************************** .. doxygengroup:: can_interface - - -CAN Transceiver API Reference -***************************** - -.. doxygengroup:: can_transceiver diff --git a/doc/hardware/peripherals/can/index.rst b/doc/hardware/peripherals/can/index.rst index c21d75eb523..6e96fb15cb2 100644 --- a/doc/hardware/peripherals/can/index.rst +++ b/doc/hardware/peripherals/can/index.rst @@ -7,3 +7,4 @@ Controller Area Network (CAN) :maxdepth: 2 controller.rst + transceiver.rst diff --git a/doc/hardware/peripherals/can/transceiver.rst b/doc/hardware/peripherals/can/transceiver.rst new file mode 100644 index 00000000000..26db7856818 --- /dev/null +++ b/doc/hardware/peripherals/can/transceiver.rst @@ -0,0 +1,37 @@ +.. _can_transceiver_api: + +CAN Transceiver +############### + +.. contents:: + :local: + :depth: 2 + +Overview +******** + +A CAN transceiver is an external device that converts the logic level signals +from the CAN controller to the bus-levels. The bus lines are called +CAN High (CAN H) and CAN Low (CAN L). +The transmit wire from the controller to the transceiver is called CAN TX, +and the receive wire is called CAN RX. +These wires use the logic levels whereas the bus-level is interpreted +differentially between CAN H and CAN L. +The bus can be either in the recessive (logical one) or dominant (logical zero) +state. The recessive state is when both lines, CAN H and CAN L, are roughly at +the same voltage level. This state is also the idle state. +To write a dominant bit to the bus, open-drain transistors tie CAN H to Vdd +and CAN L to ground. +The first and last node use a 120-ohm resistor between CAN H and CAN L to +terminate the bus. The dominant state always overrides the recessive state. +This structure is called a wired-AND. + +.. image:: transceiver.svg + :width: 70% + :align: center + :alt: CAN Transceiver + +CAN Transceiver API Reference +***************************** + +.. doxygengroup:: can_transceiver From 4d7c8790d70d553f2e1638e9a18583d53a03e96a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 13:16:07 +0100 Subject: [PATCH 2865/4498] Bluetooth samples: unicast audio server: Fix codec initialization The lc3_enable code was refering to a variable that does not exist. Fix it. Issue was introduced in 9c47eb924fa. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_server/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index 7625bcdbf7f..700c1a1ef1e 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -372,7 +372,7 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t return ret; } - ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + ret = bt_audio_codec_cfg_get_frame_dur(stream->codec_cfg); if (ret > 0) { frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); } else { From f4ee15e9393b950b83370239e8889346b2a34688 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 13:18:43 +0100 Subject: [PATCH 2866/4498] Bluetooth samples: unicast audio client: Fix build warnings In 85bb2624bc562becde8b1b6e3b570e2d4b45c7e5 init_lc3()'s prototype was changed to return an int, but the code was not updated to return something !=0 on all errors, or 0 on error. Fix it. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_client/src/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index 0e35a7d5a3d..1dc411f7b59 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -245,17 +245,17 @@ static int init_lc3(void) if (freq_hz < 0) { printk("Error: Codec frequency not set, cannot start codec."); - return; + return -1; } if (frame_duration_us < 0) { printk("Error: Frame duration not set, cannot start codec."); - return; + return -1; } if (octets_per_frame < 0) { printk("Error: Octets per frame not set, cannot start codec."); - return; + return -1; } frame_duration_100us = frame_duration_us / 100; @@ -277,7 +277,9 @@ static int init_lc3(void) if (lc3_encoder == NULL) { printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); + return -1; } + return 0; } #else From aa3e79a88ac635492c2baccf0f74dc26597dadf8 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Mon, 30 Oct 2023 16:03:52 +0100 Subject: [PATCH 2867/4498] scripts: Add test_plan.py to twister_ignore.txt There is no point in running full twister scope when test_plan.py script is modified. Signed-off-by: Maciej Perkowski --- scripts/ci/twister_ignore.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index c1dfb0a98f8..acdad51eb46 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -24,6 +24,7 @@ doc/* *.md # if we change this file or associated script, it should not trigger a full # twister. +scripts/ci/test_plan.py scripts/ci/twister_ignore.txt scripts/ci/what_changed.py scripts/ci/version_mgr.py From f14c061dd6712c03467f67127eaf480a062f9e09 Mon Sep 17 00:00:00 2001 From: Witold Lukasik Date: Thu, 26 Oct 2023 17:32:26 +0200 Subject: [PATCH 2868/4498] shell: fix SHELL_SUBCMD_COND_ADD with NULL as _handler parameter In dummy_subcmd_##syntax statement, syntax keyword should be replaced with _syntax, that is the argument name. In dummy_##syntax##_handler There are two problems: - wrong syntax keyword - _handler is an argument So if NULL is passed as an argument to _handler, and the syntax is abcd, there is: dummy_##abcd##NULL, what causes a build error. Signed-off-by: Witold Lukasik --- include/zephyr/shell/shell.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 22841392d70..8382dc8290a 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -350,8 +350,8 @@ struct shell_static_entry { SHELL_EXPR_CMD_ARG(1, _syntax, _subcmd, _help, \ _handler, _mand, _opt)\ ), \ - (static shell_cmd_handler dummy_##syntax##_handler __unused = _handler;\ - static const union shell_cmd_entry dummy_subcmd_##syntax __unused = { \ + (static shell_cmd_handler dummy_handler_##_syntax __unused = _handler;\ + static const union shell_cmd_entry dummy_subcmd_##_syntax __unused = { \ .entry = (const struct shell_static_entry *)_subcmd\ } \ ) \ From 639d1f803b3db48941ce7c27e55ad130db67b547 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 30 Oct 2023 08:56:59 +0000 Subject: [PATCH 2869/4498] github: compliance: fix python cache keys The compliance and coding guidelines workflows are using the same pip cache key, but they install a different set of packages. This is probably a copy paste error from the documentation build workflow, which has been changed to use a hash, and is causing one of the two steps to restore from a incorrect cache. Fix this by using a hash of the workflow file itself as a key, as that's where the python package list is defined. Signed-off-by: Fabio Baltieri --- .github/workflows/coding_guidelines.yml | 2 +- .github/workflows/compliance.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index ea632b7f0b2..c810a22415e 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -17,7 +17,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cache/pip - key: ${{ runner.os }}-doc-pip + key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/coding_guidelines.yml') }} - name: Install python dependencies run: | diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index cb4e1c00f77..de1decb2cc6 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -21,7 +21,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cache/pip - key: ${{ runner.os }}-doc-pip + key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/compliance.yml') }} - name: Install python dependencies run: | From 67676d8fbcf5d742bdc6bbf0635d79499fa66062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 31 Oct 2023 11:37:04 +0100 Subject: [PATCH 2870/4498] linker: Fix missing DEVNULL_REGION for XIP configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DEVNULL_REGION was created only for !CONFIG_XIP. Moved definition outside of that #ifdef. Removed condition which was repeated as it is present at the beginning of the file. Signed-off-by: Krzysztof Chruściński --- include/zephyr/linker/linker-devnull.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/zephyr/linker/linker-devnull.h b/include/zephyr/linker/linker-devnull.h index 0545da7c8a5..d5455dd6da2 100644 --- a/include/zephyr/linker/linker-devnull.h +++ b/include/zephyr/linker/linker-devnull.h @@ -65,14 +65,10 @@ #error "Cannot place devnull segment adjacent to ROM region." #endif -#if defined(CONFIG_LINKER_DEVNULL_MEMORY) -#define DEVNULL_REGION DEVNULL_ROM -#else -#define DEVNULL_REGION ROMABLE_REGION -#endif - #endif /* CONFIG_XIP */ +#define DEVNULL_REGION DEVNULL_ROM + #endif /* CONFIG_LINKER_DEVNULL_MEMORY */ #endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ */ From 0958abd2ef77dd0c4aa224da99903b0a7b8e122f Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 31 Oct 2023 11:56:09 +0100 Subject: [PATCH 2871/4498] twister: unittests: Fix unittest test_projectbuilder_gather_metrics Fix #64606 by initializing mock object. Signed-off-by: Grzegorz Chwierut --- scripts/tests/twister/test_runner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index b008793ef77..ed0533937b6 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -2235,6 +2235,7 @@ def test_projectbuilder_gather_metrics( pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) pb.options.enable_size_report = enable_size_report + pb.options.create_rom_ram_report = False pb.options.cmake_only = cmake_only pb.calc_size = mock.Mock() From c5d6ef14873569c201e3f06228c5e4ff7e273e31 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 14:02:17 +0200 Subject: [PATCH 2872/4498] tests/bsim compile: Add support for sysbuild Add support for sysbuild builds, which can be selected by settings the variable sysbuild. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/compile.source | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/bsim/compile.source b/tests/bsim/compile.source index 603585d15eb..5cababeaefa 100644 --- a/tests/bsim/compile.source +++ b/tests/bsim/compile.source @@ -13,6 +13,7 @@ function _compile(){ : "${app:?app must be defined}" local app_root="${app_root:-${ZEPHYR_BASE}}" + local BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" local conf_file="${conf_file:-prj.conf}" local conf_overlay="${conf_overlay:-""}" @@ -46,7 +47,12 @@ function _compile(){ fi local cmake_cmd+=( -DOVERLAY_CONFIG="${conf_overlay}" \ ${modules_arg} \ - ${cmake_args} -DCMAKE_C_FLAGS=\"${cc_flags}\" ${app_root}/${app}) + ${cmake_args} -DCMAKE_C_FLAGS=\"${cc_flags}\") + if [ -v sysbuild ]; then + local cmake_cmd+=( -DAPP_DIR=${app_root}/${app} ${ZEPHYR_BASE}/share/sysbuild/) + else + local cmake_cmd+=( ${app_root}/${app}) + fi # Set INCR_BUILD when calling to only do an incremental build if [ ! -v INCR_BUILD ] || [ ! -d "${this_dir}" ]; then From a84349280bee89d436266bea9525b85bf3b88174 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 27 Oct 2023 09:51:46 +0200 Subject: [PATCH 2873/4498] tests/bsim/bt conn: Add support for split build with sysbuild Add sysbuild build files, which allows building this test both for the targets we could already before (nrf52_bsim & nrf5340bsim_nrf5340_cpunet) and also adds support for the a split build with the nrf5340bsim_nrf5340_cpuapp. Note that when doing a split build the controller is taken from the hci_rpmsg BT sample, and therefore the controller configuration in this folder is not used. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/ll/conn/Kconfig.sysbuild | 14 +++++++ tests/bsim/bluetooth/ll/conn/sysbuild.cmake | 42 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/bsim/bluetooth/ll/conn/Kconfig.sysbuild create mode 100644 tests/bsim/bluetooth/ll/conn/sysbuild.cmake diff --git a/tests/bsim/bluetooth/ll/conn/Kconfig.sysbuild b/tests/bsim/bluetooth/ll/conn/Kconfig.sysbuild new file mode 100644 index 00000000000..6c89fddc9f3 --- /dev/null +++ b/tests/bsim/bluetooth/ll/conn/Kconfig.sysbuild @@ -0,0 +1,14 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake new file mode 100644 index 00000000000..959db3af95a --- /dev/null +++ b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + set(NET_APP hci_rpmsg) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + endif() + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe +add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} +) From c6f2cca5159e283a69c75f6e80b6fd3715885ec1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 12:28:05 +0200 Subject: [PATCH 2874/4498] tests/bsim/bt bis: Add support for split build with sysbuild Add sysbuild build files, which allows building this test both for the targets we could already before (nrf52_bsim & nrf5340bsim_nrf5340_cpunet) and also adds support for the a split build with the nrf5340bsim_nrf5340_cpuapp. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/ll/bis/Kconfig.sysbuild | 14 ++++++ tests/bsim/bluetooth/ll/bis/prj.conf | 3 ++ tests/bsim/bluetooth/ll/bis/sysbuild.cmake | 47 ++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 tests/bsim/bluetooth/ll/bis/Kconfig.sysbuild create mode 100644 tests/bsim/bluetooth/ll/bis/sysbuild.cmake diff --git a/tests/bsim/bluetooth/ll/bis/Kconfig.sysbuild b/tests/bsim/bluetooth/ll/bis/Kconfig.sysbuild new file mode 100644 index 00000000000..6c89fddc9f3 --- /dev/null +++ b/tests/bsim/bluetooth/ll/bis/Kconfig.sysbuild @@ -0,0 +1,14 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/ll/bis/prj.conf b/tests/bsim/bluetooth/ll/bis/prj.conf index c599e0d0656..02e2f3168db 100644 --- a/tests/bsim/bluetooth/ll/bis/prj.conf +++ b/tests/bsim/bluetooth/ll/bis/prj.conf @@ -21,3 +21,6 @@ CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX=251 CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX=251 CONFIG_BT_CTLR_TEST=y + +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake new file mode 100644 index 00000000000..9a01fec76c5 --- /dev/null +++ b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake @@ -0,0 +1,47 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + set(NET_APP hci_rpmsg) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + endif() + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe +add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} +) From 10d7b1908ecb3ffd6b06c235f5fe72427d6172de Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 14:49:59 +0200 Subject: [PATCH 2875/4498] tests/bsim run_parallel: Ignore any script with compile in its name Note just those called exactly compile.sh Signed-off-by: Alberto Escolar Piedras --- tests/bsim/run_parallel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/run_parallel.sh b/tests/bsim/run_parallel.sh index 395dc7f6084..9d6b498878e 100755 --- a/tests/bsim/run_parallel.sh +++ b/tests/bsim/run_parallel.sh @@ -50,7 +50,7 @@ elif [ -n "${TESTS_LIST}" ]; then else SEARCH_PATH="${SEARCH_PATH:-.}" all_cases=`find ${SEARCH_PATH} -name "*.sh" | \ - grep -Ev "(/_|run_parallel|compile.sh|generate_coverage_report.sh)"` + grep -Ev "(/_|run_parallel|compile|generate_coverage_report.sh)"` #we dont run ourselves fi From 21f755d651d7843583a3df68a0293fe26b2a2bed Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 16:15:24 +0200 Subject: [PATCH 2876/4498] tests/bsim run_parallel: Allow TESTS_FILE with search paths With TESTS_FILE the user could provide a file with a list of tests to run. Now we also support that file containing a mix of tests and paths in which to search for tests. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/run_parallel.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/bsim/run_parallel.sh b/tests/bsim/run_parallel.sh index 9d6b498878e..80e74512ef3 100755 --- a/tests/bsim/run_parallel.sh +++ b/tests/bsim/run_parallel.sh @@ -13,8 +13,8 @@ function display_help(){ echo " Testcases are searched for in \${SEARCH_PATH}," echo " which by default is the folder the script is run from" echo " You can instead also provide a space separated test list with \${TESTS_LIST}, " - echo " or an input file including a list of tests \${TESTS_FILE} (w one line" - echo " per test, you can comment lines with #)" + echo " or an input file including a list of tests and/or tests search paths" + echo " \${TESTS_FILE} (w one line per test/path, you can comment lines with #)" echo "" echo " Examples (run from \${ZEPHYR_BASE}):" echo " * Run all tests found under one folder:" @@ -44,7 +44,9 @@ i=0 if [ -n "${TESTS_FILE}" ]; then #remove comments and empty lines from file - all_cases=$(sed 's/#.*$//;/^$/d' "${TESTS_FILE}") + search_pattern=$(sed 's/#.*$//;/^$/d' "${TESTS_FILE}") || exit 1 + all_cases=`find ${search_pattern} -name "*.sh" | \ + grep -Ev "(/_|run_parallel|compile|generate_coverage_report.sh)"` elif [ -n "${TESTS_LIST}" ]; then all_cases=${TESTS_LIST} else From 464435e22b68eabe46b48eee9b4edf8a0a2be487 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 26 Oct 2023 16:28:25 +0200 Subject: [PATCH 2877/4498] CI bsim workflow: Also run some split BT stack tests Also run some split BT stack tests on the nrf5340 platform to test this configuration. Move the selection of which BT tests are built and run in each platform to files in the tests/bsim/ folder. Signed-off-by: Alberto Escolar Piedras --- .github/workflows/bsim-tests.yaml | 22 ++++++++++++---- .../compile.nrf5340bsim_nrf5340_cpuapp.sh | 25 +++++++++++++++++++ .../compile.nrf5340bsim_nrf5340_cpunet.sh | 23 +++++++++++++++++ tests/bsim/bluetooth/tests.nrf52bsim.txt | 3 +++ .../tests.nrf5340bsim_nrf5340_cpuapp.txt | 4 +++ .../tests.nrf5340bsim_nrf5340_cpunet.txt | 4 +++ 6 files changed, 76 insertions(+), 5 deletions(-) create mode 100755 tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh create mode 100755 tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpunet.sh create mode 100644 tests/bsim/bluetooth/tests.nrf52bsim.txt create mode 100644 tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt create mode 100644 tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpunet.txt diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index a8a49be7670..f52a0439d20 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -42,6 +42,7 @@ jobs: EDTT_PATH: ../tools/edtt bsim_bt_52_test_results_file: ./bsim_bt/52_bsim_results.xml bsim_bt_53_test_results_file: ./bsim_bt/53_bsim_results.xml + bsim_bt_53split_test_results_file: ./bsim_bt/53_bsim_split_results.xml bsim_net_52_test_results_file: ./bsim_net/52_bsim_results.xml steps: - name: Apply container owner mismatch workaround @@ -134,15 +135,25 @@ jobs: if: steps.check-bluetooth-files.outputs.any_changed == 'true' || steps.check-common-files.outputs.any_changed == 'true' run: | export ZEPHYR_BASE=${PWD} - WORK_DIR=${ZEPHYR_BASE}/bsim_bt nice tests/bsim/bluetooth/compile.sh + export WORK_DIR=${ZEPHYR_BASE}/bsim_bt + # Build and run the BT tests for nrf52_bsim: + nice tests/bsim/bluetooth/compile.sh RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bt_52_test_results_file} \ - SEARCH_PATH=tests/bsim/bluetooth/ tests/bsim/run_parallel.sh - # Run the BT controller tests also for the nrf5340 + TESTS_FILE=tests/bsim/bluetooth/tests.nrf52bsim.txt tests/bsim/run_parallel.sh + # Build and run the BT controller tests also for the nrf5340bsim_nrf5340_cpunet BOARD=nrf5340bsim_nrf5340_cpunet \ - WORK_DIR=${ZEPHYR_BASE}/bsim_bt nice tests/bsim/bluetooth/ll/compile.sh + nice tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpunet.sh BOARD=nrf5340bsim_nrf5340_cpunet \ RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bt_53_test_results_file} \ - SEARCH_PATH=tests/bsim/bluetooth/ll/ tests/bsim/run_parallel.sh + TESTS_FILE=tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpunet.txt \ + tests/bsim/run_parallel.sh + # Build and run the nrf5340 split stack tests set + BOARD=nrf5340bsim_nrf5340_cpuapp \ + nice tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh + BOARD=nrf5340bsim_nrf5340_cpuapp \ + RESULTS_FILE=${ZEPHYR_BASE}/${bsim_bt_53split_test_results_file} \ + TESTS_FILE=tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt \ + tests/bsim/run_parallel.sh - name: Run Networking Tests with BSIM if: steps.check-networking-files.outputs.any_changed == 'true' || steps.check-common-files.outputs.any_changed == 'true' @@ -160,6 +171,7 @@ jobs: path: | ./bsim_bt/52_bsim_results.xml ./bsim_bt/53_bsim_results.xml + ./bsim_bt/53_bsim_split_results.xml ./bsim_net/52_bsim_results.xml ${{ github.event_path }} if-no-files-found: warn diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh new file mode 100755 index 00000000000..ddb8349ff53 --- /dev/null +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright 2018 Oticon A/S +# SPDX-License-Identifier: Apache-2.0 + +# Compile all bluetooth applications needed for the split stack tests + +#set -x #uncomment this line for debugging +set -ue +: "${BSIM_COMPONENTS_PATH:?BSIM_COMPONENTS_PATH must be defined}" +: "${ZEPHYR_BASE:?ZEPHYR_BASE must be set to point to the zephyr root\ + directory}" + +WORK_DIR="${WORK_DIR:-${ZEPHYR_BASE}/bsim_out}" + +BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" +BOARD="${BOARD:-nrf5340bsim_nrf5340_cpuapp}" + +mkdir -p ${WORK_DIR} + +source ${ZEPHYR_BASE}/tests/bsim/compile.source + +app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile +app=tests/bsim/bluetooth/ll/bis sysbuild=1 compile + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpunet.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpunet.sh new file mode 100755 index 00000000000..e8d78683b2e --- /dev/null +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpunet.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# Copyright 2018 Oticon A/S +# SPDX-License-Identifier: Apache-2.0 + +# Compile all the applications needed by the Bluetooth bsim tests on the nrf5340_cpunet + +#set -x #uncomment this line for debugging +set -ue +: "${BSIM_COMPONENTS_PATH:?BSIM_COMPONENTS_PATH must be defined}" +: "${ZEPHYR_BASE:?ZEPHYR_BASE must be set to point to the zephyr root\ + directory}" + +WORK_DIR="${WORK_DIR:-${ZEPHYR_BASE}/bsim_out}" + +BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" + +mkdir -p ${WORK_DIR} + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +${ZEPHYR_BASE}/tests/bsim/bluetooth/ll/compile.sh + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/tests.nrf52bsim.txt b/tests/bsim/bluetooth/tests.nrf52bsim.txt new file mode 100644 index 00000000000..9b76be4ec75 --- /dev/null +++ b/tests/bsim/bluetooth/tests.nrf52bsim.txt @@ -0,0 +1,3 @@ +# Search paths(s) for tests which will be run in the nrf52bsim +# This file is used in CI to select which tests are run +tests/bsim/bluetooth/ diff --git a/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt new file mode 100644 index 00000000000..147b55103fc --- /dev/null +++ b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt @@ -0,0 +1,4 @@ +# Search paths(s) for tests which will be run in the nrf5340 split stack configuration +# This file is used in CI to select which tests are run +tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn_encrypted_split_privacy.sh +tests/bsim/bluetooth/ll/bis/tests_scripts/broadcast_iso.sh diff --git a/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpunet.txt b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpunet.txt new file mode 100644 index 00000000000..1d9d73630db --- /dev/null +++ b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpunet.txt @@ -0,0 +1,4 @@ +# Search paths(s) for tests which will be run in the nrf5340 net core (both app, host and controller +# built in the net core) +# This file is used in CI to select which tests are run +tests/bsim/bluetooth/ll/ From 482416db01e5b8d3e8b91c52bb9daa6eb3d8cddd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 27 Oct 2023 11:56:35 +0200 Subject: [PATCH 2878/4498] tests/bsim bis: Reduce the test verbosity The test was printing one line for each packet it was sending by default. That creates a huge log and slows things down. Instead, let's only print those with verbosity set at 4 or higher. Signed-off-by: Alberto Escolar Piedras --- tests/bsim/bluetooth/ll/bis/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/ll/bis/src/main.c b/tests/bsim/bluetooth/ll/bis/src/main.c index 6cc425953ed..232613171aa 100644 --- a/tests/bsim/bluetooth/ll/bis/src/main.c +++ b/tests/bsim/bluetooth/ll/bis/src/main.c @@ -183,7 +183,7 @@ static void iso_send(struct k_work *work) iso_data_len = MAX(sizeof(seq_num), ((seq_num % CONFIG_BT_ISO_TX_MTU) + 1)); net_buf_add_mem(buf, iso_data, iso_data_len); - printk("ISO send: seq_num %u\n", seq_num); + bs_trace_info_time(4, "ISO send: seq_num %u\n", seq_num); ret = bt_iso_chan_send(&bis_iso_chan, buf, seq_num++, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { From d89938f4b978c3a9a7f8f711b0b65c7cca983d3e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 31 Oct 2023 15:08:00 +0000 Subject: [PATCH 2879/4498] doc: guidelines: fix title level Specialized driver requirements should have been one level up, it now nests under "treewide". Signed-off-by: Fabio Baltieri --- doc/contribute/guidelines.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index bc6bbed81b3..c4ef5ce6bb1 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -1028,7 +1028,7 @@ support for the old one is not a treewide change. Deprecation and removal of such APIs, however, are treewide changes. Specialized driver requirements -=============================== +******************************* Drivers for standalone devices should use the Zephyr bus APIs (SPI, I2C...) whenever possible so that the device can be used with any SoC from any vendor From 2c972d5b57340ddb0abe346254122f60848a57b3 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Wed, 12 Jul 2023 11:02:06 -0400 Subject: [PATCH 2880/4498] drivers: flash: spi_nor: Allow page-size to be set via devicetree In the CONFIG_SPI_NOR_SFDP_MINIMAL configuration this value is hard coded to 256 bytes. Make it configurable via devicetree. Signed-off-by: Andriy Gelman --- drivers/flash/Kconfig.nor | 3 ++- drivers/flash/spi_nor.c | 2 +- dts/bindings/mtd/jedec,jesd216.yaml | 13 +++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/flash/Kconfig.nor b/drivers/flash/Kconfig.nor index 28bbfd5c66e..507e681c120 100644 --- a/drivers/flash/Kconfig.nor +++ b/drivers/flash/Kconfig.nor @@ -20,7 +20,8 @@ choice SPI_NOR_SFDP config SPI_NOR_SFDP_MINIMAL bool "Fixed flash configuration" help - Synthesize a minimal configuration assuming 256 By page size and + Synthesize a minimal configuration assuming 256 By page size (or as + set by the page-size devicetree property) and standard 4 KiBy and 64 KiBy erase instructions. Requires the size and jedec-id properties in the devicetree jedec,spi-nor node. diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index c8438fc847d..ea23d11eb95 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -226,7 +226,7 @@ static inline uint32_t dev_flash_size(const struct device *dev) static inline uint16_t dev_page_size(const struct device *dev) { #ifdef CONFIG_SPI_NOR_SFDP_MINIMAL - return 256; + return DT_INST_PROP_OR(0, page_size, 256); #else /* CONFIG_SPI_NOR_SFDP_MINIMAL */ const struct spi_nor_data *data = dev->data; diff --git a/dts/bindings/mtd/jedec,jesd216.yaml b/dts/bindings/mtd/jedec,jesd216.yaml index fcbc20ec84d..c55440456c2 100644 --- a/dts/bindings/mtd/jedec,jesd216.yaml +++ b/dts/bindings/mtd/jedec,jesd216.yaml @@ -68,3 +68,16 @@ properties: addressing is require to access the full address range, and automatically puts the device into 4-byte address mode when the device is initialized. + + page-size: + type: int + description: | + Number of bytes in a page from JESD216 BFP DW11 + + This property is only used in the CONFIG_SPI_NOR_SFDP_MINIMAL configuration. + It is ignored if the device is configured to use SFDP data + from the sfdp-bfp property (CONFIG_SPI_NOR_SFDP_DEVICETREE) or + if the SFDP parameters are read from the device at + runtime (CONFIG_SPI_NOR_SFDP_RUNTIME). + + The default value is 256 bytes if the value is not specified. From 5ccc0eb319b13760268b33159872424aebf3492a Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 7 Jul 2023 15:27:40 +0900 Subject: [PATCH 2881/4498] soc: arm: add support for Renesas RA4M1 series SoC Add essential support for RA4M1 Series. It only defines `r7fa4m1ab3cfm` currently. Signed-off-by: TOKITA Hiroshi --- dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi | 7 +++ dts/arm/renesas/ra/ra-cm4-common.dtsi | 52 +++++++++++++++++++ dts/arm/renesas/ra/ra4-cm4-common.dtsi | 7 +++ soc/arm/renesas_ra/CMakeLists.txt | 6 +++ soc/arm/renesas_ra/Kconfig | 18 +++++++ soc/arm/renesas_ra/Kconfig.defconfig | 4 ++ soc/arm/renesas_ra/Kconfig.soc | 4 ++ soc/arm/renesas_ra/common/ra_common_soc.h | 18 +++++++ soc/arm/renesas_ra/ra4m1/CMakeLists.txt | 4 ++ .../ra4m1/Kconfig.defconfig.r7fa4m1xxxxxx | 9 ++++ .../renesas_ra/ra4m1/Kconfig.defconfig.series | 14 +++++ soc/arm/renesas_ra/ra4m1/Kconfig.series | 11 ++++ soc/arm/renesas_ra/ra4m1/Kconfig.soc | 11 ++++ soc/arm/renesas_ra/ra4m1/linker.ld | 8 +++ soc/arm/renesas_ra/ra4m1/soc.h | 7 +++ 15 files changed, 180 insertions(+) create mode 100644 dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi create mode 100644 dts/arm/renesas/ra/ra-cm4-common.dtsi create mode 100644 dts/arm/renesas/ra/ra4-cm4-common.dtsi create mode 100644 soc/arm/renesas_ra/CMakeLists.txt create mode 100644 soc/arm/renesas_ra/Kconfig create mode 100644 soc/arm/renesas_ra/Kconfig.defconfig create mode 100644 soc/arm/renesas_ra/Kconfig.soc create mode 100644 soc/arm/renesas_ra/common/ra_common_soc.h create mode 100644 soc/arm/renesas_ra/ra4m1/CMakeLists.txt create mode 100644 soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.r7fa4m1xxxxxx create mode 100644 soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.series create mode 100644 soc/arm/renesas_ra/ra4m1/Kconfig.series create mode 100644 soc/arm/renesas_ra/ra4m1/Kconfig.soc create mode 100644 soc/arm/renesas_ra/ra4m1/linker.ld create mode 100644 soc/arm/renesas_ra/ra4m1/soc.h diff --git a/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi new file mode 100644 index 00000000000..8c1430d7790 --- /dev/null +++ b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi new file mode 100644 index 00000000000..a7c06b440cb --- /dev/null +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4"; + reg = <0>; + }; + }; + + sram0: memory0@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(32)>; + }; + + soc { + fcu: flash-controller@4001c000 { + compatible = "renesas,ra-flash-controller"; + reg = <0x4001c000 0x44>; + reg-names = "fcache"; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash0@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_K(256)>; + }; + + flash1: flash1@40100000 { + compatible = "soc-nv-flash"; + reg = <0x40100000 DT_SIZE_K(8)>; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/renesas/ra/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4-cm4-common.dtsi new file mode 100644 index 00000000000..82d5d48a037 --- /dev/null +++ b/dts/arm/renesas/ra/ra4-cm4-common.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/arm/renesas_ra/CMakeLists.txt b/soc/arm/renesas_ra/CMakeLists.txt new file mode 100644 index 00000000000..b6a22aa757b --- /dev/null +++ b/soc/arm/renesas_ra/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(common) + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/arm/renesas_ra/Kconfig b/soc/arm/renesas_ra/Kconfig new file mode 100644 index 00000000000..628b75a93de --- /dev/null +++ b/soc/arm/renesas_ra/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_RA + bool + +if SOC_FAMILY_RA + +config SOC_FAMILY + string + default "renesas_ra" + +config SERIES_SPECIFIC_SOC_INIT + bool "Use series specific initialize" + +source "soc/arm/renesas_ra/*/Kconfig.soc" + +endif # SOC_FAMILY_RA diff --git a/soc/arm/renesas_ra/Kconfig.defconfig b/soc/arm/renesas_ra/Kconfig.defconfig new file mode 100644 index 00000000000..e5e211a94b3 --- /dev/null +++ b/soc/arm/renesas_ra/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +source "soc/arm/renesas_ra/*/Kconfig.defconfig.series" diff --git a/soc/arm/renesas_ra/Kconfig.soc b/soc/arm/renesas_ra/Kconfig.soc new file mode 100644 index 00000000000..2652ee94d2e --- /dev/null +++ b/soc/arm/renesas_ra/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +source "soc/arm/renesas_ra/*/Kconfig.series" diff --git a/soc/arm/renesas_ra/common/ra_common_soc.h b/soc/arm/renesas_ra/common/ra_common_soc.h new file mode 100644 index 00000000000..60559793743 --- /dev/null +++ b/soc/arm/renesas_ra/common/ra_common_soc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_RENESAS_RA_COMMON_RA_COMMON_SOC_H_ +#define ZEPHYR_SOC_ARM_RENESAS_RA_COMMON_RA_COMMON_SOC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_RENESAS_RA_COMMON_RA_COMMON_SOC_H_ */ diff --git a/soc/arm/renesas_ra/ra4m1/CMakeLists.txt b/soc/arm/renesas_ra/ra4m1/CMakeLists.txt new file mode 100644 index 00000000000..45014584cbb --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# empty diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.r7fa4m1xxxxxx b/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.r7fa4m1xxxxxx new file mode 100644 index 00000000000..c138e20d85c --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.r7fa4m1xxxxxx @@ -0,0 +1,9 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if SOC_R7FA4M1AB3CFM + +config SOC + default "r7fa4m1ab3cfm" + +endif # SOC_R7FA4M1AB3CFM diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.series b/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.series new file mode 100644 index 00000000000..99e8e3f639d --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.defconfig.series @@ -0,0 +1,14 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RA4M1 + +rsource "Kconfig.defconfig.r7fa4*" + +config SOC_SERIES + default "ra4m1" + +config NUM_IRQS + default 32 + +endif # SOC_SERIES_RA4M1 diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.series b/soc/arm/renesas_ra/ra4m1/Kconfig.series new file mode 100644 index 00000000000..5d958f2a898 --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA4M1 + bool "Renesas RA4M1" + select ARM + select CPU_CORTEX_M4 + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M_HAS_SYSTICK + select SOC_FAMILY_RA + select XIP diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.soc b/soc/arm/renesas_ra/ra4m1/Kconfig.soc new file mode 100644 index 00000000000..a7b402fd291 --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "Renesas RA4M1 SoC Selection" + depends on SOC_SERIES_RA4M1 + +config SOC_R7FA4M1AB3CFM + bool "R7FA4M1AB3CFM" + +endchoice diff --git a/soc/arm/renesas_ra/ra4m1/linker.ld b/soc/arm/renesas_ra/ra4m1/linker.ld new file mode 100644 index 00000000000..44d5ee51889 --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/linker.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include diff --git a/soc/arm/renesas_ra/ra4m1/soc.h b/soc/arm/renesas_ra/ra4m1/soc.h new file mode 100644 index 00000000000..127ee9ab444 --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/soc.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../common/ra_common_soc.h" From 1741b3a356fadfb01f1375b08cadb7b8e395bfb4 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Thu, 20 Jul 2023 01:50:00 +0900 Subject: [PATCH 2882/4498] drivers: clock_control: Add clock driver for Renesas RA series Add initial support for Renesas RA clock generation circuit. It returns a fixed value to simplify the first commit to get the UART working now. Signed-off-by: TOKITA Hiroshi --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.ra | 9 + drivers/clock_control/clock_control_ra.c | 306 ++++++++++++++++++ dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi | 1 + dts/arm/renesas/ra/ra-cm4-common.dtsi | 61 ++++ .../renesas,ra-clock-generation-circuit.yaml | 46 +++ .../dt-bindings/clock/r7fa4m1xxxxxx-clock.h | 12 + .../zephyr/dt-bindings/clock/renesas-ra-cgc.h | 64 ++++ soc/arm/renesas_ra/ra4m1/Kconfig.series | 1 + 10 files changed, 503 insertions(+) create mode 100644 drivers/clock_control/Kconfig.ra create mode 100644 drivers/clock_control/clock_control_ra.c create mode 100644 dts/bindings/clock/renesas,ra-clock-generation-circuit.yaml create mode 100644 include/zephyr/dt-bindings/clock/r7fa4m1xxxxxx-clock.h create mode 100644 include/zephyr/dt-bindings/clock/renesas-ra-cgc.h diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 8a8d7fbb61a..8b246b55e38 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SAM clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_control_smartbond.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RA clock_control_ra.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index f4647930ae3..3ff554e684a 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -80,4 +80,6 @@ source "drivers/clock_control/Kconfig.nxp_s32" source "drivers/clock_control/Kconfig.agilex5" +source "drivers/clock_control/Kconfig.ra" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.ra b/drivers/clock_control/Kconfig.ra new file mode 100644 index 00000000000..2b4aea0fb81 --- /dev/null +++ b/drivers/clock_control/Kconfig.ra @@ -0,0 +1,9 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_RA + bool "Renesas RA series clock generation circuit driver" + default y + depends on DT_HAS_RENESAS_RA_CLOCK_GENERATION_CIRCUIT_ENABLED + help + Enable Renesas RA series clock generation circuit driver. diff --git a/drivers/clock_control/clock_control_ra.c b/drivers/clock_control/clock_control_ra.c new file mode 100644 index 00000000000..b1008e3bf83 --- /dev/null +++ b/drivers/clock_control/clock_control_ra.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define DT_DRV_COMPAT renesas_ra_clock_generation_circuit + +#include +#include +#include +#include + +#if DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, pll)) +#define SYSCLK_SRC pll +#elif DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, mosc)) +#define SYSCLK_SRC moco +#elif DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, sosc)) +#define SYSCLK_SRC soco +#elif DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, hoco)) +#define SYSCLK_SRC hoco +#elif DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, moco)) +#define SYSCLK_SRC moco +#elif DT_SAME_NODE(DT_INST_PROP(0, clock_source), DT_PATH(clocks, loco)) +#define SYSCLK_SRC loco +#else +#error Unknown clock source +#endif + +#define FREQ_iclk (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, iclk_div)) +#define FREQ_pclka (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, pclka_div)) +#define FREQ_pclkb (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, pclkb_div)) +#define FREQ_pclkc (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, pclkc_div)) +#define FREQ_pclkd (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, pclkd_div)) +#define FREQ_fclk (clock_freqs[_CONCAT(SCRSCK_, SYSCLK_SRC)] / DT_INST_PROP(0, fclk_div)) + +#define CLKSRC_FREQ(clk) DT_PROP(DT_PATH(clocks, clk), clock_frequency) + +#define IS_CLKSRC_ENABLED(clk) DT_NODE_HAS_STATUS(DT_PATH(clocks, clk), okay) + +#define SCKSCR_INIT_VALUE _CONCAT(CLKSRC_, SYSCLK_SRC) + +#define SCKDIV_ENABLED(clk) DT_INST_NODE_HAS_PROP(0, clk##_div) +#define SCKDIV_VAL(clk) _CONCAT(SCKDIV_, DT_INST_PROP(0, clk##_div)) +#define SCKDIV_POS(clk) _CONCAT(SCKDIV_POS_, clk) + +#define SCKDIVCR_BITS(clk) \ + COND_CODE_1(SCKDIV_ENABLED(clk), ((SCKDIV_VAL(clk) & 0xFU) << SCKDIV_POS(clk)), (0U)) + +#define SCKDIVCR_INIT_VALUE \ + (SCKDIVCR_BITS(iclk) | SCKDIVCR_BITS(pclka) | SCKDIVCR_BITS(pclkb) | \ + SCKDIVCR_BITS(pclkc) | SCKDIVCR_BITS(pclkd) | SCKDIVCR_BITS(bclk) | SCKDIVCR_BITS(fclk)) + +#define HOCOWTCR_INIT_VALUE (6) + +/* + * Required cycles for sub-clokc stabilizing. + */ +#define SUBCLK_STABILIZE_CYCLES 5 + +extern int z_clock_hw_cycles_per_sec; + +enum { + CLKSRC_hoco = 0, + CLKSRC_moco, + CLKSRC_loco, + CLKSRC_mosc, + CLKSRC_sosc, + CLKSRC_pll, +}; + +enum { + SCKDIV_1 = 0, + SCKDIV_2, + SCKDIV_4, + SCKDIV_8, + SCKDIV_16, + SCKDIV_32, + SCKDIV_64, + SCKDIV_128, + SCKDIV_3, + SCKDIV_6, + SCKDIV_12 +}; + +enum { + SCKDIV_POS_pclkd = 0x0U, + SCKDIV_POS_pclkc = 0x4U, + SCKDIV_POS_pclkb = 0x8U, + SCKDIV_POS_pclka = 0xcU, + SCKDIV_POS_bclk = 0x10U, + SCKDIV_POS_pclke = 0x14U, + SCKDIV_POS_iclk = 0x18U, + SCKDIV_POS_fclk = 0x1cU +}; + +enum { + OSCSF_HOCOSF_POS = 0, + OSCSF_MOSCSF_POS = 3, + OSCSF_PLLSF_POS = 5, +}; + +enum { + OPCCR_OPCMTSF_POS = 4, +}; + +static const uint32_t PRCR_KEY = 0xA500U; +static const uint32_t PRCR_CLOCKS = 0x1U; +static const uint32_t PRCR_LOW_POWER = 0x2U; + +enum { +#if DT_INST_REG_SIZE_BY_NAME(0, mstp) == 16 + MSTPCRA_OFFSET = -0x4, +#else + MSTPCRA_OFFSET = 0x0, +#endif + MSTPCRB_OFFSET = (MSTPCRA_OFFSET + 0x4), + MSTPCRC_OFFSET = (MSTPCRB_OFFSET + 0x4), + MSTPCRD_OFFSET = (MSTPCRC_OFFSET + 0x4), + MSTPCRE_OFFSET = (MSTPCRD_OFFSET + 0x4), +}; + +enum { + SCKDIVCR_OFFSET = 0x021, + SCKSCR_OFFSET = 0x026, + MEMWAIT_OFFSET = 0x031, + MOSCCR_OFFSET = 0x032, + HOCOCR_OFFSET = 0x036, + OSCSF_OFFSET = 0x03C, + CKOCR_OFFSET = 0x03E, + OPCCR_OFFSET = 0x0A0, + HOCOWTCR_OFFSET = 0x0A5, + PRCR_OFFSET = 0x3FE, + SOSCCR_OFFSET = 0x480, +}; + +enum { + SCRSCK_hoco, + SCRSCK_moco, + SCRSCK_loco, + SCRSCK_mosc, + SCRSCK_sosc, + SCRSCK_pll, +}; + +static const int clock_freqs[] = { + COND_CODE_1(IS_CLKSRC_ENABLED(hoco), (CLKSRC_FREQ(hoco)), (0)), + COND_CODE_1(IS_CLKSRC_ENABLED(moco), (CLKSRC_FREQ(moco)), (0)), + COND_CODE_1(IS_CLKSRC_ENABLED(loco), (CLKSRC_FREQ(loco)), (0)), + COND_CODE_1(IS_CLKSRC_ENABLED(mosc), (CLKSRC_FREQ(mosc)), (0)), + COND_CODE_1(IS_CLKSRC_ENABLED(sosc), (CLKSRC_FREQ(sosc)), (0)), + COND_CODE_1(IS_CLKSRC_ENABLED(pll), + (DT_PROP(DT_PHANDLE_BY_IDX(DT_PATH(clocks, pll), clocks, 0), clock_frequency) * + DT_PROP(DT_PATH(clocks, pll), clock_mult) / + DT_PROP(DT_PATH(clocks, pll), clock_div)), + (0)), +}; + +static uint32_t MSTP_read(size_t offset) +{ + return sys_read32(DT_INST_REG_ADDR_BY_NAME(0, mstp) + offset); +} + +static void MSTP_write(size_t offset, uint32_t value) +{ + sys_write32(value, DT_INST_REG_ADDR_BY_NAME(0, mstp) + offset); +} + +static uint8_t SYSTEM_read8(size_t offset) +{ + return sys_read8(DT_INST_REG_ADDR_BY_NAME(0, system) + offset); +} + +static void SYSTEM_write8(size_t offset, uint8_t value) +{ + sys_write8(value, DT_INST_REG_ADDR_BY_NAME(0, system) + offset); +} + +static void SYSTEM_write16(size_t offset, uint16_t value) +{ + sys_write16(value, DT_INST_REG_ADDR_BY_NAME(0, system) + offset); +} + +static void SYSTEM_write32(size_t offset, uint32_t value) +{ + sys_write32(value, DT_INST_REG_ADDR_BY_NAME(0, system) + offset); +} + +static int clock_control_ra_on(const struct device *dev, clock_control_subsys_t subsys) +{ + uint32_t clkid = (uint32_t)subsys; + int lock = irq_lock(); + + MSTP_write(MSTPCRA_OFFSET + RA_CLOCK_GROUP(clkid), + MSTP_read(MSTPCRB_OFFSET) & ~RA_CLOCK_BIT(clkid)); + irq_unlock(lock); + + return 0; +} + +static int clock_control_ra_off(const struct device *dev, clock_control_subsys_t subsys) +{ + uint32_t clkid = (uint32_t)subsys; + int lock = irq_lock(); + + MSTP_write(MSTPCRA_OFFSET + RA_CLOCK_GROUP(clkid), + MSTP_read(MSTPCRB_OFFSET) | RA_CLOCK_BIT(clkid)); + irq_unlock(lock); + + return 0; +} + +static int clock_control_ra_get_rate(const struct device *dev, clock_control_subsys_t subsys, + uint32_t *rate) +{ + uint32_t clkid = (uint32_t)subsys; + + switch (clkid & 0xFFFFFF00) { + case RA_CLOCK_SCI(0): + *rate = FREQ_pclka; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct clock_control_driver_api ra_clock_control_driver_api = { + .on = clock_control_ra_on, + .off = clock_control_ra_off, + .get_rate = clock_control_ra_get_rate, +}; + +static void crude_busy_loop_impl(uint32_t cycles) +{ + __asm__ volatile(".align 8\n" + "busy_loop:\n" + " sub r0, r0, #1\n" + " cmp r0, #0\n" + " bne.n busy_loop\n"); +} + +static inline void crude_busy_loop(uint32_t wait_us) +{ + static const uint64_t cycles_per_loop = 4; + + crude_busy_loop_impl(sys_clock_hw_cycles_per_sec() * wait_us / USEC_PER_SEC / + cycles_per_loop); +} + +static int clock_control_ra_init(const struct device *dev) +{ + uint8_t sysclk = SYSTEM_read8(SCKSCR_OFFSET); + + z_clock_hw_cycles_per_sec = clock_freqs[sysclk]; + + SYSTEM_write16(PRCR_OFFSET, PRCR_KEY | PRCR_CLOCKS | PRCR_LOW_POWER); + + if (clock_freqs[SCRSCK_hoco] == 64000000) { + SYSTEM_write8(HOCOWTCR_OFFSET, HOCOWTCR_INIT_VALUE); + } + + SYSTEM_write8(SOSCCR_OFFSET, !IS_CLKSRC_ENABLED(sosc)); + SYSTEM_write8(MOSCCR_OFFSET, !IS_CLKSRC_ENABLED(mosc)); + SYSTEM_write8(HOCOCR_OFFSET, !IS_CLKSRC_ENABLED(hoco)); + + if (IS_CLKSRC_ENABLED(sosc)) { + crude_busy_loop(z_clock_hw_cycles_per_sec / clock_freqs[CLKSRC_sosc] * + SUBCLK_STABILIZE_CYCLES); + } + + if (IS_CLKSRC_ENABLED(mosc)) { + while ((SYSTEM_read8(OSCSF_OFFSET) & BIT(OSCSF_MOSCSF_POS)) != + BIT(OSCSF_MOSCSF_POS)) { + ; + } + } + + if (IS_CLKSRC_ENABLED(hoco)) { + while ((SYSTEM_read8(OSCSF_OFFSET) & BIT(OSCSF_HOCOSF_POS)) != + BIT(OSCSF_HOCOSF_POS)) { + ; + } + } + + SYSTEM_write32(SCKDIVCR_OFFSET, SCKDIVCR_INIT_VALUE); + SYSTEM_write8(SCKSCR_OFFSET, SCKSCR_INIT_VALUE); + + z_clock_hw_cycles_per_sec = clock_freqs[sysclk]; + + SYSTEM_write8(OPCCR_OFFSET, 0); + while ((SYSTEM_read8(OPCCR_OFFSET) & BIT(OPCCR_OPCMTSF_POS)) != 0) { + ; + } + + SYSTEM_write8(MEMWAIT_OFFSET, 1); + SYSTEM_write16(PRCR_OFFSET, PRCR_KEY | PRCR_CLOCKS | PRCR_LOW_POWER); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, &clock_control_ra_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &ra_clock_control_driver_api); diff --git a/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi index 8c1430d7790..b35206526c3 100644 --- a/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi +++ b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi @@ -4,4 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi index a7c06b440cb..3067ff20f82 100644 --- a/dts/arm/renesas/ra/ra-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -20,12 +20,73 @@ }; }; + clocks { + mosc: mosc { + compatible = "fixed-clock"; + clock-frequency = <1200000>; + status = "disabled"; + #clock-cells = <0>; + }; + + sosc: sosc { + compatible = "fixed-clock"; + clock-frequency = <32768>; + status = "disabled"; + #clock-cells = <0>; + }; + + hoco: hoco { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + status = "disabled"; + #clock-cells = <0>; + }; + + moco: moco { + compatible = "fixed-clock"; + clock-frequency = <8000000>; + status = "disabled"; + #clock-cells = <0>; + }; + + loco: loco { + compatible = "fixed-clock"; + clock-frequency = <32768>; + status = "disabled"; + #clock-cells = <0>; + }; + + pll: pll { + compatible = "fixed-factor-clock"; + status = "disabled"; + clocks = <&mosc>; + clock-div = <2>; + clock-mult = <8>; + #clock-cells = <0>; + }; + }; + sram0: memory0@20000000 { compatible = "mmio-sram"; reg = <0x20000000 DT_SIZE_K(32)>; }; soc { + cgc: cgc@4001e000 { + compatible = "renesas,ra-clock-generation-circuit"; + reg = <0x4001e000 0x40 0x40047000 0x10>; + reg-names = "system", "mstp"; + #clock-cells = <1>; + + clock-source = <&moco>; + iclk-div = <16>; + pclka-div = <16>; + pclkb-div = <16>; + pclkc-div = <16>; + pclkd-div = <16>; + fclk-div = <16>; + }; + fcu: flash-controller@4001c000 { compatible = "renesas,ra-flash-controller"; reg = <0x4001c000 0x44>; diff --git a/dts/bindings/clock/renesas,ra-clock-generation-circuit.yaml b/dts/bindings/clock/renesas,ra-clock-generation-circuit.yaml new file mode 100644 index 00000000000..07b244ea79d --- /dev/null +++ b/dts/bindings/clock/renesas,ra-clock-generation-circuit.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA series Clock Generation Circuit + +compatible: "renesas,ra-clock-generation-circuit" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + iclk-div: + type: int + description: Division factor for ICLK + + fclk-div: + type: int + description: Division factor for FCLK + + pclka-div: + type: int + description: Division factor for PCLKA + + pclkb-div: + type: int + description: Division factor for PCLKB + + pclkc-div: + type: int + description: Division factor for PCLKC + + pclkd-div: + type: int + description: Division factor for PCLKD + + clock-source: + type: phandle + description: System clock sorce + + "#clock-cells": + const: 1 + +clock-cells: + - id diff --git a/include/zephyr/dt-bindings/clock/r7fa4m1xxxxxx-clock.h b/include/zephyr/dt-bindings/clock/r7fa4m1xxxxxx-clock.h new file mode 100644 index 00000000000..355c4982a3d --- /dev/null +++ b/include/zephyr/dt-bindings/clock/r7fa4m1xxxxxx-clock.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_BINDINGS_CLOCK_R7FA4M1XXXXXX_CLOCK_H_ +#define ZEPHYR_DT_BINDINGS_CLOCK_R7FA4M1XXXXXX_CLOCK_H_ + +#include + +#endif /* ZEPHYR_DT_BINDINGS_CLOCK_R7FA4M1XXXXXX_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/renesas-ra-cgc.h b/include/zephyr/dt-bindings/clock/renesas-ra-cgc.h new file mode 100644 index 00000000000..31bb65ecc45 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/renesas-ra-cgc.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_BINDINGS_CLOCK_RENESAS_RA_CGC_H_ +#define ZEPHYR_DT_BINDINGS_CLOCK_RENESAS_RA_CGC_H_ + +#define RA_CLOCK(grp, func, ch) ((grp << 28) | (func << 20) | ch) + +#define RA_CLOCK_GROUP(mod) (((mod >> 28) & 0xF) * 4) +#define RA_CLOCK_BIT(mod) BIT(((mod >> 20) & 0xFF) - ((mod >> 0) & 0xF)) + +#define RA_CLOCK_DMAC(channel) RA_CLOCK(0, 22, channel) +#define RA_CLOCK_DTC(channel) RA_CLOCK(0, 22, channel) +#define RA_CLOCK_CAN(channel) RA_CLOCK(1, 2, channel) +#define RA_CLOCK_CEC(channel) RA_CLOCK(1, 3U, channel) +#define RA_CLOCK_I3C(channel) RA_CLOCK(1, 4U, channel) +#define RA_CLOCK_IRDA(channel) RA_CLOCK(1, 5U, channel) +#define RA_CLOCK_QSPI(channel) RA_CLOCK(1, 6U, channel) +#define RA_CLOCK_IIC(channel) RA_CLOCK(1, 9U, channel) +#define RA_CLOCK_USBFS(channel) RA_CLOCK(1, 11U, channel) +#define RA_CLOCK_USBHS(channel) RA_CLOCK(1, 12U, channel) +#define RA_CLOCK_EPTPC(channel) RA_CLOCK(1, 13U, channel) +#define RA_CLOCK_ETHER(channel) RA_CLOCK(1, 15U, channel) +#define RA_CLOCK_OSPI(channel) RA_CLOCK(1, 16U, channel) +#define RA_CLOCK_SPI(channel) RA_CLOCK(1, 19U, channel) +#define RA_CLOCK_SCI(channel) RA_CLOCK(1, 31U, channel) +#define RA_CLOCK_CAC(channel) RA_CLOCK(2, 0U, channel) +#define RA_CLOCK_CRC(channel) RA_CLOCK(2, 1U, channel) +#define RA_CLOCK_PDC(channel) RA_CLOCK(2, 2U, channel) +#define RA_CLOCK_CTSU(channel) RA_CLOCK(2, 3U, channel) +#define RA_CLOCK_SLCDC(channel) RA_CLOCK(2, 4U, channel) +#define RA_CLOCK_GLCDC(channel) RA_CLOCK(2, 4U, channel) +#define RA_CLOCK_JPEG(channel) RA_CLOCK(2, 5U, channel) +#define RA_CLOCK_DRW(channel) RA_CLOCK(2, 6U, channel) +#define RA_CLOCK_SSI(channel) RA_CLOCK(2, 8U, channel) +#define RA_CLOCK_SRC(channel) RA_CLOCK(2, 9U, channel) +#define RA_CLOCK_SDHIMMC(channel) RA_CLOCK(2, 12U, channel) +#define RA_CLOCK_DOC(channel) RA_CLOCK(2, 13U, channel) +#define RA_CLOCK_ELC(channel) RA_CLOCK(2, 14U, channel) +#define RA_CLOCK_CEU(channel) RA_CLOCK(2, 16U, channel) +#define RA_CLOCK_TFU(channel) RA_CLOCK(2, 20U, channel) +#define RA_CLOCK_IIRFA(channel) RA_CLOCK(2, 21U, channel) +#define RA_CLOCK_CANFD(channel) RA_CLOCK(2, 27U, channel) +#define RA_CLOCK_TRNG(channel) RA_CLOCK(2, 28U, channel) +#define RA_CLOCK_SCE(channel) RA_CLOCK(2, 31U, channel) +#define RA_CLOCK_AES(channel) RA_CLOCK(2, 31U, channel) +#define RA_CLOCK_POEG(channel) RA_CLOCK(3, 14U, channel) +#define RA_CLOCK_ADC(channel) RA_CLOCK(3, 16U, channel) +#define RA_CLOCK_SDADC(channel) RA_CLOCK(3, 17U, channel) +#define RA_CLOCK_DAC8(channel) RA_CLOCK(3, 19U, channel) +#define RA_CLOCK_DAC(channel) RA_CLOCK(3, 20U, channel) +#define RA_CLOCK_TSN(channel) RA_CLOCK(3, 22U, channel) +#define RA_CLOCK_ACMPHS(channel) RA_CLOCK(3, 28U, channel) +#define RA_CLOCK_ACMPLP(channel) RA_CLOCK(3, 29U, channel) +#define RA_CLOCK_OPAMP(channel) RA_CLOCK(3, 31U, channel) +#define RA_CLOCK_AGT(channel) RA_CLOCK(4, 3U, channel) +#define RA_CLOCK_KEY(channel) RA_CLOCK(4, 4U, channel) +#define RA_CLOCK_ULPT(channel) RA_CLOCK(4, 9U, channel) +#define RA_CLOCK_GPT(channel) RA_CLOCK(5, 31U, channel) + +#endif /* ZEPHYR_DT_BINDINGS_CLOCK_RENESAS_RA_CGC_H_ */ diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.series b/soc/arm/renesas_ra/ra4m1/Kconfig.series index 5d958f2a898..a3c1aaf2a2e 100644 --- a/soc/arm/renesas_ra/ra4m1/Kconfig.series +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.series @@ -8,4 +8,5 @@ config SOC_SERIES_RA4M1 select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_SYSTICK select SOC_FAMILY_RA + select TIMER_READS_ITS_FREQUENCY_AT_RUNTIME select XIP From 04b723e900e6efefa2fd9e88011c66079da32c4e Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 8 Jul 2023 16:29:00 +0900 Subject: [PATCH 2883/4498] drivers: pinctrl: Add pinctrl driver for Renesas RA series To avoid complicating the initial code for supporting the SoC, I have implemented only the bare minimum for now. Signed-off-by: TOKITA Hiroshi --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.ra | 9 + drivers/pinctrl/pinctrl_ra.c | 83 ++++ dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi | 4 + dts/arm/renesas/ra/ra-cm4-common.dtsi | 7 + dts/bindings/pinctrl/renesas,ra-pinctrl.yaml | 26 ++ .../pinctrl/renesas/pinctrl-r7fa4m1xxxxxx.h | 437 ++++++++++++++++++ .../pinctrl/renesas/pinctrl-ra-common.h | 46 ++ soc/arm/renesas_ra/common/pinctrl_ra.h | 93 ++++ soc/arm/renesas_ra/ra4m1/pinctrl_soc.h | 7 + 11 files changed, 714 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.ra create mode 100644 drivers/pinctrl/pinctrl_ra.c create mode 100644 dts/bindings/pinctrl/renesas,ra-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-r7fa4m1xxxxxx.h create mode 100644 include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra-common.h create mode 100644 soc/arm/renesas_ra/common/pinctrl_ra.h create mode 100644 soc/arm/renesas_ra/ra4m1/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index c46cf3691f7..30b9f96eefc 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -35,3 +35,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 164cbd11089..b7dc6c2fa69 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -64,5 +64,6 @@ source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" +source "drivers/pinctrl/Kconfig.ra" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.ra b/drivers/pinctrl/Kconfig.ra new file mode 100644 index 00000000000..6ad0ebd8c06 --- /dev/null +++ b/drivers/pinctrl/Kconfig.ra @@ -0,0 +1,9 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_RA + bool "Renesas RA series pin controller driver" + default y + depends on DT_HAS_RENESAS_RA_PINCTRL_ENABLED + help + Enable Renesas RA series pin controller driver. diff --git a/drivers/pinctrl/pinctrl_ra.c b/drivers/pinctrl/pinctrl_ra.c new file mode 100644 index 00000000000..54aa881748c --- /dev/null +++ b/drivers/pinctrl/pinctrl_ra.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define DT_DRV_COMPAT renesas_ra_pinctrl + +#define PORT_NUM 15 +#define PIN_NUM 16 + +enum { + PWPR_PFSWE_POS = 6, + PWPR_B0WI_POS = 7, +}; + +static inline uint32_t pinctrl_ra_read_PmnFPS(size_t port, size_t pin) +{ + return sys_read32(DT_INST_REG_ADDR_BY_NAME(0, pfs) + (port * PIN_NUM + pin) * 4); +} + +static inline void pinctrl_ra_write_PmnFPS(size_t port, size_t pin, uint32_t value) +{ + sys_write32(value, DT_INST_REG_ADDR_BY_NAME(0, pfs) + (port * PIN_NUM + pin) * 4); +} + +static inline uint32_t pinctrl_ra_read_PMISC_PWPR(size_t port, size_t pin) +{ + return sys_read32(DT_INST_REG_ADDR_BY_NAME(0, pmisc_pwpr)); +} + +static inline void pinctrl_ra_write_PMISC_PWPR(uint32_t value) +{ + sys_write32(value, DT_INST_REG_ADDR_BY_NAME(0, pmisc_pwpr)); +} + +static void pinctrl_ra_configure_pfs(const pinctrl_soc_pin_t *pinc) +{ + pinctrl_soc_pin_t pincfg; + + memcpy(&pincfg, pinc, sizeof(pinctrl_soc_pin_t)); + pincfg.pin = 0; + pincfg.port = 0; + + /* Clear PMR bits before configuring */ + if ((pincfg.config & PmnPFS_PMR_POS)) { + uint32_t val = pinctrl_ra_read_PmnFPS(pinc->port, pinc->pin); + + pinctrl_ra_write_PmnFPS(pinc->port, pinc->pin, val & ~(BIT(PmnPFS_PMR_POS))); + pinctrl_ra_write_PmnFPS(pinc->port, pinc->pin, pincfg.config & ~PmnPFS_PMR_POS); + } + + pinctrl_ra_write_PmnFPS(pinc->port, pinc->pin, pincfg.config); +} + +int pinctrl_ra_query_config(uint32_t port, uint32_t pin, struct pinctrl_ra_pin *const pincfg) +{ + if (port >= PORT_NUM || pin >= PIN_NUM) { + return -EINVAL; + } + + pincfg->config = pinctrl_ra_read_PmnFPS(port, pin); + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + pinctrl_ra_write_PMISC_PWPR(0); + pinctrl_ra_write_PMISC_PWPR(BIT(PWPR_PFSWE_POS)); + + for (int i = 0; i < pin_cnt; i++) { + pinctrl_ra_configure_pfs(&pins[i]); + } + + pinctrl_ra_write_PMISC_PWPR(0); + pinctrl_ra_write_PMISC_PWPR(BIT(PWPR_B0WI_POS)); + + return 0; +} diff --git a/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi index b35206526c3..4836a58a0af 100644 --- a/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi +++ b/dts/arm/renesas/ra/r7fa4m1ab3cfm.dtsi @@ -4,5 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define RA_SOC_PINS 64 +#define RA_SOC_HAS_MSTPCRE 1 +#define RA_SOC_MSTPD5_CHANNELS 1 + #include #include diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi index 3067ff20f82..c7986521a07 100644 --- a/dts/arm/renesas/ra/ra-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -105,6 +105,13 @@ reg = <0x40100000 DT_SIZE_K(8)>; }; }; + + pinctrl: pinctrl@40040800 { + compatible = "renesas,ra-pinctrl"; + reg = <0x40040800 0x500 0x40040d03 0x1>; + reg-names = "pfs", "pmisc_pwpr"; + status = "okay"; + }; }; }; diff --git a/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml b/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml new file mode 100644 index 00000000000..e3f0cd03b6c --- /dev/null +++ b/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + Renesas RA series pin controller + +compatible: "renesas,ra-pinctrl" + +include: base.yaml + +child-binding: + description: | + Definitions for a pinctrl state. + child-binding: + + include: + - name: pincfg-node.yaml + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. Each + element of the array is an integer constructed from the + pin number and the alternative function of the pin. diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-r7fa4m1xxxxxx.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-r7fa4m1xxxxxx.h new file mode 100644 index 00000000000..dfe21b00183 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-r7fa4m1xxxxxx.h @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_R7FA4M1XXXXXX_H_ +#define ZEPHYR_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_R7FA4M1XXXXXX_H_ + +#include + +#define P000_AMP0P RA_PINCFG__40(0, 0, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P000_AN000 RA_PINCFG__40(0, 0, 0x01, RA_PINCFG_ANALOG) +#define P000_TS21 RA_PINCFG__40(0, 0, 0x0C, RA_PINCFG_FUNC) +#define P001_AMP0M RA_PINCFG__40(0, 1, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P001_AN001 RA_PINCFG__40(0, 1, 0x01, RA_PINCFG_ANALOG) +#define P001_TS22 RA_PINCFG__40(0, 1, 0x0C, RA_PINCFG_FUNC) +#define P002_AMP0O RA_PINCFG__48(0, 2, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P002_AN002 RA_PINCFG__48(0, 2, 0x01, RA_PINCFG_ANALOG) +#define P003_AMP1O RA_PINCFG__64(0, 3, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P003_AN003 RA_PINCFG__64(0, 3, 0x01, RA_PINCFG_ANALOG) +#define P004_AMP2O RA_PINCFG__64(0, 4, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P004_AN004 RA_PINCFG__64(0, 4, 0x01, RA_PINCFG_ANALOG) +#define P005_AMP3P RA_PINCFG_100(0, 5, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P005_AN011 RA_PINCFG_100(0, 5, 0x01, RA_PINCFG_ANALOG) +#define P006_AMP3M RA_PINCFG_100(0, 6, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P006_AN012 RA_PINCFG_100(0, 6, 0x01, RA_PINCFG_ANALOG) +#define P007_AMP3O RA_PINCFG_100(0, 7, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P007_AN013 RA_PINCFG_100(0, 7, 0x01, RA_PINCFG_ANALOG) +#define P008_AN014 RA_PINCFG_100(0, 8, 0x01, RA_PINCFG_ANALOG) +#define P010_AMP2M RA_PINCFG__40(0, 0, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P010_AN005 RA_PINCFG__40(0, 0, 0x01, RA_PINCFG_ANALOG) +#define P010_TS30 RA_PINCFG__40(0, 0, 0x0C, RA_PINCFG_FUNC) +#define P010_VREFH0 RA_PINCFG__40(0, 0, 0x03, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P011_AN006 RA_PINCFG__40(0, 1, 0x01, RA_PINCFG_ANALOG) +#define P011_TS31 RA_PINCFG__40(0, 1, 0x0C, RA_PINCFG_FUNC) +#define P011_VREFL0 RA_PINCFG__40(0, 1, 0x03, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P012_AN007 RA_PINCFG__40(0, 2, 0x01, RA_PINCFG_ANALOG) +#define P012_VREFH RA_PINCFG__40(0, 2, 0x03, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P013_AN008 RA_PINCFG__40(0, 3, 0x01, RA_PINCFG_ANALOG) +#define P013_VREFL RA_PINCFG__40(0, 3, 0x03, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P014_AN009 RA_PINCFG__40(0, 4, 0x01, RA_PINCFG_ANALOG) +#define P014_DA0 RA_PINCFG__40(0, 4, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P015_AN010 RA_PINCFG__40(0, 5, 0x01, RA_PINCFG_ANALOG) +#define P015_TS28 RA_PINCFG__40(0, 5, 0x0C, RA_PINCFG_FUNC) +#define P100_AGTIO0 RA_PINCFG__40(1, 0, 0x01, RA_PINCFG_FUNC) +#define P100_AN022 RA_PINCFG__40(1, 0, 0x01, RA_PINCFG_ANALOG) +#define P100_CMPIN0 RA_PINCFG__40(1, 0, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P100_GTETRGA RA_PINCFG__40(1, 0, 0x02, RA_PINCFG_FUNC) +#define P100_GTIOC5B RA_PINCFG__40(1, 0, 0x03, RA_PINCFG_FUNC) +#define P100_KR00 RA_PINCFG__40(1, 0, 0x08, RA_PINCFG_FUNC) +#define P100_MISO0 RA_PINCFG__40(1, 0, 0x04, RA_PINCFG_FUNC) +#define P100_MISOA RA_PINCFG__40(1, 0, 0x06, RA_PINCFG_FUNC) +#define P100_RXD0 RA_PINCFG__40(1, 0, 0x04, RA_PINCFG_FUNC) +#define P100_SCK1 RA_PINCFG__40(1, 0, 0x05, RA_PINCFG_FUNC) +#define P100_SCL0 RA_PINCFG__40(1, 0, 0x04, RA_PINCFG_FUNC) +#define P100_SCL1 RA_PINCFG__40(1, 0, 0x07, RA_PINCFG_FUNC) +#define P100_VL1 RA_PINCFG__40(1, 0, 0x0D, RA_PINCFG_FUNC) +#define P101_AGTEE0 RA_PINCFG__40(1, 1, 0x01, RA_PINCFG_FUNC) +#define P101_AN021 RA_PINCFG__40(1, 1, 0x01, RA_PINCFG_ANALOG) +#define P101_CMPREF0 RA_PINCFG__40(1, 1, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P101_CTS1_RTS1 RA_PINCFG__40(1, 1, 0x05, RA_PINCFG_FUNC) +#define P101_GTETRGB RA_PINCFG__40(1, 1, 0x02, RA_PINCFG_FUNC) +#define P101_GTIOC5A RA_PINCFG__40(1, 1, 0x03, RA_PINCFG_FUNC) +#define P101_KR01 RA_PINCFG__40(1, 1, 0x08, RA_PINCFG_FUNC) +#define P101_MOSI0 RA_PINCFG__40(1, 1, 0x04, RA_PINCFG_FUNC) +#define P101_MOSIA RA_PINCFG__40(1, 1, 0x06, RA_PINCFG_FUNC) +#define P101_SDA0 RA_PINCFG__40(1, 1, 0x04, RA_PINCFG_FUNC) +#define P101_SDA1 RA_PINCFG__40(1, 1, 0x07, RA_PINCFG_FUNC) +#define P101_SS1 RA_PINCFG__40(1, 1, 0x05, RA_PINCFG_FUNC) +#define P101_TXD0 RA_PINCFG__40(1, 1, 0x04, RA_PINCFG_FUNC) +#define P101_VL2 RA_PINCFG__40(1, 1, 0x0D, RA_PINCFG_FUNC) +#define P102_ADTRG0 RA_PINCFG__40(1, 2, 0x0A, RA_PINCFG_FUNC) +#define P102_AGTO0 RA_PINCFG__40(1, 2, 0x01, RA_PINCFG_FUNC) +#define P102_AN020 RA_PINCFG__40(1, 2, 0x01, RA_PINCFG_ANALOG) +#define P102_CMPIN1 RA_PINCFG__40(1, 2, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P102_CRX0 RA_PINCFG__40(1, 2, 0x10, RA_PINCFG_FUNC) +#define P102_GTIOC2B RA_PINCFG__40(1, 2, 0x03, RA_PINCFG_FUNC) +#define P102_GTOWLO RA_PINCFG__40(1, 2, 0x02, RA_PINCFG_FUNC) +#define P102_KR02 RA_PINCFG__40(1, 2, 0x08, RA_PINCFG_FUNC) +#define P102_MOSI2 RA_PINCFG__40(1, 2, 0x05, RA_PINCFG_FUNC) +#define P102_RSPCKA RA_PINCFG__40(1, 2, 0x06, RA_PINCFG_FUNC) +#define P102_SCK0 RA_PINCFG__40(1, 2, 0x04, RA_PINCFG_FUNC) +#define P102_SDA2 RA_PINCFG__40(1, 2, 0x05, RA_PINCFG_FUNC) +#define P102_TXD2 RA_PINCFG__40(1, 2, 0x05, RA_PINCFG_FUNC) +#define P102_VL3 RA_PINCFG__40(1, 2, 0x0D, RA_PINCFG_FUNC) +#define P103_AN019 RA_PINCFG__48(1, 3, 0x01, RA_PINCFG_ANALOG) +#define P103_CMPREF1 RA_PINCFG__48(1, 3, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P103_CTS0_RTS0 RA_PINCFG__48(1, 3, 0x04, RA_PINCFG_FUNC) +#define P103_CTX0 RA_PINCFG__48(1, 3, 0x10, RA_PINCFG_FUNC) +#define P103_GTIOC2A RA_PINCFG__48(1, 3, 0x03, RA_PINCFG_FUNC) +#define P103_GTOWUP RA_PINCFG__48(1, 3, 0x02, RA_PINCFG_FUNC) +#define P103_KR03 RA_PINCFG__48(1, 3, 0x08, RA_PINCFG_FUNC) +#define P103_SS0 RA_PINCFG__48(1, 3, 0x04, RA_PINCFG_FUNC) +#define P103_SSLA0 RA_PINCFG__48(1, 3, 0x06, RA_PINCFG_FUNC) +#define P103_VL4 RA_PINCFG__48(1, 3, 0x0D, RA_PINCFG_FUNC) +#define P104_COM0 RA_PINCFG__48(1, 4, 0x0D, RA_PINCFG_FUNC) +#define P104_GTETRGB RA_PINCFG__48(1, 4, 0x02, RA_PINCFG_FUNC) +#define P104_GTIOC1B RA_PINCFG__48(1, 4, 0x03, RA_PINCFG_FUNC) +#define P104_KR04 RA_PINCFG__48(1, 4, 0x08, RA_PINCFG_FUNC) +#define P104_MISO0 RA_PINCFG__48(1, 4, 0x04, RA_PINCFG_FUNC) +#define P104_RXD0 RA_PINCFG__48(1, 4, 0x04, RA_PINCFG_FUNC) +#define P104_SCL0 RA_PINCFG__48(1, 4, 0x04, RA_PINCFG_FUNC) +#define P104_SSLA1 RA_PINCFG__48(1, 4, 0x06, RA_PINCFG_FUNC) +#define P104_TS13 RA_PINCFG__48(1, 4, 0x0C, RA_PINCFG_FUNC) +#define P105_COM1 RA_PINCFG__64(1, 5, 0x0D, RA_PINCFG_FUNC) +#define P105_GTETRGA RA_PINCFG__64(1, 5, 0x02, RA_PINCFG_FUNC) +#define P105_GTIOC1A RA_PINCFG__64(1, 5, 0x03, RA_PINCFG_FUNC) +#define P105_KR05 RA_PINCFG__64(1, 5, 0x08, RA_PINCFG_FUNC) +#define P105_SSLA2 RA_PINCFG__64(1, 5, 0x06, RA_PINCFG_FUNC) +#define P105_TS34 RA_PINCFG__64(1, 5, 0x0C, RA_PINCFG_FUNC) +#define P106_COM2 RA_PINCFG__64(1, 6, 0x0D, RA_PINCFG_FUNC) +#define P106_GTIOC0B RA_PINCFG__64(1, 6, 0x03, RA_PINCFG_FUNC) +#define P106_KR06 RA_PINCFG__64(1, 6, 0x08, RA_PINCFG_FUNC) +#define P106_SSLA3 RA_PINCFG__64(1, 6, 0x06, RA_PINCFG_FUNC) +#define P107_COM3 RA_PINCFG__64(1, 7, 0x0D, RA_PINCFG_FUNC) +#define P107_GTIOC0A RA_PINCFG__64(1, 7, 0x03, RA_PINCFG_FUNC) +#define P107_KR07 RA_PINCFG__64(1, 7, 0x08, RA_PINCFG_FUNC) +#define P108_CTS9_RTS9 RA_PINCFG__40(1, 8, 0x05, RA_PINCFG_FUNC) +#define P108_GTIOC0B RA_PINCFG__40(1, 8, 0x03, RA_PINCFG_FUNC) +#define P108_GTOULO RA_PINCFG__40(1, 8, 0x02, RA_PINCFG_FUNC) +#define P108_SS9 RA_PINCFG__40(1, 8, 0x05, RA_PINCFG_FUNC) +#define P108_SSLB0 RA_PINCFG__40(1, 8, 0x06, RA_PINCFG_FUNC) +#define P109_CLKOUT RA_PINCFG__40(1, 9, 0x09, RA_PINCFG_FUNC) +#define P109_CTX0 RA_PINCFG__40(1, 9, 0x10, RA_PINCFG_FUNC) +#define P109_GTIOC1A RA_PINCFG__40(1, 9, 0x03, RA_PINCFG_FUNC) +#define P109_GTOVUP RA_PINCFG__40(1, 9, 0x02, RA_PINCFG_FUNC) +#define P109_MOSI9 RA_PINCFG__40(1, 9, 0x05, RA_PINCFG_FUNC) +#define P109_MOSIB RA_PINCFG__40(1, 9, 0x06, RA_PINCFG_FUNC) +#define P109_SCK1 RA_PINCFG__40(1, 9, 0x04, RA_PINCFG_FUNC) +#define P109_SDA9 RA_PINCFG__40(1, 9, 0x05, RA_PINCFG_FUNC) +#define P109_SEG23 RA_PINCFG__40(1, 9, 0x0D, RA_PINCFG_FUNC) +#define P109_TS10 RA_PINCFG__40(1, 9, 0x0C, RA_PINCFG_FUNC) +#define P109_TXD9 RA_PINCFG__40(1, 9, 0x05, RA_PINCFG_FUNC) +#define P110_CRX0 RA_PINCFG__40(1, 0, 0x10, RA_PINCFG_FUNC) +#define P110_CTS2_RTS2 RA_PINCFG__40(1, 0, 0x04, RA_PINCFG_FUNC) +#define P110_GTIOC1B RA_PINCFG__40(1, 0, 0x03, RA_PINCFG_FUNC) +#define P110_GTOVLO RA_PINCFG__40(1, 0, 0x02, RA_PINCFG_FUNC) +#define P110_MISO9 RA_PINCFG__40(1, 0, 0x05, RA_PINCFG_FUNC) +#define P110_MISOB RA_PINCFG__40(1, 0, 0x06, RA_PINCFG_FUNC) +#define P110_RXD9 RA_PINCFG__40(1, 0, 0x05, RA_PINCFG_FUNC) +#define P110_SCL9 RA_PINCFG__40(1, 0, 0x05, RA_PINCFG_FUNC) +#define P110_SEG24 RA_PINCFG__40(1, 0, 0x0D, RA_PINCFG_FUNC) +#define P110_SS2 RA_PINCFG__40(1, 0, 0x04, RA_PINCFG_FUNC) +#define P110_VCOUT RA_PINCFG__40(1, 0, 0x09, RA_PINCFG_FUNC) +#define P111_CAPH RA_PINCFG__40(1, 1, 0x0D, RA_PINCFG_FUNC) +#define P111_GTIOC3A RA_PINCFG__40(1, 1, 0x03, RA_PINCFG_FUNC) +#define P111_RSPCKB RA_PINCFG__40(1, 1, 0x06, RA_PINCFG_FUNC) +#define P111_SCK2 RA_PINCFG__40(1, 1, 0x04, RA_PINCFG_FUNC) +#define P111_SCK9 RA_PINCFG__40(1, 1, 0x05, RA_PINCFG_FUNC) +#define P111_TS12 RA_PINCFG__40(1, 1, 0x0C, RA_PINCFG_FUNC) +#define P112_CAPL RA_PINCFG__40(1, 2, 0x0D, RA_PINCFG_FUNC) +#define P112_GTIOC3B RA_PINCFG__40(1, 2, 0x03, RA_PINCFG_FUNC) +#define P112_MOSI2 RA_PINCFG__40(1, 2, 0x04, RA_PINCFG_FUNC) +#define P112_SCK1 RA_PINCFG__40(1, 2, 0x05, RA_PINCFG_FUNC) +#define P112_SDA2 RA_PINCFG__40(1, 2, 0x04, RA_PINCFG_FUNC) +#define P112_SSIBCK0 RA_PINCFG__40(1, 2, 0x12, RA_PINCFG_FUNC) +#define P112_SSLB0 RA_PINCFG__40(1, 2, 0x06, RA_PINCFG_FUNC) +#define P112_TSCAP RA_PINCFG__40(1, 2, 0x0C, RA_PINCFG_FUNC) +#define P112_TXD2 RA_PINCFG__40(1, 2, 0x04, RA_PINCFG_FUNC) +#define P113_GTIOC2A RA_PINCFG__64(1, 3, 0x03, RA_PINCFG_FUNC) +#define P113_SEG00COM4 RA_PINCFG__64(1, 3, 0x0D, RA_PINCFG_FUNC) +#define P113_SSIFS0 RA_PINCFG__64(1, 3, 0x12, RA_PINCFG_FUNC) +#define P113_SSILRCK0 RA_PINCFG__64(1, 3, 0x12, RA_PINCFG_FUNC) +#define P113_TS27 RA_PINCFG__64(1, 3, 0x0C, RA_PINCFG_FUNC) +#define P114_GTIOC2B RA_PINCFG_100(1, 4, 0x03, RA_PINCFG_FUNC) +#define P114_SEG25 RA_PINCFG_100(1, 4, 0x0D, RA_PINCFG_FUNC) +#define P114_SSIRXD0 RA_PINCFG_100(1, 4, 0x12, RA_PINCFG_FUNC) +#define P114_TS29 RA_PINCFG_100(1, 4, 0x0C, RA_PINCFG_FUNC) +#define P115_GTIOC4A RA_PINCFG_100(1, 5, 0x03, RA_PINCFG_FUNC) +#define P115_SEG26 RA_PINCFG_100(1, 5, 0x0D, RA_PINCFG_FUNC) +#define P115_SSITXD0 RA_PINCFG_100(1, 5, 0x12, RA_PINCFG_FUNC) +#define P115_TS35 RA_PINCFG_100(1, 5, 0x0C, RA_PINCFG_FUNC) +#define P202_GTIOC5B RA_PINCFG_100(2, 2, 0x03, RA_PINCFG_FUNC) +#define P202_MISO9 RA_PINCFG_100(2, 2, 0x05, RA_PINCFG_FUNC) +#define P202_MISOB RA_PINCFG_100(2, 2, 0x06, RA_PINCFG_FUNC) +#define P202_RXD9 RA_PINCFG_100(2, 2, 0x05, RA_PINCFG_FUNC) +#define P202_SCK2 RA_PINCFG_100(2, 2, 0x04, RA_PINCFG_FUNC) +#define P202_SCL9 RA_PINCFG_100(2, 2, 0x05, RA_PINCFG_FUNC) +#define P202_SEG16 RA_PINCFG_100(2, 2, 0x0D, RA_PINCFG_FUNC) +#define P203_CTS2_RTS2 RA_PINCFG_100(2, 3, 0x04, RA_PINCFG_FUNC) +#define P203_GTIOC5A RA_PINCFG_100(2, 3, 0x03, RA_PINCFG_FUNC) +#define P203_MOSI9 RA_PINCFG_100(2, 3, 0x05, RA_PINCFG_FUNC) +#define P203_MOSIB RA_PINCFG_100(2, 3, 0x06, RA_PINCFG_FUNC) +#define P203_SDA9 RA_PINCFG_100(2, 3, 0x05, RA_PINCFG_FUNC) +#define P203_SEG15 RA_PINCFG_100(2, 3, 0x0D, RA_PINCFG_FUNC) +#define P203_SS2 RA_PINCFG_100(2, 3, 0x04, RA_PINCFG_FUNC) +#define P203_TSCAP RA_PINCFG_100(2, 3, 0x0C, RA_PINCFG_FUNC) +#define P203_TXD9 RA_PINCFG_100(2, 3, 0x05, RA_PINCFG_FUNC) +#define P204_AGTIO1 RA_PINCFG__64(2, 4, 0x01, RA_PINCFG_FUNC) +#define P204_CACREF RA_PINCFG__64(2, 4, 0x0A, RA_PINCFG_FUNC) +#define P204_GTIOC4B RA_PINCFG__64(2, 4, 0x03, RA_PINCFG_FUNC) +#define P204_GTIW RA_PINCFG__64(2, 4, 0x02, RA_PINCFG_FUNC) +#define P204_RSPCKB RA_PINCFG__64(2, 4, 0x06, RA_PINCFG_FUNC) +#define P204_SCK0 RA_PINCFG__64(2, 4, 0x04, RA_PINCFG_FUNC) +#define P204_SCK9 RA_PINCFG__64(2, 4, 0x05, RA_PINCFG_FUNC) +#define P204_SCL0 RA_PINCFG__64(2, 4, 0x07, RA_PINCFG_FUNC) +#define P204_SEG14 RA_PINCFG__64(2, 4, 0x0D, RA_PINCFG_FUNC) +#define P204_TS00 RA_PINCFG__64(2, 4, 0x0C, RA_PINCFG_FUNC) +#define P204_USB_OVRCUR_B RA_PINCFG__64(2, 4, 0x13, RA_PINCFG_FUNC) +#define P205_AGTO1 RA_PINCFG__64(2, 5, 0x01, RA_PINCFG_FUNC) +#define P205_CLKOUT RA_PINCFG__64(2, 5, 0x09, RA_PINCFG_FUNC) +#define P205_CTS9_RTS9 RA_PINCFG__64(2, 5, 0x05, RA_PINCFG_FUNC) +#define P205_GTIOC4A RA_PINCFG__64(2, 5, 0x03, RA_PINCFG_FUNC) +#define P205_GTIV RA_PINCFG__64(2, 5, 0x02, RA_PINCFG_FUNC) +#define P205_MOSI0 RA_PINCFG__64(2, 5, 0x04, RA_PINCFG_FUNC) +#define P205_SCL1 RA_PINCFG__64(2, 5, 0x07, RA_PINCFG_FUNC) +#define P205_SDA0 RA_PINCFG__64(2, 5, 0x04, RA_PINCFG_FUNC) +#define P205_SEG13 RA_PINCFG__64(2, 5, 0x0D, RA_PINCFG_FUNC) +#define P205_SS9 RA_PINCFG__64(2, 5, 0x05, RA_PINCFG_FUNC) +#define P205_SSLB0 RA_PINCFG__64(2, 5, 0x06, RA_PINCFG_FUNC) +#define P205_TSCAP RA_PINCFG__64(2, 5, 0x0C, RA_PINCFG_FUNC) +#define P205_TXD0 RA_PINCFG__64(2, 5, 0x04, RA_PINCFG_FUNC) +#define P205_USB_OVRCUR_A RA_PINCFG__64(2, 5, 0x13, RA_PINCFG_FUNC) +#define P206_GTIU RA_PINCFG__48(2, 6, 0x02, RA_PINCFG_FUNC) +#define P206_MISO0 RA_PINCFG__48(2, 6, 0x04, RA_PINCFG_FUNC) +#define P206_RXD0 RA_PINCFG__48(2, 6, 0x04, RA_PINCFG_FUNC) +#define P206_SCL0 RA_PINCFG__48(2, 6, 0x04, RA_PINCFG_FUNC) +#define P206_SDA1 RA_PINCFG__48(2, 6, 0x07, RA_PINCFG_FUNC) +#define P206_SEG12 RA_PINCFG__48(2, 6, 0x0D, RA_PINCFG_FUNC) +#define P206_SSLB1 RA_PINCFG__48(2, 6, 0x06, RA_PINCFG_FUNC) +#define P206_TS01 RA_PINCFG__48(2, 6, 0x0C, RA_PINCFG_FUNC) +#define P206_USB_VBUSEN RA_PINCFG__48(2, 6, 0x13, RA_PINCFG_FUNC) +#define P212_AGTEE1 RA_PINCFG__40(2, 2, 0x01, RA_PINCFG_FUNC) +#define P212_GTETRGB RA_PINCFG__40(2, 2, 0x02, RA_PINCFG_FUNC) +#define P212_GTIOC0B RA_PINCFG__40(2, 2, 0x03, RA_PINCFG_FUNC) +#define P212_MISO1 RA_PINCFG__40(2, 2, 0x05, RA_PINCFG_FUNC) +#define P212_RXD1 RA_PINCFG__40(2, 2, 0x05, RA_PINCFG_FUNC) +#define P212_SCL1 RA_PINCFG__40(2, 2, 0x05, RA_PINCFG_FUNC) +#define P213_GTETRGA RA_PINCFG__40(2, 3, 0x02, RA_PINCFG_FUNC) +#define P213_GTIOC0A RA_PINCFG__40(2, 3, 0x03, RA_PINCFG_FUNC) +#define P213_MOSI1 RA_PINCFG__40(2, 3, 0x05, RA_PINCFG_FUNC) +#define P213_SDA1 RA_PINCFG__40(2, 3, 0x05, RA_PINCFG_FUNC) +#define P213_TXD1 RA_PINCFG__40(2, 3, 0x05, RA_PINCFG_FUNC) +#define P300_GTIOC0A RA_PINCFG__40(3, 0, 0x03, RA_PINCFG_FUNC) +#define P300_GTOUUP RA_PINCFG__40(3, 0, 0x02, RA_PINCFG_FUNC) +#define P300_SSLB1 RA_PINCFG__40(3, 0, 0x06, RA_PINCFG_FUNC) +#define P301_AGTIO0 RA_PINCFG__40(3, 1, 0x01, RA_PINCFG_FUNC) +#define P301_COM5 RA_PINCFG__40(3, 1, 0x10, RA_PINCFG_FUNC) +#define P301_CTS9_RTS9 RA_PINCFG__40(3, 1, 0x05, RA_PINCFG_FUNC) +#define P301_GTIOC4B RA_PINCFG__40(3, 1, 0x03, RA_PINCFG_FUNC) +#define P301_GTOULO RA_PINCFG__40(3, 1, 0x02, RA_PINCFG_FUNC) +#define P301_MISO2 RA_PINCFG__40(3, 1, 0x04, RA_PINCFG_FUNC) +#define P301_RXD2 RA_PINCFG__40(3, 1, 0x04, RA_PINCFG_FUNC) +#define P301_SCL2 RA_PINCFG__40(3, 1, 0x04, RA_PINCFG_FUNC) +#define P301_SEG01 RA_PINCFG__40(3, 1, 0x0D, RA_PINCFG_FUNC) +#define P301_SS9 RA_PINCFG__40(3, 1, 0x05, RA_PINCFG_FUNC) +#define P301_SSLB2 RA_PINCFG__40(3, 1, 0x06, RA_PINCFG_FUNC) +#define P301_TS09 RA_PINCFG__40(3, 1, 0x0C, RA_PINCFG_FUNC) +#define P302_COM6 RA_PINCFG__48(3, 2, 0x10, RA_PINCFG_FUNC) +#define P302_GTIOC4A RA_PINCFG__48(3, 2, 0x03, RA_PINCFG_FUNC) +#define P302_GTOUUP RA_PINCFG__48(3, 2, 0x02, RA_PINCFG_FUNC) +#define P302_MOSI2 RA_PINCFG__48(3, 2, 0x04, RA_PINCFG_FUNC) +#define P302_SDA2 RA_PINCFG__48(3, 2, 0x04, RA_PINCFG_FUNC) +#define P302_SEG02 RA_PINCFG__48(3, 2, 0x0D, RA_PINCFG_FUNC) +#define P302_SSLB3 RA_PINCFG__48(3, 2, 0x06, RA_PINCFG_FUNC) +#define P302_TS08 RA_PINCFG__48(3, 2, 0x0C, RA_PINCFG_FUNC) +#define P302_TXD2 RA_PINCFG__48(3, 2, 0x04, RA_PINCFG_FUNC) +#define P303_COM7 RA_PINCFG__64(3, 3, 0x10, RA_PINCFG_FUNC) +#define P303_GTIOC7B RA_PINCFG__64(3, 3, 0x03, RA_PINCFG_FUNC) +#define P303_SEG03 RA_PINCFG__64(3, 3, 0x0D, RA_PINCFG_FUNC) +#define P303_TS02 RA_PINCFG__64(3, 3, 0x0C, RA_PINCFG_FUNC) +#define P304_GTIOC7A RA_PINCFG__64(3, 4, 0x03, RA_PINCFG_FUNC) +#define P304_SEG20 RA_PINCFG__64(3, 4, 0x0D, RA_PINCFG_FUNC) +#define P304_TS11 RA_PINCFG__64(3, 4, 0x0C, RA_PINCFG_FUNC) +#define P305_SEG19 RA_PINCFG_100(3, 5, 0x0D, RA_PINCFG_FUNC) +#define P306_SEG18 RA_PINCFG_100(3, 6, 0x0D, RA_PINCFG_FUNC) +#define P307_SEG17 RA_PINCFG_100(3, 7, 0x0D, RA_PINCFG_FUNC) +#define P400_AGTIO1 RA_PINCFG__48(4, 0, 0x01, RA_PINCFG_FUNC) +#define P400_AUDIO_CLK RA_PINCFG__48(4, 0, 0x12, RA_PINCFG_FUNC) +#define P400_CACREF RA_PINCFG__48(4, 0, 0x0A, RA_PINCFG_FUNC) +#define P400_GTIOC6A RA_PINCFG__48(4, 0, 0x04, RA_PINCFG_FUNC) +#define P400_SCK0 RA_PINCFG__48(4, 0, 0x04, RA_PINCFG_FUNC) +#define P400_SCK1 RA_PINCFG__48(4, 0, 0x05, RA_PINCFG_FUNC) +#define P400_SCL0 RA_PINCFG__48(4, 0, 0x07, RA_PINCFG_FUNC) +#define P400_SEG04 RA_PINCFG__48(4, 0, 0x0D, RA_PINCFG_FUNC) +#define P400_TS20 RA_PINCFG__48(4, 0, 0x0C, RA_PINCFG_FUNC) +#define P401_CTS0_RTS0 RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P401_CTX0 RA_PINCFG__64(4, 1, 0x10, RA_PINCFG_FUNC) +#define P401_GTETRGA RA_PINCFG__64(4, 1, 0x03, RA_PINCFG_FUNC) +#define P401_GTIOC6B RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P401_MOSI1 RA_PINCFG__64(4, 1, 0x05, RA_PINCFG_FUNC) +#define P401_SDA0 RA_PINCFG__64(4, 1, 0x07, RA_PINCFG_FUNC) +#define P401_SDA1 RA_PINCFG__64(4, 1, 0x05, RA_PINCFG_FUNC) +#define P401_SEG05 RA_PINCFG__64(4, 1, 0x0D, RA_PINCFG_FUNC) +#define P401_SS0 RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P401_TS19 RA_PINCFG__64(4, 1, 0x0C, RA_PINCFG_FUNC) +#define P401_TXD1 RA_PINCFG__64(4, 1, 0x05, RA_PINCFG_FUNC) +#define P402_AGTIO0 RA_PINCFG__64(4, 2, 0x01, RA_PINCFG_FUNC) +#define P402_AGTIO1 RA_PINCFG__64(4, 2, 0x02, RA_PINCFG_FUNC) +#define P402_CRX0 RA_PINCFG__64(4, 2, 0x10, RA_PINCFG_FUNC) +#define P402_MISO1 RA_PINCFG__64(4, 2, 0x05, RA_PINCFG_FUNC) +#define P402_RTCIC0 RA_PINCFG__64(4, 2, 0x00, RA_PINCFG_GPIO) +#define P402_RXD1 RA_PINCFG__64(4, 2, 0x05, RA_PINCFG_FUNC) +#define P402_SCL1 RA_PINCFG__64(4, 2, 0x05, RA_PINCFG_FUNC) +#define P402_SEG06 RA_PINCFG__64(4, 2, 0x0D, RA_PINCFG_FUNC) +#define P402_TS18 RA_PINCFG__64(4, 2, 0x0C, RA_PINCFG_FUNC) +#define P403_AGTIO0 RA_PINCFG_100(4, 3, 0x01, RA_PINCFG_FUNC) +#define P403_AGTIO1 RA_PINCFG_100(4, 3, 0x02, RA_PINCFG_FUNC) +#define P403_CTS1_RTS1 RA_PINCFG_100(4, 3, 0x05, RA_PINCFG_FUNC) +#define P403_GTIOC3A RA_PINCFG_100(4, 3, 0x04, RA_PINCFG_FUNC) +#define P403_RTCIC1 RA_PINCFG_100(4, 3, 0x00, RA_PINCFG_GPIO) +#define P403_SS1 RA_PINCFG_100(4, 3, 0x05, RA_PINCFG_FUNC) +#define P403_SSIBCK0 RA_PINCFG_100(4, 3, 0x12, RA_PINCFG_FUNC) +#define P403_TS17 RA_PINCFG_100(4, 3, 0x0C, RA_PINCFG_FUNC) +#define P404_GTIOC3B RA_PINCFG_100(4, 4, 0x04, RA_PINCFG_FUNC) +#define P404_RTCIC2 RA_PINCFG_100(4, 4, 0x00, RA_PINCFG_GPIO) +#define P404_SSIFS0 RA_PINCFG_100(4, 4, 0x12, RA_PINCFG_FUNC) +#define P404_SSILRCK0 RA_PINCFG_100(4, 4, 0x12, RA_PINCFG_FUNC) +#define P405_GTIOC1A RA_PINCFG_100(4, 5, 0x04, RA_PINCFG_FUNC) +#define P405_SSITXD0 RA_PINCFG_100(4, 5, 0x12, RA_PINCFG_FUNC) +#define P406_GTIOC1B RA_PINCFG_100(4, 6, 0x04, RA_PINCFG_FUNC) +#define P406_SSIRXD0 RA_PINCFG_100(4, 6, 0x12, RA_PINCFG_FUNC) +#define P407_ADTRG0 RA_PINCFG__40(4, 7, 0x0A, RA_PINCFG_FUNC) +#define P407_AGTIO0 RA_PINCFG__40(4, 7, 0x01, RA_PINCFG_FUNC) +#define P407_CTS0_RTS0 RA_PINCFG__40(4, 7, 0x04, RA_PINCFG_FUNC) +#define P407_RTCOUT RA_PINCFG__40(4, 7, 0x09, RA_PINCFG_FUNC) +#define P407_SDA0 RA_PINCFG__40(4, 7, 0x07, RA_PINCFG_FUNC) +#define P407_SEG11 RA_PINCFG__40(4, 7, 0x0D, RA_PINCFG_FUNC) +#define P407_SS0 RA_PINCFG__40(4, 7, 0x04, RA_PINCFG_FUNC) +#define P407_SSLB3 RA_PINCFG__40(4, 7, 0x06, RA_PINCFG_FUNC) +#define P407_TS03 RA_PINCFG__40(4, 7, 0x0C, RA_PINCFG_FUNC) +#define P407_USB_VBUS RA_PINCFG__40(4, 7, 0x13, RA_PINCFG_FUNC) +#define P408_CTS1_RTS1 RA_PINCFG__40(4, 8, 0x04, RA_PINCFG_FUNC) +#define P408_GTIOC5B RA_PINCFG__40(4, 8, 0x04, RA_PINCFG_FUNC) +#define P408_GTOWLO RA_PINCFG__40(4, 8, 0x03, RA_PINCFG_FUNC) +#define P408_MISO9 RA_PINCFG__40(4, 8, 0x05, RA_PINCFG_FUNC) +#define P408_RXD9 RA_PINCFG__40(4, 8, 0x05, RA_PINCFG_FUNC) +#define P408_SCL0 RA_PINCFG__40(4, 8, 0x07, RA_PINCFG_FUNC) +#define P408_SCL9 RA_PINCFG__40(4, 8, 0x05, RA_PINCFG_FUNC) +#define P408_SEG10 RA_PINCFG__40(4, 8, 0x0D, RA_PINCFG_FUNC) +#define P408_SS1 RA_PINCFG__40(4, 8, 0x04, RA_PINCFG_FUNC) +#define P408_TS04 RA_PINCFG__40(4, 8, 0x0C, RA_PINCFG_FUNC) +#define P408_USB_ID RA_PINCFG__40(4, 8, 0x13, RA_PINCFG_FUNC) +#define P409_GTIOC5A RA_PINCFG__48(4, 9, 0x04, RA_PINCFG_FUNC) +#define P409_GTOWUP RA_PINCFG__48(4, 9, 0x03, RA_PINCFG_FUNC) +#define P409_MOSI9 RA_PINCFG__48(4, 9, 0x05, RA_PINCFG_FUNC) +#define P409_SDA9 RA_PINCFG__48(4, 9, 0x05, RA_PINCFG_FUNC) +#define P409_SEG09 RA_PINCFG__48(4, 9, 0x0D, RA_PINCFG_FUNC) +#define P409_TS05 RA_PINCFG__48(4, 9, 0x0C, RA_PINCFG_FUNC) +#define P409_TXD9 RA_PINCFG__48(4, 9, 0x05, RA_PINCFG_FUNC) +#define P409_USB_EXICEN RA_PINCFG__48(4, 9, 0x13, RA_PINCFG_FUNC) +#define P410_AGTOB1 RA_PINCFG__64(4, 0, 0x01, RA_PINCFG_FUNC) +#define P410_GTIOC6B RA_PINCFG__64(4, 0, 0x04, RA_PINCFG_FUNC) +#define P410_GTOVLO RA_PINCFG__64(4, 0, 0x03, RA_PINCFG_FUNC) +#define P410_MISO0 RA_PINCFG__64(4, 0, 0x04, RA_PINCFG_FUNC) +#define P410_MISOA RA_PINCFG__64(4, 0, 0x06, RA_PINCFG_FUNC) +#define P410_RXD0 RA_PINCFG__64(4, 0, 0x04, RA_PINCFG_FUNC) +#define P410_SCL0 RA_PINCFG__64(4, 0, 0x04, RA_PINCFG_FUNC) +#define P410_SEG08 RA_PINCFG__64(4, 0, 0x0D, RA_PINCFG_FUNC) +#define P410_TS06 RA_PINCFG__64(4, 0, 0x0C, RA_PINCFG_FUNC) +#define P411_AGTOA1 RA_PINCFG__64(4, 1, 0x01, RA_PINCFG_FUNC) +#define P411_GTIOC6A RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P411_GTOVUP RA_PINCFG__64(4, 1, 0x03, RA_PINCFG_FUNC) +#define P411_MOSI0 RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P411_MOSIA RA_PINCFG__64(4, 1, 0x06, RA_PINCFG_FUNC) +#define P411_SDA0 RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P411_SEG07 RA_PINCFG__64(4, 1, 0x0D, RA_PINCFG_FUNC) +#define P411_TS07 RA_PINCFG__64(4, 1, 0x0C, RA_PINCFG_FUNC) +#define P411_TXD0 RA_PINCFG__64(4, 1, 0x04, RA_PINCFG_FUNC) +#define P412_RSPCKA RA_PINCFG_100(4, 2, 0x06, RA_PINCFG_FUNC) +#define P412_SCK0 RA_PINCFG_100(4, 2, 0x04, RA_PINCFG_FUNC) +#define P413_CTS0_RTS0 RA_PINCFG_100(4, 3, 0x04, RA_PINCFG_FUNC) +#define P413_SS0 RA_PINCFG_100(4, 3, 0x04, RA_PINCFG_FUNC) +#define P413_SSLA0 RA_PINCFG_100(4, 3, 0x06, RA_PINCFG_FUNC) +#define P414_GTIOC0B RA_PINCFG_100(4, 4, 0x04, RA_PINCFG_FUNC) +#define P414_SSLA1 RA_PINCFG_100(4, 4, 0x06, RA_PINCFG_FUNC) +#define P415_GTIOC0A RA_PINCFG_100(4, 5, 0x04, RA_PINCFG_FUNC) +#define P415_SSLA2 RA_PINCFG_100(4, 5, 0x06, RA_PINCFG_FUNC) +#define P500_AGTOA0 RA_PINCFG__48(5, 0, 0x01, RA_PINCFG_FUNC) +#define P500_AN016 RA_PINCFG__48(5, 0, 0x01, RA_PINCFG_ANALOG) +#define P500_CMPREF1 RA_PINCFG__48(5, 0, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P500_GTIOC2A RA_PINCFG__48(5, 0, 0x04, RA_PINCFG_FUNC) +#define P500_GTIU RA_PINCFG__48(5, 0, 0x03, RA_PINCFG_FUNC) +#define P500_SEG34 RA_PINCFG__48(5, 0, 0x0D, RA_PINCFG_FUNC) +#define P500_USB_VBUSEN RA_PINCFG__48(5, 0, 0x13, RA_PINCFG_FUNC) +#define P501_AGTOB0 RA_PINCFG__64(5, 1, 0x01, RA_PINCFG_FUNC) +#define P501_AN017 RA_PINCFG__64(5, 1, 0x01, RA_PINCFG_ANALOG) +#define P501_CMPIN1 RA_PINCFG__64(5, 1, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P501_GTIOC2B RA_PINCFG__64(5, 1, 0x04, RA_PINCFG_FUNC) +#define P501_GTIV RA_PINCFG__64(5, 1, 0x03, RA_PINCFG_FUNC) +#define P501_MOSI1 RA_PINCFG__64(5, 1, 0x05, RA_PINCFG_FUNC) +#define P501_SDA1 RA_PINCFG__64(5, 1, 0x05, RA_PINCFG_FUNC) +#define P501_SEG35 RA_PINCFG__64(5, 1, 0x0D, RA_PINCFG_FUNC) +#define P501_TXD1 RA_PINCFG__64(5, 1, 0x05, RA_PINCFG_FUNC) +#define P501_USB_OVRCUR_A RA_PINCFG__64(5, 1, 0x13, RA_PINCFG_FUNC) +#define P502_AN018 RA_PINCFG__64(5, 2, 0x01, RA_PINCFG_ANALOG) +#define P502_CMPREF0 RA_PINCFG__64(5, 2, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P502_GTIOC3B RA_PINCFG__64(5, 2, 0x04, RA_PINCFG_FUNC) +#define P502_GTIW RA_PINCFG__64(5, 2, 0x03, RA_PINCFG_FUNC) +#define P502_MISO1 RA_PINCFG__64(5, 2, 0x05, RA_PINCFG_FUNC) +#define P502_RXD1 RA_PINCFG__64(5, 2, 0x05, RA_PINCFG_FUNC) +#define P502_SCL1 RA_PINCFG__64(5, 2, 0x05, RA_PINCFG_FUNC) +#define P502_SEG36 RA_PINCFG__64(5, 2, 0x0D, RA_PINCFG_FUNC) +#define P502_USB_OVRCUR_B RA_PINCFG__64(5, 2, 0x13, RA_PINCFG_FUNC) +#define P503_AN023 RA_PINCFG_100(5, 3, 0x01, RA_PINCFG_ANALOG) +#define P503_CMPIN0 RA_PINCFG_100(5, 3, 0x02, RA_PINCFG_FUNC | RA_PINCFG_ANALOG) +#define P503_SCK1 RA_PINCFG_100(5, 3, 0x05, RA_PINCFG_FUNC) +#define P503_SEG37 RA_PINCFG_100(5, 3, 0x0D, RA_PINCFG_FUNC) +#define P503_USB_EXICEN RA_PINCFG_100(5, 3, 0x13, RA_PINCFG_FUNC) +#define P504_AN024 RA_PINCFG_100(5, 4, 0x01, RA_PINCFG_ANALOG) +#define P504_CTS1_RTS1 RA_PINCFG_100(5, 4, 0x05, RA_PINCFG_FUNC) +#define P504_SS1 RA_PINCFG_100(5, 4, 0x05, RA_PINCFG_FUNC) +#define P504_USB_ID RA_PINCFG_100(5, 4, 0x13, RA_PINCFG_FUNC) +#define P505_AN025 RA_PINCFG_100(5, 5, 0x01, RA_PINCFG_ANALOG) +#define P600_GTIOC6B RA_PINCFG_100(6, 0, 0x01, RA_PINCFG_FUNC) +#define P600_SCK9 RA_PINCFG_100(6, 0, 0x05, RA_PINCFG_FUNC) +#define P600_SEG33 RA_PINCFG_100(6, 0, 0x0D, RA_PINCFG_FUNC) +#define P601_GTIOC6A RA_PINCFG_100(6, 1, 0x01, RA_PINCFG_FUNC) +#define P601_MISO9 RA_PINCFG_100(6, 1, 0x05, RA_PINCFG_FUNC) +#define P601_RXD9 RA_PINCFG_100(6, 1, 0x05, RA_PINCFG_FUNC) +#define P601_SCL9 RA_PINCFG_100(6, 1, 0x05, RA_PINCFG_FUNC) +#define P601_SEG32 RA_PINCFG_100(6, 1, 0x0D, RA_PINCFG_FUNC) +#define P602_GTIOC7B RA_PINCFG_100(6, 2, 0x01, RA_PINCFG_FUNC) +#define P602_MOSI9 RA_PINCFG_100(6, 2, 0x05, RA_PINCFG_FUNC) +#define P602_SDA9 RA_PINCFG_100(6, 2, 0x05, RA_PINCFG_FUNC) +#define P602_SEG31 RA_PINCFG_100(6, 2, 0x0D, RA_PINCFG_FUNC) +#define P602_TXD9 RA_PINCFG_100(6, 2, 0x05, RA_PINCFG_FUNC) +#define P603_CTS9_RTS9 RA_PINCFG_100(6, 3, 0x05, RA_PINCFG_FUNC) +#define P603_GTIOC7A RA_PINCFG_100(6, 3, 0x01, RA_PINCFG_FUNC) +#define P603_SEG30 RA_PINCFG_100(6, 3, 0x0D, RA_PINCFG_FUNC) +#define P603_SS9 RA_PINCFG_100(6, 3, 0x05, RA_PINCFG_FUNC) +#define P608_GTIOC4B RA_PINCFG_100(6, 8, 0x01, RA_PINCFG_FUNC) +#define P608_SEG27 RA_PINCFG_100(6, 8, 0x0D, RA_PINCFG_FUNC) +#define P609_GTIOC5A RA_PINCFG_100(6, 9, 0x01, RA_PINCFG_FUNC) +#define P609_SEG28 RA_PINCFG_100(6, 9, 0x0D, RA_PINCFG_FUNC) +#define P610_GTIOC5B RA_PINCFG_100(6, 0, 0x01, RA_PINCFG_FUNC) +#define P610_SEG29 RA_PINCFG_100(6, 0, 0x0D, RA_PINCFG_FUNC) +#define P708_MISO1 RA_PINCFG_100(7, 8, 0x05, RA_PINCFG_FUNC) +#define P708_RXD1 RA_PINCFG_100(7, 8, 0x05, RA_PINCFG_FUNC) +#define P708_SCL1 RA_PINCFG_100(7, 8, 0x05, RA_PINCFG_FUNC) +#define P708_SSLA3 RA_PINCFG_100(7, 8, 0x06, RA_PINCFG_FUNC) +#define P808_SEG21 RA_PINCFG_100(8, 8, 0x0D, RA_PINCFG_FUNC) +#define P809_SEG22 RA_PINCFG_100(8, 9, 0x0D, RA_PINCFG_FUNC) +#define P914_USB_DP RA_PINCFG__40(9, 4, 0x00, RA_PINCFG_GPIO) +#define P915_USB_DM RA_PINCFG__40(9, 5, 0x00, RA_PINCFG_GPIO) +#endif diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra-common.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra-common.h new file mode 100644 index 00000000000..88ea7ece75d --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra-common.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RA_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RA_COMMON_H_ + +#define PORT4_POS 29 +#define PORT4_MASK 0x1 +#define PSEL_POS 24 +#define PSEL_MASK 0x5 +#define PORT_POS 21 +#define PORT_MASK 0x3 +#define PIN_POS 17 +#define PIN_MASK 0xF +#define OPT_POS 0 +#define OPT_MASK 0x1B000 + +#define RA_PINCFG_GPIO 0x00000 +#define RA_PINCFG_FUNC 0x10000 +#define RA_PINCFG_ANALOG 0x08000 + +#define RA_PINCFG(port, pin, psel, opt) \ + ((((psel)&PSEL_MASK) << PSEL_POS) | (((pin)&PIN_MASK) << PIN_POS) | \ + (((port)&PORT_MASK) << PORT_POS) | ((((port) >> 3) & PORT4_MASK) << PORT4_POS) | \ + (((opt)&OPT_MASK) << OPT_POS)) + +#if RA_SOC_PINS >= 40 +#define RA_PINCFG__40(port, pin, psel, opt) RA_PINCFG(port, pin, psel, opt) +#endif + +#if RA_SOC_PINS >= 48 +#define RA_PINCFG__48(port, pin, psel, opt) RA_PINCFG(port, pin, psel, opt) +#endif + +#if RA_SOC_PINS >= 64 +#define RA_PINCFG__64(port, pin, psel, opt) RA_PINCFG(port, pin, psel, opt) +#endif + +#if RA_SOC_PINS >= 100 +#define RA_PINCFG_100(port, pin, psel, opt) RA_PINCFG(port, pin, psel, opt) +#endif + +#endif diff --git a/soc/arm/renesas_ra/common/pinctrl_ra.h b/soc/arm/renesas_ra/common/pinctrl_ra.h new file mode 100644 index 00000000000..d61f1e418d5 --- /dev/null +++ b/soc/arm/renesas_ra/common/pinctrl_ra.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_RENESAS_RA_COMMON_RA_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_RENESAS_RA_COMMON_RA_PINCTRL_SOC_H_ + +enum { + PmnPFS_PODR_POS, + PmnPFS_PIDR_POS, + PmnPFS_PDR_POS, + PmnPFS_RSV3_POS, + PmnPFS_PCR_POS, + PmnPFS_RSV5_POS, + PmnPFS_NCODR_POS, + PmnPFS_RSV7_POS, + PmnPFS_RSV8_POS, + PmnPFS_RSV9_POS, + PmnPFS_DSCR_POS, + PmnPFS_DSCR1_POS, + PmnPFS_EOR_POS, + PmnPFS_EOF_POS, + PmnPFS_ISEL_POS, + PmnPFS_ASEL_POS, + PmnPFS_PMR_POS, +}; + +struct pinctrl_ra_pin { + union { + uint32_t config; + struct { + uint8_t PODR: 1; + uint8_t PIDR: 1; + uint8_t PDR: 1; + uint8_t RESERVED3: 1; + uint8_t PCR: 1; + uint8_t RESERVED5: 1; + uint8_t NCODR: 1; + uint8_t RESERVED7: 1; + uint8_t RESERVED8: 1; + uint8_t RESERVED9: 1; + uint8_t DSCR: 2; + uint8_t EOFR: 2; + uint8_t ISEL: 1; + uint8_t ASEL: 1; + uint8_t PMR: 1; + uint8_t RESERVED17: 7; + uint8_t PSEL: 5; + uint8_t RESERVED29: 3; + }; + /* Using RESERVED fields for store pin and port info. */ + struct { + uint32_t UNUSED0: 17; + uint8_t pin: 4; + uint8_t port: 3; + uint32_t UNUSED24: 5; + uint8_t port4: 3; + }; + }; +}; + +typedef struct pinctrl_ra_pin pinctrl_soc_pin_t; + +extern int pinctrl_ra_query_config(uint32_t port, uint32_t pin, + struct pinctrl_ra_pin *const pincfg); + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .config = DT_PROP_BY_IDX(node_id, prop, idx), \ + }, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { \ + DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT) \ + } + +#endif /* ZEPHYR_SOC_ARM_RENESAS_RA_RA6E1_PINCTRL_SOC_H_ */ diff --git a/soc/arm/renesas_ra/ra4m1/pinctrl_soc.h b/soc/arm/renesas_ra/ra4m1/pinctrl_soc.h new file mode 100644 index 00000000000..e149509fab2 --- /dev/null +++ b/soc/arm/renesas_ra/ra4m1/pinctrl_soc.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../common/pinctrl_ra.h" From a9e49918cf6d918998997e28eca2c0bfa79ec631 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Fri, 11 Aug 2023 11:00:38 +0900 Subject: [PATCH 2884/4498] drivers: interrupt_controller: Add icu driver for Renesas RA series To avoid complicating the initial code for supporting the SoC, I have implemented only the bare minimum for now. Signed-off-by: TOKITA Hiroshi --- drivers/interrupt_controller/CMakeLists.txt | 1 + drivers/interrupt_controller/Kconfig | 2 + drivers/interrupt_controller/Kconfig.ra | 9 + drivers/interrupt_controller/intc_ra_icu.c | 108 ++++++++++ dts/arm/renesas/ra/ra-cm4-common.dtsi | 9 + .../renesas,ra-interrupt-controller-unit.yaml | 20 ++ dts/bindings/pinctrl/renesas,ra-pinctrl.yaml | 3 - .../interrupt_controller/intc_ra_icu.h | 38 ++++ .../interrupt-controller/renesas-ra-icu.h | 192 ++++++++++++++++++ soc/arm/renesas_ra/ra4m1/Kconfig.series | 1 + 10 files changed, 380 insertions(+), 3 deletions(-) create mode 100644 drivers/interrupt_controller/Kconfig.ra create mode 100644 drivers/interrupt_controller/intc_ra_icu.c create mode 100644 dts/bindings/interrupt-controller/renesas,ra-interrupt-controller-unit.yaml create mode 100644 include/zephyr/drivers/interrupt_controller/intc_ra_icu.h create mode 100644 include/zephyr/dt-bindings/interrupt-controller/renesas-ra-icu.h diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index c4d92304cf0..71e3435e49a 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -36,6 +36,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_NXP_S32_WKPU intc_wkpu_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ICU intc_ra_icu.c) if(CONFIG_INTEL_VTD_ICTL) zephyr_library_include_directories(${ZEPHYR_BASE}/arch/x86/include) diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig index 16ed7d40910..2a79a998c02 100644 --- a/drivers/interrupt_controller/Kconfig +++ b/drivers/interrupt_controller/Kconfig @@ -102,4 +102,6 @@ source "drivers/interrupt_controller/Kconfig.nxp_pint" source "drivers/interrupt_controller/Kconfig.vim" +source "drivers/interrupt_controller/Kconfig.ra" + endmenu diff --git a/drivers/interrupt_controller/Kconfig.ra b/drivers/interrupt_controller/Kconfig.ra new file mode 100644 index 00000000000..1105ea428b0 --- /dev/null +++ b/drivers/interrupt_controller/Kconfig.ra @@ -0,0 +1,9 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config RENESAS_RA_ICU + bool "Renesas RA series interrupt controller unit" + default y + depends on DT_HAS_RENESAS_RA_INTERRUPT_CONTROLLER_UNIT_ENABLED + help + Renesas RA series interrupt controller unit diff --git a/drivers/interrupt_controller/intc_ra_icu.c b/drivers/interrupt_controller/intc_ra_icu.c new file mode 100644 index 00000000000..167673f187f --- /dev/null +++ b/drivers/interrupt_controller/intc_ra_icu.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 TOKITTA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_interrupt_controller_unit + +#include +#include +#include +#include +#include +#include + +#define IELSRn_REG(n) (DT_INST_REG_ADDR(0) + IELSRn_OFFSET + (n * 4)) +#define IRQCRi_REG(i) (DT_INST_REG_ADDR(0) + IRQCRi_OFFSET + (i)) + +#define IRQCRi_IRQMD_POS 0 +#define IRQCRi_IRQMD_MASK BIT_MASK(2) +#define IELSRn_IR_POS 16 +#define IELSRn_IR_MASK BIT_MASK(1) + +enum { + IRQCRi_OFFSET = 0x0, + IELSRn_OFFSET = 0x300, +}; + +int ra_icu_query_exists_irq(uint32_t event) +{ + for (uint32_t i = 0; i < CONFIG_NUM_IRQS; i++) { + uint32_t els = sys_read32(IELSRn_REG(i)) & UINT8_MAX; + + if (event == els) { + return i; + } + } + + return -EINVAL; +} + +int ra_icu_query_available_irq(uint32_t event) +{ + int irq = -EINVAL; + + if (ra_icu_query_exists_irq(event) > 0) { + return -EINVAL; + } + + for (uint32_t i = 0; i < CONFIG_NUM_IRQS; i++) { + if (_sw_isr_table[i].isr == z_irq_spurious) { + irq = i; + break; + } + } + + return irq; +} + +void ra_icu_clear_int_flag(unsigned int irqn) +{ + uint32_t cfg = sys_read32(IELSRn_REG(irqn)); + + sys_write32(cfg & ~BIT(IELSRn_IR_POS), IELSRn_REG(irqn)); +} + +void ra_icu_query_irq_config(unsigned int irq, uint32_t *intcfg, ra_isr_handler *cb, + const void **cbarg) +{ + *intcfg = sys_read32(IELSRn_REG(irq)); + *cb = _sw_isr_table[irq].isr; + *cbarg = (void *)_sw_isr_table[irq].arg; +} + +static void ra_icu_irq_configure(unsigned int irqn, uint32_t intcfg) +{ + uint8_t reg = sys_read8(IRQCRi_REG(irqn)) & ~(IRQCRi_IRQMD_MASK); + + sys_write8(reg | (intcfg & IRQCRi_IRQMD_MASK), IRQCRi_REG(irqn)); +} + +int ra_icu_irq_connect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), const void *parameter, + uint32_t flags) +{ + uint32_t event = ((flags & RA_ICU_FLAG_EVENT_MASK) >> RA_ICU_FLAG_EVENT_OFFSET); + uint32_t intcfg = ((flags & RA_ICU_FLAG_INTCFG_MASK) >> RA_ICU_FLAG_INTCFG_OFFSET); + int irqn = irq; + + if (irq == RA_ICU_IRQ_UNSPECIFIED) { + irqn = ra_icu_query_available_irq(event); + if (irqn < 0) { + return irqn; + } + } + + irq_disable(irqn); + sys_write32(event, IELSRn_REG(irqn)); + z_isr_install(irqn, routine, parameter); + z_arm_irq_priority_set(irqn, priority, flags); + ra_icu_irq_configure(event, intcfg); + irq_enable(irqn); + + return irqn; +} + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, + NULL); diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi index c7986521a07..880ece373d3 100644 --- a/dts/arm/renesas/ra/ra-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -72,6 +72,15 @@ }; soc { + interrupt-parent = <&icu>; + icu: interrupt-controller@40006000 { + compatible = "renesas,ra-interrupt-controller-unit"; + reg = <0x40006000 0x40>; + reg-names = "icu"; + interrupt-controller; + #interrupt-cells = <3>; + }; + cgc: cgc@4001e000 { compatible = "renesas,ra-clock-generation-circuit"; reg = <0x4001e000 0x40 0x40047000 0x10>; diff --git a/dts/bindings/interrupt-controller/renesas,ra-interrupt-controller-unit.yaml b/dts/bindings/interrupt-controller/renesas,ra-interrupt-controller-unit.yaml new file mode 100644 index 00000000000..dd13f876cdc --- /dev/null +++ b/dts/bindings/interrupt-controller/renesas,ra-interrupt-controller-unit.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2023, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA series interrupt controller unit + +compatible: "renesas,ra-interrupt-controller-unit" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#interrupt-cells": + const: 3 + +interrupt-cells: + - irq + - priority + - flags diff --git a/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml b/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml index e3f0cd03b6c..6a48dedf37e 100644 --- a/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml +++ b/dts/bindings/pinctrl/renesas,ra-pinctrl.yaml @@ -13,9 +13,6 @@ child-binding: Definitions for a pinctrl state. child-binding: - include: - - name: pincfg-node.yaml - properties: pinmux: required: true diff --git a/include/zephyr/drivers/interrupt_controller/intc_ra_icu.h b/include/zephyr/drivers/interrupt_controller/intc_ra_icu.h new file mode 100644 index 00000000000..fcbef647d29 --- /dev/null +++ b/include/zephyr/drivers/interrupt_controller/intc_ra_icu.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_ +#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_ + +#define RA_ICU_FLAG_EVENT_OFFSET 8 +#define RA_ICU_FLAG_EVENT_MASK (BIT_MASK(8) << RA_ICU_FLAG_EVENT_OFFSET) +#define RA_ICU_FLAG_INTCFG_OFFSET 16 +#define RA_ICU_FLAG_INTCFG_MASK (BIT_MASK(8) << RA_ICU_FLAG_INTCFG_OFFSET) + +enum icu_irq_mode { + ICU_FALLING, + ICU_RISING, + ICU_BOTH_EDGE, + ICU_LOW_LEVEL, +}; + +typedef void (*ra_isr_handler)(const void *); + +extern void ra_icu_clear_int_flag(unsigned int irqn); + +extern int ra_icu_query_available_irq(uint32_t event); +extern int ra_icu_query_exists_irq(uint32_t event); + +extern void ra_icu_query_irq_config(unsigned int irq, uint32_t *intcfg, ra_isr_handler *pisr, + const void **cbarg); + +extern int ra_icu_irq_connect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), const void *parameter, + uint32_t flags); + +#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_ */ diff --git a/include/zephyr/dt-bindings/interrupt-controller/renesas-ra-icu.h b/include/zephyr/dt-bindings/interrupt-controller/renesas-ra-icu.h new file mode 100644 index 00000000000..77372b76e21 --- /dev/null +++ b/include/zephyr/dt-bindings/interrupt-controller/renesas-ra-icu.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_BINDINGS_INTERRUPT_CONTROLLER_RENESAS_RA_ICU_H_ +#define ZEPHYR_DT_BINDINGS_INTERRUPT_CONTROLLER_RENESAS_RA_ICU_H_ + +#define RA_ICU_IRQ_UNSPECIFIED (-1) + +#define RA_ICU_PORT_IRQ0 (1 << 8) +#define RA_ICU_PORT_IRQ1 (2 << 8) +#define RA_ICU_PORT_IRQ2 (3 << 8) +#define RA_ICU_PORT_IRQ3 (4 << 8) +#define RA_ICU_PORT_IRQ4 (5 << 8) +#define RA_ICU_PORT_IRQ5 (6 << 8) +#define RA_ICU_PORT_IRQ6 (7 << 8) +#define RA_ICU_PORT_IRQ7 (8 << 8) +#define RA_ICU_PORT_IRQ8 (9 << 8) +#define RA_ICU_PORT_IRQ9 (10 << 8) +#define RA_ICU_PORT_IRQ10 (11 << 8) +#define RA_ICU_PORT_IRQ11 (12 << 8) +#define RA_ICU_PORT_IRQ12 (13 << 8) +#define RA_ICU_PORT_IRQ14 (15 << 8) +#define RA_ICU_PORT_IRQ15 (16 << 8) +#define RA_ICU_DMAC0_INT (17 << 8) +#define RA_ICU_DMAC1_INT (18 << 8) +#define RA_ICU_DMAC2_INT (19 << 8) +#define RA_ICU_DMAC3_INT (20 << 8) +#define RA_ICU_DTC_COMPLETE (21 << 8) +#define RA_ICU_ICU_SNZCANCEL (23 << 8) +#define RA_ICU_FCU_FRDYI (24 << 8) +#define RA_ICU_LVD_LVD1 (25 << 8) +#define RA_ICU_LVD_LVD2 (26 << 8) +#define RA_ICU_VBATT_LVD (27 << 8) +#define RA_ICU_MOSC_STOP (28 << 8) +#define RA_ICU_SYSTEM_SNZREQ (29 << 8) +#define RA_ICU_AGT0_AGTI (30 << 8) +#define RA_ICU_AGT0_AGTCMAI (31 << 8) +#define RA_ICU_AGT0_AGTCMBI (32 << 8) +#define RA_ICU_AGT1_AGTI (33 << 8) +#define RA_ICU_AGT1_AGTCMAI (34 << 8) +#define RA_ICU_AGT1_AGTCMBI (35 << 8) +#define RA_ICU_IWDT_NMIUNDF (36 << 8) +#define RA_ICU_WDT_NMIUNDF (37 << 8) +#define RA_ICU_RTC_ALM (38 << 8) +#define RA_ICU_RTC_PRD (39 << 8) +#define RA_ICU_RTC_CUP (40 << 8) +#define RA_ICU_ADC140_ADI (41 << 8) +#define RA_ICU_ADC140_GBADI (42 << 8) +#define RA_ICU_ADC140_CMPAI (43 << 8) +#define RA_ICU_ADC140_CMPBI (44 << 8) +#define RA_ICU_ADC140_WCMPM (45 << 8) +#define RA_ICU_ADC140_WCMPUM (46 << 8) +#define RA_ICU_ACMP_LP0 (47 << 8) +#define RA_ICU_ACMP_LP1 (48 << 8) +#define RA_ICU_USBFS_D0FIFO (49 << 8) +#define RA_ICU_USBFS_D1FIFO (50 << 8) +#define RA_ICU_USBFS_USBI (51 << 8) +#define RA_ICU_USBFS_USBR (52 << 8) +#define RA_ICU_IIC0_RXI (53 << 8) +#define RA_ICU_IIC0_TXI (54 << 8) +#define RA_ICU_IIC0_TEI (55 << 8) +#define RA_ICU_IIC0_EEI (56 << 8) +#define RA_ICU_IIC0_WUI (57 << 8) +#define RA_ICU_IIC1_RXI (58 << 8) +#define RA_ICU_IIC1_TXI (59 << 8) +#define RA_ICU_IIC1_TEI (60 << 8) +#define RA_ICU_IIC1_EEI (61 << 8) +#define RA_ICU_SSIE0_SSITXI (62 << 8) +#define RA_ICU_SSIE0_SSIRXI (63 << 8) +#define RA_ICU_SSIE0_SSIF (64 << 8) +#define RA_ICU_CTSU_CTSUWR (65 << 8) +#define RA_ICU_CTSU_CTSURD (66 << 8) +#define RA_ICU_CTSU_CTSUFN (67 << 8) +#define RA_ICU_KEY_INTKR (68 << 8) +#define RA_ICU_DOC_DOPCI (69 << 8) +#define RA_ICU_CAC_FERRI (70 << 8) +#define RA_ICU_CAC_MENDI (71 << 8) +#define RA_ICU_CAC_OVFI (72 << 8) +#define RA_ICU_CAN0_ERS (73 << 8) +#define RA_ICU_CAN0_RXF (74 << 8) +#define RA_ICU_CAN0_TXF (75 << 8) +#define RA_ICU_CAN0_RXM (76 << 8) +#define RA_ICU_CAN0_TXM (77 << 8) +#define RA_ICU_IOPORT_GROUP1 (78 << 8) +#define RA_ICU_IOPORT_GROUP2 (79 << 8) +#define RA_ICU_IOPORT_GROUP3 (80 << 8) +#define RA_ICU_IOPORT_GROUP4 (81 << 8) +#define RA_ICU_ELC_SWEVT0 (82 << 8) +#define RA_ICU_ELC_SWEVT1 (83 << 8) +#define RA_ICU_POEG_GROUP0 (84 << 8) +#define RA_ICU_POEG_GROUP1 (85 << 8) +#define RA_ICU_GPT0_CCMPA (86 << 8) +#define RA_ICU_GPT0_CCMPB (87 << 8) +#define RA_ICU_GPT0_CMPC (88 << 8) +#define RA_ICU_GPT0_CMPD (89 << 8) +#define RA_ICU_GPT0_CMPE (90 << 8) +#define RA_ICU_GPT0_CMPF (91 << 8) +#define RA_ICU_GPT0_OVF (92 << 8) +#define RA_ICU_GPT0_UDF (93 << 8) +#define RA_ICU_GPT1_CCMPA (94 << 8) +#define RA_ICU_GPT1_CCMPB (95 << 8) +#define RA_ICU_GPT1_CMPC (96 << 8) +#define RA_ICU_GPT1_CMPD (97 << 8) +#define RA_ICU_GPT1_CMPE (98 << 8) +#define RA_ICU_GPT1_CMPF (99 << 8) +#define RA_ICU_GPT1_OVF (100 << 8) +#define RA_ICU_GPT1_UDF (101 << 8) +#define RA_ICU_GPT2_CCMPA (102 << 8) +#define RA_ICU_GPT2_CCMPB (103 << 8) +#define RA_ICU_GPT2_CMPC (104 << 8) +#define RA_ICU_GPT2_CMPD (105 << 8) +#define RA_ICU_GPT2_CMPE (106 << 8) +#define RA_ICU_GPT2_CMPF (107 << 8) +#define RA_ICU_GPT2_OVF (108 << 8) +#define RA_ICU_GPT2_UDF (109 << 8) +#define RA_ICU_GPT3_CCMPA (110 << 8) +#define RA_ICU_GPT3_CCMPB (111 << 8) +#define RA_ICU_GPT3_CMPC (112 << 8) +#define RA_ICU_GPT3_CMPD (113 << 8) +#define RA_ICU_GPT3_CMPE (114 << 8) +#define RA_ICU_GPT3_CMPF (115 << 8) +#define RA_ICU_GPT3_OVF (116 << 8) +#define RA_ICU_GPT3_UDF (117 << 8) +#define RA_ICU_GPT4_CCMPA (118 << 8) +#define RA_ICU_GPT4_CCMPB (119 << 8) +#define RA_ICU_GPT4_CMPC (120 << 8) +#define RA_ICU_GPT4_CMPD (121 << 8) +#define RA_ICU_GPT4_CMPE (122 << 8) +#define RA_ICU_GPT4_CMPF (123 << 8) +#define RA_ICU_GPT4_OVF (124 << 8) +#define RA_ICU_GPT4_UDF (125 << 8) +#define RA_ICU_GPT5_CCMPA (126 << 8) +#define RA_ICU_GPT5_CCMPB (127 << 8) +#define RA_ICU_GPT5_CMPC (128 << 8) +#define RA_ICU_GPT5_CMPD (129 << 8) +#define RA_ICU_GPT5_CMPE (130 << 8) +#define RA_ICU_GPT5_CMPF (131 << 8) +#define RA_ICU_GPT5_OVF (132 << 8) +#define RA_ICU_GPT5_UDF (133 << 8) +#define RA_ICU_GPT6_CCMPA (134 << 8) +#define RA_ICU_GPT6_CCMPB (135 << 8) +#define RA_ICU_GPT6_CMPC (136 << 8) +#define RA_ICU_GPT6_CMPD (137 << 8) +#define RA_ICU_GPT6_CMPE (138 << 8) +#define RA_ICU_GPT6_CMPF (139 << 8) +#define RA_ICU_GPT6_OVF (140 << 8) +#define RA_ICU_GPT6_UDF (141 << 8) +#define RA_ICU_GPT7_CCMPA (142 << 8) +#define RA_ICU_GPT7_CCMPB (143 << 8) +#define RA_ICU_GPT7_CMPC (144 << 8) +#define RA_ICU_GPT7_CMPD (145 << 8) +#define RA_ICU_GPT7_CMPE (146 << 8) +#define RA_ICU_GPT7_CMPF (147 << 8) +#define RA_ICU_GPT7_OVF (148 << 8) +#define RA_ICU_GPT7_UDF (149 << 8) +#define RA_ICU_GPT_UVWEDGE (150 << 8) +#define RA_ICU_SCI0_RXI (151 << 8) +#define RA_ICU_SCI0_TXI (152 << 8) +#define RA_ICU_SCI0_TEI (153 << 8) +#define RA_ICU_SCI0_ERI (154 << 8) +#define RA_ICU_SCI0_AM (155 << 8) +#define RA_ICU_SCI0_RXI_OR_ERI (156 << 8) +#define RA_ICU_SCI1_RXI (157 << 8) +#define RA_ICU_SCI1_TXI (158 << 8) +#define RA_ICU_SCI1_TEI (159 << 8) +#define RA_ICU_SCI1_ERI (160 << 8) +#define RA_ICU_SCI1_AM (161 << 8) +#define RA_ICU_SCI2_RXI (162 << 8) +#define RA_ICU_SCI2_TXI (163 << 8) +#define RA_ICU_SCI2_TEI (164 << 8) +#define RA_ICU_SCI2_ERI (165 << 8) +#define RA_ICU_SCI2_AM (166 << 8) +#define RA_ICU_SCI9_RXI (167 << 8) +#define RA_ICU_SCI9_TXI (168 << 8) +#define RA_ICU_SCI9_TEI (169 << 8) +#define RA_ICU_SCI9_ERI (170 << 8) +#define RA_ICU_SCI9_AM (171 << 8) +#define RA_ICU_SPI0_SPRI (172 << 8) +#define RA_ICU_SPI0_SPTI (173 << 8) +#define RA_ICU_SPI0_SPII (174 << 8) +#define RA_ICU_SPI0_SPEI (175 << 8) +#define RA_ICU_SPI0_SPTEND (176 << 8) +#define RA_ICU_SPI1_SPRI (177 << 8) +#define RA_ICU_SPI1_SPTI (178 << 8) +#define RA_ICU_SPI1_SPII (179 << 8) +#define RA_ICU_SPI1_SPEI (180 << 8) +#define RA_ICU_SPI1_SPTEND (181 << 8) + +#endif /* ZEPHYR_DT_BINDINGS_INTERRUPT_CONTROLLER_RENESAS_RA_ICU_H_ */ diff --git a/soc/arm/renesas_ra/ra4m1/Kconfig.series b/soc/arm/renesas_ra/ra4m1/Kconfig.series index a3c1aaf2a2e..7307a2d26c0 100644 --- a/soc/arm/renesas_ra/ra4m1/Kconfig.series +++ b/soc/arm/renesas_ra/ra4m1/Kconfig.series @@ -7,6 +7,7 @@ config SOC_SERIES_RA4M1 select CPU_CORTEX_M4 select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_SYSTICK + select DYNAMIC_INTERRUPTS select SOC_FAMILY_RA select TIMER_READS_ITS_FREQUENCY_AT_RUNTIME select XIP From 3292c36115c765181432d45960c2e17987368761 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 5 Jul 2023 02:59:06 +0900 Subject: [PATCH 2885/4498] drivers: gpio: Add GPIO driver for Renesas RA series Add initial support for Renesas RA GPIO. To avoid complicating the initial code for supporting the SoC, I have implemented only the bare minimum for now. Signed-off-by: TOKITA Hiroshi --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.ra | 10 + drivers/gpio/gpio_ra.c | 435 +++++++++++++++++++++++++ dts/arm/renesas/ra/ra-cm4-common.dtsi | 124 +++++++ dts/arm/renesas/ra/ra4-cm4-common.dtsi | 40 +++ dts/bindings/gpio/renesas,ra-gpio.yaml | 83 +++++ 7 files changed, 695 insertions(+) create mode 100644 drivers/gpio/Kconfig.ra create mode 100644 drivers/gpio/gpio_ra.c create mode 100644 dts/bindings/gpio/renesas,ra-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index a5974e20902..e82a815fcce 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -85,6 +85,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_RA gpio_ra.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index cce660403b4..fc09ef2994d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -210,4 +210,6 @@ source "drivers/gpio/Kconfig.altera" source "drivers/gpio/Kconfig.bcm2711" +source "drivers/gpio/Kconfig.ra" + endif # GPIO diff --git a/drivers/gpio/Kconfig.ra b/drivers/gpio/Kconfig.ra new file mode 100644 index 00000000000..391a32f293d --- /dev/null +++ b/drivers/gpio/Kconfig.ra @@ -0,0 +1,10 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_RA + bool "Renesas RA Series GPIO driver" + default y + select GPIO_GET_CONFIG + depends on DT_HAS_RENESAS_RA_GPIO_ENABLED + help + Enable Renesas RA series GPIO driver. diff --git a/drivers/gpio/gpio_ra.c b/drivers/gpio/gpio_ra.c new file mode 100644 index 00000000000..9f4fe59c83b --- /dev/null +++ b/drivers/gpio/gpio_ra.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_gpio + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + PCNTR1_OFFSET = 0x0, + PCNTR2_OFFSET = 0x4, + PCNTR3_OFFSET = 0x8, + PCNTR4_OFFSET = 0xc +}; + +enum { + PCNTR1_PDR0_OFFSET = 0, + PCNTR1_PODR0_OFFSET = 16, +}; + +enum { + PCNTR2_PIDR0_OFFSET = 0, + PCNTR2_EIDR0_OFFSET = 16, +}; + +enum { + PCNTR3_POSR0_OFFSET = 0, + PCNTR3_PORR0_OFFSET = 16, +}; + +enum { + PCNTR4_EOSR0_OFFSET = 0, + PCNTR4_EORR0_OFFSET = 16, +}; + +struct gpio_ra_irq_info { + const uint8_t *const pins; + size_t num; + int port_irq; + int irq; + uint32_t priority; + uint32_t flags; + ra_isr_handler isr; +}; + +struct gpio_ra_pin_irq_info { + const struct gpio_ra_irq_info *info; + uint8_t pin; +}; + +struct gpio_ra_config { + struct gpio_driver_config common; + mem_addr_t regs; + struct gpio_ra_irq_info *irq_info; + uint32_t irq_info_size; + uint16_t port; +}; + +struct gpio_ra_data { + struct gpio_driver_data common; + struct gpio_ra_pin_irq_info port_irq_info[16]; + sys_slist_t callbacks; +}; + +static inline uint32_t gpio_ra_irq_info_event(const struct gpio_ra_irq_info *info) +{ + return ((info->flags & RA_ICU_FLAG_EVENT_MASK) >> RA_ICU_FLAG_EVENT_OFFSET); +} + +static void gpio_ra_isr(const struct device *dev, uint32_t port_irq) +{ + struct gpio_ra_data *data = dev->data; + const struct gpio_ra_pin_irq_info *pin_irq = &data->port_irq_info[port_irq]; + const int irq = ra_icu_query_exists_irq(gpio_ra_irq_info_event(pin_irq->info)); + + if (irq >= 0) { + gpio_fire_callbacks(&data->callbacks, dev, BIT(pin_irq->pin)); + ra_icu_clear_int_flag(irq); + } +} + +static const struct gpio_ra_irq_info *query_irq_info(const struct device *dev, uint32_t pin) +{ + const struct gpio_ra_config *config = dev->config; + + for (int i = 0; i < config->irq_info_size; i++) { + const struct gpio_ra_irq_info *info = &config->irq_info[i]; + + for (int j = 0; j < info->num; j++) { + if (info->pins[j] == pin) { + return info; + } + } + } + + return NULL; +} + +static inline uint32_t reg_read(const struct device *dev, size_t offset) +{ + const struct gpio_ra_config *config = dev->config; + + return sys_read32(config->regs + offset); +} + +static inline void reg_write(const struct device *dev, size_t offset, uint32_t value) +{ + const struct gpio_ra_config *config = dev->config; + + sys_write32(value, config->regs + offset); +} + +static inline uint32_t port_read(const struct device *dev) +{ + return reg_read(dev, PCNTR2_OFFSET) & UINT16_MAX; +} + +static int port_write(const struct device *dev, uint16_t value, uint16_t mask) +{ + const uint16_t set = value & mask; + const uint16_t clr = (~value) & mask; + + reg_write(dev, PCNTR3_OFFSET, (clr << PCNTR3_PORR0_OFFSET) | set << PCNTR3_POSR0_OFFSET); + + return 0; +} + +static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const enum gpio_int_mode mode = + flags & (GPIO_INT_EDGE | GPIO_INT_DISABLE | GPIO_INT_ENABLE); + const enum gpio_int_trig trig = flags & (GPIO_INT_LOW_0 | GPIO_INT_HIGH_1); + const struct gpio_ra_config *config = dev->config; + struct gpio_ra_data *data = dev->data; + struct pinctrl_ra_pin pincfg = {0}; + + if ((flags & GPIO_OUTPUT) && (flags & GPIO_INPUT)) { + /* Pin cannot be configured as input and output */ + return -ENOTSUP; + } else if (!(flags & (GPIO_INPUT | GPIO_OUTPUT))) { + /* Pin has to be configured as input or output */ + return -ENOTSUP; + } + + if (flags & GPIO_OUTPUT) { + pincfg.config |= BIT(PmnPFS_PDR_POS); + } + + if (flags & GPIO_PULL_UP) { + pincfg.config |= BIT(PmnPFS_PCR_POS); + } + + if ((flags & GPIO_SINGLE_ENDED) && (flags & GPIO_LINE_OPEN_DRAIN)) { + pincfg.config |= BIT(PmnPFS_NCODR_POS); + } + + if (flags & GPIO_INT_ENABLE) { + pincfg.config |= BIT(PmnPFS_ISEL_POS); + } + + pincfg.config &= ~BIT(PmnPFS_PMR_POS); + + pincfg.pin = pin; + pincfg.port = config->port; + + if (flags & GPIO_INT_ENABLE) { + const struct gpio_ra_irq_info *irq_info; + uint32_t intcfg; + int irqn; + + if (mode == GPIO_INT_MODE_LEVEL) { + if (trig != GPIO_INT_TRIG_LOW) { + return -ENOTSUP; + } + + intcfg = ICU_LOW_LEVEL; + } else if (mode == GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + intcfg = ICU_FALLING; + break; + case GPIO_INT_TRIG_HIGH: + intcfg = ICU_RISING; + break; + case GPIO_INT_TRIG_BOTH: + intcfg = ICU_BOTH_EDGE; + break; + default: + return -ENOTSUP; + } + } else { + return -ENOTSUP; + } + + irq_info = query_irq_info(dev, pin); + if (irq_info == NULL) { + return -EINVAL; + } + + irqn = ra_icu_irq_connect_dynamic( + irq_info->irq, irq_info->priority, irq_info->isr, dev, + (intcfg << RA_ICU_FLAG_INTCFG_OFFSET) | irq_info->flags); + if (irqn < 0) { + return irqn; + } + + data->port_irq_info[irq_info->port_irq].pin = pin; + data->port_irq_info[irq_info->port_irq].info = irq_info; + + irq_enable(irqn); + } + + return pinctrl_configure_pins(&pincfg, 1, PINCTRL_REG_NONE); +} + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_ra_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *flags) +{ + const struct gpio_ra_config *config = dev->config; + const struct gpio_ra_irq_info *irq_info; + struct pinctrl_ra_pin pincfg; + ra_isr_handler cb; + const void *cbarg; + uint32_t intcfg; + int irqn; + int err; + + memset(flags, 0, sizeof(gpio_flags_t)); + + err = pinctrl_ra_query_config(config->port, pin, &pincfg); + if (err < 0) { + return err; + } + + if (pincfg.config & BIT(PmnPFS_PDR_POS)) { + *flags |= GPIO_OUTPUT; + } else { + *flags |= GPIO_INPUT; + } + + if (pincfg.config & BIT(PmnPFS_ISEL_POS)) { + *flags |= GPIO_INT_ENABLE; + } + + if (pincfg.config & BIT(PmnPFS_PCR_POS)) { + *flags |= GPIO_PULL_UP; + } + + irq_info = query_irq_info(dev, pin); + if (irq_info == NULL) { + return 0; + } + + irqn = ra_icu_query_exists_irq(gpio_ra_irq_info_event(irq_info)); + if (irqn < 0) { + return 0; + } + + ra_icu_query_irq_config(irqn, &intcfg, &cb, &cbarg); + + if (cbarg != dev) { + return 0; + } + + if (intcfg == ICU_FALLING) { + *flags |= GPIO_INT_TRIG_LOW; + *flags |= GPIO_INT_MODE_EDGE; + } else if (intcfg == ICU_RISING) { + *flags |= GPIO_INT_TRIG_HIGH; + *flags |= GPIO_INT_MODE_EDGE; + } else if (intcfg == ICU_BOTH_EDGE) { + *flags |= GPIO_INT_TRIG_BOTH; + *flags |= GPIO_INT_MODE_EDGE; + } else if (intcfg == ICU_LOW_LEVEL) { + *flags |= GPIO_INT_TRIG_LOW; + *flags |= GPIO_INT_MODE_LEVEL; + } + + return 0; +} +#endif + +static int gpio_ra_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + *value = port_read(dev); + + return 0; +} + +static int gpio_ra_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + uint16_t port_val; + + port_val = port_read(dev); + port_val = (port_val & ~mask) | (value & mask); + return port_write(dev, port_val, UINT16_MAX); +} + +static int gpio_ra_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + uint16_t port_val; + + port_val = port_read(dev); + port_val |= pins; + return port_write(dev, port_val, UINT16_MAX); +} + +static int gpio_ra_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + uint16_t port_val; + + port_val = port_read(dev); + port_val &= ~pins; + return port_write(dev, port_val, UINT16_MAX); +} + +static int gpio_ra_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + uint16_t port_val; + + port_val = port_read(dev); + port_val ^= pins; + return port_write(dev, port_val, UINT16_MAX); +} + +static int gpio_ra_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_ra_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static int gpio_ra_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + gpio_flags_t pincfg; + int err; + + err = gpio_ra_pin_get_config(dev, pin, &pincfg); + if (err < 0) { + return err; + } + + return gpio_ra_pin_configure(dev, pin, pincfg | mode | trig); +} + +static const struct gpio_driver_api gpio_ra_driver_api = { + .pin_configure = gpio_ra_pin_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_ra_pin_get_config, +#endif + .port_get_raw = gpio_ra_port_get_raw, + .port_set_masked_raw = gpio_ra_port_set_masked_raw, + .port_set_bits_raw = gpio_ra_port_set_bits_raw, + .port_clear_bits_raw = gpio_ra_port_clear_bits_raw, + .port_toggle_bits = gpio_ra_port_toggle_bits, + .pin_interrupt_configure = gpio_ra_pin_interrupt_configure, + .manage_callback = gpio_ra_manage_callback, +}; + +#define RA_NUM_PORT_IRQ0 0 +#define RA_NUM_PORT_IRQ1 1 +#define RA_NUM_PORT_IRQ2 2 +#define RA_NUM_PORT_IRQ3 3 +#define RA_NUM_PORT_IRQ4 4 +#define RA_NUM_PORT_IRQ5 5 +#define RA_NUM_PORT_IRQ6 6 +#define RA_NUM_PORT_IRQ7 7 +#define RA_NUM_PORT_IRQ8 8 +#define RA_NUM_PORT_IRQ9 9 +#define RA_NUM_PORT_IRQ10 10 +#define RA_NUM_PORT_IRQ11 11 +#define RA_NUM_PORT_IRQ12 12 +#define RA_NUM_PORT_IRQ13 13 +#define RA_NUM_PORT_IRQ14 14 +#define RA_NUM_PORT_IRQ15 15 + +#define GPIO_RA_DECL_PINS(n, p, i) \ + const uint8_t _CONCAT(n, ___pins##i[]) = {DT_FOREACH_PROP_ELEM_SEP( \ + n, _CONCAT(DT_STRING_TOKEN_BY_IDX(n, p, i), _pins), DT_PROP_BY_IDX, (,))}; + +#define GPIO_RA_IRQ_INFO(n, p, i) \ + { \ + .port_irq = _CONCAT(RA_NUM_, DT_STRING_UPPER_TOKEN_BY_IDX(n, p, i)), \ + .irq = DT_IRQ_BY_IDX(n, i, irq), \ + .flags = DT_IRQ_BY_IDX(n, i, flags), \ + .priority = DT_IRQ_BY_IDX(n, i, priority), \ + .pins = _CONCAT(n, ___pins##i), \ + .num = ARRAY_SIZE(_CONCAT(n, ___pins##i)), \ + .isr = _CONCAT(n, _CONCAT(gpio_ra_isr_, DT_STRING_TOKEN_BY_IDX(n, p, i))), \ + }, + +#define GPIO_RA_ISR_DECL(n, p, i) \ + static void _CONCAT(n, _CONCAT(gpio_ra_isr_, DT_STRING_TOKEN_BY_IDX(n, p, i)))( \ + const void *arg) \ + { \ + gpio_ra_isr((const struct device *)arg, \ + _CONCAT(RA_NUM_, DT_STRING_UPPER_TOKEN_BY_IDX(n, p, i))); \ + } + +#define GPIO_RA_INIT(idx) \ + static struct gpio_ra_data gpio_ra_data_##idx = {}; \ + DT_INST_FOREACH_PROP_ELEM(idx, interrupt_names, GPIO_RA_DECL_PINS); \ + DT_INST_FOREACH_PROP_ELEM(idx, interrupt_names, GPIO_RA_ISR_DECL); \ + struct gpio_ra_irq_info gpio_ra_irq_info_##idx[] = { \ + DT_INST_FOREACH_PROP_ELEM(idx, interrupt_names, GPIO_RA_IRQ_INFO)}; \ + static struct gpio_ra_config gpio_ra_config_##idx = { \ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx), \ + }, \ + .regs = DT_INST_REG_ADDR(idx), \ + .port = (DT_INST_REG_ADDR(idx) - DT_REG_ADDR(DT_NODELABEL(ioport0))) / \ + DT_INST_REG_SIZE(idx), \ + .irq_info = gpio_ra_irq_info_##idx, \ + .irq_info_size = ARRAY_SIZE(gpio_ra_irq_info_##idx), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, NULL, NULL, &gpio_ra_data_##idx, &gpio_ra_config_##idx, \ + PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_ra_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_RA_INIT) diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi index 880ece373d3..5a7fd9bbc5a 100644 --- a/dts/arm/renesas/ra/ra-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { @@ -115,6 +116,129 @@ }; }; + ioport0: gpio@40040000 { + compatible = "renesas,ra-gpio"; + reg = <0x40040000 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupts = , + , + , + , + , + ; + interrupt-names = "port-irq2", "port-irq3", "port-irq6", + "port-irq7", "port-irq10", "port-irq15"; + port-irq2-pins = <2>; + port-irq3-pins = <4>; + port-irq6-pins = <0>; + port-irq7-pins = <1 15>; + port-irq10-pins = <5>; + port-irq15-pins = <11>; + status = "disabled"; + }; + + ioport1: gpio@40040020 { + compatible = "renesas,ra-gpio"; + reg = <0x40040020 0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupts = , + , + , + , + ; + interrupt-names = "port-irq0", "port-irq1", "port-irq2", + "port-irq3", "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; + ngpios = <16>; + status = "disabled"; + }; + + ioport2: gpio@40040040 { + compatible = "renesas,ra-gpio"; + reg = <0x40040040 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupts = , + , + , + , + ; + interrupt-names = "port-irq0", "port-irq1", "port-irq2", + "port-irq3", "port-irq9"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; + status = "disabled"; + }; + + ioport3: gpio@40040060 { + compatible = "renesas,ra-gpio"; + reg = <0x40040060 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupts = , + , + , + ; + interrupt-names = "port-irq5", "port-irq6", "port-irq8", "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; + status = "disabled"; + }; + + ioport4: gpio@40040080 { + compatible = "renesas,ra-gpio"; + reg = <0x40040080 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "port-irq0", "port-irq4", "port-irq5", "port-irq6", + "port-irq7", "port-irq8", "port-irq9"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + status = "disabled"; + }; + + ioport5: gpio@400400a0 { + compatible = "renesas,ra-gpio"; + reg = <0x400400a0 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupts = , + , + ; + interrupt-names = "port-irq11", "port-irq12", "port-irq14"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5>; + status = "disabled"; + }; + pinctrl: pinctrl@40040800 { compatible = "renesas,ra-pinctrl"; reg = <0x40040800 0x500 0x40040d03 0x1>; diff --git a/dts/arm/renesas/ra/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4-cm4-common.dtsi index 82d5d48a037..08f054593a0 100644 --- a/dts/arm/renesas/ra/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4-cm4-common.dtsi @@ -5,3 +5,43 @@ */ #include + +/ { + soc { + ioport6: gpio@400400c0 { + compatible = "renesas,ra-gpio"; + reg = <0x400400c0 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport7: gpio@400400e0 { + compatible = "renesas,ra-gpio"; + reg = <0x400400e0 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport8: gpio@40040100 { + compatible = "renesas,ra-gpio"; + reg = <0x40040100 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport9: gpio@40040120 { + compatible = "renesas,ra-gpio"; + reg = <0x40040120 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + }; +}; diff --git a/dts/bindings/gpio/renesas,ra-gpio.yaml b/dts/bindings/gpio/renesas,ra-gpio.yaml new file mode 100644 index 00000000000..ad18a0d45da --- /dev/null +++ b/dts/bindings/gpio/renesas,ra-gpio.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA series GPIO + +compatible: "renesas,ra-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + port-irq0-pins: + type: array + description: Pins allow to assign port-irq0 + + port-irq1-pins: + type: array + description: Pins allow to assign port-irq1 + + port-irq2-pins: + type: array + description: Pins allow to assign port-irq2 + + port-irq3-pins: + type: array + description: Pins allow to assign port-irq3 + + port-irq4-pins: + type: array + description: Pins allow to assign port-irq4 + + port-irq5-pins: + type: array + description: Pins allow to assign port-irq5 + + port-irq6-pins: + type: array + description: Pins allow to assign port-irq6 + + port-irq7-pins: + type: array + description: Pins allow to assign port-irq7 + + port-irq8-pins: + type: array + description: Pins allow to assign port-irq8 + + port-irq9-pins: + type: array + description: Pins allow to assign port-irq9 + + port-irq10-pins: + type: array + description: Pins allow to assign port-irq10 + + port-irq11-pins: + type: array + description: Pins allow to assign port-irq11 + + port-irq12-pins: + type: array + description: Pins allow to assign port-irq12 + + port-irq13-pins: + type: array + description: Pins allow to assign port-irq13 + + port-irq14-pins: + type: array + description: Pins allow to assign port-irq14 + + port-irq15-pins: + type: array + description: Pins allow to assign port-irq15 + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags From 69a3930a1930a8a1d666a6425e195acf264c6367 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 5 Jul 2023 02:59:26 +0900 Subject: [PATCH 2886/4498] drivers: serial: Add UART driver for Renesas RA series Adding initial support for Renesas RA UART. To avoid complicating initial code for supporting the SoC, I have implemented only the bare minimum for now. Signed-off-by: TOKITA Hiroshi --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 2 + drivers/serial/Kconfig.ra | 11 + drivers/serial/uart_ra.c | 395 +++++++++++++++++++ dts/arm/renesas/ra/ra-cm4-common.dtsi | 55 +++ dts/arm/renesas/ra/ra4-cm4-common.dtsi | 18 + dts/bindings/misc/renesas,ra-sci.yaml | 15 + dts/bindings/serial/renesas,ra-uart-sci.yaml | 8 + 8 files changed, 505 insertions(+) create mode 100644 drivers/serial/Kconfig.ra create mode 100644 drivers/serial/uart_ra.c create mode 100644 dts/bindings/misc/renesas,ra-sci.yaml create mode 100644 dts/bindings/serial/renesas,ra-uart-sci.yaml diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 9ee77115e2b..62336a8980e 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -66,6 +66,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_INTEL_LW uart_intel_lw.c) +zephyr_library_sources_ifdef(CONFIG_UART_RA uart_ra.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 18845f8e394..4a42a81aadd 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -245,4 +245,6 @@ source "drivers/serial/Kconfig.bcm2711" source "drivers/serial/Kconfig.intel_lw" +source "drivers/serial/Kconfig.ra" + endif # SERIAL diff --git a/drivers/serial/Kconfig.ra b/drivers/serial/Kconfig.ra new file mode 100644 index 00000000000..3e35afed2de --- /dev/null +++ b/drivers/serial/Kconfig.ra @@ -0,0 +1,11 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config UART_RA + bool "Renesas RA Series UART Driver" + default y + depends on DT_HAS_RENESAS_RA_UART_SCI_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + Enable Renesas RA series UART driver. diff --git a/drivers/serial/uart_ra.c b/drivers/serial/uart_ra.c new file mode 100644 index 00000000000..a93ffff4b45 --- /dev/null +++ b/drivers/serial/uart_ra.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_uart_sci + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(ra_uart_sci, CONFIG_UART_LOG_LEVEL); + +struct uart_ra_cfg { + mem_addr_t regs; + const struct device *clock_dev; + clock_control_subsys_t clock_id; + const struct pinctrl_dev_config *pcfg; +}; + +struct uart_ra_data { + struct uart_config current_config; + uint32_t clk_rate; + struct k_spinlock lock; +}; + +#define REG_MASK(reg) (BIT_MASK(_CONCAT(reg, _LEN)) << _CONCAT(reg, _POS)) + +/* Registers */ +#define SMR 0x00 /*!< Serial Mode Register */ +#define BRR 0x01 /*!< Bit Rate Register */ +#define SCR 0x02 /*!< Serial Control Register */ +#define TDR 0x03 /*!< Transmit Data Register */ +#define SSR 0x04 /*!< Serial Status Register */ +#define RDR 0x05 /*!< Receive Data Register */ +#define SEMR 0x07 /*!< Serial Extended Mode Register */ +#define MDDR 0x12 /*!< Modulation Duty Register */ +#define LSR 0x18 /*!< Line Status Register */ + +/* + * SMR (Serial Mode Register) + * + * - CKS[0..2]: Clock Select + * - MP[2..3]: Multi-Processor Mode(Valid only in asynchronous mode) + * - STOP[3..4]: Stop Bit Length(Valid only in asynchronous mode) + * - PM[4..5]: Parity Mode (Valid only when the PE bit is 1) + * - PE[5..6]: Parity Enable(Valid only in asynchronous mode) + * - CHR[6..7]: Character Length(Valid only in asynchronous mode) + * - CM[7..8]: Communication Mode + */ +#define SMR_CKS_POS (0) +#define SMR_CKS_LEN (2) +#define SMR_MP_POS (2) +#define SMR_MP_LEN (1) +#define SMR_STOP_POS (3) +#define SMR_STOP_LEN (1) +#define SMR_PM_POS (4) +#define SMR_PM_LEN (1) +#define SMR_PE_POS (5) +#define SMR_PE_LEN (1) +#define SMR_CHR_POS (6) +#define SMR_CHR_LEN (1) +#define SMR_CM_POS (7) +#define SMR_CM_LEN (1) + +/** + * SCR (Serial Control Register) + * + * - CKE[0..2]: Clock Enable + * - TEIE[2..3]: Transmit End Interrupt Enable + * - MPIE[3..4]: Multi-Processor Interrupt Enable (Valid in asynchronous + * - RE[4..5]: Receive Enable + * - TE[5..6]: Transmit Enable + * - RIE[6..7]: Receive Interrupt Enable + * - TIE[7..8]: Transmit Interrupt Enable + */ +#define SCR_CKE_POS (0) +#define SCR_CKE_LEN (2) +#define SCR_TEIE_POS (2) +#define SCR_TEIE_LEN (1) +#define SCR_MPIE_POS (3) +#define SCR_MPIE_LEN (1) +#define SCR_RE_POS (4) +#define SCR_RE_LEN (1) +#define SCR_TE_POS (5) +#define SCR_TE_LEN (1) +#define SCR_RIE_POS (6) +#define SCR_RIE_LEN (1) +#define SCR_TIE_POS (7) +#define SCR_TIE_LEN (1) + +/** + * SSR (Serial Status Register) + * + * - MPBT[0..1]: Multi-Processor Bit Transfer + * - MPB[1..2]: Multi-Processor + * - TEND[2..3]: Transmit End Flag + * - PER[3..4]: Parity Error Flag + * - FER[4..5]: Framing Error Flag + * - ORER[5..6]: Overrun Error Flag + * - RDRF[6..7]: Receive Data Full Flag + * - TDRE[7..8]: Transmit Data Empty Flag + */ +#define SSR_MPBT_POS (0) +#define SSR_MPBT_LEN (1) +#define SSR_MPB_POS (1) +#define SSR_MPB_LEN (1) +#define SSR_TEND_POS (2) +#define SSR_TEND_LEN (1) +#define SSR_PER_POS (3) +#define SSR_PER_LEN (1) +#define SSR_FER_POS (4) +#define SSR_FER_LEN (1) +#define SSR_ORER_POS (5) +#define SSR_ORER_LEN (1) +#define SSR_RDRF_POS (6) +#define SSR_RDRF_LEN (1) +#define SSR_TDRE_POS (7) +#define SSR_TDRE_LEN (1) + +/** + * SEMR (Serial Extended Mode Register) + * + * - ACS0[0..1]: Asynchronous Mode Clock Source Select + * - PADIS[1..2]: Preamble function Disable + * - BRME[2..3]: Bit Rate Modulation Enable + * - ABCSE[3..4]: Asynchronous Mode Extended Base Clock Select + * - ABCS[4..5]: Asynchronous Mode Base Clock Select + * - NFEN[5..6]: Digital Noise Filter Function Enable + * - BGDM[6..7]: Baud Rate Generator Double-Speed Mode Select + * - RXDESEL[7..8]: Asynchronous Start Bit Edge Detection Select + */ +#define SEMR_ACS0_POS (0) +#define SEMR_ACS0_LEN (1) +#define SEMR_PADIS_POS (1) +#define SEMR_PADIS_LEN (1) +#define SEMR_BRME_POS (2) +#define SEMR_BRME_LEN (1) +#define SEMR_ABCSE_POS (3) +#define SEMR_ABCSE_LEN (1) +#define SEMR_ABCS_POS (4) +#define SEMR_ABCS_LEN (1) +#define SEMR_NFEN_POS (5) +#define SEMR_NFEN_LEN (1) +#define SEMR_BGDM_POS (6) +#define SEMR_BGDM_LEN (1) +#define SEMR_RXDESEL_POS (7) +#define SEMR_RXDESEL_LEN (1) + +/** + * LSR (Line Status Register) + * + * - ORER[0..1]: Overrun Error Flag + * - FNUM[2..7]: Framing Error Count + * - PNUM[8..13]: Parity Error Count + */ +#define LSR_ORER_POS (0) +#define LSR_ORER_LEN (1) +#define LSR_FNUM_POS (2) +#define LSR_FNUM_LEN (5) +#define LSR_PNUM_POS (8) +#define LSR_PNUM_LEN (5) + +static uint8_t uart_ra_read_8(const struct device *dev, + uint32_t offs) +{ + const struct uart_ra_cfg *config = dev->config; + + return sys_read8(config->regs + offs); +} + +static void uart_ra_write_8(const struct device *dev, + uint32_t offs, uint8_t value) +{ + const struct uart_ra_cfg *config = dev->config; + + sys_write8(value, config->regs + offs); +} + +static uint16_t uart_ra_read_16(const struct device *dev, + uint32_t offs) +{ + const struct uart_ra_cfg *config = dev->config; + + return sys_read16(config->regs + offs); +} + +static void uart_ra_write_16(const struct device *dev, + uint32_t offs, uint16_t value) +{ + const struct uart_ra_cfg *config = dev->config; + + sys_write16(value, config->regs + offs); +} + +static void uart_ra_set_baudrate(const struct device *dev, + uint32_t baud_rate) +{ + struct uart_ra_data *data = dev->data; + uint8_t reg_val; + + reg_val = uart_ra_read_8(dev, SEMR); + reg_val |= REG_MASK(SEMR_BGDM); + reg_val &= ~(REG_MASK(SEMR_BRME) | REG_MASK(SEMR_ABCSE) | REG_MASK(SEMR_ABCS)); + uart_ra_write_8(dev, SEMR, reg_val); + + reg_val = (data->clk_rate / (16 * data->current_config.baudrate)) - 1; + uart_ra_write_8(dev, BRR, reg_val); +} + +static int uart_ra_poll_in(const struct device *dev, unsigned char *p_char) +{ + struct uart_ra_data *data = dev->data; + int ret = 0; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if ((uart_ra_read_8(dev, SSR) & REG_MASK(SSR_RDRF)) == 0) { + ret = -1; + goto unlock; + } + + *p_char = uart_ra_read_8(dev, RDR); +unlock: + k_spin_unlock(&data->lock, key); + + return ret; +} + +static void uart_ra_poll_out(const struct device *dev, unsigned char out_char) +{ + struct uart_ra_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + uart_ra_write_8(dev, TDR, out_char); + while (!(uart_ra_read_8(dev, SSR) & REG_MASK(SSR_TEND)) || + !(uart_ra_read_8(dev, SSR) & REG_MASK(SSR_TDRE))) { + ; + } + k_spin_unlock(&data->lock, key); +} + +static int uart_ra_configure(const struct device *dev, + const struct uart_config *cfg) +{ + struct uart_ra_data *data = dev->data; + + uint16_t reg_val; + k_spinlock_key_t key; + + if (cfg->parity != UART_CFG_PARITY_NONE || cfg->stop_bits != UART_CFG_STOP_BITS_1 || + cfg->data_bits != UART_CFG_DATA_BITS_8 || cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { + return -ENOTSUP; + } + + key = k_spin_lock(&data->lock); + + /* Disable Transmit and Receive */ + reg_val = uart_ra_read_8(dev, SCR); + reg_val &= ~(REG_MASK(SCR_TE) | REG_MASK(SCR_RE)); + uart_ra_write_8(dev, SCR, reg_val); + + /* Resetting Errors Registers */ + reg_val = uart_ra_read_8(dev, SSR); + reg_val &= ~(REG_MASK(SSR_PER) | REG_MASK(SSR_FER) | REG_MASK(SSR_ORER) | + REG_MASK(SSR_RDRF) | REG_MASK(SSR_TDRE)); + uart_ra_write_8(dev, SSR, reg_val); + + reg_val = uart_ra_read_16(dev, LSR); + reg_val &= ~(REG_MASK(LSR_ORER)); + uart_ra_write_16(dev, LSR, reg_val); + + /* Select internal clock */ + reg_val = uart_ra_read_8(dev, SCR); + reg_val &= ~(REG_MASK(SCR_CKE)); + uart_ra_write_8(dev, SCR, reg_val); + + /* Serial Configuration (8N1) & Clock divider selection */ + reg_val = uart_ra_read_8(dev, SMR); + reg_val &= ~(REG_MASK(SMR_CM) | REG_MASK(SMR_CHR) | REG_MASK(SMR_PE) | REG_MASK(SMR_PM) | + REG_MASK(SMR_STOP) | REG_MASK(SMR_CKS)); + uart_ra_write_8(dev, SMR, reg_val); + + /* Set baudrate */ + uart_ra_set_baudrate(dev, cfg->baudrate); + + /* Enable Transmit & Receive + disable Interrupts */ + reg_val = uart_ra_read_8(dev, SCR); + reg_val |= (REG_MASK(SCR_TE) | REG_MASK(SCR_RE)); + reg_val &= + ~(REG_MASK(SCR_TIE) | REG_MASK(SCR_RIE) | REG_MASK(SCR_MPIE) | REG_MASK(SCR_TEIE)); + uart_ra_write_8(dev, SCR, reg_val); + + data->current_config = *cfg; + + k_spin_unlock(&data->lock, key); + + return 0; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_ra_config_get(const struct device *dev, + struct uart_config *cfg) +{ + struct uart_ra_data *data = dev->data; + + *cfg = data->current_config; + + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +static int uart_ra_init(const struct device *dev) +{ + const struct uart_ra_cfg *config = dev->config; + struct uart_ra_data *data = dev->data; + int ret; + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + if (!device_is_ready(config->clock_dev)) { + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, config->clock_id); + if (ret < 0) { + return ret; + } + + ret = clock_control_get_rate(config->clock_dev, config->clock_id, &data->clk_rate); + if (ret < 0) { + return ret; + } + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + ret = uart_ra_configure(dev, &data->current_config); + if (ret != 0) { + return ret; + } + + return 0; +} + +static const struct uart_driver_api uart_ra_driver_api = { + .poll_in = uart_ra_poll_in, + .poll_out = uart_ra_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_ra_configure, + .config_get = uart_ra_config_get, +#endif +}; + +/* Device Instantiation */ +#define UART_RCAR_INIT_CFG(n) \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(n)); \ + static const struct uart_ra_cfg uart_ra_cfg_##n = { \ + .regs = DT_REG_ADDR(DT_INST_PARENT(n)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \ + .clock_id = \ + (clock_control_subsys_t)DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(n), 0, id), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(n)), \ + } + +#define UART_RCAR_INIT(n) \ + UART_RCAR_INIT_CFG(n); \ + \ + static struct uart_ra_data uart_ra_data_##n = { \ + .current_config = { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = UART_CFG_PARITY_NONE, \ + .stop_bits = UART_CFG_STOP_BITS_1, \ + .data_bits = UART_CFG_DATA_BITS_8, \ + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + uart_ra_init, \ + NULL, \ + &uart_ra_data_##n, \ + &uart_ra_cfg_##n, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_ra_driver_api); \ + \ + +DT_INST_FOREACH_STATUS_OKAY(UART_RCAR_INIT) diff --git a/dts/arm/renesas/ra/ra-cm4-common.dtsi b/dts/arm/renesas/ra/ra-cm4-common.dtsi index 5a7fd9bbc5a..60157ab8b72 100644 --- a/dts/arm/renesas/ra/ra-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra-cm4-common.dtsi @@ -245,6 +245,61 @@ reg-names = "pfs", "pmisc_pwpr"; status = "okay"; }; + + sci0: sci@40070000 { + compatible = "renesas,ra-uart-sci"; + reg = <0x40070000 0x20>; + interrupts = , + , + , + , + , + ; + interrupt-names = "rxi", "txi", "tei", "eri", "am", "rxi-or-eri"; + clocks = <&cgc RA_CLOCK_SCI(0)>; + #clock-cells = <1>; + status = "disabled"; + uart { + compatible = "renesas,ra-uart-sci"; + status = "disabled"; + }; + }; + + sci1: sci@40070020 { + compatible = "renesas,ra-uart-sci"; + reg = <0x40070020 0x20>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "tei", "eri", "am"; + clocks = <&cgc RA_CLOCK_SCI(1)>; + #clock-cells = <1>; + status = "disabled"; + uart { + compatible = "renesas,ra-uart-sci"; + status = "disabled"; + }; + }; + + sci9: sci@40070120 { + compatible = "renesas,ra-uart-sci"; + reg = <0x40070120 0x20>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "tei", "eri", "am"; + clocks = <&cgc RA_CLOCK_SCI(9)>; + #clock-cells = <1>; + status = "disabled"; + uart { + compatible = "renesas,ra-uart-sci"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/ra/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4-cm4-common.dtsi index 08f054593a0..1d2397f85de 100644 --- a/dts/arm/renesas/ra/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4-cm4-common.dtsi @@ -43,5 +43,23 @@ ngpios = <16>; status = "disabled"; }; + + sci2: sci@40070040 { + compatible = "renesas,ra-sci"; + reg = <0x40070040 0x20>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "tei", "eri", "am"; + clocks = <&cgc RA_CLOCK_SCI(2)>; + #clock-cells = <1>; + status = "disabled"; + uart { + compatible = "renesas,ra-uart-sci"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/bindings/misc/renesas,ra-sci.yaml b/dts/bindings/misc/renesas,ra-sci.yaml new file mode 100644 index 00000000000..d5feedde201 --- /dev/null +++ b/dts/bindings/misc/renesas,ra-sci.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCI controller + +compatible: "renesas,ra-sci" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + clocks: + required: true diff --git a/dts/bindings/serial/renesas,ra-uart-sci.yaml b/dts/bindings/serial/renesas,ra-uart-sci.yaml new file mode 100644 index 00000000000..94229b06924 --- /dev/null +++ b/dts/bindings/serial/renesas,ra-uart-sci.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA Series SCI based UART controller + +compatible: "renesas,ra-uart-sci" + +include: [uart-controller.yaml] From 96c33f6d22b6e03baf287b92a0975964dcdb2c86 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 5 Jul 2023 03:01:39 +0900 Subject: [PATCH 2887/4498] boards: arm: add initial support for Arduino UNO R4 Minima Add support for the Arduino UNO R4 Minima. This board is the newest version of Arduino that uses Renesas RA4M1 SoC. This commit provides only limited support to simplify the initial support patch. Signed-off-by: TOKITA Hiroshi --- boards/arm/arduino_uno_r4/Kconfig.board | 6 ++ boards/arm/arduino_uno_r4/Kconfig.defconfig | 9 ++ .../arduino_uno_r4/arduino_uno_r4_common.dtsi | 13 +++ .../arduino_uno_r4_minima-pinctrl.dtsi | 15 ++++ .../arduino_uno_r4/arduino_uno_r4_minima.dts | 88 +++++++++++++++++++ .../arduino_uno_r4/arduino_uno_r4_minima.yaml | 12 +++ .../arduino_uno_r4_minima_defconfig | 25 ++++++ boards/arm/arduino_uno_r4/board.cmake | 6 ++ boards/arm/arduino_uno_r4/doc/index.rst | 64 ++++++++++++++ 9 files changed, 238 insertions(+) create mode 100644 boards/arm/arduino_uno_r4/Kconfig.board create mode 100644 boards/arm/arduino_uno_r4/Kconfig.defconfig create mode 100644 boards/arm/arduino_uno_r4/arduino_uno_r4_common.dtsi create mode 100644 boards/arm/arduino_uno_r4/arduino_uno_r4_minima-pinctrl.dtsi create mode 100644 boards/arm/arduino_uno_r4/arduino_uno_r4_minima.dts create mode 100644 boards/arm/arduino_uno_r4/arduino_uno_r4_minima.yaml create mode 100644 boards/arm/arduino_uno_r4/arduino_uno_r4_minima_defconfig create mode 100644 boards/arm/arduino_uno_r4/board.cmake create mode 100644 boards/arm/arduino_uno_r4/doc/index.rst diff --git a/boards/arm/arduino_uno_r4/Kconfig.board b/boards/arm/arduino_uno_r4/Kconfig.board new file mode 100644 index 00000000000..d56eff75387 --- /dev/null +++ b/boards/arm/arduino_uno_r4/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ARDUINO_UNO_R4_MINIMA + bool "Arduino Uno R4 Minima board" + depends on SOC_R7FA4M1AB3CFM diff --git a/boards/arm/arduino_uno_r4/Kconfig.defconfig b/boards/arm/arduino_uno_r4/Kconfig.defconfig new file mode 100644 index 00000000000..2d483f3bb38 --- /dev/null +++ b/boards/arm/arduino_uno_r4/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ARDUINO_UNO_R4_MINIMA + +config BOARD + default "arduino_uno_r4_minima" if BOARD_ARDUINO_UNO_R4_MINIMA + +endif # BOARD_ARDUINO_UNO_R4_MINIMA diff --git a/boards/arm/arduino_uno_r4/arduino_uno_r4_common.dtsi b/boards/arm/arduino_uno_r4/arduino_uno_r4_common.dtsi new file mode 100644 index 00000000000..472e1092f5f --- /dev/null +++ b/boards/arm/arduino_uno_r4/arduino_uno_r4_common.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Arduino Uno R4 Board"; + compatible = "renesas,r7fa4m1aB3cfm"; +}; diff --git a/boards/arm/arduino_uno_r4/arduino_uno_r4_minima-pinctrl.dtsi b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima-pinctrl.dtsi new file mode 100644 index 00000000000..c9538829a48 --- /dev/null +++ b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima-pinctrl.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + sci2_default: sci2_default { + group1 { + pinmux = , ; + }; + }; +}; diff --git a/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.dts b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.dts new file mode 100644 index 00000000000..18b1aea120c --- /dev/null +++ b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.dts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +#include "arduino_uno_r4_common.dtsi" +#include "arduino_uno_r4_minima-pinctrl.dtsi" + +/ { + model = "Arduino Uno R4 Minima"; + + chosen { + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + leds { + compatible = "gpio-leds"; + led: led { + gpios = <&ioport1 11 GPIO_ACTIVE_HIGH>; + }; + }; + + aliases { + led0 = &led; + }; +}; + +&sci2 { + status = "okay"; + pinctrl-0 = <&sci2_default>; + pinctrl-names = "default"; + uart2: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&ioport1 { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "bootloader"; + reg = <0x00000000 0x4000>; + read-only; + }; + + code_partition: partition@4000 { + label = "code"; + reg = <0x4000 0x3C000>; + read-only; + }; + }; +}; + +&fcu { + status = "okay"; +}; + +&hoco { + status = "okay"; + clock-frequency = <48000000>; +}; + +&cgc { + clock-source = <&hoco>; + iclk-div = <1>; + pclka-div = <1>; + pclkb-div = <2>; + pclkc-div = <1>; + pclkd-div = <1>; + fclk-div = <2>; +}; diff --git a/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.yaml b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.yaml new file mode 100644 index 00000000000..81f3a94866a --- /dev/null +++ b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima.yaml @@ -0,0 +1,12 @@ +identifier: arduino_uno_r4_minima +name: Arduino Uno R4 Minima +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 32 +supported: + - gpio + - uart diff --git a/boards/arm/arduino_uno_r4/arduino_uno_r4_minima_defconfig b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima_defconfig new file mode 100644 index 00000000000..8d44c120b3e --- /dev/null +++ b/boards/arm/arduino_uno_r4/arduino_uno_r4_minima_defconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_RA4M1=y +CONFIG_SOC_R7FA4M1AB3CFM=y + +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 + +CONFIG_BUILD_OUTPUT_HEX=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# enable GPIO +CONFIG_GPIO=y + +CONFIG_PINCTRL=y + +CONFIG_CLOCK_CONTROL=y + +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/arm/arduino_uno_r4/board.cmake b/boards/arm/arduino_uno_r4/board.cmake new file mode 100644 index 00000000000..a034dd9dcdf --- /dev/null +++ b/boards/arm/arduino_uno_r4/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(pyocd "--target=r7fa4m1ab") + +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/arduino_uno_r4/doc/index.rst b/boards/arm/arduino_uno_r4/doc/index.rst new file mode 100644 index 00000000000..e94c4c78902 --- /dev/null +++ b/boards/arm/arduino_uno_r4/doc/index.rst @@ -0,0 +1,64 @@ +.. _arduino_uno_r4: + +Arduino UNO R4 Minima +##################### + +Overview +******** + +The Arduino UNO R4 Minima is a development board featuring the Renesas RA4M1 SoC +in the Arduino form factor and is compatible with traditional Arduino. + +Programming and debugging +************************* + +Building & Flashing +=================== + +You can build and flash an application in the usual way (See +:ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for building and flashing the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: arduino_uno_r4_minima + :goals: build flash + +Debugging +========= + +Debugging also can be done in the usual way. +The following command is debugging the :zephyr:code-sample:`blinky` application. +Also, see the instructions specific to the debug server that you use. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: arduino_uno_r4_minima + :maybe-skip-config: + :goals: debug + + +Using pyOCD +----------- + +Various debug adapters, including cmsis-dap probes, can debug the Arduino UNO R4 with pyOCD. +The default configuration uses the pyOCD for debugging. +You must install CMSIS-Pack when flashing or debugging Arduino UNO R4 Minima with pyOCD. +If not installed yet, execute the following command to install CMSIS-Pack for Arduino UNO R4. + +.. code-block:: console + + pyocd pack install r7fa4m1ab + + +Restoring Arduino Bootloader +============================ + +If you corrupt the Arduino bootloader, you can restore it with the following command. + +.. code-block:: console + + wget https://raw.githubusercontent.com/arduino/ArduinoCore-renesas/main/bootloaders/UNO_R4/dfu_minima.hex + pyocd flash -e sector -a 0x0 -t r7fa4m1ab dfu_minima.hex From a17d49511f98e5dc377b2d7c80d99535001d5223 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 14 Aug 2023 22:54:08 +0900 Subject: [PATCH 2888/4498] tests: arch: arm: arm_irq_vector_table: exclude arduino_uno_r4_minima Renesas RA always uses interrupt handlers dynamically. But this test requires static vector tables. So, it needs to exclude platforms that use Renesas RA. Signed-off-by: TOKITA Hiroshi --- tests/arch/arm/arm_irq_vector_table/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/arch/arm/arm_irq_vector_table/testcase.yaml b/tests/arch/arm/arm_irq_vector_table/testcase.yaml index b1bacbca309..62a6bb7e912 100644 --- a/tests/arch/arm/arm_irq_vector_table/testcase.yaml +++ b/tests/arch/arm/arm_irq_vector_table/testcase.yaml @@ -10,3 +10,4 @@ tests: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE platform_exclude: - mr_canhubk3 + - arduino_uno_r4_minima From 06cfbd4159fdd6cc0714da8390e97b6b135f4011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Jakie=C5=82a?= Date: Tue, 18 Jul 2023 13:57:26 +0000 Subject: [PATCH 2889/4498] drivers: power_domain: Introduce a gpio monitor driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Power rails of some peripherals are controlled externally. This is a case in embedded controllers, where the power of some I2C devices are managed by the main application processor. To ensure that zephyr drivers access the devices where is powered on, introduce a "monitoring" power domain. It works by registering interrupt handler with gpio a pin, so that when power state changes, it will notify relevant drivers. Additionaly add CONFIG_POWER_DOMAIN_INIT_PRIORITY to replace harcoded init priority. Fixes: #51349 Signed-off-by: Albert Jakieła --- drivers/power_domain/CMakeLists.txt | 1 + drivers/power_domain/Kconfig | 13 ++ drivers/power_domain/power_domain_gpio.c | 22 +-- .../power_domain/power_domain_gpio_monitor.c | 150 ++++++++++++++++++ .../power_domain/power_domain_intel_adsp.c | 18 +-- .../power-domain-gpio-monitor.yaml | 22 +++ 6 files changed, 206 insertions(+), 20 deletions(-) create mode 100644 drivers/power_domain/power_domain_gpio_monitor.c create mode 100644 dts/bindings/power-domain/power-domain-gpio-monitor.yaml diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index 0637e64f794..27b07c945f1 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -4,4 +4,5 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO power_domain_gpio.c) +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_monitor.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 6c8563d4724..22ffc388503 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -12,6 +12,12 @@ module = POWER_DOMAIN module-str = power_domain source "subsys/logging/Kconfig.template.log_config" +config POWER_DOMAIN_INIT_PRIORITY + int "Power domain init priority" + default 75 + help + Power domain initialization priority. + config POWER_DOMAIN_GPIO bool "GPIO controlled power domain" default y @@ -28,4 +34,11 @@ config POWER_DOMAIN_INTEL_ADSP help Include Intel ADSP power domain control mechanisms +config POWER_DOMAIN_GPIO_MONITOR + bool "GPIO monitor for sensing power on rail" + default y + depends on DT_HAS_POWER_DOMAIN_GPIO_MONITOR_ENABLED + depends on GPIO + select DEVICE_DEPS + endif diff --git a/drivers/power_domain/power_domain_gpio.c b/drivers/power_domain/power_domain_gpio.c index b4702ad13eb..15c60a65d75 100644 --- a/drivers/power_domain/power_domain_gpio.c +++ b/drivers/power_domain/power_domain_gpio.c @@ -125,17 +125,17 @@ static int pd_gpio_init(const struct device *dev) return pm_device_driver_init(dev, pd_gpio_pm_action); } -#define POWER_DOMAIN_DEVICE(id) \ - static const struct pd_gpio_config pd_gpio_##id##_cfg = { \ - .enable = GPIO_DT_SPEC_INST_GET(id, enable_gpios), \ - .startup_delay_us = DT_INST_PROP(id, startup_delay_us), \ - .off_on_delay_us = DT_INST_PROP(id, off_on_delay_us), \ - }; \ - static struct pd_gpio_data pd_gpio_##id##_data; \ - PM_DEVICE_DT_INST_DEFINE(id, pd_gpio_pm_action); \ - DEVICE_DT_INST_DEFINE(id, pd_gpio_init, PM_DEVICE_DT_INST_GET(id), \ - &pd_gpio_##id##_data, &pd_gpio_##id##_cfg, \ - POST_KERNEL, 75, \ +#define POWER_DOMAIN_DEVICE(id) \ + static const struct pd_gpio_config pd_gpio_##id##_cfg = { \ + .enable = GPIO_DT_SPEC_INST_GET(id, enable_gpios), \ + .startup_delay_us = DT_INST_PROP(id, startup_delay_us), \ + .off_on_delay_us = DT_INST_PROP(id, off_on_delay_us), \ + }; \ + static struct pd_gpio_data pd_gpio_##id##_data; \ + PM_DEVICE_DT_INST_DEFINE(id, pd_gpio_pm_action); \ + DEVICE_DT_INST_DEFINE(id, pd_gpio_init, PM_DEVICE_DT_INST_GET(id), \ + &pd_gpio_##id##_data, &pd_gpio_##id##_cfg, \ + POST_KERNEL, CONFIG_POWER_DOMAIN_INIT_PRIORITY, \ NULL); DT_INST_FOREACH_STATUS_OKAY(POWER_DOMAIN_DEVICE) diff --git a/drivers/power_domain/power_domain_gpio_monitor.c b/drivers/power_domain/power_domain_gpio_monitor.c new file mode 100644 index 00000000000..55e44570553 --- /dev/null +++ b/drivers/power_domain/power_domain_gpio_monitor.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT power_domain_gpio_monitor + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(power_domain_gpio_monitor, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +struct pd_gpio_monitor_config { + struct gpio_dt_spec power_good_gpio; +}; + +struct pd_gpio_monitor_data { + struct gpio_callback callback; + const struct device *dev; + bool is_powered; +}; + +struct pd_visitor_context { + const struct device *domain; + enum pm_device_action action; +}; + +static int pd_on_domain_visitor(const struct device *dev, void *context) +{ + struct pd_visitor_context *visitor_context = context; + + /* Only run action if the device is on the specified domain */ + if (!dev->pm || (dev->pm->domain != visitor_context->domain)) { + return 0; + } + + dev->pm->usage = 0; + (void)pm_device_action_run(dev, visitor_context->action); + return 0; +} + +static void pd_gpio_monitor_callback(const struct device *port, + struct gpio_callback *cb, gpio_port_pins_t pins) +{ + struct pd_gpio_monitor_data *data = CONTAINER_OF(cb, struct pd_gpio_monitor_data, callback); + const struct pd_gpio_monitor_config *config = data->dev->config; + const struct device *dev = data->dev; + struct pd_visitor_context context = {.domain = dev}; + int rc; + + rc = gpio_pin_get_dt(&config->power_good_gpio); + if (rc < 0) { + LOG_WRN("Failed to read gpio logic level"); + return; + } + + data->is_powered = rc; + if (rc == 0) { + context.action = PM_DEVICE_ACTION_SUSPEND; + (void)device_supported_foreach(dev, pd_on_domain_visitor, &context); + context.action = PM_DEVICE_ACTION_TURN_OFF; + (void)device_supported_foreach(dev, pd_on_domain_visitor, &context); + return; + } + + pm_device_children_action_run(data->dev, PM_DEVICE_ACTION_TURN_ON, NULL); +} + +static int pd_gpio_monitor_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct pd_gpio_monitor_data *data = dev->data; + + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_TURN_OFF: + return -ENOTSUP; + case PM_DEVICE_ACTION_RESUME: + if (!data->is_powered) { + return -EAGAIN; + } + break; + default: + break; + } + + return 0; +} + +static int pd_gpio_monitor_init(const struct device *dev) +{ + const struct pd_gpio_monitor_config *config = dev->config; + struct pd_gpio_monitor_data *data = dev->data; + int rc; + + data->dev = dev; + + if (!gpio_is_ready_dt(&config->power_good_gpio)) { + LOG_ERR("GPIO port %s is not ready", config->power_good_gpio.port->name); + return -ENODEV; + } + + rc = gpio_pin_configure_dt(&config->power_good_gpio, GPIO_INPUT); + if (rc) { + LOG_ERR("Failed to configure GPIO"); + goto unconfigure_pin; + } + + rc = gpio_pin_interrupt_configure_dt(&config->power_good_gpio, GPIO_INT_EDGE_BOTH); + if (rc) { + gpio_pin_configure_dt(&config->power_good_gpio, GPIO_DISCONNECTED); + LOG_ERR("Failed to configure GPIO interrupt"); + goto unconfigure_interrupt; + } + + gpio_init_callback(&data->callback, pd_gpio_monitor_callback, + BIT(config->power_good_gpio.pin)); + rc = gpio_add_callback_dt(&config->power_good_gpio, &data->callback); + if (rc) { + LOG_ERR("Failed to add GPIO callback"); + goto remove_callback; + } + + pm_device_init_suspended(dev); + return pm_device_runtime_enable(dev); +remove_callback: + gpio_remove_callback(config->power_good_gpio.port, &data->callback); +unconfigure_interrupt: + gpio_pin_interrupt_configure_dt(&config->power_good_gpio, GPIO_INT_DISABLE); +unconfigure_pin: + gpio_pin_configure_dt(&config->power_good_gpio, GPIO_DISCONNECTED); + return rc; +} + +#define POWER_DOMAIN_DEVICE(inst) \ + static const struct pd_gpio_monitor_config pd_gpio_monitor_config_##inst = { \ + .power_good_gpio = GPIO_DT_SPEC_INST_GET(inst, gpios), \ + }; \ + static struct pd_gpio_monitor_data pd_gpio_monitor_data_##inst; \ + PM_DEVICE_DT_INST_DEFINE(inst, pd_gpio_monitor_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, pd_gpio_monitor_init, \ + PM_DEVICE_DT_INST_GET(inst), &pd_gpio_monitor_data_##inst, \ + &pd_gpio_monitor_config_##inst, POST_KERNEL, \ + CONFIG_POWER_DOMAIN_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(POWER_DOMAIN_DEVICE) diff --git a/drivers/power_domain/power_domain_intel_adsp.c b/drivers/power_domain/power_domain_intel_adsp.c index c0ca87b652e..2fdd0ecf62e 100644 --- a/drivers/power_domain/power_domain_intel_adsp.c +++ b/drivers/power_domain/power_domain_intel_adsp.c @@ -76,14 +76,14 @@ static int pd_intel_adsp_init(const struct device *dev) #define DT_DRV_COMPAT intel_adsp_power_domain -#define POWER_DOMAIN_DEVICE(id) \ - static struct pg_bits pd_pg_reg##id = { \ - .SPA_bit = DT_INST_PROP(id, bit_position), \ - .CPA_bit = DT_INST_PROP(id, bit_position), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_pm_action); \ - DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_init, PM_DEVICE_DT_INST_GET(id),\ - &pd_pg_reg##id, NULL, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); +#define POWER_DOMAIN_DEVICE(id) \ + static struct pg_bits pd_pg_reg##id = { \ + .SPA_bit = DT_INST_PROP(id, bit_position), \ + .CPA_bit = DT_INST_PROP(id, bit_position), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_pm_action); \ + DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_init, PM_DEVICE_DT_INST_GET(id), \ + &pd_pg_reg##id, NULL, POST_KERNEL, \ + CONFIG_POWER_DOMAIN_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(POWER_DOMAIN_DEVICE) diff --git a/dts/bindings/power-domain/power-domain-gpio-monitor.yaml b/dts/bindings/power-domain/power-domain-gpio-monitor.yaml new file mode 100644 index 00000000000..d7dfd8779b7 --- /dev/null +++ b/dts/bindings/power-domain/power-domain-gpio-monitor.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: | + Simple monitorig power domain + + This power domain monitors the state of a GPIO pin to detect whether a power + rail is on/off. Therefore, performing resume/suspend on power domain won't + change physical state of power rails and those action won't be triggerd on + child nodes. Additionally, due to the asynchronous nature of monitoring a + pending transaction won't be interrupted by power state change. + +compatible: "power-domain-gpio-monitor" + +include: power-domain.yaml + +properties: + gpios: + type: phandle-array + required: true + description: | + GPIO to use to sense if rail is powered on. From 74ee677e4007a65c8e617a8ec64d11508544f725 Mon Sep 17 00:00:00 2001 From: ingram weeks Date: Fri, 27 Oct 2023 09:40:25 +0100 Subject: [PATCH 2890/4498] doc: README added to lora driver receive sample README added to lora driver receive sample. Signed-off-by: ingram weeks --- samples/drivers/lora/receive/README.rst | 55 +++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 samples/drivers/lora/receive/README.rst diff --git a/samples/drivers/lora/receive/README.rst b/samples/drivers/lora/receive/README.rst new file mode 100644 index 00000000000..8d08a5445ef --- /dev/null +++ b/samples/drivers/lora/receive/README.rst @@ -0,0 +1,55 @@ +.. zephyr:code-sample:: lora-receive + :name: LoRa receive + :relevant-api: lora_api + + Receive packets in both synchronous and asynchronous mode using the LoRa + radio. + +Overview +******** + +This sample demonstrates how to use the LoRa radio driver to receive packets +both synchronously and asynchronously. + +In order to successfully receive messages, build and flash the accompanying +LoRa send sample :zephyr:code-sample:`lora-send` on another board within range. + +As this sample receives a finite number of packets and then sleeps infinitely, +the user must be ready to inspect the console output immediately after +resetting the device. + +Building and Running +******************** + +Build and flash the sample as follows, changing ``b_l072z_lrwan1`` for +your board, where your board has a ``lora0`` alias in the devicetree. + +.. zephyr-app-commands:: + :zephyr-app: zephyr/samples/drivers/lora/receive + :host-os: unix + :board: b_l072z_lrwan1 + :goals: build flash + :compact: + +Sample Output +============= + +.. code-block:: console + + [00:00:00.235,000] lora_receive: Synchronous reception + [00:00:00.956,000] lora_receive: Received data: helloworld (RSSI:-60dBm, SNR:7dBm) + [00:00:02.249,000] lora_receive: Received data: helloworld (RSSI:-57dBm, SNR:9dBm) + [00:00:03.541,000] lora_receive: Received data: helloworld (RSSI:-57dBm, SNR:9dBm) + [00:00:04.834,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:04.834,000] lora_receive: Asynchronous reception + [00:00:06.127,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:07.419,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:08.712,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:10.004,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:11.297,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:12.590,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:13.884,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:15.177,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:16.470,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:17.762,000] lora_receive: Received data: helloworld (RSSI:-55dBm, SNR:9dBm) + [00:00:17.762,000] lora_receive: Stopping packet receptions From ad813977c53b91b8c0ced6c5c5174cc7af658f46 Mon Sep 17 00:00:00 2001 From: ingram weeks Date: Fri, 27 Oct 2023 09:45:04 +0100 Subject: [PATCH 2891/4498] doc: README updated for lora driver send sample README now cross-references the lora receive sample so that both can be used together more easily. Signed-off-by: ingram weeks --- samples/drivers/lora/send/README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/drivers/lora/send/README.rst b/samples/drivers/lora/send/README.rst index ce73aa09585..f2b46bcc917 100644 --- a/samples/drivers/lora/send/README.rst +++ b/samples/drivers/lora/send/README.rst @@ -11,7 +11,8 @@ This sample demonstrates how to use the LoRa radio driver to configure the encoding settings and send data over the radio. Transmitted messages can be received by building and flashing the accompanying -LoRa receive sample on another board. +LoRa receive sample :zephyr:code-sample:`lora-receive` on another board within +range. Building and Running ******************** From ea0a5548cd876d55e638f57241122a1c50696b31 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Fri, 27 Oct 2023 19:45:57 +0200 Subject: [PATCH 2892/4498] drivers: regulator: extend API about count/list for the current limits Extend the regulator API about support of `count_current_limits` and `list_current_limit` functions for the current limits. Signed-off-by: Bartosz Bilas --- include/zephyr/drivers/regulator.h | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/include/zephyr/drivers/regulator.h b/include/zephyr/drivers/regulator.h index a2e28440591..77dd6d76b60 100644 --- a/include/zephyr/drivers/regulator.h +++ b/include/zephyr/drivers/regulator.h @@ -76,6 +76,9 @@ typedef int (*regulator_set_voltage_t)(const struct device *dev, int32_t min_uv, int32_t max_uv); typedef int (*regulator_get_voltage_t)(const struct device *dev, int32_t *volt_uv); +typedef unsigned int (*regulator_count_current_limits_t)(const struct device *dev); +typedef int (*regulator_list_current_limit_t)(const struct device *dev, + unsigned int idx, int32_t *current_ua); typedef int (*regulator_set_current_limit_t)(const struct device *dev, int32_t min_ua, int32_t max_ua); typedef int (*regulator_get_current_limit_t)(const struct device *dev, @@ -95,6 +98,8 @@ __subsystem struct regulator_driver_api { regulator_list_voltage_t list_voltage; regulator_set_voltage_t set_voltage; regulator_get_voltage_t get_voltage; + regulator_count_current_limits_t count_current_limits; + regulator_list_current_limit_t list_current_limit; regulator_set_current_limit_t set_current_limit; regulator_get_current_limit_t get_current_limit; regulator_set_mode_t set_mode; @@ -485,6 +490,57 @@ static inline int regulator_get_voltage(const struct device *dev, return api->get_voltage(dev, volt_uv); } +/** + * @brief Obtain the number of supported current limit levels. + * + * Each current limit level supported by a regulator gets an index, starting from + * zero. The total number of supported current limit levels can be used together with + * regulator_list_current_limit() to list all supported current limit levels. + * + * @param dev Regulator device instance. + * + * @return Number of supported current limits. + */ +static inline unsigned int regulator_count_current_limits(const struct device *dev) +{ + const struct regulator_driver_api *api = + (const struct regulator_driver_api *)dev->api; + + if (api->count_current_limits == NULL) { + return 0U; + } + + return api->count_current_limits(dev); +} + +/** + * @brief Obtain the value of a current limit given an index. + * + * Each current limit level supported by a regulator gets an index, starting from + * zero. Together with regulator_count_current_limits(), this function can be used + * to iterate over all supported current limits. + * + * @param dev Regulator device instance. + * @param idx Current index. + * @param[out] current_ua Where current for the given @p index will be stored, in + * microamps. + * + * @retval 0 If @p index corresponds to a supported current limit. + * @retval -EINVAL If @p index does not correspond to a supported current limit. + */ +static inline int regulator_list_current_limit(const struct device *dev, + unsigned int idx, int32_t *current_ua) +{ + const struct regulator_driver_api *api = + (const struct regulator_driver_api *)dev->api; + + if (api->list_current_limit == NULL) { + return -EINVAL; + } + + return api->list_current_limit(dev, idx, current_ua); +} + /** * @brief Set output current limit. * From e2b01a3c48326884b71928afe12e3dd7ac242517 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Fri, 27 Oct 2023 19:49:51 +0200 Subject: [PATCH 2893/4498] drivers: regulator: shell: make use of the regulator current limits support Add a new `clist` regulator shell subcommand that prints the list of supported current limits for specified regulator device. Signed-off-by: Bartosz Bilas --- drivers/regulator/regulator_shell.c | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/regulator/regulator_shell.c b/drivers/regulator/regulator_shell.c index 4caaa9f8815..74aa1f22ca6 100644 --- a/drivers/regulator/regulator_shell.c +++ b/drivers/regulator/regulator_shell.c @@ -221,6 +221,38 @@ static int cmd_vget(const struct shell *sh, size_t argc, char **argv) return 0; } +static int cmd_clist(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + unsigned int current_cnt; + int32_t last_current_ua; + + ARG_UNUSED(argc); + + dev = device_get_binding(argv[1]); + if (dev == NULL) { + shell_error(sh, "Regulator device %s not available", argv[1]); + return -ENODEV; + } + + current_cnt = regulator_count_current_limits(dev); + + for (unsigned int i = 0U; i < current_cnt; i++) { + int32_t current_ua; + + (void)regulator_list_current_limit(dev, i, ¤t_ua); + + /* do not print repeated current limits */ + if ((i == 0U) || (last_current_ua != current_ua)) { + microtoshell(sh, 'A', current_ua); + } + + last_current_ua = current_ua; + } + + return 0; +} + static int cmd_iset(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; @@ -449,6 +481,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE( "Get voltage\n" "Usage: vget ", cmd_vget, 2, 0), + SHELL_CMD_ARG(clist, &dsub_device_name, + "List all supported current limits\n" + "Usage: clist ", + cmd_clist, 2, 0), SHELL_CMD_ARG(iset, &dsub_device_name, "Set current limit\n" "Input requires units, e.g. 200ma, 20.5ma, 10ua, 1a...\n" From 09758f21e376caf8feed2b7e49f8583e44419ad3 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Mon, 30 Oct 2023 09:21:12 +0100 Subject: [PATCH 2894/4498] drivers: ieee802154: nrf: limit number of serialized calls For serialized nRF IEEE 802.15.4 Driver host, avoid using `nrf_802154_csl_writer_anchor_time_set` too often by caching the CSL RX time and period and using them to detect any shift on the periodic pattern. This improves power consumption by limiting the number of serialized calls. Signed-off-by: Eduardo Montoya --- drivers/ieee802154/ieee802154_nrf5.c | 25 +++++++++++++++++++++---- drivers/ieee802154/ieee802154_nrf5.h | 8 ++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index d4dde149ac7..39b4bac7788 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -65,6 +65,8 @@ static struct nrf5_802154_data nrf5_data; #define DRX_SLOT_RX 0 /* Delayed reception window ID */ +#define NSEC_PER_TEN_SYMBOLS (10 * IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS) + #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE) #if defined(CONFIG_SOC_NRF5340_CPUAPP) #if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) @@ -925,8 +927,20 @@ static int nrf5_configure(const struct device *dev, #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) case IEEE802154_CONFIG_EXPECTED_RX_TIME: { - nrf_802154_csl_writer_anchor_time_set(nrf_802154_timestamp_phr_to_mhr_convert( - config->expected_rx_time / NSEC_PER_USEC)); + +#if defined(CONFIG_NRF_802154_SER_HOST) + net_time_t period_ns = nrf5_data.csl_period * NSEC_PER_TEN_SYMBOLS; + bool changed = (config->csl_rx_time - nrf5_data.csl_rx_time) % period_ns; + + nrf5_data.csl_rx_time = config->csl_rx_time; + + if (changed) +#endif /* CONFIG_NRF_802154_SER_HOST */ + { + nrf_802154_csl_writer_anchor_time_set( + nrf_802154_timestamp_phr_to_mhr_convert(config->expected_rx_time / + NSEC_PER_USEC)); + } } break; case IEEE802154_CONFIG_RX_SLOT: { @@ -942,9 +956,12 @@ static int nrf5_configure(const struct device *dev, config->rx_slot.channel, DRX_SLOT_RX); } break; - case IEEE802154_CONFIG_CSL_PERIOD: + case IEEE802154_CONFIG_CSL_PERIOD: { nrf_802154_csl_writer_period_set(config->csl_period); - break; +#if defined(CONFIG_NRF_802154_SER_HOST) + nrf5_data.csl_period = config->csl_period; +#endif + } break; #endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index 2cb41debbb8..8188db46ad1 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -92,6 +92,14 @@ struct nrf5_802154_data { /* The maximum number of extra CCA attempts to be performed before transmission. */ uint8_t max_extra_cca_attempts; #endif + +#if defined(CONFIG_NRF_802154_SER_HOST) && defined(CONFIG_IEEE802154_CSL_ENDPOINT) + /* The last configured value of CSL period in units of 10 symbols. */ + uint32_t csl_period; + + /* The last configured value of CSL phase time in nanoseconds. */ + net_time_t csl_rx_time; +#endif /* CONFIG_NRF_802154_SER_HOST && CONFIG_IEEE802154_CSL_ENDPOINT */ }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ From 944ced68f5e558c9cf5e30b69b3ab8a6d7e6f15e Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Mon, 30 Oct 2023 17:39:39 +0530 Subject: [PATCH 2895/4498] bcf: Add UART console Without these config options, even the basic hello world example will not give any output Signed-off-by: Ayush Singh --- boards/arm/beagle_bcf/beagleconnect_freedom_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig b/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig index af58105267c..d1d9ff8f84e 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig +++ b/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig @@ -20,3 +20,8 @@ CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 # Enable MPU and hardware stack protection CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y + +# Enable default uart console +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y From b432293a9a3409b89aaeb3052dce92e145d48aaf Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 30 Oct 2023 14:56:39 +0100 Subject: [PATCH 2896/4498] tests: drivers: flash stm32l4 RDP on internal flash partition Define the storage_partition in the internal flash instead of the external NOR qspi flash, so the testcase can PASS on the disco_l4754_iot1 board. Signed-off-by: Francois Ramu --- .../stm32/boards/disco_l475_iot1.overlay | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/drivers/flash/stm32/boards/disco_l475_iot1.overlay diff --git a/tests/drivers/flash/stm32/boards/disco_l475_iot1.overlay b/tests/drivers/flash/stm32/boards/disco_l475_iot1.overlay new file mode 100644 index 00000000000..711a96d0161 --- /dev/null +++ b/tests/drivers/flash/stm32/boards/disco_l475_iot1.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Do not use the storage-partition of the external qspi-NOR flash */ +/delete-node/ &storage_partition; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 4KiB of flash for storage_partition. */ + storage_partition: partition@f0000 { + label = "storage"; + reg = <0x000f0000 DT_SIZE_K(4)>; + }; + }; +}; From 5d5249d85bb7bb779314693baa230195c0b070e0 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 31 Oct 2023 10:09:38 +0100 Subject: [PATCH 2897/4498] drivers: can: unify spelling of CAN Flexible Data-rate abbreviation Unify spelling of CAN Flexible Data-rate abbreviation to "CAN FD" instead of "CAN-FD". The former aligns with the CAN in Automation (CiA) recommendation. Signed-off-by: Henrik Brix Andersen --- boards/arm/gd32a503v_eval/doc/index.rst | 2 +- boards/arm/gd32e103v_eval/doc/index.rst | 2 +- boards/arm/mimxrt1060_evk/doc/index.rst | 2 +- boards/arm/mimxrt1062_fmurt6/doc/index.rst | 2 +- boards/arm/mimxrt1064_evk/doc/index.rst | 2 +- boards/arm/nucleo_g0b1re/doc/index.rst | 2 +- boards/arm/nucleo_h723zg/doc/index.rst | 2 +- boards/arm/nucleo_h743zi/doc/index.rst | 2 +- boards/arm/nucleo_h745zi_q/doc/index.rst | 2 +- boards/arm/nucleo_h753zi/doc/index.rst | 2 +- boards/arm/nucleo_h7a3zi_q/doc/index.rst | 2 +- boards/arm/sam_v71_xult/doc/index.rst | 2 +- .../mikroe_mcp2518fd_click/doc/index.rst | 6 ++-- doc/connectivity/canbus/isotp.rst | 2 +- doc/hardware/peripherals/can/controller.rst | 2 +- drivers/can/Kconfig | 4 +-- drivers/can/Kconfig.mcan | 2 +- drivers/can/Kconfig.mcux | 2 +- drivers/can/Kconfig.numaker | 4 +-- drivers/can/can_mcan.c | 4 +-- drivers/can/can_mcux_flexcan.c | 12 ++++---- drivers/can/can_nxp_s32_canxl.c | 8 +++--- drivers/can/can_shell.c | 10 +++---- .../clock_control_renesas_cpg_mssr.h | 2 +- dts/bindings/can/atmel,sam-can.yaml | 2 +- dts/bindings/can/atmel,sam0-can.yaml | 2 +- dts/bindings/can/bosch,m_can-base.yaml | 2 +- dts/bindings/can/can-fd-controller.yaml | 2 +- dts/bindings/can/microchip,mcp251xfd.yaml | 2 +- dts/bindings/can/nuvoton,numaker-canfd.yaml | 2 +- dts/bindings/can/nxp,flexcan-fd.yaml | 2 +- dts/bindings/can/nxp,lpc-mcan.yaml | 2 +- dts/bindings/can/st,stm32-fdcan.yaml | 2 +- dts/bindings/can/st,stm32h7-fdcan.yaml | 2 +- dts/bindings/can/ti,tcan4x5x.yaml | 2 +- include/zephyr/canbus/isotp.h | 6 ++-- include/zephyr/drivers/can.h | 28 +++++++++---------- include/zephyr/net/socketcan.h | 2 +- samples/drivers/can/babbling/Kconfig | 4 +-- samples/drivers/can/babbling/README.rst | 2 +- samples/drivers/can/babbling/src/main.c | 4 +-- samples/subsys/canbus/isotp/Kconfig | 2 +- subsys/canbus/isotp/Kconfig | 2 +- subsys/canbus/isotp/isotp.c | 10 +++---- tests/drivers/can/api/src/canfd.c | 20 ++++++------- tests/drivers/can/api/src/classic.c | 4 +-- tests/drivers/can/api/src/common.c | 8 +++--- tests/drivers/can/api/src/common.h | 8 +++--- tests/drivers/can/api/src/utilities.c | 12 ++++---- tests/drivers/can/timing/src/main.c | 4 +-- tests/subsys/canbus/isotp/conformance/Kconfig | 2 +- .../subsys/canbus/isotp/conformance/prj.conf | 2 +- .../canbus/isotp/conformance/src/main.c | 2 +- .../canbus/isotp/conformance/src/mode_check.c | 2 +- .../canbus/isotp/conformance/testcase.yaml | 6 ++-- 55 files changed, 117 insertions(+), 117 deletions(-) diff --git a/boards/arm/gd32a503v_eval/doc/index.rst b/boards/arm/gd32a503v_eval/doc/index.rst index 1039faf515f..b926a265bb4 100644 --- a/boards/arm/gd32a503v_eval/doc/index.rst +++ b/boards/arm/gd32a503v_eval/doc/index.rst @@ -34,7 +34,7 @@ Hardware - CMSIS-DAP swd debug interface over USB HID. -- 2 CAN port(support CAN-FD) +- 2 CAN FD ports For more information about the GD32A503 SoC and GD32A503V-EVAL board: diff --git a/boards/arm/gd32e103v_eval/doc/index.rst b/boards/arm/gd32e103v_eval/doc/index.rst index ccf1e9b1e3e..3d9058793fe 100644 --- a/boards/arm/gd32e103v_eval/doc/index.rst +++ b/boards/arm/gd32e103v_eval/doc/index.rst @@ -36,7 +36,7 @@ Hardware - CMSIS-DAP swd debug interface over USB HID. -- 2 CAN port(support CAN-FD) +- 2 CAN FD ports - This function is not available in this board due to hardware issues, please check ``GD32C103`` . diff --git a/boards/arm/mimxrt1060_evk/doc/index.rst b/boards/arm/mimxrt1060_evk/doc/index.rst index 838deeb477d..45d10009570 100644 --- a/boards/arm/mimxrt1060_evk/doc/index.rst +++ b/boards/arm/mimxrt1060_evk/doc/index.rst @@ -11,7 +11,7 @@ processor series and expands the i.MX RT series to three scalable families. The i.MX RT1060 doubles the On-Chip SRAM to 1MB while keeping pin-to-pin compatibility with i.MX RT1050. This series introduces additional features -ideal for real-time applications such as High-Speed GPIO, CAN-FD, and +ideal for real-time applications such as High-Speed GPIO, CAN FD, and synchronous parallel NAND/NOR/PSRAM controller. The i.MX RT1060 runs on the Arm® Cortex-M7® core up to 600 MHz. diff --git a/boards/arm/mimxrt1062_fmurt6/doc/index.rst b/boards/arm/mimxrt1062_fmurt6/doc/index.rst index e1b7f284cc0..2c801c454af 100644 --- a/boards/arm/mimxrt1062_fmurt6/doc/index.rst +++ b/boards/arm/mimxrt1062_fmurt6/doc/index.rst @@ -11,7 +11,7 @@ processor series and expands the i.MX RT series to three scalable families. The i.MX RT1062 doubles the On-Chip SRAM to 1MB while keeping pin-to-pin compatibility with i.MX RT1050. This series introduces additional features -ideal for real-time applications such as High-Speed GPIO, CAN-FD, and +ideal for real-time applications such as High-Speed GPIO, CAN FD, and synchronous parallel NAND/NOR/PSRAM controller. The i.MX RT1062 runs on the Arm® Cortex-M7® core up to 600 MHz. diff --git a/boards/arm/mimxrt1064_evk/doc/index.rst b/boards/arm/mimxrt1064_evk/doc/index.rst index 462fe7629b3..24abf5ca76f 100644 --- a/boards/arm/mimxrt1064_evk/doc/index.rst +++ b/boards/arm/mimxrt1064_evk/doc/index.rst @@ -10,7 +10,7 @@ The i.MX RT1064 adds to the industry's first crossover processor series and expands the i.MX RT series to three scalable families. The i.MX RT1064 doubles the On-Chip SRAM to 1MB while keeping pin-to-pin compatibility with i.MX RT1050. This series introduces additional features -ideal for real-time applications such as High-Speed GPIO, CAN-FD, and +ideal for real-time applications such as High-Speed GPIO, CAN FD, and synchronous parallel NAND/NOR/PSRAM controller. The i.MX RT1064 runs on the Arm® Cortex-M7® core up to 600 MHz. diff --git a/boards/arm/nucleo_g0b1re/doc/index.rst b/boards/arm/nucleo_g0b1re/doc/index.rst index 66e6a9ba87d..0ad60852627 100644 --- a/boards/arm/nucleo_g0b1re/doc/index.rst +++ b/boards/arm/nucleo_g0b1re/doc/index.rst @@ -56,7 +56,7 @@ Nucleo G0B1RE provides the following hardware components: - HDMI_CEC(1) - USB 2.0 FS device (crystal-less) and host controller(1) - USB Type-C Power Delivery controller -- CAN-FD(2) +- CAN FD(2) - GPIO (up to 94) with external interrupt capability - Tamper Pins(3) - 12-bit ADC with 16 channels diff --git a/boards/arm/nucleo_h723zg/doc/index.rst b/boards/arm/nucleo_h723zg/doc/index.rst index d27c7367aca..09b71835f67 100644 --- a/boards/arm/nucleo_h723zg/doc/index.rst +++ b/boards/arm/nucleo_h723zg/doc/index.rst @@ -71,7 +71,7 @@ Nucleo H723ZG provides the following hardware components: - UART(4) - USB OTG Full Speed and High Speed(1) - USB OTG Full Speed(1) -- CAN-FD(2) +- CAN FD(2) - SAI(2) - SPDIF_Rx(4) - HDMI_CEC(1) diff --git a/boards/arm/nucleo_h743zi/doc/index.rst b/boards/arm/nucleo_h743zi/doc/index.rst index af0ee0186ec..c401e3ab098 100644 --- a/boards/arm/nucleo_h743zi/doc/index.rst +++ b/boards/arm/nucleo_h743zi/doc/index.rst @@ -73,7 +73,7 @@ Nucleo H743ZI provides the following hardware components: - UART(4) - USB OTG Full Speed and High Speed(1) - USB OTG Full Speed(1) -- CAN-FD(2) +- CAN FD(2) - SAI(2) - SPDIF_Rx(4) - HDMI_CEC(1) diff --git a/boards/arm/nucleo_h745zi_q/doc/index.rst b/boards/arm/nucleo_h745zi_q/doc/index.rst index f419c17ccc4..60f86f2ab81 100644 --- a/boards/arm/nucleo_h745zi_q/doc/index.rst +++ b/boards/arm/nucleo_h745zi_q/doc/index.rst @@ -75,7 +75,7 @@ Nucleo H745ZI-Q provides the following hardware components: - UART(4) - USB OTG Full Speed and High Speed(1) - USB OTG Full Speed(1) -- CAN-FD(2) +- CAN FD(2) - SAI(2) - SPDIF_Rx(4) - HDMI_CEC(1) diff --git a/boards/arm/nucleo_h753zi/doc/index.rst b/boards/arm/nucleo_h753zi/doc/index.rst index 41a9af20954..058cbc67c9f 100644 --- a/boards/arm/nucleo_h753zi/doc/index.rst +++ b/boards/arm/nucleo_h753zi/doc/index.rst @@ -73,7 +73,7 @@ Nucleo H753ZI provides the following hardware components: - UART(4) - USB OTG Full Speed and High Speed(1) - USB OTG Full Speed(1) -- CAN-FD(2) +- CAN FD(2) - SAI(2) - SPDIF_Rx(4) - HDMI_CEC(1) diff --git a/boards/arm/nucleo_h7a3zi_q/doc/index.rst b/boards/arm/nucleo_h7a3zi_q/doc/index.rst index 92dfbd98deb..7b107733510 100644 --- a/boards/arm/nucleo_h7a3zi_q/doc/index.rst +++ b/boards/arm/nucleo_h7a3zi_q/doc/index.rst @@ -69,7 +69,7 @@ Nucleo H7A3ZI-Q provides the following hardware components: - USART(5) - UART(5) - USB OTG Full Speed and High Speed(1) -- CAN-FD(2) +- CAN FD(2) - SAI(2) - SPDIF_Rx(4) - HDMI_CEC(1) diff --git a/boards/arm/sam_v71_xult/doc/index.rst b/boards/arm/sam_v71_xult/doc/index.rst index 5bed3274d71..a61fe887d6a 100644 --- a/boards/arm/sam_v71_xult/doc/index.rst +++ b/boards/arm/sam_v71_xult/doc/index.rst @@ -70,7 +70,7 @@ features: +-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ -| CAN-FD | on-chip | can | +| CAN FD | on-chip | can | +-----------+------------+-------------------------------------+ | HWINFO | on-chip | Unique device serial number | +-----------+------------+-------------------------------------+ diff --git a/boards/shields/mikroe_mcp2518fd_click/doc/index.rst b/boards/shields/mikroe_mcp2518fd_click/doc/index.rst index 00bc60190f8..79ac2b441c3 100644 --- a/boards/shields/mikroe_mcp2518fd_click/doc/index.rst +++ b/boards/shields/mikroe_mcp2518fd_click/doc/index.rst @@ -1,12 +1,12 @@ .. _mikroe_mcp2518fd_click_shield: -MikroElektronika MCP2518FD Click shield (CAN-FD) -################################################ +MikroElektronika MCP2518FD Click shield +####################################### Overview -------- -MCP2518FD Click shield has a MCP2518FD CAN-FD controller via a SPI +MCP2518FD Click shield has a MCP2518FD CAN FD controller via a SPI interface and a high-speed ATA6563 CAN transceiver. More information about the shield can be found at diff --git a/doc/connectivity/canbus/isotp.rst b/doc/connectivity/canbus/isotp.rst index 325a45cc036..4fea2c95232 100644 --- a/doc/connectivity/canbus/isotp.rst +++ b/doc/connectivity/canbus/isotp.rst @@ -18,7 +18,7 @@ over Controller Area Networks. Nevertheless, it's not limited to applications in road vehicles or the automotive domain. This transport protocol extends the limited payload data size for classical -CAN (8 bytes) and CAN-FD (64 bytes) to theoretically four gigabytes. +CAN (8 bytes) and CAN FD (64 bytes) to theoretically four gigabytes. Additionally, it adds a flow control mechanism to influence the sender's behavior. ISO-TP segments packets into small fragments depending on the payload size of the CAN frame. The header of those segments is called Protocol Control diff --git a/doc/hardware/peripherals/can/controller.rst b/doc/hardware/peripherals/can/controller.rst index fd9c6d8df69..6943949d1a4 100644 --- a/doc/hardware/peripherals/can/controller.rst +++ b/doc/hardware/peripherals/can/controller.rst @@ -292,7 +292,7 @@ The following example sets the bitrate to 250k baud with the sampling point at LOG_ERR("Failed to start CAN controller"); } -A similar API exists for calculating and setting the timing for the data phase for CAN-FD capable +A similar API exists for calculating and setting the timing for the data phase for CAN FD capable controllers. See :c:func:`can_set_timing_data` and :c:func:`can_calc_timing_data`. SocketCAN diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index 37d9a93f170..f12bbebf6fa 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -56,9 +56,9 @@ config CAN_STATS Enable CAN controller device statistics. config CAN_FD_MODE - bool "CAN-FD" + bool "CAN FD" help - Enable CAN-FD support. Not all CAN controllers support CAN-FD. + Enable CAN FD support. Not all CAN controllers support CAN FD. config CAN_RX_TIMESTAMP bool "Receiving timestamps" diff --git a/drivers/can/Kconfig.mcan b/drivers/can/Kconfig.mcan index 6b25df34567..83cf6ffaba0 100644 --- a/drivers/can/Kconfig.mcan +++ b/drivers/can/Kconfig.mcan @@ -9,7 +9,7 @@ config CAN_MCAN Enable Bosch m_can driver. This driver supports the Bosch m_can IP. This IP is built into the STM32G4, STM32G0, STM32H7, and the Microchip SAM controllers with - CAN-FD. + CAN FD. if CAN_MCAN diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index 67ab4c26873..e584996d7c0 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -19,7 +19,7 @@ config CAN_MCUX_FLEXCAN_FD default y depends on DT_HAS_NXP_FLEXCAN_FD_ENABLED && CAN_FD_MODE help - Enable support for CAN-FD capable NXP FlexCAN devices. + Enable support for CAN FD capable NXP FlexCAN devices. config CAN_MCUX_FLEXCAN_WAIT_TIMEOUT int "Maximum number of wait loop iterations" diff --git a/drivers/can/Kconfig.numaker b/drivers/can/Kconfig.numaker index c700853c554..23de8ab50ec 100644 --- a/drivers/can/Kconfig.numaker +++ b/drivers/can/Kconfig.numaker @@ -4,10 +4,10 @@ # SPDX-License-Identifier: Apache-2.0 config CAN_NUMAKER - bool "Nuvoton NuMaker CAN-FD driver" + bool "Nuvoton NuMaker CAN FD driver" default y select CAN_MCAN depends on DT_HAS_NUVOTON_NUMAKER_CANFD_ENABLED depends on SOC_SERIES_M46X help - Enables Nuvoton NuMaker CAN-FD driver, using Bosch M_CAN + Enables Nuvoton NuMaker CAN FD driver, using Bosch M_CAN diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index 9b9fec79ace..529f2ed7dff 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -882,7 +882,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim } if (!data->fd && ((frame->flags & (CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0U)) { - LOG_ERR("CAN-FD format not supported in non-FD mode"); + LOG_ERR("CAN FD format not supported in non-FD mode"); return -ENOTSUP; } #else /* CONFIG_CAN_FD_MODE */ @@ -900,7 +900,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim if ((frame->flags & CAN_FRAME_FDF) != 0U) { if (frame->dlc > CANFD_MAX_DLC) { - LOG_ERR("DLC of %d for CAN-FD format frame", frame->dlc); + LOG_ERR("DLC of %d for CAN FD format frame", frame->dlc); return -EINVAL; } } else { diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 84b6bb67c1d..4138678911c 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -7,7 +7,7 @@ /* Base driver compatible */ #define DT_DRV_COMPAT nxp_flexcan -/* CAN-FD extension compatible */ +/* CAN FD extension compatible */ #define FLEXCAN_FD_DRV_COMPAT nxp_flexcan_fd #include @@ -443,7 +443,7 @@ static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode) } if ((mode & CAN_MODE_FD) != 0 && (mode & CAN_MODE_3_SAMPLES) != 0) { - LOG_ERR("triple samling is not supported in CAN-FD mode"); + LOG_ERR("triple samling is not supported in CAN FD mode"); return -ENOTSUP; } @@ -479,7 +479,7 @@ static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode) #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD if (config->flexcan_fd) { if ((mode & CAN_MODE_FD) != 0) { - /* Enable CAN-FD mode */ + /* Enable CAN FD mode */ mcr |= CAN_MCR_FDEN_MASK; data->fd_mode = true; @@ -490,7 +490,7 @@ static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode) config->base->FDCTRL |= CAN_FDCTRL_TDCEN_MASK; } } else { - /* Disable CAN-FD mode */ + /* Disable CAN FD mode */ mcr &= ~(CAN_MCR_FDEN_MASK); data->fd_mode = false; } @@ -849,7 +849,7 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev, } #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD - /* Defer starting FlexCAN-FD MBs unless started */ + /* Defer starting FlexCAN FD MBs unless started */ if (!config->flexcan_fd || data->started) { #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ status = mcux_flexcan_mb_start(dev, alloc); @@ -933,7 +933,7 @@ static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_i #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD const struct mcux_flexcan_config *config = dev->config; - /* Stop FlexCAN-FD MBs unless already in stopped mode */ + /* Stop FlexCAN FD MBs unless already in stopped mode */ if (!config->flexcan_fd || data->started) { #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ mcux_flexcan_mb_stop(dev, filter_id); diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index ca6961d27e2..9083569f702 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -514,13 +514,13 @@ static int can_nxp_s32_send(const struct device *dev, if ((frame->flags & CAN_FRAME_FDF) != 0 && (config->base_sic->BCFG2 & CANXL_SIC_BCFG2_FDEN_MASK) == 0) { - LOG_ERR("CAN-FD format not supported in non-FD mode"); + LOG_ERR("CAN FD format not supported in non-FD mode"); return -ENOTSUP; } if ((frame->flags & CAN_FRAME_BRS) != 0 && ~(config->base_sic->BCFG1 & CANXL_SIC_BCFG1_FDRSDIS_MASK) == 0) { - LOG_ERR("CAN-FD BRS not supported in non-FD mode"); + LOG_ERR("CAN FD BRS not supported in non-FD mode"); return -ENOTSUP; } #else @@ -544,7 +544,7 @@ static int can_nxp_s32_send(const struct device *dev, #ifdef CONFIG_CAN_FD_MODE } else { if (frame->dlc > CANFD_MAX_DLC) { - LOG_ERR("DLC of %d for CAN-FD format frame", frame->dlc); + LOG_ERR("DLC of %d for CAN FD format frame", frame->dlc); return -EINVAL; } #endif @@ -904,7 +904,7 @@ static int can_nxp_s32_init(const struct device *dev) } } - LOG_DBG("Setting CAN-FD bitrate %d:", config->bitrate_data); + LOG_DBG("Setting CAN FD bitrate %d:", config->bitrate_data); nxp_s32_zcan_timing_to_canxl_timing(&data->timing_data, &config->can_cfg->Fd_bitrate); #endif diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index bc0286d2ea6..66900f18e8f 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -669,7 +669,7 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv) frame_no = frame_counter++; shell_print(sh, "enqueuing CAN frame #%u with %s (%d-bit) CAN ID 0x%0*x, " - "RTR %d, CAN-FD %d, BRS %d, DLC %d", frame_no, + "RTR %d, CAN FD %d, BRS %d, DLC %d", frame_no, (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard", (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11, (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id, @@ -781,7 +781,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv) } shell_print(sh, "adding filter with %s (%d-bit) CAN ID 0x%0*x, " - "CAN ID mask 0x%0*x, data frames %d, RTR frames %d, CAN-FD frames %d", + "CAN ID mask 0x%0*x, data frames %d, RTR frames %d, CAN FD frames %d", (filter.flags & CAN_FILTER_IDE) != 0 ? "extended" : "standard", (filter.flags & CAN_FILTER_IDE) != 0 ? 29 : 11, (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.id, @@ -908,7 +908,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_filter_cmds, "Add rx filter\n" "Usage: can filter add [-e] [-f] [-r] [-R] [CAN ID mask]\n" "-e use extended (29-bit) CAN ID/CAN ID mask\n" - "-f match CAN-FD format frames\n" + "-f match CAN FD format frames\n" "-r also match Remote Transmission Request (RTR) frames\n" "-R only match Remote Transmission Request (RTR) frames", cmd_can_filter_add, 3, 5), @@ -950,8 +950,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_cmds, "Usage: can send [-e] [-r] [-f] [-b] [data] [...]\n" "-e use extended (29-bit) CAN ID\n" "-r send Remote Transmission Request (RTR) frame\n" - "-f use CAN-FD frame format\n" - "-b use CAN-FD Bit Rate Switching (BRS)", + "-f use CAN FD frame format\n" + "-b use CAN FD Bit Rate Switching (BRS)", cmd_can_send, 3, SHELL_OPT_ARG_CHECK_SKIP), SHELL_CMD(filter, &sub_can_filter_cmds, "CAN rx filter commands\n" diff --git a/drivers/clock_control/clock_control_renesas_cpg_mssr.h b/drivers/clock_control/clock_control_renesas_cpg_mssr.h index 13d3cbeeb4e..d616567763e 100644 --- a/drivers/clock_control/clock_control_renesas_cpg_mssr.h +++ b/drivers/clock_control/clock_control_renesas_cpg_mssr.h @@ -96,7 +96,7 @@ static const uint16_t srcr[] = { 0x920, 0x924, 0x928, 0x92C, }; -/* CAN-FD Clock Frequency Control Register */ +/* CAN FD Clock Frequency Control Register */ #define CANFDCKCR 0x244 /* Clock stop bit */ diff --git a/dts/bindings/can/atmel,sam-can.yaml b/dts/bindings/can/atmel,sam-can.yaml index 0d0dc268f4c..e6930009194 100644 --- a/dts/bindings/can/atmel,sam-can.yaml +++ b/dts/bindings/can/atmel,sam-can.yaml @@ -1,4 +1,4 @@ -description: Specialization of Bosch m_can CAN-FD controller for Atmel SAM +description: Specialization of Bosch m_can CAN FD controller for Atmel SAM compatible: "atmel,sam-can" diff --git a/dts/bindings/can/atmel,sam0-can.yaml b/dts/bindings/can/atmel,sam0-can.yaml index 0a70dfd9d5e..486620a21b7 100644 --- a/dts/bindings/can/atmel,sam0-can.yaml +++ b/dts/bindings/can/atmel,sam0-can.yaml @@ -1,4 +1,4 @@ -description: Specialization of Bosch m_can CAN-FD controller for Atmel SAM0 +description: Specialization of Bosch m_can CAN FD controller for Atmel SAM0 compatible: "atmel,sam0-can" diff --git a/dts/bindings/can/bosch,m_can-base.yaml b/dts/bindings/can/bosch,m_can-base.yaml index 1663cf82082..0c59c671949 100644 --- a/dts/bindings/can/bosch,m_can-base.yaml +++ b/dts/bindings/can/bosch,m_can-base.yaml @@ -1,4 +1,4 @@ -description: Bosch M_CAN CAN-FD controller base +description: Bosch M_CAN CAN FD controller base include: [can-fd-controller.yaml] diff --git a/dts/bindings/can/can-fd-controller.yaml b/dts/bindings/can/can-fd-controller.yaml index beb9da9f736..3882518d626 100644 --- a/dts/bindings/can/can-fd-controller.yaml +++ b/dts/bindings/can/can-fd-controller.yaml @@ -1,4 +1,4 @@ -# Common fields for CAN-FD controllers +# Common fields for CAN FD controllers include: can-controller.yaml diff --git a/dts/bindings/can/microchip,mcp251xfd.yaml b/dts/bindings/can/microchip,mcp251xfd.yaml index 3338f82e02a..de86c320d30 100644 --- a/dts/bindings/can/microchip,mcp251xfd.yaml +++ b/dts/bindings/can/microchip,mcp251xfd.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Microchip MCP251XFD SPI CAN-FD controller + Microchip MCP251XFD SPI CAN FD controller The MCP251XFD node is defined on an SPI bus. An example configuration is: diff --git a/dts/bindings/can/nuvoton,numaker-canfd.yaml b/dts/bindings/can/nuvoton,numaker-canfd.yaml index dbfa39259c0..e3d28f5ce28 100644 --- a/dts/bindings/can/nuvoton,numaker-canfd.yaml +++ b/dts/bindings/can/nuvoton,numaker-canfd.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nuvoton Technology Corporation # SPDX-License-Identifier: Apache-2.0 -description: Nuvoton NuMaker CAN-FD controller, using Bosch M_CAN IP +description: Nuvoton NuMaker CAN FD controller, using Bosch M_CAN IP compatible: "nuvoton,numaker-canfd" diff --git a/dts/bindings/can/nxp,flexcan-fd.yaml b/dts/bindings/can/nxp,flexcan-fd.yaml index 890cbd8de94..72c36292cc0 100644 --- a/dts/bindings/can/nxp,flexcan-fd.yaml +++ b/dts/bindings/can/nxp,flexcan-fd.yaml @@ -4,7 +4,7 @@ description: | NXP FlexCAN CANFD controller. - This is a specialization of the NXP FlexCAN CAN controller with support for CAN-FD. + This is a specialization of the NXP FlexCAN CAN controller with support for CAN FD. Example: flexcan3: can@401d8000 { diff --git a/dts/bindings/can/nxp,lpc-mcan.yaml b/dts/bindings/can/nxp,lpc-mcan.yaml index 65a06baea87..a17b0132e62 100644 --- a/dts/bindings/can/nxp,lpc-mcan.yaml +++ b/dts/bindings/can/nxp,lpc-mcan.yaml @@ -1,4 +1,4 @@ -description: NXP LPC SoC series MCAN CAN-FD controller +description: NXP LPC SoC series MCAN CAN FD controller compatible: "nxp,lpc-mcan" diff --git a/dts/bindings/can/st,stm32-fdcan.yaml b/dts/bindings/can/st,stm32-fdcan.yaml index 36a38d97ca3..d950bb4e924 100644 --- a/dts/bindings/can/st,stm32-fdcan.yaml +++ b/dts/bindings/can/st,stm32-fdcan.yaml @@ -1,4 +1,4 @@ -description: ST STM32 FDCAN CAN-FD controller +description: ST STM32 FDCAN CAN FD controller compatible: "st,stm32-fdcan" diff --git a/dts/bindings/can/st,stm32h7-fdcan.yaml b/dts/bindings/can/st,stm32h7-fdcan.yaml index 5679141fe8e..3cee6e29219 100644 --- a/dts/bindings/can/st,stm32h7-fdcan.yaml +++ b/dts/bindings/can/st,stm32h7-fdcan.yaml @@ -1,4 +1,4 @@ -description: ST STM32H7 series FDCAN CAN-FD controller +description: ST STM32H7 series FDCAN CAN FD controller compatible: "st,stm32h7-fdcan" diff --git a/dts/bindings/can/ti,tcan4x5x.yaml b/dts/bindings/can/ti,tcan4x5x.yaml index 567a158a205..8f57f66ae85 100644 --- a/dts/bindings/can/ti,tcan4x5x.yaml +++ b/dts/bindings/can/ti,tcan4x5x.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Texas Instruments TCAN4x5x SPI CAN-FD controller. + Texas Instruments TCAN4x5x SPI CAN FD controller. Example: &spi0 { diff --git a/include/zephyr/canbus/isotp.h b/include/zephyr/canbus/isotp.h index d162b8dc531..222cef70a31 100644 --- a/include/zephyr/canbus/isotp.h +++ b/include/zephyr/canbus/isotp.h @@ -153,10 +153,10 @@ extern "C" { /** Message uses extended (29-bit) CAN ID */ #define ISOTP_MSG_IDE BIT(2) -/** Message uses CAN-FD format (FDF) */ +/** Message uses CAN FD format (FDF) */ #define ISOTP_MSG_FDF BIT(3) -/** Message uses CAN-FD Baud Rate Switch (BRS). Only valid in combination with ``ISOTP_MSG_FDF``. */ +/** Message uses CAN FD Baud Rate Switch (BRS). Only valid in combination with ``ISOTP_MSG_FDF``. */ #define ISOTP_MSG_BRS BIT(4) /** @} */ @@ -182,7 +182,7 @@ struct isotp_msg_id { /** * ISO-TP frame data length (TX_DL for TX address or RX_DL for RX address). * - * Valid values are 8 for classical CAN or 8, 12, 16, 20, 24, 32, 48 and 64 for CAN-FD. + * Valid values are 8 for classical CAN or 8, 12, 16, 20, 24, 32, 48 and 64 for CAN FD. * * 0 will be interpreted as 8 or 64 (if ISOTP_MSG_FDF is set). * diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index a09a7cdf97b..e53a39471d7 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -60,7 +60,7 @@ extern "C" { */ #define CAN_MAX_DLC 8U /** - * @brief Maximum data length code for CAN-FD. + * @brief Maximum data length code for CAN FD. */ #define CANFD_MAX_DLC 15U @@ -94,7 +94,7 @@ extern "C" { /** Controller is not allowed to send dominant bits. */ #define CAN_MODE_LISTENONLY BIT(1) -/** Controller allows transmitting/receiving CAN-FD frames. */ +/** Controller allows transmitting/receiving CAN FD frames. */ #define CAN_MODE_FD BIT(2) /** Controller does not retransmit in case of lost arbitration or missing ACK */ @@ -144,13 +144,13 @@ enum can_state { /** Frame is a Remote Transmission Request (RTR) */ #define CAN_FRAME_RTR BIT(1) -/** Frame uses CAN-FD format (FDF) */ +/** Frame uses CAN FD format (FDF) */ #define CAN_FRAME_FDF BIT(2) -/** Frame uses CAN-FD Baud Rate Switch (BRS). Only valid in combination with ``CAN_FRAME_FDF``. */ +/** Frame uses CAN FD Baud Rate Switch (BRS). Only valid in combination with ``CAN_FRAME_FDF``. */ #define CAN_FRAME_BRS BIT(3) -/** CAN-FD Error State Indicator (ESI). Indicates that the transmitting node is in error-passive +/** CAN FD Error State Indicator (ESI). Indicates that the transmitting node is in error-passive * state. Only valid in combination with ``CAN_FRAME_FDF``. */ #define CAN_FRAME_ESI BIT(4) @@ -209,7 +209,7 @@ struct can_frame { /** Filter matches data frames */ #define CAN_FILTER_DATA BIT(2) -/** Filter matches CAN-FD frames (FDF) */ +/** Filter matches CAN FD frames (FDF) */ #define CAN_FILTER_FDF BIT(3) /** @} */ @@ -333,7 +333,7 @@ typedef int (*can_set_timing_t)(const struct device *dev, const struct can_timing *timing); /** - * @brief Optional callback API upon setting CAN-FD bus timing for the data phase. + * @brief Optional callback API upon setting CAN FD bus timing for the data phase. * See @a can_set_timing_data() for argument description */ typedef int (*can_set_timing_data_t)(const struct device *dev, @@ -841,7 +841,7 @@ __syscall int can_calc_timing(const struct device *dev, struct can_timing *res, * @param dev Pointer to the device structure for the driver instance. * * @return Pointer to the minimum supported timing parameter values, or NULL if - * CAN-FD support is not implemented by the driver. + * CAN FD support is not implemented by the driver. */ __syscall const struct can_timing *can_get_timing_data_min(const struct device *dev); @@ -865,7 +865,7 @@ static inline const struct can_timing *z_impl_can_get_timing_data_min(const stru * @param dev Pointer to the device structure for the driver instance. * * @return Pointer to the maximum supported timing parameter values, or NULL if - * CAN-FD support is not implemented by the driver. + * CAN FD support is not implemented by the driver. */ __syscall const struct can_timing *can_get_timing_data_max(const struct device *dev); @@ -901,7 +901,7 @@ __syscall int can_calc_timing_data(const struct device *dev, struct can_timing * uint32_t bitrate, uint16_t sample_pnt); /** - * @brief Configure the bus timing for the data phase of a CAN-FD controller. + * @brief Configure the bus timing for the data phase of a CAN FD controller. * * @note @kconfig{CONFIG_CAN_FD_MODE} must be selected for this function to be * available. @@ -915,13 +915,13 @@ __syscall int can_calc_timing_data(const struct device *dev, struct can_timing * * @retval -EBUSY if the CAN controller is not in stopped state. * @retval -EIO General input/output error, failed to configure device. * @retval -ENOTSUP if the timing parameters are not supported by the driver. - * @retval -ENOSYS if CAN-FD support is not implemented by the driver. + * @retval -ENOSYS if CAN FD support is not implemented by the driver. */ __syscall int can_set_timing_data(const struct device *dev, const struct can_timing *timing_data); /** - * @brief Set the bitrate for the data phase of the CAN-FD controller + * @brief Set the bitrate for the data phase of the CAN FD controller * * CAN in Automation (CiA) 301 v4.2.0 recommends a sample point location of * 87.5% percent for all bitrates. However, some CAN controllers have @@ -1605,12 +1605,12 @@ static inline bool can_frame_matches_filter(const struct can_frame *frame, } if ((frame->flags & CAN_FRAME_FDF) != 0 && (filter->flags & CAN_FILTER_FDF) == 0) { - /* CAN-FD format frame, classic format filter */ + /* CAN FD format frame, classic format filter */ return false; } if ((frame->flags & CAN_FRAME_FDF) == 0 && (filter->flags & CAN_FILTER_FDF) != 0) { - /* Classic frame, CAN-FD format filter */ + /* Classic frame, CAN FD format filter */ return false; } diff --git a/include/zephyr/net/socketcan.h b/include/zephyr/net/socketcan.h index 29ec5b3638d..c4916487d99 100644 --- a/include/zephyr/net/socketcan.h +++ b/include/zephyr/net/socketcan.h @@ -49,7 +49,7 @@ enum { #define CAN_MTU (sizeof(struct socketcan_frame)) #endif /* !CONFIG_CAN_FD_MODE */ -/* CAN-FD specific flags from Linux Kernel (include/uapi/linux/can.h) */ +/* CAN FD specific flags from Linux Kernel (include/uapi/linux/can.h) */ #define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ #define CANFD_ESI 0x02 /* error state indicator of the transmitting node */ #define CANFD_FDF 0x04 /* mark CAN FD for dual use of struct canfd_frame */ diff --git a/samples/drivers/can/babbling/Kconfig b/samples/drivers/can/babbling/Kconfig index c98047657a0..0d283081527 100644 --- a/samples/drivers/can/babbling/Kconfig +++ b/samples/drivers/can/babbling/Kconfig @@ -22,10 +22,10 @@ config SAMPLE_CAN_BABBLING_RTR Babbling node sends Remote Transmission Request (RTR) frames. config SAMPLE_CAN_BABBLING_FD_MODE - bool "Send CAN-FD format frames" + bool "Send CAN FD format frames" select CAN_FD_MODE help - Babbling node sends CAN-FD format frames. + Babbling node sends CAN FD format frames. config SAMPLE_CAN_BABBLING_TX_QUEUE_SIZE int "Maximum number of CAN frames to enqueue" diff --git a/samples/drivers/can/babbling/README.rst b/samples/drivers/can/babbling/README.rst index e80e03c8449..f13c80af822 100644 --- a/samples/drivers/can/babbling/README.rst +++ b/samples/drivers/can/babbling/README.rst @@ -47,5 +47,5 @@ Sample output .. code-block:: console *** Booting Zephyr OS build zephyr-v3.1.0-4606-g8c1efa8b96bb *** - babbling on can@40024000 with standard (11-bit) CAN ID 0x010, RTR 0, CAN-FD 0 + babbling on can@40024000 with standard (11-bit) CAN ID 0x010, RTR 0, CAN FD 0 abort by pressing User SW3 button diff --git a/samples/drivers/can/babbling/src/main.c b/samples/drivers/can/babbling/src/main.c index d43623bd878..ada6852ae8f 100644 --- a/samples/drivers/can/babbling/src/main.c +++ b/samples/drivers/can/babbling/src/main.c @@ -60,7 +60,7 @@ int main(void) if (IS_ENABLED(CONFIG_SAMPLE_CAN_BABBLING_FD_MODE)) { err = can_set_mode(dev, CAN_MODE_FD); if (err != 0) { - printk("Error setting CAN-FD mode (err %d)", err); + printk("Error setting CAN FD mode (err %d)", err); return 0; } } @@ -109,7 +109,7 @@ int main(void) frame.id = CONFIG_SAMPLE_CAN_BABBLING_CAN_ID; - printk("babbling on %s with %s (%d-bit) CAN ID 0x%0*x, RTR %d, CAN-FD %d\n", + printk("babbling on %s with %s (%d-bit) CAN ID 0x%0*x, RTR %d, CAN FD %d\n", dev->name, (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard", (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11, diff --git a/samples/subsys/canbus/isotp/Kconfig b/samples/subsys/canbus/isotp/Kconfig index 2ee75804b70..9fd282d2282 100644 --- a/samples/subsys/canbus/isotp/Kconfig +++ b/samples/subsys/canbus/isotp/Kconfig @@ -23,7 +23,7 @@ config SAMPLE_RX_THREAD_PRIORITY Priority used for the RX threads. config SAMPLE_CAN_FD_MODE - bool "Use CAN-FD" + bool "Use CAN FD" select CAN_FD_MODE config ISOTP_RX_BUF_COUNT diff --git a/subsys/canbus/isotp/Kconfig b/subsys/canbus/isotp/Kconfig index 1f9ae2d8a34..281692cf95e 100644 --- a/subsys/canbus/isotp/Kconfig +++ b/subsys/canbus/isotp/Kconfig @@ -80,7 +80,7 @@ config ISOTP_RX_BUF_SIZE help This value defines the size of a single block in the pool. The number of blocks is given by ISOTP_RX_BUF_COUNT. To be efficient use a multiple of - CAN_MAX_DLEN - 1 (for classic CAN : 8 - 1 = 7, for CAN-FD : 64 - 1 = 63). + CAN_MAX_DLEN - 1 (for classic CAN : 8 - 1 = 7, for CAN FD : 64 - 1 = 63). config ISOTP_RX_SF_FF_BUF_COUNT int "Number of SF and FF data buffers for receiving data" diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 710487950c6..776cdd312a4 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -126,7 +126,7 @@ static inline uint32_t receive_get_sf_length(struct net_buf *buf, bool fdf) { uint8_t len = net_buf_pull_u8(buf) & ISOTP_PCI_SF_DL_MASK; - /* Single frames > 8 bytes (CAN-FD only) */ + /* Single frames > 8 bytes (CAN FD only) */ if (IS_ENABLED(CONFIG_CAN_FD_MODE) && fdf && !len) { len = net_buf_pull_u8(buf); } @@ -433,7 +433,7 @@ static void process_ff_sf(struct isotp_recv_ctx *rctx, struct can_frame *frame) #endif sf_len = frame->data[index] & ISOTP_PCI_SF_DL_MASK; - /* Single frames > 8 bytes (CAN-FD only) */ + /* Single frames > 8 bytes (CAN FD only) */ if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (rctx->rx_addr.flags & ISOTP_MSG_FDF) != 0 && can_dl > ISOTP_4BIT_SF_MAX_CAN_DL) { if (sf_len != 0) { @@ -920,7 +920,7 @@ static inline int send_sf(struct isotp_send_ctx *sctx) (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && len + index > ISOTP_PADDED_FRAME_DL_MIN)) { /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. - * Mandatory for ISO-TP CAN-FD frames > 8 bytes. + * Mandatory for ISO-TP CAN FD frames > 8 bytes. */ frame.dlc = can_bytes_to_dlc( MAX(ISOTP_PADDED_FRAME_DL_MIN, len + index)); @@ -1003,7 +1003,7 @@ static inline int send_cf(struct isotp_send_ctx *sctx) (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && len + index > ISOTP_PADDED_FRAME_DL_MIN)) { /* AUTOSAR requirements SWS_CanTp_00348 / SWS_CanTp_00351. - * Mandatory for ISO-TP CAN-FD frames > 8 bytes. + * Mandatory for ISO-TP CAN FD frames > 8 bytes. */ frame.dlc = can_bytes_to_dlc( MAX(ISOTP_PADDED_FRAME_DL_MIN, len + index)); @@ -1243,7 +1243,7 @@ static int send(struct isotp_send_ctx *sctx, const struct device *can_dev, len = get_send_ctx_data_len(sctx); LOG_DBG("Send %zu bytes to addr 0x%x and listen on 0x%x", len, sctx->tx_addr.ext_id, sctx->rx_addr.ext_id); - /* Single frames > 8 bytes use an additional byte for length (CAN-FD only) */ + /* Single frames > 8 bytes use an additional byte for length (CAN FD only) */ if (len > sctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - ((sctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { ret = add_fc_filter(sctx); diff --git a/tests/drivers/can/api/src/canfd.c b/tests/drivers/can/api/src/canfd.c index 4fde63a36ae..d8dfb8b3c31 100644 --- a/tests/drivers/can/api/src/canfd.c +++ b/tests/drivers/can/api/src/canfd.c @@ -235,7 +235,7 @@ ZTEST(canfd, test_get_capabilities) err = can_get_capabilities(can_dev, &cap); zassert_equal(err, 0, "failed to get CAN capabilities (err %d)", err); zassert_not_equal(cap & (CAN_MODE_LOOPBACK | CAN_MODE_FD), 0, - "CAN-FD loopback mode not supported"); + "CAN FD loopback mode not supported"); } /** @@ -248,7 +248,7 @@ ZTEST(canfd, test_send_receive_classic) } /** - * @brief Test send/receive with standard (11-bit) CAN IDs and CAN-FD frames. + * @brief Test send/receive with standard (11-bit) CAN IDs and CAN FD frames. */ ZTEST(canfd, test_send_receive_fd) { @@ -257,7 +257,7 @@ ZTEST(canfd, test_send_receive_fd) } /** - * @brief Test send/receive with (11-bit) CAN IDs, mixed classic and CAN-FD frames. + * @brief Test send/receive with (11-bit) CAN IDs, mixed classic and CAN FD frames. */ ZTEST(canfd, test_send_receive_mixed) { @@ -290,7 +290,7 @@ static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t s err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); - /* Add classic CAN and CAN-FD filter */ + /* Add classic CAN and CAN FD filter */ filter_id_1 = add_rx_msgq(can_dev, &test_std_filter_1); filter_id_2 = add_rx_msgq(can_dev, &test_std_fdf_filter_2); @@ -301,7 +301,7 @@ static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t s assert_frame_equal(&frame, &test_std_frame_1, 0); if ((first & CAN_MODE_FD) != 0) { - /* Verify CAN-FD filter in first mode */ + /* Verify CAN FD filter in first mode */ send_test_frame(can_dev, &test_std_fdf_frame_2); err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT); zassert_equal(err, 0, "receive timeout"); @@ -329,14 +329,14 @@ static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t s assert_frame_equal(&frame, &test_std_frame_1, 0); if ((second & CAN_MODE_FD) != 0) { - /* Verify CAN-FD filter in second mode */ + /* Verify CAN FD filter in second mode */ send_test_frame(can_dev, &test_std_fdf_frame_2); err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT); zassert_equal(err, 0, "receive timeout"); assert_frame_equal(&frame, &test_std_fdf_frame_2, 0); } - /* Stop controller and restore CAN-FD loopback mode */ + /* Stop controller and restore CAN FD loopback mode */ err = can_stop(can_dev); zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err); @@ -356,7 +356,7 @@ static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t s /** * @brief Test that CAN RX filters are preserved through CAN controller mode changes between classic - * CAN and CAN-FD. + * CAN and CAN FD. */ ZTEST_USER(canfd, test_filters_preserved_through_classic_to_fd_mode_change) { @@ -364,7 +364,7 @@ ZTEST_USER(canfd, test_filters_preserved_through_classic_to_fd_mode_change) } /** - * @brief Test that CAN RX filters are preserved through CAN controller mode changes between CAN-FD + * @brief Test that CAN RX filters are preserved through CAN controller mode changes between CAN FD * and classic CAN. */ ZTEST_USER(canfd, test_filters_preserved_through_fd_to_classic_mode_change) @@ -432,7 +432,7 @@ void *canfd_setup(void) (void)can_stop(can_dev); err = can_set_mode(can_dev, CAN_MODE_LOOPBACK | CAN_MODE_FD); - zassert_equal(err, 0, "failed to set CAN-FD loopback mode (err %d)", err); + zassert_equal(err, 0, "failed to set CAN FD loopback mode (err %d)", err); err = can_start(can_dev); zassert_equal(err, 0, "failed to start CAN controller (err %d)", err); diff --git a/tests/drivers/can/api/src/classic.c b/tests/drivers/can/api/src/classic.c index 5044b600ff9..34a9b42dc1d 100644 --- a/tests/drivers/can/api/src/classic.c +++ b/tests/drivers/can/api/src/classic.c @@ -785,7 +785,7 @@ ZTEST_USER(can_classic, test_send_invalid_dlc) } /** - * @brief Test that CAN-FD format frames are rejected in non-FD mode. + * @brief Test that CAN FD format frames are rejected in non-FD mode. */ ZTEST_USER(can_classic, test_send_fd_format) { @@ -797,7 +797,7 @@ ZTEST_USER(can_classic, test_send_fd_format) frame.flags = CAN_FRAME_FDF; err = can_send(can_dev, &frame, TEST_SEND_TIMEOUT, NULL, NULL); - zassert_equal(err, -ENOTSUP, "sent a CAN-FD format frame in non-FD mode"); + zassert_equal(err, -ENOTSUP, "sent a CAN FD format frame in non-FD mode"); } /** diff --git a/tests/drivers/can/api/src/common.c b/tests/drivers/can/api/src/common.c index 8d6889fd28f..234bf1eb761 100644 --- a/tests/drivers/can/api/src/common.c +++ b/tests/drivers/can/api/src/common.c @@ -81,7 +81,7 @@ const struct can_frame test_ext_rtr_frame_1 = { }; /** - * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload. + * @brief Standard (11-bit) CAN ID frame 1 with CAN FD payload. */ const struct can_frame test_std_fdf_frame_1 = { .flags = CAN_FRAME_FDF | CAN_FRAME_BRS, @@ -95,7 +95,7 @@ const struct can_frame test_std_fdf_frame_1 = { }; /** - * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload. + * @brief Standard (11-bit) CAN ID frame 1 with CAN FD payload. */ const struct can_frame test_std_fdf_frame_2 = { .flags = CAN_FRAME_FDF | CAN_FRAME_BRS, @@ -219,7 +219,7 @@ const struct can_filter test_std_some_filter = { }; /** - * @brief Standard (11-bit) CAN-FD ID filter 1. This filter matches + * @brief Standard (11-bit) CAN FD ID filter 1. This filter matches * ``test_std_fdf_frame_1``. */ const struct can_filter test_std_fdf_filter_1 = { @@ -229,7 +229,7 @@ const struct can_filter test_std_fdf_filter_1 = { }; /** - * @brief Standard (11-bit) CAN-FD ID filter 2. This filter matches + * @brief Standard (11-bit) CAN FD ID filter 2. This filter matches * ``test_std_fdf_frame_2``. */ const struct can_filter test_std_fdf_filter_2 = { diff --git a/tests/drivers/can/api/src/common.h b/tests/drivers/can/api/src/common.h index bc4ba765280..65475add23f 100644 --- a/tests/drivers/can/api/src/common.h +++ b/tests/drivers/can/api/src/common.h @@ -87,12 +87,12 @@ extern const struct can_frame test_std_rtr_frame_1; extern const struct can_frame test_ext_rtr_frame_1; /** - * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload. + * @brief Standard (11-bit) CAN ID frame 1 with CAN FD payload. */ extern const struct can_frame test_std_fdf_frame_1; /** - * @brief Standard (11-bit) CAN ID frame 2 with CAN-FD payload. + * @brief Standard (11-bit) CAN ID frame 2 with CAN FD payload. */ extern const struct can_frame test_std_fdf_frame_2; @@ -163,13 +163,13 @@ extern const struct can_filter test_ext_rtr_filter_1; extern const struct can_filter test_std_some_filter; /** - * @brief Standard (11-bit) CAN-FD ID filter 1. This filter matches + * @brief Standard (11-bit) CAN FD ID filter 1. This filter matches * ``test_std_fdf_frame_1``. */ extern const struct can_filter test_std_fdf_filter_1; /** - * @brief Standard (11-bit) CAN-FD ID filter 2. This filter matches + * @brief Standard (11-bit) CAN FD ID filter 2. This filter matches * ``test_std_fdf_frame_2``. */ extern const struct can_filter test_std_fdf_filter_2; diff --git a/tests/drivers/can/api/src/utilities.c b/tests/drivers/can/api/src/utilities.c index 785c4b9cedf..90f5cbd2cf5 100644 --- a/tests/drivers/can/api/src/utilities.c +++ b/tests/drivers/can/api/src/utilities.c @@ -24,12 +24,12 @@ ZTEST(can_utilities, test_can_dlc_to_bytes) { uint8_t dlc; - /* CAN 2.0B/CAN-FD DLC, 0 to 8 data bytes */ + /* CAN 2.0B/CAN FD DLC, 0 to 8 data bytes */ for (dlc = 0; dlc <= 8; dlc++) { zassert_equal(can_dlc_to_bytes(dlc), dlc, "wrong number of bytes for DLC %u", dlc); } - /* CAN-FD DLC, 12 to 64 data bytes in steps */ + /* CAN FD DLC, 12 to 64 data bytes in steps */ zassert_equal(can_dlc_to_bytes(9), 12, "wrong number of bytes for DLC 9"); zassert_equal(can_dlc_to_bytes(10), 16, "wrong number of bytes for DLC 10"); zassert_equal(can_dlc_to_bytes(11), 20, "wrong number of bytes for DLC 11"); @@ -51,7 +51,7 @@ ZTEST(can_utilities, test_can_bytes_to_dlc) zassert_equal(can_bytes_to_dlc(bytes), bytes, "wrong DLC for %u byte(s)", bytes); } - /* CAN-FD DLC, 12 to 64 data bytes in steps */ + /* CAN FD DLC, 12 to 64 data bytes in steps */ zassert_equal(can_bytes_to_dlc(12), 9, "wrong DLC for 12 bytes"); zassert_equal(can_bytes_to_dlc(16), 10, "wrong DLC for 16 bytes"); zassert_equal(can_bytes_to_dlc(20), 11, "wrong DLC for 20 bytes"); @@ -119,17 +119,17 @@ ZTEST(can_utilities, test_can_frame_matches_filter) zassert_false(can_frame_matches_filter(&test_std_frame_1, &test_std_rtr_filter_1)); zassert_false(can_frame_matches_filter(&test_ext_frame_1, &test_ext_rtr_filter_1)); - /* CAN-FD format frames and filters */ + /* CAN FD format frames and filters */ zassert_true(can_frame_matches_filter(&test_std_fdf_frame_1, &test_std_fdf_filter_1)); zassert_true(can_frame_matches_filter(&test_std_fdf_frame_2, &test_std_fdf_filter_2)); zassert_false(can_frame_matches_filter(&test_std_fdf_frame_1, &test_std_fdf_filter_2)); zassert_false(can_frame_matches_filter(&test_std_fdf_frame_2, &test_std_fdf_filter_1)); - /* CAN-FD format frames and classic filters */ + /* CAN FD format frames and classic filters */ zassert_false(can_frame_matches_filter(&test_std_fdf_frame_1, &test_std_filter_1)); zassert_false(can_frame_matches_filter(&test_std_fdf_frame_2, &test_std_filter_2)); - /* Classic format frames and CAN-FD format filters */ + /* Classic format frames and CAN FD format filters */ zassert_false(can_frame_matches_filter(&test_std_frame_1, &test_std_fdf_filter_1)); zassert_false(can_frame_matches_filter(&test_std_frame_2, &test_std_fdf_filter_2)); } diff --git a/tests/drivers/can/timing/src/main.c b/tests/drivers/can/timing/src/main.c index 878d48ad208..7f576de6c0b 100644 --- a/tests/drivers/can/timing/src/main.c +++ b/tests/drivers/can/timing/src/main.c @@ -70,7 +70,7 @@ static const struct can_timing_test can_timing_data_tests[] = { { 500000, 800, false }, /** Valid bitrate, invalid sample point. */ { 500000, 1000, true }, - /** Invalid CAN-FD bitrate, valid sample point. */ + /** Invalid CAN FD bitrate, valid sample point. */ { 8000000 + 1, 750, true }, }; #endif /* CONFIG_CAN_FD_MODE */ @@ -175,7 +175,7 @@ static void test_timing_values(const struct device *dev, const struct can_timing max = can_get_timing_data_max(dev); sp_err = can_calc_timing_data(dev, &timing, test->bitrate, test->sp); } else { - zassert_unreachable("data phase timing test without CAN-FD support"); + zassert_unreachable("data phase timing test without CAN FD support"); } } else { min = can_get_timing_min(dev); diff --git a/tests/subsys/canbus/isotp/conformance/Kconfig b/tests/subsys/canbus/isotp/conformance/Kconfig index 8ba8f1c5387..cdc8ac501f3 100644 --- a/tests/subsys/canbus/isotp/conformance/Kconfig +++ b/tests/subsys/canbus/isotp/conformance/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 config TEST_USE_CAN_FD_MODE - bool "Use CAN-FD" + bool "Use CAN FD" select CAN_FD_MODE config TEST_ISOTP_TX_DL diff --git a/tests/subsys/canbus/isotp/conformance/prj.conf b/tests/subsys/canbus/isotp/conformance/prj.conf index 5b25fdc81a6..c85ac09f025 100644 --- a/tests/subsys/canbus/isotp/conformance/prj.conf +++ b/tests/subsys/canbus/isotp/conformance/prj.conf @@ -6,5 +6,5 @@ CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y CONFIG_ISOTP_RX_BUF_COUNT=6 CONFIG_ISOTP_RX_BUF_SIZE=128 CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2 -# some tests may be skipped if CAN-FD should be used, but is not supported by the controller +# some tests may be skipped if CAN FD should be used, but is not supported by the controller CONFIG_ZTEST_VERIFY_RUN_ALL=n diff --git a/tests/subsys/canbus/isotp/conformance/src/main.c b/tests/subsys/canbus/isotp/conformance/src/main.c index 64947ae0ed1..ba3e0890c7b 100644 --- a/tests/subsys/canbus/isotp/conformance/src/main.c +++ b/tests/subsys/canbus/isotp/conformance/src/main.c @@ -1019,7 +1019,7 @@ ZTEST(isotp_conformance, test_sender_fc_errors) ZTEST(isotp_conformance, test_canfd_mandatory_padding) { - /* Mandatory padding of CAN-FD frames (TX_DL > 8). + /* Mandatory padding of CAN FD frames (TX_DL > 8). * Must be padded with 0xCC up to the nearest DLC. */ #if TX_DL < 12 diff --git a/tests/subsys/canbus/isotp/conformance/src/mode_check.c b/tests/subsys/canbus/isotp/conformance/src/mode_check.c index fac5eeffa70..1fa872c5c39 100644 --- a/tests/subsys/canbus/isotp/conformance/src/mode_check.c +++ b/tests/subsys/canbus/isotp/conformance/src/mode_check.c @@ -6,7 +6,7 @@ /* * This test suite checks that correct errors are returned when trying to use the ISO-TP - * protocol with CAN-FD mode even though the controller does not support CAN-FD. + * protocol with CAN FD mode even though the controller does not support CAN FD. */ #include diff --git a/tests/subsys/canbus/isotp/conformance/testcase.yaml b/tests/subsys/canbus/isotp/conformance/testcase.yaml index 74ab3331ffa..ce9c838ab97 100644 --- a/tests/subsys/canbus/isotp/conformance/testcase.yaml +++ b/tests/subsys/canbus/isotp/conformance/testcase.yaml @@ -5,11 +5,11 @@ # +--------+------------------------+----------------------+----------------+ # | 1 | Classical CAN only | CONFIG_CAN_FD_MODE=n | nucleo_f072 | # | 2 | Classical CAN only | CONFIG_CAN_FD_MODE=y | nucleo_f072 | -# | 3 | Classical CAN + CAN-FD | CONFIG_CAN_FD_MODE=n | native_posix | -# | 4 | Classical CAN + CAN-FD | CONFIG_CAN_FD_MODE=y | native_posix | +# | 3 | Classical CAN + CAN FD | CONFIG_CAN_FD_MODE=n | native_posix | +# | 4 | Classical CAN + CAN FD | CONFIG_CAN_FD_MODE=y | native_posix | # # The test-specific CONFIG_TEST_USE_CAN_FD_MODE is used to decide if the test should use -# CAN-FD independent of CONFIG_CAN_FD_MODE configuration. +# CAN FD independent of CONFIG_CAN_FD_MODE configuration. # tests: From 213826f9151de455d65d1df948ba19bdafe5ffc8 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 31 Oct 2023 12:21:49 +0100 Subject: [PATCH 2898/4498] doc: heap: Fix heap examples Fix examples for HEAP_LISTENER_ALLOC_DEFINE() and HEAP_LISTENER_FREE_DEFINE(). Delete misused input heap_id variable. It caused incorrect log output. Signed-off-by: Andrej Butok --- include/zephyr/sys/heap_listener.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/sys/heap_listener.h b/include/zephyr/sys/heap_listener.h index 5923d5e2635..a2f49d2a7ed 100644 --- a/include/zephyr/sys/heap_listener.h +++ b/include/zephyr/sys/heap_listener.h @@ -195,7 +195,7 @@ void heap_listener_notify_resize(uintptr_t heap_id, void *old_heap_end, void *ne * @code * void on_heap_alloc(uintptr_t heap_id, void *mem, size_t bytes) * { - * LOG_INF("Memory allocated at %p, size %ld", heap_id, mem, bytes); + * LOG_INF("Memory allocated at %p, size %ld", mem, bytes); * } * * HEAP_LISTENER_ALLOC_DEFINE(my_listener, HEAP_ID_LIBC, on_heap_alloc); @@ -221,7 +221,7 @@ void heap_listener_notify_resize(uintptr_t heap_id, void *old_heap_end, void *ne * @code * void on_heap_free(uintptr_t heap_id, void *mem, size_t bytes) * { - * LOG_INF("Memory freed at %p, size %ld", heap_id, mem, bytes); + * LOG_INF("Memory freed at %p, size %ld", mem, bytes); * } * * HEAP_LISTENER_FREE_DEFINE(my_listener, HEAP_ID_LIBC, on_heap_free); From 55fa9b614936e678bf7e197127f3e52981b695cb Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 31 Oct 2023 11:47:11 +0000 Subject: [PATCH 2899/4498] serial: mchp_xec: fix PM dependencies in driver Implementation of PM in the driver requires PM to be enabled. This was enabled in the SoC until now and was recently removed. Fixes #64608 Signed-off-by: Anas Nashif --- drivers/serial/uart_mchp_xec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/serial/uart_mchp_xec.c b/drivers/serial/uart_mchp_xec.c index 12143a2d20b..603a00656ad 100644 --- a/drivers/serial/uart_mchp_xec.c +++ b/drivers/serial/uart_mchp_xec.c @@ -219,7 +219,7 @@ struct uart_xec_dev_data { static const struct uart_driver_api uart_xec_driver_api; -#ifdef CONFIG_PM_DEVICE +#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) static void uart_xec_pm_policy_state_lock_get(enum uart_xec_pm_policy_state_flag flag) { if (atomic_test_and_set_bit(pm_policy_state_flag, flag) == 0) { @@ -644,7 +644,7 @@ static int uart_xec_fifo_fill(const struct device *dev, const uint8_t *tx_data, k_spinlock_key_t key = k_spin_lock(&dev_data->lock); for (i = 0; (i < size) && (regs->LSR & LSR_THRE) != 0; i++) { -#ifdef CONFIG_PM_DEVICE +#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) uart_xec_pm_policy_state_lock_get(UART_XEC_PM_POLICY_STATE_TX_FLAG); #endif regs->RTXB = tx_data[i]; @@ -933,7 +933,7 @@ static void uart_xec_isr(const struct device *dev) dev_data->cb(dev, dev_data->cb_data); } -#ifdef CONFIG_PM_DEVICE +#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) if (uart_xec_irq_tx_complete(dev)) { uart_xec_pm_policy_state_lock_put(UART_XEC_PM_POLICY_STATE_TX_FLAG); } From 385ceb714537e783b8eeea273545926a9eab8bec Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Tue, 31 Oct 2023 10:37:25 -0700 Subject: [PATCH 2900/4498] soc: xtensa: nxp_adsp: rt595: move .noinit Mark .noinit section as NOLOAD and move it next to the other NOLOAD sections. This way it is removed from a generated image that is embedded in the rt595 app image. Signed-off-by: Mike J. Chen --- soc/xtensa/nxp_adsp/rt5xx/linker.ld | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/soc/xtensa/nxp_adsp/rt5xx/linker.ld b/soc/xtensa/nxp_adsp/rt5xx/linker.ld index 27be7215194..582c4a7fbf8 100644 --- a/soc/xtensa/nxp_adsp/rt5xx/linker.ld +++ b/soc/xtensa/nxp_adsp/rt5xx/linker.ld @@ -329,12 +329,6 @@ SECTIONS KEEP (*(.fw_ready_metadata)) } >sdram0 :sdram0_phdr - .noinit : ALIGN(4) - { - *(.noinit) - *(.noinit.*) - } >sdram0 :sdram0_phdr - .data : ALIGN(4) { __data_start = ABSOLUTE(.); @@ -391,6 +385,12 @@ SECTIONS _bss_end = ABSOLUTE(.); } >sdram0 :sdram0_phdr + .noinit (NOLOAD) : ALIGN(4) + { + *(.noinit) + *(.noinit.*) + } >sdram0 :sdram0_phdr + .heap_mem (NOLOAD) : ALIGN(8) { . = ALIGN (8); From f9809a0a72ea2a5acd32f92bbcd07b99038f96cd Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Tue, 24 Oct 2023 09:39:13 +0100 Subject: [PATCH 2901/4498] subsys/mgmt/mcumgr: Reduce unnecessary ROM usage mcumgr's SMP UDP transport was unnecessarily using a potentially large amount of ROM space due to static initialising fields in a config struct that also contains buffers/stacks. This has been changed to instead initialise fields in the start function, reducing ROM usage by ~5K in the default configuration with IPv4 and IPv6 enabled. Signed-off-by: Ben Marsh --- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index f59ca884cd0..6c0043d3f0c 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -81,20 +81,7 @@ struct configs { #endif }; -static struct configs configs = { -#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - .ipv4 = { - .proto = PROTOCOL_IPV4, - .sock = -1, - }, -#endif -#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - .ipv6 = { - .proto = PROTOCOL_IPV6, - .sock = -1, - }, -#endif -}; +static struct configs configs; static struct net_mgmt_event_callback smp_udp_mgmt_cb; @@ -382,6 +369,9 @@ static void smp_udp_start(void) int rc; #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 + configs.ipv4.proto = PROTOCOL_IPV4; + configs.ipv4.sock = -1; + k_sem_init(&configs.ipv4.network_ready_sem, 0, 1); configs.ipv4.smp_transport.functions.output = smp_udp4_tx; configs.ipv4.smp_transport.functions.get_mtu = smp_udp_get_mtu; @@ -401,6 +391,9 @@ static void smp_udp_start(void) #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 + configs.ipv6.proto = PROTOCOL_IPV6; + configs.ipv6.sock = -1; + k_sem_init(&configs.ipv6.network_ready_sem, 0, 1); configs.ipv6.smp_transport.functions.output = smp_udp6_tx; configs.ipv6.smp_transport.functions.get_mtu = smp_udp_get_mtu; From 18a09524075b6a4d1d00e5399be163d17d3f543c Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Wed, 1 Nov 2023 09:38:41 +0000 Subject: [PATCH 2902/4498] subsys/mgmt/mcumgr: Name struct to avoid violation The mcumgr SMP UDP configs struct was causing a unique tag name violation (rule 5.7). The struct name has been changed from configs to smp_udp_configs. Signed-off-by: Ben Marsh --- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 86 +++++++++++----------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index 6c0043d3f0c..f103ba91249 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -81,7 +81,7 @@ struct configs { #endif }; -static struct configs configs; +static struct configs smp_udp_configs; static struct net_mgmt_event_callback smp_udp_mgmt_cb; @@ -108,7 +108,7 @@ static int smp_udp4_tx(struct net_buf *nb) int ret; struct sockaddr *addr = net_buf_user_data(nb); - ret = sendto(configs.ipv4.sock, nb->data, nb->len, 0, addr, sizeof(*addr)); + ret = sendto(smp_udp_configs.ipv4.sock, nb->data, nb->len, 0, addr, sizeof(*addr)); if (ret < 0) { ret = MGMT_ERR_EINVAL; @@ -128,7 +128,7 @@ static int smp_udp6_tx(struct net_buf *nb) int ret; struct sockaddr *addr = net_buf_user_data(nb); - ret = sendto(configs.ipv6.sock, nb->data, nb->len, 0, addr, sizeof(*addr)); + ret = sendto(smp_udp_configs.ipv6.sock, nb->data, nb->len, 0, addr, sizeof(*addr)); if (ret < 0) { ret = MGMT_ERR_EINVAL; @@ -275,14 +275,14 @@ static void smp_udp_net_event_handler(struct net_mgmt_event_callback *cb, uint32 if (mgmt_event == NET_EVENT_L4_CONNECTED) { LOG_INF("Network connected"); #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - if (IS_THREAD_RUNNING(configs.ipv4.thread)) { - k_sem_give(&configs.ipv4.network_ready_sem); + if (IS_THREAD_RUNNING(smp_udp_configs.ipv4.thread)) { + k_sem_give(&smp_udp_configs.ipv4.network_ready_sem); } #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - if (IS_THREAD_RUNNING(configs.ipv6.thread)) { - k_sem_give(&configs.ipv6.network_ready_sem); + if (IS_THREAD_RUNNING(smp_udp_configs.ipv6.thread)) { + k_sem_give(&smp_udp_configs.ipv6.network_ready_sem); } #endif } else if (mgmt_event == NET_EVENT_L4_DISCONNECTED) { @@ -306,9 +306,9 @@ int smp_udp_open(void) bool started = false; #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - if (!IS_THREAD_RUNNING(configs.ipv4.thread)) { - (void)k_sem_reset(&configs.ipv4.network_ready_sem); - create_thread(&configs.ipv4, "smp_udp4"); + if (!IS_THREAD_RUNNING(smp_udp_configs.ipv4.thread)) { + (void)k_sem_reset(&smp_udp_configs.ipv4.network_ready_sem); + create_thread(&smp_udp_configs.ipv4, "smp_udp4"); started = true; } else { LOG_ERR("IPv4 UDP MCUmgr thread is already running"); @@ -316,9 +316,9 @@ int smp_udp_open(void) #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - if (!IS_THREAD_RUNNING(configs.ipv6.thread)) { - (void)k_sem_reset(&configs.ipv6.network_ready_sem); - create_thread(&configs.ipv6, "smp_udp6"); + if (!IS_THREAD_RUNNING(smp_udp_configs.ipv6.thread)) { + (void)k_sem_reset(&smp_udp_configs.ipv6.network_ready_sem); + create_thread(&smp_udp_configs.ipv6, "smp_udp6"); started = true; } else { LOG_ERR("IPv6 UDP MCUmgr thread is already running"); @@ -336,12 +336,12 @@ int smp_udp_open(void) int smp_udp_close(void) { #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - if (IS_THREAD_RUNNING(configs.ipv4.thread)) { - k_thread_abort(&(configs.ipv4.thread)); + if (IS_THREAD_RUNNING(smp_udp_configs.ipv4.thread)) { + k_thread_abort(&(smp_udp_configs.ipv4.thread)); - if (configs.ipv4.sock >= 0) { - close(configs.ipv4.sock); - configs.ipv4.sock = -1; + if (smp_udp_configs.ipv4.sock >= 0) { + close(smp_udp_configs.ipv4.sock); + smp_udp_configs.ipv4.sock = -1; } } else { LOG_ERR("IPv4 UDP MCUmgr thread is not running"); @@ -349,12 +349,12 @@ int smp_udp_close(void) #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - if (IS_THREAD_RUNNING(configs.ipv6.thread)) { - k_thread_abort(&(configs.ipv6.thread)); + if (IS_THREAD_RUNNING(smp_udp_configs.ipv6.thread)) { + k_thread_abort(&(smp_udp_configs.ipv6.thread)); - if (configs.ipv6.sock >= 0) { - close(configs.ipv6.sock); - configs.ipv6.sock = -1; + if (smp_udp_configs.ipv6.sock >= 0) { + close(smp_udp_configs.ipv6.sock); + smp_udp_configs.ipv6.sock = -1; } } else { LOG_ERR("IPv6 UDP MCUmgr thread is not running"); @@ -369,20 +369,20 @@ static void smp_udp_start(void) int rc; #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - configs.ipv4.proto = PROTOCOL_IPV4; - configs.ipv4.sock = -1; + smp_udp_configs.ipv4.proto = PROTOCOL_IPV4; + smp_udp_configs.ipv4.sock = -1; - k_sem_init(&configs.ipv4.network_ready_sem, 0, 1); - configs.ipv4.smp_transport.functions.output = smp_udp4_tx; - configs.ipv4.smp_transport.functions.get_mtu = smp_udp_get_mtu; - configs.ipv4.smp_transport.functions.ud_copy = smp_udp_ud_copy; + k_sem_init(&smp_udp_configs.ipv4.network_ready_sem, 0, 1); + smp_udp_configs.ipv4.smp_transport.functions.output = smp_udp4_tx; + smp_udp_configs.ipv4.smp_transport.functions.get_mtu = smp_udp_get_mtu; + smp_udp_configs.ipv4.smp_transport.functions.ud_copy = smp_udp_ud_copy; - rc = smp_transport_init(&configs.ipv4.smp_transport); + rc = smp_transport_init(&smp_udp_configs.ipv4.smp_transport); #ifdef CONFIG_SMP_CLIENT if (rc == 0) { - configs.ipv4_transport.smpt = &configs.ipv4.smp_transport; - configs.ipv4_transport.smpt_type = SMP_UDP_IPV4_TRANSPORT; - smp_client_transport_register(&configs.ipv4_transport); + smp_udp_configs.ipv4_transport.smpt = &smp_udp_configs.ipv4.smp_transport; + smp_udp_configs.ipv4_transport.smpt_type = SMP_UDP_IPV4_TRANSPORT; + smp_client_transport_register(&smp_udp_configs.ipv4_transport); } #endif if (rc) { @@ -391,20 +391,20 @@ static void smp_udp_start(void) #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - configs.ipv6.proto = PROTOCOL_IPV6; - configs.ipv6.sock = -1; + smp_udp_configs.ipv6.proto = PROTOCOL_IPV6; + smp_udp_configs.ipv6.sock = -1; - k_sem_init(&configs.ipv6.network_ready_sem, 0, 1); - configs.ipv6.smp_transport.functions.output = smp_udp6_tx; - configs.ipv6.smp_transport.functions.get_mtu = smp_udp_get_mtu; - configs.ipv6.smp_transport.functions.ud_copy = smp_udp_ud_copy; + k_sem_init(&smp_udp_configs.ipv6.network_ready_sem, 0, 1); + smp_udp_configs.ipv6.smp_transport.functions.output = smp_udp6_tx; + smp_udp_configs.ipv6.smp_transport.functions.get_mtu = smp_udp_get_mtu; + smp_udp_configs.ipv6.smp_transport.functions.ud_copy = smp_udp_ud_copy; - rc = smp_transport_init(&configs.ipv6.smp_transport); + rc = smp_transport_init(&smp_udp_configs.ipv6.smp_transport); #ifdef CONFIG_SMP_CLIENT if (rc == 0) { - configs.ipv6_transport.smpt = &configs.ipv6.smp_transport; - configs.ipv6_transport.smpt_type = SMP_UDP_IPV6_TRANSPORT; - smp_client_transport_register(&configs.ipv6_transport); + smp_udp_configs.ipv6_transport.smpt = &smp_udp_configs.ipv6.smp_transport; + smp_udp_configs.ipv6_transport.smpt_type = SMP_UDP_IPV6_TRANSPORT; + smp_client_transport_register(&smp_udp_configs.ipv6_transport); } #endif From 49c39c50d6162830ff71c4e696b97748e41a7f0f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 30 Oct 2023 13:27:10 +0000 Subject: [PATCH 2903/4498] MAINTAINERS: add co-maintainers for key areas To distribute the load, adding co-maintainer to some key areas. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 5d2e91df8f4..b49611befdb 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1644,12 +1644,13 @@ Kernel: status: maintained maintainers: - andyross + - peter-mitsis collaborators: - nashif - ceolin - dcpleung - - peter-mitsis - cfriedt + - npitre files: - doc/kernel/ - include/zephyr/kernel*.h @@ -1668,9 +1669,10 @@ Base OS: status: maintained maintainers: - andyross + - nashif collaborators: - dcpleung - - nashif + - peter-mitsis files: - include/zephyr/sys/ - lib/os/ From f9d71a2ef809c5bf62d5e238c9be83929214592d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 31 Oct 2023 13:44:27 +0000 Subject: [PATCH 2904/4498] MAINTAINERS: various updates and improvements Various updates to areas and new areas to cover some orphaned files. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 83 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b49611befdb..c095efbe95c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -111,6 +111,19 @@ # Areas are sorted by name +ACPI: + status: maintained + maintainers: + - jhedberg + - najumon1980 + collaborators: + - finikorg + files: + - lib/acpi/ + - include/zephyr/acpi/ + labels: + - "area: ACPI" + ARC arch: status: maintained maintainers: @@ -194,6 +207,18 @@ Ambiq Platforms: labels: - "platform: Ambiq" +Benchmarks: + status: maintained + maintainers: + - peter-mitsis + collaborators: + - nashif + - dcpleung + files: + - tests/benchmarks/ + labels: + - "area: Benchmarks" + Binary Descriptors: status: maintained maintainers: @@ -491,8 +516,10 @@ Common Architecture Interface: - dcpleung - nashif files: + - include/zephyr/arch/ - arch/common/ - include/zephyr/arch/common/ + - tests/arch/common/ labels: - "area: Architectures" @@ -521,6 +548,18 @@ Debug: labels: - "area: Debugging" + +Demand Paging: + status: maintained + maintainers: + - dcpleung + collaborators: + - ceolin + - peter-mitsis + - nashif + files: + - subsys/demand_paging/ + Device Driver Model: status: maintained maintainers: @@ -590,6 +629,7 @@ Disk: - subsys/sd/ - tests/subsys/sd/ - tests/drivers/disk/ + - include/zephyr/sd/ labels: - "area: Disk Access" @@ -693,6 +733,7 @@ Release Notes: files: - drivers/audio/ - include/zephyr/audio/ + - doc/hardware/peripherals/audio/ labels: - "area: Audio" @@ -704,6 +745,7 @@ Release Notes: - tests/drivers/bbram/ - drivers/bbram/ - include/zephyr/drivers/bbram.h + - doc/hardware/peripherals/bbram.rst labels: - "area: Battery Backed RAM (bbram)" @@ -717,6 +759,7 @@ Release Notes: - include/zephyr/drivers/auxdisplay.h - drivers/auxdisplay/* - dts/bindings/auxdisplay/* + - doc/hardware/peripherals/auxdisplay.rst labels: - "area: Aux display" @@ -927,6 +970,7 @@ Release Notes: - include/zephyr/dt-bindings/ethernet/ - tests/drivers/build_all/ethernet/ - dts/bindings/ethernet/ + - tests/drivers/ethernet/ labels: - "area: Ethernet" @@ -992,6 +1036,18 @@ Release Notes: labels: - "area: GPIO" +"Drivers: GNSS": + status: maintained + maintainers: + - bjarki-trackunit + files: + - doc/hardware/peripherals/gnss.rst + - drivers/gnss/ + - include/zephyr/drivers/gnss.h + - tests/drivers/gnss/ + labels: + - "area: GNSS" + "Drivers: HW Info": status: maintained maintainers: @@ -1086,6 +1142,7 @@ Release Notes: - dts/bindings/ipm/ - tests/drivers/ipm/ - doc/hardware/peripherals/ipm.rst + - include/zephyr/drivers/ipm.h description: >- Inter-processor mailboxes labels: @@ -1201,6 +1258,7 @@ Release Notes: - bjarki-trackunit files: - drivers/rtc/ + - include/zephyr/drivers/rtc/ - tests/drivers/rtc/ - doc/hardware/peripherals/rtc.rst - include/zephyr/drivers/rtc.h @@ -1333,6 +1391,7 @@ Release Notes: files: - drivers/sensor/ - include/zephyr/drivers/sensor.h + - include/zephyr/drivers/sensor_data_types.h - samples/sensor/ - tests/drivers/sensor/ - dts/bindings/sensor/ @@ -1590,6 +1649,7 @@ Input: - subsys/input/ - tests/drivers/build_all/input/ - tests/subsys/input/ + - tests/drivers/input/ description: >- Input subsystem and drivers labels: @@ -1622,6 +1682,7 @@ JSON Web Token: - include/zephyr/data/ - lib/os/json.c - tests/subsys/jwt/ + - tests/lib/json/ labels: - "area: JSON" @@ -1682,6 +1743,7 @@ Base OS: - tests/lib/cbprintf_*/ - lib/os/cbprintf* - lib/os/Kconfig.cbprintf + - include/zephyr/sys/mem_manage.h labels: - "area: Base OS" @@ -2205,6 +2267,7 @@ Twister: - gchwier files: - scripts/twister + - scripts/schemas/twister/ - scripts/pylib/twister/ - scripts/tests/twister/ - scripts/tests/twister_blackbox/ @@ -2839,6 +2902,7 @@ TF-M Integration: labels: - "area: TF-M" + "Toolchain Integration": status: maintained maintainers: @@ -2850,6 +2914,7 @@ TF-M Integration: - cmake/compiler/ - cmake/linker/ - cmake/toolchain/ + - include/zephyr/toolchain/ labels: - "area: Toolchains" @@ -2895,6 +2960,7 @@ Tracing: - teburd files: - subsys/tracing/ + - scripts/tracing/ - include/zephyr/tracing/ - subsys/timing/ - samples/subsys/tracing/ @@ -2919,6 +2985,7 @@ USB: - tests/subsys/usb/ - tests/drivers/udc/ - doc/connectivity/usb/ + - scripts/generate_usb_vif/ labels: - "area: USB" @@ -2959,6 +3026,7 @@ Userspace: - scripts/build/process_gperf.py - scripts/build/gen_relocate_app.py - include/zephyr/sys/kobject.h + - include/zephyr/sys/mem_manage.h labels: - "area: Userspace" @@ -2994,10 +3062,11 @@ West: status: maintained maintainers: - najumon1980 + - jhedberg files: - modules/acpica/ labels: - - manifest-acpica + - "area: ACPI" "West project: canopennode": status: maintained @@ -3121,7 +3190,8 @@ West: collaborators: - LucasTambor - marekmatej - files: [] + files: + - modules/Kconfig.esp32 labels: - "platform: ESP32" @@ -3133,7 +3203,7 @@ West: - drivers/misc/ethos_u/ - modules/hal_ethos_u/ labels: - - manifest-hal_ethos_u + - "area: ARM" "West project: hal_gigadevice": status: maintained @@ -3501,7 +3571,8 @@ West: - keith-packard collaborators: - stephanosio - files: [] + files: + - modules/Kconfig.picolibc labels: - "area: C Library" - "area: picolibc" @@ -3612,6 +3683,7 @@ West: - StefanHri files: - modules/uoscore-uedhoc/ + - tests/modules/uoscore/ labels: - "area: Networking" - "area: Crypto / RNG" @@ -3657,6 +3729,8 @@ Xtensa arch: - dts/xtensa/ - boards/xtensa/qemu_xtensa/ - boards/xtensa/xt-sim/ + - soc/xtensa/dc233c/ + - soc/xtensa/sample_controller/ labels: - "area: Xtensa" @@ -3710,6 +3784,7 @@ ZTest: - subsys/testsuite/ - tests/ztest/ - tests/unit/util/ + - tests/subsys/testsuite/ - samples/subsys/testsuite/ - doc/develop/test/ztest.rst labels: From 928e22c302a2df4d3570a2ace6a2968930fc8c54 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Tue, 31 Oct 2023 15:46:27 -0700 Subject: [PATCH 2905/4498] soc/riscv/riscv-ite/it8xxx2: Support DEVNULL_REGION it8xxx2 uses a custom linker script, which was not updated on dfb3674c4cb49ffa2dbdaf812dfe785bc171b025. This patch naively updates it to support DEVNULL_REGION. Signed-off-by: Ederson de Souza --- soc/riscv/riscv-ite/it8xxx2/linker.ld | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/soc/riscv/riscv-ite/it8xxx2/linker.ld b/soc/riscv/riscv-ite/it8xxx2/linker.ld index e285147f690..5c13ee2ecce 100644 --- a/soc/riscv/riscv-ite/it8xxx2/linker.ld +++ b/soc/riscv/riscv-ite/it8xxx2/linker.ld @@ -69,6 +69,8 @@ #define SHA256_BLOCK_SIZE 0x200 #endif +#include + MEMORY { #ifdef CONFIG_XIP @@ -76,6 +78,10 @@ MEMORY #endif RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE +#endif + LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ From 9cf07bbdb55f4264062297d2bee00779c7627604 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Mon, 28 Aug 2023 21:04:28 +0200 Subject: [PATCH 2906/4498] bluetooth: Rename rpmsg HCI driver and sample to ipc The existing driver and sample: - drivers/bluetooth/hci/rpmsg - samples/bluetooth/hci_rpmsg are no longer correctly named, since they now use the IPC subsystem to send and receive data. The IPC subsystem can use RPMsg as a transport, but that is one of several selectable backends. I initially wanted to deprecated both the BT_RPMSG Kconfig option as well as the zephyr,bt-hci-rpmsg-ipc chosen node in Devicetree. However, this proved to be undoable in the case of the Kconfig option. This is because it's a choice option, and those have special behavior. In particular, the only practical way to deprecate would've been to keep the old Kconfig option outside the choice (much like it's done in this commit) but then also add a 'depends on !BT_RPMSG' on each of the remaining choice symbols *except* on the new BT_HCI_IPC one. This, however, only works correctly for .conf files. If a board instead sets the default BT_HCI_BUS_TYPE in the Kconfig.defconfig file then the Kconfig tree parsing would fail, because it'd try to set it to a value (BT_RPMSG) that is no longer part of the choice. Signed-off-by: Carles Cufi --- boards/arm/bl5340_dvk/Kconfig | 2 +- boards/arm/bl5340_dvk/Kconfig.defconfig | 4 +- .../bl5340_dvk/bl5340_dvk_cpuapp_common.dtsi | 2 +- boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts | 2 +- boards/arm/nrf5340_audio_dk_nrf5340/Kconfig | 2 +- .../Kconfig.defconfig | 4 +- ...rf5340_audio_dk_nrf5340_cpuapp_common.dtsi | 2 +- .../nrf5340_audio_dk_nrf5340_cpunet.dts | 2 +- boards/arm/nrf5340dk_nrf5340/Kconfig | 2 +- .../arm/nrf5340dk_nrf5340/Kconfig.defconfig | 4 +- .../nrf5340_cpuapp_common.dtsi | 2 +- .../nrf5340dk_nrf5340_cpunet.dts | 2 +- boards/arm/pan1783_evb/Kconfig | 2 +- boards/arm/pan1783_evb/Kconfig.defconfig | 4 +- .../pan1783_evb_cpuapp_common.dtsi | 2 +- boards/arm/pan1783_evb/pan1783_evb_cpunet.dts | 2 +- .../arm/raytac_mdbt53_db_40_nrf5340/Kconfig | 2 +- .../Kconfig.defconfig | 4 +- ...tac_mdbt53_db_40_nrf5340_cpuapp_common.dts | 2 +- .../raytac_mdbt53_db_40_nrf5340_cpunet.dts | 2 +- .../arm/raytac_mdbt53v_db_40_nrf5340/Kconfig | 2 +- .../Kconfig.defconfig | 4 +- ...ac_mdbt53v_db_40_nrf5340_cpuapp_common.dts | 2 +- .../raytac_mdbt53v_db_40_nrf5340_cpunet.dts | 2 +- boards/arm/thingy53_nrf5340/Kconfig | 2 +- boards/arm/thingy53_nrf5340/Kconfig.defconfig | 4 +- .../thingy53_nrf5340_common.dtsi | 2 +- .../thingy53_nrf5340_cpunet.dts | 2 +- boards/posix/nrf_bsim/Kconfig.defconfig | 4 +- .../nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts | 2 +- .../nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts | 2 +- doc/releases/migration-guide-3.6.rst | 7 +++ drivers/bluetooth/hci/CMakeLists.txt | 15 ++++- drivers/bluetooth/hci/Kconfig | 14 ++++- drivers/bluetooth/hci/{rpmsg.c => ipc.c} | 63 ++++++++++--------- include/zephyr/drivers/bluetooth/hci_driver.h | 2 +- samples/bluetooth/bluetooth.rst | 2 +- .../direction_finding_central/README.rst | 12 ++-- .../README.rst | 12 ++-- .../README.rst | 12 ++-- .../direction_finding_peripheral/README.rst | 12 ++-- samples/bluetooth/hci_ipc/CMakeLists.txt | 14 +++++ .../{hci_rpmsg => hci_ipc}/README.rst | 21 +++---- .../{hci_rpmsg => hci_ipc}/debug_overlay.conf | 0 .../dts/arm/nordic/override.dtsi | 0 .../nrf5340_cpunet_bis-bt_ll_sw_split.conf | 0 ...nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf | 0 .../nrf5340_cpunet_cis-bt_ll_sw_split.conf | 0 .../nrf5340_cpunet_df-bt_ll_sw_split.conf | 0 .../nrf5340_cpunet_df-bt_ll_sw_split.overlay | 0 .../nrf5340_cpunet_iso-bt_ll_sw_split.conf | 0 ...0_cpunet_iso_broadcast-bt_ll_sw_split.conf | 0 ...340_cpunet_iso_central-bt_ll_sw_split.conf | 0 ..._cpunet_iso_peripheral-bt_ll_sw_split.conf | 0 ...340_cpunet_iso_receive-bt_ll_sw_split.conf | 0 .../bluetooth/{hci_rpmsg => hci_ipc}/prj.conf | 0 .../{hci_rpmsg => hci_ipc}/sample.yaml | 26 ++++---- .../{hci_rpmsg => hci_ipc}/src/main.c | 56 ++++++++--------- samples/bluetooth/hci_rpmsg/CMakeLists.txt | 8 --- samples/bluetooth/mesh/README.rst | 4 +- samples/bluetooth/mesh_demo/README.rst | 4 +- samples/bluetooth/mesh_provisioner/README.rst | 4 +- scripts/footprint/plan.txt | 6 +- subsys/bluetooth/host/Kconfig | 2 +- ...40_hci_rpmsg.conf => nrf5340_hci_ipc.conf} | 2 +- ...punet.conf => nrf5340_hci_ipc_cpunet.conf} | 2 +- tests/bluetooth/tester/overlay-le-audio.conf | 2 +- tests/bsim/bluetooth/ll/bis/sysbuild.cmake | 2 +- tests/bsim/bluetooth/ll/conn/sysbuild.cmake | 2 +- 69 files changed, 209 insertions(+), 175 deletions(-) rename drivers/bluetooth/hci/{rpmsg.c => ipc.c} (86%) create mode 100644 samples/bluetooth/hci_ipc/CMakeLists.txt rename samples/bluetooth/{hci_rpmsg => hci_ipc}/README.rst (67%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/debug_overlay.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/dts/arm/nordic/override.dtsi (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_bis-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_cis-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_df-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_df-bt_ll_sw_split.overlay (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_iso-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/prj.conf (100%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/sample.yaml (84%) rename samples/bluetooth/{hci_rpmsg => hci_ipc}/src/main.c (88%) delete mode 100644 samples/bluetooth/hci_rpmsg/CMakeLists.txt rename tests/bluetooth/tester/{nrf5340_hci_rpmsg.conf => nrf5340_hci_ipc.conf} (64%) rename tests/bluetooth/tester/{nrf5340_hci_rpmsg_cpunet.conf => nrf5340_hci_ipc_cpunet.conf} (75%) diff --git a/boards/arm/bl5340_dvk/Kconfig b/boards/arm/bl5340_dvk/Kconfig index 4be3f3971b0..365da6269e1 100644 --- a/boards/arm/bl5340_dvk/Kconfig +++ b/boards/arm/bl5340_dvk/Kconfig @@ -44,7 +44,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the bl5340_dvk_cpunet for + another board. For example hci_ipc on the bl5340_dvk_cpunet for Bluetooth applications. endif # BOARD_BL5340_DVK_CPUAPP || BOARD_BL5340_DVK_CPUAPP_NS diff --git a/boards/arm/bl5340_dvk/Kconfig.defconfig b/boards/arm/bl5340_dvk/Kconfig.defconfig index e033f718dba..798f331efc3 100644 --- a/boards/arm/bl5340_dvk/Kconfig.defconfig +++ b/boards/arm/bl5340_dvk/Kconfig.defconfig @@ -75,11 +75,11 @@ config MBOX_NRFX_IPC if BOARD_BL5340_DVK_CPUAPP || BOARD_BL5340_DVK_CPUAPP_NS choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC config BT_HCI_VS default y if BT diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_common.dtsi b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_common.dtsi index 4fd2c351013..78d1f2debf7 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_common.dtsi +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpuapp_common.dtsi @@ -15,7 +15,7 @@ zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; zephyr,display = &ili9340; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; }; /* Main LEDs and buttons are on an I2C TCA9538 GPIO port expander */ diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts index 7e6b6022e7a..2b3eb053283 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet.dts @@ -22,7 +22,7 @@ zephyr,sram = &sram1; zephyr,flash = &flash1; zephyr,code-partition = &slot0_partition; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; }; aliases { diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig b/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig index fc237786896..00e48c60542 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig @@ -43,7 +43,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP || BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP_NS diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig.defconfig index 87a9a2175a8..eaa56252095 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig.defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/Kconfig.defconfig @@ -70,11 +70,11 @@ config MBOX_NRFX_IPC if BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP || BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP_NS choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC endif # BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP || BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP_NS diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi index df028fb75a2..132687888b2 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi @@ -13,7 +13,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; watchdog0 = &wdt0; }; diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.dts b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.dts index 11244f82c5c..16aa4179fa9 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.dts +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet.dts @@ -18,7 +18,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; zephyr,sram = &sram1; zephyr,flash = &flash1; zephyr,code-partition = &slot0_partition; diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig index 85190d7c890..518328e57e8 100644 --- a/boards/arm/nrf5340dk_nrf5340/Kconfig +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig @@ -43,7 +43,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig index 09ebfbf50ba..9006846dccb 100644 --- a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig @@ -67,11 +67,11 @@ config MBOX_NRFX_IPC if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC endif # BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dtsi b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dtsi index e3029b45df3..70ba3252450 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dtsi +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dtsi @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts index f142744debd..80c3d183cd2 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts @@ -19,7 +19,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,sram = &sram1; zephyr,flash = &flash1; diff --git a/boards/arm/pan1783_evb/Kconfig b/boards/arm/pan1783_evb/Kconfig index 1e4045b7798..b9c84ba66ff 100644 --- a/boards/arm/pan1783_evb/Kconfig +++ b/boards/arm/pan1783_evb/Kconfig @@ -38,7 +38,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_PAN1783_EVB_CPUAPP diff --git a/boards/arm/pan1783_evb/Kconfig.defconfig b/boards/arm/pan1783_evb/Kconfig.defconfig index b3d7195199d..b26b4970d84 100644 --- a/boards/arm/pan1783_evb/Kconfig.defconfig +++ b/boards/arm/pan1783_evb/Kconfig.defconfig @@ -15,11 +15,11 @@ config MBOX_NRFX_IPC if BOARD_PAN1783_EVB_CPUAPP choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC endif # BOARD_PAN1783_EVB_CPUAPP diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi index 217dd0782a2..175475f5b0e 100644 --- a/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi +++ b/boards/arm/pan1783_evb/pan1783_evb_cpuapp_common.dtsi @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts b/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts index 03671c306d6..6506c46aeed 100644 --- a/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts +++ b/boards/arm/pan1783_evb/pan1783_evb_cpunet.dts @@ -19,7 +19,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,sram = &sram1; zephyr,flash = &flash1; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig index 875762de828..caf06f347d5 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig @@ -43,7 +43,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig index 103bc77168e..f179e667d6b 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/Kconfig.defconfig @@ -70,11 +70,11 @@ config MBOX_NRFX_IPC if BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts index 21cc368f959..3af7de1f17e 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts index b10848e4a28..f9c834ef228 100644 --- a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts @@ -22,7 +22,7 @@ zephyr,sram = &sram1; zephyr,flash = &flash1; zephyr,code-partition = &slot0_partition; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; }; /* These aliases are provided for compatibility with samples */ diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig index 5443d2b8486..02b44de6198 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig @@ -43,7 +43,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig index 1639553b37e..10f4373b352 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig @@ -70,11 +70,11 @@ config MBOX_NRFX_IPC if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts index 032678e7526..c7d7521d08b 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts index 8b36a2aefbb..14f0f114986 100644 --- a/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts @@ -21,7 +21,7 @@ zephyr,sram = &sram1; zephyr,flash = &flash1; zephyr,code-partition = &slot0_partition; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; }; diff --git a/boards/arm/thingy53_nrf5340/Kconfig b/boards/arm/thingy53_nrf5340/Kconfig index a907b074688..116fd1c8edb 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig @@ -56,7 +56,7 @@ config DOMAIN_CPUNET_BOARD help The board which will be used for CPUNET domain when creating a multi image application where one or more images should be located on - another board. For example hci_rpmsg on the nRF5340_cpunet for + another board. For example hci_ipc on the nRF5340_cpunet for Bluetooth applications. endif # BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index e4d9e63b7f1..708d9a05d51 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -59,11 +59,11 @@ endif # BOARD_THINGY53_NRF5340_CPUAPP_NS if !TRUSTED_EXECUTION_SECURE choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT + default BT_HCI_IPC if BT endchoice config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC config BT_HAS_HCI_VS default BT diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi index 341bb1305e1..694a6960584 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi @@ -13,7 +13,7 @@ zephyr,uart-mcumgr = &cdc_acm_uart; zephyr,bt-mon-uart = &cdc_acm_uart; zephyr,bt-c2h-uart = &cdc_acm_uart; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts index c88a8ab4f6a..895803a8623 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts @@ -19,7 +19,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,sram = &sram1; zephyr,flash = &flash1; diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 0c69364b147..6993048248c 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -45,7 +45,7 @@ config BT_CTLR depends on BT config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG + default 4096 if BT_HCI_IPC default 4096 if NRF_802154_SER_HOST && BOARD_NRF5340BSIM_NRF5340_CPUAPP default 4096 if NRF_802154_SER_RADIO && BOARD_NRF5340BSIM_NRF5340_CPUNET @@ -62,7 +62,7 @@ config IPC_SERVICE_BACKEND_RPMSG_SHMEM_RESET default y if IPC_SERVICE_BACKEND_RPMSG choice BT_HCI_BUS_TYPE - default BT_RPMSG + default BT_HCI_IPC endchoice endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index 2429134df67..36cbf9691b3 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -46,7 +46,7 @@ chosen { zephyr,flash = &flash0; - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; }; diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts index 3ae862566a2..d9d7b02fc67 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpunet.dts @@ -27,7 +27,7 @@ }; chosen { - zephyr,bt-hci-rpmsg-ipc = &ipc0; + zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; /delete-property/ zephyr,flash-controller; diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 6f30589e02f..32a5ce74961 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -32,6 +32,13 @@ Bootloader Bluetooth ========= +* The HCI implementation for both the Host and the Controller sides has been + renamed for the IPC transport. The ``CONFIG_BT_RPMSG`` Kconfig option is now + :kconfig:option:`CONFIG_BT_HCI_IPC`, and the ``zephyr,bt-hci-rpmsg-ipc`` + Devicetree chosen is now ``zephyr,bt-hci-ipc``. The existing sample has also + been renamed, from ``samples/bluetooth/hci_rpmsg`` to + ``samples/bluetooth/hci_ipc``. + Networking ========== diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index 5b09bbd81cc..b4417a72e8f 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -1,11 +1,24 @@ # SPDX-License-Identifier: Apache-2.0 +# Remove after 3.7.0 is released +if(CONFIG_BT_RPMSG) + message(FATAL_ERROR "CONFIG_BT_RPMSG has been renamed to CONFIG_BT_HCI_IPC") +endif() + +# Remove after 3.7.0 is released +if(CONFIG_BT_HCI_IPC) + dt_chosen(chosen_hci_rpmsg PROPERTY "zephyr,bt-hci-rpmsg-ipc") + if(DEFINED chosen_hci_rpmsg) + message(FATAL_ERROR "zephyr,bt-hci-rpmsg-ipc has been renamed to zephyr,bt-hci-ipc") + endif() +endif() + zephyr_library_sources_ifdef(CONFIG_BT_B91 hci_b91.c) zephyr_library_sources_ifdef(CONFIG_BT_CYW43XXX cyw43xxx.c) zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c) zephyr_library_sources_ifdef(CONFIG_BT_H4 h4.c) zephyr_library_sources_ifdef(CONFIG_BT_H5 h5.c) -zephyr_library_sources_ifdef(CONFIG_BT_RPMSG rpmsg.c) +zephyr_library_sources_ifdef(CONFIG_BT_HCI_IPC ipc.c) zephyr_library_sources_ifdef(CONFIG_BT_SPI spi.c) zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c) zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 07aa505f8b4..9c02c1a61c3 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -10,6 +10,7 @@ config BT_UART select SERIAL select UART_INTERRUPT_DRIVEN + choice BT_HCI_BUS_TYPE prompt "Bluetooth HCI driver" @@ -28,14 +29,21 @@ config BT_H5 Bluetooth three-wire (H:5) UART driver. Implementation of HCI Three-Wire UART Transport Layer. +# Removed: Here only to give the user a warning about its removal +# Remove after 3.7.0 is released config BT_RPMSG - bool "HCI using RPMsg" + bool "[REMOVED] HCI using RPMsg" + help + Use BT_HCI_IPC instead + +config BT_HCI_IPC + bool "HCI using the IPC subsystem" select BT_HAS_HCI_VS select IPC_SERVICE select MBOX help Bluetooth HCI driver for communication with another CPU - using RPMsg framework. + using the IPC subsystem. config BT_SPI bool "SPI HCI" @@ -145,7 +153,7 @@ source "drivers/bluetooth/hci/Kconfig.infineon" config BT_DRIVER_QUIRK_NO_AUTO_DLE bool "Host auto-initiated Data Length Update quirk" depends on BT_AUTO_DATA_LEN_UPDATE - default y if BT_RPMSG || BT_ESP32 + default y if BT_HCI_IPC || BT_ESP32 help Enable the quirk wherein BT Host stack will auto-initiate Data Length Update procedure for new connections for controllers that do not diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/ipc.c similarity index 86% rename from drivers/bluetooth/hci/rpmsg.c rename to drivers/bluetooth/hci/ipc.c index b3611f5f3e2..56671c702d6 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/ipc.c @@ -18,11 +18,11 @@ #include LOG_MODULE_REGISTER(bt_hci_driver); -#define RPMSG_CMD 0x01 -#define RPMSG_ACL 0x02 -#define RPMSG_SCO 0x03 -#define RPMSG_EVT 0x04 -#define RPMSG_ISO 0x05 +#define IPC_CMD 0x01 +#define IPC_ACL 0x02 +#define IPC_SCO 0x03 +#define IPC_EVT 0x04 +#define IPC_ISO 0x05 #define IPC_BOUND_TIMEOUT_IN_MS K_MSEC(1000) @@ -65,7 +65,7 @@ static bool is_hci_event_discardable(const uint8_t *evt_data) } } -static struct net_buf *bt_rpmsg_evt_recv(const uint8_t *data, size_t remaining) +static struct net_buf *bt_ipc_evt_recv(const uint8_t *data, size_t remaining) { bool discardable; struct bt_hci_evt_hdr hdr; @@ -114,7 +114,7 @@ static struct net_buf *bt_rpmsg_evt_recv(const uint8_t *data, size_t remaining) return buf; } -static struct net_buf *bt_rpmsg_acl_recv(const uint8_t *data, size_t remaining) +static struct net_buf *bt_ipc_acl_recv(const uint8_t *data, size_t remaining) { struct bt_hci_acl_hdr hdr; struct net_buf *buf; @@ -156,7 +156,7 @@ static struct net_buf *bt_rpmsg_acl_recv(const uint8_t *data, size_t remaining) return buf; } -static struct net_buf *bt_rpmsg_iso_recv(const uint8_t *data, size_t remaining) +static struct net_buf *bt_ipc_iso_recv(const uint8_t *data, size_t remaining) { struct bt_hci_iso_hdr hdr; struct net_buf *buf; @@ -198,28 +198,28 @@ static struct net_buf *bt_rpmsg_iso_recv(const uint8_t *data, size_t remaining) return buf; } -static void bt_rpmsg_rx(const uint8_t *data, size_t len) +static void bt_ipc_rx(const uint8_t *data, size_t len) { uint8_t pkt_indicator; struct net_buf *buf = NULL; size_t remaining = len; - LOG_HEXDUMP_DBG(data, len, "RPMsg data:"); + LOG_HEXDUMP_DBG(data, len, "ipc data:"); pkt_indicator = *data++; remaining -= sizeof(pkt_indicator); switch (pkt_indicator) { - case RPMSG_EVT: - buf = bt_rpmsg_evt_recv(data, remaining); + case IPC_EVT: + buf = bt_ipc_evt_recv(data, remaining); break; - case RPMSG_ACL: - buf = bt_rpmsg_acl_recv(data, remaining); + case IPC_ACL: + buf = bt_ipc_acl_recv(data, remaining); break; - case RPMSG_ISO: - buf = bt_rpmsg_iso_recv(data, remaining); + case IPC_ISO: + buf = bt_ipc_iso_recv(data, remaining); break; default: @@ -247,7 +247,7 @@ static void bt_rpmsg_rx(const uint8_t *data, size_t len) } } -static int bt_rpmsg_send(struct net_buf *buf) +static int bt_ipc_send(struct net_buf *buf) { int err; uint8_t pkt_indicator; @@ -256,13 +256,13 @@ static int bt_rpmsg_send(struct net_buf *buf) switch (bt_buf_get_type(buf)) { case BT_BUF_ACL_OUT: - pkt_indicator = RPMSG_ACL; + pkt_indicator = IPC_ACL; break; case BT_BUF_CMD: - pkt_indicator = RPMSG_CMD; + pkt_indicator = IPC_CMD; break; case BT_BUF_ISO_OUT: - pkt_indicator = RPMSG_ISO; + pkt_indicator = IPC_ISO; break; default: LOG_ERR("Unknown type %u", bt_buf_get_type(buf)); @@ -288,7 +288,7 @@ static void hci_ept_bound(void *priv) static void hci_ept_recv(const void *data, size_t len, void *priv) { - bt_rpmsg_rx(data, len); + bt_ipc_rx(data, len); } static struct ipc_ept_cfg hci_ept_cfg = { @@ -311,11 +311,12 @@ int __weak bt_hci_transport_teardown(const struct device *dev) return 0; } -static int bt_rpmsg_open(void) +static int bt_ipc_open(void) { int err; + const struct device *hci_ipc_instance = - DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc)); + DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc)); err = bt_hci_transport_setup(NULL); if (err) { @@ -346,7 +347,7 @@ static int bt_rpmsg_open(void) return 0; } -static int bt_rpmsg_close(void) +static int bt_ipc_close(void) { int err; @@ -365,7 +366,7 @@ static int bt_rpmsg_close(void) } const struct device *hci_ipc_instance = - DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc)); + DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc)); err = ipc_service_close_instance(hci_ipc_instance); if (err) { @@ -383,17 +384,17 @@ static int bt_rpmsg_close(void) } static const struct bt_hci_driver drv = { - .name = "RPMsg", - .open = bt_rpmsg_open, - .close = bt_rpmsg_close, - .send = bt_rpmsg_send, + .name = "IPC", + .open = bt_ipc_open, + .close = bt_ipc_close, + .send = bt_ipc_send, .bus = BT_HCI_DRIVER_BUS_IPM, #if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE) .quirks = BT_QUIRK_NO_AUTO_DLE, #endif }; -static int bt_rpmsg_init(void) +static int bt_ipc_init(void) { int err; @@ -406,4 +407,4 @@ static int bt_rpmsg_init(void) return err; } -SYS_INIT(bt_rpmsg_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +SYS_INIT(bt_ipc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/include/zephyr/drivers/bluetooth/hci_driver.h b/include/zephyr/drivers/bluetooth/hci_driver.h index c305ecc37c3..b318ad55ffb 100644 --- a/include/zephyr/drivers/bluetooth/hci_driver.h +++ b/include/zephyr/drivers/bluetooth/hci_driver.h @@ -245,7 +245,7 @@ int bt_hci_transport_setup(const struct device *dev); /** * @brief Teardown the HCI transport. * - * @note A weak version of this function is included in the RPMSG driver, so + * @note A weak version of this function is included in the IPC driver, so * defining it is optional. NRF5340 includes support to put network core * in reset state. * diff --git a/samples/bluetooth/bluetooth.rst b/samples/bluetooth/bluetooth.rst index e9c44451d36..b96637d0c4e 100644 --- a/samples/bluetooth/bluetooth.rst +++ b/samples/bluetooth/bluetooth.rst @@ -20,7 +20,7 @@ documentation and are prefixed with :literal:`hci_` in their folder names. ``-DBOARD=nrf5340dk_nrf5340_cpuapp`` or ``-DBOARD=nrf5340dk_nrf5340_cpuapp_ns``) you must also build and program the corresponding sample for the nRF5340 network core - :ref:`bluetooth-hci-rpmsg-sample` which implements the Bluetooth + :ref:`bluetooth-hci-ipc-sample` which implements the Bluetooth Low Energy controller. .. note:: diff --git a/samples/bluetooth/direction_finding_central/README.rst b/samples/bluetooth/direction_finding_central/README.rst index 17cbc599f6b..07a5d1c52be 100644 --- a/samples/bluetooth/direction_finding_central/README.rst +++ b/samples/bluetooth/direction_finding_central/README.rst @@ -37,21 +37,21 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :compact: To run the application on nRF5340DK, a Bluetooth controller application must -also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. To build this sample with direction finding support enabled: * Copy :zephyr_file:`samples/bluetooth/direction_finding_central/boards/nrf52833dk_nrf52833.overlay` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Make sure the same GPIO pins are assigned to Direction Finding Extension in file :zephyr_file:`samples/bluetooth/direction_finding_central/boards/nrf5340dk_nrf5340_cpuapp.overlay`. - as those in the created file :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + as those in the created file :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Copy :zephyr_file:`samples/bluetooth/direction_finding_central/boards/nrf52833dk_nrf52833.conf` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.conf`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.conf`. Antenna matrix configuration **************************** @@ -69,8 +69,8 @@ this overlay. See :ref:`set-devicetree-overlays` for information on setting up and using overlays. Note that antenna matrix configuration for the nRF5340 SoC is part of the -network core application. When :ref:`bluetooth-hci-rpmsg-sample` is used as the +network core application. When :ref:`bluetooth-hci-ipc-sample` is used as the network core application, the antenna matrix configuration should be stored in the file -:file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay` +:file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay` instead. diff --git a/samples/bluetooth/direction_finding_connectionless_rx/README.rst b/samples/bluetooth/direction_finding_connectionless_rx/README.rst index b7a970acbc4..ad8416dd537 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_rx/README.rst @@ -37,21 +37,21 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :compact: To run the application on nRF5340DK, a Bluetooth controller application must -also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. To build this sample with direction finding support enabled: * Copy :zephyr_file:`samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.overlay` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Make sure the same GPIO pins are assigned to Direction Finding Extension in file :zephyr_file:`samples/bluetooth/direction_finding_connectionless_rx/boards/nrf5340dk_nrf5340_cpuapp.overlay`. - as those in the created file :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + as those in the created file :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Copy :zephyr_file:`samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.conf` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.conf`. Add + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.conf`. Add the line ``CONFIG_BT_EXT_ADV=y`` to enable extended size of :kconfig:option:`CONFIG_BT_BUF_CMD_TX_SIZE` to support the LE Set Extended Advertising Data command. @@ -72,8 +72,8 @@ this overlay. See :ref:`set-devicetree-overlays` for information on setting up and using overlays. Note that antenna matrix configuration for the nRF5340 SoC is part of the -network core application. When :ref:`bluetooth-hci-rpmsg-sample` is used as the +network core application. When :ref:`bluetooth-hci-ipc-sample` is used as the network core application, the antenna matrix configuration should be stored in the file -:file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay` +:file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay` instead. diff --git a/samples/bluetooth/direction_finding_connectionless_tx/README.rst b/samples/bluetooth/direction_finding_connectionless_tx/README.rst index ca27319cbc7..6fe3dd68722 100644 --- a/samples/bluetooth/direction_finding_connectionless_tx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_tx/README.rst @@ -37,21 +37,21 @@ To use Angle of Arrival mode only, build this application as follows, changing :compact: To run the application on nRF5340DK, a Bluetooth controller application must -also run on the network core. The :zephyr_file:`samples/bluetooth/hci_rpmsg` +also run on the network core. The :zephyr_file:`samples/bluetooth/hci_ipc` sample application may be used. To build this sample with direction finding support enabled: * Copy :zephyr_file:`samples/bluetooth/direction_finding_connectionless_tx/boards/nrf52833dk_nrf52833.overlay` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Make sure the same GPIO pins are assigned to Direction Finding Extension in file :zephyr_file:`samples/bluetooth/direction_finding_connectionless_tx/boards/nrf5340dk_nrf5340_cpuapp.overlay`. - as those in the created file :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + as those in the created file :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Copy :zephyr_file:`samples/bluetooth/direction_finding_connectionless_tx/boards/nrf52833dk_nrf52833.conf` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.conf`. Add + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.conf`. Add the line ``CONFIG_BT_EXT_ADV=y`` to enable extended size of :kconfig:option:`CONFIG_BT_BUF_CMD_TX_SIZE` to support the LE Set Extended Advertising Data command. @@ -73,10 +73,10 @@ this overlay. See :ref:`set-devicetree-overlays` for information on setting up and using overlays. Note that antenna matrix configuration for the nRF5340 SoC is part of the -network core application. When :ref:`bluetooth-hci-rpmsg-sample` is used as +network core application. When :ref:`bluetooth-hci-ipc-sample` is used as network core application, the antenna matrix configuration should be stored in the file -:file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay` +:file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay` instead. In addition to the devicetree configuration, to successfully use the Direction diff --git a/samples/bluetooth/direction_finding_peripheral/README.rst b/samples/bluetooth/direction_finding_peripheral/README.rst index 36846c84d6f..75cc5b9a917 100644 --- a/samples/bluetooth/direction_finding_peripheral/README.rst +++ b/samples/bluetooth/direction_finding_peripheral/README.rst @@ -36,21 +36,21 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :compact: To run the application on nRF5340DK, a Bluetooth controller application must -also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. To build this sample with direction finding support enabled: * Copy :zephyr_file:`samples/bluetooth/direction_finding_peripheral/boards/nrf52833dk_nrf52833.overlay` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Make sure the same GPIO pins are assigned to Direction Finding Extension in file :zephyr_file:`samples/bluetooth/direction_finding_peripheral/boards/nrf5340dk_nrf5340_cpuapp.overlay`. - as those in the created file :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay`. + as those in the created file :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay`. * Copy :zephyr_file:`samples/bluetooth/direction_finding_peripheral/boards/nrf52833dk_nrf52833.conf` to a new file, - :file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.conf`. + :file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.conf`. Antenna matrix configuration **************************** @@ -68,8 +68,8 @@ this overlay. See :ref:`set-devicetree-overlays` for information on setting up and using overlays. Note that antenna matrix configuration for the nRF5340 SoC is part of the -network core application. When :ref:`bluetooth-hci-rpmsg-sample` is used as the +network core application. When :ref:`bluetooth-hci-ipc-sample` is used as the network core application, the antenna matrix configuration should be stored in the file -:file:`samples/bluetooth/hci_rpmsg/boards/nrf5340dk_nrf5340_cpunet.overlay` +:file:`samples/bluetooth/hci_ipc/boards/nrf5340dk_nrf5340_cpunet.overlay` instead. diff --git a/samples/bluetooth/hci_ipc/CMakeLists.txt b/samples/bluetooth/hci_ipc/CMakeLists.txt new file mode 100644 index 00000000000..02ff09719d7 --- /dev/null +++ b/samples/bluetooth/hci_ipc/CMakeLists.txt @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(hci_ipc) + +target_sources(app PRIVATE src/main.c) + +# Remove after 3.7.0 is released +dt_chosen(chosen_hci_rpmsg PROPERTY "zephyr,bt-hci-rpmsg-ipc") +if(DEFINED chosen_hci_rpmsg) + message(FATAL_ERROR "zephyr,bt-hci-rpmsg-ipc has been renamed to zephyr,bt-hci-ipc") +endif() diff --git a/samples/bluetooth/hci_rpmsg/README.rst b/samples/bluetooth/hci_ipc/README.rst similarity index 67% rename from samples/bluetooth/hci_rpmsg/README.rst rename to samples/bluetooth/hci_ipc/README.rst index 8d0cc704bfa..605898d7220 100644 --- a/samples/bluetooth/hci_rpmsg/README.rst +++ b/samples/bluetooth/hci_ipc/README.rst @@ -1,37 +1,36 @@ -.. _bluetooth-hci-rpmsg-sample: +.. _bluetooth-hci-ipc-sample: -Bluetooth: HCI RPMsg -#################### +Bluetooth: HCI IPC +################## Overview ******** This sample exposes :ref:`bluetooth_controller` support -to another device or CPU using RPMsg transport which is -a part of `OpenAMP `__. +to another device or CPU using IPC subsystem. Requirements ************ -* A board with :ref:`ipm_api` driver and Bluetooth LE support +* A board with IPC subsystem and Bluetooth LE support Building and Running ******************** -This sample can be found under :zephyr_file:`samples/bluetooth/hci_rpmsg` +This sample can be found under :zephyr_file:`samples/bluetooth/hci_ipc` in the Zephyr tree. To use this application, you need a board with a Bluetooth controller -and IPM drivers. +and IPC support. You can then build this application and flash it onto your board in the usual way. See :ref:`boards` for board-specific building and programming information. To test this sample, you need a separate device/CPU that acts as Bluetooth -HCI RPMsg peer. -This sample is compatible with the HCI RPMsg driver provided by +HCI IPC peer. +This sample is compatible with the HCI IPC driver provided by Zephyr's Bluetooth :ref:`bt_hci_drivers` core. See the -:kconfig:option:`CONFIG_BT_RPMSG` configuration option for more information. +:kconfig:option:`CONFIG_BT_HCI_IPC` configuration option for more information. You might need to adjust the Kconfig configuration of this sample to make it compatible with the peer application. For example, :kconfig:option:`CONFIG_BT_MAX_CONN` diff --git a/samples/bluetooth/hci_rpmsg/debug_overlay.conf b/samples/bluetooth/hci_ipc/debug_overlay.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/debug_overlay.conf rename to samples/bluetooth/hci_ipc/debug_overlay.conf diff --git a/samples/bluetooth/hci_rpmsg/dts/arm/nordic/override.dtsi b/samples/bluetooth/hci_ipc/dts/arm/nordic/override.dtsi similarity index 100% rename from samples/bluetooth/hci_rpmsg/dts/arm/nordic/override.dtsi rename to samples/bluetooth/hci_ipc/dts/arm/nordic/override.dtsi diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_bis-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_bis-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_cis-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_cis-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_df-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_df-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_df-bt_ll_sw_split.overlay b/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.overlay similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_df-bt_ll_sw_split.overlay rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.overlay diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf rename to samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf diff --git a/samples/bluetooth/hci_rpmsg/prj.conf b/samples/bluetooth/hci_ipc/prj.conf similarity index 100% rename from samples/bluetooth/hci_rpmsg/prj.conf rename to samples/bluetooth/hci_ipc/prj.conf diff --git a/samples/bluetooth/hci_rpmsg/sample.yaml b/samples/bluetooth/hci_ipc/sample.yaml similarity index 84% rename from samples/bluetooth/hci_rpmsg/sample.yaml rename to samples/bluetooth/hci_ipc/sample.yaml index 2ca7ce52b63..e05a5d384d2 100644 --- a/samples/bluetooth/hci_rpmsg/sample.yaml +++ b/samples/bluetooth/hci_ipc/sample.yaml @@ -1,8 +1,8 @@ sample: - description: Allows Zephyr to provide Bluetooth connectivity via RPMsg. - name: Bluetooth HCI RPMsg + description: Allows Zephyr to provide Bluetooth connectivity via IPC + name: Bluetooth HCI IPC tests: - sample.bluetooth.hci_rpmsg: + sample.bluetooth.hci_ipc: harness: bluetooth tags: bluetooth platform_allow: @@ -12,7 +12,7 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.iso_broadcast.bt_ll_sw_split: + sample.bluetooth.hci_ipc.iso_broadcast.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf" @@ -23,7 +23,7 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpunet - nrf5340_audio_dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.iso_receive.bt_ll_sw_split: + sample.bluetooth.hci_ipc.iso_receive.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf" @@ -33,7 +33,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.bis.bt_ll_sw_split: + sample.bluetooth.hci_ipc.bis.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_bis-bt_ll_sw_split.conf" @@ -43,7 +43,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.iso_central.bt_ll_sw_split: + sample.bluetooth.hci_ipc.iso_central.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso_central-bt_ll_sw_split.conf" @@ -53,7 +53,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.iso_peripheral.bt_ll_sw_split: + sample.bluetooth.hci_ipc.iso_peripheral.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf" @@ -63,7 +63,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.cis.bt_ll_sw_split: + sample.bluetooth.hci_ipc.cis.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_cis-bt_ll_sw_split.conf" @@ -73,7 +73,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.iso.bt_ll_sw_split: + sample.bluetooth.hci_ipc.iso.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_iso-bt_ll_sw_split.conf" @@ -82,7 +82,7 @@ tests: - nrf5340bsim_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.df.bt_ll_sw_split: + sample.bluetooth.hci_ipc.df.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: @@ -91,7 +91,7 @@ tests: platform_allow: nrf5340dk_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.df.no_phy_coded.bt_ll_sw_split: + sample.bluetooth.hci_ipc.df.no_phy_coded.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: @@ -101,7 +101,7 @@ tests: platform_allow: nrf5340dk_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.mesh.bt_ll_sw_split: + sample.bluetooth.hci_ipc.mesh.bt_ll_sw_split: harness: bluetooth tags: bluetooth extra_args: CONF_FILE="nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf" diff --git a/samples/bluetooth/hci_rpmsg/src/main.c b/samples/bluetooth/hci_ipc/src/main.c similarity index 88% rename from samples/bluetooth/hci_rpmsg/src/main.c rename to samples/bluetooth/hci_ipc/src/main.c index 32c4616cc79..5f0614139be 100644 --- a/samples/bluetooth/hci_rpmsg/src/main.c +++ b/samples/bluetooth/hci_ipc/src/main.c @@ -27,7 +27,7 @@ #include #include -LOG_MODULE_REGISTER(hci_rpmsg, CONFIG_BT_LOG_LEVEL); +LOG_MODULE_REGISTER(hci_ipc, CONFIG_BT_LOG_LEVEL); static struct ipc_ept hci_ept; @@ -42,16 +42,16 @@ static K_SEM_DEFINE(ipc_bound_sem, 0, 1); static bool ipc_ept_ready; #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER || CONFIG_BT_HCI_VS_FATAL_ERROR */ -#define HCI_RPMSG_CMD 0x01 -#define HCI_RPMSG_ACL 0x02 -#define HCI_RPMSG_SCO 0x03 -#define HCI_RPMSG_EVT 0x04 -#define HCI_RPMSG_ISO 0x05 +#define HCI_IPC_CMD 0x01 +#define HCI_IPC_ACL 0x02 +#define HCI_IPC_SCO 0x03 +#define HCI_IPC_EVT 0x04 +#define HCI_IPC_ISO 0x05 #define HCI_FATAL_ERR_MSG true #define HCI_REGULAR_MSG false -static struct net_buf *hci_rpmsg_cmd_recv(uint8_t *data, size_t remaining) +static struct net_buf *hci_ipc_cmd_recv(uint8_t *data, size_t remaining) { struct bt_hci_cmd_hdr *hdr = (void *)data; struct net_buf *buf; @@ -88,7 +88,7 @@ static struct net_buf *hci_rpmsg_cmd_recv(uint8_t *data, size_t remaining) return buf; } -static struct net_buf *hci_rpmsg_acl_recv(uint8_t *data, size_t remaining) +static struct net_buf *hci_ipc_acl_recv(uint8_t *data, size_t remaining) { struct bt_hci_acl_hdr *hdr = (void *)data; struct net_buf *buf; @@ -125,7 +125,7 @@ static struct net_buf *hci_rpmsg_acl_recv(uint8_t *data, size_t remaining) return buf; } -static struct net_buf *hci_rpmsg_iso_recv(uint8_t *data, size_t remaining) +static struct net_buf *hci_ipc_iso_recv(uint8_t *data, size_t remaining) { struct bt_hci_iso_hdr *hdr = (void *)data; struct net_buf *buf; @@ -162,28 +162,28 @@ static struct net_buf *hci_rpmsg_iso_recv(uint8_t *data, size_t remaining) return buf; } -static void hci_rpmsg_rx(uint8_t *data, size_t len) +static void hci_ipc_rx(uint8_t *data, size_t len) { uint8_t pkt_indicator; struct net_buf *buf = NULL; size_t remaining = len; - LOG_HEXDUMP_DBG(data, len, "RPMSG data:"); + LOG_HEXDUMP_DBG(data, len, "IPC data:"); pkt_indicator = *data++; remaining -= sizeof(pkt_indicator); switch (pkt_indicator) { - case HCI_RPMSG_CMD: - buf = hci_rpmsg_cmd_recv(data, remaining); + case HCI_IPC_CMD: + buf = hci_ipc_cmd_recv(data, remaining); break; - case HCI_RPMSG_ACL: - buf = hci_rpmsg_acl_recv(data, remaining); + case HCI_IPC_ACL: + buf = hci_ipc_acl_recv(data, remaining); break; - case HCI_RPMSG_ISO: - buf = hci_rpmsg_iso_recv(data, remaining); + case HCI_IPC_ISO: + buf = hci_ipc_iso_recv(data, remaining); break; default: @@ -220,7 +220,7 @@ static void tx_thread(void *p1, void *p2, void *p3) } } -static void hci_rpmsg_send(struct net_buf *buf, bool is_fatal_err) +static void hci_ipc_send(struct net_buf *buf, bool is_fatal_err) { uint8_t pkt_indicator; uint8_t retries = 0; @@ -232,13 +232,13 @@ static void hci_rpmsg_send(struct net_buf *buf, bool is_fatal_err) switch (bt_buf_get_type(buf)) { case BT_BUF_ACL_IN: - pkt_indicator = HCI_RPMSG_ACL; + pkt_indicator = HCI_IPC_ACL; break; case BT_BUF_EVT: - pkt_indicator = HCI_RPMSG_EVT; + pkt_indicator = HCI_IPC_EVT; break; case BT_BUF_ISO_IN: - pkt_indicator = HCI_RPMSG_ISO; + pkt_indicator = HCI_IPC_ISO; break; default: LOG_ERR("Unknown type %u", bt_buf_get_type(buf)); @@ -295,8 +295,8 @@ void bt_ctlr_assert_handle(char *file, uint32_t line) buf = hci_vs_err_assert(file, line); if (buf == NULL) { - /* Send the event over rpmsg */ - hci_rpmsg_send(buf, HCI_FATAL_ERR_MSG); + /* Send the event over ipc */ + hci_ipc_send(buf, HCI_FATAL_ERR_MSG); } else { LOG_ERR("Can't create Fatal Error HCI event: %s at %d", __FILE__, __LINE__); } @@ -334,7 +334,7 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) buf = hci_vs_err_stack_frame(reason, esf); if (buf != NULL) { - hci_rpmsg_send(buf, HCI_FATAL_ERR_MSG); + hci_ipc_send(buf, HCI_FATAL_ERR_MSG); } else { LOG_ERR("Can't create Fatal Error HCI event.\n"); } @@ -363,7 +363,7 @@ static void hci_ept_bound(void *priv) static void hci_ept_recv(const void *data, size_t len, void *priv) { LOG_INF("Received message of %u bytes.", len); - hci_rpmsg_rx((uint8_t *) data, len); + hci_ipc_rx((uint8_t *) data, len); } static struct ipc_ept_cfg hci_ept_cfg = { @@ -378,7 +378,7 @@ int main(void) { int err; const struct device *hci_ipc_instance = - DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc)); + DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc)); /* incoming events and data from the controller */ static K_FIFO_DEFINE(rx_queue); @@ -394,7 +394,7 @@ int main(void) k_thread_create(&tx_thread_data, tx_thread_stack, K_THREAD_STACK_SIZEOF(tx_thread_stack), tx_thread, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); - k_thread_name_set(&tx_thread_data, "HCI rpmsg TX"); + k_thread_name_set(&tx_thread_data, "HCI ipc TX"); /* Initialize IPC service instance and register endpoint. */ err = ipc_service_open_instance(hci_ipc_instance); @@ -413,7 +413,7 @@ int main(void) struct net_buf *buf; buf = net_buf_get(&rx_queue, K_FOREVER); - hci_rpmsg_send(buf, HCI_REGULAR_MSG); + hci_ipc_send(buf, HCI_REGULAR_MSG); } return 0; } diff --git a/samples/bluetooth/hci_rpmsg/CMakeLists.txt b/samples/bluetooth/hci_rpmsg/CMakeLists.txt deleted file mode 100644 index 11dd731c285..00000000000 --- a/samples/bluetooth/hci_rpmsg/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(hci_rpmsg) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/mesh/README.rst b/samples/bluetooth/mesh/README.rst index c30bb48adae..e6ee78ba3a7 100644 --- a/samples/bluetooth/mesh/README.rst +++ b/samples/bluetooth/mesh/README.rst @@ -45,9 +45,9 @@ Refer to your :ref:`board's documentation ` for alternative flash instructions if your board doesn't support the ``flash`` target. To run the application on an :ref:`nrf5340dk_nrf5340`, a Bluetooth controller application -must also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +must also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. Build this sample with configuration -:zephyr_file:`samples/bluetooth/hci_rpmg/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` to enable mesh support. Interacting with the sample diff --git a/samples/bluetooth/mesh_demo/README.rst b/samples/bluetooth/mesh_demo/README.rst index 52a786c164d..7fe7f0908ce 100644 --- a/samples/bluetooth/mesh_demo/README.rst +++ b/samples/bluetooth/mesh_demo/README.rst @@ -56,7 +56,7 @@ Refer to your :ref:`board's documentation ` for alternative flash instructions if your board doesn't support the ``flash`` target. To run the application on an :ref:`nrf5340dk_nrf5340`, a Bluetooth controller application -must also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +must also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. Build this sample with configuration -:zephyr_file:`samples/bluetooth/hci_rpmg/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` to enable mesh support. diff --git a/samples/bluetooth/mesh_provisioner/README.rst b/samples/bluetooth/mesh_provisioner/README.rst index 4769ae09f17..6da113afc1b 100644 --- a/samples/bluetooth/mesh_provisioner/README.rst +++ b/samples/bluetooth/mesh_provisioner/README.rst @@ -54,7 +54,7 @@ Refer to your :ref:`board's documentation ` for alternative flash instructions if your board doesn't support the ``flash`` target. To run the application on an :ref:`nrf5340dk_nrf5340`, a Bluetooth controller application -must also run on the network core. The :ref:`bluetooth-hci-rpmsg-sample` sample +must also run on the network core. The :ref:`bluetooth-hci-ipc-sample` sample application may be used. Build this sample with configuration -:zephyr_file:`samples/bluetooth/hci_rpmg/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf` to enable mesh support. diff --git a/scripts/footprint/plan.txt b/scripts/footprint/plan.txt index a734da017e8..948a430c62e 100644 --- a/scripts/footprint/plan.txt +++ b/scripts/footprint/plan.txt @@ -25,6 +25,6 @@ bt_tmap_central,default,nrf5340dk_nrf5340_cpuapp,samples/bluetooth/tmap_central, bt_tmap_peripheral,default,nrf5340dk_nrf5340_cpuapp,samples/bluetooth/tmap_peripheral, bt_tmap_bms,default,nrf5340dk_nrf5340_cpuapp,samples/bluetooth/tmap_bms, bt_tmap_bmr,default,nrf5340dk_nrf5340_cpuapp,samples/bluetooth/tmap_bmr, -bt_hci_rpmsg,default,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_rpmsg, -bt_hci_rpmsg,iso-broadcast,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_rpmsg,-DCONF_FILE=nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf -bt_hci_rpmsg,iso-receive,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_rpmsg,-DCONF_FILE=nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf +bt_hci_ipc,default,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_ipc, +bt_hci_ipc,iso-broadcast,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_ipc,-DCONF_FILE=nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf +bt_hci_ipc,iso-receive,nrf5340dk_nrf5340_cpunet,samples/bluetooth/hci_ipc,-DCONF_FILE=nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 72a65eebf6f..59cf196c363 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -76,7 +76,7 @@ config BT_HCI_RESERVE int default 0 if BT_H4 default 1 if BT_H5 - default 1 if BT_RPMSG + default 1 if BT_HCI_IPC default 1 if BT_SPI default 1 if BT_STM32_IPM default 1 if BT_USERCHAN diff --git a/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf b/tests/bluetooth/tester/nrf5340_hci_ipc.conf similarity index 64% rename from tests/bluetooth/tester/nrf5340_hci_rpmsg.conf rename to tests/bluetooth/tester/nrf5340_hci_ipc.conf index 234d0f5a249..689ee0ea5af 100644 --- a/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf +++ b/tests/bluetooth/tester/nrf5340_hci_ipc.conf @@ -1,4 +1,4 @@ -# Those have to be the same as in the controller (hci_rpmsg) +# Those have to be the same as in the controller (hci_ipc) CONFIG_BT_MAX_CONN=2 CONFIG_BT_BUF_EVT_RX_COUNT=16 CONFIG_BT_BUF_EVT_RX_SIZE=255 diff --git a/tests/bluetooth/tester/nrf5340_hci_rpmsg_cpunet.conf b/tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf similarity index 75% rename from tests/bluetooth/tester/nrf5340_hci_rpmsg_cpunet.conf rename to tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf index 7a484587c5c..399262b47c9 100644 --- a/tests/bluetooth/tester/nrf5340_hci_rpmsg_cpunet.conf +++ b/tests/bluetooth/tester/nrf5340_hci_ipc_cpunet.conf @@ -1,4 +1,4 @@ -# Apply this overlay at hci_rpmsg controller build +# Apply this overlay at hci_ipc controller build CONFIG_BT_CTLR_CONN_ISO_LOW_LATENCY_POLICY=y CONFIG_BT_CTLR_DATA_LENGTH_MAX=100 CONFIG_BT_BUF_ACL_RX_SIZE=100 diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 101b04f9f9b..1db37efb5a3 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -10,7 +10,7 @@ CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=16 # Ring buffer for streaming ISO data CONFIG_RING_BUFFER=y -# These have to be the same as in the controller (hci_rpmsg) +# These have to be the same as in the controller (hci_ipc) CONFIG_BT_MAX_CONN=2 CONFIG_BT_BUF_EVT_RX_COUNT=16 CONFIG_BT_BUF_EVT_RX_SIZE=255 diff --git a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake index 9a01fec76c5..eb75debccd3 100644 --- a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) - set(NET_APP hci_rpmsg) + set(NET_APP hci_ipc) set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) ExternalZephyrProject_Add( diff --git a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake index 959db3af95a..2294fd5bb5e 100644 --- a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) - set(NET_APP hci_rpmsg) + set(NET_APP hci_ipc) set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) ExternalZephyrProject_Add( From 2eb804a5581df2ad1f563b3ac08f5c4145826374 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 31 Oct 2023 15:00:13 +0200 Subject: [PATCH 2907/4498] net: lwm2m: Add shell support for deleting object and resource instances Extend the previous support of creating object instances by allowing creation of resource instances as well. Similarly, add support for deleting. Signed-off-by: Seppo Takalo --- doc/connectivity/networking/api/lwm2m.rst | 5 ++- subsys/net/lib/lwm2m/lwm2m_shell.c | 47 ++++++++++++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 83ed71523e7..b8c4756b5d6 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -717,7 +717,10 @@ required actions from the server side. -t Write value as time_t create :create PATH - Create object instance + Create object or resource instance + + delete :delete PATH + Delete object or resource instance cache :cache PATH NUM Enable data cache for resource diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index 335004ec5d5..26526611efa 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -39,7 +39,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "-sX\tWrite value as intX_t\n" \ "-f \tWrite value as float\n" \ "-t \tWrite value as time_t\n" -#define LWM2M_HELP_CREATE "create PATH\nCreate object instance\n" +#define LWM2M_HELP_CREATE "create PATH\nCreate object or resource instance\n" +#define LWM2M_HELP_DELETE "delete PATH\nDelete object or resource instance\n" #define LWM2M_HELP_START "start EP_NAME [BOOTSTRAP FLAG]\n" \ "Start the LwM2M RD (Registration / Discovery) Client\n" \ "-b \tSet the bootstrap flag (default 0)\n" @@ -371,10 +372,9 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) return 0; } -static int cmd_create(const struct shell *sh, size_t argc, char **argv) +static int cmd_create_or_delete(const struct shell *sh, bool delete, size_t argc, char **argv) { struct lwm2m_obj_path path; - struct lwm2m_engine_obj_inst *obj_inst; int ret; if (argc < 2) { @@ -389,22 +389,48 @@ static int cmd_create(const struct shell *sh, size_t argc, char **argv) return -ENOEXEC; } - if (path.level != LWM2M_PATH_LEVEL_OBJECT_INST) { - shell_error(sh, "path is not an object instance\n"); - shell_help(sh); - return -EINVAL; + if (delete) { + switch (path.level) { + case LWM2M_PATH_LEVEL_RESOURCE_INST: + ret = lwm2m_delete_res_inst(&path); + break; + case LWM2M_PATH_LEVEL_OBJECT_INST: + ret = lwm2m_delete_object_inst(&path); + break; + default: + return -ENOEXEC; + } + } else { + switch (path.level) { + case LWM2M_PATH_LEVEL_RESOURCE_INST: + ret = lwm2m_create_res_inst(&path); + break; + case LWM2M_PATH_LEVEL_OBJECT_INST: + ret = lwm2m_create_object_inst(&path); + break; + default: + return -ENOEXEC; + } } - ret = lwm2m_create_obj_inst(path.obj_id, path.obj_inst_id, &obj_inst); if (ret < 0) { - shell_error(sh, "Failed to create object instance %d/%d, ret=%d", path.obj_id, - path.obj_inst_id, ret); + shell_error(sh, "operation failed, %d\n", ret); return -ENOEXEC; } return 0; } +static int cmd_create(const struct shell *sh, size_t argc, char **argv) +{ + return cmd_create_or_delete(sh, false, argc, argv); +} + +static int cmd_delete(const struct shell *sh, size_t argc, char **argv) +{ + return cmd_create_or_delete(sh, true, argc, argv); +} + static int cmd_start(const struct shell *sh, size_t argc, char **argv) { struct lwm2m_ctx *ctx = lwm2m_rd_client_ctx(); @@ -595,6 +621,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(read, NULL, LWM2M_HELP_READ, cmd_read, 2, 1), SHELL_CMD_ARG(write, NULL, LWM2M_HELP_WRITE, cmd_write, 3, 1), SHELL_CMD_ARG(create, NULL, LWM2M_HELP_CREATE, cmd_create, 2, 0), + SHELL_CMD_ARG(delete, NULL, LWM2M_HELP_DELETE, cmd_delete, 2, 0), SHELL_CMD_ARG(cache, NULL, LWM2M_HELP_CACHE, cmd_cache, 3, 0), SHELL_CMD_ARG(start, NULL, LWM2M_HELP_START, cmd_start, 2, 2), SHELL_CMD_ARG(stop, NULL, LWM2M_HELP_STOP, cmd_stop, 1, 1), From b6ab302fe87c2a0836886242391c8dc7c940768a Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 31 Oct 2023 15:05:30 +0200 Subject: [PATCH 2908/4498] net: lwm2m: Fix overlapping buffers from Portfolio object Portfolio object created string buffers for Identity resources that was overlapping on some cases. Don't calculate pointers by hand, allow compiler to calculate it. Fixes #64634 Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_obj_portfolio.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_portfolio.c b/subsys/net/lib/lwm2m/lwm2m_obj_portfolio.c index c06132c2514..e5cdc2198e6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_portfolio.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_portfolio.c @@ -59,17 +59,14 @@ static struct lwm2m_engine_obj_field fields[] = { static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][PORTFOLIO_MAX_ID]; static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT]; -static char identity[MAX_INSTANCE_COUNT*PORTFOLIO_IDENTITY_MAX][DEFAULT_IDENTITY_BUFFER_LENGTH]; +static char identity[MAX_INSTANCE_COUNT][PORTFOLIO_IDENTITY_MAX][DEFAULT_IDENTITY_BUFFER_LENGTH]; static struct lwm2m_engine_obj_inst *portfolio_create(uint16_t obj_inst_id) { - int index, avail = -1, i = 0, j = 0, indentity_buffer_start = 0; + int index, avail = -1, i = 0, j = 0; /* Check that there is no other instance with this ID */ for (index = 0; index < ARRAY_SIZE(inst); index++) { - if (index) { - indentity_buffer_start += PORTFOLIO_IDENTITY_MAX; - } if (inst[index].obj && inst[index].obj_inst_id == obj_inst_id) { LOG_ERR("Can not create instance - " "already existing: %u", @@ -95,7 +92,7 @@ static struct lwm2m_engine_obj_inst *portfolio_create(uint16_t obj_inst_id) /* initialize instance resource data */ INIT_OBJ_RES_MULTI_DATA_LEN(PORTFOLIO_IDENTITY_ID, res[avail], i, res_inst[avail], j, - PORTFOLIO_IDENTITY_MAX, false, identity[indentity_buffer_start], + PORTFOLIO_IDENTITY_MAX, false, identity[avail], DEFAULT_IDENTITY_BUFFER_LENGTH, 0); INIT_OBJ_RES_EXECUTE(PORTFOLIO_GET_AUTH_DATA_ID, res[avail], i, NULL); INIT_OBJ_RES_MULTI_OPTDATA(PORTFOLIO_AUTH_DATA_ID, res[avail], i, res_inst[avail], j, From c73e67018d0a0e27594f7c76bc8b865965d0feef Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 1 Nov 2023 23:27:52 +0000 Subject: [PATCH 2909/4498] power_domain_intel_adsp.c: revert recent INIT_PRIORITY change This is a partial revert of one-line from commit 06cfbd4159fd ("drivers: power_domain: Introduce a gpio monitor driver") which not just introduced a new driver (no problem with that) but also changed the initialization priority of another, unrelated and existing power domain driver without even trying to compile it: https://github.com/zephyrproject-rtos/zephyr/pull/61166#issuecomment-1780959157 ``` west config manifest.project-filter -- +sof west update west build -b intel_adsp_ace20_lnl modules/audio/sof/app/ ERROR: /soc/ssp@28100 POST_KERNEL 43 < /soc/dfpmccu@71b00/io0_domain 51 ERROR: /soc/ssp@29100 POST_KERNEL 44 < /soc/dfpmccu@71b00/io0_domain 51 ERROR: /soc/ssp@2a100 POST_KERNEL 45 < /soc/dfpmccu@71b00/io0_domain 51 ERROR: /soc/ssp@2b100 POST_KERNEL 46 < /soc/dfpmccu@71b00/io0_domain 51 ERROR: /soc/ssp@2c100 POST_KERNEL 47 < /soc/dfpmccu@71b00/io0_domain 51 ERROR: /soc/ssp@2d100 POST_KERNEL 48 < /soc/dfpmccu@71b00/io0_domain 51 ``` Also note a reviewer (@ceolin) expressed concerns about this unrelated change but it was ignored: https://github.com/zephyrproject-rtos/zephyr/pull/61166#discussion_r1357908984 Using `CONFIG_KERNEL_INIT_PRIORITY_DEFAULT` here may be "bad" for some reason(s) and maybe it should be changed in the future, but it's nothing compared to breaking _compilation_ of code that has been validated for months and been released in production (https://github.com/thesofproject/sof-bin/releases/tag/v2023.09) So the very urgent thing is to very quickly revert to the previous state to unblock development. Then we can discuss what is the better thing to do here. Signed-off-by: Marc Herbert --- drivers/power_domain/power_domain_intel_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power_domain/power_domain_intel_adsp.c b/drivers/power_domain/power_domain_intel_adsp.c index 2fdd0ecf62e..47828d6c744 100644 --- a/drivers/power_domain/power_domain_intel_adsp.c +++ b/drivers/power_domain/power_domain_intel_adsp.c @@ -84,6 +84,6 @@ static int pd_intel_adsp_init(const struct device *dev) PM_DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_pm_action); \ DEVICE_DT_INST_DEFINE(id, pd_intel_adsp_init, PM_DEVICE_DT_INST_GET(id), \ &pd_pg_reg##id, NULL, POST_KERNEL, \ - CONFIG_POWER_DOMAIN_INIT_PRIORITY, NULL); + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); DT_INST_FOREACH_STATUS_OKAY(POWER_DOMAIN_DEVICE) From ed8f0bc985ad1422265ae15fddc45c180b8eacbd Mon Sep 17 00:00:00 2001 From: Jeff Welder Date: Tue, 10 Oct 2023 09:17:04 -0400 Subject: [PATCH 2910/4498] drivers: modem: Individualize Modem Device Macros Refactor device macro to be custom for each modem to allow custom configurations. Signed-off-by: Jeff Welder --- drivers/modem/modem_cellular.c | 168 +++++++++++++++++++++++++++------ 1 file changed, 138 insertions(+), 30 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index e47b04d0761..bc6e7340bca 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1460,49 +1460,157 @@ MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_scr #define MODEM_CELLULAR_INST_NAME(name, inst) \ _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) -#define MODEM_CELLULAR_DEVICE(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ - \ - static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ - .chat_delimiter = {'\r'}, \ - .chat_filter = {'\n'}, \ - .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ - }; \ - \ - static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ - .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ - .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ - .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ - .power_pulse_duration_ms = 1500, \ - .reset_pulse_duration_ms = 100, \ - .startup_time_ms = 10000, \ - .shutdown_time_ms = 5000, \ - .init_chat_script = &_CONCAT(DT_DRV_COMPAT, _init_chat_script), \ - .dial_chat_script = &_CONCAT(DT_DRV_COMPAT, _dial_chat_script), \ - }; \ - \ - PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ - \ - DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ - &MODEM_CELLULAR_INST_NAME(data, inst), \ +#define MODEM_CELLULAR_DEVICE_QUECTEL_BG95(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 10000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &quectel_bg95_init_chat_script, \ + .dial_chat_script = &quectel_bg95_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + +#define MODEM_CELLULAR_DEVICE_GSM_PPP(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 10000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &zephyr_gsm_ppp_init_chat_script, \ + .dial_chat_script = &zephyr_gsm_ppp_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + +#define MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 10000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &simcom_sim7080_init_chat_script, \ + .dial_chat_script = &simcom_sim7080_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + +#define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 10000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &u_blox_sara_r4_init_chat_script, \ + .dial_chat_script = &u_blox_sara_r4_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + +#define MODEM_CELLULAR_DEVICE_SWIR_HL7800(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 10000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &swir_hl7800_init_chat_script, \ + .dial_chat_script = &swir_hl7800_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); #define DT_DRV_COMPAT quectel_bg95 -DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT zephyr_gsm_ppp -DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_GSM_PPP) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT simcom_sim7080 -DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT u_blox_sara_r4 -DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT swir_hl7800 -DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800) #undef DT_DRV_COMPAT From 018cd27ac6203acbf8f01175457cad58c5c0e91f Mon Sep 17 00:00:00 2001 From: Jeff Welder Date: Tue, 10 Oct 2023 09:23:58 -0400 Subject: [PATCH 2911/4498] dts: bindings: Add Telit ME910G1 Modem Add Telit to vendor-prefixes, and add ME910G1 bindings Signed-off-by: Jeff Welder --- dts/bindings/modem/telit,me910g1.yaml | 23 +++++++++++++++++++++++ dts/bindings/vendor-prefixes.txt | 1 + 2 files changed, 24 insertions(+) create mode 100644 dts/bindings/modem/telit,me910g1.yaml diff --git a/dts/bindings/modem/telit,me910g1.yaml b/dts/bindings/modem/telit,me910g1.yaml new file mode 100644 index 00000000000..2599b6cd237 --- /dev/null +++ b/dts/bindings/modem/telit,me910g1.yaml @@ -0,0 +1,23 @@ +# Copyright(c) 2023 Jeff Welder (Ellenby Technologies, Inc.) +# SPDX-License-Identifier: Apache-2.0 + +description: Telit ME910G1 Modem + +compatible: "telit,me910g1" + +include: uart-device.yaml + +properties: + mdm-power-gpios: + type: phandle-array + required: true + + mdm-reset-gpios: + type: phandle-array + required: true + + mdm-dtr-gpios: + type: phandle-array + + mdm-ri-gpios: + type: phandle-array diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index aa514077e4d..e426bef99bd 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -608,6 +608,7 @@ tdo Shangai Top Display Optoelectronics Co., Ltd technexion TechNexion technologic Technologic Systems telink Telink Semiconductor +telit Telit Cinterion tempo Tempo Semiconductor techstar Shenzhen Techstar Electronics Co., Ltd. terasic Terasic Inc. From 372216a3ea42662dbb722dc2ef80a5070688529a Mon Sep 17 00:00:00 2001 From: Jeff Welder Date: Tue, 10 Oct 2023 09:32:09 -0400 Subject: [PATCH 2912/4498] drivers: modem: modem_cellular: add Telit ME910G1 Added chat script and initial config to support Telit ME910G1. Needed to edit power_pulse pin timing in accordance to datasheet. Signed-off-by: Jeff Welder --- drivers/modem/Kconfig.cellular | 2 +- drivers/modem/modem_cellular.c | 73 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index 6869f047dad..a729e00ff71 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -13,7 +13,7 @@ config MODEM_CELLULAR select NET_L2_PPP_OPTION_MRU depends on (DT_HAS_QUECTEL_BG95_ENABLED || DT_HAS_ZEPHYR_GSM_PPP_ENABLED || \ DT_HAS_SIMCOM_SIM7080_ENABLED || DT_HAS_U_BLOX_SARA_R4_ENABLED || \ - DT_HAS_SWIR_HL7800_ENABLED) + DT_HAS_SWIR_HL7800_ENABLED || DT_HAS_TELIT_ME910G1_ENABLED) help This driver uses the generic 3gpp AT commands, along with the standard protocols CMUX and PPP, to configure diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index bc6e7340bca..b4702889472 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1457,6 +1457,48 @@ MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_scr dial_abort_matches, modem_cellular_chat_callback_handler, 10); #endif +#if DT_HAS_COMPAT_STATUS_OKAY(telit_me910g1) +MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_init_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), + MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match), + /* The Telit me910g1 often has an error trying + * to set the PDP context. The radio must be on to set + * the context, and this step must be successful. + * It is moved to the init script to allow retries. + */ + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\"," + "\"" CONFIG_MODEM_CELLULAR_APN "\"", + ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", + 300)); + +MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_init_chat_script, telit_me910g1_init_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_dial_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),); + +MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat_script_cmds, + dial_abort_matches, modem_cellular_chat_callback_handler, 10); +#endif + #define MODEM_CELLULAR_INST_NAME(name, inst) \ _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) @@ -1595,6 +1637,33 @@ MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_scr &MODEM_CELLULAR_INST_NAME(data, inst), \ &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); +#define MODEM_CELLULAR_DEVICE_TELIT_ME910G1(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 5050, \ + .reset_pulse_duration_ms = 250, \ + .startup_time_ms = 15000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &telit_me910g1_init_chat_script, \ + .dial_chat_script = &telit_me910g1_dial_chat_script, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + #define DT_DRV_COMPAT quectel_bg95 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95) #undef DT_DRV_COMPAT @@ -1614,3 +1683,7 @@ DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4) #define DT_DRV_COMPAT swir_hl7800 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800) #undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT telit_me910g1 +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME910G1) +#undef DT_DRV_COMPAT From 9c51a26844e08f64bb779e511ee69fe7ea806490 Mon Sep 17 00:00:00 2001 From: Jeff Welder Date: Tue, 10 Oct 2023 09:45:41 -0400 Subject: [PATCH 2913/4498] tests: build_all: modem: Add Telit ME910G1 Test Coverage Added bindings to build_all test for new Telit ME910G1 Modem. Signed-off-by: Jeff Welder --- tests/drivers/build_all/modem/uart.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/drivers/build_all/modem/uart.dtsi b/tests/drivers/build_all/modem/uart.dtsi index 1600b6e165b..985f60dba69 100644 --- a/tests/drivers/build_all/modem/uart.dtsi +++ b/tests/drivers/build_all/modem/uart.dtsi @@ -51,6 +51,16 @@ test_gsm_ppp: gsm_ppp { compatible = "zephyr,gsm-ppp"; }; +test_telit_me910g1: telit_me910g1 { + compatible = "telit,me910g1"; + + mdm-power-gpios = <&test_gpio 0 0>; + mdm-reset-gpios = <&test_gpio 0 0>; + + mdm-dtr-gpios = <&test_gpio 0 0>; + mdm-ri-gpios = <&test_gpio 0 0>; +}; + test_esp_at: esp_at { compatible = "espressif,esp-at"; }; From e5d47e91a4205474012b1e6e3b2a6cbbe1d793ca Mon Sep 17 00:00:00 2001 From: Ning Yang Date: Tue, 12 Sep 2023 16:32:07 +0800 Subject: [PATCH 2914/4498] drivers: dma: add init version for dma sedi driver Add dma sedi driver support Signed-off-by: Ning Yang --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 2 + drivers/dma/Kconfig.sedi | 14 + drivers/dma/dma_sedi.c | 444 +++++++++++++++++++++++++++ dts/bindings/dma/intel,sedi_dma.yaml | 21 ++ dts/x86/intel/intel_ish5.dtsi | 13 + 6 files changed, 495 insertions(+) create mode 100644 drivers/dma/Kconfig.sedi create mode 100644 drivers/dma/dma_sedi.c create mode 100644 dts/bindings/dma/intel,sedi_dma.yaml diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 98e5642c904..da2d43fc2c0 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -35,3 +35,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) +zephyr_library_sources_ifdef(CONFIG_DMA_SEDI dma_sedi.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 71059a0e27f..0136eaa92a2 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -66,4 +66,6 @@ source "drivers/dma/Kconfig.mcux_smartdma" source "drivers/dma/Kconfig.andes_atcdmac300" +source "drivers/dma/Kconfig.sedi" + endif # DMA diff --git a/drivers/dma/Kconfig.sedi b/drivers/dma/Kconfig.sedi new file mode 100644 index 00000000000..9f07bff903a --- /dev/null +++ b/drivers/dma/Kconfig.sedi @@ -0,0 +1,14 @@ +# Intel sedi DMA configuration options + +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config DMA_SEDI + bool "SEDI DMA driver" + select DMA_64BIT + default y + depends on DT_HAS_INTEL_SEDI_DMA_ENABLED + help + This option enables the Intel SEDI DMA driver. + This driver is simply a shim driver built upon the SEDI + bare metal DMA driver in the hal-intel module diff --git a/drivers/dma/dma_sedi.c b/drivers/dma/dma_sedi.c new file mode 100644 index 00000000000..629ca8f0e20 --- /dev/null +++ b/drivers/dma/dma_sedi.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_sedi_dma + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sedi_driver_dma.h" +#include "sedi_driver_core.h" + +#include +LOG_MODULE_REGISTER(sedi_dma, CONFIG_DMA_LOG_LEVEL); + +extern void dma_isr(sedi_dma_t dma_device); + +struct dma_sedi_config_info { + sedi_dma_t peripheral_id; /* Controller instance. */ + uint8_t chn_num; + void (*irq_config)(void); +}; + +struct dma_sedi_driver_data { + struct dma_config dma_configs[DMA_CHANNEL_NUM]; +}; + +#define DEV_DATA(dev) ((struct dma_sedi_driver_data *const)(dev)->data) +#define DEV_CFG(dev) \ + ((const struct dma_sedi_config_info *const)(dev)->config) + +/* + * this function will be called when dma transferring is completed + * or error happened + */ +static void dma_handler(sedi_dma_t dma_device, int channel, int event_id, + void *args) +{ + ARG_UNUSED(args); + const struct device *dev = (const struct device *)args; + struct dma_sedi_driver_data *const data = DEV_DATA(dev); + struct dma_config *config = &(data->dma_configs[channel]); + + /* run user-defined callback */ + if (config->dma_callback) { + if ((event_id == SEDI_DMA_EVENT_TRANSFER_DONE) && + (config->complete_callback_en)) { + config->dma_callback(dev, config->user_data, + channel, 0); + } else if (config->error_callback_en) { + config->dma_callback(dev, config->user_data, + channel, event_id); + } + } +} + +/* map width to certain macros*/ +static int width_index(uint32_t num_bytes, uint32_t *index) +{ + switch (num_bytes) { + case 1: + *index = DMA_TRANS_WIDTH_8; + break; + case 2: + *index = DMA_TRANS_WIDTH_16; + break; + case 4: + *index = DMA_TRANS_WIDTH_32; + break; + case 8: + *index = DMA_TRANS_WIDTH_64; + break; + case 16: + *index = DMA_TRANS_WIDTH_128; + break; + case 32: + *index = DMA_TRANS_WIDTH_256; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +/* map burst size to certain macros*/ +static int burst_index(uint32_t num_units, uint32_t *index) +{ + switch (num_units) { + case 1: + *index = DMA_BURST_TRANS_LENGTH_1; + break; + case 4: + *index = DMA_BURST_TRANS_LENGTH_4; + break; + case 8: + *index = DMA_BURST_TRANS_LENGTH_8; + break; + case 16: + *index = DMA_BURST_TRANS_LENGTH_16; + break; + case 32: + *index = DMA_BURST_TRANS_LENGTH_32; + break; + case 64: + *index = DMA_BURST_TRANS_LENGTH_64; + break; + case 128: + *index = DMA_BURST_TRANS_LENGTH_128; + break; + case 256: + *index = DMA_BURST_TRANS_LENGTH_256; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static void dma_config_convert(struct dma_config *config, + dma_memory_type_t *src_mem, + dma_memory_type_t *dst_mem, + uint8_t *sedi_dma_dir) +{ + + *src_mem = DMA_SRAM_MEM; + *dst_mem = DMA_SRAM_MEM; + *sedi_dma_dir = MEMORY_TO_MEMORY; + switch (config->channel_direction) { + case MEMORY_TO_MEMORY: + case MEMORY_TO_PERIPHERAL: + case PERIPHERAL_TO_MEMORY: + case PERIPHERAL_TO_PERIPHERAL: + *sedi_dma_dir = config->channel_direction; + break; + case MEMORY_TO_HOST: + *dst_mem = DMA_DRAM_MEM; + break; + case HOST_TO_MEMORY: + *src_mem = DMA_DRAM_MEM; + break; +#ifdef MEMORY_TO_IMR + case MEMORY_TO_IMR: + *dst_mem = DMA_UMA_MEM; + break; +#endif +#ifdef IMR_TO_MEMORY + case IMR_TO_MEMORY: + *src_mem = DMA_UMA_MEM; + break; +#endif + } +} + +/* config basic dma */ +static int dma_sedi_apply_common_config(sedi_dma_t dev, uint32_t channel, + struct dma_config *config, uint8_t *dir) +{ + uint8_t direction = MEMORY_TO_MEMORY; + dma_memory_type_t src_mem = DMA_SRAM_MEM, dst_mem = DMA_SRAM_MEM; + + dma_config_convert(config, &src_mem, &dst_mem, &direction); + + if (dir) { + *dir = direction; + } + + /* configure dma transferring direction*/ + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_DIRECTION, + direction); + + if (direction == MEMORY_TO_MEMORY) { + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_SR_MEM_TYPE, + src_mem); + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_DT_MEM_TYPE, + dst_mem); + } else if (direction == MEMORY_TO_PERIPHERAL) { + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_HS_DEVICE_ID, + config->dma_slot); + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_HS_POLARITY, + DMA_HS_POLARITY_HIGH); + sedi_dma_control(dev, channel, + SEDI_CONFIG_DMA_HS_DEVICE_ID_PER_DIR, + DMA_HS_PER_TX); + } else if (direction == PERIPHERAL_TO_MEMORY) { + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_HS_DEVICE_ID, + config->dma_slot); + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_HS_POLARITY, + DMA_HS_POLARITY_HIGH); + sedi_dma_control(dev, channel, + SEDI_CONFIG_DMA_HS_DEVICE_ID_PER_DIR, + DMA_HS_PER_RX); + } else { + return -1; + } + return 0; +} + +static int dma_sedi_apply_single_config(sedi_dma_t dev, uint32_t channel, + struct dma_config *config) +{ + int ret = 0; + uint32_t temp = 0; + + ret = dma_sedi_apply_common_config(dev, channel, config, NULL); + if (ret != 0) { + goto INVALID_ARGS; + } + /* configurate dma width of source data*/ + ret = width_index(config->source_data_size, &temp); + if (ret != 0) { + goto INVALID_ARGS; + } + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_SR_TRANS_WIDTH, temp); + + /* configurate dma width of destination data*/ + ret = width_index(config->dest_data_size, &temp); + if (ret != 0) { + goto INVALID_ARGS; + } + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_DT_TRANS_WIDTH, temp); + + /* configurate dma burst size*/ + ret = burst_index(config->source_burst_length, &temp); + if (ret != 0) { + goto INVALID_ARGS; + } + sedi_dma_control(dev, channel, SEDI_CONFIG_DMA_BURST_LENGTH, temp); + return 0; + +INVALID_ARGS: + return ret; +} + +static int dma_sedi_chan_config(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + if ((dev == NULL) || (channel >= DEV_CFG(dev)->chn_num) + || (config == NULL) + || (config->block_count != 1)) { + goto INVALID_ARGS; + } + + const struct dma_sedi_config_info *const info = DEV_CFG(dev); + struct dma_sedi_driver_data *const data = DEV_DATA(dev); + struct dma_config *local_config = &(data->dma_configs[channel]); + + local_config->head_block = config->head_block; + + /* initialize the dma controller, following the sedi api*/ + sedi_dma_event_cb_t cb = dma_handler; + + sedi_dma_init(info->peripheral_id, (int)channel, cb, (void *)dev); + + return 0; + +INVALID_ARGS: + return -1; +} + +static int dma_sedi_reload(const struct device *dev, uint32_t channel, + uint64_t src, uint64_t dst, size_t size) +{ + if ((dev == NULL) || (channel >= DEV_CFG(dev)->chn_num)) { + LOG_ERR("dma reload failed for invalid args"); + return -ENOTSUP; + } + + int ret = 0; + struct dma_sedi_driver_data *const data = DEV_DATA(dev); + struct dma_config *config = &(data->dma_configs[channel]); + struct dma_block_config *block_config; + + if ((config == NULL) || (config->head_block == NULL)) { + LOG_ERR("dma reload failed, no config found"); + return -ENOTSUP; + } + block_config = config->head_block; + + if ((config->block_count == 1) || (block_config->next_block == NULL)) { + block_config->source_address = src; + block_config->dest_address = dst; + block_config->block_size = size; + } else { + LOG_ERR("no reload support for multi-linkedlist mode"); + return -ENOTSUP; + } + return ret; +} + +static int dma_sedi_start(const struct device *dev, uint32_t channel) +{ + if ((dev == NULL) || (channel >= DEV_CFG(dev)->chn_num)) { + LOG_ERR("dma transferring failed for invalid args"); + return -ENOTSUP; + } + + int ret = -1; + const struct dma_sedi_config_info *const info = DEV_CFG(dev); + struct dma_sedi_driver_data *const data = DEV_DATA(dev); + struct dma_config *config = &(data->dma_configs[channel]); + struct dma_block_config *block_config = config->head_block; + uint64_t src_addr, dst_addr; + + if (config->block_count == 1) { + /* call sedi start function */ + ret = dma_sedi_apply_single_config(info->peripheral_id, + channel, config); + if (ret) { + goto ERR; + } + src_addr = block_config->source_address; + dst_addr = block_config->dest_address; + + ret = sedi_dma_start_transfer(info->peripheral_id, channel, + src_addr, dst_addr, block_config->block_size); + } else { + LOG_ERR("MULTIPLE_BLOCK CONFIG is not set"); + goto ERR; + } + + if (ret != SEDI_DRIVER_OK) { + goto ERR; + } + + return ret; + +ERR: + LOG_ERR("dma transfer failed"); + return ret; +} + +static int dma_sedi_stop(const struct device *dev, uint32_t channel) +{ + const struct dma_sedi_config_info *const info = DEV_CFG(dev); + + LOG_DBG("stopping dma: %p, %d", dev, channel); + sedi_dma_abort_transfer(info->peripheral_id, channel); + + return 0; +} + +static const struct dma_driver_api dma_funcs = { .config = dma_sedi_chan_config, + .start = dma_sedi_start, + .stop = dma_sedi_stop, + .reload = dma_sedi_reload, + .get_status = NULL +}; + +static int dma_sedi_init(const struct device *dev) +{ + const struct dma_sedi_config_info *const config = DEV_CFG(dev); + + config->irq_config(); + + return 0; +} + +#ifdef CONFIG_PM_DEVICE + +static bool is_dma_busy(sedi_dma_t dev) +{ + sedi_dma_status_t chn_status; + + for (int chn = 0; chn < DMA_CHANNEL_NUM; chn++) { + sedi_dma_get_status(dev, chn, &chn_status); + if (chn_status.busy == 1) { + return true; + } + } + return false; +} + +static int dma_change_device_power(const struct device *dev, + enum pm_device_action action) +{ + struct dma_sedi_driver_data *const data = DEV_DATA(dev); + const struct dma_sedi_config_info *const info = DEV_CFG(dev); + sedi_dma_t dma_dev = info->peripheral_id; + int ret; + + sedi_power_state_t state; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + state = SEDI_POWER_FULL; + break; + case PM_DEVICE_ACTION_SUSPEND: + if (is_dma_busy(dma_dev)) { + return -EBUSY; + } + state = SEDI_POWER_SUSPEND; + break; + + default: + return -ENOTSUP; + } + + for (uint8_t chn = 0; chn < DMA_CHANNEL_NUM; chn++) { + ret = sedi_dma_set_power(dma_dev, chn, state); + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + } + + return 0; +} + +#endif + +#define DMA_DEVICE_INIT_SEDI(inst) \ + static void dma_sedi_##inst##_irq_config(void); \ + \ + static struct dma_sedi_driver_data dma_sedi_dev_data_##inst; \ + static const struct dma_sedi_config_info dma_sedi_config_data_##inst = { \ + .peripheral_id = DT_INST_PROP(inst, peripheral_id), \ + .chn_num = DT_INST_PROP(inst, dma_channels), \ + .irq_config = dma_sedi_##inst##_irq_config \ + }; \ + DEVICE_DT_DEFINE(DT_INST(inst, DT_DRV_COMPAT), &dma_sedi_init, \ + NULL, &dma_sedi_dev_data_##inst, &dma_sedi_config_data_##inst, PRE_KERNEL_2, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, (void *)&dma_funcs); \ + \ + static void dma_sedi_##inst##_irq_config(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), \ + DT_INST_IRQ(inst, priority), dma_isr, \ + (void *)DT_INST_PROP(inst, peripheral_id), \ + DT_INST_IRQ(inst, sense)); \ + irq_enable(DT_INST_IRQN(inst)); \ + } + +DT_INST_FOREACH_STATUS_OKAY(DMA_DEVICE_INIT_SEDI) diff --git a/dts/bindings/dma/intel,sedi_dma.yaml b/dts/bindings/dma/intel,sedi_dma.yaml new file mode 100644 index 00000000000..3fe1036c00c --- /dev/null +++ b/dts/bindings/dma/intel,sedi_dma.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: Intel SEDI DMA controller. + +compatible: "intel,sedi_dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + peripheral-id: + type: int + description: Peripheral Instance ID + required: true diff --git a/dts/x86/intel/intel_ish5.dtsi b/dts/x86/intel/intel_ish5.dtsi index 8215748511d..5f2ef6a1960 100644 --- a/dts/x86/intel/intel_ish5.dtsi +++ b/dts/x86/intel/intel_ish5.dtsi @@ -187,5 +187,18 @@ status = "disabled"; }; + + dma0: dma@10100000 { + compatible = "intel,sedi_dma"; + #dma-cells = <2>; + dma-channels = <8>; + peripheral-id = <0>; + reg = <0x10100000 0x1000>; + interrupts = <11 IRQ_TYPE_LOWEST_LEVEL_HIGH 2>; + interrupt-parent = <&intc>; + dma-buf-size-alignment = <4>; + dma-copy-alignment = <4>; + status = "okay"; + }; }; }; From ee2e8485e82f7537bdc15a753473cc80c8304717 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Thu, 12 Oct 2023 16:03:36 +0200 Subject: [PATCH 2915/4498] boards: lpcxpresso55s69: Fix partitions Fix MCUBoot error for LPC55S69 "slots are not compatible". Use the standard slot naming, used by TFM-enabled Zephyr platforms. Signed-off-by: Andrej Butok --- boards/arm/lpcxpresso55s69/doc/index.rst | 30 +++++++++---------- .../arm/lpcxpresso55s69/lpcxpresso55s69.dtsi | 25 ++++++++-------- .../lpcxpresso55s69/lpcxpresso55s69_cpu0.dts | 2 +- .../lpcxpresso55s69/lpcxpresso55s69_cpu1.dts | 2 +- .../lpcxpresso55s69/lpcxpresso55s69_ns.dts | 2 +- 5 files changed, 30 insertions(+), 31 deletions(-) diff --git a/boards/arm/lpcxpresso55s69/doc/index.rst b/boards/arm/lpcxpresso55s69/doc/index.rst index 9ae2c85f78e..408cd18aa91 100644 --- a/boards/arm/lpcxpresso55s69/doc/index.rst +++ b/boards/arm/lpcxpresso55s69/doc/index.rst @@ -191,21 +191,21 @@ Memory mappings There are multiple memory configurations, they all start from the MCUboot partitioning which looks like the table below -+---------+------------------+---------------------------------+ -| Name | Address[Size] | Comment | -+=========+==================+=================================+ -| boot | 0x00000000[32K] | Bootloader | -+---------+------------------+---------------------------------+ -| slot0 | 0x00008000[160k] | Image that runs after boot | -+---------+------------------+---------------------------------+ -| slot1 | 0x00030000[96k] | Second image, core 1 or NS | -+---------+------------------+---------------------------------+ -| slot2 | 0x00048000[160k] | Updates slot0 image | -+---------+------------------+---------------------------------+ -| slot3 | 0x00070000[96k] | Updates slot1 image | -+---------+------------------+---------------------------------+ -| storage | 0x00088000[50k] | File system, persistent storage | -+---------+------------------+---------------------------------+ ++----------+------------------+---------------------------------+ +| Name | Address[Size] | Comment | ++==========+==================+=================================+ +| boot | 0x00000000[32K] | Bootloader | ++----------+------------------+---------------------------------+ +| slot0 | 0x00008000[160k] | Image that runs after boot | ++----------+------------------+---------------------------------+ +| slot0_ns | 0x00030000[96k] | Second image, core 1 or NS | ++----------+------------------+---------------------------------+ +| slot1 | 0x00048000[160k] | Updates slot0 image | ++----------+------------------+---------------------------------+ +| slot1_ns | 0x00070000[96k] | Updates slot0_ns image | ++----------+------------------+---------------------------------+ +| storage | 0x00088000[50k] | File system, persistent storage | ++----------+------------------+---------------------------------+ See below examples of how this partitioning is used diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi b/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi index 11b3263c3aa..e3d5b08fa19 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi @@ -117,28 +117,27 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - /* Please enable mcuboot's swap move, no scratch */ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x00008000>; + reg = <0x00000000 DT_SIZE_K(32)>; read-only; }; slot0_partition: partition@8000 { label = "image-0"; - reg = <0x00008000 0x00028000>; + reg = <0x00008000 DT_SIZE_K(160)>; }; - slot1_partition: partition@30000 { - label = "image-1"; - reg = <0x00030000 0x00018000>; + slot0_ns_partition: partition@30000 { + label = "image-0-nonsecure"; + reg = <0x00030000 DT_SIZE_K(96)>; }; - slot2_partition: partition@48000 { - label = "image-2"; - reg = <0x00048000 0x00028000>; + slot1_partition: partition@48000 { + label = "image-1"; + reg = <0x00048000 DT_SIZE_K(160)>; }; - slot3_partition: partition@70000 { - label = "image-3"; - reg = <0x00070000 0x00018000>; + slot1_ns_partition: partition@70000 { + label = "image-1-nonsecure"; + reg = <0x00070000 DT_SIZE_K(96)>; }; /* * The flash starting at 0x88000 and ending at @@ -146,7 +145,7 @@ */ storage_partition: partition@88000 { label = "storage"; - reg = <0x00088000 0x0000ca00>; + reg = <0x00088000 DT_SIZE_K(50)>; }; }; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts index 050d625013f..5b29efecadf 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts @@ -37,7 +37,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; - zephyr,code-cpu1-partition = &slot1_partition; + zephyr,code-cpu1-partition = &slot0_ns_partition; zephyr,sram-cpu1-partition = &sram3; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts index 1c3f11882a0..9ade525bc37 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts @@ -20,7 +20,7 @@ chosen { zephyr,sram = &sram3; zephyr,flash = &flash0; - zephyr,code-partition = &slot1_partition; + zephyr,code-partition = &slot0_ns_partition; zephyr,entropy = &rng; }; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts index 0491958f9e0..cc2e41e0815 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts @@ -29,7 +29,7 @@ chosen { zephyr,sram = &non_secure_ram; zephyr,flash = &flash0; - zephyr,code-partition = &slot1_partition; + zephyr,code-partition = &slot0_ns_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,entropy = &rng; From 54c62232fcd9f132a4aa1c7aac835f0256483494 Mon Sep 17 00:00:00 2001 From: Jaap Versteegh Date: Thu, 19 Oct 2023 17:48:21 +0200 Subject: [PATCH 2916/4498] drivers: pwm: pwm_pca9685 set_pre_scale when not in restart mode The pca9685 driver assumes the chip will be in "restart" mode after putting it to sleep. This is not necessarily the case, which can cause setting the prescaler to fail. This fix allows the precaler to always be set and only restart the pwm's when the chip was actually in restart mode after being put to sleep. Signed-off-by: Jaap Versteegh --- drivers/pwm/pwm_pca9685.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm_pca9685.c b/drivers/pwm/pwm_pca9685.c index 24596d7f377..f08bdd4cf9b 100644 --- a/drivers/pwm/pwm_pca9685.c +++ b/drivers/pwm/pwm_pca9685.c @@ -119,6 +119,7 @@ static int set_pre_scale(const struct device *dev, uint8_t value) struct pca9685_data *data = dev->data; uint8_t mode1; int ret; + uint8_t restart = RESTART; k_mutex_lock(&data->mutex, K_FOREVER); @@ -134,9 +135,7 @@ static int set_pre_scale(const struct device *dev, uint8_t value) } if ((mode1 & RESTART) == 0x00) { - LOG_ERR("RESTART bit should be set"); - ret = -EIO; - goto out; + restart = 0; } ret = set_reg(dev, ADDR_PRE_SCALE, value); @@ -152,7 +151,7 @@ static int set_pre_scale(const struct device *dev, uint8_t value) k_sleep(OSCILLATOR_STABILIZE); - ret = set_reg(dev, ADDR_MODE1, AUTO_INC | RESTART); + ret = set_reg(dev, ADDR_MODE1, AUTO_INC | restart); if (ret != 0) { goto out; } From a9b59dc65ee98979bec395c857dae2af2951bb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 23 Oct 2023 11:34:18 +0700 Subject: [PATCH 2917/4498] s32z270dc2_r52: add missing vendor and supported drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing vendor and supported drivers for the `s32z270dc2_r52` boards. Signed-off-by: Manuel Argüelles --- boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml | 4 +++- boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52_D.yaml | 3 +++ boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml | 4 +++- boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52_D.yaml | 5 ++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml index dbf4d3bd840..891f6b3cce5 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 identifier: s32z270dc2_rtu0_r52 @@ -14,4 +14,6 @@ supported: - watchdog - netif:eth - can + - spi + - counter vendor: nxp diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52_D.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52_D.yaml index db8c9e68854..063ea90c351 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52_D.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu0_r52_D.yaml @@ -14,3 +14,6 @@ supported: - watchdog - netif:eth - can + - spi + - counter +vendor: nxp diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml index 2a722ee4606..de48e46091a 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 identifier: s32z270dc2_rtu1_r52 @@ -14,4 +14,6 @@ supported: - watchdog - netif:eth - can + - spi + - counter vendor: nxp diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52_D.yaml b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52_D.yaml index aeb1eac2038..70a37261c8e 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52_D.yaml +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_rtu1_r52_D.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 identifier: s32z270dc2_rtu1_r52@D @@ -14,3 +14,6 @@ supported: - watchdog - netif:eth - can + - spi + - counter +vendor: nxp From 3e82eb976ea31724641333950bb70bfb4d2217cc Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 26 Oct 2023 22:25:40 +0200 Subject: [PATCH 2918/4498] soc: move arm cortex_m common mpu code to arch/arm/core/mpu Locate common mpu code together with other arm / nxp mpu code in the arch folder where it logically belongs. Signed-off-by: Torsten Rasmussen --- arch/arm/core/mpu/CMakeLists.txt | 5 +++++ .../arm/core/mpu}/arm_mpu_regions.c | 0 soc/arm/CMakeLists.txt | 3 --- soc/arm/common/cortex_m/CMakeLists.txt | 13 ------------- 4 files changed, 5 insertions(+), 16 deletions(-) rename {soc/arm/common/cortex_m => arch/arm/core/mpu}/arm_mpu_regions.c (100%) delete mode 100644 soc/arm/common/cortex_m/CMakeLists.txt diff --git a/arch/arm/core/mpu/CMakeLists.txt b/arch/arm/core/mpu/CMakeLists.txt index 8344f4db6df..1df6561ee52 100644 --- a/arch/arm/core/mpu/CMakeLists.txt +++ b/arch/arm/core/mpu/CMakeLists.txt @@ -6,6 +6,11 @@ zephyr_library_sources( arm_core_mpu.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU arm_mpu.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU nxp_mpu.c) +if(CONFIG_CPU_CORTEX_M AND NOT CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) + zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU arm_mpu_regions.c) + zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU nxp_mpu_regions.c) +endif() + if (CONFIG_CPU_AARCH32_CORTEX_R) zephyr_library_include_directories(cortex_a_r) elseif (CONFIG_CPU_CORTEX_M) diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c similarity index 100% rename from soc/arm/common/cortex_m/arm_mpu_regions.c rename to arch/arm/core/mpu/arm_mpu_regions.c diff --git a/soc/arm/CMakeLists.txt b/soc/arm/CMakeLists.txt index f854c3b7d1e..b826da926ca 100644 --- a/soc/arm/CMakeLists.txt +++ b/soc/arm/CMakeLists.txt @@ -1,10 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M common/cortex_m) - if(SOC_FAMILY) add_subdirectory(${SOC_FAMILY}) else() add_subdirectory(${SOC_NAME}) endif() - diff --git a/soc/arm/common/cortex_m/CMakeLists.txt b/soc/arm/common/cortex_m/CMakeLists.txt deleted file mode 100644 index f6016604726..00000000000 --- a/soc/arm/common/cortex_m/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_ARM_MPU AND NOT CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) - - zephyr_library() - - zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU - arm_mpu_regions.c - ) - zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU - nxp_mpu_regions.c - ) -endif() From 7cbdbaf14671a54c8adea381449007f69a987967 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 31 Oct 2023 14:45:02 -0500 Subject: [PATCH 2919/4498] samples: ipc: openamp: fix build for IMXRT11xx Fix build for IMXRT11xx SOCs. The ARM MPU header was missing for the CM4 board overlays, add the required header so the sample can build. Signed-off-by: Daniel DeGrasse --- .../subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay | 2 ++ .../subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay | 2 ++ 2 files changed, 4 insertions(+) diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay index 32d5003bb19..87159192cf2 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { /* Switch to lpuart2, since primary core uses lpuart1 */ chosen { diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay index 32d5003bb19..87159192cf2 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { /* Switch to lpuart2, since primary core uses lpuart1 */ chosen { From 3ed8c4d64b362df00372f44d15f44ee827ccd710 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 1 Nov 2023 13:46:43 +0800 Subject: [PATCH 2920/4498] kernel: mmu: fix compilation warnings when memory address and size are 0 When both the memory base address & its size are zero, the assertions test will be comparing an unsigned int against zero which result in compilation warning, and will be raised to error in Twister Fix them with more conditional compilations. Signed-off-by: Yong Cong Sin --- include/zephyr/sys/mem_manage.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/zephyr/sys/mem_manage.h b/include/zephyr/sys/mem_manage.h index fe6d54ba3fe..2e150110f7d 100644 --- a/include/zephyr/sys/mem_manage.h +++ b/include/zephyr/sys/mem_manage.h @@ -194,8 +194,12 @@ static inline uintptr_t z_mem_phys_addr(void *virt) #if CONFIG_KERNEL_VM_BASE != 0 (addr >= CONFIG_KERNEL_VM_BASE) && #endif +#if (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE) != 0 (addr < (CONFIG_KERNEL_VM_BASE + (CONFIG_KERNEL_VM_SIZE))), +#else + false, +#endif "address %p not in permanent mappings", virt); #else /* Should be identity-mapped */ @@ -203,8 +207,12 @@ static inline uintptr_t z_mem_phys_addr(void *virt) #if CONFIG_SRAM_BASE_ADDRESS != 0 (addr >= CONFIG_SRAM_BASE_ADDRESS) && #endif +#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 (addr < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL))), +#else + false, +#endif "physical address 0x%lx not in RAM", (unsigned long)addr); #endif /* CONFIG_MMU */ @@ -227,8 +235,12 @@ static inline void *z_mem_virt_addr(uintptr_t phys) #if CONFIG_SRAM_BASE_ADDRESS != 0 (phys >= CONFIG_SRAM_BASE_ADDRESS) && #endif +#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 (phys < (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL))), +#else + false, +#endif "physical address 0x%lx not in RAM", (unsigned long)phys); #endif From 125e0e87411e8f9771ece98350b132556ec53426 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 31 Oct 2023 11:47:17 +0000 Subject: [PATCH 2921/4498] docs: migration-guide-3.5: add a note about optional modules Add a note about modules moved to optional and how to enable them again. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.5.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 179e8cd9a80..d9b81c62106 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -79,6 +79,25 @@ C Library to a smaller, but inexact conversion algorithm. This requires building Picolibc as a module. +Optional Modules +================ + +The following modules have been made optional and are not downloaded with `west update` by default anymore: + +* ``chre`` +* ``lz4`` +* ``nanopb`` +* ``psa-arch-tests`` +* ``sof`` +* ``tf-m-tests`` +* ``tflite-micro`` +* ``thrift`` +* ``zscilib`` + +To enable them again use the ``west config manifest.project-filter -- +`` command, or ``west config manifest.group-filter -- +optional`` to +enable all optional modules, and then run ``west update`` again. + Device Drivers and Device Tree ============================== From 0891448ac908303dd8016d286727d88d1a1a5061 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 30 Oct 2023 13:23:21 +0800 Subject: [PATCH 2922/4498] soc: intel_adsp: don't enable interrupt before k_cpu_idle Fix a bug on cavs platform that secondary core is not powered off by SET_DX ipc message sometimes. Secondary core is set into idle state when switching to SOF_OFF state and then halted by primary core. The interrupt is enabled before entring idle state, so the secondary core may be woken up by interrupt and soc_cpus_active is set to true before it is halted by hardware power gating. This result to error when SOF check soc_cpus_active after the secondary is halted. This patch doesn't enable interrupt before idle entry to avoid above issue. Signed-off-by: Rander Wang --- soc/xtensa/intel_adsp/cavs/power.c | 1 - 1 file changed, 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index e5b9f73285d..d3bbcea6968 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -107,7 +107,6 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) /* do power down - this function won't return */ power_down_cavs(true, uncache_to_cache(&hpsram_mask[0])); } else { - z_xt_ints_on(core_desc[cpu].intenable); k_cpu_idle(); } } else { From 043e6ecbf6b4c80e9eef4a7265e47e588fa7e44f Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 27 Oct 2023 13:11:09 +0200 Subject: [PATCH 2923/4498] drivers: can: add accessor for the CAN bit error counter Add accessor function for the CAN bit error counter. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_handlers.c | 8 ++++++++ drivers/can/can_shell.c | 5 +++-- include/zephyr/drivers/can.h | 25 +++++++++++++++++++++++++ tests/drivers/can/api/src/stats.c | 1 + 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 842c3786d5d..7401a7f9fd3 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -246,6 +246,14 @@ static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeo #ifdef CONFIG_CAN_STATS +static inline uint32_t z_vrfy_can_stats_get_bit_errors(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + + return z_impl_can_stats_get_bit_errors(dev); +} +#include + static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev) { Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index 66900f18e8f..4faf11aae4e 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -364,8 +364,9 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) #ifdef CONFIG_CAN_STATS shell_print(sh, "statistics:"); - shell_print(sh, " bit0 errors: %u", can_stats_get_bit0_errors(dev)); - shell_print(sh, " bit1 errors: %u", can_stats_get_bit1_errors(dev)); + shell_print(sh, " bit errors: %u", can_stats_get_bit_errors(dev)); + shell_print(sh, " bit0 errors: %u", can_stats_get_bit0_errors(dev)); + shell_print(sh, " bit1 errors: %u", can_stats_get_bit1_errors(dev)); shell_print(sh, " stuff errors: %u", can_stats_get_stuff_errors(dev)); shell_print(sh, " crc errors: %u", can_stats_get_crc_errors(dev)); shell_print(sh, " form errors: %u", can_stats_get_form_errors(dev)); diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index e53a39471d7..0028abb330d 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -1384,6 +1384,27 @@ static inline void can_set_state_change_callback(const struct device *dev, * @{ */ +/** + * @brief Get the bit error counter for a CAN device + * + * The bit error counter is incremented when the CAN controller is unable to + * transmit either a dominant or a recessive bit. + * + * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be + * available. + * + * @param dev Pointer to the device structure for the driver instance. + * @return bit error counter + */ +__syscall uint32_t can_stats_get_bit_errors(const struct device *dev); + +#ifdef CONFIG_CAN_STATS +static inline uint32_t z_impl_can_stats_get_bit_errors(const struct device *dev) +{ + return Z_CAN_GET_STATS(dev).bit_error; +} +#endif /* CONFIG_CAN_STATS */ + /** * @brief Get the bit0 error counter for a CAN device * @@ -1393,6 +1414,8 @@ static inline void can_set_state_change_callback(const struct device *dev, * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be * available. * + * @see can_stats_get_bit_errors() + * * @param dev Pointer to the device structure for the driver instance. * @return bit0 error counter */ @@ -1414,6 +1437,8 @@ static inline uint32_t z_impl_can_stats_get_bit0_errors(const struct device *dev * @note @kconfig{CONFIG_CAN_STATS} must be selected for this function to be * available. * + * @see can_stats_get_bit_errors() + * * @param dev Pointer to the device structure for the driver instance. * @return bit1 error counter */ diff --git a/tests/drivers/can/api/src/stats.c b/tests/drivers/can/api/src/stats.c index 85320dc64ca..c272cc89b9f 100644 --- a/tests/drivers/can/api/src/stats.c +++ b/tests/drivers/can/api/src/stats.c @@ -23,6 +23,7 @@ ZTEST_USER(can_stats, test_can_stats_accessors) { uint32_t val; + val = can_stats_get_bit_errors(can_dev); val = can_stats_get_bit0_errors(can_dev); val = can_stats_get_bit1_errors(can_dev); val = can_stats_get_stuff_errors(can_dev); From b31afe1d27456b8429194952d2b9207181a062be Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 11:14:13 +0200 Subject: [PATCH 2924/4498] sparc: add SPARC dependency to SPARC_CASA Settings which defaults to `y` but is architecture related should have a arch dependency for safety reasons. Thefore add `if SPARC` to the SPARC_CASA Kconfig to ensure this setting is only enabled on the sparc arch. Signed-off-by: Torsten Rasmussen --- soc/sparc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/sparc/Kconfig b/soc/sparc/Kconfig index 0d975d46c32..de68a730048 100644 --- a/soc/sparc/Kconfig +++ b/soc/sparc/Kconfig @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 config SPARC_CASA - default y + default y if SPARC config SOC_SPARC_LEON bool From bd4bada1519a6118de843fbdf0f5331369d739a4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 24 Oct 2023 12:21:23 +0100 Subject: [PATCH 2925/4498] doc: release: 3.6: Add notes on MCUmgr fixes Adds notes on fixed MCUmgr issues and a smp_svr sample issue Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.6.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst index 167dce4b4ac..ea62b9cc977 100644 --- a/doc/releases/release-notes-3.6.rst +++ b/doc/releases/release-notes-3.6.rst @@ -236,6 +236,15 @@ Libraries / Subsystems * Management + * Fixed an issue in MCUmgr image management whereby erasing an already erased slot would return + an unknown error, it now returns success. + + * Fixed MCUmgr UDP transport structs being statically initialised, this results in about a + ~5KiB flash saving. + + * Fixed an issue in MCUmgr which would cause a user data buffer overflow if the UDP transport was + enabled on IPv4 only but IPv6 support was enabled in the kernel. + * File systems * Modem modules @@ -278,3 +287,6 @@ Documentation Tests and Samples ***************** + +* Fixed an issue in :zephyr:code-sample:`smp-svr` sample whereby if USB was already initialised, + application would fail to boot properly. From 3ce916d68ffd4cab5b8d3173e12d3582eb89e819 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 24 Oct 2023 12:22:01 +0100 Subject: [PATCH 2926/4498] doc: migration-guide: 3.6: Add note on MCUmgr CRC change Adds a note that an additional Kconfig needs to be selected if a serial MCUmgr transport is used Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-3.6.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 32a5ce74961..09ad3fe1401 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -45,5 +45,9 @@ Networking Other Subsystems ================ +* MCUmgr applications that make use of serial transports (shell or UART) must now select + :kconfig:option:`CONFIG_CRC`, this was previously erroneously selected if MCUmgr was enabled, + when for non-serial transports it was not needed. + Recommended Changes ******************* From 596fc4850946dc3fb17c9d11e56db8a32943098c Mon Sep 17 00:00:00 2001 From: Ludvig Jordet Date: Tue, 24 Oct 2023 16:43:42 +0200 Subject: [PATCH 2927/4498] doc: bluetooth: mesh: Improve CDP128+ docs Improves the documentation about how CDP 128, 129 and 130, as well as Models Metadata Page 128 are created, as well as which functions the application will have to call to store the correct contents in the pages. Signed-off-by: Ludvig Jordet --- .../bluetooth/api/mesh/access.rst | 29 ++++++++++-------- doc/connectivity/bluetooth/api/mesh/dfu.rst | 7 ++++- .../bluetooth/api/mesh/dfu_srv.rst | 30 ++++++++++++++++++- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 151e74add28..2af8e6a03b8 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -185,17 +185,15 @@ information about the device. In order to access this information, the user may use the :ref:`bluetooth_mesh_models_cfg_srv` model or, if supported, the :ref:`bluetooth_mesh_lcd_srv` model. -Composition Data Page 0 and 128 -------------------------------- +Composition Data Page 0 +----------------------- Composition Data Page 0 provides the fundemental information about a device, and is mandatory for all mesh devices. It contains the element and model composition, -the supported features, and manufacturer information. Composition Data Page 128 -mirrors Page 0 and is used to represent the new content of the Composition Data -Page 0 after a device firmware update. +the supported features, and manufacturer information. -Composition Data Page 1 and 129 -------------------------------- +Composition Data Page 1 +----------------------- Composition Data Page 1 provides information about the relationships between models, and is mandatory for all mesh devices. A model may extend and/or correspond to one @@ -204,11 +202,9 @@ or correspond to another model by calling :c:func:`bt_mesh_model_correspond`. :kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE` specifies how many model relations can be stored in the composition on a device, and this number should reflect the number of :c:func:`bt_mesh_model_extend` and :c:func:`bt_mesh_model_correspond` calls. -Composition Data Page 129 mirrors Page 1 and is used to represent the new content of -the Composition Data Page 1 after a device firmware update. -Composition Data Page 2 and 130 -------------------------------- +Composition Data Page 2 +----------------------- Composition Data Page 2 provides information for supported mesh profiles. Mesh profile specifications define product requirements for devices that want to support a specific @@ -216,8 +212,15 @@ Bluetooth SIG defined profile. Currently supported profiles can be found in sect 3.12 in `Bluetooth SIG Assigned Numbers `_. Composition Data Page 2 is only mandatory for devices that claim support for one or more -mesh profile(s). Composition Data Page 130 mirrors Page 2 and is used to represent the -new content of the Composition Data Page 2 after a device firmware update. +mesh profile(s). + +Composition Data Pages 128, 129 and 130 +--------------------------------------- + +Composition Data Pages 128, 129 and 130 mirror Composition Data Pages 0, 1 and 2 respectively. +They are used to represent the new content of the mirrored pages when the Composition Data will +change after a firmware update. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata` +for details. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index a929f8a53fc..46d3cfb6dc3 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -210,7 +210,12 @@ re-provisioned. The complete list of available options is defined in :c:enum:`bt When the Target node receives the Firmware Update Firmware Metadata Check message, the Firmware Update Server model calls the :c:member:`bt_mesh_dfu_srv_cb.check` callback, the application can -then process the metadata and provide the effect value. +then process the metadata and provide the effect value. If the effect is +:c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE`, the application must call functions +:c:func:`bt_mesh_comp_change_prepare` and :c:func:`bt_mesh_models_metadata_change_prepare` to +prepare the Composition Data Page and Models Metadata Page contents before applying the new +firmware image. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata` for more +information. DFU procedures diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst index b78d4ce2c1d..2642dec8cc9 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst @@ -47,9 +47,37 @@ firmware image metadata. The Firmware Update Server performs the transfer check The result of the transfer check is a pass/fail status return and the expected :c:type:`bt_mesh_dfu_effect`. The DFU effect return parameter will be communicated back to the Distributor, and should indicate what effect the firmware update will have on the mesh state of the -device. If the transfer will cause the device to change its Composition Data or become +device. + +.. _bluetooth_mesh_dfu_srv_comp_data_and_models_metadata: + +Composition Data and Models Metadata +------------------------------------ + +If the transfer will cause the device to change its Composition Data or become unprovisioned, this should be communicated through the effect parameter of the metadata check. +When the transfer will cause the Composition Data to change, and the +:ref:`bluetooth_mesh_models_rpr_srv` is supported, the Composition Data of the new firmware image +will be represented by Composition Data Pages 128, 129, and 130. The Models Metadata of the new +firmware image will be represented by Models Metadata Page 128. Composition Data Pages 0, 1 and 2, +and Models Metadata Page 0, will represent the Composition Data and the Models Metadata of the old +firmware image until the device is reprovisioned with Node Provisioning Protocol Interface (NPPI) +procedures using the :ref:`bluetooth_mesh_models_rpr_cli`. + +The application must call functions :c:func:`bt_mesh_comp_change_prepare` and +:c:func:`bt_mesh_models_metadata_change_prepare` to store the existing Composition Data and Models +Metadata pages before booting into the firmware with the updated Composition Data and Models +Metadata. The old Composition Data will then be loaded into Composition Data Pages 0, 1 and 2, +while the Composition Data in the new firmware will be loaded into Composition Data Pages 128, 129 +and 130. The Models Metadata for the old image will be loaded into Models Metadata Page 0, and the +Models Metadata for the new image will be loaded into Models Metadata Page 128. + +Limitation: + +* It is not possible to change the Composition Data of the device and keep the device provisioned + and working with the old firmware after the new firmware image is applied. + Start ===== From a4b9692155a36a7ef0092477eadd3d62407897a6 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Tue, 12 Sep 2023 15:14:54 +0800 Subject: [PATCH 2928/4498] soc: intel_adsp/cavs: add secondary dsp context save support Save secondary dsp context when it is powered off in idle thread and restore it when the secondary dsp is powered up. The algorithm is aligned with ace platform. Tested on a tgl platform. Signed-off-by: Rander Wang --- soc/xtensa/intel_adsp/cavs/multiprocessing.c | 18 ++++++- soc/xtensa/intel_adsp/cavs/power.c | 50 ++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/cavs/multiprocessing.c b/soc/xtensa/intel_adsp/cavs/multiprocessing.c index bc48764515a..85d834065a7 100644 --- a/soc/xtensa/intel_adsp/cavs/multiprocessing.c +++ b/soc/xtensa/intel_adsp/cavs/multiprocessing.c @@ -7,6 +7,7 @@ #include #include #include +#include /* IDC power up message to the ROM firmware. This isn't documented * anywhere, it's basically just a magic number (except the high bit, @@ -71,7 +72,22 @@ void soc_start_core(int cpu_num) }; memcpy(lpsram, tramp, ARRAY_SIZE(tramp)); +#if CONFIG_PM + extern void dsp_restore_vector(void); + + /* We need to find out what type of booting is taking place here. Secondary cores + * can be disabled and enabled multiple times during runtime. During kernel + * initialization, the next pm state is set to ACTIVE. This way we can determine + * whether the core is being turned on again or for the first time. + */ + if (pm_state_next_get(cpu_num)->state == PM_STATE_ACTIVE) + lpsram[1] = z_soc_mp_asm_entry; + else + lpsram[1] = dsp_restore_vector; +#else lpsram[1] = z_soc_mp_asm_entry; +#endif + /* Disable automatic power and clock gating for that CPU, so * it won't just go back to sleep. Note that after startup, @@ -98,7 +114,7 @@ void soc_start_core(int cpu_num) * available, so it's sent shifted). The write to ITC * triggers the interrupt, so that comes last. */ - uint32_t ietc = ((long) z_soc_mp_asm_entry) >> 2; + uint32_t ietc = ((long)lpsram[1]) >> 2; IDC[curr_cpu].core[cpu_num].ietc = ietc; IDC[curr_cpu].core[cpu_num].itc = IDC_MSG_POWER_UP; diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index d3bbcea6968..bc955b3cb90 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -54,6 +54,9 @@ LOG_MODULE_REGISTER(soc); extern void rom_entry(void); struct core_state { + uint32_t a0; + uint32_t a1; + uint32_t excsave2; uint32_t intenable; }; @@ -76,6 +79,51 @@ static inline void __sparse_cache *uncache_to_cache(void *address) return (void __sparse_cache *)((uintptr_t)(address) | SRAM_ALIAS_OFFSET); } +static ALWAYS_INLINE void _save_core_context(void) +{ + uint32_t core_id = arch_proc_id(); + + core_desc[core_id].excsave2 = XTENSA_RSR(ZSR_CPU_STR); + __asm__ volatile("mov %0, a0" : "=r"(core_desc[core_id].a0)); + __asm__ volatile("mov %0, a1" : "=r"(core_desc[core_id].a1)); + sys_cache_data_flush_range(&core_desc[core_id], sizeof(struct core_state)); +} + +static ALWAYS_INLINE void _restore_core_context(void) +{ + uint32_t core_id = arch_proc_id(); + + XTENSA_WSR(ZSR_CPU_STR, core_desc[core_id].excsave2); + __asm__ volatile("mov a0, %0" :: "r"(core_desc[core_id].a0)); + __asm__ volatile("mov a1, %0" :: "r"(core_desc[core_id].a1)); + __asm__ volatile("rsync"); +} + +void power_gate_exit(void) +{ + cpu_early_init(); + sys_cache_data_flush_and_invd_all(); + _restore_core_context(); +} + +__asm__(".align 4\n\t" + ".global dsp_restore_vector\n\t" + "dsp_restore_vector:\n\t" + " movi a0, 0\n\t" + " movi a1, 1\n\t" + " movi a2, 0x40020\n\t"/* PS_UM|PS_WOE */ + " wsr a2, PS\n\t" + " wsr a1, WINDOWSTART\n\t" + " wsr a0, WINDOWBASE\n\t" + " rsync\n\t" + " movi a1, z_interrupt_stacks\n\t" + " rsr a2, PRID\n\t" + " movi a3, " STRINGIFY(CONFIG_ISR_STACK_SIZE) "\n\t" + " mull a2, a2, a3\n\t" + " add a2, a2, a3\n\t" + " add a1, a1, a2\n\t" + " call0 power_gate_exit\n\t"); + void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -84,6 +132,8 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) if (state == PM_STATE_SOFT_OFF) { core_desc[cpu].intenable = XTENSA_RSR("INTENABLE"); z_xt_ints_off(0xffffffff); + xthal_window_spill(); + _save_core_context(); soc_cpus_active[cpu] = false; sys_cache_data_flush_and_invd_all(); if (cpu == 0) { From f9051d626d7607f1e0e18f5bafd2acb3a199ac12 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Wed, 1 Nov 2023 09:14:31 +0100 Subject: [PATCH 2929/4498] boards: m5stack_core2: fix priorities override Instead of those set, use the default ones for the MFD/REGULATOR_AXP192_INIT_PRIORITY/GPIO_AXP192_INIT_PRIORITY that are set to the 80/86/81 values correctly. Adjust the GPIO_HOGS_INIT_PRIORITY only to be executed after GPIO driver. Signed-off-by: Bartosz Bilas --- boards/xtensa/m5stack_core2/Kconfig.defconfig | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/boards/xtensa/m5stack_core2/Kconfig.defconfig b/boards/xtensa/m5stack_core2/Kconfig.defconfig index 2e68d5614d0..feb6c7a6d6b 100644 --- a/boards/xtensa/m5stack_core2/Kconfig.defconfig +++ b/boards/xtensa/m5stack_core2/Kconfig.defconfig @@ -24,17 +24,8 @@ choice BT_HCI_BUS_TYPE default BT_ESP32 if BT endchoice -config MFD_INIT_PRIORITY - default 60 - -config REGULATOR_AXP192_INIT_PRIORITY - default 76 - -config GPIO_AXP192_INIT_PRIORITY - default 80 - config GPIO_HOGS_INIT_PRIORITY - default 81 + default 82 config INPUT_FT5336_INTERRUPT default y if INPUT From 1e15949fe04a6f778f2e0f32f62ef51fc22ef66d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 1 Nov 2023 10:45:27 +0200 Subject: [PATCH 2930/4498] tests: net: socket: tls: Increase the mbedtls heap size native_posix_64 needs more heap for the test to pass so increase it by 2kb. Fixes #64670 Signed-off-by: Jukka Rissanen --- tests/net/socket/tls/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 4db53b1442b..d67e0a2d5f8 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -39,5 +39,5 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=3072 CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=16000 +CONFIG_MBEDTLS_HEAP_SIZE=18000 CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y From 5f7d2f23816d250e110fe83dbdcce725b1e94ec9 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Thu, 26 Oct 2023 14:25:04 -0700 Subject: [PATCH 2931/4498] board/riscv/it8xxx2_evb: Disable PM for ITE IT8XXX2 The workqueue test may intermittently fail, with errors such as: work_1cpu_test_1cpu_system_schedule: (elapsed_ms <= max_ms is false) long 102 > 101 Disabling PM makes the issues go away, and it is what this patch does. Signed-off-by: Ederson de Souza --- boards/riscv/it8xxx2_evb/Kconfig.defconfig | 12 +++++++++++- boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig | 4 ---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/boards/riscv/it8xxx2_evb/Kconfig.defconfig b/boards/riscv/it8xxx2_evb/Kconfig.defconfig index a207bafd0cc..588b0dd8641 100644 --- a/boards/riscv/it8xxx2_evb/Kconfig.defconfig +++ b/boards/riscv/it8xxx2_evb/Kconfig.defconfig @@ -5,4 +5,14 @@ if BOARD_IT8XXX2_EVB config BOARD default "it8xxx2_evb" -endif + +if PM +config PM_DEVICE + default y + +choice PM_POLICY + default PM_POLICY_CUSTOM +endchoice +endif # PM + +endif # BOARD_IT8XXX2_EVB diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig index 9aa7deef842..21967527f8e 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig @@ -19,7 +19,3 @@ CONFIG_INIT_STACKS=y CONFIG_LINKER_ORPHAN_SECTION_PLACE=y CONFIG_COMPILER_OPT="-mcmodel=medlow" CONFIG_GPIO=y -# Power Management -CONFIG_PM=y -CONFIG_PM_DEVICE=y -CONFIG_PM_POLICY_CUSTOM=y From 90fec53381e08e0909988d3c0f466c91d43eb6cd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 2 Nov 2023 14:08:25 +0100 Subject: [PATCH 2932/4498] tests nrf_rtc_timer: Avoid failures w NRF53_SYNC_RTC enabled This test assumes it can use all configured NRF_RTC_TIMER_USER_CHAN_COUNT, But the sync RTC code uses one while it synchronizes. Let's just disable it the sync rtc. This fixes an issue where the test fails for a simulated nrf5340. Signed-off-by: Alberto Escolar Piedras --- tests/drivers/timer/nrf_rtc_timer/prj.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/drivers/timer/nrf_rtc_timer/prj.conf b/tests/drivers/timer/nrf_rtc_timer/prj.conf index 84caa9eb85b..15c8902ce88 100644 --- a/tests/drivers/timer/nrf_rtc_timer/prj.conf +++ b/tests/drivers/timer/nrf_rtc_timer/prj.conf @@ -2,6 +2,10 @@ CONFIG_ZTEST=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 +# This test assumes it can use all configured NRF_RTC_TIMER_USER_CHAN_COUNT +# But the sync RTC code uses one while it synchronizes. Let's just disable it. +CONFIG_NRF53_SYNC_RTC=n + # Debug build # CONFIG_NO_OPTIMIZATIONS=y # CONFIG_ZTEST_STACK_SIZE=2048 From a77871b2e53f36f005f0fc478f8264df68a39fc1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 19:07:37 +0200 Subject: [PATCH 2933/4498] tests: Add ACPI test application Add basic ACPI test application. Initially there are only tests for one ACPI table (MCFG) and fetching the ACPI PRT, but this is already a good start for caching regressions on the supported boards. Signed-off-by: Johan Hedberg --- tests/lib/acpi/CMakeLists.txt | 7 +++++++ tests/lib/acpi/prj.conf | 4 ++++ tests/lib/acpi/src/main.c | 30 ++++++++++++++++++++++++++++++ tests/lib/acpi/testcase.yaml | 8 ++++++++ 4 files changed, 49 insertions(+) create mode 100644 tests/lib/acpi/CMakeLists.txt create mode 100644 tests/lib/acpi/prj.conf create mode 100644 tests/lib/acpi/src/main.c create mode 100644 tests/lib/acpi/testcase.yaml diff --git a/tests/lib/acpi/CMakeLists.txt b/tests/lib/acpi/CMakeLists.txt new file mode 100644 index 00000000000..c7b741d444a --- /dev/null +++ b/tests/lib/acpi/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(acpi) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/lib/acpi/prj.conf b/tests/lib/acpi/prj.conf new file mode 100644 index 00000000000..855b08c19da --- /dev/null +++ b/tests/lib/acpi/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_ACPI=y +CONFIG_PCIE=y +CONFIG_PCIE_PRT=y diff --git a/tests/lib/acpi/src/main.c b/tests/lib/acpi/src/main.c new file mode 100644 index 00000000000..c7f09c1c07b --- /dev/null +++ b/tests/lib/acpi/src/main.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +ZTEST(acpi, mcfg_table) +{ + struct acpi_mcfg *mcfg; + + mcfg = acpi_table_get("MCFG", 0); + + zassert_not_null(mcfg, "Failed to get MCFG table"); +} + +ZTEST(acpi, irq_routing_table) +{ + static ACPI_PCI_ROUTING_TABLE irq_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; + int status; + + status = acpi_get_irq_routing_table(CONFIG_ACPI_PRT_BUS_NAME, + irq_prt_table, sizeof(irq_prt_table)); + zassert_ok(status, "Failed to get PRT"); +} + +ZTEST_SUITE(acpi, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/lib/acpi/testcase.yaml b/tests/lib/acpi/testcase.yaml new file mode 100644 index 00000000000..e35f91559d2 --- /dev/null +++ b/tests/lib/acpi/testcase.yaml @@ -0,0 +1,8 @@ +tests: + acpi.basic: + tags: + - acpi + - acpica + integration_platforms: + - qemu_x86_64 + depends_on: acpi From caf299ca23fff5f2f07a20fc082ed6d282fd19ee Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 1 Nov 2023 10:33:14 +0200 Subject: [PATCH 2934/4498] boards: x86: Indicate ACPI support where applicable There are several x86 boards that support ACPI, so indicate it in their yaml files. Signed-off-by: Johan Hedberg --- boards/x86/intel_adl/intel_adl_crb.yaml | 1 + boards/x86/intel_adl/intel_adl_rvp.yaml | 1 + boards/x86/intel_ehl/intel_ehl_crb.yaml | 1 + boards/x86/intel_rpl/intel_rpl_s_crb.yaml | 1 + boards/x86/qemu_x86/qemu_x86_64.yaml | 1 + boards/x86/up_squared/up_squared.yaml | 1 + tests/lib/acpi/src/main.c | 4 ++-- 7 files changed, 8 insertions(+), 2 deletions(-) diff --git a/boards/x86/intel_adl/intel_adl_crb.yaml b/boards/x86/intel_adl/intel_adl_crb.yaml index a49e0864f92..b393059d427 100644 --- a/boards/x86/intel_adl/intel_adl_crb.yaml +++ b/boards/x86/intel_adl/intel_adl_crb.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr ram: 2048 supported: + - acpi - watchdog - pwm - gpio diff --git a/boards/x86/intel_adl/intel_adl_rvp.yaml b/boards/x86/intel_adl/intel_adl_rvp.yaml index ce009bfe33b..8a09b3fe16e 100644 --- a/boards/x86/intel_adl/intel_adl_rvp.yaml +++ b/boards/x86/intel_adl/intel_adl_rvp.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr ram: 2048 supported: + - acpi - smp - watchdog testing: diff --git a/boards/x86/intel_ehl/intel_ehl_crb.yaml b/boards/x86/intel_ehl/intel_ehl_crb.yaml index 4e9d07e9caf..04cf5e2702e 100644 --- a/boards/x86/intel_ehl/intel_ehl_crb.yaml +++ b/boards/x86/intel_ehl/intel_ehl_crb.yaml @@ -7,6 +7,7 @@ toolchain: - llvm ram: 2048 supported: + - acpi - gpio - smbus - smp diff --git a/boards/x86/intel_rpl/intel_rpl_s_crb.yaml b/boards/x86/intel_rpl/intel_rpl_s_crb.yaml index ca0be3de697..ef51e444e58 100644 --- a/boards/x86/intel_rpl/intel_rpl_s_crb.yaml +++ b/boards/x86/intel_rpl/intel_rpl_s_crb.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr ram: 2048 supported: + - acpi - smp - smbus - watchdog diff --git a/boards/x86/qemu_x86/qemu_x86_64.yaml b/boards/x86/qemu_x86/qemu_x86_64.yaml index afa50057b6a..b5c77de4c0e 100644 --- a/boards/x86/qemu_x86/qemu_x86_64.yaml +++ b/boards/x86/qemu_x86/qemu_x86_64.yaml @@ -7,6 +7,7 @@ toolchain: - xtools simulation: qemu supported: + - acpi - can - smp - smbus diff --git a/boards/x86/up_squared/up_squared.yaml b/boards/x86/up_squared/up_squared.yaml index 2b27e7a7b2b..79e4d5e7e92 100644 --- a/boards/x86/up_squared/up_squared.yaml +++ b/boards/x86/up_squared/up_squared.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr ram: 256 supported: + - acpi - smp testing: ignore_tags: diff --git a/tests/lib/acpi/src/main.c b/tests/lib/acpi/src/main.c index c7f09c1c07b..db64ceea6ea 100644 --- a/tests/lib/acpi/src/main.c +++ b/tests/lib/acpi/src/main.c @@ -8,7 +8,7 @@ #include #include -ZTEST(acpi, mcfg_table) +ZTEST(acpi, test_mcfg_table) { struct acpi_mcfg *mcfg; @@ -17,7 +17,7 @@ ZTEST(acpi, mcfg_table) zassert_not_null(mcfg, "Failed to get MCFG table"); } -ZTEST(acpi, irq_routing_table) +ZTEST(acpi, test_irq_routing_table) { static ACPI_PCI_ROUTING_TABLE irq_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; int status; From 8bcdb694a23a23d2f93bea4dc3d02136e14576df Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 1 Nov 2023 19:37:08 +0200 Subject: [PATCH 2935/4498] MAINTAINERS: Add tests/lib/acpi/ to ACPI section Make sure the new ACPI test is included. Signed-off-by: Johan Hedberg --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index c095efbe95c..39b33c65629 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -121,6 +121,7 @@ ACPI: files: - lib/acpi/ - include/zephyr/acpi/ + - tests/lib/acpi/ labels: - "area: ACPI" From 75444bdc64069b70809d1c8247c33c43b9d8d0ab Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Wed, 1 Nov 2023 09:03:21 +0100 Subject: [PATCH 2936/4498] drivers: regulator: axp192: fix init priority That was missed in 66f5fce commit so let's adjust it as well. Signed-off-by: Bartosz Bilas --- drivers/regulator/Kconfig.axp192 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig.axp192 b/drivers/regulator/Kconfig.axp192 index c2ec403359e..8c8fad5cdb4 100644 --- a/drivers/regulator/Kconfig.axp192 +++ b/drivers/regulator/Kconfig.axp192 @@ -15,7 +15,7 @@ if REGULATOR_AXP192 config REGULATOR_AXP192_INIT_PRIORITY int "AXP192 regulator driver init priority" - default 76 + default 86 help Init priority for the axp192 regulator driver. It must be greater than MFD_INIT_PRIORITY. From 2d060feb51accfd31a797d178287682e208ce16c Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Thu, 2 Nov 2023 13:42:00 +0100 Subject: [PATCH 2937/4498] boards: m5stack_core2: override REGULATOR_AXP192_INIT_PRIORITY priority axp192 is used by the display controller and gpio hog subsys thus we need to set this priority to the smaller value. Signed-off-by: Bartosz Bilas --- boards/xtensa/m5stack_core2/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/xtensa/m5stack_core2/Kconfig.defconfig b/boards/xtensa/m5stack_core2/Kconfig.defconfig index feb6c7a6d6b..08fc712b0d3 100644 --- a/boards/xtensa/m5stack_core2/Kconfig.defconfig +++ b/boards/xtensa/m5stack_core2/Kconfig.defconfig @@ -24,6 +24,9 @@ choice BT_HCI_BUS_TYPE default BT_ESP32 if BT endchoice +config REGULATOR_AXP192_INIT_PRIORITY + default 81 + config GPIO_HOGS_INIT_PRIORITY default 82 From 4c21090dcb6690e0120d619df736fd6c1c6c7ac1 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 2 Nov 2023 16:07:06 +0000 Subject: [PATCH 2938/4498] samples: net: fix twister filter Use not for negation. Signed-off-by: Anas Nashif --- samples/net/cloud/aws_iot_mqtt/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/cloud/aws_iot_mqtt/sample.yaml b/samples/net/cloud/aws_iot_mqtt/sample.yaml index c7251fdb305..dee2dab638f 100644 --- a/samples/net/cloud/aws_iot_mqtt/sample.yaml +++ b/samples/net/cloud/aws_iot_mqtt/sample.yaml @@ -4,7 +4,7 @@ sample: common: tags: net mqtt cloud harness: net - filter: CONFIG_FULL_LIBC_SUPPORTED && !CONFIG_NATIVE_LIBC + filter: CONFIG_FULL_LIBC_SUPPORTED && not CONFIG_NATIVE_LIBC extra_args: USE_DUMMY_CREDS=1 tests: sample.net.cloud.aws_iot_mqtt: From e07ded1656b49a75699ad881004d48c23c42c7a8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 2 Nov 2023 16:20:03 +0200 Subject: [PATCH 2939/4498] MAINTAINERS: Add Tomasz to ACPI as collaborator Tomasz is actively involved in Zephyr's ACPI support, so add him as a collaborator to the subsystem. Signed-off-by: Johan Hedberg --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 39b33c65629..f7d08c0d511 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -118,6 +118,7 @@ ACPI: - najumon1980 collaborators: - finikorg + - tbursztyka files: - lib/acpi/ - include/zephyr/acpi/ From 4a397402a75103f91ed0af2fbaeb46bd233f5509 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 12:53:08 +0100 Subject: [PATCH 2940/4498] drivers: mfd: add Maxim MAX20335 MFD driver Maxim MAX20335 is a PMIC with Ultra-Low IQ Voltage Regulators and Battery Chargers for Small Lithium Ion Systems. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/mfd/CMakeLists.txt | 1 + drivers/mfd/Kconfig | 1 + drivers/mfd/Kconfig.max20335 | 10 ++++++ drivers/mfd/mfd_max20335.c | 51 ++++++++++++++++++++++++++++ dts/bindings/mfd/maxim,max20335.yaml | 12 +++++++ 6 files changed, 76 insertions(+) create mode 100644 drivers/mfd/Kconfig.max20335 create mode 100644 drivers/mfd/mfd_max20335.c create mode 100644 dts/bindings/mfd/maxim,max20335.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 2a3d3ccb249..a66b68c16c7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -373,6 +373,7 @@ /drivers/led_strip/ @mbolivar-ampere /drivers/lora/ @Mani-Sadhasivam /drivers/mbox/ @carlocaione +/drivers/mfd/mfd_max20335.c @bbilas /drivers/misc/ @tejlmand /drivers/misc/ft8xx/ @hubertmis /drivers/mm/ @dcpleung diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index e8e59dd1692..7c5e048fcc6 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() +zephyr_library_sources_ifdef(CONFIG_MFD_MAX20335 mfd_max20335.c) zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3edbbab1fc4..1a80cf446f5 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -19,6 +19,7 @@ config MFD_INIT_PRIORITY Multi-function devices initialization priority. source "drivers/mfd/Kconfig.axp192" +source "drivers/mfd/Kconfig.max20335" source "drivers/mfd/Kconfig.nct38xx" source "drivers/mfd/Kconfig.npm1300" source "drivers/mfd/Kconfig.npm6001" diff --git a/drivers/mfd/Kconfig.max20335 b/drivers/mfd/Kconfig.max20335 new file mode 100644 index 00000000000..3d146de17f0 --- /dev/null +++ b/drivers/mfd/Kconfig.max20335 @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +config MFD_MAX20335 + bool "MAX20335 PMIC multi-function device driver" + default y + depends on DT_HAS_MAXIM_MAX20335_ENABLED + select I2C + help + Enable the Maxim MAX20335 PMIC multi-function device driver diff --git a/drivers/mfd/mfd_max20335.c b/drivers/mfd/mfd_max20335.c new file mode 100644 index 00000000000..7ea6a9f198c --- /dev/null +++ b/drivers/mfd/mfd_max20335.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT maxim_max20335 + +#include + +#include +#include + +#define MAX20335_REG_CHIP_ID 0x00 +#define MAX20335_CHIP_ID_VAL 0x04 + +struct mfd_max20335_config { + struct i2c_dt_spec bus; +}; + +static int mfd_max20335_init(const struct device *dev) +{ + const struct mfd_max20335_config *config = dev->config; + uint8_t val; + int ret; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_CHIP_ID, &val); + if (ret < 0) { + return ret; + } + + if (val != MAX20335_CHIP_ID_VAL) { + return -ENODEV; + } + + return 0; +} + +#define MFD_MA20335_DEFINE(inst) \ + static const struct mfd_max20335_config mfd_max20335_config##inst = { \ + .bus = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfd_max20335_init, NULL, NULL, \ + &mfd_max20335_config##inst, POST_KERNEL, \ + CONFIG_MFD_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_MA20335_DEFINE) diff --git a/dts/bindings/mfd/maxim,max20335.yaml b/dts/bindings/mfd/maxim,max20335.yaml new file mode 100644 index 00000000000..deec53c872d --- /dev/null +++ b/dts/bindings/mfd/maxim,max20335.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim MAX20335 + +compatible: "maxim,max20335" + +include: i2c-device.yaml + +properties: + reg: + required: true From e87fd3165fba5de3d6b417d40624ddb38d39d08a Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 12:55:22 +0100 Subject: [PATCH 2941/4498] drivers: regulator: add MAX20335 driver Add a MAX20335 MFD subdriver to manage the built-in PMIC. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/regulator/CMakeLists.txt | 1 + drivers/regulator/Kconfig | 1 + drivers/regulator/Kconfig.max20335 | 18 + drivers/regulator/regulator_max20335.c | 326 ++++++++++++++++++ .../regulator/maxim,max20335-regulator.yaml | 49 +++ .../zephyr/dt-bindings/regulator/max20335.h | 28 ++ tests/drivers/build_all/regulator/i2c.dtsi | 15 + 8 files changed, 439 insertions(+) create mode 100644 drivers/regulator/Kconfig.max20335 create mode 100644 drivers/regulator/regulator_max20335.c create mode 100644 dts/bindings/regulator/maxim,max20335-regulator.yaml create mode 100644 include/zephyr/dt-bindings/regulator/max20335.h diff --git a/CODEOWNERS b/CODEOWNERS index a66b68c16c7..8172acd9c90 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -408,6 +408,7 @@ /drivers/pwm/*rcar* @aaillet /drivers/pwm/*max31790* @benediktibk /drivers/regulator/* @gmarull +/drivers/regulator/regulator_max20335.c @bbilas /drivers/regulator/regulator_pca9420.c @danieldegrasse /drivers/regulator/regulator_rpi_pico.c @soburi /drivers/regulator/regulator_shell.c @danieldegrasse diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 27bf32076cf..94c3a032aff 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_REGULATOR_ADP5360 regulator_adp5360.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FAKE regulator_fake.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FIXED regulator_fixed.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_GPIO regulator_gpio.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_MAX20335 regulator_max20335.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1100 regulator_npm1100.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1300 regulator_npm1300.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 5ecaf1181ea..ebf13261cbf 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -32,6 +32,7 @@ source "drivers/regulator/Kconfig.adp5360" source "drivers/regulator/Kconfig.fake" source "drivers/regulator/Kconfig.fixed" source "drivers/regulator/Kconfig.gpio" +source "drivers/regulator/Kconfig.max20335" source "drivers/regulator/Kconfig.npm1100" source "drivers/regulator/Kconfig.npm1300" source "drivers/regulator/Kconfig.npm6001" diff --git a/drivers/regulator/Kconfig.max20335 b/drivers/regulator/Kconfig.max20335 new file mode 100644 index 00000000000..a9b739e1f2c --- /dev/null +++ b/drivers/regulator/Kconfig.max20335 @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +config REGULATOR_MAX20335 + bool "MAX20335 PMIC regulator driver" + default y + depends on DT_HAS_MAXIM_MAX20335_REGULATOR_ENABLED + select I2C + select MFD + help + Enable the Maxim MAX20335 PMIC regulator driver + +config REGULATOR_MAXIM_MAX20335_INIT_PRIORITY + int "MAX20335 regulator driver init priority" + default 86 + depends on REGULATOR_MAX20335 + help + Init priority for the Maxim MAX20335 regulator driver. diff --git a/drivers/regulator/regulator_max20335.c b/drivers/regulator/regulator_max20335.c new file mode 100644 index 00000000000..5395c1de699 --- /dev/null +++ b/drivers/regulator/regulator_max20335.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT maxim_max20335_regulator + +#include +#include +#include +#include +#include + +#define MAX20335_BUCK1_CFG 0x0DU +#define MAX20335_BUCK1_VSET 0x0EU +#define MAX20335_BUCK2_CFG 0x0FU +#define MAX20335_BUCK2_VSET 0x10U +#define MAX20335_BUCK12_CSET 0x11U +#define MAX20335_BUCK1_CSET_MASK 0xF0U +#define MAX20335_BUCK2_CSET_MASK 0x0FU +#define MAX20335_BUCK2_CSET_SHIFT 4 +#define MAX20335_BUCK_EN BIT(3) +#define MAX20335_BUCK_EN_MASK GENMASK(4, 3) + +#define MAX20335_LDO1_CFG 0x12U +#define MAX20335_LDO1_VSET 0x13U +#define MAX20335_LDO2_CFG 0x14U +#define MAX20335_LDO2_VSET 0x15U +#define MAX20335_LDO3_CFG 0x16U +#define MAX20335_LDO3_VSET 0x17U +#define MAX20335_LDO_MODE_MASK BIT(0) +#define MAX20335_LDO_EN BIT(1) +#define MAX20335_LDO_EN_MASK GENMASK(2, 1) + +enum max20335_pmic_sources { + MAX20335_PMIC_SOURCE_BUCK1, + MAX20335_PMIC_SOURCE_BUCK2, + MAX20335_PMIC_SOURCE_LDO1, + MAX20335_PMIC_SOURCE_LDO2, + MAX20335_PMIC_SOURCE_LDO3, +}; + +struct regulator_max20335_desc { + uint8_t vsel_reg; + uint8_t enable_mask; + uint8_t enable_val; + uint8_t cfg_reg; + const struct linear_range *uv_range; + const struct linear_range *ua_range; +}; + +struct regulator_max20335_config { + struct regulator_common_config common; + struct i2c_dt_spec bus; + const struct regulator_max20335_desc *desc; + uint8_t source; +}; + +struct regulator_max20335_data { + struct regulator_common_data common; +}; + +static const struct linear_range buck1_range = LINEAR_RANGE_INIT(700000, 25000U, 0x0U, 0x3FU); +static const struct linear_range buck2_range = LINEAR_RANGE_INIT(700000, 50000U, 0x0U, 0x3FU); +static const struct linear_range buck12_current_limit_range = + LINEAR_RANGE_INIT(50000, 25000U, 0x02U, 0x0FU); +static const struct linear_range ldo1_range = LINEAR_RANGE_INIT(800000, 100000U, 0x0U, 0x1CU); +static const struct linear_range ldo23_range = LINEAR_RANGE_INIT(900000, 100000U, 0x0U, 0x1FU); + +static const struct regulator_max20335_desc buck1_desc = { + .vsel_reg = MAX20335_BUCK1_VSET, + .enable_mask = MAX20335_BUCK_EN_MASK, + .enable_val = MAX20335_BUCK_EN, + .cfg_reg = MAX20335_BUCK1_CFG, + .uv_range = &buck1_range, + .ua_range = &buck12_current_limit_range, +}; + +static const struct regulator_max20335_desc buck2_desc = { + .vsel_reg = MAX20335_BUCK2_VSET, + .enable_mask = MAX20335_BUCK_EN_MASK, + .enable_val = MAX20335_BUCK_EN, + .cfg_reg = MAX20335_BUCK2_CFG, + .uv_range = &buck2_range, + .ua_range = &buck12_current_limit_range, +}; + +static const struct regulator_max20335_desc ldo1_desc = { + .vsel_reg = MAX20335_LDO1_VSET, + .enable_mask = MAX20335_LDO_EN_MASK, + .enable_val = MAX20335_LDO_EN, + .cfg_reg = MAX20335_LDO1_CFG, + .uv_range = &ldo1_range, +}; + +static const struct regulator_max20335_desc ldo2_desc = { + .vsel_reg = MAX20335_LDO2_VSET, + .enable_mask = MAX20335_LDO_EN_MASK, + .enable_val = MAX20335_LDO_EN, + .cfg_reg = MAX20335_LDO2_CFG, + .uv_range = &ldo23_range, +}; + +static const struct regulator_max20335_desc ldo3_desc = { + .vsel_reg = MAX20335_LDO3_VSET, + .enable_mask = MAX20335_LDO_EN_MASK, + .enable_val = MAX20335_LDO_EN, + .cfg_reg = MAX20335_LDO3_CFG, + .uv_range = &ldo23_range, +}; + +static int regulator_max20335_set_enable(const struct device *dev, bool enable) +{ + const struct regulator_max20335_config *config = dev->config; + + return i2c_reg_update_byte_dt(&config->bus, + config->desc->cfg_reg, + config->desc->enable_mask, + enable ? config->desc->enable_val : 0); +} + +static int regulator_max20335_enable(const struct device *dev) +{ + return regulator_max20335_set_enable(dev, true); +} + +static int regulator_max20335_disable(const struct device *dev) +{ + return regulator_max20335_set_enable(dev, false); +} + +static int regulator_max20335_set_mode(const struct device *dev, regulator_mode_t mode) +{ + const struct regulator_max20335_config *config = dev->config; + + if (mode > MAX20335_LOAD_SWITCH_MODE) { + return -ENOTSUP; + } + + switch (config->source) { + case MAX20335_PMIC_SOURCE_LDO1: + __fallthrough; + case MAX20335_PMIC_SOURCE_LDO2: + __fallthrough; + case MAX20335_PMIC_SOURCE_LDO3: + return i2c_reg_update_byte_dt(&config->bus, + config->desc->cfg_reg, + MAX20335_LDO_MODE_MASK, + mode); + default: + return -ENOTSUP; + } +} + +static unsigned int regulator_max20335_count_voltages(const struct device *dev) +{ + const struct regulator_max20335_config *config = dev->config; + + return linear_range_values_count(config->desc->uv_range); +} + +static int regulator_max20335_list_voltage(const struct device *dev, unsigned int idx, + int32_t *volt_uv) +{ + const struct regulator_max20335_config *config = dev->config; + + return linear_range_get_value(config->desc->uv_range, idx, volt_uv); +} + +static int regulator_max20335_set_buck_ldo_voltage(const struct device *dev, int32_t min_uv, + int32_t max_uv, const struct linear_range *range, + uint8_t vout_reg) +{ + const struct regulator_max20335_config *config = dev->config; + uint16_t idx; + int ret; + + ret = linear_range_get_win_index(range, min_uv, max_uv, &idx); + if (ret == -EINVAL) { + return ret; + } + + return i2c_reg_write_byte_dt(&config->bus, vout_reg, (uint8_t)idx); +} + +static int regulator_max20335_buck12_ldo123_get_voltage(const struct device *dev, + const struct linear_range *range, + uint8_t vout_reg, int32_t *volt_uv) +{ + const struct regulator_max20335_config *config = dev->config; + uint8_t idx; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, vout_reg, &idx); + if (ret < 0) { + return ret; + } + + return linear_range_get_value(range, idx, volt_uv); +} + +static int regulator_max20335_get_voltage(const struct device *dev, int32_t *volt_uv) +{ + const struct regulator_max20335_config *config = dev->config; + + return regulator_max20335_buck12_ldo123_get_voltage(dev, + config->desc->uv_range, + config->desc->vsel_reg, + volt_uv); +} + +static int regulator_max20335_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv) +{ + const struct regulator_max20335_config *config = dev->config; + + return regulator_max20335_set_buck_ldo_voltage(dev, + min_uv, + max_uv, + config->desc->uv_range, + config->desc->vsel_reg); +} + +static unsigned int regulator_max20335_count_current_limits(const struct device *dev) +{ + const struct regulator_max20335_config *config = dev->config; + + return linear_range_values_count(config->desc->ua_range); +} + +static int regulator_max20335_list_current_limit(const struct device *dev, unsigned int idx, + int32_t *current_ua) +{ + const struct regulator_max20335_config *config = dev->config; + + return linear_range_get_value(config->desc->ua_range, idx, current_ua); +} + +static int regulator_max20335_set_current_limit(const struct device *dev, + int32_t min_ua, + int32_t max_ua) +{ + const struct regulator_max20335_config *config = dev->config; + uint8_t val; + uint16_t idx; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_BUCK12_CSET, &val); + if (ret < 0) { + return ret; + } + + ret = linear_range_get_win_index(config->desc->ua_range, min_ua, max_ua, &idx); + if (ret == -EINVAL) { + return ret; + } + + switch (config->source) { + case MAX20335_PMIC_SOURCE_BUCK1: + val = idx | (val & MAX20335_BUCK1_CSET_MASK); + break; + case MAX20335_PMIC_SOURCE_BUCK2: + val = (idx << MAX20335_BUCK2_CSET_SHIFT) | (val & MAX20335_BUCK2_CSET_MASK); + break; + default: + return -ENOTSUP; + } + + return i2c_reg_write_byte_dt(&config->bus, MAX20335_BUCK12_CSET, val); +} + +static int regulator_max20335_init(const struct device *dev) +{ + const struct regulator_max20335_config *config = dev->config; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + regulator_common_data_init(dev); + + return regulator_common_init(dev, false); +} + +static const struct regulator_driver_api api = { + .enable = regulator_max20335_enable, + .disable = regulator_max20335_disable, + .set_mode = regulator_max20335_set_mode, + .count_voltages = regulator_max20335_count_voltages, + .list_voltage = regulator_max20335_list_voltage, + .set_voltage = regulator_max20335_set_voltage, + .get_voltage = regulator_max20335_get_voltage, + .count_current_limits = regulator_max20335_count_current_limits, + .list_current_limit = regulator_max20335_list_current_limit, + .set_current_limit = regulator_max20335_set_current_limit, +}; + +#define REGULATOR_MAX20335_DEFINE(node_id, id, child_name, _source) \ + static const struct regulator_max20335_config regulator_max20335_config_##id = { \ + .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ + .bus = I2C_DT_SPEC_GET(DT_GPARENT(node_id)), \ + .desc = &child_name##_desc, \ + .source = _source, \ + }; \ + \ + static struct regulator_max20335_data regulator_max20335_data_##id; \ + DEVICE_DT_DEFINE(node_id, regulator_max20335_init, NULL, \ + ®ulator_max20335_data_##id, \ + ®ulator_max20335_config_##id, \ + POST_KERNEL, \ + CONFIG_REGULATOR_MAXIM_MAX20335_INIT_PRIORITY, \ + &api); + +#define REGULATOR_MAX20335_DEFINE_COND(inst, child, source) \ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \ + (REGULATOR_MAX20335_DEFINE(DT_INST_CHILD(inst, child), \ + child##inst, child, source)), \ + ()) + +#define REGULATOR_MAX20335_DEFINE_ALL(inst) \ + REGULATOR_MAX20335_DEFINE_COND(inst, buck1, MAX20335_PMIC_SOURCE_BUCK1) \ + REGULATOR_MAX20335_DEFINE_COND(inst, buck2, MAX20335_PMIC_SOURCE_BUCK2) \ + REGULATOR_MAX20335_DEFINE_COND(inst, ldo1, MAX20335_PMIC_SOURCE_LDO1) \ + REGULATOR_MAX20335_DEFINE_COND(inst, ldo2, MAX20335_PMIC_SOURCE_LDO2) \ + REGULATOR_MAX20335_DEFINE_COND(inst, ldo3, MAX20335_PMIC_SOURCE_LDO3) + +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_MAX20335_DEFINE_ALL); diff --git a/dts/bindings/regulator/maxim,max20335-regulator.yaml b/dts/bindings/regulator/maxim,max20335-regulator.yaml new file mode 100644 index 00000000000..44086e0c4fa --- /dev/null +++ b/dts/bindings/regulator/maxim,max20335-regulator.yaml @@ -0,0 +1,49 @@ +# Copyright (c), 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +description: | + Maxim MAX20335 PMIC + + The PMIC has two buck converters and three LDOs. All need to be defined as + children nodes, strictly following the BUCK1..2, LDO1..3 node names. For + example: + + pmic@28 { + reg = <0x28>; + ... + regulators { + compatible = maxim,max20335-regulator"; + + BUCK1 { + /* all properties for BUCK1 */ + }; + BUCK2 { + /* all properties for BUCK2 */ + }; + LDO1 { + /* all properties for LDO1 */ + }; + LDO2 { + /* all properties for LDO2 */ + }; + LDO3 { + /* all properties for LDO3 */ + }; + }; + }; + +compatible: "maxim,max20335-regulator" + +include: base.yaml + +child-binding: + include: + - name: regulator.yaml + property-allowlist: + - regulator-always-on + - regulator-boot-on + - regulator-max-microamp + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-allowed-modes + - regulator-initial-mode diff --git a/include/zephyr/dt-bindings/regulator/max20335.h b/include/zephyr/dt-bindings/regulator/max20335.h new file mode 100644 index 00000000000..d7d23f03c96 --- /dev/null +++ b/include/zephyr/dt-bindings/regulator/max20335.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Grinn + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_MAX20335_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_MAX20335_H_ + +/** + * @defgroup regulator_max20335 MAX20335 Devicetree helpers. + * @ingroup regulator_interface + * @{ + */ + +/** + * @name MAX20335 Regulator modes + * @{ + */ +/** LDO mode */ +#define MAX20335_LDO_MODE 0 +/** Load switch mode */ +#define MAX20335_LOAD_SWITCH_MODE 1 +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_MAX20335_H_*/ diff --git a/tests/drivers/build_all/regulator/i2c.dtsi b/tests/drivers/build_all/regulator/i2c.dtsi index 12988303a61..82668e03492 100644 --- a/tests/drivers/build_all/regulator/i2c.dtsi +++ b/tests/drivers/build_all/regulator/i2c.dtsi @@ -75,3 +75,18 @@ axp192@4 { LDO3 {}; }; }; + +max20335@5 { + compatible = "maxim,max20335"; + reg = <0x5>; + + regulators { + compatible = "maxim,max20335-regulator"; + + BUCK1 {}; + BUCK2 {}; + LDO1 {}; + LDO2 {}; + LDO3 {}; + }; +}; From 979f8ebead4f85b99826bdb2ba5db3067d8af873 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 13:22:39 +0100 Subject: [PATCH 2942/4498] Bluetooth samples: unicast audio: Add support for simulated nrf5x Add support for the simulated nrf5340 and nrf52 in these samples. And enable building in twister both for these and for the already supported nrf5340dk. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/unicast_audio_client/boards/nrf52_bsim.conf | 5 +++++ .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 5 +++++ .../boards/nrf5340bsim_nrf5340_cpunet.conf | 8 ++++++++ samples/bluetooth/unicast_audio_client/sample.yaml | 3 +++ .../bluetooth/unicast_audio_server/boards/nrf52_bsim.conf | 5 +++++ .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 5 +++++ .../boards/nrf5340bsim_nrf5340_cpunet.conf | 5 +++++ samples/bluetooth/unicast_audio_server/sample.yaml | 3 +++ 8 files changed, 39 insertions(+) create mode 100644 samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf create mode 100644 samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf create mode 100644 samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf create mode 100644 samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf create mode 100644 samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf create mode 100644 samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf b/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf new file mode 100644 index 00000000000..db5d16058b6 --- /dev/null +++ b/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf @@ -0,0 +1,5 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..db5d16058b6 --- /dev/null +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1,5 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..f968b64c424 --- /dev/null +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1,8 @@ +# This configuration overlay is used when the controller, host and application are built +# all together in the network core + +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/sample.yaml b/samples/bluetooth/unicast_audio_client/sample.yaml index 9ca15182f52..fd1a74f60e2 100644 --- a/samples/bluetooth/unicast_audio_client/sample.yaml +++ b/samples/bluetooth/unicast_audio_client/sample.yaml @@ -7,6 +7,8 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - nrf5340bsim_nrf5340_cpuapp + - nrf5340dk_nrf5340_cpuapp tags: bluetooth integration_platforms: - qemu_cortex_m3 @@ -17,6 +19,7 @@ tests: - qemu_x86 - nrf52_bsim - nrf52dk_nrf52832 + - nrf52840dk_nrf52840 integration_platforms: - nrf52dk_nrf52832 extra_args: OVERLAY_CONFIG=overlay-bt_ll_sw_split.conf diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf b/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf new file mode 100644 index 00000000000..db5d16058b6 --- /dev/null +++ b/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf @@ -0,0 +1,5 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..db5d16058b6 --- /dev/null +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1,5 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..db5d16058b6 --- /dev/null +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1,5 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/sample.yaml b/samples/bluetooth/unicast_audio_server/sample.yaml index afb93362d1e..7194cb0ea80 100644 --- a/samples/bluetooth/unicast_audio_server/sample.yaml +++ b/samples/bluetooth/unicast_audio_server/sample.yaml @@ -7,6 +7,8 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - nrf5340bsim_nrf5340_cpuapp + - nrf5340dk_nrf5340_cpuapp tags: bluetooth integration_platforms: - qemu_cortex_m3 @@ -17,6 +19,7 @@ tests: - qemu_x86 - nrf52_bsim - nrf52dk_nrf52832 + - nrf52840dk_nrf52840 integration_platforms: - nrf52dk_nrf52832 extra_args: OVERLAY_CONFIG=overlay-bt_ll_sw_split.conf From ea8d18f742b880ed70311b496c1a98f0d9f470c5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 13:55:58 +0100 Subject: [PATCH 2943/4498] Bluetooth samples: unicast audio client: Add sysbuild support So that for both the simulated nrf5340 and real HW nrf5340dk we build both network and application core images. Signed-off-by: Alberto Escolar Piedras --- .../unicast_audio_client/Kconfig.sysbuild | 9 ++++ .../unicast_audio_client/sample.yaml | 1 + .../unicast_audio_client/sysbuild.cmake | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 samples/bluetooth/unicast_audio_client/Kconfig.sysbuild create mode 100644 samples/bluetooth/unicast_audio_client/sysbuild.cmake diff --git a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild new file mode 100644 index 00000000000..7955ce2a96d --- /dev/null +++ b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/bluetooth/unicast_audio_client/sample.yaml b/samples/bluetooth/unicast_audio_client/sample.yaml index fd1a74f60e2..5b4ad850a66 100644 --- a/samples/bluetooth/unicast_audio_client/sample.yaml +++ b/samples/bluetooth/unicast_audio_client/sample.yaml @@ -12,6 +12,7 @@ tests: tags: bluetooth integration_platforms: - qemu_cortex_m3 + sysbuild: true sample.bluetooth.audio_unicast_client.bt_ll_sw_split: harness: bluetooth platform_allow: diff --git a/samples/bluetooth/unicast_audio_client/sysbuild.cmake b/samples/bluetooth/unicast_audio_client/sysbuild.cmake new file mode 100644 index 00000000000..c150913cc55 --- /dev/null +++ b/samples/bluetooth/unicast_audio_client/sysbuild.cmake @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + + if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + endif() +endif() + +if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From cbe1025bf96bbcd3d1babb94335df4c42c936b04 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 13:58:00 +0100 Subject: [PATCH 2944/4498] Bluetooth samples: unicast audio server: Add sysbuild support So that for both the simulated nrf5340 and real HW nrf5340dk we build both network and application core images. Signed-off-by: Alberto Escolar Piedras --- .../unicast_audio_server/Kconfig.sysbuild | 9 ++++ .../unicast_audio_server/sample.yaml | 1 + .../unicast_audio_server/sysbuild.cmake | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 samples/bluetooth/unicast_audio_server/Kconfig.sysbuild create mode 100644 samples/bluetooth/unicast_audio_server/sysbuild.cmake diff --git a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild new file mode 100644 index 00000000000..7955ce2a96d --- /dev/null +++ b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/bluetooth/unicast_audio_server/sample.yaml b/samples/bluetooth/unicast_audio_server/sample.yaml index 7194cb0ea80..3e645878e8b 100644 --- a/samples/bluetooth/unicast_audio_server/sample.yaml +++ b/samples/bluetooth/unicast_audio_server/sample.yaml @@ -12,6 +12,7 @@ tests: tags: bluetooth integration_platforms: - qemu_cortex_m3 + sysbuild: true sample.bluetooth.audio_unicast_server.bt_ll_sw_split: harness: bluetooth platform_allow: diff --git a/samples/bluetooth/unicast_audio_server/sysbuild.cmake b/samples/bluetooth/unicast_audio_server/sysbuild.cmake new file mode 100644 index 00000000000..c150913cc55 --- /dev/null +++ b/samples/bluetooth/unicast_audio_server/sysbuild.cmake @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + + if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + endif() +endif() + +if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From 2ffe02b2d96085928bc384799b5d6ef051ba455d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 14:59:50 +0100 Subject: [PATCH 2945/4498] Bluetooth samples: unicast: Fix configuration for nrf5340 Provide a configuration for the sample we can use by default with the ISO capable hci_rpmsg controller sample. Signed-off-by: Alberto Escolar Piedras --- .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 7 +++++++ .../boards/nrf5340dk_nrf5340_cpuapp.conf | 7 +++++++ .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 7 +++++++ .../boards/nrf5340dk_nrf5340_cpuapp.conf | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf index db5d16058b6..ea84975beb0 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -3,3 +3,10 @@ CONFIG_FPU=y CONFIG_LIBLC3=y # LC3 lib requires floating point support in the c-lib. CONFIG_REQUIRES_FULL_LIBC=y + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..68da448963a 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -6,3 +6,10 @@ CONFIG_LIBLC3=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 # LC3 lib requires floating point support in the c-lib. CONFIG_REQUIRES_FULL_LIBC=y + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf index db5d16058b6..ea84975beb0 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -3,3 +3,10 @@ CONFIG_FPU=y CONFIG_LIBLC3=y # LC3 lib requires floating point support in the c-lib. CONFIG_REQUIRES_FULL_LIBC=y + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..68da448963a 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -6,3 +6,10 @@ CONFIG_LIBLC3=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 # LC3 lib requires floating point support in the c-lib. CONFIG_REQUIRES_FULL_LIBC=y + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +CONFIG_BT_TINYCRYPT_ECC=y From 4368765e3c7dfe4b3e9a139fc4aea23b92b69060 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 15:32:54 +0100 Subject: [PATCH 2946/4498] Bluetooth samples: unicast server: L2CAP configuration workaround Due to this bug: https://github.com/zephyrproject-rtos/zephyr/issues/64574 We need to increase the number of L2CAP Tx Buffers so this sample can be used. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_server/prj.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/bluetooth/unicast_audio_server/prj.conf b/samples/bluetooth/unicast_audio_server/prj.conf index 3aec74ddbcc..6fd0c501585 100644 --- a/samples/bluetooth/unicast_audio_server/prj.conf +++ b/samples/bluetooth/unicast_audio_server/prj.conf @@ -14,3 +14,7 @@ CONFIG_BT_ATT_PREPARE_COUNT=1 CONFIG_BT_EXT_ADV=y CONFIG_BT_DEVICE_NAME="Unicast Audio Server" + +# Due to https://github.com/zephyrproject-rtos/zephyr/issues/64574 we need to increase the number +# of L2CAP buffers +CONFIG_BT_L2CAP_TX_BUF_COUNT=4 From a0ed29409b0574ed025390833894123f9777b105 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 30 Oct 2023 16:01:24 +0100 Subject: [PATCH 2947/4498] tests bsim: Add tests for unicast client/server samples Add a test based on the unicase client/server samples which runs them together and after waiting for a predefined amount of time, checks how many audio packets has the client received, and if over a threshold, passes the test. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/unicast_audio_client/src/main.c | 6 +- tests/bsim/bluetooth/audio_samples/compile.sh | 37 +++++++++ .../unicast_audio_client/CMakeLists.txt | 24 ++++++ .../unicast_audio_client/Kconfig.sysbuild | 10 +++ .../boards/nrf52_bsim.conf | 7 ++ .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 14 ++++ .../boards/nrf5340bsim_nrf5340_cpunet.conf | 7 ++ .../unicast_audio_client/prj.conf | 16 ++++ .../unicast_audio_client/src/test_main.c | 14 ++++ .../src/unicast_client_sample_test.c | 77 +++++++++++++++++++ .../unicast_audio_client/sysbuild.cmake | 13 ++++ .../tests_scripts/unicast_client.sh | 29 +++++++ .../compile.nrf5340bsim_nrf5340_cpuapp.sh | 2 + tests/bsim/bluetooth/compile.sh | 1 + .../tests.nrf5340bsim_nrf5340_cpuapp.txt | 1 + 15 files changed, 257 insertions(+), 1 deletion(-) create mode 100755 tests/bsim/bluetooth/audio_samples/compile.sh create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/Kconfig.sysbuild create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/prj.conf create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/test_main.c create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/unicast_client_sample_test.c create mode 100644 tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake create mode 100755 tests/bsim/bluetooth/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index 1dc411f7b59..3953bee99f0 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -19,6 +19,8 @@ static void start_scan(void); +uint64_t unicast_audio_recv_ctr; /* This value is exposed to test code */ + static struct bt_bap_unicast_client_cb unicast_client_cbs; static struct bt_conn *default_conn; static struct k_work_delayable audio_send_work; @@ -564,7 +566,9 @@ static void stream_recv(struct bt_bap_stream *stream, struct net_buf *buf) { if (info->flags & BT_ISO_FLAGS_VALID) { - printk("Incoming audio on stream %p len %u\n", stream, buf->len); + unicast_audio_recv_ctr++; + printk("Incoming audio on stream %p len %u (%"PRIu64")\n", stream, buf->len, + unicast_audio_recv_ctr); } } diff --git a/tests/bsim/bluetooth/audio_samples/compile.sh b/tests/bsim/bluetooth/audio_samples/compile.sh new file mode 100755 index 00000000000..e41f4f9781d --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/compile.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Compile all the applications needed by the bsim tests in these subfolders + +#set -x #uncomment this line for debugging +set -ue + +: "${BSIM_COMPONENTS_PATH:?BSIM_COMPONENTS_PATH must be defined}" +: "${ZEPHYR_BASE:?ZEPHYR_BASE must be set to point to the zephyr root\ + directory}" + +WORK_DIR="${WORK_DIR:-${ZEPHYR_BASE}/bsim_out}" + +BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}" + +mkdir -p ${WORK_DIR} + +source ${ZEPHYR_BASE}/tests/bsim/compile.source + +if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then + app=samples/bluetooth/unicast_audio_server sysbuild=1 compile +else + app=samples/bluetooth/unicast_audio_server conf_overlay=overlay-bt_ll_sw_split.conf \ + exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile +fi + +if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then + app=tests/bsim/bluetooth/audio_samples/unicast_audio_client sysbuild=1 compile +else + app=tests/bsim/bluetooth/audio_samples/unicast_audio_client \ + conf_overlay=${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/overlay-bt_ll_sw_split.conf \ + exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile +fi + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/CMakeLists.txt b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/CMakeLists.txt new file mode 100644 index 00000000000..1afb5029b33 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/CMakeLists.txt @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(unicast_audio_client_self_tets) + +set(unicast_client_path ${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client) + +target_sources(app PRIVATE + ${unicast_client_path}/src/main.c +) + +target_sources(app PRIVATE + src/unicast_client_sample_test.c + src/test_main.c +) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/Kconfig.sysbuild b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/Kconfig.sysbuild new file mode 100644 index 00000000000..4e7f66926c2 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf new file mode 100644 index 00000000000..664b1b5e238 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf @@ -0,0 +1,7 @@ +# This file content is just a copy of the equivalent one in the unicast client sample + +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..b7166971871 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1,14 @@ +# This file content is just a copy of the equivalent one in the unicast client sample + +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf new file mode 100644 index 00000000000..664b1b5e238 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -0,0 +1,7 @@ +# This file content is just a copy of the equivalent one in the unicast client sample + +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y +# LC3 lib requires floating point support in the c-lib. +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/prj.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/prj.conf new file mode 100644 index 00000000000..c7385ae8cda --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/prj.conf @@ -0,0 +1,16 @@ +# This file content is just a copy of the unicast client sample prj.conf + +CONFIG_BT=y +CONFIG_LOG=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_AUDIO=y +CONFIG_BT_BAP_UNICAST_CLIENT=y +CONFIG_BT_ISO_TX_BUF_COUNT=4 +# Support an ISO channel per ASE +CONFIG_BT_ISO_MAX_CHAN=4 +CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4 +CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2 +CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2 +CONFIG_BT_KEYS_OVERWRITE_OLDEST=y + +CONFIG_BT_EXT_ADV=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/test_main.c b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/test_main.c new file mode 100644 index 00000000000..dbba2106b19 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/test_main.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" + +extern struct bst_test_list *test_unicast_client_sample_install(struct bst_test_list *tests); + +bst_test_install_t test_installers[] = { + test_unicast_client_sample_install, + NULL +}; diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/unicast_client_sample_test.c b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/unicast_client_sample_test.c new file mode 100644 index 00000000000..729e4267b7c --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/src/unicast_client_sample_test.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2017-2019 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_types.h" +#include "bs_tracing.h" +#include "bs_utils.h" +#include "time_machine.h" +#include "bstests.h" + +#define WAIT_TIME 10 /* Seconds */ + +#define PASS_THRESHOLD 100 /* Audio packets */ + +extern enum bst_result_t bst_result; + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +static void test_unicast_client_sample_init(void) +{ + /* We set an absolute deadline in 30 seconds */ + bst_ticker_set_next_tick_absolute(WAIT_TIME*1e6); + bst_result = In_progress; +} + +static void test_unicast_client_sample_tick(bs_time_t HW_device_time) +{ + /* + * If in WAIT_TIME seconds we did not get enough packets through + * we consider the test failed + */ + + extern uint64_t unicast_audio_recv_ctr; + + bs_trace_info_time(2, "%"PRIu64" packets received, expected >= %i\n", + unicast_audio_recv_ctr, PASS_THRESHOLD); + + if (unicast_audio_recv_ctr >= PASS_THRESHOLD) { + PASS("unicast_client PASSED\n"); + bs_trace_exit("Done, disconnecting from simulation\n"); + } else { + FAIL("unicast_client FAILED (Did not pass after %i seconds)\n", + WAIT_TIME); + } +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "unicast_client", + .test_descr = "Test based on the unicast client sample. " + "It expects to be connected to a compatible unicast server, " + "waits for " STR(WAIT_TIME) " seconds, and checks how " + "many audio packets have been received correctly", + .test_post_init_f = test_unicast_client_sample_init, + .test_tick_f = test_unicast_client_sample_tick, + }, + BSTEST_END_MARKER +}; + +struct bst_test_list *test_unicast_client_sample_install(struct bst_test_list *tests) +{ + tests = bst_add_tests(tests, test_sample); + return tests; +} diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake new file mode 100644 index 00000000000..9686cde1bce --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/sysbuild.cmake) + +if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) +endif() diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh new file mode 100755 index 00000000000..cc92cda1328 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Simple selfchecking test for the unicast client/server samples, +# It relies on the bs_tests hooks to register a test timer callback, which after a deadline +# will check how many audio packets the unicast client has received, and if over a threshold +# it considers the test passed + +simulation_id="unicast_samples_test" +verbosity_level=2 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +EXECUTE_TIMEOUT=100 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_samples_bluetooth_unicast_audio_server_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_samples_unicast_audio_client_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \ + -testid=unicast_client + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs #Wait for all programs in background and return != 0 if any fails diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh index ddb8349ff53..4f175540347 100755 --- a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh @@ -22,4 +22,6 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/bis sysbuild=1 compile +run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh + wait_for_background_jobs diff --git a/tests/bsim/bluetooth/compile.sh b/tests/bsim/bluetooth/compile.sh index 016437aed73..b6b709f84d2 100755 --- a/tests/bsim/bluetooth/compile.sh +++ b/tests/bsim/bluetooth/compile.sh @@ -24,6 +24,7 @@ source ${ZEPHYR_BASE}/tests/bsim/sh_common.source # On the other hand the audio compile script, only builds one image. So we parallelize it with # the rest to save a couple of seconds. run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio/compile.sh +${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/compile.sh ${ZEPHYR_BASE}/tests/bsim/bluetooth/ll/compile.sh ${ZEPHYR_BASE}/tests/bsim/bluetooth/mesh/compile.sh diff --git a/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt index 147b55103fc..27a1fc4a76f 100644 --- a/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt +++ b/tests/bsim/bluetooth/tests.nrf5340bsim_nrf5340_cpuapp.txt @@ -2,3 +2,4 @@ # This file is used in CI to select which tests are run tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn_encrypted_split_privacy.sh tests/bsim/bluetooth/ll/bis/tests_scripts/broadcast_iso.sh +tests/bsim/bluetooth/audio_samples/ From d561548863e6c32bd4629d17c5e42ade54c65260 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 31 Oct 2023 14:45:45 +0100 Subject: [PATCH 2948/4498] Bluetooth samples: unicast audio: Improve documentation With examples of how to build for several boards Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/unicast_audio_client/README.rst | 67 ++++++++++++++++-- .../bluetooth/unicast_audio_server/README.rst | 68 +++++++++++++++++-- 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/samples/bluetooth/unicast_audio_client/README.rst b/samples/bluetooth/unicast_audio_client/README.rst index dc3b336d9a3..3735aff4ebd 100644 --- a/samples/bluetooth/unicast_audio_client/README.rst +++ b/samples/bluetooth/unicast_audio_client/README.rst @@ -9,6 +9,10 @@ Overview Application demonstrating the LE Audio unicast client functionality. Scans for and connects to a LE Audio unicast server and establishes an audio stream. +This sample can be found under +:zephyr_file:`samples/bluetooth/unicast_audio_client` in the Zephyr tree. + +Check the :ref:`bluetooth samples section ` for general information. Requirements ************ @@ -18,9 +22,62 @@ Requirements Building and Running ******************** -This sample can be found under -:zephyr_file:`samples/bluetooth/unicast_audio_client` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO -feature support in Zephyr Bluetooth Controller on supported boards. -See :ref:`bluetooth samples section ` for details. +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable the required ISO +feature support. + +Building for an nrf52840dk +-------------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_client/ + :board: nrf52840dk_nrf52840 + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_client/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + +In that case you can pair this application core image with the +:ref:`hci_ipc sample ` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf52_bsim +----------------------------------- + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_client/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + +Note this will produce a Linux executable in `./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf5340bsim +------------------------------------ + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_client/ + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild diff --git a/samples/bluetooth/unicast_audio_server/README.rst b/samples/bluetooth/unicast_audio_server/README.rst index ce7151e5fb7..79a06244839 100644 --- a/samples/bluetooth/unicast_audio_server/README.rst +++ b/samples/bluetooth/unicast_audio_server/README.rst @@ -9,6 +9,11 @@ Overview Application demonstrating the LE Audio unicast server functionality. Starts advertising and awaits connection from a LE Audio unicast client. +This sample can be found under +:zephyr_file:`samples/bluetooth/unicast_audio_server` in the Zephyr tree. + +Check the :ref:`bluetooth samples section ` for general information. + Requirements ************ @@ -17,9 +22,62 @@ Requirements Building and Running ******************** -This sample can be found under -:zephyr_file:`samples/bluetooth/unicast_audio_server` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO -feature support in Zephyr Bluetooth Controller on supported boards. -See :ref:`bluetooth samples section ` for details. +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable the required ISO +feature support. + +Building for an nrf52840dk +-------------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf52840dk_nrf52840 + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + +In that case you can pair this application core image with the +:ref:`hci_ipc sample ` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf52_bsim +----------------------------------- + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + +Note this will produce a Linux executable in `./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf5340bsim +------------------------------------ + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/unicast_audio_server/ + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild From 942923edaf1ab29b717c41719578dc1d1b0d3e76 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 31 Oct 2023 16:45:56 +0100 Subject: [PATCH 2949/4498] Bluetooth samples: unicast audio: Provide configuration for native_sim Provide configuration for native_sim instead of native_posix and enable it in the samples.yaml native_posix is being deprecated in favour of native_sim. Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.conf => native_sim.conf} | 0 samples/bluetooth/unicast_audio_client/sample.yaml | 1 + .../boards/{native_posix.conf => native_sim.conf} | 0 samples/bluetooth/unicast_audio_server/sample.yaml | 1 + 4 files changed, 2 insertions(+) rename samples/bluetooth/unicast_audio_client/boards/{native_posix.conf => native_sim.conf} (100%) rename samples/bluetooth/unicast_audio_server/boards/{native_posix.conf => native_sim.conf} (100%) diff --git a/samples/bluetooth/unicast_audio_client/boards/native_posix.conf b/samples/bluetooth/unicast_audio_client/boards/native_sim.conf similarity index 100% rename from samples/bluetooth/unicast_audio_client/boards/native_posix.conf rename to samples/bluetooth/unicast_audio_client/boards/native_sim.conf diff --git a/samples/bluetooth/unicast_audio_client/sample.yaml b/samples/bluetooth/unicast_audio_client/sample.yaml index 5b4ad850a66..5e98d3d0df8 100644 --- a/samples/bluetooth/unicast_audio_client/sample.yaml +++ b/samples/bluetooth/unicast_audio_client/sample.yaml @@ -9,6 +9,7 @@ tests: - qemu_x86 - nrf5340bsim_nrf5340_cpuapp - nrf5340dk_nrf5340_cpuapp + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/unicast_audio_server/boards/native_posix.conf b/samples/bluetooth/unicast_audio_server/boards/native_sim.conf similarity index 100% rename from samples/bluetooth/unicast_audio_server/boards/native_posix.conf rename to samples/bluetooth/unicast_audio_server/boards/native_sim.conf diff --git a/samples/bluetooth/unicast_audio_server/sample.yaml b/samples/bluetooth/unicast_audio_server/sample.yaml index 3e645878e8b..280edd44f84 100644 --- a/samples/bluetooth/unicast_audio_server/sample.yaml +++ b/samples/bluetooth/unicast_audio_server/sample.yaml @@ -9,6 +9,7 @@ tests: - qemu_x86 - nrf5340bsim_nrf5340_cpuapp - nrf5340dk_nrf5340_cpuapp + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 From ff064f6f59ea6caa8f86754a2a382b5147c9acff Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 31 Oct 2023 16:49:03 +0100 Subject: [PATCH 2950/4498] Bluetooth samples: unicast audio: Remove useless test targets Remove the qemu targets for the controller configuration. As those do not support the controller, it is just meaningless. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_client/sample.yaml | 2 -- samples/bluetooth/unicast_audio_server/sample.yaml | 2 -- 2 files changed, 4 deletions(-) diff --git a/samples/bluetooth/unicast_audio_client/sample.yaml b/samples/bluetooth/unicast_audio_client/sample.yaml index 5e98d3d0df8..be739bb5bb8 100644 --- a/samples/bluetooth/unicast_audio_client/sample.yaml +++ b/samples/bluetooth/unicast_audio_client/sample.yaml @@ -17,8 +17,6 @@ tests: sample.bluetooth.audio_unicast_client.bt_ll_sw_split: harness: bluetooth platform_allow: - - qemu_cortex_m3 - - qemu_x86 - nrf52_bsim - nrf52dk_nrf52832 - nrf52840dk_nrf52840 diff --git a/samples/bluetooth/unicast_audio_server/sample.yaml b/samples/bluetooth/unicast_audio_server/sample.yaml index 280edd44f84..063ab7ae41e 100644 --- a/samples/bluetooth/unicast_audio_server/sample.yaml +++ b/samples/bluetooth/unicast_audio_server/sample.yaml @@ -17,8 +17,6 @@ tests: sample.bluetooth.audio_unicast_server.bt_ll_sw_split: harness: bluetooth platform_allow: - - qemu_cortex_m3 - - qemu_x86 - nrf52_bsim - nrf52dk_nrf52832 - nrf52840dk_nrf52840 From 1f2ef32ad8276132c5c8b92f1f6c5934367aac7b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 31 Oct 2023 16:55:35 +0100 Subject: [PATCH 2951/4498] Bluetooth samples: unicast audio: Change integration_target Change the integration target to something more meaningfull, i.e. something users are more likely want to try it on, and therefore in which it is better to do more testing. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_client/sample.yaml | 2 +- samples/bluetooth/unicast_audio_server/sample.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/bluetooth/unicast_audio_client/sample.yaml b/samples/bluetooth/unicast_audio_client/sample.yaml index be739bb5bb8..76ff71f350b 100644 --- a/samples/bluetooth/unicast_audio_client/sample.yaml +++ b/samples/bluetooth/unicast_audio_client/sample.yaml @@ -12,7 +12,7 @@ tests: - native_sim tags: bluetooth integration_platforms: - - qemu_cortex_m3 + - nrf5340dk_nrf5340_cpuapp sysbuild: true sample.bluetooth.audio_unicast_client.bt_ll_sw_split: harness: bluetooth diff --git a/samples/bluetooth/unicast_audio_server/sample.yaml b/samples/bluetooth/unicast_audio_server/sample.yaml index 063ab7ae41e..0c7496e288b 100644 --- a/samples/bluetooth/unicast_audio_server/sample.yaml +++ b/samples/bluetooth/unicast_audio_server/sample.yaml @@ -12,7 +12,7 @@ tests: - native_sim tags: bluetooth integration_platforms: - - qemu_cortex_m3 + - nrf5340dk_nrf5340_cpuapp sysbuild: true sample.bluetooth.audio_unicast_server.bt_ll_sw_split: harness: bluetooth From 2ff4ae6a252e050da1c84588bfeaeb25629a223a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 16:08:18 +0100 Subject: [PATCH 2952/4498] Bluetooth samples: unicast audio: Add nrf5340_audio_dk to sysbuild Add support for the nrf5340_audio_dk to the sysbuild files Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/unicast_audio_client/Kconfig.sysbuild | 1 + samples/bluetooth/unicast_audio_server/Kconfig.sysbuild | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild index 7955ce2a96d..37a6b66c7f4 100644 --- a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild @@ -6,4 +6,5 @@ source "share/sysbuild/Kconfig" config NET_CORE_BOARD string default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild index 7955ce2a96d..37a6b66c7f4 100644 --- a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild @@ -6,4 +6,5 @@ source "share/sysbuild/Kconfig" config NET_CORE_BOARD string default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" From 30c36525efe443d4547680382e69fcd627ce0da7 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Thu, 26 Oct 2023 09:47:55 +0200 Subject: [PATCH 2953/4498] Doc: Bluetooth: Mesh: Specify RPR Server limitations Specifies RPR Server limitations. Signed-off-by: Omkar Kulkarni --- doc/connectivity/bluetooth/api/mesh/dfu.rst | 2 ++ doc/connectivity/bluetooth/api/mesh/rpr_srv.rst | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 46d3cfb6dc3..9cf55e244d6 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -184,6 +184,8 @@ Firmware URI The out-of-band distribution mechanism is not supported. +.. _bluetooth_mesh_dfu_firmware_effect: + Firmware effect --------------- diff --git a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst index 63c159cd2b0..e51d3c8fac9 100644 --- a/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/rpr_srv.rst @@ -21,6 +21,15 @@ Note that after refreshing the device key, node address or Composition Data thro Provisioning Protocol Interface (NPPI) procedure, the :c:member:`bt_mesh_prov.reprovisioned` callback is triggered. See section :ref:`bluetooth_mesh_models_rpr_cli` for further details. +Limitations +----------- + +The following limitations apply to Remote Provisioning Server model: + +* Provisioning of unprovisioned device using PB-GATT is not supported. +* All Node Provisioning Protocol Interface (NPPI) procedures are supported. However, if the composition data of a device gets changed after device firmware update (see :ref:`firmware effect `), it is not possible for the device to remain provisioned. The device should be unprovisioned if its composition data is expected to change. + + API reference ************* From 1b34884d8133562ba4b10fb04a82e2bce49cbc04 Mon Sep 17 00:00:00 2001 From: Benjamin Lucke Date: Tue, 31 Oct 2023 07:20:05 +0100 Subject: [PATCH 2954/4498] Bluetooth: TBS: Fixed return call_index 0 after overflow Fixed range of call_index 1 to 255, since 0 is reserved for outgoing calls. Signed-off-by: Benjamin Lucke --- subsys/bluetooth/audio/tbs.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/audio/tbs.c b/subsys/bluetooth/audio/tbs.c index 9159d2b2324..86588c11c71 100644 --- a/subsys/bluetooth/audio/tbs.c +++ b/subsys/bluetooth/audio/tbs.c @@ -307,18 +307,21 @@ static void tbs_set_terminate_reason(struct tbs_service_inst *inst, static uint8_t next_free_call_index(void) { for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) { - static uint8_t next_call_index = 1; - const struct bt_tbs_call *call = lookup_call(next_call_index); - - if (call == NULL) { - return next_call_index++; - } + static uint8_t next_call_index; + const struct bt_tbs_call *call; + /* For each new call, the call index should be incremented */ next_call_index++; - if (next_call_index == UINT8_MAX) { + + if (next_call_index == BT_TBS_FREE_CALL_INDEX) { /* call_index = 0 reserved for outgoing calls */ next_call_index = 1; } + + call = lookup_call(next_call_index); + if (call == NULL) { + return next_call_index; + } } LOG_DBG("No more free call spots"); From bd498178d32be00584d838ae9a49c5668930ec16 Mon Sep 17 00:00:00 2001 From: Michele Imbriani Date: Tue, 31 Oct 2023 14:10:47 +0100 Subject: [PATCH 2955/4498] bluetooth: audio: added support for 24kHz frequency to broadcast source Added option to support 24kHz frequency for broadcast_sample_source Signed-off-by: Michele Imbriani --- .../bluetooth/broadcast_audio_source/Kconfig | 22 +++++++++++++++++ .../broadcast_audio_source/src/main.c | 24 +++++++++++++------ 2 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 samples/bluetooth/broadcast_audio_source/Kconfig diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig b/samples/bluetooth/broadcast_audio_source/Kconfig new file mode 100644 index 00000000000..91cca49cc07 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/Kconfig @@ -0,0 +1,22 @@ +# Copyright (c) 2023 Demant A/S +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Bluetooth: Broadcast Audio Source" + +choice BAP_LC3_PRESET + prompt "The BAP LC3 Preset to be used" + default BAP_BROADCAST_16_2_1 + +config BAP_BROADCAST_16_2_1 + bool "BAP_LC3_BROADCAST_PRESET_16_2_1 preset" + help + Using the BAP_LC3_BROADCAST_PRESET_16_2_1 preset. + +config BAP_BROADCAST_24_2_1 + bool "BAP_LC3_BROADCAST_PRESET_24_2_1 preset" + help + Using the BAP_LC3_BROADCAST_PRESET_24_2_1 preset. + +endchoice + +source "Kconfig.zephyr" diff --git a/samples/bluetooth/broadcast_audio_source/src/main.c b/samples/bluetooth/broadcast_audio_source/src/main.c index 6dc853f2d6d..f9a2a5330b2 100644 --- a/samples/bluetooth/broadcast_audio_source/src/main.c +++ b/samples/bluetooth/broadcast_audio_source/src/main.c @@ -32,8 +32,18 @@ BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED, "CONFIG_BT_ISO_TX_BUF_COUNT should be at least " "BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT"); -static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( +#if defined(CONFIG_BAP_BROADCAST_16_2_1) + +static struct bt_bap_lc3_preset preset_active = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +#elif defined(CONFIG_BAP_BROADCAST_24_2_1) + +static struct bt_bap_lc3_preset preset_active = BT_BAP_LC3_BROADCAST_PRESET_24_2_1( BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +#endif + static struct broadcast_source_stream { struct bt_bap_stream stream; uint16_t seq_num; @@ -70,7 +80,7 @@ static int octets_per_frame; static void init_lc3(void) { - const struct bt_audio_codec_cfg *codec_cfg = &preset_16_2_1.codec_cfg; + const struct bt_audio_codec_cfg *codec_cfg = &preset_active.codec_cfg; int ret; ret = bt_audio_codec_cfg_get_freq(codec_cfg); @@ -152,7 +162,7 @@ static void stream_sent_cb(struct bt_bap_stream *stream) net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); #if defined(CONFIG_LIBLC3) int lc3_ret; - uint8_t lc3_encoder_buffer[preset_16_2_1.qos.sdu]; + uint8_t lc3_encoder_buffer[preset_active.qos.sdu]; if (lc3_encoder == NULL) { printk("LC3 encoder not setup, cannot encode data.\n"); @@ -167,9 +177,9 @@ static void stream_sent_cb(struct bt_bap_stream *stream) return; } - net_buf_add_mem(buf, lc3_encoder_buffer, preset_16_2_1.qos.sdu); + net_buf_add_mem(buf, lc3_encoder_buffer, preset_active.qos.sdu); #else - net_buf_add_mem(buf, mock_data, preset_16_2_1.qos.sdu); + net_buf_add_mem(buf, mock_data, preset_active.qos.sdu); #endif /* defined(CONFIG_LIBLC3) */ ret = bt_bap_stream_send(stream, buf, source_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); @@ -207,7 +217,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) for (size_t i = 0U; i < ARRAY_SIZE(subgroup_param); i++) { subgroup_param[i].params_count = streams_per_subgroup; subgroup_param[i].params = stream_params + i * streams_per_subgroup; - subgroup_param[i].codec_cfg = &preset_16_2_1.codec_cfg; + subgroup_param[i].codec_cfg = &preset_active.codec_cfg; } for (size_t j = 0U; j < ARRAY_SIZE(stream_params); j++) { @@ -219,7 +229,7 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) create_param.params_count = ARRAY_SIZE(subgroup_param); create_param.params = subgroup_param; - create_param.qos = &preset_16_2_1.qos; + create_param.qos = &preset_active.qos; create_param.encryption = false; create_param.packing = BT_ISO_PACKING_SEQUENTIAL; From 8bccb645aae8a9c09a062d28ed22fc61b987381d Mon Sep 17 00:00:00 2001 From: Mateusz Junkier Date: Tue, 31 Oct 2023 17:35:56 +0100 Subject: [PATCH 2956/4498] boards: intel_adsp: fix board flashing add missing declarations to work with ace15 board Signed-off-by: Mateusz Junkier --- boards/xtensa/intel_adsp_ace15_mtpm/board.cmake | 2 ++ scripts/west_commands/runners/intel_adsp.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/boards/xtensa/intel_adsp_ace15_mtpm/board.cmake b/boards/xtensa/intel_adsp_ace15_mtpm/board.cmake index 0948dfc49ef..63777239a1d 100644 --- a/boards/xtensa/intel_adsp_ace15_mtpm/board.cmake +++ b/boards/xtensa/intel_adsp_ace15_mtpm/board.cmake @@ -5,3 +5,5 @@ board_set_rimage_target(mtl) set(RIMAGE_SIGN_KEY "otc_private_key_3k.pem" CACHE STRING "default in ace15_mtpm/board.cmake") + +include(${ZEPHYR_BASE}/boards/common/intel_adsp.board.cmake) diff --git a/scripts/west_commands/runners/intel_adsp.py b/scripts/west_commands/runners/intel_adsp.py index cbaa106020d..18b1462ef05 100644 --- a/scripts/west_commands/runners/intel_adsp.py +++ b/scripts/west_commands/runners/intel_adsp.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -'''Runner for flashing with the Intel ADSP CAVS boards.''' +'''Runner for flashing with the Intel ADSP boards.''' import os import sys @@ -113,7 +113,7 @@ def do_run(self, command, **kwargs): if self.do_sign: self.sign(**kwargs) - if re.search("intel_adsp_cavs", self.platform): + if re.search("intel_adsp", self.platform): self.require(self.cavstool) self.flash(**kwargs) else: From 011adfa4ca0a044344ed043dc5bd319ad65d501e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 31 Oct 2023 20:38:57 +0100 Subject: [PATCH 2957/4498] modem: Add experimental tag The modem subsystem is novel and should therefore be marked experimental. Signed-off-by: Bjarki Arge Andreasen --- doc/develop/api/overview.rst | 4 ++++ subsys/modem/Kconfig | 1 + 2 files changed, 5 insertions(+) diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index 642d7b807c3..6572ab0f161 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -233,6 +233,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Stable - 1.11 + * - :ref:`modem` + - Experimental + - 3.5 + * - :ref:`mqtt_socket_interface` - Unstable - 1.14 diff --git a/subsys/modem/Kconfig b/subsys/modem/Kconfig index da992bf3760..69c102a07ad 100644 --- a/subsys/modem/Kconfig +++ b/subsys/modem/Kconfig @@ -3,6 +3,7 @@ menuconfig MODEM_MODULES bool "Modem modules" + select EXPERIMENTAL if MODEM_MODULES From dd4472c26ac92aba116744236e8dd51c47324e4f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 1 Nov 2023 15:57:42 +0000 Subject: [PATCH 2958/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 4a1effbc301fc302ecbaf40d4eb2be520b53010d Brings following Zephyr relevant fixes: - 4a1effbc zephyr: Remove deprecated ZEPHYR_TRY_MASS_ERASE option - 2b924da4 samples: zephyr: Use the default MCUBoot PEM key file - 25b7c7a8 imgtool: make "align" command line parameter optional - 301d5655 readme: update for next dev release - e0bdcdec Update version files for 2.0.0 - 9b92ee91 boot: zephyr: add support for LPC55Sxx Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 797315f7455..54581f55087 100644 --- a/west.yml +++ b/west.yml @@ -282,7 +282,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 13767d0b72eb14ce42eb8aad1e5a133ef66afc54 + revision: 4a1effbc301fc302ecbaf40d4eb2be520b53010d path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From f811a05044184288f0d11fea3d971d3d9b769525 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 1 Nov 2023 21:03:35 +0100 Subject: [PATCH 2959/4498] doc: releases: remove v3.3.0 from supported releases As of October 31, 2023, Zephyr v3.3.0 is no longer supported. Signed-off-by: Henrik Brix Andersen --- doc/conf.py | 1 - doc/releases/index.rst | 3 --- 2 files changed, 4 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 4c153e7a2e7..0f20f424f80 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -167,7 +167,6 @@ ("latest", "/"), ("3.5.0", "/3.5.0/"), ("3.4.0", "/3.4.0/"), - ("3.3.0", "/3.3.0/"), ("2.7.5 (LTS)", "/2.7.5/"), ), "display_gh_links": True, diff --git a/doc/releases/index.rst b/doc/releases/index.rst index c426aa2ca68..7a3540d227d 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -62,8 +62,6 @@ Supported Releases +-----------------+----------------+---------------+ | `Zephyr 3.4.0`_ | 2023-06-16 | 2024-02-29 | +-----------------+----------------+---------------+ -| `Zephyr 3.3.0`_ | 2023-02-19 | 2023-10-31 | -+-----------------+----------------+---------------+ As of 2022-01-01, LTS1 (1.14.x) is not supported and has reached end of life (EOL). @@ -95,6 +93,5 @@ users transition from the previous release. .. _`GitHub repository`: https://github.com/zephyrproject-rtos/zephyr .. _`GitHub tagged releases`: https://github.com/zephyrproject-rtos/zephyr/tags .. _`Zephyr 2.7.5`: https://docs.zephyrproject.org/2.7.5/ -.. _`Zephyr 3.3.0`: https://docs.zephyrproject.org/3.3.0/ .. _`Zephyr 3.4.0`: https://docs.zephyrproject.org/3.4.0/ .. _`Zephyr 3.5.0`: https://docs.zephyrproject.org/3.5.0/ From 0bc239f23de6fd840177a1c5f9c62ab3d6f8213c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 2 Nov 2023 10:19:53 +0000 Subject: [PATCH 2960/4498] doc: develop: getting_started: Change ubuntu version to 20.04 LTS Ubuntu 18.04 LTS support was dropped in May 2023, therefore bump version to oldest supported LTS release Signed-off-by: Jamie McCrae --- doc/develop/getting_started/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index ae0e6ce535d..5c1140f6157 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -22,7 +22,7 @@ Click the operating system you are using. .. group-tab:: Ubuntu - This guide covers Ubuntu version 18.04 LTS and later. + This guide covers Ubuntu version 20.04 LTS and later. .. code-block:: bash From ec75b7704f52380f67799dd5b64fe07bbfc41a7c Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 2 Nov 2023 11:50:35 +0100 Subject: [PATCH 2961/4498] docs: migration-guide-3.6: add a note about optional modules Add a note about modules moved to optional and how to enable them again. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-3.6.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 09ad3fe1401..ac5cb746e55 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -20,6 +20,18 @@ Kernel C Library ========= +Optional Modules +================ + +The following modules have been made optional and are not downloaded with `west update` by default +anymore: + +* ``canopennode`` + +To enable them again use the ``west config manifest.project-filter -- +`` command, or ``west config manifest.group-filter -- +optional`` to +enable all optional modules, and then run ``west update`` again. + Device Drivers and Device Tree ============================== From 3676e7c3602ecb14845fdc263bf2e61a6cfc9d54 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Thu, 2 Nov 2023 12:47:38 +0100 Subject: [PATCH 2962/4498] drivers: ieee802154: nrf5: set security enabled bit value Assign `ack_seb` in `net_pkt_cb_ieee802154`. Signed-off-by: Eduardo Montoya --- drivers/ieee802154/ieee802154_nrf5.c | 24 +++++++++++------------- drivers/ieee802154/ieee802154_nrf5.h | 4 ++++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 39b4bac7788..891a220e07f 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -58,11 +58,6 @@ struct nrf5_802154_config { static struct nrf5_802154_data nrf5_data; -#define ACK_REQUEST_BYTE 1 -#define ACK_REQUEST_BIT (1 << 5) -#define FRAME_PENDING_BYTE 1 -#define FRAME_PENDING_BIT (1 << 4) - #define DRX_SLOT_RX 0 /* Delayed reception window ID */ #define NSEC_PER_TEN_SYMBOLS (10 * IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS) @@ -183,6 +178,10 @@ static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3) net_pkt_set_timestamp_ns(pkt, rx_frame->time * NSEC_PER_USEC); #endif +#if defined(CONFIG_NET_L2_OPENTHREAD) + net_pkt_set_ieee802154_ack_seb(pkt, rx_frame->ack_seb); +#endif + LOG_DBG("Caught a packet (%u) (LQI: %u)", pkt_len, rx_frame->lqi); @@ -1031,13 +1030,10 @@ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi, nrf_802154_timestamp_end_to_phr_convert(time, data[0]); #endif - if (data[ACK_REQUEST_BYTE] & ACK_REQUEST_BIT) { - nrf5_data.rx_frames[i].ack_fpb = nrf5_data.last_frame_ack_fpb; - } else { - nrf5_data.rx_frames[i].ack_fpb = false; - } - + nrf5_data.rx_frames[i].ack_fpb = nrf5_data.last_frame_ack_fpb; + nrf5_data.rx_frames[i].ack_seb = nrf5_data.last_frame_ack_seb; nrf5_data.last_frame_ack_fpb = false; + nrf5_data.last_frame_ack_seb = false; k_fifo_put(&nrf5_data.rx_fifo, &nrf5_data.rx_frames[i]); @@ -1097,6 +1093,8 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) } nrf5_data.last_frame_ack_fpb = false; + nrf5_data.last_frame_ack_seb = false; + if (nrf5_data.event_handler) { nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_FAILED, (void *)&reason); } @@ -1104,8 +1102,8 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) void nrf_802154_tx_ack_started(const uint8_t *data) { - nrf5_data.last_frame_ack_fpb = - data[FRAME_PENDING_BYTE] & FRAME_PENDING_BIT; + nrf5_data.last_frame_ack_fpb = data[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT; + nrf5_data.last_frame_ack_seb = data[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT; } void nrf_802154_transmitted_raw(uint8_t *frame, diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index 8188db46ad1..9115fe0bdae 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -19,6 +19,7 @@ struct nrf5_802154_rx_frame { uint8_t lqi; /* Last received frame LQI value. */ int8_t rssi; /* Last received frame RSSI value. */ bool ack_fpb; /* FPB value in ACK sent for the received frame. */ + bool ack_seb; /* SEB value in ACK sent for the received frame. */ }; struct nrf5_802154_data { @@ -45,6 +46,9 @@ struct nrf5_802154_data { /* Frame pending bit value in ACK sent for the last received frame. */ bool last_frame_ack_fpb; + /* Security Enabled bit value in ACK sent for the last received frame. */ + bool last_frame_ack_seb; + /* CCA complete semaphore. Unlocked when CCA is complete. */ struct k_sem cca_wait; From fe5fd5b2050ca17d9b6eebdaba07780ac509f6e1 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 2 Nov 2023 15:04:36 +0100 Subject: [PATCH 2963/4498] actions: manifest: Upgrade to 1.2.2 Use revision 1.2.2 which comes with an additional bugfix. See https://github.com/zephyrproject-rtos/action-manifest/pull/11. Signed-off-by: Carles Cufi --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 61ab2e42157..fcae7973996 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -26,7 +26,7 @@ jobs: west init -l . || true - name: Manifest - uses: zephyrproject-rtos/action-manifest@v1.2.1 + uses: zephyrproject-rtos/action-manifest@v1.2.2 with: github-token: ${{ secrets.ZB_GITHUB_TOKEN }} manifest-path: 'west.yml' From 0649c819018e44edd94691462cb2c0b2c6faa7ac Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 2 Nov 2023 16:42:22 +0200 Subject: [PATCH 2964/4498] boards: intel_rpl: Simplify board configuration This makes intel_rpl board configuration similar to other Intel boards (like intel_adl) and also fixes SHELL_STACK_SIZE configuration. It should depend on ACPI. Signed-off-by: Andrei Emeltchenko --- boards/x86/intel_rpl/Kconfig.defconfig | 18 ++++++++++++------ boards/x86/intel_rpl/intel_rpl_s_crb_defconfig | 2 -- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/boards/x86/intel_rpl/Kconfig.defconfig b/boards/x86/intel_rpl/Kconfig.defconfig index e90e33b1583..78c10d200a3 100644 --- a/boards/x86/intel_rpl/Kconfig.defconfig +++ b/boards/x86/intel_rpl/Kconfig.defconfig @@ -12,6 +12,7 @@ config BUILD_OUTPUT_STRIPPED config MP_MAX_NUM_CPUS default 2 +# TSC on this board is 1.9 GHz, HPET and APIC are 19.2 MHz config SYS_CLOCK_HW_CYCLES_PER_SEC default 1900000000 if APIC_TSC_DEADLINE_TIMER default 1900000000 if APIC_TIMER_TSC @@ -29,10 +30,20 @@ endif config ACPI default y +if ACPI +config HEAP_MEM_POOL_SIZE + default 64000000 +config MAIN_STACK_SIZE + default 320000 config ACPI_PRT_BUS_NAME - depends on ACPI default "_SB.PC00" +if SHELL +config SHELL_STACK_SIZE + default 320000 +endif # SHELL +endif # ACPI + if DMA config DMA_64BIT default y @@ -42,9 +53,4 @@ config DMA_DW_CHANNEL_COUNT default 2 endif -if SHELL -config SHELL_STACK_SIZE - default 320000 -endif - endif # BOARD_INTEL_RPL_S_CRB diff --git a/boards/x86/intel_rpl/intel_rpl_s_crb_defconfig b/boards/x86/intel_rpl/intel_rpl_s_crb_defconfig index 1fe227ba4a6..1d8570bdeb7 100644 --- a/boards/x86/intel_rpl/intel_rpl_s_crb_defconfig +++ b/boards/x86/intel_rpl/intel_rpl_s_crb_defconfig @@ -13,5 +13,3 @@ CONFIG_X2APIC=y CONFIG_SMP=y CONFIG_BUILD_OUTPUT_EFI=y CONFIG_BUILD_NO_GAP_FILL=y -CONFIG_HEAP_MEM_POOL_SIZE=64000000 -CONFIG_MAIN_STACK_SIZE=320000 From d4cf7b6357dbe591b6836721398bb211ec618682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 2 Nov 2023 16:10:29 +0100 Subject: [PATCH 2965/4498] doc: gsg: Update Windows instructions regarding Python 3.12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Python 3.12 is not (yet) providing a seamless experience for Windows developers. Update Install instructions to invite people to stick to Python 3.11 for the time being. Signed-off-by: Benjamin Cabé --- doc/develop/getting_started/index.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 5c1140f6157..15b33738f86 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -164,7 +164,12 @@ The current minimum required version for the main dependencies are: .. code-block:: bat choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' - choco install ninja gperf python git dtc-msys2 wget 7zip + choco install ninja gperf python311 git dtc-msys2 wget 7zip + + .. warning:: + + As of November 2023, Python 3.12 is not recommended for Zephyr development on Windows, + as some required Python dependencies may be difficult to install. #. Close the window and open a new ``cmd.exe`` window **as a regular user** to continue. From 9571f1c502ea24283e67465a548b03e5403fd276 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 2 Nov 2023 18:21:11 +0000 Subject: [PATCH 2966/4498] twister: use correct variable for testcases We use testcases now, not cases. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/testplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 4607544efa7..4234a3cb584 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -390,7 +390,7 @@ def report_excluded_tests(self): all_tests = self.get_all_tests() to_be_run = set() for _, p in self.instances.items(): - to_be_run.update(p.testsuite.cases) + to_be_run.update(p.testsuite.testcases) if all_tests - to_be_run: print("Tests that never build or run:") From 32f7570bb4ebd870916a62b694e7bd57b3262e1c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 2 Nov 2023 18:21:41 +0000 Subject: [PATCH 2967/4498] twister: report: remove dead code Remove dead code for listing tests. This is covered already for the case of --list-tests. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/testplan.py | 18 ------------------ .../pylib/twister/twisterlib/twister_main.py | 4 ---- 2 files changed, 22 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 4234a3cb584..3f2ece1607e 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -397,24 +397,6 @@ def report_excluded_tests(self): for not_run in all_tests - to_be_run: print("- {}".format(not_run)) - def report_platform_tests(self, platforms=[]): - if len(platforms) > 1: - raise TwisterRuntimeError("When exporting tests, only one platform " - "should be specified.") - - for p in platforms: - inst = self.get_platform_instances(p) - count = 0 - for i in inst.values(): - for c in i.testsuite.cases: - print(f"- {c}") - count += 1 - print(f"Tests found: {count}") - - def get_platform_instances(self, platform): - filtered_dict = {k:v for k,v in self.instances.items() if k.startswith(platform + os.sep)} - return filtered_dict - def config(self): logger.info("coverage platform: {}".format(self.coverage_platform)) diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index 8f4b4f64893..91d20597d67 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -131,10 +131,6 @@ def main(options): logger.error(f"{e}") return 1 - if options.list_tests and options.platform: - tplan.report_platform_tests(options.platform) - return 0 - if VERBOSE > 1: # if we are using command line platform filter, no need to list every # other platform as excluded, we know that already. From 85dd4234688447a067ca98be6b8183da9b3546a7 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 2 Nov 2023 19:34:28 +0000 Subject: [PATCH 2968/4498] twister: report: remove defunct and old option --report-excluded has not been working for years, nobody has noticed. Fixes #64644 Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/environment.py | 6 ------ scripts/pylib/twister/twisterlib/testplan.py | 12 ------------ scripts/pylib/twister/twisterlib/twister_main.py | 4 ---- 3 files changed, 22 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index efa903218fb..f84749d547c 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -550,12 +550,6 @@ def add_parse_arguments(parser = None): default=True, help="deprecated, left for compatibility") - parser.add_argument("--report-excluded", - action="store_true", - help="""List all tests that are never run based on current scope and - coverage. If you are looking for accurate results, run this with - --all, but this will take a while...""") - parser.add_argument( "--report-name", help="""Create a report with a custom name. diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 3f2ece1607e..930d4573b19 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -385,18 +385,6 @@ def report_test_list(self): print("{} total.".format(cnt)) - - def report_excluded_tests(self): - all_tests = self.get_all_tests() - to_be_run = set() - for _, p in self.instances.items(): - to_be_run.update(p.testsuite.testcases) - - if all_tests - to_be_run: - print("Tests that never build or run:") - for not_run in all_tests - to_be_run: - print("- {}".format(not_run)) - def config(self): logger.info("coverage platform: {}".format(self.coverage_platform)) diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index 91d20597d67..30656544b94 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -151,10 +151,6 @@ def main(options): ) ) - if options.report_excluded: - tplan.report_excluded_tests() - return 0 - report = Reporting(tplan, env) plan_file = os.path.join(options.outdir, "testplan.json") if not os.path.exists(plan_file): From 26b649ea53dc90bca0d2abbdfe678e718f8cab9a Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 21:49:16 +0200 Subject: [PATCH 2969/4498] cmake: update board and soc linker script handling This commit updates the handling of board and SoC linker scripts. Several SoCs creates a linker.ld file which sole purpose is to include another arch common linker script, often with content like this: #include /linker.ld instead of 100+ SoC specific linker.ld files containing just a single include line of above structure, then this commit introduces two now CMake variables, BOARD_LINKER_SCRIPT and SOC_LINKER_SCRIPT. This allows the board and SoC CMake code to point directly to a common linker script instead of creating a dummy linker.ld file doing this. This removes the need for several dummy linker.ld file. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 47 +++++++++++++++--------------- cmake/linker/ld/target.cmake | 2 ++ cmake/modules/FindDeprecated.cmake | 18 ++++++++++++ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15671fc8ad3..3e3fd205a8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -484,30 +484,6 @@ if(CONFIG_USERSPACE) set(KOBJECT_LINKER_DEP kobject_linker) endif() -get_property(TOPT GLOBAL PROPERTY TOPT) -get_property(COMPILER_TOPT TARGET compiler PROPERTY linker_script) -set_ifndef( TOPT "${COMPILER_TOPT}") -set_ifndef( TOPT -Wl,-T) # Use this if the compiler driver doesn't set a value - -if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) - set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) - if(NOT EXISTS ${LINKER_SCRIPT}) - set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT}) - assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT) - endif() -else() - # Try a board specific linker file - set(LINKER_SCRIPT ${BOARD_DIR}/linker.ld) - if(NOT EXISTS ${LINKER_SCRIPT}) - # If not available, try an SoC specific linker file - set(LINKER_SCRIPT ${SOC_DIR}/${ARCH}/${SOC_PATH}/linker.ld) - endif() -endif() - -if(NOT EXISTS ${LINKER_SCRIPT}) - message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") -endif() - if(DEFINED BUILD_VERSION) set(build_version_argument "-DBUILD_VERSION=${BUILD_VERSION}") elseif(NOT ZEPHYR_GIT_INDEX) @@ -976,6 +952,29 @@ set(CMAKE_C_COMPILE_FEATURES ${compile_features_${CSTD}} PARENT_SCOPE) # @Intent: Configure linker scripts, i.e. generate linker scripts with variables substituted toolchain_ld_configure_files() +get_property(TOPT GLOBAL PROPERTY TOPT) +get_property(COMPILER_TOPT TARGET compiler PROPERTY linker_script) +set_ifndef( TOPT "${COMPILER_TOPT}") +set_ifndef( TOPT -Wl,-T) # Use this if the compiler driver doesn't set a value + +if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) + set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) + if(NOT EXISTS ${LINKER_SCRIPT}) + set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT}) + assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT) + endif() +elseif(DEFINED BOARD_LINKER_SCRIPT) + set(LINKER_SCRIPT ${BOARD_LINKER_SCRIPT}) +elseif(DEFINED SOC_LINKER_SCRIPT) + set(LINKER_SCRIPT ${SOC_LINKER_SCRIPT}) +else() + find_package(Deprecated COMPONENTS SEARCHED_LINKER_SCRIPT) +endif() + +if(NOT EXISTS ${LINKER_SCRIPT}) + message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") +endif() + if(CONFIG_USERSPACE) set(APP_SMEM_ALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld") set(APP_SMEM_UNALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld") diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index 507188540b7..baf76d2fed5 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -57,6 +57,7 @@ macro(configure_linker_script linker_script_gen linker_pass_define) zephyr_get_include_directories_for_lang(C current_includes) get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) + cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) add_custom_command( OUTPUT ${linker_script_gen} @@ -74,6 +75,7 @@ macro(configure_linker_script linker_script_gen linker_pass_define) -D_ASMLANGUAGE -imacros ${AUTOCONF_H} ${current_includes} + -I${soc_linker_script_includes} ${current_defines} ${template_script_defines} -E ${LINKER_SCRIPT} diff --git a/cmake/modules/FindDeprecated.cmake b/cmake/modules/FindDeprecated.cmake index ae9b292af09..66cac2a5583 100644 --- a/cmake/modules/FindDeprecated.cmake +++ b/cmake/modules/FindDeprecated.cmake @@ -131,5 +131,23 @@ if(NOT "${Deprecated_FIND_COMPONENTS}" STREQUAL "") "${Deprecated_FIND_COMPONENTS}") endif() +if("SEARCHED_LINKER_SCRIPT" IN_LIST Deprecated_FIND_COMPONENTS) + # This code was deprecated after Zephyr v3.5.0 + list(REMOVE_ITEM Deprecated_FIND_COMPONENTS SEARCHED_LINKER_SCRIPT) + + # Try a board specific linker file + set(LINKER_SCRIPT ${BOARD_DIR}/linker.ld) + if(NOT EXISTS ${LINKER_SCRIPT}) + # If not available, try an SoC specific linker file + set(LINKER_SCRIPT ${SOC_DIR}/${ARCH}/${SOC_PATH}/linker.ld) + endif() + message(DEPRECATION + "Pre-defined `linker.ld` script is deprecated. Please set " + "BOARD_LINKER_SCRIPT or SOC_LINKER_SCRIPT to point to ${LINKER_SCRIPT} " + "or one of the Zephyr provided common linker scripts for the ${ARCH} " + "architecture." + ) +endif() + set(Deprecated_FOUND True) set(DEPRECATED_FOUND True) From b2de93cff6417541ce0dcd6805bcb992e53ba901 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 23:39:49 +0200 Subject: [PATCH 2970/4498] cmake: arc: update arc SoC to use SOC_LINKER_SCRIPT variable This commit updates all arc SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/arc/snps_arc_hsdk/CMakeLists.txt | 2 ++ soc/arc/snps_arc_hsdk4xd/CMakeLists.txt | 2 ++ soc/arc/snps_arc_iot/CMakeLists.txt | 2 ++ soc/arc/snps_emsdp/CMakeLists.txt | 2 ++ soc/arc/snps_emsk/CMakeLists.txt | 2 ++ soc/arc/snps_nsim/CMakeLists.txt | 2 ++ soc/arc/snps_qemu/CMakeLists.txt | 2 ++ 7 files changed, 14 insertions(+) diff --git a/soc/arc/snps_arc_hsdk/CMakeLists.txt b/soc/arc/snps_arc_hsdk/CMakeLists.txt index 1d6a7c6827f..c20f4167057 100644 --- a/soc/arc/snps_arc_hsdk/CMakeLists.txt +++ b/soc/arc/snps_arc_hsdk/CMakeLists.txt @@ -18,3 +18,5 @@ else() zephyr_ld_options(-Hlib=hs38_full) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_arc_hsdk4xd/CMakeLists.txt b/soc/arc/snps_arc_hsdk4xd/CMakeLists.txt index 0e6c51029af..0c13259ca2b 100644 --- a/soc/arc/snps_arc_hsdk4xd/CMakeLists.txt +++ b/soc/arc/snps_arc_hsdk4xd/CMakeLists.txt @@ -14,3 +14,5 @@ else() zephyr_ld_options(-Hlib=hs48_slc_full) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_arc_iot/CMakeLists.txt b/soc/arc/snps_arc_iot/CMakeLists.txt index 4c478bc785c..5a28fe228d8 100644 --- a/soc/arc/snps_arc_iot/CMakeLists.txt +++ b/soc/arc/snps_arc_iot/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_sources( soc.c sysconf.c ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_emsdp/CMakeLists.txt b/soc/arc/snps_emsdp/CMakeLists.txt index 7a4ba9674fd..04466b802c0 100644 --- a/soc/arc/snps_emsdp/CMakeLists.txt +++ b/soc/arc/snps_emsdp/CMakeLists.txt @@ -18,3 +18,5 @@ elseif(CONFIG_SOC_EMSDP_EM11D) zephyr_compile_options(-mmpy-option=6) zephyr_compile_options_ifdef(CONFIG_FPU -mfpu=fpuda_all) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_emsk/CMakeLists.txt b/soc/arc/snps_emsk/CMakeLists.txt index 53b0f92a9c8..8e8ef5865ca 100644 --- a/soc/arc/snps_emsk/CMakeLists.txt +++ b/soc/arc/snps_emsk/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_compile_options_ifdef(CONFIG_FPU -mfpu=fpuda_all) endif() zephyr_sources(soc_config.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_nsim/CMakeLists.txt b/soc/arc/snps_nsim/CMakeLists.txt index 965bf79968e..094aed08cee 100644 --- a/soc/arc/snps_nsim/CMakeLists.txt +++ b/soc/arc/snps_nsim/CMakeLists.txt @@ -105,3 +105,5 @@ else() zephyr_ld_option_ifdef(CONFIG_SOC_NSIM_HS6X_SMP -Hlib=hs68_full_zephyr) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arc/snps_qemu/CMakeLists.txt b/soc/arc/snps_qemu/CMakeLists.txt index c77f0003c4c..a05efdfa22d 100644 --- a/soc/arc/snps_qemu/CMakeLists.txt +++ b/soc/arc/snps_qemu/CMakeLists.txt @@ -19,3 +19,5 @@ else() endif() endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From 4812884f84e74a4f8c049a69011be915d9ceab4d Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 23:34:14 +0200 Subject: [PATCH 2971/4498] cmake: arm: update arm SoC to use SOC_LINKER_SCRIPT variable This commit updates all arm SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/arm/ambiq/apollo4x/CMakeLists.txt | 2 ++ soc/arm/ambiq/apollo4x/linker.ld | 7 ------- soc/arm/arm/beetle/CMakeLists.txt | 2 ++ soc/arm/arm/beetle/linker.ld | 9 --------- soc/arm/arm/designstart/CMakeLists.txt | 2 ++ soc/arm/arm/designstart/linker.ld | 9 --------- soc/arm/arm/fvp_aemv8r_aarch32/CMakeLists.txt | 2 ++ soc/arm/arm/fvp_aemv8r_aarch32/linker.ld | 8 -------- soc/arm/arm/mps2/CMakeLists.txt | 2 ++ soc/arm/arm/mps2/linker.ld | 9 --------- soc/arm/arm/mps3/CMakeLists.txt | 2 ++ soc/arm/arm/mps3/linker.ld | 9 --------- soc/arm/arm/musca_b1/CMakeLists.txt | 2 ++ soc/arm/arm/musca_b1/linker.ld | 9 --------- soc/arm/arm/musca_s1/CMakeLists.txt | 2 ++ soc/arm/arm/musca_s1/linker.ld | 9 --------- soc/arm/aspeed/ast10x0/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/sam3x/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/sam3x/linker.ld | 9 --------- soc/arm/atmel_sam/sam4e/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/sam4e/linker.ld | 9 --------- soc/arm/atmel_sam/sam4l/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/sam4l/linker.ld | 9 --------- soc/arm/atmel_sam/sam4s/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/sam4s/linker.ld | 9 --------- soc/arm/atmel_sam/same70/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/same70/linker.ld | 8 -------- soc/arm/atmel_sam/samv71/CMakeLists.txt | 2 ++ soc/arm/atmel_sam/samv71/linker.ld | 8 -------- soc/arm/atmel_sam0/common/CMakeLists.txt | 2 ++ soc/arm/atmel_sam0/samc20/linker.ld | 8 -------- soc/arm/atmel_sam0/samc21/linker.ld | 8 -------- soc/arm/atmel_sam0/samd20/linker.ld | 8 -------- soc/arm/atmel_sam0/samd21/linker.ld | 8 -------- soc/arm/atmel_sam0/samd51/linker.ld | 8 -------- soc/arm/atmel_sam0/same51/linker.ld | 8 -------- soc/arm/atmel_sam0/same53/linker.ld | 8 -------- soc/arm/atmel_sam0/same54/linker.ld | 8 -------- soc/arm/atmel_sam0/saml21/linker.ld | 8 -------- soc/arm/atmel_sam0/samr21/linker.ld | 8 -------- soc/arm/atmel_sam0/samr34/linker.ld | 8 -------- soc/arm/atmel_sam0/samr35/linker.ld | 8 -------- soc/arm/bcm_vk/valkyrie/CMakeLists.txt | 2 ++ soc/arm/bcm_vk/valkyrie/linker.ld | 7 ------- soc/arm/bcm_vk/viper/CMakeLists.txt | 2 ++ soc/arm/bcm_vk/viper/linker.ld | 8 -------- soc/arm/bcm_vk/viper/linker_m7.ld | 7 ------- soc/arm/cypress/psoc6/CMakeLists.txt | 2 ++ soc/arm/cypress/psoc6/linker.ld | 15 --------------- soc/arm/gigadevice/gd32a50x/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32a50x/linker.ld | 6 ------ soc/arm/gigadevice/gd32e10x/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32e10x/linker.ld | 6 ------ soc/arm/gigadevice/gd32e50x/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32e50x/linker.ld | 6 ------ soc/arm/gigadevice/gd32f3x0/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32f3x0/linker.ld | 6 ------ soc/arm/gigadevice/gd32f403/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32f403/linker.ld | 9 --------- soc/arm/gigadevice/gd32f4xx/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32f4xx/linker.ld | 6 ------ soc/arm/gigadevice/gd32l23x/CMakeLists.txt | 2 ++ soc/arm/gigadevice/gd32l23x/linker.ld | 6 ------ soc/arm/infineon_cat1/psoc6/CMakeLists.txt | 2 ++ soc/arm/infineon_cat1/psoc6/linker.ld | 8 -------- soc/arm/infineon_xmc/4xxx/CMakeLists.txt | 2 ++ soc/arm/infineon_xmc/4xxx/linker.ld | 14 -------------- .../intel_socfpga_std/cyclonev/CMakeLists.txt | 2 ++ soc/arm/intel_socfpga_std/cyclonev/linker.ld | 8 -------- soc/arm/microchip_mec/mec1501/CMakeLists.txt | 2 ++ soc/arm/microchip_mec/mec1501/linker.ld | 9 --------- soc/arm/microchip_mec/mec172x/CMakeLists.txt | 2 ++ soc/arm/microchip_mec/mec172x/linker.ld | 9 --------- soc/arm/nordic_nrf/nrf51/CMakeLists.txt | 2 ++ soc/arm/nordic_nrf/nrf51/linker.ld | 9 --------- soc/arm/nordic_nrf/nrf52/CMakeLists.txt | 2 ++ soc/arm/nordic_nrf/nrf52/linker.ld | 9 --------- soc/arm/nordic_nrf/nrf53/CMakeLists.txt | 2 ++ soc/arm/nordic_nrf/nrf53/linker.ld | 9 --------- soc/arm/nordic_nrf/nrf91/CMakeLists.txt | 2 ++ soc/arm/nordic_nrf/nrf91/linker.ld | 9 --------- soc/arm/nuvoton_npcx/npcx4/CMakeLists.txt | 2 ++ soc/arm/nuvoton_npcx/npcx4/linker.ld | 9 --------- soc/arm/nuvoton_npcx/npcx7/CMakeLists.txt | 2 ++ soc/arm/nuvoton_npcx/npcx7/linker.ld | 9 --------- soc/arm/nuvoton_npcx/npcx9/CMakeLists.txt | 2 ++ soc/arm/nuvoton_npcx/npcx9/linker.ld | 9 --------- soc/arm/nuvoton_numaker/m46x/CMakeLists.txt | 2 ++ soc/arm/nuvoton_numaker/m46x/linker.ld | 7 ------- soc/arm/nuvoton_numicro/m48x/CMakeLists.txt | 2 ++ soc/arm/nuvoton_numicro/m48x/linker.ld | 7 ------- soc/arm/nxp_imx/mcimx6x_m4/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/mcimx6x_m4/linker.ld | 7 ------- soc/arm/nxp_imx/mcimx7_m4/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/mcimx7_m4/linker.ld | 7 ------- soc/arm/nxp_imx/mimx8ml8_m7/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/mimx8mq6_m4/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/mimx8mq6_m4/linker.ld | 7 ------- soc/arm/nxp_imx/rt/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/rt5xx/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/rt6xx/CMakeLists.txt | 2 ++ soc/arm/nxp_imx/rt6xx/linker.ld | 14 -------------- soc/arm/nxp_kinetis/k2x/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/k2x/linker.ld | 14 -------------- soc/arm/nxp_kinetis/k6x/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/k6x/linker.ld | 14 -------------- soc/arm/nxp_kinetis/k8x/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/k8x/linker.ld | 14 -------------- soc/arm/nxp_kinetis/ke1xf/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/ke1xf/linker.ld | 14 -------------- soc/arm/nxp_kinetis/kl2x/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/kl2x/linker.ld | 14 -------------- soc/arm/nxp_kinetis/kv5x/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/kv5x/linker.ld | 14 -------------- soc/arm/nxp_kinetis/kwx/CMakeLists.txt | 2 ++ soc/arm/nxp_kinetis/kwx/linker.ld | 14 -------------- soc/arm/nxp_lpc/lpc11u6x/CMakeLists.txt | 2 ++ soc/arm/nxp_lpc/lpc11u6x/linker.ld | 15 --------------- soc/arm/nxp_lpc/lpc51u68/CMakeLists.txt | 2 ++ soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt | 2 ++ soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt | 2 ++ soc/arm/nxp_s32/s32k/CMakeLists.txt | 2 ++ soc/arm/nxp_s32/s32ze/CMakeLists.txt | 2 ++ soc/arm/nxp_s32/s32ze/linker.ld | 7 ------- soc/arm/quicklogic_eos_s3/CMakeLists.txt | 2 ++ soc/arm/quicklogic_eos_s3/linker.ld | 7 ------- soc/arm/renesas_rcar/gen3/CMakeLists.txt | 2 ++ soc/arm/renesas_rcar/gen3/linker.ld | 7 ------- soc/arm/renesas_smartbond/da1469x/CMakeLists.txt | 2 ++ soc/arm/renesas_smartbond/da1469x/linker.ld | 7 ------- soc/arm/rpi_pico/rp2/CMakeLists.txt | 2 ++ soc/arm/silabs_exx32/common/CMakeLists.txt | 2 ++ soc/arm/silabs_exx32/efm32gg11b/linker.ld | 16 ---------------- soc/arm/silabs_exx32/efm32gg12b/linker.ld | 14 -------------- soc/arm/silabs_exx32/efm32hg/linker.ld | 15 --------------- soc/arm/silabs_exx32/efm32jg12b/linker.ld | 15 --------------- soc/arm/silabs_exx32/efm32pg12b/linker.ld | 15 --------------- soc/arm/silabs_exx32/efm32pg1b/linker.ld | 15 --------------- soc/arm/silabs_exx32/efm32wg/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32bg13p/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32bg22/linker.ld | 14 -------------- soc/arm/silabs_exx32/efr32bg27/linker.ld | 5 ----- soc/arm/silabs_exx32/efr32fg13p/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32fg1p/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32mg12p/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32mg21/linker.ld | 15 --------------- soc/arm/silabs_exx32/efr32mg24/linker.ld | 16 ---------------- soc/arm/st_stm32/stm32c0/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32c0/linker.ld | 9 --------- soc/arm/st_stm32/stm32f0/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f0/linker.ld | 9 --------- soc/arm/st_stm32/stm32f1/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f1/linker.ld | 9 --------- soc/arm/st_stm32/stm32f2/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f2/linker.ld | 9 --------- soc/arm/st_stm32/stm32f3/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f3/linker.ld | 9 --------- soc/arm/st_stm32/stm32f4/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f4/linker.ld | 9 --------- soc/arm/st_stm32/stm32f7/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32f7/linker.ld | 9 --------- soc/arm/st_stm32/stm32g0/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32g0/linker.ld | 10 ---------- soc/arm/st_stm32/stm32g4/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32g4/linker.ld | 9 --------- soc/arm/st_stm32/stm32h5/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32h5/linker.ld | 9 --------- soc/arm/st_stm32/stm32h7/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32h7/linker.ld | 9 --------- soc/arm/st_stm32/stm32l0/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32l0/linker.ld | 9 --------- soc/arm/st_stm32/stm32l1/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32l1/linker.ld | 9 --------- soc/arm/st_stm32/stm32l4/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32l4/linker.ld | 9 --------- soc/arm/st_stm32/stm32l5/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32l5/linker.ld | 9 --------- soc/arm/st_stm32/stm32mp1/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32u5/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32u5/linker.ld | 9 --------- soc/arm/st_stm32/stm32wb/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32wb/linker.ld | 9 --------- soc/arm/st_stm32/stm32wba/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32wba/linker.ld | 9 --------- soc/arm/st_stm32/stm32wl/CMakeLists.txt | 2 ++ soc/arm/st_stm32/stm32wl/linker.ld | 9 --------- soc/arm/ti_k3/am62x_m4/CMakeLists.txt | 2 ++ soc/arm/ti_lm3s6965/CMakeLists.txt | 2 ++ soc/arm/ti_lm3s6965/linker.ld | 9 --------- .../ti_simplelink/cc13x2_cc26x2/CMakeLists.txt | 2 ++ soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld | 8 -------- .../cc13x2x7_cc26x2x7/CMakeLists.txt | 2 ++ .../ti_simplelink/cc13x2x7_cc26x2x7/linker.ld | 8 -------- soc/arm/ti_simplelink/cc32xx/CMakeLists.txt | 2 ++ soc/arm/ti_simplelink/cc32xx/linker.ld | 8 -------- soc/arm/ti_simplelink/msp432p4xx/CMakeLists.txt | 2 ++ soc/arm/ti_simplelink/msp432p4xx/linker.ld | 8 -------- soc/arm/xilinx_zynq7000/xc7zxxx/CMakeLists.txt | 2 ++ soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld | 7 ------- soc/arm/xilinx_zynq7000/xc7zxxxs/CMakeLists.txt | 2 ++ soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld | 7 ------- soc/arm/xilinx_zynqmp/CMakeLists.txt | 4 ++++ soc/arm/xilinx_zynqmp/linker.ld | 11 ----------- 204 files changed, 192 insertions(+), 1053 deletions(-) delete mode 100644 soc/arm/ambiq/apollo4x/linker.ld delete mode 100644 soc/arm/arm/beetle/linker.ld delete mode 100644 soc/arm/arm/designstart/linker.ld delete mode 100644 soc/arm/arm/fvp_aemv8r_aarch32/linker.ld delete mode 100644 soc/arm/arm/mps2/linker.ld delete mode 100644 soc/arm/arm/mps3/linker.ld delete mode 100644 soc/arm/arm/musca_b1/linker.ld delete mode 100644 soc/arm/arm/musca_s1/linker.ld delete mode 100644 soc/arm/atmel_sam/sam3x/linker.ld delete mode 100644 soc/arm/atmel_sam/sam4e/linker.ld delete mode 100644 soc/arm/atmel_sam/sam4l/linker.ld delete mode 100644 soc/arm/atmel_sam/sam4s/linker.ld delete mode 100644 soc/arm/atmel_sam/same70/linker.ld delete mode 100644 soc/arm/atmel_sam/samv71/linker.ld delete mode 100644 soc/arm/atmel_sam0/samc20/linker.ld delete mode 100644 soc/arm/atmel_sam0/samc21/linker.ld delete mode 100644 soc/arm/atmel_sam0/samd20/linker.ld delete mode 100644 soc/arm/atmel_sam0/samd21/linker.ld delete mode 100644 soc/arm/atmel_sam0/samd51/linker.ld delete mode 100644 soc/arm/atmel_sam0/same51/linker.ld delete mode 100644 soc/arm/atmel_sam0/same53/linker.ld delete mode 100644 soc/arm/atmel_sam0/same54/linker.ld delete mode 100644 soc/arm/atmel_sam0/saml21/linker.ld delete mode 100644 soc/arm/atmel_sam0/samr21/linker.ld delete mode 100644 soc/arm/atmel_sam0/samr34/linker.ld delete mode 100644 soc/arm/atmel_sam0/samr35/linker.ld delete mode 100644 soc/arm/bcm_vk/valkyrie/linker.ld delete mode 100644 soc/arm/bcm_vk/viper/linker.ld delete mode 100644 soc/arm/bcm_vk/viper/linker_m7.ld delete mode 100644 soc/arm/cypress/psoc6/linker.ld delete mode 100644 soc/arm/gigadevice/gd32a50x/linker.ld delete mode 100644 soc/arm/gigadevice/gd32e10x/linker.ld delete mode 100644 soc/arm/gigadevice/gd32e50x/linker.ld delete mode 100644 soc/arm/gigadevice/gd32f3x0/linker.ld delete mode 100644 soc/arm/gigadevice/gd32f403/linker.ld delete mode 100644 soc/arm/gigadevice/gd32f4xx/linker.ld delete mode 100644 soc/arm/gigadevice/gd32l23x/linker.ld delete mode 100644 soc/arm/infineon_cat1/psoc6/linker.ld delete mode 100644 soc/arm/infineon_xmc/4xxx/linker.ld delete mode 100644 soc/arm/intel_socfpga_std/cyclonev/linker.ld delete mode 100644 soc/arm/microchip_mec/mec1501/linker.ld delete mode 100644 soc/arm/microchip_mec/mec172x/linker.ld delete mode 100644 soc/arm/nordic_nrf/nrf51/linker.ld delete mode 100644 soc/arm/nordic_nrf/nrf52/linker.ld delete mode 100644 soc/arm/nordic_nrf/nrf53/linker.ld delete mode 100644 soc/arm/nordic_nrf/nrf91/linker.ld delete mode 100644 soc/arm/nuvoton_npcx/npcx4/linker.ld delete mode 100644 soc/arm/nuvoton_npcx/npcx7/linker.ld delete mode 100644 soc/arm/nuvoton_npcx/npcx9/linker.ld delete mode 100644 soc/arm/nuvoton_numaker/m46x/linker.ld delete mode 100644 soc/arm/nuvoton_numicro/m48x/linker.ld delete mode 100644 soc/arm/nxp_imx/mcimx6x_m4/linker.ld delete mode 100644 soc/arm/nxp_imx/mcimx7_m4/linker.ld delete mode 100644 soc/arm/nxp_imx/mimx8mq6_m4/linker.ld delete mode 100644 soc/arm/nxp_imx/rt6xx/linker.ld delete mode 100644 soc/arm/nxp_kinetis/k2x/linker.ld delete mode 100644 soc/arm/nxp_kinetis/k6x/linker.ld delete mode 100644 soc/arm/nxp_kinetis/k8x/linker.ld delete mode 100644 soc/arm/nxp_kinetis/ke1xf/linker.ld delete mode 100644 soc/arm/nxp_kinetis/kl2x/linker.ld delete mode 100644 soc/arm/nxp_kinetis/kv5x/linker.ld delete mode 100644 soc/arm/nxp_kinetis/kwx/linker.ld delete mode 100644 soc/arm/nxp_lpc/lpc11u6x/linker.ld delete mode 100644 soc/arm/nxp_s32/s32ze/linker.ld delete mode 100644 soc/arm/quicklogic_eos_s3/linker.ld delete mode 100644 soc/arm/renesas_rcar/gen3/linker.ld delete mode 100644 soc/arm/renesas_smartbond/da1469x/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32gg11b/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32gg12b/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32hg/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32jg12b/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32pg12b/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32pg1b/linker.ld delete mode 100644 soc/arm/silabs_exx32/efm32wg/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32bg13p/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32bg22/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32bg27/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32fg13p/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32fg1p/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32mg12p/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32mg21/linker.ld delete mode 100644 soc/arm/silabs_exx32/efr32mg24/linker.ld delete mode 100644 soc/arm/st_stm32/stm32c0/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f0/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f1/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f2/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f3/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f4/linker.ld delete mode 100644 soc/arm/st_stm32/stm32f7/linker.ld delete mode 100644 soc/arm/st_stm32/stm32g0/linker.ld delete mode 100644 soc/arm/st_stm32/stm32g4/linker.ld delete mode 100644 soc/arm/st_stm32/stm32h5/linker.ld delete mode 100644 soc/arm/st_stm32/stm32h7/linker.ld delete mode 100644 soc/arm/st_stm32/stm32l0/linker.ld delete mode 100644 soc/arm/st_stm32/stm32l1/linker.ld delete mode 100644 soc/arm/st_stm32/stm32l4/linker.ld delete mode 100644 soc/arm/st_stm32/stm32l5/linker.ld delete mode 100644 soc/arm/st_stm32/stm32u5/linker.ld delete mode 100644 soc/arm/st_stm32/stm32wb/linker.ld delete mode 100644 soc/arm/st_stm32/stm32wba/linker.ld delete mode 100644 soc/arm/st_stm32/stm32wl/linker.ld delete mode 100644 soc/arm/ti_lm3s6965/linker.ld delete mode 100644 soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld delete mode 100644 soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld delete mode 100644 soc/arm/ti_simplelink/cc32xx/linker.ld delete mode 100644 soc/arm/ti_simplelink/msp432p4xx/linker.ld delete mode 100644 soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld delete mode 100644 soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld delete mode 100644 soc/arm/xilinx_zynqmp/linker.ld diff --git a/soc/arm/ambiq/apollo4x/CMakeLists.txt b/soc/arm/ambiq/apollo4x/CMakeLists.txt index 2d96101cb0b..a82fe0a51f3 100644 --- a/soc/arm/ambiq/apollo4x/CMakeLists.txt +++ b/soc/arm/ambiq/apollo4x/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_sources(soc.c) zephyr_include_directories(${ZEPHYR_BASE}/soc/arm/common/cortex_m) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ambiq/apollo4x/linker.ld b/soc/arm/ambiq/apollo4x/linker.ld deleted file mode 100644 index ab996aa9939..00000000000 --- a/soc/arm/ambiq/apollo4x/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/beetle/CMakeLists.txt b/soc/arm/arm/beetle/CMakeLists.txt index 3fd95157dfc..e911f5faab5 100644 --- a/soc/arm/arm/beetle/CMakeLists.txt +++ b/soc/arm/arm/beetle/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources( soc.c power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/beetle/linker.ld b/soc/arm/arm/beetle/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/beetle/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/designstart/CMakeLists.txt b/soc/arm/arm/designstart/CMakeLists.txt index 9881313609a..5d2598e239b 100644 --- a/soc/arm/arm/designstart/CMakeLists.txt +++ b/soc/arm/arm/designstart/CMakeLists.txt @@ -1 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/designstart/linker.ld b/soc/arm/arm/designstart/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/designstart/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/fvp_aemv8r_aarch32/CMakeLists.txt b/soc/arm/arm/fvp_aemv8r_aarch32/CMakeLists.txt index 01b4ede7dfa..d9264843fae 100644 --- a/soc/arm/arm/fvp_aemv8r_aarch32/CMakeLists.txt +++ b/soc/arm/arm/fvp_aemv8r_aarch32/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_library_sources_ifdef(CONFIG_ARM_MPU arm_mpu_regions.c) zephyr_library_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld b/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld deleted file mode 100644 index 76b6c7a5450..00000000000 --- a/soc/arm/arm/fvp_aemv8r_aarch32/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * linker.ld - Linker command/script file - * - * Copyright (c) 2022 IoT.bzh - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/mps2/CMakeLists.txt b/soc/arm/arm/mps2/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/arm/mps2/CMakeLists.txt +++ b/soc/arm/arm/mps2/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/mps2/linker.ld b/soc/arm/arm/mps2/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/mps2/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/mps3/CMakeLists.txt b/soc/arm/arm/mps3/CMakeLists.txt index a2566f7c530..d82e1bc62c5 100644 --- a/soc/arm/arm/mps3/CMakeLists.txt +++ b/soc/arm/arm/mps3/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/mps3/linker.ld b/soc/arm/arm/mps3/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/mps3/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/musca_b1/CMakeLists.txt b/soc/arm/arm/musca_b1/CMakeLists.txt index ae3f7d6c3be..9c8a3b15eb2 100644 --- a/soc/arm/arm/musca_b1/CMakeLists.txt +++ b/soc/arm/arm/musca_b1/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/musca_b1/linker.ld b/soc/arm/arm/musca_b1/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/musca_b1/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/arm/musca_s1/CMakeLists.txt b/soc/arm/arm/musca_s1/CMakeLists.txt index 2ceba388601..51df24c9b73 100644 --- a/soc/arm/arm/musca_s1/CMakeLists.txt +++ b/soc/arm/arm/musca_s1/CMakeLists.txt @@ -3,3 +3,5 @@ # # SPDX-License-Identifier: Apache-2.0 # + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/arm/musca_s1/linker.ld b/soc/arm/arm/musca_s1/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/arm/musca_s1/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/aspeed/ast10x0/CMakeLists.txt b/soc/arm/aspeed/ast10x0/CMakeLists.txt index fc5628a425e..0d73ca4ba34 100644 --- a/soc/arm/aspeed/ast10x0/CMakeLists.txt +++ b/soc/arm/aspeed/ast10x0/CMakeLists.txt @@ -13,3 +13,5 @@ set_property(GLOBAL APPEND PROPERTY extra_post_build_commands ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin ${PROJECT_BINARY_DIR}/uart_${CONFIG_KERNEL_BIN_NAME}.bin ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/sam3x/CMakeLists.txt b/soc/arm/atmel_sam/sam3x/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/atmel_sam/sam3x/CMakeLists.txt +++ b/soc/arm/atmel_sam/sam3x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/sam3x/linker.ld b/soc/arm/atmel_sam/sam3x/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/atmel_sam/sam3x/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam/sam4e/CMakeLists.txt b/soc/arm/atmel_sam/sam4e/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/atmel_sam/sam4e/CMakeLists.txt +++ b/soc/arm/atmel_sam/sam4e/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/sam4e/linker.ld b/soc/arm/atmel_sam/sam4e/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/atmel_sam/sam4e/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam/sam4l/CMakeLists.txt b/soc/arm/atmel_sam/sam4l/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/atmel_sam/sam4l/CMakeLists.txt +++ b/soc/arm/atmel_sam/sam4l/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/sam4l/linker.ld b/soc/arm/atmel_sam/sam4l/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/atmel_sam/sam4l/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam/sam4s/CMakeLists.txt b/soc/arm/atmel_sam/sam4s/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/atmel_sam/sam4s/CMakeLists.txt +++ b/soc/arm/atmel_sam/sam4s/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/sam4s/linker.ld b/soc/arm/atmel_sam/sam4s/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/atmel_sam/sam4s/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam/same70/CMakeLists.txt b/soc/arm/atmel_sam/same70/CMakeLists.txt index 0ad494174dd..8373266d4ec 100644 --- a/soc/arm/atmel_sam/same70/CMakeLists.txt +++ b/soc/arm/atmel_sam/same70/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources( soc.c soc_config.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/same70/linker.ld b/soc/arm/atmel_sam/same70/linker.ld deleted file mode 100644 index cb361723b39..00000000000 --- a/soc/arm/atmel_sam/same70/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam/samv71/CMakeLists.txt b/soc/arm/atmel_sam/samv71/CMakeLists.txt index 0ad494174dd..8373266d4ec 100644 --- a/soc/arm/atmel_sam/samv71/CMakeLists.txt +++ b/soc/arm/atmel_sam/samv71/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources( soc.c soc_config.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam/samv71/linker.ld b/soc/arm/atmel_sam/samv71/linker.ld deleted file mode 100644 index cb361723b39..00000000000 --- a/soc/arm/atmel_sam/samv71/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/common/CMakeLists.txt b/soc/arm/atmel_sam0/common/CMakeLists.txt index 53f54da8a78..6dd4525f2d2 100644 --- a/soc/arm/atmel_sam0/common/CMakeLists.txt +++ b/soc/arm/atmel_sam0/common/CMakeLists.txt @@ -23,3 +23,5 @@ zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAME53 soc_samd5x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAME54 soc_samd5x.c) zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/atmel_sam0/samc20/linker.ld b/soc/arm/atmel_sam0/samc20/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/samc20/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samc21/linker.ld b/soc/arm/atmel_sam0/samc21/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/samc21/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samd20/linker.ld b/soc/arm/atmel_sam0/samd20/linker.ld deleted file mode 100644 index 75ef287b6d9..00000000000 --- a/soc/arm/atmel_sam0/samd20/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2018 Sean Nyekjaer - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samd21/linker.ld b/soc/arm/atmel_sam0/samd21/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/samd21/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samd51/linker.ld b/soc/arm/atmel_sam0/samd51/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/samd51/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/same51/linker.ld b/soc/arm/atmel_sam0/same51/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/same51/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/same53/linker.ld b/soc/arm/atmel_sam0/same53/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/same53/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/same54/linker.ld b/soc/arm/atmel_sam0/same54/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/same54/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/saml21/linker.ld b/soc/arm/atmel_sam0/saml21/linker.ld deleted file mode 100644 index 6b4498f0932..00000000000 --- a/soc/arm/atmel_sam0/saml21/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2021 Argentum Systems Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samr21/linker.ld b/soc/arm/atmel_sam0/samr21/linker.ld deleted file mode 100644 index 745c7ad8b2a..00000000000 --- a/soc/arm/atmel_sam0/samr21/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2017 Google LLC. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samr34/linker.ld b/soc/arm/atmel_sam0/samr34/linker.ld deleted file mode 100644 index 6b4498f0932..00000000000 --- a/soc/arm/atmel_sam0/samr34/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2021 Argentum Systems Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/atmel_sam0/samr35/linker.ld b/soc/arm/atmel_sam0/samr35/linker.ld deleted file mode 100644 index 6b4498f0932..00000000000 --- a/soc/arm/atmel_sam0/samr35/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2021 Argentum Systems Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/bcm_vk/valkyrie/CMakeLists.txt b/soc/arm/bcm_vk/valkyrie/CMakeLists.txt index f75aec6b311..f5ca7d6435e 100644 --- a/soc/arm/bcm_vk/valkyrie/CMakeLists.txt +++ b/soc/arm/bcm_vk/valkyrie/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/bcm_vk/valkyrie/linker.ld b/soc/arm/bcm_vk/valkyrie/linker.ld deleted file mode 100644 index a17ecaeaf32..00000000000 --- a/soc/arm/bcm_vk/valkyrie/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright 2019 Broadcom. - */ - - -#include diff --git a/soc/arm/bcm_vk/viper/CMakeLists.txt b/soc/arm/bcm_vk/viper/CMakeLists.txt index 3b465dc7da8..b81c75442e1 100644 --- a/soc/arm/bcm_vk/viper/CMakeLists.txt +++ b/soc/arm/bcm_vk/viper/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(.) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/bcm_vk/viper/linker.ld b/soc/arm/bcm_vk/viper/linker.ld deleted file mode 100644 index c3ea22e3564..00000000000 --- a/soc/arm/bcm_vk/viper/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2020 Broadcom - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include diff --git a/soc/arm/bcm_vk/viper/linker_m7.ld b/soc/arm/bcm_vk/viper/linker_m7.ld deleted file mode 100644 index 670bb23c78b..00000000000 --- a/soc/arm/bcm_vk/viper/linker_m7.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2020 Broadcom - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/cypress/psoc6/CMakeLists.txt b/soc/arm/cypress/psoc6/CMakeLists.txt index a88416cda13..e2ea2eb6ae1 100644 --- a/soc/arm/cypress/psoc6/CMakeLists.txt +++ b/soc/arm/cypress/psoc6/CMakeLists.txt @@ -12,3 +12,5 @@ zephyr_sources( zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_PSOC6 NOINIT noinit.ld) zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_PSOC6 RWDATA rwdata.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/cypress/psoc6/linker.ld b/soc/arm/cypress/psoc6/linker.ld deleted file mode 100644 index e0657c31ee5..00000000000 --- a/soc/arm/cypress/psoc6/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Cypress - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - - -#include diff --git a/soc/arm/gigadevice/gd32a50x/CMakeLists.txt b/soc/arm/gigadevice/gd32a50x/CMakeLists.txt index 6691c489648..033272f3619 100644 --- a/soc/arm/gigadevice/gd32a50x/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32a50x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32a50x/linker.ld b/soc/arm/gigadevice/gd32a50x/linker.ld deleted file mode 100644 index 34a8f747bdc..00000000000 --- a/soc/arm/gigadevice/gd32a50x/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2021 Teslabs Engineering S.L. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32e10x/CMakeLists.txt b/soc/arm/gigadevice/gd32e10x/CMakeLists.txt index 58df401dc74..18c19936f9f 100644 --- a/soc/arm/gigadevice/gd32e10x/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32e10x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32e10x/linker.ld b/soc/arm/gigadevice/gd32e10x/linker.ld deleted file mode 100644 index 1223f99d929..00000000000 --- a/soc/arm/gigadevice/gd32e10x/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2021 YuLong Yao - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32e50x/CMakeLists.txt b/soc/arm/gigadevice/gd32e50x/CMakeLists.txt index d320b8ec86e..bcb019aac62 100644 --- a/soc/arm/gigadevice/gd32e50x/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32e50x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32e50x/linker.ld b/soc/arm/gigadevice/gd32e50x/linker.ld deleted file mode 100644 index 34a8f747bdc..00000000000 --- a/soc/arm/gigadevice/gd32e50x/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2021 Teslabs Engineering S.L. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32f3x0/CMakeLists.txt b/soc/arm/gigadevice/gd32f3x0/CMakeLists.txt index 012b6cddc94..a6856dbe680 100644 --- a/soc/arm/gigadevice/gd32f3x0/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32f3x0/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32f3x0/linker.ld b/soc/arm/gigadevice/gd32f3x0/linker.ld deleted file mode 100644 index 67650d4eb8d..00000000000 --- a/soc/arm/gigadevice/gd32f3x0/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2021 BrainCo Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32f403/CMakeLists.txt b/soc/arm/gigadevice/gd32f403/CMakeLists.txt index 0003b5a9de2..af30be8f737 100644 --- a/soc/arm/gigadevice/gd32f403/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32f403/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32f403/linker.ld b/soc/arm/gigadevice/gd32f403/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/gigadevice/gd32f403/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32f4xx/CMakeLists.txt b/soc/arm/gigadevice/gd32f4xx/CMakeLists.txt index 9d80226466c..dd55a9bcdb1 100644 --- a/soc/arm/gigadevice/gd32f4xx/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32f4xx/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32f4xx/linker.ld b/soc/arm/gigadevice/gd32f4xx/linker.ld deleted file mode 100644 index 34a8f747bdc..00000000000 --- a/soc/arm/gigadevice/gd32f4xx/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2021 Teslabs Engineering S.L. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/gigadevice/gd32l23x/CMakeLists.txt b/soc/arm/gigadevice/gd32l23x/CMakeLists.txt index 21581379afa..217e6940926 100644 --- a/soc/arm/gigadevice/gd32l23x/CMakeLists.txt +++ b/soc/arm/gigadevice/gd32l23x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/gigadevice/gd32l23x/linker.ld b/soc/arm/gigadevice/gd32l23x/linker.ld deleted file mode 100644 index 520d4ee69f0..00000000000 --- a/soc/arm/gigadevice/gd32l23x/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2022 BrainCo Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/infineon_cat1/psoc6/CMakeLists.txt b/soc/arm/infineon_cat1/psoc6/CMakeLists.txt index e047fc704bb..26c9fb8cd9c 100644 --- a/soc/arm/infineon_cat1/psoc6/CMakeLists.txt +++ b/soc/arm/infineon_cat1/psoc6/CMakeLists.txt @@ -17,3 +17,5 @@ zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1A RAM_SECTIONS SORT_K zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1A RAMFUNC_SECTION SORT_KEY 0 ram_func.ld) zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1 RODATA SORT_KEY 0 rom.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/infineon_cat1/psoc6/linker.ld b/soc/arm/infineon_cat1/psoc6/linker.ld deleted file mode 100644 index 9af77e1c523..00000000000 --- a/soc/arm/infineon_cat1/psoc6/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or - * an affiliate of Cypress Semiconductor Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/infineon_xmc/4xxx/CMakeLists.txt b/soc/arm/infineon_xmc/4xxx/CMakeLists.txt index 124571032e1..8216f9a09ee 100644 --- a/soc/arm/infineon_xmc/4xxx/CMakeLists.txt +++ b/soc/arm/infineon_xmc/4xxx/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_sources(soc.c) zephyr_linker_sources(NOINIT noinit.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/infineon_xmc/4xxx/linker.ld b/soc/arm/infineon_xmc/4xxx/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/infineon_xmc/4xxx/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/intel_socfpga_std/cyclonev/CMakeLists.txt b/soc/arm/intel_socfpga_std/cyclonev/CMakeLists.txt index 68f5199d81c..4b94d9047e4 100644 --- a/soc/arm/intel_socfpga_std/cyclonev/CMakeLists.txt +++ b/soc/arm/intel_socfpga_std/cyclonev/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_include_directories(.) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/intel_socfpga_std/cyclonev/linker.ld b/soc/arm/intel_socfpga_std/cyclonev/linker.ld deleted file mode 100644 index ef4c62338b4..00000000000 --- a/soc/arm/intel_socfpga_std/cyclonev/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2022 Intel Corporation - * SPDX-License-Identifier: Apache-2.0 - * Description: - * Adding support for Cyclone V SoC FPGA, using arm32 linker - */ - -#include diff --git a/soc/arm/microchip_mec/mec1501/CMakeLists.txt b/soc/arm/microchip_mec/mec1501/CMakeLists.txt index 70889bc982b..e92250a6989 100644 --- a/soc/arm/microchip_mec/mec1501/CMakeLists.txt +++ b/soc/arm/microchip_mec/mec1501/CMakeLists.txt @@ -21,3 +21,5 @@ if(CONFIG_SOC_HAS_TIMING_FUNCTIONS AND NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) endif() endif() endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/microchip_mec/mec1501/linker.ld b/soc/arm/microchip_mec/mec1501/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/microchip_mec/mec1501/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/microchip_mec/mec172x/CMakeLists.txt b/soc/arm/microchip_mec/mec172x/CMakeLists.txt index 3581ce69b40..59f3b5e4d2b 100644 --- a/soc/arm/microchip_mec/mec172x/CMakeLists.txt +++ b/soc/arm/microchip_mec/mec172x/CMakeLists.txt @@ -21,3 +21,5 @@ if(CONFIG_SOC_HAS_TIMING_FUNCTIONS AND NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) endif() endif() endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/microchip_mec/mec172x/linker.ld b/soc/arm/microchip_mec/mec172x/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/microchip_mec/mec172x/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt index 1a8b943ad5b..44d139e422a 100644 --- a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt @@ -10,3 +10,5 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/arm/include ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf51/linker.ld b/soc/arm/nordic_nrf/nrf51/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/nordic_nrf/nrf51/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index 24fdcf6093e..04e255a3eb1 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -22,3 +22,5 @@ if(CONFIG_SOC_NRF52832) endif() endif() endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf52/linker.ld b/soc/arm/nordic_nrf/nrf52/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/nordic_nrf/nrf52/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt index af4fe549a63..b4e82f52c28 100644 --- a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt @@ -19,3 +19,5 @@ if (CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED AND At your own risk, you can suppress this warning by setting CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED=n.") endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf53/linker.ld b/soc/arm/nordic_nrf/nrf53/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/nordic_nrf/nrf53/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf91/linker.ld b/soc/arm/nordic_nrf/nrf91/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/nordic_nrf/nrf91/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nuvoton_npcx/npcx4/CMakeLists.txt b/soc/arm/nuvoton_npcx/npcx4/CMakeLists.txt index ee55c1c2a5b..158ae5cbbc7 100644 --- a/soc/arm/nuvoton_npcx/npcx4/CMakeLists.txt +++ b/soc/arm/nuvoton_npcx/npcx4/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nuvoton_npcx/npcx4/linker.ld b/soc/arm/nuvoton_npcx/npcx4/linker.ld deleted file mode 100644 index 36859865d02..00000000000 --- a/soc/arm/nuvoton_npcx/npcx4/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2023 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nuvoton_npcx/npcx7/CMakeLists.txt b/soc/arm/nuvoton_npcx/npcx7/CMakeLists.txt index c4b945e8ad1..01792bf9fce 100644 --- a/soc/arm/nuvoton_npcx/npcx7/CMakeLists.txt +++ b/soc/arm/nuvoton_npcx/npcx7/CMakeLists.txt @@ -10,3 +10,5 @@ zephyr_sources_ifdef( CONFIG_ARM_MPU mpu_regions.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nuvoton_npcx/npcx7/linker.ld b/soc/arm/nuvoton_npcx/npcx7/linker.ld deleted file mode 100644 index c27b59604dc..00000000000 --- a/soc/arm/nuvoton_npcx/npcx7/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2020 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nuvoton_npcx/npcx9/CMakeLists.txt b/soc/arm/nuvoton_npcx/npcx9/CMakeLists.txt index 5b2aad82a5a..56f793d0580 100644 --- a/soc/arm/nuvoton_npcx/npcx9/CMakeLists.txt +++ b/soc/arm/nuvoton_npcx/npcx9/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(${ZEPHYR_BASE}/drivers) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nuvoton_npcx/npcx9/linker.ld b/soc/arm/nuvoton_npcx/npcx9/linker.ld deleted file mode 100644 index a07329b6360..00000000000 --- a/soc/arm/nuvoton_npcx/npcx9/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2021 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nuvoton_numaker/m46x/CMakeLists.txt b/soc/arm/nuvoton_numaker/m46x/CMakeLists.txt index 6b2126d22bd..2fa91b640cf 100644 --- a/soc/arm/nuvoton_numaker/m46x/CMakeLists.txt +++ b/soc/arm/nuvoton_numaker/m46x/CMakeLists.txt @@ -3,3 +3,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nuvoton_numaker/m46x/linker.ld b/soc/arm/nuvoton_numaker/m46x/linker.ld deleted file mode 100644 index 37c968fda63..00000000000 --- a/soc/arm/nuvoton_numaker/m46x/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nuvoton_numicro/m48x/CMakeLists.txt b/soc/arm/nuvoton_numicro/m48x/CMakeLists.txt index 5d14a880fef..322465a92ce 100644 --- a/soc/arm/nuvoton_numicro/m48x/CMakeLists.txt +++ b/soc/arm/nuvoton_numicro/m48x/CMakeLists.txt @@ -4,3 +4,5 @@ # Author: Saravanan Sekar zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nuvoton_numicro/m48x/linker.ld b/soc/arm/nuvoton_numicro/m48x/linker.ld deleted file mode 100644 index 737722a1611..00000000000 --- a/soc/arm/nuvoton_numicro/m48x/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright (c) 2020 Linumiz - */ - -#include diff --git a/soc/arm/nxp_imx/mcimx6x_m4/CMakeLists.txt b/soc/arm/nxp_imx/mcimx6x_m4/CMakeLists.txt index a720300fca1..ee28789fe7d 100644 --- a/soc/arm/nxp_imx/mcimx6x_m4/CMakeLists.txt +++ b/soc/arm/nxp_imx/mcimx6x_m4/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( soc.c soc_clk_freq.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/mcimx6x_m4/linker.ld b/soc/arm/nxp_imx/mcimx6x_m4/linker.ld deleted file mode 100644 index 3cf863608e1..00000000000 --- a/soc/arm/nxp_imx/mcimx6x_m4/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nxp_imx/mcimx7_m4/CMakeLists.txt b/soc/arm/nxp_imx/mcimx7_m4/CMakeLists.txt index f6aa4ef3332..e5c7ae22fd6 100644 --- a/soc/arm/nxp_imx/mcimx7_m4/CMakeLists.txt +++ b/soc/arm/nxp_imx/mcimx7_m4/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( soc.c soc_clk_freq.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/mcimx7_m4/linker.ld b/soc/arm/nxp_imx/mcimx7_m4/linker.ld deleted file mode 100644 index 3cf863608e1..00000000000 --- a/soc/arm/nxp_imx/mcimx7_m4/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nxp_imx/mimx8ml8_m7/CMakeLists.txt b/soc/arm/nxp_imx/mimx8ml8_m7/CMakeLists.txt index a992a8509b4..3dce744104f 100644 --- a/soc/arm/nxp_imx/mimx8ml8_m7/CMakeLists.txt +++ b/soc/arm/nxp_imx/mimx8ml8_m7/CMakeLists.txt @@ -15,3 +15,5 @@ if(CONFIG_OPENAMP_RSC_TABLE) zephyr_linker_section(NAME .resource_table GROUP ROM_REGION NOINPUT) zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*") endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt index 468b44a4588..c73bf2188c6 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt +++ b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt @@ -12,3 +12,5 @@ if(CONFIG_OPENAMP_RSC_TABLE) zephyr_linker_section(NAME .resource_table GROUP ROM_REGION NOINPUT) zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*") endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/mimx8mq6_m4/CMakeLists.txt b/soc/arm/nxp_imx/mimx8mq6_m4/CMakeLists.txt index af5db79548a..9555fd57a89 100644 --- a/soc/arm/nxp_imx/mimx8mq6_m4/CMakeLists.txt +++ b/soc/arm/nxp_imx/mimx8mq6_m4/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld b/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld deleted file mode 100644 index 895341fda8d..00000000000 --- a/soc/arm/nxp_imx/mimx8mq6_m4/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021, Kwon Tae-young - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/nxp_imx/rt/CMakeLists.txt b/soc/arm/nxp_imx/rt/CMakeLists.txt index 5bfc8d336fc..125db4957f8 100644 --- a/soc/arm/nxp_imx/rt/CMakeLists.txt +++ b/soc/arm/nxp_imx/rt/CMakeLists.txt @@ -59,3 +59,5 @@ zephyr_linker_section_configure( KEEP PRIO 11 ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/rt5xx/CMakeLists.txt b/soc/arm/nxp_imx/rt5xx/CMakeLists.txt index f3c6404d185..e12f2e9ae18 100644 --- a/soc/arm/nxp_imx/rt5xx/CMakeLists.txt +++ b/soc/arm/nxp_imx/rt5xx/CMakeLists.txt @@ -29,3 +29,5 @@ zephyr_linker_sources_ifdef(CONFIG_USB_DEVICE_DRIVER SECTIONS usb.ld) zephyr_code_relocate(FILES flash_clock_setup.c LOCATION RAM) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/rt6xx/CMakeLists.txt b/soc/arm/nxp_imx/rt6xx/CMakeLists.txt index a5a853cd853..57d5cb3fd04 100644 --- a/soc/arm/nxp_imx/rt6xx/CMakeLists.txt +++ b/soc/arm/nxp_imx/rt6xx/CMakeLists.txt @@ -32,3 +32,5 @@ zephyr_linker_sources_ifdef(CONFIG_USB_DEVICE_DRIVER if(CONFIG_FLASH_MCUX_FLEXSPI_XIP) zephyr_code_relocate(FILES flash_clock_setup.c LOCATION RAM) endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_imx/rt6xx/linker.ld b/soc/arm/nxp_imx/rt6xx/linker.ld deleted file mode 100644 index cf5cc4c9968..00000000000 --- a/soc/arm/nxp_imx/rt6xx/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2020, NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - - -#include diff --git a/soc/arm/nxp_kinetis/k2x/CMakeLists.txt b/soc/arm/nxp_kinetis/k2x/CMakeLists.txt index f61746c2610..017787396e4 100644 --- a/soc/arm/nxp_kinetis/k2x/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/k2x/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/k2x/linker.ld b/soc/arm/nxp_kinetis/k2x/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/k2x/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/k6x/CMakeLists.txt b/soc/arm/nxp_kinetis/k6x/CMakeLists.txt index d26821f690b..8cf7a11f62e 100644 --- a/soc/arm/nxp_kinetis/k6x/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/k6x/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources_ifdef( CONFIG_ARM_MPU nxp_mpu_regions.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/k6x/linker.ld b/soc/arm/nxp_kinetis/k6x/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/k6x/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/k8x/CMakeLists.txt b/soc/arm/nxp_kinetis/k8x/CMakeLists.txt index d26821f690b..8cf7a11f62e 100644 --- a/soc/arm/nxp_kinetis/k8x/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/k8x/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources_ifdef( CONFIG_ARM_MPU nxp_mpu_regions.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/k8x/linker.ld b/soc/arm/nxp_kinetis/k8x/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/k8x/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/ke1xf/CMakeLists.txt b/soc/arm/nxp_kinetis/ke1xf/CMakeLists.txt index 0b26284343c..ccbf2208d5a 100644 --- a/soc/arm/nxp_kinetis/ke1xf/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/ke1xf/CMakeLists.txt @@ -11,3 +11,5 @@ zephyr_sources_ifdef( CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/ke1xf/linker.ld b/soc/arm/nxp_kinetis/ke1xf/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/ke1xf/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/kl2x/CMakeLists.txt b/soc/arm/nxp_kinetis/kl2x/CMakeLists.txt index 9486f255912..268f065fb12 100644 --- a/soc/arm/nxp_kinetis/kl2x/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/kl2x/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/kl2x/linker.ld b/soc/arm/nxp_kinetis/kl2x/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/kl2x/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/kv5x/CMakeLists.txt b/soc/arm/nxp_kinetis/kv5x/CMakeLists.txt index 332416ba43b..7424bb9f7b9 100644 --- a/soc/arm/nxp_kinetis/kv5x/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/kv5x/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/kv5x/linker.ld b/soc/arm/nxp_kinetis/kv5x/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/kv5x/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_kinetis/kwx/CMakeLists.txt b/soc/arm/nxp_kinetis/kwx/CMakeLists.txt index 9b651c95828..d414d72a63a 100644 --- a/soc/arm/nxp_kinetis/kwx/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/kwx/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources_ifdef(CONFIG_SOC_MKW24D5 soc_kw2xd.c) zephyr_sources_ifdef(CONFIG_SOC_MKW22D5 soc_kw2xd.c) zephyr_sources_ifdef(CONFIG_SOC_MKW41Z4 soc_kw4xz.c) zephyr_sources_ifdef(CONFIG_SOC_MKW40Z4 soc_kw4xz.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_kinetis/kwx/linker.ld b/soc/arm/nxp_kinetis/kwx/linker.ld deleted file mode 100644 index 7a1df7beaa5..00000000000 --- a/soc/arm/nxp_kinetis/kwx/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - -#include diff --git a/soc/arm/nxp_lpc/lpc11u6x/CMakeLists.txt b/soc/arm/nxp_lpc/lpc11u6x/CMakeLists.txt index 84686ad59cd..e9a04818a93 100644 --- a/soc/arm/nxp_lpc/lpc11u6x/CMakeLists.txt +++ b/soc/arm/nxp_lpc/lpc11u6x/CMakeLists.txt @@ -3,3 +3,5 @@ # # SPDX-License-Identifier: Apache-2.0 # + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_lpc/lpc11u6x/linker.ld b/soc/arm/nxp_lpc/lpc11u6x/linker.ld deleted file mode 100644 index ad9319b4977..00000000000 --- a/soc/arm/nxp_lpc/lpc11u6x/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images and XIP images. - */ - - -#include diff --git a/soc/arm/nxp_lpc/lpc51u68/CMakeLists.txt b/soc/arm/nxp_lpc/lpc51u68/CMakeLists.txt index c2ef013fe62..a0b6a030303 100644 --- a/soc/arm/nxp_lpc/lpc51u68/CMakeLists.txt +++ b/soc/arm/nxp_lpc/lpc51u68/CMakeLists.txt @@ -11,3 +11,5 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/${ARCH}/include ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt b/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt index 09fdf8ae51a..fda5d9532e8 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt +++ b/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt @@ -19,3 +19,5 @@ zephyr_library_include_directories( if(NOT DEFINED CONFIG_LPC54XXX_SRAM2_CLOCK) zephyr_compile_definitions(DONT_ENABLE_DISABLED_RAMBANKS=1) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt b/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt index 22bb1ed0d55..fb58ca649f2 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt +++ b/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt @@ -23,3 +23,5 @@ endif() if(NOT DEFINED CONFIG_LPC55XXX_SRAM_CLOCKS) zephyr_compile_definitions(DONT_ENABLE_DISABLED_RAMBANKS=1) endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_s32/s32k/CMakeLists.txt b/soc/arm/nxp_s32/s32k/CMakeLists.txt index f223c351a70..d65a1a2e73b 100644 --- a/soc/arm/nxp_s32/s32k/CMakeLists.txt +++ b/soc/arm/nxp_s32/s32k/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_library_sources(soc.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS mpu_regions.c) zephyr_linker_sources(SECTIONS sections.ld) zephyr_library_sources_ifdef(CONFIG_PLATFORM_SPECIFIC_INIT s32k3xx_startup.S) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_s32/s32ze/CMakeLists.txt b/soc/arm/nxp_s32/s32ze/CMakeLists.txt index 155354816f3..d0eb4cf78b1 100644 --- a/soc/arm/nxp_s32/s32ze/CMakeLists.txt +++ b/soc/arm/nxp_s32/s32ze/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_library_sources( ) zephyr_library_sources_ifdef(CONFIG_ARM_MPU mpu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nxp_s32/s32ze/linker.ld b/soc/arm/nxp_s32/s32ze/linker.ld deleted file mode 100644 index d04a2dc6065..00000000000 --- a/soc/arm/nxp_s32/s32ze/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2022 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/quicklogic_eos_s3/CMakeLists.txt b/soc/arm/quicklogic_eos_s3/CMakeLists.txt index 5da2746a1bc..224b298c409 100644 --- a/soc/arm/quicklogic_eos_s3/CMakeLists.txt +++ b/soc/arm/quicklogic_eos_s3/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/quicklogic_eos_s3/linker.ld b/soc/arm/quicklogic_eos_s3/linker.ld deleted file mode 100644 index 5d2ea23f266..00000000000 --- a/soc/arm/quicklogic_eos_s3/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* -# Copyright (c) 2020 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/renesas_rcar/gen3/CMakeLists.txt b/soc/arm/renesas_rcar/gen3/CMakeLists.txt index 092b4b2c828..4356fe77d51 100644 --- a/soc/arm/renesas_rcar/gen3/CMakeLists.txt +++ b/soc/arm/renesas_rcar/gen3/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_sources( soc.c ) zephyr_library_sources_ifdef(CONFIG_SOC_R8A77951 pfc_r8a77951.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/renesas_rcar/gen3/linker.ld b/soc/arm/renesas_rcar/gen3/linker.ld deleted file mode 100644 index f94542d9256..00000000000 --- a/soc/arm/renesas_rcar/gen3/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021 IoT.bzh - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/renesas_smartbond/da1469x/CMakeLists.txt b/soc/arm/renesas_smartbond/da1469x/CMakeLists.txt index 094293e9f32..115f3a34028 100644 --- a/soc/arm/renesas_smartbond/da1469x/CMakeLists.txt +++ b/soc/arm/renesas_smartbond/da1469x/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_linker_sources( ) zephyr_library() zephyr_library_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/renesas_smartbond/da1469x/linker.ld b/soc/arm/renesas_smartbond/da1469x/linker.ld deleted file mode 100644 index dfa36b95d49..00000000000 --- a/soc/arm/renesas_smartbond/da1469x/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2022 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/rpi_pico/rp2/CMakeLists.txt b/soc/arm/rpi_pico/rp2/CMakeLists.txt index 210f5623ae9..119517e5e1c 100644 --- a/soc/arm/rpi_pico/rp2/CMakeLists.txt +++ b/soc/arm/rpi_pico/rp2/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_library() zephyr_library_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/silabs_exx32/common/CMakeLists.txt b/soc/arm/silabs_exx32/common/CMakeLists.txt index ac965e28d46..27e11228b97 100644 --- a/soc/arm/silabs_exx32/common/CMakeLists.txt +++ b/soc/arm/silabs_exx32/common/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_sources_ifdef(CONFIG_SOC_GECKO_PM_BACKEND_EMU soc_power.c) zephyr_sources_ifdef(CONFIG_SOC_GECKO_PM_BACKEND_PMGR soc_power_pmgr.c) zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/silabs_exx32/efm32gg11b/linker.ld b/soc/arm/silabs_exx32/efm32gg11b/linker.ld deleted file mode 100644 index 120507fb63f..00000000000 --- a/soc/arm/silabs_exx32/efm32gg11b/linker.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2019 Interay Solutions B.V. - * Copyright (c) 2019 Oane Kingma - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efm32gg12b/linker.ld b/soc/arm/silabs_exx32/efm32gg12b/linker.ld deleted file mode 100644 index f478ff72c40..00000000000 --- a/soc/arm/silabs_exx32/efm32gg12b/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - -#include diff --git a/soc/arm/silabs_exx32/efm32hg/linker.ld b/soc/arm/silabs_exx32/efm32hg/linker.ld deleted file mode 100644 index da96a05932a..00000000000 --- a/soc/arm/silabs_exx32/efm32hg/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Marcio Montenegro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efm32jg12b/linker.ld b/soc/arm/silabs_exx32/efm32jg12b/linker.ld deleted file mode 100644 index cb2bbd2fdf1..00000000000 --- a/soc/arm/silabs_exx32/efm32jg12b/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efm32pg12b/linker.ld b/soc/arm/silabs_exx32/efm32pg12b/linker.ld deleted file mode 100644 index cb2bbd2fdf1..00000000000 --- a/soc/arm/silabs_exx32/efm32pg12b/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efm32pg1b/linker.ld b/soc/arm/silabs_exx32/efm32pg1b/linker.ld deleted file mode 100644 index cb2bbd2fdf1..00000000000 --- a/soc/arm/silabs_exx32/efm32pg1b/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efm32wg/linker.ld b/soc/arm/silabs_exx32/efm32wg/linker.ld deleted file mode 100644 index d877abf5fd4..00000000000 --- a/soc/arm/silabs_exx32/efm32wg/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2017 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32bg13p/linker.ld b/soc/arm/silabs_exx32/efr32bg13p/linker.ld deleted file mode 100644 index 09c3e1cf943..00000000000 --- a/soc/arm/silabs_exx32/efr32bg13p/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Diego Sueiro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32bg22/linker.ld b/soc/arm/silabs_exx32/efr32bg22/linker.ld deleted file mode 100644 index 38d9b250c5b..00000000000 --- a/soc/arm/silabs_exx32/efr32bg22/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021 Sateesh Kotapati - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - -#include diff --git a/soc/arm/silabs_exx32/efr32bg27/linker.ld b/soc/arm/silabs_exx32/efr32bg27/linker.ld deleted file mode 100644 index b65086a5ce1..00000000000 --- a/soc/arm/silabs_exx32/efr32bg27/linker.ld +++ /dev/null @@ -1,5 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/silabs_exx32/efr32fg13p/linker.ld b/soc/arm/silabs_exx32/efr32fg13p/linker.ld deleted file mode 100644 index cb2bbd2fdf1..00000000000 --- a/soc/arm/silabs_exx32/efr32fg13p/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32fg1p/linker.ld b/soc/arm/silabs_exx32/efr32fg1p/linker.ld deleted file mode 100644 index cb2bbd2fdf1..00000000000 --- a/soc/arm/silabs_exx32/efr32fg1p/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32mg12p/linker.ld b/soc/arm/silabs_exx32/efr32mg12p/linker.ld deleted file mode 100644 index 09c3e1cf943..00000000000 --- a/soc/arm/silabs_exx32/efr32mg12p/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 Diego Sueiro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32mg21/linker.ld b/soc/arm/silabs_exx32/efr32mg21/linker.ld deleted file mode 100644 index 7295169eae8..00000000000 --- a/soc/arm/silabs_exx32/efr32mg21/linker.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2020 TriaGnoSys GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - - -#include diff --git a/soc/arm/silabs_exx32/efr32mg24/linker.ld b/soc/arm/silabs_exx32/efr32mg24/linker.ld deleted file mode 100644 index 0d44f863613..00000000000 --- a/soc/arm/silabs_exx32/efr32mg24/linker.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2021 Sateesh Kotapati - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * This is the linker script for both standard images. - */ - -#include - -#include diff --git a/soc/arm/st_stm32/stm32c0/CMakeLists.txt b/soc/arm/st_stm32/stm32c0/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32c0/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32c0/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32c0/linker.ld b/soc/arm/st_stm32/stm32c0/linker.ld deleted file mode 100644 index d5f07ed942a..00000000000 --- a/soc/arm/st_stm32/stm32c0/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2023 Benjamin Björnsson - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f0/CMakeLists.txt b/soc/arm/st_stm32/stm32f0/CMakeLists.txt index 56b5d1ffa8e..914e395d27a 100644 --- a/soc/arm/st_stm32/stm32f0/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f0/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_linker_sources_ifdef(CONFIG_SRAM_VECTOR_TABLE ) zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f0/linker.ld b/soc/arm/st_stm32/stm32f0/linker.ld deleted file mode 100644 index c39286d86f5..00000000000 --- a/soc/arm/st_stm32/stm32f0/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f1/CMakeLists.txt b/soc/arm/st_stm32/stm32f1/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32f1/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f1/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f1/linker.ld b/soc/arm/st_stm32/stm32f1/linker.ld deleted file mode 100644 index c39286d86f5..00000000000 --- a/soc/arm/st_stm32/stm32f1/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f2/CMakeLists.txt b/soc/arm/st_stm32/stm32f2/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32f2/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f2/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f2/linker.ld b/soc/arm/st_stm32/stm32f2/linker.ld deleted file mode 100644 index b5f5c77d59c..00000000000 --- a/soc/arm/st_stm32/stm32f2/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2018 qianfan Zhao - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f3/CMakeLists.txt b/soc/arm/st_stm32/stm32f3/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32f3/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f3/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f3/linker.ld b/soc/arm/st_stm32/stm32f3/linker.ld deleted file mode 100644 index c39286d86f5..00000000000 --- a/soc/arm/st_stm32/stm32f3/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f4/CMakeLists.txt b/soc/arm/st_stm32/stm32f4/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32f4/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f4/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f4/linker.ld b/soc/arm/st_stm32/stm32f4/linker.ld deleted file mode 100644 index c39286d86f5..00000000000 --- a/soc/arm/st_stm32/stm32f4/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32f7/CMakeLists.txt b/soc/arm/st_stm32/stm32f7/CMakeLists.txt index ac3ba70ace6..e02052e3946 100644 --- a/soc/arm/st_stm32/stm32f7/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f7/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32f7/linker.ld b/soc/arm/st_stm32/stm32f7/linker.ld deleted file mode 100644 index be06b7accb6..00000000000 --- a/soc/arm/st_stm32/stm32f7/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2018 Yurii Hamann - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32g0/CMakeLists.txt b/soc/arm/st_stm32/stm32g0/CMakeLists.txt index aff2873dc18..85869a31ddf 100644 --- a/soc/arm/st_stm32/stm32g0/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32g0/CMakeLists.txt @@ -9,3 +9,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32g0/linker.ld b/soc/arm/st_stm32/stm32g0/linker.ld deleted file mode 100644 index a5c6d669295..00000000000 --- a/soc/arm/st_stm32/stm32g0/linker.ld +++ /dev/null @@ -1,10 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 Philippe Retornaz - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32g4/CMakeLists.txt b/soc/arm/st_stm32/stm32g4/CMakeLists.txt index d924a7b2840..04911a6a2e4 100644 --- a/soc/arm/st_stm32/stm32g4/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32g4/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32g4/linker.ld b/soc/arm/st_stm32/stm32g4/linker.ld deleted file mode 100644 index 8053c5cfc11..00000000000 --- a/soc/arm/st_stm32/stm32g4/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 Richard Osterloh - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32h5/CMakeLists.txt b/soc/arm/st_stm32/stm32h5/CMakeLists.txt index 9cb843e9caf..c8d32ef22aa 100644 --- a/soc/arm/st_stm32/stm32h5/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32h5/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_sources( soc.c ) zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32h5/linker.ld b/soc/arm/st_stm32/stm32h5/linker.ld deleted file mode 100644 index f20e6999579..00000000000 --- a/soc/arm/st_stm32/stm32h5/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2023 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32h7/CMakeLists.txt b/soc/arm/st_stm32/stm32h7/CMakeLists.txt index 24f6f90e6e4..d1ae6c3325d 100644 --- a/soc/arm/st_stm32/stm32h7/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32h7/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources_ifdef(CONFIG_CPU_CORTEX_M4 soc_m4.c) zephyr_sources(mpu_regions.c) zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32h7/linker.ld b/soc/arm/st_stm32/stm32h7/linker.ld deleted file mode 100644 index 20713e9bfd3..00000000000 --- a/soc/arm/st_stm32/stm32h7/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32l0/CMakeLists.txt b/soc/arm/st_stm32/stm32l0/CMakeLists.txt index 59be7817eab..0fd5073770d 100644 --- a/soc/arm/st_stm32/stm32l0/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32l0/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32l0/linker.ld b/soc/arm/st_stm32/stm32l0/linker.ld deleted file mode 100644 index 31b070c6950..00000000000 --- a/soc/arm/st_stm32/stm32l0/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2018 Endre Karlson - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32l1/CMakeLists.txt b/soc/arm/st_stm32/stm32l1/CMakeLists.txt index 844c5252009..68bf00e81c1 100644 --- a/soc/arm/st_stm32/stm32l1/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32l1/CMakeLists.txt @@ -2,3 +2,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32l1/linker.ld b/soc/arm/st_stm32/stm32l1/linker.ld deleted file mode 100644 index 0bbb83d949b..00000000000 --- a/soc/arm/st_stm32/stm32l1/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 Linaro Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32l4/CMakeLists.txt b/soc/arm/st_stm32/stm32l4/CMakeLists.txt index 8f4b837538d..94edc262274 100644 --- a/soc/arm/st_stm32/stm32l4/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32l4/CMakeLists.txt @@ -10,3 +10,5 @@ zephyr_sources_ifdef(CONFIG_PM ) zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32l4/linker.ld b/soc/arm/st_stm32/stm32l4/linker.ld deleted file mode 100644 index c39286d86f5..00000000000 --- a/soc/arm/st_stm32/stm32l4/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014-2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32l5/CMakeLists.txt b/soc/arm/st_stm32/stm32l5/CMakeLists.txt index 59be7817eab..0fd5073770d 100644 --- a/soc/arm/st_stm32/stm32l5/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32l5/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32l5/linker.ld b/soc/arm/st_stm32/stm32l5/linker.ld deleted file mode 100644 index 987547b1ee1..00000000000 --- a/soc/arm/st_stm32/stm32l5/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2020 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32mp1/CMakeLists.txt b/soc/arm/st_stm32/stm32mp1/CMakeLists.txt index 4a1dfd30503..7805c0ffbf2 100644 --- a/soc/arm/st_stm32/stm32mp1/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32mp1/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32u5/CMakeLists.txt b/soc/arm/st_stm32/stm32u5/CMakeLists.txt index 8f4b837538d..94edc262274 100644 --- a/soc/arm/st_stm32/stm32u5/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32u5/CMakeLists.txt @@ -10,3 +10,5 @@ zephyr_sources_ifdef(CONFIG_PM ) zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32u5/linker.ld b/soc/arm/st_stm32/stm32u5/linker.ld deleted file mode 100644 index a5b0e37e825..00000000000 --- a/soc/arm/st_stm32/stm32u5/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2021 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32wb/CMakeLists.txt b/soc/arm/st_stm32/stm32wb/CMakeLists.txt index 2b21a72d326..32ce62ee530 100644 --- a/soc/arm/st_stm32/stm32wb/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32wb/CMakeLists.txt @@ -13,3 +13,5 @@ zephyr_sources_ifdef(CONFIG_PM ) zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32wb/linker.ld b/soc/arm/st_stm32/stm32wb/linker.ld deleted file mode 100644 index 20713e9bfd3..00000000000 --- a/soc/arm/st_stm32/stm32wb/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32wba/CMakeLists.txt b/soc/arm/st_stm32/stm32wba/CMakeLists.txt index 59be7817eab..0fd5073770d 100644 --- a/soc/arm/st_stm32/stm32wba/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32wba/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32wba/linker.ld b/soc/arm/st_stm32/stm32wba/linker.ld deleted file mode 100644 index f20e6999579..00000000000 --- a/soc/arm/st_stm32/stm32wba/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2023 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/st_stm32/stm32wl/CMakeLists.txt b/soc/arm/st_stm32/stm32wl/CMakeLists.txt index 40ff85ccbbe..af44cc273e1 100644 --- a/soc/arm/st_stm32/stm32wl/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32wl/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources_ifdef(CONFIG_PM ) zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/st_stm32/stm32wl/linker.ld b/soc/arm/st_stm32/stm32wl/linker.ld deleted file mode 100644 index c81df32357e..00000000000 --- a/soc/arm/st_stm32/stm32wl/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2020 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/ti_k3/am62x_m4/CMakeLists.txt b/soc/arm/ti_k3/am62x_m4/CMakeLists.txt index e8d816988de..bc9b13ea188 100644 --- a/soc/arm/ti_k3/am62x_m4/CMakeLists.txt +++ b/soc/arm/ti_k3/am62x_m4/CMakeLists.txt @@ -9,3 +9,5 @@ if(CONFIG_OPENAMP_RSC_TABLE) zephyr_linker_section(NAME .resource_table GROUP ROM_REGION NOINPUT) zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*") endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_lm3s6965/CMakeLists.txt b/soc/arm/ti_lm3s6965/CMakeLists.txt index c5f6f41f49a..c76906ff5c3 100644 --- a/soc/arm/ti_lm3s6965/CMakeLists.txt +++ b/soc/arm/ti_lm3s6965/CMakeLists.txt @@ -12,3 +12,5 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/arm/include ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_lm3s6965/linker.ld b/soc/arm/ti_lm3s6965/linker.ld deleted file mode 100644 index 757d858cb69..00000000000 --- a/soc/arm/ti_lm3s6965/linker.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/CMakeLists.txt b/soc/arm/ti_simplelink/cc13x2_cc26x2/CMakeLists.txt index d2a17487383..bf52a055e3b 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/CMakeLists.txt +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/CMakeLists.txt @@ -11,3 +11,5 @@ endif() zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) zephyr_linker_sources_ifdef(CONFIG_HAS_TI_CCFG SECTIONS ccfg.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld b/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld deleted file mode 100644 index 643b4899397..00000000000 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file - * - * Copyright (c) 2019 Brett Witherspoon - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/CMakeLists.txt b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/CMakeLists.txt index 4a2a41c5a5f..4194f426221 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/CMakeLists.txt +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/CMakeLists.txt @@ -9,3 +9,5 @@ zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_PM_DEVICE power.c) zephyr_linker_sources_ifdef(CONFIG_HAS_TI_CCFG SECTIONS ccfg.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld deleted file mode 100644 index 772be96ca3b..00000000000 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* linker.ld - Linker command/script file - * - * Copyright (c) 2022 Vaishnav Achath - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/ti_simplelink/cc32xx/CMakeLists.txt b/soc/arm/ti_simplelink/cc32xx/CMakeLists.txt index cc11ff41954..9d704214718 100644 --- a/soc/arm/ti_simplelink/cc32xx/CMakeLists.txt +++ b/soc/arm/ti_simplelink/cc32xx/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_include_directories(.) if (DEFINED CONFIG_CC3220SF_DEBUG OR DEFINED CONFIG_CC3235SF_DEBUG) zephyr_linker_sources(ROM_START SORT_KEY 0 cc32xx_debug.ld) endif() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_simplelink/cc32xx/linker.ld b/soc/arm/ti_simplelink/cc32xx/linker.ld deleted file mode 100644 index 812d6f50331..00000000000 --- a/soc/arm/ti_simplelink/cc32xx/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * linker.ld - Linker command/script file - */ - -#include diff --git a/soc/arm/ti_simplelink/msp432p4xx/CMakeLists.txt b/soc/arm/ti_simplelink/msp432p4xx/CMakeLists.txt index 363109a3853..d93f837e79e 100644 --- a/soc/arm/ti_simplelink/msp432p4xx/CMakeLists.txt +++ b/soc/arm/ti_simplelink/msp432p4xx/CMakeLists.txt @@ -2,3 +2,5 @@ zephyr_compile_definitions(-D__MSP432P401R__) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/ti_simplelink/msp432p4xx/linker.ld b/soc/arm/ti_simplelink/msp432p4xx/linker.ld deleted file mode 100644 index 812d6f50331..00000000000 --- a/soc/arm/ti_simplelink/msp432p4xx/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * linker.ld - Linker command/script file - */ - -#include diff --git a/soc/arm/xilinx_zynq7000/xc7zxxx/CMakeLists.txt b/soc/arm/xilinx_zynq7000/xc7zxxx/CMakeLists.txt index 98057786d37..d47bcfb128f 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxx/CMakeLists.txt +++ b/soc/arm/xilinx_zynq7000/xc7zxxx/CMakeLists.txt @@ -4,3 +4,5 @@ # zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld b/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld deleted file mode 100644 index 00ffe9ceff3..00000000000 --- a/soc/arm/xilinx_zynq7000/xc7zxxx/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/xilinx_zynq7000/xc7zxxxs/CMakeLists.txt b/soc/arm/xilinx_zynq7000/xc7zxxxs/CMakeLists.txt index 98057786d37..d47bcfb128f 100644 --- a/soc/arm/xilinx_zynq7000/xc7zxxxs/CMakeLists.txt +++ b/soc/arm/xilinx_zynq7000/xc7zxxxs/CMakeLists.txt @@ -4,3 +4,5 @@ # zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld b/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld deleted file mode 100644 index 00ffe9ceff3..00000000000 --- a/soc/arm/xilinx_zynq7000/xc7zxxxs/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm/xilinx_zynqmp/CMakeLists.txt b/soc/arm/xilinx_zynqmp/CMakeLists.txt index e6654d03cb7..65bf778779b 100644 --- a/soc/arm/xilinx_zynqmp/CMakeLists.txt +++ b/soc/arm/xilinx_zynqmp/CMakeLists.txt @@ -9,3 +9,7 @@ zephyr_sources_ifdef( CONFIG_ARM_MPU arm_mpu_regions.c ) + +if(CONFIG_SOC_XILINX_ZYNQMP_RPU) + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/arm/xilinx_zynqmp/linker.ld b/soc/arm/xilinx_zynqmp/linker.ld deleted file mode 100644 index 4f22c8618cf..00000000000 --- a/soc/arm/xilinx_zynqmp/linker.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2019 Lexmark International, Inc. - * Copyright (c) 2019 Stephanos Ioannidis - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#if defined(CONFIG_SOC_XILINX_ZYNQMP_RPU) -#include -#endif From 84e4f62e5b3c1255c42e01d3bcb3d0f26e79d705 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 23:54:04 +0200 Subject: [PATCH 2972/4498] cmake: arm64: update arm64 SoC to use SOC_LINKER_SCRIPT variable This commit updates all arm64 SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/arm64/arm/fvp_aemv8a/CMakeLists.txt | 2 ++ soc/arm64/arm/fvp_aemv8a/linker.ld | 8 -------- soc/arm64/arm/fvp_aemv8r/CMakeLists.txt | 2 ++ soc/arm64/arm/fvp_aemv8r/linker.ld | 8 -------- soc/arm64/bcm2711/CMakeLists.txt | 2 ++ soc/arm64/bcm2711/linker.ld | 6 ------ soc/arm64/bcm2711/linker_a72.ld | 7 ------- soc/arm64/bcm_vk/viper/CMakeLists.txt | 2 ++ soc/arm64/bcm_vk/viper/linker.ld | 8 -------- soc/arm64/bcm_vk/viper/linker_a72.ld | 7 ------- soc/arm64/intel_socfpga/agilex/CMakeLists.txt | 2 ++ soc/arm64/intel_socfpga/agilex/linker.ld | 8 -------- soc/arm64/intel_socfpga/agilex5/CMakeLists.txt | 2 ++ soc/arm64/intel_socfpga/agilex5/linker.ld | 8 -------- soc/arm64/nxp_imx/mimx8m/CMakeLists.txt | 2 ++ soc/arm64/nxp_imx/mimx8m/linker.ld | 8 -------- soc/arm64/nxp_imx/mimx9/CMakeLists.txt | 2 ++ soc/arm64/nxp_layerscape/ls1046a/CMakeLists.txt | 2 ++ soc/arm64/nxp_layerscape/ls1046a/linker.ld | 8 -------- soc/arm64/qemu_cortex_a53/CMakeLists.txt | 2 ++ soc/arm64/qemu_cortex_a53/linker.ld | 8 -------- soc/arm64/qemu_virt_arm64/CMakeLists.txt | 2 ++ soc/arm64/qemu_virt_arm64/linker.ld | 8 -------- soc/arm64/renesas_rcar/gen3/CMakeLists.txt | 2 ++ soc/arm64/renesas_rcar/gen3/linker.ld | 7 ------- soc/arm64/rockchip/rk3399/CMakeLists.txt | 2 ++ soc/arm64/rockchip/rk3399/linker.ld | 8 -------- soc/arm64/ti_k3/am6x/CMakeLists.txt | 2 ++ soc/arm64/ti_k3/am6x/linker.ld | 7 ------- soc/arm64/xenvm/CMakeLists.txt | 2 ++ soc/arm64/xenvm/linker.ld | 7 ------- 31 files changed, 30 insertions(+), 121 deletions(-) delete mode 100644 soc/arm64/arm/fvp_aemv8a/linker.ld delete mode 100644 soc/arm64/arm/fvp_aemv8r/linker.ld delete mode 100644 soc/arm64/bcm2711/linker.ld delete mode 100644 soc/arm64/bcm2711/linker_a72.ld delete mode 100644 soc/arm64/bcm_vk/viper/linker.ld delete mode 100644 soc/arm64/bcm_vk/viper/linker_a72.ld delete mode 100644 soc/arm64/intel_socfpga/agilex/linker.ld delete mode 100644 soc/arm64/intel_socfpga/agilex5/linker.ld delete mode 100644 soc/arm64/nxp_imx/mimx8m/linker.ld delete mode 100644 soc/arm64/nxp_layerscape/ls1046a/linker.ld delete mode 100644 soc/arm64/qemu_cortex_a53/linker.ld delete mode 100644 soc/arm64/qemu_virt_arm64/linker.ld delete mode 100644 soc/arm64/renesas_rcar/gen3/linker.ld delete mode 100644 soc/arm64/rockchip/rk3399/linker.ld delete mode 100644 soc/arm64/ti_k3/am6x/linker.ld delete mode 100644 soc/arm64/xenvm/linker.ld diff --git a/soc/arm64/arm/fvp_aemv8a/CMakeLists.txt b/soc/arm64/arm/fvp_aemv8a/CMakeLists.txt index fd39809a833..b28d8b24523 100644 --- a/soc/arm64/arm/fvp_aemv8a/CMakeLists.txt +++ b/soc/arm64/arm/fvp_aemv8a/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/arm/fvp_aemv8a/linker.ld b/soc/arm64/arm/fvp_aemv8a/linker.ld deleted file mode 100644 index ab1d76f36ba..00000000000 --- a/soc/arm64/arm/fvp_aemv8a/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * linker.ld - Linker command/script file - * - * Copyright (c) 2021 Carlo Caione - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/arm/fvp_aemv8r/CMakeLists.txt b/soc/arm64/arm/fvp_aemv8r/CMakeLists.txt index cf23f50c5d0..ce116cb936e 100644 --- a/soc/arm64/arm/fvp_aemv8r/CMakeLists.txt +++ b/soc/arm64/arm/fvp_aemv8r/CMakeLists.txt @@ -5,3 +5,5 @@ zephyr_library_sources( ) zephyr_library_sources_ifdef(CONFIG_ARM_MPU arm_mpu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/arm/fvp_aemv8r/linker.ld b/soc/arm64/arm/fvp_aemv8r/linker.ld deleted file mode 100644 index afed4f40d25..00000000000 --- a/soc/arm64/arm/fvp_aemv8r/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * linker.ld - Linker command/script file - * - * Copyright (c) 2021 Arm Limited (or its affiliates). All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/bcm2711/CMakeLists.txt b/soc/arm64/bcm2711/CMakeLists.txt index fb2dcd9c15f..733abbebd91 100644 --- a/soc/arm64/bcm2711/CMakeLists.txt +++ b/soc/arm64/bcm2711/CMakeLists.txt @@ -1,2 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/bcm2711/linker.ld b/soc/arm64/bcm2711/linker.ld deleted file mode 100644 index fb3fabcecfe..00000000000 --- a/soc/arm64/bcm2711/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright 2023 honglin leng - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include diff --git a/soc/arm64/bcm2711/linker_a72.ld b/soc/arm64/bcm2711/linker_a72.ld deleted file mode 100644 index 6f187219b29..00000000000 --- a/soc/arm64/bcm2711/linker_a72.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2023 honglin leng - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/bcm_vk/viper/CMakeLists.txt b/soc/arm64/bcm_vk/viper/CMakeLists.txt index 8b59f41d728..93f8b45bc82 100644 --- a/soc/arm64/bcm_vk/viper/CMakeLists.txt +++ b/soc/arm64/bcm_vk/viper/CMakeLists.txt @@ -7,3 +7,5 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_SOC_BCM58402_A72 plat_core.c) zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/bcm_vk/viper/linker.ld b/soc/arm64/bcm_vk/viper/linker.ld deleted file mode 100644 index 223bd37f5c5..00000000000 --- a/soc/arm64/bcm_vk/viper/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2020 Broadcom - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include diff --git a/soc/arm64/bcm_vk/viper/linker_a72.ld b/soc/arm64/bcm_vk/viper/linker_a72.ld deleted file mode 100644 index a12c2bd066b..00000000000 --- a/soc/arm64/bcm_vk/viper/linker_a72.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2020 Broadcom - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/intel_socfpga/agilex/CMakeLists.txt b/soc/arm64/intel_socfpga/agilex/CMakeLists.txt index ba3d3c4e034..3cdb01da699 100644 --- a/soc/arm64/intel_socfpga/agilex/CMakeLists.txt +++ b/soc/arm64/intel_socfpga/agilex/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(.) zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/intel_socfpga/agilex/linker.ld b/soc/arm64/intel_socfpga/agilex/linker.ld deleted file mode 100644 index 2b4cd596a17..00000000000 --- a/soc/arm64/intel_socfpga/agilex/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include diff --git a/soc/arm64/intel_socfpga/agilex5/CMakeLists.txt b/soc/arm64/intel_socfpga/agilex5/CMakeLists.txt index f0e79e927d3..a538caf7a33 100644 --- a/soc/arm64/intel_socfpga/agilex5/CMakeLists.txt +++ b/soc/arm64/intel_socfpga/agilex5/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_include_directories(.) zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/intel_socfpga/agilex5/linker.ld b/soc/arm64/intel_socfpga/agilex5/linker.ld deleted file mode 100644 index 9f5bc4c4f7e..00000000000 --- a/soc/arm64/intel_socfpga/agilex5/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2022 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include diff --git a/soc/arm64/nxp_imx/mimx8m/CMakeLists.txt b/soc/arm64/nxp_imx/mimx8m/CMakeLists.txt index ff4a4e0deba..032c4a8642d 100644 --- a/soc/arm64/nxp_imx/mimx8m/CMakeLists.txt +++ b/soc/arm64/nxp_imx/mimx8m/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/nxp_imx/mimx8m/linker.ld b/soc/arm64/nxp_imx/mimx8m/linker.ld deleted file mode 100644 index 65c5d0722aa..00000000000 --- a/soc/arm64/nxp_imx/mimx8m/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2020 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include diff --git a/soc/arm64/nxp_imx/mimx9/CMakeLists.txt b/soc/arm64/nxp_imx/mimx9/CMakeLists.txt index ff4a4e0deba..77a9500f5b7 100644 --- a/soc/arm64/nxp_imx/mimx9/CMakeLists.txt +++ b/soc/arm64/nxp_imx/mimx9/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_include_directories(.) zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/nxp_layerscape/ls1046a/CMakeLists.txt b/soc/arm64/nxp_layerscape/ls1046a/CMakeLists.txt index 2cf9a407f84..22fc2aa11be 100644 --- a/soc/arm64/nxp_layerscape/ls1046a/CMakeLists.txt +++ b/soc/arm64/nxp_layerscape/ls1046a/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/nxp_layerscape/ls1046a/linker.ld b/soc/arm64/nxp_layerscape/ls1046a/linker.ld deleted file mode 100644 index 40dbcd63fca..00000000000 --- a/soc/arm64/nxp_layerscape/ls1046a/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2021 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include diff --git a/soc/arm64/qemu_cortex_a53/CMakeLists.txt b/soc/arm64/qemu_cortex_a53/CMakeLists.txt index fd39809a833..b28d8b24523 100644 --- a/soc/arm64/qemu_cortex_a53/CMakeLists.txt +++ b/soc/arm64/qemu_cortex_a53/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/qemu_cortex_a53/linker.ld b/soc/arm64/qemu_cortex_a53/linker.ld deleted file mode 100644 index 9b7be757e17..00000000000 --- a/soc/arm64/qemu_cortex_a53/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2019 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include diff --git a/soc/arm64/qemu_virt_arm64/CMakeLists.txt b/soc/arm64/qemu_virt_arm64/CMakeLists.txt index 495a3d96b89..7c7a3c4d52c 100644 --- a/soc/arm64/qemu_virt_arm64/CMakeLists.txt +++ b/soc/arm64/qemu_virt_arm64/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/qemu_virt_arm64/linker.ld b/soc/arm64/qemu_virt_arm64/linker.ld deleted file mode 100644 index a7bcbf24cfb..00000000000 --- a/soc/arm64/qemu_virt_arm64/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2022 Huawei France Technologies SAS - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include diff --git a/soc/arm64/renesas_rcar/gen3/CMakeLists.txt b/soc/arm64/renesas_rcar/gen3/CMakeLists.txt index 23315289c61..16dcc07b754 100644 --- a/soc/arm64/renesas_rcar/gen3/CMakeLists.txt +++ b/soc/arm64/renesas_rcar/gen3/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_library_sources_ifdef(CONFIG_SOC_ARM64_R8A77951 pfc_r8a77951.c) zephyr_library_sources_ifdef(CONFIG_SOC_R8A77961 pfc_r8a77961.c) zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/renesas_rcar/gen3/linker.ld b/soc/arm64/renesas_rcar/gen3/linker.ld deleted file mode 100644 index 0deb8cd2794..00000000000 --- a/soc/arm64/renesas_rcar/gen3/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 EPAM Systems - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/rockchip/rk3399/CMakeLists.txt b/soc/arm64/rockchip/rk3399/CMakeLists.txt index 2cf9a407f84..22fc2aa11be 100644 --- a/soc/arm64/rockchip/rk3399/CMakeLists.txt +++ b/soc/arm64/rockchip/rk3399/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/rockchip/rk3399/linker.ld b/soc/arm64/rockchip/rk3399/linker.ld deleted file mode 100644 index 1826843d117..00000000000 --- a/soc/arm64/rockchip/rk3399/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2022 Huawei France Technologies SASU - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include diff --git a/soc/arm64/ti_k3/am6x/CMakeLists.txt b/soc/arm64/ti_k3/am6x/CMakeLists.txt index 6c961dd2801..491cafbec22 100644 --- a/soc/arm64/ti_k3/am6x/CMakeLists.txt +++ b/soc/arm64/ti_k3/am6x/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/ti_k3/am6x/linker.ld b/soc/arm64/ti_k3/am6x/linker.ld deleted file mode 100644 index 849a1199eb4..00000000000 --- a/soc/arm64/ti_k3/am6x/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Enphase Energy - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/arm64/xenvm/CMakeLists.txt b/soc/arm64/xenvm/CMakeLists.txt index ac596106c28..7ffbb965792 100644 --- a/soc/arm64/xenvm/CMakeLists.txt +++ b/soc/arm64/xenvm/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm64/xenvm/linker.ld b/soc/arm64/xenvm/linker.ld deleted file mode 100644 index 6f57b480eb8..00000000000 --- a/soc/arm64/xenvm/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2020 EPAM Systems - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include From 5130a69987646487183e26c58a78bff4b624ea24 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 22:42:32 +0200 Subject: [PATCH 2973/4498] cmake: mips: update mips SoC to use SOC_LINKER_SCRIPT variable This commit updates all mips SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/mips/qemu_malta/CMakeLists.txt | 2 ++ soc/mips/qemu_malta/linker.ld | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 soc/mips/qemu_malta/linker.ld diff --git a/soc/mips/qemu_malta/CMakeLists.txt b/soc/mips/qemu_malta/CMakeLists.txt index 49a74924cdc..351ffebf5b5 100644 --- a/soc/mips/qemu_malta/CMakeLists.txt +++ b/soc/mips/qemu_malta/CMakeLists.txt @@ -15,3 +15,5 @@ zephyr_ld_options( -mips32 ${TOOLCHAIN_LD_FLAGS} ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/mips/linker.ld CACHE INTERNAL "") diff --git a/soc/mips/qemu_malta/linker.ld b/soc/mips/qemu_malta/linker.ld deleted file mode 100644 index f6baabc0aa6..00000000000 --- a/soc/mips/qemu_malta/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2020 Antony Pavlov - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include From 59bcef3692f785e7afceefc1ee3fae6e70a1676e Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 23:56:36 +0200 Subject: [PATCH 2974/4498] cmake: posix: update posix SoC to use SOC_LINKER_SCRIPT variable This commit updates all posix SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/posix/inf_clock/CMakeLists.txt | 2 ++ soc/posix/inf_clock/linker.ld | 12 ------------ 2 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 soc/posix/inf_clock/linker.ld diff --git a/soc/posix/inf_clock/CMakeLists.txt b/soc/posix/inf_clock/CMakeLists.txt index b256d67daa9..5bc6ab3c428 100644 --- a/soc/posix/inf_clock/CMakeLists.txt +++ b/soc/posix/inf_clock/CMakeLists.txt @@ -13,3 +13,5 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/posix/include ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/posix/linker.ld CACHE INTERNAL "") diff --git a/soc/posix/inf_clock/linker.ld b/soc/posix/inf_clock/linker.ld deleted file mode 100644 index e33a3520239..00000000000 --- a/soc/posix/inf_clock/linker.ld +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * Copyright (c) 2017 Oticon A/S - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Linker script for the POSIX ARCH & INF_CLOCK SOC - */ - -#include From 10fea41f5cabef58cce0e6fcabccacbdec810798 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 22:37:54 +0200 Subject: [PATCH 2975/4498] cmake: riscv: update riscv SoC to use SOC_LINKER_SCRIPT variable This commit updates all riscv SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- .../espressif_esp32/esp32c3/CMakeLists.txt | 6 ++++++ soc/riscv/espressif_esp32/esp32c3/linker.ld | 20 ------------------- soc/riscv/litex-vexriscv/CMakeLists.txt | 2 ++ soc/riscv/litex-vexriscv/linker.ld | 7 ------- soc/riscv/openisa_rv32m1/CMakeLists.txt | 2 ++ soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt | 4 ++++ .../riscv-privileged/andes_v5/CMakeLists.txt | 4 ++++ soc/riscv/riscv-privileged/andes_v5/linker.ld | 17 ---------------- .../efinix-sapphire/CMakeLists.txt | 2 ++ .../efinix-sapphire/linker.ld | 3 --- .../riscv-privileged/gd32vf103/CMakeLists.txt | 2 ++ .../riscv-privileged/gd32vf103/linker.ld | 7 ------- soc/riscv/riscv-privileged/miv/CMakeLists.txt | 2 ++ soc/riscv/riscv-privileged/miv/linker.ld | 7 ------- .../riscv-privileged/mpfs/CMakeLists.txt | 2 ++ soc/riscv/riscv-privileged/mpfs/linker.ld | 7 ------- .../riscv-privileged/neorv32/CMakeLists.txt | 2 ++ .../riscv-privileged/niosv/CMakeLists.txt | 2 ++ .../riscv-privileged/opentitan/CMakeLists.txt | 2 ++ .../riscv-privileged/opentitan/linker.ld | 3 --- .../sifive-freedom/CMakeLists.txt | 2 ++ .../riscv-privileged/sifive-freedom/linker.ld | 11 ---------- .../starfive_jh71xx/CMakeLists.txt | 2 ++ .../starfive_jh71xx/linker.ld | 6 ------ .../telink_b91/CMakeLists.txt | 2 ++ .../riscv-privileged/virt/CMakeLists.txt | 2 ++ soc/riscv/riscv-privileged/virt/linker.ld | 6 ------ 27 files changed, 40 insertions(+), 94 deletions(-) delete mode 100644 soc/riscv/espressif_esp32/esp32c3/linker.ld delete mode 100644 soc/riscv/litex-vexriscv/linker.ld delete mode 100644 soc/riscv/riscv-privileged/andes_v5/linker.ld delete mode 100644 soc/riscv/riscv-privileged/efinix-sapphire/linker.ld delete mode 100644 soc/riscv/riscv-privileged/gd32vf103/linker.ld delete mode 100644 soc/riscv/riscv-privileged/miv/linker.ld delete mode 100644 soc/riscv/riscv-privileged/mpfs/linker.ld delete mode 100644 soc/riscv/riscv-privileged/opentitan/linker.ld delete mode 100644 soc/riscv/riscv-privileged/sifive-freedom/linker.ld delete mode 100644 soc/riscv/riscv-privileged/starfive_jh71xx/linker.ld delete mode 100644 soc/riscv/riscv-privileged/virt/linker.ld diff --git a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt index 4dd457b6801..e97f71751ef 100644 --- a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt +++ b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt @@ -94,3 +94,9 @@ endif() board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}") board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") +endif() diff --git a/soc/riscv/espressif_esp32/esp32c3/linker.ld b/soc/riscv/espressif_esp32/esp32c3/linker.ld deleted file mode 100644 index 934088ca728..00000000000 --- a/soc/riscv/espressif_esp32/esp32c3/linker.ld +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - */ - -#if defined(CONFIG_MCUBOOT) - /* Using mcuboot as ESP32C3 2nd stage bootloader */ - #include "mcuboot.ld" - -#else - /* Application default linker script */ - #include "default.ld" - -#endif /* CONFIG_MCUBOOT */ diff --git a/soc/riscv/litex-vexriscv/CMakeLists.txt b/soc/riscv/litex-vexriscv/CMakeLists.txt index 34d6046ab68..9d100ea0e2a 100644 --- a/soc/riscv/litex-vexriscv/CMakeLists.txt +++ b/soc/riscv/litex-vexriscv/CMakeLists.txt @@ -8,3 +8,5 @@ zephyr_sources( ../riscv-privileged/common/soc_irq.S ../riscv-privileged/common/vector.S ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/litex-vexriscv/linker.ld b/soc/riscv/litex-vexriscv/linker.ld deleted file mode 100644 index 424ee50014f..00000000000 --- a/soc/riscv/litex-vexriscv/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2018 - 2019 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/riscv/openisa_rv32m1/CMakeLists.txt b/soc/riscv/openisa_rv32m1/CMakeLists.txt index 37f4d9c7488..a7a722279c3 100644 --- a/soc/riscv/openisa_rv32m1/CMakeLists.txt +++ b/soc/riscv/openisa_rv32m1/CMakeLists.txt @@ -20,3 +20,5 @@ zephyr_sources( ) zephyr_linker_sources(ROM_START SORT_KEY 0x0vectors vector_table.ld) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt b/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt index b7eff43b096..df4d9021745 100644 --- a/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt +++ b/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt @@ -3,3 +3,7 @@ zephyr_sources( ) zephyr_library_sources_ifndef(CONFIG_RISCV_ISA_EXT_M __arithmetic.S) zephyr_sources_ifdef(CONFIG_SOC_IT8XXX2_USE_ILM ilm.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld + CACHE INTERNAL "SoC Linker script ${SOC_NAME}" +) diff --git a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt b/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt index 3de7b8c8841..21268312347 100644 --- a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt @@ -23,3 +23,7 @@ if(CONFIG_SOC_ANDES_V5_EXECIT) zephyr_cc_option(-mexecit) zephyr_ld_options(-Wl,--mexecit) endif() + +if(CONFIG_SOC_RISCV_ANDES_AE350) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/ae350/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/riscv/riscv-privileged/andes_v5/linker.ld b/soc/riscv/riscv-privileged/andes_v5/linker.ld deleted file mode 100644 index 5f92edc75a9..00000000000 --- a/soc/riscv/riscv-privileged/andes_v5/linker.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021 Andes Technology Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * linker script for andes_v5 SoC Series - */ - - -#if defined(CONFIG_SOC_RISCV_ANDES_AE350) -# include -#endif diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt b/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt index 9fc80635937..9edb7c3afe5 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/linker.ld b/soc/riscv/riscv-privileged/efinix-sapphire/linker.ld deleted file mode 100644 index 4cfd67a53f5..00000000000 --- a/soc/riscv/riscv-privileged/efinix-sapphire/linker.ld +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -#include diff --git a/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt b/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt index a3cabd57ab1..be61e4a64df 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources(entry.S) zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/gd32vf103/linker.ld b/soc/riscv/riscv-privileged/gd32vf103/linker.ld deleted file mode 100644 index 849c94ebe96..00000000000 --- a/soc/riscv/riscv-privileged/gd32vf103/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021 Tokita, Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/riscv/riscv-privileged/miv/CMakeLists.txt b/soc/riscv/riscv-privileged/miv/CMakeLists.txt index 55fc3999fd7..316f08474ba 100644 --- a/soc/riscv/riscv-privileged/miv/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/miv/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/miv/linker.ld b/soc/riscv/riscv-privileged/miv/linker.ld deleted file mode 100644 index 0d220a25c73..00000000000 --- a/soc/riscv/riscv-privileged/miv/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2018 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt b/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt index 55fc3999fd7..316f08474ba 100644 --- a/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/mpfs/linker.ld b/soc/riscv/riscv-privileged/mpfs/linker.ld deleted file mode 100644 index 4e3ca81bfbb..00000000000 --- a/soc/riscv/riscv-privileged/mpfs/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2021-2022 Microchip Technology Inc - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt b/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt index 7f7c334fedd..42731316d84 100644 --- a/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_sources( soc_irq.S soc.c ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/niosv/CMakeLists.txt b/soc/riscv/riscv-privileged/niosv/CMakeLists.txt index c740850bc77..e7a753a2db3 100644 --- a/soc/riscv/riscv-privileged/niosv/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/niosv/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt b/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt index 05e59ca7071..3502022cbed 100644 --- a/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_sources(soc.c rom_header.S) zephyr_linker_sources(ROM_START SORT_KEY 000romheader rom_header.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/opentitan/linker.ld b/soc/riscv/riscv-privileged/opentitan/linker.ld deleted file mode 100644 index 8eeb9c50af3..00000000000 --- a/soc/riscv/riscv-privileged/opentitan/linker.ld +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include diff --git a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt b/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt index f5f6c539efd..ff4cc56d739 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_sources() zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FREEDOM fe310_clock.c) zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU540 fu540_clock.c) zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU740 fu740_clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/sifive-freedom/linker.ld b/soc/riscv/riscv-privileged/sifive-freedom/linker.ld deleted file mode 100644 index 96720f18a2e..00000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/linker.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Linker script for the SiFive Freedom processor - */ - -#include diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt b/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt index f75aec6b311..f79d0b3255d 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/linker.ld b/soc/riscv/riscv-privileged/starfive_jh71xx/linker.ld deleted file mode 100644 index 4e63d62344d..00000000000 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2020 Cobham Gaisler AB - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include diff --git a/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt b/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt index c91adf6a993..8c489ac6dd7 100644 --- a/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt @@ -14,3 +14,5 @@ zephyr_ld_options(-fuse-ld=bfd) zephyr_compile_options_ifdef(CONFIG_TELINK_B91_HWDSP -mext-dsp) zephyr_compile_options_ifndef(CONFIG_RISCV_GP -mno-relax) zephyr_linker_sources(ROM_START SORT_KEY 0x0 init.ld) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/virt/CMakeLists.txt b/soc/riscv/riscv-privileged/virt/CMakeLists.txt index 9486f255912..6a1826b29f9 100644 --- a/soc/riscv/riscv-privileged/virt/CMakeLists.txt +++ b/soc/riscv/riscv-privileged/virt/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/virt/linker.ld b/soc/riscv/riscv-privileged/virt/linker.ld deleted file mode 100644 index 4e63d62344d..00000000000 --- a/soc/riscv/riscv-privileged/virt/linker.ld +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2020 Cobham Gaisler AB - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include From 2d96b31129f845d6afa61b5dbaef8022bb8ce7f8 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 22:45:27 +0200 Subject: [PATCH 2976/4498] cmake: sparc: update sparc SoC to use SOC_LINKER_SCRIPT variable This commit updates all sparc SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/sparc/gr716a/CMakeLists.txt | 2 ++ soc/sparc/leon3/CMakeLists.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/soc/sparc/gr716a/CMakeLists.txt b/soc/sparc/gr716a/CMakeLists.txt index 746570b05c7..888e386817e 100644 --- a/soc/sparc/gr716a/CMakeLists.txt +++ b/soc/sparc/gr716a/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(../leon3/idle.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/sparc/leon3/CMakeLists.txt b/soc/sparc/leon3/CMakeLists.txt index 53b77ee8a37..722526c00cf 100644 --- a/soc/sparc/leon3/CMakeLists.txt +++ b/soc/sparc/leon3/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(idle.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From 4b02bbc3297f15068ddb45879760c9dacc10b84c Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 21:46:21 +0200 Subject: [PATCH 2977/4498] cmake: xtensa: update xtensa SoC to use SOC_LINKER_SCRIPT variable This commit updates all xtensa SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/xtensa/dc233c/CMakeLists.txt | 2 ++ soc/xtensa/dc233c/linker.ld | 12 --------- .../espressif_esp32/esp32/CMakeLists.txt | 6 +++++ soc/xtensa/espressif_esp32/esp32/linker.ld | 20 --------------- .../espressif_esp32/esp32_net/CMakeLists.txt | 2 ++ .../espressif_esp32/esp32s2/CMakeLists.txt | 6 +++++ soc/xtensa/espressif_esp32/esp32s2/linker.ld | 20 --------------- .../espressif_esp32/esp32s3/CMakeLists.txt | 8 ++++++ soc/xtensa/espressif_esp32/esp32s3/linker.ld | 25 ------------------- soc/xtensa/intel_adsp/ace/CMakeLists.txt | 2 ++ soc/xtensa/intel_adsp/cavs/CMakeLists.txt | 2 ++ soc/xtensa/intel_adsp/cavs/linker.ld | 14 ----------- soc/xtensa/nxp_adsp/CMakeLists.txt | 2 ++ soc/xtensa/sample_controller/CMakeLists.txt | 2 +- soc/xtensa/sample_controller/linker.ld | 12 --------- 15 files changed, 31 insertions(+), 104 deletions(-) delete mode 100644 soc/xtensa/dc233c/linker.ld delete mode 100644 soc/xtensa/espressif_esp32/esp32/linker.ld delete mode 100644 soc/xtensa/espressif_esp32/esp32s2/linker.ld delete mode 100644 soc/xtensa/espressif_esp32/esp32s3/linker.ld delete mode 100644 soc/xtensa/intel_adsp/cavs/linker.ld delete mode 100644 soc/xtensa/sample_controller/linker.ld diff --git a/soc/xtensa/dc233c/CMakeLists.txt b/soc/xtensa/dc233c/CMakeLists.txt index 52a6e84baa9..8108448b61d 100644 --- a/soc/xtensa/dc233c/CMakeLists.txt +++ b/soc/xtensa/dc233c/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_XTENSA_MMU mmu.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/include/xtensa-dc233c.ld CACHE INTERNAL "") diff --git a/soc/xtensa/dc233c/linker.ld b/soc/xtensa/dc233c/linker.ld deleted file mode 100644 index 1f8e9eadd1a..00000000000 --- a/soc/xtensa/dc233c/linker.ld +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2016 Cadence Design Systems, Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * Linker script for the Xtensa platform. - */ -#include diff --git a/soc/xtensa/espressif_esp32/esp32/CMakeLists.txt b/soc/xtensa/espressif_esp32/esp32/CMakeLists.txt index 6468d1545dc..f850e56a9b1 100644 --- a/soc/xtensa/espressif_esp32/esp32/CMakeLists.txt +++ b/soc/xtensa/espressif_esp32/esp32/CMakeLists.txt @@ -95,3 +95,9 @@ endif() board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}") board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") +endif() diff --git a/soc/xtensa/espressif_esp32/esp32/linker.ld b/soc/xtensa/espressif_esp32/esp32/linker.ld deleted file mode 100644 index 981d25bf18a..00000000000 --- a/soc/xtensa/espressif_esp32/esp32/linker.ld +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - */ - -#if defined(CONFIG_MCUBOOT) - /* Using mcuboot as ESP32 2nd stage bootloader */ - #include "mcuboot.ld" - -#else - /* Application default linker script */ - #include "default.ld" - -#endif /* CONFIG_MCUBOOT */ diff --git a/soc/xtensa/espressif_esp32/esp32_net/CMakeLists.txt b/soc/xtensa/espressif_esp32/esp32_net/CMakeLists.txt index 9be4cbc549d..2997e2e9990 100644 --- a/soc/xtensa/espressif_esp32/esp32_net/CMakeLists.txt +++ b/soc/xtensa/espressif_esp32/esp32_net/CMakeLists.txt @@ -19,3 +19,5 @@ if(CONFIG_BUILD_OUTPUT_BIN) -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.c -a "esp32_net_fw_array") endif() + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/xtensa/espressif_esp32/esp32s2/CMakeLists.txt b/soc/xtensa/espressif_esp32/esp32s2/CMakeLists.txt index 2b023ede856..b9f361d1d5c 100644 --- a/soc/xtensa/espressif_esp32/esp32s2/CMakeLists.txt +++ b/soc/xtensa/espressif_esp32/esp32s2/CMakeLists.txt @@ -93,3 +93,9 @@ endif() board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}") board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") +endif() diff --git a/soc/xtensa/espressif_esp32/esp32s2/linker.ld b/soc/xtensa/espressif_esp32/esp32s2/linker.ld deleted file mode 100644 index dc2d891834e..00000000000 --- a/soc/xtensa/espressif_esp32/esp32s2/linker.ld +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - */ - -#if defined(CONFIG_MCUBOOT) - /* Using mcuboot as ESP32S2 2nd stage bootloader */ - #include "mcuboot.ld" - -#else - /* Application default linker script */ - #include "default.ld" - -#endif /* CONFIG_MCUBOOT */ diff --git a/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt b/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt index dc9e86d6604..cb5291614bc 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt +++ b/soc/xtensa/espressif_esp32/esp32s3/CMakeLists.txt @@ -112,3 +112,11 @@ else() board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") endif() + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") +elseif(CONFIG_SOC_ESP32S3_APPCPU) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default_appcpu.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") +endif() diff --git a/soc/xtensa/espressif_esp32/esp32s3/linker.ld b/soc/xtensa/espressif_esp32/esp32s3/linker.ld deleted file mode 100644 index 9303f5a325d..00000000000 --- a/soc/xtensa/espressif_esp32/esp32s3/linker.ld +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - */ - -#if defined(CONFIG_MCUBOOT) - /* Using mcuboot as ESP32S3 2nd stage bootloader */ - #include "mcuboot.ld" - -#else - - /* Application default linker script */ - #if defined(CONFIG_SOC_ESP32S3_APPCPU) - #include "default_appcpu.ld" - #else - #include "default.ld" - #endif - -#endif /* CONFIG_MCUBOOT */ diff --git a/soc/xtensa/intel_adsp/ace/CMakeLists.txt b/soc/xtensa/intel_adsp/ace/CMakeLists.txt index 43e812cbabb..fddb595fa6d 100644 --- a/soc/xtensa/intel_adsp/ace/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/ace/CMakeLists.txt @@ -15,3 +15,5 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget.c) zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget_messages.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/xtensa/intel_adsp/cavs/CMakeLists.txt b/soc/xtensa/intel_adsp/cavs/CMakeLists.txt index 2a0cbdc463c..2b5bf93a592 100644 --- a/soc/xtensa/intel_adsp/cavs/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/cavs/CMakeLists.txt @@ -17,3 +17,5 @@ if(CONFIG_SMP OR CONFIG_MP_MAX_NUM_CPUS GREATER 1) endif() zephyr_library_sources_ifdef(CONFIG_CAVS_ICTL irq.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/include/xtensa-cavs-linker.ld CACHE INTERNAL "") diff --git a/soc/xtensa/intel_adsp/cavs/linker.ld b/soc/xtensa/intel_adsp/cavs/linker.ld deleted file mode 100644 index 7c5566067b6..00000000000 --- a/soc/xtensa/intel_adsp/cavs/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2019 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * Linker script for the intel_apl_adsp platform - */ - -#include diff --git a/soc/xtensa/nxp_adsp/CMakeLists.txt b/soc/xtensa/nxp_adsp/CMakeLists.txt index f306839ac2a..575c7f47cca 100644 --- a/soc/xtensa/nxp_adsp/CMakeLists.txt +++ b/soc/xtensa/nxp_adsp/CMakeLists.txt @@ -22,3 +22,5 @@ add_custom_command( COMMAND west sign --if-tool-available --tool rimage --build-dir ${CMAKE_BINARY_DIR} ${WEST_SIGN_OPTS} DEPENDS ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} ) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/${SOC_SERIES}/linker.ld CACHE INTERNAL "") diff --git a/soc/xtensa/sample_controller/CMakeLists.txt b/soc/xtensa/sample_controller/CMakeLists.txt index 1097b991ed2..3aff8c6b8b3 100644 --- a/soc/xtensa/sample_controller/CMakeLists.txt +++ b/soc/xtensa/sample_controller/CMakeLists.txt @@ -1,3 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -# intentionally left empty +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/include/xtensa-sample-controller.ld CACHE INTERNAL "") diff --git a/soc/xtensa/sample_controller/linker.ld b/soc/xtensa/sample_controller/linker.ld deleted file mode 100644 index 08639c8908b..00000000000 --- a/soc/xtensa/sample_controller/linker.ld +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2016 Cadence Design Systems, Inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Linker command/script file - * - * Linker script for the Xtensa platform. - */ -#include From e57f0a4f7e6b105c3a3a767a85a4e07563a1fc73 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Sat, 28 Oct 2023 00:05:02 +0200 Subject: [PATCH 2978/4498] cmake: x86: update x86 SoC to use SOC_LINKER_SCRIPT variable This commit updates all x86 SoCs to set SOC_LINKER_SCRIPT CMake variable to point to active linker script directly. Signed-off-by: Torsten Rasmussen --- soc/nios2/nios2-qemu/CMakeLists.txt | 2 +- soc/nios2/nios2f-zephyr/CMakeLists.txt | 2 +- soc/x86/alder_lake/CMakeLists.txt | 2 ++ soc/x86/apollo_lake/CMakeLists.txt | 2 ++ soc/x86/atom/CMakeLists.txt | 2 ++ soc/x86/elkhart_lake/CMakeLists.txt | 2 ++ soc/x86/ia32/CMakeLists.txt | 2 ++ soc/x86/intel_ish/intel_ish5/CMakeLists.txt | 2 ++ soc/x86/lakemont/CMakeLists.txt | 2 ++ soc/x86/raptor_lake/CMakeLists.txt | 2 ++ 10 files changed, 18 insertions(+), 2 deletions(-) diff --git a/soc/nios2/nios2-qemu/CMakeLists.txt b/soc/nios2/nios2-qemu/CMakeLists.txt index 1097b991ed2..66d55c6ba96 100644 --- a/soc/nios2/nios2-qemu/CMakeLists.txt +++ b/soc/nios2/nios2-qemu/CMakeLists.txt @@ -1,3 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -# intentionally left empty +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nios2/nios2f-zephyr/CMakeLists.txt b/soc/nios2/nios2f-zephyr/CMakeLists.txt index 1097b991ed2..66d55c6ba96 100644 --- a/soc/nios2/nios2f-zephyr/CMakeLists.txt +++ b/soc/nios2/nios2f-zephyr/CMakeLists.txt @@ -1,3 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -# intentionally left empty +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/alder_lake/CMakeLists.txt b/soc/x86/alder_lake/CMakeLists.txt index 67d93138e14..47325b7a809 100644 --- a/soc/x86/alder_lake/CMakeLists.txt +++ b/soc/x86/alder_lake/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_cc_option(-march=goldmont) zephyr_library_sources(cpu.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/apollo_lake/CMakeLists.txt b/soc/x86/apollo_lake/CMakeLists.txt index 67d93138e14..47325b7a809 100644 --- a/soc/x86/apollo_lake/CMakeLists.txt +++ b/soc/x86/apollo_lake/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_cc_option(-march=goldmont) zephyr_library_sources(cpu.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/atom/CMakeLists.txt b/soc/x86/atom/CMakeLists.txt index 9881313609a..66d55c6ba96 100644 --- a/soc/x86/atom/CMakeLists.txt +++ b/soc/x86/atom/CMakeLists.txt @@ -1 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/elkhart_lake/CMakeLists.txt b/soc/x86/elkhart_lake/CMakeLists.txt index 67d93138e14..47325b7a809 100644 --- a/soc/x86/elkhart_lake/CMakeLists.txt +++ b/soc/x86/elkhart_lake/CMakeLists.txt @@ -6,3 +6,5 @@ zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_cc_option(-march=goldmont) zephyr_library_sources(cpu.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/ia32/CMakeLists.txt b/soc/x86/ia32/CMakeLists.txt index 9881313609a..66d55c6ba96 100644 --- a/soc/x86/ia32/CMakeLists.txt +++ b/soc/x86/ia32/CMakeLists.txt @@ -1 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/intel_ish/intel_ish5/CMakeLists.txt b/soc/x86/intel_ish/intel_ish5/CMakeLists.txt index 6d4f911744a..3c253ac2648 100644 --- a/soc/x86/intel_ish/intel_ish5/CMakeLists.txt +++ b/soc/x86/intel_ish/intel_ish5/CMakeLists.txt @@ -8,4 +8,6 @@ zephyr_cc_option(-march=pentium -mtune=i486) zephyr_sources(soc.c) add_subdirectory_ifdef(CONFIG_PM pm) +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") + include(../utils/build_ish_firmware.cmake) diff --git a/soc/x86/lakemont/CMakeLists.txt b/soc/x86/lakemont/CMakeLists.txt index 6f44c89f7ad..4527b084519 100644 --- a/soc/x86/lakemont/CMakeLists.txt +++ b/soc/x86/lakemont/CMakeLists.txt @@ -3,3 +3,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_cc_option(-march=pentium) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/x86/raptor_lake/CMakeLists.txt b/soc/x86/raptor_lake/CMakeLists.txt index 3be2e750b61..06c46752f81 100644 --- a/soc/x86/raptor_lake/CMakeLists.txt +++ b/soc/x86/raptor_lake/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_cc_option(-march=goldmont) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From d92ed66b39453bce8ed99f56cc4982c78808da3b Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 27 Oct 2023 21:56:02 +0200 Subject: [PATCH 2979/4498] cmake: board: update ip_k66f to use BOARD_LINKER_SCRIPT variable Update the ip_k66f board to use BOARD_LINKER_SCRIPT variable. Signed-off-by: Torsten Rasmussen --- boards/arm/ip_k66f/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/arm/ip_k66f/CMakeLists.txt b/boards/arm/ip_k66f/CMakeLists.txt index 9881313609a..2fab2b7dc86 100644 --- a/boards/arm/ip_k66f/CMakeLists.txt +++ b/boards/arm/ip_k66f/CMakeLists.txt @@ -1 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 + +set(BOARD_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "Board linker script, ${BOARD}") From d4d96b3df2e44b12aa64ee46edcf69339d5f63e2 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 2 Nov 2023 17:49:35 +0530 Subject: [PATCH 2980/4498] net: zperf: Fix the check for IPv6 It was typo. Signed-off-by: Chaitanya Tata --- subsys/net/lib/zperf/zperf_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index a553bb46c8d..444cf125c31 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -1195,7 +1195,7 @@ void zperf_shell_init(void) { int ret; - if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP6ADDR) { + if (IS_ENABLED(MY_IP6ADDR_SET) && MY_IP6ADDR) { ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { From b74aacb4e2125bceeb90d46cd12253bf6bcf1685 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 14:56:02 +0100 Subject: [PATCH 2981/4498] drivers: serial: emul: Use local work queue Define local thread to emulate different thread priorities. A UART driver may call back from within a thread with higher or lower priority than the thread calling the UART API. This can hide potential concurrency issues, especially if the thread priorities are the same, or even using the same thread in case the system work queue. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/Kconfig.emul | 12 ++++++++++++ drivers/serial/uart_emul.c | 28 +++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/serial/Kconfig.emul b/drivers/serial/Kconfig.emul index 2b48335b757..b5362eb79ee 100644 --- a/drivers/serial/Kconfig.emul +++ b/drivers/serial/Kconfig.emul @@ -12,3 +12,15 @@ config UART_EMUL select EXPERIMENTAL help Enable the emulated UART driver. + +if UART_EMUL + +config UART_EMUL_WORK_Q_STACK_SIZE + int "UART emulator work queue stack size" + default 2048 + +config UART_EMUL_WORK_Q_PRIORITY + int "UART emulator work queue tread priority" + default 1 + +endif # UART_EMUL diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index f1d90d9efb1..6bfe3cf8a85 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -49,6 +49,28 @@ struct uart_emul_data { #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; +/* + * Define local thread to emulate different thread priorities. + * + * A UART driver may call back from within a thread with higher or lower priority + * than the thread calling the UART API. This can hide potential concurrency issues, + * especially if the thread priorities are the same, or even using the same thread + * in case the system work queue. + */ +K_THREAD_STACK_DEFINE(uart_emul_stack_area, CONFIG_UART_EMUL_WORK_Q_STACK_SIZE); +struct k_work_q uart_emul_work_q; + +int uart_emul_init_work_q(void) +{ + k_work_queue_init(&uart_emul_work_q); + k_work_queue_start(&uart_emul_work_q, uart_emul_stack_area, + K_THREAD_STACK_SIZEOF(uart_emul_stack_area), + CONFIG_UART_EMUL_WORK_Q_PRIORITY, NULL); + return 0; +} + +SYS_INIT(uart_emul_init_work_q, POST_KERNEL, 0); + static int uart_emul_poll_in(const struct device *dev, unsigned char *p_char) { struct uart_emul_data *drv_data = dev->data; @@ -245,7 +267,7 @@ static void uart_emul_irq_tx_enable(const struct device *dev) } if (submit_irq_work) { - (void)k_work_submit(&data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work.work); } } @@ -260,7 +282,7 @@ static void uart_emul_irq_rx_enable(const struct device *dev) } if (submit_irq_work) { - (void)k_work_submit(&data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work.work); } } @@ -361,7 +383,7 @@ uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t s IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( if (count > 0 && irq_en && !empty) { - (void)k_work_submit(&drv_data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &drv_data->irq_work.work); } )) From 54378c18e05ef4c0d3d9d8a90e17f504857bd2d2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 15:07:24 +0100 Subject: [PATCH 2982/4498] tests: drivers: serial: emul: Store buffers in fixture Most tests define a buffer for UART data on the stack, including the tests testing UART IRQ. Move buffers to static memory, within the test fixture, which can then be passed as the user_data to the UART IRQ callback. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/uart/uart_emul/src/main.c | 33 ++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/tests/drivers/uart/uart_emul/src/main.c b/tests/drivers/uart/uart_emul/src/main.c index 2de2cdfbd08..8391245a31a 100644 --- a/tests/drivers/uart/uart_emul/src/main.c +++ b/tests/drivers/uart/uart_emul/src/main.c @@ -17,6 +17,8 @@ struct uart_emul_fixture { const struct device *dev; uint8_t sample_data[SAMPLE_DATA_SIZE]; + uint8_t tx_content[SAMPLE_DATA_SIZE]; + uint8_t rx_content[SAMPLE_DATA_SIZE]; }; static void *uart_emul_setup(void) @@ -64,19 +66,18 @@ ZTEST_F(uart_emul, test_polling_out) ZTEST_F(uart_emul, test_polling_in) { - uint8_t rx_content[SAMPLE_DATA_SIZE] = {0}; int rc; uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE); for (size_t i = 0; i < SAMPLE_DATA_SIZE; i++) { - rc = uart_poll_in(fixture->dev, &rx_content[i]); + rc = uart_poll_in(fixture->dev, &fixture->rx_content[i]); zassert_equal(rc, 0, "RX buffer should contain data"); } - zassert_mem_equal(rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); + zassert_mem_equal(fixture->rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); /* No more data in RX buffer */ - rc = uart_poll_in(fixture->dev, &rx_content[0]); + rc = uart_poll_in(fixture->dev, &fixture->rx_content[0]); zassert_equal(rc, -1, "RX buffer should be empty"); } @@ -103,47 +104,45 @@ ZTEST_F(uart_emul, test_errors) static void uart_emul_isr(const struct device *dev, void *user_data) { - /* always of size SAMPLE_DATA_SIZE */ - uint8_t *buf = user_data; + struct uart_emul_fixture *fixture = user_data; while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { if (uart_irq_tx_ready(dev)) { - uart_fifo_fill(dev, buf, SAMPLE_DATA_SIZE); + uart_fifo_fill(dev, fixture->tx_content, SAMPLE_DATA_SIZE); uart_irq_tx_disable(dev); } if (uart_irq_rx_ready(dev)) { - uart_fifo_read(dev, buf, SAMPLE_DATA_SIZE); + uart_fifo_read(dev, fixture->rx_content, SAMPLE_DATA_SIZE); } } } ZTEST_F(uart_emul, test_irq_tx) { - uint8_t tx_content[SAMPLE_DATA_SIZE] = {0}; size_t tx_len; - uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, fixture->sample_data); + uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, fixture); /* enabling the tx irq will call the callback, if set */ uart_irq_tx_enable(fixture->dev); /* allow space for work queue to run */ k_yield(); - tx_len = uart_emul_get_tx_data(fixture->dev, tx_content, SAMPLE_DATA_SIZE); + tx_len = uart_emul_get_tx_data(fixture->dev, fixture->tx_content, SAMPLE_DATA_SIZE); zassert_equal(tx_len, SAMPLE_DATA_SIZE, "TX buffer length does not match"); - zassert_mem_equal(tx_content, fixture->sample_data, SAMPLE_DATA_SIZE); + zassert_mem_equal(fixture->tx_content, fixture->sample_data, SAMPLE_DATA_SIZE); /* No more data in TX buffer */ - tx_len = uart_emul_get_tx_data(fixture->dev, tx_content, sizeof(tx_content)); + tx_len = uart_emul_get_tx_data(fixture->dev, fixture->tx_content, + sizeof(fixture->tx_content)); zassert_equal(tx_len, 0, "TX buffer should be empty"); } ZTEST_F(uart_emul, test_irq_rx) { - uint8_t rx_content[SAMPLE_DATA_SIZE] = {0}; int rc; - uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, rx_content); + uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, fixture); uart_irq_rx_enable(fixture->dev); /* putting rx data will call the irq callback, if enabled */ @@ -151,10 +150,10 @@ ZTEST_F(uart_emul, test_irq_rx) /* allow space for work queue to run */ k_yield(); - zassert_mem_equal(rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); + zassert_mem_equal(fixture->rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); /* No more data in RX buffer */ - rc = uart_poll_in(fixture->dev, &rx_content[0]); + rc = uart_poll_in(fixture->dev, &fixture->rx_content[0]); zassert_equal(rc, -1, "RX buffer should be empty"); uart_irq_rx_disable(fixture->dev); From d89cef7e19ba824deffaf08198ca1c445b3b818a Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 17:08:12 +0100 Subject: [PATCH 2983/4498] tests: drivers: serial: emul: Synchronize UART ISR tx/rx Add synchronization using semaphores for the UART ISR tx/rx tests, instead of relying on a single k_yield() call to ensure all UART ISR work can be completed before validating the result. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/uart/uart_emul/src/main.c | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/drivers/uart/uart_emul/src/main.c b/tests/drivers/uart/uart_emul/src/main.c index 8391245a31a..2d045edfeb8 100644 --- a/tests/drivers/uart/uart_emul/src/main.c +++ b/tests/drivers/uart/uart_emul/src/main.c @@ -19,6 +19,8 @@ struct uart_emul_fixture { uint8_t sample_data[SAMPLE_DATA_SIZE]; uint8_t tx_content[SAMPLE_DATA_SIZE]; uint8_t rx_content[SAMPLE_DATA_SIZE]; + struct k_sem tx_done_sem; + struct k_sem rx_done_sem; }; static void *uart_emul_setup(void) @@ -29,6 +31,9 @@ static void *uart_emul_setup(void) fixture.sample_data[i] = i; } + k_sem_init(&fixture.tx_done_sem, 0, 1); + k_sem_init(&fixture.rx_done_sem, 0, 1); + zassert_not_null(fixture.dev); return &fixture; } @@ -44,6 +49,12 @@ static void uart_emul_before(void *f) uart_emul_flush_tx_data(fixture->dev); uart_err_check(fixture->dev); + + k_sem_reset(&fixture->tx_done_sem); + k_sem_reset(&fixture->rx_done_sem); + + memset(fixture->tx_content, 0, sizeof(fixture->tx_content)); + memset(fixture->rx_content, 0, sizeof(fixture->rx_content)); } ZTEST_F(uart_emul, test_polling_out) @@ -108,12 +119,14 @@ static void uart_emul_isr(const struct device *dev, void *user_data) while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { if (uart_irq_tx_ready(dev)) { - uart_fifo_fill(dev, fixture->tx_content, SAMPLE_DATA_SIZE); + uart_fifo_fill(dev, fixture->sample_data, SAMPLE_DATA_SIZE); uart_irq_tx_disable(dev); + k_sem_give(&fixture->tx_done_sem); } if (uart_irq_rx_ready(dev)) { uart_fifo_read(dev, fixture->rx_content, SAMPLE_DATA_SIZE); + k_sem_give(&fixture->rx_done_sem); } } } @@ -125,8 +138,9 @@ ZTEST_F(uart_emul, test_irq_tx) uart_irq_callback_user_data_set(fixture->dev, uart_emul_isr, fixture); /* enabling the tx irq will call the callback, if set */ uart_irq_tx_enable(fixture->dev); - /* allow space for work queue to run */ - k_yield(); + /* Wait for all data to be received in full */ + zassert_equal(k_sem_take(&fixture->tx_done_sem, K_SECONDS(1)), 0, + "Timeout waiting for UART ISR"); tx_len = uart_emul_get_tx_data(fixture->dev, fixture->tx_content, SAMPLE_DATA_SIZE); zassert_equal(tx_len, SAMPLE_DATA_SIZE, "TX buffer length does not match"); @@ -147,8 +161,10 @@ ZTEST_F(uart_emul, test_irq_rx) /* putting rx data will call the irq callback, if enabled */ uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE); - /* allow space for work queue to run */ - k_yield(); + + /* Wait for all data to be received in full */ + zassert_equal(k_sem_take(&fixture->rx_done_sem, K_SECONDS(1)), 0, + "Timeout waiting for UART ISR"); zassert_mem_equal(fixture->rx_content, fixture->sample_data, SAMPLE_DATA_SIZE); From 27dfdd737eb03b410781af20592fa6c3bec13dfd Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 17:31:05 +0100 Subject: [PATCH 2984/4498] drivers: serial: emul: Make UART FIFO size realistic Real UARTs usually write 1 to a few bytes at a time through a latch buffer. Add latch buffer property to binding for uart_emul and limit fifo_read and fifo_fill to not exceed the latch buffer. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/uart_emul.c | 20 ++++++++++---------- dts/bindings/serial/zephyr,uart-emul.yaml | 6 ++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 6bfe3cf8a85..645c888e539 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(uart_emul, CONFIG_UART_LOG_LEVEL); struct uart_emul_config { bool loopback; + size_t latch_buffer_size; }; struct uart_emul_work { @@ -147,13 +148,14 @@ static int uart_emul_fifo_fill(const struct device *dev, const uint8_t *tx_data, int ret; struct uart_emul_data *data = dev->data; const struct uart_emul_config *config = dev->config; + uint32_t put_size = MIN(config->latch_buffer_size, size); K_SPINLOCK(&data->tx_lock) { - ret = ring_buf_put(data->tx_rb, tx_data, size); + ret = ring_buf_put(data->tx_rb, tx_data, put_size); } if (config->loopback) { - uart_emul_put_rx_data(dev, (uint8_t *)tx_data, ret); + uart_emul_put_rx_data(dev, (uint8_t *)tx_data, put_size); } if (data->tx_data_ready_cb) { data->tx_data_ready_cb(dev, ring_buf_size_get(data->tx_rb), data->user_data); @@ -164,19 +166,16 @@ static int uart_emul_fifo_fill(const struct device *dev, const uint8_t *tx_data, static int uart_emul_fifo_read(const struct device *dev, uint8_t *rx_data, int size) { - int ret; struct uart_emul_data *data = dev->data; + const struct uart_emul_config *config = dev->config; + uint32_t bytes_to_read; K_SPINLOCK(&data->rx_lock) { - ret = MIN(size, ring_buf_size_get(data->rx_rb)); - size = ret; - - for (int n = 0; size > 0; size -= n, rx_data += n) { - n = ring_buf_get(data->rx_rb, rx_data, size); - } + bytes_to_read = MIN(config->latch_buffer_size, ring_buf_size_get(data->rx_rb)); + ring_buf_get(data->rx_rb, rx_data, bytes_to_read); } - return ret; + return bytes_to_read; } static int uart_emul_irq_tx_ready(const struct device *dev) @@ -450,6 +449,7 @@ void uart_emul_set_errors(const struct device *dev, int errors) \ static struct uart_emul_config uart_emul_cfg_##inst = { \ .loopback = DT_INST_PROP(inst, loopback), \ + .latch_buffer_size = DT_INST_PROP(inst, latch_buffer_size), \ }; \ static struct uart_emul_data uart_emul_data_##inst = { \ .rx_rb = &uart_emul_##inst##_rx_rb, \ diff --git a/dts/bindings/serial/zephyr,uart-emul.yaml b/dts/bindings/serial/zephyr,uart-emul.yaml index d3d50dc9e93..119aa49df6a 100644 --- a/dts/bindings/serial/zephyr,uart-emul.yaml +++ b/dts/bindings/serial/zephyr,uart-emul.yaml @@ -25,3 +25,9 @@ properties: description: | Connects TX to RX internally creating a loop back connection. Useful for testing. + + latch-buffer-size: + type: int + default: 1 + description: | + Size of the virtual UART latch buffer. From b290ba806d90aabb238e9d1203497de492f3ac7e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 17:58:59 +0100 Subject: [PATCH 2985/4498] tests: serial: uart: emul: Update isr rx/tx tests The tests for ISR rx/tx must now be updated to send and receive bytes in smaller chunks. Signed-off-by: Bjarki Arge Andreasen --- tests/drivers/uart/uart_emul/src/main.c | 59 +++++++++++++++++++++---- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/tests/drivers/uart/uart_emul/src/main.c b/tests/drivers/uart/uart_emul/src/main.c index 2d045edfeb8..cea1dc72334 100644 --- a/tests/drivers/uart/uart_emul/src/main.c +++ b/tests/drivers/uart/uart_emul/src/main.c @@ -12,7 +12,12 @@ #define EMUL_UART_NODE DT_NODELABEL(euart0) #define EMUL_UART_RX_FIFO_SIZE DT_PROP(EMUL_UART_NODE, rx_fifo_size) #define EMUL_UART_TX_FIFO_SIZE DT_PROP(EMUL_UART_NODE, tx_fifo_size) -#define SAMPLE_DATA_SIZE MIN(EMUL_UART_RX_FIFO_SIZE, EMUL_UART_TX_FIFO_SIZE) + +/* + * Leave one byte left in tx to avoid filling it completely which will block the UART + * tx ready IRQ event. + */ +#define SAMPLE_DATA_SIZE MIN(EMUL_UART_RX_FIFO_SIZE, EMUL_UART_TX_FIFO_SIZE) - 1 struct uart_emul_fixture { const struct device *dev; @@ -21,6 +26,8 @@ struct uart_emul_fixture { uint8_t rx_content[SAMPLE_DATA_SIZE]; struct k_sem tx_done_sem; struct k_sem rx_done_sem; + size_t tx_remaining; + size_t rx_remaining; }; static void *uart_emul_setup(void) @@ -55,6 +62,9 @@ static void uart_emul_before(void *f) memset(fixture->tx_content, 0, sizeof(fixture->tx_content)); memset(fixture->rx_content, 0, sizeof(fixture->rx_content)); + + fixture->tx_remaining = SAMPLE_DATA_SIZE; + fixture->rx_remaining = SAMPLE_DATA_SIZE; } ZTEST_F(uart_emul, test_polling_out) @@ -113,20 +123,51 @@ ZTEST_F(uart_emul, test_errors) zassert_equal(errors, UART_ERROR_OVERRUN, "UART errors do not match"); } +static void uart_emul_isr_handle_tx_ready(struct uart_emul_fixture *fixture) +{ + uint32_t sample_data_it; + int ret; + + if (fixture->tx_remaining) { + sample_data_it = sizeof(fixture->sample_data) - fixture->tx_remaining; + ret = uart_fifo_fill(fixture->dev, &fixture->sample_data[sample_data_it], + fixture->tx_remaining); + fixture->tx_remaining -= (size_t)ret; + } + + if (fixture->tx_remaining == 0) { + uart_irq_tx_disable(fixture->dev); + k_sem_give(&fixture->tx_done_sem); + } +} + +static void uart_emul_isr_handle_rx_ready(struct uart_emul_fixture *fixture) +{ + uint32_t rx_content_it; + int ret; + + if (fixture->tx_remaining) { + rx_content_it = sizeof(fixture->rx_content) - fixture->rx_remaining; + ret = uart_fifo_read(fixture->dev, &fixture->rx_content[rx_content_it], + fixture->rx_remaining); + fixture->rx_remaining -= (size_t)ret; + } + + if (fixture->rx_remaining == 0) { + k_sem_give(&fixture->rx_done_sem); + } +} + static void uart_emul_isr(const struct device *dev, void *user_data) { struct uart_emul_fixture *fixture = user_data; while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { - if (uart_irq_tx_ready(dev)) { - uart_fifo_fill(dev, fixture->sample_data, SAMPLE_DATA_SIZE); - uart_irq_tx_disable(dev); - k_sem_give(&fixture->tx_done_sem); + if (uart_irq_tx_ready(fixture->dev)) { + uart_emul_isr_handle_tx_ready(fixture); } - - if (uart_irq_rx_ready(dev)) { - uart_fifo_read(dev, fixture->rx_content, SAMPLE_DATA_SIZE); - k_sem_give(&fixture->rx_done_sem); + if (uart_irq_rx_ready(fixture->dev)) { + uart_emul_isr_handle_rx_ready(fixture); } } } From 73bab817a0ae8dd0f5c09ab684170566c1291a5a Mon Sep 17 00:00:00 2001 From: Marc Lasch Date: Thu, 2 Nov 2023 14:36:12 +0100 Subject: [PATCH 2986/4498] net: lwm2m: Remove the resource type in registration message Do not include the resource type (rt=) in the registration message when using the OMA JSON format. This was a workaround specifically for the Wakaama LwM2M server which is no longer needed since the latest master branch. Signed-off-by: Marc Lasch --- subsys/net/lib/lwm2m/lwm2m_rw_link_format.c | 15 ++++++--------- .../net/lib/lwm2m/content_link_format/src/main.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c b/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c index 0cf8b440434..597641450be 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c @@ -20,22 +20,19 @@ LOG_MODULE_REGISTER(net_lwm2m_link_format, CONFIG_LWM2M_LOG_LEVEL); /* * TODO: to implement a way for clients to specify alternate path * via Kconfig (LwM2M specification 8.2.2 Alternate Path) - * - * For now, in order to inform server we support JSON format, we have to - * report 'ct=11543' to the server. '' is required in order to append - * content attribute. And resource type attribute is appended because of - * Eclipse wakaama will reject the registration when 'rt="oma.lwm2m"' is - * missing. */ - +/* + * In order to inform the server about the configured LwM2M content format, we have + * to report 'ct=' with the content type value to the server. The root path '' + * is required in order to append the content type attribute. + */ #if defined(CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT) #define REG_PREFACE ";ct=" STRINGIFY(LWM2M_FORMAT_APP_SENML_CBOR) #elif defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) #define REG_PREFACE ";ct=" STRINGIFY(LWM2M_FORMAT_APP_SEML_JSON) #elif defined(CONFIG_LWM2M_RW_JSON_SUPPORT) -#define REG_PREFACE ";rt=\"oma.lwm2m\"" \ - ";ct=" STRINGIFY(LWM2M_FORMAT_OMA_JSON) +#define REG_PREFACE ";ct=" STRINGIFY(LWM2M_FORMAT_OMA_JSON) #else #define REG_PREFACE "" #endif diff --git a/tests/net/lib/lwm2m/content_link_format/src/main.c b/tests/net/lib/lwm2m/content_link_format/src/main.c index 76429b78f98..3b0189ddbe7 100644 --- a/tests/net/lib/lwm2m/content_link_format/src/main.c +++ b/tests/net/lib/lwm2m/content_link_format/src/main.c @@ -156,7 +156,7 @@ ZTEST(net_content_link_format, test_put_begin_bs_discovery) ZTEST(net_content_link_format, test_put_begin_register) { int ret; - const char *expected_payload = ";rt=\"oma.lwm2m\";ct=11543"; + const char *expected_payload = ";ct=11543"; test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER; From 1d0dda794ce93928e217904fc6b47072e0bb7b8f Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Thu, 2 Nov 2023 09:58:19 +0100 Subject: [PATCH 2987/4498] net: pkt: remove redundant `net_pkt_cb_ieee802154` fields Remove redundant `arb` and `fv2015` fields. Signed-off-by: Eduardo Montoya --- include/zephyr/net/ieee802154_pkt.h | 24 ------------------- modules/openthread/platform/radio.c | 11 +++------ tests/net/ieee802154/l2/src/ieee802154_test.c | 1 - 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index a1dca472448..d5fdc712b49 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -68,7 +68,6 @@ struct net_pkt_cb_ieee802154 { }; /* Flags */ - uint8_t arb : 1; /* ACK Request Bit is set in the frame */ uint8_t ack_fpb : 1; /* Frame Pending Bit was set in the ACK */ uint8_t frame_secured : 1; /* Frame is authenticated and * encrypted according to its @@ -80,9 +79,6 @@ struct net_pkt_cb_ieee802154 { * e.g. Frame Counter injection. */ #if defined(CONFIG_NET_L2_OPENTHREAD) - uint8_t fv2015: 1; /* Frame version is IEEE 802.15.4 (0b10), - * see section 7.2.2.10, table 7-3. - */ uint8_t ack_seb : 1; /* Security Enabled Bit was set in the ACK */ #endif }; @@ -201,16 +197,6 @@ static inline void net_pkt_set_ieee802154_txpwr(struct net_pkt *pkt, int8_t txpw } #endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ -static inline bool net_pkt_ieee802154_arb(struct net_pkt *pkt) -{ - return net_pkt_cb_ieee802154(pkt)->arb; -} - -static inline void net_pkt_set_ieee802154_arb(struct net_pkt *pkt, bool arb) -{ - net_pkt_cb_ieee802154(pkt)->arb = arb; -} - static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt) { return net_pkt_cb_ieee802154(pkt)->ack_fpb; @@ -262,16 +248,6 @@ static inline void net_pkt_set_ieee802154_ack_keyid(struct net_pkt *pkt, uint8_t net_pkt_cb_ieee802154(pkt)->ack_keyid = keyid; } -static inline bool net_pkt_ieee802154_fv2015(struct net_pkt *pkt) -{ - return net_pkt_cb_ieee802154(pkt)->fv2015; -} - -static inline void net_pkt_set_ieee802154_fv2015(struct net_pkt *pkt, bool fv2015) -{ - net_pkt_cb_ieee802154(pkt)->fv2015 = fv2015; -} - static inline bool net_pkt_ieee802154_ack_seb(struct net_pkt *pkt) { return net_pkt_cb_ieee802154(pkt)->ack_seb; diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 67360860c56..391ffba395d 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -478,14 +478,9 @@ static void openthread_handle_received_frame(otInstance *instance, recv_frame.mInfo.mRxInfo.mTimestamp = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC; #endif - if (net_pkt_ieee802154_arb(pkt) && net_pkt_ieee802154_fv2015(pkt)) { - recv_frame.mInfo.mRxInfo.mAckedWithSecEnhAck = - net_pkt_ieee802154_ack_seb(pkt); - recv_frame.mInfo.mRxInfo.mAckFrameCounter = - net_pkt_ieee802154_ack_fc(pkt); - recv_frame.mInfo.mRxInfo.mAckKeyId = - net_pkt_ieee802154_ack_keyid(pkt); - } + recv_frame.mInfo.mRxInfo.mAckedWithSecEnhAck = net_pkt_ieee802154_ack_seb(pkt); + recv_frame.mInfo.mRxInfo.mAckFrameCounter = net_pkt_ieee802154_ack_fc(pkt); + recv_frame.mInfo.mRxInfo.mAckKeyId = net_pkt_ieee802154_ack_keyid(pkt); if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) { otPlatDiagRadioReceiveDone(instance, &recv_frame, OT_ERROR_NONE); diff --git a/tests/net/ieee802154/l2/src/ieee802154_test.c b/tests/net/ieee802154/l2/src/ieee802154_test.c index 7347969d21a..ea90fc47a3e 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_test.c +++ b/tests/net/ieee802154/l2/src/ieee802154_test.c @@ -604,7 +604,6 @@ static bool test_packet_cloning_with_cb(void) zassert_true(net_pkt_ieee802154_ack_fpb(cloned_pkt)); zassert_true(net_pkt_ieee802154_frame_secured(cloned_pkt)); - zassert_false(net_pkt_ieee802154_arb(cloned_pkt)); zassert_false(net_pkt_ieee802154_mac_hdr_rdy(cloned_pkt)); zassert_equal(net_pkt_ieee802154_lqi(cloned_pkt), 50U); zassert_equal(net_pkt_ieee802154_rssi(cloned_pkt), 0U); From 49a69dad653b00e496c7efd7ffebabaef01775a1 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 2 Nov 2023 11:10:50 +0100 Subject: [PATCH 2988/4498] boards: arm: Add support for STM32L4R9I-DISCO Adds the device trees for the board and its Arduino connector, default Kconfig and documentation. The following features have been confirmed working on hardware: * ADC * I2C * RTC * SPI * SDMMC * UART * OctoSPI Flash Signed-off-by: Mathieu Choplain --- boards/arm/stm32l4r9i_disco/Kconfig.board | 8 + boards/arm/stm32l4r9i_disco/Kconfig.defconfig | 11 + .../arduino_r3_connector.dtsi | 39 +++ boards/arm/stm32l4r9i_disco/board.cmake | 6 + .../doc/img/stm32l4r9i_disco.jpg | Bin 0 -> 57892 bytes boards/arm/stm32l4r9i_disco/doc/index.rst | 150 ++++++++++ .../arm/stm32l4r9i_disco/stm32l4r9i_disco.dts | 274 ++++++++++++++++++ .../stm32l4r9i_disco/stm32l4r9i_disco.yaml | 25 ++ .../stm32l4r9i_disco_defconfig | 26 ++ .../arm/stm32l4r9i_disco/support/openocd.cfg | 12 + 10 files changed, 551 insertions(+) create mode 100644 boards/arm/stm32l4r9i_disco/Kconfig.board create mode 100644 boards/arm/stm32l4r9i_disco/Kconfig.defconfig create mode 100644 boards/arm/stm32l4r9i_disco/arduino_r3_connector.dtsi create mode 100644 boards/arm/stm32l4r9i_disco/board.cmake create mode 100644 boards/arm/stm32l4r9i_disco/doc/img/stm32l4r9i_disco.jpg create mode 100644 boards/arm/stm32l4r9i_disco/doc/index.rst create mode 100644 boards/arm/stm32l4r9i_disco/stm32l4r9i_disco.dts create mode 100644 boards/arm/stm32l4r9i_disco/stm32l4r9i_disco.yaml create mode 100644 boards/arm/stm32l4r9i_disco/stm32l4r9i_disco_defconfig create mode 100644 boards/arm/stm32l4r9i_disco/support/openocd.cfg diff --git a/boards/arm/stm32l4r9i_disco/Kconfig.board b/boards/arm/stm32l4r9i_disco/Kconfig.board new file mode 100644 index 00000000000..57da0f65fdf --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/Kconfig.board @@ -0,0 +1,8 @@ +# STM32L4R9I Discovery board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32L4R9I_DISCO + bool "STM32L4R9I Discovery Development Board" + depends on SOC_STM32L4R9XX diff --git a/boards/arm/stm32l4r9i_disco/Kconfig.defconfig b/boards/arm/stm32l4r9i_disco/Kconfig.defconfig new file mode 100644 index 00000000000..82eafa62744 --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/Kconfig.defconfig @@ -0,0 +1,11 @@ +# STM32L4R9I Discovery board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_STM32L4R9I_DISCO + +config BOARD + default "stm32l4r9i_disco" + +endif # BOARD_STM32L4R9I_DISCO diff --git a/boards/arm/stm32l4r9i_disco/arduino_r3_connector.dtsi b/boards/arm/stm32l4r9i_disco/arduino_r3_connector.dtsi new file mode 100644 index 00000000000..29b56539b70 --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 7 0>, /* A0 */ + <1 0 &gpioc 4 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpiob 0 0>, /* A3 */ + <4 0 &gpioa 0 0>, /* A4 */ + <5 0 &gpioa 5 0>, /* A5 */ + <6 0 &gpioc 0 0>, /* D0 */ + <7 0 &gpioc 1 0>, /* D1 */ + <8 0 &gpiog 11 0>, /* D2 */ + <9 0 &gpiof 10 0>, /* D3 */ + <10 0 &gpiog 6 0>, /* D4 */ + <11 0 &gpioa 1 0>, /* D5 */ + <12 0 &gpiob 4 0>, /* D6 */ + <13 0 &gpioa 4 0>, /* D7 */ + <14 0 &gpioh 15 0>, /* D8 */ + <15 0 &gpioh 13 0>, /* D9 */ + <16 0 &gpioi 0 0>, /* D10 */ + <17 0 &gpiob 15 0>, /* D11 */ + <18 0 &gpiob 14 0>, /* D12 */ + <19 0 &gpiob 13 0>, /* D13 */ + <20 0 &gpiog 8 0>, /* D14 */ + <21 0 &gpiog 7 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c3 {}; +arduino_spi: &spi2 {}; diff --git a/boards/arm/stm32l4r9i_disco/board.cmake b/boards/arm/stm32l4r9i_disco/board.cmake new file mode 100644 index 00000000000..c88ae7d0783 --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32L4R9AI" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/stm32l4r9i_disco/doc/img/stm32l4r9i_disco.jpg b/boards/arm/stm32l4r9i_disco/doc/img/stm32l4r9i_disco.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06914737b5b6b4c3c05dc142e4ca8ee0dca3cbf2 GIT binary patch literal 57892 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 z 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 +#include +#include +#include "arduino_r3_connector.dtsi" + +/ { + model = "STMicroelectronics STM32L4R9I-DISCO board"; + compatible = "st,stm32l4r9i-disco"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + /* N.B. LD1 (orange) is not wired to MCU */ + green_led: led_2 { + gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + joy_sel: joystick_selection { + label = "joystick selection"; + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led; + sw0 = &joy_sel; + die-temp0 = &die_temp; + volt-sensor0 = &vref; + volt-sensor1 = &vbat; + spi-flash0 = &mx25lm51245; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_msi { + status = "okay"; + msi-range = <6>; + msi-pll-mode; +}; + +&pll { + status = "okay"; + div-m = <1>; + mul-n = <60>; + /* + * WORKAROUND: stm32l4-pll-clock does not allow arbitrary PLLP dividers. + * Disable PLLP completely since it only feeds SAI, which is not active either. + */ + /* div-p = <5>; */ + div-q = <2>; + div-r = <2>; + clocks = <&clk_msi>; +}; + +&rcc { + clocks = <&pll>; + ahb-prescaler = <1>; + clock-frequency = ; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&usart2 { + status = "okay"; + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&lpuart1 { + status = "okay"; + pinctrl-0 = <&lpuart1_tx_pc1 &lpuart1_rx_pc0>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&timers3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + /* + * N.B.: Datasheet indicates that ARD_D11 (wired to PB15) is connected to TIM3_CH2. + * However, this is incorrect as PB15 cannot be muxed to TIM3 (see DS12023). + * Moved ARD_D11 to TIM15_CH2 instead. + */ + pinctrl-0 = <&tim3_ch1_pb4>; + pinctrl-names = "default"; + }; +}; + +&timers5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&tim5_ch2_pa1 &tim5_ch4_pi0>; + pinctrl-names = "default"; + }; +}; + +&timers8 { + status = "okay"; + + pwm8: pwm { + status = "okay"; + pinctrl-0 = <&tim8_ch1n_ph13>; + pinctrl-names = "default"; + }; +}; + +&timers15 { + status = "okay"; + + pwm15: pwm { + status = "okay"; + pinctrl-0 = <&tim15_ch2_pf10 &tim15_ch2_pb15>; + pinctrl-names = "default"; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pg13>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&i2c3_scl_pg7 &i2c3_sda_pg8>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; + pinctrl-names = "default"; + cs-gpios = <&gpioi 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&sdmmc1 { + status = "okay"; + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; + pinctrl-names = "default"; +}; + +&adc1 { + status = "okay"; + pinctrl-0 = <&adc1_in5_pa0 &adc1_in12_pa7 &adc1_in15_pb0 + &adc1_in4_pc3 &adc1_in13_pc4>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <1>; +}; + +zephyr_udc0: &usbotg_fs { + status = "okay"; + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12 + &usb_otg_fs_id_pa10>; + pinctrl-names = "default"; +}; + +&die_temp { + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&vbat { + status = "okay"; +}; + +&octospi2 { + status = "okay"; + pinctrl-0 = <&octospim_p2_clk_pi6 &octospim_p2_ncs_pg12 + &octospim_p2_io0_pi11 &octospim_p2_io1_pi10 + &octospim_p2_io2_pi9 &octospim_p2_io3_ph8 + &octospim_p2_io4_ph9 &octospim_p2_io5_ph10 + &octospim_p2_io6_pg9 &octospim_p2_io7_pg10 + &octospim_p2_dqs_pg15>; + pinctrl-names = "default"; + + mx25lm51245: ospi-nor-flash@0 { + status = "okay"; + compatible = "st,stm32-ospi-nor"; + reg = <0>; + ospi-max-frequency = ; + size = ; /* 512 Mbits = 64 MBytes */ + spi-bus-width = ; + data-rate = ; + four-byte-opcodes; + sfdp-bfp = [ + 53 46 44 50 06 01 02 ff + 00 06 01 10 30 00 00 ff + c2 00 01 04 10 01 00 ff + 84 00 01 02 c0 00 00 ff + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + e5 20 fb ff ff ff ff 1f + 44 eb 08 6b 08 3b 04 bb + fe ff ff ff ff ff 00 ff + ff ff 44 eb 0c 20 0f 52 + 10 d8 00 ff d6 49 c5 00 + 81 df 04 e3 44 03 67 38 + 30 b0 30 b0 f7 bd d5 5c + 4a 9e 29 ff f0 50 f9 85 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 7f ef ff ff 21 5c dc ff + ]; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x00000000 DT_SIZE_M(64)>; + }; + }; + }; +}; diff --git a/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco.yaml b/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco.yaml new file mode 100644 index 00000000000..89ab98c92b1 --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco.yaml @@ -0,0 +1,25 @@ +identifier: stm32l4r9i_disco +name: ST STM32L4R9I Discovery +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 640 +flash: 2048 +vendor: st +supported: + - adc + - arduino_gpio + - arduino_i2c + - arduino_spi + - gpio + - i2c + - pwm + - rtc + - sdhc + - spi + - uart + - usb + - usb_device diff --git a/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco_defconfig b/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco_defconfig new file mode 100644 index 00000000000..546bd3379a8 --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/stm32l4r9i_disco_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32L4X=y +CONFIG_SOC_STM32L4R9XX=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable UART +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable clocks +CONFIG_CLOCK_CONTROL=y + +# Enable pin controller +CONFIG_PINCTRL=y diff --git a/boards/arm/stm32l4r9i_disco/support/openocd.cfg b/boards/arm/stm32l4r9i_disco/support/openocd.cfg new file mode 100644 index 00000000000..295299f2fbe --- /dev/null +++ b/boards/arm/stm32l4r9i_disco/support/openocd.cfg @@ -0,0 +1,12 @@ +source [find board/stm32l4discovery.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} From 4750cbab1e916146fd73420dcc97e711334fa62b Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 2 Nov 2023 11:08:21 +0100 Subject: [PATCH 2989/4498] tests: drivers/adc: Add STM32L4R9I-DISCO overlay Adds the required overlay for test to build and pass successfully on STM32L4R9I-DISCO board. Signed-off-by: Mathieu Choplain --- .../adc_api/boards/stm32l4r9i_disco.overlay | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/stm32l4r9i_disco.overlay diff --git a/tests/drivers/adc/adc_api/boards/stm32l4r9i_disco.overlay b/tests/drivers/adc/adc_api/boards/stm32l4r9i_disco.overlay new file mode 100644 index 00000000000..692d5d9aac5 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/stm32l4r9i_disco.overlay @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) STMicroelectronics + */ + +/ { + zephyr,user { + io-channels = <&adc1 0>; + }; +}; + +&adc1 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 2a70c3194535e90d871729e54035c96af9432fd2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 27 Oct 2023 09:27:48 +0000 Subject: [PATCH 2990/4498] scripts: check_init_priorities: drop the same priority check Since bb590b5b6e introduced ordinals in the priority sequence, the "same priority" case cannot happen anymore, furthermore the priority value in the script is now the position of the function in the init sequence, so if two devices have the same priority there's something real bad going on. Drop all the "same priority" handling code and tests, convert the case into ane exception instead. Drop the init stubs as well from the test, they are not required anymore. Signed-off-by: Fabio Baltieri --- CMakeLists.txt | 4 -- Kconfig.zephyr | 11 +----- scripts/build/check_init_priorities.py | 11 +----- scripts/build/check_init_priorities_test.py | 38 +++++++++++-------- .../boards/native_posix.overlay | 7 ---- tests/misc/check_init_priorities/src/main.c | 15 ++------ .../validate_check_init_priorities_output.py | 2 - 7 files changed, 30 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e3fd205a8a..be466a1ae81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1797,14 +1797,10 @@ if(CONFIG_BUILD_OUTPUT_INFO_HEADER) endif() if(CONFIG_CHECK_INIT_PRIORITIES) - if(CONFIG_CHECK_INIT_PRIORITIES_FAIL_ON_WARNING) - set(fail_on_warning "--fail-on-warning") - endif() list(APPEND post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py --elf-file=${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} - ${fail_on_warning} ) endif() diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 0edb610d677..b532dbc4435 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -785,16 +785,7 @@ config CHECK_INIT_PRIORITIES derived from the devicetree definition. Fails the build on priority errors (dependent devices, inverted - priority), see CHECK_INIT_PRIORITIES_FAIL_ON_WARNING to fail on - warnings (dependent devices, same priority) as well. - -config CHECK_INIT_PRIORITIES_FAIL_ON_WARNING - bool "Fail the build on priority check warnings" - depends on CHECK_INIT_PRIORITIES - help - Fail the build if the dependency check script identifies any pair of - devices depending on each other but initialized with the same - priority. + priority). config EMIT_ALL_SYSCALLS bool "Emit all possible syscalls in the tree" diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 88f7f310040..22a27f24ef9 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -244,7 +244,6 @@ def __init__(self, elf_file_path, edt_pickle, log): self._obj = ZephyrInitLevels(elf_file_path) - self.warnings = 0 self.errors = 0 def _check_dep(self, dev_ord, dep_ord): @@ -275,9 +274,8 @@ def _check_dep(self, dev_ord, dep_ord): return if dev_prio == dep_prio: - self.warnings += 1 - self.log.warning( - f"{dev_node.path} {dev_prio} == {dep_node.path} {dep_prio}") + raise ValueError(f"{dev_node.path} and {dep_node.path} have the " + f"same priority: {dev_prio}") elif dev_prio < dep_prio: self.errors += 1 self.log.error( @@ -311,8 +309,6 @@ def _parse_args(argv): parser.add_argument("-v", "--verbose", action="count", help=("enable verbose output, can be used multiple times " "to increase verbosity level")) - parser.add_argument("-w", "--fail-on-warning", action="store_true", - help="fail on both warnings and errors") parser.add_argument("--always-succeed", action="store_true", help="always exit with a return code of 0, used for testing") parser.add_argument("-o", "--output", @@ -363,9 +359,6 @@ def main(argv=None): if args.always_succeed: return 0 - if args.fail_on_warning and validator.warnings: - return 1 - if validator.errors: return 1 diff --git a/scripts/build/check_init_priorities_test.py b/scripts/build/check_init_priorities_test.py index 9783e5d828e..36d362a63cc 100755 --- a/scripts/build/check_init_priorities_test.py +++ b/scripts/build/check_init_priorities_test.py @@ -295,35 +295,46 @@ def test_check(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() validator._obj = mock.Mock() - validator.warnings = 0 validator.errors = 0 - validator._ord2node = {1: mock.Mock(), 2: mock.Mock(), 3: mock.Mock()} + validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} validator._ord2node[1]._binding = None validator._ord2node[1].path = "/1" validator._ord2node[2]._binding = None validator._ord2node[2].path = "/2" - validator._ord2node[3]._binding = None - validator._ord2node[3].path = "/3" - validator._obj.devices = {1: 10, 2: 10, 3: 20} + validator._obj.devices = {1: 10, 2: 20} - validator._check_dep(3, 1) validator._check_dep(2, 1) - validator._check_dep(1, 3) + validator._check_dep(1, 2) - validator.log.info.assert_called_once_with("/3 20 > /1 10") - validator.log.warning.assert_called_once_with("/2 10 == /1 10") - validator.log.error.assert_called_once_with("/1 10 < /3 20") - self.assertEqual(validator.warnings, 1) + validator.log.info.assert_called_once_with("/2 20 > /1 10") + validator.log.error.assert_called_once_with("/1 10 < /2 20") self.assertEqual(validator.errors, 1) + @mock.patch("check_init_priorities.Validator.__init__", return_value=None) + def test_check_same_prio_assert(self, mock_vinit): + validator = check_init_priorities.Validator("", "", None) + validator.log = mock.Mock() + validator._obj = mock.Mock() + validator.errors = 0 + + validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} + validator._ord2node[1]._binding = None + validator._ord2node[1].path = "/1" + validator._ord2node[2]._binding = None + validator._ord2node[2].path = "/2" + + validator._obj.devices = {1: 10, 2: 10} + + with self.assertRaises(ValueError): + validator._check_dep(1, 2) + @mock.patch("check_init_priorities.Validator.__init__", return_value=None) def test_check_swapped(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() validator._obj = mock.Mock() - validator.warnings = 0 validator.errors = 0 save_inverted_priorities = check_init_priorities._INVERTED_PRIORITY_COMPATIBLES @@ -344,7 +355,6 @@ def test_check_swapped(self, mock_vinit): mock.call("Swapped priority: compat-3, compat-1"), mock.call("/3 20 > /1 10"), ]) - self.assertEqual(validator.warnings, 0) self.assertEqual(validator.errors, 0) check_init_priorities._INVERTED_PRIORITY_COMPATIBLES = save_inverted_priorities @@ -354,7 +364,6 @@ def test_check_ignored(self, mock_vinit): validator = check_init_priorities.Validator("", "", None) validator.log = mock.Mock() validator._obj = mock.Mock() - validator.warnings = 0 validator.errors = 0 save_ignore_compatibles = check_init_priorities._IGNORE_COMPATIBLES @@ -374,7 +383,6 @@ def test_check_ignored(self, mock_vinit): self.assertListEqual(validator.log.info.call_args_list, [ mock.call("Ignoring priority: compat-3"), ]) - self.assertEqual(validator.warnings, 0) self.assertEqual(validator.errors, 0) check_init_priorities._IGNORE_COMPATIBLES = save_ignore_compatibles diff --git a/tests/misc/check_init_priorities/boards/native_posix.overlay b/tests/misc/check_init_priorities/boards/native_posix.overlay index d279a6d3f26..0f32c8121a8 100644 --- a/tests/misc/check_init_priorities/boards/native_posix.overlay +++ b/tests/misc/check_init_priorities/boards/native_posix.overlay @@ -34,12 +34,5 @@ reg = <0x11>; supply-gpios = <&test_gpio_0 2 0>; }; - - test_dev_c: test-i2c-dev@12 { - compatible = "vnd,i2c-device"; - status = "okay"; - reg = <0x12>; - supply-gpios = <&test_gpio_0 3 0>; - }; }; }; diff --git a/tests/misc/check_init_priorities/src/main.c b/tests/misc/check_init_priorities/src/main.c index a0d9e625a01..a9cf1c472cc 100644 --- a/tests/misc/check_init_priorities/src/main.c +++ b/tests/misc/check_init_priorities/src/main.c @@ -6,19 +6,12 @@ #include -static int device_init(const struct device *dev) -{ - return 0; -} - -DEVICE_DT_DEFINE(DT_INST(0, vnd_gpio_device), device_init, NULL, NULL, NULL, +DEVICE_DT_DEFINE(DT_INST(0, vnd_gpio_device), NULL, NULL, NULL, NULL, PRE_KERNEL_1, 50, NULL); -DEVICE_DT_DEFINE(DT_INST(0, vnd_i2c), device_init, NULL, NULL, NULL, +DEVICE_DT_DEFINE(DT_INST(0, vnd_i2c), NULL, NULL, NULL, NULL, PRE_KERNEL_1, 50, NULL); -DEVICE_DT_DEFINE(DT_INST(0, vnd_i2c_device), device_init, NULL, NULL, NULL, +DEVICE_DT_DEFINE(DT_INST(0, vnd_i2c_device), NULL, NULL, NULL, NULL, PRE_KERNEL_1, 49, NULL); -DEVICE_DT_DEFINE(DT_INST(1, vnd_i2c_device), device_init, NULL, NULL, NULL, +DEVICE_DT_DEFINE(DT_INST(1, vnd_i2c_device), NULL, NULL, NULL, NULL, PRE_KERNEL_1, 50, NULL); -DEVICE_DT_DEFINE(DT_INST(2, vnd_i2c_device), device_init, NULL, NULL, NULL, - PRE_KERNEL_1, 51, NULL); diff --git a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py index 84d5335372f..eec705d251b 100755 --- a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py +++ b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py @@ -12,8 +12,6 @@ "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /i2c@11112222 PRE_KERNEL_1 2", "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /gpio@ffff PRE_KERNEL_1 1", "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /i2c@11112222 PRE_KERNEL_1 2", - "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 4 > /gpio@ffff PRE_KERNEL_1 1", - "INFO: /i2c@11112222/test-i2c-dev@12 PRE_KERNEL_1 4 > /i2c@11112222 PRE_KERNEL_1 2", ] if len(sys.argv) != 2: From dd178ce3116b6dce5cbac4ed721613adc721c6b4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 27 Oct 2023 10:47:37 +0000 Subject: [PATCH 2991/4498] scripts: check_init_priorities: rework the error messages The current error messages are a bit cryptic, rework them to make them more meaningful: - add an extra message on the first error to explain what the errors refer to. - rework the error message to be more explicit. - rework the priority string print to use a LEVEL+offset format to somehow highlight that the number is the offset from the level, not the actual priority. - print the init function name in addition to the devicetree path. Signed-off-by: Fabio Baltieri --- scripts/build/check_init_priorities.py | 18 +++++++++----- scripts/build/check_init_priorities_test.py | 24 ++++++++++--------- .../validate_check_init_priorities_output.py | 9 +++---- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 22a27f24ef9..ba6f476fba5 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -77,7 +77,7 @@ def __repr__(self): _DEVICE_INIT_LEVELS[self._level], self._priority) def __str__(self): - return "%s %d" % (_DEVICE_INIT_LEVELS[self._level], self._priority) + return "%s+%d" % (_DEVICE_INIT_LEVELS[self._level], self._priority) def __lt__(self, other): return self._level_priority < other._level_priority @@ -214,7 +214,7 @@ def _process_initlevels(self): ordinal = self._device_ord_from_name(arg1_name) if ordinal: prio = Priority(level, priority) - self.devices[ordinal] = prio + self.devices[ordinal] = (prio, arg0_name) addr += size priority += 1 @@ -267,8 +267,8 @@ def _check_dep(self, dev_ord, dep_ord): self.log.info(f"Swapped priority: {dev_compat}, {dep_compat}") dev_ord, dep_ord = dep_ord, dev_ord - dev_prio = self._obj.devices.get(dev_ord, None) - dep_prio = self._obj.devices.get(dep_ord, None) + dev_prio, dev_init = self._obj.devices.get(dev_ord, (None, None)) + dep_prio, dep_init = self._obj.devices.get(dep_ord, (None, None)) if not dev_prio or not dep_prio: return @@ -277,12 +277,18 @@ def _check_dep(self, dev_ord, dep_ord): raise ValueError(f"{dev_node.path} and {dep_node.path} have the " f"same priority: {dev_prio}") elif dev_prio < dep_prio: + if not self.errors: + self.log.error("Device initialization priority validation failed, " + "the sequence of initialization calls does not match " + "the devicetree dependencies.") self.errors += 1 self.log.error( - f"{dev_node.path} {dev_prio} < {dep_node.path} {dep_prio}") + f"{dev_node.path} <{dev_init}> is initialized before its dependency " + f"{dep_node.path} <{dep_init}> ({dev_prio} < {dep_prio})") else: self.log.info( - f"{dev_node.path} {dev_prio} > {dep_node.path} {dep_prio}") + f"{dev_node.path} <{dev_init}> {dev_prio} > " + f"{dep_node.path} <{dep_init}> {dep_prio}") def check_edt(self): """Scan through all known devices and validate the init priorities.""" diff --git a/scripts/build/check_init_priorities_test.py b/scripts/build/check_init_priorities_test.py index 36d362a63cc..c7b2aabb25f 100755 --- a/scripts/build/check_init_priorities_test.py +++ b/scripts/build/check_init_priorities_test.py @@ -49,7 +49,7 @@ def test_priority_levels(self): def test_priority_strings(self): prio = check_init_priorities.Priority("POST_KERNEL", 12) - self.assertEqual(str(prio), "POST_KERNEL 12") + self.assertEqual(str(prio), "POST_KERNEL+12") self.assertEqual(repr(prio), "") class testZephyrInitLevels(unittest.TestCase): @@ -236,8 +236,8 @@ def mock_obj_name(*args): "SMP": [], }) self.assertDictEqual(obj.devices, { - 11: check_init_priorities.Priority("PRE_KERNEL_2", 0), - 22: check_init_priorities.Priority("PRE_KERNEL_2", 1), + 11: (check_init_priorities.Priority("PRE_KERNEL_2", 0), "i0"), + 22: (check_init_priorities.Priority("PRE_KERNEL_2", 1), "i1"), }) class testValidator(unittest.TestCase): @@ -280,10 +280,10 @@ def test_check_dep_no_prio(self, mock_vinit): validator._ord2node[1]._binding = None validator._ord2node[2]._binding = None - validator._obj.devices = {1: 10} + validator._obj.devices = {1: (10, "i1")} validator._check_dep(1, 2) - validator._obj.devices = {2: 20} + validator._obj.devices = {2: (20, "i2")} validator._check_dep(1, 2) self.assertFalse(validator.log.info.called) @@ -303,13 +303,15 @@ def test_check(self, mock_vinit): validator._ord2node[2]._binding = None validator._ord2node[2].path = "/2" - validator._obj.devices = {1: 10, 2: 20} + validator._obj.devices = {1: (10, "i1"), 2: (20, "i2")} validator._check_dep(2, 1) validator._check_dep(1, 2) - validator.log.info.assert_called_once_with("/2 20 > /1 10") - validator.log.error.assert_called_once_with("/1 10 < /2 20") + validator.log.info.assert_called_once_with("/2 20 > /1 10") + validator.log.error.assert_has_calls([ + mock.call("/1 is initialized before its dependency /2 (10 < 20)") + ]) self.assertEqual(validator.errors, 1) @mock.patch("check_init_priorities.Validator.__init__", return_value=None) @@ -325,7 +327,7 @@ def test_check_same_prio_assert(self, mock_vinit): validator._ord2node[2]._binding = None validator._ord2node[2].path = "/2" - validator._obj.devices = {1: 10, 2: 10} + validator._obj.devices = {1: (10, "i1"), 2: (10, "i2")} with self.assertRaises(ValueError): validator._check_dep(1, 2) @@ -347,13 +349,13 @@ def test_check_swapped(self, mock_vinit): validator._ord2node[3]._binding.compatible = "compat-3" validator._ord2node[3].path = "/3" - validator._obj.devices = {1: 20, 3: 10} + validator._obj.devices = {1: (20, "i1"), 3: (10, "i3")} validator._check_dep(3, 1) self.assertListEqual(validator.log.info.call_args_list, [ mock.call("Swapped priority: compat-3, compat-1"), - mock.call("/3 20 > /1 10"), + mock.call("/3 20 > /1 10"), ]) self.assertEqual(validator.errors, 0) diff --git a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py index eec705d251b..714976e1a09 100755 --- a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py +++ b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py @@ -8,10 +8,11 @@ import sys REFERENCE_OUTPUT = [ - "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /gpio@ffff PRE_KERNEL_1 1", - "ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /i2c@11112222 PRE_KERNEL_1 2", - "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /gpio@ffff PRE_KERNEL_1 1", - "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /i2c@11112222 PRE_KERNEL_1 2", + "ERROR: Device initialization priority validation failed, the sequence of initialization calls does not match the devicetree dependencies.", + "ERROR: /i2c@11112222/test-i2c-dev@10 is initialized before its dependency /gpio@ffff (PRE_KERNEL_1+0 < PRE_KERNEL_1+1)", + "ERROR: /i2c@11112222/test-i2c-dev@10 is initialized before its dependency /i2c@11112222 (PRE_KERNEL_1+0 < PRE_KERNEL_1+2)", + "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1+3 > /gpio@ffff PRE_KERNEL_1+1", + "INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1+3 > /i2c@11112222 PRE_KERNEL_1+2", ] if len(sys.argv) != 2: From 1bd2a4f0496eebb7abf969de9113a08809bf8abd Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Thu, 26 Oct 2023 17:23:34 +0200 Subject: [PATCH 2992/4498] drivers: bluetooth: hci: Replace printk with LOG_HEXDUMP_DBG Use LOG_HEXDUMP_DBG for SPI message logging instead of printk. Signed-off-by: Ali Hozhabri --- drivers/bluetooth/hci/spi.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 18a5ae10d5f..6200d00ac6f 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -84,30 +84,6 @@ static K_SEM_DEFINE(sem_busy, 1, 1); static K_KERNEL_STACK_DEFINE(spi_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE); static struct k_thread spi_rx_thread_data; -#if defined(CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG) -#include -static inline void spi_dump_message(const uint8_t *pre, uint8_t *buf, - uint8_t size) -{ - uint8_t i, c; - - printk("%s (%d): ", pre, size); - for (i = 0U; i < size; i++) { - c = buf[i]; - printk("%x ", c); - if (c >= 31U && c <= 126U) { - printk("[%c] ", c); - } else { - printk("[.] "); - } - } - printk("\n"); -} -#else -static inline -void spi_dump_message(const uint8_t *pre, uint8_t *buf, uint8_t size) {} -#endif - #if defined(CONFIG_BT_SPI_BLUENRG) /* Define a limit when reading IRQ high */ /* It can be required to be increased for */ @@ -404,7 +380,7 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3) continue; } - spi_dump_message("RX:ed", rxmsg, size); + LOG_HEXDUMP_DBG(rxmsg, size, "SPI RX"); /* Construct net_buf from SPI data */ buf = bt_spi_rx_buf_construct(rxmsg); @@ -480,7 +456,7 @@ static int bt_spi_send(struct net_buf *buf) goto out; } - spi_dump_message("TX:ed", buf->data, buf->len); + LOG_HEXDUMP_DBG(buf->data, buf->len, "SPI TX"); #if defined(CONFIG_BT_SPI_BLUENRG) /* From 8265213d8b8f96c2806cd08d1559f0b501a0405b Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Fri, 27 Oct 2023 08:36:45 +0200 Subject: [PATCH 2993/4498] drivers: bluetooth: hci: Omit configure_cs Remove redundant configure_cs as it is performed by SPI initialization. Signed-off-by: Ali Hozhabri --- drivers/bluetooth/hci/spi.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 6200d00ac6f..cf5bd8c6865 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -184,12 +184,6 @@ static bool bt_spi_handle_vendor_evt(uint8_t *msg) * know the amount of byte to read. * (See section 5.2 of BlueNRG-MS datasheet) */ -static int configure_cs(void) -{ - /* Configure pin as output and set to inactive */ - return gpio_pin_configure_dt(&bus.config.cs.gpio, GPIO_OUTPUT_INACTIVE); -} - static void kick_cs(void) { gpio_pin_set_dt(&bus.config.cs.gpio, 0); @@ -229,7 +223,6 @@ static bool exit_irq_high_loop(void) #else -#define configure_cs(...) 0 #define kick_cs(...) #define release_cs(...) #define irq_pin_high(...) 0 @@ -536,10 +529,6 @@ static int bt_spi_init(void) return -ENODEV; } - if (configure_cs()) { - return -EIO; - } - if (!gpio_is_ready_dt(&irq_gpio)) { LOG_ERR("IRQ GPIO device not ready"); return -ENODEV; From 7038e03695983f08973dfe6b471acee30f2ce044 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Fri, 27 Oct 2023 14:03:58 +0200 Subject: [PATCH 2994/4498] drivers: bluetooth: hci: SPI configuration Modify SPI configuration to match the features introduced in PR #63437. Set the property "controller-data-delay-us" to zero for boards which are using BlueNRG-MS. Fix Chip Select configuration for stm32l562e_dk board. Signed-off-by: Ali Hozhabri --- boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts | 2 ++ boards/arm/disco_l475_iot1/disco_l475_iot1.dts | 2 ++ boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi | 4 +++- boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay | 1 + drivers/bluetooth/hci/spi.c | 9 --------- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts index da66cb53ada..9f8900921f6 100644 --- a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts +++ b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts @@ -157,6 +157,8 @@ reset-gpios = <&gpioa 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; irq-gpios = <&gpioe 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; spi-max-frequency = <2000000>; + controller-data-delay-us = <0>; /* No need for extra delay for BlueNRG-MS */ + spi-hold-cs; }; wifi0: ism43362@1 { diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts index 8505b05656f..a37b801b3e4 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts @@ -196,6 +196,8 @@ reset-gpios = <&gpioa 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; irq-gpios = <&gpioe 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; spi-max-frequency = <2000000>; + controller-data-delay-us = <0>; /* No need for extra delay for BlueNRG-MS */ + spi-hold-cs; }; wifi0: ism43362@1 { diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi index 14f11ece9a9..5bb8c567ee6 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -111,7 +111,7 @@ &spi1 { pinctrl-0 = <&spi1_sck_pg2 &spi1_miso_pg3 &spi1_mosi_pg4>; pinctrl-names = "default"; - cs-gpios = <&gpiog 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + cs-gpios = <&gpiog 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "okay"; spbtle-rf@0 { @@ -120,6 +120,8 @@ irq-gpios = <&gpiog 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; reset-gpios = <&gpiog 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; spi-max-frequency = <2000000>; + controller-data-delay-us = <0>; /* No need for extra delay for BlueNRG-MS */ + spi-hold-cs; }; }; diff --git a/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay b/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay index a6a789c53c1..8ccf3d7dbf0 100644 --- a/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay +++ b/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay @@ -14,5 +14,6 @@ irq-gpios = <&arduino_header 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; /* A0 */ spi-max-frequency = <2000000>; controller-data-delay-us = <0>; /* No need for extra delay for BlueNRG-MS */ + spi-hold-cs; }; }; diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index cf5bd8c6865..6127bfba133 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -105,17 +105,8 @@ struct bluenrg_aci_cmd_ll_param { static int bt_spi_send_aci_config_data_controller_mode(void); #endif /* CONFIG_BT_BLUENRG_ACI */ -#if defined(CONFIG_BT_SPI_BLUENRG) -/* In case of BlueNRG-MS, it is necessary to prevent SPI driver to release CS, - * and instead, let current driver manage CS release. see kick_cs()/release_cs() - * So, add SPI_HOLD_ON_CS to operation field. - */ -static const struct spi_dt_spec bus = SPI_DT_SPEC_INST_GET( - 0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_HOLD_ON_CS, 0); -#else static const struct spi_dt_spec bus = SPI_DT_SPEC_INST_GET( 0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0); -#endif static struct spi_buf spi_tx_buf; static struct spi_buf spi_rx_buf; From 0584321ba22c3c227e8728ef8f967c35ae08c4c1 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Fri, 27 Oct 2023 14:10:48 +0200 Subject: [PATCH 2995/4498] samples: bluetooth: hci_usb: Test exclusion for stm32l562e_dk STM32L562 Discovery kit is not compatible with Bluetooth over USB application. Add missing information related to the BLE capability of this board. Signed-off-by: Ali Hozhabri --- boards/arm/stm32l562e_dk/stm32l562e_dk.yaml | 1 + samples/bluetooth/hci_usb/sample.yaml | 2 +- samples/bluetooth/hci_usb_h4/sample.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml index dcb6a01d5db..dcbe7539d64 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml @@ -15,6 +15,7 @@ supported: - dac - adc - spi + - ble - dma - usart - arduino_spi diff --git a/samples/bluetooth/hci_usb/sample.yaml b/samples/bluetooth/hci_usb/sample.yaml index 4b998f95bb6..9848aed2430 100644 --- a/samples/bluetooth/hci_usb/sample.yaml +++ b/samples/bluetooth/hci_usb/sample.yaml @@ -10,7 +10,7 @@ tests: - usb - bluetooth # FIXME: exclude due to build error - platform_exclude: 96b_carbon + platform_exclude: 96b_carbon stm32l562e_dk sample.bluetooth.hci_usb.device_next: harness: bluetooth depends_on: diff --git a/samples/bluetooth/hci_usb_h4/sample.yaml b/samples/bluetooth/hci_usb_h4/sample.yaml index b09b30185a3..afc6e2429cb 100644 --- a/samples/bluetooth/hci_usb_h4/sample.yaml +++ b/samples/bluetooth/hci_usb_h4/sample.yaml @@ -10,4 +10,4 @@ tests: - usb - bluetooth # FIXME: exclude due to build error - platform_exclude: 96b_carbon + platform_exclude: 96b_carbon stm32l562e_dk From 396e1ce9b0a96a4b29fbd856f44cbcdd62904876 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Fri, 27 Oct 2023 14:17:34 +0200 Subject: [PATCH 2996/4498] drivers: bluetooth: hci: Use macros instead of hard-coding Replace hard-coded values with suitable macros. Signed-off-by: Ali Hozhabri --- drivers/bluetooth/hci/spi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 6127bfba133..42475a5e198 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -41,6 +41,7 @@ LOG_MODULE_REGISTER(bt_driver); #define EVT_HEADER_TYPE 0 #define EVT_HEADER_EVENT 1 #define EVT_HEADER_SIZE 2 +#define EVT_LE_META_SUBEVENT 3 #define EVT_VENDOR_CODE_LSB 3 #define EVT_VENDOR_CODE_MSB 4 @@ -264,8 +265,8 @@ static struct net_buf *bt_spi_rx_buf_construct(uint8_t *msg) /* Event has not yet been handled */ __fallthrough; default: - if (msg[1] == BT_HCI_EVT_LE_META_EVENT && - (msg[3] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { + if (msg[EVT_HEADER_EVENT] == BT_HCI_EVT_LE_META_EVENT && + (msg[EVT_LE_META_SUBEVENT] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { discardable = true; timeout = K_NO_WAIT; } From b2353725464d4ca0f71041fa7d76b716dd29862c Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Wed, 18 Oct 2023 10:11:20 -0400 Subject: [PATCH 2997/4498] samples: fs: littlefs: add sample on stm32h747i-disco board This adds the required conf and dts overlays required for the application on stm32h747i-disco board. Also moved CONFIG_SDMMC_STM32_HWFC option from prj_blk.conf to nucleo_h743zi_blk.conf as that is STM specific option. Build the application as west build -p always -b stm32h747i_disco_m7 \ samples/subsys/fs/littlefs/ -- \ -DOVERLAY_CONFIG=boards/stm32h747i_disco_m7.conf -DCONF_FILE=prj_blk.conf Signed-off-by: Murali Karicheri --- .../stm32h747i_disco/stm32h747i_disco_m7.dts | 14 +++++++ .../fs/littlefs/boards/nucleo_h743zi_blk.conf | 1 + .../littlefs/boards/stm32h747i_disco_m7.conf | 3 ++ .../boards/stm32h747i_disco_m7.overlay | 38 +++++++++++++++++++ samples/subsys/fs/littlefs/prj_blk.conf | 1 - samples/subsys/fs/littlefs/sample.yaml | 6 +++ 6 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.conf create mode 100644 samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts index 8f6f519186d..514047c8a55 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts @@ -78,6 +78,16 @@ status = "okay"; }; +&pll2 { + div-m = <5>; + mul-n = <96>; + div-p = <2>; + div-q = <4>; + div-r = <10>; + clocks = <&clk_hse>; /* Assuming 25MHz HSE */ + status = "okay"; +}; + &rcc { clocks = <&pll>; clock-frequency = ; @@ -202,8 +212,12 @@ zephyr_udc0: &usbotg_hs { &sdmmc1 { status = "okay"; + clocks = <&rcc STM32_CLOCK_BUS_AHB3 0x00010000>, + <&rcc STM32_SRC_PLL2_R SDMMC_SEL(1)>; pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_d4_pb8 &sdmmc1_d5_pb9 + &sdmmc1_d6_pc6 &sdmmc1_d7_pc7 &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; pinctrl-names = "default"; cd-gpios = <&gpioi 8 GPIO_ACTIVE_LOW>; diff --git a/samples/subsys/fs/littlefs/boards/nucleo_h743zi_blk.conf b/samples/subsys/fs/littlefs/boards/nucleo_h743zi_blk.conf index eeabf1150b0..a5663cf11a2 100644 --- a/samples/subsys/fs/littlefs/boards/nucleo_h743zi_blk.conf +++ b/samples/subsys/fs/littlefs/boards/nucleo_h743zi_blk.conf @@ -7,3 +7,4 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 +CONFIG_SDMMC_STM32_HWFC=y diff --git a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.conf b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.conf new file mode 100644 index 00000000000..a45f607811f --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.conf @@ -0,0 +1,3 @@ +CONFIG_SDMMC_STM32_HWFC=y +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay new file mode 100644 index 00000000000..bc2b79ea7a7 --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 S&C Electric Company + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &storage_partition; + +/ { + fstab { + compatible = "zephyr,fstab"; + lfs1: lfs1 { + compatible = "zephyr,fstab,littlefs"; + read-size = <512>; + prog-size = <512>; + cache-size = <512>; + lookahead-size = <4096>; + block-cycles = <512>; + partition = <&storage_partition>; + mount-point = "/lfsemmc"; + }; + }; +}; + +&sdmmc1 { + sdmmc { + compatible = "zephyr,sdmmc-disk"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + storage_partition: partition@0 { + label = "storage"; + reg = <0x0 DT_SIZE_M(2048)>; + }; + }; + }; +}; diff --git a/samples/subsys/fs/littlefs/prj_blk.conf b/samples/subsys/fs/littlefs/prj_blk.conf index 7df323b59f3..011f919a568 100644 --- a/samples/subsys/fs/littlefs/prj_blk.conf +++ b/samples/subsys/fs/littlefs/prj_blk.conf @@ -19,4 +19,3 @@ CONFIG_FS_LITTLEFS_BLK_DEV=y CONFIG_APP_LITTLEFS_STORAGE_BLK_SDMMC=y CONFIG_NOCACHE_MEMORY=y -CONFIG_SDMMC_STM32_HWFC=y diff --git a/samples/subsys/fs/littlefs/sample.yaml b/samples/subsys/fs/littlefs/sample.yaml index d22cfbbd235..6ffbc14d35f 100644 --- a/samples/subsys/fs/littlefs/sample.yaml +++ b/samples/subsys/fs/littlefs/sample.yaml @@ -33,3 +33,9 @@ tests: extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_nrf52840_qspi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840_qspi.overlay + sample.filesystem.littlefs.stm32h747i_disco_m7_sdmmc: + build_only: true + platform_allow: stm32h747i_disco_m7 + extra_args: + - OVERLAY_CONFIG=boards/stm32h747i_disco_m7.conf + - CONF_FILE=prj_blk.conf From 724c162821bf70424e76c83630f41dce2105f0eb Mon Sep 17 00:00:00 2001 From: David Corbeil Date: Wed, 27 Sep 2023 13:28:39 -0400 Subject: [PATCH 2998/4498] shell: backends: telnet: Added support for echo option Adding support for echo option if telnet commands are supported. This is useful when the telnet client is in character mode. It allows to use the arrow keys, ctrl-c and more. Something to keep in mind is that when character mode is turned on by the client, network traffic is considerably increased as each typed character is sent over the wire. Note: echo mode is only supported if SHELL_TELNET_SUPPORT_COMMAND is enabled. Signed-off-by: David Corbeil --- doc/services/shell/index.rst | 26 +++++++++++++ subsys/shell/backends/Kconfig.backends | 6 ++- subsys/shell/backends/shell_telnet.c | 52 ++++++++++++++++++++++---- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index b9c88822cd3..7f8f6f0fd57 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -75,6 +75,29 @@ procedure: to the shell. +Telnet Backend +============== + +Enabling :kconfig:option:`CONFIG_SHELL_BACKEND_TELNET` will allow users to use telnet +as a shell backend. Connecting to it can be done using PuTTY or any ``telnet`` client. +For example: + +.. code-block:: none + + telnet + +By default the telnet client won't handle telnet commands and configuration. Although +command support can be enabled with :kconfig:option:`CONFIG_SHELL_TELNET_SUPPORT_COMMAND`. +This will give the telnet client access to a very limited set of supported commands but +still can be turned on if needed. One of the command options it supports is the ``ECHO`` +option. This will allow the client to be in character mode (character at a time), +similar to a UART backend in that regard. This will make the client send a character +as soon as it is typed having the effect of increasing the network traffic +considerably. For that cost, it will enable the line editing, +`tab completion `_, and `history `_ +features of the shell. + + Commands ******** @@ -428,6 +451,7 @@ These commands are activated by :kconfig:option:`CONFIG_SHELL_CMDS` set to ``y`` case of Bluetooth shell to limit the amount of transferred bytes. * :command:`stats` - Shows shell statistics. +.. _tab-feature: Tab Feature *********** @@ -448,6 +472,8 @@ the shell will do one of 3 possible things: :align: center :alt: Tab Feature usage example +.. _history-feature: + History Feature *************** diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index 44d27a812b5..1d30bee2305 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -345,7 +345,11 @@ config SHELL_TELNET_SUPPORT_COMMAND help Current support is so limited it's not interesting to enable it. However, if proven to be needed at some point, it will be possible - to extend such support. + to extend such support. It does have support for echo and "character + at a time" mode, which enable the history and line-editing features + of the shell. + IMPORTANT: This will increase network usage as a TCP packet will be + sent each time a character is typed in the telnet client. module = SHELL_TELNET default-timeout = 100 diff --git a/subsys/shell/backends/shell_telnet.c b/subsys/shell/backends/shell_telnet.c index 312c1dcb4e1..8aded7e022c 100644 --- a/subsys/shell/backends/shell_telnet.c +++ b/subsys/shell/backends/shell_telnet.c @@ -85,12 +85,52 @@ static void telnet_reply_ay_command(void) telnet_command_send_reply((uint8_t *)alive, strlen(alive)); } +static int telnet_echo_set(const struct shell *sh, bool val) +{ + int ret = shell_echo_set(sh_telnet->shell_context, val); + + if (ret < 0) { + LOG_ERR("Failed to set echo to: %d, err: %d", val, ret); + } + return ret; +} + +static void telnet_reply_dont_command(struct telnet_simple_command *cmd) +{ + switch (cmd->opt) { + case NVT_OPT_ECHO: + int ret = telnet_echo_set(sh_telnet->shell_context, false); + + if (ret >= 0) { + cmd->op = NVT_CMD_WONT; + } else { + cmd->op = NVT_CMD_WILL; + } + break; + default: + cmd->op = NVT_CMD_WONT; + break; + } + + telnet_command_send_reply((uint8_t *)cmd, + sizeof(struct telnet_simple_command)); +} + static void telnet_reply_do_command(struct telnet_simple_command *cmd) { switch (cmd->opt) { case NVT_OPT_SUPR_GA: cmd->op = NVT_CMD_WILL; break; + case NVT_OPT_ECHO: + int ret = telnet_echo_set(sh_telnet->shell_context, true); + + if (ret >= 0) { + cmd->op = NVT_CMD_WILL; + } else { + cmd->op = NVT_CMD_WONT; + } + break; default: cmd->op = NVT_CMD_WONT; break; @@ -120,6 +160,9 @@ static void telnet_reply_command(struct telnet_simple_command *cmd) case NVT_CMD_DO: telnet_reply_do_command(cmd); break; + case NVT_CMD_DONT: + telnet_reply_dont_command(cmd); + break; default: LOG_DBG("Operation %u not handled", cmd->op); break; @@ -250,8 +293,6 @@ static void telnet_accept(struct net_context *client, int error, void *user_data) { - int ret; - if (error) { LOG_ERR("Error %d", error); goto error; @@ -275,13 +316,10 @@ static void telnet_accept(struct net_context *client, sh_telnet->client_ctx = client; - /* Disable echo - if command handling is enabled we reply that we don't + /* Disable echo - if command handling is enabled we reply that we * support echo. */ - ret = shell_echo_set(sh_telnet->shell_context, false); - if (ret < 0) { - LOG_ERR("Failed to disable echo, err: %d", ret); - } + (void)telnet_echo_set(sh_telnet->shell_context, false); return; error: From cf38e76cf99b838dfa6c475586dde5273f89aa3a Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Mon, 16 Oct 2023 16:17:24 +0200 Subject: [PATCH 2999/4498] boards: arm: Add support for SensorTile.box board Add basic support for SensorTile.box Pro (STEVAL-MKBOXPRO). (https://www.st.com/en/evaluation-tools/steval-mkboxpro.html) Signed-off-by: Armando Visconti --- boards/arm/sensortile_box_pro/CMakeLists.txt | 10 + boards/arm/sensortile_box_pro/Kconfig.board | 8 + .../arm/sensortile_box_pro/Kconfig.defconfig | 24 ++ boards/arm/sensortile_box_pro/board.c | 32 ++ boards/arm/sensortile_box_pro/board.cmake | 5 + .../doc/img/sensortile_box_pro.jpg | Bin 0 -> 26646 bytes boards/arm/sensortile_box_pro/doc/index.rst | 381 ++++++++++++++++++ .../sensortile_box_pro/sensortile_box_pro.dts | 338 ++++++++++++++++ .../sensortile_box_pro.yaml | 19 + .../sensortile_box_pro_defconfig | 37 ++ .../sensortile_box_pro/support/openocd.cfg | 44 ++ 11 files changed, 898 insertions(+) create mode 100644 boards/arm/sensortile_box_pro/CMakeLists.txt create mode 100644 boards/arm/sensortile_box_pro/Kconfig.board create mode 100644 boards/arm/sensortile_box_pro/Kconfig.defconfig create mode 100644 boards/arm/sensortile_box_pro/board.c create mode 100644 boards/arm/sensortile_box_pro/board.cmake create mode 100644 boards/arm/sensortile_box_pro/doc/img/sensortile_box_pro.jpg create mode 100644 boards/arm/sensortile_box_pro/doc/index.rst create mode 100644 boards/arm/sensortile_box_pro/sensortile_box_pro.dts create mode 100644 boards/arm/sensortile_box_pro/sensortile_box_pro.yaml create mode 100644 boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig create mode 100644 boards/arm/sensortile_box_pro/support/openocd.cfg diff --git a/boards/arm/sensortile_box_pro/CMakeLists.txt b/boards/arm/sensortile_box_pro/CMakeLists.txt new file mode 100644 index 00000000000..4489ff54489 --- /dev/null +++ b/boards/arm/sensortile_box_pro/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Define the toolchain to be used (by eg CI) +if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr") + set(COMPILER_FULL_PATH ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc) +elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "gnuarmemb") + set(COMPILER_FULL_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc) +endif() + +zephyr_library_sources(board.c) diff --git a/boards/arm/sensortile_box_pro/Kconfig.board b/boards/arm/sensortile_box_pro/Kconfig.board new file mode 100644 index 00000000000..14429705999 --- /dev/null +++ b/boards/arm/sensortile_box_pro/Kconfig.board @@ -0,0 +1,8 @@ +# SENSORTILE_BOX_PRO board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SENSORTILE_BOX_PRO + bool "SENSORTILE_BOX_PRO Board" + depends on SOC_STM32U585XX diff --git a/boards/arm/sensortile_box_pro/Kconfig.defconfig b/boards/arm/sensortile_box_pro/Kconfig.defconfig new file mode 100644 index 00000000000..e37f5e4f5bf --- /dev/null +++ b/boards/arm/sensortile_box_pro/Kconfig.defconfig @@ -0,0 +1,24 @@ +# SENSORTILE_BOX_PRO board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SENSORTILE_BOX_PRO + +config BOARD + default "sensortile_box_pro" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +if LOG + +# Logger cannot use itself to log +choice USB_CDC_ACM_LOG_LEVEL_CHOICE + default USB_CDC_ACM_LOG_LEVEL_OFF +endchoice + +endif # LOG + +endif # BOARD_SENSORTILE_BOX_PRO diff --git a/boards/arm/sensortile_box_pro/board.c b/boards/arm/sensortile_box_pro/board.c new file mode 100644 index 00000000000..db3de065f2b --- /dev/null +++ b/boards/arm/sensortile_box_pro/board.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_DEVICE_STACK +/* + * Enable console on USB CDC_ACM + */ +static int sensortile_box_pro_usb_console_init(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); + + if (!device_is_ready(dev) || usb_enable(NULL)) { + return -1; + } + + return 0; +} + +/* needs to be done at Application */ +SYS_INIT(sensortile_box_pro_usb_console_init, APPLICATION, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#endif diff --git a/boards/arm/sensortile_box_pro/board.cmake b/boards/arm/sensortile_box_pro/board.cmake new file mode 100644 index 00000000000..370c5454429 --- /dev/null +++ b/boards/arm/sensortile_box_pro/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/arm/sensortile_box_pro/doc/img/sensortile_box_pro.jpg b/boards/arm/sensortile_box_pro/doc/img/sensortile_box_pro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2865d8c576b3d5d6016ac167f375b11a4bdbe062 GIT binary patch literal 26646 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 D%rZd; literal 0 HcmV?d00001 diff --git a/boards/arm/sensortile_box_pro/doc/index.rst b/boards/arm/sensortile_box_pro/doc/index.rst new file mode 100644 index 00000000000..c5f8eed3a37 --- /dev/null +++ b/boards/arm/sensortile_box_pro/doc/index.rst @@ -0,0 +1,381 @@ +.. _sensortile_box_pro_board: + +ST SensorTile.box PRO +##################### + +Overview +******** + +The STEVAL-MKBOXPRO (SensorTile.box PRO) features an ARM Cortex-M33 based STM32U585AI MCU +and is a ready-to-use box kit for wireless IoT and wearable sensor platforms to help using +and developing apps based on remote motion and environmental sensor data. + +The SensorTile.box PRO board fits into a small plastic box with a long-life rechargeable +battery, and communicates with a standard smartphone through its Bluetooth interface, +providing data coming from the sensors. + +.. image:: img/sensortile_box_pro.jpg + :align: center + :alt: SensorTile.box PRO + +More information about the board can be found at the `SensorTile.box PRO website`_. + +Supported Features +****************** + +The SensorTile.box PRO provides motion, environmental, and audio +sensor data through either the BLE or USB protocols to a host application running +on a smartphone/PC to implement applications such as: + +- Pedometer optimized for belt positioning +- Baby crying detection with Cloud AI learning +- Barometer / environmental monitoring +- Vehicle / goods tracking +- Vibration monitoring +- Compass and inclinometer +- Sensor data logger + +(see `Motion and environmental sensors`_ section for the complete lists of available +sensors on board) + +Hardware +******** + +The STM32U585xx devices are an ultra-low-power microcontrollers family (STM32U5 +Series) based on the high-performance Arm|reg| Cortex|reg|-M33 32-bit RISC core. +They operate at a frequency of up to 160 MHz. + +- Ultra-low-power with FlexPowerControl (down to 300 nA Standby mode and 19.5 uA/MHz run mode) +- Core: ARM |reg| 32-bit Cortex |reg| -M33 CPU with TrustZone |reg| and FPU. +- Performance benchmark: + + - 1.5 DMPIS/MHz (Drystone 2.1) + - 651 CoreMark |reg| (4.07 CoreMark |reg| /MHZ) + +- Security and cryptography + + - Arm |reg| TrustZone |reg| and securable I/Os memories and peripherals + - Flexible life cycle scheme with RDP (readout protection) and password protected debug + - Root of trust thanks to unique boot entry and secure hide protection area (HDP) + - Secure Firmware Installation thanks to embedded Root Secure Services + - Secure data storage with hardware unique key (HUK) + - Secure Firmware Update support with TF-M + - 2 AES coprocessors including one with DPA resistance + - Public key accelerator, DPA resistant + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - Active tampers + - True Random Number Generator NIST SP800-90B compliant + - 96-bit unique ID + - 512-byte One-Time Programmable for user data + - Active tampers + +- Clock management: + + - 4 to 50 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - 2 internal multispeed 100 kHz to 48 MHz oscillators, including one auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + - Internal 48 MHz with clock recovery + +- Power management + + - Embedded regulator (LDO) + - Embedded SMPS step-down converter supporting switch on-the-fly and voltage scaling + +- RTC with HW calendar and calibration +- Up to 136 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V +- Up to 24 capacitive sensing channels: support touchkey, linear and rotary touch sensors +- Up to 17 timers and 2 watchdogs + + - 2x 16-bit advanced motor-control + - 2x 32-bit and 5 x 16-bit general purpose + - 4x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - 2x SysTick timer + +- ART accelerator + + - 8-Kbyte instruction cache allowing 0-wait-state execution from Flash and + external memories: up to 160 MHz, MPU, 240 DMIPS and DSP + - 4-Kbyte data cache for external memories + +- Memories + + - 2-Mbyte Flash memory with ECC, 2 banks read-while-write, including 512 Kbytes with 100 kcycles + - 786-Kbyte SRAM with ECC OFF or 722-Kbyte SRAM including up to 322-Kbyte SRAM with ECC ON + - External memory interface supporting SRAM, PSRAM, NOR, NAND and FRAM memories + - 2 Octo-SPI memory interfaces + +- Rich analog peripherals (independent supply) + + - 14-bit ADC 2.5-Msps, resolution up to 16 bits with hardware oversampling + - 12-bit ADC 2.5-Msps, with hardware oversampling, autonomous in Stop 2 mode + - 12-bit DAC, low-power sample and hold + - 2 operational amplifiers with built-in PGA + - 2 ultra-low-power comparators + +- Up to 22 communication interfaces + + - USB Type-C / USB power delivery controller + - USB OTG 2.0 full-speed controller + - 2x SAIs (serial audio interface) + - 4x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (5x SPIs with dual OCTOSPI in SPI mode) + - 1x FDCAN + - 2x SDMMC interface + - 16- and 4-channel DMA controllers, functional in Stop mode + - 1 multi-function digital filter (6 filters)+ 1 audio digital filter with + sound-activity detection + +- CRC calculation unit +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| +- True Random Number Generator (RNG) + +- Graphic features + + - Chrom-ART Accelerator (DMA2D) for enhanced graphic content creation + - 1 digital camera interface + +- Mathematical co-processor + + - CORDIC for trigonometric functions acceleration + - FMAC (filter mathematical accelerator) + + +More information about STM32U585AI can be found here: + +- `STM32U585 on www.st.com`_ +- `STM32U585 reference manual`_ + +Motion and environmental sensors +================================ + + - **LSM6DSV16X** 6-axis inertial measurement unit + (`lsm6dsv16x datasheet`_) + - **LIS2MDL** 3-axis magnetometer + (`lis2mdl datasheet`_) + - **LIS2DU12** 3-axis accelerometer + (`lis2du12 datasheet`_) + - **HTS221** Humidity sensor + (`hts221 datasheet`_) + - **STTS22H** Digital temperature sensor + (`stts22hh datasheet`_) + - **MP23db01HP** Microphone / audio sensor + (`mp23db01hp datasheet`_) + +Connections and IOs +=================== + +- 4x user LEDs + + - **led0** (Green) + - **led1** (Red - shared with BLE) + - **led2** (Yellow) + - **led3** (Blue) + + +- 4x buttons/switch + + - **User BT1** button, available to user application + - **User BT2** / **boot0** button, available to user application + but useful to let the SensorTile.box PRO enter DFU mode + if found pressed after h/w reset (see **rst** button and + `Programming and Debugging`_ section) + - **rst** button, used to reset the board (not available on case) + - **power** switch, used to Power on/off the board + +System Clock +============ + +SensorTile.box PRO System Clock could be driven by internal or external +oscillator, as well as main PLL clock. By default, the System clock is +driven by the PLL clock at 80MHz, driven by the 16MHz external oscillator. +The system clock can be boosted to 120MHz. +The internal AHB/APB1/APB2 AMBA buses are all clocked at 80MHz. + +Serial Port +=========== + +The SensorTile.box PRO has 4 U(S)ARTs. The UART4 is connected to JTAG/SWD connector +and may be used as console. + +USB interface +============= + +SensorTile.box PRO can be connected as a USB device to a PC host through its USB-C connector. +The final application may use it to declare SensorTile.box PRO device as belonging to a +certain standard or vendor class, e.g. a CDC, a mass storage or a composite device with both +functions. + +Console +======= + +There are two possible options for Zephyr console output: + +- through UART4 which is available on SWD connector (JP2). In this case a JTAG adapter + can be used to connect SensorTile.box PRO and have both SWD and console lines available. + + To enable console and shell over UART + + - switch the console lines from cdc_acm to uart4 + (:file:`boards/arm/sensortile_box_pro/sensortile_box_pro.dts`) + + - comment out the USB configuration macros + (:file:`boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig`) + +.. code-block:: dts + :caption: boards/arm/sensortile_box_pro/sensortile_box_pro.dts + + / { + chosen { + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + //zephyr,console = &cdc_acm_uart0; + //zephyr,shell-uart = &cdc_acm_uart0; + }; + }; + +.. code-block:: Kconfig + :caption: boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig + + # Comment out following USB config lines when + # switching console to UART + #CONFIG_USB_DEVICE_STACK=y + #CONFIG_USB_DEVICE_VID=0x0483 + #CONFIG_USB_DEVICE_PID=0x1235 + #CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC SensorTile.box PRO" + #CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y + #CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n + + +- through USB as USB CDC/ACM class. This is the default case present in the board dts file. + +.. code-block:: dts + :caption: boards/arm/sensortile_box_pro/sensortile_box_pro.dts + + / { + chosen { + zephyr,console = &cdc_acm_uart0; + }; + }; + + &zephyr_udc0 { + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + }; + }; + + + +Console default settings are 115200 8N1. + +Programming and Debugging +************************* + +There are two alternative methods of flashing ST Sensortile.box Pro board: + +1. Using DFU software tools + + This method requires to enter STM32U585 ROM bootloader DFU mode + by powering up (or reset) the board while keeping the BOOT0 button pressed. + No additional hardware is required except a USB-C cable. This method is fully + supported by :ref:`flash-debug-host-tools`. + You can read more about how to enable and use the ROM bootloader by checking + the application note `AN2606`_ (STM32U585xx section). + +2. Using SWD hardware tools + + This method requires to connect additional hardware, like a ST-LINK/V3 + embedded debug tool, to the board SWD connector. + +DFU flashing +============ + +Install dfu-util +---------------- + +It is recommended to use at least v0.9 of dfu-util. The package available in +Debian and Ubuntu can be quite old, so you might have to build dfu-util from source. +Information about how to get the source code and how to build it can be found +at the `DFU-UTIL website`_ + +Flash an Application to SensorTile.box PRO +------------------------------------------ + +While pressing the BOOT0 button, connect the USB-C cable to the USB OTG SensorTile.box PRO +port and to your computer. The board should be forced to enter DFU mode. + +Check that the board is indeed in DFU mode: + +.. code-block:: console + + $ sudo dfu-util -l + dfu-util 0.9 + + Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. + Copyright 2010-2019 Tormod Volden and Stefan Schmidt + This program is Free Software and has ABSOLUTELY NO WARRANTY + Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ + + Found DFU: [0483:df11] ver=2200, devnum=74, cfg=1, intf=0, path="2-2", alt=2, name="@OTP Memory /0x1FFF7000/01*0001Ke", serial="204A325D574D" + Found DFU: [0483:df11] ver=2200, devnum=74, cfg=1, intf=0, path="2-2", alt=1, name="@Option Bytes /0x1FF00000/01*040 e/0x1FF01000/01*040 e", serial="204A325D574D" + Found DFU: [0483:df11] ver=2200, devnum=74, cfg=1, intf=0, path="2-2", alt=0, name="@Internal Flash /0x08000000/512*0004Kg", serial="204A325D574D" + +You should see following confirmation on your Linux host: + +.. code-block:: console + + $ dmesg + usb 2-2: new full-speed USB device number 74 using xhci_hcd + usb 2-2: New USB device found, idVendor=0483, idProduct=df11 + usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + usb 2-2: Product: STM32 BOOTLOADER + usb 2-2: Manufacturer: STMicroelectronics + usb 2-2: SerialNumber: 204A325D574D + +You can build and flash the provided sample application +(:ref:`sensortile_box_pro_sample_sensors`) that reads sensors data and outputs +values on the console. + +References +********** + +.. target-notes:: + +.. _SensorTile.box PRO website: + https://www.st.com/en/evaluation-tools/steval-mkboxpro.html + +.. _STM32U585 on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32u575-585.html + +.. _STM32U585 reference manual: + https://www.st.com/resource/en/reference_manual/rm0456-stm32u575585-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _lsm6dsv16x datasheet: + https://www.st.com/en/mems-and-sensors/lsm6dsv16x.html + +.. _lis2mdl datasheet: + https://www.st.com/en/mems-and-sensors/lis2mdl.html + +.. _lis2du12 datasheet: + https://www.st.com/en/mems-and-sensors/lis2du12.html + +.. _hts221 datasheet: + https://www.st.com/en/mems-and-sensors/hts221.html + +.. _stts22hh datasheet: + https://www.st.com/en/mems-and-sensors/stts22h.html + +.. _mp23db01hp datasheet: + https://www.st.com/en/mems-and-sensors/mp23db01hp.html + +.. _AN2606: + http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf + +.. _DFU-UTIL website: + http://dfu-util.sourceforge.net/ diff --git a/boards/arm/sensortile_box_pro/sensortile_box_pro.dts b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts new file mode 100644 index 00000000000..736ddaaedb4 --- /dev/null +++ b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "STMicroelectronics SENSORTILE-BOX-PRO board"; + compatible = "st,sensortile-box-pro"; + + chosen { + /* + * By default, Zephyr console and shell are assigned to + * USB CDC/ACM. To enable console and shell over UART, + * uncomment following lines and set the correct config + * in sensortile_box_pro_defconfig. + * + * zephyr,console = &uart4; + * zephyr,shell-uart = &uart4; + */ + zephyr,console = &cdc_acm_uart0; + zephyr,shell-uart = &cdc_acm_uart0; + + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpiof 6 GPIO_ACTIVE_HIGH>; + label = "User GREEN led"; + }; + red_led_1: led_2 { + gpios = <&gpioh 11 GPIO_ACTIVE_HIGH>; + label = "User RED led"; + }; + yellow_led_1: led_3 { + gpios = <&gpioh 12 GPIO_ACTIVE_HIGH>; + label = "User YELLOW led"; + }; + blue_led_1: led_4 { + gpios = <&gpiof 9 GPIO_ACTIVE_HIGH>; + label = "User YELLOW led"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + button1: button1 { + label = "User BT1"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + button2: button2 { + label = "User BT2"; + gpios = <&gpioe 0 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + sd_card: sd-card { + compatible = "st,stile_sd_card"; + en-sd-gpios = <&gpioh 10 (GPIO_ACTIVE_HIGH)>; + sel-sd-gpios = <&gpioh 8 (GPIO_ACTIVE_HIGH)>; + }; + + aliases { + led0 = &green_led_1; + led1 = &red_led_1; + led2 = &yellow_led_1; + led3 = &blue_led_1; + mcuboot-led0 = &blue_led_1; + mcuboot-button0 = &button1; + sw1 = &button1; + sw2 = &button2; + watchdog0 = &iwdg; + die-temp0 = &die_temp; + volt-sensor0 = &vref1; + volt-sensor1 = &vbat4; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_msis { + status = "okay"; + msi-range = <4>; + msi-pll-mode; +}; + +&gpioi { + status = "okay"; + + /* switch sensor IMU bus from I2C1 to SPI2 */ + mcu-sel-gpios { + gpio-hog; + gpios = <0 GPIO_ACTIVE_HIGH>; + output-low; + }; +}; + +&pll1 { + div-m = <1>; + mul-n = <80>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_msis>; + status = "okay"; +}; + +&rcc { + clocks = <&pll1>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00000800>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4_tx_pa0 &uart4_rx_pa1>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pe12 &spi1_sck_pe13 + &spi1_miso_pe14 &spi1_mosi_pe15>; + pinctrl-names = "default"; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_sck_pi1 &spi2_miso_pi2 &spi2_mosi_pi3>; + pinctrl-names = "default"; + status = "okay"; + + cs-gpios = <&gpioi 5 GPIO_ACTIVE_LOW>; + + lsm6dsv16x: lsm6dsv16x@0 { + compatible = "st,lsm6dsv16x"; + spi-max-frequency = ; /* 10 MHz */ + reg = <0>; + irq-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + drdy-pin = <2>; + }; +}; + +&timers4 { + status = "okay"; + st,prescaler = <1>; + pwm4: pwm { + status = "okay"; + pinctrl-0 = <&tim4_ch1_pb6>; + pinctrl-names = "default"; + }; +}; + +&timers3 { + status = "okay"; + st,prescaler = <255>; + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch2_pe4>; + pinctrl-names = "default"; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; + + hts221@5f { + compatible = "st,hts221"; + reg = <0x5f>; + drdy-gpios = <&gpioe 11 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + lis2mdl@1e { + compatible = "st,lis2mdl"; + reg = <0x1e>; + irq-gpios = <&gpioe 6 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_ph4 &i2c2_sda_ph5>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&aes { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +zephyr_udc0: &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; + + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + }; +}; + +&adc1 { + pinctrl-0 = <&adc1_in15_pb0>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&adc4 { + pinctrl-0 = <&adc4_in19_pb1>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&dac1 { + pinctrl-0 = <&dac1_out1_pa4>; + pinctrl-names = "default"; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&vref1 { + status = "okay"; +}; + +&vbat4 { + status = "okay"; +}; + +&sdmmc1 { + status = "okay"; + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2 + &sdmmc1_d0dir_pc6 &sdmmc1_d123dir_pc7 + &sdmmc1_cdir_pb9 &sdmmc1_ckin_pb8>; + pinctrl-names = "default"; + cd-gpios = <&gpioc 5 GPIO_ACTIVE_LOW>; + pwr-gpios = <&gpioh 10 GPIO_ACTIVE_LOW>; + bus-width = <4>; + clk-div = <4>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Following flash partition is dedicated to the use of sensortile_box_pro + * with TZEN=0 (so w/o TFM). + * Set the partitions with first MB to make use of the whole Bank1 + */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(416)>; + }; + slot1_partition: partition@78000 { + label = "image-1"; + reg = <0x00078000 DT_SIZE_K(416)>; + }; + scratch_partition: partition@e0000 { + label = "image-scratch"; + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + storage_partition: partition@f0000 { + label = "storage"; + reg = <0x000f0000 DT_SIZE_K(64)>; + }; + + }; +}; + +&gpdma1 { + status = "okay"; +}; diff --git a/boards/arm/sensortile_box_pro/sensortile_box_pro.yaml b/boards/arm/sensortile_box_pro/sensortile_box_pro.yaml new file mode 100644 index 00000000000..da81ee182e1 --- /dev/null +++ b/boards/arm/sensortile_box_pro/sensortile_box_pro.yaml @@ -0,0 +1,19 @@ +identifier: sensortile_box_pro +name: ST SensorTile.box Pro +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - pwm + - spi + - i2c + - gpio + - usb device + - nvs + - counter +ram: 640 +flash: 2048 +vendor: st diff --git a/boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig b/boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig new file mode 100644 index 00000000000..a75aad1dad5 --- /dev/null +++ b/boards/arm/sensortile_box_pro/sensortile_box_pro_defconfig @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32U5X=y +CONFIG_SOC_STM32U585XX=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable Clocks +CONFIG_CLOCK_CONTROL=y + +# config USB and USB console +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_LINE_CTRL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Comment out following USB config lines when +# switching console to UART +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_VID=0x0483 +CONFIG_USB_DEVICE_PID=0x1235 +CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC SensorTile.box PRO" +CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n + +# enable pin controller +CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y diff --git a/boards/arm/sensortile_box_pro/support/openocd.cfg b/boards/arm/sensortile_box_pro/support/openocd.cfg new file mode 100644 index 00000000000..ee58ed51d43 --- /dev/null +++ b/boards/arm/sensortile_box_pro/support/openocd.cfg @@ -0,0 +1,44 @@ +source [find interface/stlink-dap.cfg] + +set WORKAREASIZE 0x8000 + +transport select "dapdirect_swd" + +set CHIPNAME STM32U575ZITxQ +set BOARDNAME STILE-BOX-PRO + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# STlink Debug clock frequency +set CLOCK_FREQ 8000 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +reset_config srst_only srst_nogate connect_assert_srst +set CONNECT_UNDER_RESET 1 +set CORE_RESET 0 + +# ACCESS PORT NUMBER +set AP_NUM 0 +# GDB PORT +set GDB_PORT 3333 + +# BCTM CPU variables + +source [find target/stm32u5x.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} From 22295ee47aab0122fa40e5d4525af80990bef538 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Mon, 16 Oct 2023 17:18:29 +0200 Subject: [PATCH 3000/4498] sample: board: add SensorTile.box Pro sample for testing sensors Add sample to test SensorTile.box Pro sensors on board. Signed-off-by: Armando Visconti --- .../sensors-on-board/CMakeLists.txt | 10 + .../sensors-on-board/README.rst | 70 ++++ .../sensors-on-board/prj.conf | 14 + .../sensors-on-board/sample.yaml | 12 + .../sensors-on-board/src/main.c | 299 ++++++++++++++++++ .../usb/mass/boards/sensortile_box_pro.conf | 16 + 6 files changed, 421 insertions(+) create mode 100644 samples/boards/sensortile_box_pro/sensors-on-board/CMakeLists.txt create mode 100644 samples/boards/sensortile_box_pro/sensors-on-board/README.rst create mode 100644 samples/boards/sensortile_box_pro/sensors-on-board/prj.conf create mode 100644 samples/boards/sensortile_box_pro/sensors-on-board/sample.yaml create mode 100644 samples/boards/sensortile_box_pro/sensors-on-board/src/main.c create mode 100644 samples/subsys/usb/mass/boards/sensortile_box_pro.conf diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/CMakeLists.txt b/samples/boards/sensortile_box_pro/sensors-on-board/CMakeLists.txt new file mode 100644 index 00000000000..4904facbcd1 --- /dev/null +++ b/samples/boards/sensortile_box_pro/sensors-on-board/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(sensortile_box_pro) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/README.rst b/samples/boards/sensortile_box_pro/sensors-on-board/README.rst new file mode 100644 index 00000000000..16d5deca353 --- /dev/null +++ b/samples/boards/sensortile_box_pro/sensors-on-board/README.rst @@ -0,0 +1,70 @@ +.. _sensortile_box_pro_sample_sensors: + +ST SensorTile.box Pro on-board sensors test +########################################### + +Overview +******** +This sample provides an example of how to read sensors data +from the SensorTile.box Pro board. + +This sample enables all sensors of SensorTile.box Pro board, and then +periodically reads and displays data on the console from the following +sensors: + +- HTS221: ambient temperature and relative humidity +- LSM6DSV16X: 6-Axis acceleration and angular velocity + +Requirements +************ + +The application requires a SensorTile.box Pro board connected to the PC +through USB. The board shows up as a USB CDC class standard device. + +References +********** + +- :ref:`sensortile_box_pro_board` + +Building and Running +******************** + +Build and flash the sample in the following way: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/sensortile_box_pro/sensors-on-board + :board: sensortile_box_pro + :goals: build flash + +Please note that flashing the board requires a few preliminary steps described +in :ref:`sensortile_box_pro_board`. + +Then, power cycle the board by disconnecting and reconnecting the USB cable. +Run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the correct device path automatically created on +the host after the SensorTile.box Pro board gets connected to it, +usually :code:`/dev/ttyUSBx` or :code:`/dev/ttyACMx` (with x being 0, 1, 2, ...). +The ``-b`` option sets baud rate ignoring the value from config. + +Sample Output +============= + +The sample code outputs sensors data on the SensorTile.box Pro console. + + .. code-block:: console + + SensorTile.box Pro dashboard + + HTS221: Temperature: 26.4 C + HTS221: Relative Humidity: 60.5% + LSM6DSV16X: Accel (m.s-2): x: -0.158, y: 0.158, z: 9.811 + LSM6DSV16X: GYro (dps): x: 0.003, y: 0.000, z: -0.005 + 1:: lsm6dsv16x acc trig 836 + 1:: lsm6dsv16x gyr trig 836 + + diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf b/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf new file mode 100644 index 00000000000..82c6af865c9 --- /dev/null +++ b/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf @@ -0,0 +1,14 @@ +CONFIG_LOG=y +CONFIG_PRINTK=y +CONFIG_SPI=y +CONFIG_I2C=y +CONFIG_GPIO=y + +# config sensors +CONFIG_SENSOR=y +CONFIG_SENSOR_LOG_LEVEL_DBG=y +CONFIG_HTS221_TRIGGER_NONE=y +CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD=y +CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y + +CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/sample.yaml b/samples/boards/sensortile_box_pro/sensors-on-board/sample.yaml new file mode 100644 index 00000000000..d723fcdd7c7 --- /dev/null +++ b/samples/boards/sensortile_box_pro/sensors-on-board/sample.yaml @@ -0,0 +1,12 @@ +sample: + description: SensorTile.box Pro board testing + name: SensorTile.box Pro test +tests: + sample.board.sensortile_box_pro.sensors-on-board: + harness: sensor + platform_allow: sensortile_box_pro + tags: sensors + depends_on: + - i2c + - spi + - gpio diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c b/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c new file mode 100644 index 00000000000..8bb24ccc7d6 --- /dev/null +++ b/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_LSM6DSV16X_TRIGGER +static int lsm6dsv16x_acc_trig_cnt; +static int lsm6dsv16x_gyr_trig_cnt; +static int lsm6dsv16x_temp_trig_cnt; + +static void lsm6dsv16x_acc_trig_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ); + lsm6dsv16x_acc_trig_cnt++; +} + +static void lsm6dsv16x_gyr_trig_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_GYRO_XYZ); + lsm6dsv16x_gyr_trig_cnt++; +} + +static void lsm6dsv16x_temp_trig_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_DIE_TEMP); + lsm6dsv16x_temp_trig_cnt++; +} +#endif + +#ifdef CONFIG_LIS2MDL_TRIGGER +static int lis2mdl_trig_cnt; + +static void lis2mdl_trigger_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_ALL); + lis2mdl_trig_cnt++; +} +#endif + +static void lsm6dsv16x_config(const struct device *lsm6dsv16x) +{ + struct sensor_value odr_attr, fs_attr; + + /* set LSM6DSV16X accel sampling frequency to 208 Hz */ + odr_attr.val1 = 208; + odr_attr.val2 = 0; + + if (sensor_attr_set(lsm6dsv16x, SENSOR_CHAN_ACCEL_XYZ, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for LSM6DSV16X accel\n"); + return; + } + + sensor_g_to_ms2(16, &fs_attr); + + if (sensor_attr_set(lsm6dsv16x, SENSOR_CHAN_ACCEL_XYZ, + SENSOR_ATTR_FULL_SCALE, &fs_attr) < 0) { + printk("Cannot set fs for LSM6DSV16X accel\n"); + return; + } + + /* set LSM6DSV16X gyro sampling frequency to 208 Hz */ + odr_attr.val1 = 208; + odr_attr.val2 = 0; + + if (sensor_attr_set(lsm6dsv16x, SENSOR_CHAN_GYRO_XYZ, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for LSM6DSV16X gyro\n"); + return; + } + + sensor_degrees_to_rad(250, &fs_attr); + + if (sensor_attr_set(lsm6dsv16x, SENSOR_CHAN_GYRO_XYZ, + SENSOR_ATTR_FULL_SCALE, &fs_attr) < 0) { + printk("Cannot set fs for LSM6DSV16X gyro\n"); + return; + } + +#ifdef CONFIG_LSM6DSV16X_TRIGGER + struct sensor_trigger trig; + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_ACCEL_XYZ; + sensor_trigger_set(lsm6dsv16x, &trig, lsm6dsv16x_acc_trig_handler); + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_GYRO_XYZ; + sensor_trigger_set(lsm6dsv16x, &trig, lsm6dsv16x_gyr_trig_handler); + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_DIE_TEMP; + sensor_trigger_set(lsm6dsv16x, &trig, lsm6dsv16x_temp_trig_handler); +#endif +} + +static void lis2mdl_config(const struct device *lis2mdl) +{ + struct sensor_value odr_attr; + + /* set LIS2MDL sampling frequency to 100 Hz */ + odr_attr.val1 = 100; + odr_attr.val2 = 0; + + if (sensor_attr_set(lis2mdl, SENSOR_CHAN_ALL, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for LIS2MDL\n"); + return; + } + +#ifdef CONFIG_LIS2MDL_TRIGGER + struct sensor_trigger trig; + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_MAGN_XYZ; + sensor_trigger_set(lis2mdl, &trig, lis2mdl_trigger_handler); +#endif +} + +static int led_pattern_out(void) +{ + const struct gpio_dt_spec led0_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + const struct gpio_dt_spec led1_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios); + const struct gpio_dt_spec led2_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios); + const struct gpio_dt_spec led3_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(led3), gpios); + int i; + + /* led 0 */ + if (!gpio_is_ready_dt(&led0_gpio)) { + printk("%s: device not ready.\n", led0_gpio.port->name); + return -1; + } + gpio_pin_configure_dt(&led0_gpio, GPIO_OUTPUT_INACTIVE); + + /* led 1 */ + if (!gpio_is_ready_dt(&led1_gpio)) { + printk("%s: device not ready.\n", led1_gpio.port->name); + return -1; + } + gpio_pin_configure_dt(&led1_gpio, GPIO_OUTPUT_INACTIVE); + + /* led 2 */ + if (!gpio_is_ready_dt(&led2_gpio)) { + printk("%s: device not ready.\n", led2_gpio.port->name); + return -1; + } + gpio_pin_configure_dt(&led2_gpio, GPIO_OUTPUT_INACTIVE); + + /* led 3 */ + if (!gpio_is_ready_dt(&led3_gpio)) { + printk("%s: device not ready.\n", led3_gpio.port->name); + return -1; + } + gpio_pin_configure_dt(&led3_gpio, GPIO_OUTPUT_INACTIVE); + + /* output led pattern */ + for (i = 0; i < 12; i++) { + gpio_pin_set_dt(&led0_gpio, ((i % 4) == 0) ? 1 : 0); + gpio_pin_set_dt(&led1_gpio, ((i % 4) == 1) ? 1 : 0); + gpio_pin_set_dt(&led2_gpio, ((i % 4) == 2) ? 1 : 0); + gpio_pin_set_dt(&led3_gpio, ((i % 4) == 3) ? 1 : 0); + k_sleep(K_MSEC(100)); + } + + /* turn all leds off */ + gpio_pin_set_dt(&led0_gpio, 0); + gpio_pin_set_dt(&led1_gpio, 0); + gpio_pin_set_dt(&led2_gpio, 0); + gpio_pin_set_dt(&led3_gpio, 0); + + return 0; +} + +int main(void) +{ + int cnt = 1; + + /* signal that sample is started */ + if (led_pattern_out() < 0) { + return -1; + } + + printk("SensorTile.box Pro sensor test\n"); + + const struct device *const hts221 = DEVICE_DT_GET_ONE(st_hts221); + const struct device *const lsm6dsv16x = DEVICE_DT_GET_ONE(st_lsm6dsv16x); + const struct device *const lis2mdl = DEVICE_DT_GET_ONE(st_lis2mdl); + + if (!device_is_ready(hts221)) { + printk("%s: device not ready.\n", hts221->name); + return 0; + } + if (!device_is_ready(lsm6dsv16x)) { + printk("%s: device not ready.\n", lsm6dsv16x->name); + return 0; + } + if (!device_is_ready(lis2mdl)) { + printk("%s: device not ready.\n", lis2mdl->name); + return 0; + } + + lis2mdl_config(lis2mdl); + lsm6dsv16x_config(lsm6dsv16x); + + while (1) { + struct sensor_value hts221_hum, hts221_temp; + struct sensor_value lsm6dsv16x_accel[3], lsm6dsv16x_gyro[3]; + struct sensor_value lis2mdl_magn[3]; + struct sensor_value lis2mdl_temp; + + /* handle HTS221 sensor */ + if (sensor_sample_fetch(hts221) < 0) { + printf("HTS221 Sensor sample update error\n"); + return 0; + } + +#ifndef CONFIG_LSM6DSV16X_TRIGGER + if (sensor_sample_fetch(lsm6dsv16x) < 0) { + printf("LSM6DSV16X Sensor sample update error\n"); + return 0; + } +#endif + +#ifndef CONFIG_LIS2MDL_TRIGGER + if (sensor_sample_fetch(lis2mdl) < 0) { + printf("LIS2MDL Magn Sensor sample update error\n"); + return 0; + } +#endif + + sensor_channel_get(hts221, SENSOR_CHAN_HUMIDITY, &hts221_hum); + sensor_channel_get(hts221, SENSOR_CHAN_AMBIENT_TEMP, &hts221_temp); + sensor_channel_get(lsm6dsv16x, SENSOR_CHAN_ACCEL_XYZ, lsm6dsv16x_accel); + sensor_channel_get(lsm6dsv16x, SENSOR_CHAN_GYRO_XYZ, lsm6dsv16x_gyro); + sensor_channel_get(lis2mdl, SENSOR_CHAN_MAGN_XYZ, lis2mdl_magn); + sensor_channel_get(lis2mdl, SENSOR_CHAN_DIE_TEMP, &lis2mdl_temp); + + /* Display sensor data */ + + /* Clear terminal (ANSI ESC-C) */ + printf("\0033\014"); + + printf("SensorTile.box dashboard\n\n"); + + /* HTS221 temperature */ + printf("HTS221: Temperature: %.1f C\n", + sensor_value_to_double(&hts221_temp)); + + /* HTS221 humidity */ + printf("HTS221: Relative Humidity: %.1f%%\n", + sensor_value_to_double(&hts221_hum)); + + printf("LSM6DSV16X: Accel (m.s-2): x: %.3f, y: %.3f, z: %.3f\n", + sensor_value_to_double(&lsm6dsv16x_accel[0]), + sensor_value_to_double(&lsm6dsv16x_accel[1]), + sensor_value_to_double(&lsm6dsv16x_accel[2])); + + printf("LSM6DSV16X: GYro (dps): x: %.3f, y: %.3f, z: %.3f\n", + sensor_value_to_double(&lsm6dsv16x_gyro[0]), + sensor_value_to_double(&lsm6dsv16x_gyro[1]), + sensor_value_to_double(&lsm6dsv16x_gyro[2])); + + /* lis2mdl */ + printf("LIS2MDL: Magn (gauss): x: %.3f, y: %.3f, z: %.3f\n", + sensor_value_to_double(&lis2mdl_magn[0]), + sensor_value_to_double(&lis2mdl_magn[1]), + sensor_value_to_double(&lis2mdl_magn[2])); + + printf("LIS2MDL: Temperature: %.1f C\n", + sensor_value_to_double(&lis2mdl_temp)); + +#ifdef CONFIG_LSM6DSV16X_TRIGGER + printk("%d:: lsm6dsv16x acc trig %d\n", cnt, lsm6dsv16x_acc_trig_cnt); + printk("%d:: lsm6dsv16x gyr trig %d\n", cnt, lsm6dsv16x_gyr_trig_cnt); +#endif + +#ifdef CONFIG_LIS2MDL_TRIGGER + printk("%d:: lis2mdl trig %d\n", cnt, lis2mdl_trig_cnt); +#endif + + k_sleep(K_MSEC(2000)); + } +} diff --git a/samples/subsys/usb/mass/boards/sensortile_box_pro.conf b/samples/subsys/usb/mass/boards/sensortile_box_pro.conf new file mode 100644 index 00000000000..eca492a4505 --- /dev/null +++ b/samples/subsys/usb/mass/boards/sensortile_box_pro.conf @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022 O.S.Systems +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 + +CONFIG_DISK_ACCESS=y +CONFIG_DISK_DRIVERS=y +CONFIG_DISK_DRIVER_SDMMC=y + +CONFIG_FILE_SYSTEM=y +CONFIG_FAT_FILESYSTEM_ELM=y + +CONFIG_APP_MSC_STORAGE_SDCARD=y From 3cf254434ddee331196ac71fccd08b5622b4f7b3 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 9 Oct 2023 10:45:23 -0500 Subject: [PATCH 3001/4498] tests: drivers: spi: improve spi_loopback async test Add the following improvements to the spi_loopback async test: - Verify that a set of multiple spi_buf structures can be sent successfully - Check that the contents of the RX and TX buffers match after transfer completion Signed-off-by: Daniel DeGrasse --- tests/drivers/spi/spi_loopback/src/spi.c | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index 1b950e8a571..e272cf23567 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -561,12 +561,20 @@ static int spi_async_call(struct spi_dt_spec *spec) .buf = buffer_tx, .len = BUF_SIZE, }, + { + .buf = buffer2_tx, + .len = BUF2_SIZE, + }, }; const struct spi_buf rx_bufs[] = { { .buf = buffer_rx, .len = BUF_SIZE, }, + { + .buf = buffer2_rx, + .len = BUF2_SIZE, + }, }; const struct spi_buf_set tx = { .buffers = tx_bufs, @@ -579,6 +587,8 @@ static int spi_async_call(struct spi_dt_spec *spec) int ret; LOG_INF("Start async call"); + memset(buffer_rx, 0, sizeof(buffer_rx)); + memset(buffer2_rx, 0, sizeof(buffer2_rx)); ret = spi_transceive_signal(spec->bus, &spec->config, &tx, &rx, &async_sig); if (ret == -ENOTSUP) { @@ -600,6 +610,24 @@ static int spi_async_call(struct spi_dt_spec *spec) return -1; } + if (memcmp(buffer_tx, buffer_rx, BUF_SIZE)) { + to_display_format(buffer_tx, BUF_SIZE, buffer_print_tx); + to_display_format(buffer_rx, BUF_SIZE, buffer_print_rx); + LOG_ERR("Buffer contents are different: %s", buffer_print_tx); + LOG_ERR(" vs: %s", buffer_print_rx); + zassert_false(1, "Buffer contents are different"); + return -1; + } + + if (memcmp(buffer2_tx, buffer2_rx, BUF2_SIZE)) { + to_display_format(buffer2_tx, BUF2_SIZE, buffer_print_tx2); + to_display_format(buffer2_rx, BUF2_SIZE, buffer_print_rx2); + LOG_ERR("Buffer 2 contents are different: %s", buffer_print_tx2); + LOG_ERR(" vs: %s", buffer_print_rx2); + zassert_false(1, "Buffer 2 contents are different"); + return -1; + } + LOG_INF("Passed"); return 0; From ae265ea96e4b7ac668cad8db1681aa2dd7ae9ba7 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 15:30:16 +0000 Subject: [PATCH 3002/4498] kobject: move internal functions to own header Move all internal kobject APIs to own header and do not expose them with the rest of the public API. Signed-off-by: Anas Nashif --- .../zephyr/sys/internal/kobject_internal.h | 167 ++++++++++++++++++ include/zephyr/sys/kobject.h | 130 +------------- 2 files changed, 168 insertions(+), 129 deletions(-) create mode 100644 include/zephyr/sys/internal/kobject_internal.h diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h new file mode 100644 index 00000000000..4bb4efbae6f --- /dev/null +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_SYS_INTERNAL_KOBJECT_INTERNAL_H +#define ZEPHYR_INCLUDE_SYS_INTERNAL_KOBJECT_INTERNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond INTERNAL + */ + +#ifdef CONFIG_USERSPACE +#ifdef CONFIG_GEN_PRIV_STACKS +/* Metadata struct for K_OBJ_THREAD_STACK_ELEMENT */ +struct z_stack_data { + /* Size of the entire stack object, including reserved areas */ + size_t size; + + /* Stack buffer for privilege mode elevations */ + uint8_t *priv; +}; +#endif /* CONFIG_GEN_PRIV_STACKS */ + +/* Object extra data. Only some objects use this, determined by object type */ +union z_object_data { + /* Backing mutex for K_OBJ_SYS_MUTEX */ + struct k_mutex *mutex; + + /* Numerical thread ID for K_OBJ_THREAD */ + unsigned int thread_id; + +#ifdef CONFIG_GEN_PRIV_STACKS + /* Metadata for K_OBJ_THREAD_STACK_ELEMENT */ + const struct z_stack_data *stack_data; +#else + /* Stack buffer size for K_OBJ_THREAD_STACK_ELEMENT */ + size_t stack_size; +#endif /* CONFIG_GEN_PRIV_STACKS */ + + /* Futex wait queue and spinlock for K_OBJ_FUTEX */ + struct z_futex_data *futex_data; + + /* All other objects */ + int unused; +}; + +/* Table generated by gperf, these objects are retrieved via + * z_object_find() */ +struct z_object { + void *name; + uint8_t perms[CONFIG_MAX_THREAD_BYTES]; + uint8_t type; + uint8_t flags; + union z_object_data data; +} __packed __aligned(4); + +struct z_object_assignment { + struct k_thread *thread; + void * const *objects; +}; + + +/** + * Lookup a kernel object and init its metadata if it exists + * + * Calling this on an object will make it usable from userspace. + * Intended to be called as the last statement in kernel object init + * functions. + * + * @param obj Address of the kernel object + */ +void z_object_init(const void *obj); + + +#else +static inline void z_object_init(const void *obj) +{ + ARG_UNUSED(obj); +} +/* LCOV_EXCL_STOP */ +#endif /* !CONFIG_USERSPACE */ + +#ifdef CONFIG_DYNAMIC_OBJECTS +/** + * Allocate memory and install as a generic kernel object + * + * This is a low-level function to allocate some memory, and register that + * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. + * Initialization state and thread permissions will be cleared. The + * returned z_object's data value will be uninitialized. + * + * Most users will want to use k_object_alloc() instead. + * + * Memory allocated will be drawn from the calling thread's reasource pool + * and may be freed later by passing the actual object pointer (found + * in the returned z_object's 'name' member) to k_object_free(). + * + * @param align Required memory alignment for the allocated object + * @param size Size of the allocated object + * @return NULL on insufficient memory + * @return A pointer to the associated z_object that is installed in the + * kernel object tables + */ +struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size); + +/** + * Allocate memory and install as a generic kernel object + * + * This is a low-level function to allocate some memory, and register that + * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. + * Initialization state and thread permissions will be cleared. The + * returned z_object's data value will be uninitialized. + * + * Most users will want to use k_object_alloc() instead. + * + * Memory allocated will be drawn from the calling thread's reasource pool + * and may be freed later by passing the actual object pointer (found + * in the returned z_object's 'name' member) to k_object_free(). + * + * @param size Size of the allocated object + * @return NULL on insufficient memory + * @return A pointer to the associated z_object that is installed in the + * kernel object tables + */ +static inline struct z_object *z_dynamic_object_create(size_t size) +{ + return z_dynamic_object_aligned_create(0, size); +} + +#else + +/* LCOV_EXCL_START */ +static inline struct z_object *z_dynamic_object_aligned_create(size_t align, + size_t size) +{ + ARG_UNUSED(align); + ARG_UNUSED(size); + + return NULL; +} + +static inline struct z_object *z_dynamic_object_create(size_t size) +{ + ARG_UNUSED(size); + + return NULL; +} + +/* LCOV_EXCL_STOP */ +#endif /* CONFIG_DYNAMIC_OBJECTS */ + +/** @} */ + +/** + * @endcond INTERNAL + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zephyr/sys/kobject.h b/include/zephyr/sys/kobject.h index c423a7496ac..089898c4e70 100644 --- a/include/zephyr/sys/kobject.h +++ b/include/zephyr/sys/kobject.h @@ -10,6 +10,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -48,54 +49,6 @@ enum k_objects { */ #ifdef CONFIG_USERSPACE -#ifdef CONFIG_GEN_PRIV_STACKS -/* Metadata struct for K_OBJ_THREAD_STACK_ELEMENT */ -struct z_stack_data { - /* Size of the entire stack object, including reserved areas */ - size_t size; - - /* Stack buffer for privilege mode elevations */ - uint8_t *priv; -}; -#endif /* CONFIG_GEN_PRIV_STACKS */ - -/* Object extra data. Only some objects use this, determined by object type */ -union z_object_data { - /* Backing mutex for K_OBJ_SYS_MUTEX */ - struct k_mutex *mutex; - - /* Numerical thread ID for K_OBJ_THREAD */ - unsigned int thread_id; - -#ifdef CONFIG_GEN_PRIV_STACKS - /* Metadata for K_OBJ_THREAD_STACK_ELEMENT */ - const struct z_stack_data *stack_data; -#else - /* Stack buffer size for K_OBJ_THREAD_STACK_ELEMENT */ - size_t stack_size; -#endif /* CONFIG_GEN_PRIV_STACKS */ - - /* Futex wait queue and spinlock for K_OBJ_FUTEX */ - struct z_futex_data *futex_data; - - /* All other objects */ - int unused; -}; - -/* Table generated by gperf, these objects are retrieved via - * z_object_find() */ -struct z_object { - void *name; - uint8_t perms[CONFIG_MAX_THREAD_BYTES]; - uint8_t type; - uint8_t flags; - union z_object_data data; -} __packed __aligned(4); - -struct z_object_assignment { - struct k_thread *thread; - void * const *objects; -}; /** * @brief Grant a static thread access to a list of kernel objects @@ -126,17 +79,6 @@ struct z_object_assignment { /** Driver Object */ #define K_OBJ_FLAG_DRIVER BIT(3) -/** - * Lookup a kernel object and init its metadata if it exists - * - * Calling this on an object will make it usable from userspace. - * Intended to be called as the last statement in kernel object init - * functions. - * - * @param obj Address of the kernel object - */ -void z_object_init(const void *obj); - /** * Grant a thread access to a kernel object * @@ -209,14 +151,6 @@ bool k_object_is_valid(const void *obj, enum k_objects otype); /* LCOV_EXCL_START */ #define K_THREAD_ACCESS_GRANT(thread, ...) -/** - * @internal - */ -static inline void z_object_init(const void *obj) -{ - ARG_UNUSED(obj); -} - /** * @internal */ @@ -297,52 +231,6 @@ __syscall void *k_object_alloc(enum k_objects otype); */ __syscall void *k_object_alloc_size(enum k_objects otype, size_t size); -/** - * Allocate memory and install as a generic kernel object - * - * This is a low-level function to allocate some memory, and register that - * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. - * Initialization state and thread permissions will be cleared. The - * returned z_object's data value will be uninitialized. - * - * Most users will want to use k_object_alloc() instead. - * - * Memory allocated will be drawn from the calling thread's reasource pool - * and may be freed later by passing the actual object pointer (found - * in the returned z_object's 'name' member) to k_object_free(). - * - * @param align Required memory alignment for the allocated object - * @param size Size of the allocated object - * @return NULL on insufficient memory - * @return A pointer to the associated z_object that is installed in the - * kernel object tables - */ -struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size); - -/** - * Allocate memory and install as a generic kernel object - * - * This is a low-level function to allocate some memory, and register that - * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. - * Initialization state and thread permissions will be cleared. The - * returned z_object's data value will be uninitialized. - * - * Most users will want to use k_object_alloc() instead. - * - * Memory allocated will be drawn from the calling thread's reasource pool - * and may be freed later by passing the actual object pointer (found - * in the returned z_object's 'name' member) to k_object_free(). - * - * @param size Size of the allocated object - * @return NULL on insufficient memory - * @return A pointer to the associated z_object that is installed in the - * kernel object tables - */ -static inline struct z_object *z_dynamic_object_create(size_t size) -{ - return z_dynamic_object_aligned_create(0, size); -} - /** * Free a kernel object previously allocated with k_object_alloc() * @@ -372,22 +260,6 @@ static inline void *z_impl_k_object_alloc_size(enum k_objects otype, return NULL; } -static inline struct z_object *z_dynamic_object_aligned_create(size_t align, - size_t size) -{ - ARG_UNUSED(align); - ARG_UNUSED(size); - - return NULL; -} - -static inline struct z_object *z_dynamic_object_create(size_t size) -{ - ARG_UNUSED(size); - - return NULL; -} - /** * @brief Free an object * From d2c025dd7828bf7c5630637fec9c552bc374d7e3 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 21:29:37 +0000 Subject: [PATCH 3003/4498] kernel: objects: rename z_dynamic_object_create -> k_object_create_dynamic Do not use z_ for internal APIs and rename z_dynamic_object_create. Signed-off-by: Anas Nashif --- include/zephyr/sys/internal/kobject_internal.h | 4 ++-- subsys/net/lib/sockets/socketpair.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index 4bb4efbae6f..8d70b88dca2 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -127,7 +127,7 @@ struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size); * @return A pointer to the associated z_object that is installed in the * kernel object tables */ -static inline struct z_object *z_dynamic_object_create(size_t size) +static inline struct z_object *k_object_create_dynamic(size_t size) { return z_dynamic_object_aligned_create(0, size); } @@ -144,7 +144,7 @@ static inline struct z_object *z_dynamic_object_aligned_create(size_t align, return NULL; } -static inline struct z_object *z_dynamic_object_create(size_t size) +static inline struct z_object *k_object_create_dynamic(size_t size) { ARG_UNUSED(size); diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index 9207f4b659e..0ec4c4c1474 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -228,7 +228,7 @@ static struct spair *spair_new(void) } #elif CONFIG_USERSPACE - struct z_object *zo = z_dynamic_object_create(sizeof(*spair)); + struct z_object *zo = k_object_create_dynamic(sizeof(*spair)); if (zo == NULL) { spair = NULL; From c54fb959e30ae04a8e29c30dfbe4a63caafa929b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 21:31:33 +0000 Subject: [PATCH 3004/4498] kernel: objects: rename z_dynamic_object_aligned_create Do not use z_ for internal APIs and rename function. Signed-off-by: Anas Nashif --- include/zephyr/sys/internal/kobject_internal.h | 6 +++--- kernel/userspace.c | 2 +- tests/kernel/threads/dynamic_thread/src/main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index 8d70b88dca2..db6b031fb9a 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -106,7 +106,7 @@ static inline void z_object_init(const void *obj) * @return A pointer to the associated z_object that is installed in the * kernel object tables */ -struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size); +struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size); /** * Allocate memory and install as a generic kernel object @@ -129,13 +129,13 @@ struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size); */ static inline struct z_object *k_object_create_dynamic(size_t size) { - return z_dynamic_object_aligned_create(0, size); + return k_object_create_dynamic_aligned(0, size); } #else /* LCOV_EXCL_START */ -static inline struct z_object *z_dynamic_object_aligned_create(size_t align, +static inline struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size) { ARG_UNUSED(align); diff --git a/kernel/userspace.c b/kernel/userspace.c index ed36bec929c..e6be81e9a20 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -373,7 +373,7 @@ static struct z_object *dynamic_object_create(enum k_objects otype, size_t align return &dyn->kobj; } -struct z_object *z_dynamic_object_aligned_create(size_t align, size_t size) +struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size) { struct z_object *obj = dynamic_object_create(K_OBJ_ANY, align, size); diff --git a/tests/kernel/threads/dynamic_thread/src/main.c b/tests/kernel/threads/dynamic_thread/src/main.c index 8db6a32c4c5..0321aa792c7 100644 --- a/tests/kernel/threads/dynamic_thread/src/main.c +++ b/tests/kernel/threads/dynamic_thread/src/main.c @@ -159,7 +159,7 @@ ZTEST(thread_dynamic, test_thread_index_management) #include /** @endcond */ } - blob = z_dynamic_object_aligned_create(16, ret); + blob = k_object_create_dynamic_aligned(16, ret); zassert_true(blob != NULL, "out of heap memory"); /* Free one of the threads... */ From c91cad735aee603595c3434fb95d6e938e5f2bb1 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 21:32:13 +0000 Subject: [PATCH 3005/4498] kernel: object: rename z_object_init to k_object_init Do not use z_ for internal API and rename to k_object_init. Signed-off-by: Anas Nashif --- doc/kernel/usermode/kernelobjects.rst | 4 ++-- include/zephyr/sys/internal/kobject_internal.h | 4 ++-- kernel/condvar.c | 2 +- kernel/device.c | 2 +- kernel/events.c | 2 +- kernel/mem_slab.c | 4 ++-- kernel/msg_q.c | 2 +- kernel/mutex.c | 2 +- kernel/pipes.c | 2 +- kernel/poll.c | 2 +- kernel/queue.c | 2 +- kernel/sem.c | 2 +- kernel/stack.c | 2 +- kernel/thread.c | 4 ++-- kernel/timer.c | 2 +- kernel/userspace.c | 4 ++-- subsys/net/ip/net_if.c | 2 +- tests/kernel/mem_protect/mem_protect/src/kobject.c | 2 +- 18 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/kernel/usermode/kernelobjects.rst b/doc/kernel/usermode/kernelobjects.rst index 1ac62ab8a96..a5a20b6500e 100644 --- a/doc/kernel/usermode/kernelobjects.rst +++ b/doc/kernel/usermode/kernelobjects.rst @@ -210,7 +210,7 @@ Some objects will be implicitly initialized at boot: is run by the kernel early in the boot process. If a kernel object is initialized with a private static initializer, the object -must have :c:func:`z_object_init` called on it at some point by a supervisor +must have :c:func:`k_object_init` called on it at some point by a supervisor thread, otherwise the kernel will consider the object uninitialized if accessed by a user thread. This is very uncommon, typically only for kernel objects that are embedded within some larger struct and initialized statically. @@ -228,7 +228,7 @@ are embedded within some larger struct and initialized statically. }; ... - z_object_init(&my_foo.sem); + k_object_init(&my_foo.sem); ... diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index db6b031fb9a..65c62048396 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -74,11 +74,11 @@ struct z_object_assignment { * * @param obj Address of the kernel object */ -void z_object_init(const void *obj); +void k_object_init(const void *obj); #else -static inline void z_object_init(const void *obj) +static inline void k_object_init(const void *obj) { ARG_UNUSED(obj); } diff --git a/kernel/condvar.c b/kernel/condvar.c index 21f538c1996..e62fd27acce 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -21,7 +21,7 @@ static struct k_spinlock lock; int z_impl_k_condvar_init(struct k_condvar *condvar) { z_waitq_init(&condvar->wait_q); - z_object_init(condvar); + k_object_init(condvar); #ifdef CONFIG_OBJ_CORE_CONDVAR k_obj_core_init_and_link(K_OBJ_CORE(condvar), &obj_type_condvar); diff --git a/kernel/device.c b/kernel/device.c index d5ceb615461..8a07e4a9b23 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -21,7 +21,7 @@ void z_device_state_init(void) { STRUCT_SECTION_FOREACH(device, dev) { - z_object_init(dev); + k_object_init(dev); } } diff --git a/kernel/events.c b/kernel/events.c index 654978650bc..513559ced0f 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -58,7 +58,7 @@ void z_impl_k_event_init(struct k_event *event) z_waitq_init(&event->wait_q); - z_object_init(event); + k_object_init(event); #ifdef CONFIG_OBJ_CORE_EVENT k_obj_core_init_and_link(K_OBJ_CORE(event), &obj_type_event); diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index 7f7853213b9..3be1066d2b7 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -151,7 +151,7 @@ static int init_mem_slab_obj_core_list(void) if (rc < 0) { goto out; } - z_object_init(slab); + k_object_init(slab); #ifdef CONFIG_OBJ_CORE_MEM_SLAB k_obj_core_init_and_link(K_OBJ_CORE(slab), &obj_type_mem_slab); @@ -198,7 +198,7 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, #endif z_waitq_init(&slab->wait_q); - z_object_init(slab); + k_object_init(slab); out: SYS_PORT_TRACING_OBJ_INIT(k_mem_slab, slab, rc); diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 5b0f7cb83bd..3f56c095fcd 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -59,7 +59,7 @@ void k_msgq_init(struct k_msgq *msgq, char *buffer, size_t msg_size, SYS_PORT_TRACING_OBJ_INIT(k_msgq, msgq); - z_object_init(msgq); + k_object_init(msgq); } int z_impl_k_msgq_alloc_init(struct k_msgq *msgq, size_t msg_size, diff --git a/kernel/mutex.c b/kernel/mutex.c index 94084bdcce9..f94fa430508 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -57,7 +57,7 @@ int z_impl_k_mutex_init(struct k_mutex *mutex) z_waitq_init(&mutex->wait_q); - z_object_init(mutex); + k_object_init(mutex); #ifdef CONFIG_OBJ_CORE_MUTEX k_obj_core_init_and_link(K_OBJ_CORE(mutex), &obj_type_mutex); diff --git a/kernel/pipes.c b/kernel/pipes.c index e4bb0227901..c19b0e500c0 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -53,7 +53,7 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) #if defined(CONFIG_POLL) sys_dlist_init(&pipe->poll_events); #endif - z_object_init(pipe); + k_object_init(pipe); #ifdef CONFIG_OBJ_CORE_PIPE k_obj_core_init_and_link(K_OBJ_CORE(pipe), &obj_type_pipe); diff --git a/kernel/poll.c b/kernel/poll.c index 67e1e7f76a2..3727a2ba9f3 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -482,7 +482,7 @@ void z_impl_k_poll_signal_init(struct k_poll_signal *sig) sys_dlist_init(&sig->poll_events); sig->signaled = 0U; /* signal->result is left uninitialized */ - z_object_init(sig); + k_object_init(sig); SYS_PORT_TRACING_FUNC(k_poll_api, signal_init, sig); } diff --git a/kernel/queue.c b/kernel/queue.c index 2625b9aba5b..095ea077878 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -66,7 +66,7 @@ void z_impl_k_queue_init(struct k_queue *queue) SYS_PORT_TRACING_OBJ_INIT(k_queue, queue); - z_object_init(queue); + k_object_init(queue); } #ifdef CONFIG_USERSPACE diff --git a/kernel/sem.c b/kernel/sem.c index 3b8bcb12808..c411d9b63c2 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -63,7 +63,7 @@ int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, #if defined(CONFIG_POLL) sys_dlist_init(&sem->poll_events); #endif - z_object_init(sem); + k_object_init(sem); #ifdef CONFIG_OBJ_CORE_SEM k_obj_core_init_and_link(K_OBJ_CORE(sem), &obj_type_sem); diff --git a/kernel/stack.c b/kernel/stack.c index 0362ece76b5..dc6d1a6bfa1 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -32,7 +32,7 @@ void k_stack_init(struct k_stack *stack, stack_data_t *buffer, stack->top = stack->base + num_entries; SYS_PORT_TRACING_OBJ_INIT(k_stack, stack); - z_object_init(stack); + k_object_init(stack); #ifdef CONFIG_OBJ_CORE_STACK k_obj_core_init_and_link(K_OBJ_CORE(stack), &obj_type_stack); diff --git a/kernel/thread.c b/kernel/thread.c index 8e477b1f7dc..23585339e52 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -591,8 +591,8 @@ char *z_setup_new_thread(struct k_thread *new_thread, __ASSERT((options & K_USER) == 0U || z_stack_is_user_capable(stack), "user thread %p with kernel-only stack %p", new_thread, stack); - z_object_init(new_thread); - z_object_init(stack); + k_object_init(new_thread); + k_object_init(stack); new_thread->stack_obj = stack; new_thread->syscall_frame = NULL; diff --git a/kernel/timer.c b/kernel/timer.c index 9994ae49b64..1dc60dbe7ca 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -128,7 +128,7 @@ void k_timer_init(struct k_timer *timer, timer->user_data = NULL; - z_object_init(timer); + k_object_init(timer); #ifdef CONFIG_OBJ_CORE_TIMER k_obj_core_init_and_link(K_OBJ_CORE(timer), &obj_type_timer); diff --git a/kernel/userspace.c b/kernel/userspace.c index e6be81e9a20..02211be3029 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -754,7 +754,7 @@ int z_object_validate(struct z_object *ko, enum k_objects otype, return 0; } -void z_object_init(const void *obj) +void k_object_init(const void *obj) { struct z_object *ko; @@ -794,7 +794,7 @@ void z_object_uninit(const void *obj) { struct z_object *ko; - /* See comments in z_object_init() */ + /* See comments in k_object_init() */ ko = z_object_find(obj); if (ko == NULL) { return; diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index b77c3ad3269..acf5d628b9d 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -422,7 +422,7 @@ static inline void init_iface(struct net_if *iface) NET_DBG("On iface %p", iface); #ifdef CONFIG_USERSPACE - z_object_init(iface); + k_object_init(iface); #endif k_mutex_init(&iface->lock); diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 3b566da4457..d0ec8c1fb30 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -42,7 +42,7 @@ ZTEST(mem_protect_kobj, test_kobject_access_grant) { set_fault_valid(false); - z_object_init(random_sem_type); + k_object_init(random_sem_type); k_thread_access_grant(k_current_get(), &kobject_sem, &kobject_mutex, From a6b490073e8710b50ccd1820dc94d1bf92be3d35 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 21:37:25 +0000 Subject: [PATCH 3006/4498] kernel: object: rename z_object -> k_object Do not use z_ for internal structures and rename to k_object instead. Signed-off-by: Anas Nashif --- CMakeLists.txt | 4 +- cmake/linker_script/common/common-rom.cmake | 6 +-- doc/contribute/documentation/guidelines.rst | 4 +- .../common-rom/common-rom-kernel-devices.ld | 2 +- .../zephyr/sys/internal/kobject_internal.h | 28 +++++----- include/zephyr/sys/kobject.h | 2 +- include/zephyr/syscall_handler.h | 18 +++---- kernel/futex.c | 2 +- kernel/sched.c | 2 +- kernel/thread.c | 6 +-- kernel/userspace.c | 52 +++++++++---------- kernel/userspace_handler.c | 8 +-- lib/os/mutex.c | 2 +- scripts/build/gen_kobject_list.py | 6 +-- scripts/pylib/twister/twisterlib/size_calc.py | 2 +- subsys/net/lib/sockets/socketpair.c | 2 +- .../mem_protect/mem_protect/src/kobject.c | 2 +- tests/kernel/mem_protect/userspace/src/main.c | 2 +- tests/kernel/threads/thread_stack/src/main.c | 2 +- 19 files changed, 76 insertions(+), 76 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be466a1ae81..5a40538598b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1124,7 +1124,7 @@ if(CONFIG_USERSPACE) ${PROCESS_GPERF} -i ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} -o ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} - -p "struct z_object" + -p "struct k_object" $<$:--verbose> DEPENDS kobj_prebuilt_hash_output_src_pre ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} @@ -1316,7 +1316,7 @@ if(CONFIG_USERSPACE) ${PROCESS_GPERF} -i ${KOBJECT_HASH_OUTPUT_SRC_PRE} -o ${KOBJECT_HASH_OUTPUT_SRC} - -p "struct z_object" + -p "struct k_object" $<$:--verbose> DEPENDS kobj_hash_output_src_pre ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC_PRE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index 35c023e72e4..d79fa223fc5 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -67,13 +67,13 @@ if(CONFIG_USERSPACE) # Build-time assignment of permissions to kernel objects to # threads declared with K_THREAD_DEFINE() zephyr_linker_section( - NAME z_object_assignment_area + NAME k_object_assignment_area VMA FLASH NOINPUT SUBALIGN 4 ) zephyr_linker_section_configure( - SECTION z_object_assignment - INPUT ".z_object_assignment.static.*" + SECTION k_object_assignment + INPUT ".k_object_assignment.static.*" KEEP SORT NAME ) endif() diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index 2fd7d82785d..55db8e2e556 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -392,7 +392,7 @@ For example:: .. code-block:: c - struct z_object { + struct k_object { char *name; uint8_t perms[CONFIG_MAX_THREAD_BYTES]; uint8_t type; @@ -408,7 +408,7 @@ This would be rendered as: .. code-block:: c - struct z_object { + struct k_object { char *name; uint8_t perms[CONFIG_MAX_THREAD_BYTES]; uint8_t type; diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index cd5c610d3f6..dfa19d13492 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -75,7 +75,7 @@ /* Build-time assignment of permissions to kernel objects to * threads declared with K_THREAD_DEFINE() */ - ITERABLE_SECTION_ROM(z_object_assignment, 4) + ITERABLE_SECTION_ROM(k_object_assignment, 4) #endif SECTION_DATA_PROLOGUE(app_shmem_regions,,) diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index 65c62048396..15bab175e0f 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -27,7 +27,7 @@ struct z_stack_data { #endif /* CONFIG_GEN_PRIV_STACKS */ /* Object extra data. Only some objects use this, determined by object type */ -union z_object_data { +union k_object_data { /* Backing mutex for K_OBJ_SYS_MUTEX */ struct k_mutex *mutex; @@ -51,15 +51,15 @@ union z_object_data { /* Table generated by gperf, these objects are retrieved via * z_object_find() */ -struct z_object { +struct k_object { void *name; uint8_t perms[CONFIG_MAX_THREAD_BYTES]; uint8_t type; uint8_t flags; - union z_object_data data; + union k_object_data data; } __packed __aligned(4); -struct z_object_assignment { +struct k_object_assignment { struct k_thread *thread; void * const *objects; }; @@ -92,21 +92,21 @@ static inline void k_object_init(const void *obj) * This is a low-level function to allocate some memory, and register that * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. * Initialization state and thread permissions will be cleared. The - * returned z_object's data value will be uninitialized. + * returned k_object's data value will be uninitialized. * * Most users will want to use k_object_alloc() instead. * * Memory allocated will be drawn from the calling thread's reasource pool * and may be freed later by passing the actual object pointer (found - * in the returned z_object's 'name' member) to k_object_free(). + * in the returned k_object's 'name' member) to k_object_free(). * * @param align Required memory alignment for the allocated object * @param size Size of the allocated object * @return NULL on insufficient memory - * @return A pointer to the associated z_object that is installed in the + * @return A pointer to the associated k_object that is installed in the * kernel object tables */ -struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size); +struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size); /** * Allocate memory and install as a generic kernel object @@ -114,20 +114,20 @@ struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size); * This is a low-level function to allocate some memory, and register that * allocated memory in the kernel object lookup tables with type K_OBJ_ANY. * Initialization state and thread permissions will be cleared. The - * returned z_object's data value will be uninitialized. + * returned k_object's data value will be uninitialized. * * Most users will want to use k_object_alloc() instead. * * Memory allocated will be drawn from the calling thread's reasource pool * and may be freed later by passing the actual object pointer (found - * in the returned z_object's 'name' member) to k_object_free(). + * in the returned k_object's 'name' member) to k_object_free(). * * @param size Size of the allocated object * @return NULL on insufficient memory - * @return A pointer to the associated z_object that is installed in the + * @return A pointer to the associated k_object that is installed in the * kernel object tables */ -static inline struct z_object *k_object_create_dynamic(size_t size) +static inline struct k_object *k_object_create_dynamic(size_t size) { return k_object_create_dynamic_aligned(0, size); } @@ -135,7 +135,7 @@ static inline struct z_object *k_object_create_dynamic(size_t size) #else /* LCOV_EXCL_START */ -static inline struct z_object *k_object_create_dynamic_aligned(size_t align, +static inline struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size) { ARG_UNUSED(align); @@ -144,7 +144,7 @@ static inline struct z_object *k_object_create_dynamic_aligned(size_t align, return NULL; } -static inline struct z_object *k_object_create_dynamic(size_t size) +static inline struct k_object *k_object_create_dynamic(size_t size) { ARG_UNUSED(size); diff --git a/include/zephyr/sys/kobject.h b/include/zephyr/sys/kobject.h index 089898c4e70..628bb967551 100644 --- a/include/zephyr/sys/kobject.h +++ b/include/zephyr/sys/kobject.h @@ -65,7 +65,7 @@ enum k_objects { #define K_THREAD_ACCESS_GRANT(name_, ...) \ static void * const _CONCAT(_object_list_, name_)[] = \ { __VA_ARGS__, NULL }; \ - static const STRUCT_SECTION_ITERABLE(z_object_assignment, \ + static const STRUCT_SECTION_ITERABLE(k_object_assignment, \ _CONCAT(_object_access_, name_)) = \ { (&_k_thread_obj_ ## name_), \ (_CONCAT(_object_list_, name_)) } diff --git a/include/zephyr/syscall_handler.h b/include/zephyr/syscall_handler.h index ac6d47a23a4..8bff82e9557 100644 --- a/include/zephyr/syscall_handler.h +++ b/include/zephyr/syscall_handler.h @@ -78,7 +78,7 @@ static inline bool z_is_in_user_syscall(void) * -EPERM If the caller does not have permissions * -EINVAL Object is not initialized */ -int z_object_validate(struct z_object *ko, enum k_objects otype, +int z_object_validate(struct k_object *ko, enum k_objects otype, enum _obj_init_check init); /** @@ -86,11 +86,11 @@ int z_object_validate(struct z_object *ko, enum k_objects otype, * * @param retval Return value from z_object_validate() * @param obj Kernel object we were trying to verify - * @param ko If retval=-EPERM, struct z_object * that was looked up, or NULL + * @param ko If retval=-EPERM, struct k_object * that was looked up, or NULL * @param otype Expected type of the kernel object */ void z_dump_object_error(int retval, const void *obj, - struct z_object *ko, enum k_objects otype); + struct k_object *ko, enum k_objects otype); /** * Kernel object validation function @@ -102,14 +102,14 @@ void z_dump_object_error(int retval, const void *obj, * @return Kernel object's metadata, or NULL if the parameter wasn't the * memory address of a kernel object */ -struct z_object *z_object_find(const void *obj); +struct k_object *z_object_find(const void *obj); -typedef void (*_wordlist_cb_func_t)(struct z_object *ko, void *context); +typedef void (*_wordlist_cb_func_t)(struct k_object *ko, void *context); /** * Iterate over all the kernel object metadata in the system * - * @param func function to run on each struct z_object + * @param func function to run on each struct k_object * @param context Context pointer to pass to each invocation */ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); @@ -129,7 +129,7 @@ void z_thread_perms_inherit(struct k_thread *parent, * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -void z_thread_perms_set(struct z_object *ko, struct k_thread *thread); +void z_thread_perms_set(struct k_object *ko, struct k_thread *thread); /** * Revoke a thread's permission to a kernel object @@ -137,7 +137,7 @@ void z_thread_perms_set(struct z_object *ko, struct k_thread *thread); * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread); +void z_thread_perms_clear(struct k_object *ko, struct k_thread *thread); /* * Revoke access to all objects for the provided thread @@ -427,7 +427,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) -static inline int z_obj_validation_check(struct z_object *ko, +static inline int z_obj_validation_check(struct k_object *ko, const void *obj, enum k_objects otype, enum _obj_init_check init) diff --git a/kernel/futex.c b/kernel/futex.c index 40362045eab..360d2a99412 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -14,7 +14,7 @@ static struct z_futex_data *k_futex_find_data(struct k_futex *futex) { - struct z_object *obj; + struct k_object *obj; obj = z_object_find(futex); if (obj == NULL || obj->type != K_OBJ_FUTEX) { diff --git a/kernel/sched.c b/kernel/sched.c index 66b10c3b04f..12393c0eada 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1878,7 +1878,7 @@ int z_impl_k_thread_join(struct k_thread *thread, k_timeout_t timeout) */ static bool thread_obj_validate(struct k_thread *thread) { - struct z_object *ko = z_object_find(thread); + struct k_object *ko = z_object_find(thread); int ret = z_object_validate(ko, K_OBJ_THREAD, _OBJ_INIT_TRUE); switch (ret) { diff --git a/kernel/thread.c b/kernel/thread.c index 23585339e52..4a54fd5dd29 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -360,7 +360,7 @@ static inline int z_vrfy_k_thread_name_copy(k_tid_t thread, { #ifdef CONFIG_THREAD_NAME size_t len; - struct z_object *ko = z_object_find(thread); + struct k_object *ko = z_object_find(thread); /* Special case: we allow reading the names of initialized threads * even if we don't have permission on them @@ -725,7 +725,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, int prio, uint32_t options, k_timeout_t delay) { size_t total_size, stack_obj_size; - struct z_object *stack_object; + struct k_object *stack_object; /* The thread and stack objects *must* be in an uninitialized state */ Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD)); @@ -791,7 +791,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, static void grant_static_access(void) { - STRUCT_SECTION_FOREACH(z_object_assignment, pos) { + STRUCT_SECTION_FOREACH(k_object_assignment, pos) { for (int i = 0; pos->objects[i] != NULL; i++) { k_object_access_grant(pos->objects[i], pos->thread); diff --git a/kernel/userspace.c b/kernel/userspace.c index 02211be3029..f98654493a5 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -77,7 +77,7 @@ static struct k_spinlock obj_lock; /* kobj struct data */ extern uint8_t _thread_idx_map[CONFIG_MAX_THREAD_BYTES]; #endif -static void clear_perms_cb(struct z_object *ko, void *ctx_ptr); +static void clear_perms_cb(struct k_object *ko, void *ctx_ptr); const char *otype_to_str(enum k_objects otype) { @@ -119,7 +119,7 @@ struct perm_ctx { */ uint8_t *z_priv_stack_find(k_thread_stack_t *stack) { - struct z_object *obj = z_object_find(stack); + struct k_object *obj = z_object_find(stack); __ASSERT(obj != NULL, "stack object not found"); __ASSERT(obj->type == K_OBJ_THREAD_STACK_ELEMENT, @@ -166,14 +166,14 @@ uint8_t *z_priv_stack_find(k_thread_stack_t *stack) MAX(DYN_OBJ_DATA_ALIGN_K_THREAD, (sizeof(void *))) struct dyn_obj { - struct z_object kobj; + struct k_object kobj; sys_dnode_t dobj_list; /* The object itself */ void *data; }; -extern struct z_object *z_object_gperf_find(const void *obj); +extern struct k_object *z_object_gperf_find(const void *obj); extern void z_object_gperf_wordlist_foreach(_wordlist_cb_func_t func, void *context); @@ -311,7 +311,7 @@ static void thread_idx_free(uintptr_t tidx) sys_bitfield_set_bit((mem_addr_t)_thread_idx_map, tidx); } -static struct z_object *dynamic_object_create(enum k_objects otype, size_t align, +static struct k_object *dynamic_object_create(enum k_objects otype, size_t align, size_t size) { struct dyn_obj *dyn; @@ -373,9 +373,9 @@ static struct z_object *dynamic_object_create(enum k_objects otype, size_t align return &dyn->kobj; } -struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size) +struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size) { - struct z_object *obj = dynamic_object_create(K_OBJ_ANY, align, size); + struct k_object *obj = dynamic_object_create(K_OBJ_ANY, align, size); if (obj == NULL) { LOG_ERR("could not allocate kernel object, out of memory"); @@ -386,7 +386,7 @@ struct z_object *k_object_create_dynamic_aligned(size_t align, size_t size) static void *z_object_alloc(enum k_objects otype, size_t size) { - struct z_object *zo; + struct k_object *zo; uintptr_t tidx = 0; if (otype <= K_OBJ_ANY || otype >= K_OBJ_LAST) { @@ -475,9 +475,9 @@ void k_object_free(void *obj) } } -struct z_object *z_object_find(const void *obj) +struct k_object *z_object_find(const void *obj) { - struct z_object *ret; + struct k_object *ret; ret = z_object_gperf_find(obj); @@ -514,7 +514,7 @@ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) static unsigned int thread_index_get(struct k_thread *thread) { - struct z_object *ko; + struct k_object *ko; ko = z_object_find(thread); @@ -525,7 +525,7 @@ static unsigned int thread_index_get(struct k_thread *thread) return ko->data.thread_id; } -static void unref_check(struct z_object *ko, uintptr_t index) +static void unref_check(struct k_object *ko, uintptr_t index) { k_spinlock_key_t key = k_spin_lock(&obj_lock); @@ -579,7 +579,7 @@ static void unref_check(struct z_object *ko, uintptr_t index) k_spin_unlock(&obj_lock, key); } -static void wordlist_cb(struct z_object *ko, void *ctx_ptr) +static void wordlist_cb(struct k_object *ko, void *ctx_ptr) { struct perm_ctx *ctx = (struct perm_ctx *)ctx_ptr; @@ -602,7 +602,7 @@ void z_thread_perms_inherit(struct k_thread *parent, struct k_thread *child) } } -void z_thread_perms_set(struct z_object *ko, struct k_thread *thread) +void z_thread_perms_set(struct k_object *ko, struct k_thread *thread) { int index = thread_index_get(thread); @@ -611,7 +611,7 @@ void z_thread_perms_set(struct z_object *ko, struct k_thread *thread) } } -void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread) +void z_thread_perms_clear(struct k_object *ko, struct k_thread *thread) { int index = thread_index_get(thread); @@ -621,7 +621,7 @@ void z_thread_perms_clear(struct z_object *ko, struct k_thread *thread) } } -static void clear_perms_cb(struct z_object *ko, void *ctx_ptr) +static void clear_perms_cb(struct k_object *ko, void *ctx_ptr) { uintptr_t id = (uintptr_t)ctx_ptr; @@ -637,7 +637,7 @@ void z_thread_perms_all_clear(struct k_thread *thread) } } -static int thread_perms_test(struct z_object *ko) +static int thread_perms_test(struct k_object *ko) { int index; @@ -652,7 +652,7 @@ static int thread_perms_test(struct z_object *ko) return 0; } -static void dump_permission_error(struct z_object *ko) +static void dump_permission_error(struct k_object *ko) { int index = thread_index_get(_current); LOG_ERR("thread %p (%d) does not have permission on %s %p", @@ -661,7 +661,7 @@ static void dump_permission_error(struct z_object *ko) LOG_HEXDUMP_ERR(ko->perms, sizeof(ko->perms), "permission bitmap"); } -void z_dump_object_error(int retval, const void *obj, struct z_object *ko, +void z_dump_object_error(int retval, const void *obj, struct k_object *ko, enum k_objects otype) { switch (retval) { @@ -691,7 +691,7 @@ void z_dump_object_error(int retval, const void *obj, struct z_object *ko, void z_impl_k_object_access_grant(const void *object, struct k_thread *thread) { - struct z_object *ko = z_object_find(object); + struct k_object *ko = z_object_find(object); if (ko != NULL) { z_thread_perms_set(ko, thread); @@ -700,7 +700,7 @@ void z_impl_k_object_access_grant(const void *object, struct k_thread *thread) void k_object_access_revoke(const void *object, struct k_thread *thread) { - struct z_object *ko = z_object_find(object); + struct k_object *ko = z_object_find(object); if (ko != NULL) { z_thread_perms_clear(ko, thread); @@ -714,14 +714,14 @@ void z_impl_k_object_release(const void *object) void k_object_access_all_grant(const void *object) { - struct z_object *ko = z_object_find(object); + struct k_object *ko = z_object_find(object); if (ko != NULL) { ko->flags |= K_OBJ_FLAG_PUBLIC; } } -int z_object_validate(struct z_object *ko, enum k_objects otype, +int z_object_validate(struct k_object *ko, enum k_objects otype, enum _obj_init_check init) { if (unlikely((ko == NULL) || @@ -756,7 +756,7 @@ int z_object_validate(struct z_object *ko, enum k_objects otype, void k_object_init(const void *obj) { - struct z_object *ko; + struct k_object *ko; /* By the time we get here, if the caller was from userspace, all the * necessary checks have been done in z_object_validate(), which takes @@ -781,7 +781,7 @@ void k_object_init(const void *obj) void z_object_recycle(const void *obj) { - struct z_object *ko = z_object_find(obj); + struct k_object *ko = z_object_find(obj); if (ko != NULL) { (void)memset(ko->perms, 0, sizeof(ko->perms)); @@ -792,7 +792,7 @@ void z_object_recycle(const void *obj) void z_object_uninit(const void *obj) { - struct z_object *ko; + struct k_object *ko; /* See comments in k_object_init() */ ko = z_object_find(obj); diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 5453bbcede4..ec59ca54c53 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -9,11 +9,11 @@ #include #include -static struct z_object *validate_kernel_object(const void *obj, +static struct k_object *validate_kernel_object(const void *obj, enum k_objects otype, enum _obj_init_check init) { - struct z_object *ko; + struct k_object *ko; int ret; ko = z_object_find(obj); @@ -56,7 +56,7 @@ bool k_object_is_valid(const void *obj, enum k_objects otype) static inline void z_vrfy_k_object_access_grant(const void *object, struct k_thread *thread) { - struct z_object *ko; + struct k_object *ko; Z_OOPS(Z_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); ko = validate_any_object(object); @@ -68,7 +68,7 @@ static inline void z_vrfy_k_object_access_grant(const void *object, static inline void z_vrfy_k_object_release(const void *object) { - struct z_object *ko; + struct k_object *ko; ko = validate_any_object((void *)object); Z_OOPS(Z_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", diff --git a/lib/os/mutex.c b/lib/os/mutex.c index 3cd84612a22..b2284f076d9 100644 --- a/lib/os/mutex.c +++ b/lib/os/mutex.c @@ -11,7 +11,7 @@ static struct k_mutex *get_k_mutex(struct sys_mutex *mutex) { - struct z_object *obj; + struct k_object *obj; obj = z_object_find(mutex); if (obj == NULL || obj->type != K_OBJ_SYS_MUTEX) { diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index 420d96485d4..db274c19b3a 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -727,7 +727,7 @@ def get_symbols(elf): #include #include %} -struct z_object; +struct k_object; """ # Different versions of gperf have different prototypes for the lookup @@ -735,7 +735,7 @@ def get_symbols(elf): # turned into a string, we told gperf to expect binary strings that are not # NULL-terminated. footer = """%% -struct z_object *z_object_gperf_find(const void *obj) +struct k_object *z_object_gperf_find(const void *obj) { return z_object_lookup((const char *)obj, sizeof(void *)); } @@ -752,7 +752,7 @@ def get_symbols(elf): } #ifndef CONFIG_DYNAMIC_OBJECTS -struct z_object *z_object_find(const void *obj) +struct k_object *z_object_find(const void *obj) ALIAS_OF(z_object_gperf_find); void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) diff --git a/scripts/pylib/twister/twisterlib/size_calc.py b/scripts/pylib/twister/twisterlib/size_calc.py index 8a98c447eba..f449d26ac99 100644 --- a/scripts/pylib/twister/twisterlib/size_calc.py +++ b/scripts/pylib/twister/twisterlib/size_calc.py @@ -78,7 +78,7 @@ class SizeCalculator: "ctors", "init_array", "reset", - "z_object_assignment_area", + "k_object_assignment_area", "rodata", "net_l2", "vector", diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index 0ec4c4c1474..fad4f7aa71f 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -228,7 +228,7 @@ static struct spair *spair_new(void) } #elif CONFIG_USERSPACE - struct z_object *zo = k_object_create_dynamic(sizeof(*spair)); + struct k_object *zo = k_object_create_dynamic(sizeof(*spair)); if (zo == NULL) { spair = NULL; diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index d0ec8c1fb30..76ed3f5a5b7 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -1054,7 +1054,7 @@ ZTEST(mem_protect_kobj, test_mark_thread_exit_uninitialized) set_fault_valid(false); int ret; - struct z_object *ko; + struct k_object *ko; k_thread_access_grant(&child_thread, &child_stack); diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 2e63638a4d6..7c0289ab16b 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -867,7 +867,7 @@ static struct k_sem recycle_sem; */ ZTEST(userspace, test_object_recycle) { - struct z_object *ko; + struct k_object *ko; int perms_count = 0; int dummy = 0; diff --git a/tests/kernel/threads/thread_stack/src/main.c b/tests/kernel/threads/thread_stack/src/main.c index b84b3b3dd44..9a3a01a1cf0 100644 --- a/tests/kernel/threads/thread_stack/src/main.c +++ b/tests/kernel/threads/thread_stack/src/main.c @@ -333,7 +333,7 @@ void scenario_entry(void *stack_obj, size_t obj_size, size_t reported_size, size_t metadata_size; #ifdef CONFIG_USERSPACE - struct z_object *zo; + struct k_object *zo; zo = z_object_find(stack_obj); if (zo != NULL) { From 4e396174ce4f469ff734d314f1d78e06aaf000e9 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 26 Sep 2023 22:46:01 +0000 Subject: [PATCH 3007/4498] kernel: move syscall_handler.h to internal include directory Move the syscall_handler.h header, used internally only to a dedicated internal folder that should not be used outside of Zephyr. Signed-off-by: Anas Nashif --- arch/x86/core/userspace.c | 2 +- doc/kernel/drivers/index.rst | 2 +- doc/kernel/usermode/syscalls.rst | 4 ++-- drivers/adc/adc_handlers.c | 2 +- drivers/auxdisplay/auxdisplay_handlers.c | 2 +- drivers/bbram/bbram_handlers.c | 2 +- drivers/cache/cache_handlers.c | 2 +- drivers/can/can_handlers.c | 2 +- drivers/charger/charger_handlers.c | 2 +- drivers/console/uart_mux.c | 2 +- drivers/counter/counter_handlers.c | 2 +- drivers/counter/maxim_ds3231.c | 2 +- drivers/dac/dac_handlers.c | 2 +- drivers/dma/dma_handlers.c | 2 +- drivers/eeprom/eeprom_handlers.c | 2 +- drivers/entropy/entropy_handlers.c | 2 +- drivers/espi/espi_handlers.c | 2 +- drivers/flash/flash_handlers.c | 2 +- drivers/flash/flash_npcx_fiu_nor.c | 2 +- drivers/flash/flash_simulator.c | 2 +- drivers/flash/flash_stm32_ex_op.c | 2 +- drivers/flash/nrf_qspi_nor.c | 2 +- drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c | 2 +- drivers/fuel_gauge/fuel_gauge_syscall_handlers.c | 2 +- drivers/gpio/gpio_handlers.c | 2 +- drivers/hwinfo/hwinfo_handlers.c | 2 +- drivers/hwspinlock/hwspinlock_handlers.c | 2 +- drivers/i2c/i2c_handlers.c | 2 +- drivers/i2s/i2s_handlers.c | 2 +- drivers/i3c/i3c_handlers.c | 2 +- drivers/ipm/ipm_handlers.c | 2 +- drivers/kscan/kscan_handlers.c | 2 +- drivers/led/led_handlers.c | 2 +- drivers/mbox/mbox_handlers.c | 2 +- drivers/peci/peci_handlers.c | 2 +- drivers/ps2/ps2_handlers.c | 2 +- drivers/ptp_clock/ptp_clock.c | 2 +- drivers/pwm/pwm_handlers.c | 2 +- drivers/retained_mem/retained_mem_handlers.c | 2 +- drivers/rtc/rtc_handlers.c | 2 +- drivers/sensor/sensor_handlers.c | 2 +- drivers/serial/uart_handlers.c | 2 +- drivers/sip_svc/sip_smc_intel_socfpga.c | 2 +- drivers/smbus/smbus_handlers.c | 2 +- drivers/spi/spi_handlers.c | 2 +- drivers/usb/bc12/bc12_handlers.c | 2 +- drivers/virtualization/virt_ivshmem_handlers.c | 2 +- drivers/w1/w1_handlers.c | 2 +- drivers/watchdog/wdt_handlers.c | 2 +- include/zephyr/{ => internal}/syscall_handler.h | 0 kernel/atomic_c.c | 2 +- kernel/condvar.c | 2 +- kernel/device.c | 2 +- kernel/dynamic.c | 2 +- kernel/errno.c | 2 +- kernel/events.c | 2 +- kernel/futex.c | 2 +- kernel/mmu.c | 2 +- kernel/msg_q.c | 2 +- kernel/mutex.c | 2 +- kernel/paging/statistics.c | 2 +- kernel/pipes.c | 2 +- kernel/poll.c | 2 +- kernel/queue.c | 2 +- kernel/sched.c | 2 +- kernel/sem.c | 2 +- kernel/stack.c | 2 +- kernel/thread.c | 2 +- kernel/timeout.c | 2 +- kernel/timer.c | 2 +- kernel/userspace.c | 2 +- kernel/userspace_handler.c | 2 +- lib/libc/arcmwdt/libc-hooks.c | 2 +- lib/libc/minimal/source/stdout/stdout_console.c | 2 +- lib/libc/newlib/libc-hooks.c | 2 +- lib/libc/picolibc/libc-hooks.c | 2 +- lib/os/fdtable.c | 2 +- lib/os/mutex.c | 2 +- lib/os/printk.c | 2 +- lib/os/sem.c | 2 +- lib/posix/clock.c | 2 +- samples/userspace/prod_consumer/src/app_syscall.c | 2 +- samples/userspace/prod_consumer/src/sample_driver_handlers.c | 2 +- scripts/build/gen_kobject_list.py | 2 +- subsys/logging/log_core.c | 2 +- subsys/logging/log_mgmt.c | 2 +- subsys/logging/log_msg.c | 2 +- subsys/mgmt/updatehub/updatehub_handlers.c | 2 +- subsys/net/ip/net_if.c | 2 +- subsys/net/ip/utils.c | 2 +- subsys/net/l2/ethernet/ethernet.c | 2 +- subsys/net/lib/sockets/getaddrinfo.c | 2 +- subsys/net/lib/sockets/socketpair.c | 2 +- subsys/net/lib/sockets/sockets.c | 2 +- subsys/net/lib/sockets/sockets_can.c | 2 +- subsys/net/lib/sockets/sockets_misc.c | 2 +- subsys/net/lib/sockets/sockets_net_mgmt.c | 2 +- subsys/net/lib/sockets/sockets_packet.c | 2 +- subsys/net/lib/sockets/sockets_select.c | 2 +- subsys/net/lib/sockets/sockets_tls.c | 2 +- subsys/random/rand32_handlers.c | 3 +-- subsys/rtio/rtio_handlers.c | 2 +- tests/arch/arm/arm_interrupt/src/arm_interrupt.c | 2 +- tests/arch/arm/arm_mem_protect/src/main.c | 2 +- tests/arch/arm/arm_sw_vector_relay/src/arm_sw_vector_relay.c | 2 +- tests/arch/arm/arm_thread_swap/src/arm_syscalls.c | 2 +- tests/arch/common/ramfunc/src/ramfunc.c | 2 +- tests/arch/x86/cpu_scrubs_regs/src/main.c | 2 +- tests/benchmarks/footprints/src/userspace.c | 2 +- tests/benchmarks/footprints/src/workq.c | 2 +- tests/kernel/fatal/exception/src/main.c | 2 +- tests/kernel/mem_protect/mem_protect/src/inherit.c | 2 +- tests/kernel/mem_protect/mem_protect/src/kobject.c | 2 +- tests/kernel/mem_protect/obj_validation/src/main.c | 2 +- tests/kernel/mem_protect/syscalls/src/main.c | 2 +- tests/kernel/mem_protect/userspace/src/main.c | 2 +- tests/kernel/threads/thread_stack/src/main.c | 2 +- tests/ztest/error_hook/src/main.c | 2 +- 118 files changed, 118 insertions(+), 119 deletions(-) rename include/zephyr/{ => internal}/syscall_handler.h (100%) diff --git a/arch/x86/core/userspace.c b/arch/x86/core/userspace.c index d0876749575..2b058206232 100644 --- a/arch/x86/core/userspace.c +++ b/arch/x86/core/userspace.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/doc/kernel/drivers/index.rst b/doc/kernel/drivers/index.rst index e835759d7ae..c1a31244701 100644 --- a/doc/kernel/drivers/index.rst +++ b/doc/kernel/drivers/index.rst @@ -235,7 +235,7 @@ implementation of both the subsystem API and the specific APIs: #ifdef CONFIG_USERSPACE - #include + #include int z_vrfy_specific_from_user(const struct device *dev, int bar) { diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index af16fbd2e4f..2b0abcc1a28 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -271,7 +271,7 @@ passed in. This includes: * Any other arguments that have a limited range of valid values. Verification functions involve a great deal of boilerplate code which has been -made simpler by some macros in :zephyr_file:`include/zephyr/syscall_handler.h`. +made simpler by some macros in :zephyr_file:`include/zephyr/internal/syscall_handler.h`. Verification functions should be declared using these macros. Argument Validation @@ -630,7 +630,7 @@ APIs **** Helper macros for creating system call verification functions are provided in -:zephyr_file:`include/zephyr/syscall_handler.h`: +:zephyr_file:`include/zephyr/internal/syscall_handler.h`: * :c:macro:`Z_SYSCALL_OBJ()` * :c:macro:`Z_SYSCALL_OBJ_INIT()` diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index cf6319a6264..184368c573c 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include static inline int z_vrfy_adc_channel_setup(const struct device *dev, diff --git a/drivers/auxdisplay/auxdisplay_handlers.c b/drivers/auxdisplay/auxdisplay_handlers.c index 8944b3da9ff..70ba310f970 100644 --- a/drivers/auxdisplay/auxdisplay_handlers.c +++ b/drivers/auxdisplay/auxdisplay_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_auxdisplay_display_on(const struct device *dev) { diff --git a/drivers/bbram/bbram_handlers.c b/drivers/bbram/bbram_handlers.c index 1bc20dcd359..cd173c63b0f 100644 --- a/drivers/bbram/bbram_handlers.c +++ b/drivers/bbram/bbram_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_bbram_check_invalid(const struct device *dev) { diff --git a/drivers/cache/cache_handlers.c b/drivers/cache/cache_handlers.c index 99d7cec501c..299e67baaaa 100644 --- a/drivers/cache/cache_handlers.c +++ b/drivers/cache/cache_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_sys_cache_data_flush_range(void *addr, size_t size) { diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 7401a7f9fd3..6eff63157e5 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *res, diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c index 7b658249a84..0f2200ea724 100644 --- a/drivers/charger/charger_handlers.c +++ b/drivers/charger/charger_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_charger_get_prop(const struct device *dev, const charger_prop_t prop, diff --git a/drivers/console/uart_mux.c b/drivers/console/uart_mux.c index ba882b038ee..ca445a1f5b7 100644 --- a/drivers/console/uart_mux.c +++ b/drivers/console/uart_mux.c @@ -10,7 +10,7 @@ LOG_MODULE_REGISTER(uart_mux, CONFIG_UART_MUX_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index a493ea0c765..10cc2b79b50 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include /* For those APIs that just take one argument which is a counter driver diff --git a/drivers/counter/maxim_ds3231.c b/drivers/counter/maxim_ds3231.c index 514ddd32b1a..518f989cede 100644 --- a/drivers/counter/maxim_ds3231.c +++ b/drivers/counter/maxim_ds3231.c @@ -1300,7 +1300,7 @@ DEVICE_DT_INST_DEFINE(0, ds3231_init, NULL, &ds3231_0_data, #ifdef CONFIG_USERSPACE -#include +#include int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, struct maxim_ds3231_syncpoint *syncpoint) diff --git a/drivers/dac/dac_handlers.c b/drivers/dac/dac_handlers.c index aa6660651e2..7db06aea11b 100644 --- a/drivers/dac/dac_handlers.c +++ b/drivers/dac/dac_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include static inline int z_vrfy_dac_channel_setup(const struct device *dev, diff --git a/drivers/dma/dma_handlers.c b/drivers/dma/dma_handlers.c index 058cbbf4623..e826b30521b 100644 --- a/drivers/dma/dma_handlers.c +++ b/drivers/dma/dma_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include /* Both of these APIs are assuming that the drive implementations are checking * the validity of the channel ID and returning -errno if it's bogus diff --git a/drivers/eeprom/eeprom_handlers.c b/drivers/eeprom/eeprom_handlers.c index 79e00d3a6fd..25aee5d874c 100644 --- a/drivers/eeprom/eeprom_handlers.c +++ b/drivers/eeprom/eeprom_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, diff --git a/drivers/entropy/entropy_handlers.c b/drivers/entropy/entropy_handlers.c index 7eb4dcba0c4..3bdff1d267b 100644 --- a/drivers/entropy/entropy_handlers.c +++ b/drivers/entropy/entropy_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_entropy_get_entropy(const struct device *dev, uint8_t *buffer, diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index d6800fe0f6e..ef90547c299 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_espi_config(const struct device *dev, diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index 6d639420294..d43a78891f9 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, diff --git a/drivers/flash/flash_npcx_fiu_nor.c b/drivers/flash/flash_npcx_fiu_nor.c index 6b99e832f24..a1b2d79b24d 100644 --- a/drivers/flash/flash_npcx_fiu_nor.c +++ b/drivers/flash/flash_npcx_fiu_nor.c @@ -14,7 +14,7 @@ #include #ifdef CONFIG_USERSPACE #include -#include +#include #endif #include "flash_npcx_fiu_qspi.h" diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 7f753b534f5..51a8afdb5ca 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -481,7 +481,7 @@ void *z_impl_flash_simulator_get_memory(const struct device *dev, #ifdef CONFIG_USERSPACE -#include +#include void *z_vrfy_flash_simulator_get_memory(const struct device *dev, size_t *mock_size) diff --git a/drivers/flash/flash_stm32_ex_op.c b/drivers/flash/flash_stm32_ex_op.c index 1e2d801ffa5..37bf73840f5 100644 --- a/drivers/flash/flash_stm32_ex_op.c +++ b/drivers/flash/flash_stm32_ex_op.c @@ -11,7 +11,7 @@ #ifdef CONFIG_USERSPACE #include -#include +#include #endif #include diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index e2ce6e6a706..a499ec63e10 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1464,7 +1464,7 @@ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) } #ifdef CONFIG_USERSPACE -#include +#include void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { diff --git a/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c index a6b8ce6ee02..2382fcad77b 100644 --- a/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/emul_fuel_gauge_syscall_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include /* Emulator syscalls just need to exist as stubs as these are only called by tests. */ diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 6bcd5bd2205..8fdb29de9f3 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop, diff --git a/drivers/gpio/gpio_handlers.c b/drivers/gpio/gpio_handlers.c index ce64fc87bda..019afff4c50 100644 --- a/drivers/gpio/gpio_handlers.c +++ b/drivers/gpio/gpio_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_gpio_pin_configure(const struct device *port, gpio_pin_t pin, diff --git a/drivers/hwinfo/hwinfo_handlers.c b/drivers/hwinfo/hwinfo_handlers.c index dd411f265d0..933e8499f4a 100644 --- a/drivers/hwinfo/hwinfo_handlers.c +++ b/drivers/hwinfo/hwinfo_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include ssize_t z_vrfy_hwinfo_get_device_id(uint8_t *buffer, size_t length) diff --git a/drivers/hwspinlock/hwspinlock_handlers.c b/drivers/hwspinlock/hwspinlock_handlers.c index a8e6c2a132e..8fd8c93424a 100644 --- a/drivers/hwspinlock/hwspinlock_handlers.c +++ b/drivers/hwspinlock/hwspinlock_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_hwspinlock_trylock(const struct device *dev, uint32_t id) { diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index fca385ee27b..1e5a5ee5d7b 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -6,7 +6,7 @@ #include #include -#include +#include static inline int z_vrfy_i2c_configure(const struct device *dev, uint32_t dev_config) diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index e556d708616..8e3315131b6 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index e5a5289868d..2fa8cff161d 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -6,7 +6,7 @@ #include #include -#include +#include static inline int z_vrfy_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) diff --git a/drivers/ipm/ipm_handlers.c b/drivers/ipm/ipm_handlers.c index 647f87c543f..021d80a17b3 100644 --- a/drivers/ipm/ipm_handlers.c +++ b/drivers/ipm/ipm_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_ipm_send(const struct device *dev, int wait, diff --git a/drivers/kscan/kscan_handlers.c b/drivers/kscan/kscan_handlers.c index b2d36ba3943..663930b4576 100644 --- a/drivers/kscan/kscan_handlers.c +++ b/drivers/kscan/kscan_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_kscan_config(const struct device *dev, kscan_callback_t callback_isr) diff --git a/drivers/led/led_handlers.c b/drivers/led/led_handlers.c index a3a37fb49e1..ecffa05be31 100644 --- a/drivers/led/led_handlers.c +++ b/drivers/led/led_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_led_blink(const struct device *dev, uint32_t led, diff --git a/drivers/mbox/mbox_handlers.c b/drivers/mbox/mbox_handlers.c index 55b2b010c83..f09beabb77a 100644 --- a/drivers/mbox/mbox_handlers.c +++ b/drivers/mbox/mbox_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, diff --git a/drivers/peci/peci_handlers.c b/drivers/peci/peci_handlers.c index 39147019d1c..758806aaecc 100644 --- a/drivers/peci/peci_handlers.c +++ b/drivers/peci/peci_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_peci_config(const struct device *dev, diff --git a/drivers/ps2/ps2_handlers.c b/drivers/ps2/ps2_handlers.c index 71d1181a2d2..a63f8937e9d 100644 --- a/drivers/ps2/ps2_handlers.c +++ b/drivers/ps2/ps2_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_ps2_config(const struct device *dev, ps2_callback_t callback_isr) diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c index ba0d7e373e9..8f4c3a171c8 100644 --- a/drivers/ptp_clock/ptp_clock.c +++ b/drivers/ptp_clock/ptp_clock.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #ifdef CONFIG_USERSPACE diff --git a/drivers/pwm/pwm_handlers.c b/drivers/pwm/pwm_handlers.c index 9993b24cf73..f6153458625 100644 --- a/drivers/pwm/pwm_handlers.c +++ b/drivers/pwm/pwm_handlers.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_pwm_set_cycles(const struct device *dev, diff --git a/drivers/retained_mem/retained_mem_handlers.c b/drivers/retained_mem/retained_mem_handlers.c index 265ae7b15fd..e69b2eeec67 100644 --- a/drivers/retained_mem/retained_mem_handlers.c +++ b/drivers/retained_mem/retained_mem_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev) { diff --git a/drivers/rtc/rtc_handlers.c b/drivers/rtc/rtc_handlers.c index a0e9cb34a8c..28c598f8e1a 100644 --- a/drivers/rtc/rtc_handlers.c +++ b/drivers/rtc/rtc_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) { diff --git a/drivers/sensor/sensor_handlers.c b/drivers/sensor/sensor_handlers.c index cc1bc84f03b..668bf2d5a81 100644 --- a/drivers/sensor/sensor_handlers.c +++ b/drivers/sensor/sensor_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_sensor_attr_set(const struct device *dev, enum sensor_channel chan, diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 1dd4dd78f10..4f2ac834f71 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define UART_SIMPLE(op_) \ static inline int z_vrfy_uart_##op_(const struct device *dev) \ diff --git a/drivers/sip_svc/sip_smc_intel_socfpga.c b/drivers/sip_svc/sip_smc_intel_socfpga.c index b4db6d48a86..09d351798e3 100644 --- a/drivers/sip_svc/sip_smc_intel_socfpga.c +++ b/drivers/sip_svc/sip_smc_intel_socfpga.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/smbus/smbus_handlers.c b/drivers/smbus/smbus_handlers.c index 0c979788830..a2ed656105b 100644 --- a/drivers/smbus/smbus_handlers.c +++ b/drivers/smbus/smbus_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include static inline int z_vrfy_smbus_configure(const struct device *dev, diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index 7793d6b8a3a..dd1a1eb7d6f 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include /* This assumes that bufs and buf_copy are copies from the values passed diff --git a/drivers/usb/bc12/bc12_handlers.c b/drivers/usb/bc12/bc12_handlers.c index bf7ff8fcf39..bd578ff6894 100644 --- a/drivers/usb/bc12/bc12_handlers.c +++ b/drivers/usb/bc12/bc12_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_bc12_set_role(const struct device *dev, enum bc12_role role) { diff --git a/drivers/virtualization/virt_ivshmem_handlers.c b/drivers/virtualization/virt_ivshmem_handlers.c index bd49b8949eb..d102a56577f 100644 --- a/drivers/virtualization/virt_ivshmem_handlers.c +++ b/drivers/virtualization/virt_ivshmem_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, diff --git a/drivers/w1/w1_handlers.c b/drivers/w1/w1_handlers.c index 5eac465c383..a22446aac4a 100644 --- a/drivers/w1/w1_handlers.c +++ b/drivers/w1/w1_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include static inline int z_vrfy_w1_reset_bus(const struct device *dev) diff --git a/drivers/watchdog/wdt_handlers.c b/drivers/watchdog/wdt_handlers.c index 2af07851443..8afa81c67e6 100644 --- a/drivers/watchdog/wdt_handlers.c +++ b/drivers/watchdog/wdt_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include static inline int z_vrfy_wdt_setup(const struct device *dev, uint8_t options) { diff --git a/include/zephyr/syscall_handler.h b/include/zephyr/internal/syscall_handler.h similarity index 100% rename from include/zephyr/syscall_handler.h rename to include/zephyr/internal/syscall_handler.h diff --git a/kernel/atomic_c.c b/kernel/atomic_c.c index ef6e759a8b5..a9d2765e857 100644 --- a/kernel/atomic_c.c +++ b/kernel/atomic_c.c @@ -37,7 +37,7 @@ static struct k_spinlock lock; * forbidden. */ #ifdef CONFIG_USERSPACE -#include +#include #define ATOMIC_SYSCALL_HANDLER_TARGET(name) \ static inline atomic_val_t z_vrfy_##name(atomic_t *target) \ diff --git a/kernel/condvar.c b/kernel/condvar.c index e62fd27acce..edd895ed0e1 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_OBJ_CORE_CONDVAR diff --git a/kernel/device.c b/kernel/device.c index 8a07e4a9b23..399bd7f3022 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include /** diff --git a/kernel/dynamic.c b/kernel/dynamic.c index 5215e83fa77..3fea6b68c56 100644 --- a/kernel/dynamic.c +++ b/kernel/dynamic.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/kernel/errno.c b/kernel/errno.c index 37866819bf5..645597f02c7 100644 --- a/kernel/errno.c +++ b/kernel/errno.c @@ -13,7 +13,7 @@ */ #include -#include +#include /* * Define _k_neg_eagain for use in assembly files as errno.h is diff --git a/kernel/events.c b/kernel/events.c index 513559ced0f..39ca6fd8d50 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include /* private kernel APIs */ diff --git a/kernel/futex.c b/kernel/futex.c index 360d2a99412..f0f5e5aecbc 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/mmu.c b/kernel/mmu.c index 8c742bc36ae..6abd9349dd6 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 3f56c095fcd..1d5f3aff9df 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/mutex.c b/kernel/mutex.c index f94fa430508..7759ab55bbc 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/paging/statistics.c b/kernel/paging/statistics.c index f1017687f3e..8a2d3c6ed34 100644 --- a/kernel/paging/statistics.c +++ b/kernel/paging/statistics.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/kernel/pipes.c b/kernel/pipes.c index c19b0e500c0..b3050b66664 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/poll.c b/kernel/poll.c index 3727a2ba9f3..ed0a99664da 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/queue.c b/kernel/queue.c index 095ea077878..d86899c50c3 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/sched.c b/kernel/sched.c index 12393c0eada..e724ccc87ad 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/sem.c b/kernel/sem.c index c411d9b63c2..91d64970f36 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/stack.c b/kernel/stack.c index dc6d1a6bfa1..5e00b76e509 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_OBJ_CORE_STACK diff --git a/kernel/thread.c b/kernel/thread.c index 4a54fd5dd29..31e2563bb30 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/timeout.c b/kernel/timeout.c index 339bc65a014..16429bbba20 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/timer.c b/kernel/timer.c index 1dc60dbe7ca..bd69e35b027 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/kernel/userspace.c b/kernel/userspace.c index f98654493a5..6a4a65a8ada 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index ec59ca54c53..ea0d761db48 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/lib/libc/arcmwdt/libc-hooks.c b/lib/libc/arcmwdt/libc-hooks.c index b7ee5f90a81..223c740a63a 100644 --- a/lib/libc/arcmwdt/libc-hooks.c +++ b/lib/libc/arcmwdt/libc-hooks.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/libc/minimal/source/stdout/stdout_console.c b/lib/libc/minimal/source/stdout/stdout_console.c index 8db7528497e..fd09b87110a 100644 --- a/lib/libc/minimal/source/stdout/stdout_console.c +++ b/lib/libc/minimal/source/stdout/stdout_console.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include static int _stdout_hook_default(int c) diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index 1769e32dc14..00ebd8607c0 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/libc/picolibc/libc-hooks.c b/lib/libc/picolibc/libc-hooks.c index 8df622c492c..ab90ab8b047 100644 --- a/lib/libc/picolibc/libc-hooks.c +++ b/lib/libc/picolibc/libc-hooks.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index b261c958de2..ccb14fa58e6 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include struct fd_entry { diff --git a/lib/os/mutex.c b/lib/os/mutex.c index b2284f076d9..fb18c9650b7 100644 --- a/lib/os/mutex.c +++ b/lib/os/mutex.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include static struct k_mutex *get_k_mutex(struct sys_mutex *mutex) diff --git a/lib/os/printk.c b/lib/os/printk.c index 0701f8a3a6f..279b7067b0a 100644 --- a/lib/os/printk.c +++ b/lib/os/printk.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/os/sem.c b/lib/os/sem.c index 132a0c834a8..b01ead58e50 100644 --- a/lib/os/sem.c +++ b/lib/os/sem.c @@ -5,7 +5,7 @@ */ #include -#include +#include #ifdef CONFIG_USERSPACE #define SYS_SEM_MINIMUM 0 diff --git a/lib/posix/clock.c b/lib/posix/clock.c index 51812ed53bc..50742545b20 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include /* diff --git a/samples/userspace/prod_consumer/src/app_syscall.c b/samples/userspace/prod_consumer/src/app_syscall.c index 0f66c54c159..dc726096eda 100644 --- a/samples/userspace/prod_consumer/src/app_syscall.c +++ b/samples/userspace/prod_consumer/src/app_syscall.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include LOG_MODULE_REGISTER(app_syscall); diff --git a/samples/userspace/prod_consumer/src/sample_driver_handlers.c b/samples/userspace/prod_consumer/src/sample_driver_handlers.c index 8531b2b88f3..1f9dc610af3 100644 --- a/samples/userspace/prod_consumer/src/sample_driver_handlers.c +++ b/samples/userspace/prod_consumer/src/sample_driver_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include "sample_driver.h" int z_vrfy_sample_driver_state_set(const struct device *dev, bool active) diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index db274c19b3a..6bd12010414 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -724,7 +724,7 @@ def get_symbols(elf): %{ #include #include -#include +#include #include %} struct k_object; diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index 7ba2cde3c77..8f5e33e1e1e 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/subsys/logging/log_mgmt.c b/subsys/logging/log_mgmt.c index 08de43165bc..198433ff478 100644 --- a/subsys/logging/log_mgmt.c +++ b/subsys/logging/log_mgmt.c @@ -5,7 +5,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 12ca9883d8b..a28f1ddc10a 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include #include #include #include diff --git a/subsys/mgmt/updatehub/updatehub_handlers.c b/subsys/mgmt/updatehub/updatehub_handlers.c index 33a0d4acac6..4d889731758 100644 --- a/subsys/mgmt/updatehub/updatehub_handlers.c +++ b/subsys/mgmt/updatehub/updatehub_handlers.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index acf5d628b9d..b5887b1da86 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index 688784f5421..592d391f6a4 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(net_utils, CONFIG_NET_UTILS_LOG_LEVEL); #include #include -#include +#include #include #include #include diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index 97990dbc451..2be3c5f2820 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_ethernet, CONFIG_NET_L2_ETHERNET_LOG_LEVEL); #include #endif -#include +#include #include "arp.h" #include "eth_stats.h" diff --git a/subsys/net/lib/sockets/getaddrinfo.c b/subsys/net/lib/sockets/getaddrinfo.c index 2a499dcebb0..2acee2734e1 100644 --- a/subsys/net/lib/sockets/getaddrinfo.c +++ b/subsys/net/lib/sockets/getaddrinfo.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(net_sock_addr, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #if defined(CONFIG_DNS_RESOLVER) || defined(CONFIG_NET_IP) #define ANY_RESOLVER diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index fad4f7aa71f..ca9d78b43af 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index ba59cc98d9e..12b8d02543b 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); #else #include #endif -#include +#include #include #include #include diff --git a/subsys/net/lib/sockets/sockets_can.c b/subsys/net/lib/sockets/sockets_can.c index 5e05440d2c0..d4856a7a4be 100644 --- a/subsys/net/lib/sockets/sockets_can.c +++ b/subsys/net/lib/sockets/sockets_can.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(net_sock_can, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/lib/sockets/sockets_misc.c b/subsys/net/lib/sockets/sockets_misc.c index 9729fca19fb..fcc42834438 100644 --- a/subsys/net/lib/sockets/sockets_misc.c +++ b/subsys/net/lib/sockets/sockets_misc.c @@ -6,7 +6,7 @@ #include #include -#include +#include int z_impl_zsock_gethostname(char *buf, size_t len) { diff --git a/subsys/net/lib/sockets/sockets_net_mgmt.c b/subsys/net/lib/sockets/sockets_net_mgmt.c index 91e13ec415b..11b06b8863f 100644 --- a/subsys/net/lib/sockets/sockets_net_mgmt.c +++ b/subsys/net/lib/sockets/sockets_net_mgmt.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(net_sock_mgmt, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include #include #include diff --git a/subsys/net/lib/sockets/sockets_packet.c b/subsys/net/lib/sockets/sockets_packet.c index 1d3d47975d9..bcf063abe29 100644 --- a/subsys/net/lib/sockets/sockets_packet.c +++ b/subsys/net/lib/sockets/sockets_packet.c @@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(net_sock_packet, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include #include "../../ip/net_stats.h" diff --git a/subsys/net/lib/sockets/sockets_select.c b/subsys/net/lib/sockets/sockets_select.c index 31c98416b81..f354fd45594 100644 --- a/subsys/net/lib/sockets/sockets_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include "sockets_internal.h" diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index e0d44b68df2..14b1de26af3 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -19,7 +19,7 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include -#include +#include #include /* TODO: Remove all direct access to private fields. diff --git a/subsys/random/rand32_handlers.c b/subsys/random/rand32_handlers.c index 52130110be7..06e45bdc592 100644 --- a/subsys/random/rand32_handlers.c +++ b/subsys/random/rand32_handlers.c @@ -5,8 +5,7 @@ */ #include -#include - +#include static inline uint32_t z_vrfy_sys_rand32_get(void) { diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_handlers.c index 3be7f2f9f86..39ead483005 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_handlers.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include /** * Verify each SQE type operation and its fields ensuring diff --git a/tests/arch/arm/arm_interrupt/src/arm_interrupt.c b/tests/arch/arm/arm_interrupt/src/arm_interrupt.c index cf9e34109dc..1bbfe08bc01 100644 --- a/tests/arch/arm/arm_interrupt/src/arm_interrupt.c +++ b/tests/arch/arm/arm_interrupt/src/arm_interrupt.c @@ -382,7 +382,7 @@ ZTEST(arm_interrupt, test_arm_interrupt) } #if defined(CONFIG_USERSPACE) -#include +#include #include "test_syscalls.h" void z_impl_test_arm_user_interrupt_syscall(void) diff --git a/tests/arch/arm/arm_mem_protect/src/main.c b/tests/arch/arm/arm_mem_protect/src/main.c index 45e2314a989..83b96cf9d0f 100644 --- a/tests/arch/arm/arm_mem_protect/src/main.c +++ b/tests/arch/arm/arm_mem_protect/src/main.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include ZTEST_BMEM char user_stack[256]; diff --git a/tests/arch/arm/arm_sw_vector_relay/src/arm_sw_vector_relay.c b/tests/arch/arm/arm_sw_vector_relay/src/arm_sw_vector_relay.c index c728864c05f..be400746d92 100644 --- a/tests/arch/arm/arm_sw_vector_relay/src/arm_sw_vector_relay.c +++ b/tests/arch/arm/arm_sw_vector_relay/src/arm_sw_vector_relay.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c b/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c index 71fd8fcf456..e32de6ca726 100644 --- a/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c +++ b/tests/arch/arm/arm_thread_swap/src/arm_syscalls.c @@ -29,7 +29,7 @@ static struct k_thread user_thread; static K_THREAD_STACK_DEFINE(user_thread_stack, 1024); -#include +#include #include "test_syscalls.h" void z_impl_test_arm_user_syscall(void) diff --git a/tests/arch/common/ramfunc/src/ramfunc.c b/tests/arch/common/ramfunc/src/ramfunc.c index 7f7bb28c0ce..cd55c653618 100644 --- a/tests/arch/common/ramfunc/src/ramfunc.c +++ b/tests/arch/common/ramfunc/src/ramfunc.c @@ -6,7 +6,7 @@ #include #include -#include +#include static volatile int test_flag; diff --git a/tests/arch/x86/cpu_scrubs_regs/src/main.c b/tests/arch/x86/cpu_scrubs_regs/src/main.c index bddcc4f7929..6c27f73cd1b 100644 --- a/tests/arch/x86/cpu_scrubs_regs/src/main.c +++ b/tests/arch/x86/cpu_scrubs_regs/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include "test_syscalls.h" diff --git a/tests/benchmarks/footprints/src/userspace.c b/tests/benchmarks/footprints/src/userspace.c index 231c4279137..c4e51ccff67 100644 --- a/tests/benchmarks/footprints/src/userspace.c +++ b/tests/benchmarks/footprints/src/userspace.c @@ -11,7 +11,7 @@ */ #include #include -#include +#include #include #include "footprint.h" diff --git a/tests/benchmarks/footprints/src/workq.c b/tests/benchmarks/footprints/src/workq.c index a00afd732a8..2ad2d0152c7 100644 --- a/tests/benchmarks/footprints/src/workq.c +++ b/tests/benchmarks/footprints/src/workq.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include "footprint.h" diff --git a/tests/kernel/fatal/exception/src/main.c b/tests/kernel/fatal/exception/src/main.c index 51b338183e6..79c793ebf11 100644 --- a/tests/kernel/fatal/exception/src/main.c +++ b/tests/kernel/fatal/exception/src/main.c @@ -14,7 +14,7 @@ #if defined(CONFIG_USERSPACE) #include -#include +#include #include "test_syscalls.h" #endif diff --git a/tests/kernel/mem_protect/mem_protect/src/inherit.c b/tests/kernel/mem_protect/mem_protect/src/inherit.c index fc3cb736abe..8925535ef33 100644 --- a/tests/kernel/mem_protect/mem_protect/src/inherit.c +++ b/tests/kernel/mem_protect/mem_protect/src/inherit.c @@ -5,7 +5,7 @@ */ #include "mem_protect.h" -#include +#include #include /* for z_libc_partition */ /* function prototypes */ diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 76ed3f5a5b7..7deae8b31c2 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -5,7 +5,7 @@ */ #include "mem_protect.h" -#include +#include /* Kernel objects */ diff --git a/tests/kernel/mem_protect/obj_validation/src/main.c b/tests/kernel/mem_protect/obj_validation/src/main.c index 9cc74a36063..bd28b9e4295 100644 --- a/tests/kernel/mem_protect/obj_validation/src/main.c +++ b/tests/kernel/mem_protect/obj_validation/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 2e03c409065..23d987e747c 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include "test_syscalls.h" diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 7c0289ab16b..5a23e0c96e7 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "test_syscall.h" #include /* for z_libc_partition */ diff --git a/tests/kernel/threads/thread_stack/src/main.c b/tests/kernel/threads/thread_stack/src/main.c index 9a3a01a1cf0..19c54a052ea 100644 --- a/tests/kernel/threads/thread_stack/src/main.c +++ b/tests/kernel/threads/thread_stack/src/main.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include "test_syscall.h" diff --git a/tests/ztest/error_hook/src/main.c b/tests/ztest/error_hook/src/main.c index 560171ac365..cba35ce46b4 100644 --- a/tests/ztest/error_hook/src/main.c +++ b/tests/ztest/error_hook/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include From 4d5d04169d9ec178ee16da89bc60b5a5f3eae020 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 12:06:49 +0000 Subject: [PATCH 3008/4498] syscall: rename z_is_in_user_syscall Rename z_is_in_user_syscall -> k_is_in_user_syscall Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- subsys/net/lib/sockets/sockets.c | 2 +- tests/kernel/mem_protect/syscalls/src/main.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 8bff82e9557..bbacba74a07 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -46,7 +46,7 @@ enum _obj_init_check { * @return whether the current context is handling a syscall for a user * mode thread */ -static inline bool z_is_in_user_syscall(void) +static inline bool k_is_in_user_syscall(void) { /* This gets set on entry to the syscall's generasted z_mrsh * function and then cleared on exit. This code path is only diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 12b8d02543b..6afd4888728 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -78,7 +78,7 @@ static inline void *get_sock_vtable(int sock, lock); #ifdef CONFIG_USERSPACE - if (ctx != NULL && z_is_in_user_syscall()) { + if (ctx != NULL && k_is_in_user_syscall()) { if (!k_object_is_valid(ctx, K_OBJ_NET_SOCKET)) { /* Invalidate the context, the caller doesn't have * sufficient permission or there was some other diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 23d987e747c..35279e59a1a 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -410,7 +410,7 @@ ZTEST(syscalls, test_syscall_torture) bool z_impl_syscall_context(void) { - return z_is_in_user_syscall(); + return k_is_in_user_syscall(); } static inline bool z_vrfy_syscall_context(void) @@ -433,7 +433,7 @@ void test_syscall_context_user(void *p1, void *p2, void *p3) ZTEST(syscalls, test_syscall_context) { /* We're a regular supervisor thread. */ - zassert_false(z_is_in_user_syscall(), + zassert_false(k_is_in_user_syscall(), "reported in user syscall when in supv. thread ctx"); /* Make a system call from supervisor mode. The check in the From 684b8fcdd0fa7e91c64fc20bdc49a10aac4fd34d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:41:51 +0000 Subject: [PATCH 3009/4498] syscall: Z_SYSCALL_VERIFY_MSG -> K_SYSCALL_VERIFY_MSG Rename macros and do not use Z_ for internal APIs. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 4 ++-- drivers/adc/adc_handlers.c | 8 ++++---- drivers/can/can_handlers.c | 2 +- drivers/counter/counter_handlers.c | 4 ++-- drivers/kscan/kscan_handlers.c | 2 +- drivers/ps2/ps2_handlers.c | 2 +- drivers/usb/bc12/bc12_handlers.c | 2 +- drivers/w1/w1_handlers.c | 2 +- include/zephyr/internal/syscall_handler.h | 14 +++++++------- kernel/poll.c | 2 +- kernel/sched.c | 10 +++++----- kernel/thread.c | 6 +++--- kernel/userspace_handler.c | 4 ++-- subsys/logging/log_mgmt.c | 8 ++++---- 14 files changed, 35 insertions(+), 35 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 2b0abcc1a28..42dd7dfa067 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -309,7 +309,7 @@ Several macros exist to validate arguments: :c:macro:`Z_SYSCALL_MEMORY_ARRAY_READ()` but the calling thread must additionally have write permissions. -* :c:macro:`Z_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean +* :c:macro:`K_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean expression which must evaluate to true otherwise the check will fail. A variant :c:macro:`Z_SYSCALL_VERIFY` exists which does not take a message parameter, instead printing the expression tested if it @@ -640,7 +640,7 @@ Helper macros for creating system call verification functions are provided in * :c:macro:`Z_SYSCALL_MEMORY_WRITE()` * :c:macro:`Z_SYSCALL_MEMORY_ARRAY_READ()` * :c:macro:`Z_SYSCALL_MEMORY_ARRAY_WRITE()` -* :c:macro:`Z_SYSCALL_VERIFY_MSG()` +* :c:macro:`K_SYSCALL_VERIFY_MSG()` * :c:macro:`Z_SYSCALL_VERIFY` Functions for invoking system calls are defined in diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index 184368c573c..7ac7d5442d1 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -56,11 +56,11 @@ static inline int z_vrfy_adc_read(const struct device *dev, struct adc_sequence_options options; Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, + Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); if (sequence.options != NULL) { - Z_OOPS(Z_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, "ADC sequence callbacks forbidden from user mode")); } @@ -77,11 +77,11 @@ static inline int z_vrfy_adc_read_async(const struct device *dev, struct adc_sequence_options options; Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read_async)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, + Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); if (sequence.options != NULL) { - Z_OOPS(Z_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, "ADC sequence callbacks forbidden from user mode")); } Z_OOPS(Z_SYSCALL_OBJ(async, K_OBJ_POLL_SIGNAL)); diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 6eff63157e5..e8338e6716e 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -189,7 +189,7 @@ static inline int z_vrfy_can_send(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, send)); Z_OOPS(z_user_from_copy(&frame_copy, frame, sizeof(frame_copy))); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); + Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); return z_impl_can_send(dev, &frame_copy, timeout, callback, user_data); } diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 10cc2b79b50..58adcd0e1f0 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -90,7 +90,7 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); Z_OOPS(z_user_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_channel_alarm((const struct device *)dev, (uint8_t)chan_id, @@ -116,7 +116,7 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); Z_OOPS(z_user_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_top_value((const struct device *)dev, (const struct counter_top_cfg *) diff --git a/drivers/kscan/kscan_handlers.c b/drivers/kscan/kscan_handlers.c index 663930b4576..4892e420530 100644 --- a/drivers/kscan/kscan_handlers.c +++ b/drivers/kscan/kscan_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_kscan_config(const struct device *dev, kscan_callback_t callback_isr) { Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, config)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback_isr == 0, + Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == 0, "callback cannot be set from user mode")); return z_impl_kscan_config((const struct device *)dev, callback_isr); } diff --git a/drivers/ps2/ps2_handlers.c b/drivers/ps2/ps2_handlers.c index a63f8937e9d..987ac1e620b 100644 --- a/drivers/ps2/ps2_handlers.c +++ b/drivers/ps2/ps2_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_ps2_config(const struct device *dev, ps2_callback_t callback_isr) { Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, config)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback_isr == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == NULL, "callback not be set from user mode")); return z_impl_ps2_config(dev, callback_isr); } diff --git a/drivers/usb/bc12/bc12_handlers.c b/drivers/usb/bc12/bc12_handlers.c index bd578ff6894..55a61b76fed 100644 --- a/drivers/usb/bc12/bc12_handlers.c +++ b/drivers/usb/bc12/bc12_handlers.c @@ -18,7 +18,7 @@ static inline int z_vrfy_bc12_set_result_cb(const struct device *dev, bc12_callb void *user_data) { Z_OOPS(Z_SYSCALL_DRIVER_BC12(dev, set_result_cb)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(cb == NULL, "callbacks may not be set from user mode")); + Z_OOPS(K_SYSCALL_VERIFY_MSG(cb == NULL, "callbacks may not be set from user mode")); return z_impl_bc12_set_result_cb(dev, cb, user_data); } diff --git a/drivers/w1/w1_handlers.c b/drivers/w1/w1_handlers.c index a22446aac4a..b6735c6064a 100644 --- a/drivers/w1/w1_handlers.c +++ b/drivers/w1/w1_handlers.c @@ -102,7 +102,7 @@ static inline int z_vrfy_w1_search_bus(const struct device *dev, { Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback == 0, + Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == 0, "callbacks may not be set from user mode")); /* user_data is not dereferenced, no need to check parameter */ diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index bbacba74a07..8e81c06c5b3 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -308,7 +308,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); * arguments) to print on verification failure * @return False on success, True on failure */ -#define Z_SYSCALL_VERIFY_MSG(expr, fmt, ...) ({ \ +#define K_SYSCALL_VERIFY_MSG(expr, fmt, ...) ({ \ bool expr_copy = !(expr); \ if (expr_copy) { \ TOOLCHAIN_IGNORE_WSHADOW_BEGIN \ @@ -329,7 +329,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); * oops. A stringified version of this expression will be printed. * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_VERIFY(expr) Z_SYSCALL_VERIFY_MSG(expr, #expr) +#define Z_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr) /** * @brief Runtime check that a user thread has read and/or write permission to @@ -348,7 +348,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); * @return 0 on success, nonzero on failure */ #define Z_SYSCALL_MEMORY(ptr, size, write) \ - Z_SYSCALL_VERIFY_MSG(arch_buffer_validate((void *)ptr, size, write) \ + K_SYSCALL_VERIFY_MSG(arch_buffer_validate((void *)ptr, size, write) \ == 0, \ "Memory region %p (size %zu) %s access denied", \ (void *)(ptr), (size_t)(size), \ @@ -389,7 +389,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ ({ \ size_t product; \ - Z_SYSCALL_VERIFY_MSG(!size_mul_overflow((size_t)(nmemb), \ + K_SYSCALL_VERIFY_MSG(!size_mul_overflow((size_t)(nmemb), \ (size_t)(size), \ &product), \ "%zux%zu array is too large", \ @@ -448,7 +448,7 @@ static inline int z_obj_validation_check(struct k_object *ko, } #define Z_SYSCALL_IS_OBJ(ptr, type, init) \ - Z_SYSCALL_VERIFY_MSG(z_obj_validation_check( \ + K_SYSCALL_VERIFY_MSG(z_obj_validation_check( \ z_object_find((const void *)ptr), \ (const void *)ptr, \ type, init) == 0, "access denied") @@ -467,7 +467,7 @@ static inline int z_obj_validation_check(struct k_object *ko, ({ \ struct api_name *__device__ = (struct api_name *) \ ((const struct device *)ptr)->api; \ - Z_SYSCALL_VERIFY_MSG(__device__->op != NULL, \ + K_SYSCALL_VERIFY_MSG(__device__->op != NULL, \ "Operation %s not defined for driver " \ "instance %p", \ # op, __device__); \ @@ -495,7 +495,7 @@ static inline int z_obj_validation_check(struct k_object *ko, ({ \ const struct device *_dev = (const struct device *)_device; \ Z_SYSCALL_OBJ(_dev, _dtype) || \ - Z_SYSCALL_VERIFY_MSG(_dev->api == _api, \ + K_SYSCALL_VERIFY_MSG(_dev->api == _api, \ "API structure mismatch"); \ }) diff --git a/kernel/poll.c b/kernel/poll.c index ed0a99664da..4614367b8f4 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -368,7 +368,7 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, ret = -EINVAL; goto out; } - if (Z_SYSCALL_VERIFY_MSG(!u32_mul_overflow(num_events, + if (K_SYSCALL_VERIFY_MSG(!u32_mul_overflow(num_events, sizeof(struct k_poll_event), &bounds), "num_events too large")) { diff --git a/kernel/sched.c b/kernel/sched.c index e724ccc87ad..f3a5c92d7f6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1359,9 +1359,9 @@ void z_impl_k_thread_priority_set(k_tid_t thread, int prio) static inline void z_vrfy_k_thread_priority_set(k_tid_t thread, int prio) { Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), + Z_OOPS(K_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), "invalid thread priority %d", prio)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG((int8_t)prio >= thread->base.prio, + Z_OOPS(K_SYSCALL_VERIFY_MSG((int8_t)prio >= thread->base.prio, "thread priority may only be downgraded (%d < %d)", prio, thread->base.prio)); @@ -1390,7 +1390,7 @@ static inline void z_vrfy_k_thread_deadline_set(k_tid_t tid, int deadline) struct k_thread *thread = tid; Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(deadline > 0, + Z_OOPS(K_SYSCALL_VERIFY_MSG(deadline > 0, "invalid thread deadline %d", (int)deadline)); @@ -1890,7 +1890,7 @@ static bool thread_obj_validate(struct k_thread *thread) #ifdef CONFIG_LOG z_dump_object_error(ret, thread, ko, K_OBJ_THREAD); #endif - Z_OOPS(Z_SYSCALL_VERIFY_MSG(ret, "access denied")); + Z_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied")); } CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } @@ -1912,7 +1912,7 @@ static inline void z_vrfy_k_thread_abort(k_tid_t thread) return; } - Z_OOPS(Z_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), + Z_OOPS(K_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), "aborting essential thread %p", thread)); z_impl_k_thread_abort((struct k_thread *)thread); diff --git a/kernel/thread.c b/kernel/thread.c index 31e2563bb30..fc0d725219f 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -734,7 +734,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, * object table if it isn't */ stack_object = z_object_find(stack); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(z_obj_validation_check(stack_object, stack, + Z_OOPS(K_SYSCALL_VERIFY_MSG(z_obj_validation_check(stack_object, stack, K_OBJ_THREAD_STACK_ELEMENT, _OBJ_INIT_FALSE) == 0, "bad stack object")); @@ -742,7 +742,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, /* Verify that the stack size passed in is OK by computing the total * size and comparing it with the size value in the object metadata */ - Z_OOPS(Z_SYSCALL_VERIFY_MSG(!size_add_overflow(K_THREAD_STACK_RESERVED, + Z_OOPS(K_SYSCALL_VERIFY_MSG(!size_add_overflow(K_THREAD_STACK_RESERVED, stack_size, &total_size), "stack size overflow (%zu+%zu)", stack_size, @@ -756,7 +756,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, #else stack_obj_size = stack_object->data.stack_size; #endif - Z_OOPS(Z_SYSCALL_VERIFY_MSG(total_size <= stack_obj_size, + Z_OOPS(K_SYSCALL_VERIFY_MSG(total_size <= stack_obj_size, "stack size %zu is too big, max is %zu", total_size, stack_obj_size)); diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index ea0d761db48..a8457b3c0e5 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -60,7 +60,7 @@ static inline void z_vrfy_k_object_access_grant(const void *object, Z_OOPS(Z_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); ko = validate_any_object(object); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", + Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", object)); z_thread_perms_set(ko, thread); } @@ -71,7 +71,7 @@ static inline void z_vrfy_k_object_release(const void *object) struct k_object *ko; ko = validate_any_object((void *)object); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", + Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", (void *)object)); z_thread_perms_clear(ko, _current); } diff --git a/subsys/logging/log_mgmt.c b/subsys/logging/log_mgmt.c index 198433ff478..eb7d82f483a 100644 --- a/subsys/logging/log_mgmt.c +++ b/subsys/logging/log_mgmt.c @@ -449,13 +449,13 @@ uint32_t z_vrfy_log_filter_set(struct log_backend const *const backend, int16_t src_id, uint32_t level) { - Z_OOPS(Z_SYSCALL_VERIFY_MSG(backend == NULL, + Z_OOPS(K_SYSCALL_VERIFY_MSG(backend == NULL, "Setting per-backend filters from user mode is not supported")); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(domain_id == Z_LOG_LOCAL_DOMAIN_ID, + Z_OOPS(K_SYSCALL_VERIFY_MSG(domain_id == Z_LOG_LOCAL_DOMAIN_ID, "Invalid log domain_id")); - Z_OOPS(Z_SYSCALL_VERIFY_MSG(src_id < (int16_t)log_src_cnt_get(domain_id), + Z_OOPS(K_SYSCALL_VERIFY_MSG(src_id < (int16_t)log_src_cnt_get(domain_id), "Invalid log source id")); - Z_OOPS(Z_SYSCALL_VERIFY_MSG( + Z_OOPS(K_SYSCALL_VERIFY_MSG( (level <= LOG_LEVEL_DBG), "Invalid log level")); From 412561b62aa894f82d0b2a2ed8367eb2fac4f7cc Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:42:36 +0000 Subject: [PATCH 3010/4498] syscall: Z_SYSCALL_IS_OBJ -> K_SYSCALL_IS_OBJ Rename macros and do not use Z_ for internal APIs. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 8e81c06c5b3..adb4f1cbb73 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -447,7 +447,7 @@ static inline int z_obj_validation_check(struct k_object *ko, return ret; } -#define Z_SYSCALL_IS_OBJ(ptr, type, init) \ +#define K_SYSCALL_IS_OBJ(ptr, type, init) \ K_SYSCALL_VERIFY_MSG(z_obj_validation_check( \ z_object_find((const void *)ptr), \ (const void *)ptr, \ @@ -511,7 +511,7 @@ static inline int z_obj_validation_check(struct k_object *ko, * @return 0 on success, nonzero on failure */ #define Z_SYSCALL_OBJ(ptr, type) \ - Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE) + K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE) /** * @brief Runtime check kernel object pointer for non-init functions @@ -525,7 +525,7 @@ static inline int z_obj_validation_check(struct k_object *ko, */ #define Z_SYSCALL_OBJ_INIT(ptr, type) \ - Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY) + K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY) /** * @brief Runtime check kernel object pointer for non-init functions @@ -541,7 +541,7 @@ static inline int z_obj_validation_check(struct k_object *ko, */ #define Z_SYSCALL_OBJ_NEVER_INIT(ptr, type) \ - Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE) + K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE) #include From df9428991a14d4aaf6bbdd30b94ba9e3a6456555 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:43:36 +0000 Subject: [PATCH 3011/4498] syscall: Z_SYSCALL_MEMORY_ARRAY -> K_SYSCALL_MEMORY_ARRAY Rename macros and do not use Z_ for internal APIs. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 10 +++++----- drivers/i2c/i2c_handlers.c | 2 +- drivers/i3c/i3c_handlers.c | 10 +++++----- drivers/serial/uart_handlers.c | 4 ++-- drivers/spi/spi_handlers.c | 2 +- include/zephyr/internal/syscall_handler.h | 10 +++++----- lib/libc/minimal/source/stdout/stdout_console.c | 2 +- subsys/net/lib/sockets/getaddrinfo.c | 2 +- subsys/rtio/rtio_handlers.c | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 42dd7dfa067..07629589a46 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -299,14 +299,14 @@ Several macros exist to validate arguments: :c:macro:`Z_SYSCALL_MEMORY_READ()` but the calling thread must additionally have write permissions. -* :c:macro:`Z_SYSCALL_MEMORY_ARRAY_READ()` validates an array whose total size +* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` validates an array whose total size is expressed as separate arguments for the number of elements and the element size. This macro correctly accounts for multiplication overflow when computing the total size. The calling thread must have read permissions on the total size. -* :c:macro:`Z_SYSCALL_MEMORY_ARRAY_WRITE()` is the same as - :c:macro:`Z_SYSCALL_MEMORY_ARRAY_READ()` but the calling thread must +* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` is the same as + :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` but the calling thread must additionally have write permissions. * :c:macro:`K_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean @@ -638,8 +638,8 @@ Helper macros for creating system call verification functions are provided in * :c:macro:`Z_OOPS()` * :c:macro:`Z_SYSCALL_MEMORY_READ()` * :c:macro:`Z_SYSCALL_MEMORY_WRITE()` -* :c:macro:`Z_SYSCALL_MEMORY_ARRAY_READ()` -* :c:macro:`Z_SYSCALL_MEMORY_ARRAY_WRITE()` +* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` +* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` * :c:macro:`K_SYSCALL_VERIFY_MSG()` * :c:macro:`Z_SYSCALL_VERIFY` diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index 1e5a5ee5d7b..b1e9906fc61 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -62,7 +62,7 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, Z_OOPS(Z_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, sizeof(struct i2c_msg))); return copy_msgs_and_transfer((const struct device *)dev, diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index 2fa8cff161d..9d5cbd4880a 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -16,19 +16,19 @@ static inline int z_vrfy_i3c_do_ccc(const struct device *dev, Z_OOPS(Z_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); if (payload->ccc.data != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(payload->ccc.data, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->ccc.data, payload->ccc.data_len, sizeof(*payload->ccc.data))); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(payload->ccc.data, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->ccc.data, payload->ccc.data_len, sizeof(*payload->ccc.data))); } if (payload->targets.payloads != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(payload->targets.payloads, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->targets.payloads, payload->targets.num_targets, sizeof(*payload->targets.payloads))); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(payload->targets.payloads, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->targets.payloads, payload->targets.num_targets, sizeof(*payload->targets.payloads))); } @@ -72,7 +72,7 @@ static inline int z_vrfy_i3c_transfer(struct i3c_device_desc *target, Z_OOPS(Z_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, sizeof(struct i3c_msg))); return copy_i3c_msgs_and_transfer((struct i3c_device_desc *)target, diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 4f2ac834f71..6ce3107cab2 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -102,7 +102,7 @@ static inline int z_vrfy_uart_tx_u16(const struct device *dev, size_t len, int32_t timeout) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, tx)); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(buf, len, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(buf, len, sizeof(uint16_t))); return z_impl_uart_tx_u16(dev, buf, len, timeout); } #include @@ -127,7 +127,7 @@ static inline int z_vrfy_uart_rx_enable_u16(const struct device *dev, size_t len, int32_t timeout) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, rx_enable)); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(buf, len, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(buf, len, sizeof(uint16_t))); return z_impl_uart_rx_enable_u16(dev, buf, len, timeout); } #include diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index dd1a1eb7d6f..1ae5d69f37e 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -23,7 +23,7 @@ static struct spi_buf_set *copy_and_check(struct spi_buf_set *bufs, } /* Validate the array of struct spi_buf instances */ - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers, + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers, bufs->count, sizeof(struct spi_buf))); diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index adb4f1cbb73..557437c0233 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -386,7 +386,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_SYSCALL_MEMORY_WRITE(ptr, size) \ Z_SYSCALL_MEMORY(ptr, size, 1) -#define Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ +#define K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ ({ \ size_t product; \ K_SYSCALL_VERIFY_MSG(!size_mul_overflow((size_t)(nmemb), \ @@ -409,8 +409,8 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); * @param size Size of each array element * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \ - Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0) +#define K_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \ + K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0) /** * @brief Validate user thread has read/write permission for sized array @@ -424,8 +424,8 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); * @param size Size of each array element * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ - Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) +#define K_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ + K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) static inline int z_obj_validation_check(struct k_object *ko, const void *obj, diff --git a/lib/libc/minimal/source/stdout/stdout_console.c b/lib/libc/minimal/source/stdout/stdout_console.c index fd09b87110a..ab3777fbf91 100644 --- a/lib/libc/minimal/source/stdout/stdout_console.c +++ b/lib/libc/minimal/source/stdout/stdout_console.c @@ -101,7 +101,7 @@ static inline size_t z_vrfy_zephyr_fwrite(const void *ZRESTRICT ptr, FILE *ZRESTRICT stream) { - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(ptr, nitems, size)); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(ptr, nitems, size)); return z_impl_zephyr_fwrite((const void *ZRESTRICT)ptr, size, nitems, (FILE *ZRESTRICT)stream); } diff --git a/subsys/net/lib/sockets/getaddrinfo.c b/subsys/net/lib/sockets/getaddrinfo.c index 2acee2734e1..5bb3f6c0125 100644 --- a/subsys/net/lib/sockets/getaddrinfo.c +++ b/subsys/net/lib/sockets/getaddrinfo.c @@ -284,7 +284,7 @@ static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host, Z_OOPS(z_user_from_copy(&hints_copy, (void *)hints, sizeof(hints_copy))); } - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); if (service) { service_copy = z_user_string_alloc_copy((char *)service, 64); diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_handlers.c index 39ead483005..f49d9488b85 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_handlers.c @@ -81,7 +81,7 @@ static inline int z_vrfy_rtio_sqe_copy_in_get_handles(struct rtio *r, const stru { Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe))); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe))); struct rtio_sqe *sqe; uint32_t acquirable = rtio_sqe_acquirable(r); @@ -116,7 +116,7 @@ static inline int z_vrfy_rtio_cqe_copy_out(struct rtio *r, { Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(cqes, cqe_count, sizeof(struct rtio_cqe))); + Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(cqes, cqe_count, sizeof(struct rtio_cqe))); return z_impl_rtio_cqe_copy_out(r, cqes, cqe_count, timeout); } From d178b6a0e7b363a142d2fd98ba455c327dfa2517 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:44:21 +0000 Subject: [PATCH 3012/4498] syscall: z_obj_validation_check -> k_object_validation_check Rename z_obj_validation_check and do not use z_ for internal APIs. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 4 ++-- kernel/thread.c | 2 +- kernel/userspace_handler.c | 4 ++-- tests/kernel/mem_protect/obj_validation/src/main.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 557437c0233..34d52279bf1 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -427,7 +427,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define K_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) -static inline int z_obj_validation_check(struct k_object *ko, +static inline int k_object_validation_check(struct k_object *ko, const void *obj, enum k_objects otype, enum _obj_init_check init) @@ -448,7 +448,7 @@ static inline int z_obj_validation_check(struct k_object *ko, } #define K_SYSCALL_IS_OBJ(ptr, type, init) \ - K_SYSCALL_VERIFY_MSG(z_obj_validation_check( \ + K_SYSCALL_VERIFY_MSG(k_object_validation_check( \ z_object_find((const void *)ptr), \ (const void *)ptr, \ type, init) == 0, "access denied") diff --git a/kernel/thread.c b/kernel/thread.c index fc0d725219f..e376997b294 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -734,7 +734,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, * object table if it isn't */ stack_object = z_object_find(stack); - Z_OOPS(K_SYSCALL_VERIFY_MSG(z_obj_validation_check(stack_object, stack, + Z_OOPS(K_SYSCALL_VERIFY_MSG(k_object_validation_check(stack_object, stack, K_OBJ_THREAD_STACK_ELEMENT, _OBJ_INIT_FALSE) == 0, "bad stack object")); diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index a8457b3c0e5..cbec3245f47 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -32,14 +32,14 @@ static struct k_object *validate_kernel_object(const void *obj, return ko; } -static ALWAYS_INLINE struct z_object *validate_any_object(const void *obj) +static ALWAYS_INLINE struct k_object *validate_any_object(const void *obj) { return validate_kernel_object(obj, K_OBJ_ANY, _OBJ_INIT_ANY); } bool k_object_is_valid(const void *obj, enum k_objects otype) { - struct z_object *ko; + struct k_object *ko; ko = validate_kernel_object(obj, otype, _OBJ_INIT_TRUE); diff --git a/tests/kernel/mem_protect/obj_validation/src/main.c b/tests/kernel/mem_protect/obj_validation/src/main.c index bd28b9e4295..07c42ac510d 100644 --- a/tests/kernel/mem_protect/obj_validation/src/main.c +++ b/tests/kernel/mem_protect/obj_validation/src/main.c @@ -31,12 +31,12 @@ static int test_object(struct k_sem *sem, int retval) int ret; if (retval) { - /* Expected to fail; bypass z_obj_validation_check() so we don't + /* Expected to fail; bypass k_object_validation_check() so we don't * fill the logs with spam */ ret = z_object_validate(z_object_find(sem), K_OBJ_SEM, 0); } else { - ret = z_obj_validation_check(z_object_find(sem), sem, + ret = k_object_validation_check(z_object_find(sem), sem, K_OBJ_SEM, 0); } From 43a7402baf496f209f054cb306b08224f25338e6 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:44:47 +0000 Subject: [PATCH 3013/4498] syscall: rename z_object_recycle -> k_object_recycle Rename z_object_recycle and do not use z_ for internal APIs. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/userspace.c | 2 +- lib/os/fdtable.c | 2 +- tests/kernel/mem_protect/userspace/src/main.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 34d52279bf1..2952dc6d68c 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -176,7 +176,7 @@ void z_object_uninit(const void *obj); * * @param object Address of the kernel object */ -void z_object_recycle(const void *obj); +void k_object_recycle(const void *obj); /** * @brief Obtain the size of a C string passed from user mode diff --git a/kernel/userspace.c b/kernel/userspace.c index 6a4a65a8ada..314727569fd 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -779,7 +779,7 @@ void k_object_init(const void *obj) ko->flags |= K_OBJ_FLAG_INITIALIZED; } -void z_object_recycle(const void *obj) +void k_object_recycle(const void *obj) { struct k_object *ko = z_object_find(obj); diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index ccb14fa58e6..757ebf4361f 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -263,7 +263,7 @@ void z_finalize_fd(int fd, void *obj, const struct fd_op_vtable *vtable) * This call is a no-op if obj is invalid or points to something * not a kernel object. */ - z_object_recycle(obj); + k_object_recycle(obj); #endif fdtable[fd].obj = obj; fdtable[fd].vtable = vtable; diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 5a23e0c96e7..05516d13427 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -861,7 +861,7 @@ static struct k_sem recycle_sem; * @details Test recycle valid/invalid kernel object, see if * perms_count changes as expected. * - * @see z_object_recycle(), z_object_find() + * @see k_object_recycle(), z_object_find() * * @ingroup kernel_memprotect_tests */ @@ -877,12 +877,12 @@ ZTEST(userspace, test_object_recycle) ko = z_object_find(&dummy); zassert_true(ko == NULL, "not an invalid object"); - z_object_recycle(&dummy); + k_object_recycle(&dummy); ko = z_object_find(&recycle_sem); (void)memset(ko->perms, 0xFF, sizeof(ko->perms)); - z_object_recycle(&recycle_sem); + k_object_recycle(&recycle_sem); zassert_true(ko != NULL, "kernel object not found"); zassert_true(ko->flags & K_OBJ_FLAG_INITIALIZED, "object wasn't marked as initialized"); From 7a18c2b15027898bda0498d68825c7d94ccf8568 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:45:18 +0000 Subject: [PATCH 3014/4498] syscall: rename z_object_uninit -> k_object_uninit Rename internal function z_object_uninit. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/sched.c | 4 ++-- kernel/userspace.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 2952dc6d68c..cae1ba06983 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -157,7 +157,7 @@ void z_thread_perms_all_clear(struct k_thread *thread); * * @param object Address of the kernel object */ -void z_object_uninit(const void *obj); +void k_object_uninit(const void *obj); /** * Initialize and reset permissions to only access by the caller diff --git a/kernel/sched.c b/kernel/sched.c index f3a5c92d7f6..4d8f4deecbf 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1752,8 +1752,8 @@ static void end_thread(struct k_thread *thread) #ifdef CONFIG_USERSPACE z_mem_domain_exit_thread(thread); z_thread_perms_all_clear(thread); - z_object_uninit(thread->stack_obj); - z_object_uninit(thread); + k_object_uninit(thread->stack_obj); + k_object_uninit(thread); #endif } } diff --git a/kernel/userspace.c b/kernel/userspace.c index 314727569fd..b44526e4afe 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -790,7 +790,7 @@ void k_object_recycle(const void *obj) } } -void z_object_uninit(const void *obj) +void k_object_uninit(const void *obj) { struct k_object *ko; From 70cf96b5e10f9b9e56d9df5b6e9b3345643fb609 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:45:48 +0000 Subject: [PATCH 3015/4498] syscall: z_thread_perms_all_clear -> k_thread_perms_all_clear Rename internal function z_thread_perms_all_clear. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/sched.c | 2 +- kernel/userspace.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index cae1ba06983..e36bf8b957d 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -147,7 +147,7 @@ void z_thread_perms_clear(struct k_object *ko, struct k_thread *thread); * * @param thread Thread object to revoke access */ -void z_thread_perms_all_clear(struct k_thread *thread); +void k_thread_perms_all_clear(struct k_thread *thread); /** * Clear initialization state of a kernel object diff --git a/kernel/sched.c b/kernel/sched.c index 4d8f4deecbf..381d94d1169 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1751,7 +1751,7 @@ static void end_thread(struct k_thread *thread) #ifdef CONFIG_USERSPACE z_mem_domain_exit_thread(thread); - z_thread_perms_all_clear(thread); + k_thread_perms_all_clear(thread); k_object_uninit(thread->stack_obj); k_object_uninit(thread); #endif diff --git a/kernel/userspace.c b/kernel/userspace.c index b44526e4afe..bdf63337786 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -628,7 +628,7 @@ static void clear_perms_cb(struct k_object *ko, void *ctx_ptr) unref_check(ko, id); } -void z_thread_perms_all_clear(struct k_thread *thread) +void k_thread_perms_all_clear(struct k_thread *thread) { uintptr_t index = thread_index_get(thread); From e2a9d013e5d2df6600e30d2eb4e32b3a41864efe Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:46:26 +0000 Subject: [PATCH 3016/4498] kernel: userspace: rename z_thread_perms_clear -> k_thread_perms_clear Rename z_thread_perms_clear -> k_thread_perms_clear. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 4 ++-- kernel/userspace.c | 4 ++-- kernel/userspace_handler.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index e36bf8b957d..ba235afd1e5 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -137,12 +137,12 @@ void z_thread_perms_set(struct k_object *ko, struct k_thread *thread); * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -void z_thread_perms_clear(struct k_object *ko, struct k_thread *thread); +void k_thread_perms_clear(struct k_object *ko, struct k_thread *thread); /* * Revoke access to all objects for the provided thread * - * NOTE: Unlike z_thread_perms_clear(), this function will not clear + * NOTE: Unlike k_thread_perms_clear(), this function will not clear * permissions on public objects. * * @param thread Thread object to revoke access diff --git a/kernel/userspace.c b/kernel/userspace.c index bdf63337786..ca898e787ce 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -611,7 +611,7 @@ void z_thread_perms_set(struct k_object *ko, struct k_thread *thread) } } -void z_thread_perms_clear(struct k_object *ko, struct k_thread *thread) +void k_thread_perms_clear(struct k_object *ko, struct k_thread *thread) { int index = thread_index_get(thread); @@ -703,7 +703,7 @@ void k_object_access_revoke(const void *object, struct k_thread *thread) struct k_object *ko = z_object_find(object); if (ko != NULL) { - z_thread_perms_clear(ko, thread); + k_thread_perms_clear(ko, thread); } } diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index cbec3245f47..74ee4938083 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -73,7 +73,7 @@ static inline void z_vrfy_k_object_release(const void *object) ko = validate_any_object((void *)object); Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", (void *)object)); - z_thread_perms_clear(ko, _current); + k_thread_perms_clear(ko, _current); } #include From 993f903830508965107ca90ac3979779cb05a9b6 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:47:01 +0000 Subject: [PATCH 3017/4498] syscall: rename z_thread_perms_set -> k_thread_perms_set Rename z_thread_perms_set and do not use z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/userspace.c | 8 ++++---- kernel/userspace_handler.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index ba235afd1e5..8d05ab5357e 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -129,7 +129,7 @@ void z_thread_perms_inherit(struct k_thread *parent, * @param ko Kernel object metadata to update * @param thread The thread to grant permission */ -void z_thread_perms_set(struct k_object *ko, struct k_thread *thread); +void k_thread_perms_set(struct k_object *ko, struct k_thread *thread); /** * Revoke a thread's permission to a kernel object diff --git a/kernel/userspace.c b/kernel/userspace.c index ca898e787ce..ac705bd4fca 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -428,7 +428,7 @@ static void *z_object_alloc(enum k_objects otype, size_t size) /* The allocating thread implicitly gets permission on kernel objects * that it allocates */ - z_thread_perms_set(zo, _current); + k_thread_perms_set(zo, _current); /* Activates reference counting logic for automatic disposal when * all permissions have been revoked @@ -602,7 +602,7 @@ void z_thread_perms_inherit(struct k_thread *parent, struct k_thread *child) } } -void z_thread_perms_set(struct k_object *ko, struct k_thread *thread) +void k_thread_perms_set(struct k_object *ko, struct k_thread *thread) { int index = thread_index_get(thread); @@ -694,7 +694,7 @@ void z_impl_k_object_access_grant(const void *object, struct k_thread *thread) struct k_object *ko = z_object_find(object); if (ko != NULL) { - z_thread_perms_set(ko, thread); + k_thread_perms_set(ko, thread); } } @@ -785,7 +785,7 @@ void k_object_recycle(const void *obj) if (ko != NULL) { (void)memset(ko->perms, 0, sizeof(ko->perms)); - z_thread_perms_set(ko, _current); + k_thread_perms_set(ko, _current); ko->flags |= K_OBJ_FLAG_INITIALIZED; } } diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 74ee4938083..bc8f1b3f397 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -62,7 +62,7 @@ static inline void z_vrfy_k_object_access_grant(const void *object, ko = validate_any_object(object); Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", object)); - z_thread_perms_set(ko, thread); + k_thread_perms_set(ko, thread); } #include From a5b49458eb704a30e38b01f278ec98dc69ef7093 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:47:50 +0000 Subject: [PATCH 3018/4498] syscall: rename z_thread_perms_inherit -> k_thread_perms_inherit Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 3 +-- kernel/thread.c | 2 +- kernel/userspace.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 8d05ab5357e..f78e4cdbb4c 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -120,8 +120,7 @@ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); * @param parent Parent thread, to get permissions from * @param child Child thread, to copy permissions to */ -void z_thread_perms_inherit(struct k_thread *parent, - struct k_thread *child); +void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child); /** * Grant a thread permission to a kernel object diff --git a/kernel/thread.c b/kernel/thread.c index e376997b294..543da995832 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -673,7 +673,7 @@ char *z_setup_new_thread(struct k_thread *new_thread, z_mem_domain_init_thread(new_thread); if ((options & K_INHERIT_PERMS) != 0U) { - z_thread_perms_inherit(_current, new_thread); + k_thread_perms_inherit(_current, new_thread); } #endif #ifdef CONFIG_SCHED_DEADLINE diff --git a/kernel/userspace.c b/kernel/userspace.c index ac705bd4fca..85a60e54a0a 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -589,7 +589,7 @@ static void wordlist_cb(struct k_object *ko, void *ctx_ptr) } } -void z_thread_perms_inherit(struct k_thread *parent, struct k_thread *child) +void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child) { struct perm_ctx ctx = { thread_index_get(parent), From 27d74e95c92235d33eecb199bd835071a4e766c7 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:48:38 +0000 Subject: [PATCH 3019/4498] syscall: rename z_object_wordlist_foreach -> k_object_wordlist_foreach Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- include/zephyr/linker/kobject-text.ld | 2 +- kernel/userspace.c | 10 +++++----- scripts/build/gen_kobject_list.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index f78e4cdbb4c..d26b9508310 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -112,7 +112,7 @@ typedef void (*_wordlist_cb_func_t)(struct k_object *ko, void *context); * @param func function to run on each struct k_object * @param context Context pointer to pass to each invocation */ -void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); +void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); /** * Copy all kernel object permissions from the parent to the child diff --git a/include/zephyr/linker/kobject-text.ld b/include/zephyr/linker/kobject-text.ld index 47a989f4c23..ee93f4a2144 100644 --- a/include/zephyr/linker/kobject-text.ld +++ b/include/zephyr/linker/kobject-text.ld @@ -19,7 +19,7 @@ PROVIDE(z_object_gperf_wordlist_foreach = .); #else PROVIDE(z_object_find = .); - PROVIDE(z_object_wordlist_foreach = .); + PROVIDE(k_object_wordlist_foreach = .); #endif #endif diff --git a/kernel/userspace.c b/kernel/userspace.c index 85a60e54a0a..7a0db0f1175 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -281,7 +281,7 @@ static bool thread_idx_alloc(uintptr_t *tidx) *tidx); /* Clear permission from all objects */ - z_object_wordlist_foreach(clear_perms_cb, + k_object_wordlist_foreach(clear_perms_cb, (void *)*tidx); return true; @@ -306,7 +306,7 @@ static bool thread_idx_alloc(uintptr_t *tidx) static void thread_idx_free(uintptr_t tidx) { /* To prevent leaked permission when index is recycled */ - z_object_wordlist_foreach(clear_perms_cb, (void *)tidx); + k_object_wordlist_foreach(clear_perms_cb, (void *)tidx); sys_bitfield_set_bit((mem_addr_t)_thread_idx_map, tidx); } @@ -497,7 +497,7 @@ struct k_object *z_object_find(const void *obj) return ret; } -void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) +void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) { struct dyn_obj *obj, *next; @@ -598,7 +598,7 @@ void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child) }; if ((ctx.parent_id != -1) && (ctx.child_id != -1)) { - z_object_wordlist_foreach(wordlist_cb, &ctx); + k_object_wordlist_foreach(wordlist_cb, &ctx); } } @@ -633,7 +633,7 @@ void k_thread_perms_all_clear(struct k_thread *thread) uintptr_t index = thread_index_get(thread); if ((int)index != -1) { - z_object_wordlist_foreach(clear_perms_cb, (void *)index); + k_object_wordlist_foreach(clear_perms_cb, (void *)index); } } diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index 6bd12010414..c3df9679b1e 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -755,7 +755,7 @@ def get_symbols(elf): struct k_object *z_object_find(const void *obj) ALIAS_OF(z_object_gperf_find); -void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) +void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) ALIAS_OF(z_object_gperf_wordlist_foreach); #endif """ From c25d0804f0a9ae31a0559195a37955caa6c131b0 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:49:28 +0000 Subject: [PATCH 3020/4498] syscall: rename z_object_find -> k_object_find Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 4 ++-- include/zephyr/linker/kobject-text.ld | 2 +- include/zephyr/sys/internal/kobject_internal.h | 2 +- kernel/dynamic.c | 2 +- kernel/futex.c | 2 +- kernel/sched.c | 2 +- kernel/thread.c | 6 +++--- kernel/userspace.c | 18 +++++++++--------- kernel/userspace_handler.c | 4 ++-- lib/os/mutex.c | 2 +- scripts/build/gen_kobject_list.py | 2 +- scripts/build/process_gperf.py | 2 +- .../mem_protect/mem_protect/src/kobject.c | 6 +++--- .../mem_protect/obj_validation/src/main.c | 6 +++--- tests/kernel/mem_protect/userspace/src/main.c | 6 +++--- tests/kernel/threads/thread_stack/src/main.c | 2 +- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index d26b9508310..b2811d16152 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -102,7 +102,7 @@ void z_dump_object_error(int retval, const void *obj, * @return Kernel object's metadata, or NULL if the parameter wasn't the * memory address of a kernel object */ -struct k_object *z_object_find(const void *obj); +struct k_object *k_object_find(const void *obj); typedef void (*_wordlist_cb_func_t)(struct k_object *ko, void *context); @@ -448,7 +448,7 @@ static inline int k_object_validation_check(struct k_object *ko, #define K_SYSCALL_IS_OBJ(ptr, type, init) \ K_SYSCALL_VERIFY_MSG(k_object_validation_check( \ - z_object_find((const void *)ptr), \ + k_object_find((const void *)ptr), \ (const void *)ptr, \ type, init) == 0, "access denied") diff --git a/include/zephyr/linker/kobject-text.ld b/include/zephyr/linker/kobject-text.ld index ee93f4a2144..b1c2b69e6df 100644 --- a/include/zephyr/linker/kobject-text.ld +++ b/include/zephyr/linker/kobject-text.ld @@ -18,7 +18,7 @@ PROVIDE(z_object_gperf_find = .); PROVIDE(z_object_gperf_wordlist_foreach = .); #else - PROVIDE(z_object_find = .); + PROVIDE(k_object_find = .); PROVIDE(k_object_wordlist_foreach = .); #endif #endif diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index 15bab175e0f..b7bf816ad78 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -50,7 +50,7 @@ union k_object_data { }; /* Table generated by gperf, these objects are retrieved via - * z_object_find() */ + * k_object_find() */ struct k_object { void *name; uint8_t perms[CONFIG_MAX_THREAD_BYTES]; diff --git a/kernel/dynamic.c b/kernel/dynamic.c index 3fea6b68c56..d30dba8ac02 100644 --- a/kernel/dynamic.c +++ b/kernel/dynamic.c @@ -152,7 +152,7 @@ int z_impl_k_thread_stack_free(k_thread_stack_t *stack) if (IS_ENABLED(CONFIG_DYNAMIC_THREAD_ALLOC)) { #ifdef CONFIG_USERSPACE - if (z_object_find(stack)) { + if (k_object_find(stack)) { k_object_free(stack); } else { k_free(stack); diff --git a/kernel/futex.c b/kernel/futex.c index f0f5e5aecbc..52584fb6432 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -16,7 +16,7 @@ static struct z_futex_data *k_futex_find_data(struct k_futex *futex) { struct k_object *obj; - obj = z_object_find(futex); + obj = k_object_find(futex); if (obj == NULL || obj->type != K_OBJ_FUTEX) { return NULL; } diff --git a/kernel/sched.c b/kernel/sched.c index 381d94d1169..653e680e443 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1878,7 +1878,7 @@ int z_impl_k_thread_join(struct k_thread *thread, k_timeout_t timeout) */ static bool thread_obj_validate(struct k_thread *thread) { - struct k_object *ko = z_object_find(thread); + struct k_object *ko = k_object_find(thread); int ret = z_object_validate(ko, K_OBJ_THREAD, _OBJ_INIT_TRUE); switch (ret) { diff --git a/kernel/thread.c b/kernel/thread.c index 543da995832..66d81a8247e 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -360,7 +360,7 @@ static inline int z_vrfy_k_thread_name_copy(k_tid_t thread, { #ifdef CONFIG_THREAD_NAME size_t len; - struct k_object *ko = z_object_find(thread); + struct k_object *ko = k_object_find(thread); /* Special case: we allow reading the names of initialized threads * even if we don't have permission on them @@ -715,7 +715,7 @@ k_tid_t z_impl_k_thread_create(struct k_thread *new_thread, #ifdef CONFIG_USERSPACE bool z_stack_is_user_capable(k_thread_stack_t *stack) { - return z_object_find(stack) != NULL; + return k_object_find(stack) != NULL; } k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, @@ -733,7 +733,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, /* No need to check z_stack_is_user_capable(), it won't be in the * object table if it isn't */ - stack_object = z_object_find(stack); + stack_object = k_object_find(stack); Z_OOPS(K_SYSCALL_VERIFY_MSG(k_object_validation_check(stack_object, stack, K_OBJ_THREAD_STACK_ELEMENT, _OBJ_INIT_FALSE) == 0, diff --git a/kernel/userspace.c b/kernel/userspace.c index 7a0db0f1175..f3e73eff574 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -119,7 +119,7 @@ struct perm_ctx { */ uint8_t *z_priv_stack_find(k_thread_stack_t *stack) { - struct k_object *obj = z_object_find(stack); + struct k_object *obj = k_object_find(stack); __ASSERT(obj != NULL, "stack object not found"); __ASSERT(obj->type == K_OBJ_THREAD_STACK_ELEMENT, @@ -475,7 +475,7 @@ void k_object_free(void *obj) } } -struct k_object *z_object_find(const void *obj) +struct k_object *k_object_find(const void *obj) { struct k_object *ret; @@ -516,7 +516,7 @@ static unsigned int thread_index_get(struct k_thread *thread) { struct k_object *ko; - ko = z_object_find(thread); + ko = k_object_find(thread); if (ko == NULL) { return -1; @@ -691,7 +691,7 @@ void z_dump_object_error(int retval, const void *obj, struct k_object *ko, void z_impl_k_object_access_grant(const void *object, struct k_thread *thread) { - struct k_object *ko = z_object_find(object); + struct k_object *ko = k_object_find(object); if (ko != NULL) { k_thread_perms_set(ko, thread); @@ -700,7 +700,7 @@ void z_impl_k_object_access_grant(const void *object, struct k_thread *thread) void k_object_access_revoke(const void *object, struct k_thread *thread) { - struct k_object *ko = z_object_find(object); + struct k_object *ko = k_object_find(object); if (ko != NULL) { k_thread_perms_clear(ko, thread); @@ -714,7 +714,7 @@ void z_impl_k_object_release(const void *object) void k_object_access_all_grant(const void *object) { - struct k_object *ko = z_object_find(object); + struct k_object *ko = k_object_find(object); if (ko != NULL) { ko->flags |= K_OBJ_FLAG_PUBLIC; @@ -766,7 +766,7 @@ void k_object_init(const void *obj) * finalizes it */ - ko = z_object_find(obj); + ko = k_object_find(obj); if (ko == NULL) { /* Supervisor threads can ignore rules about kernel objects * and may declare them on stacks, etc. Such objects will never @@ -781,7 +781,7 @@ void k_object_init(const void *obj) void k_object_recycle(const void *obj) { - struct k_object *ko = z_object_find(obj); + struct k_object *ko = k_object_find(obj); if (ko != NULL) { (void)memset(ko->perms, 0, sizeof(ko->perms)); @@ -795,7 +795,7 @@ void k_object_uninit(const void *obj) struct k_object *ko; /* See comments in k_object_init() */ - ko = z_object_find(obj); + ko = k_object_find(obj); if (ko == NULL) { return; } diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index bc8f1b3f397..e345b1c2b41 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -16,7 +16,7 @@ static struct k_object *validate_kernel_object(const void *obj, struct k_object *ko; int ret; - ko = z_object_find(obj); + ko = k_object_find(obj); /* This can be any kernel object and it doesn't have to be * initialized @@ -50,7 +50,7 @@ bool k_object_is_valid(const void *obj, enum k_objects otype) * syscall_dispatch.c declares weak handlers results in build errors if these * are located in userspace.c. Just put in a separate file. * - * To avoid double z_object_find() lookups, we don't call the implementation + * To avoid double k_object_find() lookups, we don't call the implementation * function, but call a level deeper. */ static inline void z_vrfy_k_object_access_grant(const void *object, diff --git a/lib/os/mutex.c b/lib/os/mutex.c index fb18c9650b7..b74cda0ab68 100644 --- a/lib/os/mutex.c +++ b/lib/os/mutex.c @@ -13,7 +13,7 @@ static struct k_mutex *get_k_mutex(struct sys_mutex *mutex) { struct k_object *obj; - obj = z_object_find(mutex); + obj = k_object_find(mutex); if (obj == NULL || obj->type != K_OBJ_SYS_MUTEX) { return NULL; } diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index c3df9679b1e..c64eacd986e 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -752,7 +752,7 @@ def get_symbols(elf): } #ifndef CONFIG_DYNAMIC_OBJECTS -struct k_object *z_object_find(const void *obj) +struct k_object *k_object_find(const void *obj) ALIAS_OF(z_object_gperf_find); void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) diff --git a/scripts/build/process_gperf.py b/scripts/build/process_gperf.py index 002cd9cc1e6..95bbd244dc7 100755 --- a/scripts/build/process_gperf.py +++ b/scripts/build/process_gperf.py @@ -83,7 +83,7 @@ def process_line(line, fp): return # Set the lookup function to static inline so it gets rolled into - # z_object_find(), nothing else will use it + # k_object_find(), nothing else will use it if re.search(args.pattern + " [*]$", line): fp.write("static inline " + line) return diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 7deae8b31c2..1a5029f3632 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -481,7 +481,7 @@ ZTEST(mem_protect_kobj, test_thread_has_residual_permissions) * @ingroup kernel_memprotect_tests * * @see k_object_access_grant(), k_object_access_revoke(), - * z_object_find() + * k_object_find() */ ZTEST(mem_protect_kobj, test_kobject_access_grant_to_invalid_thread) { @@ -1069,12 +1069,12 @@ ZTEST(mem_protect_kobj, test_mark_thread_exit_uninitialized) k_thread_join(&child_thread, K_FOREVER); /* check thread is uninitialized after its exit */ - ko = z_object_find(&child_thread); + ko = k_object_find(&child_thread); ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); zassert_equal(ret, _OBJ_INIT_FALSE); /* check stack is uninitialized after thread exit */ - ko = z_object_find(child_stack); + ko = k_object_find(child_stack); ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); zassert_equal(ret, _OBJ_INIT_FALSE); } diff --git a/tests/kernel/mem_protect/obj_validation/src/main.c b/tests/kernel/mem_protect/obj_validation/src/main.c index 07c42ac510d..2ca87a11ed9 100644 --- a/tests/kernel/mem_protect/obj_validation/src/main.c +++ b/tests/kernel/mem_protect/obj_validation/src/main.c @@ -34,9 +34,9 @@ static int test_object(struct k_sem *sem, int retval) /* Expected to fail; bypass k_object_validation_check() so we don't * fill the logs with spam */ - ret = z_object_validate(z_object_find(sem), K_OBJ_SEM, 0); + ret = z_object_validate(k_object_find(sem), K_OBJ_SEM, 0); } else { - ret = k_object_validation_check(z_object_find(sem), sem, + ret = k_object_validation_check(k_object_find(sem), sem, K_OBJ_SEM, 0); } @@ -179,7 +179,7 @@ ZTEST(object_validation, test_no_ref_dyn_kobj_release_mem) k_object_access_revoke(test_dyn_mutex, thread); /* check object was released, when no threads have access to it */ - ret = z_object_validate(z_object_find(test_dyn_mutex), K_OBJ_MUTEX, 0); + ret = z_object_validate(k_object_find(test_dyn_mutex), K_OBJ_MUTEX, 0); zassert_true(ret == -EBADF, "Dynamic kernel object not released"); } diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index 05516d13427..1c0e7d3ef21 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -861,7 +861,7 @@ static struct k_sem recycle_sem; * @details Test recycle valid/invalid kernel object, see if * perms_count changes as expected. * - * @see k_object_recycle(), z_object_find() + * @see k_object_recycle(), k_object_find() * * @ingroup kernel_memprotect_tests */ @@ -874,12 +874,12 @@ ZTEST(userspace, test_object_recycle) /* Validate recycle invalid objects, after recycling this invalid * object, perms_count should finally still be 1. */ - ko = z_object_find(&dummy); + ko = k_object_find(&dummy); zassert_true(ko == NULL, "not an invalid object"); k_object_recycle(&dummy); - ko = z_object_find(&recycle_sem); + ko = k_object_find(&recycle_sem); (void)memset(ko->perms, 0xFF, sizeof(ko->perms)); k_object_recycle(&recycle_sem); diff --git a/tests/kernel/threads/thread_stack/src/main.c b/tests/kernel/threads/thread_stack/src/main.c index 19c54a052ea..0ab51931188 100644 --- a/tests/kernel/threads/thread_stack/src/main.c +++ b/tests/kernel/threads/thread_stack/src/main.c @@ -335,7 +335,7 @@ void scenario_entry(void *stack_obj, size_t obj_size, size_t reported_size, #ifdef CONFIG_USERSPACE struct k_object *zo; - zo = z_object_find(stack_obj); + zo = k_object_find(stack_obj); if (zo != NULL) { is_user = true; #ifdef CONFIG_GEN_PRIV_STACKS From 21254b2f40ba33bc990f8b02ca6fa9ef9cac4569 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:50:26 +0000 Subject: [PATCH 3021/4498] syscall: rename z_object_validate -> k_object_validate Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 2 +- include/zephyr/internal/syscall_handler.h | 10 +++++----- kernel/sched.c | 2 +- kernel/userspace.c | 4 ++-- kernel/userspace_handler.c | 2 +- tests/kernel/mem_protect/mem_protect/src/kobject.c | 4 ++-- tests/kernel/mem_protect/obj_validation/src/main.c | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 07629589a46..1b5572e905d 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -573,7 +573,7 @@ conventions are as follows: #. Most system calls take kernel object pointers as an argument, checked either with one of the ``Z_SYSCALL_OBJ`` functions, ``Z_SYSCALL_DRIVER_nnnnn``, or - manually using :c:func:`z_object_validate()`. These can fail for a variety + manually using :c:func:`k_object_validate()`. These can fail for a variety of reasons: missing driver API, bad kernel object pointer, wrong kernel object type, or improper initialization state. These issues should always invoke :c:macro:`Z_OOPS()`. diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index b2811d16152..8bde1db951a 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -78,13 +78,13 @@ static inline bool k_is_in_user_syscall(void) * -EPERM If the caller does not have permissions * -EINVAL Object is not initialized */ -int z_object_validate(struct k_object *ko, enum k_objects otype, +int k_object_validate(struct k_object *ko, enum k_objects otype, enum _obj_init_check init); /** - * Dump out error information on failed z_object_validate() call + * Dump out error information on failed k_object_validate() call * - * @param retval Return value from z_object_validate() + * @param retval Return value from k_object_validate() * @param obj Kernel object we were trying to verify * @param ko If retval=-EPERM, struct k_object * that was looked up, or NULL * @param otype Expected type of the kernel object @@ -433,7 +433,7 @@ static inline int k_object_validation_check(struct k_object *ko, { int ret; - ret = z_object_validate(ko, otype, init); + ret = k_object_validate(ko, otype, init); #ifdef CONFIG_LOG if (ret != 0) { @@ -501,7 +501,7 @@ static inline int k_object_validation_check(struct k_object *ko, /** * @brief Runtime check kernel object pointer for non-init functions * - * Calls z_object_validate and triggers a kernel oops if the check fails. + * Calls k_object_validate and triggers a kernel oops if the check fails. * For use in system call handlers which are not init functions; a fatal * error will occur if the object is not initialized. * diff --git a/kernel/sched.c b/kernel/sched.c index 653e680e443..aa736f6b689 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1879,7 +1879,7 @@ int z_impl_k_thread_join(struct k_thread *thread, k_timeout_t timeout) static bool thread_obj_validate(struct k_thread *thread) { struct k_object *ko = k_object_find(thread); - int ret = z_object_validate(ko, K_OBJ_THREAD, _OBJ_INIT_TRUE); + int ret = k_object_validate(ko, K_OBJ_THREAD, _OBJ_INIT_TRUE); switch (ret) { case 0: diff --git a/kernel/userspace.c b/kernel/userspace.c index f3e73eff574..ffece57043f 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -721,7 +721,7 @@ void k_object_access_all_grant(const void *object) } } -int z_object_validate(struct k_object *ko, enum k_objects otype, +int k_object_validate(struct k_object *ko, enum k_objects otype, enum _obj_init_check init) { if (unlikely((ko == NULL) || @@ -759,7 +759,7 @@ void k_object_init(const void *obj) struct k_object *ko; /* By the time we get here, if the caller was from userspace, all the - * necessary checks have been done in z_object_validate(), which takes + * necessary checks have been done in k_object_validate(), which takes * place before the object is initialized. * * This function runs after the object has been initialized and diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index e345b1c2b41..788534e6a92 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -21,7 +21,7 @@ static struct k_object *validate_kernel_object(const void *obj, /* This can be any kernel object and it doesn't have to be * initialized */ - ret = z_object_validate(ko, otype, init); + ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_ANY); if (ret != 0) { #ifdef CONFIG_LOG z_dump_object_error(ret, obj, ko, otype); diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 1a5029f3632..4671ec23f86 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -1070,12 +1070,12 @@ ZTEST(mem_protect_kobj, test_mark_thread_exit_uninitialized) /* check thread is uninitialized after its exit */ ko = k_object_find(&child_thread); - ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); + ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); zassert_equal(ret, _OBJ_INIT_FALSE); /* check stack is uninitialized after thread exit */ ko = k_object_find(child_stack); - ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); + ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE); zassert_equal(ret, _OBJ_INIT_FALSE); } diff --git a/tests/kernel/mem_protect/obj_validation/src/main.c b/tests/kernel/mem_protect/obj_validation/src/main.c index 2ca87a11ed9..3b0b2a3cae9 100644 --- a/tests/kernel/mem_protect/obj_validation/src/main.c +++ b/tests/kernel/mem_protect/obj_validation/src/main.c @@ -34,7 +34,7 @@ static int test_object(struct k_sem *sem, int retval) /* Expected to fail; bypass k_object_validation_check() so we don't * fill the logs with spam */ - ret = z_object_validate(k_object_find(sem), K_OBJ_SEM, 0); + ret = k_object_validate(k_object_find(sem), K_OBJ_SEM, 0); } else { ret = k_object_validation_check(k_object_find(sem), sem, K_OBJ_SEM, 0); @@ -179,7 +179,7 @@ ZTEST(object_validation, test_no_ref_dyn_kobj_release_mem) k_object_access_revoke(test_dyn_mutex, thread); /* check object was released, when no threads have access to it */ - ret = z_object_validate(k_object_find(test_dyn_mutex), K_OBJ_MUTEX, 0); + ret = k_object_validate(k_object_find(test_dyn_mutex), K_OBJ_MUTEX, 0); zassert_true(ret == -EBADF, "Dynamic kernel object not released"); } From 3ab356604daa0a8c0e6f212baf4445ba26825f14 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:51:23 +0000 Subject: [PATCH 3022/4498] syscall: rename z_dump_object_error -> k_object_dump_error Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 6 +++--- kernel/sched.c | 2 +- kernel/userspace.c | 2 +- kernel/userspace_handler.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 8bde1db951a..3a8d5ac381c 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -89,8 +89,8 @@ int k_object_validate(struct k_object *ko, enum k_objects otype, * @param ko If retval=-EPERM, struct k_object * that was looked up, or NULL * @param otype Expected type of the kernel object */ -void z_dump_object_error(int retval, const void *obj, - struct k_object *ko, enum k_objects otype); +void k_object_dump_error(int retval, const void *obj, + struct k_object *ko, enum k_objects otype); /** * Kernel object validation function @@ -437,7 +437,7 @@ static inline int k_object_validation_check(struct k_object *ko, #ifdef CONFIG_LOG if (ret != 0) { - z_dump_object_error(ret, obj, ko, otype); + k_object_dump_error(ret, obj, ko, otype); } #else ARG_UNUSED(obj); diff --git a/kernel/sched.c b/kernel/sched.c index aa736f6b689..87fe05fea08 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1888,7 +1888,7 @@ static bool thread_obj_validate(struct k_thread *thread) return true; default: #ifdef CONFIG_LOG - z_dump_object_error(ret, thread, ko, K_OBJ_THREAD); + k_object_dump_error(ret, thread, ko, K_OBJ_THREAD); #endif Z_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied")); } diff --git a/kernel/userspace.c b/kernel/userspace.c index ffece57043f..6fbff3ab4e3 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -661,7 +661,7 @@ static void dump_permission_error(struct k_object *ko) LOG_HEXDUMP_ERR(ko->perms, sizeof(ko->perms), "permission bitmap"); } -void z_dump_object_error(int retval, const void *obj, struct k_object *ko, +void k_object_dump_error(int retval, const void *obj, struct k_object *ko, enum k_objects otype) { switch (retval) { diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 788534e6a92..5fb75d92092 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -24,7 +24,7 @@ static struct k_object *validate_kernel_object(const void *obj, ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_ANY); if (ret != 0) { #ifdef CONFIG_LOG - z_dump_object_error(ret, obj, ko, otype); + k_object_dump_error(ret, obj, ko, otype); #endif return NULL; } From 70e791905d2458d411826de569ffa38b837a3461 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:53:39 +0000 Subject: [PATCH 3023/4498] syscall: rename z_user_string_nlen -> k_usermode_string_nlen Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/userspace.c | 4 ++-- tests/kernel/mem_protect/syscalls/src/main.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 3a8d5ac381c..336d66266d1 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -200,7 +200,7 @@ void k_object_recycle(const void *obj); * maxlen if there were no NULL terminating characters within the * first maxlen bytes. */ -static inline size_t z_user_string_nlen(const char *src, size_t maxlen, +static inline size_t k_usermode_string_nlen(const char *src, size_t maxlen, int *err) { return arch_user_string_nlen(src, maxlen, err); diff --git a/kernel/userspace.c b/kernel/userspace.c index 6fbff3ab4e3..92728ea9ef2 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -858,7 +858,7 @@ char *z_user_string_alloc_copy(const char *src, size_t maxlen) int err; char *ret = NULL; - actual_len = z_user_string_nlen(src, maxlen, &err); + actual_len = k_usermode_string_nlen(src, maxlen, &err); if (err != 0) { goto out; } @@ -890,7 +890,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen) size_t actual_len; int ret, err; - actual_len = z_user_string_nlen(src, maxlen, &err); + actual_len = k_usermode_string_nlen(src, maxlen, &err); if (err != 0) { ret = EFAULT; goto out; diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 35279e59a1a..4ecf2aed9ef 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -46,7 +46,7 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf) size_t z_impl_string_nlen(char *src, size_t maxlen, int *err) { - return z_user_string_nlen(src, maxlen, err); + return k_usermode_string_nlen(src, maxlen, err); } static inline size_t z_vrfy_string_nlen(char *src, size_t maxlen, int *err) @@ -193,14 +193,14 @@ static inline uint32_t z_vrfy_more_args(uint32_t arg1, uint32_t arg2, #include /** - * @brief Test to demonstrate usage of z_user_string_nlen() + * @brief Test to demonstrate usage of k_usermode_string_nlen() * * @details The test will be called from user mode and kernel - * mode to check the behavior of z_user_string_nlen() + * mode to check the behavior of k_usermode_string_nlen() * * @ingroup kernel_memprotect_tests * - * @see z_user_string_nlen() + * @see k_usermode_string_nlen() */ ZTEST_USER(syscalls, test_string_nlen) { From 6ba8176e33a7d2bed172139b8f12de1596bebe80 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:54:24 +0000 Subject: [PATCH 3024/4498] syscall: rename z_user_alloc_from_copy -> k_usermode_alloc_from_copy Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 2 +- kernel/userspace.c | 4 ++-- subsys/net/lib/sockets/sockets.c | 14 +++++++------- subsys/net/lib/sockets/sockets_select.c | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 336d66266d1..08f396cf26c 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -221,7 +221,7 @@ static inline size_t k_usermode_string_nlen(const char *src, size_t maxlen, * @return An allocated buffer with the data copied within it, or NULL * if some error condition occurred */ -void *z_user_alloc_from_copy(const void *src, size_t size); +void *k_usermode_alloc_from_copy(const void *src, size_t size); /** * @brief Copy data from user mode diff --git a/kernel/userspace.c b/kernel/userspace.c index 92728ea9ef2..1907fc7d846 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -806,7 +806,7 @@ void k_object_uninit(const void *obj) /* * Copy to/from helper functions used in syscall handlers */ -void *z_user_alloc_from_copy(const void *src, size_t size) +void *k_usermode_alloc_from_copy(const void *src, size_t size) { void *dst = NULL; @@ -872,7 +872,7 @@ char *z_user_string_alloc_copy(const char *src, size_t maxlen) goto out; } - ret = z_user_alloc_from_copy(src, actual_len); + ret = k_usermode_alloc_from_copy(src, actual_len); /* Someone may have modified the source string during the above * checks. Ensure what we actually copied is still terminated diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 6afd4888728..fd4f914fc84 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -955,7 +955,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, msg_copy.msg_name = NULL; msg_copy.msg_control = NULL; - msg_copy.msg_iov = z_user_alloc_from_copy(msg->msg_iov, + msg_copy.msg_iov = k_usermode_alloc_from_copy(msg->msg_iov, msg->msg_iovlen * sizeof(struct iovec)); if (!msg_copy.msg_iov) { errno = ENOMEM; @@ -964,7 +964,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, for (i = 0; i < msg->msg_iovlen; i++) { msg_copy.msg_iov[i].iov_base = - z_user_alloc_from_copy(msg->msg_iov[i].iov_base, + k_usermode_alloc_from_copy(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); if (!msg_copy.msg_iov[i].iov_base) { errno = ENOMEM; @@ -975,7 +975,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, } if (msg->msg_namelen > 0) { - msg_copy.msg_name = z_user_alloc_from_copy(msg->msg_name, + msg_copy.msg_name = k_usermode_alloc_from_copy(msg->msg_name, msg->msg_namelen); if (!msg_copy.msg_name) { errno = ENOMEM; @@ -984,7 +984,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, } if (msg->msg_controllen > 0) { - msg_copy.msg_control = z_user_alloc_from_copy(msg->msg_control, + msg_copy.msg_control = k_usermode_alloc_from_copy(msg->msg_control, msg->msg_controllen); if (!msg_copy.msg_control) { errno = ENOMEM; @@ -1906,7 +1906,7 @@ static inline int z_vrfy_zsock_poll(struct zsock_pollfd *fds, errno = EFAULT; return -1; } - fds_copy = z_user_alloc_from_copy((void *)fds, fds_size); + fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); if (!fds_copy) { errno = ENOMEM; return -1; @@ -2173,7 +2173,7 @@ int z_vrfy_zsock_getsockopt(int sock, int level, int optname, return -1; } - kernel_optval = z_user_alloc_from_copy((const void *)optval, + kernel_optval = k_usermode_alloc_from_copy((const void *)optval, kernel_optlen); Z_OOPS(!kernel_optval); @@ -2517,7 +2517,7 @@ int z_vrfy_zsock_setsockopt(int sock, int level, int optname, void *kernel_optval; int ret; - kernel_optval = z_user_alloc_from_copy((const void *)optval, optlen); + kernel_optval = k_usermode_alloc_from_copy((const void *)optval, optlen); Z_OOPS(!kernel_optval); ret = z_impl_zsock_setsockopt(sock, level, optname, diff --git a/subsys/net/lib/sockets/sockets_select.c b/subsys/net/lib/sockets/sockets_select.c index f354fd45594..3b533f63dde 100644 --- a/subsys/net/lib/sockets/sockets_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -221,7 +221,7 @@ static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, int ret = -1; if (readfds) { - readfds_copy = z_user_alloc_from_copy((void *)readfds, + readfds_copy = k_usermode_alloc_from_copy((void *)readfds, sizeof(zsock_fd_set)); if (!readfds_copy) { errno = ENOMEM; @@ -230,7 +230,7 @@ static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, } if (writefds) { - writefds_copy = z_user_alloc_from_copy((void *)writefds, + writefds_copy = k_usermode_alloc_from_copy((void *)writefds, sizeof(zsock_fd_set)); if (!writefds_copy) { errno = ENOMEM; @@ -239,7 +239,7 @@ static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, } if (exceptfds) { - exceptfds_copy = z_user_alloc_from_copy((void *)exceptfds, + exceptfds_copy = k_usermode_alloc_from_copy((void *)exceptfds, sizeof(zsock_fd_set)); if (!exceptfds_copy) { errno = ENOMEM; @@ -248,7 +248,7 @@ static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, } if (timeout) { - timeval = z_user_alloc_from_copy((void *)timeout, + timeval = k_usermode_alloc_from_copy((void *)timeout, sizeof(struct zsock_timeval)); if (!timeval) { errno = ENOMEM; From 56fddd805af0d3af75ce5cf5f1fb269024a35387 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:54:56 +0000 Subject: [PATCH 3025/4498] syscall: rename z_user_from_copy -> k_usermode_from_copy Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 16 ++++++++-------- drivers/adc/adc_handlers.c | 6 +++--- drivers/can/can_handlers.c | 12 ++++++------ drivers/charger/charger_handlers.c | 2 +- drivers/counter/counter_handlers.c | 4 ++-- drivers/dac/dac_handlers.c | 2 +- drivers/espi/espi_handlers.c | 18 +++++++++--------- drivers/flash/flash_npcx_fiu_nor.c | 4 ++-- drivers/flash/flash_stm32_ex_op.c | 4 ++-- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 10 +++++----- drivers/i2s/i2s_handlers.c | 4 ++-- drivers/peci/peci_handlers.c | 2 +- include/zephyr/internal/syscall_handler.h | 2 +- kernel/userspace.c | 4 ++-- .../userspace/prod_consumer/src/app_syscall.c | 2 +- subsys/net/ip/net_if.c | 16 ++++++++-------- subsys/net/ip/utils.c | 4 ++-- subsys/net/lib/sockets/getaddrinfo.c | 2 +- subsys/net/lib/sockets/sockets.c | 16 ++++++++-------- 19 files changed, 65 insertions(+), 65 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 1b5572e905d..c3e629f9ea5 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -377,7 +377,7 @@ The proper procedure to mitigate these attacks is to make a copies in the verification function, and only perform parameter checks on the copies, which user threads will never have access to. The implementation functions get passed the copy and not the original data sent by the user. The -:c:func:`z_user_to_copy()` and :c:func:`z_user_from_copy()` APIs exist for +:c:func:`z_user_to_copy()` and :c:func:`k_usermode_from_copy()` APIs exist for this purpose. There is one exception in place, with respect to large data buffers which are @@ -433,7 +433,7 @@ bytes processed. This too should use a stack copy: size_t size; int ret; - Z_OOPS(z_user_from_copy(&size, size_ptr, sizeof(size)); + Z_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size)); ret = z_impl_in_out_syscall(&size); Z_OOPS(z_user_to_copy(size_ptr, &size, sizeof(size))); return ret; @@ -461,11 +461,11 @@ be copied. Typically this is done by allocating copies on the stack: struct bar bar_right_copy; struct bar bar_left_copy; - Z_OOPS(z_user_from_copy(&foo_copy, foo, sizeof(*foo))); - Z_OOPS(z_user_from_copy(&bar_right_copy, foo_copy.bar_right, + Z_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); + Z_OOPS(k_usermode_from_copy(&bar_right_copy, foo_copy.bar_right, sizeof(struct bar))); foo_copy.bar_right = &bar_right_copy; - Z_OOPS(z_user_from_copy(&bar_left_copy, foo_copy.bar_left, + Z_OOPS(k_usermode_from_copy(&bar_left_copy, foo_copy.bar_left, sizeof(struct bar))); foo_copy.bar_left = &bar_left_copy; @@ -500,7 +500,7 @@ should never be used to verify if resource allocation has been successful. size_t bar_list_bytes; /* Safely copy foo into foo_copy */ - Z_OOPS(z_user_from_copy(&foo_copy, foo, sizeof(*foo))); + Z_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); /* Bounds check the count member, in the copy we made */ if (foo_copy.count > 32) { @@ -514,7 +514,7 @@ should never be used to verify if resource allocation has been successful. if (bar_list_copy == NULL) { return -ENOMEM; } - Z_OOPS(z_user_from_copy(bar_list_copy, foo_copy.bar_list, + Z_OOPS(k_usermode_from_copy(bar_list_copy, foo_copy.bar_list, bar_list_bytes)); foo_copy.bar_list = bar_list_copy; @@ -566,7 +566,7 @@ conventions are as follows: invokes :c:macro:`Z_OOPS()`. #. Any invalid access to memory found by the set of ``Z_SYSCALL_MEMORY`` APIs, - :c:func:`z_user_from_copy()`, :c:func:`z_user_to_copy()` + :c:func:`k_usermode_from_copy()`, :c:func:`z_user_to_copy()` should trigger a :c:macro:`Z_OOPS`. This happens when the caller doesn't have appropriate permissions on the memory buffer or some size calculation overflowed. diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index 7ac7d5442d1..d9fcfc90a0c 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -14,7 +14,7 @@ static inline int z_vrfy_adc_channel_setup(const struct device *dev, struct adc_channel_cfg channel_cfg; Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, channel_setup)); - Z_OOPS(z_user_from_copy(&channel_cfg, + Z_OOPS(k_usermode_from_copy(&channel_cfg, (struct adc_channel_cfg *)user_channel_cfg, sizeof(struct adc_channel_cfg))); @@ -27,13 +27,13 @@ static bool copy_sequence(struct adc_sequence *dst, struct adc_sequence_options *options, struct adc_sequence *src) { - if (z_user_from_copy(dst, src, sizeof(struct adc_sequence)) != 0) { + if (k_usermode_from_copy(dst, src, sizeof(struct adc_sequence)) != 0) { printk("couldn't copy adc_sequence struct\n"); return false; } if (dst->options) { - if (z_user_from_copy(options, dst->options, + if (k_usermode_from_copy(options, dst->options, sizeof(struct adc_sequence_options)) != 0) { printk("couldn't copy adc_options struct\n"); return false; diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index e8338e6716e..bb5e185dddf 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -14,7 +14,7 @@ static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *r int err; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(z_user_from_copy(&res_copy, res, sizeof(res_copy))); + Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing(dev, &res_copy, bitrate, sample_pnt); Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res))); @@ -29,7 +29,7 @@ static inline int z_vrfy_can_set_timing(const struct device *dev, struct can_timing timing_copy; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing)); - Z_OOPS(z_user_from_copy(&timing_copy, timing, sizeof(timing_copy))); + Z_OOPS(k_usermode_from_copy(&timing_copy, timing, sizeof(timing_copy))); return z_impl_can_set_timing(dev, &timing_copy); } @@ -81,7 +81,7 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi int err; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(z_user_from_copy(&res_copy, res, sizeof(res_copy))); + Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing_data(dev, &res_copy, bitrate, sample_pnt); Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res))); @@ -112,7 +112,7 @@ static inline int z_vrfy_can_set_timing_data(const struct device *dev, struct can_timing timing_data_copy; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data)); - Z_OOPS(z_user_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy))); + Z_OOPS(k_usermode_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy))); return z_impl_can_set_timing_data(dev, &timing_data_copy); } @@ -188,7 +188,7 @@ static inline int z_vrfy_can_send(const struct device *dev, struct can_frame frame_copy; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, send)); - Z_OOPS(z_user_from_copy(&frame_copy, frame, sizeof(frame_copy))); + Z_OOPS(k_usermode_from_copy(&frame_copy, frame, sizeof(frame_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); return z_impl_can_send(dev, &frame_copy, timeout, callback, user_data); @@ -203,7 +203,7 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(z_user_from_copy(&filter_copy, filter, sizeof(filter_copy))); + Z_OOPS(k_usermode_from_copy(&filter_copy, filter, sizeof(filter_copy))); return z_impl_can_add_rx_filter_msgq(dev, msgq, &filter_copy); } diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c index 0f2200ea724..6f4cd658b73 100644 --- a/drivers/charger/charger_handlers.c +++ b/drivers/charger/charger_handlers.c @@ -30,7 +30,7 @@ static inline int z_vrfy_charger_set_prop(const struct device *dev, const charge Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, set_property)); - Z_OOPS(z_user_from_copy(&k_val, val, sizeof(union charger_propval))); + Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union charger_propval))); return z_impl_charger_set_prop(dev, prop, &k_val); } diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 58adcd0e1f0..78a372f809d 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -89,7 +89,7 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, struct counter_alarm_cfg cfg_copy; Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); - Z_OOPS(z_user_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); + Z_OOPS(k_usermode_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_channel_alarm((const struct device *)dev, @@ -115,7 +115,7 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, struct counter_top_cfg cfg_copy; Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); - Z_OOPS(z_user_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); + Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_top_value((const struct device *)dev, diff --git a/drivers/dac/dac_handlers.c b/drivers/dac/dac_handlers.c index 7db06aea11b..76bfa2bbefb 100644 --- a/drivers/dac/dac_handlers.c +++ b/drivers/dac/dac_handlers.c @@ -14,7 +14,7 @@ static inline int z_vrfy_dac_channel_setup(const struct device *dev, struct dac_channel_cfg channel_cfg; Z_OOPS(Z_SYSCALL_DRIVER_DAC(dev, channel_setup)); - Z_OOPS(z_user_from_copy(&channel_cfg, + Z_OOPS(k_usermode_from_copy(&channel_cfg, (struct dac_channel_cfg *)user_channel_cfg, sizeof(struct dac_channel_cfg))); diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index ef90547c299..e6d903d30b9 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -14,7 +14,7 @@ static inline int z_vrfy_espi_config(const struct device *dev, struct espi_cfg cfg_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, config)); - Z_OOPS(z_user_from_copy(&cfg_copy, cfg, + Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(struct espi_cfg))); return z_impl_espi_config(dev, &cfg_copy); @@ -53,7 +53,7 @@ static inline int z_vrfy_espi_write_lpc_request(const struct device *dev, uint32_t data_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, write_lpc_request)); - Z_OOPS(z_user_from_copy(&data_copy, data, sizeof(*data))); + Z_OOPS(k_usermode_from_copy(&data_copy, data, sizeof(*data))); return z_impl_espi_write_lpc_request(dev, op, &data_copy); } @@ -92,7 +92,7 @@ static inline int z_vrfy_espi_read_request(const struct device *dev, struct espi_request_packet req_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, read_request)); - Z_OOPS(z_user_from_copy(&req_copy, req, + Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); @@ -113,7 +113,7 @@ static inline int z_vrfy_espi_write_request(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, write_request)); Z_OOPS(Z_SYSCALL_MEMORY_READ(req->data, req->len)); - Z_OOPS(z_user_from_copy(&req_copy, req, + Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); ret = z_impl_espi_write_request(dev, &req_copy); @@ -130,7 +130,7 @@ static inline int z_vrfy_espi_send_oob(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, send_oob)); Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); - Z_OOPS(z_user_from_copy(&pckt_copy, pckt, + Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); ret = z_impl_espi_send_oob(dev, &pckt_copy); @@ -146,7 +146,7 @@ static inline int z_vrfy_espi_receive_oob(const struct device *dev, struct espi_oob_packet pckt_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, receive_oob)); - Z_OOPS(z_user_from_copy(&pckt_copy, pckt, + Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); @@ -165,7 +165,7 @@ static inline int z_vrfy_espi_read_flash(const struct device *dev, struct espi_flash_packet pckt_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_read)); - Z_OOPS(z_user_from_copy(&pckt_copy, pckt, + Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); @@ -184,7 +184,7 @@ static inline int z_vrfy_espi_write_flash(const struct device *dev, struct espi_flash_packet pckt_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); - Z_OOPS(z_user_from_copy(&pckt_copy, pckt, + Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); @@ -201,7 +201,7 @@ static inline int z_vrfy_espi_flash_erase(const struct device *dev, struct espi_flash_packet pckt_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); - Z_OOPS(z_user_from_copy(&pckt_copy, pckt, + Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); diff --git a/drivers/flash/flash_npcx_fiu_nor.c b/drivers/flash/flash_npcx_fiu_nor.c index a1b2d79b24d..d60b1ee29bd 100644 --- a/drivers/flash/flash_npcx_fiu_nor.c +++ b/drivers/flash/flash_npcx_fiu_nor.c @@ -453,7 +453,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, struct npcx_ex_ops_uma_out out_copy; if (syscall_trap) { - Z_OOPS(z_user_from_copy(&in_copy, op_in, sizeof(in_copy))); + Z_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); op_in = &in_copy; op_out = &out_copy; } @@ -474,7 +474,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, struct npcx_ex_ops_qspi_oper_in in_copy; if (syscall_trap) { - Z_OOPS(z_user_from_copy(&in_copy, op_in, sizeof(in_copy))); + Z_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); op_in = &in_copy; } #endif diff --git a/drivers/flash/flash_stm32_ex_op.c b/drivers/flash/flash_stm32_ex_op.c index 37bf73840f5..b5323ae8872 100644 --- a/drivers/flash/flash_stm32_ex_op.c +++ b/drivers/flash/flash_stm32_ex_op.c @@ -36,7 +36,7 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, struct flash_stm32_ex_op_sector_wp_in in_copy; if (syscall_trap) { - Z_OOPS(z_user_from_copy(&in_copy, request, + Z_OOPS(k_usermode_from_copy(&in_copy, request, sizeof(in_copy))); request = &in_copy; } @@ -102,7 +102,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, if (request != NULL) { #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(z_user_from_copy(©, request, sizeof(copy))); + Z_OOPS(k_usermode_from_copy(©, request, sizeof(copy))); request = © } #endif diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 8fdb29de9f3..c184df73ff2 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -15,7 +15,7 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gaug Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(z_user_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); int ret = z_impl_fuel_gauge_get_prop(dev, prop, &k_val); @@ -34,8 +34,8 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); - Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); + Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); int ret = z_impl_fuel_gauge_get_props(dev, k_props, k_vals, len); @@ -66,8 +66,8 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gau Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); - Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); - Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); + Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len); diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 8e3315131b6..fc768027bf7 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -20,7 +20,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, goto out; } - Z_OOPS(z_user_from_copy(&config, (const void *)cfg_ptr, + Z_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr, sizeof(struct i2s_config))); /* Check that the k_mem_slab provided is a valid pointer and that @@ -98,7 +98,7 @@ static inline int z_vrfy_i2s_buf_write(const struct device *dev, return -ENOMEM; } - ret = z_user_from_copy(mem_block, (void *)buf, size); + ret = k_usermode_from_copy(mem_block, (void *)buf, size); if (ret) { k_mem_slab_free(tx_cfg->mem_slab, mem_block); Z_OOPS(ret); diff --git a/drivers/peci/peci_handlers.c b/drivers/peci/peci_handlers.c index 758806aaecc..c878be82edf 100644 --- a/drivers/peci/peci_handlers.c +++ b/drivers/peci/peci_handlers.c @@ -39,7 +39,7 @@ static inline int z_vrfy_peci_transfer(const struct device *dev, struct peci_msg msg_copy; Z_OOPS(Z_SYSCALL_DRIVER_PECI(dev, transfer)); - Z_OOPS(z_user_from_copy(&msg_copy, msg, sizeof(*msg))); + Z_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(*msg))); return z_impl_peci_transfer(dev, &msg_copy); } diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 08f396cf26c..77cedf12fda 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -236,7 +236,7 @@ void *k_usermode_alloc_from_copy(const void *src, size_t size); * @retval 0 On success * @retval EFAULT On memory access error */ -int z_user_from_copy(void *dst, const void *src, size_t size); +int k_usermode_from_copy(void *dst, const void *src, size_t size); /** * @brief Copy data to user mode diff --git a/kernel/userspace.c b/kernel/userspace.c index 1907fc7d846..c2c177a537f 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -842,7 +842,7 @@ static int user_copy(void *dst, const void *src, size_t size, bool to_user) return ret; } -int z_user_from_copy(void *dst, const void *src, size_t size) +int k_usermode_from_copy(void *dst, const void *src, size_t size) { return user_copy(dst, src, size, false); } @@ -907,7 +907,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen) goto out; } - ret = z_user_from_copy(dst, src, actual_len); + ret = k_usermode_from_copy(dst, src, actual_len); /* See comment above in z_user_string_alloc_copy() */ dst[actual_len - 1] = '\0'; diff --git a/samples/userspace/prod_consumer/src/app_syscall.c b/samples/userspace/prod_consumer/src/app_syscall.c index dc726096eda..85def07df54 100644 --- a/samples/userspace/prod_consumer/src/app_syscall.c +++ b/samples/userspace/prod_consumer/src/app_syscall.c @@ -38,7 +38,7 @@ static int z_vrfy_magic_syscall(unsigned int *cookie) /* Confirm that this user-supplied pointer is valid memory that * can be accessed. If it's OK, copy into cookie_copy. */ - if (z_user_from_copy(&cookie_copy, cookie, sizeof(*cookie)) != 0) { + if (k_usermode_from_copy(&cookie_copy, cookie, sizeof(*cookie)) != 0) { return -EPERM; } diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index b5887b1da86..72a5de8e3cc 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -1589,7 +1589,7 @@ static inline int z_vrfy_net_if_ipv6_addr_lookup_by_index( { struct in6_addr addr_v6; - Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_lookup_by_index(&addr_v6); } @@ -1929,7 +1929,7 @@ bool z_vrfy_net_if_ipv6_addr_add_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_add_by_index(index, &addr_v6, @@ -1965,7 +1965,7 @@ bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6); } @@ -3526,7 +3526,7 @@ static inline int z_vrfy_net_if_ipv4_addr_lookup_by_index( { struct in_addr addr_v4; - Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return z_impl_net_if_ipv4_addr_lookup_by_index(&addr_v4); } @@ -3578,7 +3578,7 @@ bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&netmask_addr, (void *)netmask, + Z_OOPS(k_usermode_from_copy(&netmask_addr, (void *)netmask, sizeof(netmask_addr))); return z_impl_net_if_ipv4_set_netmask_by_index(index, &netmask_addr); @@ -3631,7 +3631,7 @@ bool z_vrfy_net_if_ipv4_set_gw_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr))); + Z_OOPS(k_usermode_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr))); return z_impl_net_if_ipv4_set_gw_by_index(index, &gw_addr); } @@ -3805,7 +3805,7 @@ bool z_vrfy_net_if_ipv4_addr_add_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return z_impl_net_if_ipv4_addr_add_by_index(index, &addr_v4, @@ -3841,7 +3841,7 @@ bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index, return false; } - Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4); } diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index 592d391f6a4..05dfd01304a 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -307,11 +307,11 @@ char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src, Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, size)); if (family == AF_INET) { - Z_OOPS(z_user_from_copy(&addr4, (const void *)src, + Z_OOPS(k_usermode_from_copy(&addr4, (const void *)src, sizeof(addr4))); addr = &addr4; } else if (family == AF_INET6) { - Z_OOPS(z_user_from_copy(&addr6, (const void *)src, + Z_OOPS(k_usermode_from_copy(&addr6, (const void *)src, sizeof(addr6))); addr = &addr6; } else { diff --git a/subsys/net/lib/sockets/getaddrinfo.c b/subsys/net/lib/sockets/getaddrinfo.c index 5bb3f6c0125..ba782e4e5e7 100644 --- a/subsys/net/lib/sockets/getaddrinfo.c +++ b/subsys/net/lib/sockets/getaddrinfo.c @@ -281,7 +281,7 @@ static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host, uint32_t ret; if (hints) { - Z_OOPS(z_user_from_copy(&hints_copy, (void *)hints, + Z_OOPS(k_usermode_from_copy(&hints_copy, (void *)hints, sizeof(hints_copy))); } Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index fd4f914fc84..38da3dc520c 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -483,7 +483,7 @@ static inline int z_vrfy_zsock_bind(int sock, const struct sockaddr *addr, struct sockaddr_storage dest_addr_copy; Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(z_user_from_copy(&dest_addr_copy, (void *)addr, addrlen)); + Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_bind(sock, (struct sockaddr *)&dest_addr_copy, addrlen); @@ -562,7 +562,7 @@ int z_vrfy_zsock_connect(int sock, const struct sockaddr *addr, struct sockaddr_storage dest_addr_copy; Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(z_user_from_copy(&dest_addr_copy, (void *)addr, addrlen)); + Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_connect(sock, (struct sockaddr *)&dest_addr_copy, addrlen); @@ -693,7 +693,7 @@ static inline int z_vrfy_zsock_accept(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(addrlen && z_user_from_copy(&addrlen_copy, addrlen, + Z_OOPS(addrlen && k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); Z_OOPS(addr && Z_SYSCALL_MEMORY_WRITE(addr, addrlen ? addrlen_copy : 0)); @@ -865,7 +865,7 @@ ssize_t z_vrfy_zsock_sendto(int sock, const void *buf, size_t len, int flags, Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, len)); if (dest_addr) { Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(z_user_from_copy(&dest_addr_copy, (void *)dest_addr, + Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)dest_addr, addrlen)); } @@ -950,7 +950,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, size_t i; int ret; - Z_OOPS(z_user_from_copy(&msg_copy, (void *)msg, sizeof(msg_copy))); + Z_OOPS(k_usermode_from_copy(&msg_copy, (void *)msg, sizeof(msg_copy))); msg_copy.msg_name = NULL; msg_copy.msg_control = NULL; @@ -1520,7 +1520,7 @@ ssize_t z_vrfy_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, } if (addrlen) { - Z_OOPS(z_user_from_copy(&addrlen_copy, addrlen, + Z_OOPS(k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); } Z_OOPS(src_addr && Z_SYSCALL_MEMORY_WRITE(src_addr, addrlen_copy)); @@ -2591,7 +2591,7 @@ static inline int z_vrfy_zsock_getpeername(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(z_user_from_copy(&addrlen_copy, (void *)addrlen, + Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); if (Z_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { @@ -2670,7 +2670,7 @@ static inline int z_vrfy_zsock_getsockname(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(z_user_from_copy(&addrlen_copy, (void *)addrlen, + Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); if (Z_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { From 9c1aeb5fd3c027aae99e17df60288f1a846f8dd8 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 10:56:59 +0000 Subject: [PATCH 3026/4498] syscall: rename z_user_ to k_usermode_ Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 10 +++++----- drivers/can/can_handlers.c | 4 ++-- drivers/charger/charger_handlers.c | 2 +- drivers/counter/maxim_ds3231.c | 2 +- drivers/espi/espi_handlers.c | 10 +++++----- drivers/flash/flash_npcx_fiu_nor.c | 4 ++-- drivers/flash/flash_stm32_ex_op.c | 4 ++-- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 6 +++--- drivers/hwinfo/hwinfo_handlers.c | 4 ++-- drivers/i2s/i2s_handlers.c | 4 ++-- drivers/ptp_clock/ptp_clock.c | 2 +- drivers/pwm/pwm_handlers.c | 4 ++-- include/zephyr/internal/syscall_handler.h | 6 +++--- kernel/device.c | 2 +- kernel/thread.c | 6 +++--- kernel/userspace.c | 8 ++++---- .../userspace/prod_consumer/src/app_syscall.c | 2 +- subsys/net/ip/utils.c | 6 +++--- subsys/net/lib/sockets/getaddrinfo.c | 4 ++-- subsys/net/lib/sockets/socketpair.c | 2 +- subsys/net/lib/sockets/sockets.c | 18 +++++++++--------- subsys/net/lib/sockets/sockets_select.c | 6 +++--- tests/kernel/mem_protect/syscalls/src/main.c | 14 +++++++------- 23 files changed, 65 insertions(+), 65 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index c3e629f9ea5..c68dcb6f752 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -377,7 +377,7 @@ The proper procedure to mitigate these attacks is to make a copies in the verification function, and only perform parameter checks on the copies, which user threads will never have access to. The implementation functions get passed the copy and not the original data sent by the user. The -:c:func:`z_user_to_copy()` and :c:func:`k_usermode_from_copy()` APIs exist for +:c:func:`k_usermode_to_copy()` and :c:func:`k_usermode_from_copy()` APIs exist for this purpose. There is one exception in place, with respect to large data buffers which are @@ -397,12 +397,12 @@ for some integral value: int ret; ret = z_impl_some_syscall(&local_out_param); - Z_OOPS(z_user_to_copy(out_param, &local_out_param, sizeof(*out_param))); + Z_OOPS(k_usermode_to_copy(out_param, &local_out_param, sizeof(*out_param))); return ret; } Here we have allocated ``local_out_param`` on the stack, passed its address to -the implementation function, and then used :c:func:`z_user_to_copy()` to fill +the implementation function, and then used :c:func:`k_usermode_to_copy()` to fill in the memory passed in by the caller. It might be tempting to do something more concise: @@ -435,7 +435,7 @@ bytes processed. This too should use a stack copy: Z_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size)); ret = z_impl_in_out_syscall(&size); - Z_OOPS(z_user_to_copy(size_ptr, &size, sizeof(size))); + Z_OOPS(k_usermode_to_copy(size_ptr, &size, sizeof(size))); return ret; } @@ -566,7 +566,7 @@ conventions are as follows: invokes :c:macro:`Z_OOPS()`. #. Any invalid access to memory found by the set of ``Z_SYSCALL_MEMORY`` APIs, - :c:func:`k_usermode_from_copy()`, :c:func:`z_user_to_copy()` + :c:func:`k_usermode_from_copy()`, :c:func:`k_usermode_to_copy()` should trigger a :c:macro:`Z_OOPS`. This happens when the caller doesn't have appropriate permissions on the memory buffer or some size calculation overflowed. diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index bb5e185dddf..ae2541acb47 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -17,7 +17,7 @@ static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *r Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing(dev, &res_copy, bitrate, sample_pnt); - Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res))); + Z_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); return err; } @@ -84,7 +84,7 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing_data(dev, &res_copy, bitrate, sample_pnt); - Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res))); + Z_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); return err; } diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c index 6f4cd658b73..237f9ff9628 100644 --- a/drivers/charger/charger_handlers.c +++ b/drivers/charger/charger_handlers.c @@ -16,7 +16,7 @@ static inline int z_vrfy_charger_get_prop(const struct device *dev, const charge int ret = z_impl_charger_get_prop(dev, prop, &k_val); - Z_OOPS(z_user_to_copy(val, &k_val, sizeof(union charger_propval))); + Z_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union charger_propval))); return ret; } diff --git a/drivers/counter/maxim_ds3231.c b/drivers/counter/maxim_ds3231.c index 518f989cede..5f5d87490df 100644 --- a/drivers/counter/maxim_ds3231.c +++ b/drivers/counter/maxim_ds3231.c @@ -1314,7 +1314,7 @@ int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, rv = z_impl_maxim_ds3231_get_syncpoint(dev, &value); if (rv >= 0) { - Z_OOPS(z_user_to_copy(syncpoint, &value, sizeof(*syncpoint))); + Z_OOPS(k_usermode_to_copy(syncpoint, &value, sizeof(*syncpoint))); } return rv; diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index e6d903d30b9..5eaadfdc905 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -40,7 +40,7 @@ static inline int z_vrfy_espi_read_lpc_request(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, read_lpc_request)); ret = z_impl_espi_read_lpc_request(dev, op, &data_copy); - Z_OOPS(z_user_to_copy(data, &data_copy, sizeof(uint8_t))); + Z_OOPS(k_usermode_to_copy(data, &data_copy, sizeof(uint8_t))); return ret; } @@ -79,7 +79,7 @@ static inline int z_vrfy_espi_receive_vwire(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, receive_vwire)); ret = z_impl_espi_receive_vwire(dev, signal, &level_copy); - Z_OOPS(z_user_to_copy(level, &level_copy, sizeof(uint8_t))); + Z_OOPS(k_usermode_to_copy(level, &level_copy, sizeof(uint8_t))); return ret; } @@ -98,7 +98,7 @@ static inline int z_vrfy_espi_read_request(const struct device *dev, ret = z_impl_espi_read_request(dev, &req_copy); - Z_OOPS(z_user_to_copy(req, &req_copy, + Z_OOPS(k_usermode_to_copy(req, &req_copy, sizeof(struct espi_request_packet))); return ret; @@ -151,7 +151,7 @@ static inline int z_vrfy_espi_receive_oob(const struct device *dev, Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_receive_oob(dev, &pckt_copy); - Z_OOPS(z_user_to_copy(pckt, &pckt_copy, + Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, sizeof(struct espi_oob_packet))); return ret; @@ -170,7 +170,7 @@ static inline int z_vrfy_espi_read_flash(const struct device *dev, Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_read_flash(dev, pckt); - Z_OOPS(z_user_to_copy(pckt, &pckt_copy, + Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, sizeof(struct espi_flash_packet))); return ret; diff --git a/drivers/flash/flash_npcx_fiu_nor.c b/drivers/flash/flash_npcx_fiu_nor.c index d60b1ee29bd..4fcac59c027 100644 --- a/drivers/flash/flash_npcx_fiu_nor.c +++ b/drivers/flash/flash_npcx_fiu_nor.c @@ -462,7 +462,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, ret = flash_npcx_nor_ex_exec_uma(dev, op_in, op_out); #ifdef CONFIG_USERSPACE if (ret == 0 && syscall_trap) { - Z_OOPS(z_user_to_copy(out, op_out, sizeof(out_copy))); + Z_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); } #endif break; @@ -495,7 +495,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, ret = flash_npcx_nor_ex_get_spi_spec(dev, op_out); #ifdef CONFIG_USERSPACE if (ret == 0 && syscall_trap) { - Z_OOPS(z_user_to_copy(out, op_out, sizeof(out_copy))); + Z_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); } #endif break; diff --git a/drivers/flash/flash_stm32_ex_op.c b/drivers/flash/flash_stm32_ex_op.c index b5323ae8872..02e5d11279d 100644 --- a/drivers/flash/flash_stm32_ex_op.c +++ b/drivers/flash/flash_stm32_ex_op.c @@ -75,7 +75,7 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(z_user_to_copy(out, result, sizeof(out_copy))); + Z_OOPS(k_usermode_to_copy(out, result, sizeof(out_copy))); } #endif } @@ -132,7 +132,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(z_user_to_copy(out, result, sizeof(copy))); + Z_OOPS(k_usermode_to_copy(out, result, sizeof(copy))); } #endif } diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index c184df73ff2..e05f9c292b4 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -19,7 +19,7 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gaug int ret = z_impl_fuel_gauge_get_prop(dev, prop, &k_val); - Z_OOPS(z_user_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val))); return ret; } @@ -39,7 +39,7 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau int ret = z_impl_fuel_gauge_get_props(dev, k_props, k_vals, len); - Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } @@ -72,7 +72,7 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gau int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len); /* We only copy back vals because props will never be modified */ - Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); + Z_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } diff --git a/drivers/hwinfo/hwinfo_handlers.c b/drivers/hwinfo/hwinfo_handlers.c index 933e8499f4a..e9848f9d686 100644 --- a/drivers/hwinfo/hwinfo_handlers.c +++ b/drivers/hwinfo/hwinfo_handlers.c @@ -21,7 +21,7 @@ int z_vrfy_hwinfo_get_reset_cause(uint32_t *cause) uint32_t cause_copy; ret = z_impl_hwinfo_get_reset_cause(&cause_copy); - Z_OOPS(z_user_to_copy(cause, &cause_copy, sizeof(uint32_t))); + Z_OOPS(k_usermode_to_copy(cause, &cause_copy, sizeof(uint32_t))); return ret; } @@ -40,7 +40,7 @@ int z_vrfy_hwinfo_get_supported_reset_cause(uint32_t *supported) uint32_t supported_copy; ret = z_impl_hwinfo_get_supported_reset_cause(&supported_copy); - Z_OOPS(z_user_to_copy(supported, &supported_copy, sizeof(uint32_t))); + Z_OOPS(k_usermode_to_copy(supported, &supported_copy, sizeof(uint32_t))); return ret; } diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index fc768027bf7..6b268ea12d7 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -63,12 +63,12 @@ static inline int z_vrfy_i2s_buf_read(const struct device *dev, */ rx_cfg = i2s_config_get((const struct device *)dev, I2S_DIR_RX); - copy_success = z_user_to_copy((void *)buf, mem_block, + copy_success = k_usermode_to_copy((void *)buf, mem_block, data_size); k_mem_slab_free(rx_cfg->mem_slab, mem_block); Z_OOPS(copy_success); - Z_OOPS(z_user_to_copy((void *)size, &data_size, + Z_OOPS(k_usermode_to_copy((void *)size, &data_size, sizeof(data_size))); } diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c index 8f4c3a171c8..92f04cf9666 100644 --- a/drivers/ptp_clock/ptp_clock.c +++ b/drivers/ptp_clock/ptp_clock.c @@ -22,7 +22,7 @@ int z_vrfy_ptp_clock_get(const struct device *dev, return 0; } - if (z_user_to_copy((void *)tm, &ptp_time, sizeof(ptp_time)) != 0) { + if (k_usermode_to_copy((void *)tm, &ptp_time, sizeof(ptp_time)) != 0) { return 0; } diff --git a/drivers/pwm/pwm_handlers.c b/drivers/pwm/pwm_handlers.c index f6153458625..ef10c459ee9 100644 --- a/drivers/pwm/pwm_handlers.c +++ b/drivers/pwm/pwm_handlers.c @@ -64,12 +64,12 @@ static inline int z_vrfy_pwm_capture_cycles(const struct device *dev, err = z_impl_pwm_capture_cycles((const struct device *)dev, channel, flags, &period, &pulse, timeout); if (period_cycles != NULL) { - Z_OOPS(z_user_to_copy(period_cycles, &period, + Z_OOPS(k_usermode_to_copy(period_cycles, &period, sizeof(*period_cycles))); } if (pulse_cycles != NULL) { - Z_OOPS(z_user_to_copy(pulse_cycles, &pulse, + Z_OOPS(k_usermode_to_copy(pulse_cycles, &pulse, sizeof(*pulse_cycles))); } diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 77cedf12fda..59a68d41ba4 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -251,7 +251,7 @@ int k_usermode_from_copy(void *dst, const void *src, size_t size); * @retval 0 On success * @retval EFAULT On memory access error */ -int z_user_to_copy(void *dst, const void *src, size_t size); +int k_usermode_to_copy(void *dst, const void *src, size_t size); /** * @brief Copy a C string from userspace into a resource pool allocation @@ -267,7 +267,7 @@ int z_user_to_copy(void *dst, const void *src, size_t size); * @param maxlen Maximum size of the string including trailing NULL * @return The duplicated string, or NULL if an error occurred. */ -char *z_user_string_alloc_copy(const char *src, size_t maxlen); +char *k_usermode_string_alloc_copy(const char *src, size_t maxlen); /** * @brief Copy a C string from userspace into a provided buffer @@ -285,7 +285,7 @@ char *z_user_string_alloc_copy(const char *src, size_t maxlen); * to maxlen * @retval EFAULT On memory access error */ -int z_user_string_copy(char *dst, const char *src, size_t maxlen); +int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); #define Z_OOPS(expr) \ do { \ diff --git a/kernel/device.c b/kernel/device.c index 399bd7f3022..5e158a365eb 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -59,7 +59,7 @@ static inline const struct device *z_vrfy_device_get_binding(const char *name) { char name_copy[Z_DEVICE_MAX_NAME_LEN]; - if (z_user_string_copy(name_copy, (char *)name, sizeof(name_copy)) + if (k_usermode_string_copy(name_copy, (char *)name, sizeof(name_copy)) != 0) { return NULL; } diff --git a/kernel/thread.c b/kernel/thread.c index 66d81a8247e..033bd234ef2 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -266,7 +266,7 @@ static inline int z_vrfy_k_thread_name_set(struct k_thread *thread, const char * * the current z_vrfy / z_impl split does not provide a * means of doing so. */ - if (z_user_string_copy(name, (char *)str, sizeof(name)) != 0) { + if (k_usermode_string_copy(name, (char *)str, sizeof(name)) != 0) { return -EFAULT; } @@ -377,7 +377,7 @@ static inline int z_vrfy_k_thread_name_copy(k_tid_t thread, return -ENOSPC; } - return z_user_to_copy((void *)buf, thread->name, len + 1); + return k_usermode_to_copy((void *)buf, thread->name, len + 1); #else ARG_UNUSED(thread); ARG_UNUSED(buf); @@ -1070,7 +1070,7 @@ int z_vrfy_k_thread_stack_space_get(const struct k_thread *thread, return ret; } - ret = z_user_to_copy(unused_ptr, &unused, sizeof(size_t)); + ret = k_usermode_to_copy(unused_ptr, &unused, sizeof(size_t)); CHECKIF(ret != 0) { return ret; } diff --git a/kernel/userspace.c b/kernel/userspace.c index c2c177a537f..790c614e301 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -847,12 +847,12 @@ int k_usermode_from_copy(void *dst, const void *src, size_t size) return user_copy(dst, src, size, false); } -int z_user_to_copy(void *dst, const void *src, size_t size) +int k_usermode_to_copy(void *dst, const void *src, size_t size) { return user_copy(dst, src, size, true); } -char *z_user_string_alloc_copy(const char *src, size_t maxlen) +char *k_usermode_string_alloc_copy(const char *src, size_t maxlen) { size_t actual_len; int err; @@ -885,7 +885,7 @@ char *z_user_string_alloc_copy(const char *src, size_t maxlen) return ret; } -int z_user_string_copy(char *dst, const char *src, size_t maxlen) +int k_usermode_string_copy(char *dst, const char *src, size_t maxlen) { size_t actual_len; int ret, err; @@ -909,7 +909,7 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen) ret = k_usermode_from_copy(dst, src, actual_len); - /* See comment above in z_user_string_alloc_copy() */ + /* See comment above in k_usermode_string_alloc_copy() */ dst[actual_len - 1] = '\0'; out: return ret; diff --git a/samples/userspace/prod_consumer/src/app_syscall.c b/samples/userspace/prod_consumer/src/app_syscall.c index 85def07df54..c1b630ba9f2 100644 --- a/samples/userspace/prod_consumer/src/app_syscall.c +++ b/samples/userspace/prod_consumer/src/app_syscall.c @@ -47,7 +47,7 @@ static int z_vrfy_magic_syscall(unsigned int *cookie) ret = z_impl_magic_syscall(&cookie_copy); if (ret == 0 && - z_user_to_copy(cookie, &cookie_copy, sizeof(*cookie)) != 0) { + k_usermode_to_copy(cookie, &cookie_copy, sizeof(*cookie)) != 0) { return -EPERM; } diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index 05dfd01304a..42d0f3b418f 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -323,7 +323,7 @@ char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src, return 0; } - Z_OOPS(z_user_to_copy((void *)dst, str, MIN(size, sizeof(str)))); + Z_OOPS(k_usermode_to_copy((void *)dst, str, MIN(size, sizeof(str)))); return dst; } @@ -484,7 +484,7 @@ int z_vrfy_net_addr_pton(sa_family_t family, const char *src, return -EINVAL; } - if (z_user_string_copy(str, (char *)src, sizeof(str)) != 0) { + if (k_usermode_string_copy(str, (char *)src, sizeof(str)) != 0) { return -EINVAL; } @@ -495,7 +495,7 @@ int z_vrfy_net_addr_pton(sa_family_t family, const char *src, return err; } - Z_OOPS(z_user_to_copy((void *)dst, addr, size)); + Z_OOPS(k_usermode_to_copy((void *)dst, addr, size)); return 0; } diff --git a/subsys/net/lib/sockets/getaddrinfo.c b/subsys/net/lib/sockets/getaddrinfo.c index ba782e4e5e7..b5285feb156 100644 --- a/subsys/net/lib/sockets/getaddrinfo.c +++ b/subsys/net/lib/sockets/getaddrinfo.c @@ -287,7 +287,7 @@ static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host, Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); if (service) { - service_copy = z_user_string_alloc_copy((char *)service, 64); + service_copy = k_usermode_string_alloc_copy((char *)service, 64); if (!service_copy) { ret = DNS_EAI_MEMORY; goto out; @@ -295,7 +295,7 @@ static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host, } if (host) { - host_copy = z_user_string_alloc_copy((char *)host, 64); + host_copy = k_usermode_string_alloc_copy((char *)host, 64); if (!host_copy) { ret = DNS_EAI_MEMORY; goto out; diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index ca9d78b43af..3813c8f7af4 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -350,7 +350,7 @@ int z_vrfy_zsock_socketpair(int family, int type, int proto, int *sv) ret = z_impl_zsock_socketpair(family, type, proto, tmp); if (ret == 0) { - Z_OOPS(z_user_to_copy(sv, tmp, sizeof(tmp))); + Z_OOPS(k_usermode_to_copy(sv, tmp, sizeof(tmp))); } out: diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 38da3dc520c..fec5da20582 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -700,7 +700,7 @@ static inline int z_vrfy_zsock_accept(int sock, struct sockaddr *addr, ret = z_impl_zsock_accept(sock, (struct sockaddr *)addr, addrlen ? &addrlen_copy : NULL); - Z_OOPS(ret >= 0 && addrlen && z_user_to_copy(addrlen, &addrlen_copy, + Z_OOPS(ret >= 0 && addrlen && k_usermode_to_copy(addrlen, &addrlen_copy, sizeof(socklen_t))); return ret; @@ -1530,7 +1530,7 @@ ssize_t z_vrfy_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, addrlen ? &addrlen_copy : NULL); if (addrlen) { - Z_OOPS(z_user_to_copy(addrlen, &addrlen_copy, + Z_OOPS(k_usermode_to_copy(addrlen, &addrlen_copy, sizeof(socklen_t))); } @@ -1915,7 +1915,7 @@ static inline int z_vrfy_zsock_poll(struct zsock_pollfd *fds, ret = z_impl_zsock_poll(fds_copy, nfds, timeout); if (ret >= 0) { - z_user_to_copy((void *)fds, fds_copy, fds_size); + k_usermode_to_copy((void *)fds, fds_copy, fds_size); } k_free(fds_copy); @@ -1954,9 +1954,9 @@ static inline int z_vrfy_zsock_inet_pton(sa_family_t family, return -1; } - Z_OOPS(z_user_string_copy(src_copy, (char *)src, sizeof(src_copy))); + Z_OOPS(k_usermode_string_copy(src_copy, (char *)src, sizeof(src_copy))); ret = z_impl_zsock_inet_pton(family, src_copy, dst_copy); - Z_OOPS(z_user_to_copy(dst, dst_copy, dst_size)); + Z_OOPS(k_usermode_to_copy(dst, dst_copy, dst_size)); return ret; } @@ -2180,8 +2180,8 @@ int z_vrfy_zsock_getsockopt(int sock, int level, int optname, ret = z_impl_zsock_getsockopt(sock, level, optname, kernel_optval, &kernel_optlen); - Z_OOPS(z_user_to_copy((void *)optval, kernel_optval, kernel_optlen)); - Z_OOPS(z_user_to_copy((void *)optlen, &kernel_optlen, + Z_OOPS(k_usermode_to_copy((void *)optval, kernel_optval, kernel_optlen)); + Z_OOPS(k_usermode_to_copy((void *)optlen, &kernel_optlen, sizeof(socklen_t))); k_free(kernel_optval); @@ -2603,7 +2603,7 @@ static inline int z_vrfy_zsock_getpeername(int sock, struct sockaddr *addr, &addrlen_copy); if (ret == 0 && - z_user_to_copy((void *)addrlen, &addrlen_copy, + k_usermode_to_copy((void *)addrlen, &addrlen_copy, sizeof(socklen_t))) { errno = EINVAL; return -1; @@ -2682,7 +2682,7 @@ static inline int z_vrfy_zsock_getsockname(int sock, struct sockaddr *addr, &addrlen_copy); if (ret == 0 && - z_user_to_copy((void *)addrlen, &addrlen_copy, + k_usermode_to_copy((void *)addrlen, &addrlen_copy, sizeof(socklen_t))) { errno = EINVAL; return -1; diff --git a/subsys/net/lib/sockets/sockets_select.c b/subsys/net/lib/sockets/sockets_select.c index 3b533f63dde..af88e51e758 100644 --- a/subsys/net/lib/sockets/sockets_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -261,17 +261,17 @@ static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, if (ret >= 0) { if (readfds_copy) { - z_user_to_copy((void *)readfds, readfds_copy, + k_usermode_to_copy((void *)readfds, readfds_copy, sizeof(zsock_fd_set)); } if (writefds_copy) { - z_user_to_copy((void *)writefds, writefds_copy, + k_usermode_to_copy((void *)writefds, writefds_copy, sizeof(zsock_fd_set)); } if (exceptfds_copy) { - z_user_to_copy((void *)exceptfds, exceptfds_copy, + k_usermode_to_copy((void *)exceptfds, exceptfds_copy, sizeof(zsock_fd_set)); } } diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 4ecf2aed9ef..f511bd6aedb 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -59,7 +59,7 @@ static inline size_t z_vrfy_string_nlen(char *src, size_t maxlen, int *err) err_copy = -1; } - Z_OOPS(z_user_to_copy((int *)err, &err_copy, sizeof(err_copy))); + Z_OOPS(k_usermode_to_copy((int *)err, &err_copy, sizeof(err_copy))); return ret; } @@ -79,7 +79,7 @@ static inline int z_vrfy_string_alloc_copy(char *src) char *src_copy; int ret; - src_copy = z_user_string_alloc_copy((char *)src, BUF_SIZE); + src_copy = k_usermode_string_alloc_copy((char *)src, BUF_SIZE); if (!src_copy) { return -1; } @@ -102,7 +102,7 @@ int z_impl_string_copy(char *src) static inline int z_vrfy_string_copy(char *src) { - int ret = z_user_string_copy(kernel_buf, (char *)src, BUF_SIZE); + int ret = k_usermode_string_copy(kernel_buf, (char *)src, BUF_SIZE); if (ret) { return ret; @@ -123,7 +123,7 @@ int z_impl_to_copy(char *dest) static inline int z_vrfy_to_copy(char *dest) { - return z_user_to_copy((char *)dest, user_string, BUF_SIZE); + return k_usermode_to_copy((char *)dest, user_string, BUF_SIZE); } #include @@ -248,7 +248,7 @@ ZTEST_USER(syscalls, test_string_nlen) * * @ingroup kernel_memprotect_tests * - * @see z_user_string_alloc_copy(), strcmp() + * @see k_usermode_string_alloc_copy(), strcmp() */ ZTEST_USER(syscalls, test_user_string_alloc_copy) { @@ -273,7 +273,7 @@ ZTEST_USER(syscalls, test_user_string_alloc_copy) * * @ingroup kernel_memprotect_tests * - * @see z_user_string_copy(), strcmp() + * @see k_usermode_string_copy(), strcmp() */ ZTEST_USER(syscalls, test_user_string_copy) { @@ -297,7 +297,7 @@ ZTEST_USER(syscalls, test_user_string_copy) * * @ingroup kernel_memprotect_tests * - * @see memcpy(), z_user_to_copy() + * @see memcpy(), k_usermode_to_copy() */ ZTEST_USER(syscalls, test_to_copy) { From 9c4d8811836d96bfd8e8abd16a60573ab064be7a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:09:45 +0000 Subject: [PATCH 3027/4498] syscall: rename Z_SYSCALL_ to K_SYSCALL_ Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/drivers/index.rst | 2 +- doc/kernel/usermode/syscalls.rst | 42 ++++++++-------- drivers/adc/adc_handlers.c | 4 +- drivers/auxdisplay/auxdisplay_handlers.c | 38 +++++++-------- drivers/bbram/bbram_handlers.c | 18 +++---- drivers/cache/cache_handlers.c | 6 +-- drivers/can/can_handlers.c | 24 +++++----- drivers/counter/counter_handlers.c | 20 ++++---- drivers/counter/maxim_ds3231.c | 8 ++-- drivers/eeprom/eeprom_handlers.c | 4 +- drivers/entropy/entropy_handlers.c | 2 +- drivers/espi/espi_handlers.c | 14 +++--- drivers/flash/flash_handlers.c | 14 +++--- drivers/flash/flash_simulator.c | 2 +- drivers/flash/nrf_qspi_nor.c | 2 +- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 2 +- drivers/gpio/gpio_handlers.c | 8 ++-- drivers/hwinfo/hwinfo_handlers.c | 2 +- drivers/i2c/i2c_handlers.c | 12 ++--- drivers/i2s/i2s_handlers.c | 2 +- drivers/i3c/i3c_handlers.c | 10 ++-- drivers/ipm/ipm_handlers.c | 2 +- drivers/led/led_handlers.c | 14 +++--- drivers/mbox/mbox_handlers.c | 8 ++-- drivers/ps2/ps2_handlers.c | 2 +- drivers/ptp_clock/ptp_clock.c | 2 +- drivers/pwm/pwm_handlers.c | 2 +- drivers/retained_mem/retained_mem_handlers.c | 12 ++--- drivers/rtc/rtc_handlers.c | 14 +++--- drivers/sensor/sensor_handlers.c | 16 +++---- drivers/serial/uart_handlers.c | 14 +++--- drivers/smbus/smbus_handlers.c | 48 +++++++++---------- drivers/spi/spi_handlers.c | 12 ++--- .../virtualization/virt_ivshmem_handlers.c | 8 ++-- drivers/w1/w1_handlers.c | 14 +++--- include/zephyr/internal/syscall_handler.h | 26 +++++----- kernel/atomic_c.c | 10 ++-- kernel/condvar.c | 10 ++-- kernel/device.c | 2 +- kernel/events.c | 14 +++--- kernel/futex.c | 4 +- kernel/msg_q.c | 28 +++++------ kernel/mutex.c | 6 +-- kernel/paging/statistics.c | 12 ++--- kernel/pipes.c | 22 ++++----- kernel/poll.c | 24 +++++----- kernel/queue.c | 16 +++---- kernel/sched.c | 12 ++--- kernel/sem.c | 10 ++-- kernel/stack.c | 8 ++-- kernel/thread.c | 16 +++---- kernel/timer.c | 16 +++---- kernel/userspace.c | 6 +-- kernel/userspace_handler.c | 2 +- lib/libc/arcmwdt/libc-hooks.c | 2 +- lib/libc/newlib/libc-hooks.c | 4 +- lib/os/mutex.c | 2 +- lib/os/printk.c | 2 +- lib/posix/clock.c | 2 +- .../src/sample_driver_handlers.c | 2 +- scripts/build/gen_kobject_list.py | 4 +- scripts/build/gen_syscalls.py | 4 +- subsys/net/ip/utils.c | 4 +- subsys/net/lib/sockets/socketpair.c | 2 +- subsys/net/lib/sockets/sockets.c | 16 +++---- subsys/net/lib/sockets/sockets_misc.c | 2 +- subsys/random/rand32_handlers.c | 4 +- subsys/rtio/rtio_handlers.c | 28 +++++------ tests/benchmarks/footprints/src/userspace.c | 4 +- .../mem_protect/mem_protect/src/kobject.c | 2 +- tests/kernel/mem_protect/syscalls/src/main.c | 2 +- tests/kernel/threads/thread_stack/src/main.c | 4 +- 72 files changed, 369 insertions(+), 369 deletions(-) diff --git a/doc/kernel/drivers/index.rst b/doc/kernel/drivers/index.rst index c1a31244701..63500f1d5a0 100644 --- a/doc/kernel/drivers/index.rst +++ b/doc/kernel/drivers/index.rst @@ -239,7 +239,7 @@ implementation of both the subsystem API and the specific APIs: int z_vrfy_specific_from_user(const struct device *dev, int bar) { - Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_GENERIC, &api)); + Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_GENERIC, &api)); return z_impl_specific_do_that(dev, bar) } diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index c68dcb6f752..bbebad62d4b 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -279,24 +279,24 @@ Argument Validation Several macros exist to validate arguments: -* :c:macro:`Z_SYSCALL_OBJ()` Checks a memory address to assert that it is +* :c:macro:`K_SYSCALL_OBJ()` Checks a memory address to assert that it is a valid kernel object of the expected type, that the calling thread has permissions on it, and that the object is initialized. -* :c:macro:`Z_SYSCALL_OBJ_INIT()` is the same as - :c:macro:`Z_SYSCALL_OBJ()`, except that the provided object may be +* :c:macro:`K_SYSCALL_OBJ_INIT()` is the same as + :c:macro:`K_SYSCALL_OBJ()`, except that the provided object may be uninitialized. This is useful for verifiers of object init functions. -* :c:macro:`Z_SYSCALL_OBJ_NEVER_INIT()` is the same as - :c:macro:`Z_SYSCALL_OBJ()`, except that the provided object must be +* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` is the same as + :c:macro:`K_SYSCALL_OBJ()`, except that the provided object must be uninitialized. This is not used very often, currently only for :c:func:`k_thread_create()`. -* :c:macro:`Z_SYSCALL_MEMORY_READ()` validates a memory buffer of a particular +* :c:macro:`K_SYSCALL_MEMORY_READ()` validates a memory buffer of a particular size. The calling thread must have read permissions on the entire buffer. -* :c:macro:`Z_SYSCALL_MEMORY_WRITE()` is the same as - :c:macro:`Z_SYSCALL_MEMORY_READ()` but the calling thread must additionally +* :c:macro:`K_SYSCALL_MEMORY_WRITE()` is the same as + :c:macro:`K_SYSCALL_MEMORY_READ()` but the calling thread must additionally have write permissions. * :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` validates an array whose total size @@ -315,14 +315,14 @@ Several macros exist to validate arguments: a message parameter, instead printing the expression tested if it fails. The latter should only be used for the most obvious of tests. -* :c:macro:`Z_SYSCALL_DRIVER_OP()` checks at runtime if a driver +* :c:macro:`K_SYSCALL_DRIVER_OP()` checks at runtime if a driver instance is capable of performing a particular operation. While this macro can be used by itself, it's mostly a building block for macros that are automatically generated for every driver subsystem. For instance, to validate the GPIO driver, one could use the :c:macro:`Z_SYSCALL_DRIVER_GPIO()` macro. -* :c:macro:`Z_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that +* :c:macro:`K_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that a provided pointer is a valid instance of a specific device driver, that the calling thread has permissions on it, and that the driver has been initialized. It does this by checking the API structure pointer that @@ -357,7 +357,7 @@ For example: static int z_vrfy_k_sem_take(struct k_sem *sem, int32_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_take(sem, timeout); } #include @@ -411,7 +411,7 @@ It might be tempting to do something more concise: int z_vrfy_some_syscall(int *out_param) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param))); return z_impl_some_syscall(out_param); } @@ -528,7 +528,7 @@ should never be used to verify if resource allocation has been successful. Finally, we must consider large data buffers. These represent areas of user memory which either have data copied out of, or copied into. It is permitted to pass these pointers to the implementation function directly. The caller's -access to the buffer still must be validated with ``Z_SYSCALL_MEMORY`` APIs. +access to the buffer still must be validated with ``K_SYSCALL_MEMORY`` APIs. The following constraints need to be met: * If the buffer is used by the implementation function to write data, such @@ -549,7 +549,7 @@ The following constraints need to be met: int z_vrfy_get_data_from_kernel(void *buf, size_t size) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buf, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, size)); return z_impl_get_data_from_kernel(buf, size); } @@ -565,14 +565,14 @@ conventions are as follows: missing system calls are routed to :c:func:`handler_no_syscall()` which invokes :c:macro:`Z_OOPS()`. -#. Any invalid access to memory found by the set of ``Z_SYSCALL_MEMORY`` APIs, +#. Any invalid access to memory found by the set of ``K_SYSCALL_MEMORY`` APIs, :c:func:`k_usermode_from_copy()`, :c:func:`k_usermode_to_copy()` should trigger a :c:macro:`Z_OOPS`. This happens when the caller doesn't have appropriate permissions on the memory buffer or some size calculation overflowed. #. Most system calls take kernel object pointers as an argument, checked either - with one of the ``Z_SYSCALL_OBJ`` functions, ``Z_SYSCALL_DRIVER_nnnnn``, or + with one of the ``K_SYSCALL_OBJ`` functions, ``Z_SYSCALL_DRIVER_nnnnn``, or manually using :c:func:`k_object_validate()`. These can fail for a variety of reasons: missing driver API, bad kernel object pointer, wrong kernel object type, or improper initialization state. These issues should always @@ -632,12 +632,12 @@ APIs Helper macros for creating system call verification functions are provided in :zephyr_file:`include/zephyr/internal/syscall_handler.h`: -* :c:macro:`Z_SYSCALL_OBJ()` -* :c:macro:`Z_SYSCALL_OBJ_INIT()` -* :c:macro:`Z_SYSCALL_OBJ_NEVER_INIT()` +* :c:macro:`K_SYSCALL_OBJ()` +* :c:macro:`K_SYSCALL_OBJ_INIT()` +* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` * :c:macro:`Z_OOPS()` -* :c:macro:`Z_SYSCALL_MEMORY_READ()` -* :c:macro:`Z_SYSCALL_MEMORY_WRITE()` +* :c:macro:`K_SYSCALL_MEMORY_READ()` +* :c:macro:`K_SYSCALL_MEMORY_WRITE()` * :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` * :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` * :c:macro:`K_SYSCALL_VERIFY_MSG()` diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index d9fcfc90a0c..59af661c865 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -41,7 +41,7 @@ static bool copy_sequence(struct adc_sequence *dst, dst->options = options; } - if (Z_SYSCALL_MEMORY_WRITE(dst->buffer, dst->buffer_size) != 0) { + if (K_SYSCALL_MEMORY_WRITE(dst->buffer, dst->buffer_size) != 0) { printk("no access to buffer memory\n"); return false; } @@ -84,7 +84,7 @@ static inline int z_vrfy_adc_read_async(const struct device *dev, Z_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, "ADC sequence callbacks forbidden from user mode")); } - Z_OOPS(Z_SYSCALL_OBJ(async, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(async, K_OBJ_POLL_SIGNAL)); return z_impl_adc_read_async((const struct device *)dev, &sequence, (struct k_poll_signal *)async); diff --git a/drivers/auxdisplay/auxdisplay_handlers.c b/drivers/auxdisplay/auxdisplay_handlers.c index 70ba310f970..a7ea694a65a 100644 --- a/drivers/auxdisplay/auxdisplay_handlers.c +++ b/drivers/auxdisplay/auxdisplay_handlers.c @@ -9,21 +9,21 @@ static inline int z_vrfy_auxdisplay_display_on(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_on(dev); } #include static inline int z_vrfy_auxdisplay_display_off(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_off(dev); } #include static inline int z_vrfy_auxdisplay_cursor_set_enabled(const struct device *dev, bool enabled) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_set_enabled(dev, enabled); } #include @@ -31,7 +31,7 @@ static inline int z_vrfy_auxdisplay_cursor_set_enabled(const struct device *dev, static inline int z_vrfy_auxdisplay_position_blinking_set_enabled(const struct device *dev, bool enabled) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_position_blinking_set_enabled(dev, enabled); } #include @@ -39,7 +39,7 @@ static inline int z_vrfy_auxdisplay_position_blinking_set_enabled(const struct d static inline int z_vrfy_auxdisplay_cursor_shift_set(const struct device *dev, uint8_t direction, bool display_shift) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_shift_set(dev, direction, display_shift); } #include @@ -48,7 +48,7 @@ static inline int z_vrfy_auxdisplay_cursor_position_set(const struct device *dev enum auxdisplay_position type, int16_t x, int16_t y) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_position_set(dev, type, x, y); } #include @@ -56,7 +56,7 @@ static inline int z_vrfy_auxdisplay_cursor_position_set(const struct device *dev static inline int z_vrfy_auxdisplay_cursor_position_get(const struct device *dev, int16_t *x, int16_t *y) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_position_get(dev, x, y); } #include @@ -65,7 +65,7 @@ static inline int z_vrfy_auxdisplay_display_position_set(const struct device *de enum auxdisplay_position type, int16_t x, int16_t y) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_position_set(dev, type, x, y); } #include @@ -73,7 +73,7 @@ static inline int z_vrfy_auxdisplay_display_position_set(const struct device *de static inline int z_vrfy_auxdisplay_display_position_get(const struct device *dev, int16_t *x, int16_t *y) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_position_get(dev, x, y); } #include @@ -81,14 +81,14 @@ static inline int z_vrfy_auxdisplay_display_position_get(const struct device *de static inline int z_vrfy_auxdisplay_capabilities_get(const struct device *dev, struct auxdisplay_capabilities *capabilities) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_capabilities_get(dev, capabilities); } #include static inline int z_vrfy_auxdisplay_clear(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_clear(dev); } #include @@ -96,7 +96,7 @@ static inline int z_vrfy_auxdisplay_clear(const struct device *dev) static inline int z_vrfy_auxdisplay_brightness_get(const struct device *dev, uint8_t *brightness) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_brightness_get(dev, brightness); } #include @@ -104,7 +104,7 @@ static inline int z_vrfy_auxdisplay_brightness_get(const struct device *dev, static inline int z_vrfy_auxdisplay_brightness_set(const struct device *dev, uint8_t brightness) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_brightness_set(dev, brightness); } #include @@ -112,7 +112,7 @@ static inline int z_vrfy_auxdisplay_brightness_set(const struct device *dev, static inline int z_vrfy_auxdisplay_backlight_get(const struct device *dev, uint8_t *backlight) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_backlight_get(dev, backlight); } #include @@ -120,14 +120,14 @@ static inline int z_vrfy_auxdisplay_backlight_get(const struct device *dev, static inline int z_vrfy_auxdisplay_backlight_set(const struct device *dev, uint8_t backlight) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_backlight_set(dev, backlight); } #include static inline int z_vrfy_auxdisplay_is_busy(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_is_busy(dev); } #include @@ -135,7 +135,7 @@ static inline int z_vrfy_auxdisplay_is_busy(const struct device *dev) static inline int z_vrfy_auxdisplay_custom_character_set(const struct device *dev, struct auxdisplay_character *character) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_custom_character_set(dev, character); } #include @@ -143,7 +143,7 @@ static inline int z_vrfy_auxdisplay_custom_character_set(const struct device *de static inline int z_vrfy_auxdisplay_write(const struct device *dev, const uint8_t *data, uint16_t len) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_write(dev, data, len); } #include @@ -151,7 +151,7 @@ static inline int z_vrfy_auxdisplay_write(const struct device *dev, const uint8_ static inline int z_vrfy_auxdisplay_custom_command(const struct device *dev, struct auxdisplay_custom_data *data) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_custom_command(dev, data); } #include diff --git a/drivers/bbram/bbram_handlers.c b/drivers/bbram/bbram_handlers.c index cd173c63b0f..799262f69f4 100644 --- a/drivers/bbram/bbram_handlers.c +++ b/drivers/bbram/bbram_handlers.c @@ -9,29 +9,29 @@ static inline int z_vrfy_bbram_check_invalid(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_invalid(dev); } #include static inline int z_vrfy_bbram_check_standby_power(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_standby_power(dev); } #include static inline int z_vrfy_bbram_check_power(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_power(dev); } #include static inline int z_vrfy_bbram_get_size(const struct device *dev, size_t *size) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); return z_impl_bbram_get_size(dev, size); } #include @@ -39,8 +39,8 @@ static inline int z_vrfy_bbram_get_size(const struct device *dev, size_t *size) static inline int z_vrfy_bbram_read(const struct device *dev, size_t offset, size_t size, uint8_t *data) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, size)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, size)); return z_impl_bbram_read(dev, offset, size, data); } #include @@ -48,8 +48,8 @@ static inline int z_vrfy_bbram_read(const struct device *dev, size_t offset, static inline int z_vrfy_bbram_write(const struct device *dev, size_t offset, size_t size, const uint8_t *data) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(data, size)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + Z_OOPS(K_SYSCALL_MEMORY_READ(data, size)); return z_impl_bbram_write(dev, offset, size, data); } #include diff --git a/drivers/cache/cache_handlers.c b/drivers/cache/cache_handlers.c index 299e67baaaa..472e8f0ff58 100644 --- a/drivers/cache/cache_handlers.c +++ b/drivers/cache/cache_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_sys_cache_data_flush_range(void *addr, size_t size) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(addr, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_flush_range(addr, size); } @@ -17,7 +17,7 @@ static inline int z_vrfy_sys_cache_data_flush_range(void *addr, size_t size) static inline int z_vrfy_sys_cache_data_invd_range(void *addr, size_t size) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(addr, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_invd_range(addr, size); } @@ -25,7 +25,7 @@ static inline int z_vrfy_sys_cache_data_invd_range(void *addr, size_t size) static inline int z_vrfy_sys_cache_data_flush_and_invd_range(void *addr, size_t size) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(addr, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_flush_and_invd_range(addr, size); } diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index ae2541acb47..ccf2a4d6cc2 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -39,7 +39,7 @@ static inline int z_vrfy_can_get_core_clock(const struct device *dev, uint32_t *rate) { Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate))); return z_impl_can_get_core_clock(dev, rate); } @@ -49,8 +49,8 @@ static inline int z_vrfy_can_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate) { /* Optional API function */ - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(max_bitrate, sizeof(*max_bitrate))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(max_bitrate, sizeof(*max_bitrate))); return z_impl_can_get_max_bitrate(dev, max_bitrate); } @@ -58,7 +58,7 @@ static inline int z_vrfy_can_get_max_bitrate(const struct device *dev, static inline const struct can_timing *z_vrfy_can_get_timing_min(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_min(dev); } @@ -66,7 +66,7 @@ static inline const struct can_timing *z_vrfy_can_get_timing_min(const struct de static inline const struct can_timing *z_vrfy_can_get_timing_max(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_max(dev); } @@ -92,7 +92,7 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi static inline const struct can_timing *z_vrfy_can_get_timing_data_min(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_data_min(dev); } @@ -100,7 +100,7 @@ static inline const struct can_timing *z_vrfy_can_get_timing_data_min(const stru static inline const struct can_timing *z_vrfy_can_get_timing_data_max(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_data_max(dev); } @@ -132,7 +132,7 @@ static inline int z_vrfy_can_set_bitrate_data(const struct device *dev, static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide) { /* Optional API function */ - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_max_filters(dev, ide); } @@ -141,7 +141,7 @@ static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide) static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode_t *cap) { Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_capabilities)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap))); return z_impl_can_get_capabilities(dev, cap); } @@ -202,7 +202,7 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, struct can_filter filter_copy; Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); Z_OOPS(k_usermode_from_copy(&filter_copy, filter, sizeof(filter_copy))); return z_impl_can_add_rx_filter_msgq(dev, msgq, &filter_copy); @@ -223,11 +223,11 @@ static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_state)); if (state != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(state, sizeof(*state))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(state, sizeof(*state))); } if (err_cnt != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(*err_cnt))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(*err_cnt))); } return z_impl_can_get_state(dev, state, err_cnt); diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 78a372f809d..6f649523079 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -27,21 +27,21 @@ COUNTER_HANDLER(start) static inline bool z_vrfy_counter_is_counting_up(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_is_counting_up((const struct device *)dev); } #include static inline uint8_t z_vrfy_counter_get_num_of_channels(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_num_of_channels((const struct device *)dev); } #include static inline uint32_t z_vrfy_counter_get_frequency(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_frequency((const struct device *)dev); } #include @@ -49,7 +49,7 @@ static inline uint32_t z_vrfy_counter_get_frequency(const struct device *dev) static inline uint32_t z_vrfy_counter_us_to_ticks(const struct device *dev, uint64_t us) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_us_to_ticks((const struct device *)dev, (uint64_t)us); } @@ -58,7 +58,7 @@ static inline uint32_t z_vrfy_counter_us_to_ticks(const struct device *dev, static inline uint64_t z_vrfy_counter_ticks_to_us(const struct device *dev, uint32_t ticks) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_ticks_to_us((const struct device *)dev, (uint32_t)ticks); } @@ -68,7 +68,7 @@ static inline int z_vrfy_counter_get_value(const struct device *dev, uint32_t *ticks) { Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, get_value)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value((const struct device *)dev, ticks); } @@ -76,7 +76,7 @@ static inline int z_vrfy_counter_get_value_64(const struct device *dev, uint64_t *ticks) { Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, get_value_64)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value_64((const struct device *)dev, ticks); } @@ -133,7 +133,7 @@ static inline uint32_t z_vrfy_counter_get_top_value(const struct device *dev) static inline uint32_t z_vrfy_counter_get_max_top_value(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_max_top_value((const struct device *)dev); } #include @@ -141,7 +141,7 @@ static inline uint32_t z_vrfy_counter_get_max_top_value(const struct device *dev static inline uint32_t z_vrfy_counter_get_guard_period(const struct device *dev, uint32_t flags) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_guard_period((const struct device *)dev, flags); } @@ -150,7 +150,7 @@ static inline uint32_t z_vrfy_counter_get_guard_period(const struct device *dev, static inline int z_vrfy_counter_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_set_guard_period((const struct device *)dev, ticks, flags); diff --git a/drivers/counter/maxim_ds3231.c b/drivers/counter/maxim_ds3231.c index 5f5d87490df..19241a22990 100644 --- a/drivers/counter/maxim_ds3231.c +++ b/drivers/counter/maxim_ds3231.c @@ -1308,8 +1308,8 @@ int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, struct maxim_ds3231_syncpoint value; int rv; - Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint))); + Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint))); rv = z_impl_maxim_ds3231_get_syncpoint(dev, &value); @@ -1325,9 +1325,9 @@ int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, int z_vrfy_maxim_ds3231_req_syncpoint(const struct device *dev, struct k_poll_signal *sig) { - Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); + Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); if (sig != NULL) { - Z_OOPS(Z_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); } return z_impl_maxim_ds3231_req_syncpoint(dev, sig); diff --git a/drivers/eeprom/eeprom_handlers.c b/drivers/eeprom/eeprom_handlers.c index 25aee5d874c..89433f6bb50 100644 --- a/drivers/eeprom/eeprom_handlers.c +++ b/drivers/eeprom/eeprom_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, void *data, size_t len) { Z_OOPS(Z_SYSCALL_DRIVER_EEPROM(dev, read)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_eeprom_read((const struct device *)dev, offset, (void *)data, len); @@ -22,7 +22,7 @@ static inline int z_vrfy_eeprom_write(const struct device *dev, off_t offset, const void *data, size_t len) { Z_OOPS(Z_SYSCALL_DRIVER_EEPROM(dev, write)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(data, len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_eeprom_write((const struct device *)dev, offset, (const void *)data, len); } diff --git a/drivers/entropy/entropy_handlers.c b/drivers/entropy/entropy_handlers.c index 3bdff1d267b..7d62960e14a 100644 --- a/drivers/entropy/entropy_handlers.c +++ b/drivers/entropy/entropy_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_entropy_get_entropy(const struct device *dev, uint16_t len) { Z_OOPS(Z_SYSCALL_DRIVER_ENTROPY(dev, get_entropy)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); return z_impl_entropy_get_entropy((const struct device *)dev, (uint8_t *)buffer, len); diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index 5eaadfdc905..c82fbc43e6c 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -94,7 +94,7 @@ static inline int z_vrfy_espi_read_request(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, read_request)); Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); ret = z_impl_espi_read_request(dev, &req_copy); @@ -112,7 +112,7 @@ static inline int z_vrfy_espi_write_request(const struct device *dev, struct espi_request_packet req_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, write_request)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(req->data, req->len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(req->data, req->len)); Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); @@ -129,7 +129,7 @@ static inline int z_vrfy_espi_send_oob(const struct device *dev, struct espi_oob_packet pckt_copy; Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, send_oob)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); @@ -148,7 +148,7 @@ static inline int z_vrfy_espi_receive_oob(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, receive_oob)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_receive_oob(dev, &pckt_copy); Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, @@ -167,7 +167,7 @@ static inline int z_vrfy_espi_read_flash(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_read)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_read_flash(dev, pckt); Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, @@ -186,7 +186,7 @@ static inline int z_vrfy_espi_write_flash(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); ret = z_impl_espi_write_flash(dev, &pckt_copy); @@ -203,7 +203,7 @@ static inline int z_vrfy_espi_flash_erase(const struct device *dev, Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(Z_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); ret = z_impl_espi_flash_erase(dev, &pckt_copy); diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index d43a78891f9..0a1c0274213 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, void *data, size_t len) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_read((const struct device *)dev, offset, (void *)data, len); @@ -22,7 +22,7 @@ static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, const void *data, size_t len) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, write)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(data, len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_flash_write((const struct device *)dev, offset, (const void *)data, len); } @@ -38,7 +38,7 @@ static inline int z_vrfy_flash_erase(const struct device *dev, off_t offset, static inline size_t z_vrfy_flash_get_write_block_size(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); return z_impl_flash_get_write_block_size(dev); } #include @@ -56,7 +56,7 @@ static inline int z_vrfy_flash_get_page_info_by_offs(const struct device *dev, struct flash_pages_info *info) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_offs((const struct device *)dev, offs, (struct flash_pages_info *)info); @@ -68,7 +68,7 @@ static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev, struct flash_pages_info *info) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_idx((const struct device *)dev, idx, (struct flash_pages_info *)info); @@ -91,7 +91,7 @@ static inline int z_vrfy_flash_sfdp_read(const struct device *dev, void *data, size_t len) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, sfdp_read)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_sfdp_read(dev, offset, data, len); } #include @@ -100,7 +100,7 @@ static inline int z_vrfy_flash_read_jedec_id(const struct device *dev, uint8_t *id) { Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read_jedec_id)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(id, 3)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(id, 3)); return z_impl_flash_read_jedec_id(dev, id); } #include diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 51a8afdb5ca..f06f0e69750 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -486,7 +486,7 @@ void *z_impl_flash_simulator_get_memory(const struct device *dev, void *z_vrfy_flash_simulator_get_memory(const struct device *dev, size_t *mock_size) { - Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); + Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); return z_impl_flash_simulator_get_memory(dev, mock_size); } diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index a499ec63e10..0540ef2360a 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1468,7 +1468,7 @@ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { - Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, + Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &qspi_nor_api)); z_impl_nrf_qspi_nor_xip_enable(dev, enable); diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index e05f9c292b4..412153ada1f 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -85,7 +85,7 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, { Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, dst_len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, dst_len)); int ret = z_impl_fuel_gauge_get_buffer_prop(dev, prop, dst, dst_len); diff --git a/drivers/gpio/gpio_handlers.c b/drivers/gpio/gpio_handlers.c index 019afff4c50..981d56ad73e 100644 --- a/drivers/gpio/gpio_handlers.c +++ b/drivers/gpio/gpio_handlers.c @@ -24,7 +24,7 @@ static inline int z_vrfy_gpio_pin_get_config(const struct device *port, gpio_flags_t *flags) { Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, pin_get_config)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(flags, sizeof(gpio_flags_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(flags, sizeof(gpio_flags_t))); return z_impl_gpio_pin_get_config(port, pin, flags); } @@ -35,7 +35,7 @@ static inline int z_vrfy_gpio_port_get_raw(const struct device *port, gpio_port_value_t *value) { Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_get_raw)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(value, sizeof(gpio_port_value_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(gpio_port_value_t))); return z_impl_gpio_port_get_raw((const struct device *)port, (gpio_port_value_t *)value); } @@ -105,11 +105,11 @@ static inline int z_vrfy_gpio_port_get_direction(const struct device *dev, gpio_ Z_OOPS(Z_SYSCALL_DRIVER_GPIO(dev, port_get_direction)); if (inputs != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(inputs, sizeof(gpio_port_pins_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(inputs, sizeof(gpio_port_pins_t))); } if (outputs != NULL) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(outputs, sizeof(gpio_port_pins_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(outputs, sizeof(gpio_port_pins_t))); } return z_impl_gpio_port_get_direction(dev, map, inputs, outputs); diff --git a/drivers/hwinfo/hwinfo_handlers.c b/drivers/hwinfo/hwinfo_handlers.c index e9848f9d686..b9727bd4ab7 100644 --- a/drivers/hwinfo/hwinfo_handlers.c +++ b/drivers/hwinfo/hwinfo_handlers.c @@ -9,7 +9,7 @@ ssize_t z_vrfy_hwinfo_get_device_id(uint8_t *buffer, size_t length) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, length)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, length)); return z_impl_hwinfo_get_device_id((uint8_t *)buffer, (size_t)length); } diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index b1e9906fc61..34bfb34d11e 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -20,7 +20,7 @@ static inline int z_vrfy_i2c_get_config(const struct device *dev, uint32_t *dev_config) { Z_OOPS(Z_SYSCALL_DRIVER_I2C(dev, get_config)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_i2c_get_config(dev, dev_config); } @@ -41,7 +41,7 @@ static uint32_t copy_msgs_and_transfer(const struct device *dev, * that the target buffer be writable */ for (i = 0U; i < num_msgs; i++) { - Z_OOPS(Z_SYSCALL_MEMORY(copy[i].buf, copy[i].len, + Z_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, copy[i].flags & I2C_MSG_READ)); } @@ -52,7 +52,7 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); /* copy_msgs_and_transfer() will allocate a copy on the stack using * VLA, so ensure this won't blow the stack. Most functions defined @@ -73,21 +73,21 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, static inline int z_vrfy_i2c_target_driver_register(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_target_driver_register(dev); } #include static inline int z_vrfy_i2c_target_driver_unregister(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_target_driver_unregister(dev); } #include static inline int z_vrfy_i2c_recover_bus(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_recover_bus(dev); } #include diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 6b268ea12d7..48ffe50297a 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -26,7 +26,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, /* Check that the k_mem_slab provided is a valid pointer and that * the caller has permission on it */ - if (Z_SYSCALL_OBJ(config.mem_slab, K_OBJ_MEM_SLAB)) { + if (K_SYSCALL_OBJ(config.mem_slab, K_OBJ_MEM_SLAB)) { goto out; } diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index 9d5cbd4880a..2da70b520d6 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -12,8 +12,8 @@ static inline int z_vrfy_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) { Z_OOPS(Z_SYSCALL_DRIVER_I3C(dev, do_ccc)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(payload, sizeof(*payload))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); + Z_OOPS(K_SYSCALL_MEMORY_READ(payload, sizeof(*payload))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); if (payload->ccc.data != NULL) { Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->ccc.data, @@ -51,7 +51,7 @@ static uint32_t copy_i3c_msgs_and_transfer(struct i3c_device_desc *target, * that the target buffer be writable */ for (i = 0U; i < num_msgs; i++) { - Z_OOPS(Z_SYSCALL_MEMORY(copy[i].buf, copy[i].len, + Z_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, copy[i].flags & I3C_MSG_READ)); } @@ -61,8 +61,8 @@ static uint32_t copy_i3c_msgs_and_transfer(struct i3c_device_desc *target, static inline int z_vrfy_i3c_transfer(struct i3c_device_desc *target, struct i3c_msg *msgs, uint8_t num_msgs) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(target, sizeof(*target))); - Z_OOPS(Z_SYSCALL_OBJ(target->bus, K_OBJ_DRIVER_I3C)); + Z_OOPS(K_SYSCALL_MEMORY_READ(target, sizeof(*target))); + Z_OOPS(K_SYSCALL_OBJ(target->bus, K_OBJ_DRIVER_I3C)); /* copy_msgs_and_transfer() will allocate a copy on the stack using * VLA, so ensure this won't blow the stack. Most functions defined diff --git a/drivers/ipm/ipm_handlers.c b/drivers/ipm/ipm_handlers.c index 021d80a17b3..5ad930be899 100644 --- a/drivers/ipm/ipm_handlers.c +++ b/drivers/ipm/ipm_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_ipm_send(const struct device *dev, int wait, const void *data, int size) { Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, send)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(data, size)); + Z_OOPS(K_SYSCALL_MEMORY_READ(data, size)); return z_impl_ipm_send((const struct device *)dev, wait, id, (const void *)data, size); } diff --git a/drivers/led/led_handlers.c b/drivers/led/led_handlers.c index ecffa05be31..1a500e31bcc 100644 --- a/drivers/led/led_handlers.c +++ b/drivers/led/led_handlers.c @@ -19,8 +19,8 @@ static inline int z_vrfy_led_blink(const struct device *dev, uint32_t led, static inline int z_vrfy_led_get_info(const struct device *dev, uint32_t led, const struct led_info **info) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(*info))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(*info))); return z_impl_led_get_info(dev, led, info); } #include @@ -39,8 +39,8 @@ static inline int z_vrfy_led_write_channels(const struct device *dev, uint32_t start_channel, uint32_t num_channels, const uint8_t *buf) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, num_channels)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, num_channels)); return z_impl_led_write_channels(dev, start_channel, num_channels, buf); } #include @@ -48,7 +48,7 @@ z_vrfy_led_write_channels(const struct device *dev, uint32_t start_channel, static inline int z_vrfy_led_set_channel(const struct device *dev, uint32_t channel, uint8_t value) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); return z_impl_led_set_channel(dev, channel, value); } #include @@ -56,8 +56,8 @@ static inline int z_vrfy_led_set_channel(const struct device *dev, static inline int z_vrfy_led_set_color(const struct device *dev, uint32_t led, uint8_t num_colors, const uint8_t *color) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(color, num_colors)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + Z_OOPS(K_SYSCALL_MEMORY_READ(color, num_colors)); return z_impl_led_set_color(dev, led, num_colors, color); } #include diff --git a/drivers/mbox/mbox_handlers.c b/drivers/mbox/mbox_handlers.c index f09beabb77a..2b9fd6821c3 100644 --- a/drivers/mbox/mbox_handlers.c +++ b/drivers/mbox/mbox_handlers.c @@ -10,10 +10,10 @@ static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, const struct mbox_msg *msg) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); + Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); Z_OOPS(Z_SYSCALL_DRIVER_MBOX(channel->dev, send)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg))); - Z_OOPS(Z_SYSCALL_MEMORY_READ(msg->data, msg->size)); + Z_OOPS(K_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg))); + Z_OOPS(K_SYSCALL_MEMORY_READ(msg->data, msg->size)); return z_impl_mbox_send(channel, msg); } @@ -37,7 +37,7 @@ static inline uint32_t z_vrfy_mbox_max_channels_get(const struct device *dev) static inline int z_vrfy_mbox_set_enabled(const struct mbox_channel *channel, bool enable) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); + Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); Z_OOPS(Z_SYSCALL_DRIVER_MBOX(channel->dev, set_enabled)); return z_impl_mbox_set_enabled(channel, enable); diff --git a/drivers/ps2/ps2_handlers.c b/drivers/ps2/ps2_handlers.c index 987ac1e620b..dadd5294ecd 100644 --- a/drivers/ps2/ps2_handlers.c +++ b/drivers/ps2/ps2_handlers.c @@ -27,7 +27,7 @@ static inline int z_vrfy_ps2_write(const struct device *dev, uint8_t value) static inline int z_vrfy_ps2_read(const struct device *dev, uint8_t *value) { Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, read)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(value, sizeof(uint8_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(uint8_t))); return z_impl_ps2_read(dev, value); } #include diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c index 92f04cf9666..7e6c1e8cbad 100644 --- a/drivers/ptp_clock/ptp_clock.c +++ b/drivers/ptp_clock/ptp_clock.c @@ -15,7 +15,7 @@ int z_vrfy_ptp_clock_get(const struct device *dev, int ret; Z_OOPS(Z_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); ret = z_impl_ptp_clock_get((const struct device *)dev, &ptp_time); if (ret != 0) { diff --git a/drivers/pwm/pwm_handlers.c b/drivers/pwm/pwm_handlers.c index ef10c459ee9..d5f3029de6f 100644 --- a/drivers/pwm/pwm_handlers.c +++ b/drivers/pwm/pwm_handlers.c @@ -23,7 +23,7 @@ static inline int z_vrfy_pwm_get_cycles_per_sec(const struct device *dev, uint64_t *cycles) { Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint64_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint64_t))); return z_impl_pwm_get_cycles_per_sec((const struct device *)dev, channel, (uint64_t *)cycles); } diff --git a/drivers/retained_mem/retained_mem_handlers.c b/drivers/retained_mem/retained_mem_handlers.c index e69b2eeec67..4189bbacf3e 100644 --- a/drivers/retained_mem/retained_mem_handlers.c +++ b/drivers/retained_mem/retained_mem_handlers.c @@ -9,7 +9,7 @@ static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); return z_impl_retained_mem_size(dev); } #include @@ -17,8 +17,8 @@ static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev) static inline int z_vrfy_retained_mem_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, size)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, size)); return z_impl_retained_mem_read(dev, offset, buffer, size); } #include @@ -26,15 +26,15 @@ static inline int z_vrfy_retained_mem_read(const struct device *dev, off_t offse static inline int z_vrfy_retained_mem_write(const struct device *dev, off_t offset, const uint8_t *buffer, size_t size) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buffer, size)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buffer, size)); return z_impl_retained_mem_write(dev, offset, buffer, size); } #include static inline int z_vrfy_retained_mem_clear(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); return z_impl_retained_mem_clear(dev); } #include diff --git a/drivers/rtc/rtc_handlers.c b/drivers/rtc/rtc_handlers.c index 28c598f8e1a..dcd91377cf6 100644 --- a/drivers/rtc/rtc_handlers.c +++ b/drivers/rtc/rtc_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_time)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_set_time(dev, timeptr); } #include @@ -18,7 +18,7 @@ static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time *timeptr) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_time)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_get_time(dev, timeptr); } #include @@ -28,7 +28,7 @@ static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev uint16_t *mask) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); return z_impl_rtc_alarm_get_supported_fields(dev, id, mask); } #include @@ -37,7 +37,7 @@ static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t i const struct rtc_time *timeptr) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_set_time(dev, id, mask, timeptr); } #include @@ -46,8 +46,8 @@ static inline int z_vrfy_rtc_alarm_get_time(const struct device *dev, uint16_t i struct rtc_time *timeptr) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_get_time(dev, id, mask, timeptr); } #include @@ -72,7 +72,7 @@ static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t c static inline int z_vrfy_rtc_get_calibration(const struct device *dev, int32_t *calibration) { Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_calibration)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); return z_impl_rtc_get_calibration(dev, calibration); } #include diff --git a/drivers/sensor/sensor_handlers.c b/drivers/sensor/sensor_handlers.c index 668bf2d5a81..18481024465 100644 --- a/drivers/sensor/sensor_handlers.c +++ b/drivers/sensor/sensor_handlers.c @@ -13,7 +13,7 @@ static inline int z_vrfy_sensor_attr_set(const struct device *dev, const struct sensor_value *val) { Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, attr_set)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value))); + Z_OOPS(K_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_set((const struct device *)dev, chan, attr, (const struct sensor_value *)val); } @@ -25,7 +25,7 @@ static inline int z_vrfy_sensor_attr_get(const struct device *dev, struct sensor_value *val) { Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, attr_get)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_get((const struct device *)dev, chan, attr, (struct sensor_value *)val); } @@ -52,7 +52,7 @@ static inline int z_vrfy_sensor_channel_get(const struct device *dev, struct sensor_value *val) { Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, channel_get)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_channel_get((const struct device *)dev, chan, (struct sensor_value *)val); } @@ -62,8 +62,8 @@ static inline int z_vrfy_sensor_channel_get(const struct device *dev, static inline int z_vrfy_sensor_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(decoder, sizeof(struct sensor_decoder_api))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR)); + Z_OOPS(K_SYSCALL_MEMORY_READ(decoder, sizeof(struct sensor_decoder_api))); return z_impl_sensor_get_decoder(dev, decoder); } #include @@ -73,9 +73,9 @@ static inline int z_vrfy_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const enum sensor_channel *channels, size_t num_channels) { - Z_OOPS(Z_SYSCALL_OBJ(iodev, K_OBJ_RTIO_IODEV)); - Z_OOPS(Z_SYSCALL_OBJ(sensor, K_OBJ_DRIVER_SENSOR)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(channels, sizeof(enum sensor_channel) * num_channels)); + Z_OOPS(K_SYSCALL_OBJ(iodev, K_OBJ_RTIO_IODEV)); + Z_OOPS(K_SYSCALL_OBJ(sensor, K_OBJ_DRIVER_SENSOR)); + Z_OOPS(K_SYSCALL_MEMORY_READ(channels, sizeof(enum sensor_channel) * num_channels)); return z_impl_sensor_reconfigure_read_iodev(iodev, sensor, channels, num_channels); } #include diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 6ce3107cab2..7035dc3d9e6 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -28,7 +28,7 @@ static inline int z_vrfy_uart_poll_in(const struct device *dev, unsigned char *p_char) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_in)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char))); return z_impl_uart_poll_in(dev, p_char); } #include @@ -37,7 +37,7 @@ static inline int z_vrfy_uart_poll_in_u16(const struct device *dev, uint16_t *p_u16) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_in)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(p_u16, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_u16, sizeof(uint16_t))); return z_impl_uart_poll_in_u16(dev, p_u16); } #include @@ -63,7 +63,7 @@ static inline int z_vrfy_uart_config_get(const struct device *dev, struct uart_config *cfg) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, config_get)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cfg, sizeof(struct uart_config))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(cfg, sizeof(struct uart_config))); return z_impl_uart_config_get(dev, cfg); } @@ -73,7 +73,7 @@ static inline int z_vrfy_uart_configure(const struct device *dev, const struct uart_config *cfg) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, config_get)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); + Z_OOPS(K_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); return z_impl_uart_configure(dev, cfg); } @@ -91,7 +91,7 @@ static inline int z_vrfy_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, tx)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); return z_impl_uart_tx(dev, buf, len, timeout); } #include @@ -116,7 +116,7 @@ static inline int z_vrfy_uart_rx_enable(const struct device *dev, size_t len, int32_t timeout) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, rx_enable)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buf, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); return z_impl_uart_rx_enable(dev, buf, len, timeout); } #include @@ -170,7 +170,7 @@ static inline int z_vrfy_uart_line_ctrl_get(const struct device *dev, uint32_t ctrl, uint32_t *val) { Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, line_ctrl_get)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(val, sizeof(uint32_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(uint32_t))); return z_impl_uart_line_ctrl_get((const struct device *)dev, ctrl, (uint32_t *)val); } diff --git a/drivers/smbus/smbus_handlers.c b/drivers/smbus/smbus_handlers.c index a2ed656105b..cb856800ef8 100644 --- a/drivers/smbus/smbus_handlers.c +++ b/drivers/smbus/smbus_handlers.c @@ -21,7 +21,7 @@ static inline int z_vrfy_smbus_get_config(const struct device *dev, uint32_t *dev_config) { Z_OOPS(Z_SYSCALL_DRIVER_SMBUS(dev, get_config)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_smbus_get_config(dev, dev_config); } @@ -30,7 +30,7 @@ static inline int z_vrfy_smbus_get_config(const struct device *dev, static inline int z_vrfy_smbus_quick(const struct device *dev, uint16_t addr, enum smbus_direction rw) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_quick(dev, addr, rw); } @@ -39,7 +39,7 @@ static inline int z_vrfy_smbus_quick(const struct device *dev, uint16_t addr, static inline int z_vrfy_smbus_byte_write(const struct device *dev, uint16_t addr, uint8_t byte) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_byte_write(dev, addr, byte); } @@ -48,8 +48,8 @@ static inline int z_vrfy_smbus_byte_write(const struct device *dev, static inline int z_vrfy_smbus_byte_read(const struct device *dev, uint16_t addr, uint8_t *byte) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); return z_impl_smbus_byte_read(dev, addr, byte); } @@ -59,7 +59,7 @@ static inline int z_vrfy_smbus_byte_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t byte) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_byte_data_write(dev, addr, cmd, byte); } @@ -69,8 +69,8 @@ static inline int z_vrfy_smbus_byte_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *byte) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); return z_impl_smbus_byte_data_read(dev, addr, cmd, byte); } @@ -80,7 +80,7 @@ static inline int z_vrfy_smbus_word_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t word) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_word_data_write(dev, addr, cmd, word); } @@ -90,8 +90,8 @@ static inline int z_vrfy_smbus_word_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t *word) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(word, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(word, sizeof(uint16_t))); return z_impl_smbus_word_data_read(dev, addr, cmd, word); } @@ -101,8 +101,8 @@ static inline int z_vrfy_smbus_pcall(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t send_word, uint16_t *recv_word) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(recv_word, sizeof(uint16_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(recv_word, sizeof(uint16_t))); return z_impl_smbus_pcall(dev, addr, cmd, send_word, recv_word); } @@ -112,8 +112,8 @@ static inline int z_vrfy_smbus_block_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t count, uint8_t *buf) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, count)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, count)); return z_impl_smbus_block_write(dev, addr, cmd, count, buf); } @@ -123,8 +123,8 @@ static inline int z_vrfy_smbus_block_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *count, uint8_t *buf) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(count, sizeof(uint8_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(count, sizeof(uint8_t))); return z_impl_smbus_block_read(dev, addr, cmd, count, buf); } @@ -135,9 +135,9 @@ static inline int z_vrfy_smbus_block_pcall(const struct device *dev, uint8_t snd_count, uint8_t *snd_buf, uint8_t *rcv_count, uint8_t *rcv_buf) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(snd_buf, snd_count)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(rcv_count, sizeof(uint8_t))); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_MEMORY_READ(snd_buf, snd_count)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(rcv_count, sizeof(uint8_t))); return z_impl_smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf, rcv_count, rcv_buf); @@ -147,7 +147,7 @@ static inline int z_vrfy_smbus_block_pcall(const struct device *dev, static inline int z_vrfy_smbus_smbalert_set_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_smbalert_set_cb(dev, cb); } @@ -156,7 +156,7 @@ static inline int z_vrfy_smbus_smbalert_set_cb(const struct device *dev, static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_smbalert_remove_cb(dev, cb); } @@ -165,7 +165,7 @@ static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, static inline int z_vrfy_smbus_host_notify_set_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_host_notify_set_cb(dev, cb); } @@ -174,7 +174,7 @@ static inline int z_vrfy_smbus_host_notify_set_cb(const struct device *dev, static inline int z_vrfy_smbus_host_notify_remove_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_host_notify_remove_cb(dev, cb); } diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index 1ae5d69f37e..413b596dde1 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -40,7 +40,7 @@ static struct spi_buf_set *copy_and_check(struct spi_buf_set *bufs, */ const struct spi_buf *buf = &bufs->buffers[i]; - Z_OOPS(Z_SYSCALL_MEMORY(buf->buf, buf->len, writable)); + Z_OOPS(K_SYSCALL_MEMORY(buf->buf, buf->len, writable)); } return bufs; @@ -76,14 +76,14 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, struct spi_buf_set rx_bufs_copy; struct spi_config config_copy; - Z_OOPS(Z_SYSCALL_MEMORY_READ(config, sizeof(*config))); + Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, transceive)); if (tx_bufs) { const struct spi_buf_set *tx = (const struct spi_buf_set *)tx_bufs; - Z_OOPS(Z_SYSCALL_MEMORY_READ(tx_bufs, + Z_OOPS(K_SYSCALL_MEMORY_READ(tx_bufs, sizeof(struct spi_buf_set))); memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy)); Z_OOPS(Z_SYSCALL_VERIFY(tx_bufs_copy.count < 32)); @@ -95,7 +95,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, const struct spi_buf_set *rx = (const struct spi_buf_set *)rx_bufs; - Z_OOPS(Z_SYSCALL_MEMORY_READ(rx_bufs, + Z_OOPS(K_SYSCALL_MEMORY_READ(rx_bufs, sizeof(struct spi_buf_set))); memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy)); Z_OOPS(Z_SYSCALL_VERIFY(rx_bufs_copy.count < 32)); @@ -105,7 +105,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, memcpy(&config_copy, config, sizeof(*config)); if (spi_cs_is_gpio(&config_copy)) { - Z_OOPS(Z_SYSCALL_OBJ(config_copy.cs.gpio.port, + Z_OOPS(K_SYSCALL_OBJ(config_copy.cs.gpio.port, K_OBJ_DRIVER_GPIO)); } @@ -119,7 +119,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, static inline int z_vrfy_spi_release(const struct device *dev, const struct spi_config *config) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(config, sizeof(*config))); + Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, release)); return z_impl_spi_release((const struct device *)dev, config); } diff --git a/drivers/virtualization/virt_ivshmem_handlers.c b/drivers/virtualization/virt_ivshmem_handlers.c index d102a56577f..bbeb9257a75 100644 --- a/drivers/virtualization/virt_ivshmem_handlers.c +++ b/drivers/virtualization/virt_ivshmem_handlers.c @@ -12,7 +12,7 @@ static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, uintptr_t *memmap) { Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_mem)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_mem(dev, memmap); } @@ -48,7 +48,7 @@ static inline int z_vrfy_ivshmem_register_handler(const struct device *dev, uint16_t vector) { Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, register_handler)); - Z_OOPS(Z_SYSCALL_OBJ(signal, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(signal, K_OBJ_POLL_SIGNAL)); return z_impl_ivshmem_register_handler(dev, signal, vector); } @@ -60,7 +60,7 @@ static inline size_t z_vrfy_ivshmem_get_rw_mem_section(const struct device *dev, uintptr_t *memmap) { Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_rw_mem_section)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_rw_mem_section(dev, memmap); } @@ -71,7 +71,7 @@ static inline size_t z_vrfy_ivshmem_get_output_mem_section(const struct device * uintptr_t *memmap) { Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_output_mem_section)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_output_mem_section(dev, peer_id, memmap); } diff --git a/drivers/w1/w1_handlers.c b/drivers/w1/w1_handlers.c index b6735c6064a..83e4b2afad6 100644 --- a/drivers/w1/w1_handlers.c +++ b/drivers/w1/w1_handlers.c @@ -50,8 +50,8 @@ static inline int z_vrfy_w1_write_byte(const struct device *dev, uint8_t byte) static inline int z_vrfy_w1_read_block(const struct device *dev, uint8_t *buffer, size_t len) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, len)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); return z_impl_w1_read_block((const struct device *)dev, (uint8_t *)buffer, (size_t)len); @@ -61,8 +61,8 @@ static inline int z_vrfy_w1_read_block(const struct device *dev, static inline int z_vrfy_w1_write_block(const struct device *dev, const uint8_t *buffer, size_t len) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buffer, len)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buffer, len)); return z_impl_w1_write_block((const struct device *)dev, (const uint8_t *)buffer, (size_t)len); @@ -71,7 +71,7 @@ static inline int z_vrfy_w1_write_block(const struct device *dev, static inline int z_vrfy_w1_change_bus_lock(const struct device *dev, bool lock) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); return z_impl_w1_change_bus_lock((const struct device *)dev, lock); } @@ -88,7 +88,7 @@ static inline int z_vrfy_w1_configure(const struct device *dev, static inline size_t z_vrfy_w1_get_slave_count(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); return z_impl_w1_get_slave_count((const struct device *)dev); } @@ -100,7 +100,7 @@ static inline int z_vrfy_w1_search_bus(const struct device *dev, w1_search_callback_t callback, void *user_data) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == 0, "callbacks may not be set from user mode")); diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 59a68d41ba4..ddceb01834f 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -189,7 +189,7 @@ void k_object_recycle(const void *obj); * will be safely handled and an error code returned. * * NOTE: Doesn't guarantee that user mode has actual access to this - * string, you will need to still do a Z_SYSCALL_MEMORY_READ() + * string, you will need to still do a K_SYSCALL_MEMORY_READ() * with the obtained size value to guarantee this. * * @param src String to measure size of @@ -346,7 +346,7 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * read it * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_MEMORY(ptr, size, write) \ +#define K_SYSCALL_MEMORY(ptr, size, write) \ K_SYSCALL_VERIFY_MSG(arch_buffer_validate((void *)ptr, size, write) \ == 0, \ "Memory region %p (size %zu) %s access denied", \ @@ -366,8 +366,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param size Size of the memory area * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_MEMORY_READ(ptr, size) \ - Z_SYSCALL_MEMORY(ptr, size, 0) +#define K_SYSCALL_MEMORY_READ(ptr, size) \ + K_SYSCALL_MEMORY(ptr, size, 0) /** * @brief Runtime check that a user thread has write permission to a memory area @@ -382,8 +382,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param size Size of the memory area * @param 0 on success, nonzero on failure */ -#define Z_SYSCALL_MEMORY_WRITE(ptr, size) \ - Z_SYSCALL_MEMORY(ptr, size, 1) +#define K_SYSCALL_MEMORY_WRITE(ptr, size) \ + K_SYSCALL_MEMORY(ptr, size, 1) #define K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ ({ \ @@ -393,7 +393,7 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); &product), \ "%zux%zu array is too large", \ (size_t)(nmemb), (size_t)(size)) || \ - Z_SYSCALL_MEMORY(ptr, product, write); \ + K_SYSCALL_MEMORY(ptr, product, write); \ }) /** @@ -462,7 +462,7 @@ static inline int k_object_validation_check(struct k_object *ko, * @param op Driver operation (e.g. manage_callback) * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_DRIVER_OP(ptr, api_name, op) \ +#define K_SYSCALL_DRIVER_OP(ptr, api_name, op) \ ({ \ struct api_name *__device__ = (struct api_name *) \ ((const struct device *)ptr)->api; \ @@ -490,10 +490,10 @@ static inline int k_object_validation_check(struct k_object *ko, * @param _api Expected driver API structure memory address * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \ +#define K_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \ ({ \ const struct device *_dev = (const struct device *)_device; \ - Z_SYSCALL_OBJ(_dev, _dtype) || \ + K_SYSCALL_OBJ(_dev, _dtype) || \ K_SYSCALL_VERIFY_MSG(_dev->api == _api, \ "API structure mismatch"); \ }) @@ -509,7 +509,7 @@ static inline int k_object_validation_check(struct k_object *ko, * @param type Expected kernel object type * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_OBJ(ptr, type) \ +#define K_SYSCALL_OBJ(ptr, type) \ K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE) /** @@ -523,7 +523,7 @@ static inline int k_object_validation_check(struct k_object *ko, * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_OBJ_INIT(ptr, type) \ +#define K_SYSCALL_OBJ_INIT(ptr, type) \ K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY) /** @@ -539,7 +539,7 @@ static inline int k_object_validation_check(struct k_object *ko, * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_OBJ_NEVER_INIT(ptr, type) \ +#define K_SYSCALL_OBJ_NEVER_INIT(ptr, type) \ K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE) #include diff --git a/kernel/atomic_c.c b/kernel/atomic_c.c index a9d2765e857..21ca934f012 100644 --- a/kernel/atomic_c.c +++ b/kernel/atomic_c.c @@ -42,7 +42,7 @@ static struct k_spinlock lock; #define ATOMIC_SYSCALL_HANDLER_TARGET(name) \ static inline atomic_val_t z_vrfy_##name(atomic_t *target) \ { \ - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ + Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ return z_impl_##name((atomic_t *)target); \ } @@ -50,7 +50,7 @@ static struct k_spinlock lock; static inline atomic_val_t z_vrfy_##name(atomic_t *target, \ atomic_val_t value) \ { \ - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ + Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ return z_impl_##name((atomic_t *)target, value); \ } #else @@ -108,7 +108,7 @@ bool z_impl_atomic_cas(atomic_t *target, atomic_val_t old_value, bool z_vrfy_atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); return z_impl_atomic_cas((atomic_t *)target, old_value, new_value); } @@ -138,7 +138,7 @@ static inline bool z_vrfy_atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value, atomic_ptr_val_t new_value) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); return z_impl_atomic_ptr_cas(target, old_value, new_value); } @@ -276,7 +276,7 @@ atomic_ptr_val_t z_impl_atomic_ptr_set(atomic_ptr_t *target, static inline atomic_ptr_val_t z_vrfy_atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); return z_impl_atomic_ptr_set(target, value); } diff --git a/kernel/condvar.c b/kernel/condvar.c index edd895ed0e1..25e873e7f89 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -35,7 +35,7 @@ int z_impl_k_condvar_init(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_init(struct k_condvar *condvar) { - Z_OOPS(Z_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR)); + Z_OOPS(K_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_init(condvar); } #include @@ -67,7 +67,7 @@ int z_impl_k_condvar_signal(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_signal(struct k_condvar *condvar) { - Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_signal(condvar); } #include @@ -100,7 +100,7 @@ int z_impl_k_condvar_broadcast(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_broadcast(struct k_condvar *condvar) { - Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_broadcast(condvar); } #include @@ -128,8 +128,8 @@ int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, int z_vrfy_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); - Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_condvar_wait(condvar, mutex, timeout); } #include diff --git a/kernel/device.c b/kernel/device.c index 5e158a365eb..a757fc73863 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -70,7 +70,7 @@ static inline const struct device *z_vrfy_device_get_binding(const char *name) static inline bool z_vrfy_device_is_ready(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY)); + Z_OOPS(K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY)); return z_impl_device_is_ready(dev); } diff --git a/kernel/events.c b/kernel/events.c index 39ca6fd8d50..793fd340bc5 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -68,7 +68,7 @@ void z_impl_k_event_init(struct k_event *event) #ifdef CONFIG_USERSPACE void z_vrfy_k_event_init(struct k_event *event) { - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(event, K_OBJ_EVENT)); z_impl_k_event_init(event); } #include @@ -187,7 +187,7 @@ uint32_t z_impl_k_event_post(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_post(struct k_event *event, uint32_t events) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_post(event, events); } #include @@ -201,7 +201,7 @@ uint32_t z_impl_k_event_set(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_set(struct k_event *event, uint32_t events) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_set(event, events); } #include @@ -217,7 +217,7 @@ uint32_t z_impl_k_event_set_masked(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_set_masked(struct k_event *event, uint32_t events, uint32_t events_mask) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_set_masked(event, events, events_mask); } #include @@ -231,7 +231,7 @@ uint32_t z_impl_k_event_clear(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_clear(struct k_event *event, uint32_t events) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_clear(event, events); } #include @@ -317,7 +317,7 @@ uint32_t z_impl_k_event_wait(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_wait(struct k_event *event, uint32_t events, bool reset, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_wait(event, events, reset, timeout); } #include @@ -339,7 +339,7 @@ uint32_t z_impl_k_event_wait_all(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_wait_all(struct k_event *event, uint32_t events, bool reset, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_wait_all(event, events, reset, timeout); } #include diff --git a/kernel/futex.c b/kernel/futex.c index 52584fb6432..1354a6314e4 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -54,7 +54,7 @@ int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all) static inline int z_vrfy_k_futex_wake(struct k_futex *futex, bool wake_all) { - if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) { + if (K_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) { return -EACCES; } @@ -92,7 +92,7 @@ int z_impl_k_futex_wait(struct k_futex *futex, int expected, static inline int z_vrfy_k_futex_wait(struct k_futex *futex, int expected, k_timeout_t timeout) { - if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) { + if (K_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) { return -EACCES; } diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 1d5f3aff9df..cd3c8e48ff5 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -93,7 +93,7 @@ int z_impl_k_msgq_alloc_init(struct k_msgq *msgq, size_t msg_size, int z_vrfy_k_msgq_alloc_init(struct k_msgq *msgq, size_t msg_size, uint32_t max_msgs) { - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_alloc_init(msgq, msg_size, max_msgs); } @@ -187,8 +187,8 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout static inline int z_vrfy_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(data, msgq->msg_size)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_MEMORY_READ(data, msgq->msg_size)); return z_impl_k_msgq_put(msgq, data, timeout); } @@ -206,8 +206,8 @@ void z_impl_k_msgq_get_attrs(struct k_msgq *msgq, struct k_msgq_attrs *attrs) static inline void z_vrfy_k_msgq_get_attrs(struct k_msgq *msgq, struct k_msgq_attrs *attrs) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs))); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs))); z_impl_k_msgq_get_attrs(msgq, attrs); } #include @@ -285,8 +285,8 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) static inline int z_vrfy_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_get(msgq, data, timeout); } @@ -319,8 +319,8 @@ int z_impl_k_msgq_peek(struct k_msgq *msgq, void *data) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_msgq_peek(struct k_msgq *msgq, void *data) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_peek(msgq, data); } @@ -365,8 +365,8 @@ int z_impl_k_msgq_peek_at(struct k_msgq *msgq, void *data, uint32_t idx) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_msgq_peek_at(struct k_msgq *msgq, void *data, uint32_t idx) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_peek_at(msgq, data, idx); } @@ -397,21 +397,21 @@ void z_impl_k_msgq_purge(struct k_msgq *msgq) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_msgq_purge(struct k_msgq *msgq) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); z_impl_k_msgq_purge(msgq); } #include static inline uint32_t z_vrfy_k_msgq_num_free_get(struct k_msgq *msgq) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_num_free_get(msgq); } #include static inline uint32_t z_vrfy_k_msgq_num_used_get(struct k_msgq *msgq) { - Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_num_used_get(msgq); } #include diff --git a/kernel/mutex.c b/kernel/mutex.c index 7759ab55bbc..d06522a0420 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -71,7 +71,7 @@ int z_impl_k_mutex_init(struct k_mutex *mutex) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_init(struct k_mutex *mutex) { - Z_OOPS(Z_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX)); + Z_OOPS(K_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_init(mutex); } #include @@ -200,7 +200,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) static inline int z_vrfy_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_lock(mutex, timeout); } #include @@ -284,7 +284,7 @@ int z_impl_k_mutex_unlock(struct k_mutex *mutex) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) { - Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_unlock(mutex); } #include diff --git a/kernel/paging/statistics.c b/kernel/paging/statistics.c index 8a2d3c6ed34..87cd2b04b68 100644 --- a/kernel/paging/statistics.c +++ b/kernel/paging/statistics.c @@ -102,7 +102,7 @@ void z_impl_k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats) static inline void z_vrfy_k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); z_impl_k_mem_paging_stats_get(stats); } #include @@ -125,8 +125,8 @@ static inline void z_vrfy_k_mem_paging_thread_stats_get(struct k_thread *thread, struct k_mem_paging_stats_t *stats) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); z_impl_k_mem_paging_thread_stats_get(thread, stats); } #include @@ -224,7 +224,7 @@ static inline void z_vrfy_k_mem_paging_histogram_eviction_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_eviction_get(hist); } #include @@ -233,7 +233,7 @@ static inline void z_vrfy_k_mem_paging_histogram_backing_store_page_in_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_backing_store_page_in_get(hist); } #include @@ -242,7 +242,7 @@ static inline void z_vrfy_k_mem_paging_histogram_backing_store_page_out_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_backing_store_page_out_get(hist); } #include diff --git a/kernel/pipes.c b/kernel/pipes.c index b3050b66664..01c5f36b906 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -89,7 +89,7 @@ int z_impl_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) { - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_alloc_init(pipe, size); } @@ -122,7 +122,7 @@ void z_impl_k_pipe_flush(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE void z_vrfy_k_pipe_flush(struct k_pipe *pipe) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); z_impl_k_pipe_flush(pipe); } @@ -150,7 +150,7 @@ void z_impl_k_pipe_buffer_flush(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE void z_vrfy_k_pipe_buffer_flush(struct k_pipe *pipe) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); z_impl_k_pipe_buffer_flush(pipe); } @@ -517,9 +517,9 @@ int z_vrfy_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write, size_t *bytes_written, size_t min_xfer, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written))); - Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)data, bytes_to_write)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written))); + Z_OOPS(K_SYSCALL_MEMORY_READ((void *)data, bytes_to_write)); return z_impl_k_pipe_put((struct k_pipe *)pipe, (void *)data, bytes_to_write, bytes_written, min_xfer, @@ -725,9 +725,9 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read, int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read, size_t *bytes_read, size_t min_xfer, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read)); return z_impl_k_pipe_get((struct k_pipe *)pipe, (void *)data, bytes_to_read, bytes_read, min_xfer, @@ -766,7 +766,7 @@ size_t z_impl_k_pipe_read_avail(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE size_t z_vrfy_k_pipe_read_avail(struct k_pipe *pipe) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_read_avail(pipe); } @@ -803,7 +803,7 @@ size_t z_impl_k_pipe_write_avail(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE size_t z_vrfy_k_pipe_write_avail(struct k_pipe *pipe) { - Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_write_avail(pipe); } diff --git a/kernel/poll.c b/kernel/poll.c index 4614367b8f4..5b38ebefe02 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -382,7 +382,7 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, } key = k_spin_lock(&lock); - if (Z_SYSCALL_MEMORY_WRITE(events, bounds)) { + if (K_SYSCALL_MEMORY_WRITE(events, bounds)) { k_spin_unlock(&lock, key); goto oops_free; } @@ -402,20 +402,20 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, case K_POLL_TYPE_IGNORE: break; case K_POLL_TYPE_SIGNAL: - Z_OOPS(Z_SYSCALL_OBJ(e->signal, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(e->signal, K_OBJ_POLL_SIGNAL)); break; case K_POLL_TYPE_SEM_AVAILABLE: - Z_OOPS(Z_SYSCALL_OBJ(e->sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(e->sem, K_OBJ_SEM)); break; case K_POLL_TYPE_DATA_AVAILABLE: - Z_OOPS(Z_SYSCALL_OBJ(e->queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(e->queue, K_OBJ_QUEUE)); break; case K_POLL_TYPE_MSGQ_DATA_AVAILABLE: - Z_OOPS(Z_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ)); + Z_OOPS(K_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ)); break; #ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: - Z_OOPS(Z_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE)); + Z_OOPS(K_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE)); break; #endif default: @@ -490,7 +490,7 @@ void z_impl_k_poll_signal_init(struct k_poll_signal *sig) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_poll_signal_init(struct k_poll_signal *sig) { - Z_OOPS(Z_SYSCALL_OBJ_INIT(sig, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ_INIT(sig, K_OBJ_POLL_SIGNAL)); z_impl_k_poll_signal_init(sig); } #include @@ -516,9 +516,9 @@ void z_impl_k_poll_signal_check(struct k_poll_signal *sig, void z_vrfy_k_poll_signal_check(struct k_poll_signal *sig, unsigned int *signaled, int *result) { - Z_OOPS(Z_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(signaled, sizeof(unsigned int))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(result, sizeof(int))); + Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(signaled, sizeof(unsigned int))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(result, sizeof(int))); z_impl_k_poll_signal_check(sig, signaled, result); } #include @@ -553,14 +553,14 @@ int z_impl_k_poll_signal_raise(struct k_poll_signal *sig, int result) static inline int z_vrfy_k_poll_signal_raise(struct k_poll_signal *sig, int result) { - Z_OOPS(Z_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); return z_impl_k_poll_signal_raise(sig, result); } #include static inline void z_vrfy_k_poll_signal_reset(struct k_poll_signal *sig) { - Z_OOPS(Z_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); z_impl_k_poll_signal_reset(sig); } #include diff --git a/kernel/queue.c b/kernel/queue.c index d86899c50c3..d1f9a4344ad 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -72,7 +72,7 @@ void z_impl_k_queue_init(struct k_queue *queue) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_queue_init(struct k_queue *queue) { - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE)); z_impl_k_queue_init(queue); } #include @@ -114,7 +114,7 @@ void z_impl_k_queue_cancel_wait(struct k_queue *queue) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_queue_cancel_wait(struct k_queue *queue) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); z_impl_k_queue_cancel_wait(queue); } #include @@ -217,7 +217,7 @@ int32_t z_impl_k_queue_alloc_append(struct k_queue *queue, void *data) static inline int32_t z_vrfy_k_queue_alloc_append(struct k_queue *queue, void *data) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_alloc_append(queue, data); } #include @@ -238,7 +238,7 @@ int32_t z_impl_k_queue_alloc_prepend(struct k_queue *queue, void *data) static inline int32_t z_vrfy_k_queue_alloc_prepend(struct k_queue *queue, void *data) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_alloc_prepend(queue, data); } #include @@ -405,28 +405,28 @@ void *z_impl_k_queue_peek_tail(struct k_queue *queue) static inline void *z_vrfy_k_queue_get(struct k_queue *queue, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_get(queue, timeout); } #include static inline int z_vrfy_k_queue_is_empty(struct k_queue *queue) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_is_empty(queue); } #include static inline void *z_vrfy_k_queue_peek_head(struct k_queue *queue) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_peek_head(queue); } #include static inline void *z_vrfy_k_queue_peek_tail(struct k_queue *queue) { - Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_peek_tail(queue); } #include diff --git a/kernel/sched.c b/kernel/sched.c index 87fe05fea08..f1593d442a0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -689,7 +689,7 @@ void z_impl_k_thread_suspend(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_suspend(struct k_thread *thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_thread_suspend(thread); } #include @@ -718,7 +718,7 @@ void z_impl_k_thread_resume(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_resume(struct k_thread *thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_thread_resume(thread); } #include @@ -1335,7 +1335,7 @@ int z_impl_k_thread_priority_get(k_tid_t thread) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_thread_priority_get(k_tid_t thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_thread_priority_get(thread); } #include @@ -1358,7 +1358,7 @@ void z_impl_k_thread_priority_set(k_tid_t thread, int prio) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_priority_set(k_tid_t thread, int prio) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); Z_OOPS(K_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), "invalid thread priority %d", prio)); Z_OOPS(K_SYSCALL_VERIFY_MSG((int8_t)prio >= thread->base.prio, @@ -1389,7 +1389,7 @@ static inline void z_vrfy_k_thread_deadline_set(k_tid_t tid, int deadline) { struct k_thread *thread = tid; - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); Z_OOPS(K_SYSCALL_VERIFY_MSG(deadline > 0, "invalid thread deadline %d", (int)deadline)); @@ -1583,7 +1583,7 @@ void z_sched_ipi(void) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_wakeup(k_tid_t thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_wakeup(thread); } #include diff --git a/kernel/sem.c b/kernel/sem.c index 91d64970f36..b7e04207929 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -76,7 +76,7 @@ int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, int z_vrfy_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { - Z_OOPS(Z_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM)); return z_impl_k_sem_init(sem, initial_count, limit); } #include @@ -123,7 +123,7 @@ void z_impl_k_sem_give(struct k_sem *sem) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_sem_give(struct k_sem *sem) { - Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); z_impl_k_sem_give(sem); } #include @@ -188,21 +188,21 @@ void z_impl_k_sem_reset(struct k_sem *sem) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_sem_take(struct k_sem *sem, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_take((struct k_sem *)sem, timeout); } #include static inline void z_vrfy_k_sem_reset(struct k_sem *sem) { - Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); z_impl_k_sem_reset(sem); } #include static inline unsigned int z_vrfy_k_sem_count_get(struct k_sem *sem) { - Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_count_get(sem); } #include diff --git a/kernel/stack.c b/kernel/stack.c index 5e00b76e509..90c6a0f2232 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -64,7 +64,7 @@ int32_t z_impl_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) static inline int32_t z_vrfy_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) { - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK)); Z_OOPS(Z_SYSCALL_VERIFY(num_entries > 0)); return z_impl_k_stack_alloc_init(stack, num_entries); } @@ -132,7 +132,7 @@ int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_stack_push(struct k_stack *stack, stack_data_t data) { - Z_OOPS(Z_SYSCALL_OBJ(stack, K_OBJ_STACK)); + Z_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); return z_impl_k_stack_push(stack, data); } @@ -187,8 +187,8 @@ int z_impl_k_stack_pop(struct k_stack *stack, stack_data_t *data, static inline int z_vrfy_k_stack_pop(struct k_stack *stack, stack_data_t *data, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(stack, K_OBJ_STACK)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, sizeof(stack_data_t))); + Z_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, sizeof(stack_data_t))); return z_impl_k_stack_pop(stack, data, timeout); } #include diff --git a/kernel/thread.c b/kernel/thread.c index 033bd234ef2..7bd47ae2668 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -257,7 +257,7 @@ static inline int z_vrfy_k_thread_name_set(struct k_thread *thread, const char * char name[CONFIG_THREAD_MAX_NAME_LEN]; if (thread != NULL) { - if (Z_SYSCALL_OBJ(thread, K_OBJ_THREAD) != 0) { + if (K_SYSCALL_OBJ(thread, K_OBJ_THREAD) != 0) { return -EINVAL; } } @@ -369,7 +369,7 @@ static inline int z_vrfy_k_thread_name_copy(k_tid_t thread, (ko->flags & K_OBJ_FLAG_INITIALIZED) == 0) { return -EINVAL; } - if (Z_SYSCALL_MEMORY_WRITE(buf, size) != 0) { + if (K_SYSCALL_MEMORY_WRITE(buf, size) != 0) { return -EFAULT; } len = strlen(thread->name); @@ -433,7 +433,7 @@ void z_impl_k_thread_start(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_start(struct k_thread *thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_thread_start(thread); } #include @@ -728,7 +728,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, struct k_object *stack_object; /* The thread and stack objects *must* be in an uninitialized state */ - Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD)); /* No need to check z_stack_is_user_capable(), it won't be in the * object table if it isn't @@ -966,7 +966,7 @@ int z_impl_k_float_enable(struct k_thread *thread, unsigned int options) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_float_disable(struct k_thread *thread) { - Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_float_disable(thread); } #include @@ -1060,7 +1060,7 @@ int z_vrfy_k_thread_stack_space_get(const struct k_thread *thread, size_t unused; int ret; - ret = Z_SYSCALL_OBJ(thread, K_OBJ_THREAD); + ret = K_SYSCALL_OBJ(thread, K_OBJ_THREAD); CHECKIF(ret != 0) { return ret; } @@ -1085,7 +1085,7 @@ int z_vrfy_k_thread_stack_space_get(const struct k_thread *thread, static inline k_ticks_t z_vrfy_k_thread_timeout_remaining_ticks( const struct k_thread *t) { - Z_OOPS(Z_SYSCALL_OBJ(t, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); return z_impl_k_thread_timeout_remaining_ticks(t); } #include @@ -1093,7 +1093,7 @@ static inline k_ticks_t z_vrfy_k_thread_timeout_remaining_ticks( static inline k_ticks_t z_vrfy_k_thread_timeout_expires_ticks( const struct k_thread *t) { - Z_OOPS(Z_SYSCALL_OBJ(t, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); return z_impl_k_thread_timeout_expires_ticks(t); } #include diff --git a/kernel/timer.c b/kernel/timer.c index bd69e35b027..09ec65541c1 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -185,7 +185,7 @@ static inline void z_vrfy_k_timer_start(struct k_timer *timer, k_timeout_t duration, k_timeout_t period) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_start(timer, duration, period); } #include @@ -218,7 +218,7 @@ void z_impl_k_timer_stop(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_timer_stop(struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_stop(timer); } #include @@ -238,7 +238,7 @@ uint32_t z_impl_k_timer_status_get(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline uint32_t z_vrfy_k_timer_status_get(struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_status_get(timer); } #include @@ -306,7 +306,7 @@ uint32_t z_impl_k_timer_status_sync(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline uint32_t z_vrfy_k_timer_status_sync(struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_status_sync(timer); } #include @@ -314,7 +314,7 @@ static inline uint32_t z_vrfy_k_timer_status_sync(struct k_timer *timer) static inline k_ticks_t z_vrfy_k_timer_remaining_ticks( const struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_remaining_ticks(timer); } #include @@ -322,14 +322,14 @@ static inline k_ticks_t z_vrfy_k_timer_remaining_ticks( static inline k_ticks_t z_vrfy_k_timer_expires_ticks( const struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_expires_ticks(timer); } #include static inline void *z_vrfy_k_timer_user_data_get(const struct k_timer *timer) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_user_data_get(timer); } #include @@ -337,7 +337,7 @@ static inline void *z_vrfy_k_timer_user_data_get(const struct k_timer *timer) static inline void z_vrfy_k_timer_user_data_set(struct k_timer *timer, void *user_data) { - Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_user_data_set(timer, user_data); } #include diff --git a/kernel/userspace.c b/kernel/userspace.c index 790c614e301..a3e6df69120 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -811,7 +811,7 @@ void *k_usermode_alloc_from_copy(const void *src, size_t size) void *dst = NULL; /* Does the caller in user mode have access to read this memory? */ - if (Z_SYSCALL_MEMORY_READ(src, size)) { + if (K_SYSCALL_MEMORY_READ(src, size)) { goto out_err; } @@ -831,8 +831,8 @@ static int user_copy(void *dst, const void *src, size_t size, bool to_user) int ret = EFAULT; /* Does the caller in user mode have access to this memory? */ - if (to_user ? Z_SYSCALL_MEMORY_WRITE(dst, size) : - Z_SYSCALL_MEMORY_READ(src, size)) { + if (to_user ? K_SYSCALL_MEMORY_WRITE(dst, size) : + K_SYSCALL_MEMORY_READ(src, size)) { goto out_err; } diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 5fb75d92092..616b6954182 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -58,7 +58,7 @@ static inline void z_vrfy_k_object_access_grant(const void *object, { struct k_object *ko; - Z_OOPS(Z_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); + Z_OOPS(K_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); ko = validate_any_object(object); Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", object)); diff --git a/lib/libc/arcmwdt/libc-hooks.c b/lib/libc/arcmwdt/libc-hooks.c index 223c740a63a..3a79f45afe7 100644 --- a/lib/libc/arcmwdt/libc-hooks.c +++ b/lib/libc/arcmwdt/libc-hooks.c @@ -56,7 +56,7 @@ int z_impl_zephyr_write_stdout(const void *buffer, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, nbytes)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); return z_impl_zephyr_write_stdout(buf, nbytes); } #include diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index 00ebd8607c0..294db355e5a 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -181,7 +181,7 @@ int z_impl_zephyr_read_stdin(char *buf, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_read_stdin(char *buf, int nbytes) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buf, nbytes)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, nbytes)); return z_impl_zephyr_read_stdin((char *)buf, nbytes); } #include @@ -204,7 +204,7 @@ int z_impl_zephyr_write_stdout(const void *buffer, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, nbytes)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); return z_impl_zephyr_write_stdout((const void *)buf, nbytes); } #include diff --git a/lib/os/mutex.c b/lib/os/mutex.c index b74cda0ab68..e1c6d7fb48f 100644 --- a/lib/os/mutex.c +++ b/lib/os/mutex.c @@ -27,7 +27,7 @@ static bool check_sys_mutex_addr(struct sys_mutex *addr) * underlying k_mutex, but we don't want threads using mutexes * that are outside their memory domain */ - return Z_SYSCALL_MEMORY_WRITE(addr, sizeof(struct sys_mutex)); + return K_SYSCALL_MEMORY_WRITE(addr, sizeof(struct sys_mutex)); } int z_impl_z_sys_mutex_kernel_lock(struct sys_mutex *mutex, k_timeout_t timeout) diff --git a/lib/os/printk.c b/lib/os/printk.c index 279b7067b0a..970574528ee 100644 --- a/lib/os/printk.c +++ b/lib/os/printk.c @@ -174,7 +174,7 @@ void z_impl_k_str_out(char *c, size_t n) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_str_out(char *c, size_t n) { - Z_OOPS(Z_SYSCALL_MEMORY_READ(c, n)); + Z_OOPS(K_SYSCALL_MEMORY_READ(c, n)); z_impl_k_str_out((char *)c, n); } #include diff --git a/lib/posix/clock.c b/lib/posix/clock.c index 50742545b20..98d6a8161da 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -68,7 +68,7 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) #ifdef CONFIG_USERSPACE int z_vrfy_clock_gettime(clockid_t clock_id, struct timespec *ts) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); return z_impl_clock_gettime(clock_id, ts); } #include diff --git a/samples/userspace/prod_consumer/src/sample_driver_handlers.c b/samples/userspace/prod_consumer/src/sample_driver_handlers.c index 1f9dc610af3..66f8c12ce88 100644 --- a/samples/userspace/prod_consumer/src/sample_driver_handlers.c +++ b/samples/userspace/prod_consumer/src/sample_driver_handlers.c @@ -25,7 +25,7 @@ int z_vrfy_sample_driver_write(const struct device *dev, void *buf) return -EINVAL; } - if (Z_SYSCALL_MEMORY_READ(buf, SAMPLE_DRIVER_MSG_SIZE)) { + if (K_SYSCALL_MEMORY_READ(buf, SAMPLE_DRIVER_MSG_SIZE)) { return -EFAULT; } diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index c64eacd986e..0725ca0c30d 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -894,8 +894,8 @@ def write_validation_output(fp): fp.write("#define DRIVER_VALIDATION_GEN_H\n") fp.write("""#define Z_SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\ - (Z_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case) || \\ - Z_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op)) + (K_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case) || \\ + K_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op)) """) for subsystem in subsystems: diff --git a/scripts/build/gen_syscalls.py b/scripts/build/gen_syscalls.py index 9ee4e323994..8703352b133 100755 --- a/scripts/build/gen_syscalls.py +++ b/scripts/build/gen_syscalls.py @@ -322,7 +322,7 @@ def marshall_defs(func_name, func_type, args): mrsh += "\t(void) arg%d;\t/* unused */\n" % unused_arg if nmrsh > 6: - mrsh += ("\tZ_OOPS(Z_SYSCALL_MEMORY_READ(more, " + mrsh += ("\tZ_OOPS(K_SYSCALL_MEMORY_READ(more, " + str(nmrsh - 5) + " * sizeof(uintptr_t)));\n") argnum = 0 @@ -349,7 +349,7 @@ def marshall_defs(func_name, func_type, args): if need_split(func_type): ptr = "((uint64_t *)%s)" % mrsh_rval(nmrsh - 1, nmrsh) - mrsh += "\t" + "Z_OOPS(Z_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr + mrsh += "\t" + "Z_OOPS(K_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr mrsh += "\t" + "*%s = ret;\n" % ptr mrsh += "\t" + "_current->syscall_frame = NULL;\n" mrsh += "\t" + "return 0;\n" diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index 42d0f3b418f..7333f140805 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -304,7 +304,7 @@ char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src, char *out; const void *addr; - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); if (family == AF_INET) { Z_OOPS(k_usermode_from_copy(&addr4, (const void *)src, @@ -488,7 +488,7 @@ int z_vrfy_net_addr_pton(sa_family_t family, const char *src, return -EINVAL; } - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, size)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); err = z_impl_net_addr_pton(family, str, addr); if (err) { diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index 3813c8f7af4..80f7a61ea22 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -341,7 +341,7 @@ int z_vrfy_zsock_socketpair(int family, int type, int proto, int *sv) int ret; int tmp[2]; - if (!sv || Z_SYSCALL_MEMORY_WRITE(sv, sizeof(tmp)) != 0) { + if (!sv || K_SYSCALL_MEMORY_WRITE(sv, sizeof(tmp)) != 0) { /* not listed in normative spec, but mimics linux behaviour */ errno = EFAULT; ret = -1; diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index fec5da20582..1d05debcf29 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -695,7 +695,7 @@ static inline int z_vrfy_zsock_accept(int sock, struct sockaddr *addr, Z_OOPS(addrlen && k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); - Z_OOPS(addr && Z_SYSCALL_MEMORY_WRITE(addr, addrlen ? addrlen_copy : 0)); + Z_OOPS(addr && K_SYSCALL_MEMORY_WRITE(addr, addrlen ? addrlen_copy : 0)); ret = z_impl_zsock_accept(sock, (struct sockaddr *)addr, addrlen ? &addrlen_copy : NULL); @@ -862,7 +862,7 @@ ssize_t z_vrfy_zsock_sendto(int sock, const void *buf, size_t len, int flags, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, len)); + Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); if (dest_addr) { Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)dest_addr, @@ -1514,7 +1514,7 @@ ssize_t z_vrfy_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, socklen_t addrlen_copy; ssize_t ret; - if (Z_SYSCALL_MEMORY_WRITE(buf, max_len)) { + if (K_SYSCALL_MEMORY_WRITE(buf, max_len)) { errno = EFAULT; return -1; } @@ -1523,7 +1523,7 @@ ssize_t z_vrfy_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, Z_OOPS(k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); } - Z_OOPS(src_addr && Z_SYSCALL_MEMORY_WRITE(src_addr, addrlen_copy)); + Z_OOPS(src_addr && K_SYSCALL_MEMORY_WRITE(src_addr, addrlen_copy)); ret = z_impl_zsock_recvfrom(sock, (void *)buf, max_len, flags, (struct sockaddr *)src_addr, @@ -1609,7 +1609,7 @@ static inline int z_vrfy_zsock_ioctl(int sock, unsigned long request, va_list ar int *avail; avail = va_arg(args, int *); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(avail, sizeof(*avail))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(avail, sizeof(*avail))); break; } @@ -2168,7 +2168,7 @@ int z_vrfy_zsock_getsockopt(int sock, int level, int optname, void *kernel_optval; int ret; - if (Z_SYSCALL_MEMORY_WRITE(optval, kernel_optlen)) { + if (K_SYSCALL_MEMORY_WRITE(optval, kernel_optlen)) { errno = -EPERM; return -1; } @@ -2594,7 +2594,7 @@ static inline int z_vrfy_zsock_getpeername(int sock, struct sockaddr *addr, Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); - if (Z_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { + if (K_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { errno = EFAULT; return -1; } @@ -2673,7 +2673,7 @@ static inline int z_vrfy_zsock_getsockname(int sock, struct sockaddr *addr, Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); - if (Z_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { + if (K_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { errno = EFAULT; return -1; } diff --git a/subsys/net/lib/sockets/sockets_misc.c b/subsys/net/lib/sockets/sockets_misc.c index fcc42834438..65b9b27af2d 100644 --- a/subsys/net/lib/sockets/sockets_misc.c +++ b/subsys/net/lib/sockets/sockets_misc.c @@ -20,7 +20,7 @@ int z_impl_zsock_gethostname(char *buf, size_t len) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zsock_gethostname(char *buf, size_t len) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buf, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); return z_impl_zsock_gethostname(buf, len); } #include diff --git a/subsys/random/rand32_handlers.c b/subsys/random/rand32_handlers.c index 06e45bdc592..e51d3d0c2b2 100644 --- a/subsys/random/rand32_handlers.c +++ b/subsys/random/rand32_handlers.c @@ -15,7 +15,7 @@ static inline uint32_t z_vrfy_sys_rand32_get(void) static inline void z_vrfy_sys_rand_get(void *dst, size_t len) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); z_impl_sys_rand_get(dst, len); } @@ -24,7 +24,7 @@ static inline void z_vrfy_sys_rand_get(void *dst, size_t len) #ifdef CONFIG_CSPRNG_ENABLED static inline int z_vrfy_sys_csrand_get(void *dst, size_t len) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, len)); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); return z_impl_sys_csrand_get(dst, len); } diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_handlers.c index f49d9488b85..30c876e056f 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_handlers.c @@ -19,7 +19,7 @@ */ static inline bool rtio_vrfy_sqe(struct rtio_sqe *sqe) { - if (sqe->iodev != NULL && Z_SYSCALL_OBJ(sqe->iodev, K_OBJ_RTIO_IODEV)) { + if (sqe->iodev != NULL && K_SYSCALL_OBJ(sqe->iodev, K_OBJ_RTIO_IODEV)) { return false; } @@ -29,18 +29,18 @@ static inline bool rtio_vrfy_sqe(struct rtio_sqe *sqe) case RTIO_OP_NOP: break; case RTIO_OP_TX: - valid_sqe &= Z_SYSCALL_MEMORY(sqe->buf, sqe->buf_len, false); + valid_sqe &= K_SYSCALL_MEMORY(sqe->buf, sqe->buf_len, false); break; case RTIO_OP_RX: if ((sqe->flags & RTIO_SQE_MEMPOOL_BUFFER) == 0) { - valid_sqe &= Z_SYSCALL_MEMORY(sqe->buf, sqe->buf_len, true); + valid_sqe &= K_SYSCALL_MEMORY(sqe->buf, sqe->buf_len, true); } break; case RTIO_OP_TINY_TX: break; case RTIO_OP_TXRX: - valid_sqe &= Z_SYSCALL_MEMORY(sqe->tx_buf, sqe->txrx_buf_len, true); - valid_sqe &= Z_SYSCALL_MEMORY(sqe->rx_buf, sqe->txrx_buf_len, true); + valid_sqe &= K_SYSCALL_MEMORY(sqe->tx_buf, sqe->txrx_buf_len, true); + valid_sqe &= K_SYSCALL_MEMORY(sqe->rx_buf, sqe->txrx_buf_len, true); break; default: /* RTIO OP must be known and allowable from user mode @@ -54,7 +54,7 @@ static inline bool rtio_vrfy_sqe(struct rtio_sqe *sqe) static inline void z_vrfy_rtio_release_buffer(struct rtio *r, void *buff, uint32_t buff_len) { - Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); + Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); z_impl_rtio_release_buffer(r, buff, buff_len); } #include @@ -62,10 +62,10 @@ static inline void z_vrfy_rtio_release_buffer(struct rtio *r, void *buff, uint32 static inline int z_vrfy_rtio_cqe_get_mempool_buffer(const struct rtio *r, struct rtio_cqe *cqe, uint8_t **buff, uint32_t *buff_len) { - Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(Z_SYSCALL_MEMORY_READ(cqe, sizeof(struct rtio_cqe))); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buff, sizeof(void *))); - Z_OOPS(Z_SYSCALL_MEMORY_READ(buff_len, sizeof(uint32_t))); + Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + Z_OOPS(K_SYSCALL_MEMORY_READ(cqe, sizeof(struct rtio_cqe))); + Z_OOPS(K_SYSCALL_MEMORY_READ(buff, sizeof(void *))); + Z_OOPS(K_SYSCALL_MEMORY_READ(buff_len, sizeof(uint32_t))); return z_impl_rtio_cqe_get_mempool_buffer(r, cqe, buff, buff_len); } #include @@ -79,7 +79,7 @@ static inline int z_vrfy_rtio_sqe_cancel(struct rtio_sqe *sqe) static inline int z_vrfy_rtio_sqe_copy_in_get_handles(struct rtio *r, const struct rtio_sqe *sqes, struct rtio_sqe **handle, size_t sqe_count) { - Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); + Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe))); struct rtio_sqe *sqe; @@ -114,7 +114,7 @@ static inline int z_vrfy_rtio_cqe_copy_out(struct rtio *r, size_t cqe_count, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); + Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(cqes, cqe_count, sizeof(struct rtio_cqe))); @@ -124,10 +124,10 @@ static inline int z_vrfy_rtio_cqe_copy_out(struct rtio *r, static inline int z_vrfy_rtio_submit(struct rtio *r, uint32_t wait_count) { - Z_OOPS(Z_SYSCALL_OBJ(r, K_OBJ_RTIO)); + Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); #ifdef CONFIG_RTIO_SUBMIT_SEM - Z_OOPS(Z_SYSCALL_OBJ(r->submit_sem, K_OBJ_SEM)); + Z_OOPS(K_SYSCALL_OBJ(r->submit_sem, K_OBJ_SEM)); #endif return z_impl_rtio_submit(r, wait_count); diff --git a/tests/benchmarks/footprints/src/userspace.c b/tests/benchmarks/footprints/src/userspace.c index c4e51ccff67..ef6a62cdeac 100644 --- a/tests/benchmarks/footprints/src/userspace.c +++ b/tests/benchmarks/footprints/src/userspace.c @@ -41,9 +41,9 @@ int z_impl_validation_overhead_syscall(void) static inline int z_vrfy_validation_overhead_syscall(void) { - bool status_0 = Z_SYSCALL_OBJ_INIT(&test_sema, K_OBJ_SEM); + bool status_0 = K_SYSCALL_OBJ_INIT(&test_sema, K_OBJ_SEM); - bool status_1 = Z_SYSCALL_OBJ(&test_sema, K_OBJ_SEM); + bool status_1 = K_SYSCALL_OBJ(&test_sema, K_OBJ_SEM); return status_0 || status_1; } diff --git a/tests/kernel/mem_protect/mem_protect/src/kobject.c b/tests/kernel/mem_protect/mem_protect/src/kobject.c index 4671ec23f86..79bd0549b09 100644 --- a/tests/kernel/mem_protect/mem_protect/src/kobject.c +++ b/tests/kernel/mem_protect/mem_protect/src/kobject.c @@ -492,7 +492,7 @@ ZTEST(mem_protect_kobj, test_kobject_access_grant_to_invalid_thread) k_object_access_grant(&kobject_sem, &uninit_thread); k_object_access_revoke(&kobject_sem, &uninit_thread); - zassert_not_equal(Z_SYSCALL_OBJ(&uninit_thread, K_OBJ_THREAD), 0, + zassert_not_equal(K_SYSCALL_OBJ(&uninit_thread, K_OBJ_THREAD), 0, "Access granted/revoked to invalid thread k_object"); } diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index f511bd6aedb..258237d99e0 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -55,7 +55,7 @@ static inline size_t z_vrfy_string_nlen(char *src, size_t maxlen, int *err) size_t ret; ret = z_impl_string_nlen((char *)src, maxlen, &err_copy); - if (!err_copy && Z_SYSCALL_MEMORY_READ(src, ret + 1)) { + if (!err_copy && K_SYSCALL_MEMORY_READ(src, ret + 1)) { err_copy = -1; } diff --git a/tests/kernel/threads/thread_stack/src/main.c b/tests/kernel/threads/thread_stack/src/main.c index 0ab51931188..b3bfe73c0b8 100644 --- a/tests/kernel/threads/thread_stack/src/main.c +++ b/tests/kernel/threads/thread_stack/src/main.c @@ -41,8 +41,8 @@ void z_impl_stack_info_get(char **start_addr, size_t *size) static inline void z_vrfy_stack_info_get(char **start_addr, size_t *size) { - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(start_addr, sizeof(uintptr_t))); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(start_addr, sizeof(uintptr_t))); + Z_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); z_impl_stack_info_get(start_addr, size); } From 1a9de05767c74cfcd4fd4ef6b3570e3e74799398 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:18:12 +0000 Subject: [PATCH 3028/4498] syscall: rename Z_SYSCALL_DRIVER_ -> K_SYSCALL_DRIVER_ Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 4 +-- drivers/adc/adc_handlers.c | 6 ++-- drivers/can/can_handlers.c | 32 +++++++++---------- drivers/charger/charger_handlers.c | 4 +-- drivers/counter/counter_handlers.c | 14 ++++---- drivers/dac/dac_handlers.c | 4 +-- drivers/dma/dma_handlers.c | 4 +-- drivers/eeprom/eeprom_handlers.c | 6 ++-- drivers/entropy/entropy_handlers.c | 2 +- drivers/espi/espi_handlers.c | 26 +++++++-------- drivers/flash/flash_handlers.c | 20 ++++++------ .../fuel_gauge/fuel_gauge_syscall_handlers.c | 12 +++---- drivers/gpio/gpio_handlers.c | 20 ++++++------ drivers/hwspinlock/hwspinlock_handlers.c | 8 ++--- drivers/i2c/i2c_handlers.c | 4 +-- drivers/i2s/i2s_handlers.c | 8 ++--- drivers/i3c/i3c_handlers.c | 2 +- drivers/ipm/ipm_handlers.c | 8 ++--- drivers/kscan/kscan_handlers.c | 6 ++-- drivers/led/led_handlers.c | 8 ++--- drivers/mbox/mbox_handlers.c | 8 ++--- drivers/peci/peci_handlers.c | 8 ++--- drivers/ps2/ps2_handlers.c | 10 +++--- drivers/ptp_clock/ptp_clock.c | 2 +- drivers/pwm/pwm_handlers.c | 14 ++++---- drivers/rtc/rtc_handlers.c | 16 +++++----- drivers/sensor/sensor_handlers.c | 10 +++--- drivers/serial/uart_handlers.c | 30 ++++++++--------- drivers/smbus/smbus_handlers.c | 4 +-- drivers/spi/spi_handlers.c | 4 +-- drivers/usb/bc12/bc12_handlers.c | 4 +-- .../virtualization/virt_ivshmem_handlers.c | 24 +++++++------- drivers/w1/w1_handlers.c | 12 +++---- drivers/watchdog/wdt_handlers.c | 6 ++-- .../src/sample_driver_handlers.c | 4 +-- scripts/build/gen_kobject_list.py | 4 +-- 36 files changed, 179 insertions(+), 179 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index bbebad62d4b..5c0ad90822c 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -320,7 +320,7 @@ Several macros exist to validate arguments: macro can be used by itself, it's mostly a building block for macros that are automatically generated for every driver subsystem. For instance, to validate the GPIO driver, one could use the - :c:macro:`Z_SYSCALL_DRIVER_GPIO()` macro. + :c:macro:`K_SYSCALL_DRIVER_GPIO()` macro. * :c:macro:`K_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that a provided pointer is a valid instance of a specific device driver, that @@ -572,7 +572,7 @@ conventions are as follows: overflowed. #. Most system calls take kernel object pointers as an argument, checked either - with one of the ``K_SYSCALL_OBJ`` functions, ``Z_SYSCALL_DRIVER_nnnnn``, or + with one of the ``K_SYSCALL_OBJ`` functions, ``K_SYSCALL_DRIVER_nnnnn``, or manually using :c:func:`k_object_validate()`. These can fail for a variety of reasons: missing driver API, bad kernel object pointer, wrong kernel object type, or improper initialization state. These issues should always diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index 59af661c865..156415f1e5f 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -13,7 +13,7 @@ static inline int z_vrfy_adc_channel_setup(const struct device *dev, { struct adc_channel_cfg channel_cfg; - Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, channel_setup)); + Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, channel_setup)); Z_OOPS(k_usermode_from_copy(&channel_cfg, (struct adc_channel_cfg *)user_channel_cfg, sizeof(struct adc_channel_cfg))); @@ -55,7 +55,7 @@ static inline int z_vrfy_adc_read(const struct device *dev, struct adc_sequence sequence; struct adc_sequence_options options; - Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read)); + Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, read)); Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); @@ -76,7 +76,7 @@ static inline int z_vrfy_adc_read_async(const struct device *dev, struct adc_sequence sequence; struct adc_sequence_options options; - Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read_async)); + Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, read_async)); Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index ccf2a4d6cc2..5b3eecd489f 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -13,7 +13,7 @@ static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *r struct can_timing res_copy; int err; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing(dev, &res_copy, bitrate, sample_pnt); @@ -28,7 +28,7 @@ static inline int z_vrfy_can_set_timing(const struct device *dev, { struct can_timing timing_copy; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); Z_OOPS(k_usermode_from_copy(&timing_copy, timing, sizeof(timing_copy))); return z_impl_can_set_timing(dev, &timing_copy); @@ -38,7 +38,7 @@ static inline int z_vrfy_can_set_timing(const struct device *dev, static inline int z_vrfy_can_get_core_clock(const struct device *dev, uint32_t *rate) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate))); return z_impl_can_get_core_clock(dev, rate); @@ -80,7 +80,7 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi struct can_timing res_copy; int err; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing_data(dev, &res_copy, bitrate, sample_pnt); @@ -111,7 +111,7 @@ static inline int z_vrfy_can_set_timing_data(const struct device *dev, { struct can_timing timing_data_copy; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); Z_OOPS(k_usermode_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy))); return z_impl_can_set_timing_data(dev, &timing_data_copy); @@ -121,7 +121,7 @@ static inline int z_vrfy_can_set_timing_data(const struct device *dev, static inline int z_vrfy_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); return z_impl_can_set_bitrate_data(dev, bitrate_data); } @@ -140,7 +140,7 @@ static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide) static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode_t *cap) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_capabilities)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_capabilities)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap))); return z_impl_can_get_capabilities(dev, cap); @@ -149,7 +149,7 @@ static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode static inline int z_vrfy_can_start(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, start)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, start)); return z_impl_can_start(dev); } @@ -157,7 +157,7 @@ static inline int z_vrfy_can_start(const struct device *dev) static inline int z_vrfy_can_stop(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, stop)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, stop)); return z_impl_can_stop(dev); } @@ -165,7 +165,7 @@ static inline int z_vrfy_can_stop(const struct device *dev) static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_mode)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_mode)); return z_impl_can_set_mode(dev, mode); } @@ -173,7 +173,7 @@ static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode) static inline int z_vrfy_can_set_bitrate(const struct device *dev, uint32_t bitrate) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); return z_impl_can_set_bitrate(dev, bitrate); } @@ -187,7 +187,7 @@ static inline int z_vrfy_can_send(const struct device *dev, { struct can_frame frame_copy; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, send)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, send)); Z_OOPS(k_usermode_from_copy(&frame_copy, frame, sizeof(frame_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); @@ -201,7 +201,7 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, { struct can_filter filter_copy; - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); Z_OOPS(k_usermode_from_copy(&filter_copy, filter, sizeof(filter_copy))); @@ -211,7 +211,7 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int filter_id) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, remove_rx_filter)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, remove_rx_filter)); z_impl_can_remove_rx_filter(dev, filter_id); } @@ -220,7 +220,7 @@ static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int fil static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state *state, struct can_bus_err_cnt *err_cnt) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_state)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_state)); if (state != NULL) { Z_OOPS(K_SYSCALL_MEMORY_WRITE(state, sizeof(*state))); @@ -237,7 +237,7 @@ static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeout) { - Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, recover)); + Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, recover)); return z_impl_can_recover(dev, timeout); } diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c index 237f9ff9628..6f17002aac7 100644 --- a/drivers/charger/charger_handlers.c +++ b/drivers/charger/charger_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_charger_get_prop(const struct device *dev, const charge { union charger_propval k_val; - Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, get_property)); + Z_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, get_property)); int ret = z_impl_charger_get_prop(dev, prop, &k_val); @@ -28,7 +28,7 @@ static inline int z_vrfy_charger_set_prop(const struct device *dev, const charge { union charger_propval k_val; - Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, set_property)); + Z_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, set_property)); Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union charger_propval))); diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 6f649523079..191d12d49b5 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -13,7 +13,7 @@ #define COUNTER_HANDLER(name) \ static inline int z_vrfy_counter_##name(const struct device *dev) \ { \ - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, name)); \ + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, name)); \ return z_impl_counter_ ## name((const struct device *)dev); \ } @@ -67,7 +67,7 @@ static inline uint64_t z_vrfy_counter_ticks_to_us(const struct device *dev, static inline int z_vrfy_counter_get_value(const struct device *dev, uint32_t *ticks) { - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, get_value)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value((const struct device *)dev, ticks); } @@ -75,7 +75,7 @@ static inline int z_vrfy_counter_get_value(const struct device *dev, static inline int z_vrfy_counter_get_value_64(const struct device *dev, uint64_t *ticks) { - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, get_value_64)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value_64)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value_64((const struct device *)dev, ticks); } @@ -88,7 +88,7 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, { struct counter_alarm_cfg cfg_copy; - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); Z_OOPS(k_usermode_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); @@ -102,7 +102,7 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, static inline int z_vrfy_counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id) { - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, cancel_alarm)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, cancel_alarm)); return z_impl_counter_cancel_channel_alarm((const struct device *)dev, (uint8_t)chan_id); } @@ -114,7 +114,7 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, { struct counter_top_cfg cfg_copy; - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); @@ -126,7 +126,7 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, static inline uint32_t z_vrfy_counter_get_top_value(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, get_top_value)); + Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_top_value)); return z_impl_counter_get_top_value((const struct device *)dev); } #include diff --git a/drivers/dac/dac_handlers.c b/drivers/dac/dac_handlers.c index 76bfa2bbefb..c1cc24c3685 100644 --- a/drivers/dac/dac_handlers.c +++ b/drivers/dac/dac_handlers.c @@ -13,7 +13,7 @@ static inline int z_vrfy_dac_channel_setup(const struct device *dev, { struct dac_channel_cfg channel_cfg; - Z_OOPS(Z_SYSCALL_DRIVER_DAC(dev, channel_setup)); + Z_OOPS(K_SYSCALL_DRIVER_DAC(dev, channel_setup)); Z_OOPS(k_usermode_from_copy(&channel_cfg, (struct dac_channel_cfg *)user_channel_cfg, sizeof(struct dac_channel_cfg))); @@ -26,7 +26,7 @@ static inline int z_vrfy_dac_channel_setup(const struct device *dev, static inline int z_vrfy_dac_write_value(const struct device *dev, uint8_t channel, uint32_t value) { - Z_OOPS(Z_SYSCALL_DRIVER_DAC(dev, write_value)); + Z_OOPS(K_SYSCALL_DRIVER_DAC(dev, write_value)); return z_impl_dac_write_value((const struct device *)dev, channel, value); diff --git a/drivers/dma/dma_handlers.c b/drivers/dma/dma_handlers.c index e826b30521b..10c542d8380 100644 --- a/drivers/dma/dma_handlers.c +++ b/drivers/dma/dma_handlers.c @@ -13,14 +13,14 @@ static inline int z_vrfy_dma_start(const struct device *dev, uint32_t channel) { - Z_OOPS(Z_SYSCALL_DRIVER_DMA(dev, start)); + Z_OOPS(K_SYSCALL_DRIVER_DMA(dev, start)); return z_impl_dma_start((const struct device *)dev, channel); } #include static inline int z_vrfy_dma_stop(const struct device *dev, uint32_t channel) { - Z_OOPS(Z_SYSCALL_DRIVER_DMA(dev, stop)); + Z_OOPS(K_SYSCALL_DRIVER_DMA(dev, stop)); return z_impl_dma_stop((const struct device *)dev, channel); } #include diff --git a/drivers/eeprom/eeprom_handlers.c b/drivers/eeprom/eeprom_handlers.c index 89433f6bb50..7534e67d865 100644 --- a/drivers/eeprom/eeprom_handlers.c +++ b/drivers/eeprom/eeprom_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_EEPROM(dev, read)); + Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, read)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_eeprom_read((const struct device *)dev, offset, (void *)data, @@ -21,7 +21,7 @@ static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, static inline int z_vrfy_eeprom_write(const struct device *dev, off_t offset, const void *data, size_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_EEPROM(dev, write)); + Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, write)); Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_eeprom_write((const struct device *)dev, offset, (const void *)data, len); @@ -30,7 +30,7 @@ static inline int z_vrfy_eeprom_write(const struct device *dev, off_t offset, static inline size_t z_vrfy_eeprom_get_size(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_EEPROM(dev, size)); + Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, size)); return z_impl_eeprom_get_size((const struct device *)dev); } #include diff --git a/drivers/entropy/entropy_handlers.c b/drivers/entropy/entropy_handlers.c index 7d62960e14a..269d3412608 100644 --- a/drivers/entropy/entropy_handlers.c +++ b/drivers/entropy/entropy_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_entropy_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_ENTROPY(dev, get_entropy)); + Z_OOPS(K_SYSCALL_DRIVER_ENTROPY(dev, get_entropy)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); return z_impl_entropy_get_entropy((const struct device *)dev, (uint8_t *)buffer, diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index c82fbc43e6c..1bb023a7a58 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -13,7 +13,7 @@ static inline int z_vrfy_espi_config(const struct device *dev, { struct espi_cfg cfg_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, config)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, config)); Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(struct espi_cfg))); @@ -24,7 +24,7 @@ static inline int z_vrfy_espi_config(const struct device *dev, static inline bool z_vrfy_espi_get_channel_status(const struct device *dev, enum espi_channel ch) { - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, get_channel_status)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, get_channel_status)); return z_impl_espi_get_channel_status(dev, ch); } @@ -37,7 +37,7 @@ static inline int z_vrfy_espi_read_lpc_request(const struct device *dev, int ret; uint32_t data_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, read_lpc_request)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_lpc_request)); ret = z_impl_espi_read_lpc_request(dev, op, &data_copy); Z_OOPS(k_usermode_to_copy(data, &data_copy, sizeof(uint8_t))); @@ -52,7 +52,7 @@ static inline int z_vrfy_espi_write_lpc_request(const struct device *dev, { uint32_t data_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, write_lpc_request)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_lpc_request)); Z_OOPS(k_usermode_from_copy(&data_copy, data, sizeof(*data))); return z_impl_espi_write_lpc_request(dev, op, &data_copy); @@ -63,7 +63,7 @@ static inline int z_vrfy_espi_send_vwire(const struct device *dev, enum espi_vwire_signal signal, uint8_t level) { - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, send_vwire)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_vwire)); return z_impl_espi_send_vwire(dev, signal, level); } @@ -76,7 +76,7 @@ static inline int z_vrfy_espi_receive_vwire(const struct device *dev, int ret; uint8_t level_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, receive_vwire)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_vwire)); ret = z_impl_espi_receive_vwire(dev, signal, &level_copy); Z_OOPS(k_usermode_to_copy(level, &level_copy, sizeof(uint8_t))); @@ -91,7 +91,7 @@ static inline int z_vrfy_espi_read_request(const struct device *dev, int ret; struct espi_request_packet req_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, read_request)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_request)); Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); Z_OOPS(K_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); @@ -111,7 +111,7 @@ static inline int z_vrfy_espi_write_request(const struct device *dev, int ret; struct espi_request_packet req_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, write_request)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_request)); Z_OOPS(K_SYSCALL_MEMORY_READ(req->data, req->len)); Z_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); @@ -128,7 +128,7 @@ static inline int z_vrfy_espi_send_oob(const struct device *dev, int ret; struct espi_oob_packet pckt_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, send_oob)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_oob)); Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); @@ -145,7 +145,7 @@ static inline int z_vrfy_espi_receive_oob(const struct device *dev, int ret; struct espi_oob_packet pckt_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, receive_oob)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_oob)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); @@ -164,7 +164,7 @@ static inline int z_vrfy_espi_read_flash(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_read)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_read)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); @@ -183,7 +183,7 @@ static inline int z_vrfy_espi_write_flash(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); @@ -200,7 +200,7 @@ static inline int z_vrfy_espi_flash_erase(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(Z_SYSCALL_DRIVER_ESPI(dev, flash_write)); + Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index 0a1c0274213..d8b5dc377c3 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_read((const struct device *)dev, offset, (void *)data, @@ -21,7 +21,7 @@ static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, const void *data, size_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, write)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, write)); Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_flash_write((const struct device *)dev, offset, (const void *)data, len); @@ -31,7 +31,7 @@ static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, static inline int z_vrfy_flash_erase(const struct device *dev, off_t offset, size_t size) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, erase)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, erase)); return z_impl_flash_erase((const struct device *)dev, offset, size); } #include @@ -45,7 +45,7 @@ static inline size_t z_vrfy_flash_get_write_block_size(const struct device *dev) static inline const struct flash_parameters *z_vrfy_flash_get_parameters(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, get_parameters)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, get_parameters)); return z_impl_flash_get_parameters(dev); } #include @@ -55,7 +55,7 @@ static inline int z_vrfy_flash_get_page_info_by_offs(const struct device *dev, off_t offs, struct flash_pages_info *info) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_offs((const struct device *)dev, offs, @@ -67,7 +67,7 @@ static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev, uint32_t idx, struct flash_pages_info *info) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_idx((const struct device *)dev, idx, @@ -77,7 +77,7 @@ static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev, static inline size_t z_vrfy_flash_get_page_count(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); return z_impl_flash_get_page_count((const struct device *)dev); } #include @@ -90,7 +90,7 @@ static inline int z_vrfy_flash_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, sfdp_read)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, sfdp_read)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_sfdp_read(dev, offset, data, len); } @@ -99,7 +99,7 @@ static inline int z_vrfy_flash_sfdp_read(const struct device *dev, static inline int z_vrfy_flash_read_jedec_id(const struct device *dev, uint8_t *id) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read_jedec_id)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read_jedec_id)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(id, 3)); return z_impl_flash_read_jedec_id(dev, id); } @@ -112,7 +112,7 @@ static inline int z_vrfy_flash_read_jedec_id(const struct device *dev, static inline int z_vrfy_flash_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out) { - Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, ex_op)); + Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, ex_op)); /* * If the code is a vendor code, then ex_op function have to perform diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 412153ada1f..5fe1e45a35a 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -13,7 +13,7 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gaug { union fuel_gauge_prop_val k_val; - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); @@ -32,7 +32,7 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau union fuel_gauge_prop_val k_vals[len]; fuel_gauge_prop_t k_props[len]; - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); @@ -49,7 +49,7 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, union fuel_gauge_prop_val val) { - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); int ret = z_impl_fuel_gauge_set_prop(dev, prop, val); @@ -64,7 +64,7 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gau union fuel_gauge_prop_val k_vals[len]; fuel_gauge_prop_t k_props[len]; - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); @@ -83,7 +83,7 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, fuel_gauge_prop_t prop, void *dst, size_t dst_len) { - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, dst_len)); @@ -96,7 +96,7 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, static inline int z_vrfy_fuel_gauge_battery_cutoff(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, battery_cutoff)); + Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, battery_cutoff)); return z_impl_fuel_gauge_battery_cutoff(dev); } diff --git a/drivers/gpio/gpio_handlers.c b/drivers/gpio/gpio_handlers.c index 981d56ad73e..57cec40c56e 100644 --- a/drivers/gpio/gpio_handlers.c +++ b/drivers/gpio/gpio_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_gpio_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, pin_configure)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_configure)); return z_impl_gpio_pin_configure((const struct device *)port, pin, flags); @@ -23,7 +23,7 @@ static inline int z_vrfy_gpio_pin_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, pin_get_config)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_get_config)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(flags, sizeof(gpio_flags_t))); return z_impl_gpio_pin_get_config(port, pin, flags); @@ -34,7 +34,7 @@ static inline int z_vrfy_gpio_pin_get_config(const struct device *port, static inline int z_vrfy_gpio_port_get_raw(const struct device *port, gpio_port_value_t *value) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_get_raw)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_get_raw)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(gpio_port_value_t))); return z_impl_gpio_port_get_raw((const struct device *)port, (gpio_port_value_t *)value); @@ -45,7 +45,7 @@ static inline int z_vrfy_gpio_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, gpio_port_value_t value) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_set_masked_raw)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_masked_raw)); return z_impl_gpio_port_set_masked_raw((const struct device *)port, mask, value); @@ -55,7 +55,7 @@ static inline int z_vrfy_gpio_port_set_masked_raw(const struct device *port, static inline int z_vrfy_gpio_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_set_bits_raw)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_bits_raw)); return z_impl_gpio_port_set_bits_raw((const struct device *)port, pins); } @@ -64,7 +64,7 @@ static inline int z_vrfy_gpio_port_set_bits_raw(const struct device *port, static inline int z_vrfy_gpio_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_clear_bits_raw)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_clear_bits_raw)); return z_impl_gpio_port_clear_bits_raw((const struct device *)port, pins); } @@ -73,7 +73,7 @@ static inline int z_vrfy_gpio_port_clear_bits_raw(const struct device *port, static inline int z_vrfy_gpio_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, port_toggle_bits)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_toggle_bits)); return z_impl_gpio_port_toggle_bits((const struct device *)port, pins); } #include @@ -82,7 +82,7 @@ static inline int z_vrfy_gpio_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, pin_interrupt_configure)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_interrupt_configure)); return z_impl_gpio_pin_interrupt_configure((const struct device *)port, pin, flags); @@ -91,7 +91,7 @@ static inline int z_vrfy_gpio_pin_interrupt_configure(const struct device *port, static inline int z_vrfy_gpio_get_pending_int(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(dev, get_pending_int)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(dev, get_pending_int)); return z_impl_gpio_get_pending_int((const struct device *)dev); } @@ -102,7 +102,7 @@ static inline int z_vrfy_gpio_port_get_direction(const struct device *dev, gpio_ gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) { - Z_OOPS(Z_SYSCALL_DRIVER_GPIO(dev, port_get_direction)); + Z_OOPS(K_SYSCALL_DRIVER_GPIO(dev, port_get_direction)); if (inputs != NULL) { Z_OOPS(K_SYSCALL_MEMORY_WRITE(inputs, sizeof(gpio_port_pins_t))); diff --git a/drivers/hwspinlock/hwspinlock_handlers.c b/drivers/hwspinlock/hwspinlock_handlers.c index 8fd8c93424a..9b7726d09cf 100644 --- a/drivers/hwspinlock/hwspinlock_handlers.c +++ b/drivers/hwspinlock/hwspinlock_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_hwspinlock_trylock(const struct device *dev, uint32_t id) { - Z_OOPS(Z_SYSCALL_DRIVER_HWSPINLOCK(dev, trylock)); + Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, trylock)); return z_impl_hwspinlock_trylock(dev, id); } @@ -17,7 +17,7 @@ static inline int z_vrfy_hwspinlock_trylock(const struct device *dev, uint32_t i static inline void z_vrfy_hwspinlock_lock(const struct device *dev, uint32_t id) { - Z_OOPS(Z_SYSCALL_DRIVER_HWSPINLOCK(dev, lock)); + Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, lock)); z_impl_hwspinlock_lock(dev, id); } @@ -25,7 +25,7 @@ static inline void z_vrfy_hwspinlock_lock(const struct device *dev, uint32_t id) static inline void z_vrfy_hwspinlock_unlock(const struct device *dev, uint32_t id) { - Z_OOPS(Z_SYSCALL_DRIVER_HWSPINLOCK(dev, unlock)); + Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, unlock)); z_impl_hwspinlock_unlock(dev, id); } @@ -33,7 +33,7 @@ static inline void z_vrfy_hwspinlock_unlock(const struct device *dev, uint32_t i static inline uint32_t z_vrfy_hwspinlock_get_max_id(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_HWSPINLOCK(dev, get_max_id)); + Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, get_max_id)); return z_impl_hwspinlock_get_max_id(dev); } diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index 34bfb34d11e..5c463890028 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_i2c_configure(const struct device *dev, uint32_t dev_config) { - Z_OOPS(Z_SYSCALL_DRIVER_I2C(dev, configure)); + Z_OOPS(K_SYSCALL_DRIVER_I2C(dev, configure)); return z_impl_i2c_configure((const struct device *)dev, dev_config); } #include @@ -19,7 +19,7 @@ static inline int z_vrfy_i2c_configure(const struct device *dev, static inline int z_vrfy_i2c_get_config(const struct device *dev, uint32_t *dev_config) { - Z_OOPS(Z_SYSCALL_DRIVER_I2C(dev, get_config)); + Z_OOPS(K_SYSCALL_DRIVER_I2C(dev, get_config)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_i2c_get_config(dev, dev_config); diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 48ffe50297a..0f5c0db8f48 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -16,7 +16,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, struct i2s_config config; int ret = -EINVAL; - if (Z_SYSCALL_DRIVER_I2S(dev, configure)) { + if (K_SYSCALL_DRIVER_I2S(dev, configure)) { goto out; } @@ -50,7 +50,7 @@ static inline int z_vrfy_i2s_buf_read(const struct device *dev, size_t data_size; int ret; - Z_OOPS(Z_SYSCALL_DRIVER_I2S(dev, read)); + Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, read)); ret = i2s_read((const struct device *)dev, &mem_block, &data_size); @@ -83,7 +83,7 @@ static inline int z_vrfy_i2s_buf_write(const struct device *dev, const struct i2s_config *tx_cfg; void *mem_block; - Z_OOPS(Z_SYSCALL_DRIVER_I2S(dev, write)); + Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, write)); tx_cfg = i2s_config_get((const struct device *)dev, I2S_DIR_TX); if (!tx_cfg) { return -EIO; @@ -117,7 +117,7 @@ static inline int z_vrfy_i2s_trigger(const struct device *dev, enum i2s_dir dir, enum i2s_trigger_cmd cmd) { - Z_OOPS(Z_SYSCALL_DRIVER_I2S(dev, trigger)); + Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, trigger)); return z_impl_i2s_trigger((const struct device *)dev, dir, cmd); } diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index 2da70b520d6..6bb37f76448 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) { - Z_OOPS(Z_SYSCALL_DRIVER_I3C(dev, do_ccc)); + Z_OOPS(K_SYSCALL_DRIVER_I3C(dev, do_ccc)); Z_OOPS(K_SYSCALL_MEMORY_READ(payload, sizeof(*payload))); Z_OOPS(K_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); diff --git a/drivers/ipm/ipm_handlers.c b/drivers/ipm/ipm_handlers.c index 5ad930be899..ef139c67338 100644 --- a/drivers/ipm/ipm_handlers.c +++ b/drivers/ipm/ipm_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_ipm_send(const struct device *dev, int wait, uint32_t id, const void *data, int size) { - Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, send)); + Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, send)); Z_OOPS(K_SYSCALL_MEMORY_READ(data, size)); return z_impl_ipm_send((const struct device *)dev, wait, id, (const void *)data, size); @@ -20,21 +20,21 @@ static inline int z_vrfy_ipm_send(const struct device *dev, int wait, static inline int z_vrfy_ipm_max_data_size_get(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, max_data_size_get)); + Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_data_size_get)); return z_impl_ipm_max_data_size_get((const struct device *)dev); } #include static inline uint32_t z_vrfy_ipm_max_id_val_get(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, max_id_val_get)); + Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_id_val_get)); return z_impl_ipm_max_id_val_get((const struct device *)dev); } #include static inline int z_vrfy_ipm_set_enabled(const struct device *dev, int enable) { - Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, set_enabled)); + Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, set_enabled)); return z_impl_ipm_set_enabled((const struct device *)dev, enable); } #include diff --git a/drivers/kscan/kscan_handlers.c b/drivers/kscan/kscan_handlers.c index 4892e420530..d62cfbb603e 100644 --- a/drivers/kscan/kscan_handlers.c +++ b/drivers/kscan/kscan_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_kscan_config(const struct device *dev, kscan_callback_t callback_isr) { - Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, config)); + Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, config)); Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == 0, "callback cannot be set from user mode")); return z_impl_kscan_config((const struct device *)dev, callback_isr); @@ -19,7 +19,7 @@ static inline int z_vrfy_kscan_config(const struct device *dev, static inline int z_vrfy_kscan_disable_callback(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, disable_callback)); + Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, disable_callback)); return z_impl_kscan_disable_callback((const struct device *)dev); } @@ -27,7 +27,7 @@ static inline int z_vrfy_kscan_disable_callback(const struct device *dev) static int z_vrfy_kscan_enable_callback(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, enable_callback)); + Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, enable_callback)); return z_impl_kscan_enable_callback((const struct device *)dev); } diff --git a/drivers/led/led_handlers.c b/drivers/led/led_handlers.c index 1a500e31bcc..223c673c4a6 100644 --- a/drivers/led/led_handlers.c +++ b/drivers/led/led_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_led_blink(const struct device *dev, uint32_t led, uint32_t delay_on, uint32_t delay_off) { - Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, blink)); + Z_OOPS(K_SYSCALL_DRIVER_LED(dev, blink)); return z_impl_led_blink((const struct device *)dev, led, delay_on, delay_off); } @@ -29,7 +29,7 @@ static inline int z_vrfy_led_set_brightness(const struct device *dev, uint32_t led, uint8_t value) { - Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, set_brightness)); + Z_OOPS(K_SYSCALL_DRIVER_LED(dev, set_brightness)); return z_impl_led_set_brightness((const struct device *)dev, led, value); } @@ -64,14 +64,14 @@ static inline int z_vrfy_led_set_color(const struct device *dev, uint32_t led, static inline int z_vrfy_led_on(const struct device *dev, uint32_t led) { - Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, on)); + Z_OOPS(K_SYSCALL_DRIVER_LED(dev, on)); return z_impl_led_on((const struct device *)dev, led); } #include static inline int z_vrfy_led_off(const struct device *dev, uint32_t led) { - Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, off)); + Z_OOPS(K_SYSCALL_DRIVER_LED(dev, off)); return z_impl_led_off((const struct device *)dev, led); } #include diff --git a/drivers/mbox/mbox_handlers.c b/drivers/mbox/mbox_handlers.c index 2b9fd6821c3..4b2c84997ec 100644 --- a/drivers/mbox/mbox_handlers.c +++ b/drivers/mbox/mbox_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, const struct mbox_msg *msg) { Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); - Z_OOPS(Z_SYSCALL_DRIVER_MBOX(channel->dev, send)); + Z_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, send)); Z_OOPS(K_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg))); Z_OOPS(K_SYSCALL_MEMORY_READ(msg->data, msg->size)); @@ -21,7 +21,7 @@ static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, static inline int z_vrfy_mbox_mtu_get(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_MBOX(dev, mtu_get)); + Z_OOPS(K_SYSCALL_DRIVER_MBOX(dev, mtu_get)); return z_impl_mbox_mtu_get(dev); } @@ -29,7 +29,7 @@ static inline int z_vrfy_mbox_mtu_get(const struct device *dev) static inline uint32_t z_vrfy_mbox_max_channels_get(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_MBOX(dev, max_channels_get)); + Z_OOPS(K_SYSCALL_DRIVER_MBOX(dev, max_channels_get)); return z_impl_mbox_max_channels_get(dev); } @@ -38,7 +38,7 @@ static inline uint32_t z_vrfy_mbox_max_channels_get(const struct device *dev) static inline int z_vrfy_mbox_set_enabled(const struct mbox_channel *channel, bool enable) { Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); - Z_OOPS(Z_SYSCALL_DRIVER_MBOX(channel->dev, set_enabled)); + Z_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, set_enabled)); return z_impl_mbox_set_enabled(channel, enable); } diff --git a/drivers/peci/peci_handlers.c b/drivers/peci/peci_handlers.c index c878be82edf..6f695e9b72d 100644 --- a/drivers/peci/peci_handlers.c +++ b/drivers/peci/peci_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_peci_config(const struct device *dev, uint32_t bitrate) { - Z_OOPS(Z_SYSCALL_DRIVER_PECI(dev, config)); + Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, config)); return z_impl_peci_config(dev, bitrate); } @@ -19,7 +19,7 @@ static inline int z_vrfy_peci_config(const struct device *dev, static inline int z_vrfy_peci_enable(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_PECI(dev, enable)); + Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, enable)); return z_impl_peci_enable(dev); } @@ -27,7 +27,7 @@ static inline int z_vrfy_peci_enable(const struct device *dev) static inline int z_vrfy_peci_disable(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_PECI(dev, disable)); + Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, disable)); return z_impl_peci_disable(dev); } @@ -38,7 +38,7 @@ static inline int z_vrfy_peci_transfer(const struct device *dev, { struct peci_msg msg_copy; - Z_OOPS(Z_SYSCALL_DRIVER_PECI(dev, transfer)); + Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, transfer)); Z_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(*msg))); return z_impl_peci_transfer(dev, &msg_copy); diff --git a/drivers/ps2/ps2_handlers.c b/drivers/ps2/ps2_handlers.c index dadd5294ecd..f02365774bf 100644 --- a/drivers/ps2/ps2_handlers.c +++ b/drivers/ps2/ps2_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_ps2_config(const struct device *dev, ps2_callback_t callback_isr) { - Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, config)); + Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, config)); Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == NULL, "callback not be set from user mode")); return z_impl_ps2_config(dev, callback_isr); @@ -19,14 +19,14 @@ static inline int z_vrfy_ps2_config(const struct device *dev, static inline int z_vrfy_ps2_write(const struct device *dev, uint8_t value) { - Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, write)); + Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, write)); return z_impl_ps2_write(dev, value); } #include static inline int z_vrfy_ps2_read(const struct device *dev, uint8_t *value) { - Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, read)); + Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, read)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(uint8_t))); return z_impl_ps2_read(dev, value); } @@ -34,14 +34,14 @@ static inline int z_vrfy_ps2_read(const struct device *dev, uint8_t *value) static inline int z_vrfy_ps2_enable_callback(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, enable_callback)); + Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, enable_callback)); return z_impl_ps2_enable_callback(dev); } #include static inline int z_vrfy_ps2_disable_callback(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, disable_callback)); + Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, disable_callback)); return z_impl_ps2_disable_callback(dev); } #include diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c index 7e6c1e8cbad..fe105c5a21a 100644 --- a/drivers/ptp_clock/ptp_clock.c +++ b/drivers/ptp_clock/ptp_clock.c @@ -14,7 +14,7 @@ int z_vrfy_ptp_clock_get(const struct device *dev, struct net_ptp_time ptp_time; int ret; - Z_OOPS(Z_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); + Z_OOPS(K_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); ret = z_impl_ptp_clock_get((const struct device *)dev, &ptp_time); diff --git a/drivers/pwm/pwm_handlers.c b/drivers/pwm/pwm_handlers.c index d5f3029de6f..01c3c1dca8f 100644 --- a/drivers/pwm/pwm_handlers.c +++ b/drivers/pwm/pwm_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_pwm_set_cycles(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, pwm_flags_t flags) { - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, set_cycles)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, set_cycles)); return z_impl_pwm_set_cycles((const struct device *)dev, channel, period, pulse, flags); } @@ -22,7 +22,7 @@ static inline int z_vrfy_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles) { - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint64_t))); return z_impl_pwm_get_cycles_per_sec((const struct device *)dev, channel, (uint64_t *)cycles); @@ -34,7 +34,7 @@ static inline int z_vrfy_pwm_get_cycles_per_sec(const struct device *dev, static inline int z_vrfy_pwm_enable_capture(const struct device *dev, uint32_t channel) { - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, enable_capture)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); return z_impl_pwm_enable_capture((const struct device *)dev, channel); } #include @@ -42,7 +42,7 @@ static inline int z_vrfy_pwm_enable_capture(const struct device *dev, static inline int z_vrfy_pwm_disable_capture(const struct device *dev, uint32_t channel) { - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, disable_capture)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); return z_impl_pwm_disable_capture((const struct device *)dev, channel); } #include @@ -57,9 +57,9 @@ static inline int z_vrfy_pwm_capture_cycles(const struct device *dev, uint32_t pulse; int err; - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, configure_capture)); - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, enable_capture)); - Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, disable_capture)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, configure_capture)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); + Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); err = z_impl_pwm_capture_cycles((const struct device *)dev, channel, flags, &period, &pulse, timeout); diff --git a/drivers/rtc/rtc_handlers.c b/drivers/rtc/rtc_handlers.c index dcd91377cf6..95d373025a4 100644 --- a/drivers/rtc/rtc_handlers.c +++ b/drivers/rtc/rtc_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_time)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_time)); Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_set_time(dev, timeptr); } @@ -17,7 +17,7 @@ static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time *timeptr) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_time)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_time)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_get_time(dev, timeptr); } @@ -27,7 +27,7 @@ static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); return z_impl_rtc_alarm_get_supported_fields(dev, id, mask); } @@ -36,7 +36,7 @@ static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, const struct rtc_time *timeptr) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_set_time(dev, id, mask, timeptr); } @@ -45,7 +45,7 @@ static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t i static inline int z_vrfy_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, struct rtc_time *timeptr) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_get_time(dev, id, mask, timeptr); @@ -54,7 +54,7 @@ static inline int z_vrfy_rtc_alarm_get_time(const struct device *dev, uint16_t i static inline int z_vrfy_rtc_alarm_is_pending(const struct device *dev, uint16_t id) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_is_pending)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_is_pending)); return z_impl_rtc_alarm_is_pending(dev, id); } #include @@ -63,7 +63,7 @@ static inline int z_vrfy_rtc_alarm_is_pending(const struct device *dev, uint16_t #ifdef CONFIG_RTC_CALIBRATION static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t calibration) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_calibration)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_calibration)); return z_impl_rtc_set_calibration(dev, calibration); } @@ -71,7 +71,7 @@ static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t c static inline int z_vrfy_rtc_get_calibration(const struct device *dev, int32_t *calibration) { - Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_calibration)); + Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_calibration)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); return z_impl_rtc_get_calibration(dev, calibration); } diff --git a/drivers/sensor/sensor_handlers.c b/drivers/sensor/sensor_handlers.c index 18481024465..a574d20b60b 100644 --- a/drivers/sensor/sensor_handlers.c +++ b/drivers/sensor/sensor_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_sensor_attr_set(const struct device *dev, enum sensor_attribute attr, const struct sensor_value *val) { - Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, attr_set)); + Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_set)); Z_OOPS(K_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_set((const struct device *)dev, chan, attr, (const struct sensor_value *)val); @@ -24,7 +24,7 @@ static inline int z_vrfy_sensor_attr_get(const struct device *dev, enum sensor_attribute attr, struct sensor_value *val) { - Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, attr_get)); + Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_get)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_get((const struct device *)dev, chan, attr, (struct sensor_value *)val); @@ -33,7 +33,7 @@ static inline int z_vrfy_sensor_attr_get(const struct device *dev, static inline int z_vrfy_sensor_sample_fetch(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); + Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); return z_impl_sensor_sample_fetch((const struct device *)dev); } #include @@ -41,7 +41,7 @@ static inline int z_vrfy_sensor_sample_fetch(const struct device *dev) static inline int z_vrfy_sensor_sample_fetch_chan(const struct device *dev, enum sensor_channel type) { - Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); + Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); return z_impl_sensor_sample_fetch_chan((const struct device *)dev, type); } @@ -51,7 +51,7 @@ static inline int z_vrfy_sensor_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { - Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, channel_get)); + Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, channel_get)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_channel_get((const struct device *)dev, chan, (struct sensor_value *)val); diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 7035dc3d9e6..823ba718777 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -10,14 +10,14 @@ #define UART_SIMPLE(op_) \ static inline int z_vrfy_uart_##op_(const struct device *dev) \ { \ - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, op_)); \ + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ return z_impl_uart_ ## op_(dev); \ } #define UART_SIMPLE_VOID(op_) \ static inline void z_vrfy_uart_##op_(const struct device *dev) \ { \ - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, op_)); \ + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ z_impl_uart_ ## op_(dev); \ } @@ -27,7 +27,7 @@ UART_SIMPLE(err_check) static inline int z_vrfy_uart_poll_in(const struct device *dev, unsigned char *p_char) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_in)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char))); return z_impl_uart_poll_in(dev, p_char); } @@ -36,7 +36,7 @@ static inline int z_vrfy_uart_poll_in(const struct device *dev, static inline int z_vrfy_uart_poll_in_u16(const struct device *dev, uint16_t *p_u16) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_in)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_u16, sizeof(uint16_t))); return z_impl_uart_poll_in_u16(dev, p_u16); } @@ -45,7 +45,7 @@ static inline int z_vrfy_uart_poll_in_u16(const struct device *dev, static inline void z_vrfy_uart_poll_out(const struct device *dev, unsigned char out_char) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_out)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); z_impl_uart_poll_out((const struct device *)dev, out_char); } #include @@ -53,7 +53,7 @@ static inline void z_vrfy_uart_poll_out(const struct device *dev, static inline void z_vrfy_uart_poll_out_u16(const struct device *dev, uint16_t out_u16) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_out)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); z_impl_uart_poll_out_u16((const struct device *)dev, out_u16); } #include @@ -62,7 +62,7 @@ static inline void z_vrfy_uart_poll_out_u16(const struct device *dev, static inline int z_vrfy_uart_config_get(const struct device *dev, struct uart_config *cfg) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, config_get)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(cfg, sizeof(struct uart_config))); return z_impl_uart_config_get(dev, cfg); @@ -72,7 +72,7 @@ static inline int z_vrfy_uart_config_get(const struct device *dev, static inline int z_vrfy_uart_configure(const struct device *dev, const struct uart_config *cfg) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, config_get)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); Z_OOPS(K_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); return z_impl_uart_configure(dev, cfg); @@ -90,7 +90,7 @@ static inline int z_vrfy_uart_configure(const struct device *dev, static inline int z_vrfy_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, tx)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); return z_impl_uart_tx(dev, buf, len, timeout); } @@ -101,7 +101,7 @@ static inline int z_vrfy_uart_tx_u16(const struct device *dev, const uint16_t *buf, size_t len, int32_t timeout) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, tx)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(buf, len, sizeof(uint16_t))); return z_impl_uart_tx_u16(dev, buf, len, timeout); } @@ -115,7 +115,7 @@ static inline int z_vrfy_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, rx_enable)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); return z_impl_uart_rx_enable(dev, buf, len, timeout); } @@ -126,7 +126,7 @@ static inline int z_vrfy_uart_rx_enable_u16(const struct device *dev, uint16_t *buf, size_t len, int32_t timeout) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, rx_enable)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(buf, len, sizeof(uint16_t))); return z_impl_uart_rx_enable_u16(dev, buf, len, timeout); } @@ -160,7 +160,7 @@ UART_SIMPLE(irq_update) static inline int z_vrfy_uart_line_ctrl_set(const struct device *dev, uint32_t ctrl, uint32_t val) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, line_ctrl_set)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_set)); return z_impl_uart_line_ctrl_set((const struct device *)dev, ctrl, val); } @@ -169,7 +169,7 @@ static inline int z_vrfy_uart_line_ctrl_set(const struct device *dev, static inline int z_vrfy_uart_line_ctrl_get(const struct device *dev, uint32_t ctrl, uint32_t *val) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, line_ctrl_get)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_get)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(uint32_t))); return z_impl_uart_line_ctrl_get((const struct device *)dev, ctrl, (uint32_t *)val); @@ -181,7 +181,7 @@ static inline int z_vrfy_uart_line_ctrl_get(const struct device *dev, static inline int z_vrfy_uart_drv_cmd(const struct device *dev, uint32_t cmd, uint32_t p) { - Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, drv_cmd)); + Z_OOPS(K_SYSCALL_DRIVER_UART(dev, drv_cmd)); return z_impl_uart_drv_cmd((const struct device *)dev, cmd, p); } #include diff --git a/drivers/smbus/smbus_handlers.c b/drivers/smbus/smbus_handlers.c index cb856800ef8..5db5d12dfa8 100644 --- a/drivers/smbus/smbus_handlers.c +++ b/drivers/smbus/smbus_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_smbus_configure(const struct device *dev, uint32_t dev_config) { - Z_OOPS(Z_SYSCALL_DRIVER_SMBUS(dev, configure)); + Z_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, configure)); return z_impl_smbus_configure(dev, dev_config); } @@ -20,7 +20,7 @@ static inline int z_vrfy_smbus_configure(const struct device *dev, static inline int z_vrfy_smbus_get_config(const struct device *dev, uint32_t *dev_config) { - Z_OOPS(Z_SYSCALL_DRIVER_SMBUS(dev, get_config)); + Z_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, get_config)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_smbus_get_config(dev, dev_config); diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index 413b596dde1..ab1708bb5b6 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -77,7 +77,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, struct spi_config config_copy; Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); - Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, transceive)); + Z_OOPS(K_SYSCALL_DRIVER_SPI(dev, transceive)); if (tx_bufs) { const struct spi_buf_set *tx = @@ -120,7 +120,7 @@ static inline int z_vrfy_spi_release(const struct device *dev, const struct spi_config *config) { Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); - Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, release)); + Z_OOPS(K_SYSCALL_DRIVER_SPI(dev, release)); return z_impl_spi_release((const struct device *)dev, config); } #include diff --git a/drivers/usb/bc12/bc12_handlers.c b/drivers/usb/bc12/bc12_handlers.c index 55a61b76fed..0e4e6d83e25 100644 --- a/drivers/usb/bc12/bc12_handlers.c +++ b/drivers/usb/bc12/bc12_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_bc12_set_role(const struct device *dev, enum bc12_role role) { - Z_OOPS(Z_SYSCALL_DRIVER_BC12(dev, set_role)); + Z_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_role)); return z_impl_bc12_set_role(dev, role); } @@ -17,7 +17,7 @@ static inline int z_vrfy_bc12_set_role(const struct device *dev, enum bc12_role static inline int z_vrfy_bc12_set_result_cb(const struct device *dev, bc12_callback_t cb, void *user_data) { - Z_OOPS(Z_SYSCALL_DRIVER_BC12(dev, set_result_cb)); + Z_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_result_cb)); Z_OOPS(K_SYSCALL_VERIFY_MSG(cb == NULL, "callbacks may not be set from user mode")); return z_impl_bc12_set_result_cb(dev, cb, user_data); diff --git a/drivers/virtualization/virt_ivshmem_handlers.c b/drivers/virtualization/virt_ivshmem_handlers.c index bbeb9257a75..8f6221c8160 100644 --- a/drivers/virtualization/virt_ivshmem_handlers.c +++ b/drivers/virtualization/virt_ivshmem_handlers.c @@ -11,7 +11,7 @@ static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, uintptr_t *memmap) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_mem)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_mem)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_mem(dev, memmap); @@ -20,7 +20,7 @@ static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, static inline uint32_t z_vrfy_ivshmem_get_id(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_id)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_id)); return z_impl_ivshmem_get_id(dev); } @@ -28,7 +28,7 @@ static inline uint32_t z_vrfy_ivshmem_get_id(const struct device *dev) static inline uint16_t z_vrfy_ivshmem_get_vectors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_vectors)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_vectors)); return z_impl_ivshmem_get_vectors(dev); } @@ -37,7 +37,7 @@ static inline uint16_t z_vrfy_ivshmem_get_vectors(const struct device *dev) static inline int z_vrfy_ivshmem_int_peer(const struct device *dev, uint32_t peer_id, uint16_t vector) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, int_peer)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, int_peer)); return z_impl_ivshmem_int_peer(dev, peer_id, vector); } @@ -47,7 +47,7 @@ static inline int z_vrfy_ivshmem_register_handler(const struct device *dev, struct k_poll_signal *signal, uint16_t vector) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, register_handler)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, register_handler)); Z_OOPS(K_SYSCALL_OBJ(signal, K_OBJ_POLL_SIGNAL)); return z_impl_ivshmem_register_handler(dev, signal, vector); @@ -59,7 +59,7 @@ static inline int z_vrfy_ivshmem_register_handler(const struct device *dev, static inline size_t z_vrfy_ivshmem_get_rw_mem_section(const struct device *dev, uintptr_t *memmap) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_rw_mem_section)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_rw_mem_section)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_rw_mem_section(dev, memmap); @@ -70,7 +70,7 @@ static inline size_t z_vrfy_ivshmem_get_output_mem_section(const struct device * uint32_t peer_id, uintptr_t *memmap) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_output_mem_section)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_output_mem_section)); Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_output_mem_section(dev, peer_id, memmap); @@ -80,7 +80,7 @@ static inline size_t z_vrfy_ivshmem_get_output_mem_section(const struct device * static inline uint32_t z_vrfy_ivshmem_get_state(const struct device *dev, uint32_t peer_id) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_state)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_state)); return z_impl_ivshmem_get_state(dev, peer_id); } @@ -89,7 +89,7 @@ static inline uint32_t z_vrfy_ivshmem_get_state(const struct device *dev, static inline int z_vrfy_ivshmem_set_state(const struct device *dev, uint32_t state) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, set_state)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, set_state)); return z_impl_ivshmem_set_state(dev, state); } @@ -97,7 +97,7 @@ static inline int z_vrfy_ivshmem_set_state(const struct device *dev, static inline uint32_t z_vrfy_ivshmem_get_max_peers(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_max_peers)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_max_peers)); return z_impl_ivshmem_get_max_peers(dev); } @@ -105,7 +105,7 @@ static inline uint32_t z_vrfy_ivshmem_get_max_peers(const struct device *dev) static inline uint16_t z_vrfy_ivshmem_get_protocol(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, get_protocol)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_protocol)); return z_impl_ivshmem_get_protocol(dev); } @@ -114,7 +114,7 @@ static inline uint16_t z_vrfy_ivshmem_get_protocol(const struct device *dev) static inline int z_vrfy_ivshmem_enable_interrupts(const struct device *dev, bool enable) { - Z_OOPS(Z_SYSCALL_DRIVER_IVSHMEM(dev, enable_interrupts)); + Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, enable_interrupts)); return z_impl_ivshmem_enable_interrupts(dev, enable); } diff --git a/drivers/w1/w1_handlers.c b/drivers/w1/w1_handlers.c index 83e4b2afad6..496fc7a4cca 100644 --- a/drivers/w1/w1_handlers.c +++ b/drivers/w1/w1_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_w1_reset_bus(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, reset_bus)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, reset_bus)); return z_impl_w1_reset_bus((const struct device *)dev); } @@ -17,7 +17,7 @@ static inline int z_vrfy_w1_reset_bus(const struct device *dev) static inline int z_vrfy_w1_read_bit(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, read_bit)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, read_bit)); return z_impl_w1_read_bit((const struct device *)dev); } @@ -25,7 +25,7 @@ static inline int z_vrfy_w1_read_bit(const struct device *dev) static inline int z_vrfy_w1_write_bit(const struct device *dev, bool bit) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, write_bit)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, write_bit)); return z_impl_w1_write_bit((const struct device *)dev, bit); } @@ -33,7 +33,7 @@ static inline int z_vrfy_w1_write_bit(const struct device *dev, bool bit) static inline int z_vrfy_w1_read_byte(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, read_byte)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, read_byte)); return z_impl_w1_read_byte((const struct device *)dev); } @@ -41,7 +41,7 @@ static inline int z_vrfy_w1_read_byte(const struct device *dev) static inline int z_vrfy_w1_write_byte(const struct device *dev, uint8_t byte) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, write_byte)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, write_byte)); return z_impl_w1_write_byte((const struct device *)dev, (uint8_t)byte); } @@ -80,7 +80,7 @@ static inline int z_vrfy_w1_change_bus_lock(const struct device *dev, bool lock) static inline int z_vrfy_w1_configure(const struct device *dev, enum w1_settings_type type, uint32_t value) { - Z_OOPS(Z_SYSCALL_DRIVER_W1(dev, configure)); + Z_OOPS(K_SYSCALL_DRIVER_W1(dev, configure)); return z_impl_w1_configure(dev, type, value); } diff --git a/drivers/watchdog/wdt_handlers.c b/drivers/watchdog/wdt_handlers.c index 8afa81c67e6..66f99c6590d 100644 --- a/drivers/watchdog/wdt_handlers.c +++ b/drivers/watchdog/wdt_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_wdt_setup(const struct device *dev, uint8_t options) { - Z_OOPS(Z_SYSCALL_DRIVER_WDT(dev, setup)); + Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, setup)); return z_impl_wdt_setup(dev, options); } @@ -17,7 +17,7 @@ static inline int z_vrfy_wdt_setup(const struct device *dev, uint8_t options) static inline int z_vrfy_wdt_disable(const struct device *dev) { - Z_OOPS(Z_SYSCALL_DRIVER_WDT(dev, disable)); + Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, disable)); return z_impl_wdt_disable(dev); } @@ -25,7 +25,7 @@ static inline int z_vrfy_wdt_disable(const struct device *dev) static inline int z_vrfy_wdt_feed(const struct device *dev, int channel_id) { - Z_OOPS(Z_SYSCALL_DRIVER_WDT(dev, feed)); + Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, feed)); return z_impl_wdt_feed(dev, channel_id); } diff --git a/samples/userspace/prod_consumer/src/sample_driver_handlers.c b/samples/userspace/prod_consumer/src/sample_driver_handlers.c index 66f8c12ce88..89a4ff12044 100644 --- a/samples/userspace/prod_consumer/src/sample_driver_handlers.c +++ b/samples/userspace/prod_consumer/src/sample_driver_handlers.c @@ -10,7 +10,7 @@ int z_vrfy_sample_driver_state_set(const struct device *dev, bool active) { - if (Z_SYSCALL_DRIVER_SAMPLE(dev, state_set)) { + if (K_SYSCALL_DRIVER_SAMPLE(dev, state_set)) { return -EINVAL; } @@ -21,7 +21,7 @@ int z_vrfy_sample_driver_state_set(const struct device *dev, bool active) int z_vrfy_sample_driver_write(const struct device *dev, void *buf) { - if (Z_SYSCALL_DRIVER_SAMPLE(dev, write)) { + if (K_SYSCALL_DRIVER_SAMPLE(dev, write)) { return -EINVAL; } diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index 0725ca0c30d..6e41adb797d 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -885,7 +885,7 @@ def write_gperf_table(fp, syms, objs, little_endian, static_begin, static_end): driver_macro_tpl = """ -#define Z_SYSCALL_DRIVER_%(driver_upper)s(ptr, op) Z_SYSCALL_DRIVER_GEN(ptr, op, %(driver_lower)s, %(driver_upper)s) +#define K_SYSCALL_DRIVER_%(driver_upper)s(ptr, op) K_SYSCALL_DRIVER_GEN(ptr, op, %(driver_lower)s, %(driver_upper)s) """ @@ -893,7 +893,7 @@ def write_validation_output(fp): fp.write("#ifndef DRIVER_VALIDATION_GEN_H\n") fp.write("#define DRIVER_VALIDATION_GEN_H\n") - fp.write("""#define Z_SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\ + fp.write("""#define K_SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\ (K_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case) || \\ K_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op)) """) From ee9f278323dd3fd87348b701caaef283b6f261b4 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:19:04 +0000 Subject: [PATCH 3029/4498] syscall: rename Z_SYSCALL_VERIFY -> K_SYSCALL_VERIFY Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/usermode/syscalls.rst | 4 ++-- drivers/i2c/i2c_handlers.c | 2 +- drivers/i3c/i3c_handlers.c | 2 +- drivers/spi/spi_handlers.c | 4 ++-- include/zephyr/internal/syscall_handler.h | 2 +- kernel/poll.c | 4 ++-- kernel/stack.c | 2 +- kernel/thread.c | 8 ++++---- subsys/net/lib/sockets/sockets.c | 6 +++--- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 5c0ad90822c..60f0b481030 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -311,7 +311,7 @@ Several macros exist to validate arguments: * :c:macro:`K_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean expression which must evaluate to true otherwise the check will fail. - A variant :c:macro:`Z_SYSCALL_VERIFY` exists which does not take + A variant :c:macro:`K_SYSCALL_VERIFY` exists which does not take a message parameter, instead printing the expression tested if it fails. The latter should only be used for the most obvious of tests. @@ -641,7 +641,7 @@ Helper macros for creating system call verification functions are provided in * :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` * :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` * :c:macro:`K_SYSCALL_VERIFY_MSG()` -* :c:macro:`Z_SYSCALL_VERIFY` +* :c:macro:`K_SYSCALL_VERIFY` Functions for invoking system calls are defined in :zephyr_file:`include/zephyr/syscall.h`: diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index 5c463890028..99c3e60fa72 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -59,7 +59,7 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, * in i2c.h use only a handful of messages, so up to 32 messages * should be more than sufficient. */ - Z_OOPS(Z_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); + Z_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index 6bb37f76448..b9aaaa7191f 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -69,7 +69,7 @@ static inline int z_vrfy_i3c_transfer(struct i3c_device_desc *target, * in i2c.h use only a handful of messages, so up to 32 messages * should be more than sufficient. */ - Z_OOPS(Z_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); + Z_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index ab1708bb5b6..3618d9dedcb 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -86,7 +86,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, Z_OOPS(K_SYSCALL_MEMORY_READ(tx_bufs, sizeof(struct spi_buf_set))); memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy)); - Z_OOPS(Z_SYSCALL_VERIFY(tx_bufs_copy.count < 32)); + Z_OOPS(K_SYSCALL_VERIFY(tx_bufs_copy.count < 32)); } else { memset(&tx_bufs_copy, 0, sizeof(tx_bufs_copy)); } @@ -98,7 +98,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, Z_OOPS(K_SYSCALL_MEMORY_READ(rx_bufs, sizeof(struct spi_buf_set))); memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy)); - Z_OOPS(Z_SYSCALL_VERIFY(rx_bufs_copy.count < 32)); + Z_OOPS(K_SYSCALL_VERIFY(rx_bufs_copy.count < 32)); } else { memset(&rx_bufs_copy, 0, sizeof(rx_bufs_copy)); } diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index ddceb01834f..ff39f5cd9a0 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -328,7 +328,7 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * oops. A stringified version of this expression will be printed. * @return 0 on success, nonzero on failure */ -#define Z_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr) +#define K_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr) /** * @brief Runtime check that a user thread has read and/or write permission to diff --git a/kernel/poll.c b/kernel/poll.c index 5b38ebefe02..3c0c94744ad 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -364,7 +364,7 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, /* Validate the events buffer and make a copy of it in an * allocated kernel-side buffer. */ - if (Z_SYSCALL_VERIFY(num_events >= 0)) { + if (K_SYSCALL_VERIFY(num_events >= 0)) { ret = -EINVAL; goto out; } @@ -393,7 +393,7 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, for (int i = 0; i < num_events; i++) { struct k_poll_event *e = &events_copy[i]; - if (Z_SYSCALL_VERIFY(e->mode == K_POLL_MODE_NOTIFY_ONLY)) { + if (K_SYSCALL_VERIFY(e->mode == K_POLL_MODE_NOTIFY_ONLY)) { ret = -EINVAL; goto out_free; } diff --git a/kernel/stack.c b/kernel/stack.c index 90c6a0f2232..72db870b6ea 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -65,7 +65,7 @@ static inline int32_t z_vrfy_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) { Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK)); - Z_OOPS(Z_SYSCALL_VERIFY(num_entries > 0)); + Z_OOPS(K_SYSCALL_VERIFY(num_entries > 0)); return z_impl_k_stack_alloc_init(stack, num_entries); } #include diff --git a/kernel/thread.c b/kernel/thread.c index 7bd47ae2668..42327565eff 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -763,14 +763,14 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, /* User threads may only create other user threads and they can't * be marked as essential */ - Z_OOPS(Z_SYSCALL_VERIFY(options & K_USER)); - Z_OOPS(Z_SYSCALL_VERIFY(!(options & K_ESSENTIAL))); + Z_OOPS(K_SYSCALL_VERIFY(options & K_USER)); + Z_OOPS(K_SYSCALL_VERIFY(!(options & K_ESSENTIAL))); /* Check validity of prio argument; must be the same or worse priority * than the caller */ - Z_OOPS(Z_SYSCALL_VERIFY(_is_valid_prio(prio, NULL))); - Z_OOPS(Z_SYSCALL_VERIFY(z_is_prio_lower_or_equal(prio, + Z_OOPS(K_SYSCALL_VERIFY(_is_valid_prio(prio, NULL))); + Z_OOPS(K_SYSCALL_VERIFY(z_is_prio_lower_or_equal(prio, _current->base.prio))); z_setup_new_thread(new_thread, stack, stack_size, diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 1d05debcf29..050b0c1c533 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -482,7 +482,7 @@ static inline int z_vrfy_zsock_bind(int sock, const struct sockaddr *addr, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_bind(sock, (struct sockaddr *)&dest_addr_copy, @@ -561,7 +561,7 @@ int z_vrfy_zsock_connect(int sock, const struct sockaddr *addr, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_connect(sock, (struct sockaddr *)&dest_addr_copy, @@ -864,7 +864,7 @@ ssize_t z_vrfy_zsock_sendto(int sock, const void *buf, size_t len, int flags, Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); if (dest_addr) { - Z_OOPS(Z_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)dest_addr, addrlen)); } From a08bfeb49cc6f030fdd731d9254ac073e18cfee5 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:20:28 +0000 Subject: [PATCH 3030/4498] syscall: rename Z_OOPS -> K_OOPS Rename internal API to not use z_/Z_. Signed-off-by: Anas Nashif --- doc/kernel/drivers/index.rst | 2 +- doc/kernel/usermode/syscalls.rst | 44 +++++------ drivers/adc/adc_handlers.c | 18 ++--- drivers/auxdisplay/auxdisplay_handlers.c | 38 +++++----- drivers/bbram/bbram_handlers.c | 18 ++--- drivers/cache/cache_handlers.c | 6 +- drivers/can/can_handlers.c | 74 +++++++++---------- drivers/charger/charger_handlers.c | 8 +- drivers/counter/counter_handlers.c | 42 +++++------ drivers/counter/maxim_ds3231.c | 10 +-- drivers/dac/dac_handlers.c | 6 +- drivers/dma/dma_handlers.c | 4 +- drivers/eeprom/eeprom_handlers.c | 10 +-- drivers/entropy/entropy_handlers.c | 4 +- drivers/espi/espi_handlers.c | 68 ++++++++--------- drivers/flash/flash_handlers.c | 34 ++++----- drivers/flash/flash_npcx_fiu_nor.c | 8 +- drivers/flash/flash_simulator.c | 2 +- drivers/flash/flash_stm32_ex_op.c | 8 +- drivers/flash/nrf_qspi_nor.c | 2 +- .../fuel_gauge/fuel_gauge_syscall_handlers.c | 30 ++++---- drivers/gpio/gpio_handlers.c | 28 +++---- drivers/hwinfo/hwinfo_handlers.c | 6 +- drivers/hwspinlock/hwspinlock_handlers.c | 8 +- drivers/i2c/i2c_handlers.c | 20 ++--- drivers/i2s/i2s_handlers.c | 14 ++-- drivers/i3c/i3c_handlers.c | 24 +++--- drivers/ipm/ipm_handlers.c | 10 +-- drivers/kscan/kscan_handlers.c | 8 +- drivers/led/led_handlers.c | 22 +++--- drivers/mbox/mbox_handlers.c | 16 ++-- .../timeaware_gpio/timeaware_gpio_handlers.c | 16 ++-- drivers/peci/peci_handlers.c | 10 +-- drivers/ps2/ps2_handlers.c | 14 ++-- drivers/ptp_clock/ptp_clock.c | 4 +- drivers/pwm/pwm_handlers.c | 20 ++--- drivers/retained_mem/retained_mem_handlers.c | 12 +-- drivers/rtc/rtc_handlers.c | 30 ++++---- drivers/sensor/sensor_handlers.c | 26 +++---- drivers/serial/uart_handlers.c | 48 ++++++------ drivers/smbus/smbus_handlers.c | 52 ++++++------- drivers/spi/spi_handlers.c | 22 +++--- drivers/usb/bc12/bc12_handlers.c | 6 +- .../virtualization/virt_ivshmem_handlers.c | 32 ++++---- drivers/w1/w1_handlers.c | 28 +++---- drivers/watchdog/wdt_handlers.c | 6 +- include/zephyr/internal/syscall_handler.h | 2 +- kernel/atomic_c.c | 10 +-- kernel/condvar.c | 10 +-- kernel/device.c | 2 +- kernel/events.c | 14 ++-- kernel/msg_q.c | 28 +++---- kernel/mutex.c | 6 +- kernel/paging/statistics.c | 12 +-- kernel/pipes.c | 22 +++--- kernel/poll.c | 24 +++--- kernel/queue.c | 16 ++-- kernel/sched.c | 22 +++--- kernel/sem.c | 10 +-- kernel/stack.c | 10 +-- kernel/thread.c | 24 +++--- kernel/timer.c | 16 ++-- kernel/userspace_handler.c | 6 +- lib/libc/arcmwdt/libc-hooks.c | 2 +- .../minimal/source/stdout/stdout_console.c | 2 +- lib/libc/newlib/libc-hooks.c | 4 +- lib/os/printk.c | 2 +- lib/posix/clock.c | 2 +- scripts/build/gen_syscalls.py | 4 +- subsys/logging/log_mgmt.c | 8 +- subsys/net/ip/net_if.c | 16 ++-- subsys/net/ip/utils.c | 12 +-- subsys/net/lib/sockets/getaddrinfo.c | 4 +- subsys/net/lib/sockets/socketpair.c | 2 +- subsys/net/lib/sockets/sockets.c | 46 ++++++------ subsys/net/lib/sockets/sockets_misc.c | 2 +- subsys/random/rand32_handlers.c | 4 +- subsys/rtio/rtio_handlers.c | 24 +++--- tests/kernel/mem_protect/syscalls/src/main.c | 2 +- tests/kernel/threads/thread_stack/src/main.c | 4 +- tests/ztest/error_hook/README.txt | 2 +- tests/ztest/error_hook/src/main.c | 8 +- 82 files changed, 651 insertions(+), 651 deletions(-) diff --git a/doc/kernel/drivers/index.rst b/doc/kernel/drivers/index.rst index 63500f1d5a0..3d3c1715b9f 100644 --- a/doc/kernel/drivers/index.rst +++ b/doc/kernel/drivers/index.rst @@ -239,7 +239,7 @@ implementation of both the subsystem API and the specific APIs: int z_vrfy_specific_from_user(const struct device *dev, int bar) { - Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_GENERIC, &api)); + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_GENERIC, &api)); return z_impl_specific_do_that(dev, bar) } diff --git a/doc/kernel/usermode/syscalls.rst b/doc/kernel/usermode/syscalls.rst index 60f0b481030..f751697d9a3 100644 --- a/doc/kernel/usermode/syscalls.rst +++ b/doc/kernel/usermode/syscalls.rst @@ -331,7 +331,7 @@ Several macros exist to validate arguments: API structure. If any check fails, the macros will return a nonzero value. The macro -:c:macro:`Z_OOPS()` can be used to induce a kernel oops which will kill the +:c:macro:`K_OOPS()` can be used to induce a kernel oops which will kill the calling thread. This is done instead of returning some error condition to keep the APIs the same when calling from supervisor mode. @@ -357,7 +357,7 @@ For example: static int z_vrfy_k_sem_take(struct k_sem *sem, int32_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_take(sem, timeout); } #include @@ -397,7 +397,7 @@ for some integral value: int ret; ret = z_impl_some_syscall(&local_out_param); - Z_OOPS(k_usermode_to_copy(out_param, &local_out_param, sizeof(*out_param))); + K_OOPS(k_usermode_to_copy(out_param, &local_out_param, sizeof(*out_param))); return ret; } @@ -411,7 +411,7 @@ It might be tempting to do something more concise: int z_vrfy_some_syscall(int *out_param) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param))); return z_impl_some_syscall(out_param); } @@ -433,9 +433,9 @@ bytes processed. This too should use a stack copy: size_t size; int ret; - Z_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size)); + K_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size)); ret = z_impl_in_out_syscall(&size); - Z_OOPS(k_usermode_to_copy(size_ptr, &size, sizeof(size))); + K_OOPS(k_usermode_to_copy(size_ptr, &size, sizeof(size))); return ret; } @@ -461,11 +461,11 @@ be copied. Typically this is done by allocating copies on the stack: struct bar bar_right_copy; struct bar bar_left_copy; - Z_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); - Z_OOPS(k_usermode_from_copy(&bar_right_copy, foo_copy.bar_right, + K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); + K_OOPS(k_usermode_from_copy(&bar_right_copy, foo_copy.bar_right, sizeof(struct bar))); foo_copy.bar_right = &bar_right_copy; - Z_OOPS(k_usermode_from_copy(&bar_left_copy, foo_copy.bar_left, + K_OOPS(k_usermode_from_copy(&bar_left_copy, foo_copy.bar_left, sizeof(struct bar))); foo_copy.bar_left = &bar_left_copy; @@ -478,7 +478,7 @@ memory from the caller's resource pool via :c:func:`z_thread_malloc()`. This should always be considered last resort. Functional safety programming guidelines heavily discourage usage of heap and the fact that a resource pool is used must be clearly documented. Any issues with allocation must be -reported, to a caller, with returning the ``-ENOMEM`` . The ``Z_OOPS()`` +reported, to a caller, with returning the ``-ENOMEM`` . The ``K_OOPS()`` should never be used to verify if resource allocation has been successful. .. code-block:: c @@ -500,7 +500,7 @@ should never be used to verify if resource allocation has been successful. size_t bar_list_bytes; /* Safely copy foo into foo_copy */ - Z_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); + K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); /* Bounds check the count member, in the copy we made */ if (foo_copy.count > 32) { @@ -514,7 +514,7 @@ should never be used to verify if resource allocation has been successful. if (bar_list_copy == NULL) { return -ENOMEM; } - Z_OOPS(k_usermode_from_copy(bar_list_copy, foo_copy.bar_list, + K_OOPS(k_usermode_from_copy(bar_list_copy, foo_copy.bar_list, bar_list_bytes)); foo_copy.bar_list = bar_list_copy; @@ -549,7 +549,7 @@ The following constraints need to be met: int z_vrfy_get_data_from_kernel(void *buf, size_t size) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, size)); return z_impl_get_data_from_kernel(buf, size); } @@ -558,16 +558,16 @@ Verification Return Value Policies When verifying system calls, it's important to note which kinds of verification failures should propagate a return value to the caller, and which should -simply invoke :c:macro:`Z_OOPS()` which kills the calling thread. The current +simply invoke :c:macro:`K_OOPS()` which kills the calling thread. The current conventions are as follows: #. For system calls that are defined but not compiled, invocations of these missing system calls are routed to :c:func:`handler_no_syscall()` which - invokes :c:macro:`Z_OOPS()`. + invokes :c:macro:`K_OOPS()`. #. Any invalid access to memory found by the set of ``K_SYSCALL_MEMORY`` APIs, :c:func:`k_usermode_from_copy()`, :c:func:`k_usermode_to_copy()` - should trigger a :c:macro:`Z_OOPS`. This happens when the caller doesn't have + should trigger a :c:macro:`K_OOPS`. This happens when the caller doesn't have appropriate permissions on the memory buffer or some size calculation overflowed. @@ -576,7 +576,7 @@ conventions are as follows: manually using :c:func:`k_object_validate()`. These can fail for a variety of reasons: missing driver API, bad kernel object pointer, wrong kernel object type, or improper initialization state. These issues should always - invoke :c:macro:`Z_OOPS()`. + invoke :c:macro:`K_OOPS()`. #. Any error resulting from a failed memory heap allocation, often from invoking :c:func:`z_thread_malloc()`, should propagate ``-ENOMEM`` to the @@ -594,7 +594,7 @@ conventions are as follows: be registered from user mode. APIs which simply install callbacks shall not be exposed as system calls. Some driver subsystem APIs may take optional function callback pointers. User mode verification functions for these APIs - must enforce that these are NULL and should invoke :c:macro:`Z_OOPS()` if + must enforce that these are NULL and should invoke :c:macro:`K_OOPS()` if not. #. Some parameter checks are enforced only from user mode. These should be @@ -608,14 +608,14 @@ There are some known exceptions to these policies currently in Zephyr: initialization bit pulls double-duty to indicate whether a thread is running, cleared upon exit. See #23030. -* :c:func:`k_thread_create()` invokes :c:macro:`Z_OOPS()` for parameter +* :c:func:`k_thread_create()` invokes :c:macro:`K_OOPS()` for parameter checks, due to a great deal of existing code ignoring the return value. This will also be addressed by #23030. -* :c:func:`k_thread_abort()` invokes :c:macro:`Z_OOPS()` if an essential +* :c:func:`k_thread_abort()` invokes :c:macro:`K_OOPS()` if an essential thread is aborted, as the function has no return value. -* Various system calls related to logging invoke :c:macro:`Z_OOPS()` +* Various system calls related to logging invoke :c:macro:`K_OOPS()` when bad parameters are passed in as they do not propagate errors. Configuration Options @@ -635,7 +635,7 @@ Helper macros for creating system call verification functions are provided in * :c:macro:`K_SYSCALL_OBJ()` * :c:macro:`K_SYSCALL_OBJ_INIT()` * :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` -* :c:macro:`Z_OOPS()` +* :c:macro:`K_OOPS()` * :c:macro:`K_SYSCALL_MEMORY_READ()` * :c:macro:`K_SYSCALL_MEMORY_WRITE()` * :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` diff --git a/drivers/adc/adc_handlers.c b/drivers/adc/adc_handlers.c index 156415f1e5f..2b00c2d95a9 100644 --- a/drivers/adc/adc_handlers.c +++ b/drivers/adc/adc_handlers.c @@ -13,8 +13,8 @@ static inline int z_vrfy_adc_channel_setup(const struct device *dev, { struct adc_channel_cfg channel_cfg; - Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, channel_setup)); - Z_OOPS(k_usermode_from_copy(&channel_cfg, + K_OOPS(K_SYSCALL_DRIVER_ADC(dev, channel_setup)); + K_OOPS(k_usermode_from_copy(&channel_cfg, (struct adc_channel_cfg *)user_channel_cfg, sizeof(struct adc_channel_cfg))); @@ -55,12 +55,12 @@ static inline int z_vrfy_adc_read(const struct device *dev, struct adc_sequence sequence; struct adc_sequence_options options; - Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, read)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, + K_OOPS(K_SYSCALL_DRIVER_ADC(dev, read)); + K_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); if (sequence.options != NULL) { - Z_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, + K_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, "ADC sequence callbacks forbidden from user mode")); } @@ -76,15 +76,15 @@ static inline int z_vrfy_adc_read_async(const struct device *dev, struct adc_sequence sequence; struct adc_sequence_options options; - Z_OOPS(K_SYSCALL_DRIVER_ADC(dev, read_async)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, + K_OOPS(K_SYSCALL_DRIVER_ADC(dev, read_async)); + K_OOPS(K_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options, (struct adc_sequence *)user_sequence), "invalid ADC sequence")); if (sequence.options != NULL) { - Z_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, + K_OOPS(K_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL, "ADC sequence callbacks forbidden from user mode")); } - Z_OOPS(K_SYSCALL_OBJ(async, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ(async, K_OBJ_POLL_SIGNAL)); return z_impl_adc_read_async((const struct device *)dev, &sequence, (struct k_poll_signal *)async); diff --git a/drivers/auxdisplay/auxdisplay_handlers.c b/drivers/auxdisplay/auxdisplay_handlers.c index a7ea694a65a..5c88e7afa09 100644 --- a/drivers/auxdisplay/auxdisplay_handlers.c +++ b/drivers/auxdisplay/auxdisplay_handlers.c @@ -9,21 +9,21 @@ static inline int z_vrfy_auxdisplay_display_on(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_on(dev); } #include static inline int z_vrfy_auxdisplay_display_off(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_off(dev); } #include static inline int z_vrfy_auxdisplay_cursor_set_enabled(const struct device *dev, bool enabled) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_set_enabled(dev, enabled); } #include @@ -31,7 +31,7 @@ static inline int z_vrfy_auxdisplay_cursor_set_enabled(const struct device *dev, static inline int z_vrfy_auxdisplay_position_blinking_set_enabled(const struct device *dev, bool enabled) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_position_blinking_set_enabled(dev, enabled); } #include @@ -39,7 +39,7 @@ static inline int z_vrfy_auxdisplay_position_blinking_set_enabled(const struct d static inline int z_vrfy_auxdisplay_cursor_shift_set(const struct device *dev, uint8_t direction, bool display_shift) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_shift_set(dev, direction, display_shift); } #include @@ -48,7 +48,7 @@ static inline int z_vrfy_auxdisplay_cursor_position_set(const struct device *dev enum auxdisplay_position type, int16_t x, int16_t y) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_position_set(dev, type, x, y); } #include @@ -56,7 +56,7 @@ static inline int z_vrfy_auxdisplay_cursor_position_set(const struct device *dev static inline int z_vrfy_auxdisplay_cursor_position_get(const struct device *dev, int16_t *x, int16_t *y) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_cursor_position_get(dev, x, y); } #include @@ -65,7 +65,7 @@ static inline int z_vrfy_auxdisplay_display_position_set(const struct device *de enum auxdisplay_position type, int16_t x, int16_t y) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_position_set(dev, type, x, y); } #include @@ -73,7 +73,7 @@ static inline int z_vrfy_auxdisplay_display_position_set(const struct device *de static inline int z_vrfy_auxdisplay_display_position_get(const struct device *dev, int16_t *x, int16_t *y) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_display_position_get(dev, x, y); } #include @@ -81,14 +81,14 @@ static inline int z_vrfy_auxdisplay_display_position_get(const struct device *de static inline int z_vrfy_auxdisplay_capabilities_get(const struct device *dev, struct auxdisplay_capabilities *capabilities) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_capabilities_get(dev, capabilities); } #include static inline int z_vrfy_auxdisplay_clear(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_clear(dev); } #include @@ -96,7 +96,7 @@ static inline int z_vrfy_auxdisplay_clear(const struct device *dev) static inline int z_vrfy_auxdisplay_brightness_get(const struct device *dev, uint8_t *brightness) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_brightness_get(dev, brightness); } #include @@ -104,7 +104,7 @@ static inline int z_vrfy_auxdisplay_brightness_get(const struct device *dev, static inline int z_vrfy_auxdisplay_brightness_set(const struct device *dev, uint8_t brightness) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_brightness_set(dev, brightness); } #include @@ -112,7 +112,7 @@ static inline int z_vrfy_auxdisplay_brightness_set(const struct device *dev, static inline int z_vrfy_auxdisplay_backlight_get(const struct device *dev, uint8_t *backlight) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_backlight_get(dev, backlight); } #include @@ -120,14 +120,14 @@ static inline int z_vrfy_auxdisplay_backlight_get(const struct device *dev, static inline int z_vrfy_auxdisplay_backlight_set(const struct device *dev, uint8_t backlight) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_backlight_set(dev, backlight); } #include static inline int z_vrfy_auxdisplay_is_busy(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_is_busy(dev); } #include @@ -135,7 +135,7 @@ static inline int z_vrfy_auxdisplay_is_busy(const struct device *dev) static inline int z_vrfy_auxdisplay_custom_character_set(const struct device *dev, struct auxdisplay_character *character) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_custom_character_set(dev, character); } #include @@ -143,7 +143,7 @@ static inline int z_vrfy_auxdisplay_custom_character_set(const struct device *de static inline int z_vrfy_auxdisplay_write(const struct device *dev, const uint8_t *data, uint16_t len) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_write(dev, data, len); } #include @@ -151,7 +151,7 @@ static inline int z_vrfy_auxdisplay_write(const struct device *dev, const uint8_ static inline int z_vrfy_auxdisplay_custom_command(const struct device *dev, struct auxdisplay_custom_data *data) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_AUXDISPLAY)); return z_impl_auxdisplay_custom_command(dev, data); } #include diff --git a/drivers/bbram/bbram_handlers.c b/drivers/bbram/bbram_handlers.c index 799262f69f4..14e4abe21b3 100644 --- a/drivers/bbram/bbram_handlers.c +++ b/drivers/bbram/bbram_handlers.c @@ -9,29 +9,29 @@ static inline int z_vrfy_bbram_check_invalid(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_invalid(dev); } #include static inline int z_vrfy_bbram_check_standby_power(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_standby_power(dev); } #include static inline int z_vrfy_bbram_check_power(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); return z_impl_bbram_check_power(dev); } #include static inline int z_vrfy_bbram_get_size(const struct device *dev, size_t *size) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); return z_impl_bbram_get_size(dev, size); } #include @@ -39,8 +39,8 @@ static inline int z_vrfy_bbram_get_size(const struct device *dev, size_t *size) static inline int z_vrfy_bbram_read(const struct device *dev, size_t offset, size_t size, uint8_t *data) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, size)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, size)); return z_impl_bbram_read(dev, offset, size, data); } #include @@ -48,8 +48,8 @@ static inline int z_vrfy_bbram_read(const struct device *dev, size_t offset, static inline int z_vrfy_bbram_write(const struct device *dev, size_t offset, size_t size, const uint8_t *data) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); - Z_OOPS(K_SYSCALL_MEMORY_READ(data, size)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_BBRAM)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, size)); return z_impl_bbram_write(dev, offset, size, data); } #include diff --git a/drivers/cache/cache_handlers.c b/drivers/cache/cache_handlers.c index 472e8f0ff58..2005124136f 100644 --- a/drivers/cache/cache_handlers.c +++ b/drivers/cache/cache_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_sys_cache_data_flush_range(void *addr, size_t size) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_flush_range(addr, size); } @@ -17,7 +17,7 @@ static inline int z_vrfy_sys_cache_data_flush_range(void *addr, size_t size) static inline int z_vrfy_sys_cache_data_invd_range(void *addr, size_t size) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_invd_range(addr, size); } @@ -25,7 +25,7 @@ static inline int z_vrfy_sys_cache_data_invd_range(void *addr, size_t size) static inline int z_vrfy_sys_cache_data_flush_and_invd_range(void *addr, size_t size) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(addr, size)); return z_impl_sys_cache_data_flush_and_invd_range(addr, size); } diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 5b3eecd489f..1e10baf79ca 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -13,11 +13,11 @@ static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *r struct can_timing res_copy; int err; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + K_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing(dev, &res_copy, bitrate, sample_pnt); - Z_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); + K_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); return err; } @@ -28,8 +28,8 @@ static inline int z_vrfy_can_set_timing(const struct device *dev, { struct can_timing timing_copy; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); - Z_OOPS(k_usermode_from_copy(&timing_copy, timing, sizeof(timing_copy))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); + K_OOPS(k_usermode_from_copy(&timing_copy, timing, sizeof(timing_copy))); return z_impl_can_set_timing(dev, &timing_copy); } @@ -38,8 +38,8 @@ static inline int z_vrfy_can_set_timing(const struct device *dev, static inline int z_vrfy_can_get_core_clock(const struct device *dev, uint32_t *rate) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate))); return z_impl_can_get_core_clock(dev, rate); } @@ -49,8 +49,8 @@ static inline int z_vrfy_can_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate) { /* Optional API function */ - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(max_bitrate, sizeof(*max_bitrate))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(max_bitrate, sizeof(*max_bitrate))); return z_impl_can_get_max_bitrate(dev, max_bitrate); } @@ -58,7 +58,7 @@ static inline int z_vrfy_can_get_max_bitrate(const struct device *dev, static inline const struct can_timing *z_vrfy_can_get_timing_min(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_min(dev); } @@ -66,7 +66,7 @@ static inline const struct can_timing *z_vrfy_can_get_timing_min(const struct de static inline const struct can_timing *z_vrfy_can_get_timing_max(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_max(dev); } @@ -80,11 +80,11 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi struct can_timing res_copy; int err; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); - Z_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_core_clock)); + K_OOPS(k_usermode_from_copy(&res_copy, res, sizeof(res_copy))); err = z_impl_can_calc_timing_data(dev, &res_copy, bitrate, sample_pnt); - Z_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); + K_OOPS(k_usermode_to_copy(res, &res_copy, sizeof(*res))); return err; } @@ -92,7 +92,7 @@ static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timi static inline const struct can_timing *z_vrfy_can_get_timing_data_min(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_data_min(dev); } @@ -100,7 +100,7 @@ static inline const struct can_timing *z_vrfy_can_get_timing_data_min(const stru static inline const struct can_timing *z_vrfy_can_get_timing_data_max(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_timing_data_max(dev); } @@ -111,8 +111,8 @@ static inline int z_vrfy_can_set_timing_data(const struct device *dev, { struct can_timing timing_data_copy; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); - Z_OOPS(k_usermode_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); + K_OOPS(k_usermode_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy))); return z_impl_can_set_timing_data(dev, &timing_data_copy); } @@ -121,7 +121,7 @@ static inline int z_vrfy_can_set_timing_data(const struct device *dev, static inline int z_vrfy_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing_data)); return z_impl_can_set_bitrate_data(dev, bitrate_data); } @@ -132,7 +132,7 @@ static inline int z_vrfy_can_set_bitrate_data(const struct device *dev, static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide) { /* Optional API function */ - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_get_max_filters(dev, ide); } @@ -140,8 +140,8 @@ static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide) static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode_t *cap) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_capabilities)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_capabilities)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap))); return z_impl_can_get_capabilities(dev, cap); } @@ -149,7 +149,7 @@ static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode static inline int z_vrfy_can_start(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, start)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, start)); return z_impl_can_start(dev); } @@ -157,7 +157,7 @@ static inline int z_vrfy_can_start(const struct device *dev) static inline int z_vrfy_can_stop(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, stop)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, stop)); return z_impl_can_stop(dev); } @@ -165,7 +165,7 @@ static inline int z_vrfy_can_stop(const struct device *dev) static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_mode)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_mode)); return z_impl_can_set_mode(dev, mode); } @@ -173,7 +173,7 @@ static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode) static inline int z_vrfy_can_set_bitrate(const struct device *dev, uint32_t bitrate) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, set_timing)); return z_impl_can_set_bitrate(dev, bitrate); } @@ -187,9 +187,9 @@ static inline int z_vrfy_can_send(const struct device *dev, { struct can_frame frame_copy; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, send)); - Z_OOPS(k_usermode_from_copy(&frame_copy, frame, sizeof(frame_copy))); - Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, send)); + K_OOPS(k_usermode_from_copy(&frame_copy, frame, sizeof(frame_copy))); + K_OOPS(K_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode")); return z_impl_can_send(dev, &frame_copy, timeout, callback, user_data); } @@ -201,9 +201,9 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, { struct can_filter filter_copy; - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(k_usermode_from_copy(&filter_copy, filter, sizeof(filter_copy))); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, add_rx_filter)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(k_usermode_from_copy(&filter_copy, filter, sizeof(filter_copy))); return z_impl_can_add_rx_filter_msgq(dev, msgq, &filter_copy); } @@ -211,7 +211,7 @@ static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev, static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int filter_id) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, remove_rx_filter)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, remove_rx_filter)); z_impl_can_remove_rx_filter(dev, filter_id); } @@ -220,14 +220,14 @@ static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int fil static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state *state, struct can_bus_err_cnt *err_cnt) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_state)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, get_state)); if (state != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(state, sizeof(*state))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(state, sizeof(*state))); } if (err_cnt != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(*err_cnt))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(*err_cnt))); } return z_impl_can_get_state(dev, state, err_cnt); @@ -237,7 +237,7 @@ static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_DRIVER_CAN(dev, recover)); + K_OOPS(K_SYSCALL_DRIVER_CAN(dev, recover)); return z_impl_can_recover(dev, timeout); } diff --git a/drivers/charger/charger_handlers.c b/drivers/charger/charger_handlers.c index 6f17002aac7..417991f9f5f 100644 --- a/drivers/charger/charger_handlers.c +++ b/drivers/charger/charger_handlers.c @@ -12,11 +12,11 @@ static inline int z_vrfy_charger_get_prop(const struct device *dev, const charge { union charger_propval k_val; - Z_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, get_property)); + K_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, get_property)); int ret = z_impl_charger_get_prop(dev, prop, &k_val); - Z_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union charger_propval))); + K_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union charger_propval))); return ret; } @@ -28,9 +28,9 @@ static inline int z_vrfy_charger_set_prop(const struct device *dev, const charge { union charger_propval k_val; - Z_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, set_property)); + K_OOPS(K_SYSCALL_DRIVER_CHARGER(dev, set_property)); - Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union charger_propval))); + K_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union charger_propval))); return z_impl_charger_set_prop(dev, prop, &k_val); } diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 191d12d49b5..15cd0cb5881 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -13,7 +13,7 @@ #define COUNTER_HANDLER(name) \ static inline int z_vrfy_counter_##name(const struct device *dev) \ { \ - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, name)); \ + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, name)); \ return z_impl_counter_ ## name((const struct device *)dev); \ } @@ -27,21 +27,21 @@ COUNTER_HANDLER(start) static inline bool z_vrfy_counter_is_counting_up(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_is_counting_up((const struct device *)dev); } #include static inline uint8_t z_vrfy_counter_get_num_of_channels(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_num_of_channels((const struct device *)dev); } #include static inline uint32_t z_vrfy_counter_get_frequency(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_frequency((const struct device *)dev); } #include @@ -49,7 +49,7 @@ static inline uint32_t z_vrfy_counter_get_frequency(const struct device *dev) static inline uint32_t z_vrfy_counter_us_to_ticks(const struct device *dev, uint64_t us) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_us_to_ticks((const struct device *)dev, (uint64_t)us); } @@ -58,7 +58,7 @@ static inline uint32_t z_vrfy_counter_us_to_ticks(const struct device *dev, static inline uint64_t z_vrfy_counter_ticks_to_us(const struct device *dev, uint32_t ticks) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_ticks_to_us((const struct device *)dev, (uint32_t)ticks); } @@ -67,16 +67,16 @@ static inline uint64_t z_vrfy_counter_ticks_to_us(const struct device *dev, static inline int z_vrfy_counter_get_value(const struct device *dev, uint32_t *ticks) { - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value((const struct device *)dev, ticks); } static inline int z_vrfy_counter_get_value_64(const struct device *dev, uint64_t *ticks) { - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value_64)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_value_64)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(ticks, sizeof(*ticks))); return z_impl_counter_get_value_64((const struct device *)dev, ticks); } @@ -88,9 +88,9 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, { struct counter_alarm_cfg cfg_copy; - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); - Z_OOPS(k_usermode_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); - Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_alarm)); + K_OOPS(k_usermode_from_copy(&cfg_copy, alarm_cfg, sizeof(cfg_copy))); + K_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_channel_alarm((const struct device *)dev, (uint8_t)chan_id, @@ -102,7 +102,7 @@ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, static inline int z_vrfy_counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id) { - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, cancel_alarm)); + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, cancel_alarm)); return z_impl_counter_cancel_channel_alarm((const struct device *)dev, (uint8_t)chan_id); } @@ -114,9 +114,9 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, { struct counter_top_cfg cfg_copy; - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); - Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); - Z_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, set_top_value)); + K_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(cfg_copy))); + K_OOPS(K_SYSCALL_VERIFY_MSG(cfg_copy.callback == NULL, "callbacks may not be set from user mode")); return z_impl_counter_set_top_value((const struct device *)dev, (const struct counter_top_cfg *) @@ -126,14 +126,14 @@ static inline int z_vrfy_counter_set_top_value(const struct device *dev, static inline uint32_t z_vrfy_counter_get_top_value(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_top_value)); + K_OOPS(K_SYSCALL_DRIVER_COUNTER(dev, get_top_value)); return z_impl_counter_get_top_value((const struct device *)dev); } #include static inline uint32_t z_vrfy_counter_get_max_top_value(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_max_top_value((const struct device *)dev); } #include @@ -141,7 +141,7 @@ static inline uint32_t z_vrfy_counter_get_max_top_value(const struct device *dev static inline uint32_t z_vrfy_counter_get_guard_period(const struct device *dev, uint32_t flags) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_get_guard_period((const struct device *)dev, flags); } @@ -150,7 +150,7 @@ static inline uint32_t z_vrfy_counter_get_guard_period(const struct device *dev, static inline int z_vrfy_counter_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_COUNTER)); return z_impl_counter_set_guard_period((const struct device *)dev, ticks, flags); diff --git a/drivers/counter/maxim_ds3231.c b/drivers/counter/maxim_ds3231.c index 19241a22990..93d20639ecd 100644 --- a/drivers/counter/maxim_ds3231.c +++ b/drivers/counter/maxim_ds3231.c @@ -1308,13 +1308,13 @@ int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, struct maxim_ds3231_syncpoint value; int rv; - Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint))); + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint))); rv = z_impl_maxim_ds3231_get_syncpoint(dev, &value); if (rv >= 0) { - Z_OOPS(k_usermode_to_copy(syncpoint, &value, sizeof(*syncpoint))); + K_OOPS(k_usermode_to_copy(syncpoint, &value, sizeof(*syncpoint))); } return rv; @@ -1325,9 +1325,9 @@ int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev, int z_vrfy_maxim_ds3231_req_syncpoint(const struct device *dev, struct k_poll_signal *sig) { - Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api)); if (sig != NULL) { - Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); } return z_impl_maxim_ds3231_req_syncpoint(dev, sig); diff --git a/drivers/dac/dac_handlers.c b/drivers/dac/dac_handlers.c index c1cc24c3685..bd9ee0bc7e0 100644 --- a/drivers/dac/dac_handlers.c +++ b/drivers/dac/dac_handlers.c @@ -13,8 +13,8 @@ static inline int z_vrfy_dac_channel_setup(const struct device *dev, { struct dac_channel_cfg channel_cfg; - Z_OOPS(K_SYSCALL_DRIVER_DAC(dev, channel_setup)); - Z_OOPS(k_usermode_from_copy(&channel_cfg, + K_OOPS(K_SYSCALL_DRIVER_DAC(dev, channel_setup)); + K_OOPS(k_usermode_from_copy(&channel_cfg, (struct dac_channel_cfg *)user_channel_cfg, sizeof(struct dac_channel_cfg))); @@ -26,7 +26,7 @@ static inline int z_vrfy_dac_channel_setup(const struct device *dev, static inline int z_vrfy_dac_write_value(const struct device *dev, uint8_t channel, uint32_t value) { - Z_OOPS(K_SYSCALL_DRIVER_DAC(dev, write_value)); + K_OOPS(K_SYSCALL_DRIVER_DAC(dev, write_value)); return z_impl_dac_write_value((const struct device *)dev, channel, value); diff --git a/drivers/dma/dma_handlers.c b/drivers/dma/dma_handlers.c index 10c542d8380..d84c1510152 100644 --- a/drivers/dma/dma_handlers.c +++ b/drivers/dma/dma_handlers.c @@ -13,14 +13,14 @@ static inline int z_vrfy_dma_start(const struct device *dev, uint32_t channel) { - Z_OOPS(K_SYSCALL_DRIVER_DMA(dev, start)); + K_OOPS(K_SYSCALL_DRIVER_DMA(dev, start)); return z_impl_dma_start((const struct device *)dev, channel); } #include static inline int z_vrfy_dma_stop(const struct device *dev, uint32_t channel) { - Z_OOPS(K_SYSCALL_DRIVER_DMA(dev, stop)); + K_OOPS(K_SYSCALL_DRIVER_DMA(dev, stop)); return z_impl_dma_stop((const struct device *)dev, channel); } #include diff --git a/drivers/eeprom/eeprom_handlers.c b/drivers/eeprom/eeprom_handlers.c index 7534e67d865..9b1406a6004 100644 --- a/drivers/eeprom/eeprom_handlers.c +++ b/drivers/eeprom/eeprom_handlers.c @@ -10,8 +10,8 @@ static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, read)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); + K_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, read)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_eeprom_read((const struct device *)dev, offset, (void *)data, len); @@ -21,8 +21,8 @@ static inline int z_vrfy_eeprom_read(const struct device *dev, off_t offset, static inline int z_vrfy_eeprom_write(const struct device *dev, off_t offset, const void *data, size_t len) { - Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, write)); - Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); + K_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, write)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_eeprom_write((const struct device *)dev, offset, (const void *)data, len); } @@ -30,7 +30,7 @@ static inline int z_vrfy_eeprom_write(const struct device *dev, off_t offset, static inline size_t z_vrfy_eeprom_get_size(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, size)); + K_OOPS(K_SYSCALL_DRIVER_EEPROM(dev, size)); return z_impl_eeprom_get_size((const struct device *)dev); } #include diff --git a/drivers/entropy/entropy_handlers.c b/drivers/entropy/entropy_handlers.c index 269d3412608..76b7df3d0bd 100644 --- a/drivers/entropy/entropy_handlers.c +++ b/drivers/entropy/entropy_handlers.c @@ -11,8 +11,8 @@ static inline int z_vrfy_entropy_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t len) { - Z_OOPS(K_SYSCALL_DRIVER_ENTROPY(dev, get_entropy)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); + K_OOPS(K_SYSCALL_DRIVER_ENTROPY(dev, get_entropy)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); return z_impl_entropy_get_entropy((const struct device *)dev, (uint8_t *)buffer, len); diff --git a/drivers/espi/espi_handlers.c b/drivers/espi/espi_handlers.c index 1bb023a7a58..c215838fd79 100644 --- a/drivers/espi/espi_handlers.c +++ b/drivers/espi/espi_handlers.c @@ -13,8 +13,8 @@ static inline int z_vrfy_espi_config(const struct device *dev, { struct espi_cfg cfg_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, config)); - Z_OOPS(k_usermode_from_copy(&cfg_copy, cfg, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, config)); + K_OOPS(k_usermode_from_copy(&cfg_copy, cfg, sizeof(struct espi_cfg))); return z_impl_espi_config(dev, &cfg_copy); @@ -24,7 +24,7 @@ static inline int z_vrfy_espi_config(const struct device *dev, static inline bool z_vrfy_espi_get_channel_status(const struct device *dev, enum espi_channel ch) { - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, get_channel_status)); + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, get_channel_status)); return z_impl_espi_get_channel_status(dev, ch); } @@ -37,10 +37,10 @@ static inline int z_vrfy_espi_read_lpc_request(const struct device *dev, int ret; uint32_t data_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_lpc_request)); + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_lpc_request)); ret = z_impl_espi_read_lpc_request(dev, op, &data_copy); - Z_OOPS(k_usermode_to_copy(data, &data_copy, sizeof(uint8_t))); + K_OOPS(k_usermode_to_copy(data, &data_copy, sizeof(uint8_t))); return ret; } @@ -52,8 +52,8 @@ static inline int z_vrfy_espi_write_lpc_request(const struct device *dev, { uint32_t data_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_lpc_request)); - Z_OOPS(k_usermode_from_copy(&data_copy, data, sizeof(*data))); + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_lpc_request)); + K_OOPS(k_usermode_from_copy(&data_copy, data, sizeof(*data))); return z_impl_espi_write_lpc_request(dev, op, &data_copy); } @@ -63,7 +63,7 @@ static inline int z_vrfy_espi_send_vwire(const struct device *dev, enum espi_vwire_signal signal, uint8_t level) { - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_vwire)); + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_vwire)); return z_impl_espi_send_vwire(dev, signal, level); } @@ -76,10 +76,10 @@ static inline int z_vrfy_espi_receive_vwire(const struct device *dev, int ret; uint8_t level_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_vwire)); + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_vwire)); ret = z_impl_espi_receive_vwire(dev, signal, &level_copy); - Z_OOPS(k_usermode_to_copy(level, &level_copy, sizeof(uint8_t))); + K_OOPS(k_usermode_to_copy(level, &level_copy, sizeof(uint8_t))); return ret; } @@ -91,14 +91,14 @@ static inline int z_vrfy_espi_read_request(const struct device *dev, int ret; struct espi_request_packet req_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_request)); - Z_OOPS(k_usermode_from_copy(&req_copy, req, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, read_request)); + K_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(req_copy.data, req_copy.len)); ret = z_impl_espi_read_request(dev, &req_copy); - Z_OOPS(k_usermode_to_copy(req, &req_copy, + K_OOPS(k_usermode_to_copy(req, &req_copy, sizeof(struct espi_request_packet))); return ret; @@ -111,9 +111,9 @@ static inline int z_vrfy_espi_write_request(const struct device *dev, int ret; struct espi_request_packet req_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_request)); - Z_OOPS(K_SYSCALL_MEMORY_READ(req->data, req->len)); - Z_OOPS(k_usermode_from_copy(&req_copy, req, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, write_request)); + K_OOPS(K_SYSCALL_MEMORY_READ(req->data, req->len)); + K_OOPS(k_usermode_from_copy(&req_copy, req, sizeof(struct espi_request_packet))); ret = z_impl_espi_write_request(dev, &req_copy); @@ -128,9 +128,9 @@ static inline int z_vrfy_espi_send_oob(const struct device *dev, int ret; struct espi_oob_packet pckt_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_oob)); - Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); - Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, send_oob)); + K_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + K_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); ret = z_impl_espi_send_oob(dev, &pckt_copy); @@ -145,13 +145,13 @@ static inline int z_vrfy_espi_receive_oob(const struct device *dev, int ret; struct espi_oob_packet pckt_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_oob)); - Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, receive_oob)); + K_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_oob_packet))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_receive_oob(dev, &pckt_copy); - Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, + K_OOPS(k_usermode_to_copy(pckt, &pckt_copy, sizeof(struct espi_oob_packet))); return ret; @@ -164,13 +164,13 @@ static inline int z_vrfy_espi_read_flash(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_read)); - Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_read)); + K_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(pckt->buf, pckt->len)); ret = z_impl_espi_read_flash(dev, pckt); - Z_OOPS(k_usermode_to_copy(pckt, &pckt_copy, + K_OOPS(k_usermode_to_copy(pckt, &pckt_copy, sizeof(struct espi_flash_packet))); return ret; @@ -183,10 +183,10 @@ static inline int z_vrfy_espi_write_flash(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); - Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); + K_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + K_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); ret = z_impl_espi_write_flash(dev, &pckt_copy); @@ -200,10 +200,10 @@ static inline int z_vrfy_espi_flash_erase(const struct device *dev, int ret; struct espi_flash_packet pckt_copy; - Z_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); - Z_OOPS(k_usermode_from_copy(&pckt_copy, pckt, + K_OOPS(K_SYSCALL_DRIVER_ESPI(dev, flash_write)); + K_OOPS(k_usermode_from_copy(&pckt_copy, pckt, sizeof(struct espi_flash_packet))); - Z_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); + K_OOPS(K_SYSCALL_MEMORY_READ(pckt->buf, pckt->len)); ret = z_impl_espi_flash_erase(dev, &pckt_copy); diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index d8b5dc377c3..ac727b109e7 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -10,8 +10,8 @@ static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_read((const struct device *)dev, offset, (void *)data, len); @@ -21,8 +21,8 @@ static inline int z_vrfy_flash_read(const struct device *dev, off_t offset, static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, const void *data, size_t len) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, write)); - Z_OOPS(K_SYSCALL_MEMORY_READ(data, len)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, write)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, len)); return z_impl_flash_write((const struct device *)dev, offset, (const void *)data, len); } @@ -31,21 +31,21 @@ static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, static inline int z_vrfy_flash_erase(const struct device *dev, off_t offset, size_t size) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, erase)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, erase)); return z_impl_flash_erase((const struct device *)dev, offset, size); } #include static inline size_t z_vrfy_flash_get_write_block_size(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); return z_impl_flash_get_write_block_size(dev); } #include static inline const struct flash_parameters *z_vrfy_flash_get_parameters(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, get_parameters)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, get_parameters)); return z_impl_flash_get_parameters(dev); } #include @@ -55,8 +55,8 @@ static inline int z_vrfy_flash_get_page_info_by_offs(const struct device *dev, off_t offs, struct flash_pages_info *info) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_offs((const struct device *)dev, offs, (struct flash_pages_info *)info); @@ -67,8 +67,8 @@ static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev, uint32_t idx, struct flash_pages_info *info) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info))); return z_impl_flash_get_page_info_by_idx((const struct device *)dev, idx, (struct flash_pages_info *)info); @@ -77,7 +77,7 @@ static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev, static inline size_t z_vrfy_flash_get_page_count(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, page_layout)); return z_impl_flash_get_page_count((const struct device *)dev); } #include @@ -90,8 +90,8 @@ static inline int z_vrfy_flash_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, sfdp_read)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, sfdp_read)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); return z_impl_flash_sfdp_read(dev, offset, data, len); } #include @@ -99,8 +99,8 @@ static inline int z_vrfy_flash_sfdp_read(const struct device *dev, static inline int z_vrfy_flash_read_jedec_id(const struct device *dev, uint8_t *id) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read_jedec_id)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(id, 3)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, read_jedec_id)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(id, 3)); return z_impl_flash_read_jedec_id(dev, id); } #include @@ -112,7 +112,7 @@ static inline int z_vrfy_flash_read_jedec_id(const struct device *dev, static inline int z_vrfy_flash_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out) { - Z_OOPS(K_SYSCALL_DRIVER_FLASH(dev, ex_op)); + K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, ex_op)); /* * If the code is a vendor code, then ex_op function have to perform diff --git a/drivers/flash/flash_npcx_fiu_nor.c b/drivers/flash/flash_npcx_fiu_nor.c index 4fcac59c027..e42aa82f896 100644 --- a/drivers/flash/flash_npcx_fiu_nor.c +++ b/drivers/flash/flash_npcx_fiu_nor.c @@ -453,7 +453,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, struct npcx_ex_ops_uma_out out_copy; if (syscall_trap) { - Z_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); + K_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); op_in = &in_copy; op_out = &out_copy; } @@ -462,7 +462,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, ret = flash_npcx_nor_ex_exec_uma(dev, op_in, op_out); #ifdef CONFIG_USERSPACE if (ret == 0 && syscall_trap) { - Z_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); + K_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); } #endif break; @@ -474,7 +474,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, struct npcx_ex_ops_qspi_oper_in in_copy; if (syscall_trap) { - Z_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); + K_OOPS(k_usermode_from_copy(&in_copy, op_in, sizeof(in_copy))); op_in = &in_copy; } #endif @@ -495,7 +495,7 @@ static int flash_npcx_nor_ex_op(const struct device *dev, uint16_t code, ret = flash_npcx_nor_ex_get_spi_spec(dev, op_out); #ifdef CONFIG_USERSPACE if (ret == 0 && syscall_trap) { - Z_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); + K_OOPS(k_usermode_to_copy(out, op_out, sizeof(out_copy))); } #endif break; diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index f06f0e69750..ccbc28edfe4 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -486,7 +486,7 @@ void *z_impl_flash_simulator_get_memory(const struct device *dev, void *z_vrfy_flash_simulator_get_memory(const struct device *dev, size_t *mock_size) { - Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); return z_impl_flash_simulator_get_memory(dev, mock_size); } diff --git a/drivers/flash/flash_stm32_ex_op.c b/drivers/flash/flash_stm32_ex_op.c index 02e5d11279d..623d4e23d6d 100644 --- a/drivers/flash/flash_stm32_ex_op.c +++ b/drivers/flash/flash_stm32_ex_op.c @@ -36,7 +36,7 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, struct flash_stm32_ex_op_sector_wp_in in_copy; if (syscall_trap) { - Z_OOPS(k_usermode_from_copy(&in_copy, request, + K_OOPS(k_usermode_from_copy(&in_copy, request, sizeof(in_copy))); request = &in_copy; } @@ -75,7 +75,7 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(k_usermode_to_copy(out, result, sizeof(out_copy))); + K_OOPS(k_usermode_to_copy(out, result, sizeof(out_copy))); } #endif } @@ -102,7 +102,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, if (request != NULL) { #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(k_usermode_from_copy(©, request, sizeof(copy))); + K_OOPS(k_usermode_from_copy(©, request, sizeof(copy))); request = © } #endif @@ -132,7 +132,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, #ifdef CONFIG_USERSPACE if (syscall_trap) { - Z_OOPS(k_usermode_to_copy(out, result, sizeof(copy))); + K_OOPS(k_usermode_to_copy(out, result, sizeof(copy))); } #endif } diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 0540ef2360a..6dd305e9430 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1468,7 +1468,7 @@ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { - Z_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &qspi_nor_api)); z_impl_nrf_qspi_nor_xip_enable(dev, enable); diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 5fe1e45a35a..312564c35a6 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -13,13 +13,13 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gaug { union fuel_gauge_prop_val k_val; - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val))); int ret = z_impl_fuel_gauge_get_prop(dev, prop, &k_val); - Z_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val))); return ret; } @@ -32,14 +32,14 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau union fuel_gauge_prop_val k_vals[len]; fuel_gauge_prop_t k_props[len]; - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); - Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); - Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); + K_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); int ret = z_impl_fuel_gauge_get_props(dev, k_props, k_vals, len); - Z_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } @@ -49,7 +49,7 @@ static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gau static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, union fuel_gauge_prop_val val) { - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); int ret = z_impl_fuel_gauge_set_prop(dev, prop, val); @@ -64,15 +64,15 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gau union fuel_gauge_prop_val k_vals[len]; fuel_gauge_prop_t k_props[len]; - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); - Z_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); - Z_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); + K_OOPS(k_usermode_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t))); int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len); /* We only copy back vals because props will never be modified */ - Z_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); + K_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); return ret; } @@ -83,9 +83,9 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, fuel_gauge_prop_t prop, void *dst, size_t dst_len) { - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, dst_len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, dst_len)); int ret = z_impl_fuel_gauge_get_buffer_prop(dev, prop, dst, dst_len); @@ -96,7 +96,7 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, static inline int z_vrfy_fuel_gauge_battery_cutoff(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, battery_cutoff)); + K_OOPS(K_SYSCALL_DRIVER_FUEL_GAUGE(dev, battery_cutoff)); return z_impl_fuel_gauge_battery_cutoff(dev); } diff --git a/drivers/gpio/gpio_handlers.c b/drivers/gpio/gpio_handlers.c index 57cec40c56e..99fbc6f45d9 100644 --- a/drivers/gpio/gpio_handlers.c +++ b/drivers/gpio/gpio_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_gpio_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_configure)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_configure)); return z_impl_gpio_pin_configure((const struct device *)port, pin, flags); @@ -23,8 +23,8 @@ static inline int z_vrfy_gpio_pin_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_get_config)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(flags, sizeof(gpio_flags_t))); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_get_config)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(flags, sizeof(gpio_flags_t))); return z_impl_gpio_pin_get_config(port, pin, flags); } @@ -34,8 +34,8 @@ static inline int z_vrfy_gpio_pin_get_config(const struct device *port, static inline int z_vrfy_gpio_port_get_raw(const struct device *port, gpio_port_value_t *value) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_get_raw)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(gpio_port_value_t))); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_get_raw)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(gpio_port_value_t))); return z_impl_gpio_port_get_raw((const struct device *)port, (gpio_port_value_t *)value); } @@ -45,7 +45,7 @@ static inline int z_vrfy_gpio_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, gpio_port_value_t value) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_masked_raw)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_masked_raw)); return z_impl_gpio_port_set_masked_raw((const struct device *)port, mask, value); @@ -55,7 +55,7 @@ static inline int z_vrfy_gpio_port_set_masked_raw(const struct device *port, static inline int z_vrfy_gpio_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_bits_raw)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_set_bits_raw)); return z_impl_gpio_port_set_bits_raw((const struct device *)port, pins); } @@ -64,7 +64,7 @@ static inline int z_vrfy_gpio_port_set_bits_raw(const struct device *port, static inline int z_vrfy_gpio_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_clear_bits_raw)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_clear_bits_raw)); return z_impl_gpio_port_clear_bits_raw((const struct device *)port, pins); } @@ -73,7 +73,7 @@ static inline int z_vrfy_gpio_port_clear_bits_raw(const struct device *port, static inline int z_vrfy_gpio_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_toggle_bits)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, port_toggle_bits)); return z_impl_gpio_port_toggle_bits((const struct device *)port, pins); } #include @@ -82,7 +82,7 @@ static inline int z_vrfy_gpio_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_interrupt_configure)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(port, pin_interrupt_configure)); return z_impl_gpio_pin_interrupt_configure((const struct device *)port, pin, flags); @@ -91,7 +91,7 @@ static inline int z_vrfy_gpio_pin_interrupt_configure(const struct device *port, static inline int z_vrfy_gpio_get_pending_int(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(dev, get_pending_int)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(dev, get_pending_int)); return z_impl_gpio_get_pending_int((const struct device *)dev); } @@ -102,14 +102,14 @@ static inline int z_vrfy_gpio_port_get_direction(const struct device *dev, gpio_ gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) { - Z_OOPS(K_SYSCALL_DRIVER_GPIO(dev, port_get_direction)); + K_OOPS(K_SYSCALL_DRIVER_GPIO(dev, port_get_direction)); if (inputs != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(inputs, sizeof(gpio_port_pins_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(inputs, sizeof(gpio_port_pins_t))); } if (outputs != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(outputs, sizeof(gpio_port_pins_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(outputs, sizeof(gpio_port_pins_t))); } return z_impl_gpio_port_get_direction(dev, map, inputs, outputs); diff --git a/drivers/hwinfo/hwinfo_handlers.c b/drivers/hwinfo/hwinfo_handlers.c index b9727bd4ab7..02058f9b955 100644 --- a/drivers/hwinfo/hwinfo_handlers.c +++ b/drivers/hwinfo/hwinfo_handlers.c @@ -9,7 +9,7 @@ ssize_t z_vrfy_hwinfo_get_device_id(uint8_t *buffer, size_t length) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, length)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, length)); return z_impl_hwinfo_get_device_id((uint8_t *)buffer, (size_t)length); } @@ -21,7 +21,7 @@ int z_vrfy_hwinfo_get_reset_cause(uint32_t *cause) uint32_t cause_copy; ret = z_impl_hwinfo_get_reset_cause(&cause_copy); - Z_OOPS(k_usermode_to_copy(cause, &cause_copy, sizeof(uint32_t))); + K_OOPS(k_usermode_to_copy(cause, &cause_copy, sizeof(uint32_t))); return ret; } @@ -40,7 +40,7 @@ int z_vrfy_hwinfo_get_supported_reset_cause(uint32_t *supported) uint32_t supported_copy; ret = z_impl_hwinfo_get_supported_reset_cause(&supported_copy); - Z_OOPS(k_usermode_to_copy(supported, &supported_copy, sizeof(uint32_t))); + K_OOPS(k_usermode_to_copy(supported, &supported_copy, sizeof(uint32_t))); return ret; } diff --git a/drivers/hwspinlock/hwspinlock_handlers.c b/drivers/hwspinlock/hwspinlock_handlers.c index 9b7726d09cf..7064293be4b 100644 --- a/drivers/hwspinlock/hwspinlock_handlers.c +++ b/drivers/hwspinlock/hwspinlock_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_hwspinlock_trylock(const struct device *dev, uint32_t id) { - Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, trylock)); + K_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, trylock)); return z_impl_hwspinlock_trylock(dev, id); } @@ -17,7 +17,7 @@ static inline int z_vrfy_hwspinlock_trylock(const struct device *dev, uint32_t i static inline void z_vrfy_hwspinlock_lock(const struct device *dev, uint32_t id) { - Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, lock)); + K_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, lock)); z_impl_hwspinlock_lock(dev, id); } @@ -25,7 +25,7 @@ static inline void z_vrfy_hwspinlock_lock(const struct device *dev, uint32_t id) static inline void z_vrfy_hwspinlock_unlock(const struct device *dev, uint32_t id) { - Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, unlock)); + K_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, unlock)); z_impl_hwspinlock_unlock(dev, id); } @@ -33,7 +33,7 @@ static inline void z_vrfy_hwspinlock_unlock(const struct device *dev, uint32_t i static inline uint32_t z_vrfy_hwspinlock_get_max_id(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, get_max_id)); + K_OOPS(K_SYSCALL_DRIVER_HWSPINLOCK(dev, get_max_id)); return z_impl_hwspinlock_get_max_id(dev); } diff --git a/drivers/i2c/i2c_handlers.c b/drivers/i2c/i2c_handlers.c index 99c3e60fa72..20ec2a6f578 100644 --- a/drivers/i2c/i2c_handlers.c +++ b/drivers/i2c/i2c_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_i2c_configure(const struct device *dev, uint32_t dev_config) { - Z_OOPS(K_SYSCALL_DRIVER_I2C(dev, configure)); + K_OOPS(K_SYSCALL_DRIVER_I2C(dev, configure)); return z_impl_i2c_configure((const struct device *)dev, dev_config); } #include @@ -19,8 +19,8 @@ static inline int z_vrfy_i2c_configure(const struct device *dev, static inline int z_vrfy_i2c_get_config(const struct device *dev, uint32_t *dev_config) { - Z_OOPS(K_SYSCALL_DRIVER_I2C(dev, get_config)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); + K_OOPS(K_SYSCALL_DRIVER_I2C(dev, get_config)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_i2c_get_config(dev, dev_config); } @@ -41,7 +41,7 @@ static uint32_t copy_msgs_and_transfer(const struct device *dev, * that the target buffer be writable */ for (i = 0U; i < num_msgs; i++) { - Z_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, + K_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, copy[i].flags & I2C_MSG_READ)); } @@ -52,17 +52,17 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); /* copy_msgs_and_transfer() will allocate a copy on the stack using * VLA, so ensure this won't blow the stack. Most functions defined * in i2c.h use only a handful of messages, so up to 32 messages * should be more than sufficient. */ - Z_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); + K_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, sizeof(struct i2c_msg))); return copy_msgs_and_transfer((const struct device *)dev, @@ -73,21 +73,21 @@ static inline int z_vrfy_i2c_transfer(const struct device *dev, static inline int z_vrfy_i2c_target_driver_register(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_target_driver_register(dev); } #include static inline int z_vrfy_i2c_target_driver_unregister(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_target_driver_unregister(dev); } #include static inline int z_vrfy_i2c_recover_bus(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C)); return z_impl_i2c_recover_bus(dev); } #include diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 0f5c0db8f48..0ef1f6e6cd5 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -20,7 +20,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, goto out; } - Z_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr, + K_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr, sizeof(struct i2s_config))); /* Check that the k_mem_slab provided is a valid pointer and that @@ -50,7 +50,7 @@ static inline int z_vrfy_i2s_buf_read(const struct device *dev, size_t data_size; int ret; - Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, read)); + K_OOPS(K_SYSCALL_DRIVER_I2S(dev, read)); ret = i2s_read((const struct device *)dev, &mem_block, &data_size); @@ -67,8 +67,8 @@ static inline int z_vrfy_i2s_buf_read(const struct device *dev, data_size); k_mem_slab_free(rx_cfg->mem_slab, mem_block); - Z_OOPS(copy_success); - Z_OOPS(k_usermode_to_copy((void *)size, &data_size, + K_OOPS(copy_success); + K_OOPS(k_usermode_to_copy((void *)size, &data_size, sizeof(data_size))); } @@ -83,7 +83,7 @@ static inline int z_vrfy_i2s_buf_write(const struct device *dev, const struct i2s_config *tx_cfg; void *mem_block; - Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, write)); + K_OOPS(K_SYSCALL_DRIVER_I2S(dev, write)); tx_cfg = i2s_config_get((const struct device *)dev, I2S_DIR_TX); if (!tx_cfg) { return -EIO; @@ -101,7 +101,7 @@ static inline int z_vrfy_i2s_buf_write(const struct device *dev, ret = k_usermode_from_copy(mem_block, (void *)buf, size); if (ret) { k_mem_slab_free(tx_cfg->mem_slab, mem_block); - Z_OOPS(ret); + K_OOPS(ret); } ret = i2s_write((const struct device *)dev, mem_block, size); @@ -117,7 +117,7 @@ static inline int z_vrfy_i2s_trigger(const struct device *dev, enum i2s_dir dir, enum i2s_trigger_cmd cmd) { - Z_OOPS(K_SYSCALL_DRIVER_I2S(dev, trigger)); + K_OOPS(K_SYSCALL_DRIVER_I2S(dev, trigger)); return z_impl_i2s_trigger((const struct device *)dev, dir, cmd); } diff --git a/drivers/i3c/i3c_handlers.c b/drivers/i3c/i3c_handlers.c index b9aaaa7191f..a5d218992a3 100644 --- a/drivers/i3c/i3c_handlers.c +++ b/drivers/i3c/i3c_handlers.c @@ -11,24 +11,24 @@ static inline int z_vrfy_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) { - Z_OOPS(K_SYSCALL_DRIVER_I3C(dev, do_ccc)); - Z_OOPS(K_SYSCALL_MEMORY_READ(payload, sizeof(*payload))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); + K_OOPS(K_SYSCALL_DRIVER_I3C(dev, do_ccc)); + K_OOPS(K_SYSCALL_MEMORY_READ(payload, sizeof(*payload))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(payload, sizeof(*payload))); if (payload->ccc.data != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->ccc.data, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->ccc.data, payload->ccc.data_len, sizeof(*payload->ccc.data))); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->ccc.data, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->ccc.data, payload->ccc.data_len, sizeof(*payload->ccc.data))); } if (payload->targets.payloads != NULL) { - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->targets.payloads, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(payload->targets.payloads, payload->targets.num_targets, sizeof(*payload->targets.payloads))); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->targets.payloads, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(payload->targets.payloads, payload->targets.num_targets, sizeof(*payload->targets.payloads))); } @@ -51,7 +51,7 @@ static uint32_t copy_i3c_msgs_and_transfer(struct i3c_device_desc *target, * that the target buffer be writable */ for (i = 0U; i < num_msgs; i++) { - Z_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, + K_OOPS(K_SYSCALL_MEMORY(copy[i].buf, copy[i].len, copy[i].flags & I3C_MSG_READ)); } @@ -61,18 +61,18 @@ static uint32_t copy_i3c_msgs_and_transfer(struct i3c_device_desc *target, static inline int z_vrfy_i3c_transfer(struct i3c_device_desc *target, struct i3c_msg *msgs, uint8_t num_msgs) { - Z_OOPS(K_SYSCALL_MEMORY_READ(target, sizeof(*target))); - Z_OOPS(K_SYSCALL_OBJ(target->bus, K_OBJ_DRIVER_I3C)); + K_OOPS(K_SYSCALL_MEMORY_READ(target, sizeof(*target))); + K_OOPS(K_SYSCALL_OBJ(target->bus, K_OBJ_DRIVER_I3C)); /* copy_msgs_and_transfer() will allocate a copy on the stack using * VLA, so ensure this won't blow the stack. Most functions defined * in i2c.h use only a handful of messages, so up to 32 messages * should be more than sufficient. */ - Z_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); + K_OOPS(K_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32)); /* We need to be able to read the overall array of messages */ - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, sizeof(struct i3c_msg))); return copy_i3c_msgs_and_transfer((struct i3c_device_desc *)target, diff --git a/drivers/ipm/ipm_handlers.c b/drivers/ipm/ipm_handlers.c index ef139c67338..259644ae8d0 100644 --- a/drivers/ipm/ipm_handlers.c +++ b/drivers/ipm/ipm_handlers.c @@ -11,8 +11,8 @@ static inline int z_vrfy_ipm_send(const struct device *dev, int wait, uint32_t id, const void *data, int size) { - Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, send)); - Z_OOPS(K_SYSCALL_MEMORY_READ(data, size)); + K_OOPS(K_SYSCALL_DRIVER_IPM(dev, send)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, size)); return z_impl_ipm_send((const struct device *)dev, wait, id, (const void *)data, size); } @@ -20,21 +20,21 @@ static inline int z_vrfy_ipm_send(const struct device *dev, int wait, static inline int z_vrfy_ipm_max_data_size_get(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_data_size_get)); + K_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_data_size_get)); return z_impl_ipm_max_data_size_get((const struct device *)dev); } #include static inline uint32_t z_vrfy_ipm_max_id_val_get(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_id_val_get)); + K_OOPS(K_SYSCALL_DRIVER_IPM(dev, max_id_val_get)); return z_impl_ipm_max_id_val_get((const struct device *)dev); } #include static inline int z_vrfy_ipm_set_enabled(const struct device *dev, int enable) { - Z_OOPS(K_SYSCALL_DRIVER_IPM(dev, set_enabled)); + K_OOPS(K_SYSCALL_DRIVER_IPM(dev, set_enabled)); return z_impl_ipm_set_enabled((const struct device *)dev, enable); } #include diff --git a/drivers/kscan/kscan_handlers.c b/drivers/kscan/kscan_handlers.c index d62cfbb603e..98809687430 100644 --- a/drivers/kscan/kscan_handlers.c +++ b/drivers/kscan/kscan_handlers.c @@ -10,8 +10,8 @@ static inline int z_vrfy_kscan_config(const struct device *dev, kscan_callback_t callback_isr) { - Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, config)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == 0, + K_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, config)); + K_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == 0, "callback cannot be set from user mode")); return z_impl_kscan_config((const struct device *)dev, callback_isr); } @@ -19,7 +19,7 @@ static inline int z_vrfy_kscan_config(const struct device *dev, static inline int z_vrfy_kscan_disable_callback(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, disable_callback)); + K_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, disable_callback)); return z_impl_kscan_disable_callback((const struct device *)dev); } @@ -27,7 +27,7 @@ static inline int z_vrfy_kscan_disable_callback(const struct device *dev) static int z_vrfy_kscan_enable_callback(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, enable_callback)); + K_OOPS(K_SYSCALL_DRIVER_KSCAN(dev, enable_callback)); return z_impl_kscan_enable_callback((const struct device *)dev); } diff --git a/drivers/led/led_handlers.c b/drivers/led/led_handlers.c index 223c673c4a6..a089846e695 100644 --- a/drivers/led/led_handlers.c +++ b/drivers/led/led_handlers.c @@ -10,7 +10,7 @@ static inline int z_vrfy_led_blink(const struct device *dev, uint32_t led, uint32_t delay_on, uint32_t delay_off) { - Z_OOPS(K_SYSCALL_DRIVER_LED(dev, blink)); + K_OOPS(K_SYSCALL_DRIVER_LED(dev, blink)); return z_impl_led_blink((const struct device *)dev, led, delay_on, delay_off); } @@ -19,8 +19,8 @@ static inline int z_vrfy_led_blink(const struct device *dev, uint32_t led, static inline int z_vrfy_led_get_info(const struct device *dev, uint32_t led, const struct led_info **info) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(*info))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(info, sizeof(*info))); return z_impl_led_get_info(dev, led, info); } #include @@ -29,7 +29,7 @@ static inline int z_vrfy_led_set_brightness(const struct device *dev, uint32_t led, uint8_t value) { - Z_OOPS(K_SYSCALL_DRIVER_LED(dev, set_brightness)); + K_OOPS(K_SYSCALL_DRIVER_LED(dev, set_brightness)); return z_impl_led_set_brightness((const struct device *)dev, led, value); } @@ -39,8 +39,8 @@ static inline int z_vrfy_led_write_channels(const struct device *dev, uint32_t start_channel, uint32_t num_channels, const uint8_t *buf) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, num_channels)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, num_channels)); return z_impl_led_write_channels(dev, start_channel, num_channels, buf); } #include @@ -48,7 +48,7 @@ z_vrfy_led_write_channels(const struct device *dev, uint32_t start_channel, static inline int z_vrfy_led_set_channel(const struct device *dev, uint32_t channel, uint8_t value) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); return z_impl_led_set_channel(dev, channel, value); } #include @@ -56,22 +56,22 @@ static inline int z_vrfy_led_set_channel(const struct device *dev, static inline int z_vrfy_led_set_color(const struct device *dev, uint32_t led, uint8_t num_colors, const uint8_t *color) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); - Z_OOPS(K_SYSCALL_MEMORY_READ(color, num_colors)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_LED)); + K_OOPS(K_SYSCALL_MEMORY_READ(color, num_colors)); return z_impl_led_set_color(dev, led, num_colors, color); } #include static inline int z_vrfy_led_on(const struct device *dev, uint32_t led) { - Z_OOPS(K_SYSCALL_DRIVER_LED(dev, on)); + K_OOPS(K_SYSCALL_DRIVER_LED(dev, on)); return z_impl_led_on((const struct device *)dev, led); } #include static inline int z_vrfy_led_off(const struct device *dev, uint32_t led) { - Z_OOPS(K_SYSCALL_DRIVER_LED(dev, off)); + K_OOPS(K_SYSCALL_DRIVER_LED(dev, off)); return z_impl_led_off((const struct device *)dev, led); } #include diff --git a/drivers/mbox/mbox_handlers.c b/drivers/mbox/mbox_handlers.c index 4b2c84997ec..c4e43f74fe5 100644 --- a/drivers/mbox/mbox_handlers.c +++ b/drivers/mbox/mbox_handlers.c @@ -10,10 +10,10 @@ static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, const struct mbox_msg *msg) { - Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); - Z_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, send)); - Z_OOPS(K_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg))); - Z_OOPS(K_SYSCALL_MEMORY_READ(msg->data, msg->size)); + K_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); + K_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, send)); + K_OOPS(K_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg))); + K_OOPS(K_SYSCALL_MEMORY_READ(msg->data, msg->size)); return z_impl_mbox_send(channel, msg); } @@ -21,7 +21,7 @@ static inline int z_vrfy_mbox_send(const struct mbox_channel *channel, static inline int z_vrfy_mbox_mtu_get(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_MBOX(dev, mtu_get)); + K_OOPS(K_SYSCALL_DRIVER_MBOX(dev, mtu_get)); return z_impl_mbox_mtu_get(dev); } @@ -29,7 +29,7 @@ static inline int z_vrfy_mbox_mtu_get(const struct device *dev) static inline uint32_t z_vrfy_mbox_max_channels_get(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_MBOX(dev, max_channels_get)); + K_OOPS(K_SYSCALL_DRIVER_MBOX(dev, max_channels_get)); return z_impl_mbox_max_channels_get(dev); } @@ -37,8 +37,8 @@ static inline uint32_t z_vrfy_mbox_max_channels_get(const struct device *dev) static inline int z_vrfy_mbox_set_enabled(const struct mbox_channel *channel, bool enable) { - Z_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); - Z_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, set_enabled)); + K_OOPS(K_SYSCALL_MEMORY_READ(channel, sizeof(struct mbox_channel))); + K_OOPS(K_SYSCALL_DRIVER_MBOX(channel->dev, set_enabled)); return z_impl_mbox_set_enabled(channel, enable); } diff --git a/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c b/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c index e65dcb2a62c..1904db4218d 100644 --- a/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c +++ b/drivers/misc/timeaware_gpio/timeaware_gpio_handlers.c @@ -8,8 +8,8 @@ static inline int z_vrfy_tgpio_port_get_time(const struct device *port, uint64_t *current_time) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, get_time)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(current_time, sizeof(uint64_t))); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, get_time)); + K_OOPS(Z_SYSCALL_MEMORY_WRITE(current_time, sizeof(uint64_t))); return z_impl_tgpio_port_get_time((const struct device *)port, (uint64_t *)current_time); } #include @@ -17,8 +17,8 @@ static inline int z_vrfy_tgpio_port_get_time(const struct device *port, uint64_t static inline int z_vrfy_tgpio_port_get_cycles_per_second(const struct device *port, uint32_t *cycles) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, cyc_per_sec)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint32_t))); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, cyc_per_sec)); + K_OOPS(Z_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint32_t))); return z_impl_tgpio_port_get_cycles_per_second((const struct device *)port, (uint32_t *)cycles); } @@ -28,7 +28,7 @@ static inline int z_vrfy_tgpio_pin_periodic_output(const struct device *port, ui uint64_t start_time, uint64_t repeat_interval, bool periodic_enable) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, set_perout)); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, set_perout)); return z_impl_tgpio_pin_periodic_output((const struct device *)port, pin, start_time, repeat_interval, periodic_enable); } @@ -36,7 +36,7 @@ static inline int z_vrfy_tgpio_pin_periodic_output(const struct device *port, ui static inline int z_vrfy_tgpio_pin_disable(const struct device *port, uint32_t pin) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, pin_disable)); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, pin_disable)); return z_impl_tgpio_pin_disable((const struct device *)port, pin); } #include @@ -44,7 +44,7 @@ static inline int z_vrfy_tgpio_pin_disable(const struct device *port, uint32_t p static inline int z_vrfy_tgpio_pin_config_ext_timestamp(const struct device *port, uint32_t pin, uint32_t event_polarity) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, config_ext_ts)); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, config_ext_ts)); return z_impl_tgpio_pin_config_ext_timestamp((const struct device *)port, pin, event_polarity); } @@ -53,7 +53,7 @@ static inline int z_vrfy_tgpio_pin_config_ext_timestamp(const struct device *por static inline int z_vrfy_tgpio_pin_read_ts_ec(const struct device *port, uint32_t pin, uint64_t *timestamp, uint64_t *event_count) { - Z_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, read_ts_ec)); + K_OOPS(Z_SYSCALL_DRIVER_TGPIO(port, read_ts_ec)); return z_impl_tgpio_pin_read_ts_ec((const struct device *)port, pin, (uint64_t *)timestamp, (uint64_t *)event_count); } diff --git a/drivers/peci/peci_handlers.c b/drivers/peci/peci_handlers.c index 6f695e9b72d..64947a8743d 100644 --- a/drivers/peci/peci_handlers.c +++ b/drivers/peci/peci_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_peci_config(const struct device *dev, uint32_t bitrate) { - Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, config)); + K_OOPS(K_SYSCALL_DRIVER_PECI(dev, config)); return z_impl_peci_config(dev, bitrate); } @@ -19,7 +19,7 @@ static inline int z_vrfy_peci_config(const struct device *dev, static inline int z_vrfy_peci_enable(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, enable)); + K_OOPS(K_SYSCALL_DRIVER_PECI(dev, enable)); return z_impl_peci_enable(dev); } @@ -27,7 +27,7 @@ static inline int z_vrfy_peci_enable(const struct device *dev) static inline int z_vrfy_peci_disable(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, disable)); + K_OOPS(K_SYSCALL_DRIVER_PECI(dev, disable)); return z_impl_peci_disable(dev); } @@ -38,8 +38,8 @@ static inline int z_vrfy_peci_transfer(const struct device *dev, { struct peci_msg msg_copy; - Z_OOPS(K_SYSCALL_DRIVER_PECI(dev, transfer)); - Z_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(*msg))); + K_OOPS(K_SYSCALL_DRIVER_PECI(dev, transfer)); + K_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(*msg))); return z_impl_peci_transfer(dev, &msg_copy); } diff --git a/drivers/ps2/ps2_handlers.c b/drivers/ps2/ps2_handlers.c index f02365774bf..91835e85ea5 100644 --- a/drivers/ps2/ps2_handlers.c +++ b/drivers/ps2/ps2_handlers.c @@ -10,8 +10,8 @@ static inline int z_vrfy_ps2_config(const struct device *dev, ps2_callback_t callback_isr) { - Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, config)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == NULL, + K_OOPS(K_SYSCALL_DRIVER_PS2(dev, config)); + K_OOPS(K_SYSCALL_VERIFY_MSG(callback_isr == NULL, "callback not be set from user mode")); return z_impl_ps2_config(dev, callback_isr); } @@ -19,29 +19,29 @@ static inline int z_vrfy_ps2_config(const struct device *dev, static inline int z_vrfy_ps2_write(const struct device *dev, uint8_t value) { - Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, write)); + K_OOPS(K_SYSCALL_DRIVER_PS2(dev, write)); return z_impl_ps2_write(dev, value); } #include static inline int z_vrfy_ps2_read(const struct device *dev, uint8_t *value) { - Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, read)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(uint8_t))); + K_OOPS(K_SYSCALL_DRIVER_PS2(dev, read)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(value, sizeof(uint8_t))); return z_impl_ps2_read(dev, value); } #include static inline int z_vrfy_ps2_enable_callback(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, enable_callback)); + K_OOPS(K_SYSCALL_DRIVER_PS2(dev, enable_callback)); return z_impl_ps2_enable_callback(dev); } #include static inline int z_vrfy_ps2_disable_callback(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_PS2(dev, disable_callback)); + K_OOPS(K_SYSCALL_DRIVER_PS2(dev, disable_callback)); return z_impl_ps2_disable_callback(dev); } #include diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c index fe105c5a21a..0ac0e5c242f 100644 --- a/drivers/ptp_clock/ptp_clock.c +++ b/drivers/ptp_clock/ptp_clock.c @@ -14,8 +14,8 @@ int z_vrfy_ptp_clock_get(const struct device *dev, struct net_ptp_time ptp_time; int ret; - Z_OOPS(K_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); + K_OOPS(K_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); ret = z_impl_ptp_clock_get((const struct device *)dev, &ptp_time); if (ret != 0) { diff --git a/drivers/pwm/pwm_handlers.c b/drivers/pwm/pwm_handlers.c index 01c3c1dca8f..3ffaaa61e46 100644 --- a/drivers/pwm/pwm_handlers.c +++ b/drivers/pwm/pwm_handlers.c @@ -12,7 +12,7 @@ static inline int z_vrfy_pwm_set_cycles(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, pwm_flags_t flags) { - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, set_cycles)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, set_cycles)); return z_impl_pwm_set_cycles((const struct device *)dev, channel, period, pulse, flags); } @@ -22,8 +22,8 @@ static inline int z_vrfy_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles) { - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint64_t))); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(cycles, sizeof(uint64_t))); return z_impl_pwm_get_cycles_per_sec((const struct device *)dev, channel, (uint64_t *)cycles); } @@ -34,7 +34,7 @@ static inline int z_vrfy_pwm_get_cycles_per_sec(const struct device *dev, static inline int z_vrfy_pwm_enable_capture(const struct device *dev, uint32_t channel) { - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); return z_impl_pwm_enable_capture((const struct device *)dev, channel); } #include @@ -42,7 +42,7 @@ static inline int z_vrfy_pwm_enable_capture(const struct device *dev, static inline int z_vrfy_pwm_disable_capture(const struct device *dev, uint32_t channel) { - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); return z_impl_pwm_disable_capture((const struct device *)dev, channel); } #include @@ -57,19 +57,19 @@ static inline int z_vrfy_pwm_capture_cycles(const struct device *dev, uint32_t pulse; int err; - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, configure_capture)); - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); - Z_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, configure_capture)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, enable_capture)); + K_OOPS(K_SYSCALL_DRIVER_PWM(dev, disable_capture)); err = z_impl_pwm_capture_cycles((const struct device *)dev, channel, flags, &period, &pulse, timeout); if (period_cycles != NULL) { - Z_OOPS(k_usermode_to_copy(period_cycles, &period, + K_OOPS(k_usermode_to_copy(period_cycles, &period, sizeof(*period_cycles))); } if (pulse_cycles != NULL) { - Z_OOPS(k_usermode_to_copy(pulse_cycles, &pulse, + K_OOPS(k_usermode_to_copy(pulse_cycles, &pulse, sizeof(*pulse_cycles))); } diff --git a/drivers/retained_mem/retained_mem_handlers.c b/drivers/retained_mem/retained_mem_handlers.c index 4189bbacf3e..d344e37b42c 100644 --- a/drivers/retained_mem/retained_mem_handlers.c +++ b/drivers/retained_mem/retained_mem_handlers.c @@ -9,7 +9,7 @@ static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); return z_impl_retained_mem_size(dev); } #include @@ -17,8 +17,8 @@ static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev) static inline int z_vrfy_retained_mem_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, size)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, size)); return z_impl_retained_mem_read(dev, offset, buffer, size); } #include @@ -26,15 +26,15 @@ static inline int z_vrfy_retained_mem_read(const struct device *dev, off_t offse static inline int z_vrfy_retained_mem_write(const struct device *dev, off_t offset, const uint8_t *buffer, size_t size) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); - Z_OOPS(K_SYSCALL_MEMORY_READ(buffer, size)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + K_OOPS(K_SYSCALL_MEMORY_READ(buffer, size)); return z_impl_retained_mem_write(dev, offset, buffer, size); } #include static inline int z_vrfy_retained_mem_clear(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM)); return z_impl_retained_mem_clear(dev); } #include diff --git a/drivers/rtc/rtc_handlers.c b/drivers/rtc/rtc_handlers.c index 95d373025a4..33bb9076971 100644 --- a/drivers/rtc/rtc_handlers.c +++ b/drivers/rtc/rtc_handlers.c @@ -9,16 +9,16 @@ static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_time)); - Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_time)); + K_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_set_time(dev, timeptr); } #include static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time *timeptr) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_time)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_time)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_get_time(dev, timeptr); } #include @@ -27,8 +27,8 @@ static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); return z_impl_rtc_alarm_get_supported_fields(dev, id, mask); } #include @@ -36,8 +36,8 @@ static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, const struct rtc_time *timeptr) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); - Z_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); + K_OOPS(K_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_set_time(dev, id, mask, timeptr); } #include @@ -45,16 +45,16 @@ static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t i static inline int z_vrfy_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, struct rtc_time *timeptr) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); return z_impl_rtc_alarm_get_time(dev, id, mask, timeptr); } #include static inline int z_vrfy_rtc_alarm_is_pending(const struct device *dev, uint16_t id) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_is_pending)); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, alarm_is_pending)); return z_impl_rtc_alarm_is_pending(dev, id); } #include @@ -63,7 +63,7 @@ static inline int z_vrfy_rtc_alarm_is_pending(const struct device *dev, uint16_t #ifdef CONFIG_RTC_CALIBRATION static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t calibration) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_calibration)); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, set_calibration)); return z_impl_rtc_set_calibration(dev, calibration); } @@ -71,8 +71,8 @@ static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t c static inline int z_vrfy_rtc_get_calibration(const struct device *dev, int32_t *calibration) { - Z_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_calibration)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); + K_OOPS(K_SYSCALL_DRIVER_RTC(dev, get_calibration)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); return z_impl_rtc_get_calibration(dev, calibration); } #include diff --git a/drivers/sensor/sensor_handlers.c b/drivers/sensor/sensor_handlers.c index a574d20b60b..4643646c215 100644 --- a/drivers/sensor/sensor_handlers.c +++ b/drivers/sensor/sensor_handlers.c @@ -12,8 +12,8 @@ static inline int z_vrfy_sensor_attr_set(const struct device *dev, enum sensor_attribute attr, const struct sensor_value *val) { - Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_set)); - Z_OOPS(K_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value))); + K_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_set)); + K_OOPS(K_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_set((const struct device *)dev, chan, attr, (const struct sensor_value *)val); } @@ -24,8 +24,8 @@ static inline int z_vrfy_sensor_attr_get(const struct device *dev, enum sensor_attribute attr, struct sensor_value *val) { - Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_get)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); + K_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, attr_get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_attr_get((const struct device *)dev, chan, attr, (struct sensor_value *)val); } @@ -33,7 +33,7 @@ static inline int z_vrfy_sensor_attr_get(const struct device *dev, static inline int z_vrfy_sensor_sample_fetch(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); + K_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); return z_impl_sensor_sample_fetch((const struct device *)dev); } #include @@ -41,7 +41,7 @@ static inline int z_vrfy_sensor_sample_fetch(const struct device *dev) static inline int z_vrfy_sensor_sample_fetch_chan(const struct device *dev, enum sensor_channel type) { - Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); + K_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, sample_fetch)); return z_impl_sensor_sample_fetch_chan((const struct device *)dev, type); } @@ -51,8 +51,8 @@ static inline int z_vrfy_sensor_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { - Z_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, channel_get)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); + K_OOPS(K_SYSCALL_DRIVER_SENSOR(dev, channel_get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value))); return z_impl_sensor_channel_get((const struct device *)dev, chan, (struct sensor_value *)val); } @@ -62,8 +62,8 @@ static inline int z_vrfy_sensor_channel_get(const struct device *dev, static inline int z_vrfy_sensor_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR)); - Z_OOPS(K_SYSCALL_MEMORY_READ(decoder, sizeof(struct sensor_decoder_api))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR)); + K_OOPS(K_SYSCALL_MEMORY_READ(decoder, sizeof(struct sensor_decoder_api))); return z_impl_sensor_get_decoder(dev, decoder); } #include @@ -73,9 +73,9 @@ static inline int z_vrfy_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const enum sensor_channel *channels, size_t num_channels) { - Z_OOPS(K_SYSCALL_OBJ(iodev, K_OBJ_RTIO_IODEV)); - Z_OOPS(K_SYSCALL_OBJ(sensor, K_OBJ_DRIVER_SENSOR)); - Z_OOPS(K_SYSCALL_MEMORY_READ(channels, sizeof(enum sensor_channel) * num_channels)); + K_OOPS(K_SYSCALL_OBJ(iodev, K_OBJ_RTIO_IODEV)); + K_OOPS(K_SYSCALL_OBJ(sensor, K_OBJ_DRIVER_SENSOR)); + K_OOPS(K_SYSCALL_MEMORY_READ(channels, sizeof(enum sensor_channel) * num_channels)); return z_impl_sensor_reconfigure_read_iodev(iodev, sensor, channels, num_channels); } #include diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 823ba718777..954592aca28 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -10,14 +10,14 @@ #define UART_SIMPLE(op_) \ static inline int z_vrfy_uart_##op_(const struct device *dev) \ { \ - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ + K_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ return z_impl_uart_ ## op_(dev); \ } #define UART_SIMPLE_VOID(op_) \ static inline void z_vrfy_uart_##op_(const struct device *dev) \ { \ - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ + K_OOPS(K_SYSCALL_DRIVER_UART(dev, op_)); \ z_impl_uart_ ## op_(dev); \ } @@ -27,8 +27,8 @@ UART_SIMPLE(err_check) static inline int z_vrfy_uart_poll_in(const struct device *dev, unsigned char *p_char) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char))); return z_impl_uart_poll_in(dev, p_char); } #include @@ -36,8 +36,8 @@ static inline int z_vrfy_uart_poll_in(const struct device *dev, static inline int z_vrfy_uart_poll_in_u16(const struct device *dev, uint16_t *p_u16) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(p_u16, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_in)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(p_u16, sizeof(uint16_t))); return z_impl_uart_poll_in_u16(dev, p_u16); } #include @@ -45,7 +45,7 @@ static inline int z_vrfy_uart_poll_in_u16(const struct device *dev, static inline void z_vrfy_uart_poll_out(const struct device *dev, unsigned char out_char) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); z_impl_uart_poll_out((const struct device *)dev, out_char); } #include @@ -53,7 +53,7 @@ static inline void z_vrfy_uart_poll_out(const struct device *dev, static inline void z_vrfy_uart_poll_out_u16(const struct device *dev, uint16_t out_u16) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, poll_out)); z_impl_uart_poll_out_u16((const struct device *)dev, out_u16); } #include @@ -62,8 +62,8 @@ static inline void z_vrfy_uart_poll_out_u16(const struct device *dev, static inline int z_vrfy_uart_config_get(const struct device *dev, struct uart_config *cfg) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(cfg, sizeof(struct uart_config))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(cfg, sizeof(struct uart_config))); return z_impl_uart_config_get(dev, cfg); } @@ -72,8 +72,8 @@ static inline int z_vrfy_uart_config_get(const struct device *dev, static inline int z_vrfy_uart_configure(const struct device *dev, const struct uart_config *cfg) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); - Z_OOPS(K_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); + K_OOPS(K_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); return z_impl_uart_configure(dev, cfg); } @@ -90,8 +90,8 @@ static inline int z_vrfy_uart_configure(const struct device *dev, static inline int z_vrfy_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); return z_impl_uart_tx(dev, buf, len, timeout); } #include @@ -101,8 +101,8 @@ static inline int z_vrfy_uart_tx_u16(const struct device *dev, const uint16_t *buf, size_t len, int32_t timeout) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(buf, len, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, tx)); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(buf, len, sizeof(uint16_t))); return z_impl_uart_tx_u16(dev, buf, len, timeout); } #include @@ -115,8 +115,8 @@ static inline int z_vrfy_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); return z_impl_uart_rx_enable(dev, buf, len, timeout); } #include @@ -126,8 +126,8 @@ static inline int z_vrfy_uart_rx_enable_u16(const struct device *dev, uint16_t *buf, size_t len, int32_t timeout) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(buf, len, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, rx_enable)); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(buf, len, sizeof(uint16_t))); return z_impl_uart_rx_enable_u16(dev, buf, len, timeout); } #include @@ -160,7 +160,7 @@ UART_SIMPLE(irq_update) static inline int z_vrfy_uart_line_ctrl_set(const struct device *dev, uint32_t ctrl, uint32_t val) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_set)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_set)); return z_impl_uart_line_ctrl_set((const struct device *)dev, ctrl, val); } @@ -169,8 +169,8 @@ static inline int z_vrfy_uart_line_ctrl_set(const struct device *dev, static inline int z_vrfy_uart_line_ctrl_get(const struct device *dev, uint32_t ctrl, uint32_t *val) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_get)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(uint32_t))); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, line_ctrl_get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(val, sizeof(uint32_t))); return z_impl_uart_line_ctrl_get((const struct device *)dev, ctrl, (uint32_t *)val); } @@ -181,7 +181,7 @@ static inline int z_vrfy_uart_line_ctrl_get(const struct device *dev, static inline int z_vrfy_uart_drv_cmd(const struct device *dev, uint32_t cmd, uint32_t p) { - Z_OOPS(K_SYSCALL_DRIVER_UART(dev, drv_cmd)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, drv_cmd)); return z_impl_uart_drv_cmd((const struct device *)dev, cmd, p); } #include diff --git a/drivers/smbus/smbus_handlers.c b/drivers/smbus/smbus_handlers.c index 5db5d12dfa8..4762ccf1e90 100644 --- a/drivers/smbus/smbus_handlers.c +++ b/drivers/smbus/smbus_handlers.c @@ -11,7 +11,7 @@ static inline int z_vrfy_smbus_configure(const struct device *dev, uint32_t dev_config) { - Z_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, configure)); + K_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, configure)); return z_impl_smbus_configure(dev, dev_config); } @@ -20,8 +20,8 @@ static inline int z_vrfy_smbus_configure(const struct device *dev, static inline int z_vrfy_smbus_get_config(const struct device *dev, uint32_t *dev_config) { - Z_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, get_config)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); + K_OOPS(K_SYSCALL_DRIVER_SMBUS(dev, get_config)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dev_config, sizeof(uint32_t))); return z_impl_smbus_get_config(dev, dev_config); } @@ -30,7 +30,7 @@ static inline int z_vrfy_smbus_get_config(const struct device *dev, static inline int z_vrfy_smbus_quick(const struct device *dev, uint16_t addr, enum smbus_direction rw) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_quick(dev, addr, rw); } @@ -39,7 +39,7 @@ static inline int z_vrfy_smbus_quick(const struct device *dev, uint16_t addr, static inline int z_vrfy_smbus_byte_write(const struct device *dev, uint16_t addr, uint8_t byte) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_byte_write(dev, addr, byte); } @@ -48,8 +48,8 @@ static inline int z_vrfy_smbus_byte_write(const struct device *dev, static inline int z_vrfy_smbus_byte_read(const struct device *dev, uint16_t addr, uint8_t *byte) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); return z_impl_smbus_byte_read(dev, addr, byte); } @@ -59,7 +59,7 @@ static inline int z_vrfy_smbus_byte_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t byte) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_byte_data_write(dev, addr, cmd, byte); } @@ -69,8 +69,8 @@ static inline int z_vrfy_smbus_byte_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *byte) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(byte, sizeof(uint8_t))); return z_impl_smbus_byte_data_read(dev, addr, cmd, byte); } @@ -80,7 +80,7 @@ static inline int z_vrfy_smbus_word_data_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t word) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_word_data_write(dev, addr, cmd, word); } @@ -90,8 +90,8 @@ static inline int z_vrfy_smbus_word_data_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t *word) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(word, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(word, sizeof(uint16_t))); return z_impl_smbus_word_data_read(dev, addr, cmd, word); } @@ -101,8 +101,8 @@ static inline int z_vrfy_smbus_pcall(const struct device *dev, uint16_t addr, uint8_t cmd, uint16_t send_word, uint16_t *recv_word) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(recv_word, sizeof(uint16_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(recv_word, sizeof(uint16_t))); return z_impl_smbus_pcall(dev, addr, cmd, send_word, recv_word); } @@ -112,8 +112,8 @@ static inline int z_vrfy_smbus_block_write(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t count, uint8_t *buf) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, count)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, count)); return z_impl_smbus_block_write(dev, addr, cmd, count, buf); } @@ -123,8 +123,8 @@ static inline int z_vrfy_smbus_block_read(const struct device *dev, uint16_t addr, uint8_t cmd, uint8_t *count, uint8_t *buf) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(count, sizeof(uint8_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(count, sizeof(uint8_t))); return z_impl_smbus_block_read(dev, addr, cmd, count, buf); } @@ -135,9 +135,9 @@ static inline int z_vrfy_smbus_block_pcall(const struct device *dev, uint8_t snd_count, uint8_t *snd_buf, uint8_t *rcv_count, uint8_t *rcv_buf) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - Z_OOPS(K_SYSCALL_MEMORY_READ(snd_buf, snd_count)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(rcv_count, sizeof(uint8_t))); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_MEMORY_READ(snd_buf, snd_count)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(rcv_count, sizeof(uint8_t))); return z_impl_smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf, rcv_count, rcv_buf); @@ -147,7 +147,7 @@ static inline int z_vrfy_smbus_block_pcall(const struct device *dev, static inline int z_vrfy_smbus_smbalert_set_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_smbalert_set_cb(dev, cb); } @@ -156,7 +156,7 @@ static inline int z_vrfy_smbus_smbalert_set_cb(const struct device *dev, static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_smbalert_remove_cb(dev, cb); } @@ -165,7 +165,7 @@ static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, static inline int z_vrfy_smbus_host_notify_set_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_host_notify_set_cb(dev, cb); } @@ -174,7 +174,7 @@ static inline int z_vrfy_smbus_host_notify_set_cb(const struct device *dev, static inline int z_vrfy_smbus_host_notify_remove_cb(const struct device *dev, struct smbus_callback *cb) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); return z_impl_smbus_host_notify_remove_cb(dev, cb); } diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index 3618d9dedcb..68b362b5ed2 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -23,7 +23,7 @@ static struct spi_buf_set *copy_and_check(struct spi_buf_set *bufs, } /* Validate the array of struct spi_buf instances */ - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers, + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers, bufs->count, sizeof(struct spi_buf))); @@ -40,7 +40,7 @@ static struct spi_buf_set *copy_and_check(struct spi_buf_set *bufs, */ const struct spi_buf *buf = &bufs->buffers[i]; - Z_OOPS(K_SYSCALL_MEMORY(buf->buf, buf->len, writable)); + K_OOPS(K_SYSCALL_MEMORY(buf->buf, buf->len, writable)); } return bufs; @@ -76,17 +76,17 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, struct spi_buf_set rx_bufs_copy; struct spi_config config_copy; - Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); - Z_OOPS(K_SYSCALL_DRIVER_SPI(dev, transceive)); + K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); + K_OOPS(K_SYSCALL_DRIVER_SPI(dev, transceive)); if (tx_bufs) { const struct spi_buf_set *tx = (const struct spi_buf_set *)tx_bufs; - Z_OOPS(K_SYSCALL_MEMORY_READ(tx_bufs, + K_OOPS(K_SYSCALL_MEMORY_READ(tx_bufs, sizeof(struct spi_buf_set))); memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy)); - Z_OOPS(K_SYSCALL_VERIFY(tx_bufs_copy.count < 32)); + K_OOPS(K_SYSCALL_VERIFY(tx_bufs_copy.count < 32)); } else { memset(&tx_bufs_copy, 0, sizeof(tx_bufs_copy)); } @@ -95,17 +95,17 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, const struct spi_buf_set *rx = (const struct spi_buf_set *)rx_bufs; - Z_OOPS(K_SYSCALL_MEMORY_READ(rx_bufs, + K_OOPS(K_SYSCALL_MEMORY_READ(rx_bufs, sizeof(struct spi_buf_set))); memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy)); - Z_OOPS(K_SYSCALL_VERIFY(rx_bufs_copy.count < 32)); + K_OOPS(K_SYSCALL_VERIFY(rx_bufs_copy.count < 32)); } else { memset(&rx_bufs_copy, 0, sizeof(rx_bufs_copy)); } memcpy(&config_copy, config, sizeof(*config)); if (spi_cs_is_gpio(&config_copy)) { - Z_OOPS(K_SYSCALL_OBJ(config_copy.cs.gpio.port, + K_OOPS(K_SYSCALL_OBJ(config_copy.cs.gpio.port, K_OBJ_DRIVER_GPIO)); } @@ -119,8 +119,8 @@ static inline int z_vrfy_spi_transceive(const struct device *dev, static inline int z_vrfy_spi_release(const struct device *dev, const struct spi_config *config) { - Z_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); - Z_OOPS(K_SYSCALL_DRIVER_SPI(dev, release)); + K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config))); + K_OOPS(K_SYSCALL_DRIVER_SPI(dev, release)); return z_impl_spi_release((const struct device *)dev, config); } #include diff --git a/drivers/usb/bc12/bc12_handlers.c b/drivers/usb/bc12/bc12_handlers.c index 0e4e6d83e25..dce82695a14 100644 --- a/drivers/usb/bc12/bc12_handlers.c +++ b/drivers/usb/bc12/bc12_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_bc12_set_role(const struct device *dev, enum bc12_role role) { - Z_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_role)); + K_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_role)); return z_impl_bc12_set_role(dev, role); } @@ -17,8 +17,8 @@ static inline int z_vrfy_bc12_set_role(const struct device *dev, enum bc12_role static inline int z_vrfy_bc12_set_result_cb(const struct device *dev, bc12_callback_t cb, void *user_data) { - Z_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_result_cb)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(cb == NULL, "callbacks may not be set from user mode")); + K_OOPS(K_SYSCALL_DRIVER_BC12(dev, set_result_cb)); + K_OOPS(K_SYSCALL_VERIFY_MSG(cb == NULL, "callbacks may not be set from user mode")); return z_impl_bc12_set_result_cb(dev, cb, user_data); } diff --git a/drivers/virtualization/virt_ivshmem_handlers.c b/drivers/virtualization/virt_ivshmem_handlers.c index 8f6221c8160..821ab16f304 100644 --- a/drivers/virtualization/virt_ivshmem_handlers.c +++ b/drivers/virtualization/virt_ivshmem_handlers.c @@ -11,8 +11,8 @@ static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, uintptr_t *memmap) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_mem)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_mem)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_mem(dev, memmap); } @@ -20,7 +20,7 @@ static inline size_t z_vrfy_ivshmem_get_mem(const struct device *dev, static inline uint32_t z_vrfy_ivshmem_get_id(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_id)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_id)); return z_impl_ivshmem_get_id(dev); } @@ -28,7 +28,7 @@ static inline uint32_t z_vrfy_ivshmem_get_id(const struct device *dev) static inline uint16_t z_vrfy_ivshmem_get_vectors(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_vectors)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_vectors)); return z_impl_ivshmem_get_vectors(dev); } @@ -37,7 +37,7 @@ static inline uint16_t z_vrfy_ivshmem_get_vectors(const struct device *dev) static inline int z_vrfy_ivshmem_int_peer(const struct device *dev, uint32_t peer_id, uint16_t vector) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, int_peer)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, int_peer)); return z_impl_ivshmem_int_peer(dev, peer_id, vector); } @@ -47,8 +47,8 @@ static inline int z_vrfy_ivshmem_register_handler(const struct device *dev, struct k_poll_signal *signal, uint16_t vector) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, register_handler)); - Z_OOPS(K_SYSCALL_OBJ(signal, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, register_handler)); + K_OOPS(K_SYSCALL_OBJ(signal, K_OBJ_POLL_SIGNAL)); return z_impl_ivshmem_register_handler(dev, signal, vector); } @@ -59,8 +59,8 @@ static inline int z_vrfy_ivshmem_register_handler(const struct device *dev, static inline size_t z_vrfy_ivshmem_get_rw_mem_section(const struct device *dev, uintptr_t *memmap) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_rw_mem_section)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_rw_mem_section)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_rw_mem_section(dev, memmap); } @@ -70,8 +70,8 @@ static inline size_t z_vrfy_ivshmem_get_output_mem_section(const struct device * uint32_t peer_id, uintptr_t *memmap) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_output_mem_section)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_output_mem_section)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(memmap, sizeof(uintptr_t))); return z_impl_ivshmem_get_output_mem_section(dev, peer_id, memmap); } @@ -80,7 +80,7 @@ static inline size_t z_vrfy_ivshmem_get_output_mem_section(const struct device * static inline uint32_t z_vrfy_ivshmem_get_state(const struct device *dev, uint32_t peer_id) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_state)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_state)); return z_impl_ivshmem_get_state(dev, peer_id); } @@ -89,7 +89,7 @@ static inline uint32_t z_vrfy_ivshmem_get_state(const struct device *dev, static inline int z_vrfy_ivshmem_set_state(const struct device *dev, uint32_t state) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, set_state)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, set_state)); return z_impl_ivshmem_set_state(dev, state); } @@ -97,7 +97,7 @@ static inline int z_vrfy_ivshmem_set_state(const struct device *dev, static inline uint32_t z_vrfy_ivshmem_get_max_peers(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_max_peers)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_max_peers)); return z_impl_ivshmem_get_max_peers(dev); } @@ -105,7 +105,7 @@ static inline uint32_t z_vrfy_ivshmem_get_max_peers(const struct device *dev) static inline uint16_t z_vrfy_ivshmem_get_protocol(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_protocol)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, get_protocol)); return z_impl_ivshmem_get_protocol(dev); } @@ -114,7 +114,7 @@ static inline uint16_t z_vrfy_ivshmem_get_protocol(const struct device *dev) static inline int z_vrfy_ivshmem_enable_interrupts(const struct device *dev, bool enable) { - Z_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, enable_interrupts)); + K_OOPS(K_SYSCALL_DRIVER_IVSHMEM(dev, enable_interrupts)); return z_impl_ivshmem_enable_interrupts(dev, enable); } diff --git a/drivers/w1/w1_handlers.c b/drivers/w1/w1_handlers.c index 496fc7a4cca..f2299705a26 100644 --- a/drivers/w1/w1_handlers.c +++ b/drivers/w1/w1_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_w1_reset_bus(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, reset_bus)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, reset_bus)); return z_impl_w1_reset_bus((const struct device *)dev); } @@ -17,7 +17,7 @@ static inline int z_vrfy_w1_reset_bus(const struct device *dev) static inline int z_vrfy_w1_read_bit(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, read_bit)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, read_bit)); return z_impl_w1_read_bit((const struct device *)dev); } @@ -25,7 +25,7 @@ static inline int z_vrfy_w1_read_bit(const struct device *dev) static inline int z_vrfy_w1_write_bit(const struct device *dev, bool bit) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, write_bit)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, write_bit)); return z_impl_w1_write_bit((const struct device *)dev, bit); } @@ -33,7 +33,7 @@ static inline int z_vrfy_w1_write_bit(const struct device *dev, bool bit) static inline int z_vrfy_w1_read_byte(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, read_byte)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, read_byte)); return z_impl_w1_read_byte((const struct device *)dev); } @@ -41,7 +41,7 @@ static inline int z_vrfy_w1_read_byte(const struct device *dev) static inline int z_vrfy_w1_write_byte(const struct device *dev, uint8_t byte) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, write_byte)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, write_byte)); return z_impl_w1_write_byte((const struct device *)dev, (uint8_t)byte); } @@ -50,8 +50,8 @@ static inline int z_vrfy_w1_write_byte(const struct device *dev, uint8_t byte) static inline int z_vrfy_w1_read_block(const struct device *dev, uint8_t *buffer, size_t len) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, len)); return z_impl_w1_read_block((const struct device *)dev, (uint8_t *)buffer, (size_t)len); @@ -61,8 +61,8 @@ static inline int z_vrfy_w1_read_block(const struct device *dev, static inline int z_vrfy_w1_write_block(const struct device *dev, const uint8_t *buffer, size_t len) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(K_SYSCALL_MEMORY_READ(buffer, len)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + K_OOPS(K_SYSCALL_MEMORY_READ(buffer, len)); return z_impl_w1_write_block((const struct device *)dev, (const uint8_t *)buffer, (size_t)len); @@ -71,7 +71,7 @@ static inline int z_vrfy_w1_write_block(const struct device *dev, static inline int z_vrfy_w1_change_bus_lock(const struct device *dev, bool lock) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); return z_impl_w1_change_bus_lock((const struct device *)dev, lock); } @@ -80,7 +80,7 @@ static inline int z_vrfy_w1_change_bus_lock(const struct device *dev, bool lock) static inline int z_vrfy_w1_configure(const struct device *dev, enum w1_settings_type type, uint32_t value) { - Z_OOPS(K_SYSCALL_DRIVER_W1(dev, configure)); + K_OOPS(K_SYSCALL_DRIVER_W1(dev, configure)); return z_impl_w1_configure(dev, type, value); } @@ -88,7 +88,7 @@ static inline int z_vrfy_w1_configure(const struct device *dev, static inline size_t z_vrfy_w1_get_slave_count(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); return z_impl_w1_get_slave_count((const struct device *)dev); } @@ -100,9 +100,9 @@ static inline int z_vrfy_w1_search_bus(const struct device *dev, w1_search_callback_t callback, void *user_data) { - Z_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_W1)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(callback == 0, + K_OOPS(K_SYSCALL_VERIFY_MSG(callback == 0, "callbacks may not be set from user mode")); /* user_data is not dereferenced, no need to check parameter */ diff --git a/drivers/watchdog/wdt_handlers.c b/drivers/watchdog/wdt_handlers.c index 66f99c6590d..2ac872f1379 100644 --- a/drivers/watchdog/wdt_handlers.c +++ b/drivers/watchdog/wdt_handlers.c @@ -9,7 +9,7 @@ static inline int z_vrfy_wdt_setup(const struct device *dev, uint8_t options) { - Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, setup)); + K_OOPS(K_SYSCALL_DRIVER_WDT(dev, setup)); return z_impl_wdt_setup(dev, options); } @@ -17,7 +17,7 @@ static inline int z_vrfy_wdt_setup(const struct device *dev, uint8_t options) static inline int z_vrfy_wdt_disable(const struct device *dev) { - Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, disable)); + K_OOPS(K_SYSCALL_DRIVER_WDT(dev, disable)); return z_impl_wdt_disable(dev); } @@ -25,7 +25,7 @@ static inline int z_vrfy_wdt_disable(const struct device *dev) static inline int z_vrfy_wdt_feed(const struct device *dev, int channel_id) { - Z_OOPS(K_SYSCALL_DRIVER_WDT(dev, feed)); + K_OOPS(K_SYSCALL_DRIVER_WDT(dev, feed)); return z_impl_wdt_feed(dev, channel_id); } diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index ff39f5cd9a0..568c0e7b693 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -287,7 +287,7 @@ char *k_usermode_string_alloc_copy(const char *src, size_t maxlen); */ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); -#define Z_OOPS(expr) \ +#define K_OOPS(expr) \ do { \ if (expr) { \ arch_syscall_oops(_current->syscall_frame); \ diff --git a/kernel/atomic_c.c b/kernel/atomic_c.c index 21ca934f012..1790953cb11 100644 --- a/kernel/atomic_c.c +++ b/kernel/atomic_c.c @@ -42,7 +42,7 @@ static struct k_spinlock lock; #define ATOMIC_SYSCALL_HANDLER_TARGET(name) \ static inline atomic_val_t z_vrfy_##name(atomic_t *target) \ { \ - Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ + K_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ return z_impl_##name((atomic_t *)target); \ } @@ -50,7 +50,7 @@ static struct k_spinlock lock; static inline atomic_val_t z_vrfy_##name(atomic_t *target, \ atomic_val_t value) \ { \ - Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ + K_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \ return z_impl_##name((atomic_t *)target, value); \ } #else @@ -108,7 +108,7 @@ bool z_impl_atomic_cas(atomic_t *target, atomic_val_t old_value, bool z_vrfy_atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); return z_impl_atomic_cas((atomic_t *)target, old_value, new_value); } @@ -138,7 +138,7 @@ static inline bool z_vrfy_atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value, atomic_ptr_val_t new_value) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); return z_impl_atomic_ptr_cas(target, old_value, new_value); } @@ -276,7 +276,7 @@ atomic_ptr_val_t z_impl_atomic_ptr_set(atomic_ptr_t *target, static inline atomic_ptr_val_t z_vrfy_atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t))); return z_impl_atomic_ptr_set(target, value); } diff --git a/kernel/condvar.c b/kernel/condvar.c index 25e873e7f89..1aa26e937d3 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -35,7 +35,7 @@ int z_impl_k_condvar_init(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_init(struct k_condvar *condvar) { - Z_OOPS(K_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR)); + K_OOPS(K_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_init(condvar); } #include @@ -67,7 +67,7 @@ int z_impl_k_condvar_signal(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_signal(struct k_condvar *condvar) { - Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + K_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_signal(condvar); } #include @@ -100,7 +100,7 @@ int z_impl_k_condvar_broadcast(struct k_condvar *condvar) #ifdef CONFIG_USERSPACE int z_vrfy_k_condvar_broadcast(struct k_condvar *condvar) { - Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + K_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); return z_impl_k_condvar_broadcast(condvar); } #include @@ -128,8 +128,8 @@ int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, int z_vrfy_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); - Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + K_OOPS(K_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR)); + K_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_condvar_wait(condvar, mutex, timeout); } #include diff --git a/kernel/device.c b/kernel/device.c index a757fc73863..6124ada5140 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -70,7 +70,7 @@ static inline const struct device *z_vrfy_device_get_binding(const char *name) static inline bool z_vrfy_device_is_ready(const struct device *dev) { - Z_OOPS(K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY)); + K_OOPS(K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY)); return z_impl_device_is_ready(dev); } diff --git a/kernel/events.c b/kernel/events.c index 793fd340bc5..8cb90dc6160 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -68,7 +68,7 @@ void z_impl_k_event_init(struct k_event *event) #ifdef CONFIG_USERSPACE void z_vrfy_k_event_init(struct k_event *event) { - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(event, K_OBJ_EVENT)); z_impl_k_event_init(event); } #include @@ -187,7 +187,7 @@ uint32_t z_impl_k_event_post(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_post(struct k_event *event, uint32_t events) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_post(event, events); } #include @@ -201,7 +201,7 @@ uint32_t z_impl_k_event_set(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_set(struct k_event *event, uint32_t events) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_set(event, events); } #include @@ -217,7 +217,7 @@ uint32_t z_impl_k_event_set_masked(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_set_masked(struct k_event *event, uint32_t events, uint32_t events_mask) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_set_masked(event, events, events_mask); } #include @@ -231,7 +231,7 @@ uint32_t z_impl_k_event_clear(struct k_event *event, uint32_t events) #ifdef CONFIG_USERSPACE uint32_t z_vrfy_k_event_clear(struct k_event *event, uint32_t events) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_clear(event, events); } #include @@ -317,7 +317,7 @@ uint32_t z_impl_k_event_wait(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_wait(struct k_event *event, uint32_t events, bool reset, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_wait(event, events, reset, timeout); } #include @@ -339,7 +339,7 @@ uint32_t z_impl_k_event_wait_all(struct k_event *event, uint32_t events, uint32_t z_vrfy_k_event_wait_all(struct k_event *event, uint32_t events, bool reset, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); + K_OOPS(K_SYSCALL_OBJ(event, K_OBJ_EVENT)); return z_impl_k_event_wait_all(event, events, reset, timeout); } #include diff --git a/kernel/msg_q.c b/kernel/msg_q.c index cd3c8e48ff5..e11e9a2527e 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -93,7 +93,7 @@ int z_impl_k_msgq_alloc_init(struct k_msgq *msgq, size_t msg_size, int z_vrfy_k_msgq_alloc_init(struct k_msgq *msgq, size_t msg_size, uint32_t max_msgs) { - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_alloc_init(msgq, msg_size, max_msgs); } @@ -187,8 +187,8 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout static inline int z_vrfy_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(K_SYSCALL_MEMORY_READ(data, msgq->msg_size)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, msgq->msg_size)); return z_impl_k_msgq_put(msgq, data, timeout); } @@ -206,8 +206,8 @@ void z_impl_k_msgq_get_attrs(struct k_msgq *msgq, struct k_msgq_attrs *attrs) static inline void z_vrfy_k_msgq_get_attrs(struct k_msgq *msgq, struct k_msgq_attrs *attrs) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs))); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs))); z_impl_k_msgq_get_attrs(msgq, attrs); } #include @@ -285,8 +285,8 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) static inline int z_vrfy_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_get(msgq, data, timeout); } @@ -319,8 +319,8 @@ int z_impl_k_msgq_peek(struct k_msgq *msgq, void *data) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_msgq_peek(struct k_msgq *msgq, void *data) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_peek(msgq, data); } @@ -365,8 +365,8 @@ int z_impl_k_msgq_peek_at(struct k_msgq *msgq, void *data, uint32_t idx) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_msgq_peek_at(struct k_msgq *msgq, void *data, uint32_t idx) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, msgq->msg_size)); return z_impl_k_msgq_peek_at(msgq, data, idx); } @@ -397,21 +397,21 @@ void z_impl_k_msgq_purge(struct k_msgq *msgq) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_msgq_purge(struct k_msgq *msgq) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); z_impl_k_msgq_purge(msgq); } #include static inline uint32_t z_vrfy_k_msgq_num_free_get(struct k_msgq *msgq) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_num_free_get(msgq); } #include static inline uint32_t z_vrfy_k_msgq_num_used_get(struct k_msgq *msgq) { - Z_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_OBJ(msgq, K_OBJ_MSGQ)); return z_impl_k_msgq_num_used_get(msgq); } #include diff --git a/kernel/mutex.c b/kernel/mutex.c index d06522a0420..6d22ce83f22 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -71,7 +71,7 @@ int z_impl_k_mutex_init(struct k_mutex *mutex) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_init(struct k_mutex *mutex) { - Z_OOPS(K_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX)); + K_OOPS(K_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_init(mutex); } #include @@ -200,7 +200,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) static inline int z_vrfy_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + K_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_lock(mutex, timeout); } #include @@ -284,7 +284,7 @@ int z_impl_k_mutex_unlock(struct k_mutex *mutex) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) { - Z_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); + K_OOPS(K_SYSCALL_OBJ(mutex, K_OBJ_MUTEX)); return z_impl_k_mutex_unlock(mutex); } #include diff --git a/kernel/paging/statistics.c b/kernel/paging/statistics.c index 87cd2b04b68..b2f343c9fcb 100644 --- a/kernel/paging/statistics.c +++ b/kernel/paging/statistics.c @@ -102,7 +102,7 @@ void z_impl_k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats) static inline void z_vrfy_k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); z_impl_k_mem_paging_stats_get(stats); } #include @@ -125,8 +125,8 @@ static inline void z_vrfy_k_mem_paging_thread_stats_get(struct k_thread *thread, struct k_mem_paging_stats_t *stats) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(stats, sizeof(*stats))); z_impl_k_mem_paging_thread_stats_get(thread, stats); } #include @@ -224,7 +224,7 @@ static inline void z_vrfy_k_mem_paging_histogram_eviction_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_eviction_get(hist); } #include @@ -233,7 +233,7 @@ static inline void z_vrfy_k_mem_paging_histogram_backing_store_page_in_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_backing_store_page_in_get(hist); } #include @@ -242,7 +242,7 @@ static inline void z_vrfy_k_mem_paging_histogram_backing_store_page_out_get( struct k_mem_paging_histogram_t *hist) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(hist, sizeof(*hist))); z_impl_k_mem_paging_histogram_backing_store_page_out_get(hist); } #include diff --git a/kernel/pipes.c b/kernel/pipes.c index 01c5f36b906..3fa1c72036d 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -89,7 +89,7 @@ int z_impl_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) { - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_alloc_init(pipe, size); } @@ -122,7 +122,7 @@ void z_impl_k_pipe_flush(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE void z_vrfy_k_pipe_flush(struct k_pipe *pipe) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); z_impl_k_pipe_flush(pipe); } @@ -150,7 +150,7 @@ void z_impl_k_pipe_buffer_flush(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE void z_vrfy_k_pipe_buffer_flush(struct k_pipe *pipe) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); z_impl_k_pipe_buffer_flush(pipe); } @@ -517,9 +517,9 @@ int z_vrfy_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write, size_t *bytes_written, size_t min_xfer, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written))); - Z_OOPS(K_SYSCALL_MEMORY_READ((void *)data, bytes_to_write)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written))); + K_OOPS(K_SYSCALL_MEMORY_READ((void *)data, bytes_to_write)); return z_impl_k_pipe_put((struct k_pipe *)pipe, (void *)data, bytes_to_write, bytes_written, min_xfer, @@ -725,9 +725,9 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read, int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read, size_t *bytes_read, size_t min_xfer, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read))); + K_OOPS(K_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read)); return z_impl_k_pipe_get((struct k_pipe *)pipe, (void *)data, bytes_to_read, bytes_read, min_xfer, @@ -766,7 +766,7 @@ size_t z_impl_k_pipe_read_avail(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE size_t z_vrfy_k_pipe_read_avail(struct k_pipe *pipe) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_read_avail(pipe); } @@ -803,7 +803,7 @@ size_t z_impl_k_pipe_write_avail(struct k_pipe *pipe) #ifdef CONFIG_USERSPACE size_t z_vrfy_k_pipe_write_avail(struct k_pipe *pipe) { - Z_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); return z_impl_k_pipe_write_avail(pipe); } diff --git a/kernel/poll.c b/kernel/poll.c index 3c0c94744ad..d983af7e20e 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -402,20 +402,20 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, case K_POLL_TYPE_IGNORE: break; case K_POLL_TYPE_SIGNAL: - Z_OOPS(K_SYSCALL_OBJ(e->signal, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ(e->signal, K_OBJ_POLL_SIGNAL)); break; case K_POLL_TYPE_SEM_AVAILABLE: - Z_OOPS(K_SYSCALL_OBJ(e->sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(e->sem, K_OBJ_SEM)); break; case K_POLL_TYPE_DATA_AVAILABLE: - Z_OOPS(K_SYSCALL_OBJ(e->queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(e->queue, K_OBJ_QUEUE)); break; case K_POLL_TYPE_MSGQ_DATA_AVAILABLE: - Z_OOPS(K_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ)); + K_OOPS(K_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ)); break; #ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: - Z_OOPS(K_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE)); break; #endif default: @@ -432,7 +432,7 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, return ret; oops_free: k_free(events_copy); - Z_OOPS(1); + K_OOPS(1); } #include #endif @@ -490,7 +490,7 @@ void z_impl_k_poll_signal_init(struct k_poll_signal *sig) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_poll_signal_init(struct k_poll_signal *sig) { - Z_OOPS(K_SYSCALL_OBJ_INIT(sig, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ_INIT(sig, K_OBJ_POLL_SIGNAL)); z_impl_k_poll_signal_init(sig); } #include @@ -516,9 +516,9 @@ void z_impl_k_poll_signal_check(struct k_poll_signal *sig, void z_vrfy_k_poll_signal_check(struct k_poll_signal *sig, unsigned int *signaled, int *result) { - Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(signaled, sizeof(unsigned int))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(result, sizeof(int))); + K_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(signaled, sizeof(unsigned int))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(result, sizeof(int))); z_impl_k_poll_signal_check(sig, signaled, result); } #include @@ -553,14 +553,14 @@ int z_impl_k_poll_signal_raise(struct k_poll_signal *sig, int result) static inline int z_vrfy_k_poll_signal_raise(struct k_poll_signal *sig, int result) { - Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); return z_impl_k_poll_signal_raise(sig, result); } #include static inline void z_vrfy_k_poll_signal_reset(struct k_poll_signal *sig) { - Z_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); + K_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL)); z_impl_k_poll_signal_reset(sig); } #include diff --git a/kernel/queue.c b/kernel/queue.c index d1f9a4344ad..04aaa149d97 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -72,7 +72,7 @@ void z_impl_k_queue_init(struct k_queue *queue) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_queue_init(struct k_queue *queue) { - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE)); z_impl_k_queue_init(queue); } #include @@ -114,7 +114,7 @@ void z_impl_k_queue_cancel_wait(struct k_queue *queue) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_queue_cancel_wait(struct k_queue *queue) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); z_impl_k_queue_cancel_wait(queue); } #include @@ -217,7 +217,7 @@ int32_t z_impl_k_queue_alloc_append(struct k_queue *queue, void *data) static inline int32_t z_vrfy_k_queue_alloc_append(struct k_queue *queue, void *data) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_alloc_append(queue, data); } #include @@ -238,7 +238,7 @@ int32_t z_impl_k_queue_alloc_prepend(struct k_queue *queue, void *data) static inline int32_t z_vrfy_k_queue_alloc_prepend(struct k_queue *queue, void *data) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_alloc_prepend(queue, data); } #include @@ -405,28 +405,28 @@ void *z_impl_k_queue_peek_tail(struct k_queue *queue) static inline void *z_vrfy_k_queue_get(struct k_queue *queue, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_get(queue, timeout); } #include static inline int z_vrfy_k_queue_is_empty(struct k_queue *queue) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_is_empty(queue); } #include static inline void *z_vrfy_k_queue_peek_head(struct k_queue *queue) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_peek_head(queue); } #include static inline void *z_vrfy_k_queue_peek_tail(struct k_queue *queue) { - Z_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); + K_OOPS(K_SYSCALL_OBJ(queue, K_OBJ_QUEUE)); return z_impl_k_queue_peek_tail(queue); } #include diff --git a/kernel/sched.c b/kernel/sched.c index f1593d442a0..ffd3070f187 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -689,7 +689,7 @@ void z_impl_k_thread_suspend(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_suspend(struct k_thread *thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_thread_suspend(thread); } #include @@ -718,7 +718,7 @@ void z_impl_k_thread_resume(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_resume(struct k_thread *thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_thread_resume(thread); } #include @@ -1335,7 +1335,7 @@ int z_impl_k_thread_priority_get(k_tid_t thread) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_thread_priority_get(k_tid_t thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_thread_priority_get(thread); } #include @@ -1358,10 +1358,10 @@ void z_impl_k_thread_priority_set(k_tid_t thread, int prio) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_priority_set(k_tid_t thread, int prio) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), "invalid thread priority %d", prio)); - Z_OOPS(K_SYSCALL_VERIFY_MSG((int8_t)prio >= thread->base.prio, + K_OOPS(K_SYSCALL_VERIFY_MSG((int8_t)prio >= thread->base.prio, "thread priority may only be downgraded (%d < %d)", prio, thread->base.prio)); @@ -1389,8 +1389,8 @@ static inline void z_vrfy_k_thread_deadline_set(k_tid_t tid, int deadline) { struct k_thread *thread = tid; - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); - Z_OOPS(K_SYSCALL_VERIFY_MSG(deadline > 0, + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_VERIFY_MSG(deadline > 0, "invalid thread deadline %d", (int)deadline)); @@ -1583,7 +1583,7 @@ void z_sched_ipi(void) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_wakeup(k_tid_t thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); z_impl_k_wakeup(thread); } #include @@ -1890,7 +1890,7 @@ static bool thread_obj_validate(struct k_thread *thread) #ifdef CONFIG_LOG k_object_dump_error(ret, thread, ko, K_OBJ_THREAD); #endif - Z_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied")); + K_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied")); } CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } @@ -1912,7 +1912,7 @@ static inline void z_vrfy_k_thread_abort(k_tid_t thread) return; } - Z_OOPS(K_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), + K_OOPS(K_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), "aborting essential thread %p", thread)); z_impl_k_thread_abort((struct k_thread *)thread); diff --git a/kernel/sem.c b/kernel/sem.c index b7e04207929..2f8de51ed83 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -76,7 +76,7 @@ int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, int z_vrfy_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { - Z_OOPS(K_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM)); return z_impl_k_sem_init(sem, initial_count, limit); } #include @@ -123,7 +123,7 @@ void z_impl_k_sem_give(struct k_sem *sem) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_sem_give(struct k_sem *sem) { - Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); z_impl_k_sem_give(sem); } #include @@ -188,21 +188,21 @@ void z_impl_k_sem_reset(struct k_sem *sem) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_sem_take(struct k_sem *sem, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_take((struct k_sem *)sem, timeout); } #include static inline void z_vrfy_k_sem_reset(struct k_sem *sem) { - Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); z_impl_k_sem_reset(sem); } #include static inline unsigned int z_vrfy_k_sem_count_get(struct k_sem *sem) { - Z_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); return z_impl_k_sem_count_get(sem); } #include diff --git a/kernel/stack.c b/kernel/stack.c index 72db870b6ea..6ada39c9b1e 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -64,8 +64,8 @@ int32_t z_impl_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) static inline int32_t z_vrfy_k_stack_alloc_init(struct k_stack *stack, uint32_t num_entries) { - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK)); - Z_OOPS(K_SYSCALL_VERIFY(num_entries > 0)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK)); + K_OOPS(K_SYSCALL_VERIFY(num_entries > 0)); return z_impl_k_stack_alloc_init(stack, num_entries); } #include @@ -132,7 +132,7 @@ int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_stack_push(struct k_stack *stack, stack_data_t data) { - Z_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); + K_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); return z_impl_k_stack_push(stack, data); } @@ -187,8 +187,8 @@ int z_impl_k_stack_pop(struct k_stack *stack, stack_data_t *data, static inline int z_vrfy_k_stack_pop(struct k_stack *stack, stack_data_t *data, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(data, sizeof(stack_data_t))); + K_OOPS(K_SYSCALL_OBJ(stack, K_OBJ_STACK)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, sizeof(stack_data_t))); return z_impl_k_stack_pop(stack, data, timeout); } #include diff --git a/kernel/thread.c b/kernel/thread.c index 42327565eff..7741f7acc66 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -433,7 +433,7 @@ void z_impl_k_thread_start(struct k_thread *thread) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_thread_start(struct k_thread *thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_thread_start(thread); } #include @@ -728,13 +728,13 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, struct k_object *stack_object; /* The thread and stack objects *must* be in an uninitialized state */ - Z_OOPS(K_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD)); /* No need to check z_stack_is_user_capable(), it won't be in the * object table if it isn't */ stack_object = k_object_find(stack); - Z_OOPS(K_SYSCALL_VERIFY_MSG(k_object_validation_check(stack_object, stack, + K_OOPS(K_SYSCALL_VERIFY_MSG(k_object_validation_check(stack_object, stack, K_OBJ_THREAD_STACK_ELEMENT, _OBJ_INIT_FALSE) == 0, "bad stack object")); @@ -742,7 +742,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, /* Verify that the stack size passed in is OK by computing the total * size and comparing it with the size value in the object metadata */ - Z_OOPS(K_SYSCALL_VERIFY_MSG(!size_add_overflow(K_THREAD_STACK_RESERVED, + K_OOPS(K_SYSCALL_VERIFY_MSG(!size_add_overflow(K_THREAD_STACK_RESERVED, stack_size, &total_size), "stack size overflow (%zu+%zu)", stack_size, @@ -756,21 +756,21 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, #else stack_obj_size = stack_object->data.stack_size; #endif - Z_OOPS(K_SYSCALL_VERIFY_MSG(total_size <= stack_obj_size, + K_OOPS(K_SYSCALL_VERIFY_MSG(total_size <= stack_obj_size, "stack size %zu is too big, max is %zu", total_size, stack_obj_size)); /* User threads may only create other user threads and they can't * be marked as essential */ - Z_OOPS(K_SYSCALL_VERIFY(options & K_USER)); - Z_OOPS(K_SYSCALL_VERIFY(!(options & K_ESSENTIAL))); + K_OOPS(K_SYSCALL_VERIFY(options & K_USER)); + K_OOPS(K_SYSCALL_VERIFY(!(options & K_ESSENTIAL))); /* Check validity of prio argument; must be the same or worse priority * than the caller */ - Z_OOPS(K_SYSCALL_VERIFY(_is_valid_prio(prio, NULL))); - Z_OOPS(K_SYSCALL_VERIFY(z_is_prio_lower_or_equal(prio, + K_OOPS(K_SYSCALL_VERIFY(_is_valid_prio(prio, NULL))); + K_OOPS(K_SYSCALL_VERIFY(z_is_prio_lower_or_equal(prio, _current->base.prio))); z_setup_new_thread(new_thread, stack, stack_size, @@ -966,7 +966,7 @@ int z_impl_k_float_enable(struct k_thread *thread, unsigned int options) #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_float_disable(struct k_thread *thread) { - Z_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD)); return z_impl_k_float_disable(thread); } #include @@ -1085,7 +1085,7 @@ int z_vrfy_k_thread_stack_space_get(const struct k_thread *thread, static inline k_ticks_t z_vrfy_k_thread_timeout_remaining_ticks( const struct k_thread *t) { - Z_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); return z_impl_k_thread_timeout_remaining_ticks(t); } #include @@ -1093,7 +1093,7 @@ static inline k_ticks_t z_vrfy_k_thread_timeout_remaining_ticks( static inline k_ticks_t z_vrfy_k_thread_timeout_expires_ticks( const struct k_thread *t) { - Z_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ(t, K_OBJ_THREAD)); return z_impl_k_thread_timeout_expires_ticks(t); } #include diff --git a/kernel/timer.c b/kernel/timer.c index 09ec65541c1..48cc69baffe 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -185,7 +185,7 @@ static inline void z_vrfy_k_timer_start(struct k_timer *timer, k_timeout_t duration, k_timeout_t period) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_start(timer, duration, period); } #include @@ -218,7 +218,7 @@ void z_impl_k_timer_stop(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_timer_stop(struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_stop(timer); } #include @@ -238,7 +238,7 @@ uint32_t z_impl_k_timer_status_get(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline uint32_t z_vrfy_k_timer_status_get(struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_status_get(timer); } #include @@ -306,7 +306,7 @@ uint32_t z_impl_k_timer_status_sync(struct k_timer *timer) #ifdef CONFIG_USERSPACE static inline uint32_t z_vrfy_k_timer_status_sync(struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_status_sync(timer); } #include @@ -314,7 +314,7 @@ static inline uint32_t z_vrfy_k_timer_status_sync(struct k_timer *timer) static inline k_ticks_t z_vrfy_k_timer_remaining_ticks( const struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_remaining_ticks(timer); } #include @@ -322,14 +322,14 @@ static inline k_ticks_t z_vrfy_k_timer_remaining_ticks( static inline k_ticks_t z_vrfy_k_timer_expires_ticks( const struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_expires_ticks(timer); } #include static inline void *z_vrfy_k_timer_user_data_get(const struct k_timer *timer) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); return z_impl_k_timer_user_data_get(timer); } #include @@ -337,7 +337,7 @@ static inline void *z_vrfy_k_timer_user_data_get(const struct k_timer *timer) static inline void z_vrfy_k_timer_user_data_set(struct k_timer *timer, void *user_data) { - Z_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); + K_OOPS(K_SYSCALL_OBJ(timer, K_OBJ_TIMER)); z_impl_k_timer_user_data_set(timer, user_data); } #include diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 616b6954182..a1cf9f9d7a3 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -58,9 +58,9 @@ static inline void z_vrfy_k_object_access_grant(const void *object, { struct k_object *ko; - Z_OOPS(K_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); + K_OOPS(K_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD)); ko = validate_any_object(object); - Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", + K_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", object)); k_thread_perms_set(ko, thread); } @@ -71,7 +71,7 @@ static inline void z_vrfy_k_object_release(const void *object) struct k_object *ko; ko = validate_any_object((void *)object); - Z_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", + K_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", (void *)object)); k_thread_perms_clear(ko, _current); } diff --git a/lib/libc/arcmwdt/libc-hooks.c b/lib/libc/arcmwdt/libc-hooks.c index 3a79f45afe7..babf24ebda8 100644 --- a/lib/libc/arcmwdt/libc-hooks.c +++ b/lib/libc/arcmwdt/libc-hooks.c @@ -56,7 +56,7 @@ int z_impl_zephyr_write_stdout(const void *buffer, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes) { - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); return z_impl_zephyr_write_stdout(buf, nbytes); } #include diff --git a/lib/libc/minimal/source/stdout/stdout_console.c b/lib/libc/minimal/source/stdout/stdout_console.c index ab3777fbf91..33ea7ffaa66 100644 --- a/lib/libc/minimal/source/stdout/stdout_console.c +++ b/lib/libc/minimal/source/stdout/stdout_console.c @@ -101,7 +101,7 @@ static inline size_t z_vrfy_zephyr_fwrite(const void *ZRESTRICT ptr, FILE *ZRESTRICT stream) { - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(ptr, nitems, size)); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(ptr, nitems, size)); return z_impl_zephyr_fwrite((const void *ZRESTRICT)ptr, size, nitems, (FILE *ZRESTRICT)stream); } diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index 294db355e5a..88a83742a50 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -181,7 +181,7 @@ int z_impl_zephyr_read_stdin(char *buf, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_read_stdin(char *buf, int nbytes) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, nbytes)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, nbytes)); return z_impl_zephyr_read_stdin((char *)buf, nbytes); } #include @@ -204,7 +204,7 @@ int z_impl_zephyr_write_stdout(const void *buffer, int nbytes) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes) { - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, nbytes)); return z_impl_zephyr_write_stdout((const void *)buf, nbytes); } #include diff --git a/lib/os/printk.c b/lib/os/printk.c index 970574528ee..f46b950ffe4 100644 --- a/lib/os/printk.c +++ b/lib/os/printk.c @@ -174,7 +174,7 @@ void z_impl_k_str_out(char *c, size_t n) #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_str_out(char *c, size_t n) { - Z_OOPS(K_SYSCALL_MEMORY_READ(c, n)); + K_OOPS(K_SYSCALL_MEMORY_READ(c, n)); z_impl_k_str_out((char *)c, n); } #include diff --git a/lib/posix/clock.c b/lib/posix/clock.c index 98d6a8161da..d7ca3969aa8 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -68,7 +68,7 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) #ifdef CONFIG_USERSPACE int z_vrfy_clock_gettime(clockid_t clock_id, struct timespec *ts) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); return z_impl_clock_gettime(clock_id, ts); } #include diff --git a/scripts/build/gen_syscalls.py b/scripts/build/gen_syscalls.py index 8703352b133..68d0f15f48b 100755 --- a/scripts/build/gen_syscalls.py +++ b/scripts/build/gen_syscalls.py @@ -322,7 +322,7 @@ def marshall_defs(func_name, func_type, args): mrsh += "\t(void) arg%d;\t/* unused */\n" % unused_arg if nmrsh > 6: - mrsh += ("\tZ_OOPS(K_SYSCALL_MEMORY_READ(more, " + mrsh += ("\tK_OOPS(K_SYSCALL_MEMORY_READ(more, " + str(nmrsh - 5) + " * sizeof(uintptr_t)));\n") argnum = 0 @@ -349,7 +349,7 @@ def marshall_defs(func_name, func_type, args): if need_split(func_type): ptr = "((uint64_t *)%s)" % mrsh_rval(nmrsh - 1, nmrsh) - mrsh += "\t" + "Z_OOPS(K_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr + mrsh += "\t" + "K_OOPS(K_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr mrsh += "\t" + "*%s = ret;\n" % ptr mrsh += "\t" + "_current->syscall_frame = NULL;\n" mrsh += "\t" + "return 0;\n" diff --git a/subsys/logging/log_mgmt.c b/subsys/logging/log_mgmt.c index eb7d82f483a..6336e4a8385 100644 --- a/subsys/logging/log_mgmt.c +++ b/subsys/logging/log_mgmt.c @@ -449,13 +449,13 @@ uint32_t z_vrfy_log_filter_set(struct log_backend const *const backend, int16_t src_id, uint32_t level) { - Z_OOPS(K_SYSCALL_VERIFY_MSG(backend == NULL, + K_OOPS(K_SYSCALL_VERIFY_MSG(backend == NULL, "Setting per-backend filters from user mode is not supported")); - Z_OOPS(K_SYSCALL_VERIFY_MSG(domain_id == Z_LOG_LOCAL_DOMAIN_ID, + K_OOPS(K_SYSCALL_VERIFY_MSG(domain_id == Z_LOG_LOCAL_DOMAIN_ID, "Invalid log domain_id")); - Z_OOPS(K_SYSCALL_VERIFY_MSG(src_id < (int16_t)log_src_cnt_get(domain_id), + K_OOPS(K_SYSCALL_VERIFY_MSG(src_id < (int16_t)log_src_cnt_get(domain_id), "Invalid log source id")); - Z_OOPS(K_SYSCALL_VERIFY_MSG( + K_OOPS(K_SYSCALL_VERIFY_MSG( (level <= LOG_LEVEL_DBG), "Invalid log level")); diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 72a5de8e3cc..9f5a3306f94 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -1589,7 +1589,7 @@ static inline int z_vrfy_net_if_ipv6_addr_lookup_by_index( { struct in6_addr addr_v6; - Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + K_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_lookup_by_index(&addr_v6); } @@ -1929,7 +1929,7 @@ bool z_vrfy_net_if_ipv6_addr_add_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + K_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_add_by_index(index, &addr_v6, @@ -1965,7 +1965,7 @@ bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); + K_OOPS(k_usermode_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6))); return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6); } @@ -3526,7 +3526,7 @@ static inline int z_vrfy_net_if_ipv4_addr_lookup_by_index( { struct in_addr addr_v4; - Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + K_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return z_impl_net_if_ipv4_addr_lookup_by_index(&addr_v4); } @@ -3578,7 +3578,7 @@ bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&netmask_addr, (void *)netmask, + K_OOPS(k_usermode_from_copy(&netmask_addr, (void *)netmask, sizeof(netmask_addr))); return z_impl_net_if_ipv4_set_netmask_by_index(index, &netmask_addr); @@ -3631,7 +3631,7 @@ bool z_vrfy_net_if_ipv4_set_gw_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr))); + K_OOPS(k_usermode_from_copy(&gw_addr, (void *)gw, sizeof(gw_addr))); return z_impl_net_if_ipv4_set_gw_by_index(index, &gw_addr); } @@ -3805,7 +3805,7 @@ bool z_vrfy_net_if_ipv4_addr_add_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + K_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return z_impl_net_if_ipv4_addr_add_by_index(index, &addr_v4, @@ -3841,7 +3841,7 @@ bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index, return false; } - Z_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); + K_OOPS(k_usermode_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4))); return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4); } diff --git a/subsys/net/ip/utils.c b/subsys/net/ip/utils.c index 7333f140805..0e3bbce5d33 100644 --- a/subsys/net/ip/utils.c +++ b/subsys/net/ip/utils.c @@ -304,14 +304,14 @@ char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src, char *out; const void *addr; - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); if (family == AF_INET) { - Z_OOPS(k_usermode_from_copy(&addr4, (const void *)src, + K_OOPS(k_usermode_from_copy(&addr4, (const void *)src, sizeof(addr4))); addr = &addr4; } else if (family == AF_INET6) { - Z_OOPS(k_usermode_from_copy(&addr6, (const void *)src, + K_OOPS(k_usermode_from_copy(&addr6, (const void *)src, sizeof(addr6))); addr = &addr6; } else { @@ -323,7 +323,7 @@ char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src, return 0; } - Z_OOPS(k_usermode_to_copy((void *)dst, str, MIN(size, sizeof(str)))); + K_OOPS(k_usermode_to_copy((void *)dst, str, MIN(size, sizeof(str)))); return dst; } @@ -488,14 +488,14 @@ int z_vrfy_net_addr_pton(sa_family_t family, const char *src, return -EINVAL; } - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size)); err = z_impl_net_addr_pton(family, str, addr); if (err) { return err; } - Z_OOPS(k_usermode_to_copy((void *)dst, addr, size)); + K_OOPS(k_usermode_to_copy((void *)dst, addr, size)); return 0; } diff --git a/subsys/net/lib/sockets/getaddrinfo.c b/subsys/net/lib/sockets/getaddrinfo.c index b5285feb156..70a611a3f4a 100644 --- a/subsys/net/lib/sockets/getaddrinfo.c +++ b/subsys/net/lib/sockets/getaddrinfo.c @@ -281,10 +281,10 @@ static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host, uint32_t ret; if (hints) { - Z_OOPS(k_usermode_from_copy(&hints_copy, (void *)hints, + K_OOPS(k_usermode_from_copy(&hints_copy, (void *)hints, sizeof(hints_copy))); } - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo))); if (service) { service_copy = k_usermode_string_alloc_copy((char *)service, 64); diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index 80f7a61ea22..417a3b34fb1 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -350,7 +350,7 @@ int z_vrfy_zsock_socketpair(int family, int type, int proto, int *sv) ret = z_impl_zsock_socketpair(family, type, proto, tmp); if (ret == 0) { - Z_OOPS(k_usermode_to_copy(sv, tmp, sizeof(tmp))); + K_OOPS(k_usermode_to_copy(sv, tmp, sizeof(tmp))); } out: diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 050b0c1c533..9dadc452a26 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -482,8 +482,8 @@ static inline int z_vrfy_zsock_bind(int sock, const struct sockaddr *addr, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); + K_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + K_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_bind(sock, (struct sockaddr *)&dest_addr_copy, addrlen); @@ -561,8 +561,8 @@ int z_vrfy_zsock_connect(int sock, const struct sockaddr *addr, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); + K_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + K_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)addr, addrlen)); return z_impl_zsock_connect(sock, (struct sockaddr *)&dest_addr_copy, addrlen); @@ -693,14 +693,14 @@ static inline int z_vrfy_zsock_accept(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(addrlen && k_usermode_from_copy(&addrlen_copy, addrlen, + K_OOPS(addrlen && k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); - Z_OOPS(addr && K_SYSCALL_MEMORY_WRITE(addr, addrlen ? addrlen_copy : 0)); + K_OOPS(addr && K_SYSCALL_MEMORY_WRITE(addr, addrlen ? addrlen_copy : 0)); ret = z_impl_zsock_accept(sock, (struct sockaddr *)addr, addrlen ? &addrlen_copy : NULL); - Z_OOPS(ret >= 0 && addrlen && k_usermode_to_copy(addrlen, &addrlen_copy, + K_OOPS(ret >= 0 && addrlen && k_usermode_to_copy(addrlen, &addrlen_copy, sizeof(socklen_t))); return ret; @@ -862,10 +862,10 @@ ssize_t z_vrfy_zsock_sendto(int sock, const void *buf, size_t len, int flags, { struct sockaddr_storage dest_addr_copy; - Z_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); + K_OOPS(K_SYSCALL_MEMORY_READ(buf, len)); if (dest_addr) { - Z_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); - Z_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)dest_addr, + K_OOPS(K_SYSCALL_VERIFY(addrlen <= sizeof(dest_addr_copy))); + K_OOPS(k_usermode_from_copy(&dest_addr_copy, (void *)dest_addr, addrlen)); } @@ -950,7 +950,7 @@ static inline ssize_t z_vrfy_zsock_sendmsg(int sock, size_t i; int ret; - Z_OOPS(k_usermode_from_copy(&msg_copy, (void *)msg, sizeof(msg_copy))); + K_OOPS(k_usermode_from_copy(&msg_copy, (void *)msg, sizeof(msg_copy))); msg_copy.msg_name = NULL; msg_copy.msg_control = NULL; @@ -1520,17 +1520,17 @@ ssize_t z_vrfy_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, } if (addrlen) { - Z_OOPS(k_usermode_from_copy(&addrlen_copy, addrlen, + K_OOPS(k_usermode_from_copy(&addrlen_copy, addrlen, sizeof(socklen_t))); } - Z_OOPS(src_addr && K_SYSCALL_MEMORY_WRITE(src_addr, addrlen_copy)); + K_OOPS(src_addr && K_SYSCALL_MEMORY_WRITE(src_addr, addrlen_copy)); ret = z_impl_zsock_recvfrom(sock, (void *)buf, max_len, flags, (struct sockaddr *)src_addr, addrlen ? &addrlen_copy : NULL); if (addrlen) { - Z_OOPS(k_usermode_to_copy(addrlen, &addrlen_copy, + K_OOPS(k_usermode_to_copy(addrlen, &addrlen_copy, sizeof(socklen_t))); } @@ -1609,7 +1609,7 @@ static inline int z_vrfy_zsock_ioctl(int sock, unsigned long request, va_list ar int *avail; avail = va_arg(args, int *); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(avail, sizeof(*avail))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(avail, sizeof(*avail))); break; } @@ -1954,9 +1954,9 @@ static inline int z_vrfy_zsock_inet_pton(sa_family_t family, return -1; } - Z_OOPS(k_usermode_string_copy(src_copy, (char *)src, sizeof(src_copy))); + K_OOPS(k_usermode_string_copy(src_copy, (char *)src, sizeof(src_copy))); ret = z_impl_zsock_inet_pton(family, src_copy, dst_copy); - Z_OOPS(k_usermode_to_copy(dst, dst_copy, dst_size)); + K_OOPS(k_usermode_to_copy(dst, dst_copy, dst_size)); return ret; } @@ -2175,13 +2175,13 @@ int z_vrfy_zsock_getsockopt(int sock, int level, int optname, kernel_optval = k_usermode_alloc_from_copy((const void *)optval, kernel_optlen); - Z_OOPS(!kernel_optval); + K_OOPS(!kernel_optval); ret = z_impl_zsock_getsockopt(sock, level, optname, kernel_optval, &kernel_optlen); - Z_OOPS(k_usermode_to_copy((void *)optval, kernel_optval, kernel_optlen)); - Z_OOPS(k_usermode_to_copy((void *)optlen, &kernel_optlen, + K_OOPS(k_usermode_to_copy((void *)optval, kernel_optval, kernel_optlen)); + K_OOPS(k_usermode_to_copy((void *)optlen, &kernel_optlen, sizeof(socklen_t))); k_free(kernel_optval); @@ -2518,7 +2518,7 @@ int z_vrfy_zsock_setsockopt(int sock, int level, int optname, int ret; kernel_optval = k_usermode_alloc_from_copy((const void *)optval, optlen); - Z_OOPS(!kernel_optval); + K_OOPS(!kernel_optval); ret = z_impl_zsock_setsockopt(sock, level, optname, kernel_optval, optlen); @@ -2591,7 +2591,7 @@ static inline int z_vrfy_zsock_getpeername(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, + K_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); if (K_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { @@ -2670,7 +2670,7 @@ static inline int z_vrfy_zsock_getsockname(int sock, struct sockaddr *addr, socklen_t addrlen_copy; int ret; - Z_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, + K_OOPS(k_usermode_from_copy(&addrlen_copy, (void *)addrlen, sizeof(socklen_t))); if (K_SYSCALL_MEMORY_WRITE(addr, addrlen_copy)) { diff --git a/subsys/net/lib/sockets/sockets_misc.c b/subsys/net/lib/sockets/sockets_misc.c index 65b9b27af2d..fb3750e110a 100644 --- a/subsys/net/lib/sockets/sockets_misc.c +++ b/subsys/net/lib/sockets/sockets_misc.c @@ -20,7 +20,7 @@ int z_impl_zsock_gethostname(char *buf, size_t len) #ifdef CONFIG_USERSPACE static inline int z_vrfy_zsock_gethostname(char *buf, size_t len) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, len)); return z_impl_zsock_gethostname(buf, len); } #include diff --git a/subsys/random/rand32_handlers.c b/subsys/random/rand32_handlers.c index e51d3d0c2b2..38344a00190 100644 --- a/subsys/random/rand32_handlers.c +++ b/subsys/random/rand32_handlers.c @@ -15,7 +15,7 @@ static inline uint32_t z_vrfy_sys_rand32_get(void) static inline void z_vrfy_sys_rand_get(void *dst, size_t len) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); z_impl_sys_rand_get(dst, len); } @@ -24,7 +24,7 @@ static inline void z_vrfy_sys_rand_get(void *dst, size_t len) #ifdef CONFIG_CSPRNG_ENABLED static inline int z_vrfy_sys_csrand_get(void *dst, size_t len) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, len)); return z_impl_sys_csrand_get(dst, len); } diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_handlers.c index 30c876e056f..3930d5bdee9 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_handlers.c @@ -54,7 +54,7 @@ static inline bool rtio_vrfy_sqe(struct rtio_sqe *sqe) static inline void z_vrfy_rtio_release_buffer(struct rtio *r, void *buff, uint32_t buff_len) { - Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); z_impl_rtio_release_buffer(r, buff, buff_len); } #include @@ -62,10 +62,10 @@ static inline void z_vrfy_rtio_release_buffer(struct rtio *r, void *buff, uint32 static inline int z_vrfy_rtio_cqe_get_mempool_buffer(const struct rtio *r, struct rtio_cqe *cqe, uint8_t **buff, uint32_t *buff_len) { - Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(K_SYSCALL_MEMORY_READ(cqe, sizeof(struct rtio_cqe))); - Z_OOPS(K_SYSCALL_MEMORY_READ(buff, sizeof(void *))); - Z_OOPS(K_SYSCALL_MEMORY_READ(buff_len, sizeof(uint32_t))); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + K_OOPS(K_SYSCALL_MEMORY_READ(cqe, sizeof(struct rtio_cqe))); + K_OOPS(K_SYSCALL_MEMORY_READ(buff, sizeof(void *))); + K_OOPS(K_SYSCALL_MEMORY_READ(buff_len, sizeof(uint32_t))); return z_impl_rtio_cqe_get_mempool_buffer(r, cqe, buff, buff_len); } #include @@ -79,9 +79,9 @@ static inline int z_vrfy_rtio_sqe_cancel(struct rtio_sqe *sqe) static inline int z_vrfy_rtio_sqe_copy_in_get_handles(struct rtio *r, const struct rtio_sqe *sqes, struct rtio_sqe **handle, size_t sqe_count) { - Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe))); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe))); struct rtio_sqe *sqe; uint32_t acquirable = rtio_sqe_acquirable(r); @@ -100,7 +100,7 @@ static inline int z_vrfy_rtio_sqe_copy_in_get_handles(struct rtio *r, const stru if (!rtio_vrfy_sqe(sqe)) { rtio_sqe_drop_all(r); - Z_OOPS(true); + K_OOPS(true); } } @@ -114,9 +114,9 @@ static inline int z_vrfy_rtio_cqe_copy_out(struct rtio *r, size_t cqe_count, k_timeout_t timeout) { - Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); - Z_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(cqes, cqe_count, sizeof(struct rtio_cqe))); + K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(cqes, cqe_count, sizeof(struct rtio_cqe))); return z_impl_rtio_cqe_copy_out(r, cqes, cqe_count, timeout); } @@ -124,10 +124,10 @@ static inline int z_vrfy_rtio_cqe_copy_out(struct rtio *r, static inline int z_vrfy_rtio_submit(struct rtio *r, uint32_t wait_count) { - Z_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); #ifdef CONFIG_RTIO_SUBMIT_SEM - Z_OOPS(K_SYSCALL_OBJ(r->submit_sem, K_OBJ_SEM)); + K_OOPS(K_SYSCALL_OBJ(r->submit_sem, K_OBJ_SEM)); #endif return z_impl_rtio_submit(r, wait_count); diff --git a/tests/kernel/mem_protect/syscalls/src/main.c b/tests/kernel/mem_protect/syscalls/src/main.c index 258237d99e0..ed57d7e9120 100644 --- a/tests/kernel/mem_protect/syscalls/src/main.c +++ b/tests/kernel/mem_protect/syscalls/src/main.c @@ -59,7 +59,7 @@ static inline size_t z_vrfy_string_nlen(char *src, size_t maxlen, int *err) err_copy = -1; } - Z_OOPS(k_usermode_to_copy((int *)err, &err_copy, sizeof(err_copy))); + K_OOPS(k_usermode_to_copy((int *)err, &err_copy, sizeof(err_copy))); return ret; } diff --git a/tests/kernel/threads/thread_stack/src/main.c b/tests/kernel/threads/thread_stack/src/main.c index b3bfe73c0b8..a2ea5e95753 100644 --- a/tests/kernel/threads/thread_stack/src/main.c +++ b/tests/kernel/threads/thread_stack/src/main.c @@ -41,8 +41,8 @@ void z_impl_stack_info_get(char **start_addr, size_t *size) static inline void z_vrfy_stack_info_get(char **start_addr, size_t *size) { - Z_OOPS(K_SYSCALL_MEMORY_WRITE(start_addr, sizeof(uintptr_t))); - Z_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(start_addr, sizeof(uintptr_t))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size_t))); z_impl_stack_info_get(start_addr, size); } diff --git a/tests/ztest/error_hook/README.txt b/tests/ztest/error_hook/README.txt index 5ca44e9e330..1304cce5ab0 100644 --- a/tests/ztest/error_hook/README.txt +++ b/tests/ztest/error_hook/README.txt @@ -80,7 +80,7 @@ test_catch_assert_in_isr test_catch_z_oops - Pass illegal address by syscall, then inside the syscall handler, the - Z_OOPS macro will trigger a fatal error that will get caught (as expected). + K_OOPS macro will trigger a fatal error that will get caught (as expected). diff --git a/tests/ztest/error_hook/src/main.c b/tests/ztest/error_hook/src/main.c index cba35ce46b4..e38b3111cf3 100644 --- a/tests/ztest/error_hook/src/main.c +++ b/tests/ztest/error_hook/src/main.c @@ -31,7 +31,7 @@ enum { ZTEST_CATCH_FATAL_IN_ISR, ZTEST_CATCH_ASSERT_FAIL, ZTEST_CATCH_ASSERT_IN_ISR, - ZTEST_CATCH_USER_FATAL_Z_OOPS, + ZTEST_CATCH_USER_FATAL_K_OOPS, ZTEST_ERROR_MAX } error_case_type; @@ -161,7 +161,7 @@ void ztest_post_fatal_error_hook(unsigned int reason, case ZTEST_CATCH_FATAL_DIVIDE_ZERO: case ZTEST_CATCH_FATAL_K_PANIC: case ZTEST_CATCH_FATAL_K_OOPS: - case ZTEST_CATCH_USER_FATAL_Z_OOPS: + case ZTEST_CATCH_USER_FATAL_K_OOPS: zassert_true(true); break; @@ -338,7 +338,7 @@ static void trigger_z_oops(void) /* Set up a dummy syscall frame, pointing to a valid area in memory. */ _current->syscall_frame = _image_ram_start; - Z_OOPS(true); + K_OOPS(true); } /** @@ -351,7 +351,7 @@ static void trigger_z_oops(void) */ ZTEST(error_hook_tests, test_catch_z_oops) { - case_type = ZTEST_CATCH_USER_FATAL_Z_OOPS; + case_type = ZTEST_CATCH_USER_FATAL_K_OOPS; ztest_set_fault_valid(true); trigger_z_oops(); From 7cacfe84030f7bcdf6c492f320efe47831e61f4c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:25:41 +0000 Subject: [PATCH 3031/4498] doc: define internal API group Group all internal APIs under this doxygen group. Signed-off-by: Anas Nashif --- doc/_doxygen/groups.dox | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/_doxygen/groups.dox b/doc/_doxygen/groups.dox index 7aca51503db..65b229a0ce9 100644 --- a/doc/_doxygen/groups.dox +++ b/doc/_doxygen/groups.dox @@ -1,5 +1,11 @@ /** +@defgroup internal_api Internal and System API +@brief Internal and System API +@{ + +@} + @defgroup os_services Operating System Services @brief Operating System Services @{ From 864ebfec213b614ed5363580a0ad89873428374b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:29:18 +0000 Subject: [PATCH 3032/4498] syscall/userspace: doc: include in doxygen Include syscall handler API as internal APIs in doxygen. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 568c0e7b693..45b410a7b90 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -3,12 +3,17 @@ * * SPDX-License-Identifier: Apache-2.0 */ - - #ifndef ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_ #define ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_ -#ifdef CONFIG_USERSPACE +/** + * @brief User mode and Syscall APIs + * @defgroup syscall_apis User mode and Syscall APIs + * @ingroup internal_api + * @{ + */ + +#if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__) #ifndef _ASMLANGUAGE #include @@ -547,5 +552,8 @@ static inline int k_object_validation_check(struct k_object *ko, #endif /* _ASMLANGUAGE */ #endif /* CONFIG_USERSPACE */ +/** + * @} + */ #endif /* ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_ */ From b5a069db50db0cd2a413ecde0c9236f4d0e36151 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:47:09 +0000 Subject: [PATCH 3033/4498] syscall: doc: add a note about the API being internal Add a note to all internal APIs signifying they are internal and should not be used outside of the zephyr code base. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 71 ++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 45b410a7b90..84aa5b5837c 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -48,6 +48,9 @@ enum _obj_init_check { * user thread. If the system call was invoked from supervisor mode, * or we are not handling a system call, this will return false. * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * * @return whether the current context is handling a syscall for a user * mode thread */ @@ -78,6 +81,9 @@ static inline bool k_is_in_user_syscall(void) * doesn't matter * @param init Indicate whether the object needs to already be in initialized * or uninitialized state, or that we don't care + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * * @return 0 If the object is valid * -EBADF if not a valid object of the specified type * -EPERM If the caller does not have permissions @@ -93,6 +99,9 @@ int k_object_validate(struct k_object *ko, enum k_objects otype, * @param obj Kernel object we were trying to verify * @param ko If retval=-EPERM, struct k_object * that was looked up, or NULL * @param otype Expected type of the kernel object + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ void k_object_dump_error(int retval, const void *obj, struct k_object *ko, enum k_objects otype); @@ -106,6 +115,9 @@ void k_object_dump_error(int retval, const void *obj, * @param obj Address of kernel object to get metadata * @return Kernel object's metadata, or NULL if the parameter wasn't the * memory address of a kernel object + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ struct k_object *k_object_find(const void *obj); @@ -116,6 +128,9 @@ typedef void (*_wordlist_cb_func_t)(struct k_object *ko, void *context); * * @param func function to run on each struct k_object * @param context Context pointer to pass to each invocation + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); @@ -124,6 +139,9 @@ void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context); * * @param parent Parent thread, to get permissions from * @param child Child thread, to copy permissions to + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child); @@ -132,6 +150,9 @@ void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child); * * @param ko Kernel object metadata to update * @param thread The thread to grant permission + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ void k_thread_perms_set(struct k_object *ko, struct k_thread *thread); @@ -140,15 +161,21 @@ void k_thread_perms_set(struct k_object *ko, struct k_thread *thread); * * @param ko Kernel object metadata to update * @param thread The thread to grant permission + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * */ void k_thread_perms_clear(struct k_object *ko, struct k_thread *thread); -/* +/** * Revoke access to all objects for the provided thread * - * NOTE: Unlike k_thread_perms_clear(), this function will not clear + * @note Unlike k_thread_perms_clear(), this function will not clear * permissions on public objects. * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + * * @param thread Thread object to revoke access */ void k_thread_perms_all_clear(struct k_thread *thread); @@ -160,6 +187,8 @@ void k_thread_perms_all_clear(struct k_thread *thread); * that were released back to an object pool. * * @param object Address of the kernel object + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ void k_object_uninit(const void *obj); @@ -179,6 +208,8 @@ void k_object_uninit(const void *obj); * granted access to it. * * @param object Address of the kernel object + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ void k_object_recycle(const void *obj); @@ -204,6 +235,8 @@ void k_object_recycle(const void *obj); * @return undefined on error, or strlen(src) if that is less than maxlen, or * maxlen if there were no NULL terminating characters within the * first maxlen bytes. + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ static inline size_t k_usermode_string_nlen(const char *src, size_t maxlen, int *err) @@ -225,6 +258,8 @@ static inline size_t k_usermode_string_nlen(const char *src, size_t maxlen, * @param size Size of the memory buffer * @return An allocated buffer with the data copied within it, or NULL * if some error condition occurred + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ void *k_usermode_alloc_from_copy(const void *src, size_t size); @@ -240,6 +275,8 @@ void *k_usermode_alloc_from_copy(const void *src, size_t size); * @param size Number of bytes to copy * @retval 0 On success * @retval EFAULT On memory access error + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ int k_usermode_from_copy(void *dst, const void *src, size_t size); @@ -255,6 +292,8 @@ int k_usermode_from_copy(void *dst, const void *src, size_t size); * @param size Number of bytes to copy * @retval 0 On success * @retval EFAULT On memory access error + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ int k_usermode_to_copy(void *dst, const void *src, size_t size); @@ -271,6 +310,8 @@ int k_usermode_to_copy(void *dst, const void *src, size_t size); * @param src Source string pointer, in userspace * @param maxlen Maximum size of the string including trailing NULL * @return The duplicated string, or NULL if an error occurred. + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ char *k_usermode_string_alloc_copy(const char *src, size_t maxlen); @@ -289,6 +330,8 @@ char *k_usermode_string_alloc_copy(const char *src, size_t maxlen); * @retval EINVAL if the source string is too long with respect * to maxlen * @retval EFAULT On memory access error + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); @@ -311,6 +354,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param fmt Printf-style format string (followed by appropriate variadic * arguments) to print on verification failure * @return False on success, True on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_VERIFY_MSG(expr, fmt, ...) ({ \ bool expr_copy = !(expr); \ @@ -332,6 +377,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param expr Boolean expression to verify, a false result will trigger an * oops. A stringified version of this expression will be printed. * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr) @@ -350,6 +397,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param write If the thread should be able to write to this memory, not just * read it * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_MEMORY(ptr, size, write) \ K_SYSCALL_VERIFY_MSG(arch_buffer_validate((void *)ptr, size, write) \ @@ -370,6 +419,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param ptr Memory area to examine * @param size Size of the memory area * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_MEMORY_READ(ptr, size) \ K_SYSCALL_MEMORY(ptr, size, 0) @@ -386,6 +437,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param ptr Memory area to examine * @param size Size of the memory area * @param 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_MEMORY_WRITE(ptr, size) \ K_SYSCALL_MEMORY(ptr, size, 1) @@ -412,6 +465,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param nmemb Number of elements in the array * @param size Size of each array element * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \ K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0) @@ -427,6 +482,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * @param nmemb Number of elements in the array * @param size Size of each array element * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) @@ -466,6 +523,8 @@ static inline int k_object_validation_check(struct k_object *ko, * @param api_struct Name of the driver API struct (e.g. gpio_driver_api) * @param op Driver operation (e.g. manage_callback) * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_DRIVER_OP(ptr, api_name, op) \ ({ \ @@ -494,6 +553,8 @@ static inline int k_object_validation_check(struct k_object *ko, * @param _dtype Expected kernel object type for the provided device pointer * @param _api Expected driver API structure memory address * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \ ({ \ @@ -513,6 +574,8 @@ static inline int k_object_validation_check(struct k_object *ko, * @param ptr Untrusted kernel object pointer * @param type Expected kernel object type * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_OBJ(ptr, type) \ K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE) @@ -526,6 +589,8 @@ static inline int k_object_validation_check(struct k_object *ko, * @param ptr Untrusted kernel object pointer * @param type Expected kernel object type * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_OBJ_INIT(ptr, type) \ @@ -542,6 +607,8 @@ static inline int k_object_validation_check(struct k_object *ko, * @param ptr Untrusted kernel object pointer * @param type Expected kernel object type * @return 0 on success, nonzero on failure + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ #define K_SYSCALL_OBJ_NEVER_INIT(ptr, type) \ From 6358e2780b15afea337fce9e8c73b57cd6413e11 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 11:49:35 +0000 Subject: [PATCH 3034/4498] arch: doc: move arch interface to internal api group Also move architecture interface to the internal group. Signed-off-by: Anas Nashif --- include/zephyr/sys/arch_interface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index e350b1436c1..e694bce55cc 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -6,6 +6,7 @@ /** * @defgroup arch-interface Architecture Interface + * @ingroup internal_api * @brief Internal kernel APIs with public scope * * Any public kernel APIs that are implemented as inline functions and need to From 9028f137e547bb07c7c769a987906cd9a3b3e8a4 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 12:53:52 +0000 Subject: [PATCH 3035/4498] syscall: doc: fix doxygen Doxygen fixes for syscall APIs. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 12 ++++++---- .../zephyr/sys/internal/kobject_internal.h | 24 +++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 84aa5b5837c..9804b16d7c3 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -186,7 +186,8 @@ void k_thread_perms_all_clear(struct k_thread *thread); * Intended for thread objects upon thread exit, or for other kernel objects * that were released back to an object pool. * - * @param object Address of the kernel object + * @param obj Address of the kernel object + * * @note This is an internal API. Do not use unless you are extending * functionality in the Zephyr tree. */ @@ -207,7 +208,7 @@ void k_object_uninit(const void *obj); * The object will be marked as initialized and the calling thread * granted access to it. * - * @param object Address of the kernel object + * @param obj Address of the kernel object * @note This is an internal API. Do not use unless you are extending * functionality in the Zephyr tree. */ @@ -436,7 +437,8 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); * * @param ptr Memory area to examine * @param size Size of the memory area - * @param 0 on success, nonzero on failure + * @return 0 on success, nonzero on failure + * * @note This is an internal API. Do not use unless you are extending * functionality in the Zephyr tree. */ @@ -520,9 +522,11 @@ static inline int k_object_validation_check(struct k_object *ko, * Validates if the driver object is capable of performing a certain operation. * * @param ptr Untrusted device instance object pointer - * @param api_struct Name of the driver API struct (e.g. gpio_driver_api) + * @param api_name Name of the driver API struct (e.g. gpio_driver_api) * @param op Driver operation (e.g. manage_callback) + * * @return 0 on success, nonzero on failure + * * @note This is an internal API. Do not use unless you are extending * functionality in the Zephyr tree. */ diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index b7bf816ad78..3814836c8c8 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -14,8 +14,8 @@ extern "C" { * @cond INTERNAL */ -#ifdef CONFIG_USERSPACE -#ifdef CONFIG_GEN_PRIV_STACKS +#if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__) +#if defined(CONFIG_GEN_PRIV_STACKS) || defined(__DOXYGEN__) /* Metadata struct for K_OBJ_THREAD_STACK_ELEMENT */ struct z_stack_data { /* Size of the entire stack object, including reserved areas */ @@ -34,7 +34,7 @@ union k_object_data { /* Numerical thread ID for K_OBJ_THREAD */ unsigned int thread_id; -#ifdef CONFIG_GEN_PRIV_STACKS +#if defined(CONFIG_GEN_PRIV_STACKS) || defined(__DOXYGEN__) /* Metadata for K_OBJ_THREAD_STACK_ELEMENT */ const struct z_stack_data *stack_data; #else @@ -49,8 +49,13 @@ union k_object_data { int unused; }; -/* Table generated by gperf, these objects are retrieved via - * k_object_find() */ +/** + * @brief Table generated by gperf, these objects are retrieved via + * k_object_find(). + * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + */ struct k_object { void *name; uint8_t perms[CONFIG_MAX_THREAD_BYTES]; @@ -73,6 +78,9 @@ struct k_object_assignment { * functions. * * @param obj Address of the kernel object + * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ void k_object_init(const void *obj); @@ -105,6 +113,9 @@ static inline void k_object_init(const void *obj) * @return NULL on insufficient memory * @return A pointer to the associated k_object that is installed in the * kernel object tables + * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size); @@ -126,6 +137,9 @@ struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size); * @return NULL on insufficient memory * @return A pointer to the associated k_object that is installed in the * kernel object tables + * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. */ static inline struct k_object *k_object_create_dynamic(size_t size) { From 6ada378690a15cfd68c1ff213b99e1dab56ecf2f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 13:16:28 +0000 Subject: [PATCH 3036/4498] syscall: document K_OOPS Document K_OOPs using doxygen. Signed-off-by: Anas Nashif --- include/zephyr/internal/syscall_handler.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index 9804b16d7c3..f692c17dc1f 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -336,6 +336,17 @@ char *k_usermode_string_alloc_copy(const char *src, size_t maxlen); */ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); +/** + * @brief Induce a kernel oops + * + * This macro can be used to induce a kernel oops which will kill the + * calling thread. + * + * @param expr Expression to be evaluated + * + * @note This is an internal API. Do not use unless you are extending + * functionality in the Zephyr tree. + */ #define K_OOPS(expr) \ do { \ if (expr) { \ From 58ec905c0e676a5d2cfc765ca51c5ca6fff9de7d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Sep 2023 14:32:51 +0000 Subject: [PATCH 3037/4498] objects: add doxygen group for internal APIs Add objects to the internal doxygen group. Signed-off-by: Anas Nashif --- include/zephyr/sys/internal/kobject_internal.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index 3814836c8c8..fe02ed3cb8f 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -11,7 +11,9 @@ extern "C" { #endif /** - * @cond INTERNAL + * @defgroup usermode_internal_apis User Mode Internal APIs + * @ingroup internal_api + * @{ */ #if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__) @@ -170,10 +172,6 @@ static inline struct k_object *k_object_create_dynamic(size_t size) /** @} */ -/** - * @endcond INTERNAL - */ - #ifdef __cplusplus } #endif From ba9ebb7dbdb0828980f34cf40823a3025c70ecd1 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 14 Sep 2023 16:35:11 +0200 Subject: [PATCH 3038/4498] drivers: flash: stm32 qspi driver reads sfdp table Fix the SFDP command to be sent by the qspi driver to get the SFDP table from the NOR quad flash. Note that CONFIG_FLASH_STM32_QSPI=y and CONFIG_SPI_NOR=n HAL_DMA_Abort declared as weak to fix compilation error with stm32f7x Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_qspi.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index 4090cd41bbb..6a9f8a58557 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -336,8 +336,13 @@ static int qspi_read_jedec_id(const struct device *dev, uint8_t *id) static int qspi_read_sfdp(const struct device *dev, off_t addr, void *data, size_t size) { + struct flash_stm32_qspi_data *dev_data = dev->data; + HAL_StatusTypeDef hal_ret; + __ASSERT(data != NULL, "null destination"); + LOG_INF("Reading SFDP"); + QSPI_CommandTypeDef cmd = { .Instruction = JESD216_CMD_READ_SFDP, .Address = addr, @@ -346,9 +351,26 @@ static int qspi_read_sfdp(const struct device *dev, off_t addr, void *data, .InstructionMode = QSPI_INSTRUCTION_1_LINE, .AddressMode = QSPI_ADDRESS_1_LINE, .DataMode = QSPI_DATA_1_LINE, + .NbData = size, }; - return qspi_read_access(dev, &cmd, (uint8_t *)data, size); + hal_ret = HAL_QSPI_Command(&dev_data->hqspi, &cmd, + HAL_QSPI_TIMEOUT_DEFAULT_VALUE); + if (hal_ret != HAL_OK) { + LOG_ERR("%d: Failed to send SFDP instruction", hal_ret); + return -EIO; + } + + hal_ret = HAL_QSPI_Receive(&dev_data->hqspi, (uint8_t *)data, + HAL_QSPI_TIMEOUT_DEFAULT_VALUE); + if (hal_ret != HAL_OK) { + LOG_ERR("%d: Failed to read SFDP", hal_ret); + return -EIO; + } + + dev_data->cmd_status = 0; + + return 0; } static bool qspi_address_is_valid(const struct device *dev, off_t addr, @@ -615,6 +637,11 @@ static void qspi_dma_callback(const struct device *dev, void *arg, } #endif +__weak HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) +{ + return HAL_OK; +} + __weak HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) { return HAL_OK; From ce82348ccf8d75238d6ec5984995073addb9b851 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 15 Sep 2023 09:48:26 +0200 Subject: [PATCH 3039/4498] boards: arm: stm32h7b3 disco reads the SFDP table from NOR The sfdp table property is no more required in the DTS of the stm32h7b3i_dk as it is correctly read from the external NOR octoflash with the read-sfdp command. (since PR https://github.com/zephyrproject-rtos/zephyr/pull/62521) Signed-off-by: Francois Ramu --- boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts index e9acb61b820..35470174123 100644 --- a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -259,13 +259,6 @@ spi-bus-width = ; data-rate = ; status = "okay"; - sfdp-bfp = [ - 53 46 44 50 06 01 02 ff - 00 06 01 10 30 00 00 ff - C2 00 01 04 10 01 00 ff - 84 00 01 02 C0 00 00 ff - 00 00 00 00 - ]; partitions { compatible = "fixed-partitions"; From 6b87eedee02020392270305fac8258557598b074 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 15 Sep 2023 09:51:01 +0200 Subject: [PATCH 3040/4498] samples: drivers: jesd216 reading jedec IDs from stm32 boards Add the stm32-ospi-nor or stm32-qspi-nor compatible to run the sample on stm32 boards without jedec,spi-nor compatible. No more config file needed to get the jedec ID and SFDP info from the external quad- or octo-SPI flash of the stm32 disco boards. Signed-off-by: Francois Ramu --- samples/drivers/jesd216/boards/b_l4s5i_iot01a.conf | 8 -------- samples/drivers/jesd216/boards/b_u585i_iot02a.conf | 8 -------- samples/drivers/jesd216/boards/disco_l475_iot1.conf | 3 --- samples/drivers/jesd216/boards/stm32h573i_dk.conf | 8 -------- samples/drivers/jesd216/boards/stm32h735g_disco.conf | 8 -------- samples/drivers/jesd216/boards/stm32h747i_disco_m7.conf | 3 --- samples/drivers/jesd216/boards/stm32l496g_disco.conf | 3 --- samples/drivers/jesd216/boards/stm32l562e_dk.conf | 8 -------- samples/drivers/jesd216/sample.yaml | 3 +++ 9 files changed, 3 insertions(+), 49 deletions(-) delete mode 100644 samples/drivers/jesd216/boards/b_l4s5i_iot01a.conf delete mode 100644 samples/drivers/jesd216/boards/b_u585i_iot02a.conf delete mode 100644 samples/drivers/jesd216/boards/disco_l475_iot1.conf delete mode 100644 samples/drivers/jesd216/boards/stm32h573i_dk.conf delete mode 100644 samples/drivers/jesd216/boards/stm32h735g_disco.conf delete mode 100644 samples/drivers/jesd216/boards/stm32h747i_disco_m7.conf delete mode 100644 samples/drivers/jesd216/boards/stm32l496g_disco.conf delete mode 100644 samples/drivers/jesd216/boards/stm32l562e_dk.conf diff --git a/samples/drivers/jesd216/boards/b_l4s5i_iot01a.conf b/samples/drivers/jesd216/boards/b_l4s5i_iot01a.conf deleted file mode 100644 index 6e3cf258b12..00000000000 --- a/samples/drivers/jesd216/boards/b_l4s5i_iot01a.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_FLASH_STM32_OSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/b_u585i_iot02a.conf b/samples/drivers/jesd216/boards/b_u585i_iot02a.conf deleted file mode 100644 index 6e3cf258b12..00000000000 --- a/samples/drivers/jesd216/boards/b_u585i_iot02a.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_FLASH_STM32_OSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/disco_l475_iot1.conf b/samples/drivers/jesd216/boards/disco_l475_iot1.conf deleted file mode 100644 index dbb7255d188..00000000000 --- a/samples/drivers/jesd216/boards/disco_l475_iot1.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FLASH_STM32_QSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/stm32h573i_dk.conf b/samples/drivers/jesd216/boards/stm32h573i_dk.conf deleted file mode 100644 index 4dd3e9965c4..00000000000 --- a/samples/drivers/jesd216/boards/stm32h573i_dk.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_FLASH_STM32_OSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/stm32h735g_disco.conf b/samples/drivers/jesd216/boards/stm32h735g_disco.conf deleted file mode 100644 index 6e3cf258b12..00000000000 --- a/samples/drivers/jesd216/boards/stm32h735g_disco.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_FLASH_STM32_OSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/stm32h747i_disco_m7.conf b/samples/drivers/jesd216/boards/stm32h747i_disco_m7.conf deleted file mode 100644 index dbb7255d188..00000000000 --- a/samples/drivers/jesd216/boards/stm32h747i_disco_m7.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FLASH_STM32_QSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/stm32l496g_disco.conf b/samples/drivers/jesd216/boards/stm32l496g_disco.conf deleted file mode 100644 index dbb7255d188..00000000000 --- a/samples/drivers/jesd216/boards/stm32l496g_disco.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FLASH_STM32_QSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/stm32l562e_dk.conf b/samples/drivers/jesd216/boards/stm32l562e_dk.conf deleted file mode 100644 index 6e3cf258b12..00000000000 --- a/samples/drivers/jesd216/boards/stm32l562e_dk.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_FLASH_STM32_OSPI=y -CONFIG_SPI_NOR_SFDP_RUNTIME=y -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/sample.yaml b/samples/drivers/jesd216/sample.yaml index af84cbc791e..c50ce41d0f3 100644 --- a/samples/drivers/jesd216/sample.yaml +++ b/samples/drivers/jesd216/sample.yaml @@ -28,3 +28,6 @@ tests: platform_allow: nrf52840dk_nrf52840 integration_platforms: - nrf52840dk_nrf52840 + sample.drivers.stm32.jesd216: + filter: dt_compat_enabled("st,stm32-ospi-nor") or dt_compat_enabled("st,stm32-qspi-nor") + depends_on: spi From 97fab8371651ba4c4b9e5ee91759c2435a135306 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Thu, 26 Oct 2023 07:42:28 +0200 Subject: [PATCH 3041/4498] scripts: coverage: gcovr to ignore negative counters Apply a workaround for an issue introduced with bc8b7dd for code coverage collection at qemu_x86 when gcov data was broken because of optimized out memcpy() in write_u64() static inline function, so gcovr parser fails with "gcovr.gcov_parser.NegativeHits: Got negative hit value in gcov line 'branch 1 taken -1'". Add gcovr command line option to ignore such errors (since v.6.0): "--gcov-ignore-parse-errors=negative_hits.warn_once_per_file" Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/coverage.py | 10 +++++----- scripts/requirements-build-test.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/coverage.py b/scripts/pylib/twister/twisterlib/coverage.py index c215ae5bd83..c1c9065d9ad 100644 --- a/scripts/pylib/twister/twisterlib/coverage.py +++ b/scripts/pylib/twister/twisterlib/coverage.py @@ -221,11 +221,11 @@ def _generate(self, outdir, coveragelog): excludes = Gcovr._interleave_list("-e", self.ignores) # We want to remove tests/* and tests/ztest/test/* but save tests/ztest - cmd = ["gcovr", "-r", self.base_dir, "--gcov-executable", - str(self.gcov_tool), "-e", "tests/*"] + excludes + ["--json", - "-o", - coveragefile, - outdir] + cmd = ["gcovr", "-r", self.base_dir, + "--gcov-ignore-parse-errors=negative_hits.warn_once_per_file", + "--gcov-executable", str(self.gcov_tool), + "-e", "tests/*"] + cmd += excludes + ["--json", "-o", coveragefile, outdir] cmd_str = " ".join(cmd) logger.debug(f"Running {cmd_str}...") subprocess.call(cmd, stdout=coveragelog) diff --git a/scripts/requirements-build-test.txt b/scripts/requirements-build-test.txt index 79309a179cd..c0f808880fb 100644 --- a/scripts/requirements-build-test.txt +++ b/scripts/requirements-build-test.txt @@ -10,7 +10,7 @@ colorama ply>=3.10 # used for code coverage -gcovr>=4.2 +gcovr>=6.0 coverage # used for west-command testing From 8ba8c188a0dd57fc6b92d9a1011c86521ff59d7e Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Wed, 25 Oct 2023 19:39:30 +0800 Subject: [PATCH 3042/4498] drivers: ethernet: support for Nuvoton numaker series Add Nuvoton numaker series EMAC controller feature. Signed-off-by: cyliang tw --- .../numaker_pfm_m467-pinctrl.dtsi | 17 + .../arm/numaker_pfm_m467/numaker_pfm_m467.dts | 6 + drivers/ethernet/CMakeLists.txt | 1 + drivers/ethernet/Kconfig | 1 + drivers/ethernet/Kconfig.numaker | 14 + drivers/ethernet/eth_numaker.c | 790 ++++++++++++++++++ drivers/ethernet/eth_numaker_priv.h | 18 + dts/arm/nuvoton/m46x.dtsi | 10 + .../ethernet/nuvoton,numaker-ethernet.yaml | 30 + west.yml | 2 +- 10 files changed, 888 insertions(+), 1 deletion(-) create mode 100644 drivers/ethernet/Kconfig.numaker create mode 100644 drivers/ethernet/eth_numaker.c create mode 100644 drivers/ethernet/eth_numaker_priv.h create mode 100644 dts/bindings/ethernet/nuvoton,numaker-ethernet.yaml diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi b/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi index 190e4262cad..b6b8f3eb508 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467-pinctrl.dtsi @@ -32,4 +32,21 @@ ; }; }; + + /* EMAC multi-function pins for MDIO, TX, REFCLK, RX pins */ + emac_default: emac_default { + group0 { + pinmux = , + , + , + , + , + , + , + , + , + , + ; + }; + }; }; diff --git a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts index f6e7a4eb799..da3350d9494 100644 --- a/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts +++ b/boards/arm/numaker_pfm_m467/numaker_pfm_m467.dts @@ -117,3 +117,9 @@ pinctrl-names = "default"; status = "okay"; }; + +&emac { + pinctrl-0 = <&emac_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index b40872e8146..20cc367fe5b 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -42,6 +42,7 @@ if(CONFIG_ETH_NXP_S32_NETC) endif() zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_GMAC eth_nxp_s32_gmac.c) +zephyr_library_sources_ifdef(CONFIG_ETH_NUMAKER eth_numaker.c) if(CONFIG_ETH_NATIVE_POSIX) set(native_posix_source_files eth_native_posix.c eth_native_posix_adapt.c) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 8160fc74358..eae83755af0 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -61,6 +61,7 @@ source "drivers/ethernet/Kconfig.nxp_s32_gmac" source "drivers/ethernet/Kconfig.smsc91x" source "drivers/ethernet/Kconfig.ivshmem" source "drivers/ethernet/Kconfig.adin2111" +source "drivers/ethernet/Kconfig.numaker" source "drivers/ethernet/phy/Kconfig" diff --git a/drivers/ethernet/Kconfig.numaker b/drivers/ethernet/Kconfig.numaker new file mode 100644 index 00000000000..eb757870d7b --- /dev/null +++ b/drivers/ethernet/Kconfig.numaker @@ -0,0 +1,14 @@ +# NUMAKER Ethernet Driver configuration options + +# Copyright (c) 2023 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config ETH_NUMAKER + bool "Nuvoton NUMAKER MCU Ethernet driver" + default y + select HAS_NUMAKER_ETH + depends on DT_HAS_NUVOTON_NUMAKER_ETHERNET_ENABLED + help + This option enables the Ethernet driver for Nuvoton NuMaker family of + processors. + Say y if you wish to enable NuMaker ETH. diff --git a/drivers/ethernet/eth_numaker.c b/drivers/ethernet/eth_numaker.c new file mode 100644 index 00000000000..77577943f23 --- /dev/null +++ b/drivers/ethernet/eth_numaker.c @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_numaker_ethernet + +#include +#include +#include +#include +#include +#include +#include +#include "eth_numaker_priv.h" +#include "ethernet/eth_stats.h" +#include +#include +#include + +#ifdef CONFIG_SOC_M467 +#include +#endif + +LOG_MODULE_REGISTER(eth_numaker, CONFIG_ETHERNET_LOG_LEVEL); + +/* Device EMAC Interface port */ +#define NUMAKER_GMAC_INTF 0 +/* 2KB Data Flash at 0xFF800 */ +#define NUMAKER_DATA_FLASH (0xFF800U) +#define NUMAKER_MASK_32 (0xFFFFFFFFU) +#define NUMAKER_MII_CONFIG (ADVERTISE_CSMA | ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) +#define NUMAKER_MII_LINKED (BMSR_ANEGCOMPLETE | BMSR_LSTATUS) + +extern synopGMACdevice GMACdev[GMAC_CNT]; +extern struct sk_buff tx_buf[GMAC_CNT][TRANSMIT_DESC_SIZE]; +extern struct sk_buff rx_buf[GMAC_CNT][RECEIVE_DESC_SIZE]; + +static uint32_t eth_phy_addr; + +/* Device config */ +struct eth_numaker_config { + uint32_t gmac_base; + const struct reset_dt_spec reset; + uint32_t phy_addr; + uint32_t clk_modidx; + uint32_t clk_src; + uint32_t clk_div; + const struct device *clk_dev; + const struct pinctrl_dev_config *pincfg; +}; + +/* Driver context/data */ +struct eth_numaker_data { + synopGMACdevice *gmacdev; + struct net_if *iface; + uint8_t mac_addr[NU_HWADDR_SIZE]; + struct k_mutex tx_frame_buf_mutex; + struct k_spinlock rx_frame_buf_lock; +}; + +/* Delay execution for given amount of ticks for SDK-HAL */ +void plat_delay(uint32_t delay) +{ + uint32_t us_cnt = k_ticks_to_us_floor32((uint64_t)delay); + + k_busy_wait(us_cnt); +} + +static void mdio_write(synopGMACdevice *gmacdev, uint32_t addr, uint32_t reg, int data) +{ + synopGMAC_write_phy_reg((u32 *)gmacdev->MacBase, addr, reg, data); +} + +static int mdio_read(synopGMACdevice *gmacdev, uint32_t addr, uint32_t reg) +{ + uint16_t data; + + synopGMAC_read_phy_reg((u32 *)gmacdev->MacBase, addr, reg, &data); + return data; +} + +static int numaker_eth_link_ok(synopGMACdevice *gmacdev) +{ + /* first, a dummy read to latch */ + mdio_read(gmacdev, eth_phy_addr, MII_BMSR); + if (mdio_read(gmacdev, eth_phy_addr, MII_BMSR) & BMSR_LSTATUS) { + return 1; + } + return 0; +} + +static int reset_phy(synopGMACdevice *gmacdev) +{ + uint16_t reg; + uint32_t delay_us; + bool ret; + + mdio_write(gmacdev, eth_phy_addr, MII_BMCR, BMCR_RESET); + + delay_us = 200000U; + ret = WAIT_FOR(!(mdio_read(gmacdev, eth_phy_addr, MII_BMCR) & BMCR_RESET), + delay_us, k_msleep(1)); + if (ret == false) { + LOG_DBG("Reset phy failed"); + return -EIO; + } + + LOG_INF("PHY ID 1:0x%x", mdio_read(gmacdev, eth_phy_addr, MII_PHYSID1)); + LOG_INF("PHY ID 2:0x%x", mdio_read(gmacdev, eth_phy_addr, MII_PHYSID2)); + delay_us = 3000000U; + ret = WAIT_FOR(numaker_eth_link_ok(gmacdev), delay_us, k_msleep(1)); + if (ret) { + gmacdev->LinkState = LINKUP; + LOG_DBG("Link Up"); + } else { + gmacdev->LinkState = LINKDOWN; + LOG_DBG("Link Down"); + return -EIO; + } + + mdio_write(gmacdev, eth_phy_addr, MII_ADVERTISE, NUMAKER_MII_CONFIG); + reg = mdio_read(gmacdev, eth_phy_addr, MII_BMCR); + mdio_write(gmacdev, eth_phy_addr, MII_BMCR, reg | BMCR_ANRESTART); + delay_us = 3000000U; + ret = WAIT_FOR((mdio_read(gmacdev, eth_phy_addr, MII_BMSR) & + NUMAKER_MII_LINKED) == NUMAKER_MII_LINKED, + delay_us, k_msleep(1)); + if (ret == false) { + LOG_DBG("AN failed. Set to 100 FULL"); + synopGMAC_set_full_duplex(gmacdev); + synopGMAC_set_mode(NUMAKER_GMAC_INTF, 1); /* Set mode 1: 100Mbps; 2: 10Mbps */ + return -EIO; + } + + reg = mdio_read(gmacdev, eth_phy_addr, MII_LPA); + if (reg & ADVERTISE_100FULL) { + LOG_DBG("100 full"); + gmacdev->DuplexMode = FULLDUPLEX; + gmacdev->Speed = SPEED100; + synopGMAC_set_full_duplex(gmacdev); + synopGMAC_set_mode(NUMAKER_GMAC_INTF, 1); /* Set mode 1: 100Mbps; 2: 10Mbps */ + } else if (reg & ADVERTISE_100HALF) { + LOG_DBG("100 half"); + gmacdev->DuplexMode = HALFDUPLEX; + gmacdev->Speed = SPEED100; + synopGMAC_set_half_duplex(gmacdev); + synopGMAC_set_mode(NUMAKER_GMAC_INTF, 1); /* Set mode 1: 100Mbps; 2: 10Mbps */ + } else if (reg & ADVERTISE_10FULL) { + LOG_DBG("10 full"); + gmacdev->DuplexMode = FULLDUPLEX; + gmacdev->Speed = SPEED10; + synopGMAC_set_full_duplex(gmacdev); + synopGMAC_set_mode(NUMAKER_GMAC_INTF, 2); /* Set mode 1: 100Mbps; 2: 10Mbps */ + } else { + LOG_DBG("10 half"); + gmacdev->DuplexMode = HALFDUPLEX; + gmacdev->Speed = SPEED10; + synopGMAC_set_half_duplex(gmacdev); + synopGMAC_set_mode(NUMAKER_GMAC_INTF, 2); /* Set mode 1: 100Mbps; 2: 10Mbps */ + } + + return 0; +} + +static void m_numaker_read_mac_addr(char *mac) +{ + uint32_t uid1; + /* Fetch word 0 of data flash */ + uint32_t word0 = *(uint32_t *)(NUMAKER_DATA_FLASH + 0x04U); + /* + * Fetch word 1 of data flash + * we only want bottom 16 bits of word1 (MAC bits 32-47) + * and bit 9 forced to 1, bit 8 forced to 0 + * Locally administered MAC, reduced conflicts + * http://en.wikipedia.org/wiki/MAC_address + */ + uint32_t word1 = *(uint32_t *)NUMAKER_DATA_FLASH; + + /* Not burn any mac address at the beginning of data flash */ + if (word0 == NUMAKER_MASK_32) { + /* Generate a semi-unique MAC address from the UUID */ + SYS_UnlockReg(); + /* Enable FMC ISP function */ + FMC_Open(); + uid1 = FMC_ReadUID(1); + word1 = (uid1 & 0x003FFFFF) | ((uid1 & 0x030000) << 6) >> 8; + word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uid1 & 0xFF) << 12) | + (FMC_ReadUID(2) & 0xFFF); + /* Disable FMC ISP function */ + FMC_Close(); + /* Lock protected registers */ + SYS_LockReg(); + } + + word1 |= 0x00000200; + word1 &= 0x0000FEFF; + + mac[0] = (word1 & 0x0000ff00) >> 8; + mac[1] = (word1 & 0x000000ff); + mac[2] = (word0 & 0xff000000) >> 24; + mac[3] = (word0 & 0x00ff0000) >> 16; + mac[4] = (word0 & 0x0000ff00) >> 8; + mac[5] = (word0 & 0x000000ff); + + LOG_INF("mac address %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5]); +} + +static void m_numaker_gmacdev_enable(synopGMACdevice *gmacdev) +{ + + synopGMAC_clear_interrupt(gmacdev); + + /* Enable INT & TX/RX */ + synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); + synopGMAC_enable_dma_rx(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + + synopGMAC_tx_enable(gmacdev); + synopGMAC_rx_enable(gmacdev); +} + +static int m_numaker_gmacdev_init(synopGMACdevice *gmacdev, uint8_t *mac_addr, uint32_t gmac_base) +{ + int status; + int i; + uint32_t offload_needed = 0; + struct sk_buff *skb; + + LOG_DBG(""); + + /*Attach the device to MAC struct This will configure all the required base + * addresses such as Mac base, configuration base, phy base address(out of 32 + * possible phys ) + */ + synopGMAC_attach(gmacdev, gmac_base + MACBASE, gmac_base + DMABASE, DEFAULT_PHY_BASE); + synopGMAC_disable_interrupt_all(gmacdev); + + /* Reset MAC */ + synopGMAC_reset(gmacdev); + gmacdev->Intf = NUMAKER_GMAC_INTF; + synopGMAC_read_version(gmacdev); + + /* Check for Phy initialization */ + synopGMAC_set_mdc_clk_div(gmacdev, GmiiCsrClk5); + gmacdev->ClockDivMdc = synopGMAC_get_mdc_clk_div(gmacdev); + + /* Reset PHY */ + status = reset_phy(gmacdev); + + /* Set up the tx and rx descriptor queue/ring */ + synopGMAC_setup_tx_desc_queue(gmacdev, TRANSMIT_DESC_SIZE, RINGMODE); + synopGMAC_init_tx_desc_base(gmacdev); + + synopGMAC_setup_rx_desc_queue(gmacdev, RECEIVE_DESC_SIZE, RINGMODE); + synopGMAC_init_rx_desc_base(gmacdev); + + /* Initialize the dma interface */ + synopGMAC_dma_bus_mode_init(gmacdev, + DmaBurstLength32 | DmaDescriptorSkip0 | DmaDescriptor8Words); + synopGMAC_dma_control_init(gmacdev, + DmaStoreAndForward | DmaTxSecondFrame | DmaRxThreshCtrl128); + + /* Initialize the mac interface */ + synopGMAC_mac_init(gmacdev); + synopGMAC_promisc_enable(gmacdev); + + /* This enables the pause control in Full duplex mode of operation */ + synopGMAC_pause_control(gmacdev); + +#if defined(NU_USING_HW_CHECKSUM) + /*IPC Checksum offloading is enabled for this driver. Should only be used if + * Full Ip checksumm offload engine is configured in the hardware + */ + offload_needed = 1; + + /* Enable the offload engine in the receive path */ + synopGMAC_enable_rx_chksum_offload(gmacdev); + + /* Default configuration, DMA drops the packets if error in encapsulated ethernet payload */ + synopGMAC_rx_tcpip_chksum_drop_enable(gmacdev); +#endif + + for (i = 0; i < RECEIVE_DESC_SIZE; i++) { + skb = &rx_buf[NUMAKER_GMAC_INTF][i]; + synopGMAC_set_rx_qptr(gmacdev, (u32)((u64)(skb->data) & NUMAKER_MASK_32), + sizeof(skb->data), (u32)((u64)skb & NUMAKER_MASK_32)); + } + + for (i = 0; i < TRANSMIT_DESC_SIZE; i++) { + skb = &tx_buf[NUMAKER_GMAC_INTF][i]; + synopGMAC_set_tx_qptr(gmacdev, (u32)((u64)(skb->data) & NUMAKER_MASK_32), + sizeof(skb->data), (u32)((u64)skb & NUMAKER_MASK_32), + offload_needed, 0); + } + + synopGMAC_set_mac_address(NUMAKER_GMAC_INTF, mac_addr); + synopGMAC_clear_interrupt(gmacdev); + + return status; +} + +static int m_numaker_gmacdev_get_rx_buf(synopGMACdevice *gmacdev, uint16_t *len, uint8_t **buf) +{ + DmaDesc *rxdesc = gmacdev->RxBusyDesc; + + LOG_DBG("start"); + if (synopGMAC_is_desc_owned_by_dma(rxdesc)) { + return -EIO; + } + if (synopGMAC_is_desc_empty(rxdesc)) { + return -EIO; + } + + *len = synop_handle_received_data(NUMAKER_GMAC_INTF, buf); + if (*len <= 0) { + synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); + return -ENOSPC; /* No available RX frame */ + } + + /* length of payload should be <= 1514 */ + if (*len > (NU_ETH_MAX_FLEN - 4)) { + LOG_DBG("unexpected long packet length=%d, buf=0x%x", *len, (uint32_t)*buf); + *len = 0; /* Skip this unexpected long packet */ + } + + LOG_DBG("end"); + return 0; +} + +static void m_numaker_gmacdev_rx_next(synopGMACdevice *gmacdev) +{ + LOG_DBG("RX Next"); + /* Already did in synop_handle_received_data + * No-op at this stage + * DmaDesc * rxdesc = (gmacdev->RxBusyDesc - 1); + * rxdesc->status = DescOwnByDma; + */ +} + +static void m_numaker_gmacdev_trigger_rx(synopGMACdevice *gmacdev) +{ + LOG_DBG("start"); + + /* Enable the interrupt */ + synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); + + /* Trigger RX DMA */ + synopGMAC_enable_dma_rx(gmacdev); + synopGMAC_resume_dma_rx(gmacdev); + LOG_DBG("resume RX DMA"); + LOG_DBG("end"); +} + +static void m_numaker_gmacdev_packet_rx(const struct device *dev) +{ + struct eth_numaker_data *data = dev->data; + synopGMACdevice *gmacdev = data->gmacdev; + uint8_t *buffer; + uint16_t len; + struct net_pkt *pkt; + k_spinlock_key_t key; + int res; + + /* Get exclusive access, use spin-lock instead of mutex in ISR */ + key = k_spin_lock(&data->rx_frame_buf_lock); + + /* Two approach: 1. recv all RX packets in one time. + * 2. recv one RX and set pending interrupt for rx-next. + */ + while (1) { + /* get received frame */ + if (m_numaker_gmacdev_get_rx_buf(gmacdev, &len, &buffer) != 0) { + break; + } + + if (len == 0) { + LOG_WRN("No available RX frame"); + break; + } + /* Allocate a memory buffer chain from buffer pool + * Using root iface. It will be updated in net_recv_data() + */ + pkt = net_pkt_rx_alloc_with_buffer(data->iface, len, AF_UNSPEC, 0, K_NO_WAIT); + if (!pkt) { + LOG_ERR("pkt alloc frame-len=%d failed", len); + goto next; + } + + LOG_DBG("length=%d, pkt=0x%x", len, (uint32_t)pkt); + /* deliver RX packet to upper layer, pack as one net_pkt */ + if (net_pkt_write(pkt, buffer, len)) { + LOG_ERR("Unable to write RX frame into the pkt"); + net_pkt_unref(pkt); + goto error; + } + + if (pkt != NULL) { + res = net_recv_data(data->iface, pkt); + if (res < 0) { + LOG_ERR("net_recv_data: %d", res); + net_pkt_unref(pkt); + goto error; + } + } +next: + m_numaker_gmacdev_rx_next(gmacdev); + } + m_numaker_gmacdev_trigger_rx(gmacdev); + +error: + k_spin_unlock(&data->rx_frame_buf_lock, key); +} + +static uint8_t *m_numaker_gmacdev_get_tx_buf(synopGMACdevice *gmacdev) +{ + DmaDesc *txdesc = gmacdev->TxNextDesc; + + if (!synopGMAC_is_desc_empty(txdesc)) { + return NULL; + } + + if (synopGMAC_is_desc_owned_by_dma(txdesc)) { + return NULL; + } + + return (uint8_t *)(txdesc->buffer1); +} + +static void m_numaker_gmacdev_trigger_tx(synopGMACdevice *gmacdev, uint16_t length) +{ + DmaDesc *txdesc = gmacdev->TxNextDesc; + uint32_t txnext = gmacdev->TxNext; + bool offload_needed = IS_ENABLED(NU_USING_HW_CHECKSUM); + + /* busy tx descriptor is incremented by one as it will be handed over to DMA */ + (gmacdev->BusyTxDesc)++; + + txdesc->length |= ((length << DescSize1Shift) & DescSize1Mask); + txdesc->status |= (DescTxFirst | DescTxLast | DescTxIntEnable); + if (offload_needed) { + /* + * Make sure that the OS you are running supports the IP and TCP checksum + * offloading, before calling any of the functions given below. + */ + synopGMAC_tx_checksum_offload_tcp_pseudo(gmacdev, txdesc); + } else { + synopGMAC_tx_checksum_offload_bypass(gmacdev, txdesc); + } + __DSB(); + txdesc->status |= DescOwnByDma; + + gmacdev->TxNext = synopGMAC_is_last_tx_desc(gmacdev, txdesc) ? 0 : txnext + 1; + gmacdev->TxNextDesc = + synopGMAC_is_last_tx_desc(gmacdev, txdesc) ? gmacdev->TxDesc : (txdesc + 1); + + /* Enable the interrupt */ + synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); + /* Trigger TX DMA */ + synopGMAC_resume_dma_tx(gmacdev); +} + +static int numaker_eth_tx(const struct device *dev, struct net_pkt *pkt) +{ + struct eth_numaker_data *data = dev->data; + synopGMACdevice *gmacdev = data->gmacdev; + uint16_t total_len = net_pkt_get_len(pkt); + uint8_t *buffer; + + /* Get exclusive access */ + k_mutex_lock(&data->tx_frame_buf_mutex, K_FOREVER); + if (total_len > NET_ETH_MAX_FRAME_SIZE) { + /* NuMaker SDK reserve 2048 for tx_buf */ + LOG_ERR("TX packet length [%d] over max [%d]", total_len, NET_ETH_MAX_FRAME_SIZE); + goto error; + } + + buffer = m_numaker_gmacdev_get_tx_buf(gmacdev); + LOG_DBG("buffer=0x%x", (uint32_t)buffer); + if (buffer == NULL) { + goto error; + } + + if (net_pkt_read(pkt, buffer, total_len)) { + goto error; + } + + /* Prepare transmit descriptors to give to DMA */ + m_numaker_gmacdev_trigger_tx(gmacdev, total_len); + + k_mutex_unlock(&data->tx_frame_buf_mutex); + + return 0; + +error: + LOG_ERR("Writing pkt to TX descriptor failed"); + k_mutex_unlock(&data->tx_frame_buf_mutex); + return -EIO; +} + +static void numaker_eth_if_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct eth_numaker_data *data = dev->data; + + synopGMACdevice *gmacdev = data->gmacdev; + + LOG_DBG("eth_if_init"); + + /* Read mac address */ + m_numaker_read_mac_addr(data->mac_addr); + + net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr), NET_LINK_ETHERNET); + data->iface = iface; + ethernet_init(iface); + + /* Enable GMAC device INT & TX/RX */ + m_numaker_gmacdev_enable(gmacdev); +} + +static int numaker_eth_set_config(const struct device *dev, enum ethernet_config_type type, + const struct ethernet_config *config) +{ + struct eth_numaker_data *data = dev->data; + + switch (type) { + case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: + memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr)); + synopGMAC_set_mac_address(NUMAKER_GMAC_INTF, data->mac_addr); + net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr), + NET_LINK_ETHERNET); + LOG_DBG("%s MAC set to %02x:%02x:%02x:%02x:%02x:%02x", dev->name, data->mac_addr[0], + data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], + data->mac_addr[5]); + return 0; + default: + return -ENOTSUP; + } +} + +static enum ethernet_hw_caps numaker_eth_get_cap(const struct device *dev) +{ + ARG_UNUSED(dev); +#if defined(NU_USING_HW_CHECKSUM) + return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_HW_RX_CHKSUM_OFFLOAD; +#else + return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T; +#endif +} + +static const struct ethernet_api eth_numaker_driver_api = { + .iface_api.init = numaker_eth_if_init, + .get_capabilities = numaker_eth_get_cap, + .set_config = numaker_eth_set_config, + .send = numaker_eth_tx, +}; + +/* EMAC IRQ Handler */ +static void eth_numaker_isr(const struct device *dev) +{ + struct eth_numaker_data *data = dev->data; + synopGMACdevice *gmacdev = data->gmacdev; + uint32_t interrupt; + uint32_t dma_status_reg; + uint32_t mac_status_reg; + int status; + uint32_t dma_ie = DmaIntEnable; + + uint32_t volatile reg; + + /* Check GMAC interrupt */ + mac_status_reg = synopGMACReadReg((u32 *)gmacdev->MacBase, GmacInterruptStatus); + if (mac_status_reg & GmacTSIntSts) { + gmacdev->synopGMACNetStats.ts_int = 1; + status = synopGMACReadReg((u32 *)gmacdev->MacBase, GmacTSStatus); + if (!(status & BIT(1))) { + LOG_WRN("TS alarm flag not set??"); + } else { + LOG_DBG("TS alarm"); + } + } + + if (mac_status_reg & GmacLPIIntSts) { + LOG_DBG("LPI"); + } + + if (mac_status_reg & GmacRgmiiIntSts) { + reg = synopGMACReadReg((u32 *)gmacdev->MacBase, GmacRgmiiCtrlSts); + } + + synopGMACWriteReg((u32 *)gmacdev->MacBase, GmacInterruptStatus, mac_status_reg); + /* Read the Dma interrupt status to know whether the interrupt got generated by + * our device or not + */ + dma_status_reg = synopGMACReadReg((u32 *)gmacdev->DmaBase, DmaStatus); + LOG_DBG("i %08x %08x", mac_status_reg, dma_status_reg); + + if (dma_status_reg == 0) { + return; + } + + synopGMAC_disable_interrupt_all(gmacdev); + LOG_DBG("Dma Status Reg: 0x%08x", dma_status_reg); + if (dma_status_reg & GmacPmtIntr) { + LOG_DBG("Interrupt due to PMT module"); + synopGMAC_powerup_mac(gmacdev); + } + + if (dma_status_reg & GmacLineIntfIntr) { + LOG_DBG("Interrupt due to GMAC LINE module"); + } + + /* Now lets handle the DMA interrupts */ + interrupt = synopGMAC_get_interrupt_type(gmacdev); + LOG_DBG("Interrupts to be handled: 0x%08x", interrupt); + if (interrupt & synopGMACDmaError) { + LOG_DBG("Fatal Bus Error Interrupt Seen"); + synopGMAC_disable_dma_tx(gmacdev); + synopGMAC_disable_dma_rx(gmacdev); + + synopGMAC_take_desc_ownership_tx(gmacdev); + synopGMAC_take_desc_ownership_rx(gmacdev); + + synopGMAC_init_tx_rx_desc_queue(gmacdev); + + synopGMAC_reset(gmacdev); /* reset the DMA engine and the GMAC ip */ + synopGMAC_set_mac_address(NUMAKER_GMAC_INTF, data->mac_addr); + synopGMAC_dma_bus_mode_init(gmacdev, DmaFixedBurstEnable | DmaBurstLength8 | + DmaDescriptorSkip0); + synopGMAC_dma_control_init(gmacdev, DmaStoreAndForward); + synopGMAC_init_rx_desc_base(gmacdev); + synopGMAC_init_tx_desc_base(gmacdev); + synopGMAC_mac_init(gmacdev); + synopGMAC_enable_dma_rx(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + } + + if (interrupt & synopGMACDmaRxNormal) { + LOG_DBG("Rx Normal"); + /* disable RX interrupt */ + dma_ie &= ~DmaIntRxNormMask; + /* to handle received data */ + m_numaker_gmacdev_packet_rx(dev); + } + + if (interrupt & synopGMACDmaRxAbnormal) { + LOG_ERR("Abnormal Rx Interrupt Seen"); + /* If Mac is not in powerdown */ + if (gmacdev->GMAC_Power_down == 0) { + gmacdev->synopGMACNetStats.rx_over_errors++; + dma_ie &= ~DmaIntRxAbnMask; + /* To handle GBPS with 12 descriptors. */ + synopGMAC_resume_dma_rx(gmacdev); + } + } + + /* Receiver gone in to stopped state */ + if (interrupt & synopGMACDmaRxStopped) { + LOG_ERR("Receiver stopped seeing Rx interrupts"); + if (gmacdev->GMAC_Power_down == 0) { + gmacdev->synopGMACNetStats.rx_over_errors++; + synopGMAC_enable_dma_rx(gmacdev); + } + } + + if (interrupt & synopGMACDmaTxNormal) { + LOG_DBG("Finished Normal Transmission"); + synop_handle_transmit_over(0); + /* No-op at this stage for TX INT */ + } + + if (interrupt & synopGMACDmaTxAbnormal) { + LOG_ERR("Abnormal Tx Interrupt Seen"); + if (gmacdev->GMAC_Power_down == 0) { + synop_handle_transmit_over(0); + /* No-op at this stage for TX INT */ + } + } + + if (interrupt & synopGMACDmaTxStopped) { + LOG_ERR("Transmitter stopped sending the packets"); + if (gmacdev->GMAC_Power_down == 0) { + synopGMAC_disable_dma_tx(gmacdev); + synopGMAC_take_desc_ownership_tx(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + LOG_ERR("Transmission Resumed"); + } + } + + /* Enable the interrupt before returning from ISR*/ + synopGMAC_enable_interrupt(gmacdev, dma_ie); +} + +/* Declare pin-ctrl __pinctrl_dev_config__device_dts_ord_xx before + * PINCTRL_DT_INST_DEV_CONFIG_GET() + */ +PINCTRL_DT_INST_DEFINE(0); + +static int eth_numaker_init(const struct device *dev) +{ + const struct eth_numaker_config *cfg = dev->config; + struct eth_numaker_data *data = dev->data; + synopGMACdevice *gmacdev; + + /* Init MAC Address based on UUID*/ + uint8_t mac_addr[NU_HWADDR_SIZE]; + int ret = 0; + struct numaker_scc_subsys scc_subsys; + + gmacdev = &GMACdev[NUMAKER_GMAC_INTF]; + data->gmacdev = gmacdev; + + k_mutex_init(&data->tx_frame_buf_mutex); + + eth_phy_addr = cfg->phy_addr; + + /* CLK controller */ + memset(&scc_subsys, 0x00, sizeof(scc_subsys)); + scc_subsys.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC; + scc_subsys.pcc.clk_modidx = cfg->clk_modidx; + scc_subsys.pcc.clk_src = cfg->clk_src; + scc_subsys.pcc.clk_div = cfg->clk_div; + + /* Equivalent to CLK_EnableModuleClock() */ + ret = clock_control_on(cfg->clk_dev, (clock_control_subsys_t)&scc_subsys); + if (ret != 0) { + goto done; + } + + /* For EMAC, not need CLK_SetModuleClock() + * Validate this module's reset object + */ + if (!device_is_ready(cfg->reset.dev)) { + LOG_ERR("reset controller not ready"); + return -ENODEV; + } + + SYS_UnlockReg(); + + irq_disable(DT_INST_IRQN(0)); + ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (ret != 0) { + LOG_ERR("Failed to apply pinctrl state"); + goto done; + } + + /* Reset EMAC to default state, same as BSP's SYS_ResetModule(id_rst) */ + reset_line_toggle_dt(&cfg->reset); + + /* Read mac address */ + m_numaker_read_mac_addr(mac_addr); + + /* Configure GMAC device */ + ret = m_numaker_gmacdev_init(gmacdev, mac_addr, cfg->gmac_base); + if (ret != 0) { + LOG_ERR("GMAC failed to initialize"); + goto done; + } + + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), eth_numaker_isr, + DEVICE_DT_INST_GET(0), 0); + + irq_enable(DT_INST_IRQN(0)); + +done: + SYS_LockReg(); + return ret; +} + +static struct eth_numaker_data eth_numaker_data_inst; + +/* Set config based on DTS */ +static struct eth_numaker_config eth_numaker_cfg_inst = { + .gmac_base = (uint32_t)DT_INST_REG_ADDR(0), + .reset = RESET_DT_SPEC_INST_GET(0), + .phy_addr = DT_INST_PROP(0, phy_addr), + .clk_modidx = DT_INST_CLOCKS_CELL(0, clock_module_index), + .clk_src = DT_INST_CLOCKS_CELL(0, clock_source), + .clk_div = DT_INST_CLOCKS_CELL(0, clock_divider), + .clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(0))), + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), + .reset = RESET_DT_SPEC_INST_GET(0), +}; + +ETH_NET_DEVICE_DT_INST_DEFINE(0, eth_numaker_init, NULL, ð_numaker_data_inst, + ð_numaker_cfg_inst, CONFIG_ETH_INIT_PRIORITY, + ð_numaker_driver_api, NET_ETH_MTU); diff --git a/drivers/ethernet/eth_numaker_priv.h b/drivers/ethernet/eth_numaker_priv.h new file mode 100644 index 00000000000..e3bec804b98 --- /dev/null +++ b/drivers/ethernet/eth_numaker_priv.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NUMAKER_PRIV_H_ +#define ZEPHYR_DRIVERS_ETHERNET_ETH_NUMAKER_PRIV_H_ + +#include + +#define NU_ETH_MAX_FLEN (1518) + +#define NU_HWADDR_SIZE (6) + +#define NU_ETH_MTU_SIZE 1500 + +#endif /* ZEPHYR_DRIVERS_ETHERNET_ETH_NUMAKER_PRIV_H_ */ diff --git a/dts/arm/nuvoton/m46x.dtsi b/dts/arm/nuvoton/m46x.dtsi index ea0db8bac45..3e6efbb1745 100644 --- a/dts/arm/nuvoton/m46x.dtsi +++ b/dts/arm/nuvoton/m46x.dtsi @@ -492,6 +492,16 @@ sample-point = <875>; sample-point-data = <875>; }; + + emac: ethernet@40012000 { + compatible = "nuvoton,numaker-ethernet"; + reg = <0x40012000 0x105C>; + interrupts = <66 0>; + resets = <&rst NUMAKER_EMAC0_RST>; + phy-addr = <1>; + clocks = <&pcc NUMAKER_EMAC0_MODULE 0 0>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/ethernet/nuvoton,numaker-ethernet.yaml b/dts/bindings/ethernet/nuvoton,numaker-ethernet.yaml new file mode 100644 index 00000000000..4cdf35c4f60 --- /dev/null +++ b/dts/bindings/ethernet/nuvoton,numaker-ethernet.yaml @@ -0,0 +1,30 @@ +# Copyright (c) 2023 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +description: Nuvoton, NuMaker Ethernet controller + +compatible: "nuvoton,numaker-ethernet" + +include: + - ethernet-controller.yaml + - ethernet,fixed-link.yaml + - reset-device.yaml + - pinctrl-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + resets: + required: true + + clocks: + required: true + + phy-addr: + type: int + description: Address of the phy controller + required: true diff --git a/west.yml b/west.yml index 54581f55087..3ff4cc0de44 100644 --- a/west.yml +++ b/west.yml @@ -188,7 +188,7 @@ manifest: groups: - hal - name: hal_nuvoton - revision: 3e0a4c4d3328b2f72b164219add19d5308b53cb5 + revision: 584190e131655de1046088bd0d0735d83429ec7c path: modules/hal/nuvoton groups: - hal From 0b0f2f1912c271250f99a78accdea79591a9bc19 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 3 Nov 2023 14:55:25 +0100 Subject: [PATCH 3043/4498] cmake: safeguard path of SOC_LINKER_SCRIPT Issue reported on Discord. Safeguard cmake_path() for SOC_LINKER_SCRIPT so that the path is only processed when SOC_LINKER_SCRIPT is defined. Signed-off-by: Torsten Rasmussen --- cmake/linker/ld/target.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index baf76d2fed5..b57f8902044 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -57,7 +57,10 @@ macro(configure_linker_script linker_script_gen linker_pass_define) zephyr_get_include_directories_for_lang(C current_includes) get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) - cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) + if(DEFINED SOC_LINKER_SCRIPT) + cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) + set(soc_linker_script_includes -I${soc_linker_script_includes}) + endif() add_custom_command( OUTPUT ${linker_script_gen} @@ -75,7 +78,7 @@ macro(configure_linker_script linker_script_gen linker_pass_define) -D_ASMLANGUAGE -imacros ${AUTOCONF_H} ${current_includes} - -I${soc_linker_script_includes} + ${soc_linker_script_includes} ${current_defines} ${template_script_defines} -E ${LINKER_SCRIPT} From 93a8ec4b5d77cd1c445a9c46e48e85c3162b1c3b Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Thu, 24 Aug 2023 09:23:10 +0100 Subject: [PATCH 3044/4498] drivers: sensor: npm1300_charger: Updating of USB current limit Added attributes for reading USB current capability, and setting of USB current limit Signed-off-by: Andy Sinclair --- .../sensor/npm1300_charger/npm1300_charger.c | 63 +++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c index 95634a0a506..e81467d2e6f 100644 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -71,7 +71,10 @@ struct npm1300_charger_data { #define ADC_OFFSET_IBAT_EN 0x24U /* nPM1300 VBUS register offsets */ +#define VBUS_OFFSET_ILIMUPDATE 0x00U +#define VBUS_OFFSET_ILIM 0x01U #define VBUS_OFFSET_ILIMSTARTUP 0x02U +#define VBUS_OFFSET_DETECT 0x05U #define VBUS_OFFSET_STATUS 0x07U /* Ibat status */ @@ -105,6 +108,11 @@ struct adc_results_t { #define NTCTEMP_MSB_SHIFT 2U #define NTCTEMP_LSB_MASK 0x03U +/* VBUS masks */ +#define DETECT_HI_MASK 0x0AU +#define DETECT_HI_CURRENT 1500000 +#define DETECT_LO_CURRENT 500000 + /* Linear range for charger terminal voltage */ static const struct linear_range charger_volt_ranges[] = { LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)}; @@ -310,6 +318,32 @@ static int npm1300_charger_attr_get(const struct device *dev, enum sensor_channe val->val2 = 0U; } return ret; + + case SENSOR_CHAN_CURRENT: + if (attr != SENSOR_ATTR_UPPER_THRESH) { + return -ENOTSUP; + } + + ret = mfd_npm1300_reg_read(config->mfd, VBUS_BASE, VBUS_OFFSET_DETECT, &data); + if (ret < 0) { + return ret; + } + + if (data == 0U) { + /* No charger connected */ + val->val1 = 0; + val->val2 = 0; + } else if ((data & DETECT_HI_MASK) != 0U) { + /* CC1 or CC2 indicate 1.5A or 3A capability */ + val->val1 = DETECT_HI_CURRENT / 1000000; + val->val2 = DETECT_HI_CURRENT % 1000000; + } else { + val->val1 = DETECT_LO_CURRENT / 1000000; + val->val2 = DETECT_LO_CURRENT % 1000000; + } + + return 0; + default: return -ENOTSUP; } @@ -321,12 +355,12 @@ static int npm1300_charger_attr_set(const struct device *dev, enum sensor_channe const struct npm1300_charger_config *const config = dev->config; int ret; + if (attr != SENSOR_ATTR_CONFIGURATION) { + return -ENOTSUP; + } + switch ((uint32_t)chan) { case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT: - if (attr != SENSOR_ATTR_CONFIGURATION) { - return -ENOTSUP; - } - if (val->val1 == 0) { /* Disable charging */ return mfd_npm1300_reg_write(config->mfd, CHGR_BASE, CHGR_OFFSET_EN_CLR, @@ -340,6 +374,27 @@ static int npm1300_charger_attr_set(const struct device *dev, enum sensor_channe } return mfd_npm1300_reg_write(config->mfd, CHGR_BASE, CHGR_OFFSET_EN_SET, 1U); + case SENSOR_CHAN_CURRENT: + /* Set vbus current limit */ + int32_t current = (val->val1 * 1000000) + val->val2; + uint16_t idx; + + ret = linear_range_group_get_win_index(vbus_current_ranges, + ARRAY_SIZE(vbus_current_ranges), current, + current, &idx); + + if (ret == -EINVAL) { + return ret; + } + + ret = mfd_npm1300_reg_write(config->mfd, VBUS_BASE, VBUS_OFFSET_ILIM, idx); + if (ret != 0) { + return ret; + } + + /* Switch to new current limit, this will be reset automatically on USB removal */ + return mfd_npm1300_reg_write(config->mfd, VBUS_BASE, VBUS_OFFSET_ILIMUPDATE, 1U); + default: return -ENOTSUP; } From 8fd676295e3b632b06b956ee56b3a0a2f921604f Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Mon, 9 Oct 2023 10:33:59 +0100 Subject: [PATCH 3045/4498] drivers: sensor: npm1300_charger: die temp threshold configuration Added configuration of die temperature stop/resume thresholds Signed-off-by: Andy Sinclair --- .../sensor/npm1300_charger/npm1300_charger.c | 44 ++++++++++++++++++- .../sensor/nordic,npm1300-charger.yaml | 12 +++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c index e81467d2e6f..cef044d0034 100644 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -20,6 +20,7 @@ struct npm1300_charger_config { int32_t dischg_limit_microamp; int32_t vbus_limit_microamp; int32_t temp_thresholds[4U]; + int32_t dietemp_thresholds[2U]; uint32_t thermistor_ohms; uint16_t thermistor_beta; uint8_t thermistor_idx; @@ -57,6 +58,7 @@ struct npm1300_charger_data { #define CHGR_OFFSET_TRICKLE_SEL 0x0EU #define CHGR_OFFSET_ITERM_SEL 0x0FU #define CHGR_OFFSET_NTC_TEMPS 0x10U +#define CHGR_OFFSET_DIE_TEMPS 0x18U #define CHGR_OFFSET_CHG_STAT 0x34U #define CHGR_OFFSET_ERR_REASON 0x36U #define CHGR_OFFSET_VBATLOW_EN 0x50U @@ -108,11 +110,20 @@ struct adc_results_t { #define NTCTEMP_MSB_SHIFT 2U #define NTCTEMP_LSB_MASK 0x03U +/* dietemp masks */ +#define DIETEMP_MSB_SHIFT 2U +#define DIETEMP_LSB_MASK 0x03U + /* VBUS masks */ #define DETECT_HI_MASK 0x0AU #define DETECT_HI_CURRENT 1500000 #define DETECT_LO_CURRENT 500000 +/* Dietemp calculation constants */ +#define DIETEMP_OFFSET_MDEGC 394670 +#define DIETEMP_FACTOR_MUL 3963000 +#define DIETEMP_FACTOR_DIV 5000 + /* Linear range for charger terminal voltage */ static const struct linear_range charger_volt_ranges[] = { LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)}; @@ -299,6 +310,29 @@ static int set_ntc_thresholds(const struct npm1300_charger_config *const config) return 0; } +static int set_dietemp_thresholds(const struct npm1300_charger_config *const config) +{ + for (uint8_t idx = 0U; idx < 2U; idx++) { + if (config->dietemp_thresholds[idx] < INT32_MAX) { + /* Ref: Datasheet section 6.2.6: Charger thermal regulation */ + int32_t numerator = + (DIETEMP_OFFSET_MDEGC - config->dietemp_thresholds[idx]) * + DIETEMP_FACTOR_DIV; + uint16_t code = DIV_ROUND_CLOSEST(numerator, DIETEMP_FACTOR_MUL); + + int ret = mfd_npm1300_reg_write2( + config->mfd, CHGR_BASE, CHGR_OFFSET_DIE_TEMPS + (idx * 2U), + code >> DIETEMP_MSB_SHIFT, code & DIETEMP_LSB_MASK); + + if (ret != 0) { + return ret; + } + } + } + + return 0; +} + static int npm1300_charger_attr_get(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, struct sensor_value *val) { @@ -410,7 +444,7 @@ int npm1300_charger_init(const struct device *dev) return -ENODEV; } - /* Configure thermistor */ + /* Configure temperature thresholds */ ret = mfd_npm1300_reg_write(config->mfd, ADC_BASE, ADC_OFFSET_NTCR_SEL, config->thermistor_idx + 1U); if (ret != 0) { @@ -422,6 +456,11 @@ int npm1300_charger_init(const struct device *dev) return ret; } + ret = set_dietemp_thresholds(config); + if (ret != 0) { + return ret; + } + /* Configure termination voltages */ ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), config->term_microvolt, config->term_microvolt, @@ -576,6 +615,9 @@ static const struct sensor_driver_api npm1300_charger_battery_driver_api = { .iterm_sel = DT_INST_ENUM_IDX(n, term_current_percent), \ .vbatlow_charge_enable = DT_INST_PROP(n, vbatlow_charge_enable), \ .disable_recharge = DT_INST_PROP(n, disable_recharge), \ + .dietemp_thresholds = {DT_INST_PROP_OR(n, dietemp_stop_millidegrees, INT32_MAX), \ + DT_INST_PROP_OR(n, dietemp_resume_millidegrees, \ + INT32_MAX)}, \ .temp_thresholds = {DT_INST_PROP_OR(n, thermistor_cold_millidegrees, INT32_MAX), \ DT_INST_PROP_OR(n, thermistor_cool_millidegrees, INT32_MAX), \ DT_INST_PROP_OR(n, thermistor_warm_millidegrees, INT32_MAX), \ diff --git a/dts/bindings/sensor/nordic,npm1300-charger.yaml b/dts/bindings/sensor/nordic,npm1300-charger.yaml index cfb0420ecc9..2885cd0de76 100644 --- a/dts/bindings/sensor/nordic,npm1300-charger.yaml +++ b/dts/bindings/sensor/nordic,npm1300-charger.yaml @@ -114,3 +114,15 @@ properties: type: boolean description: | Disable automatic recharge. + + dietemp-stop-millidegrees: + type: int + description: | + Die temperature halt threshold in milli-degrees. + When die temperature exceeds this threshold, charging will be inhibited. + + dietemp-resume-millidegrees: + type: int + description: | + Die temperature resume threshold in milli-degrees. + When die temperature falls below this threshold, charging will be permitted. From a4446b1c5a24028e53f468593530123576166cf9 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Mon, 9 Oct 2023 13:01:48 +0100 Subject: [PATCH 3046/4498] drivers: sensor: npm1300_charger: Added die temp measurement Support for die temperature reading added Signed-off-by: Andy Sinclair --- .../sensor/npm1300_charger/npm1300_charger.c | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c index cef044d0034..c6cfd8cbe2e 100644 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -35,6 +35,7 @@ struct npm1300_charger_data { uint16_t voltage; uint16_t current; uint16_t temp; + uint16_t dietemp; uint8_t status; uint8_t error; uint8_t ibat_stat; @@ -66,6 +67,7 @@ struct npm1300_charger_data { /* nPM1300 ADC register offsets */ #define ADC_OFFSET_TASK_VBAT 0x00U #define ADC_OFFSET_TASK_TEMP 0x01U +#define ADC_OFFSET_TASK_DIE 0x02U #define ADC_OFFSET_CONFIG 0x09U #define ADC_OFFSET_NTCR_SEL 0x0AU #define ADC_OFFSET_TASK_AUTO 0x0CU @@ -104,6 +106,7 @@ struct adc_results_t { #define ADC_LSB_MASK 0x03U #define ADC_LSB_VBAT_SHIFT 0U #define ADC_LSB_NTC_SHIFT 2U +#define ADC_LSB_DIE_SHIFT 4U #define ADC_LSB_IBAT_SHIFT 4U /* NTC temp masks */ @@ -151,6 +154,17 @@ static void calc_temp(const struct npm1300_charger_config *const config, uint16_ valp->val2 = (int32_t)(fmodf(temp, 1.f) * 1000000.f); } +static void calc_dietemp(const struct npm1300_charger_config *const config, uint16_t code, + struct sensor_value *valp) +{ + /* Ref: Datasheet Figure 36: Die temperature (Celcius) */ + int32_t temp = + DIETEMP_OFFSET_MDEGC - (((int32_t)code * DIETEMP_FACTOR_MUL) / DIETEMP_FACTOR_DIV); + + valp->val1 = temp / 1000; + valp->val2 = (temp % 1000) * 1000; +} + static uint32_t calc_ntc_res(const struct npm1300_charger_config *const config, int32_t temp_mdegc) { float inv_t0 = 1.f / 298.15f; @@ -230,6 +244,9 @@ int npm1300_charger_channel_get(const struct device *dev, enum sensor_channel ch valp->val1 = config->dischg_limit_microamp / 1000000; valp->val2 = config->dischg_limit_microamp % 1000000; break; + case SENSOR_CHAN_DIE_TEMP: + calc_dietemp(config, data->dietemp, valp); + break; default: return -ENOTSUP; } @@ -264,11 +281,12 @@ int npm1300_charger_sample_fetch(const struct device *dev, enum sensor_channel c data->voltage = adc_get_res(results.msb_vbat, results.lsb_a, ADC_LSB_VBAT_SHIFT); data->temp = adc_get_res(results.msb_ntc, results.lsb_a, ADC_LSB_NTC_SHIFT); + data->dietemp = adc_get_res(results.msb_die, results.lsb_a, ADC_LSB_DIE_SHIFT); data->current = adc_get_res(results.msb_ibat, results.lsb_b, ADC_LSB_IBAT_SHIFT); data->ibat_stat = results.ibat_stat; - /* Trigger temperature measurement */ - ret = mfd_npm1300_reg_write(config->mfd, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); + /* Trigger ntc and die temperature measurements */ + ret = mfd_npm1300_reg_write2(config->mfd, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U, 1U); if (ret != 0) { return ret; } @@ -550,8 +568,8 @@ int npm1300_charger_init(const struct device *dev) return ret; } - /* Trigger temperature measurement */ - ret = mfd_npm1300_reg_write(config->mfd, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); + /* Trigger ntc and die temperature measurements */ + ret = mfd_npm1300_reg_write2(config->mfd, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U, 1U); if (ret != 0) { return ret; } From 5b8a2f910e608fbacf84a52f37274c81d7821302 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 11:38:43 -0500 Subject: [PATCH 3047/4498] drivers: can: Fix handler syscalls Z_OOPS->K_OOPS Fix can handlers calling removed Z_OOPS instead of K_OOPS Signed-off-by: Declan Snyder --- drivers/can/can_handlers.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 1e10baf79ca..1894a0220af 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -248,7 +248,7 @@ static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeo static inline uint32_t z_vrfy_can_stats_get_bit_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit_errors(dev); } @@ -256,7 +256,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit0_errors(dev); } @@ -264,7 +264,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_bit1_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit1_errors(dev); } @@ -272,7 +272,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit1_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_stuff_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_stuff_errors(dev); } @@ -280,7 +280,7 @@ static inline uint32_t z_vrfy_can_stats_get_stuff_errors(const struct device *de static inline uint32_t z_vrfy_can_stats_get_crc_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_crc_errors(dev); } @@ -288,7 +288,7 @@ static inline uint32_t z_vrfy_can_stats_get_crc_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_form_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_form_errors(dev); } @@ -296,7 +296,7 @@ static inline uint32_t z_vrfy_can_stats_get_form_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_ack_errors(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_ack_errors(dev); } @@ -304,7 +304,7 @@ static inline uint32_t z_vrfy_can_stats_get_ack_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_rx_overruns(const struct device *dev) { - Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_rx_overruns(dev); } From 6c25136e604ae54f332d60458bc604c71cb5f070 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 14:34:47 -0500 Subject: [PATCH 3048/4498] drivers: can: Fix Z_SYSCALL_OBJ->K_SYSCALL_OBJ Fix can handler calling removed Z_SYSCALL_OBJ instead of K_SYSCALL_OBJ Signed-off-by: Declan Snyder --- drivers/can/can_handlers.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 1894a0220af..57201ce6eca 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -248,7 +248,7 @@ static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeo static inline uint32_t z_vrfy_can_stats_get_bit_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit_errors(dev); } @@ -256,7 +256,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit0_errors(dev); } @@ -264,7 +264,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit0_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_bit1_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_bit1_errors(dev); } @@ -272,7 +272,7 @@ static inline uint32_t z_vrfy_can_stats_get_bit1_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_stuff_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_stuff_errors(dev); } @@ -280,7 +280,7 @@ static inline uint32_t z_vrfy_can_stats_get_stuff_errors(const struct device *de static inline uint32_t z_vrfy_can_stats_get_crc_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_crc_errors(dev); } @@ -288,7 +288,7 @@ static inline uint32_t z_vrfy_can_stats_get_crc_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_form_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_form_errors(dev); } @@ -296,7 +296,7 @@ static inline uint32_t z_vrfy_can_stats_get_form_errors(const struct device *dev static inline uint32_t z_vrfy_can_stats_get_ack_errors(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_ack_errors(dev); } @@ -304,7 +304,7 @@ static inline uint32_t z_vrfy_can_stats_get_ack_errors(const struct device *dev) static inline uint32_t z_vrfy_can_stats_get_rx_overruns(const struct device *dev) { - K_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); return z_impl_can_stats_get_rx_overruns(dev); } From 049b67aca94f0f6d79a83d48cc4882b36e39d885 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Fri, 3 Nov 2023 16:12:58 -0700 Subject: [PATCH 3049/4498] subsys/shell/backends: Fix shell_telnet.c build with clang It declares a variable inside a switch statement without brackets to properly delimit the scope, making clang barf. This patch adds them. Signed-off-by: Ederson de Souza --- subsys/shell/backends/shell_telnet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/shell/backends/shell_telnet.c b/subsys/shell/backends/shell_telnet.c index 8aded7e022c..a4dab627299 100644 --- a/subsys/shell/backends/shell_telnet.c +++ b/subsys/shell/backends/shell_telnet.c @@ -99,6 +99,7 @@ static void telnet_reply_dont_command(struct telnet_simple_command *cmd) { switch (cmd->opt) { case NVT_OPT_ECHO: + { int ret = telnet_echo_set(sh_telnet->shell_context, false); if (ret >= 0) { @@ -107,6 +108,7 @@ static void telnet_reply_dont_command(struct telnet_simple_command *cmd) cmd->op = NVT_CMD_WILL; } break; + } default: cmd->op = NVT_CMD_WONT; break; @@ -123,6 +125,7 @@ static void telnet_reply_do_command(struct telnet_simple_command *cmd) cmd->op = NVT_CMD_WILL; break; case NVT_OPT_ECHO: + { int ret = telnet_echo_set(sh_telnet->shell_context, true); if (ret >= 0) { @@ -131,6 +134,7 @@ static void telnet_reply_do_command(struct telnet_simple_command *cmd) cmd->op = NVT_CMD_WONT; } break; + } default: cmd->op = NVT_CMD_WONT; break; From 4664813a12c3500c930538949108feb72b307889 Mon Sep 17 00:00:00 2001 From: Alexander Razinkov Date: Tue, 8 Aug 2023 13:31:18 +0300 Subject: [PATCH 3050/4498] kernel: spinlock: Ticket spinlocks Basic spinlock implementation is based on single atomic variable and doesn't guarantee locking fairness across multiple CPUs. It's even possible that single CPU will win the contention every time which will result in a live-lock. Ticket spinlocks provide a FIFO order of lock aquisition which resolves such unfairness issue at the cost of slightly increased memory footprint. Signed-off-by: Alexander Razinkov --- .../qemu_riscv64/qemu_riscv64_smp_defconfig | 1 + include/zephyr/spinlock.h | 96 +++++++++++++++++-- kernel/Kconfig | 13 +++ 3 files changed, 102 insertions(+), 8 deletions(-) diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig index df0a497cbfe..78b5b74de9a 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig @@ -15,3 +15,4 @@ CONFIG_QEMU_ICOUNT=n CONFIG_IDLE_STACK_SIZE=1024 CONFIG_RISCV_PMP=y +CONFIG_TICKET_SPINLOCKS=y diff --git a/include/zephyr/spinlock.h b/include/zephyr/spinlock.h index 823ff7eea68..51c160b0f85 100644 --- a/include/zephyr/spinlock.h +++ b/include/zephyr/spinlock.h @@ -43,9 +43,28 @@ struct z_spinlock_key { * application code. */ struct k_spinlock { +/** + * @cond INTERNAL_HIDDEN + */ #ifdef CONFIG_SMP +#ifdef CONFIG_TICKET_SPINLOCKS + /* + * Ticket spinlocks are conceptually two atomic variables, + * one indicating the current FIFO head (spinlock owner), + * and the other indicating the current FIFO tail. + * Spinlock is acquired in the following manner: + * - current FIFO tail value is atomically incremented while it's + * original value is saved as a "ticket" + * - we spin until the FIFO head becomes equal to the ticket value + * + * Spinlock is released by atomic increment of the FIFO head + */ + atomic_t owner; + atomic_t tail; +#else atomic_t locked; -#endif +#endif /* CONFIG_TICKET_SPINLOCKS */ +#endif /* CONFIG_SMP */ #ifdef CONFIG_SPIN_VALIDATE /* Stores the thread that holds the lock with the locking CPU @@ -76,6 +95,9 @@ struct k_spinlock { */ char dummy; #endif +/** + * INTERNAL_HIDDEN @endcond + */ }; /* There's a spinlock validation framework available when asserts are @@ -170,10 +192,22 @@ static ALWAYS_INLINE k_spinlock_key_t k_spin_lock(struct k_spinlock *l) z_spinlock_validate_pre(l); #ifdef CONFIG_SMP +#ifdef CONFIG_TICKET_SPINLOCKS + /* + * Enqueue ourselves to the end of a spinlock waiters queue + * receiving a ticket + */ + atomic_val_t ticket = atomic_inc(&l->tail); + /* Spin until our ticket is served */ + while (atomic_get(&l->owner) != ticket) { + arch_spin_relax(); + } +#else while (!atomic_cas(&l->locked, 0, 1)) { arch_spin_relax(); } -#endif +#endif /* CONFIG_TICKET_SPINLOCKS */ +#endif /* CONFIG_SMP */ z_spinlock_validate_post(l); return k; @@ -199,16 +233,47 @@ static ALWAYS_INLINE int k_spin_trylock(struct k_spinlock *l, k_spinlock_key_t * z_spinlock_validate_pre(l); #ifdef CONFIG_SMP +#ifdef CONFIG_TICKET_SPINLOCKS + /* + * atomic_get and atomic_cas operations below are not executed + * simultaneously. + * So in theory k_spin_trylock can lock an already locked spinlock. + * To reproduce this the following conditions should be met after we + * executed atomic_get and before we executed atomic_cas: + * + * - spinlock needs to be taken 0xffff_..._ffff + 1 times + * (which requires 0xffff_..._ffff number of CPUs, as k_spin_lock call + * is blocking) or + * - spinlock needs to be taken and released 0xffff_..._ffff times and + * then taken again + * + * In real-life systems this is considered non-reproducible given that + * required actions need to be done during this tiny window of several + * CPU instructions (which execute with interrupt locked, + * so no preemption can happen here) + */ + atomic_val_t ticket_val = atomic_get(&l->owner); + + if (!atomic_cas(&l->tail, ticket_val, ticket_val + 1)) { + goto busy; + } +#else if (!atomic_cas(&l->locked, 0, 1)) { - arch_irq_unlock(key); - return -EBUSY; + goto busy; } -#endif +#endif /* CONFIG_TICKET_SPINLOCKS */ +#endif /* CONFIG_SMP */ z_spinlock_validate_post(l); k->key = key; return 0; + +#ifdef CONFIG_SMP +busy: + arch_irq_unlock(key); + return -EBUSY; +#endif /* CONFIG_SMP */ } /** @@ -249,6 +314,10 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, #endif /* CONFIG_SPIN_VALIDATE */ #ifdef CONFIG_SMP +#ifdef CONFIG_TICKET_SPINLOCKS + /* Give the spinlock to the next CPU in a FIFO */ + atomic_inc(&l->owner); +#else /* Strictly we don't need atomic_clear() here (which is an * exchange operation that returns the old value). We are always * setting a zero and (because we hold the lock) know the existing @@ -257,7 +326,8 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, * Zephyr framework for that. */ atomic_clear(&l->locked); -#endif +#endif /* CONFIG_TICKET_SPINLOCKS */ +#endif /* CONFIG_SMP */ arch_irq_unlock(key.key); } @@ -275,9 +345,15 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, */ static ALWAYS_INLINE bool z_spin_is_locked(struct k_spinlock *l) { +#ifdef CONFIG_TICKET_SPINLOCKS + atomic_val_t ticket_val = atomic_get(&l->owner); + + return !atomic_cas(&l->tail, ticket_val, ticket_val); +#else return l->locked; +#endif /* CONFIG_TICKET_SPINLOCKS */ } -#endif +#endif /* defined(CONFIG_SMP) && defined(CONFIG_TEST) */ /* Internal function: releases the lock, but leaves local interrupts disabled */ static ALWAYS_INLINE void k_spin_release(struct k_spinlock *l) @@ -287,8 +363,12 @@ static ALWAYS_INLINE void k_spin_release(struct k_spinlock *l) __ASSERT(z_spin_unlock_valid(l), "Not my spinlock %p", l); #endif #ifdef CONFIG_SMP +#ifdef CONFIG_TICKET_SPINLOCKS + atomic_inc(&l->owner); +#else atomic_clear(&l->locked); -#endif +#endif /* CONFIG_TICKET_SPINLOCKS */ +#endif /* CONFIG_SMP */ } #if defined(CONFIG_SPIN_VALIDATE) && defined(__GNUC__) diff --git a/kernel/Kconfig b/kernel/Kconfig index 41e97e1809a..4cdd6209264 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1194,6 +1194,19 @@ config KERNEL_COHERENCE may fail strangely. Some assertions exist to catch these mistakes, but not all circumstances can be tested. +config TICKET_SPINLOCKS + bool "Ticket spinlocks for lock acquisition fairness [EXPERIMENTAL]" + select EXPERIMENTAL + help + Basic spinlock implementation is based on single + atomic variable and doesn't guarantee locking fairness + across multiple CPUs. It's even possible that single CPU + will win the contention every time which will result + in a live-lock. + Ticket spinlocks provide a FIFO order of lock acquisition + which resolves such unfairness issue at the cost of slightly + increased memory footprint. + endmenu config TICKLESS_KERNEL From 8fe8f341690c9b7482088be2ea25aa62de4bc84f Mon Sep 17 00:00:00 2001 From: Alexander Razinkov Date: Fri, 8 Sep 2023 11:33:08 +0300 Subject: [PATCH 3051/4498] tests: kernel: spinlock: acquisition fairness test Added test to verify the spinlock acquisition fairness in relation to the CPUs contending for the spinlock. This test is only enabled for Ticket Spinlocks which required to provide such kind of fairness. Signed-off-by: Alexander Razinkov --- tests/kernel/spinlock/CMakeLists.txt | 1 + tests/kernel/spinlock/src/spinlock_fairness.c | 157 ++++++++++++++++++ tests/kernel/spinlock/testcase.yaml | 11 ++ 3 files changed, 169 insertions(+) create mode 100644 tests/kernel/spinlock/src/spinlock_fairness.c diff --git a/tests/kernel/spinlock/CMakeLists.txt b/tests/kernel/spinlock/CMakeLists.txt index 823174ba17e..821ffd70fe8 100644 --- a/tests/kernel/spinlock/CMakeLists.txt +++ b/tests/kernel/spinlock/CMakeLists.txt @@ -6,3 +6,4 @@ project(spinlock) target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/spinlock_error_case.c) +target_sources(app PRIVATE src/spinlock_fairness.c) diff --git a/tests/kernel/spinlock/src/spinlock_fairness.c b/tests/kernel/spinlock/src/spinlock_fairness.c new file mode 100644 index 00000000000..5e5d9c41232 --- /dev/null +++ b/tests/kernel/spinlock/src/spinlock_fairness.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2023 Syntacore. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "zephyr/ztest_test.h" +#include +#include +#include + +#ifdef CONFIG_SCHED_CPU_MASK + +#define STACK_SIZE (8 * 1024) +#define CORES_NUM CONFIG_MP_MAX_NUM_CPUS +#define FAIRNESS_TEST_CYCLES_PER_CORE 1000 + +BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS > 1); + +static K_THREAD_STACK_ARRAY_DEFINE(tstack, CORES_NUM, STACK_SIZE); +static struct k_thread tthread[CORES_NUM]; +static uint32_t spinlock_grabbed[CORES_NUM]; +static atomic_t fairness_test_cycles; +static struct k_spinlock lock; +static atomic_t start_sync; + +static inline struct k_thread *get_thread(uint8_t core_id) +{ + return &tthread[core_id]; +} + +/** + * @brief Execution thread which runs concurrently on each CPU in the system + * + * @param [in] arg1 - thread argument 1 + * @param [in] arg2 - thread argument 2 + * @param [in] arg3 - thread argument 3 + */ +static void test_thread(void *arg1, void *arg2, void *arg3) +{ + int core_id = (uintptr_t)arg1; + + /* Synchronize all the cores as much as possible */ + int key = arch_irq_lock(); + + atomic_dec(&start_sync); + while (atomic_get(&start_sync) != 0) + ; + + /* + * Run the test: let the cores contend for the spinlock and + * collect the spinlock acquisition statistics + */ + do { + k_spinlock_key_t spinlock_key = k_spin_lock(&lock); + + if (atomic_get(&fairness_test_cycles) == 0) { + k_spin_unlock(&lock, spinlock_key); + arch_irq_unlock(key); + return; + } + + spinlock_grabbed[core_id]++; + + /* Imitate some work which takes time */ + volatile uint32_t countdown = 10000; + + while (countdown--) + ; + + atomic_dec(&fairness_test_cycles); + + k_spin_unlock(&lock, spinlock_key); + } while (atomic_get(&fairness_test_cycles) != 0); + + arch_irq_unlock(key); +} + +static void test_init(void) +{ + memset(tthread, 0x00, sizeof(tthread)); + memset(tstack, 0x00, sizeof(tstack)); + atomic_set(&start_sync, CORES_NUM); + atomic_set(&fairness_test_cycles, FAIRNESS_TEST_CYCLES_PER_CORE * CORES_NUM); + + for (uintptr_t core_id = 0; core_id < CORES_NUM; core_id++) { + struct k_thread *thread = get_thread(core_id); + + k_thread_create(thread, tstack[core_id], STACK_SIZE, + (k_thread_entry_t)test_thread, + (void *)core_id, NULL, NULL, + K_PRIO_COOP(10), 0, K_FOREVER); + + /* + * Pin each thread to a particular CPU core. + * The larger the core's memory access latency in comparison to the + * other cores - the less chances to win a contention for the spinlock + * this core will have in case the spinlock implementation doesn't + * provide acquisition fairness. + */ + k_thread_cpu_pin(thread, core_id); + } +} + +/** + * @brief Test spinlock acquisition fairness + * + * @details This test verifies a spinlock acquisition fairness in relation + * to the cores contending for the spinlock. Memory access latency may + * vary between the CPU cores, so that some CPUs reach the spinlock faster + * than the others and depending on spinlock implementation may get + * higher chance to win the contention for the spinlock than the other + * cores, making them to starve. + * This effect may become critical for some real-life platforms + * (e.g. NUMA) resulting in performance loss or even a live-lock, + * when a single CPU is continuously winning the contention. + * This test ensures that the probability to win the contention for a + * spinlock is evenly distributed between all of the contending cores. + * + * @ingroup kernel_spinlock_tests + * + * @see k_spin_lock(), k_spin_unlock() + */ +ZTEST(spinlock, test_spinlock_fairness) +{ + test_init(); + + /* Launching all the threads */ + for (uint8_t core_id = 0; core_id < CORES_NUM; core_id++) { + struct k_thread *thread = get_thread(core_id); + + k_thread_start(thread); + } + /* Waiting for all the threads to complete */ + for (uint8_t core_id = 0; core_id < CORES_NUM; core_id++) { + struct k_thread *thread = get_thread(core_id); + + k_thread_join(thread, K_FOREVER); + } + + /* Print statistics */ + for (uint8_t core_id = 0; core_id < CORES_NUM; core_id++) { + printk("CPU%u acquired spinlock %u times, expected %u\n", + core_id, spinlock_grabbed[core_id], FAIRNESS_TEST_CYCLES_PER_CORE); + } + + /* Verify spinlock acquisition fairness */ + for (uint8_t core_id = 0; core_id < CORES_NUM; core_id++) { + if (spinlock_grabbed[core_id] < FAIRNESS_TEST_CYCLES_PER_CORE) { + zassert_false(spinlock_grabbed[core_id] < FAIRNESS_TEST_CYCLES_PER_CORE, + "CPU%d starved on a spinlock: acquired %u times, expected %u\n", + core_id, spinlock_grabbed[core_id], FAIRNESS_TEST_CYCLES_PER_CORE); + } + } +} + +#endif /* CONFIG_SCHED_CPU_MASK */ diff --git a/tests/kernel/spinlock/testcase.yaml b/tests/kernel/spinlock/testcase.yaml index 7844db39e61..3b1bd6ea513 100644 --- a/tests/kernel/spinlock/testcase.yaml +++ b/tests/kernel/spinlock/testcase.yaml @@ -19,3 +19,14 @@ tests: - smp extra_configs: - CONFIG_MINIMAL_LIBC=y + kernel.multiprocessing.spinlock_fairness: + tags: + - kernel + - smp + - spinlock + filter: CONFIG_SMP and CONFIG_MP_MAX_NUM_CPUS > 1 and CONFIG_MP_MAX_NUM_CPUS <= 4 + depends_on: + - smp + extra_configs: + - CONFIG_SCHED_CPU_MASK=y + - CONFIG_TICKET_SPINLOCKS=y From 5725585112dd95c3bab221781ae682cd8b47bb6c Mon Sep 17 00:00:00 2001 From: Alexander Razinkov Date: Tue, 19 Sep 2023 13:34:12 +0300 Subject: [PATCH 3052/4498] tests: kernel: common: added test on atomic_t overflow Added test to verify that the value of atomic_t will be the same in case of overflow if incremented in atomic and non-atomic manner Signed-off-by: Alexander Razinkov --- tests/kernel/common/src/atomic.c | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/kernel/common/src/atomic.c b/tests/kernel/common/src/atomic.c index 02b97fb1e85..af5273ed25b 100644 --- a/tests/kernel/common/src/atomic.c +++ b/tests/kernel/common/src/atomic.c @@ -338,6 +338,51 @@ ZTEST(atomic, test_threads_access_atomic) "atomic counting failure"); } +/** + * @brief Checks that the value of atomic_t will be the same in case of overflow + * if incremented in atomic and non-atomic manner + * + * @details According to C standard the value of a signed variable + * is undefined in case of overflow. This test checks that the the value + * of atomic_t will be the same in case of overflow if incremented in atomic + * and non-atomic manner. This allows us to increment an atomic variable + * in a non-atomic manner (as long as it is logically safe) + * and expect its value to match the result of the similar atomic increment. + * + * @ingroup kernel_common_tests + */ +ZTEST(atomic, test_atomic_overflow) +{ + /* Check overflow over max signed value */ + uint64_t overflowed_value = (uint64_t)1 << (ATOMIC_BITS - 1); + atomic_val_t atomic_value = overflowed_value - 1; + atomic_t atomic_var = ATOMIC_INIT(atomic_value); + + atomic_value++; + atomic_inc(&atomic_var); + + zassert_true(atomic_value == atomic_get(&atomic_var), + "max signed overflow mismatch: %lx/%lx", + atomic_value, atomic_get(&atomic_var)); + zassert_true(atomic_value == (atomic_val_t)overflowed_value, + "unexpected value after overflow: %lx, expected: %lx", + atomic_value, (atomic_val_t)overflowed_value); + + /* Check overflow over max unsigned value */ + atomic_value = -1; + atomic_var = ATOMIC_INIT(atomic_value); + + atomic_value++; + atomic_inc(&atomic_var); + + zassert_true(atomic_value == atomic_get(&atomic_var), + "max unsigned overflow mismatch: %lx/%lx", + atomic_value, atomic_get(&atomic_var)); + zassert_true(atomic_value == 0, + "unexpected value after overflow: %lx, expected: 0", + atomic_value); +} + extern void *common_setup(void); ZTEST_SUITE(atomic, NULL, common_setup, NULL, NULL, NULL); /** From 014666bf05a4a9bde4c4eee72942c2c08e8c9831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 16:41:29 +0100 Subject: [PATCH 3053/4498] MAINTAINERS: add some missing (mainly doc-related) entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added several documentation pages/folders (including boards and samples) to relevant areas. Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f7d08c0d511..ccf6b933bf6 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -139,6 +139,7 @@ ARC arch: - include/zephyr/arch/arc/ - tests/arch/arc/ - dts/arc/synopsys/ + - doc/hardware/arch/arc-support-status.rst labels: - "area: ARC" @@ -647,6 +648,7 @@ Display drivers: - include/zephyr/drivers/display.h - subsys/fb/ - samples/subsys/display/ + - doc/hardware/peripherals/display/ labels: - "area: Display" @@ -933,6 +935,7 @@ Release Notes: - include/zephyr/drivers/eeprom.h - samples/drivers/eeprom/ - tests/drivers/eeprom/ + - doc/hardware/peripherals/eeprom.rst labels: - "area: EEPROM" @@ -944,6 +947,7 @@ Release Notes: - drivers/entropy/ - include/zephyr/drivers/entropy.h - tests/drivers/entropy/ + - doc/hardware/peripherals/entropy.rst labels: - "area: Crypto / RNG" @@ -1278,6 +1282,7 @@ Release Notes: files: - drivers/pcie/ - include/zephyr/drivers/pcie/ + - doc/hardware/peripherals/pcie.rst labels: - "area: PCI" @@ -1452,6 +1457,7 @@ Release Notes: - drivers/video/ - include/zephyr/drivers/video.h - include/zephyr/drivers/video-controls.h + - doc/hardware/peripherals/video.rst labels: - "area: Video" @@ -1875,6 +1881,8 @@ Modem Modules: - subsys/modem/ - include/zephyr/modem/ - tests/subsys/modem/ + - doc/services/modem/ + - samples/net/cellular_modem/ OSDP: status: maintained @@ -2224,6 +2232,7 @@ Retention: - dts/bindings/retention/ - include/zephyr/retention/ - subsys/retention/ + - doc/services/retention/ labels: - "area: Retention" @@ -2701,6 +2710,7 @@ STM32 Platforms: - Desvauxm-st - GeorgeCGV files: + - boards/arm/b_*/ - boards/arm/nucleo_*/ - boards/arm/stm32*_disco/ - boards/arm/stm32*_dk*/ @@ -3005,6 +3015,7 @@ USB-C: - samples/subsys/usb_c/ - subsys/usb/usb_c/ - doc/connectivity/usb/pd/ + - doc/hardware/peripherals/usbc_vbus.rst labels: - "area: USB-C" From e466b7ac266b24fe4e1c27b01fef3a722e18ddd3 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 26 Oct 2023 09:08:54 +0200 Subject: [PATCH 3054/4498] twister: pytest: Improve reporting failed pytest scenarios When pytest scenario fails, then 'handler.log' is printed. Changed to print 'twister_harness.log' that is a log from pytest execution. That file tells much more when test fails. Signed-off-by: Grzegorz Chwierut --- .../device/hardware_adapter.py | 1 - scripts/pylib/twister/twisterlib/harness.py | 2 ++ scripts/pylib/twister/twisterlib/reports.py | 5 +++- scripts/pylib/twister/twisterlib/runner.py | 26 +++++++++++++++---- .../pytest_integration/test_harness_pytest.py | 2 ++ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 403978eed9a..3b7bf5d8214 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -116,7 +116,6 @@ def _flash_and_run(self) -> None: stdout_decoded = stdout.decode(errors='ignore') with open(self.device_log_path, 'a+') as log_file: log_file.write(stdout_decoded) - logger.debug(f'Flashing output:\n{stdout_decoded}') if self.device_config.post_flash_script: self._run_custom_script(self.device_config.post_flash_script, self.base_timeout) if process is not None and process.returncode == 0: diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index f5079f62c1f..53765f6da38 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -421,8 +421,10 @@ def _parse_report_file(self, report): if elem_ts := root.find('testsuite'): if elem_ts.get('failures') != '0': self.state = 'failed' + self.instance.reason = f"{elem_ts.get('failures')}/{elem_ts.get('tests')} pytest scenario(s) failed" elif elem_ts.get('errors') != '0': self.state = 'error' + self.instance.reason = 'Error during pytest execution' elif elem_ts.get('skipped') == elem_ts.get('tests'): self.state = 'skipped' else: diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index c1f160caad9..be1bbb4dbd7 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -246,6 +246,7 @@ def json_report(self, filename, version="NA"): for instance in self.instances.values(): suite = {} handler_log = os.path.join(instance.build_dir, "handler.log") + pytest_log = os.path.join(instance.build_dir, "twister_harness.log") build_log = os.path.join(instance.build_dir, "build.log") device_log = os.path.join(instance.build_dir, "device.log") @@ -284,7 +285,9 @@ def json_report(self, filename, version="NA"): suite['status'] = instance.status suite["reason"] = instance.reason # FIXME - if os.path.exists(handler_log): + if os.path.exists(pytest_log): + suite["log"] = self.process_log(pytest_log) + elif os.path.exists(handler_log): suite["log"] = self.process_log(handler_log) elif os.path.exists(device_log): suite["log"] = self.process_log(device_log) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 13c2bad7b91..94c24a837d8 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -40,6 +40,9 @@ from twisterlib.log_helper import log_command from twisterlib.testinstance import TestInstance +from twisterlib.environment import TwisterEnv +from twisterlib.testsuite import TestSuite +from twisterlib.platform import Platform from twisterlib.testplan import change_skip_to_error_if_integration from twisterlib.harness import HarnessImporter, Pytest @@ -220,7 +223,7 @@ class CMake: config_re = re.compile('(CONFIG_[A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$') dt_re = re.compile('([A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$') - def __init__(self, testsuite, platform, source_dir, build_dir, jobserver): + def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_dir, jobserver): self.cwd = None self.capture_output = True @@ -414,7 +417,7 @@ def run_cmake(self, args="", filter_stages=[]): class FilterBuilder(CMake): - def __init__(self, testsuite, platform, source_dir, build_dir, jobserver): + def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_dir, jobserver): super().__init__(testsuite, platform, source_dir, build_dir, jobserver) self.log = "config-twister.log" @@ -517,7 +520,7 @@ def parse_generated(self, filter_stages=[]): class ProjectBuilder(FilterBuilder): - def __init__(self, instance, env, jobserver, **kwargs): + def __init__(self, instance: TestInstance, env: TwisterEnv, jobserver, **kwargs): super().__init__(instance.testsuite, instance.platform, instance.testsuite.source_dir, instance.build_dir, jobserver) self.log = "build.log" @@ -527,8 +530,7 @@ def __init__(self, instance, env, jobserver, **kwargs): self.env = env self.duts = None - @staticmethod - def log_info(filename, inline_logs): + def log_info(self, filename, inline_logs, log_testcases=False): filename = os.path.abspath(os.path.realpath(filename)) if inline_logs: logger.info("{:-^100}".format(filename)) @@ -542,6 +544,17 @@ def log_info(filename, inline_logs): logger.error(data) logger.info("{:-^100}".format(filename)) + + if log_testcases: + for tc in self.instance.testcases: + if not tc.reason: + continue + logger.info( + f"\n{str(tc.name).center(100, '_')}\n" + f"{tc.reason}\n" + f"{100*'_'}\n" + f"{tc.output}" + ) else: logger.error("see: " + Fore.YELLOW + filename + Fore.RESET) @@ -551,9 +564,12 @@ def log_info_file(self, inline_logs): b_log = "{}/build.log".format(build_dir) v_log = "{}/valgrind.log".format(build_dir) d_log = "{}/device.log".format(build_dir) + pytest_log = "{}/twister_harness.log".format(build_dir) if os.path.exists(v_log) and "Valgrind" in self.instance.reason: self.log_info("{}".format(v_log), inline_logs) + elif os.path.exists(pytest_log) and os.path.getsize(pytest_log) > 0: + self.log_info("{}".format(pytest_log), inline_logs, log_testcases=True) elif os.path.exists(h_log) and os.path.getsize(h_log) > 0: self.log_info("{}".format(h_log), inline_logs) elif os.path.exists(d_log) and os.path.getsize(d_log) > 0: diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index ab4baf88656..150980059b3 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -188,6 +188,8 @@ def test_err(): assert tc.status == "failed" assert tc.output assert tc.reason + assert testinstance.reason + assert '2/2' in testinstance.reason def test_if_report_with_skip(pytester, testinstance: TestInstance): From 774858c6dc88578fed6698dd147de53735e90c81 Mon Sep 17 00:00:00 2001 From: Greter Raffael Date: Tue, 31 Oct 2023 11:30:29 +0100 Subject: [PATCH 3055/4498] ztest: Add comfort functions for non-zero return codes Many functions return non-zero return codes on errors. I added an assert for the case, when a function is expected to fail. It is just a shorthand for `zassert_not_equal(0, ret);`, analogous to `zassert_ok`, introduced in c5d85e175fae85dce4236d20a92717e084b57709. I also added the corresponding `zassume_nok` and `zexpect_nok`. Signed-off-by: Greter Raffael --- .../ztest/include/zephyr/ztest_assert.h | 26 +++++++++++++++++++ tests/ztest/base/src/main.c | 1 + tests/ztest/zexpect/src/main.c | 11 ++++++++ 3 files changed, 38 insertions(+) diff --git a/subsys/testsuite/ztest/include/zephyr/ztest_assert.h b/subsys/testsuite/ztest/include/zephyr/ztest_assert.h index 5b88357bd40..b84b72c8d66 100644 --- a/subsys/testsuite/ztest/include/zephyr/ztest_assert.h +++ b/subsys/testsuite/ztest/include/zephyr/ztest_assert.h @@ -282,6 +282,13 @@ static inline bool z_zexpect(bool cond, const char *default_msg, const char *fil */ #define zassert_ok(cond, ...) zassert(!(cond), #cond " is non-zero", ##__VA_ARGS__) +/** + * @brief Assert that @a cond is not 0 (failure) + * @param cond Condition to check + * @param ... Optional message and variables to print if the assertion fails + */ +#define zassert_not_ok(cond, ...) zassert(!!(cond), #cond " is zero", ##__VA_ARGS__) + /** * @brief Assert that @a ptr is NULL * @param ptr Pointer to compare @@ -425,6 +432,16 @@ static inline bool z_zexpect(bool cond, const char *default_msg, const char *fil */ #define zassume_ok(cond, ...) zassume(!(cond), #cond " is non-zero", ##__VA_ARGS__) +/** + * @brief Assume that @a cond is not 0 (failure) + * + * If the assumption fails, the test will be marked as "skipped". + * + * @param cond Condition to check + * @param ... Optional message and variables to print if the assumption fails + */ +#define zassume_not_ok(cond, ...) zassume(!!(cond), #cond " is zero", ##__VA_ARGS__) + /** * @brief Assume that @a ptr is NULL * @@ -578,6 +595,15 @@ static inline bool z_zexpect(bool cond, const char *default_msg, const char *fil */ #define zexpect_ok(cond, ...) zexpect(!(cond), #cond " is non-zero", ##__VA_ARGS__) +/** + * @brief Expect that @a cond is not 0 (failure), otherwise mark test as failed but continue its + * execution. + * + * @param cond Condition to check + * @param ... Optional message and variables to print if the expectation fails + */ +#define zexpect_not_ok(cond, ...) zexpect(!!(cond), #cond " is zero", ##__VA_ARGS__) + /** * @brief Expect that @a ptr is NULL, otherwise mark test as failed but continue its execution. * diff --git a/tests/ztest/base/src/main.c b/tests/ztest/base/src/main.c index 561b63ad5bc..5a18c15bab1 100644 --- a/tests/ztest/base/src/main.c +++ b/tests/ztest/base/src/main.c @@ -20,6 +20,7 @@ ZTEST(framework_tests, test_assert_tests) zassert_not_null("foo", NULL); zassert_equal(1, 1); zassert_equal_ptr(NULL, NULL, NULL); + zassert_not_ok(-EIO); } ZTEST(framework_tests, test_assert_mem_equal) diff --git a/tests/ztest/zexpect/src/main.c b/tests/ztest/zexpect/src/main.c index 492257af749..fb05c944c6d 100644 --- a/tests/ztest/zexpect/src/main.c +++ b/tests/ztest/zexpect/src/main.c @@ -59,6 +59,17 @@ ZTEST(expect, test_fail_expect_ok) zexpect_ok(5); } +ZTEST(expect, test_expect_not_ok) +{ + zexpect_not_ok(-EIO); +} + +ZTEST_EXPECT_FAIL(expect, test_fail_expect_not_ok); +ZTEST(expect, test_fail_expect_not_ok) +{ + zexpect_not_ok(0); +} + ZTEST(expect, test_expect_is_null) { void *ptr = NULL; From 2fbcb46a60e8dab01fca2f9808f4c1eef894c2e0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 4 Nov 2023 14:32:07 +0000 Subject: [PATCH 3056/4498] boards: m5stack_core2: do not use as default test platform Only quemu boards are used as default in CI, drop the default property from this one. Signed-off-by: Fabio Baltieri --- boards/xtensa/m5stack_core2/m5stack_core2.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.yaml b/boards/xtensa/m5stack_core2/m5stack_core2.yaml index bb929e2abc0..35dd0c12b46 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.yaml +++ b/boards/xtensa/m5stack_core2/m5stack_core2.yaml @@ -14,7 +14,6 @@ supported: - pinmux - nvs testing: - default: true ignore_tags: - net - bluetooth From 6308528e5bc2869e1a4208d5bd645d464de5f926 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 4 Oct 2023 15:34:10 +0300 Subject: [PATCH 3057/4498] tests: k_mbox: Simplify code and check return code k_mbox_get() / k_mbox_put() get timeout as is, so there is no need for extra code. Also check that k_mbox_put() actually sends message. Signed-off-by: Andrei Emeltchenko --- tests/kernel/mbox/mbox_usage/src/main.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/kernel/mbox/mbox_usage/src/main.c b/tests/kernel/mbox/mbox_usage/src/main.c index 10b95df3a2c..d7e22aacd69 100644 --- a/tests/kernel/mbox/mbox_usage/src/main.c +++ b/tests/kernel/mbox/mbox_usage/src/main.c @@ -32,6 +32,7 @@ static enum mmsg_type { static void msg_sender(struct k_mbox *pmbox, k_timeout_t timeout) { static struct k_mbox_msg mmsg; + int ret; (void)memset(&mmsg, 0, sizeof(mmsg)); @@ -41,13 +42,9 @@ static void msg_sender(struct k_mbox *pmbox, k_timeout_t timeout) mmsg.info = PUT_GET_NULL; mmsg.size = 0; mmsg.tx_data = NULL; - if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { - k_mbox_put(pmbox, &mmsg, K_FOREVER); - } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { - k_mbox_put(pmbox, &mmsg, K_NO_WAIT); - } else { - k_mbox_put(pmbox, &mmsg, timeout); - } + + ret = k_mbox_put(pmbox, &mmsg, timeout); + zassert_ok(ret, "k_mbox_put() failed, ret %d", ret); break; default: break; @@ -59,20 +56,20 @@ static void msg_receiver(struct k_mbox *pmbox, k_tid_t thd_id, { static struct k_mbox_msg mmsg; static char rxdata[MAIL_LEN]; + int ret; switch (info_type) { case PUT_GET_NULL: mmsg.size = sizeof(rxdata); mmsg.rx_source_thread = thd_id; + + ret = k_mbox_get(pmbox, &mmsg, rxdata, timeout); if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { - zassert_true(k_mbox_get(pmbox, &mmsg, - rxdata, K_FOREVER) == 0, NULL); + zassert_ok(ret, "k_mbox_get() ret %d", ret); } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { - zassert_false(k_mbox_get(pmbox, &mmsg, - rxdata, K_NO_WAIT) == 0, NULL); + zassert_false(ret == 0, "k_mbox_get() ret %d", ret); } else { - zassert_true(k_mbox_get(pmbox, &mmsg, - rxdata, timeout) == 0, NULL); + zassert_ok(ret, "k_mbox_get() ret %d", ret); } break; default: From 6247dddcb549a6b532b22e41434b67abe2b43c8e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 4 Oct 2023 15:38:50 +0300 Subject: [PATCH 3058/4498] tests: k_mbox: Remove unneeded k_sleep() The test_multi_thread_send_get() test sends and receives mbox messages with K_FOREVER as timeout, so k_sleep() is not needed here. Signed-off-by: Andrei Emeltchenko --- tests/kernel/mbox/mbox_usage/src/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/kernel/mbox/mbox_usage/src/main.c b/tests/kernel/mbox/mbox_usage/src/main.c index d7e22aacd69..4db1efbcfe7 100644 --- a/tests/kernel/mbox/mbox_usage/src/main.c +++ b/tests/kernel/mbox/mbox_usage/src/main.c @@ -175,7 +175,6 @@ ZTEST_USER(mbox_usage_1cpu, test_multi_thread_send_get) thread_high_prio, &multi_tmbox, NULL, NULL, HIGH_PRIO, 0, K_NO_WAIT); - k_sleep(K_MSEC(20)); mmsg.size = sizeof(msg_data[0]); mmsg.tx_data = msg_data[0]; mmsg.tx_target_thread = K_ANY; From a6da17aab49fa1a63900f21d05fa6380727b63ea Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 4 Oct 2023 15:52:32 +0300 Subject: [PATCH 3059/4498] tests: k_mbox: Change ZTEST_USER to ZTEST Since userspace is not enabled change ZTEST_USER to ZTEST to not confuse people, other tests are also ZTEST. Signed-off-by: Andrei Emeltchenko --- tests/kernel/mbox/mbox_usage/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kernel/mbox/mbox_usage/src/main.c b/tests/kernel/mbox/mbox_usage/src/main.c index 4db1efbcfe7..e472d22e658 100644 --- a/tests/kernel/mbox/mbox_usage/src/main.c +++ b/tests/kernel/mbox/mbox_usage/src/main.c @@ -160,7 +160,7 @@ static void thread_high_prio(void *p1, void *p2, void *p3) k_sem_give(&sync_sema); } -ZTEST_USER(mbox_usage_1cpu, test_multi_thread_send_get) +ZTEST(mbox_usage_1cpu, test_multi_thread_send_get) { static k_tid_t low_prio, high_prio; struct k_mbox_msg mmsg = {0}; From d5a1a8bf04c9a4a1f7b9c73f2426368e93844143 Mon Sep 17 00:00:00 2001 From: Marek Matej Date: Mon, 30 Oct 2023 23:23:01 +0100 Subject: [PATCH 3060/4498] drivers: wifi: esp32: Fix compilation error Fix function declaration. Signed-off-by: Marek Matej --- drivers/wifi/esp32/src/esp_wifi_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index ba6717ad634..bb89f3e8d2d 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -61,7 +61,7 @@ struct esp32_wifi_runtime { uint8_t state; }; -static void esp_wifi_event_task(void); +static void esp_wifi_event_task(void *, void *, void *); K_MSGQ_DEFINE(esp_wifi_msgq, sizeof(system_event_t), 10, 4); K_THREAD_STACK_DEFINE(esp_wifi_event_stack, CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE); From 9b488103aec83e3219af5c52f098b2afbf506634 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 3 Nov 2023 17:26:00 +0000 Subject: [PATCH 3061/4498] input: cst816s: simplify the reset code The current code deasserts the reset, just to re-assert it immediately. Just initialize with OUTPUT_ACTIVE, delay and then de-assert. Signed-off-by: Fabio Baltieri --- drivers/input/input_cst816s.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/input/input_cst816s.c b/drivers/input/input_cst816s.c index 6cebddf3379..9409deb045a 100644 --- a/drivers/input/input_cst816s.c +++ b/drivers/input/input_cst816s.c @@ -173,12 +173,11 @@ static void cst816s_chip_reset(const struct device *dev) int ret; if (gpio_is_ready_dt(&config->rst_gpio)) { - ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_INACTIVE); + ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE); if (ret < 0) { LOG_ERR("Could not configure reset GPIO pin"); return; } - gpio_pin_set_dt(&config->rst_gpio, 1); k_msleep(CST816S_RESET_DELAY); gpio_pin_set_dt(&config->rst_gpio, 0); k_msleep(CST816S_WAIT_DELAY); From 05ab1c5f77de7ada1ea18217765a8f093561fa5c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 3 Nov 2023 17:27:20 +0000 Subject: [PATCH 3062/4498] input: ft5336: fix reset control polarity This chip uses an active low reset, so the correct behavior here is to define the pin as ACTIVE_LOW, using GPIO_OUTPUT_ACTIVE to assert the reset and set to 0 to deassert. Signed-off-by: Fabio Baltieri --- boards/shields/g1120b0mipi/g1120b0mipi.overlay | 2 +- drivers/input/input_ft5336.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/shields/g1120b0mipi/g1120b0mipi.overlay b/boards/shields/g1120b0mipi/g1120b0mipi.overlay index e456a7f31c7..7fec77ee3d7 100644 --- a/boards/shields/g1120b0mipi/g1120b0mipi.overlay +++ b/boards/shields/g1120b0mipi/g1120b0mipi.overlay @@ -33,7 +33,7 @@ compatible = "focaltech,ft5336"; reg = <0x38>; int-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_LOW>; - reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_HIGH>; + reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_LOW>; }; }; diff --git a/drivers/input/input_ft5336.c b/drivers/input/input_ft5336.c index 00649ee4e71..1dd705d80f6 100644 --- a/drivers/input/input_ft5336.c +++ b/drivers/input/input_ft5336.c @@ -153,8 +153,8 @@ static int ft5336_init(const struct device *dev) k_work_init(&data->work, ft5336_work_handler); if (config->reset_gpio.port != NULL) { - /* Enable reset GPIO, and pull down */ - r = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE); + /* Enable reset GPIO and assert reset */ + r = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); if (r < 0) { LOG_ERR("Could not enable reset GPIO"); return r; @@ -166,7 +166,7 @@ static int ft5336_init(const struct device *dev) */ k_sleep(K_MSEC(5)); /* Pull reset pin high to complete reset sequence */ - r = gpio_pin_set_dt(&config->reset_gpio, 1); + r = gpio_pin_set_dt(&config->reset_gpio, 0); if (r < 0) { return r; } From 0e3d0e9b150fdca37c3baacc2901083b9c1b804b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 3 Nov 2023 17:35:19 +0000 Subject: [PATCH 3063/4498] input: gt911: fix reset control polarity This chip uses an active low reset, so the correct behavior here is to define the pin as ACTIVE_LOW, using GPIO_OUTPUT_ACTIVE to assert the reset and set to 0 to deassert. Signed-off-by: Fabio Baltieri --- boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay | 2 +- boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay | 2 +- drivers/input/input_gt911.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay b/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay index 079596b60d2..4740ee664f1 100644 --- a/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay +++ b/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay @@ -30,7 +30,7 @@ compatible = "goodix,gt911"; reg = <0x5d>; irq-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_HIGH>; - reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_HIGH>; + reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay index 29a90ee0b73..0f4e0c9ce45 100644 --- a/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay +++ b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay @@ -30,7 +30,7 @@ compatible = "goodix,gt911"; reg = <0x5d>; irq-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_HIGH>; - reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_HIGH>; + reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_LOW>; }; }; diff --git a/drivers/input/input_gt911.c b/drivers/input/input_gt911.c index f62be5f1e0f..c7f2d5c90b3 100644 --- a/drivers/input/input_gt911.c +++ b/drivers/input/input_gt911.c @@ -230,7 +230,7 @@ static int gt911_init(const struct device *dev) return -ENODEV; } - r = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_INACTIVE); + r = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE); if (r < 0) { LOG_ERR("Could not configure reset GPIO pin"); return r; @@ -253,10 +253,10 @@ static int gt911_init(const struct device *dev) /* Delay at least 10 ms after power on before we configure gt911 */ k_sleep(K_MSEC(20)); /* reset the device and confgiure the addr mode0 */ - gpio_pin_set_dt(&config->rst_gpio, 0); + gpio_pin_set_dt(&config->rst_gpio, 1); /* hold down at least 1us, 1ms here */ k_sleep(K_MSEC(1)); - gpio_pin_set_dt(&config->rst_gpio, 1); + gpio_pin_set_dt(&config->rst_gpio, 0); /* hold down at least 5ms. This is the point the INT pin must be low. */ k_sleep(K_MSEC(5)); /* hold down 50ms to make sure the address available */ From acb784eb56096c02a6aedbae3d642f8664a306c2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 3 Nov 2023 17:37:57 +0000 Subject: [PATCH 3064/4498] doc: migration guide: add a note about touchscreen reset polarity change Add a note about the fix in reset polarity for ft5336 and gt911. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.6.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index ac5cb746e55..877bff97c3c 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -61,5 +61,10 @@ Other Subsystems :kconfig:option:`CONFIG_CRC`, this was previously erroneously selected if MCUmgr was enabled, when for non-serial transports it was not needed. +* Touchscreen drivers :dtcompatible:`focaltech,ft5336` and + :dtcompatible:`goodix,gt911` were using the incorrect polarity for the + respective ``reset-gpios``. This has been fixed so those signals now have to + be flagged as :c:macro:`GPIO_ACTIVE_LOW` in the devicetree.` + Recommended Changes ******************* From b2174662d66305ae9e8448020ba9eb41522024b7 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 23 Oct 2023 19:55:16 +0200 Subject: [PATCH 3065/4498] tests: Bluetooth: Audio: Add BSIM sync API Add mechanism and API to sync devices via the babblesim backchannels. Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/audio/src/common.c | 184 ++++++++++++++++++ tests/bsim/bluetooth/audio/src/common.h | 9 +- .../_bap_broadcast_audio_assistant.sh | 9 +- .../test_scripts/bap_bass_client_sync.sh | 6 +- .../bap_bass_server_sync_client_rem.sh | 6 +- .../bap_bass_server_sync_server_rem.sh | 6 +- .../audio/test_scripts/bap_broadcast_audio.sh | 8 +- .../audio/test_scripts/bap_unicast_audio.sh | 4 +- .../bap_unicast_audio_acl_disconnect.sh | 4 +- .../audio/test_scripts/cap_broadcast.sh | 4 +- .../audio/test_scripts/cap_unicast.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_1.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_10.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_11_i.sh | 4 +- .../test_scripts/cap_unicast_ac_11_ii.sh | 6 +- .../audio/test_scripts/cap_unicast_ac_2.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_3.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_4.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_5.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_6_i.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_6_ii.sh | 6 +- .../audio/test_scripts/cap_unicast_ac_7_i.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_7_ii.sh | 6 +- .../audio/test_scripts/cap_unicast_ac_8_i.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_8_ii.sh | 6 +- .../audio/test_scripts/cap_unicast_ac_9_i.sh | 4 +- .../audio/test_scripts/cap_unicast_ac_9_ii.sh | 6 +- .../audio/test_scripts/cap_unicast_inval.sh | 4 +- .../audio/test_scripts/cap_unicast_timeout.sh | 4 +- .../bsim/bluetooth/audio/test_scripts/csip.sh | 8 +- .../audio/test_scripts/csip_encrypted_sirk.sh | 8 +- .../audio/test_scripts/csip_forced_release.sh | 8 +- .../audio/test_scripts/csip_no_lock.sh | 8 +- .../audio/test_scripts/csip_no_rank.sh | 8 +- .../audio/test_scripts/csip_no_size.sh | 8 +- .../audio/test_scripts/csip_notify.sh | 4 +- .../bsim/bluetooth/audio/test_scripts/has.sh | 4 +- .../audio/test_scripts/has_offline.sh | 4 +- .../bsim/bluetooth/audio/test_scripts/ias.sh | 4 +- .../bluetooth/audio/test_scripts/mcs_mcc.sh | 4 +- .../audio/test_scripts/media_controller.sh | 6 +- .../bsim/bluetooth/audio/test_scripts/micp.sh | 6 +- .../audio/test_scripts/pacs_notify.sh | 4 +- .../bsim/bluetooth/audio/test_scripts/tbs.sh | 6 +- .../bsim/bluetooth/audio/test_scripts/tmap.sh | 4 +- .../bsim/bluetooth/audio/test_scripts/vcp.sh | 6 +- 46 files changed, 310 insertions(+), 116 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 3e8ca12fcb1..3ad69daf9ae 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -5,6 +5,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "bs_dynargs.h" +#include "bs_pc_backchannel.h" +#include +#include + #include "common.h" extern enum bst_result_t bst_result; @@ -135,3 +140,182 @@ void test_init(void) bst_ticker_set_next_tick_absolute(WAIT_TIME); bst_result = In_progress; } + +#define SYNC_MSG_SIZE 1 +static int32_t dev_cnt; +static uint backchannel_nums[255]; +static uint chan_cnt; + +static void register_more_cmd_args(void) +{ + static bs_args_struct_t args_struct_toadd[] = { + { + .option = "D", + .name = "number_devices", + .type = 'i', + .dest = (void *)&dev_cnt, + .descript = "Number of devices which will connect in this phy", + .is_mandatory = true, + }, + ARG_TABLE_ENDMARKER, + }; + + bs_add_extra_dynargs(args_struct_toadd); +} +NATIVE_TASK(register_more_cmd_args, PRE_BOOT_1, 100); + +/** + * @brief Get the channel id based on remote device ID + * + * The is effectively a very simple hashing function to generate unique channel IDs from device IDs + * + * @param dev 16-bit device ID + * + * @return uint 32-bit channel ID + */ +static uint get_chan_num(uint16_t dev) +{ + uint16_t self = (uint16_t)bsim_args_get_global_device_nbr(); + uint channel_id; + + if (self < dev) { + channel_id = (dev << 16) | self; + } else { + channel_id = (self << 16) | dev; + } + + return channel_id; +} + +/** + * @brief Set up the backchannels between each pair of device + * + * Each pair of devices will get a unique channel + */ +static void setup_backchannels(void) +{ + __ASSERT_NO_MSG(dev_cnt > 0 && dev_cnt < ARRAY_SIZE(backchannel_nums)); + const uint self = bsim_args_get_global_device_nbr(); + uint device_numbers[dev_cnt]; + uint *channels; + + for (int32_t i = 0; i < dev_cnt; i++) { + if (i != self) { /* skip ourselves*/ + backchannel_nums[chan_cnt] = get_chan_num((uint16_t)i); + device_numbers[chan_cnt++] = i; + } + } + + channels = bs_open_back_channel(self, device_numbers, backchannel_nums, chan_cnt); + __ASSERT_NO_MSG(channels != NULL); +} +NATIVE_TASK(setup_backchannels, PRE_BOOT_3, 100); + +static uint get_chan_id_from_chan_num(uint chan_num) +{ + for (uint i = 0; i < ARRAY_SIZE(backchannel_nums); i++) { + if (backchannel_nums[i] == chan_num) { + return i; + } + } + + return 0; +} + +void backchannel_sync_send(uint dev) +{ + const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev)); + uint8_t sync_msg[SYNC_MSG_SIZE] = {0}; + + printk("Sending sync to %u\n", chan_id); + bs_bc_send_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg)); +} + +void backchannel_sync_send_all(void) +{ + for (int32_t i = 0; i < dev_cnt; i++) { + const uint self = bsim_args_get_global_device_nbr(); + + if (i != self) { /* skip ourselves*/ + backchannel_sync_send(i); + } + } +} + +void backchannel_sync_wait(uint dev) +{ + const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev)); + + printk("Waiting for sync to %u\n", chan_id); + + while (true) { + if (bs_bc_is_msg_received(chan_id) > 0) { + uint8_t sync_msg[SYNC_MSG_SIZE]; + + bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg)); + /* We don't really care about the content of the message */ + break; + } + + k_sleep(K_MSEC(1)); + } +} + +void backchannel_sync_wait_all(void) +{ + for (int32_t i = 0; i < dev_cnt; i++) { + const uint self = bsim_args_get_global_device_nbr(); + + if (i != self) { /* skip ourselves*/ + backchannel_sync_wait(i); + } + } +} + +void backchannel_sync_wait_any(void) +{ + while (true) { + for (int32_t i = 0; i < dev_cnt; i++) { + const uint self = bsim_args_get_global_device_nbr(); + + if (i != self) { /* skip ourselves*/ + const uint chan_id = + get_chan_id_from_chan_num(get_chan_num((uint16_t)i)); + + if (bs_bc_is_msg_received(chan_id) > 0) { + uint8_t sync_msg[SYNC_MSG_SIZE]; + + bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg)); + /* We don't really care about the content of the message */ + + return; + } + } + } + + k_sleep(K_MSEC(100)); + } +} + +void backchannel_sync_clear(uint dev) +{ + const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev)); + + while (bs_bc_is_msg_received(chan_id)) { + uint8_t sync_msg[SYNC_MSG_SIZE]; + + bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg)); + /* We don't really care about the content of the message */ + } +} + +void backchannel_sync_clear_all(void) +{ + for (int32_t i = 0; i < dev_cnt; i++) { + const uint self = bsim_args_get_global_device_nbr(); + + if (i != self) { /* skip ourselves*/ + backchannel_sync_clear(i); + } + } +} diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 811a5d2a453..cc0b8d11a96 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -12,10 +12,10 @@ #include +#include "bstests.h" #include "bs_types.h" #include "bs_tracing.h" #include "time_machine.h" -#include "bstests.h" #include #include @@ -97,6 +97,13 @@ extern volatile bt_security_t security_level; void disconnected(struct bt_conn *conn, uint8_t reason); void test_tick(bs_time_t HW_device_time); void test_init(void); +void backchannel_sync_send(uint dev); +void backchannel_sync_send_all(void); +void backchannel_sync_wait(uint dev); +void backchannel_sync_wait_all(void); +void backchannel_sync_wait_any(void); +void backchannel_sync_clear(uint dev); +void backchannel_sync_clear_all(void); struct bap_test_stream { struct bt_bap_stream stream; diff --git a/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh b/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh index 4f649af6395..82fcdff6c13 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh @@ -15,13 +15,16 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running BAP Broadcast Audio Assistant =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_sink_with_assistant -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 \ + -testid=broadcast_sink_with_assistant -rs=24 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=bap_broadcast_assistant_client_sync -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ + -testid=bap_broadcast_assistant_client_sync -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=broadcast_source -rs=69 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 \ + -testid=broadcast_source -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 -sim_length=60e6 $@ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh index 658fb605180..1410af91138 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh @@ -16,14 +16,14 @@ printf "\n\n======== Running BASS Client Sync =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=bap_scan_delegator_client_sync \ - -rs=24 + -rs=24 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ - -testid=bap_broadcast_assistant_client_sync -rs=46 + -testid=bap_broadcast_assistant_client_sync -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_client_rem.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_client_rem.sh index 9c04e187c33..a20060b2e6c 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_client_rem.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_client_rem.sh @@ -28,14 +28,14 @@ printf "\n\n======== Running BASS Server Sync Client Remove =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 \ - -testid=bap_scan_delegator_server_sync_client_rem -rs=24 + -testid=bap_scan_delegator_server_sync_client_rem -rs=24 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ - -testid=bap_broadcast_assistant_server_sync_client_rem -rs=46 + -testid=bap_broadcast_assistant_server_sync_client_rem -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_server_rem.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_server_rem.sh index aec69e55745..65dedab5363 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_server_rem.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_server_sync_server_rem.sh @@ -28,14 +28,14 @@ printf "\n\n======== Running BASS Server Sync Server Remove =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 \ - -testid=bap_scan_delegator_server_sync_server_rem -rs=24 + -testid=bap_scan_delegator_server_sync_server_rem -rs=24 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ - -testid=bap_broadcast_assistant_server_sync_server_rem -rs=46 + -testid=bap_broadcast_assistant_server_sync_server_rem -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio.sh index 10e9af21bbe..c80d54c99ad 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio.sh @@ -16,11 +16,11 @@ printf "\n\n======== Broadcaster test =========\n\n" SIMULATION_ID="broadcaster" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_source -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_source -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=broadcast_sink -rs=27 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=broadcast_sink -rs=27 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ @@ -33,12 +33,12 @@ printf "\n\n======== Broadcaster sink disconnect test =========\n\n" SIMULATION_ID="broadcaster_sink_disconnect" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_source -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_source -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ - -testid=broadcast_sink_disconnect -rs=27 + -testid=broadcast_sink_disconnect -rs=27 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio.sh index 425f20ccff3..c804336ec1f 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Unicast Audio test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server -rs=28 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server -rs=28 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh index 875a2b752dc..e3852b539ab 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Unicast Audio ACL Disconnect test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client_acl_disconnect -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client_acl_disconnect -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server_acl_disconnect -rs=28 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server_acl_disconnect -rs=28 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_broadcast.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_broadcast.sh index cf4f95a49e0..ce2b37d1eae 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_broadcast.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_broadcast.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running CAP broadcast test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_broadcast -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_broadcast -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_broadcast -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_broadcast -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast.sh index 7a888e1ff0e..a4404412b3c 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running CAP unicast test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh index b7b52002c7d..070c0f72820 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh @@ -17,11 +17,11 @@ function Execute_AC_1() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_1 \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh index c1a3a90b51f..2a2179b7b36 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh @@ -17,11 +17,11 @@ function Execute_AC_10() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_10 \ - -RealEncryption=1 -rs=23 -argstest source_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest source_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh index e2cb567d185..1fac51ec6c2 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh @@ -17,11 +17,11 @@ function Execute_AC_11_I() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_11_i \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh index a1f194d92b4..1908be1110b 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh @@ -17,15 +17,15 @@ function Execute_AC_11_II() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_11_ii \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=3 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=69 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh index cb6b9e8d427..dae30f9dead 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh @@ -18,11 +18,11 @@ function Execute_AC_2() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_2 \ - -RealEncryption=1 -rs=23 -argstest source_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest source_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh index 9c303b768e6..4d51d8e3a08 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh @@ -18,11 +18,11 @@ function Execute_AC_3() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_3 \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh index 85ab40eaae0..251e87e0382 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh @@ -17,11 +17,11 @@ function Execute_AC_4() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_4 \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh index bc3cfbffa7f..33b186a7fc3 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh @@ -18,11 +18,11 @@ function Execute_AC_5() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_5 \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_i.sh index 3e34f75be16..7a848655619 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_i.sh @@ -17,11 +17,11 @@ function Execute_AC_6_I() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_6_i \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_ii.sh index e354dd45287..bb3a4dca003 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_6_ii.sh @@ -17,15 +17,15 @@ function Execute_AC_6_II() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_6_ii \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 + -RealEncryption=1 -rs=23 -D=3 -argstest sink_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=69 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh index bf5a9174aa0..af439378c20 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh @@ -17,11 +17,11 @@ function Execute_AC_7_I() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_7_i \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_ii.sh index 1dd957f86dc..bea1ee05173 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_ii.sh @@ -17,15 +17,15 @@ function Execute_AC_7_II() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_7_ii \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=3 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=69 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_i.sh index 00955fd8063..420e08646f4 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_i.sh @@ -17,11 +17,11 @@ function Execute_AC_8_I() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_8_i \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=2 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_ii.sh index 1539bd0ceac..5de94703d69 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_8_ii.sh @@ -17,15 +17,15 @@ function Execute_AC_8_II() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_8_ii \ - -RealEncryption=1 -rs=23 -argstest sink_preset $1 source_preset $2 + -RealEncryption=1 -rs=23 -D=3 -argstest sink_preset $1 source_preset $2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=69 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_i.sh index b6097a88b58..75dc048593f 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_i.sh @@ -17,11 +17,11 @@ function Execute_AC_9_I() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_9_i \ - -RealEncryption=1 -rs=23 -argstest source_preset $1 + -RealEncryption=1 -rs=23 -D=2 -argstest source_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_ii.sh index 5f17668a626..75a02a1e38b 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_9_ii.sh @@ -17,15 +17,15 @@ function Execute_AC_9_II() { Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_ac_9_ii \ - -RealEncryption=1 -rs=23 -argstest source_preset $1 + -RealEncryption=1 -rs=23 -D=3 -argstest source_preset $1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=46 + -RealEncryption=1 -rs=46 -D=3 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=cap_acceptor_unicast \ - -RealEncryption=1 -rs=69 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_inval.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_inval.sh index c868f738d7b..6869821f35b 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_inval.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_inval.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running CAP unicast test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast_inval -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast_inval -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_timeout.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_timeout.sh index 8b806d40959..65b088e9805 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_timeout.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_timeout.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running CAP unicast timeout test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast_timeout -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_initiator_unicast_timeout -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast_timeout -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_acceptor_unicast_timeout -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip.sh b/tests/bsim/bluetooth/audio/test_scripts/csip.sh index 03cf05a14d3..82f929a9779 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip.sh @@ -18,19 +18,19 @@ SIMULATION_ID="csip" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 + -RealEncryption=1 -rs=1 -D=4 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member \ - -RealEncryption=1 -rs=2 -argstest rank 1 + -RealEncryption=1 -rs=2 -D=4 -argstest rank 1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member \ - -RealEncryption=1 -rs=3 -argstest rank 2 + -RealEncryption=1 -rs=3 -D=4 -argstest rank 2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member \ - -RealEncryption=1 -rs=4 -argstest rank 3 + -RealEncryption=1 -rs=4 -D=4 -argstest rank 3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_encrypted_sirk.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_encrypted_sirk.sh index 939234a4beb..96b5c511913 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_encrypted_sirk.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_encrypted_sirk.sh @@ -18,19 +18,19 @@ SIMULATION_ID="csip_sirk_encrypted" printf "\n\n======== Running test with SIRK encrypted ========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 + -RealEncryption=1 -rs=1 -D=4 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member_enc \ - -RealEncryption=1 -rs=2 -argstest rank 1 + -RealEncryption=1 -rs=2 -D=4 -argstest rank 1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member_enc \ - -RealEncryption=1 -rs=3 -argstest rank 2 + -RealEncryption=1 -rs=3 -D=4 -argstest rank 2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member_enc \ - -RealEncryption=1 -rs=4 -argstest rank 3 + -RealEncryption=1 -rs=4 -D=4 -argstest rank 3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_forced_release.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_forced_release.sh index 917fbc590d0..93f945027cf 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_forced_release.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_forced_release.sh @@ -18,19 +18,19 @@ SIMULATION_ID="csip_forced_release" printf "\n\n======== Running test with forced release of lock ========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 + -RealEncryption=1 -rs=1 -D=4 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member \ - -RealEncryption=1 -rs=2 -argstest rank 1 + -RealEncryption=1 -rs=2 -D=4 -argstest rank 1 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member \ - -RealEncryption=1 -rs=3 -argstest rank 2 + -RealEncryption=1 -rs=3 -D=4 -argstest rank 2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member_release \ - -RealEncryption=1 -rs=4 -argstest rank 3 + -RealEncryption=1 -rs=4 -D=4 -argstest rank 3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_no_lock.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_no_lock.sh index 70f54844865..22484600c85 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_no_lock.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_no_lock.sh @@ -17,19 +17,19 @@ SIMULATION_ID="csip_no_lock" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 -argstest no-lock + -RealEncryption=1 -rs=1 -D=4 -argstest no-lock Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member \ - -RealEncryption=1 -rs=2 -argstest rank 1 not-lockable + -RealEncryption=1 -rs=2 -D=4 -argstest rank 1 not-lockable Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member \ - -RealEncryption=1 -rs=3 -argstest rank 2 not-lockable + -RealEncryption=1 -rs=3 -D=4 -argstest rank 2 not-lockable Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member \ - -RealEncryption=1 -rs=4 -argstest rank 3 not-lockable + -RealEncryption=1 -rs=4 -D=4 -argstest rank 3 not-lockable # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_no_rank.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_no_rank.sh index ab6d09ce116..5eebc7759ec 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_no_rank.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_no_rank.sh @@ -17,19 +17,19 @@ SIMULATION_ID="csip_no_rank" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 -argstest no-rank no-lock + -RealEncryption=1 -rs=1 -D=4 -argstest no-rank no-lock Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member \ - -RealEncryption=1 -rs=2 -argstest rank 0 not-lockable + -RealEncryption=1 -rs=2 -D=4 -argstest rank 0 not-lockable Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member \ - -RealEncryption=1 -rs=3 -argstest rank 0 not-lockable + -RealEncryption=1 -rs=3 -D=4 -argstest rank 0 not-lockable Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member \ - -RealEncryption=1 -rs=4 -argstest rank 0 not-lockable + -RealEncryption=1 -rs=4 -D=4 -argstest rank 0 not-lockable # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_no_size.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_no_size.sh index dfd10200d8d..c586fde9205 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_no_size.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_no_size.sh @@ -17,19 +17,19 @@ SIMULATION_ID="csip_no_size" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_coordinator \ - -RealEncryption=1 -rs=1 -argstest no-size + -RealEncryption=1 -rs=1 -D=4 -argstest no-size Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_set_member \ - -RealEncryption=1 -rs=2 -argstest rank 1 size 0 + -RealEncryption=1 -rs=2 -D=4 -argstest rank 1 size 0 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=csip_set_member \ - -RealEncryption=1 -rs=3 -argstest rank 2 size 0 + -RealEncryption=1 -rs=3 -D=4 -argstest rank 2 size 0 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=3 -testid=csip_set_member \ - -RealEncryption=1 -rs=4 -argstest rank 3s size 0 + -RealEncryption=1 -rs=4 -D=4 -argstest rank 3s size 0 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh b/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh index 7f1d8a48cd2..ceaf984d037 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/csip_notify.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running CSIP Notify test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_notify_server -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_notify_server -rs=24 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_notify_client -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=csip_notify_client -rs=46 -D=2 Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ -D=2 -sim_length=60e6 $@ diff --git a/tests/bsim/bluetooth/audio/test_scripts/has.sh b/tests/bsim/bluetooth/audio/test_scripts/has.sh index e2bface0396..3d7f6508fd0 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/has.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/has.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running HAS main (API) test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=has -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=has -rs=24 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=has_client -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=has_client -rs=46 -D=2 Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ -D=2 -sim_length=60e6 $@ diff --git a/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh b/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh index c05b40adaee..7e5b0a40d7a 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/has_offline.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n Running Preset Changed Offline Behavior test \n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=has_offline_behavior -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=has_offline_behavior -rs=24 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=has_client_offline_behavior -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=has_client_offline_behavior -rs=46 -D=2 Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ -D=2 -sim_length=60e6 $@ diff --git a/tests/bsim/bluetooth/audio/test_scripts/ias.sh b/tests/bsim/bluetooth/audio/test_scripts/ias.sh index 3547d6996e8..cf3afed69ed 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/ias.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/ias.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running IAS main (API) test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=ias -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=ias -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=ias_client -rs=6 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=ias_client -rs=6 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/mcs_mcc.sh b/tests/bsim/bluetooth/audio/test_scripts/mcs_mcc.sh index 1e31932efe7..4857a5cad05 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/mcs_mcc.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/mcs_mcc.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running MCS and MCC test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=mcc -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=mcc -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=mcs -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=mcs -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/media_controller.sh b/tests/bsim/bluetooth/audio/test_scripts/media_controller.sh index ab036d39497..3e504f7275e 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/media_controller.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/media_controller.sh @@ -15,7 +15,7 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running media controller local_player test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=media_controller_local_player -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=media_controller_local_player -rs=23 -D=1 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ @@ -26,10 +26,10 @@ wait_for_background_jobs printf "\n\n======== Running media controller remote_player test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=media_controller_remote_player -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=media_controller_remote_player -rs=46 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=media_controller_server -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=media_controller_server -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/micp.sh b/tests/bsim/bluetooth/audio/test_scripts/micp.sh index 3117f665116..56bc0ac4650 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/micp.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/micp.sh @@ -15,7 +15,7 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n==== Running MICP Microphone Device Only (API) test ====n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=micp_mic_dev_only -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=micp_mic_dev_only -rs=23 -D=1 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ @@ -26,10 +26,10 @@ wait_for_background_jobs printf "\n\n==== Running MICP Microphone Device and MICP Microphone Controller test ====n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=micp_mic_dev -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=micp_mic_dev -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=micp_mic_ctlr -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=micp_mic_ctlr -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/pacs_notify.sh b/tests/bsim/bluetooth/audio/test_scripts/pacs_notify.sh index 5e29bf2b005..721a794cbd3 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/pacs_notify.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/pacs_notify.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running PACS Notify test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=pacs_notify_server -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=pacs_notify_server -rs=24 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=pacs_notify_client -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=pacs_notify_client -rs=46 -D=2 Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ -D=2 -sim_length=60e6 $@ diff --git a/tests/bsim/bluetooth/audio/test_scripts/tbs.sh b/tests/bsim/bluetooth/audio/test_scripts/tbs.sh index 894376434aa..491443a60aa 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/tbs.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/tbs.sh @@ -16,7 +16,7 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n==== Running TBS Server Only (API) test ====n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tbs_test_server_only -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tbs_test_server_only -rs=23 -D=1 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ @@ -27,10 +27,10 @@ wait_for_background_jobs printf "\n\n==== Running TBS server & client tests ====n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tbs -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tbs -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=tbs_client -rs=6 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=tbs_client -rs=6 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/tmap.sh b/tests/bsim/bluetooth/audio/test_scripts/tmap.sh index 38da32d6f34..069d4b463bb 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/tmap.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/tmap.sh @@ -15,10 +15,10 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running TMAP client & server test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tmap_client -rs=24 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tmap_client -rs=24 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=tmap_server -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=tmap_server -rs=23 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ diff --git a/tests/bsim/bluetooth/audio/test_scripts/vcp.sh b/tests/bsim/bluetooth/audio/test_scripts/vcp.sh index 0be421894ba..8d394c225b6 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/vcp.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/vcp.sh @@ -15,7 +15,7 @@ cd ${BSIM_OUT_PATH}/bin printf "\n\n======== Running VCP Volume Renderer standalone (API) test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=vcp_vol_rend_standalone -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=vcp_vol_rend_standalone -rs=23 -D=1 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ @@ -26,10 +26,10 @@ wait_for_background_jobs printf "\n\n======== Running VCP Volume Renderer and VCP Volume Controller test =========\n\n" Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=vcp_vol_rend -rs=23 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=vcp_vol_rend -rs=23 -D=2 Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=vcp_vol_ctlr -rs=46 + -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=vcp_vol_ctlr -rs=46 -D=2 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ From 9a73cbadc04dcff321dcfaff24a6572cab1bfa48 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 23 Oct 2023 23:19:35 +0200 Subject: [PATCH 3066/4498] tests: Bluetooth: Update BAP broadcast tests to use sync Update the BAP broadcast tests to use the BSIM sync API instead of sleeps, to ensure that everything is sent and receive correctly, regardless of timing. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_sink_test.c | 20 +++++++++++++++++- .../audio/src/bap_broadcast_source_test.c | 21 +++++++++---------- ...nt.sh => bap_broadcast_audio_assistant.sh} | 0 3 files changed, 29 insertions(+), 12 deletions(-) rename tests/bsim/bluetooth/audio/test_scripts/{_bap_broadcast_audio_assistant.sh => bap_broadcast_audio_assistant.sh} (100%) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index 1c213694434..0e5d1d94fb6 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -67,6 +67,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap (void)memcpy(metadata, base->subgroups[0].codec_cfg.meta, sizeof(base->subgroups[0].codec_cfg.meta)); + printk("Metadata updated\n"); SET_FLAG(flag_base_metadata_updated); } @@ -263,7 +264,10 @@ static void recv_cb(struct bt_bap_stream *stream, { struct bap_test_stream *test_stream = CONTAINER_OF(stream, struct bap_test_stream, stream); - printk("Incoming audio on stream %p len %u and ts %u\n", stream, buf->len, info->ts); + if ((test_stream->rx_cnt % 100U) == 0U) { + printk("Incoming audio on stream %p len %u and ts %u\n", stream, buf->len, + info->ts); + } if (test_stream->rx_cnt > 0U && info->ts == test_stream->last_info.ts) { FAIL("Duplicated timestamp received: %u\n", test_stream->last_info.ts); @@ -654,16 +658,20 @@ static void test_common(void) printk("Waiting for data\n"); WAIT_FOR_FLAG(flag_received); + backchannel_sync_send_all(); /* let other devices know we have received what we wanted */ /* Ensure that we also see the metadata update */ printk("Waiting for metadata update\n"); WAIT_FOR_FLAG(flag_base_metadata_updated) + backchannel_sync_send_all(); /* let other devices know we have received what we wanted */ } static void test_main(void) { test_common(); + backchannel_sync_send_all(); /* let the broadcast source know it can stop */ + /* The order of PA sync lost and BIG Sync lost is irrelevant * and depend on timeout parameters. We just wait for PA first, but * either way will work. @@ -693,6 +701,8 @@ static void test_sink_disconnect(void) test_broadcast_delete_inval(); test_broadcast_delete(); + backchannel_sync_send_all(); /* let the broadcast source know it can stop */ + PASS("Broadcast sink disconnect passed\n"); } @@ -728,6 +738,12 @@ static void broadcast_sink_with_assistant(void) printk("Waiting for data\n"); WAIT_FOR_FLAG(flag_received); + backchannel_sync_send_all(); /* let other devices know we have received what we wanted */ + + /* Ensure that we also see the metadata update */ + printk("Waiting for metadata update\n"); + WAIT_FOR_FLAG(flag_base_metadata_updated) + backchannel_sync_send_all(); /* let other devices know we have received what we wanted */ printk("Waiting for BIG sync terminate request\n"); WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested); @@ -738,6 +754,8 @@ static void broadcast_sink_with_assistant(void) test_pa_sync_delete(); test_broadcast_delete(); + backchannel_sync_send_all(); /* let the broadcast source know it can stop */ + PASS("Broadcast sink with assistant passed\n"); } diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index fbb64a85f18..773240a0c36 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -59,7 +59,9 @@ static void stream_sent_cb(struct bt_bap_stream *stream) return; } - printk("Sent with seq_num %u\n", test_stream->seq_num); + if ((test_stream->tx_cnt % 100U) == 0U) { + printk("Sent with seq_num %u\n", test_stream->seq_num); + } buf = net_buf_alloc(&tx_pool, K_FOREVER); if (buf == NULL) { @@ -468,14 +470,8 @@ static void test_main(void) } } - for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) { - /* Keep sending until we reach 5 times the minimum expected to be pretty sure - * that the receiver receives enough - */ - while (broadcast_source_streams[i].tx_cnt < MIN_SEND_COUNT) { - k_sleep(K_MSEC(100)); - } - } + /* Wait for other devices to have received what they wanted */ + backchannel_sync_wait_any(); /* Update metadata while streaming */ printk("Updating metadata\n"); @@ -486,8 +482,11 @@ static void test_main(void) return; } - /* Keeping running for a little while */ - k_sleep(K_SECONDS(5)); + /* Wait for other devices to have received what they wanted */ + backchannel_sync_wait_any(); + + /* Wait for other devices to let us know when we can stop the source */ + backchannel_sync_wait_any(); test_broadcast_source_stop(source); diff --git a/tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh similarity index 100% rename from tests/bsim/bluetooth/audio/test_scripts/_bap_broadcast_audio_assistant.sh rename to tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh From 84317da08295486a140e94127a398357dd34302a Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 24 Oct 2023 15:36:17 +0300 Subject: [PATCH 3067/4498] tests: thread_apis: Make local functions static Most of the local functions are static, make code consistent by making remaining functions static as well. Signed-off-by: Andrei Emeltchenko --- tests/kernel/threads/thread_apis/src/main.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/kernel/threads/thread_apis/src/main.c b/tests/kernel/threads/thread_apis/src/main.c index a71dd28f900..2acca437017 100644 --- a/tests/kernel/threads/thread_apis/src/main.c +++ b/tests/kernel/threads/thread_apis/src/main.c @@ -278,7 +278,7 @@ enum control_method { ISR_RUNNING }; -void join_entry(void *p1, void *p2, void *p3) +static void join_entry(void *p1, void *p2, void *p3) { enum control_method m = (enum control_method)(intptr_t)p1; @@ -299,13 +299,13 @@ void join_entry(void *p1, void *p2, void *p3) } } -void control_entry(void *p1, void *p2, void *p3) +static void control_entry(void *p1, void *p2, void *p3) { printk("control_thread: killing join thread\n"); k_thread_abort(&join_thread); } -void do_join_from_isr(const void *arg) +static void do_join_from_isr(const void *arg) { int *ret = (int *)arg; @@ -317,7 +317,7 @@ void do_join_from_isr(const void *arg) #define JOIN_TIMEOUT_MS 100 -int join_scenario_interval(enum control_method m, int64_t *interval) +static int join_scenario_interval(enum control_method m, int64_t *interval) { k_timeout_t timeout = K_FOREVER; int ret; @@ -421,7 +421,7 @@ K_THREAD_STACK_DEFINE(deadlock1_stack, STACK_SIZE); struct k_thread deadlock2_thread; K_THREAD_STACK_DEFINE(deadlock2_stack, STACK_SIZE); -void deadlock1_entry(void *p1, void *p2, void *p3) +static void deadlock1_entry(void *p1, void *p2, void *p3) { int ret; @@ -431,7 +431,7 @@ void deadlock1_entry(void *p1, void *p2, void *p3) zassert_equal(ret, -EDEADLK, "failed mutual join case"); } -void deadlock2_entry(void *p1, void *p2, void *p3) +static void deadlock2_entry(void *p1, void *p2, void *p3) { int ret; @@ -470,6 +470,7 @@ static void user_start_thread(void *p1, void *p2, void *p3) { /* do nothing */ } + ZTEST_USER(threads_lifecycle, test_thread_timeout_remaining_expires) { k_ticks_t r, e, r1, ticks, expected_expires_ticks; @@ -520,6 +521,7 @@ static void foreach_callback(const struct k_thread *thread, void *user_data) ((k_thread_runtime_stats_t *)user_data)->execution_cycles += stats.execution_cycles; } + /* This case accumulates every thread's execution_cycles first, then * get the total execution_cycles from a global * k_thread_runtime_stats_t to see that all time is reflected in the @@ -594,7 +596,7 @@ ZTEST_USER(threads_lifecycle_1cpu, test_k_busy_wait_user) } #define INT_ARRAY_SIZE 128 -int large_stack(size_t *space) +static int large_stack(size_t *space) { /* use "volatile" to protect this variable from being optimized out */ volatile int a[INT_ARRAY_SIZE]; @@ -605,7 +607,7 @@ int large_stack(size_t *space) } -int small_stack(size_t *space) +static int small_stack(size_t *space) { return k_thread_stack_space_get(k_current_get(), space); } @@ -628,7 +630,7 @@ ZTEST_USER(threads_lifecycle, test_k_thread_stack_space_get_user) zassert_true(b <= a); } -void *thread_test_setup(void) +static void *thread_test_setup(void) { k_thread_access_grant(k_current_get(), &tdata, tstack, &tdata_custom, tstack_custom, From fa6c281d82547926c2dd265daca90059ba52b8f3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 24 Oct 2023 15:58:48 +0300 Subject: [PATCH 3068/4498] tests: thread_apis: Change printk and TC_PRINT to LOG Replace combination of printk() and TC_PRINT() to LOG_DBG() disabled by default so that it does not affect execution time. Signed-off-by: Andrei Emeltchenko --- tests/kernel/threads/thread_apis/src/main.c | 25 ++++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/kernel/threads/thread_apis/src/main.c b/tests/kernel/threads/thread_apis/src/main.c index 2acca437017..86add19a5c7 100644 --- a/tests/kernel/threads/thread_apis/src/main.c +++ b/tests/kernel/threads/thread_apis/src/main.c @@ -20,6 +20,9 @@ #include #include +#include +LOG_MODULE_REGISTER(test); + struct k_thread tdata; #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE) K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); @@ -183,7 +186,7 @@ ZTEST_USER(threads_lifecycle, test_thread_name_user_get_set) ret = k_thread_name_copy(&z_main_thread, thread_name, sizeof(thread_name)); zassert_equal(ret, 0, "couldn't get main thread name"); - printk("Main thread name is '%s'\n", thread_name); + LOG_DBG("Main thread name is '%s'", thread_name); /* Set and get child thread's name */ k_tid_t tid = k_thread_create(&tdata_name, tstack_name, STACK_SIZE, @@ -288,20 +291,20 @@ static void join_entry(void *p1, void *p2, void *p3) case OTHER_ABORT: case OTHER_ABORT_TIMEOUT: case ISR_RUNNING: - printk("join_thread: sleeping forever\n"); + LOG_DBG("join_thread: sleeping forever"); k_sleep(K_FOREVER); break; case SELF_ABORT: case ALREADY_EXIT: case ISR_ALREADY_EXIT: - printk("join_thread: self-exiting\n"); + LOG_DBG("join_thread: self-exiting"); return; } } static void control_entry(void *p1, void *p2, void *p3) { - printk("control_thread: killing join thread\n"); + LOG_DBG("control_thread: killing join thread"); k_thread_abort(&join_thread); } @@ -310,9 +313,9 @@ static void do_join_from_isr(const void *arg) int *ret = (int *)arg; zassert_true(k_is_in_isr()); - printk("isr: joining join_thread\n"); + LOG_DBG("isr: joining join_thread"); *ret = k_thread_join(&join_thread, K_NO_WAIT); - printk("isr: k_thread_join() returned with %d\n", *ret); + LOG_DBG("isr: k_thread_join() returned with %d", *ret); } #define JOIN_TIMEOUT_MS 100 @@ -322,7 +325,7 @@ static int join_scenario_interval(enum control_method m, int64_t *interval) k_timeout_t timeout = K_FOREVER; int ret; - printk("ztest_thread: method %d, create join_thread\n", m); + LOG_DBG("ztest_thread: method %d, create join_thread", m); k_thread_create(&join_thread, join_stack, STACK_SIZE, join_entry, (void *)m, NULL, NULL, K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -337,7 +340,7 @@ static int join_scenario_interval(enum control_method m, int64_t *interval) timeout = K_MSEC(JOIN_TIMEOUT_MS); __fallthrough; case OTHER_ABORT: - printk("ztest_thread: create control_thread\n"); + LOG_DBG("ztest_thread: create control_thread"); k_thread_create(&control_thread, control_stack, STACK_SIZE, control_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(2), @@ -356,7 +359,7 @@ static int join_scenario_interval(enum control_method m, int64_t *interval) if (m == ISR_ALREADY_EXIT || m == ISR_RUNNING) { irq_offload(do_join_from_isr, (const void *)&ret); } else { - printk("ztest_thread: joining join_thread\n"); + LOG_DBG("ztest_thread: joining join_thread"); if (interval != NULL) { *interval = k_uptime_get(); @@ -368,7 +371,7 @@ static int join_scenario_interval(enum control_method m, int64_t *interval) *interval = k_uptime_get() - *interval; } - printk("ztest_thread: k_thread_join() returned with %d\n", ret); + LOG_DBG("ztest_thread: k_thread_join() returned with %d", ret); } if (ret != 0) { @@ -485,7 +488,7 @@ ZTEST_USER(threads_lifecycle, test_thread_timeout_remaining_expires) k_msleep(10); e = k_thread_timeout_expires_ticks(tid); - TC_PRINT("thread_expires_ticks: %d, expect: %d\n", (int)e, + LOG_DBG("thread_expires_ticks: %d, expect: %d", (int)e, (int)expected_expires_ticks); zassert_true(e >= expected_expires_ticks); From 670b917b4b0e158d0c185cd6d776ccd3f9c5cc87 Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Tue, 24 Oct 2023 10:31:41 +0200 Subject: [PATCH 3069/4498] scripts: tests: twister: Hardware map unit testing This change creates unit tests for the hardwaremap.py module. It achieves 98% coverage. Signed-off-by: Lukasz Mrugala --- scripts/tests/twister/test_hardwaremap.py | 722 ++++++++++++++++++++++ 1 file changed, 722 insertions(+) create mode 100644 scripts/tests/twister/test_hardwaremap.py diff --git a/scripts/tests/twister/test_hardwaremap.py b/scripts/tests/twister/test_hardwaremap.py new file mode 100644 index 00000000000..57c028bfea6 --- /dev/null +++ b/scripts/tests/twister/test_hardwaremap.py @@ -0,0 +1,722 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Tests for hardwaremap.py classes' methods +""" + +import mock +import pytest +import sys + +from pathlib import Path + +from twisterlib.hardwaremap import( + DUT, + HardwareMap +) + + +@pytest.fixture +def mocked_hm(): + duts = [ + DUT(platform='p1', id=1, serial='s1', product='pr1', connected=True), + DUT(platform='p2', id=2, serial='s2', product='pr2', connected=False), + DUT(platform='p3', id=3, serial='s3', product='pr3', connected=True), + DUT(platform='p4', id=4, serial='s4', product='pr4', connected=False), + DUT(platform='p5', id=5, serial='s5', product='pr5', connected=True), + DUT(platform='p6', id=6, serial='s6', product='pr6', connected=False), + DUT(platform='p7', id=7, serial='s7', product='pr7', connected=True), + DUT(platform='p8', id=8, serial='s8', product='pr8', connected=False) + ] + + hm = HardwareMap(env=mock.Mock()) + hm.duts = duts + hm.detected = duts[:5] + + return hm + + +TESTDATA_1 = [ + ( + {}, + {'baud': 115200, 'lock': mock.ANY, 'flash_timeout': 60}, + '' + ), + ( + { + 'id': 'dummy id', + 'serial': 'dummy serial', + 'serial_baud': 4400, + 'platform': 'dummy platform', + 'product': 'dummy product', + 'serial_pty': 'dummy serial pty', + 'connected': True, + 'runner_params': ['dummy', 'runner', 'params'], + 'pre_script': 'dummy pre script', + 'post_script': 'dummy post script', + 'post_flash_script': 'dummy post flash script', + 'runner': 'dummy runner', + 'flash_timeout': 30, + 'flash_with_test': True + }, + { + 'lock': mock.ANY, + 'id': 'dummy id', + 'serial': 'dummy serial', + 'baud': 4400, + 'platform': 'dummy platform', + 'product': 'dummy product', + 'serial_pty': 'dummy serial pty', + 'connected': True, + 'runner_params': ['dummy', 'runner', 'params'], + 'pre_script': 'dummy pre script', + 'post_script': 'dummy post script', + 'post_flash_script': 'dummy post flash script', + 'runner': 'dummy runner', + 'flash_timeout': 30, + 'flash_with_test': True + }, + '' + ), +] + + +@pytest.mark.parametrize( + 'kwargs, expected_dict, expected_repr', + TESTDATA_1, + ids=['no information', 'full information'] +) +def test_dut(kwargs, expected_dict, expected_repr): + d = DUT(**kwargs) + + assert d.available + assert d.counter == 0 + + d.available = False + d.counter = 1 + + assert not d.available + assert d.counter == 1 + + assert d.to_dict() == expected_dict + assert d.__repr__() == expected_repr + + +TESTDATA_2 = [ + ('ghm.yaml', mock.ANY, mock.ANY, [], mock.ANY, mock.ANY, mock.ANY, 0, + True, True, False, False, False, False, []), + (None, False, 'hm.yaml', [], mock.ANY, mock.ANY, mock.ANY, 0, + False, False, True, True, False, False, []), + (None, True, 'hm.yaml', [], mock.ANY, mock.ANY, ['fix'], 1, + False, False, True, False, False, True, ['p1', 'p3', 'p5', 'p7']), + (None, True, 'hm.yaml', ['pX'], mock.ANY, mock.ANY, ['fix'], 1, + False, False, True, False, False, True, ['pX']), + (None, True, None, ['p'], 's', None, ['fix'], 1, + False, False, False, False, True, True, ['p']), + (None, True, None, ['p'], None, 'spty', ['fix'], 1, + False, False, False, False, True, True, ['p']), +] + + +@pytest.mark.parametrize( + 'generate_hardware_map, device_testing, hardware_map, platform,' \ + ' device_serial, device_serial_pty, fixtures,' \ + ' return_code, expect_scan, expect_save, expect_load,' \ + ' expect_dump, expect_add_device, expect_fixtures, expected_platforms', + TESTDATA_2, + ids=['generate hardware map', 'existing hardware map', + 'device testing with hardware map, no platform', + 'device testing with hardware map with platform', + 'device testing with device serial', + 'device testing with device serial pty'] +) +def test_hardwaremap_discover( + caplog, + mocked_hm, + generate_hardware_map, + device_testing, + hardware_map, + platform, + device_serial, + device_serial_pty, + fixtures, + return_code, + expect_scan, + expect_save, + expect_load, + expect_dump, + expect_add_device, + expect_fixtures, + expected_platforms +): + def mock_load(*args): + mocked_hm.platform = platform + + mocked_hm.scan = mock.Mock() + mocked_hm.save = mock.Mock() + mocked_hm.load = mock.Mock(side_effect=mock_load) + mocked_hm.dump = mock.Mock() + mocked_hm.add_device = mock.Mock() + + mocked_hm.options.device_flash_with_test = True + mocked_hm.options.device_flash_timeout = 15 + mocked_hm.options.pre_script = 'dummy pre script' + mocked_hm.options.platform = platform + mocked_hm.options.device_serial = device_serial + mocked_hm.options.device_serial_pty = device_serial_pty + mocked_hm.options.device_testing = device_testing + mocked_hm.options.hardware_map = hardware_map + mocked_hm.options.persistent_hardware_map = mock.Mock() + mocked_hm.options.generate_hardware_map = generate_hardware_map + mocked_hm.options.fixture = fixtures + + returncode = mocked_hm.discover() + + assert returncode == return_code + + if expect_scan: + mocked_hm.scan.assert_called_once_with( + persistent=mocked_hm.options.persistent_hardware_map + ) + if expect_save: + mocked_hm.save.assert_called_once_with( + mocked_hm.options.generate_hardware_map + ) + if expect_load: + mocked_hm.load.assert_called_once_with( + mocked_hm.options.hardware_map + ) + if expect_dump: + mocked_hm.dump.assert_called_once_with( + connected_only=True + ) + if expect_add_device: + mocked_hm.add_device.assert_called_once() + + if expect_fixtures: + assert all( + [all( + [fixture in dut.fixtures for fixture in fixtures] + ) for dut in mocked_hm.duts] + ) + + assert sorted(expected_platforms) == sorted(mocked_hm.options.platform) + + +def test_hardwaremap_summary(capfd, mocked_hm): + selected_platforms = ['p0', 'p1', 'p6', 'p7'] + + mocked_hm.summary(selected_platforms) + + expected = """ +Hardware distribution summary: + +| Board | ID | Counter | +|---------|------|-----------| +| p1 | 1 | 0 | +| p7 | 7 | 0 | +""" + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert expected in out + + +TESTDATA_3 = [ + (True), + (False) +] + + +@pytest.mark.parametrize( + 'is_pty', + TESTDATA_3, + ids=['pty', 'not pty'] +) +def test_hardwaremap_add_device(is_pty): + hm = HardwareMap(env=mock.Mock()) + + serial = 'dummy' + platform = 'p0' + pre_script = 'dummy pre script' + hm.add_device(serial, platform, pre_script, is_pty) + + assert len(hm.duts) == 1 + if is_pty: + assert hm.duts[0].serial_pty == 'dummy' if is_pty else None + assert hm.duts[0].serial is None + else: + assert hm.duts[0].serial_pty is None + assert hm.duts[0].serial == 'dummy' + + +def test_hardwaremap_load(): + map_file = \ +""" +- id: id0 + platform: p0 + product: pr0 + runner: r0 + flash_with_test: True + flash_timeout: 15 + baud: 14400 + fixtures: + - dummy fixture 1 + - dummy fixture 2 + connected: True + serial: 'dummy' +- id: id1 + platform: p1 + product: pr1 + runner: r1 + connected: True + serial_pty: 'dummy' +- id: id2 + platform: p2 + product: pr2 + runner: r2 + connected: True +""" + map_filename = 'map-file.yaml' + + builtin_open = open + + def mock_open(*args, **kwargs): + if args[0] == map_filename: + return mock.mock_open(read_data=map_file)(*args, **kwargs) + return builtin_open(*args, **kwargs) + + hm = HardwareMap(env=mock.Mock()) + hm.options.device_flash_timeout = 30 + hm.options.device_flash_with_test = False + + with mock.patch('builtins.open', mock_open): + hm.load(map_filename) + + expected = { + 'id0': { + 'platform': 'p0', + 'product': 'pr0', + 'runner': 'r0', + 'flash_timeout': 15, + 'flash_with_test': True, + 'baud': 14400, + 'fixtures': ['dummy fixture 1', 'dummy fixture 2'], + 'connected': True, + 'serial': 'dummy', + 'serial_pty': None, + }, + 'id1': { + 'platform': 'p1', + 'product': 'pr1', + 'runner': 'r1', + 'flash_timeout': 30, + 'flash_with_test': False, + 'baud': 115200, + 'fixtures': [], + 'connected': True, + 'serial': None, + 'serial_pty': 'dummy', + }, + } + + for dut in hm.duts: + assert dut.id in expected + assert all([getattr(dut, k) == v for k, v in expected[dut.id].items()]) + + +TESTDATA_4 = [ + ( + True, + 'Linux', + ['', '', '', + '', '', + '', + '', + ''] + ), + ( + True, + 'nt', + ['', '', '', + '', '', + '', + '', + ''] + ), + ( + False, + 'Linux', + ['', '', '', + '', '', + '', + '', + ''] + ) +] + + +@pytest.mark.parametrize( + 'persistent, system, expected_reprs', + TESTDATA_4, + ids=['linux persistent map', 'no map (not linux)', 'no map (nonpersistent)'] +) +def test_hardwaremap_scan( + caplog, + mocked_hm, + persistent, + system, + expected_reprs +): + def mock_resolve(path): + if str(path).endswith('-link'): + return Path(str(path)[:-5]) + return path + + def mock_iterdir(path): + return [ + Path(path / 'basic-file1'), + Path(path / 'basic-file2-link') + ] + + mocked_hm.manufacturer = ['dummy manufacturer', 'Texas Instruments'] + mocked_hm.runner_mapping = { + 'dummy runner': ['product[0-9]+',], + 'other runner': ['other TI product', 'TI product'] + } + + comports_mock = [ + mock.Mock( + manufacturer='wrong manufacturer', + location='wrong location', + serial_number='wrong number', + product='wrong product', + device='wrong device' + ), + mock.Mock( + manufacturer='dummy manufacturer', + location='dummy location', + serial_number='dummy number', + product=None, + device='/dev/serial/by-id/basic-file2' + ), + mock.Mock( + manufacturer='dummy manufacturer', + location='dummy location', + serial_number='dummy number', + product='product123', + device='dummy device' + ), + mock.Mock( + manufacturer='Texas Instruments', + location='serial1', + serial_number='TI1', + product='TI product', + device='TI device1' + ), + mock.Mock( + manufacturer='Texas Instruments', + location='serial0', + serial_number='TI0', + product='TI product', + device='/dev/serial/by-id/basic-file1' + ), + ] + + with mock.patch('platform.system', return_value=system), \ + mock.patch('serial.tools.list_ports.comports', + return_value=comports_mock), \ + mock.patch('twisterlib.hardwaremap.Path.resolve', + autospec=True, side_effect=mock_resolve), \ + mock.patch('twisterlib.hardwaremap.Path.iterdir', + autospec=True, side_effect=mock_iterdir): + mocked_hm.scan(persistent) + + assert sorted([d.__repr__() for d in mocked_hm.detected]) == \ + sorted(expected_reprs) + + assert 'Scanning connected hardware...' in caplog.text + assert 'Unsupported device (wrong manufacturer): %s' % comports_mock[0] \ + in caplog.text + + +TESTDATA_5 = [ + ( + None, + [{ + 'platform': 'p1', + 'id': 1, + 'runner': mock.ANY, + 'serial': 's1', + 'product': 'pr1', + 'connected': True + }, + { + 'platform': 'p2', + 'id': 2, + 'runner': mock.ANY, + 'serial': 's2', + 'product': 'pr2', + 'connected': False + }, + { + 'platform': 'p3', + 'id': 3, + 'runner': mock.ANY, + 'serial': 's3', + 'product': 'pr3', + 'connected': True + }, + { + 'platform': 'p4', + 'id': 4, + 'runner': mock.ANY, + 'serial': 's4', + 'product': 'pr4', + 'connected': False + }, + { + 'platform': 'p5', + 'id': 5, + 'runner': mock.ANY, + 'serial': 's5', + 'product': 'pr5', + 'connected': True + }] + ), + ( + '', + [{ + 'serial': 's1', + 'baud': 115200, + 'platform': 'p1', + 'connected': True, + 'id': 1, + 'product': 'pr1', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's2', + 'baud': 115200, + 'platform': 'p2', + 'id': 2, + 'product': 'pr2', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's3', + 'baud': 115200, + 'platform': 'p3', + 'connected': True, + 'id': 3, + 'product': 'pr3', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's4', + 'baud': 115200, + 'platform': 'p4', + 'id': 4, + 'product': 'pr4', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's5', + 'baud': 115200, + 'platform': 'p5', + 'connected': True, + 'id': 5, + 'product': 'pr5', + 'lock': mock.ANY, + 'flash_timeout': 60 + }] + ), + ( +""" +- id: 4 + platform: p4 + product: pr4 + connected: True + serial: s4 +- id: 0 + platform: p0 + product: pr0 + connected: True + serial: s0 +- id: 10 + platform: p10 + product: pr10 + connected: False + serial: s10 +- id: 5 + platform: p5-5 + product: pr5-5 + connected: True + serial: s5-5 +""", + [{ + 'id': 0, + 'platform': 'p0', + 'product': 'pr0', + 'connected': False, + 'serial': None + }, + { + 'id': 4, + 'platform': 'p4', + 'product': 'pr4', + 'connected': True, + 'serial': 's4' + }, + { + 'id': 5, + 'platform': 'p5-5', + 'product': 'pr5-5', + 'connected': False, + 'serial': None + }, + { + 'id': 10, + 'platform': 'p10', + 'product': 'pr10', + 'connected': False, + 'serial': None + }, + { + 'serial': 's1', + 'baud': 115200, + 'platform': 'p1', + 'connected': True, + 'id': 1, + 'product': 'pr1', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's2', + 'baud': 115200, + 'platform': 'p2', + 'id': 2, + 'product': 'pr2', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's3', + 'baud': 115200, + 'platform': 'p3', + 'connected': True, + 'id': 3, + 'product': 'pr3', + 'lock': mock.ANY, + 'flash_timeout': 60 + }, + { + 'serial': 's5', + 'baud': 115200, + 'platform': 'p5', + 'connected': True, + 'id': 5, + 'product': 'pr5', + 'lock': mock.ANY, + 'flash_timeout': 60 + }] + ), +] + + +@pytest.mark.parametrize( + 'hwm, expected_dump', + TESTDATA_5, + ids=['no map', 'empty map', 'map exists'] +) +def test_hardwaremap_save(mocked_hm, hwm, expected_dump): + read_mock = mock.mock_open(read_data=hwm) + write_mock = mock.mock_open() + + def mock_open(filename, mode): + if mode == 'r': + return read_mock() + elif mode == 'w': + return write_mock() + + + mocked_hm.load = mock.Mock() + mocked_hm.dump = mock.Mock() + + open_mock = mock.Mock(side_effect=mock_open) + dump_mock = mock.Mock() + + with mock.patch('os.path.exists', return_value=hwm is not None), \ + mock.patch('builtins.open', open_mock), \ + mock.patch('twisterlib.hardwaremap.yaml.dump', dump_mock): + mocked_hm.save('hwm.yaml') + + dump_mock.assert_called_once_with(expected_dump, mock.ANY, Dumper=mock.ANY, + default_flow_style=mock.ANY) + + +TESTDATA_6 = [ + ( + ['p1', 'p3', 'p5', 'p7'], + [], + True, + True, +""" +| Platform | ID | Serial device | +|------------|------|-----------------| +| p1 | 1 | s1 | +| p3 | 3 | s3 | +| p5 | 5 | s5 | +""" + ), + ( + [], + ['?', '??', '???'], + False, + False, +""" +| ? | ?? | ??? | +|-----|------|-------| +| p1 | 1 | s1 | +| p2 | 2 | s2 | +| p3 | 3 | s3 | +| p4 | 4 | s4 | +| p5 | 5 | s5 | +| p6 | 6 | s6 | +| p7 | 7 | s7 | +| p8 | 8 | s8 | +""" + ), +] + + +@pytest.mark.parametrize( + 'filtered, header, connected_only, detected, expected_out', + TESTDATA_6, + ids=['detected no header', 'all with header'] +) +def test_hardwaremap_dump( + capfd, + mocked_hm, + filtered, + header, + connected_only, + detected, + expected_out +): + mocked_hm.dump(filtered, header, connected_only, detected) + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert out.strip() == expected_out.strip() From 72045afe1ae462fb8e6c8e36781076fa10e9193b Mon Sep 17 00:00:00 2001 From: Lukasz Mrugala Date: Wed, 25 Oct 2023 13:24:44 +0200 Subject: [PATCH 3070/4498] .github: workflows: Expand Twister Unit Tests' requirements Hardwaremap testing requires installing requirements-run-tests.txt. This change adds that to the relevant workflow. Signed-off-by: Lukasz Mrugala --- .github/workflows/twister_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index db26f055e18..606c49dfdf9 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -48,7 +48,7 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install-packages run: | - pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt + pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt -r scripts/requirements-run-test.txt - name: Run pytest for twisterlib env: ZEPHYR_BASE: ./ From 7a04649d15a93147d84ced882ecaa085b99412f8 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Fri, 27 Oct 2023 17:46:53 +0100 Subject: [PATCH 3071/4498] drivers: counter: Update NXP LPC RTC timer 1. Issue a reset during init to ensure the registers are in their reset state. 2. The value in counter_set_top_value was not written to the register. This function now returns -ENOTSUP 3. Make sure the RTC is enabled before we issue RTC_Start command. 4. Replace calls to SDK API's RTC_StartTimer and RTC_StopTimer with RTC_EnableTimer Signed-off-by: Mahesh Mahadevan --- drivers/counter/counter_mcux_lpc_rtc.c | 41 +++++++------------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/drivers/counter/counter_mcux_lpc_rtc.c b/drivers/counter/counter_mcux_lpc_rtc.c index 18cafe1272d..2bb8d920fea 100644 --- a/drivers/counter/counter_mcux_lpc_rtc.c +++ b/drivers/counter/counter_mcux_lpc_rtc.c @@ -16,9 +16,7 @@ LOG_MODULE_REGISTER(mcux_rtc, CONFIG_COUNTER_LOG_LEVEL); struct mcux_lpc_rtc_data { counter_alarm_callback_t alarm_callback; - counter_top_callback_t top_callback; void *alarm_user_data; - void *top_user_data; }; struct mcux_lpc_rtc_config { @@ -35,7 +33,7 @@ static int mcux_lpc_rtc_start(const struct device *dev) const struct mcux_lpc_rtc_config *config = CONTAINER_OF(info, struct mcux_lpc_rtc_config, info); - RTC_StartTimer(config->base); + RTC_EnableTimer(config->base, true); return 0; } @@ -46,7 +44,7 @@ static int mcux_lpc_rtc_stop(const struct device *dev) const struct mcux_lpc_rtc_config *config = CONTAINER_OF(info, struct mcux_lpc_rtc_config, info); - RTC_StopTimer(config->base); + RTC_EnableTimer(config->base, false); /* clear out any set alarms */ RTC_SetSecondsTimerMatch(config->base, 0); @@ -128,26 +126,7 @@ static int mcux_lpc_rtc_cancel_alarm(const struct device *dev, uint8_t chan_id) static int mcux_lpc_rtc_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) { - const struct counter_config_info *info = dev->config; - const struct mcux_lpc_rtc_config *config = - CONTAINER_OF(info, struct mcux_lpc_rtc_config, info); - struct mcux_lpc_rtc_data *data = dev->data; - - if (cfg->ticks != info->max_top_value) { - LOG_ERR("Wrap can only be set to 0x%x.", info->max_top_value); - return -ENOTSUP; - } - - if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) { - RTC_StopTimer(config->base); - RTC_SetSecondsTimerCount(config->base, 0); - RTC_StartTimer(config->base); - } - - data->top_callback = cfg->callback; - data->top_user_data = cfg->user_data; - - return 0; + return -ENOTSUP; } static uint32_t mcux_lpc_rtc_get_pending_int(const struct device *dev) @@ -174,6 +153,7 @@ static void mcux_lpc_rtc_isr(const struct device *dev) struct mcux_lpc_rtc_data *data = dev->data; counter_alarm_callback_t cb; uint32_t current = mcux_lpc_rtc_read(dev); + uint32_t enable = (config->base->CTRL & RTC_CTRL_RTC_EN_MASK); LOG_DBG("Current time is %d ticks", current); @@ -185,21 +165,19 @@ static void mcux_lpc_rtc_isr(const struct device *dev) cb(dev, 0, current, data->alarm_user_data); } - if (data->top_callback) { - data->top_callback(dev, data->top_user_data); - } - /* * Clear any conditions to ack the IRQ * * callback may have already reset the alarm flag if a new * alarm value was programmed to the TAR */ - RTC_StopTimer(config->base); + RTC_EnableTimer(config->base, false); if (RTC_GetStatusFlags(config->base) & RTC_CTRL_ALARM1HZ_MASK) { RTC_ClearStatusFlags(config->base, kRTC_AlarmFlag); } - RTC_StartTimer(config->base); + if (enable) { + RTC_EnableTimer(config->base, true); + } } static int mcux_lpc_rtc_init(const struct device *dev) @@ -210,6 +188,9 @@ static int mcux_lpc_rtc_init(const struct device *dev) RTC_Init(config->base); + /* Issue a software reset to set the registers to init state */ + RTC_Reset(config->base); + config->irq_config_func(dev); if (config->wakeup_source) { From c76d5b882c1416ce48b918a4d1e034b913baa873 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 31 Oct 2023 18:15:48 +0100 Subject: [PATCH 3072/4498] drivers: modem: modem_cellular: Patch init scripts The init scripts need a missing wait for OK after sending AT+CGMM and the AT+CMUX command specifies more parameters than nessesary, and in some cases incorrectly. This commit adds the missing wait for OK and fixes the AT+CMUX commands in the init scripts. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/Kconfig.cellular | 4 ++ drivers/modem/modem_cellular.c | 105 +++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index a729e00ff71..767879ccf0e 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -30,4 +30,8 @@ config MODEM_CELLULAR_APN string "APN" default "internet" +config MODEM_CELLULAR_PERIODIC_SCRIPT_MS + int "Periodic script interval in milliseconds" + default 2000 + endif diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index b4702889472..71a704bd728 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -22,6 +22,9 @@ LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL); #include #include +#define MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT \ + K_MSEC(CONFIG_MODEM_CELLULAR_PERIODIC_SCRIPT_MS) + enum modem_cellular_state { MODEM_CELLULAR_STATE_IDLE = 0, MODEM_CELLULAR_STATE_RESET_PULSE, @@ -113,6 +116,7 @@ struct modem_cellular_config { const uint16_t shutdown_time_ms; const struct modem_chat_script *init_chat_script; const struct modem_chat_script *dial_chat_script; + const struct modem_chat_script *periodic_chat_script; }; static const char *modem_cellular_state_str(enum modem_cellular_state state) @@ -769,13 +773,26 @@ static int modem_cellular_on_await_registered_state_enter(struct modem_cellular_ return -EAGAIN; } + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); return modem_chat_attach(&data->chat, data->dlci2_pipe); } static void modem_cellular_await_registered_event_handler(struct modem_cellular_data *data, enum modem_cellular_event evt) { + const struct modem_cellular_config *config = + (const struct modem_cellular_config *)data->dev->config; + switch (evt) { + case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: + case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + break; + + case MODEM_CELLULAR_EVENT_TIMEOUT: + modem_chat_run_script_async(&data->chat, config->periodic_chat_script); + break; + case MODEM_CELLULAR_EVENT_REGISTERED: modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CARRIER_ON); break; @@ -789,16 +806,35 @@ static void modem_cellular_await_registered_event_handler(struct modem_cellular_ } } +static int modem_cellular_on_await_registered_state_leave(struct modem_cellular_data *data) +{ + modem_cellular_stop_timer(data); + return 0; +} + static int modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data *data) { net_if_carrier_on(modem_ppp_get_iface(data->ppp)); + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); return 0; } static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *data, enum modem_cellular_event evt) { + const struct modem_cellular_config *config = + (const struct modem_cellular_config *)data->dev->config; + switch (evt) { + case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: + case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + break; + + case MODEM_CELLULAR_EVENT_TIMEOUT: + modem_chat_run_script_async(&data->chat, config->periodic_chat_script); + break; + case MODEM_CELLULAR_EVENT_DEREGISTERED: modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT); break; @@ -814,6 +850,7 @@ static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data * static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *data) { + modem_cellular_stop_timer(data); net_if_carrier_off(modem_ppp_get_iface(data->ppp)); modem_chat_release(&data->chat); modem_ppp_release(data->ppp); @@ -1008,6 +1045,10 @@ static int modem_cellular_on_state_leave(struct modem_cellular_data *data) ret = modem_cellular_on_run_dial_script_state_leave(data); break; + case MODEM_CELLULAR_STATE_AWAIT_REGISTERED: + ret = modem_cellular_on_await_registered_state_leave(data); + break; + case MODEM_CELLULAR_STATE_CARRIER_ON: ret = modem_cellular_on_carrier_on_state_leave(data); break; @@ -1288,8 +1329,8 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 0)); + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300)); MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1304,6 +1345,15 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_dial_chat_script, quectel_bg95_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script, + quectel_bg95_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_gsm_ppp) @@ -1324,6 +1374,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), /* The 300ms delay after sending the AT+CMUX command is required * for some modems to ensure they get enough time to enter CMUX * mode before sending the first CMUX command. If this delay is @@ -1345,6 +1396,15 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_dial_chat_script, zephyr_gsm_ppp_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_periodic_chat_script, + zephyr_gsm_ppp_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #if DT_HAS_COMPAT_STATUS_OKAY(simcom_sim7080) @@ -1365,6 +1425,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300)); MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds, @@ -1380,6 +1441,15 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_dial_chat_script, simcom_sim7080_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_periodic_chat_script, + simcom_sim7080_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r4) @@ -1400,8 +1470,8 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 0)); + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match)); MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1416,6 +1486,15 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_dial_chat_script, u_blox_sara_r4_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_periodic_chat_script, + u_blox_sara_r4_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) @@ -1436,8 +1515,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", - 0)); + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 0)); MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 10); @@ -1455,6 +1533,14 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", allow_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", allow_match)); + +MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_periodic_chat_script, + swir_hl7800_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #if DT_HAS_COMPAT_STATUS_OKAY(telit_me910g1) @@ -1521,6 +1607,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &quectel_bg95_init_chat_script, \ .dial_chat_script = &quectel_bg95_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1548,6 +1635,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &zephyr_gsm_ppp_init_chat_script, \ .dial_chat_script = &zephyr_gsm_ppp_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1575,6 +1663,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &simcom_sim7080_init_chat_script, \ .dial_chat_script = &simcom_sim7080_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1602,6 +1691,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &u_blox_sara_r4_init_chat_script, \ .dial_chat_script = &u_blox_sara_r4_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1629,6 +1719,8 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &swir_hl7800_init_chat_script, \ .dial_chat_script = &swir_hl7800_dial_chat_script, \ + .dial_chat_script = &swir_hl7800_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1656,6 +1748,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &telit_me910g1_init_chat_script, \ .dial_chat_script = &telit_me910g1_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ From 8d5322b8ff5c79d0258918edc06a78d521a0f5e4 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 31 Oct 2023 14:14:20 -0500 Subject: [PATCH 3073/4498] drivers: ipm: remove nxp,imx-mu-rev2 compatible Remove nxp,imx-mu-rev2 compatible. This IP block is the same as the nxp,imx-mu device, and should be handled by the same compatible Instead, use CONFIG_HAS_MCUX to determine which HAL APIs should be used to interact with the messaging unit IP. Signed-off-by: Daniel DeGrasse --- drivers/ipm/ipm_imx.c | 19 ++++++++++--------- dts/arm/nxp/nxp_rt11xx_cm4.dtsi | 2 +- dts/arm/nxp/nxp_rt11xx_cm7.dtsi | 2 +- dts/bindings/arm/nxp,imx-mu-rev2.yaml | 20 -------------------- dts/bindings/{arm => ipm}/nxp,imx-mu.yaml | 0 dts/xtensa/nxp/nxp_imx8m.dtsi | 2 +- soc/arm/nxp_imx/rt/soc_rt11xx.c | 4 ++-- 7 files changed, 15 insertions(+), 34 deletions(-) delete mode 100644 dts/bindings/arm/nxp,imx-mu-rev2.yaml rename dts/bindings/{arm => ipm}/nxp,imx-mu.yaml (100%) diff --git a/drivers/ipm/ipm_imx.c b/drivers/ipm/ipm_imx.c index f0fc5488670..7a4b3b1e210 100644 --- a/drivers/ipm/ipm_imx.c +++ b/drivers/ipm/ipm_imx.c @@ -1,9 +1,10 @@ /* - * Copyright (c) 2018, NXP + * Copyright 2018,2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_imx_mu #include #include @@ -12,11 +13,11 @@ #include #include #include -#if defined(CONFIG_IPM_IMX_REV2) -#define DT_DRV_COMPAT nxp_imx_mu_rev2 + +#ifdef CONFIG_HAS_MCUX +/* MCUX HAL uses a different header file than the i.MX HAL for this IP block */ #include "fsl_mu.h" #else -#define DT_DRV_COMPAT nxp_imx_mu #include #endif @@ -38,7 +39,7 @@ struct imx_mu_data { void *user_data; }; -#if defined(CONFIG_IPM_IMX_REV2) +#if defined(CONFIG_HAS_MCUX) /*! * @brief Check RX full status. * @@ -127,7 +128,7 @@ static void imx_mu_isr(const struct device *dev) } if (all_registers_full) { for (i = 0; i < IMX_IPM_DATA_REGS; i++) { -#if defined(CONFIG_IPM_IMX_REV2) +#if defined(CONFIG_HAS_MCUX) data32[i] = MU_ReceiveMsg(base, (id * IMX_IPM_DATA_REGS) + i); #else @@ -166,7 +167,7 @@ static int imx_mu_ipm_send(const struct device *dev, int wait, uint32_t id, const struct imx_mu_config *config = dev->config; MU_Type *base = MU(config); uint32_t data32[IMX_IPM_DATA_REGS] = {0}; -#if !IS_ENABLED(CONFIG_IPM_IMX_REV2) +#if !IS_ENABLED(CONFIG_HAS_MCUX) mu_status_t status; #endif int i; @@ -182,7 +183,7 @@ static int imx_mu_ipm_send(const struct device *dev, int wait, uint32_t id, /* Actual message is passing using 32 bits registers */ memcpy(data32, data, size); -#if defined(CONFIG_IPM_IMX_REV2) +#if defined(CONFIG_HAS_MCUX) if (wait) { for (i = 0; i < IMX_IPM_DATA_REGS; i++) { MU_SendMsgNonBlocking(base, id * IMX_IPM_DATA_REGS + i, @@ -249,7 +250,7 @@ static int imx_mu_ipm_set_enabled(const struct device *dev, int enable) { const struct imx_mu_config *config = dev->config; MU_Type *base = MU(config); -#if defined(CONFIG_IPM_IMX_REV2) +#if defined(CONFIG_HAS_MCUX) #if CONFIG_IPM_IMX_MAX_DATA_SIZE_4 if (enable) { MU_EnableInterrupts(base, kMU_Rx0FullInterruptEnable); diff --git a/dts/arm/nxp/nxp_rt11xx_cm4.dtsi b/dts/arm/nxp/nxp_rt11xx_cm4.dtsi index 1348bba3002..4fab1c307f3 100644 --- a/dts/arm/nxp/nxp_rt11xx_cm4.dtsi +++ b/dts/arm/nxp/nxp_rt11xx_cm4.dtsi @@ -54,7 +54,7 @@ }; mailbox_b: mailbox@40c4c000 { - compatible = "nxp,imx-mu-rev2"; + compatible = "nxp,imx-mu"; reg = <0x40c4c000 0x4000>; interrupts = <118 0>; rdc = <0>; diff --git a/dts/arm/nxp/nxp_rt11xx_cm7.dtsi b/dts/arm/nxp/nxp_rt11xx_cm7.dtsi index 63a7fc78319..28cc4ff020d 100644 --- a/dts/arm/nxp/nxp_rt11xx_cm7.dtsi +++ b/dts/arm/nxp/nxp_rt11xx_cm7.dtsi @@ -77,7 +77,7 @@ }; mailbox_a: mailbox@40c48000 { - compatible = "nxp,imx-mu-rev2"; + compatible = "nxp,imx-mu"; reg = <0x40c48000 0x4000>; interrupts = <118 0>; rdc = <0>; diff --git a/dts/bindings/arm/nxp,imx-mu-rev2.yaml b/dts/bindings/arm/nxp,imx-mu-rev2.yaml deleted file mode 100644 index 7759e52293c..00000000000 --- a/dts/bindings/arm/nxp,imx-mu-rev2.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2018, NXP -# SPDX-License-Identifier: Apache-2.0 - -description: i.MX Messaging Unit - -compatible: "nxp,imx-mu-rev2" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true - - rdc: - type: int - required: true - description: Set the RDC permission for this peripheral diff --git a/dts/bindings/arm/nxp,imx-mu.yaml b/dts/bindings/ipm/nxp,imx-mu.yaml similarity index 100% rename from dts/bindings/arm/nxp,imx-mu.yaml rename to dts/bindings/ipm/nxp,imx-mu.yaml diff --git a/dts/xtensa/nxp/nxp_imx8m.dtsi b/dts/xtensa/nxp/nxp_imx8m.dtsi index 9e72a3d59ed..f354c8303ea 100644 --- a/dts/xtensa/nxp/nxp_imx8m.dtsi +++ b/dts/xtensa/nxp/nxp_imx8m.dtsi @@ -69,7 +69,7 @@ }; mailbox0: mailbox@30e70000 { - compatible = "nxp,imx-mu-rev2"; + compatible = "nxp,imx-mu"; reg = <0x30e70000 0x10000>; interrupts = <7 0>; rdc = <0>; diff --git a/soc/arm/nxp_imx/rt/soc_rt11xx.c b/soc/arm/nxp_imx/rt/soc_rt11xx.c index 7340fd0f3ff..ca3ebd08c66 100644 --- a/soc/arm/nxp_imx/rt/soc_rt11xx.c +++ b/soc/arm/nxp_imx/rt/soc_rt11xx.c @@ -37,13 +37,13 @@ #include #define DUAL_CORE_MU_ENABLED \ - (CONFIG_SECOND_CORE_MCUX && CONFIG_IPM && CONFIG_IPM_IMX_REV2) + (CONFIG_SECOND_CORE_MCUX && CONFIG_IPM && CONFIG_IPM_IMX) #if DUAL_CORE_MU_ENABLED /* Dual core mode is enabled, and messaging unit is present */ #include #define BOOT_FLAG 0x1U -#define MU_BASE (MU_Type *)DT_REG_ADDR(DT_INST(0, nxp_imx_mu_rev2)) +#define MU_BASE (MU_Type *)DT_REG_ADDR(DT_INST(0, nxp_imx_mu)) #endif #if CONFIG_USB_DC_NXP_EHCI /* USB PHY configuration */ From 29ab2b13f6a3e6d04f6b297c16ae75fde32ff242 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 31 Oct 2023 14:15:43 -0500 Subject: [PATCH 3074/4498] drivers: ipm: Remove CONFIG_IPM_IMX_REV2 Remove CONFIG_IPM_IMX_REV2, as this Kconfig is no longer needed. The driver can now be enabled with CONFIG_IPM_IMX. Update NXP HAL to remove this Kconfig as well. Signed-off-by: Daniel DeGrasse --- drivers/ipm/CMakeLists.txt | 1 - drivers/ipm/Kconfig.imx | 13 +++---------- .../mimx8ml8_m7/Kconfig.defconfig.mimx8ml8_m7 | 2 +- .../mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 | 2 +- west.yml | 2 +- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/ipm/CMakeLists.txt b/drivers/ipm/CMakeLists.txt index a6c41f845e4..cc79cce4f83 100644 --- a/drivers/ipm/CMakeLists.txt +++ b/drivers/ipm/CMakeLists.txt @@ -6,7 +6,6 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_IPM_MCUX ipm_mcux.c) zephyr_library_sources_ifdef(CONFIG_IPM_IMX ipm_imx.c) -zephyr_library_sources_ifdef(CONFIG_IPM_IMX_REV2 ipm_imx.c) zephyr_library_sources_ifdef(CONFIG_IPM_MHU ipm_mhu.c) zephyr_library_sources_ifdef(CONFIG_IPM_STM32_IPCC ipm_stm32_ipcc.c) zephyr_library_sources_ifdef(CONFIG_IPM_NRFX ipm_nrfx_ipc.c) diff --git a/drivers/ipm/Kconfig.imx b/drivers/ipm/Kconfig.imx index f945483f0be..67fbc370ac8 100644 --- a/drivers/ipm/Kconfig.imx +++ b/drivers/ipm/Kconfig.imx @@ -15,17 +15,11 @@ config IPM_IMX help Driver for NXP i.MX messaging unit -config IPM_IMX_REV2 - bool "IMX IPM driver (rev 2)" - default y - depends on DT_HAS_NXP_IMX_MU_REV2_ENABLED - help - Rev 2 driver for NXP i.MX messaging unit (MCUX-based) +if IPM_IMX choice prompt "IMX IPM max data size" default IPM_IMX_MAX_DATA_SIZE_16 - depends on IPM_IMX || IPM_IMX_REV2 help Select maximum message size for NXP i.MX messaging unit. @@ -55,7 +49,6 @@ config IPM_IMX_MAX_DATA_SIZE default 4 if IPM_IMX_MAX_DATA_SIZE_4 default 8 if IPM_IMX_MAX_DATA_SIZE_8 default 16 if IPM_IMX_MAX_DATA_SIZE_16 - depends on IPM_IMX || IPM_IMX_REV2 config IPM_IMX_MAX_ID_VAL int @@ -63,10 +56,10 @@ config IPM_IMX_MAX_ID_VAL default 3 if IPM_IMX_MAX_DATA_SIZE_4 default 1 if IPM_IMX_MAX_DATA_SIZE_8 default 0 if IPM_IMX_MAX_DATA_SIZE_16 - depends on IPM_IMX || IPM_IMX_REV2 config IPM_IMX_FW_READY_REPLY bool "Send FW_READY reply message" - depends on IPM_IMX || IPM_IMX_REV2 help Send FW_READY reply to check for FW boot completion + +endif # IPM_IMX diff --git a/soc/arm/nxp_imx/mimx8ml8_m7/Kconfig.defconfig.mimx8ml8_m7 b/soc/arm/nxp_imx/mimx8ml8_m7/Kconfig.defconfig.mimx8ml8_m7 index df80e83fdf2..8b92477601c 100644 --- a/soc/arm/nxp_imx/mimx8ml8_m7/Kconfig.defconfig.mimx8ml8_m7 +++ b/soc/arm/nxp_imx/mimx8ml8_m7/Kconfig.defconfig.mimx8ml8_m7 @@ -16,7 +16,7 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config GPIO default y -config IPM_IMX_REV2 +config IPM_IMX default y depends on IPM diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 index 1f2fe1b6c0a..70e75a6bfce 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 @@ -13,7 +13,7 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC int default 400000000 -config IPM_IMX_REV2 +config IPM_IMX default y depends on IPM diff --git a/west.yml b/west.yml index 3ff4cc0de44..0ec8c4e2ea7 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: ad142f5612d927e29b1f9606e8edade871b8a526 + revision: 361ccc5962dfc691f6134d73605fed063c4d26cd path: modules/hal/nxp groups: - hal From 2a34ecf858a633856788fa8f3f56af41af03fd16 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Wed, 1 Nov 2023 09:29:47 +0100 Subject: [PATCH 3075/4498] Bluetooth: shell: host: add missing conditional compile There was a conditional compile misssing for the BT_PER_ADV_SYNC_TRANSFER_SENDER, potentially leading to build failures Signed-off-by: Andries Kruithof --- .../bluetooth/audio/shell/bap_broadcast_assistant.c | 5 +++-- subsys/bluetooth/audio/shell/bap_scan_delegator.c | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c index 4ed37d01a16..00892ec6187 100644 --- a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c @@ -163,7 +163,7 @@ static void bap_broadcast_assistant_recv_state_cb( } } - if (per_adv_sync) { + if (per_adv_sync && IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)) { shell_print(ctx_shell, "Sending PAST"); err = bt_le_per_adv_sync_transfer(per_adv_sync, @@ -202,7 +202,8 @@ static void bap_broadcast_assistant_recv_state_cb( } } - if (ext_adv != NULL && IS_ENABLED(CONFIG_BT_PER_ADV)) { + if (ext_adv != NULL && IS_ENABLED(CONFIG_BT_PER_ADV) && + IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)) { shell_print(ctx_shell, "Sending local PAST"); err = bt_le_per_adv_set_info_transfer(ext_adv, conn, diff --git a/subsys/bluetooth/audio/shell/bap_scan_delegator.c b/subsys/bluetooth/audio/shell/bap_scan_delegator.c index ab4ee9ede0d..9ca494d36ae 100644 --- a/subsys/bluetooth/audio/shell/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/shell/bap_scan_delegator.c @@ -144,6 +144,7 @@ static void pa_timer_handler(struct k_work *work) } } +#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) static int pa_sync_past(struct bt_conn *conn, struct sync_state *state, uint16_t pa_interval) @@ -167,6 +168,7 @@ static int pa_sync_past(struct bt_conn *conn, return err; } +#endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */ static int pa_sync_no_past(struct sync_state *state, uint16_t pa_interval) @@ -441,9 +443,11 @@ static int cmd_bap_scan_delegator_sync_pa(const struct shell *sh, size_t argc, return -ENOEXEC; } - if (past_preference && - state->past_avail && - state->conn != NULL) { + if (0) { +#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) + } else if (past_preference && + state->past_avail && + state->conn != NULL) { shell_info(sh, "Syncing with PAST"); err = pa_sync_past(state->conn, state, state->pa_interval); @@ -458,7 +462,7 @@ static int cmd_bap_scan_delegator_sync_pa(const struct shell *sh, size_t argc, return -ENOEXEC; } - +#endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */ } else { shell_info(sh, "Syncing without PAST"); err = pa_sync_no_past(state, state->pa_interval); From 3b49f79cc41f2ef8f0409b99903b4a78ae332ef4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 15:51:34 +0100 Subject: [PATCH 3076/4498] modules libc3: Add missing Kconfig dependency The LC3 coded requires floating point support in the C library, so let's select REQUIRES_FULL_LIBC in the module kconfig, instead of having samples adding it to their prj.conf Signed-off-by: Alberto Escolar Piedras --- modules/liblc3/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/liblc3/Kconfig b/modules/liblc3/Kconfig index aaca9d95d7b..11ce2e34a6c 100644 --- a/modules/liblc3/Kconfig +++ b/modules/liblc3/Kconfig @@ -7,5 +7,6 @@ config ZEPHYR_LIBLC3_MODULE config LIBLC3 bool "liblc3 Support" depends on FPU + select REQUIRES_FULL_LIBC help This option enables the Android liblc3 library for Bluetooth LE Audio From c914c512a057aa568c56ff9b0b7ba846845036ec Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 16:16:16 +0100 Subject: [PATCH 3077/4498] samples/tests: Remove REQUIRES_FULL_LIBC=y due to LIBLC3 As now this is handled by the LIBLC3 kconfig Signed-off-by: Alberto Escolar Piedras --- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- .../tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- .../tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- .../tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf | 2 -- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf | 2 -- .../unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf | 2 -- .../unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf | 2 -- .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf | 2 -- .../unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf | 2 -- .../unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- tests/bluetooth/shell/boards/native_posix.conf | 2 -- .../bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf | 2 -- .../audio_samples/unicast_audio_client/boards/nrf52_bsim.conf | 2 -- .../unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf | 2 -- .../unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf | 2 -- 25 files changed, 50 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 6850b72e7d0..29f7e03dcea 100644 --- a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,7 +4,5 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y # Enable encryption. CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 9a48e919ab6..aae6000e5ab 100644 --- a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -6,7 +6,5 @@ CONFIG_BT_ISO_TX_MTU=40 # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib NEWLIB is one way of getting that. -CONFIG_NEWLIB_LIBC=y CONFIG_MAIN_STACK_SIZE=4096 CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bmr/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bms/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_bms/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_central/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_central/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_peripheral/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/tmap_peripheral/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf b/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf index db5d16058b6..8bfd5bc41f9 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf52_bsim.conf @@ -1,5 +1,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf index ea84975beb0..7c6a3aecc26 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -1,8 +1,6 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf index f968b64c424..1572abe6586 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -4,5 +4,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf index 68da448963a..76df8dba27a 100644 --- a/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_client/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,8 +4,6 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf b/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf index db5d16058b6..8bfd5bc41f9 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf52_bsim.conf @@ -1,5 +1,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf index ea84975beb0..7c6a3aecc26 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -1,8 +1,6 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf index db5d16058b6..8bfd5bc41f9 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -1,5 +1,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf index 68da448963a..76df8dba27a 100644 --- a/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/unicast_audio_server/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,8 +4,6 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/tests/bluetooth/shell/boards/native_posix.conf b/tests/bluetooth/shell/boards/native_posix.conf index 64bcdc82d29..a2ab2f4e87a 100644 --- a/tests/bluetooth/shell/boards/native_posix.conf +++ b/tests/bluetooth/shell/boards/native_posix.conf @@ -14,5 +14,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/tests/bluetooth/shell/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf b/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf index fee662d6bab..8d48d5e1c20 100644 --- a/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/tests/bluetooth/shell/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -4,5 +4,3 @@ CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf index 664b1b5e238..e8c8629ce62 100644 --- a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf52_bsim.conf @@ -3,5 +3,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf index b7166971871..f1624acbc19 100644 --- a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -3,8 +3,6 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf index 664b1b5e238..e8c8629ce62 100644 --- a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/boards/nrf5340bsim_nrf5340_cpunet.conf @@ -3,5 +3,3 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# LC3 lib requires floating point support in the c-lib. -CONFIG_REQUIRES_FULL_LIBC=y From 3c9d952820bd4b345765a56ce421f3cde52dd67b Mon Sep 17 00:00:00 2001 From: Troels Nilsson Date: Tue, 31 Oct 2023 16:50:15 +0100 Subject: [PATCH 3078/4498] Bluetooth: Controller: Fix failing LL/DDI/SCN/BV-88-C Fixes failing EBQ test LL/DDI/SCN/BV-88-C Extended Scanning, Active, Properly Ignore RFU Fields Several minor modifications made to le_ext_adv_report() to properly ignore any invalid fields present in the received PDUs Signed-off-by: Troels Nilsson --- subsys/bluetooth/controller/hci/hci.c | 119 +++++++++++++++----------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 7b1a3b86589..fac24c8be4a 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -6959,46 +6959,56 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, ptr = h->data; if (h->adv_addr) { - bt_addr_le_t addr; + /* AdvA is RFU in AUX_CHAIN_IND */ + if (node_rx_curr == node_rx || + node_rx_curr == node_rx->hdr.rx_ftr.extra) { + bt_addr_le_t addr; - adv_addr_type_curr = adv->tx_addr; - adv_addr_curr = ptr; + adv_addr_type_curr = adv->tx_addr; + adv_addr_curr = ptr; - addr.type = adv->tx_addr; - (void)memcpy(addr.a.val, ptr, sizeof(bt_addr_t)); - ptr += BDADDR_SIZE; + addr.type = adv->tx_addr; + (void)memcpy(addr.a.val, ptr, sizeof(bt_addr_t)); + + LOG_DBG(" AdvA: %s", bt_addr_le_str(&addr)); + } - LOG_DBG(" AdvA: %s", bt_addr_le_str(&addr)); + ptr += BDADDR_SIZE; } if (h->tgt_addr) { - struct lll_scan *lll; - bt_addr_le_t addr; + /* TargetA is RFU in AUX_CHAIN_IND */ + if (node_rx_curr == node_rx || + node_rx_curr == node_rx->hdr.rx_ftr.extra) { + struct lll_scan *lll; + bt_addr_le_t addr; - lll = node_rx->hdr.rx_ftr.param; + lll = node_rx->hdr.rx_ftr.param; #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) - direct_addr_type_curr = - ext_adv_direct_addr_type(lll, - direct_resolved_curr, - direct_report_curr, - adv->rx_addr, ptr); + direct_addr_type_curr = + ext_adv_direct_addr_type(lll, + direct_resolved_curr, + direct_report_curr, + adv->rx_addr, ptr); #else /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ - direct_addr_type_curr = - ext_adv_direct_addr_type(lll, - direct_resolved_curr, - false, adv->rx_addr, - ptr); + direct_addr_type_curr = + ext_adv_direct_addr_type(lll, + direct_resolved_curr, + false, adv->rx_addr, + ptr); #endif /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ - direct_addr_curr = ptr; - ptr += BDADDR_SIZE; + direct_addr_curr = ptr; - addr.type = adv->rx_addr; - (void)memcpy(addr.a.val, direct_addr_curr, - sizeof(bt_addr_t)); + addr.type = adv->rx_addr; + (void)memcpy(addr.a.val, direct_addr_curr, + sizeof(bt_addr_t)); - LOG_DBG(" TgtA: %s", bt_addr_le_str(&addr)); + LOG_DBG(" TgtA: %s", bt_addr_le_str(&addr)); + } + + ptr += BDADDR_SIZE; } if (h->adi) { @@ -7012,34 +7022,42 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, if (h->aux_ptr) { struct pdu_adv_aux_ptr *aux_ptr; - uint8_t aux_phy; - aux_ptr = (void *)ptr; + /* AuxPtr is RFU for connectable or scannable AUX_ADV_IND */ + if (node_rx_curr != node_rx->hdr.rx_ftr.extra || + evt_type_curr == 0U) { + uint8_t aux_phy; - /* Don't report if invalid phy or AUX_ADV_IND was not received - * See BT Core 5.4, Vol 6, Part B, Section 4.4.3.5: - * If the Controller does not listen for or does not receive the - * AUX_ADV_IND PDU, no report shall be generated - */ - if ((node_rx_curr == node_rx && !node_rx_next) || - PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED) { - struct node_rx_ftr *ftr; + aux_ptr = (void *)ptr; - ftr = &node_rx->hdr.rx_ftr; - node_rx_extra_list_release(ftr->extra); - return; - } + /* Don't report if invalid phy or AUX_ADV_IND was not received + * See BT Core 5.4, Vol 6, Part B, Section 4.4.3.5: + * If the Controller does not listen for or does not receive the + * AUX_ADV_IND PDU, no report shall be generated + */ + if ((node_rx_curr == node_rx && !node_rx_next) || + PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED) { + struct node_rx_ftr *ftr; - ptr += sizeof(*aux_ptr); + ftr = &node_rx->hdr.rx_ftr; + node_rx_extra_list_release(ftr->extra); + return; + } - sec_phy_curr = HCI_AUX_PHY_TO_HCI_PHY(PDU_ADV_AUX_PTR_PHY_GET(aux_ptr)); - aux_phy = BIT(PDU_ADV_AUX_PTR_PHY_GET(aux_ptr)); + sec_phy_curr = HCI_AUX_PHY_TO_HCI_PHY( + PDU_ADV_AUX_PTR_PHY_GET(aux_ptr)); - LOG_DBG(" AuxPtr chan_idx = %u, ca = %u, offs_units " - "= %u offs = 0x%x, phy = 0x%x", - aux_ptr->chan_idx, aux_ptr->ca, - aux_ptr->offs_units, PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr), aux_phy); + aux_phy = BIT(PDU_ADV_AUX_PTR_PHY_GET(aux_ptr)); + + LOG_DBG(" AuxPtr chan_idx = %u, ca = %u, offs_units " + "= %u offs = 0x%x, phy = 0x%x", + aux_ptr->chan_idx, aux_ptr->ca, + aux_ptr->offs_units, PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr), + aux_phy); + } + + ptr += sizeof(*aux_ptr); } if (h->sync_info) { @@ -7120,9 +7138,10 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, adi = adi_curr; sec_phy = sec_phy_curr; node_rx_data = node_rx_curr; - data_len = data_len_curr; - data_len_total = data_len; - data = data_curr; + /* Adv data in ADV_EXT_IND is RFU */ + data_len = 0U; + data_len_total = 0U; + data = NULL; scan_data_len_total = 0U; tx_pwr = tx_pwr_curr; From e4448ed4989b765eed6e73ef4e0efd6cec82457b Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Fri, 3 Nov 2023 11:20:24 +0100 Subject: [PATCH 3079/4498] soc: mimx8mm6_m4: Restore linker script For this SoC, an additional section is conditionally included on top of the default linker script for Cortex-M. Set `SOC_LINKER_SCRIPT` to the local `linker.ld`. Signed-off-by: Grzegorz Swiderski --- soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt index c73bf2188c6..ef0ba73b159 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt +++ b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt @@ -13,4 +13,4 @@ if(CONFIG_OPENAMP_RSC_TABLE) zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*") endif() -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From 1081df9554d225990f5137627adf8ecbdc963c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 3 Nov 2023 10:57:08 +0100 Subject: [PATCH 3080/4498] drivers: nrf_qspi_nor: Activate QSPI peripheral when enabling XIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way that the QSPI peripheral is activated has been changed in nrfx 3.2.0. Now the peripheral is not activated during the driver initialization. Instead, the driver activates the peripheral when the first operation is requested or when `nrfx_qspi_activate()` is called. In case of XIP, the latter needs to be used, as there may be no standard operation request. Signed-off-by: Andrzej Głąbek --- drivers/flash/nrf_qspi_nor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 6dd305e9430..28c705f6707 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1457,6 +1457,9 @@ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) nrf_qspi_xip_set(NRF_QSPI, enable); #endif qspi_lock(dev); + if (enable) { + (void)nrfx_qspi_activate(false); + } dev_data->xip_enabled = enable; qspi_unlock(dev); From 3fde2d307306b2f785501f4aeb05afcdadd2a2d4 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 3 Nov 2023 14:49:37 +0100 Subject: [PATCH 3081/4498] kobject: coverage: Fix LCOV_EXCL warnings Eliminate gcovr '(WARNING) mismatched coverage exclusion flags.' on missing LCOV_EXCL_START around k_object_init() introduced with ae265ea96e. Signed-off-by: Dmitrii Golovanov --- include/zephyr/sys/internal/kobject_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/sys/internal/kobject_internal.h b/include/zephyr/sys/internal/kobject_internal.h index fe02ed3cb8f..ea19d0f9a8d 100644 --- a/include/zephyr/sys/internal/kobject_internal.h +++ b/include/zephyr/sys/internal/kobject_internal.h @@ -88,6 +88,7 @@ void k_object_init(const void *obj); #else +/* LCOV_EXCL_START */ static inline void k_object_init(const void *obj) { ARG_UNUSED(obj); From 4d654250a52289987ec580f921a609d752825293 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 09:57:25 -0500 Subject: [PATCH 3082/4498] soc: lpc55xxx: Fix system hw clock cycle rate Commit c6e3bac4f changed the core clock frequency of LPC55XXX series. That clock is used by the cortex-m systick timer, which is the default timer used for system time in zephyr on this series. The bug is that the config SYS_CLOCK_HW_CYCLES_PER_SEC default was not updated on the affected platforms to account for this change, so system time is currently recorded as 150% of reality. Fix this by changing the kconfig to be set automatically at SOC level and remove board defaults. Signed-off-by: Declan Snyder --- boards/arm/lpcxpresso55s06/lpcxpresso55s06_defconfig | 1 - boards/arm/lpcxpresso55s16/lpcxpresso55s16_defconfig | 1 - boards/arm/lpcxpresso55s28/lpcxpresso55s28_defconfig | 1 - boards/arm/lpcxpresso55s36/lpcxpresso55s36_defconfig | 1 - boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig | 1 - boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig | 1 - boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig | 1 - soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc | 4 ++++ 8 files changed, 4 insertions(+), 7 deletions(-) diff --git a/boards/arm/lpcxpresso55s06/lpcxpresso55s06_defconfig b/boards/arm/lpcxpresso55s06/lpcxpresso55s06_defconfig index b239a73b8c0..a743b67e2fd 100644 --- a/boards/arm/lpcxpresso55s06/lpcxpresso55s06_defconfig +++ b/boards/arm/lpcxpresso55s06/lpcxpresso55s06_defconfig @@ -13,7 +13,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y CONFIG_PINCTRL=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_ARM_MPU=y CONFIG_RUNTIME_NMI=y diff --git a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_defconfig b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_defconfig index 1c7617436ce..44af7c468e1 100644 --- a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_defconfig +++ b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_defconfig @@ -13,7 +13,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y CONFIG_PINCTRL=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_ARM_MPU=y CONFIG_RUNTIME_NMI=y diff --git a/boards/arm/lpcxpresso55s28/lpcxpresso55s28_defconfig b/boards/arm/lpcxpresso55s28/lpcxpresso55s28_defconfig index d99a3d01c55..8ce8f718d7e 100644 --- a/boards/arm/lpcxpresso55s28/lpcxpresso55s28_defconfig +++ b/boards/arm/lpcxpresso55s28/lpcxpresso55s28_defconfig @@ -13,7 +13,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y CONFIG_PINCTRL=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36_defconfig b/boards/arm/lpcxpresso55s36/lpcxpresso55s36_defconfig index 40c1b5fec75..4bf154138af 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36_defconfig +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36_defconfig @@ -13,7 +13,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y CONFIG_PINCTRL=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_ARM_MPU=y CONFIG_RUNTIME_NMI=y diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig index f6bfb945eec..ece94dd0b6f 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig @@ -12,7 +12,6 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y CONFIG_PINCTRL=y diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig index 63d74806221..d93ccd89329 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig @@ -8,7 +8,6 @@ CONFIG_SOC_SERIES_LPC55XXX=y CONFIG_SOC_LPC55S69_CPU1=y CONFIG_BOARD_LPCXPRESSO55S69_CPU1=y CONFIG_GPIO=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_PINCTRL=y CONFIG_RUNTIME_NMI=y diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig index a82f0241fed..451a92a74a6 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig @@ -12,7 +12,6 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 CONFIG_PINCTRL=y # TFM sets up MPU_NS, can't correctly change this configuration yet diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index a1531b8ede4..c0341a8e9c5 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -130,6 +130,10 @@ config INIT_PLL1 Note that flash programming operations are limited to 100MHz, and this PLL should not be used as the core clock in those cases. +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 144000000 if INIT_PLL1 + default 96000000 + config SECOND_CORE_MCUX bool "LPC55xxx's second core" depends on HAS_MCUX From 0f903f04ac520882cda72aa0acbf503d5c2d93d3 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 20 Oct 2023 14:00:41 +1000 Subject: [PATCH 3083/4498] bluetooth: hci: spi: log TX retransmissions Add log output when the HCI interface is forced to retransmit a packet because the controller is not ready. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/spi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 42475a5e198..5620c16a10e 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -426,10 +426,14 @@ static int bt_spi_send(struct net_buf *buf) if (!ret) { /* Transmit the message */ - do { + while (true) { ret = bt_spi_transceive(buf->data, buf->len, rx_first, 1); - } while (rx_first[0] == 0U && !ret); + if (rx_first[0] != 0U || ret) { + break; + } + LOG_DBG("Controller not ready for SPI transaction of %d bytes", buf->len); + } } release_cs(); From 2283b02ce498b0285d4aa302cae568b1c534a6c5 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 20 Oct 2023 14:08:49 +1000 Subject: [PATCH 3084/4498] bluetooth: hci: spi: delay between header and data The HCI receive path has a delay between reading the header and payload from the controller to give the controller time to setup the SPI peripheral for the next transaction. Add the same delay on the transmit path for the same reasons. Signed-off-by: Jordan Yates --- drivers/bluetooth/hci/spi.c | 5 +++++ dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 5620c16a10e..32b50ea191f 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -425,6 +425,8 @@ static int bt_spi_send(struct net_buf *buf) (header_rx[1] | header_rx[2] | header_rx[3] | header_rx[4]) == 0U) && !ret); if (!ret) { + /* Delay here is rounded up to next tick */ + k_sleep(K_USEC(DATA_DELAY_US)); /* Transmit the message */ while (true) { ret = bt_spi_transceive(buf->data, buf->len, @@ -432,6 +434,9 @@ static int bt_spi_send(struct net_buf *buf) if (rx_first[0] != 0U || ret) { break; } + /* Consider increasing controller-data-delay-us + * if this message is extremely common. + */ LOG_DBG("Controller not ready for SPI transaction of %d bytes", buf->len); } } diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml index 1a5afdc6473..50d0e311461 100644 --- a/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml +++ b/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml @@ -28,10 +28,10 @@ properties: type: int default: 20 description: - Duration to delay between reading a valid header and reading the data associated - with that header. This delay gives the controller time to configure the SPI data - transaction after finishing the header transaction. Without this delay the host - can attempt to read before the controller is ready, resulting in empty data that - then needs to be read a second time. The default of 20uS was chosen as the lowest - delay that reliably eliminated double transmits between a nRF9160 host and a - nRF52832 controller. + Duration to delay between reading a valid header and transceiving the data + associated with that header. This delay gives the controller time to configure + the SPI data transaction after finishing the header transaction. Without this + delay the host can attempt to read/write before the controller is ready, + resulting in an ignored transaction that then needs to be performed a second time. + The default of 20uS was chosen as the lowest delay that reliably eliminated double + transactions between a nRF9160 host and a nRF52832 controller. From 8242ef0a3712c35f3b068fcd1057bce5039d2c5a Mon Sep 17 00:00:00 2001 From: Caspar Friedrich Date: Thu, 2 Nov 2023 23:01:05 +0100 Subject: [PATCH 3085/4498] soc: arm: st_stm32: stm32l0: Add support for STM32L081 Add support for the STM32L081xx soc series. Signed-off-by: Caspar Friedrich --- dts/arm/st/l0/stm32l081.dtsi | 13 +++++++++++ dts/arm/st/l0/stm32l081Xz.dtsi | 22 +++++++++++++++++++ .../stm32l0/Kconfig.defconfig.stm32l081xx | 14 ++++++++++++ soc/arm/st_stm32/stm32l0/Kconfig.soc | 4 ++++ 4 files changed, 53 insertions(+) create mode 100644 dts/arm/st/l0/stm32l081.dtsi create mode 100644 dts/arm/st/l0/stm32l081Xz.dtsi create mode 100644 soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l081xx diff --git a/dts/arm/st/l0/stm32l081.dtsi b/dts/arm/st/l0/stm32l081.dtsi new file mode 100644 index 00000000000..05a473a3e1b --- /dev/null +++ b/dts/arm/st/l0/stm32l081.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 Caspar Friedrich + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32l081", "st,stm32l0", "simple-bus"; + }; +}; diff --git a/dts/arm/st/l0/stm32l081Xz.dtsi b/dts/arm/st/l0/stm32l081Xz.dtsi new file mode 100644 index 00000000000..d6f28ceecce --- /dev/null +++ b/dts/arm/st/l0/stm32l081Xz.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Caspar Friedrich + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(20)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(192)>; + }; + }; + }; +}; diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l081xx b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l081xx new file mode 100644 index 00000000000..f3cc93c38c8 --- /dev/null +++ b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l081xx @@ -0,0 +1,14 @@ +# ST Microelectronics STM32L081XX MCU + +# Copyright (c) 2023 Caspar Friedrich +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32L081XX + +config SOC + default "stm32l081xx" + +config NUM_IRQS + default 32 + +endif # SOC_STM32L081XX diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.soc b/soc/arm/st_stm32/stm32l0/Kconfig.soc index 42d49fde84e..48f7a447866 100644 --- a/soc/arm/st_stm32/stm32l0/Kconfig.soc +++ b/soc/arm/st_stm32/stm32l0/Kconfig.soc @@ -38,4 +38,8 @@ config SOC_STM32L073XX bool "STM32L073XX" select CPU_HAS_ARM_MPU +config SOC_STM32L081XX + bool "STM32L081XX" + select CPU_HAS_ARM_MPU + endchoice From 016a113eb574f60129e5ee3f7f22a1b6eb621185 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Sun, 9 Apr 2023 17:54:54 -0700 Subject: [PATCH 3086/4498] boards: xtensa: Add support for Lolin S2 Mini Add support for LOLIN S2 Mini board, a cheap board also sold as Wemos S2 Mini. Signed-off-by: Moritz Fischer --- .../xtensa/esp32s2_lolin_mini/Kconfig.board | 12 ++ .../esp32s2_lolin_mini/Kconfig.defconfig | 15 ++ boards/xtensa/esp32s2_lolin_mini/board.cmake | 9 ++ .../doc/img/esp32_s2_lolin_mini.jpg | Bin 0 -> 62652 bytes .../xtensa/esp32s2_lolin_mini/doc/index.rst | 96 +++++++++++++ .../esp32s2_lolin_mini-pinctrl.dtsi | 23 +++ .../esp32s2_lolin_mini/esp32s2_lolin_mini.dts | 131 ++++++++++++++++++ .../esp32s2_lolin_mini.yaml | 14 ++ .../esp32s2_lolin_mini_defconfig | 12 ++ .../esp32s2_lolin_mini/support/openocd.cfg | 4 + tests/lib/heap/testcase.yaml | 1 + 11 files changed, 317 insertions(+) create mode 100644 boards/xtensa/esp32s2_lolin_mini/Kconfig.board create mode 100644 boards/xtensa/esp32s2_lolin_mini/Kconfig.defconfig create mode 100644 boards/xtensa/esp32s2_lolin_mini/board.cmake create mode 100644 boards/xtensa/esp32s2_lolin_mini/doc/img/esp32_s2_lolin_mini.jpg create mode 100644 boards/xtensa/esp32s2_lolin_mini/doc/index.rst create mode 100644 boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini-pinctrl.dtsi create mode 100644 boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.dts create mode 100644 boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml create mode 100644 boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig create mode 100644 boards/xtensa/esp32s2_lolin_mini/support/openocd.cfg diff --git a/boards/xtensa/esp32s2_lolin_mini/Kconfig.board b/boards/xtensa/esp32s2_lolin_mini/Kconfig.board new file mode 100644 index 00000000000..1f567f3f42b --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/Kconfig.board @@ -0,0 +1,12 @@ +# ESP32S2 LOLIN S2 MINI board configuration + +# Copyright (c) 2023 Google, LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32S2_LOLIN_MINI + bool "ESP32S2 Lolin Mini Board" + depends on SOC_SERIES_ESP32S2 + +choice SOC_PART_NUMBER + default SOC_ESP32S2_FN4R2 +endchoice diff --git a/boards/xtensa/esp32s2_lolin_mini/Kconfig.defconfig b/boards/xtensa/esp32s2_lolin_mini/Kconfig.defconfig new file mode 100644 index 00000000000..7724f8c90a1 --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/Kconfig.defconfig @@ -0,0 +1,15 @@ +# ESP32S2 LOLIN S2 MINI board configuration + +# Copyright (c) 2023 Google, LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "esp32s2_lolin_mini" + depends on BOARD_ESP32S2_LOLIN_MINI + +config ENTROPY_GENERATOR + default y + +config HEAP_MEM_POOL_SIZE + default 32768 if WIFI + default 4096 diff --git a/boards/xtensa/esp32s2_lolin_mini/board.cmake b/boards/xtensa/esp32s2_lolin_mini/board.cmake new file mode 100644 index 00000000000..2f04d1fe886 --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/xtensa/esp32s2_lolin_mini/doc/img/esp32_s2_lolin_mini.jpg b/boards/xtensa/esp32s2_lolin_mini/doc/img/esp32_s2_lolin_mini.jpg new file mode 100644 index 0000000000000000000000000000000000000000..65ef9d11cae329b7b32aa655a510a9a77db50c37 GIT binary patch literal 62652 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 k)1p_jU$sr>d97?sW*~4PptwB|y_ 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 B36%f< literal 0 HcmV?d00001 diff --git a/boards/xtensa/esp32s2_lolin_mini/doc/index.rst b/boards/xtensa/esp32s2_lolin_mini/doc/index.rst new file mode 100644 index 00000000000..70682657f8a --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/doc/index.rst @@ -0,0 +1,96 @@ +.. _esp32s2_lolin_mini: + +ESP32-S2 Lolin Mini +################### + +Overview +******** + +ESP32-S2 is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, designed to be secure and +cost-effective, with a high performance and a rich set of IO capabilities. [1]_ + +The features include the following: + +- RSA-3072-based secure boot +- AES-XTS-256-based flash encryption +- Protected private key and device secrets from software access +- Cryptographic accelerators for enhanced performance +- Protection against physical fault injection attacks +- Various peripherals: + + - 43x programmable GPIOs + - 14x configurable capacitive touch GPIOs + - USB OTG + - LCD interface + - camera interface + - SPI + - I2S + - UART + - ADC + - DAC + - LED PWM with up to 8 channels + +.. figure:: img/esp32_s2_lolin_mini.jpg + :align: center + :alt: ESP32-S2 LOLIN MINI + +System requirements +******************* + +Prerequisites +------------- + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +------------------- + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32s2_lolin_mini + :goals: build + +The usual ``flash`` target will work with the ``esp32s2_lolin_mini`` board +configuration after putting the board into bootloader mode by holding the '0' +button then pressing 'RST' and releasing the 'RST' button. + +Here is an example for the :ref:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32s2_lolin_mini + :goals: flash + +Open a serial port using e.g. screen + +.. code-block:: shell + + screen /dev/ttyUSB0 115200 + +After the board has been manually reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! esp32s2_lolin_mini + +References +********** + +.. [1] https://www.espressif.com/en/products/socs/esp32-s2 +.. _`ESP32S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf +.. _`ESP32S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf diff --git a/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini-pinctrl.dtsi b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini-pinctrl.dtsi new file mode 100644 index 00000000000..c6dbf79e676 --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Google, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; diff --git a/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.dts b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.dts new file mode 100644 index 00000000000..9f90447560b --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.dts @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Google, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include "esp32s2_lolin_mini-pinctrl.dtsi" + +/ { + model = "esp32s2_lolin_mini"; + compatible = "espressif,esp32s2"; + + aliases { + sw0 = &user_button; + led0 = &user_led; + watchdog0 = &wdt0; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + user_led: led { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: user_button { + label = "0"; + gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&cpu0 { + clock-frequency = ; + cpu-power-states = <&deep_sleep &light_sleep>; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&timer0 { + status = "disabled"; +}; + +&timer1 { + status = "disabled"; +}; + +&timer2 { + status = "disabled"; +}; + +&timer3 { + status = "disabled"; +}; + +&trng0 { + status = "okay"; +}; + +&flash0 { + reg = <0x0 DT_SIZE_M(4)>; + + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 60kB for the bootloader */ + boot_partition: partition@1000 { + label = "mcuboot"; + reg = <0x00001000 0x0000F000>; + read-only; + }; + + /* Reserve 1024kB for the application in slot 0 */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + /* Reserve 1024kB for the application in slot 1 */ + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + /* Reserve 256kB for the scratch partition */ + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; + +&wdt0 { + status = "okay"; +}; diff --git a/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml new file mode 100644 index 00000000000..3764f5eddd7 --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml @@ -0,0 +1,14 @@ +identifier: esp32s2_lolin_mini +name: Lolin ESP32-S2 Mini +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - watchdog + - uart +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig new file mode 100644 index 00000000000..c8c04460dbe --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOARD_ESP32S2_LOLIN_MINI=y +CONFIG_SOC_SERIES_ESP32S2=y + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + +CONFIG_GPIO=y diff --git a/boards/xtensa/esp32s2_lolin_mini/support/openocd.cfg b/boards/xtensa/esp32s2_lolin_mini/support/openocd.cfg new file mode 100644 index 00000000000..f75d53b0b34 --- /dev/null +++ b/boards/xtensa/esp32s2_lolin_mini/support/openocd.cfg @@ -0,0 +1,4 @@ +set ESP_RTOS none + +source [find interface/ftdi/esp32s2_kaluga_v1.cfg] +source [find target/esp32s2.cfg] diff --git a/tests/lib/heap/testcase.yaml b/tests/lib/heap/testcase.yaml index b9ded829fa7..8f8a282f09c 100644 --- a/tests/lib/heap/testcase.yaml +++ b/tests/lib/heap/testcase.yaml @@ -12,6 +12,7 @@ tests: - m2gl025_miv - qemu_xtensa - esp32s2_saola + - esp32s2_lolin_mini - esp32s3_devkitm filter: not CONFIG_SOC_NSIM timeout: 480 From f39dba5da567901ec1079f3f1ad454b9a22fcd51 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 22 Sep 2023 17:41:48 +0200 Subject: [PATCH 3087/4498] drivers/sensor: lsm6dsv16x: add in DT both INT1 and INT2 pin Add in DT the possibility to configure both INT1 and INT2 pin. The driver will then assign one of the two (either 1 or 2, according to what value drdy_pin is set) to a gpio for receiving drdy interrupts. The other pin may be used in the future to receive event interrupts. Signed-off-by: Armando Visconti --- .../sensortile_box_pro/sensortile_box_pro.dts | 4 +++- doc/releases/migration-guide-3.6.rst | 18 ++++++++++++++++++ drivers/sensor/lsm6dsv16x/lsm6dsv16x.c | 8 ++++---- drivers/sensor/lsm6dsv16x/lsm6dsv16x.h | 5 ++++- .../sensor/lsm6dsv16x/lsm6dsv16x_trigger.c | 19 +++++++++++-------- dts/bindings/sensor/st,lsm6dsv16x-common.yaml | 13 +++++++++++-- tests/drivers/build_all/sensor/i2c.dtsi | 3 ++- tests/drivers/build_all/sensor/spi.dtsi | 3 ++- 8 files changed, 55 insertions(+), 18 deletions(-) diff --git a/boards/arm/sensortile_box_pro/sensortile_box_pro.dts b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts index 736ddaaedb4..8f5999d2aef 100644 --- a/boards/arm/sensortile_box_pro/sensortile_box_pro.dts +++ b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts @@ -175,7 +175,9 @@ compatible = "st,lsm6dsv16x"; spi-max-frequency = ; /* 10 MHz */ reg = <0>; - irq-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + int1-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>; + int2-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + drdy-pin = <2>; }; }; diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 877bff97c3c..9c2cc98c2ae 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -35,6 +35,24 @@ enable all optional modules, and then run ``west update`` again. Device Drivers and Device Tree ============================== +* The :dtcompatible:`st,lsm6dsv16x` sensor driver has been changed to support + configuration of both int1 and int2 pins. The DT attribute ``irq-gpios`` has been + removed and substituted by two new attributes, ``int1-gpios`` and ``int2-gpios``. + These attributes must be configured in the Device Tree similarly to the following + example: + + .. code-block:: devicetree + + / { + lsm6dsv16x@0 { + compatible = "st,lsm6dsv16x"; + + int1-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>; + int2-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + drdy-pin = <2>; + }; + }; + Power Management ================ diff --git a/drivers/sensor/lsm6dsv16x/lsm6dsv16x.c b/drivers/sensor/lsm6dsv16x/lsm6dsv16x.c index b2bed66b47d..f7d53bc0b93 100644 --- a/drivers/sensor/lsm6dsv16x/lsm6dsv16x.c +++ b/drivers/sensor/lsm6dsv16x/lsm6dsv16x.c @@ -919,9 +919,10 @@ static int lsm6dsv16x_init(const struct device *dev) */ #ifdef CONFIG_LSM6DSV16X_TRIGGER -#define LSM6DSV16X_CFG_IRQ(inst) \ +#define LSM6DSV16X_CFG_IRQ(inst) \ .trig_enabled = true, \ - .gpio_drdy = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \ + .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }), \ + .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, { 0 }), \ .drdy_pin = DT_INST_PROP(inst, drdy_pin) #else #define LSM6DSV16X_CFG_IRQ(inst) @@ -938,8 +939,7 @@ static int lsm6dsv16x_init(const struct device *dev) .gyro_odr = DT_INST_PROP(inst, gyro_odr), \ .gyro_range = DT_INST_PROP(inst, gyro_range), \ .drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \ - (LSM6DSV16X_CFG_IRQ(inst)), ()) + LSM6DSV16X_CFG_IRQ(inst) #define LSM6DSV16X_CONFIG_SPI(inst) \ { \ diff --git a/drivers/sensor/lsm6dsv16x/lsm6dsv16x.h b/drivers/sensor/lsm6dsv16x/lsm6dsv16x.h index 92a5e4cdcba..2b3819b306a 100644 --- a/drivers/sensor/lsm6dsv16x/lsm6dsv16x.h +++ b/drivers/sensor/lsm6dsv16x/lsm6dsv16x.h @@ -57,7 +57,8 @@ struct lsm6dsv16x_config { uint8_t gyro_range; uint8_t drdy_pulsed; #ifdef CONFIG_LSM6DSV16X_TRIGGER - const struct gpio_dt_spec gpio_drdy; + const struct gpio_dt_spec int1_gpio; + const struct gpio_dt_spec int2_gpio; uint8_t drdy_pin; bool trig_enabled; #endif /* CONFIG_LSM6DSV16X_TRIGGER */ @@ -102,6 +103,8 @@ struct lsm6dsv16x_data { uint8_t gyro_fs; #ifdef CONFIG_LSM6DSV16X_TRIGGER + struct gpio_dt_spec *drdy_gpio; + struct gpio_callback gpio_cb; sensor_trigger_handler_t handler_drdy_acc; const struct sensor_trigger *trig_drdy_acc; diff --git a/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c b/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c index a6ab65a550f..2911ee55cb7 100644 --- a/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c +++ b/drivers/sensor/lsm6dsv16x/lsm6dsv16x_trigger.c @@ -233,7 +233,7 @@ static void lsm6dsv16x_handle_interrupt(const struct device *dev) #endif } - gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, + gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); } @@ -242,11 +242,10 @@ static void lsm6dsv16x_gpio_callback(const struct device *dev, { struct lsm6dsv16x_data *lsm6dsv16x = CONTAINER_OF(cb, struct lsm6dsv16x_data, gpio_cb); - const struct lsm6dsv16x_config *cfg = lsm6dsv16x->dev->config; ARG_UNUSED(pins); - gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, GPIO_INT_DISABLE); + gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_DISABLE); #if defined(CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD) k_sem_give(&lsm6dsv16x->gpio_sem); @@ -287,8 +286,12 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; int ret; + lsm6dsv16x->drdy_gpio = (cfg->drdy_pin == 1) ? + (struct gpio_dt_spec *)&cfg->int1_gpio : + (struct gpio_dt_spec *)&cfg->int2_gpio; + /* setup data ready gpio interrupt (INT1 or INT2) */ - if (!gpio_is_ready_dt(&cfg->gpio_drdy)) { + if (!gpio_is_ready_dt(lsm6dsv16x->drdy_gpio)) { LOG_ERR("Cannot get pointer to drdy_gpio device"); return -EINVAL; } @@ -306,7 +309,7 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) lsm6dsv16x->work.handler = lsm6dsv16x_work_cb; #endif /* CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD */ - ret = gpio_pin_configure_dt(&cfg->gpio_drdy, GPIO_INPUT); + ret = gpio_pin_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INPUT); if (ret < 0) { LOG_DBG("Could not configure gpio"); return ret; @@ -314,9 +317,9 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) gpio_init_callback(&lsm6dsv16x->gpio_cb, lsm6dsv16x_gpio_callback, - BIT(cfg->gpio_drdy.pin)); + BIT(lsm6dsv16x->drdy_gpio->pin)); - if (gpio_add_callback(cfg->gpio_drdy.port, &lsm6dsv16x->gpio_cb) < 0) { + if (gpio_add_callback(lsm6dsv16x->drdy_gpio->port, &lsm6dsv16x->gpio_cb) < 0) { LOG_DBG("Could not set gpio callback"); return -EIO; } @@ -333,6 +336,6 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) return ret; } - return gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, + return gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); } diff --git a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml index d12e8c32426..619669bf545 100644 --- a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml @@ -4,10 +4,19 @@ include: sensor-device.yaml properties: - irq-gpios: + int1-gpios: type: phandle-array description: | - DRDY pin + INT1 pin + + This pin defaults to active high when produced by the sensor. + The property value should ensure the flags properly describe + the signal that is presented to the driver. + + int2-gpios: + type: phandle-array + description: | + INT2 pin This pin defaults to active high when produced by the sensor. The property value should ensure the flags properly describe diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index ae04cc44112..c7c167aca14 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -695,7 +695,8 @@ test_i2c_lsm6dso16is: lsm6dso16is@68 { test_i2c_lsm6dsv16x: lsm6dsv16x@69 { compatible = "st,lsm6dsv16x"; reg = <0x69>; - irq-gpios = <&test_gpio 0 0>; + int1-gpios = <&test_gpio 0 0>; + int2-gpios = <&test_gpio 0 0>; }; test_i2c_mcp9600: mcp9600@6a { diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index 172510894ee..bd734d98f68 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -261,7 +261,8 @@ test_spi_lsm6dsv16x: lsm6dsv16x@22 { compatible = "st,lsm6dsv16x"; reg = <0x22>; spi-max-frequency = <0>; - irq-gpios = <&test_gpio 0 0>; + int1-gpios = <&test_gpio 0 0>; + int2-gpios = <&test_gpio 0 0>; }; test_spi_bmi08x_accel: bmi08x@23 { From 85256a2c192d3655ebceb61586cf2427cc06a623 Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Thu, 28 Sep 2023 07:56:06 +0100 Subject: [PATCH 3088/4498] ARC: boards: enable ticket spinlock on nsim SMP board Enable ticket spinlock on nsim SMP board as they are naturally vulnerable to spinlock unfairness due to SMP nSIM way of work. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig | 1 + boards/arc/nsim/nsim_hs5x_smp_defconfig | 1 + boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig | 1 + boards/arc/nsim/nsim_hs6x_smp_defconfig | 1 + boards/arc/nsim/nsim_hs_smp_defconfig | 1 + 5 files changed, 5 insertions(+) diff --git a/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig b/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig index 0f327874e5b..1d146abff7f 100644 --- a/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig +++ b/boards/arc/nsim/nsim_hs5x_smp_12cores_defconfig @@ -15,3 +15,4 @@ CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y CONFIG_SMP=y CONFIG_MP_MAX_NUM_CPUS=12 +CONFIG_TICKET_SPINLOCKS=y diff --git a/boards/arc/nsim/nsim_hs5x_smp_defconfig b/boards/arc/nsim/nsim_hs5x_smp_defconfig index f4b6288b106..c801fe9430e 100644 --- a/boards/arc/nsim/nsim_hs5x_smp_defconfig +++ b/boards/arc/nsim/nsim_hs5x_smp_defconfig @@ -15,3 +15,4 @@ CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y CONFIG_SMP=y CONFIG_MP_MAX_NUM_CPUS=2 +CONFIG_TICKET_SPINLOCKS=y diff --git a/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig b/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig index 453f4782d72..86793a594c7 100644 --- a/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig +++ b/boards/arc/nsim/nsim_hs6x_smp_12cores_defconfig @@ -15,3 +15,4 @@ CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y CONFIG_SMP=y CONFIG_MP_MAX_NUM_CPUS=12 +CONFIG_TICKET_SPINLOCKS=y diff --git a/boards/arc/nsim/nsim_hs6x_smp_defconfig b/boards/arc/nsim/nsim_hs6x_smp_defconfig index 6cb2b160e1d..43085894396 100644 --- a/boards/arc/nsim/nsim_hs6x_smp_defconfig +++ b/boards/arc/nsim/nsim_hs6x_smp_defconfig @@ -15,3 +15,4 @@ CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y CONFIG_SMP=y CONFIG_MP_MAX_NUM_CPUS=2 +CONFIG_TICKET_SPINLOCKS=y diff --git a/boards/arc/nsim/nsim_hs_smp_defconfig b/boards/arc/nsim/nsim_hs_smp_defconfig index 24b1914760b..b07bc87ed41 100644 --- a/boards/arc/nsim/nsim_hs_smp_defconfig +++ b/boards/arc/nsim/nsim_hs_smp_defconfig @@ -14,3 +14,4 @@ CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y CONFIG_SMP=y CONFIG_MP_MAX_NUM_CPUS=2 +CONFIG_TICKET_SPINLOCKS=y From 88c9d1fbaf5dd61973e58bb731471283f911ca9a Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 16 Oct 2023 14:48:11 +0200 Subject: [PATCH 3089/4498] dts: st: Move eeprom from stm32l010 to stm32l010Xb The variants of this family have different sizes of eeprom. This moves eeprom definition from common family definition to device specific. Signed-off-by: Gerson Fernando Budke --- dts/arm/st/l0/stm32l010.dtsi | 4 ---- dts/arm/st/l0/stm32l010Xb.dtsi | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dts/arm/st/l0/stm32l010.dtsi b/dts/arm/st/l0/stm32l010.dtsi index db206db3721..503bbf3bd0f 100644 --- a/dts/arm/st/l0/stm32l010.dtsi +++ b/dts/arm/st/l0/stm32l010.dtsi @@ -9,9 +9,5 @@ / { soc { compatible = "st,stm32l010", "st,stm32l0", "simple-bus"; - - eeprom: eeprom@8080000{ - reg = <0x08080000 512>; - }; }; }; diff --git a/dts/arm/st/l0/stm32l010Xb.dtsi b/dts/arm/st/l0/stm32l010Xb.dtsi index 57433c87972..9b35bbe9f7b 100644 --- a/dts/arm/st/l0/stm32l010Xb.dtsi +++ b/dts/arm/st/l0/stm32l010Xb.dtsi @@ -13,6 +13,10 @@ }; soc { + eeprom: eeprom@8080000{ + reg = <0x08080000 512>; + }; + flash-controller@40022000 { flash0: flash@8000000 { reg = <0x08000000 DT_SIZE_K(128)>; From 5067e543fa0fd4b5e125a65d79ef5384e1937386 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 16 Oct 2023 14:51:10 +0200 Subject: [PATCH 3090/4498] dts: st: Add all missing l010 SoCs Add minimal devicetree entries to enable the whole stm32l010 SoC family. Signed-off-by: Gerson Fernando Budke --- dts/arm/st/l0/stm32l010X4.dtsi | 26 ++++++++++++++++++++++++++ dts/arm/st/l0/stm32l010X6.dtsi | 26 ++++++++++++++++++++++++++ dts/arm/st/l0/stm32l010X8.dtsi | 26 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 dts/arm/st/l0/stm32l010X4.dtsi create mode 100644 dts/arm/st/l0/stm32l010X6.dtsi create mode 100644 dts/arm/st/l0/stm32l010X8.dtsi diff --git a/dts/arm/st/l0/stm32l010X4.dtsi b/dts/arm/st/l0/stm32l010X4.dtsi new file mode 100644 index 00000000000..e1e25f4d5dc --- /dev/null +++ b/dts/arm/st/l0/stm32l010X4.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 OS Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(2)>; + }; + + soc { + eeprom: eeprom@8080000{ + reg = <0x08080000 128>; + }; + + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(16)>; + }; + }; + }; +}; diff --git a/dts/arm/st/l0/stm32l010X6.dtsi b/dts/arm/st/l0/stm32l010X6.dtsi new file mode 100644 index 00000000000..df6ad2c514f --- /dev/null +++ b/dts/arm/st/l0/stm32l010X6.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 OS Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(8)>; + }; + + soc { + eeprom: eeprom@8080000{ + reg = <0x08080000 256>; + }; + + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(32)>; + }; + }; + }; +}; diff --git a/dts/arm/st/l0/stm32l010X8.dtsi b/dts/arm/st/l0/stm32l010X8.dtsi new file mode 100644 index 00000000000..2d0b4a2e220 --- /dev/null +++ b/dts/arm/st/l0/stm32l010X8.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 OS Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(8)>; + }; + + soc { + eeprom: eeprom@8080000{ + reg = <0x08080000 256>; + }; + + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; From 6e3bae727bfcc24ebbb460f6a9b6845e151137a5 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 15 Oct 2023 11:01:14 +0200 Subject: [PATCH 3091/4498] soc: st: Add all missing stm32l010 SoCs Add minimal SoC entries to enable the whole stm32l010 family. Signed-off-by: Gerson Fernando Budke --- .../st_stm32/stm32l0/Kconfig.defconfig.stm32l010x4 | 14 ++++++++++++++ .../st_stm32/stm32l0/Kconfig.defconfig.stm32l010x6 | 14 ++++++++++++++ .../st_stm32/stm32l0/Kconfig.defconfig.stm32l010x8 | 14 ++++++++++++++ soc/arm/st_stm32/stm32l0/Kconfig.soc | 10 ++++++++++ 4 files changed, 52 insertions(+) create mode 100644 soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x4 create mode 100644 soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x6 create mode 100644 soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x8 diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x4 b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x4 new file mode 100644 index 00000000000..779d2624508 --- /dev/null +++ b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x4 @@ -0,0 +1,14 @@ +# ST Microelectronics STM32L010XX MCU +# +# Copyright (c) 2023 OS Systems +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32L010X4 + +config SOC + default "stm32l010x4" + +config NUM_IRQS + default 30 + +endif # SOC_STM32L010X4 diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x6 b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x6 new file mode 100644 index 00000000000..dd86c005ad8 --- /dev/null +++ b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x6 @@ -0,0 +1,14 @@ +# ST Microelectronics STM32L010XX MCU +# +# Copyright (c) 2023 OS Systems +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32L010X6 + +config SOC + default "stm32l010x6" + +config NUM_IRQS + default 30 + +endif # SOC_STM32L010X6 diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x8 b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x8 new file mode 100644 index 00000000000..20dd0b0c09a --- /dev/null +++ b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010x8 @@ -0,0 +1,14 @@ +# ST Microelectronics STM32L010XX MCU +# +# Copyright (c) 2023 OS Systems +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32L010X8 + +config SOC + default "stm32l010x8" + +config NUM_IRQS + default 30 + +endif # SOC_STM32L010X8 diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.soc b/soc/arm/st_stm32/stm32l0/Kconfig.soc index 48f7a447866..0baab0cf2b9 100644 --- a/soc/arm/st_stm32/stm32l0/Kconfig.soc +++ b/soc/arm/st_stm32/stm32l0/Kconfig.soc @@ -2,6 +2,7 @@ # Copyright (c) 2018 Endre Karlson # Copyright (c) 2021 Nomono AS +# Copyright (c) 2023 OS Systems # # SPDX-License-Identifier: Apache-2.0 @@ -9,6 +10,15 @@ choice prompt "STM32L0x MCU Selection" depends on SOC_SERIES_STM32L0X +config SOC_STM32L010X4 + bool "STM32L010X4" + +config SOC_STM32L010X6 + bool "STM32L010X6" + +config SOC_STM32L010X8 + bool "STM32L010X8" + config SOC_STM32L010XB bool "STM32L010XB" From 3ed1c990dc612adb2b48b87cf79c9364c167a4e6 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 16 Oct 2023 15:19:07 +0200 Subject: [PATCH 3092/4498] soc: st: l010xb: Fix the number of IRQs Change the NUM_IRQS value from 32 to 30 following the rm0451. Signed-off-by: Gerson Fernando Budke --- soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010xb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010xb b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010xb index d447e92f4e0..89e20292fc1 100644 --- a/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010xb +++ b/soc/arm/st_stm32/stm32l0/Kconfig.defconfig.stm32l010xb @@ -9,6 +9,6 @@ config SOC default "stm32l010xb" config NUM_IRQS - default 32 + default 30 endif # SOC_STM32L010XB From 314b72f332c9eedf6f3b2ee9dda937ba7d84fdc6 Mon Sep 17 00:00:00 2001 From: Charlie Xiong <1981639884@qq.com> Date: Wed, 1 Nov 2023 11:39:12 +0800 Subject: [PATCH 3093/4498] arch: arm64: Re-init HCR_EL2 in z_arm64_el2_init HCR_EL2 is configured to certain value by some loaders such as Uboot on some arm64 boards(such as roc_rk3568_pc), When HCR_EL2.TGE, HCR_EL2.AMO and HCR_EL2.IMO bits are set to 1, some unpredictable behaviors may occur during zephyr boot. So we clear these bits to avoid it. Signed-off-by: Charlie Xiong <1981639884@qq.com> --- arch/arm64/core/reset.c | 6 ++++++ include/zephyr/arch/arm64/cpu.h | 1 + 2 files changed, 7 insertions(+) diff --git a/arch/arm64/core/reset.c b/arch/arm64/core/reset.c index bd78555de54..f96783318f4 100644 --- a/arch/arm64/core/reset.c +++ b/arch/arm64/core/reset.c @@ -125,6 +125,12 @@ void z_arm64_el2_init(void) write_sctlr_el2(reg); reg = read_hcr_el2(); + /* when EL2 is enable in current security status: + * Clear TGE bit: All exceptions that would not be routed to EL2; + * Clear AMO bit: Physical SError interrupts are not taken to EL2 and EL3. + * Clear IMO bit: Physical IRQ interrupts are not taken to EL2 and EL3. + */ + reg &= ~(HCR_IMO_BIT | HCR_AMO_BIT | HCR_TGE_BIT); reg |= HCR_RW_BIT; /* EL1 Execution state is AArch64 */ write_hcr_el2(reg); diff --git a/include/zephyr/arch/arm64/cpu.h b/include/zephyr/arch/arm64/cpu.h index bd291957959..468db381ef5 100644 --- a/include/zephyr/arch/arm64/cpu.h +++ b/include/zephyr/arch/arm64/cpu.h @@ -137,6 +137,7 @@ #define HCR_FMO_BIT BIT(3) #define HCR_IMO_BIT BIT(4) #define HCR_AMO_BIT BIT(5) +#define HCR_TGE_BIT BIT(27) #define HCR_RW_BIT BIT(31) /* System register interface to GICv3 */ From 8fe6e0130e6f5f8e527370a5b37725b73ea12504 Mon Sep 17 00:00:00 2001 From: Charlie Xiong <1981639884@qq.com> Date: Wed, 1 Nov 2023 11:39:50 +0800 Subject: [PATCH 3094/4498] boards: arm64: provide support for ROC-RK3568-PC This is support for AArch64 development board. The board uses 4-core Cortex-A55, which are based on the ARMv8.2 architecture. In addition,we support smp support and it can use 4-cores to run basic samples. Signed-off-by: Charlie Xiong <1981639884@qq.com> --- boards/arm64/roc_rk3568_pc/CMakeLists.txt | 1 + boards/arm64/roc_rk3568_pc/Kconfig.board | 8 + boards/arm64/roc_rk3568_pc/Kconfig.defconfig | 10 ++ boards/arm64/roc_rk3568_pc/board.cmake | 1 + boards/arm64/roc_rk3568_pc/doc/index.rst | 142 ++++++++++++++++++ boards/arm64/roc_rk3568_pc/roc_rk3568_pc.dts | 33 ++++ boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml | 13 ++ .../roc_rk3568_pc/roc_rk3568_pc_defconfig | 26 ++++ .../arm64/roc_rk3568_pc/roc_rk3568_pc_smp.dts | 8 + .../roc_rk3568_pc/roc_rk3568_pc_smp.yaml | 15 ++ .../roc_rk3568_pc/roc_rk3568_pc_smp_defconfig | 36 +++++ dts/arm64/rockchip/rk3568.dtsi | 89 +++++++++++ soc/arm64/rockchip/Kconfig | 1 + soc/arm64/rockchip/rk3568/CMakeLists.txt | 3 + .../rockchip/rk3568/Kconfig.defconfig.rk3568 | 24 +++ .../rockchip/rk3568/Kconfig.defconfig.series | 12 ++ soc/arm64/rockchip/rk3568/Kconfig.series | 10 ++ soc/arm64/rockchip/rk3568/Kconfig.soc | 16 ++ soc/arm64/rockchip/rk3568/linker.ld | 7 + soc/arm64/rockchip/rk3568/mmu_regions.c | 29 ++++ 20 files changed, 484 insertions(+) create mode 100644 boards/arm64/roc_rk3568_pc/CMakeLists.txt create mode 100644 boards/arm64/roc_rk3568_pc/Kconfig.board create mode 100644 boards/arm64/roc_rk3568_pc/Kconfig.defconfig create mode 100644 boards/arm64/roc_rk3568_pc/board.cmake create mode 100644 boards/arm64/roc_rk3568_pc/doc/index.rst create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc.dts create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.dts create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml create mode 100644 boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig create mode 100644 dts/arm64/rockchip/rk3568.dtsi create mode 100644 soc/arm64/rockchip/rk3568/CMakeLists.txt create mode 100644 soc/arm64/rockchip/rk3568/Kconfig.defconfig.rk3568 create mode 100644 soc/arm64/rockchip/rk3568/Kconfig.defconfig.series create mode 100644 soc/arm64/rockchip/rk3568/Kconfig.series create mode 100644 soc/arm64/rockchip/rk3568/Kconfig.soc create mode 100644 soc/arm64/rockchip/rk3568/linker.ld create mode 100644 soc/arm64/rockchip/rk3568/mmu_regions.c diff --git a/boards/arm64/roc_rk3568_pc/CMakeLists.txt b/boards/arm64/roc_rk3568_pc/CMakeLists.txt new file mode 100644 index 00000000000..9881313609a --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/CMakeLists.txt @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/roc_rk3568_pc/Kconfig.board b/boards/arm64/roc_rk3568_pc/Kconfig.board new file mode 100644 index 00000000000..97844de31fd --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/Kconfig.board @@ -0,0 +1,8 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ROC_RK3568_PC + bool "Rockchip ROC-RK3568-PC" + depends on SOC_SERIES_RK3568 + select ARM64 diff --git a/boards/arm64/roc_rk3568_pc/Kconfig.defconfig b/boards/arm64/roc_rk3568_pc/Kconfig.defconfig new file mode 100644 index 00000000000..9ad4f73bd2b --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ROC_RK3568_PC + +config BOARD + default "roc_rk3568_pc" + +endif # BOARD_ROC_RK3568_PC diff --git a/boards/arm64/roc_rk3568_pc/board.cmake b/boards/arm64/roc_rk3568_pc/board.cmake new file mode 100644 index 00000000000..9881313609a --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/board.cmake @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/roc_rk3568_pc/doc/index.rst b/boards/arm64/roc_rk3568_pc/doc/index.rst new file mode 100644 index 00000000000..ae999409545 --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/doc/index.rst @@ -0,0 +1,142 @@ +.. _roc_rk3568_pc: + +Firefly ROC-RK3568-PC (Quad-core Cortex-A55) +############################################ + +Overview +******** + +The ROC-RK3568-PC is a Quad-Core 64-Bit Mini Computer, which supports 4G large RAM. M.2 +and SATA3.0 interfaces enables expansion with large hard drives. +Providing dual Gigabit Ethernet ports, it supports WiFi 6 wireless transmission. +Control Port can be connected with RS485/RS232 devices. + +RK3568 quad-core 64-bit Cortex-A55 processor, with brand new ARM v8.2-A architecture, +has frequency up to 2.0GHz. Zephyr OS is ported to run on it. + + +- Board features: + + - RAM: 4GB LPDDR4 + - Storage: + + - 32GB eMMC + - M.2 PCIe 3.0 x 1 (Expand with 2242 / 2280 NVMe SSD) + - TF-Card Slot + - Wireless: + + - Supports WiFi 6 (802.11 AX) + - Supports BT5.0 + - USB: + + - One USB 3.0 + - Two USB 2.0 + - One Type-C + - Ethernet + - M.2 PCIe3.0 (Expand with NVMe SSD) + - LEDs: + + - 1x Power status LED + - Debug + + - UART debug ports for board + + +Supported Features +================== + +The Zephyr roc_rk3568_pc board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| GIC-v3 | on-chip | interrupt controller | ++-----------+------------+-------------------------------------+ +| ARM TIMER | on-chip | system clock | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-----------+------------+-------------------------------------+ + +Devices +======== +System Clock +------------ + +This board configuration uses a system clock frequency of 24 MHz. +Cortex-A55 Core runs up to 2.0 GHz. + +Serial Port +----------- + +This board configuration uses a single serial communication channel with the +CPU's UART2. + +Programming and Debugging +************************* + +Use U-Boot to load the zephyr.bin to the memory and kick it: + +.. code-block:: console + + tftp 0x40000000 zephyr.bin; dcache flush; icache flush; dcache off; icache off; go 0x40000000 + +Use this configuration to run basic Zephyr applications and kernel tests, +for example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: roc_rk3568_pc + :goals: run + +This will build an image with the synchronization sample app, boot it and +display the following ram console output: + +.. code-block:: console + + *** Booting Zephyr OS build bc695c6df5eb *** + thread_a: Hello World from cpu 0 on roc_rk3568_pc! + thread_b: Hello World from cpu 0 on roc_rk3568_pc! + thread_a: Hello World from cpu 0 on roc_rk3568_pc! + thread_b: Hello World from cpu 0 on roc_rk3568_pc! + + +roc_rk3568_pc_smp support, use this configuration to run Zephyr smp applications and subsys tests, +for example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: roc_rk3568_pc_smp + :goals: run + +This will build an image with the shell_module sample app, boot it and +display the following ram console output: + +.. code-block:: console + + *** Booting Zephyr OS build bc695c6df5eb *** + I/TC: Secondary CPU 1 initializing + I/TC: Secondary CPU 1 switching to normal world boot + I/TC: Secondary CPU 2 initializing + I/TC: Secondary CPU 2 switching to normal world boot + I/TC: Secondary CPU 3 initializing + I/TC: Secondary CPU 3 switching to normal world boot + Secondary CPU core 1 (MPID:0x100) is up + Secondary CPU core 2 (MPID:0x200) is up + Secondary CPU core 3 (MPID:0x300) is up + + thread_a: Hello World from cpu 0 on roc_rk3568_pc! + thread_b: Hello World from cpu 1 on roc_rk3568_pc! + thread_a: Hello World from cpu 0 on roc_rk3568_pc! + thread_b: Hello World from cpu 1 on roc_rk3568_pc! + +References +========== + +More information can refer to Firefly official website: +`Firefly website`_. + +.. _Firefly website: + https://en.t-firefly.com/product/industry/rocrk3568pc.html?theme=pc diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.dts b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.dts new file mode 100644 index 00000000000..0e2d0137229 --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.dts @@ -0,0 +1,33 @@ +/* + * Copyright 2022 HNU-ESNL + * Copyright 2022 openEuler SIG-Zephyr + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Firefly ROC-RK3568-PC"; + compatible = "rockchip,rk3568"; + + chosen { + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + zephyr,sram = &sram0; + }; + + sram0: memory@40000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x40000000 DT_SIZE_M(1)>; + }; + +}; + +&uart2 { + status = "okay"; + current-speed = <1500000>; +}; diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml new file mode 100644 index 00000000000..6a303ded9fa --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml @@ -0,0 +1,13 @@ +identifier: roc_rk3568_pc +name: Rockchip ROC RK3568 PC +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 1024 +testing: + default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig new file mode 100644 index 00000000000..d85c08d24e7 --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig @@ -0,0 +1,26 @@ +# Copyright 2021 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_SOC_SERIES_RK3568=y +CONFIG_SOC_RK3568=y +CONFIG_BOARD_ROC_RK3568_PC=y +CONFIG_ARM_ARCH_TIMER=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# ARMv8 NS world with cache management +CONFIG_ARMV8_A_NS=y +CONFIG_CACHE_MANAGEMENT=y + +# Clock support +CONFIG_CLOCK_CONTROL=y +CONFIG_TICKLESS_KERNEL=y diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.dts b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.dts new file mode 100644 index 00000000000..41d10fb4402 --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.dts @@ -0,0 +1,8 @@ +/* + * Copyright 2022 HNU-ESNL + * Copyright 2022 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "roc_rk3568_pc.dts" diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml new file mode 100644 index 00000000000..abc5dddabda --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml @@ -0,0 +1,15 @@ +identifier: roc_rk3568_pc_smp +name: Rockchip ROC RK3568 PC SMP +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 1024 +supported: + - smp +testing: + default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig new file mode 100644 index 00000000000..3ffc3f25b41 --- /dev/null +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig @@ -0,0 +1,36 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_SOC_SERIES_RK3568=y +CONFIG_SOC_RK3568=y +CONFIG_BOARD_ROC_RK3568_PC=y +CONFIG_ARM_ARCH_TIMER=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# SMP support +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=4 +CONFIG_MAX_THREAD_BYTES=4 + +# ARMv8 NS world with cache management +CONFIG_ARMV8_A_NS=y +CONFIG_CACHE_MANAGEMENT=y +CONFIG_DCACHE=y + +# PSCI support +CONFIG_PM_CPU_OPS=y +CONFIG_PM_CPU_OPS_PSCI=y + +# Clock support +CONFIG_CLOCK_CONTROL=y +CONFIG_TICKLESS_KERNEL=y diff --git a/dts/arm64/rockchip/rk3568.dtsi b/dts/arm64/rockchip/rk3568.dtsi new file mode 100644 index 00000000000..360851987a2 --- /dev/null +++ b/dts/arm64/rockchip/rk3568.dtsi @@ -0,0 +1,89 @@ +/* + * Copyright 2020 NXP + * Copyright 2022 HNU-ESNL + * Copyright 2022 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + + +/ { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "rockchip,rk3568"; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x000>; + }; + + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x100>; + }; + + cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x200>; + + }; + + cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x300>; + }; + }; + + gic: interrupt-controller@fd400000 { + #address-cells = <1>; + compatible = "arm,gic-v3","arm,gic"; + #interrupt-cells = <4>; + interrupt-controller; + + reg = <0xfd400000 0x10000>, /* GICD */ + <0xfd460000 0xc0000>; /* GICR */ + status = "okay"; + }; + + psci { + compatible = "arm,psci-0.2", "arm,psci"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + }; + + uart2: serial@fe660000 { + compatible = "rockchip,rk3568-uart", "ns16550"; + reg = <0xfe660000 0x10000>; + interrupts = ; + clock-frequency = <12000000>; + reg-shift = <2>; + status = "disabled"; + }; + +}; diff --git a/soc/arm64/rockchip/Kconfig b/soc/arm64/rockchip/Kconfig index 668d1e9785a..e0b4b937c79 100644 --- a/soc/arm64/rockchip/Kconfig +++ b/soc/arm64/rockchip/Kconfig @@ -17,5 +17,6 @@ source "soc/arm64/rockchip/*/Kconfig.soc" config SOC_PART_NUMBER default "RK3399" if SOC_SERIES_RK3399 + default "RK3568" if SOC_SERIES_RK3568 endif # SOC_FAMILY_ROCKCHIP diff --git a/soc/arm64/rockchip/rk3568/CMakeLists.txt b/soc/arm64/rockchip/rk3568/CMakeLists.txt new file mode 100644 index 00000000000..2cf9a407f84 --- /dev/null +++ b/soc/arm64/rockchip/rk3568/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) diff --git a/soc/arm64/rockchip/rk3568/Kconfig.defconfig.rk3568 b/soc/arm64/rockchip/rk3568/Kconfig.defconfig.rk3568 new file mode 100644 index 00000000000..13dca55c6e9 --- /dev/null +++ b/soc/arm64/rockchip/rk3568/Kconfig.defconfig.rk3568 @@ -0,0 +1,24 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RK3568 + +config SOC + default "rk3568" + +config FLASH_SIZE + default 0 + +config FLASH_BASE_ADDRESS + default 0 + +config NUM_IRQS + int + default 240 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 24000000 + +endif diff --git a/soc/arm64/rockchip/rk3568/Kconfig.defconfig.series b/soc/arm64/rockchip/rk3568/Kconfig.defconfig.series new file mode 100644 index 00000000000..96279038e4a --- /dev/null +++ b/soc/arm64/rockchip/rk3568/Kconfig.defconfig.series @@ -0,0 +1,12 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RK3568 + +config SOC_SERIES + default "rk3568" + +source "soc/arm64/rockchip/rk3568/Kconfig.defconfig.rk3568" + +endif # SOC_SERIES_RK3568 diff --git a/soc/arm64/rockchip/rk3568/Kconfig.series b/soc/arm64/rockchip/rk3568/Kconfig.series new file mode 100644 index 00000000000..15909e5bff0 --- /dev/null +++ b/soc/arm64/rockchip/rk3568/Kconfig.series @@ -0,0 +1,10 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyrs +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RK3568 + bool "Rockchip RK3568 Series" + select ARM64 + select SOC_FAMILY_ROCKCHIP + help + Enable support for RK3568 Series. diff --git a/soc/arm64/rockchip/rk3568/Kconfig.soc b/soc/arm64/rockchip/rk3568/Kconfig.soc new file mode 100644 index 00000000000..7bb2be41909 --- /dev/null +++ b/soc/arm64/rockchip/rk3568/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +choice +prompt "Rockchip RK3568 SoC" +depends on SOC_SERIES_RK3568 + +config SOC_RK3568 + bool "Rockchip rk3568" + select ARM64 + select CPU_CORTEX_A55 + select ARM_ARCH_TIMER + select GIC_V3 + +endchoice diff --git a/soc/arm64/rockchip/rk3568/linker.ld b/soc/arm64/rockchip/rk3568/linker.ld new file mode 100644 index 00000000000..f1b07809e1f --- /dev/null +++ b/soc/arm64/rockchip/rk3568/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/arm64/rockchip/rk3568/mmu_regions.c b/soc/arm64/rockchip/rk3568/mmu_regions.c new file mode 100644 index 00000000000..73b615cab80 --- /dev/null +++ b/soc/arm64/rockchip/rk3568/mmu_regions.c @@ -0,0 +1,29 @@ +/* + * Copyright 2020 NXP + * Copyright 2022 HNU-ESNL + * Copyright 2022 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_NODELABEL(gic), 0), + DT_REG_SIZE_BY_IDX(DT_NODELABEL(gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_RW | MT_NS), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_NODELABEL(gic), 1), + DT_REG_SIZE_BY_IDX(DT_NODELABEL(gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_RW | MT_NS), + +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; From f027b55d026e0626905c7d4def36468f67dd923b Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 13 Oct 2023 21:28:55 +0530 Subject: [PATCH 3095/4498] dts: x86: intel: alder_lake: Added TGPIO instance Enable TGPIO instance on Alder lake platform. Signed-off-by: Anisetti Avinash Krishna --- dts/x86/intel/alder_lake.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index 5856f008f4a..610c9f4ba72 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -430,6 +430,14 @@ status = "okay"; }; + tgpio: tgpio@fe001200 { + compatible = "intel,timeaware-gpio"; + reg = <0xfe001200 0x100>; + timer-clock = <19200000>; + max-pins = <2>; + status = "okay"; + }; + hpet: hpet@fed00000 { compatible = "intel,hpet"; reg = <0xfed00000 0x400>; From 0dcaa4c668c00f8d129d768fcde81d9ccbc14102 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 30 Oct 2023 12:58:16 +0100 Subject: [PATCH 3096/4498] boards: arm: stm32f746 with all mpu regions when testing in userspace Disable the quadspi mpu region of the nucleo_f746zg when testing the samples/userspace/shared_mem or tests/kernel/mem_protect/userspace The stm32f7 cortex M7 has 8 MPU regions and the one for quadspi prevents the testcase to PASS. Signed-off-by: Francois Ramu --- .../shared_mem/boards/nucleo_f746zg.overlay | 13 +++++++++++++ .../userspace/boards/nucleo_f746zg.overlay | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 samples/userspace/shared_mem/boards/nucleo_f746zg.overlay create mode 100644 tests/kernel/mem_protect/userspace/boards/nucleo_f746zg.overlay diff --git a/samples/userspace/shared_mem/boards/nucleo_f746zg.overlay b/samples/userspace/shared_mem/boards/nucleo_f746zg.overlay new file mode 100644 index 00000000000..50fa5dcc6e1 --- /dev/null +++ b/samples/userspace/shared_mem/boards/nucleo_f746zg.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Disable quadspi MPU region for testing + * on this stm32f7 target + * else one region is missing among 8 MPU regions + */ + +/delete-node/ &quadspi_memory; diff --git a/tests/kernel/mem_protect/userspace/boards/nucleo_f746zg.overlay b/tests/kernel/mem_protect/userspace/boards/nucleo_f746zg.overlay new file mode 100644 index 00000000000..50fa5dcc6e1 --- /dev/null +++ b/tests/kernel/mem_protect/userspace/boards/nucleo_f746zg.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Disable quadspi MPU region for testing + * on this stm32f7 target + * else one region is missing among 8 MPU regions + */ + +/delete-node/ &quadspi_memory; From 1747c33796620370442b3d000202ec96fe2e2a9e Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Fri, 3 Nov 2023 16:11:39 +0100 Subject: [PATCH 3097/4498] bluetooth: audio: delegator: Notify state after updating BIG_Encryption If the server has synchronized to the PA and detected that the BIS is encrypted, the server writes a value of 0x01 (Broadcast_Code required) to the BIG_Encryption field of the Broadcast Receive State characteristic to request a client to provide a Broadcast_Code. In PTS BASS/SR/CP/BV-14-C test case the PTS (client) expects that the new value of the Broadcast Receive State characteristicstate will be notified, so the PTS could sent Set Broadcast_Code operation to the server. Signed-off-by: Magdalena Kasenberg --- subsys/bluetooth/audio/bap_scan_delegator.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index f23c438099d..d0de2a4fb27 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -1335,6 +1335,11 @@ int bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_par state_changed = true; } + if (state->encrypt_state != param->encrypt_state) { + state->encrypt_state = param->encrypt_state; + state_changed = true; + } + /* Verify that the BIS sync values is acceptable for the receive state */ for (uint8_t i = 0U; i < state->num_subgroups; i++) { const uint32_t bis_sync = param->subgroups[i].bis_sync; From e562784bac7bdcdef0b04a5237f5ccf20ae6d3cc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 16:27:49 +0200 Subject: [PATCH 3098/4498] acpi: Remove unnecessary static array The acpi_tables array is only needed for systems where dynamic memory allocation is not available during the early ACPI init phase. In the Zephyr case we can immediately start using k_malloc, so this is unnecessary. Signed-off-by: Johan Hedberg --- lib/acpi/Kconfig | 6 ------ lib/acpi/acpi.c | 15 +++++---------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index 10414338c21..de524f6c957 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -45,12 +45,6 @@ config ACPI_INIT_PRIORITY help boot time init level for acpi driver. -config ACPI_MAX_INIT_TABLES - int "maximum table entries" - default 128 - help - maximum number of table entries. - endif # ACPI config ACPI_HID_LEN_MAX diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index f84accb7af9..4d711d485be 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -26,8 +26,6 @@ static struct acpi bus_ctx = { .status = AE_NOT_CONFIGURED, }; -static ACPI_TABLE_DESC acpi_tables[CONFIG_ACPI_MAX_INIT_TABLES]; - static int acpi_init(void); static int check_init_status(void) @@ -82,13 +80,10 @@ static ACPI_STATUS initialize_acpica(void) /* Initialize the ACPI Table Manager and get all ACPI tables */ if (!bus_ctx.early_init) { status = AcpiInitializeTables(NULL, 16, FALSE); - } else { - /* Copy the root table list to dynamic memory if already initialized */ - status = AcpiReallocateRootTable(); - } - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "While initializing Table Manager")); - goto exit; + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "While initializing Table Manager")); + goto exit; + } } /* Create the ACPI namespace from ACPI tables */ @@ -358,7 +353,7 @@ static int acpi_early_init(void) return 0; } - status = AcpiInitializeTables(acpi_tables, CONFIG_ACPI_MAX_INIT_TABLES, TRUE); + status = AcpiInitializeTables(NULL, 16, FALSE); if (ACPI_FAILURE(status)) { LOG_ERR("Error in acpi table init:%d", status); return -EIO; From 3aa8b9ab83f9ac10782908d7d09ba2c95f4067e2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 16:29:50 +0200 Subject: [PATCH 3099/4498] acpi: Remove unused Kconfig variable ACPI currently uses implicit (auto) initialization, i.e. it doesn't need any init level or priority. Signed-off-by: Johan Hedberg --- lib/acpi/Kconfig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index de524f6c957..365c7f979e9 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -39,12 +39,6 @@ config ACPI_DEV_MAX help maximum acpi child devices. -config ACPI_INIT_PRIORITY - int "acpi boot time init level" - default 42 - help - boot time init level for acpi driver. - endif # ACPI config ACPI_HID_LEN_MAX From 5d8bbca05b4c5345629c74ef3d698ea5ac5ad155 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 16:45:57 +0200 Subject: [PATCH 3100/4498] acpi: Don't include PCI PRT code if not enabled in Kconfig If the CONFIG_PCIE_PRT option is disabled it makes no sense to bloat the ACPI build with PRT-related code or static tables. The diff looks a bit larger since functions in acpi.c had to be shuffled around to be able to be included in a single "#ifdef CONFIG_PCIE_PRT" block. Signed-off-by: Johan Hedberg --- lib/acpi/Kconfig | 4 + lib/acpi/acpi.c | 226 ++++++++++++++++++++++-------------------- lib/acpi/acpi_shell.c | 48 ++++----- 3 files changed, 145 insertions(+), 133 deletions(-) diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index 365c7f979e9..6c29b77875d 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -14,6 +14,8 @@ module = ACPI module-str = acpi source "subsys/logging/Kconfig.template.log_config" +if PCIE_PRT + config ACPI_PRT_BUS_NAME string "ACPI name of PCI bus" default "_SB.PCI0" @@ -26,6 +28,8 @@ config ACPI_MAX_PRT_ENTRY help Size of PRT table buffer. +endif # PCIE_PRT + config ACPI_SHELL bool "ACPI command Shell" default y diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 4d711d485be..4086692aeef 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -17,7 +17,9 @@ LOG_MODULE_REGISTER(ACPI, CONFIG_ACPI_LOG_LEVEL); struct acpi { struct acpi_dev child_dev[CONFIG_ACPI_DEV_MAX]; int num_dev; +#ifdef CONFIG_PCIE_PRT ACPI_PCI_ROUTING_TABLE pci_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; +#endif bool early_init; int status; }; @@ -194,50 +196,6 @@ static ACPI_STATUS acpi_enable_pic_mode(void) return status; } -static int acpi_get_irq_table(struct acpi *bus, char *bus_name, - ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size) -{ - ACPI_BUFFER rt_buffer; - ACPI_NAMESPACE_NODE *node; - int status; - - LOG_DBG("%s", bus_name); - - node = acpi_evaluate_method(bus_name, METHOD_NAME__PRT); - if (!node) { - LOG_ERR("Evaluation failed for given device: %s", bus_name); - return -ENODEV; - } - - rt_buffer.Pointer = rt_table; - rt_buffer.Length = rt_size; - - status = AcpiGetIrqRoutingTable(node, &rt_buffer); - if (ACPI_FAILURE(status)) { - LOG_ERR("unable to retrieve IRQ Routing Table: %s", bus_name); - return -EIO; - } - - for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { - if (!bus->pci_prt_table[i].SourceIndex) { - break; - } - if (IS_ENABLED(CONFIG_X86_64)) { - /* mark the PRT irq numbers as reserved. */ - arch_irq_set_used(bus->pci_prt_table[i].SourceIndex); - } - } - - return 0; -} - -static int acpi_retrieve_legacy_irq(struct acpi *bus) -{ - /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ - return acpi_get_irq_table(bus, CONFIG_ACPI_PRT_BUS_NAME, - bus->pci_prt_table, sizeof(bus->pci_prt_table)); -} - static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 level, void *ctx, void **ret_value) { @@ -302,46 +260,6 @@ static int acpi_enum_devices(struct acpi *bus) return 0; } -static int acpi_init(void) -{ - int status; - - LOG_DBG(""); - - if (bus_ctx.status != AE_NOT_CONFIGURED) { - LOG_DBG("acpi init already done"); - return bus_ctx.status; - } - - /* For debug version only */ - ACPI_DEBUG_INITIALIZE(); - - status = initialize_acpica(); - if (ACPI_FAILURE(status)) { - LOG_ERR("Error in ACPI init:%d", status); - goto exit; - } - - /* Enable IO APIC mode */ - status = acpi_enable_pic_mode(); - if (ACPI_FAILURE(status)) { - LOG_WRN("Error in enable pic mode acpi method:%d", status); - } - - status = acpi_retrieve_legacy_irq(&bus_ctx); - if (status) { - LOG_ERR("Error in retrieve legacy interrupt info:%d", status); - goto exit; - } - - acpi_enum_devices(&bus_ctx); - -exit: - bus_ctx.status = status; - - return status; -} - static int acpi_early_init(void) { ACPI_STATUS status; @@ -364,32 +282,6 @@ static int acpi_early_init(void) return 0; } -uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf) -{ - uint32_t slot = PCIE_BDF_TO_DEV(bdf), pin; - - LOG_DBG(""); - - if (check_init_status()) { - return UINT_MAX; - } - - pin = (pcie_conf_read(bdf, PCIE_CONF_INTR) >> 8) & 0x3; - - LOG_DBG("Device irq info: slot:%d pin:%d", slot, pin); - - for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { - if (((bus_ctx.pci_prt_table[i].Address >> 16) & 0xffff) == slot && - bus_ctx.pci_prt_table[i].Pin + 1 == pin) { - LOG_DBG("[%d]Device irq info: slot:%d pin:%d irq:%d", i, slot, pin, - bus_ctx.pci_prt_table[i].SourceIndex); - return bus_ctx.pci_prt_table[i].SourceIndex; - } - } - - return UINT_MAX; -} - int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res) { ACPI_BUFFER rt_buffer; @@ -464,6 +356,51 @@ int acpi_current_resource_free(ACPI_RESOURCE *res) return 0; } +#ifdef CONFIG_PCIE_PRT +static int acpi_get_irq_table(struct acpi *bus, char *bus_name, + ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size) +{ + ACPI_BUFFER rt_buffer; + ACPI_NAMESPACE_NODE *node; + int status; + + LOG_DBG("%s", bus_name); + + node = acpi_evaluate_method(bus_name, METHOD_NAME__PRT); + if (!node) { + LOG_ERR("Evaluation failed for given device: %s", bus_name); + return -ENODEV; + } + + rt_buffer.Pointer = rt_table; + rt_buffer.Length = rt_size; + + status = AcpiGetIrqRoutingTable(node, &rt_buffer); + if (ACPI_FAILURE(status)) { + LOG_ERR("unable to retrieve IRQ Routing Table: %s", bus_name); + return -EIO; + } + + for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { + if (!bus->pci_prt_table[i].SourceIndex) { + break; + } + if (IS_ENABLED(CONFIG_X86_64)) { + /* mark the PRT irq numbers as reserved. */ + arch_irq_set_used(bus->pci_prt_table[i].SourceIndex); + } + } + + return 0; +} + +static int acpi_retrieve_legacy_irq(struct acpi *bus) +{ + /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ + return acpi_get_irq_table(bus, CONFIG_ACPI_PRT_BUS_NAME, + bus->pci_prt_table, sizeof(bus->pci_prt_table)); +} + int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size) { @@ -477,6 +414,33 @@ int acpi_get_irq_routing_table(char *bus_name, return acpi_get_irq_table(&bus_ctx, bus_name, rt_table, rt_size); } +uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf) +{ + uint32_t slot = PCIE_BDF_TO_DEV(bdf), pin; + + LOG_DBG(""); + + if (check_init_status()) { + return UINT_MAX; + } + + pin = (pcie_conf_read(bdf, PCIE_CONF_INTR) >> 8) & 0x3; + + LOG_DBG("Device irq info: slot:%d pin:%d", slot, pin); + + for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { + if (((bus_ctx.pci_prt_table[i].Address >> 16) & 0xffff) == slot && + bus_ctx.pci_prt_table[i].Pin + 1 == pin) { + LOG_DBG("[%d]Device irq info: slot:%d pin:%d irq:%d", i, slot, pin, + bus_ctx.pci_prt_table[i].SourceIndex); + return bus_ctx.pci_prt_table[i].SourceIndex; + } + } + + return UINT_MAX; +} +#endif /* CONFIG_PCIE_PRT */ + ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type) { do { @@ -789,3 +753,45 @@ struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num) return NULL; } + +static int acpi_init(void) +{ + int status; + + LOG_DBG(""); + + if (bus_ctx.status != AE_NOT_CONFIGURED) { + LOG_DBG("acpi init already done"); + return bus_ctx.status; + } + + /* For debug version only */ + ACPI_DEBUG_INITIALIZE(); + + status = initialize_acpica(); + if (ACPI_FAILURE(status)) { + LOG_ERR("Error in ACPI init:%d", status); + goto exit; + } + + /* Enable IO APIC mode */ + status = acpi_enable_pic_mode(); + if (ACPI_FAILURE(status)) { + LOG_WRN("Error in enable pic mode acpi method:%d", status); + } + +#ifdef CONFIG_PCIE_PRT + status = acpi_retrieve_legacy_irq(&bus_ctx); + if (status) { + LOG_ERR("Error in retrieve legacy interrupt info:%d", status); + goto exit; + } +#endif + + acpi_enum_devices(&bus_ctx); + +exit: + bus_ctx.status = status; + + return status; +} diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index c6c5d5ed60d..1942b83c8ee 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -14,7 +14,6 @@ #define MAX_PR_BUFF (4096) -static ACPI_PCI_ROUTING_TABLE irq_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; static uint8_t prs_buffer[MAX_PR_BUFF]; static void dump_dev_res(const struct shell *sh, ACPI_RESOURCE *res_lst) @@ -190,29 +189,31 @@ static int dump_dev_prs(const struct shell *sh, size_t argc, char **argv) static int dump_prt(const struct shell *sh, size_t argc, char **argv) { - int status, cnt; - ACPI_PCI_ROUTING_TABLE *prt; - - if (argc < 2) { - shell_error(sh, "invalid arugment\n"); - return -EINVAL; - } + IF_ENABLED(CONFIG_PCIE_PRT, ({ + static ACPI_PCI_ROUTING_TABLE irq_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; + int status, cnt; + ACPI_PCI_ROUTING_TABLE *prt; + + if (argc < 2) { + shell_error(sh, "invalid arugment\n"); + return -EINVAL; + } - status = acpi_get_irq_routing_table(argv[1], - irq_prt_table, sizeof(irq_prt_table)); - if (status) { - return status; - } + status = acpi_get_irq_routing_table(argv[1], irq_prt_table, sizeof(irq_prt_table)); + if (status) { + return status; + } - prt = irq_prt_table; - for (cnt = 0; prt->Length; cnt++) { - shell_print(sh, "[%02X] PCI IRQ Routing Table Package\n", cnt); - shell_print(sh, - "DevNum: %lld Pin:%d IRQ: %d\n", (prt->Address >> 16) & 0xFFFF, prt->Pin, - prt->SourceIndex); + prt = irq_prt_table; + for (cnt = 0; prt->Length; cnt++) { + shell_print(sh, "[%02X] PCI IRQ Routing Table Package\n", cnt); + shell_print(sh, "DevNum: %lld Pin:%d IRQ: %d\n", + (prt->Address >> 16) & 0xFFFF, prt->Pin, + prt->SourceIndex); - prt = ACPI_ADD_PTR(ACPI_PCI_ROUTING_TABLE, prt, prt->Length); - } + prt = ACPI_ADD_PTR(ACPI_PCI_ROUTING_TABLE, prt, prt->Length); + } + })); /* IF_ENABLED(CONFIG_PCIE_PRT) */ return 0; } @@ -267,8 +268,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD(prs, NULL, "display device possible resource settings (eg:acpi crs _SB.PC00.LPCB.RTC)", dump_dev_prs), - SHELL_CMD(prt, NULL, "display PRT details for a given bus (eg:acpi prt _SB.PC00)", - dump_prt), + SHELL_COND_CMD(CONFIG_PCIE_PRT, prt, NULL, + "display PRT details for a given bus (eg:acpi prt _SB.PC00)", + dump_prt), SHELL_CMD(enum, NULL, "enumerate device using hid (for enum HPET timer device,eg:acpi enum PNP0103)", enum_dev), From 03cb76e59d7dc78801a630f3eefb0bddb4f137f4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 16:56:59 +0200 Subject: [PATCH 3101/4498] acpi: Rename bus_ctx to simply acpi ACPI is not treated as a bus in Zephyr. Rename the global context from bus_ctx to simply acpi. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 66 +++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 4086692aeef..bd3921f964b 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -14,7 +14,7 @@ #include LOG_MODULE_REGISTER(ACPI, CONFIG_ACPI_LOG_LEVEL); -struct acpi { +static struct { struct acpi_dev child_dev[CONFIG_ACPI_DEV_MAX]; int num_dev; #ifdef CONFIG_PCIE_PRT @@ -22,9 +22,7 @@ struct acpi { #endif bool early_init; int status; -}; - -static struct acpi bus_ctx = { +} acpi = { .status = AE_NOT_CONFIGURED, }; @@ -34,11 +32,11 @@ static int check_init_status(void) { int ret; - if (ACPI_SUCCESS(bus_ctx.status)) { + if (ACPI_SUCCESS(acpi.status)) { return 0; } - if (bus_ctx.status == AE_NOT_CONFIGURED) { + if (acpi.status == AE_NOT_CONFIGURED) { ret = acpi_init(); } else { LOG_ERR("ACPI init was not success\n"); @@ -80,7 +78,7 @@ static ACPI_STATUS initialize_acpica(void) } /* Initialize the ACPI Table Manager and get all ACPI tables */ - if (!bus_ctx.early_init) { + if (!acpi.early_init) { status = AcpiInitializeTables(NULL, 16, FALSE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "While initializing Table Manager")); @@ -201,7 +199,6 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev { ACPI_NAMESPACE_NODE *node; ACPI_BUFFER rt_buffer; - struct acpi *bus = (struct acpi *)ctx; struct acpi_dev *child_dev; node = ACPI_CAST_PTR(ACPI_NAMESPACE_NODE, obj_handle); @@ -218,11 +215,11 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev goto exit; } - if (bus->num_dev >= CONFIG_ACPI_DEV_MAX) { + if (acpi.num_dev >= CONFIG_ACPI_DEV_MAX) { return AE_NO_MEMORY; } - child_dev = (struct acpi_dev *)&bus->child_dev[bus->num_dev++]; + child_dev = (struct acpi_dev *)&acpi.child_dev[acpi.num_dev++]; child_dev->handle = obj_handle; child_dev->dev_info = dev_info; @@ -250,12 +247,12 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev return status; } -static int acpi_enum_devices(struct acpi *bus) +static int acpi_enum_devices(void) { LOG_DBG(""); AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - dev_resource_enum_callback, NULL, bus, NULL); + dev_resource_enum_callback, NULL, NULL, NULL); return 0; } @@ -266,7 +263,7 @@ static int acpi_early_init(void) LOG_DBG(""); - if (bus_ctx.early_init) { + if (acpi.early_init) { LOG_DBG("acpi early init already done"); return 0; } @@ -277,7 +274,7 @@ static int acpi_early_init(void) return -EIO; } - bus_ctx.early_init = true; + acpi.early_init = true; return 0; } @@ -357,8 +354,7 @@ int acpi_current_resource_free(ACPI_RESOURCE *res) } #ifdef CONFIG_PCIE_PRT -static int acpi_get_irq_table(struct acpi *bus, char *bus_name, - ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size) +static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size) { ACPI_BUFFER rt_buffer; ACPI_NAMESPACE_NODE *node; @@ -382,23 +378,23 @@ static int acpi_get_irq_table(struct acpi *bus, char *bus_name, } for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { - if (!bus->pci_prt_table[i].SourceIndex) { + if (!acpi.pci_prt_table[i].SourceIndex) { break; } if (IS_ENABLED(CONFIG_X86_64)) { /* mark the PRT irq numbers as reserved. */ - arch_irq_set_used(bus->pci_prt_table[i].SourceIndex); + arch_irq_set_used(acpi.pci_prt_table[i].SourceIndex); } } return 0; } -static int acpi_retrieve_legacy_irq(struct acpi *bus) +static int acpi_retrieve_legacy_irq(void) { /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ - return acpi_get_irq_table(bus, CONFIG_ACPI_PRT_BUS_NAME, - bus->pci_prt_table, sizeof(bus->pci_prt_table)); + return acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME, + acpi.pci_prt_table, sizeof(acpi.pci_prt_table)); } int acpi_get_irq_routing_table(char *bus_name, @@ -411,7 +407,7 @@ int acpi_get_irq_routing_table(char *bus_name, return ret; } - return acpi_get_irq_table(&bus_ctx, bus_name, rt_table, rt_size); + return acpi_get_irq_table(bus_name, rt_table, rt_size); } uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf) @@ -429,11 +425,11 @@ uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf) LOG_DBG("Device irq info: slot:%d pin:%d", slot, pin); for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { - if (((bus_ctx.pci_prt_table[i].Address >> 16) & 0xffff) == slot && - bus_ctx.pci_prt_table[i].Pin + 1 == pin) { + if (((acpi.pci_prt_table[i].Address >> 16) & 0xffff) == slot && + acpi.pci_prt_table[i].Pin + 1 == pin) { LOG_DBG("[%d]Device irq info: slot:%d pin:%d irq:%d", i, slot, pin, - bus_ctx.pci_prt_table[i].SourceIndex); - return bus_ctx.pci_prt_table[i].SourceIndex; + acpi.pci_prt_table[i].SourceIndex); + return acpi.pci_prt_table[i].SourceIndex; } } @@ -530,7 +526,7 @@ struct acpi_dev *acpi_device_get(char *hid, int inst) } do { - child_dev = &bus_ctx.child_dev[i]; + child_dev = &acpi.child_dev[i]; if (!child_dev->path) { LOG_DBG("NULL device path found\n"); continue; @@ -551,14 +547,14 @@ struct acpi_dev *acpi_device_get(char *hid, int inst) return child_dev; } } - } while (i++ < bus_ctx.num_dev); + } while (i++ < acpi.num_dev); return NULL; } struct acpi_dev *acpi_device_by_index_get(int index) { - return index < bus_ctx.num_dev ? &bus_ctx.child_dev[index] : NULL; + return index < acpi.num_dev ? &acpi.child_dev[index] : NULL; } void *acpi_table_get(char *signature, int inst) @@ -566,7 +562,7 @@ void *acpi_table_get(char *signature, int inst) int status; ACPI_TABLE_HEADER *table; - if (!bus_ctx.early_init) { + if (!acpi.early_init) { status = acpi_early_init(); if (status) { LOG_ERR("ACPI early init failed"); @@ -760,9 +756,9 @@ static int acpi_init(void) LOG_DBG(""); - if (bus_ctx.status != AE_NOT_CONFIGURED) { + if (acpi.status != AE_NOT_CONFIGURED) { LOG_DBG("acpi init already done"); - return bus_ctx.status; + return acpi.status; } /* For debug version only */ @@ -781,17 +777,17 @@ static int acpi_init(void) } #ifdef CONFIG_PCIE_PRT - status = acpi_retrieve_legacy_irq(&bus_ctx); + status = acpi_retrieve_legacy_irq(); if (status) { LOG_ERR("Error in retrieve legacy interrupt info:%d", status); goto exit; } #endif - acpi_enum_devices(&bus_ctx); + acpi_enum_devices(); exit: - bus_ctx.status = status; + acpi.status = status; return status; } From 88120ae351048c02b75a8379f63acf3013b85e6a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 31 Oct 2023 16:59:19 +0200 Subject: [PATCH 3102/4498] acpi: Fix status variable type Use the appropriate ACPI_STATUS type for any status variable that stores return values from ACPICA APIS. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index bd3921f964b..18739d0c793 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -21,7 +21,7 @@ static struct { ACPI_PCI_ROUTING_TABLE pci_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY]; #endif bool early_init; - int status; + ACPI_STATUS status; } acpi = { .status = AE_NOT_CONFIGURED, }; @@ -203,7 +203,7 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev node = ACPI_CAST_PTR(ACPI_NAMESPACE_NODE, obj_handle); char *path_name; - int status; + ACPI_STATUS status; ACPI_DEVICE_INFO *dev_info; LOG_DBG("%s %p\n", __func__, node); @@ -283,7 +283,7 @@ int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res) { ACPI_BUFFER rt_buffer; ACPI_NAMESPACE_NODE *node; - int status; + ACPI_STATUS status; LOG_DBG("%s", dev_name); @@ -319,7 +319,7 @@ int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res) { ACPI_BUFFER rt_buffer; ACPI_NAMESPACE_NODE *node; - int status; + ACPI_STATUS status; LOG_DBG("%s", dev_name); @@ -358,7 +358,7 @@ static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, { ACPI_BUFFER rt_buffer; ACPI_NAMESPACE_NODE *node; - int status; + ACPI_STATUS status; LOG_DBG("%s", bus_name); @@ -559,7 +559,7 @@ struct acpi_dev *acpi_device_by_index_get(int index) void *acpi_table_get(char *signature, int inst) { - int status; + ACPI_STATUS status; ACPI_TABLE_HEADER *table; if (!acpi.early_init) { @@ -752,7 +752,7 @@ struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num) static int acpi_init(void) { - int status; + ACPI_STATUS status; LOG_DBG(""); From 149b00f70cf8845006799edb86344a12901c53db Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 3 Nov 2023 12:09:21 +0200 Subject: [PATCH 3103/4498] acpi: Fix acpi_get_irq_routing_table() rt_size parameter meaning The acpi_get_irq_routing_table() takes a pointer to an array of ACPI_PCI_ROUTING_TABLE elements rather than a generic buffer pointer (e.g. void *). Because of the above, it makes sense to specify the array size as an actual ARRAY_SIZE() value, since it makes no sense to accept buffers which are not a multiple of sizeof(ACPI_PCI_ROUTING_TABLE) long. Signed-off-by: Johan Hedberg --- include/zephyr/acpi/acpi.h | 2 +- lib/acpi/acpi.c | 4 ++-- lib/acpi/acpi_shell.c | 3 ++- tests/lib/acpi/src/main.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/zephyr/acpi/acpi.h b/include/zephyr/acpi/acpi.h index c66f55acbb8..92a8503258b 100644 --- a/include/zephyr/acpi/acpi.h +++ b/include/zephyr/acpi/acpi.h @@ -80,7 +80,7 @@ int acpi_current_resource_free(ACPI_RESOURCE *res); * * @param bus_name the name of the bus * @param rt_table the IRQ routing table - * @param rt_size the the size of IRQ routing table + * @param rt_size number of elements in the IRQ routing table * @return return 0 on success or error code */ int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size); diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 18739d0c793..2931ad83c37 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -369,7 +369,7 @@ static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, } rt_buffer.Pointer = rt_table; - rt_buffer.Length = rt_size; + rt_buffer.Length = rt_size * sizeof(ACPI_PCI_ROUTING_TABLE); status = AcpiGetIrqRoutingTable(node, &rt_buffer); if (ACPI_FAILURE(status)) { @@ -394,7 +394,7 @@ static int acpi_retrieve_legacy_irq(void) { /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ return acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME, - acpi.pci_prt_table, sizeof(acpi.pci_prt_table)); + acpi.pci_prt_table, ARRAY_SIZE(acpi.pci_prt_table)); } int acpi_get_irq_routing_table(char *bus_name, diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index 1942b83c8ee..97ab4683989 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -199,7 +199,8 @@ static int dump_prt(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } - status = acpi_get_irq_routing_table(argv[1], irq_prt_table, sizeof(irq_prt_table)); + status = acpi_get_irq_routing_table(argv[1], + irq_prt_table, ARRAY_SIZE(irq_prt_table)); if (status) { return status; } diff --git a/tests/lib/acpi/src/main.c b/tests/lib/acpi/src/main.c index db64ceea6ea..e05a7181cc1 100644 --- a/tests/lib/acpi/src/main.c +++ b/tests/lib/acpi/src/main.c @@ -23,7 +23,7 @@ ZTEST(acpi, test_irq_routing_table) int status; status = acpi_get_irq_routing_table(CONFIG_ACPI_PRT_BUS_NAME, - irq_prt_table, sizeof(irq_prt_table)); + irq_prt_table, ARRAY_SIZE(irq_prt_table)); zassert_ok(status, "Failed to get PRT"); } From 4f2d03195bacd413e508db88efd128551049b912 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 3 Nov 2023 12:15:35 +0200 Subject: [PATCH 3104/4498] acpi: Move local pci_prt_table processing to the right place The acpi_get_irq_table() function takes a pointer to a table that can come from anywhere, i.e. it doesn't have to be the acpi.pci_prt.table that acpi.c uses. Because of this, the correct place to iterate and process the acpi.pci_prt_table is in the function that actually passes acpi.pci_prt_table to the acpi_get_irq_table() function. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 2931ad83c37..f5f92533493 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -377,7 +377,21 @@ static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, return -EIO; } - for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) { + return 0; +} + +static int acpi_retrieve_legacy_irq(void) +{ + int ret; + + /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ + ret = acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME, + acpi.pci_prt_table, ARRAY_SIZE(acpi.pci_prt_table)); + if (ret) { + return ret; + } + + for (size_t i = 0; i < ARRAY_SIZE(acpi.pci_prt_table); i++) { if (!acpi.pci_prt_table[i].SourceIndex) { break; } @@ -388,13 +402,7 @@ static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, } return 0; -} -static int acpi_retrieve_legacy_irq(void) -{ - /* TODO: assume platform have only one PCH with single PCI bus (bus 0). */ - return acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME, - acpi.pci_prt_table, ARRAY_SIZE(acpi.pci_prt_table)); } int acpi_get_irq_routing_table(char *bus_name, From 2ca5a3213f0c3220e81ee39a150c17b5609c9104 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 3 Nov 2023 12:28:00 +0200 Subject: [PATCH 3105/4498] acpi: Don't mix ACPI_STATUS and "int" return types ACPI_STATUS variables should not store values of any other error domain (like negative POSIX error codes used for Zephyr's ACPI API). Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index f5f92533493..7a9eaee02c1 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -30,19 +30,16 @@ static int acpi_init(void); static int check_init_status(void) { - int ret; + if (acpi.status == AE_NOT_CONFIGURED) { + acpi.status = acpi_init(); + } if (ACPI_SUCCESS(acpi.status)) { return 0; - } - - if (acpi.status == AE_NOT_CONFIGURED) { - ret = acpi_init(); } else { LOG_ERR("ACPI init was not success\n"); - ret = -EIO; + return -EIO; } - return ret; } static void notify_handler(ACPI_HANDLE device, UINT32 value, void *ctx) @@ -289,14 +286,13 @@ int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res) status = check_init_status(); if (status) { - return status; + return -EAGAIN; } node = acpi_evaluate_method(dev_name, METHOD_NAME__CRS); if (!node) { LOG_ERR("Evaluation failed for given device: %s", dev_name); - status = -ENOTSUP; - goto exit; + return -ENOTSUP; } rt_buffer.Pointer = NULL; @@ -305,14 +301,12 @@ int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res) status = AcpiGetCurrentResources(node, &rt_buffer); if (ACPI_FAILURE(status)) { LOG_ERR("AcpiGetCurrentResources failed: %s", AcpiFormatException(status)); - status = -ENOTSUP; + return -ENOTSUP; } else { *res = rt_buffer.Pointer; } -exit: - - return status; + return 0; } int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res) @@ -325,14 +319,13 @@ int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res) status = check_init_status(); if (status) { - return status; + return -EAGAIN; } node = acpi_evaluate_method(dev_name, METHOD_NAME__PRS); if (!node) { LOG_ERR("Evaluation failed for given device: %s", dev_name); - status = -ENOTSUP; - goto exit; + return -ENOTSUP; } rt_buffer.Pointer = NULL; @@ -341,9 +334,7 @@ int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res) AcpiGetPossibleResources(node, &rt_buffer); *res = rt_buffer.Pointer; -exit: - - return status; + return 0; } int acpi_current_resource_free(ACPI_RESOURCE *res) @@ -764,11 +755,6 @@ static int acpi_init(void) LOG_DBG(""); - if (acpi.status != AE_NOT_CONFIGURED) { - LOG_DBG("acpi init already done"); - return acpi.status; - } - /* For debug version only */ ACPI_DEBUG_INITIALIZE(); @@ -785,9 +771,11 @@ static int acpi_init(void) } #ifdef CONFIG_PCIE_PRT - status = acpi_retrieve_legacy_irq(); - if (status) { - LOG_ERR("Error in retrieve legacy interrupt info:%d", status); + int ret = acpi_retrieve_legacy_irq(); + + if (ret) { + LOG_ERR("Error in retrieve legacy interrupt info:%d", ret); + status = AE_ERROR; goto exit; } #endif @@ -795,7 +783,5 @@ static int acpi_init(void) acpi_enum_devices(); exit: - acpi.status = status; - return status; } From 537cb1ffbe5e41d5775a66036c7dbd740ca2da53 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 4 Nov 2023 14:03:55 +0200 Subject: [PATCH 3106/4498] acpi: Remove unnecessary prs_buffer variable This was never used for anything, since the ACPI API overwrites the pointer when fetching a resource list. Signed-off-by: Johan Hedberg --- lib/acpi/acpi_shell.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index 97ab4683989..651e254fb51 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -12,10 +12,6 @@ #include #include -#define MAX_PR_BUFF (4096) - -static uint8_t prs_buffer[MAX_PR_BUFF]; - static void dump_dev_res(const struct shell *sh, ACPI_RESOURCE *res_lst) { ACPI_RESOURCE *res = res_lst; @@ -169,7 +165,7 @@ static int dump_dev_crs(const struct shell *sh, size_t argc, char **argv) static int dump_dev_prs(const struct shell *sh, size_t argc, char **argv) { int status; - ACPI_RESOURCE *res_lst = (ACPI_RESOURCE *)prs_buffer; + ACPI_RESOURCE *res_lst; if (argc < 2) { shell_error(sh, "invalid arugment\n"); From fe382d4d3098f2479d09143d4d7f978ca855777e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 3 Nov 2023 17:47:02 +0200 Subject: [PATCH 3107/4498] acpi: shell: Remove unnecessary newlines The ACPI shell command create way too much vertical empty space. Remove the unnecesary newlines and use indentation to indicate grouping of lines. At the same time, place case statments with variable declarations behind {} since otherwise both the Zephyr compliance checker and some other static analyzers get confused by the code in the branch. Signed-off-by: Johan Hedberg --- lib/acpi/acpi_shell.c | 153 +++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 75 deletions(-) diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index 651e254fb51..ef940e478b3 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -16,122 +16,125 @@ static void dump_dev_res(const struct shell *sh, ACPI_RESOURCE *res_lst) { ACPI_RESOURCE *res = res_lst; - shell_print(sh, "\n**** ACPI Device Resource Info ****\n"); + shell_print(sh, "**** ACPI Device Resource Info ****"); do { if (!res->Length) { - shell_error(sh, "Error: zero length found!\n"); + shell_error(sh, "Error: zero length found!"); break; } switch (res->Type) { case ACPI_RESOURCE_TYPE_IRQ: - shell_print(sh, "\nACPI_RESOURCE_TYPE_IRQ\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_IRQ"); ACPI_RESOURCE_IRQ *irq_res = &res->Data.Irq; - shell_print(sh, - "DescriptorLength: %x, Triggering:%x, Polarity:%x, Shareable:%x,", - irq_res->DescriptorLength, irq_res->Triggering, irq_res->Polarity, - irq_res->Shareable); - shell_print(sh, - "InterruptCount:%d, Interrupts[0]:%x\n", irq_res->InterruptCount, - irq_res->Interrupts[0]); + shell_print(sh, "\tDescriptorLength: %x", irq_res->DescriptorLength); + shell_print(sh, "\tTriggering: %x", irq_res->Triggering); + shell_print(sh, "\tPolarity: %x", irq_res->Polarity); + shell_print(sh, "\tShareable: %x", irq_res->Shareable); + shell_print(sh, "\tInterruptCount: %d", irq_res->InterruptCount); + shell_print(sh, "\tInterrupts[0]: %x", irq_res->Interrupts[0]); break; - case ACPI_RESOURCE_TYPE_IO: - ACPI_RESOURCE_IO * io_res = &res->Data.Io; - - shell_print(sh, "\n ACPI_RESOURCE_TYPE_IO\n"); - shell_print(sh, - "IoDecode: %x, Alignment:%x, AddressLength:%x, Minimum:%x,Maximum:%x\n", - io_res->IoDecode, io_res->Alignment, - io_res->AddressLength, io_res->Minimum, - io_res->Maximum); + case ACPI_RESOURCE_TYPE_IO: { + ACPI_RESOURCE_IO *io_res = &res->Data.Io; + + shell_print(sh, "ACPI_RESOURCE_TYPE_IO"); + shell_print(sh, "\tIoDecode: %x", io_res->IoDecode); + shell_print(sh, "\tAlignment: %x", io_res->Alignment); + shell_print(sh, "\tAddressLength: %x", io_res->AddressLength); + shell_print(sh, "\tMinimum: %x", io_res->Minimum); + shell_print(sh, "\tMaximum: %x", io_res->Maximum); break; + } case ACPI_RESOURCE_TYPE_DMA: - shell_print(sh, "ACPI_RESOURCE_TYPE_DMA\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_DMA"); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: - shell_print(sh, "ACPI_RESOURCE_TYPE_START_DEPENDENT\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_START_DEPENDENT"); break; case ACPI_RESOURCE_TYPE_END_DEPENDENT: - shell_print(sh, "ACPI_RESOURCE_TYPE_END_DEPENDENT\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_END_DEPENDENT"); break; case ACPI_RESOURCE_TYPE_FIXED_IO: - shell_print(sh, "ACPI_RESOURCE_TYPE_FIXED_IO\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_FIXED_IO"); break; case ACPI_RESOURCE_TYPE_VENDOR: - shell_print(sh, "ACPI_RESOURCE_TYPE_VENDOR\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_VENDOR"); break; case ACPI_RESOURCE_TYPE_MEMORY24: - shell_print(sh, "ACPI_RESOURCE_TYPE_MEMORY24\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_MEMORY24"); break; - case ACPI_RESOURCE_TYPE_MEMORY32: - ACPI_RESOURCE_MEMORY32 * mem_res = &res->Data.Memory32; + case ACPI_RESOURCE_TYPE_MEMORY32: { + ACPI_RESOURCE_MEMORY32 *mem_res = &res->Data.Memory32; - shell_print(sh, "\nACPI_RESOURCE_TYPE_MEMORY32\n\n"); - shell_print(sh, "Minimum:%x, Maximum:%x\n", - mem_res->Minimum, mem_res->Maximum); + shell_print(sh, "ACPI_RESOURCE_TYPE_MEMORY32"); + shell_print(sh, "\tMinimum: %x", mem_res->Minimum); + shell_print(sh, "\tMaximum: %x", mem_res->Maximum); break; - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - ACPI_RESOURCE_FIXED_MEMORY32 * fix_mem_res = &res->Data.FixedMemory32; + } + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: { + ACPI_RESOURCE_FIXED_MEMORY32 *fix_mem_res = &res->Data.FixedMemory32; - shell_print(sh, "\nACPI_RESOURCE_TYPE_FIXED_MEMORY32\n\n"); - shell_print(sh, "Address:%x\n", fix_mem_res->Address); + shell_print(sh, "ACPI_RESOURCE_TYPE_FIXED_MEMORY32"); + shell_print(sh, "\tAddress: %x", fix_mem_res->Address); break; + } case ACPI_RESOURCE_TYPE_ADDRESS16: - shell_print(sh, "ACPI_RESOURCE_TYPE_ADDRESS16\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_ADDRESS16"); break; - case ACPI_RESOURCE_TYPE_ADDRESS32: - ACPI_RESOURCE_ADDRESS32 * add_res = &res->Data.Address32; + case ACPI_RESOURCE_TYPE_ADDRESS32: { + ACPI_RESOURCE_ADDRESS32 *add_res = &res->Data.Address32; - shell_print(sh, "\nACPI_RESOURCE_TYPE_ADDRESS32\n\n"); - shell_print(sh, "Minimum:%x, Maximum:%x\n", add_res->Address.Minimum, - add_res->Address.Maximum); + shell_print(sh, "ACPI_RESOURCE_TYPE_ADDRESS32"); + shell_print(sh, "\tMinimum: %x", add_res->Address.Minimum); + shell_print(sh, "\tMaximum: %x", add_res->Address.Maximum); break; - case ACPI_RESOURCE_TYPE_ADDRESS64: - ACPI_RESOURCE_ADDRESS64 * add_res64 = &res->Data.Address64; + } + case ACPI_RESOURCE_TYPE_ADDRESS64: { + ACPI_RESOURCE_ADDRESS64 *add_res64 = &res->Data.Address64; - shell_print(sh, "\nACPI_RESOURCE_TYPE_ADDRESS64\n\n"); - shell_print(sh, - "Minimum:%llx, Maximum:%llx\n", add_res64->Address.Minimum, - add_res64->Address.Maximum); + shell_print(sh, "ACPI_RESOURCE_TYPE_ADDRESS64"); + shell_print(sh, "\tMinimum: %llx", add_res64->Address.Minimum); + shell_print(sh, "\tMaximum: %llx", add_res64->Address.Maximum); break; + } case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: - shell_print(sh, "ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64"); break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - shell_print(sh, "ACPI_RESOURCE_TYPE_EXTENDED_IRQ\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_EXTENDED_IRQ"); break; case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: - shell_print(sh, "ACPI_RESOURCE_TYPE_GENERIC_REGISTER\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_GENERIC_REGISTER"); break; case ACPI_RESOURCE_TYPE_GPIO: - shell_print(sh, "ACPI_RESOURCE_TYPE_GPIO\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_GPIO"); break; case ACPI_RESOURCE_TYPE_FIXED_DMA: - shell_print(sh, "ACPI_RESOURCE_TYPE_FIXED_DMA\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_FIXED_DMA"); break; case ACPI_RESOURCE_TYPE_SERIAL_BUS: - shell_print(sh, "ACPI_RESOURCE_TYPE_SERIAL_BUS\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_SERIAL_BUS"); break; case ACPI_RESOURCE_TYPE_PIN_FUNCTION: - shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_FUNCTION\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_FUNCTION"); break; case ACPI_RESOURCE_TYPE_PIN_CONFIG: - shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_CONFIG\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_CONFIG"); break; case ACPI_RESOURCE_TYPE_PIN_GROUP: - shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_GROUP\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_GROUP"); break; case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION: - shell_print(sh, - "ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION"); break; case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG: - shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG\n\n"); + shell_print(sh, "ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG"); break; default: + shell_error(sh, "Unknown resource type %d", res->Type); } res = ACPI_NEXT_RESOURCE(res); @@ -145,13 +148,13 @@ static int dump_dev_crs(const struct shell *sh, size_t argc, char **argv) ACPI_RESOURCE *res_lst; if (argc < 2) { - shell_error(sh, "invalid arugment\n"); + shell_error(sh, "invalid arugment"); return -EINVAL; } status = acpi_current_resource_get(argv[1], &res_lst); if (status) { - shell_error(sh, "Error on ACPI _CRS method: %d\n", status); + shell_error(sh, "Error on ACPI _CRS method: %d", status); return status; } @@ -168,13 +171,13 @@ static int dump_dev_prs(const struct shell *sh, size_t argc, char **argv) ACPI_RESOURCE *res_lst; if (argc < 2) { - shell_error(sh, "invalid arugment\n"); + shell_error(sh, "invalid arugment"); return -EINVAL; } status = acpi_possible_resource_get(argv[1], &res_lst); if (status) { - shell_error(sh, "Error in on ACPI _PRS method: %d\n", status); + shell_error(sh, "Error in on ACPI _PRS method: %d", status); return status; } @@ -191,7 +194,7 @@ static int dump_prt(const struct shell *sh, size_t argc, char **argv) ACPI_PCI_ROUTING_TABLE *prt; if (argc < 2) { - shell_error(sh, "invalid arugment\n"); + shell_error(sh, "invalid arugment"); return -EINVAL; } @@ -203,10 +206,9 @@ static int dump_prt(const struct shell *sh, size_t argc, char **argv) prt = irq_prt_table; for (cnt = 0; prt->Length; cnt++) { - shell_print(sh, "[%02X] PCI IRQ Routing Table Package\n", cnt); - shell_print(sh, "DevNum: %lld Pin:%d IRQ: %d\n", - (prt->Address >> 16) & 0xFFFF, prt->Pin, - prt->SourceIndex); + shell_print(sh, "[%02X] PCI IRQ Routing Table Package", cnt); + shell_print(sh, "\tDevNum: %lld Pin: %d IRQ: %d", + (prt->Address >> 16) & 0xFFFF, prt->Pin, prt->SourceIndex); prt = ACPI_ADD_PTR(ACPI_PCI_ROUTING_TABLE, prt, prt->Length); } @@ -225,10 +227,11 @@ static int enum_dev(const struct shell *sh, size_t argc, char **argv) dev = acpi_device_get(argv[1], 0); if (!dev || !dev->res_lst) { - shell_error(sh, "acpi get device failed for HID: %s\n", argv[1]); + shell_error(sh, "acpi get device failed for HID: %s", argv[1]); return -EIO; } - shell_print(sh, "\nName:%s\n", dev->path ? dev->path : "Non"); + + shell_print(sh, "Name: %s", dev->path ? dev->path : "None"); dump_dev_res(sh, dev->res_lst); return 0; @@ -242,17 +245,17 @@ static int read_table(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } - shell_print(sh, "ACPI Table Name: %s\n", argv[1]); - table = acpi_table_get(argv[1], 0); if (!table) { - shell_error(sh, "ACPI get table failed\n"); + shell_error(sh, "ACPI get table %s failed", argv[1]); return -EIO; } - shell_print(sh, "ACPI Table Info:\n"); - shell_print(sh, "Signature: %4s Table Length:%d Revision:%d OemId:%s\n", - table->Signature, table->Length, table->Revision, table->OemId); + shell_print(sh, "ACPI Table %s:", argv[1]); + shell_print(sh, "\tSignature: %4s", table->Signature); + shell_print(sh, "\tTable Length: %d", table->Length); + shell_print(sh, "\tRevision: %d", table->Revision); + shell_print(sh, "\tOemId: %s", table->OemId); return 0; } From 31cafc30492b5e6deaa0bae7a4b77c485afa7bcf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 4 Nov 2023 14:36:23 +0200 Subject: [PATCH 3108/4498] acpi: Remove redundant newline characters from logs The log functions themselves automatically add newline characters, so no need to do it when calling the log macros. Signed-off-by: Johan Hedberg --- lib/acpi/acpi.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 7a9eaee02c1..aaec47894ad 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -37,7 +37,7 @@ static int check_init_status(void) if (ACPI_SUCCESS(acpi.status)) { return 0; } else { - LOG_ERR("ACPI init was not success\n"); + LOG_ERR("ACPI init was not success"); return -EIO; } } @@ -203,7 +203,7 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev ACPI_STATUS status; ACPI_DEVICE_INFO *dev_info; - LOG_DBG("%s %p\n", __func__, node); + LOG_DBG("%s %p", __func__, node); /* get device info such as HID, Class ID etc. */ status = AcpiGetObjectInfo(obj_handle, &dev_info); @@ -222,10 +222,10 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev path_name = AcpiNsGetNormalizedPathname(node, TRUE); if (!path_name) { - LOG_ERR("No memory for path_name\n"); + LOG_ERR("No memory for path_name"); goto exit; } else { - LOG_DBG("Device path: %s\n", path_name); + LOG_DBG("Device path: %s", path_name); child_dev->path = path_name; } @@ -440,7 +440,7 @@ ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type) { do { if (!res->Length) { - LOG_DBG("Error: zero length found!\n"); + LOG_DBG("Error: zero length found!"); break; } else if (res->Type == res_type) { break; @@ -500,7 +500,7 @@ int acpi_device_type_get(ACPI_RESOURCE *res) do { if (!res->Length) { - LOG_ERR("Error: zero length found!\n"); + LOG_ERR("Error: zero length found!"); break; } type = acpi_res_type(res); @@ -527,7 +527,7 @@ struct acpi_dev *acpi_device_get(char *hid, int inst) do { child_dev = &acpi.child_dev[i]; if (!child_dev->path) { - LOG_DBG("NULL device path found\n"); + LOG_DBG("NULL device path found"); continue; } @@ -634,7 +634,7 @@ int acpi_dmar_entry_get(enum AcpiDmarType type, struct acpi_subtable_header **ta struct acpi_dmar_header *subtable; if (!dmar) { - LOG_ERR("error on get DMAR table\n"); + LOG_ERR("error on get DMAR table"); return -EIO; } @@ -666,7 +666,7 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d ret = acpi_dmar_entry_get(ACPI_DMAR_TYPE_HARDWARE_UNIT, (struct acpi_subtable_header **)&drdh); if (ret) { - LOG_ERR("Error on retrieve DMAR table\n"); + LOG_ERR("Error on retrieve DMAR table"); return ret; } @@ -690,7 +690,7 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d while (num_path--) { if (i >= max_inst) { - LOG_ERR("DHRD not enough buffer size\n"); + LOG_ERR("DHRD not enough buffer size"); return -ENOBUFS; } dmar_id[i].bits.bus = subtable->Bus; @@ -711,7 +711,7 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d *num_inst = i; if (!i) { - LOG_ERR("Error on retrieve DRHD Info\n"); + LOG_ERR("Error on retrieve DRHD Info"); return -ENODEV; } From 584a1cf0fc32a4291e652a26fb7b4de85a638a38 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 5 Nov 2023 18:08:15 +0200 Subject: [PATCH 3109/4498] acpi: Use ACPICA typedef names when available For most types, ACPICA provides both a struct name as well as a typedef. The struct names follow the exact same naming style as Zephyr's ACPI API, which makes it impossible to distinguish which type is defined by Zephyr and which comes from ACPICA. It's therefore better to use the typedefs, since they follow a distinct style compared to the Zephyr API. Signed-off-by: Johan Hedberg --- include/zephyr/acpi/acpi.h | 15 +++++++-------- lib/acpi/acpi.c | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/include/zephyr/acpi/acpi.h b/include/zephyr/acpi/acpi.h index 92a8503258b..589cd7d6c4d 100644 --- a/include/zephyr/acpi/acpi.h +++ b/include/zephyr/acpi/acpi.h @@ -35,9 +35,9 @@ union acpi_dmar_id { }; struct acpi_mcfg { - struct acpi_table_header header; + ACPI_TABLE_HEADER header; uint64_t _reserved; - struct acpi_mcfg_allocation pci_segs[]; + ACPI_MCFG_ALLOCATION pci_segs[]; } __packed; /** @@ -149,7 +149,7 @@ void *acpi_table_get(char *signature, int inst); * @param num_inst number of instance for the requested table * @return return 0 on success or error code */ -int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num_inst); +int acpi_madt_entry_get(int type, ACPI_SUBTABLE_HEADER **tables, int *num_inst); /** * @brief retrieve DMA remapping structure for the given type. @@ -158,8 +158,7 @@ int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num * @param tables pointer to the dmar id structure * @return return 0 on success or error code */ -int acpi_dmar_entry_get(enum AcpiDmarType type, - struct acpi_subtable_header **tables); +int acpi_dmar_entry_get(enum AcpiDmarType type, ACPI_SUBTABLE_HEADER **tables); /** * @brief retrieve acpi DRHD info for the given scope. @@ -171,8 +170,8 @@ int acpi_dmar_entry_get(enum AcpiDmarType type, * @param max_inst maximum number of entry for the given dmar_id buffer * @return return 0 on success or error code */ -int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *dev_scope, - union acpi_dmar_id *dmar_id, int *num_inst, int max_inst); +int acpi_drhd_get(enum AcpiDmarScopeType scope, ACPI_DMAR_DEVICE_SCOPE *dev_scope, + union acpi_dmar_id *dmar_id, int *num_inst, int max_inst); /** * @brief Retrieve the 'n'th enabled local apic info. @@ -180,5 +179,5 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d * @param cpu_num the cpu number * @return local apic info on success or NULL otherwise */ -struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num); +ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num); #endif diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index aaec47894ad..7d84b4e5d29 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -578,7 +578,7 @@ void *acpi_table_get(char *signature, int inst) return (void *)table; } -static uint32_t acpi_get_subtable_entry_num(int type, struct acpi_subtable_header *subtable, +static uint32_t acpi_get_subtable_entry_num(int type, ACPI_SUBTABLE_HEADER *subtable, uintptr_t offset, uintptr_t base, uint32_t madt_len) { uint32_t subtable_cnt = 0; @@ -598,12 +598,12 @@ static uint32_t acpi_get_subtable_entry_num(int type, struct acpi_subtable_heade return subtable_cnt; } -int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num_inst) +int acpi_madt_entry_get(int type, ACPI_SUBTABLE_HEADER **tables, int *num_inst) { - struct acpi_table_header *madt = acpi_table_get("APIC", 0); + ACPI_TABLE_HEADER *madt = acpi_table_get("APIC", 0); uintptr_t base = POINTER_TO_UINT(madt); uintptr_t offset = sizeof(ACPI_TABLE_MADT); - struct acpi_subtable_header *subtable; + ACPI_SUBTABLE_HEADER *subtable; if (!madt) { return -EIO; @@ -626,12 +626,12 @@ int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num return -ENODEV; } -int acpi_dmar_entry_get(enum AcpiDmarType type, struct acpi_subtable_header **tables) +int acpi_dmar_entry_get(enum AcpiDmarType type, ACPI_SUBTABLE_HEADER **tables) { struct acpi_table_dmar *dmar = acpi_table_get("DMAR", 0); uintptr_t base = POINTER_TO_UINT(dmar); uintptr_t offset = sizeof(ACPI_TABLE_DMAR); - struct acpi_dmar_header *subtable; + ACPI_DMAR_HEADER *subtable; if (!dmar) { LOG_ERR("error on get DMAR table"); @@ -651,20 +651,20 @@ int acpi_dmar_entry_get(enum AcpiDmarType type, struct acpi_subtable_header **ta return -ENODEV; } -int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *dev_scope, - union acpi_dmar_id *dmar_id, int *num_inst, int max_inst) +int acpi_drhd_get(enum AcpiDmarScopeType scope, ACPI_DMAR_DEVICE_SCOPE *dev_scope, + union acpi_dmar_id *dmar_id, int *num_inst, int max_inst) { uintptr_t offset = sizeof(ACPI_DMAR_HARDWARE_UNIT); uint32_t i = 0; - struct acpi_dmar_header *drdh; - struct acpi_dmar_device_scope *subtable; - struct acpi_dmar_pci_path *dev_path; + ACPI_DMAR_HEADER *drdh; + ACPI_DMAR_DEVICE_SCOPE *subtable; + ACPI_DMAR_PCI_PATH *dev_path; int ret; uintptr_t base; int scope_size; ret = acpi_dmar_entry_get(ACPI_DMAR_TYPE_HARDWARE_UNIT, - (struct acpi_subtable_header **)&drdh); + (ACPI_SUBTABLE_HEADER **)&drdh); if (ret) { LOG_ERR("Error on retrieve DMAR table"); return ret; @@ -724,9 +724,9 @@ int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *d #define ACPI_CPU_FLAGS_ENABLED 0x01u -struct acpi_madt_local_apic *acpi_local_apic_get(int cpu_num) +ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num) { - struct acpi_madt_local_apic *lapic; + ACPI_MADT_LOCAL_APIC *lapic; int cpu_cnt; int idx; From 6e8a1f5859c85e62c6325d3ecb1cf2c61a42a2bf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 5 Nov 2023 21:03:17 +0200 Subject: [PATCH 3110/4498] acpi: shell: Fix specifying string precision The ACPI table signature is not null terminated, so a precision needs to be provided in format strings. There was an attempt to do this, but it was done in an incorrect way, which resulted in garbage characters getting printed. Signed-off-by: Johan Hedberg --- lib/acpi/acpi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acpi/acpi_shell.c b/lib/acpi/acpi_shell.c index ef940e478b3..e2db3aaa30e 100644 --- a/lib/acpi/acpi_shell.c +++ b/lib/acpi/acpi_shell.c @@ -252,7 +252,7 @@ static int read_table(const struct shell *sh, size_t argc, char **argv) } shell_print(sh, "ACPI Table %s:", argv[1]); - shell_print(sh, "\tSignature: %4s", table->Signature); + shell_print(sh, "\tSignature: %.4s", table->Signature); shell_print(sh, "\tTable Length: %d", table->Length); shell_print(sh, "\tRevision: %d", table->Revision); shell_print(sh, "\tOemId: %s", table->OemId); From f67ecc31aa72bce582cd66b48c87e73f01f41e86 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 6 Nov 2023 10:17:46 +0200 Subject: [PATCH 3111/4498] arch: x86: Use ACPICA typdef instead of struct name Use ACPI_MADT_LOCAL_APIC instead of struct acpi_madt_local_apic. In the same go, switch to IF_ENABLED from ifdef - slightly more readable, and this keeps some static analyzers happy (e.g. upstream Compliance check). Signed-off-by: Johan Hedberg --- arch/x86/core/intel64/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index 6afcec2a017..a522e87de3a 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -144,14 +144,14 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, uint8_t vector = ((unsigned long) x86_ap_start) >> 12; uint8_t apic_id; -#ifdef CONFIG_ACPI - struct acpi_madt_local_apic *lapic = acpi_local_apic_get(cpu_num); - - if (lapic != NULL) { - /* We update the apic_id, __start will need it. */ - x86_cpu_loapics[cpu_num] = lapic->Id; - } -#endif + IF_ENABLED(CONFIG_ACPI, ({ + ACPI_MADT_LOCAL_APIC *lapic = acpi_local_apic_get(cpu_num); + + if (lapic != NULL) { + /* We update the apic_id, __start will need it. */ + x86_cpu_loapics[cpu_num] = lapic->Id; + } + })); apic_id = x86_cpu_loapics[cpu_num]; From 01dc3c48e6652d22ad0c94b922c7e617f3f418cd Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 12 Oct 2023 17:43:51 +0200 Subject: [PATCH 3112/4498] drivers/sensor: lis2dh: add INT1/INT2 gpio interrupt config in DT Add INT1/INT2 gpio interrupt configuration at Device Tree level. Two new properties: - int1-gpio-config - int2-gpio-config Possible values: 0 = GPIO_INT_EDGE 1 = GPIO_INT_EDGE_RISING 2 = GPIO_INT_EDGE_FALLING 3 = GPIO_INT_LEVEL_HIGH 4 = GPIO_INT_LEVEL_LOW Fixes #63736 Signed-off-by: Armando Visconti --- drivers/sensor/lis2dh/lis2dh.c | 4 ++- drivers/sensor/lis2dh/lis2dh.h | 2 ++ drivers/sensor/lis2dh/lis2dh_trigger.c | 12 +++++-- dts/bindings/sensor/st,lis2dh-common.yaml | 42 +++++++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/lis2dh/lis2dh.c b/drivers/sensor/lis2dh/lis2dh.c index 3aaa8ab83fe..a12bb0e097d 100644 --- a/drivers/sensor/lis2dh/lis2dh.c +++ b/drivers/sensor/lis2dh/lis2dh.c @@ -520,7 +520,9 @@ static int lis2dh_pm_action(const struct device *dev, .gpio_int = \ COND_CODE_1(ANYM_ON_INT1(inst), \ (GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 0)), \ - (GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 1))), + (GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 1))), \ + .int1_mode = DT_INST_PROP(inst, int1_gpio_config), \ + .int2_mode = DT_INST_PROP(inst, int2_gpio_config), #else #define LIS2DH_CFG_INT(inst) #endif /* CONFIG_LIS2DH_TRIGGER */ diff --git a/drivers/sensor/lis2dh/lis2dh.h b/drivers/sensor/lis2dh/lis2dh.h index 142b1330d78..f746e983e28 100644 --- a/drivers/sensor/lis2dh/lis2dh.h +++ b/drivers/sensor/lis2dh/lis2dh.h @@ -219,6 +219,8 @@ struct lis2dh_config { #ifdef CONFIG_LIS2DH_TRIGGER const struct gpio_dt_spec gpio_drdy; const struct gpio_dt_spec gpio_int; + const uint8_t int1_mode; + const uint8_t int2_mode; #endif /* CONFIG_LIS2DH_TRIGGER */ struct { bool is_lsm303agr_dev : 1; diff --git a/drivers/sensor/lis2dh/lis2dh_trigger.c b/drivers/sensor/lis2dh/lis2dh_trigger.c index d0d3ad38dab..3c075b2a0e8 100644 --- a/drivers/sensor/lis2dh/lis2dh_trigger.c +++ b/drivers/sensor/lis2dh/lis2dh_trigger.c @@ -18,6 +18,14 @@ LOG_MODULE_DECLARE(lis2dh, CONFIG_SENSOR_LOG_LEVEL); #include "lis2dh.h" +static const gpio_flags_t gpio_int_cfg[5] = { + GPIO_INT_EDGE, + GPIO_INT_EDGE_RISING, + GPIO_INT_EDGE_FALLING, + GPIO_INT_LEVEL_HIGH, + GPIO_INT_LEVEL_LOW, + }; + static inline void setup_int1(const struct device *dev, bool enable) { @@ -25,7 +33,7 @@ static inline void setup_int1(const struct device *dev, gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, enable - ? GPIO_INT_LEVEL_ACTIVE + ? gpio_int_cfg[cfg->int1_mode] : GPIO_INT_DISABLE); } @@ -123,7 +131,7 @@ static inline void setup_int2(const struct device *dev, gpio_pin_interrupt_configure_dt(&cfg->gpio_int, enable - ? GPIO_INT_LEVEL_ACTIVE + ? gpio_int_cfg[cfg->int2_mode] : GPIO_INT_DISABLE); } diff --git a/dts/bindings/sensor/st,lis2dh-common.yaml b/dts/bindings/sensor/st,lis2dh-common.yaml index d86960e26d3..7ba07fc4b12 100644 --- a/dts/bindings/sensor/st,lis2dh-common.yaml +++ b/dts/bindings/sensor/st,lis2dh-common.yaml @@ -10,6 +10,48 @@ properties: The INT1 and (optional) INT2 signal connections. These signals are active-high as produced by the sensor. + int1-gpio-config: + type: int + default: 0 + description: | + Select the interrupt configuration for INT1 gpio. + + 0 = GPIO_INT_EDGE + 1 = GPIO_INT_EDGE_RISING + 2 = GPIO_INT_EDGE_FALLING + 3 = GPIO_INT_LEVEL_HIGH + 4 = GPIO_INT_LEVEL_LOW + + The default of 0 is the most common situation to avoid multiple interrupts + to be triggered by same event. + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + + int2-gpio-config: + type: int + default: 0 + description: | + Select the interrupt configuration for INT2 gpio. + + 0 = GPIO_INT_EDGE + 1 = GPIO_INT_EDGE_RISING + 2 = GPIO_INT_EDGE_FALLING + 3 = GPIO_INT_LEVEL_HIGH + 4 = GPIO_INT_LEVEL_LOW + + The default of 0 is the most common situation to avoid multiple interrupts + to be triggered by same event. + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + disconnect-sdo-sa0-pull-up: type: boolean description: | From c4628a795f3f6a70f066e95b03fd124a9a0c3dd9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 13:46:05 +0100 Subject: [PATCH 3113/4498] Bluetooth samples: broadcast audio sink: Add sysbuild support So that for both the simulated nrf5340 and real HW nrf5340dk we build both network and application core images. Signed-off-by: Alberto Escolar Piedras --- .../broadcast_audio_sink/Kconfig.sysbuild | 10 +++++ .../broadcast_audio_sink/sample.yaml | 1 + .../broadcast_audio_sink/sysbuild.cmake | 44 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild create mode 100644 samples/bluetooth/broadcast_audio_sink/sysbuild.cmake diff --git a/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild new file mode 100644 index 00000000000..37a6b66c7f4 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/bluetooth/broadcast_audio_sink/sample.yaml b/samples/bluetooth/broadcast_audio_sink/sample.yaml index a423dbcde18..17ba1794651 100644 --- a/samples/bluetooth/broadcast_audio_sink/sample.yaml +++ b/samples/bluetooth/broadcast_audio_sink/sample.yaml @@ -12,6 +12,7 @@ tests: - qemu_x86 - nrf5340dk_nrf5340_cpuapp tags: bluetooth + sysbuild: true sample.bluetooth.broadcast_audio_sink.bt_ll_sw_split: harness: bluetooth platform_allow: diff --git a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake new file mode 100644 index 00000000000..c150913cc55 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + + if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + endif() +endif() + +if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From 631a6a765adba1b761e76add3bfa73e98eb17585 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 13:46:43 +0100 Subject: [PATCH 3114/4498] Bluetooth samples: broadcast audio source: Add sysbuild support So that for both the simulated nrf5340 and real HW nrf5340dk we build both network and application core images. Signed-off-by: Alberto Escolar Piedras --- .../broadcast_audio_source/Kconfig.sysbuild | 10 +++++ .../broadcast_audio_source/sample.yaml | 1 + .../broadcast_audio_source/sysbuild.cmake | 44 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild create mode 100644 samples/bluetooth/broadcast_audio_source/sysbuild.cmake diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild new file mode 100644 index 00000000000..37a6b66c7f4 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" + default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/samples/bluetooth/broadcast_audio_source/sample.yaml b/samples/bluetooth/broadcast_audio_source/sample.yaml index 1c3904d8c82..a8f99290ce3 100644 --- a/samples/bluetooth/broadcast_audio_source/sample.yaml +++ b/samples/bluetooth/broadcast_audio_source/sample.yaml @@ -12,6 +12,7 @@ tests: - qemu_x86 - nrf5340dk_nrf5340_cpuapp tags: bluetooth + sysbuild: true sample.bluetooth.broadcast_audio_source.bt_ll_sw_split: harness: bluetooth platform_allow: diff --git a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake new file mode 100644 index 00000000000..c150913cc55 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + + if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + endif() +endif() + +if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} + ) +endif() From c9f09b1d66baff4eeaa61934ff1d4a160ffc403c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 16:18:19 +0100 Subject: [PATCH 3115/4498] Bluetooth samples: broadcast audio: Add more test Kconfig options Instead of handling some of the configuation thru board overlays let's handle it thru the sample Kconfig file, which reduces the amount of duplicate lines. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/broadcast_audio_sink/Kconfig | 8 ++++++++ .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 5 ----- samples/bluetooth/broadcast_audio_sink/prj.conf | 3 +++ samples/bluetooth/broadcast_audio_source/Kconfig | 9 +++++++++ .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 4 ---- samples/bluetooth/broadcast_audio_source/prj.conf | 2 ++ 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/Kconfig b/samples/bluetooth/broadcast_audio_sink/Kconfig index 189c9f210a2..b70a42e2d99 100644 --- a/samples/bluetooth/broadcast_audio_sink/Kconfig +++ b/samples/bluetooth/broadcast_audio_sink/Kconfig @@ -35,4 +35,12 @@ config TARGET_BROADCAST_NAME Name of target broadcast device. If not empty string, sink device will only listen to the specified broadcast source. Not case sensitive. +config ENABLE_LC3 + bool "Enable the LC3 codec" + # By default let's enable it in the platforms we know are capable of supporting it + default y + depends on (ARCH_POSIX || SOC_NRF5340_CPUAPP) + select LIBLC3 + select FPU + source "Kconfig.zephyr" diff --git a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 29f7e03dcea..8ab7a163fb6 100644 --- a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,8 +1,3 @@ -# For LC3 the following configs are needed -CONFIG_FPU=y -CONFIG_LIBLC3=y # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# Enable encryption. -CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_sink/prj.conf b/samples/bluetooth/broadcast_audio_sink/prj.conf index 29a479933d6..359b74a7cf1 100644 --- a/samples/bluetooth/broadcast_audio_sink/prj.conf +++ b/samples/bluetooth/broadcast_audio_sink/prj.conf @@ -14,3 +14,6 @@ CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_DEVICE_NAME="Broadcast Audio Sink" + +# Enable encryption. +CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig b/samples/bluetooth/broadcast_audio_source/Kconfig index 91cca49cc07..cc3e714ded7 100644 --- a/samples/bluetooth/broadcast_audio_source/Kconfig +++ b/samples/bluetooth/broadcast_audio_source/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2023 Demant A/S +# Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 mainmenu "Bluetooth: Broadcast Audio Source" @@ -19,4 +20,12 @@ config BAP_BROADCAST_24_2_1 endchoice +config ENABLE_LC3 + bool "Enable the LC3 codec" + # By default let's enable it in the platforms we know are capable of supporting it + default y + depends on (ARCH_POSIX || SOC_NRF5340_CPUAPP) + select LIBLC3 + select FPU + source "Kconfig.zephyr" diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index aae6000e5ab..f274c4a460c 100644 --- a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,10 +1,6 @@ -# For LC3 the following configs are needed -CONFIG_FPU=y -CONFIG_LIBLC3=y # When Host is fixed, CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE can inherit the CONFIG_BT_ISO_TX_MTU value. CONFIG_BT_ISO_TX_MTU=40 # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 -CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/prj.conf b/samples/bluetooth/broadcast_audio_source/prj.conf index 89210995535..576af17d8e1 100644 --- a/samples/bluetooth/broadcast_audio_source/prj.conf +++ b/samples/bluetooth/broadcast_audio_source/prj.conf @@ -11,3 +11,5 @@ CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2 CONFIG_BT_ISO_TX_BUF_COUNT=4 CONFIG_BT_DEVICE_NAME="Broadcast Audio Source" + +CONFIG_BT_TINYCRYPT_ECC=y From 1aa6f85252b3a909b9ecf91ddc9378436fdcd86c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 2 Nov 2023 17:07:26 +0100 Subject: [PATCH 3116/4498] Bluetooth samples: broadcast audio sink: Fix overlay for nrf52 Fix controller configuration overlay used when building the controller (for nrf52 targets), so the sample can connect to the source and get audio through. Signed-off-by: Alberto Escolar Piedras --- .../broadcast_audio_sink/overlay-bt_ll_sw_split.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf b/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf index bc0ba2c6cdd..e336dae38e1 100644 --- a/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf +++ b/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf @@ -10,3 +10,7 @@ CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX=155 # Supports the highest advertising data that is set in a single HCI command in # Zephyr Bluetooth Controller CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191 + +# Number of supported streams +CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=2 +CONFIG_BT_CTLR_ISOAL_SINKS=2 From c929ac5c23cc26e8c4d9cba0e6e104f4d14f6759 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 14:01:36 +0100 Subject: [PATCH 3117/4498] Bluetooth samples: broadcast audio: Add support for more nrf targets Add support for the simulated nrf5340 and nrf52 in these samples, as well as explicit overlays for the nrf5340dk. Signed-off-by: Alberto Escolar Piedras --- .../broadcast_audio_sink/boards/nrf5340dk_nrf5340_cpuapp.conf | 3 +++ samples/bluetooth/broadcast_audio_sink/prj.conf | 1 - samples/bluetooth/broadcast_audio_sink/sample.yaml | 1 + .../bluetooth/broadcast_audio_source/boards/nrf52_bsim.conf | 1 + .../boards/nrf5340_audio_dk_nrf5340_cpuapp.conf | 2 -- .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 1 + .../boards/nrf5340dk_nrf5340_cpuapp.conf | 4 ++++ samples/bluetooth/broadcast_audio_source/prj.conf | 2 ++ samples/bluetooth/broadcast_audio_source/sample.yaml | 1 + 9 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 samples/bluetooth/broadcast_audio_sink/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 samples/bluetooth/broadcast_audio_source/boards/nrf52_bsim.conf create mode 100644 samples/bluetooth/broadcast_audio_source/boards/nrf5340bsim_nrf5340_cpuapp.conf create mode 100644 samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf diff --git a/samples/bluetooth/broadcast_audio_sink/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..8ab7a163fb6 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_sink/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,3 @@ +# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence +# inctease stack size for that thread. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_sink/prj.conf b/samples/bluetooth/broadcast_audio_sink/prj.conf index 359b74a7cf1..c8adced28ce 100644 --- a/samples/bluetooth/broadcast_audio_sink/prj.conf +++ b/samples/bluetooth/broadcast_audio_sink/prj.conf @@ -15,5 +15,4 @@ CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_DEVICE_NAME="Broadcast Audio Sink" -# Enable encryption. CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_sink/sample.yaml b/samples/bluetooth/broadcast_audio_sink/sample.yaml index 17ba1794651..e81b86de3e0 100644 --- a/samples/bluetooth/broadcast_audio_sink/sample.yaml +++ b/samples/bluetooth/broadcast_audio_sink/sample.yaml @@ -8,6 +8,7 @@ tests: - qemu_cortex_m3 - qemu_x86 - nrf5340dk_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpuapp integration_platforms: - qemu_x86 - nrf5340dk_nrf5340_cpuapp diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf52_bsim.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf52_bsim.conf new file mode 100644 index 00000000000..5df721fba26 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf52_bsim.conf @@ -0,0 +1 @@ +CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f274c4a460c..8d28a7031d2 100644 --- a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,5 +1,3 @@ -# When Host is fixed, CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE can inherit the CONFIG_BT_ISO_TX_MTU value. -CONFIG_BT_ISO_TX_MTU=40 # The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence # inctease stack size for that thread. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..5df721fba26 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1 @@ +CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..8d28a7031d2 --- /dev/null +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence +# inctease stack size for that thread. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_source/prj.conf b/samples/bluetooth/broadcast_audio_source/prj.conf index 576af17d8e1..2e0fcb778de 100644 --- a/samples/bluetooth/broadcast_audio_source/prj.conf +++ b/samples/bluetooth/broadcast_audio_source/prj.conf @@ -10,6 +10,8 @@ CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2 CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2 CONFIG_BT_ISO_TX_BUF_COUNT=4 +CONFIG_BT_ISO_TX_MTU=60 + CONFIG_BT_DEVICE_NAME="Broadcast Audio Source" CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/sample.yaml b/samples/bluetooth/broadcast_audio_source/sample.yaml index a8f99290ce3..1c27238c35f 100644 --- a/samples/bluetooth/broadcast_audio_source/sample.yaml +++ b/samples/bluetooth/broadcast_audio_source/sample.yaml @@ -8,6 +8,7 @@ tests: - qemu_cortex_m3 - qemu_x86 - nrf5340dk_nrf5340_cpuapp + - nrf5340bsim_nrf5340_cpuapp integration_platforms: - qemu_x86 - nrf5340dk_nrf5340_cpuapp From 11fddf4a411cf61273b82ee518399565f3028cc8 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 14:20:01 +0100 Subject: [PATCH 3118/4498] Bluetooth samples: broadcast audio: Improve documentation With examples of how to build for several boards. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/broadcast_audio_sink/README.rst | 72 ++++++++++++++++--- .../broadcast_audio_source/README.rst | 66 ++++++++++++++--- 2 files changed, 119 insertions(+), 19 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/README.rst b/samples/bluetooth/broadcast_audio_sink/README.rst index 42bcc2a2c0a..aca5d18bb94 100644 --- a/samples/bluetooth/broadcast_audio_sink/README.rst +++ b/samples/bluetooth/broadcast_audio_sink/README.rst @@ -1,7 +1,8 @@ -.. _bluetooth_broadcast_audio_sink: +.. zephyr:code-sample:: bluetooth_broadcast_audio_sink + :name: Bluetooth: Broadcast Audio Sink + :relevant-api: bluetooth -Bluetooth: Broadcast Audio Sink -############################### + Bluetooth: Broadcast Audio Sink Overview ******** @@ -10,6 +11,15 @@ Application demonstrating the LE Audio broadcast sink functionality. Starts by scanning for LE Audio broadcast sources and then synchronizes to the first found and listens to it until the source is (potentially) stopped. +This sample can be found under +:zephyr_file:`samples/bluetooth/broadcast_audio_sink` in the Zephyr tree. + +Check the :ref:`bluetooth samples section ` for general information. + +Use `CONFIG_TARGET_BROADCAST_NAME` Kconfig to specify the name (CONFIG_BT_DEVICE_NAME) +of a broadcast source to listen to. With default value (empty string), sink +device will listen to all available broadcast sources. + Requirements ************ @@ -18,13 +28,53 @@ Requirements Building and Running ******************** -This sample can be found under -:zephyr_file:`samples/bluetooth/broadcast_audio_sink` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO -feature support in Zephyr Bluetooth Controller on supported boards. -Use `CONFIG_TARGET_BROADCAST_NAME` Kconfig to specify the name (CONFIG_BT_DEVICE_NAME) -of a broadcast source to listen to. With default value (empty string), sink -device will listen to all available broadcast sources. +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable the required ISO +feature support. + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_sink/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_sink/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + +In that case you can pair this application core image with the +:ref:`hci_ipc sample ` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf5340bsim +------------------------------------ + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_sink/ + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +Note this will produce a Linux executable in `./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf52_bsim +----------------------------------- -See :ref:`bluetooth samples section ` for details. +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_sink/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf diff --git a/samples/bluetooth/broadcast_audio_source/README.rst b/samples/bluetooth/broadcast_audio_source/README.rst index 12fb6c0ca1a..1c36236231b 100644 --- a/samples/bluetooth/broadcast_audio_source/README.rst +++ b/samples/bluetooth/broadcast_audio_source/README.rst @@ -1,7 +1,8 @@ -.. _bluetooth_broadcast_audio_source: +.. zephyr:code-sample:: bluetooth_broadcast_audio_source + :name: Bluetooth: Broadcast Audio Source + :relevant-api: bluetooth -Bluetooth: Broadcast Audio Source -################################# + Bluetooth: Broadcast Audio Source Overview ******** @@ -13,6 +14,11 @@ broadcast audio source endpoint (BASE) and finally the BIGinfo together with The broadcast source will reset every 30 seconds to show the full API. +This sample can be found under +:zephyr_file:`samples/bluetooth/broadcast_audio_source` in the Zephyr tree. + +Check the :ref:`bluetooth samples section ` for general information. + Requirements ************ @@ -21,9 +27,53 @@ Requirements Building and Running ******************** -This sample can be found under -:zephyr_file:`samples/bluetooth/broadcast_audio_source` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO -feature support in Zephyr Bluetooth Controller on supported boards. -See :ref:`bluetooth samples section ` for details. +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable the required ISO +feature support. + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_source/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_source/ + :board: nrf5340dk_nrf5340_cpuapp + :goals: build + +In that case you can pair this application core image with the +:ref:`hci_ipc sample ` +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf5340bsim +------------------------------------ + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_source/ + :board: nrf5340bsim_nrf5340_cpuapp + :goals: build + :west-args: --sysbuild + +Note this will produce a Linux executable in `./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf52_bsim +----------------------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/broadcast_audio_source/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf From b3447ec068bbcffb5386122c162fb4afd74a83d8 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 1 Nov 2023 16:20:13 +0100 Subject: [PATCH 3119/4498] tests bsim: Add simple tests for broadcast audio source/sink samples Add an initial test based on the broadcast audio source/sink samples which runs them together and after waiting for a predefined amount of time, checks how many audio packets has the sink received, and if over a threshold, passes the test. This test can be expanded after to cover more functionality from these samples. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/broadcast_audio_sink/src/main.c | 4 + .../broadcast_audio_sink/CMakeLists.txt | 24 ++++++ .../broadcast_audio_sink/Kconfig | 4 + .../broadcast_audio_sink/Kconfig.sysbuild | 10 +++ .../broadcast_audio_sink/prj.conf | 2 + .../src/broadcast_audio_sink_test.c | 77 +++++++++++++++++++ .../broadcast_audio_sink/src/test_main.c | 14 ++++ .../broadcast_audio_sink/sysbuild.cmake | 13 ++++ .../tests_scripts/broadcast_audio.sh | 29 +++++++ tests/bsim/bluetooth/audio_samples/compile.sh | 16 ++-- 10 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig.sysbuild create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/prj.conf create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/broadcast_audio_sink_test.c create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/test_main.c create mode 100644 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake create mode 100755 tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/tests_scripts/broadcast_audio.sh diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index fa776bf5430..6b519b715f6 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -81,6 +81,8 @@ static uint32_t requested_bis_sync; static uint32_t bis_index_bitfield; static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */ + #if defined(CONFIG_LIBLC3) #include "lc3.h" @@ -182,6 +184,7 @@ static void stream_started_cb(struct bt_bap_stream *stream) printk("Stream %p started\n", stream); + total_rx_iso_packet_count = 0U; sink_stream->recv_cnt = 0U; sink_stream->loss_cnt = 0U; sink_stream->valid_cnt = 0U; @@ -234,6 +237,7 @@ static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_rec #endif /* defined(CONFIG_LIBLC3) */ } + total_rx_iso_packet_count++; sink_stream->recv_cnt++; if ((sink_stream->recv_cnt % 1000U) == 0U) { printk("Stream %p: received %u total ISO packets: Valid %u | Error %u | Loss %u\n", diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/CMakeLists.txt b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/CMakeLists.txt new file mode 100644 index 00000000000..8a2c3e86803 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/CMakeLists.txt @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(broadcast_audio_sink_self_tets) + +set(broadcast_audio_sink_path ${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink) + +target_sources(app PRIVATE + ${broadcast_audio_sink_path}/src/main.c +) + +target_sources(app PRIVATE + src/broadcast_audio_sink_test.c + src/test_main.c +) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig new file mode 100644 index 00000000000..fadad0e4456 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/Kconfig" diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig.sysbuild b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig.sysbuild new file mode 100644 index 00000000000..6ef6bede28d --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/prj.conf b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/prj.conf new file mode 100644 index 00000000000..36e53c8cabe --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/prj.conf @@ -0,0 +1,2 @@ +# Please build using the sample configuration file: +# ${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/broadcast_audio_sink_test.c b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/broadcast_audio_sink_test.c new file mode 100644 index 00000000000..dc23f131125 --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/broadcast_audio_sink_test.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2017-2019 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_types.h" +#include "bs_tracing.h" +#include "bs_utils.h" +#include "time_machine.h" +#include "bstests.h" + +#define WAIT_TIME 10 /* Seconds */ + +#define PASS_THRESHOLD 100 /* Audio packets */ + +extern enum bst_result_t bst_result; + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +static void test_broadcast_sink_sample_init(void) +{ + /* We set an absolute deadline in 30 seconds */ + bst_ticker_set_next_tick_absolute(WAIT_TIME*1e6); + bst_result = In_progress; +} + +static void test_broadcast_sink_sample_tick(bs_time_t HW_device_time) +{ + /* + * If in WAIT_TIME seconds we did not get enough packets through + * we consider the test failed + */ + + extern uint64_t total_rx_iso_packet_count; + + bs_trace_info_time(2, "%"PRIu64" packets received, expected >= %i\n", + total_rx_iso_packet_count, PASS_THRESHOLD); + + if (total_rx_iso_packet_count >= PASS_THRESHOLD) { + PASS("broadcast_sink PASSED\n"); + bs_trace_exit("Done, disconnecting from simulation\n"); + } else { + FAIL("broadcast_sink FAILED (Did not pass after %i seconds)\n", + WAIT_TIME); + } +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "broadcast_audio_sink", + .test_descr = "Test based on the broadcast audio sink sample. " + "It expects to be connected to a compatible broadcast audio source, " + "waits for " STR(WAIT_TIME) " seconds, and checks how " + "many ISO packets have been received correctly", + .test_post_init_f = test_broadcast_sink_sample_init, + .test_tick_f = test_broadcast_sink_sample_tick, + }, + BSTEST_END_MARKER +}; + +struct bst_test_list *test_broadcast_sink_test_install(struct bst_test_list *tests) +{ + tests = bst_add_tests(tests, test_sample); + return tests; +} diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/test_main.c b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/test_main.c new file mode 100644 index 00000000000..cd9df72aaae --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/src/test_main.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" + +extern struct bst_test_list *test_broadcast_sink_test_install(struct bst_test_list *tests); + +bst_test_install_t test_installers[] = { + test_broadcast_sink_test_install, + NULL +}; diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake new file mode 100644 index 00000000000..a922830546d --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake) + +if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) +endif() diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/tests_scripts/broadcast_audio.sh b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/tests_scripts/broadcast_audio.sh new file mode 100755 index 00000000000..64e6ac4aa9f --- /dev/null +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/tests_scripts/broadcast_audio.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Simple selfchecking test for the broadcast audio sink/source samples, +# It relies on the bs_tests hooks to register a test timer callback, which after a deadline +# will check how many audio packets the broadcast audio sink has received, and if over a threshold +# it considers the test passed + +simulation_id="broadcast_audio_samples_test" +verbosity_level=2 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +EXECUTE_TIMEOUT=100 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_samples_bluetooth_broadcast_audio_source_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1 + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_samples_broadcast_audio_sink_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \ + -testid=broadcast_audio_sink + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs #Wait for all programs in background and return != 0 if any fails diff --git a/tests/bsim/bluetooth/audio_samples/compile.sh b/tests/bsim/bluetooth/audio_samples/compile.sh index e41f4f9781d..79b1a212c6e 100755 --- a/tests/bsim/bluetooth/audio_samples/compile.sh +++ b/tests/bsim/bluetooth/audio_samples/compile.sh @@ -21,17 +21,23 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then app=samples/bluetooth/unicast_audio_server sysbuild=1 compile + app=samples/bluetooth/broadcast_audio_source sysbuild=1 compile + app=tests/bsim/bluetooth/audio_samples/unicast_audio_client sysbuild=1 compile + app=tests/bsim/bluetooth/audio_samples/broadcast_audio_sink sysbuild=1 \ + conf_file=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf \ + exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile else app=samples/bluetooth/unicast_audio_server conf_overlay=overlay-bt_ll_sw_split.conf \ exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile -fi - -if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then - app=tests/bsim/bluetooth/audio_samples/unicast_audio_client sysbuild=1 compile -else + app=samples/bluetooth/broadcast_audio_source conf_overlay=overlay-bt_ll_sw_split.conf \ + exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile app=tests/bsim/bluetooth/audio_samples/unicast_audio_client \ conf_overlay=${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/overlay-bt_ll_sw_split.conf \ exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile + app=tests/bsim/bluetooth/audio_samples/broadcast_audio_sink \ + conf_file=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf \ + conf_overlay=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf \ + exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile fi wait_for_background_jobs From 5639bc033078193569ac69c35c3a5ebbb3471ac5 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 6 Nov 2023 14:47:54 +0100 Subject: [PATCH 3120/4498] modem: modem_cellular: Fix build errors Build errors where introduced by c76d5b882c1416ce48b918a4d1e034b913baa873 and are fixed with this commit. They are trivial fixes of malformed lines. Signed-off-by: Bjarki Arge Andreasen --- drivers/modem/modem_cellular.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 71a704bd728..7564283417a 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1531,16 +1531,16 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0)); -MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds, - dial_abort_matches, modem_cellular_chat_callback_handler, 10); - MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_periodic_chat_script_cmds, - MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", allow_match), - MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", allow_match)); + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match)); MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_periodic_chat_script, swir_hl7800_periodic_chat_script_cmds, abort_matches, modem_cellular_chat_callback_handler, 4); + +MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds, + dial_abort_matches, modem_cellular_chat_callback_handler, 10); #endif #if DT_HAS_COMPAT_STATUS_OKAY(telit_me910g1) @@ -1579,10 +1579,19 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_init_chat_script, telit_me910g1_init_chat MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_dial_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match), - MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),); + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0)); MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat_script_cmds, dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, + telit_me910g1_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); #endif #define MODEM_CELLULAR_INST_NAME(name, inst) \ @@ -1607,7 +1616,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &quectel_bg95_init_chat_script, \ .dial_chat_script = &quectel_bg95_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &quectel_bg95_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1635,7 +1644,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &zephyr_gsm_ppp_init_chat_script, \ .dial_chat_script = &zephyr_gsm_ppp_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &zephyr_gsm_ppp_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1663,7 +1672,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &simcom_sim7080_init_chat_script, \ .dial_chat_script = &simcom_sim7080_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &simcom_sim7080_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1691,7 +1700,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &u_blox_sara_r4_init_chat_script, \ .dial_chat_script = &u_blox_sara_r4_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &u_blox_sara_r4_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1719,8 +1728,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &swir_hl7800_init_chat_script, \ .dial_chat_script = &swir_hl7800_dial_chat_script, \ - .dial_chat_script = &swir_hl7800_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &swir_hl7800_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -1748,7 +1756,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat .shutdown_time_ms = 5000, \ .init_chat_script = &telit_me910g1_init_chat_script, \ .dial_chat_script = &telit_me910g1_dial_chat_script, \ - .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .periodic_chat_script = &telit_me910g1_periodic_chat_script, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ From 3dce4c7ba39fc7e436aee99e6d5dada70380f68f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 6 Nov 2023 12:57:04 +0100 Subject: [PATCH 3121/4498] samples/net/cloud/aws_iot_mqtt: Fix sample yaml The sample yaml filter syntax was incorrect. Fix it. Signed-off-by: Alberto Escolar Piedras --- samples/net/cloud/aws_iot_mqtt/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/net/cloud/aws_iot_mqtt/sample.yaml b/samples/net/cloud/aws_iot_mqtt/sample.yaml index dee2dab638f..314dfc252b6 100644 --- a/samples/net/cloud/aws_iot_mqtt/sample.yaml +++ b/samples/net/cloud/aws_iot_mqtt/sample.yaml @@ -4,7 +4,7 @@ sample: common: tags: net mqtt cloud harness: net - filter: CONFIG_FULL_LIBC_SUPPORTED && not CONFIG_NATIVE_LIBC + filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC extra_args: USE_DUMMY_CREDS=1 tests: sample.net.cloud.aws_iot_mqtt: From debe7fefe65cac7ca4319010d19b1ac046a8cd5c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 6 Nov 2023 13:22:55 +0000 Subject: [PATCH 3122/4498] ci: assignees: do not set trivial on manifest changes manifest changes are often a oneliner change, but they are not necessarily trivial. Signed-off-by: Anas Nashif --- scripts/set_assignees.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/set_assignees.py b/scripts/set_assignees.py index aadfde1f076..269bde82f54 100755 --- a/scripts/set_assignees.py +++ b/scripts/set_assignees.py @@ -70,8 +70,14 @@ def process_pr(gh, maintainer_file, number): all_areas = set() fn = list(pr.get_files()) + manifest_change = False + for changed_file in fn: + if changed_file.filename in ['west.yml','submanifests/optional.yaml']: + manifest_change = True + break + # one liner PRs should be trivial - if pr.commits == 1 and (pr.additions <= 1 and pr.deletions <= 1): + if pr.commits == 1 and (pr.additions <= 1 and pr.deletions <= 1) and not manifest_change: labels = {'trivial'} if len(fn) > 500: From ea4e1b328c4e3c95263bb7cd9e6a45456e292666 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 11 Oct 2023 17:07:34 +0200 Subject: [PATCH 3123/4498] drivers: sensor: lsm6dsl: Add the 1.6Hz accelerometer rate Since the accelerometer's HM (high-performance mode) bit is forced to 1, the 1.6Hz frequency is available by setting the ODR to 11. 1.6Hz is a low-power mode that conserves energy and is suitable for some applications, such as determining the orientation (portrait or landscape) of a device. Signed-off-by: Samuel Tardieu --- drivers/sensor/lsm6dsl/Kconfig | 3 ++- drivers/sensor/lsm6dsl/lsm6dsl.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/lsm6dsl/Kconfig b/drivers/sensor/lsm6dsl/Kconfig index 57d8f9a88b3..c21937cf922 100644 --- a/drivers/sensor/lsm6dsl/Kconfig +++ b/drivers/sensor/lsm6dsl/Kconfig @@ -130,7 +130,7 @@ config LSM6DSL_ACCEL_FS config LSM6DSL_ACCEL_ODR int "Accelerometer Output data rate frequency" - range 0 10 + range 0 11 default 0 help Specify the default accelerometer output data rate expressed in @@ -146,6 +146,7 @@ config LSM6DSL_ACCEL_ODR 8: 1666Hz 9: 3332Hz 10: 6664Hz + 11: 1.6Hz endmenu endif # LSM6DSL diff --git a/drivers/sensor/lsm6dsl/lsm6dsl.c b/drivers/sensor/lsm6dsl/lsm6dsl.c index 8b7dc2fe8dc..b00df0be526 100644 --- a/drivers/sensor/lsm6dsl/lsm6dsl.c +++ b/drivers/sensor/lsm6dsl/lsm6dsl.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(LSM6DSL, CONFIG_SENSOR_LOG_LEVEL); static const uint16_t lsm6dsl_odr_map[] = {0, 12, 26, 52, 104, 208, 416, 833, - 1666, 3332, 6664}; + 1666, 3332, 6664, 1}; #if defined(LSM6DSL_ACCEL_ODR_RUNTIME) || defined(LSM6DSL_GYRO_ODR_RUNTIME) static int lsm6dsl_freq_to_odr_val(uint16_t freq) @@ -48,8 +48,9 @@ static int lsm6dsl_odr_to_freq_val(uint16_t odr) return lsm6dsl_odr_map[odr]; } - /* invalid index, return last entry */ - return lsm6dsl_odr_map[ARRAY_SIZE(lsm6dsl_odr_map) - 1]; + /* invalid index, return the fastest entry (6.66kHz) */ + BUILD_ASSERT(ARRAY_SIZE(lsm6dsl_odr_map) > 10); + return lsm6dsl_odr_map[10]; } #ifdef LSM6DSL_ACCEL_FS_RUNTIME From 813ed3a8a36200d215bb6cc94e942536da246794 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 3 Aug 2023 17:19:49 +0800 Subject: [PATCH 3124/4498] arch: arm: cortex_a_r: Move mmu and mpu init to prep_c MMU or MPU unit need to be initialized by its own CPU. - Primary core initialize MMU or MPU unit in z_arm_prep_c. - Secondary core initialize MMU or MPU unit in z_arm_secondary_start. Signed-off-by: Huifeng Zhang --- arch/arm/core/cortex_a_r/prep_c.c | 13 ++++++++++++ .../arm/include/cortex_a_r/kernel_arch_func.h | 20 ------------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/arch/arm/core/cortex_a_r/prep_c.c b/arch/arm/core/cortex_a_r/prep_c.c index dc7786af59e..cb5a6cc1638 100644 --- a/arch/arm/core/cortex_a_r/prep_c.c +++ b/arch/arm/core/cortex_a_r/prep_c.c @@ -44,6 +44,13 @@ Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) void *_vector_table_pointer; #endif +#ifdef CONFIG_ARM_MPU +extern void z_arm_mpu_init(void); +extern void z_arm_configure_static_mpu_regions(void); +#elif defined(CONFIG_ARM_AARCH32_MMU) +extern int z_arm_mmu_init(void); +#endif + #if defined(CONFIG_AARCH32_ARMV8_R) #define VECTOR_ADDRESS ((uintptr_t)_vector_start) @@ -150,6 +157,12 @@ void z_arm_prep_c(void) z_arm_init_stacks(); #endif z_arm_interrupt_init(); +#ifdef CONFIG_ARM_MPU + z_arm_mpu_init(); + z_arm_configure_static_mpu_regions(); +#elif defined(CONFIG_ARM_AARCH32_MMU) + z_arm_mmu_init(); +#endif z_cstart(); CODE_UNREACHABLE; } diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h index 5bca1214da1..b62b4bbf816 100644 --- a/arch/arm/include/cortex_a_r/kernel_arch_func.h +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -25,29 +25,9 @@ extern "C" { #endif #ifndef _ASMLANGUAGE -#ifdef CONFIG_ARM_MPU -extern void z_arm_configure_static_mpu_regions(void); -extern int z_arm_mpu_init(void); -#endif /* CONFIG_ARM_MPU */ -#ifdef CONFIG_ARM_AARCH32_MMU -extern int z_arm_mmu_init(void); -#endif /* CONFIG_ARM_AARCH32_MMU */ static ALWAYS_INLINE void arch_kernel_init(void) { -#if defined(CONFIG_ARM_MPU) - z_arm_mpu_init(); - /* Configure static memory map. This will program MPU regions, - * to set up access permissions for fixed memory sections, such - * as Application Memory or No-Cacheable SRAM area. - * - * This function is invoked once, upon system initialization. - */ - z_arm_configure_static_mpu_regions(); -#endif /* CONFIG_ARM_MPU */ -#if defined(CONFIG_ARM_AARCH32_MMU) - z_arm_mmu_init(); -#endif /* CONFIG_ARM_AARCH32_MMU */ } static ALWAYS_INLINE void From c3b857c434db9ff23f4508e596350058deda23ea Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 27 Jul 2023 16:42:34 +0800 Subject: [PATCH 3125/4498] arch: arm: cortex_ar: Use TPIDRURW as a base pointer for TLS Replace the TLS base address pointer from TPIDRURO to TPIDRURW. The difference between them is that TPIDRURO is read-only in user mode but TPIDRURW isn't. So TPIDRURO is much more suitable for store the address of _kernel.CPU[n]. For this reason, this commit replaces the base pointer of the TLS area. Signed-off-by: Huifeng Zhang --- arch/arm/core/cortex_a_r/__aeabi_read_tp.S | 5 ++++- arch/arm/core/cortex_a_r/swap_helper.S | 4 ++-- cmake/compiler/gcc/target_arm.cmake | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/core/cortex_a_r/__aeabi_read_tp.S b/arch/arm/core/cortex_a_r/__aeabi_read_tp.S index 25e240b39d3..40874c4a1fa 100644 --- a/arch/arm/core/cortex_a_r/__aeabi_read_tp.S +++ b/arch/arm/core/cortex_a_r/__aeabi_read_tp.S @@ -11,5 +11,8 @@ _ASM_FILE_PROLOGUE GTEXT(__aeabi_read_tp) SECTION_FUNC(text, __aeabi_read_tp) - mrc 15, 0, r0, c13, c0, 3 + /* + * TPIDRURW will be used as a base pointer point to TLS aera. + */ + mrc 15, 0, r0, c13, c0, 2 bx lr diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S index c646e70cc7e..0031148cae9 100644 --- a/arch/arm/core/cortex_a_r/swap_helper.S +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -121,10 +121,10 @@ out_fp_inactive: ldr r0, [r4] /* Store TLS pointer in the "Process ID" register. - * This register is used as a base pointer to all + * TPIDRURW is used as a base pointer to all * thread variables with offsets added by toolchain. */ - mcr 15, 0, r0, cr13, cr0, 3 + mcr 15, 0, r0, c13, c0, 2 #endif #if defined(CONFIG_ARM_STORE_EXC_RETURN) diff --git a/cmake/compiler/gcc/target_arm.cmake b/cmake/compiler/gcc/target_arm.cmake index 0cfaba43da0..a813c2563a3 100644 --- a/cmake/compiler/gcc/target_arm.cmake +++ b/cmake/compiler/gcc/target_arm.cmake @@ -34,5 +34,10 @@ if(CONFIG_FP16) list(APPEND ARM_C_FLAGS -mfp16-format=alternative) endif() endif() + +if(CONFIG_THREAD_LOCAL_STORAGE) + list(APPEND ARM_C_FLAGS -mtp=soft) +endif() + list(APPEND TOOLCHAIN_C_FLAGS ${ARM_C_FLAGS}) list(APPEND TOOLCHAIN_LD_FLAGS NO_SPLIT ${ARM_C_FLAGS}) From 87dd43766d8fcbb9a519f5753911326adeae3f60 Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Wed, 2 Aug 2023 14:30:41 +0800 Subject: [PATCH 3126/4498] arch: arm: cortex_a_r: Hold curr_cpu instance to TPIDRURO Store the current CPU's struct _cpu instance into TPIDRURO, so that the CPU core can get its struct _cpu instance by reading TPIDRURO. This is useful in the SMP system. Signed-off-by: Huifeng Zhang --- arch/arm/core/cortex_a_r/exc.S | 13 +++--- arch/arm/core/cortex_a_r/exc_exit.S | 40 ++++++++-------- arch/arm/core/cortex_a_r/fault.c | 10 ++-- arch/arm/core/cortex_a_r/isr_wrapper.S | 17 +++---- arch/arm/core/cortex_a_r/macro_priv.inc | 19 ++++++++ arch/arm/core/cortex_a_r/prep_c.c | 3 ++ arch/arm/core/cortex_a_r/swap_helper.S | 46 +++++++++---------- arch/arm/include/cortex_a_r/exc.h | 4 +- include/zephyr/arch/arm/arch_inlines.h | 6 +-- .../zephyr/arch/arm/cortex_a_r/lib_helpers.h | 1 + include/zephyr/arch/arm/cortex_a_r/tpidruro.h | 20 ++++++++ 11 files changed, 112 insertions(+), 67 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/macro_priv.inc create mode 100644 include/zephyr/arch/arm/cortex_a_r/tpidruro.h diff --git a/arch/arm/core/cortex_a_r/exc.S b/arch/arm/core/cortex_a_r/exc.S index 87742b39808..1bff0d4bcfe 100644 --- a/arch/arm/core/cortex_a_r/exc.S +++ b/arch/arm/core/cortex_a_r/exc.S @@ -27,6 +27,7 @@ #include #include #include +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -86,10 +87,10 @@ GTEXT(z_arm_data_abort) #endif /* Increment exception nesting count */ - ldr r2, =_kernel - ldr r1, [r2, #_kernel_offset_to_nested] + get_cpu r2 + ldr r1, [r2, #___cpu_t_nested_OFFSET] add r1, r1, #1 - str r1, [r2, #_kernel_offset_to_nested] + str r1, [r2, #___cpu_t_nested_OFFSET] .endm .macro exception_exit @@ -128,10 +129,10 @@ SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_undef_instruction) sub sp, #24 /* Increment exception nesting count */ - ldr r2, =_kernel - ldr r1, [r2, #_kernel_offset_to_nested] + get_cpu r2 + ldr r1, [r2, #___cpu_t_nested_OFFSET] add r1, r1, #1 - str r1, [r2, #_kernel_offset_to_nested] + str r1, [r2, #___cpu_t_nested_OFFSET] #if defined(CONFIG_FPU_SHARING) sub sp, #___fpu_t_SIZEOF diff --git a/arch/arm/core/cortex_a_r/exc_exit.S b/arch/arm/core/cortex_a_r/exc_exit.S index 67fc5fa6e00..499fa17d30a 100644 --- a/arch/arm/core/cortex_a_r/exc_exit.S +++ b/arch/arm/core/cortex_a_r/exc_exit.S @@ -18,6 +18,7 @@ #include #include #include +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -52,8 +53,8 @@ GDATA(_kernel) bne system_thread_exit\@ /* Restore user stack pointer */ - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] + get_cpu r0 + ldr r0, [r0, #___cpu_t_current_OFFSET] cps #MODE_SYS ldr sp, [r0, #_thread_offset_to_sp_usr] /* sp_usr */ cps #MODE_SVC @@ -68,8 +69,8 @@ system_thread_exit\@: * If the floating point context pointer is null, then a context was * saved so restore the float context from the exception stack frame. */ - ldr r2, =_kernel - ldr r1, [r2, #_kernel_offset_to_fp_ctx] + get_cpu r2 + ldr r1, [r2, #___cpu_t_fp_ctx_OFFSET] cmp r1, #0 beq vfp_restore\@ @@ -79,7 +80,7 @@ system_thread_exit\@: */ cmp r0, #0 moveq r1, #0 - streq r1, [r2, #_kernel_offset_to_fp_ctx] + streq r1, [r2, #___cpu_t_fp_ctx_OFFSET] b vfp_exit\@ vfp_restore\@: @@ -140,23 +141,24 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_int_exit) #ifdef CONFIG_PREEMPT_ENABLED /* Do not context switch if exiting a nested interrupt */ - ldr r3, =_kernel - ldr r0, [r3, #_kernel_offset_to_nested] + get_cpu r3 + ldr r0, [r3, #___cpu_t_nested_OFFSET] cmp r0, #1 bhi __EXIT_INT - ldr r1, [r3, #_kernel_offset_to_current] - ldr r0, [r3, #_kernel_offset_to_ready_q_cache] + ldr r1, [r3, #___cpu_t_current_OFFSET] + ldr r2, =_kernel + ldr r0, [r2, #_kernel_offset_to_ready_q_cache] cmp r0, r1 blne z_arm_do_swap __EXIT_INT: #endif /* CONFIG_PREEMPT_ENABLED */ /* Decrement interrupt nesting count */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_nested] + get_cpu r2 + ldr r0, [r2, #___cpu_t_nested_OFFSET] sub r0, r0, #1 - str r0, [r2, #_kernel_offset_to_nested] + str r0, [r2, #___cpu_t_nested_OFFSET] /* Restore previous stack pointer */ pop {r2, r3} @@ -207,8 +209,8 @@ __EXIT_INT: */ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_exc_exit) /* Do not context switch if exiting a nested exception */ - ldr r3, =_kernel - ldr r1, [r3, #_kernel_offset_to_nested] + get_cpu r3 + ldr r1, [r3, #___cpu_t_nested_OFFSET] cmp r1, #1 bhi __EXIT_EXC @@ -239,10 +241,10 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_exc_exit) bl z_arm_do_swap /* Decrement exception nesting count */ - ldr r3, =_kernel - ldr r0, [r3, #_kernel_offset_to_nested] + get_cpu r3 + ldr r0, [r3, #___cpu_t_nested_OFFSET] sub r0, r0, #1 - str r0, [r3, #_kernel_offset_to_nested] + str r0, [r3, #___cpu_t_nested_OFFSET] /* Return to the switched thread */ cps #MODE_SYS @@ -255,9 +257,9 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_exc_exit) __EXIT_EXC: /* Decrement exception nesting count */ - ldr r0, [r3, #_kernel_offset_to_nested] + ldr r0, [r3, #___cpu_t_nested_OFFSET] sub r0, r0, #1 - str r0, [r3, #_kernel_offset_to_nested] + str r0, [r3, #___cpu_t_nested_OFFSET] #if defined(CONFIG_FPU_SHARING) add sp, sp, #___fpu_t_SIZEOF diff --git a/arch/arm/core/cortex_a_r/fault.c b/arch/arm/core/cortex_a_r/fault.c index 752fe5a95f0..4b1624cd54b 100644 --- a/arch/arm/core/cortex_a_r/fault.c +++ b/arch/arm/core/cortex_a_r/fault.c @@ -147,7 +147,7 @@ bool z_arm_fault_undef_instruction_fp(void) __set_FPEXC(FPEXC_EN); - if (_kernel.cpus[0].nested > 1) { + if (_current_cpu->nested > 1) { /* * If the nested count is greater than 1, the undefined * instruction exception came from an irq/svc context. (The @@ -155,12 +155,12 @@ bool z_arm_fault_undef_instruction_fp(void) * the undef exception would increment it to 2). */ struct __fpu_sf *spill_esf = - (struct __fpu_sf *)_kernel.cpus[0].fp_ctx; + (struct __fpu_sf *)_current_cpu->fp_ctx; if (spill_esf == NULL) return false; - _kernel.cpus[0].fp_ctx = NULL; + _current_cpu->fp_ctx = NULL; /* * If the nested count is 2 and the current thread has used the @@ -170,9 +170,9 @@ bool z_arm_fault_undef_instruction_fp(void) * saved exception stack frame, then save the floating point * context because it is about to be overwritten. */ - if (((_kernel.cpus[0].nested == 2) + if (((_current_cpu->nested == 2) && (_current->base.user_options & K_FP_REGS)) - || ((_kernel.cpus[0].nested > 2) + || ((_current_cpu->nested > 2) && (spill_esf->undefined & FPEXC_EN))) { /* * Spill VFP registers to specified exception stack diff --git a/arch/arm/core/cortex_a_r/isr_wrapper.S b/arch/arm/core/cortex_a_r/isr_wrapper.S index dc5fa9cac04..1504ba38350 100644 --- a/arch/arm/core/cortex_a_r/isr_wrapper.S +++ b/arch/arm/core/cortex_a_r/isr_wrapper.S @@ -22,6 +22,7 @@ #include #include #include +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -57,8 +58,8 @@ SECTION_FUNC(TEXT, _isr_wrapper) cmp r0, #MODE_USR bne isr_system_thread - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] + get_cpu r0 + ldr r0, [r0, #___cpu_t_current_OFFSET] /* Save away user stack pointer */ cps #MODE_SYS @@ -108,10 +109,10 @@ _vfp_not_enabled: * Mark where to store the floating context for the undefined * instruction handler */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_fp_ctx] + get_cpu r2 + ldr r0, [r2, #___cpu_t_fp_ctx_OFFSET] cmp r0, #0 - streq sp, [r2, #_kernel_offset_to_fp_ctx] + streq sp, [r2, #___cpu_t_fp_ctx_OFFSET] #endif /* CONFIG_FPU_SHARING */ /* @@ -139,10 +140,10 @@ _vfp_not_enabled: push {r2, r3} /* Increment interrupt nesting count */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_nested] + get_cpu r2 + ldr r0, [r2, #___cpu_t_nested_OFFSET] add r0, r0, #1 - str r0, [r2, #_kernel_offset_to_nested] + str r0, [r2, #___cpu_t_nested_OFFSET] #ifdef CONFIG_TRACING_ISR bl sys_trace_isr_enter diff --git a/arch/arm/core/cortex_a_r/macro_priv.inc b/arch/arm/core/cortex_a_r/macro_priv.inc new file mode 100644 index 00000000000..dfd192a70f9 --- /dev/null +++ b/arch/arm/core/cortex_a_r/macro_priv.inc @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _MACRO_PRIV_INC_ +#define _MACRO_PRIV_INC_ + +#include + +.macro get_cpu rreg0 + /* + * Get CPU pointer. + */ + mrc p15, 0, \rreg0, c13, c0, 3 + and \rreg0, #TPIDRURO_CURR_CPU +.endm + +#endif /* _MACRO_PRIV_INC_ */ diff --git a/arch/arm/core/cortex_a_r/prep_c.c b/arch/arm/core/cortex_a_r/prep_c.c index cb5a6cc1638..95dbb49cf1e 100644 --- a/arch/arm/core/cortex_a_r/prep_c.c +++ b/arch/arm/core/cortex_a_r/prep_c.c @@ -147,6 +147,9 @@ extern FUNC_NORETURN void z_cstart(void); */ void z_arm_prep_c(void) { + /* Initialize tpidruro with our struct _cpu instance address */ + write_tpidruro((uintptr_t)&_kernel.cpus[0]); + relocate_vector_table(); #if defined(CONFIG_CPU_HAS_FPU) z_arm_floating_point_init(); diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S index 0031148cae9..548bb446aa3 100644 --- a/arch/arm/core/cortex_a_r/swap_helper.S +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -20,6 +20,7 @@ #include #include #include +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -49,9 +50,9 @@ SECTION_FUNC(TEXT, z_arm_do_swap) pop {r0, lr} #endif /* CONFIG_INSTRUMENT_THREAD_SWITCHING */ - /* load _kernel into r1 and current k_thread into r2 */ - ldr r1, =_kernel - ldr r2, [r1, #_kernel_offset_to_current] + /* load current _cpu into r1 and current k_thread into r2 */ + get_cpu r1 + ldr r2, [r1, #___cpu_t_current_OFFSET] #if defined(CONFIG_ARM_STORE_EXC_RETURN) /* Store LSB of LR (EXC_RETURN) to the thread's 'mode' word. */ @@ -81,7 +82,7 @@ SECTION_FUNC(TEXT, z_arm_do_swap) * float registers have not been saved away, so write them to the * exception stack frame. */ - ldr r0, [r1, #_kernel_offset_to_fp_ctx] + ldr r0, [r1, #___cpu_t_fp_ctx_OFFSET] cmp r0, #0 beq out_store_thread_context @@ -106,13 +107,14 @@ out_fp_inactive: * frame, so zero out the global pointer to note this. */ mov r0, #0 - str r0, [r1, #_kernel_offset_to_fp_ctx] + str r0, [r1, #___cpu_t_fp_ctx_OFFSET] #endif /* CONFIG_FPU_SHARING */ /* fetch the thread to run from the ready queue cache */ - ldr r2, [r1, #_kernel_offset_to_ready_q_cache] + ldr r3, =_kernel + ldr r2, [r3, #_kernel_offset_to_ready_q_cache] - str r2, [r1, #_kernel_offset_to_current] + str r2, [r1, #___cpu_t_current_OFFSET] #if defined(CONFIG_THREAD_LOCAL_STORAGE) /* Grab the TLS pointer */ @@ -139,11 +141,6 @@ out_fp_inactive: movs r3, #0 str r3, [r2, #_thread_offset_to_basepri] -_thread_irq_disabled: - /* load _kernel into r1 and current k_thread into r2 */ - ldr r1, =_kernel - ldr r2, [r1, #_kernel_offset_to_current] - /* addr of callee-saved regs in thread in r0 */ ldr r0, =_thread_offset_to_callee_saved add r0, r2 @@ -175,9 +172,9 @@ in_fp_inactive: /* r2 contains k_thread */ mov r0, r2 /* Re-program dynamic memory map */ - push {r2, lr} + push {r0, lr} bl z_arm_configure_dynamic_mpu_regions - pop {r2, lr} + pop {r0, lr} #endif #ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING @@ -217,8 +214,8 @@ SECTION_FUNC(TEXT, z_arm_svc) cmp r0, #MODE_USR bne svc_system_thread - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] + get_cpu r0 + ldr r0, [r0, #___cpu_t_current_OFFSET] /* Save away user stack pointer */ cps #MODE_SYS @@ -265,10 +262,10 @@ _vfp_not_enabled: * Mark where to store the floating context for the undefined * instruction handler */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_fp_ctx] + get_cpu r2 + ldr r0, [r2, #___cpu_t_fp_ctx_OFFSET] cmp r0, #0 - streq sp, [r2, #_kernel_offset_to_fp_ctx] + streq sp, [r2, #___cpu_t_fp_ctx_OFFSET] #endif /* CONFIG_FPU_SHARING */ mov ip, sp @@ -282,15 +279,16 @@ _vfp_not_enabled: push {lr} /* Align stack at double-word boundary */ + /* TODO: Question, why push {r2, r3} here */ and r3, sp, #4 sub sp, sp, r3 push {r2, r3} /* Increment interrupt nesting count */ - ldr r2, =_kernel - ldr r0, [r2, #_kernel_offset_to_nested] + get_cpu r2 + ldr r0, [r2, #___cpu_t_nested_OFFSET] add r0, r0, #1 - str r0, [r2, #_kernel_offset_to_nested] + str r0, [r2, #___cpu_t_nested_OFFSET] /* Get SVC number */ mrs r0, spsr @@ -403,8 +401,8 @@ _do_syscall: ldr r6, =K_SYSCALL_BAD valid_syscall_id: - ldr r0, =_kernel - ldr r0, [r0, #_kernel_offset_to_current] + get_cpu r0 + ldr r0, [r0, #___cpu_t_current_OFFSET] ldr r1, [r0, #_thread_offset_to_mode] bic r1, #1 /* Store (privileged) mode in thread's mode state variable */ diff --git a/arch/arm/include/cortex_a_r/exc.h b/arch/arm/include/cortex_a_r/exc.h index b77febbc047..afeae801063 100644 --- a/arch/arm/include/cortex_a_r/exc.h +++ b/arch/arm/include/cortex_a_r/exc.h @@ -35,12 +35,12 @@ extern volatile irq_offload_routine_t offload_routine; /* Check the CPSR mode bits to see if we are in IRQ or FIQ mode */ static ALWAYS_INLINE bool arch_is_in_isr(void) { - return (_kernel.cpus[0].nested != 0U); + return (arch_curr_cpu()->nested != 0U); } static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) { - return (_kernel.cpus[0].nested > 1U) ? (true) : (false); + return (arch_curr_cpu()->nested > 1U) ? (true) : (false); } #if defined(CONFIG_USERSPACE) diff --git a/include/zephyr/arch/arm/arch_inlines.h b/include/zephyr/arch/arm/arch_inlines.h index 5d86858b05b..96822e0eff1 100644 --- a/include/zephyr/arch/arm/arch_inlines.h +++ b/include/zephyr/arch/arm/arch_inlines.h @@ -8,14 +8,14 @@ #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ARCH_INLINES_H #include +#include +#include -#ifndef CONFIG_SMP static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void) { /* Dummy implementation always return the first cpu */ - return &_kernel.cpus[0]; + return (_cpu_t *)(read_tpidruro() & TPIDRURO_CURR_CPU); } -#endif static ALWAYS_INLINE uint32_t arch_proc_id(void) { diff --git a/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h b/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h index a4e74b0daa4..209c4dd7325 100644 --- a/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h +++ b/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h @@ -72,6 +72,7 @@ MAKE_REG_HELPER(mair0, 0, 10, 2, 0); MAKE_REG_HELPER(vbar, 0, 12, 0, 0); MAKE_REG_HELPER(cntv_ctl, 0, 14, 3, 1); MAKE_REG_HELPER(ctr, 0, 0, 0, 1); +MAKE_REG_HELPER(tpidruro, 0, 13, 0, 3); MAKE_REG64_HELPER(ICC_SGI1R, 0, 12); MAKE_REG64_HELPER(cntvct, 1, 14); MAKE_REG64_HELPER(cntv_cval, 3, 14); diff --git a/include/zephyr/arch/arm/cortex_a_r/tpidruro.h b/include/zephyr/arch/arm/cortex_a_r/tpidruro.h new file mode 100644 index 00000000000..25eb275af9c --- /dev/null +++ b/include/zephyr/arch/arm/cortex_a_r/tpidruro.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief tpidruro bits allocation + * + * Among other things, the tpidruro holds the address for the current + * CPU's struct _cpu instance. But such a pointer is at least 4-bytes + * aligned. That leaves two of free bits for other purposes. + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_TPIDRURO_H_ +#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_TPIDRURO_H_ + +#define TPIDRURO_CURR_CPU 0xFFFFFFFCUL + +#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_TPIDRURO_H_ */ From abde709b5e0034401cff9205626005ad2baa359b Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Tue, 18 Jul 2023 13:22:52 +0800 Subject: [PATCH 3127/4498] arch: arm: cortex_a_r: introduce USE_SWITCH This commit introduce 'USE_SWITCH' feature into cortex-A/R(aarch32) architecture For introducing USE_SWITCH, the exception entry and exit are unified via `z_arm_cortex_ar_enter_exc` and `z_arm_cortex_ar_exit_exc`. All exceptions including ISR are using this way to enter and exit exception handler. Differentiate exception depth and interrupt depth. Allow doing context switch when exception depth greater than 1 but not allow doing this when interrupt depth greater than 1. Currently, USE_SWITCH doesn't support FPU_SHARING and USERSPACE. Signed-off-by: Huifeng Zhang --- arch/arm/core/Kconfig | 8 +- arch/arm/core/cortex_a_r/CMakeLists.txt | 5 +- arch/arm/core/cortex_a_r/Kconfig | 2 +- arch/arm/core/cortex_a_r/exc.S | 58 ++++++ arch/arm/core/cortex_a_r/isr_wrapper.S | 143 +++++++++++++++ arch/arm/core/cortex_a_r/macro_priv.inc | 20 +++ arch/arm/core/cortex_a_r/switch.S | 165 ++++++++++++++++++ arch/arm/core/cortex_a_r/thread.c | 7 + arch/arm/core/cortex_a_r/vector_table.S | 26 +++ arch/arm/core/offsets/offsets_aarch32.c | 5 + arch/arm/include/cortex_a_r/exc.h | 4 +- .../arm/include/cortex_a_r/kernel_arch_func.h | 18 ++ arch/arm/include/offsets_short_arch.h | 8 + include/zephyr/arch/arm/structs.h | 33 ++++ include/zephyr/arch/arm/thread.h | 7 + include/zephyr/arch/structs.h | 2 + soc/arm/arm/fvp_aemv8r_aarch32/Kconfig.soc | 2 +- 17 files changed, 504 insertions(+), 9 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/switch.S create mode 100644 include/zephyr/arch/arm/structs.h diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index a06b4cb5e95..524bd86ff4c 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -34,11 +34,12 @@ config CPU_AARCH32_CORTEX_R select HAS_CMSIS_CORE select ARCH_HAS_NESTED_EXCEPTION_DETECTION select HAS_FLASH_LOAD_OFFSET - select ARCH_HAS_USERSPACE if ARM_MPU - select ARCH_HAS_EXTRA_EXCEPTION_INFO + select ARCH_HAS_USERSPACE if ARM_MPU && !USE_SWITCH + select ARCH_HAS_EXTRA_EXCEPTION_INFO if !USE_SWITCH select ARCH_HAS_CODE_DATA_RELOCATION select ARCH_HAS_NOCACHE_MEMORY_SUPPORT if ARM_MPU && CPU_HAS_ARM_MPU && CPU_HAS_DCACHE select ARCH_SUPPORTS_ROM_START + select USE_SWITCH_SUPPORTED help This option signifies the use of a CPU of the Cortex-R family. @@ -54,8 +55,9 @@ config CPU_AARCH32_CORTEX_A select CPU_HAS_MMU select HAS_CMSIS_CORE select HAS_FLASH_LOAD_OFFSET - select ARCH_HAS_EXTRA_EXCEPTION_INFO + select ARCH_HAS_EXTRA_EXCEPTION_INFO if !USE_SWITCH select ARCH_HAS_NOCACHE_MEMORY_SUPPORT + select USE_SWITCH_SUPPORTED help This option signifies the use of a CPU of the Cortex-A family. diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index 8b0dac374ee..74dc266ad08 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -4,7 +4,6 @@ zephyr_library() zephyr_library_sources( exc.S - exc_exit.S fault.c irq_init.c reboot.c @@ -12,8 +11,6 @@ zephyr_library_sources( stacks.c tcm.c vector_table.S - swap.c - swap_helper.S irq_manage.c prep_c.c thread.c @@ -25,3 +22,5 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) +zephyr_library_sources_ifdef(CONFIG_USE_SWITCH switch.S) +zephyr_library_sources_ifndef(CONFIG_USE_SWITCH swap.c swap_helper.S exc_exit.S) diff --git a/arch/arm/core/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig index 10bf721a870..48dc04834ff 100644 --- a/arch/arm/core/cortex_a_r/Kconfig +++ b/arch/arm/core/cortex_a_r/Kconfig @@ -99,7 +99,7 @@ config CPU_CORTEX_R52 select AARCH32_ARMV8_R select CPU_HAS_ICACHE select CPU_HAS_DCACHE - select VFP_SP_D16 + select VFP_SP_D16 if !USE_SWITCH help This option signifies the use of a Cortex-R52 CPU diff --git a/arch/arm/core/cortex_a_r/exc.S b/arch/arm/core/cortex_a_r/exc.S index 1bff0d4bcfe..78414fcd0a1 100644 --- a/arch/arm/core/cortex_a_r/exc.S +++ b/arch/arm/core/cortex_a_r/exc.S @@ -42,6 +42,8 @@ GTEXT(z_arm_undef_instruction) GTEXT(z_arm_prefetch_abort) GTEXT(z_arm_data_abort) +#ifndef CONFIG_USE_SWITCH + .macro exception_entry mode /* * Store r0-r3, r12, lr, lr_und and spsr_und into the stack to @@ -233,3 +235,59 @@ SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_data_abort) streq r1, [sp, #24 + FPU_SF_SIZE] b z_arm_exc_exit + +#else +/** + * @brief Undefined instruction exception handler + * + * An undefined instruction (UNDEF) exception is generated when an undefined + * instruction, or a VFP instruction when the VFP is not enabled, is + * encountered. + */ +SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_undef_instruction) + /* + * The undefined instruction address is offset by 2 if the previous + * mode is Thumb; otherwise, it is offset by 4. + */ + push {r0} + mrs r0, spsr + tst r0, #T_BIT + subeq lr, #4 /* ARM (!T_BIT) */ + subne lr, #2 /* Thumb (T_BIT) */ + pop {r0} + + z_arm_cortex_ar_enter_exc + bl z_arm_fault_undef_instruction + b z_arm_cortex_ar_exit_exc + +/** + * @brief Prefetch abort exception handler + * + * A prefetch abort (PABT) exception is generated when the processor marks the + * prefetched instruction as invalid and the instruction is executed. + */ +SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_prefetch_abort) + /* + * The faulting instruction address is always offset by 4 for the + * prefetch abort exceptions. + */ + sub lr, #4 + z_arm_cortex_ar_enter_exc + bl z_arm_fault_prefetch + b z_arm_cortex_ar_exit_exc + +/** + * @brief Data abort exception handler + * + * A data abort (DABT) exception is generated when an error occurs on a data + * memory access. This exception can be either synchronous or asynchronous, + * depending on the type of fault that caused it. + */ +SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_data_abort) + sub lr, #8 + + z_arm_cortex_ar_enter_exc + bl z_arm_fault_data + b z_arm_cortex_ar_exit_exc + +#endif diff --git a/arch/arm/core/cortex_a_r/isr_wrapper.S b/arch/arm/core/cortex_a_r/isr_wrapper.S index 1504ba38350..0cd30e0a343 100644 --- a/arch/arm/core/cortex_a_r/isr_wrapper.S +++ b/arch/arm/core/cortex_a_r/isr_wrapper.S @@ -32,6 +32,7 @@ GDATA(_sw_isr_table) GTEXT(_isr_wrapper) GTEXT(z_arm_int_exit) +#ifndef CONFIG_USE_SWITCH /** * * @brief Wrapper around ISRs when inserted in software ISR table @@ -228,3 +229,145 @@ spurious_continue: * z_arm_int_exit() */ ldr r1, =z_arm_int_exit bx r1 + +#else +/** + * + * @brief Wrapper around ISRs when inserted in software ISR table + * + * When inserted in the vector table, _isr_wrapper() demuxes the ISR table + * using the running interrupt number as the index, and invokes the registered + * ISR with its corresponding argument. When returning from the ISR, it + * determines if a context switch needs to happen and invoke the arch_switch + * function if so. + * + */ +SECTION_FUNC(TEXT, _isr_wrapper) + sub lr, #4 + z_arm_cortex_ar_enter_exc + + /* Increment interrupt nesting count */ + get_cpu r2 + ldr r0, [r2, #___cpu_t_nested_OFFSET] + add r0, #1 + str r0, [r2, #___cpu_t_nested_OFFSET] + + /* If not nested: switch to IRQ stack and save current sp on it. */ + cmp r0, #1 + bhi 1f + mov r0, sp + cps #MODE_IRQ + push {r0} +1: +#ifdef CONFIG_TRACING_ISR + bl sys_trace_isr_enter +#endif /* CONFIG_TRACING_ISR */ + +#ifdef CONFIG_PM + /* + * All interrupts are disabled when handling idle wakeup. For tickless + * idle, this ensures that the calculation and programming of the + * device for the next timer deadline is not interrupted. For + * non-tickless idle, this ensures that the clearing of the kernel idle + * state is not interrupted. In each case, z_pm_save_idle_exit + * is called with interrupts disabled. + */ + + /* is this a wakeup from idle ? */ + ldr r2, =_kernel + /* requested idle duration, in ticks */ + ldr r0, [r2, #_kernel_offset_to_idle] + cmp r0, #0 + + beq _idle_state_cleared + movs r1, #0 + /* clear kernel idle state */ + str r1, [r2, #_kernel_offset_to_idle] + bl z_pm_save_idle_exit +_idle_state_cleared: +#endif /* CONFIG_PM */ + + /* Get active IRQ number from the interrupt controller */ +#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + bl arm_gic_get_active +#else + bl z_soc_irq_get_active +#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + + push {r0, r1} + lsl r0, r0, #3 /* table is 8-byte wide */ + + /* + * Skip calling the isr if it is a spurious interrupt. + */ + mov r1, #CONFIG_NUM_IRQS + lsl r1, r1, #3 + cmp r0, r1 + bge spurious_continue + + ldr r1, =_sw_isr_table + add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay + * in thumb mode */ + ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ + + /* + * Enable and disable interrupts again to allow nested in exception handlers. + */ + cpsie i + blx r3 /* call ISR */ + cpsid i + +spurious_continue: + /* Signal end-of-interrupt */ + pop {r0, r1} +#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + bl arm_gic_eoi +#else + bl z_soc_irq_eoi +#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + +#ifdef CONFIG_TRACING_ISR + bl sys_trace_isr_exit +#endif + +GTEXT(z_arm_cortex_ar_irq_done) +z_arm_cortex_ar_irq_done: + /* Decrement interrupt nesting count */ + get_cpu r2 + ldr r0, [r2, #___cpu_t_nested_OFFSET] + sub r0, r0, #1 + str r0, [r2, #___cpu_t_nested_OFFSET] + /* Do not context switch if exiting a nested interrupt */ + cmp r0, #0 + bhi __EXIT_INT + + /* retrieve pointer to the current thread */ + pop {r0} + cps #MODE_SYS + mov sp, r0 + + ldr r1, [r2, #___cpu_t_current_OFFSET] + push {r1} + mov r0, #0 + bl z_get_next_switch_handle + + pop {r1} + cmp r0, #0 + beq __EXIT_INT + + /* + * Switch thread + * r0: new thread + * r1: old thread + */ + bl z_arm_context_switch + +__EXIT_INT: + +#ifdef CONFIG_STACK_SENTINEL + bl z_check_stack_sentinel +#endif /* CONFIG_STACK_SENTINEL */ + + b z_arm_cortex_ar_exit_exc + +#endif diff --git a/arch/arm/core/cortex_a_r/macro_priv.inc b/arch/arm/core/cortex_a_r/macro_priv.inc index dfd192a70f9..6079c92ab5f 100644 --- a/arch/arm/core/cortex_a_r/macro_priv.inc +++ b/arch/arm/core/cortex_a_r/macro_priv.inc @@ -16,4 +16,24 @@ and \rreg0, #TPIDRURO_CURR_CPU .endm +.macro z_arm_cortex_ar_enter_exc + /* + * Store r0-r3, r12, lr into the stack to construct an exception + * stack frame. + */ + srsdb sp!, #MODE_SYS + cps #MODE_SYS + stmdb sp, {r0-r3, r12, lr}^ + sub sp, #24 + + /* TODO: EXTRA_EXCEPTION_INFO */ + mov r0, sp + + /* increment exception depth */ + get_cpu r2 + ldrb r1, [r2, #_cpu_offset_to_exc_depth] + add r1, r1, #1 + strb r1, [r2, #_cpu_offset_to_exc_depth] +.endm + #endif /* _MACRO_PRIV_INC_ */ diff --git a/arch/arm/core/cortex_a_r/switch.S b/arch/arm/core/cortex_a_r/switch.S new file mode 100644 index 00000000000..800d46bbf94 --- /dev/null +++ b/arch/arm/core/cortex_a_r/switch.S @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Thread context switching for ARM Cortex-A and Cortex-R (AArch32) + * + * This module implements the routines necessary for thread context switching + * on ARM Cortex-A and Cortex-R CPUs. + */ + +#include +#include +#include +#include +#include +#include "macro_priv.inc" + +_ASM_FILE_PROLOGUE + +GTEXT(z_arm_svc) +GTEXT(z_arm_context_switch) +GTEXT(z_do_kernel_oops) +GTEXT(z_arm_do_syscall) + +/* + * Routine to handle context switches + * + * This function is directly called either by _isr_wrapper() in case of + * preemption, or arch_switch() in case of cooperative switching. + * + * void z_arm_context_switch(struct k_thread *new, struct k_thread *old); + */ +SECTION_FUNC(TEXT, z_arm_context_switch) + + ldr r2, =_thread_offset_to_callee_saved + add r2, r1, r2 + + stm r2, {r4-r11, sp, lr} + + /* save current thread's exception depth */ + get_cpu r2 + ldrb r3, [r2, #_cpu_offset_to_exc_depth] + strb r3, [r1, #_thread_offset_to_exception_depth] + + /* retrieve next thread's exception depth */ + ldrb r3, [r0, #_thread_offset_to_exception_depth] + strb r3, [r2, #_cpu_offset_to_exc_depth] + + /* save old thread into switch handle which is required by + * z_sched_switch_spin(). + * + * Note that this step must be done after all relevant state is + * saved. + */ + dsb + str r1, [r1, #___thread_t_switch_handle_OFFSET] + +#if defined(CONFIG_THREAD_LOCAL_STORAGE) + /* Grab the TLS pointer */ + ldr r3, [r0, #_thread_offset_to_tls] + + /* Store TLS pointer in the "Process ID" register. + * This register is used as a base pointer to all + * thread variables with offsets added by toolchain. + */ + mcr 15, 0, r3, c13, c0, 2 +#endif + + ldr r2, =_thread_offset_to_callee_saved + add r2, r0, r2 + ldm r2, {r4-r11, sp, lr} + +#if defined (CONFIG_ARM_MPU) + /* Re-program dynamic memory map */ + push {r0, lr} + bl z_arm_configure_dynamic_mpu_regions + pop {r0, lr} +#endif + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push {lr} + bl z_thread_mark_switched_in + pop {lr} +#endif + + bx lr + +/** + * + * @brief Service call handler + * + * The service call (svc) is used in the following occasions: + * - Cooperative context switching + * - IRQ offloading + * - Kernel run-time exceptions + * + */ +SECTION_FUNC(TEXT, z_arm_svc) + z_arm_cortex_ar_enter_exc + + /* Get SVC number */ + cps #MODE_SVC + mrs r0, spsr + tst r0, #0x20 + ldreq r1, [lr, #-4] + biceq r1, #0xff000000 + beq demux + + ldr r1, [lr, #-2] + and r1, #0xff + + /* + * grab service call number: + * TODO 0: context switch + * 1: irq_offload (if configured) + * 2: kernel panic or oops (software generated fatal exception) + * TODO 3: system calls for memory protection + */ +demux: + cps #MODE_SYS + + cmp r1, #_SVC_CALL_RUNTIME_EXCEPT + beq _oops + +#ifdef CONFIG_IRQ_OFFLOAD + cmp r1, #_SVC_CALL_IRQ_OFFLOAD + beq offload + b inv +offload: + get_cpu r2 + ldr r3, [r2, #___cpu_t_nested_OFFSET] + add r3, r3, #1 + str r3, [r2, #___cpu_t_nested_OFFSET] + + /* If not nested: switch to IRQ stack and save current sp on it. */ + cmp r3, #1 + bhi 1f + mov r0, sp + cps #MODE_IRQ + push {r0} + +1: + blx z_irq_do_offload + b z_arm_cortex_ar_irq_done +#endif + b inv + +_oops: + /* + * Pass the exception frame to z_do_kernel_oops. r0 contains the + * exception reason. + */ + mov r0, sp + bl z_do_kernel_oops + +inv: + mov r0, #0 /* K_ERR_CPU_EXCEPTION */ + mov r1, sp + bl z_arm_fatal_error + + /* Return here only in case of recoverable error */ + b z_arm_cortex_ar_exit_exc diff --git a/arch/arm/core/cortex_a_r/thread.c b/arch/arm/core/cortex_a_r/thread.c index c5dbdc81ba6..9d57563f6bd 100644 --- a/arch/arm/core/cortex_a_r/thread.c +++ b/arch/arm/core/cortex_a_r/thread.c @@ -125,6 +125,13 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * initial values in all other registers/thread entries are * irrelevant. */ +#if defined(CONFIG_USE_SWITCH) + extern void z_arm_cortex_ar_exit_exc(void); + thread->switch_handle = thread; + /* thread birth happens through the exception return path */ + thread->arch.exception_depth = 1; + thread->callee_saved.lr = (uint32_t)z_arm_cortex_ar_exit_exc; +#endif } #if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) \ diff --git a/arch/arm/core/cortex_a_r/vector_table.S b/arch/arm/core/cortex_a_r/vector_table.S index 971f90240c8..8c1060e6122 100644 --- a/arch/arm/core/cortex_a_r/vector_table.S +++ b/arch/arm/core/cortex_a_r/vector_table.S @@ -13,6 +13,8 @@ #include #include #include "vector_table.h" +#include "offsets_short.h" +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -28,4 +30,28 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) #else ldr pc, =z_irq_spurious #endif +#ifndef CONFIG_USE_SWITCH ldr pc, =z_arm_nmi /* FIQ offset 0x1c */ +#else + ldr pc,=z_irq_spurious +#endif + + +#ifdef CONFIG_USE_SWITCH +GTEXT(z_arm_cortex_ar_exit_exc) +SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc) + + /* decrement exception depth */ + get_cpu r2 + ldrb r1, [r2, #_cpu_offset_to_exc_depth] + sub r1, r1, #1 + strb r1, [r2, #_cpu_offset_to_exc_depth] + + /* + * Restore r0-r3, r12, lr, lr_und and spsr_und from the exception stack + * and return to the current thread. + */ + ldmia sp, {r0-r3, r12, lr}^ + add sp, #24 + rfeia sp! +#endif diff --git a/arch/arm/core/offsets/offsets_aarch32.c b/arch/arm/core/offsets/offsets_aarch32.c index 1eb63bec54f..4399377134d 100644 --- a/arch/arm/core/offsets/offsets_aarch32.c +++ b/arch/arm/core/offsets/offsets_aarch32.c @@ -32,6 +32,11 @@ GEN_OFFSET_SYM(_thread_arch_t, basepri); GEN_OFFSET_SYM(_thread_arch_t, swap_return_value); +#if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R) +GEN_OFFSET_SYM(_thread_arch_t, exception_depth); +GEN_OFFSET_SYM(_cpu_arch_t, exc_depth); +#endif + #if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE) GEN_OFFSET_SYM(_thread_arch_t, mode); #endif diff --git a/arch/arm/include/cortex_a_r/exc.h b/arch/arm/include/cortex_a_r/exc.h index afeae801063..6cddaa1c72c 100644 --- a/arch/arm/include/cortex_a_r/exc.h +++ b/arch/arm/include/cortex_a_r/exc.h @@ -40,7 +40,7 @@ static ALWAYS_INLINE bool arch_is_in_isr(void) static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) { - return (arch_curr_cpu()->nested > 1U) ? (true) : (false); + return (arch_curr_cpu()->arch.exc_depth > 1U) ? (true) : (false); } #if defined(CONFIG_USERSPACE) @@ -54,7 +54,9 @@ static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const z_arch_esf_t } #endif +#ifndef CONFIG_USE_SWITCH extern void z_arm_cortex_r_svc(void); +#endif #ifdef __cplusplus } diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h index b62b4bbf816..88f631ff4b4 100644 --- a/arch/arm/include/cortex_a_r/kernel_arch_func.h +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -30,12 +30,30 @@ static ALWAYS_INLINE void arch_kernel_init(void) { } +#ifndef CONFIG_USE_SWITCH + static ALWAYS_INLINE void arch_thread_return_value_set(struct k_thread *thread, unsigned int value) { thread->arch.swap_return_value = value; } +#else + +static ALWAYS_INLINE void arch_switch(void *switch_to, void **switched_from) +{ + extern void z_arm_context_switch(struct k_thread *new, + struct k_thread *old); + + struct k_thread *new = switch_to; + struct k_thread *old = CONTAINER_OF(switched_from, struct k_thread, + switch_handle); + + z_arm_context_switch(new, old); +} + +#endif + extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3, uint32_t stack_end, diff --git a/arch/arm/include/offsets_short_arch.h b/arch/arm/include/offsets_short_arch.h index 78a2607655c..4ceb1fc3f7a 100644 --- a/arch/arm/include/offsets_short_arch.h +++ b/arch/arm/include/offsets_short_arch.h @@ -23,6 +23,14 @@ #define _thread_offset_to_preempt_float \ (___thread_t_arch_OFFSET + ___thread_arch_t_preempt_float_OFFSET) +#if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R) +#define _thread_offset_to_exception_depth \ + (___thread_t_arch_OFFSET + ___thread_arch_t_exception_depth_OFFSET) + +#define _cpu_offset_to_exc_depth \ + (___cpu_t_arch_OFFSET + ___cpu_arch_t_exc_depth_OFFSET) +#endif + #if defined(CONFIG_USERSPACE) || defined(CONFIG_FPU_SHARING) #define _thread_offset_to_mode \ (___thread_t_arch_OFFSET + ___thread_arch_t_mode_OFFSET) diff --git a/include/zephyr/arch/arm/structs.h b/include/zephyr/arch/arm/structs.h new file mode 100644 index 00000000000..4fbf588c5cd --- /dev/null +++ b/include/zephyr/arch/arm/structs.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARM_STRUCTS_H_ +#define ZEPHYR_INCLUDE_ARM_STRUCTS_H_ + +#include + +#if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R) +/* Per CPU architecture specifics */ +struct _cpu_arch { + int8_t exc_depth; +}; + +#else + +/* Default definitions when no architecture specific definitions exist. */ + +/* Per CPU architecture specifics (empty) */ +struct _cpu_arch { +#ifdef __cplusplus + /* This struct will have a size 0 in C which is not allowed in C++ (it'll have a size 1). To + * prevent this, we add a 1 byte dummy variable. + */ + uint8_t dummy; +#endif +}; + +#endif + +#endif /* ZEPHYR_INCLUDE_ARM_STRUCTS_H_ */ diff --git a/include/zephyr/arch/arm/thread.h b/include/zephyr/arch/arm/thread.h index 7ddd574c579..b4d34b137cb 100644 --- a/include/zephyr/arch/arm/thread.h +++ b/include/zephyr/arch/arm/thread.h @@ -32,6 +32,9 @@ struct _callee_saved { uint32_t v7; /* r10 */ uint32_t v8; /* r11 */ uint32_t psp; /* r13 */ +#ifdef CONFIG_USE_SWITCH + uint32_t lr; /* lr */ +#endif }; typedef struct _callee_saved _callee_saved_t; @@ -74,6 +77,10 @@ struct _thread_arch { struct _preempt_float preempt_float; #endif +#if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R) + int8_t exception_depth; +#endif + #if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE) /* * Status variable holding several thread status flags diff --git a/include/zephyr/arch/structs.h b/include/zephyr/arch/structs.h index 570c3959b7e..703ec81f889 100644 --- a/include/zephyr/arch/structs.h +++ b/include/zephyr/arch/structs.h @@ -27,6 +27,8 @@ #include #elif defined(CONFIG_RISCV) #include +#elif defined(CONFIG_ARM) +#include #else /* Default definitions when no architecture specific definitions exist. */ diff --git a/soc/arm/arm/fvp_aemv8r_aarch32/Kconfig.soc b/soc/arm/arm/fvp_aemv8r_aarch32/Kconfig.soc index a7f2131e065..6993cfe715a 100644 --- a/soc/arm/arm/fvp_aemv8r_aarch32/Kconfig.soc +++ b/soc/arm/arm/fvp_aemv8r_aarch32/Kconfig.soc @@ -10,7 +10,7 @@ config SOC_FVP_AEMV8R_AARCH32 select CPU_CORTEX_R52 select CPU_HAS_ARM_MPU select CPU_HAS_MPU - select VFP_DP_D32_FP16_FMAC + select VFP_DP_D32_FP16_FMAC if !USE_SWITCH select GIC_V3 select GIC_SINGLE_SECURITY_STATE select PLATFORM_SPECIFIC_INIT From e898dafb38b03a599b01de58587a0c913159174c Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 13 Jul 2023 13:06:14 +0800 Subject: [PATCH 3128/4498] arch: cortex_ar: Introduce SMP support into Cortex-A/R aarch32 This commit introduces SMP support into Cortex-A/R aarch32 architecture. For now, this only supports multiple core start together and only allow one CPU initialize system as primary core, others loop at the beginning as the secondary cores and wait for wake up. Signed-off-by: Huifeng Zhang --- arch/arm/core/cortex_a_r/CMakeLists.txt | 1 + arch/arm/core/cortex_a_r/Kconfig | 4 + arch/arm/core/cortex_a_r/boot.h | 30 ++ arch/arm/core/cortex_a_r/macro_priv.inc | 10 + arch/arm/core/cortex_a_r/reset.S | 56 +++- arch/arm/core/cortex_a_r/smp.c | 264 ++++++++++++++++++ arch/arm/core/cortex_a_r/stacks.c | 16 +- .../zephyr/arch/arm/cortex_a_r/lib_helpers.h | 3 + 8 files changed, 372 insertions(+), 12 deletions(-) create mode 100644 arch/arm/core/cortex_a_r/boot.h create mode 100644 arch/arm/core/cortex_a_r/smp.c diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index 74dc266ad08..d4e18a614f0 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources( prep_c.c thread.c cpu_idle.S + smp.c ) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) diff --git a/arch/arm/core/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig index 48dc04834ff..3ec57cc408e 100644 --- a/arch/arm/core/cortex_a_r/Kconfig +++ b/arch/arm/core/cortex_a_r/Kconfig @@ -130,6 +130,7 @@ config ARMV7_R_FP config AARCH32_ARMV8_R bool select ATOMIC_OPERATIONS_BUILTIN + select SCHED_IPI_SUPPORTED if SMP help This option signifies the use of an ARMv8-R AArch32 processor implementation. @@ -188,3 +189,6 @@ config ICACHE_LINE_SIZE default 32 endif # CPU_AARCH32_CORTEX_R + +config TEST_EXTRA_STACK_SIZE + default 1024 if SMP diff --git a/arch/arm/core/cortex_a_r/boot.h b/arch/arm/core/cortex_a_r/boot.h new file mode 100644 index 00000000000..7eeba8b6ada --- /dev/null +++ b/arch/arm/core/cortex_a_r/boot.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for boot code + */ + +#ifndef _BOOT_H_ +#define _BOOT_H_ + +#ifndef _ASMLANGUAGE + +extern void *_vector_table[]; +extern void __start(void); + +#endif /* _ASMLANGUAGE */ + +/* Offsets into the boot_params structure */ +#define BOOT_PARAM_MPID_OFFSET 0 +#define BOOT_PARAM_IRQ_SP_OFFSET 4 +#define BOOT_PARAM_FIQ_SP_OFFSET 8 +#define BOOT_PARAM_ABT_SP_OFFSET 12 +#define BOOT_PARAM_UDF_SP_OFFSET 16 +#define BOOT_PARAM_SVC_SP_OFFSET 20 +#define BOOT_PARAM_SYS_SP_OFFSET 24 + +#endif /* _BOOT_H_ */ diff --git a/arch/arm/core/cortex_a_r/macro_priv.inc b/arch/arm/core/cortex_a_r/macro_priv.inc index 6079c92ab5f..e02433692f9 100644 --- a/arch/arm/core/cortex_a_r/macro_priv.inc +++ b/arch/arm/core/cortex_a_r/macro_priv.inc @@ -8,6 +8,16 @@ #include +/* + * Get CPU id + */ + +.macro get_cpu_id rreg0 + /* Read MPIDR register */ + mrc p15, 0, \rreg0, c0, c0, 5 + ubfx \rreg0, \rreg0, #0, #24 +.endm + .macro get_cpu rreg0 /* * Get CPU pointer. diff --git a/arch/arm/core/cortex_a_r/reset.S b/arch/arm/core/cortex_a_r/reset.S index c72f0814c7a..ff3c35e0f18 100644 --- a/arch/arm/core/cortex_a_r/reset.S +++ b/arch/arm/core/cortex_a_r/reset.S @@ -18,6 +18,8 @@ #include #include #include "vector_table.h" +#include "boot.h" +#include "macro_priv.inc" _ASM_FILE_PROLOGUE @@ -76,6 +78,7 @@ SECTION_SUBSEC_FUNC(TEXT, _reset_section, __start) EL1_Reset_Handler: #endif + #if defined(CONFIG_DCLS) /* * Initialise CPU registers to a defined state if the processor is @@ -196,33 +199,72 @@ EL1_Reset_Handler: #endif /* CONFIG_DCLS */ + ldr r0, =arm_cpu_boot_params +#if CONFIG_MP_MAX_NUM_CPUS > 1 + get_cpu_id r1 + + ldrex r2, [r0, #BOOT_PARAM_MPID_OFFSET] + cmp r2, #-1 + bne 1f + strex r3, r1, [r0, #BOOT_PARAM_MPID_OFFSET] + cmp r3, #0 + beq _primary_core + +1: + dmb ld + ldr r2, [r0, #BOOT_PARAM_MPID_OFFSET] + cmp r1, r2 + bne 1b + + /* we can now move on */ + ldr r4, =z_arm_secondary_start + ldr r5, [r0, #BOOT_PARAM_FIQ_SP_OFFSET] + ldr r6, [r0, #BOOT_PARAM_IRQ_SP_OFFSET] + ldr r7, [r0, #BOOT_PARAM_ABT_SP_OFFSET] + ldr r8, [r0, #BOOT_PARAM_UDF_SP_OFFSET] + ldr r9, [r0, #BOOT_PARAM_SVC_SP_OFFSET] + ldr r10, [r0, #BOOT_PARAM_SYS_SP_OFFSET] + b 2f + +_primary_core: +#endif + + ldr r4, =z_arm_prep_c + ldr r5, =(z_arm_fiq_stack + CONFIG_ARMV7_FIQ_STACK_SIZE) + ldr r6, =(z_interrupt_stacks + CONFIG_ISR_STACK_SIZE) + ldr r7, =(z_arm_abort_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE) + ldr r8, =(z_arm_undef_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE) + ldr r9, =(z_arm_svc_stack + CONFIG_ARMV7_SVC_STACK_SIZE) + ldr r10, =(z_arm_sys_stack + CONFIG_ARMV7_SYS_STACK_SIZE) + +2: /* * Configure stack. */ /* FIQ mode stack */ msr CPSR_c, #(MODE_FIQ | I_BIT | F_BIT) - ldr sp, =(z_arm_fiq_stack + CONFIG_ARMV7_FIQ_STACK_SIZE) + mov sp, r5 /* IRQ mode stack */ msr CPSR_c, #(MODE_IRQ | I_BIT | F_BIT) - ldr sp, =(z_interrupt_stacks + CONFIG_ISR_STACK_SIZE) + mov sp, r6 /* ABT mode stack */ msr CPSR_c, #(MODE_ABT | I_BIT | F_BIT) - ldr sp, =(z_arm_abort_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE) + mov sp, r7 /* UND mode stack */ msr CPSR_c, #(MODE_UND | I_BIT | F_BIT) - ldr sp, =(z_arm_undef_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE) + mov sp, r8 /* SVC mode stack */ msr CPSR_c, #(MODE_SVC | I_BIT | F_BIT) - ldr sp, =(z_arm_svc_stack + CONFIG_ARMV7_SVC_STACK_SIZE) + mov sp, r9 /* SYS mode stack */ msr CPSR_c, #(MODE_SYS | I_BIT | F_BIT) - ldr sp, =(z_arm_sys_stack + CONFIG_ARMV7_SYS_STACK_SIZE) + mov sp, r10 #if defined(CONFIG_PLATFORM_SPECIFIC_INIT) /* Execute platform-specific initialisation if applicable */ @@ -238,4 +280,4 @@ EL1_Reset_Handler: bl z_arm_tcm_disable_ecc #endif - b z_arm_prep_c + bx r4 diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c new file mode 100644 index 00000000000..2aeb36c1735 --- /dev/null +++ b/arch/arm/core/cortex_a_r/smp.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "boot.h" +#include "zephyr/cache.h" +#include "zephyr/kernel/thread_stack.h" +#include "zephyr/toolchain/gcc.h" + +#define INV_MPID UINT32_MAX + +#define SGI_SCHED_IPI 0 +#define SGI_MMCFG_IPI 1 +#define SGI_FPU_IPI 2 + +K_KERNEL_PINNED_STACK_ARRAY_DECLARE(z_interrupt_stacks, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ISR_STACK_SIZE); + +K_KERNEL_STACK_ARRAY_DECLARE(z_arm_fiq_stack, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_FIQ_STACK_SIZE); + +K_KERNEL_STACK_ARRAY_DECLARE(z_arm_abort_stack, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_EXCEPTION_STACK_SIZE); + +K_KERNEL_STACK_ARRAY_DECLARE(z_arm_undef_stack, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_EXCEPTION_STACK_SIZE); + +K_KERNEL_STACK_ARRAY_DECLARE(z_arm_svc_stack, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_SVC_STACK_SIZE); + +K_KERNEL_STACK_ARRAY_DECLARE(z_arm_sys_stack, + CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_SVC_STACK_SIZE); + +struct boot_params { + uint32_t mpid; + char *irq_sp; + char *fiq_sp; + char *abt_sp; + char *udf_sp; + char *svc_sp; + char *sys_sp; + arch_cpustart_t fn; + void *arg; + int cpu_num; +}; + +/* Offsets used in reset.S */ +BUILD_ASSERT(offsetof(struct boot_params, mpid) == BOOT_PARAM_MPID_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, irq_sp) == BOOT_PARAM_IRQ_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, fiq_sp) == BOOT_PARAM_FIQ_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, abt_sp) == BOOT_PARAM_ABT_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, udf_sp) == BOOT_PARAM_UDF_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, svc_sp) == BOOT_PARAM_SVC_SP_OFFSET); +BUILD_ASSERT(offsetof(struct boot_params, sys_sp) == BOOT_PARAM_SYS_SP_OFFSET); + +volatile struct boot_params arm_cpu_boot_params = { + .mpid = -1, + .irq_sp = (char *)(z_interrupt_stacks + CONFIG_ISR_STACK_SIZE), + .fiq_sp = (char *)(z_arm_fiq_stack + CONFIG_ARMV7_FIQ_STACK_SIZE), + .abt_sp = (char *)(z_arm_abort_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE), + .udf_sp = (char *)(z_arm_undef_stack + CONFIG_ARMV7_EXCEPTION_STACK_SIZE), + .svc_sp = (char *)(z_arm_svc_stack + CONFIG_ARMV7_SVC_STACK_SIZE), + .sys_sp = (char *)(z_arm_sys_stack + CONFIG_ARMV7_SYS_STACK_SIZE), +}; + +static const uint32_t cpu_node_list[] = { + DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,))}; + +/* cpu_map saves the maping of core id and mpid */ +static uint32_t cpu_map[CONFIG_MP_MAX_NUM_CPUS] = { + [0 ... (CONFIG_MP_MAX_NUM_CPUS - 1)] = INV_MPID +}; + +#ifdef CONFIG_ARM_MPU +extern void z_arm_mpu_init(void); +extern void z_arm_configure_static_mpu_regions(void); +#elif defined(CONFIG_ARM_AARCH32_MMU) +extern int z_arm_mmu_init(void); +#endif + +/* Called from Zephyr initialization */ +void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) +{ + int cpu_count, i, j; + uint32_t cpu_mpid = 0; + uint32_t master_core_mpid; + + /* Now it is on master core */ + __ASSERT(arch_curr_cpu()->id == 0, ""); + master_core_mpid = MPIDR_TO_CORE(GET_MPIDR()); + + cpu_count = ARRAY_SIZE(cpu_node_list); + __ASSERT(cpu_count == CONFIG_MP_MAX_NUM_CPUS, + "The count of CPU Cores nodes in dts is not equal to CONFIG_MP_MAX_NUM_CPUS\n"); + + for (i = 0, j = 0; i < cpu_count; i++) { + if (cpu_node_list[i] == master_core_mpid) { + continue; + } + if (j == cpu_num - 1) { + cpu_mpid = cpu_node_list[i]; + break; + } + j++; + } + if (i == cpu_count) { + printk("Can't find CPU Core %d from dts and failed to boot it\n", cpu_num); + return; + } + + /* Pass stack address to secondary core */ + arm_cpu_boot_params.irq_sp = Z_KERNEL_STACK_BUFFER(stack) + sz; + arm_cpu_boot_params.fiq_sp = Z_KERNEL_STACK_BUFFER(z_arm_fiq_stack[cpu_num]) + + CONFIG_ARMV7_FIQ_STACK_SIZE; + arm_cpu_boot_params.abt_sp = Z_KERNEL_STACK_BUFFER(z_arm_abort_stack[cpu_num]) + + CONFIG_ARMV7_EXCEPTION_STACK_SIZE; + arm_cpu_boot_params.udf_sp = Z_KERNEL_STACK_BUFFER(z_arm_undef_stack[cpu_num]) + + CONFIG_ARMV7_EXCEPTION_STACK_SIZE; + arm_cpu_boot_params.svc_sp = Z_KERNEL_STACK_BUFFER(z_arm_svc_stack[cpu_num]) + + CONFIG_ARMV7_SVC_STACK_SIZE; + arm_cpu_boot_params.sys_sp = Z_KERNEL_STACK_BUFFER(z_arm_sys_stack[cpu_num]) + + CONFIG_ARMV7_SYS_STACK_SIZE; + + arm_cpu_boot_params.fn = fn; + arm_cpu_boot_params.arg = arg; + arm_cpu_boot_params.cpu_num = cpu_num; + + /* store mpid last as this is our synchronization point */ + arm_cpu_boot_params.mpid = cpu_mpid; + + barrier_dsync_fence_full(); + sys_cache_data_invd_range( + (void *)&arm_cpu_boot_params, + sizeof(arm_cpu_boot_params)); + + /*! TODO: Support PSCI + * \todo Support PSCI + */ + + /* Wait secondary cores up, see z_arm64_secondary_start */ + while (arm_cpu_boot_params.fn) { + wfe(); + } + + cpu_map[cpu_num] = cpu_mpid; + + printk("Secondary CPU core %d (MPID:%#x) is up\n", cpu_num, cpu_mpid); +} + +/* the C entry of secondary cores */ +void z_arm_secondary_start(void) +{ + int cpu_num = arm_cpu_boot_params.cpu_num; + arch_cpustart_t fn; + void *arg; + + __ASSERT(arm_cpu_boot_params.mpid == MPIDR_TO_CORE(GET_MPIDR()), ""); + + /* Initialize tpidrro_el0 with our struct _cpu instance address */ + write_tpidruro((uintptr_t)&_kernel.cpus[cpu_num]); + +#ifdef CONFIG_ARM_MPU + + /*! TODO: Unify mpu and mmu initialization function + * \todo Unify mpu and mmu initialization function + */ + z_arm_mpu_init(); + z_arm_configure_static_mpu_regions(); +#elif defined(CONFIG_ARM_AARCH32_MMU) + z_arm_mmu_init(); +#endif + +#ifdef CONFIG_SMP + arm_gic_secondary_init(); + + irq_enable(SGI_SCHED_IPI); + + /*! TODO: FPU irq + * \todo FPU irq + */ +#endif + + fn = arm_cpu_boot_params.fn; + arg = arm_cpu_boot_params.arg; + barrier_dsync_fence_full(); + + /* + * Secondary core clears .fn to announce its presence. + * Primary core is polling for this. We no longer own + * arm_cpu_boot_params afterwards. + */ + arm_cpu_boot_params.fn = NULL; + barrier_dsync_fence_full(); + + sev(); + + fn(arg); +} + +#ifdef CONFIG_SMP + +static void broadcast_ipi(unsigned int ipi) +{ + uint32_t mpidr = MPIDR_TO_CORE(GET_MPIDR()); + + /* + * Send SGI to all cores except itself + */ + unsigned int num_cpus = arch_num_cpus(); + + for (int i = 0; i < num_cpus; i++) { + uint32_t target_mpidr = cpu_map[i]; + uint8_t aff0; + + if (mpidr == target_mpidr || mpidr == INV_MPID) { + continue; + } + + aff0 = MPIDR_AFFLVL(target_mpidr, 0); + gic_raise_sgi(ipi, (uint64_t)target_mpidr, 1 << aff0); + } +} + +void sched_ipi_handler(const void *unused) +{ + ARG_UNUSED(unused); + + z_sched_ipi(); +} + +/* arch implementation of sched_ipi */ +void arch_sched_ipi(void) +{ + broadcast_ipi(SGI_SCHED_IPI); +} + +static int arm_smp_init(void) +{ + cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR()); + + /* + * SGI0 is use for sched ipi, this might be changed to use Kconfig + * option + */ + IRQ_CONNECT(SGI_SCHED_IPI, IRQ_DEFAULT_PRIORITY, sched_ipi_handler, NULL, 0); + irq_enable(SGI_SCHED_IPI); + + return 0; +} + +SYS_INIT(arm_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + +#endif diff --git a/arch/arm/core/cortex_a_r/stacks.c b/arch/arm/core/cortex_a_r/stacks.c index 29a5062e299..0691595c359 100644 --- a/arch/arm/core/cortex_a_r/stacks.c +++ b/arch/arm/core/cortex_a_r/stacks.c @@ -4,16 +4,22 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "zephyr/kernel/thread_stack.h" #include #include #include #include -K_KERNEL_STACK_DEFINE(z_arm_fiq_stack, CONFIG_ARMV7_FIQ_STACK_SIZE); -K_KERNEL_STACK_DEFINE(z_arm_abort_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); -K_KERNEL_STACK_DEFINE(z_arm_undef_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); -K_KERNEL_STACK_DEFINE(z_arm_svc_stack, CONFIG_ARMV7_SVC_STACK_SIZE); -K_KERNEL_STACK_DEFINE(z_arm_sys_stack, CONFIG_ARMV7_SYS_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DEFINE(z_arm_fiq_stack, CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_FIQ_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DEFINE(z_arm_abort_stack, CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_EXCEPTION_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DEFINE(z_arm_undef_stack, CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_EXCEPTION_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DEFINE(z_arm_svc_stack, CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_SVC_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DEFINE(z_arm_sys_stack, CONFIG_MP_MAX_NUM_CPUS, + CONFIG_ARMV7_SYS_STACK_SIZE); #if defined(CONFIG_INIT_STACKS) void z_arm_init_stacks(void) diff --git a/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h b/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h index 209c4dd7325..7b89ddf515c 100644 --- a/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h +++ b/include/zephyr/arch/arm/cortex_a_r/lib_helpers.h @@ -99,5 +99,8 @@ MAKE_REG_HELPER(ICC_IGRPEN1_EL1, 0, 12, 12, 7); #define write_sysreg(val, reg) write_##reg(val) #define read_sysreg(reg) read_##reg() +#define sev() __asm__ volatile("sev" : : : "memory") +#define wfe() __asm__ volatile("wfe" : : : "memory") + #endif /* !_ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_A_R_LIB_HELPERS_H_ */ From 0be647ccaab9ecd8a4f476dec6da21fef3b3572a Mon Sep 17 00:00:00 2001 From: Huifeng Zhang Date: Thu, 13 Jul 2023 13:14:57 +0800 Subject: [PATCH 3129/4498] boards: fvp_baser_aemv8r_aarch32: Add fvp_baser_aemv8r_aarch32_smp board This commit add a new board named 'fvp_baser_aemv8r_aarch32_smp' Signed-off-by: Huifeng Zhang --- .../fvp_baser_aemv8r_aarch32_smp.dts | 8 +++++ .../fvp_baser_aemv8r_aarch32_smp.yaml | 14 ++++++++ .../fvp_baser_aemv8r_aarch32_smp_defconfig | 32 +++++++++++++++++++ tests/subsys/zbus/integration/testcase.yaml | 1 + 4 files changed, 55 insertions(+) create mode 100644 boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.dts create mode 100644 boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.yaml create mode 100644 boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp_defconfig diff --git a/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.dts b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.dts new file mode 100644 index 00000000000..cdc0a933ba3 --- /dev/null +++ b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.dts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "fvp_baser_aemv8r_aarch32.dts" diff --git a/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.yaml b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.yaml new file mode 100644 index 00000000000..08d01e51ec4 --- /dev/null +++ b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +identifier: fvp_baser_aemv8r_aarch32_smp +name: FVP Emulation FVP_BaseR_AEMv8R AArch32 +arch: arm +type: sim +toolchain: + - zephyr + - cross-compile +ram: 2048 +flash: 64 +testing: + timeout_multiplier: 25 diff --git a/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp_defconfig b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp_defconfig new file mode 100644 index 00000000000..3f7f981b46e --- /dev/null +++ b/boards/arm/fvp_baser_aemv8r_aarch32/fvp_baser_aemv8r_aarch32_smp_defconfig @@ -0,0 +1,32 @@ +# Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_FVP_AEMV8R_AARCH32=y +CONFIG_SOC_FVP_AEMV8R_AARCH32=y +CONFIG_BOARD_FVP_BASER_AEMV8R_AARCH32=y +CONFIG_ARM_MPU=y + +CONFIG_ISR_STACK_SIZE=1024 +CONFIG_THREAD_STACK_INFO=y + +# Enable Timer and Sys clock +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_ARM_ARCH_TIMER=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable serial port +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_CACHE_MANAGEMENT=y + +CONFIG_USE_SWITCH=y +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=4 + +CONFIG_DCACHE=n diff --git a/tests/subsys/zbus/integration/testcase.yaml b/tests/subsys/zbus/integration/testcase.yaml index 2f36fa057c3..ae918fcfb0f 100644 --- a/tests/subsys/zbus/integration/testcase.yaml +++ b/tests/subsys/zbus/integration/testcase.yaml @@ -4,6 +4,7 @@ tests: - qemu_cortex_a9 - hifive_unleashed - fvp_base_revc_2xaemv8a_smp_ns + - fvp_baser_aemv8r_aarch32_smp tags: zbus integration_platforms: - native_posix From 7f19764d9e09bb1e4cf02f44f487ac69dc6da88f Mon Sep 17 00:00:00 2001 From: Emil Lindqvist Date: Thu, 2 Nov 2023 08:44:48 +0100 Subject: [PATCH 3130/4498] kconfig: name choices to make changable in outside Kconfigs This commit names a couple of choices to allow the default value to be overridden by Kconfig files out of tree Signed-off-by: Emil Lindqvist --- drivers/sensor/vcnl4040/Kconfig | 2 +- subsys/net/ip/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/vcnl4040/Kconfig b/drivers/sensor/vcnl4040/Kconfig index 5973316ca6a..a4e6be8d715 100644 --- a/drivers/sensor/vcnl4040/Kconfig +++ b/drivers/sensor/vcnl4040/Kconfig @@ -21,7 +21,7 @@ config VCNL4040_ENABLE_ALS config VCNL4040_TRIGGER bool -choice +choice VCNL4040_TRIGGER prompt "Trigger mode" default VCNL4040_TRIGGER_NONE help diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index dd057d46760..b8e51e09f64 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -863,7 +863,7 @@ config NET_HEADERS_ALWAYS_CONTIGUOUS # If we are running network tests found in tests/net, then the NET_TEST is # set and in that case we default to Dummy L2 layer as typically the tests # use that by default. -choice +choice NET_DEFAULT_IF prompt "Default Network Interface" default NET_DEFAULT_IF_DUMMY if NET_TEST default NET_DEFAULT_IF_FIRST From 70932c5be2ac4b3243dd896001e0609c211ce879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 6 Nov 2023 15:29:00 +0100 Subject: [PATCH 3131/4498] drivers: serial: nrfx_uarte: Add const to the isr function argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISR function prototype requires const void *. Signed-off-by: Krzysztof Chruściński --- drivers/serial/uart_nrfx_uarte.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index b70af538abf..dc577ea9fc4 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -205,7 +205,7 @@ static void endtx_isr(const struct device *dev) * * @param arg Argument to ISR. */ -static void uarte_nrfx_isr_int(void *arg) +static void uarte_nrfx_isr_int(const void *arg) { const struct device *dev = arg; const struct uarte_nrfx_config *config = dev->config; From 0a6fc6f70a25cc0859165b5ac7e04115c8c4322c Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 6 Nov 2023 12:17:11 +0800 Subject: [PATCH 3132/4498] soc: intel_adsp: cavs: fix dts memory address format Fix the following compilation warning: ``` Warning (unit_address_format): /memory@0xb0000000: \ unit name should not have leading "0x" ``` Signed-off-by: Yong Cong Sin --- dts/xtensa/intel/intel_adsp_cavs25.dtsi | 2 +- dts/xtensa/intel/intel_adsp_cavs25_tgph.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/xtensa/intel/intel_adsp_cavs25.dtsi b/dts/xtensa/intel/intel_adsp_cavs25.dtsi index 1039a00b094..36ad7afa218 100644 --- a/dts/xtensa/intel/intel_adsp_cavs25.dtsi +++ b/dts/xtensa/intel/intel_adsp_cavs25.dtsi @@ -98,7 +98,7 @@ wovcro-supported; }; - IMR1: memory@0xb0000000 { + IMR1: memory@b0000000 { compatible = "intel,adsp-imr"; reg = <0xB0000000 DT_SIZE_M(16)>; block-size = <0x1000>; diff --git a/dts/xtensa/intel/intel_adsp_cavs25_tgph.dtsi b/dts/xtensa/intel/intel_adsp_cavs25_tgph.dtsi index a03605df515..facb914904c 100644 --- a/dts/xtensa/intel/intel_adsp_cavs25_tgph.dtsi +++ b/dts/xtensa/intel/intel_adsp_cavs25_tgph.dtsi @@ -84,7 +84,7 @@ wovcro-supported; }; - IMR1: memory@0xb0000000 { + IMR1: memory@b0000000 { compatible = "intel,adsp-imr"; reg = <0xB0000000 DT_SIZE_M(16)>; block-size = <0x1000>; From 9b9a74e70ce0b02ded4311b2143e3a07fb7deb07 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 22 Sep 2023 22:17:54 +0000 Subject: [PATCH 3133/4498] drivers: display: hx8394: fix TEAR and DPHYCMD0 settings Fix settings for TEAR and DPHYCMD0 to match initialization data provided by MCUX SDK driver. The following fixes were needed: - Tear effect signal should only be sent at the VBLANK interval, so TEON should be set to 0x0 - DPHYCMD0 LP-RX VHYS trimming was incorrectly being set to 37mV, when it should be set to 66mV (the default value) These changes resolve some flickering and blooming that occasionally occurred during initialization Signed-off-by: Daniel DeGrasse --- drivers/display/display_hx8394.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/display/display_hx8394.c b/drivers/display/display_hx8394.c index 9a71197b481..d5fecfb4fe1 100644 --- a/drivers/display/display_hx8394.c +++ b/drivers/display/display_hx8394.c @@ -31,7 +31,7 @@ struct hx8394_config { #define HX8394_MIPI_LP_CD_DIS BIT(5) #define HX8394_MIPI_TA_6TL 0x3 #define HX8394_MIPI_DPHYCMD_LPRX_8NS 0x40 -#define HX8394_MIPI_DPHYCMD_LPRX_66mV 0x10 +#define HX8394_MIPI_DPHYCMD_LPRX_66mV 0x20 #define HX8394_MIPI_DPHYCMD_LPTX_SRLIM 0x8 #define HX8394_MIPI_DPHYCMD_LDO_1_55V 0x60 #define HX8394_MIPI_DPHYCMD_HSRX_7X 0x8 @@ -404,7 +404,7 @@ const uint8_t hx8394_bank0[] = { const uint8_t hx8394_cmd3[] = {0xC6U, 0xEDU}; -const uint8_t tear_config[] = {HX8394_SET_TEAR, HX8394_TEAR_VBLANK | 0x3}; +const uint8_t tear_config[] = {HX8394_SET_TEAR, HX8394_TEAR_VBLANK}; static int hx8394_write(const struct device *dev, const uint16_t x, const uint16_t y, From c5cd8865187a31e2953e88faf1071d9e6aaade1b Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Sun, 5 Nov 2023 13:25:50 +0000 Subject: [PATCH 3134/4498] test: spinlock: cleanup assertion Don't double check on assertion condition. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- tests/kernel/spinlock/src/spinlock_fairness.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/kernel/spinlock/src/spinlock_fairness.c b/tests/kernel/spinlock/src/spinlock_fairness.c index 5e5d9c41232..d61acde2259 100644 --- a/tests/kernel/spinlock/src/spinlock_fairness.c +++ b/tests/kernel/spinlock/src/spinlock_fairness.c @@ -146,11 +146,9 @@ ZTEST(spinlock, test_spinlock_fairness) /* Verify spinlock acquisition fairness */ for (uint8_t core_id = 0; core_id < CORES_NUM; core_id++) { - if (spinlock_grabbed[core_id] < FAIRNESS_TEST_CYCLES_PER_CORE) { - zassert_false(spinlock_grabbed[core_id] < FAIRNESS_TEST_CYCLES_PER_CORE, - "CPU%d starved on a spinlock: acquired %u times, expected %u\n", - core_id, spinlock_grabbed[core_id], FAIRNESS_TEST_CYCLES_PER_CORE); - } + zassert_false(spinlock_grabbed[core_id] < FAIRNESS_TEST_CYCLES_PER_CORE, + "CPU%d starved on a spinlock: acquired %u times, expected %u\n", + core_id, spinlock_grabbed[core_id], FAIRNESS_TEST_CYCLES_PER_CORE); } } From b0d0f60389ef689ff5850c09522e2d2cf321f780 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 31 Oct 2023 13:55:57 +0200 Subject: [PATCH 3135/4498] net: shell: Print device and wifi information for iface cmd If the interface is WiFi one, then print information about it. Also the device information is useful to know so print device name corresponding to the network interface. Signed-off-by: Jukka Rissanen --- subsys/net/lib/shell/iface.c | 3 +++ subsys/net/lib/shell/net_shell.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index a072a715b1c..89983bd4839 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -243,6 +243,9 @@ static void iface_cb(struct net_if *iface, void *user_data) PR("MTU : %d\n", net_if_get_mtu(iface)); PR("Flags : %s\n", iface_flags2str(iface)); + PR("Device : %s (%p)\n", + net_if_get_device(iface) ? net_if_get_device(iface)->name : "", + net_if_get_device(iface)); #if defined(CONFIG_NET_L2_ETHERNET_MGMT) if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 81191c77c20..19bab12e029 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -18,6 +18,8 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include #include +#include + #include "common.h" #include "net_shell.h" @@ -142,6 +144,16 @@ const char *iface2str(struct net_if *iface, const char **extra) #ifdef CONFIG_NET_L2_ETHERNET if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + + if (eth_ctx->eth_if_type == L2_ETH_IF_TYPE_WIFI) { + if (extra) { + *extra = "===="; + } + + return "WiFi"; + } + if (extra) { *extra = "========"; } From 6ae52f00e08b864ddc7759658dfae877805eb132 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 31 Oct 2023 12:41:31 +0100 Subject: [PATCH 3136/4498] net: ieee802154_radio: Document requirements for Thread 1.2 features Mention which 15.4 radio features are required for advanced Thread 1.2 functionalities. Signed-off-by: Robert Lubos --- include/zephyr/net/ieee802154_radio.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 9c2aa3816e4..71519dfe839 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -622,6 +622,9 @@ enum ieee802154_tx_mode { * Transmit packet in the future, perform CCA before transmission. * * @note requires IEEE802154_HW_TXTIME capability. + * + * @note Required for Thread 1.2 Coordinated Sampled Listening feature + * (see Thread specification 1.2.0, ch. 3.2.6.3). */ IEEE802154_TX_MODE_TXTIME_CCA, @@ -699,7 +702,8 @@ enum ieee802154_config_type { * larger than the current frame counter associated with the same key, * see sections 8.2.2, 9.2.4 g/h) and 9.4.3. * - * @note Available in any interface operational state. + * @note Requires @ref IEEE802154_HW_TX_SEC capability and is available + * in any interface operational state. */ IEEE802154_CONFIG_MAC_KEYS, @@ -715,7 +719,8 @@ enum ieee802154_config_type { * Drivers SHALL return -EINVAL in case the configured frame counter * does not conform to this requirement. * - * @note Available in any interface operational state. + * @note Requires @ref IEEE802154_HW_TX_SEC capability and is available + * in any interface operational state. */ IEEE802154_CONFIG_FRAME_COUNTER, @@ -723,7 +728,8 @@ enum ieee802154_config_type { * Sets the current MAC frame counter value if the provided value is greater than * the current one. * - * @note Available in any interface operational state. + * @note Requires @ref IEEE802154_HW_TX_SEC capability and is available + * in any interface operational state. * * @warning This configuration option does not conform to the * requirements specified in #61227 as it is redundant with @ref @@ -777,6 +783,9 @@ enum ieee802154_config_type { * * @note requires @ref IEEE802154_HW_RXTIME capability and is available * in any interface operational state. + * + * @note Required for Thread 1.2 Coordinated Sampled Listening feature + * (see Thread specification 1.2.0, ch. 3.2.6.3). */ IEEE802154_CONFIG_RX_SLOT, @@ -906,6 +915,9 @@ enum ieee802154_config_type { * +--------------------- loop ---------+ * * @note Available in any interface operational state. + * + * @note Required for Thread 1.2 Coordinated Sampled Listening feature + * (see Thread specification 1.2.0, ch. 3.2.6.3). */ IEEE802154_CONFIG_CSL_PERIOD, @@ -957,6 +969,9 @@ enum ieee802154_config_type { * same clock (as in PTP). * * @note Available in any interface operational state. + * + * @note Required for Thread 1.2 Coordinated Sampled Listening feature + * (see Thread specification 1.2.0, ch. 3.2.6.3). */ IEEE802154_CONFIG_EXPECTED_RX_TIME, @@ -1033,6 +1048,12 @@ enum ieee802154_config_type { * @note requires @ref IEEE802154_HW_RX_TX_ACK capability and is * available in any interface operational state. Currently we only * support header IEs but that may change in the future. + * + * @note Required for Thread 1.2 Coordinated Sampled Listening feature + * (see Thread specification 1.2.0, ch. 3.2.6.3). + * + * @note Required for Thread 1.2 Link Metrics feature (see Thread + * specification 1.2.0, ch. 4.11.3.3). */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, From 30fe8702deaf86fa47b243f9ea3e38c5fa319a97 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sat, 4 Nov 2023 15:17:47 +1100 Subject: [PATCH 3137/4498] drivers: eeprom_emulator: fix compile warning Fixes compile warning: drivers/eeprom/eeprom_emulator.c:645:13: warning: 'rc' may be used uninitialized [-Wmaybe-uninitialized] 645 | int rc; Signed-off-by: Nick Ward --- drivers/eeprom/eeprom_emulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/eeprom/eeprom_emulator.c b/drivers/eeprom/eeprom_emulator.c index 822c9a7e2cf..0672e83f839 100644 --- a/drivers/eeprom/eeprom_emulator.c +++ b/drivers/eeprom/eeprom_emulator.c @@ -642,7 +642,7 @@ static int eeprom_emu_init(const struct device *dev) struct eeprom_emu_data *dev_data = dev->data; off_t offset; uint8_t buf[dev_config->flash_cbs]; - int rc; + int rc = 0; k_mutex_init(&dev_data->lock); if (!device_is_ready(dev_config->flash_dev)) { From ba7e6fa69f0bf95f79d6ec02d035dd0c3b7e72d9 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 30 Oct 2023 11:18:51 +0100 Subject: [PATCH 3138/4498] cmake: cleanup and simplify the standard include logic in Zephyr Several paths are checked for existence before added as global Zephyr include path. The existence check was needed because some tooling emit warnings on non-existing paths. Only few SoCs are using those pre-defined paths, yet this code runs for all SoCs. The principle originates back from Kbuild days, and with CMake it's more common and generally more visible to let the CMake code defining libraries to specify include paths. Furthermore it appears that several SoC implementation following the /include was unaware that the path would be automatically added as include path, cause they contain lines like: zephyr_library_include_directories(include) Remove pre-defineds path except the `` path, which is guaranteed to exists. This simplifies the CMake logic in the top-level Zephyr CMakeLists.txt file. This cleanup further prepares for future work where SoCs need not to be organised under architectures which is important for multi-arch SoCs. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 14 +------------- soc/nios2/nios2-qemu/CMakeLists.txt | 1 + soc/nios2/nios2f-zephyr/CMakeLists.txt | 2 ++ soc/xtensa/dc233c/CMakeLists.txt | 1 + soc/xtensa/intel_adsp/CMakeLists.txt | 1 + soc/xtensa/intel_adsp/ace/CMakeLists.txt | 2 ++ soc/xtensa/intel_adsp/cavs/CMakeLists.txt | 3 ++- soc/xtensa/intel_adsp/common/CMakeLists.txt | 2 +- soc/xtensa/nxp_adsp/CMakeLists.txt | 1 + soc/xtensa/nxp_adsp/common/CMakeLists.txt | 3 ++- soc/xtensa/sample_controller/CMakeLists.txt | 2 ++ 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a40538598b..c29fa6885a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,19 +118,7 @@ zephyr_include_directories( include(${ZEPHYR_BASE}/cmake/linker_script/${ARCH}/linker.cmake OPTIONAL) -# Don't add non-existing include directories, it creates noise and -# warnings in some tooling -foreach(optional_include_dir - ${SOC_DIR}/${ARCH}/${SOC_PATH} - ${SOC_DIR}/${ARCH}/${SOC_PATH}/include - ${SOC_DIR}/${ARCH}/${SOC_PATH}/include/${SOC_NAME} - ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/include - ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/include - ) - if(EXISTS ${optional_include_dir}) - zephyr_include_directories(${optional_include_dir}) - endif() -endforeach() +zephyr_include_directories(${SOC_DIR}/${ARCH}/${SOC_PATH}) # Don't inherit compiler flags from the environment foreach(var AFLAGS CFLAGS CXXFLAGS CPPFLAGS LDFLAGS) diff --git a/soc/nios2/nios2-qemu/CMakeLists.txt b/soc/nios2/nios2-qemu/CMakeLists.txt index 66d55c6ba96..b6dd454d035 100644 --- a/soc/nios2/nios2-qemu/CMakeLists.txt +++ b/soc/nios2/nios2-qemu/CMakeLists.txt @@ -1,3 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(include) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nios2/nios2f-zephyr/CMakeLists.txt b/soc/nios2/nios2f-zephyr/CMakeLists.txt index 66d55c6ba96..789c4c81fc9 100644 --- a/soc/nios2/nios2f-zephyr/CMakeLists.txt +++ b/soc/nios2/nios2f-zephyr/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(include) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/xtensa/dc233c/CMakeLists.txt b/soc/xtensa/dc233c/CMakeLists.txt index 8108448b61d..8012661a437 100644 --- a/soc/xtensa/dc233c/CMakeLists.txt +++ b/soc/xtensa/dc233c/CMakeLists.txt @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(include) zephyr_library_sources_ifdef(CONFIG_XTENSA_MMU mmu.c) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/include/xtensa-dc233c.ld CACHE INTERNAL "") diff --git a/soc/xtensa/intel_adsp/CMakeLists.txt b/soc/xtensa/intel_adsp/CMakeLists.txt index 8a3b1f01f25..2cee15bbcf6 100644 --- a/soc/xtensa/intel_adsp/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/CMakeLists.txt @@ -10,3 +10,4 @@ endif() if(CONFIG_INTEL_ADSP_CAVS) add_subdirectory(cavs) endif() +zephyr_include_directories(common/include) diff --git a/soc/xtensa/intel_adsp/ace/CMakeLists.txt b/soc/xtensa/intel_adsp/ace/CMakeLists.txt index fddb595fa6d..a5aa90b59d0 100644 --- a/soc/xtensa/intel_adsp/ace/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/ace/CMakeLists.txt @@ -13,6 +13,8 @@ zephyr_library_sources( boot.c ) +zephyr_include_directories(include) +zephyr_include_directories(include/${SOC_NAME}) zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget.c) zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget_messages.c) diff --git a/soc/xtensa/intel_adsp/cavs/CMakeLists.txt b/soc/xtensa/intel_adsp/cavs/CMakeLists.txt index 2b5bf93a592..5226f1b0535 100644 --- a/soc/xtensa/intel_adsp/cavs/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/cavs/CMakeLists.txt @@ -3,7 +3,8 @@ # Copyright (c) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -zephyr_library_include_directories(include) +zephyr_include_directories(include) +zephyr_include_directories(include/${SOC_NAME}) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources( diff --git a/soc/xtensa/intel_adsp/common/CMakeLists.txt b/soc/xtensa/intel_adsp/common/CMakeLists.txt index ff09b1e4ea8..c463e4453fc 100644 --- a/soc/xtensa/intel_adsp/common/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/common/CMakeLists.txt @@ -6,7 +6,7 @@ zephyr_interface_library_named(INTEL_ADSP_COMMON) zephyr_library_named(intel_adsp_common) -zephyr_library_include_directories(include) +zephyr_include_directories(include) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_IPC ipc.c) diff --git a/soc/xtensa/nxp_adsp/CMakeLists.txt b/soc/xtensa/nxp_adsp/CMakeLists.txt index 575c7f47cca..a0ab21fb6a8 100644 --- a/soc/xtensa/nxp_adsp/CMakeLists.txt +++ b/soc/xtensa/nxp_adsp/CMakeLists.txt @@ -8,6 +8,7 @@ if(CONFIG_SOC_NXP_RT595) endif() add_subdirectory(common) +zephyr_include_directories(${SOC_SERIES}/include) # west sign diff --git a/soc/xtensa/nxp_adsp/common/CMakeLists.txt b/soc/xtensa/nxp_adsp/common/CMakeLists.txt index 8d6294a6777..02c2ef503e3 100644 --- a/soc/xtensa/nxp_adsp/common/CMakeLists.txt +++ b/soc/xtensa/nxp_adsp/common/CMakeLists.txt @@ -3,10 +3,11 @@ # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(include) + zephyr_interface_library_named(NXP_ADSP_COMMON) zephyr_library_named(nxp_adsp_common) -zephyr_library_include_directories(include) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(soc.c) diff --git a/soc/xtensa/sample_controller/CMakeLists.txt b/soc/xtensa/sample_controller/CMakeLists.txt index 3aff8c6b8b3..20e40128eeb 100644 --- a/soc/xtensa/sample_controller/CMakeLists.txt +++ b/soc/xtensa/sample_controller/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(include) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/include/xtensa-sample-controller.ld CACHE INTERNAL "") From e76a2b9b4b6f278562ff073584259a6f0cdbbaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 6 Nov 2023 14:35:30 +0100 Subject: [PATCH 3139/4498] doc: application: add missing language attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure application-kconfig.include is properly highlighted by setting the :language: attribute. Signed-off-by: Benjamin Cabé --- doc/develop/application/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index 0dae0d288e0..148cb50f936 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -521,6 +521,7 @@ Make sure to follow these steps in order. Structure your :file:`Kconfig` file like this: .. literalinclude:: application-kconfig.include + :language: kconfig .. note:: From 52ae56b8a9e0d4b28e7046e3a5923f03801d983e Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 8 Aug 2023 10:20:59 -0400 Subject: [PATCH 3140/4498] kernel: Add halt_queue field to k_thread The halt queue will be used to identify threads that are waiting for a thread on another CPU to finish suspending. Signed-off-by: Peter Mitsis --- include/zephyr/kernel/thread.h | 5 +++++ kernel/thread.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 7a231196cb4..20d88bba250 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -351,6 +351,11 @@ struct k_thread { struct k_obj_core obj_core; #endif +#ifdef CONFIG_SMP + /** threads waiting in k_thread_suspend() */ + _wait_q_t halt_queue; +#endif + /** arch-specifics: must always be at the end */ struct _thread_arch arch; }; diff --git a/kernel/thread.c b/kernel/thread.c index 7741f7acc66..9e456c45fc9 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -681,6 +681,10 @@ char *z_setup_new_thread(struct k_thread *new_thread, #endif new_thread->resource_pool = _current->resource_pool; +#ifdef CONFIG_SMP + z_waitq_init(&new_thread->halt_queue); +#endif + #ifdef CONFIG_SCHED_THREAD_USAGE new_thread->base.usage = (struct k_cycle_stats) {}; new_thread->base.usage.track_usage = From e1db1cec64dbb5dd9a5dc86f59258f1623ac798a Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 14 Aug 2023 14:06:52 -0400 Subject: [PATCH 3141/4498] kernel: Rename end_thread() to halt_thread() The routine halt_thread() acts nearly identical to end_thread() except that instead of only halting the thread if the _THREAD_DEAD state bit is not set, it will halt it if bit specified by the parameter new_state is not set (which is always _THREAD_DEAD). Signed-off-by: Peter Mitsis --- kernel/sched.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index ffd3070f187..39ebe513831 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -57,7 +57,7 @@ static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq, struct k_spinlock sched_spinlock; static void update_cache(int preempt_ok); -static void end_thread(struct k_thread *thread); +static void halt_thread(struct k_thread *thread, uint8_t new_state); static inline int is_preempt(struct k_thread *thread) @@ -323,7 +323,7 @@ static ALWAYS_INLINE struct k_thread *next_up(void) { #ifdef CONFIG_SMP if (is_aborting(_current)) { - end_thread(_current); + halt_thread(_current, _THREAD_DEAD); } #endif @@ -1712,13 +1712,21 @@ static inline void unpend_all(_wait_q_t *wait_q) extern void z_thread_cmsis_status_mask_clear(struct k_thread *thread); #endif -static void end_thread(struct k_thread *thread) +/** + * @brief Dequeues the specified thread + * + * Dequeues the specified thread and move it into the specified new state. + * + * @param thread Identify the thread to halt + * @param new_state New thread state (_THREAD_DEAD) + */ +static void halt_thread(struct k_thread *thread, uint8_t new_state) { /* We hold the lock, and the thread is known not to be running * anywhere. */ - if ((thread->base.thread_state & _THREAD_DEAD) == 0U) { - thread->base.thread_state |= _THREAD_DEAD; + if ((thread->base.thread_state & new_state) == 0U) { + thread->base.thread_state |= new_state; thread->base.thread_state &= ~_THREAD_ABORTING; if (z_is_thread_queued(thread)) { dequeue_thread(thread); @@ -1777,7 +1785,7 @@ void z_thread_abort(struct k_thread *thread) #ifdef CONFIG_SMP if (is_aborting(thread) && thread == _current && arch_is_in_isr()) { /* Another CPU is spinning for us, don't deadlock */ - end_thread(thread); + halt_thread(thread, _THREAD_DEAD); } bool active = thread_active_elsewhere(thread); @@ -1815,8 +1823,8 @@ void z_thread_abort(struct k_thread *thread) return; /* lock has been released */ } #endif - end_thread(thread); - if (thread == _current && !arch_is_in_isr()) { + halt_thread(thread, _THREAD_DEAD); + if ((thread == _current) && !arch_is_in_isr()) { z_swap(&sched_spinlock, key); __ASSERT(false, "aborted _current back from dead"); } From b1384a71bfd1a2f4b875fdbf1bb5eaa8c446bcd9 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 14 Aug 2023 14:22:05 -0400 Subject: [PATCH 3142/4498] kernel: Create z_thread_halt() Extracts the essential thread synchronization logic when aborting a thread from z_thread_abort() and moves it to its own routine called z_thread_halt(). Signed-off-by: Peter Mitsis --- kernel/sched.c | 115 +++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 47 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 39ebe513831..6140ea2740d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -58,6 +58,7 @@ struct k_spinlock sched_spinlock; static void update_cache(int preempt_ok); static void halt_thread(struct k_thread *thread, uint8_t new_state); +static void add_to_waitq_locked(struct k_thread *thread, _wait_q_t *wait_q); static inline int is_preempt(struct k_thread *thread) @@ -665,6 +666,72 @@ void z_sched_start(struct k_thread *thread) z_reschedule(&sched_spinlock, key); } +/** + * @brief Halt a thread + * + * If the target thread is running on another CPU, flag it as needing to + * abort and send an IPI (if supported) to force a schedule point and wait + * until the target thread is switched out (ISRs will spin to wait and threads + * will block to wait). If the target thread is not running on another CPU, + * then it is safe to act immediately. + * + * Upon entry to this routine, the scheduler lock is already held. It is + * released before this routine returns. + * + * @param thread Thread to suspend or abort + * @param key Current key for sched_spinlock + */ +static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key) +{ +#ifdef CONFIG_SMP + if (is_aborting(thread) && thread == _current && arch_is_in_isr()) { + /* Another CPU is spinning for us, don't deadlock */ + halt_thread(thread, _THREAD_DEAD); + } + + bool active = thread_active_elsewhere(thread); + + if (active) { + /* It's running somewhere else, flag and poke */ + thread->base.thread_state |= _THREAD_ABORTING; + + /* We're going to spin, so need a true synchronous IPI + * here, not deferred! + */ +#ifdef CONFIG_SCHED_IPI_SUPPORTED + arch_sched_ipi(); +#endif + } + + if (is_aborting(thread) && thread != _current) { + if (arch_is_in_isr()) { + /* ISRs can only spin waiting another CPU */ + k_spin_unlock(&sched_spinlock, key); + while (is_aborting(thread)) { + } + + /* Now we know it's dying, but not necessarily + * dead. Wait for the switch to happen! + */ + key = k_spin_lock(&sched_spinlock); + z_sched_switch_spin(thread); + k_spin_unlock(&sched_spinlock, key); + } else if (active) { + /* Threads can join */ + add_to_waitq_locked(_current, &thread->join_queue); + z_swap(&sched_spinlock, key); + } + return; /* lock has been released */ + } +#endif + halt_thread(thread, _THREAD_DEAD); + if ((thread == _current) && !arch_is_in_isr()) { + z_swap(&sched_spinlock, key); + __ASSERT(false, "aborted _current back from dead"); + } + k_spin_unlock(&sched_spinlock, key); +} + void z_impl_k_thread_suspend(struct k_thread *thread) { SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_thread, suspend, thread); @@ -1782,53 +1849,7 @@ void z_thread_abort(struct k_thread *thread) return; } -#ifdef CONFIG_SMP - if (is_aborting(thread) && thread == _current && arch_is_in_isr()) { - /* Another CPU is spinning for us, don't deadlock */ - halt_thread(thread, _THREAD_DEAD); - } - - bool active = thread_active_elsewhere(thread); - - if (active) { - /* It's running somewhere else, flag and poke */ - thread->base.thread_state |= _THREAD_ABORTING; - - /* We're going to spin, so need a true synchronous IPI - * here, not deferred! - */ -#ifdef CONFIG_SCHED_IPI_SUPPORTED - arch_sched_ipi(); -#endif - } - - if (is_aborting(thread) && thread != _current) { - if (arch_is_in_isr()) { - /* ISRs can only spin waiting another CPU */ - k_spin_unlock(&sched_spinlock, key); - while (is_aborting(thread)) { - } - - /* Now we know it's dying, but not necessarily - * dead. Wait for the switch to happen! - */ - key = k_spin_lock(&sched_spinlock); - z_sched_switch_spin(thread); - k_spin_unlock(&sched_spinlock, key); - } else if (active) { - /* Threads can join */ - add_to_waitq_locked(_current, &thread->join_queue); - z_swap(&sched_spinlock, key); - } - return; /* lock has been released */ - } -#endif - halt_thread(thread, _THREAD_DEAD); - if ((thread == _current) && !arch_is_in_isr()) { - z_swap(&sched_spinlock, key); - __ASSERT(false, "aborted _current back from dead"); - } - k_spin_unlock(&sched_spinlock, key); + z_thread_halt(thread, key); } #if !defined(CONFIG_ARCH_HAS_THREAD_ABORT) From e7986eb5522cfd19156c3a28ea6924087fe294b2 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 14 Aug 2023 16:41:05 -0400 Subject: [PATCH 3143/4498] kernel: Extend halting to support suspending Extends the concept of halting a thread from just aborting a thread to both aborting and suspending a thread. Part of this involves updating k_thread_suspend() to operate in a similar fashion to that of k_thread_abort(). Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 11 ++-- include/zephyr/kernel_structs.h | 5 +- kernel/sched.c | 107 +++++++++++++++++++++----------- 3 files changed, 82 insertions(+), 41 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a62e55f72c3..51d5aa37901 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -621,11 +621,7 @@ static inline k_tid_t k_current_get(void) * this is done via blocking the caller (in the same manner as * k_thread_join()), but in interrupt context on SMP systems the * implementation is required to spin for threads that are running on - * other CPUs. Note that as specified, this means that on SMP - * platforms it is possible for application code to create a deadlock - * condition by simultaneously aborting a cycle of threads using at - * least one termination from interrupt context. Zephyr cannot detect - * all such conditions. + * other CPUs. * * @param thread ID of thread to abort. */ @@ -978,6 +974,11 @@ int k_thread_cpu_pin(k_tid_t thread, int cpu); * will be canceled. On resume, the thread will begin running * immediately and return from the blocked call. * + * When the target thread is active on another CPU, the caller will block until + * the target thread is halted (suspended or aborted). But if the caller is in + * an interrupt context, it will spin waiting for that target thread active on + * another CPU to halt. + * * If @a thread is already suspended, the routine has no effect. * * @param thread ID of thread to suspend. diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 692d8229403..986165006eb 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -60,9 +60,12 @@ extern "C" { /* Thread is suspended */ #define _THREAD_SUSPENDED (BIT(4)) -/* Thread is being aborted */ +/* Thread is in the process of aborting */ #define _THREAD_ABORTING (BIT(5)) +/* Thread is in the process of suspending */ +#define _THREAD_SUSPENDING (BIT(6)) + /* Thread is present in the ready queue */ #define _THREAD_QUEUED (BIT(7)) diff --git a/kernel/sched.c b/kernel/sched.c index 6140ea2740d..7dd782c9490 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -314,17 +314,32 @@ void z_requeue_current(struct k_thread *curr) signal_pending_ipi(); } +/* Return true if the thread is aborting, else false */ static inline bool is_aborting(struct k_thread *thread) { return (thread->base.thread_state & _THREAD_ABORTING) != 0U; } + +/* Return true if the thread is aborting or suspending, else false */ +static inline bool is_halting(struct k_thread *thread) +{ + return (thread->base.thread_state & + (_THREAD_ABORTING | _THREAD_SUSPENDING)) != 0U; +} #endif +/* Clear the halting bits (_THREAD_ABORTING and _THREAD_SUSPENDING) */ +static inline void clear_halting(struct k_thread *thread) +{ + thread->base.thread_state &= ~(_THREAD_ABORTING | _THREAD_SUSPENDING); +} + static ALWAYS_INLINE struct k_thread *next_up(void) { #ifdef CONFIG_SMP - if (is_aborting(_current)) { - halt_thread(_current, _THREAD_DEAD); + if (is_halting(_current)) { + halt_thread(_current, is_aborting(_current) ? + _THREAD_DEAD : _THREAD_SUSPENDED); } #endif @@ -680,22 +695,30 @@ void z_sched_start(struct k_thread *thread) * * @param thread Thread to suspend or abort * @param key Current key for sched_spinlock + * @param terminate True if aborting thread, false if suspending thread */ -static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key) +static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key, + bool terminate) { #ifdef CONFIG_SMP - if (is_aborting(thread) && thread == _current && arch_is_in_isr()) { - /* Another CPU is spinning for us, don't deadlock */ - halt_thread(thread, _THREAD_DEAD); + if (is_halting(_current) && arch_is_in_isr()) { + /* Another CPU (in an ISR) or thread is waiting for the + * current thread to halt. Halt it now to help avoid a + * potential deadlock. + */ + halt_thread(_current, + is_aborting(_current) ? _THREAD_DEAD + : _THREAD_SUSPENDED); } bool active = thread_active_elsewhere(thread); if (active) { /* It's running somewhere else, flag and poke */ - thread->base.thread_state |= _THREAD_ABORTING; + thread->base.thread_state |= (terminate ? _THREAD_ABORTING + : _THREAD_SUSPENDING); - /* We're going to spin, so need a true synchronous IPI + /* We might spin to wait, so a true synchronous IPI is needed * here, not deferred! */ #ifdef CONFIG_SCHED_IPI_SUPPORTED @@ -703,33 +726,37 @@ static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key) #endif } - if (is_aborting(thread) && thread != _current) { + if (is_halting(thread) && (thread != _current)) { if (arch_is_in_isr()) { /* ISRs can only spin waiting another CPU */ k_spin_unlock(&sched_spinlock, key); - while (is_aborting(thread)) { + while (is_halting(thread)) { } - /* Now we know it's dying, but not necessarily - * dead. Wait for the switch to happen! + /* Now we know it's halting, but not necessarily + * halted (suspended or aborted). Wait for the switch + * to happen! */ key = k_spin_lock(&sched_spinlock); z_sched_switch_spin(thread); k_spin_unlock(&sched_spinlock, key); } else if (active) { - /* Threads can join */ - add_to_waitq_locked(_current, &thread->join_queue); + /* Threads can wait on a queue */ + add_to_waitq_locked(_current, terminate ? + &thread->join_queue : + &thread->halt_queue); z_swap(&sched_spinlock, key); } return; /* lock has been released */ } #endif - halt_thread(thread, _THREAD_DEAD); + halt_thread(thread, terminate ? _THREAD_DEAD : _THREAD_SUSPENDED); if ((thread == _current) && !arch_is_in_isr()) { z_swap(&sched_spinlock, key); - __ASSERT(false, "aborted _current back from dead"); + __ASSERT(!terminate, "aborted _current back from dead"); + } else { + k_spin_unlock(&sched_spinlock, key); } - k_spin_unlock(&sched_spinlock, key); } void z_impl_k_thread_suspend(struct k_thread *thread) @@ -738,18 +765,18 @@ void z_impl_k_thread_suspend(struct k_thread *thread) (void)z_abort_thread_timeout(thread); - K_SPINLOCK(&sched_spinlock) { - if (z_is_thread_queued(thread)) { - dequeue_thread(thread); - } - z_mark_thread_as_suspended(thread); - update_cache(thread == _current); - } + k_spinlock_key_t key = k_spin_lock(&sched_spinlock); - if (thread == _current) { - z_reschedule_unlocked(); + if ((thread->base.thread_state & _THREAD_SUSPENDED) != 0U) { + + /* The target thread is already suspended. Nothing to do. */ + + k_spin_unlock(&sched_spinlock, key); + return; } + z_thread_halt(thread, key, false); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_thread, suspend, thread); } @@ -865,8 +892,8 @@ ALWAYS_INLINE void z_unpend_thread_no_timeout(struct k_thread *thread) void z_sched_wake_thread(struct k_thread *thread, bool is_timeout) { K_SPINLOCK(&sched_spinlock) { - bool killed = ((thread->base.thread_state & _THREAD_DEAD) || - (thread->base.thread_state & _THREAD_ABORTING)); + bool killed = (thread->base.thread_state & + (_THREAD_DEAD | _THREAD_ABORTING)); #ifdef CONFIG_EVENTS bool do_nothing = thread->no_wake_on_timeout && is_timeout; @@ -1785,7 +1812,7 @@ extern void z_thread_cmsis_status_mask_clear(struct k_thread *thread); * Dequeues the specified thread and move it into the specified new state. * * @param thread Identify the thread to halt - * @param new_state New thread state (_THREAD_DEAD) + * @param new_state New thread state (_THREAD_DEAD or _THREAD_SUSPENDED) */ static void halt_thread(struct k_thread *thread, uint8_t new_state) { @@ -1794,17 +1821,27 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) */ if ((thread->base.thread_state & new_state) == 0U) { thread->base.thread_state |= new_state; - thread->base.thread_state &= ~_THREAD_ABORTING; + clear_halting(thread); if (z_is_thread_queued(thread)) { dequeue_thread(thread); } - if (thread->base.pended_on != NULL) { - unpend_thread_no_timeout(thread); + + if (new_state == _THREAD_DEAD) { + if (thread->base.pended_on != NULL) { + unpend_thread_no_timeout(thread); + } + (void)z_abort_thread_timeout(thread); + unpend_all(&thread->join_queue); } - (void)z_abort_thread_timeout(thread); - unpend_all(&thread->join_queue); +#ifdef CONFIG_SMP + unpend_all(&thread->halt_queue); +#endif update_cache(1); + if (new_state == _THREAD_SUSPENDED) { + return; + } + #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) arch_float_disable(thread); #endif @@ -1849,7 +1886,7 @@ void z_thread_abort(struct k_thread *thread) return; } - z_thread_halt(thread, key); + z_thread_halt(thread, key, true); } #if !defined(CONFIG_ARCH_HAS_THREAD_ABORT) From 9364ba4353c7f26ddbf5ccb24de790137eb90941 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Tue, 15 Aug 2023 10:43:59 -0400 Subject: [PATCH 3144/4498] kernel: Update k_thread_state_str() Updates k_thread_state_str() to interpret the halting bits correctly. Signed-off-by: Peter Mitsis --- kernel/thread.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/kernel/thread.c b/kernel/thread.c index 9e456c45fc9..8f60054e798 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -311,15 +311,33 @@ static size_t copy_bytes(char *dest, size_t dest_size, const char *src, size_t s return bytes_to_copy; } +#define Z_STATE_STR_DUMMY "dummy" +#define Z_STATE_STR_PENDING "pending" +#define Z_STATE_STR_PRESTART "prestart" +#define Z_STATE_STR_DEAD "dead" +#define Z_STATE_STR_SUSPENDED "suspended" +#define Z_STATE_STR_ABORTING "aborting" +#define Z_STATE_STR_SUSPENDING "suspending" +#define Z_STATE_STR_QUEUED "queued" + const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size) { size_t off = 0; uint8_t bit; uint8_t thread_state = thread_id->base.thread_state; - static const char *states_str[8] = {"dummy", "pending", "prestart", - "dead", "suspended", "aborting", - "", "queued"}; - static const size_t states_sz[8] = {5, 7, 8, 4, 9, 8, 0, 6}; + static const struct { + const char *str; + size_t len; + } state_string[] = { + { Z_STATE_STR_DUMMY, sizeof(Z_STATE_STR_DUMMY) - 1}, + { Z_STATE_STR_PENDING, sizeof(Z_STATE_STR_PENDING) - 1}, + { Z_STATE_STR_PRESTART, sizeof(Z_STATE_STR_PRESTART) - 1}, + { Z_STATE_STR_DEAD, sizeof(Z_STATE_STR_DEAD) - 1}, + { Z_STATE_STR_SUSPENDED, sizeof(Z_STATE_STR_SUSPENDED) - 1}, + { Z_STATE_STR_ABORTING, sizeof(Z_STATE_STR_ABORTING) - 1}, + { Z_STATE_STR_SUSPENDING, sizeof(Z_STATE_STR_SUSPENDING) - 1}, + { Z_STATE_STR_QUEUED, sizeof(Z_STATE_STR_QUEUED) - 1}, + }; if ((buf == NULL) || (buf_size == 0)) { return ""; @@ -333,14 +351,16 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size) * separate the descriptive strings with a '+'. */ - for (uint8_t index = 0; thread_state != 0; index++) { + + for (unsigned int index = 0; thread_state != 0; index++) { bit = BIT(index); if ((thread_state & bit) == 0) { continue; } off += copy_bytes(buf + off, buf_size - off, - states_str[index], states_sz[index]); + state_string[index].str, + state_string[index].len); thread_state &= ~bit; From ddedb7171c8b4006b7b917d78d3a1ec67ef59204 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Tue, 31 Oct 2023 15:21:03 -0500 Subject: [PATCH 3145/4498] include: drivers: sdhc: indentation cleanups Indentation of multiline function declarations wasn't aligned properly. Clean this up. Signed-off-by: Daniel DeGrasse --- include/zephyr/drivers/sdhc.h | 38 +++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index 78529af2f4b..bf980fb9e9c 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -234,14 +234,14 @@ struct sdhc_host_props { __subsystem struct sdhc_driver_api { int (*reset)(const struct device *dev); int (*request)(const struct device *dev, - struct sdhc_command *cmd, - struct sdhc_data *data); + struct sdhc_command *cmd, + struct sdhc_data *data); int (*set_io)(const struct device *dev, struct sdhc_io *ios); int (*get_card_present)(const struct device *dev); int (*execute_tuning)(const struct device *dev); int (*card_busy)(const struct device *dev); int (*get_host_props)(const struct device *dev, - struct sdhc_host_props *props); + struct sdhc_host_props *props); }; /** @@ -260,8 +260,7 @@ __syscall int sdhc_hw_reset(const struct device *dev); static inline int z_impl_sdhc_hw_reset(const struct device *dev) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->reset) { return -ENOSYS; @@ -285,13 +284,13 @@ static inline int z_impl_sdhc_hw_reset(const struct device *dev) * @retval -EIO: I/O error */ __syscall int sdhc_request(const struct device *dev, struct sdhc_command *cmd, - struct sdhc_data *data); + struct sdhc_data *data); static inline int z_impl_sdhc_request(const struct device *dev, - struct sdhc_command *cmd, struct sdhc_data *data) + struct sdhc_command *cmd, + struct sdhc_data *data) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->request) { return -ENOSYS; @@ -315,10 +314,9 @@ static inline int z_impl_sdhc_request(const struct device *dev, __syscall int sdhc_set_io(const struct device *dev, struct sdhc_io *io); static inline int z_impl_sdhc_set_io(const struct device *dev, - struct sdhc_io *io) + struct sdhc_io *io) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->set_io) { return -ENOSYS; @@ -342,8 +340,7 @@ __syscall int sdhc_card_present(const struct device *dev); static inline int z_impl_sdhc_card_present(const struct device *dev) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->get_card_present) { return -ENOSYS; @@ -368,8 +365,7 @@ __syscall int sdhc_execute_tuning(const struct device *dev); static inline int z_impl_sdhc_execute_tuning(const struct device *dev) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->execute_tuning) { return -ENOSYS; @@ -393,8 +389,7 @@ __syscall int sdhc_card_busy(const struct device *dev); static inline int z_impl_sdhc_card_busy(const struct device *dev) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->card_busy) { return -ENOSYS; @@ -415,13 +410,12 @@ static inline int z_impl_sdhc_card_busy(const struct device *dev) * @retval -ENOTSUP host controller does not support this call */ __syscall int sdhc_get_host_props(const struct device *dev, - struct sdhc_host_props *props); + struct sdhc_host_props *props); static inline int z_impl_sdhc_get_host_props(const struct device *dev, - struct sdhc_host_props *props) + struct sdhc_host_props *props) { - const struct sdhc_driver_api *api = - (const struct sdhc_driver_api *)dev->api; + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; if (!api->get_host_props) { return -ENOSYS; From f9216f0d63a4216e790f44d9b73eea5913152cdd Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:09:29 -0500 Subject: [PATCH 3146/4498] sd: add SDIO specification definitions Add SDIO specification definitions, including SDIO commands. Signed-off-by: Daniel DeGrasse --- include/zephyr/sd/sd_spec.h | 163 ++++++++++++++++++++++++++++++++++-- 1 file changed, 158 insertions(+), 5 deletions(-) diff --git a/include/zephyr/sd/sd_spec.h b/include/zephyr/sd/sd_spec.h index ed0426766ec..ed61932e655 100644 --- a/include/zephyr/sd/sd_spec.h +++ b/include/zephyr/sd/sd_spec.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,6 +54,8 @@ enum sd_opcode { SD_ERASE_BLOCK_START = 32, SD_ERASE_BLOCK_END = 33, SD_ERASE_BLOCK_OPERATION = 38, + SDIO_RW_DIRECT = 52, + SDIO_RW_EXTENDED = 53, SD_APP_CMD = 55, SD_SPI_READ_OCR = 58, /* SPI mode only */ SD_SPI_CRC_ON_OFF = 59, /* SPI mode only */ @@ -244,6 +246,7 @@ enum sd_support_flag { SD_3000MV_FLAG = BIT(6), SD_CMD23_FLAG = BIT(7), SD_SPEED_CLASS_CONTROL_FLAG = BIT(8), + SD_MEM_PRESENT_FLAG = BIT(9), }; @@ -298,9 +301,9 @@ enum mmc_ocr_flag { MMC_OCR_PWR_BUSY_FLAG = BIT(31) }; -#define SDIO_OCR_IO_NUMBER_SHIFT (28U) +#define SDIO_OCR_IO_NUMBER_SHIFT 28 /* Lower 24 bits hold SDIO I/O OCR */ -#define SDIO_IO_OCR_MASK (0xFFFFFFU) +#define SDIO_IO_OCR_MASK 0xFFFFFF /** * @brief SDIO OCR bit flags @@ -491,7 +494,7 @@ struct sd_switch_caps { }; -#define SD_PRODUCT_NAME_BYTES (5U) +#define SD_PRODUCT_NAME_BYTES 5 /** * @brief SD card identification register @@ -754,8 +757,158 @@ enum sd_spec_version { }; -#define SDMMC_DEFAULT_BLOCK_SIZE (512U) +#define SDMMC_DEFAULT_BLOCK_SIZE 512 #define MMC_EXT_CSD_BYTES 512 +/** + * @brief SDIO function number + * + * SDIO function number used to select function when performing I/O on SDIO card + */ +enum sdio_func_num { + SDIO_FUNC_NUM_0 = 0, + SDIO_FUNC_NUM_1 = 1, + SDIO_FUNC_NUM_2 = 2, + SDIO_FUNC_NUM_3 = 3, + SDIO_FUNC_NUM_4 = 4, + SDIO_FUNC_NUM_5 = 5, + SDIO_FUNC_NUM_6 = 6, + SDIO_FUNC_NUM_7 = 7, + SDIO_FUNC_MEMORY = 8, +}; + +/** + * @brief SDIO I/O direction + * + * SDIO I/O direction (read or write) + */ +enum sdio_io_dir { + SDIO_IO_READ = 0, + SDIO_IO_WRITE = 1, +}; + +#define SDIO_CMD_ARG_RW_SHIFT 31 /*!< read/write flag shift */ +#define SDIO_CMD_ARG_FUNC_NUM_SHIFT 28 /*!< function number shift */ +#define SDIO_DIRECT_CMD_ARG_RAW_SHIFT 27 /*!< direct raw flag shift */ +#define SDIO_CMD_ARG_REG_ADDR_SHIFT 9 /*!< direct reg addr shift */ +#define SDIO_CMD_ARG_REG_ADDR_MASK 0x1FFFF /*!< direct reg addr mask */ +#define SDIO_DIRECT_CMD_DATA_MASK 0xFF /*!< data mask */ + +#define SDIO_EXTEND_CMD_ARG_BLK_SHIFT 27 /*!< extended write block mode */ +#define SDIO_EXTEND_CMD_ARG_OP_CODE_SHIFT 26 /*!< op code (increment address) */ + +/** + * @brief Card common control register definitions + * + * Card common control registers, present on all SDIO cards + */ +#define SDIO_CCCR_CCCR 0x00 /*!< SDIO CCCR revision register */ +#define SDIO_CCCR_CCCR_REV_MASK 0x0F +#define SDIO_CCCR_CCCR_REV_SHIFT 0x0 +#define SDIO_CCCR_CCCR_REV_1_00 0x0 /*!< CCCR/FBR Version 1.00 */ +#define SDIO_CCCR_CCCR_REV_1_10 0x1 /*!< CCCR/FBR Version 1.10 */ +#define SDIO_CCCR_CCCR_REV_2_00 0x2 /*!< CCCR/FBR Version 2.00 */ +#define SDIO_CCCR_CCCR_REV_3_00 0x3 /*!< CCCR/FBR Version 3.00 */ + +#define SDIO_CCCR_SD 0x01 /*!< SD spec version register */ +#define SDIO_CCCR_SD_SPEC_MASK 0x0F +#define SDIO_CCCR_SD_SPEC_SHIFT 0x0 + +#define SDIO_CCCR_IO_EN 0x02 /*!< SDIO IO Enable register */ + +#define SDIO_CCCR_IO_RD 0x03 /*!< SDIO IO Ready register */ + +#define SDIO_CCCR_INT_EN 0x04 /*!< SDIO Interrupt enable register */ + +#define SDIO_CCCR_INT_P 0x05 /*!< SDIO Interrupt pending register */ + +#define SDIO_CCCR_ABORT 0x06 /*!< SDIO IO abort register */ + +#define SDIO_CCCR_BUS_IF 0x07 /*!< SDIO bus interface control register */ +#define SDIO_CCCR_BUS_IF_WIDTH_MASK 0x3 /*!< SDIO bus width setting mask */ +#define SDIO_CCCR_BUS_IF_WIDTH_1_BIT 0x00 /*!< 1 bit SDIO bus setting */ +#define SDIO_CCCR_BUS_IF_WIDTH_4_BIT 0x02 /*!< 4 bit SDIO bus setting */ +#define SDIO_CCCR_BUS_IF_WIDTH_8_BIT 0x03 /*!< 8 bit SDIO bus setting */ + +#define SDIO_CCCR_CAPS 0x08 /*!< SDIO card capabilities */ +#define SDIO_CCCR_CAPS_SDC BIT(0) /*!< support CMD52 while data transfer */ +#define SDIO_CCCR_CAPS_SMB BIT(1) /*!< support multiple block transfer */ +#define SDIO_CCCR_CAPS_SRW BIT(2) /*!< support read wait control */ +#define SDIO_CCCR_CAPS_SBS BIT(3) /*!< support bus control */ +#define SDIO_CCCR_CAPS_S4MI BIT(4) /*!< support block gap interrupt */ +#define SDIO_CCCR_CAPS_E4MI BIT(5) /*!< enable block gap interrupt */ +#define SDIO_CCCR_CAPS_LSC BIT(6) /*!< low speed card */ +#define SDIO_CCCR_CAPS_BLS BIT(7) /*!< low speed card with 4 bit support */ + +#define SDIO_CCCR_CIS 0x09 /*!< SDIO CIS tuples pointer */ + +#define SDIO_CCCR_SPEED 0x13 /*!< SDIO bus speed select */ +#define SDIO_CCCR_SPEED_SHS BIT(0) /*!< high speed support */ +#define SDIO_CCCR_SPEED_MASK 0xE /*!< bus speed select mask*/ +#define SDIO_CCCR_SPEED_SHIFT 0x1 /*!< bus speed select shift */ +#define SDIO_CCCR_SPEED_SDR12 0x0 /*!< select SDR12 */ +#define SDIO_CCCR_SPEED_HS 0x1 /*!< select High speed mode */ +#define SDIO_CCCR_SPEED_SDR25 0x1 /*!< select SDR25 */ +#define SDIO_CCCR_SPEED_SDR50 0x2 /*!< select SDR50 */ +#define SDIO_CCCR_SPEED_SDR104 0x3 /*!< select SDR104 */ +#define SDIO_CCCR_SPEED_DDR50 0x4 /*!< select DDR50 */ + +#define SDIO_CCCR_UHS 0x14 /*!< SDIO UHS support */ +#define SDIO_CCCR_UHS_SDR50 BIT(0) /*!< SDR50 support */ +#define SDIO_CCCR_UHS_SDR104 BIT(1) /*!< SDR104 support */ +#define SDIO_CCCR_UHS_DDR50 BIT(2) /*!< DDR50 support */ + +#define SDIO_CCCR_DRIVE_STRENGTH 0x15 /*!< SDIO drive strength */ +#define SDIO_CCCR_DRIVE_STRENGTH_A BIT(0) /*!< drive type A */ +#define SDIO_CCCR_DRIVE_STRENGTH_C BIT(1) /*!< drive type C */ +#define SDIO_CCCR_DRIVE_STRENGTH_D BIT(2) /*!< drive type D */ + +#define SDIO_FBR_BASE(n) ((n) * 0x100) /*!< Get function base register addr */ + +#define SDIO_FBR_CIS 0x09 /*!< SDIO function base register CIS pointer */ +#define SDIO_FBR_CSA 0x0C /*!< SDIO function base register CSA pointer */ +#define SDIO_FBR_BLK_SIZE 0x10 /*!< SDIO function base register block size */ + + +#define SDIO_MAX_IO_NUMS 7 /*!< Maximum number of I/O functions for SDIO */ + +#define SDIO_TPL_CODE_NULL 0x00 /*!< NULL CIS tuple code */ +#define SDIO_TPL_CODE_MANIFID 0x20 /*!< manufacturer ID CIS tuple code */ +#define SDIO_TPL_CODE_FUNCID 0x21 /*!< function ID CIS tuple code */ +#define SDIO_TPL_CODE_FUNCE 0x22 /*!< function extension CIS tuple code */ +#define SDIO_TPL_CODE_END 0xFF /*!< End CIS tuple code */ + +/** + * @brief Card common control register flags + * + * flags to indicate capabilities supported by an SDIO card, read from the CCCR + * registers + */ +enum sdio_cccr_flags { + SDIO_SUPPORT_HS = BIT(0), + SDIO_SUPPORT_SDR50 = BIT(1), + SDIO_SUPPORT_SDR104 = BIT(2), + SDIO_SUPPORT_DDR50 = BIT(3), + SDIO_SUPPORT_4BIT_LS_BUS = BIT(4), + SDIO_SUPPORT_MULTIBLOCK = BIT(5), +}; + +/** + * @brief SDIO common CIS tuple properties + * + * CIS tuple properties. Note that additional properties exist for + * functions 1-7, but we do not read this data as the stack does not utilize it. + */ +struct sdio_cis { + /* Manufacturer ID string tuple */ + uint16_t manf_id; /*!< manufacturer ID */ + uint16_t manf_code; /*!< manufacturer code */ + /* Function identification tuple */ + uint8_t func_id; /*!< sdio device class function id */ + /* Function extension table */ + uint16_t max_blk_size; /*!< Max transfer block size */ + uint8_t max_speed; /*!< Max transfer speed */ + uint16_t rdy_timeout; /*!< I/O ready timeout */ +}; #ifdef __cplusplus } From c9acfafd780dc064ef99e2fbf8388daeced3df26 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:56:32 -0500 Subject: [PATCH 3147/4498] drivers: sdhc: add support for interrupts add support for card interrupt sources to SDHC drivers. This can be used for SDIO card interrupts, or to detect card insertion/removal. Signed-off-by: Daniel DeGrasse --- include/zephyr/drivers/sdhc.h | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index bf980fb9e9c..092fca8a9ef 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -231,6 +231,29 @@ struct sdhc_host_props { bool is_spi; /*!< Is the host using SPI mode */ }; +/** + * @brief SD host controller interrupt sources + * + * Interrupt sources for SD host controller. + */ +enum sdhc_interrupt_source { + SDHC_INT_SDIO = BIT(0), /*!< Card interrupt, used by SDIO cards */ + SDHC_INT_INSERTED = BIT(1), /*!< Card was inserted into slot */ + SDHC_INT_REMOVED = BIT(2), /*!< Card was removed from slot */ +}; + +/** + * @typedef sdhc_interrupt_cb_t + * @brief SDHC card interrupt callback prototype + * + * Function prototype for SDHC card interrupt callback. + * @param dev: SDHC device that produced interrupt + * @param reason: one of @ref sdhc_interrupt_source values. + * @param user_data: User data, set via @ref sdhc_enable_interrupt + */ +typedef void (*sdhc_interrupt_cb_t)(const struct device *dev, int reason, + const void *user_data); + __subsystem struct sdhc_driver_api { int (*reset)(const struct device *dev); int (*request)(const struct device *dev, @@ -242,6 +265,10 @@ __subsystem struct sdhc_driver_api { int (*card_busy)(const struct device *dev); int (*get_host_props)(const struct device *dev, struct sdhc_host_props *props); + int (*enable_interrupt)(const struct device *dev, + sdhc_interrupt_cb_t callback, + int sources, void *user_data); + int (*disable_interrupt)(const struct device *dev, int sources); }; /** @@ -424,6 +451,64 @@ static inline int z_impl_sdhc_get_host_props(const struct device *dev, return api->get_host_props(dev, props); } +/** + * @brief Enable SDHC interrupt sources. + * + * Enables SDHC interrupt sources. Each subsequent call of this function + * should replace the previous callback set, and leave only the interrupts + * specified in the "sources" argument enabled. + * @param dev: SDHC device + * @param callback: Callback called when interrupt occurs + * @param sources: bitmask of @ref sdhc_interrupt_source values + * indicating which interrupts should produce a callback + * @param user_data: parameter that will be passed to callback function + * @retval 0 interrupts were enabled, and callback was installed + * @retval -ENOTSUP: controller does not support this function + * @retval -EIO: I/O error + */ +__syscall int sdhc_enable_interrupt(const struct device *dev, + sdhc_interrupt_cb_t callback, + int sources, void *user_data); + +static inline int z_impl_sdhc_enable_interrupt(const struct device *dev, + sdhc_interrupt_cb_t callback, + int sources, void *user_data) +{ + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; + + if (!api->enable_interrupt) { + return -ENOSYS; + } + + return api->enable_interrupt(dev, callback, sources, user_data); +} + +/** + * @brief Disable SDHC interrupt sources + * + * Disables SDHC interrupt sources. If multiple sources are enabled, only + * the ones specified in "sources" will be masked. + * @param dev: SDHC device + * @param sources: bitmask of @ref sdhc_interrupt_source values + * indicating which interrupts should be disabled. + * @retval 0 interrupts were disabled + * @retval -ENOTSUP: controller does not support this function + * @retval -EIO: I/O error + */ +__syscall int sdhc_disable_interrupt(const struct device *dev, int sources); + +static inline int z_impl_sdhc_disable_interrupt(const struct device *dev, + int sources) +{ + const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api; + + if (!api->disable_interrupt) { + return -ENOSYS; + } + + return api->disable_interrupt(dev, sources); +} + /** * @} */ From 69aaed126671279c86ba2d94060c0606da0d9345 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:57:09 -0500 Subject: [PATCH 3148/4498] drivers: sdhc: imx_usdhc: add support for card interrupts Add support for card interrupt sources to USDHC driver. Signed-off-by: Daniel DeGrasse --- drivers/sdhc/imx_usdhc.c | 194 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 2 deletions(-) diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index 49914137eec..0a1896a3fa4 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -75,6 +75,7 @@ struct usdhc_config { }; struct usdhc_data { + const struct device *dev; struct sdhc_host_props props; bool card_present; struct k_sem transfer_sem; @@ -82,6 +83,9 @@ struct usdhc_data { usdhc_handle_t transfer_handle; struct sdhc_io host_io; struct k_mutex access_mutex; + sdhc_interrupt_cb_t sdhc_cb; + struct gpio_callback cd_callback; + void *sdhc_cb_user_data; uint8_t usdhc_rx_dummy[128] __aligned(32); #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT uint32_t *usdhc_dma_descriptor; /* ADMA descriptor table (noncachable) */ @@ -107,6 +111,55 @@ static void transfer_complete_cb(USDHC_Type *usdhc, usdhc_handle_t *handle, k_sem_give(&data->transfer_sem); } + +static void sdio_interrupt_cb(USDHC_Type *usdhc, void *user_data) +{ + const struct device *dev = user_data; + struct usdhc_data *data = dev->data; + + if (data->sdhc_cb) { + data->sdhc_cb(dev, SDHC_INT_SDIO, data->sdhc_cb_user_data); + } +} + +static void card_inserted_cb(USDHC_Type *usdhc, void *user_data) +{ + const struct device *dev = user_data; + struct usdhc_data *data = dev->data; + + if (data->sdhc_cb) { + data->sdhc_cb(dev, SDHC_INT_INSERTED, data->sdhc_cb_user_data); + } +} + +static void card_removed_cb(USDHC_Type *usdhc, void *user_data) +{ + const struct device *dev = user_data; + struct usdhc_data *data = dev->data; + + if (data->sdhc_cb) { + data->sdhc_cb(dev, SDHC_INT_REMOVED, data->sdhc_cb_user_data); + } +} + +static void card_detect_gpio_cb(const struct device *port, + struct gpio_callback *cb, + gpio_port_pins_t pins) +{ + struct usdhc_data *data = CONTAINER_OF(cb, struct usdhc_data, cd_callback); + const struct device *dev = data->dev; + const struct usdhc_config *cfg = dev->config; + + if (data->sdhc_cb) { + if (gpio_pin_get_dt(&cfg->detect_gpio)) { + data->sdhc_cb(dev, SDHC_INT_INSERTED, data->sdhc_cb_user_data); + } else { + data->sdhc_cb(dev, SDHC_INT_REMOVED, data->sdhc_cb_user_data); + } + } +} + + static int imx_usdhc_dat3_pull(const struct usdhc_config *cfg, bool pullup) { int ret = 0U; @@ -757,8 +810,7 @@ static int imx_usdhc_get_card_present(const struct device *dev) } else if (cfg->detect_gpio.port) { data->card_present = gpio_pin_get_dt(&cfg->detect_gpio) > 0; } else { - LOG_WRN("No card presence method configured, assuming card is present"); - data->card_present = true; + data->card_present = USDHC_DetectCardInsert(cfg->base); } return ((int)data->card_present); } @@ -775,6 +827,132 @@ static int imx_usdhc_get_host_props(const struct device *dev, return 0; } +/* + * Enable SDHC card interrupt + */ +static int imx_usdhc_enable_interrupt(const struct device *dev, + sdhc_interrupt_cb_t callback, + int sources, void *user_data) +{ + const struct usdhc_config *cfg = dev->config; + struct usdhc_data *data = dev->data; + int ret; + + /* Record SDIO callback parameters */ + data->sdhc_cb = callback; + data->sdhc_cb_user_data = user_data; + + /* Disable interrupts, then enable what the user requested */ + USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag); + USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag); + if (cfg->detect_gpio.port) { + ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, + GPIO_INT_DISABLE); + if (ret) { + return ret; + } + } else { + USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInsertionFlag); + USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInsertionFlag); + USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardRemovalFlag); + USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardRemovalFlag); + } + + if (sources & SDHC_INT_SDIO) { + /* Enable SDIO card interrupt */ + USDHC_EnableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag); + USDHC_EnableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag); + } + if (sources & SDHC_INT_INSERTED) { + if (cfg->detect_gpio.port) { + /* Use GPIO interrupt */ + ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret) { + return ret; + } + } else { + /* Enable card insertion interrupt */ + USDHC_EnableInterruptStatus(cfg->base, + kUSDHC_CardInsertionFlag); + USDHC_EnableInterruptSignal(cfg->base, + kUSDHC_CardInsertionFlag); + } + } + if (sources & SDHC_INT_REMOVED) { + if (cfg->detect_gpio.port) { + /* Use GPIO interrupt */ + ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, + GPIO_INT_EDGE_TO_INACTIVE); + if (ret) { + return ret; + } + } else { + /* Enable card removal interrupt */ + USDHC_EnableInterruptStatus(cfg->base, + kUSDHC_CardRemovalFlag); + USDHC_EnableInterruptSignal(cfg->base, + kUSDHC_CardRemovalFlag); + } + } + + return 0; +} + +static int imx_usdhc_disable_interrupt(const struct device *dev, int sources) +{ + const struct usdhc_config *cfg = dev->config; + struct usdhc_data *data = dev->data; + int ret; + + + if (sources & SDHC_INT_SDIO) { + /* Disable SDIO card interrupt */ + USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag); + USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag); + } + if (sources & SDHC_INT_INSERTED) { + if (cfg->detect_gpio.port) { + ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, + GPIO_INT_DISABLE); + if (ret) { + return ret; + } + } else { + /* Disable card insertion interrupt */ + USDHC_DisableInterruptStatus(cfg->base, + kUSDHC_CardInsertionFlag); + USDHC_DisableInterruptSignal(cfg->base, + kUSDHC_CardInsertionFlag); + } + } + if (sources & SDHC_INT_REMOVED) { + if (cfg->detect_gpio.port) { + ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, + GPIO_INT_DISABLE); + if (ret) { + return ret; + } + } else { + /* Disable card removal interrupt */ + USDHC_DisableInterruptStatus(cfg->base, + kUSDHC_CardRemovalFlag); + USDHC_DisableInterruptSignal(cfg->base, + kUSDHC_CardRemovalFlag); + } + } + + /* If all interrupt flags are disabled, remove callback */ + if ((USDHC_GetEnabledInterruptStatusFlags(cfg->base) & + (kUSDHC_CardInterruptFlag | kUSDHC_CardInsertionFlag | + kUSDHC_CardRemovalFlag)) == 0) { + data->sdhc_cb = NULL; + data->sdhc_cb_user_data = NULL; + } + + return 0; +} + static int imx_usdhc_isr(const struct device *dev) { const struct usdhc_config *cfg = dev->config; @@ -795,6 +973,9 @@ static int imx_usdhc_init(const struct device *dev) int ret; const usdhc_transfer_callback_t callbacks = { .TransferComplete = transfer_complete_cb, + .SdioInterrupt = sdio_interrupt_cb, + .CardInserted = card_inserted_cb, + .CardRemoved = card_removed_cb, }; if (!device_is_ready(cfg->clock_dev)) { @@ -833,7 +1014,14 @@ static int imx_usdhc_init(const struct device *dev) if (ret) { return ret; } + gpio_init_callback(&data->cd_callback, card_detect_gpio_cb, + BIT(cfg->detect_gpio.pin)); + ret = gpio_add_callback_dt(&cfg->detect_gpio, &data->cd_callback); + if (ret) { + return ret; + } } + data->dev = dev; k_mutex_init(&data->access_mutex); memset(&data->host_io, 0, sizeof(data->host_io)); return k_sem_init(&data->transfer_sem, 0, 1); @@ -847,6 +1035,8 @@ static const struct sdhc_driver_api usdhc_api = { .execute_tuning = imx_usdhc_execute_tuning, .card_busy = imx_usdhc_card_busy, .get_host_props = imx_usdhc_get_host_props, + .enable_interrupt = imx_usdhc_enable_interrupt, + .disable_interrupt = imx_usdhc_disable_interrupt, }; #ifdef CONFIG_NOCACHE_MEMORY From 0fc49b6290750282206e5c3649b86de237408c11 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 28 Sep 2023 15:08:46 -0500 Subject: [PATCH 3149/4498] tests: drivers: sdhc: add test for card insertion interrupt Add test for card insertion interrupt to SDHC test. The test will now wait for the card insertion interrupt whenever it is run without a card in the slot. By inserting a card, the user can verify that card insertion interrupts work correctly, as this should notify the test and allow it to proceed. Signed-off-by: Daniel DeGrasse --- tests/drivers/sdhc/src/main.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/drivers/sdhc/src/main.c b/tests/drivers/sdhc/src/main.c index 559884499b0..1ee9b7a1ba9 100644 --- a/tests/drivers/sdhc/src/main.c +++ b/tests/drivers/sdhc/src/main.c @@ -15,6 +15,8 @@ static struct sdhc_io io; #define SDHC_FREQUENCY_SLIP 10000000 +K_SEM_DEFINE(card_sem, 0, 1); + /* Resets SD host controller, verifies API */ ZTEST(sdhc, test_reset) { @@ -73,9 +75,22 @@ ZTEST(sdhc, test_set_io) zassert_not_equal(ret, 0, "Invalid io configuration should not succeed"); } +void sdhc_interrupt_cb(const struct device *dev, int source, const void *data) +{ + ARG_UNUSED(data); + + /* Check that the device pointer is correct */ + zassert_equal(dev, sdhc_dev, "Incorrect device pointer in interrupt callback"); + zassert_equal(source, SDHC_INT_INSERTED, "Got unexpected SDHC interrupt"); + k_sem_give(&card_sem); +} + -/* Verify that the driver can detect a present SD card */ -ZTEST(sdhc, test_card_presence) +/* + * Verify that the driver can detect a present SD card + * This test must run first, to ensure the card is present. + */ +ZTEST(sdhc, test_0_card_presence) { int ret; @@ -85,6 +100,19 @@ ZTEST(sdhc, test_card_presence) k_msleep(props.power_delay); ret = sdhc_card_present(sdhc_dev); + if (ret == 0) { + /* Card not in slot, test card insertion interrupt */ + TC_PRINT("Waiting for card to be present in slot\n"); + ret = sdhc_enable_interrupt(sdhc_dev, sdhc_interrupt_cb, + SDHC_INT_INSERTED, NULL); + zassert_equal(ret, 0, "Could not install card insertion interrupt"); + /* Wait for card insertion */ + ret = k_sem_take(&card_sem, K_FOREVER); + /* Delay now that card is in slot */ + k_msleep(props.power_delay); + zassert_equal(ret, 0, "Card insertion interrupt did not fire"); + ret = sdhc_card_present(sdhc_dev); + } zassert_equal(ret, 1, "Card is not reported as present, is one connected?"); } From c28ffb43054892837225ba518581ba01b853676f Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 18:05:46 -0500 Subject: [PATCH 3150/4498] drivers: sdhc: imx_usdhc: add support for SDIO RW extended command Add support for CMD53 (read/write extended) to imx USDHC driver. Signed-off-by: Daniel DeGrasse --- drivers/sdhc/imx_usdhc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index 0a1896a3fa4..396b7b371bd 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -698,6 +698,14 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd, case SD_APP_SEND_NUM_WRITTEN_BLK: host_data.rxData = data->data; break; + case SDIO_RW_EXTENDED: + /* Use R/W bit to determine data direction */ + if (host_cmd.argument & BIT(SDIO_CMD_ARG_RW_SHIFT)) { + host_data.txData = data->data; + } else { + host_data.rxData = data->data; + } + break; default: return -ENOTSUP; From a517d79efff489a78964a7201cb394f7faa04725 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 18:06:52 -0500 Subject: [PATCH 3151/4498] drivers: sdhc: imx_usdhc: enable DDR50 mode Enable support for DDR50 mode within imx usdhc driver. Signed-off-by: Daniel DeGrasse --- drivers/sdhc/imx_usdhc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index 396b7b371bd..186072fab6b 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -406,6 +406,10 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios) case SDHC_TIMING_LEGACY: case SDHC_TIMING_HS: break; + case SDHC_TIMING_DDR50: + case SDHC_TIMING_DDR52: + /* Enable DDR mode */ + USDHC_EnableDDRMode(cfg->base, true, 0); case SDHC_TIMING_SDR12: case SDHC_TIMING_SDR25: pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_SLOW); @@ -424,8 +428,6 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios) return -ENOTSUP; #endif case SDHC_TIMING_SDR104: - case SDHC_TIMING_DDR50: - case SDHC_TIMING_DDR52: case SDHC_TIMING_HS200: pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_FAST); break; From 7ca3aec97eed6b27e76df7fa6bd4e173b2a21863 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 15:03:37 -0500 Subject: [PATCH 3152/4498] drivers: sdhc: imx_usdhc: Initialize card clock with CMD0 Use CMD0 to detect card initialization, rather than using card power on. Signed-off-by: Daniel DeGrasse --- drivers/sdhc/imx_usdhc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index 186072fab6b..8ae8fa9741f 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -386,16 +386,10 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios) /* Set card power */ if ((host_io->power_mode != ios->power_mode) && (cfg->pwr_gpio.port)) { - if (host_io->power_mode == SDHC_POWER_ON) { - /* Send 74 clock cycles if SD card is just powering on */ - USDHC_SetCardActive(cfg->base, 0xFFFF); - } - if (cfg->pwr_gpio.port) { - if (ios->power_mode == SDHC_POWER_OFF) { - gpio_pin_set_dt(&cfg->pwr_gpio, 0); - } else if (ios->power_mode == SDHC_POWER_ON) { - gpio_pin_set_dt(&cfg->pwr_gpio, 1); - } + if (ios->power_mode == SDHC_POWER_OFF) { + gpio_pin_set_dt(&cfg->pwr_gpio, 0); + } else if (ios->power_mode == SDHC_POWER_ON) { + gpio_pin_set_dt(&cfg->pwr_gpio, 1); } host_io->power_mode = ios->power_mode; } @@ -646,6 +640,10 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd, int ret = 0; int retries = (int)cmd->retries; + if (cmd->opcode == SD_GO_IDLE_STATE) { + USDHC_SetCardActive(cfg->base, 0xFFFF); + } + host_cmd.index = cmd->opcode; host_cmd.argument = cmd->arg; /* Mask out part of response type field used for SPI commands */ From 64878aa115a34e390c530841e06390dca12b6d0c Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:49:48 -0500 Subject: [PATCH 3153/4498] sd: add sdio header file Add SDIO header file, defining functions supported by SDIO subsystem Signed-off-by: Daniel DeGrasse --- include/zephyr/sd/sd.h | 15 +++ include/zephyr/sd/sdio.h | 212 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 include/zephyr/sd/sdio.h diff --git a/include/zephyr/sd/sd.h b/include/zephyr/sd/sd.h index a93aec5f012..69d3057e8ad 100644 --- a/include/zephyr/sd/sd.h +++ b/include/zephyr/sd/sd.h @@ -39,6 +39,19 @@ enum card_type { CARD_MMC = 3, /*!< MMC memory card */ }; +/** + * @brief SDIO function definition + * + * SDIO function definition. Used to store function information + * per each SDIO function + */ +struct sdio_func { + enum sdio_func_num num; /*!< Function number */ + struct sd_card *card; /*!< Card this function is present on */ + struct sdio_cis cis; /*!< CIS tuple data for this function */ + uint16_t block_size; /*!< Current block size for this function */ +}; + /** * @brief SD card structure @@ -65,6 +78,8 @@ struct sd_card { enum card_type type; /*!< Card type */ uint16_t flags; /*!< Card flags */ uint8_t bus_width; /*!< Desired bus width */ + uint32_t cccr_flags; /*!< SDIO CCCR data */ + struct sdio_func func0; /*!< Function 0 common card data */ uint8_t card_buffer[CONFIG_SD_BUFFER_SIZE] __aligned(CONFIG_SDHC_BUFFER_ALIGNMENT); /* Card internal buffer */ }; diff --git a/include/zephyr/sd/sdio.h b/include/zephyr/sd/sdio.h new file mode 100644 index 00000000000..546a68d2bbb --- /dev/null +++ b/include/zephyr/sd/sdio.h @@ -0,0 +1,212 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public API for SDIO subsystem + */ + +#ifndef ZEPHYR_INCLUDE_SD_SDIO_H_ +#define ZEPHYR_INCLUDE_SD_SDIO_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize SDIO function. + * + * Initializes SDIO card function. The card function will not be enabled, + * but after this call returns the SDIO function structure can be used to read + * and write data from the card. + * @param func: function structure to initialize + * @param card: SD card to enable function on + * @param num: function number to initialize + * @retval 0 function was initialized successfully + * @retval -EIO: I/O error + */ +int sdio_init_func(struct sd_card *card, struct sdio_func *func, + enum sdio_func_num num); + +/** + * @brief Enable SDIO function + * + * Enables SDIO card function. @ref sdio_init_func must be called to + * initialized the function structure before enabling it in the card. + * @param func: function to enable + * @retval 0 function was enabled successfully + * @retval -ETIMEDOUT: card I/O timed out + * @retval -EIO: I/O error + */ +int sdio_enable_func(struct sdio_func *func); + +/** + * @brief Set block size of SDIO function + * + * Set desired block size for SDIO function, used by block transfers + * to SDIO registers. + * @param func: function to set block size for + * @param bsize: block size + * @retval 0 block size was set + * @retval -EINVAL: unsupported/invalid block size + * @retval -EIO: I/O error + */ +int sdio_set_block_size(struct sdio_func *func, uint16_t bsize); + +/** + * @brief Read byte from SDIO register + * + * Reads byte from SDIO register + * @param func: function to read from + * @param reg: register address to read from + * @param val: filled with byte value read from register + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_byte(struct sdio_func *func, uint32_t reg, uint8_t *val); + +/** + * @brief Write byte to SDIO register + * + * Writes byte to SDIO register + * @param func: function to write to + * @param reg: register address to write to + * @param write_val: value to write to register + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_byte(struct sdio_func *func, uint32_t reg, uint8_t write_val); + +/** + * @brief Write byte to SDIO register, and read result + * + * Writes byte to SDIO register, and reads the register after write + * @param func: function to write to + * @param reg: register address to write to + * @param write_val: value to write to register + * @param read_val: filled with value read from register + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_rw_byte(struct sdio_func *func, uint32_t reg, uint8_t write_val, + uint8_t *read_val); + +/** + * @brief Read bytes from SDIO fifo + * + * Reads bytes from SDIO register, treating it as a fifo. Reads will + * all be done from same address. + * @param func: function to read from + * @param reg: register address of fifo + * @param data: filled with data read from fifo + * @param len: length of data to read from card + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len); + +/** + * @brief Write bytes to SDIO fifo + * + * Writes bytes to SDIO register, treating it as a fifo. Writes will + * all be done to same address. + * @param func: function to write to + * @param reg: register address of fifo + * @param data: data to write to fifo + * @param len: length of data to write to card + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len); + +/** + * @brief Read blocks from SDIO fifo + * + * Reads blocks from SDIO register, treating it as a fifo. Reads will + * all be done from same address. + * @param func: function to read from + * @param reg: register address of fifo + * @param data: filled with data read from fifo + * @param blocks: number of blocks to read from fifo + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_blocks_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t blocks); + +/** + * @brief Write blocks to SDIO fifo + * + * Writes blocks from SDIO register, treating it as a fifo. Writes will + * all be done to same address. + * @param func: function to write to + * @param reg: register address of fifo + * @param data: data to write to fifo + * @param blocks: number of blocks to write to fifo + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_blocks_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t blocks); + +/** + * @brief Copy bytes from an SDIO card + * + * Copies bytes from an SDIO card, starting from provided address. + * @param func: function to read from + * @param reg: register address to start copy at + * @param data: buffer to copy data into + * @param len: length of data to read + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_addr(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len); + +/** + * @brief Copy bytes to an SDIO card + * + * Copies bytes to an SDIO card, starting from provided address. + * + * @param func: function to write to + * @param reg: register address to start copy at + * @param data: buffer to copy data from + * @param len: length of data to write + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_addr(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_SD_SDMMC_H_ */ From 726128f81076a041bb33d20bb47d2fe90c341ae7 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:11:19 -0500 Subject: [PATCH 3154/4498] sd: add SDIO subsystem add SDIO subsystem code. SDIO subsystem currently supports card initialization, SDIO read/write, SDIO extended read/write, and SDIO card interrupts. Signed-off-by: Daniel DeGrasse --- subsys/sd/Kconfig | 2 + subsys/sd/sdio.c | 1006 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 1001 insertions(+), 7 deletions(-) diff --git a/subsys/sd/Kconfig b/subsys/sd/Kconfig index 37ef6372a77..403eaef341a 100644 --- a/subsys/sd/Kconfig +++ b/subsys/sd/Kconfig @@ -72,6 +72,8 @@ config SD_BUFFER_SIZE default 512 if SDHC_BUFFER_ALIGNMENT != 1 # If MMC is being used, need 512 bytes to read EXT_CSD default 512 if MMC_STACK + # If SDIO is being used, need 512 bytes to read FUNC0 CIS + default 512 if SDIO_STACK # Otherwise, we only need 64 bytes to read SD switch function default 64 help diff --git a/subsys/sd/sdio.c b/subsys/sd/sdio.c index cdf02814443..ea507fbf496 100644 --- a/subsys/sd/sdio.c +++ b/subsys/sd/sdio.c @@ -1,24 +1,31 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include #include #include +#include "sd_ops.h" #include "sd_utils.h" LOG_MODULE_DECLARE(sd, CONFIG_SD_LOG_LEVEL); +uint8_t cis_tuples[] = { + SDIO_TPL_CODE_MANIFID, + SDIO_TPL_CODE_FUNCID, + SDIO_TPL_CODE_FUNCE, +}; + /* * Send SDIO OCR using CMD5 */ -int sdio_send_ocr(struct sd_card *card, uint32_t ocr) +static int sdio_send_ocr(struct sd_card *card, uint32_t ocr) { struct sdhc_command cmd = {0}; int ret; @@ -56,7 +63,482 @@ int sdio_send_ocr(struct sd_card *card, uint32_t ocr) */ return 0; } + /* Check to see if card is busy with power up */ + if (cmd.response[0] & SD_OCR_PWR_BUSY_FLAG) { + break; + } + /* Delay before retrying command */ + sd_delay(10); + } + if (retries >= CONFIG_SD_OCR_RETRY_COUNT) { + /* OCR timed out */ + LOG_ERR("Card never left busy state"); + return -ETIMEDOUT; + } + LOG_DBG("SDIO responded to CMD5 after %d attempts", retries); + if (!card->host_props.is_spi) { + /* Save OCR */ + card->ocr = cmd.response[0U]; + } + return 0; +} + +static int sdio_io_rw_direct(struct sd_card *card, + enum sdio_io_dir direction, + enum sdio_func_num func, + uint32_t reg_addr, + uint8_t data_in, + uint8_t *data_out) +{ + int ret; + struct sdhc_command cmd = {0}; + + cmd.opcode = SDIO_RW_DIRECT; + cmd.arg = (func << SDIO_CMD_ARG_FUNC_NUM_SHIFT) | + ((reg_addr & SDIO_CMD_ARG_REG_ADDR_MASK) << SDIO_CMD_ARG_REG_ADDR_SHIFT); + if (direction == SDIO_IO_WRITE) { + cmd.arg |= data_in & SDIO_DIRECT_CMD_DATA_MASK; + cmd.arg |= BIT(SDIO_CMD_ARG_RW_SHIFT); + if (data_out) { + cmd.arg |= BIT(SDIO_DIRECT_CMD_ARG_RAW_SHIFT); + } + } + cmd.response_type = (SD_RSP_TYPE_R5 | SD_SPI_RSP_TYPE_R5); + cmd.timeout_ms = CONFIG_SD_CMD_TIMEOUT; + + ret = sdhc_request(card->sdhc, &cmd, NULL); + if (ret) { + return ret; + } + if (data_out) { + if (card->host_props.is_spi) { + *data_out = (cmd.response[0U] >> 8) & SDIO_DIRECT_CMD_DATA_MASK; + } else { + *data_out = cmd.response[0U] & SDIO_DIRECT_CMD_DATA_MASK; + } + } + return ret; +} + + +static int sdio_io_rw_extended(struct sd_card *card, + enum sdio_io_dir direction, + enum sdio_func_num func, + uint32_t reg_addr, + bool increment, + uint8_t *buf, + uint32_t blocks, + uint32_t block_size) +{ + struct sdhc_command cmd = {0}; + struct sdhc_data data = {0}; + + cmd.opcode = SDIO_RW_EXTENDED; + cmd.arg = (func << SDIO_CMD_ARG_FUNC_NUM_SHIFT) | + ((reg_addr & SDIO_CMD_ARG_REG_ADDR_MASK) << SDIO_CMD_ARG_REG_ADDR_SHIFT); + cmd.arg |= (direction == SDIO_IO_WRITE) ? BIT(SDIO_CMD_ARG_RW_SHIFT) : 0; + cmd.arg |= increment ? BIT(SDIO_EXTEND_CMD_ARG_OP_CODE_SHIFT) : 0; + cmd.response_type = (SD_RSP_TYPE_R5 | SD_SPI_RSP_TYPE_R5); + cmd.timeout_ms = CONFIG_SD_CMD_TIMEOUT; + if (blocks == 0) { + /* Byte mode */ + cmd.arg |= (block_size == 512) ? 0 : block_size; + } else { + /* Block mode */ + cmd.arg |= BIT(SDIO_EXTEND_CMD_ARG_BLK_SHIFT) | blocks; } + + data.block_size = block_size; + /* Host expects blocks to be at least 1 */ + data.blocks = blocks ? blocks : 1; + data.data = buf; + data.timeout_ms = CONFIG_SD_DATA_TIMEOUT; + return sdhc_request(card->sdhc, &cmd, &data); +} + +/* + * Helper for extended r/w. Splits the transfer into the minimum possible + * number of block r/w, then uses byte transfers for remaining data + */ +static int sdio_io_rw_extended_helper(struct sdio_func *func, + enum sdio_io_dir direction, + uint32_t reg_addr, + bool increment, + uint8_t *buf, + uint32_t len) +{ + int ret; + int remaining = len; + uint32_t blocks, size; + + if (func->num > SDIO_MAX_IO_NUMS) { + return -EINVAL; + } + + if ((func->card->cccr_flags & SDIO_SUPPORT_MULTIBLOCK) && + ((len > func->block_size))) { + /* Use block I/O for r/w where possible */ + while (remaining >= func->block_size) { + blocks = remaining / func->block_size; + size = blocks * func->block_size; + ret = sdio_io_rw_extended(func->card, direction, + func->num, reg_addr, increment, buf, blocks, + func->block_size); + if (ret) { + return ret; + } + /* Update remaining length and buffer pointer */ + remaining -= size; + buf += size; + if (increment) { + reg_addr += size; + } + } + } + /* Remaining data must be written using byte I/O */ + while (remaining > 0) { + size = MIN(remaining, func->cis.max_blk_size); + + ret = sdio_io_rw_extended(func->card, direction, func->num, + reg_addr, increment, buf, 0, size); + if (ret) { + return ret; + } + remaining -= size; + buf += size; + if (increment) { + reg_addr += size; + } + } + return 0; +} + +/* + * Read card capability register to determine features card supports. + */ +static int sdio_read_cccr(struct sd_card *card) +{ + int ret; + uint8_t data; + uint32_t cccr_ver; + + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_CCCR, 0, &data); + if (ret) { + LOG_DBG("CCCR read failed: %d", ret); + return ret; + } + cccr_ver = (data & SDIO_CCCR_CCCR_REV_MASK) >> + SDIO_CCCR_CCCR_REV_SHIFT; + LOG_DBG("SDIO cccr revision %u", cccr_ver); + /* Read SD spec version */ + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_SD, 0, &data); + if (ret) { + return ret; + } + card->sd_version = (data & SDIO_CCCR_SD_SPEC_MASK) >> SDIO_CCCR_SD_SPEC_SHIFT; + /* Read CCCR capability flags */ + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_CAPS, 0, &data); + if (ret) { + return ret; + } + card->cccr_flags = 0; + if (data & SDIO_CCCR_CAPS_BLS) { + card->cccr_flags |= SDIO_SUPPORT_4BIT_LS_BUS; + } + if (data & SDIO_CCCR_CAPS_SMB) { + card->cccr_flags |= SDIO_SUPPORT_MULTIBLOCK; + } + if (cccr_ver >= SDIO_CCCR_CCCR_REV_2_00) { + /* Read high speed properties */ + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_SPEED, 0, &data); + if (ret) { + return ret; + } + if (data & SDIO_CCCR_SPEED_SHS) { + card->cccr_flags |= SDIO_SUPPORT_HS; + } + } + if (cccr_ver >= SDIO_CCCR_CCCR_REV_3_00 && + (card->flags & SD_1800MV_FLAG)) { + /* Read UHS properties */ + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_UHS, 0, &data); + if (ret) { + return ret; + } + if (sdmmc_host_uhs(&card->host_props)) { + if (data & SDIO_CCCR_UHS_SDR50) { + card->cccr_flags |= SDIO_SUPPORT_SDR50; + } + if (data & SDIO_CCCR_UHS_SDR104) { + card->cccr_flags |= SDIO_SUPPORT_SDR104; + } + if (data & SDIO_CCCR_UHS_DDR50) { + card->cccr_flags |= SDIO_SUPPORT_DDR50; + } + } + + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_DRIVE_STRENGTH, 0, &data); + if (ret) { + return ret; + } + card->switch_caps.sd_drv_type = 0; + if (data & SDIO_CCCR_DRIVE_STRENGTH_A) { + card->switch_caps.sd_drv_type |= SD_DRIVER_TYPE_A; + } + if (data & SDIO_CCCR_DRIVE_STRENGTH_C) { + card->switch_caps.sd_drv_type |= SD_DRIVER_TYPE_C; + } + if (data & SDIO_CCCR_DRIVE_STRENGTH_D) { + card->switch_caps.sd_drv_type |= SD_DRIVER_TYPE_D; + } + } + return 0; +} + +static void sdio_decode_cis(struct sdio_cis *cis, enum sdio_func_num func, + uint8_t *data, uint8_t tpl_code, uint8_t tpl_link) +{ + switch (tpl_code) { + case SDIO_TPL_CODE_MANIFID: + cis->manf_id = data[0] | ((uint16_t)data[1] << 8); + cis->manf_code = data[2] | ((uint16_t)data[3] << 8); + break; + case SDIO_TPL_CODE_FUNCID: + cis->func_id = data[0]; + break; + case SDIO_TPL_CODE_FUNCE: + if (func == 0) { + cis->max_blk_size = data[1] | ((uint16_t)data[2] << 8); + cis->max_speed = data[3]; + } else { + cis->max_blk_size = data[12] | ((uint16_t)data[13] << 8); + cis->rdy_timeout = data[28] | ((uint16_t)data[29] << 8); + } + break; + default: + LOG_WRN("Unknown CIS tuple %d", tpl_code); + break; + } +} + +/* + * Read CIS for a given SDIO function. + * Tuples provides a list of tuples that should be decoded. + */ +static int sdio_read_cis(struct sdio_func *func, + uint8_t *tuples, + uint32_t tuple_count) +{ + int ret; + char *data = func->card->card_buffer; + uint32_t cis_ptr = 0, num = 0; + uint8_t tpl_code, tpl_link; + bool match_tpl = false; + + memset(&func->cis, 0, sizeof(struct sdio_cis)); + /* First find the CIS pointer for this function */ + for (int i = 0; i < 3; i++) { + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_FBR_BASE(func->num) + SDIO_FBR_CIS + i, 0, data); + if (ret) { + return ret; + } + cis_ptr |= *data << (i * 8); + } + /* Read CIS tuples until we have read all requested CIS tuple codes */ + do { + /* Read tuple code */ + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + cis_ptr++, 0, &tpl_code); + if (ret) { + return ret; + } + if (tpl_code == SDIO_TPL_CODE_END) { + /* End of tuple chain */ + break; + } + if (tpl_code == SDIO_TPL_CODE_NULL) { + /* Skip NULL tuple */ + continue; + } + /* Read tuple link */ + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + cis_ptr++, 0, &tpl_link); + if (ret) { + return ret; + } + if (tpl_link == SDIO_TPL_CODE_END) { + /* End of tuple chain */ + break; + } + /* Check to see if read tuple matches any we should look for */ + for (int i = 0; i < tuple_count; i++) { + if (tpl_code == tuples[i]) { + match_tpl = true; + break; + } + } + if (match_tpl) { + /* tuple chains may be maximum of 255 bytes long */ + memset(data, 0, 255); + for (int i = 0; i < tpl_link; i++) { + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, + SDIO_FUNC_NUM_0, cis_ptr++, 0, data + i); + if (ret) { + return ret; + } + } + num++; + match_tpl = false; + /* Decode the CIS data we read */ + sdio_decode_cis(&func->cis, func->num, data, + tpl_code, tpl_link); + } else { + /* Advance CIS pointer */ + cis_ptr += tpl_link; + } + } while (num < tuple_count); + LOG_DBG("SDIO CIS max block size for func %d: %d", func->num, + func->cis.max_blk_size); + return ret; +} + +static int sdio_set_bus_width(struct sd_card *card, enum sdhc_bus_width width) +{ + uint8_t reg_bus_interface = 0U; + int ret; + + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_BUS_IF, 0, ®_bus_interface); + if (ret) { + return ret; + } + reg_bus_interface &= ~SDIO_CCCR_BUS_IF_WIDTH_MASK; + switch (width) { + case SDHC_BUS_WIDTH1BIT: + reg_bus_interface |= SDIO_CCCR_BUS_IF_WIDTH_1_BIT; + break; + case SDHC_BUS_WIDTH4BIT: + reg_bus_interface |= SDIO_CCCR_BUS_IF_WIDTH_4_BIT; + break; + case SDHC_BUS_WIDTH8BIT: + reg_bus_interface |= SDIO_CCCR_BUS_IF_WIDTH_8_BIT; + break; + default: + return -ENOTSUP; + } + ret = sdio_io_rw_direct(card, SDIO_IO_WRITE, SDIO_FUNC_NUM_0, + SDIO_CCCR_BUS_IF, reg_bus_interface, ®_bus_interface); + if (ret) { + return ret; + } + /* Card now has changed bus width. Change host bus width */ + card->bus_io.bus_width = width; + ret = sdhc_set_io(card->sdhc, &card->bus_io); + if (ret) { + LOG_DBG("Could not change host bus width"); + } + return ret; +} + +static inline void sdio_select_bus_speed(struct sd_card *card) +{ + if (card->host_props.host_caps.sdr104_support && + (card->cccr_flags & SDIO_SUPPORT_SDR104) && + (card->host_props.f_max >= SD_CLOCK_208MHZ)) { + card->card_speed = SD_TIMING_SDR104; + } else if (card->host_props.host_caps.ddr50_support && + (card->cccr_flags & SDIO_SUPPORT_DDR50) && + (card->host_props.f_max >= SD_CLOCK_50MHZ)) { + card->card_speed = SD_TIMING_DDR50; + } else if (card->host_props.host_caps.sdr50_support && + (card->cccr_flags & SDIO_SUPPORT_SDR50) && + (card->host_props.f_max >= SD_CLOCK_100MHZ)) { + card->card_speed = SD_TIMING_SDR50; + } else if (card->host_props.host_caps.high_spd_support && + (card->switch_caps.bus_speed & SDIO_SUPPORT_HS) && + (card->host_props.f_max >= SD_CLOCK_50MHZ)) { + card->card_speed = SD_TIMING_SDR25; + } else { + card->card_speed = SD_TIMING_SDR12; + } +} + +/* Applies selected card bus speed to card and host */ +static int sdio_set_bus_speed(struct sd_card *card) +{ + int ret, timing, retries = CONFIG_SD_RETRY_COUNT; + uint8_t speed_reg, target_speed; + + switch (card->card_speed) { + /* Set bus clock speed */ + case SD_TIMING_SDR104: + card->switch_caps.uhs_max_dtr = SD_CLOCK_208MHZ; + target_speed = SDIO_CCCR_SPEED_SDR104; + timing = SDHC_TIMING_SDR104; + break; + case SD_TIMING_DDR50: + card->switch_caps.uhs_max_dtr = SD_CLOCK_50MHZ; + target_speed = SDIO_CCCR_SPEED_DDR50; + timing = SDHC_TIMING_DDR50; + break; + case SD_TIMING_SDR50: + card->switch_caps.uhs_max_dtr = SD_CLOCK_100MHZ; + target_speed = SDIO_CCCR_SPEED_SDR50; + timing = SDHC_TIMING_SDR50; + break; + case SD_TIMING_SDR25: + card->switch_caps.uhs_max_dtr = SD_CLOCK_50MHZ; + target_speed = SDIO_CCCR_SPEED_SDR25; + timing = SDHC_TIMING_SDR25; + break; + case SD_TIMING_SDR12: + card->switch_caps.uhs_max_dtr = SD_CLOCK_25MHZ; + target_speed = SDIO_CCCR_SPEED_SDR12; + timing = SDHC_TIMING_SDR12; + break; + default: + /* No need to change bus speed */ + return 0; + } + /* Read the bus speed register */ + ret = sdio_io_rw_direct(card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_SPEED, 0, &speed_reg); + if (ret) { + return ret; + } + /* Attempt to set speed several times */ + do { + /* Set new speed */ + speed_reg &= ~SDIO_CCCR_SPEED_MASK; + speed_reg |= (target_speed << SDIO_CCCR_SPEED_SHIFT); + ret = sdio_io_rw_direct(card, SDIO_IO_WRITE, SDIO_FUNC_NUM_0, + SDIO_CCCR_SPEED, speed_reg, &speed_reg); + if (ret) { + return ret; + } + } while (((speed_reg & target_speed) != target_speed) && retries-- > 0); + if (retries == 0) { + /* Don't error out, as card can still work */ + LOG_WRN("Could not set target SDIO speed"); + } else { + /* Set card bus clock and timing */ + card->bus_io.timing = timing; + card->bus_io.clock = card->switch_caps.uhs_max_dtr; + LOG_DBG("Setting bus clock to: %d", card->bus_io.clock); + ret = sdhc_set_io(card->sdhc, &card->bus_io); + if (ret) { + LOG_ERR("Failed to change host bus speed"); + return ret; + } + } + return ret; } /* @@ -65,14 +547,524 @@ int sdio_send_ocr(struct sd_card *card, uint32_t ocr) int sdio_card_init(struct sd_card *card) { int ret; + uint32_t ocr_arg = 0U; /* Probe card with SDIO OCR CM5 */ - ret = sdio_send_ocr(card, 0); + ret = sdio_send_ocr(card, ocr_arg); if (ret) { return ret; } - /* Card responded to ACMD41, type is SDIO */ + /* Card responded to CMD5, type is SDIO */ card->type = CARD_SDIO; - /* No support for SDIO */ - return -ENOTSUP; + /* Set voltage window */ + if (card->host_props.host_caps.vol_300_support) { + ocr_arg |= SD_OCR_VDD29_30FLAG; + } + ocr_arg |= (SD_OCR_VDD32_33FLAG | SD_OCR_VDD33_34FLAG); + if (IS_ENABLED(CONFIG_SDHC_SUPPORTS_NATIVE_MODE) && + card->host_props.host_caps.vol_180_support) { + /* See if the card also supports 1.8V */ + ocr_arg |= SD_OCR_SWITCH_18_REQ_FLAG; + } + ret = sdio_send_ocr(card, ocr_arg); + if (ret) { + return ret; + } + if (card->ocr & SD_OCR_SWITCH_18_ACCEPT_FLAG) { + LOG_DBG("Card supports 1.8V signalling"); + card->flags |= SD_1800MV_FLAG; + } + /* Check OCR voltage window */ + if (card->ocr & SD_OCR_VDD29_30FLAG) { + card->flags |= SD_3000MV_FLAG; + } + /* Check mem present flag */ + if (card->ocr & SDIO_OCR_MEM_PRESENT_FLAG) { + card->flags |= SD_MEM_PRESENT_FLAG; + } + /* Following steps are only required when using native SD mode */ + if (IS_ENABLED(CONFIG_SDHC_SUPPORTS_NATIVE_MODE)) { + /* + * If card and host support 1.8V, perform voltage switch sequence now. + * note that we skip this switch if the UHS protocol is not enabled. + */ + if ((card->flags & SD_1800MV_FLAG) && + (!card->host_props.is_spi) && + (card->host_props.host_caps.vol_180_support) && + IS_ENABLED(CONFIG_SD_UHS_PROTOCOL)) { + ret = sdmmc_switch_voltage(card); + if (ret) { + /* Disable host support for 1.8 V */ + card->host_props.host_caps.vol_180_support = false; + /* + * The host or SD card may have already switched to + * 1.8V. Return SD_RESTART to indicate + * negotiation should be restarted. + */ + card->status = CARD_ERROR; + return SD_RESTART; + } + } + if ((card->flags & SD_MEM_PRESENT_FLAG) && + ((card->flags & SD_SDHC_FLAG) == 0)) { + /* We must send CMD2 to get card cid */ + ret = card_read_cid(card); + if (ret) { + return ret; + } + } + /* Send CMD3 to get card relative address */ + ret = sdmmc_request_rca(card); + if (ret) { + return ret; + } + /* Move the card to transfer state (with CMD7) to run + * remaining commands + */ + ret = sdmmc_select_card(card); + if (ret) { + return ret; + } + } + /* Read SDIO card common control register */ + ret = sdio_read_cccr(card); + if (ret) { + return ret; + } + /* Initialize internal card function 0 structure */ + card->func0.num = SDIO_FUNC_NUM_0; + card->func0.card = card; + ret = sdio_read_cis(&card->func0, cis_tuples, + ARRAY_SIZE(cis_tuples)); + if (ret) { + return ret; + } + + /* If card and host support 4 bit bus, enable it */ + if (IS_ENABLED(CONFIG_SDHC_SUPPORTS_NATIVE_MODE) && + ((card->cccr_flags & SDIO_SUPPORT_HS) || + (card->cccr_flags & SDIO_SUPPORT_4BIT_LS_BUS))) { + /* Raise bus width to 4 bits */ + ret = sdio_set_bus_width(card, SDHC_BUS_WIDTH4BIT); + if (ret) { + return ret; + } + LOG_DBG("Raised card bus width to 4 bits"); + } + + /* Select and set bus speed */ + sdio_select_bus_speed(card); + ret = sdio_set_bus_speed(card); + if (ret) { + return ret; + } + if (card->card_speed == SD_TIMING_SDR50 || + card->card_speed == SD_TIMING_SDR104) { + /* SDR104, SDR50, and DDR50 mode need tuning */ + ret = sdhc_execute_tuning(card->sdhc); + if (ret) { + LOG_ERR("SD tuning failed: %d", ret); + } + } + return ret; +} + +/** + * @brief Initialize SDIO function. + * + * Initializes SDIO card function. The card function will not be enabled, + * but after this call returns the SDIO function structure can be used to read + * and write data from the card. + * @param func: function structure to initialize + * @param card: SD card to enable function on + * @param num: function number to initialize + * @retval 0 function was initialized successfully + * @retval -EIO: I/O error + */ +int sdio_init_func(struct sd_card *card, struct sdio_func *func, + enum sdio_func_num num) +{ + /* Initialize function structure */ + func->num = num; + func->card = card; + func->block_size = 0; + /* Read function properties from CCCR */ + return sdio_read_cis(func, cis_tuples, ARRAY_SIZE(cis_tuples)); +} + + + +/** + * @brief Enable SDIO function + * + * Enables SDIO card function. @ref sdio_init_func must be called to + * initialized the function structure before enabling it in the card. + * @param func: function to enable + * @retval 0 function was enabled successfully + * @retval -ETIMEDOUT: card I/O timed out + * @retval -EIO: I/O error + */ +int sdio_enable_func(struct sdio_func *func) +{ + int ret; + uint8_t reg; + uint16_t retries = CONFIG_SD_RETRY_COUNT; + + /* Enable the I/O function */ + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, SDIO_FUNC_NUM_0, + SDIO_CCCR_IO_EN, 0, ®); + if (ret) { + return ret; + } + reg |= BIT(func->num); + ret = sdio_io_rw_direct(func->card, SDIO_IO_WRITE, SDIO_FUNC_NUM_0, + SDIO_CCCR_IO_EN, reg, ®); + if (ret) { + return ret; + } + /* Wait for I/O ready to be set */ + if (func->cis.rdy_timeout) { + retries = 1U; + } + do { + /* Timeout is in units of 10ms */ + sd_delay(((uint32_t)func->cis.rdy_timeout) * 10U); + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, + SDIO_FUNC_NUM_0, SDIO_CCCR_IO_RD, 0, ®); + if (ret) { + return ret; + } + if (reg & BIT(func->num)) { + return 0; + } + } while (retries-- != 0); + return -ETIMEDOUT; +} + +/** + * @brief Set block size of SDIO function + * + * Set desired block size for SDIO function, used by block transfers + * to SDIO registers. + * @param func: function to set block size for + * @param bsize: block size + * @retval 0 block size was set + * @retval -EINVAL: unsupported/invalid block size + * @retval -EIO: I/O error + */ +int sdio_set_block_size(struct sdio_func *func, uint16_t bsize) +{ + int ret; + uint8_t reg; + + if (func->cis.max_blk_size < bsize) { + return -EINVAL; + } + for (int i = 0; i < 2; i++) { + reg = (bsize >> (i * 8)); + ret = sdio_io_rw_direct(func->card, SDIO_IO_WRITE, SDIO_FUNC_NUM_0, + SDIO_FBR_BASE(func->num) + SDIO_FBR_BLK_SIZE + i, reg, NULL); + if (ret) { + return ret; + } + } + func->block_size = bsize; + return 0; +} + +/** + * @brief Read byte from SDIO register + * + * Reads byte from SDIO register + * @param func: function to read from + * @param reg: register address to read from + * @param val: filled with byte value read from register + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_byte(struct sdio_func *func, uint32_t reg, uint8_t *val) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_direct(func->card, SDIO_IO_READ, func->num, reg, 0, val); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Write byte to SDIO register + * + * Writes byte to SDIO register + * @param func: function to write to + * @param reg: register address to write to + * @param write_val: value to write to register + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_byte(struct sdio_func *func, uint32_t reg, uint8_t write_val) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_direct(func->card, SDIO_IO_WRITE, func->num, reg, + write_val, NULL); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Write byte to SDIO register, and read result + * + * Writes byte to SDIO register, and reads the register after write + * @param func: function to write to + * @param reg: register address to write to + * @param write_val: value to write to register + * @param read_val: filled with value read from register + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_rw_byte(struct sdio_func *func, uint32_t reg, uint8_t write_val, + uint8_t *read_val) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_direct(func->card, SDIO_IO_WRITE, func->num, reg, + write_val, read_val); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Read bytes from SDIO fifo + * + * Reads bytes from SDIO register, treating it as a fifo. Reads will + * all be done from same address. + * @param func: function to read from + * @param reg: register address of fifo + * @param data: filled with data read from fifo + * @param len: length of data to read from card + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended_helper(func, SDIO_IO_READ, reg, false, + data, len); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Write bytes to SDIO fifo + * + * Writes bytes to SDIO register, treating it as a fifo. Writes will + * all be done to same address. + * @param func: function to write to + * @param reg: register address of fifo + * @param data: data to write to fifo + * @param len: length of data to write to card + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended_helper(func, SDIO_IO_WRITE, reg, false, + data, len); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Read blocks from SDIO fifo + * + * Reads blocks from SDIO register, treating it as a fifo. Reads will + * all be done from same address. + * @param func: function to read from + * @param reg: register address of fifo + * @param data: filled with data read from fifo + * @param blocks: number of blocks to read from fifo + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_blocks_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t blocks) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended(func->card, SDIO_IO_READ, func->num, reg, + false, data, blocks, func->block_size); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Write blocks to SDIO fifo + * + * Writes blocks from SDIO register, treating it as a fifo. Writes will + * all be done to same address. + * @param func: function to write to + * @param reg: register address of fifo + * @param data: data to write to fifo + * @param blocks: number of blocks to write to fifo + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_blocks_fifo(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t blocks) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended(func->card, SDIO_IO_WRITE, func->num, reg, + false, data, blocks, func->block_size); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Copy bytes from an SDIO card + * + * Copies bytes from an SDIO card, starting from provided address. + * @param func: function to read from + * @param reg: register address to start copy at + * @param data: buffer to copy data into + * @param len: length of data to read + * @retval 0 read succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card read timed out + * @retval -EIO: I/O error + */ +int sdio_read_addr(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended_helper(func, SDIO_IO_READ, reg, true, + data, len); + k_mutex_unlock(&func->card->lock); + return ret; +} + +/** + * @brief Copy bytes to an SDIO card + * + * Copies bytes to an SDIO card, starting from provided address. + * + * @param func: function to write to + * @param reg: register address to start copy at + * @param data: buffer to copy data from + * @param len: length of data to write + * @retval 0 write succeeded + * @retval -EBUSY: card is busy with another request + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdio_write_addr(struct sdio_func *func, uint32_t reg, uint8_t *data, + uint32_t len) +{ + int ret; + + if ((func->card->type != CARD_SDIO) && (func->card->type != CARD_COMBO)) { + LOG_WRN("Card does not support SDIO commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&func->card->lock, K_NO_WAIT); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = sdio_io_rw_extended_helper(func, SDIO_IO_WRITE, reg, true, + data, len); + k_mutex_unlock(&func->card->lock); + return ret; } From 6a31ed50b8294cf46e968511c70b9570f20159d1 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Mon, 15 Aug 2022 16:20:37 -0500 Subject: [PATCH 3155/4498] tests: add test for SDIO subsystem Add test to verify SDIO subsystem. Note that due to the nature of SDIO cards, this test only reads from common registers and does not verify extended reads or writes. Signed-off-by: Daniel DeGrasse --- tests/subsys/sd/sdio/CMakeLists.txt | 8 ++ tests/subsys/sd/sdio/README.txt | 18 +++++ tests/subsys/sd/sdio/prj.conf | 5 ++ tests/subsys/sd/sdio/src/main.c | 114 ++++++++++++++++++++++++++++ tests/subsys/sd/sdio/testcase.yaml | 13 ++++ 5 files changed, 158 insertions(+) create mode 100644 tests/subsys/sd/sdio/CMakeLists.txt create mode 100644 tests/subsys/sd/sdio/README.txt create mode 100644 tests/subsys/sd/sdio/prj.conf create mode 100644 tests/subsys/sd/sdio/src/main.c create mode 100644 tests/subsys/sd/sdio/testcase.yaml diff --git a/tests/subsys/sd/sdio/CMakeLists.txt b/tests/subsys/sd/sdio/CMakeLists.txt new file mode 100644 index 00000000000..1a5c25efd91 --- /dev/null +++ b/tests/subsys/sd/sdio/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(sdmmc_subsys_test) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/sd/sdio/README.txt b/tests/subsys/sd/sdio/README.txt new file mode 100644 index 00000000000..f037480c4e7 --- /dev/null +++ b/tests/subsys/sd/sdio/README.txt @@ -0,0 +1,18 @@ +SDIO Subsystem Test +################## + +This test is designed to verify the SD subsystem stack implementation for SDIO +devices. Note that this test will only perform basic reads from the SDIO card +after initialization, as most registers present on the card will be vendor +specific. It requires an SDIO card be connected to the board to pass. +The test has the following phases: + +* Init test: verify the SD host controller can detect card presence, and + test the initialization flow of the SDIO subsystem to verify that the stack + can correctly initialize an SDIO card. + +* Read test: verify that a read from the SDIO common card register area returns + valid data. + +* Configuration test: verify that the SD stack reports a valid configuration + for this card after initialization. diff --git a/tests/subsys/sd/sdio/prj.conf b/tests/subsys/sd/sdio/prj.conf new file mode 100644 index 00000000000..7c1034503df --- /dev/null +++ b/tests/subsys/sd/sdio/prj.conf @@ -0,0 +1,5 @@ +CONFIG_TEST=y +CONFIG_ZTEST=y +CONFIG_SDHC=y +CONFIG_SDIO_STACK=y +CONFIG_LOG=y diff --git a/tests/subsys/sd/sdio/src/main.c b/tests/subsys/sd/sdio/src/main.c new file mode 100644 index 00000000000..ad311904b4e --- /dev/null +++ b/tests/subsys/sd/sdio/src/main.c @@ -0,0 +1,114 @@ +/* + * Copyright 2022 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + + +static const struct device *sdhc_dev = DEVICE_DT_GET(DT_ALIAS(sdhc0)); +static struct sd_card card; + +/* + * Verify that SD stack can initialize an SDIO card. + * This test must run first, to ensure the card is initialized. + */ +ZTEST(sd_stack, test_0_init) +{ + int ret; + + zassert_true(device_is_ready(sdhc_dev), "SDHC device is not ready"); + + ret = sd_is_card_present(sdhc_dev); + zassert_equal(ret, 1, "SD card not present in slot"); + + ret = sd_init(sdhc_dev, &card); + zassert_equal(ret, 0, "Card initialization failed"); +} + +/* + * Verify that a register read works. Given the custom nature of SDIO devices, + * we just read from the card common I/O area. + */ +ZTEST(sd_stack, test_read) +{ + int ret; + uint8_t reg = 0xFF; + + /* Read from card common I/O area. */ + ret = sdio_read_byte(&card.func0, SDIO_CCCR_CCCR, ®); + zassert_equal(ret, 0, "SD card read failed"); + /* Check to make sure CCCR read actually returned valid data */ + zassert_not_equal(reg, 0xFF, "CCCR read returned invalid data"); +} + +/* Simply dump the card configuration. */ +ZTEST(sd_stack, test_card_config) +{ + switch (card.card_voltage) { + case SD_VOL_1_2_V: + TC_PRINT("Card voltage: 1.2V\n"); + break; + case SD_VOL_1_8_V: + TC_PRINT("Card voltage: 1.8V\n"); + break; + case SD_VOL_3_0_V: + TC_PRINT("Card voltage: 3.0V\n"); + break; + case SD_VOL_3_3_V: + TC_PRINT("Card voltage: 3.3V\n"); + break; + default: + zassert_unreachable("Card voltage is not known value"); + } + zassert_equal(card.status, CARD_INITIALIZED, "Card status is not OK"); + switch (card.card_speed) { + case SD_TIMING_SDR12: + TC_PRINT("Card timing: SDR12\n"); + break; + case SD_TIMING_SDR25: + TC_PRINT("Card timing: SDR25\n"); + break; + case SD_TIMING_SDR50: + TC_PRINT("Card timing: SDR50\n"); + break; + case SD_TIMING_SDR104: + TC_PRINT("Card timing: SDR104\n"); + break; + case SD_TIMING_DDR50: + TC_PRINT("Card timing: DDR50\n"); + break; + default: + zassert_unreachable("Card timing is not known value"); + } + switch (card.type) { + case CARD_SDIO: + TC_PRINT("Card type: SDIO\n"); + break; + case CARD_SDMMC: + TC_PRINT("Card type: SDMMC\n"); + break; + case CARD_COMBO: + TC_PRINT("Card type: combo card\n"); + break; + default: + zassert_unreachable("Card type is not known value"); + } + if (card.sd_version >= SD_SPEC_VER3_0) { + TC_PRINT("Card spec: 3.0\n"); + } else if (card.sd_version >= SD_SPEC_VER2_0) { + TC_PRINT("Card spec: 2.0\n"); + } else if (card.sd_version >= SD_SPEC_VER1_1) { + TC_PRINT("Card spec: 1.1\n"); + } else if (card.sd_version >= SD_SPEC_VER1_0) { + TC_PRINT("Card spec: 1.0\n"); + } else { + zassert_unreachable("Card spec is unknown value"); + } +} + +ZTEST_SUITE(sd_stack, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/sd/sdio/testcase.yaml b/tests/subsys/sd/sdio/testcase.yaml new file mode 100644 index 00000000000..a19e17dab4c --- /dev/null +++ b/tests/subsys/sd/sdio/testcase.yaml @@ -0,0 +1,13 @@ +common: + depends_on: sdhc + tags: drivers sdhc +tests: + sd.sdio: + harness: ztest + harness_config: + fixture: fixture_sdhc + filter: dt_alias_exists("sdhc0") + tags: sdhc + min_ram: 32 + integration_platforms: + - mimxrt1064_evk From c777ef255b1d0a695e3afcab1ed3af92d49887e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sat, 4 Nov 2023 09:10:03 +0700 Subject: [PATCH 3156/4498] spi: nxp_s32: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Signed-off-by: Manuel Argüelles --- drivers/spi/spi_nxp_s32.c | 114 ++++++++++++++------------------------ drivers/spi/spi_nxp_s32.h | 1 - west.yml | 2 +- 3 files changed, 44 insertions(+), 73 deletions(-) diff --git a/drivers/spi/spi_nxp_s32.c b/drivers/spi/spi_nxp_s32.c index f0d59ea443d..5acfa1c68a8 100644 --- a/drivers/spi/spi_nxp_s32.c +++ b/drivers/spi/spi_nxp_s32.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_spi + #include #include #include "spi_nxp_s32.h" @@ -58,7 +60,8 @@ static int spi_nxp_s32_transfer_next_packet(const struct device *dev) * Keep CS signal asserted until the last package, there is no other way * than directly intervening to internal state of low level driver */ - Spi_Ip_apxStateStructureArray[config->instance]->KeepCs = !spi_nxp_s32_last_packet(data); + Spi_Ip_apxStateStructureArray[config->spi_hw_cfg->Instance]->KeepCs = + !spi_nxp_s32_last_packet(data); status = Spi_Ip_AsyncTransmit(&data->transfer_cfg, (uint8_t *)data->ctx.tx_buf, data->ctx.rx_buf, data->transfer_len, data_cb); @@ -72,11 +75,11 @@ static int spi_nxp_s32_transfer_next_packet(const struct device *dev) return 0; #else - while (Spi_Ip_GetStatus(config->instance) == SPI_IP_BUSY) { - Spi_Ip_ManageBuffers(config->instance); + while (Spi_Ip_GetStatus(config->spi_hw_cfg->Instance) == SPI_IP_BUSY) { + Spi_Ip_ManageBuffers(config->spi_hw_cfg->Instance); } - if (Spi_Ip_GetStatus(config->instance) == SPI_IP_FAULT) { + if (Spi_Ip_GetStatus(config->spi_hw_cfg->Instance) == SPI_IP_FAULT) { return -EIO; } @@ -528,7 +531,7 @@ static int spi_nxp_s32_init(const struct device *dev) } #ifdef CONFIG_NXP_S32_SPI_INTERRUPT - if (Spi_Ip_UpdateTransferMode(config->instance, SPI_IP_INTERRUPT)) { + if (Spi_Ip_UpdateTransferMode(config->spi_hw_cfg->Instance, SPI_IP_INTERRUPT)) { return -EBUSY; } @@ -566,6 +569,13 @@ static int spi_nxp_s32_init(const struct device *dev) #ifdef CONFIG_NXP_S32_SPI_INTERRUPT +void spi_nxp_s32_isr(const struct device *dev) +{ + const struct spi_nxp_s32_config *config = dev->config; + + Spi_Ip_IrqHandler(config->spi_hw_cfg->Instance); +} + static void spi_nxp_s32_transfer_callback(const struct device *dev, Spi_Ip_EventType event) { struct spi_nxp_s32_data *data = dev->data; @@ -601,12 +611,17 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { .release = spi_nxp_s32_release, }; -#define SPI_NXP_S32_NODE(n) DT_NODELABEL(spi##n) -#define SPI_NXP_S32_NUM_CS(n) DT_PROP(SPI_NXP_S32_NODE(n), num_cs) -#define SPI_NXP_S32_IS_MASTER(n) !DT_PROP(SPI_NXP_S32_NODE(n), slave) +#define SPI_NXP_S32_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_SPI_##i##_BASE) ? i : 0) + +#define SPI_NXP_S32_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET SPI_INSTANCE_COUNT, SPI_NXP_S32_HW_INSTANCE_CHECK, (|), n) + +#define SPI_NXP_S32_NUM_CS(n) DT_INST_PROP(n, num_cs) +#define SPI_NXP_S32_IS_MASTER(n) !DT_INST_PROP(n, slave) #ifdef CONFIG_SPI_SLAVE -#define SPI_NXP_S32_SET_SLAVE(n) .SlaveMode = DT_PROP(SPI_NXP_S32_NODE(n), slave), +#define SPI_NXP_S32_SET_SLAVE(n) .SlaveMode = DT_INST_PROP(n, slave), #else #define SPI_NXP_S32_SET_SLAVE(n) #endif @@ -617,15 +632,12 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { .irq_config_func = spi_nxp_s32_config_func_##n, #define SPI_NXP_S32_INTERRUPT_DEFINE(n) \ - extern void Spi_Ip_SPI_##n##_IRQHandler(void); \ static void spi_nxp_s32_config_func_##n(const struct device *dev) \ { \ - IRQ_CONNECT(DT_IRQN(SPI_NXP_S32_NODE(n)), \ - DT_IRQ(SPI_NXP_S32_NODE(n), priority), \ - Spi_Ip_SPI_##n##_IRQHandler, \ - DEVICE_DT_GET(SPI_NXP_S32_NODE(n)), \ - DT_IRQ(SPI_NXP_S32_NODE(n), flags)); \ - irq_enable(DT_IRQN(SPI_NXP_S32_NODE(n))); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + spi_nxp_s32_isr, DEVICE_DT_INST_GET(n), \ + DT_INST_IRQ(n, flags)); \ + irq_enable(DT_INST_IRQN(n)); \ } #define SPI_NXP_S32_CONFIG_CALLBACK_FUNC(n) \ @@ -635,7 +647,7 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { static void spi_nxp_s32_##n##_callback(uint8 instance, Spi_Ip_EventType event) \ { \ ARG_UNUSED(instance); \ - const struct device *dev = DEVICE_DT_GET(SPI_NXP_S32_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ \ spi_nxp_s32_transfer_callback(dev, event); \ } @@ -652,39 +664,37 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { */ #define SPI_NXP_S32_INSTANCE_CONFIG(n) \ static const Spi_Ip_ConfigType spi_nxp_s32_default_config_##n = { \ - .Instance = n, \ + .Instance = SPI_NXP_S32_HW_INSTANCE(n), \ .Mcr = (SPI_MCR_MSTR(SPI_NXP_S32_IS_MASTER(n)) | \ SPI_MCR_CONT_SCKE(0U) | SPI_MCR_FRZ(0U) | \ SPI_MCR_MTFE(0U) | SPI_MCR_SMPL_PT(0U) | \ SPI_MCR_PCSIS(BIT_MASK(SPI_NXP_S32_NUM_CS(n))) | \ SPI_MCR_MDIS(0U) | SPI_MCR_XSPI(1U) | SPI_MCR_HALT(1U)), \ .TransferMode = SPI_IP_POLLING, \ - .StateIndex = n, \ + .StateIndex = SPI_NXP_S32_HW_INSTANCE(n), \ SPI_NXP_S32_SET_SLAVE(n) \ } #define SPI_NXP_S32_TRANSFER_CONFIG(n) \ .transfer_cfg = { \ - .Instance = n, \ + .Instance = SPI_NXP_S32_HW_INSTANCE(n), \ .Ctare = SPI_CTARE_FMSZE(0U) | SPI_CTARE_DTCP(1U), \ } #define SPI_NXP_S32_DEVICE(n) \ - PINCTRL_DT_DEFINE(SPI_NXP_S32_NODE(n)); \ + PINCTRL_DT_INST_DEFINE(n); \ SPI_NXP_S32_CALLBACK_DEFINE(n) \ SPI_NXP_S32_INTERRUPT_DEFINE(n) \ SPI_NXP_S32_INSTANCE_CONFIG(n); \ static const struct spi_nxp_s32_config spi_nxp_s32_config_##n = { \ - .instance = n, \ .num_cs = SPI_NXP_S32_NUM_CS(n), \ - .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SPI_NXP_S32_NODE(n))), \ - .clock_subsys = (clock_control_subsys_t) \ - DT_CLOCKS_CELL(SPI_NXP_S32_NODE(n), name), \ - .sck_cs_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_sck_cs_delay, 0U), \ - .cs_sck_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_cs_sck_delay, 0U), \ - .cs_cs_delay = DT_PROP_OR(SPI_NXP_S32_NODE(n), spi_cs_cs_delay, 0U), \ - .spi_hw_cfg = (Spi_Ip_ConfigType *)&spi_nxp_s32_default_config_##n, \ - .pincfg = PINCTRL_DT_DEV_CONFIG_GET(SPI_NXP_S32_NODE(n)), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ + .sck_cs_delay = DT_INST_PROP_OR(n, spi_sck_cs_delay, 0U), \ + .cs_sck_delay = DT_INST_PROP_OR(n, spi_cs_sck_delay, 0U), \ + .cs_cs_delay = DT_INST_PROP_OR(n, spi_cs_cs_delay, 0U), \ + .spi_hw_cfg = (Spi_Ip_ConfigType *)&spi_nxp_s32_default_config_##n, \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ SPI_NXP_S32_CONFIG_CALLBACK_FUNC(n) \ SPI_NXP_S32_CONFIG_INTERRUPT_FUNC(n) \ }; \ @@ -692,50 +702,12 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { SPI_NXP_S32_TRANSFER_CONFIG(n), \ SPI_CONTEXT_INIT_LOCK(spi_nxp_s32_data_##n, ctx), \ SPI_CONTEXT_INIT_SYNC(spi_nxp_s32_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPI_NXP_S32_NODE(n), ctx) \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ - DEVICE_DT_DEFINE(SPI_NXP_S32_NODE(n), \ + DEVICE_DT_INST_DEFINE(n, \ &spi_nxp_s32_init, NULL, \ &spi_nxp_s32_data_##n, &spi_nxp_s32_config_##n, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_nxp_s32_driver_api); -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(0), okay) -SPI_NXP_S32_DEVICE(0); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(1), okay) -SPI_NXP_S32_DEVICE(1); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(2), okay) -SPI_NXP_S32_DEVICE(2); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(3), okay) -SPI_NXP_S32_DEVICE(3); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(4), okay) -SPI_NXP_S32_DEVICE(4); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(5), okay) -SPI_NXP_S32_DEVICE(5); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(6), okay) -SPI_NXP_S32_DEVICE(6); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(7), okay) -SPI_NXP_S32_DEVICE(7); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(8), okay) -SPI_NXP_S32_DEVICE(8); -#endif - -#if DT_NODE_HAS_STATUS(SPI_NXP_S32_NODE(9), okay) -SPI_NXP_S32_DEVICE(9); -#endif +DT_INST_FOREACH_STATUS_OKAY(SPI_NXP_S32_DEVICE) diff --git a/drivers/spi/spi_nxp_s32.h b/drivers/spi/spi_nxp_s32.h index 3d01d1625bf..68f0943b130 100644 --- a/drivers/spi/spi_nxp_s32.h +++ b/drivers/spi/spi_nxp_s32.h @@ -47,7 +47,6 @@ struct spi_nxp_s32_data { }; struct spi_nxp_s32_config { - uint8_t instance; uint8_t num_cs; const struct device *clock_dev; clock_control_subsys_t clock_subsys; diff --git a/west.yml b/west.yml index 0ec8c4e2ea7..1998ae73432 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 361ccc5962dfc691f6134d73605fed063c4d26cd + revision: 3731aefd0cd55f8507498c336b3256268ecd9d61 path: modules/hal/nxp groups: - hal From 237ec65ad365dd027552da3823da2fcc414b5138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sat, 4 Nov 2023 08:54:51 +0700 Subject: [PATCH 3157/4498] intc: nxp_s32: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics. Note that for some peripheral instances is needed to define the HAL macros of the peripheral base address because there are gaps in the instances or there are SoCs with a single instance. Signed-off-by: Manuel Argüelles --- .../interrupt_controller/intc_eirq_nxp_s32.c | 70 +++++++------------ soc/arm/nxp_s32/s32k/soc.h | 5 ++ soc/arm/nxp_s32/s32ze/soc.h | 7 +- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/drivers/interrupt_controller/intc_eirq_nxp_s32.c b/drivers/interrupt_controller/intc_eirq_nxp_s32.c index 51631e0546c..2dae70824ce 100644 --- a/drivers/interrupt_controller/intc_eirq_nxp_s32.c +++ b/drivers/interrupt_controller/intc_eirq_nxp_s32.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_siul2_eirq + #include #include #include @@ -124,23 +126,17 @@ static int eirq_nxp_s32_init(const struct device *dev) return 0; } -#define EIRQ_NXP_S32_NODE(n) DT_NODELABEL(eirq##n) - #define EIRQ_NXP_S32_CALLBACK(line, n) \ void nxp_s32_icu_##n##_eirq_line_##line##_callback(void) \ { \ - const struct device *dev = DEVICE_DT_GET(EIRQ_NXP_S32_NODE(n)); \ - \ - eirq_nxp_s32_callback(dev, line); \ + eirq_nxp_s32_callback(DEVICE_DT_INST_GET(n), line); \ } #define EIRQ_NXP_S32_CHANNEL_CONFIG(idx, n) \ { \ .hwChannel = idx, \ - .digFilterEn = DT_PROP_OR(DT_CHILD(EIRQ_NXP_S32_NODE(n), line_##idx), \ - filter_enable, 0), \ - .maxFilterCnt = DT_PROP_OR(DT_CHILD(EIRQ_NXP_S32_NODE(n), line_##idx), \ - filter_counter, 0), \ + .digFilterEn = DT_INST_PROP_OR(DT_CHILD(n, line_##idx), filter_enable, 0), \ + .maxFilterCnt = DT_INST_PROP_OR(DT_CHILD(n, line_##idx), filter_counter, 0), \ .intSel = SIUL2_ICU_IRQ, \ .intEdgeSel = SIUL2_ICU_DISABLE, \ .callback = NULL, \ @@ -155,8 +151,7 @@ static int eirq_nxp_s32_init(const struct device *dev) #define EIRQ_NXP_S32_INSTANCE_CONFIG(n) \ static const Siul2_Icu_Ip_InstanceConfigType eirq_##n##_instance_nxp_s32_cfg = { \ - .intFilterClk = DT_PROP_OR(EIRQ_NXP_S32_NODE(n), \ - filter_prescaler, (0)), \ + .intFilterClk = DT_INST_PROP_OR(n, filter_prescaler, 0), \ .altIntFilterClk = 0U, \ } @@ -176,42 +171,45 @@ static int eirq_nxp_s32_init(const struct device *dev) #define _EIRQ_NXP_S32_IRQ_NAME(name) DT_CAT3(SIUL2_EXT_IRQ_, name, _ISR) #define EIRQ_NXP_S32_IRQ_NAME(idx, n) \ - COND_CODE_1(DT_NODE_HAS_PROP(EIRQ_NXP_S32_NODE(n), interrupt_names), \ - (_EIRQ_NXP_S32_IRQ_NAME( \ - DT_STRING_TOKEN_BY_IDX(EIRQ_NXP_S32_NODE(n), interrupt_names, idx))), \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, interrupt_names), \ + (_EIRQ_NXP_S32_IRQ_NAME(DT_INST_STRING_TOKEN_BY_IDX(n, interrupt_names, idx))), \ (DT_CAT3(SIUL2_, n, _ICU_EIRQ_SINGLE_INT_HANDLER))) #define _EIRQ_NXP_S32_IRQ_CONFIG(idx, n) \ do { \ - IRQ_CONNECT(DT_IRQ_BY_IDX(EIRQ_NXP_S32_NODE(n), idx, irq), \ - DT_IRQ_BY_IDX(EIRQ_NXP_S32_NODE(n), idx, priority), \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + DT_INST_IRQ_BY_IDX(n, idx, priority), \ EIRQ_NXP_S32_IRQ_NAME(idx, n), \ - DEVICE_DT_GET(EIRQ_NXP_S32_NODE(n)), \ - COND_CODE_1(CONFIG_GIC, \ - (DT_IRQ_BY_IDX(EIRQ_NXP_S32_NODE(n), idx, flags)), \ - (0))); \ - irq_enable(DT_IRQ_BY_IDX(EIRQ_NXP_S32_NODE(n), idx, irq)); \ + DEVICE_DT_INST_GET(n), \ + COND_CODE_1(CONFIG_GIC, (DT_INST_IRQ_BY_IDX(n, idx, flags)), (0))); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ } while (false); #define EIRQ_NXP_S32_IRQ_CONFIG(n) \ - LISTIFY(DT_NUM_IRQS(EIRQ_NXP_S32_NODE(n)), _EIRQ_NXP_S32_IRQ_CONFIG, (), n) + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), _EIRQ_NXP_S32_IRQ_CONFIG, (), n) + +#define EIRQ_NXP_S32_HW_INSTANCE_CHECK(i, n) \ + (((DT_REG_ADDR(DT_INST_PARENT(n))) == IP_SIUL2_##i##_BASE) ? i : 0) + +#define EIRQ_NXP_S32_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET SIUL2_INSTANCE_COUNT, EIRQ_NXP_S32_HW_INSTANCE_CHECK, (|), n) #define EIRQ_NXP_S32_INIT_DEVICE(n) \ EIRQ_NXP_S32_CONFIG(n) \ - PINCTRL_DT_DEFINE(EIRQ_NXP_S32_NODE(n)); \ + PINCTRL_DT_INST_DEFINE(n); \ static const struct eirq_nxp_s32_config eirq_nxp_s32_conf_##n = { \ - .instance = n, \ - .disr0 = (mem_addr_t)DT_REG_ADDR_BY_NAME(EIRQ_NXP_S32_NODE(n), disr0), \ - .direr0 = (mem_addr_t)DT_REG_ADDR_BY_NAME(EIRQ_NXP_S32_NODE(n), direr0), \ + .instance = EIRQ_NXP_S32_HW_INSTANCE(n), \ + .disr0 = (mem_addr_t)DT_INST_REG_ADDR_BY_NAME(n, disr0), \ + .direr0 = (mem_addr_t)DT_INST_REG_ADDR_BY_NAME(n, direr0), \ .icu_cfg = (Siul2_Icu_Ip_ConfigType *)&eirq_##n##_nxp_s32_cfg, \ - .pincfg = PINCTRL_DT_DEV_CONFIG_GET(EIRQ_NXP_S32_NODE(n)) \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n) \ }; \ static struct eirq_nxp_s32_cb eirq_nxp_s32_cb_##n[NXP_S32_NUM_CHANNELS]; \ static struct eirq_nxp_s32_data eirq_nxp_s32_data_##n = { \ .cb = eirq_nxp_s32_cb_##n, \ }; \ static int eirq_nxp_s32_init##n(const struct device *dev); \ - DEVICE_DT_DEFINE(EIRQ_NXP_S32_NODE(n), \ + DEVICE_DT_INST_DEFINE(n, \ eirq_nxp_s32_init##n, \ NULL, \ &eirq_nxp_s32_data_##n, \ @@ -233,18 +231,4 @@ static int eirq_nxp_s32_init(const struct device *dev) return 0; \ } -#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(0), okay) -EIRQ_NXP_S32_INIT_DEVICE(0) -#endif - -#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(1), okay) -EIRQ_NXP_S32_INIT_DEVICE(1) -#endif - -#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(4), okay) -EIRQ_NXP_S32_INIT_DEVICE(4) -#endif - -#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(5), okay) -EIRQ_NXP_S32_INIT_DEVICE(5) -#endif +DT_INST_FOREACH_STATUS_OKAY(EIRQ_NXP_S32_INIT_DEVICE) diff --git a/soc/arm/nxp_s32/s32k/soc.h b/soc/arm/nxp_s32/s32k/soc.h index fa29a960172..bbc53e18023 100644 --- a/soc/arm/nxp_s32/s32k/soc.h +++ b/soc/arm/nxp_s32/s32k/soc.h @@ -18,4 +18,9 @@ #undef FALSE #endif +/* Aliases for peripheral base addresses */ + +/* SIUL2 */ +#define IP_SIUL2_0_BASE IP_SIUL2_BASE + #endif /* _NXP_S32_S32K_SOC_H_ */ diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index 1bacb430a00..cc13dfcc6aa 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,4 +10,9 @@ /* Do not let CMSIS to handle GIC */ #define __GIC_PRESENT 0 +/* Aliases for peripheral base addresses */ + +/* SIUL2 */ +#define IP_SIUL2_2_BASE 0U /* instance does not exist on this SoC */ + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From 95a5f5178fed90dc193c5c934f4a61559f203cf8 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Mon, 6 Nov 2023 09:21:39 +0100 Subject: [PATCH 3158/4498] doc: memory: Fix SYS_MEM_BLOCKS_DEFINE_STATIC description Fix SYS_MEM_BLOCKS_DEFINE_STATIC() description. Use a "memory blocks allocator" instead of "slab", which is most probably was copy-pasted from the previous "slab" chapter by mistake. Signed-off-by: Andrej Butok --- doc/kernel/memory_management/sys_mem_blocks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/kernel/memory_management/sys_mem_blocks.rst b/doc/kernel/memory_management/sys_mem_blocks.rst index abc1edd1a80..da84f7c151c 100644 --- a/doc/kernel/memory_management/sys_mem_blocks.rst +++ b/doc/kernel/memory_management/sys_mem_blocks.rst @@ -112,7 +112,7 @@ to a 4-byte boundary: SYS_MEM_BLOCKS_DEFINE(allocator, 64, 4, 4); -Similarly, you can define a memory slab in private scope: +Similarly, you can define a memory blocks allocator in private scope: .. code-block:: c From 14dccd772d71612f0a8b34e7e3bbb918f4455821 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Mon, 6 Nov 2023 12:57:49 +0100 Subject: [PATCH 3159/4498] manifest: update cmsis to 5.9.0 This includes updates in: * Core-M (with added support for Cortex-M85) * Core-A Signed-off-by: Marcin Niestroj --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 1998ae73432..a6457386358 100644 --- a/west.yml +++ b/west.yml @@ -116,7 +116,7 @@ manifest: groups: - babblesim - name: cmsis - revision: 5a00331455dd74e31e80efa383a489faea0590e3 + revision: 4b96cbb174678dcd3ca86e11e1f24bc5f8726da0 path: modules/hal/cmsis groups: - hal From f4e6e4b2e57ce73e4de3399b650db33565b4f1c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 5 Sep 2023 14:19:07 -0700 Subject: [PATCH 3160/4498] libc/picolibc: Don't force TLS when using picolibc module The picolibc module can be built without thread local storage support if desired. Allow that by using 'imply' instead of 'select'. However, when using the toolchain picolibc, we assume that TLS will be enabled wherever supported, so make sure we match by adding a 'select' for this case. Signed-off-by: Keith Packard --- lib/libc/Kconfig | 2 +- lib/libc/picolibc/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 7c5f92f7e97..c9678adf2c2 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -81,7 +81,7 @@ config MINIMAL_LIBC config PICOLIBC bool "Picolibc library" select COMMON_LIBC_ABORT - select THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + imply THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE select LIBC_ERRNO if THREAD_LOCAL_STORAGE select NEED_LIBC_MEM_PARTITION imply COMMON_LIBC_MALLOC diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig index b5e1f1bb581..21c6fc38501 100644 --- a/lib/libc/picolibc/Kconfig +++ b/lib/libc/picolibc/Kconfig @@ -13,6 +13,12 @@ config PICOLIBC_USE_MODULE This is enabled by default for toolchains other than the Zephyr SDK. +# force TLS when using toolchain with TLS support +config PICOLIBC_USE_TOOLCHAIN + bool + default y if PICOLIBC && !PICOLIBC_USE_MODULE + select THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + config PICOLIBC_HEAP_SIZE int "[DEPRECATED] Picolibc heap size (bytes)" default -2 From 6d38ecae1d83f220e7a8d089bb0ce7a20d44c8ac Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 5 Sep 2023 14:33:45 -0700 Subject: [PATCH 3161/4498] tests/c_lib: Test picolibc module configurations Make sure the picolibc module builds and runs in both TLS and non-TLS variants. Signed-off-by: Keith Packard --- tests/lib/c_lib/testcase.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/lib/c_lib/testcase.yaml b/tests/lib/c_lib/testcase.yaml index 90313614d10..eb42925958a 100644 --- a/tests/lib/c_lib/testcase.yaml +++ b/tests/lib/c_lib/testcase.yaml @@ -38,3 +38,18 @@ tests: extra_configs: - CONFIG_MINIMAL_LIBC=y - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=n + libraries.libc.picolibc.module: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + ignore_faults: true + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + libraries.libc.picolibc.notls: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + ignore_faults: true + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + - CONFIG_THREAD_LOCAL_STORAGE=n From 6722544f1e36ea749f28b7b616ff7ce9395782f9 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Sat, 4 Nov 2023 08:26:51 +0800 Subject: [PATCH 3162/4498] drivers: clock_control: Add Ambiq clock_control driver. This commit adds Ambiq clock_control driver support. Signed-off-by: Aaron Ye --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.ambiq | 14 ++ drivers/clock_control/clock_control_ambiq.c | 138 ++++++++++++++++++ dts/bindings/clock/ambiq,clkctrl.yaml | 23 +++ .../clock_control/clock_control_ambiq.h | 37 +++++ 6 files changed, 215 insertions(+) create mode 100644 drivers/clock_control/Kconfig.ambiq create mode 100644 drivers/clock_control/clock_control_ambiq.c create mode 100644 dts/bindings/clock/ambiq,clkctrl.yaml create mode 100644 include/zephyr/drivers/clock_control/clock_control_ambiq.h diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 8b246b55e38..0f7a1c4dd4a 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -27,6 +27,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RA clock_control_ra.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 3ff554e684a..a380b9a9c12 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -82,4 +82,6 @@ source "drivers/clock_control/Kconfig.agilex5" source "drivers/clock_control/Kconfig.ra" +source "drivers/clock_control/Kconfig.ambiq" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.ambiq b/drivers/clock_control/Kconfig.ambiq new file mode 100644 index 00000000000..ca0a4c1bce5 --- /dev/null +++ b/drivers/clock_control/Kconfig.ambiq @@ -0,0 +1,14 @@ +# Ambiq Clock Control Driver configuration options +# +# Copyright (c) 2023 Ambiq Micro Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +config CLOCK_CONTROL_AMBIQ + bool "AMBIQ clock control driver" + default y + depends on DT_HAS_AMBIQ_CLKCTRL_ENABLED + select AMBIQ_HAL + help + Enable driver for Ambiq clock control. diff --git a/drivers/clock_control/clock_control_ambiq.c b/drivers/clock_control/clock_control_ambiq.c new file mode 100644 index 00000000000..a64030c2a2d --- /dev/null +++ b/drivers/clock_control/clock_control_ambiq.c @@ -0,0 +1,138 @@ +/* + * Copyright 2023 Ambiq Micro Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ambiq_clkctrl + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(clock_control_ambiq, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +struct ambiq_clock_config { + uint32_t clock_freq; + const struct pinctrl_dev_config *pcfg; +}; + +static int ambiq_clock_on(const struct device *dev, clock_control_subsys_t sub_system) +{ + ARG_UNUSED(dev); + + int ret; + uint32_t clock_name = (uint32_t)sub_system; + am_hal_mcuctrl_control_arg_t arg = { + .b_arg_hfxtal_in_use = true, + .b_arg_apply_ext_source = false, + .b_arg_force_update = false, + }; + + if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) { + return -EINVAL; + } + + switch (clock_name) { + case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE: + arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN); + arg.b_arg_enable_HfXtalClockout = true; + ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_KICK_START, &arg); + break; + case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL: + ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE, 0); + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +static int ambiq_clock_off(const struct device *dev, clock_control_subsys_t sub_system) +{ + ARG_UNUSED(dev); + + int ret; + uint32_t clock_name = (uint32_t)sub_system; + am_hal_mcuctrl_control_arg_t arg = { + .b_arg_hfxtal_in_use = true, + .b_arg_apply_ext_source = false, + .b_arg_force_update = false, + }; + + if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) { + return -EINVAL; + } + + switch (clock_name) { + case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE: + arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN); + arg.b_arg_enable_HfXtalClockout = true; + ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_DISABLE, &arg); + break; + case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL: + ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE, 0); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +static inline int ambiq_clock_get_rate(const struct device *dev, clock_control_subsys_t sub_system, + uint32_t *rate) +{ + ARG_UNUSED(sub_system); + + const struct ambiq_clock_config *cfg = dev->config; + *rate = cfg->clock_freq; + + return 0; +} + +static inline int ambiq_clock_configure(const struct device *dev, clock_control_subsys_t sub_system, + void *data) +{ + ARG_UNUSED(sub_system); + ARG_UNUSED(data); + + const struct ambiq_clock_config *cfg = dev->config; + int ret; + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + + return ret; +} + +static int ambiq_clock_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* Nothing to do.*/ + return 0; +} + +static const struct clock_control_driver_api ambiq_clock_driver_api = { + .on = ambiq_clock_on, + .off = ambiq_clock_off, + .get_rate = ambiq_clock_get_rate, + .configure = ambiq_clock_configure, +}; + +#define AMBIQ_CLOCK_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct ambiq_clock_config ambiq_clock_config##n = { \ + .clock_freq = DT_INST_PROP(n, clock_frequency), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \ + DEVICE_DT_INST_DEFINE(n, ambiq_clock_init, NULL, NULL, &ambiq_clock_config##n, \ + POST_KERNEL, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \ + &ambiq_clock_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(AMBIQ_CLOCK_INIT) diff --git a/dts/bindings/clock/ambiq,clkctrl.yaml b/dts/bindings/clock/ambiq,clkctrl.yaml new file mode 100644 index 00000000000..e1b3f9534b3 --- /dev/null +++ b/dts/bindings/clock/ambiq,clkctrl.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq Apollo Series SoC Clock Controller + +compatible: "ambiq,clkctrl" + +include: [clock-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + clock-frequency: + type: int + description: output clock frequency (Hz) + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + "#clock-cells": + const: 1 diff --git a/include/zephyr/drivers/clock_control/clock_control_ambiq.h b/include/zephyr/drivers/clock_control/clock_control_ambiq.h new file mode 100644 index 00000000000..02ca16b54db --- /dev/null +++ b/include/zephyr/drivers/clock_control/clock_control_ambiq.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Ambiq Micro Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Clocks handled by the CLOCK peripheral. + * + * Enum shall be used as a sys argument in clock_control API. + */ +enum clock_control_ambiq_type { + CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE, + CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_USB, + CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_ADC, + CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_AUADC, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_DBGCTRL, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_CLKGEN_MISC, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_CLKGEN_CLKOUT, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_PDM, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_IIS, + CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_IOM, + CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL, + CLOCK_CONTROL_AMBIQ_TYPE_MAX +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_ */ From 0e827e3598d5c2301a9f2d764b60cdffa6030abc Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Fri, 3 Nov 2023 22:47:06 +0800 Subject: [PATCH 3163/4498] dts: arm: ambiq: Add clock control instances to Apollo4 Blue Plus SoC. This commit instantiates the clock control for Apollo4 Blue Plus. Signed-off-by: Aaron Ye --- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 86bd5937eb2..65166caa335 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -2,6 +2,7 @@ #include #include +#include #include / { @@ -11,6 +12,16 @@ clock-frequency = <24000000>; #clock-cells = <0>; }; + xo32m: xo32m { + compatible = "ambiq,clkctrl"; + clock-frequency = ; + #clock-cells = <1>; + }; + xo32k: xo32k { + compatible = "ambiq,clkctrl"; + clock-frequency = ; + #clock-cells = <1>; + }; }; cpus { From 0d47cf90578d14d4e4a30e5e5d57bce89d98a5d4 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Fri, 3 Nov 2023 22:47:06 +0800 Subject: [PATCH 3164/4498] boards: arm: apollo4p_blue_kxr_evb: Enable clock control. This commit enables clock control instances for apollo4p_blue_kxr_evb. Also adds pin configuration for each instance. Signed-off-by: Aaron Ye --- .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 13 +++++++++++++ .../apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi index 4d8f6cb0525..0622157b2d0 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -192,4 +192,17 @@ ambiq,iom-nce-module = <36>; }; }; + + xo32m_default: xo32m_default { + group1 { + pinmux = ; + drive-strength = "0.1"; + }; + }; + xo32k_default: xo32k_default { + group1 { + pinmux = ; + drive-strength = "0.1"; + }; + }; }; diff --git a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index add81097c40..68e0195056c 100644 --- a/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/arm/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -74,3 +74,15 @@ }; }; }; + +&xo32m { + pinctrl-0 = <&xo32m_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&xo32k { + pinctrl-0 = <&xo32k_default>; + pinctrl-names = "default"; + status = "okay"; +}; From 12eac1ea9a0805a9b0fc9383ac29189da5e1a7d8 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Fri, 3 Nov 2023 22:47:07 +0800 Subject: [PATCH 3165/4498] manifest: Update hal_ambiq revision. This commit adds am_hal_mcuctrl.c for wide usage. Signed-off-by: Aaron Ye --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a6457386358..14907f79ef9 100644 --- a/west.yml +++ b/west.yml @@ -142,7 +142,7 @@ manifest: groups: - hal - name: hal_ambiq - revision: 0a7c99325aa73a1ef777501da91c2c6608661e56 + revision: 0c5ea5749245c8ff6ce7aefbf0aa9981943c2857 path: modules/hal/ambiq groups: - hal From 457d437841eb6bccf2617d02a5c531635f7e1fdd Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 26 Sep 2023 11:16:52 +0200 Subject: [PATCH 3166/4498] timer: cortex-m systick: add idle timer Some chips, that use Cortex-M SysTick as the system timer, disable a clock in a low power mode, that is the input for the SysTick e.g. STM32Fx family. It blocks enabling power management for these chips. The wake-up function doesn't work and the time measurement is lost. Add an additional IDLE timer that handles these functionality when the system is about to enter IDLE. It has to wake up the chip and update the cycle counter by time not measured by the SysTick. The IDLE timer has to support counter API (setting alarm and reading current value). Signed-off-by: Dawid Niedzwiecki --- drivers/timer/Kconfig.cortex_m_systick | 19 +++++ drivers/timer/cortex_m_systick.c | 101 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/drivers/timer/Kconfig.cortex_m_systick b/drivers/timer/Kconfig.cortex_m_systick index 31e4f56fce5..baf1f6c817e 100644 --- a/drivers/timer/Kconfig.cortex_m_systick +++ b/drivers/timer/Kconfig.cortex_m_systick @@ -3,6 +3,8 @@ # Copyright (c) 2019 Intel Corp. # SPDX-License-Identifier: Apache-2.0 +DT_CHOSEN_IDLE_TIMER := zephyr,cortex-m-idle-timer + config CORTEX_M_SYSTICK bool "Cortex-M SYSTICK timer" depends on CPU_CORTEX_M_HAS_SYSTICK @@ -40,3 +42,20 @@ config CORTEX_M_SYSTICK_64BIT_CYCLE_COUNTER This is set to y by default when the hardware clock is fast enough to wrap sys_clock_cycle_get_32() in about a minute or less. + +config CORTEX_M_SYSTICK_IDLE_TIMER + bool "Use an additional timer while entering IDLE" + default $(dt_chosen_enabled,$(DT_CHOSEN_IDLE_TIMER)) + depends on COUNTER + depends on TICKLESS_KERNEL + help + There are chips e.g. STMFX family that use SysTick as a system timer, + but SysTick is not clocked in low power mode. These chips usually have + another timer that is not stopped, but it has lower frequency e.g. + RTC, thus it can't be used as a main system timer. + + Use the IDLE timer for timeout (wakeup) when the system is entering + IDLE state. + + The chosen IDLE timer node has to support setting alarm from the + counter API. diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index e026c3603c6..13e499efec4 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -10,6 +10,7 @@ #include #include #include +#include #define COUNTER_MAX 0x00ffffff #define TIMER_STOPPED 0xff000000 @@ -77,6 +78,26 @@ static cycle_t announced_cycles; */ static volatile uint32_t overflow_cyc; +#ifdef CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER +/* This local variable indicates that the timeout was set right before + * entering idle state. + * + * It is used for chips that has to use a separate idle timer in such + * case because the Cortex-m SysTick is not clocked in the low power + * mode state. + */ +static bool timeout_idle; + +/* Cycle counter before entering the idle state. */ +static cycle_t cycle_pre_idle; + +/* Idle timer value before entering the idle state. */ +static uint32_t idle_timer_pre_idle; + +/* Idle timer used for timer while entering the idle state */ +static const struct device *idle_timer = DEVICE_DT_GET(DT_CHOSEN(zephyr_cortex_m_idle_timer)); +#endif /* CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER */ + /* This internal function calculates the amount of HW cycles that have * elapsed since the last time the absolute HW cycles counter has been * updated. 'cycle_count' may be updated either by the ISR, or when we @@ -159,6 +180,19 @@ void sys_clock_isr(void *arg) cycle_count += overflow_cyc; overflow_cyc = 0; +#ifdef CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER + /* Rare case, when the interrupt was triggered, with previously programmed + * LOAD value, just before entering the idle mode (SysTick is clocked) or right + * after exiting the idle mode, before executing the procedure in the + * sys_clock_idle_exit function. + */ + if (timeout_idle) { + z_arm_int_exit(); + + return; + } +#endif /* CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER */ + if (TICKLESS) { /* In TICKLESS mode, the SysTick.LOAD is re-programmed * in sys_clock_set_timeout(), followed by resetting of @@ -196,6 +230,36 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) return; } +#ifdef CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER + if (idle) { + uint64_t timeout_us = + ((uint64_t)ticks * USEC_PER_SEC) / CONFIG_SYS_CLOCK_TICKS_PER_SEC; + struct counter_alarm_cfg cfg = { + .callback = NULL, + .ticks = counter_us_to_ticks(idle_timer, timeout_us), + .user_data = NULL, + .flags = 0, + }; + + timeout_idle = true; + + /* Set the alarm using timer that runs the idle. + * Needed rump-up/setting time, lower accurency etc. should be + * included in the exit-latency in the power state definition. + */ + counter_cancel_channel_alarm(idle_timer, 0); + counter_set_channel_alarm(idle_timer, 0, &cfg); + + /* Store current values to calculate a difference in + * measurements after exiting the idle state. + */ + counter_get_value(idle_timer, &idle_timer_pre_idle); + cycle_pre_idle = cycle_count + elapsed(); + + return; + } +#endif /* CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER */ + #if defined(CONFIG_TICKLESS_KERNEL) uint32_t delay; uint32_t val1, val2; @@ -300,6 +364,43 @@ uint64_t sys_clock_cycle_get_64(void) void sys_clock_idle_exit(void) { +#ifdef CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER + if (timeout_idle) { + cycle_t systick_diff, missed_cycles; + uint32_t idle_timer_diff, idle_timer_post, dcycles, dticks; + uint64_t systick_us, idle_timer_us, measurement_diff_us; + + /* Get current values for both timers */ + counter_get_value(idle_timer, &idle_timer_post); + systick_diff = cycle_count + elapsed() - cycle_pre_idle; + + /* Calculate has much time has pasted since last measurement for both timers */ + idle_timer_diff = idle_timer_post - idle_timer_pre_idle; + idle_timer_us = counter_ticks_to_us(idle_timer, idle_timer_diff); + systick_us = + ((uint64_t)systick_diff * USEC_PER_SEC) / sys_clock_hw_cycles_per_sec(); + + /* Calculate difference in measurements to get how much time + * the SysTick missed in idle state. + */ + measurement_diff_us = idle_timer_us - systick_us; + missed_cycles = + (sys_clock_hw_cycles_per_sec() * measurement_diff_us) / USEC_PER_SEC; + + /* Update the cycle counter to include the cycles missed in idle */ + cycle_count += missed_cycles; + + /* Announce the passed ticks to the kernel */ + dcycles = cycle_count + elapsed() - announced_cycles; + dticks = dcycles / CYC_PER_TICK; + announced_cycles += dticks * CYC_PER_TICK; + sys_clock_announce(dticks); + + /* We've alredy performed all needed operations */ + timeout_idle = false; + } +#endif /* CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER */ + if (last_load == TIMER_STOPPED) { SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } From 0229d1010bffadf7cda4912f8a46d27886ad5c9b Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Thu, 5 Oct 2023 15:49:57 +0200 Subject: [PATCH 3167/4498] boards: arm: lpcxpresso55s36: add boot and slot1 flash partitions. Add boot_partition and slot1_partition to lpcxpresso55s36 dts. Signed-off-by: Andrej Butok --- .../arm/lpcxpresso55s36/lpcxpresso55s36.dts | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts index 3b51a1602f2..be2b16c27f7 100644 --- a/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts +++ b/boards/arm/lpcxpresso55s36/lpcxpresso55s36.dts @@ -17,7 +17,7 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &sramx; + zephyr,code-partition = &slot0_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,canbus = &can0; @@ -143,20 +143,33 @@ pinctrl-names = "default"; }; +/* Flash is divided into 32 kB sub-regions. + * Each sub-region can be assigned individual + * security tier in secure AHB controller. + */ &flash0 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - slot0_partition: partition@0 { - label = "executable"; - reg = <0x00000000 DT_SIZE_K(182)>; - }; - - storage_partition: partition@88000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(32)>; + }; + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 DT_SIZE_K(96)>; + }; + slot1_partition: partition@20000 { + label = "image-1"; + reg = <0x00020000 DT_SIZE_K(96)>; + }; + storage_partition: partition@38000 { label = "storage"; - reg = <0x0002d800 DT_SIZE_K(64)>; + reg = <0x00038000 DT_SIZE_K(20)>; }; + /* The last 12KB are reserved for PFR on the 256KB flash. + */ }; }; From 0a104185fef22caf1019a78b2d2b2f74301771ad Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Fri, 20 Oct 2023 10:10:28 +0300 Subject: [PATCH 3168/4498] tests: lwm2m: Add Qemu X86 and fix Qemu Cortex-M3 * Add support for running interoperability tests with Qemu X86. * Remove some debugging messages to allow binary to fix Qemu Cortex-M3 board. * Tune buffer and stack sizes to fit all boards. Signed-off-by: Seppo Takalo --- samples/net/lwm2m_client/boards/qemu_x86.conf | 4 ++ .../lwm2m/interop/boards/native_posix.conf | 1 + .../lwm2m/interop/boards/qemu_cortex_m3.conf | 20 +++--- .../lib/lwm2m/interop/boards/qemu_x86.conf | 4 ++ tests/net/lib/lwm2m/interop/prj.conf | 69 +++++++++++-------- .../net/lib/lwm2m/interop/src/lwm2m-client.c | 39 ++++++++++- tests/net/lib/lwm2m/interop/testcase.yaml | 1 + 7 files changed, 96 insertions(+), 42 deletions(-) create mode 100644 tests/net/lib/lwm2m/interop/boards/qemu_x86.conf diff --git a/samples/net/lwm2m_client/boards/qemu_x86.conf b/samples/net/lwm2m_client/boards/qemu_x86.conf index c099c8e81df..5a1dc0925c3 100644 --- a/samples/net/lwm2m_client/boards/qemu_x86.conf +++ b/samples/net/lwm2m_client/boards/qemu_x86.conf @@ -1 +1,5 @@ CONFIG_FPU=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_QEMU_ETHERNET=y + +CONFIG_PCIE=y diff --git a/tests/net/lib/lwm2m/interop/boards/native_posix.conf b/tests/net/lib/lwm2m/interop/boards/native_posix.conf index 44346db12ed..422e2c1bde4 100644 --- a/tests/net/lib/lwm2m/interop/boards/native_posix.conf +++ b/tests/net/lib/lwm2m/interop/boards/native_posix.conf @@ -5,3 +5,4 @@ CONFIG_LWM2M_DNS_SUPPORT=y CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y +CONFIG_ASAN=y diff --git a/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf b/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf index 7a3fd344e50..44263f885a4 100644 --- a/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf +++ b/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf @@ -5,16 +5,14 @@ CONFIG_NET_QEMU_ETHERNET=y # RAM/ROM tuning CONFIG_IDLE_STACK_SIZE=128 -CONFIG_MBEDTLS_HEAP_SIZE=7000 CONFIG_ISR_STACK_SIZE=512 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1024 -CONFIG_LWM2M_ENGINE_STACK_SIZE=2000 CONFIG_LWM2M_LOG_LEVEL_INF=y -CONFIG_LWM2M_ENGINE_MAX_MESSAGES=3 -CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE=0 -CONFIG_LWM2M_ENGINE_MAX_OBSERVER=5 -CONFIG_LWM2M_SECURITY_DTLS_TLS_CIPHERSUITE_MAX=3 -CONFIG_LWM2M_DEVICE_PWRSRC_MAX=2 -CONFIG_LWM2M_DEVICE_ERROR_CODE_MAX=5 -CONFIG_LWM2M_DEVICE_EXT_DEV_INFO_MAX=2 -CONFIG_LWM2M_NUM_ATTR=10 +CONFIG_LOG_BUFFER_SIZE=512 + +# qemu_cortex_m3 have smaller memory so simulate a small +# device and small network where max CoAP packet is 256+headers. +# This excercises the outgoing block-wise module intentionally. +CONFIG_LWM2M_COAP_MAX_MSG_SIZE=256 +CONFIG_LWM2M_COAP_BLOCK_SIZE=256 +CONFIG_LWM2M_COAP_BLOCK_TRANSFER=y +CONFIG_LWM2M_COAP_ENCODE_BUFFER_SIZE=2048 diff --git a/tests/net/lib/lwm2m/interop/boards/qemu_x86.conf b/tests/net/lib/lwm2m/interop/boards/qemu_x86.conf new file mode 100644 index 00000000000..18e513dffd1 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/boards/qemu_x86.conf @@ -0,0 +1,4 @@ +CONFIG_FPU=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_QEMU_ETHERNET=y +CONFIG_PCIE=y diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 66d6334264f..b393621b581 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -1,36 +1,22 @@ CONFIG_NETWORKING=y CONFIG_LOG=y -CONFIG_LWM2M_LOG_LEVEL_DBG=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NET_IPV6=y -CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 -CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=2 CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=n CONFIG_NET_DHCPV4=n -CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 -CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT=2 -CONFIG_PRINTK=y -CONFIG_NET_PKT_RX_COUNT=10 -CONFIG_NET_PKT_TX_COUNT=10 -CONFIG_NET_BUF_RX_COUNT=10 -CONFIG_NET_BUF_TX_COUNT=10 -CONFIG_NET_MAX_CONTEXTS=5 -CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" -CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" +CONFIG_NET_PKT_RX_COUNT=4 +CONFIG_NET_PKT_TX_COUNT=4 +CONFIG_NET_BUF_RX_COUNT=8 +CONFIG_NET_BUF_TX_COUNT=8 +CONFIG_NET_MAX_CONTEXTS=4 CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" - -CONFIG_NET_LOG=y - -CONFIG_NET_CONFIG_NEED_IPV6=y CONFIG_NET_CONFIG_NEED_IPV4=y CONFIG_NET_CONFIG_SETTINGS=y CONFIG_LWM2M=y -CONFIG_LWM2M_COAP_BLOCK_SIZE=512 CONFIG_LWM2M_IPSO_SUPPORT=y CONFIG_LWM2M_SHELL=y -CONFIG_LWM2M_ACCESS_CONTROL_ENABLE=n #Enable Portfolio object CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y @@ -47,7 +33,7 @@ CONFIG_LWM2M_RW_SENML_JSON_SUPPORT=y #Enable SenML CBOR content format CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT=y -CONFIG_LWM2M_RW_SENML_CBOR_RECORDS=60 +CONFIG_LWM2M_RW_SENML_CBOR_RECORDS=40 CONFIG_ZCBOR_CANONICAL=y #Enable legacy content formats @@ -62,7 +48,6 @@ CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 CONFIG_LWM2M_UPDATE_PERIOD=30 -CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10 # LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 @@ -74,19 +59,45 @@ CONFIG_MBEDTLS_TLS_VERSION_1_2=y # Special MbedTLS changes CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=8192 -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1500 +# MTU - IPv6 header - UDP header - DTLS header +# 1280 - 40 - 8 - 21 +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1211 +CONFIG_MBEDTLS_HEAP_SIZE=7168 CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y - # Disable RSA, we don't parse certs: saves flash/memory CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n # Enable PSK instead CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y +CONFIG_LWM2M_SECURITY_DTLS_TLS_CIPHERSUITE_MAX=3 CONFIG_NET_SOCKETS_SOCKOPT_TLS=y -CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 +# For testing purposes, limit DTLS contexts to one, +# LwM2M engine should not use more than one on any given time. +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=1 CONFIG_NET_SOCKETS_ENABLE_DTLS=y -# MbedTLS needs a larger stack -CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 +# Assume that IPv6 minimum MTU is accepted +# MTU - IPv6 header - UDP header - DTLS header - CoAP header room +# 1280 - 40 - 8 - 21 - 48 +CONFIG_LWM2M_COAP_MAX_MSG_SIZE=1163 +CONFIG_LWM2M_COAP_BLOCK_SIZE=1024 +CONFIG_LWM2M_COAP_BLOCK_TRANSFER=y +CONFIG_LWM2M_COAP_ENCODE_BUFFER_SIZE=4096 +CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT=1 +CONFIG_LWM2M_NUM_BLOCK1_CONTEXT=1 +CONFIG_SYS_HASH_FUNC32=y +CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE=0 +CONFIG_LWM2M_ENGINE_MAX_PENDING=2 +CONFIG_LWM2M_ENGINE_MAX_REPLIES=2 +CONFIG_LWM2M_ENGINE_MAX_MESSAGES=3 +CONFIG_LWM2M_ENGINE_MAX_OBSERVER=5 +CONFIG_LWM2M_DEVICE_PWRSRC_MAX=2 +CONFIG_LWM2M_DEVICE_ERROR_CODE_MAX=2 +CONFIG_LWM2M_DEVICE_EXT_DEV_INFO_MAX=2 +CONFIG_LWM2M_NUM_ATTR=20 + +# Configure stack sizes +CONFIG_MAIN_STACK_SIZE=1024 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 +CONFIG_SHELL_STACK_SIZE=1536 +CONFIG_LWM2M_ENGINE_STACK_SIZE=2048 diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 983fea79f3e..9fe1f1dce7b 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -11,7 +11,6 @@ #include LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include -#include #include #include #include @@ -28,15 +27,37 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define VERSION "1.2.3" static struct lwm2m_ctx client; +static void rd_client_event(struct lwm2m_ctx *client, + enum lwm2m_rd_client_event client_event); +static void observe_cb(enum lwm2m_observe_event event, + struct lwm2m_obj_path *path, void *user_data); + +static uint8_t bat_idx = LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT; +static int bat_mv = 3800; +static int bat_ma = 125; +static uint8_t usb_idx = LWM2M_DEVICE_PWR_SRC_TYPE_USB; +static int usb_mv = 5000; +static int usb_ma = 900; + +static void reboot_handler(struct k_work *work) +{ + /* I cannot really restart the client, as we don't know + * the endpoint name. Testcase sets that on a command line. + * So we only stop. + */ + lwm2m_rd_client_stop(&client, rd_client_event, true); +} + +K_WORK_DEFINE(reboot_work, reboot_handler); static int device_reboot_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { LOG_INF("DEVICE: REBOOT"); + k_work_submit(&reboot_work); return 0; } - static int lwm2m_setup(void) { /* setup DEVICE object */ @@ -53,6 +74,20 @@ static int lwm2m_setup(void) lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 17), CONFIG_BOARD, sizeof(CONFIG_BOARD), sizeof(CONFIG_BOARD), LWM2M_RES_DATA_FLAG_RO); + /* add power source resource instances */ + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 6, 0)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 6, 0), &bat_idx, sizeof(bat_idx), sizeof(bat_idx), 0); + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 7, 0)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 7, 0), &bat_mv, sizeof(bat_mv), sizeof(bat_mv), 0); + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 8, 0)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 8, 0), &bat_ma, sizeof(bat_ma), sizeof(bat_ma), 0); + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 6, 1)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 6, 1), &usb_idx, sizeof(usb_idx), sizeof(usb_idx), 0); + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 7, 1)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 7, 1), &usb_mv, sizeof(usb_mv), sizeof(usb_mv), 0); + lwm2m_create_res_inst(&LWM2M_OBJ(3, 0, 8, 1)); + lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 8, 1), &usb_ma, sizeof(usb_ma), sizeof(usb_ma), 0); + return 0; } diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml index aeba64748df..93f3fc13b1c 100644 --- a/tests/net/lib/lwm2m/interop/testcase.yaml +++ b/tests/net/lib/lwm2m/interop/testcase.yaml @@ -8,6 +8,7 @@ tests: platform_allow: - native_posix - qemu_cortex_m3 + - qemu_x86 tags: - testing - pytest From 1506a43705630bf150cbc5af56b7b259d7d0d65f Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 1 Nov 2023 10:20:06 +0200 Subject: [PATCH 3169/4498] tests: lwm2m: Enable DTLS CID for interoperability tests Leshan Demo server seem to support it so it makes sense to use it. Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/interop/prj.conf | 2 ++ .../net/lib/lwm2m/interop/src/lwm2m-client.c | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index b393621b581..07bd9a0535d 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -48,6 +48,7 @@ CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 CONFIG_LWM2M_UPDATE_PERIOD=30 +CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE=y # LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 @@ -75,6 +76,7 @@ CONFIG_NET_SOCKETS_SOCKOPT_TLS=y # LwM2M engine should not use more than one on any given time. CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=1 CONFIG_NET_SOCKETS_ENABLE_DTLS=y +CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y # Assume that IPv6 minimum MTU is accepted # MTU - IPv6 header - UDP header - DTLS header - CoAP header room diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 9fe1f1dce7b..706091659a5 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #define APP_BANNER "Run LWM2M client" @@ -58,6 +59,24 @@ static int device_reboot_cb(uint16_t obj_inst_id, return 0; } +int set_socketoptions(struct lwm2m_ctx *ctx) +{ + if (IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) && ctx->use_dtls) { + int ret; + + /* Enable CID */ + int cid = TLS_DTLS_CID_ENABLED; + + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_CID, &cid, + sizeof(cid)); + if (ret) { + ret = -errno; + LOG_ERR("Failed to enable TLS_DTLS_CID: %d", ret); + } + } + return lwm2m_set_default_sockopt(ctx); +} + static int lwm2m_setup(void) { /* setup DEVICE object */ @@ -201,6 +220,7 @@ int main(void) } client.tls_tag = 1; + client.set_socketoptions = set_socketoptions; lwm2m_rd_client_start(&client, CONFIG_BOARD, 0, rd_client_event, observe_cb); lwm2m_rd_client_stop(&client, rd_client_event, false); From e01657c269e9a421ffb9be7c094a5a1afc9cd170 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Fri, 13 Oct 2023 16:34:49 +0300 Subject: [PATCH 3170/4498] tests: lwm2m: Add interoperability tests 222 - 281 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add remaining test cases from Device management & Service Enablement Interface * LightweightM2M-1.1-int-222 – Read on Object * LightweightM2M-1.1-int-223 – Read on Object Instance * LightweightM2M-1.1-int-224 – Read on Resource * LightweightM2M-1.1-int-225 – Read on Resource Instance * LightweightM2M-1.1-int-226 – Write (Partial Update) on Object Instance * LightweightM2M-1.1-int-227 - Write (replace) on Resource * LightweightM2M-1.1-int-228 - Write on Resource Instance * LightweightM2M-1.1-int-229 - Read-Composite Operation * LightweightM2M-1.1-int-230 - Write-Composite Operation * LightweightM2M-1.1-int-231 - Querying basic information in SenML JSON format * LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format * LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format * LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format * LightweightM2M-1.1-int-235 - Read-Composite Operation on root path * LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence * LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type * LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device * LightweightM2M-1.1-int-256 - Write Operation Failure * LightweightM2M-1.1-int-257 - Write-Composite Operation * LightweightM2M-1.1-int-260 - Discover Command * LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource * LightweightM2M-1.1-int-280 - Successful Read-Composite Operation * LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation Modify tests binary * Allow CoAP payload of 1211 bytes. * Allow outgoing messages to use block-wise if they are bigger. * Use 4kB encode buffer for outgoing messages. * Check configured heap and stack sizes. * Limit number of interface addresses, sockets and contexts Qemu-cortex-m3 platform ran out of RAM, so reconfigure it to use * packet size of 256 bytes. * encode buffer of 2kB This exercises the block-transferring on some of the test cases. Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/interop/README.md | 110 +++- tests/net/lib/lwm2m/interop/pytest/leshan.py | 276 +++++++++- .../lib/lwm2m/interop/pytest/test_lwm2m.py | 511 +++++++++++++----- 3 files changed, 711 insertions(+), 186 deletions(-) diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md index 19883ac1821..72eb430f8e4 100644 --- a/tests/net/lib/lwm2m/interop/README.md +++ b/tests/net/lib/lwm2m/interop/README.md @@ -15,7 +15,39 @@ running Zephyr is using address `192.0.2.1`. Follow [Networking with the host system](https://docs.zephyrproject.org/latest/connectivity/networking/networking_with_host.html#networking-with-the-host-system) from Zephyr's documentation how to set it up, or follow [Create NAT and routing for Zephyr native network on Linux](https://github.com/zephyrproject-rtos/net-tools/blob/master/README%20NAT.md). -### Leshan server setup + +### Run Lehan server from net-tools Docker container + +Zephyr's net-tools Docker container already contains Leshan, so if you don't want to set the environment up manually, +use the pre-made docker. + +First, build the docker container. You only need to do this one, or when you update the container. +``` +cd tools/net-tools/docker +docker build -t net-tools . +``` + +Start the docker networking +``` +cd tools/net-tools/ +sudo ./net-setup.sh --config docker.conf start +``` + +Start the docker container and run leshan +``` +docker run --hostname=net-tools --name=net-tools --ip=192.0.2.2 --ip6=2001:db8::2 -p 8080:8080 -p 8081:8081 -p 5683:5683/udp --rm -dit --network=net-tools0 net-tools +docker container exec net-tools /net-tools/start-leshan.sh +``` + +### Stop Leshan, docker and networking + +``` +cd tools/net-tools/ +docker kill net-tools +sudo ./net-setup.sh --config docker.conf stop +docker network rm net-tools0 +``` +### Leshan server setup (manual) * Leshan server must be reachable from the device using IP address `192.0.2.2`. Configure the port forwarding, if you use Docker to run Leshan. @@ -87,23 +119,59 @@ Or use the Docker based testing Tests are written from test spec; [OMA Enabler Test Specification (Interoperability) for Lightweight M2M](https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf) -Following tests are implemented: -* LightweightM2M-1.1-int-0 – Client Initiated Bootstrap -* LightweightM2M-1.1-int-1 – Client Initiated Bootstrap Full (PSK) -* LightweightM2M-1.1-int-101 – Initial Registration -* LightweightM2M-1.1-int-102 – Registration Update -* LightweightM2M-1.1-int-104 – Registration Update Trigge -* LightweightM2M-1.1-int-105 - Discarded Register Update -* LightweightM2M-1.1-int-107 – Extending the lifetime of a registration -* LightweightM2M-1.1-int-108 – Turn on Queue Mode -* LightweightM2M-1.1-int-109 – Behavior in Queue Mode -* LightweightM2M-1.1-int-201 – Querying basic information in Plain Text -* LightweightM2M-1.1-int-203 – Querying basic information in TLV format -* LightweightM2M-1.1-int-204 – Querying basic information in JSON format -* LightweightM2M-1.1-int-205 – Setting basic information in Plain Text -* LightweightM2M-1.1-int-211 – Querying basic information in CBOR format -* LightweightM2M-1.1-int-212 – Setting basic information in CBOR format -* LightweightM2M-1.1-int-215 – Setting basic information in TLV format -* LightweightM2M-1.1-int-220 – Setting basic information in JSON format -* LightweightM2M-1.1-int-221 – Attempt to perform operations on Security -* LightweightM2M-1.1-int-401 – UDP Channel Security – PSK Mode +## Current status + +|Test case|Status|Notes| +|---------|------|-----| +|LightweightM2M-1.1-int-0 - Client Initiated Bootstrap |:white_check_mark:| | +|LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK) |:white_check_mark:| | +|LightweightM2M-1.1-int-101 - Initial Registration |:white_check_mark:| | +|LightweightM2M-1.1-int-102 - Registration Update |:white_check_mark:| | +|LightweightM2M-1.1-int-103 - Deregistration |:large_orange_diamond:|We don't have "disabled" functionality in server object| +|LightweightM2M-1.1-int-104 - Registration Update Trigge |:white_check_mark:| | +|LightweightM2M-1.1-int-105 - Discarded Register Update |:white_check_mark:| | +|LightweightM2M-1.1-int-107 - Extending the lifetime of a registration |:white_check_mark:| | +|LightweightM2M-1.1-int-108 - Turn on Queue Mode |:white_check_mark:| | +|LightweightM2M-1.1-int-109 - Behavior in Queue Mode |:white_check_mark:| | +|LightweightM2M-1.1-int-201 - Querying basic information in Plain Text |:white_check_mark:| | +|LightweightM2M-1.1-int-203 - Querying basic information in TLV format |:white_check_mark:| | +|LightweightM2M-1.1-int-204 - Querying basic information in JSON format |:white_check_mark:| | +|LightweightM2M-1.1-int-205 - Setting basic information in Plain Text |:white_check_mark:| | +|LightweightM2M-1.1-int-211 - Querying basic information in CBOR format |:white_check_mark:| | +|LightweightM2M-1.1-int-212 - Setting basic information in CBOR format |:white_check_mark:| | +|LightweightM2M-1.1-int-215 - Setting basic information in TLV format |:white_check_mark:| | +|LightweightM2M-1.1-int-220 - Setting basic information in JSON format |:white_check_mark:| | +|LightweightM2M-1.1-int-221 - Attempt to perform operations on Security |:white_check_mark:| | +|LightweightM2M-1.1-int-222 - Read on Object |:white_check_mark:| | +|LightweightM2M-1.1-int-223 - Read on Object Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-224 - Read on Resource |:white_check_mark:| | +|LightweightM2M-1.1-int-225 - Read on Resource Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-226 - Write (Partial Update) on Object Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-222 - Read on Object |:white_check_mark:| | +|LightweightM2M-1.1-int-223 - Read on Object Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-224 - Read on Resource |:white_check_mark:| | +|LightweightM2M-1.1-int-225 - Read on Resource Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-226 - Write (Partial Update) on Object Instance |:white_check_mark:| | +|LightweightM2M-1.1-int-227 - Write (replace) on Resource |:white_check_mark:| | +|LightweightM2M-1.1-int-228 - Write on Resource Instance |:white_check_mark:|[~~#64011~~](https://github.com/zephyrproject-rtos/zephyr/issues/64011) | +|LightweightM2M-1.1-int-229 - Read-Composite Operation|:white_check_mark:|[~~#64012~~](https://github.com/zephyrproject-rtos/zephyr/issues/64012) [~~#64189~~](https://github.com/zephyrproject-rtos/zephyr/issues/64189) | +|LightweightM2M-1.1-int-230 - Write-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-231 - Querying basic information in SenML JSON format|:white_check_mark:| | +|LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format|:white_check_mark:| | +|LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format|:white_check_mark:| | +|LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format|:white_check_mark:| | +|LightweightM2M-1.1-int-235 - Read-Composite Operation on root path|:large_orange_diamond:|Root Path is not yet supported by Leshan.| +|LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence|:white_check_mark:| | +|LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type|:white_check_mark:| | +|LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device|:white_check_mark:| | +|LightweightM2M-1.1-int-256 - Write Operation Failure|:white_check_mark:| | +|LightweightM2M-1.1-int-257 - Write-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-260 - Discover Command|:white_check_mark:| | +|LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource|:large_orange_diamond:|Leshan don't allow writing attributes to resource instance| +|LightweightM2M-1.1-int-280 - Successful Read-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-401 - UDP Channel Security - PSK Mode |:white_check_mark:| | + +* :white_check_mark: Working OK. +* :large_orange_diamond: Feature or operation not implemented. +* :red_circle: Broken diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index 4d69a3a977f..ecd14b2481c 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -5,15 +5,16 @@ from __future__ import annotations import json -import requests import binascii +import requests +from datetime import datetime class Leshan: def __init__(self, url: str): self.api_url = url self.timeout = 10 - self.format = 'TLV' - # self.format = "SENML_CBOR" + #self.format = 'TLV' + self.format = "SENML_CBOR" try: resp = self.get('/security/clients') if not isinstance(resp, list): @@ -23,7 +24,18 @@ def __init__(self, url: str): @staticmethod def handle_response(resp: requests.models.Response): - """Generic response handler for all queries""" + """ + Handle the response received from the server. + + Parameters: + - response: The response object received from the server. + + Returns: + - dict: The parsed JSON response as a dictionary. + + Raises: + - Exception: If the response indicates an error condition. + """ if resp.status_code >= 300 or resp.status_code < 200: raise RuntimeError(f'Error {resp.status_code}: {resp.text}') if len(resp.text): @@ -34,11 +46,14 @@ def handle_response(resp: requests.models.Response): def get(self, path: str): """Send HTTP GET query""" - resp = requests.get(f'{self.api_url}{path}?timeout={self.timeout}&format={self.format}') + params = {'timeout': self.timeout} + if self.format is not None: + params['format'] = self.format + resp = requests.get(f'{self.api_url}{path}', params=params, timeout=self.timeout) return Leshan.handle_response(resp) def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): - resp = requests.put(f'{self.api_url}{path}', data=data, headers=headers) + resp = requests.put(f'{self.api_url}{path}', data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) def put(self, path: str, data: str | dict, uri_options: str = ''): @@ -47,42 +62,249 @@ def put(self, path: str, data: str | dict, uri_options: str = ''): return self.put_raw(f'{path}?timeout={self.timeout}&format={self.format}' + uri_options, data=data, headers={'content-type': 'application/json'}) def post(self, path: str, data: str | dict | None = None): - resp = requests.post(f'{self.api_url}{path}', data=data, headers={'content-type': 'application/json'}) + if isinstance(data, dict): + data = json.dumps(data) + if data is not None: + headers={'content-type': 'application/json'} + uri_options = f'?timeout={self.timeout}&format={self.format}' + else: + headers=None + uri_options = '' + resp = requests.post(f'{self.api_url}{path}' + uri_options, data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) def delete(self, path: str): - resp = requests.delete(f'{self.api_url}{path}') + resp = requests.delete(f'{self.api_url}{path}', timeout=self.timeout) return Leshan.handle_response(resp) def execute(self, endpoint: str, path: str): return self.post(f'/clients/{endpoint}/{path}') def write(self, endpoint: str, path: str, value: bool | int | str): + if len(path.split('/')) == 3: + kind = 'singleResource' + else: + kind = 'resourceInstance' + rid = path.split('/')[-1] + return self.put(f'/clients/{endpoint}/{path}', self._define_resource(rid, value, kind)) + + def update_obj_instance(self, endpoint: str, path: str, resources: dict): + data = self._define_obj_inst(path, resources) + return self.put(f'/clients/{endpoint}/{path}', data, uri_options='&replace=false') + + def replace_obj_instance(self, endpoint: str, path: str, resources: dict): + data = self._define_obj_inst(path, resources) + return self.put(f'/clients/{endpoint}/{path}', data, uri_options='&replace=true') + + def create_obj_instance(self, endpoint: str, path: str, resources: dict): + data = self._define_obj_inst(path, resources) + path = '/'.join(path.split('/')[:-1]) # Create call should not have instance ID in path + return self.post(f'/clients/{endpoint}/{path}', data) + + @classmethod + def _type_to_string(cls, value): + """ + Convert a Python value to its corresponding Leshan representation. + + Parameters: + - value: The value to be converted. + + Returns: + - str: The string representation of the value. + """ if isinstance(value, bool): - type = 'boolean' - value = "true" if value else "false" - elif isinstance(value, int): - type = 'integer' - value = str(value) - elif isinstance(value, str): - type = 'string' - value = '"' + value + '"' - id = path.split('/')[2] - return self.put(f'/clients/{endpoint}/{path}', f'{{"id":{id},"kind":"singleResource","value":{value},"type":"{type}"}}') + return 'boolean' + if isinstance(value, int): + return 'integer' + if isinstance(value, datetime): + return 'time' + return 'string' + + @classmethod + def _convert_type(cls, value): + if isinstance(value, datetime): + return int(value.timestamp()) + else: + return value + + def _define_obj_inst(self, path: str, resources: dict): + data = { + "kind": "instance", + "id": int(path.split('/')[-1]), # ID is last element of path + "resources": [] + } + for key, value in resources.items(): + if isinstance(value, dict): + kind = 'multiResource' + else: + kind = 'singleResource' + data['resources'].append(self._define_resource(key, value, kind)) + return data + + def _define_resource(self, rid, value, kind='singleResource'): + if kind in ('singleResource', 'resourceInstance'): + return { + "id": rid, + "kind": kind, + "value": self._convert_type(value), + "type": self._type_to_string(value) + } + if kind == 'multiResource': + return { + "id": rid, + "kind": kind, + "values": value, + "type": self._type_to_string(list(value.values())[0]) + } + raise RuntimeError(f'Unhandled type {kind}') + + def _decode_value(self, type, value): + """ + Decode the Leshan representation of a value back to a Python value. + """ + if type == 'BOOLEAN': + return bool(value) + if type == 'INTEGER': + return int(value) + return value + + def _decode_resource(self, content): + """ + Decode the Leshan representation of a resource back to a Python dictionary. + """ + if content['kind'] == 'singleResource' or content['kind'] == 'resourceInstance': + return {content['id']: self._decode_value(content['type'], content['value'])} + elif content['kind'] == 'multiResource': + values = {} + for riid, value in content['values'].items(): + values.update({int(riid): self._decode_value(content['type'], value)}) + return {content['id']: values} + raise RuntimeError(f'Unhandled type {content["kind"]}') + + def _decode_obj_inst(self, content): + """ + Decode the Leshan representation of an object instance back to a Python dictionary. + """ + resources = {} + for resource in content['resources']: + resources.update(self._decode_resource(resource)) + return {content['id']: resources} + + def _decode_obj(self, content): + """ + Decode the Leshan representation of an object back to a Python dictionary. + """ + instances = {} + for instance in content['instances']: + instances.update(self._decode_obj_inst(instance)) + return {content['id']: instances} def read(self, endpoint: str, path: str): resp = self.get(f'/clients/{endpoint}/{path}') if not resp['success']: return resp content = resp['content'] - if content['kind'] == 'instance': - return content['resources'] - elif content['kind'] == 'singleResource': - return content['value'] + if content['kind'] == 'obj': + return self._decode_obj(content) + elif content['kind'] == 'instance': + return self._decode_obj_inst(content) + elif content['kind'] == 'singleResource' or content['kind'] == 'resourceInstance': + return self._decode_value(content['type'], content['value']) elif content['kind'] == 'multiResource': - return content['values'] + return self._decode_resource(content) raise RuntimeError(f'Unhandled type {content["kind"]}') + def composite_read(self, endpoint: str, paths: list[str]): + paths = [path if path.startswith('/') else '/' + path for path in paths] + parameters = { + 'pathformat': self.format, + 'nodeformat': self.format, + 'timeout': self.timeout, + 'paths': ','.join(paths) + } + resp = requests.get(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, timeout=self.timeout) + payload = Leshan.handle_response(resp) + if not payload['status'] == 'CONTENT(205)': + raise RuntimeError(f'No content received') + data = {} + for path, content in payload['content'].items(): + keys = [int(key) for key in path.lstrip("/").split('/')] + if len(keys) == 1: + data.update(self._decode_obj(content)) + elif len(keys) == 2: + if keys[0] not in data: + data[keys[0]] = {} + data[keys[0]].update(self._decode_obj_inst(content)) + elif len(keys) == 3: + if keys[0] not in data: + data[keys[0]] = {} + if keys[1] not in data[keys[0]]: + data[keys[0]][keys[1]] = {} + data[keys[0]][keys[1]].update(self._decode_resource(content)) + elif len(keys) == 4: + if keys[0] not in data: + data[keys[0]] = {} + if keys[1] not in data[keys[0]]: + data[keys[0]][keys[1]] = {} + if keys[2] not in data[keys[0]][keys[1]]: + data[keys[0]][keys[1]][keys[2]] = {} + data[keys[0]][keys[1]][keys[2]].update(self._decode_resource(content)) + else: + raise RuntimeError(f'Unhandled path {path}') + print(f'Requested paths: {paths}') + print(data) + return data + + + def composite_write(self, endpoint: str, resources: dict): + """ + Do LwM2m composite write operation. + + Targeted resources are defined as a dictionary with the following structure: + { + "/1/0/1": 60, + "/1/0/6": True, + "/16/0/0": { + "0": "aa", + "1": "bb", + "2": "cc", + "3": "dd" + } + } + + Objects or object instances cannot be targeted. + """ + data = { } + parameters = { + 'pathformat': self.format, + 'nodeformat': self.format, + 'timeout': self.timeout + } + for path, value in resources.items(): + path = path if path.startswith('/') else '/' + path + level = len(path.split('/')) - 1 + rid = int(path.split('/')[-1]) + if level == 3: + if isinstance(value, dict): + value = self._define_resource(rid, value, kind='multiResource') + else: + value = self._define_resource(rid, value) + elif level == 4: + value = self._define_resource(rid, value, kind='resourceInstance') + else: + raise RuntimeError(f'Unhandled path {path}') + data[path] = value + + resp = requests.put(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, json=data, timeout=self.timeout) + return Leshan.handle_response(resp) + + def discover(self, endpoint: str, path: str): + resp = self.handle_response(requests.get(f'{self.api_url}/clients/{endpoint}/{path}/discover', timeout=self.timeout)) + data = {} + for obj in resp['objectLinks']: + data[obj['url']] = obj['attributes'] + return data + def create_psk_device(self, endpoint: str, passwd: str): psk = binascii.b2a_hex(passwd.encode()).decode() self.put('/security/clients/', f'{{"endpoint":"{endpoint}","tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}} }} }}') @@ -90,13 +312,13 @@ def create_psk_device(self, endpoint: str, passwd: str): def delete_device(self, endpoint: str): self.delete(f'/security/clients/{endpoint}') - def create_bs_device(self, endpoint: str, server_uri: str, passwd: str): - psk = binascii.b2a_hex(passwd.encode()).decode() + def create_bs_device(self, endpoint: str, server_uri: str, bs_passwd: str, passwd: str): + psk = binascii.b2a_hex(bs_passwd.encode()).decode() data = f'{{"tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}}}},"endpoint":"{endpoint}"}}' self.put('/security/clients/', data) - id = str([ord(n) for n in endpoint]) + ep = str([ord(n) for n in endpoint]) key = str([ord(n) for n in passwd]) - content = '{"servers":{"0":{"binding":"U","defaultMinPeriod":1,"lifetime":86400,"notifIfDisabled":false,"shortId":1}},"security":{"1":{"bootstrapServer":false,"clientOldOffTime":1,"publicKeyOrId":' + id + ',"secretKey":' + key + ',"securityMode":"PSK","serverId":1,"serverSmsNumber":"","smsBindingKeyParam":[],"smsBindingKeySecret":[],"smsSecurityMode":"NO_SEC","uri":"'+server_uri+'"}},"oscore":{},"toDelete":["/0","/1"]}' + content = '{"servers":{"0":{"binding":"U","defaultMinPeriod":1,"lifetime":86400,"notifIfDisabled":false,"shortId":1}},"security":{"1":{"bootstrapServer":false,"clientOldOffTime":1,"publicKeyOrId":' + ep + ',"secretKey":' + key + ',"securityMode":"PSK","serverId":1,"serverSmsNumber":"","smsBindingKeyParam":[],"smsBindingKeySecret":[],"smsSecurityMode":"NO_SEC","uri":"'+server_uri+'"}},"oscore":{},"toDelete":["/0","/1"]}' self.post(f'/bootstrap/{endpoint}', content) def delete_bs_device(self, endpoint: str): diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index 53a205fadb9..384e3cadda5 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -12,6 +12,7 @@ import string from twister_harness import Shell +from datetime import datetime LESHAN_IP: str = '192.0.2.2' COAP_PORT: int = 5683 @@ -67,8 +68,8 @@ def verify_LightweightM2M_1_1_int_101(shell: Shell, leshan: Leshan, endpoint: st def verify_LightweightM2M_1_1_int_102(shell: Shell, leshan: Leshan, endpoint: str): logger.info("LightweightM2M-1.1-int-102 - Registration Update") lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) - litetime = int(lines[0]) - lifetime = litetime + 10 + lifetime = int(lines[0]) + lifetime = lifetime + 10 start_time = time.time() * 1000 leshan.write(endpoint, '1/0/1', lifetime) shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) @@ -95,10 +96,10 @@ def verify_LightweightM2M_1_1_int_105(shell: Shell, leshan: Leshan, endpoint: st if status["secure"]: logger.debug("Skip, requires non-secure connection") return - id = status["registrationId"] - assert id + regid = status["registrationId"] + assert regid # Fake unregister message - helperclient.delete(f'rd/{id}', timeout=0.1) + helperclient.delete(f'rd/{regid}', timeout=0.1) helperclient.stop() time.sleep(1) shell.exec_command('lwm2m update') @@ -122,7 +123,6 @@ def verify_LightweightM2M_1_1_int_108(leshan, endpoint): def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: str): logger.info("LightweightM2M-1.1-int-109 - Behavior in Queue Mode") - verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) logger.debug('Wait for Queue RX OFF') shell._device.readlines_until(regex='.*Queue mode RX window closed', timeout=120) # Restore previous value @@ -130,74 +130,39 @@ def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: st shell._device.readlines_until(regex='.*Registration update complete', timeout=10) def verify_LightweightM2M_1_1_int_201(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-201 - Querying basic information in Plain Text format") fmt = leshan.format leshan.format = 'TEXT' - assert leshan.get(f'/clients/{endpoint}/3/0/0')['content']['value'] == 'Zephyr' - assert leshan.get(f'/clients/{endpoint}/3/0/1')['content']['value'] == 'client-1' - assert leshan.get(f'/clients/{endpoint}/3/0/2')['content']['value'] == 'serial-1' + assert leshan.read(endpoint, '3/0/0') == 'Zephyr' + assert leshan.read(endpoint, '3/0/1') == 'client-1' + assert leshan.read(endpoint, '3/0/2') == 'serial-1' leshan.format = fmt def verify_device_object(resp): ''' Verify that Device object match Configuration 3 ''' - assert resp['valid'] is True - found = 0 - for res in resp['content']['resources']: - if res['id'] == 0: - assert res['value'] == 'Zephyr' - found += 1 - elif res['id'] == 1: - assert res['value'] == 'client-1' - found += 1 - elif res['id'] == 2: - assert res['value'] == 'serial-1' - found += 1 - elif res['id'] == 3: - assert res['value'] == '1.2.3' - found += 1 - elif res['id'] == 11: - assert res['kind'] == 'multiResource' - assert res['values']['0'] == '0' - found += 1 - elif res['id'] == 16: - assert res['value'] == 'U' - found += 1 - assert found == 6 + assert resp[0][0] == 'Zephyr' + assert resp[0][1] == 'client-1' + assert resp[0][2] == 'serial-1' + assert resp[0][3] == '1.2.3' + assert resp[0][11][0] == 0 + assert resp[0][16] == 'U' def verify_server_object(obj): ''' Verify that server object match Configuration 3 ''' - found = 0 - for res in obj['resources']: - if res['id'] == 0: - assert res['value'] == '1' - found += 1 - elif res['id'] == 1: - assert res['value'] == '86400' - found += 1 - elif res['id'] == 2: - assert res['value'] == '1' - found += 1 - elif res['id'] == 3: - assert res['value'] == '10' - found += 1 - elif res['id'] == 5: - assert res['value'] == '86400' - found += 1 - elif res['id'] == 6: - assert res['value'] is False - found += 1 - elif res['id'] == 7: - assert res['value'] == 'U' - found += 1 - assert found == 7 + assert obj[0][0] == 1 + assert obj[0][1] == 86400 + assert obj[0][2] == 1 + assert obj[0][3] == 10 + assert obj[0][5] == 86400 + assert obj[0][6] is False + assert obj[0][7] == 'U' def verify_LightweightM2M_1_1_int_203(shell: Shell, leshan: Leshan, endpoint: str): shell.exec_command('lwm2m update') logger.info('LightweightM2M-1.1-int-203 - Querying basic information in TLV format') fmt = leshan.format leshan.format = 'TLV' - resp = leshan.get(f'/clients/{endpoint}/3/0') + resp = leshan.read(endpoint,'3/0') verify_device_object(resp) leshan.format = fmt @@ -206,7 +171,7 @@ def verify_LightweightM2M_1_1_int_204(shell: Shell, leshan: Leshan, endpoint: st logger.info('LightweightM2M-1.1-int-204 - Querying basic information in JSON format') fmt = leshan.format leshan.format = 'JSON' - resp = leshan.get(f'/clients/{endpoint}/3/0') + resp = leshan.read(endpoint, '3/0') verify_device_object(resp) leshan.format = fmt @@ -217,15 +182,15 @@ def verify_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: st leshan.write(endpoint, '1/0/2', 101) leshan.write(endpoint, '1/0/3', 1010) leshan.write(endpoint, '1/0/5', 2000) - assert leshan.read(endpoint, '1/0/2') == '101' - assert leshan.read(endpoint, '1/0/3') == '1010' - assert leshan.read(endpoint, '1/0/5') == '2000' + assert leshan.read(endpoint, '1/0/2') == 101 + assert leshan.read(endpoint, '1/0/3') == 1010 + assert leshan.read(endpoint, '1/0/5') == 2000 leshan.write(endpoint, '1/0/2', 1) leshan.write(endpoint, '1/0/3', 10) leshan.write(endpoint, '1/0/5', 86400) - assert leshan.read(endpoint, '1/0/2') == '1' - assert leshan.read(endpoint, '1/0/3') == '10' - assert leshan.read(endpoint, '1/0/5') == '86400' + assert leshan.read(endpoint, '1/0/2') == 1 + assert leshan.read(endpoint, '1/0/3') == 10 + assert leshan.read(endpoint, '1/0/5') == 86400 leshan.format = fmt def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: str): @@ -233,8 +198,8 @@ def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: st fmt = leshan.format leshan.format = 'CBOR' lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) - id = lines[0] - assert leshan.read(endpoint, '1/0/0') == id + short_id = int(lines[0]) + assert leshan.read(endpoint, '1/0/0') == short_id assert leshan.read(endpoint, '1/0/6') is False assert leshan.read(endpoint, '1/0/7') == 'U' leshan.format = fmt @@ -246,8 +211,8 @@ def verify_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: st leshan.write(endpoint, '1/0/2', 101) leshan.write(endpoint, '1/0/3', 1010) leshan.write(endpoint, '1/0/6', True) - assert leshan.read(endpoint, '1/0/2') == '101' - assert leshan.read(endpoint, '1/0/3') == '1010' + assert leshan.read(endpoint, '1/0/2') == 101 + assert leshan.read(endpoint, '1/0/3') == 1010 assert leshan.read(endpoint, '1/0/6') is True leshan.write(endpoint, '1/0/2', 1) leshan.write(endpoint, '1/0/3', 10) @@ -257,71 +222,26 @@ def verify_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: st def verify_setting_basic_in_format(shell, leshan, endpoint, format): fmt = leshan.format leshan.format = format - server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] + server_obj = leshan.read(endpoint, '1/0') verify_server_object(server_obj) # Remove Read-Only resources, so we don't end up writing those - for res in server_obj['resources']: - if res['id'] in (0, 11, 12): - server_obj['resources'].remove(res) - data = '''{ - "kind": "instance", - "id": 0, - "resources": [ - { - "id": 2, - "kind": "singleResource", - "value": "101", - "type": "integer" - }, - { - "id": 3, - "kind": "singleResource", - "value": "1010", - "type": "integer" - }, - { - "id": 5, - "kind": "singleResource", - "value": "2000", - "type": "integer" - }, - { - "id": 6, - "kind": "singleResource", - "value": true, - "type": "boolean" - }, - { - "id": 7, - "kind": "singleResource", - "value": "U", - "type": "string" - } - ] - }''' - assert leshan.put(f'/clients/{endpoint}/1/0', data, uri_options = '&replace=false')['status'] == 'CHANGED(204)' - resp = leshan.get(f'/clients/{endpoint}/1/0') - assert resp['valid'] is True - found = 0 - for res in resp['content']['resources']: - if res['id'] == 2: - assert res['value'] == '101' - found += 1 - elif res['id'] == 3: - assert res['value'] == '1010' - found += 1 - elif res['id'] == 5: - assert res['value'] == '2000' - found += 1 - elif res['id'] == 6: - assert res['value'] is True - found += 1 - elif res['id'] == 7: - assert res['value'] == 'U' - found += 1 - assert found == 5 - assert leshan.put(f'/clients/{endpoint}/1/0', data = server_obj, uri_options = '&replace=true')['status'] == 'CHANGED(204)' - server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] + del server_obj[0][0] + data = { + 2: 101, + 3: 1010, + 5: 2000, + 6: True, + 7: 'U' + } + assert leshan.update_obj_instance(endpoint, '1/0', data)['status'] == 'CHANGED(204)' + resp = leshan.read(endpoint, '1/0') + assert resp[0][2] == 101 + assert resp[0][3] == 1010 + assert resp[0][5] == 2000 + assert resp[0][6] is True + assert resp[0][7] == 'U' + assert leshan.replace_obj_instance(endpoint, '1/0', server_obj[0])['status'] == 'CHANGED(204)' + server_obj = leshan.read(endpoint, '1/0') verify_server_object(server_obj) leshan.format = fmt @@ -339,6 +259,297 @@ def verify_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: st assert leshan.write(endpoint, '0/0/0', 'coap://localhost')['status'] == 'UNAUTHORIZED(401)' assert leshan.put_raw(f'/clients/{endpoint}/0/attributes?pmin=10')['status'] == 'UNAUTHORIZED(401)' +def verify_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-222 - Read on Object") + resp = leshan.read(endpoint, '1') + assert len(resp) == 1 + assert len(resp[1][0]) == 9 + resp = leshan.read(endpoint, '3') + assert len(resp) == 1 + assert len(resp[3]) == 1 + assert len(resp[3][0]) == 15 + assert resp[3][0][0] == 'Zephyr' + +def verify_LightweightM2M_1_1_int_223(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-223 - Read on Object Instance") + resp = leshan.read(endpoint, '1/0') + assert len(resp[0]) == 9 + resp = leshan.read(endpoint, '3/0') + assert len(resp[0]) == 15 + assert resp[0][0] == 'Zephyr' + +def verify_LightweightM2M_1_1_int_224(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-224 - Read on Resource") + assert leshan.read(endpoint, '1/0/0') == 1 + assert leshan.read(endpoint, '1/0/1') == 86400 + assert leshan.read(endpoint, '1/0/6') is False + assert leshan.read(endpoint, '1/0/7') == 'U' + +def verify_LightweightM2M_1_1_int_225(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-225 - Read on Resource Instance") + assert leshan.read(endpoint, '3/0/11/0') == 0 + +def verify_LightweightM2M_1_1_int_226(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-226 - Write (Partial Update) on Object Instance") + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) + lifetime = int(lines[0]) + resources = { + 1: 60, + 6: True + } + assert leshan.update_obj_instance(endpoint, '1/0', resources)['status'] == 'CHANGED(204)' + assert leshan.read(endpoint, '1/0/1') == 60 + assert leshan.read(endpoint, '1/0/6') is True + resources = { + 1: lifetime, + 6: False + } + assert leshan.update_obj_instance(endpoint, '1/0', resources)['status'] == 'CHANGED(204)' + +def verify_LightweightM2M_1_1_int_227(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-227 - Write (replace) on Resource") + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) + lifetime = int(lines[0]) + assert leshan.write(endpoint, '1/0/1', int(63))['status'] == 'CHANGED(204)' + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + latest = leshan.get(f'/clients/{endpoint}') + assert latest["lifetime"] == 63 + assert leshan.read(endpoint, '1/0/1') == 63 + assert leshan.write(endpoint, '1/0/1', lifetime)['status'] == 'CHANGED(204)' + +def verify_LightweightM2M_1_1_int_228(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-228 - Write on Resource Instance") + resources = { + 0: {0: 'a', 1: 'b'} + } + assert leshan.create_obj_instance(endpoint, '16/0', resources)['status'] == 'CREATED(201)' + shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + assert leshan.write(endpoint, '16/0/0/0', 'test')['status'] == 'CHANGED(204)' + assert leshan.read(endpoint, '16/0/0/0') == 'test' + +def verify_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-229 - Read-Composite Operation") + old_fmt = leshan.format + for fmt in ['SENML_JSON', 'SENML_CBOR']: + leshan.format = fmt + resp = leshan.composite_read(endpoint, ['/3', '1/0']) + assert len(resp.keys()) == 2 + assert resp[3] is not None + assert resp[1][0] is not None + assert len(resp[3][0]) == 15 + assert len(resp[1][0]) == 9 + + resp = leshan.composite_read(endpoint, ['1/0/1', '/3/0/11/0']) + logger.debug(resp) + assert len(resp.keys()) == 2 + assert resp[1][0][1] is not None + assert resp[3][0][11][0] is not None + leshan.format = old_fmt + +def verify_LightweightM2M_1_1_int_230(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-230 - Write-Composite Operation") + resources = { + "/1/0/1": 60, + "/1/0/6": True, + "/16/0/0": { + "0": "aa", + "1": "bb", + "2": "cc", + "3": "dd" + } + } + old_fmt = leshan.format + for fmt in ['SENML_JSON', 'SENML_CBOR']: + leshan.format = fmt + assert leshan.composite_write(endpoint, resources)['status'] == 'CHANGED(204)' + resp = leshan.read(endpoint, '1/0') + assert resp[0][1] == 60 + assert resp[0][6] is True + resp = leshan.read(endpoint, '16/0/0') + assert resp[0][0] == "aa" + assert resp[0][1] == "bb" + assert resp[0][2] == "cc" + assert resp[0][3] == "dd" + # Return to default + shell.exec_command('lwm2m write /1/0/1 -u32 86400') + shell.exec_command('lwm2m write /1/0/6 -u8 0') + leshan.format = old_fmt + +def query_basic_in_senml(leshan: Leshan, endpoint: str, fmt: str): + old_fmt = leshan.format + leshan.format = fmt + verify_server_object(leshan.read(endpoint, '1')[1]) + verify_device_object(leshan.read(endpoint, '3/0')) + assert leshan.read(endpoint, '3/0/16') == 'U' + assert leshan.read(endpoint, '3/0/11/0') == 0 + leshan.format = old_fmt + +def verify_LightweightM2M_1_1_int_231(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-231 - Querying basic information in SenML JSON format") + query_basic_in_senml(leshan, endpoint, 'SENML_JSON') + +def verify_LightweightM2M_1_1_int_232(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format") + query_basic_in_senml(leshan, endpoint, 'SENML_CBOR') + +def setting_basic_senml(shell: Shell, leshan: Leshan, endpoint: str, fmt: str): + old_fmt = leshan.format + leshan.format = fmt + resources = { + 1: 61, + 6: True, + } + assert leshan.update_obj_instance(endpoint, '1/0', resources)['status'] == 'CHANGED(204)' + srv_obj = leshan.read(endpoint, '1/0') + assert srv_obj[0][1] == 61 + assert srv_obj[0][6] is True + assert leshan.write(endpoint, '16/0/0/0', 'test_value')['status'] == 'CHANGED(204)' + portfolio = leshan.read(endpoint, '16') + assert portfolio[16][0][0][0] == 'test_value' + assert leshan.write(endpoint, '1/0/1', 63)['status'] == 'CHANGED(204)' + assert leshan.read(endpoint, '1/0/1') == 63 + shell.exec_command('lwm2m write /1/0/1 -u32 86400') + shell.exec_command('lwm2m write /1/0/6 -u8 0') + leshan.format = old_fmt + +def verify_LightweightM2M_1_1_int_233(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format") + setting_basic_senml(shell, leshan, endpoint, 'SENML_CBOR') + +def verify_LightweightM2M_1_1_int_234(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format") + setting_basic_senml(shell, leshan, endpoint, 'SENML_JSON') + +def verify_LightweightM2M_1_1_int_235(): + """LightweightM2M-1.1-int-235 - Read-Composite Operation on root path""" + # Unsupported. Leshan does not allow this. + +def verify_LightweightM2M_1_1_int_236(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence") + resp = leshan.composite_read(endpoint, ['1/0', '/3/0/11/0', '/3339/0/5522', '/3353/0/6030']) + assert resp[1][0][1] is not None + assert resp[3][0][11][0] is not None + assert len(resp) == 2 + +def verify_LightweightM2M_1_1_int_237(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type") + old_fmt = leshan.format + leshan.format = None + assert leshan.read(endpoint, '1')[1][0][1] is not None + assert leshan.read(endpoint, '3')[3][0][0] == 'Zephyr' + leshan.format = old_fmt + +def verify_LightweightM2M_1_1_int_241(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device") + leshan.execute(endpoint, '3/0/4') + shell._device.readlines_until(regex='.*DEVICE: REBOOT', timeout=5.0) + shell._device.readlines_until(regex='.*rd_client_event: Disconnected', timeout=5.0) + shell.exec_command(f'lwm2m start {endpoint} -b 0') + shell._device.readlines_until(regex='.*Registration Done', timeout=5.0) + assert leshan.get(f'/clients/{endpoint}') + +def verify_LightweightM2M_1_1_int_256(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-256 - Write Operation Failure") + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) + short_id = int(lines[0]) + assert leshan.write(endpoint, '1/0/0', 123)['status'] == 'METHOD_NOT_ALLOWED(405)' + assert leshan.read(endpoint, '1/0/0') == short_id + +def verify_LightweightM2M_1_1_int_257(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-257 - Write-Composite Operation") + resources = { + "/1/0/2": 102, + "/1/0/6": True, + "/3/0/13": datetime.fromtimestamp(0) + } + old_fmt = leshan.format + for fmt in ['SENML_JSON', 'SENML_CBOR']: + leshan.format = fmt + assert leshan.composite_write(endpoint, resources)['status'] == 'CHANGED(204)' + assert leshan.read(endpoint, '1/0/2') == 102 + assert leshan.read(endpoint, '1/0/6') is True + # Cannot verify the /3/0/13, it is a timestamp that moves forward. + + # Return to default + shell.exec_command(f'lwm2m write /3/0/13 -u32 {int(datetime.now().timestamp())}') + shell.exec_command('lwm2m write /1/0/6 -u8 0') + shell.exec_command('lwm2m write /1/0/2 -u32 1') + leshan.format = old_fmt + +def verify_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-260 - Discover Command") + resp = leshan.discover(endpoint, '3') + expected_keys = ['/3', '/3/0', '/3/0/1', '/3/0/2', '/3/0/3', '/3/0/4', '/3/0/6', '/3/0/7', '/3/0/8', '/3/0/9', '/3/0/11', '/3/0/16'] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=10')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=200')['status'] == 'CHANGED(204)' + resp = leshan.discover(endpoint, '3/0') + assert int(resp['/3/0/6']['dim']) == 2 + assert int(resp['/3/0/7']['dim']) == 2 + assert int(resp['/3/0/8']['dim']) == 2 + assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?lt=1')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?gt=6')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?st=1')['status'] == 'CHANGED(204)' + resp = leshan.discover(endpoint, '3/0') + expected_keys = ['/3/0', '/3/0/1', '/3/0/2', '/3/0/3', '/3/0/4', '/3/0/6', '/3/0/7', '/3/0/8', '/3/0/9', '/3/0/11', '/3/0/16'] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 + assert int(resp['/3/0/7']['dim']) == 2 + assert float(resp['/3/0/7']['lt']) == 1.0 + assert float(resp['/3/0/7']['gt']) == 6.0 + assert float(resp['/3/0/7']['st']) == 1.0 + resp = leshan.discover(endpoint, '3/0/7') + expected_keys = ['/3/0/7', '/3/0/7/0', '/3/0/7/1'] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 + assert len(resp) == len(expected_keys) + +def verify_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource") + resp = leshan.discover(endpoint, '3/0/11') + logger.debug(resp) + expected_keys = ['/3/0/11', '/3/0/11/0'] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 + assert len(resp) == len(expected_keys) + assert int(resp['/3/0/11']['dim']) == 1 + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=10')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=200')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/attributes?pmax=320')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?pmax=100')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?epmin=1')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?epmax=20')['status'] == 'CHANGED(204)' + resp = leshan.discover(endpoint, '3/0/11') + logger.debug(resp) + assert int(resp['/3/0/11']['pmin']) == 10 + assert int(resp['/3/0/11']['pmax']) == 320 + assert int(resp['/3/0/11/0']['pmax']) == 100 + assert int(resp['/3/0/11/0']['epmin']) == 1 + assert int(resp['/3/0/11/0']['epmax']) == 20 + +def verify_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-280 - Successful Read-Composite Operation") + resp = leshan.composite_read(endpoint, ['/3/0/16', '/3/0/11/0', '/1/0']) + logger.debug(resp) + assert len(resp) == 2 + assert len(resp[3]) == 1 + assert len(resp[3][0]) == 2 # No extra resources + assert resp[3][0][11][0] == 0 + assert resp[3][0][16] == 'U' + assert resp[1][0][0] == 1 + assert resp[1][0][1] == 86400 + assert resp[1][0][6] is False + assert resp[1][0][7] == 'U' + +def verify_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str): + logger.info("LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation") + resp = leshan.composite_read(endpoint, ['/1/0/1', '/1/0/7', '/1/0/8']) + assert len(resp) == 1 + assert len(resp[1][0]) == 2 # /1/0/8 should not be there + assert resp[1][0][1] == 86400 + assert resp[1][0][7] == 'U' + def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): logger.info("LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode") lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) @@ -354,11 +565,15 @@ def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): try: # Generate randon device id and password (PSK key) endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() + bs_passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) + logger.debug('Endpoint: %s', endpoint) + logger.debug('Boostrap PSK: %s', binascii.b2a_hex(bs_passwd.encode()).decode()) + logger.debug('PSK: %s', binascii.b2a_hex(passwd.encode()).decode()) # Create device entries in Leshan and Bootstrap server - leshan_bootstrap.create_bs_device(endpoint, f'coaps://{LESHAN_IP}:{COAPS_PORT}', passwd) + leshan_bootstrap.create_bs_device(endpoint, f'coaps://{LESHAN_IP}:{COAPS_PORT}', bs_passwd, passwd) leshan.create_psk_device(endpoint, passwd) # Allow engine to start & stop once. @@ -373,7 +588,7 @@ def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): shell.exec_command('lwm2m write 0/0/1 -b 1') shell.exec_command('lwm2m write 0/0/2 -u8 0') shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') - shell.exec_command(f'lwm2m write 0/0/5 -s {passwd}') + shell.exec_command(f'lwm2m write 0/0/5 -s {bs_passwd}') shell.exec_command(f'lwm2m start {endpoint} -b 1') @@ -403,6 +618,30 @@ def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): verify_LightweightM2M_1_1_int_211(shell, leshan, endpoint) verify_LightweightM2M_1_1_int_212(shell, leshan, endpoint) verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_220(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_221(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_222(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_223(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_224(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_225(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_226(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_227(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_228(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_229(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_230(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_231(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_232(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_233(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_234(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_236(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_237(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_241(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_256(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_257(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_260(shell, leshan, endpoint) + # skip, not supported in Leshan, verify_LightweightM2M_1_1_int_261(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_280(shell, leshan, endpoint) + verify_LightweightM2M_1_1_int_281(shell, leshan, endpoint) shell.exec_command('lwm2m stop') shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) @@ -413,7 +652,6 @@ def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): leshan.delete_device(endpoint) leshan_bootstrap.delete_bs_device(endpoint) - def test_lwm2m_nosecure(shell: Shell, leshan, helperclient): # Allow engine to start & stop once. @@ -438,9 +676,6 @@ def test_lwm2m_nosecure(shell: Shell, leshan, helperclient): verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) verify_LightweightM2M_1_1_int_105(shell, leshan, endpoint, helperclient) # needs no-security - verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_220(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_221(shell, leshan, endpoint) # All done shell.exec_command('lwm2m stop') From 944ad183dc2402c6ee74e9af6f3e5f0a1ea01a55 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 26 Oct 2023 13:13:42 +0300 Subject: [PATCH 3171/4498] tests: lwm2m: Implement event stream support for Leshan Implement support for reading stream of events from Leshan. This allows testing the LwM2M SEND/Notify/Update operations and reading content of those. Also convert the whole Leshan class to use requests.session() so it pools up connections and uses keep-alive. Signed-off-by: Seppo Takalo --- tests/net/lib/lwm2m/interop/pytest/leshan.py | 138 +++++++++++++------ 1 file changed, 95 insertions(+), 43 deletions(-) diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index ecd14b2481c..307a390bf9b 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -8,6 +8,8 @@ import binascii import requests from datetime import datetime +import time +from contextlib import contextmanager class Leshan: def __init__(self, url: str): @@ -15,6 +17,7 @@ def __init__(self, url: str): self.timeout = 10 #self.format = 'TLV' self.format = "SENML_CBOR" + self._s = requests.Session() try: resp = self.get('/security/clients') if not isinstance(resp, list): @@ -41,19 +44,18 @@ def handle_response(resp: requests.models.Response): if len(resp.text): obj = json.loads(resp.text) return obj - else: - return None + return None def get(self, path: str): """Send HTTP GET query""" params = {'timeout': self.timeout} if self.format is not None: params['format'] = self.format - resp = requests.get(f'{self.api_url}{path}', params=params, timeout=self.timeout) + resp = self._s.get(f'{self.api_url}{path}', params=params, timeout=self.timeout) return Leshan.handle_response(resp) def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): - resp = requests.put(f'{self.api_url}{path}', data=data, headers=headers, timeout=self.timeout) + resp = self._s.put(f'{self.api_url}{path}', data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) def put(self, path: str, data: str | dict, uri_options: str = ''): @@ -70,11 +72,11 @@ def post(self, path: str, data: str | dict | None = None): else: headers=None uri_options = '' - resp = requests.post(f'{self.api_url}{path}' + uri_options, data=data, headers=headers, timeout=self.timeout) + resp = self._s.post(f'{self.api_url}{path}' + uri_options, data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) def delete(self, path: str): - resp = requests.delete(f'{self.api_url}{path}', timeout=self.timeout) + resp = self._s.delete(f'{self.api_url}{path}', timeout=self.timeout) return Leshan.handle_response(resp) def execute(self, endpoint: str, path: str): @@ -127,7 +129,8 @@ def _convert_type(cls, value): else: return value - def _define_obj_inst(self, path: str, resources: dict): + @classmethod + def _define_obj_inst(cls, path: str, resources: dict): data = { "kind": "instance", "id": int(path.split('/')[-1]), # ID is last element of path @@ -138,65 +141,70 @@ def _define_obj_inst(self, path: str, resources: dict): kind = 'multiResource' else: kind = 'singleResource' - data['resources'].append(self._define_resource(key, value, kind)) + data['resources'].append(cls._define_resource(key, value, kind)) return data - def _define_resource(self, rid, value, kind='singleResource'): + @classmethod + def _define_resource(cls, rid, value, kind='singleResource'): if kind in ('singleResource', 'resourceInstance'): return { "id": rid, "kind": kind, - "value": self._convert_type(value), - "type": self._type_to_string(value) + "value": cls._convert_type(value), + "type": cls._type_to_string(value) } if kind == 'multiResource': return { "id": rid, "kind": kind, "values": value, - "type": self._type_to_string(list(value.values())[0]) + "type": cls._type_to_string(list(value.values())[0]) } raise RuntimeError(f'Unhandled type {kind}') - def _decode_value(self, type, value): + @classmethod + def _decode_value(cls, val_type: str, value: str): """ Decode the Leshan representation of a value back to a Python value. """ - if type == 'BOOLEAN': + if val_type == 'BOOLEAN': return bool(value) - if type == 'INTEGER': + if val_type == 'INTEGER': return int(value) return value - def _decode_resource(self, content): + @classmethod + def _decode_resource(cls, content: dict): """ Decode the Leshan representation of a resource back to a Python dictionary. """ if content['kind'] == 'singleResource' or content['kind'] == 'resourceInstance': - return {content['id']: self._decode_value(content['type'], content['value'])} + return {content['id']: cls._decode_value(content['type'], content['value'])} elif content['kind'] == 'multiResource': values = {} for riid, value in content['values'].items(): - values.update({int(riid): self._decode_value(content['type'], value)}) + values.update({int(riid): cls._decode_value(content['type'], value)}) return {content['id']: values} raise RuntimeError(f'Unhandled type {content["kind"]}') - def _decode_obj_inst(self, content): + @classmethod + def _decode_obj_inst(cls, content): """ Decode the Leshan representation of an object instance back to a Python dictionary. """ resources = {} for resource in content['resources']: - resources.update(self._decode_resource(resource)) + resources.update(cls._decode_resource(resource)) return {content['id']: resources} - def _decode_obj(self, content): + @classmethod + def _decode_obj(cls, content): """ Decode the Leshan representation of an object back to a Python dictionary. """ instances = {} for instance in content['instances']: - instances.update(self._decode_obj_inst(instance)) + instances.update(cls._decode_obj_inst(instance)) return {content['id']: instances} def read(self, endpoint: str, path: str): @@ -214,33 +222,23 @@ def read(self, endpoint: str, path: str): return self._decode_resource(content) raise RuntimeError(f'Unhandled type {content["kind"]}') - def composite_read(self, endpoint: str, paths: list[str]): - paths = [path if path.startswith('/') else '/' + path for path in paths] - parameters = { - 'pathformat': self.format, - 'nodeformat': self.format, - 'timeout': self.timeout, - 'paths': ','.join(paths) - } - resp = requests.get(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, timeout=self.timeout) - payload = Leshan.handle_response(resp) - if not payload['status'] == 'CONTENT(205)': - raise RuntimeError(f'No content received') + @classmethod + def parse_composite(cls, content: dict): data = {} - for path, content in payload['content'].items(): + for path, content in content.items(): keys = [int(key) for key in path.lstrip("/").split('/')] if len(keys) == 1: - data.update(self._decode_obj(content)) + data.update(cls._decode_obj(content)) elif len(keys) == 2: if keys[0] not in data: data[keys[0]] = {} - data[keys[0]].update(self._decode_obj_inst(content)) + data[keys[0]].update(cls._decode_obj_inst(content)) elif len(keys) == 3: if keys[0] not in data: data[keys[0]] = {} if keys[1] not in data[keys[0]]: data[keys[0]][keys[1]] = {} - data[keys[0]][keys[1]].update(self._decode_resource(content)) + data[keys[0]][keys[1]].update(cls._decode_resource(content)) elif len(keys) == 4: if keys[0] not in data: data[keys[0]] = {} @@ -248,13 +246,24 @@ def composite_read(self, endpoint: str, paths: list[str]): data[keys[0]][keys[1]] = {} if keys[2] not in data[keys[0]][keys[1]]: data[keys[0]][keys[1]][keys[2]] = {} - data[keys[0]][keys[1]][keys[2]].update(self._decode_resource(content)) + data[keys[0]][keys[1]][keys[2]].update(cls._decode_resource(content)) else: raise RuntimeError(f'Unhandled path {path}') - print(f'Requested paths: {paths}') - print(data) return data + def composite_read(self, endpoint: str, paths: list[str]): + paths = [path if path.startswith('/') else '/' + path for path in paths] + parameters = { + 'pathformat': self.format, + 'nodeformat': self.format, + 'timeout': self.timeout, + 'paths': ','.join(paths) + } + resp = self._s.get(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, timeout=self.timeout) + payload = Leshan.handle_response(resp) + if not payload['status'] == 'CONTENT(205)': + raise RuntimeError(f'No content received') + return self.parse_composite(payload['content']) def composite_write(self, endpoint: str, resources: dict): """ @@ -295,11 +304,11 @@ def composite_write(self, endpoint: str, resources: dict): raise RuntimeError(f'Unhandled path {path}') data[path] = value - resp = requests.put(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, json=data, timeout=self.timeout) + resp = self._s.put(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, json=data, timeout=self.timeout) return Leshan.handle_response(resp) def discover(self, endpoint: str, path: str): - resp = self.handle_response(requests.get(f'{self.api_url}/clients/{endpoint}/{path}/discover', timeout=self.timeout)) + resp = self.handle_response(self._s.get(f'{self.api_url}/clients/{endpoint}/{path}/discover', timeout=self.timeout)) data = {} for obj in resp['objectLinks']: data[obj['url']] = obj['attributes'] @@ -324,3 +333,46 @@ def create_bs_device(self, endpoint: str, server_uri: str, bs_passwd: str, passw def delete_bs_device(self, endpoint: str): self.delete(f'/security/clients/{endpoint}') self.delete(f'/bootstrap/{endpoint}') + + @contextmanager + def get_event_stream(self, endpoint: str): + """ + Get stream of events regarding the given endpoint. + + Events are notifications, updates and sends. + + The event stream must be closed after the use, so this must be used in 'with' statement like this: + with leshan.get_event_stream('native_posix') as events: + data = events.next_event('SEND') + + If timeout happens, the event streams returns None. + """ + r = self._s.get(f'{self.api_url}/event?{endpoint}', stream=True, headers={'Accept': 'text/event-stream'}, timeout=self.timeout) + if r.encoding is None: + r.encoding = 'utf-8' + try: + yield LeshanEventsIterator(r, self.timeout) + finally: + r.close() + +class LeshanEventsIterator: + def __init__(self, req: requests.Response, timeout: int): + self._it = req.iter_lines(chunk_size=1, decode_unicode=True) + self._timeout = timeout + + def next_event(self, event: str): + timeout = time.time() + self._timeout + try: + for line in self._it: + if line == f'event: {event}': + for line in self._it: + if not line.startswith('data: '): + continue + data = json.loads(line.lstrip('data: ')) + if event == 'SEND': + return Leshan.parse_composite(data['val']) + return data + if time.time() > timeout: + return None + except requests.exceptions.Timeout: + return None From 86efc9f1c31feb48de17783f5d5e0d3bc2f76f30 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 30 Oct 2023 15:25:33 +0200 Subject: [PATCH 3172/4498] tests: lwm2m: Refactor to use module scoped DUT When testcases share one DUT per module, we save the time from running bootstrap on each testcase. Each testcase start with DUT that is registered. Signed-off-by: Seppo Takalo --- .../net/lib/lwm2m/interop/pytest/conftest.py | 148 +++++++ tests/net/lib/lwm2m/interop/pytest/leshan.py | 63 ++- .../lwm2m/interop/pytest/test_bootstrap.py | 58 +++ .../lib/lwm2m/interop/pytest/test_lwm2m.py | 405 +++++------------- .../lib/lwm2m/interop/pytest/test_nosec.py | 53 +++ tests/net/lib/lwm2m/interop/testcase.yaml | 2 + 6 files changed, 421 insertions(+), 308 deletions(-) create mode 100644 tests/net/lib/lwm2m/interop/pytest/conftest.py create mode 100644 tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py create mode 100644 tests/net/lib/lwm2m/interop/pytest/test_nosec.py diff --git a/tests/net/lib/lwm2m/interop/pytest/conftest.py b/tests/net/lib/lwm2m/interop/pytest/conftest.py new file mode 100644 index 00000000000..9ca971b85c7 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/conftest.py @@ -0,0 +1,148 @@ +""" +Common test fixtures +#################### + +Copyright (c) 2023 Nordic Semiconductor ASA + +SPDX-License-Identifier: Apache-2.0 + +""" + +import time +import logging +import os +import binascii +import random +import string +import pytest +from leshan import Leshan + +from twister_harness import Shell +from twister_harness import DeviceAdapter + +LESHAN_IP: str = '192.0.2.2' +COAP_PORT: int = 5683 +COAPS_PORT: int = 5684 +BOOTSTRAP_COAPS_PORT: int = 5784 + +logger = logging.getLogger(__name__) + +@pytest.fixture(scope='session') +def leshan() -> Leshan: + """ + Fixture that returns a Leshan object for interacting with the Leshan server. + + :return: The Leshan object. + :rtype: Leshan + """ + try: + return Leshan("http://localhost:8080/api") + except RuntimeError: + pytest.skip('Leshan server not available') + +@pytest.fixture(scope='session') +def leshan_bootstrap() -> Leshan: + """ + Fixture that returns a Leshan object for interacting with the Bootstrap Leshan server. + + :return: The Leshan object. + :rtype: Leshan + """ + try: + return Leshan("http://localhost:8081/api") + except RuntimeError: + pytest.skip('Leshan Bootstrap server not available') + +@pytest.fixture(scope='module') +def helperclient() -> object: + """ + Fixture that returns a helper client object for testing. + + :return: The helper client object. + :rtype: object + """ + try: + from coapthon.client.helperclient import HelperClient + except ModuleNotFoundError: + pytest.skip('CoAPthon3 package not installed') + return HelperClient(server=('127.0.0.1', COAP_PORT)) + + +@pytest.fixture(scope='module') +def endpoint_nosec(shell: Shell, dut: DeviceAdapter, leshan: Leshan) -> str: + """Fixture that returns an endpoint that starts on no-secure mode""" + # Allow engine to start & stop once. + time.sleep(2) + + # Generate randon device id and password (PSK key) + ep = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() + + # + # Registration Interface test cases (using Non-secure mode) + # + shell.exec_command(f'lwm2m write 0/0/0 -s coap://{LESHAN_IP}:{COAP_PORT}') + shell.exec_command('lwm2m write 0/0/1 -b 0') + shell.exec_command('lwm2m write 0/0/2 -u8 3') + shell.exec_command(f'lwm2m write 0/0/3 -s {ep}') + shell.exec_command('lwm2m create 1/0') + shell.exec_command('lwm2m write 0/0/10 -u16 1') + shell.exec_command('lwm2m write 1/0/0 -u16 1') + shell.exec_command('lwm2m write 1/0/1 -u32 86400') + shell.exec_command(f'lwm2m start {ep} -b 0') + dut.readlines_until(regex=f"RD Client started with endpoint '{ep}'", timeout=10.0) + + yield ep + + # All done + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=10.0) + +@pytest.fixture(scope='module') +def endpoint_bootstrap(shell: Shell, dut: DeviceAdapter, leshan: Leshan, leshan_bootstrap: Leshan) -> str: + """Fixture that returns an endpoint that starts the bootstrap.""" + try: + # Generate randon device id and password (PSK key) + ep = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() + bs_passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) + passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) + + logger.debug('Endpoint: %s', ep) + logger.debug('Boostrap PSK: %s', binascii.b2a_hex(bs_passwd.encode()).decode()) + logger.debug('PSK: %s', binascii.b2a_hex(passwd.encode()).decode()) + + # Create device entries in Leshan and Bootstrap server + leshan_bootstrap.create_bs_device(ep, f'coaps://{LESHAN_IP}:{COAPS_PORT}', bs_passwd, passwd) + leshan.create_psk_device(ep, passwd) + + # Allow engine to start & stop once. + time.sleep(2) + + # Write bootsrap server information and PSK keys + shell.exec_command(f'lwm2m write 0/0/0 -s coaps://{LESHAN_IP}:{BOOTSTRAP_COAPS_PORT}') + shell.exec_command('lwm2m write 0/0/1 -b 1') + shell.exec_command('lwm2m write 0/0/2 -u8 0') + shell.exec_command(f'lwm2m write 0/0/3 -s {ep}') + shell.exec_command(f'lwm2m write 0/0/5 -s {bs_passwd}') + shell.exec_command(f'lwm2m start {ep} -b 1') + + yield ep + + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=10.0) + + finally: + # Remove device and bootstrap information + # Leshan does not accept non-secure connection if device information is provided with PSK + leshan.delete_device(ep) + leshan_bootstrap.delete_bs_device(ep) + +@pytest.fixture(scope='module') +def endpoint_registered(endpoint_bootstrap, shell: Shell, dut: DeviceAdapter) -> str: + """Fixture that returns an endpoint that is registered.""" + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + return endpoint_bootstrap + +@pytest.fixture(scope='module') +def endpoint(endpoint_registered) -> str: + """Fixture that returns an endpoint that is registered.""" + return endpoint_registered diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index 307a390bf9b..88030139d97 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -1,6 +1,12 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 +""" +REST client for Leshan demo server +################################## + +Copyright (c) 2023 Nordic Semiconductor ASA + +SPDX-License-Identifier: Apache-2.0 + +""" from __future__ import annotations @@ -12,7 +18,9 @@ from contextlib import contextmanager class Leshan: + """This class represents a Leshan client that interacts with demo server's REAT API""" def __init__(self, url: str): + """Initialize Leshan client and check if server is available""" self.api_url = url self.timeout = 10 #self.format = 'TLV' @@ -22,8 +30,8 @@ def __init__(self, url: str): resp = self.get('/security/clients') if not isinstance(resp, list): raise RuntimeError('Did not receive list of endpoints') - except requests.exceptions.ConnectionError: - raise RuntimeError('Leshan not responding') + except requests.exceptions.ConnectionError as exc: + raise RuntimeError('Leshan not responding') from exc @staticmethod def handle_response(resp: requests.models.Response): @@ -47,7 +55,7 @@ def handle_response(resp: requests.models.Response): return None def get(self, path: str): - """Send HTTP GET query""" + """Send HTTP GET query with typical parameters""" params = {'timeout': self.timeout} if self.format is not None: params['format'] = self.format @@ -55,15 +63,18 @@ def get(self, path: str): return Leshan.handle_response(resp) def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): + """Send HTTP PUT query without any default parameters""" resp = self._s.put(f'{self.api_url}{path}', data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) def put(self, path: str, data: str | dict, uri_options: str = ''): + """Send HTTP PUT query with typical parameters""" if isinstance(data, dict): data = json.dumps(data) return self.put_raw(f'{path}?timeout={self.timeout}&format={self.format}' + uri_options, data=data, headers={'content-type': 'application/json'}) def post(self, path: str, data: str | dict | None = None): + """Send HTTP POST query""" if isinstance(data, dict): data = json.dumps(data) if data is not None: @@ -76,13 +87,16 @@ def post(self, path: str, data: str | dict | None = None): return Leshan.handle_response(resp) def delete(self, path: str): + """Send HTTP DELETE query""" resp = self._s.delete(f'{self.api_url}{path}', timeout=self.timeout) return Leshan.handle_response(resp) def execute(self, endpoint: str, path: str): + """Send LwM2M EXECUTE command""" return self.post(f'/clients/{endpoint}/{path}') def write(self, endpoint: str, path: str, value: bool | int | str): + """Send LwM2M WRITE command to a single resource or resource instance""" if len(path.split('/')) == 3: kind = 'singleResource' else: @@ -91,14 +105,17 @@ def write(self, endpoint: str, path: str, value: bool | int | str): return self.put(f'/clients/{endpoint}/{path}', self._define_resource(rid, value, kind)) def update_obj_instance(self, endpoint: str, path: str, resources: dict): + """Update object instance""" data = self._define_obj_inst(path, resources) return self.put(f'/clients/{endpoint}/{path}', data, uri_options='&replace=false') def replace_obj_instance(self, endpoint: str, path: str, resources: dict): + """Replace object instance""" data = self._define_obj_inst(path, resources) return self.put(f'/clients/{endpoint}/{path}', data, uri_options='&replace=true') def create_obj_instance(self, endpoint: str, path: str, resources: dict): + """Send LwM2M CREATE command""" data = self._define_obj_inst(path, resources) path = '/'.join(path.split('/')[:-1]) # Create call should not have instance ID in path return self.post(f'/clients/{endpoint}/{path}', data) @@ -124,6 +141,7 @@ def _type_to_string(cls, value): @classmethod def _convert_type(cls, value): + """Wrapper for special types that are not understood by Json""" if isinstance(value, datetime): return int(value.timestamp()) else: @@ -131,6 +149,7 @@ def _convert_type(cls, value): @classmethod def _define_obj_inst(cls, path: str, resources: dict): + """Define an object instance for Leshan""" data = { "kind": "instance", "id": int(path.split('/')[-1]), # ID is last element of path @@ -146,6 +165,7 @@ def _define_obj_inst(cls, path: str, resources: dict): @classmethod def _define_resource(cls, rid, value, kind='singleResource'): + """Define a resource for Leshan""" if kind in ('singleResource', 'resourceInstance'): return { "id": rid, @@ -208,6 +228,7 @@ def _decode_obj(cls, content): return {content['id']: instances} def read(self, endpoint: str, path: str): + """Send LwM2M READ command and decode the response to a Python dictionary""" resp = self.get(f'/clients/{endpoint}/{path}') if not resp['success']: return resp @@ -223,9 +244,10 @@ def read(self, endpoint: str, path: str): raise RuntimeError(f'Unhandled type {content["kind"]}') @classmethod - def parse_composite(cls, content: dict): + def parse_composite(cls, payload: dict): + """Decode the Leshan's response to composite query back to a Python dictionary""" data = {} - for path, content in content.items(): + for path, content in payload.items(): keys = [int(key) for key in path.lstrip("/").split('/')] if len(keys) == 1: data.update(cls._decode_obj(content)) @@ -251,14 +273,22 @@ def parse_composite(cls, content: dict): raise RuntimeError(f'Unhandled path {path}') return data - def composite_read(self, endpoint: str, paths: list[str]): - paths = [path if path.startswith('/') else '/' + path for path in paths] + def _composite_params(self, paths: list[str] | None = None): + """Common URI parameters for composite query""" parameters = { 'pathformat': self.format, 'nodeformat': self.format, - 'timeout': self.timeout, - 'paths': ','.join(paths) + 'timeout': self.timeout } + if paths is not None: + paths = [path if path.startswith('/') else '/' + path for path in paths] + parameters['paths'] = ','.join(paths) + + return parameters + + def composite_read(self, endpoint: str, paths: list[str]): + """Send LwM2M Composite-Read command and decode the response to a Python dictionary""" + parameters = self._composite_params(paths) resp = self._s.get(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, timeout=self.timeout) payload = Leshan.handle_response(resp) if not payload['status'] == 'CONTENT(205)': @@ -267,7 +297,7 @@ def composite_read(self, endpoint: str, paths: list[str]): def composite_write(self, endpoint: str, resources: dict): """ - Do LwM2m composite write operation. + Send LwM2m Composite-Write operation. Targeted resources are defined as a dictionary with the following structure: { @@ -356,11 +386,18 @@ def get_event_stream(self, endpoint: str): r.close() class LeshanEventsIterator: + """Iterator for Leshan event stream""" def __init__(self, req: requests.Response, timeout: int): + """Initialize the iterator in line mode""" self._it = req.iter_lines(chunk_size=1, decode_unicode=True) self._timeout = timeout def next_event(self, event: str): + """ + Finds the next occurrence of a specific event in the stream. + + If timeout happens, the returns None. + """ timeout = time.time() + self._timeout try: for line in self._it: diff --git a/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py new file mode 100644 index 00000000000..65561db0676 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py @@ -0,0 +1,58 @@ +""" +LwM2M Bootstrap interface tests +############################### + +Copyright (c) 2023 Nordic Semiconductor ASA + +SPDX-License-Identifier: Apache-2.0 + +Test specification: +=================== +https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf + + +This module contains only testcases that verify the bootstrap. +""" + +import logging +from leshan import Leshan +from twister_harness import Shell +from twister_harness import DeviceAdapter + +logger = logging.getLogger(__name__) + + +# +# Test specification: +# https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf +# +# Bootstrap Interface: [0-99] +# + +def verify_LightweightM2M_1_1_int_0(shell: Shell, dut: DeviceAdapter): + """LightweightM2M-1.1-int-0 - Client Initiated Bootstrap""" + dut.readlines_until(regex='.*Bootstrap started with endpoint', timeout=5.0) + dut.readlines_until(regex='.*Bootstrap registration done', timeout=5.0) + dut.readlines_until(regex='.*Bootstrap data transfer done', timeout=5.0) + +def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: str): + """LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)""" + verify_LightweightM2M_1_1_int_0(shell, dut) + verify_LightweightM2M_1_1_int_101(shell, dut, leshan, endpoint_bootstrap) + verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint_bootstrap) + +def verify_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-101 - Initial Registration""" + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert leshan.get(f'/clients/{endpoint}') + +def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode""" + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) + host = lines[0] + assert 'coaps://' in host + lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/2 -u8')) + mode = int(lines[0]) + assert mode == 0 + resp = leshan.get(f'/clients/{endpoint}') + assert resp["secure"] diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index 384e3cadda5..bdeb8783847 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -1,136 +1,81 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 +""" +Various LwM2M interoperability tests +#################################### + +Copyright (c) 2023 Nordic Semiconductor ASA + +SPDX-License-Identifier: Apache-2.0 + +Test specification: +=================== +https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf + + +This module contains testcases for + * Registration Interface [100-199] + * Device management & Service Enablement Interface [200-299] + * Information Reporting Interface [300-399] + +""" import time import logging +from datetime import datetime import pytest from leshan import Leshan -import os -import binascii -import random -import string from twister_harness import Shell -from datetime import datetime - -LESHAN_IP: str = '192.0.2.2' -COAP_PORT: int = 5683 -COAPS_PORT: int = 5684 -BOOTSTRAP_COAPS_PORT: int = 5784 +from twister_harness import DeviceAdapter logger = logging.getLogger(__name__) -@pytest.fixture(scope='module') -def helperclient() -> object: - try: - from coapthon.client.helperclient import HelperClient - except ModuleNotFoundError: - pytest.skip('CoAPthon3 package not installed') - return HelperClient(server=('127.0.0.1', COAP_PORT)) - -@pytest.fixture(scope='session') -def leshan() -> Leshan: - try: - return Leshan("http://localhost:8080/api") - except RuntimeError: - pytest.skip('Leshan server not available') - -@pytest.fixture(scope='session') -def leshan_bootstrap() -> Leshan: - try: - return Leshan("http://localhost:8081/api") - except RuntimeError: - pytest.skip('Leshan Bootstrap server not available') - -# -# Test specification: -# https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf -# - -def verify_LightweightM2M_1_1_int_0(shell: Shell): - logger.info("LightweightM2M-1.1-int-0 - Client Initiated Bootstrap") - shell._device.readlines_until(regex='.*Bootstrap started with endpoint', timeout=5.0) - shell._device.readlines_until(regex='.*Bootstrap registration done', timeout=5.0) - shell._device.readlines_until(regex='.*Bootstrap data transfer done', timeout=5.0) - -def verify_LightweightM2M_1_1_int_1(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)") - verify_LightweightM2M_1_1_int_0(shell) - verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint) - -def verify_LightweightM2M_1_1_int_101(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-101 - Initial Registration") - shell._device.readlines_until(regex='.*Registration Done', timeout=5.0) - assert leshan.get(f'/clients/{endpoint}') -def verify_LightweightM2M_1_1_int_102(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-102 - Registration Update") +def test_LightweightM2M_1_1_int_102(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-102 - Registration Update""" lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) lifetime = int(lines[0]) lifetime = lifetime + 10 start_time = time.time() * 1000 leshan.write(endpoint, '1/0/1', lifetime) - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) latest = leshan.get(f'/clients/{endpoint}') assert latest["lastUpdate"] > start_time assert latest["lastUpdate"] <= time.time()*1000 assert latest["lifetime"] == lifetime shell.exec_command('lwm2m write 1/0/1 -u32 86400') -def verify_LightweightM2M_1_1_int_103(): - """LightweightM2M-1.1-int-103 - Deregistration""" - # Unsupported. We don't have "disabled" functionality in server object - -def verify_LightweightM2M_1_1_int_104(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-104 - Registration Update Trigger") +def test_LightweightM2M_1_1_int_104(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-104 - Registration Update Trigger""" shell.exec_command('lwm2m update') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) leshan.execute(endpoint, '1/0/8') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - -def verify_LightweightM2M_1_1_int_105(shell: Shell, leshan: Leshan, endpoint: str, helperclient: object): - logger.info("LightweightM2M-1.1-int-105 - Discarded Register Update") - status = leshan.get(f'/clients/{endpoint}') - if status["secure"]: - logger.debug("Skip, requires non-secure connection") - return - regid = status["registrationId"] - assert regid - # Fake unregister message - helperclient.delete(f'rd/{regid}', timeout=0.1) - helperclient.stop() - time.sleep(1) - shell.exec_command('lwm2m update') - shell._device.readlines_until(regex=r'.*Failed with code 4\.4', timeout=5.0) - shell._device.readlines_until(regex='.*Registration Done', timeout=10.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) -def verify_LightweightM2M_1_1_int_107(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-107 - Extending the lifetime of a registration") +def test_LightweightM2M_1_1_int_107(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-107 - Extending the lifetime of a registration""" leshan.write(endpoint, '1/0/1', 120) - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) lifetime = int(lines[0]) assert lifetime == 120 logger.debug(f'Wait for update, max {lifetime} s') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=lifetime) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=lifetime) assert leshan.get(f'/clients/{endpoint}') -def verify_LightweightM2M_1_1_int_108(leshan, endpoint): - logger.info("LightweightM2M-1.1-int-108 - Turn on Queue Mode") +def test_LightweightM2M_1_1_int_108(leshan, endpoint): + """LightweightM2M-1.1-int-108 - Turn on Queue Mode""" assert leshan.get(f'/clients/{endpoint}')["queuemode"] -def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-109 - Behavior in Queue Mode") +def test_LightweightM2M_1_1_int_109(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-109 - Behavior in Queue Mode""" logger.debug('Wait for Queue RX OFF') - shell._device.readlines_until(regex='.*Queue mode RX window closed', timeout=120) + dut.readlines_until(regex='.*Queue mode RX window closed', timeout=120) # Restore previous value shell.exec_command('lwm2m write 1/0/1 -u32 86400') - shell._device.readlines_until(regex='.*Registration update complete', timeout=10) + dut.readlines_until(regex='.*Registration update complete', timeout=10) -def verify_LightweightM2M_1_1_int_201(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-201 - Querying basic information in Plain Text format") +def test_LightweightM2M_1_1_int_201(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-201 - Querying basic information in Plain Text format""" fmt = leshan.format leshan.format = 'TEXT' assert leshan.read(endpoint, '3/0/0') == 'Zephyr' @@ -157,26 +102,24 @@ def verify_server_object(obj): assert obj[0][6] is False assert obj[0][7] == 'U' -def verify_LightweightM2M_1_1_int_203(shell: Shell, leshan: Leshan, endpoint: str): - shell.exec_command('lwm2m update') - logger.info('LightweightM2M-1.1-int-203 - Querying basic information in TLV format') +def test_LightweightM2M_1_1_int_203(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-203 - Querying basic information in TLV format""" fmt = leshan.format leshan.format = 'TLV' resp = leshan.read(endpoint,'3/0') verify_device_object(resp) leshan.format = fmt -def verify_LightweightM2M_1_1_int_204(shell: Shell, leshan: Leshan, endpoint: str): - shell.exec_command('lwm2m update') - logger.info('LightweightM2M-1.1-int-204 - Querying basic information in JSON format') +def test_LightweightM2M_1_1_int_204(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-204 - Querying basic information in JSON format""" fmt = leshan.format leshan.format = 'JSON' resp = leshan.read(endpoint, '3/0') verify_device_object(resp) leshan.format = fmt -def verify_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-205 - Setting basic information in Plain Text format') +def test_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-205 - Setting basic information in Plain Text format""" fmt = leshan.format leshan.format = 'TEXT' leshan.write(endpoint, '1/0/2', 101) @@ -193,8 +136,8 @@ def verify_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: st assert leshan.read(endpoint, '1/0/5') == 86400 leshan.format = fmt -def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-211 - Querying basic information in CBOR format') +def test_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-211 - Querying basic information in CBOR format""" fmt = leshan.format leshan.format = 'CBOR' lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) @@ -204,8 +147,8 @@ def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: st assert leshan.read(endpoint, '1/0/7') == 'U' leshan.format = fmt -def verify_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-212 - Setting basic information in CBOR format') +def test_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-212 - Setting basic information in CBOR format""" fmt = leshan.format leshan.format = 'CBOR' leshan.write(endpoint, '1/0/2', 101) @@ -245,22 +188,22 @@ def verify_setting_basic_in_format(shell, leshan, endpoint, format): verify_server_object(server_obj) leshan.format = fmt -def verify_LightweightM2M_1_1_int_215(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-215 - Setting basic information in TLV format') +def test_LightweightM2M_1_1_int_215(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-215 - Setting basic information in TLV format""" verify_setting_basic_in_format(shell, leshan, endpoint, 'TLV') -def verify_LightweightM2M_1_1_int_220(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-220 - Setting basic information in JSON format') +def test_LightweightM2M_1_1_int_220(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-220 - Setting basic information in JSON format""" verify_setting_basic_in_format(shell, leshan, endpoint, 'JSON') -def verify_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-221 - Attempt to perform operations on Security') +def test_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-221 - Attempt to perform operations on Security""" assert leshan.read(endpoint, '0/0')['status'] == 'UNAUTHORIZED(401)' assert leshan.write(endpoint, '0/0/0', 'coap://localhost')['status'] == 'UNAUTHORIZED(401)' assert leshan.put_raw(f'/clients/{endpoint}/0/attributes?pmin=10')['status'] == 'UNAUTHORIZED(401)' -def verify_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-222 - Read on Object") +def test_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-222 - Read on Object""" resp = leshan.read(endpoint, '1') assert len(resp) == 1 assert len(resp[1][0]) == 9 @@ -270,27 +213,27 @@ def verify_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: st assert len(resp[3][0]) == 15 assert resp[3][0][0] == 'Zephyr' -def verify_LightweightM2M_1_1_int_223(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-223 - Read on Object Instance") +def test_LightweightM2M_1_1_int_223(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-223 - Read on Object Instance""" resp = leshan.read(endpoint, '1/0') assert len(resp[0]) == 9 resp = leshan.read(endpoint, '3/0') assert len(resp[0]) == 15 assert resp[0][0] == 'Zephyr' -def verify_LightweightM2M_1_1_int_224(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-224 - Read on Resource") +def test_LightweightM2M_1_1_int_224(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-224 - Read on Resource""" assert leshan.read(endpoint, '1/0/0') == 1 assert leshan.read(endpoint, '1/0/1') == 86400 assert leshan.read(endpoint, '1/0/6') is False assert leshan.read(endpoint, '1/0/7') == 'U' -def verify_LightweightM2M_1_1_int_225(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-225 - Read on Resource Instance") +def test_LightweightM2M_1_1_int_225(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-225 - Read on Resource Instance""" assert leshan.read(endpoint, '3/0/11/0') == 0 -def verify_LightweightM2M_1_1_int_226(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-226 - Write (Partial Update) on Object Instance") +def test_LightweightM2M_1_1_int_226(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-226 - Write (Partial Update) on Object Instance""" lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) lifetime = int(lines[0]) resources = { @@ -306,29 +249,29 @@ def verify_LightweightM2M_1_1_int_226(shell: Shell, leshan: Leshan, endpoint: st } assert leshan.update_obj_instance(endpoint, '1/0', resources)['status'] == 'CHANGED(204)' -def verify_LightweightM2M_1_1_int_227(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-227 - Write (replace) on Resource") +def test_LightweightM2M_1_1_int_227(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-227 - Write (replace) on Resource""" lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) lifetime = int(lines[0]) assert leshan.write(endpoint, '1/0/1', int(63))['status'] == 'CHANGED(204)' - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) latest = leshan.get(f'/clients/{endpoint}') assert latest["lifetime"] == 63 assert leshan.read(endpoint, '1/0/1') == 63 assert leshan.write(endpoint, '1/0/1', lifetime)['status'] == 'CHANGED(204)' -def verify_LightweightM2M_1_1_int_228(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-228 - Write on Resource Instance") +def test_LightweightM2M_1_1_int_228(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-228 - Write on Resource Instance""" resources = { 0: {0: 'a', 1: 'b'} } assert leshan.create_obj_instance(endpoint, '16/0', resources)['status'] == 'CREATED(201)' - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) assert leshan.write(endpoint, '16/0/0/0', 'test')['status'] == 'CHANGED(204)' assert leshan.read(endpoint, '16/0/0/0') == 'test' -def verify_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-229 - Read-Composite Operation") +def test_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-229 - Read-Composite Operation""" old_fmt = leshan.format for fmt in ['SENML_JSON', 'SENML_CBOR']: leshan.format = fmt @@ -346,8 +289,8 @@ def verify_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: st assert resp[3][0][11][0] is not None leshan.format = old_fmt -def verify_LightweightM2M_1_1_int_230(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-230 - Write-Composite Operation") +def test_LightweightM2M_1_1_int_230(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-230 - Write-Composite Operation""" resources = { "/1/0/1": 60, "/1/0/6": True, @@ -376,6 +319,7 @@ def verify_LightweightM2M_1_1_int_230(shell: Shell, leshan: Leshan, endpoint: st leshan.format = old_fmt def query_basic_in_senml(leshan: Leshan, endpoint: str, fmt: str): + """Querying basic information in one of the SenML formats""" old_fmt = leshan.format leshan.format = fmt verify_server_object(leshan.read(endpoint, '1')[1]) @@ -384,15 +328,16 @@ def query_basic_in_senml(leshan: Leshan, endpoint: str, fmt: str): assert leshan.read(endpoint, '3/0/11/0') == 0 leshan.format = old_fmt -def verify_LightweightM2M_1_1_int_231(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-231 - Querying basic information in SenML JSON format") +def test_LightweightM2M_1_1_int_231(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-231 - Querying basic information in SenML JSON format""" query_basic_in_senml(leshan, endpoint, 'SENML_JSON') -def verify_LightweightM2M_1_1_int_232(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format") +def test_LightweightM2M_1_1_int_232(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format""" query_basic_in_senml(leshan, endpoint, 'SENML_CBOR') def setting_basic_senml(shell: Shell, leshan: Leshan, endpoint: str, fmt: str): + """Setting basic information in one of the SenML formats""" old_fmt = leshan.format leshan.format = fmt resources = { @@ -412,51 +357,51 @@ def setting_basic_senml(shell: Shell, leshan: Leshan, endpoint: str, fmt: str): shell.exec_command('lwm2m write /1/0/6 -u8 0') leshan.format = old_fmt -def verify_LightweightM2M_1_1_int_233(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format") +def test_LightweightM2M_1_1_int_233(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format""" setting_basic_senml(shell, leshan, endpoint, 'SENML_CBOR') -def verify_LightweightM2M_1_1_int_234(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format") +def test_LightweightM2M_1_1_int_234(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format""" setting_basic_senml(shell, leshan, endpoint, 'SENML_JSON') -def verify_LightweightM2M_1_1_int_235(): +@pytest.mark.skip("Leshan does not allow reading root path") +def test_LightweightM2M_1_1_int_235(): """LightweightM2M-1.1-int-235 - Read-Composite Operation on root path""" - # Unsupported. Leshan does not allow this. -def verify_LightweightM2M_1_1_int_236(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence") +def test_LightweightM2M_1_1_int_236(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence""" resp = leshan.composite_read(endpoint, ['1/0', '/3/0/11/0', '/3339/0/5522', '/3353/0/6030']) assert resp[1][0][1] is not None assert resp[3][0][11][0] is not None assert len(resp) == 2 -def verify_LightweightM2M_1_1_int_237(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type") +def test_LightweightM2M_1_1_int_237(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type""" old_fmt = leshan.format leshan.format = None assert leshan.read(endpoint, '1')[1][0][1] is not None assert leshan.read(endpoint, '3')[3][0][0] == 'Zephyr' leshan.format = old_fmt -def verify_LightweightM2M_1_1_int_241(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device") +def test_LightweightM2M_1_1_int_241(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device""" leshan.execute(endpoint, '3/0/4') - shell._device.readlines_until(regex='.*DEVICE: REBOOT', timeout=5.0) - shell._device.readlines_until(regex='.*rd_client_event: Disconnected', timeout=5.0) + dut.readlines_until(regex='.*DEVICE: REBOOT', timeout=5.0) + dut.readlines_until(regex='.*rd_client_event: Disconnected', timeout=5.0) shell.exec_command(f'lwm2m start {endpoint} -b 0') - shell._device.readlines_until(regex='.*Registration Done', timeout=5.0) + dut.readlines_until(regex='.*Registration Done', timeout=5.0) assert leshan.get(f'/clients/{endpoint}') -def verify_LightweightM2M_1_1_int_256(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-256 - Write Operation Failure") +def test_LightweightM2M_1_1_int_256(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-256 - Write Operation Failure""" lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) short_id = int(lines[0]) assert leshan.write(endpoint, '1/0/0', 123)['status'] == 'METHOD_NOT_ALLOWED(405)' assert leshan.read(endpoint, '1/0/0') == short_id -def verify_LightweightM2M_1_1_int_257(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-257 - Write-Composite Operation") +def test_LightweightM2M_1_1_int_257(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-257 - Write-Composite Operation""" resources = { "/1/0/2": 102, "/1/0/6": True, @@ -476,8 +421,8 @@ def verify_LightweightM2M_1_1_int_257(shell: Shell, leshan: Leshan, endpoint: st shell.exec_command('lwm2m write /1/0/2 -u32 1') leshan.format = old_fmt -def verify_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-260 - Discover Command") +def test_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-260 - Discover Command""" resp = leshan.discover(endpoint, '3') expected_keys = ['/3', '/3/0', '/3/0/1', '/3/0/2', '/3/0/3', '/3/0/4', '/3/0/6', '/3/0/7', '/3/0/8', '/3/0/9', '/3/0/11', '/3/0/16'] missing_keys = [key for key in expected_keys if key not in resp.keys()] @@ -505,8 +450,9 @@ def verify_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: st assert len(missing_keys) == 0 assert len(resp) == len(expected_keys) -def verify_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource") +@pytest.mark.skip(reason="Leshan don't allow writing attributes to resource instance") +def test_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource""" resp = leshan.discover(endpoint, '3/0/11') logger.debug(resp) expected_keys = ['/3/0/11', '/3/0/11/0'] @@ -528,8 +474,8 @@ def verify_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: st assert int(resp['/3/0/11/0']['epmin']) == 1 assert int(resp['/3/0/11/0']['epmax']) == 20 -def verify_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-280 - Successful Read-Composite Operation") +def test_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-280 - Successful Read-Composite Operation""" resp = leshan.composite_read(endpoint, ['/3/0/16', '/3/0/11/0', '/1/0']) logger.debug(resp) assert len(resp) == 2 @@ -542,141 +488,10 @@ def verify_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: st assert resp[1][0][6] is False assert resp[1][0][7] == 'U' -def verify_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation") +def test_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation""" resp = leshan.composite_read(endpoint, ['/1/0/1', '/1/0/7', '/1/0/8']) assert len(resp) == 1 assert len(resp[1][0]) == 2 # /1/0/8 should not be there assert resp[1][0][1] == 86400 assert resp[1][0][7] == 'U' - -def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode") - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) - host = lines[0] - assert 'coaps://' in host - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/2 -u8')) - mode = int(lines[0]) - assert mode == 0 - resp = leshan.get(f'/clients/{endpoint}') - assert resp["secure"] - -def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): - try: - # Generate randon device id and password (PSK key) - endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() - bs_passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) - passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) - - logger.debug('Endpoint: %s', endpoint) - logger.debug('Boostrap PSK: %s', binascii.b2a_hex(bs_passwd.encode()).decode()) - logger.debug('PSK: %s', binascii.b2a_hex(passwd.encode()).decode()) - - # Create device entries in Leshan and Bootstrap server - leshan_bootstrap.create_bs_device(endpoint, f'coaps://{LESHAN_IP}:{COAPS_PORT}', bs_passwd, passwd) - leshan.create_psk_device(endpoint, passwd) - - # Allow engine to start & stop once. - time.sleep(2) - - # - # Verify PSK security using Bootstrap - # - - # Write bootsrap server information and PSK keys - shell.exec_command(f'lwm2m write 0/0/0 -s coaps://{LESHAN_IP}:{BOOTSTRAP_COAPS_PORT}') - shell.exec_command('lwm2m write 0/0/1 -b 1') - shell.exec_command('lwm2m write 0/0/2 -u8 0') - shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') - shell.exec_command(f'lwm2m write 0/0/5 -s {bs_passwd}') - shell.exec_command(f'lwm2m start {endpoint} -b 1') - - - # - # Bootstrap Interface test cases - # LightweightM2M-1.1-int-0 (included) - # LightweightM2M-1.1-int-401 (included) - verify_LightweightM2M_1_1_int_1(shell, leshan, endpoint) - - # - # Registration Interface test cases (using PSK security) - # - verify_LightweightM2M_1_1_int_102(shell, leshan, endpoint) - # skip, not implemented verify_LightweightM2M_1_1_int_103() - verify_LightweightM2M_1_1_int_104(shell, leshan, endpoint) - # skip, included in 109: verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_108(leshan, endpoint) - verify_LightweightM2M_1_1_int_109(shell, leshan, endpoint) - - # - # Device management & Service Enablement Interface test cases - # - verify_LightweightM2M_1_1_int_201(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_203(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_204(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_205(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_211(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_212(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_220(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_221(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_222(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_223(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_224(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_225(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_226(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_227(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_228(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_229(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_230(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_231(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_232(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_233(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_234(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_236(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_237(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_241(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_256(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_257(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_260(shell, leshan, endpoint) - # skip, not supported in Leshan, verify_LightweightM2M_1_1_int_261(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_280(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_281(shell, leshan, endpoint) - - shell.exec_command('lwm2m stop') - shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) - - finally: - # Remove device and bootstrap information - # Leshan does not accept non-secure connection if device information is provided with PSK - leshan.delete_device(endpoint) - leshan_bootstrap.delete_bs_device(endpoint) - -def test_lwm2m_nosecure(shell: Shell, leshan, helperclient): - - # Allow engine to start & stop once. - time.sleep(2) - - # Generate randon device id and password (PSK key) - endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() - - # - # Registration Interface test cases (using Non-secure mode) - # - shell.exec_command(f'lwm2m write 0/0/0 -s coap://{LESHAN_IP}:{COAP_PORT}') - shell.exec_command('lwm2m write 0/0/1 -b 0') - shell.exec_command('lwm2m write 0/0/2 -u8 3') - shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') - shell.exec_command('lwm2m create 1/0') - shell.exec_command('lwm2m write 0/0/10 -u16 1') - shell.exec_command('lwm2m write 1/0/0 -u16 1') - shell.exec_command('lwm2m write 1/0/1 -u32 86400') - shell.exec_command(f'lwm2m start {endpoint} -b 0') - shell._device.readlines_until(regex=f"RD Client started with endpoint '{endpoint}'", timeout=10.0) - - verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_105(shell, leshan, endpoint, helperclient) # needs no-security - - # All done - shell.exec_command('lwm2m stop') - shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) diff --git a/tests/net/lib/lwm2m/interop/pytest/test_nosec.py b/tests/net/lib/lwm2m/interop/pytest/test_nosec.py new file mode 100644 index 00000000000..15ac98f2d1a --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/test_nosec.py @@ -0,0 +1,53 @@ +""" +Tests for No-security mode +########################## + +Copyright (c) 2023 Nordic Semiconductor ASA + +SPDX-License-Identifier: Apache-2.0 + +Test specification: +=================== +https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf + + +This module contains only testcases that are able to run on non-secure mode. +""" + +import time +import logging +from leshan import Leshan + +from twister_harness import Shell +from twister_harness import DeviceAdapter + +logger = logging.getLogger(__name__) + +def test_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_nosec: str): + """ + Verify that the client is registered. + Note that this MUST be the first testcase executed, otherwise it will fail to get the + correct log output. + """ + logger.info("LightweightM2M-1.1-int-101 - Initial Registration") + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert leshan.get(f'/clients/{endpoint_nosec}') + +def test_LightweightM2M_1_1_int_105(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_nosec: str, helperclient: object): + """ + Run testcase LightweightM2M-1.1-int-105 - Discarded Register Update + """ + logger.info("LightweightM2M-1.1-int-105 - Discarded Register Update") + status = leshan.get(f'/clients/{endpoint_nosec}') + if status["secure"]: + logger.debug("Skip, requires non-secure connection") + return + regid = status["registrationId"] + assert regid + # Fake unregister message + helperclient.delete(f'rd/{regid}', timeout=0.1) + helperclient.stop() + time.sleep(1) + shell.exec_command('lwm2m update') + dut.readlines_until(regex=r'.*Failed with code 4\.4', timeout=5.0) + dut.readlines_until(regex='.*Registration Done', timeout=10.0) diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml index 93f3fc13b1c..1b9818e777e 100644 --- a/tests/net/lib/lwm2m/interop/testcase.yaml +++ b/tests/net/lib/lwm2m/interop/testcase.yaml @@ -3,6 +3,8 @@ tests: harness: pytest timeout: 300 slow: true + harness_config: + pytest_dut_scope: module integration_platforms: - native_posix platform_allow: From 8608b2dc450df10c5144149fd5e321903e9fb731 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 24 Oct 2023 17:01:55 +0300 Subject: [PATCH 3173/4498] tests: lwm2m: Information Reporting Interface [300-399] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement testcases for Information Reporting Interface [300-399]: * LightweightM2M-1.1-int-301 - Observation and Notification of parameter values * LightweightM2M-1.1-int-302 - Cancel Observations using Reset * LightweightM2M-1.1-int-304 - Observe-Composite Operation * LightweightM2M-1.1-int-306 – Send Operation * LightweightM2M-1.1-int-307 – Muting Send * LightweightM2M-1.1-int-308 - Observe-Composite and Creating Object Instance * LightweightM2M-1.1-int-309 - Observe-Composite and Deleting Object Instance * LightweightM2M-1.1-int-310 - Observe-Composite and modification of parameter values * LightweightM2M-1.1-int-311 - Send command 303 and 305 cannot be implemented using Leshan as it only support passive cancelling of observation. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_shell.c | 7 +- tests/net/lib/lwm2m/interop/README.md | 11 + tests/net/lib/lwm2m/interop/pytest/leshan.py | 59 +++-- .../lib/lwm2m/interop/pytest/test_lwm2m.py | 207 ++++++++++++++++++ tests/net/lib/lwm2m/interop/testcase.yaml | 3 +- 5 files changed, 267 insertions(+), 20 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index 26526611efa..a4807d517f2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -55,6 +55,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "PATH is LwM2M path\n" \ "NUM how many elements to cache\n" \ +static void send_cb(enum lwm2m_send_status status) +{ + LOG_INF("SEND status: %d\n", status); +} + static int cmd_send(const struct shell *sh, size_t argc, char **argv) { int ret = 0; @@ -86,7 +91,7 @@ static int cmd_send(const struct shell *sh, size_t argc, char **argv) } } - ret = lwm2m_send_cb(ctx, lwm2m_path_list, path_cnt, NULL); + ret = lwm2m_send_cb(ctx, lwm2m_path_list, path_cnt, send_cb); if (ret < 0) { shell_error(sh, "can't do send operation, request failed (%d)\n", ret); diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md index 72eb430f8e4..bda38924d26 100644 --- a/tests/net/lib/lwm2m/interop/README.md +++ b/tests/net/lib/lwm2m/interop/README.md @@ -170,6 +170,17 @@ Tests are written from test spec; |LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource|:large_orange_diamond:|Leshan don't allow writing attributes to resource instance| |LightweightM2M-1.1-int-280 - Successful Read-Composite Operation|:white_check_mark:| | |LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-301 - Observation and Notification of parameter values|:white_check_mark:| | +|LightweightM2M-1.1-int-302 - Cancel Observations using Reset Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-303 - Cancel observations using Observe with Cancel parameter|:large_orange_diamond:|Leshan only supports passive cancelling| +|LightweightM2M-1.1-int-304 - Observe-Composite Operation|:white_check_mark:| | +|LightweightM2M-1.1-int-305 - Cancel Observation-Composite Operation|:large_orange_diamond:|Leshan only supports passive cancelling| +|LightweightM2M-1.1-int-306 – Send Operation|:white_check_mark:|[~~#64290~~](https://github.com/zephyrproject-rtos/zephyr/issues/64290)| +|LightweightM2M-1.1-int-307 – Muting Send|:white_check_mark:| | +|LightweightM2M-1.1-int-308 - Observe-Composite and Creating Object Instance|:white_check_mark:|[~~#64634~~](https://github.com/zephyrproject-rtos/zephyr/issues/64634)| +|LightweightM2M-1.1-int-309 - Observe-Composite and Deleting Object Instance|:white_check_mark:|[~~#64634~~](https://github.com/zephyrproject-rtos/zephyr/issues/64634)| +|LightweightM2M-1.1-int-310 - Observe-Composite and modification of parameter values|:white_check_mark:| | +|LightweightM2M-1.1-int-311 - Send command|:white_check_mark:| | |LightweightM2M-1.1-int-401 - UDP Channel Security - PSK Mode |:white_check_mark:| | * :white_check_mark: Working OK. diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index 88030139d97..7240aae2baf 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -12,10 +12,10 @@ import json import binascii -import requests -from datetime import datetime import time +from datetime import datetime from contextlib import contextmanager +import requests class Leshan: """This class represents a Leshan client that interacts with demo server's REAT API""" @@ -86,11 +86,15 @@ def post(self, path: str, data: str | dict | None = None): resp = self._s.post(f'{self.api_url}{path}' + uri_options, data=data, headers=headers, timeout=self.timeout) return Leshan.handle_response(resp) - def delete(self, path: str): + def delete_raw(self, path: str): """Send HTTP DELETE query""" resp = self._s.delete(f'{self.api_url}{path}', timeout=self.timeout) return Leshan.handle_response(resp) + def delete(self, endpoint: str, path: str): + """Send LwM2M DELETE command""" + return self.delete_raw(f'/clients/{endpoint}/{path}') + def execute(self, endpoint: str, path: str): """Send LwM2M EXECUTE command""" return self.post(f'/clients/{endpoint}/{path}') @@ -247,6 +251,10 @@ def read(self, endpoint: str, path: str): def parse_composite(cls, payload: dict): """Decode the Leshan's response to composite query back to a Python dictionary""" data = {} + if 'status' in payload: + if payload['status'] != 'CONTENT(205)' or 'content' not in payload: + raise RuntimeError(f'No content received') + payload = payload['content'] for path, content in payload.items(): keys = [int(key) for key in path.lstrip("/").split('/')] if len(keys) == 1: @@ -291,9 +299,7 @@ def composite_read(self, endpoint: str, paths: list[str]): parameters = self._composite_params(paths) resp = self._s.get(f'{self.api_url}/clients/{endpoint}/composite', params=parameters, timeout=self.timeout) payload = Leshan.handle_response(resp) - if not payload['status'] == 'CONTENT(205)': - raise RuntimeError(f'No content received') - return self.parse_composite(payload['content']) + return self.parse_composite(payload) def composite_write(self, endpoint: str, resources: dict): """ @@ -314,11 +320,7 @@ def composite_write(self, endpoint: str, resources: dict): Objects or object instances cannot be targeted. """ data = { } - parameters = { - 'pathformat': self.format, - 'nodeformat': self.format, - 'timeout': self.timeout - } + parameters = self._composite_params() for path, value in resources.items(): path = path if path.startswith('/') else '/' + path level = len(path.split('/')) - 1 @@ -349,7 +351,7 @@ def create_psk_device(self, endpoint: str, passwd: str): self.put('/security/clients/', f'{{"endpoint":"{endpoint}","tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}} }} }}') def delete_device(self, endpoint: str): - self.delete(f'/security/clients/{endpoint}') + self.delete_raw(f'/security/clients/{endpoint}') def create_bs_device(self, endpoint: str, server_uri: str, bs_passwd: str, passwd: str): psk = binascii.b2a_hex(bs_passwd.encode()).decode() @@ -361,11 +363,27 @@ def create_bs_device(self, endpoint: str, server_uri: str, bs_passwd: str, passw self.post(f'/bootstrap/{endpoint}', content) def delete_bs_device(self, endpoint: str): - self.delete(f'/security/clients/{endpoint}') - self.delete(f'/bootstrap/{endpoint}') + self.delete_raw(f'/security/clients/{endpoint}') + self.delete_raw(f'/bootstrap/{endpoint}') + + def observe(self, endpoint: str, path: str): + return self.post(f'/clients/{endpoint}/{path}/observe', data="") + + def cancel_observe(self, endpoint: str, path: str): + return self.delete_raw(f'/clients/{endpoint}/{path}/observe') + + def composite_observe(self, endpoint: str, paths: list[str]): + parameters = self._composite_params(paths) + resp = self._s.post(f'{self.api_url}/clients/{endpoint}/composite/observe', params=parameters, timeout=self.timeout) + payload = Leshan.handle_response(resp) + return self.parse_composite(payload) + + def cancel_composite_observe(self, endpoint: str, paths: list[str]): + paths = [path if path.startswith('/') else '/' + path for path in paths] + return self.delete_raw(f'/clients/{endpoint}/composite/observe?paths=' + ','.join(paths)) @contextmanager - def get_event_stream(self, endpoint: str): + def get_event_stream(self, endpoint: str, timeout: int = None): """ Get stream of events regarding the given endpoint. @@ -377,11 +395,13 @@ def get_event_stream(self, endpoint: str): If timeout happens, the event streams returns None. """ - r = self._s.get(f'{self.api_url}/event?{endpoint}', stream=True, headers={'Accept': 'text/event-stream'}, timeout=self.timeout) + if timeout is None: + timeout = self.timeout + r = requests.get(f'{self.api_url}/event?{endpoint}', stream=True, headers={'Accept': 'text/event-stream'}, timeout=timeout) if r.encoding is None: r.encoding = 'utf-8' try: - yield LeshanEventsIterator(r, self.timeout) + yield LeshanEventsIterator(r, timeout) finally: r.close() @@ -406,8 +426,11 @@ def next_event(self, event: str): if not line.startswith('data: '): continue data = json.loads(line.lstrip('data: ')) - if event == 'SEND': + if event == 'SEND' or (event == 'NOTIFICATION' and data['kind'] == 'composite'): return Leshan.parse_composite(data['val']) + if event == 'NOTIFICATION': + d = {data['res']: data['val']} + return Leshan.parse_composite(d) return data if time.time() > timeout: return None diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index bdeb8783847..8f3acd69c7e 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -495,3 +495,210 @@ def test_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str) assert len(resp[1][0]) == 2 # /1/0/8 should not be there assert resp[1][0][1] == 86400 assert resp[1][0][7] == 'U' + +# +# Information Reporting Interface [300-399] +# + +def test_LightweightM2M_1_1_int_301(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-301 - Observation and Notification of parameter values""" + pwr_src = leshan.read(endpoint, '3/0/6') + logger.debug(pwr_src) + assert pwr_src[6][0] == 1 + assert pwr_src[6][1] == 5 + assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?pmin=5')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?pmax=10')['status'] == 'CHANGED(204)' + leshan.observe(endpoint, '3/0/7') + with leshan.get_event_stream(endpoint, timeout=30) as events: + shell.exec_command('lwm2m write /3/0/7/0 -u32 3000') + data = events.next_event('NOTIFICATION') + assert data is not None + assert data[3][0][7][0] == 3000 + # Ensure that we don't get new data before pMin + start = time.time() + shell.exec_command('lwm2m write /3/0/7/0 -u32 3500') + data = events.next_event('NOTIFICATION') + assert data[3][0][7][0] == 3500 + assert (start + 5) < time.time() + 0.5 # Allow 0.5 second diff + assert (start + 5) > time.time() - 0.5 + # Ensure that we get update when pMax expires + data = events.next_event('NOTIFICATION') + assert data[3][0][7][0] == 3500 + assert (start + 15) <= time.time() + 1 # Allow 1 second slack. (pMinx + pMax=15) + leshan.cancel_observe(endpoint, '3/0/7') + +def test_LightweightM2M_1_1_int_302(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-302 - Cancel Observations using Reset Operation""" + leshan.observe(endpoint, '3/0/7') + leshan.observe(endpoint, '3/0/8') + with leshan.get_event_stream(endpoint) as events: + shell.exec_command('lwm2m write /3/0/7/0 -u32 4000') + data = events.next_event('NOTIFICATION') + assert data[3][0][7][0] == 4000 + leshan.cancel_observe(endpoint, '3/0/7') + shell.exec_command('lwm2m write /3/0/7/0 -u32 3000') + dut.readlines_until(regex=r'.*Observer removed for 3/0/7') + with leshan.get_event_stream(endpoint) as events: + shell.exec_command('lwm2m write /3/0/8/0 -u32 100') + data = events.next_event('NOTIFICATION') + assert data[3][0][8][0] == 100 + leshan.cancel_observe(endpoint, '3/0/8') + shell.exec_command('lwm2m write /3/0/8/0 -u32 50') + dut.readlines_until(regex=r'.*Observer removed for 3/0/8') + +def test_LightweightM2M_1_1_int_304(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-304 - Observe-Composite Operation""" + assert leshan.put_raw(f'/clients/{endpoint}/1/0/1/attributes?pmin=30')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/1/0/1/attributes?pmax=45')['status'] == 'CHANGED(204)' + data = leshan.composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + assert data[1][0][1] is not None + assert data[3][0][11][0] is not None + assert data[3][0][16] == 'U' + assert len(data) == 2 + assert len(data[1]) == 1 + assert len(data[3][0]) == 2 + start = time.time() + with leshan.get_event_stream(endpoint, timeout=50) as events: + data = events.next_event('NOTIFICATION') + logger.debug(data) + assert data[1][0][1] is not None + assert data[3][0][11][0] is not None + assert data[3][0][16] == 'U' + assert len(data) == 2 + assert len(data[1]) == 1 + assert len(data[3][0]) == 2 + assert (start + 30) < time.time() + assert (start + 45) > time.time() - 1 + leshan.cancel_composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + +def test_LightweightM2M_1_1_int_306(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-306 - Send Operation""" + with leshan.get_event_stream(endpoint) as events: + shell.exec_command('lwm2m send /1 /3') + dut.readlines_until(regex=r'.*SEND status: 0', timeout=5.0) + data = events.next_event('SEND') + assert data is not None + verify_server_object(data[1]) + verify_device_object(data[3]) + +def test_LightweightM2M_1_1_int_307(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-307 - Muting Send""" + leshan.write(endpoint, '1/0/23', True) + lines = shell.get_filtered_output(shell.exec_command('lwm2m send /3/0')) + assert any("can't do send operation" in line for line in lines) + leshan.write(endpoint, '1/0/23', False) + shell.exec_command('lwm2m send /3/0') + dut.readlines_until(regex=r'.*SEND status: 0', timeout=5.0) + +def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-308 - Observe-Composite and Creating Object Instance""" + shell.exec_command('lwm2m delete /16/0') + shell.exec_command('lwm2m delete /16/1') + # Need to use Configuration C.1 + shell.exec_command('lwm2m write 1/0/2 -u32 0') + shell.exec_command('lwm2m write 1/0/3 -u32 0') + resources_a = { + 0: {0: 'aa', + 1: 'bb', + 2: 'cc', + 3: 'dd'} + } + content_one = {16: {0: resources_a}} + resources_b = { + 0: {0: '11', + 1: '22', + 2: '33', + 3: '44'} + } + content_both = {16: {0: resources_a, 1: resources_b}} + assert leshan.create_obj_instance(endpoint, '16/0', resources_a)['status'] == 'CREATED(201)' + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmin=30')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmax=45')['status'] == 'CHANGED(204)' + data = leshan.composite_observe(endpoint, ['/16/0', '/16/1']) + assert data == content_one + with leshan.get_event_stream(endpoint, timeout=50) as events: + data = events.next_event('NOTIFICATION') + start = time.time() + assert data == content_one + assert leshan.create_obj_instance(endpoint, '16/1', resources_b)['status'] == 'CREATED(201)' + data = events.next_event('NOTIFICATION') + assert (start + 30) < time.time() + 2 + assert (start + 45) > time.time() - 2 + assert data == content_both + leshan.cancel_composite_observe(endpoint, ['/16/0', '/16/1']) + # Restore configuration C.3 + shell.exec_command('lwm2m write 1/0/2 -u32 1') + shell.exec_command('lwm2m write 1/0/3 -u32 10') + +def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-309 - Observe-Composite and Deleting Object Instance""" + shell.exec_command('lwm2m delete /16/0') + shell.exec_command('lwm2m delete /16/1') + # Need to use Configuration C.1 + shell.exec_command('lwm2m write 1/0/2 -u32 0') + shell.exec_command('lwm2m write 1/0/3 -u32 0') + resources_a = { + 0: {0: 'aa', + 1: 'bb', + 2: 'cc', + 3: 'dd'} + } + content_one = {16: {0: resources_a}} + resources_b = { + 0: {0: '11', + 1: '22', + 2: '33', + 3: '44'} + } + content_both = {16: {0: resources_a, 1: resources_b}} + assert leshan.create_obj_instance(endpoint, '16/0', resources_a)['status'] == 'CREATED(201)' + assert leshan.create_obj_instance(endpoint, '16/1', resources_b)['status'] == 'CREATED(201)' + dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) + assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmin=30')['status'] == 'CHANGED(204)' + assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmax=45')['status'] == 'CHANGED(204)' + data = leshan.composite_observe(endpoint, ['/16/0', '/16/1']) + assert data == content_both + with leshan.get_event_stream(endpoint, timeout=50) as events: + data = events.next_event('NOTIFICATION') + start = time.time() + assert data == content_both + assert leshan.delete(endpoint, '16/1')['status'] == 'DELETED(202)' + data = events.next_event('NOTIFICATION') + assert (start + 30) < time.time() + 2 + assert (start + 45) > time.time() - 2 + assert data == content_one + leshan.cancel_composite_observe(endpoint, ['/16/0', '/16/1']) + # Restore configuration C.3 + shell.exec_command('lwm2m write 1/0/2 -u32 1') + shell.exec_command('lwm2m write 1/0/3 -u32 10') + +def test_LightweightM2M_1_1_int_310(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-310 - Observe-Composite and modification of parameter values""" + # Need to use Configuration C.1 + shell.exec_command('lwm2m write 1/0/2 -u32 0') + shell.exec_command('lwm2m write 1/0/3 -u32 0') + # Ensure that our previous attributes are not conflicting + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=0')['status'] == 'CHANGED(204)' + leshan.composite_observe(endpoint, ['/1/0/1', '/3/0']) + with leshan.get_event_stream(endpoint, timeout=50) as events: + assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=5')['status'] == 'CHANGED(204)' + start = time.time() + data = events.next_event('NOTIFICATION') + assert data[3][0][0] == 'Zephyr' + assert data[1] == {0: {1: 86400}} + assert (start + 5) > time.time() - 1 + start = time.time() + data = events.next_event('NOTIFICATION') + assert (start + 5) > time.time() - 1 + leshan.cancel_composite_observe(endpoint, ['/1/0/1', '/3/0']) + # Restore configuration C.3 + shell.exec_command('lwm2m write 1/0/2 -u32 1') + shell.exec_command('lwm2m write 1/0/3 -u32 10') + +def test_LightweightM2M_1_1_int_311(shell: Shell, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-311 - Send command""" + with leshan.get_event_stream(endpoint, timeout=50) as events: + shell.exec_command('lwm2m send /1/0/1 /3/0/11') + data = events.next_event('SEND') + assert data == {3: {0: {11: {0: 0}}}, 1: {0: {1: 86400}}} diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml index 1b9818e777e..42bd53814bf 100644 --- a/tests/net/lib/lwm2m/interop/testcase.yaml +++ b/tests/net/lib/lwm2m/interop/testcase.yaml @@ -1,10 +1,11 @@ tests: net.lwm2m.interop: harness: pytest - timeout: 300 + timeout: 600 slow: true harness_config: pytest_dut_scope: module + pytest_args: [] integration_platforms: - native_posix platform_allow: From 883f604f1274e38a5cc4781e38c35953d68941c9 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 25 Oct 2023 13:40:34 +0000 Subject: [PATCH 3174/4498] soc: arm: nxp_imx: rt11xx: allow user to disable CONFIG_ADJUST_DCDC Allow user to disable CONFIG_ADJUST_DCDC for their board, rather than selecting it at the SOC level. The symbol still defaults to enabled, preserving existing behavior unless a user explicitly chooses to disable it. Signed-off-by: Daniel DeGrasse --- soc/arm/nxp_imx/rt/Kconfig.soc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index 253e316548e..0058993e825 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -1,6 +1,6 @@ # i.MX RT series -# Copyright (c) 2017-2021, NXP +# Copyright 2017-2021,2023 NXP # SPDX-License-Identifier: Apache-2.0 choice @@ -339,7 +339,6 @@ config SOC_MIMXRT1176_CM7 select INIT_VIDEO_PLL select HAS_MCUX_EDMA select CPU_HAS_FPU_DOUBLE_PRECISION - select ADJUST_DCDC select BYPASS_LDO_LPSR select ADJUST_LDO select HAS_MCUX_PWM @@ -408,7 +407,6 @@ config SOC_MIMXRT1166_CM7 select INIT_VIDEO_PLL select HAS_MCUX_EDMA select CPU_HAS_FPU_DOUBLE_PRECISION - select ADJUST_DCDC select BYPASS_LDO_LPSR select ADJUST_LDO select HAS_MCUX_PWM @@ -686,6 +684,7 @@ config DCDC_VALUE config ADJUST_DCDC bool "Adjust internal DCDC output" + default y if SOC_SERIES_IMX_RT11XX config BYPASS_LDO_LPSR bool "Bypass LDO lpsr" From 6db61686f761128a48d258773c8f7696aaa47f3b Mon Sep 17 00:00:00 2001 From: Roman Kellner Date: Tue, 31 Oct 2023 15:38:55 +0100 Subject: [PATCH 3175/4498] kernel: poll: remove extra semicolons in macros When _POLL_EVENT becomes an empty define due to CONFIG_POLL, it will create an empty line terminated with a semicolon. Empty struct members contradict the C specification eventhough most compiler will tolerate it without -Wpedantic. Signed-off-by: Roman Kellner --- include/zephyr/kernel.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 51d5aa37901..23fdbba8c8f 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -60,7 +60,7 @@ BUILD_ASSERT(sizeof(intptr_t) == sizeof(long)); #ifdef CONFIG_POLL #define _POLL_EVENT_OBJ_INIT(obj) \ .poll_events = SYS_DLIST_STATIC_INIT(&obj.poll_events), -#define _POLL_EVENT sys_dlist_t poll_events +#define _POLL_EVENT sys_dlist_t poll_events; #else #define _POLL_EVENT_OBJ_INIT(obj) #define _POLL_EVENT @@ -1849,7 +1849,7 @@ struct k_queue { struct k_spinlock lock; _wait_q_t wait_q; - _POLL_EVENT; + _POLL_EVENT SYS_PORT_TRACING_TRACKING_FIELD(k_queue) }; @@ -3111,7 +3111,7 @@ struct k_sem { unsigned int count; unsigned int limit; - _POLL_EVENT; + _POLL_EVENT SYS_PORT_TRACING_TRACKING_FIELD(k_sem) @@ -4424,7 +4424,7 @@ struct k_msgq { /** Number of used messages */ uint32_t used_msgs; - _POLL_EVENT; + _POLL_EVENT /** Message queue */ uint8_t flags; @@ -4864,7 +4864,7 @@ struct k_pipe { _wait_q_t writers; /**< Writer wait queue */ } wait_q; /** Wait queue */ - _POLL_EVENT; + _POLL_EVENT uint8_t flags; /**< Flags */ From 80f00ab63b80cb3b9894fc8c27202d7f89f2056e Mon Sep 17 00:00:00 2001 From: Roman Kellner Date: Tue, 31 Oct 2023 15:49:33 +0100 Subject: [PATCH 3176/4498] kernel: poll: change macro prefix from '_' to 'Z_' Identifiers starting with an underscore and a capital letter are reserved by the C standard. Prefix '_POLL_EVENT' with an additional 'DECL' for better recognition. Signed-off-by: Roman Kellner --- include/zephyr/kernel.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 23fdbba8c8f..fac7df01904 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -58,12 +58,12 @@ BUILD_ASSERT(sizeof(intptr_t) == sizeof(long)); #define K_LOWEST_APPLICATION_THREAD_PRIO (K_LOWEST_THREAD_PRIO - 1) #ifdef CONFIG_POLL -#define _POLL_EVENT_OBJ_INIT(obj) \ +#define Z_POLL_EVENT_OBJ_INIT(obj) \ .poll_events = SYS_DLIST_STATIC_INIT(&obj.poll_events), -#define _POLL_EVENT sys_dlist_t poll_events; +#define Z_DECL_POLL_EVENT sys_dlist_t poll_events; #else -#define _POLL_EVENT_OBJ_INIT(obj) -#define _POLL_EVENT +#define Z_POLL_EVENT_OBJ_INIT(obj) +#define Z_DECL_POLL_EVENT #endif struct k_thread; @@ -1849,7 +1849,7 @@ struct k_queue { struct k_spinlock lock; _wait_q_t wait_q; - _POLL_EVENT + Z_DECL_POLL_EVENT SYS_PORT_TRACING_TRACKING_FIELD(k_queue) }; @@ -1863,7 +1863,7 @@ struct k_queue { .data_q = SYS_SFLIST_STATIC_INIT(&obj.data_q), \ .lock = { }, \ .wait_q = Z_WAIT_Q_INIT(&obj.wait_q), \ - _POLL_EVENT_OBJ_INIT(obj) \ + Z_POLL_EVENT_OBJ_INIT(obj) \ } /** @@ -3111,7 +3111,7 @@ struct k_sem { unsigned int count; unsigned int limit; - _POLL_EVENT + Z_DECL_POLL_EVENT SYS_PORT_TRACING_TRACKING_FIELD(k_sem) @@ -3125,7 +3125,7 @@ struct k_sem { .wait_q = Z_WAIT_Q_INIT(&obj.wait_q), \ .count = initial_count, \ .limit = count_limit, \ - _POLL_EVENT_OBJ_INIT(obj) \ + Z_POLL_EVENT_OBJ_INIT(obj) \ } /** @@ -4424,7 +4424,7 @@ struct k_msgq { /** Number of used messages */ uint32_t used_msgs; - _POLL_EVENT + Z_DECL_POLL_EVENT /** Message queue */ uint8_t flags; @@ -4450,7 +4450,7 @@ struct k_msgq { .read_ptr = q_buffer, \ .write_ptr = q_buffer, \ .used_msgs = 0, \ - _POLL_EVENT_OBJ_INIT(obj) \ + Z_POLL_EVENT_OBJ_INIT(obj) \ } /** @@ -4864,7 +4864,7 @@ struct k_pipe { _wait_q_t writers; /**< Writer wait queue */ } wait_q; /** Wait queue */ - _POLL_EVENT + Z_DECL_POLL_EVENT uint8_t flags; /**< Flags */ @@ -4892,7 +4892,7 @@ struct k_pipe { .readers = Z_WAIT_Q_INIT(&obj.wait_q.readers), \ .writers = Z_WAIT_Q_INIT(&obj.wait_q.writers) \ }, \ - _POLL_EVENT_OBJ_INIT(obj) \ + Z_POLL_EVENT_OBJ_INIT(obj) \ .flags = 0, \ } From b92ac426771e128a4945725ee4a85ccc15158ab9 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 31 Oct 2023 16:21:36 +0100 Subject: [PATCH 3177/4498] Bluetooth: CAP: Commander API and skeleton Adds the CAP Commendar API and skeleton that can implemented. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/cap.h | 238 +++++++++++++++++++++++++ subsys/bluetooth/Kconfig.logging | 5 + subsys/bluetooth/audio/CMakeLists.txt | 1 + subsys/bluetooth/audio/Kconfig.cap | 13 ++ subsys/bluetooth/audio/cap_commander.c | 68 +++++++ tests/bluetooth/shell/audio.conf | 2 + 6 files changed, 327 insertions(+) create mode 100644 subsys/bluetooth/audio/cap_commander.c diff --git a/include/zephyr/bluetooth/audio/cap.h b/include/zephyr/bluetooth/audio/cap.h index 2327907310f..06da5700506 100644 --- a/include/zephyr/bluetooth/audio/cap.h +++ b/include/zephyr/bluetooth/audio/cap.h @@ -636,6 +636,244 @@ struct bt_cap_broadcast_to_unicast_param { int bt_cap_initiator_broadcast_to_unicast(const struct bt_cap_broadcast_to_unicast_param *param, struct bt_bap_unicast_group **unicast_group); +/** + * @brief Discovers audio support on a remote device. + * + * This will discover the Common Audio Service (CAS) on the remote device, to + * verify if the remote device supports the Common Audio Profile. + * + * @note @kconfig{CONFIG_BT_CAP_COMMANDER} must be enabled for this function. If + * @kconfig{CONFIG_BT_CAP_INITIATOR} is also enabled, it does not matter if + * bt_cap_commander_unicast_discover() or bt_cap_initiator_unicast_discover() is used. + * + * @param conn Connection to a remote server. + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_unicast_discover(struct bt_conn *conn); + +struct bt_cap_commander_broadcast_reception_start_member_param { + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member member; + + /** Address of the advertiser. */ + bt_addr_le_t addr; + + /** SID of the advertising set. */ + uint8_t adv_sid; + + /** + * @brief Periodic advertising interval in milliseconds. + * + * BT_BAP_PA_INTERVAL_UNKNOWN if unknown. + */ + uint16_t pa_interval; + + /** 24-bit broadcast ID */ + uint32_t broadcast_id; + + /** + * @brief Pointer to array of subgroups + * + * At least one bit in one of the subgroups bis_sync parameters shall be set. + */ + struct bt_bap_scan_delegator_subgroup *subgroups; + + /** Number of subgroups */ + size_t num_subgroups; +}; + +/** Parameters for starting broadcast reception */ +struct bt_cap_commander_broadcast_reception_start_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** The set of devices for this procedure */ + struct bt_cap_commander_broadcast_reception_start_member_param *param; + + /** The number of parameters in @p param */ + size_t count; +}; + +/** + * @brief Starts the reception of broadcast audio on one or more remote Common Audio Profile + * Acceptors + * + * @param param The parameters to start the broadcast audio + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_broadcast_reception_start( + const struct bt_cap_commander_broadcast_reception_start_param *param); + +/** Parameters for stopping broadcast reception */ +struct bt_cap_commander_broadcast_reception_stop_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member *members; + + /** The number of members in @p members */ + size_t count; +}; + +/** + * @brief Stops the reception of broadcast audio on one or more remote Common Audio Profile + * Acceptors + * + * @param param The parameters to stop the broadcast audio + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_broadcast_reception_stop( + const struct bt_cap_commander_broadcast_reception_stop_param *param); + +/** Parameters for changing absolute volume */ +struct bt_cap_commander_change_volume_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member *members; + + /** The number of members in @p members */ + size_t count; + + /** The absolute volume to set */ + uint8_t volume; +}; + +/** + * @brief Change the volume on one or more Common Audio Profile Acceptors + * + * @param param The parameters for the volume change + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_change_volume(const struct bt_cap_commander_change_volume_param *param); + +struct bt_cap_commander_change_volume_offset_member_param { + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member member; + + /** + * @brief The offset to set + * + * Value shall be between @ref BT_VOCS_MIN_OFFSET and @ref BT_VOCS_MAX_OFFSET + */ + int16_t offset; +}; + +/** Parameters for changing volume offset */ +struct bt_cap_commander_change_volume_offset_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** The set of devices for this procedure */ + struct bt_cap_commander_change_volume_offset_member_param *param; + + /** The number of parameters in @p param */ + size_t count; +}; + +/** + * @brief Change the volume offset on one or more Common Audio Profile Acceptors + * + * @param param The parameters for the volume offset change + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_change_volume_offset( + const struct bt_cap_commander_change_volume_offset_param *param); + +/** Parameters for changing volume mute state */ +struct bt_cap_commander_change_volume_mute_state_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member *members; + + /** The number of members in @p members */ + size_t count; + + /** + * @brief The volume mute state to set + * + * true to mute, and false to unmute + */ + bool mute; +}; + +/** + * @brief Change the volume mute state on one or more Common Audio Profile Acceptors + * + * @param param The parameters for the volume mute state change + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_change_volume_mute_state( + const struct bt_cap_commander_change_volume_mute_state_param *param); + +/** Parameters for changing microphone mute state */ +struct bt_cap_commander_change_microphone_mute_state_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member *members; + + /** The number of members in @p members */ + size_t count; + + /** + * @brief The microphone mute state to set + * + * true to mute, and false to unmute + */ + bool mute; +}; + +/** + * @brief Change the microphone mute state on one or more Common Audio Profile Acceptors + * + * @param param The parameters for the microphone mute state change + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_change_microphone_mute_state( + const struct bt_cap_commander_change_microphone_mute_state_param *param); + +struct bt_cap_commander_change_microphone_gain_setting_member_param { + /** Coordinated or ad-hoc set member. */ + union bt_cap_set_member member; + + /** @brief The microphone gain setting to set */ + int8_t gain; +}; + +/** Parameters for changing microphone mute state */ +struct bt_cap_commander_change_microphone_gain_setting_param { + /** The type of the set. */ + enum bt_cap_set_type type; + + /** The set of devices for this procedure */ + struct bt_cap_commander_change_microphone_gain_setting_member_param *param; + + /** The number of parameters in @p param */ + size_t count; +}; + +/** + * @brief Change the microphone gain setting on one or more Common Audio Profile Acceptors + * + * @param param The parameters for the microphone gain setting change + * + * @return 0 on success or negative error value on failure. + */ +int bt_cap_commander_change_microphone_gain_setting( + const struct bt_cap_commander_change_microphone_gain_setting_param *param); #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/Kconfig.logging b/subsys/bluetooth/Kconfig.logging index addf8eb65fe..ec95ddad10e 100644 --- a/subsys/bluetooth/Kconfig.logging +++ b/subsys/bluetooth/Kconfig.logging @@ -716,6 +716,11 @@ legacy-debug-sym = BT_DEBUG_CAP_INITIATOR module-str = "Common Audio Profile Initiator" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" +parent-module = BT +module = BT_CAP_COMMANDER +module-str = "Common Audio Profile Commander" +source "subsys/logging/Kconfig.template.log_config_inherit" + parent-module = BT module = BT_CAP_STREAM module-str = "Common Audio Profile Stream" diff --git a/subsys/bluetooth/audio/CMakeLists.txt b/subsys/bluetooth/audio/CMakeLists.txt index 8f24c50233b..2ae08c2d7b5 100644 --- a/subsys/bluetooth/audio/CMakeLists.txt +++ b/subsys/bluetooth/audio/CMakeLists.txt @@ -60,4 +60,5 @@ zephyr_library_sources_ifdef(CONFIG_BT_HAS_CLIENT has_client.c) zephyr_library_sources_ifdef(CONFIG_BT_CAP cap_stream.c) zephyr_library_sources_ifdef(CONFIG_BT_CAP_ACCEPTOR cap_acceptor.c) zephyr_library_sources_ifdef(CONFIG_BT_CAP_INITIATOR cap_initiator.c) +zephyr_library_sources_ifdef(CONFIG_BT_CAP_COMMANDER cap_commander.c) zephyr_library_sources_ifdef(CONFIG_BT_TMAP tmap.c) diff --git a/subsys/bluetooth/audio/Kconfig.cap b/subsys/bluetooth/audio/Kconfig.cap index 9fdc1506c3d..0488b610a08 100644 --- a/subsys/bluetooth/audio/Kconfig.cap +++ b/subsys/bluetooth/audio/Kconfig.cap @@ -35,3 +35,16 @@ config BT_CAP_INITIATOR select EXPERIMENTAL help Enabling this will enable the CAP Initiator role. + + +config BT_CAP_COMMANDER + bool "Common Audio Profile Initiator Role Support [EXPERIMENTAL]" + depends on (BT_BAP_BROADCAST_ASSISTANT && BT_BAP_SCAN_DELEGATOR && BT_CSIP_SET_COORDINATOR) || \ + (BT_BAP_SCAN_DELEGATOR && BT_CSIP_SET_COORDINATOR) || \ + (BT_VCP_VOL_CTLR && BT_CSIP_SET_COORDINATOR) || \ + (BT_MICP_MIC_CTLR && BT_CSIP_SET_COORDINATOR) || \ + BT_TBS_CLIENT || \ + BT_MCC + select EXPERIMENTAL + help + Enabling this will enable the CAP Initiator role. diff --git a/subsys/bluetooth/audio/cap_commander.c b/subsys/bluetooth/audio/cap_commander.c new file mode 100644 index 00000000000..ffe8cd0f89a --- /dev/null +++ b/subsys/bluetooth/audio/cap_commander.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "cap_internal.h" +#include "ccid_internal.h" +#include "csip_internal.h" +#include "bap_endpoint.h" + +#include + +LOG_MODULE_REGISTER(bt_cap_commander, CONFIG_BT_CAP_COMMANDER_LOG_LEVEL); + +#include "common/bt_str.h" + +int bt_cap_commander_unicast_discover(struct bt_conn *conn) +{ + return -ENOSYS; +} + +int bt_cap_commander_broadcast_reception_start( + const struct bt_cap_commander_broadcast_reception_start_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_broadcast_reception_stop( + const struct bt_cap_commander_broadcast_reception_stop_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_change_volume(const struct bt_cap_commander_change_volume_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_change_volume_offset( + const struct bt_cap_commander_change_volume_offset_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_change_volume_mute_state( + const struct bt_cap_commander_change_volume_mute_state_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_change_microphone_mute_state( + const struct bt_cap_commander_change_microphone_mute_state_param *param) +{ + return -ENOSYS; +} + +int bt_cap_commander_change_microphone_gain_setting( + const struct bt_cap_commander_change_microphone_gain_setting_param *param) +{ + + return -ENOSYS; +} diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index 2a8d64858f4..8cf39af0bdb 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -153,6 +153,7 @@ CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE=y CONFIG_BT_CAP_ACCEPTOR=y CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER=y CONFIG_BT_CAP_INITIATOR=y +CONFIG_BT_CAP_COMMANDER=y # Telephone and Media Audio Profile CONFIG_BT_TMAP=y @@ -201,4 +202,5 @@ CONFIG_BT_CSIP_SET_COORDINATOR_LOG_LEVEL_DBG=y CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL_DBG=y CONFIG_BT_CAP_ACCEPTOR_LOG_LEVEL_DBG=y CONFIG_BT_CAP_INITIATOR_LOG_LEVEL_DBG=y +CONFIG_BT_CAP_COMMANDER_LOG_LEVEL_DBG=y CONFIG_BT_TMAP_LOG_LEVEL_DBG=y From 08ca98fbd1e781c2dfd96f52176716831213e9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 2 Nov 2023 11:29:31 +0100 Subject: [PATCH 3178/4498] doc: gsg: Remove misleading mention of Powershell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While we will probably want to properly document how to use Powershell on Windows in the near future, current Getting Started Guide contained a misleading mention to activating Pythonv venv using Powershell that this commit removes. Addresses comments raised in #64682. Signed-off-by: Benjamin Cabé --- doc/develop/getting_started/index.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 15b33738f86..35eafb38561 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -402,10 +402,7 @@ additional Python dependencies. .. code-block:: bat - :: cmd.exe zephyrproject\.venv\Scripts\activate.bat - :: PowerShell - zephyrproject\.venv\Scripts\Activate.ps1 Once activated your shell will be prefixed with ``(.venv)``. The virtual environment can be deactivated at any time by running From 8c179870d426b18d24c8c359c52f8a30dd1bc0e5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 3 Nov 2023 00:38:43 +0530 Subject: [PATCH 3179/4498] wifi: shell: Fix default band value The enum is mainly to print output of band, so, the default value is 0 which means 2.4GHz, which is not correct when using it to configure like in connect. Fix the default value to unknown i.e., no user preference. This way we can use same enum for both set and get. Signed-off-by: Chaitanya Tata --- subsys/net/l2/wifi/wifi_shell.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 7d03fb0c217..69b0c84c747 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -341,6 +341,8 @@ static int __wifi_args_to_params(size_t argc, char *argv[], return -EINVAL; } + params->band = WIFI_FREQ_BAND_UNKNOWN; + /* SSID */ params->ssid = argv[0]; params->ssid_length = strlen(params->ssid); From d12627e70f9f13d7dcdbac46886aede417a71cdd Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 3 Nov 2023 00:41:39 +0530 Subject: [PATCH 3180/4498] wifi: shell: Move defaults to beginning This sets defaults first and then overrides if configured, easier to read. Signed-off-by: Chaitanya Tata --- subsys/net/l2/wifi/wifi_shell.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 69b0c84c747..ed85b015971 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -341,7 +341,10 @@ static int __wifi_args_to_params(size_t argc, char *argv[], return -EINVAL; } + /* Defaults */ params->band = WIFI_FREQ_BAND_UNKNOWN; + params->channel = WIFI_CHANNEL_ANY; + params->security = WIFI_SECURITY_TYPE_NONE; /* SSID */ params->ssid = argv[0]; @@ -362,8 +365,6 @@ static int __wifi_args_to_params(size_t argc, char *argv[], } idx++; - } else { - params->channel = WIFI_CHANNEL_ANY; } /* PSK (optional) */ @@ -402,8 +403,6 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->psk_length > WIFI_SAE_PSWD_MAX_LEN)) { return -EINVAL; } - } else { - params->security = WIFI_SECURITY_TYPE_NONE; } From 82ec6394a142214921167478c8572fbd57ba4f32 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 3 Nov 2023 16:23:43 +0100 Subject: [PATCH 3181/4498] soc: arm: Fix cmake linker.ld warning for arduino_uno_r4_minima Fix cmake depreciation warning on pre-defined linker.id (soc/arm/renesas_ra/ra4m1/linker.ld) used for arduino_uno_r4_minima. Signed-off-by: Dmitrii Golovanov --- soc/arm/renesas_ra/ra4m1/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/renesas_ra/ra4m1/CMakeLists.txt b/soc/arm/renesas_ra/ra4m1/CMakeLists.txt index 45014584cbb..4debbfdbf8a 100644 --- a/soc/arm/renesas_ra/ra4m1/CMakeLists.txt +++ b/soc/arm/renesas_ra/ra4m1/CMakeLists.txt @@ -1,4 +1,4 @@ # Copyright (c) 2023 TOKITA Hiroshi # SPDX-License-Identifier: Apache-2.0 -# empty +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From 63b8890ad42840262eb9d02d268e04651430cd11 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 3 Nov 2023 14:28:54 -0600 Subject: [PATCH 3182/4498] ITE: drivers/i2c/i2c_ite_enhance: Fix I2C dump messages The ISR for CQ mode was unconditionally writing into the I2C message buffer for all transfer types. The correct data was transferred on the I2C interface, but the clobber caused CONFIG_I2C_LOG_LEVEL_DBG to display incorrect data for I2C writes. This change will also help performance of large I2C write transactions. Signed-off-by: Keith Short --- drivers/i2c/i2c_ite_enhance.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index a499c81bf0a..93187ff940a 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -735,9 +735,11 @@ static int enhanced_i2c_cq_isr(const struct device *dev) uint8_t msgs_idx = data->num_msgs - 1; /* Get data if this is a read transaction. */ - for (int i = 0; i < data->cq_msgs[msgs_idx].len; i++) { - data->cq_msgs[msgs_idx].buf[i] = - host_buffer->i2c_cq_mode_rx_dlm[i]; + if (data->cq_msgs[msgs_idx].flags & I2C_MSG_READ) { + for (int i = 0; i < data->cq_msgs[msgs_idx].len; i++) { + data->cq_msgs[msgs_idx].buf[i] = + host_buffer->i2c_cq_mode_rx_dlm[i]; + } } } else { /* Device 1 error have occurred. eg. nack, timeout... */ From 054f9d7a82f0dab36a666d6d81bed7e5710d2c81 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Fri, 3 Nov 2023 16:37:25 -0700 Subject: [PATCH 3183/4498] drivers: gpio: gpio_mcux_lpc: fix bug disabling pulls If the gpio had pull previous enabled, but new config request wants the pull disabled, the code was failing to clear the previous pull setting. Signed-off-by: Mike J. Chen --- drivers/gpio/gpio_mcux_lpc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpio/gpio_mcux_lpc.c b/drivers/gpio/gpio_mcux_lpc.c index ae0ef1bf796..297e83930f2 100644 --- a/drivers/gpio/gpio_mcux_lpc.c +++ b/drivers/gpio/gpio_mcux_lpc.c @@ -119,6 +119,12 @@ static int gpio_mcux_lpc_configure(const struct device *dev, gpio_pin_t pin, } else if ((flags & GPIO_PULL_DOWN) != 0) { *pinconfig |= IOCON_PIO_MODE_PULLDOWN; } +#endif + } else { +#ifdef IOPCTL /* RT600 and RT500 series */ + *pinconfig &= ~IOPCTL_PIO_PUPD_EN; +#else /* LPC SOCs */ + *pinconfig &= ~(IOCON_PIO_MODE_PULLUP|IOCON_PIO_MODE_PULLDOWN); #endif } From ee57b56ba5d8b1f0130b891c12c821ec3dbf1460 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 5 Nov 2023 15:21:35 +1000 Subject: [PATCH 3184/4498] doc: contribute: instructions for local viewing of docs Add instructions for serving the generated HTML docs on a local IP address. Signed-off-by: Jordan Yates --- doc/contribute/documentation/generation.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index 7c5466ee5ed..87a00357c89 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -278,6 +278,25 @@ or invoke make with the following target:: # To generate HTML output without detailed Kconfig make html-fast +Viewing generated documentation locally +*************************************** + +The generated HTML documentation can be hosted locally with python for viewing +with a web browser: + +.. code-block:: console + + $ python3 -m http.server -d _build/html + +.. note:: + + WSL2 users may need to explicitly bind the address to ``127.0.0.1`` in order + to be accessible from the host machine: + + .. code-block:: console + + $ python3 -m http.server -d _build/html --bind 127.0.0.1 + Linking external Doxygen projects against Zephyr ************************************************ From e89c9a667190c73d8ffbd2cdd03d78988cfac272 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 6 Nov 2023 09:41:43 +0200 Subject: [PATCH 3185/4498] net: tcp: Fix compilation if congestion avoidance is disabled Fix tcp.c compilation if user unsets CONFIG_NET_TCP_CONGESTION_AVOIDANCE config option. Fixes #64824 Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 18da61f5812..4965c34061a 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1350,9 +1350,10 @@ static int tcp_pkt_peek(struct net_pkt *to, struct net_pkt *from, size_t pos, static bool tcp_window_full(struct tcp *conn) { bool window_full = (conn->send_data_total >= conn->send_win); - if (IS_ENABLED(CONFIG_NET_TCP_CONGESTION_AVOIDANCE)) { - window_full = window_full || (conn->send_data_total >= conn->ca.cwnd); - } + +#ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE + window_full = window_full || (conn->send_data_total >= conn->ca.cwnd); +#endif NET_DBG("conn: %p window_full=%hu", conn, window_full); @@ -1375,13 +1376,14 @@ static int tcp_unsent_len(struct tcp *conn) unsent_len = 0; } else { unsent_len = MIN(unsent_len, conn->send_win - conn->unacked_len); - if (IS_ENABLED(CONFIG_NET_TCP_CONGESTION_AVOIDANCE)) { - if (conn->unacked_len >= conn->ca.cwnd) { - unsent_len = 0; - } else { - unsent_len = MIN(unsent_len, conn->ca.cwnd - conn->unacked_len); - } + +#ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE + if (conn->unacked_len >= conn->ca.cwnd) { + unsent_len = 0; + } else { + unsent_len = MIN(unsent_len, conn->ca.cwnd - conn->unacked_len); } +#endif } out: NET_DBG("unsent_len=%d", unsent_len); From 00badc243d5dec9b3129901fa2b9dc7bc760548a Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 6 Nov 2023 08:43:38 +0100 Subject: [PATCH 3186/4498] tests: drivers: gpio: fix cs gpios reg property Adjust the reg of the CS gpios to fix the warning about the same value used for all existing nodes. Signed-off-by: Bartosz Bilas --- tests/drivers/build_all/gpio/app.overlay | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/drivers/build_all/gpio/app.overlay b/tests/drivers/build_all/gpio/app.overlay index 10eea2e04e0..b6a315cedfa 100644 --- a/tests/drivers/build_all/gpio/app.overlay +++ b/tests/drivers/build_all/gpio/app.overlay @@ -221,30 +221,30 @@ ngpios = <16>; }; - test_spi_mcp23sxx: mcp23sxx@0 { + test_spi_mcp23sxx: mcp23sxx@1 { compatible = "microchip,mcp23sxx"; spi-max-frequency = <0>; - reg = <0x0>; + reg = <0x01>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; }; - test_spi_bd8lb600fs: bd8lb600fs@0 { + test_spi_bd8lb600fs: bd8lb600fs@2 { compatible = "rohm,bd8lb600fs"; spi-max-frequency = <0>; - reg = <0x0>; + reg = <0x02>; gpio-controller; #gpio-cells = <2>; ngpios = <8>; reset-gpios = <&test_gpio 0 0>; }; - test_spi_ads114s08: ads114s08@0 { + test_spi_ads114s08: ads114s08@3 { compatible = "ti,ads114s08"; status = "okay"; spi-max-frequency = <10000000>; - reg = <0x0>; + reg = <0x03>; #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; From 0e358bb95702bdc6856031843385d21949975762 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 6 Nov 2023 12:42:01 +0200 Subject: [PATCH 3187/4498] drivers: adltc2990_emul: Correct print format Correct print format for msgs->len. Signed-off-by: Andrei Emeltchenko --- drivers/sensor/adltc2990/adltc2990_emul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/adltc2990/adltc2990_emul.c b/drivers/sensor/adltc2990/adltc2990_emul.c index 664edbd8245..80078f21dc5 100644 --- a/drivers/sensor/adltc2990/adltc2990_emul.c +++ b/drivers/sensor/adltc2990/adltc2990_emul.c @@ -86,7 +86,7 @@ static int adltc2990_emul_transfer_i2c(const struct emul *target, struct i2c_msg return -EIO; } if (msgs->len < 1) { - LOG_ERR("Unexpected msg0 length %s", msgs->len); + LOG_ERR("Unexpected msg0 length %d", msgs->len); return -EIO; } From 92da98389ed2143e0916fd9960dc433b44b22493 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 6 Nov 2023 12:48:11 +0200 Subject: [PATCH 3188/4498] drivers: akm09918c_emul: Correct print format Correct print format for msgs->len. Signed-off-by: Andrei Emeltchenko --- drivers/sensor/akm09918c/akm09918c_emul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/akm09918c/akm09918c_emul.c b/drivers/sensor/akm09918c/akm09918c_emul.c index a8ce27fd3d3..02dc28b35db 100644 --- a/drivers/sensor/akm09918c/akm09918c_emul.c +++ b/drivers/sensor/akm09918c/akm09918c_emul.c @@ -87,7 +87,7 @@ static int akm09918c_emul_transfer_i2c(const struct emul *target, struct i2c_msg return -EIO; } if (msgs->len < 1) { - LOG_ERR("Unexpected msg0 length %s", msgs->len); + LOG_ERR("Unexpected msg0 length %d", msgs->len); return -EIO; } From cde428cbcaad7edabfbb12daf61832c2619d5c0d Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 6 Nov 2023 12:53:46 +0200 Subject: [PATCH 3189/4498] tests: ieee802154_test: Fix missing format specifier Add missing format specifier. Signed-off-by: Andrei Emeltchenko --- tests/net/ieee802154/l2/src/ieee802154_test.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/net/ieee802154/l2/src/ieee802154_test.c b/tests/net/ieee802154/l2/src/ieee802154_test.c index ea90fc47a3e..bda17d72f1c 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_test.c +++ b/tests/net/ieee802154/l2/src/ieee802154_test.c @@ -446,19 +446,18 @@ static bool test_packet_parsing(struct ieee802154_pkt_test *t) NET_INFO("d: %p vs %p -- s: %p vs %p\n", mpdu.mhr.dst_addr, t->mhr_check.dst_addr, mpdu.mhr.src_addr, t->mhr_check.src_addr); - NET_ERR("*** Wrong MPDU information on frame %s\n", - t->name); + NET_ERR("*** Wrong MPDU information on frame %s\n", t->name); return false; } if (mpdu.mhr.fs->sequence != t->sequence) { - NET_ERR("*** Invalid sequence number\n", t->name); + NET_ERR("*** Invalid sequence number for frame %s\n", t->name); return false; } if (mpdu.payload_length != t->payload_length) { - NET_ERR("*** Invalid payload length\n", t->name); + NET_ERR("*** Invalid payload length for frame %s\n", t->name); return false; } From a4a4e6872c96999bfbaa9fd61e73606a81e34502 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 6 Nov 2023 18:26:40 +0200 Subject: [PATCH 3190/4498] tests: ieee802154: Remove double new line from logs NET_XXX() functions already add newline. Signed-off-by: Andrei Emeltchenko --- tests/net/ieee802154/l2/src/ieee802154_test.c | 160 +++++++++--------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/tests/net/ieee802154/l2/src/ieee802154_test.c b/tests/net/ieee802154/l2/src/ieee802154_test.c index bda17d72f1c..7b4ff21dc52 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_test.c +++ b/tests/net/ieee802154/l2/src/ieee802154_test.c @@ -216,7 +216,7 @@ static int disassociate(struct net_if *iface, struct ieee802154_context *ctx) &short_addr_not_associated, sizeof(short_addr_not_associated)); if (ret) { - NET_ERR("*** Failed to %s.\n", __func__); + NET_ERR("*** Failed to %s.", __func__); return ret; } @@ -235,14 +235,14 @@ static int associate(struct net_if *iface, struct ieee802154_context *ctx, uint1 ret = net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface, &mock_pan_id, sizeof(mock_pan_id)); if (ret) { - NET_ERR("*** Failed to set PAN ID in %s.\n", __func__); + NET_ERR("*** Failed to set PAN ID in %s.", __func__); return ret; } ret = net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface, &short_addr, sizeof(short_addr)); if (ret) { - NET_ERR("*** Failed to set short addr in %s.\n", __func__); + NET_ERR("*** Failed to set short addr in %s.", __func__); return ret; } @@ -320,7 +320,7 @@ static struct net_pkt *get_data_pkt_with_ar(void) pkt = net_pkt_rx_alloc_with_buffer(net_iface, sizeof(data_pkt_with_ar), AF_UNSPEC, 0, K_FOREVER); if (!pkt) { - NET_ERR("*** No buffer to allocate\n"); + NET_ERR("*** No buffer to allocate"); return NULL; } @@ -354,7 +354,7 @@ static bool set_up_security(uint8_t security_level) if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, ¶ms, sizeof(struct ieee802154_security_params))) { - NET_ERR("*** Failed to set security settings\n"); + NET_ERR("*** Failed to set security settings"); return false; } @@ -380,7 +380,7 @@ static bool tear_down_security(void) if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, ¶ms, sizeof(struct ieee802154_security_params))) { - NET_ERR("*** Failed to tear down security settings\n"); + NET_ERR("*** Failed to tear down security settings"); return false; } @@ -407,17 +407,17 @@ static int set_up_recv_socket(enum net_sock_type socket_type) fd = socket(AF_PACKET, socket_type, ETH_P_IEEE802154); if (fd < 0) { - NET_ERR("*** Failed to create recv socket : %d\n", errno); + NET_ERR("*** Failed to create recv socket : %d", errno); return fd; } if (bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) { - NET_ERR("*** Failed to bind packet socket : %d\n", errno); + NET_ERR("*** Failed to bind packet socket : %d", errno); goto release_fd; } if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) { - NET_ERR("*** Failed to set reception timeout on packet socket : %d\n", errno); + NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno); goto release_fd; } @@ -433,31 +433,31 @@ static bool test_packet_parsing(struct ieee802154_pkt_test *t) { struct ieee802154_mpdu mpdu = {0}; - NET_INFO("- Parsing packet 0x%p of frame %s\n", t->pkt, t->name); + NET_INFO("- Parsing packet 0x%p of frame %s", t->pkt, t->name); if (!ieee802154_validate_frame(t->pkt, t->length, &mpdu)) { - NET_ERR("*** Could not validate frame %s\n", t->name); + NET_ERR("*** Could not validate frame %s", t->name); return false; } if (mpdu.mhr.fs != t->mhr_check.fc_seq || mpdu.mhr.dst_addr != t->mhr_check.dst_addr || mpdu.mhr.src_addr != t->mhr_check.src_addr) { - NET_INFO("d: %p vs %p -- s: %p vs %p\n", + NET_INFO("d: %p vs %p -- s: %p vs %p", mpdu.mhr.dst_addr, t->mhr_check.dst_addr, mpdu.mhr.src_addr, t->mhr_check.src_addr); - NET_ERR("*** Wrong MPDU information on frame %s\n", t->name); + NET_ERR("*** Wrong MPDU information on frame %s", t->name); return false; } if (mpdu.mhr.fs->sequence != t->sequence) { - NET_ERR("*** Invalid sequence number for frame %s\n", t->name); + NET_ERR("*** Invalid sequence number for frame %s", t->name); return false; } if (mpdu.payload_length != t->payload_length) { - NET_ERR("*** Invalid payload length for frame %s\n", t->name); + NET_ERR("*** Invalid payload length for frame %s", t->name); return false; } @@ -470,7 +470,7 @@ static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr) struct ieee802154_mpdu mpdu; bool result = false; - NET_INFO("- Sending NS packet\n"); + NET_INFO("- Sending NS packet"); /* ensure reproducible results */ ctx->sequence = t->sequence; @@ -480,7 +480,7 @@ static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr) } if (net_ipv6_send_ns(net_iface, NULL, &t->src, &t->dst, &t->dst, false)) { - NET_ERR("*** Could not create IPv6 NS packet\n"); + NET_ERR("*** Could not create IPv6 NS packet"); tear_down_short_addr(net_iface, ctx); goto out; } @@ -491,7 +491,7 @@ static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr) k_sem_take(&driver_lock, K_SECONDS(1)); if (!current_pkt->frags) { - NET_ERR("*** Could not send IPv6 NS packet\n"); + NET_ERR("*** Could not send IPv6 NS packet"); goto out; } @@ -500,14 +500,14 @@ static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr) if (!with_short_addr) { if (net_pkt_get_len(current_pkt) != t->length || memcmp(net_pkt_data(current_pkt), t->pkt, t->length)) { - NET_ERR("*** Sent packet deviates from expected packet\n"); + NET_ERR("*** Sent packet deviates from expected packet"); goto release_frag; } } if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt), &mpdu)) { - NET_ERR("*** Sent packet is not valid\n"); + NET_ERR("*** Sent packet is not valid"); goto release_frag; } @@ -528,7 +528,7 @@ static bool test_wait_for_ack(struct ieee802154_pkt_test *t) bool result = false; bool ack_required; - NET_INFO("- Waiting for ACK reply when sending a data packet\n"); + NET_INFO("- Waiting for ACK reply when sending a data packet"); tx_pkt = get_data_pkt_with_ar(); if (!tx_pkt) { @@ -537,36 +537,36 @@ static bool test_wait_for_ack(struct ieee802154_pkt_test *t) ack_required = ieee802154_prepare_for_ack(net_iface, tx_pkt, tx_pkt->frags); if (!ack_required) { - NET_ERR("*** Expected AR flag to be set\n"); + NET_ERR("*** Expected AR flag to be set"); goto release_tx_pkt; } if (!ieee802154_validate_frame(net_pkt_data(tx_pkt), net_pkt_get_len(tx_pkt), &mpdu)) { - NET_ERR("*** Could not parse data pkt.\n"); + NET_ERR("*** Could not parse data pkt."); goto release_tx_pkt; } one_ack_pkt = net_pkt_rx_alloc_with_buffer(net_iface, IEEE802154_ACK_PKT_LENGTH, AF_UNSPEC, 0, K_FOREVER); if (!one_ack_pkt) { - NET_ERR("*** Could not allocate ack pkt.\n"); + NET_ERR("*** Could not allocate ack pkt."); goto release_tx_pkt; } if (!ieee802154_create_ack_frame(net_iface, one_ack_pkt, mpdu.mhr.fs->sequence)) { - NET_ERR("*** Could not create ack frame.\n"); + NET_ERR("*** Could not create ack frame."); goto release_tx_pkt; } pkt_hexdump(net_pkt_data(one_ack_pkt), net_pkt_get_len(one_ack_pkt)); if (ieee802154_handle_ack(net_iface, one_ack_pkt) != NET_OK) { - NET_ERR("*** Ack frame was not handled.\n"); + NET_ERR("*** Ack frame was not handled."); goto release_ack_pkt; } if (ieee802154_wait_for_ack(net_iface, ack_required) != 0) { - NET_ERR("*** Ack frame was not recorded.\n"); + NET_ERR("*** Ack frame was not recorded."); goto release_ack_pkt; } @@ -585,11 +585,11 @@ static bool test_packet_cloning_with_cb(void) struct net_pkt *pkt; struct net_pkt *cloned_pkt; - NET_INFO("- Cloning packet\n"); + NET_INFO("- Cloning packet"); pkt = net_pkt_rx_alloc_with_buffer(net_iface, 64, AF_UNSPEC, 0, K_NO_WAIT); if (!pkt) { - NET_ERR("*** No buffer to allocate\n"); + NET_ERR("*** No buffer to allocate"); return false; } @@ -619,11 +619,11 @@ static bool test_packet_rssi_conversion(void) int8_t signed_rssi_dbm; struct net_pkt *pkt; - NET_INFO("- RSSI conversion between unsigned and signed representation\n"); + NET_INFO("- RSSI conversion between unsigned and signed representation"); pkt = net_pkt_rx_alloc_on_iface(net_iface, K_NO_WAIT); if (!pkt) { - NET_ERR("*** No pkt to allocate\n"); + NET_ERR("*** No pkt to allocate"); return false; } @@ -696,10 +696,10 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint goto out; } - NET_INFO("- Sending DGRAM packet via AF_PACKET socket\n"); + NET_INFO("- Sending DGRAM packet via AF_PACKET socket"); fd = socket(AF_PACKET, SOCK_DGRAM, ETH_P_IEEE802154); if (fd < 0) { - NET_ERR("*** Failed to create DGRAM socket : %d\n", errno); + NET_ERR("*** Failed to create DGRAM socket : %d", errno); goto reset_security; } @@ -716,13 +716,13 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint } if (bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) { - NET_ERR("*** Failed to bind packet socket : %d\n", errno); + NET_ERR("*** Failed to bind packet socket : %d", errno); goto release_fd; } if (sendto(fd, payload, sizeof(payload), 0, (const struct sockaddr *)&pkt_dst_sll, sizeof(struct sockaddr_ll)) != sizeof(payload)) { - NET_ERR("*** Failed to send, errno %d\n", errno); + NET_ERR("*** Failed to send, errno %d", errno); goto release_fd; } @@ -730,7 +730,7 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint k_sem_take(&driver_lock, K_SECONDS(1)); if (!current_pkt->frags) { - NET_ERR("*** Could not send DGRAM packet\n"); + NET_ERR("*** Could not send DGRAM packet"); goto release_fd; } @@ -738,7 +738,7 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt), &mpdu)) { - NET_ERR("*** Sent packet is not valid\n"); + NET_ERR("*** Sent packet is not valid"); goto release_frag; } @@ -746,12 +746,12 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint net_pkt_lladdr_src(current_pkt)->len = net_if_get_link_addr(net_iface)->len; if (!ieee802154_decipher_data_frame(net_iface, current_pkt, &mpdu)) { - NET_ERR("*** Cannot decipher/authenticate packet\n"); + NET_ERR("*** Cannot decipher/authenticate packet"); goto release_frag; } if (memcmp(mpdu.payload, payload, sizeof(payload)) != 0) { - NET_ERR("*** Payload of sent packet is incorrect\n"); + NET_ERR("*** Payload of sent packet is incorrect"); goto release_frag; } @@ -796,7 +796,7 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l goto out; } - NET_INFO("- Receiving DGRAM packet via AF_PACKET socket\n"); + NET_INFO("- Receiving DGRAM packet via AF_PACKET socket"); fd = set_up_recv_socket(SOCK_DGRAM); if (fd < 0) { @@ -805,7 +805,7 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l pkt = net_pkt_rx_alloc(K_FOREVER); if (!pkt) { - NET_ERR("*** Failed to allocate net pkt.\n"); + NET_ERR("*** Failed to allocate net pkt."); goto release_fd; } @@ -817,14 +817,14 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) { pkt->lladdr_src.addr = src_ll_addr; } else { - NET_ERR("*** Illegal L2 source address length.\n"); + NET_ERR("*** Illegal L2 source address length."); goto release_pkt; } pkt->lladdr_src.len = src_ll_addr_len; frame_buf = net_pkt_get_frag(pkt, IEEE802154_MTU, K_FOREVER); if (!frame_buf) { - NET_ERR("*** Failed to allocate net pkt frag.\n"); + NET_ERR("*** Failed to allocate net pkt frag."); goto release_pkt; } @@ -844,7 +844,7 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l } else if (src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) { sys_memcpy_swap(ctx->ext_addr, src_ll_addr, sizeof(ctx->ext_addr)); } else { - NET_ERR("*** Illegal L2 source address length.\n"); + NET_ERR("*** Illegal L2 source address length."); goto release_pkt; } @@ -858,19 +858,19 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l } if (!frame_result) { - NET_ERR("*** Error while creating data frame.\n"); + NET_ERR("*** Error while creating data frame."); goto release_pkt; }; net_pkt_frag_add(pkt, frame_buf); if (net_recv_data(net_iface, pkt)) { - NET_ERR("*** Error while processing packet.\n"); + NET_ERR("*** Error while processing packet."); goto release_pkt; } if (current_pkt->frags) { - NET_ERR("*** Generated unexpected (ACK?) packet when processing packet.\n"); + NET_ERR("*** Generated unexpected (ACK?) packet when processing packet."); net_pkt_frag_unref(current_pkt->frags); current_pkt->frags = NULL; goto release_pkt; @@ -880,14 +880,14 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l received_len = recvfrom(fd, received_payload, sizeof(received_payload), 0, (struct sockaddr *)&recv_src_sll, &recv_src_sll_len); if (received_len < 0) { - NET_ERR("*** Failed to receive packet, errno %d\n", errno); + NET_ERR("*** Failed to receive packet, errno %d", errno); goto release_pkt; } pkt_hexdump(received_payload, received_len); if (received_len != sizeof(payload) || memcmp(received_payload, payload, sizeof(payload))) { - NET_ERR("*** Payload of received packet is incorrect\n"); + NET_ERR("*** Payload of received packet is incorrect"); goto release_pkt; } @@ -896,7 +896,7 @@ static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_l recv_src_sll.sll_ifindex != net_if_get_by_iface(net_iface) || recv_src_sll.sll_halen != src_ll_addr_len || memcmp(recv_src_sll.sll_addr, src_ll_addr, src_ll_addr_len)) { - NET_ERR("*** Source L2 address of received packet is incorrect\n"); + NET_ERR("*** Source L2 address of received packet is incorrect"); goto release_pkt; } @@ -922,11 +922,11 @@ static bool test_raw_packet_sending(void) bool result = false; int fd; - NET_INFO("- Sending RAW packet via AF_PACKET socket\n"); + NET_INFO("- Sending RAW packet via AF_PACKET socket"); fd = socket(AF_PACKET, SOCK_RAW, ETH_P_IEEE802154); if (fd < 0) { - NET_ERR("*** Failed to create RAW socket : %d\n", errno); + NET_ERR("*** Failed to create RAW socket : %d", errno); goto out; } @@ -935,7 +935,7 @@ static bool test_raw_packet_sending(void) socket_sll.sll_protocol = ETH_P_IEEE802154; if (bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) { - NET_ERR("*** Failed to bind packet socket : %d\n", errno); + NET_ERR("*** Failed to bind packet socket : %d", errno); goto release_fd; } @@ -945,7 +945,7 @@ static bool test_raw_packet_sending(void) msg.msg_iovlen = 1; if (sendmsg(fd, &msg, 0) != sizeof(raw_payload)) { - NET_ERR("*** Failed to send, errno %d\n", errno); + NET_ERR("*** Failed to send, errno %d", errno); goto release_fd; } @@ -953,7 +953,7 @@ static bool test_raw_packet_sending(void) k_sem_take(&driver_lock, K_SECONDS(1)); if (!current_pkt->frags) { - NET_ERR("*** Could not send RAW packet\n"); + NET_ERR("*** Could not send RAW packet"); goto release_fd; } @@ -961,13 +961,13 @@ static bool test_raw_packet_sending(void) if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt), &mpdu)) { - NET_ERR("*** Sent packet is not valid\n"); + NET_ERR("*** Sent packet is not valid"); goto release_frag; } if (memcmp(mpdu.payload, &raw_payload[RAW_MAC_PAYLOAD_START_INDEX], RAW_MAC_PAYLOAD_LENGTH) != 0) { - NET_ERR("*** Payload of sent packet is incorrect\n"); + NET_ERR("*** Payload of sent packet is incorrect"); goto release_frag; } @@ -993,7 +993,7 @@ static bool test_raw_packet_reception(void) result = false; - NET_INFO("- Receiving RAW packet via AF_PACKET socket\n"); + NET_INFO("- Receiving RAW packet via AF_PACKET socket"); fd = set_up_recv_socket(SOCK_RAW); if (fd < 0) { @@ -1002,13 +1002,13 @@ static bool test_raw_packet_reception(void) pkt = net_pkt_rx_alloc(K_FOREVER); if (!pkt) { - NET_ERR("*** Failed to allocate net pkt.\n"); + NET_ERR("*** Failed to allocate net pkt."); goto release_fd; } frame_buf = net_pkt_get_frag(pkt, sizeof(raw_payload), K_FOREVER); if (!frame_buf) { - NET_ERR("*** Failed to allocate net pkt frag.\n"); + NET_ERR("*** Failed to allocate net pkt frag."); goto release_pkt; } @@ -1016,12 +1016,12 @@ static bool test_raw_packet_reception(void) net_pkt_frag_add(pkt, frame_buf); if (net_recv_data(net_iface, pkt)) { - NET_ERR("*** Error while processing packet.\n"); + NET_ERR("*** Error while processing packet."); goto release_pkt; } if (current_pkt->frags) { - NET_ERR("*** Generated unexpected packet when processing packet.\n"); + NET_ERR("*** Generated unexpected packet when processing packet."); net_pkt_frag_unref(current_pkt->frags); current_pkt->frags = NULL; goto release_pkt; @@ -1033,7 +1033,7 @@ static bool test_raw_packet_reception(void) */ received_len = recv(fd, received_payload, sizeof(received_payload), 0); if (received_len < 0) { - NET_ERR("*** Failed to receive packet, errno %d\n", errno); + NET_ERR("*** Failed to receive packet, errno %d", errno); goto release_pkt; } @@ -1049,7 +1049,7 @@ static bool test_raw_packet_reception(void) */ if (received_len != sizeof(raw_payload) || memcmp(received_payload, raw_payload, sizeof(raw_payload))) { - NET_ERR("*** Payload of received packet is incorrect\n"); + NET_ERR("*** Payload of received packet is incorrect"); goto release_pkt; } @@ -1106,21 +1106,21 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) int received_len; int fd; - NET_INFO("- Sending ACK reply to a data packet\n"); + NET_INFO("- Sending ACK reply to a data packet"); fd = socket(AF_PACKET, SOCK_DGRAM, ETH_P_IEEE802154); if (fd < 0) { - NET_ERR("*** Failed to create DGRAM socket : %d\n", errno); + NET_ERR("*** Failed to create DGRAM socket : %d", errno); goto out; } if (bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) { - NET_ERR("*** Failed to bind packet socket : %d\n", errno); + NET_ERR("*** Failed to bind packet socket : %d", errno); goto release_fd; } if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) { - NET_ERR("*** Failed to set reception timeout on packet socket : %d\n", errno); + NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno); goto release_fd; } @@ -1142,7 +1142,7 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) received_len = recvfrom(fd, received_payload, sizeof(received_payload), 0, (struct sockaddr *)&recv_src_sll, &recv_src_sll_len); if (received_len < 0) { - NET_ERR("*** Failed to receive packet, errno %d\n", errno); + NET_ERR("*** Failed to receive packet, errno %d", errno); goto release_rx_pkt; } @@ -1152,7 +1152,7 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) recv_src_sll.sll_family != AF_PACKET || recv_src_sll.sll_protocol != ETH_P_IEEE802154 || recv_src_sll.sll_halen != IEEE802154_EXT_ADDR_LENGTH || memcmp(recv_src_sll.sll_addr, mac_be, IEEE802154_EXT_ADDR_LENGTH)) { - NET_ERR("*** Received socket address does not compare\n", errno); + NET_ERR("*** Received socket address does not compare", errno); goto release_rx_pkt; } @@ -1160,7 +1160,7 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) if (memcmp(expected_rx_pkt, received_payload, sizeof(expected_rx_pkt))) { - NET_ERR("*** Received uncompressed IPv6 payload does not compare\n"); + NET_ERR("*** Received uncompressed IPv6 payload does not compare"); goto release_rx_pkt; } @@ -1169,7 +1169,7 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) /* an ACK packet should be in current_pkt */ if (!current_pkt->frags) { - NET_ERR("*** No ACK reply sent\n"); + NET_ERR("*** No ACK reply sent"); goto release_rx_pkt; } @@ -1177,18 +1177,18 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt), &mpdu)) { - NET_ERR("*** ACK Reply is invalid\n"); + NET_ERR("*** ACK Reply is invalid"); goto release_tx_frag; } if (memcmp(mpdu.mhr.fs, t->mhr_check.fc_seq, sizeof(struct ieee802154_fcf_seq))) { - NET_ERR("*** ACK Reply does not compare\n"); + NET_ERR("*** ACK Reply does not compare"); goto release_tx_frag; } if (mpdu.mhr.fs->sequence != t->sequence) { - NET_ERR("*** Sequence number invalid\n"); + NET_ERR("*** Sequence number invalid"); goto release_tx_frag; } @@ -1217,29 +1217,29 @@ static bool initialize_test_environment(void) current_pkt = net_pkt_rx_alloc(K_FOREVER); if (!current_pkt) { - NET_ERR("*** No buffer to allocate\n"); + NET_ERR("*** No buffer to allocate"); return false; } dev = device_get_binding("fake_ieee802154"); if (!dev) { - NET_ERR("*** Could not get fake device\n"); + NET_ERR("*** Could not get fake device"); goto release_pkt; } net_iface = net_if_lookup_by_dev(dev); if (!net_iface) { - NET_ERR("*** Could not get fake iface\n"); + NET_ERR("*** Could not get fake iface"); goto release_pkt; } if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, net_iface, &mock_pan_id, sizeof(mock_pan_id))) { - NET_ERR("*** Failed to set PAN ID in %s.\n", __func__); + NET_ERR("*** Failed to set PAN ID in %s.", __func__); goto release_pkt; } - NET_INFO("Fake IEEE 802.15.4 network interface ready\n"); + NET_INFO("Fake IEEE 802.15.4 network interface ready"); ieee_addr_hexdump(net_if_get_link_addr(net_iface)->addr, 8); From 8b2dd61ebab8af6a1c17abee4b565f1d1c8222b6 Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Mon, 6 Nov 2023 14:49:08 +0100 Subject: [PATCH 3191/4498] Bluetooth: HCI: Add bt_hci_get_ver_str() This new API returns the version string corresponding to a given HCI version. The API can be used by applications to print out human-readable information about the controller being used. Adding this API removes possible code duplication. Signed-off-by: Rubin Gerritsen --- include/zephyr/bluetooth/hci.h | 13 +++++++++++++ subsys/bluetooth/host/hci_core.c | 10 +++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 8dd7434e445..258f86519b6 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -97,6 +97,19 @@ int bt_hci_get_conn_handle(const struct bt_conn *conn, uint16_t *conn_handle); */ int bt_hci_get_adv_handle(const struct bt_le_ext_adv *adv, uint8_t *adv_handle); +/** @brief Obtain the version string given a core version number. + * + * The core version of a controller can be obtained by issuing + * the HCI Read Local Version Information command. + * + * See also the defines prefixed with BT_HCI_VERSION_. + * + * @param core_version The core version. + * + * @return Version string corresponding to the core version number. + */ +const char *bt_hci_get_ver_str(uint8_t core_version); + /** @typedef bt_hci_vnd_evt_cb_t * @brief Callback type for vendor handling of HCI Vendor-Specific Events. * diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 5dd68da4dce..51f9ac8d211 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3440,15 +3440,15 @@ static int set_event_mask(void) return bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL); } -static const char *ver_str(uint8_t ver) +const char *bt_hci_get_ver_str(uint8_t core_version) { const char * const str[] = { "1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2", "5.3", "5.4" }; - if (ver < ARRAY_SIZE(str)) { - return str[ver]; + if (core_version < ARRAY_SIZE(str)) { + return str[core_version]; } return "unknown"; @@ -3489,9 +3489,9 @@ static void bt_dev_show_info(void) } LOG_INF("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x", - ver_str(bt_dev.hci_version), bt_dev.hci_version, bt_dev.hci_revision, + bt_hci_get_ver_str(bt_dev.hci_version), bt_dev.hci_version, bt_dev.hci_revision, bt_dev.manufacturer); - LOG_INF("LMP: version %s (0x%02x) subver 0x%04x", ver_str(bt_dev.lmp_version), + LOG_INF("LMP: version %s (0x%02x) subver 0x%04x", bt_hci_get_ver_str(bt_dev.lmp_version), bt_dev.lmp_version, bt_dev.lmp_subversion); } From 9e58ad31e915cadcdd33e23ecad6a779d5fa50a5 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 6 Nov 2023 14:58:34 +0100 Subject: [PATCH 3192/4498] tests: Bluetooth: BAP Broadcast sink RX fail fix Added an additional check before failing a BSIM test on ISO error, so that when we stop the broadcast source (after the sink have received the expected data), lost data does not trigger a test failure. Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index 0e5d1d94fb6..70e2e74d738 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -280,7 +280,11 @@ static void recv_cb(struct bt_bap_stream *stream, } if (info->flags & BT_ISO_FLAGS_ERROR) { - FAIL("ISO receive error\n"); + /* Fail the test if we have not received what we expected */ + if (!TEST_FLAG(flag_received)) { + FAIL("ISO receive error\n"); + } + return; } From 133f20abc58bc195fe92e131cbdc1f0b3b566e27 Mon Sep 17 00:00:00 2001 From: Daniel Mangum Date: Tue, 7 Nov 2023 00:57:36 -0500 Subject: [PATCH 3193/4498] docs: rpi_pico: fix typo in SPI PIO sample Fixes minor typo in the SPI via PIO sample documentation. Signed-off-by: Daniel Mangum --- boards/arm/rpi_pico/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/rpi_pico/doc/index.rst b/boards/arm/rpi_pico/doc/index.rst index 2fb41387864..c94698f14fe 100644 --- a/boards/arm/rpi_pico/doc/index.rst +++ b/boards/arm/rpi_pico/doc/index.rst @@ -140,7 +140,7 @@ Zephyr does not (currently) assemble PIO programs. Rather, they should be manually assembled and embedded in source code. An example of how this is done can be found at `drivers/serial/uart_rpi_pico_pio.c`. -Sample: SPI vio PIO +Sample: SPI via PIO ==================== The :zephyr_file:`samples/sensor/bme280/README.rst` sample includes a From bfff0f9f4cdf8f32454c87b0c15a16be4ca1fc4f Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Thu, 26 Oct 2023 17:10:48 +0200 Subject: [PATCH 3194/4498] Bluetooth: Host: Tests: Move testlib to common This is the first patch with the goal of establishing a common library for Bluetooth utilities that are commonly used for setup in Bluetooth Host tests. The ultimate goal is to remove redundant (near) copies of these utilities and other more ad-hoc solutions. This patch moves one instance of testlib (from tests/bsim/bluetooth/host/att/long_read) to tests/bluetooth/common/testlib and makes it a proper CMake library. The long_read test is updated to link to the new CMake library. Further changes and de-duplication will come in later patches. Signed-off-by: Aleksander Wasaznik --- tests/bluetooth/common/testlib/CMakeLists.txt | 24 +++++++++++++++++++ .../common/testlib/include/testlib/adv.h | 12 ++++++++++ .../testlib/include}/testlib/att_read.h | 11 ++++++--- .../testlib/include}/testlib/att_write.h | 5 ++++ .../testlib/include}/testlib/conn_ref.h | 5 ++++ .../testlib/include/testlib/conn_wait.h | 12 ++++++++++ .../common/testlib/include/testlib/connect.h | 12 ++++++++++ .../testlib/include}/testlib/log_utils.h | 5 ++++ .../common/testlib/include/testlib/scan.h | 12 ++++++++++ .../common/testlib/include/testlib/security.h | 12 ++++++++++ .../common/testlib/src}/adv.c | 0 .../common/testlib/src}/att_read.c | 10 ++++---- .../common/testlib/src}/att_write.c | 2 +- .../common/testlib/src}/conn_wait.c | 6 ++--- .../common/testlib/src}/connect.c | 4 ++-- .../common/testlib/src}/scan.c | 12 +++++----- .../common/testlib/src}/security.c | 2 +- .../host/att/long_read/CMakeLists.txt | 17 +++++++------ .../att/long_read/{testlib => }/bs_macro.h | 0 .../att/long_read/{testlib => }/bs_main.c | 0 .../att/long_read/{testlib => }/bs_sync.c | 0 .../att/long_read/{testlib => }/bs_sync.h | 0 .../bsim/bluetooth/host/att/long_read/main.c | 10 ++++---- .../host/att/long_read/testlib/adv.h | 7 ------ .../host/att/long_read/testlib/conn_wait.h | 4 ---- .../host/att/long_read/testlib/connect.h | 7 ------ .../host/att/long_read/testlib/scan.h | 7 ------ .../host/att/long_read/testlib/security.h | 7 ------ 28 files changed, 138 insertions(+), 67 deletions(-) create mode 100644 tests/bluetooth/common/testlib/CMakeLists.txt create mode 100644 tests/bluetooth/common/testlib/include/testlib/adv.h rename tests/{bsim/bluetooth/host/att/long_read => bluetooth/common/testlib/include}/testlib/att_read.h (79%) rename tests/{bsim/bluetooth/host/att/long_read => bluetooth/common/testlib/include}/testlib/att_write.h (54%) rename tests/{bsim/bluetooth/host/att/long_read => bluetooth/common/testlib/include}/testlib/conn_ref.h (83%) create mode 100644 tests/bluetooth/common/testlib/include/testlib/conn_wait.h create mode 100644 tests/bluetooth/common/testlib/include/testlib/connect.h rename tests/{bsim/bluetooth/host/att/long_read => bluetooth/common/testlib/include}/testlib/log_utils.h (82%) create mode 100644 tests/bluetooth/common/testlib/include/testlib/scan.h create mode 100644 tests/bluetooth/common/testlib/include/testlib/security.h rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/adv.c (100%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/att_read.c (97%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/att_write.c (96%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/conn_wait.c (89%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/connect.c (95%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/scan.c (89%) rename tests/{bsim/bluetooth/host/att/long_read/testlib => bluetooth/common/testlib/src}/security.c (98%) rename tests/bsim/bluetooth/host/att/long_read/{testlib => }/bs_macro.h (100%) rename tests/bsim/bluetooth/host/att/long_read/{testlib => }/bs_main.c (100%) rename tests/bsim/bluetooth/host/att/long_read/{testlib => }/bs_sync.c (100%) rename tests/bsim/bluetooth/host/att/long_read/{testlib => }/bs_sync.h (100%) delete mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/adv.h delete mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h delete mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/connect.h delete mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/scan.h delete mode 100644 tests/bsim/bluetooth/host/att/long_read/testlib/security.h diff --git a/tests/bluetooth/common/testlib/CMakeLists.txt b/tests/bluetooth/common/testlib/CMakeLists.txt new file mode 100644 index 00000000000..7166abd3e06 --- /dev/null +++ b/tests/bluetooth/common/testlib/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_library(testlib) + +target_link_libraries(testlib PUBLIC + kernel + subsys__bluetooth__host + zephyr_interface +) + +target_include_directories(testlib PUBLIC + include +) + +target_sources(testlib PRIVATE + src/adv.c + src/att_read.c + src/att_write.c + src/connect.c + src/conn_wait.c + src/scan.c + src/security.c +) diff --git a/tests/bluetooth/common/testlib/include/testlib/adv.h b/tests/bluetooth/common/testlib/include/testlib/adv.h new file mode 100644 index 00000000000..2b326802b1c --- /dev/null +++ b/tests/bluetooth/common/testlib/include/testlib/adv.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ADV_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ADV_H_ + +#include + +int bt_testlib_adv_conn(struct bt_conn **conn, int id, uint32_t adv_options); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ADV_H_ */ diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h b/tests/bluetooth/common/testlib/include/testlib/att_read.h similarity index 79% rename from tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h rename to tests/bluetooth/common/testlib/include/testlib/att_read.h index ced1265289d..6e12d441e4e 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.h +++ b/tests/bluetooth/common/testlib/include/testlib/att_read.h @@ -2,6 +2,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_READ_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_READ_H_ + #include #include @@ -20,9 +23,9 @@ int bt_testlib_att_read_by_handle_sync(struct net_buf_simple *result_data, uint1 enum bt_att_chan_opt bearer, uint16_t handle, uint16_t offset); -int btt_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, - struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, - uint16_t offset); +int bt_testlib_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, + struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset); int bt_testlib_gatt_discover_primary(uint16_t *result_handle, uint16_t *result_end_handle, struct bt_conn *conn, const struct bt_uuid *uuid, @@ -37,3 +40,5 @@ int bt_testlib_gatt_discover_characteristic(uint16_t *const result_value_handle, uint16_t *const result_def_handle, struct bt_conn *conn, const struct bt_uuid *uuid, uint16_t start_handle, uint16_t svc_end_handle); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_READ_H_ */ diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h b/tests/bluetooth/common/testlib/include/testlib/att_write.h similarity index 54% rename from tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h rename to tests/bluetooth/common/testlib/include/testlib/att_write.h index 9bf063d3bd4..0cfd03e88b6 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.h +++ b/tests/bluetooth/common/testlib/include/testlib/att_write.h @@ -2,8 +2,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_WRITE_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_WRITE_H_ + #include #include int bt_testlib_att_write(struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, const uint8_t *data, uint16_t size); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_ATT_WRITE_H_ */ diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h b/tests/bluetooth/common/testlib/include/testlib/conn_ref.h similarity index 83% rename from tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h rename to tests/bluetooth/common/testlib/include/testlib/conn_ref.h index c9978b635dc..9e96eb3fc40 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_ref.h +++ b/tests/bluetooth/common/testlib/include/testlib/conn_ref.h @@ -2,6 +2,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_REF_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_REF_H_ + #include #include @@ -35,3 +38,5 @@ void bt_testlib_conn_unref(struct bt_conn **connp) __ASSERT_NO_MSG(conn); bt_conn_unref(conn); } + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_REF_H_ */ diff --git a/tests/bluetooth/common/testlib/include/testlib/conn_wait.h b/tests/bluetooth/common/testlib/include/testlib/conn_wait.h new file mode 100644 index 00000000000..00f8ddb5cdc --- /dev/null +++ b/tests/bluetooth/common/testlib/include/testlib/conn_wait.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_WAIT_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_WAIT_H_ +#include + +int bt_testlib_wait_connected(struct bt_conn *conn); +int bt_testlib_wait_disconnected(struct bt_conn *conn); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_WAIT_H_ */ diff --git a/tests/bluetooth/common/testlib/include/testlib/connect.h b/tests/bluetooth/common/testlib/include/testlib/connect.h new file mode 100644 index 00000000000..912e4d0cdc7 --- /dev/null +++ b/tests/bluetooth/common/testlib/include/testlib/connect.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONNECT_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONNECT_H_ + +#include + +int bt_testlib_connect(const bt_addr_le_t *peer, struct bt_conn **conn); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONNECT_H_ */ diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h b/tests/bluetooth/common/testlib/include/testlib/log_utils.h similarity index 82% rename from tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h rename to tests/bluetooth/common/testlib/include/testlib/log_utils.h index c3825246bb9..66cd2c0a2f7 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/log_utils.h +++ b/tests/bluetooth/common/testlib/include/testlib/log_utils.h @@ -2,6 +2,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_LOG_UTILS_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_LOG_UTILS_H_ + #include #include @@ -34,3 +37,5 @@ static inline void bt_testlib_log_level_set_all(uint32_t new_level) __ASSERT(result_level == new_level, "%u %u", result_level, new_level); } } + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_LOG_UTILS_H_ */ diff --git a/tests/bluetooth/common/testlib/include/testlib/scan.h b/tests/bluetooth/common/testlib/include/testlib/scan.h new file mode 100644 index 00000000000..d68f3aba684 --- /dev/null +++ b/tests/bluetooth/common/testlib/include/testlib/scan.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SCAN_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SCAN_H_ + +#include + +int bt_testlib_scan_find_name(bt_addr_le_t *result, const char *name); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SCAN_H_ */ diff --git a/tests/bluetooth/common/testlib/include/testlib/security.h b/tests/bluetooth/common/testlib/include/testlib/security.h new file mode 100644 index 00000000000..9950f5f71b9 --- /dev/null +++ b/tests/bluetooth/common/testlib/include/testlib/security.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SECURITY_H_ +#define ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SECURITY_H_ + +#include + +int bt_testlib_secure(struct bt_conn *conn, bt_security_t new_minimum); + +#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_SECURITY_H_ */ diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/adv.c b/tests/bluetooth/common/testlib/src/adv.c similarity index 100% rename from tests/bsim/bluetooth/host/att/long_read/testlib/adv.c rename to tests/bluetooth/common/testlib/src/adv.c diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c b/tests/bluetooth/common/testlib/src/att_read.c similarity index 97% rename from tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c rename to tests/bluetooth/common/testlib/src/att_read.c index b418aed440a..5e4990f02b5 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/att_read.c +++ b/tests/bluetooth/common/testlib/src/att_read.c @@ -12,10 +12,10 @@ #include #include -#include "att_read.h" +#include #include -LOG_MODULE_REGISTER(att_read, LOG_LEVEL_DBG); +LOG_MODULE_REGISTER(bt_testlib_att_read, LOG_LEVEL_DBG); struct bt_testlib_att_read_closure { uint8_t att_err; @@ -161,9 +161,9 @@ int bt_testlib_att_read_by_handle_sync(struct net_buf_simple *result_data, uint1 return bt_testlib_sync_bt_gatt_read(&ctx); } -int btt_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, - struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, - uint16_t offset) +int bt_testlib_gatt_long_read(struct net_buf_simple *result_data, uint16_t *result_size, + struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle, + uint16_t offset) { int err; uint16_t _result_data_size = 0; diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c b/tests/bluetooth/common/testlib/src/att_write.c similarity index 96% rename from tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c rename to tests/bluetooth/common/testlib/src/att_write.c index a82269e1301..8da01ea233a 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/att_write.c +++ b/tests/bluetooth/common/testlib/src/att_write.c @@ -13,7 +13,7 @@ #include #include -LOG_MODULE_REGISTER(att_write, LOG_LEVEL_DBG); +LOG_MODULE_REGISTER(bt_testlib_att_write, LOG_LEVEL_DBG); struct bt_testlib_att_write_closure { uint8_t att_err; diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c b/tests/bluetooth/common/testlib/src/conn_wait.c similarity index 89% rename from tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c rename to tests/bluetooth/common/testlib/src/conn_wait.c index 7edd12a699b..a99b47a0edc 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.c +++ b/tests/bluetooth/common/testlib/src/conn_wait.c @@ -14,12 +14,12 @@ #include #include -LOG_MODULE_REGISTER(conn_wait, LOG_LEVEL_DBG); +LOG_MODULE_REGISTER(bt_testlib_conn_wait, LOG_LEVEL_DBG); static K_MUTEX_DEFINE(conn_wait_mutex); static K_CONDVAR_DEFINE(something_changed); -void on_change(struct bt_conn *conn, uint8_t err) +static void on_change(struct bt_conn *conn, uint8_t err) { k_mutex_lock(&conn_wait_mutex, K_FOREVER); k_condvar_broadcast(&something_changed); @@ -31,7 +31,7 @@ BT_CONN_CB_DEFINE(conn_callbacks) = { .disconnected = on_change, }; -enum bt_conn_state bt_conn_state(struct bt_conn *conn) +static enum bt_conn_state bt_conn_state(struct bt_conn *conn) { int err; struct bt_conn_info info; diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.c b/tests/bluetooth/common/testlib/src/connect.c similarity index 95% rename from tests/bsim/bluetooth/host/att/long_read/testlib/connect.c rename to tests/bluetooth/common/testlib/src/connect.c index ddfa81de9ce..afb4b9c271d 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.c +++ b/tests/bluetooth/common/testlib/src/connect.c @@ -7,9 +7,9 @@ #include #include -#include "connect.h" +#include -LOG_MODULE_REGISTER(testlib_connect, LOG_LEVEL_INF); +LOG_MODULE_REGISTER(bt_testlib_connect, LOG_LEVEL_INF); struct bt_testlib_connect_closure { uint8_t conn_err; diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.c b/tests/bluetooth/common/testlib/src/scan.c similarity index 89% rename from tests/bsim/bluetooth/host/att/long_read/testlib/scan.c rename to tests/bluetooth/common/testlib/src/scan.c index 337dfef15ca..a06ce5d3bf7 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.c +++ b/tests/bluetooth/common/testlib/src/scan.c @@ -8,12 +8,12 @@ #include #include -#include "scan.h" +#include -LOG_MODULE_REGISTER(testlib_scan, LOG_LEVEL_INF); +LOG_MODULE_REGISTER(bt_testlib_scan, LOG_LEVEL_INF); struct bt_scan_find_name_closure { - char *wanted_name; + const char *wanted_name; bt_addr_le_t *result; struct k_condvar done; }; @@ -25,7 +25,7 @@ static struct bt_scan_find_name_closure *g_ctx; static bool bt_scan_find_name_cb_data_cb(struct bt_data *data, void *user_data) { - char **wanted = user_data; + const char **wanted = user_data; if (data->type == BT_DATA_NAME_COMPLETE) { if (data->data_len == strlen(*wanted) && @@ -43,7 +43,7 @@ static bool bt_scan_find_name_cb_data_cb(struct bt_data *data, void *user_data) static void bt_scan_find_name_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, struct net_buf_simple *buf) { - char *wanted; + const char *wanted; k_mutex_lock(&g_ctx_lock, K_FOREVER); @@ -63,7 +63,7 @@ static void bt_scan_find_name_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t k_mutex_unlock(&g_ctx_lock); } -int bt_testlib_scan_find_name(bt_addr_le_t *result, char name[]) +int bt_testlib_scan_find_name(bt_addr_le_t *result, const char *name) { int api_err; struct bt_scan_find_name_closure ctx = { diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/security.c b/tests/bluetooth/common/testlib/src/security.c similarity index 98% rename from tests/bsim/bluetooth/host/att/long_read/testlib/security.c rename to tests/bluetooth/common/testlib/src/security.c index e7de704acee..a229cf5487c 100644 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/security.c +++ b/tests/bluetooth/common/testlib/src/security.c @@ -12,7 +12,7 @@ #include #include -LOG_MODULE_REGISTER(testlib_security, LOG_LEVEL_INF); +LOG_MODULE_REGISTER(bt_testlib_security, LOG_LEVEL_INF); struct testlib_security_ctx { enum bt_security_err result; diff --git a/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt b/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt index 04bd6641153..0f6727fd5a4 100644 --- a/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt +++ b/tests/bsim/bluetooth/host/att/long_read/CMakeLists.txt @@ -5,16 +5,11 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(app) +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/common/testlib testlib) + target_sources(app PRIVATE - testlib/bs_main.c - testlib/adv.c - testlib/connect.c - testlib/scan.c - testlib/security.c - testlib/att_read.c - testlib/att_write.c - testlib/bs_sync.c - testlib/conn_wait.c + bs_main.c + bs_sync.c main.c ) @@ -22,3 +17,7 @@ zephyr_include_directories( ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ ) + +target_link_libraries(app PRIVATE + testlib +) diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h b/tests/bsim/bluetooth/host/att/long_read/bs_macro.h similarity index 100% rename from tests/bsim/bluetooth/host/att/long_read/testlib/bs_macro.h rename to tests/bsim/bluetooth/host/att/long_read/bs_macro.h diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c b/tests/bsim/bluetooth/host/att/long_read/bs_main.c similarity index 100% rename from tests/bsim/bluetooth/host/att/long_read/testlib/bs_main.c rename to tests/bsim/bluetooth/host/att/long_read/bs_main.c diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c b/tests/bsim/bluetooth/host/att/long_read/bs_sync.c similarity index 100% rename from tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.c rename to tests/bsim/bluetooth/host/att/long_read/bs_sync.c diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h b/tests/bsim/bluetooth/host/att/long_read/bs_sync.h similarity index 100% rename from tests/bsim/bluetooth/host/att/long_read/testlib/bs_sync.h rename to tests/bsim/bluetooth/host/att/long_read/bs_sync.h diff --git a/tests/bsim/bluetooth/host/att/long_read/main.c b/tests/bsim/bluetooth/host/att/long_read/main.c index ad99d298a56..29a3de0a9e6 100644 --- a/tests/bsim/bluetooth/host/att/long_read/main.c +++ b/tests/bsim/bluetooth/host/att/long_read/main.c @@ -13,8 +13,8 @@ #include "testlib/adv.h" #include "testlib/att_read.h" #include "testlib/att_write.h" -#include "testlib/bs_macro.h" -#include "testlib/bs_sync.h" +#include "bs_macro.h" +#include "bs_sync.h" #include "testlib/conn_ref.h" #include "testlib/conn_wait.h" #include "testlib/connect.h" @@ -25,7 +25,7 @@ /* This test uses system asserts to fail tests. */ BUILD_ASSERT(__ASSERT_ON); -#define CENTRAL_DEVICE_NBR 0 +#define CENTRAL_DEVICE_NBR 0 #define PERIPHERAL_DEVICE_NBR 1 LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); @@ -146,8 +146,8 @@ static void test_long_read(enum bt_att_chan_opt bearer, uint16_t chrc_value_hand NET_BUF_SIMPLE_DEFINE(attr_value_buf, BT_ATT_MAX_ATTRIBUTE_LEN); /* Perform the whole long read operation. */ - EXPECT_ZERO(btt_gatt_long_read(&attr_value_buf, NULL, conn, bearer, - chrc_value_handle, 0)); + EXPECT_ZERO(bt_testlib_gatt_long_read(&attr_value_buf, NULL, conn, bearer, + chrc_value_handle, 0)); /* Parse the read attribute value to verify the * integrity of the transfer. diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h b/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h deleted file mode 100644 index a9d429d5ad2..00000000000 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/adv.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -int bt_testlib_adv_conn(struct bt_conn **conn, int id, uint32_t adv_options); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h b/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h deleted file mode 100644 index d28b150aebc..00000000000 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/conn_wait.h +++ /dev/null @@ -1,4 +0,0 @@ -#include - -int bt_testlib_wait_connected(struct bt_conn *conn); -int bt_testlib_wait_disconnected(struct bt_conn *conn); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h b/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h deleted file mode 100644 index e8da223849a..00000000000 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/connect.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -int bt_testlib_connect(const bt_addr_le_t *peer, struct bt_conn **conn); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h b/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h deleted file mode 100644 index 58c887c21c9..00000000000 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/scan.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -int bt_testlib_scan_find_name(bt_addr_le_t *result, char name[]); diff --git a/tests/bsim/bluetooth/host/att/long_read/testlib/security.h b/tests/bsim/bluetooth/host/att/long_read/testlib/security.h deleted file mode 100644 index 8b7dd46423c..00000000000 --- a/tests/bsim/bluetooth/host/att/long_read/testlib/security.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -int bt_testlib_secure(struct bt_conn *conn, bt_security_t new_minimum); From 8b456ea2a12c96f65ab63c19f31e077448af3ad6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 6 Nov 2023 11:42:07 +0100 Subject: [PATCH 3195/4498] treewide: Replace all uses of CONCAT with _CONCAT One of the ARM architure files, defined since long ago CONCAT having the exact same purpose as Zephyr's _CONCAT. Unfortunately this header is included almost always and the macro defined in all ARM based platforms, which seems to have lead to many uses of this macro instead of _CONCAT. Fix it by using _CONCAT instead. Signed-off-by: Alberto Escolar Piedras --- drivers/ethernet/eth_nxp_s32_gmac.c | 4 ++-- drivers/memc/memc_nxp_s32_qspi.c | 8 ++++---- drivers/watchdog/wdt_nxp_fs26.c | 8 ++++---- include/zephyr/arch/arm/irq.h | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/ethernet/eth_nxp_s32_gmac.c b/drivers/ethernet/eth_nxp_s32_gmac.c index 423f2b1499e..428a57c6065 100644 --- a/drivers/ethernet/eth_nxp_s32_gmac.c +++ b/drivers/ethernet/eth_nxp_s32_gmac.c @@ -564,7 +564,7 @@ BUILD_ASSERT((CONFIG_ETH_NXP_S32_TX_RING_BUF_SIZE % FEATURE_GMAC_DATA_BUS_WIDTH_ #define ETH_NXP_S32_MAC_SPEED(n) \ COND_CODE_1(ETH_NXP_S32_IS_FIXED_LINK(n), \ - (CONCAT(CONCAT(GMAC_SPEED_, ETH_NXP_S32_FIXED_LINK_SPEED(n)), M)), \ + (_CONCAT(_CONCAT(GMAC_SPEED_, ETH_NXP_S32_FIXED_LINK_SPEED(n)), M)), \ (GMAC_SPEED_100M)) #define ETH_NXP_S32_MAC_DUPLEX(n) \ @@ -574,7 +574,7 @@ BUILD_ASSERT((CONFIG_ETH_NXP_S32_TX_RING_BUF_SIZE % FEATURE_GMAC_DATA_BUS_WIDTH_ (GMAC_FULL_DUPLEX)) #define ETH_NXP_S32_MAC_MII(n) \ - CONCAT(CONCAT(GMAC_, DT_INST_STRING_UPPER_TOKEN(n, phy_connection_type)), _MODE) + _CONCAT(_CONCAT(GMAC_, DT_INST_STRING_UPPER_TOKEN(n, phy_connection_type)), _MODE) #define ETH_NXP_S32_IRQ_INIT(n, name) \ IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, name, irq), \ diff --git a/drivers/memc/memc_nxp_s32_qspi.c b/drivers/memc/memc_nxp_s32_qspi.c index b2dc1466d6f..f588a0bd9af 100644 --- a/drivers/memc/memc_nxp_s32_qspi.c +++ b/drivers/memc/memc_nxp_s32_qspi.c @@ -78,7 +78,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) #define QSPI_DATA_CFG(n) \ IF_ENABLED(FEATURE_QSPI_DDR, ( \ - .dataRate = CONCAT(QSPI_IP_DATA_RATE_, \ + .dataRate = _CONCAT(QSPI_IP_DATA_RATE_, \ DT_INST_STRING_UPPER_TOKEN(n, data_rate)), \ .dataAlign = COND_CODE_1(DT_INST_PROP(n, hold_time_2x), \ (QSPI_IP_FLASH_DATA_ALIGN_2X_REFCLK), \ @@ -115,7 +115,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) #define QSPI_DLL_CFG(n, side, side_upper) \ IF_ENABLED(FEATURE_QSPI_HAS_DLL, ( \ .dllSettings##side_upper = { \ - .dllMode = CONCAT(QSPI_IP_DLL_, \ + .dllMode = _CONCAT(QSPI_IP_DLL_, \ DT_INST_STRING_UPPER_TOKEN(n, side##_dll_mode)), \ .freqEnable = DT_INST_PROP(n, side##_dll_freq_enable), \ .coarseDelay = DT_INST_PROP(n, side##_dll_coarse_delay), \ @@ -129,7 +129,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) )) #define QSPI_READ_MODE(n, side, side_upper) \ - CONCAT(QSPI_IP_READ_MODE_, DT_INST_STRING_UPPER_TOKEN(n, side##_rx_clock_source)) + _CONCAT(QSPI_IP_READ_MODE_, DT_INST_STRING_UPPER_TOKEN(n, side##_rx_clock_source)) #define QSPI_IDLE_SIGNAL_DRIVE(n, side, side_upper) \ IF_ENABLED(FEATURE_QSPI_CONFIGURABLE_ISD, ( \ @@ -160,7 +160,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) BUILD_ASSERT(DT_INST_PROP_LEN(n, ahb_buffers_sizes) == QSPI_IP_AHB_BUFFERS, \ "ahb-buffers-sizes must be of size QSPI_IP_AHB_BUFFERS"); \ BUILD_ASSERT( \ - CONCAT(FEATURE_QSPI_, DT_INST_STRING_UPPER_TOKEN(n, a_rx_clock_source)) == 1,\ + _CONCAT(FEATURE_QSPI_, DT_INST_STRING_UPPER_TOKEN(n, a_rx_clock_source)) == 1,\ "a-rx-clock-source source mode selected is not supported"); \ \ static const Qspi_Ip_ControllerConfigType \ diff --git a/drivers/watchdog/wdt_nxp_fs26.c b/drivers/watchdog/wdt_nxp_fs26.c index b821d01df96..f6aed5079e4 100644 --- a/drivers/watchdog/wdt_nxp_fs26.c +++ b/drivers/watchdog/wdt_nxp_fs26.c @@ -27,9 +27,9 @@ LOG_MODULE_REGISTER(wdt_nxp_fs26); #define FS26_INIT_FS_TIMEOUT_MS 1000U /* Helper macros to set register values from Kconfig options */ -#define WD_ERR_LIMIT(x) CONCAT(WD_ERR_LIMIT_, x) -#define WD_RFR_LIMIT(x) CONCAT(WD_RFR_LIMIT_, x) -#define WDW_PERIOD(x) CONCAT(CONCAT(WDW_PERIOD_, x), MS) +#define WD_ERR_LIMIT(x) _CONCAT(WD_ERR_LIMIT_, x) +#define WD_RFR_LIMIT(x) _CONCAT(WD_RFR_LIMIT_, x) +#define WDW_PERIOD(x) _CONCAT(_CONCAT(WDW_PERIOD_, x), MS) #define BAD_WD_REFRESH_ERROR_STRING(x) \ ((((x) & BAD_WD_DATA) ? "error in the data" : \ @@ -826,7 +826,7 @@ static const struct wdt_driver_api wdt_nxp_fs26_api = { static const struct wdt_nxp_fs26_config wdt_nxp_fs26_config_##n = { \ .spi = SPI_DT_SPEC_INST_GET(n, \ SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(32), 0), \ - .wd_type = CONCAT(FS26_WD_, DT_INST_STRING_UPPER_TOKEN(n, type)), \ + .wd_type = _CONCAT(FS26_WD_, DT_INST_STRING_UPPER_TOKEN(n, type)), \ .int_gpio = GPIO_DT_SPEC_INST_GET(n, int_gpios), \ }; \ \ diff --git a/include/zephyr/arch/arm/irq.h b/include/zephyr/arch/arm/irq.h index aafc56a19a7..e363b963803 100644 --- a/include/zephyr/arch/arm/irq.h +++ b/include/zephyr/arch/arm/irq.h @@ -241,7 +241,7 @@ extern void z_arm_irq_direct_dynamic_dispatch_no_reschedule(void); */ #define ARM_IRQ_DIRECT_DYNAMIC_CONNECT(irq_p, priority_p, flags_p, resch) \ IRQ_DIRECT_CONNECT(irq_p, priority_p, \ - CONCAT(z_arm_irq_direct_dynamic_dispatch_, resch), flags_p) + _CONCAT(z_arm_irq_direct_dynamic_dispatch_, resch), flags_p) #endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */ From e1a56058898dae2df5e35131d4d9908727c4ab83 Mon Sep 17 00:00:00 2001 From: Ingar Kulbrandstad Date: Mon, 6 Nov 2023 13:41:58 +0100 Subject: [PATCH 3196/4498] Bluetooth: Mesh: Remove experimental tag Remove experimental tag for Mesh Protocol v1.1, Mesh Model v1.1, Mesh DFU v1.0 and Mesh BLOB v1.0 features. Signed-off-by: Ingar Kulbrandstad --- subsys/bluetooth/mesh/Kconfig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 154bf0b5b50..a7155d8e514 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1049,13 +1049,10 @@ config BT_MESH_FRIEND_ADV_LATENCY endif # BT_MESH_FRIEND menuconfig BT_MESH_V1d1 - bool "Bluetooth mesh v1.1 support [EXPERIMENTAL]" - select EXPERIMENTAL + bool "Bluetooth mesh v1.1 support" help This option enables Bluetooth mesh v1.1 support. Bluetooth mesh v1.1 - is backward compatible with v1.0.1. The stack cannot be qualified - with this option enabled because the Bluetooth mesh v1.1 specification - is in a draft state. + is backward compatible with v1.0.1. config BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM bool "Support CMAC AES128 for OOB authentication" if BT_MESH_V1d1 From 2010d4d599a06419759813bf33e5b8f583d6fe64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 12 Oct 2023 15:09:31 +0200 Subject: [PATCH 3197/4498] nrfx_usbd: Copy nrfx usbd code to Zephyr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy nrfx_usbd code from zephyrproject-rtos/hal_nordic git revision d054a315eb888ba70e09e5f6decd4097b0276d1f. This enables us to refactor the code towards a native driver in a step by step manner where the smallest changes that bring biggest performance improvements are done early on. The code is not a vanilla copy from zephyrproject-rtos/hal_nordic. The code was reformated with clang-format to match project style. Manual modifications were done to change comments formatting, place constant comparisons on the right and add blank lines to pass Zephyr compliance check. Relicense to Apache 2.0. No functional changes. Signed-off-by: Tomasz Moń --- modules/hal_nordic/nrfx/nrfx_usbd.c | 2118 ++++++++++++++++++++ modules/hal_nordic/nrfx/nrfx_usbd.h | 828 ++++++++ modules/hal_nordic/nrfx/nrfx_usbd_errata.h | 58 + 3 files changed, 3004 insertions(+) create mode 100644 modules/hal_nordic/nrfx/nrfx_usbd.c create mode 100644 modules/hal_nordic/nrfx/nrfx_usbd.h create mode 100644 modules/hal_nordic/nrfx/nrfx_usbd_errata.h diff --git a/modules/hal_nordic/nrfx/nrfx_usbd.c b/modules/hal_nordic/nrfx/nrfx_usbd.c new file mode 100644 index 00000000000..886bf448ce2 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_usbd.c @@ -0,0 +1,2118 @@ +/* + * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#if NRFX_CHECK(NRFX_USBD_ENABLED) + +#include +#include "nrfx_usbd_errata.h" +#include + +#define NRFX_LOG_MODULE USBD +#include + +#ifndef NRFX_USBD_EARLY_DMA_PROCESS +/* Try to process DMA request when endpoint transmission has been detected + * and just after last EasyDMA has been processed. + * It speeds up the transmission a little (about 10% measured) + * with a cost of more CPU power used. + */ +#define NRFX_USBD_EARLY_DMA_PROCESS 1 +#endif + +#ifndef NRFX_USBD_STARTED_EV_ENABLE +#define NRFX_USBD_STARTED_EV_ENABLE 0 +#endif + +#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP +/* + * Respond to an IN token on ISO IN endpoint with ZLP when no data is ready. + */ +#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 +#endif + +#ifndef NRFX_USBD_ISO_DEBUG +/* Also generate information about ISOCHRONOUS events and transfers. + * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this + * option generates a lot of useless messages. + */ +#define NRFX_USBD_ISO_DEBUG 1 +#endif + +#ifndef NRFX_USBD_FAILED_TRANSFERS_DEBUG +/* Also generate debug information for failed transfers. + * It might be useful but may generate a lot of useless debug messages + * in some library usages (for example when transfer is generated and the + * result is used to check whatever endpoint was busy. + */ +#define NRFX_USBD_FAILED_TRANSFERS_DEBUG 1 +#endif + +#ifndef NRFX_USBD_DMAREQ_PROCESS_DEBUG +/* Generate additional messages that mark the status inside + * @ref usbd_dmareq_process. + * It is useful to debug library internals but may generate a lot of + * useless debug messages. + */ +#define NRFX_USBD_DMAREQ_PROCESS_DEBUG 1 +#endif + +#ifndef NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 +/* Anomaly 211 - Device remains in SUSPEND too long when host resumes + * a bus activity (sending SOF packets) without a RESUME condition. + */ +#define NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 0 +#endif + +/** + * @defgroup nrfx_usbd_int USB Device driver internal part + * @internal + * @ingroup nrfx_usbd + * + * This part contains auxiliary internal macros, variables and functions. + * @{ + */ + +/** + * @brief Assert endpoint number validity. + * + * Internal macro to be used during program creation in debug mode. + * Generates assertion if endpoint number is not valid. + * + * @param ep Endpoint number to validity check. + */ +#define NRFX_USBD_ASSERT_EP_VALID(ep) \ + NRFX_ASSERT( \ + ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) || \ + (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)))); + +/** + * @brief Lowest position of bit for IN endpoint. + * + * The first bit position corresponding to IN endpoint. + * @sa ep2bit bit2ep + */ +#define NRFX_USBD_EPIN_BITPOS_0 0 + +/** + * @brief Lowest position of bit for OUT endpoint. + * + * The first bit position corresponding to OUT endpoint + * @sa ep2bit bit2ep + */ +#define NRFX_USBD_EPOUT_BITPOS_0 16 + +/** + * @brief Input endpoint bits mask. + */ +#define NRFX_USBD_EPIN_BIT_MASK (0xFFFFU << NRFX_USBD_EPIN_BITPOS_0) + +/** + * @brief Output endpoint bits mask. + */ +#define NRFX_USBD_EPOUT_BIT_MASK (0xFFFFU << NRFX_USBD_EPOUT_BITPOS_0) + +/** + * @brief Isochronous endpoint bit mask + */ +#define USBD_EPISO_BIT_MASK \ + ((1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT8)) | \ + (1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN8))) + +/** + * @brief Auxiliary macro to change EP number into bit position. + * + * This macro is used by @ref ep2bit function but also for statically check + * the bitpos values integrity during compilation. + * + * @param[in] ep Endpoint number. + * @return Endpoint bit position. + */ +#define NRFX_USBD_EP_BITPOS(ep) \ + ((NRF_USBD_EPIN_CHECK(ep) ? NRFX_USBD_EPIN_BITPOS_0 : NRFX_USBD_EPOUT_BITPOS_0) + \ + NRF_USBD_EP_NR_GET(ep)) + +/** + * @brief Helper macro for creating an endpoint transfer event. + * + * @param[in] name Name of the created transfer event variable. + * @param[in] endpoint Endpoint number. + * @param[in] ep_stat Endpoint state to report. + * + * @return Initialized event constant variable. + */ +#define NRFX_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ + const nrfx_usbd_evt_t name = {NRFX_USBD_EVT_EPTRANSFER, \ + .data = {.eptransfer = {.ep = endpont, .status = ep_stat}}} + +/* Check it the bit positions values match defined DATAEPSTATUS bit positions */ +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos); +NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos); + +/** + * @brief Current driver state. + */ +static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; + +/** + * @brief Event handler for the driver. + * + * Event handler that would be called on events. + * + * @note Currently it cannot be null if any interrupt is activated. + */ +static nrfx_usbd_event_handler_t m_event_handler; + +/** + * @brief Detected state of the bus. + * + * Internal state changed in interrupts handling when + * RESUME or SUSPEND event is processed. + * + * Values: + * - true - bus suspended + * - false - ongoing normal communication on the bus + * + * @note This is only the bus state and does not mean that the peripheral is in suspend state. + */ +static volatile bool m_bus_suspend; + +/** + * @brief Internal constant that contains interrupts disabled in suspend state. + * + * Internal constant used in @ref nrfx_usbd_suspend_irq_config and @ref nrfx_usbd_active_irq_config + * functions. + */ +static const uint32_t m_irq_disabled_in_suspend = + NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | NRF_USBD_INT_ENDEPOUT0_MASK | + NRF_USBD_INT_EP0SETUP_MASK | NRF_USBD_INT_DATAEP_MASK; + +/** + * @brief Direction of last received Setup transfer. + * + * This variable is used to redirect internal setup data event + * into selected endpoint (IN or OUT). + */ +static nrfx_usbd_ep_t m_last_setup_dir; + +/** + * @brief Mark endpoint readiness for DMA transfer. + * + * Bits in this variable are cleared and set in interrupts. + * 1 means that endpoint is ready for DMA transfer. + * 0 means that DMA transfer cannot be performed on selected endpoint. + */ +static uint32_t m_ep_ready; + +/** + * @brief Mark endpoint with prepared data to transfer by DMA. + * + * This variable can be from any place in the code (interrupt or main thread). + * It would be cleared only from USBD interrupt. + * + * Mask prepared USBD data for transmission. + * It is cleared when no more data to transmit left. + */ +static nrfx_atomic_t m_ep_dma_waiting; + +/** + * @brief Current EasyDMA state. + * + * Single flag, updated only inside interrupts, that marks current EasyDMA state. + * In USBD there is only one DMA channel working in background, and new transfer + * cannot be started when there is ongoing transfer on any other channel. + */ +static bool m_dma_pending; + +/** + * @brief Tracks whether total bytes transferred by DMA is even or odd. + */ +static uint8_t m_dma_odd; + +/** + * @brief First time enabling after reset. Used in nRF52 errata 223. + */ +static bool m_first_enable = true; + +/** + * @brief The structure that would hold transfer configuration to every endpoint + * + * The structure that holds all the data required by the endpoint to proceed + * with LIST functionality and generate quick callback directly when data + * buffer is ready. + */ +typedef struct { + nrfx_usbd_handler_t handler; /*!< Handler for current transfer, function pointer. */ + void *p_context; /*!< Context for transfer handler. */ + size_t transfer_cnt; /*!< Number of transferred bytes in the current transfer. */ + uint16_t max_packet_size; /*!< Configured endpoint size. */ + nrfx_usbd_ep_status_t status; /*!< NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY */ + /*!< - this one is calculated. */ +} usbd_ep_state_t; + +/** + * @brief The array of transfer configurations for the endpoints. + * + * The status of the transfer on each endpoint. + */ +static struct { + usbd_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; /*!< Status for OUT endpoints. */ + usbd_ep_state_t ep_in[NRF_USBD_EPIN_CNT]; /*!< Status for IN endpoints. */ +} m_ep_state; + +/** + * @brief Status variables for integrated feeders. + * + * Current status for integrated feeders (IN transfers). + * Integrated feeders are used for default transfers: + * 1. Simple RAM transfer. + * 2. Simple flash transfer. + * 3. RAM transfer with automatic ZLP. + * 4. Flash transfer with automatic ZLP. + */ +nrfx_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; + +/** + * @brief Status variables for integrated consumers. + * + * Current status for integrated consumers. + * Currently one type of transfer is supported: + * 1. Transfer to RAM. + * + * Transfer is finished automatically when received data block is smaller + * than the endpoint buffer or all the required data is received. + */ +nrfx_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; + +/** + * @brief Buffer used to send data directly from FLASH. + * + * This is internal buffer that would be used to emulate the possibility + * to transfer data directly from FLASH. + * We do not have to care about the source of data when calling transfer functions. + * + * We do not need more buffers that one, because only one transfer can be pending + * at once. + */ +static uint32_t m_tx_buffer[NRFX_CEIL_DIV(NRFX_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))]; + +/* Early declaration. Documentation above definition. */ +static void usbd_dmareq_process(void); + +/** + * @brief Change endpoint number to endpoint event code. + * + * @param ep Endpoint number. + * + * @return Connected endpoint event code. + * + * Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE <<. + */ +static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + + static const nrf_usbd_event_t epin_endev[] = { + NRF_USBD_EVENT_ENDEPIN0, NRF_USBD_EVENT_ENDEPIN1, NRF_USBD_EVENT_ENDEPIN2, + NRF_USBD_EVENT_ENDEPIN3, NRF_USBD_EVENT_ENDEPIN4, NRF_USBD_EVENT_ENDEPIN5, + NRF_USBD_EVENT_ENDEPIN6, NRF_USBD_EVENT_ENDEPIN7, NRF_USBD_EVENT_ENDISOIN0}; + static const nrf_usbd_event_t epout_endev[] = { + NRF_USBD_EVENT_ENDEPOUT0, NRF_USBD_EVENT_ENDEPOUT1, NRF_USBD_EVENT_ENDEPOUT2, + NRF_USBD_EVENT_ENDEPOUT3, NRF_USBD_EVENT_ENDEPOUT4, NRF_USBD_EVENT_ENDEPOUT5, + NRF_USBD_EVENT_ENDEPOUT6, NRF_USBD_EVENT_ENDEPOUT7, NRF_USBD_EVENT_ENDISOOUT0}; + + return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; +} + +/** + * @brief Get interrupt mask for selected endpoint. + * + * @param[in] ep Endpoint number. + * + * @return Interrupt mask related to the EasyDMA transfer end for the + * chosen endpoint. + */ +static inline uint32_t nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + + static const uint8_t epin_bitpos[] = { + USBD_INTEN_ENDEPIN0_Pos, USBD_INTEN_ENDEPIN1_Pos, USBD_INTEN_ENDEPIN2_Pos, + USBD_INTEN_ENDEPIN3_Pos, USBD_INTEN_ENDEPIN4_Pos, USBD_INTEN_ENDEPIN5_Pos, + USBD_INTEN_ENDEPIN6_Pos, USBD_INTEN_ENDEPIN7_Pos, USBD_INTEN_ENDISOIN_Pos}; + static const uint8_t epout_bitpos[] = { + USBD_INTEN_ENDEPOUT0_Pos, USBD_INTEN_ENDEPOUT1_Pos, USBD_INTEN_ENDEPOUT2_Pos, + USBD_INTEN_ENDEPOUT3_Pos, USBD_INTEN_ENDEPOUT4_Pos, USBD_INTEN_ENDEPOUT5_Pos, + USBD_INTEN_ENDEPOUT6_Pos, USBD_INTEN_ENDEPOUT7_Pos, USBD_INTEN_ENDISOOUT_Pos}; + + return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos + : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)]; +} + +/** + * @name Integrated feeders and consumers + * + * Internal, default functions for transfer processing. + * @{ + */ + +/** + * @brief Integrated consumer to RAM buffer. + * + * @param p_next See @ref nrfx_usbd_consumer_t documentation. + * @param p_context See @ref nrfx_usbd_consumer_t documentation. + * @param ep_size See @ref nrfx_usbd_consumer_t documentation. + * @param data_size See @ref nrfx_usbd_consumer_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrfx_usbd_consumer(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size, + size_t data_size) +{ + nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + + NRFX_ASSERT(ep_size >= data_size); + NRFX_ASSERT((p_transfer->p_data.rx == NULL) || nrfx_is_in_ram(p_transfer->p_data.rx)); + + size_t size = p_transfer->size; + + if (size < data_size) { + NRFX_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size); + /* Buffer size to small */ + p_next->size = 0; + p_next->p_data = p_transfer->p_data; + } else { + p_next->size = data_size; + p_next->p_data = p_transfer->p_data; + size -= data_size; + p_transfer->size = size; + p_transfer->p_data.addr += data_size; + } + return (ep_size == data_size) && (size != 0); +} + +/** + * @brief Integrated feeder from RAM source. + * + * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrfx_usbd_feeder_ram(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +{ + nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + + NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx)); + + size_t tx_size = p_transfer->size; + + if (tx_size > ep_size) { + tx_size = ep_size; + } + + p_next->p_data = p_transfer->p_data; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.addr += tx_size; + + return (p_transfer->size != 0); +} + +/** + * @brief Integrated feeder from RAM source with ZLP. + * + * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrfx_usbd_feeder_ram_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +{ + nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + + NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx)); + + size_t tx_size = p_transfer->size; + + if (tx_size > ep_size) { + tx_size = ep_size; + } + + p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.addr += tx_size; + + return (tx_size != 0); +} + +/** + * @brief Integrated feeder from a flash source. + * + * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +{ + nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + + NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx)); + + size_t tx_size = p_transfer->size; + void *p_buffer = nrfx_usbd_feeder_buffer_get(); + + if (tx_size > ep_size) { + tx_size = ep_size; + } + + NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE); + memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); + + p_next->p_data.tx = p_buffer; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.addr += tx_size; + + return (p_transfer->size != 0); +} + +/** + * @brief Integrated feeder from a flash source with ZLP. + * + * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +{ + nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + + NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx)); + + size_t tx_size = p_transfer->size; + void *p_buffer = nrfx_usbd_feeder_buffer_get(); + + if (tx_size > ep_size) { + tx_size = ep_size; + } + + NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE); + + if (tx_size != 0) { + memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); + p_next->p_data.tx = p_buffer; + } else { + p_next->p_data.tx = NULL; + } + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.addr += tx_size; + + return (tx_size != 0); +} + +/** @} */ + +/** + * @brief Change Driver endpoint number to HAL endpoint number. + * + * @param ep Driver endpoint identifier. + * + * @return Endpoint identifier in HAL. + * + * @sa nrfx_usbd_ep_from_hal + */ +static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + return (uint8_t)ep; +} + +/** + * @brief Generate start task number for selected endpoint index. + * + * @param ep Endpoint number. + * + * @return Task for starting EasyDMA transfer on selected endpoint. + */ +static inline nrf_usbd_task_t task_start_ep(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + return (nrf_usbd_task_t)((NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 + : NRF_USBD_TASK_STARTEPOUT0) + + (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); +} + +/** + * @brief Access selected endpoint state structure. + * + * Function used to change or just read the state of selected endpoint. + * It is used for internal transmission state. + * + * @param ep Endpoint number. + */ +static inline usbd_ep_state_t *ep_state_access(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + + NRF_USBD_EP_NR_GET(ep)); +} + +/** + * @brief Change endpoint number to bit position. + * + * Bit positions are defined the same way as they are placed in DATAEPSTATUS register, + * but bits for endpoint 0 are included. + * + * @param ep Endpoint number. + * + * @return Bit position related to the given endpoint number. + * + * @sa bit2ep + */ +static inline uint8_t ep2bit(nrfx_usbd_ep_t ep) +{ + NRFX_USBD_ASSERT_EP_VALID(ep); + return NRFX_USBD_EP_BITPOS(ep); +} + +/** + * @brief Change bit position to endpoint number. + * + * @param bitpos Bit position. + * + * @return Endpoint number corresponding to given bit position. + * + * @sa ep2bit + */ +static inline nrfx_usbd_ep_t bit2ep(uint8_t bitpos) +{ + NRFX_STATIC_ASSERT(NRFX_USBD_EPOUT_BITPOS_0 > NRFX_USBD_EPIN_BITPOS_0); + return (nrfx_usbd_ep_t)((bitpos >= NRFX_USBD_EPOUT_BITPOS_0) + ? NRF_USBD_EPOUT(bitpos - NRFX_USBD_EPOUT_BITPOS_0) + : NRF_USBD_EPIN(bitpos)); +} + +/** + * @brief Mark that EasyDMA is working. + * + * Internal function to set the flag informing about EasyDMA transfer pending. + * This function is called always just after the EasyDMA transfer is started. + */ +static inline void usbd_dma_pending_set(void) +{ + if (nrfx_usbd_errata_199()) { + *((volatile uint32_t *)0x40027C1C) = 0x00000082; + } + m_dma_pending = true; +} + +/** + * @brief Mark that EasyDMA is free. + * + * Internal function to clear the flag informing about EasyDMA transfer pending. + * This function is called always just after the finished EasyDMA transfer is detected. + */ +static inline void usbd_dma_pending_clear(void) +{ + if (nrfx_usbd_errata_199()) { + *((volatile uint32_t *)0x40027C1C) = 0x00000000; + } + m_dma_pending = false; +} + +/** + * @brief Start selected EasyDMA transmission. + * + * This is internal auxiliary function. + * No checking is made if EasyDMA is ready for new transmission. + * + * @param[in] ep Number of endpoint for transmission. + * If it is OUT endpoint transmission would be directed from endpoint to RAM. + * If it is in endpoint transmission would be directed from RAM to endpoint. + */ +static inline void usbd_dma_start(nrfx_usbd_ep_t ep) +{ + nrf_usbd_task_trigger(NRF_USBD, task_start_ep(ep)); +} + +void nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config) +{ + nrf_usbd_isoinconfig_set(NRF_USBD, config); +} + +nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void) +{ + return nrf_usbd_isoinconfig_get(NRF_USBD); +} + +/** + * @brief Abort pending transfer on selected endpoint. + * + * @param ep Endpoint number. + * + * @note + * This function locks interrupts that may be costly. + * It is good idea to test if the endpoint is still busy before calling this function: + * @code + (m_ep_dma_waiting & (1U << ep2bit(ep))) + * @endcode + * This function would check it again, but it makes it inside critical section. + */ +static inline void usbd_ep_abort(nrfx_usbd_ep_t ep) +{ + NRFX_CRITICAL_SECTION_ENTER(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (NRF_USBD_EPOUT_CHECK(ep)) { + /* Host -> Device */ + if ((~m_ep_dma_waiting) & (1U << ep2bit(ep))) { + /* If the bit in m_ep_dma_waiting in cleared - nothing would be + * processed inside transfer processing + */ + nrfx_usbd_transfer_out_drop(ep); + } else { + p_state->handler.consumer = NULL; + m_ep_dma_waiting &= ~(1U << ep2bit(ep)); + m_ep_ready &= ~(1U << ep2bit(ep)); + } + /* Aborted */ + p_state->status = NRFX_USBD_EP_ABORTED; + } else { + if (!NRF_USBD_EPISO_CHECK(ep)) { + /* Workaround: Disarm the endpoint if there is any data buffered. */ + if (ep != NRFX_USBD_EPIN0) { + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = + 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1)); + uint8_t temp = + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)); + temp |= (1U << 1); + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp; + (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804))); + } else { + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B4; + uint8_t temp = + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)); + temp |= (1U << 2); + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp; + (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804))); + } + } + if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep))) { + /* Device -> Host */ + m_ep_dma_waiting &= ~(1U << ep2bit(ep)); + m_ep_ready |= 1U << ep2bit(ep); + + p_state->handler.feeder = NULL; + p_state->status = NRFX_USBD_EP_ABORTED; + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_ABORTED); + m_event_handler(&evt); + } + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep) +{ + usbd_ep_abort(ep); +} + +/** + * @brief Abort all pending endpoints. + * + * Function aborts all pending endpoint transfers. + */ +static void usbd_ep_abort_all(void) +{ + uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & NRFX_USBD_EPOUT_BIT_MASK); + + while (ep_waiting != 0) { + uint8_t bitpos = NRF_CTZ(ep_waiting); + + if (!NRF_USBD_EPISO_CHECK(bit2ep(bitpos))) { + usbd_ep_abort(bit2ep(bitpos)); + } + ep_waiting &= ~(1U << bitpos); + } + + m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0); +} + +/** + * @brief Force the USBD interrupt into pending state. + * + * This function is used to force USBD interrupt to be processed right now. + * It makes it possible to process all EasyDMA access on one thread priority level. + */ +static inline void usbd_int_rise(void) +{ + NRFX_IRQ_PENDING_SET(USBD_IRQn); +} + +/** + * @name USBD interrupt runtimes. + * + * Interrupt runtimes that would be vectorized using @ref m_isr. + * @{ + */ + +static void ev_usbreset_handler(void) +{ + m_bus_suspend = false; + m_last_setup_dir = NRFX_USBD_EPOUT0; + + const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_RESET}; + + m_event_handler(&evt); +} + +static void ev_started_handler(void) +{ +#if NRFX_USBD_STARTED_EV_ENABLE + /* Handler not used by the stack. + * May be used for debugging. + */ +#endif +} + +/** + * @brief Handler for EasyDMA event without endpoint clearing. + * + * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. + * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. + * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler. + * + * @param[in] ep Endpoint number. + */ +static inline void nrf_usbd_ep0in_dma_handler(void) +{ + const nrfx_usbd_ep_t ep = NRFX_USBD_EPIN0; + + NRFX_LOG_DEBUG("USB event: DMA ready IN0"); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Clear transfer information just in case */ + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else if (p_state->handler.feeder == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else { + /* Nothing to do */ + } +} + +/** + * @brief Handler for EasyDMA event without endpoint clearing. + * + * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. + * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. + * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler. + * + * @param[in] ep Endpoint number. + */ +static inline void nrf_usbd_epin_dma_handler(nrfx_usbd_ep_t ep) +{ + NRFX_LOG_DEBUG("USB event: DMA ready IN: %x", ep); + NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep)); + NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Clear transfer information just in case */ + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else if (p_state->handler.feeder == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else { + /* Nothing to do */ + } +} + +/** + * @brief Handler for EasyDMA event from in isochronous endpoint. + */ +static inline void nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep) +{ + if (NRFX_USBD_ISO_DEBUG) { + NRFX_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep); + } + NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep)); + NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep)); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Clear transfer information just in case */ + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else if (p_state->handler.feeder == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished + * in this moment + */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + m_event_handler(&evt); + } else { + /* Nothing to do */ + } +} + +/** + * @brief Handler for EasyDMA event for OUT endpoint 0. + * + * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer. + * It cannot be cleared when required transfer is finished because it means the same that accepting + * the comment. + */ +static inline void nrf_usbd_ep0out_dma_handler(void) +{ + const nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT0; + + NRFX_LOG_DEBUG("USB event: DMA ready OUT0"); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Clear transfer information just in case */ + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else if (p_state->handler.consumer == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + /* Send event to the user - for an OUT endpoint, the whole transfer is finished in + * this moment + */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + m_event_handler(&evt); + } else { + nrfx_usbd_setup_data_clear(); + } +} + +/** + * @brief Handler for EasyDMA event from endpoinpoint that requires clearing. + * + * This handler would be called when EasyDMA transfer for OUT endpoint has been finished. + * + * @param[in] ep Endpoint number. + */ +static inline void nrf_usbd_epout_dma_handler(nrfx_usbd_ep_t ep) +{ + NRFX_LOG_DEBUG("DMA ready OUT: %x", ep); + NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Clear transfer information just in case */ + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + } else if (p_state->handler.consumer == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + /* Send event to the user - for an OUT endpoint, the whole transfer is finished in + * this moment + */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + m_event_handler(&evt); + } else { + /* Nothing to do */ + } + +#if NRFX_USBD_EARLY_DMA_PROCESS + /* Speed up */ + usbd_dmareq_process(); +#endif +} + +/** + * @brief Handler for EasyDMA event from out isochronous endpoint. + */ +static inline void nrf_usbd_epoutiso_dma_handler(nrfx_usbd_ep_t ep) +{ + if (NRFX_USBD_ISO_DEBUG) { + NRFX_LOG_DEBUG("DMA ready ISOOUT: %x", ep); + } + NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep)); + usbd_dma_pending_clear(); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + if (p_state->status == NRFX_USBD_EP_ABORTED) { + /* Nothing to do - just ignore */ + } else if (p_state->handler.consumer == NULL) { + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + /* Send event to the user - for an OUT endpoint, the whole transfer is finished in + * this moment + */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + m_event_handler(&evt); + } else { + /* Nothing to do */ + } +} + +static void ev_dma_epin0_handler(void) +{ + nrf_usbd_ep0in_dma_handler(); +} +static void ev_dma_epin1_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN1); +} +static void ev_dma_epin2_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN2); +} +static void ev_dma_epin3_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN3); +} +static void ev_dma_epin4_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN4); +} +static void ev_dma_epin5_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN5); +} +static void ev_dma_epin6_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN6); +} +static void ev_dma_epin7_handler(void) +{ + nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN7); +} +static void ev_dma_epin8_handler(void) +{ + nrf_usbd_epiniso_dma_handler(NRFX_USBD_EPIN8); +} + +static void ev_dma_epout0_handler(void) +{ + nrf_usbd_ep0out_dma_handler(); +} +static void ev_dma_epout1_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT1); +} +static void ev_dma_epout2_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT2); +} +static void ev_dma_epout3_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT3); +} +static void ev_dma_epout4_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT4); +} +static void ev_dma_epout5_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT5); +} +static void ev_dma_epout6_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT6); +} +static void ev_dma_epout7_handler(void) +{ + nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT7); +} +static void ev_dma_epout8_handler(void) +{ + nrf_usbd_epoutiso_dma_handler(NRFX_USBD_EPOUT8); +} + +static void ev_sof_handler(void) +{ + nrfx_usbd_evt_t evt = { + NRFX_USBD_EVT_SOF, + .data = {.sof = {.framecnt = (uint16_t)nrf_usbd_framecntr_get(NRF_USBD)}}}; + + /* Process isochronous endpoints */ + uint32_t iso_ready_mask = (1U << ep2bit(NRFX_USBD_EPIN8)); + + if (nrf_usbd_episoout_size_get(NRF_USBD, NRFX_USBD_EPOUT8) != NRF_USBD_EPISOOUT_NO_DATA) { + iso_ready_mask |= (1U << ep2bit(NRFX_USBD_EPOUT8)); + } + m_ep_ready |= iso_ready_mask; + + m_event_handler(&evt); +} + +/** + * @brief React on data transfer finished. + * + * Auxiliary internal function. + * @param ep Endpoint number. + * @param bitpos Bit position for selected endpoint number. + */ +static void usbd_ep_data_handler(nrfx_usbd_ep_t ep, uint8_t bitpos) +{ + NRFX_LOG_DEBUG("USBD event: EndpointData: %x", ep); + /* Mark endpoint ready for next DMA access */ + m_ep_ready |= (1U << bitpos); + + if (NRF_USBD_EPIN_CHECK(ep)) { + /* IN endpoint (Device -> Host) */ + + /* Secure against the race condition that occurs when an IN transfer is interrupted + * by an OUT transaction, which in turn is interrupted by a process with higher + * priority. If the IN events ENDEPIN and EPDATA arrive during that high priority + * process, the OUT handler might call usbd_ep_data_handler without calling + * nrf_usbd_epin_dma_handler (or nrf_usbd_ep0in_dma_handler) for the IN transaction. + */ + if (nrf_usbd_event_get_and_clear(NRF_USBD, nrfx_usbd_ep_to_endevent(ep))) { + if (ep != NRFX_USBD_EPIN0) { + nrf_usbd_epin_dma_handler(ep); + } else { + nrf_usbd_ep0in_dma_handler(); + } + } + + if (0 == (m_ep_dma_waiting & (1U << bitpos))) { + NRFX_LOG_DEBUG("USBD event: EndpointData: In finished"); + /* No more data to be send - transmission finished */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + m_event_handler(&evt); + } + } else { + /* OUT endpoint (Host -> Device) */ + if (0 == (m_ep_dma_waiting & (1U << bitpos))) { + NRFX_LOG_DEBUG("USBD event: EndpointData: Out waiting"); + /* No buffer prepared - send event to the application */ + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_WAITING); + m_event_handler(&evt); + } + } +} + +static void ev_setup_data_handler(void) +{ + usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir)); +} + +static void ev_setup_handler(void) +{ + NRFX_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", + nrf_usbd_setup_bmrequesttype_get(NRF_USBD), + nrf_usbd_setup_brequest_get(NRF_USBD), nrf_usbd_setup_wvalue_get(NRF_USBD), + nrf_usbd_setup_windex_get(NRF_USBD), nrf_usbd_setup_wlength_get(NRF_USBD)); + uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); + + if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + (1U << ep2bit(m_last_setup_dir))) { + NRFX_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0"); + usbd_ep_abort(m_last_setup_dir); + } + + m_last_setup_dir = + ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) == + (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) + ? NRFX_USBD_EPOUT0 + : NRFX_USBD_EPIN0; + + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~((1U << ep2bit(NRFX_USBD_EPOUT0)) | + (1U << ep2bit(NRFX_USBD_EPIN0))))); + m_ep_ready |= 1U << ep2bit(NRFX_USBD_EPIN0); + + const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_SETUP}; + + m_event_handler(&evt); +} + +static void ev_usbevent_handler(void) +{ + uint32_t event = nrf_usbd_eventcause_get_and_clear(NRF_USBD); + + if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK) { + NRFX_LOG_DEBUG("USBD event: ISOOUTCRC"); + /* Currently no support */ + } + if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK) { + NRFX_LOG_DEBUG("USBD event: SUSPEND"); + m_bus_suspend = true; + const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_SUSPEND}; + + m_event_handler(&evt); + } + if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK) { + NRFX_LOG_DEBUG("USBD event: RESUME"); + m_bus_suspend = false; + const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_RESUME}; + + m_event_handler(&evt); + } + if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK) { + NRFX_LOG_DEBUG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active"); + if (m_bus_suspend) { + NRFX_ASSERT(!nrf_usbd_lowpower_check(NRF_USBD)); + m_bus_suspend = false; + + nrf_usbd_dpdmvalue_set(NRF_USBD, NRF_USBD_DPDMVALUE_RESUME); + nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_DRIVEDPDM); + + const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_WUREQ}; + + m_event_handler(&evt); + } + } +} + +static void ev_epdata_handler(void) +{ + /* Get all endpoints that have acknowledged transfer */ + uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear(NRF_USBD); + + NRFX_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus); + + /* All finished endpoint have to be marked as busy */ + while (dataepstatus) { + uint8_t bitpos = NRF_CTZ(dataepstatus); + nrfx_usbd_ep_t ep = bit2ep(bitpos); + + dataepstatus &= ~(1UL << bitpos); + + (void)(usbd_ep_data_handler(ep, bitpos)); + } + if (NRFX_USBD_EARLY_DMA_PROCESS) { + /* Speed up */ + usbd_dmareq_process(); + } +} + +/** + * @brief Function to select the endpoint to start. + * + * Function that realizes algorithm to schedule right channel for EasyDMA transfer. + * It gets a variable with flags for the endpoints currently requiring transfer. + * + * @param[in] req Bit flags for channels currently requiring transfer. + * Bits 0...8 used for IN endpoints. + * Bits 16...24 used for OUT endpoints. + * @note + * This function would be never called with 0 as a @c req argument. + * @return The bit number of the endpoint that should be processed now. + */ +static uint8_t usbd_dma_scheduler_algorithm(uint32_t req) +{ + /* Only prioritized scheduling mode is supported. */ + return NRF_CTZ(req); +} + +/** + * @brief Get the size of isochronous endpoint. + * + * The size of isochronous endpoint is configurable. + * This function returns the size of isochronous buffer taking into account + * current configuration. + * + * @param[in] ep Endpoint number. + * + * @return The size of endpoint buffer. + */ +static inline size_t usbd_ep_iso_capacity(nrfx_usbd_ep_t ep) +{ + (void)ep; + nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get(NRF_USBD); + + if (split == NRF_USBD_ISOSPLIT_HALF) { + return NRFX_USBD_ISOSIZE / 2; + } + return NRFX_USBD_ISOSIZE; +} + +/** + * @brief Process all DMA requests. + * + * Function that have to be called from USBD interrupt handler. + * It have to be called when all the interrupts connected with endpoints transfer + * and DMA transfer are already handled. + */ +static void usbd_dmareq_process(void) +{ + if (!m_dma_pending) { + uint32_t req; + + while (0 != (req = m_ep_dma_waiting & m_ep_ready)) { + uint8_t pos; + + if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST && + ((req & USBD_EPISO_BIT_MASK) != 0)) { + pos = usbd_dma_scheduler_algorithm(req & USBD_EPISO_BIT_MASK); + } else { + pos = usbd_dma_scheduler_algorithm(req); + } + nrfx_usbd_ep_t ep = bit2ep(pos); + usbd_ep_state_t *p_state = ep_state_access(ep); + + nrfx_usbd_ep_transfer_t transfer; + bool continue_transfer; + + NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) == + offsetof(usbd_ep_state_t, handler.consumer)); + NRFX_ASSERT((p_state->handler.feeder) != NULL); + + if (NRF_USBD_EPIN_CHECK(ep)) { + /* Device -> Host */ + continue_transfer = p_state->handler.feeder( + &transfer, p_state->p_context, p_state->max_packet_size); + + if (!continue_transfer) { + p_state->handler.feeder = NULL; + } + } else { + /* Host -> Device */ + const size_t rx_size = nrfx_usbd_epout_size_get(ep); + + continue_transfer = p_state->handler.consumer( + &transfer, p_state->p_context, p_state->max_packet_size, + rx_size); + + if (transfer.p_data.rx == NULL) { + /* Dropping transfer - allow processing */ + NRFX_ASSERT(transfer.size == 0); + } else if (transfer.size < rx_size) { + NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, + rx_size, transfer.size); + p_state->status = NRFX_USBD_EP_OVERLOAD; + (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, + ~(1U << pos))); + NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OVERLOAD); + m_event_handler(&evt); + /* This endpoint will not be transmitted now, repeat the + * loop + */ + continue; + } else { + /* Nothing to do - only check integrity if assertions are + * enabled + */ + NRFX_ASSERT(transfer.size == rx_size); + } + + if (!continue_transfer) { + p_state->handler.consumer = NULL; + } + } + + usbd_dma_pending_set(); + m_ep_ready &= ~(1U << pos); + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG( + "USB DMA process: Starting transfer on EP: %x, size: %u", + ep, transfer.size); + } + /* Update number of currently transferred bytes */ + p_state->transfer_cnt += transfer.size; + /* Start transfer to the endpoint buffer */ + nrf_usbd_ep_easydma_set(NRF_USBD, ep, transfer.p_data.addr, + (uint32_t)transfer.size); + + usbd_dma_start(ep); + /* There is a lot of USBD registers that cannot be accessed during EasyDMA + * transfer. This is quick fix to maintain stability of the stack. It cost + * some performance but makes stack stable. + */ + while (!nrf_usbd_event_check(NRF_USBD, nrfx_usbd_ep_to_endevent(ep))) { + /* Empty */ + } + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; + + if (NRFX_USBD_DMAREQ_PROCESS_DEBUG) { + NRFX_LOG_DEBUG("USB DMA process - finishing"); + } + /* Transfer started - exit the loop */ + break; + } + } else { + if (NRFX_USBD_DMAREQ_PROCESS_DEBUG) { + NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy"); + } + } +} + +/** + * @brief Wait for a specified eventcause and clear it afterwards. + */ +static inline void usbd_eventcause_wait_and_clear(nrf_usbd_eventcause_mask_t eventcause) +{ + while (0 == (eventcause & nrf_usbd_eventcause_get(NRF_USBD))) { + /* Empty loop */ + } + nrf_usbd_eventcause_clear(NRF_USBD, eventcause); +} + +/** + * @brief Begin errata 171. + */ +static inline void usbd_errata_171_begin(void) +{ + NRFX_CRITICAL_SECTION_ENTER(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +/** + * @brief End errata 171. + */ +static inline void usbd_errata_171_end(void) +{ + NRFX_CRITICAL_SECTION_ENTER(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +/** + * @brief Begin erratas 187 and 211. + */ +static inline void usbd_errata_187_211_begin(void) +{ + NRFX_CRITICAL_SECTION_ENTER(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +/** + * @brief End erratas 187 and 211. + */ +static inline void usbd_errata_187_211_end(void) +{ + NRFX_CRITICAL_SECTION_ENTER(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +/** + * @brief Enable USBD peripheral. + */ +static void usbd_enable(void) +{ + if (nrfx_usbd_errata_187()) { + usbd_errata_187_211_begin(); + } + + if (nrfx_usbd_errata_171()) { + usbd_errata_171_begin(); + } + + /* Enable the peripheral */ + nrf_usbd_enable(NRF_USBD); + + /* Waiting for peripheral to enable, this should take a few us */ + usbd_eventcause_wait_and_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + + if (nrfx_usbd_errata_171()) { + usbd_errata_171_end(); + } + + if (nrfx_usbd_errata_187()) { + usbd_errata_187_211_end(); + } +} +/** @} */ + +/** + * @brief USBD interrupt service routines. + * + */ +static const nrfx_irq_handler_t m_isr[] = {[USBD_INTEN_USBRESET_Pos] = ev_usbreset_handler, + [USBD_INTEN_STARTED_Pos] = ev_started_handler, + [USBD_INTEN_ENDEPIN0_Pos] = ev_dma_epin0_handler, + [USBD_INTEN_ENDEPIN1_Pos] = ev_dma_epin1_handler, + [USBD_INTEN_ENDEPIN2_Pos] = ev_dma_epin2_handler, + [USBD_INTEN_ENDEPIN3_Pos] = ev_dma_epin3_handler, + [USBD_INTEN_ENDEPIN4_Pos] = ev_dma_epin4_handler, + [USBD_INTEN_ENDEPIN5_Pos] = ev_dma_epin5_handler, + [USBD_INTEN_ENDEPIN6_Pos] = ev_dma_epin6_handler, + [USBD_INTEN_ENDEPIN7_Pos] = ev_dma_epin7_handler, + [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler, + [USBD_INTEN_ENDISOIN_Pos] = ev_dma_epin8_handler, + [USBD_INTEN_ENDEPOUT0_Pos] = ev_dma_epout0_handler, + [USBD_INTEN_ENDEPOUT1_Pos] = ev_dma_epout1_handler, + [USBD_INTEN_ENDEPOUT2_Pos] = ev_dma_epout2_handler, + [USBD_INTEN_ENDEPOUT3_Pos] = ev_dma_epout3_handler, + [USBD_INTEN_ENDEPOUT4_Pos] = ev_dma_epout4_handler, + [USBD_INTEN_ENDEPOUT5_Pos] = ev_dma_epout5_handler, + [USBD_INTEN_ENDEPOUT6_Pos] = ev_dma_epout6_handler, + [USBD_INTEN_ENDEPOUT7_Pos] = ev_dma_epout7_handler, + [USBD_INTEN_ENDISOOUT_Pos] = ev_dma_epout8_handler, + [USBD_INTEN_SOF_Pos] = ev_sof_handler, + [USBD_INTEN_USBEVENT_Pos] = ev_usbevent_handler, + [USBD_INTEN_EP0SETUP_Pos] = ev_setup_handler, + [USBD_INTEN_EPDATA_Pos] = ev_epdata_handler}; + +/** + * @name Interrupt handlers + * + * @{ + */ +void nrfx_usbd_irq_handler(void) +{ + const uint32_t enabled = nrf_usbd_int_enable_get(NRF_USBD); + uint32_t to_process = enabled; + uint32_t active = 0; + + /* Check all enabled interrupts */ + while (to_process) { + uint8_t event_nr = NRF_CTZ(to_process); + + if (nrf_usbd_event_get_and_clear( + NRF_USBD, (nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr))) { + active |= 1UL << event_nr; + } + to_process &= ~(1UL << event_nr); + } + + /* Process the active interrupts */ + bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK); + + active &= ~NRF_USBD_INT_EP0SETUP_MASK; + + while (active) { + uint8_t event_nr = NRF_CTZ(active); + + m_isr[event_nr](); + active &= ~(1UL << event_nr); + } + usbd_dmareq_process(); + + if (setup_active) { + m_isr[USBD_INTEN_EP0SETUP_Pos](); + } +} + +/** @} */ +/** @} */ + +nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler) +{ + NRFX_ASSERT(event_handler); + + if (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED) { + return NRFX_ERROR_INVALID_STATE; + } + + m_event_handler = event_handler; + m_drv_state = NRFX_DRV_STATE_INITIALIZED; + + uint8_t n; + + for (n = 0; n < NRF_USBD_EPIN_CNT; ++n) { + nrfx_usbd_ep_t ep = NRFX_USBD_EPIN(n); + + nrfx_usbd_ep_max_packet_size_set( + ep, NRF_USBD_EPISO_CHECK(ep) ? (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE); + usbd_ep_state_t *p_state = ep_state_access(ep); + + p_state->status = NRFX_USBD_EP_OK; + p_state->handler.feeder = NULL; + p_state->transfer_cnt = 0; + } + for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n) { + nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT(n); + + nrfx_usbd_ep_max_packet_size_set( + ep, NRF_USBD_EPISO_CHECK(ep) ? (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE); + usbd_ep_state_t *p_state = ep_state_access(ep); + + p_state->status = NRFX_USBD_EP_OK; + p_state->handler.consumer = NULL; + p_state->transfer_cnt = 0; + } + + return NRFX_SUCCESS; +} + +void nrfx_usbd_uninit(void) +{ + NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED); + + m_event_handler = NULL; + m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; +} + +void nrfx_usbd_enable(void) +{ + NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED); + + /* Prepare for READY event receiving */ + nrf_usbd_eventcause_clear(NRF_USBD, NRF_USBD_EVENTCAUSE_READY_MASK); + + usbd_enable(); + + if (nrfx_usbd_errata_223() && m_first_enable) { + nrf_usbd_disable(NRF_USBD); + + usbd_enable(); + + m_first_enable = false; + } + +#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrfx_usbd_errata_187() || nrfx_usbd_errata_211()) +#else + if (nrfx_usbd_errata_187()) +#endif + { + usbd_errata_187_211_begin(); + } + + if (nrfx_usbd_errata_166()) { + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7E3; + *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0x40; + __ISB(); + __DSB(); + } + + nrf_usbd_isosplit_set(NRF_USBD, NRF_USBD_ISOSPLIT_HALF); + + if (NRFX_USBD_CONFIG_ISO_IN_ZLP) { + nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA); + } else { + nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP); + } + + m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0); + m_ep_dma_waiting = 0; + m_dma_odd = 0; + usbd_dma_pending_clear(); + m_last_setup_dir = NRFX_USBD_EPOUT0; + + m_drv_state = NRFX_DRV_STATE_POWERED_ON; + +#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrfx_usbd_errata_187() && !nrfx_usbd_errata_211()) +#else + if (nrfx_usbd_errata_187()) +#endif + { + usbd_errata_187_211_end(); + } +} + +void nrfx_usbd_disable(void) +{ + NRFX_ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED); + + /* Stop just in case */ + nrfx_usbd_stop(); + + /* Disable all parts */ + nrf_usbd_int_disable(NRF_USBD, nrf_usbd_int_enable_get(NRF_USBD)); + if (m_dma_odd) { + /* Prevent invalid bus request after next USBD enable by ensuring + * that total number of bytes transferred by DMA is even. + */ + nrf_usbd_event_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0); + nrf_usbd_ep_easydma_set(NRF_USBD, NRFX_USBD_EPIN0, (uint32_t)&m_dma_odd, 1); + usbd_dma_start(NRFX_USBD_EPIN0); + while (!nrf_usbd_event_check(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0)) { + } + m_dma_odd = 0; + } + nrf_usbd_disable(NRF_USBD); + usbd_dma_pending_clear(); + m_drv_state = NRFX_DRV_STATE_INITIALIZED; + +#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrfx_usbd_errata_211()) { + usbd_errata_187_211_end(); + } +#endif +} + +void nrfx_usbd_start(bool enable_sof) +{ + NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); + m_bus_suspend = false; + + uint32_t ints_to_enable = NRF_USBD_INT_USBRESET_MASK | NRF_USBD_INT_STARTED_MASK | + NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | + NRF_USBD_INT_ENDEPOUT0_MASK | NRF_USBD_INT_USBEVENT_MASK | + NRF_USBD_INT_EP0SETUP_MASK | NRF_USBD_INT_DATAEP_MASK; + + if (enable_sof) { + ints_to_enable |= NRF_USBD_INT_SOF_MASK; + } + + /* Enable all required interrupts */ + nrf_usbd_int_enable(NRF_USBD, ints_to_enable); + + /* Enable interrupt globally */ + NRFX_IRQ_PRIORITY_SET(USBD_IRQn, NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY); + NRFX_IRQ_ENABLE(USBD_IRQn); + + /* Enable pullups */ + nrf_usbd_pullup_enable(NRF_USBD); +} + +void nrfx_usbd_stop(void) +{ + NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); + + /* Clear interrupt */ + NRFX_IRQ_PENDING_CLEAR(USBD_IRQn); + + if (NRFX_IRQ_IS_ENABLED(USBD_IRQn)) { + /* Abort transfers */ + usbd_ep_abort_all(); + + /* Disable pullups */ + nrf_usbd_pullup_disable(NRF_USBD); + + /* Disable interrupt globally */ + NRFX_IRQ_DISABLE(USBD_IRQn); + + /* Disable all interrupts */ + nrf_usbd_int_disable(NRF_USBD, ~0U); + } +} + +bool nrfx_usbd_is_initialized(void) +{ + return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED); +} + +bool nrfx_usbd_is_enabled(void) +{ + return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON); +} + +bool nrfx_usbd_is_started(void) +{ + return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn)); +} + +bool nrfx_usbd_suspend(void) +{ + bool suspended = false; + + NRFX_CRITICAL_SECTION_ENTER(); + if (m_bus_suspend) { + if (!(nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK)) { + nrf_usbd_lowpower_enable(NRF_USBD); + if (nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK) { + nrf_usbd_lowpower_disable(NRF_USBD); + } else { + suspended = true; + } + } + } + NRFX_CRITICAL_SECTION_EXIT(); + + return suspended; +} + +bool nrfx_usbd_wakeup_req(void) +{ + bool started = false; + + NRFX_CRITICAL_SECTION_ENTER(); + if (m_bus_suspend && nrf_usbd_lowpower_check(NRF_USBD)) { + nrf_usbd_lowpower_disable(NRF_USBD); + started = true; + + if (nrfx_usbd_errata_171()) { + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; + *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; + } + } + } + NRFX_CRITICAL_SECTION_EXIT(); + + return started; +} + +bool nrfx_usbd_suspend_check(void) +{ + return nrf_usbd_lowpower_check(NRF_USBD); +} + +void nrfx_usbd_suspend_irq_config(void) +{ + nrf_usbd_int_disable(NRF_USBD, m_irq_disabled_in_suspend); +} + +void nrfx_usbd_active_irq_config(void) +{ + nrf_usbd_int_enable(NRF_USBD, m_irq_disabled_in_suspend); +} + +bool nrfx_usbd_bus_suspend_check(void) +{ + return m_bus_suspend; +} + +void nrfx_usbd_force_bus_wakeup(void) +{ + m_bus_suspend = false; +} + +void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size) +{ + /* Only the power of 2 size allowed for Control Endpoints */ + NRFX_ASSERT((((size & (size - 1)) == 0) || (NRF_USBD_EP_NR_GET(ep) != 0))); + /* Only non zero size allowed for Control Endpoints */ + NRFX_ASSERT((size != 0) || (NRF_USBD_EP_NR_GET(ep) != 0)); + /* Packet size cannot be higher than maximum buffer size */ + NRFX_ASSERT((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) || + (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRFX_USBD_EPSIZE))); + + usbd_ep_state_t *p_state = ep_state_access(ep); + + p_state->max_packet_size = size; +} + +uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep) +{ + usbd_ep_state_t const *p_state = ep_state_access(ep); + + return p_state->max_packet_size; +} + +bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep) +{ + return nrf_usbd_ep_enable_check(NRF_USBD, ep_to_hal(ep)); +} + +void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep) +{ + nrf_usbd_int_enable(NRF_USBD, nrfx_usbd_ep_to_int(ep)); + + if (nrf_usbd_ep_enable_check(NRF_USBD, ep)) { + return; + } + nrf_usbd_ep_enable(NRF_USBD, ep_to_hal(ep)); + if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && + !NRF_USBD_EPISO_CHECK(ep)) { + NRFX_CRITICAL_SECTION_ENTER(); + nrfx_usbd_transfer_out_drop(ep); + m_ep_dma_waiting &= ~(1U << ep2bit(ep)); + NRFX_CRITICAL_SECTION_EXIT(); + } +} + +void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep) +{ + usbd_ep_abort(ep); + nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep)); + nrf_usbd_int_disable(NRF_USBD, nrfx_usbd_ep_to_int(ep)); +} + +void nrfx_usbd_ep_default_config(void) +{ + nrf_usbd_int_disable(NRF_USBD, + NRF_USBD_INT_ENDEPIN1_MASK | NRF_USBD_INT_ENDEPIN2_MASK | + NRF_USBD_INT_ENDEPIN3_MASK | NRF_USBD_INT_ENDEPIN4_MASK | + NRF_USBD_INT_ENDEPIN5_MASK | NRF_USBD_INT_ENDEPIN6_MASK | + NRF_USBD_INT_ENDEPIN7_MASK | NRF_USBD_INT_ENDISOIN0_MASK | + NRF_USBD_INT_ENDEPOUT1_MASK | NRF_USBD_INT_ENDEPOUT2_MASK | + NRF_USBD_INT_ENDEPOUT3_MASK | NRF_USBD_INT_ENDEPOUT4_MASK | + NRF_USBD_INT_ENDEPOUT5_MASK | NRF_USBD_INT_ENDEPOUT6_MASK | + NRF_USBD_INT_ENDEPOUT7_MASK | NRF_USBD_INT_ENDISOOUT0_MASK); + nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK); + nrf_usbd_ep_default_config(NRF_USBD); +} + +nrfx_err_t nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep, nrfx_usbd_transfer_t const *p_transfer) +{ + nrfx_err_t ret; + const uint8_t ep_bitpos = ep2bit(ep); + + NRFX_ASSERT(p_transfer != NULL); + + NRFX_CRITICAL_SECTION_ENTER(); + /* Setup data transaction can go only in one direction at a time */ + if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { + ret = NRFX_ERROR_INVALID_ADDR; + if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && + (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + NRFX_LOG_DEBUG("Transfer failed: Invalid EPr\n"); + } + } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + (1U << ep_bitpos)) { + /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission + */ + ret = NRFX_ERROR_BUSY; + if (NRFX_USBD_FAILED_TRANSFERS_DEBUG) { + NRFX_LOG_DEBUG("Transfer failed: EP is busy"); + } + } else { + usbd_ep_state_t *p_state = ep_state_access(ep); + /* Prepare transfer context and handler description */ + nrfx_usbd_transfer_t *p_context; + + if (NRF_USBD_EPIN_CHECK(ep)) { + p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep); + if (nrfx_is_in_ram(p_transfer->p_data.tx)) { + /* RAM */ + if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG)) { + p_state->handler.feeder = nrfx_usbd_feeder_ram; + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG("Transfer called on endpoint %x, " + "size: %u, mode: " + "RAM", + ep, p_transfer->size); + } + } else { + p_state->handler.feeder = nrfx_usbd_feeder_ram_zlp; + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG("Transfer called on endpoint %x, " + "size: %u, mode: " + "RAM_ZLP", + ep, p_transfer->size); + } + } + } else { + /* Flash */ + if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG)) { + p_state->handler.feeder = nrfx_usbd_feeder_flash; + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG("Transfer called on endpoint %x, " + "size: %u, mode: " + "FLASH", + ep, p_transfer->size); + } + } else { + p_state->handler.feeder = nrfx_usbd_feeder_flash_zlp; + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG("Transfer called on endpoint %x, " + "size: %u, mode: " + "FLASH_ZLP", + ep, p_transfer->size); + } + } + } + } else { + p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep); + NRFX_ASSERT((p_transfer->p_data.rx == NULL) || + (nrfx_is_in_ram(p_transfer->p_data.rx))); + p_state->handler.consumer = nrfx_usbd_consumer; + } + *p_context = *p_transfer; + p_state->p_context = p_context; + + p_state->transfer_cnt = 0; + p_state->status = NRFX_USBD_EP_OK; + m_ep_dma_waiting |= 1U << ep_bitpos; + ret = NRFX_SUCCESS; + usbd_int_rise(); + } + NRFX_CRITICAL_SECTION_EXIT(); + return ret; +} + +nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, + nrfx_usbd_handler_desc_t const *p_handler) +{ + nrfx_err_t ret; + const uint8_t ep_bitpos = ep2bit(ep); + + NRFX_ASSERT(p_handler != NULL); + + NRFX_CRITICAL_SECTION_ENTER(); + /* Setup data transaction can go only in one direction at a time */ + if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { + ret = NRFX_ERROR_INVALID_ADDR; + if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && + (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + NRFX_LOG_DEBUG("Transfer failed: Invalid EP"); + } + } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + (1U << ep_bitpos)) { + /* IN (Device -> Host) transfer has to be transmitted out to allow a new + * transmission + */ + ret = NRFX_ERROR_BUSY; + if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && + (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + NRFX_LOG_DEBUG("Transfer failed: EP is busy"); + } + } else { + /* Transfer can be configured now */ + usbd_ep_state_t *p_state = ep_state_access(ep); + + p_state->transfer_cnt = 0; + p_state->handler = p_handler->handler; + p_state->p_context = p_handler->p_context; + p_state->status = NRFX_USBD_EP_OK; + m_ep_dma_waiting |= 1U << ep_bitpos; + + ret = NRFX_SUCCESS; + if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + NRFX_LOG_DEBUG("Transfer called on endpoint %x, mode: Handler", ep); + } + usbd_int_rise(); + } + NRFX_CRITICAL_SECTION_EXIT(); + return ret; +} + +void *nrfx_usbd_feeder_buffer_get(void) +{ + return m_tx_buffer; +} + +nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t *p_size) +{ + nrfx_usbd_ep_status_t ret; + usbd_ep_state_t const *p_state = ep_state_access(ep); + + NRFX_CRITICAL_SECTION_ENTER(); + *p_size = p_state->transfer_cnt; + ret = (p_state->handler.consumer == NULL) ? p_state->status : NRFX_USBD_EP_BUSY; + NRFX_CRITICAL_SECTION_EXIT(); + return ret; +} + +size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep) +{ + return nrf_usbd_epout_size_get(NRF_USBD, ep_to_hal(ep)); +} + +bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep) +{ + return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + (1U << ep2bit(ep)))); +} + +void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep) +{ + NRFX_LOG_DEBUG("USB: EP %x stalled.", ep); + nrf_usbd_ep_stall(NRF_USBD, ep_to_hal(ep)); +} + +void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep) +{ + if (NRF_USBD_EPOUT_CHECK(ep) && nrfx_usbd_ep_stall_check(ep)) { + nrfx_usbd_transfer_out_drop(ep); + } + nrf_usbd_ep_unstall(NRF_USBD, ep_to_hal(ep)); +} + +bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep) +{ + return nrf_usbd_ep_is_stall(NRF_USBD, ep_to_hal(ep)); +} + +void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep) +{ + nrf_usbd_dtoggle_set(NRF_USBD, ep, NRF_USBD_DTOGGLE_DATA0); +} + +void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup) +{ + memset(p_setup, 0, sizeof(nrfx_usbd_setup_t)); + p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); + p_setup->bRequest = nrf_usbd_setup_brequest_get(NRF_USBD); + p_setup->wValue = nrf_usbd_setup_wvalue_get(NRF_USBD); + p_setup->wIndex = nrf_usbd_setup_windex_get(NRF_USBD); + p_setup->wLength = nrf_usbd_setup_wlength_get(NRF_USBD); +} + +void nrfx_usbd_setup_data_clear(void) +{ + nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0RCVOUT); +} + +void nrfx_usbd_setup_clear(void) +{ + NRFX_LOG_DEBUG(">> ep0status >>"); + nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STATUS); +} + +void nrfx_usbd_setup_stall(void) +{ + NRFX_LOG_DEBUG("Setup stalled."); + nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STALL); +} + +nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void) +{ + return m_last_setup_dir; +} + +void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep) +{ + NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + + NRFX_CRITICAL_SECTION_ENTER(); + m_ep_ready &= ~(1U << ep2bit(ep)); + if (!NRF_USBD_EPISO_CHECK(ep)) { + nrf_usbd_epout_clear(NRF_USBD, ep); + } + NRFX_CRITICAL_SECTION_EXIT(); +} + +#endif /* NRFX_CHECK(NRFX_USBD_ENABLED) */ diff --git a/modules/hal_nordic/nrfx/nrfx_usbd.h b/modules/hal_nordic/nrfx/nrfx_usbd.h new file mode 100644 index 00000000000..cf6251cb4bd --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_usbd.h @@ -0,0 +1,828 @@ +/* + * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_USBD_H__ +#define NRFX_USBD_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrfx_usbd USBD driver + * @{ + * @ingroup nrf_usbd + * @brief Universal Serial Bus Device (USBD) peripheral driver. + */ + +/** + * @brief Number of bytes in the endpoint. + */ +#define NRFX_USBD_EPSIZE 64 + +/** + * @brief Number of bytes for isochronous endpoints. + * + * Number of bytes for isochronous endpoints in total. + * This number would be shared between IN and OUT endpoint. + * It may be also assigned totaly to one endpoint. + * @sa nrf_usbd_isosplit_set + * @sa nrf_usbd_isosplit_get + */ +#define NRFX_USBD_ISOSIZE 1023 + +/** + * @brief The size of internal feeder buffer. + * + * @sa nrfx_usbd_feeder_buffer_get + */ +#define NRFX_USBD_FEEDER_BUFFER_SIZE NRFX_USBD_EPSIZE + +/** + * @name Macros for creating endpoint identifiers. + * + * Auxiliary macros for creating endpoint identifiers compatible with the USB specification. + * @{ + */ + +/** + * @brief Create identifier for IN endpoint. + * + * Simple macro to create IN endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ +#define NRFX_USBD_EPIN(n) ((nrfx_usbd_ep_t)NRF_USBD_EPIN(n)) +/** + * @brief Create identifier for OUT endpoint. + * + * Simple macro to create OUT endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ +#define NRFX_USBD_EPOUT(n) ((nrfx_usbd_ep_t)NRF_USBD_EPOUT(n)) +/** @} */ + +/** + * @brief Endpoint identifier. + * + * Endpoint identifier used in the driver. + * This endpoint number is consistent with USB 2.0 specification. + */ +typedef enum { + NRFX_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ + NRFX_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ + NRFX_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ + NRFX_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ + NRFX_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ + NRFX_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ + NRFX_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ + NRFX_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ + NRFX_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ + + NRFX_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ + NRFX_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ + NRFX_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ + NRFX_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ + NRFX_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ + NRFX_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ + NRFX_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ + NRFX_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ + NRFX_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ +} nrfx_usbd_ep_t; + +/** + * @brief Events generated by the driver. + * + * Enumeration of possible events that may be generated by the driver. + */ +typedef enum { + NRFX_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected. */ + NRFX_USBD_EVT_RESET, /**< Reset condition on USB bus detected. */ + NRFX_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now. */ + NRFX_USBD_EVT_RESUME, /**< This device should resume from suspend now. */ + /** Wakeup request - the USBD peripheral is ready to generate + * WAKEUP signal after exiting low power mode. + */ + NRFX_USBD_EVT_WUREQ, + NRFX_USBD_EVT_SETUP, /**< Setup frame received and decoded. */ + /** For Rx (OUT: Host->Device): + * 1. The packet has been received but there is no buffer + * prepared for transfer already. + * 2. Whole transfer has been finished. + * + * For Tx (IN: Device->Host): + * The last packet from requested transfer has been transferred + * over USB bus and acknowledged. + */ + NRFX_USBD_EVT_EPTRANSFER, + NRFX_USBD_EVT_CNT /**< Number of defined events. */ +} nrfx_usbd_event_type_t; + +/** + * @brief Endpoint status codes. + * + * Status codes that may be returned by @ref nrfx_usbd_ep_status_get or, except for + * @ref NRFX_USBD_EP_BUSY, reported together with @ref NRFX_USBD_EVT_EPTRANSFER. + */ +typedef enum { + /** No error occurred. */ + NRFX_USBD_EP_OK, + /** Data received, no buffer prepared already - waiting for configured transfer. */ + NRFX_USBD_EP_WAITING, + /** Received number of bytes cannot fit given buffer. + * This error would also be returned when next_transfer function + * has been defined but currently received data cannot fit completely + * in current buffer. No data split from single endpoint transmission + * is supported. + * + * When this error is reported - data is left inside endpoint + * buffer. Clear endpoint or prepare new buffer and read it. + */ + NRFX_USBD_EP_OVERLOAD, + /** EP0 transfer can be aborted when new setup comes. + * Any other transfer can be aborted by USB reset or driver stopping. + */ + NRFX_USBD_EP_ABORTED, + /** Transfer is in progress. */ + NRFX_USBD_EP_BUSY, +} nrfx_usbd_ep_status_t; + +/** + * @brief Event structure. + * + * Structure passed to event handler. + */ +typedef struct { + nrfx_usbd_event_type_t type; /**< Event type. */ + union { + struct { + uint16_t framecnt; /**< Current value of frame counter. */ + } sof; /**< Data available for @ref NRFX_USBD_EVT_SOF. */ + struct { + nrfx_usbd_ep_t ep; /**< Endpoint number. */ + } isocrc; /**< Isochronouns channel endpoint number. */ + struct { + nrfx_usbd_ep_t ep; /**< Endpoint number. */ + nrfx_usbd_ep_status_t status; /**< Status for the endpoint. */ + } eptransfer; /**< Endpoint transfer status. */ + } data; /**< Union to store event data. */ +} nrfx_usbd_evt_t; + +/** + * @brief USBD event callback function type. + * + * @param[in] p_event Event information structure. + */ +typedef void (*nrfx_usbd_event_handler_t)(nrfx_usbd_evt_t const *p_event); + +/** + * @brief Universal data pointer. + * + * Universal data pointer that can be used for any type of transfer. + */ +typedef union { + void const *tx; /*!< Constant TX buffer pointer. */ + void *rx; /*!< Writable RX buffer pointer. */ + uint32_t addr; /*!< Numeric value used internally by the driver. */ +} nrfx_usbd_data_ptr_t; + +/** + * @brief Structure to be filled with information about the next transfer. + * + * This is used mainly for transfer feeders and consumers. + * It describes a single endpoint transfer and therefore the size of the buffer + * can never be higher than the endpoint size. + */ +typedef struct { + nrfx_usbd_data_ptr_t p_data; /*!< Union with available data pointers used by the driver. */ + size_t size; /*!< Size of the requested transfer. */ +} nrfx_usbd_ep_transfer_t; + +/** + * @brief Flags for the current transfer. + * + * Flags configured for the transfer that can be merged using the bitwise 'or' operator (|). + */ +typedef enum { + NRFX_USBD_TRANSFER_ZLP_FLAG = 1U << 0, /*!< Add a zero-length packet. */ +} nrfx_usbd_transfer_flags_t; + +/** + * @brief Total transfer configuration. + * + * This structure is used to configure total transfer information. + * It is used by internal built-in feeders and consumers. + */ +typedef struct { + nrfx_usbd_data_ptr_t p_data; /*!< Union with available data pointers used by the driver. */ + size_t size; /*!< Total size of the requested transfer. */ + uint32_t flags; /*!< Transfer flags. */ + /**< Use the @ref nrfx_usbd_transfer_flags_t values. */ +} nrfx_usbd_transfer_t; + +/** + * @brief Auxiliary macro for declaring IN transfer description with optional flags. + * + * The base macro for creating transfers with any configuration option. + * + * @param name Instance name. + * @param tx_buff Buffer to transfer. + * @param tx_size Transfer size. + * @param tx_flags Flags for the transfer (see @ref nrfx_usbd_transfer_flags_t). + * + * @return Configured variable with total transfer description. + */ +#define NRFX_USBD_TRANSFER_IN(name, tx_buff, tx_size, tx_flags) \ + const nrfx_usbd_transfer_t name = { \ + .p_data = {.tx = (tx_buff)}, .size = (tx_size), .flags = (tx_flags)} + +/** + * @brief Helper macro for declaring OUT transfer item (@ref nrfx_usbd_transfer_t). + * + * @param name Instance name. + * @param rx_buff Buffer to transfer. + * @param rx_size Transfer size. + */ +#define NRFX_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \ + const nrfx_usbd_transfer_t name = { \ + .p_data = {.rx = (rx_buff)}, .size = (rx_size), .flags = 0} + +/** + * @brief USBD transfer feeder. + * + * Pointer for a transfer feeder. + * Transfer feeder is a feedback function used to prepare a single + * TX (Device->Host) endpoint transfer. + * + * The transfers provided by the feeder must be simple: + * - The size of the transfer provided by this function is limited to a single endpoint buffer. + * Bigger transfers are not handled automatically in this case. + * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before. + * + * @note + * This function may use @ref nrfx_usbd_feeder_buffer_get to gain a temporary buffer + * that can be used to prepare transfer. + * + * @param[out] p_next Structure with the data for the next transfer to be filled. + * Required only if the function returns true. + * @param[in,out] p_context Context variable configured with the transfer. + * @param[in] ep_size The endpoint size. + * + * @retval false The current transfer is the last one - you do not need to call + * the function again. + * @retval true There is more data to be prepared and when the current transfer + * finishes, the feeder function is expected to be called again. + */ +typedef bool (*nrfx_usbd_feeder_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_context, + size_t ep_size); + +/** + * @brief USBD transfer consumer. + * + * Pointer for a transfer consumer. + * Transfer consumer is a feedback function used to prepare a single + * RX (Host->Device) endpoint transfer. + * + * The transfer must provide a buffer big enough to fit the whole data from the endpoint. + * Otherwise, the NRFX_USBD_EP_OVERLOAD event is generated. + * + * @param[out] p_next Structure with the data for the next transfer to be filled. + * Required only if the function returns true. + * @param[in,out] p_context Context variable configured with the transfer. + * @param[in] ep_size The endpoint size. + * @param[in] data_size Number of received bytes in the endpoint buffer. + * + * @retval false Current transfer is the last one - you do not need to call + * the function again. + * @retval true There is more data to be prepared and when current transfer + * finishes, the feeder function is expected to be called again. + */ +typedef bool (*nrfx_usbd_consumer_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_context, + size_t ep_size, size_t data_size); + +/** + * @brief Universal transfer handler. + * + * Union with feeder and consumer function pointer. + */ +typedef union { + nrfx_usbd_feeder_t feeder; /*!< Feeder function pointer. */ + nrfx_usbd_consumer_t consumer; /*!< Consumer function pointer. */ +} nrfx_usbd_handler_t; + +/** + * @brief USBD transfer descriptor. + * + * Universal structure that may hold the setup for callback configuration for + * IN or OUT type of the transfer. + */ +typedef struct { + nrfx_usbd_handler_t handler; /*!< Handler for the current transfer, function pointer. */ + void *p_context; /*!< Context for the transfer handler. */ +} nrfx_usbd_handler_desc_t; + +/** + * @brief Setup packet structure. + * + * Structure that contains interpreted SETUP packet as described in USB specification. + */ +typedef struct { + uint8_t bmRequestType; /*!< byte 0 */ + uint8_t bRequest; /*!< byte 1 */ + uint16_t wValue; /*!< byte 2, 3 */ + uint16_t wIndex; /*!< byte 4, 5 */ + uint16_t wLength; /*!< byte 6, 7 */ +} nrfx_usbd_setup_t; + +/** + * @brief Driver initialization. + * + * @param[in] event_handler Event handler provided by the user. Cannot be null. + * + * @retval NRFX_SUCCESS Initialization successful. + * @retval NRFX_ERROR_INVALID_STATE Driver was already initialized. + */ +nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler); + +/** + * @brief Driver deinitialization. + */ +void nrfx_usbd_uninit(void); + +/** + * @brief Enable the USBD port. + * + * After calling this function USBD peripheral would be enabled. + * The USB LDO would be enabled. + * Enabled USBD peripheral would request HFCLK. + * This function does not enable external oscillator, so if it is not enabled by other part of the + * program after enabling USBD driver HFINT would be used for the USBD peripheral. + * It is perfectly fine until USBD is started. See @ref nrfx_usbd_start. + * + * In normal situation this function should be called in reaction to USBDETECTED + * event from POWER peripheral. + * + * Interrupts and USB pins pull-up would stay disabled until @ref nrfx_usbd_start + * function is called. + */ +void nrfx_usbd_enable(void); + +/** + * @brief Disable the USBD port. + * + * After calling this function USBD peripheral would be disabled. + * No events would be detected or processed by the driver. + * Clock for the peripheral would be disconnected. + */ +void nrfx_usbd_disable(void); + +/** + * @brief Start USB functionality. + * + * After calling this function USBD peripheral should be fully functional + * and all new incoming events / interrupts would be processed by the driver. + * + * Also only after calling this function host sees new connected device. + * + * Call this function when USBD power LDO regulator is ready - on USBPWRRDY event + * from POWER peripheral. + * + * Before USBD interrupts are enabled, external HFXO is requested. + * + * @param enable_sof The flag that is used to enable SOF processing. + * If it is false, SOF interrupt is left disabled and will not be generated. + * This improves power saving if SOF is not required. + * + * @note If the isochronous endpoints are going to be used, + * it is required to enable the SOF. + * In other case any isochronous endpoint would stay busy + * after first transmission. + */ +void nrfx_usbd_start(bool enable_sof); + +/** + * @brief Stop USB functionality. + * + * This function disables USBD pull-up and interrupts. + * + * The HFXO request is released in this function. + * + * @note + * This function can also be used to logically disconnect USB from the HOST that + * would force it to enumerate device after calling @ref nrfx_usbd_start. + */ +void nrfx_usbd_stop(void); + +/** + * @brief Check if driver is initialized. + * + * @retval false Driver is not initialized. + * @retval true Driver is initialized. + */ +bool nrfx_usbd_is_initialized(void); + +/** + * @brief Check if driver is enabled. + * + * @retval false Driver is disabled. + * @retval true Driver is enabled. + */ +bool nrfx_usbd_is_enabled(void); + +/** + * @brief Check if driver is started. + * + * @retval false Driver is not started. + * @retval true Driver is started (fully functional). + * @note The USBD peripheral interrupt state is checked. + */ +bool nrfx_usbd_is_started(void); + +/** + * @brief Suspend USBD operation. + * + * The USBD peripheral is forced to go into the low power mode. + * The function has to be called in the reaction to @ref NRFX_USBD_EVT_SUSPEND event + * when the firmware is ready. + * + * After successful call of this function most of the USBD registers would be unavailable. + * + * @note Check returned value for the feedback if suspending was successful. + * + * @retval true USBD peripheral successfully suspended. + * @retval false USBD peripheral was not suspended due to resume detection. + */ +bool nrfx_usbd_suspend(void); + +/** + * @brief Start wake up procedure. + * + * The USBD peripheral is forced to quit the low power mode. + * After calling this function all the USBD registers would be available. + * + * The hardware starts measuring time when wake up is possible. + * This may take 0-5 ms depending on how long the SUSPEND state was kept on the USB line. + + * When NRFX_USBD_EVT_WUREQ event is generated it means that Wake Up signaling has just been + * started on the USB lines. + * + * @note Do not expect only @ref NRFX_USBD_EVT_WUREQ event. + * There always may appear @ref NRFX_USBD_EVT_RESUME event. + * @note NRFX_USBD_EVT_WUREQ event means that Remote WakeUp signal + * has just begun to be generated. + * This may take up to 20 ms for the bus to become active. + * + * @retval true WakeUp procedure started. + * @retval false No WakeUp procedure started - bus is already active. + */ +bool nrfx_usbd_wakeup_req(void); + +/** + * @brief Check if USBD is in SUSPEND mode. + * + * @note This is the information about peripheral itself, not about the bus state. + * + * @retval true USBD peripheral is suspended. + * @retval false USBD peripheral is active. + */ +bool nrfx_usbd_suspend_check(void); + +/** + * @brief Enable only interrupts that should be processed in SUSPEND mode. + * + * Auxiliary function to help with SUSPEND mode integration. + * It enables only the interrupts that can be properly processed without stable HFCLK. + * + * Normally all the interrupts are enabled. + * Use this function to suspend interrupt processing that may require stable HFCLK until the + * clock is enabled. + * + * @sa nrfx_usbd_active_irq_config + */ +void nrfx_usbd_suspend_irq_config(void); + +/** + * @brief Default active interrupt configuration. + * + * Default interrupt configuration. + * Use in a pair with @ref nrfx_usbd_active_irq_config. + * + * @sa nrfx_usbd_suspend_irq_config + */ +void nrfx_usbd_active_irq_config(void); + +/** + * @brief Check the bus state. + * + * This function checks if the bus state is suspended. + * + * @note The value returned by this function changes on SUSPEND and RESUME event processing. + * + * @retval true USBD bus is suspended. + * @retval false USBD bus is active. + */ +bool nrfx_usbd_bus_suspend_check(void); + +/** + * @brief Force the bus state to active + */ +void nrfx_usbd_force_bus_wakeup(void); + +/** + * @brief Configure packet size that should be supported by the endpoint. + * + * The real endpoint buffer size is always the same. + * This value sets max packet size that would be transmitted over the endpoint. + * This is required by the driver. + * + * @param[in] ep Endpoint number. + * @param[in] size Required maximum packet size. + * + * @note Endpoint size is always set to @ref NRFX_USBD_EPSIZE or @ref NRFX_USBD_ISOSIZE / 2 + * when @ref nrfx_usbd_ep_enable function is called. + */ +void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size); + +/** + * @brief Get configured endpoint packet size. + * + * Function to get configured endpoint size on the buffer. + * + * @param[in] ep Endpoint number. + * + * @return Maximum pocket size configured on selected endpoint. + */ +uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep); + +/** + * @brief Check if the selected endpoint is enabled. + * + * @param[in] ep Endpoint number to check. + * + * @retval true Endpoint is enabled. + * @retval false Endpoint is disabled. + */ +bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep); + +/** + * @brief Enable selected endpoint. + * + * This function enables endpoint itself and its interrupts. + * + * @param[in] ep Endpoint number to enable. + * + * @note + * Max packet size is set to endpoint default maximum value. + * + * @sa nrfx_usbd_ep_max_packet_size_set + */ +void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep); + +/** + * @brief Disable selected endpoint. + * + * This function disables endpoint itself and its interrupts. + * + * @param[in] ep Endpoint number to disable. + */ +void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep); + +/** + * @brief Disable all endpoints except for EP0. + * + * Disable all endpoints that can be disabled in USB device while it is still active. + */ +void nrfx_usbd_ep_default_config(void); + +/** + * @brief Start sending data over endpoint. + * + * Function initializes endpoint transmission. + * This is asynchronous function - it finishes immediately after configuration + * for transmission is prepared. + * + * @note Data buffer pointed by p_data have to be kept active till + * @ref NRFX_USBD_EVT_EPTRANSFER event is generated. + * + * @param[in] ep Endpoint number. + * For IN endpoint sending would be initiated. + * For OUT endpoint receiving would be initiated. + * @param[in] p_transfer Transfer parameters. + * + * @retval NRFX_SUCCESS Transfer queued or started. + * @retval NRFX_ERROR_BUSY Selected endpoint is pending. + * @retval NRFX_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. + */ +nrfx_err_t nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep, nrfx_usbd_transfer_t const *p_transfer); + +/** + * @brief Start sending data over the endpoint using the transfer handler function. + * + * This function initializes an endpoint transmission. + * Just before data is transmitted, the transfer handler + * is called and it prepares a data chunk. + * + * @param[in] ep Endpoint number. + * For an IN endpoint, sending is initiated. + * For an OUT endpoint, receiving is initiated. + * @param[in] p_handler Transfer handler - feeder for IN direction and consumer for + * OUT direction. + * + * @retval NRFX_SUCCESS Transfer queued or started. + * @retval NRFX_ERROR_BUSY Selected endpoint is pending. + * @retval NRFX_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. + */ +nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, + nrfx_usbd_handler_desc_t const *p_handler); + +/** + * @brief Get the temporary buffer to be used by the feeder. + * + * This buffer is used for TX transfers and it can be reused automatically + * when the transfer is finished. + * Use it for transfer preparation. + * + * May be used inside the feeder configured in @ref nrfx_usbd_ep_handled_transfer. + * + * @return Pointer to the buffer that can be used temporarily. + * + * @sa NRFX_USBD_FEEDER_BUFFER_SIZE + */ +void *nrfx_usbd_feeder_buffer_get(void); + +/** + * @brief Get the information about last finished or current transfer. + * + * Function returns the status of the last buffer set for transfer on selected endpoint. + * The status considers last buffer set by @ref nrfx_usbd_ep_transfer function or + * by transfer callback function. + * + * @param[in] ep Endpoint number. + * @param[out] p_size Information about the current/last transfer size. + * + * @return Endpoint status. + * + * @sa nrfx_usbd_ep_status_t + */ +nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t *p_size); + +/** + * @brief Get number of received bytes. + * + * Get the number of received bytes. + * The function behavior is undefined when called on IN endpoint. + * + * @param[in] ep Endpoint number. + * + * @return Number of received bytes. + */ +size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep); + +/** + * @brief Check if endpoint buffer is ready or is under USB IP control. + * + * Function to test if endpoint is busy. + * Endpoint that is busy cannot be accessed by MCU. + * It means that: + * - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting + * to be received by the host. + * - IN (RX) endpoint: Endpoint is ready to receive data from the host + * and the endpoint does not have any data. + * When endpoint is not busy: + * - OUT (TX) endpoint: New data can be uploaded. + * - IN (RX) endpoint: New data can be downloaded using @ref nrfx_usbd_ep_transfer + * function. + * + * @param[in] ep Endpoint number. + * + * @retval false Endpoint is not busy. + * @retval true Endpoint is busy. + */ +bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep); + +/** + * @brief Stall endpoint + * + * Stall endpoit to send error information during next transfer request from + * the host. + * + * @note To stall endpoint it is safer to use @ref nrfx_usbd_setup_stall + * @note Stalled endpoint would not be cleared when DMA transfer finishes. + * + * @param[in] ep Endpoint number to stall. + */ +void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep); + +/** + * @brief Clear stall flag on endpoint. + * + * This function clears endpoint that is stalled. + * @note + * If it is OUT endpoint (receiving) it would be also prepared for reception. + * It means that busy flag would be set. + * @note + * In endpoint (transmitting) would not be cleared - it gives possibility to + * write new data before transmitting. + * + * @param[in] ep Endpoint number. + */ +void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep); + +/** + * @brief Check if endpoint is stalled. + * + * This function gets stall state of selected endpoint. + * + * @param[in] ep Endpoint number to check. + * + * @retval false Endpoint is not stalled. + * @retval true Endpoint is stalled. + */ +bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep); + +/** + * @brief Clear current endpoint data toggle. + * + * @param[in] ep Endpoint number to clear. + */ +void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep); + +/** + * @brief Get parsed setup data. + * + * Function fills the parsed setup data structure. + * + * @param[out] p_setup Pointer to data structure that would be filled by + * parsed data. + */ +void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup); + +/** + * @brief Clear the control endpoint for packet reception during DATA stage. + * + * This function may be called if any more data in control write transfer is expected. + * Clears only OUT endpoint to be able to take another OUT data token. + * It does not allow STATUS stage. + * @sa nrfx_usbd_setup_clear + */ +void nrfx_usbd_setup_data_clear(void); + +/** + * @brief Clear setup endpoint. + * + * This function acknowledges setup when SETUP command was received and processed. + * It has to be called if no data respond for the SETUP command is sent. + */ +void nrfx_usbd_setup_clear(void); + +/** + * @brief Stall setup endpoint. + * + * Mark an error on setup endpoint. + */ +void nrfx_usbd_setup_stall(void); + +/** + * @brief Abort pending transfer on selected endpoint. + * + * @param[in] ep Endpoint number. + */ +void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep); + +/** + * @brief Get the information about expected transfer SETUP data direction. + * + * Function returns the information about last expected transfer direction. + * + * @retval NRFX_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data. + * @retval NRFX_USBD_EPIN0 Expecting IN (Device->Host) direction. + */ +nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void); + +/** + * @brief Drop transfer on OUT endpoint. + * + * @param[in] ep OUT endpoint ID. + */ +void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep); + +/** @} */ + +void nrfx_usbd_irq_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NRFX_USBD_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_usbd_errata.h b/modules/hal_nordic/nrfx/nrfx_usbd_errata.h new file mode 100644 index 00000000000..7ce8b3955d3 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_usbd_errata.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_USBD_ERRATA_H__ +#define NRFX_USBD_ERRATA_H__ + +#include +#include + +#ifndef NRFX_USBD_ERRATA_ENABLE +/** + * @brief The constant that informs if errata should be enabled at all. + * + * If this constant is set to 0, all the Errata bug fixes will be automatically disabled. + */ +#define NRFX_USBD_ERRATA_ENABLE 1 +#endif + +/* Errata: ISO double buffering not functional. **/ +static inline bool nrfx_usbd_errata_166(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_166(); +} + +/* Errata: USBD might not reach its active state. **/ +static inline bool nrfx_usbd_errata_171(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_171(); +} + +/* Errata: USB cannot be enabled. **/ +static inline bool nrfx_usbd_errata_187(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_187(); +} + +/* Errata: USBD cannot receive tasks during DMA. **/ +static inline bool nrfx_usbd_errata_199(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_199(); +} + +/* Errata: Device remains in SUSPEND too long. */ +static inline bool nrfx_usbd_errata_211(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_211(); +} + +/* Errata: Unexpected behavior after reset. **/ +static inline bool nrfx_usbd_errata_223(void) +{ + return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_223(); +} + +#endif /* NRFX_USBD_ERRATA_H__ */ From 8db69196950cf7dcebe69f7033250b069f424b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Tue, 17 Oct 2023 13:58:45 +0200 Subject: [PATCH 3198/4498] nrfx_usbd: Rename to nrf_usbd_common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename local usbd copy from nrfx_usbd to nrf_usbd_common and use it in both USB stacks. Renaming header to nrf_usbd_common.h allows breaking changes in exposed interface. Mark all doxygen comments as internal because local usbd copy should not be treated as public interface because we are under refactoring process that aims to arrive at native driver and therefore drop nrf_usbd_common in the future. Use Zephyr constructs directly instead of nrfx glue macros. No functional changes. Signed-off-by: Tomasz Moń --- drivers/usb/CMakeLists.txt | 1 + drivers/usb/Kconfig | 1 + drivers/usb/common/CMakeLists.txt | 3 + drivers/usb/common/Kconfig | 4 + .../usb/common/nrf_usbd_common/CMakeLists.txt | 10 + drivers/usb/common/nrf_usbd_common/Kconfig | 20 + .../common/nrf_usbd_common/nrf_usbd_common.c | 910 +++++++++--------- .../common/nrf_usbd_common/nrf_usbd_common.h | 308 +++--- .../nrf_usbd_common/nrf_usbd_common_errata.h | 64 ++ drivers/usb/device/Kconfig | 2 +- drivers/usb/device/usb_dc_nrfx.c | 139 +-- drivers/usb/udc/Kconfig.nrf | 2 +- drivers/usb/udc/udc_nrf.c | 115 +-- modules/hal_nordic/nrfx/CMakeLists.txt | 1 - modules/hal_nordic/nrfx/Kconfig | 13 - modules/hal_nordic/nrfx/Kconfig.logging | 4 - modules/hal_nordic/nrfx/nrfx_config.h | 11 - modules/hal_nordic/nrfx/nrfx_usbd_errata.h | 58 -- subsys/usb/device/Kconfig | 2 +- 19 files changed, 866 insertions(+), 802 deletions(-) create mode 100644 drivers/usb/common/CMakeLists.txt create mode 100644 drivers/usb/common/Kconfig create mode 100644 drivers/usb/common/nrf_usbd_common/CMakeLists.txt create mode 100644 drivers/usb/common/nrf_usbd_common/Kconfig rename modules/hal_nordic/nrfx/nrfx_usbd.c => drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c (62%) rename modules/hal_nordic/nrfx/nrfx_usbd.h => drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h (68%) create mode 100644 drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h delete mode 100644 modules/hal_nordic/nrfx/nrfx_usbd_errata.h diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 7a0570f146d..e0d9f196b29 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory_ifdef(CONFIG_UHC_DRIVER uhc) add_subdirectory_ifdef(CONFIG_UVB uvb) add_subdirectory_ifdef(CONFIG_USB_BC12 bc12) add_subdirectory_ifdef(CONFIG_USB_DEVICE_DRIVER device) +add_subdirectory(common) diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 369b40f6fa3..bcccdf6b657 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -8,3 +8,4 @@ source "drivers/usb/udc/Kconfig" source "drivers/usb/uhc/Kconfig" source "drivers/usb/uvb/Kconfig" source "drivers/usb/device/Kconfig" +source "drivers/usb/common/Kconfig" diff --git a/drivers/usb/common/CMakeLists.txt b/drivers/usb/common/CMakeLists.txt new file mode 100644 index 00000000000..56e4c734ced --- /dev/null +++ b/drivers/usb/common/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_HAS_NRFX nrf_usbd_common) diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig new file mode 100644 index 00000000000..7f6a02614b8 --- /dev/null +++ b/drivers/usb/common/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +rsource "nrf_usbd_common/Kconfig" diff --git a/drivers/usb/common/nrf_usbd_common/CMakeLists.txt b/drivers/usb/common/nrf_usbd_common/CMakeLists.txt new file mode 100644 index 00000000000..84952a8e5f8 --- /dev/null +++ b/drivers/usb/common/nrf_usbd_common/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_NRF_USBD_COMMON) + zephyr_library() + + zephyr_include_directories(.) + + zephyr_library_sources(nrf_usbd_common.c) +endif() diff --git a/drivers/usb/common/nrf_usbd_common/Kconfig b/drivers/usb/common/nrf_usbd_common/Kconfig new file mode 100644 index 00000000000..ae8f631fc72 --- /dev/null +++ b/drivers/usb/common/nrf_usbd_common/Kconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2016-2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +module = NRF_USBD_COMMON +module-str = nRF USBD common +source "subsys/logging/Kconfig.template.log_config" + +config NRF_USBD_COMMON + bool "USBD driver" + depends on HAS_NRFX + depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_USBD)) + +config NRF_USBD_ISO_IN_ZLP + bool "Send ZLP on ISO IN when not ready" + depends on NRF_USBD_COMMON + default y + help + Controls the response of the ISO IN endpoint to an IN token when no + data is ready to be sent. When enabled, ZLP is sent when no data is + ready. When disabled, no response is sent (bus timeout occurs). diff --git a/modules/hal_nordic/nrfx/nrfx_usbd.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c similarity index 62% rename from modules/hal_nordic/nrfx/nrfx_usbd.c rename to drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 886bf448ce2..0a7235e9b52 100644 --- a/modules/hal_nordic/nrfx/nrfx_usbd.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -4,74 +4,69 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +/* This file is undergoing transition towards native Zephyr nrf USB driver. */ + +/** @cond INTERNAL_HIDDEN */ -#if NRFX_CHECK(NRFX_USBD_ENABLED) +#include -#include -#include "nrfx_usbd_errata.h" +#include "nrf_usbd_common.h" +#include "nrf_usbd_common_errata.h" #include -#define NRFX_LOG_MODULE USBD -#include +#include +LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); -#ifndef NRFX_USBD_EARLY_DMA_PROCESS +#ifndef NRF_USBD_COMMON_EARLY_DMA_PROCESS /* Try to process DMA request when endpoint transmission has been detected * and just after last EasyDMA has been processed. * It speeds up the transmission a little (about 10% measured) * with a cost of more CPU power used. */ -#define NRFX_USBD_EARLY_DMA_PROCESS 1 -#endif - -#ifndef NRFX_USBD_STARTED_EV_ENABLE -#define NRFX_USBD_STARTED_EV_ENABLE 0 +#define NRF_USBD_COMMON_EARLY_DMA_PROCESS 1 #endif -#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP -/* - * Respond to an IN token on ISO IN endpoint with ZLP when no data is ready. - */ -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 +#ifndef NRF_USBD_COMMON_STARTED_EV_ENABLE +#define NRF_USBD_COMMON_STARTED_EV_ENABLE 0 #endif -#ifndef NRFX_USBD_ISO_DEBUG +#ifndef NRF_USBD_COMMON_ISO_DEBUG /* Also generate information about ISOCHRONOUS events and transfers. * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this * option generates a lot of useless messages. */ -#define NRFX_USBD_ISO_DEBUG 1 +#define NRF_USBD_COMMON_ISO_DEBUG 1 #endif -#ifndef NRFX_USBD_FAILED_TRANSFERS_DEBUG +#ifndef NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG /* Also generate debug information for failed transfers. * It might be useful but may generate a lot of useless debug messages * in some library usages (for example when transfer is generated and the * result is used to check whatever endpoint was busy. */ -#define NRFX_USBD_FAILED_TRANSFERS_DEBUG 1 +#define NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG 1 #endif -#ifndef NRFX_USBD_DMAREQ_PROCESS_DEBUG +#ifndef NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG /* Generate additional messages that mark the status inside * @ref usbd_dmareq_process. * It is useful to debug library internals but may generate a lot of * useless debug messages. */ -#define NRFX_USBD_DMAREQ_PROCESS_DEBUG 1 +#define NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG 1 #endif -#ifndef NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 +#ifndef NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 /* Anomaly 211 - Device remains in SUSPEND too long when host resumes * a bus activity (sending SOF packets) without a RESUME condition. */ -#define NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 0 +#define NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 0 #endif /** - * @defgroup nrfx_usbd_int USB Device driver internal part + * @defgroup nrf_usbd_common_int USB Device driver internal part * @internal - * @ingroup nrfx_usbd + * @ingroup nrf_usbd_common * * This part contains auxiliary internal macros, variables and functions. * @{ @@ -85,10 +80,9 @@ * * @param ep Endpoint number to validity check. */ -#define NRFX_USBD_ASSERT_EP_VALID(ep) \ - NRFX_ASSERT( \ - ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) || \ - (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)))); +#define NRF_USBD_COMMON_ASSERT_EP_VALID(ep) __ASSERT_NO_MSG( \ + ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) || \ + (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)))); /** * @brief Lowest position of bit for IN endpoint. @@ -96,7 +90,7 @@ * The first bit position corresponding to IN endpoint. * @sa ep2bit bit2ep */ -#define NRFX_USBD_EPIN_BITPOS_0 0 +#define NRF_USBD_COMMON_EPIN_BITPOS_0 0 /** * @brief Lowest position of bit for OUT endpoint. @@ -104,24 +98,24 @@ * The first bit position corresponding to OUT endpoint * @sa ep2bit bit2ep */ -#define NRFX_USBD_EPOUT_BITPOS_0 16 +#define NRF_USBD_COMMON_EPOUT_BITPOS_0 16 /** * @brief Input endpoint bits mask. */ -#define NRFX_USBD_EPIN_BIT_MASK (0xFFFFU << NRFX_USBD_EPIN_BITPOS_0) +#define NRF_USBD_COMMON_EPIN_BIT_MASK (0xFFFFU << NRF_USBD_COMMON_EPIN_BITPOS_0) /** * @brief Output endpoint bits mask. */ -#define NRFX_USBD_EPOUT_BIT_MASK (0xFFFFU << NRFX_USBD_EPOUT_BITPOS_0) +#define NRF_USBD_COMMON_EPOUT_BIT_MASK (0xFFFFU << NRF_USBD_COMMON_EPOUT_BITPOS_0) /** * @brief Isochronous endpoint bit mask */ -#define USBD_EPISO_BIT_MASK \ - ((1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT8)) | \ - (1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN8))) +#define USBD_EPISO_BIT_MASK \ + ((1U << NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT8)) | \ + (1U << NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN8))) /** * @brief Auxiliary macro to change EP number into bit position. @@ -132,9 +126,9 @@ * @param[in] ep Endpoint number. * @return Endpoint bit position. */ -#define NRFX_USBD_EP_BITPOS(ep) \ - ((NRF_USBD_EPIN_CHECK(ep) ? NRFX_USBD_EPIN_BITPOS_0 : NRFX_USBD_EPOUT_BITPOS_0) + \ - NRF_USBD_EP_NR_GET(ep)) +#define NRF_USBD_COMMON_EP_BITPOS(ep) \ + ((NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_COMMON_EPIN_BITPOS_0 : NRF_USBD_COMMON_EPOUT_BITPOS_0)\ + + NRF_USBD_EP_NR_GET(ep)) /** * @brief Helper macro for creating an endpoint transfer event. @@ -145,25 +139,28 @@ * * @return Initialized event constant variable. */ -#define NRFX_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ - const nrfx_usbd_evt_t name = {NRFX_USBD_EVT_EPTRANSFER, \ +#define NRF_USBD_COMMON_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ + const nrf_usbd_common_evt_t name = {NRF_USBD_COMMON_EVT_EPTRANSFER, \ .data = {.eptransfer = {.ep = endpont, .status = ep_stat}}} /* Check it the bit positions values match defined DATAEPSTATUS bit positions */ -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos); -NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos); +BUILD_ASSERT( + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos) && + (NRF_USBD_COMMON_EP_BITPOS(NRF_USBD_COMMON_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos), + "NRF_USBD_COMMON bit positions do not match hardware" +); /** * @brief Current driver state. @@ -177,7 +174,7 @@ static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; * * @note Currently it cannot be null if any interrupt is activated. */ -static nrfx_usbd_event_handler_t m_event_handler; +static nrf_usbd_common_event_handler_t m_event_handler; /** * @brief Detected state of the bus. @@ -196,8 +193,8 @@ static volatile bool m_bus_suspend; /** * @brief Internal constant that contains interrupts disabled in suspend state. * - * Internal constant used in @ref nrfx_usbd_suspend_irq_config and @ref nrfx_usbd_active_irq_config - * functions. + * Internal constant used in @ref nrf_usbd_common_suspend_irq_config and + * @ref nrf_usbd_common_active_irq_config functions. */ static const uint32_t m_irq_disabled_in_suspend = NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | NRF_USBD_INT_ENDEPOUT0_MASK | @@ -209,7 +206,7 @@ static const uint32_t m_irq_disabled_in_suspend = * This variable is used to redirect internal setup data event * into selected endpoint (IN or OUT). */ -static nrfx_usbd_ep_t m_last_setup_dir; +static nrf_usbd_common_ep_t m_last_setup_dir; /** * @brief Mark endpoint readiness for DMA transfer. @@ -229,7 +226,7 @@ static uint32_t m_ep_ready; * Mask prepared USBD data for transmission. * It is cleared when no more data to transmit left. */ -static nrfx_atomic_t m_ep_dma_waiting; +static atomic_t m_ep_dma_waiting; /** * @brief Current EasyDMA state. @@ -258,12 +255,16 @@ static bool m_first_enable = true; * buffer is ready. */ typedef struct { - nrfx_usbd_handler_t handler; /*!< Handler for current transfer, function pointer. */ - void *p_context; /*!< Context for transfer handler. */ - size_t transfer_cnt; /*!< Number of transferred bytes in the current transfer. */ - uint16_t max_packet_size; /*!< Configured endpoint size. */ - nrfx_usbd_ep_status_t status; /*!< NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY */ - /*!< - this one is calculated. */ + /** Handler for current transfer, function pointer. */ + nrf_usbd_common_handler_t handler; + /** Context for transfer handler. */ + void *p_context; + /** Number of transferred bytes in the current transfer. */ + size_t transfer_cnt; + /** Configured endpoint size. */ + uint16_t max_packet_size; + /** NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY - this one is calculated. */ + nrf_usbd_common_ep_status_t status; } usbd_ep_state_t; /** @@ -286,7 +287,7 @@ static struct { * 3. RAM transfer with automatic ZLP. * 4. Flash transfer with automatic ZLP. */ -nrfx_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; +nrf_usbd_common_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; /** * @brief Status variables for integrated consumers. @@ -298,7 +299,7 @@ nrfx_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; * Transfer is finished automatically when received data block is smaller * than the endpoint buffer or all the required data is received. */ -nrfx_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; +nrf_usbd_common_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; /** * @brief Buffer used to send data directly from FLASH. @@ -310,7 +311,7 @@ nrfx_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; * We do not need more buffers that one, because only one transfer can be pending * at once. */ -static uint32_t m_tx_buffer[NRFX_CEIL_DIV(NRFX_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))]; +static uint32_t m_tx_buffer[NRFX_CEIL_DIV(NRF_USBD_COMMON_FEEDER_BUFFER_SIZE, sizeof(uint32_t))]; /* Early declaration. Documentation above definition. */ static void usbd_dmareq_process(void); @@ -322,11 +323,11 @@ static void usbd_dmareq_process(void); * * @return Connected endpoint event code. * - * Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE <<. + * Marker to delete when not required anymore: >> NRF_USBD_COMMON_ERRATA_ENABLE <<. */ -static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep) +static inline nrf_usbd_event_t nrf_usbd_common_ep_to_endevent(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); static const nrf_usbd_event_t epin_endev[] = { NRF_USBD_EVENT_ENDEPIN0, NRF_USBD_EVENT_ENDEPIN1, NRF_USBD_EVENT_ENDEPIN2, @@ -348,9 +349,9 @@ static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep) * @return Interrupt mask related to the EasyDMA transfer end for the * chosen endpoint. */ -static inline uint32_t nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep) +static inline uint32_t nrf_usbd_common_ep_to_int(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); static const uint8_t epin_bitpos[] = { USBD_INTEN_ENDEPIN0_Pos, USBD_INTEN_ENDEPIN1_Pos, USBD_INTEN_ENDEPIN2_Pos, @@ -375,26 +376,26 @@ static inline uint32_t nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep) /** * @brief Integrated consumer to RAM buffer. * - * @param p_next See @ref nrfx_usbd_consumer_t documentation. - * @param p_context See @ref nrfx_usbd_consumer_t documentation. - * @param ep_size See @ref nrfx_usbd_consumer_t documentation. - * @param data_size See @ref nrfx_usbd_consumer_t documentation. + * @param p_next See @ref nrf_usbd_common_consumer_t documentation. + * @param p_context See @ref nrf_usbd_common_consumer_t documentation. + * @param ep_size See @ref nrf_usbd_common_consumer_t documentation. + * @param data_size See @ref nrf_usbd_common_consumer_t documentation. * * @retval true Continue transfer. * @retval false This was the last transfer. */ -bool nrfx_usbd_consumer(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size, - size_t data_size) +bool nrf_usbd_common_consumer(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, + size_t ep_size, size_t data_size) { - nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - NRFX_ASSERT(ep_size >= data_size); - NRFX_ASSERT((p_transfer->p_data.rx == NULL) || nrfx_is_in_ram(p_transfer->p_data.rx)); + __ASSERT_NO_MSG(ep_size >= data_size); + __ASSERT_NO_MSG((p_transfer->p_data.rx == NULL) || nrfx_is_in_ram(p_transfer->p_data.rx)); size_t size = p_transfer->size; if (size < data_size) { - NRFX_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size); + LOG_DBG("consumer: buffer too small: r: %u, l: %u", data_size, size); /* Buffer size to small */ p_next->size = 0; p_next->p_data = p_transfer->p_data; @@ -411,18 +412,19 @@ bool nrfx_usbd_consumer(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t /** * @brief Integrated feeder from RAM source. * - * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. + * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. * * @retval true Continue transfer. * @retval false This was the last transfer. */ -bool nrfx_usbd_feeder_ram(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +bool nrf_usbd_common_feeder_ram(nrf_usbd_common_ep_transfer_t *p_next, + void *p_context, size_t ep_size) { - nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx)); + __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); size_t tx_size = p_transfer->size; @@ -442,18 +444,19 @@ bool nrfx_usbd_feeder_ram(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size /** * @brief Integrated feeder from RAM source with ZLP. * - * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. + * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. * * @retval true Continue transfer. * @retval false This was the last transfer. */ -bool nrfx_usbd_feeder_ram_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +bool nrf_usbd_common_feeder_ram_zlp(nrf_usbd_common_ep_transfer_t *p_next, + void *p_context, size_t ep_size) { - nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx)); + __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); size_t tx_size = p_transfer->size; @@ -473,27 +476,28 @@ bool nrfx_usbd_feeder_ram_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context, /** * @brief Integrated feeder from a flash source. * - * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. + * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. * * @retval true Continue transfer. * @retval false This was the last transfer. */ -bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +bool nrf_usbd_common_feeder_flash(nrf_usbd_common_ep_transfer_t *p_next, + void *p_context, size_t ep_size) { - nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx)); + __ASSERT_NO_MSG(!nrfx_is_in_ram(p_transfer->p_data.tx)); size_t tx_size = p_transfer->size; - void *p_buffer = nrfx_usbd_feeder_buffer_get(); + void *p_buffer = nrf_usbd_common_feeder_buffer_get(); if (tx_size > ep_size) { tx_size = ep_size; } - NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE); + __ASSERT_NO_MSG(tx_size <= NRF_USBD_COMMON_FEEDER_BUFFER_SIZE); memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); p_next->p_data.tx = p_buffer; @@ -508,27 +512,28 @@ bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t *p_next, void *p_context, si /** * @brief Integrated feeder from a flash source with ZLP. * - * @param[out] p_next See @ref nrfx_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrfx_usbd_feeder_t documentation. + * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. + * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. * * @retval true Continue transfer. * @retval false This was the last transfer. */ -bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context, size_t ep_size) +bool nrf_usbd_common_feeder_flash_zlp(nrf_usbd_common_ep_transfer_t *p_next, + void *p_context, size_t ep_size) { - nrfx_usbd_transfer_t *p_transfer = (nrfx_usbd_transfer_t *)p_context; + nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx)); + __ASSERT_NO_MSG(!nrfx_is_in_ram(p_transfer->p_data.tx)); size_t tx_size = p_transfer->size; - void *p_buffer = nrfx_usbd_feeder_buffer_get(); + void *p_buffer = nrf_usbd_common_feeder_buffer_get(); if (tx_size > ep_size) { tx_size = ep_size; } - NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE); + __ASSERT_NO_MSG(tx_size <= NRF_USBD_COMMON_FEEDER_BUFFER_SIZE); if (tx_size != 0) { memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); @@ -553,11 +558,11 @@ bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t *p_next, void *p_context * * @return Endpoint identifier in HAL. * - * @sa nrfx_usbd_ep_from_hal + * @sa nrf_usbd_common_ep_from_hal */ -static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep) +static inline uint8_t ep_to_hal(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); return (uint8_t)ep; } @@ -568,9 +573,9 @@ static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep) * * @return Task for starting EasyDMA transfer on selected endpoint. */ -static inline nrf_usbd_task_t task_start_ep(nrfx_usbd_ep_t ep) +static inline nrf_usbd_task_t task_start_ep(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); return (nrf_usbd_task_t)((NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) + (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); @@ -584,9 +589,9 @@ static inline nrf_usbd_task_t task_start_ep(nrfx_usbd_ep_t ep) * * @param ep Endpoint number. */ -static inline usbd_ep_state_t *ep_state_access(nrfx_usbd_ep_t ep) +static inline usbd_ep_state_t *ep_state_access(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + NRF_USBD_EP_NR_GET(ep)); } @@ -603,10 +608,10 @@ static inline usbd_ep_state_t *ep_state_access(nrfx_usbd_ep_t ep) * * @sa bit2ep */ -static inline uint8_t ep2bit(nrfx_usbd_ep_t ep) +static inline uint8_t ep2bit(nrf_usbd_common_ep_t ep) { - NRFX_USBD_ASSERT_EP_VALID(ep); - return NRFX_USBD_EP_BITPOS(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); + return NRF_USBD_COMMON_EP_BITPOS(ep); } /** @@ -618,11 +623,12 @@ static inline uint8_t ep2bit(nrfx_usbd_ep_t ep) * * @sa ep2bit */ -static inline nrfx_usbd_ep_t bit2ep(uint8_t bitpos) +static inline nrf_usbd_common_ep_t bit2ep(uint8_t bitpos) { - NRFX_STATIC_ASSERT(NRFX_USBD_EPOUT_BITPOS_0 > NRFX_USBD_EPIN_BITPOS_0); - return (nrfx_usbd_ep_t)((bitpos >= NRFX_USBD_EPOUT_BITPOS_0) - ? NRF_USBD_EPOUT(bitpos - NRFX_USBD_EPOUT_BITPOS_0) + BUILD_ASSERT(NRF_USBD_COMMON_EPOUT_BITPOS_0 > NRF_USBD_COMMON_EPIN_BITPOS_0, + "OUT endpoint bits should be higher than IN endpoint bits"); + return (nrf_usbd_common_ep_t)((bitpos >= NRF_USBD_COMMON_EPOUT_BITPOS_0) + ? NRF_USBD_EPOUT(bitpos - NRF_USBD_COMMON_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos)); } @@ -634,7 +640,7 @@ static inline nrfx_usbd_ep_t bit2ep(uint8_t bitpos) */ static inline void usbd_dma_pending_set(void) { - if (nrfx_usbd_errata_199()) { + if (nrf_usbd_common_errata_199()) { *((volatile uint32_t *)0x40027C1C) = 0x00000082; } m_dma_pending = true; @@ -648,7 +654,7 @@ static inline void usbd_dma_pending_set(void) */ static inline void usbd_dma_pending_clear(void) { - if (nrfx_usbd_errata_199()) { + if (nrf_usbd_common_errata_199()) { *((volatile uint32_t *)0x40027C1C) = 0x00000000; } m_dma_pending = false; @@ -664,17 +670,17 @@ static inline void usbd_dma_pending_clear(void) * If it is OUT endpoint transmission would be directed from endpoint to RAM. * If it is in endpoint transmission would be directed from RAM to endpoint. */ -static inline void usbd_dma_start(nrfx_usbd_ep_t ep) +static inline void usbd_dma_start(nrf_usbd_common_ep_t ep) { nrf_usbd_task_trigger(NRF_USBD, task_start_ep(ep)); } -void nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config) +void nrf_usbd_common_isoinconfig_set(nrf_usbd_isoinconfig_t config) { nrf_usbd_isoinconfig_set(NRF_USBD, config); } -nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void) +nrf_usbd_isoinconfig_t nrf_usbd_common_isoinconfig_get(void) { return nrf_usbd_isoinconfig_get(NRF_USBD); } @@ -692,10 +698,9 @@ nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void) * @endcode * This function would check it again, but it makes it inside critical section. */ -static inline void usbd_ep_abort(nrfx_usbd_ep_t ep) +static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) { - NRFX_CRITICAL_SECTION_ENTER(); - + unsigned int irq_lock_key = irq_lock(); usbd_ep_state_t *p_state = ep_state_access(ep); if (NRF_USBD_EPOUT_CHECK(ep)) { @@ -704,18 +709,18 @@ static inline void usbd_ep_abort(nrfx_usbd_ep_t ep) /* If the bit in m_ep_dma_waiting in cleared - nothing would be * processed inside transfer processing */ - nrfx_usbd_transfer_out_drop(ep); + nrf_usbd_common_transfer_out_drop(ep); } else { p_state->handler.consumer = NULL; m_ep_dma_waiting &= ~(1U << ep2bit(ep)); m_ep_ready &= ~(1U << ep2bit(ep)); } /* Aborted */ - p_state->status = NRFX_USBD_EP_ABORTED; + p_state->status = NRF_USBD_COMMON_EP_ABORTED; } else { if (!NRF_USBD_EPISO_CHECK(ep)) { /* Workaround: Disarm the endpoint if there is any data buffered. */ - if (ep != NRFX_USBD_EPIN0) { + if (ep != NRF_USBD_COMMON_EPIN0) { *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1)); uint8_t temp = @@ -738,15 +743,16 @@ static inline void usbd_ep_abort(nrfx_usbd_ep_t ep) m_ep_ready |= 1U << ep2bit(ep); p_state->handler.feeder = NULL; - p_state->status = NRFX_USBD_EP_ABORTED; - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_ABORTED); + p_state->status = NRF_USBD_COMMON_EP_ABORTED; + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_ABORTED); m_event_handler(&evt); } } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } -void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_abort(nrf_usbd_common_ep_t ep) { usbd_ep_abort(ep); } @@ -758,7 +764,7 @@ void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep) */ static void usbd_ep_abort_all(void) { - uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & NRFX_USBD_EPOUT_BIT_MASK); + uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & NRF_USBD_COMMON_EPOUT_BIT_MASK); while (ep_waiting != 0) { uint8_t bitpos = NRF_CTZ(ep_waiting); @@ -769,7 +775,7 @@ static void usbd_ep_abort_all(void) ep_waiting &= ~(1U << bitpos); } - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0); + m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); } /** @@ -780,7 +786,7 @@ static void usbd_ep_abort_all(void) */ static inline void usbd_int_rise(void) { - NRFX_IRQ_PENDING_SET(USBD_IRQn); + NVIC_SetPendingIRQ(USBD_IRQn); } /** @@ -793,16 +799,16 @@ static inline void usbd_int_rise(void) static void ev_usbreset_handler(void) { m_bus_suspend = false; - m_last_setup_dir = NRFX_USBD_EPOUT0; + m_last_setup_dir = NRF_USBD_COMMON_EPOUT0; - const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_RESET}; + const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_RESET}; m_event_handler(&evt); } static void ev_started_handler(void) { -#if NRFX_USBD_STARTED_EV_ENABLE +#if NRF_USBD_COMMON_STARTED_EV_ENABLE /* Handler not used by the stack. * May be used for debugging. */ @@ -820,18 +826,18 @@ static void ev_started_handler(void) */ static inline void nrf_usbd_ep0in_dma_handler(void) { - const nrfx_usbd_ep_t ep = NRFX_USBD_EPIN0; + const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPIN0; - NRFX_LOG_DEBUG("USB event: DMA ready IN0"); + LOG_DBG("USB event: DMA ready IN0"); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else if (p_state->handler.feeder == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else { /* Nothing to do */ } @@ -846,21 +852,21 @@ static inline void nrf_usbd_ep0in_dma_handler(void) * * @param[in] ep Endpoint number. */ -static inline void nrf_usbd_epin_dma_handler(nrfx_usbd_ep_t ep) +static inline void nrf_usbd_epin_dma_handler(nrf_usbd_common_ep_t ep) { - NRFX_LOG_DEBUG("USB event: DMA ready IN: %x", ep); - NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep)); - NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep)); - NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); + LOG_DBG("USB event: DMA ready IN: %x", ep); + __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); + __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else if (p_state->handler.feeder == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else { /* Nothing to do */ } @@ -869,26 +875,26 @@ static inline void nrf_usbd_epin_dma_handler(nrfx_usbd_ep_t ep) /** * @brief Handler for EasyDMA event from in isochronous endpoint. */ -static inline void nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep) +static inline void nrf_usbd_epiniso_dma_handler(nrf_usbd_common_ep_t ep) { - if (NRFX_USBD_ISO_DEBUG) { - NRFX_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep); + if (NRF_USBD_COMMON_ISO_DEBUG) { + LOG_DBG("USB event: DMA ready ISOIN: %x", ep); } - NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep)); - NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else if (p_state->handler.feeder == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished * in this moment */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); m_event_handler(&evt); } else { /* Nothing to do */ @@ -904,25 +910,25 @@ static inline void nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep) */ static inline void nrf_usbd_ep0out_dma_handler(void) { - const nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT0; + const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPOUT0; - NRFX_LOG_DEBUG("USB event: DMA ready OUT0"); + LOG_DBG("USB event: DMA ready OUT0"); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else if (p_state->handler.consumer == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); /* Send event to the user - for an OUT endpoint, the whole transfer is finished in * this moment */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); m_event_handler(&evt); } else { - nrfx_usbd_setup_data_clear(); + nrf_usbd_common_setup_data_clear(); } } @@ -933,31 +939,31 @@ static inline void nrf_usbd_ep0out_dma_handler(void) * * @param[in] ep Endpoint number. */ -static inline void nrf_usbd_epout_dma_handler(nrfx_usbd_ep_t ep) +static inline void nrf_usbd_epout_dma_handler(nrf_usbd_common_ep_t ep) { - NRFX_LOG_DEBUG("DMA ready OUT: %x", ep); - NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep)); - NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep)); - NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); + LOG_DBG("DMA ready OUT: %x", ep); + __ASSERT_NO_MSG(NRF_USBD_EPOUT_CHECK(ep)); + __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); } else if (p_state->handler.consumer == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); /* Send event to the user - for an OUT endpoint, the whole transfer is finished in * this moment */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); m_event_handler(&evt); } else { /* Nothing to do */ } -#if NRFX_USBD_EARLY_DMA_PROCESS +#if NRF_USBD_COMMON_EARLY_DMA_PROCESS /* Speed up */ usbd_dmareq_process(); #endif @@ -966,24 +972,24 @@ static inline void nrf_usbd_epout_dma_handler(nrfx_usbd_ep_t ep) /** * @brief Handler for EasyDMA event from out isochronous endpoint. */ -static inline void nrf_usbd_epoutiso_dma_handler(nrfx_usbd_ep_t ep) +static inline void nrf_usbd_epoutiso_dma_handler(nrf_usbd_common_ep_t ep) { - if (NRFX_USBD_ISO_DEBUG) { - NRFX_LOG_DEBUG("DMA ready ISOOUT: %x", ep); + if (NRF_USBD_COMMON_ISO_DEBUG) { + LOG_DBG("DMA ready ISOOUT: %x", ep); } - NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); usbd_dma_pending_clear(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (p_state->status == NRFX_USBD_EP_ABORTED) { + if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Nothing to do - just ignore */ } else if (p_state->handler.consumer == NULL) { - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); /* Send event to the user - for an OUT endpoint, the whole transfer is finished in * this moment */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); m_event_handler(&evt); } else { /* Nothing to do */ @@ -996,35 +1002,35 @@ static void ev_dma_epin0_handler(void) } static void ev_dma_epin1_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN1); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN1); } static void ev_dma_epin2_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN2); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN2); } static void ev_dma_epin3_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN3); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN3); } static void ev_dma_epin4_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN4); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN4); } static void ev_dma_epin5_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN5); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN5); } static void ev_dma_epin6_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN6); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN6); } static void ev_dma_epin7_handler(void) { - nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN7); + nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN7); } static void ev_dma_epin8_handler(void) { - nrf_usbd_epiniso_dma_handler(NRFX_USBD_EPIN8); + nrf_usbd_epiniso_dma_handler(NRF_USBD_COMMON_EPIN8); } static void ev_dma_epout0_handler(void) @@ -1033,48 +1039,49 @@ static void ev_dma_epout0_handler(void) } static void ev_dma_epout1_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT1); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT1); } static void ev_dma_epout2_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT2); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT2); } static void ev_dma_epout3_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT3); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT3); } static void ev_dma_epout4_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT4); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT4); } static void ev_dma_epout5_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT5); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT5); } static void ev_dma_epout6_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT6); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT6); } static void ev_dma_epout7_handler(void) { - nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT7); + nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT7); } static void ev_dma_epout8_handler(void) { - nrf_usbd_epoutiso_dma_handler(NRFX_USBD_EPOUT8); + nrf_usbd_epoutiso_dma_handler(NRF_USBD_COMMON_EPOUT8); } static void ev_sof_handler(void) { - nrfx_usbd_evt_t evt = { - NRFX_USBD_EVT_SOF, + nrf_usbd_common_evt_t evt = { + NRF_USBD_COMMON_EVT_SOF, .data = {.sof = {.framecnt = (uint16_t)nrf_usbd_framecntr_get(NRF_USBD)}}}; /* Process isochronous endpoints */ - uint32_t iso_ready_mask = (1U << ep2bit(NRFX_USBD_EPIN8)); + uint32_t iso_ready_mask = (1U << ep2bit(NRF_USBD_COMMON_EPIN8)); - if (nrf_usbd_episoout_size_get(NRF_USBD, NRFX_USBD_EPOUT8) != NRF_USBD_EPISOOUT_NO_DATA) { - iso_ready_mask |= (1U << ep2bit(NRFX_USBD_EPOUT8)); + if (nrf_usbd_episoout_size_get(NRF_USBD, NRF_USBD_COMMON_EPOUT8) != + NRF_USBD_EPISOOUT_NO_DATA) { + iso_ready_mask |= (1U << ep2bit(NRF_USBD_COMMON_EPOUT8)); } m_ep_ready |= iso_ready_mask; @@ -1088,9 +1095,9 @@ static void ev_sof_handler(void) * @param ep Endpoint number. * @param bitpos Bit position for selected endpoint number. */ -static void usbd_ep_data_handler(nrfx_usbd_ep_t ep, uint8_t bitpos) +static void usbd_ep_data_handler(nrf_usbd_common_ep_t ep, uint8_t bitpos) { - NRFX_LOG_DEBUG("USBD event: EndpointData: %x", ep); + LOG_DBG("USBD event: EndpointData: %x", ep); /* Mark endpoint ready for next DMA access */ m_ep_ready |= (1U << bitpos); @@ -1103,8 +1110,8 @@ static void usbd_ep_data_handler(nrfx_usbd_ep_t ep, uint8_t bitpos) * process, the OUT handler might call usbd_ep_data_handler without calling * nrf_usbd_epin_dma_handler (or nrf_usbd_ep0in_dma_handler) for the IN transaction. */ - if (nrf_usbd_event_get_and_clear(NRF_USBD, nrfx_usbd_ep_to_endevent(ep))) { - if (ep != NRFX_USBD_EPIN0) { + if (nrf_usbd_event_get_and_clear(NRF_USBD, nrf_usbd_common_ep_to_endevent(ep))) { + if (ep != NRF_USBD_COMMON_EPIN0) { nrf_usbd_epin_dma_handler(ep); } else { nrf_usbd_ep0in_dma_handler(); @@ -1112,17 +1119,17 @@ static void usbd_ep_data_handler(nrfx_usbd_ep_t ep, uint8_t bitpos) } if (0 == (m_ep_dma_waiting & (1U << bitpos))) { - NRFX_LOG_DEBUG("USBD event: EndpointData: In finished"); + LOG_DBG("USBD event: EndpointData: In finished"); /* No more data to be send - transmission finished */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); m_event_handler(&evt); } } else { /* OUT endpoint (Host -> Device) */ if (0 == (m_ep_dma_waiting & (1U << bitpos))) { - NRFX_LOG_DEBUG("USBD event: EndpointData: Out waiting"); + LOG_DBG("USBD event: EndpointData: Out waiting"); /* No buffer prepared - send event to the application */ - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_WAITING); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_WAITING); m_event_handler(&evt); } } @@ -1135,29 +1142,29 @@ static void ev_setup_data_handler(void) static void ev_setup_handler(void) { - NRFX_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", + LOG_DBG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", nrf_usbd_setup_bmrequesttype_get(NRF_USBD), nrf_usbd_setup_brequest_get(NRF_USBD), nrf_usbd_setup_wvalue_get(NRF_USBD), nrf_usbd_setup_windex_get(NRF_USBD), nrf_usbd_setup_wlength_get(NRF_USBD)); uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); - if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & (1U << ep2bit(m_last_setup_dir))) { - NRFX_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0"); + LOG_DBG("USBD drv: Trying to abort last transfer on EP0"); usbd_ep_abort(m_last_setup_dir); } m_last_setup_dir = ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) == (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) - ? NRFX_USBD_EPOUT0 - : NRFX_USBD_EPIN0; + ? NRF_USBD_COMMON_EPOUT0 + : NRF_USBD_COMMON_EPIN0; - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~((1U << ep2bit(NRFX_USBD_EPOUT0)) | - (1U << ep2bit(NRFX_USBD_EPIN0))))); - m_ep_ready |= 1U << ep2bit(NRFX_USBD_EPIN0); + (void)(atomic_and(&m_ep_dma_waiting, ~((1U << ep2bit(NRF_USBD_COMMON_EPOUT0)) | + (1U << ep2bit(NRF_USBD_COMMON_EPIN0))))); + m_ep_ready |= 1U << ep2bit(NRF_USBD_COMMON_EPIN0); - const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_SETUP}; + const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_SETUP}; m_event_handler(&evt); } @@ -1167,33 +1174,33 @@ static void ev_usbevent_handler(void) uint32_t event = nrf_usbd_eventcause_get_and_clear(NRF_USBD); if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK) { - NRFX_LOG_DEBUG("USBD event: ISOOUTCRC"); + LOG_DBG("USBD event: ISOOUTCRC"); /* Currently no support */ } if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK) { - NRFX_LOG_DEBUG("USBD event: SUSPEND"); + LOG_DBG("USBD event: SUSPEND"); m_bus_suspend = true; - const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_SUSPEND}; + const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_SUSPEND}; m_event_handler(&evt); } if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK) { - NRFX_LOG_DEBUG("USBD event: RESUME"); + LOG_DBG("USBD event: RESUME"); m_bus_suspend = false; - const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_RESUME}; + const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_RESUME}; m_event_handler(&evt); } if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK) { - NRFX_LOG_DEBUG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active"); + LOG_DBG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active"); if (m_bus_suspend) { - NRFX_ASSERT(!nrf_usbd_lowpower_check(NRF_USBD)); + __ASSERT_NO_MSG(!nrf_usbd_lowpower_check(NRF_USBD)); m_bus_suspend = false; nrf_usbd_dpdmvalue_set(NRF_USBD, NRF_USBD_DPDMVALUE_RESUME); nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_DRIVEDPDM); - const nrfx_usbd_evt_t evt = {.type = NRFX_USBD_EVT_WUREQ}; + const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_WUREQ}; m_event_handler(&evt); } @@ -1205,18 +1212,18 @@ static void ev_epdata_handler(void) /* Get all endpoints that have acknowledged transfer */ uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear(NRF_USBD); - NRFX_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus); + LOG_DBG("USBD event: EndpointEPStatus: %x", dataepstatus); /* All finished endpoint have to be marked as busy */ while (dataepstatus) { uint8_t bitpos = NRF_CTZ(dataepstatus); - nrfx_usbd_ep_t ep = bit2ep(bitpos); + nrf_usbd_common_ep_t ep = bit2ep(bitpos); dataepstatus &= ~(1UL << bitpos); (void)(usbd_ep_data_handler(ep, bitpos)); } - if (NRFX_USBD_EARLY_DMA_PROCESS) { + if (NRF_USBD_COMMON_EARLY_DMA_PROCESS) { /* Speed up */ usbd_dmareq_process(); } @@ -1252,15 +1259,15 @@ static uint8_t usbd_dma_scheduler_algorithm(uint32_t req) * * @return The size of endpoint buffer. */ -static inline size_t usbd_ep_iso_capacity(nrfx_usbd_ep_t ep) +static inline size_t usbd_ep_iso_capacity(nrf_usbd_common_ep_t ep) { (void)ep; nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get(NRF_USBD); if (split == NRF_USBD_ISOSPLIT_HALF) { - return NRFX_USBD_ISOSIZE / 2; + return NRF_USBD_COMMON_ISOSIZE / 2; } - return NRFX_USBD_ISOSIZE; + return NRF_USBD_COMMON_ISOSIZE; } /** @@ -1284,15 +1291,16 @@ static void usbd_dmareq_process(void) } else { pos = usbd_dma_scheduler_algorithm(req); } - nrfx_usbd_ep_t ep = bit2ep(pos); + nrf_usbd_common_ep_t ep = bit2ep(pos); usbd_ep_state_t *p_state = ep_state_access(ep); - nrfx_usbd_ep_transfer_t transfer; + nrf_usbd_common_ep_transfer_t transfer; bool continue_transfer; - NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) == - offsetof(usbd_ep_state_t, handler.consumer)); - NRFX_ASSERT((p_state->handler.feeder) != NULL); + BUILD_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) == + offsetof(usbd_ep_state_t, handler.consumer), + "feeder and consumer must be in union"); + __ASSERT_NO_MSG((p_state->handler.feeder) != NULL); if (NRF_USBD_EPIN_CHECK(ep)) { /* Device -> Host */ @@ -1304,7 +1312,7 @@ static void usbd_dmareq_process(void) } } else { /* Host -> Device */ - const size_t rx_size = nrfx_usbd_epout_size_get(ep); + const size_t rx_size = nrf_usbd_common_epout_size_get(ep); continue_transfer = p_state->handler.consumer( &transfer, p_state->p_context, p_state->max_packet_size, @@ -1312,14 +1320,14 @@ static void usbd_dmareq_process(void) if (transfer.p_data.rx == NULL) { /* Dropping transfer - allow processing */ - NRFX_ASSERT(transfer.size == 0); + __ASSERT_NO_MSG(transfer.size == 0); } else if (transfer.size < rx_size) { - NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, + LOG_DBG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size); - p_state->status = NRFX_USBD_EP_OVERLOAD; - (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, - ~(1U << pos))); - NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OVERLOAD); + p_state->status = NRF_USBD_COMMON_EP_OVERLOAD; + (void)(atomic_and(&m_ep_dma_waiting, ~(1U << pos))); + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, + NRF_USBD_COMMON_EP_OVERLOAD); m_event_handler(&evt); /* This endpoint will not be transmitted now, repeat the * loop @@ -1329,7 +1337,7 @@ static void usbd_dmareq_process(void) /* Nothing to do - only check integrity if assertions are * enabled */ - NRFX_ASSERT(transfer.size == rx_size); + __ASSERT_NO_MSG(transfer.size == rx_size); } if (!continue_transfer) { @@ -1339,9 +1347,8 @@ static void usbd_dmareq_process(void) usbd_dma_pending_set(); m_ep_ready &= ~(1U << pos); - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG( - "USB DMA process: Starting transfer on EP: %x, size: %u", + if (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("USB DMA process: Starting transfer on EP: %x, size: %u", ep, transfer.size); } /* Update number of currently transferred bytes */ @@ -1355,21 +1362,22 @@ static void usbd_dmareq_process(void) * transfer. This is quick fix to maintain stability of the stack. It cost * some performance but makes stack stable. */ - while (!nrf_usbd_event_check(NRF_USBD, nrfx_usbd_ep_to_endevent(ep))) { + while (!nrf_usbd_event_check(NRF_USBD, + nrf_usbd_common_ep_to_endevent(ep))) { /* Empty */ } /* DMA finished, track if total bytes transferred is even or odd */ m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - if (NRFX_USBD_DMAREQ_PROCESS_DEBUG) { - NRFX_LOG_DEBUG("USB DMA process - finishing"); + if (NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG) { + LOG_DBG("USB DMA process - finishing"); } /* Transfer started - exit the loop */ break; } } else { - if (NRFX_USBD_DMAREQ_PROCESS_DEBUG) { - NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy"); + if (NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG) { + LOG_DBG("USB DMA process - EasyDMA busy"); } } } @@ -1390,7 +1398,8 @@ static inline void usbd_eventcause_wait_and_clear(nrf_usbd_eventcause_mask_t eve */ static inline void usbd_errata_171_begin(void) { - NRFX_CRITICAL_SECTION_ENTER(); + unsigned int irq_lock_key = irq_lock(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; @@ -1398,7 +1407,8 @@ static inline void usbd_errata_171_begin(void) } else { *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } /** @@ -1406,7 +1416,8 @@ static inline void usbd_errata_171_begin(void) */ static inline void usbd_errata_171_end(void) { - NRFX_CRITICAL_SECTION_ENTER(); + unsigned int irq_lock_key = irq_lock(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; @@ -1414,7 +1425,8 @@ static inline void usbd_errata_171_end(void) } else { *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } /** @@ -1422,7 +1434,8 @@ static inline void usbd_errata_171_end(void) */ static inline void usbd_errata_187_211_begin(void) { - NRFX_CRITICAL_SECTION_ENTER(); + unsigned int irq_lock_key = irq_lock(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; @@ -1430,7 +1443,8 @@ static inline void usbd_errata_187_211_begin(void) } else { *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } /** @@ -1438,7 +1452,8 @@ static inline void usbd_errata_187_211_begin(void) */ static inline void usbd_errata_187_211_end(void) { - NRFX_CRITICAL_SECTION_ENTER(); + unsigned int irq_lock_key = irq_lock(); + if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; @@ -1446,7 +1461,8 @@ static inline void usbd_errata_187_211_end(void) } else { *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } /** @@ -1454,11 +1470,11 @@ static inline void usbd_errata_187_211_end(void) */ static void usbd_enable(void) { - if (nrfx_usbd_errata_187()) { + if (nrf_usbd_common_errata_187()) { usbd_errata_187_211_begin(); } - if (nrfx_usbd_errata_171()) { + if (nrf_usbd_common_errata_171()) { usbd_errata_171_begin(); } @@ -1468,11 +1484,11 @@ static void usbd_enable(void) /* Waiting for peripheral to enable, this should take a few us */ usbd_eventcause_wait_and_clear(NRF_USBD_EVENTCAUSE_READY_MASK); - if (nrfx_usbd_errata_171()) { + if (nrf_usbd_common_errata_171()) { usbd_errata_171_end(); } - if (nrfx_usbd_errata_187()) { + if (nrf_usbd_common_errata_187()) { usbd_errata_187_211_end(); } } @@ -1513,7 +1529,7 @@ static const nrfx_irq_handler_t m_isr[] = {[USBD_INTEN_USBRESET_Pos] = ev_usbres * * @{ */ -void nrfx_usbd_irq_handler(void) +void nrf_usbd_common_irq_handler(void) { const uint32_t enabled = nrf_usbd_int_enable_get(NRF_USBD); uint32_t to_process = enabled; @@ -1551,9 +1567,9 @@ void nrfx_usbd_irq_handler(void) /** @} */ /** @} */ -nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler) +nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler) { - NRFX_ASSERT(event_handler); + __ASSERT_NO_MSG(event_handler); if (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED) { return NRFX_ERROR_INVALID_STATE; @@ -1565,24 +1581,24 @@ nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler) uint8_t n; for (n = 0; n < NRF_USBD_EPIN_CNT; ++n) { - nrfx_usbd_ep_t ep = NRFX_USBD_EPIN(n); + nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPIN(n); - nrfx_usbd_ep_max_packet_size_set( - ep, NRF_USBD_EPISO_CHECK(ep) ? (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE); + nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ? + (NRF_USBD_COMMON_ISOSIZE / 2) : NRF_USBD_COMMON_EPSIZE); usbd_ep_state_t *p_state = ep_state_access(ep); - p_state->status = NRFX_USBD_EP_OK; + p_state->status = NRF_USBD_COMMON_EP_OK; p_state->handler.feeder = NULL; p_state->transfer_cnt = 0; } for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n) { - nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT(n); + nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPOUT(n); - nrfx_usbd_ep_max_packet_size_set( - ep, NRF_USBD_EPISO_CHECK(ep) ? (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE); + nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ? + (NRF_USBD_COMMON_ISOSIZE / 2) : NRF_USBD_COMMON_EPSIZE); usbd_ep_state_t *p_state = ep_state_access(ep); - p_state->status = NRFX_USBD_EP_OK; + p_state->status = NRF_USBD_COMMON_EP_OK; p_state->handler.consumer = NULL; p_state->transfer_cnt = 0; } @@ -1590,24 +1606,24 @@ nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler) return NRFX_SUCCESS; } -void nrfx_usbd_uninit(void) +void nrf_usbd_common_uninit(void) { - NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED); + __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_INITIALIZED); m_event_handler = NULL; m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; } -void nrfx_usbd_enable(void) +void nrf_usbd_common_enable(void) { - NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED); + __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_INITIALIZED); /* Prepare for READY event receiving */ nrf_usbd_eventcause_clear(NRF_USBD, NRF_USBD_EVENTCAUSE_READY_MASK); usbd_enable(); - if (nrfx_usbd_errata_223() && m_first_enable) { + if (nrf_usbd_common_errata_223() && m_first_enable) { nrf_usbd_disable(NRF_USBD); usbd_enable(); @@ -1615,16 +1631,16 @@ void nrfx_usbd_enable(void) m_first_enable = false; } -#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 - if (nrfx_usbd_errata_187() || nrfx_usbd_errata_211()) +#if NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrf_usbd_common_errata_187() || nrf_usbd_common_errata_211()) #else - if (nrfx_usbd_errata_187()) + if (nrf_usbd_common_errata_187()) #endif { usbd_errata_187_211_begin(); } - if (nrfx_usbd_errata_166()) { + if (nrf_usbd_common_errata_166()) { *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7E3; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0x40; __ISB(); @@ -1633,36 +1649,36 @@ void nrfx_usbd_enable(void) nrf_usbd_isosplit_set(NRF_USBD, NRF_USBD_ISOSPLIT_HALF); - if (NRFX_USBD_CONFIG_ISO_IN_ZLP) { - nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA); + if (IS_ENABLED(CONFIG_NRF_USBD_ISO_IN_ZLP)) { + nrf_usbd_common_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA); } else { - nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP); + nrf_usbd_common_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP); } - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0); + m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); m_ep_dma_waiting = 0; m_dma_odd = 0; usbd_dma_pending_clear(); - m_last_setup_dir = NRFX_USBD_EPOUT0; + m_last_setup_dir = NRF_USBD_COMMON_EPOUT0; m_drv_state = NRFX_DRV_STATE_POWERED_ON; -#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 - if (nrfx_usbd_errata_187() && !nrfx_usbd_errata_211()) +#if NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrf_usbd_common_errata_187() && !nrf_usbd_common_errata_211()) #else - if (nrfx_usbd_errata_187()) + if (nrf_usbd_common_errata_187()) #endif { usbd_errata_187_211_end(); } } -void nrfx_usbd_disable(void) +void nrf_usbd_common_disable(void) { - NRFX_ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED); + __ASSERT_NO_MSG(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED); /* Stop just in case */ - nrfx_usbd_stop(); + nrf_usbd_common_stop(); /* Disable all parts */ nrf_usbd_int_disable(NRF_USBD, nrf_usbd_int_enable_get(NRF_USBD)); @@ -1671,8 +1687,8 @@ void nrfx_usbd_disable(void) * that total number of bytes transferred by DMA is even. */ nrf_usbd_event_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0); - nrf_usbd_ep_easydma_set(NRF_USBD, NRFX_USBD_EPIN0, (uint32_t)&m_dma_odd, 1); - usbd_dma_start(NRFX_USBD_EPIN0); + nrf_usbd_ep_easydma_set(NRF_USBD, NRF_USBD_COMMON_EPIN0, (uint32_t)&m_dma_odd, 1); + usbd_dma_start(NRF_USBD_COMMON_EPIN0); while (!nrf_usbd_event_check(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0)) { } m_dma_odd = 0; @@ -1681,16 +1697,16 @@ void nrfx_usbd_disable(void) usbd_dma_pending_clear(); m_drv_state = NRFX_DRV_STATE_INITIALIZED; -#if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 - if (nrfx_usbd_errata_211()) { +#if NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 + if (nrf_usbd_common_errata_211()) { usbd_errata_187_211_end(); } #endif } -void nrfx_usbd_start(bool enable_sof) +void nrf_usbd_common_start(bool enable_sof) { - NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); + __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_POWERED_ON); m_bus_suspend = false; uint32_t ints_to_enable = NRF_USBD_INT_USBRESET_MASK | NRF_USBD_INT_STARTED_MASK | @@ -1706,21 +1722,20 @@ void nrfx_usbd_start(bool enable_sof) nrf_usbd_int_enable(NRF_USBD, ints_to_enable); /* Enable interrupt globally */ - NRFX_IRQ_PRIORITY_SET(USBD_IRQn, NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY); - NRFX_IRQ_ENABLE(USBD_IRQn); + irq_enable(USBD_IRQn); /* Enable pullups */ nrf_usbd_pullup_enable(NRF_USBD); } -void nrfx_usbd_stop(void) +void nrf_usbd_common_stop(void) { - NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); + __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_POWERED_ON); /* Clear interrupt */ - NRFX_IRQ_PENDING_CLEAR(USBD_IRQn); + NVIC_ClearPendingIRQ(USBD_IRQn); - if (NRFX_IRQ_IS_ENABLED(USBD_IRQn)) { + if (irq_is_enabled(USBD_IRQn)) { /* Abort transfers */ usbd_ep_abort_all(); @@ -1728,33 +1743,33 @@ void nrfx_usbd_stop(void) nrf_usbd_pullup_disable(NRF_USBD); /* Disable interrupt globally */ - NRFX_IRQ_DISABLE(USBD_IRQn); + irq_disable(USBD_IRQn); /* Disable all interrupts */ nrf_usbd_int_disable(NRF_USBD, ~0U); } } -bool nrfx_usbd_is_initialized(void) +bool nrf_usbd_common_is_initialized(void) { return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED); } -bool nrfx_usbd_is_enabled(void) +bool nrf_usbd_common_is_enabled(void) { return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON); } -bool nrfx_usbd_is_started(void) +bool nrf_usbd_common_is_started(void) { - return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn)); + return (nrf_usbd_common_is_enabled() && irq_is_enabled(USBD_IRQn)); } -bool nrfx_usbd_suspend(void) +bool nrf_usbd_common_suspend(void) { bool suspended = false; + unsigned int irq_lock_key = irq_lock(); - NRFX_CRITICAL_SECTION_ENTER(); if (m_bus_suspend) { if (!(nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK)) { nrf_usbd_lowpower_enable(NRF_USBD); @@ -1765,21 +1780,22 @@ bool nrfx_usbd_suspend(void) } } } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); return suspended; } -bool nrfx_usbd_wakeup_req(void) +bool nrf_usbd_common_wakeup_req(void) { bool started = false; + unsigned int irq_lock_key = irq_lock(); - NRFX_CRITICAL_SECTION_ENTER(); if (m_bus_suspend && nrf_usbd_lowpower_check(NRF_USBD)) { nrf_usbd_lowpower_disable(NRF_USBD); started = true; - if (nrfx_usbd_errata_171()) { + if (nrf_usbd_common_errata_171()) { if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) { *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; @@ -1789,66 +1805,67 @@ bool nrfx_usbd_wakeup_req(void) } } } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); return started; } -bool nrfx_usbd_suspend_check(void) +bool nrf_usbd_common_suspend_check(void) { return nrf_usbd_lowpower_check(NRF_USBD); } -void nrfx_usbd_suspend_irq_config(void) +void nrf_usbd_common_suspend_irq_config(void) { nrf_usbd_int_disable(NRF_USBD, m_irq_disabled_in_suspend); } -void nrfx_usbd_active_irq_config(void) +void nrf_usbd_common_active_irq_config(void) { nrf_usbd_int_enable(NRF_USBD, m_irq_disabled_in_suspend); } -bool nrfx_usbd_bus_suspend_check(void) +bool nrf_usbd_common_bus_suspend_check(void) { return m_bus_suspend; } -void nrfx_usbd_force_bus_wakeup(void) +void nrf_usbd_common_force_bus_wakeup(void) { m_bus_suspend = false; } -void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size) +void nrf_usbd_common_ep_max_packet_size_set(nrf_usbd_common_ep_t ep, uint16_t size) { /* Only the power of 2 size allowed for Control Endpoints */ - NRFX_ASSERT((((size & (size - 1)) == 0) || (NRF_USBD_EP_NR_GET(ep) != 0))); + __ASSERT_NO_MSG((((size & (size - 1)) == 0) || (NRF_USBD_EP_NR_GET(ep) != 0))); /* Only non zero size allowed for Control Endpoints */ - NRFX_ASSERT((size != 0) || (NRF_USBD_EP_NR_GET(ep) != 0)); + __ASSERT_NO_MSG((size != 0) || (NRF_USBD_EP_NR_GET(ep) != 0)); /* Packet size cannot be higher than maximum buffer size */ - NRFX_ASSERT((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) || - (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRFX_USBD_EPSIZE))); + __ASSERT_NO_MSG((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) || + (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRF_USBD_COMMON_EPSIZE))); usbd_ep_state_t *p_state = ep_state_access(ep); p_state->max_packet_size = size; } -uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep) +uint16_t nrf_usbd_common_ep_max_packet_size_get(nrf_usbd_common_ep_t ep) { usbd_ep_state_t const *p_state = ep_state_access(ep); return p_state->max_packet_size; } -bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep) +bool nrf_usbd_common_ep_enable_check(nrf_usbd_common_ep_t ep) { return nrf_usbd_ep_enable_check(NRF_USBD, ep_to_hal(ep)); } -void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep) { - nrf_usbd_int_enable(NRF_USBD, nrfx_usbd_ep_to_int(ep)); + nrf_usbd_int_enable(NRF_USBD, nrf_usbd_common_ep_to_int(ep)); if (nrf_usbd_ep_enable_check(NRF_USBD, ep)) { return; @@ -1856,21 +1873,23 @@ void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep) nrf_usbd_ep_enable(NRF_USBD, ep_to_hal(ep)); if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && !NRF_USBD_EPISO_CHECK(ep)) { - NRFX_CRITICAL_SECTION_ENTER(); - nrfx_usbd_transfer_out_drop(ep); + unsigned int irq_lock_key = irq_lock(); + + nrf_usbd_common_transfer_out_drop(ep); m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } } -void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) { usbd_ep_abort(ep); nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep)); - nrf_usbd_int_disable(NRF_USBD, nrfx_usbd_ep_to_int(ep)); + nrf_usbd_int_disable(NRF_USBD, nrf_usbd_common_ep_to_int(ep)); } -void nrfx_usbd_ep_default_config(void) +void nrf_usbd_common_ep_default_config(void) { nrf_usbd_int_disable(NRF_USBD, NRF_USBD_INT_ENDEPIN1_MASK | NRF_USBD_INT_ENDEPIN2_MASK | @@ -1885,119 +1904,126 @@ void nrfx_usbd_ep_default_config(void) nrf_usbd_ep_default_config(NRF_USBD); } -nrfx_err_t nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep, nrfx_usbd_transfer_t const *p_transfer) +nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, + nrf_usbd_common_transfer_t const *p_transfer) { nrfx_err_t ret; const uint8_t ep_bitpos = ep2bit(ep); + unsigned int irq_lock_key = irq_lock(); - NRFX_ASSERT(p_transfer != NULL); + __ASSERT_NO_MSG(p_transfer != NULL); - NRFX_CRITICAL_SECTION_ENTER(); /* Setup data transaction can go only in one direction at a time */ if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { ret = NRFX_ERROR_INVALID_ADDR; - if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && - (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { - NRFX_LOG_DEBUG("Transfer failed: Invalid EPr\n"); + if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && + (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + LOG_DBG("Transfer failed: Invalid EPr\n"); } - } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & (1U << ep_bitpos)) { /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */ ret = NRFX_ERROR_BUSY; - if (NRFX_USBD_FAILED_TRANSFERS_DEBUG) { - NRFX_LOG_DEBUG("Transfer failed: EP is busy"); + if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG) { + LOG_DBG("Transfer failed: EP is busy"); } } else { usbd_ep_state_t *p_state = ep_state_access(ep); /* Prepare transfer context and handler description */ - nrfx_usbd_transfer_t *p_context; + nrf_usbd_common_transfer_t *p_context; if (NRF_USBD_EPIN_CHECK(ep)) { p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep); if (nrfx_is_in_ram(p_transfer->p_data.tx)) { /* RAM */ - if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG)) { - p_state->handler.feeder = nrfx_usbd_feeder_ram; - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG("Transfer called on endpoint %x, " - "size: %u, mode: " - "RAM", - ep, p_transfer->size); + if (0 == (p_transfer->flags & NRF_USBD_COMMON_TRANSFER_ZLP_FLAG)) { + p_state->handler.feeder = nrf_usbd_common_feeder_ram; + if (NRF_USBD_COMMON_ISO_DEBUG || + (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("Transfer called on endpoint %x, " + "size: %u, mode: " + "RAM", + ep, p_transfer->size); } } else { - p_state->handler.feeder = nrfx_usbd_feeder_ram_zlp; - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG("Transfer called on endpoint %x, " - "size: %u, mode: " - "RAM_ZLP", - ep, p_transfer->size); + p_state->handler.feeder = nrf_usbd_common_feeder_ram_zlp; + if (NRF_USBD_COMMON_ISO_DEBUG || + (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("Transfer called on endpoint %x, " + "size: %u, mode: " + "RAM_ZLP", + ep, p_transfer->size); } } } else { /* Flash */ - if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG)) { - p_state->handler.feeder = nrfx_usbd_feeder_flash; - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG("Transfer called on endpoint %x, " - "size: %u, mode: " - "FLASH", - ep, p_transfer->size); + if (0 == (p_transfer->flags & NRF_USBD_COMMON_TRANSFER_ZLP_FLAG)) { + p_state->handler.feeder = nrf_usbd_common_feeder_flash; + if (NRF_USBD_COMMON_ISO_DEBUG || + (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("Transfer called on endpoint %x, " + "size: %u, mode: " + "FLASH", + ep, p_transfer->size); } } else { - p_state->handler.feeder = nrfx_usbd_feeder_flash_zlp; - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG("Transfer called on endpoint %x, " - "size: %u, mode: " - "FLASH_ZLP", - ep, p_transfer->size); + p_state->handler.feeder = nrf_usbd_common_feeder_flash_zlp; + if (NRF_USBD_COMMON_ISO_DEBUG || + (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("Transfer called on endpoint %x, " + "size: %u, mode: " + "FLASH_ZLP", + ep, p_transfer->size); } } } } else { p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep); - NRFX_ASSERT((p_transfer->p_data.rx == NULL) || + __ASSERT_NO_MSG((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx))); - p_state->handler.consumer = nrfx_usbd_consumer; + p_state->handler.consumer = nrf_usbd_common_consumer; } *p_context = *p_transfer; p_state->p_context = p_context; p_state->transfer_cnt = 0; - p_state->status = NRFX_USBD_EP_OK; + p_state->status = NRF_USBD_COMMON_EP_OK; m_ep_dma_waiting |= 1U << ep_bitpos; ret = NRFX_SUCCESS; usbd_int_rise(); } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); + return ret; } -nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, - nrfx_usbd_handler_desc_t const *p_handler) +nrfx_err_t nrf_usbd_common_ep_handled_transfer(nrf_usbd_common_ep_t ep, + nrf_usbd_common_handler_desc_t const *p_handler) { nrfx_err_t ret; const uint8_t ep_bitpos = ep2bit(ep); + unsigned int irq_lock_key = irq_lock(); - NRFX_ASSERT(p_handler != NULL); + __ASSERT_NO_MSG(p_handler != NULL); - NRFX_CRITICAL_SECTION_ENTER(); /* Setup data transaction can go only in one direction at a time */ if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { ret = NRFX_ERROR_INVALID_ADDR; - if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && - (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { - NRFX_LOG_DEBUG("Transfer failed: Invalid EP"); + if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && + (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + LOG_DBG("Transfer failed: Invalid EP"); } - } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & (1U << ep_bitpos)) { /* IN (Device -> Host) transfer has to be transmitted out to allow a new * transmission */ ret = NRFX_ERROR_BUSY; - if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && - (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { - NRFX_LOG_DEBUG("Transfer failed: EP is busy"); + if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && + (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + LOG_DBG("Transfer failed: EP is busy"); } } else { /* Transfer can be configured now */ @@ -2006,74 +2032,78 @@ nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, p_state->transfer_cnt = 0; p_state->handler = p_handler->handler; p_state->p_context = p_handler->p_context; - p_state->status = NRFX_USBD_EP_OK; + p_state->status = NRF_USBD_COMMON_EP_OK; m_ep_dma_waiting |= 1U << ep_bitpos; ret = NRFX_SUCCESS; - if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - NRFX_LOG_DEBUG("Transfer called on endpoint %x, mode: Handler", ep); + if (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + LOG_DBG("Transfer called on endpoint %x, mode: Handler", ep); } usbd_int_rise(); } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); + return ret; } -void *nrfx_usbd_feeder_buffer_get(void) +void *nrf_usbd_common_feeder_buffer_get(void) { return m_tx_buffer; } -nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t *p_size) +nrf_usbd_common_ep_status_t nrf_usbd_common_ep_status_get(nrf_usbd_common_ep_t ep, size_t *p_size) { - nrfx_usbd_ep_status_t ret; + nrf_usbd_common_ep_status_t ret; usbd_ep_state_t const *p_state = ep_state_access(ep); + unsigned int irq_lock_key = irq_lock(); - NRFX_CRITICAL_SECTION_ENTER(); *p_size = p_state->transfer_cnt; - ret = (p_state->handler.consumer == NULL) ? p_state->status : NRFX_USBD_EP_BUSY; - NRFX_CRITICAL_SECTION_EXIT(); + ret = (p_state->handler.consumer == NULL) ? p_state->status : NRF_USBD_COMMON_EP_BUSY; + + irq_unlock(irq_lock_key); + return ret; } -size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep) +size_t nrf_usbd_common_epout_size_get(nrf_usbd_common_ep_t ep) { return nrf_usbd_epout_size_get(NRF_USBD, ep_to_hal(ep)); } -bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep) +bool nrf_usbd_common_ep_is_busy(nrf_usbd_common_ep_t ep) { - return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & + return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & (1U << ep2bit(ep)))); } -void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_stall(nrf_usbd_common_ep_t ep) { - NRFX_LOG_DEBUG("USB: EP %x stalled.", ep); + LOG_DBG("USB: EP %x stalled.", ep); nrf_usbd_ep_stall(NRF_USBD, ep_to_hal(ep)); } -void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_stall_clear(nrf_usbd_common_ep_t ep) { - if (NRF_USBD_EPOUT_CHECK(ep) && nrfx_usbd_ep_stall_check(ep)) { - nrfx_usbd_transfer_out_drop(ep); + if (NRF_USBD_EPOUT_CHECK(ep) && nrf_usbd_common_ep_stall_check(ep)) { + nrf_usbd_common_transfer_out_drop(ep); } nrf_usbd_ep_unstall(NRF_USBD, ep_to_hal(ep)); } -bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep) +bool nrf_usbd_common_ep_stall_check(nrf_usbd_common_ep_t ep) { return nrf_usbd_ep_is_stall(NRF_USBD, ep_to_hal(ep)); } -void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep) +void nrf_usbd_common_ep_dtoggle_clear(nrf_usbd_common_ep_t ep) { nrf_usbd_dtoggle_set(NRF_USBD, ep, NRF_USBD_DTOGGLE_DATA0); } -void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup) +void nrf_usbd_common_setup_get(nrf_usbd_common_setup_t *p_setup) { - memset(p_setup, 0, sizeof(nrfx_usbd_setup_t)); + memset(p_setup, 0, sizeof(nrf_usbd_common_setup_t)); p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); p_setup->bRequest = nrf_usbd_setup_brequest_get(NRF_USBD); p_setup->wValue = nrf_usbd_setup_wvalue_get(NRF_USBD); @@ -2081,38 +2111,40 @@ void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup) p_setup->wLength = nrf_usbd_setup_wlength_get(NRF_USBD); } -void nrfx_usbd_setup_data_clear(void) +void nrf_usbd_common_setup_data_clear(void) { nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0RCVOUT); } -void nrfx_usbd_setup_clear(void) +void nrf_usbd_common_setup_clear(void) { - NRFX_LOG_DEBUG(">> ep0status >>"); + LOG_DBG(">> ep0status >>"); nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STATUS); } -void nrfx_usbd_setup_stall(void) +void nrf_usbd_common_setup_stall(void) { - NRFX_LOG_DEBUG("Setup stalled."); + LOG_DBG("Setup stalled."); nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STALL); } -nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void) +nrf_usbd_common_ep_t nrf_usbd_common_last_setup_dir_get(void) { return m_last_setup_dir; } -void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep) +void nrf_usbd_common_transfer_out_drop(nrf_usbd_common_ep_t ep) { - NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + unsigned int irq_lock_key = irq_lock(); + + __ASSERT_NO_MSG(NRF_USBD_EPOUT_CHECK(ep)); - NRFX_CRITICAL_SECTION_ENTER(); m_ep_ready &= ~(1U << ep2bit(ep)); if (!NRF_USBD_EPISO_CHECK(ep)) { nrf_usbd_epout_clear(NRF_USBD, ep); } - NRFX_CRITICAL_SECTION_EXIT(); + + irq_unlock(irq_lock_key); } -#endif /* NRFX_CHECK(NRFX_USBD_ENABLED) */ +/** @endcond */ diff --git a/modules/hal_nordic/nrfx/nrfx_usbd.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h similarity index 68% rename from modules/hal_nordic/nrfx/nrfx_usbd.h rename to drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h index cf6251cb4bd..047c5a29709 100644 --- a/modules/hal_nordic/nrfx/nrfx_usbd.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h @@ -4,8 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef NRFX_USBD_H__ -#define NRFX_USBD_H__ +/* This file is undergoing transition towards native Zephyr nrf USB driver. */ + +/** @cond INTERNAL_HIDDEN */ + +#ifndef NRF_USBD_COMMON_H__ +#define NRF_USBD_COMMON_H__ #include #include @@ -15,7 +19,7 @@ extern "C" { #endif /** - * @defgroup nrfx_usbd USBD driver + * @defgroup nrf_usbd_common USBD driver * @{ * @ingroup nrf_usbd * @brief Universal Serial Bus Device (USBD) peripheral driver. @@ -24,7 +28,7 @@ extern "C" { /** * @brief Number of bytes in the endpoint. */ -#define NRFX_USBD_EPSIZE 64 +#define NRF_USBD_COMMON_EPSIZE 64 /** * @brief Number of bytes for isochronous endpoints. @@ -35,14 +39,14 @@ extern "C" { * @sa nrf_usbd_isosplit_set * @sa nrf_usbd_isosplit_get */ -#define NRFX_USBD_ISOSIZE 1023 +#define NRF_USBD_COMMON_ISOSIZE 1023 /** * @brief The size of internal feeder buffer. * - * @sa nrfx_usbd_feeder_buffer_get + * @sa nrf_usbd_common_feeder_buffer_get */ -#define NRFX_USBD_FEEDER_BUFFER_SIZE NRFX_USBD_EPSIZE +#define NRF_USBD_COMMON_FEEDER_BUFFER_SIZE NRF_USBD_COMMON_EPSIZE /** * @name Macros for creating endpoint identifiers. @@ -60,7 +64,7 @@ extern "C" { * * @return Endpoint identifier that connects endpoint number and endpoint direction. */ -#define NRFX_USBD_EPIN(n) ((nrfx_usbd_ep_t)NRF_USBD_EPIN(n)) +#define NRF_USBD_COMMON_EPIN(n) ((nrf_usbd_common_ep_t)NRF_USBD_EPIN(n)) /** * @brief Create identifier for OUT endpoint. * @@ -70,7 +74,7 @@ extern "C" { * * @return Endpoint identifier that connects endpoint number and endpoint direction. */ -#define NRFX_USBD_EPOUT(n) ((nrfx_usbd_ep_t)NRF_USBD_EPOUT(n)) +#define NRF_USBD_COMMON_EPOUT(n) ((nrf_usbd_common_ep_t)NRF_USBD_EPOUT(n)) /** @} */ /** @@ -80,26 +84,26 @@ extern "C" { * This endpoint number is consistent with USB 2.0 specification. */ typedef enum { - NRFX_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ - NRFX_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ - NRFX_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ - NRFX_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ - NRFX_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ - NRFX_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ - NRFX_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ - NRFX_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ - NRFX_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ - - NRFX_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ - NRFX_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ - NRFX_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ - NRFX_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ - NRFX_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ - NRFX_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ - NRFX_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ - NRFX_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ - NRFX_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ -} nrfx_usbd_ep_t; + NRF_USBD_COMMON_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ + NRF_USBD_COMMON_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ + NRF_USBD_COMMON_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ + NRF_USBD_COMMON_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ + NRF_USBD_COMMON_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ + NRF_USBD_COMMON_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ + NRF_USBD_COMMON_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ + NRF_USBD_COMMON_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ + NRF_USBD_COMMON_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ + + NRF_USBD_COMMON_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ + NRF_USBD_COMMON_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ + NRF_USBD_COMMON_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ + NRF_USBD_COMMON_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ + NRF_USBD_COMMON_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ + NRF_USBD_COMMON_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ + NRF_USBD_COMMON_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ + NRF_USBD_COMMON_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ + NRF_USBD_COMMON_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ +} nrf_usbd_common_ep_t; /** * @brief Events generated by the driver. @@ -107,15 +111,15 @@ typedef enum { * Enumeration of possible events that may be generated by the driver. */ typedef enum { - NRFX_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected. */ - NRFX_USBD_EVT_RESET, /**< Reset condition on USB bus detected. */ - NRFX_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now. */ - NRFX_USBD_EVT_RESUME, /**< This device should resume from suspend now. */ + NRF_USBD_COMMON_EVT_SOF, /**< Start Of Frame event on USB bus detected. */ + NRF_USBD_COMMON_EVT_RESET, /**< Reset condition on USB bus detected. */ + NRF_USBD_COMMON_EVT_SUSPEND, /**< This device should go to suspend mode now. */ + NRF_USBD_COMMON_EVT_RESUME, /**< This device should resume from suspend now. */ /** Wakeup request - the USBD peripheral is ready to generate * WAKEUP signal after exiting low power mode. */ - NRFX_USBD_EVT_WUREQ, - NRFX_USBD_EVT_SETUP, /**< Setup frame received and decoded. */ + NRF_USBD_COMMON_EVT_WUREQ, + NRF_USBD_COMMON_EVT_SETUP, /**< Setup frame received and decoded. */ /** For Rx (OUT: Host->Device): * 1. The packet has been received but there is no buffer * prepared for transfer already. @@ -125,21 +129,21 @@ typedef enum { * The last packet from requested transfer has been transferred * over USB bus and acknowledged. */ - NRFX_USBD_EVT_EPTRANSFER, - NRFX_USBD_EVT_CNT /**< Number of defined events. */ -} nrfx_usbd_event_type_t; + NRF_USBD_COMMON_EVT_EPTRANSFER, + NRF_USBD_COMMON_EVT_CNT /**< Number of defined events. */ +} nrf_usbd_common_event_type_t; /** * @brief Endpoint status codes. * - * Status codes that may be returned by @ref nrfx_usbd_ep_status_get or, except for - * @ref NRFX_USBD_EP_BUSY, reported together with @ref NRFX_USBD_EVT_EPTRANSFER. + * Status codes that may be returned by @ref nrf_usbd_common_ep_status_get or, except for + * @ref NRF_USBD_COMMON_EP_BUSY, reported together with @ref NRF_USBD_COMMON_EVT_EPTRANSFER. */ typedef enum { /** No error occurred. */ - NRFX_USBD_EP_OK, + NRF_USBD_COMMON_EP_OK, /** Data received, no buffer prepared already - waiting for configured transfer. */ - NRFX_USBD_EP_WAITING, + NRF_USBD_COMMON_EP_WAITING, /** Received number of bytes cannot fit given buffer. * This error would also be returned when next_transfer function * has been defined but currently received data cannot fit completely @@ -149,14 +153,14 @@ typedef enum { * When this error is reported - data is left inside endpoint * buffer. Clear endpoint or prepare new buffer and read it. */ - NRFX_USBD_EP_OVERLOAD, + NRF_USBD_COMMON_EP_OVERLOAD, /** EP0 transfer can be aborted when new setup comes. * Any other transfer can be aborted by USB reset or driver stopping. */ - NRFX_USBD_EP_ABORTED, + NRF_USBD_COMMON_EP_ABORTED, /** Transfer is in progress. */ - NRFX_USBD_EP_BUSY, -} nrfx_usbd_ep_status_t; + NRF_USBD_COMMON_EP_BUSY, +} nrf_usbd_common_ep_status_t; /** * @brief Event structure. @@ -164,27 +168,27 @@ typedef enum { * Structure passed to event handler. */ typedef struct { - nrfx_usbd_event_type_t type; /**< Event type. */ + nrf_usbd_common_event_type_t type; /**< Event type. */ union { struct { uint16_t framecnt; /**< Current value of frame counter. */ - } sof; /**< Data available for @ref NRFX_USBD_EVT_SOF. */ + } sof; /**< Data available for @ref NRF_USBD_COMMON_EVT_SOF. */ struct { - nrfx_usbd_ep_t ep; /**< Endpoint number. */ + nrf_usbd_common_ep_t ep; /**< Endpoint number. */ } isocrc; /**< Isochronouns channel endpoint number. */ struct { - nrfx_usbd_ep_t ep; /**< Endpoint number. */ - nrfx_usbd_ep_status_t status; /**< Status for the endpoint. */ + nrf_usbd_common_ep_t ep; /**< Endpoint number. */ + nrf_usbd_common_ep_status_t status; /**< Status for the endpoint. */ } eptransfer; /**< Endpoint transfer status. */ } data; /**< Union to store event data. */ -} nrfx_usbd_evt_t; +} nrf_usbd_common_evt_t; /** * @brief USBD event callback function type. * * @param[in] p_event Event information structure. */ -typedef void (*nrfx_usbd_event_handler_t)(nrfx_usbd_evt_t const *p_event); +typedef void (*nrf_usbd_common_event_handler_t)(nrf_usbd_common_evt_t const *p_event); /** * @brief Universal data pointer. @@ -195,7 +199,7 @@ typedef union { void const *tx; /*!< Constant TX buffer pointer. */ void *rx; /*!< Writable RX buffer pointer. */ uint32_t addr; /*!< Numeric value used internally by the driver. */ -} nrfx_usbd_data_ptr_t; +} nrf_usbd_common_data_ptr_t; /** * @brief Structure to be filled with information about the next transfer. @@ -205,9 +209,11 @@ typedef union { * can never be higher than the endpoint size. */ typedef struct { - nrfx_usbd_data_ptr_t p_data; /*!< Union with available data pointers used by the driver. */ - size_t size; /*!< Size of the requested transfer. */ -} nrfx_usbd_ep_transfer_t; + /** Union with available data pointers used by the driver. */ + nrf_usbd_common_data_ptr_t p_data; + /** Size of the requested transfer. */ + size_t size; +} nrf_usbd_common_ep_transfer_t; /** * @brief Flags for the current transfer. @@ -215,8 +221,8 @@ typedef struct { * Flags configured for the transfer that can be merged using the bitwise 'or' operator (|). */ typedef enum { - NRFX_USBD_TRANSFER_ZLP_FLAG = 1U << 0, /*!< Add a zero-length packet. */ -} nrfx_usbd_transfer_flags_t; + NRF_USBD_COMMON_TRANSFER_ZLP_FLAG = 1U << 0, /*!< Add a zero-length packet. */ +} nrf_usbd_common_transfer_flags_t; /** * @brief Total transfer configuration. @@ -225,11 +231,13 @@ typedef enum { * It is used by internal built-in feeders and consumers. */ typedef struct { - nrfx_usbd_data_ptr_t p_data; /*!< Union with available data pointers used by the driver. */ - size_t size; /*!< Total size of the requested transfer. */ - uint32_t flags; /*!< Transfer flags. */ - /**< Use the @ref nrfx_usbd_transfer_flags_t values. */ -} nrfx_usbd_transfer_t; + /** Union with available data pointers used by the driver. */ + nrf_usbd_common_data_ptr_t p_data; + /** Total size of the requested transfer. */ + size_t size; + /*!< Transfer flags. Use the @ref nrf_usbd_common_transfer_flags_t values. */ + uint32_t flags; +} nrf_usbd_common_transfer_t; /** * @brief Auxiliary macro for declaring IN transfer description with optional flags. @@ -239,23 +247,23 @@ typedef struct { * @param name Instance name. * @param tx_buff Buffer to transfer. * @param tx_size Transfer size. - * @param tx_flags Flags for the transfer (see @ref nrfx_usbd_transfer_flags_t). + * @param tx_flags Flags for the transfer (see @ref nrf_usbd_common_transfer_flags_t). * * @return Configured variable with total transfer description. */ -#define NRFX_USBD_TRANSFER_IN(name, tx_buff, tx_size, tx_flags) \ - const nrfx_usbd_transfer_t name = { \ +#define NRF_USBD_COMMON_TRANSFER_IN(name, tx_buff, tx_size, tx_flags) \ + const nrf_usbd_common_transfer_t name = { \ .p_data = {.tx = (tx_buff)}, .size = (tx_size), .flags = (tx_flags)} /** - * @brief Helper macro for declaring OUT transfer item (@ref nrfx_usbd_transfer_t). + * @brief Helper macro for declaring OUT transfer item (@ref nrf_usbd_common_transfer_t). * * @param name Instance name. * @param rx_buff Buffer to transfer. * @param rx_size Transfer size. */ -#define NRFX_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \ - const nrfx_usbd_transfer_t name = { \ +#define NRF_USBD_COMMON_TRANSFER_OUT(name, rx_buff, rx_size) \ + const nrf_usbd_common_transfer_t name = { \ .p_data = {.rx = (rx_buff)}, .size = (rx_size), .flags = 0} /** @@ -271,7 +279,7 @@ typedef struct { * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before. * * @note - * This function may use @ref nrfx_usbd_feeder_buffer_get to gain a temporary buffer + * This function may use @ref nrf_usbd_common_feeder_buffer_get to gain a temporary buffer * that can be used to prepare transfer. * * @param[out] p_next Structure with the data for the next transfer to be filled. @@ -284,7 +292,7 @@ typedef struct { * @retval true There is more data to be prepared and when the current transfer * finishes, the feeder function is expected to be called again. */ -typedef bool (*nrfx_usbd_feeder_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_context, +typedef bool (*nrf_usbd_common_feeder_t)(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, size_t ep_size); /** @@ -295,7 +303,7 @@ typedef bool (*nrfx_usbd_feeder_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_cont * RX (Host->Device) endpoint transfer. * * The transfer must provide a buffer big enough to fit the whole data from the endpoint. - * Otherwise, the NRFX_USBD_EP_OVERLOAD event is generated. + * Otherwise, the NRF_USBD_COMMON_EP_OVERLOAD event is generated. * * @param[out] p_next Structure with the data for the next transfer to be filled. * Required only if the function returns true. @@ -308,7 +316,7 @@ typedef bool (*nrfx_usbd_feeder_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_cont * @retval true There is more data to be prepared and when current transfer * finishes, the feeder function is expected to be called again. */ -typedef bool (*nrfx_usbd_consumer_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_context, +typedef bool (*nrf_usbd_common_consumer_t)(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, size_t ep_size, size_t data_size); /** @@ -317,9 +325,9 @@ typedef bool (*nrfx_usbd_consumer_t)(nrfx_usbd_ep_transfer_t *p_next, void *p_co * Union with feeder and consumer function pointer. */ typedef union { - nrfx_usbd_feeder_t feeder; /*!< Feeder function pointer. */ - nrfx_usbd_consumer_t consumer; /*!< Consumer function pointer. */ -} nrfx_usbd_handler_t; + nrf_usbd_common_feeder_t feeder; /*!< Feeder function pointer. */ + nrf_usbd_common_consumer_t consumer; /*!< Consumer function pointer. */ +} nrf_usbd_common_handler_t; /** * @brief USBD transfer descriptor. @@ -328,9 +336,11 @@ typedef union { * IN or OUT type of the transfer. */ typedef struct { - nrfx_usbd_handler_t handler; /*!< Handler for the current transfer, function pointer. */ - void *p_context; /*!< Context for the transfer handler. */ -} nrfx_usbd_handler_desc_t; + /** Handler for the current transfer, function pointer. */ + nrf_usbd_common_handler_t handler; + /** Context for the transfer handler. */ + void *p_context; +} nrf_usbd_common_handler_desc_t; /** * @brief Setup packet structure. @@ -343,7 +353,7 @@ typedef struct { uint16_t wValue; /*!< byte 2, 3 */ uint16_t wIndex; /*!< byte 4, 5 */ uint16_t wLength; /*!< byte 6, 7 */ -} nrfx_usbd_setup_t; +} nrf_usbd_common_setup_t; /** * @brief Driver initialization. @@ -353,12 +363,12 @@ typedef struct { * @retval NRFX_SUCCESS Initialization successful. * @retval NRFX_ERROR_INVALID_STATE Driver was already initialized. */ -nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler); +nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler); /** * @brief Driver deinitialization. */ -void nrfx_usbd_uninit(void); +void nrf_usbd_common_uninit(void); /** * @brief Enable the USBD port. @@ -368,15 +378,15 @@ void nrfx_usbd_uninit(void); * Enabled USBD peripheral would request HFCLK. * This function does not enable external oscillator, so if it is not enabled by other part of the * program after enabling USBD driver HFINT would be used for the USBD peripheral. - * It is perfectly fine until USBD is started. See @ref nrfx_usbd_start. + * It is perfectly fine until USBD is started. See @ref nrf_usbd_common_start. * * In normal situation this function should be called in reaction to USBDETECTED * event from POWER peripheral. * - * Interrupts and USB pins pull-up would stay disabled until @ref nrfx_usbd_start + * Interrupts and USB pins pull-up would stay disabled until @ref nrf_usbd_common_start * function is called. */ -void nrfx_usbd_enable(void); +void nrf_usbd_common_enable(void); /** * @brief Disable the USBD port. @@ -385,7 +395,7 @@ void nrfx_usbd_enable(void); * No events would be detected or processed by the driver. * Clock for the peripheral would be disconnected. */ -void nrfx_usbd_disable(void); +void nrf_usbd_common_disable(void); /** * @brief Start USB functionality. @@ -409,7 +419,7 @@ void nrfx_usbd_disable(void); * In other case any isochronous endpoint would stay busy * after first transmission. */ -void nrfx_usbd_start(bool enable_sof); +void nrf_usbd_common_start(bool enable_sof); /** * @brief Stop USB functionality. @@ -420,9 +430,9 @@ void nrfx_usbd_start(bool enable_sof); * * @note * This function can also be used to logically disconnect USB from the HOST that - * would force it to enumerate device after calling @ref nrfx_usbd_start. + * would force it to enumerate device after calling @ref nrf_usbd_common_start. */ -void nrfx_usbd_stop(void); +void nrf_usbd_common_stop(void); /** * @brief Check if driver is initialized. @@ -430,7 +440,7 @@ void nrfx_usbd_stop(void); * @retval false Driver is not initialized. * @retval true Driver is initialized. */ -bool nrfx_usbd_is_initialized(void); +bool nrf_usbd_common_is_initialized(void); /** * @brief Check if driver is enabled. @@ -438,7 +448,7 @@ bool nrfx_usbd_is_initialized(void); * @retval false Driver is disabled. * @retval true Driver is enabled. */ -bool nrfx_usbd_is_enabled(void); +bool nrf_usbd_common_is_enabled(void); /** * @brief Check if driver is started. @@ -447,13 +457,13 @@ bool nrfx_usbd_is_enabled(void); * @retval true Driver is started (fully functional). * @note The USBD peripheral interrupt state is checked. */ -bool nrfx_usbd_is_started(void); +bool nrf_usbd_common_is_started(void); /** * @brief Suspend USBD operation. * * The USBD peripheral is forced to go into the low power mode. - * The function has to be called in the reaction to @ref NRFX_USBD_EVT_SUSPEND event + * The function has to be called in the reaction to @ref NRF_USBD_COMMON_EVT_SUSPEND event * when the firmware is ready. * * After successful call of this function most of the USBD registers would be unavailable. @@ -463,7 +473,7 @@ bool nrfx_usbd_is_started(void); * @retval true USBD peripheral successfully suspended. * @retval false USBD peripheral was not suspended due to resume detection. */ -bool nrfx_usbd_suspend(void); +bool nrf_usbd_common_suspend(void); /** * @brief Start wake up procedure. @@ -474,19 +484,19 @@ bool nrfx_usbd_suspend(void); * The hardware starts measuring time when wake up is possible. * This may take 0-5 ms depending on how long the SUSPEND state was kept on the USB line. - * When NRFX_USBD_EVT_WUREQ event is generated it means that Wake Up signaling has just been + * When NRF_USBD_COMMON_EVT_WUREQ event is generated it means that Wake Up signaling has just been * started on the USB lines. * - * @note Do not expect only @ref NRFX_USBD_EVT_WUREQ event. - * There always may appear @ref NRFX_USBD_EVT_RESUME event. - * @note NRFX_USBD_EVT_WUREQ event means that Remote WakeUp signal + * @note Do not expect only @ref NRF_USBD_COMMON_EVT_WUREQ event. + * There always may appear @ref NRF_USBD_COMMON_EVT_RESUME event. + * @note NRF_USBD_COMMON_EVT_WUREQ event means that Remote WakeUp signal * has just begun to be generated. * This may take up to 20 ms for the bus to become active. * * @retval true WakeUp procedure started. * @retval false No WakeUp procedure started - bus is already active. */ -bool nrfx_usbd_wakeup_req(void); +bool nrf_usbd_common_wakeup_req(void); /** * @brief Check if USBD is in SUSPEND mode. @@ -496,7 +506,7 @@ bool nrfx_usbd_wakeup_req(void); * @retval true USBD peripheral is suspended. * @retval false USBD peripheral is active. */ -bool nrfx_usbd_suspend_check(void); +bool nrf_usbd_common_suspend_check(void); /** * @brief Enable only interrupts that should be processed in SUSPEND mode. @@ -508,19 +518,19 @@ bool nrfx_usbd_suspend_check(void); * Use this function to suspend interrupt processing that may require stable HFCLK until the * clock is enabled. * - * @sa nrfx_usbd_active_irq_config + * @sa nrf_usbd_common_active_irq_config */ -void nrfx_usbd_suspend_irq_config(void); +void nrf_usbd_common_suspend_irq_config(void); /** * @brief Default active interrupt configuration. * * Default interrupt configuration. - * Use in a pair with @ref nrfx_usbd_active_irq_config. + * Use in a pair with @ref nrf_usbd_common_active_irq_config. * - * @sa nrfx_usbd_suspend_irq_config + * @sa nrf_usbd_common_suspend_irq_config */ -void nrfx_usbd_active_irq_config(void); +void nrf_usbd_common_active_irq_config(void); /** * @brief Check the bus state. @@ -532,12 +542,12 @@ void nrfx_usbd_active_irq_config(void); * @retval true USBD bus is suspended. * @retval false USBD bus is active. */ -bool nrfx_usbd_bus_suspend_check(void); +bool nrf_usbd_common_bus_suspend_check(void); /** * @brief Force the bus state to active */ -void nrfx_usbd_force_bus_wakeup(void); +void nrf_usbd_common_force_bus_wakeup(void); /** * @brief Configure packet size that should be supported by the endpoint. @@ -549,10 +559,11 @@ void nrfx_usbd_force_bus_wakeup(void); * @param[in] ep Endpoint number. * @param[in] size Required maximum packet size. * - * @note Endpoint size is always set to @ref NRFX_USBD_EPSIZE or @ref NRFX_USBD_ISOSIZE / 2 - * when @ref nrfx_usbd_ep_enable function is called. + * @note Endpoint size is always set to @ref NRF_USBD_COMMON_EPSIZE + * or @ref NRF_USBD_COMMON_ISOSIZE / 2 + * when @ref nrf_usbd_common_ep_enable function is called. */ -void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size); +void nrf_usbd_common_ep_max_packet_size_set(nrf_usbd_common_ep_t ep, uint16_t size); /** * @brief Get configured endpoint packet size. @@ -563,7 +574,7 @@ void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size); * * @return Maximum pocket size configured on selected endpoint. */ -uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep); +uint16_t nrf_usbd_common_ep_max_packet_size_get(nrf_usbd_common_ep_t ep); /** * @brief Check if the selected endpoint is enabled. @@ -573,7 +584,7 @@ uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep); * @retval true Endpoint is enabled. * @retval false Endpoint is disabled. */ -bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep); +bool nrf_usbd_common_ep_enable_check(nrf_usbd_common_ep_t ep); /** * @brief Enable selected endpoint. @@ -585,9 +596,9 @@ bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep); * @note * Max packet size is set to endpoint default maximum value. * - * @sa nrfx_usbd_ep_max_packet_size_set + * @sa nrf_usbd_common_ep_max_packet_size_set */ -void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep); /** * @brief Disable selected endpoint. @@ -596,14 +607,14 @@ void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep); * * @param[in] ep Endpoint number to disable. */ -void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep); /** * @brief Disable all endpoints except for EP0. * * Disable all endpoints that can be disabled in USB device while it is still active. */ -void nrfx_usbd_ep_default_config(void); +void nrf_usbd_common_ep_default_config(void); /** * @brief Start sending data over endpoint. @@ -613,7 +624,7 @@ void nrfx_usbd_ep_default_config(void); * for transmission is prepared. * * @note Data buffer pointed by p_data have to be kept active till - * @ref NRFX_USBD_EVT_EPTRANSFER event is generated. + * @ref NRF_USBD_COMMON_EVT_EPTRANSFER event is generated. * * @param[in] ep Endpoint number. * For IN endpoint sending would be initiated. @@ -624,7 +635,8 @@ void nrfx_usbd_ep_default_config(void); * @retval NRFX_ERROR_BUSY Selected endpoint is pending. * @retval NRFX_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. */ -nrfx_err_t nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep, nrfx_usbd_transfer_t const *p_transfer); +nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, + nrf_usbd_common_transfer_t const *p_transfer); /** * @brief Start sending data over the endpoint using the transfer handler function. @@ -643,8 +655,8 @@ nrfx_err_t nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep, nrfx_usbd_transfer_t const * * @retval NRFX_ERROR_BUSY Selected endpoint is pending. * @retval NRFX_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. */ -nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, - nrfx_usbd_handler_desc_t const *p_handler); +nrfx_err_t nrf_usbd_common_ep_handled_transfer(nrf_usbd_common_ep_t ep, + nrf_usbd_common_handler_desc_t const *p_handler); /** * @brief Get the temporary buffer to be used by the feeder. @@ -653,19 +665,19 @@ nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep, * when the transfer is finished. * Use it for transfer preparation. * - * May be used inside the feeder configured in @ref nrfx_usbd_ep_handled_transfer. + * May be used inside the feeder configured in @ref nrf_usbd_common_ep_handled_transfer. * * @return Pointer to the buffer that can be used temporarily. * - * @sa NRFX_USBD_FEEDER_BUFFER_SIZE + * @sa NRF_USBD_COMMON_FEEDER_BUFFER_SIZE */ -void *nrfx_usbd_feeder_buffer_get(void); +void *nrf_usbd_common_feeder_buffer_get(void); /** * @brief Get the information about last finished or current transfer. * * Function returns the status of the last buffer set for transfer on selected endpoint. - * The status considers last buffer set by @ref nrfx_usbd_ep_transfer function or + * The status considers last buffer set by @ref nrf_usbd_common_ep_transfer function or * by transfer callback function. * * @param[in] ep Endpoint number. @@ -673,9 +685,9 @@ void *nrfx_usbd_feeder_buffer_get(void); * * @return Endpoint status. * - * @sa nrfx_usbd_ep_status_t + * @sa nrf_usbd_common_ep_status_t */ -nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t *p_size); +nrf_usbd_common_ep_status_t nrf_usbd_common_ep_status_get(nrf_usbd_common_ep_t ep, size_t *p_size); /** * @brief Get number of received bytes. @@ -687,7 +699,7 @@ nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t *p_size) * * @return Number of received bytes. */ -size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep); +size_t nrf_usbd_common_epout_size_get(nrf_usbd_common_ep_t ep); /** * @brief Check if endpoint buffer is ready or is under USB IP control. @@ -701,7 +713,7 @@ size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep); * and the endpoint does not have any data. * When endpoint is not busy: * - OUT (TX) endpoint: New data can be uploaded. - * - IN (RX) endpoint: New data can be downloaded using @ref nrfx_usbd_ep_transfer + * - IN (RX) endpoint: New data can be downloaded using @ref nrf_usbd_common_ep_transfer * function. * * @param[in] ep Endpoint number. @@ -709,7 +721,7 @@ size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep); * @retval false Endpoint is not busy. * @retval true Endpoint is busy. */ -bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep); +bool nrf_usbd_common_ep_is_busy(nrf_usbd_common_ep_t ep); /** * @brief Stall endpoint @@ -717,12 +729,12 @@ bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep); * Stall endpoit to send error information during next transfer request from * the host. * - * @note To stall endpoint it is safer to use @ref nrfx_usbd_setup_stall + * @note To stall endpoint it is safer to use @ref nrf_usbd_common_setup_stall * @note Stalled endpoint would not be cleared when DMA transfer finishes. * * @param[in] ep Endpoint number to stall. */ -void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_stall(nrf_usbd_common_ep_t ep); /** * @brief Clear stall flag on endpoint. @@ -737,7 +749,7 @@ void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep); * * @param[in] ep Endpoint number. */ -void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_stall_clear(nrf_usbd_common_ep_t ep); /** * @brief Check if endpoint is stalled. @@ -749,14 +761,14 @@ void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep); * @retval false Endpoint is not stalled. * @retval true Endpoint is stalled. */ -bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep); +bool nrf_usbd_common_ep_stall_check(nrf_usbd_common_ep_t ep); /** * @brief Clear current endpoint data toggle. * * @param[in] ep Endpoint number to clear. */ -void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_dtoggle_clear(nrf_usbd_common_ep_t ep); /** * @brief Get parsed setup data. @@ -766,7 +778,7 @@ void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep); * @param[out] p_setup Pointer to data structure that would be filled by * parsed data. */ -void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup); +void nrf_usbd_common_setup_get(nrf_usbd_common_setup_t *p_setup); /** * @brief Clear the control endpoint for packet reception during DATA stage. @@ -774,9 +786,9 @@ void nrfx_usbd_setup_get(nrfx_usbd_setup_t *p_setup); * This function may be called if any more data in control write transfer is expected. * Clears only OUT endpoint to be able to take another OUT data token. * It does not allow STATUS stage. - * @sa nrfx_usbd_setup_clear + * @sa nrf_usbd_common_setup_clear */ -void nrfx_usbd_setup_data_clear(void); +void nrf_usbd_common_setup_data_clear(void); /** * @brief Clear setup endpoint. @@ -784,45 +796,47 @@ void nrfx_usbd_setup_data_clear(void); * This function acknowledges setup when SETUP command was received and processed. * It has to be called if no data respond for the SETUP command is sent. */ -void nrfx_usbd_setup_clear(void); +void nrf_usbd_common_setup_clear(void); /** * @brief Stall setup endpoint. * * Mark an error on setup endpoint. */ -void nrfx_usbd_setup_stall(void); +void nrf_usbd_common_setup_stall(void); /** * @brief Abort pending transfer on selected endpoint. * * @param[in] ep Endpoint number. */ -void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep); +void nrf_usbd_common_ep_abort(nrf_usbd_common_ep_t ep); /** * @brief Get the information about expected transfer SETUP data direction. * * Function returns the information about last expected transfer direction. * - * @retval NRFX_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data. - * @retval NRFX_USBD_EPIN0 Expecting IN (Device->Host) direction. + * @retval NRF_USBD_COMMON_EPOUT0 Expecting OUT (Host->Device) direction or no data. + * @retval NRF_USBD_COMMON_EPIN0 Expecting IN (Device->Host) direction. */ -nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void); +nrf_usbd_common_ep_t nrf_usbd_common_last_setup_dir_get(void); /** * @brief Drop transfer on OUT endpoint. * * @param[in] ep OUT endpoint ID. */ -void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep); +void nrf_usbd_common_transfer_out_drop(nrf_usbd_common_ep_t ep); /** @} */ -void nrfx_usbd_irq_handler(void); +void nrf_usbd_common_irq_handler(void); #ifdef __cplusplus } #endif -#endif /* NRFX_USBD_H__ */ +#endif /* NRF_USBD_COMMON_H__ */ + +/** @endcond */ diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h new file mode 100644 index 00000000000..0ee23ccd2c5 --- /dev/null +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This file is undergoing transition towards native Zephyr nrf USB driver. */ + +/** @cond INTERNAL_HIDDEN */ + +#ifndef NRF_USBD_COMMON_ERRATA_H__ +#define NRF_USBD_COMMON_ERRATA_H__ + +#include +#include + +#ifndef NRF_USBD_COMMON_ERRATA_ENABLE +/** + * @brief The constant that informs if errata should be enabled at all. + * + * If this constant is set to 0, all the Errata bug fixes will be automatically disabled. + */ +#define NRF_USBD_COMMON_ERRATA_ENABLE 1 +#endif + +/* Errata: ISO double buffering not functional. **/ +static inline bool nrf_usbd_common_errata_166(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_166(); +} + +/* Errata: USBD might not reach its active state. **/ +static inline bool nrf_usbd_common_errata_171(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_171(); +} + +/* Errata: USB cannot be enabled. **/ +static inline bool nrf_usbd_common_errata_187(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_187(); +} + +/* Errata: USBD cannot receive tasks during DMA. **/ +static inline bool nrf_usbd_common_errata_199(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_199(); +} + +/* Errata: Device remains in SUSPEND too long. */ +static inline bool nrf_usbd_common_errata_211(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_211(); +} + +/* Errata: Unexpected behavior after reset. **/ +static inline bool nrf_usbd_common_errata_223(void) +{ + return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_223(); +} + +#endif /* NRF_USBD_COMMON_ERRATA_H__ */ + +/** @endcond */ diff --git a/drivers/usb/device/Kconfig b/drivers/usb/device/Kconfig index 768c0da7cf9..41d3d446f8d 100644 --- a/drivers/usb/device/Kconfig +++ b/drivers/usb/device/Kconfig @@ -104,7 +104,7 @@ config USB_NRFX bool "Nordic Semiconductor USB Device Controller Driver" default y depends on DT_HAS_NORDIC_NRF_USBD_ENABLED - select NRFX_USBD + select NRF_USBD_COMMON select NRFX_POWER imply USB_DEVICE_REMOTE_WAKEUP help diff --git a/drivers/usb/device/usb_dc_nrfx.c b/drivers/usb/device/usb_dc_nrfx.c index a8032baf1f1..49cb4621911 100644 --- a/drivers/usb/device/usb_dc_nrfx.c +++ b/drivers/usb/device/usb_dc_nrfx.c @@ -22,7 +22,8 @@ #include #include #include -#include +#include +#include #include @@ -288,12 +289,12 @@ static inline bool dev_ready(void) return get_usbd_ctx()->ready; } -static inline nrfx_usbd_ep_t ep_addr_to_nrfx(uint8_t ep) +static inline nrf_usbd_common_ep_t ep_addr_to_nrfx(uint8_t ep) { - return (nrfx_usbd_ep_t)ep; + return (nrf_usbd_common_ep_t)ep; } -static inline uint8_t nrfx_addr_to_ep(nrfx_usbd_ep_t ep) +static inline uint8_t nrfx_addr_to_ep(nrf_usbd_common_ep_t ep) { return (uint8_t)ep; } @@ -559,7 +560,7 @@ static void usbd_enable_endpoints(struct nrf_usbd_ctx *ctx) __ASSERT_NO_MSG(ep_ctx); if (ep_ctx->cfg.en) { - nrfx_usbd_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); + nrf_usbd_common_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); } } @@ -568,7 +569,7 @@ static void usbd_enable_endpoints(struct nrf_usbd_ctx *ctx) __ASSERT_NO_MSG(ep_ctx); if (ep_ctx->cfg.en) { - nrfx_usbd_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); + nrf_usbd_common_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); } } @@ -577,7 +578,7 @@ static void usbd_enable_endpoints(struct nrf_usbd_ctx *ctx) __ASSERT_NO_MSG(ep_ctx); if (ep_ctx->cfg.en) { - nrfx_usbd_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); + nrf_usbd_common_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); } } @@ -586,7 +587,7 @@ static void usbd_enable_endpoints(struct nrf_usbd_ctx *ctx) __ASSERT_NO_MSG(ep_ctx); if (ep_ctx->cfg.en) { - nrfx_usbd_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); + nrf_usbd_common_ep_enable(ep_addr_to_nrfx(ep_ctx->cfg.addr)); } } } @@ -606,7 +607,7 @@ static void ep_ctx_reset(struct nrf_usbd_ep_ctx *ep_ctx) /* Abort ongoing write operation. */ if (ep_ctx->write_in_progress) { - nrfx_usbd_ep_abort(ep_addr_to_nrfx(ep_ctx->cfg.addr)); + nrf_usbd_common_ep_abort(ep_addr_to_nrfx(ep_ctx->cfg.addr)); } ep_ctx->read_complete = true; @@ -673,9 +674,9 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt) switch (pwr_evt->state) { case USBD_ATTACHED: - if (!nrfx_usbd_is_enabled()) { + if (!nrf_usbd_common_is_enabled()) { LOG_DBG("USB detected"); - nrfx_usbd_enable(); + nrf_usbd_common_enable(); err = hfxo_start(ctx); __ASSERT_NO_MSG(err >= 0); } @@ -687,7 +688,7 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt) case USBD_POWERED: usbd_enable_endpoints(ctx); - nrfx_usbd_start(IS_ENABLED(CONFIG_USB_DEVICE_SOF)); + nrf_usbd_common_start(IS_ENABLED(CONFIG_USB_DEVICE_SOF)); ctx->ready = true; LOG_DBG("USB Powered"); @@ -699,7 +700,7 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt) case USBD_DETACHED: ctx->ready = false; - nrfx_usbd_disable(); + nrf_usbd_common_disable(); err = hfxo_stop(ctx); __ASSERT_NO_MSG(err >= 0); @@ -712,7 +713,7 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt) case USBD_SUSPENDED: if (dev_ready()) { - nrfx_usbd_suspend(); + nrf_usbd_common_suspend(); LOG_DBG("USB Suspend state"); if (ctx->status_cb) { @@ -771,7 +772,7 @@ static inline void usbd_work_process_setup(struct nrf_usbd_ep_ctx *ep_ctx) if (usb_reqtype_is_to_device(usbd_setup) && usbd_setup->wLength) { ctx->ctrl_read_len = usbd_setup->wLength; /* Allow data chunk on EP0 OUT */ - nrfx_usbd_setup_data_clear(); + nrf_usbd_common_setup_data_clear(); } else { ctx->ctrl_read_len = 0U; } @@ -791,9 +792,9 @@ static inline void usbd_work_process_recvreq(struct nrf_usbd_ctx *ctx, ep_ctx->read_complete = false; k_mutex_lock(&ctx->drv_lock, K_FOREVER); - NRFX_USBD_TRANSFER_OUT(transfer, ep_ctx->buf.data, - ep_ctx->cfg.max_sz); - nrfx_err_t err = nrfx_usbd_ep_transfer( + NRF_USBD_COMMON_TRANSFER_OUT(transfer, ep_ctx->buf.data, + ep_ctx->cfg.max_sz); + nrfx_err_t err = nrf_usbd_common_ep_transfer( ep_addr_to_nrfx(ep_ctx->cfg.addr), &transfer); if (err != NRFX_SUCCESS) { LOG_ERR("nRF USBD transfer error (OUT): 0x%02x", err); @@ -831,7 +832,7 @@ static inline void usbd_work_process_ep_events(struct usbd_ep_event *ep_evt) * no ZLP required. */ k_mutex_lock(&ctx->drv_lock, K_FOREVER); - nrfx_usbd_setup_clear(); + nrf_usbd_common_setup_clear(); k_mutex_unlock(&ctx->drv_lock); } ep_ctx->cfg.cb(ep_ctx->cfg.addr, @@ -842,14 +843,14 @@ static inline void usbd_work_process_ep_events(struct usbd_ep_event *ep_evt) } } -static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) +static void usbd_event_transfer_ctrl(nrf_usbd_common_evt_t const *const p_event) { struct nrf_usbd_ep_ctx *ep_ctx = endpoint_ctx(p_event->data.eptransfer.ep); if (NRF_USBD_EPIN_CHECK(p_event->data.eptransfer.ep)) { switch (p_event->data.eptransfer.status) { - case NRFX_USBD_EP_OK: { + case NRF_USBD_COMMON_EP_OK: { struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { @@ -867,7 +868,7 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) } break; - case NRFX_USBD_EP_ABORTED: { + case NRF_USBD_COMMON_EP_ABORTED: { LOG_DBG("Endpoint 0x%02x write aborted", p_event->data.eptransfer.ep); } @@ -882,7 +883,7 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) } } else { switch (p_event->data.eptransfer.status) { - case NRFX_USBD_EP_WAITING: { + case NRF_USBD_COMMON_EP_WAITING: { struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { @@ -901,23 +902,23 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) } break; - case NRFX_USBD_EP_OK: { + case NRF_USBD_COMMON_EP_OK: { struct nrf_usbd_ctx *ctx = get_usbd_ctx(); struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { return; } - nrfx_usbd_ep_status_t err_code; + nrf_usbd_common_ep_status_t err_code; ev->evt_type = USBD_EVT_EP; ev->evt.ep_evt.evt_type = EP_EVT_RECV_COMPLETE; ev->evt.ep_evt.ep = ep_ctx; - err_code = nrfx_usbd_ep_status_get( + err_code = nrf_usbd_common_ep_status_get( p_event->data.eptransfer.ep, &ep_ctx->buf.len); - if (err_code != NRFX_USBD_EP_OK) { + if (err_code != NRF_USBD_COMMON_EP_OK) { LOG_ERR("_ep_status_get failed! Code: %d", err_code); __ASSERT_NO_MSG(0); @@ -927,7 +928,7 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) if (ctx->ctrl_read_len > ep_ctx->buf.len) { ctx->ctrl_read_len -= ep_ctx->buf.len; /* Allow next data chunk on EP0 OUT */ - nrfx_usbd_setup_data_clear(); + nrf_usbd_common_setup_data_clear(); } else { ctx->ctrl_read_len = 0U; } @@ -947,14 +948,14 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event) } } -static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event) +static void usbd_event_transfer_data(nrf_usbd_common_evt_t const *const p_event) { struct nrf_usbd_ep_ctx *ep_ctx = endpoint_ctx(p_event->data.eptransfer.ep); if (NRF_USBD_EPIN_CHECK(p_event->data.eptransfer.ep)) { switch (p_event->data.eptransfer.status) { - case NRFX_USBD_EP_OK: { + case NRF_USBD_COMMON_EP_OK: { struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { @@ -973,7 +974,7 @@ static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event) } break; - case NRFX_USBD_EP_ABORTED: { + case NRF_USBD_COMMON_EP_ABORTED: { LOG_DBG("Endpoint 0x%02x write aborted", p_event->data.eptransfer.ep); } @@ -989,7 +990,7 @@ static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event) } else { switch (p_event->data.eptransfer.status) { - case NRFX_USBD_EP_WAITING: { + case NRF_USBD_COMMON_EP_WAITING: { struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { @@ -1009,7 +1010,7 @@ static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event) } break; - case NRFX_USBD_EP_OK: { + case NRF_USBD_COMMON_EP_OK: { struct usbd_event *ev = usbd_evt_alloc(); if (!ev) { @@ -1045,42 +1046,42 @@ static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event) /** * @brief nRFx USBD driver event handler function. */ -static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event) +static void usbd_event_handler(nrf_usbd_common_evt_t const *const p_event) { struct usbd_event evt = {0}; bool put_evt = false; switch (p_event->type) { - case NRFX_USBD_EVT_SUSPEND: + case NRF_USBD_COMMON_EVT_SUSPEND: LOG_DBG("SUSPEND state detected"); evt.evt_type = USBD_EVT_POWER; evt.evt.pwr_evt.state = USBD_SUSPENDED; put_evt = true; break; - case NRFX_USBD_EVT_RESUME: + case NRF_USBD_COMMON_EVT_RESUME: LOG_DBG("RESUMING from suspend"); evt.evt_type = USBD_EVT_POWER; evt.evt.pwr_evt.state = USBD_RESUMED; put_evt = true; break; - case NRFX_USBD_EVT_WUREQ: + case NRF_USBD_COMMON_EVT_WUREQ: LOG_DBG("RemoteWU initiated"); evt.evt_type = USBD_EVT_POWER; evt.evt.pwr_evt.state = USBD_RESUMED; put_evt = true; break; - case NRFX_USBD_EVT_RESET: + case NRF_USBD_COMMON_EVT_RESET: evt.evt_type = USBD_EVT_RESET; put_evt = true; break; - case NRFX_USBD_EVT_SOF: + case NRF_USBD_COMMON_EVT_SOF: if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) { evt.evt_type = USBD_EVT_SOF; put_evt = true; } break; - case NRFX_USBD_EVT_EPTRANSFER: { + case NRF_USBD_COMMON_EVT_EPTRANSFER: { struct nrf_usbd_ep_ctx *ep_ctx; ep_ctx = endpoint_ctx(p_event->data.eptransfer.ep); @@ -1101,10 +1102,10 @@ static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event) break; } - case NRFX_USBD_EVT_SETUP: { - nrfx_usbd_setup_t drv_setup; + case NRF_USBD_COMMON_EVT_SETUP: { + nrf_usbd_common_setup_t drv_setup; - nrfx_usbd_setup_get(&drv_setup); + nrf_usbd_common_setup_get(&drv_setup); if ((drv_setup.bRequest != USB_SREQ_SET_ADDRESS) || (USB_REQTYPE_GET_TYPE(drv_setup.bmRequestType) != USB_REQTYPE_TYPE_STANDARD)) { @@ -1147,8 +1148,8 @@ static inline void usbd_reinit(void) nrfx_err_t err; nrfx_power_usbevt_disable(); - nrfx_usbd_disable(); - nrfx_usbd_uninit(); + nrf_usbd_common_disable(); + nrf_usbd_common_uninit(); usbd_evt_flush(); @@ -1156,7 +1157,7 @@ static inline void usbd_reinit(void) __ASSERT_NO_MSG(ret == 0); nrfx_power_usbevt_enable(); - err = nrfx_usbd_init(usbd_event_handler); + err = nrf_usbd_common_init(usbd_event_handler); if (err != NRFX_SUCCESS) { LOG_DBG("nRF USBD driver reinit failed. Code: %d", err); @@ -1177,7 +1178,7 @@ static void usbd_sof_trigger_iso_read(void) struct usbd_event *ev; struct nrf_usbd_ep_ctx *ep_ctx; - ep_ctx = endpoint_ctx(NRFX_USBD_EPOUT8); + ep_ctx = endpoint_ctx(NRF_USBD_COMMON_EPOUT8); if (!ep_ctx) { LOG_ERR("There is no ISO ep"); return; @@ -1281,7 +1282,7 @@ int usb_dc_attach(void) (CLOCK_CONTROL_NRF_SUBSYS_HF))); IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), - nrfx_isr, nrfx_usbd_irq_handler, 0); + nrfx_isr, nrf_usbd_common_irq_handler, 0); nrfx_power_usbevt_enable(); @@ -1316,8 +1317,8 @@ int usb_dc_detach(void) usbd_evt_flush(); - if (nrfx_usbd_is_enabled()) { - nrfx_usbd_disable(); + if (nrf_usbd_common_is_enabled()) { + nrf_usbd_common_disable(); } (void)hfxo_stop(ctx); @@ -1440,8 +1441,8 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const ep_cfg) } } - nrfx_usbd_ep_max_packet_size_set(ep_addr_to_nrfx(ep_cfg->ep_addr), - ep_cfg->ep_mps); + nrf_usbd_common_ep_max_packet_size_set(ep_addr_to_nrfx(ep_cfg->ep_addr), + ep_cfg->ep_mps); return 0; } @@ -1461,11 +1462,11 @@ int usb_dc_ep_set_stall(const uint8_t ep) switch (ep_ctx->cfg.type) { case USB_DC_EP_CONTROL: - nrfx_usbd_setup_stall(); + nrf_usbd_common_setup_stall(); break; case USB_DC_EP_BULK: case USB_DC_EP_INTERRUPT: - nrfx_usbd_ep_stall(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_stall(ep_addr_to_nrfx(ep)); break; case USB_DC_EP_ISOCHRONOUS: LOG_ERR("STALL unsupported on ISO endpoint"); @@ -1499,8 +1500,8 @@ int usb_dc_ep_clear_stall(const uint8_t ep) return -EINVAL; } - nrfx_usbd_ep_dtoggle_clear(ep_addr_to_nrfx(ep)); - nrfx_usbd_ep_stall_clear(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_dtoggle_clear(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_stall_clear(ep_addr_to_nrfx(ep)); LOG_DBG("Unstall on EP 0x%02x", ep); return 0; @@ -1528,7 +1529,7 @@ int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled) return -EINVAL; } - *stalled = (uint8_t) nrfx_usbd_ep_stall_check(ep_addr_to_nrfx(ep)); + *stalled = (uint8_t) nrf_usbd_common_ep_stall_check(ep_addr_to_nrfx(ep)); return 0; } @@ -1550,11 +1551,11 @@ int usb_dc_ep_enable(const uint8_t ep) /* ISO transactions for full-speed device do not support * toggle sequencing and should only send DATA0 PID. */ - nrfx_usbd_ep_dtoggle_clear(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_dtoggle_clear(ep_addr_to_nrfx(ep)); /** Endpoint is enabled on SetInterface request. * This should also clear EP's halt status. */ - nrfx_usbd_ep_stall_clear(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_stall_clear(ep_addr_to_nrfx(ep)); } if (ep_ctx->cfg.en) { return -EALREADY; @@ -1566,7 +1567,7 @@ int usb_dc_ep_enable(const uint8_t ep) /* Defer the endpoint enable if USBD is not ready yet. */ if (dev_ready()) { - nrfx_usbd_ep_enable(ep_addr_to_nrfx(ep)); + nrf_usbd_common_ep_enable(ep_addr_to_nrfx(ep)); } return 0; @@ -1587,8 +1588,8 @@ int usb_dc_ep_disable(const uint8_t ep) LOG_DBG("EP disable: 0x%02x", ep); - nrfx_usbd_ep_disable(ep_addr_to_nrfx(ep)); - /* Clear write_in_progress as nrfx_usbd_ep_disable() + nrf_usbd_common_ep_disable(ep_addr_to_nrfx(ep)); + /* Clear write_in_progress as nrf_usbd_common_ep_disable() * terminates endpoint transaction. */ ep_ctx->write_in_progress = false; @@ -1614,7 +1615,7 @@ int usb_dc_ep_flush(const uint8_t ep) ep_ctx->buf.len = 0U; ep_ctx->buf.curr = ep_ctx->buf.data; - nrfx_usbd_transfer_out_drop(ep_addr_to_nrfx(ep)); + nrf_usbd_common_transfer_out_drop(ep_addr_to_nrfx(ep)); return 0; } @@ -1682,15 +1683,15 @@ int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data, * and perform appropriate action. */ if ((ep_ctx->cfg.type == USB_DC_EP_CONTROL) - && (nrfx_usbd_last_setup_dir_get() != ep)) { - nrfx_usbd_setup_clear(); + && (nrf_usbd_common_last_setup_dir_get() != ep)) { + nrf_usbd_common_setup_clear(); k_mutex_unlock(&ctx->drv_lock); return 0; } ep_ctx->write_in_progress = true; - NRFX_USBD_TRANSFER_IN(transfer, data, data_len, 0); - nrfx_err_t err = nrfx_usbd_ep_transfer(ep_addr_to_nrfx(ep), &transfer); + NRF_USBD_COMMON_TRANSFER_IN(transfer, data, data_len, 0); + nrfx_err_t err = nrf_usbd_common_ep_transfer(ep_addr_to_nrfx(ep), &transfer); if (err != NRFX_SUCCESS) { ep_ctx->write_in_progress = false; @@ -1870,7 +1871,7 @@ int usb_dc_ep_mps(const uint8_t ep) int usb_dc_wakeup_request(void) { - bool res = nrfx_usbd_wakeup_req(); + bool res = nrf_usbd_common_wakeup_req(); if (!res) { return -EAGAIN; @@ -1906,7 +1907,7 @@ static int usb_init(void) .handler = usb_dc_power_event_handler }; - err = nrfx_usbd_init(usbd_event_handler); + err = nrf_usbd_common_init(usbd_event_handler); if (err != NRFX_SUCCESS) { LOG_DBG("nRF USBD driver init failed. Code: %d", (uint32_t)err); return -EIO; diff --git a/drivers/usb/udc/Kconfig.nrf b/drivers/usb/udc/Kconfig.nrf index 0f424ffe5d0..93c5090bed2 100644 --- a/drivers/usb/udc/Kconfig.nrf +++ b/drivers/usb/udc/Kconfig.nrf @@ -5,7 +5,7 @@ config UDC_NRF bool "Nordic Semiconductor USB device controller driver" default y depends on DT_HAS_NORDIC_NRF_USBD_ENABLED - select NRFX_USBD + select NRF_USBD_COMMON select NRFX_POWER help nRF USB device controller driver. diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index 64fae5dae21..bca098347d8 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -21,7 +21,8 @@ #include #include -#include +#include +#include #include #include "udc_common.h" @@ -47,7 +48,7 @@ enum udc_nrf_event_type { struct udc_nrf_evt { enum udc_nrf_event_type type; union { - nrfx_usbd_evt_t hal_evt; + nrf_usbd_common_evt_t hal_evt; uint8_t ep; }; }; @@ -82,10 +83,10 @@ static struct onoff_client hfxo_cli; static void udc_nrf_clear_control_out(const struct device *dev) { - if (nrfx_usbd_last_setup_dir_get() == USB_CONTROL_EP_OUT && + if (nrf_usbd_common_last_setup_dir_get() == USB_CONTROL_EP_OUT && udc_nrf_setup_rcvd) { /* Allow data chunk on EP0 OUT */ - nrfx_usbd_setup_data_clear(); + nrf_usbd_common_setup_data_clear(); udc_nrf_setup_rcvd = false; LOG_INF("Allow data OUT"); } @@ -101,15 +102,15 @@ static void udc_event_xfer_in_next(const struct device *dev, const uint8_t ep) buf = udc_buf_peek(dev, ep); if (buf != NULL) { - nrfx_usbd_transfer_t xfer = { + nrf_usbd_common_transfer_t xfer = { .p_data = {.tx = buf->data}, .size = buf->len, .flags = udc_ep_buf_has_zlp(buf) ? - NRFX_USBD_TRANSFER_ZLP_FLAG : 0, + NRF_USBD_COMMON_TRANSFER_ZLP_FLAG : 0, }; nrfx_err_t err; - err = nrfx_usbd_ep_transfer(ep, &xfer); + err = nrf_usbd_common_ep_transfer(ep, &xfer); if (err != NRFX_SUCCESS) { LOG_ERR("ep 0x%02x nrfx error: %x", ep, err); /* REVISE: remove from endpoint queue? ASSERT? */ @@ -141,7 +142,7 @@ static void udc_event_xfer_ctrl_in(const struct device *dev, /* Update to next stage of control transfer */ udc_ctrl_update_stage(dev, buf); - nrfx_usbd_setup_clear(); + nrf_usbd_common_setup_clear(); } static void udc_event_fake_status_in(const struct device *dev) @@ -159,13 +160,13 @@ static void udc_event_fake_status_in(const struct device *dev) } static void udc_event_xfer_in(const struct device *dev, - nrfx_usbd_evt_t const *const event) + nrf_usbd_common_evt_t const *const event) { uint8_t ep = event->data.eptransfer.ep; struct net_buf *buf; switch (event->data.eptransfer.status) { - case NRFX_USBD_EP_OK: + case NRF_USBD_COMMON_EP_OK: buf = udc_buf_get(dev, ep); if (buf == NULL) { LOG_ERR("ep 0x%02x queue is empty", ep); @@ -181,7 +182,7 @@ static void udc_event_xfer_in(const struct device *dev, udc_submit_ep_event(dev, buf, 0); break; - case NRFX_USBD_EP_ABORTED: + case NRF_USBD_COMMON_EP_ABORTED: LOG_WRN("aborted IN ep 0x%02x", ep); buf = udc_buf_get_all(dev, ep); @@ -228,14 +229,14 @@ static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) buf = udc_buf_peek(dev, ep); if (buf != NULL) { - nrfx_usbd_transfer_t xfer = { + nrf_usbd_common_transfer_t xfer = { .p_data = {.rx = buf->data}, .size = buf->size, .flags = 0, }; nrfx_err_t err; - err = nrfx_usbd_ep_transfer(ep, &xfer); + err = nrf_usbd_common_ep_transfer(ep, &xfer); if (err != NRFX_SUCCESS) { LOG_ERR("ep 0x%02x nrfx error: %x", ep, err); /* REVISE: remove from endpoint queue? ASSERT? */ @@ -249,24 +250,24 @@ static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) } static void udc_event_xfer_out(const struct device *dev, - nrfx_usbd_evt_t const *const event) + nrf_usbd_common_evt_t const *const event) { uint8_t ep = event->data.eptransfer.ep; - nrfx_usbd_ep_status_t err_code; + nrf_usbd_common_ep_status_t err_code; struct net_buf *buf; size_t len; switch (event->data.eptransfer.status) { - case NRFX_USBD_EP_WAITING: + case NRF_USBD_COMMON_EP_WAITING: /* * There is nothing to do here, new transfer * will be tried in both cases later. */ break; - case NRFX_USBD_EP_OK: - err_code = nrfx_usbd_ep_status_get(ep, &len); - if (err_code != NRFX_USBD_EP_OK) { + case NRF_USBD_COMMON_EP_OK: + err_code = nrf_usbd_common_ep_status_get(ep, &len); + if (err_code != NRF_USBD_COMMON_EP_OK) { LOG_ERR("OUT transfer failed %d", err_code); } @@ -325,8 +326,8 @@ static int udc_event_xfer_setup(const struct device *dev) } udc_ep_buf_set_setup(buf); - nrfx_usbd_setup_get((nrfx_usbd_setup_t *)buf->data); - net_buf_add(buf, sizeof(nrfx_usbd_setup_t)); + nrf_usbd_common_setup_get((nrf_usbd_common_setup_t *)buf->data); + net_buf_add(buf, sizeof(nrf_usbd_common_setup_t)); udc_nrf_setup_rcvd = true; /* Update to next stage of control transfer */ @@ -366,7 +367,7 @@ static void udc_nrf_thread(void *p1, void *p2, void *p3) case UDC_NRF_EVT_HAL: ep = evt.hal_evt.data.eptransfer.ep; switch (evt.hal_evt.type) { - case NRFX_USBD_EVT_EPTRANSFER: + case NRF_USBD_COMMON_EVT_EPTRANSFER: start_xfer = true; if (USB_EP_DIR_IS_IN(ep)) { udc_event_xfer_in(dev, &evt.hal_evt); @@ -374,7 +375,7 @@ static void udc_nrf_thread(void *p1, void *p2, void *p3) udc_event_xfer_out(dev, &evt.hal_evt); } break; - case NRFX_USBD_EVT_SETUP: + case NRF_USBD_COMMON_EVT_SETUP: udc_event_xfer_setup(dev); break; default: @@ -419,33 +420,33 @@ static void udc_sof_check_iso_out(const struct device *dev) } } -static void usbd_event_handler(nrfx_usbd_evt_t const *const hal_evt) +static void usbd_event_handler(nrf_usbd_common_evt_t const *const hal_evt) { switch (hal_evt->type) { - case NRFX_USBD_EVT_SUSPEND: + case NRF_USBD_COMMON_EVT_SUSPEND: LOG_INF("SUSPEND state detected"); - nrfx_usbd_suspend(); + nrf_usbd_common_suspend(); udc_set_suspended(udc_nrf_dev, true); udc_submit_event(udc_nrf_dev, UDC_EVT_SUSPEND, 0); break; - case NRFX_USBD_EVT_RESUME: + case NRF_USBD_COMMON_EVT_RESUME: LOG_INF("RESUMING from suspend"); udc_set_suspended(udc_nrf_dev, false); udc_submit_event(udc_nrf_dev, UDC_EVT_RESUME, 0); break; - case NRFX_USBD_EVT_WUREQ: + case NRF_USBD_COMMON_EVT_WUREQ: LOG_INF("Remote wakeup initiated"); break; - case NRFX_USBD_EVT_RESET: + case NRF_USBD_COMMON_EVT_RESET: LOG_INF("Reset"); udc_submit_event(udc_nrf_dev, UDC_EVT_RESET, 0); break; - case NRFX_USBD_EVT_SOF: + case NRF_USBD_COMMON_EVT_SOF: udc_submit_event(udc_nrf_dev, UDC_EVT_SOF, 0); udc_sof_check_iso_out(udc_nrf_dev); break; - case NRFX_USBD_EVT_EPTRANSFER: - case NRFX_USBD_EVT_SETUP: { + case NRF_USBD_COMMON_EVT_EPTRANSFER: + case NRF_USBD_COMMON_EVT_SETUP: { struct udc_nrf_evt evt = { .type = UDC_NRF_EVT_HAL, .hal_evt = *hal_evt, @@ -471,7 +472,7 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt) case NRFX_POWER_USB_EVT_READY: LOG_INF("POWER event ready"); udc_submit_event(udc_nrf_dev, UDC_EVT_VBUS_READY, 0); - nrfx_usbd_start(true); + nrf_usbd_common_start(true); break; case NRFX_POWER_USB_EVT_REMOVED: LOG_INF("POWER event removed"); @@ -489,7 +490,7 @@ static void udc_nrf_fake_status_in(const struct device *dev) .ep = USB_CONTROL_EP_IN, }; - if (nrfx_usbd_last_setup_dir_get() == USB_CONTROL_EP_OUT) { + if (nrf_usbd_common_last_setup_dir_get() == USB_CONTROL_EP_OUT) { /* Let controller perform status IN stage */ k_msgq_put(&drv_msgq, &evt, K_NO_WAIT); } @@ -519,9 +520,9 @@ static int udc_nrf_ep_enqueue(const struct device *dev, static int udc_nrf_ep_dequeue(const struct device *dev, struct udc_ep_config *cfg) { - bool busy = nrfx_usbd_ep_is_busy(cfg->addr); + bool busy = nrf_usbd_common_ep_is_busy(cfg->addr); - nrfx_usbd_ep_abort(cfg->addr); + nrf_usbd_common_ep_abort(cfg->addr); if (USB_EP_DIR_IS_OUT(cfg->addr) || !busy) { struct net_buf *buf; @@ -550,14 +551,14 @@ static int udc_nrf_ep_enable(const struct device *dev, __ASSERT_NO_MSG(cfg); mps = (cfg->mps == 0) ? cfg->caps.mps : cfg->mps; - nrfx_usbd_ep_max_packet_size_set(cfg->addr, mps); - nrfx_usbd_ep_enable(cfg->addr); + nrf_usbd_common_ep_max_packet_size_set(cfg->addr, mps); + nrf_usbd_common_ep_enable(cfg->addr); if (!NRF_USBD_EPISO_CHECK(cfg->addr)) { /* ISO transactions for full-speed device do not support * toggle sequencing and should only send DATA0 PID. */ - nrfx_usbd_ep_dtoggle_clear(cfg->addr); - nrfx_usbd_ep_stall_clear(cfg->addr); + nrf_usbd_common_ep_dtoggle_clear(cfg->addr); + nrf_usbd_common_ep_stall_clear(cfg->addr); } LOG_DBG("Enable ep 0x%02x", cfg->addr); @@ -569,7 +570,7 @@ static int udc_nrf_ep_disable(const struct device *dev, struct udc_ep_config *cfg) { __ASSERT_NO_MSG(cfg); - nrfx_usbd_ep_disable(cfg->addr); + nrf_usbd_common_ep_disable(cfg->addr); LOG_DBG("Disable ep 0x%02x", cfg->addr); return 0; @@ -582,9 +583,9 @@ static int udc_nrf_ep_set_halt(const struct device *dev, if (cfg->addr == USB_CONTROL_EP_OUT || cfg->addr == USB_CONTROL_EP_IN) { - nrfx_usbd_setup_stall(); + nrf_usbd_common_setup_stall(); } else { - nrfx_usbd_ep_stall(cfg->addr); + nrf_usbd_common_ep_stall(cfg->addr); } return 0; @@ -595,8 +596,8 @@ static int udc_nrf_ep_clear_halt(const struct device *dev, { LOG_DBG("Clear halt ep 0x%02x", cfg->addr); - nrfx_usbd_ep_dtoggle_clear(cfg->addr); - nrfx_usbd_ep_stall_clear(cfg->addr); + nrf_usbd_common_ep_dtoggle_clear(cfg->addr); + nrf_usbd_common_ep_stall_clear(cfg->addr); return 0; } @@ -616,7 +617,7 @@ static int udc_nrf_set_address(const struct device *dev, const uint8_t addr) static int udc_nrf_host_wakeup(const struct device *dev) { - bool res = nrfx_usbd_wakeup_req(); + bool res = nrf_usbd_common_wakeup_req(); LOG_DBG("Host wakeup request"); if (!res) { @@ -630,7 +631,7 @@ static int udc_nrf_enable(const struct device *dev) { int ret; - nrfx_usbd_enable(); + nrf_usbd_common_enable(); sys_notify_init_spinwait(&hfxo_cli.notify); ret = onoff_request(hfxo_mgr, &hfxo_cli); @@ -646,7 +647,7 @@ static int udc_nrf_disable(const struct device *dev) { int ret; - nrfx_usbd_disable(); + nrf_usbd_common_disable(); ret = onoff_cancel_or_release(hfxo_mgr, &hfxo_cli); if (ret < 0) { @@ -675,12 +676,12 @@ static int udc_nrf_init(const struct device *dev) #endif IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), - nrfx_isr, nrfx_usbd_irq_handler, 0); + nrfx_isr, nrf_usbd_common_irq_handler, 0); (void)nrfx_power_init(&cfg->pwr); nrfx_power_usbevt_init(&cfg->evt); - ret = nrfx_usbd_init(usbd_event_handler); + ret = nrf_usbd_common_init(usbd_event_handler); if (ret != NRFX_SUCCESS) { LOG_ERR("nRF USBD driver initialization failed"); return -EIO; @@ -719,7 +720,7 @@ static int udc_nrf_shutdown(const struct device *dev) } nrfx_power_usbevt_disable(); - nrfx_usbd_uninit(); + nrf_usbd_common_uninit(); nrfx_power_usbevt_uninit(); #ifdef CONFIG_HAS_HW_NRF_USBREG irq_disable(USBREGULATOR_IRQn); @@ -748,14 +749,14 @@ static int udc_nrf_driver_init(const struct device *dev) ep_cfg_out[i].caps.out = 1; if (i == 0) { ep_cfg_out[i].caps.control = 1; - ep_cfg_out[i].caps.mps = NRFX_USBD_EPSIZE; + ep_cfg_out[i].caps.mps = NRF_USBD_COMMON_EPSIZE; } else if (i < (CFG_EPOUT_CNT + 1)) { ep_cfg_out[i].caps.bulk = 1; ep_cfg_out[i].caps.interrupt = 1; - ep_cfg_out[i].caps.mps = NRFX_USBD_EPSIZE; + ep_cfg_out[i].caps.mps = NRF_USBD_COMMON_EPSIZE; } else { ep_cfg_out[i].caps.iso = 1; - ep_cfg_out[i].caps.mps = NRFX_USBD_ISOSIZE / 2; + ep_cfg_out[i].caps.mps = NRF_USBD_COMMON_ISOSIZE / 2; } ep_cfg_out[i].addr = USB_EP_DIR_OUT | i; @@ -770,14 +771,14 @@ static int udc_nrf_driver_init(const struct device *dev) ep_cfg_in[i].caps.in = 1; if (i == 0) { ep_cfg_in[i].caps.control = 1; - ep_cfg_in[i].caps.mps = NRFX_USBD_EPSIZE; + ep_cfg_in[i].caps.mps = NRF_USBD_COMMON_EPSIZE; } else if (i < (CFG_EPIN_CNT + 1)) { ep_cfg_in[i].caps.bulk = 1; ep_cfg_in[i].caps.interrupt = 1; - ep_cfg_in[i].caps.mps = NRFX_USBD_EPSIZE; + ep_cfg_in[i].caps.mps = NRF_USBD_COMMON_EPSIZE; } else { ep_cfg_in[i].caps.iso = 1; - ep_cfg_in[i].caps.mps = NRFX_USBD_ISOSIZE / 2; + ep_cfg_in[i].caps.mps = NRF_USBD_COMMON_ISOSIZE / 2; } ep_cfg_in[i].addr = USB_EP_DIR_IN | i; diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 4d637ba43f1..69afbcc9c51 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -104,7 +104,6 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_TWIM ${SRC_DIR}/nrfx_twim.c) zephyr_library_sources_ifdef(CONFIG_NRFX_TWIS ${SRC_DIR}/nrfx_twis.c) zephyr_library_sources_ifdef(CONFIG_NRFX_UART ${SRC_DIR}/nrfx_uart.c) zephyr_library_sources_ifdef(CONFIG_NRFX_UARTE ${SRC_DIR}/nrfx_uarte.c) -zephyr_library_sources_ifdef(CONFIG_NRFX_USBD ${SRC_DIR}/nrfx_usbd.c) zephyr_library_sources_ifdef(CONFIG_NRFX_USBREG ${SRC_DIR}/nrfx_usbreg.c) zephyr_library_sources_ifdef(CONFIG_NRFX_WDT ${SRC_DIR}/nrfx_wdt.c) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 25ba1194da8..78d9671b3c4 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -519,19 +519,6 @@ config NRFX_UARTE3 depends on $(dt_nodelabel_has_compat,uart3,$(DT_COMPAT_NORDIC_NRF_UARTE)) select NRFX_UARTE -config NRFX_USBD - bool "USBD driver" - depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_USBD)) - -config NRFX_USBD_ISO_IN_ZLP - bool "Send ZLP on ISO IN when not ready" - depends on NRFX_USBD - default y - help - Controls the response of the ISO IN endpoint to an IN token when no - data is ready to be sent. When enabled, ZLP is sent when no data is - ready. When disabled, no response is sent (bus timeout occurs). - config NRFX_USBREG bool "USBREG driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_USBREG)) diff --git a/modules/hal_nordic/nrfx/Kconfig.logging b/modules/hal_nordic/nrfx/Kconfig.logging index 41776380cdb..7f7b785e70c 100644 --- a/modules/hal_nordic/nrfx/Kconfig.logging +++ b/modules/hal_nordic/nrfx/Kconfig.logging @@ -132,10 +132,6 @@ config NRFX_UARTE_LOG bool "UARTE driver logging" depends on NRFX_UARTE -config NRFX_USBD_LOG - bool "USBD driver logging" - depends on NRFX_USBD - config NRFX_USBREG_LOG bool "USBREG driver logging" depends on NRFX_USBREG diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index ce4a6214f7d..04be67a7b43 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -546,17 +546,6 @@ #define NRFX_UARTE3_ENABLED 1 #endif -#ifdef CONFIG_NRFX_USBD -#define NRFX_USBD_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_USBD_LOG -#define NRFX_USBD_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_USBD_ISO_IN_ZLP -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 1 -#endif - #ifdef CONFIG_NRFX_USBREG #define NRFX_USBREG_ENABLED 1 #endif diff --git a/modules/hal_nordic/nrfx/nrfx_usbd_errata.h b/modules/hal_nordic/nrfx/nrfx_usbd_errata.h deleted file mode 100644 index 7ce8b3955d3..00000000000 --- a/modules/hal_nordic/nrfx/nrfx_usbd_errata.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_USBD_ERRATA_H__ -#define NRFX_USBD_ERRATA_H__ - -#include -#include - -#ifndef NRFX_USBD_ERRATA_ENABLE -/** - * @brief The constant that informs if errata should be enabled at all. - * - * If this constant is set to 0, all the Errata bug fixes will be automatically disabled. - */ -#define NRFX_USBD_ERRATA_ENABLE 1 -#endif - -/* Errata: ISO double buffering not functional. **/ -static inline bool nrfx_usbd_errata_166(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_166(); -} - -/* Errata: USBD might not reach its active state. **/ -static inline bool nrfx_usbd_errata_171(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_171(); -} - -/* Errata: USB cannot be enabled. **/ -static inline bool nrfx_usbd_errata_187(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_187(); -} - -/* Errata: USBD cannot receive tasks during DMA. **/ -static inline bool nrfx_usbd_errata_199(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_199(); -} - -/* Errata: Device remains in SUSPEND too long. */ -static inline bool nrfx_usbd_errata_211(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_211(); -} - -/* Errata: Unexpected behavior after reset. **/ -static inline bool nrfx_usbd_errata_223(void) -{ - return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_223(); -} - -#endif /* NRFX_USBD_ERRATA_H__ */ diff --git a/subsys/usb/device/Kconfig b/subsys/usb/device/Kconfig index 8907d952d87..1f0a008058e 100644 --- a/subsys/usb/device/Kconfig +++ b/subsys/usb/device/Kconfig @@ -97,7 +97,7 @@ config USB_NUMOF_EP_WRITE_RETRIES config USB_DEVICE_SOF bool "Start of Frame processing in events" - default y if (USB_DEVICE_AUDIO && NRFX_USBD) + default y if (USB_DEVICE_AUDIO && NRF_USBD_COMMON) config USB_DEVICE_BOS bool "USB Binary Device Object Store (BOS)" From a0a80f6299ff1cd211bcaa147cd189c634562eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 12 Oct 2023 15:21:21 +0200 Subject: [PATCH 3199/4498] nrf_usbd_common: Guard DMA with semaphore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rely on semaphore to serialize access to DMA instead of busy looping after triggering DMA. With this change Ozone Code Profile generated with J-Trace Pro on nrf52840dk_nrf52840 board running headphones microphone sample shows following Load changes (trace data was reset once playback and recording started and percentages were taken when memcpy reached 200 000 Run Count): * usbd_dmareq_process() from 17.16% to 2.24% * memcpy() from 9.37% to 8.36% * nrf_usbd_common_irq_handler() from 8.89% to 10.88% Mark nrf_usbd_common_stop() as static because the caller must acquire DMA semaphore before calling this function and the only place where it is used is already acquiring the semaphore. Disable EP0 SETUP interrupt when there is active DMA on EP0 to eliminate the need for aborting DMA on EP0. This code path should not really happen in real life though because hosts must not issue new SETUP before a relatively long timeout (at least 50 ms). Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 102 ++++++++++++------ .../common/nrf_usbd_common/nrf_usbd_common.h | 13 --- 2 files changed, 68 insertions(+), 47 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 0a7235e9b52..77907bd9244 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -13,6 +13,7 @@ #include "nrf_usbd_common.h" #include "nrf_usbd_common_errata.h" #include +#include #include LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); @@ -228,14 +229,11 @@ static uint32_t m_ep_ready; */ static atomic_t m_ep_dma_waiting; -/** - * @brief Current EasyDMA state. - * - * Single flag, updated only inside interrupts, that marks current EasyDMA state. +/* Semaphore to guard EasyDMA access. * In USBD there is only one DMA channel working in background, and new transfer * cannot be started when there is ongoing transfer on any other channel. */ -static bool m_dma_pending; +static K_SEM_DEFINE(dma_available, 1, 1); /** * @brief Tracks whether total bytes transferred by DMA is even or odd. @@ -315,6 +313,8 @@ static uint32_t m_tx_buffer[NRFX_CEIL_DIV(NRF_USBD_COMMON_FEEDER_BUFFER_SIZE, si /* Early declaration. Documentation above definition. */ static void usbd_dmareq_process(void); +static inline void usbd_int_rise(void); +static void nrf_usbd_common_stop(void); /** * @brief Change endpoint number to endpoint event code. @@ -643,7 +643,6 @@ static inline void usbd_dma_pending_set(void) if (nrf_usbd_common_errata_199()) { *((volatile uint32_t *)0x40027C1C) = 0x00000082; } - m_dma_pending = true; } /** @@ -657,7 +656,6 @@ static inline void usbd_dma_pending_clear(void) if (nrf_usbd_common_errata_199()) { *((volatile uint32_t *)0x40027C1C) = 0x00000000; } - m_dma_pending = false; } /** @@ -754,7 +752,16 @@ static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_abort(nrf_usbd_common_ep_t ep) { + /* Only abort if there is no active DMA */ + k_sem_take(&dma_available, K_FOREVER); usbd_ep_abort(ep); + k_sem_give(&dma_available); + + /* This function was holding DMA semaphore and could potentially prevent + * next DMA from executing. Fire IRQ handler to check if any DMA needs + * to be started. + */ + usbd_int_rise(); } /** @@ -829,7 +836,12 @@ static inline void nrf_usbd_ep0in_dma_handler(void) const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPIN0; LOG_DBG("USB event: DMA ready IN0"); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); + + nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -858,7 +870,10 @@ static inline void nrf_usbd_epin_dma_handler(nrf_usbd_common_ep_t ep) __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -882,7 +897,10 @@ static inline void nrf_usbd_epiniso_dma_handler(nrf_usbd_common_ep_t ep) } __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -913,7 +931,12 @@ static inline void nrf_usbd_ep0out_dma_handler(void) const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPOUT0; LOG_DBG("USB event: DMA ready OUT0"); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); + + nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -945,7 +968,10 @@ static inline void nrf_usbd_epout_dma_handler(nrf_usbd_common_ep_t ep) __ASSERT_NO_MSG(NRF_USBD_EPOUT_CHECK(ep)); __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -978,7 +1004,10 @@ static inline void nrf_usbd_epoutiso_dma_handler(nrf_usbd_common_ep_t ep) LOG_DBG("DMA ready ISOOUT: %x", ep); } __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); + /* DMA finished, track if total bytes transferred is even or odd */ + m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); + k_sem_give(&dma_available); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -1148,12 +1177,6 @@ static void ev_setup_handler(void) nrf_usbd_setup_windex_get(NRF_USBD), nrf_usbd_setup_wlength_get(NRF_USBD)); uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); - if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & - (1U << ep2bit(m_last_setup_dir))) { - LOG_DBG("USBD drv: Trying to abort last transfer on EP0"); - usbd_ep_abort(m_last_setup_dir); - } - m_last_setup_dir = ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) == (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) @@ -1162,6 +1185,7 @@ static void ev_setup_handler(void) (void)(atomic_and(&m_ep_dma_waiting, ~((1U << ep2bit(NRF_USBD_COMMON_EPOUT0)) | (1U << ep2bit(NRF_USBD_COMMON_EPIN0))))); + m_ep_ready &= ~(1U << ep2bit(NRF_USBD_COMMON_EPOUT0)); m_ep_ready |= 1U << ep2bit(NRF_USBD_COMMON_EPIN0); const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_SETUP}; @@ -1279,7 +1303,8 @@ static inline size_t usbd_ep_iso_capacity(nrf_usbd_common_ep_t ep) */ static void usbd_dmareq_process(void) { - if (!m_dma_pending) { + if ((m_ep_dma_waiting & m_ep_ready) && + (k_sem_take(&dma_available, K_NO_WAIT) == 0)) { uint32_t req; while (0 != (req = m_ep_dma_waiting & m_ep_ready)) { @@ -1358,23 +1383,20 @@ static void usbd_dmareq_process(void) (uint32_t)transfer.size); usbd_dma_start(ep); - /* There is a lot of USBD registers that cannot be accessed during EasyDMA - * transfer. This is quick fix to maintain stability of the stack. It cost - * some performance but makes stack stable. + + /* Do not process SETUP packet until EP0 DMA completes. + * DMA transfer itself will always complete regardless + * of host actions and this action is solely to prevent + * the need to abort active DMA. */ - while (!nrf_usbd_event_check(NRF_USBD, - nrf_usbd_common_ep_to_endevent(ep))) { - /* Empty */ + if ((ep == NRF_USBD_COMMON_EPOUT0) || (ep == NRF_USBD_COMMON_EPIN0)) { + nrf_usbd_int_disable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); } - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - if (NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG) { - LOG_DBG("USB DMA process - finishing"); - } /* Transfer started - exit the loop */ - break; + return; } + k_sem_give(&dma_available); } else { if (NRF_USBD_COMMON_DMAREQ_PROCESS_DEBUG) { LOG_DBG("USB DMA process - EasyDMA busy"); @@ -1532,7 +1554,7 @@ static const nrfx_irq_handler_t m_isr[] = {[USBD_INTEN_USBRESET_Pos] = ev_usbres void nrf_usbd_common_irq_handler(void) { const uint32_t enabled = nrf_usbd_int_enable_get(NRF_USBD); - uint32_t to_process = enabled; + uint32_t to_process = enabled & ~NRF_USBD_INT_EP0SETUP_MASK; uint32_t active = 0; /* Check all enabled interrupts */ @@ -1547,10 +1569,6 @@ void nrf_usbd_common_irq_handler(void) } /* Process the active interrupts */ - bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK); - - active &= ~NRF_USBD_INT_EP0SETUP_MASK; - while (active) { uint8_t event_nr = NRF_CTZ(active); @@ -1559,7 +1577,9 @@ void nrf_usbd_common_irq_handler(void) } usbd_dmareq_process(); - if (setup_active) { + /* Handle SETUP only if there is no active DMA on EP0 */ + if (nrf_usbd_int_enable_check(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK) && + nrf_usbd_event_get_and_clear(NRF_USBD, NRF_USBD_EVENT_EP0SETUP)) { m_isr[USBD_INTEN_EP0SETUP_Pos](); } } @@ -1658,6 +1678,7 @@ void nrf_usbd_common_enable(void) m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); m_ep_dma_waiting = 0; m_dma_odd = 0; + __ASSERT_NO_MSG(k_sem_count_get(&dma_available) == 1); usbd_dma_pending_clear(); m_last_setup_dir = NRF_USBD_COMMON_EPOUT0; @@ -1677,6 +1698,9 @@ void nrf_usbd_common_disable(void) { __ASSERT_NO_MSG(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED); + /* Make sure DMA is not active */ + k_sem_take(&dma_available, K_FOREVER); + /* Stop just in case */ nrf_usbd_common_stop(); @@ -1689,12 +1713,13 @@ void nrf_usbd_common_disable(void) nrf_usbd_event_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0); nrf_usbd_ep_easydma_set(NRF_USBD, NRF_USBD_COMMON_EPIN0, (uint32_t)&m_dma_odd, 1); usbd_dma_start(NRF_USBD_COMMON_EPIN0); - while (!nrf_usbd_event_check(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0)) { + while (!nrf_usbd_event_get_and_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0)) { } m_dma_odd = 0; } nrf_usbd_disable(NRF_USBD); usbd_dma_pending_clear(); + k_sem_give(&dma_available); m_drv_state = NRFX_DRV_STATE_INITIALIZED; #if NRF_USBD_COMMON_USE_WORKAROUND_FOR_ANOMALY_211 @@ -1728,7 +1753,7 @@ void nrf_usbd_common_start(bool enable_sof) nrf_usbd_pullup_enable(NRF_USBD); } -void nrf_usbd_common_stop(void) +static void nrf_usbd_common_stop(void) { __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_POWERED_ON); @@ -1884,9 +1909,18 @@ void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) { + /* Only disable endpoint if there is no active DMA */ + k_sem_take(&dma_available, K_FOREVER); usbd_ep_abort(ep); nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep)); nrf_usbd_int_disable(NRF_USBD, nrf_usbd_common_ep_to_int(ep)); + k_sem_give(&dma_available); + + /* This function was holding DMA semaphore and could potentially prevent + * next DMA from executing. Fire IRQ handler to check if any DMA needs + * to be started. + */ + usbd_int_rise(); } void nrf_usbd_common_ep_default_config(void) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h index 047c5a29709..328a8e7dd2b 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h @@ -421,19 +421,6 @@ void nrf_usbd_common_disable(void); */ void nrf_usbd_common_start(bool enable_sof); -/** - * @brief Stop USB functionality. - * - * This function disables USBD pull-up and interrupts. - * - * The HFXO request is released in this function. - * - * @note - * This function can also be used to logically disconnect USB from the HOST that - * would force it to enumerate device after calling @ref nrf_usbd_common_start. - */ -void nrf_usbd_common_stop(void); - /** * @brief Check if driver is initialized. * From 0efdff96df047e0f0541b0119fe795839cd60dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Tue, 17 Oct 2023 11:00:35 +0200 Subject: [PATCH 3200/4498] nrf_usbd_common: Remove early DMA process handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Early DMA process handling actually decreases performance in real world scenarios because real world scenarios tend to be CPU bound. Moreover the actual optimization is questionable because DMA semaphore can only be released after the respective endpoint end event is handled. Remove early DMA processing altogether and only check pending DMA at the end of interrupt handler. Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 77907bd9244..904c96d9702 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -18,15 +18,6 @@ #include LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); -#ifndef NRF_USBD_COMMON_EARLY_DMA_PROCESS -/* Try to process DMA request when endpoint transmission has been detected - * and just after last EasyDMA has been processed. - * It speeds up the transmission a little (about 10% measured) - * with a cost of more CPU power used. - */ -#define NRF_USBD_COMMON_EARLY_DMA_PROCESS 1 -#endif - #ifndef NRF_USBD_COMMON_STARTED_EV_ENABLE #define NRF_USBD_COMMON_STARTED_EV_ENABLE 0 #endif @@ -988,11 +979,6 @@ static inline void nrf_usbd_epout_dma_handler(nrf_usbd_common_ep_t ep) } else { /* Nothing to do */ } - -#if NRF_USBD_COMMON_EARLY_DMA_PROCESS - /* Speed up */ - usbd_dmareq_process(); -#endif } /** @@ -1247,10 +1233,6 @@ static void ev_epdata_handler(void) (void)(usbd_ep_data_handler(ep, bitpos)); } - if (NRF_USBD_COMMON_EARLY_DMA_PROCESS) { - /* Speed up */ - usbd_dmareq_process(); - } } /** From fc59ed701b030c9b756a7d79f8c330c8651d6e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 19 Oct 2023 09:19:05 +0200 Subject: [PATCH 3201/4498] nrf_usbd_common: Disable started interrupt handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in calling an empty function on every single DMA transfer start. While the empty function is just BX LR the fact that is is called on every DMA transfer makes its impact visible. This change improves CDC ACM echo throughput by approximately 2%. Signed-off-by: Tomasz Moń --- drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 904c96d9702..e024c111dcd 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -18,10 +18,6 @@ #include LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); -#ifndef NRF_USBD_COMMON_STARTED_EV_ENABLE -#define NRF_USBD_COMMON_STARTED_EV_ENABLE 0 -#endif - #ifndef NRF_USBD_COMMON_ISO_DEBUG /* Also generate information about ISOCHRONOUS events and transfers. * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this @@ -806,11 +802,6 @@ static void ev_usbreset_handler(void) static void ev_started_handler(void) { -#if NRF_USBD_COMMON_STARTED_EV_ENABLE - /* Handler not used by the stack. - * May be used for debugging. - */ -#endif } /** @@ -1716,7 +1707,7 @@ void nrf_usbd_common_start(bool enable_sof) __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_POWERED_ON); m_bus_suspend = false; - uint32_t ints_to_enable = NRF_USBD_INT_USBRESET_MASK | NRF_USBD_INT_STARTED_MASK | + uint32_t ints_to_enable = NRF_USBD_INT_USBRESET_MASK | NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | NRF_USBD_INT_ENDEPOUT0_MASK | NRF_USBD_INT_USBEVENT_MASK | NRF_USBD_INT_EP0SETUP_MASK | NRF_USBD_INT_DATAEP_MASK; From 3d523a9cb40c3871e7f4d44eec6f9e5d3e206c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 19 Oct 2023 14:43:32 +0200 Subject: [PATCH 3202/4498] nrf_usbd_common: Refactor interrupt handling code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure strict order within interrupt processing to eliminate workaround in IN transfer acknowledged handler. EPDATASTATUS and DMA done events are processed in a way that eliminates the possibility for race condions between interrupt handler and host IN tokens. Store last started DMA endpoint and use it in common handler for all DMA finished events. Unify use of ep dma waiting variable because atomics only make sense if all accesses are through atomic functions - here the accesses are guarded with critical section. Do not disable SETUP interrupt when DMA transfers data on endpoint 0 but simply postpone handling if currently active DMA is on endpoint 0. Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 423 +++--------------- 1 file changed, 74 insertions(+), 349 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index e024c111dcd..501659b67d5 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -208,13 +208,13 @@ static uint32_t m_ep_ready; /** * @brief Mark endpoint with prepared data to transfer by DMA. * - * This variable can be from any place in the code (interrupt or main thread). + * This variable can be set in interrupt context or within critical section. * It would be cleared only from USBD interrupt. * * Mask prepared USBD data for transmission. * It is cleared when no more data to transmit left. */ -static atomic_t m_ep_dma_waiting; +static uint32_t m_ep_dma_waiting; /* Semaphore to guard EasyDMA access. * In USBD there is only one DMA channel working in background, and new transfer @@ -222,6 +222,9 @@ static atomic_t m_ep_dma_waiting; */ static K_SEM_DEFINE(dma_available, 1, 1); +/* Endpoint on which DMA was started. */ +static nrf_usbd_common_ep_t dma_ep; + /** * @brief Tracks whether total bytes transferred by DMA is even or odd. */ @@ -800,85 +803,8 @@ static void ev_usbreset_handler(void) m_event_handler(&evt); } -static void ev_started_handler(void) -{ -} - -/** - * @brief Handler for EasyDMA event without endpoint clearing. - * - * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. - * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. - * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler. - * - * @param[in] ep Endpoint number. - */ -static inline void nrf_usbd_ep0in_dma_handler(void) +static void nrf_usbd_dma_finished(nrf_usbd_common_ep_t ep) { - const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPIN0; - - LOG_DBG("USB event: DMA ready IN0"); - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - usbd_dma_pending_clear(); - k_sem_give(&dma_available); - - nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); - - usbd_ep_state_t *p_state = ep_state_access(ep); - - if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { - /* Clear transfer information just in case */ - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else if (p_state->handler.feeder == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event without endpoint clearing. - * - * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. - * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. - * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler. - * - * @param[in] ep Endpoint number. - */ -static inline void nrf_usbd_epin_dma_handler(nrf_usbd_common_ep_t ep) -{ - LOG_DBG("USB event: DMA ready IN: %x", ep); - __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); - __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); - __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - usbd_dma_pending_clear(); - k_sem_give(&dma_available); - - usbd_ep_state_t *p_state = ep_state_access(ep); - - if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { - /* Clear transfer information just in case */ - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else if (p_state->handler.feeder == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event from in isochronous endpoint. - */ -static inline void nrf_usbd_epiniso_dma_handler(nrf_usbd_common_ep_t ep) -{ - if (NRF_USBD_COMMON_ISO_DEBUG) { - LOG_DBG("USB event: DMA ready ISOIN: %x", ep); - } - __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep)); - __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); /* DMA finished, track if total bytes transferred is even or odd */ m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; usbd_dma_pending_clear(); @@ -888,194 +814,22 @@ static inline void nrf_usbd_epiniso_dma_handler(nrf_usbd_common_ep_t ep) if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else if (p_state->handler.feeder == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished - * in this moment - */ - NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); - m_event_handler(&evt); - } else { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event for OUT endpoint 0. - * - * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer. - * It cannot be cleared when required transfer is finished because it means the same that accepting - * the comment. - */ -static inline void nrf_usbd_ep0out_dma_handler(void) -{ - const nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPOUT0; - - LOG_DBG("USB event: DMA ready OUT0"); - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - usbd_dma_pending_clear(); - k_sem_give(&dma_available); - - nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); - - usbd_ep_state_t *p_state = ep_state_access(ep); + m_ep_dma_waiting &= ~(1U << ep2bit(ep)); + } else if (!p_state->handler.consumer || !p_state->handler.feeder) { + m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { - /* Clear transfer information just in case */ - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else if (p_state->handler.consumer == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in - * this moment - */ - NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); - m_event_handler(&evt); - } else { + if (NRF_USBD_EPOUT_CHECK(ep) || (ep == NRF_USBD_COMMON_EPIN8)) { + /* Send event to the user - for an ISO IN or any OUT endpoint, + * the whole transfer is finished in this moment + */ + NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); + m_event_handler(&evt); + } + } else if (ep == NRF_USBD_COMMON_EPOUT0) { nrf_usbd_common_setup_data_clear(); } } -/** - * @brief Handler for EasyDMA event from endpoinpoint that requires clearing. - * - * This handler would be called when EasyDMA transfer for OUT endpoint has been finished. - * - * @param[in] ep Endpoint number. - */ -static inline void nrf_usbd_epout_dma_handler(nrf_usbd_common_ep_t ep) -{ - LOG_DBG("DMA ready OUT: %x", ep); - __ASSERT_NO_MSG(NRF_USBD_EPOUT_CHECK(ep)); - __ASSERT_NO_MSG(!NRF_USBD_EPISO_CHECK(ep)); - __ASSERT_NO_MSG(NRF_USBD_EP_NR_GET(ep) > 0); - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - usbd_dma_pending_clear(); - k_sem_give(&dma_available); - - usbd_ep_state_t *p_state = ep_state_access(ep); - - if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { - /* Clear transfer information just in case */ - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } else if (p_state->handler.consumer == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in - * this moment - */ - NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); - m_event_handler(&evt); - } else { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event from out isochronous endpoint. - */ -static inline void nrf_usbd_epoutiso_dma_handler(nrf_usbd_common_ep_t ep) -{ - if (NRF_USBD_COMMON_ISO_DEBUG) { - LOG_DBG("DMA ready ISOOUT: %x", ep); - } - __ASSERT_NO_MSG(NRF_USBD_EPISO_CHECK(ep)); - /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; - usbd_dma_pending_clear(); - k_sem_give(&dma_available); - - usbd_ep_state_t *p_state = ep_state_access(ep); - - if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { - /* Nothing to do - just ignore */ - } else if (p_state->handler.consumer == NULL) { - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in - * this moment - */ - NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OK); - m_event_handler(&evt); - } else { - /* Nothing to do */ - } -} - -static void ev_dma_epin0_handler(void) -{ - nrf_usbd_ep0in_dma_handler(); -} -static void ev_dma_epin1_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN1); -} -static void ev_dma_epin2_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN2); -} -static void ev_dma_epin3_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN3); -} -static void ev_dma_epin4_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN4); -} -static void ev_dma_epin5_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN5); -} -static void ev_dma_epin6_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN6); -} -static void ev_dma_epin7_handler(void) -{ - nrf_usbd_epin_dma_handler(NRF_USBD_COMMON_EPIN7); -} -static void ev_dma_epin8_handler(void) -{ - nrf_usbd_epiniso_dma_handler(NRF_USBD_COMMON_EPIN8); -} - -static void ev_dma_epout0_handler(void) -{ - nrf_usbd_ep0out_dma_handler(); -} -static void ev_dma_epout1_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT1); -} -static void ev_dma_epout2_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT2); -} -static void ev_dma_epout3_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT3); -} -static void ev_dma_epout4_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT4); -} -static void ev_dma_epout5_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT5); -} -static void ev_dma_epout6_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT6); -} -static void ev_dma_epout7_handler(void) -{ - nrf_usbd_epout_dma_handler(NRF_USBD_COMMON_EPOUT7); -} -static void ev_dma_epout8_handler(void) -{ - nrf_usbd_epoutiso_dma_handler(NRF_USBD_COMMON_EPOUT8); -} - static void ev_sof_handler(void) { nrf_usbd_common_evt_t evt = { @@ -1109,21 +863,6 @@ static void usbd_ep_data_handler(nrf_usbd_common_ep_t ep, uint8_t bitpos) if (NRF_USBD_EPIN_CHECK(ep)) { /* IN endpoint (Device -> Host) */ - - /* Secure against the race condition that occurs when an IN transfer is interrupted - * by an OUT transaction, which in turn is interrupted by a process with higher - * priority. If the IN events ENDEPIN and EPDATA arrive during that high priority - * process, the OUT handler might call usbd_ep_data_handler without calling - * nrf_usbd_epin_dma_handler (or nrf_usbd_ep0in_dma_handler) for the IN transaction. - */ - if (nrf_usbd_event_get_and_clear(NRF_USBD, nrf_usbd_common_ep_to_endevent(ep))) { - if (ep != NRF_USBD_COMMON_EPIN0) { - nrf_usbd_epin_dma_handler(ep); - } else { - nrf_usbd_ep0in_dma_handler(); - } - } - if (0 == (m_ep_dma_waiting & (1U << bitpos))) { LOG_DBG("USBD event: EndpointData: In finished"); /* No more data to be send - transmission finished */ @@ -1141,11 +880,6 @@ static void usbd_ep_data_handler(nrf_usbd_common_ep_t ep, uint8_t bitpos) } } -static void ev_setup_data_handler(void) -{ - usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir)); -} - static void ev_setup_handler(void) { LOG_DBG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", @@ -1160,8 +894,8 @@ static void ev_setup_handler(void) ? NRF_USBD_COMMON_EPOUT0 : NRF_USBD_COMMON_EPIN0; - (void)(atomic_and(&m_ep_dma_waiting, ~((1U << ep2bit(NRF_USBD_COMMON_EPOUT0)) | - (1U << ep2bit(NRF_USBD_COMMON_EPIN0))))); + m_ep_dma_waiting &= ~((1U << ep2bit(NRF_USBD_COMMON_EPOUT0)) | + (1U << ep2bit(NRF_USBD_COMMON_EPIN0))); m_ep_ready &= ~(1U << ep2bit(NRF_USBD_COMMON_EPOUT0)); m_ep_ready |= 1U << ep2bit(NRF_USBD_COMMON_EPIN0); @@ -1208,11 +942,8 @@ static void ev_usbevent_handler(void) } } -static void ev_epdata_handler(void) +static void ev_epdata_handler(uint32_t dataepstatus) { - /* Get all endpoints that have acknowledged transfer */ - uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear(NRF_USBD); - LOG_DBG("USBD event: EndpointEPStatus: %x", dataepstatus); /* All finished endpoint have to be marked as busy */ @@ -1323,7 +1054,7 @@ static void usbd_dmareq_process(void) LOG_DBG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size); p_state->status = NRF_USBD_COMMON_EP_OVERLOAD; - (void)(atomic_and(&m_ep_dma_waiting, ~(1U << pos))); + m_ep_dma_waiting &= ~(1U << pos); NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_OVERLOAD); m_event_handler(&evt); @@ -1355,17 +1086,9 @@ static void usbd_dmareq_process(void) nrf_usbd_ep_easydma_set(NRF_USBD, ep, transfer.p_data.addr, (uint32_t)transfer.size); + dma_ep = ep; usbd_dma_start(ep); - /* Do not process SETUP packet until EP0 DMA completes. - * DMA transfer itself will always complete regardless - * of host actions and this action is solely to prevent - * the need to abort active DMA. - */ - if ((ep == NRF_USBD_COMMON_EPOUT0) || (ep == NRF_USBD_COMMON_EPIN0)) { - nrf_usbd_int_disable(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK); - } - /* Transfer started - exit the loop */ return; } @@ -1489,36 +1212,6 @@ static void usbd_enable(void) } /** @} */ -/** - * @brief USBD interrupt service routines. - * - */ -static const nrfx_irq_handler_t m_isr[] = {[USBD_INTEN_USBRESET_Pos] = ev_usbreset_handler, - [USBD_INTEN_STARTED_Pos] = ev_started_handler, - [USBD_INTEN_ENDEPIN0_Pos] = ev_dma_epin0_handler, - [USBD_INTEN_ENDEPIN1_Pos] = ev_dma_epin1_handler, - [USBD_INTEN_ENDEPIN2_Pos] = ev_dma_epin2_handler, - [USBD_INTEN_ENDEPIN3_Pos] = ev_dma_epin3_handler, - [USBD_INTEN_ENDEPIN4_Pos] = ev_dma_epin4_handler, - [USBD_INTEN_ENDEPIN5_Pos] = ev_dma_epin5_handler, - [USBD_INTEN_ENDEPIN6_Pos] = ev_dma_epin6_handler, - [USBD_INTEN_ENDEPIN7_Pos] = ev_dma_epin7_handler, - [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler, - [USBD_INTEN_ENDISOIN_Pos] = ev_dma_epin8_handler, - [USBD_INTEN_ENDEPOUT0_Pos] = ev_dma_epout0_handler, - [USBD_INTEN_ENDEPOUT1_Pos] = ev_dma_epout1_handler, - [USBD_INTEN_ENDEPOUT2_Pos] = ev_dma_epout2_handler, - [USBD_INTEN_ENDEPOUT3_Pos] = ev_dma_epout3_handler, - [USBD_INTEN_ENDEPOUT4_Pos] = ev_dma_epout4_handler, - [USBD_INTEN_ENDEPOUT5_Pos] = ev_dma_epout5_handler, - [USBD_INTEN_ENDEPOUT6_Pos] = ev_dma_epout6_handler, - [USBD_INTEN_ENDEPOUT7_Pos] = ev_dma_epout7_handler, - [USBD_INTEN_ENDISOOUT_Pos] = ev_dma_epout8_handler, - [USBD_INTEN_SOF_Pos] = ev_sof_handler, - [USBD_INTEN_USBEVENT_Pos] = ev_usbevent_handler, - [USBD_INTEN_EP0SETUP_Pos] = ev_setup_handler, - [USBD_INTEN_EPDATA_Pos] = ev_epdata_handler}; - /** * @name Interrupt handlers * @@ -1526,35 +1219,67 @@ static const nrfx_irq_handler_t m_isr[] = {[USBD_INTEN_USBRESET_Pos] = ev_usbres */ void nrf_usbd_common_irq_handler(void) { - const uint32_t enabled = nrf_usbd_int_enable_get(NRF_USBD); - uint32_t to_process = enabled & ~NRF_USBD_INT_EP0SETUP_MASK; - uint32_t active = 0; + uint32_t epdatastatus = 0; - /* Check all enabled interrupts */ - while (to_process) { - uint8_t event_nr = NRF_CTZ(to_process); + /* Clear EPDATA event and only then get and clear EPDATASTATUS to make + * sure we don't miss any event. + */ + if (NRF_USBD->EVENTS_EPDATA) { + NRF_USBD->EVENTS_EPDATA = 0; + epdatastatus = NRF_USBD->EPDATASTATUS; + NRF_USBD->EPDATASTATUS = epdatastatus; + } - if (nrf_usbd_event_get_and_clear( - NRF_USBD, (nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr))) { - active |= 1UL << event_nr; - } - to_process &= ~(1UL << event_nr); + /* Use common variable to store EP0DATADONE processing needed flag */ + if (NRF_USBD->EVENTS_EP0DATADONE) { + NRF_USBD->EVENTS_EP0DATADONE = 0; + epdatastatus |= BIT(ep2bit(m_last_setup_dir)); } - /* Process the active interrupts */ - while (active) { - uint8_t event_nr = NRF_CTZ(active); + /* Check DMA end event only for last enabled DMA channel. Other channels + * cannot be active and there's no harm in rechecking the event multiple + * times (it is not a problem to check it even if DMA is not active). + * + * It is important to check DMA and handle DMA finished event before + * handling acknowledged data transfer bits (epdatastatus) to avoid + * a race condition between interrupt handler and host IN token. + */ + if (nrf_usbd_event_get_and_clear(NRF_USBD, nrf_usbd_common_ep_to_endevent(dma_ep))) { + nrf_usbd_dma_finished(dma_ep); + } + + /* Process acknowledged transfers so we can prepare next DMA (if any) */ + ev_epdata_handler(epdatastatus); - m_isr[event_nr](); - active &= ~(1UL << event_nr); + if (NRF_USBD->EVENTS_USBRESET) { + NRF_USBD->EVENTS_USBRESET = 0; + ev_usbreset_handler(); + } + + /* Always check and clear SOF but call handler only if SOF interrupt + * is actually enabled. + */ + if (NRF_USBD->EVENTS_SOF) { + NRF_USBD->EVENTS_SOF = 0; + if (NRF_USBD->INTENSET & USBD_INTEN_SOF_Msk) { + ev_sof_handler(); + } + } + + if (NRF_USBD->EVENTS_USBEVENT) { + NRF_USBD->EVENTS_USBEVENT = 0; + ev_usbevent_handler(); } - usbd_dmareq_process(); /* Handle SETUP only if there is no active DMA on EP0 */ - if (nrf_usbd_int_enable_check(NRF_USBD, NRF_USBD_INT_EP0SETUP_MASK) && - nrf_usbd_event_get_and_clear(NRF_USBD, NRF_USBD_EVENT_EP0SETUP)) { - m_isr[USBD_INTEN_EP0SETUP_Pos](); + if (unlikely(NRF_USBD->EVENTS_EP0SETUP) && + (k_sem_count_get(&dma_available) || + (dma_ep != NRF_USBD_COMMON_EPIN0 && dma_ep != NRF_USBD_COMMON_EPOUT0))) { + NRF_USBD->EVENTS_EP0SETUP = 0; + ev_setup_handler(); } + + usbd_dmareq_process(); } /** @} */ From 3e6b86ff732b794b0fe1e7d09755a5eee2491904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 2 Nov 2023 11:13:43 +0100 Subject: [PATCH 3203/4498] nrf_usbd_common: Keep interrupt configuration constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not enable nor disable endpoint done interrupts at runtime because it is not necessary. Simply keep all relevant interrupts enabled when USBD is active and disable all interrupts when USBD is disabled. Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 81 ++++--------------- .../common/nrf_usbd_common/nrf_usbd_common.h | 24 ------ 2 files changed, 15 insertions(+), 90 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 501659b67d5..377fe14857b 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -178,16 +178,6 @@ static nrf_usbd_common_event_handler_t m_event_handler; */ static volatile bool m_bus_suspend; -/** - * @brief Internal constant that contains interrupts disabled in suspend state. - * - * Internal constant used in @ref nrf_usbd_common_suspend_irq_config and - * @ref nrf_usbd_common_active_irq_config functions. - */ -static const uint32_t m_irq_disabled_in_suspend = - NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | NRF_USBD_INT_ENDEPOUT0_MASK | - NRF_USBD_INT_EP0SETUP_MASK | NRF_USBD_INT_DATAEP_MASK; - /** * @brief Direction of last received Setup transfer. * @@ -331,31 +321,6 @@ static inline nrf_usbd_event_t nrf_usbd_common_ep_to_endevent(nrf_usbd_common_ep return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; } -/** - * @brief Get interrupt mask for selected endpoint. - * - * @param[in] ep Endpoint number. - * - * @return Interrupt mask related to the EasyDMA transfer end for the - * chosen endpoint. - */ -static inline uint32_t nrf_usbd_common_ep_to_int(nrf_usbd_common_ep_t ep) -{ - NRF_USBD_COMMON_ASSERT_EP_VALID(ep); - - static const uint8_t epin_bitpos[] = { - USBD_INTEN_ENDEPIN0_Pos, USBD_INTEN_ENDEPIN1_Pos, USBD_INTEN_ENDEPIN2_Pos, - USBD_INTEN_ENDEPIN3_Pos, USBD_INTEN_ENDEPIN4_Pos, USBD_INTEN_ENDEPIN5_Pos, - USBD_INTEN_ENDEPIN6_Pos, USBD_INTEN_ENDEPIN7_Pos, USBD_INTEN_ENDISOIN_Pos}; - static const uint8_t epout_bitpos[] = { - USBD_INTEN_ENDEPOUT0_Pos, USBD_INTEN_ENDEPOUT1_Pos, USBD_INTEN_ENDEPOUT2_Pos, - USBD_INTEN_ENDEPOUT3_Pos, USBD_INTEN_ENDEPOUT4_Pos, USBD_INTEN_ENDEPOUT5_Pos, - USBD_INTEN_ENDEPOUT6_Pos, USBD_INTEN_ENDEPOUT7_Pos, USBD_INTEN_ENDISOOUT_Pos}; - - return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos - : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)]; -} - /** * @name Integrated feeders and consumers * @@ -1403,7 +1368,6 @@ void nrf_usbd_common_disable(void) nrf_usbd_common_stop(); /* Disable all parts */ - nrf_usbd_int_disable(NRF_USBD, nrf_usbd_int_enable_get(NRF_USBD)); if (m_dma_odd) { /* Prevent invalid bus request after next USBD enable by ensuring * that total number of bytes transferred by DMA is even. @@ -1432,17 +1396,25 @@ void nrf_usbd_common_start(bool enable_sof) __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_POWERED_ON); m_bus_suspend = false; - uint32_t ints_to_enable = NRF_USBD_INT_USBRESET_MASK | - NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_EP0DATADONE_MASK | - NRF_USBD_INT_ENDEPOUT0_MASK | NRF_USBD_INT_USBEVENT_MASK | - NRF_USBD_INT_EP0SETUP_MASK | NRF_USBD_INT_DATAEP_MASK; + uint32_t int_mask = USBD_INTEN_USBRESET_Msk | USBD_INTEN_ENDEPIN0_Msk | + USBD_INTEN_ENDEPIN1_Msk | USBD_INTEN_ENDEPIN2_Msk | + USBD_INTEN_ENDEPIN3_Msk | USBD_INTEN_ENDEPIN4_Msk | + USBD_INTEN_ENDEPIN5_Msk | USBD_INTEN_ENDEPIN6_Msk | + USBD_INTEN_ENDEPIN7_Msk | USBD_INTEN_EP0DATADONE_Msk | + USBD_INTEN_ENDISOIN_Msk | USBD_INTEN_ENDEPOUT0_Msk | + USBD_INTEN_ENDEPOUT1_Msk | USBD_INTEN_ENDEPOUT2_Msk | + USBD_INTEN_ENDEPOUT3_Msk | USBD_INTEN_ENDEPOUT4_Msk | + USBD_INTEN_ENDEPOUT5_Msk | USBD_INTEN_ENDEPOUT6_Msk | + USBD_INTEN_ENDEPOUT7_Msk | USBD_INTEN_ENDISOOUT_Msk | + USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EP0SETUP_Msk | + USBD_INTEN_EPDATA_Msk; if (enable_sof) { - ints_to_enable |= NRF_USBD_INT_SOF_MASK; + int_mask |= USBD_INTEN_SOF_Msk; } /* Enable all required interrupts */ - nrf_usbd_int_enable(NRF_USBD, ints_to_enable); + NRF_USBD->INTEN = int_mask; /* Enable interrupt globally */ irq_enable(USBD_IRQn); @@ -1469,7 +1441,7 @@ static void nrf_usbd_common_stop(void) irq_disable(USBD_IRQn); /* Disable all interrupts */ - nrf_usbd_int_disable(NRF_USBD, ~0U); + NRF_USBD->INTEN = 0; } } @@ -1539,16 +1511,6 @@ bool nrf_usbd_common_suspend_check(void) return nrf_usbd_lowpower_check(NRF_USBD); } -void nrf_usbd_common_suspend_irq_config(void) -{ - nrf_usbd_int_disable(NRF_USBD, m_irq_disabled_in_suspend); -} - -void nrf_usbd_common_active_irq_config(void) -{ - nrf_usbd_int_enable(NRF_USBD, m_irq_disabled_in_suspend); -} - bool nrf_usbd_common_bus_suspend_check(void) { return m_bus_suspend; @@ -1588,8 +1550,6 @@ bool nrf_usbd_common_ep_enable_check(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep) { - nrf_usbd_int_enable(NRF_USBD, nrf_usbd_common_ep_to_int(ep)); - if (nrf_usbd_ep_enable_check(NRF_USBD, ep)) { return; } @@ -1611,7 +1571,6 @@ void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) k_sem_take(&dma_available, K_FOREVER); usbd_ep_abort(ep); nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep)); - nrf_usbd_int_disable(NRF_USBD, nrf_usbd_common_ep_to_int(ep)); k_sem_give(&dma_available); /* This function was holding DMA semaphore and could potentially prevent @@ -1623,16 +1582,6 @@ void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_default_config(void) { - nrf_usbd_int_disable(NRF_USBD, - NRF_USBD_INT_ENDEPIN1_MASK | NRF_USBD_INT_ENDEPIN2_MASK | - NRF_USBD_INT_ENDEPIN3_MASK | NRF_USBD_INT_ENDEPIN4_MASK | - NRF_USBD_INT_ENDEPIN5_MASK | NRF_USBD_INT_ENDEPIN6_MASK | - NRF_USBD_INT_ENDEPIN7_MASK | NRF_USBD_INT_ENDISOIN0_MASK | - NRF_USBD_INT_ENDEPOUT1_MASK | NRF_USBD_INT_ENDEPOUT2_MASK | - NRF_USBD_INT_ENDEPOUT3_MASK | NRF_USBD_INT_ENDEPOUT4_MASK | - NRF_USBD_INT_ENDEPOUT5_MASK | NRF_USBD_INT_ENDEPOUT6_MASK | - NRF_USBD_INT_ENDEPOUT7_MASK | NRF_USBD_INT_ENDISOOUT0_MASK); - nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK); nrf_usbd_ep_default_config(NRF_USBD); } diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h index 328a8e7dd2b..d559387fd4a 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h @@ -495,30 +495,6 @@ bool nrf_usbd_common_wakeup_req(void); */ bool nrf_usbd_common_suspend_check(void); -/** - * @brief Enable only interrupts that should be processed in SUSPEND mode. - * - * Auxiliary function to help with SUSPEND mode integration. - * It enables only the interrupts that can be properly processed without stable HFCLK. - * - * Normally all the interrupts are enabled. - * Use this function to suspend interrupt processing that may require stable HFCLK until the - * clock is enabled. - * - * @sa nrf_usbd_common_active_irq_config - */ -void nrf_usbd_common_suspend_irq_config(void); - -/** - * @brief Default active interrupt configuration. - * - * Default interrupt configuration. - * Use in a pair with @ref nrf_usbd_common_active_irq_config. - * - * @sa nrf_usbd_common_suspend_irq_config - */ -void nrf_usbd_common_active_irq_config(void); - /** * @brief Check the bus state. * From f533ec16e64813d08c3ed5b57932fda4f44a704b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 2 Nov 2023 14:35:53 +0100 Subject: [PATCH 3204/4498] nrf_usbd_common: Remove dynamic feeders/consumers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in setting the feeder or consumer at runtime. The time saved due to not checking conditions on each transaction is smaller than the additional cost of calling function via pointer. Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 340 ++---------------- .../common/nrf_usbd_common/nrf_usbd_common.h | 118 ------ 2 files changed, 39 insertions(+), 419 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 377fe14857b..30b0494da91 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -233,10 +233,8 @@ static bool m_first_enable = true; * buffer is ready. */ typedef struct { - /** Handler for current transfer, function pointer. */ - nrf_usbd_common_handler_t handler; - /** Context for transfer handler. */ - void *p_context; + nrf_usbd_common_transfer_t transfer_state; + bool more_transactions; /** Number of transferred bytes in the current transfer. */ size_t transfer_cnt; /** Configured endpoint size. */ @@ -255,29 +253,7 @@ static struct { usbd_ep_state_t ep_in[NRF_USBD_EPIN_CNT]; /*!< Status for IN endpoints. */ } m_ep_state; -/** - * @brief Status variables for integrated feeders. - * - * Current status for integrated feeders (IN transfers). - * Integrated feeders are used for default transfers: - * 1. Simple RAM transfer. - * 2. Simple flash transfer. - * 3. RAM transfer with automatic ZLP. - * 4. Flash transfer with automatic ZLP. - */ -nrf_usbd_common_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; - -/** - * @brief Status variables for integrated consumers. - * - * Current status for integrated consumers. - * Currently one type of transfer is supported: - * 1. Transfer to RAM. - * - * Transfer is finished automatically when received data block is smaller - * than the endpoint buffer or all the required data is received. - */ -nrf_usbd_common_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; +#define NRF_USBD_COMMON_FEEDER_BUFFER_SIZE NRF_USBD_COMMON_EPSIZE /** * @brief Buffer used to send data directly from FLASH. @@ -321,29 +297,10 @@ static inline nrf_usbd_event_t nrf_usbd_common_ep_to_endevent(nrf_usbd_common_ep return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; } -/** - * @name Integrated feeders and consumers - * - * Internal, default functions for transfer processing. - * @{ - */ - -/** - * @brief Integrated consumer to RAM buffer. - * - * @param p_next See @ref nrf_usbd_common_consumer_t documentation. - * @param p_context See @ref nrf_usbd_common_consumer_t documentation. - * @param ep_size See @ref nrf_usbd_common_consumer_t documentation. - * @param data_size See @ref nrf_usbd_common_consumer_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_usbd_common_consumer(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, - size_t ep_size, size_t data_size) +static bool nrf_usbd_common_consumer(nrf_usbd_common_ep_transfer_t *p_next, + nrf_usbd_common_transfer_t *p_transfer, + size_t ep_size, size_t data_size) { - nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - __ASSERT_NO_MSG(ep_size >= data_size); __ASSERT_NO_MSG((p_transfer->p_data.rx == NULL) || nrfx_is_in_ram(p_transfer->p_data.rx)); @@ -364,53 +321,10 @@ bool nrf_usbd_common_consumer(nrf_usbd_common_ep_transfer_t *p_next, void *p_con return (ep_size == data_size) && (size != 0); } -/** - * @brief Integrated feeder from RAM source. - * - * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. - * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_usbd_common_feeder_ram(nrf_usbd_common_ep_transfer_t *p_next, - void *p_context, size_t ep_size) -{ - nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - - __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); - - size_t tx_size = p_transfer->size; - - if (tx_size > ep_size) { - tx_size = ep_size; - } - - p_next->p_data = p_transfer->p_data; - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.addr += tx_size; - - return (p_transfer->size != 0); -} - -/** - * @brief Integrated feeder from RAM source with ZLP. - * - * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. - * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_usbd_common_feeder_ram_zlp(nrf_usbd_common_ep_transfer_t *p_next, - void *p_context, size_t ep_size) +static bool nrf_usbd_common_feeder(nrf_usbd_common_ep_transfer_t *p_next, + nrf_usbd_common_transfer_t *p_transfer, + size_t ep_size) { - nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); size_t tx_size = p_transfer->size; @@ -419,93 +333,26 @@ bool nrf_usbd_common_feeder_ram_zlp(nrf_usbd_common_ep_transfer_t *p_next, tx_size = ep_size; } - p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx; - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.addr += tx_size; - - return (tx_size != 0); -} - -/** - * @brief Integrated feeder from a flash source. - * - * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. - * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_usbd_common_feeder_flash(nrf_usbd_common_ep_transfer_t *p_next, - void *p_context, size_t ep_size) -{ - nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - - __ASSERT_NO_MSG(!nrfx_is_in_ram(p_transfer->p_data.tx)); - - size_t tx_size = p_transfer->size; - void *p_buffer = nrf_usbd_common_feeder_buffer_get(); - - if (tx_size > ep_size) { - tx_size = ep_size; + if (!nrfx_is_in_ram(p_transfer->p_data.tx)) { + __ASSERT_NO_MSG(tx_size <= NRF_USBD_COMMON_FEEDER_BUFFER_SIZE); + memcpy(m_tx_buffer, (p_transfer->p_data.tx), tx_size); + p_next->p_data.tx = m_tx_buffer; + } else { + p_next->p_data = p_transfer->p_data; } - __ASSERT_NO_MSG(tx_size <= NRF_USBD_COMMON_FEEDER_BUFFER_SIZE); - memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); - - p_next->p_data.tx = p_buffer; p_next->size = tx_size; p_transfer->size -= tx_size; p_transfer->p_data.addr += tx_size; - return (p_transfer->size != 0); -} - -/** - * @brief Integrated feeder from a flash source with ZLP. - * - * @param[out] p_next See @ref nrf_usbd_common_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_usbd_common_feeder_t documentation. - * @param[in] ep_size See @ref nrf_usbd_common_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_usbd_common_feeder_flash_zlp(nrf_usbd_common_ep_transfer_t *p_next, - void *p_context, size_t ep_size) -{ - nrf_usbd_common_transfer_t *p_transfer = (nrf_usbd_common_transfer_t *)p_context; - - __ASSERT_NO_MSG(!nrfx_is_in_ram(p_transfer->p_data.tx)); - - size_t tx_size = p_transfer->size; - void *p_buffer = nrf_usbd_common_feeder_buffer_get(); - - if (tx_size > ep_size) { - tx_size = ep_size; - } - - __ASSERT_NO_MSG(tx_size <= NRF_USBD_COMMON_FEEDER_BUFFER_SIZE); - - if (tx_size != 0) { - memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); - p_next->p_data.tx = p_buffer; + if (p_transfer->flags & NRF_USBD_COMMON_TRANSFER_ZLP_FLAG) { + return (tx_size != 0); } else { - p_next->p_data.tx = NULL; + return (p_transfer->size != 0); } - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.addr += tx_size; - - return (tx_size != 0); } -/** @} */ - /** * @brief Change Driver endpoint number to HAL endpoint number. * @@ -664,7 +511,7 @@ static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) */ nrf_usbd_common_transfer_out_drop(ep); } else { - p_state->handler.consumer = NULL; + p_state->more_transactions = false; m_ep_dma_waiting &= ~(1U << ep2bit(ep)); m_ep_ready &= ~(1U << ep2bit(ep)); } @@ -695,7 +542,7 @@ static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) m_ep_dma_waiting &= ~(1U << ep2bit(ep)); m_ep_ready |= 1U << ep2bit(ep); - p_state->handler.feeder = NULL; + p_state->more_transactions = false; p_state->status = NRF_USBD_COMMON_EP_ABORTED; NRF_USBD_COMMON_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_COMMON_EP_ABORTED); m_event_handler(&evt); @@ -780,7 +627,7 @@ static void nrf_usbd_dma_finished(nrf_usbd_common_ep_t ep) if (p_state->status == NRF_USBD_COMMON_EP_ABORTED) { /* Clear transfer information just in case */ m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - } else if (!p_state->handler.consumer || !p_state->handler.feeder) { + } else if (!p_state->more_transactions) { m_ep_dma_waiting &= ~(1U << ep2bit(ep)); if (NRF_USBD_EPOUT_CHECK(ep) || (ep == NRF_USBD_COMMON_EPIN8)) { @@ -991,26 +838,20 @@ static void usbd_dmareq_process(void) nrf_usbd_common_ep_transfer_t transfer; bool continue_transfer; - BUILD_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) == - offsetof(usbd_ep_state_t, handler.consumer), - "feeder and consumer must be in union"); - __ASSERT_NO_MSG((p_state->handler.feeder) != NULL); + __ASSERT_NO_MSG(p_state->more_transactions); if (NRF_USBD_EPIN_CHECK(ep)) { /* Device -> Host */ - continue_transfer = p_state->handler.feeder( - &transfer, p_state->p_context, p_state->max_packet_size); - - if (!continue_transfer) { - p_state->handler.feeder = NULL; - } + continue_transfer = nrf_usbd_common_feeder( + &transfer, &p_state->transfer_state, + p_state->max_packet_size); } else { /* Host -> Device */ const size_t rx_size = nrf_usbd_common_epout_size_get(ep); - continue_transfer = p_state->handler.consumer( - &transfer, p_state->p_context, p_state->max_packet_size, - rx_size); + continue_transfer = nrf_usbd_common_consumer( + &transfer, &p_state->transfer_state, + p_state->max_packet_size, rx_size); if (transfer.p_data.rx == NULL) { /* Dropping transfer - allow processing */ @@ -1033,10 +874,10 @@ static void usbd_dmareq_process(void) */ __ASSERT_NO_MSG(transfer.size == rx_size); } + } - if (!continue_transfer) { - p_state->handler.consumer = NULL; - } + if (!continue_transfer) { + p_state->more_transactions = false; } usbd_dma_pending_set(); @@ -1271,7 +1112,7 @@ nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler) usbd_ep_state_t *p_state = ep_state_access(ep); p_state->status = NRF_USBD_COMMON_EP_OK; - p_state->handler.feeder = NULL; + p_state->more_transactions = false; p_state->transfer_cnt = 0; } for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n) { @@ -1282,7 +1123,7 @@ nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler) usbd_ep_state_t *p_state = ep_state_access(ep); p_state->status = NRF_USBD_COMMON_EP_OK; - p_state->handler.consumer = NULL; + p_state->more_transactions = false; p_state->transfer_cnt = 0; } @@ -1611,115 +1452,17 @@ nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, } } else { usbd_ep_state_t *p_state = ep_state_access(ep); - /* Prepare transfer context and handler description */ - nrf_usbd_common_transfer_t *p_context; - - if (NRF_USBD_EPIN_CHECK(ep)) { - p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep); - if (nrfx_is_in_ram(p_transfer->p_data.tx)) { - /* RAM */ - if (0 == (p_transfer->flags & NRF_USBD_COMMON_TRANSFER_ZLP_FLAG)) { - p_state->handler.feeder = nrf_usbd_common_feeder_ram; - if (NRF_USBD_COMMON_ISO_DEBUG || - (!NRF_USBD_EPISO_CHECK(ep))) { - LOG_DBG("Transfer called on endpoint %x, " - "size: %u, mode: " - "RAM", - ep, p_transfer->size); - } - } else { - p_state->handler.feeder = nrf_usbd_common_feeder_ram_zlp; - if (NRF_USBD_COMMON_ISO_DEBUG || - (!NRF_USBD_EPISO_CHECK(ep))) { - LOG_DBG("Transfer called on endpoint %x, " - "size: %u, mode: " - "RAM_ZLP", - ep, p_transfer->size); - } - } - } else { - /* Flash */ - if (0 == (p_transfer->flags & NRF_USBD_COMMON_TRANSFER_ZLP_FLAG)) { - p_state->handler.feeder = nrf_usbd_common_feeder_flash; - if (NRF_USBD_COMMON_ISO_DEBUG || - (!NRF_USBD_EPISO_CHECK(ep))) { - LOG_DBG("Transfer called on endpoint %x, " - "size: %u, mode: " - "FLASH", - ep, p_transfer->size); - } - } else { - p_state->handler.feeder = nrf_usbd_common_feeder_flash_zlp; - if (NRF_USBD_COMMON_ISO_DEBUG || - (!NRF_USBD_EPISO_CHECK(ep))) { - LOG_DBG("Transfer called on endpoint %x, " - "size: %u, mode: " - "FLASH_ZLP", - ep, p_transfer->size); - } - } - } - } else { - p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep); - __ASSERT_NO_MSG((p_transfer->p_data.rx == NULL) || - (nrfx_is_in_ram(p_transfer->p_data.rx))); - p_state->handler.consumer = nrf_usbd_common_consumer; - } - *p_context = *p_transfer; - p_state->p_context = p_context; - p_state->transfer_cnt = 0; - p_state->status = NRF_USBD_COMMON_EP_OK; - m_ep_dma_waiting |= 1U << ep_bitpos; - ret = NRFX_SUCCESS; - usbd_int_rise(); - } - - irq_unlock(irq_lock_key); - - return ret; -} - -nrfx_err_t nrf_usbd_common_ep_handled_transfer(nrf_usbd_common_ep_t ep, - nrf_usbd_common_handler_desc_t const *p_handler) -{ - nrfx_err_t ret; - const uint8_t ep_bitpos = ep2bit(ep); - unsigned int irq_lock_key = irq_lock(); - - __ASSERT_NO_MSG(p_handler != NULL); - - /* Setup data transaction can go only in one direction at a time */ - if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { - ret = NRFX_ERROR_INVALID_ADDR; - if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && - (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { - LOG_DBG("Transfer failed: Invalid EP"); - } - } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & - (1U << ep_bitpos)) { - /* IN (Device -> Host) transfer has to be transmitted out to allow a new - * transmission - */ - ret = NRFX_ERROR_BUSY; - if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && - (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { - LOG_DBG("Transfer failed: EP is busy"); - } - } else { - /* Transfer can be configured now */ - usbd_ep_state_t *p_state = ep_state_access(ep); + __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep) || + (p_transfer->p_data.rx == NULL) || + (nrfx_is_in_ram(p_transfer->p_data.rx))); + p_state->more_transactions = true; + p_state->transfer_state = *p_transfer; p_state->transfer_cnt = 0; - p_state->handler = p_handler->handler; - p_state->p_context = p_handler->p_context; p_state->status = NRF_USBD_COMMON_EP_OK; m_ep_dma_waiting |= 1U << ep_bitpos; - ret = NRFX_SUCCESS; - if (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { - LOG_DBG("Transfer called on endpoint %x, mode: Handler", ep); - } usbd_int_rise(); } @@ -1728,11 +1471,6 @@ nrfx_err_t nrf_usbd_common_ep_handled_transfer(nrf_usbd_common_ep_t ep, return ret; } -void *nrf_usbd_common_feeder_buffer_get(void) -{ - return m_tx_buffer; -} - nrf_usbd_common_ep_status_t nrf_usbd_common_ep_status_get(nrf_usbd_common_ep_t ep, size_t *p_size) { nrf_usbd_common_ep_status_t ret; @@ -1740,7 +1478,7 @@ nrf_usbd_common_ep_status_t nrf_usbd_common_ep_status_get(nrf_usbd_common_ep_t e unsigned int irq_lock_key = irq_lock(); *p_size = p_state->transfer_cnt; - ret = (p_state->handler.consumer == NULL) ? p_state->status : NRF_USBD_COMMON_EP_BUSY; + ret = (!p_state->more_transactions) ? p_state->status : NRF_USBD_COMMON_EP_BUSY; irq_unlock(irq_lock_key); diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h index d559387fd4a..ac4149f3c42 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h @@ -41,13 +41,6 @@ extern "C" { */ #define NRF_USBD_COMMON_ISOSIZE 1023 -/** - * @brief The size of internal feeder buffer. - * - * @sa nrf_usbd_common_feeder_buffer_get - */ -#define NRF_USBD_COMMON_FEEDER_BUFFER_SIZE NRF_USBD_COMMON_EPSIZE - /** * @name Macros for creating endpoint identifiers. * @@ -266,82 +259,6 @@ typedef struct { const nrf_usbd_common_transfer_t name = { \ .p_data = {.rx = (rx_buff)}, .size = (rx_size), .flags = 0} -/** - * @brief USBD transfer feeder. - * - * Pointer for a transfer feeder. - * Transfer feeder is a feedback function used to prepare a single - * TX (Device->Host) endpoint transfer. - * - * The transfers provided by the feeder must be simple: - * - The size of the transfer provided by this function is limited to a single endpoint buffer. - * Bigger transfers are not handled automatically in this case. - * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before. - * - * @note - * This function may use @ref nrf_usbd_common_feeder_buffer_get to gain a temporary buffer - * that can be used to prepare transfer. - * - * @param[out] p_next Structure with the data for the next transfer to be filled. - * Required only if the function returns true. - * @param[in,out] p_context Context variable configured with the transfer. - * @param[in] ep_size The endpoint size. - * - * @retval false The current transfer is the last one - you do not need to call - * the function again. - * @retval true There is more data to be prepared and when the current transfer - * finishes, the feeder function is expected to be called again. - */ -typedef bool (*nrf_usbd_common_feeder_t)(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, - size_t ep_size); - -/** - * @brief USBD transfer consumer. - * - * Pointer for a transfer consumer. - * Transfer consumer is a feedback function used to prepare a single - * RX (Host->Device) endpoint transfer. - * - * The transfer must provide a buffer big enough to fit the whole data from the endpoint. - * Otherwise, the NRF_USBD_COMMON_EP_OVERLOAD event is generated. - * - * @param[out] p_next Structure with the data for the next transfer to be filled. - * Required only if the function returns true. - * @param[in,out] p_context Context variable configured with the transfer. - * @param[in] ep_size The endpoint size. - * @param[in] data_size Number of received bytes in the endpoint buffer. - * - * @retval false Current transfer is the last one - you do not need to call - * the function again. - * @retval true There is more data to be prepared and when current transfer - * finishes, the feeder function is expected to be called again. - */ -typedef bool (*nrf_usbd_common_consumer_t)(nrf_usbd_common_ep_transfer_t *p_next, void *p_context, - size_t ep_size, size_t data_size); - -/** - * @brief Universal transfer handler. - * - * Union with feeder and consumer function pointer. - */ -typedef union { - nrf_usbd_common_feeder_t feeder; /*!< Feeder function pointer. */ - nrf_usbd_common_consumer_t consumer; /*!< Consumer function pointer. */ -} nrf_usbd_common_handler_t; - -/** - * @brief USBD transfer descriptor. - * - * Universal structure that may hold the setup for callback configuration for - * IN or OUT type of the transfer. - */ -typedef struct { - /** Handler for the current transfer, function pointer. */ - nrf_usbd_common_handler_t handler; - /** Context for the transfer handler. */ - void *p_context; -} nrf_usbd_common_handler_desc_t; - /** * @brief Setup packet structure. * @@ -601,41 +518,6 @@ void nrf_usbd_common_ep_default_config(void); nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, nrf_usbd_common_transfer_t const *p_transfer); -/** - * @brief Start sending data over the endpoint using the transfer handler function. - * - * This function initializes an endpoint transmission. - * Just before data is transmitted, the transfer handler - * is called and it prepares a data chunk. - * - * @param[in] ep Endpoint number. - * For an IN endpoint, sending is initiated. - * For an OUT endpoint, receiving is initiated. - * @param[in] p_handler Transfer handler - feeder for IN direction and consumer for - * OUT direction. - * - * @retval NRFX_SUCCESS Transfer queued or started. - * @retval NRFX_ERROR_BUSY Selected endpoint is pending. - * @retval NRFX_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. - */ -nrfx_err_t nrf_usbd_common_ep_handled_transfer(nrf_usbd_common_ep_t ep, - nrf_usbd_common_handler_desc_t const *p_handler); - -/** - * @brief Get the temporary buffer to be used by the feeder. - * - * This buffer is used for TX transfers and it can be reused automatically - * when the transfer is finished. - * Use it for transfer preparation. - * - * May be used inside the feeder configured in @ref nrf_usbd_common_ep_handled_transfer. - * - * @return Pointer to the buffer that can be used temporarily. - * - * @sa NRF_USBD_COMMON_FEEDER_BUFFER_SIZE - */ -void *nrf_usbd_common_feeder_buffer_get(void); - /** * @brief Get the information about last finished or current transfer. * From f2c804b46eea29308d08a3f6d2f97f1cca58e6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 3 Nov 2023 09:40:30 +0100 Subject: [PATCH 3205/4498] nrf_usbd_common: Do not use USBD HAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use MDK directly instead of via USBD HAL to not mix direct register accesses with USBD HAL. In my opinion this change is not really necessary but reviewers are strict about consistency. Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common.c | 406 ++++++++++-------- .../common/nrf_usbd_common/nrf_usbd_common.h | 50 +-- 2 files changed, 252 insertions(+), 204 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 30b0494da91..9045e1ded70 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -18,6 +18,13 @@ #include LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); +#define NRF_USBD_COMMON_EPIN_CNT 9 +#define NRF_USBD_COMMON_EPOUT_CNT 9 +#define NRF_USBD_COMMON_EP_NUM(ep) (ep & 0xF) +#define NRF_USBD_COMMON_EP_IS_IN(ep) ((ep & 0x80) == 0x80) +#define NRF_USBD_COMMON_EP_IS_OUT(ep) ((ep & 0x80) == 0) +#define NRF_USBD_COMMON_EP_IS_ISO(ep) ((ep & 0xF) >= 8) + #ifndef NRF_USBD_COMMON_ISO_DEBUG /* Also generate information about ISOCHRONOUS events and transfers. * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this @@ -68,9 +75,11 @@ LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); * * @param ep Endpoint number to validity check. */ -#define NRF_USBD_COMMON_ASSERT_EP_VALID(ep) __ASSERT_NO_MSG( \ - ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) || \ - (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)))); +#define NRF_USBD_COMMON_ASSERT_EP_VALID(ep) __ASSERT_NO_MSG( \ + ((NRF_USBD_COMMON_EP_IS_IN(ep) && \ + (NRF_USBD_COMMON_EP_NUM(ep) < NRF_USBD_COMMON_EPIN_CNT)) || \ + (NRF_USBD_COMMON_EP_IS_OUT(ep) && \ + (NRF_USBD_COMMON_EP_NUM(ep) < NRF_USBD_COMMON_EPOUT_CNT)))); /** * @brief Lowest position of bit for IN endpoint. @@ -114,9 +123,9 @@ LOG_MODULE_REGISTER(nrf_usbd_common, CONFIG_NRF_USBD_COMMON_LOG_LEVEL); * @param[in] ep Endpoint number. * @return Endpoint bit position. */ -#define NRF_USBD_COMMON_EP_BITPOS(ep) \ - ((NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_COMMON_EPIN_BITPOS_0 : NRF_USBD_COMMON_EPOUT_BITPOS_0)\ - + NRF_USBD_EP_NR_GET(ep)) +#define NRF_USBD_COMMON_EP_BITPOS(ep) ((NRF_USBD_COMMON_EP_IS_IN(ep) \ + ? NRF_USBD_COMMON_EPIN_BITPOS_0 : NRF_USBD_COMMON_EPOUT_BITPOS_0) \ + + NRF_USBD_COMMON_EP_NUM(ep)) /** * @brief Helper macro for creating an endpoint transfer event. @@ -249,8 +258,8 @@ typedef struct { * The status of the transfer on each endpoint. */ static struct { - usbd_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; /*!< Status for OUT endpoints. */ - usbd_ep_state_t ep_in[NRF_USBD_EPIN_CNT]; /*!< Status for IN endpoints. */ + usbd_ep_state_t ep_out[NRF_USBD_COMMON_EPOUT_CNT]; /*!< Status for OUT endpoints. */ + usbd_ep_state_t ep_in[NRF_USBD_COMMON_EPIN_CNT]; /*!< Status for IN endpoints. */ } m_ep_state; #define NRF_USBD_COMMON_FEEDER_BUFFER_SIZE NRF_USBD_COMMON_EPSIZE @@ -272,29 +281,71 @@ static void usbd_dmareq_process(void); static inline void usbd_int_rise(void); static void nrf_usbd_common_stop(void); -/** - * @brief Change endpoint number to endpoint event code. - * - * @param ep Endpoint number. - * - * @return Connected endpoint event code. - * - * Marker to delete when not required anymore: >> NRF_USBD_COMMON_ERRATA_ENABLE <<. - */ -static inline nrf_usbd_event_t nrf_usbd_common_ep_to_endevent(nrf_usbd_common_ep_t ep) +/* Get EasyDMA end event address for given endpoint */ +static volatile uint32_t *usbd_ep_to_endevent(nrf_usbd_common_ep_t ep) +{ + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); + + if (!NRF_USBD_COMMON_EP_IS_ISO(ep_num)) { + if (ep_in) { + return &NRF_USBD->EVENTS_ENDEPIN[ep_num]; + } else { + return &NRF_USBD->EVENTS_ENDEPOUT[ep_num]; + } + } + + return ep_in ? &NRF_USBD->EVENTS_ENDISOIN : &NRF_USBD->EVENTS_ENDISOOUT; +} + +/* Return number of bytes last transferred by EasyDMA on given endpoint */ +static uint32_t usbd_ep_amount_get(nrf_usbd_common_ep_t ep) { + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); - static const nrf_usbd_event_t epin_endev[] = { - NRF_USBD_EVENT_ENDEPIN0, NRF_USBD_EVENT_ENDEPIN1, NRF_USBD_EVENT_ENDEPIN2, - NRF_USBD_EVENT_ENDEPIN3, NRF_USBD_EVENT_ENDEPIN4, NRF_USBD_EVENT_ENDEPIN5, - NRF_USBD_EVENT_ENDEPIN6, NRF_USBD_EVENT_ENDEPIN7, NRF_USBD_EVENT_ENDISOIN0}; - static const nrf_usbd_event_t epout_endev[] = { - NRF_USBD_EVENT_ENDEPOUT0, NRF_USBD_EVENT_ENDEPOUT1, NRF_USBD_EVENT_ENDEPOUT2, - NRF_USBD_EVENT_ENDEPOUT3, NRF_USBD_EVENT_ENDEPOUT4, NRF_USBD_EVENT_ENDEPOUT5, - NRF_USBD_EVENT_ENDEPOUT6, NRF_USBD_EVENT_ENDEPOUT7, NRF_USBD_EVENT_ENDISOOUT0}; + if (!NRF_USBD_COMMON_EP_IS_ISO(ep_num)) { + if (ep_in) { + return NRF_USBD->EPIN[ep_num].AMOUNT; + } else { + return NRF_USBD->EPOUT[ep_num].AMOUNT; + } + } + + return ep_in ? NRF_USBD->ISOIN.AMOUNT : NRF_USBD->ISOOUT.AMOUNT; +} + +/* Start EasyDMA on given endpoint */ +static void usbd_ep_dma_start(nrf_usbd_common_ep_t ep, uint32_t addr, size_t len) +{ + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); - return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); + + if (!NRF_USBD_COMMON_EP_IS_ISO(ep_num)) { + if (ep_in) { + NRF_USBD->EPIN[ep_num].PTR = addr; + NRF_USBD->EPIN[ep_num].MAXCNT = len; + NRF_USBD->TASKS_STARTEPIN[ep_num] = 1; + } else { + NRF_USBD->EPOUT[ep_num].PTR = addr; + NRF_USBD->EPOUT[ep_num].MAXCNT = len; + NRF_USBD->TASKS_STARTEPOUT[ep_num] = 1; + } + } else if (ep_in) { + NRF_USBD->ISOIN.PTR = addr; + NRF_USBD->ISOIN.MAXCNT = len; + NRF_USBD->TASKS_STARTISOIN = 1; + } else { + NRF_USBD->ISOOUT.PTR = addr; + NRF_USBD->ISOOUT.MAXCNT = len; + NRF_USBD->TASKS_STARTISOOUT = 1; + } } static bool nrf_usbd_common_consumer(nrf_usbd_common_ep_transfer_t *p_next, @@ -368,21 +419,6 @@ static inline uint8_t ep_to_hal(nrf_usbd_common_ep_t ep) return (uint8_t)ep; } -/** - * @brief Generate start task number for selected endpoint index. - * - * @param ep Endpoint number. - * - * @return Task for starting EasyDMA transfer on selected endpoint. - */ -static inline nrf_usbd_task_t task_start_ep(nrf_usbd_common_ep_t ep) -{ - NRF_USBD_COMMON_ASSERT_EP_VALID(ep); - return (nrf_usbd_task_t)((NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 - : NRF_USBD_TASK_STARTEPOUT0) + - (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); -} - /** * @brief Access selected endpoint state structure. * @@ -394,8 +430,8 @@ static inline nrf_usbd_task_t task_start_ep(nrf_usbd_common_ep_t ep) static inline usbd_ep_state_t *ep_state_access(nrf_usbd_common_ep_t ep) { NRF_USBD_COMMON_ASSERT_EP_VALID(ep); - return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + - NRF_USBD_EP_NR_GET(ep)); + return ((NRF_USBD_COMMON_EP_IS_IN(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + + NRF_USBD_COMMON_EP_NUM(ep)); } /** @@ -430,8 +466,8 @@ static inline nrf_usbd_common_ep_t bit2ep(uint8_t bitpos) BUILD_ASSERT(NRF_USBD_COMMON_EPOUT_BITPOS_0 > NRF_USBD_COMMON_EPIN_BITPOS_0, "OUT endpoint bits should be higher than IN endpoint bits"); return (nrf_usbd_common_ep_t)((bitpos >= NRF_USBD_COMMON_EPOUT_BITPOS_0) - ? NRF_USBD_EPOUT(bitpos - NRF_USBD_COMMON_EPOUT_BITPOS_0) - : NRF_USBD_EPIN(bitpos)); + ? NRF_USBD_COMMON_EPOUT(bitpos - NRF_USBD_COMMON_EPOUT_BITPOS_0) + : NRF_USBD_COMMON_EPIN(bitpos)); } /** @@ -460,31 +496,6 @@ static inline void usbd_dma_pending_clear(void) } } -/** - * @brief Start selected EasyDMA transmission. - * - * This is internal auxiliary function. - * No checking is made if EasyDMA is ready for new transmission. - * - * @param[in] ep Number of endpoint for transmission. - * If it is OUT endpoint transmission would be directed from endpoint to RAM. - * If it is in endpoint transmission would be directed from RAM to endpoint. - */ -static inline void usbd_dma_start(nrf_usbd_common_ep_t ep) -{ - nrf_usbd_task_trigger(NRF_USBD, task_start_ep(ep)); -} - -void nrf_usbd_common_isoinconfig_set(nrf_usbd_isoinconfig_t config) -{ - nrf_usbd_isoinconfig_set(NRF_USBD, config); -} - -nrf_usbd_isoinconfig_t nrf_usbd_common_isoinconfig_get(void) -{ - return nrf_usbd_isoinconfig_get(NRF_USBD); -} - /** * @brief Abort pending transfer on selected endpoint. * @@ -503,7 +514,7 @@ static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) unsigned int irq_lock_key = irq_lock(); usbd_ep_state_t *p_state = ep_state_access(ep); - if (NRF_USBD_EPOUT_CHECK(ep)) { + if (NRF_USBD_COMMON_EP_IS_OUT(ep)) { /* Host -> Device */ if ((~m_ep_dma_waiting) & (1U << ep2bit(ep))) { /* If the bit in m_ep_dma_waiting in cleared - nothing would be @@ -518,11 +529,11 @@ static inline void usbd_ep_abort(nrf_usbd_common_ep_t ep) /* Aborted */ p_state->status = NRF_USBD_COMMON_EP_ABORTED; } else { - if (!NRF_USBD_EPISO_CHECK(ep)) { + if (!NRF_USBD_COMMON_EP_IS_ISO(ep)) { /* Workaround: Disarm the endpoint if there is any data buffered. */ if (ep != NRF_USBD_COMMON_EPIN0) { *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = - 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1)); + 0x7B6 + (2u * (NRF_USBD_COMMON_EP_NUM(ep) - 1)); uint8_t temp = *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)); temp |= (1U << 1); @@ -578,13 +589,13 @@ static void usbd_ep_abort_all(void) while (ep_waiting != 0) { uint8_t bitpos = NRF_CTZ(ep_waiting); - if (!NRF_USBD_EPISO_CHECK(bit2ep(bitpos))) { + if (!NRF_USBD_COMMON_EP_IS_ISO(bit2ep(bitpos))) { usbd_ep_abort(bit2ep(bitpos)); } ep_waiting &= ~(1U << bitpos); } - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); + m_ep_ready = (((1U << NRF_USBD_COMMON_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); } /** @@ -618,7 +629,7 @@ static void ev_usbreset_handler(void) static void nrf_usbd_dma_finished(nrf_usbd_common_ep_t ep) { /* DMA finished, track if total bytes transferred is even or odd */ - m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1; + m_dma_odd ^= usbd_ep_amount_get(ep) & 1; usbd_dma_pending_clear(); k_sem_give(&dma_available); @@ -630,7 +641,7 @@ static void nrf_usbd_dma_finished(nrf_usbd_common_ep_t ep) } else if (!p_state->more_transactions) { m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - if (NRF_USBD_EPOUT_CHECK(ep) || (ep == NRF_USBD_COMMON_EPIN8)) { + if (NRF_USBD_COMMON_EP_IS_OUT(ep) || (ep == NRF_USBD_COMMON_EPIN8)) { /* Send event to the user - for an ISO IN or any OUT endpoint, * the whole transfer is finished in this moment */ @@ -646,13 +657,13 @@ static void ev_sof_handler(void) { nrf_usbd_common_evt_t evt = { NRF_USBD_COMMON_EVT_SOF, - .data = {.sof = {.framecnt = (uint16_t)nrf_usbd_framecntr_get(NRF_USBD)}}}; + .data = {.sof = {.framecnt = (uint16_t)NRF_USBD->FRAMECNTR}}}; /* Process isochronous endpoints */ uint32_t iso_ready_mask = (1U << ep2bit(NRF_USBD_COMMON_EPIN8)); - if (nrf_usbd_episoout_size_get(NRF_USBD, NRF_USBD_COMMON_EPOUT8) != - NRF_USBD_EPISOOUT_NO_DATA) { + /* SIZE.ISOOUT is 0 only when no packet was received at all */ + if (NRF_USBD->SIZE.ISOOUT) { iso_ready_mask |= (1U << ep2bit(NRF_USBD_COMMON_EPOUT8)); } m_ep_ready |= iso_ready_mask; @@ -673,7 +684,7 @@ static void usbd_ep_data_handler(nrf_usbd_common_ep_t ep, uint8_t bitpos) /* Mark endpoint ready for next DMA access */ m_ep_ready |= (1U << bitpos); - if (NRF_USBD_EPIN_CHECK(ep)) { + if (NRF_USBD_COMMON_EP_IS_IN(ep)) { /* IN endpoint (Device -> Host) */ if (0 == (m_ep_dma_waiting & (1U << bitpos))) { LOG_DBG("USBD event: EndpointData: In finished"); @@ -695,10 +706,11 @@ static void usbd_ep_data_handler(nrf_usbd_common_ep_t ep, uint8_t bitpos) static void ev_setup_handler(void) { LOG_DBG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", - nrf_usbd_setup_bmrequesttype_get(NRF_USBD), - nrf_usbd_setup_brequest_get(NRF_USBD), nrf_usbd_setup_wvalue_get(NRF_USBD), - nrf_usbd_setup_windex_get(NRF_USBD), nrf_usbd_setup_wlength_get(NRF_USBD)); - uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); + NRF_USBD->BMREQUESTTYPE, NRF_USBD->BREQUEST, + NRF_USBD->WVALUEL | (NRF_USBD->WVALUEH << 8), + NRF_USBD->WINDEXL | (NRF_USBD->WINDEXH << 8), + NRF_USBD->WLENGTHL | (NRF_USBD->WLENGTHH << 8)); + uint8_t bmRequestType = NRF_USBD->BMREQUESTTYPE; m_last_setup_dir = ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) == @@ -718,34 +730,38 @@ static void ev_setup_handler(void) static void ev_usbevent_handler(void) { - uint32_t event = nrf_usbd_eventcause_get_and_clear(NRF_USBD); + uint32_t event = NRF_USBD->EVENTCAUSE; - if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK) { + /* Clear handled events */ + NRF_USBD->EVENTCAUSE = event; + + if (event & USBD_EVENTCAUSE_ISOOUTCRC_Msk) { LOG_DBG("USBD event: ISOOUTCRC"); /* Currently no support */ } - if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK) { + if (event & USBD_EVENTCAUSE_SUSPEND_Msk) { LOG_DBG("USBD event: SUSPEND"); m_bus_suspend = true; const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_SUSPEND}; m_event_handler(&evt); } - if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK) { + if (event & USBD_EVENTCAUSE_RESUME_Msk) { LOG_DBG("USBD event: RESUME"); m_bus_suspend = false; const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_RESUME}; m_event_handler(&evt); } - if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK) { + if (event & USBD_EVENTCAUSE_USBWUALLOWED_Msk) { LOG_DBG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active"); if (m_bus_suspend) { - __ASSERT_NO_MSG(!nrf_usbd_lowpower_check(NRF_USBD)); + __ASSERT_NO_MSG(!nrf_usbd_common_suspend_check()); m_bus_suspend = false; - nrf_usbd_dpdmvalue_set(NRF_USBD, NRF_USBD_DPDMVALUE_RESUME); - nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_DRIVEDPDM); + NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume + << USBD_DPDMVALUE_STATE_Pos; + NRF_USBD->TASKS_DPDMDRIVE = 1; const nrf_usbd_common_evt_t evt = {.type = NRF_USBD_COMMON_EVT_WUREQ}; @@ -802,9 +818,8 @@ static uint8_t usbd_dma_scheduler_algorithm(uint32_t req) static inline size_t usbd_ep_iso_capacity(nrf_usbd_common_ep_t ep) { (void)ep; - nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get(NRF_USBD); - if (split == NRF_USBD_ISOSPLIT_HALF) { + if (NRF_USBD->ISOSPLIT == USBD_ISOSPLIT_SPLIT_HalfIN << USBD_ISOSPLIT_SPLIT_Pos) { return NRF_USBD_COMMON_ISOSIZE / 2; } return NRF_USBD_COMMON_ISOSIZE; @@ -840,7 +855,7 @@ static void usbd_dmareq_process(void) __ASSERT_NO_MSG(p_state->more_transactions); - if (NRF_USBD_EPIN_CHECK(ep)) { + if (NRF_USBD_COMMON_EP_IS_IN(ep)) { /* Device -> Host */ continue_transfer = nrf_usbd_common_feeder( &transfer, &p_state->transfer_state, @@ -882,18 +897,15 @@ static void usbd_dmareq_process(void) usbd_dma_pending_set(); m_ep_ready &= ~(1U << pos); - if (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) { + if (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_COMMON_EP_IS_ISO(ep))) { LOG_DBG("USB DMA process: Starting transfer on EP: %x, size: %u", ep, transfer.size); } /* Update number of currently transferred bytes */ p_state->transfer_cnt += transfer.size; /* Start transfer to the endpoint buffer */ - nrf_usbd_ep_easydma_set(NRF_USBD, ep, transfer.p_data.addr, - (uint32_t)transfer.size); - dma_ep = ep; - usbd_dma_start(ep); + usbd_ep_dma_start(ep, transfer.p_data.addr, transfer.size); /* Transfer started - exit the loop */ return; @@ -906,17 +918,6 @@ static void usbd_dmareq_process(void) } } -/** - * @brief Wait for a specified eventcause and clear it afterwards. - */ -static inline void usbd_eventcause_wait_and_clear(nrf_usbd_eventcause_mask_t eventcause) -{ - while (0 == (eventcause & nrf_usbd_eventcause_get(NRF_USBD))) { - /* Empty loop */ - } - nrf_usbd_eventcause_clear(NRF_USBD, eventcause); -} - /** * @brief Begin errata 171. */ @@ -1003,10 +1004,12 @@ static void usbd_enable(void) } /* Enable the peripheral */ - nrf_usbd_enable(NRF_USBD); + NRF_USBD->ENABLE = 1; /* Waiting for peripheral to enable, this should take a few us */ - usbd_eventcause_wait_and_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + while ((NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_READY_Msk) == 0) { + } + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; if (nrf_usbd_common_errata_171()) { usbd_errata_171_end(); @@ -1025,6 +1028,7 @@ static void usbd_enable(void) */ void nrf_usbd_common_irq_handler(void) { + volatile uint32_t *dma_endevent; uint32_t epdatastatus = 0; /* Clear EPDATA event and only then get and clear EPDATASTATUS to make @@ -1050,7 +1054,9 @@ void nrf_usbd_common_irq_handler(void) * handling acknowledged data transfer bits (epdatastatus) to avoid * a race condition between interrupt handler and host IN token. */ - if (nrf_usbd_event_get_and_clear(NRF_USBD, nrf_usbd_common_ep_to_endevent(dma_ep))) { + dma_endevent = usbd_ep_to_endevent(dma_ep); + if (*dma_endevent) { + *dma_endevent = 0; nrf_usbd_dma_finished(dma_ep); } @@ -1104,10 +1110,10 @@ nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler) uint8_t n; - for (n = 0; n < NRF_USBD_EPIN_CNT; ++n) { + for (n = 0; n < NRF_USBD_COMMON_EPIN_CNT; ++n) { nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPIN(n); - nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ? + nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_COMMON_EP_IS_ISO(ep) ? (NRF_USBD_COMMON_ISOSIZE / 2) : NRF_USBD_COMMON_EPSIZE); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -1115,10 +1121,10 @@ nrfx_err_t nrf_usbd_common_init(nrf_usbd_common_event_handler_t event_handler) p_state->more_transactions = false; p_state->transfer_cnt = 0; } - for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n) { + for (n = 0; n < NRF_USBD_COMMON_EPOUT_CNT; ++n) { nrf_usbd_common_ep_t ep = NRF_USBD_COMMON_EPOUT(n); - nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ? + nrf_usbd_common_ep_max_packet_size_set(ep, NRF_USBD_COMMON_EP_IS_ISO(ep) ? (NRF_USBD_COMMON_ISOSIZE / 2) : NRF_USBD_COMMON_EPSIZE); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -1143,12 +1149,12 @@ void nrf_usbd_common_enable(void) __ASSERT_NO_MSG(m_drv_state == NRFX_DRV_STATE_INITIALIZED); /* Prepare for READY event receiving */ - nrf_usbd_eventcause_clear(NRF_USBD, NRF_USBD_EVENTCAUSE_READY_MASK); + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; usbd_enable(); if (nrf_usbd_common_errata_223() && m_first_enable) { - nrf_usbd_disable(NRF_USBD); + NRF_USBD->ENABLE = 0; usbd_enable(); @@ -1171,15 +1177,17 @@ void nrf_usbd_common_enable(void) __DSB(); } - nrf_usbd_isosplit_set(NRF_USBD, NRF_USBD_ISOSPLIT_HALF); + NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN << USBD_ISOSPLIT_SPLIT_Pos; if (IS_ENABLED(CONFIG_NRF_USBD_ISO_IN_ZLP)) { - nrf_usbd_common_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA); + NRF_USBD->ISOINCONFIG = USBD_ISOINCONFIG_RESPONSE_ZeroData + << USBD_ISOINCONFIG_RESPONSE_Pos; } else { - nrf_usbd_common_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP); + NRF_USBD->ISOINCONFIG = USBD_ISOINCONFIG_RESPONSE_NoResp + << USBD_ISOINCONFIG_RESPONSE_Pos; } - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); + m_ep_ready = (((1U << NRF_USBD_COMMON_EPIN_CNT) - 1U) << NRF_USBD_COMMON_EPIN_BITPOS_0); m_ep_dma_waiting = 0; m_dma_odd = 0; __ASSERT_NO_MSG(k_sem_count_get(&dma_available) == 1); @@ -1213,14 +1221,14 @@ void nrf_usbd_common_disable(void) /* Prevent invalid bus request after next USBD enable by ensuring * that total number of bytes transferred by DMA is even. */ - nrf_usbd_event_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0); - nrf_usbd_ep_easydma_set(NRF_USBD, NRF_USBD_COMMON_EPIN0, (uint32_t)&m_dma_odd, 1); - usbd_dma_start(NRF_USBD_COMMON_EPIN0); - while (!nrf_usbd_event_get_and_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0)) { + NRF_USBD->EVENTS_ENDEPIN[0] = 0; + usbd_ep_dma_start(NRF_USBD_COMMON_EPIN0, (uint32_t)&m_dma_odd, 1); + while (!NRF_USBD->EVENTS_ENDEPIN[0]) { } + NRF_USBD->EVENTS_ENDEPIN[0] = 0; m_dma_odd = 0; } - nrf_usbd_disable(NRF_USBD); + NRF_USBD->ENABLE = 0; usbd_dma_pending_clear(); k_sem_give(&dma_available); m_drv_state = NRFX_DRV_STATE_INITIALIZED; @@ -1261,7 +1269,7 @@ void nrf_usbd_common_start(bool enable_sof) irq_enable(USBD_IRQn); /* Enable pullups */ - nrf_usbd_pullup_enable(NRF_USBD); + NRF_USBD->USBPULLUP = 1; } static void nrf_usbd_common_stop(void) @@ -1276,7 +1284,7 @@ static void nrf_usbd_common_stop(void) usbd_ep_abort_all(); /* Disable pullups */ - nrf_usbd_pullup_disable(NRF_USBD); + NRF_USBD->USBPULLUP = 0; /* Disable interrupt globally */ irq_disable(USBD_IRQn); @@ -1307,10 +1315,13 @@ bool nrf_usbd_common_suspend(void) unsigned int irq_lock_key = irq_lock(); if (m_bus_suspend) { - if (!(nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK)) { - nrf_usbd_lowpower_enable(NRF_USBD); - if (nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK) { - nrf_usbd_lowpower_disable(NRF_USBD); + if (!(NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_RESUME_Msk)) { + NRF_USBD->LOWPOWER = USBD_LOWPOWER_LOWPOWER_LowPower + << USBD_LOWPOWER_LOWPOWER_Pos; + (void)NRF_USBD->LOWPOWER; + if (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_RESUME_Msk) { + NRF_USBD->LOWPOWER = USBD_LOWPOWER_LOWPOWER_ForceNormal + << USBD_LOWPOWER_LOWPOWER_Pos; } else { suspended = true; } @@ -1327,8 +1338,9 @@ bool nrf_usbd_common_wakeup_req(void) bool started = false; unsigned int irq_lock_key = irq_lock(); - if (m_bus_suspend && nrf_usbd_lowpower_check(NRF_USBD)) { - nrf_usbd_lowpower_disable(NRF_USBD); + if (m_bus_suspend && nrf_usbd_common_suspend_check()) { + NRF_USBD->LOWPOWER = USBD_LOWPOWER_LOWPOWER_ForceNormal + << USBD_LOWPOWER_LOWPOWER_Pos; started = true; if (nrf_usbd_common_errata_171()) { @@ -1349,7 +1361,8 @@ bool nrf_usbd_common_wakeup_req(void) bool nrf_usbd_common_suspend_check(void) { - return nrf_usbd_lowpower_check(NRF_USBD); + return NRF_USBD->LOWPOWER != + (USBD_LOWPOWER_LOWPOWER_ForceNormal << USBD_LOWPOWER_LOWPOWER_Pos); } bool nrf_usbd_common_bus_suspend_check(void) @@ -1365,12 +1378,12 @@ void nrf_usbd_common_force_bus_wakeup(void) void nrf_usbd_common_ep_max_packet_size_set(nrf_usbd_common_ep_t ep, uint16_t size) { /* Only the power of 2 size allowed for Control Endpoints */ - __ASSERT_NO_MSG((((size & (size - 1)) == 0) || (NRF_USBD_EP_NR_GET(ep) != 0))); + __ASSERT_NO_MSG((((size & (size - 1)) == 0) || (NRF_USBD_COMMON_EP_NUM(ep) != 0))); /* Only non zero size allowed for Control Endpoints */ - __ASSERT_NO_MSG((size != 0) || (NRF_USBD_EP_NR_GET(ep) != 0)); + __ASSERT_NO_MSG((size != 0) || (NRF_USBD_COMMON_EP_NUM(ep) != 0)); /* Packet size cannot be higher than maximum buffer size */ - __ASSERT_NO_MSG((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) || - (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRF_USBD_COMMON_EPSIZE))); + __ASSERT_NO_MSG((NRF_USBD_COMMON_EP_IS_ISO(ep) && (size <= usbd_ep_iso_capacity(ep))) || + (!NRF_USBD_COMMON_EP_IS_ISO(ep) && (size <= NRF_USBD_COMMON_EPSIZE))); usbd_ep_state_t *p_state = ep_state_access(ep); @@ -1386,17 +1399,30 @@ uint16_t nrf_usbd_common_ep_max_packet_size_get(nrf_usbd_common_ep_t ep) bool nrf_usbd_common_ep_enable_check(nrf_usbd_common_ep_t ep) { - return nrf_usbd_ep_enable_check(NRF_USBD, ep_to_hal(ep)); + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + + NRF_USBD_COMMON_ASSERT_EP_VALID(ep); + + return (ep_in ? NRF_USBD->EPINEN : NRF_USBD->EPOUTEN) & BIT(ep_num); } void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep) { - if (nrf_usbd_ep_enable_check(NRF_USBD, ep)) { + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + + if (nrf_usbd_common_ep_enable_check(ep)) { return; } - nrf_usbd_ep_enable(NRF_USBD, ep_to_hal(ep)); - if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && - !NRF_USBD_EPISO_CHECK(ep)) { + + if (ep_in) { + NRF_USBD->EPINEN |= BIT(ep_num); + } else { + NRF_USBD->EPOUTEN |= BIT(ep_num); + } + + if (ep >= NRF_USBD_COMMON_EPOUT1 && ep <= NRF_USBD_COMMON_EPOUT7) { unsigned int irq_lock_key = irq_lock(); nrf_usbd_common_transfer_out_drop(ep); @@ -1408,10 +1434,17 @@ void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) { + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + /* Only disable endpoint if there is no active DMA */ k_sem_take(&dma_available, K_FOREVER); usbd_ep_abort(ep); - nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep)); + if (ep_in) { + NRF_USBD->EPINEN &= ~BIT(ep_num); + } else { + NRF_USBD->EPOUTEN &= ~BIT(ep_num); + } k_sem_give(&dma_available); /* This function was holding DMA semaphore and could potentially prevent @@ -1421,11 +1454,6 @@ void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep) usbd_int_rise(); } -void nrf_usbd_common_ep_default_config(void) -{ - nrf_usbd_ep_default_config(NRF_USBD); -} - nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, nrf_usbd_common_transfer_t const *p_transfer) { @@ -1436,10 +1464,10 @@ nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, __ASSERT_NO_MSG(p_transfer != NULL); /* Setup data transaction can go only in one direction at a time */ - if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) { + if ((NRF_USBD_COMMON_EP_NUM(ep) == 0) && (ep != m_last_setup_dir)) { ret = NRFX_ERROR_INVALID_ADDR; if (NRF_USBD_COMMON_FAILED_TRANSFERS_DEBUG && - (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) { + (NRF_USBD_COMMON_ISO_DEBUG || (!NRF_USBD_COMMON_EP_IS_ISO(ep)))) { LOG_DBG("Transfer failed: Invalid EPr\n"); } } else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRF_USBD_COMMON_EPIN_BIT_MASK)) & @@ -1453,7 +1481,7 @@ nrfx_err_t nrf_usbd_common_ep_transfer(nrf_usbd_common_ep_t ep, } else { usbd_ep_state_t *p_state = ep_state_access(ep); - __ASSERT_NO_MSG(NRF_USBD_EPIN_CHECK(ep) || + __ASSERT_NO_MSG(NRF_USBD_COMMON_EP_IS_IN(ep) || (p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx))); p_state->more_transactions = true; @@ -1487,7 +1515,17 @@ nrf_usbd_common_ep_status_t nrf_usbd_common_ep_status_get(nrf_usbd_common_ep_t e size_t nrf_usbd_common_epout_size_get(nrf_usbd_common_ep_t ep) { - return nrf_usbd_epout_size_get(NRF_USBD, ep_to_hal(ep)); + if (NRF_USBD_COMMON_EP_IS_ISO(ep)) { + size_t size = NRF_USBD->SIZE.ISOOUT; + + if ((size & USBD_SIZE_ISOOUT_ZERO_Msk) == + (USBD_SIZE_ISOOUT_ZERO_ZeroData << USBD_SIZE_ISOOUT_ZERO_Pos)) { + size = 0; + } + return size; + } + + return NRF_USBD->SIZE.EPOUT[NRF_USBD_COMMON_EP_NUM(ep)]; } bool nrf_usbd_common_ep_is_busy(nrf_usbd_common_ep_t ep) @@ -1498,53 +1536,71 @@ bool nrf_usbd_common_ep_is_busy(nrf_usbd_common_ep_t ep) void nrf_usbd_common_ep_stall(nrf_usbd_common_ep_t ep) { + __ASSERT_NO_MSG(!NRF_USBD_COMMON_EP_IS_ISO(ep)); + LOG_DBG("USB: EP %x stalled.", ep); - nrf_usbd_ep_stall(NRF_USBD, ep_to_hal(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep; } void nrf_usbd_common_ep_stall_clear(nrf_usbd_common_ep_t ep) { - if (NRF_USBD_EPOUT_CHECK(ep) && nrf_usbd_common_ep_stall_check(ep)) { + __ASSERT_NO_MSG(!NRF_USBD_COMMON_EP_IS_ISO(ep)); + + if (NRF_USBD_COMMON_EP_IS_OUT(ep) && nrf_usbd_common_ep_stall_check(ep)) { nrf_usbd_common_transfer_out_drop(ep); } - nrf_usbd_ep_unstall(NRF_USBD, ep_to_hal(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep; } bool nrf_usbd_common_ep_stall_check(nrf_usbd_common_ep_t ep) { - return nrf_usbd_ep_is_stall(NRF_USBD, ep_to_hal(ep)); + int ep_in = NRF_USBD_COMMON_EP_IS_IN(ep); + int ep_num = NRF_USBD_COMMON_EP_NUM(ep); + + if (!NRF_USBD_COMMON_EP_IS_ISO(ep_num)) { + if (ep_in) { + return NRF_USBD->HALTED.EPIN[ep_num]; + } else { + return NRF_USBD->HALTED.EPOUT[ep_num]; + } + } + + return false; } void nrf_usbd_common_ep_dtoggle_clear(nrf_usbd_common_ep_t ep) { - nrf_usbd_dtoggle_set(NRF_USBD, ep, NRF_USBD_DTOGGLE_DATA0); + __ASSERT_NO_MSG(!NRF_USBD_COMMON_EP_IS_ISO(ep)); + + NRF_USBD->DTOGGLE = ep | (USBD_DTOGGLE_VALUE_Nop << USBD_DTOGGLE_VALUE_Pos); + NRF_USBD->DTOGGLE = ep | (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos); } void nrf_usbd_common_setup_get(nrf_usbd_common_setup_t *p_setup) { memset(p_setup, 0, sizeof(nrf_usbd_common_setup_t)); - p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD); - p_setup->bRequest = nrf_usbd_setup_brequest_get(NRF_USBD); - p_setup->wValue = nrf_usbd_setup_wvalue_get(NRF_USBD); - p_setup->wIndex = nrf_usbd_setup_windex_get(NRF_USBD); - p_setup->wLength = nrf_usbd_setup_wlength_get(NRF_USBD); + p_setup->bmRequestType = NRF_USBD->BMREQUESTTYPE; + p_setup->bRequest = NRF_USBD->BREQUEST; + p_setup->wValue = NRF_USBD->WVALUEL | (NRF_USBD->WVALUEH << 8); + p_setup->wIndex = NRF_USBD->WINDEXL | (NRF_USBD->WINDEXH << 8); + p_setup->wLength = NRF_USBD->WLENGTHL | (NRF_USBD->WLENGTHH << 8); } void nrf_usbd_common_setup_data_clear(void) { - nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0RCVOUT); + NRF_USBD->TASKS_EP0RCVOUT = 1; } void nrf_usbd_common_setup_clear(void) { LOG_DBG(">> ep0status >>"); - nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STATUS); + NRF_USBD->TASKS_EP0STATUS = 1; } void nrf_usbd_common_setup_stall(void) { LOG_DBG("Setup stalled."); - nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STALL); + NRF_USBD->TASKS_EP0STALL = 1; } nrf_usbd_common_ep_t nrf_usbd_common_last_setup_dir_get(void) @@ -1556,11 +1612,11 @@ void nrf_usbd_common_transfer_out_drop(nrf_usbd_common_ep_t ep) { unsigned int irq_lock_key = irq_lock(); - __ASSERT_NO_MSG(NRF_USBD_EPOUT_CHECK(ep)); + __ASSERT_NO_MSG(NRF_USBD_COMMON_EP_IS_OUT(ep)); m_ep_ready &= ~(1U << ep2bit(ep)); - if (!NRF_USBD_EPISO_CHECK(ep)) { - nrf_usbd_epout_clear(NRF_USBD, ep); + if (!NRF_USBD_COMMON_EP_IS_ISO(ep)) { + NRF_USBD->SIZE.EPOUT[NRF_USBD_COMMON_EP_NUM(ep)] = 0; } irq_unlock(irq_lock_key); diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h index ac4149f3c42..bb3db14a05b 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.h @@ -12,7 +12,6 @@ #define NRF_USBD_COMMON_H__ #include -#include #ifdef __cplusplus extern "C" { @@ -57,7 +56,7 @@ extern "C" { * * @return Endpoint identifier that connects endpoint number and endpoint direction. */ -#define NRF_USBD_COMMON_EPIN(n) ((nrf_usbd_common_ep_t)NRF_USBD_EPIN(n)) +#define NRF_USBD_COMMON_EPIN(n) ((nrf_usbd_common_ep_t)(0x80 | n)) /** * @brief Create identifier for OUT endpoint. * @@ -67,7 +66,7 @@ extern "C" { * * @return Endpoint identifier that connects endpoint number and endpoint direction. */ -#define NRF_USBD_COMMON_EPOUT(n) ((nrf_usbd_common_ep_t)NRF_USBD_EPOUT(n)) +#define NRF_USBD_COMMON_EPOUT(n) ((nrf_usbd_common_ep_t)(n)) /** @} */ /** @@ -77,25 +76,25 @@ extern "C" { * This endpoint number is consistent with USB 2.0 specification. */ typedef enum { - NRF_USBD_COMMON_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ - NRF_USBD_COMMON_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ - NRF_USBD_COMMON_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ - NRF_USBD_COMMON_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ - NRF_USBD_COMMON_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ - NRF_USBD_COMMON_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ - NRF_USBD_COMMON_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ - NRF_USBD_COMMON_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ - NRF_USBD_COMMON_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ - - NRF_USBD_COMMON_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ - NRF_USBD_COMMON_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ - NRF_USBD_COMMON_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ - NRF_USBD_COMMON_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ - NRF_USBD_COMMON_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ - NRF_USBD_COMMON_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ - NRF_USBD_COMMON_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ - NRF_USBD_COMMON_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ - NRF_USBD_COMMON_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ + NRF_USBD_COMMON_EPOUT0 = 0x00, /**< Endpoint OUT 0 */ + NRF_USBD_COMMON_EPOUT1 = 0x01, /**< Endpoint OUT 1 */ + NRF_USBD_COMMON_EPOUT2 = 0x02, /**< Endpoint OUT 2 */ + NRF_USBD_COMMON_EPOUT3 = 0x03, /**< Endpoint OUT 3 */ + NRF_USBD_COMMON_EPOUT4 = 0x04, /**< Endpoint OUT 4 */ + NRF_USBD_COMMON_EPOUT5 = 0x05, /**< Endpoint OUT 5 */ + NRF_USBD_COMMON_EPOUT6 = 0x06, /**< Endpoint OUT 6 */ + NRF_USBD_COMMON_EPOUT7 = 0x07, /**< Endpoint OUT 7 */ + NRF_USBD_COMMON_EPOUT8 = 0x08, /**< Endpoint OUT 8 */ + + NRF_USBD_COMMON_EPIN0 = 0x80, /**< Endpoint IN 0 */ + NRF_USBD_COMMON_EPIN1 = 0x81, /**< Endpoint IN 1 */ + NRF_USBD_COMMON_EPIN2 = 0x82, /**< Endpoint IN 2 */ + NRF_USBD_COMMON_EPIN3 = 0x83, /**< Endpoint IN 3 */ + NRF_USBD_COMMON_EPIN4 = 0x84, /**< Endpoint IN 4 */ + NRF_USBD_COMMON_EPIN5 = 0x85, /**< Endpoint IN 5 */ + NRF_USBD_COMMON_EPIN6 = 0x86, /**< Endpoint IN 6 */ + NRF_USBD_COMMON_EPIN7 = 0x87, /**< Endpoint IN 7 */ + NRF_USBD_COMMON_EPIN8 = 0x88, /**< Endpoint IN 8 */ } nrf_usbd_common_ep_t; /** @@ -489,13 +488,6 @@ void nrf_usbd_common_ep_enable(nrf_usbd_common_ep_t ep); */ void nrf_usbd_common_ep_disable(nrf_usbd_common_ep_t ep); -/** - * @brief Disable all endpoints except for EP0. - * - * Disable all endpoints that can be disabled in USB device while it is still active. - */ -void nrf_usbd_common_ep_default_config(void); - /** * @brief Start sending data over endpoint. * From 9dd8f94fd47b8b399c230fac2c24e4949cc25b99 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 3 Nov 2023 21:50:52 +0000 Subject: [PATCH 3206/4498] drivers: flash: mcux_flexspi_nor: Remove flash reads while programming Care must be taken to avoid any flash access while programming the flash attached to the FlexSPI either via executing XIP code or reading RO data. Remove locations where a constant device pointer might be dereferenced within the mcux_flexspi_nor driver, to help avoid RWW hazards. Fixes #64702 Signed-off-by: Daniel DeGrasse --- drivers/flash/flash_mcux_flexspi_nor.c | 146 +++++++++++++------------ 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 78d353e9160..8a9c4f182ad 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -58,9 +58,17 @@ enum { ERASE_CHIP, }; +struct flash_flexspi_nor_config { + /* Note: don't use this controller reference in code. It is + * only used during init to copy the device structure from ROM + * into a RAM structure + */ + const struct device *controller; +}; + /* Device variables used in critical sections should be in this structure */ struct flash_flexspi_nor_data { - const struct device *controller; + struct device controller; flexspi_device_config_t config; flexspi_port_t port; struct flash_pages_layout layout; @@ -154,10 +162,9 @@ static const uint32_t flash_flexspi_nor_lut[][4] = { }, }; -static int flash_flexspi_nor_get_vendor_id(const struct device *dev, +static int flash_flexspi_nor_get_vendor_id(struct flash_flexspi_nor_data *data, uint8_t *vendor_id) { - struct flash_flexspi_nor_data *data = dev->data; uint32_t buffer = 0; int ret; @@ -173,17 +180,15 @@ static int flash_flexspi_nor_get_vendor_id(const struct device *dev, LOG_DBG("Reading id"); - ret = memc_flexspi_transfer(data->controller, &transfer); + ret = memc_flexspi_transfer(&data->controller, &transfer); *vendor_id = buffer; return ret; } -static int flash_flexspi_nor_read_status(const struct device *dev, +static int flash_flexspi_nor_read_status(struct flash_flexspi_nor_data *data, uint32_t *status) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = 0, .port = data->port, @@ -196,14 +201,12 @@ static int flash_flexspi_nor_read_status(const struct device *dev, LOG_DBG("Reading status register"); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_write_status(const struct device *dev, +static int flash_flexspi_nor_write_status(struct flash_flexspi_nor_data *data, uint32_t *status) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = 0, .port = data->port, @@ -216,13 +219,11 @@ static int flash_flexspi_nor_write_status(const struct device *dev, LOG_DBG("Writing status register"); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_write_enable(const struct device *dev) +static int flash_flexspi_nor_write_enable(struct flash_flexspi_nor_data *data) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = 0, .port = data->port, @@ -235,14 +236,12 @@ static int flash_flexspi_nor_write_enable(const struct device *dev) LOG_DBG("Enabling write"); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_erase_sector(const struct device *dev, +static int flash_flexspi_nor_erase_sector(struct flash_flexspi_nor_data *data, off_t offset) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = offset, .port = data->port, @@ -255,14 +254,12 @@ static int flash_flexspi_nor_erase_sector(const struct device *dev, LOG_DBG("Erasing sector at 0x%08zx", (ssize_t) offset); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_erase_block(const struct device *dev, +static int flash_flexspi_nor_erase_block(struct flash_flexspi_nor_data *data, off_t offset) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = offset, .port = data->port, @@ -275,13 +272,11 @@ static int flash_flexspi_nor_erase_block(const struct device *dev, LOG_DBG("Erasing block at 0x%08zx", (ssize_t) offset); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_erase_chip(const struct device *dev) +static int flash_flexspi_nor_erase_chip(struct flash_flexspi_nor_data *data) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = 0, .port = data->port, @@ -294,14 +289,12 @@ static int flash_flexspi_nor_erase_chip(const struct device *dev) LOG_DBG("Erasing chip"); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_page_program(const struct device *dev, +static int flash_flexspi_nor_page_program(struct flash_flexspi_nor_data *data, off_t offset, const void *buffer, size_t len) { - struct flash_flexspi_nor_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = offset, .port = data->port, @@ -314,16 +307,16 @@ static int flash_flexspi_nor_page_program(const struct device *dev, LOG_DBG("Page programming %d bytes to 0x%08zx", len, (ssize_t) offset); - return memc_flexspi_transfer(data->controller, &transfer); + return memc_flexspi_transfer(&data->controller, &transfer); } -static int flash_flexspi_nor_wait_bus_busy(const struct device *dev) +static int flash_flexspi_nor_wait_bus_busy(struct flash_flexspi_nor_data *data) { uint32_t status = 0; int ret; do { - ret = flash_flexspi_nor_read_status(dev, &status); + ret = flash_flexspi_nor_read_status(data, &status); LOG_DBG("status: 0x%x", status); if (ret) { LOG_ERR("Could not read status"); @@ -334,14 +327,13 @@ static int flash_flexspi_nor_wait_bus_busy(const struct device *dev) return 0; } -static int flash_flexspi_nor_enable_quad_mode(const struct device *dev) +static int flash_flexspi_nor_enable_quad_mode(struct flash_flexspi_nor_data *data) { - struct flash_flexspi_nor_data *data = dev->data; uint32_t status = 0x40; - flash_flexspi_nor_write_status(dev, &status); - flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(data->controller); + flash_flexspi_nor_write_status(data, &status); + flash_flexspi_nor_wait_bus_busy(data); + memc_flexspi_reset(&data->controller); return 0; } @@ -350,7 +342,7 @@ static int flash_flexspi_nor_read(const struct device *dev, off_t offset, void *buffer, size_t len) { struct flash_flexspi_nor_data *data = dev->data; - uint8_t *src = memc_flexspi_get_ahb_address(data->controller, + uint8_t *src = memc_flexspi_get_ahb_address(&data->controller, data->port, offset); @@ -368,11 +360,11 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, int i; unsigned int key = 0; - uint8_t *dst = memc_flexspi_get_ahb_address(data->controller, + uint8_t *dst = memc_flexspi_get_ahb_address(&data->controller, data->port, offset); - if (memc_flexspi_is_running_xip(data->controller)) { + if (memc_flexspi_is_running_xip(&data->controller)) { /* * ==== ENTER CRITICAL SECTION ==== * No flash access should be performed in critical section. All @@ -390,20 +382,20 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER memcpy(nor_write_buf, src, i); #endif - flash_flexspi_nor_write_enable(dev); + flash_flexspi_nor_write_enable(data); #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER - flash_flexspi_nor_page_program(dev, offset, nor_write_buf, i); + flash_flexspi_nor_page_program(data, offset, nor_write_buf, i); #else - flash_flexspi_nor_page_program(dev, offset, src, i); + flash_flexspi_nor_page_program(data, offset, src, i); #endif - flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(data->controller); + flash_flexspi_nor_wait_bus_busy(data); + memc_flexspi_reset(&data->controller); src += i; offset += i; len -= i; } - if (memc_flexspi_is_running_xip(data->controller)) { + if (memc_flexspi_is_running_xip(&data->controller)) { /* ==== EXIT CRITICAL SECTION ==== */ irq_unlock(key); } @@ -425,7 +417,7 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, int i; unsigned int key = 0; - uint8_t *dst = memc_flexspi_get_ahb_address(data->controller, + uint8_t *dst = memc_flexspi_get_ahb_address(&data->controller, data->port, offset); @@ -439,7 +431,7 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, return -EINVAL; } - if (memc_flexspi_is_running_xip(data->controller)) { + if (memc_flexspi_is_running_xip(&data->controller)) { /* * ==== ENTER CRITICAL SECTION ==== * No flash access should be performed in critical section. All @@ -449,29 +441,29 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, } if ((offset == 0) && (size == data->config.flashSize * KB(1))) { - flash_flexspi_nor_write_enable(dev); - flash_flexspi_nor_erase_chip(dev); - flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(data->controller); + flash_flexspi_nor_write_enable(data); + flash_flexspi_nor_erase_chip(data); + flash_flexspi_nor_wait_bus_busy(data); + memc_flexspi_reset(&data->controller); } else if ((0 == (offset % SPI_NOR_BLOCK_SIZE)) && (0 == (size % SPI_NOR_BLOCK_SIZE))) { for (i = 0; i < num_blocks; i++) { - flash_flexspi_nor_write_enable(dev); - flash_flexspi_nor_erase_block(dev, offset); - flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(data->controller); + flash_flexspi_nor_write_enable(data); + flash_flexspi_nor_erase_block(data, offset); + flash_flexspi_nor_wait_bus_busy(data); + memc_flexspi_reset(&data->controller); offset += SPI_NOR_BLOCK_SIZE; } } else { for (i = 0; i < num_sectors; i++) { - flash_flexspi_nor_write_enable(dev); - flash_flexspi_nor_erase_sector(dev, offset); - flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(data->controller); + flash_flexspi_nor_write_enable(data); + flash_flexspi_nor_erase_sector(data, offset); + flash_flexspi_nor_wait_bus_busy(data); + memc_flexspi_reset(&data->controller); offset += SPI_NOR_SECTOR_SIZE; } } - if (memc_flexspi_is_running_xip(data->controller)) { + if (memc_flexspi_is_running_xip(&data->controller)) { /* ==== EXIT CRITICAL SECTION ==== */ irq_unlock(key); } @@ -504,19 +496,26 @@ static void flash_flexspi_nor_pages_layout(const struct device *dev, static int flash_flexspi_nor_init(const struct device *dev) { + const struct flash_flexspi_nor_config *config = dev->config; struct flash_flexspi_nor_data *data = dev->data; uint8_t vendor_id; - if (!device_is_ready(data->controller)) { + /* First step- use ROM pointer to controller device to create + * a copy of the device structure in RAM we can use while in + * critical sections of code. + */ + memcpy(&data->controller, config->controller, sizeof(struct device)); + + if (!device_is_ready(&data->controller)) { LOG_ERR("Controller device is not ready"); return -ENODEV; } - if (memc_flexspi_is_running_xip(data->controller)) { + if (memc_flexspi_is_running_xip(&data->controller)) { /* Wait for bus idle before configuring */ - memc_flexspi_wait_bus_idle(data->controller); + memc_flexspi_wait_bus_idle(&data->controller); } - if (memc_flexspi_set_device_config(data->controller, &data->config, + if (memc_flexspi_set_device_config(&data->controller, &data->config, (const uint32_t *)flash_flexspi_nor_lut, sizeof(flash_flexspi_nor_lut) / MEMC_FLEXSPI_CMD_SIZE, data->port)) { @@ -524,15 +523,15 @@ static int flash_flexspi_nor_init(const struct device *dev) return -EINVAL; } - memc_flexspi_reset(data->controller); + memc_flexspi_reset(&data->controller); - if (flash_flexspi_nor_get_vendor_id(dev, &vendor_id)) { + if (flash_flexspi_nor_get_vendor_id(data, &vendor_id)) { LOG_ERR("Could not read vendor id"); return -EIO; } LOG_DBG("Vendor id: 0x%0x", vendor_id); - if (flash_flexspi_nor_enable_quad_mode(dev)) { + if (flash_flexspi_nor_enable_quad_mode(data)) { LOG_ERR("Could not enable quad mode"); return -EIO; } @@ -583,9 +582,12 @@ static const struct flash_driver_api flash_flexspi_nor_api = { } \ #define FLASH_FLEXSPI_NOR(n) \ + static const struct flash_flexspi_nor_config \ + flash_flexspi_nor_config_##n = { \ + .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ + }; \ static struct flash_flexspi_nor_data \ flash_flexspi_nor_data_##n = { \ - .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ .config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \ .port = DT_INST_REG_ADDR(n), \ .layout = { \ @@ -603,7 +605,7 @@ static const struct flash_driver_api flash_flexspi_nor_api = { flash_flexspi_nor_init, \ NULL, \ &flash_flexspi_nor_data_##n, \ - NULL, \ + &flash_flexspi_nor_config_##n, \ POST_KERNEL, \ CONFIG_FLASH_INIT_PRIORITY, \ &flash_flexspi_nor_api); From ec031029f4cab3c0fbb116f5cd63afcf59205a84 Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Fri, 3 Nov 2023 16:17:52 -0400 Subject: [PATCH 3207/4498] samples: fs: littlefs: sdmmc: remove fstab and fixed partition For littleFS, the fstab entries in DTS are ignored currently. So remove the overlay entries for the same. Also fixed-partitions can't be used for sdmmc-disk. So remove the same. We just need to have sdmmc node with zephyr,sdmmc-disk compatible string to have littleFS working on disk. build littleFS sample as follows:- west build -p always -b stm32h747i_disco_m7 \ samples/subsys/fs/littlefs/ -- \ -DOVERLAY_CONFIG=boards/stm32h747i_disco_m7.conf \ -DCONF_FILE=prj_blk.conf Signed-off-by: Murali Karicheri --- .../boards/stm32h747i_disco_m7.overlay | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay index bc2b79ea7a7..cf1c30e2e87 100644 --- a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay +++ b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay @@ -4,35 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/delete-node/ &storage_partition; - -/ { - fstab { - compatible = "zephyr,fstab"; - lfs1: lfs1 { - compatible = "zephyr,fstab,littlefs"; - read-size = <512>; - prog-size = <512>; - cache-size = <512>; - lookahead-size = <4096>; - block-cycles = <512>; - partition = <&storage_partition>; - mount-point = "/lfsemmc"; - }; - }; -}; - &sdmmc1 { sdmmc { compatible = "zephyr,sdmmc-disk"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - storage_partition: partition@0 { - label = "storage"; - reg = <0x0 DT_SIZE_M(2048)>; - }; - }; }; }; From ec527228613e2768caaddedaa5cdea04951d3a06 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Wed, 1 Nov 2023 16:29:12 +0000 Subject: [PATCH 3208/4498] drivers: regulator: npm1300: Add boot state detection Added boot state detection, so that the reference count is set correctly and enable/disable work as expected. With this fix it is no longer necessary to set regulator-boot-on when the regulator is enabled in hardware. Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_npm1300.c | 50 ++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index 84ea5b68263..b3a9d1aced9 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -48,6 +48,7 @@ enum npm1300_gpio_type { #define BUCK_OFFSET_SW_CTRL 0x0FU #define BUCK_OFFSET_VOUT_STAT 0x10U #define BUCK_OFFSET_CTRL0 0x15U +#define BUCK_OFFSET_STATUS 0x34U /* nPM1300 ldsw register offsets */ #define LDSW_OFFSET_EN_SET 0x00U @@ -61,6 +62,12 @@ enum npm1300_gpio_type { /* nPM1300 ship register offsets */ #define SHIP_OFFSET_SHIP 0x02U +#define BUCK1_ON_MASK 0x04U +#define BUCK2_ON_MASK 0x40U + +#define LDSW1_ON_MASK 0x03U +#define LDSW2_ON_MASK 0x0CU + struct regulator_npm1300_pconfig { const struct device *mfd; struct gpio_dt_spec dvs_state_pins[5]; @@ -512,16 +519,57 @@ int regulator_npm1300_common_init(const struct device *dev) return 0; } +static int get_enabled_reg(const struct device *dev, uint8_t base, uint8_t offset, uint8_t mask, + bool *enabled) +{ + const struct regulator_npm1300_config *config = dev->config; + uint8_t data; + + int ret = mfd_npm1300_reg_read(config->mfd, base, offset, &data); + + if (ret != 0) { + return ret; + } + + *enabled = (data & mask) != 0U; + + return 0; +} + +static int get_enabled(const struct device *dev, bool *enabled) +{ + const struct regulator_npm1300_config *config = dev->config; + + switch (config->source) { + case NPM1300_SOURCE_BUCK1: + return get_enabled_reg(dev, BUCK_BASE, BUCK_OFFSET_STATUS, BUCK1_ON_MASK, enabled); + case NPM1300_SOURCE_BUCK2: + return get_enabled_reg(dev, BUCK_BASE, BUCK_OFFSET_STATUS, BUCK2_ON_MASK, enabled); + case NPM1300_SOURCE_LDO1: + return get_enabled_reg(dev, LDSW_BASE, LDSW_OFFSET_STATUS, LDSW1_ON_MASK, enabled); + case NPM1300_SOURCE_LDO2: + return get_enabled_reg(dev, LDSW_BASE, LDSW_OFFSET_STATUS, LDSW2_ON_MASK, enabled); + default: + return -ENODEV; + } +} + int regulator_npm1300_init(const struct device *dev) { const struct regulator_npm1300_config *config = dev->config; + bool enabled; int ret = 0; if (!device_is_ready(config->mfd)) { return -ENODEV; } - ret = regulator_common_init(dev, false); + ret = get_enabled(dev, &enabled); + if (ret < 0) { + return ret; + } + + ret = regulator_common_init(dev, enabled); if (ret < 0) { return ret; } From 3be2956b866e3edfed4ad7617e8ca01e16d98065 Mon Sep 17 00:00:00 2001 From: Georgij Cernysiov Date: Mon, 6 Nov 2023 12:26:12 +0100 Subject: [PATCH 3209/4498] drivers: ethernet: fix adin set_config lock Use correct argument to lock/unlock the MAC. Signed-off-by: Georgij Cernysiov --- drivers/ethernet/eth_adin2111.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index 070b8698c10..e73beb891d4 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -700,7 +700,7 @@ static int adin2111_port_set_config(const struct device *dev, const struct device *adin = cfg->adin; int ret = -ENOTSUP; - (void)eth_adin2111_lock(dev, K_FOREVER); + (void)eth_adin2111_lock(adin, K_FOREVER); if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { ret = adin2111_filter_unicast(adin, (uint8_t *)&config->mac_address.addr[0], @@ -716,7 +716,7 @@ static int adin2111_port_set_config(const struct device *dev, } end_unlock: - (void)eth_adin2111_unlock(dev); + (void)eth_adin2111_unlock(adin); return ret; } From 8bec2d7b37e14b5605f786f3ea6c0d3749fc96ab Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 7 Nov 2023 20:32:18 +0000 Subject: [PATCH 3210/4498] boards: roc_rk3568: do not use as default test platform Only qemu boards are used as default in CI, drop the default property from this one. Signed-off-by: Fabio Baltieri --- boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml | 1 - boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml index 6a303ded9fa..82f35f567d5 100644 --- a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc.yaml @@ -7,7 +7,6 @@ toolchain: - cross-compile ram: 1024 testing: - default: true ignore_tags: - net - bluetooth diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml index abc5dddabda..07120b871fa 100644 --- a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp.yaml @@ -9,7 +9,6 @@ ram: 1024 supported: - smp testing: - default: true ignore_tags: - net - bluetooth From 386b65800896262779336e83552c8a44ba96f7a2 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Fri, 1 Sep 2023 11:20:03 +0200 Subject: [PATCH 3211/4498] boards: arm: add nrf9131ek_nrf9131 This patch adds the nRF9131-EK board. Signed-off-by: Maximilian Deubel --- boards/arm/nrf9131ek_nrf9131/Kconfig.board | 14 ++ .../arm/nrf9131ek_nrf9131/Kconfig.defconfig | 38 +++ boards/arm/nrf9131ek_nrf9131/board.cmake | 14 ++ .../nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts | 19 ++ .../nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml | 17 ++ .../nrf9131ek_nrf9131_common-pinctrl.dtsi | 100 ++++++++ .../nrf9131ek_nrf9131_common.dtsi | 227 ++++++++++++++++++ .../nrf9131ek_nrf9131_defconfig | 26 ++ .../nrf9131ek_nrf9131_ns.dts | 22 ++ .../nrf9131ek_nrf9131_ns.yaml | 15 ++ .../nrf9131ek_nrf9131_ns_defconfig | 35 +++ .../nrf9131ek_nrf9131_partition_conf.dtsi | 60 +++++ .../arm/nrf9131ek_nrf9131/pre_dt_board.cmake | 7 + tests/lib/devicetree/devices/testcase.yaml | 2 + 14 files changed, 596 insertions(+) create mode 100644 boards/arm/nrf9131ek_nrf9131/Kconfig.board create mode 100644 boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig create mode 100644 boards/arm/nrf9131ek_nrf9131/board.cmake create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig create mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi create mode 100644 boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.board b/boards/arm/nrf9131ek_nrf9131/Kconfig.board new file mode 100644 index 00000000000..4a237e3fb61 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/Kconfig.board @@ -0,0 +1,14 @@ +# nRF9131-EK board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9131_LACA + +config BOARD_NRF9131EK_NRF9131 + bool "nRF9131 EK NRF9131" + +config BOARD_NRF9131EK_NRF9131_NS + bool "nRF9131 EK NRF9131 non-secure" + +endif # SOC_NRF9131_LACA diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig new file mode 100644 index 00000000000..0ece4f9a2ac --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig @@ -0,0 +1,38 @@ +# nRF9131 EK NRF9131 board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS + +config BOARD + default "nrf9131ek_nrf9131" + +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + depends on BOARD_NRF9131EK_NRF9131 && TRUSTED_EXECUTION_SECURE + +if BOARD_NRF9131EK_NRF9131_NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_NRF9131EK_NRF9131_NS + +endif # BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS diff --git a/boards/arm/nrf9131ek_nrf9131/board.cmake b/boards/arm/nrf9131ek_nrf9131/board.cmake new file mode 100644 index 00000000000..8293a428b40 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/board.cmake @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_NRF9131EK_NRF9131_NS) + set(TFM_PUBLIC_KEY_FORMAT "full") +endif() + +if(CONFIG_TFM_FLASH_MERGED_BINARY) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) +endif() + +# TODO: change to nRF9131_xxAA when such device is available in JLink +board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts new file mode 100644 index 00000000000..4b66e5348a0 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9131ek_nrf9131_common.dtsi" + +/ { + chosen { + zephyr,sram = &sram0_s; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml new file mode 100644 index 00000000000..d1b04054ce8 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml @@ -0,0 +1,17 @@ +identifier: nrf9131ek_nrf9131 +name: nRF9131-EK-NRF9131 +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 88 +flash: 1024 +supported: + - gpio + - i2c + - pwm + - spi + - watchdog + - counter diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi new file mode 100644 index 00000000000..419e7c8d70c --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + uart1_default: uart1_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + i2c2_default: i2c2_default { + group1 { + psels = , + ; + }; + }; + + i2c2_sleep: i2c2_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = , + , + ; + }; + }; + + pwm0_sleep: pwm0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + spi3_default: spi3_default { + group1 { + psels = , + , + ; + nordic,drive-mode = ; + }; + }; + + spi3_sleep: spi3_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi new file mode 100644 index 00000000000..35314cd0784 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "nrf9131ek_nrf9131_common-pinctrl.dtsi" +#include + +/ { + model = "Nordic nRF9131 EK NRF9131"; + compatible = "nordic,nrf9131-ek-nrf9131"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led1: led_1 { + gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led2: led_2 { + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 PWM_MSEC(8) PWM_POLARITY_NORMAL>; + }; + pwm_led1: pwm_led_1 { + pwms = <&pwm0 1 PWM_MSEC(8) PWM_POLARITY_NORMAL>; + }; + pwm_led2: pwm_led_2 { + pwms = <&pwm0 2 PWM_MSEC(8) PWM_POLARITY_NORMAL>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 28 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + pwm-led0 = &pwm_led0; + pwm-led1 = &pwm_led1; + pwm-led2 = &pwm_led2; + sw0 = &button0; + bootloader-led0 = &led0; + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; + watchdog0 = &wdt0; + spi-flash0 = &gd25wb256; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&i2c2 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + pinctrl-names = "default", "sleep"; + clock-frequency = ; + + pmic_main: npm1300@6b { + compatible = "nordic,npm1300"; + reg = <0x6b>; + pmic_charger: charger { + compatible = "nordic,npm1300-charger"; + term-microvolt = <4150000>; + term-warm-microvolt = <4000000>; + current-microamp = <150000>; + dischg-limit-microamp = <1000000>; + vbus-limit-microamp = <500000>; + thermistor-ohms = <10000>; + thermistor-beta = <3380>; + charging-enable; + }; + regulators { + compatible = "nordic,npm1300-regulator"; + BUCK1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + BUCK2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + }; + }; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; + + gd25wb256: gd25wb256e3ir@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; + spi-max-frequency = <8000000>; + size = <268435456>; + has-dpd; + t-enter-dpd = <3000>; + t-exit-dpd = <40000>; + sfdp-bfp = [ + e5 20 f3 ff ff ff ff 0f 44 eb 08 6b 08 3b 42 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 44 7a c9 fe 83 67 26 62 ec 82 18 44 + 7a 75 7a 75 04 c4 d5 5c 00 06 74 00 08 50 00 01 + ]; + jedec-id = [c8 65 19]; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x10000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@50000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@85000 { + label = "image-1"; + }; + slot1_ns_partition: partition@c5000 { + label = "image-1-nonsecure"; + }; + storage_partition: partition@fa000 { + label = "storage"; + reg = <0x000fa000 0x00006000>; + }; + }; +}; + + + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_modem: image_modem@20016000 { + /* Modem (shared) memory */ + }; + + sram0_ns: image_ns@20020000 { + /* Non-Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "nrf9131ek_nrf9131_partition_conf.dtsi" diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig new file mode 100644 index 00000000000..fc77ffe0d13 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9131_LACA=y +CONFIG_BOARD_NRF9131EK_NRF9131=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts new file mode 100644 index 00000000000..9a652cd0aed --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9131ek_nrf9131_common.dtsi" + +/ { + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0_ns; + zephyr,code-partition = &slot0_ns_partition; + }; +}; + +/* Disable UART1, because it is used by default in TF-M */ +&uart1 { + status = "disabled"; +}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml new file mode 100644 index 00000000000..cf33abd55da --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml @@ -0,0 +1,15 @@ +identifier: nrf9131ek_nrf9131_ns +name: nRF9131-EK-NRF9131-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 128 +flash: 212 +supported: + - i2c + - pwm + - watchdog + - netif:modem diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig new file mode 100644 index 00000000000..83af1cf6b74 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9131_LACA=y +CONFIG_BOARD_NRF9131EK_NRF9131_NS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y + +# enable PMIC +CONFIG_I2C=y +CONFIG_REGULATOR=y +CONFIG_SENSOR=y +CONFIG_NPM1300_CHARGER=y diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi new file mode 100644 index 00000000000..d14d8d95f75 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for nRF9131ek_nrf9131. + * + * Zephyr build for nRF9131 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot0_ns_partition { + reg = <0x00050000 0x35000>; +}; + +&slot1_partition { + reg = <0x00085000 0x40000>; +}; + +&slot1_ns_partition { + reg = <0x000c5000 0x35000>; +}; + +/* Default SRAM planning when building for nRF9131 with + * ARM TrustZone-M support + * - Lowest 88 kB SRAM allocated to Secure image (sram0_s). + * - 40 kB SRAM reserved for and used by the modem library + * (sram0_modem). This memory is Non-Secure. + * - Upper 128 kB allocated to Non-Secure image (sram0_ns). + * When building with TF-M, both sram0_modem and sram0_ns + * are allocated to the Non-Secure image. + */ + +&sram0_s { + reg = <0x20000000 DT_SIZE_K(88)>; +}; + +&sram0_modem { + reg = <0x20016000 DT_SIZE_K(40)>; +}; + +&sram0_ns { + reg = <0x20020000 DT_SIZE_K(128)>; +}; diff --git a/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake b/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake new file mode 100644 index 00000000000..c8267afd1b4 --- /dev/null +++ b/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - flash-controller@39000 & kmu@39000 +# - power@5000 & clock@5000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/tests/lib/devicetree/devices/testcase.yaml b/tests/lib/devicetree/devices/testcase.yaml index d7695220b8b..07c99fcdb62 100644 --- a/tests/lib/devicetree/devices/testcase.yaml +++ b/tests/lib/devicetree/devices/testcase.yaml @@ -16,3 +16,5 @@ tests: - bl5340_dvk_cpuapp_ns - m5stack_core2 - mimxrt595_evk_cm33 + - nrf9131ek_nrf9131 + - nrf9131ek_nrf9131_ns From 84bfb4a63b13a5062c7a9bd3fc458a4d97d224e5 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Thu, 14 Sep 2023 13:03:43 +0200 Subject: [PATCH 3212/4498] boards: arm: nrf9161dk: remove scratch partition This patch removes the now unused scratch partition and enlarges the application slots instead. Signed-off-by: Maximilian Deubel --- .../arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi | 8 ++------ .../nrf9161dk_nrf9161_partition_conf.dtsi | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi index a6aeccf34b9..8168a8317e4 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi @@ -230,16 +230,12 @@ arduino_spi: &spi3 { slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@80000 { + slot1_partition: partition@85000 { label = "image-1"; }; - slot1_ns_partition: partition@c0000 { + slot1_ns_partition: partition@c5000 { label = "image-1-nonsecure"; }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; storage_partition: partition@fa000 { label = "storage"; reg = <0x000fa000 0x00006000>; diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_partition_conf.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_partition_conf.dtsi index 80b4c5f6b3a..9e378cb94e0 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_partition_conf.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_partition_conf.dtsi @@ -26,15 +26,15 @@ }; &slot0_ns_partition { - reg = <0x00050000 0x30000>; + reg = <0x00050000 0x35000>; }; &slot1_partition { - reg = <0x00080000 0x40000>; + reg = <0x00085000 0x40000>; }; &slot1_ns_partition { - reg = <0x000c0000 0x30000>; + reg = <0x000c5000 0x35000>; }; /* Default SRAM planning when building for nRF9161 with From 13ca0dc806426aefed6efec1180f5a5e358bd196 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 13 Oct 2023 12:04:57 +0200 Subject: [PATCH 3213/4498] drivers: adc: stm32: refactor calibration Refactor calibration code in anticipation of PM addition. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 281 +++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 134 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 53562734bd0..a4f0d585b47 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -341,6 +341,52 @@ static int check_buffer(const struct adc_sequence *sequence, return 0; } +/* + * Enable ADC peripheral, and wait until ready if required by SOC. + */ +static int adc_stm32_enable(ADC_TypeDef *adc) +{ + if (LL_ADC_IsEnabled(adc) == 1UL) { + return 0; + } + +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + LL_ADC_ClearFlag_ADRDY(adc); + LL_ADC_Enable(adc); + + /* + * Enabling ADC modules in many series may fail if they are + * still not stabilized, this will wait for a short time (about 1ms) + * to ensure ADC modules are properly enabled. + */ + uint32_t count_timeout = 0; + + while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { +#ifdef CONFIG_SOC_SERIES_STM32F0X + /* For F0, continue to write ADEN=1 until ADRDY=1 */ + if (LL_ADC_IsEnabled(adc) == 0UL) { + LL_ADC_Enable(adc); + } +#endif /* CONFIG_SOC_SERIES_STM32F0X */ + count_timeout++; + k_busy_wait(100); + if (count_timeout >= 10) { + return -ETIMEDOUT; + } + } +#else + /* + * On STM32F1, F2, F37x, F4, F7 and L1, do not re-enable the ADC. + * On F1 and F37x if ADON holds 1 (LL_ADC_IsEnabled is true) and 1 is + * written, then conversion starts. That's not what is expected. + */ + LL_ADC_Enable(adc); +#endif + + return 0; +} + static void adc_stm32_start_conversion(const struct device *dev) { const struct adc_stm32_cfg *config = dev->config; @@ -356,6 +402,53 @@ static void adc_stm32_start_conversion(const struct device *dev) #endif } +/* + * Disable ADC peripheral, and wait until it is disabled + */ +static void adc_stm32_disable(ADC_TypeDef *adc) +{ + if (LL_ADC_IsEnabled(adc) != 1UL) { + return; + } + + /* Stop ongoing conversion if any + * Software must poll ADSTART (or JADSTART) until the bit is reset before assuming + * the ADC is completely stopped. + */ + +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + if (LL_ADC_REG_IsConversionOngoing(adc)) { + LL_ADC_REG_StopConversion(adc); + while (LL_ADC_REG_IsConversionOngoing(adc)) { + } + } +#endif + +#if !defined(CONFIG_SOC_SERIES_STM32C0X) && \ + !defined(CONFIG_SOC_SERIES_STM32F0X) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) && \ + !defined(CONFIG_SOC_SERIES_STM32G0X) && \ + !defined(CONFIG_SOC_SERIES_STM32L0X) && \ + !defined(CONFIG_SOC_SERIES_STM32WBAX) && \ + !defined(CONFIG_SOC_SERIES_STM32WLX) + if (LL_ADC_INJ_IsConversionOngoing(adc)) { + LL_ADC_INJ_StopConversion(adc); + while (LL_ADC_INJ_IsConversionOngoing(adc)) { + } + } +#endif + + LL_ADC_Disable(adc); + + /* Wait ADC is fully disabled so that we don't leave the driver into intermediate state + * which could prevent enabling the peripheral + */ + while (LL_ADC_IsEnabled(adc) == 1UL) { + } +} + #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) #define HAS_CALIBRATION @@ -369,7 +462,7 @@ static void adc_stm32_start_conversion(const struct device *dev) #define ADC_DELAY_CALIB_ADC_CYCLES LL_ADC_DELAY_DISABLE_CALIB_ADC_CYCLES #endif -static void adc_stm32_calib_delay(const struct device *dev) +static void adc_stm32_calibration_delay(const struct device *dev) { /* * Calibration of F1 and F3 (ADC1_V2_5) must start two cycles after ADON @@ -397,7 +490,7 @@ static void adc_stm32_calib_delay(const struct device *dev) } } -static void adc_stm32_calib(const struct device *dev) +static void adc_stm32_calibration_start(const struct device *dev) { const struct adc_stm32_cfg *config = (const struct adc_stm32_cfg *)dev->config; @@ -429,54 +522,60 @@ static void adc_stm32_calib(const struct device *dev) while (LL_ADC_IsCalibrationOnGoing(adc)) { } } -#endif -/* - * Disable ADC peripheral, and wait until it is disabled - */ -static void adc_stm32_disable(ADC_TypeDef *adc) +static int adc_stm32_calibrate(const struct device *dev) { - if (LL_ADC_IsEnabled(adc) != 1UL) { - return; - } - - /* Stop ongoing conversion if any - * Software must poll ADSTART (or JADSTART) until the bit is reset before assuming - * the ADC is completely stopped. - */ + const struct adc_stm32_cfg *config = + (const struct adc_stm32_cfg *)dev->config; + ADC_TypeDef *adc = config->base; + int err; -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) - if (LL_ADC_REG_IsConversionOngoing(adc)) { - LL_ADC_REG_StopConversion(adc); - while (LL_ADC_REG_IsConversionOngoing(adc)) { - } - } -#endif +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) + adc_stm32_disable(adc); + adc_stm32_calibration_start(dev); + adc_stm32_calibration_delay(dev); +#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ -#if !defined(CONFIG_SOC_SERIES_STM32C0X) && \ - !defined(CONFIG_SOC_SERIES_STM32F0X) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) && \ - !defined(CONFIG_SOC_SERIES_STM32G0X) && \ - !defined(CONFIG_SOC_SERIES_STM32L0X) && \ - !defined(CONFIG_SOC_SERIES_STM32WBAX) && \ - !defined(CONFIG_SOC_SERIES_STM32WLX) - if (LL_ADC_INJ_IsConversionOngoing(adc)) { - LL_ADC_INJ_StopConversion(adc); - while (LL_ADC_INJ_IsConversionOngoing(adc)) { - } + err = adc_stm32_enable(adc); + if (err < 0) { + return err; } -#endif - LL_ADC_Disable(adc); +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) + adc_stm32_calibration_delay(dev); + adc_stm32_calibration_start(dev); +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ - /* Wait ADC is fully disabled so that we don't leave the driver into intermediate state - * which could prevent enabling the peripheral +#ifdef CONFIG_SOC_SERIES_STM32H7X + /* + * To ensure linearity the factory calibration values + * should be loaded on initialization. */ - while (LL_ADC_IsEnabled(adc) == 1UL) { + uint32_t channel_offset = 0U; + uint32_t linear_calib_buffer = 0U; + + if (adc == ADC1) { + channel_offset = 0UL; + } else if (adc == ADC2) { + channel_offset = 8UL; + } else /*Case ADC3*/ { + channel_offset = 16UL; } + /* Read factory calibration factors */ + for (uint32_t count = 0UL; count < ADC_LINEAR_CALIB_REG_COUNT; count++) { + linear_calib_buffer = *(uint32_t *)( + ADC_LINEAR_CALIB_REG_1_ADDR + channel_offset + count + ); + LL_ADC_SetCalibrationLinearFactor( + adc, LL_ADC_CALIB_LINEARITY_WORD1 << count, + linear_calib_buffer + ); + } +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + + return 0; } +#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) */ #if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ !defined(CONFIG_SOC_SERIES_STM32F1X) && \ @@ -609,52 +708,6 @@ static int adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio) } #endif /* CONFIG_SOC_SERIES_STM32xxx */ -/* - * Enable ADC peripheral, and wait until ready if required by SOC. - */ -static int adc_stm32_enable(ADC_TypeDef *adc) -{ - if (LL_ADC_IsEnabled(adc) == 1UL) { - return 0; - } - -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) - LL_ADC_ClearFlag_ADRDY(adc); - LL_ADC_Enable(adc); - - /* - * Enabling ADC modules in many series may fail if they are - * still not stabilized, this will wait for a short time (about 1ms) - * to ensure ADC modules are properly enabled. - */ - uint32_t count_timeout = 0; - - while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { -#ifdef CONFIG_SOC_SERIES_STM32F0X - /* For F0, continue to write ADEN=1 until ADRDY=1 */ - if (LL_ADC_IsEnabled(adc) == 0UL) { - LL_ADC_Enable(adc); - } -#endif /* CONFIG_SOC_SERIES_STM32F0X */ - count_timeout++; - k_busy_wait(100); - if (count_timeout >= 10) { - return -ETIMEDOUT; - } - } -#else - /* - * On STM32F1, F2, F37x, F4, F7 and L1, do not re-enable the ADC. - * On F1 and F37x if ADON holds 1 (LL_ADC_IsEnabled is true) and 1 is - * written, then conversion starts. That's not what is expected. - */ - LL_ADC_Enable(adc); -#endif - - return 0; -} - #ifdef CONFIG_ADC_STM32_DMA static void dma_callback(const struct device *dev, void *user_data, uint32_t channel, int status) @@ -899,12 +952,8 @@ static int start_read(const struct device *dev, #endif /* HAS_OVERSAMPLING */ if (sequence->calibrate) { -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) - - /* we cannot calibrate the ADC while the ADC is enabled */ - adc_stm32_disable(adc); - adc_stm32_calib(dev); +#if defined(HAS_CALIBRATION) + adc_stm32_calibrate(dev); #else LOG_ERR("Calibration not supported"); return -ENOTSUP; @@ -1236,6 +1285,8 @@ static int adc_stm32_init(const struct device *dev) ADC_TypeDef *adc = (ADC_TypeDef *)config->base; int err; + ARG_UNUSED(adc); /* Necessary to avoid warnings on some series */ + LOG_DBG("Initializing %s", dev->name); if (!device_is_ready(clk)) { @@ -1264,6 +1315,7 @@ static int adc_stm32_init(const struct device *dev) LOG_ERR("ADC pinctrl setup failed (%d)", err); return err; } + #if defined(CONFIG_SOC_SERIES_STM32U5X) /* Enable the independent analog supply */ LL_PWR_EnableVDDA(); @@ -1306,51 +1358,12 @@ static int adc_stm32_init(const struct device *dev) k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); #endif -#if defined(HAS_CALIBRATION) && !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) - adc_stm32_disable(adc); - adc_stm32_calib(dev); - adc_stm32_calib_delay(dev); -#endif /* HAS_CALIBRATION && !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ - - err = adc_stm32_enable(adc); - if (err < 0) { - return err; - } - config->irq_cfg_func(); -#if defined(HAS_CALIBRATION) && DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) - adc_stm32_calib_delay(dev); - adc_stm32_calib(dev); - LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE); -#endif /* HAS_CALIBRATION && DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ - -#ifdef CONFIG_SOC_SERIES_STM32H7X - /* - * To ensure linearity the factory calibration values - * should be loaded on initialization. - */ - uint32_t channel_offset = 0U; - uint32_t linear_calib_buffer = 0U; +#if defined(HAS_CALIBRATION) + adc_stm32_calibrate(dev); +#endif /* HAS_CALIBRATION */ - if (adc == ADC1) { - channel_offset = 0UL; - } else if (adc == ADC2) { - channel_offset = 8UL; - } else /*Case ADC3*/ { - channel_offset = 16UL; - } - /* Read factory calibration factors */ - for (uint32_t count = 0UL; count < ADC_LINEAR_CALIB_REG_COUNT; count++) { - linear_calib_buffer = *(uint32_t *)( - ADC_LINEAR_CALIB_REG_1_ADDR + channel_offset + count - ); - LL_ADC_SetCalibrationLinearFactor( - adc, LL_ADC_CALIB_LINEARITY_WORD1 << count, - linear_calib_buffer - ); - } -#endif adc_context_unlock_unconditionally(&data->ctx); return 0; From 479ba144a7d832f46982c04d3823c058690d02ea Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 13 Oct 2023 12:08:31 +0200 Subject: [PATCH 3214/4498] drivers: adc: stm32: enable PM Enable PM for STM32 ADC. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 89 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index a4f0d585b47..12a38c415fd 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #if defined(CONFIG_SOC_SERIES_STM32U5X) #include @@ -1341,12 +1342,9 @@ static int adc_stm32_init(const struct device *dev) * mode, and restore its calibration parameters if there are some * previously stored calibration parameters. */ - LL_ADC_DisableDeepPowerDown(adc); -#elif defined(CONFIG_SOC_SERIES_STM32WLX) - /* The ADC clock must be disabled by clock gating during CPU1 sleep/stop */ - LL_APB2_GRP1_DisableClockSleep(LL_APB2_GRP1_PERIPH_ADC); #endif + /* * Many ADC modules need some time to be stabilized before performing * any enable or calibration actions. @@ -1369,6 +1367,85 @@ static int adc_stm32_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int adc_stm32_suspend_setup(const struct device *dev) +{ + const struct adc_stm32_cfg *config = dev->config; + ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + int err; + + /* Disable ADC */ + adc_stm32_disable(adc); + +#if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + /* Disable ADC internal voltage regulator */ + LL_ADC_DisableInternalRegulator(adc); + while (LL_ADC_IsInternalRegulatorEnabled(adc) == 1U) { + } +#endif + +#if defined(CONFIG_SOC_SERIES_STM32L4X) || \ + defined(CONFIG_SOC_SERIES_STM32L5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBX) || \ + defined(CONFIG_SOC_SERIES_STM32G4X) || \ + defined(CONFIG_SOC_SERIES_STM32H5X) || \ + defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32U5X) + /* + * L4, WB, G4, H5, H7 and U5 series STM32 needs to be put into + * deep sleep mode. + */ + + LL_ADC_EnableDeepPowerDown(adc); +#endif + +#if defined(CONFIG_SOC_SERIES_STM32U5X) + /* Disable the independent analog supply */ + LL_PWR_DisableVDDA(); +#endif /* CONFIG_SOC_SERIES_STM32U5X */ + + /* Stop device clock. Note: fixed clocks are not handled yet. */ + err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken[0]); + if (err != 0) { + LOG_ERR("Could not disable ADC clock"); + return err; + } + + /* Move pins to sleep state */ + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); + if ((err < 0) && (err != -ENOENT)) { + /* + * If returning -ENOENT, no pins where defined for sleep mode : + * Do not output on console (might sleep already) when going to sleep, + * "ADC pinctrl sleep state not available" + * and don't block PM suspend. + * Else return the error. + */ + return err; + } + + return 0; +} + +static int adc_stm32_pm_action(const struct device *dev, + enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: + return adc_stm32_init(dev); + case PM_DEVICE_ACTION_SUSPEND: + return adc_stm32_suspend_setup(dev); + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + static const struct adc_driver_api api_stm32_driver_api = { .channel_setup = adc_stm32_channel_setup, .read = adc_stm32_read, @@ -1531,8 +1608,10 @@ static struct adc_stm32_data adc_stm32_data_##index = { \ ADC_DMA_CHANNEL(index, dmamux, NULL, PERIPHERAL, MEMORY) \ }; \ \ +PM_DEVICE_DT_INST_DEFINE(index, adc_stm32_pm_action); \ + \ DEVICE_DT_INST_DEFINE(index, \ - &adc_stm32_init, NULL, \ + &adc_stm32_init, PM_DEVICE_DT_INST_GET(index), \ &adc_stm32_data_##index, &adc_stm32_cfg_##index, \ POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ &api_stm32_driver_api); From 2caf720c51c459864636ba2fd43d08fb78acbe74 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Fri, 20 Oct 2023 11:10:22 +0200 Subject: [PATCH 3215/4498] samples: board: stm32 pm: add adc power management sample Add a sample for STM32 ADC power management Signed-off-by: Guillaume Gautier --- .../stm32/power_mgmt/adc/CMakeLists.txt | 7 ++ .../boards/stm32/power_mgmt/adc/README.rst | 42 ++++++++ .../adc/boards/nucleo_g474re.overlay | 27 ++++++ .../adc/boards/nucleo_wb55rg.overlay | 26 +++++ .../adc/boards/nucleo_wba52cg.overlay | 12 +++ samples/boards/stm32/power_mgmt/adc/prj.conf | 6 ++ .../boards/stm32/power_mgmt/adc/sample.yaml | 17 ++++ .../boards/stm32/power_mgmt/adc/src/main.c | 97 +++++++++++++++++++ 8 files changed, 234 insertions(+) create mode 100644 samples/boards/stm32/power_mgmt/adc/CMakeLists.txt create mode 100644 samples/boards/stm32/power_mgmt/adc/README.rst create mode 100644 samples/boards/stm32/power_mgmt/adc/boards/nucleo_g474re.overlay create mode 100644 samples/boards/stm32/power_mgmt/adc/boards/nucleo_wb55rg.overlay create mode 100644 samples/boards/stm32/power_mgmt/adc/boards/nucleo_wba52cg.overlay create mode 100644 samples/boards/stm32/power_mgmt/adc/prj.conf create mode 100644 samples/boards/stm32/power_mgmt/adc/sample.yaml create mode 100644 samples/boards/stm32/power_mgmt/adc/src/main.c diff --git a/samples/boards/stm32/power_mgmt/adc/CMakeLists.txt b/samples/boards/stm32/power_mgmt/adc/CMakeLists.txt new file mode 100644 index 00000000000..b0eea852bf5 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stm32_pm_adc) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/power_mgmt/adc/README.rst b/samples/boards/stm32/power_mgmt/adc/README.rst new file mode 100644 index 00000000000..2ec694884fa --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/README.rst @@ -0,0 +1,42 @@ +.. _stm32-pm-adc-sample: + +STM32 PM ADC +############ + +Overview +******** + +This sample is a minimum application to demonstrate basic power management +behavior in a basic ADC set up in low power context. + +.. _stm32-pm-adc-sample-requirements: + +Requirements +************ + +The board should support enabling PM. For a STM32 based target, it means that +it should support a clock source alternative to Cortex Systick that can be used +in core sleep states, as LPTIM (:dtcompatible:`st,stm32-lptim`). + +Building and Running +******************** + +Build and flash as follows, changing ``nucleo_wb55rg`` for your board: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/power_mgmt/adc + :board: nucleo_wb55rg + :goals: build flash + :compact: + +After flashing, the console shows the ADC measurement in the form: +``ADC reading[0]:`` +``- adc@50040000, channel 3: 1158 = 932 mV`` + +PM configurations +***************** + +By default, :kconfig:option:`CONFIG_PM_DEVICE` and :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME` are +enabled. +On STM32WB, we can observe a power consumption of about 25µA with both kconfig +enabled, 27.5µA without (each time with :kconfig:option:`CONFIG_PM` enabled). diff --git a/samples/boards/stm32/power_mgmt/adc/boards/nucleo_g474re.overlay b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_g474re.overlay new file mode 100644 index 00000000000..bde07e0f2d6 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_g474re.overlay @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +#include + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 1>; + }; +}; + +&adc1 { + #address-cells = <1>; + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wb55rg.overlay b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wb55rg.overlay new file mode 100644 index 00000000000..6a39f681c45 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wb55rg.overlay @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 3>; + }; +}; + +&adc1 { + pinctrl-0 = <&adc1_in3_pc2>; + #address-cells = <1>; + #size-cells = <0>; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wba52cg.overlay b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wba52cg.overlay new file mode 100644 index 00000000000..3cd6cb64bf5 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/boards/nucleo_wba52cg.overlay @@ -0,0 +1,12 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc4 8>; + }; +}; diff --git a/samples/boards/stm32/power_mgmt/adc/prj.conf b/samples/boards/stm32/power_mgmt/adc/prj.conf new file mode 100644 index 00000000000..c5359fe0238 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/prj.conf @@ -0,0 +1,6 @@ +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y +CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n +CONFIG_ADC=y +#CONFIG_DEBUG=y diff --git a/samples/boards/stm32/power_mgmt/adc/sample.yaml b/samples/boards/stm32/power_mgmt/adc/sample.yaml new file mode 100644 index 00000000000..e27cc5b268d --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/sample.yaml @@ -0,0 +1,17 @@ +sample: + name: STM32 ADC Power Management +tests: + sample.boards.stm32.power_mgmt.adc: + tags: + - ADC + - power + harness: console + harness_config: + type: one_line + regex: + - "Device ready" + filter: dt_compat_enabled("zephyr,power-state") and + dt_compat_enabled("st,stm32-adc") and + dt_compat_enabled("st,stm32-lptim") + extra_args: "CONFIG_DEBUG=y" + platform_allow: nucleo_wb55rg diff --git a/samples/boards/stm32/power_mgmt/adc/src/main.c b/samples/boards/stm32/power_mgmt/adc/src/main.c new file mode 100644 index 00000000000..b75ab4a9af2 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/adc/src/main.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define SLEEP_TIME_MS 2000 + +#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \ + !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels) +#error "No suitable devicetree overlay specified" +#endif + +#define DT_SPEC_AND_COMMA(node_id, prop, idx) \ + ADC_DT_SPEC_GET_BY_IDX(node_id, idx), + +/* Data of ADC io-channels specified in devicetree. */ +static const struct adc_dt_spec adc_channels[] = { + DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, + DT_SPEC_AND_COMMA) +}; + +int main(void) +{ + int err; + uint32_t count = 0; + uint16_t buf; + struct adc_sequence sequence = { + .buffer = &buf, + /* buffer size in bytes, not number of samples */ + .buffer_size = sizeof(buf), + }; + + /* Configure channels individually prior to sampling. */ + for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) { + if (!adc_is_ready_dt(&adc_channels[i])) { + printk("ADC controller device %s not ready\n", adc_channels[i].dev->name); + return 0; + } + + err = adc_channel_setup_dt(&adc_channels[i]); + if (err < 0) { + printk("Could not setup channel #%d (%d)\n", i, err); + return 0; + } + } + + printk("Device ready\n"); + + while (true) { + printk("ADC reading[%u]:\n", count++); + for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) { + int32_t val_mv; + + printk("- %s, channel %d: ", + adc_channels[i].dev->name, + adc_channels[i].channel_id); + + (void)adc_sequence_init_dt(&adc_channels[i], &sequence); + + err = adc_read_dt(&adc_channels[i], &sequence); + if (err < 0) { + printk("Could not read (%d)\n", err); + continue; + } + + /* + * If using differential mode, the 16 bit value + * in the ADC sample buffer should be a signed 2's + * complement value. + */ + if (adc_channels[i].channel_cfg.differential) { + val_mv = (int32_t)((int16_t)buf); + } else { + val_mv = (int32_t)buf; + } + printk("%"PRId32, val_mv); + err = adc_raw_to_millivolts_dt(&adc_channels[i], + &val_mv); + /* conversion to mV may not be supported, skip if not */ + if (err < 0) { + printk(" (value in mV not available)\n"); + } else { + printk(" = %"PRId32" mV\n", val_mv); + } + } + + k_msleep(SLEEP_TIME_MS); + } + return 0; +} From bda3b101d321fd3e087485c085d7f3336b5a7e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sat, 4 Nov 2023 09:08:15 +0700 Subject: [PATCH 3216/4498] serial: nxp_s32: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles --- drivers/serial/uart_nxp_s32_linflexd.c | 313 +++++++------------------ drivers/serial/uart_nxp_s32_linflexd.h | 10 +- soc/arm/nxp_s32/s32ze/soc.h | 3 + 3 files changed, 88 insertions(+), 238 deletions(-) diff --git a/drivers/serial/uart_nxp_s32_linflexd.c b/drivers/serial/uart_nxp_s32_linflexd.c index fe1c6c51f86..aeb8925da9f 100644 --- a/drivers/serial/uart_nxp_s32_linflexd.c +++ b/drivers/serial/uart_nxp_s32_linflexd.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_linflexd + #include #include #include @@ -243,45 +245,54 @@ static void uart_nxp_s32_irq_callback_set(const struct device *dev, data->cb_data = cb_data; } -/** - * @brief Interrupt service routine. - * - * This simply calls the callback function, if one exists. - * - * Note: s32 UART Tx interrupts when ready to send; Rx interrupts when char - * received. - * - * @param arg Argument to ISR. - * - * @return N/A - */ - void uart_nxp_s32_isr(const struct device *dev) { + const struct uart_nxp_s32_config *config = dev->config; + + Linflexd_Uart_Ip_IRQHandler(config->instance); +} + +static void uart_nxp_s32_event_handler(const uint8 instance, + Linflexd_Uart_Ip_EventType event, + void *user_data) +{ + const struct device *dev = (const struct device *)user_data; + const struct uart_nxp_s32_config *config = dev->config; struct uart_nxp_s32_data *data = dev->data; + struct uart_nxp_s32_int *int_data = &(data->int_data); + Linflexd_Uart_Ip_StatusType status; - if (data->callback) { - data->callback(dev, data->cb_data); + if (event == LINFLEXD_UART_IP_EVENT_END_TRANSFER) { + /* + * Check the previous UART transmit has finished + * because Rx may also trigger this event + */ + status = Linflexd_Uart_Ip_GetTransmitStatus(config->instance, NULL); + if (status != LINFLEXD_UART_IP_STATUS_BUSY) { + int_data->tx_fifo_busy = false; + if (data->callback) { + data->callback(dev, data->cb_data); + } + } + } else if (event == LINFLEXD_UART_IP_EVENT_RX_FULL) { + int_data->rx_fifo_busy = false; + if (data->callback) { + data->callback(dev, data->cb_data); + } + } else if (event == LINFLEXD_UART_IP_EVENT_ERROR) { + if (data->callback) { + data->callback(dev, data->cb_data); + } + } else { + /* Other events are not used */ } } + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -/** - * @brief Initialize UART channel - * - * This routine is called to reset the chip in a quiescent state. - * It is assumed that this function is called only once per UART. - * - * @param dev UART device struct - * - * @return 0 - */ static int uart_nxp_s32_init(const struct device *dev) { const struct uart_nxp_s32_config *config = dev->config; - struct uart_nxp_s32_data *data = dev->data; - static uint8_t state_idx; - uint8_t key; int err; err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); @@ -289,24 +300,7 @@ static int uart_nxp_s32_init(const struct device *dev) return err; } - key = irq_lock(); - - /* Initialize UART with default configuration */ - data->hw_cfg.BaudRate = 115200; - data->hw_cfg.BaudRateMantissa = 26U; - data->hw_cfg.BaudRateFractionalDivisor = 1U; - data->hw_cfg.ParityCheck = false; - data->hw_cfg.ParityType = LINFLEXD_UART_IP_PARITY_EVEN; - data->hw_cfg.StopBitsCount = LINFLEXD_UART_IP_ONE_STOP_BIT; - data->hw_cfg.WordLength = LINFLEXD_UART_IP_8_BITS; - data->hw_cfg.TransferType = LINFLEXD_UART_IP_USING_INTERRUPTS; - data->hw_cfg.Callback = s32_uart_callback; - data->hw_cfg.CallbackParam = NULL; - data->hw_cfg.StateStruct = &Linflexd_Uart_Ip_apStateStructure[state_idx++]; - - Linflexd_Uart_Ip_Init(config->instance, &data->hw_cfg); - - irq_unlock(key); + Linflexd_Uart_Ip_Init(config->instance, &config->hw_cfg); return 0; } @@ -334,207 +328,62 @@ static const struct uart_driver_api uart_nxp_s32_driver_api = { }; -#define UART_NXP_S32_NODE(n) DT_NODELABEL(uart##n) - -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) -#define UART_NXP_S32_INTERRUPT_DEFINE(n, isr_handler, parameter) \ - do { \ - IRQ_CONNECT(DT_IRQN(UART_NXP_S32_NODE(n)), \ - DT_IRQ(UART_NXP_S32_NODE(n), priority), \ - isr_handler, \ - parameter, \ - DT_IRQ(UART_NXP_S32_NODE(n), flags)); \ - \ - irq_enable(DT_IRQN(UART_NXP_S32_NODE(n))); \ +#define UART_NXP_S32_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_LINFLEX_##i##_BASE) ? i : 0) + +#define UART_NXP_S32_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET LINFLEXD_INSTANCE_COUNT, UART_NXP_S32_HW_INSTANCE_CHECK, (|), n) + +#define UART_NXP_S32_INTERRUPT_DEFINE(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + uart_nxp_s32_isr, DEVICE_DT_INST_GET(n), \ + DT_INST_IRQ(n, flags)); \ + irq_enable(DT_INST_IRQN(n)); \ } while (0) -#else -#define UART_NXP_S32_INTERRUPT_DEFINE(n, isr_handler, parameter) -#endif +#define UART_NXP_S32_HW_CONFIG(n) \ + { \ + .BaudRate = 115200, \ + .BaudRateMantissa = 26U, \ + .BaudRateFractionalDivisor = 1U, \ + .ParityCheck = false, \ + .ParityType = LINFLEXD_UART_IP_PARITY_EVEN, \ + .StopBitsCount = LINFLEXD_UART_IP_ONE_STOP_BIT, \ + .WordLength = LINFLEXD_UART_IP_8_BITS, \ + .TransferType = LINFLEXD_UART_IP_USING_INTERRUPTS, \ + .StateStruct = &Linflexd_Uart_Ip_apStateStructure[n], \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( \ + .Callback = uart_nxp_s32_event_handler, \ + .CallbackParam = (void *)DEVICE_DT_INST_GET(n), \ + )) \ + } #define UART_NXP_S32_INIT_DEVICE(n) \ - PINCTRL_DT_DEFINE(UART_NXP_S32_NODE(n)); \ - static struct uart_nxp_s32_data uart_nxp_s32_data_##n; \ + PINCTRL_DT_INST_DEFINE(n); \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (static struct uart_nxp_s32_data uart_nxp_s32_data_##n;)) \ static const struct uart_nxp_s32_config uart_nxp_s32_config_##n = { \ - .instance = n, \ - .base = (LINFLEXD_Type *)DT_REG_ADDR(UART_NXP_S32_NODE(n)), \ - .pincfg = PINCTRL_DT_DEV_CONFIG_GET(UART_NXP_S32_NODE(n)), \ + .instance = UART_NXP_S32_HW_INSTANCE(n), \ + .base = (LINFLEXD_Type *)DT_INST_REG_ADDR(n), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .hw_cfg = UART_NXP_S32_HW_CONFIG(n), \ }; \ static int uart_nxp_s32_init_##n(const struct device *dev) \ { \ - UART_NXP_S32_INTERRUPT_DEFINE(n, Linflexd_Uart_Ip_IRQHandler, n);\ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (UART_NXP_S32_INTERRUPT_DEFINE(n);)) \ \ return uart_nxp_s32_init(dev); \ } \ - DEVICE_DT_DEFINE(UART_NXP_S32_NODE(n), \ + DEVICE_DT_INST_DEFINE(n, \ &uart_nxp_s32_init_##n, \ NULL, \ - &uart_nxp_s32_data_##n, \ + COND_CODE_1(CONFIG_UART_INTERRUPT_DRIVEN, \ + (&uart_nxp_s32_data_##n), (NULL)), \ &uart_nxp_s32_config_##n, \ PRE_KERNEL_1, \ CONFIG_SERIAL_INIT_PRIORITY, \ &uart_nxp_s32_driver_api); -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(0), okay) -UART_NXP_S32_INIT_DEVICE(0) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(1), okay) -UART_NXP_S32_INIT_DEVICE(1) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(2), okay) -UART_NXP_S32_INIT_DEVICE(2) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(3), okay) -UART_NXP_S32_INIT_DEVICE(3) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(4), okay) -UART_NXP_S32_INIT_DEVICE(4) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(5), okay) -UART_NXP_S32_INIT_DEVICE(5) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(6), okay) -UART_NXP_S32_INIT_DEVICE(6) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(7), okay) -UART_NXP_S32_INIT_DEVICE(7) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(8), okay) -UART_NXP_S32_INIT_DEVICE(8) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(9), okay) -UART_NXP_S32_INIT_DEVICE(9) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(10), okay) -UART_NXP_S32_INIT_DEVICE(10) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(11), okay) -UART_NXP_S32_INIT_DEVICE(11) -#endif - -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(12), okay) -UART_NXP_S32_INIT_DEVICE(12) -#endif - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -static void s32_uart_device_event(const struct device *dev, Linflexd_Uart_Ip_EventType event, - void *user_data) -{ - const struct uart_nxp_s32_config *config = dev->config; - struct uart_nxp_s32_data *data = dev->data; - struct uart_nxp_s32_int *int_data = &(data->int_data); - Linflexd_Uart_Ip_StatusType status; - - ARG_UNUSED(user_data); - - if (event == LINFLEXD_UART_IP_EVENT_END_TRANSFER) { - /* - * Check the previous UART transmit has finished - * because Rx may also trigger this event - */ - status = Linflexd_Uart_Ip_GetTransmitStatus(config->instance, NULL); - if (status != LINFLEXD_UART_IP_STATUS_BUSY) { - int_data->tx_fifo_busy = false; - uart_nxp_s32_isr(dev); - } - } else if (event == LINFLEXD_UART_IP_EVENT_RX_FULL) { - int_data->rx_fifo_busy = false; - uart_nxp_s32_isr(dev); - } else if (event == LINFLEXD_UART_IP_EVENT_ERROR) { - uart_nxp_s32_isr(dev); - } else { - /* Other events are not used */ - } -} - -void s32_uart_callback(const uint8 instance, Linflexd_Uart_Ip_EventType event, void *user_data) -{ - const struct device *dev; - - switch (instance) { -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(0), okay) - case 0: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(0)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(1), okay) - case 1: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(1)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(2), okay) - case 2: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(2)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(3), okay) - case 3: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(3)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(4), okay) - case 4: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(4)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(5), okay) - case 5: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(5)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(6), okay) - case 6: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(6)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(7), okay) - case 7: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(7)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(8), okay) - case 8: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(8)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(9), okay) - case 9: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(9)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(10), okay) - case 10: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(10)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(11), okay) - case 11: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(11)); - break; -#endif -#if DT_NODE_HAS_STATUS(UART_NXP_S32_NODE(12), okay) - case 12: - dev = DEVICE_DT_GET(UART_NXP_S32_NODE(12)); - break; -#endif - default: - dev = NULL; - break; - } - - if (dev != NULL) { - s32_uart_device_event(dev, event, user_data); - } -} -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +DT_INST_FOREACH_STATUS_OKAY(UART_NXP_S32_INIT_DEVICE) diff --git a/drivers/serial/uart_nxp_s32_linflexd.h b/drivers/serial/uart_nxp_s32_linflexd.h index ce5180c26c1..997cd1e9112 100644 --- a/drivers/serial/uart_nxp_s32_linflexd.h +++ b/drivers/serial/uart_nxp_s32_linflexd.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ struct uart_nxp_s32_config { uint32_t instance; LINFLEXD_Type *base; const struct pinctrl_dev_config *pincfg; + Linflexd_Uart_Ip_UserConfigType hw_cfg; }; #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -23,16 +24,13 @@ struct uart_nxp_s32_int { }; #endif -struct uart_nxp_s32_data { - Linflexd_Uart_Ip_UserConfigType hw_cfg; - #ifdef CONFIG_UART_INTERRUPT_DRIVEN +struct uart_nxp_s32_data { struct uart_nxp_s32_int int_data; uart_irq_callback_user_data_t callback; void *cb_data; -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ - }; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ extern Linflexd_Uart_Ip_StateStructureType Linflexd_Uart_Ip_apStateStructure[LINFLEXD_UART_IP_NUMBER_OF_INSTANCES]; diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index cc13dfcc6aa..cdee74ad54c 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -15,4 +15,7 @@ /* SIUL2 */ #define IP_SIUL2_2_BASE 0U /* instance does not exist on this SoC */ +/* LINFlexD*/ +#define IP_LINFLEX_12_BASE IP_MSC_0_LIN_BASE + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From 8816852c2cf0f74c17ce0ede8a402bec823d35e1 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 26 Oct 2023 19:40:59 +0100 Subject: [PATCH 3217/4498] doc: dts: api: update the inter-node dependencies documentation Update the inter-node dependencies documentation to clarify the child node dependency inheritance recently introduced in 403640b75e. Signed-off-by: Fabio Baltieri --- doc/build/dts/api/api.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 7d802838041..f452d0f5281 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -140,6 +140,7 @@ depends on" relation: - a node directly depends on any nodes its properties refer to by phandle - a node directly depends on its ``interrupt-parent`` if it has an ``interrupts`` property +- a parent node inherits all dependencies from its child nodes A *dependency ordering* of a devicetree is a list of its nodes, where each node ``n`` appears earlier in the list than any nodes that depend on ``n``. A node's From d2c101d466f5260e68054e6fd37c16fd19291833 Mon Sep 17 00:00:00 2001 From: Alexander Razinkov Date: Fri, 27 Oct 2023 18:33:15 +0300 Subject: [PATCH 3218/4498] kernel: init: conditional .bss section zeroing Some platforms already have .bss section zeroed-out externally before the Zephyr initialization and there is no sence to zero it out the second time from the SW. Such boot-time optimization could be critical e.g. for RTL Simulation. Signed-off-by: Alexander Razinkov --- arch/Kconfig | 2 ++ kernel/Kconfig | 10 ++++++++++ kernel/init.c | 7 +------ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 65b73557f7b..0a108702ad9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -139,6 +139,8 @@ config ARCH_POSIX select NATIVE_BUILD select HAS_COVERAGE_SUPPORT select BARRIER_OPERATIONS_BUILTIN + # native_posix gets its memory cleared on entry by the host OS + select SKIP_BSS_CLEAR help POSIX (native) architecture diff --git a/kernel/Kconfig b/kernel/Kconfig index 4cdd6209264..6280e80a400 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -382,6 +382,16 @@ config INIT_STACKS water mark can be easily determined. This applies to the stack areas for threads, as well as to the interrupt stack. +config SKIP_BSS_CLEAR + bool + help + This option disables software .bss section zeroing during Zephyr + initialization. Such boot-time optimization could be used for + platforms where .bss section is zeroed-out externally. + Please pay attention that when this option is enabled + the responsibility for .bss zeroing in all possible scenarios + (mind e.g. SW reset) is delegated to the external SW or HW. + config BOOT_BANNER bool "Boot banner" default y diff --git a/kernel/init.c b/kernel/init.c index c2109499a07..e4637d3aff1 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -165,12 +165,7 @@ void __weak z_early_memcpy(void *dst, const void *src, size_t n) __boot_func void z_bss_zero(void) { - if (IS_ENABLED(CONFIG_ARCH_POSIX)) { - /* native_posix gets its memory cleared on entry by - * the host OS, and in any case the host clang/lld - * doesn't emit the __bss_end symbol this code expects - * to see - */ + if (IS_ENABLED(CONFIG_SKIP_BSS_CLEAR)) { return; } From 9bdff044f06ed7062d171b54f223649724b592ce Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 20:35:32 +0100 Subject: [PATCH 3219/4498] drivers: mfd: add AD5592 MFD driver This commit introduces a driver for Analog AD5592 8-channel, configurable ADC/DAC/GPIO chip. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/mfd/CMakeLists.txt | 1 + drivers/mfd/Kconfig | 1 + drivers/mfd/Kconfig.ad5592 | 10 ++ drivers/mfd/mfd_ad5592.c | 169 ++++++++++++++++++++++++++++ dts/bindings/mfd/adi,ad5592.yaml | 13 +++ include/zephyr/drivers/mfd/ad5592.h | 91 +++++++++++++++ 7 files changed, 286 insertions(+) create mode 100644 drivers/mfd/Kconfig.ad5592 create mode 100644 drivers/mfd/mfd_ad5592.c create mode 100644 dts/bindings/mfd/adi,ad5592.yaml create mode 100644 include/zephyr/drivers/mfd/ad5592.h diff --git a/CODEOWNERS b/CODEOWNERS index 8172acd9c90..335e9191c6e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -373,6 +373,7 @@ /drivers/led_strip/ @mbolivar-ampere /drivers/lora/ @Mani-Sadhasivam /drivers/mbox/ @carlocaione +/drivers/mfd/mfd_ad5592.c @bbilas /drivers/mfd/mfd_max20335.c @bbilas /drivers/misc/ @tejlmand /drivers/misc/ft8xx/ @hubertmis diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index 7c5e048fcc6..5141a86c2ee 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -8,3 +8,4 @@ zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c) zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c) +zephyr_library_sources_ifdef(CONFIG_MFD_AD5592 mfd_ad5592.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 1a80cf446f5..1a400d6383e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -18,6 +18,7 @@ config MFD_INIT_PRIORITY help Multi-function devices initialization priority. +source "drivers/mfd/Kconfig.ad5592" source "drivers/mfd/Kconfig.axp192" source "drivers/mfd/Kconfig.max20335" source "drivers/mfd/Kconfig.nct38xx" diff --git a/drivers/mfd/Kconfig.ad5592 b/drivers/mfd/Kconfig.ad5592 new file mode 100644 index 00000000000..8b94f5517cb --- /dev/null +++ b/drivers/mfd/Kconfig.ad5592 @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +config MFD_AD5592 + bool "Analog AD5592 SPI configurable ADC/DAC/GPIO chip" + default y + depends on DT_HAS_ADI_AD5592_ENABLED + depends on SPI + help + Enable driver for Analog AD5592. diff --git a/drivers/mfd/mfd_ad5592.c b/drivers/mfd/mfd_ad5592.c new file mode 100644 index 00000000000..d8f8f60de39 --- /dev/null +++ b/drivers/mfd/mfd_ad5592.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_ad5592 + +#include +#include +#include +#include + +#include + +#define AD5592_GPIO_READBACK_EN BIT(10) +#define AD5592_LDAC_READBACK_EN BIT(6) +#define AD5592_REG_SOFTWARE_RESET 0x0FU +#define AD5592_SOFTWARE_RESET_MAGIC_VAL 0xDAC +#define AD5592_REV_VAL_MASK 0x3FF +#define AD5592_REG_SHIFT_VAL 11 +#define AD5592_REG_READBACK_SHIFT_VAL 2 + +#define AD5592_SPI_SPEC_CONF (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \ + SPI_OP_MODE_MASTER | SPI_MODE_CPOL) + +struct mfd_ad5592_config { + struct gpio_dt_spec reset_gpio; + struct spi_dt_spec bus; +}; + +int mfd_ad5592_read_raw(const struct device *dev, uint16_t *val) +{ + const struct mfd_ad5592_config *config = dev->config; + uint16_t nop_msg = 0; + + struct spi_buf tx_buf[] = { + { + .buf = &nop_msg, + .len = sizeof(nop_msg) + } + }; + + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = 1 + }; + + struct spi_buf rx_buf[] = { + { + .buf = val, + .len = sizeof(uint16_t) + } + }; + + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = 1 + }; + + return spi_transceive_dt(&config->bus, &tx, &rx); +} + +int mfd_ad5592_write_raw(const struct device *dev, uint16_t val) +{ + const struct mfd_ad5592_config *config = dev->config; + + struct spi_buf tx_buf[] = { + { + .buf = &val, + .len = sizeof(val) + } + }; + + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = 1 + }; + + return spi_write_dt(&config->bus, &tx); +} + +int mfd_ad5592_read_reg(const struct device *dev, uint8_t reg, uint8_t reg_data, uint16_t *val) +{ + uint16_t data; + uint16_t msg; + int ret; + + switch (reg) { + case AD5592_REG_GPIO_INPUT_EN: + msg = sys_cpu_to_be16(AD5592_GPIO_READBACK_EN | + (AD5592_REG_GPIO_INPUT_EN << AD5592_REG_SHIFT_VAL) | + reg_data); + break; + default: + msg = sys_cpu_to_be16(AD5592_LDAC_READBACK_EN | + (AD5592_REG_READ_AND_LDAC << AD5592_REG_SHIFT_VAL) | + reg << AD5592_REG_READBACK_SHIFT_VAL); + break; + } + + ret = mfd_ad5592_write_raw(dev, msg); + if (ret < 0) { + return ret; + } + + ret = mfd_ad5592_read_raw(dev, &data); + if (ret < 0) { + return ret; + } + + *val = sys_be16_to_cpu(data); + + return 0; +} + +int mfd_ad5592_write_reg(const struct device *dev, uint8_t reg, uint16_t val) +{ + uint16_t msg = sys_cpu_to_be16((reg << AD5592_REG_SHIFT_VAL) | (val & AD5592_REV_VAL_MASK)); + + return mfd_ad5592_write_raw(dev, msg); +} + +static int mfd_add592_software_reset(const struct device *dev) +{ + return mfd_ad5592_write_reg(dev, + AD5592_REG_SOFTWARE_RESET, + AD5592_SOFTWARE_RESET_MAGIC_VAL); +} + +static int mfd_ad5592_init(const struct device *dev) +{ + const struct mfd_ad5592_config *config = dev->config; + int ret; + + if (!spi_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + if (!gpio_is_ready_dt(&config->reset_gpio)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + + ret = mfd_add592_software_reset(dev); + if (ret < 0) { + return ret; + } + + return 0; +} + +#define MFD_AD5592_DEFINE(inst) \ + static const struct mfd_ad5592_config mfd_ad5592_config_##inst = { \ + .reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios), \ + .bus = SPI_DT_SPEC_INST_GET(inst, AD5592_SPI_SPEC_CONF, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfd_ad5592_init, NULL, \ + NULL, \ + &mfd_ad5592_config_##inst, \ + POST_KERNEL, \ + CONFIG_MFD_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_AD5592_DEFINE); diff --git a/dts/bindings/mfd/adi,ad5592.yaml b/dts/bindings/mfd/adi,ad5592.yaml new file mode 100644 index 00000000000..d3e404ec143 --- /dev/null +++ b/dts/bindings/mfd/adi,ad5592.yaml @@ -0,0 +1,13 @@ +# Copyright (C) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +description: Analog AD5592 ADC/DAC/GPIO chip + +compatible: "adi,ad5592" + +include: spi-device.yaml + +properties: + reset-gpios: + type: phandle-array + description: RESET pin diff --git a/include/zephyr/drivers/mfd/ad5592.h b/include/zephyr/drivers/mfd/ad5592.h new file mode 100644 index 00000000000..014ccdd02ba --- /dev/null +++ b/include/zephyr/drivers/mfd/ad5592.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_AD5592_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_AD5592_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define AD5592_REG_SEQ_ADC 0x02U +#define AD5592_REG_ADC_CONFIG 0x04U +#define AD5592_REG_LDAC_EN 0x05U +#define AD5592_REG_GPIO_PULLDOWN 0x06U +#define AD5592_REG_READ_AND_LDAC 0x07U +#define AD5592_REG_GPIO_OUTPUT_EN 0x08U +#define AD5592_REG_GPIO_SET 0x09U +#define AD5592_REG_GPIO_INPUT_EN 0x0AU +#define AD5592_REG_PD_REF_CTRL 0x0BU + +#define AD5592_EN_REF BIT(9) + +#define AD5592_PIN_MAX 8U + +/** + * @defgroup mdf_interface_ad5592 MFD AD5592 interface + * @ingroup mfd_interfaces + * @{ + */ + +/** + * @brief Read raw data from the chip + * + * @param[in] dev Pointer to MFD device + * @param[in] val Pointer to data buffer + * + * @retval 0 if success + * @retval negative errno if failure + */ +int mfd_ad5592_read_raw(const struct device *dev, uint16_t *val); + +/** + * @brief Write raw data to chip + * + * @param[in] dev Pointer to MFD device + * @param[in] val Data to be written + * + * + * @retval 0 if success + * @retval negative errno if failure + */ +int mfd_ad5592_write_raw(const struct device *dev, uint16_t val); + +/** + * @brief Read data from provided register + * + * @param[in] dev Pointer to MFD device + * @param[in] reg Register to be read + * @param[in] reg_data Additional data passed to selected register + * @param[in] val Pointer to data buffer + * + * @retval 0 if success + * @retval negative errno if failure + */ +int mfd_ad5592_read_reg(const struct device *dev, uint8_t reg, uint8_t reg_data, uint16_t *val); + +/** + * @brief Write data to provided register + * + * @param[in] dev Pointer to MFD device + * @param[in] reg Register to be written + * @param[in] val Data to be written + * + * @retval 0 if success + * @retval negative errno if failure + */ +int mfd_ad5592_write_reg(const struct device *dev, uint8_t reg, uint16_t val); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_AD5952_H_ */ From ad3c5a27b407614cc3500074c451f88b1c3dcbc9 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 20:38:59 +0100 Subject: [PATCH 3220/4498] drivers: adc: add driver for AD5592 Add MFD subdriver for the built-in ADC controller in AD5592 chip. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig | 2 + drivers/adc/Kconfig.ad5592 | 25 +++ drivers/adc/adc_ad5592.c | 255 ++++++++++++++++++++++++ drivers/adc/adc_shell.c | 1 + dts/bindings/adc/adi,ad5592-adc.yaml | 15 ++ tests/drivers/build_all/adc/app.overlay | 50 +++++ tests/drivers/build_all/adc/prj.conf | 1 + 9 files changed, 351 insertions(+) create mode 100644 drivers/adc/Kconfig.ad5592 create mode 100644 drivers/adc/adc_ad5592.c create mode 100644 dts/bindings/adc/adi,ad5592-adc.yaml create mode 100644 tests/drivers/build_all/adc/app.overlay diff --git a/CODEOWNERS b/CODEOWNERS index 335e9191c6e..63fc8876a96 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -245,6 +245,7 @@ /drivers/adc/adc_rpi_pico.c @soburi /drivers/adc/*ads114s0x* @benediktibk /drivers/adc/*max11102_17* @benediktibk +/drivers/adc/adc_ad5592.c @bbilas /drivers/audio/*nrfx* @anangl /drivers/auxdisplay/*pt6314* @xingrz /drivers/auxdisplay/* @thedjnK diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index a22af9a5336..4738aaa891c 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -46,3 +46,4 @@ zephyr_library_sources_ifdef(CONFIG_ADC_TLA2021 adc_tla2021.c) zephyr_library_sources_ifdef(CONFIG_ADC_NXP_S32_ADC_SAR adc_nxp_s32_adc_sar.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX1125X adc_max1125x.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX11102_17 adc_max11102_17.c) +zephyr_library_sources_ifdef(CONFIG_ADC_AD5592 adc_ad5592.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 32cf7601e8d..14f4d89657e 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -116,4 +116,6 @@ source "drivers/adc/Kconfig.max1125x" source "drivers/adc/Kconfig.max11102_17" +source "drivers/adc/Kconfig.ad5592" + endif # ADC diff --git a/drivers/adc/Kconfig.ad5592 b/drivers/adc/Kconfig.ad5592 new file mode 100644 index 00000000000..92b80f34217 --- /dev/null +++ b/drivers/adc/Kconfig.ad5592 @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +config ADC_AD5592 + bool "AD5592 ADC driver" + default y + depends on DT_HAS_ADI_AD5592_ADC_ENABLED + select MFD + help + Enable the AD5592 ADC driver. + +config ADC_AD5592_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the ADC data acquisition thread" + depends on ADC_AD5592 + default 384 + help + Size of the stack used for the internal data acquisition + thread. + +config ADC_AD5592_ACQUISITION_THREAD_PRIO + int "Priority for the ADC data acquisition thread" + depends on ADC_AD5592 + default 0 + help + Priority level for the internal ADC data acquisition thread. diff --git a/drivers/adc/adc_ad5592.c b/drivers/adc/adc_ad5592.c new file mode 100644 index 00000000000..422fd549868 --- /dev/null +++ b/drivers/adc/adc_ad5592.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_ad5592_adc + +#include +#include +#include + +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +#include +LOG_MODULE_REGISTER(adc_ad5592, CONFIG_ADC_LOG_LEVEL); + +#define AD5592_ADC_RESOLUTION 12U +#define AD5592_ADC_MAX_VAL 4096 + +struct adc_ad5592_config { + const struct device *mfd_dev; +}; + +struct adc_ad5592_data { + struct adc_context ctx; + const struct device *dev; + uint8_t adc_conf; + uint16_t *buffer; + uint16_t *repeat_buffer; + uint8_t channels; + struct k_thread thread; + struct k_sem sem; + + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_AD5592_ACQUISITION_THREAD_STACK_SIZE); +}; + +static int adc_ad5592_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + const struct adc_ad5592_config *config = dev->config; + struct adc_ad5592_data *data = dev->data; + + if (channel_cfg->channel_id >= AD5592_PIN_MAX) { + LOG_ERR("invalid channel id %d", channel_cfg->channel_id); + return -EINVAL; + } + + data->adc_conf |= BIT(channel_cfg->channel_id); + + return mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_ADC_CONFIG, data->adc_conf); +} + +static int adc_ad5592_validate_buffer_size(const struct device *dev, + const struct adc_sequence *sequence) +{ + uint8_t channels; + size_t needed; + + channels = POPCOUNT(sequence->channels); + needed = channels * sizeof(uint16_t); + + if (sequence->buffer_size < needed) { + return -ENOMEM; + } + + return 0; +} + +static int adc_ad5592_start_read(const struct device *dev, const struct adc_sequence *sequence) +{ + struct adc_ad5592_data *data = dev->data; + int ret; + + if (sequence->resolution != AD5592_ADC_RESOLUTION) { + LOG_ERR("invalid resolution %d", sequence->resolution); + return -EINVAL; + } + + if (find_msb_set(sequence->channels) > AD5592_PIN_MAX) { + LOG_ERR("invalid channels in mask: 0x%08x", sequence->channels); + return -EINVAL; + } + + ret = adc_ad5592_validate_buffer_size(dev, sequence); + if (ret < 0) { + LOG_ERR("insufficient buffer size"); + return ret; + } + + data->buffer = sequence->buffer; + adc_context_start_read(&data->ctx, sequence); + + return adc_context_wait_for_completion(&data->ctx); +} + +static int adc_ad5592_read_channel(const struct device *dev, uint8_t channel, uint16_t *result) +{ + const struct adc_ad5592_config *config = dev->config; + uint16_t val; + int ret; + + ret = mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_SEQ_ADC, BIT(channel)); + if (ret < 0) { + return ret; + } + + /* + * Invalid data: + * See Figure 46. Single-Channel ADC Conversion Sequence. + * The first conversion result always returns invalid data. + */ + (void) mfd_ad5592_read_raw(config->mfd_dev, &val); + + ret = mfd_ad5592_read_raw(config->mfd_dev, &val); + if (ret < 0) { + return ret; + } + + val = sys_be16_to_cpu(val); + if (channel >= 1) { + val -= channel * AD5592_ADC_MAX_VAL; + } + + *result = val; + + return 0; +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct adc_ad5592_data *data = CONTAINER_OF(ctx, struct adc_ad5592_data, ctx); + + data->channels = ctx->sequence.channels; + data->repeat_buffer = data->buffer; + + k_sem_give(&data->sem); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, + bool repeat_sampling) +{ + struct adc_ad5592_data *data = CONTAINER_OF(ctx, struct adc_ad5592_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +static void adc_ad5592_acquisition_thread(struct adc_ad5592_data *data) +{ + uint16_t result; + uint8_t channel; + int ret; + + while (true) { + k_sem_take(&data->sem, K_FOREVER); + + while (data->channels != 0) { + channel = find_lsb_set(data->channels) - 1; + + ret = adc_ad5592_read_channel(data->dev, channel, &result); + if (ret < 0) { + LOG_ERR("failed to read channel %d (ret %d)", channel, ret); + adc_context_complete(&data->ctx, ret); + break; + } + + *data->buffer++ = result; + WRITE_BIT(data->channels, channel, 0); + } + + adc_context_on_sampling_done(&data->ctx, data->dev); + } +} + +static int adc_ad5592_read_async(const struct device *dev, + const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_ad5592_data *data = dev->data; + int ret; + + adc_context_lock(&data->ctx, async ? true : false, async); + ret = adc_ad5592_start_read(dev, sequence); + adc_context_release(&data->ctx, ret); + + return ret; +} + +static int adc_ad5592_read(const struct device *dev, + const struct adc_sequence *sequence) +{ + return adc_ad5592_read_async(dev, sequence, NULL); +} + +static int adc_ad5592_init(const struct device *dev) +{ + const struct adc_ad5592_config *config = dev->config; + struct adc_ad5592_data *data = dev->data; + k_tid_t tid; + int ret; + + if (!device_is_ready(config->mfd_dev)) { + return -ENODEV; + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_PD_REF_CTRL, AD5592_EN_REF); + if (ret < 0) { + return ret; + } + + data->dev = dev; + + k_sem_init(&data->sem, 0, 1); + adc_context_init(&data->ctx); + + tid = k_thread_create(&data->thread, data->stack, + CONFIG_ADC_AD5592_ACQUISITION_THREAD_STACK_SIZE, + (k_thread_entry_t)adc_ad5592_acquisition_thread, data, NULL, NULL, + CONFIG_ADC_AD5592_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); + + ret = k_thread_name_set(tid, "adc_ad5592"); + if (ret < 0) { + return ret; + } + + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static const struct adc_driver_api adc_ad5592_api = { + .channel_setup = adc_ad5592_channel_setup, + .read = adc_ad5592_read, +#ifdef CONFIG_ADC_ASYNC + .read_async = adc_ad5592_read_async, +#endif +}; + +#define ADC_AD5592_DEFINE(inst) \ + static const struct adc_ad5592_config adc_ad5592_config##inst = { \ + .mfd_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + }; \ + \ + struct adc_ad5592_data adc_ad5592_data##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, adc_ad5592_init, NULL, \ + &adc_ad5592_data##inst, &adc_ad5592_config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + &adc_ad5592_api); + +DT_INST_FOREACH_STATUS_OKAY(ADC_AD5592_DEFINE) diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index 2069b97b5ec..81b0d0d3d2f 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -104,6 +104,7 @@ static struct adc_hdl { DT_FOREACH_STATUS_OKAY(maxim_max11115, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(maxim_max11116, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(maxim_max11117, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(adi_ad5592_adc, ADC_HDL_LIST_ENTRY) }; static struct adc_hdl *get_adc(const char *device_label) diff --git a/dts/bindings/adc/adi,ad5592-adc.yaml b/dts/bindings/adc/adi,ad5592-adc.yaml new file mode 100644 index 00000000000..2432b55d25a --- /dev/null +++ b/dts/bindings/adc/adi,ad5592-adc.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +description: AD5592 ADC Controller + +compatible: "adi,ad5592-adc" + +include: adc-controller.yaml + +properties: + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/tests/drivers/build_all/adc/app.overlay b/tests/drivers/build_all/adc/app.overlay new file mode 100644 index 00000000000..82634f87df4 --- /dev/null +++ b/tests/drivers/build_all/adc/app.overlay @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Grinn + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for testing driver builds + * + * Names in this file should be chosen in a way that won't conflict + * with real-world devicetree nodes, to allow these tests to run on + * (and be extended to test) real hardware. + */ + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_gpio: gpio@deadbeef { + compatible = "vnd,gpio"; + gpio-controller; + reg = <0xdeadbeef 0x1000>; + #gpio-cells = <0x2>; + status = "okay"; + }; + + test_spi: spi@33334444 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "vnd,spi"; + reg = <0x33334444 0x1000>; + status = "okay"; + clock-frequency = <2000000>; + + cs-gpios = <&test_gpio 0 0>; + + test_spi_ad5592: ad5592@0 { + compatible = "adi,ad5592"; + status = "okay"; + reg = <0x0>; + spi-max-frequency = <0>; + reset-gpios = <&test_gpio 0 0>; + + ad5592_adc: adc-controller { + compatible = "adi,ad5592-adc"; + #io-channel-cells = <1>; + }; + }; + }; + }; +}; diff --git a/tests/drivers/build_all/adc/prj.conf b/tests/drivers/build_all/adc/prj.conf index c5d1cb3b04f..cdf8b315168 100644 --- a/tests/drivers/build_all/adc/prj.conf +++ b/tests/drivers/build_all/adc/prj.conf @@ -4,3 +4,4 @@ CONFIG_ADC=y CONFIG_MAX_THREAD_BYTES=4 CONFIG_ADC_INIT_PRIORITY=80 CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES=256 +CONFIG_SPI=y From 0689d3dc1145fea9c872571bbba8b102db026fbc Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 20:43:46 +0100 Subject: [PATCH 3221/4498] drivers: gpio: add driver for AD5592 Add MFD subdriver for the built-in GPIO controller in AD5592 chip. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.ad5592 | 10 + drivers/gpio/gpio_ad5592.c | 227 +++++++++++++++++++++++ dts/bindings/gpio/adi,ad5592-gpio.yaml | 12 ++ tests/drivers/build_all/gpio/app.overlay | 21 ++- 7 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 drivers/gpio/Kconfig.ad5592 create mode 100644 drivers/gpio/gpio_ad5592.c create mode 100644 dts/bindings/gpio/adi,ad5592-gpio.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 63fc8876a96..3314e8c26b4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -330,6 +330,7 @@ /drivers/gpio/*bd8lb600fs* @benediktibk /drivers/gpio/*pcal64xxa* @benediktibk /drivers/gpio/gpio_altera_pio.c @shilinte +/drivers/gpio/gpio_ad5592.c @bbilas /drivers/hwinfo/ @alexanderwachter /drivers/i2c/i2c_common.c @sjg20 /drivers/i2c/i2c_emul.c @sjg20 diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index e82a815fcce..19c9d3e976c 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/gpio.h) zephyr_library() +zephyr_library_sources_ifdef(CONFIG_GPIO_AD5592 gpio_ad5592.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AXP192 gpio_axp192.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TELINK_B91 gpio_b91.c) zephyr_library_sources_ifdef(CONFIG_GPIO_INFINEON_CAT1 gpio_ifx_cat1.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fc09ef2994d..92d7b0587e9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -69,6 +69,8 @@ config GPIO_ENABLE_DISABLE_INTERRUPT pending register, etc. The driver must implement it to work. +source "drivers/gpio/Kconfig.ad5592" + source "drivers/gpio/Kconfig.axp192" source "drivers/gpio/Kconfig.b91" diff --git a/drivers/gpio/Kconfig.ad5592 b/drivers/gpio/Kconfig.ad5592 new file mode 100644 index 00000000000..c2654d1857b --- /dev/null +++ b/drivers/gpio/Kconfig.ad5592 @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_AD5592 + bool "AD5592 GPIO driver" + default y + depends on DT_HAS_ADI_AD5592_GPIO_ENABLED + select MFD + help + Enable the AD5592 GPIO driver. diff --git a/drivers/gpio/gpio_ad5592.c b/drivers/gpio/gpio_ad5592.c new file mode 100644 index 00000000000..a8b30ddcee4 --- /dev/null +++ b/drivers/gpio/gpio_ad5592.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_ad5592_gpio + +#include +#include +#include +#include + +#include + +struct gpio_ad5592_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + const struct device *mfd_dev; +}; + +struct gpio_ad5592_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + uint8_t gpio_val; + uint8_t gpio_out; + uint8_t gpio_in; + uint8_t gpio_pull_down; +}; + +static int gpio_ad5592_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_ad5592_config *config = dev->config; + struct gpio_ad5592_data *drv_data = dev->data; + uint16_t data; + int ret; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + ret = mfd_ad5592_read_reg(config->mfd_dev, + AD5592_REG_GPIO_INPUT_EN, drv_data->gpio_in, &data); + if (ret < 0) { + return ret; + } + + *value = (uint32_t)data; + + return 0; +} + +static int gpio_ad5592_port_set_bits_raw(const struct device *dev, + gpio_port_pins_t pins) +{ + struct gpio_ad5592_data *data = dev->data; + const struct gpio_ad5592_config *config = dev->config; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + data->gpio_val |= (uint8_t)pins; + + return mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_GPIO_SET, data->gpio_val); +} + +static int gpio_ad5592_port_clear_bits_raw(const struct device *dev, + gpio_port_pins_t pins) +{ + struct gpio_ad5592_data *data = dev->data; + const struct gpio_ad5592_config *config = dev->config; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + data->gpio_val &= ~(uint8_t)pins; + + return mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_GPIO_SET, data->gpio_val); +} + +static inline int gpio_ad5592_configure(const struct device *dev, + gpio_pin_t pin, gpio_flags_t flags) +{ + struct gpio_ad5592_data *data = dev->data; + const struct gpio_ad5592_config *config = dev->config; + uint8_t val; + int ret; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + if (pin >= AD5592_PIN_MAX) { + return -EINVAL; + } + + val = BIT(pin); + if ((flags & GPIO_OUTPUT) != 0U) { + data->gpio_in &= ~val; + data->gpio_out |= val; + + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) { + ret = gpio_ad5592_port_set_bits_raw( + dev, (gpio_port_pins_t)BIT(pin)); + if (ret < 0) { + return ret; + } + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) { + ret = gpio_ad5592_port_clear_bits_raw( + dev, (gpio_port_pins_t)BIT(pin)); + if (ret < 0) { + return ret; + } + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, + AD5592_REG_GPIO_OUTPUT_EN, data->gpio_out); + if (ret < 0) { + return ret; + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, + AD5592_REG_GPIO_INPUT_EN, data->gpio_in); + } else if ((flags & GPIO_INPUT) != 0U) { + data->gpio_in |= val; + data->gpio_out &= ~val; + + if ((flags & GPIO_PULL_DOWN) != 0U) { + data->gpio_pull_down |= val; + + ret = mfd_ad5592_write_reg(config->mfd_dev, + AD5592_REG_GPIO_PULLDOWN, + data->gpio_pull_down); + if (ret < 0) { + return ret; + } + } else if ((flags & GPIO_PULL_UP) != 0U) { + return -ENOTSUP; + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, + AD5592_REG_GPIO_OUTPUT_EN, data->gpio_out); + if (ret < 0) { + return ret; + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, + AD5592_REG_GPIO_INPUT_EN, data->gpio_in); + } else { + return -ENOTSUP; + } + + return ret; +} + +static int gpio_ad5592_port_set_masked_raw(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + ARG_UNUSED(dev); + ARG_UNUSED(mask); + ARG_UNUSED(value); + + return -ENOTSUP; +} + +static int gpio_ad5592_port_toggle_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + return -ENOTSUP; +} + +static int gpio_ad5592_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + +static const struct gpio_driver_api gpio_ad5592_api = { + .pin_configure = gpio_ad5592_configure, + .port_get_raw = gpio_ad5592_port_get_raw, + .port_set_masked_raw = gpio_ad5592_port_set_masked_raw, + .port_set_bits_raw = gpio_ad5592_port_set_bits_raw, + .port_clear_bits_raw = gpio_ad5592_port_clear_bits_raw, + .port_toggle_bits = gpio_ad5592_port_toggle_bits, + .pin_interrupt_configure = gpio_ad5592_pin_interrupt_configure, +}; + +static int gpio_ad5592_init(const struct device *dev) +{ + const struct gpio_ad5592_config *config = dev->config; + + if (!device_is_ready(config->mfd_dev)) { + return -ENODEV; + } + + return 0; +} + +#define GPIO_AD5592_DEFINE(inst) \ + static const struct gpio_ad5592_config gpio_ad5592_config##inst = { \ + .common = { \ + .port_pin_mask = \ + GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ + }, \ + .mfd_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + }; \ + \ + static struct gpio_ad5592_data gpio_ad5592_data##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, gpio_ad5592_init, NULL, \ + &gpio_ad5592_data##inst, &gpio_ad5592_config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + &gpio_ad5592_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_AD5592_DEFINE) diff --git a/dts/bindings/gpio/adi,ad5592-gpio.yaml b/dts/bindings/gpio/adi,ad5592-gpio.yaml new file mode 100644 index 00000000000..b815f557c51 --- /dev/null +++ b/dts/bindings/gpio/adi,ad5592-gpio.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +description: AD5592 GPIO Controller + +compatible: "adi,ad5592-gpio" + +include: gpio-controller.yaml + +gpio-cells: + - pin + - flags diff --git a/tests/drivers/build_all/gpio/app.overlay b/tests/drivers/build_all/gpio/app.overlay index b6a315cedfa..715480a94f0 100644 --- a/tests/drivers/build_all/gpio/app.overlay +++ b/tests/drivers/build_all/gpio/app.overlay @@ -210,7 +210,11 @@ clock-frequency = <2000000>; /* one entry for every devices at spi.dtsi */ - cs-gpios = <&test_gpio 0 0 &test_gpio 0 0 &test_gpio 0 0>; + cs-gpios = <&test_gpio 0 0 + &test_gpio 0 0 + &test_gpio 0 0 + &test_gpio 0 0 + &test_gpio 0 0>; test_spi_mcp23s17: mcp23s17@0 { compatible = "microchip,mcp23s17"; @@ -259,6 +263,21 @@ #gpio-cells = <2>; }; }; + + test_spi_ad5592: ad5592@4 { + compatible = "adi,ad5592"; + status = "okay"; + reg = <0x04>; + spi-max-frequency = <0>; + reset-gpios = <&test_gpio 0 0>; + + ad5592_gpio: gpio-controller { + compatible = "adi,ad5592-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + }; + }; }; }; }; From 2c09999d247824cbcdf23b0bd84c2f1bef040a6f Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 30 Oct 2023 20:44:27 +0100 Subject: [PATCH 3222/4498] drivers: dac: add driver for AD5592 Add MFD subdriver for the built-in DAC controller in AD5592 chip. Signed-off-by: Bartosz Bilas --- CODEOWNERS | 1 + drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig | 2 + drivers/dac/Kconfig.ad5592 | 10 +++ drivers/dac/dac_ad5592.c | 107 ++++++++++++++++++++++++ dts/bindings/dac/adi,ad5592-dac.yaml | 15 ++++ tests/drivers/build_all/dac/app.overlay | 14 ++++ 7 files changed, 150 insertions(+) create mode 100644 drivers/dac/Kconfig.ad5592 create mode 100644 drivers/dac/dac_ad5592.c create mode 100644 dts/bindings/dac/adi,ad5592-dac.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 3314e8c26b4..f339c8958fe 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -275,6 +275,7 @@ /drivers/display/display_ili9342c.* @extremegtx /drivers/dac/ @martinjaeger /drivers/dac/*ad56xx* @benediktibk +/drivers/dac/dac_ad5592.c @bbilas /drivers/dai/ @kv2019i @marcinszkudlinski @abonislawski /drivers/dai/intel/ @kv2019i @marcinszkudlinski @abonislawski /drivers/dai/intel/ssp/ @kv2019i @marcinszkudlinski @abonislawski diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index d2164f92d7e..c84b0d9d78e 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -18,5 +18,6 @@ zephyr_library_sources_ifdef(CONFIG_DAC_MCP4725 dac_mcp4725.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCP4728 dac_mcp4728.c) zephyr_library_sources_ifdef(CONFIG_DAC_GD32 dac_gd32.c) zephyr_library_sources_ifdef(CONFIG_DAC_ESP32 dac_esp32.c) +zephyr_library_sources_ifdef(CONFIG_DAC_AD5592 dac_ad5592.c) zephyr_library_sources_ifdef(CONFIG_DAC_AD56XX dac_ad56xx.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE dac_handlers.c) diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index 6449032fa48..553d9f05355 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -54,4 +54,6 @@ source "drivers/dac/Kconfig.esp32" source "drivers/dac/Kconfig.ad56xx" +source "drivers/dac/Kconfig.ad5592" + endif # DAC diff --git a/drivers/dac/Kconfig.ad5592 b/drivers/dac/Kconfig.ad5592 new file mode 100644 index 00000000000..1010992fb7f --- /dev/null +++ b/drivers/dac/Kconfig.ad5592 @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +config DAC_AD5592 + bool "AD5592 DAC driver" + default y + depends on DT_HAS_ADI_AD5592_DAC_ENABLED + select MFD + help + Enable the AD5592 DAC driver. diff --git a/drivers/dac/dac_ad5592.c b/drivers/dac/dac_ad5592.c new file mode 100644 index 00000000000..653df85dd56 --- /dev/null +++ b/drivers/dac/dac_ad5592.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 Grinn + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_ad5592_dac + +#include +#include +#include + +#include + +#include +LOG_MODULE_REGISTER(dac_ad5592, CONFIG_DAC_LOG_LEVEL); + +#define AD5592_DAC_RESOLUTION 12 +#define AD5592_DAC_WR_MSB_BIT BIT(15) +#define AD5592_DAC_CHANNEL_SHIFT_VAL 12 + +struct dac_ad5592_config { + const struct device *mfd_dev; +}; + +struct dac_ad5592_data { + uint8_t dac_conf; +}; + +static int dac_ad5592_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + const struct dac_ad5592_config *config = dev->config; + struct dac_ad5592_data *data = dev->data; + + if (channel_cfg->channel_id >= AD5592_PIN_MAX) { + LOG_ERR("Invalid channel number %d", channel_cfg->channel_id); + return -EINVAL; + } + + if (channel_cfg->resolution != AD5592_DAC_RESOLUTION) { + LOG_ERR("Invalid resolution %d", channel_cfg->resolution); + return -EINVAL; + } + + data->dac_conf |= BIT(channel_cfg->channel_id); + + return mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_LDAC_EN, data->dac_conf); +} + +static int dac_ad5592_write_value(const struct device *dev, uint8_t channel, + uint32_t value) +{ + const struct dac_ad5592_config *config = dev->config; + uint16_t msg; + + if (channel >= AD5592_PIN_MAX) { + LOG_ERR("Invalid channel number %d", channel); + return -EINVAL; + } + + if (value >= (1 << AD5592_DAC_RESOLUTION)) { + LOG_ERR("Value %d out of range", value); + return -EINVAL; + } + + msg = sys_cpu_to_be16(AD5592_DAC_WR_MSB_BIT | + channel << AD5592_DAC_CHANNEL_SHIFT_VAL | + value); + + return mfd_ad5592_write_raw(config->mfd_dev, msg); +} + +static const struct dac_driver_api dac_ad5592_api = { + .channel_setup = dac_ad5592_channel_setup, + .write_value = dac_ad5592_write_value, +}; + +static int dac_ad5592_init(const struct device *dev) +{ + const struct dac_ad5592_config *config = dev->config; + int ret; + + if (!device_is_ready(config->mfd_dev)) { + return -ENODEV; + } + + ret = mfd_ad5592_write_reg(config->mfd_dev, AD5592_REG_PD_REF_CTRL, AD5592_EN_REF); + if (ret < 0) { + return ret; + } + + return 0; +} + +#define DAC_AD5592_DEFINE(inst) \ + static const struct dac_ad5592_config dac_ad5592_config##inst = { \ + .mfd_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + }; \ + \ + struct dac_ad5592_data dac_ad5592_data##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, dac_ad5592_init, NULL, \ + &dac_ad5592_data##inst, &dac_ad5592_config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + &dac_ad5592_api); + +DT_INST_FOREACH_STATUS_OKAY(DAC_AD5592_DEFINE) diff --git a/dts/bindings/dac/adi,ad5592-dac.yaml b/dts/bindings/dac/adi,ad5592-dac.yaml new file mode 100644 index 00000000000..3ac8087b91d --- /dev/null +++ b/dts/bindings/dac/adi,ad5592-dac.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +description: AD5592 DAC Controller + +compatible: "adi,ad5592-dac" + +include: dac-controller.yaml + +properties: + "#io-channel-cells": + const: 1 + +io-channel-cells: + - output diff --git a/tests/drivers/build_all/dac/app.overlay b/tests/drivers/build_all/dac/app.overlay index 40218f7949d..ee82a5e8b86 100644 --- a/tests/drivers/build_all/dac/app.overlay +++ b/tests/drivers/build_all/dac/app.overlay @@ -82,6 +82,7 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, + <&test_gpio 0 0>, <&test_gpio 0 0>; test_spi_dac60508: dac60508@0 { @@ -233,6 +234,19 @@ #io-channel-cells = <1>; reset-gpios = <&test_gpio 0 0>; }; + + test_spi_ad5592: ad5592@10 { + compatible = "adi,ad5592"; + status = "okay"; + reg = <0x10>; + spi-max-frequency = <0>; + reset-gpios = <&test_gpio 0 0>; + + ad5592_dac: dac-controller { + compatible = "adi,ad5592-dac"; + #io-channel-cells = <1>; + }; + }; }; }; }; From 79c9f17320c43a718d0dc2745f4869a86726d243 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 1 Nov 2023 15:29:22 -0500 Subject: [PATCH 3223/4498] samples: llext shell_loader reduced size Reduce the heap and stack sizes needed for the shell loader sample app so more devices may try it out. Tried on a mimxrt1010_evk and noted the total ram usage was approximately 44000 bytes. Prior to this change the mimxrt1010_evk was unable to run the sample as the bss section overflowed the ram size. Signed-off-by: Tom Burdick --- samples/subsys/llext/shell_loader/prj.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/subsys/llext/shell_loader/prj.conf b/samples/subsys/llext/shell_loader/prj.conf index 678e5eb55ae..0e0d38fdcf4 100644 --- a/samples/subsys/llext/shell_loader/prj.conf +++ b/samples/subsys/llext/shell_loader/prj.conf @@ -2,11 +2,11 @@ CONFIG_LOG=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_SHELL=y -CONFIG_SHELL_CMD_BUFF_SIZE=32768 +CONFIG_SHELL_CMD_BUFF_SIZE=8192 CONFIG_SHELL_LOG_LEVEL_INF=y -CONFIG_SHELL_STACK_SIZE=8192 +CONFIG_SHELL_STACK_SIZE=4096 CONFIG_LLEXT=y CONFIG_LLEXT_LOG_LEVEL_DBG=y -CONFIG_LLEXT_HEAP_SIZE=32 +CONFIG_LLEXT_HEAP_SIZE=8 CONFIG_LLEXT_SHELL=y From 6d651e37a32354161ceccf9ff22d7e643464a08d Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 1 Nov 2023 15:33:24 -0500 Subject: [PATCH 3224/4498] llext: Track module memory usage The memory usage shown in the shell was 0 which is obviously incorrect. At some point the memory allocation tracking was dropped from llext.c mistakenly. Add it back. Signed-off-by: Tom Burdick --- subsys/llext/llext.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index b94d6ae1183..9e3cbd79990 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -252,6 +252,7 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, if (!ext->mem[mem_idx]) { return -ENOMEM; } + ext->mem_size += ldr->sects[sect_idx].sh_size; ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); if (ret != 0) { @@ -347,11 +348,13 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) { int ret = 0; + size_t syms_size = ldr->sym_cnt * sizeof(struct llext_symbol); - ext->sym_tab.syms = k_heap_alloc(&llext_heap, ldr->sym_cnt * sizeof(struct llext_symbol), + ext->sym_tab.syms = k_heap_alloc(&llext_heap, syms_size, K_NO_WAIT); ext->sym_tab.sym_cnt = ldr->sym_cnt; memset(ext->sym_tab.syms, 0, ldr->sym_cnt * sizeof(struct llext_symbol)); + ext->mem_size += syms_size; return ret; } @@ -551,6 +554,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) } memset(ldr->sect_map, 0, ldr->hdr.e_shnum*sizeof(uint32_t)); ldr->sect_cnt = ldr->hdr.e_shnum; + ext->mem_size += sect_map_sz; LOG_DBG("Finding ELF tables..."); ret = llext_find_tables(ldr); From 982cc794e3dd5db1089dc37dacfad7f3dc69e5d3 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 1 Nov 2023 15:39:54 -0500 Subject: [PATCH 3225/4498] llext: Make the shell list command output nicer Remove unnecessary newline characters from shell_print, it already adds them. Align the table pipe characters better in the list of modules. Signed-off-by: Tom Burdick --- subsys/llext/shell.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/llext/shell.c b/subsys/llext/shell.c index 370fd83405f..b9a4121acc6 100644 --- a/subsys/llext/shell.c +++ b/subsys/llext/shell.c @@ -43,9 +43,9 @@ static int cmd_llext_list_symbols(const struct shell *sh, size_t argc, char *arg } shell_print(sh, "Extension: %s symbols", m->name); - shell_print(sh, "| Symbol | Address |\n"); + shell_print(sh, "| Symbol | Address |"); for (elf_word i = 0; i < m->sym_tab.sym_cnt; i++) { - shell_print(sh, "| %16s | %p |\n", m->sym_tab.syms[i].name, + shell_print(sh, "| %16s | %p |", m->sym_tab.syms[i].name, m->sym_tab.syms[i].addr); } @@ -84,10 +84,10 @@ static int cmd_llext_list(const struct shell *sh, size_t argc, char *argv[]) sys_snode_t *node; struct llext *ext; - shell_print(sh, "| Name | Size |\n"); + shell_print(sh, "| Name | Size |"); SYS_SLIST_FOR_EACH_NODE(llext_list(), node) { ext = CONTAINER_OF(node, struct llext, _llext_list); - shell_print(sh, "| %16s | %12d |\n", ext->name, ext->mem_size); + shell_print(sh, "| %16s | %12d |", ext->name, ext->mem_size); } return 0; From 2c5f5bfd0af4435cdb266f8e9f3b37838131ff2b Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Fri, 3 Nov 2023 16:17:52 -0400 Subject: [PATCH 3226/4498] samples: fs: fat_fs: support on stm32h747i-disco board This patch allow demonstrating fat_fs sample application on stm32h747i-disco board with SD card. Build fs_sample using following command west build -p always -b stm32h747i_disco_m7 \ samples/subsys/fs/fs_sample Signed-off-by: Murali Karicheri --- .../fs/fs_sample/boards/stm32h747i_disco_m7.conf | 1 + .../fs/fs_sample/boards/stm32h747i_disco_m7.overlay | 11 +++++++++++ samples/subsys/fs/fs_sample/sample.yaml | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.conf create mode 100644 samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.overlay diff --git a/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.conf b/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.conf new file mode 100644 index 00000000000..857d2e8ddfd --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.conf @@ -0,0 +1 @@ +CONFIG_SDMMC_STM32_HWFC=y diff --git a/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.overlay b/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.overlay new file mode 100644 index 00000000000..d80aa5114fc --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/stm32h747i_disco_m7.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 S&C Electric Company + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sdmmc1 { + sdmmc { + compatible = "zephyr,sdmmc-disk"; + }; +}; diff --git a/samples/subsys/fs/fs_sample/sample.yaml b/samples/subsys/fs/fs_sample/sample.yaml index e022ca1e4c1..375bacf4f8f 100644 --- a/samples/subsys/fs/fs_sample/sample.yaml +++ b/samples/subsys/fs/fs_sample/sample.yaml @@ -45,3 +45,8 @@ tests: sample.filesystem.ext2: extra_args: CONF_FILE="prj_ext.conf" platform_allow: hifive_unmatched bl5340_dvk_cpuapp + sample.filesystem.fat_fs.stm32h747i_disco_m7_sdmmc: + build_only: true + platform_allow: stm32h747i_disco_m7 + extra_args: + - OVERLAY_CONFIG=boards/stm32h747i_disco_m7.conf From f1dc11174c9dda97c142eee35a2d21bc417bc775 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 6 Nov 2023 14:08:27 +0800 Subject: [PATCH 3227/4498] ITE: drivers/i2c: Add a property for I2C located channel Add a property for I2C channel switch selection. This property will write to the SMBxxCHS register according to the I2C node you selected, which can make channel swapping. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_enhance.c | 23 ++++++++++ drivers/i2c/i2c_ite_it8xxx2.c | 14 ++++++ dts/bindings/i2c/ite,common-i2c.yaml | 48 ++++++++++++++++++++ dts/riscv/ite/it81xx2.dtsi | 6 +++ dts/riscv/ite/it82xx2.dtsi | 6 +++ include/zephyr/dt-bindings/i2c/it8xxx2-i2c.h | 8 ++++ soc/riscv/riscv-ite/common/chip_chipregs.h | 8 ++-- 7 files changed, 109 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index 93187ff940a..1d26ade56c1 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -63,6 +63,7 @@ struct i2c_enhance_config { uint8_t *base; uint8_t i2c_irq_base; uint8_t port; + uint8_t channel_switch_sel; /* SCL GPIO cells */ struct gpio_dt_spec scl_gpios; /* SDA GPIO cells */ @@ -1174,6 +1175,27 @@ static int i2c_enhance_init(const struct device *dev) enhanced_i2c_set_cmd_addr_regs(dev); #endif + /* ChannelA-F switch selection of I2C pin */ + if (config->port == SMB_CHANNEL_A) { + IT8XXX2_SMB_SMB01CHS = (IT8XXX2_SMB_SMB01CHS &= ~GENMASK(2, 0)) | + config->channel_switch_sel; + } else if (config->port == SMB_CHANNEL_B) { + IT8XXX2_SMB_SMB01CHS = (config->channel_switch_sel << 4) | + (IT8XXX2_SMB_SMB01CHS &= ~GENMASK(6, 4)); + } else if (config->port == SMB_CHANNEL_C) { + IT8XXX2_SMB_SMB23CHS = (IT8XXX2_SMB_SMB23CHS &= ~GENMASK(2, 0)) | + config->channel_switch_sel; + } else if (config->port == I2C_CHANNEL_D) { + IT8XXX2_SMB_SMB23CHS = (config->channel_switch_sel << 4) | + (IT8XXX2_SMB_SMB23CHS &= ~GENMASK(6, 4)); + } else if (config->port == I2C_CHANNEL_E) { + IT8XXX2_SMB_SMB45CHS = (IT8XXX2_SMB_SMB45CHS &= ~GENMASK(2, 0)) | + config->channel_switch_sel; + } else if (config->port == I2C_CHANNEL_F) { + IT8XXX2_SMB_SMB45CHS = (config->channel_switch_sel << 4) | + (IT8XXX2_SMB_SMB45CHS &= ~GENMASK(6, 4)); + } + /* Set clock frequency for I2C ports */ if (config->bitrate == I2C_BITRATE_STANDARD || config->bitrate == I2C_BITRATE_FAST || @@ -1427,6 +1449,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_I2C_TARGET_BUFFER_MODE), .bitrate = DT_INST_PROP(inst, clock_frequency), \ .i2c_irq_base = DT_INST_IRQN(inst), \ .port = DT_INST_PROP(inst, port_num), \ + .channel_switch_sel = DT_INST_PROP(inst, channel_switch_sel), \ .scl_gpios = GPIO_DT_SPEC_INST_GET(inst, scl_gpios), \ .sda_gpios = GPIO_DT_SPEC_INST_GET(inst, sda_gpios), \ .prescale_scl_low = DT_INST_PROP_OR(inst, prescale_scl_low, 0), \ diff --git a/drivers/i2c/i2c_ite_it8xxx2.c b/drivers/i2c/i2c_ite_it8xxx2.c index 2a55576ef5b..57f69a6aaeb 100644 --- a/drivers/i2c/i2c_ite_it8xxx2.c +++ b/drivers/i2c/i2c_ite_it8xxx2.c @@ -44,6 +44,7 @@ struct i2c_it8xxx2_config { uint8_t *reg_mstfctrl; uint8_t i2c_irq_base; uint8_t port; + uint8_t channel_switch_sel; /* SCL GPIO cells */ struct gpio_dt_spec scl_gpios; /* SDA GPIO cells */ @@ -1134,6 +1135,18 @@ static int i2c_it8xxx2_init(const struct device *dev) } #endif + /* ChannelA-C switch selection of I2C pin */ + if (config->port == SMB_CHANNEL_A) { + IT8XXX2_SMB_SMB01CHS = (IT8XXX2_SMB_SMB01CHS &= ~GENMASK(2, 0)) | + config->channel_switch_sel; + } else if (config->port == SMB_CHANNEL_B) { + IT8XXX2_SMB_SMB01CHS = (config->channel_switch_sel << 4) | + (IT8XXX2_SMB_SMB01CHS &= ~GENMASK(6, 4)); + } else if (config->port == SMB_CHANNEL_C) { + IT8XXX2_SMB_SMB23CHS = (IT8XXX2_SMB_SMB23CHS &= ~GENMASK(2, 0)) | + config->channel_switch_sel; + } + /* Set clock frequency for I2C ports */ if (config->bitrate == I2C_BITRATE_STANDARD || config->bitrate == I2C_BITRATE_FAST || @@ -1265,6 +1278,7 @@ BUILD_ASSERT((DT_INST_PROP(SMB_CHANNEL_C, fifo_enable) == false), .bitrate = DT_INST_PROP(inst, clock_frequency), \ .i2c_irq_base = DT_INST_IRQN(inst), \ .port = DT_INST_PROP(inst, port_num), \ + .channel_switch_sel = DT_INST_PROP(inst, channel_switch_sel), \ .scl_gpios = GPIO_DT_SPEC_INST_GET(inst, scl_gpios), \ .sda_gpios = GPIO_DT_SPEC_INST_GET(inst, sda_gpios), \ .clock_gate_offset = DT_INST_PROP(inst, clock_gate_offset), \ diff --git a/dts/bindings/i2c/ite,common-i2c.yaml b/dts/bindings/i2c/ite,common-i2c.yaml index 251903efafc..1e4e90793da 100644 --- a/dts/bindings/i2c/ite,common-i2c.yaml +++ b/dts/bindings/i2c/ite,common-i2c.yaml @@ -30,6 +30,54 @@ properties: 4 = I2C_CHANNEL_E, 5 = I2C_CHANNEL_F, + channel-switch-sel: + type: int + required: true + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + description: | + The default setting is as described below + 0 = I2C_CHA_LOCATE: Channel A is located at SMCLK0/SMDAT0 + 1 = I2C_CHB_LOCATE: Channel B is located at SMCLK1/SMDAT1 + 2 = I2C_CHC_LOCATE: Channel C is located at SMCLK2/SMDAT2 + 3 = I2C_CHD_LOCATE: Channel D is located at SMCLK3/SMDAT3 + 4 = I2C_CHE_LOCATE: Channel E is located at SMCLK4/SMDAT4 + 5 = I2C_CHF_LOCATE: Channel F is located at SMCLK5/SMDAT5 + + The following is an example of the 'channel-switch-sel' property + being swapped between node &i2c0 and &i2c2 in the application: + Note: The property of 'port-num' cannot be changed in the + application. + + Channel C is located at SMCLK0/SMDAT0: + &i2c0 { + channel-switch-sel = ; + pinctrl-0 = <&i2c2_clk_gpf6_default + &i2c2_data_gpf7_default>; + pinctrl-names = "default"; + scl-gpios = <&gpiof 6 0>; + sda-gpios = <&gpiof 7 0>; + }; + + Channel A is located at SMCLK2/SMDAT2: + &i2c2 { + channel-switch-sel = ; + pinctrl-0 = <&i2c0_clk_gpb3_default + &i2c0_data_gpb4_default>; + pinctrl-names = "default"; + scl-gpios = <&gpiob 3 0>; + sda-gpios = <&gpiob 4 0>; + }; + + If the property of 'channel-switch-sel' is changed, the pinctrl + setting and recovery pin in &i2c0 and &i2c2 nodes must also be + modified accordingly. + scl-gpios: type: phandle-array required: true diff --git a/dts/riscv/ite/it81xx2.dtsi b/dts/riscv/ite/it81xx2.dtsi index 939e1672bfc..32d47861ee7 100644 --- a/dts/riscv/ite/it81xx2.dtsi +++ b/dts/riscv/ite/it81xx2.dtsi @@ -347,6 +347,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpiob 3 0>; sda-gpios = <&gpiob 4 0>; clock-gate-offset = ; @@ -363,6 +364,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioc 1 0>; sda-gpios = <&gpioc 2 0>; clock-gate-offset = ; @@ -379,6 +381,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpiof 6 0>; sda-gpios = <&gpiof 7 0>; clock-gate-offset = ; @@ -394,6 +397,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioh 1 0>; sda-gpios = <&gpioh 2 0>; clock-gate-offset = ; @@ -408,6 +412,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioe 0 0>; sda-gpios = <&gpioe 7 0>; clock-gate-offset = ; @@ -422,6 +427,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioa 4 0>; sda-gpios = <&gpioa 5 0>; clock-gate-offset = ; diff --git a/dts/riscv/ite/it82xx2.dtsi b/dts/riscv/ite/it82xx2.dtsi index 810b77f8d8a..6b3eea97aa9 100644 --- a/dts/riscv/ite/it82xx2.dtsi +++ b/dts/riscv/ite/it82xx2.dtsi @@ -885,6 +885,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpiob 3 0>; sda-gpios = <&gpiob 4 0>; clock-gate-offset = ; @@ -899,6 +900,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioc 1 0>; sda-gpios = <&gpioc 2 0>; clock-gate-offset = ; @@ -913,6 +915,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpiof 6 0>; sda-gpios = <&gpiof 7 0>; clock-gate-offset = ; @@ -927,6 +930,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioh 1 0>; sda-gpios = <&gpioh 2 0>; clock-gate-offset = ; @@ -941,6 +945,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioe 0 0>; sda-gpios = <&gpioe 7 0>; clock-gate-offset = ; @@ -955,6 +960,7 @@ interrupt-parent = <&intc>; status = "disabled"; port-num = ; + channel-switch-sel = ; scl-gpios = <&gpioa 4 0>; sda-gpios = <&gpioa 5 0>; clock-gate-offset = ; diff --git a/include/zephyr/dt-bindings/i2c/it8xxx2-i2c.h b/include/zephyr/dt-bindings/i2c/it8xxx2-i2c.h index a42879d1331..199e813308e 100644 --- a/include/zephyr/dt-bindings/i2c/it8xxx2-i2c.h +++ b/include/zephyr/dt-bindings/i2c/it8xxx2-i2c.h @@ -20,4 +20,12 @@ #define CGC_OFFSET_SMBB ((IT8XXX2_ECPM_CGCTRL4R_OFF << 8) | 0x08) #define CGC_OFFSET_SMBA ((IT8XXX2_ECPM_CGCTRL4R_OFF << 8) | 0x04) +/* I2C channel switch selection */ +#define I2C_CHA_LOCATE 0 +#define I2C_CHB_LOCATE 1 +#define I2C_CHC_LOCATE 2 +#define I2C_CHD_LOCATE 3 +#define I2C_CHE_LOCATE 4 +#define I2C_CHF_LOCATE 5 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_I2C_IT8XXX2_H_ */ diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h index 17e1fa11b7a..b1009e3eee5 100644 --- a/soc/riscv/riscv-ite/common/chip_chipregs.h +++ b/soc/riscv/riscv-ite/common/chip_chipregs.h @@ -1203,11 +1203,11 @@ enum chip_pll_mode { #define IT8XXX2_SMB_MSTFSTS1 ECREG(IT8XXX2_SMB_BASE + 0x0E) #define IT8XXX2_SMB_MSTFCTRL2 ECREG(IT8XXX2_SMB_BASE + 0x0F) #define IT8XXX2_SMB_MSTFSTS2 ECREG(IT8XXX2_SMB_BASE + 0x10) -#define IT8XXX2_SMB_CHSEF ECREG(IT8XXX2_SMB_BASE + 0x11) +#define IT8XXX2_SMB_SMB45CHS ECREG(IT8XXX2_SMB_BASE + 0x11) #define IT8XXX2_SMB_I2CW2RF ECREG(IT8XXX2_SMB_BASE + 0x12) #define IT8XXX2_SMB_IWRFISTA ECREG(IT8XXX2_SMB_BASE + 0x13) -#define IT8XXX2_SMB_CHSAB ECREG(IT8XXX2_SMB_BASE + 0x20) -#define IT8XXX2_SMB_CHSCD ECREG(IT8XXX2_SMB_BASE + 0x21) +#define IT8XXX2_SMB_SMB01CHS ECREG(IT8XXX2_SMB_BASE + 0x20) +#define IT8XXX2_SMB_SMB23CHS ECREG(IT8XXX2_SMB_BASE + 0x21) #define IT8XXX2_SMB_SFFCTL ECREG(IT8XXX2_SMB_BASE + 0x55) #define IT8XXX2_SMB_HOSTA(base) ECREG(base + 0x00) #define IT8XXX2_SMB_HOCTL(base) ECREG(base + 0x01) @@ -1223,7 +1223,7 @@ enum chip_pll_mode { #define IT8XXX2_SMB_SLVISEL ECREG(IT8XXX2_SMB_BASE + 0x08) #define IT8XXX2_SMB_SMB01CHS ECREG(IT8XXX2_SMB_BASE + 0x09) #define IT8XXX2_SMB_SMB23CHS ECREG(IT8XXX2_SMB_BASE + 0x0A) -#define IT8XXX2_SMB_SMB4CHS ECREG(IT8XXX2_SMB_BASE + 0x0B) +#define IT8XXX2_SMB_SMB45CHS ECREG(IT8XXX2_SMB_BASE + 0x0B) #define IT8XXX2_SMB_SCLKTS_BRGS ECREG(IT8XXX2_SMB_BASE + 0x80) #define IT8XXX2_SMB_SCLKTS_BRGM ECREG(IT8XXX2_SMB_BASE + 0x81) #define IT8XXX2_SMB_CHSBRG ECREG(IT8XXX2_SMB_BASE + 0x82) From 50d17a0d52410290da788a7de9a027fd28478896 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Mon, 6 Nov 2023 12:51:48 +0100 Subject: [PATCH 3228/4498] Bluetooth: Mesh: split gatt client and solicitation pdu sending The ability to send the solicitation PDU doesn't depend on GATT Client role. Commit makes independent one functionality from another. Signed-off-by: Aleksandr Khromykh --- doc/connectivity/bluetooth/api/mesh/proxy.rst | 2 +- include/zephyr/bluetooth/mesh/proxy.h | 4 ++-- subsys/bluetooth/mesh/Kconfig | 5 ++--- subsys/bluetooth/mesh/shell/shell.c | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index d9212e24bc0..823401c9571 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -31,7 +31,7 @@ In the case where both GATT Proxy and Private GATT Proxy states are disabled on device cannot connect to it. A node supporting the :ref:`bluetooth_mesh_od_srv` may however be solicited to advertise connectable advertising events without enabling the Private GATT Proxy state. To solicit the node, the legacy device can send a Solicitation PDU by calling the -:func:`bt_mesh_proxy_solicit` function. To enable this feature, the client must to be compiled with +:func:`bt_mesh_proxy_solicit` function. To enable this feature, the device must to be compiled with the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` option set. Solicitation PDUs are non-mesh, non-connectable, undirected advertising messages containing Proxy diff --git a/include/zephyr/bluetooth/mesh/proxy.h b/include/zephyr/bluetooth/mesh/proxy.h index 60a397b9484..03576acf9bf 100644 --- a/include/zephyr/bluetooth/mesh/proxy.h +++ b/include/zephyr/bluetooth/mesh/proxy.h @@ -97,9 +97,9 @@ int bt_mesh_proxy_connect(uint16_t net_idx); */ int bt_mesh_proxy_disconnect(uint16_t net_idx); -/** @brief Schedule advertising of Solicitation PDUs on Proxy Client . +/** @brief Schedule advertising of Solicitation PDUs. * - * Once called Proxy Client will schedule advertising Solicitation PDUs for the amount of time + * Once called, the device will schedule advertising Solicitation PDUs for the amount of time * defined by @c adv_int * (@c CONFIG_BT_MESH_SOL_ADV_XMIT + 1), where @c adv_int is 20ms * for Bluetooth v5.0 or higher, or 100ms otherwise. * diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index a7155d8e514..de409e9c53c 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1439,11 +1439,10 @@ config BT_MESH_SOLICITATION bool config BT_MESH_PROXY_SOLICITATION - bool "Proxy solicitation feature for Proxy Client support" - depends on BT_MESH_PROXY_CLIENT + bool "Proxy solicitation feature" select BT_MESH_SOLICITATION help - This option enables support for sending Solicitation PDUs for Proxy Client. + This option enables support for sending Solicitation PDUs. config BT_MESH_SOL_ADV_XMIT int "Solicitation PDU retransmission count" diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index c5592db02cf..6ee825d4c09 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -387,6 +387,7 @@ static int cmd_proxy_disconnect(const struct shell *sh, size_t argc, return 0; } +#endif /* CONFIG_BT_MESH_PROXY_CLIENT */ #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) static int cmd_proxy_solicit(const struct shell *sh, size_t argc, @@ -410,7 +411,6 @@ static int cmd_proxy_solicit(const struct shell *sh, size_t argc, return err; } #endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */ -#endif /* CONFIG_BT_MESH_PROXY_CLIENT */ #endif /* CONFIG_BT_MESH_SHELL_GATT_PROXY */ #if defined(CONFIG_BT_MESH_SHELL_PROV) @@ -1739,11 +1739,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(proxy_cmds, #if defined(CONFIG_BT_MESH_PROXY_CLIENT) SHELL_CMD_ARG(connect, NULL, "", cmd_proxy_connect, 2, 0), SHELL_CMD_ARG(disconnect, NULL, "", cmd_proxy_disconnect, 2, 0), +#endif #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) SHELL_CMD_ARG(solicit, NULL, "", cmd_proxy_solicit, 2, 0), -#endif #endif SHELL_SUBCMD_SET_END); #endif /* CONFIG_BT_MESH_SHELL_GATT_PROXY */ From b6f20d67c2deb5e46de30b9f7ca0101c5c8cb4aa Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Mon, 6 Nov 2023 13:40:55 +0100 Subject: [PATCH 3229/4498] Bluetooth: Mesh: fix On-Demand API usage On-Demand proxy client API has been changed but usage of this API in shell test was missed. Commit fixes this API usage. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/shell/od_priv_proxy.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/mesh/shell/od_priv_proxy.c b/subsys/bluetooth/mesh/shell/od_priv_proxy.c index da353b9e95b..517fcfcaea3 100644 --- a/subsys/bluetooth/mesh/shell/od_priv_proxy.c +++ b/subsys/bluetooth/mesh/shell/od_priv_proxy.c @@ -15,13 +15,12 @@ static int cmd_od_priv_gatt_proxy_set(const struct shell *sh, size_t argc, char *argv[]) { uint8_t val, val_rsp; + uint16_t net_idx = bt_mesh_shell_target_ctx.net_idx; + uint16_t addr = bt_mesh_shell_target_ctx.dst; int err = 0; - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst); - if (argc < 2) { - err = bt_mesh_od_priv_proxy_cli_get(&ctx, &val_rsp); + err = bt_mesh_od_priv_proxy_cli_get(net_idx, addr, &val_rsp); } else { val = shell_strtoul(argv[1], 0, &err); @@ -30,7 +29,7 @@ static int cmd_od_priv_gatt_proxy_set(const struct shell *sh, size_t argc, return err; } - err = bt_mesh_od_priv_proxy_cli_set(&ctx, val, &val_rsp); + err = bt_mesh_od_priv_proxy_cli_set(net_idx, addr, val, &val_rsp); } if (err) { From 56816ceb526854625760106d7dad4e505f2b01d6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 10:03:49 +0100 Subject: [PATCH 3230/4498] manifest: Update nrf hw models to latest * Update the HW models module to a715dcc179f1a71f51c574165958b72fe932ae3f Including the following: * a715dcc irq_ctrl: Fix interrupt name getter * b9e1f00 Makefile: For 5340 build both HAL versions as separate libraries * 68aa50b Makefile: Set default target to compile and fix makefiles rules * 0cf5ea9 nrfx_glue: Provide a stubbed NRFX_DELAY for builds without Zephyr * b0d95c2 doc: Update required Nordic nrfx version to 3.2 Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 14907f79ef9..bde31c3303e 100644 --- a/west.yml +++ b/west.yml @@ -295,7 +295,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 90f4484cbaec986ed253b4fe9649aa75e632de15 + revision: a715dcc179f1a71f51c574165958b72fe932ae3f path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 From 2a4350dfd2b27c9ca14889c81023be4d6bfa0139 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Tue, 7 Nov 2023 10:24:36 +0100 Subject: [PATCH 3231/4498] net: openthread: Adding snoop entries kconfig. Adding missing `CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES` to thread kconfig file. Signed-off-by: Przemyslaw Bida --- .../platform/openthread-core-zephyr-config.h | 12 ++++++++++++ subsys/net/l2/openthread/Kconfig | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 8d6b5e54fd0..881585e5578 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -60,6 +60,18 @@ CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_ENTRIES #endif +/** + * @def CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES + * + * The maximum number of EID-to-RLOC cache entries that can be used for + * "snoop optimization" where an entry is created by inspecting a received message. + * + */ +#ifdef CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES +#define OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES \ + CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES +#endif + /** * @def OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL * diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index f8803b316de..70c7d642674 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -289,6 +289,14 @@ config OPENTHREAD_TMF_ADDRESS_CACHE_ENTRIES help The number of EID-to-RLOC cache entries. +config OPENTHREAD_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES + int "The maximum number of EID-to-RLOC cache entries" + default 2 + help + The maximum number of EID-to-RLOC cache entries that can be used for + "snoop optimization" where an entry is created by inspecting a received + message. + config OPENTHREAD_LOG_PREPEND_LEVEL_ENABLE bool "Prepending the log level to all OpenThread log messages" help From e60878e7eb9d8e37dd7334d600ff1d7a40fdf861 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 10:58:49 +0100 Subject: [PATCH 3232/4498] nrf52_bsim: Remove nfct peripheral from DT This board HW models do not yet support the NFCT peripheral, let's remove the DT node to avoid the driver being selected. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/nrf52_bsim.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/posix/nrf_bsim/nrf52_bsim.dts b/boards/posix/nrf_bsim/nrf52_bsim.dts index 9c01240540e..a408ceb0eee 100644 --- a/boards/posix/nrf_bsim/nrf52_bsim.dts +++ b/boards/posix/nrf_bsim/nrf52_bsim.dts @@ -54,6 +54,7 @@ /delete-node/ spi@40004000; /delete-node/ spi@40023000; /delete-node/ spi@4002f000; + /delete-node/ nfct@40005000; /delete-node/ watchdog@40010000; /delete-node/ acl@4001e000; /delete-node/ usbd@40027000; From 38060ea2a009f2c807c1122f4912347928ec1803 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 7 Nov 2023 11:18:35 +0000 Subject: [PATCH 3233/4498] tests: boot: mcuboot_recovery_retention: Move USB CDC to USB device Moves the USB CDC device to the USB CDC port instead of wrongly using the serial port, this was not used but is needed to prevent a build error added to MCUboot which prevents using the same device for console and serial recovery chosen nodes Signed-off-by: Jamie McCrae --- .../boards/nrf52840dk_nrf52840.overlay | 9 +++++++++ .../boards/nrf52840dk_nrf52840_mem.overlay | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840.overlay b/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840.overlay index 2257c1a8888..bd69d21527d 100644 --- a/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840.overlay +++ b/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840.overlay @@ -3,6 +3,7 @@ / { chosen { zephyr,boot-mode = &boot_mode0; + zephyr,uart-mcumgr = &cdc_acm_uart; }; }; @@ -16,6 +17,14 @@ }; }; +&zephyr_udc0 { + status = "okay"; + + cdc_acm_uart: cdc_acm_uart { + compatible = "zephyr,cdc-acm-uart"; + }; +}; + /delete-node/ &boot_partition; /delete-node/ &slot0_partition; /delete-node/ &slot1_partition; diff --git a/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840_mem.overlay b/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840_mem.overlay index 907b1c0cb50..a6b9dc2e528 100644 --- a/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840_mem.overlay +++ b/tests/boot/mcuboot_recovery_retention/boards/nrf52840dk_nrf52840_mem.overlay @@ -26,6 +26,15 @@ chosen { zephyr,boot-mode = &boot_mode0; + zephyr,uart-mcumgr = &cdc_acm_uart; + }; +}; + +&zephyr_udc0 { + status = "okay"; + + cdc_acm_uart: cdc_acm_uart { + compatible = "zephyr,cdc-acm-uart"; }; }; From 5d3ae7690a7d6075f4ec1594f70e2e34a9b2f136 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 7 Nov 2023 10:26:14 +0000 Subject: [PATCH 3234/4498] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 0c0470e294dcfb52aab92299356a5f3caa0aa52b Brings following Zephyr relevant fixes: - e9fccef5 boot_serial: Fix missing response if echo command disabled - 013c9e76 boot: zephyr: board: various: Remove size optimisation - 0a8bbbf4 boot: zephyr: Fix USB configs - d5c963c5 boot: zephyr: serial_adapter: Add error if main thread not preemptible - 822b6cb7 boot: zephyr: serial_adapter: Fail if USB CDC enabled with console Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index bde31c3303e..9326bd85722 100644 --- a/west.yml +++ b/west.yml @@ -282,7 +282,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 4a1effbc301fc302ecbaf40d4eb2be520b53010d + revision: 0c0470e294dcfb52aab92299356a5f3caa0aa52b path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From 5730dd6fb75e4b405e40580d8f1562a2a9352516 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 7 Nov 2023 12:39:49 +0100 Subject: [PATCH 3235/4498] doc: fix typos Add missed "space". Add missed "been". Signed-off-by: Andrej Butok --- doc/develop/env_vars.rst | 2 +- doc/kernel/services/synchronization/mutexes.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/develop/env_vars.rst b/doc/develop/env_vars.rst index 459c62b580a..fba31b7735e 100644 --- a/doc/develop/env_vars.rst +++ b/doc/develop/env_vars.rst @@ -72,7 +72,7 @@ Option 2: In all Terminals You can then run ``rapidee`` from your terminal to launch the program and set environment variables. Make sure to use the "User" environment variables area -- otherwise, you have to run RapidEE as administrator. Also make sure to save - your changes by clicking the Save button at top left before exiting.Settings + your changes by clicking the Save button at top left before exiting. Settings you make in RapidEE will be available whenever you open a new terminal window. .. _env_vars_zephyrrc: diff --git a/doc/kernel/services/synchronization/mutexes.rst b/doc/kernel/services/synchronization/mutexes.rst index b813fec2d68..8fa7d150422 100644 --- a/doc/kernel/services/synchronization/mutexes.rst +++ b/doc/kernel/services/synchronization/mutexes.rst @@ -20,7 +20,7 @@ is referenced by its memory address. A mutex has the following key properties: -* A **lock count** that indicates the number of times the mutex has be locked +* A **lock count** that indicates the number of times the mutex has been locked by the thread that has locked it. A count of zero indicates that the mutex is unlocked. From dc92b32ceb5d41d722249057219f9983c7e8f5de Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 7 Nov 2023 13:11:42 +0100 Subject: [PATCH 3236/4498] doc: fix link to extensions.cmake "cmake/extensions.cmake" does not exist. The link is broken. Fix it to correct one "cmake/modules/extensions.cmake". Signed-off-by: Andrej Butok --- doc/develop/application/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index 148cb50f936..f2be0d8b551 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -702,7 +702,7 @@ be useful for glue code to have access to Zephyr kernel header files. To make it easier to integrate third-party components, the Zephyr build system has defined CMake functions that give application build scripts access to the zephyr compiler options. The functions are -documented and defined in :zephyr_file:`cmake/extensions.cmake` +documented and defined in :zephyr_file:`cmake/modules/extensions.cmake` and follow the naming convention ``zephyr_get__``. The following variables will often need to be exported to the From 583fd8a79e74e5f59f938bde53fec0a53a80f79a Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 7 Nov 2023 14:30:28 +0100 Subject: [PATCH 3237/4498] doc: slist: fix duplicated sys_sfnode_flags_get() Replace duplicated sys_sfnode_flags_get() by sys_sfnode_flags_set(). Signed-off-by: Andrej Butok --- doc/kernel/data_structures/slist.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/kernel/data_structures/slist.rst b/doc/kernel/data_structures/slist.rst index add76e869a6..c1eb062ff83 100644 --- a/doc/kernel/data_structures/slist.rst +++ b/doc/kernel/data_structures/slist.rst @@ -108,7 +108,7 @@ ways identically to the slist API. It adds the ability to associate exactly two bits of user defined "flags" with each list node. These can be accessed and modified with -:c:func:`sys_sfnode_flags_get` and :c:func:`sys_sfnode_flags_get`. +:c:func:`sys_sfnode_flags_get` and :c:func:`sys_sfnode_flags_set`. Internally, the flags are stored unioned with the bottom bits of the next pointer and incur no SRAM storage overhead when compared with the simpler slist code. From 07328c4afaf1545e6814799ae9fb3b32458c7ef0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 7 Nov 2023 14:41:25 +0000 Subject: [PATCH 3238/4498] doc: migration-guide: 3.6: Add note on MCUboot Kconfig Adds a note about how to replicate the functionality of the now removed MCUboot mass erase Kconfig option Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-3.6.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 9c2cc98c2ae..ca73ed0ae82 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -59,6 +59,10 @@ Power Management Bootloader ========== +* MCUboot's deprecated ``CONFIG_ZEPHYR_TRY_MASS_ERASE`` Kconfig option has been removed. If an + erase is needed when flashing MCUboot, this should now be provided directly to the ``west`` + command e.g. ``west flash --erase``. + Bluetooth ========= From 09be84eb77eda34c4fd5559c9a2ca25663b1b20d Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Tue, 7 Nov 2023 18:45:05 +0700 Subject: [PATCH 3239/4498] drivers: nxp_s32_netc: remove dependency to NET_TEST There is no require to prevent building nxp s32 netc shim driver if NET_TEST is set, so just remove this unnecessary dependency Fix #64944 Signed-off-by: Dat Nguyen Duy --- drivers/ethernet/Kconfig.nxp_s32_netc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ethernet/Kconfig.nxp_s32_netc b/drivers/ethernet/Kconfig.nxp_s32_netc index e73f65502a3..6c568ca211e 100644 --- a/drivers/ethernet/Kconfig.nxp_s32_netc +++ b/drivers/ethernet/Kconfig.nxp_s32_netc @@ -1,11 +1,10 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 menuconfig ETH_NXP_S32_NETC bool "NXP S32 Ethernet Switch and Controller (NETC) driver" default y depends on (DT_HAS_NXP_S32_NETC_PSI_ENABLED || DT_HAS_NXP_S32_NETC_VSI_ENABLED) - depends on !NET_TEST select MBOX select MDIO if DT_HAS_NXP_S32_NETC_PSI_ENABLED select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT From c6b86d5b1bc1d23f8cdc600283f9614cc168f539 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Tue, 7 Nov 2023 21:00:51 +0700 Subject: [PATCH 3240/4498] drivers: mdio: mdio nxp s32 netc should depend on eth netc driver MDIO is currently initialized in the ETH NXP S32 NETC driver for Physical Station Interface (PSI), so do not try to build the MDIO driver if the ETH driver is not built Signed-off-by: Dat Nguyen Duy --- drivers/mdio/Kconfig.nxp_s32 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mdio/Kconfig.nxp_s32 b/drivers/mdio/Kconfig.nxp_s32 index 07674f7a57d..61b02d53809 100644 --- a/drivers/mdio/Kconfig.nxp_s32 +++ b/drivers/mdio/Kconfig.nxp_s32 @@ -1,10 +1,11 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 config MDIO_NXP_S32_NETC bool "NXP S32 NETC External MDIO driver" default y depends on DT_HAS_NXP_S32_NETC_EMDIO_ENABLED + depends on ETH_NXP_S32_NETC && DT_HAS_NXP_S32_NETC_PSI_ENABLED select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable NETC External MDIO Controller driver for NXP S32 SoCs. From 4df07224f8dcca5c882be94e28faeb91df5455ca Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 08:49:28 +0100 Subject: [PATCH 3241/4498] drivers ieee802154_nrf5: Fix infinite loop for simulation on stop With CSL enabled, when nrf5_stop is called, nrf_802154_sleep_if_idle() will be called, and if the radio is busy with another task, another IEEE802154_EVENT_RX_OFF event will be pended right away, resulting in another call to nrf5_stop(), effectively busy waiting until the radio has reached idle. In simulation, this whole operation (busy wait loop) is done without letting the CPU sleep, in an infinite loop, and therefore without letting any time pass (note that in the POSIX architecture, no time passes if the CPU does not go to sleep). And therefore the radio will never be done with whatever it is doing, resulting in the simulation being stuck in this loop. Let's add a very minor delay to this loop, which is conditionally compiled only for the POSIX architecture. Which effectively mimics the time it takes for the CPU to loop thru, let's time pass, and allows the radio to eventually be done. Signed-off-by: Alberto Escolar Piedras --- drivers/ieee802154/ieee802154_nrf5.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 891a220e07f..9a02aef7e4c 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -668,6 +668,7 @@ static int nrf5_stop(const struct device *dev) } else { LOG_WRN("Transition to radio sleep cannot be handled."); } + Z_SPIN_DELAY(1); return 0; } #else From cf053d07e37e9ee59c444af3c635317e17123a76 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Wed, 8 Nov 2023 11:06:20 +0800 Subject: [PATCH 3242/4498] test: twister: test_runner remove line number check in log 1. remove the line number check in test vector 2. log_info is not a static method anymore, change test Signed-off-by: Hake Huang --- scripts/tests/twister/test_runner.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index ed0533937b6..50732bf4228 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -785,6 +785,7 @@ def mock_pickle(datafile): ) def test_projectbuilder_log_info( caplog, + mocked_jobserver, inline_logs, read_exception, expected_logs @@ -802,10 +803,14 @@ def mock_abspath(filename, *args, **kwargs): filename = 'dummy_file.log' + env_mock = mock.Mock() + instance_mock = mock.Mock() + + pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) with mock.patch('builtins.open', mock_open), \ mock.patch('os.path.realpath', mock_realpath), \ mock.patch('os.path.abspath', mock_abspath): - ProjectBuilder.log_info(filename, inline_logs) + pb.log_info(filename, inline_logs) assert all([log in caplog.text for log in expected_logs]) @@ -1876,14 +1881,14 @@ def mock_open(fname, *args, **kwargs): TESTDATA_13 = [ ( 'error', True, True, False, - ['INFO twister:runner.py:950 20/25 dummy platform' \ + ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' ERROR dummy reason (cmake)'], None ), ( 'failed', False, False, False, - ['ERROR twister:runner.py:904 dummy platform' \ + ['ERROR dummy platform' \ ' dummy.testsuite.name' \ ' FAILED : dummy reason'], 'INFO - Total complete: 20/ 25 80% skipped: 3,' \ @@ -1891,7 +1896,7 @@ def mock_open(fname, *args, **kwargs): ), ( 'skipped', True, False, False, - ['INFO twister:runner.py:950 20/25 dummy platform' \ + ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' SKIPPED (dummy reason)'], None @@ -1904,7 +1909,7 @@ def mock_open(fname, *args, **kwargs): ), ( 'passed', True, False, True, - ['INFO twister:runner.py:950 20/25 dummy platform' \ + ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' PASSED' \ ' (dummy handler type: dummy dut, 60.000s)'], @@ -1912,7 +1917,7 @@ def mock_open(fname, *args, **kwargs): ), ( 'passed', True, False, False, - ['INFO twister:runner.py:950 20/25 dummy platform' \ + ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' PASSED (build)'], None @@ -1925,7 +1930,7 @@ def mock_open(fname, *args, **kwargs): ), ( 'timeout', True, False, True, - ['INFO twister:runner.py:950 20/25 dummy platform' \ + ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' UNKNOWN' \ ' (dummy handler type: dummy dut, 60.000s/seed: 123)'], @@ -1988,11 +1993,13 @@ def test_projectbuilder_report_out( assert results_mock.cases == 25 - assert all([log in re.sub( + trim_actual_log = re.sub( r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])', '', caplog.text - ) for log in expected_logs]) + ) + trim_actual_log = re.sub(r'twister:runner.py:\d+', '', trim_actual_log) + assert all([log in trim_actual_log for log in expected_logs]) if expected_out: out, err = capfd.readouterr() From 1fd080b8cff68276297fc19525a9ccff8a0c5c39 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Tue, 20 Jun 2023 14:45:39 +0300 Subject: [PATCH 3243/4498] drivers: sdhc: added Infineon CAT1 SDHC/SDIO driver Added initial version of Infineon CAT1 SDHC/SDIO driver Added initial version of binding file for Infineon CAT1 SDHC/SDIO driver Signed-off-by: Nazar Palamar --- drivers/sdhc/CMakeLists.txt | 1 + drivers/sdhc/Kconfig | 1 + drivers/sdhc/Kconfig.ifx_cat1 | 22 ++ drivers/sdhc/ifx_cat1_sdio.c | 332 ++++++++++++++++++ dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi | 7 + dts/arm/infineon/psoc6/psoc6_02/psoc6_02.dtsi | 7 + dts/arm/infineon/psoc6/psoc6_03/psoc6_03.dtsi | 6 + dts/arm/infineon/psoc6/psoc6_04/psoc6_04.dtsi | 6 + .../sdhc/infineon,cat1-sdhc-sdio.yaml | 20 ++ modules/hal_infineon/Kconfig | 7 +- 10 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 drivers/sdhc/Kconfig.ifx_cat1 create mode 100644 drivers/sdhc/ifx_cat1_sdio.c create mode 100644 dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index a43e3f54806..431867fb2b8 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -8,4 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_SPI_SDHC sdhc_spi.c) zephyr_library_sources_ifdef(CONFIG_MCUX_SDIF mcux_sdif.c) zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) zephyr_library_sources_ifdef(CONFIG_INTEL_EMMC_HOST intel_emmc_host.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1 ifx_cat1_sdio.c) endif() diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index 69a942238e4..7e75e03a024 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -8,6 +8,7 @@ menuconfig SDHC if SDHC +source "drivers/sdhc/Kconfig.ifx_cat1" source "drivers/sdhc/Kconfig.imx" source "drivers/sdhc/Kconfig.spi" source "drivers/sdhc/Kconfig.mcux_sdif" diff --git a/drivers/sdhc/Kconfig.ifx_cat1 b/drivers/sdhc/Kconfig.ifx_cat1 new file mode 100644 index 00000000000..13dde4cf18f --- /dev/null +++ b/drivers/sdhc/Kconfig.ifx_cat1 @@ -0,0 +1,22 @@ +# Infineon CAT1 SDHC configuration options + +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +config SDHC_INFINEON_CAT1 + bool "Infineon CAT1 SDHC driver" + default y + depends on DT_HAS_INFINEON_CAT1_SDHC_SDIO_ENABLED + select USE_INFINEON_SDIO + select SDHC_SUPPORTS_NATIVE_MODE + help + This option enables the SDHC driver for Infineon CAT1 family. + +if SDHC_INFINEON_CAT1 + +config SDHC_INIT_PRIORITY + default 70 + +endif diff --git a/drivers/sdhc/ifx_cat1_sdio.c b/drivers/sdhc/ifx_cat1_sdio.c new file mode 100644 index 00000000000..d298e1d7b6b --- /dev/null +++ b/drivers/sdhc/ifx_cat1_sdio.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/** + * @brief SDIO driver for Infineon CAT1 MCU family. + * + * This driver support only SDIO protocol of the SD interface for general + * I/O functions. + * + * Refer to the SD Specifications Part 1 SDIO Specifications Version 4.10 for more + * information on the SDIO protocol and specifications. + * + * Features + * - Supports 4-bit interface + * - Supports Ultra High Speed (UHS-I) mode + * - Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes + * - Supports SDIO card interrupts in both 1-bit SD and 4-bit SD modes + * - Supports Standard capacity (SDSC), High capacity (SDHC) and + * Extended capacity (SDXC) memory + * + * Note (limitations): + * - current version of ifx_cat1_sdio supports only following set of commands: + * > GO_IDLE_STATE (CMD0) + * > SEND_RELATIVE_ADDR (CMD3) + * > IO_SEND_OP_COND (CMD5) + * > SELECT_CARD (CMD7) + * > VOLTAGE_SWITCH (CMD11) + * > GO_INACTIVE_STATE (CMD15) + * > IO_RW_DIRECT (CMD52) + * > IO_RW_EXTENDED (CMD53) + */ + +#define DT_DRV_COMPAT infineon_cat1_sdhc_sdio + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(ifx_cat1_sdio, CONFIG_SDHC_LOG_LEVEL); + +#include + +#define IFX_CAT1_SDIO_F_MIN (SDMMC_CLOCK_400KHZ) +#define IFX_CAT1_SDIO_F_MAX (SD_CLOCK_50MHZ) + +struct ifx_cat1_sdio_config { + const struct pinctrl_dev_config *pincfg; + SDHC_Type *reg_addr; + uint8_t irq_priority; +}; + +struct ifx_cat1_sdio_data { + cyhal_sdio_t sdio_obj; + cyhal_resource_inst_t hw_resource; + cyhal_sdio_configurator_t cyhal_sdio_config; + enum sdhc_clock_speed clock_speed; + enum sdhc_bus_width bus_width; + + void *sdio_cb_user_data; + sdhc_interrupt_cb_t sdio_cb; +}; + +static uint32_t sdio_rca; +static const cy_stc_sd_host_init_config_t host_config = {false, CY_SD_HOST_DMA_ADMA2, false}; +static cy_en_sd_host_card_capacity_t sd_host_card_capacity = CY_SD_HOST_SDSC; +static cy_en_sd_host_card_type_t sd_host_card_type = CY_SD_HOST_NOT_EMMC; +static cy_stc_sd_host_sd_card_config_t sd_host_sd_card_config = { + .lowVoltageSignaling = false, + .busWidth = CY_SD_HOST_BUS_WIDTH_4_BIT, + .cardType = &sd_host_card_type, + .rca = &sdio_rca, + .cardCapacity = &sd_host_card_capacity, +}; + +/* List of available SDHC instances */ +static SDHC_Type *const IFX_CAT1_SDHC_BASE_ADDRESSES[CY_IP_MXSDHC_INSTANCES] = { +#ifdef SDHC0 + SDHC0, +#endif /* ifdef SDHC0 */ + +#ifdef SDHC1 + SDHC1, +#endif /* ifdef SDHC1 */ +}; + +static int32_t _get_hw_block_num(SDHC_Type *reg_addr) +{ + uint32_t i; + + for (i = 0u; i < CY_IP_MXSDHC_INSTANCES; i++) { + if (IFX_CAT1_SDHC_BASE_ADDRESSES[i] == reg_addr) { + return i; + } + } + + return -EINVAL; +} + +static int ifx_cat1_sdio_reset(const struct device *dev) +{ + struct ifx_cat1_sdio_data *dev_data = dev->data; + + cyhal_sdhc_software_reset((cyhal_sdhc_t *)&dev_data->sdio_obj); + + return 0; +} + +static int ifx_cat1_sdio_set_io(const struct device *dev, struct sdhc_io *ios) +{ + cy_rslt_t ret; + struct ifx_cat1_sdio_data *dev_data = dev->data; + cyhal_sdio_cfg_t config = {.frequencyhal_hz = ios->clock}; + + /* NOTE: Set bus width, set card power, set host signal voltage, + * set I/O timing does not support in current version of driver + */ + + /* Set host clock */ + if ((dev_data->clock_speed != ios->clock) && (ios->clock != 0)) { + + if ((ios->clock > IFX_CAT1_SDIO_F_MAX) || (ios->clock < IFX_CAT1_SDIO_F_MIN)) { + return -EINVAL; + } + + ret = cyhal_sdio_configure(&dev_data->sdio_obj, &config); + if (ret != CY_RSLT_SUCCESS) { + return -ENOTSUP; + } + + dev_data->clock_speed = ios->clock; + } + + return 0; +} + +static int ifx_cat1_sdio_card_busy(const struct device *dev) +{ + struct ifx_cat1_sdio_data *dev_data = dev->data; + + return cyhal_sdio_is_busy(&dev_data->sdio_obj) ? 1 : 0; +} + +static int ifx_cat1_sdio_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *data) +{ + struct ifx_cat1_sdio_data *dev_data = dev->data; + int ret; + + switch (cmd->opcode) { + case CYHAL_SDIO_CMD_GO_IDLE_STATE: + case CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR: + case CYHAL_SDIO_CMD_IO_SEND_OP_COND: + case CYHAL_SDIO_CMD_SELECT_CARD: + case CYHAL_SDIO_CMD_VOLTAGE_SWITCH: + case CYHAL_SDIO_CMD_GO_INACTIVE_STATE: + case CYHAL_SDIO_CMD_IO_RW_DIRECT: + ret = cyhal_sdio_send_cmd(&dev_data->sdio_obj, CYHAL_SDIO_XFER_TYPE_READ, + cmd->opcode, cmd->arg, cmd->response); + if (ret != CY_RSLT_SUCCESS) { + LOG_ERR("cyhal_sdio_send_cmd failed ret = %d \r\n", ret); + } + break; + + case CYHAL_SDIO_CMD_IO_RW_EXTENDED: + cyhal_sdio_transfer_type_t direction; + + direction = (cmd->arg & BIT(SDIO_CMD_ARG_RW_SHIFT)) ? CYHAL_SDIO_XFER_TYPE_WRITE + : CYHAL_SDIO_XFER_TYPE_READ; + + ret = cyhal_sdio_bulk_transfer(&dev_data->sdio_obj, direction, cmd->arg, data->data, + data->blocks * data->block_size, cmd->response); + + if (ret != CY_RSLT_SUCCESS) { + LOG_ERR("cyhal_sdio_bulk_transfer failed ret = %d \r\n", ret); + } + break; + + default: + ret = -ENOTSUP; + } + + return ret; +} + +static int ifx_cat1_sdio_get_card_present(const struct device *dev) +{ + return 1; +} + +static int ifx_cat1_sdio_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + memset(props, 0, sizeof(*props)); + props->f_max = IFX_CAT1_SDIO_F_MAX; + props->f_min = IFX_CAT1_SDIO_F_MIN; + props->host_caps.bus_4_bit_support = true; + props->host_caps.high_spd_support = true; + props->host_caps.sdr50_support = true; + props->host_caps.sdio_async_interrupt_support = true; + props->host_caps.vol_330_support = true; + + return 0; +} + +static int ifx_cat1_sdio_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, + int sources, void *user_data) +{ + struct ifx_cat1_sdio_data *data = dev->data; + const struct ifx_cat1_sdio_config *cfg = dev->config; + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + if (callback == NULL) { + return -EINVAL; + } + + /* Record SDIO callback parameters */ + data->sdio_cb = callback; + data->sdio_cb_user_data = user_data; + + /* Enable CARD INTERRUPT event */ + cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, + cfg->irq_priority, true); + + return 0; +} + +static int ifx_cat1_sdio_disable_interrupt(const struct device *dev, int sources) +{ + struct ifx_cat1_sdio_data *data = dev->data; + const struct ifx_cat1_sdio_config *cfg = dev->config; + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + data->sdio_cb = NULL; + data->sdio_cb_user_data = NULL; + + /* Disable CARD INTERRUPT event */ + cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, + cfg->irq_priority, false); + + return 0; +} + +static void ifx_cat1_sdio_event_callback(void *callback_arg, cyhal_sdio_event_t event) +{ + const struct device *dev = callback_arg; + struct ifx_cat1_sdio_data *data = dev->data; + + if ((event == CYHAL_SDIO_CARD_INTERRUPT) && (data->sdio_cb != NULL)) { + data->sdio_cb(dev, SDHC_INT_SDIO, data->sdio_cb_user_data); + } +} + +static int ifx_cat1_sdio_init(const struct device *dev) +{ + cy_rslt_t ret; + struct ifx_cat1_sdio_data *data = dev->data; + const struct ifx_cat1_sdio_config *config = dev->config; + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (ret) { + return ret; + } + + /* Dedicate SDIO HW resource */ + data->hw_resource.type = CYHAL_RSC_SDIODEV; + data->hw_resource.block_num = _get_hw_block_num(config->reg_addr); + + /* Initialize the SDIO peripheral */ + data->cyhal_sdio_config.resource = &data->hw_resource; + data->cyhal_sdio_config.host_config = &host_config, + data->cyhal_sdio_config.card_config = &sd_host_sd_card_config, + + ret = cyhal_sdio_init_cfg(&data->sdio_obj, &data->cyhal_sdio_config); + if (ret != CY_RSLT_SUCCESS) { + LOG_ERR("cyhal_sdio_init_cfg failed ret = %d \r\n", ret); + return ret; + } + + /* Register callback for SDIO events */ + cyhal_sdio_register_callback(&data->sdio_obj, ifx_cat1_sdio_event_callback, (void *)dev); + + return 0; +} + +static const struct sdhc_driver_api ifx_cat1_sdio_api = { + .reset = ifx_cat1_sdio_reset, + .request = ifx_cat1_sdio_request, + .set_io = ifx_cat1_sdio_set_io, + .get_card_present = ifx_cat1_sdio_get_card_present, + .card_busy = ifx_cat1_sdio_card_busy, + .get_host_props = ifx_cat1_sdio_get_host_props, + .enable_interrupt = ifx_cat1_sdio_enable_interrupt, + .disable_interrupt = ifx_cat1_sdio_disable_interrupt, +}; + +#define IFX_CAT1_SDHC_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct ifx_cat1_sdio_config ifx_cat1_sdio_##n##_config = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .reg_addr = (SDHC_Type *)DT_INST_REG_ADDR(n), \ + .irq_priority = DT_INST_IRQ(n, priority)}; \ + \ + static struct ifx_cat1_sdio_data ifx_cat1_sdio_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, &ifx_cat1_sdio_init, NULL, &ifx_cat1_sdio_##n##_data, \ + &ifx_cat1_sdio_##n##_config, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ + &ifx_cat1_sdio_api); + +DT_INST_FOREACH_STATUS_OKAY(IFX_CAT1_SDHC_INIT) diff --git a/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi b/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi index 4f3b420d3e5..56957dddab0 100644 --- a/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi +++ b/dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi @@ -537,5 +537,12 @@ resolution = <16>; status = "disabled"; }; + + sdhc0: sdhc@40460000 { + compatible = "infineon,cat1-sdhc-sdio"; + reg = <0x40460000 0x2000>; + interrupts = <164 6>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/infineon/psoc6/psoc6_02/psoc6_02.dtsi b/dts/arm/infineon/psoc6/psoc6_02/psoc6_02.dtsi index a4109291dfd..c61ba9e0ca4 100644 --- a/dts/arm/infineon/psoc6/psoc6_02/psoc6_02.dtsi +++ b/dts/arm/infineon/psoc6/psoc6_02/psoc6_02.dtsi @@ -541,5 +541,12 @@ resolution = <16>; status = "disabled"; }; + + sdhc0: sdhc@40460000 { + compatible = "infineon,cat1-sdhc-sdio"; + reg = <0x40460000 0x2000>; + interrupts = <164 6>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/infineon/psoc6/psoc6_03/psoc6_03.dtsi b/dts/arm/infineon/psoc6/psoc6_03/psoc6_03.dtsi index 8e8ada040d2..14aefdc5ada 100644 --- a/dts/arm/infineon/psoc6/psoc6_03/psoc6_03.dtsi +++ b/dts/arm/infineon/psoc6/psoc6_03/psoc6_03.dtsi @@ -241,6 +241,12 @@ interrupts = <18 6>; status = "disabled"; }; + sdhc0: sdhc@40460000 { + compatible = "infineon,cat1-sdhc-sdio"; + reg = <0x40460000 0x2000>; + interrupts = <164 6>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/infineon/psoc6/psoc6_04/psoc6_04.dtsi b/dts/arm/infineon/psoc6/psoc6_04/psoc6_04.dtsi index 73282624e3f..d44b0583f70 100644 --- a/dts/arm/infineon/psoc6/psoc6_04/psoc6_04.dtsi +++ b/dts/arm/infineon/psoc6/psoc6_04/psoc6_04.dtsi @@ -247,6 +247,12 @@ interrupts = <18 6>; status = "disabled"; }; + sdhc0: sdhc@40460000 { + compatible = "infineon,cat1-sdhc-sdio"; + reg = <0x40460000 0x2000>; + interrupts = <164 6>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml b/dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml new file mode 100644 index 00000000000..8bb1071b02b --- /dev/null +++ b/dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: Infineon CAT1 SDHC/SDIO controller + +compatible: "infineon,cat1-sdhc-sdio" + +include: [sdhc.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index 0522c96769c..83d24bfacd5 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -27,6 +27,12 @@ config USE_INFINEON_SDIO Enable Secure Digital Input/Output interface (SDIO) HAL module for Infineon devices driver +config USE_INFINEON_SDHC + bool + help + Enable SDHC HAL module for Infineon devices + driver + config USE_INFINEON_SPI bool help @@ -68,7 +74,6 @@ config USE_INFINEON_WDT config ABSTRACTION_RTOS_COMPONENT_ZEPHYR bool "Abstraction RTOS component (Zephyr support)" - default n help Enable Abstraction RTOS component with Zephyr support From 5c3abe9197445547820e65e6ac01c86551a37e17 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Wed, 4 Oct 2023 09:54:18 +0300 Subject: [PATCH 3244/4498] drivers: bluetooth: rename BT_CYW43XXX to BT_AIROC rename BT_CYW43XXX to BT_AIROC to be compatible with WIFI_AIROC Signed-off-by: Nazar Palamar --- boards/arm/arduino_giga_r1/Kconfig.defconfig | 2 +- drivers/bluetooth/hci/CMakeLists.txt | 2 +- drivers/bluetooth/hci/Kconfig | 4 ++-- drivers/bluetooth/hci/Kconfig.infineon | 20 +++++++++---------- modules/hal_infineon/CMakeLists.txt | 4 ++-- .../btstack-integration/CMakeLists.txt | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/boards/arm/arduino_giga_r1/Kconfig.defconfig b/boards/arm/arduino_giga_r1/Kconfig.defconfig index 5880f88f7e0..e72fb499055 100644 --- a/boards/arm/arduino_giga_r1/Kconfig.defconfig +++ b/boards/arm/arduino_giga_r1/Kconfig.defconfig @@ -9,7 +9,7 @@ config BOARD if BT -choice CYW43XXX_PART +choice AIROC_PART default CYW4343W endchoice diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index b4417a72e8f..6aaf5205b0d 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -14,7 +14,7 @@ if(CONFIG_BT_HCI_IPC) endif() zephyr_library_sources_ifdef(CONFIG_BT_B91 hci_b91.c) -zephyr_library_sources_ifdef(CONFIG_BT_CYW43XXX cyw43xxx.c) +zephyr_library_sources_ifdef(CONFIG_BT_AIROC cyw43xxx.c) zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c) zephyr_library_sources_ifdef(CONFIG_BT_H4 h4.c) zephyr_library_sources_ifdef(CONFIG_BT_H5 h5.c) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 9c02c1a61c3..835b90edd54 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -137,8 +137,8 @@ config BT_STM32_IPM_RX_STACK_SIZE depends on BT_STM32_IPM default 512 -menuconfig BT_CYW43XXX - bool "CYW43XXX BT connectivity" +menuconfig BT_AIROC + bool "AIROC BT connectivity" default y select BT_HCI_SETUP depends on GPIO diff --git a/drivers/bluetooth/hci/Kconfig.infineon b/drivers/bluetooth/hci/Kconfig.infineon index d0e4478ac34..1f4193bd28a 100644 --- a/drivers/bluetooth/hci/Kconfig.infineon +++ b/drivers/bluetooth/hci/Kconfig.infineon @@ -2,10 +2,10 @@ # an affiliate of Cypress Semiconductor Corporation # SPDX-License-Identifier: Apache-2.0 -if BT_CYW43XXX +if BT_AIROC -choice CYW43XXX_PART - prompt "Select CYW43XXX part" +choice AIROC_PART + prompt "Select AIROC part" config CYW4343W bool "CYW4343W" @@ -42,12 +42,12 @@ config CYW43439 More information about CYW43439 device you can find on https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43439/ -config BT_CYW43XXX_CUSTOM - bool "Custom CYW43xx device/module" +config BT_AIROC_CUSTOM + bool "Custom AIROC device/module" help - Select Custom CYW43xx device/module. For this option, + Select Custom AIROC device/module. For this option, user must to provide path to BT firmware HCD file for - custom or vendor CYW43xx modules in CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB. + custom or vendor AIROC modules in AIROC_CUSTOM_FIRMWARE_HCD_BLOB. endchoice @@ -117,8 +117,8 @@ config CYW43439_MURATA_1YN endchoice -config CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB - depends on BT_CYW43XXX_CUSTOM +config AIROC_CUSTOM_FIRMWARE_HCD_BLOB + depends on BT_AIROC_CUSTOM string "Path to user BT firmware HCD file" help Path to BT firmware HCD file for custom or vendor CYW43xx modules. @@ -134,7 +134,7 @@ config BT_BUF_CMD_TX_SIZE config BT_ATT_ENFORCE_FLOW default n -endif # BT_CYW43XXX +endif # BT_AIROC if BT_PSOC6_BLESS diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index aff4d21f0aa..1db3cf57a6a 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -36,8 +36,8 @@ if (CONFIG_SOC_FAMILY_INFINEON_CAT1A) add_subdirectory(abstraction-rtos) endif() -## Add btstack-integration for CYW43xx BT devices -if (CONFIG_BT_CYW43XXX) +## Add BT assets for AIROC devices +if (CONFIG_BT_AIROC) add_subdirectory(btstack-integration) endif() diff --git a/modules/hal_infineon/btstack-integration/CMakeLists.txt b/modules/hal_infineon/btstack-integration/CMakeLists.txt index ef6a64cff3d..d82fe10662d 100644 --- a/modules/hal_infineon/btstack-integration/CMakeLists.txt +++ b/modules/hal_infineon/btstack-integration/CMakeLists.txt @@ -30,13 +30,13 @@ if(CONFIG_CYW4373_STERLING_LWB5PLUS) set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/bt_firmware.hcd) endif() -# use user provided FIRMWARE HCD file (path must be defined in CONFIG_CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB) -if(CONFIG_CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB) +# use user provided FIRMWARE HCD file (path must be defined in CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB) +if(CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB) # Allowed to pass absolute path to HCD blob file, or relative path from Application folder. - if(IS_ABSOLUTE ${CONFIG_CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB}) - set(blob_hcd_file ${CONFIG_CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB}) + if(IS_ABSOLUTE ${CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB}) + set(blob_hcd_file ${CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB}) else() - set(blob_hcd_file ${APPLICATION_SOURCE_DIR}/${CONFIG_CYW43XX_CUSTOM_FIRMWARE_HCD_BLOB}) + set(blob_hcd_file ${APPLICATION_SOURCE_DIR}/${CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB}) endif() endif() From 4fd732a7387524a18b10fd0657bf37cd66153e09 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Wed, 4 Oct 2023 09:29:17 +0300 Subject: [PATCH 3245/4498] drivers: wifi: added Infineon AIROC WIFI driver Added initial version of Infineon AIROC WIFI driver Added initial version of binding file for Infineon AIROC WIFI driver Rename CONFIG_ABSTRACTION_RTOS_COMPONENT_ZEPHYR to CONFIG_USE_INFINEON_ABSTRACTION_RTOS Exclude cy8cproto_062_4343w platform from drivers.modem.esp_at.build test Change revision hal_infineon to 69c883d3bd9fac8a18dd8384624b8c472a68d06f Signed-off-by: Nazar Palamar --- drivers/wifi/CMakeLists.txt | 1 + drivers/wifi/Kconfig | 1 + drivers/wifi/infineon/CMakeLists.txt | 13 + drivers/wifi/infineon/Kconfig.airoc | 150 ++++ drivers/wifi/infineon/airoc_whd_hal.c | 438 ++++++++++ drivers/wifi/infineon/airoc_wifi.c | 772 ++++++++++++++++++ drivers/wifi/infineon/airoc_wifi.h | 50 ++ drivers/wifi/infineon/cybsp.h | 8 + dts/bindings/wifi/infineon,airoc-wifi.yaml | 50 ++ modules/hal_infineon/CMakeLists.txt | 5 + modules/hal_infineon/Kconfig | 2 +- .../abstraction-rtos/CMakeLists.txt | 4 +- .../wifi-host-driver/CMakeLists.txt | 216 +++++ .../net/wifi/boards/cy8cproto_062_4343w.conf | 3 + tests/drivers/build_all/modem/testcase.yaml | 4 +- west.yml | 2 +- 16 files changed, 1714 insertions(+), 5 deletions(-) create mode 100644 drivers/wifi/infineon/CMakeLists.txt create mode 100644 drivers/wifi/infineon/Kconfig.airoc create mode 100644 drivers/wifi/infineon/airoc_whd_hal.c create mode 100644 drivers/wifi/infineon/airoc_wifi.c create mode 100644 drivers/wifi/infineon/airoc_wifi.h create mode 100644 drivers/wifi/infineon/cybsp.h create mode 100644 dts/bindings/wifi/infineon,airoc-wifi.yaml create mode 100644 modules/hal_infineon/wifi-host-driver/CMakeLists.txt create mode 100644 samples/net/wifi/boards/cy8cproto_062_4343w.conf diff --git a/drivers/wifi/CMakeLists.txt b/drivers/wifi/CMakeLists.txt index b12ecf88a3e..df1e7c39465 100644 --- a/drivers/wifi/CMakeLists.txt +++ b/drivers/wifi/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32) add_subdirectory_ifdef(CONFIG_WIFI_ESWIFI eswifi) add_subdirectory_ifdef(CONFIG_WIFI_SIMPLELINK simplelink) add_subdirectory_ifdef(CONFIG_WIFI_WINC1500 winc1500) +add_subdirectory_ifdef(CONFIG_WIFI_AIROC infineon) diff --git a/drivers/wifi/Kconfig b/drivers/wifi/Kconfig index 4bb4197bede..d7133f5be04 100644 --- a/drivers/wifi/Kconfig +++ b/drivers/wifi/Kconfig @@ -40,5 +40,6 @@ source "drivers/wifi/simplelink/Kconfig.simplelink" source "drivers/wifi/eswifi/Kconfig.eswifi" source "drivers/wifi/esp_at/Kconfig.esp_at" source "drivers/wifi/esp32/Kconfig.esp32" +source "drivers/wifi/infineon/Kconfig.airoc" endif # WIFI diff --git a/drivers/wifi/infineon/CMakeLists.txt b/drivers/wifi/infineon/CMakeLists.txt new file mode 100644 index 00000000000..20f69f18111 --- /dev/null +++ b/drivers/wifi/infineon/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(./) + +zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_wifi.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_whd_hal.c) + +zephyr_compile_definitions(CYBSP_WIFI_CAPABLE) +zephyr_compile_definitions(CY_RTOS_AWARE) +zephyr_compile_definitions(WHD_USE_CUSTOM_MALLOC_IMPL) +zephyr_compile_definitions(WHD_USE_CUSTOM_HAL_IMPL) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc new file mode 100644 index 00000000000..993fbdad212 --- /dev/null +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -0,0 +1,150 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig WIFI_AIROC + bool "Infineon AIROC SoC Wi-Fi support" + select THREAD_CUSTOM_DATA + select WIFI_OFFLOAD + select NET_L2_WIFI_MGMT + select SDIO_STACK + select SDHC + select WIFI_USE_NATIVE_NETWORKING + select USE_INFINEON_ABSTRACTION_RTOS + depends on DT_HAS_INFINEON_AIROC_WIFI_ENABLED + help + Enable Infineon AIROC SoC Wi-Fi support. + +if WIFI_AIROC + +if SHELL +config SHELL_STACK_SIZE + default 4096 +endif # SHELL + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 4096 + +config AIROC_WIFI_EVENT_TASK_STACK_SIZE + int "Event Task Stack Size" + default 4096 + +config AIROC_WIFI_EVENT_TASK_PRIO + int "Event Task Priority" + default 4 + +config AIROC_WLAN_MFG_FIRMWARE + bool "WLAN Manufacturing Firmware" + help + Enable WLAN Manufacturing Firmware. + +config AIROC_WIFI_CUSTOM + bool "Custom CYW43xx device/module" + help + Select Custom CYW43xx device/module. For this option, + user must to provide path to FW, CLM and NVRAM for + custom or vendor CYW43xx modules. + +choice AIROC_PART + prompt "Select AIROC part" + depends on !AIROC_WIFI_CUSTOM + +config CYW4343W + bool "CYW4343W" + help + Enable Infineon AIROC CYW4343W Wi-Fi connectivity, + More information about CYW4343W device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw4343w/ + +config CYW4373 + bool "CYW4373" + help + Enable Infineon AIROC CYW4373 Wi-Fi connectivity, + More information about CYW4373 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw4373/ + +config CYW43012 + bool "CYW43012" + help + Enable Infineon AIROC CYW43012 Wi-Fi connectivity, + More information about CYW43012 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43012/ + +config CYW43438 + bool "CYW43438" + help + Enable Infineon AIROC CYW43438 Wi-Fi connectivity, + More information about CYW43438 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43438/ + +config CYW43439 + bool "CYW43439" + help + Enable Infineon AIROC CYW43439 Wi-Fi connectivity, + More information about CYW43439 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43439/ +endchoice + +choice CYW43012_MODULE + prompt "Select CYW43012 module" + depends on CYW43012 && !AIROC_WIFI_CUSTOM + +config CYW43012_MURATA_1LV + bool "MURATA-1LV" + help + Murata Type 1LV module based on Infineon CYW43012 combo chipset + which supports Wi-Fi® 802.11a/b/g/n + Bluetooth® 5.0 BR/EDR/LE + up to 72.2Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate + on Bluetooth®. 2Mbps LE PHY is also supported. + + Detailed information about Murata Type 1LV module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1lv +endchoice + +choice CYW4343W_MODULE + prompt "Select CYW4343W module" + depends on CYW4343W && !AIROC_WIFI_CUSTOM + +config CYW4343W_MURATA_1DX + bool "MURATA-1DX" + help + Murata Type 1DX modules based on Infineon CYW4343W combo chipset + which supports Wi-Fi® 802.11b/g/n + Bluetooth® 5.1 BR/EDR/LE + up to 65Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate + on Bluetooth®. + + Detailed information about Type 1DX module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1dx +endchoice + +choice CYW4373_MODULE + prompt "Select CYW4373 module" + depends on CYW4373 && !AIROC_WIFI_CUSTOM + +config CYW4373_STERLING_LWB5PLUS + bool "STERLING-LWB5plus" + help + Laird Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board + (E-Type Key w/ SDIO/UART) + + Detailed information about Type Sterling LWB5+ module you can find on + https://www.lairdconnect.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module +endchoice + +choice CYW43439_MODULE + prompt "Select CYW43439 module" + depends on CYW43439 && !AIROC_WIFI_CUSTOM + +config CYW43439_MURATA_1YN + bool "MURATA_1YN" + help + Murata Type 1YN module based on Infineon CYW43439 combo chipset + which supports Wi-Fi® 802.11b/g/n + Bluetooth® 5.2 BR/EDR/LE + up to 65Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate on + Bluetooth®. + + Detailed information about Murata Type 1YN module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1yn +endchoice + +endif # AIROC_WIFI diff --git a/drivers/wifi/infineon/airoc_whd_hal.c b/drivers/wifi/infineon/airoc_whd_hal.c new file mode 100644 index 00000000000..5b02d0bba49 --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal.c @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#define DT_DRV_COMPAT infineon_airoc_wifi + +LOG_MODULE_REGISTER(infineon_airoc, CONFIG_WIFI_LOG_LEVEL); + +#ifdef __cplusplus +extern "C" { +#endif + +/** Defines the amount of stack memory available for the wifi thread. */ +#if !defined(CY_WIFI_THREAD_STACK_SIZE) +#define CY_WIFI_THREAD_STACK_SIZE (5120) +#endif + +/** Defines the priority of the thread that services wifi packets. Legal values are defined by the + * RTOS being used. + */ +#if !defined(CY_WIFI_THREAD_PRIORITY) +#define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH) +#endif + +/** Defines the country this will operate in for wifi initialization parameters. See the + * wifi-host-driver's whd_country_code_t for legal options. + */ +#if !defined(CY_WIFI_COUNTRY) +#define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA) +#endif + +/** Defines the priority of the interrupt that handles out-of-band notifications from the wifi + * chip. Legal values are defined by the MCU running this code. + */ +#if !defined(CY_WIFI_OOB_INTR_PRIORITY) +#define CY_WIFI_OOB_INTR_PRIORITY (2) +#endif + +/** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */ +#if defined(CY_WIFI_HOST_WAKE_SW_FORCE) +#define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE) +#else +#define CY_USE_OOB_INTR (1u) +#endif /* defined(CY_WIFI_HOST_WAKE_SW_FORCE) */ + +#define CY_WIFI_HOST_WAKE_IRQ_EVENT GPIO_INT_TRIG_LOW +#define DEFAULT_OOB_PIN (0) +#define WLAN_POWER_UP_DELAY_MS (250) +#define WLAN_CBUCK_DISCHARGE_MS (10) + +extern whd_resource_source_t resource_ops; + +struct whd_bus_priv { + whd_sdio_config_t sdio_config; + whd_bus_stats_t whd_bus_stats; + whd_sdio_t sdio_obj; +}; + +static whd_init_config_t init_config_default = { + .thread_stack_size = CY_WIFI_THREAD_STACK_SIZE, + .thread_stack_start = NULL, + .thread_priority = (uint32_t)CY_WIFI_THREAD_PRIORITY, + .country = CY_WIFI_COUNTRY +}; + +/****************************************************** + * Function + ******************************************************/ + +int airoc_wifi_power_on(const struct device *dev) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_reg_on_gpios) + int ret; + const struct airoc_wifi_config *config = dev->config; + + /* Check WIFI REG_ON gpio instance */ + if (!device_is_ready(config->wifi_reg_on_gpio.port)) { + LOG_ERR("Error: failed to configure wifi_reg_on %s pin %d", + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return -EIO; + } + + /* Configure wifi_reg_on as output */ + ret = gpio_pin_configure_dt(&config->wifi_reg_on_gpio, GPIO_OUTPUT); + if (ret) { + LOG_ERR("Error %d: failed to configure wifi_reg_on %s pin %d", ret, + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return ret; + } + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 0); + if (ret) { + return ret; + } + + /* Allow CBUCK regulator to discharge */ + (void)cyhal_system_delay_ms(WLAN_CBUCK_DISCHARGE_MS); + + /* WIFI power on */ + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 1); + if (ret) { + return ret; + } + (void)cyhal_system_delay_ms(WLAN_POWER_UP_DELAY_MS); +#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */ + + return 0; +} + +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if) +{ + int ret; + struct airoc_wifi_data *data = dev->data; + const struct airoc_wifi_config *config = dev->config; + + whd_sdio_config_t whd_sdio_config = { + .sdio_1bit_mode = WHD_FALSE, + .high_speed_sdio_clock = WHD_FALSE, + }; + +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + whd_oob_config_t oob_config = { + .host_oob_pin = (void *)&config->wifi_host_wake_gpio, + .dev_gpio_sel = DEFAULT_OOB_PIN, + .is_falling_edge = + (CY_WIFI_HOST_WAKE_IRQ_EVENT == GPIO_INT_TRIG_LOW) ? WHD_TRUE : WHD_FALSE, + .intr_priority = CY_WIFI_OOB_INTR_PRIORITY}; + whd_sdio_config.oob_config = oob_config; +#endif + + if (airoc_wifi_power_on(dev)) { + LOG_ERR("airoc_wifi_power_on retuens fail"); + return -ENODEV; + } + + if (!device_is_ready(config->sdhc_dev)) { + LOG_ERR("SDHC device is not ready"); + return -ENODEV; + } + + ret = sd_init(config->sdhc_dev, &data->card); + if (ret) { + return ret; + } + + /* Init SDIO functions */ + ret = sdio_init_func(&data->card, &data->sdio_func1, BACKPLANE_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_init_func(&data->card, &data->sdio_func2, WLAN_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func WLAN_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func1, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func2, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for WLAN_FUNCTION, error: %x", ret); + return ret; + } + + /* Init wifi host driver (whd) */ + cy_rslt_t whd_ret = whd_init(&data->whd_drv, &init_config_default, &resource_ops, buffer_if, + netif_funcs); + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_bus_sdio_attach(data->whd_drv, &whd_sdio_config, + (whd_sdio_t)&data->card); + + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_wifi_on(data->whd_drv, interface); + } + + if (whd_ret != CY_RSLT_SUCCESS) { + whd_deinit(*interface); + return -ENODEV; + } + } + return 0; +} + +/* + * Implement SDIO CMD52/53 wrappers + */ + +static struct sdio_func *airoc_wifi_get_sdio_func(struct sd_card *sd, whd_bus_function_t function) +{ + struct airoc_wifi_data *data = CONTAINER_OF(sd, struct airoc_wifi_data, card); + struct sdio_func *func[] = {&sd->func0, &data->sdio_func1, &data->sdio_func2}; + + if (function > WLAN_FUNCTION) { + return NULL; + } + + return func[function]; +} + +whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint8_t value, + sdio_response_needed_t response_expected, uint8_t *response) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); + + if (direction == BUS_WRITE) { + ret = sdio_rw_byte(func, address, value, response); + } else { + ret = sdio_read_byte(func, address, response); + } + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (ret != WHD_SUCCESS), + cmd52_fail); + + /* Possibly device might not respond to this cmd. So, don't check return value here */ + if ((ret != WHD_SUCCESS) && (address == SDIO_SLEEP_CSR)) { + return ret; + } + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, sdio_transfer_mode_t mode, + uint32_t address, uint16_t data_size, uint8_t *data, + sdio_response_needed_t response_expected, uint32_t *response) +{ + whd_result_t ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + if (direction == BUS_WRITE) { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); + ret = sdio_write_addr(func, address, data, data_size); + } else { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); + ret = sdio_read_addr(func, address, data, data_size); + } + + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_READ)), + cmd53_read_fail); + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_WRITE)), + cmd53_write_fail); + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +/* + * Implement SDIO Card interrupt + */ + +void whd_bus_sdio_irq_handler(const struct device *dev, int reason, const void *user_data) +{ + if (reason == SDHC_INT_SDIO) { + whd_driver_t whd_driver = (whd_driver_t)user_data; + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); + + /* call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); + } +} + +whd_result_t whd_bus_sdio_irq_register(whd_driver_t whd_driver) +{ + /* Nothing to do here, all handles by whd_bus_sdio_irq_enable function */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + + /* Enable/disable SDIO Card interrupts */ + if (enable) { + ret = sdhc_enable_interrupt(sd->sdhc, whd_bus_sdio_irq_handler, SDHC_INT_SDIO, + whd_driver); + } else { + ret = sdhc_disable_interrupt(sd->sdhc, SDHC_INT_SDIO); + } + return ret; +} + +/* + * Implement OOB functionality + */ + +void whd_bus_sdio_oob_irq_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + struct airoc_wifi_data *data = CONTAINER_OF(cb, struct airoc_wifi_data, host_oob_pin_cb); + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &data->whd_drv->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check OOB state is correct */ + int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; + + if (!(pins & BIT(host_oob_pin->pin)) || (gpio_pin_get_dt(host_oob_pin) != expected_event)) { + WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", expected_event)); + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, error_intrs); + return; + } + + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, oob_intrs); + + /* Call thread notify to wake up WHD thread */ + whd_thread_notify_irq(data->whd_drv); + +#endif /* DT_INST_NODE_HAS_PROP(0, wifi-host-wake-gpios) */ +} + +whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct airoc_wifi_data *data = dev->data; + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check if OOB pin is ready */ + if (!gpio_is_ready_dt(host_oob_pin)) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_is_ready_dt for host_oob_pin\n", __func__)); + return WHD_HAL_ERROR; + } + + /* Configure OOB pin as output */ + ret = gpio_pin_configure_dt(host_oob_pin, GPIO_INPUT); + if (ret != 0) { + WPRINT_WHD_ERROR(( + " %s: Failed at gpio_pin_configure_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } + + /* Initialize/add OOB pin callback */ + gpio_init_callback(&data->host_oob_pin_cb, whd_bus_sdio_oob_irq_handler, + BIT(host_oob_pin->pin)); + + ret = gpio_add_callback_dt(host_oob_pin, &data->host_oob_pin_cb); + if (ret != 0) { + WPRINT_WHD_ERROR( + ("%s: Failed at gpio_add_callback_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + + /* Disable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, GPIO_INT_DISABLE); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + uint32_t trig_conf = + (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_TRIG_LOW : GPIO_INT_TRIG_HIGH; + + /* Enable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, + GPIO_INT_ENABLE | GPIO_INT_EDGE | trig_conf); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +/* + * Implement WHD memory wrappers + */ + +void *whd_mem_malloc(size_t size) +{ + return k_malloc(size); +} + +void *whd_mem_calloc(size_t nitems, size_t size) +{ + return k_calloc(nitems, size); +} + +void whd_mem_free(void *ptr) +{ + k_free(ptr); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c new file mode 100644 index 00000000000..c0c780822d8 --- /dev/null +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -0,0 +1,772 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief AIROC Wi-Fi driver. + */ + +#define DT_DRV_COMPAT infineon_airoc_wifi + +#include +#include + +LOG_MODULE_REGISTER(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); + +#ifndef AIROC_WIFI_TX_PACKET_POOL_COUNT +#define AIROC_WIFI_TX_PACKET_POOL_COUNT (10) +#endif + +#ifndef AIROC_WIFI_RX_PACKET_POOL_COUNT +#define AIROC_WIFI_RX_PACKET_POOL_COUNT (10) +#endif + +#ifndef AIROC_WIFI_PACKET_POOL_SIZE +#define AIROC_WIFI_PACKET_POOL_SIZE (1600) +#endif + +#define AIROC_WIFI_PACKET_POOL_COUNT \ + (AIROC_WIFI_TX_PACKET_POOL_COUNT + AIROC_WIFI_RX_PACKET_POOL_COUNT) + +#define AIROC_WIFI_WAIT_SEMA_MS (30 * 1000) +#define AIROC_WIFI_SCAN_TIMEOUT_MS (12 * 1000) + +/* AIROC private functions */ +static whd_result_t airoc_wifi_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, + uint16_t size, uint32_t timeout_ms); +static void airoc_wifi_buffer_release(whd_buffer_t buffer, whd_buffer_dir_t direction); +static uint8_t *airoc_wifi_buffer_get_current_piece_data_pointer(whd_buffer_t buffer); +static uint16_t airoc_wifi_buffer_get_current_piece_size(whd_buffer_t buffer); +static whd_result_t airoc_wifi_buffer_set_size(whd_buffer_t buffer, unsigned short size); +static whd_result_t airoc_wifi_buffer_add_remove_at_front(whd_buffer_t *buffer, + int32_t add_remove_amount); +static void airoc_wifi_network_process_ethernet_data(whd_interface_t interface, + whd_buffer_t buffer); +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if); + +/* Allocate network pool */ +NET_BUF_POOL_FIXED_DEFINE(airoc_pool, AIROC_WIFI_PACKET_POOL_COUNT, + AIROC_WIFI_PACKET_POOL_SIZE, 0, NULL); + +/* AIROC globals */ +static uint16_t ap_event_handler_index = 0xFF; + +/* Use global iface pointer to support any Ethernet driver */ +/* necessary for wifi callback functions */ +static struct net_if *airoc_wifi_iface; + +static whd_interface_t airoc_if; +static whd_interface_t airoc_sta_if; +static whd_interface_t airoc_ap_if; + +static const whd_event_num_t sta_link_events[] = { + WLC_E_LINK, WLC_E_DEAUTH_IND, WLC_E_DISASSOC_IND, + WLC_E_PSK_SUP, WLC_E_CSA_COMPLETE_IND, WLC_E_NONE}; + +static const whd_event_num_t ap_link_events[] = {WLC_E_DISASSOC_IND, WLC_E_DEAUTH_IND, + WLC_E_ASSOC_IND, WLC_E_REASSOC_IND, + WLC_E_AUTHORIZED, WLC_E_NONE}; + +static uint16_t sta_event_handler_index = 0xFF; +static void airoc_event_task(void); +static struct airoc_wifi_data airoc_wifi_data = {0}; + +static struct airoc_wifi_config airoc_wifi_config = { + .sdhc_dev = DEVICE_DT_GET(DT_INST_PARENT(0)), + .wifi_reg_on_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_reg_on_gpios, {0}), + .wifi_host_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_host_wake_gpios, {0}), + .wifi_dev_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_dev_wake_gpios, {0}), +}; + +static whd_buffer_funcs_t airoc_wifi_buffer_if_default = { + .whd_host_buffer_get = airoc_wifi_host_buffer_get, + .whd_buffer_release = airoc_wifi_buffer_release, + .whd_buffer_get_current_piece_data_pointer = + airoc_wifi_buffer_get_current_piece_data_pointer, + .whd_buffer_get_current_piece_size = airoc_wifi_buffer_get_current_piece_size, + .whd_buffer_set_size = airoc_wifi_buffer_set_size, + .whd_buffer_add_remove_at_front = airoc_wifi_buffer_add_remove_at_front, +}; + +static whd_netif_funcs_t airoc_wifi_netif_if_default = { + .whd_network_process_ethernet_data = airoc_wifi_network_process_ethernet_data, +}; + +K_MSGQ_DEFINE(airoc_wifi_msgq, sizeof(whd_event_header_t), 10, 4); +K_THREAD_STACK_DEFINE(airoc_wifi_event_stack, CONFIG_AIROC_WIFI_EVENT_TASK_STACK_SIZE); +static struct k_thread airoc_wifi_event_thread; + +struct airoc_wifi_event_t { + uint8_t is_ap_event; + uint32_t event_type; +}; + +/* + * AIROC Wi-Fi helper functions + */ +whd_interface_t airoc_wifi_get_whd_interface(void) +{ + return airoc_if; +} + +static void airoc_wifi_scan_cb_search(whd_scan_result_t **result_ptr, void *user_data, + whd_scan_status_t status) +{ + if (status == WHD_SCAN_ABORTED) { + k_sem_give(&airoc_wifi_data.sema_scan); + return; + } + + if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY) { + k_sem_give(&airoc_wifi_data.sema_scan); + } else if ((status == WHD_SCAN_INCOMPLETE) && (user_data != NULL) && + ((**result_ptr).SSID.length > 0)) { + + if (strncmp(((whd_scan_result_t *)user_data)->SSID.value, (**result_ptr).SSID.value, + (**result_ptr).SSID.length) == 0) { + memcpy(user_data, *result_ptr, sizeof(whd_scan_result_t)); + } + } +} + +static int convert_whd_security_to_zephyr(whd_security_t security) +{ + int zephyr_security = WIFI_SECURITY_TYPE_UNKNOWN; + + switch (security) { + case WHD_SECURITY_OPEN: + zephyr_security = WIFI_SECURITY_TYPE_NONE; + break; + case WHD_SECURITY_WEP_PSK: + zephyr_security = WIFI_SECURITY_TYPE_WEP; + break; + + case WHD_SECURITY_WPA3_WPA2_PSK: + case WHD_SECURITY_WPA2_AES_PSK: + zephyr_security = WIFI_SECURITY_TYPE_PSK; + break; + + case WHD_SECURITY_WPA2_AES_PSK_SHA256: + zephyr_security = WIFI_SECURITY_TYPE_PSK_SHA256; + break; + + case WHD_SECURITY_WPA3_SAE: + zephyr_security = WIFI_SECURITY_TYPE_SAE; + break; + + case WHD_SECURITY_WPA_AES_PSK: + zephyr_security = WIFI_SECURITY_TYPE_WPA_PSK; + break; + + default: + if ((security & ENTERPRISE_ENABLED) != 0) { + zephyr_security = WIFI_SECURITY_TYPE_EAP; + } + break; + } + return zephyr_security; +} + +static void parse_scan_result(whd_scan_result_t *p_whd_result, struct wifi_scan_result *p_zy_result) +{ + if (p_whd_result->SSID.length != 0) { + p_zy_result->ssid_length = p_whd_result->SSID.length; + strncpy(p_zy_result->ssid, p_whd_result->SSID.value, p_whd_result->SSID.length); + p_zy_result->channel = p_whd_result->channel; + p_zy_result->security = convert_whd_security_to_zephyr(p_whd_result->security); + p_zy_result->rssi = (int8_t)p_whd_result->signal_strength; + p_zy_result->mac_length = 6; + memcpy(p_zy_result->mac, &p_whd_result->BSSID, 6); + } +} + +static void scan_callback(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) +{ + struct airoc_wifi_data *data = user_data; + whd_scan_result_t whd_scan_result; + struct wifi_scan_result zephyr_scan_result; + + if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY || status == WHD_SCAN_ABORTED) { + data->scan_rslt_cb(data->iface, 0, NULL); + data->scan_rslt_cb = NULL; + /* NOTE: It is complete of scan packet, do not need to clean result_ptr, + * WHD will release result_ptr buffer + */ + return; + } + + /* We recived scan data so process it */ + if ((result_ptr != NULL) && (*result_ptr != NULL)) { + memcpy(&whd_scan_result, *result_ptr, sizeof(whd_scan_result_t)); + parse_scan_result(&whd_scan_result, &zephyr_scan_result); + data->scan_rslt_cb(data->iface, 0, &zephyr_scan_result); + } + memset(*result_ptr, 0, sizeof(whd_scan_result_t)); +} + +/* + * Implement WHD network buffers functions + */ +static whd_result_t airoc_wifi_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, + uint16_t size, uint32_t timeout_ms) +{ + ARG_UNUSED(direction); + ARG_UNUSED(timeout_ms); + struct net_buf *buf; + + buf = net_buf_alloc_len(&airoc_pool, size, K_NO_WAIT); + if (buf == NULL) { + return WHD_BUFFER_ALLOC_FAIL; + } + *buffer = buf; + return WHD_SUCCESS; +} + +static void airoc_wifi_buffer_release(whd_buffer_t buffer, whd_buffer_dir_t direction) +{ + CY_UNUSED_PARAMETER(direction); + (void)net_buf_destroy((struct net_buf *)buffer); +} + +static uint8_t *airoc_wifi_buffer_get_current_piece_data_pointer(whd_buffer_t buffer) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + return (uint8_t *)buf->data; +} + +static uint16_t airoc_wifi_buffer_get_current_piece_size(whd_buffer_t buffer) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + return (uint16_t)buf->size; +} + +static whd_result_t airoc_wifi_buffer_set_size(whd_buffer_t buffer, unsigned short size) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + buf->size = size; + return CY_RSLT_SUCCESS; +} + +static whd_result_t airoc_wifi_buffer_add_remove_at_front(whd_buffer_t *buffer, + int32_t add_remove_amount) +{ + CY_ASSERT(buffer != NULL); + struct net_buf **buf = (struct net_buf **)buffer; + + if (add_remove_amount > 0) { + (*buf)->len = (*buf)->size; + (*buf)->data = net_buf_pull(*buf, add_remove_amount); + } else { + (*buf)->data = net_buf_push(*buf, -add_remove_amount); + (*buf)->len = (*buf)->size; + } + return WHD_SUCCESS; +} + +static int airoc_mgmt_send(const struct device *dev, struct net_pkt *pkt) +{ + struct airoc_wifi_data *data = dev->data; + cy_rslt_t ret; + size_t pkt_len = net_pkt_get_len(pkt); + struct net_buf *buf = NULL; + + /* Read the packet payload */ + if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) { + LOG_ERR("net_pkt_read failed"); + return -EIO; + } + + /* Allocate Network Buffer from pool with Packet Length + Data Header */ + buf = net_buf_alloc_len(&airoc_pool, pkt_len + sizeof(data_header_t), K_NO_WAIT); + if (buf == NULL) { + return -EIO; + } + + /* Reserve the buffer Headroom for WHD Data header */ + net_buf_reserve(buf, sizeof(data_header_t)); + + /* Copy the buffer to network Buffer pointer */ + (void)memcpy(buf->data, data->frame_buf, pkt_len); + + /* Call WHD API to send out the Packet */ + ret = whd_network_send_ethernet_data(airoc_if, (void *)buf); + if (ret != CY_RSLT_SUCCESS) { + LOG_ERR("whd_network_send_ethernet_data failed"); +#if defined(CONFIG_NET_STATISTICS_WIFI) + data->stats.errors.tx++; +#endif + return -EIO; + } + +#if defined(CONFIG_NET_STATISTICS_WIFI) + data->stats.bytes.sent += pkt_len; + data->stats.pkts.tx++; +#endif + + return 0; +} + +static void airoc_wifi_network_process_ethernet_data(whd_interface_t interface, whd_buffer_t buffer) +{ + struct net_pkt *pkt; + uint8_t *data = whd_buffer_get_current_piece_data_pointer(interface->whd_driver, buffer); + uint32_t len = whd_buffer_get_current_piece_size(interface->whd_driver, buffer); + bool net_pkt_unref_flag = false; + + if ((airoc_wifi_iface != NULL) && net_if_flag_is_set(airoc_wifi_iface, NET_IF_UP)) { + + pkt = net_pkt_rx_alloc_with_buffer(airoc_wifi_iface, len, AF_UNSPEC, 0, K_NO_WAIT); + + if (pkt != NULL) { + if (net_pkt_write(pkt, data, len) < 0) { + LOG_ERR("Failed to write pkt"); + net_pkt_unref_flag = true; + } + + if ((net_pkt_unref_flag) || (net_recv_data(airoc_wifi_iface, pkt) < 0)) { + LOG_ERR("Failed to push received data"); + net_pkt_unref_flag = true; + } + } else { + LOG_ERR("Failed to get net buffer"); + } + } + + /* Release a packet buffer */ + airoc_wifi_buffer_release(buffer, WHD_NETWORK_RX); + +#if defined(CONFIG_NET_STATISTICS_WIFI) + airoc_wifi_data.stats.bytes.received += len; + airoc_wifi_data.stats.pkts.rx++; +#endif + + if (net_pkt_unref_flag) { + net_pkt_unref(pkt); +#if defined(CONFIG_NET_STATISTICS_WIFI) + airoc_wifi_data.stats.errors.rx++; +#endif + } +} + +static void *link_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, + const uint8_t *event_data, void *handler_user_data) +{ + ARG_UNUSED(ifp); + ARG_UNUSED(event_data); + ARG_UNUSED(handler_user_data); + + k_msgq_put(&airoc_wifi_msgq, event_header, K_FOREVER); + return NULL; +} + +static void airoc_event_task(void) +{ + whd_event_header_t event_header; + + while (1) { + k_msgq_get(&airoc_wifi_msgq, &event_header, K_FOREVER); + + switch ((whd_event_num_t)event_header.event_type) { + case WLC_E_LINK: + break; + + case WLC_E_DEAUTH_IND: + case WLC_E_DISASSOC_IND: + net_if_dormant_on(airoc_wifi_iface); + break; + + default: + break; + } + } +} + +static void airoc_mgmt_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct airoc_wifi_data *data = dev->data; + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; + data->iface = iface; + airoc_wifi_iface = iface; + + /* Read WLAN MAC Address */ + if (whd_wifi_get_mac_address(airoc_sta_if, &airoc_sta_if->mac_addr) != WHD_SUCCESS) { + LOG_ERR("Failed to get mac address"); + } else { + (void)memcpy(&data->mac_addr, &airoc_sta_if->mac_addr, + sizeof(airoc_sta_if->mac_addr)); + } + + /* Assign link local address. */ + if (net_if_set_link_addr(iface, data->mac_addr, 6, NET_LINK_ETHERNET)) { + LOG_ERR("Failed to set link addr"); + } + + /* Initialize Ethernet L2 stack */ + ethernet_init(iface); + + /* Not currently connected to a network */ + net_if_dormant_on(iface); + + /* L1 network layer (physical layer) is up */ + net_if_carrier_on(data->iface); +} + +static int airoc_mgmt_scan(const struct device *dev, struct wifi_scan_params *params, + scan_result_cb_t cb) +{ + struct airoc_wifi_data *data = dev->data; + + if (data->scan_rslt_cb != NULL) { + LOG_INF("Scan callback in progress"); + return -EINPROGRESS; + } + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + data->scan_rslt_cb = cb; + + /* Connect to the network */ + if (whd_wifi_scan(airoc_sta_if, params->scan_type, WHD_BSS_TYPE_ANY, &(data->ssid), NULL, + NULL, NULL, scan_callback, &(data->scan_result), data) != WHD_SUCCESS) { + LOG_ERR("Failed to start scan"); + k_sem_give(&data->sema_common); + return -EAGAIN; + } + + k_sem_give(&data->sema_common); + return 0; +} + +static int airoc_mgmt_connect(const struct device *dev, struct wifi_connect_req_params *params) +{ + struct airoc_wifi_data *data = (struct airoc_wifi_data *)dev->data; + whd_ssid_t ssid = {0}; + int ret = 0; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (data->is_sta_connected) { + LOG_ERR("Already connected"); + ret = -EALREADY; + goto error; + } + + if (data->is_ap_up) { + LOG_ERR("Network interface is busy AP. Please first disable AP."); + ret = -EBUSY; + goto error; + } + + ssid.length = params->ssid_length; + memcpy(ssid.value, params->ssid, params->ssid_length); + + whd_scan_result_t scan_result; + whd_scan_result_t usr_result = {0}; + + usr_result.SSID.length = ssid.length; + memcpy(usr_result.SSID.value, ssid.value, ssid.length); + + if (whd_wifi_scan(airoc_sta_if, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY, NULL, NULL, NULL, + NULL, airoc_wifi_scan_cb_search, &scan_result, + &(usr_result)) != WHD_SUCCESS) { + LOG_ERR("Failed start scan"); + ret = -EAGAIN; + goto error; + } + + if (k_sem_take(&airoc_wifi_data.sema_scan, K_MSEC(AIROC_WIFI_SCAN_TIMEOUT_MS)) != 0) { + whd_wifi_stop_scan(airoc_sta_if); + ret = -EAGAIN; + goto error; + } + + if (usr_result.security == 0) { + ret = -EAGAIN; + LOG_ERR("Could not scan device"); + goto error; + } + + /* Connect to the network */ + if (whd_wifi_join(airoc_sta_if, &usr_result.SSID, usr_result.security, params->psk, + params->psk_length) != WHD_SUCCESS) { + LOG_ERR("Failed to connect with network"); + + ret = -EAGAIN; + goto error; + } + +error: + if (ret < 0) { + net_if_dormant_on(data->iface); + } else { + net_if_dormant_off(data->iface); + data->is_sta_connected = true; +#if defined(CONFIG_NET_DHCPV4) + net_dhcpv4_restart(data->iface); +#endif /* defined(CONFIG_NET_DHCPV4) */ + } + + wifi_mgmt_raise_connect_result_event(data->iface, ret); + k_sem_give(&data->sema_common); + return ret; +} + +static int airoc_mgmt_disconnect(const struct device *dev) +{ + int ret = 0; + struct airoc_wifi_data *data = (struct airoc_wifi_data *)dev->data; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (whd_wifi_leave(airoc_sta_if) != WHD_SUCCESS) { + k_sem_give(&data->sema_common); + ret = -EAGAIN; + } else { + data->is_sta_connected = false; + net_if_dormant_on(data->iface); + } + + wifi_mgmt_raise_disconnect_result_event(data->iface, ret); + k_sem_give(&data->sema_common); + + return ret; +} + +static void *airoc_wifi_ap_link_events_handler(whd_interface_t ifp, + const whd_event_header_t *event_header, + const uint8_t *event_data, void *handler_user_data) +{ + struct airoc_wifi_event_t airoc_event = { + .is_ap_event = 1, + .event_type = event_header->event_type + }; + + k_msgq_put(&airoc_wifi_msgq, &airoc_event, K_FOREVER); + + return NULL; +} + +static int airoc_mgmt_ap_enable(const struct device *dev, struct wifi_connect_req_params *params) +{ + struct airoc_wifi_data *data = dev->data; + whd_security_t security; + whd_ssid_t ssid; + uint8_t channel; + int ret = 0; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (data->is_sta_connected) { + LOG_ERR("Network interface is busy in STA mode. Please first disconnect STA."); + ret = -EBUSY; + goto error; + } + + if (data->is_ap_up) { + LOG_ERR("Already AP is on - first disable"); + ret = -EAGAIN; + goto error; + } + + if (!data->second_interface_init) { + if (whd_add_secondary_interface(data->whd_drv, NULL, &airoc_ap_if) != + CY_RSLT_SUCCESS) { + LOG_ERR("Error Unable to bring up the whd secondary interface"); + ret = -EAGAIN; + goto error; + } + data->second_interface_init = true; + } + + ssid.length = params->ssid_length; + memcpy(ssid.value, params->ssid, ssid.length); + + /* make sure to set valid channels for 2G and 5G: + * - 2G channels from 1 to 11, + * - 5G channels from 36 to 165 + */ + if (((params->channel > 0) && (params->channel < 12)) || + ((params->channel > 35) && (params->channel < 166))) { + channel = params->channel; + } else { + channel = 1; + LOG_WRN("Discard of setting unsupported channel: %u (will set 1)", + params->channel); + } + + if (params->psk_length == 0) { + security = WHD_SECURITY_OPEN; + } else { + security = WHD_SECURITY_WPA2_AES_PSK; + } + + if (whd_wifi_init_ap(airoc_ap_if, &ssid, security, (const uint8_t *)params->psk, + params->psk_length, channel) != 0) { + LOG_ERR("Failed to init whd ap interface"); + ret = -EAGAIN; + goto error; + } + + if (whd_wifi_start_ap(airoc_ap_if) != 0) { + LOG_ERR("Failed to start whd ap interface"); + ret = -EAGAIN; + goto error; + } + + /* set event handler */ + if (whd_management_set_event_handler(airoc_ap_if, ap_link_events, + airoc_wifi_ap_link_events_handler, NULL, + &ap_event_handler_index) != 0) { + whd_wifi_stop_ap(airoc_ap_if); + ret = -EAGAIN; + goto error; + } + + data->is_ap_up = true; + airoc_if = airoc_ap_if; +error: + + k_sem_give(&data->sema_common); + return ret; +} + +#if defined(CONFIG_NET_STATISTICS_WIFI) +static int airoc_mgmt_wifi_stats(const struct device *dev, struct net_stats_wifi *stats) +{ + struct airoc_wifi_data *data = dev->data; + + stats->bytes.received = data->stats.bytes.received; + stats->bytes.sent = data->stats.bytes.sent; + stats->pkts.rx = data->stats.pkts.rx; + stats->pkts.tx = data->stats.pkts.tx; + stats->errors.rx = data->stats.errors.rx; + stats->errors.tx = data->stats.errors.tx; + stats->broadcast.rx = data->stats.broadcast.rx; + stats->broadcast.tx = data->stats.broadcast.tx; + stats->multicast.rx = data->stats.multicast.rx; + stats->multicast.tx = data->stats.multicast.tx; + stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx; + stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss; + + return 0; +} +#endif + +static int airoc_mgmt_ap_disable(const struct device *dev) +{ + cy_rslt_t whd_ret; + struct airoc_wifi_data *data = dev->data; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (whd_wifi_deregister_event_handler(airoc_ap_if, ap_event_handler_index)) { + LOG_ERR("Can't whd_wifi_deregister_event_handler"); + } + + whd_ret = whd_wifi_stop_ap(airoc_ap_if); + if (whd_ret == CY_RSLT_SUCCESS) { + data->is_ap_up = false; + airoc_if = airoc_sta_if; + } else { + LOG_ERR("Can't stop wifi ap: %u", whd_ret); + } + + k_sem_give(&data->sema_common); + + if (whd_ret != CY_RSLT_SUCCESS) { + return -ENODEV; + } + + return 0; +} + +static int airoc_init(const struct device *dev) +{ + int ret; + cy_rslt_t whd_ret; + struct airoc_wifi_data *data = dev->data; + + k_tid_t tid = k_thread_create( + &airoc_wifi_event_thread, airoc_wifi_event_stack, + CONFIG_AIROC_WIFI_EVENT_TASK_STACK_SIZE, (k_thread_entry_t)airoc_event_task, NULL, + NULL, NULL, CONFIG_AIROC_WIFI_EVENT_TASK_PRIO, K_INHERIT_PERMS, K_NO_WAIT); + + if (!tid) { + LOG_ERR("ERROR spawning tx thread"); + return -EAGAIN; + } + k_thread_name_set(tid, "airoc_event"); + + whd_ret = airoc_wifi_init_primary(dev, &airoc_sta_if, &airoc_wifi_netif_if_default, + &airoc_wifi_buffer_if_default); + if (whd_ret != CY_RSLT_SUCCESS) { + LOG_ERR("airoc_wifi_init_primary failed ret = %d \r\n", whd_ret); + return -EAGAIN; + } + airoc_if = airoc_sta_if; + + whd_ret = whd_management_set_event_handler(airoc_sta_if, sta_link_events, + link_events_handler, NULL, &sta_event_handler_index); + if (whd_ret != CY_RSLT_SUCCESS) { + LOG_ERR("whd_management_set_event_handler failed ret = %d \r\n", whd_ret); + return -EAGAIN; + } + + ret = k_sem_init(&data->sema_common, 1, 1); + if (ret != 0) { + LOG_ERR("k_sem_init(sema_common) failure"); + return ret; + } + + ret = k_sem_init(&data->sema_scan, 0, 1); + if (ret != 0) { + LOG_ERR("k_sem_init(sema_scan) failure"); + return ret; + } + + return 0; +} + +static const struct wifi_mgmt_ops airoc_wifi_mgmt = { + .scan = airoc_mgmt_scan, + .connect = airoc_mgmt_connect, + .disconnect = airoc_mgmt_disconnect, + .ap_enable = airoc_mgmt_ap_enable, + .ap_disable = airoc_mgmt_ap_disable, +#if defined(CONFIG_NET_STATISTICS_ETHERNET) + .get_stats = airoc_mgmt_wifi_stats, +#endif +}; + +static const struct net_wifi_mgmt_offload airoc_api = { + .wifi_iface.iface_api.init = airoc_mgmt_init, + .wifi_iface.send = airoc_mgmt_send, + .wifi_mgmt_api = &airoc_wifi_mgmt, +}; + +NET_DEVICE_DT_INST_DEFINE(0, airoc_init, NULL, &airoc_wifi_data, &airoc_wifi_config, + CONFIG_WIFI_INIT_PRIORITY, &airoc_api, ETHERNET_L2, + NET_L2_GET_CTX_TYPE(ETHERNET_L2), WHD_LINK_MTU); diff --git a/drivers/wifi/infineon/airoc_wifi.h b/drivers/wifi/infineon/airoc_wifi.h new file mode 100644 index 00000000000..648423ab109 --- /dev/null +++ b/drivers/wifi/infineon/airoc_wifi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +struct airoc_wifi_data { + struct sd_card card; + struct sdio_func sdio_func1; + struct sdio_func sdio_func2; + struct net_if *iface; + bool second_interface_init; + bool is_ap_up; + bool is_sta_connected; + uint8_t mac_addr[6]; + scan_result_cb_t scan_rslt_cb; + whd_ssid_t ssid; + whd_scan_result_t scan_result; + struct k_sem sema_common; + struct k_sem sema_scan; +#if defined(CONFIG_NET_STATISTICS_WIFI) + struct net_stats_wifi stats; +#endif + whd_driver_t whd_drv; + struct gpio_callback host_oob_pin_cb; + uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE]; +}; + +struct airoc_wifi_config { + const struct device *sdhc_dev; + struct gpio_dt_spec wifi_reg_on_gpio; + struct gpio_dt_spec wifi_host_wake_gpio; + struct gpio_dt_spec wifi_dev_wake_gpio; +}; + +/** + * \brief This function returns pointer type to handle instance + * of whd interface (whd_interface_t) which allocated in + * Zephyr AIROC driver (drivers/wifi/infineon/airoc_wifi.c) + */ + +whd_interface_t airoc_wifi_get_whd_interface(void); diff --git a/drivers/wifi/infineon/cybsp.h b/drivers/wifi/infineon/cybsp.h new file mode 100644 index 00000000000..dfa23ffbae5 --- /dev/null +++ b/drivers/wifi/infineon/cybsp.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This is enpty/stub file used in WHD */ diff --git a/dts/bindings/wifi/infineon,airoc-wifi.yaml b/dts/bindings/wifi/infineon,airoc-wifi.yaml new file mode 100644 index 00000000000..9c93b238a4e --- /dev/null +++ b/dts/bindings/wifi/infineon,airoc-wifi.yaml @@ -0,0 +1,50 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + AIROC Wi-Fi Connectivity. + + Example of enabling AIROC Wi-Fi device (for SDIO): + &sdhc0 { + status = "okay"; + + /* SDIO pins */ + pinctrl-0 = <&p2_4_sdio_cmd &p2_5_sdio_clk &p2_0_sdio_data0 + &p2_1_sdio_data1 &p2_2_sdio_data2 &p2_3_sdio_data3>; + pinctrl-names = "default"; + + /* Wifi configuration */ + airoc-wifi { + status = "okay"; + compatible = "infineon,airoc-wifi-sdio"; + + /* Wi-Fi control gpios */ + wifi-reg-on-gpios = <&gpio_prt2 6 GPIO_ACTIVE_HIGH>; + wifi-host-wake-gpios = <&gpio_prt0 4 GPIO_ACTIVE_HIGH>; + }; + }; + +compatible: "infineon,airoc-wifi" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + wifi-reg-on-gpios: + description: | + Power-up/down gpio to control the internal regulators used + by the WiFi section of AIROC Wi-Fi device. + type: phandle-array + + wifi-host-wake-gpios: + description: | + Host wake-up gpio. Signal from the AIROC Wi-Fi device + to the host indicating that the device requires attention. + type: phandle-array + + wifi-dev-wake-gpios: + description: | + WiFi device wake-up gpio. Signal from the host to the + AIROC Wi-Fi device indicating that the host requires attention. + type: phandle-array diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index 1db3cf57a6a..27dbd71897f 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -36,6 +36,11 @@ if (CONFIG_SOC_FAMILY_INFINEON_CAT1A) add_subdirectory(abstraction-rtos) endif() +## Add Wi-Fi assets for AIROC devices +if (CONFIG_WIFI_AIROC) + add_subdirectory(wifi-host-driver) +endif() + ## Add BT assets for AIROC devices if (CONFIG_BT_AIROC) add_subdirectory(btstack-integration) diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index 83d24bfacd5..af92b98b3dc 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -72,7 +72,7 @@ config USE_INFINEON_WDT Enable WATCHDOG TIMER (WDT) HAL module driver for Infineon devices -config ABSTRACTION_RTOS_COMPONENT_ZEPHYR +config USE_INFINEON_ABSTRACTION_RTOS bool "Abstraction RTOS component (Zephyr support)" help Enable Abstraction RTOS component with Zephyr support diff --git a/modules/hal_infineon/abstraction-rtos/CMakeLists.txt b/modules/hal_infineon/abstraction-rtos/CMakeLists.txt index cd61908659f..6b2b0e6449f 100644 --- a/modules/hal_infineon/abstraction-rtos/CMakeLists.txt +++ b/modules/hal_infineon/abstraction-rtos/CMakeLists.txt @@ -5,7 +5,7 @@ zephyr_include_directories(${ZEPHYR_HAL_INFINEON_MODULE_DIR}/abstraction-rtos/include) # Enable Zephyr support -zephyr_include_directories_ifdef(CONFIG_ABSTRACTION_RTOS_COMPONENT_ZEPHYR +zephyr_include_directories_ifdef(CONFIG_USE_INFINEON_ABSTRACTION_RTOS include/COMPONENT_ZEPHYR) -zephyr_library_sources_ifdef(CONFIG_ABSTRACTION_RTOS_COMPONENT_ZEPHYR +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ABSTRACTION_RTOS source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c) diff --git a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt new file mode 100644 index 00000000000..afdb147676d --- /dev/null +++ b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt @@ -0,0 +1,216 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation. +# +# SPDX-License-Identifier: Apache-2.0 + +set(hal_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}) +set(hal_wifi_dir ${hal_dir}/wifi-host-driver) +set(hal_wifi_dir_resources ${hal_dir}/wifi-host-driver/WiFi_Host_Driver/resources) + +set(hal_blobs_dir ${hal_dir}/zephyr/blobs/img/whd/resources) +set(blob_gen_dir ${ZEPHYR_BINARY_DIR}/include/generated) + +set(cyw43xx_fw_bin_gen_inc ${blob_gen_dir}/cyw43xx_fw_blob.inc) +set(cyw43xx_clm_bin_gen_inc ${blob_gen_dir}/cyw43xx_clm_blob.inc) + +######################################################################################### +# Wi-Fi Host driver +######################################################################################### +if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + zephyr_compile_definitions(WLAN_MFG_FIRMWARE) +endif() + +# Add WHD includes +zephyr_include_directories(${hal_wifi_dir}) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/inc) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/src) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/src/include) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/resource_imp) + +# src +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_ap.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_buffer_api.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_cdc_bdc.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_chip.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_chip_constants.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_clm.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_debug.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_events.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_logging.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_management.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_network_if.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_resource_if.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_sdpcm.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_thread.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_utils.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi_api.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi_p2p.c) + +# src/bus_protocols +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_common.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_sdio_protocol.c) + +# resources/resource_imp +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/resources/resource_imp/whd_resources.c) + +# CYW43012 firmware +if(CONFIG_CYW43012 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/firmware/COMPONENT_43012) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43012/43012C0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43012/43012C0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43012/43012C0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43012/43012C0_bin.c) + endif() +endif() + +# CYW4343W firmware +if(CONFIG_CYW4343W AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4343W/4343WA1-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W/4343WA1-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4343W/4343WA1.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W/4343WA1_bin.c) + endif() +endif() + +# CYW43438 firmware/clm +if(CONFIG_CYW43438 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_43438) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_43438) + + # firmware/clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43438/43438A1-mfgtest.bin) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43438/43438A1-mfgtest.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43438/43438A1-mfgtest_bin.c) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43438/43438A1-mfgtest_clm_blob.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43438/43438A1.bin) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43438/43438A1.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43438/43438A1_bin.c) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43438/43438A1_clm_blob.c) + endif() + +endif() + +# CYW43439 firmware +if(CONFIG_CYW43439 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_43439) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43439/43439A0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43439/43439A0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43439/43439A0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43439/43439A0_bin.c) + endif() +endif() + +# CYW4373 firmware +if(CONFIG_CYW4373 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_4373) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4373/4373A0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4373/4373A0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4373/4373A0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4373/4373A0_bin.c) + endif() +endif() + + +# CYW43012_MURATA_1LV clm/nvram +if(CONFIG_CYW43012_MURATA_1LV AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/clm/COMPONENT_43012) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43012/43012C0-mfgtest.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43012/43012C0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43012/43012C0.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43012/43012C0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_43012/COMPONENT_MURATA-1LV) +endif() + +# CYW4343W_MURATA_1DX clm/nvram +if(CONFIG_CYW4343W_MURATA_1DX AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_4343W) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4343W/4343WA1-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4343W/4343WA1-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4343W/4343WA1.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4343W/4343WA1_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_4343W/COMPONENT_MURATA-1DX) +endif() + +# CYW43439_MURATA_1YN +if(CONFIG_CYW43439_MURATA_1YN AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_43439) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43439/43439A0-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43439/43439A0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43439/43439A0.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43439/43439A0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_43439/COMPONENT_MURATA-1YN) +endif() + +# CYW4373_STERLING_LWB5PLUS +if(CONFIG_CYW4373_STERLING_LWB5PLUS AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories_ifdef(${hal_wifi_dir_resources}/nvram/COMPONENT_4373/COMPONENT_STERLING-LWB5plus) +endif() + +# generate FW inc_blob from fw_bin +if(EXISTS ${cyw43xx_fw_bin}) + message(INFO " generate include of blob FW file: ${cyw43xx_fw_bin}") + generate_inc_file_for_target(app ${cyw43xx_fw_bin} ${cyw43xx_fw_bin_gen_inc}) +endif() + +# generate CLM inc_blob from clm_bin +if(EXISTS ${cyw43xx_clm_bin}) + message(INFO " generate include of blob CLM file: ${cyw43xx_clm_bin}") + generate_inc_file_for_target(app ${cyw43xx_clm_bin} ${cyw43xx_clm_bin_gen_inc}) +endif() diff --git a/samples/net/wifi/boards/cy8cproto_062_4343w.conf b/samples/net/wifi/boards/cy8cproto_062_4343w.conf new file mode 100644 index 00000000000..943db317fad --- /dev/null +++ b/samples/net/wifi/boards/cy8cproto_062_4343w.conf @@ -0,0 +1,3 @@ +CONFIG_NET_IF_MAX_IPV4_COUNT=2 +CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=20 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 8b42363b4ff..89abfbd79df 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -63,7 +63,9 @@ tests: - CONFIG_UART_MUX=y drivers.modem.esp_at.build: extra_args: CONF_FILE=modem_esp_at.conf - platform_exclude: ip_k66f + platform_exclude: + - ip_k66f + - cy8cproto_062_4343w filter: CONFIG_SERIAL min_ram: 36 drivers.modem.esp_at.async.build: diff --git a/west.yml b/west.yml index 9326bd85722..6b4391cb380 100644 --- a/west.yml +++ b/west.yml @@ -168,7 +168,7 @@ manifest: groups: - hal - name: hal_infineon - revision: 815e84a5150f95627201f192779a0180d5052de7 + revision: 69c883d3bd9fac8a18dd8384624b8c472a68d06f path: modules/hal/infineon groups: - hal From d8606727df5e3fc9754de87dc0dcfc786f87e1a5 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Wed, 4 Oct 2023 09:28:04 +0300 Subject: [PATCH 3246/4498] boards: arm: cy8cproto-062-4343w: enable WIFI feature Enable WIFI feature for cy8cproto-062-4343w board. Signed-off-by: Nazar Palamar --- .../arm/cy8cproto_062_4343w/Kconfig.defconfig | 19 ++++++++- .../cy8cproto_062_4343w-common.dtsi | 4 ++ .../cy8cproto_062_4343w-pinctrl.dtsi | 41 ++++++++++++++++++- .../cy8cproto_062_4343w.dts | 22 +++++++++- .../cy8cproto_062_4343w.yaml | 4 ++ .../cy8cproto_062_4343w_defconfig | 3 ++ 6 files changed, 89 insertions(+), 4 deletions(-) diff --git a/boards/arm/cy8cproto_062_4343w/Kconfig.defconfig b/boards/arm/cy8cproto_062_4343w/Kconfig.defconfig index 14c47a06e58..ba117ace665 100644 --- a/boards/arm/cy8cproto_062_4343w/Kconfig.defconfig +++ b/boards/arm/cy8cproto_062_4343w/Kconfig.defconfig @@ -10,8 +10,8 @@ config BOARD if WIFI || BT -# Select CYW43XXX part and module -choice CYW43XXX_PART +# Select AIROC part and module +choice AIROC_PART default CYW4343W endchoice @@ -21,6 +21,16 @@ endchoice endif # WIFI || BT +if WIFI + +config WIFI_AIROC + default y + +# Enable L2 Ethernet +config NET_L2_ETHERNET + default y + +endif # WIFI if BT @@ -38,4 +48,9 @@ endchoice endif # BT +# Heap Pool Size +config HEAP_MEM_POOL_SIZE + default 15000 if WIFI + default 4096 + endif # BOARD_CY8CPROTO_062_4343W diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-common.dtsi b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-common.dtsi index 3676cdbb471..75012f88ffc 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-common.dtsi +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-common.dtsi @@ -34,6 +34,10 @@ status = "okay"; }; +&gpio_prt2 { + status = "okay"; +}; + &gpio_prt3 { status = "okay"; }; diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi index d86f9b67bfa..14202d8fbcd 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Rtone. + * Copyright (c) 2023 Cypress Semiconductor Corporation. * SPDX-License-Identifier: Apache-2.0 */ @@ -28,3 +28,42 @@ &p5_0_scb5_uart_rx { input-enable; }; + +&pinctrl { + /* Configure pin control bias mode for SDIO */ + p2_5_sdio_clk: p2_5_sdio_clk { + pinmux = ; + drive-push-pull; + input-enable; + }; + + p2_4_sdio_cmd: p2_4_sdio_cmd { + pinmux = ; + drive-push-pull; + input-enable; + }; + + p2_0_sdio_data0: p2_0_sdio_data0 { + pinmux = ; + drive-push-pull; + input-enable; + }; + + p2_1_sdio_data1: p2_1_sdio_data1 { + pinmux = ; + drive-push-pull; + input-enable; + }; + + p2_2_sdio_data2: p2_2_sdio_data2 { + pinmux = ; + drive-push-pull; + input-enable; + }; + + p2_3_sdio_data3: p2_3_sdio_data3 { + pinmux = ; + drive-push-pull; + input-enable; + }; +}; diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 4d9149b198a..cc793184b14 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -17,6 +17,7 @@ uart-5 = &uart5; i2c-0 = &i2c3; watchdog0 = &watchdog0; + sdhc0 = &sdhc0; }; chosen { @@ -50,7 +51,7 @@ uart2: &scb2 { current-speed = <115200>; - /* HCI-UART pins*/ + /* HCI-UART pins */ pinctrl-0 = <&p3_1_scb2_uart_tx &p3_0_scb2_uart_rx &p3_2_scb2_uart_rts &p3_3_scb2_uart_cts>; pinctrl-names = "default"; @@ -68,6 +69,25 @@ uart2: &scb2 { }; }; +&sdhc0 { + status = "okay"; + + /* SDIO pins */ + pinctrl-0 = <&p2_4_sdio_cmd &p2_5_sdio_clk &p2_0_sdio_data0 + &p2_1_sdio_data1 &p2_2_sdio_data2 &p2_3_sdio_data3>; + pinctrl-names = "default"; + + /* Wi-Fi configuration */ + airoc-wifi { + status = "okay"; + compatible = "infineon,airoc-wifi"; + + /* Wi-Fi control gpios */ + wifi-reg-on-gpios = <&gpio_prt2 6 GPIO_ACTIVE_HIGH>; + wifi-host-wake-gpios = <&gpio_prt0 4 GPIO_ACTIVE_HIGH>; + }; +}; + /* System clock configuration */ &fll0 { status = "okay"; diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml index 36d08b2a4d0..b6d56577209 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml @@ -14,6 +14,10 @@ toolchain: - gnuarmemb supported: - adc + - bluetooth + - wifi + - airoc + - cyw4343w - counter - gpio - uart diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig index c36ce13e1a8..3dd8e0eac78 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig @@ -29,3 +29,6 @@ CONFIG_GPIO=y # Enable clock controller CONFIG_CLOCK_CONTROL=y + +# Main Stack Size +CONFIG_MAIN_STACK_SIZE=2048 From 950e25578a539d47a4619e92f0ded2080ab65b53 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Mon, 2 Oct 2023 17:06:54 +0200 Subject: [PATCH 3247/4498] drivers: mfd: npm6001: Add separate initialization priority Enables setting the initialization priority of the nPM6001 independently from other MFDs. Signed-off-by: Bernt Johan Damslora --- drivers/mfd/Kconfig.npm6001 | 10 ++++++++++ drivers/mfd/mfd_npm6001.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/Kconfig.npm6001 b/drivers/mfd/Kconfig.npm6001 index 10360aa2347..be549ff96c1 100644 --- a/drivers/mfd/Kconfig.npm6001 +++ b/drivers/mfd/Kconfig.npm6001 @@ -8,3 +8,13 @@ config MFD_NPM6001 select I2C help Enable the Nordic nPM6001 PMIC multi-function device driver + +if MFD_NPM6001 + +config MFD_NPM6001_INIT_PRIORITY + int "nPM6001 MFD initialization priority" + default MFD_INIT_PRIORITY + help + Multi-function device initialization priority for nPM6001. + +endif # MFD_NPM6001 diff --git a/drivers/mfd/mfd_npm6001.c b/drivers/mfd/mfd_npm6001.c index 4bed77c4958..1a077791816 100644 --- a/drivers/mfd/mfd_npm6001.c +++ b/drivers/mfd/mfd_npm6001.c @@ -87,6 +87,6 @@ static int mfd_npm6001_init(const struct device *dev) }; \ \ DEVICE_DT_INST_DEFINE(inst, mfd_npm6001_init, NULL, NULL, &config##inst, POST_KERNEL, \ - CONFIG_MFD_INIT_PRIORITY, NULL); + CONFIG_MFD_NPM6001_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(MFD_NPM6001_DEFINE) From 5fc7304878eb1ffeeb74de0b4821b4680927f988 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Mon, 2 Oct 2023 17:10:00 +0200 Subject: [PATCH 3248/4498] drivers: mfd: npm1300: Add separate initialization priority Enables setting the initialization priority of the nPM1300 independently from other MFDs. Signed-off-by: Bernt Johan Damslora --- drivers/mfd/Kconfig.npm1300 | 7 +++++++ drivers/mfd/Kconfig.npm6001 | 5 +---- drivers/mfd/mfd_npm1300.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/mfd/Kconfig.npm1300 b/drivers/mfd/Kconfig.npm1300 index cc3eb0ef303..506508bd902 100644 --- a/drivers/mfd/Kconfig.npm1300 +++ b/drivers/mfd/Kconfig.npm1300 @@ -8,3 +8,10 @@ config MFD_NPM1300 select I2C help Enable the Nordic nPM1300 PMIC multi-function device driver + +config MFD_NPM1300_INIT_PRIORITY + int "nPM1300 MFD initialization priority" + default MFD_INIT_PRIORITY + depends on MFD_NPM1300 + help + Multi-function device initialization priority for nPM1300. diff --git a/drivers/mfd/Kconfig.npm6001 b/drivers/mfd/Kconfig.npm6001 index be549ff96c1..b81c942f2d6 100644 --- a/drivers/mfd/Kconfig.npm6001 +++ b/drivers/mfd/Kconfig.npm6001 @@ -9,12 +9,9 @@ config MFD_NPM6001 help Enable the Nordic nPM6001 PMIC multi-function device driver -if MFD_NPM6001 - config MFD_NPM6001_INIT_PRIORITY int "nPM6001 MFD initialization priority" default MFD_INIT_PRIORITY + depends on MFD_NPM6001 help Multi-function device initialization priority for nPM6001. - -endif # MFD_NPM6001 diff --git a/drivers/mfd/mfd_npm1300.c b/drivers/mfd/mfd_npm1300.c index 678d3572a24..ef06b6da7f0 100644 --- a/drivers/mfd/mfd_npm1300.c +++ b/drivers/mfd/mfd_npm1300.c @@ -297,6 +297,6 @@ int mfd_npm1300_remove_callback(const struct device *dev, struct gpio_callback * }; \ \ DEVICE_DT_INST_DEFINE(inst, mfd_npm1300_init, NULL, &data_##inst, &config##inst, \ - POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); + POST_KERNEL, CONFIG_MFD_NPM1300_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(MFD_NPM1300_DEFINE) From 29a67338d12a298baeb85c68a53d255e1ddf2fa3 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Thu, 26 Oct 2023 13:24:13 +0200 Subject: [PATCH 3249/4498] bluetooth: id: fix uninitialized RPA for non-default identities This change fixes uninitialized RPA values for advertising sets of non-default Bluetooth identities. The regression has been introduced in the following commit: https://github.com/zephyrproject-rtos/zephyr/commit/8d6b206064c915316245616a718ae29eb157a717 The follow-up fix for the default Bluetooth identity has been introduced in a separate commit: https://github.com/zephyrproject-rtos/zephyr/commit/88c20b9cddf0bd5e5d6c163611b2563f9266be6f Non-default Bluetooth identities can be loaded from the Settings subsystem. In this case, RPAs of related advertising sets to these identities are left uninitialized as the bt_id_create() function context is not executed. As a result, the RPA is not created for advertising sets of non-default Bluetooth identities, and the advertising is started with the 00:00:00:00:00:00 address. Signed-off-by: Kamil Piszczek --- subsys/bluetooth/host/id.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/id.c b/subsys/bluetooth/host/id.c index 4bbc5e23192..cf07418dd02 100644 --- a/subsys/bluetooth/host/id.c +++ b/subsys/bluetooth/host/id.c @@ -2064,7 +2064,9 @@ int bt_id_init(void) int err; #if defined(CONFIG_BT_PRIVACY) - bt_addr_copy(&bt_dev.rpa[BT_ID_DEFAULT], BT_ADDR_NONE); + for (uint8_t id = 0U; id < ARRAY_SIZE(bt_dev.rpa); id++) { + bt_addr_copy(&bt_dev.rpa[id], BT_ADDR_NONE); + } k_work_init_delayable(&bt_dev.rpa_update, rpa_timeout); #endif From 069bd8376c125cd7229d36756d2c92464eefcb4f Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Fri, 27 Oct 2023 09:14:23 +0200 Subject: [PATCH 3250/4498] tests: bsim: bluetooth: host: privacy: peripheral: test after reboot Extended the scope of the BabbleSim test for the Bluetooth test under the host/privacy/peripheral category. The tests ensures correct RPA advertising after the system a reboot when the Bluetooth identities are preloaded from the Settings subsystem. Signed-off-by: Kamil Piszczek --- .../host/privacy/peripheral/prj.conf | 12 ++++++ .../host/privacy/peripheral/src/dut.c | 43 ++++++++++++++----- .../host/privacy/peripheral/src/tester.c | 6 +++ .../peripheral/test_scripts/run_test.sh | 23 +++++++++- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf index bd5bf844bd0..9113a44382b 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf @@ -8,4 +8,16 @@ CONFIG_BT_EXT_ADV=y CONFIG_BT_PRIVACY=y CONFIG_BT_RPA_TIMEOUT=10 CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=3 CONFIG_BT_ID_MAX=3 + +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y + +# Increased stack due to settings API usage +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c index 3000a3e0f9e..9d72b5368b2 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/dut.c @@ -13,9 +13,13 @@ #include #include #include +#include #include "common/bt_str.h" +#define ID_A_INDEX 1 +#define ID_B_INDEX 2 + #define ADV_SET_INDEX_ONE 0x00 #define ADV_SET_INDEX_TWO 0x01 #define ADV_SET_INDEX_THREE 0x02 @@ -66,8 +70,7 @@ static void create_adv(struct bt_le_ext_adv **adv, int id) void start_advertising(void) { int err; - int id_a; - int id_b; + size_t bt_id_count; /* Enable bluetooth */ err = bt_enable(NULL); @@ -75,24 +78,44 @@ void start_advertising(void) FAIL("Failed to enable bluetooth (err %d\n)", err); } - id_a = bt_id_create(NULL, NULL); - if (id_a < 0) { - FAIL("bt_id_create id_a failed (err %d)\n", id_a); + err = settings_load(); + if (err) { + FAIL("Failed to enable settings (err %d\n)", err); + } + + bt_id_get(NULL, &bt_id_count); + if (bt_id_count == 1) { + int id_a; + int id_b; + + printk("No extra identity found in settings, creating new ones...\n"); + + id_a = bt_id_create(NULL, NULL); + if (id_a != ID_A_INDEX) { + FAIL("bt_id_create id_a failed (err %d)\n", id_a); + } + + id_b = bt_id_create(NULL, NULL); + if (id_b != ID_B_INDEX) { + FAIL("bt_id_create id_b failed (err %d)\n", id_b); + } + } else { + printk("Extra identities loaded from settings\n"); } - id_b = bt_id_create(NULL, NULL); - if (id_b < 0) { - FAIL("bt_id_create id_b failed (err %d)\n", id_b); + bt_id_get(NULL, &bt_id_count); + if (bt_id_count != CONFIG_BT_ID_MAX) { + FAIL("bt_id_get returned incorrect number of identities %u\n", bt_id_count); } for (int i = 0; i < CONFIG_BT_EXT_ADV_MAX_ADV_SET; i++) { if (i != ADV_SET_INDEX_THREE) { /* Create advertising set 1 and 2 with same id */ - create_adv(&adv_set[i], id_a); + create_adv(&adv_set[i], ID_A_INDEX); } else { /* Create advertising set 3 with different id */ - create_adv(&adv_set[i], id_b); + create_adv(&adv_set[i], ID_B_INDEX); } /* Set extended advertising data */ diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c index b553ee74b25..da94207387c 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c @@ -9,6 +9,7 @@ #include #include #include +#include #define EXPECTED_NUM_ROTATIONS 5 @@ -128,6 +129,11 @@ void tester_procedure(void) FAIL("Failed to enable bluetooth (err %d\n)", err); } + err = settings_load(); + if (err) { + FAIL("Failed to enable settings (err %d\n)", err); + } + start_scanning(); /* The rest of the test is driven by the callback */ diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh index ccbe6e844f2..37929a4efb2 100755 --- a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test.sh @@ -15,10 +15,29 @@ EXECUTE_TIMEOUT=30 cd ${BSIM_OUT_PATH}/bin Execute "$central_exe" \ - -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" + Execute "$peripheral_exe" \ - -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" + + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs + +Execute "$central_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_rm + + +Execute "$peripheral_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_rm + Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ -D=2 -sim_length=70e6 $@ From b182c92af5ae76b09a090e87010e4501c01ce2ad Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Mon, 30 Oct 2023 09:14:28 +0100 Subject: [PATCH 3251/4498] tests: bsim: bluetooth: host: privacy: peripheral: add RPA check Modified the BabbleSim test for the Bluetooth test under the host/privacy/peripheral category. Added the RPA check in the scan callback context of the scanning tester device to validate if the DUT advertising address is correct. Signed-off-by: Kamil Piszczek --- tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c index da94207387c..deaa001ddbe 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c @@ -60,6 +60,10 @@ static void test_address(bt_addr_le_t *addr) { int64_t diff_ms, rpa_timeout_ms; + if (!BT_ADDR_IS_RPA(&addr->a)) { + FAIL("Bluetooth address is not RPA\n"); + } + /* Only save the address + time if this is the first scan */ if (bt_addr_le_eq(&adv_set_data[adv_index].old_addr, BT_ADDR_LE_ANY)) { bt_addr_le_copy(&adv_set_data[adv_index].old_addr, addr); From 98b46340f23fcb6e0a5aa43d3ab3f2486454a7b8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 11 Oct 2023 16:34:30 +0200 Subject: [PATCH 3252/4498] net: pkt: Add flag indicating checksum status Add new net_pkt checksum, which indicate checksum status on the packet (i. e. whether it has already been calculated or not). Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 14 ++++++++++++++ subsys/net/ip/net_pkt.c | 1 + 2 files changed, 15 insertions(+) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 4931f95009d..98646b25b26 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -194,6 +194,9 @@ struct net_pkt { uint8_t l2_processed : 1; /* Set to 1 if this packet has already been * processed by the L2 */ + uint8_t chksum_done : 1; /* Checksum has already been computed for + * the packet. + */ /* bitfield byte alignment boundary */ @@ -398,6 +401,17 @@ static inline void net_pkt_set_l2_processed(struct net_pkt *pkt, pkt->l2_processed = is_l2_processed; } +static inline bool net_pkt_is_chksum_done(struct net_pkt *pkt) +{ + return !!(pkt->chksum_done); +} + +static inline void net_pkt_set_chksum_done(struct net_pkt *pkt, + bool is_chksum_done) +{ + pkt->chksum_done = is_chksum_done; +} + static inline uint8_t net_pkt_ip_hdr_len(struct net_pkt *pkt) { #if defined(CONFIG_NET_IP) diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index 944ea8499f1..cef7cbcd107 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1812,6 +1812,7 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt) net_pkt_set_eof(clone_pkt, net_pkt_eof(pkt)); net_pkt_set_ptp(clone_pkt, net_pkt_is_ptp(pkt)); net_pkt_set_forwarding(clone_pkt, net_pkt_forwarding(pkt)); + net_pkt_set_chksum_done(clone_pkt, net_pkt_is_chksum_done(pkt)); net_pkt_set_l2_bridged(clone_pkt, net_pkt_is_l2_bridged(pkt)); net_pkt_set_l2_processed(clone_pkt, net_pkt_is_l2_processed(pkt)); From eadd9336077c88aa0051fe89430c8b23e824d120 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 11 Oct 2023 16:45:36 +0200 Subject: [PATCH 3253/4498] net: Set a flag when checksum has been computed Set checksum flag on the net_pkt, when checksum is calculated in software. Signed-off-by: Robert Lubos --- subsys/net/ip/icmpv4.c | 1 + subsys/net/ip/icmpv6.c | 1 + subsys/net/ip/tcp.c | 1 + subsys/net/ip/udp.c | 1 + 4 files changed, 4 insertions(+) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 7133ca16ee7..205ca562754 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -67,6 +67,7 @@ int net_icmpv4_finalize(struct net_pkt *pkt) icmp_hdr->chksum = 0U; if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { icmp_hdr->chksum = net_calc_chksum_icmpv4(pkt); + net_pkt_set_chksum_done(pkt, true); } return net_pkt_set_data(pkt, &icmpv4_access); diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index ccd4c7f99ce..6b436139d1a 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -71,6 +71,7 @@ int net_icmpv6_finalize(struct net_pkt *pkt) icmp_hdr->chksum = 0U; if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { icmp_hdr->chksum = net_calc_chksum_icmpv6(pkt); + net_pkt_set_chksum_done(pkt, true); } return net_pkt_set_data(pkt, &icmp_access); diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 4965c34061a..253004c4e1f 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -3597,6 +3597,7 @@ int net_tcp_finalize(struct net_pkt *pkt) if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { tcp_hdr->chksum = net_calc_chksum_tcp(pkt); + net_pkt_set_chksum_done(pkt, true); } return net_pkt_set_data(pkt, &tcp_access); diff --git a/subsys/net/ip/udp.c b/subsys/net/ip/udp.c index 972eadb5a02..858c046b907 100644 --- a/subsys/net/ip/udp.c +++ b/subsys/net/ip/udp.c @@ -53,6 +53,7 @@ int net_udp_finalize(struct net_pkt *pkt) if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { udp_hdr->chksum = net_calc_chksum_udp(pkt); + net_pkt_set_chksum_done(pkt, true); } return net_pkt_set_data(pkt, &udp_access); From 08879ea7fbb9d17ec3d057d6fd3e0a6950edd0cf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 12 Oct 2023 15:49:00 +0200 Subject: [PATCH 3254/4498] net: ip: Add option to force checksum calculation Modify internal L4 protocols APIs, to allow to enforce checksum calculation, regardless of the checksum HW offloading capability. Signed-off-by: Robert Lubos --- subsys/net/ip/icmpv4.c | 4 ++-- subsys/net/ip/icmpv4.h | 2 +- subsys/net/ip/icmpv6.c | 4 ++-- subsys/net/ip/icmpv6.h | 2 +- subsys/net/ip/ipv4.c | 6 +++--- subsys/net/ip/ipv6.c | 6 +++--- subsys/net/ip/tcp.c | 4 ++-- subsys/net/ip/tcp.h | 2 +- subsys/net/ip/tcp_internal.h | 5 +++-- subsys/net/ip/udp.c | 4 ++-- subsys/net/ip/udp_internal.h | 5 +++-- tests/net/ipv4_fragment/src/main.c | 6 +++--- tests/net/ipv6_fragment/src/main.c | 4 ++-- 13 files changed, 28 insertions(+), 26 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 205ca562754..8bab97d9cfc 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -47,7 +47,7 @@ int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code) return net_pkt_set_data(pkt, &icmpv4_access); } -int net_icmpv4_finalize(struct net_pkt *pkt) +int net_icmpv4_finalize(struct net_pkt *pkt, bool force_chksum) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access, struct net_icmp_hdr); @@ -65,7 +65,7 @@ int net_icmpv4_finalize(struct net_pkt *pkt) } icmp_hdr->chksum = 0U; - if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) { icmp_hdr->chksum = net_calc_chksum_icmpv4(pkt); net_pkt_set_chksum_done(pkt, true); } diff --git a/subsys/net/ip/icmpv4.h b/subsys/net/ip/icmpv4.h index b9680c44b34..ae848c9d964 100644 --- a/subsys/net/ip/icmpv4.h +++ b/subsys/net/ip/icmpv4.h @@ -48,7 +48,7 @@ enum net_verdict net_icmpv4_input(struct net_pkt *pkt, struct net_ipv4_hdr *ip_hdr); int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code); -int net_icmpv4_finalize(struct net_pkt *pkt); +int net_icmpv4_finalize(struct net_pkt *pkt, bool force_chksum); void net_icmpv4_init(void); #else diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index 6b436139d1a..c04e3dddf72 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -57,7 +57,7 @@ const char *net_icmpv6_type2str(int icmpv6_type) return "?"; } -int net_icmpv6_finalize(struct net_pkt *pkt) +int net_icmpv6_finalize(struct net_pkt *pkt, bool force_chksum) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmp_hdr); @@ -69,7 +69,7 @@ int net_icmpv6_finalize(struct net_pkt *pkt) } icmp_hdr->chksum = 0U; - if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) { icmp_hdr->chksum = net_calc_chksum_icmpv6(pkt); net_pkt_set_chksum_done(pkt, true); } diff --git a/subsys/net/ip/icmpv6.h b/subsys/net/ip/icmpv6.h index 967111955f3..64ee1dfaa7b 100644 --- a/subsys/net/ip/icmpv6.h +++ b/subsys/net/ip/icmpv6.h @@ -188,7 +188,7 @@ enum net_verdict net_icmpv6_input(struct net_pkt *pkt, struct net_ipv6_hdr *ip_hdr); int net_icmpv6_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code); -int net_icmpv6_finalize(struct net_pkt *pkt); +int net_icmpv6_finalize(struct net_pkt *pkt, bool force_chksum); void net_icmpv6_init(void); #else diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 922068274f7..ce5c1e9986c 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -118,12 +118,12 @@ int net_ipv4_finalize(struct net_pkt *pkt, uint8_t next_header_proto) if (IS_ENABLED(CONFIG_NET_UDP) && next_header_proto == IPPROTO_UDP) { - return net_udp_finalize(pkt); + return net_udp_finalize(pkt, false); } else if (IS_ENABLED(CONFIG_NET_TCP) && next_header_proto == IPPROTO_TCP) { - return net_tcp_finalize(pkt); + return net_tcp_finalize(pkt, false); } else if (next_header_proto == IPPROTO_ICMP) { - return net_icmpv4_finalize(pkt); + return net_icmpv4_finalize(pkt, false); } return 0; diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 7ef75831406..4957f1cb557 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -120,12 +120,12 @@ int net_ipv6_finalize(struct net_pkt *pkt, uint8_t next_header_proto) if (IS_ENABLED(CONFIG_NET_UDP) && next_header_proto == IPPROTO_UDP) { - return net_udp_finalize(pkt); + return net_udp_finalize(pkt, false); } else if (IS_ENABLED(CONFIG_NET_TCP) && next_header_proto == IPPROTO_TCP) { - return net_tcp_finalize(pkt); + return net_tcp_finalize(pkt, false); } else if (next_header_proto == IPPROTO_ICMPV6) { - return net_icmpv6_finalize(pkt); + return net_icmpv6_finalize(pkt, false); } return 0; diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 253004c4e1f..6ec7745c952 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -3583,7 +3583,7 @@ int net_tcp_recv(struct net_context *context, net_context_recv_cb_t cb, return 0; } -int net_tcp_finalize(struct net_pkt *pkt) +int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum) { NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct net_tcp_hdr); struct net_tcp_hdr *tcp_hdr; @@ -3595,7 +3595,7 @@ int net_tcp_finalize(struct net_pkt *pkt) tcp_hdr->chksum = 0U; - if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) { tcp_hdr->chksum = net_calc_chksum_tcp(pkt); net_pkt_set_chksum_done(pkt, true); } diff --git a/subsys/net/ip/tcp.h b/subsys/net/ip/tcp.h index f6f481d5443..77d5c5634a6 100644 --- a/subsys/net/ip/tcp.h +++ b/subsys/net/ip/tcp.h @@ -113,7 +113,7 @@ void net_tcp_init(void); #endif int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta); int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt); -int net_tcp_finalize(struct net_pkt *pkt); +int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum); #if defined(CONFIG_NET_TEST_PROTOCOL) /** diff --git a/subsys/net/ip/tcp_internal.h b/subsys/net/ip/tcp_internal.h index 42752060092..49edae13f68 100644 --- a/subsys/net/ip/tcp_internal.h +++ b/subsys/net/ip/tcp_internal.h @@ -249,11 +249,12 @@ static inline int net_tcp_recv(struct net_context *context, * @return 0 on success, negative errno otherwise. */ #if defined(CONFIG_NET_NATIVE_TCP) -int net_tcp_finalize(struct net_pkt *pkt); +int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum); #else -static inline int net_tcp_finalize(struct net_pkt *pkt) +static inline int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum) { ARG_UNUSED(pkt); + ARG_UNUSED(force_chksum); return 0; } #endif diff --git a/subsys/net/ip/udp.c b/subsys/net/ip/udp.c index 858c046b907..5ecc595053b 100644 --- a/subsys/net/ip/udp.c +++ b/subsys/net/ip/udp.c @@ -35,7 +35,7 @@ int net_udp_create(struct net_pkt *pkt, uint16_t src_port, uint16_t dst_port) return net_pkt_set_data(pkt, &udp_access); } -int net_udp_finalize(struct net_pkt *pkt) +int net_udp_finalize(struct net_pkt *pkt, bool force_chksum) { NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr); struct net_udp_hdr *udp_hdr; @@ -51,7 +51,7 @@ int net_udp_finalize(struct net_pkt *pkt) udp_hdr->len = htons(length); - if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) { udp_hdr->chksum = net_calc_chksum_udp(pkt); net_pkt_set_chksum_done(pkt, true); } diff --git a/subsys/net/ip/udp_internal.h b/subsys/net/ip/udp_internal.h index 94106d60010..00009177d0b 100644 --- a/subsys/net/ip/udp_internal.h +++ b/subsys/net/ip/udp_internal.h @@ -63,11 +63,12 @@ static inline int net_udp_create(struct net_pkt *pkt, * @return 0 on success, negative errno otherwise. */ #if defined(CONFIG_NET_NATIVE_UDP) -int net_udp_finalize(struct net_pkt *pkt); +int net_udp_finalize(struct net_pkt *pkt, bool force_chksum); #else -static inline int net_udp_finalize(struct net_pkt *pkt) +static inline int net_udp_finalize(struct net_pkt *pkt, bool force_chksum) { ARG_UNUSED(pkt); + ARG_UNUSED(force_chksum); return 0; } diff --git a/tests/net/ipv4_fragment/src/main.c b/tests/net/ipv4_fragment/src/main.c index 4db5b877d4f..7375aab17aa 100644 --- a/tests/net/ipv4_fragment/src/main.c +++ b/tests/net/ipv4_fragment/src/main.c @@ -636,7 +636,7 @@ ZTEST(net_ipv4_fragment, test_udp) net_pkt_cursor_init(pkt); net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt)); - net_udp_finalize(pkt); + net_udp_finalize(pkt, false); pkt_recv_expected_size = net_pkt_get_len(pkt); @@ -706,7 +706,7 @@ ZTEST(net_ipv4_fragment, test_tcp) net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt)); - net_tcp_finalize(pkt); + net_tcp_finalize(pkt, false); pkt_recv_expected_size = net_pkt_get_len(pkt); @@ -849,7 +849,7 @@ ZTEST(net_ipv4_fragment, test_do_not_fragment) net_pkt_cursor_init(pkt); net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt)); - net_udp_finalize(pkt); + net_udp_finalize(pkt, false); pkt_recv_expected_size = net_pkt_get_len(pkt); diff --git a/tests/net/ipv6_fragment/src/main.c b/tests/net/ipv6_fragment/src/main.c index 890ddc32b57..adb8652bdc1 100644 --- a/tests/net/ipv6_fragment/src/main.c +++ b/tests/net/ipv6_fragment/src/main.c @@ -2015,7 +2015,7 @@ ZTEST(net_ipv6_fragment, test_send_ipv6_fragment) net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt)); - net_udp_finalize(pkt); + net_udp_finalize(pkt, false); test_failed = false; test_complete = false; @@ -2175,7 +2175,7 @@ ZTEST(net_ipv6_fragment, test_send_ipv6_fragment_udp_loopback) net_pkt_set_overwrite(pkt, true); net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt)); - net_udp_finalize(pkt); + net_udp_finalize(pkt, false); test_failed = false; test_complete = false; From 887a3a321d812249b200dd99f26d0845ae67e899 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 12 Oct 2023 18:18:11 +0200 Subject: [PATCH 3255/4498] net: ipv4: Calculate checksum before fragmentation In case the stack has to fragment the IPv4 packet, calculate the checksum before fragmentation (if haven't done so). Signed-off-by: Robert Lubos --- subsys/net/ip/ipv4_fragment.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index d61dd246075..53cd72a8748 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -480,9 +480,9 @@ static int send_ipv4_fragment(struct net_pkt *pkt, uint16_t rand_id, uint16_t fi ipv4_hdr->len = htons((fit_len + net_pkt_ip_hdr_len(pkt))); ipv4_hdr->chksum = 0; - if (net_if_need_calc_tx_checksum(net_pkt_iface(frag_pkt))) { - ipv4_hdr->chksum = net_calc_chksum_ipv4(frag_pkt); - } + ipv4_hdr->chksum = net_calc_chksum_ipv4(frag_pkt); + + net_pkt_set_chksum_done(frag_pkt, true); net_pkt_set_data(frag_pkt, &ipv4_access); @@ -554,6 +554,35 @@ int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, pkt_len -= net_pkt_ip_hdr_len(pkt); + /* Calculate the L4 checksum (if not done already) before the fragmentation. */ + if (!net_pkt_is_chksum_done(pkt)) { + struct net_pkt_cursor backup; + + net_pkt_cursor_backup(pkt, &backup); + net_pkt_acknowledge_data(pkt, &frag_access); + + switch (frag_hdr->proto) { + case IPPROTO_ICMP: + ret = net_icmpv4_finalize(pkt, true); + break; + case IPPROTO_TCP: + ret = net_tcp_finalize(pkt, true); + break; + case IPPROTO_UDP: + ret = net_udp_finalize(pkt, true); + break; + default: + ret = 0; + break; + } + + if (ret < 0) { + return ret; + } + + net_pkt_cursor_restore(pkt, &backup); + } + while (frag_offset < pkt_len) { bool final = false; From 13a22e68142a3da882df4d6d3332e129bd444a30 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 20 Oct 2023 11:52:00 +0200 Subject: [PATCH 3256/4498] net: ipv6: Calculate checksum before fragmentation In case the stack has to fragment the IPv6 packet, calculate the checksum before fragmentation (if haven't done so). Signed-off-by: Robert Lubos --- subsys/net/ip/ipv6_fragment.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 3aa2a49fb65..5ff789aaac9 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -635,6 +635,8 @@ static int send_ipv6_fragment(struct net_pkt *pkt, frag_hdr->id = net_pkt_ipv6_fragment_id(pkt); frag_hdr->offset = htons(((frag_offset / 8U) << 3) | !final); + net_pkt_set_chksum_done(frag_pkt, true); + if (net_pkt_set_data(frag_pkt, &frag_access)) { goto fail; } @@ -720,6 +722,31 @@ int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, frag_offset = 0U; + /* Calculate the L4 checksum (if not done already) before the fragmentation. */ + if (!net_pkt_is_chksum_done(pkt)) { + net_pkt_cursor_init(pkt); + net_pkt_skip(pkt, last_hdr_off); + + switch (next_hdr) { + case IPPROTO_ICMPV6: + ret = net_icmpv6_finalize(pkt, true); + break; + case IPPROTO_TCP: + ret = net_tcp_finalize(pkt, true); + break; + case IPPROTO_UDP: + ret = net_udp_finalize(pkt, true); + break; + default: + ret = 0; + break; + } + + if (ret < 0) { + return ret; + } + } + length = net_pkt_get_len(pkt) - (net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt)); while (length) { From 0c1c939d9e322057203b8a4910d3cf5258cdbb4f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 20 Oct 2023 16:43:35 +0200 Subject: [PATCH 3257/4498] net: ipv6: Remove invalid/unneeded code from fragmentation logic Skipping both next_hdr_off and last_hdr_off and filling last_hdr variable doesn't make much sense, as this effectively moves the packet cursor inside/behind the last (L4) header with no particular meaning. Plus the last_hdr variable isn't really used anywhere, which kind of proves the point. Therefore, remove the unused variable and needless net_pkt operations. Signed-off-by: Robert Lubos --- subsys/net/ip/ipv6_fragment.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 5ff789aaac9..e10af12dad9 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -687,7 +687,6 @@ int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, uint16_t frag_offset; size_t length; uint8_t next_hdr; - uint8_t last_hdr; int fit_len; int ret; @@ -701,9 +700,7 @@ int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, net_pkt_cursor_init(pkt); if (net_pkt_skip(pkt, next_hdr_off) || - net_pkt_read_u8(pkt, &next_hdr) || - net_pkt_skip(pkt, last_hdr_off) || - net_pkt_read_u8(pkt, &last_hdr)) { + net_pkt_read_u8(pkt, &next_hdr)) { return -ENOBUFS; } From 64e615263afa0845d762fd8ebf04a28df8868d95 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Sun, 29 Oct 2023 16:07:16 +0100 Subject: [PATCH 3258/4498] net: ipv6: Set IP header length on the fragmented packet IPv6 fragmentation code did not set the IP header field on the fragment net_pkt. Signed-off-by: Robert Lubos --- subsys/net/ip/ipv6_fragment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index e10af12dad9..7ea9765be4c 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -641,6 +641,7 @@ static int send_ipv6_fragment(struct net_pkt *pkt, goto fail; } + net_pkt_set_ip_hdr_len(frag_pkt, net_pkt_ip_hdr_len(pkt)); net_pkt_set_ipv6_ext_len(frag_pkt, net_pkt_ipv6_ext_len(pkt) + sizeof(struct net_ipv6_frag_hdr)); From 2836d0701d647d380d1f798bf58483cae894d5b1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 20 Oct 2023 14:43:20 +0200 Subject: [PATCH 3259/4498] net: ip: Set net_context on the final fragment IPv4/6 fragmentation did not set the net_context pointer on the fragment packet and in result the send callback registered on net_context was not called. Therefore, copy the net_context pointer from the original packet to the final fragment to ensure that the registered callback is called. Signed-off-by: Robert Lubos --- subsys/net/ip/ipv4_fragment.c | 4 ++++ subsys/net/ip/ipv6_fragment.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index 53cd72a8748..5bcf4e0026c 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -489,6 +489,10 @@ static int send_ipv4_fragment(struct net_pkt *pkt, uint16_t rand_id, uint16_t fi net_pkt_set_overwrite(frag_pkt, false); net_pkt_cursor_restore(frag_pkt, &cur); + if (final) { + net_pkt_set_context(frag_pkt, net_pkt_context(pkt)); + } + /* If everything has been ok so far, we can send the packet. */ ret = net_send_data(frag_pkt); if (ret < 0) { diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 7ea9765be4c..6d391b3b823 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -660,6 +660,10 @@ static int send_ipv6_fragment(struct net_pkt *pkt, goto fail; } + if (final) { + net_pkt_set_context(frag_pkt, net_pkt_context(pkt)); + } + /* If everything has been ok so far, we can send the packet. */ ret = net_send_data(frag_pkt); if (ret < 0) { From 76a256ea576a41544c9b64665ad2a5a80ddbf2db Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 30 Oct 2023 13:17:51 +0100 Subject: [PATCH 3260/4498] net: pkt: Add function to check if packet was reassembled at IP level Move the existing code verifying that the net_pkt was reassembled at IP level to a helper function, as it will be needed in other places as well. Additionally, add packet family check before accessing union fields. Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 14 ++++++++++++++ subsys/net/ip/net_core.c | 3 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 98646b25b26..591002a9d66 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -836,6 +836,20 @@ static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ +static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt) +{ + if ((IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) && + net_pkt_family(pkt) == AF_INET && + net_pkt_ipv4_fragment_more(pkt)) || + (IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT) && + net_pkt_family(pkt) == AF_INET6 && + net_pkt_ipv6_fragment_start(pkt))) { + return true; + } + + return false; +} + static inline uint8_t net_pkt_priority(struct net_pkt *pkt) { return pkt->priority; diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 3d37743a39d..baa8cd695c5 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -76,8 +76,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt, /* If the packet is routed back to us when we have reassembled an IPv4 or IPv6 packet, * then do not pass it to L2 as the packet does not have link layer headers in it. */ - if ((IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) && net_pkt_ipv4_fragment_more(pkt)) || - (IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT) && net_pkt_ipv6_fragment_start(pkt))) { + if (net_pkt_is_ip_reassembled(pkt)) { locally_routed = true; } From 24abc4307bafc43edd3f7c7cdf80a934eaa06c5e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 30 Oct 2023 13:23:02 +0100 Subject: [PATCH 3261/4498] net: Verify L4 checksum unconditionally for reassembled packets In case of reassembled IP packets, we cannot rely on checksum offloading as the drivers/HW has no means to verify L4 checksum before the fragment is reassembled. Therefore, for such packets, verify L4 checksum in the software unconditionally. Signed-off-by: Robert Lubos --- subsys/net/ip/icmpv4.c | 3 ++- subsys/net/ip/icmpv6.c | 3 ++- subsys/net/ip/tcp.c | 3 ++- subsys/net/ip/udp.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 8bab97d9cfc..0ea8d40ba46 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -610,7 +610,8 @@ enum net_verdict net_icmpv4_input(struct net_pkt *pkt, return NET_DROP; } - if (net_if_need_calc_rx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_rx_checksum(net_pkt_iface(pkt)) || + net_pkt_is_ip_reassembled(pkt)) { if (net_calc_chksum_icmpv4(pkt) != 0U) { NET_DBG("DROP: Invalid checksum"); goto drop; diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index c04e3dddf72..65c01a510c7 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -342,7 +342,8 @@ enum net_verdict net_icmpv6_input(struct net_pkt *pkt, } - if (net_if_need_calc_rx_checksum(net_pkt_iface(pkt))) { + if (net_if_need_calc_rx_checksum(net_pkt_iface(pkt)) || + net_pkt_is_ip_reassembled(pkt)) { if (net_calc_chksum_icmpv6(pkt) != 0U) { NET_DBG("DROP: invalid checksum"); goto drop; diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 6ec7745c952..82faa777694 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -3609,7 +3609,8 @@ struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt, struct net_tcp_hdr *tcp_hdr; if (IS_ENABLED(CONFIG_NET_TCP_CHECKSUM) && - net_if_need_calc_rx_checksum(net_pkt_iface(pkt)) && + (net_if_need_calc_rx_checksum(net_pkt_iface(pkt)) || + net_pkt_is_ip_reassembled(pkt)) && net_calc_chksum_tcp(pkt) != 0U) { NET_DBG("DROP: checksum mismatch"); goto drop; diff --git a/subsys/net/ip/udp.c b/subsys/net/ip/udp.c index 5ecc595053b..e3f45b3db38 100644 --- a/subsys/net/ip/udp.c +++ b/subsys/net/ip/udp.c @@ -164,7 +164,8 @@ struct net_udp_hdr *net_udp_input(struct net_pkt *pkt, } if (IS_ENABLED(CONFIG_NET_UDP_CHECKSUM) && - net_if_need_calc_rx_checksum(net_pkt_iface(pkt))) { + (net_if_need_calc_rx_checksum(net_pkt_iface(pkt)) || + net_pkt_is_ip_reassembled(pkt))) { if (!udp_hdr->chksum) { if (IS_ENABLED(CONFIG_NET_UDP_MISSING_CHECKSUM) && net_pkt_family(pkt) == AF_INET) { From 736888be0c02a2c5ea74b12becc693598236c897 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 27 Oct 2023 14:11:20 +0200 Subject: [PATCH 3262/4498] tests: net: checksum_offload: Move net context init to helper function Move code responsible for net context initialization, repeated over multiple test cases, to a helper function to reduce code duplication. Signed-off-by: Robert Lubos --- tests/net/checksum_offload/src/main.c | 343 +++++++++----------------- 1 file changed, 122 insertions(+), 221 deletions(-) diff --git a/tests/net/checksum_offload/src/main.c b/tests/net/checksum_offload/src/main.c index 52b8add0fb0..4fc13344211 100644 --- a/tests/net/checksum_offload/src/main.c +++ b/tests/net/checksum_offload/src/main.c @@ -490,42 +490,103 @@ static void add_neighbor(struct net_if *iface, struct in6_addr *addr) } } -ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) +static struct net_context *test_udp_context_prepare(sa_family_t family, + bool offloaded, + struct sockaddr *dst_addr) { struct net_context *net_ctx; struct eth_context *ctx; /* This is interface context */ + struct sockaddr src_addr; + socklen_t addrlen; struct net_if *iface; - int ret, len; - struct sockaddr_in6 dst_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = htons(TEST_PORT), - }; - struct sockaddr_in6 src_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = 0, - }; - - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv6 UDP context failed"); - - memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr1, sizeof(struct in6_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, - sizeof(struct sockaddr_in6)); + int ret; + + if (family == AF_INET6) { + struct sockaddr_in6 *dst_addr6 = + (struct sockaddr_in6 *)dst_addr; + struct sockaddr_in6 *src_addr6 = + (struct sockaddr_in6 *)&src_addr; + + dst_addr6->sin6_family = AF_INET6; + dst_addr6->sin6_port = htons(TEST_PORT); + src_addr6->sin6_family = AF_INET6; + src_addr6->sin6_port = 0; + + if (offloaded) { + memcpy(&src_addr6->sin6_addr, &my_addr2, + sizeof(struct in6_addr)); + memcpy(&dst_addr6->sin6_addr, &dst_addr2, + sizeof(struct in6_addr)); + } else { + memcpy(&src_addr6->sin6_addr, &my_addr1, + sizeof(struct in6_addr)); + memcpy(&dst_addr6->sin6_addr, &dst_addr1, + sizeof(struct in6_addr)); + } + + addrlen = sizeof(struct sockaddr_in6); + } else { + struct sockaddr_in *dst_addr4 = + (struct sockaddr_in *)dst_addr; + struct sockaddr_in *src_addr4 = + (struct sockaddr_in *)&src_addr; + + dst_addr4->sin_family = AF_INET; + dst_addr4->sin_port = htons(TEST_PORT); + src_addr4->sin_family = AF_INET; + src_addr4->sin_port = 0; + + if (offloaded) { + memcpy(&src_addr4->sin_addr, &in4addr_my2, + sizeof(struct in_addr)); + memcpy(&dst_addr4->sin_addr, &in4addr_dst2, + sizeof(struct in_addr)); + } else { + memcpy(&src_addr4->sin_addr, &in4addr_my, + sizeof(struct in_addr)); + memcpy(&dst_addr4->sin_addr, &in4addr_dst, + sizeof(struct in_addr)); + } + + addrlen = sizeof(struct sockaddr_in6); + } + + ret = net_context_get(family, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); + zassert_equal(ret, 0, "Create %s UDP context failed", + family == AF_INET6 ? "IPv6" : "IPv4"); + + ret = net_context_bind(net_ctx, &src_addr, addrlen); zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[0]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_disabled, ctx, - "eth context mismatch"); + /* Verify iface data */ + if (offloaded) { + iface = eth_interfaces[1]; + ctx = net_if_get_device(iface)->data; + zassert_equal_ptr(ð_context_offloading_enabled, ctx, + "eth context mismatch"); + } else { + iface = eth_interfaces[0]; + ctx = net_if_get_device(iface)->data; + zassert_equal_ptr(ð_context_offloading_disabled, ctx, + "eth context mismatch"); + } + + return net_ctx; +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) +{ + struct net_context *net_ctx; + struct sockaddr dst_addr; + int ret, len; + + net_ctx = test_udp_context_prepare(AF_INET6, false, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; len = strlen(test_data); - - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr6, + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -541,39 +602,16 @@ ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in dst_addr4 = { - .sin_family = AF_INET, - .sin_port = htons(TEST_PORT), - }; - struct sockaddr_in src_addr4 = { - .sin_family = AF_INET, - .sin_port = 0, - }; - - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv4 UDP context failed"); - - memcpy(&src_addr4.sin_addr, &in4addr_my, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, - sizeof(struct sockaddr_in)); - zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[0]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_disabled, ctx, - "eth context mismatch"); - - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET, false, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr4, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -589,39 +627,16 @@ ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4) ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in6 dst_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = htons(TEST_PORT), - }; - struct sockaddr_in6 src_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = 0, - }; - - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv6 UDP context failed"); - - memcpy(&src_addr6.sin6_addr, &my_addr2, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr2, sizeof(struct in6_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, - sizeof(struct sockaddr_in6)); - zassert_equal(ret, 0, "Context bind failure test failed"); - - iface = eth_interfaces[1]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_enabled, ctx, - "eth context mismatch"); - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET6, true, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr6, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -637,39 +652,16 @@ ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6) ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in dst_addr4 = { - .sin_family = AF_INET, - .sin_port = htons(TEST_PORT), - }; - struct sockaddr_in src_addr4 = { - .sin_family = AF_INET, - .sin_port = 0, - }; - - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv4 UDP context failed"); - - memcpy(&src_addr4.sin_addr, &in4addr_my2, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst2, sizeof(struct in_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, - sizeof(struct sockaddr_in)); - zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[1]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_enabled, ctx, - "eth context mismatch"); - - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET, true, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr4, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -728,34 +720,11 @@ static void recv_cb_offload_enabled(struct net_context *context, ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in6 dst_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = htons(TEST_PORT), - }; - struct sockaddr_in6 src_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = 0, - }; - - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv6 UDP context failed"); - - memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr1, sizeof(struct in6_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, - sizeof(struct sockaddr_in6)); - zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[0]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_disabled, ctx, - "eth context mismatch"); - - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET6, false, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; start_receiving = true; @@ -764,8 +733,8 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr6, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -784,34 +753,11 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in dst_addr4 = { - .sin_family = AF_INET, - .sin_port = htons(TEST_PORT), - }; - struct sockaddr_in src_addr4 = { - .sin_family = AF_INET, - .sin_port = 0, - }; - - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv4 UDP context failed"); - - memcpy(&src_addr4.sin_addr, &in4addr_my, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst, sizeof(struct in_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, - sizeof(struct sockaddr_in)); - zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[0]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_disabled, ctx, - "eth context mismatch"); - - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET, false, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; start_receiving = true; @@ -820,8 +766,9 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); + len = strlen(test_data); ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr4, + (struct sockaddr *)&dst_addr, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -840,34 +787,11 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in6 dst_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = htons(TEST_PORT), - }; - struct sockaddr_in6 src_addr6 = { - .sin6_family = AF_INET6, - .sin6_port = 0, - }; - - ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv6 UDP context failed"); - - memcpy(&src_addr6.sin6_addr, &my_addr2, sizeof(struct in6_addr)); - memcpy(&dst_addr6.sin6_addr, &dst_addr2, sizeof(struct in6_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr6, - sizeof(struct sockaddr_in6)); - zassert_equal(ret, 0, "Context bind failure test failed"); - - iface = net_if_ipv6_select_src_iface(&dst_addr6.sin6_addr); - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_enabled, ctx, - "eth context mismatch"); - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET6, true, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; start_receiving = true; @@ -876,8 +800,8 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6) K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr6, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in6), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); @@ -896,34 +820,11 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6) ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4) { struct net_context *net_ctx; - struct eth_context *ctx; /* This is interface context */ - struct net_if *iface; + struct sockaddr dst_addr; int ret, len; - struct sockaddr_in dst_addr4 = { - .sin_family = AF_INET, - .sin_port = htons(TEST_PORT), - }; - struct sockaddr_in src_addr4 = { - .sin_family = AF_INET, - .sin_port = 0, - }; - - ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &net_ctx); - zassert_equal(ret, 0, "Create IPv4 UDP context failed"); - - memcpy(&src_addr4.sin_addr, &in4addr_my2, sizeof(struct in_addr)); - memcpy(&dst_addr4.sin_addr, &in4addr_dst2, sizeof(struct in_addr)); - - ret = net_context_bind(net_ctx, (struct sockaddr *)&src_addr4, - sizeof(struct sockaddr_in)); - zassert_equal(ret, 0, "Context bind failure test failed"); - iface = eth_interfaces[1]; - ctx = net_if_get_device(iface)->data; - zassert_equal_ptr(ð_context_offloading_enabled, ctx, - "eth context mismatch"); - - len = strlen(test_data); + net_ctx = test_udp_context_prepare(AF_INET, true, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; start_receiving = true; @@ -932,8 +833,8 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4) K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr4, + len = strlen(test_data); + ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, sizeof(struct sockaddr_in), NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); From 5f8a73f6cbc56fb454f5ab2508bd2636449ea0f7 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Sun, 29 Oct 2023 14:24:32 +0100 Subject: [PATCH 3263/4498] tests: net: checksum_offload: Move test code into helper function Further reduce code duplication by moving test code for similar test cases into a helper function, parametrized based on the test case. Signed-off-by: Robert Lubos --- tests/net/checksum_offload/src/main.c | 196 +++++--------------------- 1 file changed, 33 insertions(+), 163 deletions(-) diff --git a/tests/net/checksum_offload/src/main.c b/tests/net/checksum_offload/src/main.c index 4fc13344211..99d3057a1c5 100644 --- a/tests/net/checksum_offload/src/main.c +++ b/tests/net/checksum_offload/src/main.c @@ -574,24 +574,26 @@ static struct net_context *test_udp_context_prepare(sa_family_t family, return net_ctx; } -ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) +static void test_tx_chksum(sa_family_t family, bool offloaded) { + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + socklen_t addrlen = (family == AF_INET6) ? sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); struct net_context *net_ctx; struct sockaddr dst_addr; int ret, len; - net_ctx = test_udp_context_prepare(AF_INET6, false, &dst_addr); + net_ctx = test_udp_context_prepare(family, offloaded, &dst_addr); zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; len = strlen(test_data); ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in6), - NULL, K_FOREVER, NULL); + addrlen, NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { + if (k_sem_take(wait_data, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } @@ -599,79 +601,24 @@ ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) net_context_unref(net_ctx); } -ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4) +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET, false, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } + test_tx_chksum(AF_INET6, false); +} - net_context_unref(net_ctx); +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4) +{ + test_tx_chksum(AF_INET, false); } ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET6, true, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in6), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_off, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } - - net_context_unref(net_ctx); + test_tx_chksum(AF_INET6, true); } ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET, true, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_off, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } - - net_context_unref(net_ctx); + test_tx_chksum(AF_INET, true); } static void recv_cb_offload_disabled(struct net_context *context, @@ -717,29 +664,32 @@ static void recv_cb_offload_enabled(struct net_context *context, net_pkt_unref(pkt); } -ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) +static void test_rx_chksum(sa_family_t family, bool offloaded) { + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + net_context_recv_cb_t cb = offloaded ? recv_cb_offload_enabled : + recv_cb_offload_disabled; + socklen_t addrlen = (family == AF_INET6) ? sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); struct net_context *net_ctx; struct sockaddr dst_addr; int ret, len; - net_ctx = test_udp_context_prepare(AF_INET6, false, &dst_addr); + net_ctx = test_udp_context_prepare(family, offloaded, &dst_addr); zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; start_receiving = true; - ret = net_context_recv(net_ctx, recv_cb_offload_disabled, - K_NO_WAIT, NULL); + ret = net_context_recv(net_ctx, cb, K_NO_WAIT, NULL); zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); len = strlen(test_data); ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in6), - NULL, K_FOREVER, NULL); + addrlen, NULL, K_FOREVER, NULL); zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { + if (k_sem_take(wait_data, WAIT_TIME)) { DBG("Timeout while waiting interface data\n"); zassert_false(true, "Timeout"); } @@ -750,104 +700,24 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) net_context_unref(net_ctx); } -ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET, false, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - start_receiving = true; - - ret = net_context_recv(net_ctx, recv_cb_offload_disabled, - K_NO_WAIT, NULL); - zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, - (struct sockaddr *)&dst_addr, - sizeof(struct sockaddr_in), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_nonoff, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } - - /* Let the receiver to receive the packets */ - k_sleep(K_MSEC(10)); + test_rx_chksum(AF_INET6, false); +} - net_context_unref(net_ctx); +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4) +{ + test_rx_chksum(AF_INET, false); } ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET6, true, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - start_receiving = true; - - ret = net_context_recv(net_ctx, recv_cb_offload_enabled, - K_NO_WAIT, NULL); - zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in6), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_off, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } - - /* Let the receiver to receive the packets */ - k_sleep(K_MSEC(10)); - - net_context_unref(net_ctx); + test_rx_chksum(AF_INET6, true); } ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4) { - struct net_context *net_ctx; - struct sockaddr dst_addr; - int ret, len; - - net_ctx = test_udp_context_prepare(AF_INET, true, &dst_addr); - zassert_not_null(net_ctx, "Failed to obtain net_ctx"); - - test_started = true; - start_receiving = true; - - ret = net_context_recv(net_ctx, recv_cb_offload_enabled, - K_NO_WAIT, NULL); - zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); - - len = strlen(test_data); - ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, - sizeof(struct sockaddr_in), - NULL, K_FOREVER, NULL); - zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); - - if (k_sem_take(&wait_data_off, WAIT_TIME)) { - DBG("Timeout while waiting interface data\n"); - zassert_false(true, "Timeout"); - } - - /* Let the receiver to receive the packets */ - k_sleep(K_MSEC(10)); - - net_context_unref(net_ctx); + test_rx_chksum(AF_INET, true); } static void *net_chksum_offload_tests_setup(void) From f505dc528e0aa565ba24f6eaf0ff01a8f64fa860 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 26 Oct 2023 14:59:22 +0200 Subject: [PATCH 3264/4498] tests: net: checksum_offload: Add tests involving IP fragmentation Add test cases verifying proper checksum calculation involving IPv4/IPv6 fragmentation. Signed-off-by: Robert Lubos --- tests/net/checksum_offload/prj.conf | 6 +- tests/net/checksum_offload/src/main.c | 647 +++++++++++++++++++++++++- 2 files changed, 631 insertions(+), 22 deletions(-) diff --git a/tests/net/checksum_offload/prj.conf b/tests/net/checksum_offload/prj.conf index ac345eaa1d7..fb86bf9dfac 100644 --- a/tests/net/checksum_offload/prj.conf +++ b/tests/net/checksum_offload/prj.conf @@ -1,9 +1,11 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_NET_IPV6=y +CONFIG_NET_IPV6_FRAGMENT=y CONFIG_NET_UDP=y CONFIG_NET_TCP=y CONFIG_NET_IPV4=y +CONFIG_NET_IPV4_FRAGMENT=y CONFIG_NET_ARP=n CONFIG_NET_MAX_CONTEXTS=4 CONFIG_NET_L2_ETHERNET=y @@ -14,8 +16,8 @@ CONFIG_NET_IPV6_DAD=n CONFIG_NET_IPV6_MLD=n CONFIG_NET_PKT_TX_COUNT=15 CONFIG_NET_PKT_RX_COUNT=15 -CONFIG_NET_BUF_RX_COUNT=15 -CONFIG_NET_BUF_TX_COUNT=15 +CONFIG_NET_BUF_RX_COUNT=40 +CONFIG_NET_BUF_TX_COUNT=40 CONFIG_NET_IF_MAX_IPV6_COUNT=2 CONFIG_NET_IF_MAX_IPV4_COUNT=2 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 diff --git a/tests/net/checksum_offload/src/main.c b/tests/net/checksum_offload/src/main.c index 99d3057a1c5..e9c59695602 100644 --- a/tests/net/checksum_offload/src/main.c +++ b/tests/net/checksum_offload/src/main.c @@ -43,6 +43,8 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #define TEST_PORT 9999 static char *test_data = "Test data to be sent"; +static uint8_t test_data_large[2000]; +static uint8_t verify_buf[2000]; /* Interface 1 addresses */ static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, @@ -78,7 +80,12 @@ static struct net_if *eth_interfaces[2 + IS_ENABLED(CONFIG_ETH_NATIVE_POSIX)]; static bool test_failed; static bool test_started; +static int test_proto; +static bool verify_fragment; static bool start_receiving; +static bool change_chksum; +static int fragment_count; +static int fragment_offset; static K_SEM_DEFINE(wait_data_off, 0, UINT_MAX); static K_SEM_DEFINE(wait_data_nonoff, 0, UINT_MAX); @@ -95,6 +102,15 @@ struct eth_context { static struct eth_context eth_context_offloading_disabled; static struct eth_context eth_context_offloading_enabled; +static void verify_test_data_large(uint8_t *buf, size_t offset, size_t len) +{ + zassert(offset + len <= sizeof(test_data_large), "Out of bound data"); + + for (size_t i = 0; i < len; i++) { + zassert_equal(buf[i], test_data_large[offset + i], "Invalid data"); + } +} + static void eth_iface_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); @@ -137,10 +153,35 @@ static uint16_t get_udp_chksum(struct net_pkt *pkt) return udp_hdr->chksum; } +static uint16_t get_icmp_chksum(struct net_pkt *pkt) +{ + NET_PKT_DATA_ACCESS_DEFINE(icmp_access, struct net_icmp_hdr); + struct net_icmp_hdr *icmp_hdr; + struct net_pkt_cursor backup; + + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_backup(pkt, &backup); + net_pkt_cursor_init(pkt); + + /* Move the cursor to the ICMP header */ + if (net_pkt_skip(pkt, sizeof(struct net_eth_hdr) + + net_pkt_ip_hdr_len(pkt) + + net_pkt_ipv6_ext_len(pkt))) { + return 0; + } + + icmp_hdr = (struct net_icmp_hdr *)net_pkt_get_data(pkt, &icmp_access); + if (!icmp_hdr) { + return 0; + } + + net_pkt_cursor_restore(pkt, &backup); + + return icmp_hdr->chksum; +} + static void test_receiving(struct net_pkt *pkt) { - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(udp_access, struct net_udp_hdr); - struct net_udp_hdr *udp_hdr; uint16_t port; uint8_t lladdr[6]; @@ -187,13 +228,39 @@ static void test_receiving(struct net_pkt *pkt) net_ipv4_addr_copy_raw(ipv4_hdr->dst, (uint8_t *)&addr); } - net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ip_opts_len(pkt)); - udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access); - zassert_not_null(udp_hdr, "Can't access UDP header"); - - port = udp_hdr->src_port; - udp_hdr->src_port = udp_hdr->dst_port; - udp_hdr->dst_port = port; + if (!verify_fragment || fragment_count == 1) { + net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ip_opts_len(pkt)); + if (test_proto == IPPROTO_UDP) { + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE( + udp_access, struct net_udp_hdr); + struct net_udp_hdr *udp_hdr; + + udp_hdr = (struct net_udp_hdr *) + net_pkt_get_data(pkt, &udp_access); + zassert_not_null(udp_hdr, "Can't access UDP header"); + + port = udp_hdr->src_port; + udp_hdr->src_port = udp_hdr->dst_port; + udp_hdr->dst_port = port; + + if (change_chksum) { + udp_hdr->chksum++; + } + } else if (test_proto == IPPROTO_ICMP || + test_proto == IPPROTO_ICMPV6) { + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE( + icmp_access, struct net_icmp_hdr); + struct net_icmp_hdr *icmp_hdr; + + icmp_hdr = (struct net_icmp_hdr *) + net_pkt_get_data(pkt, &icmp_access); + zassert_not_null(icmp_hdr, "Can't access ICMP header"); + + if (change_chksum) { + icmp_hdr->chksum++; + } + } + } net_pkt_cursor_init(pkt); @@ -204,6 +271,61 @@ static void test_receiving(struct net_pkt *pkt) } } +static void test_fragment(struct net_pkt *pkt, bool offloaded) +{ + uint16_t chksum = 0; + size_t data_len; + size_t hdr_offset = sizeof(struct net_eth_hdr) + + net_pkt_ip_hdr_len(pkt) + + net_pkt_ip_opts_len(pkt); + + fragment_count++; + + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_init(pkt); + + if (start_receiving) { + test_receiving(pkt); + return; + } + + if (fragment_count == 1) { + if (test_proto == IPPROTO_UDP) { + chksum = get_udp_chksum(pkt); + hdr_offset += sizeof(struct net_udp_hdr); + } else if (test_proto == IPPROTO_ICMP || + test_proto == IPPROTO_ICMPV6) { + chksum = get_icmp_chksum(pkt); + hdr_offset += sizeof(struct net_icmp_hdr) + + sizeof(struct net_icmpv6_echo_req); + } + + /* Fragmented packet should have checksum set regardless of + * checksum offloading + */ + zassert_not_equal(chksum, 0, "Checksum missing"); + } + + zassert_true(net_pkt_is_chksum_done(pkt), + "Checksum should me marked as ready on net_pkt"); + + /* Verify that payload has not been altered. */ + data_len = net_pkt_get_len(pkt) - hdr_offset; + net_pkt_skip(pkt, hdr_offset); + net_pkt_read(pkt, verify_buf, data_len); + + verify_test_data_large(verify_buf, fragment_offset, data_len); + fragment_offset += data_len; + + if (fragment_count > 1) { + if (offloaded) { + k_sem_give(&wait_data_off); + } else { + k_sem_give(&wait_data_nonoff); + } + } +} + static int eth_tx_offloading_disabled(const struct device *dev, struct net_pkt *pkt) { @@ -218,19 +340,29 @@ static int eth_tx_offloading_disabled(const struct device *dev, return -ENODATA; } + if (verify_fragment) { + test_fragment(pkt, false); + return 0; + } + if (start_receiving) { test_receiving(pkt); return 0; } if (test_started) { - uint16_t chksum; + uint16_t chksum = 0; - chksum = get_udp_chksum(pkt); + if (test_proto == IPPROTO_UDP) { + chksum = get_udp_chksum(pkt); + } else if (test_proto == IPPROTO_ICMP || + test_proto == IPPROTO_ICMPV6) { + chksum = get_icmp_chksum(pkt); + } DBG("Chksum 0x%x offloading disabled\n", chksum); - zassert_not_equal(chksum, 0, "Checksum calculated"); + zassert_not_equal(chksum, 0, "Checksum not calculated"); k_sem_give(&wait_data_nonoff); } @@ -252,15 +384,24 @@ static int eth_tx_offloading_enabled(const struct device *dev, return -ENODATA; } + if (verify_fragment) { + test_fragment(pkt, true); + return 0; + } + if (start_receiving) { test_receiving(pkt); - return 0; } if (test_started) { - uint16_t chksum; + uint16_t chksum = 0; - chksum = get_udp_chksum(pkt); + if (test_proto == IPPROTO_UDP) { + chksum = get_udp_chksum(pkt); + } else if (test_proto == IPPROTO_ICMP || + test_proto == IPPROTO_ICMPV6) { + chksum = get_icmp_chksum(pkt); + } DBG("Chksum 0x%x offloading enabled\n", chksum); @@ -587,6 +728,7 @@ static void test_tx_chksum(sa_family_t family, bool offloaded) zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; + test_proto = IPPROTO_UDP; len = strlen(test_data); ret = net_context_sendto(net_ctx, test_data, len, &dst_addr, @@ -621,6 +763,179 @@ ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4) test_tx_chksum(AF_INET, true); } +static void test_tx_chksum_udp_frag(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + socklen_t addrlen = (family == AF_INET6) ? sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + struct net_context *net_ctx; + struct sockaddr dst_addr; + int ret, len; + + net_ctx = test_udp_context_prepare(family, offloaded, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); + + test_started = true; + test_proto = IPPROTO_UDP; + verify_fragment = true; + + len = sizeof(test_data_large); + ret = net_context_sendto(net_ctx, test_data_large, len, &dst_addr, + addrlen, NULL, K_FOREVER, NULL); + zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); + + if (k_sem_take(wait_data, WAIT_TIME)) { + DBG("Timeout while waiting interface data\n"); + zassert_false(true, "Timeout"); + } + + net_context_unref(net_ctx); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6_udp_frag) +{ + test_tx_chksum_udp_frag(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4_udp_frag) +{ + test_tx_chksum_udp_frag(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6_udp_frag) +{ + test_tx_chksum_udp_frag(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4_udp_frag) +{ + test_tx_chksum_udp_frag(AF_INET, true); +} + +static int dummy_icmp_handler(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + ARG_UNUSED(ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(hdr); + ARG_UNUSED(icmp_hdr); + ARG_UNUSED(user_data); + + return 0; +} + +static void test_icmp_init(sa_family_t family, bool offloaded, + struct sockaddr *dst_addr, struct net_if **iface) +{ + if (family == AF_INET6) { + struct sockaddr_in6 *dst_addr6 = + (struct sockaddr_in6 *)dst_addr; + + dst_addr6->sin6_family = AF_INET6; + + if (offloaded) { + memcpy(&dst_addr6->sin6_addr, &dst_addr2, + sizeof(struct in6_addr)); + } else { + memcpy(&dst_addr6->sin6_addr, &dst_addr1, + sizeof(struct in6_addr)); + } + } else { + struct sockaddr_in *dst_addr4 = + (struct sockaddr_in *)dst_addr; + + dst_addr4->sin_family = AF_INET; + + if (offloaded) { + memcpy(&dst_addr4->sin_addr, &in4addr_dst2, + sizeof(struct in_addr)); + } else { + memcpy(&dst_addr4->sin_addr, &in4addr_dst, + sizeof(struct in_addr)); + } + } + + if (offloaded) { + *iface = eth_interfaces[1]; + } else { + *iface = eth_interfaces[0]; + } +} + +static void test_tx_chksum_icmp_frag(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + struct net_icmp_ping_params params = { 0 }; + struct net_icmp_ctx ctx; + struct sockaddr dst_addr; + struct net_if *iface; + int ret; + + test_icmp_init(family, offloaded, &dst_addr, &iface); + + ret = net_icmp_init_ctx(&ctx, 0, 0, dummy_icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + test_started = true; + test_proto = (family == AF_INET6) ? IPPROTO_ICMPV6 : IPPROTO_ICMP; + verify_fragment = true; + + params.data = test_data_large; + params.data_size = sizeof(test_data_large); + ret = net_icmp_send_echo_request(&ctx, iface, &dst_addr, ¶ms, NULL); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + if (k_sem_take(wait_data, WAIT_TIME)) { + DBG("Timeout while waiting interface data\n"); + zassert_false(true, "Timeout"); + } + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6_icmp_frag) +{ + test_tx_chksum_icmp_frag(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4_icmp_frag) +{ + test_tx_chksum_icmp_frag(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6_icmp_frag) +{ + test_tx_chksum_icmp_frag(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4_icmp_frag) +{ + test_tx_chksum_icmp_frag(AF_INET, true); +} + +static void test_fragment_rx_udp(struct net_pkt *pkt, + union net_proto_header *proto_hdr) +{ + size_t hdr_offset = net_pkt_ip_hdr_len(pkt) + + net_pkt_ip_opts_len(pkt) + + sizeof(struct net_udp_hdr); + size_t data_len = net_pkt_get_len(pkt) - hdr_offset; + + /* In case of fragmented packets, checksum shall be present/verified + * regardless. + */ + zassert_not_equal(proto_hdr->udp->chksum, 0, "Checksum is not set"); + zassert_equal(net_calc_verify_chksum_udp(pkt), 0, "Incorrect checksum"); + + /* Verify that packet content has not been altered */ + net_pkt_read(pkt, verify_buf, data_len); + verify_test_data_large(verify_buf, 0, data_len); +} + static void recv_cb_offload_disabled(struct net_context *context, struct net_pkt *pkt, union net_ip_header *ip_hdr, @@ -629,7 +944,13 @@ static void recv_cb_offload_disabled(struct net_context *context, void *user_data) { zassert_not_null(proto_hdr->udp, "UDP header missing"); - zassert_not_equal(proto_hdr->udp->chksum, 0, "Checksum is not set"); + + if (verify_fragment) { + test_fragment_rx_udp(pkt, proto_hdr); + } else { + zassert_not_equal(proto_hdr->udp->chksum, 0, "Checksum is not set"); + zassert_equal(net_calc_verify_chksum_udp(pkt), 0, "Incorrect checksum"); + } if (net_pkt_family(pkt) == AF_INET) { struct net_ipv4_hdr *ipv4 = NET_IPV4_HDR(pkt); @@ -651,12 +972,17 @@ static void recv_cb_offload_enabled(struct net_context *context, void *user_data) { zassert_not_null(proto_hdr->udp, "UDP header missing"); - zassert_equal(proto_hdr->udp->chksum, 0, "Checksum is set"); - if (net_pkt_family(pkt) == AF_INET) { - struct net_ipv4_hdr *ipv4 = NET_IPV4_HDR(pkt); + if (verify_fragment) { + test_fragment_rx_udp(pkt, proto_hdr); + } else { + zassert_equal(proto_hdr->udp->chksum, 0, "Checksum is set"); + + if (net_pkt_family(pkt) == AF_INET) { + struct net_ipv4_hdr *ipv4 = NET_IPV4_HDR(pkt); - zassert_equal(ipv4->chksum, 0, "IPv4 checksum is set"); + zassert_equal(ipv4->chksum, 0, "IPv4 checksum is set"); + } } k_sem_give(&wait_data_off); @@ -679,6 +1005,7 @@ static void test_rx_chksum(sa_family_t family, bool offloaded) zassert_not_null(net_ctx, "Failed to obtain net_ctx"); test_started = true; + test_proto = IPPROTO_UDP; start_receiving = true; ret = net_context_recv(net_ctx, cb, K_NO_WAIT, NULL); @@ -720,6 +1047,275 @@ ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4) test_rx_chksum(AF_INET, true); } +static void test_rx_chksum_udp_frag(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + net_context_recv_cb_t cb = offloaded ? recv_cb_offload_enabled : + recv_cb_offload_disabled; + socklen_t addrlen = (family == AF_INET6) ? sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + struct net_context *net_ctx; + struct sockaddr dst_addr; + int ret, len; + + net_ctx = test_udp_context_prepare(family, offloaded, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); + + test_started = true; + test_proto = IPPROTO_UDP; + start_receiving = true; + verify_fragment = true; + + ret = net_context_recv(net_ctx, cb, K_NO_WAIT, NULL); + zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); + + len = sizeof(test_data_large); + ret = net_context_sendto(net_ctx, test_data_large, len, &dst_addr, + addrlen, NULL, K_FOREVER, NULL); + zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); + + if (k_sem_take(wait_data, WAIT_TIME)) { + DBG("Timeout while waiting interface data\n"); + zassert_false(true, "Timeout"); + } + + /* Let the receiver to receive the packets */ + k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6_udp_frag) +{ + test_rx_chksum_udp_frag(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4_udp_frag) +{ + test_rx_chksum_udp_frag(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6_udp_frag) +{ + test_rx_chksum_udp_frag(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4_udp_frag) +{ + test_rx_chksum_udp_frag(AF_INET, true); +} + +static void test_rx_chksum_udp_frag_bad(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + net_context_recv_cb_t cb = offloaded ? recv_cb_offload_enabled : + recv_cb_offload_disabled; + socklen_t addrlen = (family == AF_INET6) ? sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + struct net_context *net_ctx; + struct sockaddr dst_addr; + int ret, len; + + net_ctx = test_udp_context_prepare(family, offloaded, &dst_addr); + zassert_not_null(net_ctx, "Failed to obtain net_ctx"); + + test_started = true; + test_proto = IPPROTO_UDP; + start_receiving = true; + verify_fragment = true; + change_chksum = true; + + ret = net_context_recv(net_ctx, cb, K_NO_WAIT, NULL); + zassert_equal(ret, 0, "Recv UDP failed (%d)\n", ret); + + len = sizeof(test_data_large); + ret = net_context_sendto(net_ctx, test_data_large, len, &dst_addr, + addrlen, NULL, K_FOREVER, NULL); + zassert_equal(ret, len, "Send UDP pkt failed (%d)\n", ret); + + if (k_sem_take(wait_data, WAIT_TIME) == 0) { + DBG("Packet with bad chksum should be dropped\n"); + zassert_false(true, "Packet received"); + } + + /* Let the receiver to receive the packets */ + k_sleep(K_MSEC(10)); + + net_context_unref(net_ctx); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v6_udp_frag_bad) +{ + test_rx_chksum_udp_frag_bad(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_disabled_test_v4_udp_frag_bad) +{ + test_rx_chksum_udp_frag_bad(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v6_udp_frag_bad) +{ + test_rx_chksum_udp_frag_bad(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_tx_chksum_offload_enabled_test_v4_udp_frag_bad) +{ + test_rx_chksum_udp_frag_bad(AF_INET, true); +} + +static int icmp_handler(struct net_icmp_ctx *ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + struct k_sem *wait_data = user_data; + + size_t hdr_offset = net_pkt_ip_hdr_len(pkt) + + net_pkt_ip_opts_len(pkt) + + sizeof(struct net_icmp_hdr) + + sizeof(struct net_icmpv6_echo_req); + size_t data_len = net_pkt_get_len(pkt) - hdr_offset; + + /* In case of fragmented packets, checksum shall be present/verified + * regardless. + */ + zassert_not_equal(icmp_hdr->chksum, 0, "Checksum is not set"); + + if (test_proto == IPPROTO_ICMPV6) { + zassert_equal(net_calc_chksum_icmpv6(pkt), 0, "Incorrect checksum"); + } else { + zassert_equal(net_calc_chksum_icmpv4(pkt), 0, "Incorrect checksum"); + } + + /* Verify that packet content has not been altered */ + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_init(pkt); + net_pkt_skip(pkt, hdr_offset); + net_pkt_read(pkt, verify_buf, data_len); + verify_test_data_large(verify_buf, 0, data_len); + + k_sem_give(wait_data); + + return 0; +} + +static void test_rx_chksum_icmp_frag(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + struct net_icmp_ping_params params = { 0 }; + struct net_icmp_ctx ctx; + struct sockaddr dst_addr; + struct net_if *iface; + int ret; + + test_icmp_init(family, offloaded, &dst_addr, &iface); + + ret = net_icmp_init_ctx(&ctx, + family == AF_INET6 ? NET_ICMPV6_ECHO_REPLY : + NET_ICMPV4_ECHO_REPLY, + 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + test_started = true; + test_proto = (family == AF_INET6) ? IPPROTO_ICMPV6 : IPPROTO_ICMP; + start_receiving = true; + verify_fragment = true; + + params.data = test_data_large; + params.data_size = sizeof(test_data_large); + ret = net_icmp_send_echo_request(&ctx, iface, &dst_addr, ¶ms, + wait_data); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + if (k_sem_take(wait_data, WAIT_TIME)) { + DBG("Timeout while waiting interface data\n"); + zassert_false(true, "Timeout"); + } + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6_icmp_frag) +{ + test_rx_chksum_icmp_frag(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4_icmp_frag) +{ + test_rx_chksum_icmp_frag(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6_icmp_frag) +{ + test_rx_chksum_icmp_frag(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4_icmp_frag) +{ + test_rx_chksum_icmp_frag(AF_INET, true); +} + +static void test_rx_chksum_icmp_frag_bad(sa_family_t family, bool offloaded) +{ + struct k_sem *wait_data = offloaded ? &wait_data_off : &wait_data_nonoff; + struct net_icmp_ping_params params = { 0 }; + struct net_icmp_ctx ctx; + struct sockaddr dst_addr; + struct net_if *iface; + int ret; + + test_icmp_init(family, offloaded, &dst_addr, &iface); + + ret = net_icmp_init_ctx(&ctx, + family == AF_INET6 ? NET_ICMPV6_ECHO_REPLY : + NET_ICMPV4_ECHO_REPLY, + 0, icmp_handler); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + test_started = true; + test_proto = (family == AF_INET6) ? IPPROTO_ICMPV6 : IPPROTO_ICMP; + start_receiving = true; + verify_fragment = true; + change_chksum = true; + + params.data = test_data_large; + params.data_size = sizeof(test_data_large); + ret = net_icmp_send_echo_request(&ctx, iface, &dst_addr, ¶ms, + wait_data); + zassert_equal(ret, 0, "Cannot send ICMP Echo-Request (%d)", ret); + + if (k_sem_take(wait_data, WAIT_TIME) == 0) { + DBG("Packet with bad chksum should be dropped\n"); + zassert_false(true, "Packet received"); + } + + ret = net_icmp_cleanup_ctx(&ctx); + zassert_equal(ret, 0, "Cannot cleanup ICMP (%d)", ret); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v6_icmp_frag_bad) +{ + test_rx_chksum_icmp_frag_bad(AF_INET6, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_disabled_test_v4_icmp_frag_bad) +{ + test_rx_chksum_icmp_frag_bad(AF_INET, false); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v6_icmp_frag_bad) +{ + test_rx_chksum_icmp_frag_bad(AF_INET6, true); +} + +ZTEST(net_chksum_offload, test_rx_chksum_offload_enabled_test_v4_icmp_frag_bad) +{ + test_rx_chksum_icmp_frag_bad(AF_INET, true); +} + static void *net_chksum_offload_tests_setup(void) { test_eth_setup(); @@ -728,6 +1324,10 @@ static void *net_chksum_offload_tests_setup(void) add_neighbor(eth_interfaces[0], &dst_addr1); add_neighbor(eth_interfaces[1], &dst_addr2); + for (size_t i = 0; i < sizeof(test_data_large); i++) { + test_data_large[i] = (uint8_t)i; + } + return NULL; } @@ -741,6 +1341,13 @@ static void net_chksum_offload_tests_before(void *fixture) test_failed = false; test_started = false; start_receiving = false; + verify_fragment = false; + change_chksum = false; + fragment_count = 0; + fragment_offset = 0; + test_proto = 0; + + memset(verify_buf, 0, sizeof(verify_buf)); } ZTEST_SUITE(net_chksum_offload, NULL, net_chksum_offload_tests_setup, From c724cf99f4d40a056dc1aaef594c55754b43e99a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 8 Nov 2023 10:18:01 +0100 Subject: [PATCH 3265/4498] net: pkt: Add explicit flag to indicate packet is IP reassembled The current logic to determine whether a packet is IP reassembled is flawed, as it only worked in certain conditions (which was ok, as the conditions were satisfied for the current use case, but now it's a public function). Therefore, add an explicit flag that indicates whether a packet is IP reassembled or not. Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 33 ++++++++++++++++++++++++--------- subsys/net/ip/ipv4_fragment.c | 1 + subsys/net/ip/ipv6_fragment.c | 1 + subsys/net/ip/net_pkt.c | 1 + 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 591002a9d66..fb00d7b980c 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -197,7 +197,9 @@ struct net_pkt { uint8_t chksum_done : 1; /* Checksum has already been computed for * the packet. */ - +#if defined(CONFIG_NET_IPV4_FRAGMENT) || defined(CONFIG_NET_IPV6_FRAGMENT) + uint8_t ip_reassembled : 1; /* Packet is a reassembled IP packet. */ +#endif /* bitfield byte alignment boundary */ #if defined(CONFIG_NET_IP) @@ -836,20 +838,33 @@ static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ +#if defined(CONFIG_NET_IPV4_FRAGMENT) || defined(CONFIG_NET_IPV6_FRAGMENT) static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt) { - if ((IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) && - net_pkt_family(pkt) == AF_INET && - net_pkt_ipv4_fragment_more(pkt)) || - (IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT) && - net_pkt_family(pkt) == AF_INET6 && - net_pkt_ipv6_fragment_start(pkt))) { - return true; - } + return !!(pkt->ip_reassembled); +} + +static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt, + bool reassembled) +{ + pkt->ip_reassembled = reassembled; +} +#else /* CONFIG_NET_IPV4_FRAGMENT || CONFIG_NET_IPV6_FRAGMENT */ +static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); return false; } +static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt, + bool reassembled) +{ + ARG_UNUSED(pkt); + ARG_UNUSED(reassembled); +} +#endif /* CONFIG_NET_IPV4_FRAGMENT || CONFIG_NET_IPV6_FRAGMENT */ + static inline uint8_t net_pkt_priority(struct net_pkt *pkt) { return pkt->priority; diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index 5bcf4e0026c..ee6e43c83d3 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -203,6 +203,7 @@ static void reassemble_packet(struct net_ipv4_reassembly *reass) ipv4_hdr->chksum = net_calc_chksum_ipv4(pkt); net_pkt_set_data(pkt, &ipv4_access); + net_pkt_set_ip_reassembled(pkt, true); LOG_DBG("New pkt %p IPv4 len is %d bytes", pkt, net_pkt_get_len(pkt)); diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 6d391b3b823..fda00c59f03 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -338,6 +338,7 @@ static void reassemble_packet(struct net_ipv6_reassembly *reass) ipv6.hdr->len = htons(len); net_pkt_set_data(pkt, &ipv6_access); + net_pkt_set_ip_reassembled(pkt, true); NET_DBG("New pkt %p IPv6 len is %d bytes", pkt, len + NET_IPV6H_LEN); diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index cef7cbcd107..ea60060abe5 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1813,6 +1813,7 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt) net_pkt_set_ptp(clone_pkt, net_pkt_is_ptp(pkt)); net_pkt_set_forwarding(clone_pkt, net_pkt_forwarding(pkt)); net_pkt_set_chksum_done(clone_pkt, net_pkt_is_chksum_done(pkt)); + net_pkt_set_ip_reassembled(pkt, net_pkt_is_ip_reassembled(pkt)); net_pkt_set_l2_bridged(clone_pkt, net_pkt_is_l2_bridged(pkt)); net_pkt_set_l2_processed(clone_pkt, net_pkt_is_l2_processed(pkt)); From 83f9fc4ce2537d9cb9ba820ec2b705a09926c68e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 8 Nov 2023 10:53:04 +0100 Subject: [PATCH 3266/4498] net: ip: Add hidden Kconfig symbol for IP fragmentation Instead of consistently checking for both, IPv4 and IPv6 fragmentation in several places, add a hidden Kconfig symbol which indicates that some IP fragmentation has been enabled (either IPv4 or IPv6 or both). Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 12 ++++++------ subsys/net/ip/Kconfig | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index fb00d7b980c..4f67249f15b 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -197,7 +197,7 @@ struct net_pkt { uint8_t chksum_done : 1; /* Checksum has already been computed for * the packet. */ -#if defined(CONFIG_NET_IPV4_FRAGMENT) || defined(CONFIG_NET_IPV6_FRAGMENT) +#if defined(CONFIG_NET_IP_FRAGMENT) uint8_t ip_reassembled : 1; /* Packet is a reassembled IP packet. */ #endif /* bitfield byte alignment boundary */ @@ -224,7 +224,7 @@ struct net_pkt { #endif }; -#if defined(CONFIG_NET_IPV4_FRAGMENT) || defined(CONFIG_NET_IPV6_FRAGMENT) +#if defined(CONFIG_NET_IP_FRAGMENT) union { #if defined(CONFIG_NET_IPV4_FRAGMENT) struct { @@ -240,7 +240,7 @@ struct net_pkt { } ipv6_fragment; #endif /* CONFIG_NET_IPV6_FRAGMENT */ }; -#endif /* CONFIG_NET_IPV4_FRAGMENT || CONFIG_NET_IPV6_FRAGMENT */ +#endif /* CONFIG_NET_IP_FRAGMENT */ #if defined(CONFIG_NET_IPV6) /* Where is the start of the last header before payload data @@ -838,7 +838,7 @@ static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt, } #endif /* CONFIG_NET_IPV6_FRAGMENT */ -#if defined(CONFIG_NET_IPV4_FRAGMENT) || defined(CONFIG_NET_IPV6_FRAGMENT) +#if defined(CONFIG_NET_IP_FRAGMENT) static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt) { return !!(pkt->ip_reassembled); @@ -849,7 +849,7 @@ static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt, { pkt->ip_reassembled = reassembled; } -#else /* CONFIG_NET_IPV4_FRAGMENT || CONFIG_NET_IPV6_FRAGMENT */ +#else /* CONFIG_NET_IP_FRAGMENT */ static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt) { ARG_UNUSED(pkt); @@ -863,7 +863,7 @@ static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt, ARG_UNUSED(pkt); ARG_UNUSED(reassembled); } -#endif /* CONFIG_NET_IPV4_FRAGMENT || CONFIG_NET_IPV6_FRAGMENT */ +#endif /* CONFIG_NET_IP_FRAGMENT */ static inline uint8_t net_pkt_priority(struct net_pkt *pkt) { diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index b8e51e09f64..fffa028b628 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -12,6 +12,11 @@ config NET_IP bool default y if NET_IPV6 || NET_IPV4 +# Hidden option enabled whenever an IP fragmentation is enabled. +config NET_IP_FRAGMENT + bool + default y if NET_IPV6_FRAGMENT || NET_IPV4_FRAGMENT + # Hidden option selected by net connection based socket implementations # to draw in all code required for connection infrastructure. config NET_CONNECTION_SOCKETS From c5ee143d773e713901896319a4d116082ca0771d Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Wed, 1 Nov 2023 15:44:23 +0100 Subject: [PATCH 3267/4498] Bluetooth: Mesh: no more tinycrypt in ble mesh tfm image PR allows to get rid of tinycrypt objects from the final binary of the ble mesh apps based on PSA TFM crypto. Signed-off-by: Aleksandr Khromykh --- .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 5 +++ .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 5 +++ .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 3 ++ subsys/bluetooth/host/Kconfig | 7 ++-- subsys/bluetooth/mesh/crypto_psa.c | 10 ++++++ tests/bsim/bluetooth/mesh/overlay_psa.conf | 5 +++ tests/bsim/bluetooth/mesh/src/test_dfu.c | 35 ++++++++++--------- .../bluetooth/mesh/src/test_persistence.c | 2 +- .../bluetooth/mesh/src/test_replay_cache.c | 8 +++++ 9 files changed, 59 insertions(+), 21 deletions(-) diff --git a/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index c638a292c91..4693e4d1f78 100644 --- a/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,3 +1,8 @@ +# The option adds TinyCrypt based bt_rand. +CONFIG_BT_HOST_CRYPTO=n +# The option adds GATT caching feature that is based on TinyCrypt. +CONFIG_BT_GATT_CACHING=n + # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index c638a292c91..4693e4d1f78 100644 --- a/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,3 +1,8 @@ +# The option adds TinyCrypt based bt_rand. +CONFIG_BT_HOST_CRYPTO=n +# The option adds GATT caching feature that is based on TinyCrypt. +CONFIG_BT_GATT_CACHING=n + # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index c638a292c91..c3d134592fc 100644 --- a/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,3 +1,6 @@ +# The option adds TinyCrypt based bt_rand. +CONFIG_BT_HOST_CRYPTO=n + # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 59cf196c363..f09d8a14d72 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -163,12 +163,13 @@ rsource "../mesh/Kconfig" rsource "../audio/Kconfig" config BT_HOST_CRYPTO - # Hidden option that compiles in AES encryption support using TinyCrypt - # library if this is not provided by the controller implementation. - bool + bool "Use crypto functionality implemented in the Bluetooth host" default y if !BT_CTLR_CRYPTO select TINYCRYPT select TINYCRYPT_AES + help + The option adds the AES encryption support using TinyCrypt + library if this is not provided by the controller implementation. config BT_HOST_CRYPTO_PRNG bool "Use Tinycrypt library for random number generation" diff --git a/subsys/bluetooth/mesh/crypto_psa.c b/subsys/bluetooth/mesh/crypto_psa.c index 450cde679a8..587c367a6bd 100644 --- a/subsys/bluetooth/mesh/crypto_psa.c +++ b/subsys/bluetooth/mesh/crypto_psa.c @@ -7,6 +7,7 @@ #include #include +#include #define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL #include @@ -510,3 +511,12 @@ int bt_mesh_key_compare(const uint8_t raw_key[16], const struct bt_mesh_key *key return memcmp(out, raw_key, 16); } + +__weak int bt_rand(void *buf, size_t len) +{ + CHECKIF(buf == NULL || len == 0) { + return -EINVAL; + } + + return psa_generate_random(buf, len) == PSA_SUCCESS ? 0 : -EIO; +} diff --git a/tests/bsim/bluetooth/mesh/overlay_psa.conf b/tests/bsim/bluetooth/mesh/overlay_psa.conf index ba81c1e0213..1957085b7e4 100644 --- a/tests/bsim/bluetooth/mesh/overlay_psa.conf +++ b/tests/bsim/bluetooth/mesh/overlay_psa.conf @@ -1,2 +1,7 @@ +# The option adds TinyCrypt based bt_rand. +CONFIG_BT_HOST_CRYPTO=n +# The option adds GATT caching feature that is based on TinyCrypt. +CONFIG_BT_GATT_CACHING=n + # Enable mbedTLS PSA as a crypto backend CONFIG_BT_MESH_USES_MBEDTLS_PSA=y diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 08631cba6b6..0eed5d1478d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define TARGET_ADDR 0x0100 #define IMPOSTER_MODEL_ID 0xe000 #define TEST_BLOB_ID 0xaabbccdd +#define SEMAPHORE_TIMEOUT 250 /* seconds */ struct bind_params { uint16_t model_id; @@ -1016,7 +1017,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(200))) { + if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } @@ -1050,7 +1051,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client apply failed (err: %d)", err); } - if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Failed to apply firmware"); } @@ -1063,7 +1064,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client confirm failed (err: %d)", err); } - if (k_sem_take(&dfu_cli_confirmed_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_cli_confirmed_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Failed to confirm firmware"); } @@ -1096,7 +1097,7 @@ static void test_cli_all_targets_lost_common(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(200))) { + if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } } @@ -1187,7 +1188,7 @@ static void test_cli_all_targets_lost_on_apply(void) FAIL("DFU Client apply failed (err: %d)", err); } - if (!k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { + if (!k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Apply should not be successful on any target"); } @@ -1218,7 +1219,7 @@ static void test_cli_stop(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_started, K_SECONDS(200))) { + if (k_sem_take(&dfu_started, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } @@ -1234,7 +1235,7 @@ static void test_cli_stop(void) FAIL("DFU Client resume failed (err: %d)", err); } - if (k_sem_take(&dfu_verifying, K_SECONDS(200))) { + if (k_sem_take(&dfu_verifying, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } ASSERT_EQUAL(BT_MESH_DFU_ERR_INTERNAL, dfu_cli_xfer.targets[0].status); @@ -1253,7 +1254,7 @@ static void test_cli_stop(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_verify_failed, K_SECONDS(200))) { + if (k_sem_take(&dfu_verify_failed, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } @@ -1269,12 +1270,12 @@ static void test_cli_stop(void) if (err) { FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(200))) { + if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware transfer failed"); } bt_mesh_dfu_cli_apply(&dfu_cli); - if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { /* This will time out as target will reboot before applying */ } ASSERT_EQUAL(BT_MESH_DFU_ERR_INTERNAL, dfu_cli_xfer.targets[0].status); @@ -1464,7 +1465,7 @@ static void test_target_fail_on_metadata(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_metadata_check_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_metadata_check_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Metadata check CB wasn't called"); } @@ -1478,7 +1479,7 @@ static void test_target_fail_on_caps_get(void) common_fail_on_target_init(&srv_caps_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&caps_get_sem, K_SECONDS(200))) { + if (k_sem_take(&caps_get_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("BLOB Info Get msg handler wasn't called"); } @@ -1492,11 +1493,11 @@ static void test_target_fail_on_update_get(void) common_fail_on_target_init(&srv_update_get_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&dfu_verify_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_verify_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Transfer end CB wasn't triggered"); } - if (k_sem_take(&update_get_sem, K_SECONDS(200))) { + if (k_sem_take(&update_get_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware Update Get msg handler wasn't called"); } @@ -1511,7 +1512,7 @@ static void test_target_fail_on_verify(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_verify_sem, K_SECONDS(200))) { + if (k_sem_take(&dfu_verify_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Transfer end CB wasn't triggered"); } @@ -1525,7 +1526,7 @@ static void test_target_fail_on_apply(void) common_fail_on_target_init(&srv_update_apply_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&update_apply_sem, K_SECONDS(200))) { + if (k_sem_take(&update_apply_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("Firmware Update Apply msg handler wasn't called"); } @@ -1537,7 +1538,7 @@ static void test_target_fail_on_nothing(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_ended, K_SECONDS(200))) { + if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { FAIL("DFU failed"); } diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 2f8d523bede..17244be15fe 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -549,7 +549,7 @@ static void node_configure(void) */ uint8_t net_transmit; - net_transmit = BT_MESH_TRANSMIT(3, 20); + net_transmit = BT_MESH_TRANSMIT(3, 50); err = bt_mesh_cfg_cli_net_transmit_set(test_netkey_idx, TEST_ADDR, net_transmit, &status); if (err || status != net_transmit) { FAIL("Net transmit set failed (err %d, transmit %x)", err, status); diff --git a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c index 5479387a4f4..68dc52a7b5d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c +++ b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c @@ -149,6 +149,8 @@ static void test_tx_immediate_replay_attack(void) } ASSERT_TRUE(is_tx_succeeded); + /* Let complete advertising of the previous transaction to prevent collisions. */ + k_sleep(K_SECONDS(1)); } bt_mesh.seq = seq; @@ -165,6 +167,8 @@ static void test_tx_immediate_replay_attack(void) } ASSERT_TRUE(!is_tx_succeeded); + /* Let complete advertising of the previous transaction to prevent collisions. */ + k_sleep(K_SECONDS(1)); } PASS(); @@ -208,6 +212,8 @@ static void test_tx_power_replay_attack(void) } ASSERT_TRUE(!is_tx_succeeded); + /* Let complete advertising of the previous transaction to prevent collisions. */ + k_sleep(K_SECONDS(1)); } for (int i = 0; i < 3; i++) { @@ -222,6 +228,8 @@ static void test_tx_power_replay_attack(void) } ASSERT_TRUE(is_tx_succeeded); + /* Let complete advertising of the previous transaction to prevent collisions. */ + k_sleep(K_SECONDS(1)); } PASS(); From 7a32e1d84b596ecb77173b5651dd053021e5e1c5 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 2 Nov 2023 10:50:15 +0100 Subject: [PATCH 3268/4498] samples: Bluetooth: Mesh: add main stack for mesh provisioner The current main stack size is not enough for any platform. This commit stack size was checked for nrf52840 and nrf5340. Everything works. Signed-off-by: Aleksandr Khromykh --- samples/bluetooth/mesh_provisioner/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/bluetooth/mesh_provisioner/prj.conf b/samples/bluetooth/mesh_provisioner/prj.conf index 3b40d2c2c7b..bfc6d5a1241 100644 --- a/samples/bluetooth/mesh_provisioner/prj.conf +++ b/samples/bluetooth/mesh_provisioner/prj.conf @@ -1,5 +1,5 @@ #CONFIG_INIT_STACKS=y -CONFIG_MAIN_STACK_SIZE=1408 +CONFIG_MAIN_STACK_SIZE=2048 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 # The Bluetooth API should not be used from a preemptive thread: CONFIG_MAIN_THREAD_PRIORITY=-2 From a0db07888f3509e98b3b0cf10d020b3be558c19a Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 27 Oct 2023 17:01:58 +0200 Subject: [PATCH 3269/4498] drivers: flash: stm32 ospi driver active wait during init Wait with k_busy_wait instead of k_sleep during the peripheral init. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_ospi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 7e06f8ee2be..eb84564ddea 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -827,7 +827,7 @@ static int stm32_ospi_config_mem(const struct device *dev) } /* Wait that the configuration is effective and check that memory is ready */ - k_msleep(STM32_OSPI_WRITE_REG_MAX_TIME); + k_busy_wait(STM32_OSPI_WRITE_REG_MAX_TIME * USEC_PER_MSEC); /* Reconfigure the memory type of the peripheral */ dev_data->hospi.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; @@ -949,8 +949,8 @@ static int stm32_ospi_mem_reset(const struct device *dev) } #endif - /* After SWreset CMD, wait in case SWReset occurred during erase operation */ - k_msleep(STM32_OSPI_RESET_MAX_TIME); + /* Wait after SWreset CMD, in case SWReset occurred during erase operation */ + k_busy_wait(STM32_OSPI_RESET_MAX_TIME * USEC_PER_MSEC); return 0; } From a2210bde638641666d8d9a9e56ba9f5add0223b8 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Tue, 7 Nov 2023 13:32:18 +0100 Subject: [PATCH 3270/4498] bluetooth: audio: delegator: Use BT_ATT_ERR_WRITE_REQ_REJECTED If the total length of the opcode and parameter values of Broadcast Receive State characteristic operation is incorrect, the server shall respond with an ATT Error Response and the Error Code set to Write Request Rejected (0xfc), instead of 0x0d (BT_ATT_ERR_INVALID_ATTRIBUTE_LEN). Signed-off-by: Magdalena Kasenberg --- subsys/bluetooth/audio/bap_scan_delegator.c | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index d0de2a4fb27..79865fc382a 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -459,7 +459,7 @@ static int scan_delegator_add_source(struct bt_conn *conn, /* subtract 1 as the opcode has already been pulled */ if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } internal_state = get_free_recv_state(); @@ -510,7 +510,7 @@ static int scan_delegator_add_source(struct bt_conn *conn, if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf); @@ -545,7 +545,7 @@ static int scan_delegator_add_source(struct bt_conn *conn, if (buf->len < subgroup->metadata_len) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } @@ -563,7 +563,7 @@ static int scan_delegator_add_source(struct bt_conn *conn, if (buf->len != 0) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC) { @@ -625,7 +625,7 @@ static int scan_delegator_mod_src(struct bt_conn *conn, if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) { LOG_DBG("Invalid length %u", buf->len); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } src_id = net_buf_simple_pull_u8(buf); @@ -664,7 +664,7 @@ static int scan_delegator_mod_src(struct bt_conn *conn, if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) { LOG_DBG("Invalid length %u", buf->len); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } old_bis_sync_req = internal_state->requested_bis_sync[i]; @@ -699,7 +699,7 @@ static int scan_delegator_mod_src(struct bt_conn *conn, if (buf->len < subgroup->metadata_len) { LOG_DBG("Invalid length %u", buf->len); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } if (subgroup->metadata_len > CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN) { @@ -717,7 +717,7 @@ static int scan_delegator_mod_src(struct bt_conn *conn, if (buf->len != 0) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } /* All input has been validated; update receive state and check for changes */ @@ -797,7 +797,7 @@ static int scan_delegator_broadcast_code(struct bt_conn *conn, /* subtract 1 as the opcode has already been pulled */ if (buf->len != sizeof(struct bt_bap_bass_cp_broadcase_code) - 1) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } src_id = net_buf_simple_pull_u8(buf); @@ -836,7 +836,7 @@ static int scan_delegator_rem_src(struct bt_conn *conn, /* subtract 1 as the opcode has already been pulled */ if (buf->len != sizeof(struct bt_bap_bass_cp_rem_src) - 1) { LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } src_id = net_buf_simple_pull_u8(buf); @@ -903,7 +903,7 @@ static ssize_t write_control_point(struct bt_conn *conn, if (offset != 0) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); } else if (len == 0) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } net_buf_simple_init_with_data(&buf, (void *)data, len); @@ -928,7 +928,7 @@ static ssize_t write_control_point(struct bt_conn *conn, if (buf.len != 0) { LOG_DBG("Invalid length %u", buf.size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } bap_broadcast_assistant->scanning = false; @@ -938,7 +938,7 @@ static ssize_t write_control_point(struct bt_conn *conn, if (buf.len != 0) { LOG_DBG("Invalid length %u", buf.size); - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } bap_broadcast_assistant->scanning = true; break; From bf8a055b4ba12e248e4d17c90428b552ea1217c8 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 7 Nov 2023 14:28:07 +0100 Subject: [PATCH 3271/4498] include: dt-bindings: stm32wba_clocks.h: Add RTC_SEL macro Add a dt macro to allow configuring RTC domain clock. Signed-off-by: Erwan Gouriou --- include/zephyr/dt-bindings/clock/stm32wba_clock.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/zephyr/dt-bindings/clock/stm32wba_clock.h b/include/zephyr/dt-bindings/clock/stm32wba_clock.h index 757cb8a0552..50ec4703e3f 100644 --- a/include/zephyr/dt-bindings/clock/stm32wba_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wba_clock.h @@ -72,6 +72,8 @@ #define CCIPR1_REG 0xE0 #define CCIPR2_REG 0xE4 #define CCIPR3_REG 0xE8 +/** @brief RCC_BCDR1 register offset (RM0493.pdf) */ +#define BCDR1_REG 0xF0 /** @brief Device clk sources selection helpers */ /** CCIPR1 devices */ @@ -90,5 +92,7 @@ #define I2C3_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR3_REG) #define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR3_REG) #define ADC_SEL(val) STM32_CLOCK(val, 7, 12, CCIPR3_REG) +/** BCDR1 devices */ +#define RTC_SEL(val) STM32_CLOCK(val, 3, 8, BCDR1_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WBA_CLOCK_H_ */ From 645de482f0d3bfba3a3af4e3ea50cb8e9f45a155 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 7 Nov 2023 14:55:40 +0100 Subject: [PATCH 3272/4498] drivers: counter: Add support for stm32wba devices Implement RTC support in counter driver for STM32WBA devices. Changes are made according to the following specificities: - Similarly to STM32U5, it is not connected to EXTI. - On this series, there is no bit in BCDR register to enable RTC. Enabling RTC is done directly via the RCC APB register bit Signed-off-by: Erwan Gouriou --- drivers/counter/counter_ll_stm32_rtc.c | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index bb8a119409b..76114cab386 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -184,11 +184,22 @@ static void rtc_stm32_irq_config(const struct device *dev); static int rtc_stm32_start(const struct device *dev) { +#if defined(CONFIG_SOC_SERIES_STM32WBAX) + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + const struct rtc_stm32_config *cfg = dev->config; + + /* Enable RTC bus clock */ + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) { + LOG_ERR("clock op failed\n"); + return -EIO; + } +#else ARG_UNUSED(dev); z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); LL_RCC_EnableRTC(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); +#endif return 0; } @@ -196,11 +207,22 @@ static int rtc_stm32_start(const struct device *dev) static int rtc_stm32_stop(const struct device *dev) { +#if defined(CONFIG_SOC_SERIES_STM32WBAX) + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + const struct rtc_stm32_config *cfg = dev->config; + + /* Enable RTC bus clock */ + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) { + LOG_ERR("clock op failed\n"); + return -EIO; + } +#else ARG_UNUSED(dev); z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); LL_RCC_DisableRTC(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); +#endif return 0; } @@ -504,7 +526,7 @@ void rtc_stm32_isr(const struct device *dev) || defined(CONFIG_SOC_SERIES_STM32L5X) \ || defined(CONFIG_SOC_SERIES_STM32H5X) LL_EXTI_ClearRisingFlag_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) +#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) /* in STM32U5 family RTC is not connected to EXTI */ #else LL_EXTI_ClearFlag_0_31(RTC_EXTI_LINE); @@ -546,7 +568,9 @@ static int rtc_stm32_init(const struct device *dev) return -EIO; } +#if !defined(CONFIG_SOC_SERIES_STM32WBAX) LL_RCC_EnableRTC(); +#endif z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); @@ -570,7 +594,7 @@ static int rtc_stm32_init(const struct device *dev) #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4) LL_C2_EXTI_EnableIT_0_31(RTC_EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) +#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) /* in STM32U5 family RTC is not connected to EXTI */ #else LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE); From 9e74efd159fbf7e5f664b2764ad7f8c81f5a765b Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 7 Nov 2023 14:56:23 +0100 Subject: [PATCH 3273/4498] dts: stm32wba: Add rtc node Add RTC node for stm32wba series. Signed-off-by: Erwan Gouriou --- dts/arm/st/wba/stm32wba.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index de7ec91d347..6c5cc8f869a 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -189,6 +189,14 @@ }; }; + rtc: rtc@46007800 { + compatible = "st,stm32-rtc"; + reg = <0x46007800 0x400>; + interrupts = <2 0>; + clocks = <&rcc STM32_CLOCK_BUS_APB7 0x00200000>; + status = "disabled"; + }; + iwdg: watchdog@40003000 { compatible = "st,stm32-watchdog"; reg = <0x40003000 0x400>; From ee75020c0a12f4dd94b5dea54fab8601b5637ed5 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 7 Nov 2023 14:58:23 +0100 Subject: [PATCH 3274/4498] boards: nucleo_wba52cg: Enable RTC node Set LSE as domain clock. Configure rtc prescaler accordingly. Signed-off-by: Erwan Gouriou --- boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts | 7 +++++++ boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml | 1 + 2 files changed, 8 insertions(+) diff --git a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts index 23b8f85e8cd..df2707f4eeb 100644 --- a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts +++ b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.dts @@ -82,6 +82,13 @@ status = "okay"; }; +&rtc { + status = "okay"; + clocks = <&rcc STM32_CLOCK_BUS_APB7 0x00200000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + prescaler = <32768>; +}; + &usart1 { pinctrl-0 = <&usart1_tx_pb12 &usart1_rx_pa8>; pinctrl-names = "default"; diff --git a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml index a5eb79afc42..8e075b44ae1 100644 --- a/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml +++ b/boards/arm/nucleo_wba52cg/nucleo_wba52cg.yaml @@ -15,6 +15,7 @@ supported: - arduino_gpio - arduino_i2c - arduino_spi + - counter ram: 128 flash: 1024 vendor: st From 614df97a4979d89311061d0e9912513bf28f9c20 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 7 Nov 2023 15:07:39 +0100 Subject: [PATCH 3275/4498] tests: counter_basic_api: Test subseconds on nucleo_wba52cg Enable STM32 RTC subsecond test on nucleo_wba52cg. Signed-off-by: Erwan Gouriou --- tests/drivers/counter/counter_basic_api/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/counter/counter_basic_api/testcase.yaml b/tests/drivers/counter/counter_basic_api/testcase.yaml index 6e68f4480f4..2173d417c06 100644 --- a/tests/drivers/counter/counter_basic_api/testcase.yaml +++ b/tests/drivers/counter/counter_basic_api/testcase.yaml @@ -23,7 +23,7 @@ tests: - drivers - counter depends_on: counter - platform_allow: nucleo_f429zi + platform_allow: nucleo_f429zi nucleo_wba52cg timeout: 600 extra_configs: - CONFIG_COUNTER_RTC_STM32_SUBSECONDS=y From d69d4013d3c39b2b1c14522863364cfe3eb73b6c Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 7 Nov 2023 16:23:34 +0200 Subject: [PATCH 3276/4498] net: lwm2m: Fix blockwise response code In CoAP blockwise the client is supposed to respond with 2.31 Continue code on Ack. This was recently broken when Block1 parsing was moved after the initialization of reponse packet. We need separate CoAP API to modify the code of existing CoAP packet. Also Ack packet should contain the Block1 options, even the last one. Signed-off-by: Seppo Takalo --- include/zephyr/net/coap.h | 9 ++++++ subsys/net/lib/coap/coap.c | 10 +++++++ subsys/net/lib/lwm2m/lwm2m_message_handling.c | 30 +++++++++++++------ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 325ced2ebbc..ebc72709751 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -373,6 +373,15 @@ uint8_t coap_header_get_token(const struct coap_packet *cpkt, uint8_t *token); */ uint8_t coap_header_get_code(const struct coap_packet *cpkt); +/** + * @brief Modifies the code of the CoAP packet. + * + * @param cpkt CoAP packet representation + * @param code CoAP code + * @return 0 on success, -EINVAL on failure + */ +int coap_header_set_code(const struct coap_packet *cpkt, uint8_t code); + /** * @brief Returns the message id associated with the CoAP packet. * diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 429d3fd3d4a..8ac8d73e78d 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -950,6 +950,16 @@ static uint8_t __coap_header_get_code(const struct coap_packet *cpkt) return cpkt->data[1]; } +int coap_header_set_code(const struct coap_packet *cpkt, uint8_t code) +{ + if (!cpkt || !cpkt->data) { + return -EINVAL; + } + + cpkt->data[1] = code; + return 0; +} + uint8_t coap_header_get_token(const struct coap_packet *cpkt, uint8_t *token) { uint8_t tkl; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index ed5f28aabdb..6d006b4603e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2065,6 +2065,13 @@ static int parse_write_op(struct lwm2m_message *msg, uint16_t format) if (block_num < block_ctx->expected) { LOG_WRN("Block already handled %d, expected %d", block_num, block_ctx->expected); + (void)coap_header_set_code(msg->out.out_cpkt, COAP_RESPONSE_CODE_CONTINUE); + /* Respond with the original Block1 header, original Ack migh have been + * lost, and this is a retry. We don't know the original response, but + * since it is handled, just assume we can continue. + */ + (void)coap_append_option_int(msg->out.out_cpkt, COAP_OPTION_BLOCK1, + block_opt); return 0; } if (block_num > block_ctx->expected) { @@ -2087,30 +2094,35 @@ static int parse_write_op(struct lwm2m_message *msg, uint16_t format) * number. */ block_ctx->expected += GET_BLOCK_SIZE(block_opt) - block_ctx->ctx.block_size + 1; - - /* Handle blockwise 1 (Part 1): Set response code */ - if (!last_block) { - msg->code = COAP_RESPONSE_CODE_CONTINUE; - } } r = do_write_op(msg, format); /* Handle blockwise 1 (Part 2): Append BLOCK1 option / free context */ if (block_ctx) { - if (r >= 0 && !last_block) { - /* More to come, ack with correspond block # */ + if (r >= 0) { + /* Add block1 option to response. + * As RFC7959 Section-2.3, More flag is off, because we have already + * written the data. + */ r = coap_append_block1_option(msg->out.out_cpkt, &block_ctx->ctx); if (r < 0) { /* report as internal server error */ - LOG_ERR("Fail adding block1 option: %d", r); + LOG_DBG("Fail adding block1 option: %d", r); r = -EINVAL; } + if (!last_block) { + r = coap_header_set_code(msg->out.out_cpkt, + COAP_RESPONSE_CODE_CONTINUE); + if (r < 0) { + LOG_DBG("Failed to modify response code"); + r = -EINVAL; + } + } } if (r < 0 || last_block) { /* Free context when finished or when there is error */ free_block_ctx(block_ctx); - } } From 58ba0e1e2683582d8f6b299c7a8729a437361f51 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Nov 2023 09:44:46 +0200 Subject: [PATCH 3277/4498] modules: acpica: Fix CMakeLists.txt style Fix indentation to use spaces (instead of tabs) and remove the unnecessary repetition of the condition inside endif(). Signed-off-by: Johan Hedberg --- modules/acpica/CMakeLists.txt | 342 +++++++++++++++++----------------- 1 file changed, 171 insertions(+), 171 deletions(-) diff --git a/modules/acpica/CMakeLists.txt b/modules/acpica/CMakeLists.txt index 2c77a6c1633..ad8a75b0230 100644 --- a/modules/acpica/CMakeLists.txt +++ b/modules/acpica/CMakeLists.txt @@ -1,179 +1,179 @@ # Copyright (c) 2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -if (CONFIG_ACPI) - set(ACPI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/) - set(INC_DIR ${ACPI_DIR}/source/include/) - set(SRC_DIR ${ACPI_DIR}/source) - set(COMP_DIR ${ACPI_DIR}/source/components) - set(PARENT_SRC_DIR ${ACPI_DIR}../../zephyr) - set(ACPI_PARENT_DIR ${ACPI_DIR}/../) +if(CONFIG_ACPI) + set(ACPI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/) + set(INC_DIR ${ACPI_DIR}/source/include/) + set(SRC_DIR ${ACPI_DIR}/source) + set(COMP_DIR ${ACPI_DIR}/source/components) + set(PARENT_SRC_DIR ${ACPI_DIR}../../zephyr) + set(ACPI_PARENT_DIR ${ACPI_DIR}/../) - zephyr_include_directories( - ${PARENT_SRC_DIR}/include/ - ${ACPI_PARENT_DIR}/ - ${INC_DIR}/ - ${INC_DIR}/platform/ - ${SRC_DIR}/compiler/ - ${ZEPHYR_CURRENT_MODULE_DIR}/generate/zephyr/ - ${SRC_DIR}/tools/acpiexec/ - ${SRC_DIR}/tools/acpidump/ - ) + zephyr_include_directories( + ${PARENT_SRC_DIR}/include/ + ${ACPI_PARENT_DIR}/ + ${INC_DIR}/ + ${INC_DIR}/platform/ + ${SRC_DIR}/compiler/ + ${ZEPHYR_CURRENT_MODULE_DIR}/generate/zephyr/ + ${SRC_DIR}/tools/acpiexec/ + ${SRC_DIR}/tools/acpidump/ + ) - zephyr_library() + zephyr_library() - add_compile_definitions(__ZEPHYR__) - add_compile_definitions(ACPI_DEBUG_OUTPUT) - add_compile_definitions(ACPI_EXAMPLE_APP) - add_compile_definitions(CONFIG_EXTERNAL_LIBC) + add_compile_definitions(__ZEPHYR__) + add_compile_definitions(ACPI_DEBUG_OUTPUT) + add_compile_definitions(ACPI_EXAMPLE_APP) + add_compile_definitions(CONFIG_EXTERNAL_LIBC) - get_filename_component(libname "${SRC_DIR}/common/" NAME) + get_filename_component(libname "${SRC_DIR}/common/" NAME) -if (CONFIG_ACPI_DSDT_SUPPORT) - zephyr_library_sources( - ${COMP_DIR}/dispatcher/dsargs.c - ${COMP_DIR}/dispatcher/dscontrol.c - ${COMP_DIR}/dispatcher/dsdebug.c - ${COMP_DIR}/dispatcher/dsfield.c - ${COMP_DIR}/dispatcher/dsinit.c - ${COMP_DIR}/dispatcher/dsmethod.c - ${COMP_DIR}/dispatcher/dsmthdat.c - ${COMP_DIR}/dispatcher/dsobject.c - ${COMP_DIR}/dispatcher/dsopcode.c - ${COMP_DIR}/dispatcher/dspkginit.c - ${COMP_DIR}/dispatcher/dsutils.c - ${COMP_DIR}/dispatcher/dswexec.c - ${COMP_DIR}/dispatcher/dswload.c - ${COMP_DIR}/dispatcher/dswload2.c - ${COMP_DIR}/dispatcher/dswscope.c - ${COMP_DIR}/dispatcher/dswstate.c - ${COMP_DIR}/events/evhandler.c - ${COMP_DIR}/events/evmisc.c - ${COMP_DIR}/events/evregion.c - ${COMP_DIR}/events/evrgnini.c - ${COMP_DIR}/events/evxface.c - ${COMP_DIR}/events/evxfregn.c - ${COMP_DIR}/executer/exconcat.c - ${COMP_DIR}/executer/exconfig.c - ${COMP_DIR}/executer/exconvrt.c - ${COMP_DIR}/executer/excreate.c - ${COMP_DIR}/executer/exdebug.c - ${COMP_DIR}/executer/exdump.c - ${COMP_DIR}/executer/exfield.c - ${COMP_DIR}/executer/exfldio.c - ${COMP_DIR}/executer/exmisc.c - ${COMP_DIR}/executer/exmutex.c - ${COMP_DIR}/executer/exnames.c - ${COMP_DIR}/executer/exoparg1.c - ${COMP_DIR}/executer/exoparg2.c - ${COMP_DIR}/executer/exoparg3.c - ${COMP_DIR}/executer/exoparg6.c - ${COMP_DIR}/executer/exprep.c - ${COMP_DIR}/executer/exregion.c - ${COMP_DIR}/executer/exresnte.c - ${COMP_DIR}/executer/exresolv.c - ${COMP_DIR}/executer/exresop.c - ${COMP_DIR}/executer/exserial.c - ${COMP_DIR}/executer/exstore.c - ${COMP_DIR}/executer/exstoren.c - ${COMP_DIR}/executer/exstorob.c - ${COMP_DIR}/executer/exsystem.c - ${COMP_DIR}/executer/extrace.c - ${COMP_DIR}/executer/exutils.c - ${COMP_DIR}/hardware/hwpci.c - ${COMP_DIR}/namespace/nsaccess.c - ${COMP_DIR}/namespace/nsalloc.c - ${COMP_DIR}/namespace/nsarguments.c - ${COMP_DIR}/namespace/nsconvert.c - ${COMP_DIR}/namespace/nsdump.c - ${COMP_DIR}/namespace/nseval.c - ${COMP_DIR}/namespace/nsinit.c - ${COMP_DIR}/namespace/nsload.c - ${COMP_DIR}/namespace/nsnames.c - ${COMP_DIR}/namespace/nsobject.c - ${COMP_DIR}/namespace/nsparse.c - ${COMP_DIR}/namespace/nspredef.c - ${COMP_DIR}/namespace/nsprepkg.c - ${COMP_DIR}/namespace/nsrepair.c - ${COMP_DIR}/namespace/nsrepair2.c - ${COMP_DIR}/namespace/nssearch.c - ${COMP_DIR}/namespace/nsutils.c - ${COMP_DIR}/namespace/nswalk.c - ${COMP_DIR}/namespace/nsxfeval.c - ${COMP_DIR}/namespace/nsxfname.c - ${COMP_DIR}/namespace/nsxfobj.c - ${COMP_DIR}/parser/psargs.c - ${COMP_DIR}/parser/psloop.c - ${COMP_DIR}/parser/psobject.c - ${COMP_DIR}/parser/psopcode.c - ${COMP_DIR}/parser/psopinfo.c - ${COMP_DIR}/parser/psparse.c - ${COMP_DIR}/parser/psscope.c - ${COMP_DIR}/parser/pstree.c - ${COMP_DIR}/parser/psutils.c - ${COMP_DIR}/parser/pswalk.c - ${COMP_DIR}/parser/psxface.c - ${COMP_DIR}/resources/rsxface.c - ${COMP_DIR}/resources/rsutils.c - ${COMP_DIR}/resources/rsaddr.c - ${COMP_DIR}/resources/rscalc.c - ${COMP_DIR}/resources/rscreate.c - ${COMP_DIR}/resources/rsdumpinfo.c - ${COMP_DIR}/resources/rsinfo.c - ${COMP_DIR}/resources/rsio.c - ${COMP_DIR}/resources/rsirq.c - ${COMP_DIR}/resources/rslist.c - ${COMP_DIR}/resources/rsmemory.c - ${COMP_DIR}/resources/rsmisc.c - ${COMP_DIR}/resources/rsserial.c - ) -endif (CONFIG_ACPI_DSDT_SUPPORT) - zephyr_library_sources( - ${COMP_DIR}/tables/tbdata.c - ${COMP_DIR}/tables/tbfadt.c - ${COMP_DIR}/tables/tbfind.c - ${COMP_DIR}/tables/tbinstal.c - ${COMP_DIR}/tables/tbprint.c - ${COMP_DIR}/tables/tbutils.c - ${COMP_DIR}/tables/tbxface.c - ${COMP_DIR}/tables/tbxfload.c - ${COMP_DIR}/tables/tbxfroot.c - ${COMP_DIR}/utilities/utaddress.c - ${COMP_DIR}/utilities/utalloc.c - ${COMP_DIR}/utilities/utascii.c - ${COMP_DIR}/utilities/utbuffer.c - ${COMP_DIR}/utilities/utcache.c - ${COMP_DIR}/utilities/utcksum.c - ${COMP_DIR}/utilities/utcopy.c - ${COMP_DIR}/utilities/utdebug.c - ${COMP_DIR}/utilities/utdecode.c - ${COMP_DIR}/utilities/utdelete.c - ${COMP_DIR}/utilities/uterror.c - ${COMP_DIR}/utilities/uteval.c - ${COMP_DIR}/utilities/utexcep.c - ${COMP_DIR}/utilities/utglobal.c - ${COMP_DIR}/utilities/uthex.c - ${COMP_DIR}/utilities/utids.c - ${COMP_DIR}/utilities/utinit.c - ${COMP_DIR}/utilities/utlock.c - ${COMP_DIR}/utilities/utmath.c - ${COMP_DIR}/utilities/utmisc.c - ${COMP_DIR}/utilities/utmutex.c - ${COMP_DIR}/utilities/utobject.c - ${COMP_DIR}/utilities/utosi.c - ${COMP_DIR}/utilities/utownerid.c - ${COMP_DIR}/utilities/utnonansi.c - ${COMP_DIR}/utilities/utpredef.c - ${COMP_DIR}/utilities/utresrc.c - ${COMP_DIR}/utilities/utstate.c - ${COMP_DIR}/utilities/utstring.c - ${COMP_DIR}/utilities/utstrsuppt.c - ${COMP_DIR}/utilities/utstrtoul64.c - ${COMP_DIR}/utilities/utxface.c - ${COMP_DIR}/utilities/utxferror.c - ${COMP_DIR}/utilities/utxfinit.c - ${COMP_DIR}/utilities/utresdecode.c - ${COMP_DIR}/hardware/hwvalid.c - ${SRC_DIR}/os_specific/service_layers/oszephyr.c - ) -endif (CONFIG_ACPI) + if(CONFIG_ACPI_DSDT_SUPPORT) + zephyr_library_sources( + ${COMP_DIR}/dispatcher/dsargs.c + ${COMP_DIR}/dispatcher/dscontrol.c + ${COMP_DIR}/dispatcher/dsdebug.c + ${COMP_DIR}/dispatcher/dsfield.c + ${COMP_DIR}/dispatcher/dsinit.c + ${COMP_DIR}/dispatcher/dsmethod.c + ${COMP_DIR}/dispatcher/dsmthdat.c + ${COMP_DIR}/dispatcher/dsobject.c + ${COMP_DIR}/dispatcher/dsopcode.c + ${COMP_DIR}/dispatcher/dspkginit.c + ${COMP_DIR}/dispatcher/dsutils.c + ${COMP_DIR}/dispatcher/dswexec.c + ${COMP_DIR}/dispatcher/dswload.c + ${COMP_DIR}/dispatcher/dswload2.c + ${COMP_DIR}/dispatcher/dswscope.c + ${COMP_DIR}/dispatcher/dswstate.c + ${COMP_DIR}/events/evhandler.c + ${COMP_DIR}/events/evmisc.c + ${COMP_DIR}/events/evregion.c + ${COMP_DIR}/events/evrgnini.c + ${COMP_DIR}/events/evxface.c + ${COMP_DIR}/events/evxfregn.c + ${COMP_DIR}/executer/exconcat.c + ${COMP_DIR}/executer/exconfig.c + ${COMP_DIR}/executer/exconvrt.c + ${COMP_DIR}/executer/excreate.c + ${COMP_DIR}/executer/exdebug.c + ${COMP_DIR}/executer/exdump.c + ${COMP_DIR}/executer/exfield.c + ${COMP_DIR}/executer/exfldio.c + ${COMP_DIR}/executer/exmisc.c + ${COMP_DIR}/executer/exmutex.c + ${COMP_DIR}/executer/exnames.c + ${COMP_DIR}/executer/exoparg1.c + ${COMP_DIR}/executer/exoparg2.c + ${COMP_DIR}/executer/exoparg3.c + ${COMP_DIR}/executer/exoparg6.c + ${COMP_DIR}/executer/exprep.c + ${COMP_DIR}/executer/exregion.c + ${COMP_DIR}/executer/exresnte.c + ${COMP_DIR}/executer/exresolv.c + ${COMP_DIR}/executer/exresop.c + ${COMP_DIR}/executer/exserial.c + ${COMP_DIR}/executer/exstore.c + ${COMP_DIR}/executer/exstoren.c + ${COMP_DIR}/executer/exstorob.c + ${COMP_DIR}/executer/exsystem.c + ${COMP_DIR}/executer/extrace.c + ${COMP_DIR}/executer/exutils.c + ${COMP_DIR}/hardware/hwpci.c + ${COMP_DIR}/namespace/nsaccess.c + ${COMP_DIR}/namespace/nsalloc.c + ${COMP_DIR}/namespace/nsarguments.c + ${COMP_DIR}/namespace/nsconvert.c + ${COMP_DIR}/namespace/nsdump.c + ${COMP_DIR}/namespace/nseval.c + ${COMP_DIR}/namespace/nsinit.c + ${COMP_DIR}/namespace/nsload.c + ${COMP_DIR}/namespace/nsnames.c + ${COMP_DIR}/namespace/nsobject.c + ${COMP_DIR}/namespace/nsparse.c + ${COMP_DIR}/namespace/nspredef.c + ${COMP_DIR}/namespace/nsprepkg.c + ${COMP_DIR}/namespace/nsrepair.c + ${COMP_DIR}/namespace/nsrepair2.c + ${COMP_DIR}/namespace/nssearch.c + ${COMP_DIR}/namespace/nsutils.c + ${COMP_DIR}/namespace/nswalk.c + ${COMP_DIR}/namespace/nsxfeval.c + ${COMP_DIR}/namespace/nsxfname.c + ${COMP_DIR}/namespace/nsxfobj.c + ${COMP_DIR}/parser/psargs.c + ${COMP_DIR}/parser/psloop.c + ${COMP_DIR}/parser/psobject.c + ${COMP_DIR}/parser/psopcode.c + ${COMP_DIR}/parser/psopinfo.c + ${COMP_DIR}/parser/psparse.c + ${COMP_DIR}/parser/psscope.c + ${COMP_DIR}/parser/pstree.c + ${COMP_DIR}/parser/psutils.c + ${COMP_DIR}/parser/pswalk.c + ${COMP_DIR}/parser/psxface.c + ${COMP_DIR}/resources/rsxface.c + ${COMP_DIR}/resources/rsutils.c + ${COMP_DIR}/resources/rsaddr.c + ${COMP_DIR}/resources/rscalc.c + ${COMP_DIR}/resources/rscreate.c + ${COMP_DIR}/resources/rsdumpinfo.c + ${COMP_DIR}/resources/rsinfo.c + ${COMP_DIR}/resources/rsio.c + ${COMP_DIR}/resources/rsirq.c + ${COMP_DIR}/resources/rslist.c + ${COMP_DIR}/resources/rsmemory.c + ${COMP_DIR}/resources/rsmisc.c + ${COMP_DIR}/resources/rsserial.c + ) + endif() + zephyr_library_sources( + ${COMP_DIR}/tables/tbdata.c + ${COMP_DIR}/tables/tbfadt.c + ${COMP_DIR}/tables/tbfind.c + ${COMP_DIR}/tables/tbinstal.c + ${COMP_DIR}/tables/tbprint.c + ${COMP_DIR}/tables/tbutils.c + ${COMP_DIR}/tables/tbxface.c + ${COMP_DIR}/tables/tbxfload.c + ${COMP_DIR}/tables/tbxfroot.c + ${COMP_DIR}/utilities/utaddress.c + ${COMP_DIR}/utilities/utalloc.c + ${COMP_DIR}/utilities/utascii.c + ${COMP_DIR}/utilities/utbuffer.c + ${COMP_DIR}/utilities/utcache.c + ${COMP_DIR}/utilities/utcksum.c + ${COMP_DIR}/utilities/utcopy.c + ${COMP_DIR}/utilities/utdebug.c + ${COMP_DIR}/utilities/utdecode.c + ${COMP_DIR}/utilities/utdelete.c + ${COMP_DIR}/utilities/uterror.c + ${COMP_DIR}/utilities/uteval.c + ${COMP_DIR}/utilities/utexcep.c + ${COMP_DIR}/utilities/utglobal.c + ${COMP_DIR}/utilities/uthex.c + ${COMP_DIR}/utilities/utids.c + ${COMP_DIR}/utilities/utinit.c + ${COMP_DIR}/utilities/utlock.c + ${COMP_DIR}/utilities/utmath.c + ${COMP_DIR}/utilities/utmisc.c + ${COMP_DIR}/utilities/utmutex.c + ${COMP_DIR}/utilities/utobject.c + ${COMP_DIR}/utilities/utosi.c + ${COMP_DIR}/utilities/utownerid.c + ${COMP_DIR}/utilities/utnonansi.c + ${COMP_DIR}/utilities/utpredef.c + ${COMP_DIR}/utilities/utresrc.c + ${COMP_DIR}/utilities/utstate.c + ${COMP_DIR}/utilities/utstring.c + ${COMP_DIR}/utilities/utstrsuppt.c + ${COMP_DIR}/utilities/utstrtoul64.c + ${COMP_DIR}/utilities/utxface.c + ${COMP_DIR}/utilities/utxferror.c + ${COMP_DIR}/utilities/utxfinit.c + ${COMP_DIR}/utilities/utresdecode.c + ${COMP_DIR}/hardware/hwvalid.c + ${SRC_DIR}/os_specific/service_layers/oszephyr.c + ) +endif() From d06c93f24c3a96d2b582013b4cbde8f4b7230e12 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 25 Jul 2023 15:33:12 +0200 Subject: [PATCH 3278/4498] drivers: clock_control: stm32wba: Apply VOS range 2 when sysclock = 16MHz When sysclock is 16MHz, we're allowed to used VOS range 2. Signed-off-by: Erwan Gouriou --- drivers/clock_control/clock_stm32_ll_wba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_stm32_ll_wba.c b/drivers/clock_control/clock_stm32_ll_wba.c index 46b834c52e9..8b9da70017a 100644 --- a/drivers/clock_control/clock_stm32_ll_wba.c +++ b/drivers/clock_control/clock_stm32_ll_wba.c @@ -287,7 +287,7 @@ static int get_vco_input_range(uint32_t m_div, uint32_t *range) static void set_regu_voltage(uint32_t hclk_freq) { - if (hclk_freq < MHZ(16)) { + if (hclk_freq <= MHZ(16)) { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2); } else { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); From 26002b0607081182cd6183b690dc0f24f1ef7b29 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 8 Nov 2023 14:05:19 +0100 Subject: [PATCH 3279/4498] Bluetooth: fix doxygen warnings Fix doxygen warnings ("warning: found tag without matching ") from building the Bluetooth API documention. Signed-off-by: Henrik Brix Andersen --- .../zephyr/bluetooth/audio/bap_lc3_preset.h | 128 +++++++++--------- include/zephyr/bluetooth/audio/lc3.h | 48 +++---- include/zephyr/bluetooth/gatt.h | 34 ++--- 3 files changed, 105 insertions(+), 105 deletions(-) diff --git a/include/zephyr/bluetooth/audio/bap_lc3_preset.h b/include/zephyr/bluetooth/audio/bap_lc3_preset.h index c8b82054e01..952451d4b16 100644 --- a/include/zephyr/bluetooth/audio/bap_lc3_preset.h +++ b/include/zephyr/bluetooth/audio/bap_lc3_preset.h @@ -31,7 +31,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 8_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_8_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_8_1(_loc, _stream_context), \ @@ -41,7 +41,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 8_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_8_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_8_2(_loc, _stream_context), \ @@ -51,7 +51,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 16_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_16_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_1(_loc, _stream_context), \ @@ -63,7 +63,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as both unicast client and server * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_16_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_2(_loc, _stream_context), \ @@ -73,7 +73,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 24_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_24_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_1(_loc, _stream_context), \ @@ -85,7 +85,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as unicast server * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_24_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_2(_loc, _stream_context), \ @@ -95,7 +95,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 32_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_32_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \ @@ -105,7 +105,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 32_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_32_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \ @@ -115,7 +115,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 441_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_441_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_1(_loc, _stream_context), \ @@ -126,7 +126,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 441_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_441_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_2(_loc, _stream_context), \ @@ -137,7 +137,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \ @@ -147,7 +147,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \ @@ -157,7 +157,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_3_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_3_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \ @@ -167,7 +167,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_4_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_4_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \ @@ -177,7 +177,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 8_5_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_5_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_5(_loc, _stream_context), \ @@ -187,7 +187,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_6_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_6_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_6(_loc, _stream_context), \ @@ -197,7 +197,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 8_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ /* Following presets are for unicast high reliability audio data */ #define BT_BAP_LC3_UNICAST_PRESET_8_1_2(_loc, _stream_context) \ @@ -208,7 +208,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 8_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_8_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_8_2(_loc, _stream_context), \ @@ -218,7 +218,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 16_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_16_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_1(_loc, _stream_context), \ @@ -228,7 +228,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 16_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_16_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_2(_loc, _stream_context), \ @@ -238,7 +238,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 24_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_24_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_1(_loc, _stream_context), \ @@ -248,7 +248,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 24_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_24_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_2(_loc, _stream_context), \ @@ -258,7 +258,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 32_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_32_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \ @@ -268,7 +268,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 32_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_32_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \ @@ -278,7 +278,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 441_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_441_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_1(_loc, _stream_context), \ @@ -289,7 +289,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 441_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_441_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_2(_loc, _stream_context), \ @@ -300,7 +300,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \ @@ -310,7 +310,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \ @@ -320,7 +320,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_3_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_3_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \ @@ -330,7 +330,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_4_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_4_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \ @@ -340,7 +340,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_5_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_5_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_5(_loc, _stream_context), \ @@ -350,7 +350,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Unicast 48_6_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_UNICAST_PRESET_48_6_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_6(_loc, _stream_context), \ @@ -360,7 +360,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 8_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ /* LC3 Broadcast presets defined by table 6.4 in the BAP v1.0 specification */ #define BT_BAP_LC3_BROADCAST_PRESET_8_1_1(_loc, _stream_context) \ @@ -371,7 +371,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 8_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_8_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_8_2(_loc, _stream_context), \ @@ -381,7 +381,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 16_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_16_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_1(_loc, _stream_context), \ @@ -393,7 +393,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as both broadcast source and sink * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_16_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_2(_loc, _stream_context), \ @@ -403,7 +403,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 24_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_24_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_1(_loc, _stream_context), \ @@ -415,7 +415,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as broadcast sink * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_24_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_2(_loc, _stream_context), \ @@ -425,7 +425,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 32_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_32_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \ @@ -435,7 +435,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 32_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_32_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \ @@ -445,7 +445,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 441_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_441_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_1(_loc, _stream_context), \ @@ -456,7 +456,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 441_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_441_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_2(_loc, _stream_context), \ @@ -467,7 +467,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_1_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_1_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \ @@ -477,7 +477,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_2_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_2_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \ @@ -487,7 +487,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_3_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_3_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \ @@ -497,7 +497,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_4_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_4_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \ @@ -507,7 +507,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_5_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_5_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_5(_loc, _stream_context), \ @@ -517,7 +517,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_6_1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_6_1(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_6(_loc, _stream_context), \ @@ -527,7 +527,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 8_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ /* Following presets are for broadcast high reliability audio data */ #define BT_BAP_LC3_BROADCAST_PRESET_8_1_2(_loc, _stream_context) \ @@ -538,7 +538,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 8_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_8_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_8_2(_loc, _stream_context), \ @@ -548,7 +548,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 16_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_16_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_1(_loc, _stream_context), \ @@ -560,7 +560,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as both broadcast source and sink * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_16_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_16_2(_loc, _stream_context), \ @@ -570,7 +570,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 24_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_24_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_1(_loc, _stream_context), \ @@ -582,7 +582,7 @@ struct bt_bap_lc3_preset { * Mandatory to support as broadcast sink * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_24_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_24_2(_loc, _stream_context), \ @@ -592,7 +592,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 32_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_32_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \ @@ -602,7 +602,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 32_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_32_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \ @@ -612,7 +612,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 441_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_441_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_1(_loc, _stream_context), \ @@ -623,7 +623,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 441_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_441_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_441_2(_loc, _stream_context), \ @@ -634,7 +634,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_1_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_1_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \ @@ -644,7 +644,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_2_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_2_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \ @@ -654,7 +654,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_3_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_3_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \ @@ -664,7 +664,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_4_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_4_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \ @@ -674,7 +674,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_5_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_5_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_5(_loc, _stream_context), \ @@ -684,7 +684,7 @@ struct bt_bap_lc3_preset { * @brief Helper to declare LC3 Broadcast 48_6_2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_BAP_LC3_BROADCAST_PRESET_48_6_2(_loc, _stream_context) \ BT_BAP_LC3_PRESET(BT_AUDIO_CODEC_LC3_CONFIG_48_6(_loc, _stream_context), \ diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 5ca0f276849..80fec536f89 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -257,7 +257,7 @@ enum bt_audio_codec_config_frame_dur { /** * @brief Helper to declare LC3 codec capability * - * _max_frames_per_sdu value is optional and will be included only if != 1 + * ``_max_frames_per_sdu`` value is optional and will be included only if != 1 */ /* COND_CODE_1 is used to omit an LTV entry in case the _frames_per_sdu is 1. * COND_CODE_1 will evaluate to second argument if the flag parameter(first argument) is 1 @@ -292,8 +292,8 @@ enum bt_audio_codec_config_frame_dur { /** * @brief Helper to declare LC3 codec * - * @param _freq Supported Sampling Frequencies bitfield (see BT_AUDIO_CODEC_LC3_FREQ_*) - * @param _duration Supported Frame Durations bitfield (see BT_AUDIO_CODEC_LC3_DURATION_*) + * @param _freq Supported Sampling Frequencies bitfield (see ``BT_AUDIO_CODEC_LC3_FREQ_*``) + * @param _duration Supported Frame Durations bitfield (see ``BT_AUDIO_CODEC_LC3_DURATION_*``) * @param _chan_count Supported channels (see @ref BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT) * @param _len_min Minimum number of octets supported per codec frame * @param _len_max Maximum number of octets supported per codec frame @@ -311,8 +311,8 @@ enum bt_audio_codec_config_frame_dur { /** * @brief Helper to declare LC3 codec data configuration * - * @param _freq Sampling frequency (BT_AUDIO_CODEC_CONFIG_LC3_FREQ_*) - * @param _duration Frame duration (BT_AUDIO_CODEC_CONFIG_LC3_DURATION_*) + * @param _freq Sampling frequency (``BT_AUDIO_CODEC_CONFIG_LC3_FREQ_*``) + * @param _duration Frame duration (``BT_AUDIO_CODEC_CONFIG_LC3_DURATION_*``) * @param _loc Audio channel location bitfield (@ref bt_audio_location) * @param _len Octets per frame (16-bit integer) * @param _frames_per_sdu Frames per SDU (8-bit integer). This value is optional and will be @@ -343,12 +343,12 @@ enum bt_audio_codec_config_frame_dur { /** * @brief Helper to declare LC3 codec configuration. * - * @param _freq Sampling frequency (BT_AUDIO_CODEC_CONFIG_LC3_FREQ_*) - * @param _duration Frame duration (BT_AUDIO_CODEC_CONFIG_LC3_DURATION_*) + * @param _freq Sampling frequency (``BT_AUDIO_CODEC_CONFIG_LC3_FREQ_*``) + * @param _duration Frame duration (``BT_AUDIO_CODEC_CONFIG_LC3_DURATION_*``) * @param _loc Audio channel location bitfield (@ref bt_audio_location) * @param _len Octets per frame (16-bit integer) * @param _frames_per_sdu Frames per SDU (8-bit integer) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG(_freq, _duration, _loc, _len, _frames_per_sdu, _stream_context) \ BT_AUDIO_CODEC_CFG( \ @@ -360,7 +360,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 8.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_8_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ, \ @@ -370,7 +370,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 8.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_8_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ, \ @@ -380,7 +380,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 16.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_16_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ, \ @@ -390,7 +390,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 16.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_16_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ, \ @@ -401,7 +401,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 24.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_24_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ, \ @@ -411,7 +411,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 24.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_24_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ, \ @@ -421,7 +421,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 32.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_32_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ, \ @@ -431,7 +431,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 32.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_32_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ, \ @@ -441,7 +441,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 441.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_441_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ, \ @@ -451,7 +451,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 441.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_441_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ, \ @@ -461,7 +461,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.1 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_1(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ @@ -471,7 +471,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.2 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_2(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ @@ -481,7 +481,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.3 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_3(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ @@ -491,7 +491,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.4 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_4(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ @@ -501,7 +501,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.5 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_5(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ @@ -511,7 +511,7 @@ enum bt_audio_codec_config_frame_dur { * @brief Helper to declare LC3 48.6 codec configuration * * @param _loc Audio channel location bitfield (@ref bt_audio_location) - * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) + * @param _stream_context Stream context (``BT_AUDIO_CONTEXT_*``) */ #define BT_AUDIO_CODEC_LC3_CONFIG_48_6(_loc, _stream_context) \ BT_AUDIO_CODEC_LC3_CONFIG(BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ, \ diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 6b31e5dc92b..c50bfb25c3d 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -72,7 +72,7 @@ enum bt_gatt_perm { /** @brief Attribute prepare write permission. * - * If set, allows prepare writes with use of BT_GATT_WRITE_FLAG_PREPARE + * If set, allows prepare writes with use of ``BT_GATT_WRITE_FLAG_PREPARE`` * passed to write callback. */ BT_GATT_PERM_PREPARE_WRITE = BIT(6), @@ -140,7 +140,7 @@ struct bt_gatt_attr; * @param offset Offset to start reading from * * @return Number of bytes read, or in case of an error - * BT_GATT_ERR() with a specific BT_ATT_ERR_* error code. + * ``BT_GATT_ERR()`` with a specific ``BT_ATT_ERR_*`` error code. */ typedef ssize_t (*bt_gatt_attr_read_func_t)(struct bt_conn *conn, const struct bt_gatt_attr *attr, @@ -155,10 +155,10 @@ typedef ssize_t (*bt_gatt_attr_read_func_t)(struct bt_conn *conn, * @param buf Buffer with the data to write * @param len Number of bytes in the buffer * @param offset Offset to start writing from - * @param flags Flags (BT_GATT_WRITE_FLAG_*) + * @param flags Flags (``BT_GATT_WRITE_FLAG_*``) * * @return Number of bytes written, or in case of an error - * BT_GATT_ERR() with a specific BT_ATT_ERR_* error code. + * ``BT_GATT_ERR()`` with a specific ``BT_ATT_ERR_*`` error code. */ typedef ssize_t (*bt_gatt_attr_write_func_t)(struct bt_conn *conn, const struct bt_gatt_attr *attr, @@ -178,7 +178,7 @@ struct bt_gatt_attr { uint16_t handle; /** @brief Attribute permissions. * - * Will be 0 if returned from bt_gatt_discover(). + * Will be 0 if returned from ``bt_gatt_discover()``. */ uint16_t perm; }; @@ -379,8 +379,8 @@ void bt_gatt_cb_register(struct bt_gatt_cb *cb); /** @brief Register GATT service. * * Register GATT service. Applications can make use of - * macros such as BT_GATT_PRIMARY_SERVICE, BT_GATT_CHARACTERISTIC, - * BT_GATT_DESCRIPTOR, etc. + * macros such as ``BT_GATT_PRIMARY_SERVICE``, ``BT_GATT_CHARACTERISTIC``, + * ``BT_GATT_DESCRIPTOR``, etc. * * When using @kconfig{CONFIG_BT_SETTINGS} then all services that should have * bond configuration loaded, i.e. CCC values, must be registered before @@ -400,7 +400,7 @@ void bt_gatt_cb_register(struct bt_gatt_cb *cb); * @param svc Service containing the available attributes * * @return 0 in case of success or negative value in case of error. - * @return -EAGAIN if `bt_init()` has been called but `settings_load()` hasn't yet. + * @return -EAGAIN if ``bt_init()`` has been called but ``settings_load()`` hasn't yet. */ int bt_gatt_service_register(struct bt_gatt_service *svc); @@ -432,8 +432,8 @@ enum { * @param handle Attribute handle found. * @param user_data Data given. * - * @return BT_GATT_ITER_CONTINUE if should continue to the next attribute. - * @return BT_GATT_ITER_STOP to stop. + * @return ``BT_GATT_ITER_CONTINUE`` if should continue to the next attribute. + * @return ``BT_GATT_ITER_STOP`` to stop. */ typedef uint8_t (*bt_gatt_attr_func_t)(const struct bt_gatt_attr *attr, uint16_t handle, @@ -488,7 +488,7 @@ struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr); * * Find the attribute with the matching UUID. * To limit the search to a service set the attr to the service attributes and - * the attr_count to the service attribute count . + * the ``attr_count`` to the service attribute count . * * @param attr Pointer to an attribute that serves as the starting point * for the search of a match for the UUID. @@ -515,7 +515,7 @@ uint16_t bt_gatt_attr_get_handle(const struct bt_gatt_attr *attr); * * @param attr A Characteristic Attribute. * - * @note The user_data of the attribute must of type @ref bt_gatt_chrc. + * @note The ``user_data`` of the attribute must of type @ref bt_gatt_chrc. * * @return the handle of the corresponding Characteristic Value. The value will * be zero (the invalid handle) if @p attr was not a characteristic @@ -546,7 +546,7 @@ ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, * * Read service attribute value from local database storing the result into * buffer after encoding it. - * @note Only use this with attributes which user_data is a bt_uuid. + * @note Only use this with attributes which ``user_data`` is a ``bt_uuid``. * * @param conn Connection object. * @param attr Attribute to read. @@ -583,7 +583,7 @@ ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, * * Helper macro to statically define service structure array. Each element * of the array is linked to the service attribute array which is also - * defined in this scope using _attrs_def macro. + * defined in this scope using ``_attrs_def`` macro. * * @param _name Name of service structure array. * @param _instances Array of instances to pass as user context to the @@ -645,7 +645,7 @@ ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, * * Read include service attribute value from local database storing the result * into buffer after encoding it. - * @note Only use this with attributes which user_data is a bt_gatt_include. + * @note Only use this with attributes which user_data is a ``bt_gatt_include``. * * @param conn Connection object. * @param attr Attribute to read. @@ -675,7 +675,7 @@ ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, * * Read characteristic attribute value from local database storing the result * into buffer after encoding it. - * @note Only use this with attributes which user_data is a bt_gatt_chrc. + * @note Only use this with attributes which ``user_data`` is a ``bt_gatt_chrc``. * * @param conn Connection object. * @param attr Attribute to read. @@ -705,7 +705,7 @@ ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn, * * @param _uuid Characteristic attribute uuid. * @param _props Characteristic attribute properties, - * a bitmap of BT_GATT_CHRC_* macros. + * a bitmap of ``BT_GATT_CHRC_*`` macros. * @param _perm Characteristic Attribute access permissions, * a bitmap of @ref bt_gatt_perm values. * @param _read Characteristic Attribute read callback From ec202d852f8dffb3787349088c93266505d83f8b Mon Sep 17 00:00:00 2001 From: Tobias Pisani Date: Fri, 27 Oct 2023 11:09:39 +0200 Subject: [PATCH 3280/4498] drivers: sensor: bq274xx: Configure or confirm chemistry profile Both the BQ27421 and BQ27427 have a few preset Chemistry profiles. For the BQ27421 there exists three variants of the IC, and for the BQ27427, it can be configured. The chemistry profile among other things includes the taper voltage, which is used to detect charge termination. This adds an optional `chemistry-id` config option to the driver. On the BQ27421, it will confirm that the correct variant of the IC is mounted, and on the BQ27427, it will configure it with the correct value. Side note: The reference manual for the BQ27427 (https://www.ti.com/lit/ug/sluucd5/sluucd5.pdf) currently contains some errors and inconsistencies regarding these registers. The table on page 7 appears to be correct. Signed-off-by: Tobias Pisani --- drivers/sensor/bq274xx/bq274xx.c | 69 +++++++++++++++++++++ drivers/sensor/bq274xx/bq274xx.h | 7 +++ dts/bindings/sensor/ti,bq274xx.yaml | 6 ++ include/zephyr/dt-bindings/sensor/bq274xx.h | 27 ++++++++ 4 files changed, 109 insertions(+) create mode 100644 include/zephyr/dt-bindings/sensor/bq274xx.h diff --git a/drivers/sensor/bq274xx/bq274xx.c b/drivers/sensor/bq274xx/bq274xx.c index 0cf52c79f17..27810204798 100644 --- a/drivers/sensor/bq274xx/bq274xx.c +++ b/drivers/sensor/bq274xx/bq274xx.c @@ -321,6 +321,69 @@ static int bq27427_ccgain_quirk(const struct device *dev) return 0; } +static int bq274xx_ensure_chemistry(const struct device *dev) +{ + struct bq274xx_data *data = dev->data; + const struct bq274xx_config *const config = dev->config; + uint16_t chem_id = config->chemistry_id; + + if (chem_id == 0) { + /* No chemistry ID set, rely on the default of the device.*/ + return 0; + } + int ret; + uint16_t val; + + ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_CHEM_ID); + if (ret < 0) { + LOG_ERR("Unable to write control register"); + return -EIO; + } + + ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_CONTROL, &val); + if (ret < 0) { + LOG_ERR("Unable to read register"); + return -EIO; + } + + LOG_DBG("Chem ID: %04x", val); + + if (val != chem_id) { + /* Only the bq27427 has a configurable Chemistry ID. On bq27421, it depends on the + * variant of the chip, so just error out if the chemistry ID is wrong. + */ + if (data->regs != &bq27427_regs) { + LOG_ERR("Unable to confirm chemistry ID 0x%04x. Device reported 0x%04x", + chem_id, val); + return -EIO; + } + + uint16_t cmd; + + switch (val) { + case BQ27427_CHEM_ID_A: + cmd = BQ27427_CTRL_CHEM_A; + break; + case BQ27427_CHEM_ID_B: + cmd = BQ27427_CTRL_CHEM_B; + break; + case BQ27427_CHEM_ID_C: + cmd = BQ27427_CTRL_CHEM_C; + break; + default: + LOG_ERR("Unsupported chemistry ID 0x%04x", val); + return -EINVAL; + } + + ret = bq274xx_ctrl_reg_write(dev, cmd); + if (ret < 0) { + LOG_ERR("Unable to configure chemistry"); + return -EIO; + } + } + return 0; +} + static int bq274xx_gauge_configure(const struct device *dev) { const struct bq274xx_config *const config = dev->config; @@ -390,6 +453,11 @@ static int bq274xx_gauge_configure(const struct device *dev) } } + ret = bq274xx_ensure_chemistry(dev); + if (ret < 0) { + return ret; + } + ret = bq274xx_mode_cfgupdate(dev, false); if (ret < 0) { return ret; @@ -798,6 +866,7 @@ static const struct sensor_driver_api bq274xx_battery_driver_api = { .design_capacity = DT_INST_PROP(index, design_capacity), \ .taper_current = DT_INST_PROP(index, taper_current), \ .terminate_voltage = DT_INST_PROP(index, terminate_voltage), \ + .chemistry_id = DT_INST_PROP_OR(index, chemistry_id, 0), \ .lazy_loading = DT_INST_PROP(index, zephyr_lazy_load), \ }; \ \ diff --git a/drivers/sensor/bq274xx/bq274xx.h b/drivers/sensor/bq274xx/bq274xx.h index ead248a4738..3fbf4f52f08 100644 --- a/drivers/sensor/bq274xx/bq274xx.h +++ b/drivers/sensor/bq274xx/bq274xx.h @@ -9,6 +9,7 @@ #include #include +#include /*** General Constant ***/ #define BQ274XX_UNSEAL_KEY_A 0x8000 /* Unseal code one on BQ27441-G1A and similar */ @@ -59,6 +60,11 @@ #define BQ274XX_CTRL_EXIT_CFGUPDATE 0x0043 #define BQ274XX_CTRL_EXIT_RESIM 0x0044 +/* BQ27427 */ +#define BQ27427_CTRL_CHEM_A 0x0030 +#define BQ27427_CTRL_CHEM_B 0x0031 +#define BQ27427_CTRL_CHEM_C 0x0032 + /*** Extended Data Commands ***/ #define BQ274XX_EXT_OPCONFIG 0x3A /* OpConfig() */ #define BQ274XX_EXT_CAPACITY 0x3C /* DesignCapacity() */ @@ -119,6 +125,7 @@ struct bq274xx_config { #if defined(CONFIG_BQ274XX_PM) || defined(CONFIG_BQ274XX_TRIGGER) struct gpio_dt_spec int_gpios; #endif + uint16_t chemistry_id; bool lazy_loading; }; diff --git a/dts/bindings/sensor/ti,bq274xx.yaml b/dts/bindings/sensor/ti,bq274xx.yaml index 16032b625cf..f50aba228c1 100644 --- a/dts/bindings/sensor/ti,bq274xx.yaml +++ b/dts/bindings/sensor/ti,bq274xx.yaml @@ -31,6 +31,12 @@ properties: required: true description: Battery Terminate Voltage in mV + chemistry-id: + type: int + description: | + The value of the Chem ID register. When zero, the driver will not check the register. + See the reference manual for the specific BQ274xx variant for values. + int-gpios: type: phandle-array description: | diff --git a/include/zephyr/dt-bindings/sensor/bq274xx.h b/include/zephyr/dt-bindings/sensor/bq274xx.h new file mode 100644 index 00000000000..9e8c259068e --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/bq274xx.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 The Zephyr Contributors. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Relevant documents: + * - BQ27421 + * Datasheet: https://www.ti.com/lit/gpn/bq27421-g1 + * Technical reference manual: https://www.ti.com/lit/pdf/sluuac5 + * - BQ27427 + * Datasheet: https://www.ti.com/lit/gpn/bq27427 + * Technical reference manual: https://www.ti.com/lit/pdf/sluucd5 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_SENSOR_BQ274XX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_SENSOR_BQ274XX_H_ + +/* Chemistry IDs for BQ27427 */ +#define BQ27427_CHEM_ID_A 0x3230 +#define BQ27427_CHEM_ID_B 0x1202 +#define BQ27427_CHEM_ID_C 0x3142 + +/* Chemistry IDs for BQ27421 variants */ +#define BQ27421_G1A_CHEM_ID 0x0128 +#define BQ27421_G1B_CHEM_ID 0x0312 +#define BQ27421_G1D_CHEM_ID 0x3142 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_SENSOR_BQ274XX_H_ */ From 73a106ccb404fa7236a457b64f4440ead510de06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 8 Nov 2023 14:32:57 +0100 Subject: [PATCH 3281/4498] charger: doc: Fix doxygen docstrings in charger header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a couple of improperly formatted Javadoc docstrings. Added @file tag. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/charger.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 25802e6b76a..6159f41dcc0 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Charger APIs + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ #define ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ @@ -106,7 +111,7 @@ enum charger_charge_type { CHARGER_CHARGE_TYPE_UNKNOWN = 0, /** Charging is not occurring */ CHARGER_CHARGE_TYPE_NONE, - /* + /** * Charging is occurring at the slowest desired charge rate, * typically for battery detection or preconditioning */ @@ -145,7 +150,7 @@ enum charger_health { CHARGER_HEALTH_OVERHEAT, /** The battery voltage has exceeded its overvoltage threshold */ CHARGER_HEALTH_OVERVOLTAGE, - /* + /** * The battery or charger device is experiencing an unspecified * failure. */ From 559424285f635e7bb1c6878d8475907942723249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 6 Nov 2023 14:59:58 +0100 Subject: [PATCH 3282/4498] doc: develop: update ram and rom report sample and reduce width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the sample outputs for ram and rom report commands to reflect current look&feel, and reduce the width of the output to better fit on narrow screens & PDF output. Signed-off-by: Benjamin Cabé --- doc/develop/optimizations/tools.rst | 148 ++++++++++++++-------------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/doc/develop/optimizations/tools.rst b/doc/develop/optimizations/tools.rst index 762891cf8d8..c253d47092e 100644 --- a/doc/develop/optimizations/tools.rst +++ b/doc/develop/optimizations/tools.rst @@ -33,37 +33,48 @@ Use the ``ram_report`` target with your board: which will generate something similar to the output below:: - Path Size % - ============================================================================================================== - ... - ... - SystemCoreClock 4 0.08% - _kernel 48 0.99% - _sw_isr_table 384 7.94% - cli.10544 16 0.33% - gpio_initialized.9765 1 0.02% - on.10543 4 0.08% - poll_out_lock.9764 4 0.08% - z_idle_threads 128 2.65% - z_interrupt_stacks 2048 42.36% - z_main_thread 128 2.65% - arch 1 0.02% - arm 1 0.02% - core 1 0.02% - aarch32 1 0.02% - cortex_m 1 0.02% - mpu 1 0.02% - arm_mpu.c 1 0.02% - static_regions_num 1 0.02% - drivers 536 11.09% - clock_control 100 2.07% - nrf_power_clock.c 100 2.07% - __device_clock_nrf 16 0.33% - data 80 1.65% - hfclk_users 4 0.08% - ... - ... - + Path Size % + ======================================================================================== + Root 4637 100.00% + ├── (hidden) 4 0.09% + ├── (no paths) 2748 59.26% + │ ├── _cpus_active 4 0.09% + │ ├── _kernel 32 0.69% + │ ├── _sw_isr_table 384 8.28% + │ ├── cli.1 16 0.35% + │ ├── on.2 4 0.09% + │ ├── poll_out_lock.0 4 0.09% + │ ├── z_idle_threads 128 2.76% + │ ├── z_interrupt_stacks 2048 44.17% + │ └── z_main_thread 128 2.76% + ├── WORKSPACE 184 3.97% + │ └── modules 184 3.97% + │ └── hal 184 3.97% + │ └── nordic 184 3.97% + │ └── nrfx 184 3.97% + │ └── drivers 184 3.97% + │ └── src 184 3.97% + │ ├── nrfx_clock.c 8 0.17% + │ │ └── m_clock_cb 8 0.17% + │ ├── nrfx_gpiote.c 132 2.85% + │ │ └── m_cb 132 2.85% + │ ├── nrfx_ppi.c 4 0.09% + │ │ └── m_channels_allocated 4 0.09% + │ └── nrfx_twim.c 40 0.86% + │ └── m_cb 40 0.86% + └── ZEPHYR_BASE 1701 36.68% + ├── arch 5 0.11% + │ └── arm 5 0.11% + │ └── core 5 0.11% + │ ├── mpu 1 0.02% + │ │ └── arm_mpu.c 1 0.02% + │ │ └── static_regions_num 1 0.02% + │ └── tls.c 4 0.09% + │ └── z_arm_tls_ptr 4 0.09% + ├── drivers 258 5.56% + │ ├── ... ... ...% + ======================================================================================== + 4637 Build Target: rom_report ======================== @@ -82,47 +93,40 @@ Use the ``rom_report`` to get the ROM report: which will generate something similar to the output below:: - Path Size % - ============================================================================================================== - ... - ... - CSWTCH.5 4 0.02% - SystemCoreClock 4 0.02% - __aeabi_idiv0 2 0.01% - __udivmoddi4 702 3.37% - _sw_isr_table 384 1.85% - delay_machine_code.9114 6 0.03% - levels.8826 20 0.10% - mpu_config 8 0.04% - transitions.10558 12 0.06% - arch 1194 5.74% - arm 1194 5.74% - core 1194 5.74% - aarch32 1194 5.74% - cortex_m 852 4.09% - fault.c 400 1.92% - bus_fault.isra.0 60 0.29% - mem_manage_fault.isra.0 56 0.27% - usage_fault.isra.0 36 0.17% - z_arm_fault 232 1.11% - z_arm_fault_init 16 0.08% - irq_init.c 24 0.12% - z_arm_interrupt_init 24 0.12% - mpu 352 1.69% - arm_core_mpu.c 56 0.27% - z_arm_configure_static_mpu_regions 56 0.27% - arm_mpu.c 296 1.42% - __init_sys_init_arm_mpu_init0 8 0.04% - arm_core_mpu_configure_static_mpu_regions 20 0.10% - arm_core_mpu_disable 16 0.08% - arm_core_mpu_enable 20 0.10% - arm_mpu_init 92 0.44% - mpu_configure_regions 140 0.67% - thread_abort.c 76 0.37% - z_impl_k_thread_abort - 76 0.37% - ... - ... + Path Size % + ======================================================================================== + Root 21652 100.00% + ├── ... ... ...% + └── ZEPHYR_BASE 13378 61.79% + ├── arch 1718 7.93% + │ └── arm 1718 7.93% + │ └── core 1718 7.93% + │ ├── cortex_m 1020 4.71% + │ │ ├── fault.c 620 2.86% + │ │ │ ├── bus_fault.constprop.0 108 0.50% + │ │ │ ├── mem_manage_fault.constprop.0 120 0.55% + │ │ │ ├── usage_fault.constprop.0 84 0.39% + │ │ │ ├── z_arm_fault 292 1.35% + │ │ │ └── z_arm_fault_init 16 0.07% + │ │ ├── ... ... ...% + ├── boards 32 0.15% + │ └── arm 32 0.15% + │ └── reel_board 32 0.15% + │ └── board.c 32 0.15% + │ ├── __init_board_reel_board_init 8 0.04% + │ └── board_reel_board_init 24 0.11% + ├── build 194 0.90% + │ └── zephyr 194 0.90% + │ ├── isr_tables.c 192 0.89% + │ │ └── _irq_vector_table 192 0.89% + │ └── misc 2 0.01% + │ └── generated 2 0.01% + │ └── configs.c 2 0.01% + │ └── _ConfigAbsSyms 2 0.01% + ├── drivers 6162 28.46% + │ ├── ... ... ...% + ======================================================================================== + 21652 Build Target: puncover ====================== From 3769938e785b09cff9ebb604a371100d1bfcf257 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Mon, 6 Nov 2023 16:53:17 -0600 Subject: [PATCH 3283/4498] boards: arm: Fix sensor shell sample for beagleconnect_freedom board Commit 944ced68f5e558c9cf5e30b69b3ab8a6d7e6f15e enabled CONFIG_UART_CONSOLE=y for the beagleconnect_freedom board, which had the side effect of satisfying a required dependency for the sensor shell sample application and causing new build errors in the weekly full twister run. Fix the build errors by moving the board's light and humidity sensor nodes to be children of the I2C controller node. Signed-off-by: Maureen Helm --- .../arm/beagle_bcf/beagleconnect_freedom.dts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom.dts b/boards/arm/beagle_bcf/beagleconnect_freedom.dts index 3f6fcafaa21..7300e9de5db 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom.dts +++ b/boards/arm/beagle_bcf/beagleconnect_freedom.dts @@ -64,18 +64,6 @@ #size-cells = <0>; controller = <&i2c0>; gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; - - light: opt3001-light@44 { - status = "okay"; - compatible = "ti,opt3001"; - reg = <0x44>; - }; - - humidity: hdc2010-humidity@41 { - status = "okay"; - compatible = "ti,hdc2010"; - reg = <0x41>; - }; }; }; @@ -138,6 +126,18 @@ compatible = "beagle,usbbridge"; reg = <0x4>; }; + + light: opt3001-light@44 { + status = "okay"; + compatible = "ti,opt3001"; + reg = <0x44>; + }; + + humidity: hdc2010-humidity@41 { + status = "okay"; + compatible = "ti,hdc2010"; + reg = <0x41>; + }; }; &spi0 { From 9bb44b8e5fc42d6d638660ef9d42edd11aa63623 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 8 Nov 2023 21:11:44 +0000 Subject: [PATCH 3284/4498] dts: arm: st: set flash size for stm32l011X4 This device lost the reg property since 88c9d1fbaf, causing the nucleo_l011k4 board to not build anymore. Add it back, 512 bytes should be the right number for this chip. Signed-off-by: Fabio Baltieri --- dts/arm/st/l0/stm32l011X4.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dts/arm/st/l0/stm32l011X4.dtsi b/dts/arm/st/l0/stm32l011X4.dtsi index e42fa1af64c..e2d7b5eafd3 100644 --- a/dts/arm/st/l0/stm32l011X4.dtsi +++ b/dts/arm/st/l0/stm32l011X4.dtsi @@ -18,5 +18,9 @@ reg = <0x08000000 DT_SIZE_K(16)>; }; }; + + eeprom: eeprom@8080000{ + reg = <0x08080000 512>; + }; }; }; From b4625d6f137905846af62bb44d0adc437c17da7c Mon Sep 17 00:00:00 2001 From: Gustavo Silva Date: Wed, 4 Oct 2023 13:57:24 -0300 Subject: [PATCH 3285/4498] drivers: sensor: add tsl2561 basic support Add basic support for ams TSL2561 light sensor. Triggers, attributes and manual integration time are currently not supported. Signed-off-by: Gustavo Silva --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/tsl2561/CMakeLists.txt | 5 + drivers/sensor/tsl2561/Kconfig | 10 + drivers/sensor/tsl2561/tsl2561.c | 346 ++++++++++++++++++++++++ dts/bindings/sensor/ams,tsl2561.yaml | 28 ++ tests/drivers/build_all/sensor/i2c.dtsi | 5 + 7 files changed, 396 insertions(+) create mode 100644 drivers/sensor/tsl2561/CMakeLists.txt create mode 100644 drivers/sensor/tsl2561/Kconfig create mode 100644 drivers/sensor/tsl2561/tsl2561.c create mode 100644 dts/bindings/sensor/ams,tsl2561.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index a50b1c55657..b0359f0254b 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -146,6 +146,7 @@ add_subdirectory_ifdef(CONFIG_TMP108 tmp108) add_subdirectory_ifdef(CONFIG_TMP112 tmp112) add_subdirectory_ifdef(CONFIG_TMP116 tmp116) add_subdirectory_ifdef(CONFIG_TSL2540 tsl2540) +add_subdirectory_ifdef(CONFIG_TSL2561 tsl2561) add_subdirectory_ifdef(CONFIG_VCMP_IT8XXX2 ite_vcmp_it8xxx2) add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040) add_subdirectory_ifdef(CONFIG_VEML7700 veml7700) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 585bc7dc2db..31809dd0791 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -202,6 +202,7 @@ source "drivers/sensor/tmp108/Kconfig" source "drivers/sensor/tmp112/Kconfig" source "drivers/sensor/tmp116/Kconfig" source "drivers/sensor/tsl2540/Kconfig" +source "drivers/sensor/tsl2561/Kconfig" source "drivers/sensor/vcnl4040/Kconfig" source "drivers/sensor/veml7700/Kconfig" source "drivers/sensor/vl53l0x/Kconfig" diff --git a/drivers/sensor/tsl2561/CMakeLists.txt b/drivers/sensor/tsl2561/CMakeLists.txt new file mode 100644 index 00000000000..7c2d251b150 --- /dev/null +++ b/drivers/sensor/tsl2561/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(tsl2561.c) diff --git a/drivers/sensor/tsl2561/Kconfig b/drivers/sensor/tsl2561/Kconfig new file mode 100644 index 00000000000..e5b975bad34 --- /dev/null +++ b/drivers/sensor/tsl2561/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Gustavo Silva +# SPDX-License-Identifier: Apache-2.0 + +config TSL2561 + bool "OSRAM-AMS TSL2561 light sensor" + default y + depends on DT_HAS_AMS_TSL2561_ENABLED + select I2C + help + Enable driver for TSL2561 sensor. diff --git a/drivers/sensor/tsl2561/tsl2561.c b/drivers/sensor/tsl2561/tsl2561.c new file mode 100644 index 00000000000..42efffb2242 --- /dev/null +++ b/drivers/sensor/tsl2561/tsl2561.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2023, Gustavo Silva + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ams_tsl2561 + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(TSL2561, CONFIG_SENSOR_LOG_LEVEL); + +#define TSL2561_CHIP_ID 0x05 + +#define TSL2561_GAIN_1X 0x00 +#define TSL2561_GAIN_16X 0x01 + +#define TSL2561_INTEGRATION_13MS 0x00 +#define TSL2561_INTEGRATION_101MS 0x01 +#define TSL2561_INTEGRATION_402MS 0x02 + +/* Register set */ +#define TSL2561_REG_CONTROL 0x00 +#define TSL2561_REG_TIMING 0x01 +#define TSL2561_REG_THRESHLOWLOW 0x02 +#define TSL2561_REG_THRESHLOWHIGH 0x03 +#define TSL2561_REG_THRESHHIGHLOW 0x04 +#define TSL2561_REG_THRESHHIGHHIGH 0x05 +#define TSL2561_REG_INTERRUPT 0x06 +#define TSL2561_REG_ID 0x0A +#define TSL2561_REG_DATA0LOW 0x0C +#define TSL2561_REG_DATA0HIGH 0x0D +#define TSL2561_REG_DATA1LOW 0x0E +#define TSL2561_REG_DATA1HIGH 0x0F + +/* Command register fields */ +#define TSL2561_COMMAND_CMD BIT(7) +#define TSL2561_COMMAND_WORD BIT(5) + +/* Control register fields */ +#define TSL2561_CONTROL_POWER_UP 0x03 +#define TSL2561_CONTROL_POWER_DOWN 0x00 + +/* Timing register fields */ +#define TSL2561_TIMING_GAIN BIT(4) +#define TSL2561_TIMING_INTEG GENMASK(1, 0) + +/* ID register part number mask */ +#define TSL2561_ID_PARTNO GENMASK(7, 4) + +/* Lux calculation constants */ +#define TSL2561_LUX_SCALE 14U +#define TSL2561_RATIO_SCALE 9U +#define TSL2561_CH_SCALE 10U +#define TSL2561_CHSCALE_TINT0 0x7517 +#define TSL2561_CHSCALE_TINT1 0x0FE7 + +#define TSL2561_LUX_K1T 0X0040 /* 0.125 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B1T 0X01F2 /* 0.0304 * 2^LUX_SCALE */ +#define TSL2561_LUX_M1T 0X01BE /* 0.0272 * 2^LUX_SCALE */ +#define TSL2561_LUX_K2T 0X0080 /* 0.250 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B2T 0X0214 /* 0.0325 * 2^LUX_SCALE */ +#define TSL2561_LUX_M2T 0X02D1 /* 0.0440 * 2^LUX_SCALE */ +#define TSL2561_LUX_K3T 0X00C0 /* 0.375 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B3T 0X023F /* 0.0351 * 2^LUX_SCALE */ +#define TSL2561_LUX_M3T 0X037B /* 0.0544 * 2^LUX_SCALE */ +#define TSL2561_LUX_K4T 0X0100 /* 0.50 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B4T 0X0270 /* 0.0381 * 2^LUX_SCALE */ +#define TSL2561_LUX_M4T 0X03FE /* 0.0624 * 2^LUX_SCALE */ +#define TSL2561_LUX_K5T 0X0138 /* 0.61 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B5T 0X016F /* 0.0224 * 2^LUX_SCALE */ +#define TSL2561_LUX_M5T 0X01FC /* 0.0310 * 2^LUX_SCALE */ +#define TSL2561_LUX_K6T 0X019A /* 0.80 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B6T 0X00D2 /* 0.0128 * 2^LUX_SCALE */ +#define TSL2561_LUX_M6T 0X00FB /* 0.0153 * 2^LUX_SCALE */ +#define TSL2561_LUX_K7T 0X029A /* 1.3 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B7T 0X0018 /* 0.00146 * 2^LUX_SCALE */ +#define TSL2561_LUX_M7T 0X0012 /* 0.00112 * 2^LUX_SCALE */ +#define TSL2561_LUX_K8T 0X029A /* 1.3 * 2^RATIO_SCALE */ +#define TSL2561_LUX_B8T 0X0000 /* 0.000 * 2^LUX_SCALE */ +#define TSL2561_LUX_M8T 0X0000 /* 0.000 * 2^LUX_SCALE */ + +struct tsl2561_config { + struct i2c_dt_spec i2c; + uint16_t integration_time; + uint8_t gain; +}; + +struct tsl2561_data { + uint16_t ch0; + uint16_t ch1; + uint32_t ch_scale; +}; + +static int tsl2561_reg_read(const struct device *dev, uint8_t reg, uint8_t *buf, uint8_t size) +{ + int ret; + const struct tsl2561_config *config = dev->config; + uint8_t cmd = (TSL2561_COMMAND_CMD | TSL2561_COMMAND_WORD | reg); + + ret = i2c_write_read_dt(&config->i2c, &cmd, 1U, buf, size); + if (ret < 0) { + LOG_ERR("Failed reading register 0x%02x", reg); + return ret; + } + + return 0; +} + +static int tsl2561_reg_write(const struct device *dev, uint8_t reg, uint8_t val) +{ + int ret; + const struct tsl2561_config *config = dev->config; + uint8_t buf[2]; + + buf[0] = (TSL2561_COMMAND_CMD | TSL2561_COMMAND_WORD | reg); + buf[1] = val; + + ret = i2c_write_dt(&config->i2c, buf, 2U); + if (ret < 0) { + LOG_ERR("Failed writing register 0x%02x", reg); + return ret; + } + + return 0; +} + +static int tsl2561_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct tsl2561_config *config = dev->config; + struct tsl2561_data *data = dev->data; + uint8_t bytes[2]; + uint8_t ret; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_LIGHT) { + LOG_ERR("Unsupported sensor channel"); + return -ENOTSUP; + } + + ret = tsl2561_reg_write(dev, TSL2561_REG_CONTROL, TSL2561_CONTROL_POWER_UP); + if (ret < 0) { + LOG_ERR("Failed to power up device"); + return ret; + } + + /* Short sleep after power up. Not in the datasheet, but found by trial and error */ + k_msleep(5); + + k_msleep(config->integration_time); + + /* Read data register's lower and upper bytes consecutively */ + ret = tsl2561_reg_read(dev, TSL2561_REG_DATA0LOW, bytes, 2U); + if (ret < 0) { + LOG_ERR("Failed reading channel0 data"); + return ret; + } + data->ch0 = bytes[1] << 8 | bytes[0]; + + ret = tsl2561_reg_read(dev, TSL2561_REG_DATA1LOW, bytes, 2U); + if (ret < 0) { + LOG_ERR("Failed reading channel1 data"); + return ret; + } + data->ch1 = bytes[1] << 8 | bytes[0]; + + ret = tsl2561_reg_write(dev, TSL2561_REG_CONTROL, TSL2561_CONTROL_POWER_DOWN); + if (ret < 0) { + LOG_ERR("Failed to power down device"); + return ret; + } + + LOG_DBG("channel0: 0x%x; channel1: 0x%x", data->ch0, data->ch1); + + return 0; +} + +static int tsl2561_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct tsl2561_data *data = dev->data; + uint32_t channel0; + uint32_t channel1; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_LIGHT) { + return -ENOTSUP; + } + + channel0 = (data->ch0 * data->ch_scale) >> TSL2561_CH_SCALE; + channel1 = (data->ch1 * data->ch_scale) >> TSL2561_CH_SCALE; + + uint32_t ratio1 = 0; + + if (channel0 != 0) { + ratio1 = (channel1 << (TSL2561_RATIO_SCALE + 1)) / channel0; + } + + /* Round the ratio value */ + uint32_t ratio = (ratio1 + 1) >> 1; + + uint32_t b = 0; + uint32_t m = 0; + + if (ratio <= TSL2561_LUX_K1T) { + b = TSL2561_LUX_B1T; + m = TSL2561_LUX_M1T; + } else if (ratio <= TSL2561_LUX_K2T) { + b = TSL2561_LUX_B2T; + m = TSL2561_LUX_M2T; + } else if (ratio <= TSL2561_LUX_K3T) { + b = TSL2561_LUX_B3T; + m = TSL2561_LUX_M3T; + } else if (ratio <= TSL2561_LUX_K4T) { + b = TSL2561_LUX_B4T; + m = TSL2561_LUX_M4T; + } else if (ratio <= TSL2561_LUX_K5T) { + b = TSL2561_LUX_B5T; + m = TSL2561_LUX_M5T; + } else if (ratio <= TSL2561_LUX_K6T) { + b = TSL2561_LUX_B6T; + m = TSL2561_LUX_M6T; + } else if (ratio <= TSL2561_LUX_K7T) { + b = TSL2561_LUX_B7T; + m = TSL2561_LUX_M7T; + } else if (ratio > TSL2561_LUX_K8T) { + b = TSL2561_LUX_B8T; + m = TSL2561_LUX_M8T; + } + + int32_t tmp = ((channel0 * b) - (channel1 * m)); + + /* Round LSB (2^(LUX_SCALE−1)) */ + tmp += (1 << (TSL2561_LUX_SCALE - 1)); + + /* Strip off fractional portion */ + val->val1 = tmp >> TSL2561_LUX_SCALE; + + val->val2 = 0; + + return 0; +} + +static const struct sensor_driver_api tsl2561_driver_api = { + .sample_fetch = tsl2561_sample_fetch, + .channel_get = tsl2561_channel_get +}; + +static int tsl2561_sensor_setup(const struct device *dev) +{ + const struct tsl2561_config *config = dev->config; + struct tsl2561_data *data = dev->data; + uint8_t timing_reg; + uint8_t chip_id; + uint8_t tmp; + int ret; + + ret = tsl2561_reg_read(dev, TSL2561_REG_ID, &chip_id, 1U); + if (ret < 0) { + LOG_ERR("Failed reading chip ID"); + return ret; + } + + if (FIELD_GET(TSL2561_ID_PARTNO, chip_id) != TSL2561_CHIP_ID) { + LOG_ERR("Chip ID is invalid! Device @%02x is not TSL2561!", config->i2c.addr); + return -EIO; + } + + switch (config->integration_time) { + case 13: + tmp = TSL2561_INTEGRATION_13MS; + data->ch_scale = TSL2561_CHSCALE_TINT0; + break; + case 101: + tmp = TSL2561_INTEGRATION_101MS; + data->ch_scale = TSL2561_CHSCALE_TINT1; + break; + case 402: + tmp = TSL2561_INTEGRATION_402MS; + data->ch_scale = (1 << TSL2561_CH_SCALE); + break; + default: + LOG_ERR("Invalid integration time"); + return -EINVAL; + } + + timing_reg = TSL2561_TIMING_INTEG & tmp; + + switch (config->gain) { + case 1: + tmp = TSL2561_GAIN_1X; + data->ch_scale = data->ch_scale << 4; + break; + case 16: + tmp = TSL2561_GAIN_16X; + break; + default: + LOG_ERR("Invalid ADC gain"); + return -EINVAL; + } + + timing_reg |= FIELD_PREP(TSL2561_TIMING_GAIN, tmp); + + ret = tsl2561_reg_write(dev, TSL2561_REG_TIMING, timing_reg); + if (ret < 0) { + LOG_ERR("Failed setting timing register"); + return ret; + } + + return 0; +} + +static int tsl2561_init(const struct device *dev) +{ + const struct tsl2561_config *config = dev->config; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C dev %s not ready", config->i2c.bus->name); + return -ENODEV; + } + + ret = tsl2561_sensor_setup(dev); + if (ret < 0) { + LOG_ERR("Failed to configure device"); + return ret; + } + + return 0; +} + +#define TSL2561_INIT_INST(n) \ + static struct tsl2561_data tsl2561_data_##n; \ + static const struct tsl2561_config tsl2561_config_##n = { \ + .i2c = I2C_DT_SPEC_INST_GET(n), \ + .integration_time = DT_INST_PROP(n, integration_time), \ + .gain = DT_INST_PROP(n, gain)}; \ + SENSOR_DEVICE_DT_INST_DEFINE(n, tsl2561_init, NULL, &tsl2561_data_##n, \ + &tsl2561_config_##n, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tsl2561_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TSL2561_INIT_INST) diff --git a/dts/bindings/sensor/ams,tsl2561.yaml b/dts/bindings/sensor/ams,tsl2561.yaml new file mode 100644 index 00000000000..fbc97a673e8 --- /dev/null +++ b/dts/bindings/sensor/ams,tsl2561.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2023, Gustavo Silva +# SPDX-License-Identifier: Apache-2.0 + +description: | + OSRAM ams TSL2561 light sensor. + +compatible: "ams,tsl2561" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + integration-time: + type: int + default: 402 + description: | + ADC integration time in ms. The default value matches Timing Register's value at power on. + enum: + - 13 + - 101 + - 402 + gain: + type: int + default: 16 + description: | + ADC gain factor. The default value matches Timing Register's value at power on. + enum: + - 1 + - 16 diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index c7c167aca14..4e54911f969 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -794,3 +794,8 @@ test_i2c_adxl367: adxl367@77 { reg = <0x77>; odr = <4>; }; + +test_i2c_tsl2561: tsl2561@78 { + compatible = "ams,tsl2561"; + reg = <0x78>; +}; From 546a64065773841af565771fe968f5c72ab3a2f3 Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Mon, 9 Oct 2023 10:58:56 +0300 Subject: [PATCH 3286/4498] drivers: dma: smartbond: Support DMA accelerator. Add support for the DMA engine. Signed-off-by: Ioannis Karachalios --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 1 + drivers/dma/Kconfig.smartbond | 11 + drivers/dma/dma_smartbond.c | 969 ++++++++++++++++++++ dts/bindings/dma/renesas,smartbond-dma.yaml | 21 + include/zephyr/drivers/dma/dma_smartbond.h | 33 + 6 files changed, 1036 insertions(+) create mode 100644 drivers/dma/Kconfig.smartbond create mode 100644 drivers/dma/dma_smartbond.c create mode 100644 dts/bindings/dma/renesas,smartbond-dma.yaml create mode 100644 include/zephyr/drivers/dma/dma_smartbond.h diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index da2d43fc2c0..271ddf19ff0 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -36,3 +36,4 @@ zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) zephyr_library_sources_ifdef(CONFIG_DMA_SEDI dma_sedi.c) +zephyr_library_sources_ifdef(CONFIG_DMA_SMARTBOND dma_smartbond.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 0136eaa92a2..5a2ce5bdced 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -68,4 +68,5 @@ source "drivers/dma/Kconfig.andes_atcdmac300" source "drivers/dma/Kconfig.sedi" +source "drivers/dma/Kconfig.smartbond" endif # DMA diff --git a/drivers/dma/Kconfig.smartbond b/drivers/dma/Kconfig.smartbond new file mode 100644 index 00000000000..3234e13020f --- /dev/null +++ b/drivers/dma/Kconfig.smartbond @@ -0,0 +1,11 @@ +# Smartbond DMA Accelerator Configuration Options + +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config DMA_SMARTBOND + bool "Smartbond DMA Accelerator Driver" + depends on DT_HAS_RENESAS_SMARTBOND_DMA_ENABLED + default y + help + Enable Smartbond DMA Accelerator Driver diff --git a/drivers/dma/dma_smartbond.c b/drivers/dma/dma_smartbond.c new file mode 100644 index 00000000000..79305c77d6a --- /dev/null +++ b/drivers/dma/dma_smartbond.c @@ -0,0 +1,969 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(dma_smartbond, CONFIG_DMA_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_smartbond_dma + +#define SMARTBOND_IRQN DT_INST_IRQN(0) +#define SMARTBOND_IRQ_PRIO DT_INST_IRQ(0, priority) + +#define DMA_CHANNELS_COUNT DT_PROP(DT_NODELABEL(dma), dma_channels) +#define DMA_BLOCK_COUNT DT_PROP(DT_NODELABEL(dma), block_count) +#define DMA_SECURE_CHANNEL 7 + +#define DMA_CTRL_REG_SET_FIELD(_field, _var, _val) \ + (_var) = \ + (((_var) & ~DMA_DMA0_CTRL_REG_ ## _field ## _Msk) | \ + (((_val) << DMA_DMA0_CTRL_REG_ ## _field ## _Pos) & DMA_DMA0_CTRL_REG_ ## _field ## _Msk)) + +#define DMA_CTRL_REG_GET_FIELD(_field, _var) \ + (((_var) & DMA_DMA0_CTRL_REG_ ## _field ## _Msk) >> DMA_DMA0_CTRL_REG_ ## _field ## _Pos) + +#define DMA_CHN2REG(_idx) (&((struct channel_regs *)DMA)[(_idx)]) + +#define DMA_MUX_SHIFT(_idx) (((_idx) >> 1) * 4) + +#define DMA_REQ_MUX_REG_SET(_idx, _val) \ + DMA->DMA_REQ_MUX_REG = \ + (DMA->DMA_REQ_MUX_REG & ~(0xf << DMA_MUX_SHIFT((_idx)))) | \ + (((_val) & 0xf) << DMA_MUX_SHIFT((_idx))) + +#define DMA_REQ_MUX_REG_GET(_idx) \ + ((DMA->DMA_REQ_MUX_REG >> DMA_MUX_SHIFT((_idx))) & 0xf) + +#define CRYPTO_KEYS_BUF_ADDR 0x30040100 +#define CRYPTO_KEYS_BUF_SIZE 0x100 +#define IS_AES_KEYS_BUF_RANGE(_a) ((uint32_t)(_a) >= (uint32_t)(CRYPTO_KEYS_BUF_ADDR)) && \ + ((uint32_t)(_a) < (uint32_t)(CRYPTO_KEYS_BUF_ADDR + CRYPTO_KEYS_BUF_SIZE)) + +/* + * DMA channel priority level. The smaller the value the lower the priority granted to a channel + * when two or more channels request the bus at the same time. For channels of same priority an + * inherent mechanism is applied in which the lower the channel number the higher the priority. + */ +enum dma_smartbond_channel_prio { + DMA_SMARTBOND_CHANNEL_PRIO_0 = 0x0, /* Lowest channel priority */ + DMA_SMARTBOND_CHANNEL_PRIO_1, + DMA_SMARTBOND_CHANNEL_PRIO_2, + DMA_SMARTBOND_CHANNEL_PRIO_3, + DMA_SMARTBOND_CHANNEL_PRIO_4, + DMA_SMARTBOND_CHANNEL_PRIO_5, + DMA_SMARTBOND_CHANNEL_PRIO_6, + DMA_SMARTBOND_CHANNEL_PRIO_7, /* Highest channel priority */ + DMA_SMARTBOND_CHANNEL_PRIO_MAX +}; + +enum dma_smartbond_channel { + DMA_SMARTBOND_CHANNEL_0 = 0x0, + DMA_SMARTBOND_CHANNEL_1, + DMA_SMARTBOND_CHANNEL_2, + DMA_SMARTBOND_CHANNEL_3, + DMA_SMARTBOND_CHANNEL_4, + DMA_SMARTBOND_CHANNEL_5, + DMA_SMARTBOND_CHANNEL_6, + DMA_SMARTBOND_CHANNEL_7, + DMA_SMARTBOND_CHANNEL_MAX +}; + +enum dma_smartbond_burst_len { + DMA_SMARTBOND_BURST_LEN_1B = 0x1, /* Burst mode is disabled */ + DMA_SMARTBOND_BURST_LEN_4B = 0x4, /* Perform bursts of 4 beats (INCR4) */ + DMA_SMARTBOND_BURST_LEN_8B = 0x8 /* Perform bursts of 8 beats (INCR8) */ +}; + +/* + * DMA bus width indicating how many bytes are retrived/written per transfer. + * Note that the bus width is the same for the source and destination. + */ +enum dma_smartbond_bus_width { + DMA_SMARTBOND_BUS_WIDTH_1B = 0x1, + DMA_SMARTBOND_BUS_WIDTH_2B = 0x2, + DMA_SMARTBOND_BUS_WIDTH_4B = 0x4 +}; + +enum dreq_mode { + DREQ_MODE_SW = 0x0, + DREQ_MODE_HW +}; + +enum burst_mode { + BURST_MODE_0B = 0x0, + BURST_MODE_4B = 0x1, + BURST_MODE_8B = 0x2 +}; + +enum bus_width { + BUS_WIDTH_1B = 0x0, + BUS_WIDTH_2B = 0x1, + BUS_WIDTH_4B = 0x2 +}; + +enum addr_adj { + ADDR_ADJ_NO_CHANGE = 0x0, + ADDR_ADJ_INCR +}; + +enum copy_mode { + COPY_MODE_BLOCK = 0x0, + COPY_MODE_INIT +}; + +enum req_sense { + REQ_SENSE_LEVEL = 0x0, + REQ_SENSE_EDGE +}; + +struct channel_regs { + __IO uint32_t DMA_A_START; + __IO uint32_t DMA_B_START; + __IO uint32_t DMA_INT_REG; + __IO uint32_t DMA_LEN_REG; + __IO uint32_t DMA_CTRL_REG; + + __I uint32_t DMA_IDX_REG; + __I uint32_t RESERVED[2]; +}; + +struct dma_channel_data { + dma_callback_t cb; + void *user_data; + enum dma_smartbond_bus_width bus_width; + enum dma_smartbond_burst_len burst_len; + enum dma_channel_direction dir; + bool is_dma_configured; +}; + +struct dma_smartbond_data { + /* Should be the first member of the driver data */ + struct dma_context dma_ctx; + + ATOMIC_DEFINE(channels_atomic, DMA_CHANNELS_COUNT); + + /* User callbacks and data to be stored per channel */ + struct dma_channel_data channel_data[DMA_CHANNELS_COUNT]; +}; + +/* True if there is any DMA activity on any channel, false otheriwise. */ +static bool dma_smartbond_is_dma_active(void) +{ + int idx; + struct channel_regs *regs; + + for (idx = 0; idx < DMA_CHANNELS_COUNT; idx++) { + regs = DMA_CHN2REG(idx); + + if (DMA_CTRL_REG_GET_FIELD(DMA_ON, regs->DMA_CTRL_REG)) { + return true; + } + } + + return false; +} + +static void dma_smartbond_set_channel_status(uint32_t channel, bool status) +{ + unsigned int key; + struct channel_regs *regs = DMA_CHN2REG(channel); + + key = irq_lock(); + + if (status) { + /* Make sure the status register for the requested channel is cleared. */ + DMA->DMA_CLEAR_INT_REG |= BIT(channel); + /* Enable interrupts for the requested channel. */ + DMA->DMA_INT_MASK_REG |= BIT(channel); + + /* Check if this is the first attempt to enable DMA interrupts. */ + if (!irq_is_enabled(SMARTBOND_IRQN)) { + irq_enable(SMARTBOND_IRQN); + } + + DMA_CTRL_REG_SET_FIELD(DMA_ON, regs->DMA_CTRL_REG, 0x1); + } else { + DMA_CTRL_REG_SET_FIELD(DMA_ON, regs->DMA_CTRL_REG, 0x0); + + /* + * It might happen that DMA is already in progress. Make sure the current + * on-going transfer is complete (cannot be interrupted). + */ + while (DMA_CTRL_REG_GET_FIELD(DMA_ON, regs->DMA_CTRL_REG)) { + } + + /* Disable interrupts for the requested channel */ + DMA->DMA_INT_MASK_REG &= ~(BIT(channel)); + /* Clear the status register; the requested channel should be considered obsolete */ + DMA->DMA_CLEAR_INT_REG |= BIT(channel); + + /* DMA interrupts should be disabled only if all channels are disabled. */ + if (!dma_smartbond_is_dma_active()) { + irq_disable(SMARTBOND_IRQN); + } + } + + irq_unlock(key); +} + +static bool dma_channel_dst_addr_check_and_adjust(uint32_t channel, uint32_t *dst) +{ + uint32_t phy_address; + uint32_t secure_boot_reg; + bool is_aes_keys_protected, is_qspic_keys_protected; + + phy_address = black_orca_phy_addr(*dst); + + secure_boot_reg = CRG_TOP->SECURE_BOOT_REG; + is_aes_keys_protected = + (secure_boot_reg & CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Msk); + is_qspic_keys_protected = + (secure_boot_reg & CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Msk); + + /* + * If the destination address reflects the AES key buffer area and secure keys are protected + * then only the secure channel #7 can be used to transfer data to AES key buffer. + */ + if ((IS_AES_KEYS_BUF_RANGE(phy_address) && + (is_aes_keys_protected || is_qspic_keys_protected) && + (channel != DMA_SECURE_CHANNEL))) { + LOG_ERR("Keys are protected. Only secure channel #7 can be employed."); + return false; + } + + if (IS_QSPIF_ADDRESS(phy_address) || IS_QSPIF_CACHED_ADDRESS(phy_address) || + IS_OTP_ADDRESS(phy_address) || IS_OTP_P_ADDRESS(phy_address)) { + LOG_ERR("Invalid destination location."); + return false; + } + + *dst = phy_address; + + return true; +} + +static bool dma_channel_src_addr_check_and_adjust(uint32_t channel, uint32_t *src) +{ + uint32_t phy_address; + uint32_t secure_boot_reg; + bool is_aes_keys_protected, is_qspic_keys_protected; + + /* DMA can only access physical addresses, not remapped. */ + phy_address = black_orca_phy_addr(*src); + + if (IS_QSPIF_CACHED_ADDRESS(phy_address)) { + /* + * To achiebe max. perfomance, peripherals should not access the Flash memory + * through the instruction cache controller (avoid cache misses). + */ + phy_address += (MCU_QSPIF_M_BASE - MCU_QSPIF_M_CACHED_BASE); + } else if (IS_OTP_ADDRESS(phy_address)) { + /* Peripherals should access OTP through its peripheral address space. */ + phy_address += (MCU_OTP_M_P_BASE - MCU_OTP_M_BASE); + } + + secure_boot_reg = CRG_TOP->SECURE_BOOT_REG; + is_aes_keys_protected = + (secure_boot_reg & CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Msk); + is_qspic_keys_protected = + (secure_boot_reg & CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Msk); + + /* + * If the source address reflects protected area in OTP then only the + * secure channel #7 can be used to fetch secure keys data. + */ + if (((IS_ADDRESS_USER_DATA_KEYS_SEGMENT(phy_address) && is_aes_keys_protected) || + (IS_ADDRESS_QSPI_FW_KEYS_SEGMENT(phy_address) && is_qspic_keys_protected)) && + (channel != DMA_SECURE_CHANNEL)) { + LOG_ERR("Keys are protected. Only secure channel #7 can be employed."); + return false; + } + + *src = phy_address; + + return true; +} + +static bool dma_channel_update_dreq_mode(enum dma_channel_direction direction, + uint32_t *dma_ctrl_reg) +{ + switch (direction) { + case MEMORY_TO_HOST: + case HOST_TO_MEMORY: + case MEMORY_TO_MEMORY: + /* DMA channel starts immediately */ + DMA_CTRL_REG_SET_FIELD(DREQ_MODE, *dma_ctrl_reg, DREQ_MODE_SW); + break; + case PERIPHERAL_TO_MEMORY: + case PERIPHERAL_TO_PERIPHERAL: + /* DMA channels starts by peripheral DMA req */ + DMA_CTRL_REG_SET_FIELD(DREQ_MODE, *dma_ctrl_reg, DREQ_MODE_HW); + break; + default: + return false; + }; + + return true; +} + +static bool dma_channel_update_src_addr_adj(enum dma_addr_adj addr_adj, uint32_t *dma_ctrl_reg) +{ + switch (addr_adj) { + case DMA_ADDR_ADJ_NO_CHANGE: + DMA_CTRL_REG_SET_FIELD(AINC, *dma_ctrl_reg, ADDR_ADJ_NO_CHANGE); + break; + case DMA_ADDR_ADJ_INCREMENT: + DMA_CTRL_REG_SET_FIELD(AINC, *dma_ctrl_reg, ADDR_ADJ_INCR); + break; + default: + return false; + } + + return true; +} + +static bool dma_channel_update_dst_addr_adj(enum dma_addr_adj addr_adj, uint32_t *dma_ctrl_reg) +{ + switch (addr_adj) { + case DMA_ADDR_ADJ_NO_CHANGE: + DMA_CTRL_REG_SET_FIELD(BINC, *dma_ctrl_reg, ADDR_ADJ_NO_CHANGE); + break; + case DMA_ADDR_ADJ_INCREMENT: + DMA_CTRL_REG_SET_FIELD(BINC, *dma_ctrl_reg, ADDR_ADJ_INCR); + break; + default: + return false; + } + + return true; +} + +static bool dma_channel_update_bus_width(uint16_t bw, uint32_t *dma_ctrl_reg) +{ + switch (bw) { + case DMA_SMARTBOND_BUS_WIDTH_1B: + DMA_CTRL_REG_SET_FIELD(BW, *dma_ctrl_reg, BUS_WIDTH_1B); + break; + case DMA_SMARTBOND_BUS_WIDTH_2B: + DMA_CTRL_REG_SET_FIELD(BW, *dma_ctrl_reg, BUS_WIDTH_2B); + break; + case DMA_SMARTBOND_BUS_WIDTH_4B: + DMA_CTRL_REG_SET_FIELD(BW, *dma_ctrl_reg, BUS_WIDTH_4B); + break; + default: + return false; + } + + return true; +} + +static bool dma_channel_update_burst_mode(uint16_t burst, uint32_t *dma_ctrl_reg) +{ + switch (burst) { + case DMA_SMARTBOND_BURST_LEN_1B: + DMA_CTRL_REG_SET_FIELD(BURST_MODE, *dma_ctrl_reg, BURST_MODE_0B); + break; + case DMA_SMARTBOND_BURST_LEN_4B: + DMA_CTRL_REG_SET_FIELD(BURST_MODE, *dma_ctrl_reg, BURST_MODE_4B); + break; + case DMA_SMARTBOND_BURST_LEN_8B: + DMA_CTRL_REG_SET_FIELD(BURST_MODE, *dma_ctrl_reg, BURST_MODE_8B); + break; + default: + return false; + } + + return true; +} + +static void dma_channel_update_req_sense(enum dma_smartbond_trig_mux trig_mux, + uint32_t channel, uint32_t *dma_ctrl_reg) +{ + switch (trig_mux) { + case DMA_SMARTBOND_TRIG_MUX_UART: + case DMA_SMARTBOND_TRIG_MUX_UART2: + case DMA_SMARTBOND_TRIG_MUX_UART3: + case DMA_SMARTBOND_TRIG_MUX_I2C: + case DMA_SMARTBOND_TRIG_MUX_I2C2: + case DMA_SMARTBOND_TRIG_MUX_USB: + /* Odd channel numbers should reflect TX path */ + if (channel & BIT(0)) { + DMA_CTRL_REG_SET_FIELD(REQ_SENSE, *dma_ctrl_reg, REQ_SENSE_EDGE); + break; + } + default: + DMA_CTRL_REG_SET_FIELD(REQ_SENSE, *dma_ctrl_reg, REQ_SENSE_LEVEL); + } +} + +static void dma_set_mux_request(enum dma_smartbond_trig_mux trig_mux, uint32_t channel) +{ + unsigned int key; + + key = irq_lock(); + DMA_REQ_MUX_REG_SET(channel, trig_mux); + + /* + * Having same trigger for different channels can cause unpredictable results. + * The audio triggers (src and pcm) are an exception, as they use 2 pairs each + * for DMA access. + * The lesser significant selector has higher priority and will control + * the DMA acknowledge signal driven to the selected peripheral. Make sure + * the current selector does not match with selectors of + * higher priorities (dma channels of lower indexing). It's OK if a + * channel of higher indexing defines the same peripheral request source + * (should be ignored as it has lower priority). + */ + if (trig_mux != DMA_SMARTBOND_TRIG_MUX_NONE) { + switch (channel) { + case DMA_SMARTBOND_CHANNEL_7: + case DMA_SMARTBOND_CHANNEL_6: + if (DMA_REQ_MUX_REG_GET(DMA_SMARTBOND_CHANNEL_5) == trig_mux) { + DMA_REQ_MUX_REG_SET(DMA_SMARTBOND_CHANNEL_5, + DMA_SMARTBOND_TRIG_MUX_NONE); + } + /* fall-through */ + case DMA_SMARTBOND_CHANNEL_5: + case DMA_SMARTBOND_CHANNEL_4: + if (DMA_REQ_MUX_REG_GET(DMA_SMARTBOND_CHANNEL_3) == trig_mux) { + DMA_REQ_MUX_REG_SET(DMA_SMARTBOND_CHANNEL_3, + DMA_SMARTBOND_TRIG_MUX_NONE); + } + /* fall-through */ + case DMA_SMARTBOND_CHANNEL_3: + case DMA_SMARTBOND_CHANNEL_2: + if (DMA_REQ_MUX_REG_GET(DMA_SMARTBOND_CHANNEL_1) == trig_mux) { + DMA_REQ_MUX_REG_SET(DMA_SMARTBOND_CHANNEL_1, + DMA_SMARTBOND_TRIG_MUX_NONE); + } + case DMA_SMARTBOND_CHANNEL_1: + case DMA_SMARTBOND_CHANNEL_0: + break; + } + } + + irq_unlock(key); +} + +static int dma_smartbond_config(const struct device *dev, uint32_t channel, struct dma_config *cfg) +{ + struct dma_smartbond_data *data = dev->data; + struct channel_regs *regs; + uint32_t dma_ctrl_reg; + uint32_t src_dst_address; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + regs = DMA_CHN2REG(channel); + + dma_ctrl_reg = regs->DMA_CTRL_REG; + + if (DMA_CTRL_REG_GET_FIELD(DMA_ON, dma_ctrl_reg)) { + LOG_ERR("Requested channel is enabled. It should first be disabled"); + return -EIO; + } + + if (cfg == NULL || cfg->head_block == NULL) { + LOG_ERR("Missing configuration structure"); + return -EINVAL; + } + + /* Error handling is not supported; just warn user. */ + if (cfg->error_callback_en) { + LOG_WRN("Error handling is not supported"); + } + + if (!cfg->complete_callback_en) { + data->channel_data[channel].cb = cfg->dma_callback; + data->channel_data[channel].user_data = cfg->user_data; + } else { + LOG_WRN("User callback can only be called at completion only and not per block."); + + /* Nulify pointers to indicate notifications are disabled. */ + data->channel_data[channel].cb = NULL; + data->channel_data[channel].user_data = NULL; + } + + data->channel_data[channel].dir = cfg->channel_direction; + + if (cfg->block_count > DMA_BLOCK_COUNT) { + LOG_WRN("A single block is supported. The rest blocks will be discarded"); + } + + if (cfg->channel_priority >= DMA_SMARTBOND_CHANNEL_PRIO_MAX) { + cfg->channel_priority = DMA_SMARTBOND_CHANNEL_PRIO_7; + LOG_WRN("Channel priority exceeded max. Setting to highest valid level"); + } + + DMA_CTRL_REG_SET_FIELD(DMA_PRIO, dma_ctrl_reg, cfg->channel_priority); + + if (((cfg->source_burst_length != cfg->dest_burst_length) || + !dma_channel_update_burst_mode(cfg->source_burst_length, &dma_ctrl_reg))) { + LOG_ERR("Invalid burst mode or source and destination mode mismatch"); + return -EINVAL; + } + + data->channel_data[channel].burst_len = cfg->source_burst_length; + + if (cfg->source_data_size != cfg->dest_data_size || + !dma_channel_update_bus_width(cfg->source_data_size, &dma_ctrl_reg)) { + LOG_ERR("Invalid bus width or source and destination bus width mismatch"); + return -EINVAL; + } + + data->channel_data[channel].bus_width = cfg->source_data_size; + + if (cfg->source_chaining_en || cfg->dest_chaining_en || + cfg->head_block->source_gather_en || cfg->head_block->dest_scatter_en || + cfg->head_block->source_reload_en || cfg->head_block->dest_reload_en) { + LOG_WRN("Chainning, scattering, gathering or reloading is not supported"); + } + + if (!dma_channel_update_src_addr_adj(cfg->head_block->source_addr_adj, + &dma_ctrl_reg)) { + LOG_ERR("Invalid source address adjustment"); + return -EINVAL; + } + + if (!dma_channel_update_dst_addr_adj(cfg->head_block->dest_addr_adj, &dma_ctrl_reg)) { + LOG_ERR("Invalid destination address adjustment"); + return -EINVAL; + } + + if (!dma_channel_update_dreq_mode(cfg->channel_direction, &dma_ctrl_reg)) { + LOG_ERR("Inavlid channel direction"); + return -EINVAL; + } + + /* Cyclic is valid only when DREQ_MODE is set */ + if (cfg->cyclic && DMA_CTRL_REG_GET_FIELD(DREQ_MODE, dma_ctrl_reg) != DREQ_MODE_HW) { + LOG_ERR("Circular mode is only supported for non memory-memory transfers"); + return -EINVAL; + } + + DMA_CTRL_REG_SET_FIELD(CIRCULAR, dma_ctrl_reg, cfg->cyclic); + + if (DMA_CTRL_REG_GET_FIELD(DREQ_MODE, dma_ctrl_reg) == DREQ_MODE_SW && + DMA_CTRL_REG_GET_FIELD(AINC, dma_ctrl_reg) == ADDR_ADJ_NO_CHANGE && + DMA_CTRL_REG_GET_FIELD(BINC, dma_ctrl_reg) == ADDR_ADJ_INCR) { + /* + * Valid for memory initialization to a specific value. This process + * cannot be interrupted by other DMA channels. + */ + DMA_CTRL_REG_SET_FIELD(DMA_INIT, dma_ctrl_reg, COPY_MODE_INIT); + } else { + DMA_CTRL_REG_SET_FIELD(DMA_INIT, dma_ctrl_reg, COPY_MODE_BLOCK); + } + + dma_channel_update_req_sense(cfg->dma_slot, channel, &dma_ctrl_reg); + + regs->DMA_CTRL_REG = dma_ctrl_reg; + + /* Requested address might be changed */ + src_dst_address = cfg->head_block->source_address; + if (!dma_channel_src_addr_check_and_adjust(channel, &src_dst_address)) { + return -EINVAL; + } + + if (src_dst_address % cfg->source_data_size) { + LOG_ERR("Source address is not bus width aligned"); + return -EINVAL; + } + + regs->DMA_A_START = src_dst_address; + + src_dst_address = cfg->head_block->dest_address; + if (!dma_channel_dst_addr_check_and_adjust(channel, &src_dst_address)) { + return -EINVAL; + } + + if (src_dst_address % cfg->dest_data_size) { + LOG_ERR("Destination address is not bus width aligned"); + return -EINVAL; + } + + regs->DMA_B_START = src_dst_address; + + if (cfg->head_block->block_size % (cfg->source_data_size * cfg->source_burst_length)) { + LOG_ERR("Requested data size is not multiple of bus width"); + return -EINVAL; + } + + regs->DMA_LEN_REG = (cfg->head_block->block_size / cfg->source_data_size) - 1; + + /* Interrupt will be raised once all transfers are complete. */ + regs->DMA_INT_REG = (cfg->head_block->block_size / cfg->source_data_size) - 1; + + if ((cfg->source_handshake != cfg->dest_handshake) || + (cfg->source_handshake != 0)/*HW*/) { + LOG_ERR("Source/destination handshakes mismatch or invalid"); + return -EINVAL; + } + + dma_set_mux_request(cfg->dma_slot, channel); + + /* Designate that channel has been configured */ + data->channel_data[channel].is_dma_configured = true; + + return 0; +} + + +static int dma_smartbond_reload(const struct device *dev, uint32_t channel, uint32_t src, + uint32_t dst, size_t size) +{ + struct dma_smartbond_data *data = dev->data; + struct channel_regs *regs; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + regs = DMA_CHN2REG(channel); + + if (!data->channel_data[channel].is_dma_configured) { + LOG_ERR("Requested DMA channel should first be configured"); + return -EINVAL; + } + + if (size == 0) { + LOG_ERR("Min. transfer size is one"); + return -EINVAL; + } + + if (DMA_CTRL_REG_GET_FIELD(DMA_ON, regs->DMA_CTRL_REG)) { + LOG_ERR("Channel is busy, settings cannot be changed mid-transfer"); + return -EBUSY; + } + + if (src % data->channel_data[channel].bus_width) { + LOG_ERR("Source address is not bus width aligned"); + return -EINVAL; + } + + if (!dma_channel_src_addr_check_and_adjust(channel, &src)) { + return -EINVAL; + } + + regs->DMA_A_START = src; + + if (dst % data->channel_data[channel].bus_width) { + LOG_ERR("Destination address is not bus width aligned"); + return -EINVAL; + } + + if (!dma_channel_dst_addr_check_and_adjust(channel, &dst)) { + return -EINVAL; + } + + regs->DMA_B_START = dst; + + if (size % (data->channel_data[channel].burst_len * + data->channel_data[channel].bus_width)) { + LOG_ERR("Requested data size is not multiple of bus width"); + return -EINVAL; + } + + regs->DMA_LEN_REG = (size / data->channel_data[channel].bus_width) - 1; + + /* Interrupt will be raised once all transfers are complete. */ + regs->DMA_INT_REG = (size / data->channel_data[channel].bus_width) - 1; + + return 0; +} + +static int dma_smartbond_start(const struct device *dev, uint32_t channel) +{ + struct channel_regs *regs; + struct dma_smartbond_data *data = dev->data; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + regs = DMA_CHN2REG(channel); + + if (!data->channel_data[channel].is_dma_configured) { + LOG_ERR("Requested DMA channel should first be configured"); + return -EINVAL; + } + + /* Should return succss if the requested channel is already started. */ + if (DMA_CTRL_REG_GET_FIELD(DMA_ON, regs->DMA_CTRL_REG)) { + return 0; + } + + dma_smartbond_set_channel_status(channel, true); + + return 0; +} + +static int dma_smartbond_stop(const struct device *dev, uint32_t channel) +{ + struct channel_regs *regs; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + regs = DMA_CHN2REG(channel); + + /* + * In normal mode DMA_ON is cleared automatically. However we need to clear + * the corresponding register mask and disable NVIC if there is no other + * channel in use. + */ + dma_smartbond_set_channel_status(channel, false); + + return 0; +} + +static int dma_smartbond_suspend(const struct device *dev, uint32_t channel) +{ + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + + /* + * Freezing the DMA engine is valid for memory-to-memory operations. + * Valid memory locations are SYSRAM and/or PSRAM. + */ + LOG_WRN("DMA is freezed globally"); + + /* + * Freezing the DMA engine can be done universally and not per channel!. + * An attempt to disable the channel would result in resetting the IDX + * register next time the channel was re-enabled. + */ + GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_DMA_Msk; + + return 0; +} + +static int dma_smartbond_resume(const struct device *dev, uint32_t channel) +{ + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + + LOG_WRN("DMA is unfreezed globally"); + + /* Unfreezing the DMA engine can be done unviversally and not per channel! */ + GPREG->RESET_FREEZE_REG = GPREG_RESET_FREEZE_REG_FRZ_DMA_Msk; + + return 0; +} + +static int dma_smartbond_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + struct channel_regs *regs; + int key; + struct dma_smartbond_data *data = dev->data; + uint8_t bus_width; + uint32_t dma_ctrl_reg, dma_idx_reg, dma_len_reg; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + + if (stat == NULL) { + LOG_ERR("User should provide a valid pointer to store the status info requested"); + } + + if (!data->channel_data[channel].is_dma_configured) { + LOG_ERR("Requested DMA channel should first be configured"); + return -EINVAL; + } + + regs = DMA_CHN2REG(channel); + + /* + * The DMA is running in parallel with CPU and so it might happen that an on-going transfer + * might be completed the moment user parses the status results. Disable interrupts globally + * so there is no chance for a new transfer to be initiated from within ISR and so changing + * the channel registers values. + */ + key = irq_lock(); + + dma_ctrl_reg = regs->DMA_CTRL_REG; + dma_idx_reg = regs->DMA_IDX_REG; + dma_len_reg = regs->DMA_LEN_REG; + + /* Calculate how many byes each transfer consists of. */ + bus_width = DMA_CTRL_REG_GET_FIELD(BW, dma_ctrl_reg); + if (bus_width == BUS_WIDTH_1B) { + bus_width = 1; + } else { + bus_width <<= 1; + } + + /* Convert transfers to bytes. */ + stat->total_copied = dma_idx_reg * bus_width; + stat->pending_length = ((dma_len_reg + 1) - dma_idx_reg) * bus_width; + stat->busy = DMA_CTRL_REG_GET_FIELD(DMA_ON, dma_ctrl_reg); + stat->dir = data->channel_data[channel].dir; + + /* DMA does not support circular buffer functionality */ + stat->free = 0; + stat->read_position = 0; + stat->write_position = 0; + + irq_unlock(key); + + return 0; +} + +static int dma_smartbond_get_attribute(const struct device *dev, uint32_t type, uint32_t *value) +{ + if (value == NULL) { + LOG_ERR("User should provide a valid pointer to attribute value"); + return -EINVAL; + } + + switch (type) { + /* + * Source and destination addresses should be multiple of a channel's bus width. + * This info could be provided at runtime given that attributes of a specific + * channel could be requested. + */ + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + /* + * Buffer size should be multiple of a channel's bus width multiplied by burst length. + * This info could be provided at runtime given that attributes of a specific channel + * could be requested. + */ + case DMA_ATTR_BUFFER_SIZE_ALIGNMENT: + return -ENOSYS; + case DMA_ATTR_MAX_BLOCK_COUNT: + *value = DMA_BLOCK_COUNT; + return 0; + default: + return -EINVAL; + } +} + +static bool dma_smartbond_chan_filter(const struct device *dev, int channel, void *filter_param) +{ + uint32_t requested_channel; + + if (channel >= DMA_CHANNELS_COUNT) { + LOG_ERR("Inavlid DMA channel index"); + return -EINVAL; + } + + /* If user does not provide any channel request explicitly, return true. */ + if (filter_param == NULL) { + return true; + } + + requested_channel = *(uint32_t *)filter_param; + + if (channel == requested_channel) { + return true; + } + + return false; +} + +static struct dma_driver_api dma_smartbond_driver_api = { + .config = dma_smartbond_config, + .reload = dma_smartbond_reload, + .start = dma_smartbond_start, + .stop = dma_smartbond_stop, + .suspend = dma_smartbond_suspend, + .resume = dma_smartbond_resume, + .get_status = dma_smartbond_get_status, + .get_attribute = dma_smartbond_get_attribute, + .chan_filter = dma_smartbond_chan_filter +}; + +static void smartbond_dma_isr(const void *arg) +{ + uint16_t dma_int_status_reg; + int i; + struct channel_regs *regs; + struct dma_smartbond_data *data = ((const struct device *)arg)->data; + + /* + * A single interrupt line is generated for all channels and so each channel + * should be parsed separately. + */ + for (i = 0, dma_int_status_reg = DMA->DMA_INT_STATUS_REG; + i < DMA_CHANNELS_COUNT && dma_int_status_reg != 0; ++i, dma_int_status_reg >>= 1) { + /* Check if the selected channel has raised the interrupt line */ + if (dma_int_status_reg & BIT(0)) { + + regs = DMA_CHN2REG(i); + /* + * Should be valid if callbacks are explicitly enabled by users. + * Interrupt should be triggered only when the total size of + * bytes has been transferred. Bus errors cannot raise interrupts. + */ + if (data->channel_data[i].cb) { + data->channel_data[i].cb((const struct device *)arg, + data->channel_data[i].user_data, i, DMA_STATUS_COMPLETE); + } + /* Channel line should be cleared otherwise ISR will keep firing! */ + DMA->DMA_CLEAR_INT_REG = BIT(i); + } + } +} + +static int dma_smartbond_init(const struct device *dev) +{ +#ifdef CONFIG_DMA_64BIT + LOG_ERR("64-bit addressing mode is not supported\n"); + return -ENOSYS; +#endif + + int idx; + struct dma_smartbond_data *data; + + data = dev->data; + data->dma_ctx.magic = DMA_MAGIC; + data->dma_ctx.dma_channels = DMA_CHANNELS_COUNT; + data->dma_ctx.atomic = data->channels_atomic; + + /* Make sure that all channels are disabled. */ + for (idx = 0; idx < DMA_CHANNELS_COUNT; idx++) { + dma_smartbond_set_channel_status(idx, false); + data->channel_data[idx].is_dma_configured = false; + } + + IRQ_CONNECT(SMARTBOND_IRQN, SMARTBOND_IRQ_PRIO, smartbond_dma_isr, + DEVICE_DT_INST_GET(0), 0); + + return 0; +} + +#define SMARTBOND_DMA_INIT(inst) \ + BUILD_ASSERT((inst) == 0, "multiple instances are not supported"); \ + \ + static struct dma_smartbond_data dma_smartbond_data_ ## inst; \ + \ + DEVICE_DT_INST_DEFINE(0, dma_smartbond_init, NULL, \ + &dma_smartbond_data_ ## inst, NULL, \ + POST_KERNEL, \ + CONFIG_DMA_INIT_PRIORITY, \ + &dma_smartbond_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SMARTBOND_DMA_INIT) diff --git a/dts/bindings/dma/renesas,smartbond-dma.yaml b/dts/bindings/dma/renesas,smartbond-dma.yaml new file mode 100644 index 00000000000..0845df77463 --- /dev/null +++ b/dts/bindings/dma/renesas,smartbond-dma.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +include: dma-controller.yaml + +description: Renesas Smartbond(tm) DMA + +compatible: "renesas,smartbond-dma" + +properties: + reg: + required: true + + interrupts: + required: true + + block-count: + required: true + type: int + const: 1 + description: Number of block counts supported diff --git a/include/zephyr/drivers/dma/dma_smartbond.h b/include/zephyr/drivers/dma/dma_smartbond.h new file mode 100644 index 00000000000..c154488039d --- /dev/null +++ b/include/zephyr/drivers/dma/dma_smartbond.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DMA_SMARTBOND_H_ +#define DMA_SMARTBOND_H_ + +/** + * @brief Vendror-specific DMA peripheral triggering sources. + * + * A valid triggering source should be provided when DMA + * is configured for peripheral to peripheral or memory to peripheral + * transactions. + */ +enum dma_smartbond_trig_mux { + DMA_SMARTBOND_TRIG_MUX_SPI = 0x0, + DMA_SMARTBOND_TRIG_MUX_SPI2 = 0x1, + DMA_SMARTBOND_TRIG_MUX_UART = 0x2, + DMA_SMARTBOND_TRIG_MUX_UART2 = 0x3, + DMA_SMARTBOND_TRIG_MUX_I2C = 0x4, + DMA_SMARTBOND_TRIG_MUX_I2C2 = 0x5, + DMA_SMARTBOND_TRIG_MUX_USB = 0x6, + DMA_SMARTBOND_TRIG_MUX_UART3 = 0x7, + DMA_SMARTBOND_TRIG_MUX_PCM = 0x8, + DMA_SMARTBOND_TRIG_MUX_SRC = 0x9, + DMA_SMARTBOND_TRIG_MUX_GPADC = 0xC, + DMA_SMARTBOND_TRIG_MUX_SDADC = 0xD, + DMA_SMARTBOND_TRIG_MUX_NONE = 0xF +}; + +#endif /* DMA_SMARTBOND_H_ */ From dd1371da8b64ed79036e7bdec4c4d78190ba4f7d Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Mon, 9 Oct 2023 10:39:24 +0300 Subject: [PATCH 3287/4498] dts: renesas: smartbond: Support the DMA engine. Update DTS and board configurations to support the DMA accelerator. Signed-off-by: Ioannis Karachalios --- boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml | 1 + dts/arm/renesas/smartbond/da1469x.dtsi | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml index edfaff84876..e31a2749002 100644 --- a/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml +++ b/boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml @@ -17,4 +17,5 @@ supported: - usb_device - rtc - crypto + - dma vendor: renesas diff --git a/dts/arm/renesas/smartbond/da1469x.dtsi b/dts/arm/renesas/smartbond/da1469x.dtsi index ecf2f4df63a..6916b2b804c 100644 --- a/dts/arm/renesas/smartbond/da1469x.dtsi +++ b/dts/arm/renesas/smartbond/da1469x.dtsi @@ -303,6 +303,16 @@ interrupts = <15 0>, <21 0>; status = "disabled"; }; + + dma: dma@50040800 { + compatible = "renesas,smartbond-dma"; + reg = <0x50040800 0x110>; + interrupts = <1 0>; + status = "disabled"; + dma-channels = <8>; + block-count = <1>; + #dma-cells = <0>; + }; }; }; From 96a4300c6f7bb99b4734ad060ae69ab950019c1c Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Tue, 24 Oct 2023 20:26:47 +0300 Subject: [PATCH 3288/4498] tests: drivers: dma: Control testcases via Kconfig Added Kconfig to control BURST16 and board config for da1469x_dk_pro. Signed-off-by: Ioannis Karachalios --- tests/drivers/dma/chan_blen_transfer/Kconfig | 4 ++++ .../chan_blen_transfer/boards/da1469x_dk_pro.conf | 1 + .../boards/da1469x_dk_pro.overlay | 9 +++++++++ .../drivers/dma/chan_blen_transfer/src/test_dma.c | 15 +++++++++++++++ 4 files changed, 29 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.conf create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/Kconfig b/tests/drivers/dma/chan_blen_transfer/Kconfig index 7867be5a629..748f380b71e 100644 --- a/tests/drivers/dma/chan_blen_transfer/Kconfig +++ b/tests/drivers/dma/chan_blen_transfer/Kconfig @@ -21,3 +21,7 @@ config DMA_LOOP_TRANSFER_SRAM_SECTION config DMA_LOOP_TRANSFER_NUMBER_OF_DMAS int "Number of DMAs to test" default 1 + +config DMA_TRANSFER_BURST16 + bool "Enable loop transfers of 16-beat bursts" + default y diff --git a/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.conf b/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.conf new file mode 100644 index 00000000000..9664ee7c621 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.conf @@ -0,0 +1 @@ +CONFIG_DMA_TRANSFER_BURST16=n diff --git a/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.overlay b/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.overlay new file mode 100644 index 00000000000..eca3c9dc752 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/da1469x_dk_pro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + test_dma0: &dma { + status = "okay"; +}; diff --git a/tests/drivers/dma/chan_blen_transfer/src/test_dma.c b/tests/drivers/dma/chan_blen_transfer/src/test_dma.c index d0fa561f37b..312e7666aec 100644 --- a/tests/drivers/dma/chan_blen_transfer/src/test_dma.c +++ b/tests/drivers/dma/chan_blen_transfer/src/test_dma.c @@ -106,6 +106,7 @@ static int test_task(const struct device *dma, uint32_t chan_id, uint32_t blen) #define DMA_NAME(i, _) test_dma##i #define DMA_LIST LISTIFY(CONFIG_DMA_LOOP_TRANSFER_NUMBER_OF_DMAS, DMA_NAME, (,)) +#if CONFIG_DMA_TRANSFER_BURST16 #define TEST_TASK(dma_name) \ ZTEST(dma_m2m, test_##dma_name##_m2m_chan0_burst8) \ { \ @@ -130,5 +131,19 @@ static int test_task(const struct device *dma, uint32_t chan_id, uint32_t blen) const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \ zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_1, 16) == TC_PASS)); \ } +#else +#define TEST_TASK(dma_name) \ + ZTEST(dma_m2m, test_##dma_name##_m2m_chan0_burst8) \ + { \ + const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \ + zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_0, 8) == TC_PASS)); \ + } \ + \ + ZTEST(dma_m2m, test_##dma_name##_m2m_chan1_burst8) \ + { \ + const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \ + zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_1, 8) == TC_PASS)); \ + } +#endif FOR_EACH(TEST_TASK, (), DMA_LIST); From fbee62d9e32a6caae99949cd4b32af9133a9008a Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Fri, 27 Oct 2023 11:39:34 +0300 Subject: [PATCH 3289/4498] dts: bindings: adxl372: move int1-gpios to common The `int1-gpios` property is common for both spi and i2c implementations of adxl372. Therefore move it to `adi,adxl372-common.yaml` Signed-off-by: Antoniu Miclaus --- dts/bindings/sensor/adi,adxl372-common.yaml | 7 +++++++ dts/bindings/sensor/adi,adxl372-i2c.yaml | 8 -------- dts/bindings/sensor/adi,adxl372-spi.yaml | 8 -------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/dts/bindings/sensor/adi,adxl372-common.yaml b/dts/bindings/sensor/adi,adxl372-common.yaml index 6c666dce8a9..547337fc70a 100644 --- a/dts/bindings/sensor/adi,adxl372-common.yaml +++ b/dts/bindings/sensor/adi,adxl372-common.yaml @@ -56,3 +56,10 @@ properties: - 2 - 3 - 4 + + int1-gpios: + type: phandle-array + description: | + The INT1 signal defaults to active high as produced by the + sensor. The property value should ensure the flags properly + describe the signal that is presented to the driver. diff --git a/dts/bindings/sensor/adi,adxl372-i2c.yaml b/dts/bindings/sensor/adi,adxl372-i2c.yaml index f6f0ac197ed..1e732b1f9d4 100644 --- a/dts/bindings/sensor/adi,adxl372-i2c.yaml +++ b/dts/bindings/sensor/adi,adxl372-i2c.yaml @@ -6,11 +6,3 @@ description: ADXL372 3-axis high-g accelerometer, accessed through I2C bus compatible: "adi,adxl372" include: ["i2c-device.yaml", "adi,adxl372-common.yaml"] - -properties: - int1-gpios: - type: phandle-array - description: | - The INT1 signal defaults to active high as produced by the - sensor. The property value should ensure the flags properly - describe the signal that is presented to the driver. diff --git a/dts/bindings/sensor/adi,adxl372-spi.yaml b/dts/bindings/sensor/adi,adxl372-spi.yaml index 7d6863c3118..2cb4e674522 100644 --- a/dts/bindings/sensor/adi,adxl372-spi.yaml +++ b/dts/bindings/sensor/adi,adxl372-spi.yaml @@ -7,11 +7,3 @@ description: ADXL372 3-axis high-g accelerometer, accessed through SPI bus compatible: "adi,adxl372" include: ["spi-device.yaml", "adi,adxl372-common.yaml"] - -properties: - int1-gpios: - type: phandle-array - description: | - The INT1 signal defaults to active high as produced by the - sensor. The property value should ensure the flags properly - describe the signal that is presented to the driver. From f93243b68feb253e7b0f3cd9c0da344e72d63e35 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Tue, 24 Oct 2023 16:59:10 +0200 Subject: [PATCH 3290/4498] ipc: Remove nocopy feature from icmsg_me backend Remove nocopy feature from icmsg_me backend. The backend is not meant to be used to send big data chunks thus no-copy feature is removed. If one wants to use no-copy it is recommended to use icmsg_me only for control messages while allocator will shall be written seperately. Signed-off-by: Emil Obalski --- include/zephyr/ipc/icmsg.h | 145 ------------------ include/zephyr/ipc/icmsg_me.h | 112 -------------- .../subsys/ipc/ipc_service/icmsg_me/prj.conf | 1 - .../ipc/ipc_service/icmsg_me/remote/prj.conf | 1 - .../ipc_service/icmsg_me/remote/src/main.c | 39 +---- .../ipc/ipc_service/icmsg_me/src/main.c | 40 +---- .../ipc/ipc_service/backends/Kconfig.icmsg_me | 10 -- .../backends/ipc_icmsg_me_follower.c | 61 -------- .../backends/ipc_icmsg_me_initiator.c | 57 ------- subsys/ipc/ipc_service/lib/Kconfig | 9 -- subsys/ipc/ipc_service/lib/Kconfig.icmsg | 7 - subsys/ipc/ipc_service/lib/icmsg_me.c | 118 -------------- 12 files changed, 14 insertions(+), 586 deletions(-) diff --git a/include/zephyr/ipc/icmsg.h b/include/zephyr/ipc/icmsg.h index cdd1cb064d1..099c6265acd 100644 --- a/include/zephyr/ipc/icmsg.h +++ b/include/zephyr/ipc/icmsg.h @@ -134,151 +134,6 @@ int icmsg_send(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data, const void *msg, size_t len); -/** @brief Get an empty TX buffer to be sent using @ref icmsg_send_nocopy - * - * This function can be called to get an empty TX buffer so that the - * application can directly put its data into the sending buffer avoiding copy - * performed by the icmsg library. - * - * It is the application responsibility to correctly fill the allocated TX - * buffer with data and passing correct parameters to @ref - * icmsg_send_nocopy function to perform data no-copy-send mechanism. - * - * The size parameter can be used to request a buffer with a certain size: - * - if the size can be accommodated the function returns no errors and the - * buffer is allocated - * - if the requested size is too big, the function returns -ENOMEM and the - * the buffer is not allocated. - * - if the requested size is '0' the buffer is allocated with the maximum - * allowed size. - * - * In all the cases on return the size parameter contains the maximum size for - * the returned buffer. - * - * When the function returns no errors, the buffer is intended as allocated - * and it is released under one of two conditions: (1) when sending the buffer - * using @ref icmsg_send_nocopy (and in this case the buffer is automatically - * released by the backend), (2) when using @ref icmsg_drop_tx_buffer on a - * buffer not sent. - * - * @param[in] conf Structure containing configuration parameters for the icmsg - * instance. - * @param[inout] dev_data Structure containing run-time data used by the icmsg - * instance. - * @param[out] data Pointer to the empty TX buffer. - * @param[inout] size Pointer to store the requested TX buffer size. If the - * function returns -ENOMEM, this parameter returns the - * maximum allowed size. - * - * @retval -ENOBUFS when there are no TX buffers available. - * @retval -EALREADY when a buffer was already claimed and not yet released. - * @retval -ENOMEM when the requested size is too big (and the size parameter - * contains the maximum allowed size). - * - * @retval 0 on success. - */ -int icmsg_get_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - void **data, size_t *size); - -/** @brief Drop and release a TX buffer - * - * Drop and release a TX buffer. It is possible to drop only TX buffers - * obtained by using @ref icmsg_get_tx_buffer. - * - * @param[in] conf Structure containing configuration parameters for the icmsg - * instance. - * @param[inout] dev_data Structure containing run-time data used by the icmsg - * instance. - * @param[in] data Pointer to the TX buffer. - * - * @retval -EALREADY when the buffer was already dropped. - * @retval -ENXIO when the buffer was not obtained using @ref - * ipc_service_get_tx_buffer - * - * @retval 0 on success. - */ -int icmsg_drop_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data); - -/** @brief Send a message from a buffer obtained by @ref icmsg_get_tx_buffer - * to the remote icmsg instance. - * - * This is equivalent to @ref icmsg_send but in this case the TX buffer must - * have been obtained by using @ref icmsg_get_tx_buffer. - * - * The API user has to take the responsibility for getting the TX buffer using - * @ref icmsg_get_tx_buffer and filling the TX buffer with the data. - * - * After the @ref icmsg_send_nocopy function is issued the TX buffer is no - * more owned by the sending task and must not be touched anymore unless the - * function fails and returns an error. - * - * If this function returns an error, @ref icmsg_drop_tx_buffer can be used - * to drop the TX buffer. - * - * @param[in] conf Structure containing configuration parameters for the icmsg - * instance. - * @param[inout] dev_data Structure containing run-time data used by the icmsg - * instance. - * @param[in] msg Pointer to a buffer containing data to send. - * @param[in] len Size of data in the @p msg buffer. - * - * - * @return Size of sent data on success. - * @retval -EBUSY when the instance has not finished handshake with the remote - * instance. - * @retval -ENODATA when the requested data to send is empty. - * @retval -EBADMSG when the requested data to send is too big. - * @retval -ENXIO when the buffer was not obtained using @ref - * ipc_service_get_tx_buffer - * @retval other errno codes from dependent modules. - */ -int icmsg_send_nocopy(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *msg, size_t len); - -#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX -/** @brief Hold RX buffer to be used outside of the received callback. - * - * @param[in] conf Structure containing configuration parameters for the icmsg - * instance. - * @param[inout] dev_data Structure containing run-time data used by the icmsg - * instance. - * @param[in] data Pointer to the buffer to be held. - * - * @retval 0 on success. - * @retval -EBUSY when the instance has not finished handshake with the remote - * instance. - * @retval -EINVAL when the @p data argument does not point to a valid RX - * buffer. - * @retval -EALREADY when the buffer is already held. - */ -int icmsg_hold_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data); - -/** @brief Release RX buffer for future use. - * - * @param[in] conf Structure containing configuration parameters for the icmsg - * instance. - * @param[inout] dev_data Structure containing run-time data used by the icmsg - * instance. - * @param[in] data Pointer to the buffer to be released. - * - * @retval 0 on success. - * @retval -EBUSY when the instance has not finished handshake with the remote - * instance. - * @retval -EINVAL when the @p data argument does not point to a valid RX - * buffer. - * @retval -EALREADY when the buffer is not held. - */ -int icmsg_release_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data); -#endif - /** * @} */ diff --git a/include/zephyr/ipc/icmsg_me.h b/include/zephyr/ipc/icmsg_me.h index 554f5785ba8..9736b0148c6 100644 --- a/include/zephyr/ipc/icmsg_me.h +++ b/include/zephyr/ipc/icmsg_me.h @@ -247,118 +247,6 @@ int icmsg_me_send(const struct icmsg_config_t *conf, struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, const void *msg, size_t len); -/** @brief Get an empty TX buffer to be sent using @ref icmsg_me_send_nocopy - * - * This function is a wrapper around @ref icmsg_get_tx_buffer aligning buffer - * size and pointers to fit header required by the multi-endpoint feature. - * It shares all properites and usage scenarios with @ref icmsg_get_tx_buffer. - * - * @param[in] conf Structure containing configuration parameters for the - & underlying icmsg instance. - * @param[inout] data Structure containing run-time data used by the icmsg_me - * instance. The structure is initialized with - * @ref icmsg_me_init and its content must be preserved - * while the icmsg_me instance is active. - * @param[out] buffer Pointer to the empty TX buffer. - * @param[inout] size Pointer to store the requested TX buffer size. If the - * function returns -ENOMEM, this parameter returns the - * maximum allowed size. - * @param[in] wait Timeout value to wait for a free buffer acceptable by - * the function caller. Only K_NO_WAIT is supported by icmsg. - * - * @retval 0 on success. - * @retval -ENOTSUP when requested unsupported @p wait timeout. - * @retval -ENOBUFS when there are no TX buffers available. - * @retval -ENOMEM when the requested size is too big (and the size parameter - * contains the maximum allowed size). - * @retval other errno codes from dependent modules. - */ -int icmsg_me_get_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, - void **buffer, uint32_t *size, k_timeout_t wait); - -/** @brief Drop and release a TX buffer - * - * This function is a wrapper around @ref icmsg_drop_tx_buffer aligning buffer - * pointer to fit header required by the multi-endpoint feature. This function - * shares all properties and usage scenarios with @ref icmsg_drop_tx_buffer. - * - * @param[in] conf Structure containing configuration parameters for the - * underlying icmsg instance. - * @param[inout] data Structure containing run-time data used by the icmsg_me - * instance. The structure is initialized with - * @ref icmsg_me_init and its content must be preserved - * while the icmsg_me instance is active. - * @param[in] buffer Pointer to the TX buffer obtained with - * @ref icmsg_me_get_tx_buffer. - * - * @retval 0 on success. - * @retval other errno codes from dependent modules. - */ -int icmsg_me_drop_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, - const void *buffer); - -/** @brief Send a message from a buffer obtained by @ref icmsg_me_get_tx_buffer - * to the remote icmsg_me instance. - * - * This function is a wrapper around @ref icmsg_send_nocopy aligning buffer - * size and pointer to fit header required by the multi-endpoint feature. This - * function shares all properties and usage scenarios with - * @ref icmsg_send_nocopy. - * - * @param[in] conf Structure containing configuration parameters for the - * underlying icmsg instance. - * @param[inout] data Structure containing run-time data used by the icmsg_me - * instance. The structure is initialized with - * @ref icmsg_me_init and its content must be preserved - * while the icmsg_me instance is active. - * @param[in] id Id of the endpoint to use. - * @param[in] msg Pointer to a buffer containing data to send. - * @param[in] len Size of data in the @p msg buffer. - * - * - * @return Size of sent data on success. - * @retval other errno codes from dependent modules. - */ -int icmsg_me_send_nocopy(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, - const void *msg, size_t len); - -#ifdef CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX -/** @brief Hold RX buffer to be used outside of the received callback. - * - * @param[in] conf Structure containing configuration parameters for the - * underlying icmsg instance. - * @param[inout] data Structure containing run-time data used by the icmsg_me - * instance. The structure is initialized with - * @ref icmsg_me_init and its content must be preserved - * while the icmsg_me instance is active. - * @param[in] buffer Pointer to the buffer to be held. - * - * @retval 0 on success. - * @retval other errno codes from dependent modules. - */ -int icmsg_me_hold_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, void *buffer); - -/** @brief Release RX buffer for future use. - * - * @param[in] conf Structure containing configuration parameters for the - * underlying icmsg instance. - * @param[inout] data Structure containing run-time data used by the icmsg_me - * instance. The structure is initialized with - * @ref icmsg_me_init and its content must be preserved - * while the icmsg_me instance is active. - * @param[in] buffer Pointer to the buffer to be released. - * - * @retval 0 on success. - * @retval other errno codes from dependent modules. - */ -int icmsg_me_release_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, void *buffer); -#endif /* CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX */ - /** * @} */ diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf b/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf index 5feb10b3120..4c5326d1397 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf +++ b/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf @@ -1,7 +1,6 @@ CONFIG_PRINTK=y CONFIG_IPC_SERVICE=y -CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX=y CONFIG_MBOX=y CONFIG_LOG=y diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf b/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf index 5feb10b3120..4c5326d1397 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf +++ b/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf @@ -1,7 +1,6 @@ CONFIG_PRINTK=y CONFIG_IPC_SERVICE=y -CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX=y CONFIG_MBOX=y CONFIG_LOG=y diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c b/samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c index 387f962af95..9b288f8a6a1 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c +++ b/samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c @@ -18,7 +18,7 @@ K_THREAD_STACK_DEFINE(ipc1_stack, STACKSIZE); static volatile uint8_t ipc0A_received_data; static volatile uint8_t ipc0B_received_data; -static const void *ipc1_received_data; +static volatile uint8_t ipc1_received_data; static K_SEM_DEFINE(ipc0A_bound_sem, 0, 1); static K_SEM_DEFINE(ipc0B_bound_sem, 0, 1); @@ -182,11 +182,8 @@ K_THREAD_DEFINE(ipc0B_thread_id, STACKSIZE, ipc0B_entry, NULL, NULL, NULL, PRIOR /* * ==> THREAD 1 (IPC instance 1) <== * - * NOTE: This instance is using the NOCOPY copability of the backend. */ -static struct ipc_ept ipc1_ept; - static void ipc1_ept_bound(void *priv) { k_sem_give(&ipc1_bound_sem); @@ -194,10 +191,9 @@ static void ipc1_ept_bound(void *priv) static void ipc1_ept_recv(const void *data, size_t len, void *priv) { - ipc_service_hold_rx_buffer(&ipc1_ept, (void *)data); - ipc1_received_data = data; + ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc1_data_sem); + k_sem_give(&ipc0B_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { @@ -216,6 +212,7 @@ static void ipc1_entry(void *dummy0, void *dummy1, void *dummy2) const struct device *ipc1_instance; unsigned char message = 0; + struct ipc_ept ipc1_ept; int ret; printk("IPC-service REMOTE [INST 1] demo started\n"); @@ -237,38 +234,16 @@ static void ipc1_entry(void *dummy0, void *dummy1, void *dummy2) k_sem_take(&ipc1_bound_sem, K_FOREVER); while (message < 99) { - void *tx_buffer; - uint32_t tx_buffer_size = sizeof(message); - k_sem_take(&ipc1_data_sem, K_FOREVER); - message = *((uint8_t *) ipc1_received_data); - - ret = ipc_service_release_rx_buffer(&ipc1_ept, (void *) ipc1_received_data); - if (ret < 0) { - printk("release_rx_buffer() failed with ret %d\n", ret); - break; - } + message = ipc1_received_data; printk("REMOTE [1]: %d\n", message); message++; - ret = ipc_service_get_tx_buffer(&ipc1_ept, &tx_buffer, &tx_buffer_size, K_NO_WAIT); + ret = ipc_service_send(&ipc1_ept, &message, sizeof(message)); if (ret < 0) { - printk("get_tx_buffer(%u) failed with ret %d\n", sizeof(message), ret); - break; - } - if (tx_buffer_size != sizeof(message)) { - printk("get_tx_buffer modified buffer size to unexpected value %u\n", - tx_buffer_size); - break; - } - - *((uint8_t *) tx_buffer) = message; - - ret = ipc_service_send_nocopy(&ipc1_ept, tx_buffer, tx_buffer_size); - if (ret < 0) { - printk("send_message_nocopy(%u) failed with ret %d\n", message, ret); + printk("send_message(%d) failed with ret %d\n", message, ret); break; } } diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/src/main.c b/samples/subsys/ipc/ipc_service/icmsg_me/src/main.c index 92b3a5569ef..78d7af05288 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/src/main.c +++ b/samples/subsys/ipc/ipc_service/icmsg_me/src/main.c @@ -18,7 +18,7 @@ K_THREAD_STACK_DEFINE(ipc1_stack, STACKSIZE); static volatile uint8_t ipc0A_received_data; static volatile uint8_t ipc0B_received_data; -static const void *ipc1_received_data; +static volatile uint8_t ipc1_received_data; static K_SEM_DEFINE(ipc0A_bound_sem, 0, 1); static K_SEM_DEFINE(ipc0B_bound_sem, 0, 1); @@ -179,12 +179,8 @@ K_THREAD_DEFINE(ipc0B_thread_id, STACKSIZE, ipc0B_entry, NULL, NULL, NULL, PRIOR /* * ==> THREAD 1 (IPC instance 1) <== - * - * NOTE: This instance is using the NOCOPY copability of the backend. */ -static struct ipc_ept ipc1_ept; - static void ipc1_ept_bound(void *priv) { k_sem_give(&ipc1_bound_sem); @@ -192,10 +188,9 @@ static void ipc1_ept_bound(void *priv) static void ipc1_ept_recv(const void *data, size_t len, void *priv) { - ipc_service_hold_rx_buffer(&ipc1_ept, (void *)data); - ipc1_received_data = data; + ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc1_data_sem); + k_sem_give(&ipc0B_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { @@ -214,6 +209,7 @@ static void ipc1_entry(void *dummy0, void *dummy1, void *dummy2) const struct device *ipc1_instance; unsigned char message = 0; + struct ipc_ept ipc1_ept; int ret; printk("IPC-service HOST [INST 1] demo started\n"); @@ -242,36 +238,14 @@ static void ipc1_entry(void *dummy0, void *dummy1, void *dummy2) k_sleep(K_MSEC(1000)); while (message < 100) { - void *tx_buffer; - uint32_t tx_buffer_size = sizeof(message); - - ret = ipc_service_get_tx_buffer(&ipc1_ept, &tx_buffer, &tx_buffer_size, K_NO_WAIT); - if (ret < 0) { - printk("get_tx_buffer(%u) failed with ret %d\n", sizeof(message), ret); - break; - } - if (tx_buffer_size != sizeof(message)) { - printk("get_tx_buffer modified buffer size to unexpected value %u\n", - tx_buffer_size); - break; - } - - *((uint8_t *) tx_buffer) = message; - - ret = ipc_service_send_nocopy(&ipc1_ept, tx_buffer, tx_buffer_size); + ret = ipc_service_send(&ipc1_ept, &message, sizeof(message)); if (ret < 0) { - printk("send_message_nocopy(%u) failed with ret %d\n", message, ret); + printk("send_message(%d) failed with ret %d\n", message, ret); break; } k_sem_take(&ipc1_data_sem, K_FOREVER); - message = *((uint8_t *) ipc1_received_data); - - ret = ipc_service_release_rx_buffer(&ipc1_ept, (void *) ipc1_received_data); - if (ret < 0) { - printk("release_rx_buffer() failed with ret %d\n", ret); - break; - } + message = ipc1_received_data; printk("HOST [1]: %d\n", message); message++; diff --git a/subsys/ipc/ipc_service/backends/Kconfig.icmsg_me b/subsys/ipc/ipc_service/backends/Kconfig.icmsg_me index 0513719cc98..e348984fb62 100644 --- a/subsys/ipc/ipc_service/backends/Kconfig.icmsg_me +++ b/subsys/ipc/ipc_service/backends/Kconfig.icmsg_me @@ -28,14 +28,4 @@ config IPC_SERVICE_BACKEND_ICMSG_ME_EP_NAME_LEN Maximal length of a string used to discover endpoints between the initiator and the follower. -config IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX - bool "Nocopy feature for receive path" - select IPC_SERVICE_ICMSG_ME_NOCOPY_RX - help - Enable nocopy feature for receive path of multiendpoint icmsg - ipc_service backend. This features enables functions to hold and - release rx buffer by the ipc_service API user. It also creates - performance and memory overhead so it is recommended to disable - this feature if unused by the API user. - endif # IPC_SERVICE_BACKEND_ICMSG_ME_INITIATOR || IPC_SERVICE_BACKEND_ICMSG_ME_FOLLOWER diff --git a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c index df27aaedcbb..8b0944c840f 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c +++ b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c @@ -260,71 +260,10 @@ static int send(const struct device *instance, void *token, user_len); } -static int get_tx_buffer(const struct device *instance, void *token, - void **data, uint32_t *user_len, k_timeout_t wait) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_get_tx_buffer(conf, &dev_data->icmsg_me_data, data, - user_len, wait); -} - -static int drop_tx_buffer(const struct device *instance, void *token, - const void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_drop_tx_buffer(conf, &dev_data->icmsg_me_data, data); -} - -static int send_nocopy(const struct device *instance, void *token, - const void *data, size_t len) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - icmsg_me_ept_id_t *id = token; - - if (*id == INVALID_EPT_ID) { - return -ENOTCONN; - } - - return icmsg_me_send_nocopy(conf, &dev_data->icmsg_me_data, *id, - data, len); -} - -#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX -int hold_rx_buffer(const struct device *instance, void *token, void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_hold_rx_buffer(conf, &dev_data->icmsg_me_data, data); -} - -int release_rx_buffer(const struct device *instance, void *token, void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_release_rx_buffer(conf, &dev_data->icmsg_me_data, data); -} -#endif /* CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX */ - const static struct ipc_service_backend backend_ops = { .open_instance = open, .register_endpoint = register_ept, .send = send, - - .get_tx_buffer = get_tx_buffer, - .drop_tx_buffer = drop_tx_buffer, - .send_nocopy = send_nocopy, - -#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX - .hold_rx_buffer = hold_rx_buffer, - .release_rx_buffer = release_rx_buffer, -#endif }; static int backend_init(const struct device *instance) diff --git a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c index da6912c8388..2699d3b6db6 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c +++ b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c @@ -166,67 +166,10 @@ static int send(const struct device *instance, void *token, return icmsg_me_send(conf, &dev_data->icmsg_me_data, *id, msg, len); } -static int get_tx_buffer(const struct device *instance, void *token, - void **data, uint32_t *user_len, k_timeout_t wait) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_get_tx_buffer(conf, &dev_data->icmsg_me_data, data, - user_len, wait); -} - -static int drop_tx_buffer(const struct device *instance, void *token, - const void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_drop_tx_buffer(conf, &dev_data->icmsg_me_data, data); -} - -static int send_nocopy(const struct device *instance, void *token, - const void *data, size_t len) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - icmsg_me_ept_id_t *id = token; - - return icmsg_me_send_nocopy(conf, &dev_data->icmsg_me_data, *id, - data, len); -} - -#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX -int hold_rx_buffer(const struct device *instance, void *token, void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_hold_rx_buffer(conf, &dev_data->icmsg_me_data, data); -} - -int release_rx_buffer(const struct device *instance, void *token, void *data) -{ - const struct icmsg_config_t *conf = instance->config; - struct backend_data_t *dev_data = instance->data; - - return icmsg_me_release_rx_buffer(conf, &dev_data->icmsg_me_data, data); -} -#endif /* CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX */ - const static struct ipc_service_backend backend_ops = { .open_instance = open, .register_endpoint = register_ept, .send = send, - - .get_tx_buffer = get_tx_buffer, - .drop_tx_buffer = drop_tx_buffer, - .send_nocopy = send_nocopy, - -#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX - .hold_rx_buffer = hold_rx_buffer, - .release_rx_buffer = release_rx_buffer, -#endif }; static int backend_init(const struct device *instance) diff --git a/subsys/ipc/ipc_service/lib/Kconfig b/subsys/ipc/ipc_service/lib/Kconfig index f2b4d8ae210..6bd57ab15aa 100644 --- a/subsys/ipc/ipc_service/lib/Kconfig +++ b/subsys/ipc/ipc_service/lib/Kconfig @@ -36,12 +36,3 @@ config IPC_SERVICE_ICMSG_ME select EVENTS help Multi-endpoint functionality for the icmsg library - -config IPC_SERVICE_ICMSG_ME_NOCOPY_RX - bool - depends on IPC_SERVICE_ICMSG_ME - select IPC_SERVICE_ICMSG_NOCOPY_RX - help - Enable nocopy feature for receiving path of the multi-endpoint - feature of the icmsg library. This features might be used by backends - based on multi-endpoint icmsg. diff --git a/subsys/ipc/ipc_service/lib/Kconfig.icmsg b/subsys/ipc/ipc_service/lib/Kconfig.icmsg index e8f92a945a3..8f1a380a18f 100644 --- a/subsys/ipc/ipc_service/lib/Kconfig.icmsg +++ b/subsys/ipc/ipc_service/lib/Kconfig.icmsg @@ -1,13 +1,6 @@ # Copyright (c) 2022 Nordic Semiconductor (ASA) # SPDX-License-Identifier: Apache-2.0 -config IPC_SERVICE_ICMSG_NOCOPY_RX - bool - depends on IPC_SERVICE_ICMSG - help - Enable nocopy feature for receiving path of the icmsg library that - might be used by backends based on icmsg. - config IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC bool "Synchronize access to shared memory" default y diff --git a/subsys/ipc/ipc_service/lib/icmsg_me.c b/subsys/ipc/ipc_service/lib/icmsg_me.c index 870dca0d483..24e3ba6514e 100644 --- a/subsys/ipc/ipc_service/lib/icmsg_me.c +++ b/subsys/ipc/ipc_service/lib/icmsg_me.c @@ -20,11 +20,6 @@ static void *icmsg_buffer_to_user_buffer(const void *icmsg_buffer) return (void *)(((char *)icmsg_buffer) + HEADER_SIZE); } -static void *user_buffer_to_icmsg_buffer(const void *user_buffer) -{ - return (void *)(((char *)user_buffer) - HEADER_SIZE); -} - static size_t icmsg_buffer_len_to_user_buffer_len(size_t icmsg_buffer_len) { return icmsg_buffer_len - HEADER_SIZE; @@ -202,116 +197,3 @@ int icmsg_me_send(const struct icmsg_config_t *conf, return sent_bytes; } - -static size_t get_buffer_length_to_pass(size_t icmsg_buffer_len) -{ - if (icmsg_buffer_len >= HEADER_SIZE) { - return icmsg_buffer_len_to_user_buffer_len(icmsg_buffer_len); - } else { - return 0; - } -} - -int icmsg_me_get_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, - void **buffer, uint32_t *user_len, k_timeout_t wait) -{ - void *icmsg_buffer; - int r; - size_t icmsg_len; - - if (!K_TIMEOUT_EQ(wait, K_NO_WAIT)) { - return -ENOTSUP; - } - - if (*user_len) { - icmsg_len = user_buffer_len_to_icmsg_buffer_len(*user_len); - } else { - icmsg_len = 0; - } - - r = icmsg_get_tx_buffer(conf, &data->icmsg_data, - &icmsg_buffer, &icmsg_len); - if (r == -ENOMEM) { - *user_len = get_buffer_length_to_pass(icmsg_len); - return -ENOMEM; - } - - if (r < 0) { - return r; - } - - /* If requested max buffer length (*len == 0) allocated buffer might be - * shorter than HEADER_SIZE. In such circumstances drop the buffer - * and return error. - */ - *user_len = get_buffer_length_to_pass(icmsg_len); - - if (!(*user_len)) { - r = icmsg_drop_tx_buffer(conf, &data->icmsg_data, icmsg_buffer); - __ASSERT_NO_MSG(!r); - return -ENOBUFS; - } - - *buffer = icmsg_buffer_to_user_buffer(icmsg_buffer); - return 0; - -} - -int icmsg_me_drop_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, - const void *buffer) -{ - const void *buffer_to_drop = user_buffer_to_icmsg_buffer(buffer); - - return icmsg_drop_tx_buffer(conf, &data->icmsg_data, buffer_to_drop); -} - -int icmsg_me_send_nocopy(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, - const void *msg, size_t len) -{ - void *buffer_to_send; - size_t len_to_send; - int r; - int sent_bytes; - - buffer_to_send = user_buffer_to_icmsg_buffer(msg); - len_to_send = user_buffer_len_to_icmsg_buffer_len(len); - - set_ept_id_in_send_buffer(buffer_to_send, id); - - r = icmsg_send_nocopy(conf, &data->icmsg_data, - buffer_to_send, len_to_send); - - if (r < 0) { - return r; - } - - __ASSERT_NO_MSG(r >= HEADER_SIZE); - if (r < HEADER_SIZE) { - return 0; - } - - sent_bytes = icmsg_buffer_len_to_user_buffer_len(r); - - return sent_bytes; -} - -#ifdef CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX -int icmsg_me_hold_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, void *buffer) -{ - void *icmsg_buffer = user_buffer_to_icmsg_buffer(buffer); - - return icmsg_hold_rx_buffer(conf, &data->icmsg_data, icmsg_buffer); -} - -int icmsg_me_release_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_me_data_t *data, void *buffer) -{ - void *icmsg_buffer = user_buffer_to_icmsg_buffer(buffer); - - return icmsg_release_rx_buffer(conf, &data->icmsg_data, icmsg_buffer); -} -#endif /* CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX */ From 380f83bab1efb4480dfebdbefb1ed22fbae317e8 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Fri, 11 Aug 2023 14:29:29 +0200 Subject: [PATCH 3291/4498] ipc: Add pbuf implementation This adds implementation of secure packed buffer. Secure packed buffer is added with intention to be used in icmsg backed backends. Signed-off-by: Emil Obalski --- include/zephyr/ipc/pbuf.h | 201 +++++++++++++++++++ subsys/ipc/ipc_service/lib/CMakeLists.txt | 1 + subsys/ipc/ipc_service/lib/Kconfig.icmsg | 8 + subsys/ipc/ipc_service/lib/pbuf.c | 223 ++++++++++++++++++++++ 4 files changed, 433 insertions(+) create mode 100644 include/zephyr/ipc/pbuf.h create mode 100644 subsys/ipc/ipc_service/lib/pbuf.c diff --git a/include/zephyr/ipc/pbuf.h b/include/zephyr/ipc/pbuf.h new file mode 100644 index 00000000000..f8eff0b1ad1 --- /dev/null +++ b/include/zephyr/ipc/pbuf.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_IPC_PBUF_H_ +#define ZEPHYR_INCLUDE_IPC_PBUF_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Packed buffer API + * @ingroup kernel_apis + * @{ + */ + +/** @brief Size of packet length field. */ +#define PBUF_PACKET_LEN_SZ sizeof(uint32_t) + +/* Amount of data that is left unused to distinguish between empty and full. */ +#define _PBUF_IDX_SIZE sizeof(uint32_t) + +/* Minimal length of the data field in the buffer to store the smalest packet + * possible. + * (+1) for at least one byte of data. + * (+_PBUF_IDX_SIZE) to distinguish buffer full and buffer empty. + * Rounded up to keep wr/rd indexes pointing to aligned address. + */ +#define _PBUF_MIN_DATA_LEN ROUND_UP(PBUF_PACKET_LEN_SZ + 1 + _PBUF_IDX_SIZE, _PBUF_IDX_SIZE) + +/** @brief Control block of packet buffer. + * + * The structure contains configuration data. + */ +struct pbuf_cfg { + volatile uint32_t *rd_idx_loc; /* Address of the variable holding + * index value of the first valid byte + * in data[]. + */ + volatile uint32_t *wr_idx_loc; /* Address of the variable holding + * index value of the first free byte + * in data[]. + */ + uint32_t dcache_alignment; /* CPU data cache line size in bytes. + * Used for validation - TODO: To be + * replaced by flags. + */ + uint32_t len; /* Length of data[] in bytes. */ + uint8_t *data_loc; /* Location of the data[]. */ +}; + +/** + * @brief Data block of the packed buffer. + * + * The structure contains local copies of wr and rd indexes used by writer and + * reader respecitvely. + */ +struct pbuf_data { + volatile uint32_t wr_idx; /* Index of the first holding first + * free byte in data[]. Used for + * writing. + */ + volatile uint32_t rd_idx; /* Index of the first holding first + * valid byte in data[]. Used for + * reading. + */ +}; + + +/** + * @brief Scure packed buffer. + * + * The packet buffer implements lightweight unidirectional packet + * buffer with read/write semantics on top of a memory region shared + * by the reader and writer. It embeds cache and memory barrier management to + * ensure correct data access. + * + * This structure supports single writer and reader. Data stored in the buffer + * is encapsulated to a message (with length header). The read/write API is + * written in a way to protect the data from being corrupted. + */ +struct pbuf { + const struct pbuf_cfg *const cfg; /* Configuration of the + * buffer. + */ + struct pbuf_data data; /* Data used to read and write + * to the buffer + */ +}; + +/** + * @brief Macro for configuration initialization. + * + * It is recommended to use this macro to initialize packed buffer + * configuration. + * + * @param mem_addr Memory address for pbuf. + * @param size Size of the memory. + * @param dcache_align Data cache alignment. + */ +#define PBUF_CFG_INIT(mem_addr, size, dcache_align) \ +{ \ + .rd_idx_loc = (uint32_t *)(mem_addr), \ + .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + \ + MAX(dcache_align, _PBUF_IDX_SIZE)), \ + .data_loc = (uint8_t *)((uint8_t *)(mem_addr) + \ + MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \ + .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, _PBUF_IDX_SIZE) - \ + _PBUF_IDX_SIZE), \ + .dcache_alignment = (dcache_align), \ +} + +/** + * @brief Statically define and initialize pbuf. + * + * @param name Name of the pbuf. + * @param mem_addr Memory address for pbuf. + * @param size Size of the memory. + * @param dcache_align Data cache line size. + */ +#define PBUF_DEFINE(name, mem_addr, size, dcache_align) \ + BUILD_ASSERT(dcache_align >= 0, \ + "Cache line size must be non negative."); \ + BUILD_ASSERT((size) > 0 && IS_PTR_ALIGNED_BYTES(size, _PBUF_IDX_SIZE), \ + "Incorrect size."); \ + BUILD_ASSERT(IS_PTR_ALIGNED_BYTES(mem_addr, MAX(dcache_align, _PBUF_IDX_SIZE)), \ + "Misaligned memory."); \ + BUILD_ASSERT(size >= (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE + \ + _PBUF_MIN_DATA_LEN), "Insufficient size."); \ + \ + static const struct pbuf_cfg cfg_##name = \ + PBUF_CFG_INIT(mem_addr, size, dcache_align); \ + static struct pbuf name = { \ + .cfg = &cfg_##name, \ + } + +/** + * @brief Initialize the packet buffer. + * + * This function initializes the packet buffer based on provided configuration. + * If the configuration is incorrect, the function will return error. + * + * It is recommended to use PBUF_DEFINE macro for build time initialization. + * + * @param pb Pointer to the packed buffer containing + * configuration and data. Configuration has to be + * fixed before the initialization. + * @retval 0 on success. + * @retval -EINVAL when the input parameter is incorrect. + */ +int pbuf_init(struct pbuf *pb); + +/** + * @brief Write specified amount of data to the packet buffer. + * + * This function call writes specified amount of data to the packet buffer if + * the buffer will fit the data. + * + * @param pb A buffer to which to write. + * @param buf Pointer to the data to be written to the buffer. + * @param len Number of bytes to be written to the buffer. Must be positive. + * @retval int Number of bytes written, negative error code on fail. + * -EINVAL, if any of input parameter is incorrect. + * -ENOMEM, if len is bigger than the buffer can fit. + */ + +int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len); + +/** + * @brief Read specified amount of data from the packet buffer. + * + * Single read allows to read the message send by the single write. + * The provided %p buf must be big enough to store the whole message. + * + * @param pb A buffer from which data will be read. + * @param buf Data pointer to which read data will be written. + * If NULL, len of stored message is returned. + * @param len Number of bytes to be read from the buffer. + * @retval int Bytes read, negative error code on fail. + * Bytes to be read, if buf == NULL. + * -EINVAL, if any of input parameter is incorrect. + * -ENOMEM, if message can not fit in provided buf. + * -EAGAIN, if not whole message is ready yet. + */ +int pbuf_read(struct pbuf *pb, char *buf, uint16_t len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_IPC_PBUF_H_ */ diff --git a/subsys/ipc/ipc_service/lib/CMakeLists.txt b/subsys/ipc/ipc_service/lib/CMakeLists.txt index 97148185954..a560489be72 100644 --- a/subsys/ipc/ipc_service/lib/CMakeLists.txt +++ b/subsys/ipc/ipc_service/lib/CMakeLists.txt @@ -4,3 +4,4 @@ zephyr_sources_ifdef(CONFIG_IPC_SERVICE_ICMSG icmsg.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_ICMSG_ME icmsg_me.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_RPMSG ipc_rpmsg.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_STATIC_VRINGS ipc_static_vrings.c) +zephyr_sources_ifdef(CONFIG_PBUF pbuf.c) diff --git a/subsys/ipc/ipc_service/lib/Kconfig.icmsg b/subsys/ipc/ipc_service/lib/Kconfig.icmsg index 8f1a380a18f..39b8c8d0c75 100644 --- a/subsys/ipc/ipc_service/lib/Kconfig.icmsg +++ b/subsys/ipc/ipc_service/lib/Kconfig.icmsg @@ -70,3 +70,11 @@ endif # at a cooperative priority. config SYSTEM_WORKQUEUE_PRIORITY range -256 -1 if !IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE + +config PBUF + bool "Packed buffer support library" + help + The packet buffer implements lightweight unidirectional packet buffer + with read/write semantics on top of a memory region shared by the + reader and writer. It optionally embeds cache and memory barrier + management to ensure correct data access. diff --git a/subsys/ipc/ipc_service/lib/pbuf.c b/subsys/ipc/ipc_service/lib/pbuf.c new file mode 100644 index 00000000000..1164f814ca0 --- /dev/null +++ b/subsys/ipc/ipc_service/lib/pbuf.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/* Helper funciton for getting numer of bytes being written to the bufer. */ +static uint32_t idx_occupied(uint32_t len, uint32_t wr_idx, uint32_t rd_idx) +{ + /* It is implicitly assumed wr_idx and rd_idx cannot differ by more then len. */ + return (rd_idx > wr_idx) ? (len - (rd_idx - wr_idx)) : (wr_idx - rd_idx); +} + +/* Helper function for wrapping the index from the begging if above buffer len. */ +static uint32_t idx_wrap(uint32_t len, uint32_t idx) +{ + return (idx >= len) ? (idx % len) : (idx); +} + +static int validate_cfg(const struct pbuf_cfg *cfg) +{ + /* Validate pointers. */ + if (!cfg || !cfg->rd_idx_loc || !cfg->wr_idx_loc || !cfg->data_loc) { + return -EINVAL; + } + + /* Validate pointer alignment. */ + if (!IS_PTR_ALIGNED_BYTES(cfg->rd_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) || + !IS_PTR_ALIGNED_BYTES(cfg->wr_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) || + !IS_PTR_ALIGNED_BYTES(cfg->data_loc, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + /* Validate len. */ + if (cfg->len < _PBUF_MIN_DATA_LEN || !IS_PTR_ALIGNED_BYTES(cfg->len, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + /* Validate pointer values. */ + if (!(cfg->rd_idx_loc < cfg->wr_idx_loc) || + !((uint8_t *)cfg->wr_idx_loc < cfg->data_loc) || + !(((uint8_t *)cfg->rd_idx_loc + MAX(_PBUF_IDX_SIZE, cfg->dcache_alignment)) == + (uint8_t *)cfg->wr_idx_loc)) { + return -EINVAL; + } + + return 0; +} + +int pbuf_init(struct pbuf *pb) +{ + if (validate_cfg(pb->cfg) != 0) { + return -EINVAL; + } + + /* Initialize local copy of indexes. */ + pb->data.wr_idx = 0; + pb->data.rd_idx = 0; + + /* Clear shared memory. */ + *(pb->cfg->wr_idx_loc) = pb->data.wr_idx; + *(pb->cfg->rd_idx_loc) = pb->data.rd_idx; + + __sync_synchronize(); + + /* Take care cache. */ + sys_cache_data_flush_range((void *)(pb->cfg->wr_idx_loc), sizeof(*(pb->cfg->wr_idx_loc))); + sys_cache_data_flush_range((void *)(pb->cfg->rd_idx_loc), sizeof(*(pb->cfg->rd_idx_loc))); + + return 0; +} + +int pbuf_write(struct pbuf *pb, const char *data, uint16_t len) +{ + if (pb == NULL || len == 0 || data == NULL) { + /* Incorrect call. */ + return -EINVAL; + } + + /* Invalidate rd_idx only, local wr_idx is used to increase buffer security. */ + sys_cache_data_invd_range((void *)(pb->cfg->rd_idx_loc), sizeof(*(pb->cfg->rd_idx_loc))); + __sync_synchronize(); + + uint8_t *const data_loc = pb->cfg->data_loc; + const uint32_t blen = pb->cfg->len; + uint32_t rd_idx = *(pb->cfg->rd_idx_loc); + uint32_t wr_idx = pb->data.wr_idx; + + /* wr_idx must always be aligned. */ + __ASSERT_NO_MSG(IS_PTR_ALIGNED_BYTES(wr_idx, _PBUF_IDX_SIZE)); + /* rd_idx shall always be aligned, but its value is received from the reader. + * Can not assert. + */ + if (!IS_PTR_ALIGNED_BYTES(rd_idx, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + uint32_t free_space = blen - idx_occupied(blen, wr_idx, rd_idx) - _PBUF_IDX_SIZE; + + /* Packet length, data + packet length size. */ + uint32_t plen = len + PBUF_PACKET_LEN_SZ; + + /* Check if packet will fit into the buffer. */ + if (free_space < plen) { + return -ENOMEM; + } + + /* Clear packet len with zeros and update. Clearing is done for possible versioning in the + * future. Writing is allowed now, because shared wr_idx value is updated at the very end. + */ + *((uint32_t *)(&data_loc[wr_idx])) = 0; + sys_put_be16(len, &data_loc[wr_idx]); + __sync_synchronize(); + sys_cache_data_flush_range(&data_loc[wr_idx], PBUF_PACKET_LEN_SZ); + + wr_idx = idx_wrap(blen, wr_idx + PBUF_PACKET_LEN_SZ); + + /* Write until end of the buffer, if data will be wrapped. */ + uint32_t tail = MIN(len, blen - wr_idx); + + memcpy(&data_loc[wr_idx], data, tail); + sys_cache_data_flush_range(&data_loc[wr_idx], tail); + + if (len > tail) { + /* Copy remaining data to buffer front. */ + memcpy(&data_loc[0], data + tail, len - tail); + sys_cache_data_flush_range(&data_loc[0], len - tail); + } + + wr_idx = idx_wrap(blen, ROUND_UP(wr_idx + len, _PBUF_IDX_SIZE)); + /* Update wr_idx. */ + pb->data.wr_idx = wr_idx; + *(pb->cfg->wr_idx_loc) = wr_idx; + __sync_synchronize(); + sys_cache_data_flush_range((void *)pb->cfg->wr_idx_loc, sizeof(*(pb->cfg->wr_idx_loc))); + + return len; +} + +int pbuf_read(struct pbuf *pb, char *buf, uint16_t len) +{ + if (pb == NULL) { + /* Incorrect call. */ + return -EINVAL; + } + + /* Invalidate wr_idx only, local rd_idx is used to increase buffer security. */ + sys_cache_data_invd_range((void *)(pb->cfg->wr_idx_loc), sizeof(*(pb->cfg->wr_idx_loc))); + __sync_synchronize(); + + uint8_t *const data_loc = pb->cfg->data_loc; + const uint32_t blen = pb->cfg->len; + uint32_t wr_idx = *(pb->cfg->wr_idx_loc); + uint32_t rd_idx = pb->data.rd_idx; + + /* rd_idx must always be aligned. */ + __ASSERT_NO_MSG(IS_PTR_ALIGNED_BYTES(rd_idx, _PBUF_IDX_SIZE)); + /* wr_idx shall always be aligned, but its value is received from the + * writer. Can not assert. + */ + if (!IS_PTR_ALIGNED_BYTES(wr_idx, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + if (rd_idx == wr_idx) { + /* Buffer is empty. */ + return 0; + } + + /* Get packet len.*/ + sys_cache_data_invd_range(&data_loc[rd_idx], PBUF_PACKET_LEN_SZ); + uint16_t plen = sys_get_be16(&data_loc[rd_idx]); + + if (!buf) { + return (int)plen; + } + + if (plen > len) { + return -ENOMEM; + } + + uint32_t occupied_space = idx_occupied(blen, wr_idx, rd_idx); + + if (occupied_space < plen + PBUF_PACKET_LEN_SZ) { + /* This should never happen. */ + return -EAGAIN; + } + + rd_idx = idx_wrap(blen, rd_idx + PBUF_PACKET_LEN_SZ); + + /* Packet will fit into provided buffer, truncate len if provided len + * is bigger than necessary. + */ + len = MIN(plen, len); + + /* Read until end of the buffer, if data are wrapped. */ + uint32_t tail = MIN(blen - rd_idx, len); + + sys_cache_data_invd_range(&data_loc[rd_idx], tail); + memcpy(buf, &data_loc[rd_idx], tail); + + if (len > tail) { + sys_cache_data_invd_range(&data_loc[0], len - tail); + memcpy(&buf[tail], &pb->cfg->data_loc[0], len - tail); + } + + /* Update rd_idx. */ + rd_idx = idx_wrap(blen, ROUND_UP(rd_idx + len, _PBUF_IDX_SIZE)); + + pb->data.rd_idx = rd_idx; + *(pb->cfg->rd_idx_loc) = rd_idx; + __sync_synchronize(); + sys_cache_data_flush_range((void *)pb->cfg->rd_idx_loc, sizeof(*(pb->cfg->rd_idx_loc))); + + return len; +} From 25a0489d62bfe16975ffff7d31adf31ac3a85a06 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Wed, 9 Aug 2023 16:58:33 +0200 Subject: [PATCH 3292/4498] tests: ipc: Add pbuf unit tests Add unit tests for packed buffer. Signed-off-by: Emil Obalski --- tests/subsys/ipc/pbuf/CMakeLists.txt | 8 + tests/subsys/ipc/pbuf/prj.conf | 7 + tests/subsys/ipc/pbuf/src/main.c | 294 +++++++++++++++++++++++++++ tests/subsys/ipc/pbuf/testcase.yaml | 5 + 4 files changed, 314 insertions(+) create mode 100644 tests/subsys/ipc/pbuf/CMakeLists.txt create mode 100644 tests/subsys/ipc/pbuf/prj.conf create mode 100644 tests/subsys/ipc/pbuf/src/main.c create mode 100644 tests/subsys/ipc/pbuf/testcase.yaml diff --git a/tests/subsys/ipc/pbuf/CMakeLists.txt b/tests/subsys/ipc/pbuf/CMakeLists.txt new file mode 100644 index 00000000000..9d12b21862b --- /dev/null +++ b/tests/subsys/ipc/pbuf/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ipc_pbuf) + +FILE(GLOB app_sources src/main.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/ipc/pbuf/prj.conf b/tests/subsys/ipc/pbuf/prj.conf new file mode 100644 index 00000000000..8580c4f26a5 --- /dev/null +++ b/tests/subsys/ipc/pbuf/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_ZTRESS=y +CONFIG_ZTEST_SHUFFLE=y + +CONFIG_IPC_SERVICE=y +CONFIG_IPC_SERVICE_ICMSG=y +CONFIG_PBUF=y diff --git a/tests/subsys/ipc/pbuf/src/main.c b/tests/subsys/ipc/pbuf/src/main.c new file mode 100644 index 00000000000..7a20fc9bdd6 --- /dev/null +++ b/tests/subsys/ipc/pbuf/src/main.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + + +#define MEM_AREA_SZ 256 +#define MPS 240 +#define MSGA_SZ 11 +#define MSGB_SZ 25 + +static char memory_area[MEM_AREA_SZ] __aligned(32); + +static void print_pbuf_info(struct pbuf *pb) +{ + printk("----------stats start-----------\n"); + printk("cfg->rd_idx_loc: %p, val: %u\n", pb->cfg->rd_idx_loc, *(pb->cfg->rd_idx_loc)); + printk("cfg->wr_idx_loc: %p, val: %u\n", pb->cfg->wr_idx_loc, *(pb->cfg->wr_idx_loc)); + printk("cfg->data_loc: %p\n", pb->cfg->data_loc); + printk("cfg->len: %u\n", pb->cfg->len); + printk("cfg->dcache_alignment: %u\n", pb->cfg->dcache_alignment); + + printk("data.rd_idx: %u\n", pb->data.rd_idx); + printk("data.wr_idx: %u\n", pb->data.wr_idx); + printk("-----------stats end------------\n"); +} + +/* Read/write tests. */ +ZTEST(test_pbuf, test_rw) +{ + uint8_t read_buf[MEM_AREA_SZ] = {0}; + uint8_t write_buf[MEM_AREA_SZ]; + int ret; + + BUILD_ASSERT(MSGA_SZ < MEM_AREA_SZ); + BUILD_ASSERT(MSGB_SZ < MEM_AREA_SZ); + BUILD_ASSERT(MPS < MEM_AREA_SZ); + + /* TODO: Use PBUF_DEFINE(). + * The user should use PBUF_DEFINE() macro to define the buffer, + * however for the purpose of this test PBUF_CFG_INIT() is used in + * order to avoid clang complains about memory_area not being constant + * expression. + */ + static const struct pbuf_cfg cfg = PBUF_CFG_INIT(memory_area, MEM_AREA_SZ, 0); + + static struct pbuf pb = { + .cfg = &cfg, + }; + + for (size_t i = 0; i < MEM_AREA_SZ; i++) { + write_buf[i] = i+1; + } + + zassert_equal(pbuf_init(&pb), 0); + + /* Write MSGA_SZ bytes packet. */ + ret = pbuf_write(&pb, write_buf, MSGA_SZ); + zassert_equal(ret, MSGA_SZ); + + /* Write MSGB_SZ bytes packet. */ + ret = pbuf_write(&pb, write_buf+MSGA_SZ, MSGB_SZ); + zassert_equal(ret, MSGB_SZ); + + /* Get the number of bytes stored. */ + ret = pbuf_read(&pb, NULL, 0); + zassert_equal(ret, MSGA_SZ); + /* Attempt to read with too small read buffer. */ + ret = pbuf_read(&pb, read_buf, ret-1); + zassert_equal(ret, -ENOMEM); + /* Read the packet. */ + ret = pbuf_read(&pb, read_buf, ret); + zassert_equal(ret, MSGA_SZ); + /* Check data corectness. */ + zassert_mem_equal(read_buf, write_buf, ret); + + /* Get the number of bytes stored. */ + ret = pbuf_read(&pb, NULL, 0); + zassert_equal(ret, MSGB_SZ); + /* Read the packet. */ + ret = pbuf_read(&pb, read_buf, ret); + zassert_equal(ret, MSGB_SZ); + /* Check data corectness. */ + zassert_mem_equal(read_buf, write_buf+MSGA_SZ, ret); + + /* Get the number of bytes stored. */ + ret = pbuf_read(&pb, NULL, 0); + zassert_equal(ret, 0); + + /* Write max packet size with wrapping around. */ + ret = pbuf_write(&pb, write_buf, MPS); + zassert_equal(ret, MPS); + /* Get the number of bytes stored. */ + ret = pbuf_read(&pb, NULL, 0); + zassert_equal(ret, MPS); + /* Read max packet size with wrapp around. */ + ret = pbuf_read(&pb, read_buf, ret); + zassert_equal(ret, MPS); + /* Check data corectness. */ + zassert_mem_equal(write_buf, read_buf, MPS); +} + +/* API ret codes tests. */ +ZTEST(test_pbuf, test_retcodes) +{ + /* TODO: Use PBUF_DEFINE(). + * The user should use PBUF_DEFINE() macro to define the buffer, + * however for the purpose of this test PBUF_CFG_INIT() is used in + * order to avoid clang complains about memory_area not being constant + * expression. + */ + static const struct pbuf_cfg cfg0 = PBUF_CFG_INIT(memory_area, MEM_AREA_SZ, 32); + static const struct pbuf_cfg cfg1 = PBUF_CFG_INIT(memory_area, MEM_AREA_SZ, 0); + static const struct pbuf_cfg cfg2 = PBUF_CFG_INIT(memory_area, 20, 4); + + static struct pbuf pb0 = { + .cfg = &cfg0, + }; + + static struct pbuf pb1 = { + .cfg = &cfg1, + }; + + static struct pbuf pb2 = { + .cfg = &cfg2, + }; + + /* Initialize buffers. */ + zassert_equal(pbuf_init(&pb0), 0); + zassert_equal(pbuf_init(&pb1), 0); + zassert_equal(pbuf_init(&pb2), 0); + + print_pbuf_info(&pb0); + print_pbuf_info(&pb1); + print_pbuf_info(&pb2); + + uint8_t read_buf[MEM_AREA_SZ]; + uint8_t write_buf[MEM_AREA_SZ]; + + for (size_t i = 0; i < MEM_AREA_SZ; i++) { + write_buf[i] = i+1; + } + + /* pbuf_write incorrect params tests. */ + zassert_equal(pbuf_write(NULL, write_buf, 10), -EINVAL); + zassert_equal(pbuf_write(&pb2, NULL, 10), -EINVAL); + zassert_equal(pbuf_write(&pb2, write_buf, 0), -EINVAL); + zassert_equal(pbuf_read(NULL, read_buf, 10), -EINVAL); + + /* Attempt to write more than the buffer can fit. */ + zassert_equal(pbuf_write(&pb2, write_buf, 5), -ENOMEM); + + /* Write maximal amount, the buffer fit. */ + zassert_equal(pbuf_write(&pb2, write_buf, 4), 4); + + /* Attempt to write to full buffer. */ + zassert_equal(pbuf_write(&pb2, write_buf, 1), -ENOMEM); + + /* Get the bytes stored. */ + zassert_equal(pbuf_read(&pb2, NULL, 1), 4); + + /* Attempt to read with too small read buffer. */ + zassert_equal(pbuf_read(&pb2, read_buf, 1), -ENOMEM); + + /* Get the bytes stored. */ + zassert_equal(pbuf_read(&pb2, NULL, 0), 4); + + /* Read the data with correct buffer size. */ + zassert_equal(pbuf_read(&pb2, read_buf, 4), 4); + + /* Check data correctness. */ + zassert_mem_equal(read_buf, write_buf, 4); + + /* Read from empty buffer. */ + zassert_equal(pbuf_read(&pb2, read_buf, 10), 0); + zassert_equal(pbuf_read(&pb2, read_buf, 10), 0); + zassert_equal(pbuf_read(&pb2, read_buf, 10), 0); +} + +#define STRESS_LEN_MOD (44) +#define STRESS_LEN_MIN (20) +#define STRESS_LEN_MAX (STRESS_LEN_MIN + STRESS_LEN_MOD) + +struct stress_data { + struct pbuf *pbuf; + uint32_t wr_cnt; + uint32_t rd_cnt; + uint32_t wr_err; +}; + +/* Check if buffer of len contains exp values. */ +static int check_buffer(char *buf, uint16_t len, char exp) +{ + for (uint16_t i = 0; i < len; i++) { + if (buf[i] != exp) { + return -EINVAL; + } + } + + return 0; +} + +bool stress_read(void *user_data, uint32_t cnt, bool last, int prio) +{ + struct stress_data *ctx = (struct stress_data *)user_data; + char buf[STRESS_LEN_MAX]; + int len; + int rpt = (sys_rand32_get() & 3) + 1; + + for (int i = 0; i < rpt; i++) { + len = pbuf_read(ctx->pbuf, buf, (uint16_t)sizeof(buf)); + if (len == 0) { + return true; + } + + if (len < 0) { + zassert_true(false, "Unexpected error: %d, cnt:%d", len, ctx->rd_cnt); + } + + zassert_ok(check_buffer(buf, len, ctx->rd_cnt)); + ctx->rd_cnt++; + } + + return true; +} + +bool stress_write(void *user_data, uint32_t cnt, bool last, int prio) +{ + struct stress_data *ctx = (struct stress_data *)user_data; + char buf[STRESS_LEN_MAX]; + + uint16_t len = STRESS_LEN_MIN + (sys_rand32_get() % STRESS_LEN_MOD); + int rpt = (sys_rand32_get() & 1) + 1; + + zassert_true(len < sizeof(buf)); + + for (int i = 0; i < rpt; i++) { + memset(buf, (uint8_t)ctx->wr_cnt, len); + int ret = pbuf_write(ctx->pbuf, buf, len); + + if (ret == len) { + ctx->wr_cnt++; + } else if (ret == -ENOMEM) { + ctx->wr_err++; + } else { + zassert_unreachable(); + } + } + + return true; +} + +ZTEST(test_pbuf, test_stress) +{ + static uint8_t buffer[MEM_AREA_SZ] __aligned(32); + static struct stress_data ctx = {}; + uint32_t repeat = 0; + + /* TODO: Use PBUF_DEFINE(). + * The user should use PBUF_DEFINE() macro to define the buffer, + * however for the purpose of this test PBUF_CFG_INIT() is used in + * order to avoid clang complains about buffer not being constant + * expression. + */ + static const struct pbuf_cfg cfg = PBUF_CFG_INIT(buffer, MEM_AREA_SZ, 4); + + static struct pbuf pb = { + .cfg = &cfg, + }; + + zassert_equal(pbuf_init(&pb), 0); + ctx.pbuf = &pb; + ctx.wr_cnt = 0; + ctx.rd_cnt = 0; + + ztress_set_timeout(K_MSEC(1500)); + TC_PRINT("Reading from an interrupt, writing from a thread\n"); + ZTRESS_EXECUTE(ZTRESS_TIMER(stress_read, &ctx, repeat, Z_TIMEOUT_TICKS(4)), + ZTRESS_THREAD(stress_write, &ctx, repeat, 2000, Z_TIMEOUT_TICKS(4))); + TC_PRINT("Writes:%d unsuccessful: %d\n", ctx.wr_cnt, ctx.wr_err); + + TC_PRINT("Writing from an interrupt, reading from a thread\n"); + ZTRESS_EXECUTE(ZTRESS_TIMER(stress_write, &ctx, repeat, Z_TIMEOUT_TICKS(4)), + ZTRESS_THREAD(stress_read, &ctx, repeat, 1000, Z_TIMEOUT_TICKS(4))); + TC_PRINT("Writes:%d unsuccessful: %d\n", ctx.wr_cnt, ctx.wr_err); +} + +ZTEST_SUITE(test_pbuf, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/ipc/pbuf/testcase.yaml b/tests/subsys/ipc/pbuf/testcase.yaml new file mode 100644 index 00000000000..4113335403a --- /dev/null +++ b/tests/subsys/ipc/pbuf/testcase.yaml @@ -0,0 +1,5 @@ +tests: + ipc.icmsg_pbuf: + integration_platforms: + - native_posix + timeout: 120 From eb4fc3f0838541512f84febceeab8712f5f7fbc2 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Tue, 24 Oct 2023 12:24:49 +0200 Subject: [PATCH 3293/4498] ipc: backends: Port IcMsg based backends to use pbuf Replace spsc_pbuf with pbuf implementation dedicated to be used by IcMsg based backends. The pbuf is written on top of simple read/write semantics with minimal footprint and code complexity Signed-off-by: Emil Obalski --- dts/bindings/ipc/zephyr,ipc-icmsg.yaml | 13 + include/zephyr/ipc/icmsg.h | 17 +- subsys/ipc/ipc_service/backends/ipc_icmsg.c | 48 +-- .../backends/ipc_icmsg_me_follower.c | 26 +- .../backends/ipc_icmsg_me_initiator.c | 26 +- subsys/ipc/ipc_service/lib/Kconfig | 3 +- subsys/ipc/ipc_service/lib/icmsg.c | 276 ++---------------- 7 files changed, 105 insertions(+), 304 deletions(-) diff --git a/dts/bindings/ipc/zephyr,ipc-icmsg.yaml b/dts/bindings/ipc/zephyr,ipc-icmsg.yaml index b67c9072980..41793005373 100644 --- a/dts/bindings/ipc/zephyr,ipc-icmsg.yaml +++ b/dts/bindings/ipc/zephyr,ipc-icmsg.yaml @@ -21,6 +21,19 @@ properties: required: true type: phandle + dcache-alignment: + type: int + description: | + Data cache alignment. If any side of the communication uses cache on + rx-region/tx-region this property must be the biggest value of the + invalidation or the write-back size for both sides of the communication. + If no side of the communication uses data cache this property could be + safely omitted. + For example: + Side A: no data cache + Side B: 32 Bytes write-back size, 16 Bytes invalidation size + dcache-alignment = 32; for both + mboxes: description: phandle to the MBOX controller (TX and RX are required) required: true diff --git a/include/zephyr/ipc/icmsg.h b/include/zephyr/ipc/icmsg.h index 099c6265acd..a3b43690cc4 100644 --- a/include/zephyr/ipc/icmsg.h +++ b/include/zephyr/ipc/icmsg.h @@ -12,8 +12,8 @@ #include #include #include +#include #include -#include #ifdef __cplusplus extern "C" { @@ -33,19 +33,14 @@ enum icmsg_state { }; struct icmsg_config_t { - uintptr_t tx_shm_addr; - uintptr_t rx_shm_addr; - size_t tx_shm_size; - size_t rx_shm_size; struct mbox_channel mbox_tx; struct mbox_channel mbox_rx; }; struct icmsg_data_t { /* Tx/Rx buffers. */ - struct spsc_pbuf *tx_ib; - struct spsc_pbuf *rx_ib; - atomic_t tx_buffer_state; + struct pbuf *tx_pb; + struct pbuf *rx_pb; #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC struct k_mutex tx_lock; #endif @@ -59,12 +54,6 @@ struct icmsg_data_t { struct k_work_delayable notify_work; struct k_work mbox_work; atomic_t state; - /* No-copy */ -#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - atomic_t rx_buffer_state; - const void *rx_buffer; - uint16_t rx_len; -#endif }; /** @brief Open an icmsg instance diff --git a/subsys/ipc/ipc_service/backends/ipc_icmsg.c b/subsys/ipc/ipc_service/backends/ipc_icmsg.c index eca84f3275c..28b94b861e3 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icmsg.c +++ b/subsys/ipc/ipc_service/backends/ipc_icmsg.c @@ -54,27 +54,33 @@ static int backend_init(const struct device *instance) return 0; } -#define DEFINE_BACKEND_DEVICE(i) \ - static const struct icmsg_config_t backend_config_##i = { \ - .tx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ - .tx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ - .rx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ - .rx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ - .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ - .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ - }; \ - \ - BUILD_ASSERT(DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)) > \ - sizeof(struct spsc_pbuf)); \ - static struct icmsg_data_t backend_data_##i; \ - \ - DEVICE_DT_INST_DEFINE(i, \ - &backend_init, \ - NULL, \ - &backend_data_##i, \ - &backend_config_##i, \ - POST_KERNEL, \ - CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY, \ +#define DEFINE_BACKEND_DEVICE(i) \ + static const struct icmsg_config_t backend_config_##i = { \ + .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ + .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ + }; \ + \ + PBUF_DEFINE(tx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + PBUF_DEFINE(rx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + \ + static struct icmsg_data_t backend_data_##i = { \ + .tx_pb = &tx_pb_##i, \ + .rx_pb = &rx_pb_##i, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(i, \ + &backend_init, \ + NULL, \ + &backend_data_##i, \ + &backend_config_##i, \ + POST_KERNEL, \ + CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY, \ &backend_ops); DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE) diff --git a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c index 8b0944c840f..5492da0a302 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c +++ b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_follower.c @@ -277,16 +277,28 @@ static int backend_init(const struct device *instance) } #define DEFINE_BACKEND_DEVICE(i) \ - static const struct icmsg_config_t backend_config_##i = \ - { \ - .tx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ - .tx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ - .rx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ - .rx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ + static const struct icmsg_config_t backend_config_##i = { \ .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ }; \ - static struct backend_data_t backend_data_##i; \ + \ + PBUF_DEFINE(tx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + PBUF_DEFINE(rx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + \ + static struct backend_data_t backend_data_##i = { \ + .icmsg_me_data = { \ + .icmsg_data = { \ + .tx_pb = &tx_pb_##i, \ + .rx_pb = &rx_pb_##i, \ + } \ + } \ + }; \ \ DEVICE_DT_INST_DEFINE(i, \ &backend_init, \ diff --git a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c index 2699d3b6db6..2d537dc84a2 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c +++ b/subsys/ipc/ipc_service/backends/ipc_icmsg_me_initiator.c @@ -183,16 +183,28 @@ static int backend_init(const struct device *instance) } #define DEFINE_BACKEND_DEVICE(i) \ - static const struct icmsg_config_t backend_config_##i = \ - { \ - .tx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ - .tx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ - .rx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ - .rx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ + static const struct icmsg_config_t backend_config_##i = { \ .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ }; \ - static struct backend_data_t backend_data_##i; \ + \ + PBUF_DEFINE(tx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + PBUF_DEFINE(rx_pb_##i, \ + DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \ + DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \ + DT_INST_PROP_OR(i, dcache_alignment, 0)); \ + \ + static struct backend_data_t backend_data_##i = { \ + .icmsg_me_data = { \ + .icmsg_data = { \ + .tx_pb = &tx_pb_##i, \ + .rx_pb = &rx_pb_##i, \ + } \ + } \ + }; \ \ DEVICE_DT_INST_DEFINE(i, \ &backend_init, \ diff --git a/subsys/ipc/ipc_service/lib/Kconfig b/subsys/ipc/ipc_service/lib/Kconfig index 6bd57ab15aa..0fbc82ddc13 100644 --- a/subsys/ipc/ipc_service/lib/Kconfig +++ b/subsys/ipc/ipc_service/lib/Kconfig @@ -21,8 +21,7 @@ config IPC_SERVICE_STATIC_VRINGS_MEM_ALIGNMENT menuconfig IPC_SERVICE_ICMSG bool "icmsg IPC library" - select SPSC_PBUF - select SPSC_PBUF_USE_CACHE + select PBUF help Icmsg library diff --git a/subsys/ipc/ipc_service/lib/icmsg.c b/subsys/ipc/ipc_service/lib/icmsg.c index 9d238f19351..5d93686eed9 100644 --- a/subsys/ipc/ipc_service/lib/icmsg.c +++ b/subsys/ipc/ipc_service/lib/icmsg.c @@ -9,22 +9,12 @@ #include #include #include -#include +#include #include #define BOND_NOTIFY_REPEAT_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS) #define SHMEM_ACCESS_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS) -enum rx_buffer_state { - RX_BUFFER_STATE_RELEASED, - RX_BUFFER_STATE_RELEASING, - RX_BUFFER_STATE_HELD -}; - -enum tx_buffer_state { - TX_BUFFER_STATE_UNUSED, - TX_BUFFER_STATE_RESERVED -}; static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b, 0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34}; @@ -82,12 +72,6 @@ static bool is_endpoint_ready(struct icmsg_data_t *dev_data) return atomic_get(&dev_data->state) == ICMSG_STATE_READY; } -static bool is_tx_buffer_reserved(struct icmsg_data_t *dev_data) -{ - return atomic_get(&dev_data->tx_buffer_state) == - TX_BUFFER_STATE_RESERVED; -} - static int reserve_tx_buffer_if_unused(struct icmsg_data_t *dev_data) { #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC @@ -97,52 +81,20 @@ static int reserve_tx_buffer_if_unused(struct icmsg_data_t *dev_data) return ret; } #endif - - bool was_unused = atomic_cas(&dev_data->tx_buffer_state, - TX_BUFFER_STATE_UNUSED, TX_BUFFER_STATE_RESERVED); - - return was_unused ? 0 : -EALREADY; + return 0; } static int release_tx_buffer(struct icmsg_data_t *dev_data) { - bool was_reserved = atomic_cas(&dev_data->tx_buffer_state, - TX_BUFFER_STATE_RESERVED, TX_BUFFER_STATE_UNUSED); - - if (!was_reserved) { - return -EALREADY; - } - #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC return k_mutex_unlock(&dev_data->tx_lock); -#else - return 0; -#endif -} - -static bool is_rx_buffer_free(struct icmsg_data_t *dev_data) -{ -#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - return atomic_get(&dev_data->rx_buffer_state) == RX_BUFFER_STATE_RELEASED; -#else - return true; -#endif -} - -static bool is_rx_buffer_held(struct icmsg_data_t *dev_data) -{ -#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - return atomic_get(&dev_data->rx_buffer_state) == RX_BUFFER_STATE_HELD; -#else - return false; #endif + return 0; } -static bool is_rx_data_available(struct icmsg_data_t *dev_data) +static uint32_t data_available(struct icmsg_data_t *dev_data) { - int len = spsc_pbuf_read(dev_data->rx_ib, NULL, 0); - - return len > 0; + return pbuf_read(dev_data->rx_pb, NULL, 0); } static void submit_mbox_work(struct icmsg_data_t *dev_data) @@ -157,20 +109,13 @@ static void submit_mbox_work(struct icmsg_data_t *dev_data) static void submit_work_if_buffer_free(struct icmsg_data_t *dev_data) { - if (!is_rx_buffer_free(dev_data)) { - return; - } - submit_mbox_work(dev_data); } static void submit_work_if_buffer_free_and_data_available( struct icmsg_data_t *dev_data) { - if (!is_rx_buffer_free(dev_data)) { - return; - } - if (!is_rx_data_available(dev_data)) { + if (!data_available(dev_data)) { return; } @@ -179,47 +124,31 @@ static void submit_work_if_buffer_free_and_data_available( static void mbox_callback_process(struct k_work *item) { - char *rx_buffer; struct icmsg_data_t *dev_data = CONTAINER_OF(item, struct icmsg_data_t, mbox_work); atomic_t state = atomic_get(&dev_data->state); - uint16_t len = spsc_pbuf_claim(dev_data->rx_ib, &rx_buffer); + uint32_t len = data_available(dev_data); if (len == 0) { /* Unlikely, no data in buffer. */ return; } + uint8_t rx_buffer[len]; + + len = pbuf_read(dev_data->rx_pb, rx_buffer, len); + if (state == ICMSG_STATE_READY) { if (dev_data->cb->received) { -#if CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - dev_data->rx_buffer = rx_buffer; - dev_data->rx_len = len; -#endif - dev_data->cb->received(rx_buffer, len, dev_data->ctx); - - /* Release Rx buffer here only in case when user did not request - * to hold it. - */ - if (!is_rx_buffer_held(dev_data)) { - spsc_pbuf_free(dev_data->rx_ib, len); - -#if CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - dev_data->rx_buffer = NULL; - dev_data->rx_len = 0; -#endif - } } } else { __ASSERT_NO_MSG(state == ICMSG_STATE_BUSY); bool endpoint_invalid = (len != sizeof(magic) || memcmp(magic, rx_buffer, len)); - spsc_pbuf_free(dev_data->rx_ib, len); - if (endpoint_invalid) { __ASSERT_NO_MSG(false); return; @@ -262,8 +191,6 @@ int icmsg_open(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data, const struct ipc_service_cb *cb, void *ctx) { - __ASSERT_NO_MSG(conf->tx_shm_size > sizeof(struct spsc_pbuf)); - if (!atomic_cas(&dev_data->state, ICMSG_STATE_OFF, ICMSG_STATE_BUSY)) { /* Already opened. */ return -EALREADY; @@ -277,12 +204,18 @@ int icmsg_open(const struct icmsg_config_t *conf, k_mutex_init(&dev_data->tx_lock); #endif - dev_data->tx_ib = spsc_pbuf_init((void *)conf->tx_shm_addr, - conf->tx_shm_size, - SPSC_PBUF_CACHE); - dev_data->rx_ib = (void *)conf->rx_shm_addr; + int ret = pbuf_init(dev_data->tx_pb); - int ret = spsc_pbuf_write(dev_data->tx_ib, magic, sizeof(magic)); + if (ret < 0) { + __ASSERT(false, "Incorrect configuration"); + return ret; + } + + /* Initialize local copies of rx_pb. */ + dev_data->rx_pb->data.wr_idx = 0; + dev_data->rx_pb->data.rd_idx = 0; + + ret = pbuf_write(dev_data->tx_pb, magic, sizeof(magic)); if (ret < 0) { __ASSERT_NO_MSG(false); @@ -345,7 +278,7 @@ int icmsg_send(const struct icmsg_config_t *conf, return -ENOBUFS; } - write_ret = spsc_pbuf_write(dev_data->tx_ib, msg, len); + write_ret = pbuf_write(dev_data->tx_pb, msg, len); release_ret = release_tx_buffer(dev_data); __ASSERT_NO_MSG(!release_ret); @@ -366,169 +299,6 @@ int icmsg_send(const struct icmsg_config_t *conf, return sent_bytes; } -int icmsg_get_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - void **data, size_t *size) -{ - int ret; - int release_ret; - uint16_t requested_size; - int allocated_len; - char *allocated_buf; - - if (*size == 0) { - /* Requested allocation of maximal size. - * Try to allocate maximal buffer size from spsc, - * potentially after wrapping marker. - */ - requested_size = SPSC_PBUF_MAX_LEN - 1; - } else { - requested_size = *size; - } - - ret = reserve_tx_buffer_if_unused(dev_data); - if (ret < 0) { - return -ENOBUFS; - } - - ret = spsc_pbuf_alloc(dev_data->tx_ib, requested_size, &allocated_buf); - if (ret < 0) { - release_ret = release_tx_buffer(dev_data); - __ASSERT_NO_MSG(!release_ret); - return ret; - } - allocated_len = ret; - - if (*size == 0) { - /* Requested allocation of maximal size. - * Pass the buffer that was allocated. - */ - *size = allocated_len; - *data = allocated_buf; - return 0; - } - - if (*size == allocated_len) { - /* Allocated buffer is of requested size. */ - *data = allocated_buf; - return 0; - } - - /* Allocated smaller buffer than requested. - * Silently stop using the allocated buffer what is allowed by SPSC API - */ - release_tx_buffer(dev_data); - *size = allocated_len; - return -ENOMEM; -} - -int icmsg_drop_tx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data) -{ - /* Silently stop using the allocated buffer what is allowed by SPSC API - */ - return release_tx_buffer(dev_data); -} - -int icmsg_send_nocopy(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *msg, size_t len) -{ - int ret; - int sent_bytes; - - if (!is_endpoint_ready(dev_data)) { - return -EBUSY; - } - - /* Empty message is not allowed */ - if (len == 0) { - return -ENODATA; - } - - if (!is_tx_buffer_reserved(dev_data)) { - return -ENXIO; - } - - spsc_pbuf_commit(dev_data->tx_ib, len); - sent_bytes = len; - - ret = release_tx_buffer(dev_data); - __ASSERT_NO_MSG(!ret); - - __ASSERT_NO_MSG(conf->mbox_tx.dev != NULL); - - ret = mbox_send(&conf->mbox_tx, NULL); - if (ret) { - return ret; - } - - return sent_bytes; -} - -#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX -int icmsg_hold_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data) -{ - bool was_released; - - if (!is_endpoint_ready(dev_data)) { - return -EBUSY; - } - - if (data != dev_data->rx_buffer) { - return -EINVAL; - } - - was_released = atomic_cas(&dev_data->rx_buffer_state, - RX_BUFFER_STATE_RELEASED, RX_BUFFER_STATE_HELD); - if (!was_released) { - return -EALREADY; - } - - return 0; -} - -int icmsg_release_rx_buffer(const struct icmsg_config_t *conf, - struct icmsg_data_t *dev_data, - const void *data) -{ - bool was_held; - - if (!is_endpoint_ready(dev_data)) { - return -EBUSY; - } - - if (data != dev_data->rx_buffer) { - return -EINVAL; - } - - /* Do not schedule new packet processing until buffer will be released. - * Protect buffer against being freed multiple times. - */ - was_held = atomic_cas(&dev_data->rx_buffer_state, - RX_BUFFER_STATE_HELD, RX_BUFFER_STATE_RELEASING); - if (!was_held) { - return -EALREADY; - } - - spsc_pbuf_free(dev_data->rx_ib, dev_data->rx_len); - -#if CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX - dev_data->rx_buffer = NULL; - dev_data->rx_len = 0; -#endif - - atomic_set(&dev_data->rx_buffer_state, RX_BUFFER_STATE_RELEASED); - - submit_work_if_buffer_free_and_data_available(dev_data); - - return 0; -} -#endif /* CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX */ - #if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE) static int work_q_init(void) From d769a925201f58e13763ccbf400670190cbfee85 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Thu, 2 Nov 2023 15:24:14 +0100 Subject: [PATCH 3294/4498] ipc: icmsg: Allow to support future versions Allow magic number to be longer than the sizeof(magic). This will allow to support future versions of the icmsg with backwards compatibility. Signed-off-by: Emil Obalski --- subsys/ipc/ipc_service/lib/icmsg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/ipc/ipc_service/lib/icmsg.c b/subsys/ipc/ipc_service/lib/icmsg.c index 5d93686eed9..52e2dd10f1b 100644 --- a/subsys/ipc/ipc_service/lib/icmsg.c +++ b/subsys/ipc/ipc_service/lib/icmsg.c @@ -147,7 +147,9 @@ static void mbox_callback_process(struct k_work *item) } else { __ASSERT_NO_MSG(state == ICMSG_STATE_BUSY); - bool endpoint_invalid = (len != sizeof(magic) || memcmp(magic, rx_buffer, len)); + /* Allow magic number longer than sizeof(magic) for future protocol version. */ + bool endpoint_invalid = (len < sizeof(magic) || + memcmp(magic, rx_buffer, sizeof(magic))); if (endpoint_invalid) { __ASSERT_NO_MSG(false); From c4ffadb0b61fb4c7e5d0cdb517bbd21ca6791484 Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Fri, 3 Nov 2023 15:54:46 +0200 Subject: [PATCH 3295/4498] arch: arm64: avoid invalidating of RO mem after mem map The Cortex ARM documentation states that the DC IVAC instruction requires write access permission to the virtual address (VA); otherwise, it may generate a permission fault. Therefore, it is needed to avoid invalidating read-only memory after the memory map operation. This issue has been produced by commit c9b534c. This commit resolves the issue #64758. Signed-off-by: Mykola Kvach --- arch/arm64/core/mmu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/core/mmu.c b/arch/arm64/core/mmu.c index 7d5670da0f2..2260d22c101 100644 --- a/arch/arm64/core/mmu.c +++ b/arch/arm64/core/mmu.c @@ -731,6 +731,14 @@ static inline void add_arm_mmu_region(struct arm_mmu_ptables *ptables, static inline void inv_dcache_after_map_helper(void *virt, size_t size, uint32_t attrs) { + /* + * DC IVAC instruction requires write access permission to the VA, + * otherwise it can generate a permission fault + */ + if ((attrs & MT_RW) != MT_RW) { + return; + } + if (MT_TYPE(attrs) == MT_NORMAL || MT_TYPE(attrs) == MT_NORMAL_WT) { sys_cache_data_invd_range(virt, size); } @@ -987,6 +995,7 @@ void arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flags) case K_MEM_CACHE_WB: case K_MEM_CACHE_WT: mem_flags = (mem_flags == K_MEM_CACHE_WB) ? MT_NORMAL : MT_NORMAL_WT; + mem_flags |= (flags & K_MEM_PERM_RW) ? MT_RW : 0; inv_dcache_after_map_helper(virt, size, mem_flags); default: break; From 4e5868faaf9d5cbe1796e06b915f417a8b3aab0f Mon Sep 17 00:00:00 2001 From: Corey Wharton Date: Wed, 20 Sep 2023 15:19:29 -0700 Subject: [PATCH 3296/4498] arch: arm: cortex-m: support custom interrupt controllers This change adds support for the CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER option on Cortex-M platforms. While all Cortex-M platforms have a NVIC controller some custom SoCs may have additional IRQ controllers or custom handling. This change allows those SoCs to modify this bahaviour without having to place platform specific logic inside applications or drivers. Signed-off-by: Corey Wharton --- arch/arm/Kconfig | 12 ++++++------ arch/arm/core/cortex_m/CMakeLists.txt | 2 +- arch/arm/core/cortex_m/irq_manage.c | 4 ++++ arch/arm/core/cortex_m/isr_wrapper.S | 16 ++++++++++++++++ arch/arm/core/cortex_m/prep_c.c | 5 +++++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3f775e4d638..8b0d53ec3cf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -16,23 +16,23 @@ config CPU_CORTEX config ARM_CUSTOM_INTERRUPT_CONTROLLER bool - depends on !CPU_CORTEX_M help This option indicates that the ARM CPU is connected to a custom (i.e. - non-GIC) interrupt controller. + non-GIC or NVIC) interrupt controller. A number of Cortex-A and Cortex-R cores (Cortex-A5, Cortex-R4/5, ...) allow interfacing to a custom external interrupt controller and this option must be selected when such cores are connected to an interrupt - controller that is not the ARM Generic Interrupt Controller (GIC). + controller that is not the ARM Generic Interrupt Controller (GIC) or + the Cortex-M ARM Nested Vectored Interrupt Controller (NVIC). When this option is selected, the architecture interrupt control functions are mapped to the SoC interrupt control interface, which is implemented at the SoC level. - N.B. This option is only applicable to the Cortex-A and Cortex-R - family cores. The Cortex-M family cores are always equipped with - the ARM Nested Vectored Interrupt Controller (NVIC). + N.B. Since all Cortex-M cores have a NVIC, if this option is selected it + is assumed that the custom interrupt control interface implementation + assumes responsibility for handling the NVIC. config CODE_DATA_RELOCATION_SRAM bool "Relocate code/data sections to SRAM" diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index 7ec2441f12f..225d7111bdc 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -7,7 +7,6 @@ zephyr_library_sources( fault.c fault_s.S fpu.c - irq_init.c reset.S scb.c thread_abort.c @@ -20,6 +19,7 @@ zephyr_library_sources( cpu_idle.S ) +zephyr_library_sources_ifndef(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER irq_init.c) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) diff --git a/arch/arm/core/cortex_m/irq_manage.c b/arch/arm/core/cortex_m/irq_manage.c index cd0c6f6e5bf..3940d5246d4 100644 --- a/arch/arm/core/cortex_m/irq_manage.c +++ b/arch/arm/core/cortex_m/irq_manage.c @@ -32,6 +32,8 @@ extern void z_arm_reserved(void); #define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG) #define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG) +#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + void arch_irq_enable(unsigned int irq) { NVIC_EnableIRQ((IRQn_Type)irq); @@ -90,6 +92,8 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) NVIC_SetPriority((IRQn_Type)irq, prio); } +#endif /* !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) */ + void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); /** diff --git a/arch/arm/core/cortex_m/isr_wrapper.S b/arch/arm/core/cortex_m/isr_wrapper.S index 78ad6cd1e83..f81b577804f 100644 --- a/arch/arm/core/cortex_m/isr_wrapper.S +++ b/arch/arm/core/cortex_m/isr_wrapper.S @@ -97,13 +97,24 @@ _idle_state_cleared: #endif /* CONFIG_PM */ +#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + bl z_soc_irq_get_active +#else mrs r0, IPSR /* get exception number */ +#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) ldr r1, =16 subs r0, r1 /* get IRQ number */ +#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + push {r0} +#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ lsls r0, #3 /* table is 8-byte wide */ #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) sub r0, r0, #16 /* get IRQ number */ +#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + push {r0} +#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ lsl r0, r0, #3 /* table is 8-byte wide */ #else #error Unknown ARM architecture @@ -116,6 +127,11 @@ _idle_state_cleared: ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ blx r3 /* call ISR */ +#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + pop {r0} + bl z_soc_irq_eoi +#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + #ifdef CONFIG_TRACING_ISR bl sys_trace_isr_exit #endif diff --git a/arch/arm/core/cortex_m/prep_c.c b/arch/arm/core/cortex_m/prep_c.c index ad166775ca4..329f7f8987d 100644 --- a/arch/arm/core/cortex_m/prep_c.c +++ b/arch/arm/core/cortex_m/prep_c.c @@ -187,7 +187,12 @@ void z_arm_prep_c(void) #endif z_bss_zero(); z_data_copy(); +#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) + /* Invoke SoC-specific interrupt controller initialization */ + z_soc_irq_init(); +#else z_arm_interrupt_init(); +#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ z_cstart(); CODE_UNREACHABLE; } From 0fdb50b8694f9ceac1af234a4c6e3ce2c2e723ec Mon Sep 17 00:00:00 2001 From: Corey Wharton Date: Wed, 20 Sep 2023 15:42:01 -0700 Subject: [PATCH 3297/4498] tests: arch: arm: add new test for custom interrupt control on Cortex-M Adds a new test for ARM Cortex-M architectures with the CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER option enabled. Signed-off-by: Corey Wharton --- .../arm/arm_custom_interrupt/CMakeLists.txt | 9 + tests/arch/arm/arm_custom_interrupt/Kconfig | 13 ++ .../arch/arm/arm_custom_interrupt/README.txt | 35 +++ tests/arch/arm/arm_custom_interrupt/prj.conf | 4 + .../src/arm_custom_interrupt.c | 209 ++++++++++++++++++ .../arch/arm/arm_custom_interrupt/src/main.c | 9 + .../arm/arm_custom_interrupt/testcase.yaml | 10 + 7 files changed, 289 insertions(+) create mode 100644 tests/arch/arm/arm_custom_interrupt/CMakeLists.txt create mode 100644 tests/arch/arm/arm_custom_interrupt/Kconfig create mode 100644 tests/arch/arm/arm_custom_interrupt/README.txt create mode 100644 tests/arch/arm/arm_custom_interrupt/prj.conf create mode 100644 tests/arch/arm/arm_custom_interrupt/src/arm_custom_interrupt.c create mode 100644 tests/arch/arm/arm_custom_interrupt/src/main.c create mode 100644 tests/arch/arm/arm_custom_interrupt/testcase.yaml diff --git a/tests/arch/arm/arm_custom_interrupt/CMakeLists.txt b/tests/arch/arm/arm_custom_interrupt/CMakeLists.txt new file mode 100644 index 00000000000..04c09451564 --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/CMakeLists.txt @@ -0,0 +1,9 @@ +#SPDX - License - Identifier : Apache - 2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(arm_interrupt) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/arch/arm/arm_custom_interrupt/Kconfig b/tests/arch/arm/arm_custom_interrupt/Kconfig new file mode 100644 index 00000000000..73a87ef561b --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/Kconfig @@ -0,0 +1,13 @@ +# Private config options for test + +# Copyright Meta Platforms, Inc. and its affiliates. +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Custom interrupt test" + +source "Kconfig.zephyr" + +config ENABLE_CUSTOM_INTERRUPTS + bool + default y + select ARM_CUSTOM_INTERRUPT_CONTROLLER diff --git a/tests/arch/arm/arm_custom_interrupt/README.txt b/tests/arch/arm/arm_custom_interrupt/README.txt new file mode 100644 index 00000000000..d5adfc01241 --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/README.txt @@ -0,0 +1,35 @@ +Title: Test to verify custom interrupt controller handling with on + the Cortex-M architectures. + +Description: + +This test verifies customer interrupt controller handling on +Cortex-M architectures using the CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER +option. It will locate a unused interrupt to trigger via software and test +all methods that are part of the SoC interrupt control interface. + +--------------------------------------------------------------------------- + +Sample Output +*** Booting Zephyr OS build zephyr-v3.4.0-4023-g7fca0aa8a693 *** +Running TESTSUITE arm_custom_interrupt +=================================================================== +START - test_arm_interrupt +Available IRQ line: 42 +Got IRQ: 42 +Got IRQ: 42 +Got IRQ: 42 + PASS - test_arm_interrupt in 0.001 seconds +=================================================================== +TESTSUITE arm_custom_interrupt succeeded + +------ TESTSUITE SUMMARY START ------ + +SUITE PASS - 100.00% [arm_custom_interrupt]: pass = 1, fail = 0, skip = 0, total = 1 duration = 0.001 seconds + - PASS - [arm_custom_interrupt.test_arm_interrupt] duration = 0.001 seconds + +------ TESTSUITE SUMMARY END ------ + +=================================================================== +RunID: b979ee8bbf5ad07d1754866129997539 +PROJECT EXECUTION SUCCESSFUL diff --git a/tests/arch/arm/arm_custom_interrupt/prj.conf b/tests/arch/arm/arm_custom_interrupt/prj.conf new file mode 100644 index 00000000000..ab8b7519f55 --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_DYNAMIC_INTERRUPTS=y +CONFIG_IDLE_STACK_SIZE=512 +CONFIG_ASSERT_TEST=y diff --git a/tests/arch/arm/arm_custom_interrupt/src/arm_custom_interrupt.c b/tests/arch/arm/arm_custom_interrupt/src/arm_custom_interrupt.c new file mode 100644 index 00000000000..97d3c55365d --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/src/arm_custom_interrupt.c @@ -0,0 +1,209 @@ +/* + * Copyright Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +unsigned int sw_irq_number = (unsigned int)(-1); +static volatile bool custom_init_called; +static volatile bool custom_enable_called; +static volatile bool custom_disable_called; +static volatile bool custom_set_priority_called; +static volatile bool custom_eoi_called; +static volatile bool irq_handler_called; + +/* Define out custom SoC interrupt controller interface methods. + * These closely match the normal Cortex-M implementations. + */ + +#define NUM_IRQS_PER_REG 32 +#define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG) +#define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG) + +void z_soc_irq_init(void) +{ + int irq = 0; + + for (; irq < CONFIG_NUM_IRQS; irq++) { + NVIC_SetPriority((IRQn_Type)irq, _IRQ_PRIO_OFFSET); + } + + custom_init_called = true; +} + +void z_soc_irq_enable(unsigned int irq) +{ + if (irq == sw_irq_number) { + custom_enable_called = true; + } + NVIC_EnableIRQ((IRQn_Type)irq); +} + +void z_soc_irq_disable(unsigned int irq) +{ + if (irq == sw_irq_number) { + custom_disable_called = true; + } + NVIC_DisableIRQ((IRQn_Type)irq); +} + +int z_soc_irq_is_enabled(unsigned int irq) +{ + return NVIC->ISER[REG_FROM_IRQ(irq)] & BIT(BIT_FROM_IRQ(irq)); +} + +void z_soc_irq_eoi(unsigned int irq) +{ + if (irq == sw_irq_number) { + custom_eoi_called = true; + } +} + +inline __attribute__((always_inline)) unsigned int z_soc_irq_get_active(void) +{ + return __get_IPSR(); +} + +void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) +{ + if (irq == sw_irq_number) { + custom_set_priority_called = true; + } + + if (IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) && (flags & IRQ_ZERO_LATENCY)) { + prio = _EXC_ZERO_LATENCY_IRQS_PRIO; + } else { + prio += _IRQ_PRIO_OFFSET; + } + + NVIC_SetPriority((IRQn_Type)irq, prio); +} + +void arm_isr_handler(const void *args) +{ + ARG_UNUSED(args); + +#if defined(CONFIG_CPU_CORTEX_M) && defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + /* Clear Floating Point Status and Control Register (FPSCR), + * to prevent from having the interrupt line set to pending again, + * in case FPU IRQ is selected by the test as "Available IRQ line" + */ +#if defined(CONFIG_ARMV8_1_M_MAINLINE) + /* + * For ARMv8.1-M with FPU, the FPSCR[18:16] LTPSIZE field must be set + * to 0b100 for "Tail predication not applied" as it's reset value + */ + __set_FPSCR(4 << FPU_FPDSCR_LTPSIZE_Pos); +#else + __set_FPSCR(0); +#endif +#endif + + /* IRQ numbers are offset by 16 on Cortex-M. */ + unsigned int this_irq = z_soc_irq_get_active() - 16; + + TC_PRINT("Got IRQ: %u\n", this_irq); + + zassert_equal(this_irq, sw_irq_number, "Unexpected active IRQ\n"); + irq_handler_called = true; +} + +/** + * @brief Test custom interrupt controller handling with CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER. + * @addtogroup kernel_interrupt_tests + * @ingroup all_tests + * @{ + */ + +ZTEST(arm_custom_interrupt, test_arm_interrupt) +{ + zassert_true(custom_init_called, "Custom IRQ init not called\n"); + + /* Determine an NVIC IRQ line that is not currently in use. */ + int i; + + for (i = CONFIG_NUM_IRQS - 1; i >= 0; i--) { + if (NVIC_GetEnableIRQ(i) == 0) { + /* + * Interrupts configured statically with IRQ_CONNECT(.) + * are automatically enabled. NVIC_GetEnableIRQ() + * returning false, here, implies that the IRQ line is + * either not implemented or it is not enabled, thus, + * currently not in use by Zephyr. + */ + + /* Set the NVIC line to pending. */ + NVIC_SetPendingIRQ(i); + + if (NVIC_GetPendingIRQ(i)) { + /* If the NVIC line is pending, it is + * guaranteed that it is implemented; clear the + * line. + */ + NVIC_ClearPendingIRQ(i); + + if (!NVIC_GetPendingIRQ(i)) { + /* + * If the NVIC line can be successfully + * un-pended, it is guaranteed that it + * can be used for software interrupt + * triggering. + */ + break; + } + } + } + } + + zassert_true(i >= 0, "No available IRQ line to use in the test\n"); + + TC_PRINT("Available IRQ line: %u\n", i); + sw_irq_number = i; + + zassert_false(custom_set_priority_called, "Custom set priority flag set\n"); + arch_irq_connect_dynamic(sw_irq_number, 0 /* highest priority */, arm_isr_handler, NULL, 0); + zassert_true(custom_set_priority_called, "Custom set priority not called\n"); + + NVIC_ClearPendingIRQ(i); + + zassert_false(arch_irq_is_enabled(sw_irq_number), "SW IRQ already enabled\n"); + zassert_false(custom_enable_called, "Custom IRQ enable flag is set\n"); + irq_enable(sw_irq_number); + zassert_true(custom_enable_called, "Custom IRQ enable not called\n"); + zassert_true(arch_irq_is_enabled(sw_irq_number), "SW IRQ is not enabled\n"); + + for (int j = 1; j <= 3; j++) { + custom_eoi_called = false; + irq_handler_called = false; + custom_set_priority_called = false; + + /* Set the dynamic IRQ to pending state. */ + NVIC_SetPendingIRQ(i); + + /* + * Instruction barriers to make sure the NVIC IRQ is + * set to pending state before 'test_flag' is checked. + */ + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + + /* Returning here implies the thread was not aborted. */ + + /* Confirm test flag is set by the ISR handler. */ + zassert_true(custom_eoi_called, "Custom EOI handler not called\n"); + zassert_true(irq_handler_called, "ISR handler not called\n"); + } + + zassert_false(custom_disable_called, "Custom IRQ disable flag is set\n"); + irq_disable(sw_irq_number); + zassert_true(custom_disable_called, "Custom IRQ disable not called\n"); +} + +/** + * @} + */ diff --git a/tests/arch/arm/arm_custom_interrupt/src/main.c b/tests/arch/arm/arm_custom_interrupt/src/main.c new file mode 100644 index 00000000000..e1f3c267965 --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/src/main.c @@ -0,0 +1,9 @@ +/* + * Copyright Meta Platforms, Inc. and its affiliates. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +ZTEST_SUITE(arm_custom_interrupt, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/arm/arm_custom_interrupt/testcase.yaml b/tests/arch/arm/arm_custom_interrupt/testcase.yaml new file mode 100644 index 00000000000..d20f87e17ae --- /dev/null +++ b/tests/arch/arm/arm_custom_interrupt/testcase.yaml @@ -0,0 +1,10 @@ +common: + filter: CONFIG_ARMV6_M_ARMV8_M_BASELINE or CONFIG_ARMV7_M_ARMV8_M_MAINLINE + tags: + - arm + - interrupt + ignore_faults: true + arch_allow: arm +tests: + arch.arm.custom_interrupt: + filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE From 6744d6084dd3ef0e1ab683551dd5301885f43dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 7 Nov 2023 08:53:36 +0700 Subject: [PATCH 3298/4498] watchdog: nxp_s32: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles --- drivers/watchdog/wdt_nxp_s32.c | 63 ++++++++++++++-------------------- soc/arm/nxp_s32/s32ze/soc.h | 15 ++++++++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/drivers/watchdog/wdt_nxp_s32.c b/drivers/watchdog/wdt_nxp_s32.c index 2d380264b94..709cf9aaffb 100644 --- a/drivers/watchdog/wdt_nxp_s32.c +++ b/drivers/watchdog/wdt_nxp_s32.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_swt + #include #include #include @@ -129,6 +131,13 @@ static int swt_nxp_s32_feed(const struct device *dev, int channel_id) return 0; } +void swt_nxp_s32_isr(const struct device *dev) +{ + const struct swt_nxp_s32_config *config = dev->config; + + Swt_Ip_IrqHandler(config->instance); +} + static const struct wdt_driver_api swt_nxp_s32_driver_api = { .setup = swt_nxp_s32_setup, .disable = swt_nxp_s32_disable, @@ -136,17 +145,10 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { .feed = swt_nxp_s32_feed, }; -#define SWT_NODE(n) DT_NODELABEL(swt##n) -#define RTU0_SWT_OFFSET_IDX 2 -#define RTU1_SWT_OFFSET_IDX 7 -#define RTU_SWT(n) \ - COND_CODE_1(CONFIG_NXP_S32_RTU_INDEX, (RTU1_SWT_OFFSET_IDX + n), \ - (RTU0_SWT_OFFSET_IDX + n)) - #define SWT_NXP_S32_CALLBACK(n) \ void swt_nxp_s32_##n##_callback(void) \ { \ - const struct device *dev = DEVICE_DT_GET(SWT_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ struct swt_nxp_s32_data *data = dev->data; \ \ if (data->callback) { \ @@ -154,6 +156,12 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { } \ } +#define SWT_NXP_S32_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_SWT_##i##_BASE) ? i : 0) + +#define SWT_NXP_S32_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET SWT_INSTANCE_COUNT, SWT_NXP_S32_HW_INSTANCE_CHECK, (|), n) + #define SWT_NXP_S32_DEVICE_INIT(n) \ SWT_NXP_S32_CALLBACK(n) \ static struct swt_nxp_s32_data swt_nxp_s32_data_##n = { \ @@ -171,10 +179,10 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { }, \ }; \ static const struct swt_nxp_s32_config swt_nxp_s32_config_##n = { \ - .instance = (uint8_t)(RTU_SWT(n)), \ - .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SWT_NODE(n))), \ + .instance = SWT_NXP_S32_HW_INSTANCE(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t) \ - DT_CLOCKS_CELL(SWT_NODE(n), name), \ + DT_INST_CLOCKS_CELL(n, name), \ }; \ \ static int swt_nxp_s32_##n##_init(const struct device *dev) \ @@ -191,17 +199,15 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { return err; \ } \ \ - IRQ_CONNECT(DT_IRQN(SWT_NODE(n)), \ - DT_IRQ(SWT_NODE(n), priority), \ - Swt_Ip_IrqHandler, \ - (uint8_t)(RTU_SWT(n)), \ - DT_IRQ(SWT_NODE(n), flags)); \ - irq_enable(DT_IRQN(SWT_NODE(n))); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + swt_nxp_s32_isr, DEVICE_DT_INST_GET(n), \ + DT_INST_IRQ(n, flags)); \ + irq_enable(DT_INST_IRQN(n)); \ \ return 0; \ } \ \ - DEVICE_DT_DEFINE(SWT_NODE(n), \ + DEVICE_DT_INST_DEFINE(n, \ swt_nxp_s32_##n##_init, \ NULL, \ &swt_nxp_s32_data_##n, \ @@ -210,23 +216,4 @@ static const struct wdt_driver_api swt_nxp_s32_driver_api = { CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &swt_nxp_s32_driver_api); - -#if DT_NODE_HAS_STATUS(SWT_NODE(0), okay) -SWT_NXP_S32_DEVICE_INIT(0) -#endif - -#if DT_NODE_HAS_STATUS(SWT_NODE(1), okay) -SWT_NXP_S32_DEVICE_INIT(1) -#endif - -#if DT_NODE_HAS_STATUS(SWT_NODE(2), okay) -SWT_NXP_S32_DEVICE_INIT(2) -#endif - -#if DT_NODE_HAS_STATUS(SWT_NODE(3), okay) -SWT_NXP_S32_DEVICE_INIT(3) -#endif - -#if DT_NODE_HAS_STATUS(SWT_NODE(4), okay) -SWT_NXP_S32_DEVICE_INIT(4) -#endif +DT_INST_FOREACH_STATUS_OKAY(SWT_NXP_S32_DEVICE_INIT) diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index cdee74ad54c..756774d7202 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -18,4 +18,19 @@ /* LINFlexD*/ #define IP_LINFLEX_12_BASE IP_MSC_0_LIN_BASE +/* SWT */ +#define IP_SWT_0_BASE IP_CE_SWT_0_BASE +#define IP_SWT_1_BASE IP_CE_SWT_1_BASE +#define IP_SWT_2_BASE IP_RTU0__SWT_0_BASE +#define IP_SWT_3_BASE IP_RTU0__SWT_1_BASE +#define IP_SWT_4_BASE IP_RTU0__SWT_2_BASE +#define IP_SWT_5_BASE IP_RTU0__SWT_3_BASE +#define IP_SWT_6_BASE IP_RTU0__SWT_4_BASE +#define IP_SWT_7_BASE IP_RTU1__SWT_0_BASE +#define IP_SWT_8_BASE IP_RTU1__SWT_1_BASE +#define IP_SWT_9_BASE IP_RTU1__SWT_2_BASE +#define IP_SWT_10_BASE IP_RTU1__SWT_3_BASE +#define IP_SWT_11_BASE IP_RTU1__SWT_4_BASE +#define IP_SWT_12_BASE IP_SMU__SWT_BASE + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From db0ec23ba4cf839ec5115b3cec7cea9275deadf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 7 Nov 2023 09:07:08 +0700 Subject: [PATCH 3299/4498] tests: samples: watchdog: add s32z270dc2_r52 rev.D MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twister treats board revisions as separate boards, so s32z270dc2_r52 revision D must be added to the filters. Signed-off-by: Manuel Argüelles --- samples/drivers/watchdog/sample.yaml | 4 ++++ tests/drivers/watchdog/wdt_basic_api/testcase.yaml | 4 ++++ tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml | 2 ++ 3 files changed, 10 insertions(+) diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index d9c908d536d..f3e11dda9b5 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -20,6 +20,8 @@ tests: platform_exclude: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - s32z270dc2_rtu0_r52@D + - s32z270dc2_rtu1_r52@D sample.drivers.watchdog.stm32_wwdg: extra_args: DTC_OVERLAY_FILE=boards/stm32_wwdg.overlay filter: dt_compat_enabled("st,stm32-window-watchdog") @@ -106,3 +108,5 @@ tests: platform_allow: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - s32z270dc2_rtu0_r52@D + - s32z270dc2_rtu1_r52@D diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index f42734011c8..a2f8ea97f1f 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -14,6 +14,8 @@ tests: - mec15xxevb_assy6853 - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - s32z270dc2_rtu0_r52@D + - s32z270dc2_rtu1_r52@D drivers.watchdog.stm32wwdg: filter: dt_compat_enabled("st,stm32-window-watchdog") or dt_compat_enabled("st,stm32-watchdog") extra_args: DTC_OVERLAY_FILE="boards/stm32_wwdg.overlay" @@ -117,6 +119,8 @@ tests: platform_allow: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - s32z270dc2_rtu0_r52@D + - s32z270dc2_rtu1_r52@D - mr_canhubk3 drivers.watchdog.mimxrt1050_evk_ti_tps382x: filter: dt_compat_enabled("ti,tps382x") diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml index 0096842c2ec..0290edbafc1 100644 --- a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml @@ -6,6 +6,8 @@ tests: platform_allow: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 + - s32z270dc2_rtu0_r52@D + - s32z270dc2_rtu1_r52@D tags: - drivers - watchdog From f9a4a3597bb56fa99aac69f699e213c51ca354d2 Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Fri, 22 Sep 2023 01:46:28 -0700 Subject: [PATCH 3300/4498] soc: arm: npcx: move soc-specific register definitions to soc.h This CL is to minimize `CONFIG_SOC_SERIES_XXXX` definitions when we introduce a new chip series. Most of them are relevant to register layouts in different npcx soc series. It moves soc-specific register definitions from `reg_def.h` to its own soc.h file. Signed-off-by: Mulin Chao --- drivers/flash/flash_npcx_fiu_qspi.c | 9 +- drivers/pinctrl/pinctrl_npcx.c | 11 +- soc/arm/nuvoton_npcx/common/reg/reg_def.h | 184 +++------------------- soc/arm/nuvoton_npcx/common/soc_clock.h | 22 --- soc/arm/nuvoton_npcx/npcx4/soc.h | 51 ++++++ soc/arm/nuvoton_npcx/npcx7/soc.h | 32 ++++ soc/arm/nuvoton_npcx/npcx9/soc.h | 43 +++++ 7 files changed, 153 insertions(+), 199 deletions(-) diff --git a/drivers/flash/flash_npcx_fiu_qspi.c b/drivers/flash/flash_npcx_fiu_qspi.c index 37afe6cfa42..39e699bbef9 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.c +++ b/drivers/flash/flash_npcx_fiu_qspi.c @@ -247,7 +247,6 @@ void qspi_npcx_fiu_mutex_unlock(const struct device *dev) static int qspi_npcx_fiu_init(const struct device *dev) { const struct npcx_qspi_fiu_config *const config = dev->config; - struct fiu_reg *const inst = HAL_INSTANCE(dev); struct npcx_qspi_fiu_data *const data = dev->data; const struct device *const clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE); int ret; @@ -270,9 +269,11 @@ static int qspi_npcx_fiu_init(const struct device *dev) /* Enable direct access for 2 external SPI devices */ if (config->en_direct_access_2dev) { - if (IS_ENABLED(CONFIG_FLASH_NPCX_FIU_SUPP_DRA_2_DEV)) { - inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); - } +#if defined(CONFIG_FLASH_NPCX_FIU_SUPP_DRA_2_DEV) + struct fiu_reg *const inst = HAL_INSTANCE(dev); + + inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); +#endif } return 0; diff --git a/drivers/pinctrl/pinctrl_npcx.c b/drivers/pinctrl/pinctrl_npcx.c index 5759122018f..373a7158cfc 100644 --- a/drivers/pinctrl/pinctrl_npcx.c +++ b/drivers/pinctrl/pinctrl_npcx.c @@ -38,17 +38,10 @@ static const struct npcx_pwm_pinctrl_config pwm_pinctrl_cfg[] = { /* Pin-control local functions for peripheral devices */ static bool npcx_periph_pinmux_has_lock(int group) { -#if defined(CONFIG_SOC_SERIES_NPCX7) - if (group == 0x00 || (group >= 0x02 && group <= 0x04) || group == 0x06 || - group == 0x0b || group == 0x0f) { + if ((BIT(group) & NPCX_DEVALT_LK_GROUP_MASK) != 0) { return true; } -#elif defined(CONFIG_SOC_SERIES_NPCX9) - if (group == 0x00 || (group >= 0x02 && group <= 0x06) || group == 0x0b || - group == 0x0d || (group >= 0x0f && group <= 0x12)) { - return true; - } -#endif + return false; } diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 794bb5545bb..e9ef3460e63 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -228,49 +228,17 @@ struct scfg_reg { volatile uint8_t LV_GPIO_CTL0[5]; }; -/* SCFG internal inline functions for multi-registers */ -static inline uint32_t npcx_devalt_offset(uint32_t alt_no) -{ - return 0x010 + alt_no; -} - -static inline uint32_t npcx_devalt_lk_offset(uint32_t alt_lk_no) -{ - return 0x210 + alt_lk_no; -} - -static inline uint32_t npcx_pupd_en_offset(uint32_t pupd_en_no) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7) || IS_ENABLED(CONFIG_SOC_SERIES_NPCX9)) { - return 0x28 + pupd_en_no; - } else { /* NPCX4 and later series */ - return 0x2b + pupd_en_no; - } -} - -static inline uint32_t npcx_lv_gpio_ctl_offset(uint32_t ctl_no) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7) || IS_ENABLED(CONFIG_SOC_SERIES_NPCX9)) { - if (ctl_no < 5) { - return 0x02a + ctl_no; - } else { - return 0x026 + ctl_no - 5; - } - } else { /* NPCX4 and later series */ - return 0x150 + ctl_no; - } -} - /* Macro functions for SCFG multi-registers */ -#define NPCX_DEV_CTL(base, n) (*(volatile uint8_t *)(base + n)) -#define NPCX_DEVALT(base, n) (*(volatile uint8_t *)(base + \ - npcx_devalt_offset(n))) -#define NPCX_DEVALT_LK(base, n) (*(volatile uint8_t *)(base + \ - npcx_devalt_lk_offset(n))) -#define NPCX_PUPD_EN(base, n) (*(volatile uint8_t *)(base + \ - npcx_pupd_en_offset(n))) -#define NPCX_LV_GPIO_CTL(base, n) (*(volatile uint8_t *)(base + \ - npcx_lv_gpio_ctl_offset(n))) +#define NPCX_DEV_CTL(base, n) \ + (*(volatile uint8_t *)(base + n)) +#define NPCX_DEVALT(base, n) \ + (*(volatile uint8_t *)(base + NPCX_DEVALT_OFFSET(n))) +#define NPCX_DEVALT_LK(base, n) \ + (*(volatile uint8_t *)(base + NPCX_DEVALT_LK_OFFSET(n))) +#define NPCX_PUPD_EN(base, n) \ + (*(volatile uint8_t *)(base + NPCX_PUPD_EN_OFFSET(n))) +#define NPCX_LV_GPIO_CTL(base, n) \ + (*(volatile uint8_t *)(base + NPCX_LV_GPIO_CTL_OFFSET(n))) /* SCFG register fields */ #define NPCX_DEVCNT_F_SPI_TRIS 6 @@ -413,95 +381,21 @@ struct uart_reg { #define NPCX_UFRCTL_RNEMPTY_EN 6 #define NPCX_UFRCTL_ERR_EN 7 -/* - * Multi-Input Wake-Up Unit (MIWU) device registers - */ - -/* MIWU internal inline functions for multi-registers */ -static inline uint32_t npcx_wkedg_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x000 + (group * 2ul) + (group < 5 ? 0 : 0x1e); - } else { /* NPCX9 and later series */ - return 0x000 + group * 0x10UL; - } -} - -static inline uint32_t npcx_wkaedg_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x001 + (group * 2ul) + (group < 5 ? 0 : 0x1e); - } else { /* NPCX9 and later series */ - return 0x001 + group * 0x10ul; - } -} - -static inline uint32_t npcx_wkmod_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x070 + group; - } else { /* NPCX9 and later series */ - return 0x002 + group * 0x10ul; - } -} - -static inline uint32_t npcx_wkpnd_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x00a + (group * 4ul) + (group < 5 ? 0 : 0x10); - } else { /* NPCX9 and later series */ - return 0x003 + group * 0x10ul; - } -} - -static inline uint32_t npcx_wkpcl_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x00c + (group * 4ul) + (group < 5 ? 0 : 0x10); - } else { /* NPCX9 and later series */ - return 0x004 + group * 0x10ul; - } -} - -static inline uint32_t npcx_wken_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x01e + (group * 2ul) + (group < 5 ? 0 : 0x12); - } else { /* NPCX9 and later series */ - return 0x005 + group * 0x10ul; - } -} - -static inline uint32_t npcx_wkst_offset(uint32_t group) -{ - /* NPCX9 and later series only */ - return 0x006 + group * 0x10ul; -} - -static inline uint32_t npcx_wkinen_offset(uint32_t group) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x01f + (group * 2ul) + (group < 5 ? 0 : 0x12); - } else { /* NPCX9 and later series */ - return 0x007 + group * 0x10ul; - } -} - /* Macro functions for MIWU multi-registers */ #define NPCX_WKEDG(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkedg_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKEDG_OFFSET(group))) #define NPCX_WKAEDG(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkaedg_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKAEDG_OFFSET(group))) #define NPCX_WKPND(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkpnd_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKPND_OFFSET(group))) #define NPCX_WKPCL(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkpcl_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKPCL_OFFSET(group))) #define NPCX_WKEN(base, group) \ - (*(volatile uint8_t *)(base + npcx_wken_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKEN_OFFSET(group))) #define NPCX_WKINEN(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkinen_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKINEN_OFFSET(group))) #define NPCX_WKMOD(base, group) \ - (*(volatile uint8_t *)(base + npcx_wkmod_offset(group))) + (*(volatile uint8_t *)(base + NPCX_WKMOD_OFFSET(group))) /* * General-Purpose I/O (GPIO) device registers @@ -582,33 +476,10 @@ struct adc_reg { }; /* ADC internal inline functions for multi-registers */ -static inline uint32_t npcx_chndat_offset(uint32_t ch) -{ - return 0x40 + ch * 2; -} - -static inline uint32_t npcx_thr_base(void) -{ - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) { - return 0x014; - } else if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX9)) { - return 0x060; - } else { /* NPCX4 and later series */ - return 0x080; - } -} - -static inline uint32_t npcx_thrctl_offset(uint32_t ctrl) -{ - return npcx_thr_base() + ctrl * 2; -} - -#define CHNDAT(base, ch) (*(volatile uint16_t *)((base) + npcx_chndat_offset(ch))) +#define CHNDAT(base, ch) \ + (*(volatile uint16_t *)((base) + NPCX_CHNDAT_OFFSET(ch))) #define THRCTL(base, ctrl) \ - (*(volatile uint16_t *)(base + npcx_thrctl_offset(ctrl))) -#ifdef CONFIG_SOC_SERIES_NPCX4 -#define THEN(base) (*(volatile uint16_t *)(base + 0x90)) -#endif + (*(volatile uint16_t *)(base + NPCX_THRCTL_OFFSET(ctrl))) /* ADC register fields */ #define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) @@ -628,16 +499,6 @@ static inline uint32_t npcx_thrctl_offset(uint32_t ctrl) #define NPCX_ADCCNF_STOP 11 #define NPCX_CHNDAT_CHDAT_FIELD FIELD(0, 10) #define NPCX_CHNDAT_NEW 15 -#ifdef CONFIG_SOC_SERIES_NPCX4 -#define NPCX_THRCTL_L_H 15 -#define NPCX_THRCTL_CHNSEL FIELD(10, 5) -#define NPCX_THRCTL_THRVAL FIELD(0, 10) -#else -#define NPCX_THRCTL_THEN 15 -#define NPCX_THRCTL_L_H 14 -#define NPCX_THRCTL_CHNSEL FIELD(10, 4) -#define NPCX_THRCTL_THRVAL FIELD(0, 10) -#endif #define NPCX_THRCTS_ADC_WKEN 15 #define NPCX_THRCTS_THR3_IEN 10 #define NPCX_THRCTS_THR2_IEN 9 @@ -1598,11 +1459,6 @@ struct fiu_reg { #define NPCX_SPI1_DEV_FOUR_BADDR_CS10 6 #define NPCX_SPI1_DEV_FOUR_BADDR_CS11 7 #define NPCX_SPI1_DEV_SPI1_LO_DEV_SIZE FIELD(0, 4) -#if defined(CONFIG_SOC_SERIES_NPCX9) -#define NPCX_FIU_EXT_CFG_SPI1_2DEV 7 -#else -#define NPCX_FIU_EXT_CFG_SPI1_2DEV 6 -#endif #define NPCX_FIU_EXT_CFG_SET_DMM_EN 2 #define NPCX_FIU_EXT_CFG_SET_CMD_EN 1 #define NPCX_SPI_DEV_NADDRB FIELD(5, 3) diff --git a/soc/arm/nuvoton_npcx/common/soc_clock.h b/soc/arm/nuvoton_npcx/common/soc_clock.h index cda024dc0df..6b302f2e885 100644 --- a/soc/arm/nuvoton_npcx/common/soc_clock.h +++ b/soc/arm/nuvoton_npcx/common/soc_clock.h @@ -42,14 +42,6 @@ struct npcx_clk_cfg { #define APB2DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb2_prescaler) - 1) /* APB3 clock divider */ #define APB3DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb3_prescaler) - 1) -/* APB4 clock divider if supported */ -#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) -#if !defined(CONFIG_SOC_SERIES_NPCX7) /* Supported in NPCX9 and later series */ -#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) -#else -#error "APB4 clock divider is not supported but defined in pcc node!" -#endif /* !CONFIG_SOC_SERIES_NPCX7 */ -#endif /* Construct a uint8_t array from 'pwdwn-ctl-val' prop for PWDWN_CTL initialization. */ #define NPCX_PWDWN_CTL_ITEMS_INIT(node, prop, idx) DT_PROP_BY_IDX(node, prop, idx), @@ -68,12 +60,6 @@ struct npcx_clk_cfg { * - CORE_CLK > MAX_OFMCLK/2, AHB6DIV should be 1, else 0. * - CORE_CLK > MAX_OFMCLK/2, FIUDIV should be 1, else 0. */ -#if defined(CONFIG_SOC_SERIES_NPCX4) -#define MAX_OFMCLK 120000000 -#else -#define MAX_OFMCLK 100000000 -#endif /* CONFIG_SOC_SERIES_NPCX4 */ - /* Core domain clock */ #define CORE_CLK (OFMCLK / DT_PROP(DT_NODELABEL(pcc), core_prescaler)) /* Low Frequency clock */ @@ -103,14 +89,6 @@ struct npcx_clk_cfg { #define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */ #endif -#if defined(CONFIG_SOC_SERIES_NPCX4) -#if (CORE_CLK > (MAX_OFMCLK / 2)) -#define FIU1DIV_VAL 1 /* FIU1_CLK = CORE_CLK/2 */ -#else -#define FIU1DIV_VAL 0 /* FIU1_CLK = CORE_CLK */ -#endif -#endif /* CONFIG_SOC_SERIES_NPCX4 */ - /* Get APB clock freq */ #define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1)) diff --git a/soc/arm/nuvoton_npcx/npcx4/soc.h b/soc/arm/nuvoton_npcx/npcx4/soc.h index e61c1e108f0..5c3f7cf5927 100644 --- a/soc/arm/nuvoton_npcx/npcx4/soc.h +++ b/soc/arm/nuvoton_npcx/npcx4/soc.h @@ -11,6 +11,45 @@ #define __FPU_PRESENT CONFIG_CPU_HAS_FPU #define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +/* NPCX4 SCFG multi-registers */ +#define NPCX_DEVALT_OFFSET(n) (0x010 + n) +#define NPCX_PUPD_EN_OFFSET(n) (0x02b + n) +#define NPCX_LV_GPIO_CTL_OFFSET(n) (0x150 + n) +#define NPCX_DEVALT_LK_OFFSET(n) (0x210 + n) + +/* NPCX4 MIWU multi-registers */ +#define NPCX_WKEDG_OFFSET(n) (0x000 + (n * 0x010)) +#define NPCX_WKAEDG_OFFSET(n) (0x001 + (n * 0x010)) +#define NPCX_WKMOD_OFFSET(n) (0x002 + (n * 0x010)) +#define NPCX_WKPND_OFFSET(n) (0x003 + (n * 0x010)) +#define NPCX_WKPCL_OFFSET(n) (0x004 + (n * 0x010)) +#define NPCX_WKEN_OFFSET(n) (0x005 + (n * 0x010)) +#define NPCX_WKST_OFFSET(n) (0x006 + (n * 0x010)) +#define NPCX_WKINEN_OFFSET(n) (0x007 + (n * 0x010)) + +/* NPCX4 ADC multi-registers */ +#define NPCX_CHNDAT_OFFSET(n) (0x040 + n * 2) +#define NPCX_THRCTL_OFFSET(n) (0x080 + n * 2) +#define NPCX_THEN_OFFSET 0x090 +#define THEN(base) (*(volatile uint16_t *)(base + NPCX_THEN_OFFSET)) + +/* NPCX4 ADC register fields */ +#define NPCX_THRCTL_L_H 15 +#define NPCX_THRCTL_CHNSEL FIELD(10, 5) +#define NPCX_THRCTL_THRVAL FIELD(0, 10) + +/* NPCX4 FIU register fields */ +#define NPCX_FIU_EXT_CFG_SPI1_2DEV 6 + +/* NPCX4 supported group mask of DEVALT_LK */ +#define NPCX_DEVALT_LK_GROUP_MASK \ + (BIT(0) | BIT(2) | BIT(3) | BIT(4) | \ + BIT(5) | BIT(6) | BIT(11) | BIT(13) | \ + BIT(15) | BIT(16) | BIT(17) | BIT(18) | \ + BIT(19) | BIT(21)) /* DEVALT0_LK - DEVALTN_LK */ + +/* NPCX4 Clock Configuration */ +#define MAX_OFMCLK 120000000 #include #include @@ -19,4 +58,16 @@ #include #include +/* NPCX4 Clock definitions */ +#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) +/* APB4 clock divider if supported */ +#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) +#endif + +#if (CORE_CLK > (MAX_OFMCLK / 2)) +#define FIU1DIV_VAL 1 /* If CORE_CLK > MAX_OFMCLK / 2, FIU1_CLK = CORE_CLK/2 */ +#else +#define FIU1DIV_VAL 0 /* Else, FIU1_CLK = CORE_CLK */ +#endif + #endif /* _NUVOTON_NPCX_SOC_H_ */ diff --git a/soc/arm/nuvoton_npcx/npcx7/soc.h b/soc/arm/nuvoton_npcx/npcx7/soc.h index 9c293e05753..7099552cec3 100644 --- a/soc/arm/nuvoton_npcx/npcx7/soc.h +++ b/soc/arm/nuvoton_npcx/npcx7/soc.h @@ -11,6 +11,38 @@ #define __FPU_PRESENT CONFIG_CPU_HAS_FPU #define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +/* NPCX7 SCFG multi-registers offset */ +#define NPCX_DEVALT_OFFSET(n) (0x010 + n) +#define NPCX_PUPD_EN_OFFSET(n) (0x028 + n) +#define NPCX_LV_GPIO_CTL_OFFSET(n) ((n < 5) ? (0x02a + n) : (0x021 + n)) +#define NPCX_DEVALT_LK_OFFSET(n) (0x210 + n) + +/* NPCX7 MIWU multi-registers offset */ +#define NPCX_WKEDG_OFFSET(n) (0x000 + (n * 2) + ((n < 5) ? 0 : 0x01e)) +#define NPCX_WKAEDG_OFFSET(n) (0x001 + (n * 2) + ((n < 5) ? 0 : 0x01e)) +#define NPCX_WKMOD_OFFSET(n) (0x070 + n) +#define NPCX_WKPND_OFFSET(n) (0x00a + (n * 4) + ((n < 5) ? 0 : 0x010)) +#define NPCX_WKPCL_OFFSET(n) (0x00c + (n * 4) + ((n < 5) ? 0 : 0x010)) +#define NPCX_WKEN_OFFSET(n) (0x01e + (n * 2) + ((n < 5) ? 0 : 0x012)) +#define NPCX_WKINEN_OFFSET(n) (0x01f + (n * 2) + ((n < 5) ? 0 : 0x012)) + +/* NPCX7 ADC multi-registers offset */ +#define NPCX_CHNDAT_OFFSET(n) (0x040 + (n * 2)) +#define NPCX_THRCTL_OFFSET(n) (0x014 + (n * 2)) + +/* NPCX7 ADC register fields */ +#define NPCX_THRCTL_THEN 15 +#define NPCX_THRCTL_L_H 14 +#define NPCX_THRCTL_CHNSEL FIELD(10, 4) +#define NPCX_THRCTL_THRVAL FIELD(0, 10) + +/* NPCX7 supported group mask of DEVALT_LK */ +#define NPCX_DEVALT_LK_GROUP_MASK \ + (BIT(0) | BIT(2) | BIT(3) | BIT(4) | \ + BIT(6) | BIT(11) | BIT(15)) /* DEVALT0_LK - DEVALTF_LK */ + +/* NPCX7 Clock configuration */ +#define MAX_OFMCLK 100000000 #include #include diff --git a/soc/arm/nuvoton_npcx/npcx9/soc.h b/soc/arm/nuvoton_npcx/npcx9/soc.h index a1769e11a00..0e9e23cda36 100644 --- a/soc/arm/nuvoton_npcx/npcx9/soc.h +++ b/soc/arm/nuvoton_npcx/npcx9/soc.h @@ -11,6 +11,43 @@ #define __FPU_PRESENT CONFIG_CPU_HAS_FPU #define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +/* NPCX9 SCFG multi-registers */ +#define NPCX_DEVALT_OFFSET(n) (0x010 + n) +#define NPCX_PUPD_EN_OFFSET(n) (0x028 + n) +#define NPCX_LV_GPIO_CTL_OFFSET(n) ((n < 5) ? (0x02a + n) : (0x021 + n)) +#define NPCX_DEVALT_LK_OFFSET(n) (0x210 + n) + +/* NPCX9 MIWU multi-registers */ +#define NPCX_WKEDG_OFFSET(n) (0x000 + (n * 0x010)) +#define NPCX_WKAEDG_OFFSET(n) (0x001 + (n * 0x010)) +#define NPCX_WKMOD_OFFSET(n) (0x002 + (n * 0x010)) +#define NPCX_WKPND_OFFSET(n) (0x003 + (n * 0x010)) +#define NPCX_WKPCL_OFFSET(n) (0x004 + (n * 0x010)) +#define NPCX_WKEN_OFFSET(n) (0x005 + (n * 0x010)) +#define NPCX_WKST_OFFSET(n) (0x006 + (n * 0x010)) +#define NPCX_WKINEN_OFFSET(n) (0x007 + (n * 0x010)) + +/* NPCX9 ADC multi-registers */ +#define NPCX_CHNDAT_OFFSET(n) (0x040 + (n * 2)) +#define NPCX_THRCTL_OFFSET(n) (0x060 + (n * 2)) + +/* NPCX9 ADC register fields */ +#define NPCX_THRCTL_THEN 15 +#define NPCX_THRCTL_L_H 14 +#define NPCX_THRCTL_CHNSEL FIELD(10, 4) +#define NPCX_THRCTL_THRVAL FIELD(0, 10) + +/* NPCX9 FIU register fields */ +#define NPCX_FIU_EXT_CFG_SPI1_2DEV 7 + +/* NPCX9 supported group mask of DEVALT_LK */ +#define NPCX_DEVALT_LK_GROUP_MASK \ + (BIT(0) | BIT(2) | BIT(3) | BIT(4) | \ + BIT(5) | BIT(6) | BIT(11) | BIT(13) | \ + BIT(15) | BIT(16) | BIT(17) | BIT(18)) /* DEVALT0_LK - DEVALTJ_LK */ + +/* NPCX9 Clock configuration and limitation */ +#define MAX_OFMCLK 100000000 #include #include @@ -19,4 +56,10 @@ #include #include +/* NPCX9 Clock definitions */ +#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) +/* APB4 clock divider if supported */ +#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) +#endif + #endif /* _NUVOTON_NPCX_SOC_H_ */ From d24545072c0b5dd2bdcf0169a014ca4ec66d1386 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 20 Sep 2023 16:08:36 +0800 Subject: [PATCH 3301/4498] arch: sw_isr: store device info in the table and add funtions to access Change the internal function to `get_parent_entry`, which returns the entire entry of table. Store the parent interrupt controller device in the `irq_parent_offset` table, and added 2 helper functions to: 1. determine the parent interrupt controller based on the IRQ 2. determine the IRQ of the parent interrupt controller Declare the `struct _irq_parent_entry` in the header and added `-` suffix to the struct so that it can be used to test the functions in testsuites. Signed-off-by: Yong Cong Sin --- arch/common/sw_isr_common.c | 129 ++++++++++++++++++++++++++++------ include/zephyr/sw_isr_table.h | 26 +++++++ 2 files changed, 132 insertions(+), 23 deletions(-) diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index a9c0a6df3d2..907fbfdfa16 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -17,12 +18,38 @@ #ifdef CONFIG_MULTI_LEVEL_INTERRUPTS -struct irq_parent_offset { - unsigned int irq; - unsigned int offset; -}; +/* + * Insert code if the node_id is an interrupt controller + */ +#define Z_IF_DT_IS_INTC(node_id, code) \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code)) + +/* + * Expands to node_id if its IRQN is equal to `irq`, nothing otherwise + * This only works for `irq` between 0 & 4095, see `IS_EQ` + */ +#define Z_IF_DT_INTC_IRQN_EQ(node_id, irq) IF_ENABLED(IS_EQ(DT_IRQ(node_id, irq), irq), (node_id)) -#define INIT_IRQ_PARENT_OFFSET(i, o) { \ +/* + * Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise + */ +#define Z_DT_INTC_GET_IRQN(node_id, irq) \ + Z_IF_DT_IS_INTC(node_id, Z_IF_DT_INTC_IRQN_EQ(node_id, irq)) + +/** + * Loop through child of "/soc" and get root interrupt controllers with `irq` as IRQN, + * this assumes only one device has the IRQN + * @param irq irq number + * @return node_id(s) that has the `irq` number, or empty if none of them has the `irq` + */ +#define INTC_DT_IRQN_GET(irq) \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), Z_DT_INTC_GET_IRQN, irq) + +/* If can't find any matching interrupt controller, fills with `NULL` */ +#define INTC_DEVICE_INIT(node_id) .dev = DEVICE_DT_GET_OR_NULL(node_id), + +#define INIT_IRQ_PARENT_OFFSET(d, i, o) { \ + INTC_DEVICE_INIT(d) \ .irq = i, \ .offset = o, \ } @@ -32,9 +59,9 @@ struct irq_parent_offset { #ifdef CONFIG_2ND_LEVEL_INTERRUPTS #define CAT_2ND_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET, \ - IRQ_INDEX_TO_OFFSET(i, base)) -static struct irq_parent_offset lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS] + INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \ + CONFIG_2ND_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) +const struct _irq_parent_entry _lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS] = { LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (,), CONFIG_2ND_LVL_ISR_TBL_OFFSET) }; @@ -43,57 +70,113 @@ static struct irq_parent_offset lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS] #ifdef CONFIG_3RD_LEVEL_INTERRUPTS #define CAT_3RD_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET, \ - IRQ_INDEX_TO_OFFSET(i, base)) -static struct irq_parent_offset lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS] + INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \ + CONFIG_3RD_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) +const struct _irq_parent_entry _lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS] = { LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (,), CONFIG_3RD_LVL_ISR_TBL_OFFSET) }; #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ -unsigned int get_parent_offset(unsigned int parent_irq, - struct irq_parent_offset list[], - unsigned int length) +static const struct _irq_parent_entry *get_parent_entry(unsigned int parent_irq, + const struct _irq_parent_entry list[], + unsigned int length) { unsigned int i; - unsigned int offset = 0U; + const struct _irq_parent_entry *entry = NULL; for (i = 0U; i < length; ++i) { if (list[i].irq == parent_irq) { - offset = list[i].offset; + entry = &list[i]; break; } } __ASSERT(i != length, "Invalid argument: %i", parent_irq); - return offset; + return entry; } #endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ +const struct device *z_get_sw_isr_device_from_irq(unsigned int irq) +{ + const struct device *dev = NULL; + +#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS + unsigned int level, parent_irq; + const struct _irq_parent_entry *entry = NULL; + + level = irq_get_level(irq); + + if (level == 2U) { + parent_irq = irq_parent_level_2(irq); + entry = get_parent_entry(parent_irq, + _lvl2_irq_list, + CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + } +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + else if (level == 3U) { + parent_irq = irq_parent_level_3(irq); + entry = get_parent_entry(parent_irq, + _lvl3_irq_list, + CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + } +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ + dev = entry != NULL ? entry->dev : NULL; +#endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ + + return dev; +} + +unsigned int z_get_sw_isr_irq_from_device(const struct device *dev) +{ +#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS + for (size_t i = 0U; i < CONFIG_NUM_2ND_LEVEL_AGGREGATORS; ++i) { + if (_lvl2_irq_list[i].dev == dev) { + return _lvl2_irq_list[i].irq; + } + } + +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + for (size_t i = 0U; i < CONFIG_NUM_3RD_LEVEL_AGGREGATORS; ++i) { + if (_lvl3_irq_list[i].dev == dev) { + return _lvl3_irq_list[i].irq; + } + } +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ +#else + ARG_UNUSED(dev); +#endif + + return 0; +} + unsigned int z_get_sw_isr_table_idx(unsigned int irq) { unsigned int table_idx; #ifdef CONFIG_MULTI_LEVEL_INTERRUPTS unsigned int level, parent_irq, parent_offset; + const struct _irq_parent_entry *entry = NULL; level = irq_get_level(irq); if (level == 2U) { parent_irq = irq_parent_level_2(irq); - parent_offset = get_parent_offset(parent_irq, - lvl2_irq_list, - CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + entry = get_parent_entry(parent_irq, + _lvl2_irq_list, + CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + parent_offset = entry != NULL ? entry->offset : 0U; table_idx = parent_offset + irq_from_level_2(irq); } #ifdef CONFIG_3RD_LEVEL_INTERRUPTS else if (level == 3U) { parent_irq = irq_parent_level_3(irq); - parent_offset = get_parent_offset(parent_irq, - lvl3_irq_list, - CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + entry = get_parent_entry(parent_irq, + _lvl3_irq_list, + CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + parent_offset = entry != NULL ? entry->offset : 0U; table_idx = parent_offset + irq_from_level_3(irq); } #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index 7db7381422b..fb68272c34c 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -15,6 +15,7 @@ #define ZEPHYR_INCLUDE_SW_ISR_TABLE_H_ #if !defined(_ASMLANGUAGE) +#include #include #include @@ -43,6 +44,12 @@ struct _isr_table_entry { */ extern struct _isr_table_entry _sw_isr_table[]; +struct _irq_parent_entry { + const struct device *dev; + unsigned int irq; + unsigned int offset; +}; + /* * Data structure created in a special binary .intlist section for each * configured interrupt. gen_irq_tables.py pulls this out of the binary and @@ -87,6 +94,25 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; */ unsigned int z_get_sw_isr_table_idx(unsigned int irq); +/** + * @brief Helper function used to get the parent interrupt controller device based on passed IRQ. + * + * @param irq IRQ number in its zephyr format + * + * @return corresponding interrupt controller device in _sw_isr_table + */ +const struct device *z_get_sw_isr_device_from_irq(unsigned int irq); + +/** + * @brief Helper function used to get the IRQN of the passed in parent interrupt + * controller device. + * + * @param dev parent interrupt controller device + * + * @return IRQN of the interrupt controller + */ +unsigned int z_get_sw_isr_irq_from_device(const struct device *dev); + /** This interrupt gets put directly in the vector table */ #define ISR_FLAG_DIRECT BIT(0) From ad788a335f87d41b5ac49afa0e64b6a1a0bda3ea Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 22 Sep 2023 12:43:54 +0800 Subject: [PATCH 3302/4498] tests: interrupt: add testcase for functions in the sw_isr_table Validate the following functions in the sw_isr_table: - z_get_sw_isr_table_idx - z_get_sw_isr_device_from_irq - z_get_sw_isr_irq_from_device Signed-off-by: Yong Cong Sin --- tests/kernel/interrupt/CMakeLists.txt | 4 ++ tests/kernel/interrupt/src/sw_isr_table.c | 54 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/kernel/interrupt/src/sw_isr_table.c diff --git a/tests/kernel/interrupt/CMakeLists.txt b/tests/kernel/interrupt/CMakeLists.txt index 80f3fbca665..645f1f7965b 100644 --- a/tests/kernel/interrupt/CMakeLists.txt +++ b/tests/kernel/interrupt/CMakeLists.txt @@ -22,3 +22,7 @@ target_sources_ifdef(CONFIG_SHARED_INTERRUPTS app PRIVATE src/static_shared_irq. if (CONFIG_SHARED_INTERRUPTS) target_sources_ifdef(CONFIG_DYNAMIC_INTERRUPTS app PRIVATE src/dynamic_shared_irq.c) endif() + +if(CONFIG_MULTI_LEVEL_INTERRUPTS) + target_sources_ifdef(CONFIG_DYNAMIC_INTERRUPTS app PRIVATE src/sw_isr_table.c) +endif() diff --git a/tests/kernel/interrupt/src/sw_isr_table.c b/tests/kernel/interrupt/src/sw_isr_table.c new file mode 100644 index 00000000000..621480905a7 --- /dev/null +++ b/tests/kernel/interrupt/src/sw_isr_table.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +extern const struct _irq_parent_entry _lvl2_irq_list[]; + +/** + * @brief Test sw_isr_table function + * + * @details Validates that: + * - z_get_sw_isr_device_from_irq() returns the parent interrupt controller for an IRQN + * - z_get_sw_isr_irq_from_device() returns the IRQN of a parent interrupt controller + * - z_get_sw_isr_table_idx() returns the corresponding SW ISR table index for an IRQN + */ +ZTEST(interrupt_feature, test_sw_isr_irq_parent_table) +{ + const struct device *parent_dev; + unsigned int parent_irq; + unsigned int parent_isr_offset; + const struct device *test_dev; + unsigned int test_irq; + unsigned int test_isr_offset; + + for (size_t i = 0; i < CONFIG_NUM_2ND_LEVEL_AGGREGATORS; i++) { + parent_dev = _lvl2_irq_list[i].dev; + parent_irq = _lvl2_irq_list[i].irq; + parent_isr_offset = _lvl2_irq_list[i].offset; + + for (unsigned int local_irq = 0; + local_irq < BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS); local_irq++) { + test_irq = irq_to_level_2(local_irq) | parent_irq; + test_dev = z_get_sw_isr_device_from_irq(test_irq); + zassert_equal_ptr(parent_dev, test_dev, "expected dev: %p, got: %p", + parent_dev, test_dev); + } + + test_irq = z_get_sw_isr_irq_from_device(parent_dev); + zassert_equal(parent_irq, test_irq, "expected offset: %d, got: %d", parent_irq, + test_irq); + + for (unsigned int local_irq = 0; + local_irq < BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS); local_irq++) { + test_irq = irq_to_level_2(local_irq) | parent_irq; + test_isr_offset = z_get_sw_isr_table_idx(test_irq); + zassert_equal(parent_isr_offset + local_irq, test_isr_offset, + "expected offset: %d, got: %d", parent_isr_offset + local_irq, + test_isr_offset); + } + } +} From ec93404a2682ca72ec0313c5008b92bf45a69f36 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 16 Oct 2023 15:39:48 +0800 Subject: [PATCH 3303/4498] arch: common: irq: relocate internal functions into a private header Relocate new and existing internal software-managed table access functions from the public `sw_isr_table.h` into a private header that should only be accessed internally. Signed-off-by: Yong Cong Sin --- arch/common/CMakeLists.txt | 2 + arch/common/include/sw_isr_common.h | 57 +++++++++++++++++++++++ arch/common/shared_irq.c | 2 + include/zephyr/sw_isr_table.h | 29 ------------ tests/kernel/interrupt/CMakeLists.txt | 1 + tests/kernel/interrupt/src/sw_isr_table.c | 2 + 6 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 arch/common/include/sw_isr_common.h diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 8056ad5d95d..7421e44631a 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -2,6 +2,8 @@ zephyr_library() +zephyr_library_include_directories(include) + # Library may be empty due to kconfigs zephyr_library_property(ALLOW_EMPTY TRUE) diff --git a/arch/common/include/sw_isr_common.h b/arch/common/include/sw_isr_common.h new file mode 100644 index 00000000000..223c9ba2442 --- /dev/null +++ b/arch/common/include/sw_isr_common.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private header for the software-managed ISR table's functions + */ + +#ifndef ZEPHYR_ARCH_COMMON_INCLUDE_SW_ISR_COMMON_H_ +#define ZEPHYR_ARCH_COMMON_INCLUDE_SW_ISR_COMMON_H_ + +#if !defined(_ASMLANGUAGE) +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Helper function used to compute the index in _sw_isr_table + * based on passed IRQ. + * + * @param irq IRQ number in its zephyr format + * + * @return corresponding index in _sw_isr_table + */ +unsigned int z_get_sw_isr_table_idx(unsigned int irq); + +/** + * @brief Helper function used to get the parent interrupt controller device based on passed IRQ. + * + * @param irq IRQ number in its zephyr format + * + * @return corresponding interrupt controller device in _sw_isr_table + */ +const struct device *z_get_sw_isr_device_from_irq(unsigned int irq); + +/** + * @brief Helper function used to get the IRQN of the passed in parent interrupt + * controller device. + * + * @param dev parent interrupt controller device + * + * @return IRQN of the interrupt controller + */ +unsigned int z_get_sw_isr_irq_from_device(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_ARCH_COMMON_INCLUDE_SW_ISR_COMMON_H_ */ diff --git a/arch/common/shared_irq.c b/arch/common/shared_irq.c index 744aece2fd7..68641cb2bb0 100644 --- a/arch/common/shared_irq.c +++ b/arch/common/shared_irq.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sw_isr_common.h" + #include #include diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index fb68272c34c..f43efafad49 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -84,35 +84,6 @@ void z_shared_isr(const void *data); extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #endif /* CONFIG_SHARED_INTERRUPTS */ -/** - * @brief Helper function used to compute the index in _sw_isr_table - * based on passed IRQ. - * - * @param irq IRQ number in its zephyr format - * - * @return corresponding index in _sw_isr_table - */ -unsigned int z_get_sw_isr_table_idx(unsigned int irq); - -/** - * @brief Helper function used to get the parent interrupt controller device based on passed IRQ. - * - * @param irq IRQ number in its zephyr format - * - * @return corresponding interrupt controller device in _sw_isr_table - */ -const struct device *z_get_sw_isr_device_from_irq(unsigned int irq); - -/** - * @brief Helper function used to get the IRQN of the passed in parent interrupt - * controller device. - * - * @param dev parent interrupt controller device - * - * @return IRQN of the interrupt controller - */ -unsigned int z_get_sw_isr_irq_from_device(const struct device *dev); - /** This interrupt gets put directly in the vector table */ #define ISR_FLAG_DIRECT BIT(0) diff --git a/tests/kernel/interrupt/CMakeLists.txt b/tests/kernel/interrupt/CMakeLists.txt index 645f1f7965b..b464719f89a 100644 --- a/tests/kernel/interrupt/CMakeLists.txt +++ b/tests/kernel/interrupt/CMakeLists.txt @@ -7,6 +7,7 @@ project(interrupt) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/${ARCH}/include + ${ZEPHYR_BASE}/arch/common/include ) target_sources(app PRIVATE diff --git a/tests/kernel/interrupt/src/sw_isr_table.c b/tests/kernel/interrupt/src/sw_isr_table.c index 621480905a7..385f2c244b5 100644 --- a/tests/kernel/interrupt/src/sw_isr_table.c +++ b/tests/kernel/interrupt/src/sw_isr_table.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sw_isr_common.h" + #include extern const struct _irq_parent_entry _lvl2_irq_list[]; From cdb606aa033053a449e470921c086921fc6548fa Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 6 Nov 2023 15:27:30 +0800 Subject: [PATCH 3304/4498] arch: common: refactor multi-level IRQ code Refactor multi-level IRQ related code from `sw_isr_common.c` to `multilevel_irq.c` to simplify `sw_isr_common` & macrologies. Signed-off-by: Yong Cong Sin --- arch/common/CMakeLists.txt | 5 + arch/common/multilevel_irq.c | 167 ++++++++++++++++++++++++++++++++ arch/common/sw_isr_common.c | 182 +---------------------------------- 3 files changed, 177 insertions(+), 177 deletions(-) create mode 100644 arch/common/multilevel_irq.c diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 7421e44631a..e1353c1eaab 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -12,6 +12,11 @@ zephyr_library_sources_ifdef( sw_isr_common.c ) +zephyr_library_sources_ifdef( + CONFIG_MULTI_LEVEL_INTERRUPTS + multilevel_irq.c + ) + zephyr_library_sources_ifdef(CONFIG_SHARED_INTERRUPTS shared_irq.c) if(NOT CONFIG_ARCH_HAS_TIMING_FUNCTIONS AND diff --git a/arch/common/multilevel_irq.c b/arch/common/multilevel_irq.c new file mode 100644 index 00000000000..96f3ab0801f --- /dev/null +++ b/arch/common/multilevel_irq.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2018 Intel Corporation. + * Copyright (c) 2023 Meta. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* + * Insert code if the node_id is an interrupt controller + */ +#define Z_IF_DT_IS_INTC(node_id, code) \ + IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code)) + +/* + * Expands to node_id if its IRQN is equal to `irq`, nothing otherwise + * This only works for `irq` between 0 & 4095, see `IS_EQ` + */ +#define Z_IF_DT_INTC_IRQN_EQ(node_id, irq) IF_ENABLED(IS_EQ(DT_IRQ(node_id, irq), irq), (node_id)) + +/* + * Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise + */ +#define Z_DT_INTC_GET_IRQN(node_id, irq) \ + Z_IF_DT_IS_INTC(node_id, Z_IF_DT_INTC_IRQN_EQ(node_id, irq)) + +/** + * Loop through child of "/soc" and get root interrupt controllers with `irq` as IRQN, + * this assumes only one device has the IRQN + * @param irq irq number + * @return node_id(s) that has the `irq` number, or empty if none of them has the `irq` + */ +#define INTC_DT_IRQN_GET(irq) \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), Z_DT_INTC_GET_IRQN, irq) + +/* If can't find any matching interrupt controller, fills with `NULL` */ +#define INTC_DEVICE_INIT(node_id) .dev = DEVICE_DT_GET_OR_NULL(node_id), + +#define INIT_IRQ_PARENT_OFFSET(d, i, o) { \ + INTC_DEVICE_INIT(d) \ + .irq = i, \ + .offset = o, \ +} + +#define IRQ_INDEX_TO_OFFSET(i, base) (base + i * CONFIG_MAX_IRQ_PER_AGGREGATOR) + +#define CAT_2ND_LVL_LIST(i, base) \ + INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \ + CONFIG_2ND_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) +const struct _irq_parent_entry _lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS] + = { LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (,), + CONFIG_2ND_LVL_ISR_TBL_OFFSET) }; + +#define CAT_3RD_LVL_LIST(i, base) \ + INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \ + CONFIG_3RD_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) + +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + +const struct _irq_parent_entry _lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS] + = { LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (,), + CONFIG_3RD_LVL_ISR_TBL_OFFSET) }; + +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ + +static const struct _irq_parent_entry *get_parent_entry(unsigned int parent_irq, + const struct _irq_parent_entry list[], + unsigned int length) +{ + unsigned int i; + const struct _irq_parent_entry *entry = NULL; + + for (i = 0U; i < length; ++i) { + if (list[i].irq == parent_irq) { + entry = &list[i]; + break; + } + } + + __ASSERT(i != length, "Invalid argument: %i", parent_irq); + + return entry; +} + +const struct device *z_get_sw_isr_device_from_irq(unsigned int irq) +{ + const struct device *dev = NULL; + unsigned int level, parent_irq; + const struct _irq_parent_entry *entry = NULL; + + level = irq_get_level(irq); + + if (level == 2U) { + parent_irq = irq_parent_level_2(irq); + entry = get_parent_entry(parent_irq, + _lvl2_irq_list, + CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + } +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + else if (level == 3U) { + parent_irq = irq_parent_level_3(irq); + entry = get_parent_entry(parent_irq, + _lvl3_irq_list, + CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + } +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ + dev = entry != NULL ? entry->dev : NULL; + + return dev; +} + +unsigned int z_get_sw_isr_irq_from_device(const struct device *dev) +{ + for (size_t i = 0U; i < CONFIG_NUM_2ND_LEVEL_AGGREGATORS; ++i) { + if (_lvl2_irq_list[i].dev == dev) { + return _lvl2_irq_list[i].irq; + } + } + +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + for (size_t i = 0U; i < CONFIG_NUM_3RD_LEVEL_AGGREGATORS; ++i) { + if (_lvl3_irq_list[i].dev == dev) { + return _lvl3_irq_list[i].irq; + } + } +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ + + return 0; +} + +unsigned int z_get_sw_isr_table_idx(unsigned int irq) +{ + unsigned int table_idx; + unsigned int level, parent_irq, parent_offset; + const struct _irq_parent_entry *entry = NULL; + + level = irq_get_level(irq); + + if (level == 2U) { + parent_irq = irq_parent_level_2(irq); + entry = get_parent_entry(parent_irq, + _lvl2_irq_list, + CONFIG_NUM_2ND_LEVEL_AGGREGATORS); + parent_offset = entry != NULL ? entry->offset : 0U; + table_idx = parent_offset + irq_from_level_2(irq); + } +#ifdef CONFIG_3RD_LEVEL_INTERRUPTS + else if (level == 3U) { + parent_irq = irq_parent_level_3(irq); + entry = get_parent_entry(parent_irq, + _lvl3_irq_list, + CONFIG_NUM_3RD_LEVEL_AGGREGATORS); + parent_offset = entry != NULL ? entry->offset : 0U; + table_idx = parent_offset + irq_from_level_3(irq); + } +#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ + else { + table_idx = irq; + } + + table_idx -= CONFIG_GEN_IRQ_START_VECTOR; + + return table_idx; +} diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index 907fbfdfa16..9ed50e1084f 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -4,193 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "sw_isr_common.h" #include -#include #include -#include #include -/* - * Common code for arches that use software ISR tables (CONFIG_GEN_ISR_TABLES) - */ - -#ifdef CONFIG_DYNAMIC_INTERRUPTS - -#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS /* - * Insert code if the node_id is an interrupt controller - */ -#define Z_IF_DT_IS_INTC(node_id, code) \ - IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code)) - -/* - * Expands to node_id if its IRQN is equal to `irq`, nothing otherwise - * This only works for `irq` between 0 & 4095, see `IS_EQ` - */ -#define Z_IF_DT_INTC_IRQN_EQ(node_id, irq) IF_ENABLED(IS_EQ(DT_IRQ(node_id, irq), irq), (node_id)) - -/* - * Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise - */ -#define Z_DT_INTC_GET_IRQN(node_id, irq) \ - Z_IF_DT_IS_INTC(node_id, Z_IF_DT_INTC_IRQN_EQ(node_id, irq)) - -/** - * Loop through child of "/soc" and get root interrupt controllers with `irq` as IRQN, - * this assumes only one device has the IRQN - * @param irq irq number - * @return node_id(s) that has the `irq` number, or empty if none of them has the `irq` + * Common code for arches that use software ISR tables (CONFIG_GEN_ISR_TABLES) */ -#define INTC_DT_IRQN_GET(irq) \ - DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), Z_DT_INTC_GET_IRQN, irq) - -/* If can't find any matching interrupt controller, fills with `NULL` */ -#define INTC_DEVICE_INIT(node_id) .dev = DEVICE_DT_GET_OR_NULL(node_id), - -#define INIT_IRQ_PARENT_OFFSET(d, i, o) { \ - INTC_DEVICE_INIT(d) \ - .irq = i, \ - .offset = o, \ -} - -#define IRQ_INDEX_TO_OFFSET(i, base) (base + i * CONFIG_MAX_IRQ_PER_AGGREGATOR) - -#ifdef CONFIG_2ND_LEVEL_INTERRUPTS - -#define CAT_2ND_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \ - CONFIG_2ND_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) -const struct _irq_parent_entry _lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS] - = { LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (,), - CONFIG_2ND_LVL_ISR_TBL_OFFSET) }; - -#endif/* CONFIG_2ND_LEVEL_INTERRUPTS */ - -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS - -#define CAT_3RD_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \ - CONFIG_3RD_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base)) -const struct _irq_parent_entry _lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS] - = { LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (,), - CONFIG_3RD_LVL_ISR_TBL_OFFSET) }; - -#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ -static const struct _irq_parent_entry *get_parent_entry(unsigned int parent_irq, - const struct _irq_parent_entry list[], - unsigned int length) +unsigned int __weak z_get_sw_isr_table_idx(unsigned int irq) { - unsigned int i; - const struct _irq_parent_entry *entry = NULL; - - for (i = 0U; i < length; ++i) { - if (list[i].irq == parent_irq) { - entry = &list[i]; - break; - } - } - - __ASSERT(i != length, "Invalid argument: %i", parent_irq); - - return entry; + return irq - CONFIG_GEN_IRQ_START_VECTOR; } -#endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ - -const struct device *z_get_sw_isr_device_from_irq(unsigned int irq) -{ - const struct device *dev = NULL; - -#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS - unsigned int level, parent_irq; - const struct _irq_parent_entry *entry = NULL; - - level = irq_get_level(irq); - - if (level == 2U) { - parent_irq = irq_parent_level_2(irq); - entry = get_parent_entry(parent_irq, - _lvl2_irq_list, - CONFIG_NUM_2ND_LEVEL_AGGREGATORS); - } -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS - else if (level == 3U) { - parent_irq = irq_parent_level_3(irq); - entry = get_parent_entry(parent_irq, - _lvl3_irq_list, - CONFIG_NUM_3RD_LEVEL_AGGREGATORS); - } -#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ - dev = entry != NULL ? entry->dev : NULL; -#endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ - - return dev; -} - -unsigned int z_get_sw_isr_irq_from_device(const struct device *dev) -{ -#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS - for (size_t i = 0U; i < CONFIG_NUM_2ND_LEVEL_AGGREGATORS; ++i) { - if (_lvl2_irq_list[i].dev == dev) { - return _lvl2_irq_list[i].irq; - } - } - -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS - for (size_t i = 0U; i < CONFIG_NUM_3RD_LEVEL_AGGREGATORS; ++i) { - if (_lvl3_irq_list[i].dev == dev) { - return _lvl3_irq_list[i].irq; - } - } -#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ -#else - ARG_UNUSED(dev); -#endif - - return 0; -} - -unsigned int z_get_sw_isr_table_idx(unsigned int irq) -{ - unsigned int table_idx; - -#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS - unsigned int level, parent_irq, parent_offset; - const struct _irq_parent_entry *entry = NULL; - - level = irq_get_level(irq); - - if (level == 2U) { - parent_irq = irq_parent_level_2(irq); - entry = get_parent_entry(parent_irq, - _lvl2_irq_list, - CONFIG_NUM_2ND_LEVEL_AGGREGATORS); - parent_offset = entry != NULL ? entry->offset : 0U; - table_idx = parent_offset + irq_from_level_2(irq); - } -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS - else if (level == 3U) { - parent_irq = irq_parent_level_3(irq); - entry = get_parent_entry(parent_irq, - _lvl3_irq_list, - CONFIG_NUM_3RD_LEVEL_AGGREGATORS); - parent_offset = entry != NULL ? entry->offset : 0U; - table_idx = parent_offset + irq_from_level_3(irq); - } -#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ - else { - table_idx = irq; - } - - table_idx -= CONFIG_GEN_IRQ_START_VECTOR; -#else - table_idx = irq - CONFIG_GEN_IRQ_START_VECTOR; -#endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ - - return table_idx; -} +#ifdef CONFIG_DYNAMIC_INTERRUPTS void __weak z_isr_install(unsigned int irq, void (*routine)(const void *), const void *param) From 63bd547e9f084013a25f8ce61da6f05b4c663b59 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 6 Nov 2023 15:37:52 +0800 Subject: [PATCH 3305/4498] arch: common: guard the compilation of sw_isr_common with CMakeLists.txt Instead of using a macro guard to prevent functions in `sw_isr_common.c` from getting compiled when `CONFIG_DYNAMIC_INTERRUPTS` isn't enabled, do that in `CMakeLists.txt` instead. Signed-off-by: Yong Cong Sin --- arch/common/CMakeLists.txt | 11 ++++++--- arch/common/dynamic_isr.c | 49 +++++++++++++++++++++++++++++++++++++ arch/common/sw_isr_common.c | 43 -------------------------------- 3 files changed, 57 insertions(+), 46 deletions(-) create mode 100644 arch/common/dynamic_isr.c diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index e1353c1eaab..1a89ba9c13a 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -7,10 +7,15 @@ zephyr_library_include_directories(include) # Library may be empty due to kconfigs zephyr_library_property(ALLOW_EMPTY TRUE) -zephyr_library_sources_ifdef( - CONFIG_GEN_ISR_TABLES - sw_isr_common.c +if(CONFIG_GEN_ISR_TABLES) + zephyr_library_sources( + sw_isr_common.c ) + zephyr_library_sources_ifdef( + CONFIG_DYNAMIC_INTERRUPTS + dynamic_isr.c + ) +endif() zephyr_library_sources_ifdef( CONFIG_MULTI_LEVEL_INTERRUPTS diff --git a/arch/common/dynamic_isr.c b/arch/common/dynamic_isr.c new file mode 100644 index 00000000000..9f56977f259 --- /dev/null +++ b/arch/common/dynamic_isr.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sw_isr_common.h" +#include +#include +#include + +void __weak z_isr_install(unsigned int irq, void (*routine)(const void *), + const void *param) +{ + unsigned int table_idx; + + /* + * Do not assert on the IRQ enable status for ARM GIC since the SGI + * type interrupts are always enabled and attempting to install an ISR + * for them will cause the assertion to fail. + */ +#ifndef CONFIG_GIC + __ASSERT(!irq_is_enabled(irq), "IRQ %d is enabled", irq); +#endif /* !CONFIG_GIC */ + + table_idx = z_get_sw_isr_table_idx(irq); + + /* If dynamic IRQs are enabled, then the _sw_isr_table is in RAM and + * can be modified + */ + _sw_isr_table[table_idx].arg = param; + _sw_isr_table[table_idx].isr = routine; +} + +/* Some architectures don't/can't interpret flags or priority and have + * no more processing to do than this. Provide a generic fallback. + */ +int __weak arch_irq_connect_dynamic(unsigned int irq, + unsigned int priority, + void (*routine)(const void *), + const void *parameter, + uint32_t flags) +{ + ARG_UNUSED(flags); + ARG_UNUSED(priority); + + z_isr_install(irq, routine, parameter); + return irq; +} diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index 9ed50e1084f..5efdeb89a67 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -17,46 +17,3 @@ unsigned int __weak z_get_sw_isr_table_idx(unsigned int irq) { return irq - CONFIG_GEN_IRQ_START_VECTOR; } - -#ifdef CONFIG_DYNAMIC_INTERRUPTS - -void __weak z_isr_install(unsigned int irq, void (*routine)(const void *), - const void *param) -{ - unsigned int table_idx; - - /* - * Do not assert on the IRQ enable status for ARM GIC since the SGI - * type interrupts are always enabled and attempting to install an ISR - * for them will cause the assertion to fail. - */ -#ifndef CONFIG_GIC - __ASSERT(!irq_is_enabled(irq), "IRQ %d is enabled", irq); -#endif /* !CONFIG_GIC */ - - table_idx = z_get_sw_isr_table_idx(irq); - - /* If dynamic IRQs are enabled, then the _sw_isr_table is in RAM and - * can be modified - */ - _sw_isr_table[table_idx].arg = param; - _sw_isr_table[table_idx].isr = routine; -} - -/* Some architectures don't/can't interpret flags or priority and have - * no more processing to do than this. Provide a generic fallback. - */ -int __weak arch_irq_connect_dynamic(unsigned int irq, - unsigned int priority, - void (*routine)(const void *), - const void *parameter, - uint32_t flags) -{ - ARG_UNUSED(flags); - ARG_UNUSED(priority); - - z_isr_install(irq, routine, parameter); - return irq; -} - -#endif /* CONFIG_DYNAMIC_INTERRUPTS */ From 7485ef91f54a682c8061a38e7da523ee483f5ed4 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 6 Nov 2023 15:53:50 +0800 Subject: [PATCH 3306/4498] irq: multilevel: reduce the use of macros Convert `#if defined CONFIG_*` to use `if (IS_ENABLED(CONFIG_*))` and removed some macro guards since they are safe to be compile. Signed-off-by: Yong Cong Sin --- include/zephyr/irq_multilevel.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/include/zephyr/irq_multilevel.h b/include/zephyr/irq_multilevel.h index 7d320ca1419..3a2b5116602 100644 --- a/include/zephyr/irq_multilevel.h +++ b/include/zephyr/irq_multilevel.h @@ -45,7 +45,6 @@ static inline unsigned int irq_get_level(unsigned int irq) return 1; } -#if defined(CONFIG_2ND_LEVEL_INTERRUPTS) /** * @brief Return the 2nd level interrupt number * @@ -58,12 +57,12 @@ static inline unsigned int irq_get_level(unsigned int irq) */ static inline unsigned int irq_from_level_2(unsigned int irq) { -#if defined(CONFIG_3RD_LEVEL_INTERRUPTS) - return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & - BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; -#else - return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) - 1; -#endif + if (IS_ENABLED(CONFIG_3RD_LEVEL_INTERRUPTS)) { + return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & + BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1; + } else { + return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) - 1; + } } /** @@ -106,9 +105,7 @@ static inline unsigned int irq_parent_level_2(unsigned int irq) { return irq & BIT_MASK(CONFIG_1ST_LEVEL_INTERRUPT_BITS); } -#endif -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS /** * @brief Return the 3rd level interrupt number * @@ -167,7 +164,6 @@ static inline unsigned int irq_parent_level_3(unsigned int irq) return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) & BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS); } -#endif #ifdef __cplusplus } From 7f7b097499e4ca212ccd554b52e94367d722cfa3 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 28 Sep 2023 13:25:34 +0200 Subject: [PATCH 3307/4498] bluetooth: tester: MCP Client tests Add support for Media Control Client tests Signed-off-by: Piotr Narajowski --- tests/bluetooth/tester/CMakeLists.txt | 4 + tests/bluetooth/tester/overlay-le-audio.conf | 5 + tests/bluetooth/tester/src/btp/btp.h | 4 +- tests/bluetooth/tester/src/btp/btp_mcp.h | 291 ++++ tests/bluetooth/tester/src/btp/bttester.h | 3 + tests/bluetooth/tester/src/btp_core.c | 13 + tests/bluetooth/tester/src/btp_mcp.c | 1319 ++++++++++++++++++ 7 files changed, 1638 insertions(+), 1 deletion(-) create mode 100644 tests/bluetooth/tester/src/btp/btp_mcp.h create mode 100644 tests/bluetooth/tester/src/btp_mcp.c diff --git a/tests/bluetooth/tester/CMakeLists.txt b/tests/bluetooth/tester/CMakeLists.txt index d76de937f5d..842b6ebe5d8 100644 --- a/tests/bluetooth/tester/CMakeLists.txt +++ b/tests/bluetooth/tester/CMakeLists.txt @@ -59,3 +59,7 @@ endif() if (CONFIG_BT_CAP_ACCEPTOR) target_sources(app PRIVATE src/btp_cas.c) endif() + +if(CONFIG_BT_MCC) + target_sources(app PRIVATE src/btp_mcp.c) +endif() diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 1db37efb5a3..530558c1308 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -92,3 +92,8 @@ CONFIG_BT_TBS_CLIENT_TBS=n # CAS CONFIG_BT_CAP_ACCEPTOR=y CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER=y + +# MCP +CONFIG_BT_MCC=y +CONFIG_BT_OTS_CLIENT=y +CONFIG_BT_MCC_OTS=y diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index b1092dc6d5d..c7781932801 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -30,6 +30,7 @@ #include "btp_ccp.h" #include "btp_vcp.h" #include "btp_cas.h" +#include "btp_mcp.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -59,8 +60,9 @@ #define BTP_SERVICE_ID_CCP 19 #define BTP_SERVICE_ID_VCP 20 #define BTP_SERVICE_ID_CAS 21 +#define BTP_SERVICE_ID_MCP 22 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_CAS +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_MCP #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/tests/bluetooth/tester/src/btp/btp_mcp.h b/tests/bluetooth/tester/src/btp/btp_mcp.h new file mode 100644 index 00000000000..d9b7f84e410 --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_mcp.h @@ -0,0 +1,291 @@ +/* btp_mcp.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/* MCP commands */ +#define BTP_MCP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_mcp_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MCP_DISCOVER 0x02 +struct btp_mcp_discover_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_TRACK_DURATION_READ 0x03 +struct btp_mcp_track_duration_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_TRACK_POSITION_READ 0x04 +struct btp_mcp_track_position_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_TRACK_POSITION_SET 0x05 +struct btp_mcp_track_position_set_cmd { + bt_addr_le_t address; + int32_t pos; +} __packed; + +#define BTP_MCP_PLAYBACK_SPEED_READ 0x06 +struct btp_mcp_playback_speed_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_PLAYBACK_SPEED_SET 0x07 +struct btp_mcp_playback_speed_set { + bt_addr_le_t address; + int8_t speed; +} __packed; + +#define BTP_MCP_SEEKING_SPEED_READ 0x08 +struct btp_mcp_seeking_speed_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_ICON_OBJ_ID_READ 0x09 +struct btp_mcp_icon_obj_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_NEXT_TRACK_OBJ_ID_READ 0x0a +struct btp_mcp_next_track_obj_id_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_NEXT_TRACK_OBJ_ID_SET 0x0b +struct btp_mcp_set_next_track_obj_id_cmd { + bt_addr_le_t address; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_PARENT_GROUP_OBJ_ID_READ 0x0c +struct btp_mcp_parent_group_obj_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_CURRENT_GROUP_OBJ_ID_READ 0x0d +struct btp_mcp_current_group_obj_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_CURRENT_GROUP_OBJ_ID_SET 0x0e +struct btp_mcp_current_group_obj_id_set_cmd { + bt_addr_le_t address; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_PLAYING_ORDER_READ 0x0f +struct btp_mcp_playing_order_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_PLAYING_ORDER_SET 0x10 +struct btp_mcp_playing_order_set_cmd { + bt_addr_le_t address; + uint8_t order; +} __packed; + +#define BTP_MCP_PLAYING_ORDERS_SUPPORTED_READ 0x11 +struct btp_mcp_playing_orders_supported_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_MEDIA_STATE_READ 0x12 +struct btp_mcp_media_state_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_OPCODES_SUPPORTED_READ 0x13 +struct btp_mcp_opcodes_supported_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_CONTENT_CONTROL_ID_READ 0x14 +struct btp_mcp_content_control_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_SEGMENTS_OBJ_ID_READ 0x15 +struct btp_mcp_segments_obj_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_CURRENT_TRACK_OBJ_ID_READ 0x16 +struct btp_mcp_current_track_obj_id_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MCP_CURRENT_TRACK_OBJ_ID_SET 0x17 +struct btp_mcp_current_track_obj_id_set_cmd { + bt_addr_le_t address; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_CMD_SEND 0x18 +struct btp_mcp_send_cmd { + bt_addr_le_t address; + uint8_t opcode; + uint8_t use_param; + int32_t param; +} __packed; + +#define BTP_MCP_CMD_SEARCH 0x19 +struct btp_mcp_search_cmd { + bt_addr_le_t address; + uint8_t type; + uint8_t param_len; + uint8_t param[]; +} __packed; + +/* MCP events */ +#define BTP_MCP_DISCOVERED_EV 0x80 +struct btp_mcp_discovered_ev { + bt_addr_le_t address; + uint8_t status; +} __packed; + +#define BTP_MCP_TRACK_DURATION_EV 0x81 +struct btp_mcp_track_duration_ev { + bt_addr_le_t address; + uint8_t status; + int32_t dur; +} __packed; + +#define BTP_MCP_TRACK_POSITION_EV 0x82 +struct btp_mcp_track_position_ev { + bt_addr_le_t address; + uint8_t status; + int32_t pos; +} __packed; + +#define BTP_MCP_PLAYBACK_SPEED_EV 0x83 +struct btp_mcp_playback_speed_ev { + bt_addr_le_t address; + uint8_t status; + int8_t speed; +} __packed; + +#define BTP_MCP_SEEKING_SPEED_EV 0x84 +struct btp_mcp_seeking_speed_ev { + bt_addr_le_t address; + uint8_t status; + int8_t speed; +} __packed; + +#define BTP_MCP_ICON_OBJ_ID_EV 0x85 +struct btp_mcp_icon_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_NEXT_TRACK_OBJ_ID_EV 0x86 +struct btp_mcp_next_track_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_PARENT_GROUP_OBJ_ID_EV 0x87 +struct btp_mcp_parent_group_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_CURRENT_GROUP_OBJ_ID_EV 0x88 +struct btp_mcp_current_group_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_PLAYING_ORDER_EV 0x89 +struct btp_mcp_playing_order_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t order; +} __packed; + +#define BTP_MCP_PLAYING_ORDERS_SUPPORTED_EV 0x8a +struct btp_mcp_playing_orders_supported_ev { + bt_addr_le_t address; + uint8_t status; + uint16_t orders; +} __packed; + +#define BTP_MCP_MEDIA_STATE_EV 0x8b +struct btp_mcp_media_state_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t state; +} __packed; + +#define BTP_MCP_OPCODES_SUPPORTED_EV 0x8c +struct btp_mcp_opcodes_supported_ev { + bt_addr_le_t address; + uint8_t status; + uint32_t opcodes; +} __packed; + +#define BTP_MCP_CONTENT_CONTROL_ID_EV 0x8d +struct btp_mcp_content_control_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t ccid; +} __packed; + +#define BTP_MCP_SEGMENTS_OBJ_ID_EV 0x8e +struct btp_mcp_segments_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_CURRENT_TRACK_OBJ_ID_EV 0x8f +struct btp_mcp_current_track_obj_id_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t id[BT_OTS_OBJ_ID_SIZE]; +} __packed; + +#define BTP_MCP_MEDIA_CP_EV 0x90 +struct btp_mcp_media_cp_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t opcode; + bool use_param; + int32_t param; +} __packed; + +#define BTP_MCP_SEARCH_CP_EV 0x91 +struct btp_mcp_search_cp_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t param_len; + uint8_t search_type; + uint8_t param[]; +} __packed; + +#define BTP_MCP_NTF_EV 0x92 +struct btp_mcp_cmd_ntf_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t requested_opcode; + uint8_t result_code; +} __packed; + +#define BTP_SCP_NTF_EV 0x93 +struct btp_scp_cmd_ntf_ev { + bt_addr_le_t address; + uint8_t status; + uint8_t result_code; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index b6ddc561cf4..ce8b1259a42 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -114,3 +114,6 @@ uint8_t tester_unregister_vcp(void); uint8_t tester_init_cas(void); uint8_t tester_unregister_cas(void); + +uint8_t tester_init_mcp(void); +uint8_t tester_unregister_mcp(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index b91aa5be1e1..1840d2d5d0b 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -92,6 +92,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_CAP_ACCEPTOR) tester_set_bit(rp->data, BTP_SERVICE_ID_CAS); #endif /* CONFIG_BT_CAP_ACCEPTOR */ +#if defined(CONFIG_BT_MCC) + tester_set_bit(rp->data, BTP_SERVICE_ID_MCP); +#endif /* CONFIG_BT_MCC */ *rsp_len = sizeof(*rp) + 2; @@ -192,6 +195,11 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_cas(); break; #endif /* CONFIG_BT_CAP_ACCEPTOR */ +#if defined(CONFIG_BT_MCC) + case BTP_SERVICE_ID_MCP: + status = tester_init_mcp(); + break; +#endif /* CONFIG_BT_MCC */ default: LOG_WRN("unknown id: 0x%02x", cp->id); status = BTP_STATUS_FAILED; @@ -291,6 +299,11 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_cas(); break; #endif /* CONFIG_BT_CAP_ACCEPTOR */ +#if defined(CONFIG_BT_MCC) + case BTP_SERVICE_ID_MCP: + status = tester_unregister_mcp(); + break; +#endif /* CONFIG_BT_MCC */ default: LOG_WRN("unknown id: 0x%x", cp->id); status = BTP_STATUS_FAILED; diff --git a/tests/bluetooth/tester/src/btp_mcp.c b/tests/bluetooth/tester/src/btp_mcp.c new file mode 100644 index 00000000000..d04dca35dc0 --- /dev/null +++ b/tests/bluetooth/tester/src/btp_mcp.c @@ -0,0 +1,1319 @@ +/* btp_mcp.c - Bluetooth MCP Tester */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "bap_endpoint.h" +#include "btp/btp.h" +#include "../../../../include/zephyr/bluetooth/audio/media_proxy.h" + +#define LOG_MODULE_NAME bttester_mcp +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); + +#define SEARCH_LEN_MAX 64 + +static struct net_buf_simple *rx_ev_buf = NET_BUF_SIMPLE(SEARCH_LEN_MAX + + sizeof(struct btp_mcp_search_cp_ev)); + +/* Media Control Profile */ +static void btp_send_mcp_found_ev(struct bt_conn *conn, uint8_t status) +{ + struct btp_mcp_discovered_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_DISCOVERED_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_track_duration_ev(struct bt_conn *conn, uint8_t status, int32_t dur) +{ + struct btp_mcp_track_duration_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.dur = sys_cpu_to_le32(dur); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_TRACK_DURATION_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_track_position_ev(struct bt_conn *conn, uint8_t status, int32_t pos) +{ + struct btp_mcp_track_position_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.pos = sys_cpu_to_le32(pos); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_TRACK_POSITION_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_playback_speed_ev(struct bt_conn *conn, uint8_t status, int8_t speed) +{ + struct btp_mcp_playback_speed_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.speed = speed; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYBACK_SPEED_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_seeking_speed_ev(struct bt_conn *conn, uint8_t status, int8_t speed) +{ + struct btp_mcp_seeking_speed_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.speed = speed; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEEKING_SPEED_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_icon_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id) +{ + struct btp_mcp_icon_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_ICON_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_next_track_obj_id_ev(struct bt_conn *conn, uint8_t status, + uint64_t id) +{ + struct btp_mcp_next_track_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_NEXT_TRACK_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_parent_group_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id) +{ + struct btp_mcp_parent_group_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PARENT_GROUP_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_current_group_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id) +{ + struct btp_mcp_current_group_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CURRENT_GROUP_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_playing_order_ev(struct bt_conn *conn, uint8_t status, uint8_t order) +{ + struct btp_mcp_playing_order_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.order = order; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYING_ORDER_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_playing_orders_supported_ev(struct bt_conn *conn, uint8_t status, + uint16_t orders) +{ + struct btp_mcp_playing_orders_supported_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.orders = sys_cpu_to_le16(orders); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYING_ORDERS_SUPPORTED_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_media_state_ev(struct bt_conn *conn, uint8_t status, uint8_t state) +{ + struct btp_mcp_media_state_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.state = state; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_MEDIA_STATE_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_opcodes_supported_ev(struct bt_conn *conn, uint8_t status, + uint32_t opcodes) +{ + struct btp_mcp_opcodes_supported_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.opcodes = sys_cpu_to_le32(opcodes); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_OPCODES_SUPPORTED_EV, &ev, sizeof(ev)); +} + +static void btp_send_mcp_content_control_id_ev(struct bt_conn *conn, uint8_t status, + uint8_t ccid) +{ + struct btp_mcp_content_control_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.ccid = ccid; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CONTENT_CONTROL_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_segments_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id) +{ + struct btp_mcp_segments_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEGMENTS_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_current_track_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id) +{ + struct btp_mcp_current_track_obj_id_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + sys_put_le48(id, ev.id); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CURRENT_TRACK_OBJ_ID_EV, &ev, sizeof(ev)); +} + +static void btp_send_media_cp_ev(struct bt_conn *conn, uint8_t status, + const struct mpl_cmd *cmd) +{ + struct btp_mcp_media_cp_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.opcode = cmd->opcode; + ev.use_param = cmd->use_param; + ev.param = sys_cpu_to_le32(cmd->param); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_MEDIA_CP_EV, &ev, sizeof(ev)); +} + +static void btp_send_search_cp_ev(struct bt_conn *conn, uint8_t status, + const struct mpl_search *search) +{ + struct btp_mcp_search_cp_ev *ev; + uint8_t param[SEARCH_LEN_MAX]; + + net_buf_simple_init(rx_ev_buf, 0); + + ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev)); + + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); + + ev->status = status; + ev->param_len = (uint8_t)search->search[0]; + + if (ev->param_len > (SEARCH_LEN_MAX - sizeof(ev->param_len))) { + return; + } + + ev->search_type = search->search[1]; + strcpy(param, &search->search[2]); + net_buf_simple_add_mem(rx_ev_buf, param, ev->param_len); + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEARCH_CP_EV, ev, sizeof(*ev) + ev->param_len); +} + +static void btp_send_command_notifications_ev(struct bt_conn *conn, uint8_t status, + const struct mpl_cmd_ntf *ntf) +{ + struct btp_mcp_cmd_ntf_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.requested_opcode = ntf->requested_opcode; + ev.result_code = ntf->result_code; + + tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_NTF_EV, &ev, sizeof(ev)); +} + +static void btp_send_search_notifications_ev(struct bt_conn *conn, uint8_t status, + uint8_t result_code) +{ + struct btp_scp_cmd_ntf_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + ev.status = status; + ev.result_code = result_code; + + tester_event(BTP_SERVICE_ID_MCP, BTP_SCP_NTF_EV, &ev, sizeof(ev)); +} + +static void mcc_discover_cb(struct bt_conn *conn, int err) +{ + if (err) { + LOG_DBG("Discovery failed (%d)", err); + return; + } + + btp_send_mcp_found_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); +} + +static void mcc_read_track_duration_cb(struct bt_conn *conn, int err, int32_t dur) +{ + LOG_DBG("MCC Read track duration cb (%d)", err); + + btp_send_mcp_track_duration_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, dur); +} + +static void mcc_read_track_position_cb(struct bt_conn *conn, int err, int32_t pos) +{ + LOG_DBG("MCC Read track position cb (%d)", err); + + btp_send_mcp_track_position_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, pos); +} + +static void mcc_set_track_position_cb(struct bt_conn *conn, int err, int32_t pos) +{ + LOG_DBG("MCC Set track position cb (%d)", err); + + btp_send_mcp_track_position_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, pos); +} + +static void mcc_read_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed) +{ + LOG_DBG("MCC read playback speed cb (%d)", err); + + btp_send_mcp_playback_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed); +} + +static void mcc_set_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed) +{ + LOG_DBG("MCC set playback speed cb (%d)", err); + + btp_send_mcp_playback_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed); +} + +static void mcc_read_seeking_speed_cb(struct bt_conn *conn, int err, int8_t speed) +{ + LOG_DBG("MCC read seeking speed cb (%d)", err); + + btp_send_mcp_seeking_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed); +} + +static void mcc_read_icon_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC read Icon Object ID cb (%d)", err); + + btp_send_mcp_icon_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_read_next_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC read next track obj ID cb (%d)", err); + + btp_send_mcp_next_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_set_next_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC set next track obj ID cb (%d)", err); + + btp_send_mcp_next_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_read_parent_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC read parent group obj ID cb (%d)", err); + + btp_send_parent_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_read_current_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC read current group obj ID cb (%d)", err); + + btp_send_current_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_set_current_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC read current group obj ID cb (%d)", err); + + btp_send_current_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_read_playing_order_cb(struct bt_conn *conn, int err, uint8_t order) +{ + LOG_DBG("MCC read playing order cb (%d)", err); + + btp_send_mcp_playing_order_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, order); +} + +static void mcc_set_playing_order_cb(struct bt_conn *conn, int err, uint8_t order) +{ + LOG_DBG("MCC set playing order cb (%d)", err); + + btp_send_mcp_playing_order_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, order); +} + +static void mcc_read_playing_orders_supported_cb(struct bt_conn *conn, int err, uint16_t orders) +{ + LOG_DBG("MCC set playing order cb (%d)", err); + + btp_send_mcp_playing_orders_supported_ev(conn, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, + orders); +} + +static void mcc_media_state_read_cb(struct bt_conn *conn, int err, uint8_t state) +{ + LOG_DBG("MCC media state read cb (%d)", err); + + btp_send_mcp_media_state_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, state); +} + +static void mcc_opcodes_supported_cb(struct bt_conn *conn, int err, uint32_t opcodes) +{ + LOG_DBG("MCC opcodes supported cb (%d)", err); + + btp_send_mcp_opcodes_supported_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, + opcodes); +} + +static void mcc_content_control_id_cb(struct bt_conn *conn, int err, uint8_t ccid) +{ + LOG_DBG("MCC Content control ID cb (%d)", err); + + btp_send_mcp_content_control_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, + ccid); +} + +static void mcc_segments_object_id_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC Segments Object ID cb (%d)", err); + + btp_send_segments_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_current_track_obj_id_read_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC Segments Object ID read cb (%d)", err); + + btp_send_current_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_current_track_obj_id_set_cb(struct bt_conn *conn, int err, uint64_t id) +{ + LOG_DBG("MCC Segments Object ID set cb (%d)", err); + + btp_send_current_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id); +} + +static void mcc_send_cmd_cb(struct bt_conn *conn, int err, const struct mpl_cmd *cmd) +{ + LOG_DBG("MCC Send Command cb (%d)", err); + + btp_send_media_cp_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, cmd); +} + +static void mcc_send_search_cb(struct bt_conn *conn, int err, const struct mpl_search *search) +{ + LOG_DBG("MCC Send Search cb (%d)", err); + + btp_send_search_cp_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, search); +} + +static void mcc_cmd_ntf_cb(struct bt_conn *conn, int err, const struct mpl_cmd_ntf *ntf) +{ + LOG_DBG("MCC Media Control Point Command Notify cb (%d)", err); + + btp_send_command_notifications_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, ntf); +} + +static void mcc_search_ntf_cb(struct bt_conn *conn, int err, uint8_t result_code) +{ + LOG_DBG("MCC Search Control Point Notify cb (%d)", err); + + btp_send_search_notifications_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, + result_code); +} + +static struct bt_mcc_cb mcp_cb = { + .discover_mcs = mcc_discover_cb, + .read_track_duration = mcc_read_track_duration_cb, + .read_track_position = mcc_read_track_position_cb, + .set_track_position = mcc_set_track_position_cb, + .read_playback_speed = mcc_read_playback_speed_cb, + .set_playback_speed = mcc_set_playback_speed_cb, + .read_seeking_speed = mcc_read_seeking_speed_cb, + .read_playing_order = mcc_read_playing_order_cb, + .set_playing_order = mcc_set_playing_order_cb, + .read_playing_orders_supported = mcc_read_playing_orders_supported_cb, + .read_media_state = mcc_media_state_read_cb, + .read_opcodes_supported = mcc_opcodes_supported_cb, + .read_content_control_id = mcc_content_control_id_cb, + .send_cmd = mcc_send_cmd_cb, + .cmd_ntf = mcc_cmd_ntf_cb, +#ifdef CONFIG_BT_OTS_CLIENT + .read_icon_obj_id = mcc_read_icon_obj_id_cb, + .read_next_track_obj_id = mcc_read_next_track_obj_id_cb, + .set_next_track_obj_id = mcc_set_next_track_obj_id_cb, + .read_parent_group_obj_id = mcc_read_parent_group_obj_id_cb, + .read_current_group_obj_id = mcc_read_current_group_obj_id_cb, + .set_current_group_obj_id = mcc_set_current_group_obj_id_cb, + .read_segments_obj_id = mcc_segments_object_id_cb, + .read_current_track_obj_id = mcc_current_track_obj_id_read_cb, + .set_current_track_obj_id = mcc_current_track_obj_id_set_cb, + .send_search = mcc_send_search_cb, + .search_ntf = mcc_search_ntf_cb, +#endif /* CONFIG_BT_OTS_CLIENT */ +}; + +static uint8_t mcp_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + struct btp_mcp_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_MCP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_MCP_DISCOVER); + tester_set_bit(rp->data, BTP_MCP_TRACK_DURATION_READ); + tester_set_bit(rp->data, BTP_MCP_TRACK_POSITION_READ); + tester_set_bit(rp->data, BTP_MCP_TRACK_POSITION_SET); + tester_set_bit(rp->data, BTP_MCP_PLAYBACK_SPEED_READ); + tester_set_bit(rp->data, BTP_MCP_PLAYBACK_SPEED_SET); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_MCP_SEEKING_SPEED_READ); + tester_set_bit(rp->data, BTP_MCP_ICON_OBJ_ID_READ); + tester_set_bit(rp->data, BTP_MCP_NEXT_TRACK_OBJ_ID_READ); + tester_set_bit(rp->data, BTP_MCP_NEXT_TRACK_OBJ_ID_SET); + tester_set_bit(rp->data, BTP_MCP_PARENT_GROUP_OBJ_ID_READ); + tester_set_bit(rp->data, BTP_MCP_CURRENT_GROUP_OBJ_ID_READ); + tester_set_bit(rp->data, BTP_MCP_CURRENT_GROUP_OBJ_ID_SET); + + /* octet 2 */ + tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDER_READ); + tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDER_SET); + tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDERS_SUPPORTED_READ); + tester_set_bit(rp->data, BTP_MCP_MEDIA_STATE_READ); + tester_set_bit(rp->data, BTP_MCP_OPCODES_SUPPORTED_READ); + tester_set_bit(rp->data, BTP_MCP_CONTENT_CONTROL_ID_READ); + tester_set_bit(rp->data, BTP_MCP_SEGMENTS_OBJ_ID_READ); + + /* octet 3 */ + tester_set_bit(rp->data, BTP_MCP_CURRENT_TRACK_OBJ_ID_READ); + tester_set_bit(rp->data, BTP_MCP_CURRENT_TRACK_OBJ_ID_SET); + tester_set_bit(rp->data, BTP_MCP_CMD_SEND); + tester_set_bit(rp->data, BTP_MCP_CMD_SEARCH); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_discover(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_mcp_discover_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_discover_mcs(conn, true); + if (err) { + LOG_DBG("Discovery failed: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_track_duration_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_track_duration_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read track duration"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_track_duration(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_track_position_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_track_position_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read track position"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_track_position(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_track_position_set(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_track_position_set_cmd *cp = cmd; + uint32_t pos = sys_le32_to_cpu(cp->pos); + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set track position"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_track_position(conn, pos); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_playback_speed_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_playback_speed_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read playback speed"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_playback_speed(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_playback_speed_set(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_playback_speed_set *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set playback speed"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_playback_speed(conn, cp->speed); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_seeking_speed_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_seeking_speed_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read seeking speed"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_seeking_speed(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_read_icon_obj_id(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_icon_obj_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read Icon Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_icon_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_read_next_track_obj_id(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_next_track_obj_id_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read Next Track Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_next_track_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_set_next_track_obj_id(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_set_next_track_obj_id_cmd *cp = cmd; + uint64_t id = sys_get_le48(cp->id); + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set Next Track Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_next_track_obj_id(conn, id); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_parent_group_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_parent_group_obj_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read Parent Group Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_parent_group_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_current_group_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_current_group_obj_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read Current Group Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_current_group_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_set_current_group_obj_id(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_current_group_obj_id_set_cmd *cp = cmd; + uint64_t id = sys_get_le48(cp->id); + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set Next Track Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_current_group_obj_id(conn, id); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_playing_order_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_playing_order_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Read Playing Order"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_playing_order(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_playing_order_set(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_playing_order_set_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set Playing Order"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_playing_order(conn, cp->order); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_playing_orders_supported_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_playing_orders_supported_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Playing orders supported read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_playing_orders_supported(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_media_state_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_media_state_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Media State read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_media_state(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_opcodes_supported_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_opcodes_supported_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Supported opcodes read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_opcodes_supported(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_content_control_id_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_content_control_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Content Control ID read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_content_control_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_segments_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_segments_obj_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Track Segments Object ID read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_segments_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_current_track_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_current_track_obj_id_read_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Current Track Object ID read"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_read_current_track_obj_id(conn); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_current_track_obj_id_set(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_mcp_current_track_obj_id_set_cmd *cp = cmd; + uint64_t id = sys_get_le48(cp->id); + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Set Current Track Object ID"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_mcc_set_current_track_obj_id(conn, id); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_cmd_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_mcp_send_cmd *cp = cmd; + struct mpl_cmd mcp_cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Send Command"); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + mcp_cmd.opcode = cp->opcode; + mcp_cmd.use_param = cp->use_param; + mcp_cmd.param = sys_le32_to_cpu(cp->param); + + err = bt_mcc_send_cmd(conn, &mcp_cmd); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t mcp_cmd_search(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct btp_mcp_search_cmd *cp = cmd; + struct mpl_search search_items; + struct mpl_sci scp_cmd; + struct bt_conn *conn; + int err; + + LOG_DBG("MCC Send Search Control Point Command"); + + if (cmd_len < sizeof(*cp) || cmd_len != sizeof(*cp) + cp->param_len) { + return BTP_STATUS_FAILED; + } + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + search_items.len = 0; + scp_cmd.type = cp->type; + + if (scp_cmd.type == BT_MCS_SEARCH_TYPE_ONLY_TRACKS || + scp_cmd.type == BT_MCS_SEARCH_TYPE_ONLY_GROUPS) { + scp_cmd.len = sizeof(scp_cmd.type); + + if (ARRAY_SIZE(search_items.search) < (sizeof(scp_cmd.len) + + sizeof(scp_cmd.type))) { + return BTP_STATUS_FAILED; + } + + memcpy(&search_items.search[search_items.len], &scp_cmd.len, sizeof(scp_cmd.len)); + search_items.len += sizeof(scp_cmd.len); + + memcpy(&search_items.search[search_items.len], &scp_cmd.type, + sizeof(scp_cmd.type)); + search_items.len += sizeof(scp_cmd.type); + } else { + if (cp->param_len >= (SEARCH_LEN_MAX - 1)) { + return BTP_STATUS_FAILED; + } + + strcpy(scp_cmd.param, cp->param); + scp_cmd.len = sizeof(scp_cmd.type) + strlen(scp_cmd.param); + + if (ARRAY_SIZE(search_items.search) < (sizeof(scp_cmd.len) + sizeof(scp_cmd.len) + + strlen(scp_cmd.param))) { + return BTP_STATUS_FAILED; + } + + memcpy(&search_items.search[search_items.len], &scp_cmd.len, sizeof(scp_cmd.len)); + search_items.len += sizeof(scp_cmd.len); + + memcpy(&search_items.search[search_items.len], &scp_cmd.type, + sizeof(scp_cmd.type)); + search_items.len += sizeof(scp_cmd.type); + + strcpy(&search_items.search[search_items.len], scp_cmd.param); + search_items.len += strlen(scp_cmd.param); + search_items.search[search_items.len] = '\0'; + } + + err = bt_mcc_send_search(conn, &search_items); + if (err) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler mcp_handlers[] = { + { + .opcode = BTP_MCP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = mcp_supported_commands, + }, + { + .opcode = BTP_MCP_DISCOVER, + .expect_len = sizeof(struct btp_mcp_discover_cmd), + .func = mcp_discover, + }, + { + .opcode = BTP_MCP_TRACK_DURATION_READ, + .expect_len = sizeof(struct btp_mcp_track_duration_cmd), + .func = mcp_track_duration_read, + }, + { + .opcode = BTP_MCP_TRACK_POSITION_READ, + .expect_len = sizeof(struct btp_mcp_track_position_read_cmd), + .func = mcp_track_position_read, + }, + { + .opcode = BTP_MCP_TRACK_POSITION_SET, + .expect_len = sizeof(struct btp_mcp_track_position_set_cmd), + .func = mcp_track_position_set, + }, + { + .opcode = BTP_MCP_PLAYBACK_SPEED_READ, + .expect_len = sizeof(struct btp_mcp_playback_speed_read_cmd), + .func = mcp_playback_speed_read, + }, + { + .opcode = BTP_MCP_PLAYBACK_SPEED_SET, + .expect_len = sizeof(struct btp_mcp_playback_speed_set), + .func = mcp_playback_speed_set, + }, + { + .opcode = BTP_MCP_SEEKING_SPEED_READ, + .expect_len = sizeof(struct btp_mcp_seeking_speed_read_cmd), + .func = mcp_seeking_speed_read, + }, + { + .opcode = BTP_MCP_ICON_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_icon_obj_id_read_cmd), + .func = mcp_read_icon_obj_id, + }, + { + .opcode = BTP_MCP_NEXT_TRACK_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_next_track_obj_id_cmd), + .func = mcp_read_next_track_obj_id, + }, + { + .opcode = BTP_MCP_NEXT_TRACK_OBJ_ID_SET, + .expect_len = sizeof(struct btp_mcp_set_next_track_obj_id_cmd), + .func = mcp_set_next_track_obj_id, + }, + { + .opcode = BTP_MCP_PARENT_GROUP_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_parent_group_obj_id_read_cmd), + .func = mcp_parent_group_obj_id_read, + }, + { + .opcode = BTP_MCP_CURRENT_GROUP_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_current_group_obj_id_read_cmd), + .func = mcp_current_group_obj_id_read, + }, + { + .opcode = BTP_MCP_CURRENT_GROUP_OBJ_ID_SET, + .expect_len = sizeof(struct btp_mcp_current_group_obj_id_set_cmd), + .func = mcp_set_current_group_obj_id, + }, + { + .opcode = BTP_MCP_PLAYING_ORDER_READ, + .expect_len = sizeof(struct btp_mcp_playing_order_read_cmd), + .func = mcp_playing_order_read, + }, + { + .opcode = BTP_MCP_PLAYING_ORDER_SET, + .expect_len = sizeof(struct btp_mcp_playing_order_set_cmd), + .func = mcp_playing_order_set, + }, + { + .opcode = BTP_MCP_PLAYING_ORDERS_SUPPORTED_READ, + .expect_len = sizeof(struct btp_mcp_playing_orders_supported_read_cmd), + .func = mcp_playing_orders_supported_read, + }, + { + .opcode = BTP_MCP_MEDIA_STATE_READ, + .expect_len = sizeof(struct btp_mcp_media_state_read_cmd), + .func = mcp_media_state_read, + }, + { + .opcode = BTP_MCP_OPCODES_SUPPORTED_READ, + .expect_len = sizeof(struct btp_mcp_opcodes_supported_read_cmd), + .func = mcp_opcodes_supported_read, + }, + { + .opcode = BTP_MCP_CONTENT_CONTROL_ID_READ, + .expect_len = sizeof(struct btp_mcp_content_control_id_read_cmd), + .func = mcp_content_control_id_read, + }, + { + .opcode = BTP_MCP_SEGMENTS_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_segments_obj_id_read_cmd), + .func = mcp_segments_obj_id_read, + }, + { + .opcode = BTP_MCP_CURRENT_TRACK_OBJ_ID_READ, + .expect_len = sizeof(struct btp_mcp_current_track_obj_id_read_cmd), + .func = mcp_current_track_obj_id_read, + }, + { + .opcode = BTP_MCP_CURRENT_TRACK_OBJ_ID_SET, + .expect_len = sizeof(struct btp_mcp_current_track_obj_id_set_cmd), + .func = mcp_current_track_obj_id_set, + }, + { + .opcode = BTP_MCP_CMD_SEND, + .expect_len = sizeof(struct btp_mcp_send_cmd), + .func = mcp_cmd_send, + }, + { + .opcode = BTP_MCP_CMD_SEARCH, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = mcp_cmd_search, + }, +}; + +uint8_t tester_init_mcp(void) +{ + int err; + + err = bt_mcc_init(&mcp_cb); + if (err) { + LOG_DBG("Failed to initialize Media Control Client: %d", err); + return BTP_STATUS_FAILED; + } + + tester_register_command_handlers(BTP_SERVICE_ID_MCP, mcp_handlers, + ARRAY_SIZE(mcp_handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_mcp(void) +{ + return BTP_STATUS_SUCCESS; +} From ed17320c3d2e43c76b09dc359d3b371e9d23732d Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 8 Nov 2023 20:23:37 +0530 Subject: [PATCH 3308/4498] net: Remove unnecessary lock The main action in this function it queueing the packet for transmission which doesn't need a lock and interface flags use atomic operations. So, remove the unnecessary lock. Signed-off-by: Chaitanya Tata --- subsys/net/ip/net_if.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 9f5a3306f94..099618b8476 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -437,8 +437,6 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt) enum net_verdict verdict = NET_OK; int status = -EIO; - net_if_lock(iface); - if (!net_if_flag_is_set(iface, NET_IF_LOWER_UP) || net_if_flag_is_set(iface, NET_IF_SUSPENDED)) { /* Drop packet if interface is not up */ @@ -521,8 +519,6 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt) net_if_queue_tx(iface, pkt); } - net_if_unlock(iface); - return verdict; } From c33ed20eb87c39b9f415f0ca1b33abf6b500124b Mon Sep 17 00:00:00 2001 From: Ning Yang Date: Wed, 8 Nov 2023 10:24:36 +0800 Subject: [PATCH 3309/4498] drivers: dma: copy whole user dma config to fix dma case failure user dma config is not fully saved in dma_sedi_chan_config function. When dma_sedi_start function it will check local context, it will cause failure here. Signed-off-by: Ning Yang --- drivers/dma/dma_sedi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/dma_sedi.c b/drivers/dma/dma_sedi.c index 629ca8f0e20..96ae8bbf8fb 100644 --- a/drivers/dma/dma_sedi.c +++ b/drivers/dma/dma_sedi.c @@ -254,9 +254,8 @@ static int dma_sedi_chan_config(const struct device *dev, uint32_t channel, const struct dma_sedi_config_info *const info = DEV_CFG(dev); struct dma_sedi_driver_data *const data = DEV_DATA(dev); - struct dma_config *local_config = &(data->dma_configs[channel]); - local_config->head_block = config->head_block; + memcpy(&(data->dma_configs[channel]), config, sizeof(struct dma_config)); /* initialize the dma controller, following the sedi api*/ sedi_dma_event_cb_t cb = dma_handler; From 1158c5dc01ca0033ea489e549f8d1c8596c0ecbd Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 23 Oct 2023 15:35:51 +0200 Subject: [PATCH 3310/4498] include: coap: Fix typo Fixed a typo to include DOXYGEN generated documentation. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index ebc72709751..b80e93df32a 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -274,7 +274,7 @@ struct coap_packet { uint8_t hdr_len; /**< CoAP header length */ uint16_t opt_len; /**< Total options length (delta + len + value) */ uint16_t delta; /**< Used for delta calculation in CoAP packet */ -#if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(DOXGEN) +#if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(DOXYGEN) /** * Application specific user data. * Only available when @kconfig{CONFIG_COAP_KEEP_USER_DATA} is enabled. From bea29cf631e581e05456b0ae76651d15814ab853 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 25 Sep 2023 22:05:54 +0200 Subject: [PATCH 3311/4498] net: lib: coap: Add resources length based variants Add length variant for the well known core resource and parsing. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 26 +++++++- include/zephyr/net/coap_link_format.h | 36 ++++++++++- subsys/net/lib/coap/coap.c | 39 ++++++++---- subsys/net/lib/coap/coap_link_format.c | 85 +++++++++++++++++--------- 4 files changed, 141 insertions(+), 45 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index b80e93df32a..efe2d010d0b 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -583,12 +583,36 @@ int coap_packet_append_payload(struct coap_packet *cpkt, const uint8_t *payload, * * @param cpkt Packet received * @param resources Array of known resources + * @param resources_len Number of resources in the array * @param options Parsed options from coap_packet_parse() * @param opt_num Number of options * @param addr Peer address * @param addr_len Peer address length * - * @retval 0 in case of success. + * @retval >= 0 in case of success. + * @retval -ENOTSUP in case of invalid request code. + * @retval -EPERM in case resource handler is not implemented. + * @retval -ENOENT in case the resource is not found. + */ +int coap_handle_request_len(struct coap_packet *cpkt, + struct coap_resource *resources, + size_t resources_len, + struct coap_option *options, + uint8_t opt_num, + struct sockaddr *addr, socklen_t addr_len); + +/** + * @brief When a request is received, call the appropriate methods of + * the matching resources. + * + * @param cpkt Packet received + * @param resources Array of known resources (terminated with empty resource) + * @param options Parsed options from coap_packet_parse() + * @param opt_num Number of options + * @param addr Peer address + * @param addr_len Peer address length + * + * @retval >= 0 in case of success. * @retval -ENOTSUP in case of invalid request code. * @retval -EPERM in case resource handler is not implemented. * @retval -ENOENT in case the resource is not found. diff --git a/include/zephyr/net/coap_link_format.h b/include/zephyr/net/coap_link_format.h index 17374202b6d..cabfb9ff859 100644 --- a/include/zephyr/net/coap_link_format.h +++ b/include/zephyr/net/coap_link_format.h @@ -24,15 +24,45 @@ extern "C" { /** * This resource should be added before all other resources that should be - * included in the responses of the .well-known/core resource. + * included in the responses of the .well-known/core resource if is to be used with + * coap_well_known_core_get. */ #define COAP_WELL_KNOWN_CORE_PATH \ ((const char * const[]) { ".well-known", "core", NULL }) +/** + * @brief Build a CoAP response for a .well-known/core CoAP request. + * + * @param resource Array of known resources, terminated with an empty resource + * @param request A pointer to the .well-known/core CoAP request + * @param response A pointer to a CoAP response, will be initialized + * @param data A data pointer to be used to build the CoAP response + * @param data_len The maximum length of the data buffer + * + * @return 0 in case of success or negative in case of error. + */ int coap_well_known_core_get(struct coap_resource *resource, - struct coap_packet *request, + const struct coap_packet *request, struct coap_packet *response, - uint8_t *data, uint16_t len); + uint8_t *data, uint16_t data_len); + +/** + * @brief Build a CoAP response for a .well-known/core CoAP request. + * + * @param resources Array of known resources + * @param resources_len Number of resources in the array + * @param request A pointer to the .well-known/core CoAP request + * @param response A pointer to a CoAP response, will be initialized + * @param data A data pointer to be used to build the CoAP response + * @param data_len The maximum length of the data buffer + * + * @return 0 in case of success or negative in case of error. + */ +int coap_well_known_core_get_len(struct coap_resource *resources, + size_t resources_len, + const struct coap_packet *request, + struct coap_packet *response, + uint8_t *data, uint16_t data_len); /** * In case you want to add attributes to the resources included in the diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 8ac8d73e78d..45974210367 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1147,29 +1147,28 @@ static bool is_request(const struct coap_packet *cpkt) return !(code & ~COAP_REQUEST_MASK); } -int coap_handle_request(struct coap_packet *cpkt, - struct coap_resource *resources, - struct coap_option *options, - uint8_t opt_num, - struct sockaddr *addr, socklen_t addr_len) +int coap_handle_request_len(struct coap_packet *cpkt, + struct coap_resource *resources, + size_t resources_len, + struct coap_option *options, + uint8_t opt_num, + struct sockaddr *addr, socklen_t addr_len) { - struct coap_resource *resource; - if (!is_request(cpkt)) { return 0; } /* FIXME: deal with hierarchical resources */ - for (resource = resources; resource && resource->path; resource++) { + for (size_t i = 0; i < resources_len; i++) { coap_method_t method; uint8_t code; - if (!uri_path_eq(cpkt, resource->path, options, opt_num)) { + if (!uri_path_eq(cpkt, resources[i].path, options, opt_num)) { continue; } code = coap_header_get_code(cpkt); - if (method_from_code(resource, code, &method) < 0) { + if (method_from_code(&resources[i], code, &method) < 0) { return -ENOTSUP; } @@ -1177,13 +1176,29 @@ int coap_handle_request(struct coap_packet *cpkt, return -EPERM; } - return method(resource, cpkt, addr, addr_len); + return method(&resources[i], cpkt, addr, addr_len); } - NET_DBG("%d", __LINE__); return -ENOENT; } +int coap_handle_request(struct coap_packet *cpkt, + struct coap_resource *resources, + struct coap_option *options, + uint8_t opt_num, + struct sockaddr *addr, socklen_t addr_len) +{ + size_t resources_len = 0; + struct coap_resource *resource; + + for (resource = resources; resource && resource->path; resource++) { + resources_len++; + } + + return coap_handle_request_len(cpkt, resources, resources_len, options, opt_num, addr, + addr_len); +} + int coap_block_transfer_init(struct coap_block_context *ctx, enum coap_block_size block_size, size_t total_size) diff --git a/subsys/net/lib/coap/coap_link_format.c b/subsys/net/lib/coap/coap_link_format.c index 10c72d62c9e..a3ea175b2df 100644 --- a/subsys/net/lib/coap/coap_link_format.c +++ b/subsys/net/lib/coap/coap_link_format.c @@ -432,10 +432,11 @@ int clear_more_flag(struct coap_packet *cpkt) return 0; } -int coap_well_known_core_get(struct coap_resource *resource, - struct coap_packet *request, - struct coap_packet *response, - uint8_t *data, uint16_t len) +int coap_well_known_core_get_len(struct coap_resource *resources, + size_t resources_len, + struct coap_packet *request, + struct coap_packet *response, + uint8_t *data, uint16_t len) { static struct coap_block_context ctx; struct coap_option query; @@ -446,9 +447,9 @@ int coap_well_known_core_get(struct coap_resource *resource, uint16_t id; uint8_t tkl; int r; - bool more = false; + bool more = false, first = true; - if (!resource || !request || !response || !data || !len) { + if (!resources || !request || !response || !data || !len) { return -EINVAL; } @@ -505,29 +506,31 @@ int coap_well_known_core_get(struct coap_resource *resource, offset = 0; remaining = coap_block_size_to_bytes(ctx.block_size); - while (resource++ && resource->path) { + for (size_t i = 0; i < resources_len; ++i) { if (!remaining) { more = true; break; } - if (!match_queries_resource(resource, &query, num_queries)) { + if (!match_queries_resource(&resources[i], &query, num_queries)) { continue; } - r = format_resource(resource, response, &remaining, &offset, - ctx.current, &more); - if (r < 0) { - goto end; - } - - if ((resource + 1) && (resource + 1)->path) { + if (first) { + first = false; + } else { r = append_to_coap_pkt(response, ",", 1, &remaining, &offset, ctx.current); if (!r) { goto end; } } + + r = format_resource(&resources[i], response, &remaining, &offset, + ctx.current, &more); + if (r < 0) { + goto end; + } } /* Offset is the total size now, but block2 option is already @@ -631,10 +634,11 @@ static int format_resource(const struct coap_resource *resource, return format_attributes(attributes, response); } -int coap_well_known_core_get(struct coap_resource *resource, - struct coap_packet *request, - struct coap_packet *response, - uint8_t *data, uint16_t len) +int coap_well_known_core_get_len(struct coap_resource *resources, + size_t resources_len, + const struct coap_packet *request, + struct coap_packet *response, + uint8_t *data, uint16_t data_len) { struct coap_option query; uint8_t token[COAP_TOKEN_MAX_LEN]; @@ -642,8 +646,9 @@ int coap_well_known_core_get(struct coap_resource *resource, uint8_t tkl; uint8_t num_queries; int r; + bool first = true; - if (!resource || !request || !response || !data || !len) { + if (!resources || !request || !response || !data || !data_len) { return -EINVAL; } @@ -660,7 +665,7 @@ int coap_well_known_core_get(struct coap_resource *resource, num_queries = r; - r = coap_packet_init(response, data, len, COAP_VERSION_1, COAP_TYPE_ACK, + r = coap_packet_init(response, data, data_len, COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, COAP_RESPONSE_CODE_CONTENT, id); if (r < 0) { return r; @@ -677,28 +682,50 @@ int coap_well_known_core_get(struct coap_resource *resource, return -EINVAL; } - while (resource++ && resource->path) { - if (!match_queries_resource(resource, &query, num_queries)) { + for (size_t i = 0; i < resources_len; ++i) { + if (!match_queries_resource(&resources[i], &query, num_queries)) { continue; } - r = format_resource(resource, response); - if (r < 0) { - return r; - } - - if ((resource + 1)->path) { + if (first) { + first = false; + } else { r = append_u8(response, (uint8_t) ','); if (!r) { return -ENOMEM; } } + + r = format_resource(&resources[i], response); + if (r < 0) { + return r; + } } return 0; } #endif +int coap_well_known_core_get(struct coap_resource *resource, + const struct coap_packet *request, + struct coap_packet *response, + uint8_t *data, uint16_t data_len) +{ + struct coap_resource *resources = resource + 1; + size_t resources_len = 0; + + if (resource == NULL) { + return -EINVAL; + } + + while (resources[resources_len].path) { + resources_len++; + } + + return coap_well_known_core_get_len(resources, resources_len, request, response, data, + data_len); +} + /* Exposing some of the APIs to CoAP unit tests in tests/net/lib/coap */ #if defined(CONFIG_COAP_TEST_API_ENABLE) bool _coap_match_path_uri(const char * const *path, From 0a4668a2f73bc17eaa11396fe7813a56bb220583 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 27 Sep 2023 14:47:42 +0200 Subject: [PATCH 3312/4498] net: lib: coap: Add coap_uri_path_match Add URI path matching function to public CoAP API. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 14 ++++++++++++++ subsys/net/lib/coap/coap.c | 9 ++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index efe2d010d0b..ee511b71a48 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -403,6 +403,20 @@ uint16_t coap_header_get_id(const struct coap_packet *cpkt); const uint8_t *coap_packet_get_payload(const struct coap_packet *cpkt, uint16_t *len); +/** + * @brief Verify if CoAP URI path matches with provided options. + * + * @param path Null-terminated array of strings. + * @param options Parsed options from coap_packet_parse() + * @param opt_num Number of options + * + * @return true if the CoAP URI path matches, + * false otherwise. + */ +bool coap_uri_path_match(const char * const *path, + struct coap_option *options, + uint8_t opt_num); + /** * @brief Parses the CoAP packet in data, validating it and * initializing @a cpkt. @a data must remain valid while @a cpkt is used. diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 45974210367..c8f12b71e13 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1056,10 +1056,9 @@ const uint8_t *coap_packet_get_payload(const struct coap_packet *cpkt, uint16_t cpkt->data + cpkt->hdr_len + cpkt->opt_len + 1; } -static bool uri_path_eq(const struct coap_packet *cpkt, - const char * const *path, - struct coap_option *options, - uint8_t opt_num) +bool coap_uri_path_match(const char * const *path, + struct coap_option *options, + uint8_t opt_num) { uint8_t i; uint8_t j = 0U; @@ -1163,7 +1162,7 @@ int coap_handle_request_len(struct coap_packet *cpkt, coap_method_t method; uint8_t code; - if (!uri_path_eq(cpkt, resources[i].path, options, opt_num)) { + if (!coap_uri_path_match(resources[i].path, options, opt_num)) { continue; } From cc893388887a4c0d2d7723619b3cb71bc13f3d6b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 27 Sep 2023 15:05:12 +0200 Subject: [PATCH 3313/4498] net: lib: coap: Add coap_packet_is_request Add function to check if CoAP packet is a request to the public API. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 10 ++++++++++ subsys/net/lib/coap/coap.c | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index ee511b71a48..67a70cbc43a 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -591,6 +591,16 @@ int coap_packet_append_payload_marker(struct coap_packet *cpkt); int coap_packet_append_payload(struct coap_packet *cpkt, const uint8_t *payload, uint16_t payload_len); +/** + * @brief Check if a CoAP packet is a CoAP request. + * + * @param cpkt Packet to be checked. + * + * @return true if the packet is a request, + * false otherwise. + */ +bool coap_packet_is_request(const struct coap_packet *cpkt); + /** * @brief When a request is received, call the appropriate methods of * the matching resources. diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index c8f12b71e13..bd266360f98 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1139,7 +1139,7 @@ static inline bool is_empty_message(const struct coap_packet *cpkt) return __coap_header_get_code(cpkt) == COAP_CODE_EMPTY; } -static bool is_request(const struct coap_packet *cpkt) +bool coap_packet_is_request(const struct coap_packet *cpkt) { uint8_t code = coap_header_get_code(cpkt); @@ -1153,7 +1153,7 @@ int coap_handle_request_len(struct coap_packet *cpkt, uint8_t opt_num, struct sockaddr *addr, socklen_t addr_len) { - if (!is_request(cpkt)) { + if (!coap_packet_is_request(cpkt)) { return 0; } @@ -1219,7 +1219,7 @@ int coap_block_transfer_init(struct coap_block_context *ctx, int coap_append_descriptive_block_option(struct coap_packet *cpkt, struct coap_block_context *ctx) { - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { return coap_append_block1_option(cpkt, ctx); } else { return coap_append_block2_option(cpkt, ctx); @@ -1228,7 +1228,7 @@ int coap_append_descriptive_block_option(struct coap_packet *cpkt, struct coap_b bool coap_has_descriptive_block_option(struct coap_packet *cpkt) { - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { return coap_get_option_int(cpkt, COAP_OPTION_BLOCK1) >= 0; } else { return coap_get_option_int(cpkt, COAP_OPTION_BLOCK2) >= 0; @@ -1237,7 +1237,7 @@ bool coap_has_descriptive_block_option(struct coap_packet *cpkt) int coap_remove_descriptive_block_option(struct coap_packet *cpkt) { - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { return coap_packet_remove_option(cpkt, COAP_OPTION_BLOCK1); } else { return coap_packet_remove_option(cpkt, COAP_OPTION_BLOCK2); @@ -1251,7 +1251,7 @@ int coap_append_block1_option(struct coap_packet *cpkt, unsigned int val = 0U; int r; - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { SET_BLOCK_SIZE(val, ctx->block_size); SET_MORE(val, ctx->current + bytes < ctx->total_size); SET_NUM(val, ctx->current / bytes); @@ -1271,7 +1271,7 @@ int coap_append_block2_option(struct coap_packet *cpkt, int r, val = 0; uint16_t bytes = coap_block_size_to_bytes(ctx->block_size); - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { SET_BLOCK_SIZE(val, ctx->block_size); SET_NUM(val, ctx->current / bytes); } else { @@ -1479,7 +1479,7 @@ int coap_update_from_block(const struct coap_packet *cpkt, size1 = coap_get_option_int(cpkt, COAP_OPTION_SIZE1); size2 = coap_get_option_int(cpkt, COAP_OPTION_SIZE2); - if (is_request(cpkt)) { + if (coap_packet_is_request(cpkt)) { r = update_control_block2(ctx, block2, size2); if (r) { return r; @@ -1534,7 +1534,7 @@ size_t coap_next_block(const struct coap_packet *cpkt, enum coap_option_num option; int ret; - option = is_request(cpkt) ? COAP_OPTION_BLOCK1 : COAP_OPTION_BLOCK2; + option = coap_packet_is_request(cpkt) ? COAP_OPTION_BLOCK1 : COAP_OPTION_BLOCK2; ret = coap_next_block_for_option(cpkt, ctx, option); return MAX(ret, 0); @@ -1737,7 +1737,7 @@ struct coap_reply *coap_response_received( uint8_t tkl; size_t i; - if (!is_empty_message(response) && is_request(response)) { + if (!is_empty_message(response) && coap_packet_is_request(response)) { /* Request can't be response */ return NULL; } From fac670e1e26c8d3487f84fbb2e158aaef1c7c51b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 9 Oct 2023 09:57:46 +0200 Subject: [PATCH 3314/4498] net: lib: coap: Add coap_find_observer_by_token Add a CoAP helper function to find a matching observer by token. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 15 +++++++++++++++ subsys/net/lib/coap/coap.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 67a70cbc43a..42eee01cfc1 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -916,6 +916,21 @@ struct coap_observer *coap_find_observer_by_addr( struct coap_observer *observers, size_t len, const struct sockaddr *addr); +/** + * @brief Returns the observer that has token @a token. + * + * @param observers Pointer to the array of observers + * @param len Size of the array of observers + * @param token Pointer to the token + * @param token_len Length of valid bytes in the token + * + * @return A pointer to a observer if a match is found, NULL + * otherwise. + */ +struct coap_observer *coap_find_observer_by_token( + struct coap_observer *observers, size_t len, + const uint8_t *token, uint8_t token_len); + /** * @brief Returns the next available observer representation. * diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index bd266360f98..a7dd9302ba2 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1915,6 +1915,25 @@ struct coap_observer *coap_find_observer_by_addr( return NULL; } +struct coap_observer *coap_find_observer_by_token( + struct coap_observer *observers, size_t len, + const uint8_t *token, uint8_t token_len) +{ + if (token_len == 0U || token_len > COAP_TOKEN_MAX_LEN) { + return NULL; + } + + for (size_t i = 0; i < len; i++) { + struct coap_observer *o = &observers[i]; + + if (o->tkl == token_len && memcmp(o->token, token, token_len) == 0) { + return o; + } + } + + return NULL; +} + /** * @brief Internal initialization function for CoAP library. * From 291743b686499ec13b909c318c74ab720da667ed Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 9 Oct 2023 10:08:33 +0200 Subject: [PATCH 3315/4498] net: lib: coap: coap_remove_observer result type Change coap_remove_observer to return the result of removing the observer if found. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 4 +++- subsys/net/lib/coap/coap.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 42eee01cfc1..ddc6b080df5 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -898,8 +898,10 @@ bool coap_register_observer(struct coap_resource *resource, * * @param resource Resource in which to remove the observer * @param observer Observer to be removed + * + * @return true if the observer was found and removed. */ -void coap_remove_observer(struct coap_resource *resource, +bool coap_remove_observer(struct coap_resource *resource, struct coap_observer *observer); /** diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index a7dd9302ba2..97226fc9c54 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1856,10 +1856,10 @@ bool coap_register_observer(struct coap_resource *resource, return first; } -void coap_remove_observer(struct coap_resource *resource, +bool coap_remove_observer(struct coap_resource *resource, struct coap_observer *observer) { - sys_slist_find_and_remove(&resource->observers, &observer->list); + return sys_slist_find_and_remove(&resource->observers, &observer->list); } static bool sockaddr_equal(const struct sockaddr *a, From 5227f248153f67e05b0ede9f859deb6f63ed4456 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 23 Oct 2023 14:55:45 +0200 Subject: [PATCH 3316/4498] net: lib: coap: Add support for observer event callbacks This commit adds the option to register an event handler to CoAP resources when observers are added/removed. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 30 ++++++++++++++++++++++++++++++ subsys/net/lib/coap/Kconfig | 6 ++++++ subsys/net/lib/coap/coap.c | 17 ++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index ddc6b080df5..ef9eb660ff4 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -238,6 +238,29 @@ typedef int (*coap_method_t)(struct coap_resource *resource, typedef void (*coap_notify_t)(struct coap_resource *resource, struct coap_observer *observer); +/** + * @brief Event types for observer event callbacks. + */ +enum coap_observer_event { + /** An observer was added. */ + COAP_OBSERVER_ADDED = 0, + /** An observer was removed. */ + COAP_OBSERVER_REMOVED, +}; + +/** + * @typedef coap_observer_event_handler_t + * @brief Type of the handler being called when a resource's observers has been modified. + * Either an observer was added or removed. + * + * @param resource A pointer to a CoAP resource for which the event occurred + * @param observer The observer being added/removed + * @param event The event type + */ +typedef void (*coap_observer_event_handler_t)(struct coap_resource *resource, + struct coap_observer *observer, + enum coap_observer_event event); + /** * @brief Description of CoAP resource. * @@ -252,6 +275,13 @@ struct coap_resource { void *user_data; sys_slist_t observers; int age; +#if defined(CONFIG_COAP_OBSERVER_EVENTS) || defined(DOXYGEN) + /** + * Optional observer event callback function + * Only available when @kconfig{CONFIG_COAP_OBSERVER_EVENTS} is enabled. + */ + coap_observer_event_handler_t observer_event_handler; +#endif }; /** diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index e7587ab21ac..00ee157a116 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -89,6 +89,12 @@ config COAP_URI_WILDCARD This option enables MQTT-style wildcards in path. Disable it if resource path may contain plus or hash symbol. +config COAP_OBSERVER_EVENTS + bool "CoAP resource observer events" + help + This option enables to register a callback function to CoAP resources + that will be called when adding/removing observers. + config COAP_KEEP_USER_DATA bool "Keeping user data in the CoAP packet" help diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 97226fc9c54..9747e33fc56 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1853,13 +1853,28 @@ bool coap_register_observer(struct coap_resource *resource, resource->age = 2; } +#ifdef CONFIG_COAP_OBSERVER_EVENTS + if (resource->observer_event_handler) { + resource->observer_event_handler(resource, observer, COAP_OBSERVER_ADDED); + } +#endif + return first; } bool coap_remove_observer(struct coap_resource *resource, struct coap_observer *observer) { - return sys_slist_find_and_remove(&resource->observers, &observer->list); + if (!sys_slist_find_and_remove(&resource->observers, &observer->list)) { + return false; + } + +#ifdef CONFIG_COAP_OBSERVER_EVENTS + if (resource->observer_event_handler) { + resource->observer_event_handler(resource, observer, COAP_OBSERVER_REMOVED); + } +#endif + return true; } static bool sockaddr_equal(const struct sockaddr *a, From ae6e0106e7a0309d55b343760dabbdd915a42eae Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 21 Sep 2023 17:25:22 +0200 Subject: [PATCH 3317/4498] net: lib: coap: Add service support Add CoAP services and server as a subsystem implementation. Signed-off-by: Pieter De Gendt --- .../linker/common-rom/common-rom-net.ld | 4 + include/zephyr/net/coap_service.h | 292 +++++++ subsys/net/lib/coap/CMakeLists.txt | 4 + subsys/net/lib/coap/Kconfig | 93 +++ subsys/net/lib/coap/coap_server.c | 762 ++++++++++++++++++ 5 files changed, 1155 insertions(+) create mode 100644 include/zephyr/net/coap_service.h create mode 100644 subsys/net/lib/coap/coap_server.c diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index e535f5f1fd0..71c1c1e089f 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -17,3 +17,7 @@ #if defined(CONFIG_HTTP_SERVER) ITERABLE_SECTION_ROM(http_service_desc, 4) #endif + +#if defined(CONFIG_COAP_SERVER) + ITERABLE_SECTION_ROM(coap_service, 4) +#endif diff --git a/include/zephyr/net/coap_service.h b/include/zephyr/net/coap_service.h new file mode 100644 index 00000000000..3e3201308b9 --- /dev/null +++ b/include/zephyr/net/coap_service.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief CoAP Service API + * + * An API for applications to respond to CoAP requests + */ + +#ifndef ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_ +#define ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief CoAP Service API + * @defgroup coap_service CoAP service API + * @ingroup networking + * @{ + */ + +/** + * @name CoAP Service configuration flags + * @anchor COAP_SERVICE_FLAGS + * @{ + */ + +/** Start the service on boot. */ +#define COAP_SERVICE_AUTOSTART BIT(0) + +/** @} */ + +/** @cond INTERNAL_HIDDEN */ + +struct coap_service_data { + int sock_fd; + struct coap_observer observers[CONFIG_COAP_SERVICE_OBSERVERS]; + struct coap_pending pending[CONFIG_COAP_SERVICE_PENDING_MESSAGES]; +}; + +struct coap_service { + const char *name; + const char *host; + uint16_t *port; + uint8_t flags; + struct coap_resource *res_begin; + struct coap_resource *res_end; + struct coap_service_data *data; +}; + +#define __z_coap_service_define(_name, _host, _port, _flags, _res_begin, _res_end) \ + static struct coap_service_data coap_service_data_##_name; \ + const STRUCT_SECTION_ITERABLE(coap_service, _name) = { \ + .name = STRINGIFY(_name), \ + .host = _host, \ + .port = (uint16_t *)(_port), \ + .flags = _flags, \ + .res_begin = (_res_begin), \ + .res_end = (_res_end), \ + .data = &coap_service_data_##_name, \ + } + +/** @endcond */ + +/** + * @brief Define a static CoAP resource owned by the service named @p _service . + * + * @note The handlers registered with the resource can return a CoAP response code to reply with + * an acknowledge without any payload, nothing is sent if the return value is 0 or negative. + * As seen in the example. + * + * @code{.c} + * static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + * + * static int led_put(struct coap_resource *resource, struct coap_packet *request, + * struct sockaddr *addr, socklen_t addr_len) + * { + * const uint8_t *payload; + * uint16_t payload_len; + * + * payload = coap_packet_get_payload(request, &payload_len); + * if (payload_len != 1) { + * return COAP_RESPONSE_CODE_BAD_REQUEST; + * } + * + * if (gpio_pin_set_dt(&led, payload[0]) < 0) { + * return COAP_RESPONSE_CODE_INTERNAL_ERROR; + * } + * + * return COAP_RESPONSE_CODE_CHANGED; + * } + * + * COAP_RESOURCE_DEFINE(my_resource, my_service, { + * .put = led_put, + * }); + * @endcode + * + * @param _name Name of the resource. + * @param _service Name of the associated service. + */ +#define COAP_RESOURCE_DEFINE(_name, _service, ...) \ + STRUCT_SECTION_ITERABLE_ALTERNATE(coap_resource_##_service, coap_resource, _name) \ + = __VA_ARGS__ + +/** + * @brief Define a CoAP service with static resources. + * + * @note The @p _host parameter can be `NULL`. If not, it is used to specify an IP address either in + * IPv4 or IPv6 format a fully-qualified hostname or a virtual host, otherwise the any address is + * used. + * + * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port + * number to use for the service. If the specified port number is zero, then an ephemeral port + * number will be used and the actual port number assigned will be written back to memory. For + * ephemeral port numbers, the memory pointed to by @p _port must be writeable. + * + * @param _name Name of the service. + * @param _host IP address or hostname associated with the service. + * @param[inout] _port Pointer to port associated with the service. + * @param _flags Configuration flags @see @ref COAP_SERVICE_FLAGS. + */ +#define COAP_SERVICE_DEFINE(_name, _host, _port, _flags) \ + extern struct coap_resource _CONCAT(_coap_resource_##_name, _list_start)[]; \ + extern struct coap_resource _CONCAT(_coap_resource_##_name, _list_end)[]; \ + __z_coap_service_define(_name, _host, _port, _flags, \ + &_CONCAT(_coap_resource_##_name, _list_start)[0], \ + &_CONCAT(_coap_resource_##_name, _list_end)[0]) + +/** + * @brief Count the number of CoAP services. + * + * @param[out] _dst Pointer to location where result is written. + */ +#define COAP_SERVICE_COUNT(_dst) STRUCT_SECTION_COUNT(coap_service, _dst) + +/** + * @brief Count CoAP service static resources. + * + * @param _service Pointer to a service. + */ +#define COAP_SERVICE_RESOURCE_COUNT(_service) ((_service)->res_end - (_service)->res_begin) + +/** + * @brief Check if service has the specified resource. + * + * @param _service Pointer to a service. + * @param _resource Pointer to a resource. + */ +#define COAP_SERVICE_HAS_RESOURCE(_service, _resource) \ + ((_service)->res_begin <= _resource && _resource < (_service)->res_end) + +/** + * @brief Iterate over all CoAP services. + * + * @param _it Name of iterator (of type @ref coap_service) + */ +#define COAP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(coap_service, _it) + +/** + * @brief Iterate over static CoAP resources associated with a given @p _service. + * + * @note This macro requires that @p _service is defined with @ref COAP_SERVICE_DEFINE. + * + * @param _service Name of CoAP service + * @param _it Name of iterator (of type @ref coap_resource) + */ +#define COAP_RESOURCE_FOREACH(_service, _it) \ + STRUCT_SECTION_FOREACH_ALTERNATE(coap_resource_##_service, coap_resource, _it) + +/** + * @brief Iterate over all static resources associated with @p _service . + * + * @note This macro is suitable for a @p _service defined with @ref COAP_SERVICE_DEFINE. + * + * @param _service Pointer to COAP service + * @param _it Name of iterator (of type @ref coap_resource) + */ +#define COAP_SERVICE_FOREACH_RESOURCE(_service, _it) \ + for (struct coap_resource *_it = (_service)->res_begin; ({ \ + __ASSERT(_it <= (_service)->res_end, "unexpected list end location"); \ + _it < (_service)->res_end; \ + }); _it++) + +/** + * @brief Start the provided @p service . + * + * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE. + * + * @param service Pointer to CoAP service + * @retval 0 in case of success. + * @retval -EALREADY in case of an already running service. + * @retval -ENOMEM in case the server has no available context. + */ +int coap_service_start(const struct coap_service *service); + +/** + * @brief Stop the provided @p service . + * + * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE. + * + * @param service Pointer to CoAP service + * @retval 0 in case of success. + * @retval -EALREADY in case the service isn't running. + */ +int coap_service_stop(const struct coap_service *service); + +/** + * @brief Send a CoAP message from the provided @p service . + * + * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE. + * + * @param service Pointer to CoAP service + * @param cpkt CoAP Packet to send + * @param addr Peer address + * @param addr_len Peer address length + * @return 0 in case of success or negative in case of error. + */ +int coap_service_send(const struct coap_service *service, const struct coap_packet *cpkt, + const struct sockaddr *addr, socklen_t addr_len); + +/** + * @brief Send a CoAP message from the provided @p resource . + * + * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE. + * + * @param resource Pointer to CoAP resource + * @param cpkt CoAP Packet to send + * @param addr Peer address + * @param addr_len Peer address length + * @return 0 in case of success or negative in case of error. + */ +int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt, + const struct sockaddr *addr, socklen_t addr_len); + +/** + * @brief Parse a CoAP observe request for the provided @p resource . + * + * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE. + * + * If the observe option value is equal to 0, an observer will be added, if the value is equal + * to 1, an existing observer will be removed. + * + * @param resource Pointer to CoAP resource + * @param request CoAP request to parse + * @param addr Peer address + * @return the observe option value in case of success or negative in case of error. + */ +int coap_resource_parse_observe(struct coap_resource *resource, const struct coap_packet *request, + const struct sockaddr *addr); + +/** + * @brief Lookup an observer by address and remove it from the @p resource . + * + * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE. + * + * @param resource Pointer to CoAP resource + * @param addr Peer address + * @return 0 in case of success or negative in case of error. + */ +int coap_resource_remove_observer_by_addr(struct coap_resource *resource, + const struct sockaddr *addr); + +/** + * @brief Lookup an observer by token and remove it from the @p resource . + * + * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE. + * + * @param resource Pointer to CoAP resource + * @param token Pointer to the token + * @param token_len Length of valid bytes in the token + * @return 0 in case of success or negative in case of error. + */ +int coap_resource_remove_observer_by_token(struct coap_resource *resource, + const uint8_t *token, uint8_t token_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_ */ diff --git a/subsys/net/lib/coap/CMakeLists.txt b/subsys/net/lib/coap/CMakeLists.txt index 39ef8196fbb..b2e40f9bcfb 100644 --- a/subsys/net/lib/coap/CMakeLists.txt +++ b/subsys/net/lib/coap/CMakeLists.txt @@ -10,3 +10,7 @@ zephyr_sources_ifdef(CONFIG_COAP zephyr_sources_ifdef(CONFIG_COAP_CLIENT coap_client.c ) + +zephyr_sources_ifdef(CONFIG_COAP_SERVER + coap_server.c +) diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 00ee157a116..3125c4ce612 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -153,6 +153,99 @@ config COAP_CLIENT_MAX_REQUESTS endif # COAP_CLIENT +config COAP_SERVER + bool "CoAP server support [EXPERIMENTAL]" + select EXPERIMENTAL + select NET_SOCKETS + select NET_SOCKETPAIR + help + This option enables the API for CoAP-services to register resources. + +if COAP_SERVER + +config COAP_SERVER_STACK_SIZE + int "CoAP server thread stack size" + default 4096 + help + CoAP server thread stack size for processing RX/TX events. + +config COAP_SERVER_BLOCK_SIZE + int "CoAP server block-wise transfer size" + default 256 + range 64 1024 + help + CoAP block size used by CoAP server resources when performing block-wise + transfers. Possible values: 64, 128, 256, 512 and 1024. + +config COAP_SERVER_MESSAGE_SIZE + int "CoAP server message payload size" + default COAP_SERVER_BLOCK_SIZE + help + CoAP server message payload size. Can't be smaller than COAP_SERVER_BLOCK_SIZE. + +config COAP_SERVER_MESSAGE_OPTIONS + int "CoAP server message options" + default 16 + help + CoAP server message maximum number of options to parse. + +config COAP_SERVER_WELL_KNOWN_CORE + bool "CoAP server support ./well-known/core service" + default y + help + Enable responding to the ./well-known/core service resource. + +config COAP_SERVICE_PENDING_MESSAGES + int "CoAP service pending messages" + default 10 + help + Maximum number of pending CoAP messages to retransmit per active service. + +config COAP_SERVICE_PENDING_RETRANSMITS + int "CoAP retransmit count" + default 2 + help + Maximum number of retries to send a pending message. + +config COAP_SERVICE_OBSERVERS + int "CoAP service observers" + default 3 + help + Maximum number of CoAP observers per active service. + +choice COAP_SERVER_PENDING_ALLOCATOR + prompt "Pending data allocator" + default COAP_SERVER_PENDING_ALLOCATOR_STATIC + +config COAP_SERVER_PENDING_ALLOCATOR_NONE + bool "No pending packets" + help + Never allocate data for pending requests, this disables retransmits for confirmable + packets. + +config COAP_SERVER_PENDING_ALLOCATOR_STATIC + bool "Static reserved memory" + help + Static memory will be reserved for pending messages. The total size is equal to + COAP_SERVER_PENDING_ALLOCATOR_STATIC_BLOCKS * COAP_SERVER_MESSAGE_SIZE. + +config COAP_SERVER_PENDING_ALLOCATOR_SYSTEM_HEAP + bool "System heap allocator" + depends on HEAP_MEM_POOL_SIZE > 0 + help + Use k_malloc/k_free for pending data. + +endchoice + +config COAP_SERVER_PENDING_ALLOCATOR_STATIC_BLOCKS + int "Number of pending data blocks" + default COAP_SERVICE_PENDING_MESSAGES + depends on COAP_SERVER_PENDING_ALLOCATOR_STATIC + help + The number of data blocks to reserve for pending messages to retransmit. + +endif + module = COAP module-dep = NET_LOG module-str = Log level for CoAP diff --git a/subsys/net/lib/coap/coap_server.c b/subsys/net/lib/coap/coap_server.c new file mode 100644 index 00000000000..fbcbe1721b2 --- /dev/null +++ b/subsys/net/lib/coap/coap_server.c @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); + +#include + +#include +#include +#include +#include +#include +#ifdef CONFIG_ARCH_POSIX +#include +#else +#include +#endif + +#if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) +/* Lowest priority cooperative thread */ +#define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1) +#else +#define THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NUM_PREEMPT_PRIORITIES - 1) +#endif + +#define ADDRLEN(sock) \ + (((struct sockaddr *)sock)->sa_family == AF_INET ? \ + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) + +/* Shortened defines */ +#define MAX_OPTIONS CONFIG_COAP_SERVER_MESSAGE_OPTIONS +#define MAX_PENDINGS CONFIG_COAP_SERVICE_PENDING_MESSAGES +#define MAX_OBSERVERS CONFIG_COAP_SERVICE_OBSERVERS +#define MAX_POLL_FD CONFIG_NET_SOCKETS_POLL_MAX + +BUILD_ASSERT(CONFIG_NET_SOCKETS_POLL_MAX > 0, "CONFIG_NET_SOCKETS_POLL_MAX can't be 0"); + +static K_MUTEX_DEFINE(lock); +static int control_socks[2]; + +#if defined(CONFIG_COAP_SERVER_PENDING_ALLOCATOR_STATIC) +K_MEM_SLAB_DEFINE_STATIC(pending_data, CONFIG_COAP_SERVER_MESSAGE_SIZE, + CONFIG_COAP_SERVER_PENDING_ALLOCATOR_STATIC_BLOCKS, 4); +#endif + +static inline void *coap_server_alloc(size_t len) +{ +#if defined(CONFIG_COAP_SERVER_PENDING_ALLOCATOR_STATIC) + void *ptr; + int ret; + + if (len > CONFIG_COAP_SERVER_MESSAGE_SIZE) { + return NULL; + } + + ret = k_mem_slab_alloc(&pending_data, &ptr, K_NO_WAIT); + if (ret < 0) { + return NULL; + } + + return ptr; +#elif defined(CONFIG_COAP_SERVER_PENDING_ALLOCATOR_SYSTEM_HEAP) + return k_malloc(len); +#else + ARG_UNUSED(len); + + return NULL; +#endif +} + +static inline void coap_server_free(void *ptr) +{ +#if defined(CONFIG_COAP_SERVER_PENDING_ALLOCATOR_STATIC) + k_mem_slab_free(&pending_data, ptr); +#elif defined(CONFIG_COAP_SERVER_PENDING_ALLOCATOR_SYSTEM_HEAP) + k_free(ptr); +#else + ARG_UNUSED(ptr); +#endif +} + +static int coap_service_remove_observer(const struct coap_service *service, + struct coap_resource *resource, + const struct sockaddr *addr, + const uint8_t *token, uint8_t tkl) +{ + struct coap_observer *obs; + + /* Prefer token to find the observer */ + if (tkl > 0 && token != NULL) { + obs = coap_find_observer_by_token(service->data->observers, MAX_OBSERVERS, token, + tkl); + } else if (addr != NULL) { + obs = coap_find_observer_by_addr(service->data->observers, MAX_OBSERVERS, addr); + } else { + /* Either a token or an address is required */ + return -EINVAL; + } + + if (obs == NULL) { + return 0; + } + + if (resource == NULL) { + COAP_SERVICE_FOREACH_RESOURCE(service, it) { + if (coap_remove_observer(it, obs)) { + memset(obs, 0, sizeof(*obs)); + return 1; + } + } + } else if (coap_remove_observer(resource, obs)) { + memset(obs, 0, sizeof(*obs)); + return 1; + } + + return 0; +} + +static int coap_server_process(int sock_fd) +{ + uint8_t buf[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct sockaddr client_addr; + socklen_t client_addr_len = sizeof(client_addr); + struct coap_service *service = NULL; + struct coap_packet request; + struct coap_pending *pending; + struct coap_option options[MAX_OPTIONS] = { 0 }; + uint8_t opt_num = MAX_OPTIONS; + uint8_t type; + ssize_t received; + int ret; + + received = zsock_recvfrom(sock_fd, buf, sizeof(buf), ZSOCK_MSG_DONTWAIT, &client_addr, + &client_addr_len); + __ASSERT_NO_MSG(received <= sizeof(buf)); + + if (received < 0) { + if (errno == EWOULDBLOCK) { + return 0; + } + + LOG_ERR("Failed to process client request (%d)", -errno); + return -errno; + } + + ret = coap_packet_parse(&request, buf, received, options, opt_num); + if (ret < 0) { + LOG_ERR("Failed To parse coap message (%d)", ret); + return ret; + } + + (void)k_mutex_lock(&lock, K_FOREVER); + /* Find the active service */ + COAP_SERVICE_FOREACH(svc) { + if (svc->data->sock_fd == sock_fd) { + service = svc; + break; + } + } + if (service == NULL) { + ret = -ENOENT; + goto unlock; + } + + type = coap_header_get_type(&request); + + pending = coap_pending_received(&request, service->data->pending, MAX_PENDINGS); + if (pending) { + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; + + switch (type) { + case COAP_TYPE_RESET: + tkl = coap_header_get_token(&request, token); + coap_service_remove_observer(service, NULL, &client_addr, token, tkl); + __fallthrough; + case COAP_TYPE_ACK: + coap_server_free(pending->data); + coap_pending_clear(pending); + break; + default: + LOG_WRN("Unexpected pending type %d", type); + ret = -EINVAL; + goto unlock; + } + + goto unlock; + } else if (type == COAP_TYPE_ACK || type == COAP_TYPE_RESET) { + LOG_WRN("Unexpected type %d without pending packet", type); + ret = -EINVAL; + goto unlock; + } + + if (IS_ENABLED(CONFIG_COAP_SERVER_WELL_KNOWN_CORE) && + coap_header_get_code(&request) == COAP_METHOD_GET && + coap_uri_path_match(COAP_WELL_KNOWN_CORE_PATH, options, opt_num)) { + uint8_t well_known_buf[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + + ret = coap_well_known_core_get_len(service->res_begin, + COAP_SERVICE_RESOURCE_COUNT(service), + &request, &response, + well_known_buf, sizeof(well_known_buf)); + if (ret < 0) { + LOG_ERR("Failed to build well known core for %s (%d)", service->name, ret); + goto unlock; + } + + ret = coap_service_send(service, &response, &client_addr, client_addr_len); + } else { + ret = coap_handle_request_len(&request, service->res_begin, + COAP_SERVICE_RESOURCE_COUNT(service), + options, opt_num, &client_addr, client_addr_len); + + /* Shortcut for replying a code without a body */ + if (ret > 0 && type == COAP_TYPE_CON) { + /* Minimal sized ack buffer */ + uint8_t ack_buf[COAP_TOKEN_MAX_LEN + 4U]; + struct coap_packet ack; + + ret = coap_ack_init(&ack, &request, ack_buf, sizeof(ack_buf), (uint8_t)ret); + if (ret < 0) { + LOG_ERR("Failed to init ACK (%d)", ret); + goto unlock; + } + + ret = coap_service_send(service, &ack, &client_addr, client_addr_len); + } + } + +unlock: + (void)k_mutex_unlock(&lock); + + return ret; +} + +static void coap_server_retransmit(void) +{ + struct coap_pending *pending; + int64_t remaining; + int64_t now = k_uptime_get(); + int ret; + + (void)k_mutex_lock(&lock, K_FOREVER); + + COAP_SERVICE_FOREACH(service) { + if (service->data->sock_fd < 0) { + continue; + } + + pending = coap_pending_next_to_expire(service->data->pending, MAX_PENDINGS); + if (pending == NULL) { + /* No work to be done */ + continue; + } + + /* Check if the pending request has expired */ + remaining = pending->t0 + pending->timeout - now; + if (remaining > 0) { + continue; + } + + if (coap_pending_cycle(pending)) { + ret = zsock_sendto(service->data->sock_fd, pending->data, pending->len, 0, + &pending->addr, ADDRLEN(&pending->addr)); + if (ret < 0) { + LOG_ERR("Failed to send pending retransmission for %s (%d)", + service->name, ret); + } + __ASSERT_NO_MSG(ret == pending->len); + } else { + LOG_WRN("Packet retransmission failed for %s", service->name); + + coap_service_remove_observer(service, NULL, &pending->addr, NULL, 0U); + coap_server_free(pending->data); + coap_pending_clear(pending); + } + } + + (void)k_mutex_unlock(&lock); +} + +static int coap_server_poll_timeout(void) +{ + struct coap_pending *pending; + int64_t result = INT64_MAX; + int64_t remaining; + int64_t now = k_uptime_get(); + + COAP_SERVICE_FOREACH(svc) { + if (svc->data->sock_fd < -1) { + continue; + } + + pending = coap_pending_next_to_expire(svc->data->pending, MAX_PENDINGS); + if (pending == NULL) { + continue; + } + + remaining = pending->t0 + pending->timeout - now; + if (result > remaining) { + result = remaining; + } + } + + if (result == INT64_MAX) { + return -1; + } + + return MAX(result, 0); +} + +static void coap_server_update_services(void) +{ + zsock_send(control_socks[1], &(char){0}, 1, 0); +} + +static inline bool coap_service_in_section(const struct coap_service *service) +{ + STRUCT_SECTION_START_EXTERN(coap_service); + STRUCT_SECTION_END_EXTERN(coap_service); + + return STRUCT_SECTION_START(coap_service) <= service && + STRUCT_SECTION_END(coap_service) > service; +} + +int coap_service_start(const struct coap_service *service) +{ + int ret; + + uint8_t af; + socklen_t len; + struct sockaddr_storage addr_storage; + union { + struct sockaddr *addr; + struct sockaddr_in *addr4; + struct sockaddr_in6 *addr6; + } addr_ptrs = { + .addr = (struct sockaddr *)&addr_storage, + }; + + if (!coap_service_in_section(service)) { + __ASSERT_NO_MSG(false); + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + if (service->data->sock_fd >= 0) { + ret = -EALREADY; + goto end; + } + + /* set the default address (in6addr_any / INADDR_ANY are all 0) */ + addr_storage = (struct sockaddr_storage){0}; + if (IS_ENABLED(CONFIG_NET_IPV6) && service->host != NULL && + zsock_inet_pton(AF_INET6, service->host, &addr_ptrs.addr6->sin6_addr) == 1) { + /* if a literal IPv6 address is provided as the host, use IPv6 */ + af = AF_INET6; + len = sizeof(struct sockaddr_in6); + + addr_ptrs.addr6->sin6_family = AF_INET6; + addr_ptrs.addr6->sin6_port = htons(*service->port); + } else if (IS_ENABLED(CONFIG_NET_IPV4) && service->host != NULL && + zsock_inet_pton(AF_INET, service->host, &addr_ptrs.addr4->sin_addr) == 1) { + /* if a literal IPv4 address is provided as the host, use IPv4 */ + af = AF_INET; + len = sizeof(struct sockaddr_in); + + addr_ptrs.addr4->sin_family = AF_INET; + addr_ptrs.addr4->sin_port = htons(*service->port); + } else if (IS_ENABLED(CONFIG_NET_IPV6)) { + /* prefer IPv6 if both IPv6 and IPv4 are supported */ + af = AF_INET6; + len = sizeof(struct sockaddr_in6); + + addr_ptrs.addr6->sin6_family = AF_INET6; + addr_ptrs.addr6->sin6_port = htons(*service->port); + } else if (IS_ENABLED(CONFIG_NET_IPV4)) { + af = AF_INET; + len = sizeof(struct sockaddr_in); + + addr_ptrs.addr4->sin_family = AF_INET; + addr_ptrs.addr4->sin_port = htons(*service->port); + } else { + ret = -ENOTSUP; + goto end; + } + + service->data->sock_fd = zsock_socket(af, SOCK_DGRAM, IPPROTO_UDP); + if (service->data->sock_fd < 0) { + ret = -errno; + goto end; + } + + ret = zsock_fcntl(service->data->sock_fd, F_SETFL, O_NONBLOCK); + if (ret < 0) { + ret = -errno; + goto close; + } + + ret = zsock_bind(service->data->sock_fd, addr_ptrs.addr, len); + if (ret < 0) { + ret = -errno; + goto close; + } + + if (*service->port == 0) { + /* ephemeral port - read back the port number */ + len = sizeof(addr_storage); + ret = zsock_getsockname(service->data->sock_fd, addr_ptrs.addr, &len); + if (ret < 0) { + goto close; + } + + if (af == AF_INET6) { + *service->port = addr_ptrs.addr6->sin6_port; + } else { + *service->port = addr_ptrs.addr4->sin_port; + } + } + +end: + k_mutex_unlock(&lock); + + coap_server_update_services(); + + return ret; + +close: + (void)zsock_close(service->data->sock_fd); + service->data->sock_fd = -1; + + k_mutex_unlock(&lock); + + return ret; +} + +int coap_service_stop(const struct coap_service *service) +{ + int ret; + + if (!coap_service_in_section(service)) { + __ASSERT_NO_MSG(false); + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + if (service->data->sock_fd < 0) { + ret = -EALREADY; + goto end; + } + + /* Closing a socket will trigger a poll event */ + ret = zsock_close(service->data->sock_fd); + service->data->sock_fd = -1; + +end: + k_mutex_unlock(&lock); + + return ret; +} + +int coap_service_send(const struct coap_service *service, const struct coap_packet *cpkt, + const struct sockaddr *addr, socklen_t addr_len) +{ + int ret; + + if (!coap_service_in_section(service)) { + __ASSERT_NO_MSG(false); + return -EINVAL; + } + + (void)k_mutex_lock(&lock, K_FOREVER); + + if (service->data->sock_fd < 0) { + (void)k_mutex_unlock(&lock); + return -EBADF; + } + + /* + * Check if we should start with retransmits, if creating a pending message fails we still + * try to send. + */ + if (coap_header_get_type(cpkt) == COAP_TYPE_CON) { + struct coap_pending *pending = coap_pending_next_unused(service->data->pending, + MAX_PENDINGS); + + if (pending == NULL) { + LOG_WRN("No pending message available for %s", service->name); + goto send; + } + + ret = coap_pending_init(pending, cpkt, addr, + CONFIG_COAP_SERVICE_PENDING_RETRANSMITS); + if (ret < 0) { + LOG_WRN("Failed to init pending message for %s (%d)", service->name, ret); + goto send; + } + + /* Replace tracked data with our allocated copy */ + pending->data = coap_server_alloc(pending->len); + if (pending->data == NULL) { + LOG_WRN("Failed to allocate pending message data for %s", service->name); + coap_pending_clear(pending); + goto send; + } + memcpy(pending->data, cpkt->data, pending->len); + + coap_pending_cycle(pending); + + /* Trigger event in receive loop to schedule retransmit */ + coap_server_update_services(); + } + +send: + (void)k_mutex_unlock(&lock); + + ret = zsock_sendto(service->data->sock_fd, cpkt->data, cpkt->offset, 0, addr, addr_len); + if (ret < 0) { + LOG_ERR("Failed to send CoAP message (%d)", ret); + return ret; + } + __ASSERT_NO_MSG(ret == cpkt->offset); + + return 0; +} + +int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt, + const struct sockaddr *addr, socklen_t addr_len) +{ + /* Find owning service */ + COAP_SERVICE_FOREACH(svc) { + if (COAP_SERVICE_HAS_RESOURCE(svc, resource)) { + return coap_service_send(svc, cpkt, addr, addr_len); + } + } + + return -ENOENT; +} + +int coap_resource_parse_observe(struct coap_resource *resource, const struct coap_packet *request, + const struct sockaddr *addr) +{ + const struct coap_service *service = NULL; + int ret; + + if (!coap_packet_is_request(request)) { + return -EINVAL; + } + + ret = coap_get_option_int(request, COAP_OPTION_OBSERVE); + if (ret < 0) { + return ret; + } + + /* Find owning service */ + COAP_SERVICE_FOREACH(svc) { + if (COAP_SERVICE_HAS_RESOURCE(svc, resource)) { + service = svc; + break; + } + } + + if (service == NULL) { + return -ENOENT; + } + + (void)k_mutex_lock(&lock, K_FOREVER); + + if (ret == 0) { + struct coap_observer *observer; + + observer = coap_observer_next_unused(service->data->observers, MAX_OBSERVERS); + if (observer == NULL) { + ret = -ENOMEM; + goto unlock; + } + + coap_observer_init(observer, request, addr); + coap_register_observer(resource, observer); + } else if (ret == 1) { + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; + + tkl = coap_header_get_token(request, token); + ret = coap_service_remove_observer(service, resource, addr, token, tkl); + if (ret < 0) { + LOG_WRN("Failed to remove observer (%d)", ret); + } + } + +unlock: + (void)k_mutex_unlock(&lock); + + return ret; +} + +static int coap_resource_remove_observer(struct coap_resource *resource, + const struct sockaddr *addr, + const uint8_t *token, uint8_t token_len) +{ + const struct coap_service *service = NULL; + int ret; + + /* Find owning service */ + COAP_SERVICE_FOREACH(svc) { + if (COAP_SERVICE_HAS_RESOURCE(svc, resource)) { + service = svc; + break; + } + } + + if (service == NULL) { + return -ENOENT; + } + + (void)k_mutex_lock(&lock, K_FOREVER); + ret = coap_service_remove_observer(service, resource, addr, token, token_len); + (void)k_mutex_unlock(&lock); + + if (ret == 1) { + /* An observer was found and removed */ + return 0; + } else if (ret == 0) { + /* No matching observer found */ + return -ENOENT; + } + + /* An error occurred */ + return ret; +} + +int coap_resource_remove_observer_by_addr(struct coap_resource *resource, + const struct sockaddr *addr) +{ + return coap_resource_remove_observer(resource, addr, NULL, 0); +} + +int coap_resource_remove_observer_by_token(struct coap_resource *resource, + const uint8_t *token, uint8_t token_len) +{ + return coap_resource_remove_observer(resource, NULL, token, token_len); +} + +static void coap_server_thread(void *p1, void *p2, void *p3) +{ + struct zsock_pollfd sock_fds[MAX_POLL_FD]; + int sock_nfds; + int ret; + + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + /* Create a socket pair to wake zsock_poll */ + ret = zsock_socketpair(AF_UNIX, SOCK_STREAM, 0, control_socks); + if (ret < 0) { + LOG_ERR("Failed to create socket pair (%d)", ret); + return; + } + + for (int i = 0; i < 2; ++i) { + ret = zsock_fcntl(control_socks[i], F_SETFL, O_NONBLOCK); + + if (ret < 0) { + zsock_close(control_socks[0]); + zsock_close(control_socks[1]); + + LOG_ERR("Failed to set socket pair [%d] non-blocking (%d)", i, ret); + return; + } + } + + COAP_SERVICE_FOREACH(svc) { + /* Init all file descriptors to -1 */ + svc->data->sock_fd = -1; + + if (svc->flags & COAP_SERVICE_AUTOSTART) { + ret = coap_service_start(svc); + if (ret < 0) { + LOG_ERR("Failed to autostart service %s (%d)", svc->name, ret); + } + } + } + + while (true) { + sock_nfds = 0; + COAP_SERVICE_FOREACH(svc) { + if (svc->data->sock_fd < 0) { + continue; + } + if (sock_nfds >= MAX_POLL_FD) { + LOG_ERR("Maximum active CoAP services reached (%d), " + "increase CONFIG_NET_SOCKETS_POLL_MAX to support more.", + MAX_POLL_FD); + break; + } + + sock_fds[sock_nfds].fd = svc->data->sock_fd; + sock_fds[sock_nfds].events = ZSOCK_POLLIN; + sock_fds[sock_nfds].revents = 0; + sock_nfds++; + } + + /* Add socket pair FD to allow wake up */ + if (sock_nfds < MAX_POLL_FD) { + sock_fds[sock_nfds].fd = control_socks[0]; + sock_fds[sock_nfds].events = ZSOCK_POLLIN; + sock_fds[sock_nfds].revents = 0; + sock_nfds++; + } + + __ASSERT_NO_MSG(sock_nfds > 0); + + ret = zsock_poll(sock_fds, sock_nfds, coap_server_poll_timeout()); + if (ret < 0) { + LOG_ERR("Poll error (%d)", -errno); + k_msleep(10); + } + + for (int i = 0; i < sock_nfds; ++i) { + /* Check the wake up event */ + if (sock_fds[i].fd == control_socks[0] && + sock_fds[i].revents & ZSOCK_POLLIN) { + char tmp; + + zsock_recv(sock_fds[i].fd, &tmp, 1, 0); + continue; + } + + /* Check if socket can receive/was closed first */ + if (sock_fds[i].revents & ZSOCK_POLLIN) { + coap_server_process(sock_fds[i].fd); + continue; + } + + if (sock_fds[i].revents & ZSOCK_POLLERR) { + LOG_ERR("Poll error on %d", sock_fds[i].fd); + } + if (sock_fds[i].revents & ZSOCK_POLLHUP) { + LOG_ERR("Poll hup on %d", sock_fds[i].fd); + } + if (sock_fds[i].revents & ZSOCK_POLLNVAL) { + LOG_ERR("Poll invalid on %d", sock_fds[i].fd); + } + } + + /* Process retransmits */ + coap_server_retransmit(); + } +} + +K_THREAD_DEFINE(coap_server_id, CONFIG_COAP_SERVER_STACK_SIZE, + coap_server_thread, NULL, NULL, NULL, + THREAD_PRIORITY, 0, 0); From e8e6d23270e734c06225aef31af2ebad909557d5 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 4 Oct 2023 10:09:43 +0200 Subject: [PATCH 3318/4498] net: lib: coap: Add CoAP server shell Add shell commands that allow to start/stop CoAP services. Signed-off-by: Pieter De Gendt --- subsys/net/lib/coap/CMakeLists.txt | 4 + subsys/net/lib/coap/Kconfig | 6 ++ subsys/net/lib/coap/coap_server_shell.c | 98 +++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 subsys/net/lib/coap/coap_server_shell.c diff --git a/subsys/net/lib/coap/CMakeLists.txt b/subsys/net/lib/coap/CMakeLists.txt index b2e40f9bcfb..c0a555082b2 100644 --- a/subsys/net/lib/coap/CMakeLists.txt +++ b/subsys/net/lib/coap/CMakeLists.txt @@ -14,3 +14,7 @@ zephyr_sources_ifdef(CONFIG_COAP_CLIENT zephyr_sources_ifdef(CONFIG_COAP_SERVER coap_server.c ) + +zephyr_sources_ifdef(CONFIG_COAP_SERVER_SHELL + coap_server_shell.c +) diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 3125c4ce612..8e62983ea72 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -244,6 +244,12 @@ config COAP_SERVER_PENDING_ALLOCATOR_STATIC_BLOCKS help The number of data blocks to reserve for pending messages to retransmit. +config COAP_SERVER_SHELL + bool "CoAP service shell commands" + depends on SHELL + help + Enable CoAP service shell commands. + endif module = COAP diff --git a/subsys/net/lib/coap/coap_server_shell.c b/subsys/net/lib/coap/coap_server_shell.c new file mode 100644 index 00000000000..bf0a52553da --- /dev/null +++ b/subsys/net/lib/coap/coap_server_shell.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + + +static int cmd_list(const struct shell *sh, size_t argc, char **argv) +{ + int count = 0; + + ARG_UNUSED(argv); + + if (argc > 1) { + return -EINVAL; + } + + shell_print(sh, " Name State Endpoint"); + COAP_SERVICE_FOREACH(service) { + shell_print(sh, + "[%2d] %-16s %-16s %s:%d", + ++count, + service->name, + service->data->sock_fd < 0 ? "INACTIVE" : "ACTIVE", + service->host != NULL ? service->host : "", + *service->port); + } + + if (count == 0) { + shell_print(sh, "No services available"); + return -ENOENT; + } + + return 0; +} + +static int cmd_start(const struct shell *sh, size_t argc, char **argv) +{ + int ret = -ENOENT; + + if (argc != 2) { + shell_error(sh, "Usage: start "); + return -EINVAL; + } + + COAP_SERVICE_FOREACH(service) { + if (strcmp(argv[1], service->name) == 0) { + ret = coap_service_start(service); + break; + } + } + + if (ret < 0) { + shell_error(sh, "Failed to start service (%d)", ret); + } + + return ret; +} + +static int cmd_stop(const struct shell *sh, size_t argc, char **argv) +{ + int ret = -ENOENT; + + if (argc != 2) { + shell_error(sh, "Usage: stop "); + return -EINVAL; + } + + COAP_SERVICE_FOREACH(service) { + if (strcmp(argv[1], service->name) == 0) { + ret = coap_service_stop(service); + break; + } + } + + if (ret < 0) { + shell_error(sh, "Failed to stop service (%d)", ret); + } + + return ret; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_coap_service, + SHELL_CMD(start, NULL, + "Start a CoAP Service\n" + "Usage: start ", + cmd_start), + SHELL_CMD(stop, NULL, + "Stop a CoAP Service\n" + "Usage: stop ", + cmd_stop), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); +SHELL_CMD_REGISTER(coap_service, &sub_coap_service, "CoAP Service commands", cmd_list); From 74db06694176e7807c8934e12c8f21750e96d025 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 21 Sep 2023 17:25:58 +0200 Subject: [PATCH 3319/4498] tests: net: lib: Add CoAP service tests Add a test for CoAP macro usage. Signed-off-by: Pieter De Gendt --- .../net/lib/coap_server/common/CMakeLists.txt | 10 + tests/net/lib/coap_server/common/prj.conf | 9 + .../lib/coap_server/common/sections-ram.ld | 7 + tests/net/lib/coap_server/common/src/main.c | 321 ++++++++++++++++++ .../net/lib/coap_server/common/testcase.yaml | 11 + 5 files changed, 358 insertions(+) create mode 100644 tests/net/lib/coap_server/common/CMakeLists.txt create mode 100644 tests/net/lib/coap_server/common/prj.conf create mode 100644 tests/net/lib/coap_server/common/sections-ram.ld create mode 100644 tests/net/lib/coap_server/common/src/main.c create mode 100644 tests/net/lib/coap_server/common/testcase.yaml diff --git a/tests/net/lib/coap_server/common/CMakeLists.txt b/tests/net/lib/coap_server/common/CMakeLists.txt new file mode 100644 index 00000000000..6607ada6948 --- /dev/null +++ b/tests/net/lib/coap_server/common/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(coap_service_defines) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +zephyr_linker_sources(DATA_SECTIONS sections-ram.ld) diff --git a/tests/net/lib/coap_server/common/prj.conf b/tests/net/lib/coap_server/common/prj.conf new file mode 100644 index 00000000000..07cf69355fc --- /dev/null +++ b/tests/net/lib/coap_server/common/prj.conf @@ -0,0 +1,9 @@ +CONFIG_ZTEST=y + +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y + +CONFIG_COAP=y +CONFIG_COAP_SERVER=y diff --git a/tests/net/lib/coap_server/common/sections-ram.ld b/tests/net/lib/coap_server/common/sections-ram.ld new file mode 100644 index 00000000000..d435ffbddd4 --- /dev/null +++ b/tests/net/lib/coap_server/common/sections-ram.ld @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +ITERABLE_SECTION_RAM(coap_resource_service_A, 4) +ITERABLE_SECTION_RAM(coap_resource_service_B, 4) +ITERABLE_SECTION_RAM(coap_resource_service_C, 4) diff --git a/tests/net/lib/coap_server/common/src/main.c b/tests/net/lib/coap_server/common/src/main.c new file mode 100644 index 00000000000..7af940c5360 --- /dev/null +++ b/tests/net/lib/coap_server/common/src/main.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +static int coap_method1(struct coap_resource *resource, struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + ARG_UNUSED(resource); + ARG_UNUSED(request); + ARG_UNUSED(addr); + ARG_UNUSED(addr_len); + + return -ENOSYS; +} + +static int coap_method2(struct coap_resource *resource, struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + ARG_UNUSED(resource); + ARG_UNUSED(request); + ARG_UNUSED(addr); + ARG_UNUSED(addr_len); + + return -ENOSYS; +} + +static const uint16_t service_A_port = 4242; +COAP_SERVICE_DEFINE(service_A, "a.service.com", &service_A_port, COAP_SERVICE_AUTOSTART); + +static const char * const resource_0_path[] = { "res0", NULL }; +COAP_RESOURCE_DEFINE(resource_0, service_A, { + .path = resource_0_path, + .get = coap_method1, + .put = coap_method2, +}); + +static const char * const resource_1_path[] = { "res1", NULL }; +COAP_RESOURCE_DEFINE(resource_1, service_A, { + .path = resource_1_path, + .post = coap_method1, +}); + +static uint16_t service_B_port; +COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, COAP_SERVICE_AUTOSTART); + +static const char * const resource_2_path[] = { "res2", "sub", NULL }; +COAP_RESOURCE_DEFINE(resource_2, service_B, { + .path = resource_2_path, + .get = coap_method2, + .put = coap_method1, +}); + +static const char * const resource_3_path[] = { "res3", "+", NULL }; +COAP_RESOURCE_DEFINE(resource_3, service_B, { + .path = resource_3_path, + .post = coap_method2, +}); + +static const uint16_t service_C_port = 5959; +COAP_SERVICE_DEFINE(service_C, "192.168.1.1", &service_C_port, 0); + +static const char * const resource_4_path[] = { "res4", "*", NULL }; +COAP_RESOURCE_DEFINE(resource_4, service_C, { + .path = resource_4_path, + .get = coap_method1, +}); + +ZTEST(coap_service, test_COAP_SERVICE_DEFINE) +{ + zassert_ok(strcmp(service_A.host, "a.service.com")); + zassert_equal(service_A.port, &service_A_port); + zassert_equal(*service_A.port, 4242); + + zassert_ok(strcmp(service_B.host, "b.service.com")); + zassert_equal(service_B.port, &service_B_port); + zassert_equal(*service_B.port, 0); + + zassert_ok(strcmp(service_C.host, "192.168.1.1")); + zassert_equal(service_C.port, &service_C_port); + zassert_equal(*service_C.port, 5959); +} + +ZTEST(coap_service, test_COAP_SERVICE_COUNT) +{ + size_t n_svc; + + n_svc = 4273; + COAP_SERVICE_COUNT(&n_svc); + zassert_equal(n_svc, 3); +} + +ZTEST(coap_service, test_COAP_SERVICE_RESOURCE_COUNT) +{ + zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_A), 2); + zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_B), 2); + zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_C), 1); +} + +ZTEST(coap_service, test_COAP_SERVICE_HAS_RESOURCE) +{ + zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_0)); + zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_1)); + zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_2)); + zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_3)); + + zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_0)); + zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_1)); + zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_2)); + zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_3)); + + zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_0)); + zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_4)); +} + +ZTEST(coap_service, test_COAP_SERVICE_FOREACH) +{ + size_t n_svc = 0; + size_t have_service_A = 0; + size_t have_service_B = 0; + size_t have_service_C = 0; + + COAP_SERVICE_FOREACH(svc) { + if (svc == &service_A) { + have_service_A = 1; + zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART); + } else if (svc == &service_B) { + have_service_B = 1; + zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART); + } else if (svc == &service_C) { + have_service_C = 1; + zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0); + } else { + zassert_unreachable("svc (%p) not equal to &service_A (%p), &service_B " + "(%p), or &service_C (%p)", + svc, &service_A, &service_B, &service_C); + } + + n_svc++; + } + + zassert_equal(n_svc, 3); + zassert_equal(have_service_A + have_service_B + have_service_C, n_svc); +} + +ZTEST(coap_service, test_COAP_RESOURCE_FOREACH) +{ + size_t first_res, second_res, n_res; + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_RESOURCE_FOREACH(service_A, res) { + if (res == &resource_0) { + first_res = 1; + } else if (res == &resource_1) { + second_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res, + &resource_0, &resource_1); + } + + n_res++; + } + + zassert_equal(n_res, 2); + zassert_equal(first_res + second_res, n_res); + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_RESOURCE_FOREACH(service_B, res) { + if (res == &resource_2) { + first_res = 1; + } else if (res == &resource_3) { + second_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res, + &resource_2, &resource_3); + } + + n_res++; + } + + zassert_equal(n_res, 2); + zassert_equal(first_res + second_res, n_res); + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_RESOURCE_FOREACH(service_C, res) { + if (res == &resource_4) { + first_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_4 (%p)", res, &resource_4); + } + n_res++; + } + + zassert_equal(n_res, 1); + zassert_equal(first_res + second_res, n_res); +} + +ZTEST(coap_service, test_COAP_SERVICE_FOREACH_RESOURCE) +{ + size_t first_res, second_res, n_res; + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) { + if (res == &resource_0) { + first_res = 1; + } else if (res == &resource_1) { + second_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res, + &resource_0, &resource_1); + } + + n_res++; + } + + zassert_equal(n_res, 2); + zassert_equal(first_res + second_res, n_res); + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) { + if (res == &resource_2) { + first_res = 1; + } else if (res == &resource_3) { + second_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res, + &resource_2, &resource_3); + } + + n_res++; + } + + zassert_equal(n_res, 2); + zassert_equal(first_res + second_res, n_res); + + n_res = 0; + first_res = 0; + second_res = 0; + COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) { + if (res == &resource_4) { + first_res = 1; + } else { + zassert_unreachable( + "res (%p) not equal to &resource_4 (%p)", res, &resource_4); + } + n_res++; + } + + zassert_equal(n_res, 1); + zassert_equal(first_res + second_res, n_res); +} + +ZTEST(coap_service, test_COAP_RESOURCE_DEFINE) +{ + COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) { + if (res == &resource_0) { + zassert_ok(strcmp(res->path[0], "res0")); + zassert_equal(res->get, coap_method1); + zassert_equal(res->put, coap_method2); + } else if (res == &resource_1) { + zassert_ok(strcmp(res->path[0], "res1")); + zassert_equal(res->post, coap_method1); + } else { + zassert_unreachable( + "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res, + &resource_0, &resource_1); + } + } + + COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) { + if (res == &resource_2) { + zassert_ok(strcmp(res->path[0], "res2")); + zassert_ok(strcmp(res->path[1], "sub")); + zassert_equal(res->get, coap_method2); + zassert_equal(res->put, coap_method1); + } else if (res == &resource_3) { + zassert_ok(strcmp(res->path[0], "res3")); + zassert_ok(strcmp(res->path[1], "+")); + zassert_equal(res->post, coap_method2); + } else { + zassert_unreachable( + "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res, + &resource_2, &resource_3); + } + } + + COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) { + if (res == &resource_4) { + zassert_ok(strcmp(res->path[0], "res4")); + zassert_ok(strcmp(res->path[1], "*")); + zassert_equal(res->get, coap_method1); + zassert_equal(res->put, NULL); + } else { + zassert_unreachable( + "res (%p) not equal to &resource_4 (%p)", res, &resource_4); + } + } +} + +ZTEST_SUITE(coap_service, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/lib/coap_server/common/testcase.yaml b/tests/net/lib/coap_server/common/testcase.yaml new file mode 100644 index 00000000000..c36e9646270 --- /dev/null +++ b/tests/net/lib/coap_server/common/testcase.yaml @@ -0,0 +1,11 @@ +common: + min_ram: 16 + tags: + - net + - coap + - server + integration_platforms: + - native_posix + +tests: + net.coap.server.common: {} From 1f63c32c03041ca032eafed4f911a7f2149d056b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 4 Oct 2023 12:29:04 +0200 Subject: [PATCH 3320/4498] samples: net: sockets: Add CoAP service example Replaced the CoAP server example with CoAP services. Signed-off-by: Pieter De Gendt --- .../net/sockets/coap_server/CMakeLists.txt | 2 + samples/net/sockets/coap_server/README.rst | 13 +- .../coap_server/boards/native_posix.conf | 3 + .../coap_server/boards/native_posix_64.conf | 3 + .../coap_server/boards/qemu_cortex_m3.conf | 4 + samples/net/sockets/coap_server/prj.conf | 7 +- samples/net/sockets/coap_server/sample.yaml | 8 +- .../net/sockets/coap_server/sections-ram.ld | 5 + .../net/sockets/coap_server/src/coap-server.c | 1466 ----------------- samples/net/sockets/coap_server/src/core.c | 81 + samples/net/sockets/coap_server/src/large.c | 266 +++ .../sockets/coap_server/src/location_query.c | 72 + samples/net/sockets/coap_server/src/main.c | 85 + .../net/sockets/coap_server/src/observer.c | 153 ++ samples/net/sockets/coap_server/src/query.c | 102 ++ .../net/sockets/coap_server/src/separate.c | 99 ++ samples/net/sockets/coap_server/src/test.c | 262 +++ 17 files changed, 1155 insertions(+), 1476 deletions(-) create mode 100644 samples/net/sockets/coap_server/boards/native_posix.conf create mode 100644 samples/net/sockets/coap_server/boards/native_posix_64.conf create mode 100644 samples/net/sockets/coap_server/boards/qemu_cortex_m3.conf create mode 100644 samples/net/sockets/coap_server/sections-ram.ld delete mode 100644 samples/net/sockets/coap_server/src/coap-server.c create mode 100644 samples/net/sockets/coap_server/src/core.c create mode 100644 samples/net/sockets/coap_server/src/large.c create mode 100644 samples/net/sockets/coap_server/src/location_query.c create mode 100644 samples/net/sockets/coap_server/src/main.c create mode 100644 samples/net/sockets/coap_server/src/observer.c create mode 100644 samples/net/sockets/coap_server/src/query.c create mode 100644 samples/net/sockets/coap_server/src/separate.c create mode 100644 samples/net/sockets/coap_server/src/test.c diff --git a/samples/net/sockets/coap_server/CMakeLists.txt b/samples/net/sockets/coap_server/CMakeLists.txt index 97f67d0a358..17d20709825 100644 --- a/samples/net/sockets/coap_server/CMakeLists.txt +++ b/samples/net/sockets/coap_server/CMakeLists.txt @@ -7,3 +7,5 @@ project(coap_server) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) + +zephyr_linker_sources(DATA_SECTIONS sections-ram.ld) diff --git a/samples/net/sockets/coap_server/README.rst b/samples/net/sockets/coap_server/README.rst index 57e4a818809..89490ad399b 100644 --- a/samples/net/sockets/coap_server/README.rst +++ b/samples/net/sockets/coap_server/README.rst @@ -1,13 +1,18 @@ .. zephyr:code-sample:: coap-server - :name: CoAP server - :relevant-api: coap udp + :name: CoAP service + :relevant-api: coap coap_service udp - Use the CoAP library to implement a server that exposes CoAP resources. + Use the CoAP server subsystem to register CoAP resources. Overview ******** -This sample is a simple CoAP server showing how to expose a simple resource. +This sample shows how to register CoAP resources to a main CoAP service. +The CoAP server implementation expects all services and resources to be +available at compile time, as they are put into dedicated sections. + +The resource is placed into the correct linker section based on the owning +service's name. A linker file is required, see ``sections-ram.ld`` for an example. This demo assumes that the platform of choice has networking support, some adjustments to the configuration may be needed. diff --git a/samples/net/sockets/coap_server/boards/native_posix.conf b/samples/net/sockets/coap_server/boards/native_posix.conf new file mode 100644 index 00000000000..b8f2d57be74 --- /dev/null +++ b/samples/net/sockets/coap_server/boards/native_posix.conf @@ -0,0 +1,3 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/samples/net/sockets/coap_server/boards/native_posix_64.conf b/samples/net/sockets/coap_server/boards/native_posix_64.conf new file mode 100644 index 00000000000..b8f2d57be74 --- /dev/null +++ b/samples/net/sockets/coap_server/boards/native_posix_64.conf @@ -0,0 +1,3 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/samples/net/sockets/coap_server/boards/qemu_cortex_m3.conf b/samples/net/sockets/coap_server/boards/qemu_cortex_m3.conf new file mode 100644 index 00000000000..dc256b47832 --- /dev/null +++ b/samples/net/sockets/coap_server/boards/qemu_cortex_m3.conf @@ -0,0 +1,4 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_ETH_DRIVER=y +CONFIG_ETH_STELLARIS=y +CONFIG_NET_QEMU_ETHERNET=y diff --git a/samples/net/sockets/coap_server/prj.conf b/samples/net/sockets/coap_server/prj.conf index 6a8b972b069..1a26e614786 100644 --- a/samples/net/sockets/coap_server/prj.conf +++ b/samples/net/sockets/coap_server/prj.conf @@ -10,7 +10,10 @@ CONFIG_NET_SOCKETS_POLL_MAX=4 # CoAP CONFIG_COAP=y +CONFIG_COAP_SERVER=y +CONFIG_COAP_SERVER_WELL_KNOWN_CORE=y CONFIG_COAP_WELL_KNOWN_BLOCK_WISE=n +CONFIG_COAP_OBSERVER_EVENTS=y # Kernel options CONFIG_ENTROPY_GENERATOR=y @@ -22,9 +25,7 @@ CONFIG_NET_LOG=y # Network Shell CONFIG_NET_SHELL=y - -CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_HEAP_MEM_POOL_SIZE=4096 +CONFIG_COAP_SERVER_SHELL=y # Configuration CONFIG_NET_CONFIG_SETTINGS=y diff --git a/samples/net/sockets/coap_server/sample.yaml b/samples/net/sockets/coap_server/sample.yaml index 8b6ab35ab6a..3c0cfe475db 100644 --- a/samples/net/sockets/coap_server/sample.yaml +++ b/samples/net/sockets/coap_server/sample.yaml @@ -1,12 +1,14 @@ common: filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample: - description: TBD - name: TBD + description: BSD Sockets API CoAP server example + name: socket_coap_server tests: sample.net.sockets.coap_server: harness: net tags: - net - socket - platform_allow: qemu_x86 + platform_allow: + - native_posix + - qemu_x86 diff --git a/samples/net/sockets/coap_server/sections-ram.ld b/samples/net/sockets/coap_server/sections-ram.ld new file mode 100644 index 00000000000..04534264195 --- /dev/null +++ b/samples/net/sockets/coap_server/sections-ram.ld @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +ITERABLE_SECTION_RAM(coap_resource_coap_server, 4) diff --git a/samples/net/sockets/coap_server/src/coap-server.c b/samples/net/sockets/coap_server/src/coap-server.c deleted file mode 100644 index ce47e31a245..00000000000 --- a/samples/net/sockets/coap_server/src/coap-server.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(net_coap_server_sample, LOG_LEVEL_DBG); - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "net_private.h" -#if defined(CONFIG_NET_IPV6) -#include "ipv6.h" -#endif - -#define MAX_RETRANSMIT_COUNT 2 - -#define MAX_COAP_MSG_LEN 256 - -#define MY_COAP_PORT 5683 - -#define BLOCK_WISE_TRANSFER_SIZE_GET 2048 - -#if defined(CONFIG_NET_IPV6) -#define ALL_NODES_LOCAL_COAP_MCAST \ - { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd } } } - -#define MY_IP6ADDR \ - { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } } -#endif - -#define ADDRLEN(sock) \ - (((struct sockaddr *)sock)->sa_family == AF_INET ? \ - sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) - -#define NUM_OBSERVERS 3 - -#define NUM_PENDINGS 10 - -/* CoAP socket fd */ -static int sock; - -static struct coap_observer observers[NUM_OBSERVERS]; - -static struct coap_pending pendings[NUM_PENDINGS]; - -static struct k_work_delayable observer_work; - -static int obs_counter; - -static struct coap_resource *resource_to_notify; - -static struct k_work_delayable retransmit_work; - -#if defined(CONFIG_NET_IPV6) -static bool join_coap_multicast_group(void) -{ - static struct in6_addr my_addr = MY_IP6ADDR; - static struct sockaddr_in6 mcast_addr = { - .sin6_family = AF_INET6, - .sin6_addr = ALL_NODES_LOCAL_COAP_MCAST, - .sin6_port = htons(MY_COAP_PORT) }; - struct net_if_addr *ifaddr; - struct net_if *iface; - int ret; - - iface = net_if_get_default(); - if (!iface) { - LOG_ERR("Could not get te default interface\n"); - return false; - } - -#if defined(CONFIG_NET_CONFIG_SETTINGS) - if (net_addr_pton(AF_INET6, - CONFIG_NET_CONFIG_MY_IPV6_ADDR, - &my_addr) < 0) { - LOG_ERR("Invalid IPv6 address %s", - CONFIG_NET_CONFIG_MY_IPV6_ADDR); - } -#endif - - ifaddr = net_if_ipv6_addr_add(iface, &my_addr, NET_ADDR_MANUAL, 0); - if (!ifaddr) { - LOG_ERR("Could not add unicast address to interface"); - return false; - } - - ifaddr->addr_state = NET_ADDR_PREFERRED; - - ret = net_ipv6_mld_join(iface, &mcast_addr.sin6_addr); - if (ret < 0) { - LOG_ERR("Cannot join %s IPv6 multicast group (%d)", - net_sprint_ipv6_addr(&mcast_addr.sin6_addr), ret); - return false; - } - - return true; -} -#endif - -#if defined(CONFIG_NET_IPV6) -static int start_coap_server(void) -{ - struct sockaddr_in6 addr6; - int r; - - memset(&addr6, 0, sizeof(addr6)); - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons(MY_COAP_PORT); - - sock = socket(addr6.sin6_family, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) { - LOG_ERR("Failed to create UDP socket %d", errno); - return -errno; - } - - r = bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)); - if (r < 0) { - LOG_ERR("Failed to bind UDP socket %d", errno); - return -errno; - } - - return 0; -} -#endif - -#if defined(CONFIG_NET_IPV4) -static int start_coap_server(void) -{ - struct sockaddr_in addr; - int r; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(MY_COAP_PORT); - - sock = socket(addr.sin_family, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) { - LOG_ERR("Failed to create UDP socket %d", errno); - return -errno; - } - - r = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); - if (r < 0) { - LOG_ERR("Failed to bind UDP socket %d", errno); - return -errno; - } - - return 0; -} -#endif - -static int send_coap_reply(struct coap_packet *cpkt, - const struct sockaddr *addr, - socklen_t addr_len) -{ - int r; - - net_hexdump("Response", cpkt->data, cpkt->offset); - - r = sendto(sock, cpkt->data, cpkt->offset, 0, addr, addr_len); - if (r < 0) { - LOG_ERR("Failed to send %d", errno); - r = -errno; - } - - return r; -} - -static int well_known_core_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_packet response; - uint8_t *data; - int r; - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_well_known_core_get(resource, request, &response, - data, MAX_COAP_MSG_LEN); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int piggyback_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_packet response; - uint8_t payload[40]; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_NON_CON; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - goto end; - } - - r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, - COAP_CONTENT_FORMAT_TEXT_PLAIN); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - goto end; - } - - /* The response that coap-client expects */ - r = snprintk((char *) payload, sizeof(payload), - "Type: %u\nCode: %u\nMID: %u\n", type, code, id); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload(&response, (uint8_t *)payload, - strlen(payload)); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int test_del(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_packet response; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint8_t tkl; - uint8_t code; - uint8_t type; - uint16_t id; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_NON_CON; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_DELETED, id); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int test_put(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_packet response; - uint8_t token[COAP_TOKEN_MAX_LEN]; - const uint8_t *payload; - uint8_t *data; - uint16_t payload_len; - uint8_t code; - uint8_t type; - uint8_t tkl; - uint16_t id; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - payload = coap_packet_get_payload(request, &payload_len); - if (payload) { - net_hexdump("PUT Payload", payload, payload_len); - } - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_NON_CON; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CHANGED, id); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int test_post(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - static const char * const location_path[] = { "location1", - "location2", - "location3", - NULL }; - const char * const *p; - struct coap_packet response; - uint8_t token[COAP_TOKEN_MAX_LEN]; - const uint8_t *payload; - uint8_t *data; - uint16_t payload_len; - uint8_t code; - uint8_t type; - uint8_t tkl; - uint16_t id; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - payload = coap_packet_get_payload(request, &payload_len); - if (payload) { - net_hexdump("POST Payload", payload, payload_len); - } - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_NON_CON; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CREATED, id); - if (r < 0) { - goto end; - } - - for (p = location_path; *p; p++) { - r = coap_packet_append_option(&response, - COAP_OPTION_LOCATION_PATH, - *p, strlen(*p)); - if (r < 0) { - goto end; - } - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int query_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_option options[4]; - struct coap_packet response; - uint8_t payload[40]; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int i, r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - r = coap_find_options(request, COAP_OPTION_URI_QUERY, options, 4); - if (r < 0) { - return -EINVAL; - } - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("num queries: %d", r); - - for (i = 0; i < r; i++) { - char str[16]; - - if (options[i].len + 1 > sizeof(str)) { - LOG_INF("Unexpected length of query: " - "%d (expected %zu)", - options[i].len, sizeof(str)); - break; - } - - memcpy(str, options[i].value, options[i].len); - str[options[i].len] = '\0'; - - LOG_INF("query[%d]: %s", i + 1, str); - } - - LOG_INF("*******"); - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - goto end; - } - - r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, - COAP_CONTENT_FORMAT_TEXT_PLAIN); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - goto end; - } - - /* The response that coap-client expects */ - r = snprintk((char *) payload, sizeof(payload), - "Type: %u\nCode: %u\nMID: %u\n", type, code, id); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload(&response, (uint8_t *)payload, - strlen(payload)); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int location_query_post(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - static const char *const location_query[] = { "first=1", - "second=2", - NULL }; - const char * const *p; - struct coap_packet response; - uint8_t *data; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_NON_CON; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CREATED, id); - if (r < 0) { - goto end; - } - - for (p = location_query; *p; p++) { - r = coap_packet_append_option(&response, - COAP_OPTION_LOCATION_QUERY, - *p, strlen(*p)); - if (r < 0) { - goto end; - } - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int separate_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_packet response; - uint8_t payload[40]; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - if (type == COAP_TYPE_ACK) { - return 0; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, 0, id); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - if (r < 0) { - goto end; - } - - if (type == COAP_TYPE_CON) { - type = COAP_TYPE_CON; - } else { - type = COAP_TYPE_NON_CON; - } - - /* Do not free and allocate "data" again, re-use the buffer */ - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - goto end; - } - - r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, - COAP_CONTENT_FORMAT_TEXT_PLAIN); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - goto end; - } - - /* The response that coap-client expects */ - r = snprintk((char *) payload, sizeof(payload), - "Type: %u\nCode: %u\nMID: %u\n", type, code, id); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload(&response, (uint8_t *)payload, - strlen(payload)); - if (r < 0) { - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int large_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) - -{ - static struct coap_block_context ctx; - struct coap_packet response; - uint8_t payload[64]; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t size; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - - if (ctx.total_size == 0) { - coap_block_transfer_init(&ctx, COAP_BLOCK_64, - BLOCK_WISE_TRANSFER_SIZE_GET); - } - - r = coap_update_from_block(request, &ctx); - if (r < 0) { - return -EINVAL; - } - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - return -EINVAL; - } - - r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, - COAP_CONTENT_FORMAT_TEXT_PLAIN); - if (r < 0) { - goto end; - } - - r = coap_append_block2_option(&response, &ctx); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - goto end; - } - - size = MIN(coap_block_size_to_bytes(ctx.block_size), - ctx.total_size - ctx.current); - - memset(payload, 'A', MIN(size, sizeof(payload))); - - r = coap_packet_append_payload(&response, (uint8_t *)payload, size); - if (r < 0) { - goto end; - } - - r = coap_next_block(&response, &ctx); - if (!r) { - /* Will return 0 when it's the last block. */ - memset(&ctx, 0, sizeof(ctx)); - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int large_update_put(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - static struct coap_block_context ctx; - struct coap_packet response; - const uint8_t *payload; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t id; - uint16_t len; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - bool last_block; - - r = coap_get_option_int(request, COAP_OPTION_BLOCK1); - if (r < 0) { - return -EINVAL; - } - - last_block = !GET_MORE(r); - - /* initialize block context upon the arrival of first block */ - if (!GET_BLOCK_NUM(r)) { - coap_block_transfer_init(&ctx, COAP_BLOCK_64, 0); - } - - r = coap_update_from_block(request, &ctx); - if (r < 0) { - LOG_ERR("Invalid block size option from request"); - return -EINVAL; - } - - payload = coap_packet_get_payload(request, &len); - if (!last_block && payload == NULL) { - LOG_ERR("Packet without payload"); - return -EINVAL; - } - - LOG_INF("**************"); - LOG_INF("[ctx] current %zu block_size %u total_size %zu", - ctx.current, coap_block_size_to_bytes(ctx.block_size), - ctx.total_size); - LOG_INF("**************"); - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - /* Do something with the payload */ - - if (!last_block) { - code = COAP_RESPONSE_CODE_CONTINUE; - } else { - code = COAP_RESPONSE_CODE_CHANGED; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, - code, id); - if (r < 0) { - goto end; - } - - r = coap_append_block1_option(&response, &ctx); - if (r < 0) { - LOG_ERR("Could not add Block1 option to response"); - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static int large_create_post(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - static struct coap_block_context ctx; - struct coap_packet response; - const uint8_t *payload; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t len; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - int r; - bool last_block; - - r = coap_get_option_int(request, COAP_OPTION_BLOCK1); - if (r < 0) { - return -EINVAL; - } - - last_block = !GET_MORE(r); - - /* initialize block context upon the arrival of first block */ - if (!GET_BLOCK_NUM(r)) { - coap_block_transfer_init(&ctx, COAP_BLOCK_32, 0); - } - - r = coap_update_from_block(request, &ctx); - if (r < 0) { - LOG_ERR("Invalid block size option from request"); - return -EINVAL; - } - - payload = coap_packet_get_payload(request, &len); - if (!last_block && payload) { - LOG_ERR("Packet without payload"); - return -EINVAL; - } - - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - if (!last_block) { - code = COAP_RESPONSE_CODE_CONTINUE; - } else { - code = COAP_RESPONSE_CODE_CREATED; - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, - code, id); - if (r < 0) { - goto end; - } - - r = coap_append_block1_option(&response, &ctx); - if (r < 0) { - LOG_ERR("Could not add Block1 option to response"); - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static void schedule_next_retransmission(void) -{ - struct coap_pending *pending; - int64_t remaining; - int64_t now = k_uptime_get(); - - /* Get the first pending retransmission to expire after cycling. */ - pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS); - if (!pending) { - return; - } - - remaining = pending->t0 + pending->timeout - now; - if (remaining < 0) { - remaining = 0; - } - - k_work_reschedule(&retransmit_work, K_MSEC(remaining)); -} - -static void remove_observer(struct sockaddr *addr); - -static void retransmit_request(struct k_work *work) -{ - struct coap_pending *pending; - int r; - - pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS); - if (!pending) { - return; - } - - if (!coap_pending_cycle(pending)) { - remove_observer(&pending->addr); - k_free(pending->data); - coap_pending_clear(pending); - } else { - net_hexdump("Retransmit", pending->data, pending->len); - - r = sendto(sock, pending->data, pending->len, 0, - &pending->addr, ADDRLEN(&pending->addr)); - if (r < 0) { - LOG_ERR("Failed to send %d", errno); - } - } - - schedule_next_retransmission(); -} - -static void update_counter(struct k_work *work) -{ - obs_counter++; - - if (resource_to_notify) { - coap_resource_notify(resource_to_notify); - } - - k_work_reschedule(&observer_work, K_SECONDS(5)); -} - -static int create_pending_request(struct coap_packet *response, - const struct sockaddr *addr) -{ - struct coap_pending *pending; - int r; - - pending = coap_pending_next_unused(pendings, NUM_PENDINGS); - if (!pending) { - return -ENOMEM; - } - - r = coap_pending_init(pending, response, addr, MAX_RETRANSMIT_COUNT); - if (r < 0) { - return -EINVAL; - } - - coap_pending_cycle(pending); - - schedule_next_retransmission(); - - return 0; -} - -static int send_notification_packet(const struct sockaddr *addr, - socklen_t addr_len, - uint16_t age, uint16_t id, - const uint8_t *token, uint8_t tkl, - bool is_response) -{ - struct coap_packet response; - char payload[14]; - uint8_t *data; - uint8_t type; - int r; - - if (is_response) { - type = COAP_TYPE_ACK; - } else { - type = COAP_TYPE_CON; - } - - if (!is_response) { - id = coap_next_id(); - } - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, type, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - goto end; - } - - if (age >= 2U) { - r = coap_append_option_int(&response, COAP_OPTION_OBSERVE, age); - if (r < 0) { - goto end; - } - } - - r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, - COAP_CONTENT_FORMAT_TEXT_PLAIN); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - goto end; - } - - /* The response that coap-client expects */ - r = snprintk((char *) payload, sizeof(payload), - "Counter: %d\n", obs_counter); - if (r < 0) { - goto end; - } - - r = coap_packet_append_payload(&response, (uint8_t *)payload, - strlen(payload)); - if (r < 0) { - goto end; - } - - if (type == COAP_TYPE_CON) { - r = create_pending_request(&response, addr); - if (r < 0) { - goto end; - } - } - - k_work_reschedule(&observer_work, K_SECONDS(5)); - - r = send_coap_reply(&response, addr, addr_len); - - /* On successful creation of pending request, do not free memory */ - if (type == COAP_TYPE_CON) { - return r; - } - -end: - k_free(data); - - return r; -} - -static int obs_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - struct coap_observer *observer; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint16_t id; - uint8_t code; - uint8_t type; - uint8_t tkl; - bool observe = true; - - if (!coap_request_is_observe(request)) { - if (coap_get_option_int(request, COAP_OPTION_OBSERVE) == 1) { - remove_observer(addr); - } - observe = false; - goto done; - } - - observer = coap_observer_next_unused(observers, NUM_OBSERVERS); - if (!observer) { - LOG_ERR("Not enough observer slots."); - return -ENOMEM; - } - - coap_observer_init(observer, request, addr); - - coap_register_observer(resource, observer); - - resource_to_notify = resource; - -done: - code = coap_header_get_code(request); - type = coap_header_get_type(request); - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - LOG_INF("*******"); - LOG_INF("type: %u code %u id %u", type, code, id); - LOG_INF("*******"); - - return send_notification_packet(addr, addr_len, - observe ? resource->age : 0, - id, token, tkl, true); -} - -static void obs_notify(struct coap_resource *resource, - struct coap_observer *observer) -{ - send_notification_packet(&observer->addr, - sizeof(observer->addr), - resource->age, 0, - observer->token, observer->tkl, false); -} - -static int core_get(struct coap_resource *resource, - struct coap_packet *request, - struct sockaddr *addr, socklen_t addr_len) -{ - static const char dummy_str[] = "Just a test\n"; - struct coap_packet response; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t *data; - uint16_t id; - uint8_t tkl; - int r; - - id = coap_header_get_id(request); - tkl = coap_header_get_token(request, token); - - data = (uint8_t *)k_malloc(MAX_COAP_MSG_LEN); - if (!data) { - return -ENOMEM; - } - - r = coap_packet_init(&response, data, MAX_COAP_MSG_LEN, - COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, - COAP_RESPONSE_CODE_CONTENT, id); - if (r < 0) { - r = -EINVAL; - goto end; - } - - r = coap_packet_append_payload_marker(&response); - if (r < 0) { - r = -EINVAL; - goto end; - } - - r = coap_packet_append_payload(&response, (uint8_t *)dummy_str, - sizeof(dummy_str)); - if (r < 0) { - r = -EINVAL; - goto end; - } - - r = send_coap_reply(&response, addr, addr_len); - -end: - k_free(data); - - return r; -} - -static const char * const test_path[] = { "test", NULL }; - -static const char * const segments_path[] = { "seg1", "seg2", "seg3", NULL }; - -#if defined(CONFIG_COAP_URI_WILDCARD) -static const char * const wildcard1_path[] = { "wild1", "+", "wild3", NULL }; - -static const char * const wildcard2_path[] = { "wild2", "#", NULL }; -#endif /* CONFIG_COAP_URI_WILDCARD */ - -static const char * const query_path[] = { "query", NULL }; - -static const char * const separate_path[] = { "separate", NULL }; - -static const char * const location_query_path[] = { "location-query", NULL }; - -static const char * const large_path[] = { "large", NULL }; - -static const char * const large_update_path[] = { "large-update", NULL }; - -static const char * const large_create_path[] = { "large-create", NULL }; - -static const char * const obs_path[] = { "obs", NULL }; - -static const char * const core_1_path[] = { "core1", NULL }; -static const char * const core_1_attributes[] = { - "title=\"Core 1\"", - "rt=core1", - NULL }; - -static const char * const core_2_path[] = { "core2", NULL }; -static const char * const core_2_attributes[] = { - "title=\"Core 1\"", - "rt=core1", - NULL }; - -static struct coap_resource coap_resources[] = { - { .get = well_known_core_get, - .path = COAP_WELL_KNOWN_CORE_PATH, - }, - { .get = piggyback_get, - .post = test_post, - .del = test_del, - .put = test_put, - .path = test_path - }, - { .get = piggyback_get, - .path = segments_path, - }, -#if defined(CONFIG_COAP_URI_WILDCARD) - { .get = piggyback_get, - .path = wildcard1_path, - }, - { .get = piggyback_get, - .path = wildcard2_path, - }, -#endif /* CONFIG_COAP_URI_WILDCARD */ - { .get = query_get, - .path = query_path, - }, - { .get = separate_get, - .path = separate_path, - }, - { .path = location_query_path, - .post = location_query_post, - }, - { .path = large_path, - .get = large_get, - }, - { .path = large_update_path, - .put = large_update_put, - }, - { .path = large_create_path, - .post = large_create_post, - }, - { .path = obs_path, - .get = obs_get, - .notify = obs_notify, - }, - { .get = core_get, - .path = core_1_path, - .user_data = &((struct coap_core_metadata) { - .attributes = core_1_attributes, - }), - }, - { .get = core_get, - .path = core_2_path, - .user_data = &((struct coap_core_metadata) { - .attributes = core_2_attributes, - }), - }, - { }, -}; - -static struct coap_resource *find_resource_by_observer( - struct coap_resource *resources, struct coap_observer *o) -{ - struct coap_resource *r; - - for (r = resources; r && r->path; r++) { - sys_snode_t *node; - - SYS_SLIST_FOR_EACH_NODE(&r->observers, node) { - if (&o->list == node) { - return r; - } - } - } - - return NULL; -} - -static void remove_observer(struct sockaddr *addr) -{ - struct coap_resource *r; - struct coap_observer *o; - - o = coap_find_observer_by_addr(observers, NUM_OBSERVERS, addr); - if (!o) { - return; - } - - r = find_resource_by_observer(coap_resources, o); - if (!r) { - LOG_ERR("Observer found but Resource not found\n"); - return; - } - - LOG_INF("Removing observer %p", o); - - coap_remove_observer(r, o); - memset(o, 0, sizeof(struct coap_observer)); -} - -static void process_coap_request(uint8_t *data, uint16_t data_len, - struct sockaddr *client_addr, - socklen_t client_addr_len) -{ - struct coap_packet request; - struct coap_pending *pending; - struct coap_option options[16] = { 0 }; - uint8_t opt_num = 16U; - uint8_t type; - int r; - - r = coap_packet_parse(&request, data, data_len, options, opt_num); - if (r < 0) { - LOG_ERR("Invalid data received (%d)\n", r); - return; - } - - type = coap_header_get_type(&request); - - pending = coap_pending_received(&request, pendings, NUM_PENDINGS); - if (!pending) { - goto not_found; - } - - /* Clear CoAP pending request */ - if (type == COAP_TYPE_ACK || type == COAP_TYPE_RESET) { - k_free(pending->data); - coap_pending_clear(pending); - - if (type == COAP_TYPE_RESET) { - remove_observer(client_addr); - } - } - - return; - -not_found: - r = coap_handle_request(&request, coap_resources, options, opt_num, - client_addr, client_addr_len); - if (r < 0) { - LOG_WRN("No handler for such request (%d)\n", r); - } -} - -static int process_client_request(void) -{ - int received; - struct sockaddr client_addr; - socklen_t client_addr_len; - uint8_t request[MAX_COAP_MSG_LEN]; - - do { - client_addr_len = sizeof(client_addr); - received = recvfrom(sock, request, sizeof(request), 0, - &client_addr, &client_addr_len); - if (received < 0) { - LOG_ERR("Connection error %d", errno); - return -errno; - } - - process_coap_request(request, received, &client_addr, - client_addr_len); - } while (true); - - return 0; -} - -int main(void) -{ - int r; - - LOG_DBG("Start CoAP-server sample"); - -#if defined(CONFIG_NET_IPV6) - bool res; - - res = join_coap_multicast_group(); - if (!res) { - goto quit; - } -#endif - - r = start_coap_server(); - if (r < 0) { - goto quit; - } - - k_work_init_delayable(&retransmit_work, retransmit_request); - k_work_init_delayable(&observer_work, update_counter); - - while (1) { - r = process_client_request(); - if (r < 0) { - goto quit; - } - } - - LOG_DBG("Done"); - return 0; - -quit: - LOG_ERR("Quit"); - return 0; -} diff --git a/samples/net/sockets/coap_server/src/core.c b/samples/net/sockets/coap_server/src/core.c new file mode 100644 index 00000000000..276ab0d5de1 --- /dev/null +++ b/samples/net/sockets/coap_server/src/core.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include +#include + +static int core_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + static const char dummy_str[] = "Just a test\n"; + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t tkl; + int r; + + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload(&response, (uint8_t *)dummy_str, + sizeof(dummy_str)); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const core_1_path[] = { "core1", NULL }; +static const char * const core_1_attributes[] = { + "title=\"Core 1\"", + "rt=core1", + NULL, +}; +COAP_RESOURCE_DEFINE(core_1, coap_server, +{ + .get = core_get, + .path = core_1_path, + .user_data = &((struct coap_core_metadata) { + .attributes = core_1_attributes, + }), +}); + +static const char * const core_2_path[] = { "core2", NULL }; +static const char * const core_2_attributes[] = { + "title=\"Core 2\"", + "rt=core2", + NULL, +}; +COAP_RESOURCE_DEFINE(core_2, coap_server, +{ + .get = core_get, + .path = core_2_path, + .user_data = &((struct coap_core_metadata) { + .attributes = core_2_attributes, + }), +}); diff --git a/samples/net/sockets/coap_server/src/large.c b/samples/net/sockets/coap_server/src/large.c new file mode 100644 index 00000000000..28a3eebe099 --- /dev/null +++ b/samples/net/sockets/coap_server/src/large.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +#define BLOCK_WISE_TRANSFER_SIZE_GET 2048 + +static int large_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) + +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + static struct coap_block_context ctx; + struct coap_packet response; + uint8_t payload[64]; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t size; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + + if (ctx.total_size == 0) { + coap_block_transfer_init(&ctx, COAP_BLOCK_64, BLOCK_WISE_TRANSFER_SIZE_GET); + } + + r = coap_update_from_block(request, &ctx); + if (r < 0) { + return -EINVAL; + } + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return -EINVAL; + } + + r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + if (r < 0) { + return r; + } + + r = coap_append_block2_option(&response, &ctx); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + size = MIN(coap_block_size_to_bytes(ctx.block_size), + ctx.total_size - ctx.current); + + memset(payload, 'A', MIN(size, sizeof(payload))); + + r = coap_packet_append_payload(&response, (uint8_t *)payload, size); + if (r < 0) { + return r; + } + + r = coap_next_block(&response, &ctx); + if (!r) { + /* Will return 0 when it's the last block. */ + memset(&ctx, 0, sizeof(ctx)); + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int large_update_put(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + static struct coap_block_context ctx; + struct coap_packet response; + const uint8_t *payload; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint16_t len; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + bool last_block; + + r = coap_get_option_int(request, COAP_OPTION_BLOCK1); + if (r < 0) { + return -EINVAL; + } + + last_block = !GET_MORE(r); + + /* initialize block context upon the arrival of first block */ + if (!GET_BLOCK_NUM(r)) { + coap_block_transfer_init(&ctx, COAP_BLOCK_64, 0); + } + + r = coap_update_from_block(request, &ctx); + if (r < 0) { + LOG_ERR("Invalid block size option from request"); + return -EINVAL; + } + + payload = coap_packet_get_payload(request, &len); + if (!last_block && payload == NULL) { + LOG_ERR("Packet without payload"); + return -EINVAL; + } + + LOG_INF("**************"); + LOG_INF("[ctx] current %zu block_size %u total_size %zu", + ctx.current, coap_block_size_to_bytes(ctx.block_size), + ctx.total_size); + LOG_INF("**************"); + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + /* Do something with the payload */ + + if (!last_block) { + code = COAP_RESPONSE_CODE_CONTINUE; + } else { + code = COAP_RESPONSE_CODE_CHANGED; + } + + r = coap_ack_init(&response, request, data, sizeof(data), code); + if (r < 0) { + return r; + } + + r = coap_append_block1_option(&response, &ctx); + if (r < 0) { + LOG_ERR("Could not add Block1 option to response"); + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int large_create_post(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + static struct coap_block_context ctx; + struct coap_packet response; + const uint8_t *payload; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t len; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + bool last_block; + + r = coap_get_option_int(request, COAP_OPTION_BLOCK1); + if (r < 0) { + return -EINVAL; + } + + last_block = !GET_MORE(r); + + /* initialize block context upon the arrival of first block */ + if (!GET_BLOCK_NUM(r)) { + coap_block_transfer_init(&ctx, COAP_BLOCK_32, 0); + } + + r = coap_update_from_block(request, &ctx); + if (r < 0) { + LOG_ERR("Invalid block size option from request"); + return -EINVAL; + } + + payload = coap_packet_get_payload(request, &len); + if (!last_block && payload) { + LOG_ERR("Packet without payload"); + return -EINVAL; + } + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + if (!last_block) { + code = COAP_RESPONSE_CODE_CONTINUE; + } else { + code = COAP_RESPONSE_CODE_CREATED; + } + + r = coap_ack_init(&response, request, data, sizeof(data), code); + if (r < 0) { + return r; + } + + r = coap_append_block1_option(&response, &ctx); + if (r < 0) { + LOG_ERR("Could not add Block1 option to response"); + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const large_path[] = { "large", NULL }; +COAP_RESOURCE_DEFINE(large, coap_server, +{ + .get = large_get, + .path = large_path, +}); + +static const char * const large_update_path[] = { "large-update", NULL }; +COAP_RESOURCE_DEFINE(large_update, coap_server, +{ + .put = large_update_put, + .path = large_update_path, +}); + +static const char * const large_create_path[] = { "large-create", NULL }; +COAP_RESOURCE_DEFINE(large_create, coap_server, +{ + .post = large_create_post, + .path = large_create_path, +}); diff --git a/samples/net/sockets/coap_server/src/location_query.c b/samples/net/sockets/coap_server/src/location_query.c new file mode 100644 index 00000000000..b13079bc456 --- /dev/null +++ b/samples/net/sockets/coap_server/src/location_query.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +static int location_query_post(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + static const char *const location_query[] = { "first=1", + "second=2", + NULL }; + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + const char * const *p; + struct coap_packet response; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_NON_CON; + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CREATED, id); + if (r < 0) { + return r; + } + + for (p = location_query; *p; p++) { + r = coap_packet_append_option(&response, + COAP_OPTION_LOCATION_QUERY, + *p, strlen(*p)); + if (r < 0) { + return r; + } + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const location_query_path[] = { "location-query", NULL }; +COAP_RESOURCE_DEFINE(location_query, coap_server, +{ + .post = location_query_post, + .path = location_query_path, +}); diff --git a/samples/net/sockets/coap_server/src/main.c b/samples/net/sockets/coap_server/src/main.c new file mode 100644 index 00000000000..4f476511b2c --- /dev/null +++ b/samples/net/sockets/coap_server/src/main.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_coap_service_sample, LOG_LEVEL_DBG); + +#include + +#ifdef CONFIG_NET_IPV6 +#include "net_private.h" +#include "ipv6.h" +#endif + +static const uint16_t coap_port = 5683; + +#ifdef CONFIG_NET_IPV6 + +#define ALL_NODES_LOCAL_COAP_MCAST \ + { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd } } } + +#define MY_IP6ADDR \ + { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } } + +static int join_coap_multicast_group(void) +{ + static struct in6_addr my_addr = MY_IP6ADDR; + static struct sockaddr_in6 mcast_addr = { + .sin6_family = AF_INET6, + .sin6_addr = ALL_NODES_LOCAL_COAP_MCAST, + .sin6_port = htons(coap_port) }; + struct net_if_addr *ifaddr; + struct net_if *iface; + int ret; + + iface = net_if_get_default(); + if (!iface) { + LOG_ERR("Could not get the default interface"); + return -ENOENT; + } + +#if defined(CONFIG_NET_CONFIG_SETTINGS) + if (net_addr_pton(AF_INET6, + CONFIG_NET_CONFIG_MY_IPV6_ADDR, + &my_addr) < 0) { + LOG_ERR("Invalid IPv6 address %s", + CONFIG_NET_CONFIG_MY_IPV6_ADDR); + } +#endif + + ifaddr = net_if_ipv6_addr_add(iface, &my_addr, NET_ADDR_MANUAL, 0); + if (!ifaddr) { + LOG_ERR("Could not add unicast address to interface"); + return -EINVAL; + } + + ifaddr->addr_state = NET_ADDR_PREFERRED; + + ret = net_ipv6_mld_join(iface, &mcast_addr.sin6_addr); + if (ret < 0) { + LOG_ERR("Cannot join %s IPv6 multicast group (%d)", + net_sprint_ipv6_addr(&mcast_addr.sin6_addr), ret); + return ret; + } + + return 0; +} + +int main(void) +{ + return join_coap_multicast_group(); +} + +#else /* CONFIG_NET_IPV6 */ + +int main(void) +{ + return 0; +} + +#endif /* CONFIG_NET_IPV6 */ + +COAP_SERVICE_DEFINE(coap_server, NULL, &coap_port, COAP_SERVICE_AUTOSTART); diff --git a/samples/net/sockets/coap_server/src/observer.c b/samples/net/sockets/coap_server/src/observer.c new file mode 100644 index 00000000000..29b7b4ed472 --- /dev/null +++ b/samples/net/sockets/coap_server/src/observer.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include +#include + +static int obs_counter; + +static void update_counter(struct k_work *work); +K_WORK_DELAYABLE_DEFINE(obs_work, update_counter); + +#ifdef CONFIG_COAP_OBSERVER_EVENTS + +static void observer_event(struct coap_resource *resource, struct coap_observer *observer, + enum coap_observer_event event) +{ + LOG_INF("Observer %s", event == COAP_OBSERVER_ADDED ? "added" : "removed"); +} + +#endif + +static int send_notification_packet(struct coap_resource *resource, + const struct sockaddr *addr, + socklen_t addr_len, + uint16_t age, uint16_t id, + const uint8_t *token, uint8_t tkl, + bool is_response) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + char payload[14]; + uint8_t type; + int r; + + if (is_response) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_CON; + } + + if (!is_response) { + id = coap_next_id(); + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return r; + } + + if (age >= 2U) { + r = coap_append_option_int(&response, COAP_OPTION_OBSERVE, age); + if (r < 0) { + return r; + } + } + + r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + /* The response that coap-client expects */ + r = snprintk((char *) payload, sizeof(payload), + "Counter: %d\n", obs_counter); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload(&response, (uint8_t *)payload, + strlen(payload)); + if (r < 0) { + return r; + } + + k_work_reschedule(&obs_work, K_SECONDS(5)); + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int obs_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + + r = coap_resource_parse_observe(resource, request, addr); + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + return send_notification_packet(resource, addr, addr_len, + r == 0 ? resource->age : 0, + id, token, tkl, true); +} + +static void obs_notify(struct coap_resource *resource, + struct coap_observer *observer) +{ + send_notification_packet(resource, + &observer->addr, + sizeof(observer->addr), + resource->age, 0, + observer->token, observer->tkl, false); +} + +static const char * const obs_path[] = { "obs", NULL }; +COAP_RESOURCE_DEFINE(obs, coap_server, +{ + .get = obs_get, + .path = obs_path, + .notify = obs_notify, +#ifdef CONFIG_COAP_OBSERVER_EVENTS + .observer_event_handler = observer_event, +#endif +}); + +static void update_counter(struct k_work *work) +{ + obs_counter++; + + coap_resource_notify(&obs); + + k_work_reschedule(&obs_work, K_SECONDS(5)); +} diff --git a/samples/net/sockets/coap_server/src/query.c b/samples/net/sockets/coap_server/src/query.c new file mode 100644 index 00000000000..10479b1e6f1 --- /dev/null +++ b/samples/net/sockets/coap_server/src/query.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +static int query_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_option options[4]; + struct coap_packet response; + uint8_t payload[40]; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int i, r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + r = coap_find_options(request, COAP_OPTION_URI_QUERY, options, 4); + if (r < 0) { + return -EINVAL; + } + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("num queries: %d", r); + + for (i = 0; i < r; i++) { + char str[16]; + + if (options[i].len + 1 > sizeof(str)) { + LOG_INF("Unexpected length of query: " + "%d (expected %zu)", + options[i].len, sizeof(str)); + break; + } + + memcpy(str, options[i].value, options[i].len); + str[options[i].len] = '\0'; + + LOG_INF("query[%d]: %s", i + 1, str); + } + + LOG_INF("*******"); + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, COAP_TYPE_ACK, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return r; + } + + r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + /* The response that coap-client expects */ + r = snprintk((char *) payload, sizeof(payload), + "Type: %u\nCode: %u\nMID: %u\n", type, code, id); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload(&response, (uint8_t *)payload, + strlen(payload)); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const query_path[] = { "query", NULL }; +COAP_RESOURCE_DEFINE(query, coap_server, +{ + .get = query_get, + .path = query_path, +}); diff --git a/samples/net/sockets/coap_server/src/separate.c b/samples/net/sockets/coap_server/src/separate.c new file mode 100644 index 00000000000..c3f6f6c256e --- /dev/null +++ b/samples/net/sockets/coap_server/src/separate.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +static int separate_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint8_t payload[40]; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + if (type == COAP_TYPE_ACK) { + return 0; + } + + r = coap_ack_init(&response, request, data, sizeof(data), 0); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + if (r < 0) { + return r; + } + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_CON; + } else { + type = COAP_TYPE_NON_CON; + } + + /* Re-use the buffer */ + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return r; + } + + r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + /* The response that coap-client expects */ + r = snprintk((char *) payload, sizeof(payload), + "Type: %u\nCode: %u\nMID: %u\n", type, code, id); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload(&response, (uint8_t *)payload, + strlen(payload)); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const separate_path[] = { "separate", NULL }; +COAP_RESOURCE_DEFINE(separate, coap_server, +{ + .get = separate_get, + .path = separate_path, +}); diff --git a/samples/net/sockets/coap_server/src/test.c b/samples/net/sockets/coap_server/src/test.c new file mode 100644 index 00000000000..aa496a125b1 --- /dev/null +++ b/samples/net/sockets/coap_server/src/test.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +#include "net_private.h" + +static int piggyback_get(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint8_t payload[40]; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t code; + uint8_t type; + uint8_t tkl; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_NON_CON; + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + if (r < 0) { + return r; + } + + r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload_marker(&response); + if (r < 0) { + return r; + } + + /* The response that coap-client expects */ + r = snprintk((char *) payload, sizeof(payload), + "Type: %u\nCode: %u\nMID: %u\n", type, code, id); + if (r < 0) { + return r; + } + + r = coap_packet_append_payload(&response, (uint8_t *)payload, + strlen(payload)); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int test_del(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; + uint8_t code; + uint8_t type; + uint16_t id; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_NON_CON; + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_DELETED, id); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int test_put(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint8_t token[COAP_TOKEN_MAX_LEN]; + const uint8_t *payload; + uint16_t payload_len; + uint8_t code; + uint8_t type; + uint8_t tkl; + uint16_t id; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + payload = coap_packet_get_payload(request, &payload_len); + if (payload) { + net_hexdump("PUT Payload", payload, payload_len); + } + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_NON_CON; + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CHANGED, id); + if (r < 0) { + return r; + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static int test_post(struct coap_resource *resource, + struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) +{ + static const char * const location_path[] = { "location1", + "location2", + "location3", + NULL }; + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + const char * const *p; + struct coap_packet response; + uint8_t token[COAP_TOKEN_MAX_LEN]; + const uint8_t *payload; + uint16_t payload_len; + uint8_t code; + uint8_t type; + uint8_t tkl; + uint16_t id; + int r; + + code = coap_header_get_code(request); + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + LOG_INF("*******"); + LOG_INF("type: %u code %u id %u", type, code, id); + LOG_INF("*******"); + + payload = coap_packet_get_payload(request, &payload_len); + if (payload) { + net_hexdump("POST Payload", payload, payload_len); + } + + if (type == COAP_TYPE_CON) { + type = COAP_TYPE_ACK; + } else { + type = COAP_TYPE_NON_CON; + } + + r = coap_packet_init(&response, data, sizeof(data), + COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CREATED, id); + if (r < 0) { + return r; + } + + for (p = location_path; *p; p++) { + r = coap_packet_append_option(&response, + COAP_OPTION_LOCATION_PATH, + *p, strlen(*p)); + if (r < 0) { + return r; + } + } + + r = coap_resource_send(resource, &response, addr, addr_len); + + return r; +} + +static const char * const test_path[] = { "test", NULL }; +COAP_RESOURCE_DEFINE(test, coap_server, +{ + .get = piggyback_get, + .post = test_post, + .del = test_del, + .put = test_put, + .path = test_path, +}); + +static const char * const segments_path[] = { "seg1", "seg2", "seg3", NULL }; +COAP_RESOURCE_DEFINE(segments, coap_server, +{ + .get = piggyback_get, + .path = segments_path, +}); + +#if defined(CONFIG_COAP_URI_WILDCARD) + +static const char * const wildcard1_path[] = { "wild1", "+", "wild3", NULL }; +COAP_RESOURCE_DEFINE(wildcard1, coap_server, +{ + .get = piggyback_get, + .path = wildcard1_path, +}); + +static const char * const wildcard2_path[] = { "wild2", "#", NULL }; +COAP_RESOURCE_DEFINE(wildcard2, coap_server, +{ + .get = piggyback_get, + .path = wildcard2_path, +}); + +#endif From 230c989590328eebe272b452ef310ee2c4be07b1 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 7 Nov 2023 14:22:38 +0100 Subject: [PATCH 3321/4498] doc: connectivity: networking: api: Add CoAP server documentation Created a dedicated page for CoAP service and resource examples. Signed-off-by: Pieter De Gendt --- .../networking/api/coap_server.rst | 247 ++++++++++++++++++ doc/connectivity/networking/api/protocols.rst | 1 + 2 files changed, 248 insertions(+) create mode 100644 doc/connectivity/networking/api/coap_server.rst diff --git a/doc/connectivity/networking/api/coap_server.rst b/doc/connectivity/networking/api/coap_server.rst new file mode 100644 index 00000000000..9a91081f449 --- /dev/null +++ b/doc/connectivity/networking/api/coap_server.rst @@ -0,0 +1,247 @@ +.. _coap_server_interface: + +CoAP server +########### + +.. contents:: + :local: + :depth: 2 + +Overview +******** + +Zephyr comes with a batteries-included CoAP server, which uses services to listen for CoAP +requests. The CoAP services handle communication over sockets and pass requests to registered +CoAP resources. + +Setup +***** + +Some configuration is required to make sure services can be started using the CoAP server. The +:kconfig:option:`CONFIG_COAP_SERVER` option should be enabled in your project: + +.. code-block:: cfg + :caption: ``prj.conf`` + + CONFIG_COAP_SERVER=y + +All services are added to a predefined linker section and all resources for each service also get +their respective linker sections. If you would have a service ``my_service`` it has to be +prefixed wth ``coap_resource_`` and added to a linker file: + +.. code-block:: c + :caption: ``sections-ram.ld`` + + #include + + ITERABLE_SECTION_RAM(coap_resource_my_service, 4) + +Add this linker file to your application using CMake: + +.. code-block:: cmake + :caption: ``CMakeLists.txt`` + + zephyr_linker_sources(DATA_SECTIONS sections-ram.ld) + +You can now define your service as part of the application: + +.. code-block:: c + + #include + + static const uint16_t my_service_port = 5683; + + COAP_SERVICE_DEFINE(my_service, "0.0.0.0", &my_service_port, COAP_SERVICE_AUTOSTART); + +.. note:: + + Services defined with the ``COAP_SERVICE_AUTOSTART`` flag will be started together with the CoAP + server thread. Services can be manually started and stopped with ``coap_service_start`` and + ``coap_service_stop`` respectively. + +Sample Usage +************ + +The following is an example of a CoAP resource registered with our service: + +.. code-block:: c + + #include + + static int my_get(struct coap_resource *resource, struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) + { + static const char *msg = "Hello, world!"; + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + uint16_t id; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl, type; + + type = coap_header_get_type(request); + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + /* Determine response type */ + type = (type == COAP_TYPE_CON) ? COAP_TYPE_ACK : COAP_TYPE_NON_CON; + + coap_packet_init(&response, data, sizeof(data), COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + + /* Set content format */ + coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + + /* Append payload */ + coap_packet_append_payload_marker(&response); + coap_packet_append_payload(&response, (uint8_t *)msg, sizeof(msg)); + + /* Send to response back to the client */ + return coap_resource_send(resource, &response, addr, addr_len); + } + + static int my_put(struct coap_resource *resource, struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) + { + /* ... Handle the incoming request ... */ + + /* Return a CoAP response code as a shortcut for an empty ACK message */ + return COAP_RESPONSE_CODE_CHANGED; + } + + static const char * const my_resource_path[] = { "test", NULL }; + COAP_RESOURCE_DEFINE(my_resource, my_service, { + .path = my_resource_path, + .get = my_get, + .put = my_put, + }); + +.. note:: + + As demonstrated in the example above, a CoAP resource handler can return response codes to let + the server respond with an empty ACK response. + +Observable resources +******************** + +The CoAP server provides logic for parsing observe requests and stores these using the runtime data +of CoAP services. Together with observer events, enabled with +:kconfig:option:`CONFIG_COAP_OBSERVER_EVENTS`, the application can easily keep track of clients +and send state updates. An example using a temperature sensor can look like: + +.. code-block:: c + + #include + #include + #include + + static void notify_observers(struct k_work *work); + K_WORK_DELAYABLE_DEFINE(temp_work, notify_observers); + + static void temp_observer_event(struct coap_resource *resource, struct coap_observer *observer, + enum coap_observer_event event) + { + /* Only track the sensor temperature if an observer is active */ + if (event == COAP_OBSERVER_ADDED) { + k_work_schedule(&temp_work, K_SECONDS(1)); + } + } + + static int send_temperature(struct coap_resource *resource, + const struct sockaddr *addr, socklen_t addr_len, + uint16_t age, uint16_t id, const uint8_t *token, uint8_t tkl, + bool is_response) + { + const struct device *dev = DEVICE_DT_GET(DT_ALIAS(ambient_temp0)); + uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE]; + struct coap_packet response; + char payload[14]; + struct sensor_value value; + double temp; + uint8_t type; + + /* Determine response type */ + type = is_response ? COAP_TYPE_ACK : COAP_TYPE_CON; + + if (!is_response) { + id = coap_next_id(); + } + + coap_packet_init(&response, data, sizeof(data), COAP_VERSION_1, type, tkl, token, + COAP_RESPONSE_CODE_CONTENT, id); + + if (age >= 2U) { + coap_append_option_int(&response, COAP_OPTION_OBSERVE, age); + } + + /* Set content format */ + coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, + COAP_CONTENT_FORMAT_TEXT_PLAIN); + + /* Get the sensor date */ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP); + sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &value); + temp = sensor_value_to_double(&value); + + snprintk(payload, sizeof(payload), "%0.2f°C", temp); + + /* Append payload */ + coap_packet_append_payload_marker(&response); + coap_packet_append_payload(&response, (uint8_t *)payload, strlen(payload)); + + return coap_resource_send(resource, &response, addr, addr_len); + } + + static int temp_get(struct coap_resource *resource, struct coap_packet *request, + struct sockaddr *addr, socklen_t addr_len) + { + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint16_t id; + uint8_t tkl; + int r; + + /* Let the CoAP server parse the request and add/remove observers if needed */ + r = coap_resource_parse_observe(resource, request, addr); + + id = coap_header_get_id(request); + tkl = coap_header_get_token(request, token); + + return send_temperature(resource, addr, addr_len, r == 0 ? resource->age : 0, + id, token, tkl, true); + } + + static void temp_notify(struct coap_resource *resource, struct coap_observer *observer) + { + send_temperature(resource, &observer->addr, sizeof(observer->addr), resource->age, 0, + observer->token, observer->tkl, false); + } + + static const char * const temp_resource_path[] = { "sensors", "temp1", NULL }; + COAP_RESOURCE_DEFINE(temp_resource, my_service, { + .path = temp_resource_path, + .get = temp_get, + .notify = temp_notify, + .observer_event_handler = temp_observer_event, + }); + + static void notify_observers(struct k_work *work) + { + if (sys_slist_is_empty(&temp_resource.observers)) { + return; + } + + coap_resource_notify(&temp_resource); + k_work_reschedule(&temp_work, K_SECONDS(1)); + } + +CoRE Link Format +**************** + +The :kconfig:option:`CONFIG_COAP_SERVER_WELL_KNOWN_CORE` option enables handling the +``.well-known/core`` GET requests by the server. This allows clients to get a list of hypermedia +links to other resources hosted in that server. + +API Reference +************* + +.. doxygengroup:: coap_service diff --git a/doc/connectivity/networking/api/protocols.rst b/doc/connectivity/networking/api/protocols.rst index 8f2bc2af3d5..aea485b74aa 100644 --- a/doc/connectivity/networking/api/protocols.rst +++ b/doc/connectivity/networking/api/protocols.rst @@ -9,6 +9,7 @@ Protocols coap coap_client + coap_server http lwm2m mqtt From b81ce1f95747f6ad6239735a03da4d52a93fc507 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 8 Nov 2023 11:08:42 +0100 Subject: [PATCH 3322/4498] doc: connectivity: networking: api: Add subsystem link notes to CoAP The CoAP documentation has server/clients sample usages, added a note about the available subsystems that can be used instead. Signed-off-by: Pieter De Gendt --- doc/connectivity/networking/api/coap.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/networking/api/coap.rst b/doc/connectivity/networking/api/coap.rst index 4f0654a57d4..ffb794a0c8a 100644 --- a/doc/connectivity/networking/api/coap.rst +++ b/doc/connectivity/networking/api/coap.rst @@ -28,8 +28,6 @@ See :ref:`lwm2m_interface` for more information. Supported RFCs: -Supported RFCs: - - `RFC7252: The Constrained Application Protocol (CoAP) `_ - `RFC6690: Constrained RESTful Environments (CoRE) Link Format `_ - `RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP) `_ @@ -43,6 +41,11 @@ Sample Usage CoAP Server =========== +.. note:: + + A :ref:`coap_server_interface` subsystem is available, the following is for creating a custom + server implementation. + To create a CoAP server, resources for the server need to be defined. The ``.well-known/core`` resource should be added before all other resources that should be included in the responses of the ``.well-known/core`` @@ -97,6 +100,11 @@ with resource path like '/some_resource/+/#'. CoAP Client =========== +.. note:: + + A :ref:`coap_client_interface` subsystem is available, the following is for creating a custom + client implementation. + If the CoAP client knows about resources in the CoAP server, the client can start prepare CoAP requests and wait for responses. If the client doesn't know about resources in the CoAP server, it can request resources through From 98052aabb7bb3594ec0e48bfb3d424010810a448 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 8 Nov 2023 11:11:26 +0100 Subject: [PATCH 3323/4498] doc: releases: migration: Add CoAP API changes Add a note to the 3.6 migration guide about the CoAP API changes introduced with the CoAP server subsystem. Signed-off-by: Pieter De Gendt --- doc/releases/migration-guide-3.6.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index ca73ed0ae82..42a485d633e 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -76,6 +76,11 @@ Bluetooth Networking ========== +* The CoAP public API has some minor changes to take into account. The + :c:func:`coap_remove_observer` now returns a result if the observer was removed. This + change is used by the newly introduced :ref:`coap_server_interface` subsystem. Also, the + ``request`` argument for :c:func:`coap_well_known_core_get` is made ``const``. + Other Subsystems ================ From be0cb45e1abdcb02a6b83079696dff868c2f313b Mon Sep 17 00:00:00 2001 From: Ning Yang Date: Wed, 8 Nov 2023 13:54:28 +0800 Subject: [PATCH 3324/4498] drivers: dma: fix build warning issue for dma sedi driver Remove unused functions to avoid build warning check. Signed-off-by: Ning Yang --- drivers/dma/dma_sedi.c | 52 ------------------------------------------ 1 file changed, 52 deletions(-) diff --git a/drivers/dma/dma_sedi.c b/drivers/dma/dma_sedi.c index 96ae8bbf8fb..7c4ffa72e57 100644 --- a/drivers/dma/dma_sedi.c +++ b/drivers/dma/dma_sedi.c @@ -366,58 +366,6 @@ static int dma_sedi_init(const struct device *dev) return 0; } -#ifdef CONFIG_PM_DEVICE - -static bool is_dma_busy(sedi_dma_t dev) -{ - sedi_dma_status_t chn_status; - - for (int chn = 0; chn < DMA_CHANNEL_NUM; chn++) { - sedi_dma_get_status(dev, chn, &chn_status); - if (chn_status.busy == 1) { - return true; - } - } - return false; -} - -static int dma_change_device_power(const struct device *dev, - enum pm_device_action action) -{ - struct dma_sedi_driver_data *const data = DEV_DATA(dev); - const struct dma_sedi_config_info *const info = DEV_CFG(dev); - sedi_dma_t dma_dev = info->peripheral_id; - int ret; - - sedi_power_state_t state; - - switch (action) { - case PM_DEVICE_ACTION_RESUME: - state = SEDI_POWER_FULL; - break; - case PM_DEVICE_ACTION_SUSPEND: - if (is_dma_busy(dma_dev)) { - return -EBUSY; - } - state = SEDI_POWER_SUSPEND; - break; - - default: - return -ENOTSUP; - } - - for (uint8_t chn = 0; chn < DMA_CHANNEL_NUM; chn++) { - ret = sedi_dma_set_power(dma_dev, chn, state); - if (ret != SEDI_DRIVER_OK) { - return -EIO; - } - } - - return 0; -} - -#endif - #define DMA_DEVICE_INIT_SEDI(inst) \ static void dma_sedi_##inst##_irq_config(void); \ \ From 1f0b4c62a26983815442fb5bb5b952e6d08e8661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 7 Nov 2023 16:19:15 +0100 Subject: [PATCH 3325/4498] drivers: entropy: psa: Don't have PSA_CRYPTO_RNG depend on TF-M MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the depenency on TF-M so that this driver can be used when PSA is provided by something else than TF-M. Signed-off-by: Sebastian Bøe --- drivers/entropy/Kconfig.psa_crypto | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/entropy/Kconfig.psa_crypto b/drivers/entropy/Kconfig.psa_crypto index 50f31509004..d06001225b0 100644 --- a/drivers/entropy/Kconfig.psa_crypto +++ b/drivers/entropy/Kconfig.psa_crypto @@ -5,7 +5,6 @@ config ENTROPY_PSA_CRYPTO_RNG bool "PSA Crypto Random source Entropy driver" - depends on BUILD_WITH_TFM depends on DT_HAS_ZEPHYR_PSA_CRYPTO_RNG_ENABLED select ENTROPY_HAS_DRIVER default y From 702399080e94131c124d8c5428e6508e8c8d0bb1 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 8 Nov 2023 10:05:50 +0000 Subject: [PATCH 3326/4498] Kconfig: drop COMPAT_INCLUDES Last reference of this was dropped in 01b7800bc8, almost 2y ago. Signed-off-by: Fabio Baltieri --- Kconfig.zephyr | 11 ----------- doc/releases/release-notes-3.6.rst | 2 ++ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index b532dbc4435..c484898206b 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -921,14 +921,3 @@ config BOOTLOADER_BOSSA_ADAFRUIT_UF2 endchoice endmenu - -menu "Compatibility" - -config COMPAT_INCLUDES - bool "Suppress warnings when using header shims" - default y - help - Suppress any warnings from the pre-processor when including - deprecated header files. - -endmenu diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst index ea62b9cc977..3c1248222ee 100644 --- a/doc/releases/release-notes-3.6.rst +++ b/doc/releases/release-notes-3.6.rst @@ -110,6 +110,8 @@ Boards & SoC Support Build system and infrastructure ******************************* +- Dropped the ``COMPAT_INCLUDES`` option, it was unused since 3.0. + Drivers and Sensors ******************* From 56395ec42f59aa43667006b400903ee04c30f43c Mon Sep 17 00:00:00 2001 From: William MARTIN Date: Wed, 8 Nov 2023 14:19:08 +0100 Subject: [PATCH 3327/4498] dts: arm: st: Update stm32l496.dtsi Add missing master-can-reg into stm32l496.dtsi Signed-off-by: William MARTIN --- dts/arm/st/l4/stm32l496.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/arm/st/l4/stm32l496.dtsi b/dts/arm/st/l4/stm32l496.dtsi index 12d74f6859b..c11eba47796 100644 --- a/dts/arm/st/l4/stm32l496.dtsi +++ b/dts/arm/st/l4/stm32l496.dtsi @@ -54,6 +54,7 @@ interrupts = <86 0>, <87 0>, <88 0>, <89 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x04000000>; //RCC_APB1ENR1_CAN2EN + master-can-reg = <0x40006400>; status = "disabled"; sample-point = <875>; }; From 6af171d44b275b6c3df7b2d2daa6e6d7fc9242ea Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 8 Nov 2023 09:12:47 -0600 Subject: [PATCH 3328/4498] include: net_if: Fix IPV6 prefix struct doc desc IPv6 Prefix struct doc description is a copy paste error, fix Signed-off-by: Declan Snyder --- include/zephyr/net/net_if.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 82a1447b4f9..79fc2c79b31 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -106,7 +106,7 @@ struct net_if_mcast_addr { /** * @brief Network Interface IPv6 prefixes * - * Stores the multicast IP addresses assigned to this network interface. + * Stores the IPV6 prefixes assigned to this network interface. */ struct net_if_ipv6_prefix { /** Prefix lifetime */ From f409f67db4530e36b176d914e8d4ac7367118045 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Wed, 8 Nov 2023 16:15:09 +0100 Subject: [PATCH 3329/4498] tests: drivers: adc: move ad5592-adc node into native_posix.overlay Remove the `app.overlay` file which has been wrongly added in ad3c5a2 commit. Instead of that add the ad5592-adc node into `native_posix.overlay` file. Signed-off-by: Bartosz Bilas --- tests/drivers/build_all/adc/app.overlay | 50 ------------------- .../build_all/adc/boards/native_posix.overlay | 14 ++++++ 2 files changed, 14 insertions(+), 50 deletions(-) delete mode 100644 tests/drivers/build_all/adc/app.overlay diff --git a/tests/drivers/build_all/adc/app.overlay b/tests/drivers/build_all/adc/app.overlay deleted file mode 100644 index 82634f87df4..00000000000 --- a/tests/drivers/build_all/adc/app.overlay +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 Grinn - * - * SPDX-License-Identifier: Apache-2.0 - * - * Application overlay for testing driver builds - * - * Names in this file should be chosen in a way that won't conflict - * with real-world devicetree nodes, to allow these tests to run on - * (and be extended to test) real hardware. - */ - -/ { - test { - #address-cells = <1>; - #size-cells = <1>; - - test_gpio: gpio@deadbeef { - compatible = "vnd,gpio"; - gpio-controller; - reg = <0xdeadbeef 0x1000>; - #gpio-cells = <0x2>; - status = "okay"; - }; - - test_spi: spi@33334444 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "vnd,spi"; - reg = <0x33334444 0x1000>; - status = "okay"; - clock-frequency = <2000000>; - - cs-gpios = <&test_gpio 0 0>; - - test_spi_ad5592: ad5592@0 { - compatible = "adi,ad5592"; - status = "okay"; - reg = <0x0>; - spi-max-frequency = <0>; - reset-gpios = <&test_gpio 0 0>; - - ad5592_adc: adc-controller { - compatible = "adi,ad5592-adc"; - #io-channel-cells = <1>; - }; - }; - }; - }; -}; diff --git a/tests/drivers/build_all/adc/boards/native_posix.overlay b/tests/drivers/build_all/adc/boards/native_posix.overlay index 7f6f64243c8..5e787d8932f 100644 --- a/tests/drivers/build_all/adc/boards/native_posix.overlay +++ b/tests/drivers/build_all/adc/boards/native_posix.overlay @@ -118,6 +118,7 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, + <&test_gpio 0 0>, <&test_gpio 0 0>; test_spi_mcp3204: mcp3204@0 { @@ -305,6 +306,19 @@ spi-max-frequency = <0>; #io-channel-cells = <1>; }; + + test_spi_ad5592: ad5592@13 { + compatible = "adi,ad5592"; + status = "okay"; + reg = <0x13>; + spi-max-frequency = <0>; + reset-gpios = <&test_gpio 0 0>; + + ad5592_adc: adc-controller { + compatible = "adi,ad5592-adc"; + #io-channel-cells = <1>; + }; + }; }; }; }; From 00758b3e9a5f6c20d779ae82d47604cb005f5919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 8 Nov 2023 17:57:49 +0100 Subject: [PATCH 3330/4498] doc: gsg: macOS: Use menuselection role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Small tweak to use Sphinx `menuselection` role and make the menu output more readable. Signed-off-by: Benjamin Cabé --- doc/develop/getting_started/installation_mac.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/develop/getting_started/installation_mac.rst b/doc/develop/getting_started/installation_mac.rst index de7b3f861b3..a6043d37b4f 100644 --- a/doc/develop/getting_started/installation_mac.rst +++ b/doc/develop/getting_started/installation_mac.rst @@ -19,9 +19,9 @@ get around this issue you can take two different approaches: ``path/to/folder`` is the path to the enclosing folder where the executables you want to run are located. -* Open "System Preferences" -> "Security and Privacy" -> "Privacy" and then - scroll down to "Developer Tools". Then unlock the lock to be able to make - changes and check the checkbox corresponding to your terminal emulator of +* Open :menuselection:`System Preferences --> Security and Privacy --> Privacy` + and then scroll down to "Developer Tools". Then unlock the lock to be able to + make changes and check the checkbox corresponding to your terminal emulator of choice. This will apply to any executable being launched from such terminal program. From df6a9f2d309e1b0196cb782bcc0c17a903cbb488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 8 Nov 2023 19:34:33 +0100 Subject: [PATCH 3331/4498] doc: css: fix dark theme for gui roles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix dark theme issues with guilabel and menuselection roles. Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 8 ++++++++ doc/_static/css/dark.css | 3 +++ doc/_static/css/light.css | 3 +++ 3 files changed, 14 insertions(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index edd7f24629b..72756780b8e 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -582,6 +582,14 @@ kbd, .kbd, vertical-align: middle; } +/* guilabel and menuselection tweaks */ +.rst-content .guilabel, +.rst-content .menuselection { + color: var(--body-color); + background-color: var(--guiitems-background-color); + border-color: var(--guiitems-border-color); +} + /* Buttons */ .btn-neutral { diff --git a/doc/_static/css/dark.css b/doc/_static/css/dark.css index a577bd69d35..47d555242f6 100644 --- a/doc/_static/css/dark.css +++ b/doc/_static/css/dark.css @@ -87,6 +87,9 @@ --kbd-shadow-color: #1e2023; --kbd-text-color: #e2f2ff; + --guiitems-background-color: #303d4f; + --guiitems-border-color: #7fbbe3; + --btn-neutral-background-color: #404040; --btn-neutral-hover-background-color: #505050; --footer-color: #aaa; diff --git a/doc/_static/css/light.css b/doc/_static/css/light.css index 625516dce31..0389650278c 100644 --- a/doc/_static/css/light.css +++ b/doc/_static/css/light.css @@ -85,6 +85,9 @@ --kbd-shadow-color: #b0b7bf; --kbd-text-color: #444d56; + --guiitems-background-color: #e7f2fa; + --guiitems-border-color: #7fbbe3; + --btn-neutral-background-color: #f3f6f6; --btn-neutral-hover-background-color: #e5ebeb; --footer-color: #808080; From a39d2dc9d574299824c5be0359d74c678405923b Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 9 Nov 2023 01:50:14 +0700 Subject: [PATCH 3332/4498] drivers: nxp_s32: add missing soc.h inclusion Some NXP S32 shim drivers are using macros defined in soc/arm/nxp_s32/*/soc.h but not including soc.h. Those still can be built because the header file is included indirectly by some other header files. This is very fragile, it should be included directly Signed-off-by: Dat Nguyen Duy --- drivers/interrupt_controller/intc_eirq_nxp_s32.c | 1 + drivers/serial/uart_nxp_s32_linflexd.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/interrupt_controller/intc_eirq_nxp_s32.c b/drivers/interrupt_controller/intc_eirq_nxp_s32.c index 2dae70824ce..2526aecad4d 100644 --- a/drivers/interrupt_controller/intc_eirq_nxp_s32.c +++ b/drivers/interrupt_controller/intc_eirq_nxp_s32.c @@ -6,6 +6,7 @@ #define DT_DRV_COMPAT nxp_s32_siul2_eirq +#include #include #include #include diff --git a/drivers/serial/uart_nxp_s32_linflexd.c b/drivers/serial/uart_nxp_s32_linflexd.c index aeb8925da9f..9a8d8fe3790 100644 --- a/drivers/serial/uart_nxp_s32_linflexd.c +++ b/drivers/serial/uart_nxp_s32_linflexd.c @@ -6,6 +6,7 @@ #define DT_DRV_COMPAT nxp_s32_linflexd +#include #include #include #include From 0f07889bcd1409cd9a1b3a4faae075faf841b060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 15:44:39 +0100 Subject: [PATCH 3333/4498] doc: gh_utils: add docstring for get_page_prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation to the get_page_prefix method. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 4d2127756b4..313260a2968 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -51,6 +51,20 @@ def get_page_prefix(app: Sphinx, pagename: str) -> str: + """Return the prefix that needs to be added to the page path to get its location in the + repository. + + If pagename refers to a page that is automatically generated by Sphinx or if it matches one of + the patterns in ``gh_link_exclude`` configuration option, return None. + + Args: + app: Sphinx instance. + pagename: Page name (path). + + Returns: + Prefix if applicable, None otherwise. + """ + if not os.path.isfile(app.env.project.doc2path(pagename)): return None From cf52afb3fb9afe3a7dd125dbbeb61628cbf19f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 15:43:54 +0100 Subject: [PATCH 3334/4498] doc: gh_utils: Remove unnecessary ZEPHYR_BASE config option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compute ZEPHYR_BASE like other extensions do rather than artificially pretend it's a config option. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 313260a2968..0efc524e579 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -40,12 +40,13 @@ from datetime import datetime from pathlib import Path from textwrap import dedent -from typing import Optional, Tuple +from typing import Final, Optional, Tuple from urllib.parse import quote from sphinx.application import Sphinx from sphinx.util.i18n import format_date +ZEPHYR_BASE : Final[str] = Path(__file__).parents[3] __version__ = "0.1.0" @@ -162,7 +163,7 @@ def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: return None orig_path = os.path.join( - app.config.ZEPHYR_BASE, + ZEPHYR_BASE, page_prefix, app.env.project.doc2path(pagename, basedir=False), ) @@ -214,7 +215,6 @@ def add_jinja_filter(app: Sphinx): def setup(app: Sphinx): - app.add_config_value("ZEPHYR_BASE", Path(__file__).resolve().parents[3], "html") app.add_config_value("gh_link_version", "", "") app.add_config_value("gh_link_base_url", "", "") app.add_config_value("gh_link_prefixes", {}, "") From 61dd68a5ee3a5fa09c4ddd73ad41e56999bf0b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 11:33:36 +0100 Subject: [PATCH 3335/4498] doc: gh_utils: use doc2path method from BuildEnvironment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use BuildEnvironment to get the path of a document. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 0efc524e579..b79697e9241 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -66,7 +66,7 @@ def get_page_prefix(app: Sphinx, pagename: str) -> str: Prefix if applicable, None otherwise. """ - if not os.path.isfile(app.env.project.doc2path(pagename)): + if not os.path.isfile(app.env.doc2path(pagename)): return None for exclude in app.config.gh_link_exclude: @@ -104,7 +104,7 @@ def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[ mode, app.config.gh_link_version, page_prefix, - app.env.project.doc2path(pagename, basedir=False), + app.env.doc2path(pagename, False), ] ) @@ -121,7 +121,7 @@ def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optiona URL to open a new issue if applicable, None otherwise. """ - if not os.path.isfile(app.env.project.doc2path(pagename)): + if not os.path.isfile(app.env.doc2path(pagename)): return None title = quote(f"[doc] Documentation issue in '{pagename}'") @@ -165,7 +165,7 @@ def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: orig_path = os.path.join( ZEPHYR_BASE, page_prefix, - app.env.project.doc2path(pagename, basedir=False), + app.env.doc2path(pagename, False), ) try: From f6400f17cbfe5dfb12462ba400f4a3dd50e6b247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 12:06:45 +0100 Subject: [PATCH 3336/4498] doc: gh_utils: Fix incorrect condition for empty string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Page prefix can be an empty string. Fixed the condition so that it only evaluates to try when prefix is truly None. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index b79697e9241..ff5e0fa5b6d 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -95,7 +95,7 @@ def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[ """ page_prefix = get_page_prefix(app, pagename) - if not page_prefix: + if page_prefix is None: return None return "/".join( @@ -159,7 +159,7 @@ def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: """ page_prefix = get_page_prefix(app, pagename) - if not page_prefix: + if page_prefix is None: return None orig_path = os.path.join( From a3ed8f827f33fd6487f60291e7c2a592d989d647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 15:25:40 +0100 Subject: [PATCH 3337/4498] doc: gh_utils: Use "doc:" prefix in opened issue title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure why I used square brackets for "[doc]" prefix of the default Github issue title. Change it to "doc:". Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index ff5e0fa5b6d..019a37a7dfb 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -124,7 +124,7 @@ def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optiona if not os.path.isfile(app.env.doc2path(pagename)): return None - title = quote(f"[doc] Documentation issue in '{pagename}'") + title = quote(f"doc: Documentation issue in '{pagename}'") labels = quote("area: Documentation") body = quote( dedent( From 6cf694a2adcfaf26011a1edc45faab1daaed8533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 16:21:58 +0100 Subject: [PATCH 3338/4498] doc: gh_utils: Use MAINTAINERS file to add labels to opened issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use get_maintainer.py to add more meaningful labels to issues creates from a documentation page. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/gh_utils.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 019a37a7dfb..6ba75ce5ab7 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -37,6 +37,7 @@ import os import re import subprocess +import sys from datetime import datetime from pathlib import Path from textwrap import dedent @@ -47,6 +48,13 @@ from sphinx.util.i18n import format_date ZEPHYR_BASE : Final[str] = Path(__file__).parents[3] +SCRIPTS : Final[str] = ZEPHYR_BASE / "scripts" +sys.path.insert(0, str(SCRIPTS)) + +from get_maintainer import Maintainers + +MAINTAINERS : Final[Maintainers] = Maintainers() + __version__ = "0.1.0" @@ -121,11 +129,21 @@ def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optiona URL to open a new issue if applicable, None otherwise. """ - if not os.path.isfile(app.env.doc2path(pagename)): + page_prefix = get_page_prefix(app, pagename) + if page_prefix is None: return None + rel_path = os.path.join( + os.path.relpath(ZEPHYR_BASE), + page_prefix, + app.env.doc2path(pagename, False), + ) + title = quote(f"doc: Documentation issue in '{pagename}'") labels = quote("area: Documentation") + areas = MAINTAINERS.path2areas(rel_path) + if areas: + labels += "," + ",".join([label for area in areas for label in area.labels]) body = quote( dedent( f"""\ From 7d3381f9c8850dbd309c3ac0b3bf2327233cd07e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 3 Nov 2023 16:34:41 +0100 Subject: [PATCH 3339/4498] doc: Rename "report an issue" label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clarify the "Report an issue" label in HTML documentation. Signed-off-by: Benjamin Cabé --- doc/_templates/breadcrumbs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_templates/breadcrumbs.html b/doc/_templates/breadcrumbs.html index 4f974503da4..d1855e491fd 100644 --- a/doc/_templates/breadcrumbs.html +++ b/doc/_templates/breadcrumbs.html @@ -26,7 +26,7 @@ {%- set git_last_updated, sha1 = pagename | git_info | default((None, None), true) %} {%- if sha1 %} - {{ _('Report an issue')}} + {{ _('Report an issue with this page')}} {% endif %} {% endif %} From 4b0fa40c71e03c42569e0fe55ada13dc973b16c9 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 9 Nov 2023 16:30:26 +0800 Subject: [PATCH 3340/4498] doc: kconfig: remove duplicated devicetree function These devicetree function entries already existed in the doc since #21133. Signed-off-by: Yong Cong Sin --- doc/build/kconfig/preprocessor-functions.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/build/kconfig/preprocessor-functions.rst b/doc/build/kconfig/preprocessor-functions.rst index cb66658d2e4..2c94188c01c 100644 --- a/doc/build/kconfig/preprocessor-functions.rst +++ b/doc/build/kconfig/preprocessor-functions.rst @@ -29,10 +29,8 @@ while the ``*_hex`` version returns a hexadecimal value starting with ``0x``. .. code-block:: none $(dt_has_compat,) - $(dt_compat_enabled,) $(dt_compat_on_bus,,) $(dt_chosen_label,) - $(dt_chosen_enabled,) $(dt_chosen_path,) $(dt_chosen_has_compat,) $(dt_path_enabled,) From 30940418b3fbcf860c287c02a2b85c50227020af Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 9 Nov 2023 16:32:21 +0800 Subject: [PATCH 3341/4498] doc: kconfig: sort devicetree functions alphabetically Sort these entries alphabetically to make it easier to read. Signed-off-by: Yong Cong Sin --- doc/build/kconfig/preprocessor-functions.rst | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/doc/build/kconfig/preprocessor-functions.rst b/doc/build/kconfig/preprocessor-functions.rst index 2c94188c01c..ae3777444d8 100644 --- a/doc/build/kconfig/preprocessor-functions.rst +++ b/doc/build/kconfig/preprocessor-functions.rst @@ -28,43 +28,43 @@ while the ``*_hex`` version returns a hexadecimal value starting with ``0x``. .. code-block:: none - $(dt_has_compat,) - $(dt_compat_on_bus,,) + $(dt_alias_enabled,) + $(dt_chosen_bool_prop, , ) + $(dt_chosen_enabled,) + $(dt_chosen_has_compat,) $(dt_chosen_label,) $(dt_chosen_path,) - $(dt_chosen_has_compat,) - $(dt_path_enabled,) - $(dt_alias_enabled,) - $(dt_nodelabel_enabled,) - $(dt_nodelabel_enabled_with_compat,,) - $(dt_chosen_reg_addr_int,[,,]) $(dt_chosen_reg_addr_hex,[,,]) - $(dt_chosen_reg_size_int,[,,]) + $(dt_chosen_reg_addr_int,[,,]) $(dt_chosen_reg_size_hex,[,,]) - $(dt_node_reg_addr_int,[,,]) - $(dt_node_reg_addr_hex,[,,]) - $(dt_node_reg_size_int,[,,]) - $(dt_node_reg_size_hex,[,,]) - $(dt_nodelabel_reg_addr_int,[,,]) - $(dt_nodelabel_reg_addr_hex,[,,]) - $(dt_nodelabel_reg_size_int,[,,]) - $(dt_nodelabel_reg_size_hex,[,,]) + $(dt_chosen_reg_size_int,[,,]) $(dt_compat_enabled,) - $(dt_chosen_enabled,) + $(dt_compat_on_bus,,) + $(dt_gpio_hogs_enabled) + $(dt_has_compat,) $(dt_node_bool_prop,,) - $(dt_nodelabel_bool_prop,,) - $(dt_chosen_bool_prop, , ) + $(dt_node_has_compat,,) $(dt_node_has_prop,,) - $(dt_nodelabel_has_prop,,) - $(dt_node_int_prop_int,,[,]) $(dt_node_int_prop_hex,,[,]) + $(dt_node_int_prop_int,,[,]) + $(dt_node_parent,) + $(dt_node_reg_addr_hex,[,,]) + $(dt_node_reg_addr_int,[,,]) + $(dt_node_reg_size_hex,[,,]) + $(dt_node_reg_size_int,[,,]) $(dt_node_str_prop_equals,,,) + $(dt_nodelabel_array_prop_has_val, , , ) + $(dt_nodelabel_bool_prop,,) + $(dt_nodelabel_enabled,) + $(dt_nodelabel_enabled_with_compat,,) $(dt_nodelabel_has_compat,,) - $(dt_node_has_compat,,) + $(dt_nodelabel_has_prop,,) $(dt_nodelabel_path,) - $(dt_node_parent,) - $(dt_nodelabel_array_prop_has_val, , , ) - $(dt_gpio_hogs_enabled) + $(dt_nodelabel_reg_addr_hex,[,,]) + $(dt_nodelabel_reg_addr_int,[,,]) + $(dt_nodelabel_reg_size_hex,[,,]) + $(dt_nodelabel_reg_size_int,[,,]) + $(dt_path_enabled,) $(shields_list_contains,) From 47ce94527aed5d0c16a887cd3ac01a286eb45e1e Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 8 Nov 2023 14:19:54 -0600 Subject: [PATCH 3342/4498] doc: services: pm: fix function prototype for PM device support Function prototype in PM device implementation documentation had the incorrect prototype for device power management. Fix this to align with the correct prototype. Signed-off-by: Daniel DeGrasse --- doc/services/pm/device.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/services/pm/device.rst b/doc/services/pm/device.rst index 490102e78a4..3eb936942ea 100644 --- a/doc/services/pm/device.rst +++ b/doc/services/pm/device.rst @@ -146,7 +146,7 @@ support in a device driver. #define DT_DRV_COMPAT dummy_device static int dummy_driver_pm_action(const struct device *dev, - enum pm_device_action *action) + enum pm_device_action action) { switch (action) { case PM_DEVICE_ACTION_SUSPEND: From 45f664abf5421546ab0aa9119ba3e0d1637458e2 Mon Sep 17 00:00:00 2001 From: Mariano Goluboff Date: Wed, 8 Nov 2023 06:45:07 -0500 Subject: [PATCH 3343/4498] drivers: console: fix dropped characters when using debug hooks When using console debug server hooks, not all characters are processed if the server hook returns non-zero for one character while there are other characters in the buffer. This is seen when using a fast console (like USB) where multiple characters come in before the ISR is called. Fix it by continuing to process characters instead of returning from the ISR with characters still in the buffer. Fixes: #64661 Signed-off-by: Mariano Goluboff --- drivers/console/uart_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c index 378bbe91ff3..21df7fd3455 100644 --- a/drivers/console/uart_console.c +++ b/drivers/console/uart_console.c @@ -474,7 +474,7 @@ static void uart_console_isr(const struct device *unused, void *user_data) * The input hook indicates that no further processing * should be done by this handler. */ - return; + continue; } #endif From 488f56c0333f33942cd2b918eec8b6eafde9dc0a Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Mon, 6 Nov 2023 14:36:50 +0000 Subject: [PATCH 3344/4498] drivers: regulator: npm1300: soft start configuration Added configuration of soft start functionality Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_npm1300.c | 33 +++++++++++++++++++ .../regulator/nordic,npm1300-regulator.yaml | 10 ++++++ 2 files changed, 43 insertions(+) diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index b3a9d1aced9..fb193f1d39e 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -68,6 +68,11 @@ enum npm1300_gpio_type { #define LDSW1_ON_MASK 0x03U #define LDSW2_ON_MASK 0x0CU +#define LDSW1_SOFTSTART_MASK 0x0CU +#define LDSW1_SOFTSTART_SHIFT 2U +#define LDSW2_SOFTSTART_MASK 0x30U +#define LDSW2_SOFTSTART_SHIFT 4U + struct regulator_npm1300_pconfig { const struct device *mfd; struct gpio_dt_spec dvs_state_pins[5]; @@ -81,6 +86,7 @@ struct regulator_npm1300_config { struct gpio_dt_spec enable_gpios; struct gpio_dt_spec retention_gpios; struct gpio_dt_spec pwm_gpios; + uint8_t soft_start; }; struct regulator_npm1300_data { @@ -554,6 +560,24 @@ static int get_enabled(const struct device *dev, bool *enabled) } } +static int soft_start_set(const struct device *dev, uint8_t soft_start) +{ + const struct regulator_npm1300_config *config = dev->config; + + switch (config->source) { + case NPM1300_SOURCE_LDO1: + return mfd_npm1300_reg_update(config->mfd, LDSW_BASE, LDSW_OFFSET_CONFIG, + soft_start << LDSW1_SOFTSTART_SHIFT, + LDSW1_SOFTSTART_MASK); + case NPM1300_SOURCE_LDO2: + return mfd_npm1300_reg_update(config->mfd, LDSW_BASE, LDSW_OFFSET_CONFIG, + soft_start << LDSW2_SOFTSTART_SHIFT, + LDSW2_SOFTSTART_MASK); + default: + return -ENOTSUP; + } +} + int regulator_npm1300_init(const struct device *dev) { const struct regulator_npm1300_config *config = dev->config; @@ -582,6 +606,14 @@ int regulator_npm1300_init(const struct device *dev) } } + /* Configure soft start */ + if (config->soft_start != UINT8_MAX) { + ret = soft_start_set(dev, config->soft_start); + if (ret != 0) { + return ret; + } + } + /* Configure GPIO pin control */ ret = regulator_npm1300_set_pin_ctrl(dev, &config->enable_gpios, NPM1300_GPIO_TYPE_ENABLE); if (ret != 0) { @@ -618,6 +650,7 @@ static const struct regulator_driver_api api = {.enable = regulator_npm1300_enab .mfd = DEVICE_DT_GET(DT_GPARENT(node_id)), \ .source = _source, \ .retention_uv = DT_PROP_OR(node_id, retention_microvolt, 0), \ + .soft_start = DT_ENUM_IDX_OR(node_id, soft_start_microamp, UINT8_MAX), \ .enable_gpios = GPIO_DT_SPEC_GET_OR(node_id, enable_gpios, {0}), \ .retention_gpios = GPIO_DT_SPEC_GET_OR(node_id, retention_gpios, {0}), \ .pwm_gpios = GPIO_DT_SPEC_GET_OR(node_id, pwm_gpios, {0})}; \ diff --git a/dts/bindings/regulator/nordic,npm1300-regulator.yaml b/dts/bindings/regulator/nordic,npm1300-regulator.yaml index 987a3b522e1..cbd62671f15 100644 --- a/dts/bindings/regulator/nordic,npm1300-regulator.yaml +++ b/dts/bindings/regulator/nordic,npm1300-regulator.yaml @@ -83,3 +83,13 @@ child-binding: type: phandle-array description: | Retention mode controlled by specified regulator GPIO pin. + + soft-start-microamp: + type: int + enum: + - 10000 + - 20000 + - 35000 + - 50000 + description: | + Soft start current limit in microamps. From 0cbe0298cbfa4cc5f2db64a86b3d4830f3a4752e Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Wed, 8 Nov 2023 11:00:08 +0000 Subject: [PATCH 3345/4498] drivers: regulator: npm1300: Fixed LDSW GPIO control The load switch / LDO pin configuration function now correctly configures the associated GPIO pin. Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_npm1300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index fb193f1d39e..8adb2d3cb81 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -439,7 +439,7 @@ static int regulator_npm1300_set_ldsw_pin_ctrl(const struct device *dev, uint8_t ctrl = (pin + 1U) | (inv << 3U); - return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_GPISEL + chan, type); + return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_GPISEL + chan, ctrl); } int regulator_npm1300_set_pin_ctrl(const struct device *dev, const struct gpio_dt_spec *spec, From 35f326b82120708ae44a7360c9e95fa5e73022ad Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Wed, 8 Nov 2023 10:25:14 +0100 Subject: [PATCH 3346/4498] bluetooth: leaudio: Termination of PA at Modify Source From BASS spec: If the PA_Sync parameter value written by the client is set to a value of 0x00 (Do not synchronize to PA) and the server is synchronized to the PA, the server shall stop synchronization with the PA and shall write a value of 0x00 (Not synchronized to PA) to the PA_Sync_State field of the Broadcast Receive State characteristic . Fixes BASS/SR/CP/BV-12-C test case. Signed-off-by: Magdalena Kasenberg --- subsys/bluetooth/audio/bap_scan_delegator.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 79865fc382a..3cef96bd1b8 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -770,6 +770,20 @@ static int scan_delegator_mod_src(struct bt_conn *conn, return err; } + } else if (pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC && + (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ || + state->pa_sync_state == BT_BAP_PA_STATE_SYNCED)) { + /* Terminate PA sync */ + const int err = pa_sync_term_request(conn, &internal_state->state); + + if (err != 0) { + LOG_DBG("PA sync term from %p was reject with reason %d", + conn, err); + + return err; + } + + state_changed = true; } /* Notify if changed */ From 2938856cac67b574f556ddb966ec060ac825befb Mon Sep 17 00:00:00 2001 From: Dong Wang Date: Mon, 6 Nov 2023 20:47:01 +0800 Subject: [PATCH 3347/4498] west.yml: update hal_intel to latest It contains changes from ISH code base: - Switch IPC/SPI SEDI drivers to use OSXML header files. - Enhance SEDI debug functions. - I2C and SPI drivers' bug fix and enhancements. Signed-off-by: Dong Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 6b4391cb380..17fe8066384 100644 --- a/west.yml +++ b/west.yml @@ -173,7 +173,7 @@ manifest: groups: - hal - name: hal_intel - revision: 11feb65898253ac6f715bf12bd04b869e4c1d577 + revision: 7b4c25669f1513b0d6d6ee78ee42340d91958884 path: modules/hal/intel groups: - hal From abc334016f2f236560a6b83ba3e1846870a8f66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 6 Nov 2023 12:39:57 +0100 Subject: [PATCH 3348/4498] doc: pdf: Use single column for the index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The index at the end of the PDF document can contain pretty long strings that don't fit in the default 2-column layout. This commit makes the index use a single-column. Note: this relies on LaTeX package idxlayout which should already be included in the packages recommended for installation in our instructions. Signed-off-by: Benjamin Cabé --- doc/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/conf.py b/doc/conf.py index 0f20f424f80..85488318a0a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -184,6 +184,7 @@ "papersize": "a4paper", "maketitle": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read(), "preamble": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read(), + "makeindex": r"\usepackage[columns=1]{idxlayout}\makeindex", "fontpkg": textwrap.dedent(r""" \usepackage{noto} \usepackage{inconsolata-nerd-font} From 2b98b6710959de1bf20dc8d2a1fa4b4557ba3283 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Thu, 26 Oct 2023 13:47:02 +0530 Subject: [PATCH 3349/4498] dt-bindings: i2c: Add gpio-i2c-switch Generic GPIO enabled analog switch to isolate devices from an I2C bus Signed-off-by: Vaishnav Achath Signed-off-by: Ayush Singh --- dts/bindings/i2c/gpio-i2c-switch.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 dts/bindings/i2c/gpio-i2c-switch.yaml diff --git a/dts/bindings/i2c/gpio-i2c-switch.yaml b/dts/bindings/i2c/gpio-i2c-switch.yaml new file mode 100644 index 00000000000..ebd932afc71 --- /dev/null +++ b/dts/bindings/i2c/gpio-i2c-switch.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2023, Ayush Singh +# Copyright (c) 2021, Jason Kridner, BeagleBoard.org Foundation +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO enabled analog switch to isolate devices from an I2C bus + +compatible: "gpio-i2c-switch" + +include: i2c-controller.yaml + +properties: + "#address-cells": + required: true + const: 1 + "#size-cells": + required: true + const: 0 + controller: + type: phandle + required: true + gpios: + type: phandle-array + required: true From dfe1c3a32bdd0e6d01259501d83a4eb91eedcc3e Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 1 Nov 2023 18:32:05 +0530 Subject: [PATCH 3350/4498] drivers: i2c: add gpio_i2c_switch Add drivers for gpio_i2c_switch which is present in beagleconnect freedom Signed-off-by: Vaishnav Achath Signed-off-by: Ayush Singh --- .../arm/beagle_bcf/beagleconnect_freedom.dts | 2 +- drivers/i2c/CMakeLists.txt | 1 + drivers/i2c/Kconfig | 7 ++ drivers/i2c/gpio_i2c_switch.c | 95 +++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 drivers/i2c/gpio_i2c_switch.c diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom.dts b/boards/arm/beagle_bcf/beagleconnect_freedom.dts index 7300e9de5db..7fd8341e89b 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom.dts +++ b/boards/arm/beagle_bcf/beagleconnect_freedom.dts @@ -59,7 +59,7 @@ sens_i2c: sensor-switch { status = "okay"; - compatible = "ti,ts5a2066"; + compatible = "gpio-i2c-switch"; #address-cells = <1>; #size-cells = <0>; controller = <&i2c0>; diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt index 20ea5c0cb1e..f7f363ed8d4 100644 --- a/drivers/i2c/CMakeLists.txt +++ b/drivers/i2c/CMakeLists.txt @@ -54,6 +54,7 @@ zephyr_library_sources_ifdef(CONFIG_I2C_XILINX_AXI i2c_xilinx_axi.c) zephyr_library_sources_ifdef(CONFIG_I2C_MCHP_MSS i2c_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_I2C_SEDI i2c_sedi.c) zephyr_library_sources_ifdef(CONFIG_I2C_AMBIQ i2c_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_I2C_SWITCH gpio_i2c_switch.c) zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V1 i2c_ll_stm32_v1.c diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 5f62fbb4eb1..2523877c851 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -195,4 +195,11 @@ config I2C_RV32M1_LPI2C help Enable the RV32M1 LPI2C driver. +config GPIO_I2C_SWITCH + bool "GPIO controlled I2C bus switch" + default y + depends on DT_HAS_GPIO_I2C_SWITCH_ENABLED + help + Enable GPIO controlled I2C bus switch driver. + endif # I2C diff --git a/drivers/i2c/gpio_i2c_switch.c b/drivers/i2c/gpio_i2c_switch.c new file mode 100644 index 00000000000..938ed11d769 --- /dev/null +++ b/drivers/i2c/gpio_i2c_switch.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Ayush Singh + * Copyright (c) 2021 Jason Kridner, BeagleBoard.org Foundation + * Copyright (c) 2020 Innoseis BV + * + * Based on i2c_tca9656a.c + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT gpio_i2c_switch + +#define GPIO_I2C_TOGGLE_DELAY_US 1 +#define GPIO_I2C_LOCK_TIMEOUT_US (GPIO_I2C_TOGGLE_DELAY_US * 2 + 100) + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(gpio_i2c_switch, CONFIG_I2C_LOG_LEVEL); + +struct gpio_i2c_switch_config { + const struct device *bus; + const struct gpio_dt_spec gpio; +}; + +struct gpio_i2c_switch_data { + struct k_mutex lock; +}; + +static int gpio_i2c_switch_configure(const struct device *dev, uint32_t dev_config) +{ + const struct gpio_i2c_switch_config *config = dev->config; + + return i2c_configure(config->bus, dev_config); +} + +static int gpio_i2c_switch_transfer(const struct device *dev, struct i2c_msg *msgs, + uint8_t num_msgs, uint16_t addr) +{ + int res; + struct gpio_i2c_switch_data *data = dev->data; + const struct gpio_i2c_switch_config *config = dev->config; + + res = k_mutex_lock(&data->lock, K_USEC(GPIO_I2C_LOCK_TIMEOUT_US)); + if (res != 0) { + return res; + } + + /* enable switch */ + gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_HIGH); + k_busy_wait(GPIO_I2C_TOGGLE_DELAY_US); + + res = i2c_transfer(config->bus, msgs, num_msgs, addr); + + /* disable switch */ + gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_LOW); + k_busy_wait(GPIO_I2C_TOGGLE_DELAY_US); + k_mutex_unlock(&data->lock); + + return res; +} + +const struct i2c_driver_api gpio_i2c_switch_api_funcs = { + .configure = gpio_i2c_switch_configure, + .transfer = gpio_i2c_switch_transfer, +}; + +static int gpio_i2c_switch_init(const struct device *dev) +{ + const struct gpio_i2c_switch_config *config = dev->config; + struct gpio_i2c_switch_data *data = dev->data; + + k_mutex_init(&data->lock); + + return gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_LOW); +} + +#define DEFINE_GPIO_I2C_SWITCH(inst) \ + \ + static struct gpio_i2c_switch_data gpio_i2c_switch_dev_data_##inst; \ + \ + static const struct gpio_i2c_switch_config gpio_i2c_switch_dev_cfg_##inst = { \ + .bus = DEVICE_DT_GET(DT_PHANDLE(DT_DRV_INST(inst), controller)), \ + .gpio = GPIO_DT_SPEC_GET(DT_DRV_INST(inst), gpios), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, gpio_i2c_switch_init, device_pm_control_nop, \ + &gpio_i2c_switch_dev_data_##inst, &gpio_i2c_switch_dev_cfg_##inst, \ + POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, &gpio_i2c_switch_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_GPIO_I2C_SWITCH) From c5d3fc10c1917624b589cee33d52f5f4ee2f46ce Mon Sep 17 00:00:00 2001 From: Ting Shen Date: Fri, 27 Oct 2023 15:08:24 +0800 Subject: [PATCH 3351/4498] drivers: usb_dc_it82xx2: fix uninitialized variable warning ep_ctrl and ep_trans_type is not used inside it82xx2_usb_dc_isr, this triggers a compile warning. Move these variables to a smaller scope. Signed-off-by: Ting Shen --- drivers/usb/device/usb_dc_it82xx2.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/usb/device/usb_dc_it82xx2.c b/drivers/usb/device/usb_dc_it82xx2.c index f67db012e1d..b5307252325 100644 --- a/drivers/usb/device/usb_dc_it82xx2.c +++ b/drivers/usb/device/usb_dc_it82xx2.c @@ -719,7 +719,7 @@ static void it82xx2_ep_in_out_config(uint8_t idx) } } -static void it82xx2_usb_dc_trans_done(uint8_t ep_ctrl, uint8_t ep_trans_type) +static void it82xx2_usb_dc_trans_done(void) { struct usb_it82xx2_regs *const usb_regs = (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); @@ -730,12 +730,12 @@ static void it82xx2_usb_dc_trans_done(uint8_t ep_ctrl, uint8_t ep_trans_type) int ret; for (uint8_t idx = 0 ; idx < EP4 ; idx++) { - ep_ctrl = ep_regs[idx].ep_ctrl; + uint8_t ep_ctrl = ep_regs[idx].ep_ctrl; /* check ready bit ,will be 0 when trans done */ if ((ep_ctrl & ENDPOINT_EN) && !(ep_ctrl & ENDPOINT_RDY)) { if (idx == EP0) { - ep_trans_type = ep_regs[idx].ep_transtype_sts & + uint8_t ep_trans_type = ep_regs[idx].ep_transtype_sts & DC_ALL_TRANS; /* set up*/ @@ -785,7 +785,6 @@ static void it82xx2_usb_dc_isr(void) uint8_t status = usb_regs->dc_interrupt_status & usb_regs->dc_interrupt_mask; /* mask non enable int */ - uint8_t ep_ctrl, ep_trans_type; /* reset */ if (status & DC_RESET_EVENT) { @@ -813,7 +812,7 @@ static void it82xx2_usb_dc_isr(void) if (status & DC_TRANS_DONE) { /* clear interrupt before new transaction */ usb_regs->dc_interrupt_status = DC_TRANS_DONE; - it82xx2_usb_dc_trans_done(ep_ctrl, ep_trans_type); + it82xx2_usb_dc_trans_done(); return; } From 345f079e49598d2dcab17215aaef965073cc613f Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Mon, 16 Oct 2023 16:55:09 -0500 Subject: [PATCH 3352/4498] dts: bindings: Fix NXP USB bindings NXP USB bindings were combined into one binding and using a property corresponding to HAL enums which is improper use of devicetree. Signed-off-by: Declan Snyder --- drivers/usb/device/Kconfig | 2 +- drivers/usb/device/usb_dc_mcux.c | 36 ++++++++++++++++++++++--- dts/arm/nxp/nxp_lpc55S1x_common.dtsi | 3 +-- dts/arm/nxp/nxp_lpc55S2x_common.dtsi | 3 +-- dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 3 +-- dts/arm/nxp/nxp_lpc55S6x_common.dtsi | 6 ++--- dts/arm/nxp/nxp_rt1010.dtsi | 3 +-- dts/arm/nxp/nxp_rt10xx.dtsi | 6 ++--- dts/arm/nxp/nxp_rt11xx.dtsi | 6 ++--- dts/arm/nxp/nxp_rt5xx_common.dtsi | 3 +-- dts/arm/nxp/nxp_rt6xx_common.dtsi | 3 +-- dts/bindings/usb/nxp,ehci.yaml | 8 ++++++ dts/bindings/usb/nxp,lpcip3511.yaml | 8 ++++++ dts/bindings/usb/nxp,mcux-usbd.yaml | 23 ---------------- modules/hal_nxp/usb/usb_device_config.h | 10 ++++++- soc/arm/nxp_lpc/lpc55xxx/soc.c | 4 +-- 16 files changed, 73 insertions(+), 54 deletions(-) create mode 100644 dts/bindings/usb/nxp,ehci.yaml create mode 100644 dts/bindings/usb/nxp,lpcip3511.yaml diff --git a/drivers/usb/device/Kconfig b/drivers/usb/device/Kconfig index 41d3d446f8d..91db896eede 100644 --- a/drivers/usb/device/Kconfig +++ b/drivers/usb/device/Kconfig @@ -147,7 +147,7 @@ config USB_KINETIS config USB_MCUX bool "NXP MCUX USB Device Controller Driver" default y - depends on DT_HAS_NXP_MCUX_USBD_ENABLED + depends on DT_HAS_NXP_EHCI_ENABLED || DT_HAS_NXP_LPCIP3511_ENABLED help NXP MCUX USB Device Controller Driver for MXRT and LPC SoC's. diff --git a/drivers/usb/device/usb_dc_mcux.c b/drivers/usb/device/usb_dc_mcux.c index 7278d25d728..0667486b628 100644 --- a/drivers/usb/device/usb_dc_mcux.c +++ b/drivers/usb/device/usb_dc_mcux.c @@ -5,8 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_mcux_usbd - #include #include #include @@ -21,15 +19,20 @@ #include "usb_device_dci.h" #ifdef CONFIG_USB_DC_NXP_EHCI +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_ehci #include "usb_device_ehci.h" #endif #ifdef CONFIG_USB_DC_NXP_LPCIP3511 +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_lpcip3511 #include "usb_device_lpcip3511.h" #endif #ifdef CONFIG_HAS_MCUX_CACHE #include #endif + #define LOG_LEVEL CONFIG_USB_DRIVER_LOG_LEVEL #include #include @@ -68,7 +71,34 @@ static void usb_isr_handler(void); #define EP_ABS_IDX(ep) (USB_EP_GET_IDX(ep) * 2 + \ (USB_EP_GET_DIR(ep) >> 7)) #define NUM_OF_EP_MAX (DT_INST_PROP(0, num_bidir_endpoints) * 2) -#define CONTROLLER_ID (DT_INST_ENUM_IDX(0, usb_controller_index)) + +#define NUM_INSTS DT_NUM_INST_STATUS_OKAY(nxp_ehci) + DT_NUM_INST_STATUS_OKAY(nxp_lpcip3511) +BUILD_ASSERT(NUM_INSTS <= 1, "Only one USB device supported"); + +/* Controller ID is for HAL usage */ +#if defined(CONFIG_SOC_SERIES_IMX_RT5XX) || \ + defined(CONFIG_SOC_SERIES_IMX_RT6XX) || \ + defined(CONFIG_SOC_LPC55S28) || \ + defined(CONFIG_SOC_LPC55S16) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0 +#elif defined(CONFIG_SOC_LPC55S36) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0 +#elif defined(CONFIG_SOC_LPC55S69_CPU0) || defined(CONFIG_SOC_LPC55S69_CPU1) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(usbhs), okay) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0 +#elif DT_NODE_HAS_STATUS(DT_NODELABEL(usbfs), okay) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0 +#endif /* LPC55s69 */ +#elif defined(CONFIG_SOC_SERIES_IMX_RT) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(usb1), okay) +#define CONTROLLER_ID kUSB_ControllerEhci0 +#elif DT_NODE_HAS_STATUS(DT_NODELABEL(usb2), okay) +#define CONTROLLER_ID kUSB_ControllerEhci1 +#endif /* IMX RT */ +#else +/* If SOC has EHCI or LPCIP3511 then probably just need to add controller ID to this code */ +#error "USB driver does not yet support this SOC" +#endif /* CONTROLLER ID */ /* We do not need a buffer for the write side on platforms that have USB RAM. * The SDK driver will copy the data buffer to be sent to USB RAM. diff --git a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi index 9e4ee4841db..76d551555ef 100644 --- a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi @@ -240,11 +240,10 @@ }; usbhs: usbhs@144000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x94000 0x1000>; interrupts = <47 1>; num-bidir-endpoints = <6>; - usb-controller-index = "LpcIp3511Hs0"; status = "disabled"; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi index c429a4bd4ef..16d9c1312c3 100644 --- a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi @@ -284,11 +284,10 @@ }; usbhs: usbhs@144000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x94000 0x1000>; interrupts = <47 1>; num-bidir-endpoints = <6>; - usb-controller-index = "LpcIp3511Hs0"; status = "disabled"; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index 381a0b07391..dd011ece96d 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -443,12 +443,11 @@ }; usbfs: usbfs@84000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x84000 0x1000>; interrupts = <28 0>; num-bidir-endpoints = <5>; maximum-speed = "full-speed"; - usb-controller-index = "LpcIp3511Fs0"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi index c7c7d238dc7..411f8ac8f5f 100644 --- a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi @@ -325,21 +325,19 @@ }; usbfs: usbfs@84000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x84000 0x1000>; interrupts = <28 1>; num-bidir-endpoints = <5>; maximum-speed = "full-speed"; - usb-controller-index = "LpcIp3511Fs0"; status = "disabled"; }; usbhs: usbhs@94000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x94000 0x1000>; interrupts = <47 1>; num-bidir-endpoints = <6>; - usb-controller-index = "LpcIp3511Hs0"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt1010.dtsi b/dts/arm/nxp/nxp_rt1010.dtsi index cdd132b59df..1afed91a45c 100644 --- a/dts/arm/nxp/nxp_rt1010.dtsi +++ b/dts/arm/nxp/nxp_rt1010.dtsi @@ -234,13 +234,12 @@ /* Fixup USB it has different base addr and interrupt numbers on RT1010 */ /delete-node/ usbd@402e0000; usb1: usbd@400e4000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,ehci"; reg = <0x400e4000 0x200>; interrupts = <25 1>; interrupt-names = "usb_otg"; clocks = <&usbclk>; num-bidir-endpoints = <8>; - usb-controller-index = "Ehci0"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index d6c247ba651..23bd7255301 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -790,24 +790,22 @@ }; usb1: usbd@402e0000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,ehci"; reg = <0x402E0000 0x200>; interrupts = <113 1>; interrupt-names = "usb_otg"; clocks = <&usbclk>; num-bidir-endpoints = <8>; - usb-controller-index = "Ehci0"; status = "disabled"; }; usb2: usbd@402e0200 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,ehci"; reg = <0x402E0200 0x200>; interrupts = <112 1>; interrupt-names = "usb_otg"; clocks = <&usbclk>; num-bidir-endpoints = <8>; - usb-controller-index = "Ehci1"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index faf4b9cae7b..eb14d37f834 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -749,24 +749,22 @@ }; usb1: usbd@40430000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,ehci"; reg = <0x40430000 0x200>; interrupts = <136 1>; interrupt-names = "usb_otg"; clocks = <&xtal>; num-bidir-endpoints = <8>; - usb-controller-index = "Ehci0"; status = "disabled"; }; usb2: usbd@4042c000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,ehci"; reg = <0x4042c000 0x200>; interrupts = <135 1>; interrupt-names = "usb_otg"; clocks = <&xtal>; num-bidir-endpoints = <8>; - usb-controller-index = "Ehci1"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 9165b26441e..3f5319a7401 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -338,11 +338,10 @@ }; usbhs: usbhs@144000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x144000 0x1000>; interrupts = <50 1>; num-bidir-endpoints = <6>; - usb-controller-index = "LpcIp3511Hs0"; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index 843c1739cd2..e4acafbafa5 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -259,11 +259,10 @@ }; usbhs: usbhs@144000 { - compatible = "nxp,mcux-usbd"; + compatible = "nxp,lpcip3511"; reg = <0x144000 0x1000>; interrupts = <50 1>; num-bidir-endpoints = <6>; - usb-controller-index = "LpcIp3511Hs0"; status = "disabled"; }; diff --git a/dts/bindings/usb/nxp,ehci.yaml b/dts/bindings/usb/nxp,ehci.yaml new file mode 100644 index 00000000000..cf72a69545c --- /dev/null +++ b/dts/bindings/usb/nxp,ehci.yaml @@ -0,0 +1,8 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP EHCI USB device mode + +compatible: nxp,ehci + +include: "nxp,mcux-usbd.yaml" diff --git a/dts/bindings/usb/nxp,lpcip3511.yaml b/dts/bindings/usb/nxp,lpcip3511.yaml new file mode 100644 index 00000000000..70ea1188837 --- /dev/null +++ b/dts/bindings/usb/nxp,lpcip3511.yaml @@ -0,0 +1,8 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP LPCIP3511 USB device mode + +compatible: nxp,lpcip3511 + +include: "nxp,mcux-usbd.yaml" diff --git a/dts/bindings/usb/nxp,mcux-usbd.yaml b/dts/bindings/usb/nxp,mcux-usbd.yaml index 389f43e1da0..af0dd762137 100644 --- a/dts/bindings/usb/nxp,mcux-usbd.yaml +++ b/dts/bindings/usb/nxp,mcux-usbd.yaml @@ -4,8 +4,6 @@ description: | NPX MXRT and LPC USBOTG Controller in device mode -compatible: "nxp,mcux-usbd" - include: [usb-ep.yaml, pinctrl-device.yaml] properties: @@ -14,24 +12,3 @@ properties: interrupts: required: true - - usb-controller-index: - required: true - type: string - description: | - This is taken from the usb_controller_index_t enum that is included inside the NXP SDK - enum: - - "Khci0" - - "Khci1" - - "Ehci0" - - "Ehci1" - - "LpcIp3511Fs0" - - "LpcIp3511Fs1" - - "LpcIp3511Hs0" - - "LpcIp3511Hs1" - - "Ohci0" - - "Ohci1" - - "Ip3516Hs0" - - "Ip3516Hs1" - - "Dwc30" - - "Dwc31" diff --git a/modules/hal_nxp/usb/usb_device_config.h b/modules/hal_nxp/usb/usb_device_config.h index ca2bc5d9373..31a62ffbfeb 100644 --- a/modules/hal_nxp/usb/usb_device_config.h +++ b/modules/hal_nxp/usb/usb_device_config.h @@ -39,7 +39,15 @@ /* Whether device is self power. 1U supported, 0U not supported */ #define USB_DEVICE_CONFIG_SELF_POWER (1U) -#define DT_DRV_COMPAT nxp_mcux_usbd +#define NUM_INSTS DT_NUM_INST_STATUS_OKAY(nxp_ehci) + DT_NUM_INST_STATUS_OKAY(nxp_lpcip3511) +BUILD_ASSERT(NUM_INSTS <= 1, "Only one USB device supported"); +#if DT_HAS_COMPAT_STATUS_OKAY(nxp_lpcip3511) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_lpcip3511 +#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_ehci) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_ehci +#endif /* Number of endpoints supported */ #define USB_DEVICE_CONFIG_ENDPOINTS (DT_INST_PROP(0, num_bidir_endpoints)) diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 8084be53384..e3620782acb 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -217,7 +217,7 @@ static ALWAYS_INLINE void clock_init(void) #if CONFIG_USB_DC_NXP_LPCIP3511 -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbfs), nxp_mcux_usbd, okay) +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbfs), nxp_lpcip3511, okay) /*< Turn on USB Phy */ #if defined(CONFIG_SOC_LPC55S36) POWER_DisablePD(kPDRUNCFG_PD_USBFSPHY); @@ -248,7 +248,7 @@ static ALWAYS_INLINE void clock_init(void) #endif /* USB_DEVICE_TYPE_FS */ -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbhs), nxp_mcux_usbd, okay) +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbhs), nxp_lpcip3511, okay) /* enable usb1 host clock */ CLOCK_EnableClock(kCLOCK_Usbh1); /* Put PHY powerdown under software control */ From 1cef7f3250efef663b0f0ce33b7b4768ee97c1b9 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 8 Aug 2023 13:00:30 +0200 Subject: [PATCH 3353/4498] driver: eth: Implementation of Open Alliance's TC6 T1S communication Those files provide generic functions to handle transmission between chip conforming OA TC6 standard and Zephyr's network stack represented by struct net_pkt. The communication is performed via SPI and is focused on reduced memory footprint (works with SOC equipped with 32 KiB of RAM) and robustness of operation. Signed-off-by: Lukasz Majewski --- CODEOWNERS | 1 + drivers/ethernet/oa_tc6.c | 393 ++++++++++++++++++++++++++++++++++++++ drivers/ethernet/oa_tc6.h | 233 ++++++++++++++++++++++ 3 files changed, 627 insertions(+) create mode 100644 drivers/ethernet/oa_tc6.c create mode 100644 drivers/ethernet/oa_tc6.h diff --git a/CODEOWNERS b/CODEOWNERS index f339c8958fe..f3d2bb732c9 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -305,6 +305,7 @@ /drivers/ethernet/*xlnx_gem* @ibirnbaum /drivers/ethernet/*smsc91x* @sgrrzhf /drivers/ethernet/*adin2111* @GeorgeCGV +/drivers/ethernet/*oa_tc6* @lmajewski /drivers/ethernet/phy/ @rlubos @tbursztyka @arvinf @jukkar /drivers/ethernet/phy/*adin2111* @GeorgeCGV /drivers/mdio/ @rlubos @tbursztyka @arvinf diff --git a/drivers/ethernet/oa_tc6.c b/drivers/ethernet/oa_tc6.c new file mode 100644 index 00000000000..0fa1f105581 --- /dev/null +++ b/drivers/ethernet/oa_tc6.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "oa_tc6.h" + +#include +LOG_MODULE_REGISTER(oa_tc6, CONFIG_ETHERNET_LOG_LEVEL); + +int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val) +{ + uint8_t buf[OA_TC6_HDR_SIZE + 12] = { 0 }; + struct spi_buf tx_buf = { .buf = buf, .len = sizeof(buf) }; + const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; + struct spi_buf rx_buf = { .buf = buf, .len = sizeof(buf) }; + const struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 }; + uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *) &buf[0]; + int ret = 0; + + /* + * Buffers are allocated for protected (larger) case (by 4 bytes). + * When non-protected case - we need to decrase them + */ + if (!tc6->protected) { + tx_buf.len -= sizeof(rvn); + rx_buf.len -= sizeof(rvn); + } + + *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | + FIELD_PREP(OA_CTRL_HDR_WNR, 0) | + FIELD_PREP(OA_CTRL_HDR_AID, 0) | + FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | + FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | + FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ + *hdr |= FIELD_PREP(OA_CTRL_HDR_P, oa_tc6_get_parity(*hdr)); + hdr_bkp = *hdr; + *hdr = sys_cpu_to_be32(*hdr); + + ret = spi_transceive_dt(tc6->spi, &tx, &rx); + if (ret < 0) { + return ret; + } + + /* Check if echoed control command header is correct */ + rv = sys_be32_to_cpu(*(uint32_t *)&buf[4]); + if (hdr_bkp != rv) { + LOG_ERR("Header transmission error!"); + return -1; + } + + rv = sys_be32_to_cpu(*(uint32_t *)&buf[8]); + + /* In protected mode read data is followed by its compliment value */ + if (tc6->protected) { + rvn = sys_be32_to_cpu(*(uint32_t *)&buf[12]); + if (rv != ~rvn) { + LOG_ERR("Protected mode transmission error!"); + return -1; + } + } + + *val = rv; + + return ret; +} + +int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val) +{ + uint8_t buf_tx[OA_TC6_HDR_SIZE + 12] = { 0 }; + uint8_t buf_rx[OA_TC6_HDR_SIZE + 12] = { 0 }; + struct spi_buf tx_buf = { .buf = buf_tx, .len = sizeof(buf_tx) }; + const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; + struct spi_buf rx_buf = { .buf = buf_rx, .len = sizeof(buf_rx) }; + const struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 }; + uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *) &buf_tx[0]; + int ret; + + /* + * Buffers are allocated for protected (larger) case (by 4 bytes). + * When non-protected case - we need to decrase them + */ + if (!tc6->protected) { + tx_buf.len -= sizeof(rvn); + rx_buf.len -= sizeof(rvn); + } + + *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | + FIELD_PREP(OA_CTRL_HDR_WNR, 1) | + FIELD_PREP(OA_CTRL_HDR_AID, 0) | + FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | + FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | + FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ + *hdr |= FIELD_PREP(OA_CTRL_HDR_P, oa_tc6_get_parity(*hdr)); + hdr_bkp = *hdr; + *hdr = sys_cpu_to_be32(*hdr); + + *(uint32_t *)&buf_tx[4] = sys_cpu_to_be32(val); + if (tc6->protected) { + *(uint32_t *)&buf_tx[8] = sys_be32_to_cpu(~val); + } + + ret = spi_transceive_dt(tc6->spi, &tx, &rx); + if (ret < 0) { + return ret; + } + + /* Check if echoed control command header is correct */ + rv = sys_be32_to_cpu(*(uint32_t *)&buf_rx[4]); + if (hdr_bkp != rv) { + LOG_ERR("Header transmission error!"); + return -1; + } + + /* Check if echoed value is correct */ + rv = sys_be32_to_cpu(*(uint32_t *)&buf_rx[8]); + if (val != rv) { + LOG_ERR("Header transmission error!"); + return -1; + } + + /* + * In protected mode check if read value is followed by its + * compliment value + */ + if (tc6->protected) { + rvn = sys_be32_to_cpu(*(uint32_t *)&buf_rx[12]); + if (val != ~rvn) { + LOG_ERR("Protected mode transmission error!"); + return -1; + } + } + + return ret; +} + +int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote) +{ + uint32_t val; + int ret; + + ret = oa_tc6_reg_read(tc6, OA_CONFIG0, &val); + if (ret < 0) { + return ret; + } + + if (prote) { + val |= OA_CONFIG0_PROTE; + } else { + val &= ~OA_CONFIG0_PROTE; + } + + ret = oa_tc6_reg_write(tc6, OA_CONFIG0, val); + if (ret < 0) { + return ret; + } + + tc6->protected = prote; + return 0; +} + +int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt) +{ + uint16_t len = net_pkt_get_len(pkt); + uint8_t oa_tx[tc6->cps]; + uint32_t hdr, ftr; + uint8_t chunks, i; + int ret; + + chunks = (len / tc6->cps) + 1; + + /* Check if LAN865x has any free internal buffer space */ + if (chunks > tc6->txc) { + return -EIO; + } + + /* Transform struct net_pkt content into chunks */ + for (i = 1; i <= chunks; i++) { + hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | + FIELD_PREP(OA_DATA_HDR_DV, 1) | + FIELD_PREP(OA_DATA_HDR_NORX, 1) | + FIELD_PREP(OA_DATA_HDR_SWO, 0); + + if (i == 1) { + hdr |= FIELD_PREP(OA_DATA_HDR_SV, 1); + } + + if (i == chunks) { + hdr |= FIELD_PREP(OA_DATA_HDR_EBO, len - 1) | + FIELD_PREP(OA_DATA_HDR_EV, 1); + } + + hdr |= FIELD_PREP(OA_DATA_HDR_P, oa_tc6_get_parity(hdr)); + + ret = net_pkt_read(pkt, oa_tx, len > tc6->cps ? tc6->cps : len); + if (ret < 0) { + return ret; + } + + ret = oa_tc6_chunk_spi_transfer(tc6, NULL, oa_tx, hdr, &ftr); + if (ret < 0) { + return ret; + } + + len -= tc6->cps; + } + + return 0; +} + +static void oa_tc6_update_status(struct oa_tc6 *tc6, uint32_t ftr) +{ + tc6->exst = FIELD_GET(OA_DATA_FTR_EXST, ftr); + tc6->sync = FIELD_GET(OA_DATA_FTR_SYNC, ftr); + tc6->rca = FIELD_GET(OA_DATA_FTR_RCA, ftr); + tc6->txc = FIELD_GET(OA_DATA_FTR_TXC, ftr); +} + +int oa_tc6_update_buf_info(struct oa_tc6 *tc6) +{ + uint32_t val; + int ret; + + ret = oa_tc6_reg_read(tc6, OA_BUFSTS, &val); + if (ret < 0) { + return ret; + } + + tc6->rca = FIELD_GET(OA_BUFSTS_RCA, val); + tc6->txc = FIELD_GET(OA_BUFSTS_TXC, val); + + return 0; +} + +int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, + uint32_t hdr, uint32_t *ftr) +{ + struct spi_buf tx_buf[2]; + struct spi_buf rx_buf[2]; + struct spi_buf_set tx; + struct spi_buf_set rx; + int ret; + + hdr = sys_cpu_to_be32(hdr); + tx_buf[0].buf = &hdr; + tx_buf[0].len = sizeof(hdr); + + tx_buf[1].buf = buf_tx; + tx_buf[1].len = tc6->cps; + + tx.buffers = tx_buf; + tx.count = ARRAY_SIZE(tx_buf); + + rx_buf[0].buf = buf_rx; + rx_buf[0].len = tc6->cps; + + rx_buf[1].buf = ftr; + rx_buf[1].len = sizeof(*ftr); + + rx.buffers = rx_buf; + rx.count = ARRAY_SIZE(rx_buf); + + ret = spi_transceive_dt(tc6->spi, &tx, &rx); + if (ret < 0) { + return ret; + } + *ftr = sys_be32_to_cpu(*ftr); + oa_tc6_update_status(tc6, *ftr); + + return 0; +} + +int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr) +{ + uint32_t hdr; + + hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | + FIELD_PREP(OA_DATA_HDR_DV, 0) | + FIELD_PREP(OA_DATA_HDR_NORX, 1); + hdr |= FIELD_PREP(OA_DATA_HDR_P, oa_tc6_get_parity(hdr)); + + return oa_tc6_chunk_spi_transfer(tc6, NULL, NULL, hdr, ftr); +} + +int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt) +{ + struct net_buf *buf_rx = NULL; + uint8_t chunks, sbo, ebo; + uint32_t hdr, ftr; + int ret; + + /* + * Special case - append already received data (extracted from previous + * chunk) to new packet. + */ + if (tc6->concat_buf) { + net_pkt_append_buffer(pkt, tc6->concat_buf); + tc6->concat_buf = NULL; + } + + for (chunks = tc6->rca; chunks; chunks--) { + buf_rx = net_pkt_get_frag(pkt, tc6->cps, OA_TC6_BUF_ALLOC_TIMEOUT); + if (!buf_rx) { + LOG_ERR("OA RX: Can't allocate RX buffer fordata!"); + return -ENOMEM; + } + + hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1); + hdr |= FIELD_PREP(OA_DATA_HDR_P, oa_tc6_get_parity(hdr)); + + ret = oa_tc6_chunk_spi_transfer(tc6, buf_rx->data, NULL, hdr, &ftr); + if (ret < 0) { + LOG_ERR("OA RX: transmission error: %d!", ret); + goto unref_buf; + } + + ret = -EIO; + if (oa_tc6_get_parity(ftr)) { + LOG_ERR("OA RX: Footer parity error!"); + goto unref_buf; + } + + if (!FIELD_GET(OA_DATA_FTR_SYNC, ftr)) { + LOG_ERR("OA RX: Configuration not SYNC'ed!"); + goto unref_buf; + } + + if (!FIELD_GET(OA_DATA_FTR_DV, ftr)) { + LOG_ERR("OA RX: Data chunk not valid, skip!"); + goto unref_buf; + } + + sbo = FIELD_GET(OA_DATA_FTR_SWO, ftr) * sizeof(uint32_t); + ebo = FIELD_GET(OA_DATA_FTR_EBO, ftr) + 1; + + if (FIELD_GET(OA_DATA_FTR_SV, ftr)) { + /* + * Adjust beginning of the buffer with SWO only when + * we DO NOT have two frames concatenated together + * in one chunk. + */ + if (!(FIELD_GET(OA_DATA_FTR_EV, ftr) && (ebo <= sbo))) { + if (sbo) { + net_buf_pull(buf_rx, sbo); + } + } + } + + net_pkt_append_buffer(pkt, buf_rx); + buf_rx->len = tc6->cps; + + if (FIELD_GET(OA_DATA_FTR_EV, ftr)) { + /* + * Check if received frame shall be dropped - i.e. MAC has + * detected error condition, which shall result in frame drop + * by the SPI host. + */ + if (FIELD_GET(OA_DATA_FTR_FD, ftr)) { + ret = -EIO; + goto unref_buf; + } + + /* + * Concatenation of frames in a single chunk - one frame ends + * and second one starts just afterwards (ebo == sbo). + */ + if (FIELD_GET(OA_DATA_FTR_SV, ftr) && (ebo <= sbo)) { + tc6->concat_buf = net_buf_clone(buf_rx, OA_TC6_BUF_ALLOC_TIMEOUT); + if (!tc6->concat_buf) { + LOG_ERR("OA RX: Can't allocate RX buffer for data!"); + ret = -ENOMEM; + goto unref_buf; + } + net_buf_pull(tc6->concat_buf, sbo); + } + + /* Set final size of the buffer */ + buf_rx->len = ebo; + /* + * Exit when complete packet is read and added to + * struct net_pkt + */ + break; + } + } + + return 0; + + unref_buf: + net_buf_unref(buf_rx); + return ret; +} diff --git a/drivers/ethernet/oa_tc6.h b/drivers/ethernet/oa_tc6.h new file mode 100644 index 00000000000..7a9337e7c5d --- /dev/null +++ b/drivers/ethernet/oa_tc6.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef OA_TC6_CFG_H__ +#define OA_TC6_CFG_H__ + +#include +#include +#include +#include +#include +#include + +#define MMS_REG(m, r) ((((m) & GENMASK(3, 0)) << 16) | ((r) & GENMASK(15, 0))) +/* Memory Map Sector (MMS) 0 */ +#define OA_ID MMS_REG(0x0, 0x000) /* expect 0x11 */ +#define OA_PHYID MMS_REG(0x0, 0x001) +#define OA_RESET MMS_REG(0x0, 0x003) +#define OA_RESET_SWRESET BIT(0) +#define OA_CONFIG0 MMS_REG(0x0, 0x004) +#define OA_CONFIG0_SYNC BIT(15) +#define OA_CONFIG0_PROTE BIT(5) +#define OA_STATUS0 MMS_REG(0x0, 0x008) +#define OA_STATUS0_RESETC BIT(6) +#define OA_STATUS1 MMS_REG(0x0, 0x009) +#define OA_BUFSTS MMS_REG(0x0, 0x00B) +#define OA_BUFSTS_TXC GENMASK(15, 8) +#define OA_BUFSTS_RCA GENMASK(7, 0) +#define OA_IMASK0 MMS_REG(0x0, 0x00C) +#define OA_IMASK0_TXPEM BIT(0) +#define OA_IMASK0_TXBOEM BIT(1) +#define OA_IMASK0_TXBUEM BIT(2) +#define OA_IMASK0_RXBOEM BIT(3) +#define OA_IMASK0_LOFEM BIT(4) +#define OA_IMASK0_HDREM BIT(5) +#define OA_IMASK1 MMS_REG(0x0, 0x00D) +#define OA_IMASK0_UV18M BIT(19) + +/* OA Control header */ +#define OA_CTRL_HDR_DNC BIT(31) +#define OA_CTRL_HDR_HDRB BIT(30) +#define OA_CTRL_HDR_WNR BIT(29) +#define OA_CTRL_HDR_AID BIT(28) +#define OA_CTRL_HDR_MMS GENMASK(27, 24) +#define OA_CTRL_HDR_ADDR GENMASK(23, 8) +#define OA_CTRL_HDR_LEN GENMASK(7, 1) +#define OA_CTRL_HDR_P BIT(0) + +/* OA Data header */ +#define OA_DATA_HDR_DNC BIT(31) +#define OA_DATA_HDR_SEQ BIT(30) +#define OA_DATA_HDR_NORX BIT(29) +#define OA_DATA_HDR_DV BIT(21) +#define OA_DATA_HDR_SV BIT(20) +#define OA_DATA_HDR_SWO GENMASK(19, 16) +#define OA_DATA_HDR_EV BIT(14) +#define OA_DATA_HDR_EBO GENMASK(13, 8) +#define OA_DATA_HDR_P BIT(0) + +/* OA Data footer */ +#define OA_DATA_FTR_EXST BIT(31) +#define OA_DATA_FTR_HDRB BIT(30) +#define OA_DATA_FTR_SYNC BIT(29) +#define OA_DATA_FTR_RCA GENMASK(28, 24) +#define OA_DATA_FTR_DV BIT(21) +#define OA_DATA_FTR_SV BIT(20) +#define OA_DATA_FTR_SWO GENMASK(19, 16) +#define OA_DATA_FTR_FD BIT(15) +#define OA_DATA_FTR_EV BIT(14) +#define OA_DATA_FTR_EBO GENMASK(13, 8) +#define OA_DATA_FTR_TXC GENMASK(5, 1) +#define OA_DATA_FTR_P BIT(0) + +#define OA_TC6_HDR_SIZE 4 +#define OA_TC6_FTR_SIZE 4 +#define OA_TC6_BUF_ALLOC_TIMEOUT K_MSEC(10) + +/** + * @brief OA TC6 data. + */ +struct oa_tc6 { + /** Pointer to SPI device */ + const struct spi_dt_spec *spi; + + /** OA data payload (chunk) size */ + uint8_t cps; + + /** + * Number of available chunks buffers in OA TC6 device to store + * data for transmission + */ + uint8_t txc; + + /** Number of available chunks to read from OA TC6 device */ + uint8_t rca; + + /** Indication of pending interrupt in OA TC6 device */ + bool exst; + + /** Indication of OA TC6 device being ready for transmission */ + bool sync; + + /** Indication of protected control transmission mode */ + bool protected; + + /** Pointer to network buffer concatenated from received chunk */ + struct net_buf *concat_buf; +}; + +typedef struct { + uint32_t address; + uint32_t value; +} oa_mem_map_t; + +/** + * @brief Calculate parity bit from data + * + * @param x data to calculate parity + * + * @return 0 if number of ones is odd, 1 otherwise. + */ +static inline bool oa_tc6_get_parity(const uint32_t x) +{ + uint32_t y; + + y = x ^ (x >> 1); + y = y ^ (y >> 2); + y = y ^ (y >> 4); + y = y ^ (y >> 8); + y = y ^ (y >> 16); + + return !(y & 1); +} + +/** + * @brief Read OA TC6 compliant device single register + * + * @param tc6 OA TC6 specific data + * + * @param reg register to read + + * @param val pointer to variable to store read value + * + * @return 0 if read was successful, <0 otherwise. + */ +int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val); + +/** + * @brief Write to OA TC6 compliant device a single register + * + * @param tc6 OA TC6 specific data + * + * @param reg register to read + + * @param val data to send to device + * + * @return 0 if write was successful, <0 otherwise. + */ +int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val); + +/** + * @brief Enable or disable the protected mode for control transactions + * + * @param tc6 OA TC6 specific data + * + * @param prote enable or disable protected control transactions + * + * @return 0 if operation was successful, <0 otherwise. + */ +int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote); + +/** + * @brief Send OA TC6 data chunks to the device + * + * @param tc6 OA TC6 specific data + * + * @param pkt network packet to be send + * + * @return 0 if data send was successful, <0 otherwise. + */ +int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt); + +/** + * @brief Read data chunks from OA TC6 device + * + * @param tc6 OA TC6 specific data + * + * @param pkt network packet to store received data + * + * @return 0 if read was successful, <0 otherwise. + */ +int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt); + +/** + * @brief Perform SPI transfer of single chunk from/to OA TC6 device + * + * @param tc6 OA TC6 specific data + * + * @param buf_rx buffer to store read data + * + * @param buf_tx buffer with data to send + * + * @param hdr OA TC6 data transmission header value + * + * @param ftr poniter to OA TC6 data received footer + * + * @return 0 if transmission was successful, <0 otherwise. + */ +int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, + uint32_t hdr, uint32_t *ftr); + +/** + * @brief Read status from OA TC6 device + * + * @param tc6 OA TC6 specific data + * + * @param ftr poniter to OA TC6 data received footer + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr); + +/** + * @brief Read from OA TC6 device and update buffer information + * + * @param tc6 OA TC6 specific data + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_update_buf_info(struct oa_tc6 *tc6); +#endif /* OA_TC6_CFG_H__ */ From 12665a0dc12b1ed5dce71d232a6abcb8d6a6056b Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 6 Oct 2023 16:59:42 +0200 Subject: [PATCH 3354/4498] driver: eth: Support for lan8651 T1S ETH This patch set provides support for T1S ethernet device - LAN8651. For SPI communication the implementation of Open Alliance TC6 specification is used. The driver implementation focuses mostly on reducing memory footprint, as the used SoC (STM32G491) for development has only 32 KiB RAM in total. Signed-off-by: Lukasz Majewski --- CODEOWNERS | 1 + drivers/ethernet/CMakeLists.txt | 1 + drivers/ethernet/Kconfig | 1 + drivers/ethernet/Kconfig.lan865x | 50 ++ drivers/ethernet/eth_lan865x.c | 585 +++++++++++++++++++ drivers/ethernet/eth_lan865x_priv.h | 77 +++ dts/bindings/ethernet/microchip,lan865x.yaml | 46 ++ 7 files changed, 761 insertions(+) create mode 100644 drivers/ethernet/Kconfig.lan865x create mode 100644 drivers/ethernet/eth_lan865x.c create mode 100644 drivers/ethernet/eth_lan865x_priv.h create mode 100644 dts/bindings/ethernet/microchip,lan865x.yaml diff --git a/CODEOWNERS b/CODEOWNERS index f3d2bb732c9..1db37fb9dd5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -306,6 +306,7 @@ /drivers/ethernet/*smsc91x* @sgrrzhf /drivers/ethernet/*adin2111* @GeorgeCGV /drivers/ethernet/*oa_tc6* @lmajewski +/drivers/ethernet/*lan865x* @lmajewski /drivers/ethernet/phy/ @rlubos @tbursztyka @arvinf @jukkar /drivers/ethernet/phy/*adin2111* @GeorgeCGV /drivers/mdio/ @rlubos @tbursztyka @arvinf diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index 20cc367fe5b..1ae6ef58e82 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -34,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_SLIP_TAP eth_slip_tap.c) zephyr_library_sources_ifdef(CONFIG_ETH_SMSC91X eth_smsc91x.c) zephyr_library_sources_ifdef(CONFIG_ETH_IVSHMEM eth_ivshmem.c eth_ivshmem_queue.c) zephyr_library_sources_ifdef(CONFIG_ETH_ADIN2111 eth_adin2111.c) +zephyr_library_sources_ifdef(CONFIG_ETH_LAN865X eth_lan865x.c oa_tc6.c) if(CONFIG_ETH_NXP_S32_NETC) zephyr_library_sources(eth_nxp_s32_netc.c) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index eae83755af0..69b60e09bc2 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -62,6 +62,7 @@ source "drivers/ethernet/Kconfig.smsc91x" source "drivers/ethernet/Kconfig.ivshmem" source "drivers/ethernet/Kconfig.adin2111" source "drivers/ethernet/Kconfig.numaker" +source "drivers/ethernet/Kconfig.lan865x" source "drivers/ethernet/phy/Kconfig" diff --git a/drivers/ethernet/Kconfig.lan865x b/drivers/ethernet/Kconfig.lan865x new file mode 100644 index 00000000000..c3bdc2f9b73 --- /dev/null +++ b/drivers/ethernet/Kconfig.lan865x @@ -0,0 +1,50 @@ +# Copyright (c) 2023 DENX Software Engineering GmbH +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ETH_LAN865X + bool "LAN865X 10BASE-T1S Controller" + default y + depends on DT_HAS_MICROCHIP_LAN865X_ENABLED + select SPI + help + The LAN865X is a low power, 10BASE-T1S transceiver compliant with + the IEEE® 802.3cg-2019™ Ethernet standard for long reach, 10 + Mbps single pair Ethernet (SPE). + + Featuring an integrated media access control (MAC) and a PHY, + the LAN865X enables direct connectivity with a variety of controllers + via a serial peripheral inter-face (SPI). + +if ETH_LAN865X + +config ETH_LAN865X_INIT_PRIORITY + int "LAN865X driver init priority" + default 72 + help + LAN865X device driver initialization priority. + Must be initialized after SPI. + + +config ETH_LAN865X_IRQ_THREAD_STACK_SIZE + int "Stack size for a thread that processes IRQ" + default 512 + help + Size of the stack used for internal thread which is ran to + process raised INT IRQ. + +config ETH_LAN865X_IRQ_THREAD_PRIO + int "Priority for internal incoming packet handler" + default 2 + help + Priority level for internal thread which is ran for LAN + INT IRQ processing. + +config ETH_LAN865X_TIMEOUT + int "IP buffer timeout" + default 100 + help + Given timeout in milliseconds. Maximum amount of time + that the driver will wait from the IP stack to get + a memory buffer before the Ethernet frame is dropped. + +endif # ETH_LAN865X diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c new file mode 100644 index 00000000000..8107b7d3542 --- /dev/null +++ b/drivers/ethernet/eth_lan865x.c @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_lan865x + +#include +LOG_MODULE_REGISTER(eth_lan865x, CONFIG_ETHERNET_LOG_LEVEL); + +#include +#include + +#include +#include + +#include +#include +#include + +#include "eth_lan865x_priv.h" + +static int lan865x_mac_rxtx_control(const struct device *dev, bool en) +{ + struct lan865x_data *ctx = dev->data; + uint32_t ctl = 0; + + if (en) { + ctl = LAN865x_MAC_NCR_TXEN | LAN865x_MAC_NCR_RXEN; + } + + return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCR, ctl); +} + +static void lan865x_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct lan865x_data *ctx = dev->data; + + net_if_set_link_addr(iface, ctx->mac_address, sizeof(ctx->mac_address), + NET_LINK_ETHERNET); + + if (ctx->iface == NULL) { + ctx->iface = iface; + } + + ethernet_init(iface); + + net_eth_carrier_on(iface); + ctx->iface_initialized = true; +} + +static enum ethernet_hw_caps lan865x_port_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + return ETHERNET_LINK_10BASE_T | ETHERNET_PROMISC_MODE; +} + +static void lan865x_write_macaddress(const struct device *dev); +static int lan865x_set_config(const struct device *dev, enum ethernet_config_type type, + const struct ethernet_config *config) +{ + struct lan865x_data *ctx = dev->data; + int ret = -ENOTSUP; + + if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) { + ret = lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_OFF); + if (ret) { + return ret; + } + + ret = oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCFGR, + LAN865x_MAC_NCFGR_CAF); + if (ret) { + return ret; + } + + return lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_ON); + } + + if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { + ret = lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_OFF); + if (ret) { + return ret; + } + + memcpy(ctx->mac_address, config->mac_address.addr, + sizeof(ctx->mac_address)); + + lan865x_write_macaddress(dev); + + net_if_set_link_addr(ctx->iface, ctx->mac_address, + sizeof(ctx->mac_address), + NET_LINK_ETHERNET); + + return lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_ON); + } + + return ret; +} + +static int lan865x_wait_for_reset(const struct device *dev) +{ + struct lan865x_data *ctx = dev->data; + uint8_t i; + + /* Wait for end of LAN865x reset */ + for (i = 0; !ctx->reset && i < LAN865X_RESET_TIMEOUT; i++) { + k_msleep(1); + } + + if (i == LAN865X_RESET_TIMEOUT) { + LOG_ERR("LAN865x reset timeout reached!"); + return -ENODEV; + } + + return 0; +} + +static int lan865x_gpio_reset(const struct device *dev) +{ + const struct lan865x_config *cfg = dev->config; + + /* Perform (GPIO based) HW reset */ + /* assert RESET_N low for 10 µs (5 µs min) */ + gpio_pin_set_dt(&cfg->reset, 1); + k_busy_wait(10U); + /* deassert - end of reset indicated by IRQ_N low */ + gpio_pin_set_dt(&cfg->reset, 0); + + return lan865x_wait_for_reset(dev); +} + +static int lan865x_check_spi(const struct device *dev) +{ + struct lan865x_data *ctx = dev->data; + uint32_t val; + int ret; + + ret = oa_tc6_reg_read(ctx->tc6, LAN865x_DEVID, &val); + if (ret < 0) { + return -ENODEV; + } + + ctx->silicon_rev = val & LAN865X_REV_MASK; + if (ctx->silicon_rev != 1 && ctx->silicon_rev != 2) { + return -ENODEV; + } + + ctx->chip_id = (val >> 4) & 0xFFFF; + if (ctx->chip_id != LAN8650_DEVID && ctx->chip_id != LAN8651_DEVID) { + return -ENODEV; + } + + return ret; +} + +/* Implementation of pseudo code from AN1760 */ +static uint8_t lan865x_read_indirect_reg(const struct device *dev, uint8_t addr, + uint8_t mask) +{ + struct lan865x_data *ctx = dev->data; + uint32_t val; + + oa_tc6_reg_write(ctx->tc6, 0x000400D8, addr); + oa_tc6_reg_write(ctx->tc6, 0x000400DA, 0x02); + + oa_tc6_reg_read(ctx->tc6, 0x000400D9, &val); + + return (uint8_t) val & mask; +} + +static int lan865x_init_chip(const struct device *dev, uint8_t silicon_rev) +{ + struct lan865x_data *ctx = dev->data; + uint8_t value1, value2; + int8_t offset1 = 0, offset2 = 0, ret; + uint16_t value3, value4, value5, value6, value7; + uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5; + uint32_t val; + + ret = lan865x_read_indirect_reg(dev, 0x05, 0x40); + if (ret == 0) { + LOG_ERR("LAN865x error! Please contact microchip support for replacement."); + return -EIO; + } + + value1 = lan865x_read_indirect_reg(dev, 0x04, 0x1F); + if ((value1 & 0x10) != 0) { /* Convert uint8_t to int8_t */ + offset1 = value1 | 0xE0; + if (offset1 < -5) { + LOG_ERR("LAN865x internal error!"); + return -EIO; + } + } else { + offset1 = value1; + } + + value2 = lan865x_read_indirect_reg(dev, 0x08, 0x1F); + if ((value2 & 0x10) != 0) { /* Convert uint8_t to int8_t */ + offset2 = value2 | 0xE0; + } else { + offset2 = value2; + } + + oa_tc6_reg_read(ctx->tc6, 0x00040084, &val); + value3 = (uint16_t)val; + + oa_tc6_reg_read(ctx->tc6, 0x0004008A, &val); + value4 = (uint16_t)val; + + oa_tc6_reg_read(ctx->tc6, 0x000400AD, &val); + value5 = (uint16_t)val; + + oa_tc6_reg_read(ctx->tc6, 0x000400AE, &val); + value6 = (uint8_t)val; + + oa_tc6_reg_read(ctx->tc6, 0x000400AF, &val); + value7 = (uint8_t)val; + + cfgparam1 = (value3 & 0xF) | (((9 + offset1) << 10) | ((14 + offset1) << 4)); + cfgparam2 = (value4 & 0x3FF) | ((40 + offset2) << 10); + cfgparam3 = (value5 & 0xC0C0) | (((5 + offset1) << 8) | (9 + offset1)); + cfgparam4 = (value6 & 0xC0C0) | (((9 + offset1) << 8) | (14 + offset1)); + cfgparam5 = (value7 & 0xC0C0) | (((17 + offset1) << 8) | (22 + offset1)); + + oa_tc6_reg_write(ctx->tc6, 0x00040084, (uint32_t) cfgparam1); + oa_tc6_reg_write(ctx->tc6, 0x0004008A, (uint32_t) cfgparam2); + oa_tc6_reg_write(ctx->tc6, 0x000400AD, (uint32_t) cfgparam3); + oa_tc6_reg_write(ctx->tc6, 0x000400AE, (uint32_t) cfgparam4); + oa_tc6_reg_write(ctx->tc6, 0x000400AF, (uint32_t) cfgparam5); + + return 0; +} +/* Implementation of pseudo code from AN1760 - END */ + +static int lan865x_config_plca(const struct device *dev, uint8_t node_id, + uint8_t node_cnt, uint8_t burst_cnt, uint8_t burst_timer) +{ + struct lan865x_data *ctx = dev->data; + uint32_t val; + + /* Collision Detection */ + oa_tc6_reg_write(ctx->tc6, 0x00040087, 0x0083u); /* COL_DET_CTRL0 */ + + /* T1S Phy Node Id and Max Node Count */ + val = ((uint32_t)node_cnt << 8) | node_id; + oa_tc6_reg_write(ctx->tc6, 0x0004CA02, val); /* PLCA_CONTROL_1_REGISTER */ + + /* PLCA Burst Count and Burst Timer */ + val = ((uint32_t)burst_cnt << 8) | burst_timer; + oa_tc6_reg_write(ctx->tc6, 0x0004CA05, val); /* PLCA_BURST_MODE_REGISTER */ + + /* Enable PLCA */ + oa_tc6_reg_write(ctx->tc6, 0x0004CA01, BIT(15)); /* PLCA_CONTROL_0_REGISTER */ + + return 0; +} + +static void lan865x_write_macaddress(const struct device *dev) +{ + struct lan865x_data *ctx = dev->data; + uint8_t *mac = &ctx->mac_address[0]; + uint32_t val; + + /* SPEC_ADD2_BOTTOM */ + val = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]; + oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_SAB2, val); + + /* SPEC_ADD2_TOP */ + val = (mac[5] << 8) | mac[4]; + oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_SAT2, val); + + /* SPEC_ADD1_BOTTOM */ + val = (mac[5] << 24) | (mac[4] << 16) | (mac[3] << 8) | mac[2]; + oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_SAB1, val); +} + +static int lan865x_default_config(const struct device *dev, uint8_t silicon_rev) +{ + /* Values in the below table are the same for LAN865x rev. B0 and B1 */ + static const oa_mem_map_t lan865x_conf[] = { + { .address = 0x00010000, .value = 0x00000000 }, + { .address = 0x00040091, .value = 0x00009660 }, + { .address = 0x00040081, .value = 0x00000080 }, + { .address = 0x00010077, .value = 0x00000028 }, + { .address = 0x00040043, .value = 0x000000FF }, + { .address = 0x00040044, .value = 0x0000FFFF }, + { .address = 0x00040045, .value = 0x00000000 }, + { .address = 0x00040053, .value = 0x000000FF }, + { .address = 0x00040054, .value = 0x0000FFFF }, + { .address = 0x00040055, .value = 0x00000000 }, + { .address = 0x00040040, .value = 0x00000002 }, + { .address = 0x00040050, .value = 0x00000002 }, + { .address = 0x000400E9, .value = 0x00009E50 }, + { .address = 0x000400F5, .value = 0x00001CF8 }, + { .address = 0x000400F4, .value = 0x0000C020 }, + { .address = 0x000400F8, .value = 0x00009B00 }, + { .address = 0x000400F9, .value = 0x00004E53 }, + { .address = 0x000400B0, .value = 0x00000103 }, + { .address = 0x000400B1, .value = 0x00000910 }, + { .address = 0x000400B2, .value = 0x00001D26 }, + { .address = 0x000400B3, .value = 0x0000002A }, + { .address = 0x000400B4, .value = 0x00000103 }, + { .address = 0x000400B5, .value = 0x0000070D }, + { .address = 0x000400B6, .value = 0x00001720 }, + { .address = 0x000400B7, .value = 0x00000027 }, + { .address = 0x000400B8, .value = 0x00000509 }, + { .address = 0x000400B9, .value = 0x00000E13 }, + { .address = 0x000400BA, .value = 0x00001C25 }, + { .address = 0x000400BB, .value = 0x0000002B }, + { .address = 0x0000000C, .value = 0x00000100 }, + { .address = 0x00040081, .value = 0x000000E0 }, + }; + const struct lan865x_config *cfg = dev->config; + uint8_t i, size = ARRAY_SIZE(lan865x_conf); + struct lan865x_data *ctx = dev->data; + int ret; + + /* Enable protected control RW */ + oa_tc6_set_protected_ctrl(ctx->tc6, true); + + for (i = 0; i < size; i++) { + oa_tc6_reg_write(ctx->tc6, lan865x_conf[i].address, + lan865x_conf[i].value); + } + + if (silicon_rev == 1) { + /* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */ + oa_tc6_reg_write(ctx->tc6, 0x000400D0, 0x5F21); + } + + lan865x_write_macaddress(dev); + + ret = lan865x_init_chip(dev, silicon_rev); + if (ret < 0) + return ret; + + if (cfg->plca_enable) { + ret = lan865x_config_plca(dev, cfg->plca_node_id, + cfg->plca_node_count, + cfg->plca_burst_count, + cfg->plca_burst_timer); + if (ret < 0) { + return ret; + } + } + return 0; +} + +static void lan865x_int_callback(const struct device *dev, + struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct lan865x_data *ctx = + CONTAINER_OF(cb, struct lan865x_data, gpio_int_callback); + + k_sem_give(&ctx->int_sem); +} + +static void lan865x_read_chunks(const struct device *dev) +{ + const struct lan865x_config *cfg = dev->config; + struct lan865x_data *ctx = dev->data; + struct oa_tc6 *tc6 = ctx->tc6; + struct net_pkt *pkt; + int ret; + + k_sem_take(&ctx->tx_rx_sem, K_FOREVER); + pkt = net_pkt_rx_alloc(K_MSEC(cfg->timeout)); + if (!pkt) { + LOG_ERR("OA RX: Could not allocate packet!"); + k_sem_give(&ctx->tx_rx_sem); + return; + } + + ret = oa_tc6_read_chunks(tc6, pkt); + k_sem_give(&ctx->tx_rx_sem); + if (ret < 0) { + eth_stats_update_errors_rx(ctx->iface); + net_pkt_unref(pkt); + return; + } + + /* Feed buffer frame to IP stack */ + ret = net_recv_data(ctx->iface, pkt); + if (ret < 0) { + LOG_ERR("OA RX: Could not process packet (%d)!", ret); + net_pkt_unref(pkt); + } +} + +static void lan865x_int_thread(const struct device *dev) +{ + struct lan865x_data *ctx = dev->data; + struct oa_tc6 *tc6 = ctx->tc6; + uint32_t sts, val, ftr; + + while (true) { + k_sem_take(&ctx->int_sem, K_FOREVER); + if (!ctx->reset) { + oa_tc6_reg_read(tc6, OA_STATUS0, &sts); + if (sts & OA_STATUS0_RESETC) { + oa_tc6_reg_write(tc6, OA_STATUS0, sts); + lan865x_default_config(dev, ctx->silicon_rev); + oa_tc6_reg_read(tc6, OA_CONFIG0, &val); + oa_tc6_reg_write(tc6, OA_CONFIG0, OA_CONFIG0_SYNC | val); + lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_ON); + + ctx->reset = true; + /* + * According to OA T1S standard - it is mandatory to + * read chunk of data to get the IRQ_N negated (deasserted). + */ + oa_tc6_read_status(tc6, &ftr); + continue; + } + } + + /* + * The IRQ_N is asserted when RCA becomes > 0, so update its value + * before reading chunks. + */ + oa_tc6_update_buf_info(tc6); + + while (tc6->rca > 0) { + lan865x_read_chunks(dev); + } + + if (tc6->exst) { + /* + * Just clear any pending interrupts - data RX will be served + * earlier. + * The RESETC is handled separately as it requires LAN865x device + * configuration. + */ + oa_tc6_reg_read(tc6, OA_STATUS0, &sts); + if (sts != 0) { + oa_tc6_reg_write(tc6, OA_STATUS0, sts); + } + + oa_tc6_reg_read(tc6, OA_STATUS1, &sts); + if (sts != 0) { + oa_tc6_reg_write(tc6, OA_STATUS1, sts); + } + } + } +} + +static int lan865x_init(const struct device *dev) +{ + const struct lan865x_config *cfg = dev->config; + struct lan865x_data *ctx = dev->data; + int ret; + + __ASSERT(cfg->spi.config.frequency <= LAN865X_SPI_MAX_FREQUENCY, + "SPI frequency exceeds supported maximum\n"); + + if (!spi_is_ready_dt(&cfg->spi)) { + LOG_ERR("SPI bus %s not ready", cfg->spi.bus->name); + return -ENODEV; + } + + if (!gpio_is_ready_dt(&cfg->interrupt)) { + LOG_ERR("Interrupt GPIO device %s is not ready", + cfg->interrupt.port->name); + return -ENODEV; + } + + /* Check SPI communication after reset */ + ret = lan865x_check_spi(dev); + if (ret < 0) { + LOG_ERR("SPI communication not working, %d", ret); + return ret; + } + + /* + * Configure interrupt service routine for LAN865x IRQ + */ + ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt GPIO, %d", ret); + return ret; + } + + gpio_init_callback(&(ctx->gpio_int_callback), lan865x_int_callback, + BIT(cfg->interrupt.pin)); + + ret = gpio_add_callback(cfg->interrupt.port, &ctx->gpio_int_callback); + if (ret < 0) { + LOG_ERR("Failed to add INT callback, %d", ret); + return ret; + } + + gpio_pin_interrupt_configure_dt(&cfg->interrupt, GPIO_INT_EDGE_TO_ACTIVE); + + /* Start interruption-poll thread */ + ctx->tid_int = + k_thread_create(&ctx->thread, ctx->thread_stack, + CONFIG_ETH_LAN865X_IRQ_THREAD_STACK_SIZE, + (k_thread_entry_t)lan865x_int_thread, + (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_ETH_LAN865X_IRQ_THREAD_PRIO), + 0, K_NO_WAIT); + k_thread_name_set(ctx->tid_int, "lan865x_interrupt"); + + ctx->reset = false; + + /* Perform HW reset - 'rst-gpios' required property set in DT */ + if (!gpio_is_ready_dt(&cfg->reset)) { + LOG_ERR("Reset GPIO device %s is not ready", + cfg->reset.port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure reset GPIO, %d", ret); + return ret; + } + + return lan865x_gpio_reset(dev); +} + +static int lan865x_port_send(const struct device *dev, struct net_pkt *pkt) +{ + struct lan865x_data *ctx = dev->data; + struct oa_tc6 *tc6 = ctx->tc6; + int ret; + + k_sem_take(&ctx->tx_rx_sem, K_FOREVER); + ret = oa_tc6_send_chunks(tc6, pkt); + k_sem_give(&ctx->tx_rx_sem); + if (ret < 0) { + LOG_ERR("TX transmission error, %d", ret); + eth_stats_update_errors_tx(net_pkt_iface(pkt)); + return ret; + } + + return 0; +} + +static const struct ethernet_api lan865x_api_func = { + .iface_api.init = lan865x_iface_init, + .get_capabilities = lan865x_port_get_capabilities, + .set_config = lan865x_set_config, + .send = lan865x_port_send, +}; + +#define LAN865X_DEFINE(inst) \ + static const struct lan865x_config lan865x_config_##inst = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ + .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + .reset = GPIO_DT_SPEC_INST_GET(inst, rst_gpios), \ + .timeout = CONFIG_ETH_LAN865X_TIMEOUT, \ + .plca_node_id = DT_INST_PROP(inst, plca_node_id), \ + .plca_node_count = DT_INST_PROP(inst, plca_node_count), \ + .plca_burst_count = DT_INST_PROP(inst, plca_burst_count), \ + .plca_burst_timer = DT_INST_PROP(inst, plca_burst_timer), \ + .plca_to_timer = DT_INST_PROP(inst, plca_to_timer), \ + .plca_enable = DT_INST_PROP(inst, plca_enable), \ + }; \ + \ + struct oa_tc6 oa_tc6_##inst = { \ + .cps = 64, \ + .protected = 0, \ + .spi = &lan865x_config_##inst.spi \ + }; \ + static struct lan865x_data lan865x_data_##inst = { \ + .mac_address = DT_INST_PROP(inst, local_mac_address), \ + .tx_rx_sem = \ + Z_SEM_INITIALIZER((lan865x_data_##inst).tx_rx_sem, 1, UINT_MAX), \ + .int_sem = Z_SEM_INITIALIZER((lan865x_data_##inst).int_sem, 0, UINT_MAX), \ + .tc6 = &oa_tc6_##inst \ + }; \ + \ + ETH_NET_DEVICE_DT_INST_DEFINE(inst, lan865x_init, NULL, &lan865x_data_##inst, \ + &lan865x_config_##inst, CONFIG_ETH_INIT_PRIORITY, \ + &lan865x_api_func, NET_ETH_MTU); + +DT_INST_FOREACH_STATUS_OKAY(LAN865X_DEFINE); diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h new file mode 100644 index 00000000000..fa4af1a949a --- /dev/null +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ETH_LAN865X_PRIV_H__ +#define ETH_LAN865X_PRIV_H__ + +#include +#include +#include +#include +#include +#include +#include +#include "oa_tc6.h" + +#define LAN865X_SPI_MAX_FREQUENCY 25000000U +#define LAN865X_HW_BOOT_DELAY_MS 7 +#define LAN8650_DEVID 0x8650 +#define LAN8651_DEVID 0x8651 +#define LAN865X_REV_MASK GENMASK(3, 0) +#define LAN865X_RESET_TIMEOUT 10 + +/* Memory Map Sector (MMS) 1 (0x1) */ +#define LAN865x_MAC_NCR MMS_REG(0x1, 0x000) +#define LAN865x_MAC_NCR_TXEN BIT(3) +#define LAN865x_MAC_NCR_RXEN BIT(2) +#define LAN865x_MAC_NCFGR MMS_REG(0x1, 0x001) +#define LAN865x_MAC_NCFGR_CAF BIT(4) +#define LAN865x_MAC_SAB1 MMS_REG(0x1, 0x022) +#define LAN865x_MAC_SAB2 MMS_REG(0x1, 0x024) +#define LAN865x_MAC_SAT2 MMS_REG(0x1, 0x025) + +#define LAN865x_MAC_TXRX_ON 1 +#define LAN865x_MAC_TXRX_OFF 0 + +/* Memory Map Sector (MMS) 10 (0xA) */ +#define LAN865x_DEVID MMS_REG(0xA, 0x094) + +struct lan865x_config { + struct spi_dt_spec spi; + struct gpio_dt_spec interrupt; + struct gpio_dt_spec reset; + int32_t timeout; + + /* PLCA */ + bool plca_enable : 1; /* 1 - PLCA enable, 0 - CSMA/CD enable */ + uint8_t plca_node_id /* PLCA node id range: 0 to 254 */; + uint8_t plca_node_count; /* PLCA node count range: 1 to 255 */ + uint8_t plca_burst_count; /* PLCA burst count range: 0x0 to 0xFF */ + uint8_t plca_burst_timer; /* PLCA burst timer */ + uint8_t plca_to_timer; /* PLCA TO value */ + + /* MAC */ + bool tx_cut_through_mode; /* 1 - tx cut through, 0 - Store and forward */ + bool rx_cut_through_mode; /* 1 - rx cut through, 0 - Store and forward */ +}; + +struct lan865x_data { + struct net_if *iface; + struct gpio_callback gpio_int_callback; + struct k_sem tx_rx_sem; + struct k_sem int_sem; + struct oa_tc6 *tc6; + uint16_t chip_id; + uint8_t silicon_rev; + uint8_t mac_address[6]; + bool iface_initialized; + bool reset; + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ETH_LAN865X_IRQ_THREAD_STACK_SIZE); + struct k_thread thread; + k_tid_t tid_int; +}; + +#endif /* ETH_LAN865X_PRIV_H__ */ diff --git a/dts/bindings/ethernet/microchip,lan865x.yaml b/dts/bindings/ethernet/microchip,lan865x.yaml new file mode 100644 index 00000000000..699bfca7dc6 --- /dev/null +++ b/dts/bindings/ethernet/microchip,lan865x.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2023 DENX Software Engineering GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: | + LAN865x standalone 10BASE-T1L Ethernet controller with SPI interface. + +compatible: "microchip,lan865x" + +include: [spi-device.yaml, ethernet-controller.yaml] + +properties: + tx-cut-through-mode: + type: boolean + description: Enable TX cut through mode + rx-cut-through-mode: + type: boolean + description: Enable RX cut through mode + plca-enable: + type: boolean + description: Enable or disable PLCA support + plca-node-id: + type: int + description: Specify the PLCA node ID number + plca-node-count: + type: int + description: Specify the PLCA node count + plca-burst-count: + type: int + description: Specify the PLCA burst count + plca-burst-timer: + type: int + description: Specify the PLCA burst timer value + plca-to-timer: + type: int + description: Specify the PLCA to timer value + int-gpios: + type: phandle-array + required: true + description: | + The interrupt pin of LAN865X is active low. + If connected directly the MCU pin should be configured + as active low. + rst-gpios: + type: phandle-array + required: true + description: The reset pin of LAN865X. From 8129307887e6f9385af5ef5dc98ec7e254fe0d59 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Tue, 7 Nov 2023 19:45:01 +0100 Subject: [PATCH 3355/4498] drivers: charger: add charger prefix for bq24190 Many (or almost all) drivers contain the specified prefixes related to the driver subsys so add the missing one for the BQ24190. Signed-off-by: Bartosz Bilas --- drivers/charger/CMakeLists.txt | 2 +- drivers/charger/Kconfig.bq24190 | 2 +- drivers/charger/{bq24190.c => charger_bq24190.c} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename drivers/charger/{bq24190.c => charger_bq24190.c} (100%) diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt index 84b34009423..894561982a3 100644 --- a/drivers/charger/CMakeLists.txt +++ b/drivers/charger/CMakeLists.txt @@ -3,7 +3,7 @@ zephyr_library() zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) -zephyr_library_sources_ifdef(CONFIG_BQ24190 bq24190.c) +zephyr_library_sources_ifdef(CONFIG_CHARGER_BQ24190 charger_bq24190.c) zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig.bq24190 b/drivers/charger/Kconfig.bq24190 index 3327f671c69..be3e29727a2 100644 --- a/drivers/charger/Kconfig.bq24190 +++ b/drivers/charger/Kconfig.bq24190 @@ -1,7 +1,7 @@ # Copyright 2023 Cirrus Logic, Inc. # SPDX-License-Identifier: Apache-2.0 -config BQ24190 +config CHARGER_BQ24190 bool "BQ24190 Battery Charger" default y depends on DT_HAS_TI_BQ24190_ENABLED diff --git a/drivers/charger/bq24190.c b/drivers/charger/charger_bq24190.c similarity index 100% rename from drivers/charger/bq24190.c rename to drivers/charger/charger_bq24190.c From 8a77ad406f3eb20ccfc97050e4d07df6a6608b4c Mon Sep 17 00:00:00 2001 From: Emil Lindqvist Date: Thu, 2 Nov 2023 08:25:49 +0100 Subject: [PATCH 3356/4498] lsm6dsl: add pm suspend and resume to lsm6dsl This commit implements the suspend and resume PM API for LSM6DSL accelerometer. Signed-off-by: Emil Lindqvist --- drivers/sensor/lsm6dsl/lsm6dsl.c | 62 ++++++++++++++++++++++++++++++-- drivers/sensor/lsm6dsl/lsm6dsl.h | 1 + 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/lsm6dsl/lsm6dsl.c b/drivers/sensor/lsm6dsl/lsm6dsl.c index b00df0be526..0a0f3525804 100644 --- a/drivers/sensor/lsm6dsl/lsm6dsl.c +++ b/drivers/sensor/lsm6dsl/lsm6dsl.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "lsm6dsl.h" @@ -26,7 +27,8 @@ LOG_MODULE_REGISTER(LSM6DSL, CONFIG_SENSOR_LOG_LEVEL); static const uint16_t lsm6dsl_odr_map[] = {0, 12, 26, 52, 104, 208, 416, 833, 1666, 3332, 6664, 1}; -#if defined(LSM6DSL_ACCEL_ODR_RUNTIME) || defined(LSM6DSL_GYRO_ODR_RUNTIME) +#if defined(LSM6DSL_ACCEL_ODR_RUNTIME) || defined(LSM6DSL_GYRO_ODR_RUNTIME) ||\ + defined(CONFIG_PM_DEVICE) static int lsm6dsl_freq_to_odr_val(uint16_t freq) { size_t i; @@ -169,6 +171,8 @@ static int lsm6dsl_gyro_set_odr_raw(const struct device *dev, uint8_t odr) return -EIO; } + data->gyro_freq = lsm6dsl_odr_to_freq_val(odr); + return 0; } @@ -826,6 +830,59 @@ static int lsm6dsl_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int lsm6dsl_pm_action(const struct device *dev, + enum pm_device_action action) +{ + struct lsm6dsl_data *data = dev->data; + int ret = -EIO; + uint8_t accel_odr = 0; + uint8_t gyro_odr = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + /* Restore saved ODR values */ + accel_odr = lsm6dsl_freq_to_odr_val(data->accel_freq); + ret = lsm6dsl_accel_set_odr_raw(dev, accel_odr); + if (ret < 0) { + LOG_ERR("Failed to resume accelerometer"); + break; + } + gyro_odr = lsm6dsl_freq_to_odr_val(data->gyro_freq); + ret = lsm6dsl_gyro_set_odr_raw(dev, gyro_odr); + if (ret < 0) { + LOG_ERR("Failed to resume gyro"); + break; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + /* + * Set accelerometer ODR to power-down. Don't use the direct + * function to not overwrite the saved value + */ + ret = data->hw_tf->update_reg(dev, LSM6DSL_REG_CTRL1_XL, + LSM6DSL_MASK_CTRL1_XL_ODR_XL, 0); + if (ret < 0) { + LOG_ERR("Failed to suspend accelerometer"); + break; + } + /* Set gyro ODR to power-down */ + ret = data->hw_tf->update_reg(dev, LSM6DSL_REG_CTRL2_G, + LSM6DSL_MASK_CTRL2_G_ODR_G, 0); + if (ret < 0) { + LOG_ERR("Failed to suspend gyro"); + break; + } + + break; + default: + return -ENOTSUP; + } + + return ret; +} +#endif + #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 #warning "LSM6DSL driver enabled without any devices" @@ -837,9 +894,10 @@ static int lsm6dsl_init(const struct device *dev) */ #define LSM6DSL_DEVICE_INIT(inst) \ + PM_DEVICE_DT_INST_DEFINE(inst, lsm6dsl_pm_action); \ SENSOR_DEVICE_DT_INST_DEFINE(inst, \ lsm6dsl_init, \ - NULL, \ + PM_DEVICE_DT_INST_GET(inst), \ &lsm6dsl_data_##inst, \ &lsm6dsl_config_##inst, \ POST_KERNEL, \ diff --git a/drivers/sensor/lsm6dsl/lsm6dsl.h b/drivers/sensor/lsm6dsl/lsm6dsl.h index f424cbf2326..da176f4f692 100644 --- a/drivers/sensor/lsm6dsl/lsm6dsl.h +++ b/drivers/sensor/lsm6dsl/lsm6dsl.h @@ -667,6 +667,7 @@ struct lsm6dsl_data { #endif const struct lsm6dsl_transfer_function *hw_tf; uint16_t accel_freq; + uint16_t gyro_freq; #ifdef CONFIG_LSM6DSL_TRIGGER const struct device *dev; From b72e5c1f3d56c31734ccb5e69ee4e3a9ad28ce8a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 1 Nov 2023 15:59:43 +0000 Subject: [PATCH 3357/4498] MAINTAINERS: more fixes and expansion of coverage More fixes and new areas that were not covered before. Signed-off-by: Anas Nashif --- MAINTAINERS.yml | 92 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index ccf6b933bf6..883f9afed53 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -184,6 +184,26 @@ ARM64 arch: labels: - "area: ARM64" +ARM Platforms: + status: odd fixes + files: + - boards/arm/mps*/ + - soc/arm/arm/ + - boards/arm/v2m_*/ + labels: + - "platform: ARM" + +ARM SiP SVC: + status: odd fixes + files: + - subsys/sip_svc/ + - tests/subsys/sip_svc/ + - include/zephyr/sip_svc/ + - include/zephyr/drivers/sip_svc/ + - drivers/sip_svc/ + labels: + - "area: ARM SiP SVC" + MIPS arch: status: odd fixes files: @@ -231,6 +251,7 @@ Binary Descriptors: - include/zephyr/bindesc.h - samples/subsys/bindesc/ - scripts/west_commands/bindesc.py + - tests/subsys/bindesc/ labels: - "area: Binary Descriptors" @@ -413,6 +434,20 @@ Board/SoC configuration: labels: - "area: C++" +Cache: + status: maintained + maintainers: + - carlocaione + collaborators: + - nashif + files: + - include/zephyr/drivers/cache.h + - include/zephyr/cache.h + - doc/hardware/cache/index.rst + - drivers/cache/ + labels: + - "area: Cache" + C library: status: maintained maintainers: @@ -433,7 +468,7 @@ CMSIS API layer: collaborators: - nashif files: - - subsys/portability/cmsis_rtos_v*/ + - subsys/portability/ - include/zephyr/portability/cmsis* - samples/subsys/portability/cmsis_rtos_v*/ - tests/subsys/portability/cmsis_rtos_v*/ @@ -523,6 +558,7 @@ Common Architecture Interface: - arch/common/ - include/zephyr/arch/common/ - tests/arch/common/ + - doc/hardware/porting/arch.rst labels: - "area: Architectures" @@ -551,7 +587,6 @@ Debug: labels: - "area: Debugging" - Demand Paging: status: maintained maintainers: @@ -614,6 +649,7 @@ Devicetree Bindings: - galak files: - dts/bindings/ + - include/zephyr/dt-bindings/ labels: - "area: Devicetree Binding" @@ -1226,7 +1262,7 @@ Release Notes: - dts/bindings/modem/ - include/zephyr/drivers/modem/ labels: - - "area: Modem" + - "area: Modem Drivers" "Drivers: Regulators": status: maintained @@ -1255,6 +1291,7 @@ Release Notes: - dts/bindings/retained_mem/ - include/zephyr/drivers/retained_mem.h - tests/drivers/retained_mem/ + - doc/hardware/peripherals/retained_mem.rst labels: - "area: Retained Memory" @@ -1703,6 +1740,8 @@ Kconfig: - scripts/kconfig/ - doc/build/kconfig/ - Kconfig.zephyr + - tests/kconfig/configdefault/ + - tests/misc/kconfigoptions/ labels: - "area: Kconfig" description: >- @@ -1752,6 +1791,9 @@ Base OS: - lib/os/cbprintf* - lib/os/Kconfig.cbprintf - include/zephyr/sys/mem_manage.h + - include/zephyr/sys/mpsc_pbuf.h + - include/zephyr/sys/mpsc_packet.h + - lib/os/mpsc_pbuf.c labels: - "area: Base OS" @@ -1790,11 +1832,17 @@ Logging: - dcpleung files: - include/zephyr/logging/ + - include/zephyr/sys/mpsc_pbuf.h + - include/zephyr/sys/mpsc_packet.h + - lib/os/mpsc_pbuf.c + - doc/kernel/data_structures/mpsc_pbuf.rst + - tests/lib/mpsc_pbuf/ - samples/subsys/logging/ - subsys/logging/ - tests/subsys/logging/ - scripts/logging/ - doc/services/logging/ + - tests/lib/spsc_pbuf/ labels: - "area: Logging" @@ -1883,6 +1931,8 @@ Modem Modules: - tests/subsys/modem/ - doc/services/modem/ - samples/net/cellular_modem/ + labels: + - "area: Modem" OSDP: status: maintained @@ -1927,6 +1977,7 @@ Native POSIX/Sim and POSIX arch: - aescolar files: - arch/posix/ + - boards/posix/common/ - boards/posix/native_*/ - boards/posix/doc/ - boards/posix/*.rst @@ -2149,6 +2200,8 @@ NIOS-2 arch: - nashif files: - arch/nios2/ + - boards/common/nios2.board.cmake + - boards/nios2/ - soc/nios2/ - include/zephyr/arch/nios2/ - tests/boards/altera_max10/ @@ -2265,6 +2318,14 @@ Sensor Subsystem: labels: - "area: Sensor Subsystem" +Stats: + status: odd fixes + files: + - subsys/stats/ + - include/zephyr/stats/stats.h + labels: + - "area: Stats" + Twister: status: maintained maintainers: @@ -2285,6 +2346,7 @@ Twister: - doc/develop/test/twister.rst - scripts/pylib/pytest-twister-harness/ - doc/develop/test/pytest.rst + - tests/test_config.yaml labels: - "area: Twister" @@ -2530,6 +2592,7 @@ Intel Platforms (Xtensa): - tests/boards/intel_adsp/ - samples/boards/intel_adsp/ - dts/bindings/*/intel,adsp* + - scripts/west_commands/runners/intel_adsp.py labels: - "platform: Intel ADSP" @@ -2600,6 +2663,7 @@ NXP Platforms: - dts/arm/nxp/ - dts/bindings/*/nxp* - soc/xtensa/nxp_adsp/ + - boards/xtensa/nxp_adsp_*/ - samples/boards/nxp*/ - include/zephyr/dt-bindings/*/nxp* - include/zephyr/drivers/*/*nxp* @@ -2901,6 +2965,18 @@ Task Watchdog: labels: - "area: Task Watchdog" +"Drivers: Time Aware GPIO": + status: maintained + maintainers: + - akanisetti + files: + - doc/hardware/peripherals/tgpio.rst + - drivers/misc/timeaware_gpio/ + - include/zephyr/drivers/misc/timeaware_gpio/ + - samples/drivers/misc/timeaware_gpio/ + labels: + - "area: Time Aware GPIO" + TF-M Integration: status: maintained maintainers: @@ -2927,6 +3003,7 @@ TF-M Integration: - cmake/linker/ - cmake/toolchain/ - include/zephyr/toolchain/ + - include/zephyr/toolchain.h labels: - "area: Toolchains" @@ -3026,6 +3103,7 @@ Userspace: collaborators: - ceolin files: + - include/zephyr/internal/syscall_handler.h - doc/kernel/usermode/kernelobjects.rst - include/zephyr/app_memory/ - include/zephyr/linker/app_smem*.ld @@ -3076,6 +3154,8 @@ West: maintainers: - najumon1980 - jhedberg + collaborators: + - tbursztyka files: - modules/acpica/ labels: @@ -3096,6 +3176,7 @@ West: - yperess files: - samples/modules/chre/ + - modules/Kconfig.chre labels: - "area: CHRE" @@ -3107,7 +3188,7 @@ West: - microbuilder - povergoing files: - - modules/cmsis/Kconfig + - modules/cmsis/ labels: - "area: ARM" @@ -3169,7 +3250,8 @@ West: collaborators: - tgorochowik - msobkowski - files: [] + files: + - modules/hal_ambiq/ labels: - "platform: Ambiq" From 76a7b3cf1c4bdf90836fa060dea73dec172b4fc4 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 21 Sep 2023 15:48:21 +0800 Subject: [PATCH 3358/4498] drivers: intc: plic: initial refactor for multi-instance support Use a config struct to store per-instance device config during init and connect the IRQ based on the devicetree instead of hardcoded value and instance number. The `get_plic_dev_from_irq` is still a placeholder for now and always return the first instance. Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/intc_plic.c | 145 ++++++++++++++++------- 1 file changed, 99 insertions(+), 46 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 42f6cbc1f06..e874de51ab6 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -36,15 +36,6 @@ */ #define PLIC_REG_TRIG_TYPE_OFFSET 0x1080 -#define PLIC_MAX_PRIO DT_INST_PROP(0, riscv_max_priority) -#define PLIC_PRIO (PLIC_BASE_ADDR(0) + PLIC_REG_PRIO_OFFSET) -#define PLIC_IRQ_EN (PLIC_BASE_ADDR(0) + PLIC_REG_IRQ_EN_OFFSET) -#define PLIC_REG (PLIC_BASE_ADDR(0) + PLIC_REG_REGS_OFFSET) - -#define PLIC_IRQS (CONFIG_NUM_IRQS - CONFIG_2ND_LVL_ISR_TBL_OFFSET) -#define PLIC_EN_SIZE ((PLIC_IRQS >> 5) + 1) - -#define PLIC_EDGE_TRIG_TYPE (PLIC_BASE_ADDR(0) + PLIC_REG_TRIG_TYPE_OFFSET) #define PLIC_EDGE_TRIG_SHIFT 5 struct plic_regs_t { @@ -52,7 +43,39 @@ struct plic_regs_t { uint32_t claim_complete; }; -static int save_irq; +typedef void (*riscv_plic_irq_config_func_t)(void); +struct plic_config { + mem_addr_t prio; + mem_addr_t irq_en; + mem_addr_t reg; + mem_addr_t trig; + uint32_t max_prio; + uint32_t num_irqs; + riscv_plic_irq_config_func_t irq_config_func; +}; + +static uint32_t save_irq; + +static inline uint32_t get_plic_enabled_size(const struct device *dev) +{ + const struct plic_config *config = dev->config; + + return (config->num_irqs >> 5) + 1; +} + +/** + * @brief Determine the PLIC device from the IRQ + * + * FIXME: This function is currently hardcoded to return the first instance. + * + * @param irq IRQ number + * + * @return PLIC device of that IRQ + */ +static inline const struct device *get_plic_dev_from_irq(uint32_t irq) +{ + return DEVICE_DT_INST_GET(0); +} /** * @brief return edge irq value or zero @@ -61,16 +84,18 @@ static int save_irq; * value of the irq. In the event edge irq is not supported this * routine will return 0 * - * @param irq IRQ number to add to the trigger + * @param dev PLIC-instance device + * @param local_irq PLIC-instance IRQ number to add to the trigger * * @return irq value when enabled 0 otherwise */ -static int riscv_plic_is_edge_irq(uint32_t irq) +static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) { - volatile uint32_t *trig = (volatile uint32_t *)PLIC_EDGE_TRIG_TYPE; + const struct plic_config *config = dev->config; + volatile uint32_t *trig = (volatile uint32_t *) config->trig; - trig += (irq >> PLIC_EDGE_TRIG_SHIFT); - return *trig & BIT(irq); + trig += (local_irq >> PLIC_EDGE_TRIG_SHIFT); + return *trig & BIT(local_irq); } /** @@ -85,8 +110,10 @@ static int riscv_plic_is_edge_irq(uint32_t irq) */ void riscv_plic_irq_enable(uint32_t irq) { + const struct device *dev = get_plic_dev_from_irq(irq); + const struct plic_config *config = dev->config; + volatile uint32_t *en = (volatile uint32_t *) config->irq_en; uint32_t key; - volatile uint32_t *en = (volatile uint32_t *)PLIC_IRQ_EN; key = irq_lock(); en += (irq >> 5); @@ -106,8 +133,10 @@ void riscv_plic_irq_enable(uint32_t irq) */ void riscv_plic_irq_disable(uint32_t irq) { + const struct device *dev = get_plic_dev_from_irq(irq); + const struct plic_config *config = dev->config; + volatile uint32_t *en = (volatile uint32_t *) config->irq_en; uint32_t key; - volatile uint32_t *en = (volatile uint32_t *)PLIC_IRQ_EN; key = irq_lock(); en += (irq >> 5); @@ -125,7 +154,9 @@ void riscv_plic_irq_disable(uint32_t irq) */ int riscv_plic_irq_is_enabled(uint32_t irq) { - volatile uint32_t *en = (volatile uint32_t *)PLIC_IRQ_EN; + const struct device *dev = get_plic_dev_from_irq(irq); + const struct plic_config *config = dev->config; + volatile uint32_t *en = (volatile uint32_t *) config->irq_en; en += (irq >> 5); return !!(*en & (1 << (irq & 31))); @@ -143,10 +174,12 @@ int riscv_plic_irq_is_enabled(uint32_t irq) */ void riscv_plic_set_priority(uint32_t irq, uint32_t priority) { - volatile uint32_t *prio = (volatile uint32_t *)PLIC_PRIO; + const struct device *dev = get_plic_dev_from_irq(irq); + const struct plic_config *config = dev->config; + volatile uint32_t *prio = (volatile uint32_t *) config->prio; - if (priority > PLIC_MAX_PRIO) - priority = PLIC_MAX_PRIO; + if (priority > config->max_prio) + priority = config->max_prio; prio += irq; *prio = priority; @@ -165,11 +198,10 @@ int riscv_plic_get_irq(void) return save_irq; } -static void plic_irq_handler(const void *arg) +static void plic_irq_handler(const struct device *dev) { - volatile struct plic_regs_t *regs = - (volatile struct plic_regs_t *) PLIC_REG; - + const struct plic_config *config = dev->config; + volatile struct plic_regs_t *regs = (volatile struct plic_regs_t *) config->reg; uint32_t irq; struct _isr_table_entry *ite; int edge_irq; @@ -189,10 +221,10 @@ static void plic_irq_handler(const void *arg) * If the IRQ is out of range, call z_irq_spurious. * A call to z_irq_spurious will not return. */ - if (irq == 0U || irq >= PLIC_IRQS) + if (irq == 0U || irq >= config->num_irqs) z_irq_spurious(NULL); - edge_irq = riscv_plic_is_edge_irq(irq); + edge_irq = riscv_plic_is_edge_irq(dev, irq); /* * For edge triggered interrupts, write to the claim_complete register @@ -220,25 +252,25 @@ static void plic_irq_handler(const void *arg) /** * @brief Initialize the Platform Level Interrupt Controller * + * @param dev PLIC device struct + * * @retval 0 on success. */ static int plic_init(const struct device *dev) { - - volatile uint32_t *en = (volatile uint32_t *)PLIC_IRQ_EN; - volatile uint32_t *prio = (volatile uint32_t *)PLIC_PRIO; - volatile struct plic_regs_t *regs = - (volatile struct plic_regs_t *)PLIC_REG; - int i; + const struct plic_config *config = dev->config; + volatile uint32_t *en = (volatile uint32_t *) config->irq_en; + volatile uint32_t *prio = (volatile uint32_t *) config->prio; + volatile struct plic_regs_t *regs = (volatile struct plic_regs_t *) config->reg; /* Ensure that all interrupts are disabled initially */ - for (i = 0; i < PLIC_EN_SIZE; i++) { + for (uint32_t i = 0; i < get_plic_enabled_size(dev); i++) { *en = 0U; en++; } /* Set priority of each interrupt line to 0 initially */ - for (i = 0; i < PLIC_IRQS; i++) { + for (uint32_t i = 0; i < config->num_irqs; i++) { *prio = 0U; prio++; } @@ -246,18 +278,39 @@ static int plic_init(const struct device *dev) /* Set threshold priority to 0 */ regs->threshold_prio = 0U; - /* Setup IRQ handler for PLIC driver */ - IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, - 0, - plic_irq_handler, - NULL, - 0); - - /* Enable IRQ for PLIC driver */ - irq_enable(RISCV_MACHINE_EXT_IRQ); + /* Configure IRQ for PLIC driver */ + config->irq_config_func(); return 0; } -DEVICE_DT_INST_DEFINE(0, plic_init, NULL, NULL, NULL, - PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); +#define PLIC_INTC_IRQ_FUNC_DECLARE(n) static void plic_irq_config_func_##n(void) + +#define PLIC_INTC_IRQ_FUNC_DEFINE(n) \ + static void plic_irq_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), 0, plic_irq_handler, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +#define PLIC_INTC_CONFIG_INIT(n) \ + PLIC_INTC_IRQ_FUNC_DECLARE(n); \ + static const struct plic_config plic_config_##n = { \ + .prio = PLIC_BASE_ADDR(n) + PLIC_REG_PRIO_OFFSET, \ + .irq_en = PLIC_BASE_ADDR(n) + PLIC_REG_IRQ_EN_OFFSET, \ + .reg = PLIC_BASE_ADDR(n) + PLIC_REG_REGS_OFFSET, \ + .trig = PLIC_BASE_ADDR(n) + PLIC_REG_TRIG_TYPE_OFFSET, \ + .max_prio = DT_INST_PROP(n, riscv_max_priority), \ + .num_irqs = DT_INST_PROP(n, riscv_ndev), \ + .irq_config_func = plic_irq_config_func_##n, \ + }; \ + PLIC_INTC_IRQ_FUNC_DEFINE(n) + +#define PLIC_INTC_DEVICE_INIT(n) \ + PLIC_INTC_CONFIG_INIT(n) \ + DEVICE_DT_INST_DEFINE(n, &plic_init, NULL, \ + NULL, &plic_config_##n, \ + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(PLIC_INTC_DEVICE_INIT) From e538b0e5a67e1ecc3073f892d8ff5e0d608793bd Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 20 Sep 2023 18:01:35 +0800 Subject: [PATCH 3359/4498] drivers: plic: support multiple instances for multi-level Most of the public APIs in `riscv_plic.h` (except `riscv_plic_get_irq` & `riscv_plic_get_dev`) expect the `irq` argument to be in Zephyr-encoded format, instead of the previously `irq_from_level_2`-stripped version. The first level IRQ is needed by `intc_plic` to differentiate between the parent interrupt controllers, so that correct ISR offset can be obtained using the LUT in `sw_isr_common`. Signed-off-by: Yong Cong Sin --- arch/riscv/core/irq_manage.c | 8 +-- drivers/interrupt_controller/CMakeLists.txt | 2 + drivers/interrupt_controller/intc_plic.c | 60 ++++++++++++------- .../drivers/interrupt_controller/riscv_plic.h | 19 ++++-- .../riscv-privileged/common/soc_common_irq.c | 4 -- 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index f0a0eae2cd0..e0ef1374bf1 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -25,8 +25,10 @@ FUNC_NORETURN void z_irq_spurious(const void *unused) LOG_ERR("Spurious interrupt detected! IRQ: %ld", mcause); #if defined(CONFIG_RISCV_HAS_PLIC) if (mcause == RISCV_MACHINE_EXT_IRQ) { - LOG_ERR("PLIC interrupt line causing the IRQ: %d", - riscv_plic_get_irq()); + unsigned int save_irq = riscv_plic_get_irq(); + const struct device *save_dev = riscv_plic_get_dev(); + + LOG_ERR("PLIC interrupt line causing the IRQ: %d (%p)", save_irq, save_dev); } #endif z_riscv_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); @@ -43,8 +45,6 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, #if defined(CONFIG_RISCV_HAS_PLIC) if (irq_get_level(irq) == 2) { - irq = irq_from_level_2(irq); - riscv_plic_set_priority(irq, priority); } #else diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 71e3435e49a..5598d038940 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -41,3 +41,5 @@ zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ICU intc_ra_icu.c) if(CONFIG_INTEL_VTD_ICTL) zephyr_library_include_directories(${ZEPHYR_BASE}/arch/x86/include) endif() + +zephyr_library_include_directories(${ZEPHYR_BASE}/arch/common/include) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index e874de51ab6..7bfe6c288ea 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -12,6 +12,8 @@ * for RISC-V processors */ +#include "sw_isr_common.h" + #include #include #include @@ -55,6 +57,7 @@ struct plic_config { }; static uint32_t save_irq; +static const struct device *save_dev; static inline uint32_t get_plic_enabled_size(const struct device *dev) { @@ -66,15 +69,16 @@ static inline uint32_t get_plic_enabled_size(const struct device *dev) /** * @brief Determine the PLIC device from the IRQ * - * FIXME: This function is currently hardcoded to return the first instance. - * * @param irq IRQ number * * @return PLIC device of that IRQ */ static inline const struct device *get_plic_dev_from_irq(uint32_t irq) { - return DEVICE_DT_INST_GET(0); + const struct device *dev = COND_CODE_1(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), + (z_get_sw_isr_device_from_irq(irq)), (NULL)); + + return dev == NULL ? DEVICE_DT_INST_GET(0) : dev; } /** @@ -113,11 +117,12 @@ void riscv_plic_irq_enable(uint32_t irq) const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; volatile uint32_t *en = (volatile uint32_t *) config->irq_en; + const uint32_t local_irq = irq_from_level_2(irq); uint32_t key; key = irq_lock(); - en += (irq >> 5); - *en |= (1 << (irq & 31)); + en += (local_irq >> 5); + *en |= (1 << (local_irq & 31)); irq_unlock(key); } @@ -136,11 +141,12 @@ void riscv_plic_irq_disable(uint32_t irq) const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; volatile uint32_t *en = (volatile uint32_t *) config->irq_en; + const uint32_t local_irq = irq_from_level_2(irq); uint32_t key; key = irq_lock(); - en += (irq >> 5); - *en &= ~(1 << (irq & 31)); + en += (local_irq >> 5); + *en &= ~(1 << (local_irq & 31)); irq_unlock(key); } @@ -157,9 +163,10 @@ int riscv_plic_irq_is_enabled(uint32_t irq) const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; volatile uint32_t *en = (volatile uint32_t *) config->irq_en; + const uint32_t local_irq = irq_from_level_2(irq); - en += (irq >> 5); - return !!(*en & (1 << (irq & 31))); + en += (local_irq >> 5); + return !!(*en & (1 << (local_irq & 31))); } /** @@ -177,11 +184,12 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t priority) const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; volatile uint32_t *prio = (volatile uint32_t *) config->prio; + const uint32_t local_irq = irq_from_level_2(irq); if (priority > config->max_prio) priority = config->max_prio; - prio += irq; + prio += local_irq; *prio = priority; } @@ -191,23 +199,29 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t priority) * This routine returns the RISCV PLIC-specific interrupt line causing an * interrupt. * + * @param dev Optional device pointer to get the interrupt line's controller + * * @return PLIC-specific interrupt line causing an interrupt. */ -int riscv_plic_get_irq(void) +unsigned int riscv_plic_get_irq(void) { return save_irq; } +const struct device *riscv_plic_get_dev(void) +{ + return save_dev; +} + static void plic_irq_handler(const struct device *dev) { const struct plic_config *config = dev->config; volatile struct plic_regs_t *regs = (volatile struct plic_regs_t *) config->reg; - uint32_t irq; struct _isr_table_entry *ite; int edge_irq; /* Get the IRQ number generating the interrupt */ - irq = regs->claim_complete; + const uint32_t local_irq = regs->claim_complete; /* * Save IRQ in save_irq. To be used, if need be, by @@ -215,16 +229,17 @@ static void plic_irq_handler(const struct device *dev) * as IRQ number held by the claim_complete register is * cleared upon read. */ - save_irq = irq; + save_irq = local_irq; + save_dev = dev; /* * If the IRQ is out of range, call z_irq_spurious. * A call to z_irq_spurious will not return. */ - if (irq == 0U || irq >= config->num_irqs) + if (local_irq == 0U || local_irq >= config->num_irqs) z_irq_spurious(NULL); - edge_irq = riscv_plic_is_edge_irq(dev, irq); + edge_irq = riscv_plic_is_edge_irq(dev, local_irq); /* * For edge triggered interrupts, write to the claim_complete register @@ -232,12 +247,17 @@ static void plic_irq_handler(const struct device *dev) * for edge triggered interrupts. */ if (edge_irq) - regs->claim_complete = save_irq; + regs->claim_complete = local_irq; - irq += CONFIG_2ND_LVL_ISR_TBL_OFFSET; + const uint32_t parent_irq = COND_CODE_1(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), + (z_get_sw_isr_irq_from_device(dev)), (0U)); + const uint32_t irq = irq_to_level_2(local_irq) | parent_irq; + const unsigned int isr_offset = + COND_CODE_1(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), (z_get_sw_isr_table_idx(irq)), + (irq_from_level_2(irq) + CONFIG_2ND_LVL_ISR_TBL_OFFSET)); /* Call the corresponding IRQ handler in _sw_isr_table */ - ite = (struct _isr_table_entry *)&_sw_isr_table[irq]; + ite = (struct _isr_table_entry *)&_sw_isr_table[isr_offset]; ite->isr(ite->arg); /* @@ -246,7 +266,7 @@ static void plic_irq_handler(const struct device *dev) * for level triggered interrupts. */ if (!edge_irq) - regs->claim_complete = save_irq; + regs->claim_complete = local_irq; } /** diff --git a/include/zephyr/drivers/interrupt_controller/riscv_plic.h b/include/zephyr/drivers/interrupt_controller/riscv_plic.h index 1cec5cc8109..22c57a4b696 100644 --- a/include/zephyr/drivers/interrupt_controller/riscv_plic.h +++ b/include/zephyr/drivers/interrupt_controller/riscv_plic.h @@ -12,24 +12,26 @@ #ifndef ZEPHYR_INCLUDE_DRIVERS_RISCV_PLIC_H_ #define ZEPHYR_INCLUDE_DRIVERS_RISCV_PLIC_H_ +#include + /** * @brief Enable interrupt * - * @param irq interrupt ID + * @param irq Multi-level encoded interrupt ID */ void riscv_plic_irq_enable(uint32_t irq); /** * @brief Disable interrupt * - * @param irq interrupt ID + * @param irq Multi-level encoded interrupt ID */ void riscv_plic_irq_disable(uint32_t irq); /** * @brief Check if an interrupt is enabled * - * @param irq interrupt ID + * @param irq Multi-level encoded interrupt ID * @return Returns true if interrupt is enabled, false otherwise */ int riscv_plic_irq_is_enabled(uint32_t irq); @@ -37,7 +39,7 @@ int riscv_plic_irq_is_enabled(uint32_t irq); /** * @brief Set interrupt priority * - * @param irq interrupt ID + * @param irq Multi-level encoded interrupt ID * @param prio interrupt priority */ void riscv_plic_set_priority(uint32_t irq, uint32_t prio); @@ -47,6 +49,13 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t prio); * * @return Returns the ID of an active interrupt */ -int riscv_plic_get_irq(void); +unsigned int riscv_plic_get_irq(void); + +/** + * @brief Get active interrupt controller device + * + * @return Returns device pointer of the active interrupt device + */ +const struct device *riscv_plic_get_dev(void); #endif /* ZEPHYR_INCLUDE_DRIVERS_RISCV_PLIC_H_ */ diff --git a/soc/riscv/riscv-privileged/common/soc_common_irq.c b/soc/riscv/riscv-privileged/common/soc_common_irq.c index f33e4dceeef..24aee37bdaf 100644 --- a/soc/riscv/riscv-privileged/common/soc_common_irq.c +++ b/soc/riscv/riscv-privileged/common/soc_common_irq.c @@ -47,7 +47,6 @@ void arch_irq_enable(unsigned int irq) unsigned int level = irq_get_level(irq); if (level == 2) { - irq = irq_from_level_2(irq); riscv_plic_irq_enable(irq); return; } @@ -68,7 +67,6 @@ void arch_irq_disable(unsigned int irq) unsigned int level = irq_get_level(irq); if (level == 2) { - irq = irq_from_level_2(irq); riscv_plic_irq_disable(irq); return; } @@ -89,7 +87,6 @@ int arch_irq_is_enabled(unsigned int irq) unsigned int level = irq_get_level(irq); if (level == 2) { - irq = irq_from_level_2(irq); return riscv_plic_irq_is_enabled(irq); } #endif @@ -105,7 +102,6 @@ void z_riscv_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flag unsigned int level = irq_get_level(irq); if (level == 2) { - irq = irq_from_level_2(irq); riscv_plic_set_priority(irq, prio); } } From efd1073ceb798d5c246a36c990090e6af738b65f Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 21 Sep 2023 16:45:10 +0800 Subject: [PATCH 3360/4498] tests: build_all: plic: multi instance Add PLIC multi-instance build-only test. Signed-off-by: Yong Cong Sin --- .../interrupt_controller/intc_plic/Kconfig | 7 ++++ .../intc_plic/app.multi_instance.overlay | 38 +++++++++++++++++++ .../intc_plic/testcase.yaml | 10 +++++ 3 files changed, 55 insertions(+) create mode 100644 tests/drivers/build_all/interrupt_controller/intc_plic/Kconfig create mode 100644 tests/drivers/build_all/interrupt_controller/intc_plic/app.multi_instance.overlay diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/Kconfig b/tests/drivers/build_all/interrupt_controller/intc_plic/Kconfig new file mode 100644 index 00000000000..6d7b572d877 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/Kconfig @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config NUM_IRQS + int "" + +source "Kconfig" diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/app.multi_instance.overlay b/tests/drivers/build_all/interrupt_controller/intc_plic/app.multi_instance.overlay new file mode 100644 index 00000000000..93d8c626aa7 --- /dev/null +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/app.multi_instance.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + + /{ + soc { + plic1: interrupt-controller@8000000 { + riscv,max-priority = <7>; + riscv,ndev = <0x35>; + reg = <0x08000000 0x04000000>; + interrupts-extended = < + &hlic0 0x03 + &hlic1 0x03 + &hlic2 0x03 + &hlic3 0x03 + &hlic4 0x03 + &hlic5 0x03 + &hlic6 0x03 + &hlic7 0x03 + >; + interrupt-controller; + compatible = "sifive,plic-1.0.0"; + #address-cells = <0x00>; + #interrupt-cells = <0x02>; + }; + }; + + uart1: uart@10000100 { + interrupts = <0x0a 1>; + interrupt-parent = <&plic1>; + clock-frequency = <0x384000>; + reg = <0x10000100 0x100>; + compatible = "ns16550"; + reg-shift = <0>; + }; +}; diff --git a/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml index 6d6164a3bed..ea80ccf8d26 100644 --- a/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml +++ b/tests/drivers/build_all/interrupt_controller/intc_plic/testcase.yaml @@ -10,3 +10,13 @@ common: - plic tests: drivers.interrupt_controller.intc_plic.build: {} + drivers.interrupt_controller.intc_plic.multi_instance.build: + extra_args: + DTC_OVERLAY_FILE="./app.multi_instance.overlay" + extra_configs: + - CONFIG_NUM_IRQS=116 + - CONFIG_MULTI_LEVEL_INTERRUPTS=y + - CONFIG_DYNAMIC_INTERRUPTS=y + - CONFIG_NUM_2ND_LEVEL_AGGREGATORS=2 + - CONFIG_2ND_LVL_INTR_01_OFFSET=3 + - CONFIG_UART_INTERRUPT_DRIVEN=y From 980fb4b84674af35c2870523a4ecf9a30cfd64fe Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 25 Sep 2023 15:44:39 +0800 Subject: [PATCH 3361/4498] drivers: intc: plic: make sense of magic number Added some defines and helper functions to help with the arithmetics so that the bit shifts and stuff do not look like magic number. Converted manual bit shift/set/unset to use macros provided by Zephyr. Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/intc_plic.c | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 7bfe6c288ea..7ced9580123 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -38,7 +38,9 @@ */ #define PLIC_REG_TRIG_TYPE_OFFSET 0x1080 -#define PLIC_EDGE_TRIG_SHIFT 5 +/* PLIC registers are 32-bit memory-mapped */ +#define PLIC_REG_SIZE 32 +#define PLIC_REG_MASK BIT_MASK(LOG2(PLIC_REG_SIZE)) struct plic_regs_t { uint32_t threshold_prio; @@ -59,11 +61,16 @@ struct plic_config { static uint32_t save_irq; static const struct device *save_dev; +static inline uint32_t local_irq_to_reg_offset(uint32_t local_irq) +{ + return local_irq >> LOG2(PLIC_REG_SIZE); +} + static inline uint32_t get_plic_enabled_size(const struct device *dev) { const struct plic_config *config = dev->config; - return (config->num_irqs >> 5) + 1; + return local_irq_to_reg_offset(config->num_irqs) + 1; } /** @@ -98,7 +105,7 @@ static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) const struct plic_config *config = dev->config; volatile uint32_t *trig = (volatile uint32_t *) config->trig; - trig += (local_irq >> PLIC_EDGE_TRIG_SHIFT); + trig += local_irq_to_reg_offset(local_irq); return *trig & BIT(local_irq); } @@ -121,8 +128,8 @@ void riscv_plic_irq_enable(uint32_t irq) uint32_t key; key = irq_lock(); - en += (local_irq >> 5); - *en |= (1 << (local_irq & 31)); + en += local_irq_to_reg_offset(local_irq); + WRITE_BIT(*en, local_irq & PLIC_REG_MASK, true); irq_unlock(key); } @@ -145,8 +152,8 @@ void riscv_plic_irq_disable(uint32_t irq) uint32_t key; key = irq_lock(); - en += (local_irq >> 5); - *en &= ~(1 << (local_irq & 31)); + en += local_irq_to_reg_offset(local_irq); + WRITE_BIT(*en, local_irq & PLIC_REG_MASK, false); irq_unlock(key); } @@ -165,8 +172,8 @@ int riscv_plic_irq_is_enabled(uint32_t irq) volatile uint32_t *en = (volatile uint32_t *) config->irq_en; const uint32_t local_irq = irq_from_level_2(irq); - en += (local_irq >> 5); - return !!(*en & (1 << (local_irq & 31))); + en += local_irq_to_reg_offset(local_irq); + return !!(*en & BIT(local_irq & PLIC_REG_MASK)); } /** From ffb8f31bffd39b3a21e99e31deb7555d0585d81c Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 26 Sep 2023 14:43:22 +0800 Subject: [PATCH 3362/4498] drivers: intc: plic: Use sys IO APIs to access memory-mapped registers Use arch-specific sys IO APIs to access the memory-mapped registers to ensure safe memory operations fixes #62956 Signed-off-by: Yong Cong Sin --- drivers/interrupt_controller/intc_plic.c | 79 ++++++++++++++---------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 7ced9580123..41ee75823b0 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Jean-Paul Etienne + * Copyright (c) 2023 Meta * Contributors: 2018 Antmicro * * SPDX-License-Identifier: Apache-2.0 @@ -31,6 +32,8 @@ #define PLIC_REG_PRIO_OFFSET 0x0 #define PLIC_REG_IRQ_EN_OFFSET 0x2000 #define PLIC_REG_REGS_OFFSET 0x200000 +#define PLIC_REG_REGS_THRES_PRIORITY_OFFSET 0 +#define PLIC_REG_REGS_CLAIM_COMPLETE_OFFSET sizeof(uint32_t) /* * Trigger type is mentioned, but not defined in the RISCV PLIC specs. * However, it is defined and supported by at least the Andes & Telink datasheet, and supported @@ -42,11 +45,6 @@ #define PLIC_REG_SIZE 32 #define PLIC_REG_MASK BIT_MASK(LOG2(PLIC_REG_SIZE)) -struct plic_regs_t { - uint32_t threshold_prio; - uint32_t claim_complete; -}; - typedef void (*riscv_plic_irq_config_func_t)(void); struct plic_config { mem_addr_t prio; @@ -73,6 +71,20 @@ static inline uint32_t get_plic_enabled_size(const struct device *dev) return local_irq_to_reg_offset(config->num_irqs) + 1; } +static inline uint32_t get_claim_complete_offset(const struct device *dev) +{ + const struct plic_config *config = dev->config; + + return config->reg + PLIC_REG_REGS_CLAIM_COMPLETE_OFFSET; +} + +static inline uint32_t get_threshold_priority_offset(const struct device *dev) +{ + const struct plic_config *config = dev->config; + + return config->reg + PLIC_REG_REGS_THRES_PRIORITY_OFFSET; +} + /** * @brief Determine the PLIC device from the IRQ * @@ -103,10 +115,9 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq) static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) { const struct plic_config *config = dev->config; - volatile uint32_t *trig = (volatile uint32_t *) config->trig; + mem_addr_t trig_addr = config->trig + local_irq_to_reg_offset(local_irq); - trig += local_irq_to_reg_offset(local_irq); - return *trig & BIT(local_irq); + return sys_read32(trig_addr) & BIT(local_irq); } /** @@ -123,13 +134,15 @@ void riscv_plic_irq_enable(uint32_t irq) { const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; - volatile uint32_t *en = (volatile uint32_t *) config->irq_en; const uint32_t local_irq = irq_from_level_2(irq); + mem_addr_t en_addr = config->irq_en + local_irq_to_reg_offset(local_irq); + uint32_t en_value; uint32_t key; key = irq_lock(); - en += local_irq_to_reg_offset(local_irq); - WRITE_BIT(*en, local_irq & PLIC_REG_MASK, true); + en_value = sys_read32(en_addr); + WRITE_BIT(en_value, local_irq & PLIC_REG_MASK, true); + sys_write32(en_value, en_addr); irq_unlock(key); } @@ -147,13 +160,15 @@ void riscv_plic_irq_disable(uint32_t irq) { const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; - volatile uint32_t *en = (volatile uint32_t *) config->irq_en; const uint32_t local_irq = irq_from_level_2(irq); + mem_addr_t en_addr = config->irq_en + local_irq_to_reg_offset(local_irq); + uint32_t en_value; uint32_t key; key = irq_lock(); - en += local_irq_to_reg_offset(local_irq); - WRITE_BIT(*en, local_irq & PLIC_REG_MASK, false); + en_value = sys_read32(en_addr); + WRITE_BIT(en_value, local_irq & PLIC_REG_MASK, false); + sys_write32(en_value, en_addr); irq_unlock(key); } @@ -169,11 +184,14 @@ int riscv_plic_irq_is_enabled(uint32_t irq) { const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; - volatile uint32_t *en = (volatile uint32_t *) config->irq_en; const uint32_t local_irq = irq_from_level_2(irq); + mem_addr_t en_addr = config->irq_en + local_irq_to_reg_offset(local_irq); + uint32_t en_value; + + en_value = sys_read32(en_addr); + en_value &= BIT(local_irq & PLIC_REG_MASK); - en += local_irq_to_reg_offset(local_irq); - return !!(*en & BIT(local_irq & PLIC_REG_MASK)); + return !!en_value; } /** @@ -190,14 +208,13 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t priority) { const struct device *dev = get_plic_dev_from_irq(irq); const struct plic_config *config = dev->config; - volatile uint32_t *prio = (volatile uint32_t *) config->prio; const uint32_t local_irq = irq_from_level_2(irq); + mem_addr_t prio_addr = config->prio + (local_irq * sizeof(uint32_t)); if (priority > config->max_prio) priority = config->max_prio; - prio += local_irq; - *prio = priority; + sys_write32(priority, prio_addr); } /** @@ -223,12 +240,12 @@ const struct device *riscv_plic_get_dev(void) static void plic_irq_handler(const struct device *dev) { const struct plic_config *config = dev->config; - volatile struct plic_regs_t *regs = (volatile struct plic_regs_t *) config->reg; + mem_addr_t claim_complete_addr = get_claim_complete_offset(dev); struct _isr_table_entry *ite; int edge_irq; /* Get the IRQ number generating the interrupt */ - const uint32_t local_irq = regs->claim_complete; + const uint32_t local_irq = sys_read32(claim_complete_addr); /* * Save IRQ in save_irq. To be used, if need be, by @@ -254,7 +271,7 @@ static void plic_irq_handler(const struct device *dev) * for edge triggered interrupts. */ if (edge_irq) - regs->claim_complete = local_irq; + sys_write32(local_irq, claim_complete_addr); const uint32_t parent_irq = COND_CODE_1(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), (z_get_sw_isr_irq_from_device(dev)), (0U)); @@ -273,7 +290,7 @@ static void plic_irq_handler(const struct device *dev) * for level triggered interrupts. */ if (!edge_irq) - regs->claim_complete = local_irq; + sys_write32(local_irq, claim_complete_addr); } /** @@ -286,24 +303,22 @@ static void plic_irq_handler(const struct device *dev) static int plic_init(const struct device *dev) { const struct plic_config *config = dev->config; - volatile uint32_t *en = (volatile uint32_t *) config->irq_en; - volatile uint32_t *prio = (volatile uint32_t *) config->prio; - volatile struct plic_regs_t *regs = (volatile struct plic_regs_t *) config->reg; + mem_addr_t en_addr = config->irq_en; + mem_addr_t prio_addr = config->prio; + mem_addr_t thres_prio_addr = get_threshold_priority_offset(dev); /* Ensure that all interrupts are disabled initially */ for (uint32_t i = 0; i < get_plic_enabled_size(dev); i++) { - *en = 0U; - en++; + sys_write32(0U, en_addr + (i * sizeof(uint32_t))); } /* Set priority of each interrupt line to 0 initially */ for (uint32_t i = 0; i < config->num_irqs; i++) { - *prio = 0U; - prio++; + sys_write32(0U, prio_addr + (i * sizeof(uint32_t))); } /* Set threshold priority to 0 */ - regs->threshold_prio = 0U; + sys_write32(0U, thres_prio_addr); /* Configure IRQ for PLIC driver */ config->irq_config_func(); From d45d323da2a5f443c2933e70a2ffaedf3097aeae Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 14:05:44 +0300 Subject: [PATCH 3363/4498] manifest: Bump up hal_xtensa revision Bump up hal_xtensa revision to contain the overlays for i.MX8QM and i.MX8QXP. Signed-off-by: Laurentiu Mihalcea --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 17fe8066384..9f1317eb21d 100644 --- a/west.yml +++ b/west.yml @@ -249,7 +249,7 @@ manifest: groups: - hal - name: hal_xtensa - revision: e6da34fc07dfe96161ab8743f5dbeb6e6307ab93 + revision: 08325d6fb7190a105f5382d35e64ed2812c57cf4 path: modules/hal/xtensa groups: - hal From 5e7a9e5e9f1e813f07469fc1f000d19d3eb6f034 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Mon, 16 Oct 2023 14:13:44 +0300 Subject: [PATCH 3364/4498] manifest: Bump up hal_nxp revision Bump up hal_nxp revision to contain the HAL headers for i.MX8QM's and i.MX8QXP's DSP. Signed-off-by: Laurentiu Mihalcea --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9f1317eb21d..6a9d1e743bb 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 3731aefd0cd55f8507498c336b3256268ecd9d61 + revision: d5e5358e56542b94bc65b6483396f50ed8f3172d path: modules/hal/nxp groups: - hal From a0ecc05cdfa52d5b501ed8a25986767501ae57a1 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 10:18:13 +0300 Subject: [PATCH 3365/4498] soc: xtensa: imx8: Split generic i.MX8 SoC into i.MX8QXP and i.MX8QM This commit attempts to split the generic i.MX8 SoC into its QXP and QM variants. As things are now, the i.MX8 SoC doesn't have any NXP HAL files to back it up. As a consequence, the native Zephyr drivers cannot be used. To solve this issue, the generic i.MX8 has been split into i.MX8QXP and i.MX8QM, each of them having different NXP HAL files. Signed-off-by: Laurentiu Mihalcea --- boards/xtensa/nxp_adsp_imx8/Kconfig.board | 2 ++ .../nxp_adsp_imx8/nxp_adsp_imx8_defconfig | 1 + boards/xtensa/nxp_adsp_imx8x/Kconfig.board | 2 ++ .../nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig | 1 + .../nxp_adsp/imx8/Kconfig.defconfig.imx8qm | 9 ++++++++ .../nxp_adsp/imx8/Kconfig.defconfig.imx8qxp | 9 ++++++++ .../nxp_adsp/imx8/Kconfig.defconfig.series | 6 ++---- soc/xtensa/nxp_adsp/imx8/Kconfig.soc | 21 +++++++++++++++++-- soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qm | 17 +++++++++++++++ soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qxp | 21 +++++++++++++++++++ 10 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qm create mode 100644 soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qxp create mode 100644 soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qm create mode 100644 soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qxp diff --git a/boards/xtensa/nxp_adsp_imx8/Kconfig.board b/boards/xtensa/nxp_adsp_imx8/Kconfig.board index e24c0a45316..4bb4f564040 100644 --- a/boards/xtensa/nxp_adsp_imx8/Kconfig.board +++ b/boards/xtensa/nxp_adsp_imx8/Kconfig.board @@ -5,3 +5,5 @@ config BOARD_NXP_ADSP_IMX8 bool "NXP ADSP i.MX8" + depends on SOC_SERIES_NXP_IMX8 + select SOC_PART_NUMBER_MIMX8QM6AVUFF diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig index 3d0c02d5017..2a2a34f0329 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig @@ -3,6 +3,7 @@ CONFIG_MAIN_STACK_SIZE=3072 CONFIG_SOC_SERIES_NXP_IMX8=y +CONFIG_SOC_MIMX8QM_ADSP=y CONFIG_BOARD_NXP_ADSP_IMX8=y CONFIG_GEN_ISR_TABLES=y diff --git a/boards/xtensa/nxp_adsp_imx8x/Kconfig.board b/boards/xtensa/nxp_adsp_imx8x/Kconfig.board index 7f4f7e0e3f9..7d5336ce7a7 100644 --- a/boards/xtensa/nxp_adsp_imx8x/Kconfig.board +++ b/boards/xtensa/nxp_adsp_imx8x/Kconfig.board @@ -5,3 +5,5 @@ config BOARD_NXP_ADSP_IMX8X bool "NXP ADSP i.MX8X" + depends on SOC_SERIES_NXP_IMX8 + select SOC_PART_NUMBER_MIMX8QX6AVLFZ diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig index 92a66362cd0..a424e54cd52 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig @@ -3,6 +3,7 @@ CONFIG_MAIN_STACK_SIZE=3072 CONFIG_SOC_SERIES_NXP_IMX8=y +CONFIG_SOC_MIMX8QXP_ADSP=y CONFIG_BOARD_NXP_ADSP_IMX8X=y CONFIG_GEN_ISR_TABLES=y diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qm b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qm new file mode 100644 index 00000000000..e678be83592 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qm @@ -0,0 +1,9 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX8QM_ADSP + +config SOC + default "mimx8qm6" + +endif # SOC_MIMX8QM_ADSP diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qxp b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qxp new file mode 100644 index 00000000000..e4fcdd92fd0 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8qxp @@ -0,0 +1,9 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX8QXP_ADSP + +config SOC + default "mimx8qx6" + +endif # SOC_MIMX8QXP_ADSP diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series index 1976bc11912..517e2c52a8e 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series @@ -11,10 +11,6 @@ config SOC_TOOLCHAIN_NAME string default "nxp_imx_adsp" -config SOC - string - default "nxp_imx8" - config SYS_CLOCK_HW_CYCLES_PER_SEC default 666000000 if XTENSA_TIMER @@ -27,4 +23,6 @@ config DYNAMIC_INTERRUPTS config LOG default y +source "soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8q*" + endif # SOC_SERIES_NXP_IMX8 diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.soc b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc index 16c36eb8a6e..33794a85c2b 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.soc +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc @@ -3,9 +3,26 @@ choice prompt "NXP i.MX SoC Selection" + depends on SOC_SERIES_NXP_IMX8 - config SOC_NXP_IMX8 - bool "i.MX8 SoC" + config SOC_MIMX8QM_ADSP + bool "NXP i.MX8QM Audio DSP" depends on SOC_SERIES_NXP_IMX8 + select HAS_MCUX + config SOC_MIMX8QXP_ADSP + bool "NXP i.MX8QXP Audio DSP" + depends on SOC_SERIES_NXP_IMX8 + select HAS_MCUX endchoice + +if SOC_SERIES_NXP_IMX8 + +config SOC_PART_NUMBER + string + default SOC_PART_NUMBER_MIMX8QM_DSP if SOC_MIMX8QM_ADSP + default SOC_PART_NUMBER_MIMX8QXP_DSP if SOC_MIMX8QXP_ADSP + +source "soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8q*" + +endif # SOC_SERIES_NXP_IMX8 diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qm b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qm new file mode 100644 index 00000000000..fd5334cfee5 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qm @@ -0,0 +1,17 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX8QM_ADSP + +config SOC_PART_NUMBER_MIMX8QM6AVUFF + bool + +config SOC_PART_NUMBER_MIMX8QM_DSP + string + default "MIMX8QM6AVUFF_dsp" if SOC_PART_NUMBER_MIMX8QM6AVUFF + help + This string holds the full part number of the SoC. It is a hidden + option that you should not set directly. The part number selection + choice defines the default value for this string. + +endif # SOC_MIMX8QM_ADSP diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qxp b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qxp new file mode 100644 index 00000000000..20f0a13e117 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.soc.imx8qxp @@ -0,0 +1,21 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX8QXP_ADSP + +config SOC_PART_NUMBER_MIMX8QX6AVLFZ + bool + +config SOC_PART_NUMBER_MIMX8QX6CVLDZ + bool + +config SOC_PART_NUMBER_MIMX8QXP_DSP + string + default "MIMX8QX6AVLFZ_dsp" if SOC_PART_NUMBER_MIMX8QX6AVLFZ + default "MIMX8QX6CVLDZ_dsp" if SOC_PART_NUMBER_MIMX8QX6CVLDZ + help + This string holds the full part number of the SoC. It is a hidden + option that you should not set directly. The part number selection + choice defines the default value for this string. + +endif # SOC_MIMX8QXP_ADSP From f29d6edece913b2f2ee417d382b2d02f63ab3a0b Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 10:23:06 +0300 Subject: [PATCH 3366/4498] soc: xtensa: imx8: Remove include/soc directory Since platform.h is a SOF-specific header that's no longer used there's no point in keeping the include/soc directory. As such, move memory.h to include/ and modify the linker script to reflect this location change. Signed-off-by: Laurentiu Mihalcea --- .../nxp_adsp/imx8/include/{soc => }/memory.h | 0 .../nxp_adsp/imx8/include/soc/platform.h | 21 ------------------- soc/xtensa/nxp_adsp/imx8/linker.ld | 2 +- 3 files changed, 1 insertion(+), 22 deletions(-) rename soc/xtensa/nxp_adsp/imx8/include/{soc => }/memory.h (100%) delete mode 100644 soc/xtensa/nxp_adsp/imx8/include/soc/platform.h diff --git a/soc/xtensa/nxp_adsp/imx8/include/soc/memory.h b/soc/xtensa/nxp_adsp/imx8/include/memory.h similarity index 100% rename from soc/xtensa/nxp_adsp/imx8/include/soc/memory.h rename to soc/xtensa/nxp_adsp/imx8/include/memory.h diff --git a/soc/xtensa/nxp_adsp/imx8/include/soc/platform.h b/soc/xtensa/nxp_adsp/imx8/include/soc/platform.h deleted file mode 100644 index 44d8f46d1d4..00000000000 --- a/soc/xtensa/nxp_adsp/imx8/include/soc/platform.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2021 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __PLATFORM_PLATFORM_H__ -#define __PLATFORM_PLATFORM_H__ - -#define PLATFORM_PRIMARY_CORE_ID 0 - -#define MAX_CORE_COUNT 1 - -#if PLATFORM_CORE_COUNT > MAX_CORE_COUNT -#error "Invalid core count - exceeding core limit" -/* IPC Interrupt */ -#define PLATFORM_IPC_INTERRUPT IRQ_NUM_MU -#define PLATFORM_IPC_INTERRUPT_NAME NULL -#endif - -#endif /* __PLATFORM_PLATFORM_H__ */ diff --git a/soc/xtensa/nxp_adsp/imx8/linker.ld b/soc/xtensa/nxp_adsp/imx8/linker.ld index 599ef7339b8..7e5829c8d13 100644 --- a/soc/xtensa/nxp_adsp/imx8/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8/linker.ld @@ -15,7 +15,7 @@ OUTPUT_ARCH(xtensa) #include #include -#include +#include #include #include From ad7e85893802c36ce05eebefa231758a6a697979 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 10:27:52 +0300 Subject: [PATCH 3367/4498] soc: xtensa: imx8: memory.h: Cleanup This commit attempts to clean the memory.h header by doing the following changes: 1) Change the include guard to the standard ZEPHYR_.... 2) Remove unused macro definitions. Signed-off-by: Laurentiu Mihalcea --- soc/xtensa/nxp_adsp/imx8/include/memory.h | 58 ++--------------------- 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/soc/xtensa/nxp_adsp/imx8/include/memory.h b/soc/xtensa/nxp_adsp/imx8/include/memory.h index ee4785995a8..56bac21c780 100644 --- a/soc/xtensa/nxp_adsp/imx8/include/memory.h +++ b/soc/xtensa/nxp_adsp/imx8/include/memory.h @@ -4,13 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __INC_MEMORY_H -#define __INC_MEMORY_H - -#define PLATFORM_CORE_COUNT 1 - -/** Id of master DSP core */ -#define PLATFORM_PRIMARY_CORE_ID 0 +#ifndef ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ +#define ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ #define IRAM_RESERVE_HEADER_SPACE 0x400 @@ -164,51 +159,4 @@ + SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE \ + SRAM_STREAM_SIZE + SRAM_TRACE_SIZE) -/* Heap section sizes for module pool */ -#define HEAP_RT_COUNT8 0 -#define HEAP_RT_COUNT16 48 -#define HEAP_RT_COUNT32 48 -#define HEAP_RT_COUNT64 32 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 32 -#define HEAP_RT_COUNT512 4 -#define HEAP_RT_COUNT1024 4 -#define HEAP_RT_COUNT2048 4 - -/* Heap section sizes for system runtime heap */ -#define HEAP_SYS_RT_COUNT64 128 -#define HEAP_SYS_RT_COUNT512 16 -#define HEAP_SYS_RT_COUNT1024 8 - -/* Heap configuration */ -#define HEAP_SYSTEM_BASE SDRAM1_BASE + SOF_MAILBOX_SIZE -#define HEAP_SYSTEM_SIZE 0xe000 - -#define HEAP_SYS_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) -#define HEAP_SYS_RUNTIME_SIZE \ - (HEAP_SYS_RT_COUNT64 * 64 + HEAP_SYS_RT_COUNT512 * 512 + \ - HEAP_SYS_RT_COUNT1024 * 1024) - -#define HEAP_RUNTIME_BASE (HEAP_SYS_RUNTIME_BASE + HEAP_SYS_RUNTIME_SIZE) -#define HEAP_RUNTIME_SIZE \ - (HEAP_RT_COUNT8 * 8 + HEAP_RT_COUNT16 * 16 + \ - HEAP_RT_COUNT32 * 32 + HEAP_RT_COUNT64 * 64 + \ - HEAP_RT_COUNT128 * 128 + HEAP_RT_COUNT256 * 256 + \ - HEAP_RT_COUNT512 * 512 + HEAP_RT_COUNT1024 * 1024 + \ - HEAP_RT_COUNT2048 * 2048) - -#define HEAP_BUFFER_BASE (HEAP_RUNTIME_BASE + HEAP_RUNTIME_SIZE) -#define HEAP_BUFFER_SIZE \ - (SDRAM1_SIZE - SOF_MAILBOX_SIZE - HEAP_RUNTIME_SIZE - SOF_STACK_TOTAL_SIZE -\ - HEAP_SYS_RUNTIME_SIZE - HEAP_SYSTEM_SIZE) - -/* Stack configuration */ -#define SOF_STACK_SIZE 0x1000 -#define SOF_STACK_TOTAL_SIZE SOF_STACK_SIZE -#define SOF_STACK_BASE (SDRAM1_BASE + SDRAM1_SIZE) -#define SOF_STACK_END (SOF_STACK_BASE - SOF_STACK_TOTAL_SIZE) - -/* Host page size */ -#define HOST_PAGE_SIZE 4096 - -#endif /* __INC_MEMORY_H */ +#endif /* ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ */ From eb12bae0486c1ab14ddb085448416b452a39b3fd Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 10:56:42 +0300 Subject: [PATCH 3368/4498] soc: xtensa: imx8: Configuration cleanup As the name suggests, this commit attempts to cleanup some of the configurations for the i.MX8 series. This cleanup consists of either relocating the configuration or removing unnecessary configurations. As a rule of thumb, SoC-specific configurations have been moved to Kconfig.series. If the configuration is by default 'y' and needs to be set to 'n' or it has a numeric value then it has been moved to Kconfig.defconfig.series. Configurations that are default 'n' and were also explicitly set to 'n' have been removed. Also, enabling logging has been moved to the board level to avoid having to force all boards based on the same SoC to enable logging. Signed-off-by: Laurentiu Mihalcea --- boards/xtensa/nxp_adsp_imx8/Kconfig.defconfig | 11 ----------- .../nxp_adsp_imx8/nxp_adsp_imx8_defconfig | 17 ++++------------- boards/xtensa/nxp_adsp_imx8x/Kconfig.defconfig | 10 ---------- .../nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig | 17 ++++------------- .../nxp_adsp/imx8/Kconfig.defconfig.series | 8 ++++---- soc/xtensa/nxp_adsp/imx8/Kconfig.series | 2 ++ 6 files changed, 14 insertions(+), 51 deletions(-) diff --git a/boards/xtensa/nxp_adsp_imx8/Kconfig.defconfig b/boards/xtensa/nxp_adsp_imx8/Kconfig.defconfig index f72d1a4e11f..04aa0aa6ed3 100644 --- a/boards/xtensa/nxp_adsp_imx8/Kconfig.defconfig +++ b/boards/xtensa/nxp_adsp_imx8/Kconfig.defconfig @@ -7,15 +7,4 @@ if BOARD_NXP_ADSP_IMX8 config BOARD default "nxp_adsp_imx8" -config DUMMY_DMA - bool - default y - depends on DMA - -config IMX_EDMA - bool - default y - depends on DMA - - endif # BOARD_NXP_ADSP_IMX8 diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig index 2a2a34f0329..2cf0553a8eb 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig @@ -2,22 +2,13 @@ CONFIG_MAIN_STACK_SIZE=3072 +# board/soc-related configurations CONFIG_SOC_SERIES_NXP_IMX8=y CONFIG_SOC_MIMX8QM_ADSP=y CONFIG_BOARD_NXP_ADSP_IMX8=y -CONFIG_GEN_ISR_TABLES=y -CONFIG_GEN_IRQ_VECTOR_TABLE=n - -CONFIG_XTENSA_RESET_VECTOR=y - -CONFIG_XTENSA_USE_CORE_CRT1=y - -CONFIG_XTENSA_SMALL_VECTOR_TABLE_ENTRY=y - -CONFIG_MULTI_LEVEL_INTERRUPTS=n -CONFIG_2ND_LEVEL_INTERRUPTS=n +CONFIG_LOG=y +# TODO: maybe move this to SOF? +CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_BUILD_OUTPUT_BIN=n - -CONFIG_DCACHE_LINE_SIZE=128 diff --git a/boards/xtensa/nxp_adsp_imx8x/Kconfig.defconfig b/boards/xtensa/nxp_adsp_imx8x/Kconfig.defconfig index 31d42395503..a985696286a 100644 --- a/boards/xtensa/nxp_adsp_imx8x/Kconfig.defconfig +++ b/boards/xtensa/nxp_adsp_imx8x/Kconfig.defconfig @@ -7,14 +7,4 @@ if BOARD_NXP_ADSP_IMX8X config BOARD default "nxp_adsp_imx8x" -config DUMMY_DMA - bool - default y - depends on DMA - -config IMX_EDMA - bool - default y - depends on DMA - endif # BOARD_NXP_ADSP_IMX8X diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig index a424e54cd52..87de9b515c5 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig @@ -2,22 +2,13 @@ CONFIG_MAIN_STACK_SIZE=3072 +# board/soc-related configurations CONFIG_SOC_SERIES_NXP_IMX8=y CONFIG_SOC_MIMX8QXP_ADSP=y CONFIG_BOARD_NXP_ADSP_IMX8X=y -CONFIG_GEN_ISR_TABLES=y -CONFIG_GEN_IRQ_VECTOR_TABLE=n - -CONFIG_XTENSA_RESET_VECTOR=y - -CONFIG_XTENSA_USE_CORE_CRT1=y - -CONFIG_XTENSA_SMALL_VECTOR_TABLE_ENTRY=y - -CONFIG_MULTI_LEVEL_INTERRUPTS=n -CONFIG_2ND_LEVEL_INTERRUPTS=n +CONFIG_LOG=y +# TODO: maybe move this to SOF? +CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_BUILD_OUTPUT_BIN=n - -CONFIG_DCACHE_LINE_SIZE=128 diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series index 517e2c52a8e..a5f4597f069 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series @@ -17,11 +17,11 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config SYS_CLOCK_TICKS_PER_SEC default 50000 -config DYNAMIC_INTERRUPTS - default y +config DCACHE_LINE_SIZE + default 128 -config LOG - default y +config GEN_IRQ_VECTOR_TABLE + default n source "soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.imx8q*" diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.series b/soc/xtensa/nxp_adsp/imx8/Kconfig.series index 396607a4847..003784e842b 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.series +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.series @@ -9,5 +9,7 @@ config SOC_SERIES_NXP_IMX8 select XTENSA_RESET_VECTOR select XTENSA_USE_CORE_CRT1 select ATOMIC_OPERATIONS_BUILTIN + select GEN_ISR_TABLES + select XTENSA_SMALL_VECTOR_TABLE_ENTRY help NXP i.MX8 From ea99578b764a70b48755d22a5b3cde0e38b9af5c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 11:19:57 +0300 Subject: [PATCH 3369/4498] soc: xtensa: imx8: Enable clock control on i.MX8QM/QXP This commit enables clock control on the i.MX8QM and QXP boards. This is achieved through the following changes: 1) The "reg" property is no longer marked as required for the "nxp,imx-ccm" binding. This is necessary because in the case of i.MX8QM and i.MX8QXP the clock management is done through the SCFW, hence there's no need to access CCM's MMIO space (not that you could anyways). 2) The DTS now contains a scu_mu node. This node refers to the MU instance used by the DSP to communicate with the SCFW. 3) The CCM driver needs to support the LPUART clocks (which will be the only IP that's supported for now) and needs to perform an initialization so that the NXP HAL driver knows which MU to use to communicate with the SCFW. Signed-off-by: Laurentiu Mihalcea --- .../nxp_adsp_imx8/nxp_adsp_imx8_defconfig | 3 + .../nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig | 3 + .../clock_control/clock_control_mcux_ccm.c | 95 ++++++++++++++++++- dts/bindings/clock/nxp,imx-ccm.yaml | 3 - dts/xtensa/nxp/nxp_imx8.dtsi | 13 +++ 5 files changed, 112 insertions(+), 5 deletions(-) diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig index 2cf0553a8eb..64fdb3219d7 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig @@ -12,3 +12,6 @@ CONFIG_LOG=y # TODO: maybe move this to SOF? CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_BUILD_OUTPUT_BIN=n + +# clock-related configurations +CONFIG_CLOCK_CONTROL=y diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig index 87de9b515c5..ceb0bf13a59 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig @@ -12,3 +12,6 @@ CONFIG_LOG=y # TODO: maybe move this to SOF? CONFIG_DYNAMIC_INTERRUPTS=y CONFIG_BUILD_OUTPUT_BIN=n + +# clock-related configurations +CONFIG_CLOCK_CONTROL=y diff --git a/drivers/clock_control/clock_control_mcux_ccm.c b/drivers/clock_control/clock_control_mcux_ccm.c index 93a495b9dae..77736caa1c9 100644 --- a/drivers/clock_control/clock_control_mcux_ccm.c +++ b/drivers/clock_control/clock_control_mcux_ccm.c @@ -12,6 +12,10 @@ #include #include +#if defined(CONFIG_SOC_MIMX8QM_ADSP) || defined(CONFIG_SOC_MIMX8QXP_ADSP) +#include

    +#endif + #define LOG_LEVEL CONFIG_CLOCK_CONTROL_LOG_LEVEL #include LOG_MODULE_REGISTER(clock_control); @@ -52,6 +56,34 @@ static const clock_root_t lpuart_clk_root[] = { }; #endif +#ifdef CONFIG_UART_MCUX_LPUART + +#ifdef CONFIG_SOC_MIMX8QM_ADSP +static const clock_ip_name_t lpuart_clocks[] = { + kCLOCK_DMA_Lpuart0, + kCLOCK_DMA_Lpuart1, + kCLOCK_DMA_Lpuart2, + kCLOCK_DMA_Lpuart3, + kCLOCK_DMA_Lpuart4, +}; + +static const uint32_t lpuart_rate = MHZ(80); +#endif /* CONFIG_SOC_MIMX8QM_ADSP */ + +#ifdef CONFIG_SOC_MIMX8QXP_ADSP +static const clock_ip_name_t lpuart_clocks[] = { + kCLOCK_DMA_Lpuart0, + kCLOCK_DMA_Lpuart1, + kCLOCK_DMA_Lpuart2, + kCLOCK_DMA_Lpuart3, +}; + +static const uint32_t lpuart_rate = MHZ(80); +#endif /* CONFIG_SOC_MIMX8QXP_ADSP */ + +#endif /* CONFIG_UART_MCUX_LPUART */ + + static int mcux_ccm_on(const struct device *dev, clock_control_subsys_t sub_system) { @@ -67,6 +99,25 @@ static int mcux_ccm_on(const struct device *dev, CLOCK_EnableClock(uart_clocks[instance]); return 0; #endif + +#if defined(CONFIG_UART_MCUX_LPUART) && defined(CONFIG_SOC_MIMX8QM_ADSP) + case IMX_CCM_LPUART1_CLK: + case IMX_CCM_LPUART2_CLK: + case IMX_CCM_LPUART3_CLK: + case IMX_CCM_LPUART4_CLK: + case IMX_CCM_LPUART5_CLK: + CLOCK_EnableClock(lpuart_clocks[instance]); + return 0; +#endif + +#if defined(CONFIG_UART_MCUX_LPUART) && defined(CONFIG_SOC_MIMX8QXP_ADSP) + case IMX_CCM_LPUART1_CLK: + case IMX_CCM_LPUART2_CLK: + case IMX_CCM_LPUART3_CLK: + case IMX_CCM_LPUART4_CLK: + CLOCK_EnableClock(lpuart_clocks[instance]); + return 0; +#endif default: (void)instance; return 0; @@ -128,7 +179,31 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, #endif #ifdef CONFIG_UART_MCUX_LPUART -#ifdef CONFIG_SOC_MIMX93_A55 + +#if defined(CONFIG_SOC_MIMX8QM_ADSP) + case IMX_CCM_LPUART1_CLK: + case IMX_CCM_LPUART2_CLK: + case IMX_CCM_LPUART3_CLK: + case IMX_CCM_LPUART4_CLK: + case IMX_CCM_LPUART5_CLK: + uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK; + + CLOCK_SetIpFreq(lpuart_clocks[instance], lpuart_rate); + *rate = CLOCK_GetIpFreq(lpuart_clocks[instance]); + break; + +#elif defined(CONFIG_SOC_MIMX8QXP_ADSP) + case IMX_CCM_LPUART1_CLK: + case IMX_CCM_LPUART2_CLK: + case IMX_CCM_LPUART3_CLK: + case IMX_CCM_LPUART4_CLK: + uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK; + + CLOCK_SetIpFreq(lpuart_clocks[instance], lpuart_rate); + *rate = CLOCK_GetIpFreq(lpuart_clocks[instance]); + break; + +#elif defined(CONFIG_SOC_MIMX93_A55) case IMX_CCM_LPUART1_CLK: case IMX_CCM_LPUART2_CLK: case IMX_CCM_LPUART3_CLK: @@ -270,6 +345,22 @@ static const struct clock_control_driver_api mcux_ccm_driver_api = { .get_rate = mcux_ccm_get_subsys_rate, }; -DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, +static int mcux_ccm_init(const struct device *dev) +{ +#if defined(CONFIG_SOC_MIMX8QM_ADSP) || defined(CONFIG_SOC_MIMX8QXP_ADSP) + sc_ipc_t ipc_handle; + int ret; + + ret = sc_ipc_open(&ipc_handle, DT_REG_ADDR(DT_NODELABEL(scu_mu))); + if (ret != SC_ERR_NONE) { + return -ENODEV; + } + + CLOCK_Init(ipc_handle); +#endif + return 0; +} + +DEVICE_DT_INST_DEFINE(0, mcux_ccm_init, NULL, NULL, NULL, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &mcux_ccm_driver_api); diff --git a/dts/bindings/clock/nxp,imx-ccm.yaml b/dts/bindings/clock/nxp,imx-ccm.yaml index 9ddda734e81..f328b6f034a 100644 --- a/dts/bindings/clock/nxp,imx-ccm.yaml +++ b/dts/bindings/clock/nxp,imx-ccm.yaml @@ -8,9 +8,6 @@ compatible: "nxp,imx-ccm" include: [clock-controller.yaml, base.yaml] properties: - reg: - required: true - "#clock-cells": const: 3 diff --git a/dts/xtensa/nxp/nxp_imx8.dtsi b/dts/xtensa/nxp/nxp_imx8.dtsi index 06b38e1bbee..b223fa10843 100644 --- a/dts/xtensa/nxp/nxp_imx8.dtsi +++ b/dts/xtensa/nxp/nxp_imx8.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { cpus { @@ -30,4 +31,16 @@ compatible = "mmio-sram"; reg = <0x92c00000 DT_SIZE_K(512)>; }; + + /* LSIO MU2, used to interact with the SCFW */ + scu_mu: mailbox@5d1d0000 { + reg = <0x5d1d0000 DT_SIZE_K(64)>; + }; + + scu: system-controller { + ccm: clock-controller { + compatible = "nxp,imx-ccm"; + #clock-cells = <3>; + }; + }; }; From 707759bd121a0fec8d1a65adc10edec120f349cc Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 12:06:05 +0300 Subject: [PATCH 3370/4498] soc: xtensa: imx8: Add pinctrl support This commit introduces support for pinctrl-related operations on i.MX8QM/QXP. Signed-off-by: Laurentiu Mihalcea --- .../nxp_adsp_imx8/nxp_adsp_imx8-pinctrl.dtsi | 26 ++++++++++++ boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts | 1 + .../nxp_adsp_imx8x-pinctrl.dtsi | 26 ++++++++++++ .../xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts | 1 + drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig.imx | 7 ++++ drivers/pinctrl/pinctrl_imx_scu.c | 38 +++++++++++++++++ dts/bindings/pinctrl/nxp,imx-iomuxc-scu.yaml | 25 +++++++++++ dts/bindings/pinctrl/nxp,imx8-pinctrl.yaml | 17 ++++++++ dts/xtensa/nxp/nxp_imx8.dtsi | 7 ++++ .../dt-bindings/pinctrl/imx8qm-pinctrl.h | 18 ++++++++ .../dt-bindings/pinctrl/imx8qxp-pinctrl.h | 18 ++++++++ soc/xtensa/nxp_adsp/imx8/pinctrl_soc.h | 41 +++++++++++++++++++ 13 files changed, 226 insertions(+) create mode 100644 boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8-pinctrl.dtsi create mode 100644 boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x-pinctrl.dtsi create mode 100644 drivers/pinctrl/pinctrl_imx_scu.c create mode 100644 dts/bindings/pinctrl/nxp,imx-iomuxc-scu.yaml create mode 100644 dts/bindings/pinctrl/nxp,imx8-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/imx8qm-pinctrl.h create mode 100644 include/zephyr/dt-bindings/pinctrl/imx8qxp-pinctrl.h create mode 100644 soc/xtensa/nxp_adsp/imx8/pinctrl_soc.h diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8-pinctrl.dtsi b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8-pinctrl.dtsi new file mode 100644 index 00000000000..a6291a5d4b8 --- /dev/null +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8-pinctrl.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&iomuxc { + iomuxc_uart2_rx_uart0_rts_b: IOMUXC_UART2_RX_UART0_RTS_B { + pinmux = ; + }; + + iomuxc_uart2_tx_uart0_cts_b: IOMUXC_UART2_TX_UART0_CTS_B { + pinmux = ; + }; +}; + +&pinctrl { + lpuart2_default: lpuart2_default { + group0 { + pinmux = <&iomuxc_uart2_rx_uart0_rts_b>, + <&iomuxc_uart2_tx_uart0_cts_b>; + }; + }; +}; diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts index 51d3162134a..2d26c61f13f 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include "nxp_adsp_imx8-pinctrl.dtsi" / { model = "nxp_adsp_imx8"; diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x-pinctrl.dtsi b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x-pinctrl.dtsi new file mode 100644 index 00000000000..18cfb473257 --- /dev/null +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x-pinctrl.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&iomuxc { + iomuxc_uart2_rx_uart2_rx: IOMUXC_UART2_RX_UART2_RX { + pinmux = ; + }; + + iomuxc_uart2_tx_uart2_tx: IOMUXC_UART2_TX_UART2_TX { + pinmux = ; + }; +}; + +&pinctrl { + lpuart2_default: lpuart2_default { + group0 { + pinmux = <&iomuxc_uart2_rx_uart2_rx>, + <&iomuxc_uart2_tx_uart2_tx>; + }; + }; +}; diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts index bee8ccdb1a1..69e4a57dd64 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include "nxp_adsp_imx8x-pinctrl.dtsi" / { model = "nxp_adsp_imx8x"; diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 30b9f96eefc..ba49a637689 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -36,3 +36,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c) diff --git a/drivers/pinctrl/Kconfig.imx b/drivers/pinctrl/Kconfig.imx index b31a90e7291..506f5b30016 100644 --- a/drivers/pinctrl/Kconfig.imx +++ b/drivers/pinctrl/Kconfig.imx @@ -7,6 +7,13 @@ config PINCTRL_IMX help Enable pin controller driver for NXP iMX series MCUs +config PINCTRL_IMX_SCU + bool "Pin controller driver for SCU-based i.MX SoCs" + depends on DT_HAS_NXP_IMX_IOMUXC_SCU_ENABLED + default y + help + Enable pin controller driver for SCU-based NXP i.MX SoCs. + # TODO: Find better place for this option config MCUX_XBARA bool "MCUX XBARA driver" diff --git a/drivers/pinctrl/pinctrl_imx_scu.c b/drivers/pinctrl/pinctrl_imx_scu.c new file mode 100644 index 00000000000..67448ed5999 --- /dev/null +++ b/drivers/pinctrl/pinctrl_imx_scu.c @@ -0,0 +1,38 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include
    + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, + uint8_t pin_cnt, uintptr_t reg) +{ + sc_ipc_t ipc_handle; + int ret, i; + + ret = sc_ipc_open(&ipc_handle, DT_REG_ADDR(DT_NODELABEL(scu_mu))); + if (ret != SC_ERR_NONE) { + return -ENODEV; + } + + for (i = 0; i < pin_cnt; i++) { + /* TODO: for now, pad configuration is not supported. As such, + * the state of the pad is the following: + * 1) Normal configuration (no OD) + * 2) ISO off + * 3) Pull select and drive strength initialized by another + * entity (e.g: SCFW, Linux etc...) or set to the default + * values as specified in the TRM. + */ + ret = sc_pad_set_mux(ipc_handle, pins[i].pad, pins[i].mux, 0, 0); + if (ret != SC_ERR_NONE) { + return -EINVAL; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/nxp,imx-iomuxc-scu.yaml b/dts/bindings/pinctrl/nxp,imx-iomuxc-scu.yaml new file mode 100644 index 00000000000..60dde5ae4c9 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,imx-iomuxc-scu.yaml @@ -0,0 +1,25 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + Use this compatible for i.MX boards on which the + IOMUXC is managed by the SCU. + +compatible: "nxp,imx-iomuxc-scu" + +include: base.yaml + +child-binding: + description: SCFW-based IOMUXC pin mux. + properties: + pinmux: + required: true + type: array + description: | + This is an array of values defining the pin mux selection + with the following format: + + + + pad: Which pad to configure. + mux: Select which signal to route. diff --git a/dts/bindings/pinctrl/nxp,imx8-pinctrl.yaml b/dts/bindings/pinctrl/nxp,imx8-pinctrl.yaml new file mode 100644 index 00000000000..4f0427d5d95 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,imx8-pinctrl.yaml @@ -0,0 +1,17 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Use this compatible for i.MX8QM/QXP boards. + +compatible: "nxp,imx8-pinctrl" + +include: base.yaml + +child-binding: + description: i.MX8QM/QXP pin controller pin group + child-binding: + description: i.MX8QM/QXP pin controller pin configuration node. + properties: + pinmux: + required: true + type: phandles diff --git a/dts/xtensa/nxp/nxp_imx8.dtsi b/dts/xtensa/nxp/nxp_imx8.dtsi index b223fa10843..5f14d220a06 100644 --- a/dts/xtensa/nxp/nxp_imx8.dtsi +++ b/dts/xtensa/nxp/nxp_imx8.dtsi @@ -42,5 +42,12 @@ compatible = "nxp,imx-ccm"; #clock-cells = <3>; }; + + iomuxc: iomuxc { + compatible = "nxp,imx-iomuxc-scu"; + pinctrl: pinctrl { + compatible = "nxp,imx8-pinctrl"; + }; + }; }; }; diff --git a/include/zephyr/dt-bindings/pinctrl/imx8qm-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/imx8qm-pinctrl.h new file mode 100644 index 00000000000..9748a2ce4aa --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/imx8qm-pinctrl.h @@ -0,0 +1,18 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QM_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QM_PINCTRL_H_ + +/* values for pad field */ +#define SC_P_UART0_RTS_B 23 +#define SC_P_UART0_CTS_B 24 + +/* mux values */ +#define IMX8QM_DMA_LPUART2_RX_UART0_RTS_B 2 /* UART0_RTS_B ---> DMA_LPUART2_RX */ +#define IMX8QM_DMA_LPUART2_TX_UART0_CTS_B 2 /* DMA_LPUART2_TX ---> UART0_CTS_B */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QM_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/imx8qxp-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/imx8qxp-pinctrl.h new file mode 100644 index 00000000000..0143540f6bf --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/imx8qxp-pinctrl.h @@ -0,0 +1,18 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QXP_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QXP_PINCTRL_H_ + +/* values for pad field */ +#define SC_P_UART2_TX 113 +#define SC_P_UART2_RX 114 + +/* mux values */ +#define IMX8QXP_DMA_LPUART2_RX_UART2_RX 0 /* UART2_RX ---> DMA_LPUART2_RX */ +#define IMX8QXP_DMA_LPUART2_TX_UART2_TX 0 /* DMA_LPUART2_TX ---> UART2_TX */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IMX8QXP_PINCTRL_H_ */ diff --git a/soc/xtensa/nxp_adsp/imx8/pinctrl_soc.h b/soc/xtensa/nxp_adsp/imx8/pinctrl_soc.h new file mode 100644 index 00000000000..ac748220b56 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8/pinctrl_soc.h @@ -0,0 +1,41 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_XTENSA_NXP_ADSP_IMX8_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_XTENSA_NXP_ADSP_IMX8_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pinmux { + uint32_t pad; + uint32_t mux; +}; + +typedef struct pinctrl_soc_pinmux pinctrl_soc_pin_t; + +#define IMX8_PINMUX(n) \ +{ \ + .pad = DT_PROP_BY_IDX(n, pinmux, 0), \ + .mux = DT_PROP_BY_IDX(n, pinmux, 1), \ +}, + +#define Z_PINCTRL_PINMUX(group_id, pin_prop, idx)\ + IMX8_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, Z_PINCTRL_PINMUX) }; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_XTENSA_NXP_ADSP_IMX8_PINCTRL_SOC_H_ */ From dcddb2e0f74c16c3c7172c09ec2a6b307ce6ca32 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 12:08:40 +0300 Subject: [PATCH 3371/4498] dts: xtensa: nxp_imx8: Add dummy interrupt controller node Since the LPUART peripheral DTS binding requires the "interrupts" property be specified even if it's not going to be used for now we need to add a dummy interrupt controller node to make that possible. Logically speaking, this dummy interrupt controller should be used by peripherals which can assert interrupts directly routed to the DSP. Signed-off-by: Laurentiu Mihalcea --- dts/xtensa/nxp/nxp_imx8.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dts/xtensa/nxp/nxp_imx8.dtsi b/dts/xtensa/nxp/nxp_imx8.dtsi index 5f14d220a06..2ec110adf1e 100644 --- a/dts/xtensa/nxp/nxp_imx8.dtsi +++ b/dts/xtensa/nxp/nxp_imx8.dtsi @@ -17,6 +17,16 @@ device_type = "cpu"; compatible = "cdns,tensilica-xtensa-lx6"; reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + clic: interrupt-controller@0 { + compatible = "cdns,xtensa-core-intc"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <3>; + }; }; }; From 5cdd377316e7cb18648c7ebe30a2485a94deb683 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 22 Sep 2023 12:23:06 +0300 Subject: [PATCH 3372/4498] boards: xtensa: nxp_adsp_imx8(x): Add serial support This commit introduces all changes necessary for utilizing the serial interface on i.MX8QM/QXP. Signed-off-by: Laurentiu Mihalcea --- boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts | 9 +++++++++ .../nxp_adsp_imx8/nxp_adsp_imx8_defconfig | 5 +++++ boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts | 9 +++++++++ .../nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig | 5 +++++ dts/xtensa/nxp/nxp_imx8.dtsi | 17 +++++++++++++++++ 5 files changed, 45 insertions(+) diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts index 2d26c61f13f..a17690109ec 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.dts @@ -15,5 +15,14 @@ chosen { zephyr,sram = &sram0; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; }; }; + +&lpuart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&lpuart2_default>; + pinctrl-names = "default"; +}; diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig index 64fdb3219d7..a16d8be5e2e 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8_defconfig @@ -15,3 +15,8 @@ CONFIG_BUILD_OUTPUT_BIN=n # clock-related configurations CONFIG_CLOCK_CONTROL=y + +# serial-related configurations +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts index 69e4a57dd64..5aa0e59ebdd 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.dts @@ -15,5 +15,14 @@ chosen { zephyr,sram = &sram0; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; }; }; + +&lpuart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&lpuart2_default>; + pinctrl-names = "default"; +}; diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig index ceb0bf13a59..0635e78adf8 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x_defconfig @@ -15,3 +15,8 @@ CONFIG_BUILD_OUTPUT_BIN=n # clock-related configurations CONFIG_CLOCK_CONTROL=y + +# serial-related configurations +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/dts/xtensa/nxp/nxp_imx8.dtsi b/dts/xtensa/nxp/nxp_imx8.dtsi index 2ec110adf1e..7a8c23cedc4 100644 --- a/dts/xtensa/nxp/nxp_imx8.dtsi +++ b/dts/xtensa/nxp/nxp_imx8.dtsi @@ -60,4 +60,21 @@ }; }; }; + + lpuart2: serial@5a080000 { + compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + reg = <0x5a080000 DT_SIZE_K(4)>; + /* TODO: THIS INTID IS JUST A DUMMY ONE UNTIL IRQ_STEER + * DRIVER CAN BE USED ON i.MX8QM/QXP. DO NOT ATTEMPT TO + * ENABLE UART INTERRUPT SUPPORT. + * + * THE CURRENT INTID VALUE IS CHOSEN SUCH THAT gen_isr_tables.py + * WILL BREAK IF YOU ATTEMPT TO IRQ_CONNECT(). + */ + interrupt-parent = <&clic>; + interrupts = <259 0 0>; + /* this is actually LPUART2 clock but the macro indexing starts at 1 */ + clocks = <&ccm IMX_CCM_LPUART3_CLK 0x0 0x0>; + status = "disabled"; + }; }; From 595a9c11c8ea8f7e2e504a9a925643e45c05a83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 7 Nov 2023 08:44:08 +0700 Subject: [PATCH 3373/4498] counter: nxp_s32_sys_timer: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles --- drivers/counter/counter_nxp_s32_sys_timer.c | 55 +++++++++------------ soc/arm/nxp_s32/s32ze/soc.h | 15 ++++++ 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/drivers/counter/counter_nxp_s32_sys_timer.c b/drivers/counter/counter_nxp_s32_sys_timer.c index 1c25039aab2..b6c7f8a1d96 100644 --- a/drivers/counter/counter_nxp_s32_sys_timer.c +++ b/drivers/counter/counter_nxp_s32_sys_timer.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_sys_timer + #include #include #include @@ -14,13 +16,8 @@ LOG_MODULE_REGISTER(nxp_s32_sys_timer, CONFIG_COUNTER_LOG_LEVEL); -#define SYS_TIMER_NODE(n) DT_NODELABEL(stm##n) #define SYS_TIMER_MAX_VALUE 0xFFFFFFFFU #define SYS_TIMER_NUM_CHANNELS 4 -#define SYS_TIMER_INSTANCE_ID(n) (n + 3 + CONFIG_NXP_S32_RTU_INDEX * 4) - -#define _SYS_TIMER_ISR(r, n) RTU##r##_STM_##n##_ISR -#define SYS_TIMER_ISR(r, n) _SYS_TIMER_ISR(r, n) struct nxp_s32_sys_timer_chan_data { counter_alarm_callback_t callback; @@ -209,15 +206,24 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { .channelMode = STM_IP_CH_MODE_ONESHOT, \ } +#define _SYS_TIMER_ISR(r, n) RTU##r##_STM_##n##_ISR +#define SYS_TIMER_ISR(r, n) _SYS_TIMER_ISR(r, n) + #define SYS_TIMER_ISR_DECLARE(n) \ extern void SYS_TIMER_ISR(CONFIG_NXP_S32_RTU_INDEX, n)(void) +#define SYS_TIMER_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_STM_##i##_BASE) ? i : 0) + +#define SYS_TIMER_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET STM_INSTANCE_COUNT, SYS_TIMER_HW_INSTANCE_CHECK, (|), n) + #define SYS_TIMER_INIT_DEVICE(n) \ SYS_TIMER_ISR_DECLARE(n); \ \ void nxp_s32_sys_timer_##n##_callback(uint8_t chan_id) \ { \ - const struct device *dev = DEVICE_DT_GET(SYS_TIMER_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ const struct nxp_s32_sys_timer_config *config = dev->config; \ struct nxp_s32_sys_timer_data *data = dev->data; \ struct nxp_s32_sys_timer_chan_data *ch_data = &data->ch_data[chan_id]; \ @@ -233,12 +239,10 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { \ static int nxp_s32_sys_timer_##n##_init(const struct device *dev) \ { \ - IRQ_CONNECT(DT_IRQN(SYS_TIMER_NODE(n)), \ - DT_IRQ(SYS_TIMER_NODE(n), priority), \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ SYS_TIMER_ISR(CONFIG_NXP_S32_RTU_INDEX, n), \ - DEVICE_DT_GET(SYS_TIMER_NODE(n)), \ - DT_IRQ(SYS_TIMER_NODE(n), flags)); \ - irq_enable(DT_IRQN(SYS_TIMER_NODE(n))); \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ(n, flags)); \ + irq_enable(DT_INST_IRQN(n)); \ \ return nxp_s32_sys_timer_init(dev); \ } \ @@ -252,19 +256,18 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ }, \ .hw_cfg = { \ - .stopInDebugMode = DT_PROP(SYS_TIMER_NODE(n), freeze), \ - .clockPrescaler = DT_PROP(SYS_TIMER_NODE(n), prescaler) - 1, \ + .stopInDebugMode = DT_INST_PROP(n, freeze), \ + .clockPrescaler = DT_INST_PROP(n, prescaler) - 1, \ }, \ .ch_cfg = { \ LISTIFY(SYS_TIMER_NUM_CHANNELS, SYS_TIMER_CHANNEL_CFG, (,), n) \ }, \ - .instance = SYS_TIMER_INSTANCE_ID(n), \ - .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(SYS_TIMER_NODE(n))), \ - .clock_subsys = (clock_control_subsys_t) \ - DT_CLOCKS_CELL(SYS_TIMER_NODE(n), name), \ + .instance = SYS_TIMER_HW_INSTANCE(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ }; \ \ - DEVICE_DT_DEFINE(SYS_TIMER_NODE(n), \ + DEVICE_DT_INST_DEFINE(n, \ nxp_s32_sys_timer_##n##_init, \ NULL, \ &nxp_s32_sys_timer_data_##n, \ @@ -273,18 +276,4 @@ static const struct counter_driver_api nxp_s32_sys_timer_driver_api = { CONFIG_COUNTER_INIT_PRIORITY, \ &nxp_s32_sys_timer_driver_api); -#if DT_NODE_HAS_STATUS(SYS_TIMER_NODE(0), okay) -SYS_TIMER_INIT_DEVICE(0) -#endif - -#if DT_NODE_HAS_STATUS(SYS_TIMER_NODE(1), okay) -SYS_TIMER_INIT_DEVICE(1) -#endif - -#if DT_NODE_HAS_STATUS(SYS_TIMER_NODE(2), okay) -SYS_TIMER_INIT_DEVICE(2) -#endif - -#if DT_NODE_HAS_STATUS(SYS_TIMER_NODE(3), okay) -SYS_TIMER_INIT_DEVICE(3) -#endif +DT_INST_FOREACH_STATUS_OKAY(SYS_TIMER_INIT_DEVICE) diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index 756774d7202..a6a7ca51ced 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -33,4 +33,19 @@ #define IP_SWT_11_BASE IP_RTU1__SWT_4_BASE #define IP_SWT_12_BASE IP_SMU__SWT_BASE +/* STM */ +#define IP_STM_0_BASE IP_CE_STM_0_BASE +#define IP_STM_1_BASE IP_CE_STM_1_BASE +#define IP_STM_2_BASE IP_CE_STM_2_BASE +#define IP_STM_3_BASE IP_RTU0__STM_0_BASE +#define IP_STM_4_BASE IP_RTU0__STM_1_BASE +#define IP_STM_5_BASE IP_RTU0__STM_2_BASE +#define IP_STM_6_BASE IP_RTU0__STM_3_BASE +#define IP_STM_7_BASE IP_RTU1__STM_0_BASE +#define IP_STM_8_BASE IP_RTU1__STM_1_BASE +#define IP_STM_9_BASE IP_RTU1__STM_2_BASE +#define IP_STM_10_BASE IP_RTU1__STM_3_BASE +#define IP_STM_11_BASE IP_SMU__STM_0_BASE +#define IP_STM_12_BASE IP_SMU__STM_2_BASE + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From ade72c2b3a193aad36d0830cc2c90495ce7cd6b7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 27 Sep 2023 17:30:59 +0200 Subject: [PATCH 3374/4498] llext: remove a superfluous variable initialisation ret in llext_load() is always assigned before use, remove its redundant initialisation. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 9e3cbd79990..83f05f121c5 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -635,7 +635,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) { - int ret = 0; + int ret; elf_ehdr_t ehdr; ret = llext_seek(ldr, 0); From f0527b5571e947092457859e22d2426e780d9a64 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 7 Sep 2023 16:51:50 +0200 Subject: [PATCH 3375/4498] llext: add a weak arch_elf_relocate() stub The module linking API can be used for shared objects with no architecture-specific relocation code. Add a weak function for such cases. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 83f05f121c5..d46e021b894 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -403,6 +403,10 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext return ret; } +__weak void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval) +{ +} + static int llext_link(struct llext_loader *ldr, struct llext *ext) { int ret = 0; From 6185da5d716fe5eb9493385e7879feb1c74fb031 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 28 Sep 2023 10:22:58 +0200 Subject: [PATCH 3376/4498] llext: fix a typo in elf_rel_t 64-bit definition struct elf64_rela is undefined, use the correct structure name. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/llext/elf.h b/include/zephyr/llext/elf.h index 1e83142dcd3..6e2b62986dd 100644 --- a/include/zephyr/llext/elf.h +++ b/include/zephyr/llext/elf.h @@ -435,7 +435,7 @@ typedef elf64_half elf_half; /** Machine sized integer */ typedef elf64_xword elf_word; /** Machine sized relocation struct */ -typedef struct elf64_rela elf_rel_t; +typedef struct elf64_rel elf_rel_t; /** Machine sized symbol struct */ typedef struct elf64_sym elf_sym_t; /** Machine sized macro alias for obtaining a relocation symbol */ From bca88b4b3a9d35d3ff47e6a41c0f6a2e5e0f6647 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 22 Sep 2023 15:00:52 +0200 Subject: [PATCH 3377/4498] llext: fix exporting objects When exporting a symbol, we need to use "&" explicitly, otherwise it only works for functions and doesn't work for objects. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/symbol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index c7f7b829902..b1aef67413e 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -75,7 +75,7 @@ struct llext_symtable { */ #define EXPORT_SYMBOL(x) \ static const STRUCT_SECTION_ITERABLE(llext_const_symbol, x ## _sym) = { \ - .name = STRINGIFY(x), .addr = x, \ + .name = STRINGIFY(x), .addr = &x, \ } /** From a9a82d557c72c615ede2fe1009c38b14a55c9e55 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 22 Sep 2023 15:40:26 +0200 Subject: [PATCH 3378/4498] llext: use elf_rela_t instead of elf_rel_t elf_rela_t contains elf_rel_t exactly and contains an additional field at the end. Therefore pointers of that type can be used for both types, making the code generic. Signed-off-by: Guennadi Liakhovetski --- arch/arm/core/elf.c | 2 +- include/zephyr/llext/elf.h | 14 ++++++++++++++ include/zephyr/llext/llext.h | 2 +- subsys/llext/llext.c | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/elf.c b/arch/arm/core/elf.c index 0a7aa654479..e16af6199e6 100644 --- a/arch/arm/core/elf.c +++ b/arch/arm/core/elf.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL); * The relocation codes for arm are well documented * https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#relocation */ -void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval) +void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval) { elf_word reloc_type = ELF32_R_TYPE(rel->r_info); diff --git a/include/zephyr/llext/elf.h b/include/zephyr/llext/elf.h index 6e2b62986dd..6dc3cc4e5c8 100644 --- a/include/zephyr/llext/elf.h +++ b/include/zephyr/llext/elf.h @@ -306,6 +306,12 @@ struct elf32_rel { elf32_word r_info; }; +struct elf32_rela { + elf32_addr r_offset; + elf32_word r_info; + elf32_word r_addend; +}; + /** * @brief Relocation symbol index from r_info * @@ -330,6 +336,12 @@ struct elf64_rel { elf64_xword r_info; }; +struct elf64_rela { + elf64_addr r_offset; + elf64_word r_info; + elf64_word r_addend; +}; + /** @brief Relocation symbol from r_info * * @param i Value of r_info @@ -436,6 +448,7 @@ typedef elf64_half elf_half; typedef elf64_xword elf_word; /** Machine sized relocation struct */ typedef struct elf64_rel elf_rel_t; +typedef struct elf64_rela elf_rela_t; /** Machine sized symbol struct */ typedef struct elf64_sym elf_sym_t; /** Machine sized macro alias for obtaining a relocation symbol */ @@ -461,6 +474,7 @@ typedef elf32_half elf_half; typedef elf32_word elf_word; /** Machine sized relocation struct */ typedef struct elf32_rel elf_rel_t; +typedef struct elf32_rela elf_rela_t; /** Machine sized symbol struct */ typedef struct elf32_sym elf_sym_t; /** Machine sized macro alias for obtaining a relocation symbol */ diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 6afb48682be..33feba50bd5 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -135,7 +135,7 @@ int llext_call_fn(struct llext *ext, const char *sym_name); * @param[in] opaddr Address of operation to rewrite with relocation * @param[in] opval Value of looked up symbol to relocate */ -void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval); +void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval); /** * @} diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index d46e021b894..24f48414ad8 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -403,7 +403,7 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext return ret; } -__weak void arch_elf_relocate(elf_rel_t *rel, uintptr_t opaddr, uintptr_t opval) +__weak void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval) { } @@ -412,7 +412,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) int ret = 0; uintptr_t loc = 0; elf_shdr_t shdr; - elf_rel_t rel; + elf_rela_t rel; elf_sym_t sym; size_t pos = ldr->hdr.e_shoff; elf_word rel_cnt = 0; From 3508cd609c9e13b21b10d592ee4ef5f3817f787e Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Thu, 9 Nov 2023 11:33:31 +0100 Subject: [PATCH 3379/4498] net: openthread: upmerge to `6edb06e` Regular OpenThread upmerge to `6edb06e`. Also add `OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC` config. Signed-off-by: Eduardo Montoya --- modules/openthread/CMakeLists.txt | 6 ++++++ modules/openthread/Kconfig.features | 7 +++++++ west.yml | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 826d9b31590..bad6d131771 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -148,6 +148,12 @@ else() set(OT_CSL_RECEIVER OFF CACHE BOOL "Enable CSL receiver feature for Thread 1.2" FORCE) endif() +if(CONFIG_OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC) + set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC ON CACHE BOOL "Use local time for CSL sync" FORCE) +else() + set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC OFF CACHE BOOL "Use local time for CSL sync" FORCE) +endif() + if(CONFIG_OPENTHREAD_DATASET_UPDATER) set(OT_DATASET_UPDATER ON CACHE BOOL "Enable Dataset updater" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 87c220944a4..a75c9e8fd48 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -92,6 +92,13 @@ config OPENTHREAD_CSL_RECEIVER help Enable CSL Receiver support for Thread 1.2 +config OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC + bool "Use local time for CSL synchronization" + help + Use host time rather than radio platform time to track elapsed time + since last CSL synchronization. This reduces the usage of radio API + calls, and it is useful for platforms in which those are costly. + config OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT bool "Device props for leader weight" default n if (OPENTHREAD_THREAD_VERSION_1_1 || \ diff --git a/west.yml b/west.yml index 6a9d1e743bb..62194f60c19 100644 --- a/west.yml +++ b/west.yml @@ -301,7 +301,7 @@ manifest: revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread - revision: d62167ee34b091e7025c9ec2820aae71e17a3944 + revision: 6edb06e4e0472411200ce2a084a783eaf3faffe3 path: modules/lib/openthread - name: percepio path: modules/debug/percepio From 1572ea16fc70c7bb0ab681f7b300e798592c7a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 9 Nov 2023 17:36:17 +0700 Subject: [PATCH 3380/4498] drivers: can: nxp_s32_canxl: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Signed-off-by: Manuel Argüelles --- drivers/can/can_nxp_s32_canxl.c | 110 ++++++++++++++++--------------- dts/arm/nxp/nxp_s32z27x_r52.dtsi | 4 +- 2 files changed, 60 insertions(+), 54 deletions(-) diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index 9083569f702..211e901055f 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -933,6 +933,20 @@ static int can_nxp_s32_init(const struct device *dev) return 0; } +static void can_nxp_s32_isr_rx_tx(const struct device *dev) +{ + const struct can_nxp_s32_config *config = dev->config; + + Canexcel_Ip_RxTxIRQHandler(config->instance); +} + +static void can_nxp_s32_isr_error(const struct device *dev) +{ + const struct can_nxp_s32_config *config = dev->config; + + Canexcel_Ip_ErrIRQHandler(config->instance); +} + static const struct can_driver_api can_nxp_s32_driver_api = { .get_capabilities = can_nxp_s32_get_capabilities, .start = can_nxp_s32_start, @@ -983,19 +997,13 @@ static const struct can_driver_api can_nxp_s32_driver_api = { #endif }; -#define CAN_NXP_S32_NODE(n) DT_NODELABEL(can##n) - -#define CAN_NXP_S32_IRQ_HANDLER(n, irq_name) DT_CAT5(CANXL, n, _, irq_name, Handler) - -#define _CAN_NXP_S32_IRQ_CONFIG(node_id, prop, idx, n) \ +#define _CAN_NXP_S32_IRQ_CONFIG(node_id, prop, idx) \ do { \ - extern void (CAN_NXP_S32_IRQ_HANDLER(n, \ - DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)))(void); \ IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \ DT_IRQ_BY_IDX(node_id, idx, priority), \ - CAN_NXP_S32_IRQ_HANDLER(n, \ + UTIL_CAT(can_nxp_s32_isr_, \ DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), \ - NULL, \ + DEVICE_DT_GET(node_id), \ DT_IRQ_BY_IDX(node_id, idx, flags)); \ irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ } while (false); @@ -1003,15 +1011,14 @@ static const struct can_driver_api can_nxp_s32_driver_api = { #define CAN_NXP_S32_IRQ_CONFIG(n) \ static void can_irq_config_##n(void) \ { \ - DT_FOREACH_PROP_ELEM_VARGS(CAN_NXP_S32_NODE(n), interrupt_names, \ - _CAN_NXP_S32_IRQ_CONFIG, n); \ + DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, _CAN_NXP_S32_IRQ_CONFIG); \ } #define CAN_NXP_S32_ERR_CALLBACK(n) \ void nxp_s32_can_##n##_err_callback(uint8 instance, Canexcel_Ip_EventType eventType,\ uint32 u32SysStatus, const Canexcel_Ip_StateType *canexcelState) \ { \ - const struct device *dev = DEVICE_DT_GET(CAN_NXP_S32_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ can_nxp_s32_err_callback(dev, eventType, u32SysStatus, canexcelState); \ } @@ -1019,18 +1026,18 @@ static const struct can_driver_api can_nxp_s32_driver_api = { void nxp_s32_can_##n##_ctrl_callback(uint8 instance, Canexcel_Ip_EventType eventType,\ uint32 buffIdx, const Canexcel_Ip_StateType *canexcelState) \ { \ - const struct device *dev = DEVICE_DT_GET(CAN_NXP_S32_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ can_nxp_s32_ctrl_callback(dev, eventType, buffIdx, canexcelState); \ } #if defined(CONFIG_CAN_FD_MODE) #define CAN_NXP_S32_TIMING_DATA_CONFIG(n) \ - .bitrate_data = DT_PROP(CAN_NXP_S32_NODE(n), bus_speed_data), \ - .sjw_data = DT_PROP(CAN_NXP_S32_NODE(n), sjw_data), \ - .prop_seg_data = DT_PROP_OR(CAN_NXP_S32_NODE(n), prop_seg_data, 0), \ - .phase_seg1_data = DT_PROP_OR(CAN_NXP_S32_NODE(n), phase_seg1_data, 0), \ - .phase_seg2_data = DT_PROP_OR(CAN_NXP_S32_NODE(n), phase_seg2_data, 0), \ - .sample_point_data = DT_PROP_OR(CAN_NXP_S32_NODE(n), sample_point_data, 0), + .bitrate_data = DT_INST_PROP(n, bus_speed_data), \ + .sjw_data = DT_INST_PROP(n, sjw_data), \ + .prop_seg_data = DT_INST_PROP_OR(n, prop_seg_data, 0), \ + .phase_seg1_data = DT_INST_PROP_OR(n, phase_seg1_data, 0), \ + .phase_seg2_data = DT_INST_PROP_OR(n, phase_seg2_data, 0), \ + .sample_point_data = DT_INST_PROP_OR(n, sample_point_data, 0), #define CAN_NXP_S32_FD_MODE 1 #define CAN_NXP_S32_BRS 1 #else @@ -1045,11 +1052,17 @@ static const struct can_driver_api can_nxp_s32_driver_api = { #define CAN_NXP_S32_CTRL_OPTIONS 0 #endif +#define CAN_NXP_S32_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_CANXL_##i##__SIC_BASE) ? i : 0) + +#define CAN_NXP_S32_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET CANXL_SIC_INSTANCE_COUNT, CAN_NXP_S32_HW_INSTANCE_CHECK, (|), n) + #define CAN_NXP_S32_INIT_DEVICE(n) \ CAN_NXP_S32_CTRL_CALLBACK(n) \ CAN_NXP_S32_ERR_CALLBACK(n) \ CAN_NXP_S32_IRQ_CONFIG(n) \ - PINCTRL_DT_DEFINE(CAN_NXP_S32_NODE(n)); \ + PINCTRL_DT_INST_DEFINE(n); \ Canexcel_Ip_ConfigType can_nxp_s32_default_config##n = { \ .rx_mbdesc = (uint8)CONFIG_CAN_NXP_S32_MAX_RX, \ .tx_mbdesc = (uint8)CONFIG_CAN_NXP_S32_MAX_TX, \ @@ -1069,27 +1082,26 @@ static const struct can_driver_api can_nxp_s32_driver_api = { .rx_msg = rx_msg_##n, \ }; \ static struct can_nxp_s32_config can_nxp_s32_config_##n = { \ - .base_sic = (CANXL_SIC_Type *) \ - DT_REG_ADDR_BY_NAME(CAN_NXP_S32_NODE(n), sic), \ + .base_sic = (CANXL_SIC_Type *)DT_INST_REG_ADDR_BY_NAME(n, sic), \ .base_grp_ctrl = (CANXL_GRP_CONTROL_Type *) \ - DT_REG_ADDR_BY_NAME(CAN_NXP_S32_NODE(n), grp_ctrl), \ + DT_INST_REG_ADDR_BY_NAME(n, grp_ctrl), \ .base_dsc_ctrl = (CANXL_DSC_CONTROL_Type *) \ - DT_REG_ADDR_BY_NAME(CAN_NXP_S32_NODE(n), dsc_ctrl), \ - .instance = n, \ - .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(CAN_NXP_S32_NODE(n))), \ + DT_INST_REG_ADDR_BY_NAME(n, dsc_ctrl), \ + .instance = CAN_NXP_S32_HW_INSTANCE(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t) \ - DT_CLOCKS_CELL(CAN_NXP_S32_NODE(n), name), \ - .bitrate = DT_PROP(CAN_NXP_S32_NODE(n), bus_speed), \ - .sjw = DT_PROP(CAN_NXP_S32_NODE(n), sjw), \ - .prop_seg = DT_PROP_OR(CAN_NXP_S32_NODE(n), prop_seg, 0), \ - .phase_seg1 = DT_PROP_OR(CAN_NXP_S32_NODE(n), phase_seg1, 0), \ - .phase_seg2 = DT_PROP_OR(CAN_NXP_S32_NODE(n), phase_seg2, 0), \ - .sample_point = DT_PROP_OR(CAN_NXP_S32_NODE(n), sample_point, 0), \ + DT_INST_CLOCKS_CELL(n, name), \ + .bitrate = DT_INST_PROP(n, bus_speed), \ + .sjw = DT_INST_PROP(n, sjw), \ + .prop_seg = DT_INST_PROP_OR(n, prop_seg, 0), \ + .phase_seg1 = DT_INST_PROP_OR(n, phase_seg1, 0), \ + .phase_seg2 = DT_INST_PROP_OR(n, phase_seg2, 0), \ + .sample_point = DT_INST_PROP_OR(n, sample_point, 0), \ CAN_NXP_S32_TIMING_DATA_CONFIG(n) \ - .max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(CAN_NXP_S32_NODE(n), \ + .max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(n, \ CAN_NXP_S32_MAX_BITRATE), \ - .phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(CAN_NXP_S32_NODE(n), phys)), \ - .pin_cfg = PINCTRL_DT_DEV_CONFIG_GET(CAN_NXP_S32_NODE(n)), \ + .phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(n, phys)), \ + .pin_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .can_cfg = (Canexcel_Ip_ConfigType *)&can_nxp_s32_default_config##n, \ .irq_config_func = can_irq_config_##n \ }; \ @@ -1097,19 +1109,13 @@ static const struct can_driver_api can_nxp_s32_driver_api = { { \ return can_nxp_s32_init(dev); \ } \ - CAN_DEVICE_DT_DEFINE(CAN_NXP_S32_NODE(n), \ - can_nxp_s32_##n##_init, \ - NULL, \ - &can_nxp_s32_data_##n, \ - &can_nxp_s32_config_##n, \ - POST_KERNEL, \ - CONFIG_CAN_INIT_PRIORITY, \ - &can_nxp_s32_driver_api); - -#if DT_NODE_HAS_STATUS(CAN_NXP_S32_NODE(0), okay) -CAN_NXP_S32_INIT_DEVICE(0) -#endif - -#if DT_NODE_HAS_STATUS(CAN_NXP_S32_NODE(1), okay) -CAN_NXP_S32_INIT_DEVICE(1) -#endif + CAN_DEVICE_DT_INST_DEFINE(n, \ + can_nxp_s32_##n##_init, \ + NULL, \ + &can_nxp_s32_data_##n, \ + &can_nxp_s32_config_##n, \ + POST_KERNEL, \ + CONFIG_CAN_INIT_PRIORITY, \ + &can_nxp_s32_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(CAN_NXP_S32_INIT_DEVICE) diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index e26ae436860..4f92c8ca71a 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -700,7 +700,7 @@ status = "disabled"; interrupts = , ; - interrupt-names = "RX_TX_DATA_IRQ", "INT_ERROR_IRQ"; + interrupt-names = "rx_tx", "error"; clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; @@ -713,7 +713,7 @@ status = "disabled"; interrupts = , ; - interrupt-names = "RX_TX_DATA_IRQ", "INT_ERROR_IRQ"; + interrupt-names = "rx_tx", "error"; clocks = <&clock NXP_S32_P5_CANXL_PE_CLK>; }; }; From 62b01532496d8b4ed7ede7b23bcabf351aaa1aba Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 9 Nov 2023 17:16:28 +0000 Subject: [PATCH 3381/4498] ci: doc-build: only rebase on pull requests Skip the rebase step if it's not a pull request. Schedule and push runs have no base ref to rebase against anyway, currently the step is failing and being skipped. Signed-off-by: Fabio Baltieri --- .github/workflows/doc-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f4cad6bfa0d..7bfeb25b26a 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -50,6 +50,7 @@ jobs: fetch-depth: 0 - name: Rebase + if: github.event_name == 'pull_request' continue-on-error: true env: BASE_REF: ${{ github.base_ref }} From 35e9104de7a32a1cb2f7083015da0609a89f04b5 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 9 Nov 2023 17:28:26 +0000 Subject: [PATCH 3382/4498] ci: doc-build: add the container owner workaround step Seems like the PDF build hit the "detected dubious ownership in repository" issue that has already been worked around in other workflow. Add that step here as well. Signed-off-by: Fabio Baltieri --- .github/workflows/doc-build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 7bfeb25b26a..fa83fe252c7 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -161,6 +161,10 @@ jobs: cancel-in-progress: true steps: + - name: Apply container owner mismatch workaround + run: | + git config --global --add safe.directory ${GITHUB_WORKSPACE} + - name: checkout uses: actions/checkout@v3 From d291ef457702e1adbcb6c1ab95e6de50a9dab641 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 3 Nov 2023 15:01:58 -0500 Subject: [PATCH 3383/4498] doc: charger: Removes misleading statement at introduction Removes a statement at the introduction claiming only getting properties is supported by the API. The charger API can get/set properties. Signed-off-by: Ricardo Rivera-Matos --- doc/hardware/peripherals/charger.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/hardware/peripherals/charger.rst b/doc/hardware/peripherals/charger.rst index a3e2c177e3e..6158eaacdc8 100644 --- a/doc/hardware/peripherals/charger.rst +++ b/doc/hardware/peripherals/charger.rst @@ -3,8 +3,7 @@ Chargers ######## -The charger subsystem exposes an API to uniformly access battery charger devices. Currently, -only reading data is supported. +The charger subsystem exposes an API to uniformly access battery charger devices. Basic Operation *************** From 2253ba571bb330900e599b1ed363e27837956ab0 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 3 Nov 2023 15:06:42 -0500 Subject: [PATCH 3384/4498] docs: charger: Corrects text in the Properties section Correct Properties subsection of the document to be accurate to the latest implementation of the charger API. Signed-off-by: Ricardo Rivera-Matos --- doc/hardware/peripherals/charger.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/hardware/peripherals/charger.rst b/doc/hardware/peripherals/charger.rst index 6158eaacdc8..b88876058b8 100644 --- a/doc/hardware/peripherals/charger.rst +++ b/doc/hardware/peripherals/charger.rst @@ -17,8 +17,8 @@ measure. Chargers typically support multiple properties, such as temperature readings of the battery-pack or present-time current/voltage. -Properties are fetched using a client allocated array of :c:struct:`charger_get_property`. This -array is then populated by values as according to its `property_type` field. +Properties are fetched by the client one at a time using :c:func:`charger_get_prop`. +Properties are set by the client one at a time using :c:func:`charger_set_prop`. .. _charger_api_reference: From 1a0b1124c6294b9f3851b54fc7d0aeeba12a5f34 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Thu, 9 Nov 2023 11:17:22 -0600 Subject: [PATCH 3385/4498] MAINTAINERS: charger: Adds entry for "Chargers" Adds an entry for the charging API. Signed-off-by: Ricardo Rivera-Matos --- MAINTAINERS.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 883f9afed53..b65679cb6a1 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -840,6 +840,20 @@ Release Notes: labels: - "area: CAN" +"Drivers: Charger": + status: maintained + maintainers: + - aaronemassey + - rriveramcrus + files: + - drivers/charger/ + - dts/bindings/charger/ + - include/zephyr/drivers/charger.h + - tests/drivers/charger/ + - doc/hardware/peripherals/charger.rst + labels: + - "area: Charger" + "Drivers: Clock control": status: maintained maintainers: From 38373aa599d884fedfbc94a921a0179cb8097384 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 9 Nov 2023 17:10:54 -0500 Subject: [PATCH 3386/4498] riscv: FPU trap: catch fused multiply-add instructions The FMADD, FMSUB, FNMSUB and FNMADD instructions occupy major opcode spaces of their own, separate from LOAD-FP/STORE-FP and OP-FP spaces. Insert code to cover them. Signed-off-by: Nicolas Pitre --- arch/riscv/core/isr.S | 17 +++++++++++++-- tests/arch/riscv/fpu_sharing/src/main.c | 28 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index ab90d2b1d1e..c36679ae6db 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -187,10 +187,23 @@ SECTION_FUNC(exception.entry, _isr_wrapper) 1: #endif andi t0, t2, 0x7f /* keep only the opcode bits */ + /* + * Major FP opcodes: + * 0000111 = LOAD-FP + * 0100111 = STORE-FP + * 1000011 = MADD + * 1000111 = MSUB + * 1001011 = NMSUB + * 1001111 = NMADD + * 1010011 = OP-FP + */ xori t1, t0, 0b1010011 /* OP-FP */ beqz t1, is_fp - ori t0, t0, 0b0100000 - xori t1, t0, 0b0100111 /* LOAD-FP / STORE-FP */ + ori t1, t0, 0b0100000 + xori t1, t1, 0b0100111 /* LOAD-FP / STORE-FP */ + beqz t1, is_fp + ori t1, t0, 0b0001100 + xori t1, t1, 0b1001111 /* MADD / MSUB / NMSUB / NMADD */ beqz t1, is_fp /* * The FRCSR, FSCSR, FRRM, FSRM, FSRMI, FRFLAGS, FSFLAGS and FSFLAGSI diff --git a/tests/arch/riscv/fpu_sharing/src/main.c b/tests/arch/riscv/fpu_sharing/src/main.c index db44fe34c47..1884adde313 100644 --- a/tests/arch/riscv/fpu_sharing/src/main.c +++ b/tests/arch/riscv/fpu_sharing/src/main.c @@ -417,6 +417,34 @@ ZTEST(riscv_fpu_sharing, test_fp_insn_trap) "got %#llx instead", buf64); #endif #endif /* CONFIG_RISCV_ISA_EXT_C */ + + /* MADD major opcode space */ + reg = 3579; + TEST_TRAP("fcvt.s.w fa1, %0"); + TEST_TRAP("fmadd.s fa0, fa1, fa1, fa1"); + TEST_TRAP("fcvt.w.s %0, fa0"); + zassert_true(reg == 12812820, "got %ld instead", reg); + + /* NMSUB major opcode space */ + reg = 1234; + TEST_TRAP("fcvt.s.w fa1, %0"); + TEST_TRAP("fmsub.s fa0, fa1, fa1, fa0"); + TEST_TRAP("fcvt.w.s %0, fa0"); + zassert_true(reg == -11290064, "got %ld instead", reg); + + /* NMSUB major opcode space */ + reg = -23; + TEST_TRAP("fcvt.s.w fa1, %0"); + TEST_TRAP("fnmsub.s fa0, fa1, fa1, fa0"); + TEST_TRAP("fcvt.w.s %0, fa0"); + zassert_true(reg == -11290593, "got %ld instead", reg); + + /* NMADD major opcode space */ + reg = 765; + TEST_TRAP("fcvt.s.w fa1, %0"); + TEST_TRAP("fnmadd.s fa0, fa1, fa1, fa1"); + TEST_TRAP("fcvt.w.s %0, fa0"); + zassert_true(reg == -585990, "got %ld instead", reg); } ZTEST_SUITE(riscv_fpu_sharing, NULL, NULL, NULL, NULL, NULL); From b2fb5706357b2583f41b5049d85ac2a75c606da2 Mon Sep 17 00:00:00 2001 From: Maciej Zagrabski Date: Thu, 9 Nov 2023 21:33:17 +0100 Subject: [PATCH 3387/4498] net: wifi: Pass psk and sae as const There shouldn't be any reason to be able to modify the passed psk, and having this non-const gives application warnings if passing a constant string. Signed-off-by: Maciej Zagrabski --- include/zephyr/net/wifi_mgmt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ae5bf27370d..faf83b42b84 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -302,11 +302,11 @@ struct wifi_connect_req_params { /** SSID length */ uint8_t ssid_length; /* Max 32 */ /** Pre-shared key */ - uint8_t *psk; + const uint8_t *psk; /** Pre-shared key length */ uint8_t psk_length; /* Min 8 - Max 64 */ /** SAE password (same as PSK but with no length restrictions), optional */ - uint8_t *sae_password; + const uint8_t *sae_password; /** SAE password length */ uint8_t sae_password_length; /* No length restrictions */ /** Frequency band */ From bcaa7c2bdbb3affd0e645c76505aaa3458588f4e Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Thu, 9 Nov 2023 13:14:23 +0200 Subject: [PATCH 3388/4498] boards: arm64: xenvm: read real frequency Read real frequncy from ARM Arch Timer instead of using define 'CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC' which can be incorrect for some run cases. If we run xenvm under qemu we get one frequency, but we can run this build as a DomU for Xen under different real platforms and thus with differenty arch timer frequencies. So, we need to read frequency from the timer registers. Signed-off-by: Mykola Kvach --- boards/arm64/xenvm/xenvm_defconfig | 2 ++ boards/arm64/xenvm/xenvm_gicv3_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/boards/arm64/xenvm/xenvm_defconfig b/boards/arm64/xenvm/xenvm_defconfig index ff8597199e7..39e8a20767c 100644 --- a/boards/arm64/xenvm/xenvm_defconfig +++ b/boards/arm64/xenvm/xenvm_defconfig @@ -16,3 +16,5 @@ CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=n CONFIG_USERSPACE=n + +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y diff --git a/boards/arm64/xenvm/xenvm_gicv3_defconfig b/boards/arm64/xenvm/xenvm_gicv3_defconfig index 59a0c306cb7..7b6b9afa888 100644 --- a/boards/arm64/xenvm/xenvm_gicv3_defconfig +++ b/boards/arm64/xenvm/xenvm_gicv3_defconfig @@ -15,3 +15,5 @@ CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=n CONFIG_USERSPACE=n + +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y From 4ce5f7ebe118e466d7d69f9a09c22c2d82d08ae2 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Thu, 9 Nov 2023 13:50:31 +0900 Subject: [PATCH 3389/4498] arch: riscv: fix hangup of multicore boot This patch fixes hangup of RISC-V multicore boot. Currently boot sequence uses a riscv_cpu_wake_flag to notify wakeup request for secondary core(s). But initial value of riscv_cpu_wake_flag is undefined, so current mechanism is going to hangup if riscv_cpu_wake_flag and mhartid of secondary core have the same value. This is an example situation of this problem: - hart1: check riscv_cpu_wake_flag (value is 1) and end the loop - hart1: set riscv_cpu_wake_flag to 0 - hart0: set riscv_cpu_wake_flag to 1 hart0 expects it will be changed to 0 by hart1 but it has never happened Note: - hart0's mhartid is 0, hart1's mhartid is 1 - hart0 is main, hart1 is secondary in this example Signed-off-by: Katsuhiro Suzuki --- arch/riscv/core/reset.S | 14 +++++++++++--- arch/riscv/core/smp.c | 7 ++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/riscv/core/reset.S b/arch/riscv/core/reset.S index 094e51b9183..e2faa6fe94d 100644 --- a/arch/riscv/core/reset.S +++ b/arch/riscv/core/reset.S @@ -93,16 +93,24 @@ aa_loop: boot_secondary_core: #if CONFIG_MP_MAX_NUM_CPUS > 1 + la t0, riscv_cpu_wake_flag + li t1, -1 + sr t1, 0(t0) + la t0, riscv_cpu_boot_flag + sr zero, 0(t0) + +wait_secondary_wake_flag: la t0, riscv_cpu_wake_flag lr t0, 0(t0) - bne a0, t0, boot_secondary_core + bne a0, t0, wait_secondary_wake_flag /* Set up stack */ la t0, riscv_cpu_sp lr sp, 0(t0) - la t0, riscv_cpu_wake_flag - sr zero, 0(t0) + la t0, riscv_cpu_boot_flag + li t1, 1 + sr t1, 0(t0) j z_riscv_secondary_cpu_init #else j loop_unconfigured_cores diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 7bcfff6828e..a5499d4e16b 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -17,6 +17,7 @@ volatile struct { } riscv_cpu_init[CONFIG_MP_MAX_NUM_CPUS]; volatile uintptr_t riscv_cpu_wake_flag; +volatile uintptr_t riscv_cpu_boot_flag; volatile void *riscv_cpu_sp; extern void __start(void); @@ -28,7 +29,7 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, riscv_cpu_init[cpu_num].arg = arg; riscv_cpu_sp = Z_KERNEL_STACK_BUFFER(stack) + sz; - riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid; + riscv_cpu_boot_flag = 0U; #ifdef CONFIG_PM_CPU_OPS if (pm_cpu_on(cpu_num, (uintptr_t)&__start)) { @@ -37,8 +38,8 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, } #endif - while (riscv_cpu_wake_flag != 0U) { - ; + while (riscv_cpu_boot_flag == 0U) { + riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid; } } From 344d24bcb7f6b5072b67cc7cc9f38556455cb603 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 8 Nov 2023 11:06:08 -0600 Subject: [PATCH 3390/4498] docs: Better document the DMA API and expectations The DMA API has several expectations for drivers and callers that were underdocumented or undocumented. Better clarify the driver expectations and caller expectations. The DMA API from the caller side is not a portable API and really cannot be as each DMA has unique properties and expectations of memory, peripheral interaction, and features. The API in effect provides a union of all useful DMA functionality drivers have needed in the tree. It can still be a good abstraction, with care, for peripheral devices for vendors where the DMA IP might be very similar but have slight variances. From the driver implementation side expectations around synchronization, state transitions, and memory management for transfer descriptors is now described in documentation rather than solely from me in github review comments. Signed-off-by: Tom Burdick --- doc/hardware/peripherals/dma.rst | 66 ++++++++++++++++++++++++++++++++ include/zephyr/drivers/dma.h | 26 ++++++++++--- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/doc/hardware/peripherals/dma.rst b/doc/hardware/peripherals/dma.rst index 198590905d3..53fd18a1aa7 100644 --- a/doc/hardware/peripherals/dma.rst +++ b/doc/hardware/peripherals/dma.rst @@ -6,6 +6,72 @@ Direct Memory Access (DMA) Overview ******** +Direct Memory Access (Controller) is a commonly provided type of co-processor that can typically +offload transferring data to and from peripherals and memory. + +The DMA API is not a portable API and really cannot be as each DMA has unique memory requirements, +peripheral interactions, and features. The API in effect provides a union of all useful DMA +functionality drivers have needed in the tree. It can still be a good abstraction, with care, for +peripheral devices for vendors where the DMA IP might be very similar but have slight variances. + +Driver Implementation Expectations +********************************** + +Synchronization and Ownership ++++++++++++++++++++++++++++++ + +From an API point of view, a DMA channel is a single-owner object, meaning the drivers should not +attempt to wrap a channel with kernel synchronization primitives such as mutexes or semaphores. If +DMA channels require mutating shared registers, those register updates should be wrapped in a spin +lock. + +This enables the entire API to be low-cost and callable from any call context, including ISRs where +it may be very useful to start/stop/suspend/resume/reload a channel transfer. + +Transfer Descriptor Memory Management ++++++++++++++++++++++++++++++++++++++ + +Drivers should not attempt to use heap allocations of any kind. If object pools are needed for +transfer descriptors then those should be setup in a way that does not break the promise of +ISR-allowable calls. Many drivers choose to create a simple static descriptor array per channel with +the size of the descriptor array adjustable using Kconfig. + +Channel State Machine Expectations +++++++++++++++++++++++++++++++++++ + +DMA channels should be viewed as state machines that the DMA API provides transition events for in +the form of API calls. Every driver is expected to maintain its own channel state tracking. The busy +state of the channel should be inspectable at any time with :c:func:`dma_get_status()`. + +A diagram showing those expectated possible state transitions and their API calls is provided here +for reference. + +.. graphviz:: + :caption: DMA state finite state machine + + digraph { + node [style=rounded]; + edge [fontname=Courier]; + init [shape=point]; + + CONFIGURED [label=Configured,shape=box]; + RUNNING [label=Running,shape=box]; + SUSPENDED [label=Suspended,shape=box]; + + init -> CONFIGURED [label=dma_config]; + + CONFIGURED -> RUNNING [label=dma_start]; + CONFIGURED -> CONFIGURED [label=dma_stop]; + + RUNNING -> CONFIGURED [label=dma_stop]; + RUNNING -> RUNNING [label=dma_start]; + RUNNING -> RUNNING [label=dma_resume, headport=w]; + RUNNING -> SUSPENDED [label=dma_suspend]; + + SUSPENDED -> SUSPENDED [label=dma_suspend]; + SUSPENDED -> RUNNING [label=dma_resume]; + SUSPENDED -> CONFIGURED [label=dma_stop]; + } API Reference ************* diff --git a/include/zephyr/drivers/dma.h b/include/zephyr/drivers/dma.h index eb04334101d..2dd82651501 100644 --- a/include/zephyr/drivers/dma.h +++ b/include/zephyr/drivers/dma.h @@ -386,6 +386,8 @@ static inline int dma_reload(const struct device *dev, uint32_t channel, * Start is allowed on channels that have already been started and must report * success. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel Numeric identification of the channel where the transfer will * be processed @@ -412,6 +414,8 @@ static inline int z_impl_dma_start(const struct device *dev, uint32_t channel) * Stop is allowed on channels that have already been stopped and must report * success. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel Numeric identification of the channel where the transfer was * being processed @@ -436,6 +440,8 @@ static inline int z_impl_dma_stop(const struct device *dev, uint32_t channel) * Implementations must check the validity of the channel state and ID passed * in and return -EINVAL if either are invalid. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel Numeric identification of the channel to suspend * @@ -462,6 +468,8 @@ static inline int z_impl_dma_suspend(const struct device *dev, uint32_t channel) * Implementations must check the validity of the channel state and ID passed * in and return -EINVAL if either are invalid. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel Numeric identification of the channel to resume * @@ -488,6 +496,8 @@ static inline int z_impl_dma_resume(const struct device *dev, uint32_t channel) * request DMA channel resources * return -EINVAL if there is no valid channel available. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param filter_param filter function parameter * @@ -531,6 +541,8 @@ static inline int z_impl_dma_request_channel(const struct device *dev, * * release DMA channel resources * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel channel number * @@ -587,6 +599,8 @@ static inline int z_impl_dma_chan_filter(const struct device *dev, * Implementations must check the validity of the channel ID passed in and * return -EINVAL if it is invalid or -ENOSYS if not supported. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param channel Numeric identification of the channel where the transfer was * being processed @@ -616,6 +630,8 @@ static inline int dma_get_status(const struct device *dev, uint32_t channel, * Implementations must check the validity of the type passed in and * return -EINVAL if it is invalid or -ENOSYS if not supported. * + * @funcprops \isr_ok + * * @param dev Pointer to the device structure for the driver instance. * @param type Numeric identification of the attribute * @param value A non-NULL pointer to the variable where the read value is to be placed @@ -637,7 +653,7 @@ static inline int dma_get_attribute(const struct device *dev, uint32_t type, uin /** * @brief Look-up generic width index to be used in registers * - * WARNING: This look-up works for most controllers, but *may* not work for + * @warning This look-up works for most controllers, but *may* not work for * yours. Ensure your controller expects the most common register * bit values before using this convenience function. If your * controller does not support these values, you will have to write @@ -666,7 +682,7 @@ static inline uint32_t dma_width_index(uint32_t size) /** * @brief Look-up generic burst index to be used in registers * - * WARNING: This look-up works for most controllers, but *may* not work for + * @warning This look-up works for most controllers, but *may* not work for * yours. Ensure your controller expects the most common register * bit values before using this convenience function. If your * controller does not support these values, you will have to write @@ -693,7 +709,7 @@ static inline uint32_t dma_burst_index(uint32_t burst) } /** - * Get the device tree property describing the buffer address alignment + * @brief Get the device tree property describing the buffer address alignment * * Useful when statically defining or allocating buffers for DMA usage where * memory alignment often matters. @@ -704,7 +720,7 @@ static inline uint32_t dma_burst_index(uint32_t burst) #define DMA_BUF_ADDR_ALIGNMENT(node) DT_PROP(node, dma_buf_addr_alignment) /** - * Get the device tree property describing the buffer size alignment + * @brief Get the device tree property describing the buffer size alignment * * Useful when statically defining or allocating buffers for DMA usage where * memory alignment often matters. @@ -715,7 +731,7 @@ static inline uint32_t dma_burst_index(uint32_t burst) #define DMA_BUF_SIZE_ALIGNMENT(node) DT_PROP(node, dma_buf_size_alignment) /** - * Get the device tree property describing the minimal chunk of data possible to be copied + * @brief Get the device tree property describing the minimal chunk of data possible to be copied * * @param node Node identifier, e.g. DT_NODELABEL(dma_0) * @return minimal Minimal chunk of data possible to be copied From 986422f4f2461762ab86c16426381d2db4ab5bb2 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Thu, 9 Nov 2023 09:59:38 -0600 Subject: [PATCH 3391/4498] dma: Move struct member doc comments to fields To better cover the struct fields of the DMA API in doxygen the fields are now individually documented rather than documenting them ad-hoc in the struct header doc comment. A best attempt at marking fields that are HW specific has been done as well. That means almost all of them. Signed-off-by: Tom Burdick --- include/zephyr/drivers/dma.h | 224 +++++++++++++++++++++-------------- 1 file changed, 132 insertions(+), 92 deletions(-) diff --git a/include/zephyr/drivers/dma.h b/include/zephyr/drivers/dma.h index 2dd82651501..2905c6fc434 100644 --- a/include/zephyr/drivers/dma.h +++ b/include/zephyr/drivers/dma.h @@ -28,12 +28,21 @@ extern "C" { * @{ */ +/** + * @brief DMA channel direction + */ enum dma_channel_direction { + /** Memory to memory */ MEMORY_TO_MEMORY = 0x0, + /** Memory to peripheral */ MEMORY_TO_PERIPHERAL, + /** Peripheral to memory */ PERIPHERAL_TO_MEMORY, + /** Peripheral to peripheral */ PERIPHERAL_TO_PERIPHERAL, + /** Host to memory */ HOST_TO_MEMORY, + /** Memory to host */ MEMORY_TO_HOST, /** @@ -53,20 +62,31 @@ enum dma_channel_direction { DMA_CHANNEL_DIRECTION_MAX = 0x7 }; -/** Valid values for @a source_addr_adj and @a dest_addr_adj */ +/** + * @brief DMA address adjustment + * + * Valid values for @a source_addr_adj and @a dest_addr_adj + */ enum dma_addr_adj { + /** Increment the address */ DMA_ADDR_ADJ_INCREMENT, + /** Decrement the address */ DMA_ADDR_ADJ_DECREMENT, + /** No change the address */ DMA_ADDR_ADJ_NO_CHANGE, }; -/* channel attributes */ +/** + * @brief DMA channel attributes + */ enum dma_channel_filter { DMA_CHANNEL_NORMAL, /* normal DMA channel */ DMA_CHANNEL_PERIODIC, /* can be triggered by periodic sources */ }; -/* DMA attributes */ +/** + * @brief DMA attributes + */ enum dma_attribute_type { DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, @@ -78,65 +98,73 @@ enum dma_attribute_type { * @struct dma_block_config * @brief DMA block configuration structure. * - * @param source_address is block starting address at source - * @param source_gather_interval is the address adjustment at gather boundary - * @param dest_address is block starting address at destination - * @param dest_scatter_interval is the address adjustment at scatter boundary - * @param dest_scatter_count is the continuous transfer count between scatter - * boundaries - * @param source_gather_count is the continuous transfer count between gather - * boundaries - * - * @param block_size is the number of bytes to be transferred for this block. - * - * @param config is a bit field with the following parts: - * - * source_gather_en [ 0 ] - 0-disable, 1-enable. - * dest_scatter_en [ 1 ] - 0-disable, 1-enable. - * source_addr_adj [ 2 : 3 ] - 00-increment, 01-decrement, - * 10-no change. - * dest_addr_adj [ 4 : 5 ] - 00-increment, 01-decrement, - * 10-no change. - * source_reload_en [ 6 ] - reload source address at the end of - * block transfer - * 0-disable, 1-enable. - * dest_reload_en [ 7 ] - reload destination address at the end - * of block transfer - * 0-disable, 1-enable. - * fifo_mode_control [ 8 : 11 ] - How full of the fifo before transfer - * start. HW specific. - * flow_control_mode [ 12 ] - 0-source request served upon data - * availability. - * 1-source request postponed until - * destination request happens. - * reserved [ 13 : 15 ] + * Aside from source address, destination address, and block size many of these options are hardware + * and driver dependent. */ struct dma_block_config { #ifdef CONFIG_DMA_64BIT + /** block starting address at source */ uint64_t source_address; + /** block starting address at destination */ uint64_t dest_address; #else + /** block starting address at source */ uint32_t source_address; + /** block starting address at destination */ uint32_t dest_address; #endif + /** Address adjustment at gather boundary */ uint32_t source_gather_interval; + /** Address adjustment at scatter boundary */ uint32_t dest_scatter_interval; + /** Continuous transfer count between scatter boundaries */ uint16_t dest_scatter_count; + /** Continuous transfer count between gather boundaries */ uint16_t source_gather_count; + /** Number of bytes to be transferred for this block */ uint32_t block_size; + /** Pointer to next block in a transfer list */ struct dma_block_config *next_block; + /** Enable source gathering when set to 1 */ uint16_t source_gather_en : 1; + /** Enable destination scattering when set to 1 */ uint16_t dest_scatter_en : 1; + /** + * Source address adjustment option + * + * - 0b00 increment + * - 0b01 decrement + * - 0b10 no change + */ uint16_t source_addr_adj : 2; + /** + * Destination address adjustment + * + * - 0b00 increment + * - 0b01 decrement + * - 0b10 no change + */ uint16_t dest_addr_adj : 2; + /** Reload source address at the end of block transfer */ uint16_t source_reload_en : 1; + /** Reload destination address at the end of block transfer */ uint16_t dest_reload_en : 1; + /** FIFO fill before starting transfer, HW specific meaning */ uint16_t fifo_mode_control : 4; + /** + * Transfer flow control mode + * + * - 0b0 source request service upon data availability + * - 0b1 source request postponed until destination request happens + */ uint16_t flow_control_mode : 1; - uint16_t reserved : 3; + + uint16_t _reserved : 3; }; +/** The DMA callback event has occurred at the completion of a transfer list */ #define DMA_STATUS_COMPLETE 0 +/** The DMA callback has occurred at the completion of a single transfer block in a transfer list */ #define DMA_STATUS_BLOCK 1 /** @@ -151,10 +179,11 @@ struct dma_block_config { * @param dev Pointer to the DMA device calling the callback. * @param user_data A pointer to some user data or NULL * @param channel The channel number - * @param status - 0-DMA_STATUS_COMPLETE buffer fully consumed - * - 1-DMA_STATUS_BLOCK buffer consumption reached a configured block + * @param status Status of the transfer + * - DMA_STATUS_COMPLETE buffer fully consumed + * - DMA_STATUS_BLOCK buffer consumption reached a configured block * or water mark - * - a negative errno otherwise + * - A negative errno otherwise */ typedef void (*dma_callback_t)(const struct device *dev, void *user_data, uint32_t channel, int status); @@ -162,86 +191,99 @@ typedef void (*dma_callback_t)(const struct device *dev, void *user_data, /** * @struct dma_config * @brief DMA configuration structure. - * - * @param dma_slot [ 0 : 7 ] - which peripheral and direction - * (HW specific) - * @param channel_direction [ 8 : 10 ] - 000-memory to memory, - * 001-memory to peripheral, - * 010-peripheral to memory, - * 011-peripheral to peripheral, - * 100-host to memory - * 101-memory to host - * ... - * @param complete_callback_en [ 11 ] - 0-callback invoked at completion only - * 1-callback invoked at completion of - * each block - * @param error_callback_en [ 12 ] - 0-error callback enabled - * 1-error callback disabled - * @param source_handshake [ 13 ] - 0-HW, 1-SW - * @param dest_handshake [ 14 ] - 0-HW, 1-SW - * @param channel_priority [ 15 : 18 ] - DMA channel priority - * @param source_chaining_en [ 19 ] - enable/disable source block chaining - * 0-disable, 1-enable - * @param dest_chaining_en [ 20 ] - enable/disable destination block - * chaining. - * 0-disable, 1-enable - * @param linked_channel [ 21 : 27 ] - after channel count exhaust will - * initiate a channel service request - * at this channel - * @param cyclic [ 28 ] - enable/disable cyclic buffer - * 0-disable, 1-enable - * @param reserved [ 29 : 31 ] - * @param source_data_size [ 0 : 15 ] - width of source data (in bytes) - * @param dest_data_size [ 16 : 31 ] - width of dest data (in bytes) - * @param source_burst_length [ 0 : 15 ] - number of source data units - * @param dest_burst_length [ 16 : 31 ] - number of destination data units - * @param block_count is the number of blocks used for block chaining, this - * depends on availability of the DMA controller. - * @param user_data private data from DMA client. - * @param dma_callback see dma_callback_t for details */ struct dma_config { + /** Which peripheral and direction, HW specific */ uint32_t dma_slot : 8; + /** + * Direction the transfers are occurring + * + * - 0b000 memory to memory, + * - 0b001 memory to peripheral, + * - 0b010 peripheral to memory, + * - 0b011 peripheral to peripheral, + * - 0b100 host to memory + * - 0b101 memory to host + * - others hardware specific + */ uint32_t channel_direction : 3; + /** + * Completion callback enable + * + * - 0b0 callback invoked at transfer list completion only + * - 0b1 callback invoked at completion of each block + */ uint32_t complete_callback_en : 1; + /** + * Error callback enable + * + * - 0b0 error callback enabled + * - 0b1 error callback disabled + */ uint32_t error_callback_en : 1; + /** + * Source handshake, HW specific + * + * - 0b0 HW + * - 0b1 SW + */ uint32_t source_handshake : 1; + /** + * Destination handshake, HW specific + * + * - 0b0 HW + * - 0b1 SW + */ uint32_t dest_handshake : 1; + /** + * Channel priority for arbitration, HW specific + */ uint32_t channel_priority : 4; + /** Source chaining enable, HW specific */ uint32_t source_chaining_en : 1; + /** Destination chaining enable, HW specific */ uint32_t dest_chaining_en : 1; + /** Linked channel, HW specific */ uint32_t linked_channel : 7; + /** Cyclic transfer list, HW specific */ uint32_t cyclic : 1; - uint32_t reserved : 3; + + uint32_t _reserved : 3; + /** Width of source data (in bytes) */ uint32_t source_data_size : 16; + /** Width of destination data (in bytes) */ uint32_t dest_data_size : 16; + /** Source burst length in bytes */ uint32_t source_burst_length : 16; + /** Destination burst length in bytes */ uint32_t dest_burst_length : 16; + /** Number of blocks in transfer list */ uint32_t block_count; + /** Pointer to the first block in the transfer list */ struct dma_block_config *head_block; + /** Optional attached user data for callbacks */ void *user_data; + /** Optional callback for completion and error events */ dma_callback_t dma_callback; }; /** * DMA runtime status structure - * - * busy - is current DMA transfer busy or idle - * dir - DMA transfer direction - * pending_length - data length pending to be transferred in bytes - * or platform dependent. - * free - free buffer space - * write_position - write position in a circular dma buffer - * read_position - read position in a circular dma buffer - * */ struct dma_status { + /** Is the current DMA transfer busy or idle */ bool busy; + /** Direction fo the transfer */ enum dma_channel_direction dir; + /** Pending length to be transferred in bytes, HW specific */ uint32_t pending_length; + /** Available buffers space, HW specific */ uint32_t free; + /** Write position in circular DMA buffer, HW specific */ uint32_t write_position; + /** Read position in circular DMA buffer, HW specific */ uint32_t read_position; + /** Total copied, HW specific */ uint64_t total_copied; }; @@ -249,19 +291,17 @@ struct dma_status { * DMA context structure * Note: the dma_context shall be the first member * of DMA client driver Data, got by dev->data - * - * magic - magic code to identify the context - * dma_channels - dma channels - * atomic - driver atomic_t pointer - * */ struct dma_context { + /** magic code to identify the context */ int32_t magic; + /** number of dma channels */ int dma_channels; + /** atomic holding bit flags for each channel to mark as used/unused */ atomic_t *atomic; }; -/* magic code to identify context content */ +/** Magic code to identify context content */ #define DMA_MAGIC 0x47494749 /** From adc30ff29448eab781928fdc4d2b415fe15478a2 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Wed, 8 Nov 2023 17:43:31 +0800 Subject: [PATCH 3392/4498] ITE: drivers/i2c: Bug in build assert when FIFO enable We need to do a build assert for the fifo enable status of 'I2C2'. There is a problem with using instance to obtain property when any one I2C port is not enabled. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_it8xxx2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c_ite_it8xxx2.c b/drivers/i2c/i2c_ite_it8xxx2.c index 57f69a6aaeb..b931a932030 100644 --- a/drivers/i2c/i2c_ite_it8xxx2.c +++ b/drivers/i2c/i2c_ite_it8xxx2.c @@ -1255,7 +1255,7 @@ static const struct i2c_driver_api i2c_it8xxx2_driver_api = { * that channel C may encounter wrong register being written due to FIFO2 * byte counter wrong write after channel B's write operation. */ -BUILD_ASSERT((DT_INST_PROP(SMB_CHANNEL_C, fifo_enable) == false), +BUILD_ASSERT((DT_PROP(DT_NODELABEL(i2c2), fifo_enable) == false), "Channel C cannot use FIFO mode."); #endif From ce4cdac3c0b57954caf35a129e8ca96f26ae4ecd Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 27 Sep 2023 17:40:16 +0200 Subject: [PATCH 3393/4498] llext: add llext_peek() The only way so far to access extension images is via a memory buffer. Since this, supposedly, will also be a rather common method, it makes sense to add a method to access extension data quickly by obtaining a pointer instead of copying data into local buffers. Add a llext_peek() method for that. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/buf_loader.h | 4 +++- include/zephyr/llext/loader.h | 14 +++++++++++++- subsys/llext/buf_loader.c | 7 +++++++ subsys/llext/llext.c | 9 +++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/zephyr/llext/buf_loader.h b/include/zephyr/llext/buf_loader.h index c75d20e4530..5a50e215bd3 100644 --- a/include/zephyr/llext/buf_loader.h +++ b/include/zephyr/llext/buf_loader.h @@ -37,6 +37,7 @@ struct llext_buf_loader { /** @cond ignore */ int llext_buf_read(struct llext_loader *ldr, void *buf, size_t len); int llext_buf_seek(struct llext_loader *ldr, size_t pos); +void *llext_buf_peek(struct llext_loader *ldr, size_t pos); /** @endcond */ /** @@ -49,7 +50,8 @@ int llext_buf_seek(struct llext_loader *ldr, size_t pos); { \ .loader = { \ .read = llext_buf_read, \ - .seek = llext_buf_seek \ + .seek = llext_buf_seek, \ + .peek = llext_buf_peek, \ }, \ .buf = (_buf), \ .len = (_buf_len), \ diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index db4157168aa..915a6278a44 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -73,7 +73,19 @@ struct llext_loader { * @retval 0 Success * @retval -errno Error reading (any errno) */ - int (*seek)(struct llext_loader *s, size_t pos); + int (*seek)(struct llext_loader *ldr, size_t pos); + + /** + * @brief Peek at an absolute location + * + * Return a pointer to the buffer at specified offset. + * + * @param[in] ldr Loader + * @param[in] pos Position to obtain a pointer to + * + * @retval pointer into the buffer + */ + void *(*peek)(struct llext_loader *ldr, size_t pos); /** @cond ignore */ elf_ehdr_t hdr; diff --git a/subsys/llext/buf_loader.c b/subsys/llext/buf_loader.c index 1b9fb576e7d..d744a85e473 100644 --- a/subsys/llext/buf_loader.c +++ b/subsys/llext/buf_loader.c @@ -29,3 +29,10 @@ int llext_buf_seek(struct llext_loader *l, size_t pos) return 0; } + +void *llext_buf_peek(struct llext_loader *l, size_t pos) +{ + struct llext_buf_loader *buf_l = CONTAINER_OF(l, struct llext_buf_loader, loader); + + return (void *)(buf_l->buf + pos); +} diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 24f48414ad8..50f98654bae 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -31,6 +31,15 @@ static inline int llext_seek(struct llext_loader *l, size_t pos) return l->seek(l, pos); } +static inline void *llext_peek(struct llext_loader *l, size_t pos) +{ + if (l->peek) { + return l->peek(l, pos); + } + + return NULL; +} + static sys_slist_t _llext_list = SYS_SLIST_STATIC_INIT(&_llext_list); sys_slist_t *llext_list(void) From 0bf08e5775b4664cdef42a1c69785ab644a43462 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 25 Oct 2023 17:05:38 +0200 Subject: [PATCH 3394/4498] llext: use llext_peek() for section pointers Try to use llext_peek() for section pointers. If it's supported and succeeds we don't need to allocate buffers. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 4 ++++ subsys/llext/llext.c | 32 +++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 33feba50bd5..e0ceece0cf8 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -52,6 +53,9 @@ struct llext { /** Lookup table of llext memory regions */ void *mem[LLEXT_MEM_COUNT]; + /** Memory allocated on heap */ + bool mem_on_heap[LLEXT_MEM_COUNT]; + /** Total size of the llext memory usage */ size_t mem_size; diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 50f98654bae..93c03d18aba 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -255,6 +255,14 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, return 0; } + if (ldr->sects[sect_idx].sh_type != SHT_NOBITS) { + ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset); + if (ext->mem[mem_idx]) { + ext->mem_on_heap[mem_idx] = false; + return 0; + } + } + ext->mem[mem_idx] = k_heap_aligned_alloc(&llext_heap, sizeof(uintptr_t), ldr->sects[sect_idx].sh_size, K_NO_WAIT); @@ -263,16 +271,22 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, } ext->mem_size += ldr->sects[sect_idx].sh_size; - ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); - if (ret != 0) { - goto err; - } + if (ldr->sects[sect_idx].sh_type == SHT_NOBITS) { + memset(ext->mem[mem_idx], 0, ldr->sects[sect_idx].sh_size); + } else { + ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset); + if (ret != 0) { + goto err; + } - ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size); - if (ret != 0) { - goto err; + ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size); + if (ret != 0) { + goto err; + } } + ext->mem_on_heap[mem_idx] = true; + return 0; err: @@ -633,7 +647,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) if (ret != 0) { LOG_DBG("Failed to load extension, freeing memory..."); for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) { - if (ext->mem[mem_idx] != NULL) { + if (ext->mem_on_heap[mem_idx]) { k_heap_free(&llext_heap, ext->mem[mem_idx]); } } @@ -714,7 +728,7 @@ void llext_unload(struct llext *ext) sys_slist_find_and_remove(&_llext_list, &ext->_llext_list); for (int i = 0; i < LLEXT_MEM_COUNT; i++) { - if (ext->mem[i] != NULL) { + if (ext->mem_on_heap[i]) { LOG_DBG("freeing memory region %d", i); k_heap_free(&llext_heap, ext->mem[i]); ext->mem[i] = NULL; From 3a95c78545e1f3c20f4c0583ea982cef5b979b53 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 6 Nov 2023 21:40:18 +0100 Subject: [PATCH 3395/4498] tests: coredump: Enable code coverage Enable code coverage for debug.coredump.logging_backend test. Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/coredump/src/main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/subsys/debug/coredump/src/main.c b/tests/subsys/debug/coredump/src/main.c index ace12f8a296..ddad60f9230 100644 --- a/tests/subsys/debug/coredump/src/main.c +++ b/tests/subsys/debug/coredump/src/main.c @@ -8,6 +8,23 @@ #include #include +#ifdef CONFIG_COVERAGE_DUMP +#include +#endif + + +void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf) +{ + ARG_UNUSED(pEsf); + + printk("%s is expected; reason = %u; halting ...\n", __func__, reason); + +#ifdef CONFIG_COVERAGE_DUMP + gcov_coverage_dump(); /* LCOV_EXCL_LINE */ +#endif + k_fatal_halt(reason); +} + void func_3(uint32_t *addr) { #if defined(CONFIG_BOARD_M2GL025_MIV) || \ From c88a7b659bc1f9332cf6e363052b7b3031361846 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 6 Nov 2023 21:42:21 +0100 Subject: [PATCH 3396/4498] tests: coredump: Extend matching patterns Extend test matching patterns and fix cmake project name. Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/coredump/CMakeLists.txt | 2 +- tests/subsys/debug/coredump/testcase.yaml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/subsys/debug/coredump/CMakeLists.txt b/tests/subsys/debug/coredump/CMakeLists.txt index ecb7d24bb8f..2ed92da99af 100644 --- a/tests/subsys/debug/coredump/CMakeLists.txt +++ b/tests/subsys/debug/coredump/CMakeLists.txt @@ -3,6 +3,6 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(hello_world) +project(debug_coredump) target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/debug/coredump/testcase.yaml b/tests/subsys/debug/coredump/testcase.yaml index db407b3d774..5b7dde692b1 100644 --- a/tests/subsys/debug/coredump/testcase.yaml +++ b/tests/subsys/debug/coredump/testcase.yaml @@ -14,8 +14,11 @@ tests: type: multi_line regex: - "Coredump: (.*)" + - ">>> ZEPHYR FATAL ERROR " - "E: #CD:BEGIN#" - "E: #CD:5([aA])45([0-9a-fA-F]+)" - "E: #CD:41([0-9a-fA-F]+)" - "E: #CD:4([dD])([0-9a-fA-F]+)" + - "E: #CD:4([dD])([0-9a-fA-F]+)" - "E: #CD:END#" + - "k_sys_fatal_error_handler" From 647207c0248a136ae82ee72c5b7e0cfba6af5966 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 6 Nov 2023 15:55:16 +0100 Subject: [PATCH 3397/4498] bluetooth: leaudio: Fix missing set of BIG_Encryption In the PTS BASS/SR/CP/BV-19-C test case a client executes Set Broadcast Code operation of Broadcast Audio Scan Control Point characteristic with Broadcast_Code set to an invalid value. After syncing to an ISO stream there is an expected failed attempt to decrypt the stream data, but the host does not set BIG_Encryption value to the expected value 0x03 (BT_BAP_BIG_ENC_STATE_BAD_CODE). Add missing BIG_Encryption state into the failing check. Signed-off-by: Magdalena Kasenberg --- subsys/bluetooth/audio/bap_broadcast_sink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 86c7076174a..4d2134455b8 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -157,7 +157,8 @@ static void update_recv_state_big_cleared(const struct bt_bap_broadcast_sink *si return; } - if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ && + if ((recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ || + recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_DEC) && reason == BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL) { /* Sync failed due to bad broadcast code */ mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_BAD_CODE; From 0b5e48985d3062e9708150e4f6cc04c0c73540f6 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:27:57 -0500 Subject: [PATCH 3398/4498] dts: bindings: Add binding for NXP Multirate Timer Add binding for nxp,mrt and nxp,mrt-channel. MRT is NXP multirate timer, a simple timer with multiple independent channels. Signed-off-by: Declan Snyder --- dts/bindings/counter/nxp,mrt-channel.yaml | 15 ++++++++++++ dts/bindings/counter/nxp,mrt.yaml | 28 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 dts/bindings/counter/nxp,mrt-channel.yaml create mode 100644 dts/bindings/counter/nxp,mrt.yaml diff --git a/dts/bindings/counter/nxp,mrt-channel.yaml b/dts/bindings/counter/nxp,mrt-channel.yaml new file mode 100644 index 00000000000..c3ab744fc5a --- /dev/null +++ b/dts/bindings/counter/nxp,mrt-channel.yaml @@ -0,0 +1,15 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP Multirate Timer Channel + + Must be a child node of an nxp,mrt compatible node. + +compatible: "nxp,mrt-channel" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/counter/nxp,mrt.yaml b/dts/bindings/counter/nxp,mrt.yaml new file mode 100644 index 00000000000..e9e05b6c5b5 --- /dev/null +++ b/dts/bindings/counter/nxp,mrt.yaml @@ -0,0 +1,28 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP Multirate Timer + +compatible: "nxp,mrt" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + num-channels: + type: int + required: true + description: Number of channels on the IP version + + num-bits: + type: int + required: true + description: Timer width in bits of IP version + + clocks: + required: true From c83037ceceb1da6dc1f9c1aa18acf5c90a74b670 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:30:14 -0500 Subject: [PATCH 3399/4498] drivers: clock_control_mcux_syscon: Add MRT subsys Add code to handle MRT subsys clock to LPC syscon driver Signed-off-by: Declan Snyder --- .../clock_control/clock_control_mcux_syscon.c | 16 +++++++++++++--- .../dt-bindings/clock/mcux_lpc_syscon_clock.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 2349be21711..3dcc073954c 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -19,12 +19,19 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { #if defined(CONFIG_CAN_MCUX_MCAN) - uint32_t clock_name = (uint32_t)sub_system; - - if (clock_name == MCUX_MCAN_CLK) { + if ((uint32_t)sub_system == MCUX_MCAN_CLK) { CLOCK_EnableClock(kCLOCK_Mcan); } #endif /* defined(CONFIG_CAN_MCUX_MCAN) */ +#if defined(CONFIG_COUNTER_NXP_MRT) + if ((uint32_t)sub_system == MCUX_MRT_CLK) { +#if defined(CONFIG_SOC_FAMILY_LPC) + CLOCK_EnableClock(kCLOCK_Mrt); +#elif defined(CONFIG_SOC_FAMILY_IMX) + CLOCK_EnableClock(kCLOCK_Mrt0); +#endif + } +#endif /* defined(CONFIG_COUNTER_NXP_MRT) */ return 0; } @@ -145,6 +152,9 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate( break; #endif +#if defined(CONFIG_COUNTER_NXP_MRT) + case MCUX_MRT_CLK: +#endif #if defined(CONFIG_PWM_MCUX_SCTIMER) case MCUX_SCTIMER_CLK: #endif diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index 581c5b57e08..9f80b662c60 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -51,4 +51,6 @@ #define MCUX_SCTIMER_CLK 34 +#define MCUX_MRT_CLK 40 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ From 31722446aa4fa668e38e1d2374a1838d94fd9389 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:34:09 -0500 Subject: [PATCH 3400/4498] drivers: counter: Add NXP MRT driver Add driver for NXP Multirate Timer Signed-off-by: Declan Snyder --- drivers/counter/CMakeLists.txt | 5 +- drivers/counter/Kconfig | 2 + drivers/counter/Kconfig.nxp_mrt | 9 + drivers/counter/counter_nxp_mrt.c | 341 ++++++++++++++++++++++++++++++ 4 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 drivers/counter/Kconfig.nxp_mrt create mode 100644 drivers/counter/counter_nxp_mrt.c diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index 3a59312da24..50a1ffad441 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -44,7 +44,8 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_INFINEON_CAT1 counter_ifx_cat1 zephyr_library_sources_ifdef(CONFIG_ACE_V1X_ART_COUNTER counter_ace_v1x_art.c) zephyr_library_sources_ifdef(CONFIG_ACE_V1X_RTC_COUNTER counter_ace_v1x_rtc.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_NXP_S32_SYS_TIMER counter_nxp_s32_sys_timer.c) -zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_GD32 counter_gd32_timer.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_GD32 counter_gd32_timer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_SNPS_DW counter_dw_timer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_SHELL counter_timer_shell.c) -zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_RPI_PICO counter_rpi_pico_timer.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_RPI_PICO counter_rpi_pico_timer.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_NXP_MRT counter_nxp_mrt.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 956c5d59f64..16adaee75b2 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -94,4 +94,6 @@ source "drivers/counter/Kconfig.dw" source "drivers/counter/Kconfig.rpi_pico" +source "drivers/counter/Kconfig.nxp_mrt" + endif # COUNTER diff --git a/drivers/counter/Kconfig.nxp_mrt b/drivers/counter/Kconfig.nxp_mrt new file mode 100644 index 00000000000..a395ada36b4 --- /dev/null +++ b/drivers/counter/Kconfig.nxp_mrt @@ -0,0 +1,9 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_NXP_MRT + bool "NXP MRT driver" + default y if DT_HAS_NXP_MRT_CHANNEL_ENABLED && \ + DT_HAS_NXP_MRT_ENABLED + help + Enable driver for the NXP Multirate Timer (MRT). diff --git a/drivers/counter/counter_nxp_mrt.c b/drivers/counter/counter_nxp_mrt.c new file mode 100644 index 00000000000..741e7b34d40 --- /dev/null +++ b/drivers/counter/counter_nxp_mrt.c @@ -0,0 +1,341 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * MRT (Multirate timer) is a lightweight timer with multiple independent channels, each capable + * of signalling the shared interrupt with a different period. This driver treats all the channels + * as separate devices adhering to the counter API. The parent device is responsible for the + * initialization, interrupt handling, and any other module-wide tasks. The current implementation + * of this driver prioritizes minimizing image size over speed, because it is not expected for the + * functions to be called very often, and this IP is mostly present on low memory devices. + */ + +#define DT_DRV_COMPAT nxp_mrt + +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE_NAME counter_mrt +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_COUNTER_LOG_LEVEL); + +/* Device holds a pointer to pointer to data */ +#define MRT_CHANNEL_DATA(dev) \ + (*(struct nxp_mrt_channel_data *const *const)dev->data) + +/* Device config->data is an array of data pointers ordered by channel number, + * dev->data is a pointer to one of these pointers in that array, + * so the value of the dev->data - dev->config->data is the channel index + */ +#define MRT_CHANNEL_ID(dev) \ + (((struct nxp_mrt_channel_data *const *)dev->data) - \ + ((const struct nxp_mrt_config *)dev->config)->data) + +/* Specific for each channel */ +struct nxp_mrt_channel_data { + uint32_t top; + counter_top_callback_t cb; + void *user_data; +}; + +/* Shared between all channels */ +struct nxp_mrt_config { + struct counter_config_info info; + MRT_Type *base; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + void (*irq_config_func)(const struct device *dev); + struct nxp_mrt_channel_data *const *data; + const struct device *const *channels; +}; + +static int nxp_mrt_stop(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + int channel_id = MRT_CHANNEL_ID(dev); + + LOG_DBG("MRT@%p channel %d stopped", base, channel_id); + LOG_WRN("MRT channel resets upon stopping"); + + /* LOAD bit and 0 ivalue allows us to forcibly stop the timer */ + base->CHANNEL[channel_id].INTVAL = MRT_CHANNEL_INTVAL_LOAD(1); + + return 0; +} + +static int nxp_mrt_start(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + struct nxp_mrt_channel_data *data = MRT_CHANNEL_DATA(dev); + int channel_id = MRT_CHANNEL_ID(dev); + + if (data->top <= 1) { + /* Zephyr API says default should be max top value */ + LOG_INF("\"Started\" MRT@%p channel %d with default value %d", + base, channel_id, config->info.max_top_value); + data->top = config->info.max_top_value; + } + + /* Start with previously configured top value (if already running this has no effect) */ + base->CHANNEL[channel_id].INTVAL = data->top; + + LOG_DBG("MRT@%p channel %d started with top value %d", base, channel_id, data->top); + + return 0; +} + +static int nxp_mrt_get_value(const struct device *dev, uint32_t *ticks) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + int channel_id = MRT_CHANNEL_ID(dev); + + *ticks = base->CHANNEL[channel_id].TIMER & MRT_CHANNEL_TIMER_VALUE_MASK; + + return 0; +} + + +static int nxp_mrt_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + struct nxp_mrt_channel_data *data = MRT_CHANNEL_DATA(dev); + int channel_id = MRT_CHANNEL_ID(dev); + /* By default in Zephyr API, the counter resets on changing top value */ + bool reset = !(cfg->flags & COUNTER_TOP_CFG_DONT_RESET); + bool active = base->CHANNEL[channel_id].STAT & MRT_CHANNEL_STAT_RUN_MASK; + uint32_t current_val = base->CHANNEL[channel_id].TIMER & MRT_CHANNEL_TIMER_VALUE_MASK; + int ret = 0; + + /* Store for use by counter_start */ + data->top = cfg->ticks; + + /* Used by ISR */ + data->cb = cfg->callback; + data->user_data = cfg->user_data; + + + /* If not yet started, wait for counter_start because setting reg value starts timer */ + if (!active) { + LOG_DBG("Set MRT@%p channel %d top value to %d", base, channel_id, data->top); + return ret; + } + + /* Otherwise if currently running, need to check for lateness */ + if (cfg->ticks < current_val) { + LOG_WRN("MRT@%p channel %d received requested top value %d which is " + "smaller than current count %d", + base, channel_id, cfg->ticks, current_val); + /* Zephyr API says return this error in case of lateness + * when COUNTER_TOP_CFG_DONT_RESET is set but can still set period + */ + ret = reset ? 0 : -ETIME; + /* If user said not to reset, they can also clarify exception for lateness */ + reset |= cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE; + } + + /* Sets the top value. If we need to reset, LOAD bit does this */ + base->CHANNEL[channel_id].INTVAL = MRT_CHANNEL_INTVAL_IVALUE(cfg->ticks) | + MRT_CHANNEL_INTVAL_LOAD(reset ? 1 : 0); + + LOG_DBG("Changed MRT@%p channel %d top value while active to %d", + base, channel_id, + base->CHANNEL[channel_id].INTVAL & MRT_CHANNEL_INTVAL_IVALUE_MASK); + + return ret; +} + +static uint32_t nxp_mrt_get_top_value(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + int channel_id = MRT_CHANNEL_ID(dev); + + return base->CHANNEL[channel_id].INTVAL & MRT_CHANNEL_INTVAL_IVALUE_MASK; +} + +static uint32_t nxp_mrt_get_pending_int(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + int channel_id = MRT_CHANNEL_ID(dev); + + return base->CHANNEL[channel_id].STAT & MRT_CHANNEL_STAT_INTFLAG_MASK; +} + +static inline int nxp_mrt_set_alarm(const struct device *dev, + uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + ARG_UNUSED(dev); + ARG_UNUSED(chan_id); + ARG_UNUSED(alarm_cfg); + + LOG_ERR("MRT does not support alarms"); + return -ENOTSUP; +} + +static inline int nxp_mrt_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + ARG_UNUSED(dev); + ARG_UNUSED(chan_id); + + LOG_ERR("MRT does not support alarms"); + return -ENOTSUP; +} + +uint32_t nxp_mrt_get_freq(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + uint32_t freq; + + clock_control_get_rate(config->clock_dev, config->clock_subsys, &freq); + + return freq; +} + +static int nxp_mrt_init(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + uint32_t num_channels = (base->MODCFG & MRT_MODCFG_NOC_MASK) >> MRT_MODCFG_NOC_SHIFT; + + clock_control_on(config->clock_dev, config->clock_subsys); + + config->irq_config_func(dev); + + /* Enable interrupts for all the channels that have devices */ + for (int i = 0; i < num_channels; i++) { + if (config->channels[i]) { + base->CHANNEL[i].CTRL = MRT_CHANNEL_CTRL_INTEN_MASK; + } + } + + return 0; +} + +static void nxp_mrt_isr(const struct device *dev) +{ + const struct nxp_mrt_config *config = dev->config; + MRT_Type *base = config->base; + uint32_t irq_pends = base->IRQ_FLAG; + uint32_t num_channels = (base->MODCFG & MRT_MODCFG_NOC_MASK) >> MRT_MODCFG_NOC_SHIFT; + + for (int i = 0; i < num_channels; i++) { + /* Channel IRQ pending flags lowest order bits in IRQ_FLAG register */ + if (!(irq_pends & (0x1 << i))) { + continue; + } + + LOG_DBG("Handling interrupt for MRT%p channel %d", base, i); + + /* W1C interrupt flag */ + base->CHANNEL[i].STAT |= MRT_CHANNEL_STAT_INTFLAG_MASK; + + /* Channel devs & pointer path to channel cbs is in shared config */ + if (config->data[i]->cb) { + config->data[i]->cb(config->channels[i], config->data[i]->user_data); + } + } +} + +struct counter_driver_api nxp_mrt_api = { + .get_value = nxp_mrt_get_value, + .start = nxp_mrt_start, + .stop = nxp_mrt_stop, + .set_top_value = nxp_mrt_set_top_value, + .get_top_value = nxp_mrt_get_top_value, + .get_pending_int = nxp_mrt_get_pending_int, + .set_alarm = nxp_mrt_set_alarm, + .cancel_alarm = nxp_mrt_cancel_alarm, + .get_freq = nxp_mrt_get_freq, +}; + +/* Creates a device for a channel (needed for counter API) */ +#define NXP_MRT_CHANNEL_DEV_INIT(node, mrt_inst) \ + DEVICE_DT_DEFINE(node, NULL, NULL, \ + (void *) \ + &nxp_mrt_##mrt_inst##_channel_datas[DT_REG_ADDR(node)], \ + &nxp_mrt_##mrt_inst##_config, \ + POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, \ + &nxp_mrt_api); \ + +/* Creates a data struct for a channel device */ +#define NXP_MRT_CHANNEL_DATA_INIT(node) \ + static struct nxp_mrt_channel_data \ + nxp_mrt_channel_data_##node; \ + +/* Initializes an element of the channel data pointer array */ +#define NXP_MRT_CHANNEL_DATA_ARRAY_INIT(node) \ + [DT_REG_ADDR(node)] = \ + &nxp_mrt_channel_data_##node, + +/* Initializes an element of the channel device pointer array */ +#define NXP_MRT_CHANNEL_DEV_ARRAY_INIT(node) \ + [DT_REG_ADDR(node)] = DEVICE_DT_GET(node), + +#define NXP_MRT_INIT(n) \ + /* ISR is shared between all channels */ \ + static void nxp_mrt_##n##_irq_config_func(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + nxp_mrt_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + /* Initialize all the data structs for active channels */ \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, NXP_MRT_CHANNEL_DATA_INIT) \ + \ + /* Create an array of const pointers to the data structs */ \ + static struct nxp_mrt_channel_data *const nxp_mrt_##n##_channel_datas \ + [DT_INST_PROP(n, num_channels)] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \ + NXP_MRT_CHANNEL_DATA_ARRAY_INIT) \ + }; \ + \ + /* Forward declaration */ \ + const static struct nxp_mrt_config nxp_mrt_##n##_config; \ + \ + /* Create all the channel/counter devices */ \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, NXP_MRT_CHANNEL_DEV_INIT, n) \ + \ + /* This channel device array is needed by the module device ISR */ \ + const struct device *const nxp_mrt_##n##_channels \ + [DT_INST_PROP(n, num_channels)] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \ + NXP_MRT_CHANNEL_DEV_ARRAY_INIT) \ + }; \ + \ + /* This config struct is shared by all the channels and parent device */\ + const static struct nxp_mrt_config nxp_mrt_##n##_config = { \ + .info = { \ + .max_top_value = \ + GENMASK(DT_INST_PROP(n, num_bits) - 1, 0), \ + .channels = 0, \ + }, \ + .base = (MRT_Type *)DT_INST_REG_ADDR(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL(n, name), \ + .irq_config_func = nxp_mrt_##n##_irq_config_func, \ + .data = nxp_mrt_##n##_channel_datas, \ + .channels = nxp_mrt_##n##_channels, \ + }; \ + \ + /* Init parent device in order to handle ISR and init. */ \ + DEVICE_DT_INST_DEFINE(n, &nxp_mrt_init, NULL, NULL, \ + &nxp_mrt_##n##_config, \ + POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(NXP_MRT_INIT) From 8257ff8f6a7639cc8c986ec639d2a075b54f9c72 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:34:52 -0500 Subject: [PATCH 3401/4498] tests: counter: Update for NXP MRT Update counter test to test NXP MRT devices Signed-off-by: Declan Snyder --- tests/drivers/counter/counter_basic_api/src/test_counter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/drivers/counter/counter_basic_api/src/test_counter.c b/tests/drivers/counter/counter_basic_api/src/test_counter.c index 462de26d037..f63ee5ce6c4 100644 --- a/tests/drivers/counter/counter_basic_api/src/test_counter.c +++ b/tests/drivers/counter/counter_basic_api/src/test_counter.c @@ -66,6 +66,9 @@ static const struct device *const devices[] = { #ifdef CONFIG_COUNTER_MCUX_QTMR DEVS_FOR_DT_COMPAT(nxp_imx_tmr) #endif +#ifdef CONFIG_COUNTER_NXP_MRT + DEVS_FOR_DT_COMPAT(nxp_mrt_channel) +#endif #ifdef CONFIG_COUNTER_MCUX_LPC_RTC DEVS_FOR_DT_COMPAT(nxp_lpc_rtc) #endif From ff83745c9aedd36aef035372a76d11d49b7ee3f4 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:36:15 -0500 Subject: [PATCH 3402/4498] soc: rt5xx: Enable NXP MRT Enable NXP MRT on RT5xx soc and MIMXRT595_EVK board Signed-off-by: Declan Snyder --- .../arm/mimxrt595_evk/mimxrt595_evk_cm33.dts | 4 +++ dts/arm/nxp/nxp_rt5xx_common.dtsi | 32 +++++++++++++++++++ soc/arm/nxp_imx/rt5xx/soc.c | 4 +++ 3 files changed, 40 insertions(+) diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts index 49dd4f424be..b91a45f5008 100644 --- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts +++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts @@ -478,3 +478,7 @@ zephyr_udc0: &usbhs { dmas = <&smartdma>; dma-names = "smartdma"; }; + +&mrt_channel0 { + status = "okay"; +}; diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 3f5319a7401..8a1a1aa3c3d 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -578,6 +578,38 @@ #mbox-cells = <1>; status = "disabled"; }; + + mrt: mrt@2d000 { + compatible = "nxp,mrt"; + reg = <0x2d000 0x100>; + interrupts = <9 0>; + num-channels = <4>; + num-bits = <24>; + clocks = <&clkctl1 MCUX_MRT_CLK>; + #address-cells = <1>; + #size-cells = <0>; + + mrt_channel0: mrt_channel@0 { + compatible = "nxp,mrt-channel"; + reg = <0>; + status = "disabled"; + }; + mrt_channel1: mrt_channel@1 { + compatible = "nxp,mrt-channel"; + reg = <1>; + status = "disabled"; + }; + mrt_channel2: mrt_channel@2 { + compatible = "nxp,mrt-channel"; + reg = <2>; + status = "disabled"; + }; + mrt_channel3: mrt_channel@3 { + compatible = "nxp,mrt-channel"; + reg = <3>; + status = "disabled"; + }; + }; }; &flexspi { diff --git a/soc/arm/nxp_imx/rt5xx/soc.c b/soc/arm/nxp_imx/rt5xx/soc.c index 72684393959..f6af227b17c 100644 --- a/soc/arm/nxp_imx/rt5xx/soc.c +++ b/soc/arm/nxp_imx/rt5xx/soc.c @@ -419,6 +419,10 @@ void __weak rt5xx_clock_init(void) CLOCK_SetClkDiv(kCLOCK_DivAdcClk, 1); #endif +#if CONFIG_COUNTER_NXP_MRT + RESET_PeripheralReset(kMRT0_RST_SHIFT_RSTn); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; From 93c59793c2741d845d9415236cc529ea1f5c290c Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:38:16 -0500 Subject: [PATCH 3403/4498] soc: rt6xx: Add NXP MRT Add NXP MRT to RT6xx DT definition and add peripheral reset to soc.c Signed-off-by: Declan Snyder --- dts/arm/nxp/nxp_rt6xx_common.dtsi | 32 +++++++++++++++++++++++++++++++ soc/arm/nxp_imx/rt6xx/soc.c | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index e4acafbafa5..0c81f71d140 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -458,6 +458,38 @@ #address-cells = <3>; #size-cells = <0>; }; + + mrt: mrt@2d000 { + compatible = "nxp,mrt"; + reg = <0x2d000 0x100>; + interrupts = <9 0>; + num-channels = <4>; + num-bits = <24>; + clocks = <&clkctl1 MCUX_MRT_CLK>; + #address-cells = <1>; + #size-cells = <0>; + + mrt_channel0: mrt_channel@0 { + compatible = "nxp,mrt-channel"; + reg = <0>; + status = "disabled"; + }; + mrt_channel1: mrt_channel@1 { + compatible = "nxp,mrt-channel"; + reg = <1>; + status = "disabled"; + }; + mrt_channel2: mrt_channel@2 { + compatible = "nxp,mrt-channel"; + reg = <2>; + status = "disabled"; + }; + mrt_channel3: mrt_channel@3 { + compatible = "nxp,mrt-channel"; + reg = <3>; + status = "disabled"; + }; + }; }; &flexspi { diff --git a/soc/arm/nxp_imx/rt6xx/soc.c b/soc/arm/nxp_imx/rt6xx/soc.c index e04499b289d..2d4eab6854d 100644 --- a/soc/arm/nxp_imx/rt6xx/soc.c +++ b/soc/arm/nxp_imx/rt6xx/soc.c @@ -321,6 +321,10 @@ static ALWAYS_INLINE void clock_init(void) flexspi_setup_clock(FLEXSPI, 1U, 9U); #endif +#if CONFIG_COUNTER_NXP_MRT + RESET_PeripheralReset(kMRT0_RST_SHIFT_RSTn); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; From fef0018ccafb4241b4b788e9dfccd669ba3f47f3 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 3 Nov 2023 10:39:36 -0500 Subject: [PATCH 3404/4498] soc: lpc55xxx: Support, enable, test NXP MRT Support NXP MRT on LPC55XXX SOC series, enable on lpcxpresso55s69_cpu0, add test overlay to counter basic api test Signed-off-by: Declan Snyder --- .../lpcxpresso55s69/lpcxpresso55s69_cpu0.dts | 4 +++ dts/arm/nxp/nxp_lpc55S6x_common.dtsi | 32 +++++++++++++++++++ soc/arm/nxp_lpc/lpc55xxx/soc.c | 4 +++ .../boards/lpcxpresso55s69_cpu0.overlay | 15 +++++++++ 4 files changed, 55 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/boards/lpcxpresso55s69_cpu0.overlay diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts index 5b29efecadf..14ba04fa448 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts @@ -204,3 +204,7 @@ i2s1: &flexcomm7 { &dma1 { status = "okay"; }; + +&mrt_channel0 { + status = "okay"; +}; diff --git a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi index 411f8ac8f5f..5095a96738f 100644 --- a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi @@ -410,6 +410,38 @@ prescaler = <2>; #pwm-cells = <3>; }; + + mrt: mrt@d000 { + compatible = "nxp,mrt"; + reg = <0xd000 0x100>; + interrupts = <9 0>; + num-channels = <4>; + num-bits = <24>; + clocks = <&syscon MCUX_MRT_CLK>; + #address-cells = <1>; + #size-cells = <0>; + + mrt_channel0: mrt_channel@0 { + compatible = "nxp,mrt-channel"; + reg = <0>; + status = "disabled"; + }; + mrt_channel1: mrt_channel@1 { + compatible = "nxp,mrt-channel"; + reg = <1>; + status = "disabled"; + }; + mrt_channel2: mrt_channel@2 { + compatible = "nxp,mrt-channel"; + reg = <2>; + status = "disabled"; + }; + mrt_channel3: mrt_channel@3 { + compatible = "nxp,mrt-channel"; + reg = <3>; + status = "disabled"; + }; + }; }; &nvic { diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index e3620782acb..6730c6cfcff 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -347,6 +347,10 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) #endif /* SOC platform */ #endif /* DAC */ +#ifdef CONFIG_COUNTER_NXP_MRT + RESET_PeripheralReset(kMRT_RST_SHIFT_RSTn); +#endif + } /** diff --git a/tests/drivers/counter/counter_basic_api/boards/lpcxpresso55s69_cpu0.overlay b/tests/drivers/counter/counter_basic_api/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 00000000000..968741c5148 --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,15 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&mrt_channel1 { + status = "okay"; +}; + +/* channel 2 disabled to test disabled channel not breaking things */ + +&mrt_channel3 { + status = "okay"; +}; From f7761883446ef006462a05b3a2fe13dada3065b0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Nov 2023 13:52:28 +0200 Subject: [PATCH 3405/4498] doc: smbus: Make smbus fully api covered Add file description for full API coverage. Signed-off-by: Andrei Emeltchenko --- include/zephyr/drivers/smbus.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/drivers/smbus.h b/include/zephyr/drivers/smbus.h index b624462f425..ccb67a14d4a 100644 --- a/include/zephyr/drivers/smbus.h +++ b/include/zephyr/drivers/smbus.h @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Public SMBus Driver APIs + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ #define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ From 44e4425ef7e4e96d3c61e6b5bc1ce687f0a1f54c Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Nov 2023 14:09:18 +0200 Subject: [PATCH 3406/4498] doc: edac: Do not include hidden API Exclude hidden API marking them with INTERNAL_HIDDEN. Signed-off-by: Andrei Emeltchenko --- include/zephyr/drivers/edac.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/zephyr/drivers/edac.h b/include/zephyr/drivers/edac.h index 34dcb730dc3..6a30a0eaef7 100644 --- a/include/zephyr/drivers/edac.h +++ b/include/zephyr/drivers/edac.h @@ -16,8 +16,6 @@ #include -typedef void (*edac_notify_callback_f)(const struct device *dev, void *data); - /** * @defgroup edac EDAC API * @ingroup io_interfaces @@ -34,6 +32,14 @@ enum edac_error_type { EDAC_ERROR_TYPE_DRAM_UC = BIT(1) }; +/** + * @cond INTERNAL_HIDDEN + * + * For internal use only, skip these in public documentation. + */ + +typedef void (*edac_notify_callback_f)(const struct device *dev, void *data); + /** * @brief EDAC driver API * @@ -64,6 +70,10 @@ __subsystem struct edac_driver_api { edac_notify_callback_f cb); }; +/** + * INTERNAL_HIDDEN @endcond + */ + /* Optional interfaces */ /** From 1f03bad7cb34326a75c52fd658bba1e621f24eac Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Nov 2023 14:31:37 +0200 Subject: [PATCH 3407/4498] doc: edac: Separate Optional and Mandatory APIs Make documentation more readable by separating API with help of @name instead of simple comment in the code. Signed-off-by: Andrei Emeltchenko --- include/zephyr/drivers/edac.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/include/zephyr/drivers/edac.h b/include/zephyr/drivers/edac.h index 6a30a0eaef7..bbdd304bb8e 100644 --- a/include/zephyr/drivers/edac.h +++ b/include/zephyr/drivers/edac.h @@ -74,7 +74,12 @@ __subsystem struct edac_driver_api { * INTERNAL_HIDDEN @endcond */ -/* Optional interfaces */ +/** + * @name Optional interfaces + * @{ + * + * EDAC Optional Interfaces + */ /** * @brief Set injection parameter param1 @@ -241,7 +246,14 @@ static inline int edac_inject_error_trigger(const struct device *dev) return api->inject_error_trigger(dev); } -/* Mandatory interfaces */ +/** @} */ /* End of EDAC Optional Interfaces */ + +/** + * @name Mandatory interfaces + * @{ + * + * EDAC Mandatory Interfaces + */ /** * @brief Get ECC Error Log @@ -398,8 +410,9 @@ static inline int edac_notify_callback_set(const struct device *dev, return api->notify_cb_set(dev, cb); } -/** - * @} - */ + +/** @} */ /* End of EDAC Mandatory Interfaces */ + +/** @} */ /* End of EDAC API */ #endif /* ZEPHYR_INCLUDE_DRIVERS_EDAC_H_ */ From 329ef222dd72ff79c44883f1965eaaf7ec93787a Mon Sep 17 00:00:00 2001 From: Benjamin Deuter Date: Tue, 31 Oct 2023 14:07:50 +0100 Subject: [PATCH 3408/4498] tests: drivers: serial: async: Add support for stm32h735g_disco On the STM32H735G-DK Discovery kit, when connecting a UART from pin PF7 to PF6, the test uart_async_api passes now. Signed-off-by: Benjamin Deuter --- .../boards/stm32h735g_disco.conf | 1 + .../boards/stm32h735g_disco.overlay | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.conf create mode 100644 tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.conf b/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.conf new file mode 100644 index 00000000000..24be02d577c --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.conf @@ -0,0 +1 @@ +CONFIG_DCACHE=n diff --git a/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.overlay b/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.overlay new file mode 100644 index 00000000000..58618373e6f --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/stm32h735g_disco.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 STMicroelectronics + * Copyright (c) 2023 Benjamin Deuter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dut: &uart7 { + dmas = <&dmamux1 2 80 STM32_DMA_PERIPH_TX>, + <&dmamux1 3 79 STM32_DMA_PERIPH_RX>; + dma-names = "tx", "rx"; + pinctrl-0 = <&uart7_tx_pf7 &uart7_rx_pf6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&dma2 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; From a5d85503fea9f1af0d705ae294ab85446695923a Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Thu, 26 Oct 2023 16:26:05 +0800 Subject: [PATCH 3409/4498] boards: riscv: adp_xc7k_ae350: doc: index.rst Due to the west build path in official sample doc is now change to root directory, we modify our west build command align the official sample doc. Signed-off-by: Kevin Wang --- boards/riscv/adp_xc7k_ae350/doc/index.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/boards/riscv/adp_xc7k_ae350/doc/index.rst b/boards/riscv/adp_xc7k_ae350/doc/index.rst index 62cae957f11..c12c04cabc4 100644 --- a/boards/riscv/adp_xc7k_ae350/doc/index.rst +++ b/boards/riscv/adp_xc7k_ae350/doc/index.rst @@ -229,6 +229,7 @@ You can build applications in the usual way. Here is an example for the :ref:`hello_world` application. .. zephyr-app-commands:: + :zephyr-app: samples/hello_world :board: adp_xc7k_ae350 :goals: build @@ -264,7 +265,7 @@ and execute it. # Check the ICEman server is running # Load the program into RAM and execute it - riscv64-zephyr-elf-gdb zephyr/zephyr.elf + riscv64-zephyr-elf-gdb build/zephyr/zephyr.elf (gdb) target remote :1111 (gdb) monitor reset halt (gdb) load @@ -278,7 +279,7 @@ and execute it. # Check the ICEman server is running # Burn the program into flash and execute it /bin/target_burn_frontend \ - -P 4444 --unlock --verify --image=zephyr/zephyr.bin \ + -P 4444 --unlock --verify --image=build/zephyr/zephyr.bin \ --algorithm-bin=/target_bin/target_SPI_v5_[32|64].bin # Note: @@ -307,7 +308,7 @@ Debugging # Check the ICEman server is running # Load and debug program - ./riscv64-zephyr-elf-gdb zephyr/zephyr.elf + ./riscv64-zephyr-elf-gdb build/zephyr/zephyr.elf (gdb) target remote :1111 (gdb) monitor reset halt (gdb) load From 5bd18886e96a3deaa56eb8e5360cdd6598f0f2a4 Mon Sep 17 00:00:00 2001 From: Nick Kraus Date: Thu, 12 Oct 2023 23:55:57 -0400 Subject: [PATCH 3410/4498] sam: mdio: Fix Transfer Timeout at Initialization Initialize the MDIO peripheral clock (normally done during GMAC initialization) before trying any MDIO transfers, preventing startup errors. Signed-off-by: Nick Kraus --- drivers/mdio/mdio_sam.c | 19 +++++++++++++++++++ dts/arm/atmel/sam4e.dtsi | 1 + dts/arm/atmel/same70.dtsi | 1 + dts/bindings/mdio/atmel,sam-mdio.yaml | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/drivers/mdio/mdio_sam.c b/drivers/mdio/mdio_sam.c index 078f12c9338..5665057f7c9 100644 --- a/drivers/mdio/mdio_sam.c +++ b/drivers/mdio/mdio_sam.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,9 @@ struct mdio_sam_dev_data { struct mdio_sam_dev_config { Gmac * const regs; const struct pinctrl_dev_config *pcfg; +#ifdef CONFIG_SOC_FAMILY_SAM + const struct atmel_sam_pmc_config clock_cfg; +#endif }; static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, @@ -140,6 +144,15 @@ static int mdio_sam_initialize(const struct device *dev) k_sem_init(&data->sem, 1, 1); +#ifdef CONFIG_SOC_FAMILY_SAM + /* Enable GMAC module's clock */ + (void) clock_control_on(SAM_DT_PMC_CONTROLLER, (clock_control_subsys_t) &cfg->clock_cfg); +#else + /* Enable MCLK clock on GMAC */ + MCLK->AHBMASK.reg |= MCLK_AHBMASK_GMAC; + *MCLK_GMAC |= MCLK_GMAC_MASK; +#endif + retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); return retval; @@ -154,10 +167,16 @@ static const struct mdio_driver_api mdio_sam_driver_api = { .bus_disable = mdio_sam_bus_disable, }; +#define MDIO_SAM_CLOCK(n) \ + COND_CODE_1(CONFIG_SOC_FAMILY_SAM, \ + (.clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n),), () \ + ) + #define MDIO_SAM_CONFIG(n) \ static const struct mdio_sam_dev_config mdio_sam_dev_config_##n = { \ .regs = (Gmac *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + MDIO_SAM_CLOCK(n) \ }; #define MDIO_SAM_DEVICE(n) \ diff --git a/dts/arm/atmel/sam4e.dtsi b/dts/arm/atmel/sam4e.dtsi index 00212c4eaa3..2e9e916eef2 100644 --- a/dts/arm/atmel/sam4e.dtsi +++ b/dts/arm/atmel/sam4e.dtsi @@ -178,6 +178,7 @@ mdio: mdio@40034000 { compatible = "atmel,sam-mdio"; reg = <0x40034000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 44>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 002f0969ebb..8c378d90d0d 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -340,6 +340,7 @@ mdio: mdio@40050000 { compatible = "atmel,sam-mdio"; reg = <0x40050000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/bindings/mdio/atmel,sam-mdio.yaml b/dts/bindings/mdio/atmel,sam-mdio.yaml index 4eb649b5b24..bc15ad2b76f 100644 --- a/dts/bindings/mdio/atmel,sam-mdio.yaml +++ b/dts/bindings/mdio/atmel,sam-mdio.yaml @@ -8,3 +8,7 @@ compatible: "atmel,sam-mdio" include: - name: mdio-controller.yaml - name: pinctrl-device.yaml + +properties: + clocks: + type: phandle-array From 318836af23aa1607342a019c01580fd87442f32b Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 9 Nov 2023 18:15:32 +0100 Subject: [PATCH 3411/4498] doc: gsg: macOS: Include instructions to add homebrew to the path Multiple users have failed to read the output from the Homebrew installation script, which instructs the user how to add it to the path. Include the instructions in the guide. Also add a step to include the Homebrew Python executable to the path, which allows then for invocation of python and pip as well as python3 and pip3. Signed-off-by: Carles Cufi --- doc/develop/getting_started/index.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 35eafb38561..8a36a6d2732 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -116,12 +116,32 @@ The current minimum required version for the main dependencies are: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + #. After the Homebrew installation script completes, follow the on-screen + instructions to add the Homebrew installation to the path. + + * On macOS running on Apple Silicon, this is achieved with: + + .. code-block:: bash + + (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> ~/.zprofile + source ~/.zprofile + + * On macOS running on Intel, use the command for Apple Silicon, but replace ``/opt/homebrew/`` with ``/usr/local/``. + #. Use ``brew`` to install the required dependencies: .. code-block:: bash brew install cmake ninja gperf python3 ccache qemu dtc wget libmagic + #. Add the Homebrew Python folder to the path, in order to be able to + execute ``python`` and ``pip`` as well ``python3`` and ``pip3``. + + .. code-block:: bash + + (echo; echo 'export PATH="'$(brew --prefix)'/opt/python/libexec/bin:$PATH"') >> ~/.zprofile + source ~/.zprofile + .. group-tab:: Windows .. note:: From d817a8ebff2ceac1f3c7e4471b295dc58b0310a0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 10 Nov 2023 12:19:19 +0200 Subject: [PATCH 3412/4498] drivers: timeaware_gpio: Fix include path Fixes CI after syscall_handler changes path. Signed-off-by: Andrei Emeltchenko --- drivers/misc/timeaware_gpio/timeaware_gpio_intel.c | 2 +- include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c b/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c index 5c193389552..ae0e519a437 100644 --- a/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c +++ b/drivers/misc/timeaware_gpio/timeaware_gpio_intel.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* TGPIO Register offsets */ #define ART_L 0x00 /* ART lower 32 bit reg */ diff --git a/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h b/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h index 68c305f9e18..b65b697f54f 100644 --- a/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h +++ b/include/zephyr/drivers/misc/timeaware_gpio/timeaware_gpio.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #ifdef __cplusplus extern "C" { From 9a44f7f583335e42223ffed2820a213e1b8b65d2 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 9 Nov 2023 16:24:36 +0100 Subject: [PATCH 3413/4498] doc: gsg: Windows: Clarify usage of terminal/cmd.exe Responding to feedback from the community, clarify that the cmd.exe window needs to be closed and reopened. Also be specific about the type of terminal window to be used. Signed-off-by: Carles Cufi --- doc/develop/getting_started/index.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 8a36a6d2732..495a3792b94 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -154,8 +154,9 @@ The current minimum required version for the main dependencies are: Therefore, we don't recommend using WSL when getting started. - These instructions must be run in a ``cmd.exe`` command prompt. The - required commands differ on PowerShell. + These instructions must be run in a ``cmd.exe`` command prompt terminal window. + In modern version of Windows (10 and later) it is recommended to install the Windows Terminal + application from the Microsoft Store. The required commands differ on PowerShell. These instructions rely on `Chocolatey`_. If Chocolatey isn't an option, you can install dependencies from their respective websites and ensure @@ -168,9 +169,9 @@ The current minimum required version for the main dependencies are: #. `Install chocolatey`_. - #. Open a ``cmd.exe`` window as **Administrator**. To do so, press the Windows key, - type "cmd.exe", right-click the result, and choose :guilabel:`Run as - Administrator`. + #. Open a ``cmd.exe`` terminal window as **Administrator**. To do so, press the Windows key, + type ``cmd.exe``, right-click the :guilabel:`Command Prompt`` search result, and choose + :guilabel:`Run as Administrator`. #. Disable global confirmation to avoid having to confirm the installation of individual programs: @@ -191,7 +192,7 @@ The current minimum required version for the main dependencies are: As of November 2023, Python 3.12 is not recommended for Zephyr development on Windows, as some required Python dependencies may be difficult to install. - #. Close the window and open a new ``cmd.exe`` window **as a regular user** to continue. + #. Close the terminal window. .. _Chocolatey: https://chocolatey.org/ .. _Install chocolatey: https://chocolatey.org/install @@ -411,6 +412,8 @@ additional Python dependencies. .. group-tab:: Install within virtual environment + #. Open a ``cmd.exe`` terminal window **as a regular user** + #. Create a new virtual environment: .. code-block:: bat @@ -464,6 +467,8 @@ additional Python dependencies. .. group-tab:: Install globally + #. Open a ``cmd.exe`` terminal window **as a regular user** + #. Install west: .. code-block:: bat @@ -618,7 +623,7 @@ that are used to emulate, flash and debug Zephyr applications. .. _windows_zephyr_sdk: - #. Open a ``cmd.exe`` window by pressing the Windows key typing "cmd.exe". + #. Open a ``cmd.exe`` terminal window **as a regular user** #. Download the `Zephyr SDK bundle `_: From ac450be5c80a8ef29f195f5e74d87f1eaaadc935 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 9 Nov 2023 19:04:13 +0000 Subject: [PATCH 3414/4498] i2c: gpio_i2c_switch: fix gpio api misuse Use GPIO_OUTPUT_INACTIVE to initialize the pin so that the ACTIVE_LOW DT flag is honored and use the gpio_pin_set_dt functions to set the (logical) value of the pin instead of gpio_pin_configure_dt, that tries to reconfigure the pin each time. Signed-off-by: Fabio Baltieri --- drivers/i2c/gpio_i2c_switch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/gpio_i2c_switch.c b/drivers/i2c/gpio_i2c_switch.c index 938ed11d769..07183d82e62 100644 --- a/drivers/i2c/gpio_i2c_switch.c +++ b/drivers/i2c/gpio_i2c_switch.c @@ -51,13 +51,13 @@ static int gpio_i2c_switch_transfer(const struct device *dev, struct i2c_msg *ms } /* enable switch */ - gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_HIGH); + gpio_pin_set_dt(&config->gpio, 1); k_busy_wait(GPIO_I2C_TOGGLE_DELAY_US); res = i2c_transfer(config->bus, msgs, num_msgs, addr); /* disable switch */ - gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_LOW); + gpio_pin_set_dt(&config->gpio, 0); k_busy_wait(GPIO_I2C_TOGGLE_DELAY_US); k_mutex_unlock(&data->lock); @@ -76,7 +76,7 @@ static int gpio_i2c_switch_init(const struct device *dev) k_mutex_init(&data->lock); - return gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_LOW); + return gpio_pin_configure_dt(&config->gpio, GPIO_OUTPUT_INACTIVE); } #define DEFINE_GPIO_I2C_SWITCH(inst) \ From 12e8490b8f0a00428e3bcafab39de8adcdc08ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 10 Nov 2023 11:09:01 +0100 Subject: [PATCH 3415/4498] boards: nxp: doc: Fix typo in imx8mn_evk board specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The M core on this board is an M7, not M47. Fixes #65047. Signed-off-by: Benjamin Cabé --- boards/arm64/mimx8mn_evk/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm64/mimx8mn_evk/doc/index.rst b/boards/arm64/mimx8mn_evk/doc/index.rst index 546df0d5c2d..b9620176b6e 100644 --- a/boards/arm64/mimx8mn_evk/doc/index.rst +++ b/boards/arm64/mimx8mn_evk/doc/index.rst @@ -7,7 +7,7 @@ Overview ******** i.MX8M Nano LPDDR4 EVK board is based on NXP i.MX8M Nano applications -processor, composed of a quad Cortex®-A53 cluster and a single Cortex®-M47 core. +processor, composed of a quad Cortex®-A53 cluster and a single Cortex®-M7 core. Zephyr OS is ported to run on the Cortex®-A53 core. - Board features: From 7a3a6d0c030b3bc99e669797ceb387d404331ce0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 8 Nov 2023 16:25:52 +0000 Subject: [PATCH 3416/4498] input: convert ite_it8xxx2_kbd driver from kscan to input Convert the ITE keyboard scanning driver from kscan to input, add the corresponding kscan compatibility node to the current board, build test only. Signed-off-by: Fabio Baltieri --- boards/riscv/it82xx2_evb/Kconfig.defconfig | 4 + boards/riscv/it82xx2_evb/it82xx2_evb.dts | 10 +- boards/riscv/it8xxx2_evb/Kconfig.defconfig | 3 + boards/riscv/it8xxx2_evb/it8xxx2_evb.dts | 10 +- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/{kscan => input}/Kconfig.it8xxx2 | 30 ++-- .../input_ite_it8xxx2_kbd.c} | 168 ++++++------------ drivers/kscan/CMakeLists.txt | 1 - drivers/kscan/Kconfig | 1 - .../ite,it8xxx2-kbd.yaml} | 2 +- dts/riscv/ite/it8xxx2.dtsi | 4 +- 12 files changed, 94 insertions(+), 141 deletions(-) rename drivers/{kscan => input}/Kconfig.it8xxx2 (56%) rename drivers/{kscan/kscan_ite_it8xxx2.c => input/input_ite_it8xxx2_kbd.c} (77%) rename dts/bindings/{kscan/ite,it8xxx2-kscan.yaml => input/ite,it8xxx2-kbd.yaml} (96%) diff --git a/boards/riscv/it82xx2_evb/Kconfig.defconfig b/boards/riscv/it82xx2_evb/Kconfig.defconfig index eb57ed18431..37d6dc601c9 100644 --- a/boards/riscv/it82xx2_evb/Kconfig.defconfig +++ b/boards/riscv/it82xx2_evb/Kconfig.defconfig @@ -5,4 +5,8 @@ if BOARD_IT82XX2_EVB config BOARD default "it82xx2_evb" + +config INPUT + default y if KSCAN + endif diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.dts b/boards/riscv/it82xx2_evb/it82xx2_evb.dts index fa8f3090973..3110363d88a 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb.dts +++ b/boards/riscv/it82xx2_evb/it82xx2_evb.dts @@ -17,7 +17,7 @@ i2c-0 = &i2c0; peci-0 = &peci0; led0 = &led0; - kscan0 = &kscan0; + kscan0 = &kscan_input; watchdog0 = &twd0; pwm-0 = &pwm0; }; @@ -30,7 +30,7 @@ zephyr,flash = &flash0; zephyr,flash-controller = &flashctrl; zephyr,code-partition = &slot0_partition; - zephyr,keyboard-scan = &kscan0; + zephyr,keyboard-scan = &kscan_input; }; leds { @@ -162,7 +162,7 @@ pinctrl-names = "default"; }; -&kscan0 { +&kbd { status = "okay"; pinctrl-0 = <&ksi0_default &ksi1_default @@ -189,6 +189,10 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + + kscan_input: kscan-input { + compatible = "zephyr,kscan-input"; + }; }; &peci0 { diff --git a/boards/riscv/it8xxx2_evb/Kconfig.defconfig b/boards/riscv/it8xxx2_evb/Kconfig.defconfig index 588b0dd8641..8c198316bed 100644 --- a/boards/riscv/it8xxx2_evb/Kconfig.defconfig +++ b/boards/riscv/it8xxx2_evb/Kconfig.defconfig @@ -15,4 +15,7 @@ choice PM_POLICY endchoice endif # PM +config INPUT + default y if KSCAN + endif # BOARD_IT8XXX2_EVB diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index ffac4a2ed99..73f7ec1b1de 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -17,7 +17,7 @@ i2c-0 = &i2c0; peci-0 = &peci0; led0 = &led0; - kscan0 = &kscan0; + kscan0 = &kscan_input; watchdog0 = &twd0; pwm-0 = &pwm0; }; @@ -30,7 +30,7 @@ zephyr,flash = &flash0; zephyr,flash-controller = &flashctrl; zephyr,code-partition = &slot0_partition; - zephyr,keyboard-scan = &kscan0; + zephyr,keyboard-scan = &kscan_input; }; leds { @@ -146,7 +146,7 @@ pinctrl-0 = <&tach0a_gpd6_default>; pinctrl-names = "default"; }; -&kscan0 { +&kbd { status = "okay"; pinctrl-0 = <&ksi0_default &ksi1_default @@ -173,6 +173,10 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + + kscan_input: kscan-input { + compatible = "zephyr,kscan-input"; + }; }; &peci0 { status = "okay"; diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 23da1afa2db..e141652fe48 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KEYS input_gpio_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_QDEC input_gpio_qdec.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GT911 input_gt911.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT8XXX2_KBD input_ite_it8xxx2_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_KBD_MATRIX input_kbd_matrix.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e10aed70e8b..21401d9dbdb 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -11,6 +11,7 @@ source "drivers/input/Kconfig.ft5336" source "drivers/input/Kconfig.gpio_keys" source "drivers/input/Kconfig.gpio_qdec" source "drivers/input/Kconfig.gt911" +source "drivers/input/Kconfig.it8xxx2" source "drivers/input/Kconfig.kbd_matrix" source "drivers/input/Kconfig.npcx" source "drivers/input/Kconfig.sdl" diff --git a/drivers/kscan/Kconfig.it8xxx2 b/drivers/input/Kconfig.it8xxx2 similarity index 56% rename from drivers/kscan/Kconfig.it8xxx2 rename to drivers/input/Kconfig.it8xxx2 index da5cead4b78..bbd9699decc 100644 --- a/drivers/kscan/Kconfig.it8xxx2 +++ b/drivers/input/Kconfig.it8xxx2 @@ -1,47 +1,47 @@ # Copyright (c) 2021 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -menuconfig KSCAN_ITE_IT8XXX2 - bool "ITE KSCAN driver" +menuconfig INPUT_ITE_IT8XXX2_KBD + bool "ITE keyboard scanning driver" default y - depends on DT_HAS_ITE_IT8XXX2_KSCAN_ENABLED + depends on DT_HAS_ITE_IT8XXX2_KBD_ENABLED select MULTITHREADING help This option enables the ITE keyboard scan driver. -if KSCAN_ITE_IT8XXX2 +if INPUT_ITE_IT8XXX2_KBD -config KSCAN_ITE_IT8XXX2_COLUMN_SIZE - int "KSCAN_ITE_IT8XXX2_COLUMN_SIZE" +config INPUT_ITE_IT8XXX2_COLUMN_SIZE + int "INPUT_ITE_IT8XXX2_COLUMN_SIZE" range 16 18 default 16 help Adjust the value to your keyboard columns. The maximum column size for the ITE family is 18. -config KSCAN_ITE_IT8XXX2_ROW_SIZE - int "KSCAN_ITE_IT8XXX2_ROW_SIZE" +config INPUT_ITE_IT8XXX2_ROW_SIZE + int "INPUT_ITE_IT8XXX2_ROW_SIZE" default 8 help Adjust the value to your keyboard rows. The maximum row size for the ITE family is 8. -config KSCAN_ITE_IT8XXX2_DEBOUNCE_DOWN - int "KSCAN_ITE_IT8XXX2_DEBOUNCE_DOWN" +config INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN + int "INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN" default 9 help Determines the time in msecs for debouncing a key press. -config KSCAN_ITE_IT8XXX2_DEBOUNCE_UP - int "KSCAN_ITE_IT8XXX2_DEBOUNCE_UP" +config INPUT_ITE_IT8XXX2_DEBOUNCE_UP + int "INPUT_ITE_IT8XXX2_DEBOUNCE_UP" default 30 help Determines the time in msecs for debouncing a key release. -config KSCAN_ITE_IT8XXX2_POLL_PERIOD - int "KSCAN_ITE_IT8XXX2_POLL_PERIOD" +config INPUT_ITE_IT8XXX2_POLL_PERIOD + int "INPUT_ITE_IT8XXX2_POLL_PERIOD" default 3 help Defines the poll period in msecs between matrix scans. -endif # KSCAN_ITE_IT8XXX2 +endif diff --git a/drivers/kscan/kscan_ite_it8xxx2.c b/drivers/input/input_ite_it8xxx2_kbd.c similarity index 77% rename from drivers/kscan/kscan_ite_it8xxx2.c rename to drivers/input/input_ite_it8xxx2_kbd.c index 85d47d9d230..560f4fdd7d9 100644 --- a/drivers/kscan/kscan_ite_it8xxx2.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -3,23 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT ite_it8xxx2_kscan +#define DT_DRV_COMPAT ite_it8xxx2_kbd +#include +#include +#include #include #include #include -#include #include #include -#include +#include #include -#include -#include #include #include -#define LOG_LEVEL CONFIG_KSCAN_LOG_LEVEL -LOG_MODULE_REGISTER(kscan_ite_it8xxx2); +LOG_MODULE_REGISTER(input_ite_it8xxx2_kbd); #define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) #define KEYBOARD_COLUMN_DRIVE_ALL -2 @@ -35,26 +34,20 @@ LOG_MODULE_REGISTER(kscan_ite_it8xxx2); /* Thread stack size */ #define TASK_STACK_SIZE 1024 -/* Device config */ -enum kscan_pin_func { - KSO16 = 0, - KSO17, -}; - -struct kscan_wuc_map_cfg { +struct input_it8xxx2_kbd_wuc_map_cfg { /* WUC control device structure */ const struct device *wucs; /* WUC pin mask */ uint8_t mask; }; -struct kscan_it8xxx2_config { +struct input_it8xxx2_kbd_config { /* Keyboard scan controller base address */ struct kscan_it8xxx2_regs *base; /* Keyboard scan input (KSI) wake-up irq */ int irq; /* KSI[7:0] wake-up input source configuration list */ - const struct kscan_wuc_map_cfg *wuc_map_list; + const struct input_it8xxx2_kbd_wuc_map_cfg *wuc_map_list; /* KSI[7:0]/KSO[17:0] keyboard scan alternate configuration */ const struct pinctrl_dev_config *pcfg; /* KSO16 GPIO cells */ @@ -64,18 +57,18 @@ struct kscan_it8xxx2_config { }; /* Device data */ -struct kscan_it8xxx2_data { +struct input_it8xxx2_kbd_data { /* Variables in usec units */ uint32_t deb_time_press; uint32_t deb_time_rel; int32_t poll_timeout; uint32_t poll_period; - uint8_t matrix_stable_state[CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_unstable_state[CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_previous_state[CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE]; + uint8_t matrix_stable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; + uint8_t matrix_unstable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; + uint8_t matrix_previous_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; /* Index in to the scan_clock_cycle to indicate start of debouncing */ - uint8_t scan_cycle_idx[CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE] - [CONFIG_KSCAN_ITE_IT8XXX2_ROW_SIZE]; + uint8_t scan_cycle_idx[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] + [CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE]; /* * Track previous "elapsed clock cycles" per matrix scan. This * is used to calculate the debouncing time for every key @@ -83,9 +76,7 @@ struct kscan_it8xxx2_data { uint8_t scan_clk_cycle[SCAN_OCURRENCES]; struct k_sem poll_lock; uint8_t scan_cycles_idx; - kscan_callback_t callback; struct k_thread thread; - atomic_t enable_scan; /* KSI[7:0] wake-up interrupt status mask */ uint8_t ksi_pin_mask; @@ -94,7 +85,7 @@ struct kscan_it8xxx2_data { static void drive_keyboard_column(const struct device *dev, int col) { - const struct kscan_it8xxx2_config *const config = dev->config; + const struct input_it8xxx2_kbd_config *const config = dev->config; struct kscan_it8xxx2_regs *const inst = config->base; int mask; @@ -112,14 +103,14 @@ static void drive_keyboard_column(const struct device *dev, int col) /* Set KSO[17:0] output data */ inst->KBS_KSOL = (uint8_t) (mask & 0xff); inst->KBS_KSOH1 = (uint8_t) ((mask >> 8) & 0xff); -#if (CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE > 16) +#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff); #endif } static uint8_t read_keyboard_row(const struct device *dev) { - const struct kscan_it8xxx2_config *const config = dev->config; + const struct input_it8xxx2_kbd_config *const config = dev->config; struct kscan_it8xxx2_regs *const inst = config->base; /* Bits are active-low, so toggle it (return 1 means key pressed) */ @@ -143,11 +134,11 @@ static bool is_matrix_ghosting(const uint8_t *state) * w, q and a simultaneously. A block can also be formed, * with not adjacent columns. */ - for (int c = 0; c < CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE; c++) { + for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { if (!state[c]) continue; - for (int c_n = c + 1; c_n < CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE; c_n++) { + for (int c_n = c + 1; c_n < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c_n++) { /* * We AND the columns to detect a "block". * this is an indication of ghosting, due to current @@ -172,7 +163,7 @@ static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state) uint8_t row; uint8_t key_event = 0U; - for (int col = 0; col < CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE; col++) { + for (int col = 0; col < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; col++) { /* Drive specific column low and others high */ drive_keyboard_column(dev, col); /* Allow the matrix to stabilize before reading it */ @@ -190,8 +181,8 @@ static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state) static void keyboard_raw_interrupt(const struct device *dev) { - const struct kscan_it8xxx2_config *const config = dev->config; - struct kscan_it8xxx2_data *data = dev->data; + const struct input_it8xxx2_kbd_config *const config = dev->config; + struct input_it8xxx2_kbd_data *data = dev->data; /* * W/C wakeup interrupt status of KSI[7:0] pins @@ -211,8 +202,8 @@ static void keyboard_raw_interrupt(const struct device *dev) void keyboard_raw_enable_interrupt(const struct device *dev, int enable) { - const struct kscan_it8xxx2_config *const config = dev->config; - struct kscan_it8xxx2_data *data = dev->data; + const struct input_it8xxx2_kbd_config *const config = dev->config; + struct input_it8xxx2_kbd_data *data = dev->data; if (enable) { /* @@ -235,8 +226,8 @@ void keyboard_raw_enable_interrupt(const struct device *dev, int enable) static bool check_key_events(const struct device *dev) { - struct kscan_it8xxx2_data *data = dev->data; - uint8_t matrix_new_state[CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE] = {0U}; + struct input_it8xxx2_kbd_data *data = dev->data; + uint8_t matrix_new_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] = {0U}; bool key_pressed = false; uint32_t cycles_now = k_cycle_get_32(); uint8_t row_changed = 0U; @@ -260,7 +251,7 @@ static bool check_key_events(const struct device *dev) * The intent of this loop is to gather information related to key * changes */ - for (int c = 0; c < CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE; c++) { + for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { /* Check if there was an update from the previous scan */ row_changed = matrix_new_state[c] ^ data->matrix_previous_state[c]; @@ -268,7 +259,7 @@ static bool check_key_events(const struct device *dev) if (!row_changed) continue; - for (int r = 0; r < CONFIG_KSCAN_ITE_IT8XXX2_ROW_SIZE; r++) { + for (int r = 0; r < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; r++) { /* * Index all they keys that changed for each row * in order to debounce each key in terms of it @@ -282,14 +273,14 @@ static bool check_key_events(const struct device *dev) data->matrix_previous_state[c] = matrix_new_state[c]; } - for (int c = 0; c < CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE; c++) { + for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { deb_col = data->matrix_unstable_state[c]; if (!deb_col) continue; /* Debouncing for each row key occurs here */ - for (int r = 0; r < CONFIG_KSCAN_ITE_IT8XXX2_ROW_SIZE; r++) { + for (int r = 0; r < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; r++) { uint8_t mask = BIT(r); uint8_t row_bit = matrix_new_state[c] & mask; @@ -322,11 +313,10 @@ static bool check_key_events(const struct device *dev) * application about the keys pressed. */ data->matrix_stable_state[c] ^= mask; - if ((atomic_get(&data->enable_scan) == 1U) && - (data->callback != NULL)) { - data->callback(dev, r, c, - row_bit ? true : false); - } + + input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); } } @@ -358,7 +348,7 @@ static bool poll_expired(uint32_t start_cycles, int32_t *timeout) void polling_task(const struct device *dev, void *dummy2, void *dummy3) { - struct kscan_it8xxx2_data *data = dev->data; + struct input_it8xxx2_kbd_data *data = dev->data; int32_t local_poll_timeout = data->poll_timeout; uint32_t current_cycles; uint32_t cycles_delta; @@ -379,7 +369,7 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3) uint32_t start_poll_cycles = k_cycle_get_32(); - while (atomic_get(&data->enable_scan) == 1U) { + while (true) { uint32_t start_period_cycles = k_cycle_get_32(); if (check_key_events(dev)) { @@ -420,17 +410,17 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3) } } -static int kscan_it8xxx2_init(const struct device *dev) +static int input_it8xxx2_kbd_init(const struct device *dev) { - const struct kscan_it8xxx2_config *const config = dev->config; - struct kscan_it8xxx2_data *data = dev->data; + const struct input_it8xxx2_kbd_config *const config = dev->config; + struct input_it8xxx2_kbd_data *data = dev->data; struct kscan_it8xxx2_regs *const inst = config->base; int status; /* Disable wakeup and interrupt of KSI pins before configuring */ keyboard_raw_enable_interrupt(dev, 0); -#if (CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE > 16) +#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) /* * For KSO[16] and KSO[17]: * 1.GPOTRC: @@ -459,7 +449,7 @@ static int kscan_it8xxx2_init(const struct device *dev) /* KSO[17:0] pins output low */ inst->KBS_KSOL = 0x00; inst->KBS_KSOH1 = 0x00; -#if (CONFIG_KSCAN_ITE_IT8XXX2_COLUMN_SIZE > 16) +#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) inst->KBS_KSOH2 = 0x00; #endif @@ -492,22 +482,16 @@ static int kscan_it8xxx2_init(const struct device *dev) /* Kconfig.it8xxx2 time figures are transformed from msec to usec */ data->deb_time_press = - (uint32_t) (CONFIG_KSCAN_ITE_IT8XXX2_DEBOUNCE_DOWN * MS_TO_US); + (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN * MS_TO_US); data->deb_time_rel = - (uint32_t) (CONFIG_KSCAN_ITE_IT8XXX2_DEBOUNCE_UP * MS_TO_US); + (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_UP * MS_TO_US); data->poll_period = - (uint32_t) (CONFIG_KSCAN_ITE_IT8XXX2_POLL_PERIOD * MS_TO_US); + (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_POLL_PERIOD * MS_TO_US); data->poll_timeout = 100 * MS_TO_US; - /* Init null for callback function */ - data->callback = NULL; - /* Create poll lock semaphore */ k_sem_init(&data->poll_lock, 0, 1); - /* Enable keyboard scan loop */ - atomic_set(&data->enable_scan, 1); - irq_connect_dynamic(DT_INST_IRQN(0), 0, (void (*)(const void *))keyboard_raw_interrupt, (const void *)dev, 0); @@ -522,68 +506,22 @@ static int kscan_it8xxx2_init(const struct device *dev) return 0; } -static int kscan_it8xxx2_configure(const struct device *dev, - kscan_callback_t callback) -{ - struct kscan_it8xxx2_data *data = dev->data; - - if (!callback) { - return -EINVAL; - } - - /* Setup callback function */ - data->callback = callback; - - return 0; -} - -static int kscan_it8xxx2_disable_callback(const struct device *dev) -{ - struct kscan_it8xxx2_data *data = dev->data; - - /* Disable keyboard scan loop */ - atomic_set(&data->enable_scan, 0); - - return 0; -} - -static int kscan_it8xxx2_enable_callback(const struct device *dev) -{ - struct kscan_it8xxx2_data *data = dev->data; - - /* Enable keyboard scan loop */ - atomic_set(&data->enable_scan, 1); - - return 0; -} - -static const struct kscan_driver_api kscan_it8xxx2_driver_api = { - .config = kscan_it8xxx2_configure, - .disable_callback = kscan_it8xxx2_disable_callback, - .enable_callback = kscan_it8xxx2_enable_callback, -}; - -static const struct kscan_wuc_map_cfg kscan_wuc_0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = - IT8XXX2_DT_WUC_ITEMS_LIST(0); +static const struct input_it8xxx2_kbd_wuc_map_cfg + input_it8xxx2_kbd_wuc[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = IT8XXX2_DT_WUC_ITEMS_LIST(0); PINCTRL_DT_INST_DEFINE(0); -static const struct kscan_it8xxx2_config kscan_it8xxx2_cfg_0 = { +static const struct input_it8xxx2_kbd_config input_it8xxx2_kbd_cfg = { .base = (struct kscan_it8xxx2_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0), .irq = DT_INST_IRQN(0), - .wuc_map_list = kscan_wuc_0, + .wuc_map_list = input_it8xxx2_kbd_wuc, .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .kso16_gpios = GPIO_DT_SPEC_INST_GET(0, kso16_gpios), .kso17_gpios = GPIO_DT_SPEC_INST_GET(0, kso17_gpios), }; -static struct kscan_it8xxx2_data kscan_it8xxx2_kbd_data; +static struct input_it8xxx2_kbd_data input_it8xxx2_kbd_kbd_data; -DEVICE_DT_INST_DEFINE(0, - &kscan_it8xxx2_init, - NULL, - &kscan_it8xxx2_kbd_data, - &kscan_it8xxx2_cfg_0, - POST_KERNEL, - CONFIG_KSCAN_INIT_PRIORITY, - &kscan_it8xxx2_driver_api); +DEVICE_DT_INST_DEFINE(0, &input_it8xxx2_kbd_init, NULL, + &input_it8xxx2_kbd_kbd_data, &input_it8xxx2_kbd_cfg, + POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); diff --git a/drivers/kscan/CMakeLists.txt b/drivers/kscan/CMakeLists.txt index d650f17f917..005c53ab4b7 100644 --- a/drivers/kscan/CMakeLists.txt +++ b/drivers/kscan/CMakeLists.txt @@ -4,7 +4,6 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/kscan.h) zephyr_library() -zephyr_library_sources_ifdef(CONFIG_KSCAN_ITE_IT8XXX2 kscan_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_KSCAN_XEC kscan_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_KSCAN_HT16K33 kscan_ht16k33.c) zephyr_library_sources_ifdef(CONFIG_KSCAN_INPUT kscan_input.c) diff --git a/drivers/kscan/Kconfig b/drivers/kscan/Kconfig index 02ef0987cc6..a2a786c31e3 100644 --- a/drivers/kscan/Kconfig +++ b/drivers/kscan/Kconfig @@ -10,7 +10,6 @@ menuconfig KSCAN if KSCAN -source "drivers/kscan/Kconfig.it8xxx2" source "drivers/kscan/Kconfig.xec" source "drivers/kscan/Kconfig.ht16k33" source "drivers/kscan/Kconfig.input" diff --git a/dts/bindings/kscan/ite,it8xxx2-kscan.yaml b/dts/bindings/input/ite,it8xxx2-kbd.yaml similarity index 96% rename from dts/bindings/kscan/ite,it8xxx2-kscan.yaml rename to dts/bindings/input/ite,it8xxx2-kbd.yaml index 47a06b44ee3..1aec1e1e7a9 100644 --- a/dts/bindings/kscan/ite,it8xxx2-kscan.yaml +++ b/dts/bindings/input/ite,it8xxx2-kbd.yaml @@ -3,7 +3,7 @@ description: ITE it8xxx2 keyboard matrix controller -compatible: "ite,it8xxx2-kscan" +compatible: "ite,it8xxx2-kbd" include: [kscan.yaml, pinctrl-device.yaml] diff --git a/dts/riscv/ite/it8xxx2.dtsi b/dts/riscv/ite/it8xxx2.dtsi index 62734db2675..454e9c0c177 100644 --- a/dts/riscv/ite/it8xxx2.dtsi +++ b/dts/riscv/ite/it8xxx2.dtsi @@ -691,8 +691,8 @@ status = "disabled"; }; - kscan0: kscan@f01d00 { - compatible = "ite,it8xxx2-kscan"; + kbd: kbd@f01d00 { + compatible = "ite,it8xxx2-kbd"; reg = <0x00f01d00 0x29>; interrupt-parent = <&intc>; interrupts = ; From 678b29386dadeba9090b3518845560eb2b3087fc Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Thu, 19 Oct 2023 11:06:37 +0300 Subject: [PATCH 3417/4498] dts: bindings: adxl367: add interrupt support Add int1-gpios property in the adxl367 dts bindings. Signed-off-by: Antoniu Miclaus --- dts/bindings/sensor/adi,adxl367-common.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/bindings/sensor/adi,adxl367-common.yaml b/dts/bindings/sensor/adi,adxl367-common.yaml index 07ffc8ba440..722d13d92e0 100644 --- a/dts/bindings/sensor/adi,adxl367-common.yaml +++ b/dts/bindings/sensor/adi,adxl367-common.yaml @@ -22,3 +22,10 @@ properties: - 3 - 4 - 5 + + int1-gpios: + type: phandle-array + description: | + The INT1 signal defaults to active high as produced by the + sensor. The property value should ensure the flags properly + describe the signal that is presented to the driver. From af0b6567090d6af78f13ccb96be4076e09f4bafc Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Thu, 19 Oct 2023 11:07:09 +0300 Subject: [PATCH 3418/4498] drivers: sensor: adxl367: add trigger support Add trigger support for the adxl367 Zephyr driver. Signed-off-by: Antoniu Miclaus --- drivers/sensor/adxl367/CMakeLists.txt | 1 + drivers/sensor/adxl367/Kconfig | 38 +++++ drivers/sensor/adxl367/adxl367.c | 26 ++++ drivers/sensor/adxl367/adxl367.h | 45 ++++++ drivers/sensor/adxl367/adxl367_trigger.c | 180 +++++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 drivers/sensor/adxl367/adxl367_trigger.c diff --git a/drivers/sensor/adxl367/CMakeLists.txt b/drivers/sensor/adxl367/CMakeLists.txt index 3dafe9fffbf..1496eb11266 100644 --- a/drivers/sensor/adxl367/CMakeLists.txt +++ b/drivers/sensor/adxl367/CMakeLists.txt @@ -8,3 +8,4 @@ zephyr_library() zephyr_library_sources(adxl367.c) zephyr_library_sources(adxl367_spi.c) zephyr_library_sources(adxl367_i2c.c) +zephyr_library_sources_ifdef(CONFIG_ADXL367_TRIGGER adxl367_trigger.c) diff --git a/drivers/sensor/adxl367/Kconfig b/drivers/sensor/adxl367/Kconfig index af77a9e12cb..e0b4660b0f3 100644 --- a/drivers/sensor/adxl367/Kconfig +++ b/drivers/sensor/adxl367/Kconfig @@ -92,4 +92,42 @@ config ADXL367_REFERENCED_INACTIVITY_DETECTION_MODE compared directly to a user set threshold to determine whether motion is present. +choice ADXL367_TRIGGER_MODE + prompt "Trigger mode" + default ADXL367_TRIGGER_NONE + help + Specify the type of triggering used by the driver. + +config ADXL367_TRIGGER_NONE + bool "No trigger" + +config ADXL367_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select ADXL367_TRIGGER + +config ADXL367_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select ADXL367_TRIGGER + +endchoice + +config ADXL367_TRIGGER + bool + +config ADXL367_THREAD_PRIORITY + int "Thread priority" + depends on ADXL367_TRIGGER_OWN_THREAD && ADXL367_TRIGGER + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config ADXL367_THREAD_STACK_SIZE + int "Thread stack size" + depends on ADXL367_TRIGGER_OWN_THREAD && ADXL367_TRIGGER + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + endif # ADXL367 diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c index 44eecf1c975..2979b945b62 100644 --- a/drivers/sensor/adxl367/adxl367.c +++ b/drivers/sensor/adxl367/adxl367.c @@ -846,6 +846,9 @@ static const struct sensor_driver_api adxl367_api_funcs = { .attr_set = adxl367_attr_set, .sample_fetch = adxl367_sample_fetch, .channel_get = adxl367_channel_get, +#ifdef CONFIG_ADXL367_TRIGGER + .trigger_set = adxl367_trigger_set, +#endif }; static int adxl367_probe(const struct device *dev) @@ -876,7 +879,11 @@ static int adxl367_probe(const struct device *dev) data->range = cfg->range; +#ifdef CONFIG_ADXL367_TRIGGER + data->act_proc_mode = ADXL367_LINKED; +#else data->act_proc_mode = ADXL367_LOOPED; +#endif ret = adxl367_self_test(dev); if (ret) { @@ -931,6 +938,14 @@ static int adxl367_probe(const struct device *dev) return ret; } +if (IS_ENABLED(CONFIG_ADXL367_TRIGGER)) { + ret = adxl367_init_interrupt(dev); + if (ret != 0) { + LOG_ERR("Failed to initialize interrupt!"); + return -EIO; + } +} + ret = adxl367_set_op_mode(dev, cfg->op_mode); if (ret) { return ret; @@ -977,6 +992,13 @@ static int adxl367_init(const struct device *dev) CONFIG_SENSOR_INIT_PRIORITY, \ &adxl367_api_funcs); +#ifdef CONFIG_ADXL367_TRIGGER +#define ADXL367_CFG_IRQ(inst) \ + .interrupt = GPIO_DT_SPEC_INST_GET(inst, int1_gpios), +#else +#define ADXL367_CFG_IRQ(inst) +#endif /* CONFIG_ADXL367_TRIGGER */ + #define ADXL367_CONFIG(inst) \ .odr = DT_INST_PROP(inst, odr), \ .autosleep = false, \ @@ -1011,6 +1033,8 @@ static int adxl367_init(const struct device *dev) .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8) | \ SPI_TRANSFER_MSB, 0), \ ADXL367_CONFIG(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ + (ADXL367_CFG_IRQ(inst)), ()) \ } #define ADXL367_DEFINE_SPI(inst) \ @@ -1028,6 +1052,8 @@ static int adxl367_init(const struct device *dev) .bus_init = adxl367_i2c_init, \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ ADXL367_CONFIG(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ + (ADXL367_CFG_IRQ(inst)), ()) \ } #define ADXL367_DEFINE_I2C(inst) \ diff --git a/drivers/sensor/adxl367/adxl367.h b/drivers/sensor/adxl367/adxl367.h index 0b7b44faea4..8cef47420bb 100644 --- a/drivers/sensor/adxl367/adxl367.h +++ b/drivers/sensor/adxl367/adxl367.h @@ -177,6 +177,25 @@ #define ADXL367_STATUS_FIFO_RDY BIT(1) #define ADXL367_STATUS_DATA_RDY BIT(0) +/* ADXL367_INTMAP_LOWER */ +#define ADXL367_INT_LOW BIT(7) +#define ADXL367_AWAKE_INT BIT(6) +#define ADXL367_INACT_INT BIT(5) +#define ADXL367_ACT_INT BIT(4) +#define ADXL367_FIFO_OVERRUN BIT(3) +#define ADXL367_FIFO_WATERMARK BIT(2) +#define ADXL367_FIFO_RDY BIT(1) +#define ADXL367_DATA_RDY BIT(0) + +/* ADXL367_INTMAP_UPPER */ +#define ADXL367_ERR_FUSE BIT(7) +#define ADXL367_ERR_USER_REGS BIT(6) +#define ADXL367_KPALV_TIMER BIT(4) +#define ADXL367_TEMP_ADC_HI BIT(3) +#define ADXL367_TEMP_ADC_LOW BIT(2) +#define ADXL367_TAP_TWO BIT(1) +#define ADXL367_TAP_ONE BIT(0) + /* Min change = 90mg. Sensitivity = 4LSB / mg */ #define ADXL367_SELF_TEST_MIN (90 * 100 / 25) /* Max change = 270mg. Sensitivity = 4LSB / mg */ @@ -280,6 +299,23 @@ struct adxl367_data { struct adxl367_fifo_config fifo_config; enum adxl367_act_proc_mode act_proc_mode; enum adxl367_range range; +#ifdef CONFIG_ADXL367_TRIGGER + struct gpio_callback gpio_cb; + + sensor_trigger_handler_t th_handler; + const struct sensor_trigger *th_trigger; + sensor_trigger_handler_t drdy_handler; + const struct sensor_trigger *drdy_trigger; + const struct device *dev; + +#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ADXL367_THREAD_STACK_SIZE); + struct k_sem gpio_sem; + struct k_thread thread; +#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif +#endif /* CONFIG_ADXL367_TRIGGER */ }; struct adxl367_dev_config { @@ -291,6 +327,10 @@ struct adxl367_dev_config { #endif int (*bus_init)(const struct device *dev); +#ifdef CONFIG_ADXL367_TRIGGER + struct gpio_dt_spec interrupt; +#endif + enum adxl367_odr odr; /* Device Settings */ @@ -311,5 +351,10 @@ struct adxl367_dev_config { int adxl367_spi_init(const struct device *dev); int adxl367_i2c_init(const struct device *dev); +int adxl367_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int adxl367_init_interrupt(const struct device *dev); #endif /* ZEPHYR_DRIVERS_SENSOR_ADXL367_ADXL367_H_ */ diff --git a/drivers/sensor/adxl367/adxl367_trigger.c b/drivers/sensor/adxl367/adxl367_trigger.c new file mode 100644 index 00000000000..4e86d466343 --- /dev/null +++ b/drivers/sensor/adxl367/adxl367_trigger.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2023 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "adxl367.h" + +#include +LOG_MODULE_DECLARE(ADXL367, CONFIG_SENSOR_LOG_LEVEL); + +static void adxl367_thread_cb(const struct device *dev) +{ + const struct adxl367_dev_config *cfg = dev->config; + struct adxl367_data *drv_data = dev->data; + uint8_t status; + int ret; + + /* Clear the status */ + ret = drv_data->hw_tf->read_reg(dev, ADXL367_STATUS, &status); + if (ret != 0) { + return; + } + + if (drv_data->th_handler != NULL) { + if (((FIELD_GET(ADXL367_STATUS_INACT, status)) != 0) || + (FIELD_GET(ADXL367_STATUS_ACT, status)) != 0) { + drv_data->th_handler(dev, drv_data->th_trigger); + } + } + + if ((drv_data->drdy_handler != NULL) && + (FIELD_GET(ADXL367_STATUS_DATA_RDY, status) != 0)) { + drv_data->drdy_handler(dev, drv_data->drdy_trigger); + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt, + GPIO_INT_EDGE_TO_ACTIVE); + __ASSERT(ret == 0, "Interrupt configuration failed"); +} + +static void adxl367_gpio_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + struct adxl367_data *drv_data = + CONTAINER_OF(cb, struct adxl367_data, gpio_cb); + const struct adxl367_dev_config *cfg = drv_data->dev->config; + + gpio_pin_interrupt_configure_dt(&cfg->interrupt, GPIO_INT_DISABLE); + +#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD) + k_sem_give(&drv_data->gpio_sem); +#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD) + k_work_submit(&drv_data->work); +#endif +} + +#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD) +static void adxl367_thread(struct adxl367_data *drv_data) +{ + while (true) { + k_sem_take(&drv_data->gpio_sem, K_FOREVER); + adxl367_thread_cb(drv_data->dev); + } +} + +#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD) +static void adxl367_work_cb(struct k_work *work) +{ + struct adxl367_data *drv_data = + CONTAINER_OF(work, struct adxl367_data, work); + + adxl367_thread_cb(drv_data->dev); +} +#endif + +int adxl367_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + const struct adxl367_dev_config *cfg = dev->config; + struct adxl367_data *drv_data = dev->data; + uint8_t int_mask, int_en, status; + int ret; + + ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt, + GPIO_INT_DISABLE); + if (ret != 0) { + return ret; + } + + switch (trig->type) { + case SENSOR_TRIG_THRESHOLD: + drv_data->th_handler = handler; + drv_data->th_trigger = trig; + int_mask = ADXL367_ACT_INT | ADXL367_INACT_INT; + break; + case SENSOR_TRIG_DATA_READY: + drv_data->drdy_handler = handler; + drv_data->drdy_trigger = trig; + int_mask = ADXL367_DATA_RDY; + break; + default: + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + if (handler != NULL) { + int_en = int_mask; + } else { + int_en = 0U; + } + + ret = drv_data->hw_tf->write_reg_mask(dev, ADXL367_INTMAP1_LOWER, int_mask, int_en); + if (ret != 0) { + return ret; + } + + /* Clear status */ + ret = drv_data->hw_tf->read_reg(dev, ADXL367_STATUS, &status); + if (ret != 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + return ret; + } + + return 0; +} + +int adxl367_init_interrupt(const struct device *dev) +{ + const struct adxl367_dev_config *cfg = dev->config; + struct adxl367_data *drv_data = dev->data; + int ret; + + if (!gpio_is_ready_dt(&cfg->interrupt)) { + LOG_ERR("GPIO port %s not ready", cfg->interrupt.port->name); + return -EINVAL; + } + + ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT); + if (ret != 0) { + return ret; + } + + gpio_init_callback(&drv_data->gpio_cb, + adxl367_gpio_callback, + BIT(cfg->interrupt.pin)); + + ret = gpio_add_callback(cfg->interrupt.port, &drv_data->gpio_cb); + if (ret != 0) { + LOG_ERR("Failed to set gpio callback!"); + return ret; + } + + drv_data->dev = dev; + +#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD) + k_sem_init(&drv_data->gpio_sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&drv_data->thread, drv_data->thread_stack, + CONFIG_ADXL367_THREAD_STACK_SIZE, + (k_thread_entry_t)adxl367_thread, drv_data, + NULL, NULL, K_PRIO_COOP(CONFIG_ADXL367_THREAD_PRIORITY), + 0, K_NO_WAIT); +#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD) + drv_data->work.handler = adxl367_work_cb; +#endif + + return 0; +} From 1088846e9a47dfcd72d6e49073addcf436434a4e Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Thu, 19 Oct 2023 14:09:08 +0300 Subject: [PATCH 3419/4498] tests: build_all: sensor: add adxl367 trigger Add trigger support for adxl367 build all sensor tests. Signed-off-by: Antoniu Miclaus --- tests/drivers/build_all/sensor/i2c.dtsi | 1 + tests/drivers/build_all/sensor/sensors_trigger_global.conf | 1 + tests/drivers/build_all/sensor/sensors_trigger_none.conf | 1 + tests/drivers/build_all/sensor/sensors_trigger_own.conf | 1 + tests/drivers/build_all/sensor/spi.dtsi | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 4e54911f969..eda5bff0ff7 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -793,6 +793,7 @@ test_i2c_adxl367: adxl367@77 { compatible = "adi,adxl367"; reg = <0x77>; odr = <4>; + int1-gpios = <&test_gpio 0 0>; }; test_i2c_tsl2561: tsl2561@78 { diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index f0c34845ce0..74ba8f20239 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -1,6 +1,7 @@ CONFIG_ADT7310_TRIGGER_GLOBAL_THREAD=y CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD=y CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD=y +CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD=y CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD=y CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD=y CONFIG_APDS9960_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index 2c4b51c2184..905907928f5 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -1,6 +1,7 @@ CONFIG_ADT7310_TRIGGER_NONE=y CONFIG_ADT7420_TRIGGER_NONE=y CONFIG_ADXL362_TRIGGER_NONE=y +CONFIG_ADXL367_TRIGGER_NONE=y CONFIG_ADXL372_TRIGGER_NONE=y CONFIG_AMG88XX_TRIGGER_NONE=y CONFIG_APDS9960_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index a64f6aa5c8b..92504b6c2f4 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -1,6 +1,7 @@ CONFIG_ADT7310_TRIGGER_OWN_THREAD=y CONFIG_ADT7420_TRIGGER_OWN_THREAD=y CONFIG_ADXL362_TRIGGER_OWN_THREAD=y +CONFIG_ADXL367_TRIGGER_OWN_THREAD=y CONFIG_ADXL372_TRIGGER_OWN_THREAD=y CONFIG_AMG88XX_TRIGGER_OWN_THREAD=y CONFIG_BMA280_TRIGGER_OWN_THREAD=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index bd734d98f68..d026e244f88 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -302,4 +302,5 @@ test_spi_adxl367: adxl367@26 { reg = <0x26>; spi-max-frequency = <0>; odr = <4>; + int1-gpios = <&test_gpio 0 0>; }; From 94dc05b3f2542c5035d6120f6e5e4ed825775626 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Mon, 5 Jun 2023 20:26:19 -0600 Subject: [PATCH 3420/4498] sensors: Add streaming APIs Introduce a streaming API that uses the same data path as the async API. This includes features to the decoder: * Checking if triggers are present Adding streaming features built ontop of existing triggers: * Adding 3 operations to be done on a trigger * include - include the data with the trigger information * nop - do nothing * drop - drop the data (flush) * Add a new sensor_stream() API to mirror sensor_read() but add an optional handler to be able to cancel the stream. Signed-off-by: Yuval Peress topic#sensor_stream --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 17 + drivers/sensor/default_rtio_sensor.c | 6 +- drivers/sensor/sensor_shell.c | 317 +++++++++++++++--- drivers/sensor/sensor_shell.h | 26 ++ drivers/sensor/sensor_shell_stream.c | 124 +++++++ include/zephyr/drivers/sensor.h | 111 +++++- .../sensor_shell/boards/tdk_robokit1.conf | 3 + samples/sensor/sensor_shell/sample.yaml | 2 + 9 files changed, 543 insertions(+), 64 deletions(-) create mode 100644 drivers/sensor/sensor_shell.h create mode 100644 drivers/sensor/sensor_shell_stream.c create mode 100644 samples/sensor/sensor_shell/boards/tdk_robokit1.conf diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index b0359f0254b..8ac3da6c937 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -166,5 +166,6 @@ zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_USERSPACE sensor_handlers.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL sensor_shell.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_STREAM sensor_shell_stream.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_BATTERY shell_battery.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API sensor_decoders_init.c default_rtio_sensor.c) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 31809dd0791..000c4bb1a35 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -36,6 +36,23 @@ config SENSOR_SHELL help This shell provides access to basic sensor data. +config SENSOR_SHELL_STREAM + bool "Sensor shell 'stream' command" + depends on SENSOR_SHELL + help + Add the 'stream' subcommand to the sensor shell. When run on drivers that + support streaming (usually hardware FIFO backed), the shell will continue + to print new values as they come until the stream is closed. + +config SENSOR_SHELL_THREAD_STACK_SIZE + int "Stack size for the sensor shell data processing thread" + depends on SENSOR_SHELL_STREAM + default 1024 + help + The sensor shell uses a dedicated thread to process data coming from the + sensors in either one-shot or streaming mode. Use this config to control + the size of that thread's stack. + config SENSOR_SHELL_BATTERY bool "Sensor shell 'battery' command" depends on SHELL diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index e088b4f61c2..3f9377c33b3 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -28,8 +28,10 @@ static void sensor_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) if (api->submit != NULL) { api->submit(dev, iodev_sqe); - } else { + } else if (!cfg->is_streaming) { sensor_submit_fallback(dev, iodev_sqe); + } else { + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); } } @@ -235,7 +237,7 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s } sample_idx += num_samples; } - LOG_DBG("Total channels in header: %u", header->num_channels); + LOG_DBG("Total channels in header: %" PRIu32, header->num_channels); rtio_iodev_sqe_ok(iodev_sqe, 0); } diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index a85eab23e43..5d41663c491 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -16,6 +16,8 @@ #include #include +#include "sensor_shell.h" + LOG_MODULE_REGISTER(sensor_shell); #define SENSOR_GET_HELP \ @@ -23,6 +25,11 @@ LOG_MODULE_REGISTER(sensor_shell); "when no channels are provided. Syntax:\n" \ " .. " +#define SENSOR_STREAM_HELP \ + "Start/stop streaming sensor data. Data ready trigger will be used if no triggers " \ + "are provided. Syntax:\n" \ + " on|off incl|drop|nop" + #define SENSOR_ATTR_GET_HELP \ "Get the sensor's channel attribute. Syntax:\n" \ " [ .. " \ @@ -38,7 +45,7 @@ LOG_MODULE_REGISTER(sensor_shell); "Get or set the trigger type on a sensor. Currently only supports `data_ready`.\n" \ " " -const char *sensor_channel_name[SENSOR_CHAN_ALL] = { +const char *sensor_channel_name[SENSOR_CHAN_COMMON_COUNT] = { [SENSOR_CHAN_ACCEL_X] = "accel_x", [SENSOR_CHAN_ACCEL_Y] = "accel_y", [SENSOR_CHAN_ACCEL_Z] = "accel_z", @@ -96,6 +103,7 @@ const char *sensor_channel_name[SENSOR_CHAN_ALL] = { [SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE] = "gauge_design_voltage", [SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE] = "gauge_desired_voltage", [SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT] = "gauge_desired_charging_current", + [SENSOR_CHAN_ALL] = "all", }; static const char *sensor_attribute_name[SENSOR_ATTR_COMMON_COUNT] = { @@ -114,6 +122,7 @@ static const char *sensor_attribute_name[SENSOR_ATTR_COMMON_COUNT] = { [SENSOR_ATTR_FEATURE_MASK] = "feature_mask", [SENSOR_ATTR_ALERT] = "alert", [SENSOR_ATTR_FF_DUR] = "ff_dur", + [SENSOR_ATTR_FIFO_WATERMARK] = "fifo_wm", }; /* Forward declaration */ @@ -146,12 +155,32 @@ static const struct { TRIGGER_DATA_ENTRY(SENSOR_TRIG_FREEFALL, freefall, NULL), TRIGGER_DATA_ENTRY(SENSOR_TRIG_MOTION, motion, NULL), TRIGGER_DATA_ENTRY(SENSOR_TRIG_STATIONARY, stationary, NULL), + TRIGGER_DATA_ENTRY(SENSOR_TRIG_FIFO_WATERMARK, fifo_wm, NULL), + TRIGGER_DATA_ENTRY(SENSOR_TRIG_FIFO_FULL, fifo_full, NULL), }; +/** + * Lookup the sensor trigger data by name + * + * @param name The name of the trigger + * @return < 0 on error + * @return >= 0 if found + */ +static int sensor_trigger_name_lookup(const char *name) +{ + for (int i = 0; i < ARRAY_SIZE(sensor_trigger_table); ++i) { + if (strcmp(name, sensor_trigger_table[i].name) == 0) { + return i; + } + } + return -1; +} + enum dynamic_command_context { NONE, CTX_GET, CTX_ATTR_GET_SET, + CTX_STREAM_ON_OFF, }; static enum dynamic_command_context current_cmd_ctx = NONE; @@ -163,6 +192,7 @@ K_MUTEX_DEFINE(cmd_get_mutex); static enum sensor_channel iodev_sensor_shell_channels[SENSOR_CHAN_ALL]; static struct sensor_read_config iodev_sensor_shell_read_config = { .sensor = NULL, + .is_streaming = false, .channels = iodev_sensor_shell_channels, .count = 0, .max = ARRAY_SIZE(iodev_sensor_shell_channels), @@ -234,17 +264,18 @@ static int parse_sensor_value(const char *val_str, struct sensor_value *out) return 0; } -struct sensor_shell_processing_context { - const struct device *dev; - const struct shell *sh; -}; - -static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len, - void *userdata) +void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len, void *userdata) { struct sensor_shell_processing_context *ctx = userdata; const struct sensor_decoder_api *decoder; uint8_t decoded_buffer[128]; + struct { + uint64_t base_timestamp_ns; + int count; + uint64_t timestamp_delta; + int64_t values[3]; + int8_t shift; + } accumulator_buffer; int rc; ARG_UNUSED(buf_len); @@ -260,6 +291,17 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t return; } + for (int trigger = 0; decoder->has_trigger != NULL && trigger < SENSOR_TRIG_COMMON_COUNT; + ++trigger) { + if (!decoder->has_trigger(buf, trigger)) { + continue; + } + shell_info(ctx->sh, "Trigger (%d / %s) detected", trigger, + (sensor_trigger_table[trigger].name == NULL + ? "UNKNOWN" + : sensor_trigger_table[trigger].name)); + } + for (int channel = 0; channel < SENSOR_CHAN_ALL; ++channel) { uint32_t fit = 0; size_t base_size; @@ -292,6 +334,7 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t while (decoder->get_frame_count(buf, channel, channel_idx, &frame_count) == 0) { fit = 0; + memset(&accumulator_buffer, 0, sizeof(accumulator_buffer)); while (decoder->decode(buf, channel, channel_idx, &fit, 1, decoded_buffer) > 0) { @@ -303,41 +346,127 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t struct sensor_three_axis_data *data = (struct sensor_three_axis_data *)decoded_buffer; - shell_info(ctx->sh, - "channel idx=%d %s shift=%d " - "value=%" PRIsensor_three_axis_data, - channel, sensor_channel_name[channel], - data->shift, - PRIsensor_three_axis_data_arg(*data, 0)); + if (accumulator_buffer.count == 0) { + accumulator_buffer.base_timestamp_ns = + data->header.base_timestamp_ns; + } + accumulator_buffer.count++; + accumulator_buffer.shift = data->shift; + accumulator_buffer.timestamp_delta += + data->readings[0].timestamp_delta; + accumulator_buffer.values[0] += data->readings[0].values[0]; + accumulator_buffer.values[1] += data->readings[0].values[1]; + accumulator_buffer.values[2] += data->readings[0].values[2]; break; } case SENSOR_CHAN_PROX: { struct sensor_byte_data *data = (struct sensor_byte_data *)decoded_buffer; - shell_info(ctx->sh, - "channel idx=%d %s value=%" PRIsensor_byte_data( - is_near), - channel, sensor_channel_name[channel], - PRIsensor_byte_data_arg(*data, 0, is_near)); + if (accumulator_buffer.count == 0) { + accumulator_buffer.base_timestamp_ns = + data->header.base_timestamp_ns; + } + accumulator_buffer.count++; + accumulator_buffer.timestamp_delta += + data->readings[0].timestamp_delta; + accumulator_buffer.values[0] += data->readings[0].is_near; break; } default: { struct sensor_q31_data *data = (struct sensor_q31_data *)decoded_buffer; - shell_info(ctx->sh, - "channel idx=%d %s shift=%d " - "value=%" PRIsensor_q31_data, - channel, - (channel >= ARRAY_SIZE(sensor_channel_name)) - ? "" - : sensor_channel_name[channel], - data->shift, PRIsensor_q31_data_arg(*data, 0)); + if (accumulator_buffer.count == 0) { + accumulator_buffer.base_timestamp_ns = + data->header.base_timestamp_ns; + } + accumulator_buffer.count++; + accumulator_buffer.shift = data->shift; + accumulator_buffer.timestamp_delta += + data->readings[0].timestamp_delta; + accumulator_buffer.values[0] += data->readings[0].value; break; } } } + + /* Print the accumulated value average */ + switch (channel) { + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_MAGN_XYZ: + case SENSOR_CHAN_POS_DX: { + struct sensor_three_axis_data *data = + (struct sensor_three_axis_data *)decoded_buffer; + + data->header.base_timestamp_ns = + accumulator_buffer.base_timestamp_ns; + data->header.reading_count = 1; + data->shift = accumulator_buffer.shift; + data->readings[0].timestamp_delta = + (uint32_t)(accumulator_buffer.timestamp_delta / + accumulator_buffer.count); + data->readings[0].values[0] = (q31_t)(accumulator_buffer.values[0] / + accumulator_buffer.count); + data->readings[0].values[1] = (q31_t)(accumulator_buffer.values[1] / + accumulator_buffer.count); + data->readings[0].values[2] = (q31_t)(accumulator_buffer.values[2] / + accumulator_buffer.count); + shell_info(ctx->sh, + "channel idx=%d %s shift=%d num_samples=%d " + "value=%" PRIsensor_three_axis_data, + channel, sensor_channel_name[channel], + data->shift, accumulator_buffer.count, + PRIsensor_three_axis_data_arg(*data, 0)); + break; + } + case SENSOR_CHAN_PROX: { + struct sensor_byte_data *data = + (struct sensor_byte_data *)decoded_buffer; + + data->header.base_timestamp_ns = + accumulator_buffer.base_timestamp_ns; + data->header.reading_count = 1; + data->readings[0].timestamp_delta = + (uint32_t)(accumulator_buffer.timestamp_delta / + accumulator_buffer.count); + data->readings[0].is_near = + accumulator_buffer.values[0] / accumulator_buffer.count; + + shell_info(ctx->sh, + "channel idx=%d %s num_samples=%d " + "value=%" PRIsensor_byte_data(is_near), + channel, sensor_channel_name[channel], + accumulator_buffer.count, + PRIsensor_byte_data_arg(*data, 0, is_near)); + break; + } + default: { + struct sensor_q31_data *data = + (struct sensor_q31_data *)decoded_buffer; + + data->header.base_timestamp_ns = + accumulator_buffer.base_timestamp_ns; + data->header.reading_count = 1; + data->shift = accumulator_buffer.shift; + data->readings[0].timestamp_delta = + (uint32_t)(accumulator_buffer.timestamp_delta / + accumulator_buffer.count); + data->readings[0].value = (q31_t)(accumulator_buffer.values[0] / + accumulator_buffer.count); + + shell_info(ctx->sh, + "channel idx=%d %s shift=%d num_samples=%d " + "value=%" PRIsensor_q31_data, + channel, + (channel >= ARRAY_SIZE(sensor_channel_name)) + ? "" + : sensor_channel_name[channel], + data->shift, accumulator_buffer.count, + PRIsensor_q31_data_arg(*data, 0)); + } + } ++channel_idx; } } @@ -345,6 +474,7 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) { + static struct sensor_shell_processing_context ctx; const struct device *dev; int count = 0; int err; @@ -392,21 +522,27 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) iodev_sensor_shell_read_config.sensor = dev; iodev_sensor_shell_read_config.count = count; - struct sensor_shell_processing_context ctx = { - .dev = dev, - .sh = sh, - }; + ctx.dev = dev; + ctx.sh = sh; err = sensor_read(&iodev_sensor_shell_read, &sensor_read_rtio, &ctx); if (err < 0) { shell_error(sh, "Failed to read sensor: %d", err); } - sensor_processing_with_callback(&sensor_read_rtio, sensor_shell_processing_callback); + if (!IS_ENABLED(CONFIG_SENSOR_SHELL_STREAM)) { + /* + * Streaming enables a thread that polls the RTIO context, so if it's enabled, we + * don't need a blocking read here. + */ + sensor_processing_with_callback(&sensor_read_rtio, + sensor_shell_processing_callback); + } k_mutex_unlock(&cmd_get_mutex); return 0; } + static int cmd_sensor_attr_set(const struct shell *shell_ptr, size_t argc, char *argv[]) { const struct device *dev; @@ -517,9 +653,37 @@ static int cmd_sensor_attr_get(const struct shell *shell_ptr, size_t argc, char } static void channel_name_get(size_t idx, struct shell_static_entry *entry); - SHELL_DYNAMIC_CMD_CREATE(dsub_channel_name, channel_name_get); +static void attribute_name_get(size_t idx, struct shell_static_entry *entry); +SHELL_DYNAMIC_CMD_CREATE(dsub_attribute_name, attribute_name_get); + +static void channel_name_get(size_t idx, struct shell_static_entry *entry) +{ + int cnt = 0; + + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + if (current_cmd_ctx == CTX_GET) { + entry->subcmd = &dsub_channel_name; + } else if (current_cmd_ctx == CTX_ATTR_GET_SET) { + entry->subcmd = &dsub_attribute_name; + } else { + entry->subcmd = NULL; + } + + for (int i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) { + if (sensor_channel_name[i] != NULL) { + if (cnt == idx) { + entry->syntax = sensor_channel_name[i]; + break; + } + cnt++; + } + } +} + static void attribute_name_get(size_t idx, struct shell_static_entry *entry) { int cnt = 0; @@ -529,7 +693,7 @@ static void attribute_name_get(size_t idx, struct shell_static_entry *entry) entry->help = NULL; entry->subcmd = &dsub_channel_name; - for (int i = 0; i < SENSOR_ATTR_COMMON_COUNT; i++) { + for (int i = 0; i < ARRAY_SIZE(sensor_attribute_name); i++) { if (sensor_attribute_name[i] != NULL) { if (cnt == idx) { entry->syntax = sensor_attribute_name[i]; @@ -539,27 +703,46 @@ static void attribute_name_get(size_t idx, struct shell_static_entry *entry) } } } -SHELL_DYNAMIC_CMD_CREATE(dsub_attribute_name, attribute_name_get); -static void channel_name_get(size_t idx, struct shell_static_entry *entry) +static void trigger_opt_get_for_stream(size_t idx, struct shell_static_entry *entry); +SHELL_DYNAMIC_CMD_CREATE(dsub_trigger_opt_get_for_stream, trigger_opt_get_for_stream); + +static void trigger_opt_get_for_stream(size_t idx, struct shell_static_entry *entry) +{ + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; + + switch (idx) { + case SENSOR_STREAM_DATA_INCLUDE: + entry->syntax = "incl"; + break; + case SENSOR_STREAM_DATA_DROP: + entry->syntax = "drop"; + break; + case SENSOR_STREAM_DATA_NOP: + entry->syntax = "nop"; + break; + } +} + +static void trigger_name_get_for_stream(size_t idx, struct shell_static_entry *entry); +SHELL_DYNAMIC_CMD_CREATE(dsub_trigger_name_for_stream, trigger_name_get_for_stream); + +static void trigger_name_get_for_stream(size_t idx, struct shell_static_entry *entry) { int cnt = 0; entry->syntax = NULL; entry->handler = NULL; entry->help = NULL; - if (current_cmd_ctx == CTX_GET) { - entry->subcmd = &dsub_channel_name; - } else if (current_cmd_ctx == CTX_ATTR_GET_SET) { - entry->subcmd = &dsub_attribute_name; - } else { - entry->subcmd = NULL; - } + entry->subcmd = &dsub_trigger_opt_get_for_stream; - for (int i = 0; i < SENSOR_CHAN_ALL; i++) { - if (sensor_channel_name[i] != NULL) { + for (int i = 0; i < ARRAY_SIZE(sensor_trigger_table); i++) { + if (sensor_trigger_table[i].name != NULL) { if (cnt == idx) { - entry->syntax = sensor_channel_name[i]; + entry->syntax = sensor_trigger_table[i].name; break; } cnt++; @@ -567,6 +750,22 @@ static void channel_name_get(size_t idx, struct shell_static_entry *entry) } } +static void stream_on_off(size_t idx, struct shell_static_entry *entry) +{ + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + + if (idx == 0) { + entry->syntax = "on"; + entry->subcmd = &dsub_trigger_name_for_stream; + } else if (idx == 1) { + entry->syntax = "off"; + entry->subcmd = NULL; + } +} +SHELL_DYNAMIC_CMD_CREATE(dsub_stream_on_off, stream_on_off); + static void device_name_get(size_t idx, struct shell_static_entry *entry); SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); @@ -603,7 +802,7 @@ static void trigger_name_get(size_t idx, struct shell_static_entry *entry) entry->help = NULL; entry->subcmd = NULL; - for (int i = 0; i < SENSOR_TRIG_COMMON_COUNT; i++) { + for (int i = 0; i < ARRAY_SIZE(sensor_trigger_table); i++) { if (sensor_trigger_table[i].name != NULL) { if (cnt == idx) { entry->syntax = sensor_trigger_table[i].name; @@ -649,6 +848,18 @@ static void device_name_get_for_trigger(size_t idx, struct shell_static_entry *e SHELL_DYNAMIC_CMD_CREATE(dsub_trigger, device_name_get_for_trigger); +static void device_name_get_for_stream(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_lookup(idx, NULL); + + current_cmd_ctx = CTX_STREAM_ON_OFF; + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = &dsub_stream_on_off; +} +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name_for_stream, device_name_get_for_stream); + static int cmd_get_sensor_info(const struct shell *sh, size_t argc, char **argv) { ARG_UNUSED(argc); @@ -738,7 +949,7 @@ static void data_ready_trigger_handler(const struct device *sensor, static int cmd_trig_sensor(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; - enum sensor_trigger_type trigger; + int trigger; int err; if (argc < 4) { @@ -754,12 +965,8 @@ static int cmd_trig_sensor(const struct shell *sh, size_t argc, char **argv) } /* Map the trigger string to an enum value */ - for (trigger = 0; trigger < ARRAY_SIZE(sensor_trigger_table); trigger++) { - if (strcmp(argv[3], sensor_trigger_table[trigger].name) == 0) { - break; - } - } - if (trigger >= SENSOR_TRIG_COMMON_COUNT || sensor_trigger_table[trigger].handler == NULL) { + trigger = sensor_trigger_name_lookup(argv[3]); + if (trigger < 0 || sensor_trigger_table[trigger].handler == NULL) { shell_error(sh, "Unsupported trigger type (%s)", argv[3]); return -ENOTSUP; } @@ -792,6 +999,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor, cmd_sensor_attr_set, 2, 255), SHELL_CMD_ARG(attr_get, &dsub_device_name_for_attr, SENSOR_ATTR_GET_HELP, cmd_sensor_attr_get, 2, 255), + SHELL_COND_CMD(CONFIG_SENSOR_SHELL_STREAM, stream, &dsub_device_name_for_stream, + SENSOR_STREAM_HELP, cmd_sensor_stream), SHELL_COND_CMD(CONFIG_SENSOR_INFO, info, NULL, SENSOR_INFO_HELP, cmd_get_sensor_info), SHELL_CMD_ARG(trig, &dsub_trigger, SENSOR_TRIG_HELP, cmd_trig_sensor, diff --git a/drivers/sensor/sensor_shell.h b/drivers/sensor/sensor_shell.h new file mode 100644 index 00000000000..cfc8b2489db --- /dev/null +++ b/drivers/sensor/sensor_shell.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_SENSOR_SHELL_H +#define ZEPHYR_DRIVERS_SENSOR_SENSOR_SHELL_H + +#include +#include +#include +#include + +struct sensor_shell_processing_context { + const struct device *dev; + const struct shell *sh; +}; + +extern struct rtio sensor_read_rtio; + +int cmd_sensor_stream(const struct shell *shell_ptr, size_t argc, char *argv[]); + +void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len, void *userdata); + +#endif /* ZEPHYR_DRIVERS_SENSOR_SENSOR_SHELL_H */ diff --git a/drivers/sensor/sensor_shell_stream.c b/drivers/sensor/sensor_shell_stream.c new file mode 100644 index 00000000000..ab3b835aa10 --- /dev/null +++ b/drivers/sensor/sensor_shell_stream.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include "sensor_shell.h" + +/* Create a single common config for streaming */ +static struct sensor_stream_trigger iodev_sensor_shell_trigger; +static struct sensor_read_config iodev_sensor_shell_stream_config = { + .sensor = NULL, + .is_streaming = true, + .triggers = &iodev_sensor_shell_trigger, + .count = 0, + .max = 1, +}; +RTIO_IODEV_DEFINE(iodev_sensor_shell_stream, &__sensor_iodev_api, + &iodev_sensor_shell_stream_config); + +static void sensor_shell_processing_entry_point(void *a, void *b, void *c) +{ + ARG_UNUSED(a); + ARG_UNUSED(b); + ARG_UNUSED(c); + + while (true) { + sensor_processing_with_callback(&sensor_read_rtio, + sensor_shell_processing_callback); + } +} +K_THREAD_DEFINE(sensor_shell_processing_tid, CONFIG_SENSOR_SHELL_THREAD_STACK_SIZE, + sensor_shell_processing_entry_point, NULL, NULL, NULL, 0, 0, 0); + +int cmd_sensor_stream(const struct shell *shell_ptr, size_t argc, char *argv[]) +{ + static struct rtio_sqe *current_streaming_handle; + static struct sensor_shell_processing_context ctx; + const struct device *dev = device_get_binding(argv[1]); + + if (argc != 5 && argc != 3) { + shell_error(shell_ptr, "Wrong number of arguments (%zu)", argc); + return -EINVAL; + } + + if (dev == NULL) { + shell_error(shell_ptr, "Device unknown (%s)", argv[1]); + return -ENODEV; + } + + if (current_streaming_handle != NULL) { + shell_info(shell_ptr, "Disabling existing stream"); + rtio_sqe_cancel(current_streaming_handle); + } + + if (strcmp("off", argv[2]) == 0) { + return 0; + } + + if (strcmp("on", argv[2]) != 0) { + shell_error(shell_ptr, "Unknown streaming operation (%s)", argv[2]); + return -EINVAL; + } + + if (strcmp("double_tap", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DOUBLE_TAP; + } else if (strcmp("data_ready", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DATA_READY; + } else if (strcmp("delta", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DELTA; + } else if (strcmp("freefall", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FREEFALL; + } else if (strcmp("motion", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_MOTION; + } else if (strcmp("near_far", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_NEAR_FAR; + } else if (strcmp("stationary", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_STATIONARY; + } else if (strcmp("threshold", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_THRESHOLD; + } else if (strcmp("fifo_wm", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_WATERMARK; + } else if (strcmp("fifo_full", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_FULL; + } else if (strcmp("tap", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TAP; + } else { + shell_error(shell_ptr, "Invalid trigger (%s)", argv[3]); + return -EINVAL; + } + + if (strcmp("incl", argv[4]) == 0) { + iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_INCLUDE; + } else if (strcmp("drop", argv[4]) == 0) { + iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_DROP; + } else if (strcmp("nop", argv[4]) == 0) { + iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_NOP; + } else { + shell_error(shell_ptr, "Unknown trigger op (%s)", argv[4]); + return -EINVAL; + } + + shell_print(shell_ptr, "Enabling stream..."); + iodev_sensor_shell_stream_config.sensor = dev; + + iodev_sensor_shell_stream_config.count = 1; + + ctx.dev = dev; + ctx.sh = shell_ptr; + + int rc = sensor_stream(&iodev_sensor_shell_stream, &sensor_read_rtio, &ctx, + ¤t_streaming_handle); + + if (rc != 0) { + shell_error(shell_ptr, "Failed to start stream"); + } + return rc; +} diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index bbc85fda86d..80fda1b1634 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -251,6 +251,12 @@ enum sensor_trigger_type { /** Trigger fires when no motion has been detected for a while. */ SENSOR_TRIG_STATIONARY, + + /** Trigger fires when the FIFO watermark has been reached. */ + SENSOR_TRIG_FIFO_WATERMARK, + + /** Trigger fires when the FIFO becomes full. */ + SENSOR_TRIG_FIFO_FULL, /** * Number of all common sensor triggers. */ @@ -328,6 +334,8 @@ enum sensor_attribute { * to the new sampling frequency. */ SENSOR_ATTR_FF_DUR, + /** Watermark % for the hardware fifo interrupt */ + SENSOR_ATTR_FIFO_WATERMARK, /** * Number of all common sensor attributes. */ @@ -466,6 +474,15 @@ struct sensor_decoder_api { */ int (*decode)(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx, uint32_t *fit, uint16_t max_count, void *data_out); + + /** + * @brief Check if the given trigger type is present + * + * @param[in] buffer The buffer provided on the @ref rtio context + * @param[in] trigger The trigger type in question + * @return Whether the trigger is present in the buffer + */ + bool (*has_trigger)(const uint8_t *buffer, enum sensor_trigger_type trigger); }; /** @@ -538,13 +555,38 @@ int sensor_natively_supported_channel_size_info(enum sensor_channel channel, siz typedef int (*sensor_get_decoder_t)(const struct device *dev, const struct sensor_decoder_api **api); +/** + * @brief Options for what to do with the associated data when a trigger is consumed + */ +enum sensor_stream_data_opt { + /** @brief Include whatever data is associated with the trigger */ + SENSOR_STREAM_DATA_INCLUDE = 0, + /** @brief Do nothing with the associated trigger data, it may be consumed later */ + SENSOR_STREAM_DATA_NOP = 1, + /** @brief Flush/clear whatever data is associated with the trigger */ + SENSOR_STREAM_DATA_DROP = 2, +}; + +struct sensor_stream_trigger { + enum sensor_trigger_type trigger; + enum sensor_stream_data_opt opt; +}; + +#define SENSOR_STREAM_TRIGGER_PREP(_trigger, _opt) \ + { \ + .trigger = (_trigger), .opt = (_opt), \ + } /* * Internal data structure used to store information about the IODevice for async reading and * streaming sensor data. */ struct sensor_read_config { const struct device *sensor; - enum sensor_channel *const channels; + const bool is_streaming; + union { + enum sensor_channel *const channels; + struct sensor_stream_trigger *const triggers; + }; size_t count; const size_t max; }; @@ -564,14 +606,45 @@ struct sensor_read_config { * @endcode */ #define SENSOR_DT_READ_IODEV(name, dt_node, ...) \ - static enum sensor_channel __channel_array_##name[] = {__VA_ARGS__}; \ - static struct sensor_read_config __sensor_read_config_##name = { \ + static enum sensor_channel _CONCAT(__channel_array_, name)[] = {__VA_ARGS__}; \ + static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = { \ .sensor = DEVICE_DT_GET(dt_node), \ - .channels = __channel_array_##name, \ - .count = ARRAY_SIZE(__channel_array_##name), \ - .max = ARRAY_SIZE(__channel_array_##name), \ + .is_streaming = false, \ + .channels = _CONCAT(__channel_array_, name), \ + .count = ARRAY_SIZE(_CONCAT(__channel_array_, name)), \ + .max = ARRAY_SIZE(_CONCAT(__channel_array_, name)), \ }; \ - RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, &__sensor_read_config_##name) + RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, _CONCAT(&__sensor_read_config_, name)) + +/** + * @brief Define a stream instance of a sensor + * + * Use this macro to generate a @ref rtio_iodev for starting a stream that's triggered by specific + * interrupts. Example: + * + * @code(.c) + * SENSOR_DT_STREAM_IODEV(imu_stream, DT_ALIAS(imu), + * {SENSOR_TRIG_FIFO_WATERMARK, SENSOR_STREAM_DATA_INCLUDE}, + * {SENSOR_TRIG_FIFO_FULL, SENSOR_STREAM_DATA_NOP}); + * + * int main(void) { + * struct rtio_sqe *handle; + * sensor_stream(&imu_stream, &rtio, NULL, &handle); + * k_msleep(1000); + * rtio_sqe_cancel(handle); + * } + * @endcode + */ +#define SENSOR_DT_STREAM_IODEV(name, dt_node, ...) \ + static struct sensor_stream_trigger _CONCAT(__trigger_array_, name)[] = {__VA_ARGS__}; \ + static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = { \ + .sensor = DEVICE_DT_GET(dt_node), \ + .is_streaming = true, \ + .triggers = _CONCAT(__trigger_array_, name), \ + .count = ARRAY_SIZE(_CONCAT(__trigger_array_, name)), \ + .max = ARRAY_SIZE(_CONCAT(__trigger_array_, name)), \ + }; \ + RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, &_CONCAT(__sensor_read_config_, name)) /* Used to submit an RTIO sqe to the sensor's iodev */ typedef int (*sensor_submit_t)(const struct device *sensor, struct rtio_iodev_sqe *sqe); @@ -880,7 +953,7 @@ static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, { struct sensor_read_config *cfg = (struct sensor_read_config *)iodev->data; - if (cfg->max < num_channels) { + if (cfg->max < num_channels || cfg->is_streaming) { return -ENOMEM; } @@ -888,6 +961,28 @@ static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, memcpy(cfg->channels, channels, num_channels * sizeof(enum sensor_channel)); cfg->count = num_channels; return 0; +} + +static inline int sensor_stream(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata, + struct rtio_sqe **handle) +{ + if (IS_ENABLED(CONFIG_USERSPACE)) { + struct rtio_sqe sqe; + + rtio_sqe_prep_read_multishot(&sqe, iodev, RTIO_PRIO_NORM, userdata); + rtio_sqe_copy_in_get_handles(ctx, &sqe, handle, 1); + } else { + struct rtio_sqe *sqe = rtio_sqe_acquire(ctx); + + if (sqe == NULL) { + return -ENOMEM; + } + if (handle != NULL) { + *handle = sqe; + } + rtio_sqe_prep_read_multishot(sqe, iodev, RTIO_PRIO_NORM, userdata); + } + rtio_submit(ctx, 0); return 0; } diff --git a/samples/sensor/sensor_shell/boards/tdk_robokit1.conf b/samples/sensor/sensor_shell/boards/tdk_robokit1.conf new file mode 100644 index 00000000000..aee20b8b100 --- /dev/null +++ b/samples/sensor/sensor_shell/boards/tdk_robokit1.conf @@ -0,0 +1,3 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 +CONFIG_SPI_RTIO=y diff --git a/samples/sensor/sensor_shell/sample.yaml b/samples/sensor/sensor_shell/sample.yaml index 7b194f4d622..d89dfebc21a 100644 --- a/samples/sensor/sensor_shell/sample.yaml +++ b/samples/sensor/sensor_shell/sample.yaml @@ -4,6 +4,8 @@ tests: sample.sensor.shell: integration_platforms: - frdm_k64f + # TODO Remove once #63414 is resolved + platform_exclude: gd32l233r_eval filter: ( CONFIG_UART_CONSOLE and CONFIG_SERIAL_SUPPORT_INTERRUPT ) tags: shell harness: keyboard From 1326c7c4543d56ee961a7ea07099c4b7df8936d1 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Wed, 5 Jul 2023 13:42:04 -0600 Subject: [PATCH 3421/4498] icm42688: Implement streaming APIs Add streaming implementation for icm42688 using both threshold and full FIFO triggers. Signed-off-by: Yuval Peress topic#sensor_stream --- drivers/sensor/icm42688/CMakeLists.txt | 1 + drivers/sensor/icm42688/Kconfig | 10 + drivers/sensor/icm42688/icm42688.c | 32 +- drivers/sensor/icm42688/icm42688.h | 12 + drivers/sensor/icm42688/icm42688_common.c | 9 +- drivers/sensor/icm42688/icm42688_decoder.c | 352 +++++++++++++++++- drivers/sensor/icm42688/icm42688_decoder.h | 9 + drivers/sensor/icm42688/icm42688_reg.h | 8 + drivers/sensor/icm42688/icm42688_rtio.c | 16 +- drivers/sensor/icm42688/icm42688_rtio.h | 7 + .../sensor/icm42688/icm42688_rtio_stream.c | 319 ++++++++++++++++ drivers/sensor/icm42688/icm42688_trigger.c | 24 +- drivers/sensor/icm42688/icm42688_trigger.h | 3 +- 13 files changed, 773 insertions(+), 29 deletions(-) create mode 100644 drivers/sensor/icm42688/icm42688_rtio_stream.c diff --git a/drivers/sensor/icm42688/CMakeLists.txt b/drivers/sensor/icm42688/CMakeLists.txt index cf9308bb95c..fbc63b6a4b2 100644 --- a/drivers/sensor/icm42688/CMakeLists.txt +++ b/drivers/sensor/icm42688/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API icm42688_rtio.c) zephyr_library_sources_ifdef(CONFIG_ICM42688_DECODER icm42688_decoder.c) +zephyr_library_sources_ifdef(CONFIG_ICM42688_STREAM icm42688_rtio_stream.c) zephyr_library_sources_ifdef(CONFIG_ICM42688_TRIGGER icm42688_trigger.c) zephyr_library_sources_ifdef(CONFIG_EMUL_ICM42688 icm42688_emul.c) zephyr_include_directories_ifdef(CONFIG_EMUL_ICM42688 .) diff --git a/drivers/sensor/icm42688/Kconfig b/drivers/sensor/icm42688/Kconfig index 2944a9d1183..d7ee43bc761 100644 --- a/drivers/sensor/icm42688/Kconfig +++ b/drivers/sensor/icm42688/Kconfig @@ -33,6 +33,7 @@ if ICM42688 choice prompt "Trigger mode" + default ICM42688_TRIGGER_NONE if ICM42688_STREAM default ICM42688_TRIGGER_GLOBAL_THREAD help Specify the type of triggering to be used by the driver @@ -50,6 +51,15 @@ config ICM42688_TRIGGER_OWN_THREAD endchoice +config ICM42688_STREAM + bool "Use hardware FIFO to stream data" + select ICM42688_TRIGGER + default y + depends on SPI_RTIO + depends on SENSOR_ASYNC_API + help + Use this config option to enable streaming sensor data via RTIO subsystem. + config ICM42688_TRIGGER bool diff --git a/drivers/sensor/icm42688/icm42688.c b/drivers/sensor/icm42688/icm42688.c index 43fd6a72f47..ee92c30987e 100644 --- a/drivers/sensor/icm42688/icm42688.c +++ b/drivers/sensor/icm42688/icm42688.c @@ -82,7 +82,7 @@ int icm42688_channel_parse_readings(enum sensor_channel chan, int16_t readings[7 } static int icm42688_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *val) + struct sensor_value *val) { struct icm42688_dev_data *data = dev->data; @@ -156,6 +156,19 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, res = -EINVAL; } break; + case SENSOR_CHAN_ALL: + if (attr == SENSOR_ATTR_FIFO_WATERMARK) { + int64_t mval = sensor_value_to_micro(val); + + if (mval < 0 || mval > 1000000) { + return -EINVAL; + } + new_config.fifo_wm = CLAMP(mval * 2048 / 1000000, 0, 2048); + } else { + LOG_ERR("Unsupported attribute"); + res = -EINVAL; + } + break; default: LOG_ERR("Unsupported channel"); res = -EINVAL; @@ -257,7 +270,13 @@ int icm42688_init(const struct device *dev) data->cfg.gyro_mode = ICM42688_GYRO_LN; data->cfg.gyro_fs = ICM42688_GYRO_FS_125; data->cfg.gyro_odr = ICM42688_GYRO_ODR_1000; - data->cfg.fifo_en = false; + data->cfg.temp_dis = false; + data->cfg.fifo_en = IS_ENABLED(CONFIG_ICM42688_STREAM); + data->cfg.fifo_wm = 0; + data->cfg.fifo_hires = 0; + data->cfg.interrupt1_drdy = 0; + data->cfg.interrupt1_fifo_ths = 0; + data->cfg.interrupt1_fifo_full = 0; res = icm42688_configure(dev, &data->cfg); if (res != 0) { @@ -283,8 +302,15 @@ void icm42688_unlock(const struct device *dev) #define ICM42688_SPI_CFG \ SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_TRANSFER_MSB +#define ICM42688_RTIO_DEFINE(inst) \ + SPI_DT_IODEV_DEFINE(icm42688_spi_iodev_##inst, DT_DRV_INST(inst), ICM42688_SPI_CFG, 0U); \ + RTIO_DEFINE(icm42688_rtio_##inst, 8, 4); + #define ICM42688_DEFINE_DATA(inst) \ - static struct icm42688_dev_data icm42688_driver_##inst; + IF_ENABLED(CONFIG_ICM42688_STREAM, (ICM42688_RTIO_DEFINE(inst))); \ + static struct icm42688_dev_data icm42688_driver_##inst = { \ + IF_ENABLED(CONFIG_ICM42688_STREAM, (.r = &icm42688_rtio_##inst, \ + .spi_iodev = &icm42688_spi_iodev_##inst,))}; #define ICM42688_INIT(inst) \ ICM42688_DEFINE_DATA(inst); \ diff --git a/drivers/sensor/icm42688/icm42688.h b/drivers/sensor/icm42688/icm42688.h index 18ae4606e72..c4167e6a3b9 100644 --- a/drivers/sensor/icm42688/icm42688.h +++ b/drivers/sensor/icm42688/icm42688.h @@ -385,6 +385,9 @@ struct icm42688_cfg { /* TODO additional FIFO options */ /* TODO interrupt options */ + bool interrupt1_drdy; + bool interrupt1_fifo_ths; + bool interrupt1_fifo_full; }; struct icm42688_trigger_entry { @@ -405,6 +408,15 @@ struct icm42688_dev_data { #elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) struct k_work work; #endif +#ifdef CONFIG_ICM42688_STREAM + struct rtio_iodev_sqe *streaming_sqe; + struct rtio *r; + struct rtio_iodev *spi_iodev; + uint8_t int_status; + uint16_t fifo_count; + uint64_t timestamp; + atomic_t reading_fifo; +#endif /* CONFIG_ICM42688_STREAM */ const struct device *dev; struct gpio_callback gpio_cb; sensor_trigger_handler_t data_ready_handler; diff --git a/drivers/sensor/icm42688/icm42688_common.c b/drivers/sensor/icm42688/icm42688_common.c index 3ccd107cfbb..9cb3037ed06 100644 --- a/drivers/sensor/icm42688/icm42688_common.c +++ b/drivers/sensor/icm42688/icm42688_common.c @@ -12,6 +12,7 @@ #include "icm42688.h" #include "icm42688_reg.h" #include "icm42688_spi.h" +#include "icm42688_trigger.h" #include LOG_MODULE_REGISTER(ICM42688_LL, CONFIG_SENSOR_LOG_LEVEL); @@ -165,8 +166,12 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) } /* Pulse mode with async reset (resets interrupt line on int status read) */ - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG, - BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY); + if (IS_ENABLED(CONFIG_ICM42688_TRIGGER)) { + res = icm42688_trigger_enable_interrupt(dev, cfg); + } else { + res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG, + BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY); + } if (res) { LOG_ERR("Error writing to INT_CONFIG"); return res; diff --git a/drivers/sensor/icm42688/icm42688_decoder.c b/drivers/sensor/icm42688/icm42688_decoder.c index 0a340aff369..3dc556ac61c 100644 --- a/drivers/sensor/icm42688/icm42688_decoder.c +++ b/drivers/sensor/icm42688/icm42688_decoder.c @@ -198,9 +198,262 @@ int icm42688_encode(const struct device *dev, const enum sensor_channel *const c return 0; } +#define IS_ACCEL(chan) ((chan) >= SENSOR_CHAN_ACCEL_X && (chan) <= SENSOR_CHAN_ACCEL_XYZ) +#define IS_GYRO(chan) ((chan) >= SENSOR_CHAN_GYRO_X && (chan) <= SENSOR_CHAN_GYRO_XYZ) + +static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt) +{ + int32_t temperature; + int32_t whole; + int32_t fraction; + + /* Temperature always assumes a shift of 9 for a range of (-273,273) C */ + if (FIELD_GET(FIFO_HEADER_20, pkt[0]) == 1) { + temperature = (pkt[0xd] << 8) | pkt[0xe]; + + icm42688_temp_c(temperature, &whole, &fraction); + } else { + if (FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1 && + FIELD_GET(FIFO_HEADER_GYRO, pkt[0]) == 1) { + temperature = pkt[0xd]; + } else { + temperature = pkt[0x7]; + } + + int64_t sensitivity = 207; + int64_t temperature100 = (temperature * 100) + (25 * sensitivity); + + whole = temperature100 / sensitivity; + fraction = + ((temperature100 - whole * sensitivity) * INT64_C(1000000)) / sensitivity; + } + __ASSERT_NO_MSG(whole >= -512 && whole <= 511); + return FIELD_PREP(GENMASK(31, 22), whole) | (fraction * GENMASK64(21, 0) / 1000000); +} + +static int icm42688_read_imu_from_packet(const uint8_t *pkt, bool is_accel, int fs, + uint8_t axis_offset, q31_t *out) +{ + int32_t value; + int64_t scale = 0; + int32_t max = BIT(15); + int offset = 1 + (axis_offset * 2); + + if (is_accel) { + switch (fs) { + case ICM42688_ACCEL_FS_2G: + scale = INT64_C(2) * BIT(31 - 5) * 9.80665; + break; + case ICM42688_ACCEL_FS_4G: + scale = INT64_C(4) * BIT(31 - 6) * 9.80665; + break; + case ICM42688_ACCEL_FS_8G: + scale = INT64_C(8) * BIT(31 - 7) * 9.80665; + break; + case ICM42688_ACCEL_FS_16G: + scale = INT64_C(16) * BIT(31 - 8) * 9.80665; + break; + } + } else { + switch (fs) { + case ICM42688_GYRO_FS_2000: + scale = 164; + break; + case ICM42688_GYRO_FS_1000: + scale = 328; + break; + case ICM42688_GYRO_FS_500: + scale = 655; + break; + case ICM42688_GYRO_FS_250: + scale = 1310; + break; + case ICM42688_GYRO_FS_125: + scale = 2620; + break; + case ICM42688_GYRO_FS_62_5: + scale = 5243; + break; + case ICM42688_GYRO_FS_31_25: + scale = 10486; + break; + case ICM42688_GYRO_FS_15_625: + scale = 20972; + break; + } + } + + if (!is_accel && FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1) { + offset += 7; + } + + value = (int16_t)sys_le16_to_cpu((pkt[offset] << 8) | pkt[offset + 1]); + + if (FIELD_GET(FIFO_HEADER_20, pkt[0]) == 1) { + uint32_t mask = is_accel ? GENMASK(7, 4) : GENMASK(3, 0); + + offset = 0x11 + axis_offset; + value = (value << 4) | FIELD_GET(mask, pkt[offset]); + /* In 20 bit mode, FS can only be +/-16g and +/-2000dps */ + scale = is_accel ? (INT64_C(16) * BIT(8) * 9.80665) : 131; + max = is_accel ? BIT(18) : BIT(19); + if (value == -524288) { + /* Invalid 20 bit value */ + return -ENODATA; + } + } else { + if (value <= -32767) { + /* Invalid 16 bit value */ + return -ENODATA; + } + } + + *out = (q31_t)(value * scale / max); + return 0; +} + +static uint32_t accel_period_ns[] = { + [ICM42688_ACCEL_ODR_1_5625] = UINT32_C(10000000000000) / 15625, + [ICM42688_ACCEL_ODR_3_125] = UINT32_C(10000000000000) / 31250, + [ICM42688_ACCEL_ODR_6_25] = UINT32_C(10000000000000) / 62500, + [ICM42688_ACCEL_ODR_12_5] = UINT32_C(10000000000000) / 12500, + [ICM42688_ACCEL_ODR_25] = UINT32_C(1000000000) / 25, + [ICM42688_ACCEL_ODR_50] = UINT32_C(1000000000) / 50, + [ICM42688_ACCEL_ODR_100] = UINT32_C(1000000000) / 100, + [ICM42688_ACCEL_ODR_200] = UINT32_C(1000000000) / 200, + [ICM42688_ACCEL_ODR_500] = UINT32_C(1000000000) / 500, + [ICM42688_ACCEL_ODR_1000] = UINT32_C(1000000), + [ICM42688_ACCEL_ODR_2000] = UINT32_C(1000000) / 2, + [ICM42688_ACCEL_ODR_4000] = UINT32_C(1000000) / 4, + [ICM42688_ACCEL_ODR_8000] = UINT32_C(1000000) / 8, + [ICM42688_ACCEL_ODR_16000] = UINT32_C(1000000) / 16, + [ICM42688_ACCEL_ODR_32000] = UINT32_C(1000000) / 32, +}; + +static uint32_t gyro_period_ns[] = { + [ICM42688_GYRO_ODR_12_5] = UINT32_C(10000000000000) / 12500, + [ICM42688_GYRO_ODR_25] = UINT32_C(1000000000) / 25, + [ICM42688_GYRO_ODR_50] = UINT32_C(1000000000) / 50, + [ICM42688_GYRO_ODR_100] = UINT32_C(1000000000) / 100, + [ICM42688_GYRO_ODR_200] = UINT32_C(1000000000) / 200, + [ICM42688_GYRO_ODR_500] = UINT32_C(1000000000) / 500, + [ICM42688_GYRO_ODR_1000] = UINT32_C(1000000), + [ICM42688_GYRO_ODR_2000] = UINT32_C(1000000) / 2, + [ICM42688_GYRO_ODR_4000] = UINT32_C(1000000) / 4, + [ICM42688_GYRO_ODR_8000] = UINT32_C(1000000) / 8, + [ICM42688_GYRO_ODR_16000] = UINT32_C(1000000) / 16, + [ICM42688_GYRO_ODR_32000] = UINT32_C(1000000) / 32, +}; + +static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel channel, + size_t channel_idx, uint32_t *fit, uint16_t max_count, + void *data_out) +{ + const struct icm42688_fifo_data *edata = (const struct icm42688_fifo_data *)buffer; + const uint8_t *buffer_end = buffer + sizeof(struct icm42688_fifo_data) + edata->fifo_count; + int accel_frame_count = 0; + int gyro_frame_count = 0; + int count = 0; + int rc; + + if ((uintptr_t)buffer_end <= *fit || channel_idx != 0) { + return 0; + } + + ((struct sensor_data_header *)data_out)->base_timestamp_ns = edata->header.timestamp; + + buffer += sizeof(struct icm42688_fifo_data); + while (count < max_count && buffer < buffer_end) { + const bool is_20b = FIELD_GET(FIFO_HEADER_20, buffer[0]) == 1; + const bool has_accel = FIELD_GET(FIFO_HEADER_ACCEL, buffer[0]) == 1; + const bool has_gyro = FIELD_GET(FIFO_HEADER_GYRO, buffer[0]) == 1; + const uint8_t *frame_end = buffer; + + if (is_20b) { + frame_end += 20; + } else if (has_accel && has_gyro) { + frame_end += 16; + } else { + frame_end += 8; + } + if (has_accel) { + accel_frame_count++; + } + if (has_gyro) { + gyro_frame_count++; + } + + if ((uintptr_t)buffer < *fit) { + /* This frame was already decoded, move on to the next frame */ + buffer = frame_end; + continue; + } + if (channel == SENSOR_CHAN_DIE_TEMP) { + struct sensor_q31_data *data = (struct sensor_q31_data *)data_out; + + data->shift = 9; + if (has_accel) { + data->readings[count].timestamp_delta = + accel_period_ns[edata->accel_odr] * (accel_frame_count - 1); + } else { + data->readings[count].timestamp_delta = + gyro_period_ns[edata->gyro_odr] * (gyro_frame_count - 1); + } + data->readings[count].temperature = + icm42688_read_temperature_from_packet(buffer); + } else if (IS_ACCEL(channel) && has_accel) { + /* Decode accel */ + struct sensor_three_axis_data *data = + (struct sensor_three_axis_data *)data_out; + uint64_t period_ns = accel_period_ns[edata->accel_odr]; + + icm42688_get_shift(SENSOR_CHAN_ACCEL_XYZ, edata->header.accel_fs, + edata->header.gyro_fs, &data->shift); + + data->readings[count].timestamp_delta = (accel_frame_count - 1) * period_ns; + rc = icm42688_read_imu_from_packet(buffer, true, edata->header.accel_fs, 0, + &data->readings[count].x); + rc |= icm42688_read_imu_from_packet(buffer, true, edata->header.accel_fs, 1, + &data->readings[count].y); + rc |= icm42688_read_imu_from_packet(buffer, true, edata->header.accel_fs, 2, + &data->readings[count].z); + if (rc != 0) { + accel_frame_count--; + buffer = frame_end; + continue; + } + } else if (IS_GYRO(channel) && has_gyro) { + /* Decode gyro */ + struct sensor_three_axis_data *data = + (struct sensor_three_axis_data *)data_out; + uint64_t period_ns = accel_period_ns[edata->gyro_odr]; + + icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, edata->header.accel_fs, + edata->header.gyro_fs, &data->shift); + + data->readings[count].timestamp_delta = (gyro_frame_count - 1) * period_ns; + rc = icm42688_read_imu_from_packet(buffer, false, edata->header.gyro_fs, 0, + &data->readings[count].x); + rc |= icm42688_read_imu_from_packet(buffer, false, edata->header.gyro_fs, 1, + &data->readings[count].y); + rc |= icm42688_read_imu_from_packet(buffer, false, edata->header.gyro_fs, 2, + &data->readings[count].z); + if (rc != 0) { + gyro_frame_count--; + buffer = frame_end; + continue; + } + } + buffer = frame_end; + *fit = (uintptr_t)frame_end; + count++; + } + return count; +} + static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel channel, - size_t channel_idx, uint32_t *fit, - uint16_t max_count, void *data_out) + size_t channel_idx, uint32_t *fit, uint16_t max_count, + void *data_out) { const struct icm42688_encoded_data *edata = (const struct icm42688_encoded_data *)buffer; const struct icm42688_decoder_header *header = &edata->header; @@ -318,34 +571,76 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel c } static int icm42688_decoder_decode(const uint8_t *buffer, enum sensor_channel channel, - size_t channel_idx, uint32_t *fit, - uint16_t max_count, void *data_out) + size_t channel_idx, uint32_t *fit, uint16_t max_count, + void *data_out) { + const struct icm42688_decoder_header *header = + (const struct icm42688_decoder_header *)buffer; + + if (header->is_fifo) { + return icm42688_fifo_decode(buffer, channel, channel_idx, fit, max_count, data_out); + } return icm42688_one_shot_decode(buffer, channel, channel_idx, fit, max_count, data_out); } static int icm42688_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx, uint16_t *frame_count) { - ARG_UNUSED(buffer); + const struct icm42688_fifo_data *data = (const struct icm42688_fifo_data *)buffer; + const struct icm42688_decoder_header *header = &data->header; + if (channel_idx != 0) { return -ENOTSUP; } - switch (channel) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_ACCEL_XYZ: - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: - case SENSOR_CHAN_GYRO_XYZ: - case SENSOR_CHAN_DIE_TEMP: - *frame_count = 1; + + if (!header->is_fifo) { + switch (channel) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_DIE_TEMP: + *frame_count = 1; + return 0; + default: + return -ENOTSUP; + } return 0; - default: - return -ENOTSUP; } + + /* Skip the header */ + buffer += sizeof(struct icm42688_fifo_data); + + uint16_t count = 0; + const uint8_t *end = buffer + data->fifo_count; + + while (buffer < end) { + bool is_20b = FIELD_GET(FIFO_HEADER_20, buffer[0]); + int size = is_20b ? 3 : 2; + + if (FIELD_GET(FIFO_HEADER_ACCEL, buffer[0])) { + size += 6; + } + if (FIELD_GET(FIFO_HEADER_GYRO, buffer[0])) { + size += 6; + } + if (FIELD_GET(FIFO_HEADER_TIMESTAMP_FSYNC, buffer[0])) { + size += 2; + } + if (is_20b) { + size += 3; + } + + buffer += size; + ++count; + } + + *frame_count = count; + return 0; } static int icm42688_decoder_get_size_info(enum sensor_channel channel, size_t *base_size, @@ -372,10 +667,31 @@ static int icm42688_decoder_get_size_info(enum sensor_channel channel, size_t *b } } +static bool icm24688_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) +{ + const struct icm42688_fifo_data *edata = (const struct icm42688_fifo_data *)buffer; + + if (!edata->header.is_fifo) { + return false; + } + + switch (trigger) { + case SENSOR_TRIG_DATA_READY: + return FIELD_GET(BIT_INT_STATUS_DATA_RDY, edata->int_status); + case SENSOR_TRIG_FIFO_WATERMARK: + return FIELD_GET(BIT_INT_STATUS_FIFO_THS, edata->int_status); + case SENSOR_TRIG_FIFO_FULL: + return FIELD_GET(BIT_INT_STATUS_FIFO_FULL, edata->int_status); + default: + return false; + } +} + SENSOR_DECODER_API_DT_DEFINE() = { .get_frame_count = icm42688_decoder_get_frame_count, .get_size_info = icm42688_decoder_get_size_info, .decode = icm42688_decoder_decode, + .has_trigger = icm24688_decoder_has_trigger, }; int icm42688_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) diff --git a/drivers/sensor/icm42688/icm42688_decoder.h b/drivers/sensor/icm42688/icm42688_decoder.h index 2ef806373c9..499cf3d0801 100644 --- a/drivers/sensor/icm42688/icm42688_decoder.h +++ b/drivers/sensor/icm42688/icm42688_decoder.h @@ -18,6 +18,15 @@ struct icm42688_decoder_header { uint8_t reserved: 2; } __attribute__((__packed__)); +struct icm42688_fifo_data { + struct icm42688_decoder_header header; + uint8_t int_status; + uint16_t gyro_odr: 4; + uint16_t accel_odr: 4; + uint16_t fifo_count: 11; + uint16_t reserved: 5; +} __attribute__((__packed__)); + struct icm42688_encoded_data { struct icm42688_decoder_header header; struct { diff --git a/drivers/sensor/icm42688/icm42688_reg.h b/drivers/sensor/icm42688/icm42688_reg.h index dfc348c072c..5f3b58f0b3c 100644 --- a/drivers/sensor/icm42688/icm42688_reg.h +++ b/drivers/sensor/icm42688/icm42688_reg.h @@ -286,4 +286,12 @@ #define MCLK_POLL_ATTEMPTS 100 #define SOFT_RESET_TIME_MS 2 /* 1ms + elbow room */ +/* FIFO header */ +#define FIFO_HEADER_ACCEL BIT(6) +#define FIFO_HEADER_GYRO BIT(5) +#define FIFO_HEADER_20 BIT(4) +#define FIFO_HEADER_TIMESTAMP_FSYNC GENMASK(3, 2) +#define FIFO_HEADER_ODR_ACCEL BIT(1) +#define FIFO_HEADER_ODR_GYRO BIT(0) + #endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_REG_H_ */ diff --git a/drivers/sensor/icm42688/icm42688_rtio.c b/drivers/sensor/icm42688/icm42688_rtio.c index c1b20689393..ccb9532ee45 100644 --- a/drivers/sensor/icm42688/icm42688_rtio.c +++ b/drivers/sensor/icm42688/icm42688_rtio.c @@ -8,6 +8,7 @@ #include "icm42688.h" #include "icm42688_decoder.h" #include "icm42688_reg.h" +#include "icm42688_rtio.h" #include "icm42688_spi.h" #include @@ -42,7 +43,7 @@ static int icm42688_rtio_sample_fetch(const struct device *dev, int16_t readings return 0; } -int icm42688_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +static int icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; const enum sensor_channel *const channels = cfg->channels; @@ -78,4 +79,17 @@ int icm42688_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) return 0; } +int icm42688_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + + if (!cfg->is_streaming) { + return icm42688_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_ICM42688_STREAM)) { + return icm42688_submit_stream(dev, iodev_sqe); + } else { + return -ENOTSUP; + } +} + BUILD_ASSERT(sizeof(struct icm42688_decoder_header) == 9); diff --git a/drivers/sensor/icm42688/icm42688_rtio.h b/drivers/sensor/icm42688/icm42688_rtio.h index 748c8a022b0..888e8e95357 100644 --- a/drivers/sensor/icm42688/icm42688_rtio.h +++ b/drivers/sensor/icm42688/icm42688_rtio.h @@ -7,6 +7,13 @@ #ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ #define ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ +#include +#include + int icm42688_submit(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); +int icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); + +void icm42688_fifo_event(const struct device *dev); + #endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ */ diff --git a/drivers/sensor/icm42688/icm42688_rtio_stream.c b/drivers/sensor/icm42688/icm42688_rtio_stream.c new file mode 100644 index 00000000000..57d1a66cfde --- /dev/null +++ b/drivers/sensor/icm42688/icm42688_rtio_stream.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "icm42688.h" +#include "icm42688_decoder.h" +#include "icm42688_reg.h" +#include "icm42688_rtio.h" + +LOG_MODULE_DECLARE(ICM42688_RTIO); + +int icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + struct icm42688_dev_data *data = sensor->data; + struct icm42688_cfg new_config = data->cfg; + + new_config.interrupt1_drdy = false; + new_config.interrupt1_fifo_ths = false; + new_config.interrupt1_fifo_full = false; + for (int i = 0; i < cfg->count; ++i) { + switch (cfg->triggers[i].trigger) { + case SENSOR_TRIG_DATA_READY: + new_config.interrupt1_drdy = true; + break; + case SENSOR_TRIG_FIFO_WATERMARK: + new_config.interrupt1_fifo_ths = true; + break; + case SENSOR_TRIG_FIFO_FULL: + new_config.interrupt1_fifo_full = true; + break; + default: + LOG_DBG("Trigger (%d) not supported", cfg->triggers[i].trigger); + break; + } + } + + if (new_config.interrupt1_drdy != data->cfg.interrupt1_drdy || + new_config.interrupt1_fifo_ths != data->cfg.interrupt1_fifo_ths || + new_config.interrupt1_fifo_full != data->cfg.interrupt1_fifo_full) { + int rc = icm42688_safely_configure(sensor, &new_config); + + if (rc != 0) { + LOG_ERR("Failed to configure sensor"); + return rc; + } + } + + data->streaming_sqe = iodev_sqe; + return 0; +} + +static void icm42688_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +{ + const struct device *dev = arg; + struct icm42688_dev_data *drv_data = dev->data; + const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct rtio_iodev_sqe *iodev_sqe = sqe->userdata; + + rtio_iodev_sqe_ok(iodev_sqe, drv_data->fifo_count); + + gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); +} + +static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +{ + const struct device *dev = arg; + struct icm42688_dev_data *drv_data = dev->data; + const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct rtio_iodev *spi_iodev = drv_data->spi_iodev; + uint8_t *fifo_count_buf = (uint8_t *)&drv_data->fifo_count; + uint16_t fifo_count = ((fifo_count_buf[0] << 8) | fifo_count_buf[1]); + + drv_data->fifo_count = fifo_count; + + /* Pull a operation from our device iodev queue, validated to only be reads */ + struct rtio_iodev_sqe *iodev_sqe = drv_data->streaming_sqe; + + drv_data->streaming_sqe = NULL; + + /* Not inherently an underrun/overrun as we may have a buffer to fill next time */ + if (iodev_sqe == NULL) { + LOG_DBG("No pending SQE"); + gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + return; + } + + const size_t packet_size = drv_data->cfg.fifo_hires ? 20 : 16; + const size_t min_read_size = sizeof(struct icm42688_fifo_data) + packet_size; + const size_t ideal_read_size = sizeof(struct icm42688_fifo_data) + fifo_count; + uint8_t *buf; + uint32_t buf_len; + + if (rtio_sqe_rx_buf(iodev_sqe, min_read_size, ideal_read_size, &buf, &buf_len) != 0) { + LOG_ERR("Failed to get buffer"); + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + return; + } + LOG_DBG("Requesting buffer [%u, %u] got %u", (unsigned int)min_read_size, + (unsigned int)ideal_read_size, buf_len); + + /* Read FIFO and call back to rtio with rtio_sqe completion */ + /* TODO is packet format even needed? the fifo has a header per packet + * already + */ + struct icm42688_fifo_data hdr = { + .header = { + .is_fifo = true, + .gyro_fs = drv_data->cfg.gyro_fs, + .accel_fs = drv_data->cfg.accel_fs, + .timestamp = drv_data->timestamp, + }, + .int_status = drv_data->int_status, + .gyro_odr = drv_data->cfg.gyro_odr, + .accel_odr = drv_data->cfg.accel_odr, + }; + uint32_t buf_avail = buf_len; + + memcpy(buf, &hdr, sizeof(hdr)); + buf_avail -= sizeof(hdr); + + uint32_t read_len = MIN(fifo_count, buf_avail); + uint32_t pkts = read_len / packet_size; + + read_len = pkts * packet_size; + ((struct icm42688_fifo_data *)buf)->fifo_count = read_len; + + __ASSERT_NO_MSG(read_len % pkt_size == 0); + + uint8_t *read_buf = buf + sizeof(hdr); + + /* Flush out completions */ + struct rtio_cqe *cqe; + + do { + cqe = rtio_cqe_consume(r); + if (cqe != NULL) { + rtio_cqe_release(r, cqe); + } + } while (cqe != NULL); + + /* Setup new rtio chain to read the fifo data and report then check the + * result + */ + struct rtio_sqe *write_fifo_addr = rtio_sqe_acquire(r); + struct rtio_sqe *read_fifo_data = rtio_sqe_acquire(r); + struct rtio_sqe *complete_op = rtio_sqe_acquire(r); + const uint8_t reg_addr = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_FIFO_DATA); + + rtio_sqe_prep_tiny_write(write_fifo_addr, spi_iodev, RTIO_PRIO_NORM, ®_addr, 1, NULL); + write_fifo_addr->flags = RTIO_SQE_TRANSACTION; + rtio_sqe_prep_read(read_fifo_data, spi_iodev, RTIO_PRIO_NORM, read_buf, read_len, + iodev_sqe); + + rtio_sqe_prep_callback(complete_op, icm42688_complete_cb, (void *)dev, iodev_sqe); + + rtio_submit(r, 0); +} + +static struct sensor_stream_trigger * +icm42688_get_read_config_trigger(const struct sensor_read_config *cfg, + enum sensor_trigger_type trig) +{ + for (int i = 0; i < cfg->count; ++i) { + if (cfg->triggers[i].trigger == trig) { + return &cfg->triggers[i]; + } + } + LOG_DBG("Unsupported trigger (%d)", trig); + return NULL; +} + +static void icm42688_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, void *arg) +{ + const struct device *dev = arg; + struct icm42688_dev_data *drv_data = dev->data; + const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct rtio_iodev *spi_iodev = drv_data->spi_iodev; + struct rtio_iodev_sqe *streaming_sqe = drv_data->streaming_sqe; + struct sensor_read_config *read_config; + + if (streaming_sqe == NULL) { + return; + } + + read_config = (struct sensor_read_config *)streaming_sqe->sqe.iodev->data; + __ASSERT_NO_MSG(read_config != NULL); + + if (!read_config->is_streaming) { + /* Oops, not really configured for streaming data */ + return; + } + + struct sensor_stream_trigger *fifo_ths_cfg = + icm42688_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_WATERMARK); + bool has_fifo_ths_trig = fifo_ths_cfg != NULL && + FIELD_GET(BIT_INT_STATUS_FIFO_THS, drv_data->int_status) != 0; + + struct sensor_stream_trigger *fifo_full_cfg = + icm42688_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_FULL); + bool has_fifo_full_trig = fifo_full_cfg != NULL && + FIELD_GET(BIT_INT_STATUS_FIFO_FULL, drv_data->int_status) != 0; + + if (!has_fifo_ths_trig && !has_fifo_full_trig) { + gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + return; + } + + /* Flush completions */ + struct rtio_cqe *cqe; + + do { + cqe = rtio_cqe_consume(r); + if (cqe != NULL) { + rtio_cqe_release(r, cqe); + } + } while (cqe != NULL); + + enum sensor_stream_data_opt data_opt; + + if (has_fifo_ths_trig && !has_fifo_full_trig) { + /* Only care about fifo threshold */ + data_opt = fifo_ths_cfg->opt; + } else if (!has_fifo_ths_trig && has_fifo_full_trig) { + /* Only care about fifo full */ + data_opt = fifo_full_cfg->opt; + } else { + /* Both fifo threshold and full */ + data_opt = MIN(fifo_ths_cfg->opt, fifo_full_cfg->opt); + } + + if (data_opt == SENSOR_STREAM_DATA_NOP || data_opt == SENSOR_STREAM_DATA_DROP) { + uint8_t *buf; + uint32_t buf_len; + + /* Clear streaming_sqe since we're done with the call */ + drv_data->streaming_sqe = NULL; + if (rtio_sqe_rx_buf(streaming_sqe, sizeof(struct icm42688_fifo_data), + sizeof(struct icm42688_fifo_data), &buf, &buf_len) != 0) { + rtio_iodev_sqe_err(streaming_sqe, -ENOMEM); + return; + } + + struct icm42688_fifo_data *data = (struct icm42688_fifo_data *)buf; + + memset(buf, 0, buf_len); + data->header.timestamp = drv_data->timestamp; + data->int_status = drv_data->int_status; + data->fifo_count = 0; + rtio_iodev_sqe_ok(streaming_sqe, 0); + gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + if (data_opt == SENSOR_STREAM_DATA_DROP) { + /* Flush the FIFO */ + struct rtio_sqe *write_signal_path_reset = rtio_sqe_acquire(r); + uint8_t write_buffer[] = { + FIELD_GET(REG_ADDRESS_MASK, REG_SIGNAL_PATH_RESET), + BIT_FIFO_FLUSH, + }; + + rtio_sqe_prep_tiny_write(write_signal_path_reset, spi_iodev, RTIO_PRIO_NORM, + write_buffer, ARRAY_SIZE(write_buffer), NULL); + /* TODO Add a new flag for fire-and-forget so we don't have to block here */ + rtio_submit(r, 1); + ARG_UNUSED(rtio_cqe_consume(r)); + } + return; + } + + /* We need the data, read the fifo length */ + struct rtio_sqe *write_fifo_count_reg = rtio_sqe_acquire(r); + struct rtio_sqe *read_fifo_count = rtio_sqe_acquire(r); + struct rtio_sqe *check_fifo_count = rtio_sqe_acquire(r); + uint8_t reg = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_FIFO_COUNTH); + uint8_t *read_buf = (uint8_t *)&drv_data->fifo_count; + + rtio_sqe_prep_tiny_write(write_fifo_count_reg, spi_iodev, RTIO_PRIO_NORM, ®, 1, NULL); + write_fifo_count_reg->flags = RTIO_SQE_TRANSACTION; + rtio_sqe_prep_read(read_fifo_count, spi_iodev, RTIO_PRIO_NORM, read_buf, 2, NULL); + rtio_sqe_prep_callback(check_fifo_count, icm42688_fifo_count_cb, arg, NULL); + + rtio_submit(r, 0); +} + +void icm42688_fifo_event(const struct device *dev) +{ + struct icm42688_dev_data *drv_data = dev->data; + struct rtio_iodev *spi_iodev = drv_data->spi_iodev; + struct rtio *r = drv_data->r; + + if (drv_data->streaming_sqe == NULL) { + return; + } + + drv_data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + + /* + * Setup rtio chain of ops with inline calls to make decisions + * 1. read int status + * 2. call to check int status and get pending RX operation + * 4. read fifo len + * 5. call to determine read len + * 6. read fifo + * 7. call to report completion + */ + struct rtio_sqe *write_int_reg = rtio_sqe_acquire(r); + struct rtio_sqe *read_int_reg = rtio_sqe_acquire(r); + struct rtio_sqe *check_int_status = rtio_sqe_acquire(r); + uint8_t reg = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_INT_STATUS); + + rtio_sqe_prep_tiny_write(write_int_reg, spi_iodev, RTIO_PRIO_NORM, ®, 1, NULL); + write_int_reg->flags = RTIO_SQE_TRANSACTION; + rtio_sqe_prep_read(read_int_reg, spi_iodev, RTIO_PRIO_NORM, &drv_data->int_status, 1, NULL); + rtio_sqe_prep_callback(check_int_status, icm42688_int_status_cb, (void *)dev, NULL); + rtio_submit(r, 0); +} diff --git a/drivers/sensor/icm42688/icm42688_trigger.c b/drivers/sensor/icm42688/icm42688_trigger.c index adaecf84baa..32b60f3cd75 100644 --- a/drivers/sensor/icm42688/icm42688_trigger.c +++ b/drivers/sensor/icm42688/icm42688_trigger.c @@ -12,6 +12,7 @@ #include "icm42688.h" #include "icm42688_reg.h" +#include "icm42688_rtio.h" #include "icm42688_spi.h" #include "icm42688_trigger.h" @@ -30,6 +31,9 @@ static void icm42688_gpio_callback(const struct device *dev, struct gpio_callbac #elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) k_work_submit(&data->work); #endif + if (IS_ENABLED(CONFIG_ICM42688_STREAM)) { + icm42688_fifo_event(data->dev); + } } #if defined(CONFIG_ICM42688_TRIGGER_OWN_THREAD) || defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) @@ -90,6 +94,8 @@ int icm42688_trigger_set(const struct device *dev, const struct sensor_trigger * switch (trig->type) { case SENSOR_TRIG_DATA_READY: + case SENSOR_TRIG_FIFO_WATERMARK: + case SENSOR_TRIG_FIFO_FULL: data->data_ready_handler = handler; data->data_ready_trigger = trig; @@ -146,7 +152,7 @@ int icm42688_trigger_init(const struct device *dev) return gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); } -int icm42688_trigger_enable_interrupt(const struct device *dev) +int icm42688_trigger_enable_interrupt(const struct device *dev, struct icm42688_cfg *new_cfg) { int res; const struct icm42688_dev_cfg *cfg = dev->config; @@ -164,9 +170,19 @@ int icm42688_trigger_enable_interrupt(const struct device *dev) return res; } - /* enable data ready interrupt on INT1 pin */ - return icm42688_spi_single_write(&cfg->spi, REG_INT_SOURCE0, - FIELD_PREP(BIT_UI_DRDY_INT1_EN, 1)); + /* enable interrupts on INT1 pin */ + uint8_t value = 0; + + if (new_cfg->interrupt1_drdy) { + value |= FIELD_PREP(BIT_UI_DRDY_INT1_EN, 1); + } + if (new_cfg->interrupt1_fifo_ths) { + value |= FIELD_PREP(BIT_FIFO_THS_INT1_EN, 1); + } + if (new_cfg->interrupt1_fifo_full) { + value |= FIELD_PREP(BIT_FIFO_FULL_INT1_EN, 1); + } + return icm42688_spi_single_write(&cfg->spi, REG_INT_SOURCE0, value); } void icm42688_lock(const struct device *dev) diff --git a/drivers/sensor/icm42688/icm42688_trigger.h b/drivers/sensor/icm42688/icm42688_trigger.h index 5ed382eb0d4..e0397591618 100644 --- a/drivers/sensor/icm42688/icm42688_trigger.h +++ b/drivers/sensor/icm42688/icm42688_trigger.h @@ -26,9 +26,10 @@ int icm42688_trigger_init(const struct device *dev); * @brief enable the trigger gpio interrupt * * @param dev icm42688 device pointer + * @param new_cfg New configuration to use for the device * @return int 0 on success, negative error code otherwise */ -int icm42688_trigger_enable_interrupt(const struct device *dev); +int icm42688_trigger_enable_interrupt(const struct device *dev, struct icm42688_cfg *new_cfg); /** * @brief lock access to the icm42688 device driver From 3c6e66e5b576d774a0357dc2af61d6c4eb4f3307 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Tue, 10 Oct 2023 01:59:04 -0600 Subject: [PATCH 3422/4498] sensors: convert fifo_wm to batch_dur Having a % FIFO watermark isn't very useful as it doesn't convey how long the SoC can sleep (or do other work) while batching sensor data. Convert the attribute to a batch duration using ticks. Currently the ticks are in system ticks, but eventually when an external clock is attached to the sensor it will be in the external clock's ticks. Signed-off-by: Yuval Peress --- drivers/sensor/icm42688/icm42688.c | 19 ++++--- drivers/sensor/icm42688/icm42688.h | 2 +- drivers/sensor/icm42688/icm42688_common.c | 61 ++++++++++++++++++++++- drivers/sensor/sensor_shell.c | 2 +- include/zephyr/drivers/sensor.h | 6 ++- 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/drivers/sensor/icm42688/icm42688.c b/drivers/sensor/icm42688/icm42688.c index ee92c30987e..a6b4cd06c52 100644 --- a/drivers/sensor/icm42688/icm42688.c +++ b/drivers/sensor/icm42688/icm42688.c @@ -157,13 +157,11 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, } break; case SENSOR_CHAN_ALL: - if (attr == SENSOR_ATTR_FIFO_WATERMARK) { - int64_t mval = sensor_value_to_micro(val); - - if (mval < 0 || mval > 1000000) { + if (attr == SENSOR_ATTR_BATCH_DURATION) { + if (val->val1 < 0) { return -EINVAL; } - new_config.fifo_wm = CLAMP(mval * 2048 / 1000000, 0, 2048); + new_config.batch_ticks = val->val1; } else { LOG_ERR("Unsupported attribute"); res = -EINVAL; @@ -217,6 +215,15 @@ static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, res = -EINVAL; } break; + case SENSOR_CHAN_ALL: + if (attr == SENSOR_ATTR_BATCH_DURATION) { + val->val1 = cfg->batch_ticks; + val->val2 = 0; + } else { + LOG_ERR("Unsupported attribute"); + res = -EINVAL; + } + break; default: LOG_ERR("Unsupported channel"); res = -EINVAL; @@ -272,7 +279,7 @@ int icm42688_init(const struct device *dev) data->cfg.gyro_odr = ICM42688_GYRO_ODR_1000; data->cfg.temp_dis = false; data->cfg.fifo_en = IS_ENABLED(CONFIG_ICM42688_STREAM); - data->cfg.fifo_wm = 0; + data->cfg.batch_ticks = 0; data->cfg.fifo_hires = 0; data->cfg.interrupt1_drdy = 0; data->cfg.interrupt1_fifo_ths = 0; diff --git a/drivers/sensor/icm42688/icm42688.h b/drivers/sensor/icm42688/icm42688.h index c4167e6a3b9..5ec470cff27 100644 --- a/drivers/sensor/icm42688/icm42688.h +++ b/drivers/sensor/icm42688/icm42688.h @@ -380,7 +380,7 @@ struct icm42688_cfg { /* TODO timestamp options */ bool fifo_en; - uint16_t fifo_wm; + int32_t batch_ticks; bool fifo_hires; /* TODO additional FIFO options */ diff --git a/drivers/sensor/icm42688/icm42688_common.c b/drivers/sensor/icm42688/icm42688_common.c index 9cb3037ed06..4df2f787092 100644 --- a/drivers/sensor/icm42688/icm42688_common.c +++ b/drivers/sensor/icm42688/icm42688_common.c @@ -62,6 +62,62 @@ int icm42688_reset(const struct device *dev) return 0; } +static uint16_t icm42688_compute_fifo_wm(const struct icm42688_cfg *cfg) +{ + const bool accel_enabled = cfg->accel_mode != ICM42688_ACCEL_OFF; + const bool gyro_enabled = cfg->gyro_mode != ICM42688_GYRO_OFF; + const int pkt_size = cfg->fifo_hires ? 20 : (accel_enabled && gyro_enabled ? 16 : 8); + int accel_modr = 0; + int gyro_modr = 0; + int64_t modr; + + if (cfg->batch_ticks == 0 || (!accel_enabled && !gyro_enabled)) { + return 0; + } + + if (accel_enabled) { + struct sensor_value val = {0}; + + icm42688_accel_reg_to_hz(cfg->accel_odr, &val); + accel_modr = sensor_value_to_micro(&val) / 1000; + } + if (gyro_enabled) { + struct sensor_value val = {0}; + + icm42688_gyro_reg_to_odr(cfg->gyro_odr, &val); + gyro_modr = sensor_value_to_micro(&val) / 1000; + } + + if (accel_modr == 0) { + modr = gyro_modr; + } else if (gyro_modr == 0) { + modr = accel_modr; + } else { + /* Need to find the least common multiplier (LCM) */ + int n1 = accel_modr; + int n2 = gyro_modr; + + while (n1 != n2) { + if (n1 > n2) { + n1 -= n2; + } else { + n2 -= n1; + } + } + LOG_DBG("GCD=%d", n1); + modr = ((int64_t)accel_modr * (int64_t)gyro_modr) / n1; + } + /* At this point we have 'modr' as mHz which is 1 / msec. */ + + /* Convert 'modr' to bytes * batch_ticks / msec */ + modr *= (int64_t)cfg->batch_ticks * pkt_size; + + /* 'modr' = byte_ticks_per_msec / kticks_per_sec */ + modr = DIV_ROUND_UP(modr, CONFIG_SYS_CLOCK_TICKS_PER_SEC * INT64_C(1000)); + + return (uint16_t)MIN(modr, 0x7ff); +} + int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) { struct icm42688_dev_data *dev_data = dev->data; @@ -210,7 +266,8 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) } /* Set watermark and interrupt handling first */ - uint8_t fifo_wml = (cfg->fifo_wm) & 0xFF; + uint16_t fifo_wm = icm42688_compute_fifo_wm(cfg); + uint8_t fifo_wml = fifo_wm & 0xFF; LOG_DBG("FIFO_CONFIG2( (0x%x)) (WM Low) 0x%x", REG_FIFO_CONFIG2, fifo_wml); res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG2, fifo_wml); @@ -219,7 +276,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) return -EINVAL; } - uint8_t fifo_wmh = (cfg->fifo_wm >> 8) & 0x0F; + uint8_t fifo_wmh = (fifo_wm >> 8) & 0x0F; LOG_DBG("FIFO_CONFIG3 (0x%x) (WM High) 0x%x", REG_FIFO_CONFIG3, fifo_wmh); res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG3, fifo_wmh); diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index 5d41663c491..bfeac4e452f 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -122,7 +122,7 @@ static const char *sensor_attribute_name[SENSOR_ATTR_COMMON_COUNT] = { [SENSOR_ATTR_FEATURE_MASK] = "feature_mask", [SENSOR_ATTR_ALERT] = "alert", [SENSOR_ATTR_FF_DUR] = "ff_dur", - [SENSOR_ATTR_FIFO_WATERMARK] = "fifo_wm", + [SENSOR_ATTR_BATCH_DURATION] = "batch_dur", }; /* Forward declaration */ diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 80fda1b1634..e652c3a2040 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -334,8 +334,10 @@ enum sensor_attribute { * to the new sampling frequency. */ SENSOR_ATTR_FF_DUR, - /** Watermark % for the hardware fifo interrupt */ - SENSOR_ATTR_FIFO_WATERMARK, + + /** Hardware batch duration in ticks */ + SENSOR_ATTR_BATCH_DURATION, + /** * Number of all common sensor attributes. */ From 155f866ecc2c3117f8665a53408bef6fd9bd3a97 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Fri, 3 Nov 2023 13:03:46 +0100 Subject: [PATCH 3423/4498] dts: intel_adsp: ace remove dw watchdog DW watchdog driver is not used on ACE, Intel ADSP watchdog driver will be used in DTS when ready to use Signed-off-by: Adrian Bonislawski --- dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi | 26 --------------------- 1 file changed, 26 deletions(-) diff --git a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi index 564ee3fe26d..de8aa8ed6fd 100644 --- a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi @@ -513,32 +513,6 @@ interrupt-parent = <&ace_intc>; }; - watchdog0: watchdog@78300 { - compatible = "snps,designware-watchdog"; - reg = <0x78300 0x100>; - interrupts = <8 0 0>; - interrupt-parent = <&core_intc>; - clock-frequency = <32768>; - reset-pulse-length = <2>; - status = "okay"; - }; - - watchdog1: watchdog@78400 { - compatible = "snps,designware-watchdog"; - reg = <0x78400 0x100>; - clock-frequency = <32768>; - reset-pulse-length = <2>; - status = "okay"; - }; - - watchdog2: watchdog@78500 { - compatible = "snps,designware-watchdog"; - reg = <0x78500 0x100>; - clock-frequency = <32768>; - reset-pulse-length = <2>; - status = "okay"; - }; - /* This is actually an array of per-core designware * controllers, but the special setup and extra * masking layer makes it easier for MTL to handle From 6bd0b54526cda9dcbcb77c0adf933517ca46fecd Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Mon, 6 Nov 2023 13:48:51 -0700 Subject: [PATCH 3424/4498] twister: Fix gtest harness Some platforms prefix extra logging information before the standard [] blocks so I've added `.\*` to the regex. Also, removed the static values so they're only referenced using 'self.' and stopped parsing lines after the FINISHED_PATTERN is matched since some versions of gTest also print out a test summary after and it's not useful for the processing. Signed-off-by: Yuval Peress --- scripts/pylib/twister/twisterlib/harness.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 53765f6da38..ef24ef57720 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -450,17 +450,23 @@ def _parse_report_file(self, report): class Gtest(Harness): ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') - TEST_START_PATTERN = r"\[ RUN \] (?P.*)\.(?P.*)$" - TEST_PASS_PATTERN = r"\[ OK \] (?P.*)\.(?P.*)$" - TEST_FAIL_PATTERN = r"\[ FAILED \] (?P.*)\.(?P.*)$" - FINISHED_PATTERN = r"\[==========\] Done running all tests\.$" - has_failures = False - tc = None + TEST_START_PATTERN = r".*\[ RUN \] (?P.*)\.(?P.*)$" + TEST_PASS_PATTERN = r".*\[ OK \] (?P.*)\.(?P.*)$" + TEST_FAIL_PATTERN = r".*\[ FAILED \] (?P.*)\.(?P.*)$" + FINISHED_PATTERN = r".*\[==========\] Done running all tests\.$" + + def __init__(self): + super().__init__() + self.tc = None + self.has_failures = False def handle(self, line): # Strip the ANSI characters, they mess up the patterns non_ansi_line = self.ANSI_ESCAPE.sub('', line) + if self.state: + return + # Check if we started running a new test test_start_match = re.search(self.TEST_START_PATTERN, non_ansi_line) if test_start_match: From 27fe62c33ff73b066fe8fc4ccd2e8fe45e64a058 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 10 Nov 2023 14:31:28 +0530 Subject: [PATCH 3425/4498] ieee802154: ieee802154_cc13xx_cc26xx_subg: Add cc1352p7 support - Add support cc1352p7 used by beagleconnect_freedom - Since this is a multi interface device, auto config does not work. Signed-off-by: Ayush Singh --- drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 780700aac4f..ea626908d16 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -82,7 +82,7 @@ static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = { }; /* Radio values for CC13X2P */ -#elif defined(CONFIG_SOC_CC1352P) +#elif defined(CONFIG_SOC_CC1352P) || defined(CONFIG_SOC_CC1352P7) /* CC1352P overrides from SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */ static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = { /* Tx: Configure PA ramp time, PACTL2.RC=0x3 (in ADI0, set PACTL2[4:3]=0x1) */ @@ -141,7 +141,7 @@ static uint32_t rf_prop_overrides_tx_20[] = { #if defined(CONFIG_SOC_CC1352R) static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_subg_radio_div_setup = { .commandNo = CMD_PROP_RADIO_DIV_SETUP, -#elif defined(CONFIG_SOC_CC1352P) +#elif defined(CONFIG_SOC_CC1352P) || defined(CONFIG_SOC_CC1352P7) static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_subg_radio_div_setup = { .commandNo = CMD_PROP_RADIO_DIV_SETUP_PA, #endif /* CONFIG_SOC_CC1352x */ @@ -207,7 +207,7 @@ static const RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[] = { #endif RF_TxPowerTable_TERMINATION_ENTRY }; -#elif defined(CONFIG_SOC_CC1352P) +#elif defined(CONFIG_SOC_CC1352P) || defined(CONFIG_SOC_CC1352P7) /* Sub GHz power table */ static const RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[] = { { -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) }, From 26f30db8adabe40983ca2501e1c866dc7ebe2d5c Mon Sep 17 00:00:00 2001 From: Jason Kridner Date: Fri, 10 Nov 2023 15:48:41 +0530 Subject: [PATCH 3426/4498] soc: arm: ti_simplelink: cc13x2x7_cc26x2x7: add caparray delta config - Make caparray delta a Kconfig variable - Set caparray delta for beagle_bcf at beagleconnect_freedom_defconfig Signed-off-by: Ayush Singh Signed-off-by: Jason Kridner --- boards/arm/beagle_bcf/beagleconnect_freedom_defconfig | 3 +++ soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.soc | 7 +++++++ soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/ccfg.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig b/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig index d1d9ff8f84e..a2c05f40f32 100644 --- a/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig +++ b/boards/arm/beagle_bcf/beagleconnect_freedom_defconfig @@ -25,3 +25,6 @@ CONFIG_HW_STACK_PROTECTION=y CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y + +# Adjust for oscillator capacitors +CONFIG_CC13X2_CC26X2_XOSC_CAPARRAY_DELTA=0x02 diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.soc b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.soc index 74fae9acafd..96bd6cfce94 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.soc +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.soc @@ -65,4 +65,11 @@ config CC13X2_CC26X2_BOOTLOADER_BACKDOOR_LEVEL help Set the active level of the pin selected for the bootloader backdoor. +config CC13X2_CC26X2_XOSC_CAPARRAY_DELTA + hex "Cap array tuning delta" + range 0 0xFF + default 0xD5 + help + Enable a specific cap array tunning delta. + endmenu diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/ccfg.c b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/ccfg.c index 74f34acac0d..de7b81c32bf 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/ccfg.c +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/ccfg.c @@ -28,7 +28,7 @@ * https://software-dl.ti.com/simplelink/esd/simplelink_cc13xx_cc26xx_sdk/6.20.00.29/exports/release_notes_simplelink_cc13xx_cc26xx_sdk_6_20_00_29.html#known-issues */ #define SET_CCFG_MODE_CONF_XOSC_CAP_MOD 0x0 -#define SET_CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA 0xD5 +#define SET_CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA CONFIG_CC13X2_CC26X2_XOSC_CAPARRAY_DELTA #endif /* TI recommends setting CCFG values and then including the TI provided ccfg.c */ From 6ae03d98a0e5b636c62f8191f464e12d3782d6b1 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 22 May 2023 13:57:55 +0000 Subject: [PATCH 3427/4498] drivers, subsys: sort the lists again, mark the blocks for checking Sort the Kconfig and CMakeLists include blocks again, and mark the start and end of the blocks so that the CI can keep them sorted. Signed-off-by: Fabio Baltieri --- drivers/CMakeLists.txt | 16 +++++++++------- drivers/Kconfig | 10 ++++++---- subsys/CMakeLists.txt | 6 ++++-- subsys/Kconfig | 4 +++- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index b7fcdbed373..6310146bb3d 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -5,6 +5,7 @@ add_compile_options($) add_definitions(-D__ZEPHYR_SUPERVISOR__) +# zephyr-keep-sorted-start add_subdirectory(disk) add_subdirectory(interrupt_controller) add_subdirectory(misc) @@ -13,14 +14,15 @@ add_subdirectory(usb) add_subdirectory(usb_c) add_subdirectory_ifdef(CONFIG_ADC adc) +add_subdirectory_ifdef(CONFIG_ARM_SIP_SVC_DRIVER sip_svc) add_subdirectory_ifdef(CONFIG_AUDIO audio) +add_subdirectory_ifdef(CONFIG_AUXDISPLAY auxdisplay) add_subdirectory_ifdef(CONFIG_BBRAM bbram) -add_subdirectory_ifdef(CONFIG_XEN xen) add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth) add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache) add_subdirectory_ifdef(CONFIG_CAN can) -add_subdirectory_ifdef(CONFIG_CLOCK_CONTROL clock_control) add_subdirectory_ifdef(CONFIG_CHARGER charger) +add_subdirectory_ifdef(CONFIG_CLOCK_CONTROL clock_control) add_subdirectory_ifdef(CONFIG_CONSOLE console) add_subdirectory_ifdef(CONFIG_COREDUMP_DEVICE coredump) add_subdirectory_ifdef(CONFIG_COUNTER counter) @@ -28,7 +30,6 @@ add_subdirectory_ifdef(CONFIG_CRYPTO crypto) add_subdirectory_ifdef(CONFIG_DAC dac) add_subdirectory_ifdef(CONFIG_DAI dai) add_subdirectory_ifdef(CONFIG_DISPLAY display) -add_subdirectory_ifdef(CONFIG_AUXDISPLAY auxdisplay) add_subdirectory_ifdef(CONFIG_DMA dma) add_subdirectory_ifdef(CONFIG_EDAC edac) add_subdirectory_ifdef(CONFIG_EEPROM eeprom) @@ -40,8 +41,8 @@ add_subdirectory_ifdef(CONFIG_FUEL_GAUGE fuel_gauge) add_subdirectory_ifdef(CONFIG_GNSS gnss) add_subdirectory_ifdef(CONFIG_GPIO gpio) add_subdirectory_ifdef(CONFIG_HWINFO hwinfo) +add_subdirectory_ifdef(CONFIG_HWSPINLOCK hwspinlock) add_subdirectory_ifdef(CONFIG_I2C i2c) -add_subdirectory_ifdef(CONFIG_SMBUS smbus) add_subdirectory_ifdef(CONFIG_I2S i2s) add_subdirectory_ifdef(CONFIG_I3C i3c) add_subdirectory_ifdef(CONFIG_IEEE802154 ieee802154) @@ -70,9 +71,11 @@ add_subdirectory_ifdef(CONFIG_PWM pwm) add_subdirectory_ifdef(CONFIG_REGULATOR regulator) add_subdirectory_ifdef(CONFIG_RESET reset) add_subdirectory_ifdef(CONFIG_RETAINED_MEM retained_mem) +add_subdirectory_ifdef(CONFIG_RTC rtc) add_subdirectory_ifdef(CONFIG_SDHC sdhc) add_subdirectory_ifdef(CONFIG_SENSOR sensor) add_subdirectory_ifdef(CONFIG_SERIAL serial) +add_subdirectory_ifdef(CONFIG_SMBUS smbus) add_subdirectory_ifdef(CONFIG_SPI spi) add_subdirectory_ifdef(CONFIG_SYSCON syscon) add_subdirectory_ifdef(CONFIG_SYS_CLOCK_EXISTS timer) @@ -81,6 +84,5 @@ add_subdirectory_ifdef(CONFIG_VIRTUALIZATION virtualization) add_subdirectory_ifdef(CONFIG_W1 w1) add_subdirectory_ifdef(CONFIG_WATCHDOG watchdog) add_subdirectory_ifdef(CONFIG_WIFI wifi) -add_subdirectory_ifdef(CONFIG_RTC rtc) -add_subdirectory_ifdef(CONFIG_ARM_SIP_SVC_DRIVER sip_svc) -add_subdirectory_ifdef(CONFIG_HWSPINLOCK hwspinlock) +add_subdirectory_ifdef(CONFIG_XEN xen) +# zephyr-keep-sorted-stop diff --git a/drivers/Kconfig b/drivers/Kconfig index 1eca764fce2..45b03e4829c 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -5,9 +5,10 @@ menu "Device Drivers" +# zephyr-keep-sorted-start source "drivers/adc/Kconfig" -source "drivers/auxdisplay/Kconfig" source "drivers/audio/Kconfig" +source "drivers/auxdisplay/Kconfig" source "drivers/bbram/Kconfig" source "drivers/bluetooth/Kconfig" source "drivers/cache/Kconfig" @@ -34,10 +35,10 @@ source "drivers/fuel_gauge/Kconfig" source "drivers/gnss/Kconfig" source "drivers/gpio/Kconfig" source "drivers/hwinfo/Kconfig" +source "drivers/hwspinlock/Kconfig" source "drivers/i2c/Kconfig" source "drivers/i2s/Kconfig" source "drivers/i3c/Kconfig" -source "drivers/smbus/Kconfig" source "drivers/ieee802154/Kconfig" source "drivers/input/Kconfig" source "drivers/interrupt_controller/Kconfig" @@ -71,6 +72,8 @@ source "drivers/rtc/Kconfig" source "drivers/sdhc/Kconfig" source "drivers/sensor/Kconfig" source "drivers/serial/Kconfig" +source "drivers/sip_svc/Kconfig" +source "drivers/smbus/Kconfig" source "drivers/spi/Kconfig" source "drivers/syscon/Kconfig" source "drivers/timer/Kconfig" @@ -82,7 +85,6 @@ source "drivers/w1/Kconfig" source "drivers/watchdog/Kconfig" source "drivers/wifi/Kconfig" source "drivers/xen/Kconfig" -source "drivers/sip_svc/Kconfig" -source "drivers/hwspinlock/Kconfig" +# zephyr-keep-sorted-stop endmenu diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index bef01e0f24a..ccd2c8c88bf 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory_ifdef(CONFIG_LORAWAN lorawan) # FIXME: SHADOW_VARS: Remove this once we have enabled -Wshadow globally. add_compile_options($) +# zephyr-keep-sorted-start add_subdirectory(canbus) add_subdirectory(debug) add_subdirectory(fb) @@ -32,6 +33,7 @@ add_subdirectory(testsuite) add_subdirectory(tracing) add_subdirectory(usb) +add_subdirectory_ifdef(CONFIG_ARM_SIP_SVC_SUBSYS sip_svc) add_subdirectory_ifdef(CONFIG_BINDESC bindesc) add_subdirectory_ifdef(CONFIG_BT bluetooth) add_subdirectory_ifdef(CONFIG_CONSOLE_SUBSYS console) @@ -42,8 +44,8 @@ add_subdirectory_ifdef(CONFIG_EMUL emul) add_subdirectory_ifdef(CONFIG_IMG_MANAGER dfu) add_subdirectory_ifdef(CONFIG_INPUT input) add_subdirectory_ifdef(CONFIG_JWT jwt) -add_subdirectory_ifdef(CONFIG_MODEM_MODULES modem) add_subdirectory_ifdef(CONFIG_LLEXT llext) +add_subdirectory_ifdef(CONFIG_MODEM_MODULES modem) add_subdirectory_ifdef(CONFIG_NET_BUF net) add_subdirectory_ifdef(CONFIG_RETENTION retention) add_subdirectory_ifdef(CONFIG_SENSING sensing) @@ -51,4 +53,4 @@ add_subdirectory_ifdef(CONFIG_SETTINGS settings) add_subdirectory_ifdef(CONFIG_SHELL shell) add_subdirectory_ifdef(CONFIG_TIMING_FUNCTIONS timing) add_subdirectory_ifdef(CONFIG_ZBUS zbus) -add_subdirectory_ifdef(CONFIG_ARM_SIP_SVC_SUBSYS sip_svc) +# zephyr-keep-sorted-stop diff --git a/subsys/Kconfig b/subsys/Kconfig index e4fa9212ab0..f0dab7c8c72 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -6,6 +6,7 @@ menu "Subsystems and OS Services" +# zephyr-keep-sorted-start source "subsys/bindesc/Kconfig" source "subsys/bluetooth/Kconfig" source "subsys/canbus/Kconfig" @@ -38,6 +39,7 @@ source "subsys/sd/Kconfig" source "subsys/sensing/Kconfig" source "subsys/settings/Kconfig" source "subsys/shell/Kconfig" +source "subsys/sip_svc/Kconfig" source "subsys/stats/Kconfig" source "subsys/storage/Kconfig" source "subsys/task_wdt/Kconfig" @@ -49,6 +51,6 @@ source "subsys/usb/device_next/Kconfig" source "subsys/usb/host/Kconfig" source "subsys/usb/usb_c/Kconfig" source "subsys/zbus/Kconfig" -source "subsys/sip_svc/Kconfig" +# zephyr-keep-sorted-stop endmenu From 98d9a7f86f5af8bebb98bda445ff3bbc3321c330 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 22 May 2023 14:22:35 +0000 Subject: [PATCH 3428/4498] scripts: compliance: add a compliance check to keep blocks of code sorted This allows defining a list within two marker (zephyr-keep-sorted-start and zephyr-keep-sorted-stop), and have the CI validate that the block is kept sorted every time stuff gets added to it. This is mainly for Kconfig and CMake include lists so that there's no ambiguity on where to add new stuff. Signed-off-by: Fabio Baltieri --- .gitignore | 1 + scripts/ci/check_compliance.py | 53 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/.gitignore b/.gitignore index fae5aabbf30..13c99731c52 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,7 @@ ImageSize.txt Kconfig.txt KconfigBasic.txt KconfigBasicNoModules.txt +KeepSorted.txt MaintainersFormat.txt ModulesMaintainers.txt Nits.txt diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 779da01f2c5..cbbd0da9b66 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1163,6 +1163,59 @@ def run(self): p.line, col=p.column, desc=p.desc) +class KeepSorted(ComplianceTest): + """ + Check for blocks of code or config that should be kept sorted. + """ + name = "KeepSorted" + doc = "Check for blocks of code or config that should be kept sorted." + path_hint = "" + + MARKER = "zephyr-keep-sorted" + + def check_file(self, file, fp): + lines = [] + in_block = False + + start_marker = f"{self.MARKER}-start" + stop_marker = f"{self.MARKER}-stop" + + for line_num, line in enumerate(fp.readlines(), start=1): + if start_marker in line: + if in_block: + desc = f"nested {start_marker}" + self.fmtd_failure("error", "KeepSorted", file, line_num, + desc=desc) + in_block = True + lines = [] + elif stop_marker in line: + if not in_block: + desc = f"{stop_marker} without {start_marker}" + self.fmtd_failure("error", "KeepSorted", file, line_num, + desc=desc) + in_block = False + + if lines != sorted(lines): + desc = f"sorted block is not sorted" + self.fmtd_failure("error", "KeepSorted", file, line_num, + desc=desc) + elif not line.strip() or line.startswith("#"): + # Ignore comments and blank lines + continue + elif in_block: + if line.startswith((" ", "\t")): + lines[-1] += line + else: + lines.append(line) + + if in_block: + self.failure(f"unterminated {start_marker} in {file}") + + def run(self): + for file in get_files(filter="d"): + with open(file, "r") as fp: + self.check_file(file, fp) + def init_logs(cli_arg): # Initializes logging From 3003cc1938f53074ad717af79d1ff1e7ff15b514 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 11 Nov 2023 18:41:29 +0000 Subject: [PATCH 3429/4498] input: keep CMakeLists and Kconfig sorted Add zephyr-keep-sorted tags to CMakeLists and Kconfig in input. Signed-off-by: Fabio Baltieri --- drivers/input/CMakeLists.txt | 2 ++ drivers/input/Kconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index e141652fe48..96f85ba0e72 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) +# zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_INPUT_CAP1203 input_cap1203.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CST816S input_cst816s.c) zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) @@ -14,6 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_KBD_MATRIX input_kbd_matrix.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c) +# zephyr-keep-sorted-stop if (CONFIG_INPUT_SDL_TOUCH) zephyr_library_sources(input_sdl_touch.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 21401d9dbdb..2a0f8ac8526 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -5,6 +5,7 @@ if INPUT menu "Input drivers" +# zephyr-keep-sorted-start source "drivers/input/Kconfig.cap1203" source "drivers/input/Kconfig.cst816s" source "drivers/input/Kconfig.ft5336" @@ -17,6 +18,7 @@ source "drivers/input/Kconfig.npcx" source "drivers/input/Kconfig.sdl" source "drivers/input/Kconfig.stmpe811" source "drivers/input/Kconfig.xpt2046" +# zephyr-keep-sorted-stop endmenu # Input Drivers From 6db785404ac13e8692833cbc440f699c7d50432c Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Wed, 27 Sep 2023 19:04:12 -0400 Subject: [PATCH 3430/4498] tests: drivers: uart_async_api: Be more robust to early buf release Commit eb44414af99a44447afa52bb81ac0767f2ff791e modified test_single_read for early rx buf release. The commit assumed that tdata.last_rx_buf points to either &tdata.rx_buf[0] if the driver releases the first buffer or at &rx_buf[5] if the first buffer is not released. However, where tdata.last_rx_buf points to depends on the timeout given to uart_rx_enable(), making the test flaky. This commit modifies the test by keeping track how many bytes have been received in the first and second buffers. The function tdata_check_recv_buffer() validates that the sent data matches the received bytes which may have been split between first and second buffer. This fixes the uart_async_api test on the xmc45_relax_kit. Signed-off-by: Andriy Gelman --- .../uart/uart_async_api/src/test_uart_async.c | 91 +++++++++++++------ 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/tests/drivers/uart/uart_async_api/src/test_uart_async.c b/tests/drivers/uart/uart_async_api/src/test_uart_async.c index af3a63b197d..9579e49c759 100644 --- a/tests/drivers/uart/uart_async_api/src/test_uart_async.c +++ b/tests/drivers/uart/uart_async_api/src/test_uart_async.c @@ -79,10 +79,11 @@ static void uart_async_test_init(void) struct test_data { volatile uint32_t tx_aborted_count; - uint8_t rx_buf[5]; - bool rx_buf_req_done; - bool supply_next_buffer; - uint8_t *last_rx_buf; + uint8_t rx_first_buffer[10]; + uint32_t recv_bytes_first_buffer; + uint8_t rx_second_buffer[5]; + uint32_t recv_bytes_second_buffer; + bool supply_second_buffer; }; ZTEST_BMEM struct test_data tdata; @@ -101,17 +102,22 @@ static void test_single_read_callback(const struct device *dev, data->tx_aborted_count++; break; case UART_RX_RDY: - data->last_rx_buf = &evt->data.rx.buf[evt->data.rx.offset]; + if ((uintptr_t)evt->data.rx.buf < (uintptr_t)tdata.rx_second_buffer) { + data->recv_bytes_first_buffer += evt->data.rx.len; + } else { + data->recv_bytes_second_buffer += evt->data.rx.len; + } k_sem_give(&rx_rdy); break; case UART_RX_BUF_RELEASED: k_sem_give(&rx_buf_released); break; case UART_RX_BUF_REQUEST: - if (data->supply_next_buffer) { + if (data->supply_second_buffer) { /* Reply to one buffer request. */ - uart_rx_buf_rsp(dev, data->rx_buf, sizeof(data->rx_buf)); - data->supply_next_buffer = false; + uart_rx_buf_rsp(dev, data->rx_second_buffer, + sizeof(data->rx_second_buffer)); + data->supply_second_buffer = false; } break; case UART_RX_DISABLED: @@ -129,7 +135,7 @@ static void *single_read_setup(void) uart_async_test_init(); memset(&tdata, 0, sizeof(tdata)); - tdata.supply_next_buffer = true; + tdata.supply_second_buffer = true; uart_callback_set(uart_dev, test_single_read_callback, (void *) &tdata); @@ -137,30 +143,57 @@ static void *single_read_setup(void) return NULL; } -ZTEST_USER(uart_async_single_read, test_single_read) +static void tdata_check_recv_buffers(const uint8_t *tx_buf, uint32_t sent_bytes) { - uint8_t rx_buf[10] = {0}; + uint32_t recv_bytes_total; + + recv_bytes_total = tdata.recv_bytes_first_buffer + tdata.recv_bytes_second_buffer; + zassert_equal(recv_bytes_total, sent_bytes, "Incorrect number of bytes received"); + + zassert_equal(memcmp(tx_buf, tdata.rx_first_buffer, tdata.recv_bytes_first_buffer), 0, + "Invalid data received in first buffer"); + zassert_equal(memcmp(tx_buf + tdata.recv_bytes_first_buffer, tdata.rx_second_buffer, + tdata.recv_bytes_second_buffer), + 0, "Invalid data received in second buffer"); + + /* check that the remaining bytes in the buffers are zero */ + for (int i = tdata.recv_bytes_first_buffer; i < sizeof(tdata.rx_first_buffer); i++) { + zassert_equal(tdata.rx_first_buffer[i], 0, + "Received extra data to the first buffer"); + } + for (int i = tdata.recv_bytes_second_buffer; i < sizeof(tdata.rx_second_buffer); i++) { + zassert_equal(tdata.rx_second_buffer[i], 0, + "Received extra data to the second buffer"); + } +} + +ZTEST_USER(uart_async_single_read, test_single_read) +{ /* Check also if sending from read only memory (e.g. flash) works. */ - static const uint8_t tx_buf[5] = "test\0"; + static const uint8_t tx_buf[] = "0123456789"; + uint32_t sent_bytes = 0; - zassert_not_equal(memcmp(tx_buf, rx_buf, 5), 0, + zassert_not_equal(memcmp(tx_buf, tdata.rx_first_buffer, 5), 0, "Initial buffer check failed"); - uart_rx_enable(uart_dev, rx_buf, 10, 50 * USEC_PER_MSEC); + uart_rx_enable(uart_dev, tdata.rx_first_buffer, 10, 50 * USEC_PER_MSEC); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, "RX_RDY not expected at this point"); - uart_tx(uart_dev, tx_buf, sizeof(tx_buf), 100 * USEC_PER_MSEC); + uart_tx(uart_dev, tx_buf, 5, 100 * USEC_PER_MSEC); + sent_bytes += 5; + zassert_equal(k_sem_take(&tx_done, K_MSEC(100)), 0, "TX_DONE timeout"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), 0, "RX_RDY timeout"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, "Extra RX_RDY received"); - zassert_equal(memcmp(tx_buf, tdata.last_rx_buf, 5), 0, "Buffers not equal"); - zassert_not_equal(memcmp(tx_buf, rx_buf+5, 5), 0, "Buffers not equal"); + tdata_check_recv_buffers(tx_buf, sent_bytes); + + uart_tx(uart_dev, tx_buf + sent_bytes, 5, 100 * USEC_PER_MSEC); + sent_bytes += 5; - uart_tx(uart_dev, tx_buf, sizeof(tx_buf), 100 * USEC_PER_MSEC); zassert_equal(k_sem_take(&tx_done, K_MSEC(100)), 0, "TX_DONE timeout"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), 0, "RX_RDY timeout"); zassert_equal(k_sem_take(&rx_buf_released, K_MSEC(100)), @@ -173,7 +206,8 @@ ZTEST_USER(uart_async_single_read, test_single_read) zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, "Extra RX_RDY received"); - zassert_equal(memcmp(tx_buf, tdata.last_rx_buf, 5), 0, "Buffers not equal"); + tdata_check_recv_buffers(tx_buf, sent_bytes); + zassert_equal(tdata.tx_aborted_count, 0, "TX aborted triggered"); } @@ -196,11 +230,13 @@ ZTEST_USER(uart_async_multi_rx, test_multiple_rx_enable) { /* Check also if sending from read only memory (e.g. flash) works. */ static const uint8_t tx_buf[] = "test"; - uint8_t rx_buf[sizeof(tx_buf)] = {0}; + const uint32_t rx_buf_size = sizeof(tx_buf); int ret; + BUILD_ASSERT(rx_buf_size <= sizeof(tdata.rx_first_buffer), "Invalid buf size"); + /* Enable RX without a timeout. */ - ret = uart_rx_enable(uart_dev, rx_buf, sizeof(rx_buf), SYS_FOREVER_US); + ret = uart_rx_enable(uart_dev, tdata.rx_first_buffer, rx_buf_size, SYS_FOREVER_US); zassert_equal(ret, 0, "uart_rx_enable failed"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, "RX_RDY not expected at this point"); @@ -221,7 +257,7 @@ ZTEST_USER(uart_async_multi_rx, test_multiple_rx_enable) k_sem_reset(&rx_disabled); /* Check that RX can be reenabled after "manual" disabling. */ - ret = uart_rx_enable(uart_dev, rx_buf, sizeof(rx_buf), + ret = uart_rx_enable(uart_dev, tdata.rx_first_buffer, rx_buf_size, 50 * USEC_PER_MSEC); zassert_equal(ret, 0, "uart_rx_enable failed"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, @@ -240,17 +276,17 @@ ZTEST_USER(uart_async_multi_rx, test_multiple_rx_enable) "RX_DISABLED timeout"); zassert_equal(tx_aborted_count, 0, "Unexpected TX abort"); - zassert_equal(memcmp(tx_buf, rx_buf, sizeof(tx_buf)), 0, - "Buffers not equal"); + tdata_check_recv_buffers(tx_buf, sizeof(tx_buf)); k_sem_reset(&rx_rdy); k_sem_reset(&rx_buf_released); k_sem_reset(&rx_disabled); k_sem_reset(&tx_done); - memset(rx_buf, 0, sizeof(rx_buf)); + + memset(&tdata, 0, sizeof(tdata)); /* Check that RX can be reenabled after automatic disabling. */ - ret = uart_rx_enable(uart_dev, rx_buf, sizeof(rx_buf), + ret = uart_rx_enable(uart_dev, tdata.rx_first_buffer, rx_buf_size, 50 * USEC_PER_MSEC); zassert_equal(ret, 0, "uart_rx_enable failed"); zassert_equal(k_sem_take(&rx_rdy, K_MSEC(100)), -EAGAIN, @@ -269,8 +305,7 @@ ZTEST_USER(uart_async_multi_rx, test_multiple_rx_enable) "RX_DISABLED timeout"); zassert_equal(tx_aborted_count, 0, "Unexpected TX abort"); - zassert_equal(memcmp(tx_buf, rx_buf, sizeof(tx_buf)), 0, - "Buffers not equal"); + tdata_check_recv_buffers(tx_buf, sizeof(tx_buf)); } ZTEST_BMEM uint8_t chained_read_buf[2][8]; From 1946dd829d1e11c1bd4b6dbe8b4fb1876a162fb6 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 11:14:38 +0200 Subject: [PATCH 3431/4498] tests: Bluetooth: Add inval testing of bt_bap_broadcast_source_get_id Add invalid parameter and state testing of bt_bap_broadcast_source_get_id Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index ff974565240..5ba0e624276 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -1164,6 +1164,57 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_id) fixture->source = NULL; } +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_id_inval_source_null) +{ + uint32_t broadcast_id; + int err; + + err = bt_bap_broadcast_source_get_id(NULL, &broadcast_id); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_id_inval_id_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_id(fixture->source, NULL); + zassert_not_equal(0, err, "Did not fail with null ID"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_id_inval_state) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source *source; + uint32_t broadcast_id; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + source = fixture->source; + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; + + err = bt_bap_broadcast_source_get_id(source, &broadcast_id); + zassert_not_equal(0, err, "Did not fail with deleted broadcast source"); +} + ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_single_bis) { struct bt_bap_broadcast_source_param *create_param = fixture->param; From 475e0673795603e68f3a635ecb2bf720b26802af Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 11:22:24 +0200 Subject: [PATCH 3432/4498] tests: Bluetooth: Add inval testing of bt_bap_broadcast_source_get_base Add invalid parameter and state testing of bt_bap_broadcast_source_get_base Signed-off-by: Emil Gydesen --- .../audio/bap_broadcast_source/src/main.c | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tests/bluetooth/audio/bap_broadcast_source/src/main.c b/tests/bluetooth/audio/bap_broadcast_source/src/main.c index 5ba0e624276..8d85eb321ac 100644 --- a/tests/bluetooth/audio/bap_broadcast_source/src/main.c +++ b/tests/bluetooth/audio/bap_broadcast_source/src/main.c @@ -1334,3 +1334,101 @@ ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base) zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); fixture->source = NULL; } + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_inval_source_null) +{ + int err; + + NET_BUF_SIMPLE_DEFINE(base_buf, 64); + + err = bt_bap_broadcast_source_get_base(NULL, &base_buf); + zassert_not_equal(0, err, "Did not fail with null source"); +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_inval_base_buf_null) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_base(fixture->source, NULL); + zassert_not_equal(0, err, "Did not fail with null BASE buffer"); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_inval_state) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + struct bt_bap_broadcast_source *source; + int err; + + NET_BUF_SIMPLE_DEFINE(base_buf, 64); + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + source = fixture->source; + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; + + err = bt_bap_broadcast_source_get_base(source, &base_buf); + zassert_not_equal(0, err, "Did not fail with deleted broadcast source"); +} + +/** This tests that providing a buffer too small for _any_ BASE fails correctly */ +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_inval_very_small_buf) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + NET_BUF_SIMPLE_DEFINE(base_buf, 15); /* Too small to hold any BASE */ + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_base(fixture->source, &base_buf); + zassert_not_equal(0, err, "Did not fail with too small base_buf (%u)", base_buf.size); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} + +/** This tests that providing a buffer too small for the BASE we want to setup fails correctly */ +ZTEST_F(bap_broadcast_source_test_suite, test_broadcast_source_get_base_inval_small_buf) +{ + struct bt_bap_broadcast_source_param *create_param = fixture->param; + int err; + + /* Can hold a base, but not large enough for this configuration */ + NET_BUF_SIMPLE_DEFINE(base_buf, 64); + + printk("Creating broadcast source with %zu subgroups with %zu streams\n", + create_param->params_count, fixture->stream_cnt); + + err = bt_bap_broadcast_source_create(create_param, &fixture->source); + zassert_equal(0, err, "Unable to create broadcast source: err %d", err); + + err = bt_bap_broadcast_source_get_base(fixture->source, &base_buf); + zassert_not_equal(0, err, "Did not fail with too small base_buf (%u)", base_buf.size); + + err = bt_bap_broadcast_source_delete(fixture->source); + zassert_equal(0, err, "Unable to delete broadcast source: err %d", err); + fixture->source = NULL; +} From 175a2f3287af96107c4f7e3ff7092dd372eee33f Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 11:28:09 +0200 Subject: [PATCH 3433/4498] tests: bsim: Bluetooth: Remove broadcast_source_get_id_inval Removed the tests for invalid bt_bap_broadcast_source_get_id parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index 773240a0c36..fcc72701e34 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -149,26 +149,6 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) return 0; } -static void test_broadcast_source_get_id_inval(struct bt_bap_broadcast_source *source, - uint32_t *broadcast_id_out) -{ - int err; - - printk("Test bt_bap_broadcast_source_get_id with NULL source\n"); - err = bt_bap_broadcast_source_get_id(NULL, broadcast_id_out); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_id with NULL source did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_get_id with NULL broadcast_id\n"); - err = bt_bap_broadcast_source_get_id(source, NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_id with NULL ID did not fail\n"); - return; - } -} - static void test_broadcast_source_get_id(struct bt_bap_broadcast_source *source, uint32_t *broadcast_id_out) { @@ -256,7 +236,6 @@ static int setup_extended_adv(struct bt_bap_broadcast_source *source, struct bt_ return err; } - test_broadcast_source_get_id_inval(source, &broadcast_id); test_broadcast_source_get_id(source, &broadcast_id); /* Setup extended advertising data */ From 9f3858aad967e7477cdc7180fa7978d8367237d5 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 8 Sep 2023 11:28:47 +0200 Subject: [PATCH 3434/4498] tests: bsim: Bluetooth: Remove broadcast_source_get_base_inval Removed the tests for invalid bt_bap_broadcast_source_get_base parameters and state, as those tests now implemented as unit tests. Signed-off-by: Emil Gydesen --- .../audio/src/bap_broadcast_source_test.c | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c index fcc72701e34..2c6c5bc1828 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_source_test.c @@ -161,43 +161,6 @@ static void test_broadcast_source_get_id(struct bt_bap_broadcast_source *source, } } -static void test_broadcast_source_get_base_inval(struct bt_bap_broadcast_source *source, - struct net_buf_simple *base_buf) -{ - /* Large enough for minimum, but not large enough for any CC or Meta data */ - NET_BUF_SIMPLE_DEFINE(small_base_buf, BT_BAP_BASE_MIN_SIZE + 2); - NET_BUF_SIMPLE_DEFINE(very_small_base_buf, 4); - int err; - - printk("Test bt_bap_broadcast_source_get_base with NULL source\n"); - err = bt_bap_broadcast_source_get_base(NULL, base_buf); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_base with NULL source did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_get_base with NULL buf\n"); - err = bt_bap_broadcast_source_get_base(source, NULL); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_base with NULL buf did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_get_base with very small buf\n"); - err = bt_bap_broadcast_source_get_base(source, &very_small_base_buf); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_base with very small buf did not fail\n"); - return; - } - - printk("Test bt_bap_broadcast_source_get_base with small buf\n"); - err = bt_bap_broadcast_source_get_base(source, &small_base_buf); - if (err == 0) { - FAIL("bt_bap_broadcast_source_get_base with small buf did not fail\n"); - return; - } -} - static void test_broadcast_source_get_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *base_buf) { @@ -251,7 +214,6 @@ static int setup_extended_adv(struct bt_bap_broadcast_source *source, struct bt_ } /* Setup periodic advertising data */ - test_broadcast_source_get_base_inval(source, &base_buf); test_broadcast_source_get_base(source, &base_buf); per_ad.type = BT_DATA_SVC_DATA16; From a2f971795f96b6c6785565b1e9bedef55188767d Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Fri, 8 Sep 2023 14:21:39 -0700 Subject: [PATCH 3435/4498] soc: arm: ti_k3: am62x_m4: Lower Initialization level for init Other drivers like the pinctrl_ti_k3 rely on a fully initialized system. Move the am62x_init to an earlier stage than PRE_KERNEL_1 to keep both PRE_KERNEL_{1,2} free for drivers. Signed-off-by: Daniel Schultz --- soc/arm/ti_k3/am62x_m4/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/ti_k3/am62x_m4/soc.c b/soc/arm/ti_k3/am62x_m4/soc.c index 1010e045ea5..9c86eb09a1d 100644 --- a/soc/arm/ti_k3/am62x_m4/soc.c +++ b/soc/arm/ti_k3/am62x_m4/soc.c @@ -70,4 +70,4 @@ static int am62x_m4_init(void) return 0; } -SYS_INIT(am62x_m4_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(am62x_m4_init, EARLY, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); From fbd2b84e0ea72babad4ae14a0265e0965a5dfca1 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Mon, 4 Sep 2023 09:58:35 -0700 Subject: [PATCH 3436/4498] drivers: gpio: davinci: Add pinctrl Add pinctrl to the Davinci GPIO driver to allow muxing pins dirctly in this driver. Also aligned the macro backslashes as line continuation character at the end of each line with each at the same position and removed the GPIO_DAVINCI_DEVICE_INIT macro which seems to be not used. Signed-off-by: Daniel Schultz --- drivers/gpio/gpio_davinci.c | 77 ++++++++++---------- dts/bindings/gpio/ti,davinci-gpio-nexus.yaml | 2 +- dts/bindings/gpio/ti,davinci-gpio.yaml | 2 +- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/gpio/gpio_davinci.c b/drivers/gpio/gpio_davinci.c index 5726ed1bf32..205e0112cde 100644 --- a/drivers/gpio/gpio_davinci.c +++ b/drivers/gpio/gpio_davinci.c @@ -17,10 +17,14 @@ #include #include #include +#include +#include + +LOG_MODULE_REGISTER(gpio_davinci, CONFIG_GPIO_LOG_LEVEL); /* Helper Macros for GPIO */ #define DEV_CFG(dev) \ - ((const struct gpio_davinci_config * const)((dev)->config)) + ((const struct gpio_davinci_config *)((dev)->config)) #define DEV_DATA(dev) ((struct gpio_davinci_data *)(dev)->data) #define DEV_GPIO_CFG_BASE(dev) \ ((struct gpio_davinci_regs *)DEVICE_MMIO_NAMED_GET(dev, port_base)) @@ -55,6 +59,7 @@ struct gpio_davinci_config { DEVICE_MMIO_NAMED_ROM(port_base); uint32_t port_num; + const struct pinctrl_dev_config *pcfg; }; static int gpio_davinci_configure(const struct device *dev, gpio_pin_t pin, @@ -76,11 +81,9 @@ static int gpio_davinci_configure(const struct device *dev, gpio_pin_t pin, } else { regs->clr_data = BIT(pin); } - - regs->dir &= (~(BIT(pin))); - + regs->dir &= ~(BIT(pin)); } else { - regs->dir |= (BIT(pin)); + regs->dir |= BIT(pin); } return 0; @@ -149,6 +152,7 @@ static int gpio_davinci_init(const struct device *dev) { const struct gpio_davinci_config *config = DEV_CFG(dev); volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev); + int ret; DEVICE_MMIO_NAMED_MAP(dev, port_base, K_MEM_CACHE_NONE); @@ -156,44 +160,43 @@ static int gpio_davinci_init(const struct device *dev) config->bank_config(dev); + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("failed to apply pinctrl"); + return ret; + } return 0; } -#define GPIO_DAVINCI_INIT_FUNC(n) \ - static void gpio_davinci_bank_##n##_config(const struct device *dev) \ - { \ +#define GPIO_DAVINCI_INIT_FUNC(n) \ + static void gpio_davinci_bank_##n##_config(const struct device *dev) \ + { \ volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev); \ - ARG_UNUSED(regs); \ + ARG_UNUSED(regs); \ } -#define GPIO_DAVINCI_DEVICE_INIT(n) \ - DEVICE_DT_INST_DEFINE(n, &gpio_davinci_##n##_init, \ - NULL, &gpio_davinci_##n##_data, \ - &gpio_davinci_##n##_config, \ - POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \ - &api_funcs) - -#define GPIO_DAVINCI_INIT(n) \ - \ - GPIO_DAVINCI_INIT_FUNC(n) \ - static const struct gpio_davinci_config gpio_davinci_##n##_config = { \ - .bank_config = gpio_davinci_bank_##n##_config, \ - .common = { \ - .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ - }, \ - DEVICE_MMIO_NAMED_ROM_INIT(port_base, DT_DRV_INST(n)), \ - .port_num = n \ - }; \ - \ - static struct gpio_davinci_data gpio_davinci_##n##_data; \ - \ - DEVICE_DT_INST_DEFINE(n, \ - &gpio_davinci_init, \ - NULL, \ - &gpio_davinci_##n##_data, \ - &gpio_davinci_##n##_config, \ - PRE_KERNEL_2, \ - CONFIG_GPIO_INIT_PRIORITY, \ +#define GPIO_DAVINCI_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + GPIO_DAVINCI_INIT_FUNC(n); \ + static const struct gpio_davinci_config gpio_davinci_##n##_config = { \ + .bank_config = gpio_davinci_bank_##n##_config, \ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + DEVICE_MMIO_NAMED_ROM_INIT(port_base, DT_DRV_INST(n)), \ + .port_num = n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct gpio_davinci_data gpio_davinci_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &gpio_davinci_init, \ + NULL, \ + &gpio_davinci_##n##_data, \ + &gpio_davinci_##n##_config, \ + PRE_KERNEL_2, \ + CONFIG_GPIO_INIT_PRIORITY, \ &gpio_davinci_driver_api); DT_INST_FOREACH_STATUS_OKAY(GPIO_DAVINCI_INIT) diff --git a/dts/bindings/gpio/ti,davinci-gpio-nexus.yaml b/dts/bindings/gpio/ti,davinci-gpio-nexus.yaml index 3cfccfa5ee3..1b38fe927ca 100644 --- a/dts/bindings/gpio/ti,davinci-gpio-nexus.yaml +++ b/dts/bindings/gpio/ti,davinci-gpio-nexus.yaml @@ -7,7 +7,7 @@ description: GPIO controller for Davinci and Keystone devices compatible: "ti,davinci-gpio-nexus" -include: [base.yaml, gpio-nexus.yaml] +include: [base.yaml, gpio-nexus.yaml, pinctrl-device.yaml] properties: "#gpio-cells": diff --git a/dts/bindings/gpio/ti,davinci-gpio.yaml b/dts/bindings/gpio/ti,davinci-gpio.yaml index 0472dfa1aa1..64c0bbd5db5 100644 --- a/dts/bindings/gpio/ti,davinci-gpio.yaml +++ b/dts/bindings/gpio/ti,davinci-gpio.yaml @@ -7,7 +7,7 @@ description: GPIO controller for Davinci and Keystone devices. compatible: "ti,davinci-gpio" -include: [gpio-controller.yaml, base.yaml] +include: [base.yaml, gpio-controller.yaml, pinctrl-device.yaml] properties: reg: From 474bbd12e94513d08314bb67c0a783499f43cdec Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Mon, 4 Sep 2023 09:55:44 -0700 Subject: [PATCH 3437/4498] dts: arm: ti: am62x_m4: Add gpio0 node The M4F subsystem has a dedicated GPIO controller with 24 available pins. Add the node definition for the recently added driver. Signed-off-by: Daniel Schultz --- dts/arm/ti/am62x_m4.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dts/arm/ti/am62x_m4.dtsi b/dts/arm/ti/am62x_m4.dtsi index 22de7a14f82..8d5e5a14c40 100644 --- a/dts/arm/ti/am62x_m4.dtsi +++ b/dts/arm/ti/am62x_m4.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include / { @@ -54,6 +55,16 @@ reg-shift = <2>; status = "disabled"; }; + + gpio0: gpio@4201010 { + compatible = "ti,davinci-gpio"; + reg = <0x4201010 0x100>; + #address-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <24>; + status = "disabled"; + }; }; &nvic { From da1427406da4778d4f76dbe78c5828126a0a145b Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Mon, 4 Sep 2023 10:01:03 -0700 Subject: [PATCH 3438/4498] boards: arm: am62x_m4: Add GPIO0 to phyBOARD-lyra Enable the gpio0 node and mux the heartbeat LED. Moreover, add the heartbeart LED as LED node and create an alias with 'led0'. Signed-off-by: Daniel Schultz --- .../arm/am62x_m4/am62x_m4_phyboard_lyra.dts | 21 +++++++++++++++++++ .../am62x_m4/am62x_m4_phyboard_lyra_defconfig | 3 +++ 2 files changed, 24 insertions(+) diff --git a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.dts b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.dts index 3fac130ee90..ba370240340 100644 --- a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.dts +++ b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra.dts @@ -20,6 +20,10 @@ zephyr,sram1 = &ddr0; }; + aliases { + led0 = &heartbeat_led; + }; + cpus { cpu@0 { status = "okay"; @@ -32,6 +36,14 @@ reg = <0x9CC00000 DT_SIZE_K(4)>; zephyr,memory-region = "DDR"; }; + + leds: leds { + compatible = "gpio-leds"; + heartbeat_led: led_0 { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "Heartbeat LED"; + }; + }; }; &pinctrl { @@ -41,6 +53,9 @@ mcu_uart0_tx_default: mcu_uart0_tx_default { pinmux = ; }; + mcu_gpio0_led_default: mcu_gpio0_led_default { + pinmux = ; + }; }; &uart0 { @@ -49,3 +64,9 @@ pinctrl-names = "default"; status = "okay"; }; + +&gpio0 { + pinctrl-0 = <&mcu_gpio0_led_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra_defconfig b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra_defconfig index 15d2b0f5b28..822222a8900 100644 --- a/boards/arm/am62x_m4/am62x_m4_phyboard_lyra_defconfig +++ b/boards/arm/am62x_m4/am62x_m4_phyboard_lyra_defconfig @@ -20,6 +20,9 @@ CONFIG_PINCTRL=y # Serial Driver CONFIG_SERIAL=y +# GPIO Driver +CONFIG_GPIO=y + # Enable Console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y From 71b0db21189b49b0402ecdf9fa03c26a6edf04ac Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 8 Sep 2023 21:08:51 -0500 Subject: [PATCH 3439/4498] dts: bindings: Add nxp,flexram binding Add binding for NXP FlexRAM Signed-off-by: Declan Snyder --- .../memory-controllers/nxp,flexram.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 dts/bindings/memory-controllers/nxp,flexram.yaml diff --git a/dts/bindings/memory-controllers/nxp,flexram.yaml b/dts/bindings/memory-controllers/nxp,flexram.yaml new file mode 100644 index 00000000000..76248c06394 --- /dev/null +++ b/dts/bindings/memory-controllers/nxp,flexram.yaml @@ -0,0 +1,52 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexRAM on-chip ram controller + +include: base.yaml + +compatible: "nxp,flexram" + +properties: + reg: + required: true + + interrupts: + required: true + + flexram,has-magic-addr: + type: boolean + description: | + Whether or not the flexram on the SOC has the + magic address feature, which allows for an interrupt + on arbitrary address access in any on chip RAM region. + + flexram,num-ram-banks: + type: int + required: true + description: | + Number of RAM banks in the SOC ram array + + flexram,bank-size: + type: int + required: true + description: | + Size of each RAM bank in KB + + flexram,bank-spec: + type: array + description: | + Custom mapping of runtime RAM bank partitions. If this + property is present, then it will be used. If this + property is not present, then the fusemap configuration + will be used. + + flexram,tcm-read-wait-mode: + type: boolean + description: | + TCM RAM read will finish in 2 cycles instead of 1. + + flexram,tcm-write-wait-mode: + type: boolean + description: | + TCM RAM write will finish in 2 cycles instead of 1. From 97d991f7d6d4628a6a742e2dcbb5503672342f26 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 8 Sep 2023 21:09:45 -0500 Subject: [PATCH 3440/4498] drivers: memc: Add NXP FlexRAM driver Add driver for NXP FlexRAM Signed-off-by: Declan Snyder --- drivers/memc/CMakeLists.txt | 1 + drivers/memc/Kconfig.mcux | 23 +- drivers/memc/memc_nxp_flexram.c | 231 ++++++++++++++++++ drivers/memc/memc_nxp_flexram.h | 98 ++++++++ .../memory-controller/nxp,flexram.h | 15 ++ 5 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 drivers/memc/memc_nxp_flexram.c create mode 100644 drivers/memc/memc_nxp_flexram.h create mode 100644 include/zephyr/dt-bindings/memory-controller/nxp,flexram.h diff --git a/drivers/memc/CMakeLists.txt b/drivers/memc/CMakeLists.txt index ca967b1a045..8aaedc22073 100644 --- a/drivers/memc/CMakeLists.txt +++ b/drivers/memc/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI memc_mcux_flexspi.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_W956A8MBYA memc_mcux_flexspi_w956a8mbya.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_S27KS0641 memc_mcux_flexspi_s27ks0641.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_APS6408L memc_mcux_flexspi_aps6408l.c) +zephyr_library_sources_ifdef(CONFIG_MEMC_NXP_FLEXRAM memc_nxp_flexram.c) zephyr_library_sources_ifdef(CONFIG_MEMC_SAM_SMC memc_sam_smc.c) diff --git a/drivers/memc/Kconfig.mcux b/drivers/memc/Kconfig.mcux index ed7e73929db..e801e7577ae 100644 --- a/drivers/memc/Kconfig.mcux +++ b/drivers/memc/Kconfig.mcux @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2022 NXP +# Copyright 2020-2023 NXP # Copyright (c) 2021 Basalte bv # Copyright (c) 2023, ithinx GmbH # Copyright (c) 2023, Tonies GmbH @@ -28,4 +28,23 @@ config MEMC_MCUX_FLEXSPI bool select PINCTRL -endif +endif # DT_HAS_NXP_IMX_FLEXSPI_ENABLED + + +if DT_HAS_NXP_FLEXRAM_ENABLED + +config MEMC_NXP_FLEXRAM + bool + default y + +config MEMC_NXP_FLEXRAM_MAGIC_ADDR_API + bool "NXP FlexRAM magic addr API" + help + Enable API to use flexRAM magic address functionality + +config MEMC_NXP_FLEXRAM_ERROR_INTERRUPT + bool "NXP FlexRAM error interrupt" + help + Allow flexram to generate error interrupts + +endif # DT_HAS_NXP_FLEXRAM_ENABLED diff --git a/drivers/memc/memc_nxp_flexram.c b/drivers/memc/memc_nxp_flexram.c new file mode 100644 index 00000000000..39da8349e1a --- /dev/null +++ b/drivers/memc/memc_nxp_flexram.c @@ -0,0 +1,231 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "memc_nxp_flexram.h" +#include +#include +#include +#include +#include +#include + +#include "fsl_device_registers.h" + + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) +BUILD_ASSERT(DT_PROP(FLEXRAM_DT_NODE, flexram_has_magic_addr), + "SOC does not support magic flexram addresses"); +#endif + +#define BANK_SIZE (DT_PROP(FLEXRAM_DT_NODE, flexram_bank_size) * 1024) +#define NUM_BANKS DT_PROP(FLEXRAM_DT_NODE, flexram_num_ram_banks) + +#define IS_CHILD_RAM_TYPE(node_id, compat) DT_NODE_HAS_COMPAT(node_id, compat) +#define DOES_RAM_TYPE_EXIST(compat) \ + DT_FOREACH_CHILD_SEP_VARGS(FLEXRAM_DT_NODE, IS_CHILD_RAM_TYPE, (+), compat) + +#if DOES_RAM_TYPE_EXIST(mmio_sram) +#define FIND_OCRAM_NODE(node_id) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, mmio_sram), (node_id), ()) +#define OCRAM_DT_NODE DT_FOREACH_CHILD(FLEXRAM_DT_NODE, FIND_OCRAM_NODE) +#define OCRAM_START (DT_REG_ADDR(OCRAM_DT_NODE)) +#define OCRAM_END (OCRAM_START + DT_REG_SIZE(OCRAM_DT_NODE)) +#endif /* OCRAM */ +#if DOES_RAM_TYPE_EXIST(nxp_imx_dtcm) +#define FIND_DTCM_NODE(node_id) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nxp_imx_dtcm), (node_id), ()) +#define DTCM_DT_NODE DT_FOREACH_CHILD(FLEXRAM_DT_NODE, FIND_DTCM_NODE) +#define DTCM_START (DT_REG_ADDR(DTCM_DT_NODE)) +#define DTCM_END (DTCM_START + DT_REG_SIZE(DTCM_DT_NODE)) +#endif /* DTCM */ +#if DOES_RAM_TYPE_EXIST(nxp_imx_itcm) +#define FIND_ITCM_NODE(node_id) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nxp_imx_itcm), (node_id), ()) +#define ITCM_DT_NODE DT_FOREACH_CHILD(FLEXRAM_DT_NODE, FIND_ITCM_NODE) +#define ITCM_START (DT_REG_ADDR(ITCM_DT_NODE)) +#define ITCM_END (ITCM_START + DT_REG_SIZE(ITCM_DT_NODE)) +#endif /* ITCM */ + + +#ifdef FLEXRAM_RUNTIME_BANKS_USED + +#define PLUS_ONE_BANK(node_id, prop, idx) 1 +#define COUNT_BANKS \ + DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec, PLUS_ONE_BANK, (+)) +BUILD_ASSERT(COUNT_BANKS == NUM_BANKS, "wrong number of flexram banks defined"); + +#ifdef OCRAM_DT_NODE +#define ADD_BANK_IF_OCRAM(node_id, prop, idx) \ + COND_CODE_1(IS_EQ(DT_PROP_BY_IDX(node_id, prop, idx), FLEXRAM_OCRAM), \ + (BANK_SIZE), (0)) +#define OCRAM_TOTAL \ + DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec, ADD_BANK_IF_OCRAM, (+)) +BUILD_ASSERT((OCRAM_TOTAL) == DT_REG_SIZE(OCRAM_DT_NODE), "OCRAM node size is wrong"); +#endif /* OCRAM */ + +#ifdef DTCM_DT_NODE +#define ADD_BANK_IF_DTCM(node_id, prop, idx) \ + COND_CODE_1(IS_EQ(DT_PROP_BY_IDX(node_id, prop, idx), FLEXRAM_DTCM), \ + (BANK_SIZE), (0)) +#define DTCM_TOTAL \ + DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec, ADD_BANK_IF_DTCM, (+)) +BUILD_ASSERT((DTCM_TOTAL) == DT_REG_SIZE(DTCM_DT_NODE), "DTCM node size is wrong"); +#endif /* DTCM */ + +#ifdef ITCM_DT_NODE +#define ADD_BANK_IF_ITCM(node_id, prop, idx) \ + COND_CODE_1(IS_EQ(DT_PROP_BY_IDX(node_id, prop, idx), FLEXRAM_ITCM), \ + (BANK_SIZE), (0)) +#define ITCM_TOTAL \ + DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec, ADD_BANK_IF_ITCM, (+)) +BUILD_ASSERT((ITCM_TOTAL) == DT_REG_SIZE(ITCM_DT_NODE), "ITCM node size is wrong"); +#endif /* ITCM */ + +#endif /* FLEXRAM_RUNTIME_BANKS_USED */ + +static FLEXRAM_Type *const base = (FLEXRAM_Type *) DT_REG_ADDR(FLEXRAM_DT_NODE); + +#ifdef FLEXRAM_INTERRUPTS_USED +static flexram_callback_t flexram_callback; +static void *flexram_user_data; + +void memc_flexram_register_callback(flexram_callback_t callback, void *user_data) +{ + flexram_callback = callback; + flexram_user_data = user_data; +} + +static void nxp_flexram_isr(void *arg) +{ + ARG_UNUSED(arg); + + if (flexram_callback == NULL) { + return; + } + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT) + if (base->INT_STATUS & FLEXRAM_INT_STATUS_OCRAM_ERR_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_OCRAM_ERR_STATUS_MASK; + flexram_callback(flexram_ocram_access_error, flexram_user_data); + } + if (base->INT_STATUS & FLEXRAM_INT_STATUS_DTCM_ERR_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_DTCM_ERR_STATUS_MASK; + flexram_callback(flexram_dtcm_access_error, flexram_user_data); + } + if (base->INT_STATUS & FLEXRAM_INT_STATUS_ITCM_ERR_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_ITCM_ERR_STATUS_MASK; + flexram_callback(flexram_itcm_access_error, flexram_user_data); + } +#endif /* CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT */ + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) + if (base->INT_STATUS & FLEXRAM_INT_STATUS_OCRAM_MAM_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_OCRAM_MAM_STATUS_MASK; + flexram_callback(flexram_ocram_magic_addr, flexram_user_data); + } + if (base->INT_STATUS & FLEXRAM_INT_STATUS_DTCM_MAM_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_DTCM_MAM_STATUS_MASK; + flexram_callback(flexram_dtcm_magic_addr, flexram_user_data); + } + if (base->INT_STATUS & FLEXRAM_INT_STATUS_ITCM_MAM_STATUS_MASK) { + base->INT_STATUS |= FLEXRAM_INT_STATUS_ITCM_MAM_STATUS_MASK; + flexram_callback(flexram_itcm_magic_addr, flexram_user_data); + } +#endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */ +} + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) +int memc_flexram_set_ocram_magic_addr(uint32_t ocram_addr) +{ +#ifdef OCRAM_DT_NODE + ocram_addr -= DT_REG_ADDR(OCRAM_DT_NODE); + if (ocram_addr >= DT_REG_SIZE(OCRAM_DT_NODE)) { + return -EINVAL; + } + + base->OCRAM_MAGIC_ADDR &= ~FLEXRAM_OCRAM_MAGIC_ADDR_OCRAM_MAGIC_ADDR_MASK; + base->OCRAM_MAGIC_ADDR |= FLEXRAM_OCRAM_MAGIC_ADDR_OCRAM_MAGIC_ADDR(ocram_addr); + + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_OCRAM_MAM_STAT_EN_MASK; + return 0; +#else + return -ENODEV; +#endif +} + +int memc_flexram_set_itcm_magic_addr(uint32_t itcm_addr) +{ +#ifdef ITCM_DT_NODE + itcm_addr -= DT_REG_ADDR(ITCM_DT_NODE); + if (itcm_addr >= DT_REG_SIZE(ITCM_DT_NODE)) { + return -EINVAL; + } + + base->ITCM_MAGIC_ADDR &= ~FLEXRAM_ITCM_MAGIC_ADDR_ITCM_MAGIC_ADDR_MASK; + base->ITCM_MAGIC_ADDR |= FLEXRAM_ITCM_MAGIC_ADDR_ITCM_MAGIC_ADDR(itcm_addr); + + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_ITCM_MAM_STAT_EN_MASK; + return 0; +#else + return -ENODEV; +#endif +} + +int memc_flexram_set_dtcm_magic_addr(uint32_t dtcm_addr) +{ +#ifdef DTCM_DT_NODE + dtcm_addr -= DT_REG_ADDR(DTCM_DT_NODE); + if (dtcm_addr >= DT_REG_SIZE(DTCM_DT_NODE)) { + return -EINVAL; + } + + base->DTCM_MAGIC_ADDR &= ~FLEXRAM_DTCM_MAGIC_ADDR_DTCM_MAGIC_ADDR_MASK; + base->DTCM_MAGIC_ADDR |= FLEXRAM_DTCM_MAGIC_ADDR_DTCM_MAGIC_ADDR(dtcm_addr); + + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_DTCM_MAM_STAT_EN_MASK; + return 0; +#else + return -ENODEV; +#endif +} +#endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */ + +#endif /* FLEXRAM_INTERRUPTS_USED */ + +static int nxp_flexram_init(void) +{ + if (DT_PROP(FLEXRAM_DT_NODE, flexram_tcm_read_wait_mode)) { + base->TCM_CTRL |= FLEXRAM_TCM_CTRL_TCM_WWAIT_EN_MASK; + } + if (DT_PROP(FLEXRAM_DT_NODE, flexram_tcm_write_wait_mode)) { + base->TCM_CTRL |= FLEXRAM_TCM_CTRL_TCM_RWAIT_EN_MASK; + } + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT) + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_OCRAM_ERR_SIG_EN_MASK; + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_DTCM_ERR_SIG_EN_MASK; + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_ITCM_ERR_SIG_EN_MASK; + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_OCRAM_ERR_STAT_EN_MASK; + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_DTCM_ERR_STAT_EN_MASK; + base->INT_STAT_EN |= FLEXRAM_INT_STAT_EN_ITCM_ERR_STAT_EN_MASK; +#endif /* CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT */ + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_OCRAM_MAM_SIG_EN_MASK; + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_DTCM_MAM_SIG_EN_MASK; + base->INT_SIG_EN |= FLEXRAM_INT_SIG_EN_ITCM_MAM_SIG_EN_MASK; +#endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */ + +#ifdef FLEXRAM_INTERRUPTS_USED + IRQ_CONNECT(DT_IRQN(FLEXRAM_DT_NODE), DT_IRQ(FLEXRAM_DT_NODE, priority), + nxp_flexram_isr, NULL, 0); + irq_enable(DT_IRQN(FLEXRAM_DT_NODE)); +#endif /* FLEXRAM_INTERRUPTS_USED */ + + return 0; +} + +SYS_INIT(nxp_flexram_init, EARLY, 0); diff --git a/drivers/memc/memc_nxp_flexram.h b/drivers/memc/memc_nxp_flexram.h new file mode 100644 index 00000000000..34f606e6b86 --- /dev/null +++ b/drivers/memc/memc_nxp_flexram.h @@ -0,0 +1,98 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define FLEXRAM_DT_NODE DT_INST(0, nxp_flexram) +#define IOMUXC_GPR_DT_NODE DT_INST(0, nxp_imx_gpr) + +#if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) || \ + defined(CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT) +#define FLEXRAM_INTERRUPTS_USED +#endif + +#if DT_PROP_HAS_IDX(FLEXRAM_DT_NODE, flexram_bank_spec, 0) +#define FLEXRAM_RUNTIME_BANKS_USED 1 +#endif + +#ifdef FLEXRAM_INTERRUPTS_USED +enum memc_flexram_interrupt_cause { +#ifdef CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT + flexram_ocram_access_error, + flexram_itcm_access_error, + flexram_dtcm_access_error, +#endif +#ifdef CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API + flexram_ocram_magic_addr, + flexram_itcm_magic_addr, + flexram_dtcm_magic_addr, +#endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */ +}; + +typedef void (*flexram_callback_t)(enum memc_flexram_interrupt_cause, void *user_data); + +void memc_flexram_register_callback(flexram_callback_t callback, void *user_data); +#endif /* FLEXRAM_INTERRUPTS_USED */ + +#ifdef FLEXRAM_RUNTIME_BANKS_USED + +/* + * call from platform_init to set up flexram if using runtime map + * must be inlined because cannot use stack + */ +#define GPR17_REG_FILL(node_id, prop, idx) + (DT_PROP_BY_IDX(node_id, prop, idx) << idx) +static inline void memc_flexram_dt_partition(void) +{ + /* iomuxc_gpr must be const (in ROM region) because used in reconfiguring ram */ + static IOMUXC_GPR_Type *const iomuxc_gpr = + (IOMUXC_GPR_Type *) DT_REG_ADDR(IOMUXC_GPR_DT_NODE); + /* do not create stack variables or use any data from ram in this function */ + iomuxc_gpr->GPR17 = DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, + flexram_bank_spec, GPR17_REG_FILL, (+)); + iomuxc_gpr->GPR16 |= IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL_MASK; +} +#endif /* FLEXRAM_RUNTIME_BANKS_USED */ + + +#ifdef CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API +/** @brief Sets magic address for OCRAM + * + * Magic address allows core interrupt from FlexRAM when address + * is accessed. + * + * @param ocram_addr: An address in OCRAM to set magic function on. + * @retval 0 on success + * @retval -EINVAL if ocram_addr is not in OCRAM + * @retval -ENODEV if there is no OCRAM allocation in flexram + */ +int memc_flexram_set_ocram_magic_addr(uint32_t ocram_addr); + +/** @brief Sets magic address for ITCM + * + * Magic address allows core interrupt from FlexRAM when address + * is accessed. + * + * @param itcm_addr: An address in ITCM to set magic function on. + * @retval 0 on success + * @retval -EINVAL if itcm_addr is not in ITCM + * @retval -ENODEV if there is no ITCM allocation in flexram + */ +int memc_flexram_set_itcm_magic_addr(uint32_t itcm_addr); + +/** @brief Sets magic address for DTCM + * + * Magic address allows core interrupt from FlexRAM when address + * is accessed. + * + * @param dtcm_addr: An address in DTCM to set magic function on. + * @retval 0 on success + * @retval -EINVAL if dtcm_addr is not in DTCM + * @retval -ENODEV if there is no DTCM allocation in flexram + */ +int memc_flexram_set_dtcm_magic_addr(uint32_t dtcm_addr); + +#endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */ diff --git a/include/zephyr/dt-bindings/memory-controller/nxp,flexram.h b/include/zephyr/dt-bindings/memory-controller/nxp,flexram.h new file mode 100644 index 00000000000..2c35e655fc9 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-controller/nxp,flexram.h @@ -0,0 +1,15 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEMORY_CONTROLLER_NXP_FLEXRAM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEMORY_CONTROLLER_NXP_FLEXRAM_H_ + +#define FLEXRAM_NONE 0 +#define FLEXRAM_OCRAM 1 +#define FLEXRAM_DTCM 2 +#define FLEXRAM_ITCM 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEMORY_CONTROLLER_NXP_FLEXRAM_H_ */ From 2d1fdb5586d219bb1e27e5e335bd216bf46a09c9 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 14 Sep 2023 19:40:17 -0500 Subject: [PATCH 3441/4498] soc: nxp: rt1xxx: Enable NXP FlexRAM Enable NXP FlexRAM in DTS and SOC code. Do not configure flexram at runtime if the code is in the RAM. Fix RT1060 DT to be more accurate. Signed-off-by: Declan Snyder --- dts/arm/nxp/nxp_rt1010.dtsi | 9 +++++ dts/arm/nxp/nxp_rt1015.dtsi | 9 +++++ dts/arm/nxp/nxp_rt1020.dtsi | 13 ++++++ dts/arm/nxp/nxp_rt1024.dtsi | 13 ++++++ dts/arm/nxp/nxp_rt1040.dtsi | 4 ++ dts/arm/nxp/nxp_rt1050.dtsi | 21 ++++++++++ dts/arm/nxp/nxp_rt1060.dtsi | 44 ++++++++++++++++----- dts/arm/nxp/nxp_rt1064.dtsi | 21 ++++++++++ dts/arm/nxp/nxp_rt10xx.dtsi | 7 +++- dts/arm/nxp/nxp_rt11xx_cm7.dtsi | 28 ++++++++++++- soc/arm/nxp_imx/rt/CMakeLists.txt | 3 ++ soc/arm/nxp_imx/rt/Kconfig.defconfig.series | 3 ++ soc/arm/nxp_imx/rt/soc_rt10xx.c | 7 ++++ soc/arm/nxp_imx/rt/soc_rt11xx.c | 8 +++- 14 files changed, 178 insertions(+), 12 deletions(-) diff --git a/dts/arm/nxp/nxp_rt1010.dtsi b/dts/arm/nxp/nxp_rt1010.dtsi index 1afed91a45c..84d47e0f35e 100644 --- a/dts/arm/nxp/nxp_rt1010.dtsi +++ b/dts/arm/nxp/nxp_rt1010.dtsi @@ -6,6 +6,15 @@ #include +&flexram { + flexram,num-ram-banks = <4>; + /* default fuse */ + flexram,bank-spec = , + , + , + ; +}; + &sysclk { clock-frequency = <500000000>; }; diff --git a/dts/arm/nxp/nxp_rt1015.dtsi b/dts/arm/nxp/nxp_rt1015.dtsi index 05aeeb86be1..59c62eb4452 100644 --- a/dts/arm/nxp/nxp_rt1015.dtsi +++ b/dts/arm/nxp/nxp_rt1015.dtsi @@ -7,6 +7,15 @@ #include +&flexram { + flexram,num-ram-banks = <4>; + /* default fuse */ + flexram,bank-spec = , + , + , + ; +}; + &sysclk { clock-frequency = <500000000>; }; diff --git a/dts/arm/nxp/nxp_rt1020.dtsi b/dts/arm/nxp/nxp_rt1020.dtsi index 6b2a26f5242..b42a17960fa 100644 --- a/dts/arm/nxp/nxp_rt1020.dtsi +++ b/dts/arm/nxp/nxp_rt1020.dtsi @@ -7,6 +7,19 @@ #include +&flexram { + flexram,num-ram-banks = <8>; + /* default fuse */ + flexram,bank-spec = , + , + , + , + , + , + , + ; +}; + &sysclk { clock-frequency = <500000000>; }; diff --git a/dts/arm/nxp/nxp_rt1024.dtsi b/dts/arm/nxp/nxp_rt1024.dtsi index c8332df17e0..62262bb2118 100644 --- a/dts/arm/nxp/nxp_rt1024.dtsi +++ b/dts/arm/nxp/nxp_rt1024.dtsi @@ -7,6 +7,19 @@ #include +&flexram { + flexram,num-ram-banks = <8>; + /* default fuse */ + flexram,bank-spec = , + , + , + , + , + , + , + ; +}; + &sysclk { clock-frequency = <500000000>; }; diff --git a/dts/arm/nxp/nxp_rt1040.dtsi b/dts/arm/nxp/nxp_rt1040.dtsi index 110680f44a7..c4aa2d57891 100644 --- a/dts/arm/nxp/nxp_rt1040.dtsi +++ b/dts/arm/nxp/nxp_rt1040.dtsi @@ -6,6 +6,10 @@ #include +&flexram { + flexram,num-ram-banks = <16>; +}; + &sysclk { clock-frequency = <500000000>; }; diff --git a/dts/arm/nxp/nxp_rt1050.dtsi b/dts/arm/nxp/nxp_rt1050.dtsi index 16b2669b416..0a66b9b791e 100644 --- a/dts/arm/nxp/nxp_rt1050.dtsi +++ b/dts/arm/nxp/nxp_rt1050.dtsi @@ -5,6 +5,27 @@ */ #include +&flexram { + flexram,num-ram-banks = <16>; + /* default fuse */ + flexram,bank-spec = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; +}; + &ccm { arm-podf { clock-div = <2>; diff --git a/dts/arm/nxp/nxp_rt1060.dtsi b/dts/arm/nxp/nxp_rt1060.dtsi index 62e01a5f609..8a9cba715e0 100644 --- a/dts/arm/nxp/nxp_rt1060.dtsi +++ b/dts/arm/nxp/nxp_rt1060.dtsi @@ -6,14 +6,33 @@ #include -/* i.MX rt1060 has two continuous on-chip RAM, one is part of the - * FlexRAM mapped at 0x20280000 (vs 0x20280000 on rt1050) and is - * configurable (256KB by defaults), the other one is dedicated 512KB - * ram (OCRAM2) mapped at 0x20200000. In order to have a continuous - * region, we describe them in one 768Kb unique node. - */ -&ocram { - reg = <0x20200000 DT_SIZE_K(768)>; +&flexram { + /* FlexRAM OCRAM is at a different address on RT1060 */ + /delete-node/ ocram@20200000; + ocram: ocram@20280000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20280000 DT_SIZE_K(256)>; + zephyr,memory-region = "OCRAM"; + }; + + flexram,num-ram-banks = <16>; + /* default fuse */ + flexram,bank-spec = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; &ccm { @@ -26,9 +45,9 @@ }; }; -/* i.MX rt1060 has a second Ethernet controller. */ / { soc { + /* i.MX rt1060 has a second Ethernet controller. */ enet2: ethernet@402d4000 { compatible = "nxp,kinetis-ethernet"; reg = <0x402D4000 0x628>; @@ -42,6 +61,13 @@ interrupt-names = "IEEE1588_TMR"; }; }; + + /* RT1060 has a dedicated OCRAM region */ + ocram2: ocram@20200000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20200000 DT_SIZE_K(512)>; + zephyr,memory-region = "OCRAM2"; + }; }; }; diff --git a/dts/arm/nxp/nxp_rt1064.dtsi b/dts/arm/nxp/nxp_rt1064.dtsi index fcb909e0cfc..73ed8827738 100644 --- a/dts/arm/nxp/nxp_rt1064.dtsi +++ b/dts/arm/nxp/nxp_rt1064.dtsi @@ -7,6 +7,27 @@ #include +&flexram { + flexram,num-ram-banks = <16>; + /* default fuse */ + flexram,bank-spec = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; +}; + &flexspi2 { status = "okay"; reg = <0x402a4000 0x4000>, <0x70000000 DT_SIZE_M(4)>; diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index 23bd7255301..e7e4e6448b2 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include / { chosen { @@ -87,13 +88,17 @@ soc { flexram: flexram@400b0000 { - compatible = "nxp,imx-flexram"; + compatible = "nxp,flexram"; reg = <0x400b0000 0x4000>; interrupts = <38 0>; #address-cells = <1>; #size-cells = <1>; + status = "okay"; + + flexram,bank-size = <32>; + itcm: itcm@0 { compatible = "zephyr,memory-region", "nxp,imx-itcm"; reg = <0x00000000 DT_SIZE_K(128)>; diff --git a/dts/arm/nxp/nxp_rt11xx_cm7.dtsi b/dts/arm/nxp/nxp_rt11xx_cm7.dtsi index 28cc4ff020d..88d1035ddc3 100644 --- a/dts/arm/nxp/nxp_rt11xx_cm7.dtsi +++ b/dts/arm/nxp/nxp_rt11xx_cm7.dtsi @@ -1,10 +1,11 @@ /* - * Copyright (c) 2021, NXP + * Copyright 2021-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include +#include / { cpus { @@ -22,12 +23,35 @@ /delete-node/ dma-controller@40c14000; flexram: flexram@40028000 { + compatible = "nxp,flexram"; + reg = <0x40028000 0x4000>; interrupts = <50 0>; #address-cells = <1>; #size-cells = <1>; + flexram,bank-size = <32>; + flexram,num-ram-banks = <16>; + flexram,has-magic-addr; + /* same as default fuse value */ + flexram,bank-spec = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + itcm: itcm@0 { compatible = "zephyr,memory-region", "nxp,imx-itcm"; reg = <0x00000000 DT_SIZE_K(256)>; @@ -39,6 +63,8 @@ reg = <0x20000000 DT_SIZE_K(256)>; zephyr,memory-region = "DTCM"; }; + + /* no ocram node for this bank-spec */ }; /* diff --git a/soc/arm/nxp_imx/rt/CMakeLists.txt b/soc/arm/nxp_imx/rt/CMakeLists.txt index 125db4957f8..92ab665a0ef 100644 --- a/soc/arm/nxp_imx/rt/CMakeLists.txt +++ b/soc/arm/nxp_imx/rt/CMakeLists.txt @@ -50,6 +50,9 @@ zephyr_compile_definitions_ifdef(CONFIG_ENTROPY_MCUX_CAAM CACHE_MODE_WRITE_THROU zephyr_compile_definitions_ifdef(CONFIG_USB_DEVICE_DRIVER DATA_SECTION_IS_CACHEABLE=1) +# flexram header +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/memc) + zephyr_linker_section_configure( SECTION .rom_start INPUT ".boot_hdr.ivt" diff --git a/soc/arm/nxp_imx/rt/Kconfig.defconfig.series b/soc/arm/nxp_imx/rt/Kconfig.defconfig.series index 7a1aac41ce3..b4e8aeb7422 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.defconfig.series +++ b/soc/arm/nxp_imx/rt/Kconfig.defconfig.series @@ -92,6 +92,9 @@ config FLASH_SIZE default $(dt_node_int_prop_int,$(DT_CHOSEN_FLASH_NODE),size,Kb) \ if $(DT_FLASH_HAS_SIZE_PROP) +config MEMC + default y + choice USB_MCUX_CONTROLLER_TYPE default USB_DC_NXP_EHCI endchoice diff --git a/soc/arm/nxp_imx/rt/soc_rt10xx.c b/soc/arm/nxp_imx/rt/soc_rt10xx.c index ba22a633a50..91ec748a61a 100644 --- a/soc/arm/nxp_imx/rt/soc_rt10xx.c +++ b/soc/arm/nxp_imx/rt/soc_rt10xx.c @@ -21,6 +21,8 @@ #include "usb.h" #endif +#include "memc_nxp_flexram.h" + #include #define CCM_NODE DT_INST(0, nxp_imx_ccm) @@ -345,6 +347,11 @@ void z_arm_platform_init(void) { /* Call CMSIS SystemInit */ SystemInit(); + +#if defined(FLEXRAM_RUNTIME_BANKS_USED) + /* Configure flexram if not running from RAM */ + memc_flexram_dt_partition(); +#endif } #endif diff --git a/soc/arm/nxp_imx/rt/soc_rt11xx.c b/soc/arm/nxp_imx/rt/soc_rt11xx.c index ca3ebd08c66..f9eb7b7e381 100644 --- a/soc/arm/nxp_imx/rt/soc_rt11xx.c +++ b/soc/arm/nxp_imx/rt/soc_rt11xx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NXP + * Copyright 2021-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,6 +33,7 @@ #include "usb_phy.h" #include "usb.h" #endif +#include "memc_nxp_flexram.h" #include @@ -689,6 +690,11 @@ static int imxrt_init(void) void z_arm_platform_init(void) { SystemInit(); + +#if defined(FLEXRAM_RUNTIME_BANKS_USED) + /* Configure flexram if not running from RAM */ + memc_flexram_dt_partition(); +#endif } #endif From 31eb944fcdf0d30630d56a76ac543c7c5dce34d9 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 14 Sep 2023 23:25:32 -0500 Subject: [PATCH 3442/4498] samples: boards: mimxrt11xx_cm7: Magic addr sample Add magic address sample to show how to use flexram magic address using memc flexram driver. Signed-off-by: Declan Snyder --- .../magic_addr/CMakeLists.txt | 10 ++++ .../mimxrt1170_evk_cm7/magic_addr/README.rst | 18 ++++++ .../mimxrt1170_evk_cm7/magic_addr/prj.conf | 3 + .../mimxrt1170_evk_cm7/magic_addr/sample.yaml | 12 ++++ .../mimxrt1170_evk_cm7/magic_addr/src/main.c | 58 +++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 samples/boards/mimxrt1170_evk_cm7/magic_addr/CMakeLists.txt create mode 100644 samples/boards/mimxrt1170_evk_cm7/magic_addr/README.rst create mode 100644 samples/boards/mimxrt1170_evk_cm7/magic_addr/prj.conf create mode 100644 samples/boards/mimxrt1170_evk_cm7/magic_addr/sample.yaml create mode 100644 samples/boards/mimxrt1170_evk_cm7/magic_addr/src/main.c diff --git a/samples/boards/mimxrt1170_evk_cm7/magic_addr/CMakeLists.txt b/samples/boards/mimxrt1170_evk_cm7/magic_addr/CMakeLists.txt new file mode 100644 index 00000000000..b8af716702a --- /dev/null +++ b/samples/boards/mimxrt1170_evk_cm7/magic_addr/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(magic_addr) + +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/memc) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/mimxrt1170_evk_cm7/magic_addr/README.rst b/samples/boards/mimxrt1170_evk_cm7/magic_addr/README.rst new file mode 100644 index 00000000000..679343d84ff --- /dev/null +++ b/samples/boards/mimxrt1170_evk_cm7/magic_addr/README.rst @@ -0,0 +1,18 @@ +.. _flexram_magic_addr: + +FLEXRAM Magic Addr +################## + +Overview +******** + +A sample that shows how to use RT11XX FLEXRAM Magic Addr functionality + +Magic Addr is a feature of FlexRAM that allows user to configure an interrupt +on an arbitrary RAM/TCM address access. This sample shows how to use the custom +API for the flexram in zephyr to use this unique feature. + +Building and Running +******************** + +see board documentation diff --git a/samples/boards/mimxrt1170_evk_cm7/magic_addr/prj.conf b/samples/boards/mimxrt1170_evk_cm7/magic_addr/prj.conf new file mode 100644 index 00000000000..b58887f4998 --- /dev/null +++ b/samples/boards/mimxrt1170_evk_cm7/magic_addr/prj.conf @@ -0,0 +1,3 @@ +CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API=y +CONFIG_CONSOLE_SUBSYS=y +CONFIG_CONSOLE_GETCHAR=y diff --git a/samples/boards/mimxrt1170_evk_cm7/magic_addr/sample.yaml b/samples/boards/mimxrt1170_evk_cm7/magic_addr/sample.yaml new file mode 100644 index 00000000000..10e876847f7 --- /dev/null +++ b/samples/boards/mimxrt1170_evk_cm7/magic_addr/sample.yaml @@ -0,0 +1,12 @@ +sample: + description: RT1170 FLEXRAM Magic Addr example + name: magic addr +common: + integration_platforms: + - mimxrt1170_evk_cm7 + - mimxrt1160_evk_cm7 +tests: + sample.boards.mimxrt1170_evk.magic_addr: + platform_allow: + - mimxrt1170_evk_cm7 + - mimxrt1160_evk_cm7 diff --git a/samples/boards/mimxrt1170_evk_cm7/magic_addr/src/main.c b/samples/boards/mimxrt1170_evk_cm7/magic_addr/src/main.c new file mode 100644 index 00000000000..6856ca8f10f --- /dev/null +++ b/samples/boards/mimxrt1170_evk_cm7/magic_addr/src/main.c @@ -0,0 +1,58 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "memc_nxp_flexram.h" +#include +#include +#include + +K_SEM_DEFINE(dtcm_magic, 0, 1); + +__dtcm_bss_section uint8_t var; +int cnt; + +void flexram_magic_addr_isr_cb(enum memc_flexram_interrupt_cause cause, + void *data) +{ + ARG_UNUSED(data); + + if (cause == flexram_dtcm_magic_addr) { + printf("Magic DTCM address accessed %d times\n", ++cnt); + k_sem_give(&dtcm_magic); + } +} + + +int main(void) +{ + memc_flexram_register_callback(flexram_magic_addr_isr_cb, NULL); + + console_init(); + + printf("%s is opening spellbook...\n", CONFIG_BOARD); + printf("Cast some characters:\n"); + + uint32_t dtcm_addr = (uint32_t)&var; + + memc_flexram_set_dtcm_magic_addr(dtcm_addr); + + uint8_t tmp; + + while (1) { + printf("\n"); + tmp = console_getchar(); + printf("Writing %c to magic addr...\n", tmp); + var = tmp; + k_sem_take(&dtcm_magic, K_FOREVER); + printf("Reading from magic addr...\n"); + printf("Magic variable got: %c\n", var); + k_sem_take(&dtcm_magic, K_FOREVER); + } + + return 0; +} From c35e677d823d4684fc26beeeaac154b1b83ddc3f Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 28 Sep 2023 11:57:43 +0200 Subject: [PATCH 3443/4498] Bluetooth: Audio: Split ltv_set_val from codec_cfg_set_val Add a new function, ltv_set_val, that did most of the data manipulation from codec_cfg_set_val, so that we can reuse that code for the codec cap and codec meta functions as well. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/codec.c | 184 ++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 83 deletions(-) diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 5b064987a25..1c156d87028 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -112,6 +112,11 @@ int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us) } } +#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 || \ + CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ + CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 || \ + CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 + struct search_type_param { bool found; uint8_t type; @@ -134,6 +139,94 @@ static bool parse_cb(struct bt_data *data, void *user_data) return true; } +static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t *data, + size_t data_len) +{ + for (uint16_t i = 0U; i < buf->len;) { + uint8_t *len = &buf->data[i++]; + const uint8_t data_type = buf->data[i++]; + const uint8_t value_len = *len - sizeof(data_type); + + if (data_type == type) { + uint8_t *value = &buf->data[i]; + + if (data_len == value_len) { + memcpy(value, data, data_len); + } else { + const int16_t diff = data_len - value_len; + uint8_t *old_next_data_start; + uint8_t *new_next_data_start; + uint8_t data_len_to_move; + + /* Check if this is the last value in the buffer */ + if (value + value_len == buf->data + buf->len) { + data_len_to_move = 0U; + } else { + old_next_data_start = value + value_len + 1; + new_next_data_start = value + data_len + 1; + data_len_to_move = + buf->len - (old_next_data_start - buf->data); + } + + if (diff < 0) { + /* In this case we need to move memory around after the copy + * to fit the new shorter data + */ + + memcpy(value, data, data_len); + if (data_len_to_move > 0U) { + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + } + } else { + /* In this case we need to move memory around before + * the copy to fit the new longer data + */ + if ((buf->len + diff) > buf->size) { + LOG_DBG("Cannot fit data_len %zu in buf with len " + "%u and size %u", + data_len, buf->len, buf->size); + return -ENOMEM; + } + + if (data_len_to_move > 0) { + memmove(new_next_data_start, old_next_data_start, + data_len_to_move); + } + memcpy(value, data, data_len); + } + + buf->len += diff; + *len += diff; + } + + return buf->len; + } + + i += value_len; + } + + /* If we reach here, we did not find the data in the buffer, so we simply add it */ + if ((buf->len + data_len) <= buf->size) { + net_buf_simple_add_u8(buf, data_len + sizeof(type)); + net_buf_simple_add_u8(buf, type); + if (data_len > 0) { + net_buf_simple_add_mem(buf, data, data_len); + } + } else { + LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len, + buf->len, buf->size); + return -ENOMEM; + } + + return buf->len; +} +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 || \ + * CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ + * CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 || \ + * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ + */ + #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf, @@ -185,6 +278,9 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t *data, size_t data_len) { + struct net_buf_simple buf; + int ret; + CHECKIF(codec_cfg == NULL) { LOG_DBG("codec_cfg is NULL"); return -EINVAL; @@ -200,92 +296,14 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ return -EINVAL; } - for (uint16_t i = 0U; i < codec_cfg->data_len;) { - uint8_t *len = &codec_cfg->data[i++]; - const uint8_t data_type = codec_cfg->data[i++]; - const uint8_t value_len = *len - sizeof(data_type); - - if (data_type == type) { - uint8_t *value = &codec_cfg->data[i]; - - if (data_len == value_len) { - memcpy(value, data, data_len); - } else { - const int16_t diff = data_len - value_len; - uint8_t *old_next_data_start; - uint8_t *new_next_data_start; - uint8_t data_len_to_move; - - /* Check if this is the last value in the buffer */ - if (value + value_len == codec_cfg->data + codec_cfg->data_len) { - data_len_to_move = 0U; - } else { - old_next_data_start = value + value_len + 1; - new_next_data_start = value + data_len + 1; - data_len_to_move = codec_cfg->data_len - - (old_next_data_start - codec_cfg->data); - } - - if (diff < 0) { - /* In this case we need to move memory around after the copy - * to fit the new shorter data - */ - - memcpy(value, data, data_len); - if (data_len_to_move > 0U) { - memmove(new_next_data_start, old_next_data_start, - data_len_to_move); - } - } else { - /* In this case we need to move memory around before - * the copy to fit the new longer data - */ - if ((codec_cfg->data_len + diff) > - ARRAY_SIZE(codec_cfg->data)) { - LOG_DBG("Cannot fit data_len %zu in buf with len " - "%u and size %u", - data_len, codec_cfg->data_len, - ARRAY_SIZE(codec_cfg->data)); - return -ENOMEM; - } - - if (data_len_to_move > 0) { - memmove(new_next_data_start, old_next_data_start, - data_len_to_move); - } - - memcpy(value, data, data_len); - } - - codec_cfg->data_len += diff; - *len += diff; - } - - return codec_cfg->data_len; - } - - i += value_len; - } - - /* If we reach here, we did not find the data in the buffer, so we simply add it */ - if ((codec_cfg->data_len + data_len) <= ARRAY_SIZE(codec_cfg->data)) { - struct net_buf_simple buf; - - init_net_buf_simple_from_codec_cfg(&buf, codec_cfg); + init_net_buf_simple_from_codec_cfg(&buf, codec_cfg); - net_buf_simple_add_u8(&buf, data_len + sizeof(type)); - net_buf_simple_add_u8(&buf, type); - if (data_len > 0) { - net_buf_simple_add_mem(&buf, data, data_len); - } - codec_cfg->data_len = buf.len; - } else { - LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len, - codec_cfg->data_len, ARRAY_SIZE(codec_cfg->data)); - return -ENOMEM; + ret = ltv_set_val(&buf, type, data, data_len); + if (ret >= 0) { + codec_cfg->data_len = ret; } - return codec_cfg->data_len; + return ret; } int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) From de0c543e6243d69726cbbc3712bf112c9e2f7324 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 28 Sep 2023 14:13:21 +0200 Subject: [PATCH 3444/4498] Bluetooth: Audio: Update some codec cap assigned numbers Update codec capabiliy frequency, frame duration and channel count to use enums, and add additional documentation and missing values. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/lc3.h | 184 ++++++++++++++++++--------- 1 file changed, 123 insertions(+), 61 deletions(-) diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 80fec536f89..ab42f9fdbdf 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -67,67 +67,129 @@ enum bt_audio_codec_capability_type { BT_AUDIO_CODEC_LC3_FRAME_COUNT = 0x05, }; -/** - * @brief LC3 8 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_8KHZ BIT(0) -/** - * @brief LC3 11.025 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_11KHZ BIT(1) -/** - * @brief LC3 16 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_16KHZ BIT(2) -/** - * @brief LC3 22.05 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_22KHZ BIT(3) -/** - * @brief LC3 24 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_24KHZ BIT(4) -/** - * @brief LC3 32 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_32KHZ BIT(5) -/** - * @brief LC3 44.1 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_44KHZ BIT(6) -/** - * @brief LC3 48 Khz frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_48KHZ BIT(7) -/** - * @brief LC3 any frequency capability - */ -#define BT_AUDIO_CODEC_LC3_FREQ_ANY \ - (BT_AUDIO_CODEC_LC3_FREQ_8KHZ | BT_AUDIO_CODEC_LC3_FREQ_16KHZ | \ - BT_AUDIO_CODEC_LC3_FREQ_24KHZ | BT_AUDIO_CODEC_LC3_FREQ_32KHZ | \ - BT_AUDIO_CODEC_LC3_FREQ_44KHZ | BT_AUDIO_CODEC_LC3_FREQ_48KHZ) +/** @brief Supported frequencies bitfield */ +enum bt_audio_codec_cap_freq { + /** + * @brief LC3 8 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_8KHZ = BIT(0), + /** + * @brief LC3 11.025 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_11KHZ = BIT(1), + /** + * @brief LC3 16 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_16KHZ = BIT(2), + /** + * @brief LC3 22.05 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_22KHZ = BIT(3), + /** + * @brief LC3 24 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_24KHZ = BIT(4), + /** + * @brief LC3 32 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_32KHZ = BIT(5), + /** + * @brief LC3 44.1 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_44KHZ = BIT(6), + /** + * @brief LC3 48 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_48KHZ = BIT(7), + /** + * @brief LC3 88.2 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_88KHZ = BIT(8), + /** + * @brief LC3 96 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_96KHZ = BIT(9), + /** + * @brief LC3 176.4 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_176KHZ = BIT(10), + /** + * @brief LC3 192 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_192KHZ = BIT(11), + /** + * @brief LC3 384 Khz frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_384KHZ = BIT(12), + /** + * @brief LC3 any frequency capability + */ + BT_AUDIO_CODEC_LC3_FREQ_ANY = + (BT_AUDIO_CODEC_LC3_FREQ_8KHZ | BT_AUDIO_CODEC_LC3_FREQ_11KHZ | + BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_22KHZ | + BT_AUDIO_CODEC_LC3_FREQ_24KHZ | BT_AUDIO_CODEC_LC3_FREQ_32KHZ | + BT_AUDIO_CODEC_LC3_FREQ_44KHZ | BT_AUDIO_CODEC_LC3_FREQ_48KHZ | + BT_AUDIO_CODEC_LC3_FREQ_88KHZ | BT_AUDIO_CODEC_LC3_FREQ_96KHZ | + BT_AUDIO_CODEC_LC3_FREQ_176KHZ | BT_AUDIO_CODEC_LC3_FREQ_192KHZ | + BT_AUDIO_CODEC_LC3_FREQ_384KHZ), +}; -/** - * @brief LC3 7.5 msec frame duration capability - */ -#define BT_AUDIO_CODEC_LC3_DURATION_7_5 BIT(0) -/** - * @brief LC3 10 msec frame duration capability - */ -#define BT_AUDIO_CODEC_LC3_DURATION_10 BIT(1) -/** - * @brief LC3 any frame duration capability - */ -#define BT_AUDIO_CODEC_LC3_DURATION_ANY \ - (BT_AUDIO_CODEC_LC3_DURATION_7_5 | BT_AUDIO_CODEC_LC3_DURATION_10) -/** - * @brief LC3 7.5 msec preferred frame duration capability - */ -#define BT_AUDIO_CODEC_LC3_DURATION_PREFER_7_5 BIT(4) -/** - * @brief LC3 10 msec preferred frame duration capability - */ -#define BT_AUDIO_CODEC_LC3_DURATION_PREFER_10 BIT(5) +/** @brief Supported frame durations bitfield */ +enum bt_audio_codec_cap_frame_dur { + /** + * @brief LC3 7.5 msec frame duration capability + */ + BT_AUDIO_CODEC_LC3_DURATION_7_5 = BIT(0), + /** + * @brief LC3 10 msec frame duration capability + */ + BT_AUDIO_CODEC_LC3_DURATION_10 = BIT(1), + /** + * @brief LC3 any frame duration capability + */ + BT_AUDIO_CODEC_LC3_DURATION_ANY = + (BT_AUDIO_CODEC_LC3_DURATION_7_5 | BT_AUDIO_CODEC_LC3_DURATION_10), + + /** + * @brief LC3 7.5 msec preferred frame duration capability. + * + * This shall only be set if @ref BT_AUDIO_CODEC_LC3_DURATION_7_5 is also set, and if @ref + * BT_AUDIO_CODEC_LC3_DURATION_PREFER_10 is not set. + */ + BT_AUDIO_CODEC_LC3_DURATION_PREFER_7_5 = BIT(4), + /** + * @brief LC3 10 msec preferred frame duration capability + * + * This shall only be set if @ref BT_AUDIO_CODEC_LC3_DURATION_10 is also set, and if @ref + * BT_AUDIO_CODEC_LC3_DURATION_PREFER_7_5 is not set. + */ + BT_AUDIO_CODEC_LC3_DURATION_PREFER_10 = BIT(5), +}; + +enum bt_audio_codec_cap_chan_count { + /** Supporting 1 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_1 = BIT(0), + /** Supporting 2 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_2 = BIT(1), + /** Supporting 3 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_3 = BIT(2), + /** Supporting 4 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_4 = BIT(3), + /** Supporting 5 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_5 = BIT(4), + /** Supporting 6 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_6 = BIT(5), + /** Supporting 7 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_7 = BIT(6), + /** Supporting 8 channel */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_8 = BIT(7), + /** Supporting all channels */ + BT_AUDIO_CODEC_CAP_CHAN_COUNT_ALL = + (BT_AUDIO_CODEC_CAP_CHAN_COUNT_1 | BT_AUDIO_CODEC_CAP_CHAN_COUNT_2 | + BT_AUDIO_CODEC_CAP_CHAN_COUNT_3 | BT_AUDIO_CODEC_CAP_CHAN_COUNT_4 | + BT_AUDIO_CODEC_CAP_CHAN_COUNT_5 | BT_AUDIO_CODEC_CAP_CHAN_COUNT_6 | + BT_AUDIO_CODEC_CAP_CHAN_COUNT_7 | BT_AUDIO_CODEC_CAP_CHAN_COUNT_8), +}; /** * @brief LC3 minimum supported channel counts @@ -148,7 +210,7 @@ enum bt_audio_codec_capability_type { * BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1, 3) */ #define BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(...) \ - ((uint8_t)((FOR_EACH(BIT, (|), __VA_ARGS__)) >> 1)) + ((enum bt_audio_codec_cap_chan_count)((FOR_EACH(BIT, (|), __VA_ARGS__)) >> 1)) struct BT_AUDIO_CODEC_LC3_frame_len { uint16_t min; From 06d5a625a60981ce08f69fd1f787f57f5d6270ed Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 28 Sep 2023 14:14:17 +0200 Subject: [PATCH 3445/4498] Bluetooth: Audio: Add codec cap set functions Add set functions for codec capability, to set all assigned number values in the bt_audio_codec_cap struct. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 85 +++++++++++-- subsys/bluetooth/audio/codec.c | 163 ++++++++++++++++++++++++- tests/bluetooth/audio/codec/src/main.c | 106 +++++++++++++++- 3 files changed, 342 insertions(+), 12 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 403993172ea..597e49ade9c 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -994,31 +994,57 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, u /** * @brief Extract the frequency from a codec capability. * - * @param codec_cap The codec configuration to extract data from. + * @param codec_cap The codec capabilities to extract data from. * - * @retval Bitfield of supported frequencies if 0 or positive + * @retval Bitfield of supported frequencies (@ref bt_audio_codec_cap_freq) if 0 or positive * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the supported frequencies of a codec capability. + * + * @param codec_cap The codec capabilities to set data for. + * @param freq The supported frequencies to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_freq(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_cap_freq freq); + /** * @brief Extract the frequency from a codec capability. * - * @param codec_cap The codec configuration to extract data from. + * @param codec_cap The codec capabilities to extract data from. * * @retval Bitfield of supported frame durations if 0 or positive * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap); +int bt_audio_codec_cap_get_frame_dur(const struct bt_audio_codec_cap *codec_cap); + +/** + * @brief Set the frame duration of a codec capability. + * + * @param codec_cap The codec capabilities to set data for. + * @param frame_dur The frame duration to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_frame_dur(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_cap_frame_dur frame_dur); /** * @brief Extract the frequency from a codec capability. * - * @param codec_cap The codec configuration to extract data from. + * @param codec_cap The codec capabilities to extract data from. * * @retval Bitfield of supported channel counts if 0 or positive * @retval -EINVAL if arguments are invalid @@ -1028,9 +1054,22 @@ int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap); /** - * @brief Extract the frequency from a codec capability. + * @brief Set the channel count of a codec capability. + * + * @param codec_cap The codec capabilities to set data for. + * @param chan_count The channel count frequency to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_supported_audio_chan_counts( + struct bt_audio_codec_cap *codec_cap, enum bt_audio_codec_cap_chan_count chan_count); + +/** + * @brief Extract the supported octets per codec frame from a codec capability. * - * @param[in] codec_cap The codec configuration to extract data from. + * @param[in] codec_cap The codec capabilities to extract data from. * @param[out] codec_frame Struct to place the resulting values in * * @retval 0 on success @@ -1043,9 +1082,23 @@ int bt_audio_codec_cap_get_octets_per_frame( struct bt_audio_codec_octets_per_codec_frame *codec_frame); /** - * @brief Extract the frequency from a codec capability. + * @brief Set the octets per codec frame of a codec capability. + * + * @param codec_cap The codec capabilities to set data for. + * @param codec_frame The octets per codec frame to set. * - * @param codec_cap The codec configuration to extract data from. + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_octets_per_frame( + struct bt_audio_codec_cap *codec_cap, + const struct bt_audio_codec_octets_per_codec_frame *codec_frame); + +/** + * @brief Extract the maximum codec frames per SDU from a codec capability. + * + * @param codec_cap The codec capabilities to extract data from. * * @retval Maximum number of codec frames per SDU supported * @retval -EINVAL if arguments are invalid @@ -1054,6 +1107,19 @@ int bt_audio_codec_cap_get_octets_per_frame( */ int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the maximum codec frames per SDU of a codec capability. + * + * @param codec_cap The codec capabilities to set data for. + * @param codec_frames_per_sdu The maximum codec frames per SDU to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap *codec_cap, + uint8_t codec_frames_per_sdu); + /** @brief Lookup a specific metadata value based on type * * @param[in] codec_cap The codec data to search in. @@ -1214,6 +1280,7 @@ int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_ */ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, const uint8_t **vendor_meta); + /** @} */ /* End of bt_audio_codec_cap */ #ifdef __cplusplus diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 1c156d87028..382c6f370b0 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -1074,6 +1074,15 @@ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_ca #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 +static void init_net_buf_simple_from_codec_cap(struct net_buf_simple *buf, + struct bt_audio_codec_cap *codec_cap) +{ + buf->__buf = codec_cap->data; + buf->data = codec_cap->data; + buf->size = sizeof(codec_cap->data); + buf->len = codec_cap->data_len; +} + uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, const uint8_t **data) { @@ -1110,6 +1119,37 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, u return param.data_len; } +int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, uint8_t type, + const uint8_t *data, size_t data_len) +{ + struct net_buf_simple buf; + int ret; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + CHECKIF(data == NULL) { + LOG_DBG("data is NULL"); + return -EINVAL; + } + + CHECKIF(data_len == 0U || data_len > UINT8_MAX) { + LOG_DBG("Invalid data_len %zu", data_len); + return -EINVAL; + } + + init_net_buf_simple_from_codec_cap(&buf, codec_cap); + + ret = ltv_set_val(&buf, type, data, data_len); + if (ret >= 0) { + codec_cap->data_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap) { const uint8_t *data; @@ -1132,7 +1172,28 @@ int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap) return sys_get_le16(data); } -int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap) +int bt_audio_codec_cap_set_freq(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_cap_freq freq) +{ + uint16_t freq_le16; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + if ((freq & BT_AUDIO_CODEC_LC3_FREQ_ANY) != freq) { + LOG_DBG("Invalid freq value: %d", freq); + return -EINVAL; + } + + freq_le16 = sys_cpu_to_le16((uint16_t)freq); + + return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_LC3_FREQ, (uint8_t *)&freq_le16, + sizeof(freq_le16)); +} + +int bt_audio_codec_cap_get_frame_dur(const struct bt_audio_codec_cap *codec_cap) { const uint8_t *data; uint8_t data_len; @@ -1154,6 +1215,45 @@ int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec return data[0]; } +int bt_audio_codec_cap_set_frame_dur(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_cap_frame_dur frame_dur) +{ + uint8_t frame_dur_u8; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + if ((frame_dur & BT_AUDIO_CODEC_LC3_DURATION_ANY) == 0) { + LOG_DBG("Invalid frame_dur value: %d", frame_dur); + return -EINVAL; + } + + if ((frame_dur & BT_AUDIO_CODEC_LC3_DURATION_PREFER_7_5) != 0) { + if ((frame_dur & BT_AUDIO_CODEC_LC3_DURATION_PREFER_10) != 0) { + LOG_DBG("Cannot prefer both 7.5 and 10ms: %d", frame_dur); + return -EINVAL; + } + + if ((frame_dur & BT_AUDIO_CODEC_LC3_DURATION_7_5) == 0) { + LOG_DBG("Cannot prefer 7.5ms when not supported: %d", frame_dur); + return -EINVAL; + } + } + + if ((frame_dur & BT_AUDIO_CODEC_LC3_DURATION_PREFER_10) != 0 && + (frame_dur & BT_AUDIO_CODEC_LC3_DURATION_10) == 0) { + LOG_DBG("Cannot prefer 10ms when not supported: %d", frame_dur); + return -EINVAL; + } + + frame_dur_u8 = (uint8_t)frame_dur; + + return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_LC3_DURATION, &frame_dur_u8, + sizeof(frame_dur_u8)); +} + int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap) { const uint8_t *data; @@ -1176,6 +1276,27 @@ int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_cod return data[0]; } +int bt_audio_codec_cap_set_supported_audio_chan_counts( + struct bt_audio_codec_cap *codec_cap, enum bt_audio_codec_cap_chan_count chan_count) +{ + uint8_t chan_count_u8; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + if ((chan_count & BT_AUDIO_CODEC_CAP_CHAN_COUNT_ALL) != chan_count) { + LOG_DBG("Invalid chan_count value: %d", chan_count); + return -EINVAL; + } + + chan_count_u8 = (uint8_t)chan_count; + + return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_LC3_CHAN_COUNT, &chan_count_u8, + sizeof(chan_count_u8)); +} + int bt_audio_codec_cap_get_octets_per_frame( const struct bt_audio_codec_cap *codec_cap, struct bt_audio_codec_octets_per_codec_frame *codec_frame) @@ -1208,6 +1329,34 @@ int bt_audio_codec_cap_get_octets_per_frame( return 0; } +int bt_audio_codec_cap_set_octets_per_frame( + struct bt_audio_codec_cap *codec_cap, + const struct bt_audio_codec_octets_per_codec_frame *codec_frame) +{ + uint8_t codec_frame_le32[4]; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + CHECKIF(codec_frame == NULL) { + LOG_DBG("codec_frame is NULL"); + return -EINVAL; + } + + if (codec_frame->min > codec_frame->max) { + LOG_DBG("Invalid codec_frame values: %u/%u", codec_frame->min, codec_frame->max); + return -EINVAL; + } + + sys_put_le16(codec_frame->min, codec_frame_le32); + sys_put_le16(codec_frame->max, codec_frame_le32 + 2); + + return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_LEN, codec_frame_le32, + sizeof(codec_frame_le32)); +} + int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap) { const uint8_t *data; @@ -1230,4 +1379,16 @@ int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_ return data[0]; } +int bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap *codec_cap, + uint8_t codec_frames_per_sdu) +{ + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_COUNT, + &codec_frames_per_sdu, sizeof(codec_frames_per_sdu)); +} + #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */ diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index edc87c56007..99d5d6f21fd 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -376,7 +376,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_freq) zassert_equal(ret, 4, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_frame_duration) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_set_freq) +{ + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_freq(&codec_cap); + zassert_equal(ret, 4, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_set_freq(&codec_cap, BT_AUDIO_CODEC_LC3_FREQ_22KHZ); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_get_freq(&codec_cap); + zassert_equal(ret, 8, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_frame_dur) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, @@ -385,8 +404,27 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_frame_duration) int ret; - ret = bt_audio_codec_cap_get_frame_duration(&codec_cap); + ret = bt_audio_codec_cap_get_frame_dur(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_set_frame_dur) +{ + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_frame_dur(&codec_cap); zassert_equal(ret, 2, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_set_frame_dur(&codec_cap, BT_AUDIO_CODEC_LC3_DURATION_7_5); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_get_frame_dur(&codec_cap); + zassert_equal(ret, 1, "Unexpected return value %d", ret); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_supported_audio_chan_counts) @@ -402,6 +440,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_supported_audio_chan_c zassert_equal(ret, 2, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_set_supported_audio_chan_counts) +{ + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_supported_audio_chan_counts(&codec_cap); + zassert_equal(ret, 1, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_set_frame_dur(&codec_cap, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(2)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_get_frame_dur(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_octets_per_frame) { struct bt_audio_codec_octets_per_codec_frame expected = { @@ -424,6 +482,31 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_octets_per_frame) codec_frame.max); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_set_octets_per_frame) +{ + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + struct bt_audio_codec_octets_per_codec_frame codec_frame; + int ret; + + ret = bt_audio_codec_cap_get_octets_per_frame(&codec_cap, &codec_frame); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_equal(codec_frame.min, 40U, "Unexpected minimum value %d", codec_frame.min); + zassert_equal(codec_frame.max, 120U, "Unexpected maximum value %d", codec_frame.max); + + codec_frame.min = 50U; + codec_frame.max = 100U; + ret = bt_audio_codec_cap_set_octets_per_frame(&codec_cap, &codec_frame); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_get_octets_per_frame(&codec_cap, &codec_frame); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_equal(codec_frame.min, 50U, "Unexpected minimum value %d", codec_frame.min); + zassert_equal(codec_frame.max, 100U, "Unexpected maximum value %d", codec_frame.max); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_max_codec_frames_per_sdu) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( @@ -437,6 +520,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_max_codec_frames_per_s zassert_equal(ret, 2, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_set_max_codec_frames_per_sdu) +{ + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + BT_AUDIO_CODEC_LC3_FREQ_16KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40U, 120U, 2U, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); + + int ret; + + ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(&codec_cap); + zassert_equal(ret, 2, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_set_max_codec_frames_per_sdu(&codec_cap, 4U); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(&codec_cap); + zassert_equal(ret, 4, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_pref_context) { const enum bt_audio_context ctx = From dbed2512490687083aca4b97d159763a6c8e0004 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Tue, 24 Oct 2023 00:39:25 +0800 Subject: [PATCH 3446/4498] test: twister: testplan.py use normpath when load test plan it is possible the plan is built in another os so the case key would be 'samples/hello_world/samples.baseic.hello_world' but the testsuite is scaned in current os may in window and the key is like 'samples\\hello_world\\samples.baseic.hello_world' so update the uniq path with only backslash in path Signed-off-by: Hake Huang --- scripts/pylib/twister/twisterlib/testsuite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index ecb7c8b4000..419d0f39596 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -450,7 +450,7 @@ def get_unique(testsuite_root, workdir, name): relative_ts_root = "" # workdir can be "." - unique = os.path.normpath(os.path.join(relative_ts_root, workdir, name)) + unique = os.path.normpath(os.path.join(relative_ts_root, workdir, name)).replace(os.sep, '/') return unique @staticmethod From da4e3e713b9510f3c3a453faebe92e7de8ef5061 Mon Sep 17 00:00:00 2001 From: Ethan Duckett Date: Wed, 25 Oct 2023 17:13:54 +0100 Subject: [PATCH 3447/4498] drivers: adc: ltc2451: Add ltc2451 driver Adds support for the Linear Technologies LTC2451 ADC. Signed-off-by: Ethan Duckett --- drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig | 2 + drivers/adc/Kconfig.ltc2451 | 8 ++ drivers/adc/adc_ltc2451.c | 105 ++++++++++++++++++ dts/bindings/adc/lltc,ltc2451.yaml | 16 +++ .../build_all/adc/boards/native_posix.overlay | 7 ++ tests/drivers/build_all/adc/testcase.yaml | 1 + 7 files changed, 140 insertions(+) create mode 100644 drivers/adc/Kconfig.ltc2451 create mode 100644 drivers/adc/adc_ltc2451.c create mode 100644 dts/bindings/adc/lltc,ltc2451.yaml diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index 4738aaa891c..34536f4c4e0 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -47,3 +47,4 @@ zephyr_library_sources_ifdef(CONFIG_ADC_NXP_S32_ADC_SAR adc_nxp_s32_adc_sar.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX1125X adc_max1125x.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX11102_17 adc_max11102_17.c) zephyr_library_sources_ifdef(CONFIG_ADC_AD5592 adc_ad5592.c) +zephyr_library_sources_ifdef(CONFIG_ADC_LTC2451 adc_ltc2451.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 14f4d89657e..b52183c2b47 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -118,4 +118,6 @@ source "drivers/adc/Kconfig.max11102_17" source "drivers/adc/Kconfig.ad5592" +source "drivers/adc/Kconfig.ltc2451" + endif # ADC diff --git a/drivers/adc/Kconfig.ltc2451 b/drivers/adc/Kconfig.ltc2451 new file mode 100644 index 00000000000..8f3cb384cfb --- /dev/null +++ b/drivers/adc/Kconfig.ltc2451 @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Brill Power +# SPDX-License-Identifier: Apache-2.0 + +config ADC_LTC2451 + bool "LTC2451 driver" + default y + depends on DT_HAS_LLTC_LTC2451_ENABLED + select I2C diff --git a/drivers/adc/adc_ltc2451.c b/drivers/adc/adc_ltc2451.c new file mode 100644 index 00000000000..95b86f30d68 --- /dev/null +++ b/drivers/adc/adc_ltc2451.c @@ -0,0 +1,105 @@ +/* LLTC LTC2451 ADC + * + * Copyright (c) 2023 Brill Power Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ltc2451, CONFIG_ADC_LOG_LEVEL); + +#define DT_DRV_COMPAT lltc_ltc2451 + +struct ltc2451_config { + struct i2c_dt_spec i2c; + uint8_t conversion_speed; +}; + +static int ltc2451_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + ARG_UNUSED(dev); + + if (channel_cfg->channel_id != 0) { + LOG_ERR("Invalid channel id '%d'", channel_cfg->channel_id); + return -EINVAL; + } + + return 0; +} + +static int ltc2451_set_conversion_speed(const struct device *dev, uint8_t conversion_speed) +{ + const struct ltc2451_config *config = dev->config; + uint8_t wr_buf[1]; + int err; + + if (conversion_speed == 60) { + wr_buf[0] = 0; + } else if (conversion_speed == 30) { + wr_buf[0] = 1; + } else { + LOG_ERR("Invalid conversion speed selected"); + return -EINVAL; + } + + err = i2c_write_dt(&config->i2c, wr_buf, sizeof(wr_buf)); + + if (err != 0) { + LOG_ERR("LTC write failed (err %d)", err); + } + + return err; +} + +static int ltc2451_read_latest_conversion(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct ltc2451_config *config = dev->config; + uint8_t rd_buf[2]; + uint16_t *value_buf; + int err = i2c_read_dt(&config->i2c, rd_buf, sizeof(rd_buf)); + + if (err == 0) { + value_buf = (uint16_t *)sequence->buffer; + value_buf[0] = sys_get_be16(rd_buf); + } else { + LOG_ERR("LTC read failed (err %d)", err); + } + + return err; +} + +static int ltc2451_init(const struct device *dev) +{ + const struct ltc2451_config *config = dev->config; + + if (!device_is_ready(config->i2c.bus)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + + return ltc2451_set_conversion_speed(dev, config->conversion_speed); +} + +static const struct adc_driver_api ltc2451_api = { + .channel_setup = ltc2451_channel_setup, + .read = ltc2451_read_latest_conversion, +}; + +#define LTC2451_DEFINE(index) \ + static const struct ltc2451_config ltc2451_cfg_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + .conversion_speed = DT_INST_PROP(index, conversion_speed), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, <c2451_init, NULL, NULL, \ + <c2451_cfg_##index, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + <c2451_api); + +DT_INST_FOREACH_STATUS_OKAY(LTC2451_DEFINE) diff --git a/dts/bindings/adc/lltc,ltc2451.yaml b/dts/bindings/adc/lltc,ltc2451.yaml new file mode 100644 index 00000000000..b68f127337f --- /dev/null +++ b/dts/bindings/adc/lltc,ltc2451.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Brill Power Ltd. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +description: Linear Technology LTC2451 ADC + +compatible: "lltc,ltc2451" + +include: i2c-device.yaml + +properties: + conversion-speed: + type: int + enum: + - 30 + - 60 + description: Set conversion speed in Hz diff --git a/tests/drivers/build_all/adc/boards/native_posix.overlay b/tests/drivers/build_all/adc/boards/native_posix.overlay index 5e787d8932f..120e05dcfb0 100644 --- a/tests/drivers/build_all/adc/boards/native_posix.overlay +++ b/tests/drivers/build_all/adc/boards/native_posix.overlay @@ -87,6 +87,13 @@ reg = <0x7>; #io-channel-cells = <1>; }; + + test_i2c_ltc2451: ltc2451@8{ + compatible = "lltc,ltc2451"; + reg = <0x8>; + conversion-speed = <60>; + #io-channel-cells = <1>; + }; }; test_spi: spi@33334444 { diff --git a/tests/drivers/build_all/adc/testcase.yaml b/tests/drivers/build_all/adc/testcase.yaml index cde46e57a09..c8a6fe5e3a7 100644 --- a/tests/drivers/build_all/adc/testcase.yaml +++ b/tests/drivers/build_all/adc/testcase.yaml @@ -18,6 +18,7 @@ tests: - adc_ads114s08 - adc_emul - adc_max1125x + - adc_ltc2451 extra_args: "CONFIG_GPIO=y" drivers.adc.cc32xx.build: platform_allow: cc3220sf_launchxl From 9ddc94e0d49f0e2a499bc5200ec4d275e4c1546c Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sat, 28 Oct 2023 11:12:35 -0700 Subject: [PATCH 3448/4498] drivers: i3c: specify start addr when searching for a free addr For example, if a driver needed to reserve address before it does a ENTDAA, it would need to get free address in a loop, but the get free address func would return the same address everytime. It needs the start address, which would be the last free address it go, to be passed in to get the next free address. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 2 +- drivers/i3c/i3c_common.c | 10 +++++----- include/zephyr/drivers/i3c/addresses.h | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index cad6bab6566..cad71e5cae6 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -703,7 +703,7 @@ static void cdns_i3c_program_controller_retaining_reg(const struct device *dev) if (!i3c_addr_slots_is_free(&data->common.attached_dev.addr_slots, controller_da)) { controller_da = - i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots); + i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); } sys_write32(prepare_rr0_dev_address(controller_da), config->base + DEV_ID_RR0(0)); diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index 29746f3cf68..6c170edb9e3 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -157,13 +157,13 @@ bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, return (status == I3C_ADDR_SLOT_STATUS_FREE); } -uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots) +uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr) { uint8_t addr; enum i3c_addr_slot_status status; /* Addresses 0 to 7 are reserved. So start at 8. */ - for (addr = 8; addr < I3C_MAX_ADDR; addr++) { + for (addr = MAX(start_addr, 8); addr < I3C_MAX_ADDR; addr++) { status = i3c_addr_slots_status(slots, addr); if (status == I3C_ADDR_SLOT_STATUS_FREE) { return addr; @@ -252,7 +252,7 @@ int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr) } else { /* address is not free, get the next one */ *addr = i3c_addr_slots_next_free_find( - &data->attached_dev.addr_slots); + &data->attached_dev.addr_slots, 0); } } else { /* Use the init dynamic address as it's DA, but the RR will need to @@ -281,7 +281,7 @@ int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr) } else { /* pick a DA to use */ *addr = i3c_addr_slots_next_free_find( - &data->attached_dev.addr_slots); + &data->attached_dev.addr_slots, 0); } } } else { @@ -488,7 +488,7 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, /* * Find the next available address. */ - dyn_addr = i3c_addr_slots_next_free_find(addr_slots); + dyn_addr = i3c_addr_slots_next_free_find(addr_slots, 0); if (dyn_addr == 0U) { /* No free addresses available */ diff --git a/include/zephyr/drivers/i3c/addresses.h b/include/zephyr/drivers/i3c/addresses.h index 191e7f881da..c85255d8a69 100644 --- a/include/zephyr/drivers/i3c/addresses.h +++ b/include/zephyr/drivers/i3c/addresses.h @@ -113,10 +113,11 @@ bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, * assigned to a new device. * * @param slots Pointer to the address slots structure. + * @param start_addr Where to start searching * * @return The next free address, or 0 if none found. */ -uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots); +uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr); /** * @brief Mark the address as free (not used) in device list. From fc2a54b80cf0950f615b0259d751c94b64147f5a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 30 Oct 2023 18:17:33 +0100 Subject: [PATCH 3449/4498] doc: Bluetooth: Audio Stack status table Adds table of the status of the LE Audio stack in the Bluetooth subsystem. Signed-off-by: Emil Gydesen --- .../bluetooth/bluetooth-audio-arch.rst | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/doc/connectivity/bluetooth/bluetooth-audio-arch.rst b/doc/connectivity/bluetooth/bluetooth-audio-arch.rst index 49461128270..aa62b426160 100644 --- a/doc/connectivity/bluetooth/bluetooth-audio-arch.rst +++ b/doc/connectivity/bluetooth/bluetooth-audio-arch.rst @@ -43,6 +43,178 @@ GAF has been implemented in Zephyr with the following structure. Zephyr Generic Audio Framework +Bluetooth Audio Stack Status +============================ + +The following table shows the current status and support of the profiles in the +Bluetooth Audio Stack. + +.. table:: Bluetooth Audio Profile status + :widths: auto + + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | Module | Role | Version | Added in Release | Status | Remaining | + +========+===============================+=========+==================+=======================+==================================================+ + | VCP | Volume Renderer | 1.0 | 2.6 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Volume Controller | 1.0 | 2.6 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | MICP | Microphone Device | 1.0 | 2.7 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Microphone Controller | 1.0 | 2.7 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | CSIP | Set Member | 1.0.1 | 3.0 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Set Coordinator | 1.0.1 | 3.0 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | CCP | Call Control Server | 1.0 | 3.0 | - Feature complete | - API refactor | + | | | | | - Shell Module | - Sample Application | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Call Control Client | 1.0 | 3.0 | - Feature complete | - API refactor | + | | | | | - Shell Module | - Sample Application | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | MCP | Media Control Server | 1.0 | 3.0 | - Feature complete | - API refactor | + | | | | | - Shell Module | - Support for multiple instances and connections | + | | | | | - BSIM test | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Media Control Client | 1.0 | 3.0 | - Feature complete | - API refactor | + | | | | | - Shell Module | - Sample Application | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | BAP | Unicast Server | 1.0.1 | 3.0 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Unicast Client | 1.0.1 | 3.0 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Source | 1.0.1 | 3.0 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Sink | 1.0.1 | 3.0 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Scan Delegator | 1.0.1 | 3.3 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Assistant | 1.0.1 | 3.3 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | CAP | Acceptor | 1.0 | 3.2 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Initiator | 1.0 | 3.3 | - Feature complete | - Sample Application | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Commander | | | - Not Started | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | HAP | Hearing Aid | 1.0 | 3.1 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Hearing Aid Unicast Client | 1.0 | 3.1 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Hearing Aid Remote Controller | | | - WIP | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | TMAP | Call Gateway | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Call Terminal | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Unicast Media Sender | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Unicast Media Receiver | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Media Sender | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Media Receiver | 1.0 | 3.4 | - Feature complete | | + | | | | | - Shell Module | | + | | | | | - BSIM test | | + | | | | | - Sample Application | | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | PBP | Public Broadcast Source | | | - WIP :github:`60777` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Public Broadcast Sink | | | - WIP :github:`60777` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Public Broadcast Assistant | | | | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | GMAP | Unicast Game Gateway | | | - WIP :github:`57032` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Unicast Game Terminal | | | - WIP :github:`57032` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Game Sender | | | - WIP :github:`57032` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + | | Broadcast Game Receiver | | | - WIP :github:`57032` | - Feature complete | + | | | | | | - Shell Module | + | | | | | | - BSIM test | + | | | | | | - Sample Application | + +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ + Using the Bluetooth Audio Stack =============================== From 0127d000a2871a2868067001ad55cfce40a4986e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 2 Nov 2023 08:43:26 +0100 Subject: [PATCH 3450/4498] usb: device: cdc_acm: Use ZLP to detect initial host read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent ECHO on Linux by arming IN endpoint with ZLP when interface is configured and making sure that actual payload is only sent after initialization timeout. The ZLP is not visible to host side applications because the applications are really accessing tty buffer and received ZLP does not modify tty buffer in any way. Signed-off-by: Tomasz Moń --- subsys/usb/device/class/Kconfig.cdc | 7 ++++++ subsys/usb/device/class/cdc_acm.c | 33 ++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/subsys/usb/device/class/Kconfig.cdc b/subsys/usb/device/class/Kconfig.cdc index 7c748028023..59a72e25b6e 100644 --- a/subsys/usb/device/class/Kconfig.cdc +++ b/subsys/usb/device/class/Kconfig.cdc @@ -37,6 +37,13 @@ config CDC_ACM_BULK_EP_MPS help CDC ACM class bulk endpoints size +config CDC_ACM_TX_DELAY_MS + int + default 100 + help + Time in milliseconds to wait before sending actual payload to host. + This is needed to prevent tty ECHO on Linux. + config CDC_ACM_IAD bool "Force using Interface Association Descriptor" default y diff --git a/subsys/usb/device/class/cdc_acm.c b/subsys/usb/device/class/cdc_acm.c index 1530813ab47..fabe0d8e9d9 100644 --- a/subsys/usb/device/class/cdc_acm.c +++ b/subsys/usb/device/class/cdc_acm.c @@ -223,12 +223,27 @@ static void cdc_acm_write_cb(uint8_t ep, int size, void *priv) k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work); } - if (ring_buf_is_empty(dev_data->tx_ringbuf)) { + /* If size is 0, we want to schedule tx work even if ringbuf is empty to + * ensure that actual payload will not be sent before initialization + * timeout passes. + */ + if (ring_buf_is_empty(dev_data->tx_ringbuf) && size) { LOG_DBG("tx_ringbuf is empty"); return; } - k_work_schedule_for_queue(&USB_WORK_Q, &dev_data->tx_work, K_NO_WAIT); + /* If size is 0, it means that host started polling IN data because it + * has read the ZLP we armed when interface was configured. This ZLP is + * probably the best indication that host has started to read the data. + * Wait initialization timeout before sending actual payload to make it + * possible for application to disable ECHO. The echo is long known + * problem related to the fact that POSIX defaults to ECHO ON and thus + * every application that opens tty device (on Linux) will have ECHO + * enabled in the short window between open() and ioctl() that disables + * the echo (if application wishes to disable the echo). + */ + k_work_schedule_for_queue(&USB_WORK_Q, &dev_data->tx_work, size ? + K_NO_WAIT : K_MSEC(CONFIG_CDC_ACM_TX_DELAY_MS)); } static void tx_work_handler(struct k_work *work) @@ -247,6 +262,10 @@ static void tx_work_handler(struct k_work *work) return; } + if (!dev_data->configured) { + return; + } + len = ring_buf_get_claim(dev_data->tx_ringbuf, &data, CONFIG_USB_CDC_ACM_RINGBUF_SIZE); @@ -375,12 +394,10 @@ static void cdc_acm_do_cb(struct cdc_acm_dev_data_t *dev_data, dev_data->configured = true; cdc_acm_read_cb(cfg->endpoint[ACM_OUT_EP_IDX].ep_addr, 0, dev_data); - } - if (!dev_data->tx_ready) { - dev_data->tx_ready = true; - /* if wait tx irq, invoke callback */ - if (dev_data->cb != NULL && dev_data->tx_irq_ena) { - k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work); + /* Queue ZLP on IN endpoint so we know when host starts polling */ + if (!dev_data->tx_ready) { + usb_transfer(cfg->endpoint[ACM_IN_EP_IDX].ep_addr, NULL, 0, + USB_TRANS_WRITE, cdc_acm_write_cb, dev_data); } } break; From c275fa737ba4346ff69fbf95f3c4d190924d8b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Thu, 9 Nov 2023 08:33:17 +0100 Subject: [PATCH 3451/4498] doc: connectivity: usb: Document CDC ACM ECHO mitigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explain the root cause behind garbage characters received in shell applications, what Zephyr does to mitigate the issue and what is expected from host userspace applications. Signed-off-by: Tomasz Moń --- doc/connectivity/usb/device/usb_device.rst | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index c770c57bc79..3362f07840f 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -175,6 +175,37 @@ CDC ACM UART as backend for a subsystem or application: for example see :zephyr_file:`samples/subsys/shell/shell_module` * ``zephyr,uart-mcumgr`` used by :zephyr:code-sample:`smp-svr` sample +POSIX default tty ECHO mitigation +--------------------------------- + +POSIX systems, like Linux, default to enabling ECHO on tty devices. Host side +application can disable ECHO by calling ``open()`` on the tty device and issuing +``ioctl()`` (preferably via ``tcsetattr()``) to disable echo if it is not desired. +Unfortunately, there is an inherent race between the ``open()`` and ``ioctl()`` +where the ECHO is enabled and any characters received (even if host application +does not call ``read()``) will be echoed back. This issue is especially visible +when the CDC ACM port is used without any real UART on the other side because +there is no arbitrary delay due to baud rate. + +To mitigate the issue, Zephyr CDC ACM implementation arms IN endpoint with ZLP +after device is configured. When the host reads the ZLP, which is pretty much +the best indication that host application has opened the tty device, Zephyr will +force :kconfig:option:`CONFIG_CDC_ACM_TX_DELAY_MS` millisecond delay before real +payload is sent. This should allow sufficient time for first, and only first, +application that opens the tty device to disable ECHO if ECHO is not desired. +If ECHO is not desired at all from CDC ACM device it is best to set up udev rule +to disable ECHO as soon as device is connected. + +ECHO is particurarly unwanted when CDC ACM instance is used for Zephyr shell, +because the control characters to set color sent back to shell are interpreted +as (invalid) command and user will see garbage as a result. While minicom does +disable ECHO by default, on exit with reset it will restore the termios settings +to whatever was set on entry. Therefore, if minicom is the first application to +open the tty device, the exit with reset will enable ECHO back and thus set up +a problem for the next application (which cannot be mitigated at Zephyr side). +To prevent the issue it is recommended either to leave minicom without reset or +to disable ECHO before minicom is started. + DFU === From f12e1d75ed02de34afdb2d507d6f190568f59583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Wed, 8 Nov 2023 10:37:11 +0100 Subject: [PATCH 3452/4498] usb: device: cdc_acm: Always buffer poll out data if possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Queue characters in TX ring buffer regardless of interface state. This allows simple applications that print basic output to CDC ACM port to not care about connection or DTR state. Note that depending on actual application requirements it might be still wise to wait for DTR before trying to send data. Signed-off-by: Tomasz Moń --- subsys/usb/device/class/cdc_acm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/subsys/usb/device/class/cdc_acm.c b/subsys/usb/device/class/cdc_acm.c index fabe0d8e9d9..fedccf5fdc0 100644 --- a/subsys/usb/device/class/cdc_acm.c +++ b/subsys/usb/device/class/cdc_acm.c @@ -1029,11 +1029,6 @@ static void cdc_acm_poll_out(const struct device *dev, unsigned char c) { struct cdc_acm_dev_data_t * const dev_data = dev->data; - if (!dev_data->configured || dev_data->suspended) { - LOG_INF("USB device not ready, drop data"); - return; - } - dev_data->tx_ready = false; while (!ring_buf_put(dev_data->tx_ringbuf, &c, 1)) { From f0715fcbb3ebaacee805cb1431a6c8460f1e67b4 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 7 Nov 2023 14:23:15 +0100 Subject: [PATCH 3453/4498] tests: bsim: testlib: Fix compilation error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes compilation error seen if CONFIG_BT_EATT is unset testlib/src/att_read.c:179:73: error: expected expression before ‘,’ token 179 | IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer)), | ^ Signed-off-by: Mariusz Skamra --- tests/bluetooth/common/testlib/src/att_read.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/common/testlib/src/att_read.c b/tests/bluetooth/common/testlib/src/att_read.c index 5e4990f02b5..d7dd17ee07c 100644 --- a/tests/bluetooth/common/testlib/src/att_read.c +++ b/tests/bluetooth/common/testlib/src/att_read.c @@ -149,7 +149,7 @@ int bt_testlib_att_read_by_handle_sync(struct net_buf_simple *result_data, uint1 .params = { .handle_count = 1, .single = {.handle = handle, .offset = offset}, - IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer)), + IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer,)) }}; if (bearer == BT_ATT_CHAN_OPT_ENHANCED_ONLY) { @@ -176,7 +176,7 @@ int bt_testlib_gatt_long_read(struct net_buf_simple *result_data, uint16_t *resu .params = { .handle_count = 1, .single = {.handle = handle, .offset = offset}, - IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer)), + IF_ENABLED(CONFIG_BT_EATT, (.chan_opt = bearer,)) }}; if (bearer == BT_ATT_CHAN_OPT_ENHANCED_ONLY) { From f434198a2bca29faac455a5df21bf7a845f071a5 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 3 Nov 2023 16:22:05 +0100 Subject: [PATCH 3454/4498] Bluetooth: att: Retry ATT request if security elevation is in progress If the conn security elevation is already in progress, retry the ATT request if failed due to security reasons. Signed-off-by: Mariusz Skamra --- subsys/bluetooth/host/att.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index dd953115c5c..cb8c17983cb 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -2519,9 +2519,13 @@ static uint8_t att_error_rsp(struct bt_att_chan *chan, struct net_buf *buf) } err = rsp->error; + #if defined(CONFIG_BT_ATT_RETRY_ON_SEC_ERR) + int ret; + /* Check if error can be handled by elevating security. */ - if (!att_change_security(chan->chan.chan.conn, err)) { + ret = att_change_security(chan->chan.chan.conn, err); + if (ret == 0 || ret == -EBUSY) { /* ATT timeout work is normally cancelled in att_handle_rsp. * However retrying is special case, so the timeout shall * be cancelled here. From f80b237e306a02aa4f7ba6beecc972cee9c28f70 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 3 Nov 2023 13:21:43 +0100 Subject: [PATCH 3455/4498] tests: Bluetooth: Add tests for ATT automatic security elevation This adds tests for automatic security elevation and retry on security errors. This includes two tests: 1. where the security is elevated by the central 2. the security is elevated by security request, so pairing is already in progress. Signed-off-by: Mariusz Skamra --- .../retry_on_sec_err/client/CMakeLists.txt | 22 ++ .../host/att/retry_on_sec_err/client/main.c | 195 ++++++++++++++++++ .../host/att/retry_on_sec_err/client/prj.conf | 12 ++ .../host/att/retry_on_sec_err/common_defs.h | 12 ++ .../retry_on_sec_err/server/CMakeLists.txt | 22 ++ .../host/att/retry_on_sec_err/server/main.c | 98 +++++++++ .../host/att/retry_on_sec_err/server/prj.conf | 13 ++ .../retry_on_sec_err/test_scripts/_compile.sh | 18 ++ .../att/retry_on_sec_err/test_scripts/_env.sh | 15 ++ .../retry_on_sec_err/test_scripts/run_test.sh | 27 +++ .../test_scripts/run_test_security_request.sh | 27 +++ .../host/att/retry_on_sec_err/test_utils.c | 21 ++ .../host/att/retry_on_sec_err/test_utils.h | 29 +++ tests/bsim/bluetooth/host/compile.sh | 2 + 14 files changed, 513 insertions(+) create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/client/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/client/main.c create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/client/prj.conf create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/common_defs.h create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/server/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/server/main.c create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/server/prj.conf create mode 100755 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_env.sh create mode 100755 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test.sh create mode 100755 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test_security_request.sh create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.c create mode 100644 tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.h diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/CMakeLists.txt b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/CMakeLists.txt new file mode 100644 index 00000000000..b244078e761 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/CMakeLists.txt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(app) + +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/common/testlib testlib) + +target_sources(app PRIVATE + ../test_utils.c + main.c +) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ +) + +target_link_libraries(app PRIVATE + testlib +) diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/main.c b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/main.c new file mode 100644 index 00000000000..2a3c005515c --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/main.c @@ -0,0 +1,195 @@ +/* Copyright (c) 2023 Codecoup + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../common_defs.h" +#include "../test_utils.h" + +#include "testlib/connect.h" +#include "testlib/scan.h" +#include "testlib/security.h" + +LOG_MODULE_REGISTER(client, LOG_LEVEL_DBG); + +DEFINE_FLAG(flag_attr_read_success); + +static uint8_t gatt_attr_read_cb(struct bt_conn *conn, uint8_t att_err, + struct bt_gatt_read_params *params, const void *data, uint16_t len) +{ + __ASSERT_NO_MSG(!att_err); + + SET_FLAG(flag_attr_read_success); + + return BT_GATT_ITER_STOP; +} + +static void gatt_attr_read(struct bt_conn *conn) +{ + static struct bt_gatt_read_params params; + static struct bt_uuid_128 uuid; + int err; + + memset(¶ms, 0, sizeof(params)); + params.func = gatt_attr_read_cb; + params.by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + params.by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + memcpy(&uuid.uuid, TEST_CHRC_UUID, sizeof(uuid)); + params.by_uuid.uuid = &uuid.uuid; + + err = bt_gatt_read(conn, ¶ms); + __ASSERT_NO_MSG(!err); +} + +DEFINE_FLAG(flag_conn_encrypted); + +static void security_changed_cb(struct bt_conn *conn, bt_security_t level, + enum bt_security_err err) +{ + if (err != BT_SECURITY_ERR_SUCCESS || level < BT_SECURITY_L2) { + return; + } + + SET_FLAG(flag_conn_encrypted); +} + +static struct bt_conn_cb conn_cb = { + .security_changed = security_changed_cb, +}; + +static void test_client(void) +{ + struct bt_conn *conn = NULL; + bt_addr_le_t scan_result; + int err; + + err = bt_enable(NULL); + __ASSERT_NO_MSG(!err); + + bt_conn_cb_register(&conn_cb); + + err = bt_testlib_scan_find_name(&scan_result, "d1"); + __ASSERT_NO_MSG(!err); + + err = bt_testlib_connect(&scan_result, &conn); + __ASSERT_NO_MSG(!err); + + /* Read characteristic value that requires encryption */ + gatt_attr_read(conn); + + /* Expect link encryption */ + WAIT_FOR_FLAG(flag_conn_encrypted); + + /* Wait for successful Read Response */ + WAIT_FOR_FLAG(flag_attr_read_success); + + err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + __ASSERT_NO_MSG(!err); + + bt_conn_unref(conn); + conn = NULL; + + PASS("PASS\n"); +} + +DEFINE_FLAG(flag_pairing_in_progress); + +static void auth_cancel_cb(struct bt_conn *conn) +{ + +} + +static void auth_pairing_confirm_cb(struct bt_conn *conn) +{ + SET_FLAG(flag_pairing_in_progress); +} + +static struct bt_conn_auth_cb auth_cb = { + .cancel = auth_cancel_cb, + .pairing_confirm = auth_pairing_confirm_cb, +}; + +static void test_client_security_request(void) +{ + struct bt_conn *conn = NULL; + bt_addr_le_t scan_result; + int err; + + err = bt_enable(NULL); + __ASSERT_NO_MSG(!err); + + bt_conn_cb_register(&conn_cb); + + err = bt_conn_auth_cb_register(&auth_cb); + __ASSERT_NO_MSG(!err); + + err = bt_testlib_scan_find_name(&scan_result, "d1"); + __ASSERT_NO_MSG(!err); + + err = bt_testlib_connect(&scan_result, &conn); + __ASSERT_NO_MSG(!err); + + /* Wait for peripheral to initaiate pairing */ + WAIT_FOR_FLAG(flag_pairing_in_progress); + + /* Read characteristic value that requires encryption */ + gatt_attr_read(conn); + + /* Accept pairing */ + err = bt_conn_auth_pairing_confirm(conn); + __ASSERT_NO_MSG(!err); + + /* Expect link encryption */ + WAIT_FOR_FLAG(flag_conn_encrypted); + + /* Wait for successful Read Response */ + WAIT_FOR_FLAG(flag_attr_read_success); + + err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + __ASSERT_NO_MSG(!err); + + bt_conn_unref(conn); + conn = NULL; + + PASS("PASS\n"); +} + +static const struct bst_test_instance client_tests[] = { + { + .test_id = "test_client", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_client, + }, + { + .test_id = "test_client_security_request", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_client_security_request, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *client_tests_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, client_tests); +}; + +bst_test_install_t test_installers[] = { + client_tests_install, + NULL +}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/prj.conf b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/prj.conf new file mode 100644 index 00000000000..32e911d4396 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/client/prj.conf @@ -0,0 +1,12 @@ +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_CENTRAL=y + +CONFIG_BT_SMP=y + +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_ATT_RETRY_ON_SEC_ERR=y + +CONFIG_LOG=y +CONFIG_BT_ATT_LOG_LEVEL_DBG=y diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/common_defs.h b/tests/bsim/bluetooth/host/att/retry_on_sec_err/common_defs.h new file mode 100644 index 00000000000..7f9a091203b --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/common_defs.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2023 Codecoup + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define TEST_SERVICE_UUID \ + BT_UUID_DECLARE_128(0x1f, 0x5c, 0x31, 0x85, 0x05, 0xe8, 0x4d, 0x58, 0xb9, 0xf5, 0xae, \ + 0xf1, 0x7a, 0x88, 0xbe, 0x82) +#define TEST_CHRC_UUID \ + BT_UUID_DECLARE_128(0x68, 0xb4, 0x35, 0x19, 0x01, 0x65, 0x4d, 0xdc, 0xb9, 0xf3, 0x91, \ + 0x0f, 0xf3, 0x18, 0x46, 0x7b) diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/CMakeLists.txt b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/CMakeLists.txt new file mode 100644 index 00000000000..b244078e761 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/CMakeLists.txt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(app) + +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/common/testlib testlib) + +target_sources(app PRIVATE + ../test_utils.c + main.c +) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ +) + +target_link_libraries(app PRIVATE + testlib +) diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/main.c b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/main.c new file mode 100644 index 00000000000..b07f0034aab --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/main.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2023 Codecoup + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#include "testlib/adv.h" +#include "testlib/security.h" + +#include "../common_defs.h" +#include "../test_utils.h" + +LOG_MODULE_REGISTER(server, LOG_LEVEL_DBG); + +static ssize_t read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t buf_len, uint16_t offset) +{ + return 0; +} + +BT_GATT_SERVICE_DEFINE(test_svc, + BT_GATT_PRIMARY_SERVICE(TEST_SERVICE_UUID), + BT_GATT_CHARACTERISTIC(TEST_CHRC_UUID, BT_GATT_CHRC_READ, + BT_GATT_PERM_READ_ENCRYPT, read_chrc, NULL, NULL)); + +static void test_common(struct bt_conn **conn) +{ + int err; + + err = bt_enable(NULL); + __ASSERT_NO_MSG(!err); + + __ASSERT_NO_MSG(get_device_nbr() == 1); + err = bt_set_name("d1"); + __ASSERT_NO_MSG(!err); + + err = bt_testlib_adv_conn(conn, BT_ID_DEFAULT, + (BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_FORCE_NAME_IN_AD)); + __ASSERT_NO_MSG(!err); +} + +static void test_server(void) +{ + test_common(NULL); + + PASS("PASS\n"); +} + +static void test_server_security_request(void) +{ + struct bt_conn *conn = NULL; + int err; + + test_common(&conn); + + err = bt_testlib_secure(conn, BT_SECURITY_L2); + __ASSERT(!err, "err %d", err); + + PASS("PASS\n"); +} + +static const struct bst_test_instance server_tests[] = { + { + .test_id = "test_server", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_server, + }, + { + .test_id = "test_server_security_request", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_server_security_request, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *server_tests_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, server_tests); +}; + +bst_test_install_t test_installers[] = { + server_tests_install, + NULL +}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/prj.conf b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/prj.conf new file mode 100644 index 00000000000..1b3a186979e --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/server/prj.conf @@ -0,0 +1,13 @@ +CONFIG_ASSERT=y + +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y + +CONFIG_BT_DEVICE_NAME_DYNAMIC=y + +CONFIG_BT_SMP=y + +CONFIG_BT_EXT_ADV=y + +CONFIG_LOG=y +CONFIG_BT_ATT_LOG_LEVEL_DBG=y diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_compile.sh new file mode 100755 index 00000000000..88a5454b674 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_compile.sh @@ -0,0 +1,18 @@ +#!/bin/env bash +# Copyright 2023 Codecoup +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +source "${bash_source_dir}/_env.sh" + +pushd client +west build -b nrf52_bsim && \ + cp -v build/zephyr/zephyr.exe "${test_exe_d0}" +popd + +pushd server +west build -b nrf52_bsim && \ + cp -v build/zephyr/zephyr.exe "${test_exe_d1}" +popd diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_env.sh b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_env.sh new file mode 100755 index 00000000000..66b074ca3d8 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/_env.sh @@ -0,0 +1,15 @@ +#!/bin/env bash +# Copyright 2023 Codecoup +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" + +test_name="$(basename "$(realpath "$bash_source_dir/..")")" +bsim_bin="${BSIM_OUT_PATH}/bin" +verbosity_level=2 +BOARD="${BOARD:-nrf52_bsim}" +test_exe_d0="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_att_${test_name}_client_prj_conf" +test_exe_d1="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_att_${test_name}_server_prj_conf" diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test.sh new file mode 100755 index 00000000000..8ea8f38cddc --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test.sh @@ -0,0 +1,27 @@ +#!/bin/env bash +# Copyright 2023 Codecoup +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +simulation_id=$(basename "$0") +source "${bash_source_dir}/_env.sh" +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n===== ATT retry on security error (auto security elevation) ======\n\n" + +Execute "$test_exe_d0" \ + -v=${verbosity_level} -s="${simulation_id}" -d=0 -testid=test_client \ + -RealEncryption=1 + +Execute "$test_exe_d1" \ + -v=${verbosity_level} -s="${simulation_id}" -d=1 -testid=test_server \ + -RealEncryption=1 + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s="${simulation_id}" \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test_security_request.sh b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test_security_request.sh new file mode 100755 index 00000000000..8d7c86c4d04 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_scripts/run_test_security_request.sh @@ -0,0 +1,27 @@ +#!/bin/env bash +# Copyright 2023 Codecoup +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +simulation_id=$(basename "$0") +source "${bash_source_dir}/_env.sh" +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +printf "\n\n==== ATT retry on security error (peripheral security request) ====\n\n" + +Execute "$test_exe_d0" \ + -v=${verbosity_level} -s="${simulation_id}" -d=0 -testid=test_client_security_request \ + -RealEncryption=1 + +Execute "$test_exe_d1" \ + -v=${verbosity_level} -s="${simulation_id}" -d=1 -testid=test_server_security_request \ + -RealEncryption=1 + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s="${simulation_id}" \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.c b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.c new file mode 100644 index 00000000000..cacb0fa9e53 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.c @@ -0,0 +1,21 @@ +/* Copyright (c) 2023 Codecoup + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "test_utils.h" + +void test_init(void) +{ + bst_result = In_progress; + bst_ticker_set_next_tick_absolute(SIMULATED_TEST_TIMEOUT); +} + +void test_tick(bs_time_t HW_device_time) +{ + bs_trace_debug_time(0, "Simulation ends now.\n"); + if (bst_result == In_progress) { + bst_result = Failed; + bs_trace_error("Test did not pass before simulation ended. Consider increasing " + "simulation length.\n"); + } +} diff --git a/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.h b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.h new file mode 100644 index 00000000000..0d5113f00f6 --- /dev/null +++ b/tests/bsim/bluetooth/host/att/retry_on_sec_err/test_utils.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2023 Codecoup + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DECLARE_FLAG(flag) extern atomic_t flag +#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * 1000000) +#define SIMULATED_TEST_TIMEOUT BS_SECONDS(60) + +extern enum bst_result_t bst_result; + +void test_init(void); +void test_tick(bs_time_t HW_device_time); diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 7a9757e3e4a..9840083305c 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -35,6 +35,8 @@ app=tests/bsim/bluetooth/host/att/eatt_notif conf_file=prj.conf compile app=tests/bsim/bluetooth/host/att/mtu_update compile app=tests/bsim/bluetooth/host/att/read_fill_buf/client compile app=tests/bsim/bluetooth/host/att/read_fill_buf/server compile +app=tests/bsim/bluetooth/host/att/retry_on_sec_err/client compile +app=tests/bsim/bluetooth/host/att/retry_on_sec_err/server compile app=tests/bsim/bluetooth/host/att/sequential/dut compile app=tests/bsim/bluetooth/host/att/sequential/tester compile app=tests/bsim/bluetooth/host/att/long_read compile From 9439c816e95b9453389981c76d293a628e18c7ce Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 3 Nov 2023 16:31:25 +0000 Subject: [PATCH 3456/4498] input: split npcx generic keyboard code into input_kbd_matrix.c Move all the generic code from the Nuvoton NPCX keyboard scanning driver into input_kbd_matrix.c. While doing that convert few configs into devicetree properties and tweak few other things to enable the generic code to support multiple instances. This is limited to 8 rows for now, and that's fine for all the current in-tree drivers, the limit could be removed down the road but this should be fine for now, added few generic build checks to make sure a driver does not go over the limit, as well and some more implementation specific checks. Signed-off-by: Fabio Baltieri --- drivers/input/Kconfig.npcx | 20 +- drivers/input/input_kbd_matrix.c | 281 +++++++++++++++++- drivers/input/input_kbd_matrix.h | 90 +++++- drivers/input/input_npcx_kbd.c | 343 +++------------------- dts/bindings/input/kbd-matrix-common.yaml | 52 ++++ dts/bindings/input/nuvoton,npcx-kbd.yaml | 32 -- 6 files changed, 454 insertions(+), 364 deletions(-) diff --git a/drivers/input/Kconfig.npcx b/drivers/input/Kconfig.npcx index ad738ac6563..ef380b0ca4b 100644 --- a/drivers/input/Kconfig.npcx +++ b/drivers/input/Kconfig.npcx @@ -3,7 +3,7 @@ # Copyright (c) 2022 Nuvoton Technology Corporation. # SPDX-License-Identifier: Apache-2.0 -menuconfig INPUT_NPCX_KBD +config INPUT_NPCX_KBD bool "Nuvoton NPCX embedded controller (EC) keyboard scan driver" default y depends on DT_HAS_NUVOTON_NPCX_KBD_ENABLED @@ -13,26 +13,10 @@ menuconfig INPUT_NPCX_KBD This option enables the keyboard scan driver for NPCX family of processors. -if INPUT_NPCX_KBD - -config INPUT_NPCX_KBD_POLL_PERIOD_MS - int "Keyscan NPCX Poll Period" - default 5 - help - Defines the poll period in msecs between between matrix scans. - config INPUT_NPCX_KBD_KSO_HIGH_DRIVE bool "Select quasi-bidirectional buffers for KSO pins" default y + depends on INPUT_NPCX_KBD help Select quasi-bidirectional buffers for KSO pins to reduce the low-to-high transition time. - -config INPUT_NPCX_KBD_POLL_COL_OUTPUT_SETTLE_TIME_US - int "keyboard matrix poll column output settle time" - default 50 - help - Delay (us) between setting column output and waiting for it - to settle - -endif # INPUT_NPCX_KBD diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 0ac6d4b1777..d6da7764f73 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -1,23 +1,298 @@ /* + * Copyright 2019 Intel Corporation + * Copyright 2022 Nuvoton Technology Corporation. * Copyright 2023 Google LLC * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include +#include +#include + +#define LOG_LEVEL CONFIG_INPUT_LOG_LEVEL +LOG_MODULE_REGISTER(input_kbd_matrix); #include "input_kbd_matrix.h" -int input_kbd_matrix_common_init(const struct device *dev) +#define INPUT_KBD_MATRIX_ROW_MASK UINT8_MAX + +void input_kbd_matrix_poll_start(const struct device *dev) +{ + struct input_kbd_matrix_common_data *data = dev->data; + + k_sem_give(&data->poll_lock); +} + +static bool input_kbd_matrix_ghosting(const struct device *dev) +{ + const struct input_kbd_matrix_common_config *cfg = dev->config; + const uint8_t *state = cfg->matrix_new_state; + + /* + * Matrix keyboard designs are suceptible to ghosting. + * An extra key appears to be pressed when 3 keys belonging to the same + * block are pressed. For example, in the following block: + * + * . . w . q . + * . . . . . . + * . . . . . . + * . . m . a . + * + * the key m would look as pressed if the user pressed keys w, q and a + * simultaneously. A block can also be formed, with not adjacent + * columns. + */ + for (int c = 0; c < cfg->col_size; c++) { + if (!state[c]) { + continue; + } + + for (int c_next = c + 1; c_next < cfg->col_size; c_next++) { + /* + * We AND the columns to detect a "block". This is an + * indication of ghosting, due to current flowing from + * a key which was never pressed. In our case, current + * flowing is a bit set to 1 as we flipped the bits + * when the matrix was scanned. Now we OR the colums + * using z&(z-1) which is non-zero only if z has more + * than one bit set. + */ + uint8_t common_row_bits = state[c] & state[c_next]; + + if (common_row_bits & (common_row_bits - 1)) { + return true; + } + } + } + + return false; +} + +static bool input_kbd_matrix_scan(const struct device *dev) +{ + const struct input_kbd_matrix_common_config *cfg = dev->config; + const struct input_kbd_matrix_api *api = &cfg->api; + int row; + uint8_t key_event = 0U; + + for (int col = 0; col < cfg->col_size; col++) { + api->drive_column(dev, col); + + /* Allow the matrix to stabilize before reading it */ + k_busy_wait(cfg->settle_time_us); + + row = api->read_row(dev) & INPUT_KBD_MATRIX_ROW_MASK; + cfg->matrix_new_state[col] = row; + key_event |= row; + } + + api->drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE); + + return key_event != 0U; +} + +static void input_kbd_matrix_update_state(const struct device *dev) +{ + const struct input_kbd_matrix_common_config *cfg = dev->config; + struct input_kbd_matrix_common_data *data = dev->data; + uint8_t *matrix_new_state = cfg->matrix_new_state; + uint32_t cycles_now = k_cycle_get_32(); + uint8_t row_changed; + uint8_t deb_col; + + data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now; + + /* + * The intent of this loop is to gather information related to key + * changes. + */ + for (int c = 0; c < cfg->col_size; c++) { + /* Check if there was an update from the previous scan */ + row_changed = matrix_new_state[c] ^ cfg->matrix_previous_state[c]; + + if (!row_changed) { + continue; + } + + for (int r = 0; r < cfg->row_size; r++) { + uint8_t cyc_idx = c * cfg->row_size + r; + + /* + * Index all they keys that changed for each row in + * order to debounce each key in terms of it + */ + if (row_changed & BIT(r)) { + cfg->scan_cycle_idx[cyc_idx] = data->scan_cycles_idx; + } + } + + cfg->matrix_unstable_state[c] |= row_changed; + cfg->matrix_previous_state[c] = matrix_new_state[c]; + } + + for (int c = 0; c < cfg->col_size; c++) { + deb_col = cfg->matrix_unstable_state[c]; + + if (!deb_col) { + continue; + } + + /* Debouncing for each row key occurs here */ + for (int r = 0; r < cfg->row_size; r++) { + uint8_t mask = BIT(r); + uint8_t row_bit = matrix_new_state[c] & mask; + + /* Continue if we already debounce a key */ + if (!(deb_col & mask)) { + continue; + } + + uint8_t cyc_idx = c * cfg->row_size + r; + uint8_t scan_cyc_idx = cfg->scan_cycle_idx[cyc_idx]; + uint8_t scan_clk_cycle = data->scan_clk_cycle[scan_cyc_idx]; + + /* Convert the clock cycle differences to usec */ + uint32_t debt = k_cyc_to_us_floor32(cycles_now - scan_clk_cycle); + + /* Does the key requires more time to be debounced? */ + if (debt < (row_bit ? cfg->debounce_down_ms : cfg->debounce_up_ms)) { + /* Need more time to debounce */ + continue; + } + + cfg->matrix_unstable_state[c] &= ~row_bit; + + /* Check if there was a change in the stable state */ + if ((cfg->matrix_stable_state[c] & mask) == row_bit) { + /* Key state did not change */ + continue; + } + + /* + * The current row has been debounced, therefore update + * the stable state. Then, proceed to notify the + * application about the keys pressed. + */ + cfg->matrix_stable_state[c] ^= mask; + + input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); + } + } +} + +static bool input_kbd_matrix_check_key_events(const struct device *dev) +{ + const struct input_kbd_matrix_common_config *cfg = dev->config; + struct input_kbd_matrix_common_data *data = dev->data; + bool key_pressed; + + if (++data->scan_cycles_idx >= INPUT_KBD_MATRIX_SCAN_OCURRENCES) { + data->scan_cycles_idx = 0U; + } + + /* Scan the matrix */ + key_pressed = input_kbd_matrix_scan(dev); + + for (int c = 0; c < cfg->col_size; c++) { + LOG_DBG("U%x, P%x, N%x", + cfg->matrix_unstable_state[c], + cfg->matrix_previous_state[c], + cfg->matrix_new_state[c]); + } + + /* Abort if ghosting is detected */ + if (cfg->ghostkey_check && input_kbd_matrix_ghosting(dev)) { + return key_pressed; + } + + input_kbd_matrix_update_state(dev); + + return key_pressed; +} + +static void input_kbd_matrix_poll(const struct device *dev) { + const struct input_kbd_matrix_common_config *cfg = dev->config; + k_timepoint_t poll_time_end = sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms)); + uint32_t current_cycles; + uint32_t cycles_diff; + uint32_t wait_period_us; + + while (true) { + uint32_t start_period_cycles = k_cycle_get_32(); + + if (input_kbd_matrix_check_key_events(dev)) { + poll_time_end = sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms)); + } else if (sys_timepoint_expired(poll_time_end)) { + break; + } + + /* + * Subtract the time invested from the sleep period in order to + * compensate for the time invested in debouncing a key + */ + current_cycles = k_cycle_get_32(); + cycles_diff = current_cycles - start_period_cycles; + wait_period_us = cfg->poll_period_us - k_cyc_to_us_floor32(cycles_diff); + + /* Wait for at least 1ms */ + if (wait_period_us < USEC_PER_MSEC) { + wait_period_us = USEC_PER_MSEC; + } + + /* + * Wait period results in a larger number when current cycles + * counter wrap. In this case, the whole poll period is used + */ + if (wait_period_us > cfg->poll_period_us) { + LOG_DBG("wait_period_us: %u", wait_period_us); + + wait_period_us = cfg->poll_period_us; + } + + /* Allow other threads to run while we sleep */ + k_usleep(wait_period_us); + } +} + +static void input_kbd_matrix_polling_thread(void *arg1, void *unused2, void *unused3) +{ + const struct device *dev = arg1; const struct input_kbd_matrix_common_config *cfg = dev->config; const struct input_kbd_matrix_api *api = &cfg->api; - struct input_kbd_matrix_common_data *const data = dev->data; + struct input_kbd_matrix_common_data *data = dev->data; + + ARG_UNUSED(unused2); + ARG_UNUSED(unused3); + + while (true) { + api->drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL); + api->set_detect_mode(dev, true); + + k_sem_take(&data->poll_lock, K_FOREVER); + LOG_DBG("Start KB scan"); + + /* Disable interrupt of KSI pins and start polling */ + api->set_detect_mode(dev, false); + + input_kbd_matrix_poll(dev); + } +} + +int input_kbd_matrix_common_init(const struct device *dev) +{ + struct input_kbd_matrix_common_data *data = dev->data; + + k_sem_init(&data->poll_lock, 0, 1); k_thread_create(&data->thread, data->thread_stack, CONFIG_INPUT_KBD_MATRIX_THREAD_STACK_SIZE, - api->polling_thread, (void *)dev, NULL, NULL, + input_kbd_matrix_polling_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(4), 0, K_NO_WAIT); k_thread_name_set(&data->thread, dev->name); diff --git a/drivers/input/input_kbd_matrix.h b/drivers/input/input_kbd_matrix.h index b70e0d5c4d1..ec286ab5520 100644 --- a/drivers/input/input_kbd_matrix.h +++ b/drivers/input/input_kbd_matrix.h @@ -6,13 +6,26 @@ #include #include +#include +#include #include +/** Special drive_column argument for not driving any column */ +#define INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE -1 + +/** Special drive_column argument for driving all the columns */ +#define INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL -2 + +/** Number of tracked scan cycles */ +#define INPUT_KBD_MATRIX_SCAN_OCURRENCES 30U + /** * @brief Keyboard matrix internal APIs. */ struct input_kbd_matrix_api { - k_thread_entry_t polling_thread; + void (*drive_column)(const struct device *dev, int col); + int (*read_row)(const struct device *dev); + void (*set_detect_mode)(const struct device *dev, bool enabled); }; /** @@ -22,8 +35,53 @@ struct input_kbd_matrix_api { */ struct input_kbd_matrix_common_config { struct input_kbd_matrix_api api; + uint8_t row_size; + uint8_t col_size; + uint32_t poll_period_us; + uint32_t poll_timeout_ms; + uint32_t debounce_down_ms; + uint32_t debounce_up_ms; + uint32_t settle_time_us; + bool ghostkey_check; + + /* extra data pointers */ + uint8_t *matrix_stable_state; + uint8_t *matrix_unstable_state; + uint8_t *matrix_previous_state; + uint8_t *matrix_new_state; + uint8_t *scan_cycle_idx; }; +#define INPUT_KBD_MATRIX_DATA_NAME(node_id, name) \ + _CONCAT(__input_kbd_matrix_, \ + _CONCAT(name, DEVICE_DT_NAME_GET(node_id))) + +/** + * @brief Defines the common keyboard matrix support data from devicetree. + */ +#define INPUT_KBD_MATRIX_DT_DEFINE(node_id) \ + BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, row_size), 1, 8), "invalid row-size"); \ + BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, col_size), 1, UINT8_MAX), "invalid col-size"); \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ + node_id, stable_state)[DT_PROP(node_id, col_size)]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ + node_id, unstable_state)[DT_PROP(node_id, col_size)]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ + node_id, previous_state)[DT_PROP(node_id, col_size)]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ + node_id, new_state)[DT_PROP(node_id, col_size)]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ + node_id, scan_cycle_idx)[DT_PROP(node_id, row_size) * \ + DT_PROP(node_id, col_size)]; + +/** + * @brief Defines the common keyboard matrix support data from devicetree instance. + * + * @param inst Instance. + */ +#define INPUT_KBD_MATRIX_DT_INST_DEFINE(inst) \ + INPUT_KBD_MATRIX_DT_DEFINE(DT_DRV_INST(inst)) + /** * @brief Initialize common keyboard matrix config from devicetree. * @@ -32,6 +90,20 @@ struct input_kbd_matrix_common_config { #define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, _api) \ { \ .api = _api, \ + .row_size = DT_PROP(node_id, row_size), \ + .col_size = DT_PROP(node_id, col_size), \ + .poll_period_us = DT_PROP(node_id, poll_period_ms) * USEC_PER_MSEC, \ + .poll_timeout_ms = DT_PROP(node_id, poll_timeout_ms), \ + .debounce_down_ms = DT_PROP(node_id, debounce_down_ms), \ + .debounce_up_ms = DT_PROP(node_id, debounce_up_ms), \ + .settle_time_us = DT_PROP(node_id, settle_time_us), \ + .ghostkey_check = !DT_PROP(node_id, no_ghostkey_check), \ + \ + .matrix_stable_state = INPUT_KBD_MATRIX_DATA_NAME(node_id, stable_state), \ + .matrix_unstable_state = INPUT_KBD_MATRIX_DATA_NAME(node_id, unstable_state), \ + .matrix_previous_state = INPUT_KBD_MATRIX_DATA_NAME(node_id, previous_state), \ + .matrix_new_state = INPUT_KBD_MATRIX_DATA_NAME(node_id, new_state), \ + .scan_cycle_idx = INPUT_KBD_MATRIX_DATA_NAME(node_id, scan_cycle_idx), \ } /** @@ -49,6 +121,12 @@ struct input_kbd_matrix_common_config { * This structure **must** be placed first in the driver's data structure. */ struct input_kbd_matrix_common_data { + /* Track previous cycles, used for debouncing. */ + uint8_t scan_clk_cycle[INPUT_KBD_MATRIX_SCAN_OCURRENCES]; + uint8_t scan_cycles_idx; + + struct k_sem poll_lock; + struct k_thread thread; K_KERNEL_STACK_MEMBER(thread_stack, @@ -67,6 +145,16 @@ struct input_kbd_matrix_common_data { BUILD_ASSERT(offsetof(data, common) == 0, \ "struct input_kbd_matrix_common_data must be placed first") +/** + * @brief Start scanning the keyboard matrix + * + * Starts the keyboard matrix scanning cycle, this should be called in reaction + * of a press event, after the device has been put in detect mode. + * + * @param dev Keyboard matrix device instance. + */ +void input_kbd_matrix_poll_start(const struct device *dev); + /** * @brief Common function to initialize a keyboard matrix device at init time. * diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index 2b3284e6d9c..65ef7747875 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -12,24 +12,16 @@ #include #include -#include #include #include +#include +#include #include #define LOG_LEVEL CONFIG_INPUT_LOG_LEVEL LOG_MODULE_REGISTER(input_npcx_kbd); -#define KEYBOARD_COLUMN_DRIVE_ALL -2 -#define KEYBOARD_COLUMN_DRIVE_NONE -1 - -/* Number of tracked scan times */ -#define SCAN_OCURRENCES 30U - -#define KSCAN_ROW_SIZE DT_INST_PROP(0, row_size) -#define KSCAN_COL_SIZE DT_INST_PROP(0, col_size) - -#define HAS_GHOSTING_ENABLED !DT_INST_PROP(0, no_ghostkey_check) +#define ROW_SIZE DT_INST_PROP(0, row_size) /* Driver config */ struct input_npcx_kbd_config { @@ -44,31 +36,13 @@ struct input_npcx_kbd_config { int irq; /* Size of keyboard inputs-wui mapping array */ int wui_size; - uint8_t row_size; - uint8_t col_size; - uint32_t deb_time_press; - uint32_t deb_time_rel; /* Mapping table between keyboard inputs and wui */ struct npcx_wui wui_maps[]; }; struct input_npcx_kbd_data { struct input_kbd_matrix_common_data common; - int64_t poll_timeout_us; - uint32_t poll_period_us; - uint8_t matrix_stable_state[KSCAN_COL_SIZE]; - uint8_t matrix_unstable_state[KSCAN_COL_SIZE]; - uint8_t matrix_previous_state[KSCAN_COL_SIZE]; - uint8_t matrix_new_state[KSCAN_COL_SIZE]; - /* Index in to the scan_clock_cycle to indicate start of debouncing */ - uint8_t scan_cycle_idx[KSCAN_COL_SIZE * KSCAN_ROW_SIZE]; - struct miwu_callback ksi_callback[KSCAN_ROW_SIZE]; - /* Track previous "elapsed clock cycles" per matrix scan. This - * is used to calculate the debouncing time for every key - */ - uint8_t scan_clk_cycle[SCAN_OCURRENCES]; - struct k_sem poll_lock; - uint8_t scan_cycles_idx; + struct miwu_callback ksi_callback[ROW_SIZE]; }; INPUT_KBD_STRUCT_CHECK(struct input_npcx_kbd_config, struct input_npcx_kbd_data); @@ -77,40 +51,39 @@ INPUT_KBD_STRUCT_CHECK(struct input_npcx_kbd_config, struct input_npcx_kbd_data) static void input_npcx_kbd_ksi_isr(const struct device *dev, struct npcx_wui *wui) { ARG_UNUSED(wui); - struct input_npcx_kbd_data *const data = dev->data; - k_sem_give(&data->poll_lock); + input_kbd_matrix_poll_start(dev); } -static int input_npcx_kbd_resume_detection(const struct device *dev, bool resume) +static void input_npcx_kbd_set_detect_mode(const struct device *dev, bool enabled) { const struct input_npcx_kbd_config *const config = dev->config; - if (resume) { + if (enabled) { irq_enable(config->irq); } else { irq_disable(config->irq); } - - return 0; } -static int input_npcx_kbd_drive_column(const struct device *dev, int col) +static void input_npcx_kbd_drive_column(const struct device *dev, int col) { const struct input_npcx_kbd_config *config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; struct kbs_reg *const inst = config->base; uint32_t mask; - if (col >= config->col_size) { - return -EINVAL; + if (col >= common->col_size) { + LOG_ERR("invalid column: %d", col); + return; } - if (col == KEYBOARD_COLUMN_DRIVE_NONE) { + if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { /* Drive all lines to high: key detection is disabled */ mask = ~0; - } else if (col == KEYBOARD_COLUMN_DRIVE_ALL) { + } else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) { /* Drive all lines to low for detection any key press */ - mask = ~(BIT(config->col_size) - 1); + mask = ~BIT_MASK(common->col_size); } else { /* * Drive one line to low for determining which key's state @@ -123,275 +96,23 @@ static int input_npcx_kbd_drive_column(const struct device *dev, int col) inst->KBSOUT0 = (mask & 0xFFFF); inst->KBSOUT1 = ((mask >> 16) & 0x03); - - return 0; } static int input_npcx_kbd_read_row(const struct device *dev) { const struct input_npcx_kbd_config *config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; struct kbs_reg *const inst = config->base; int val; val = inst->KBSIN; /* 1 means key pressed, otherwise means key released. */ - val = (~val & (BIT(config->row_size) - 1)); + val = ~val & BIT_MASK(common->row_size); return val; } -static bool is_matrix_ghosting(const struct device *dev, const uint8_t *state) -{ - const struct input_npcx_kbd_config *const config = dev->config; - - /* - * Matrix keyboard designs are suceptible to ghosting. - * An extra key appears to be pressed when 3 keys belonging to the same - * block are pressed. For example, in the following block: - * - * . . w . q . - * . . . . . . - * . . . . . . - * . . m . a . - * - * the key m would look as pressed if the user pressed keys w, q and a - * simultaneously. A block can also be formed, with not adjacent - * columns. - */ - for (int c = 0; c < config->col_size; c++) { - if (!state[c]) { - continue; - } - - for (int c_next = c + 1; c_next < config->col_size; c_next++) { - /* - * We AND the columns to detect a "block". This is an - * indication of ghosting, due to current flowing from - * a key which was never pressed. In our case, current - * flowing is a bit set to 1 as we flipped the bits - * when the matrix was scanned. Now we OR the colums - * using z&(z-1) which is non-zero only if z has more - * than one bit set. - */ - uint8_t common_row_bits = state[c] & state[c_next]; - - if (common_row_bits & (common_row_bits - 1)) { - return true; - } - } - } - - return false; -} - -static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state) -{ - const struct input_npcx_kbd_config *const config = dev->config; - int row; - uint8_t key_event = 0U; - - for (int col = 0; col < config->col_size; col++) { - input_npcx_kbd_drive_column(dev, col); - - /* Allow the matrix to stabilize before reading it */ - k_busy_wait(CONFIG_INPUT_NPCX_KBD_POLL_COL_OUTPUT_SETTLE_TIME_US); - - row = input_npcx_kbd_read_row(dev); - new_state[col] = row & 0xFF; - key_event |= row; - } - - input_npcx_kbd_drive_column(dev, KEYBOARD_COLUMN_DRIVE_NONE); - - return key_event != 0U; -} - -static void update_matrix_state(const struct device *dev, uint8_t *matrix_new_state) -{ - const struct input_npcx_kbd_config *const config = dev->config; - struct input_npcx_kbd_data *const data = dev->data; - uint32_t cycles_now = k_cycle_get_32(); - uint8_t row_changed = 0U; - uint8_t deb_col; - - data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now; - - /* - * The intent of this loop is to gather information related to key - * changes. - */ - for (int c = 0; c < config->col_size; c++) { - /* Check if there was an update from the previous scan */ - row_changed = matrix_new_state[c] ^ data->matrix_previous_state[c]; - - if (!row_changed) { - continue; - } - - for (int r = 0; r < config->row_size; r++) { - uint8_t cyc_idx = c * config->row_size + r; - - /* - * Index all they keys that changed for each row in - * order to debounce each key in terms of it - */ - if (row_changed & BIT(r)) { - data->scan_cycle_idx[cyc_idx] = data->scan_cycles_idx; - } - } - - data->matrix_unstable_state[c] |= row_changed; - data->matrix_previous_state[c] = matrix_new_state[c]; - } - - for (int c = 0; c < config->col_size; c++) { - deb_col = data->matrix_unstable_state[c]; - - if (!deb_col) { - continue; - } - - /* Debouncing for each row key occurs here */ - for (int r = 0; r < config->row_size; r++) { - uint8_t mask = BIT(r); - uint8_t row_bit = matrix_new_state[c] & mask; - - /* Continue if we already debounce a key */ - if (!(deb_col & mask)) { - continue; - } - - uint8_t cyc_idx = c * config->row_size + r; - /* Convert the clock cycle differences to usec */ - uint32_t debt = k_cyc_to_us_floor32( - cycles_now - data->scan_clk_cycle[data->scan_cycle_idx[cyc_idx]]); - - /* Does the key requires more time to be debounced? */ - if (debt < (row_bit ? config->deb_time_press : config->deb_time_rel)) { - /* Need more time to debounce */ - continue; - } - - data->matrix_unstable_state[c] &= ~row_bit; - - /* Check if there was a change in the stable state */ - if ((data->matrix_stable_state[c] & mask) == row_bit) { - /* Key state did not change */ - continue; - } - - /* - * The current row has been debounced, therefore update - * the stable state. Then, proceed to notify the - * application about the keys pressed. - */ - data->matrix_stable_state[c] ^= mask; - - input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER); - input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER); - input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); - } - } -} - -static bool check_key_events(const struct device *dev) -{ - const struct input_npcx_kbd_config *const config = dev->config; - struct input_npcx_kbd_data *const data = dev->data; - uint8_t *matrix_new_state = data->matrix_new_state; - bool key_pressed = false; - - if (++data->scan_cycles_idx >= SCAN_OCURRENCES) { - data->scan_cycles_idx = 0U; - } - - /* Scan the matrix */ - key_pressed = read_keyboard_matrix(dev, matrix_new_state); - - for (int c = 0; c < config->col_size; c++) { - LOG_DBG("U%x, P%x, N%x", data->matrix_unstable_state[c], - data->matrix_previous_state[c], matrix_new_state[c]); - } - - /* Abort if ghosting is detected */ - if (HAS_GHOSTING_ENABLED && is_matrix_ghosting(dev, matrix_new_state)) { - return key_pressed; - } - - update_matrix_state(dev, matrix_new_state); - - return key_pressed; -} - -static void kbd_matrix_poll(const struct device *dev) -{ - struct input_npcx_kbd_data *const data = dev->data; - k_timepoint_t poll_time_end = sys_timepoint_calc(K_USEC(data->poll_timeout_us)); - uint32_t current_cycles; - uint32_t cycles_diff; - uint32_t wait_period; - - while (true) { - uint32_t start_period_cycles = k_cycle_get_32(); - - if (check_key_events(dev)) { - poll_time_end = sys_timepoint_calc(K_USEC(data->poll_timeout_us)); - } else if (sys_timepoint_expired(poll_time_end)) { - break; - } - - /* - * Subtract the time invested from the sleep period in order to - * compensate for the time invested in debouncing a key - */ - current_cycles = k_cycle_get_32(); - cycles_diff = current_cycles - start_period_cycles; - wait_period = data->poll_period_us - k_cyc_to_us_floor32(cycles_diff); - - /* Override wait_period in case it is less than 1 ms */ - if (wait_period < USEC_PER_MSEC) { - wait_period = USEC_PER_MSEC; - } - - /* - * Wait period results in a larger number when current cycles - * counter wrap. In this case, the whole poll period is used - */ - if (wait_period > data->poll_period_us) { - LOG_DBG("wait_period: %u", wait_period); - - wait_period = data->poll_period_us; - } - - /* Allow other threads to run while we sleep */ - k_usleep(wait_period); - } -} - -static void kbd_matrix_polling_thread(void *dummy1, void *dummy2, void *dummy3) -{ - const struct device *dev = dummy1; - struct input_npcx_kbd_data *const data = dev->data; - - ARG_UNUSED(dummy2); - ARG_UNUSED(dummy3); - - while (true) { - /* Enable interrupt of KSI pins */ - input_npcx_kbd_resume_detection(dev, true); - - input_npcx_kbd_drive_column(dev, KEYBOARD_COLUMN_DRIVE_ALL); - k_sem_take(&data->poll_lock, K_FOREVER); - LOG_DBG("Start KB scan"); - - /* Disable interrupt of KSI pins and start polling */ - input_npcx_kbd_resume_detection(dev, false); - - kbd_matrix_poll(dev); - } -} - static void input_npcx_kbd_init_ksi_wui_callback(const struct device *dev, struct miwu_callback *callback, const struct npcx_wui *wui, @@ -415,6 +136,7 @@ static int input_npcx_kbd_init(const struct device *dev) { const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE); const struct input_npcx_kbd_config *const config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; struct input_npcx_kbd_data *const data = dev->data; struct kbs_reg *const inst = config->base; int ret; @@ -428,6 +150,7 @@ static int input_npcx_kbd_init(const struct device *dev) ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->clk_cfg); if (ret < 0) { LOG_ERR("Turn on KBSCAN clock fail %d", ret); + return -EIO; } /* Pull-up KBSIN0-7 internally */ @@ -453,10 +176,15 @@ static int input_npcx_kbd_init(const struct device *dev) } /* Drive all column lines to low for detection any key press */ - input_npcx_kbd_drive_column(dev, KEYBOARD_COLUMN_DRIVE_NONE); + input_npcx_kbd_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE); + + if (common->row_size != ROW_SIZE) { + LOG_ERR("Unexpected ROW_SIZE: %d != %d", common->row_size, ROW_SIZE); + return -EINVAL; + } /* Configure wake-up input and callback for keyboard input signal */ - for (int i = 0; i < config->row_size; i++) { + for (int i = 0; i < common->row_size; i++) { input_npcx_kbd_init_ksi_wui_callback( dev, &data->ksi_callback[i], &config->wui_maps[i], input_npcx_kbd_ksi_isr); @@ -469,20 +197,17 @@ static int input_npcx_kbd_init(const struct device *dev) return ret; } - /* Initialize semaphore used by keyboard scan task and driver */ - k_sem_init(&data->poll_lock, 0, 1); - - /* Time figures are transformed from msec to usec */ - data->poll_period_us = (uint32_t)(CONFIG_INPUT_NPCX_KBD_POLL_PERIOD_MS * USEC_PER_MSEC); - data->poll_timeout_us = 100 * USEC_PER_MSEC; - return input_kbd_matrix_common_init(dev); } PINCTRL_DT_INST_DEFINE(0); +INPUT_KBD_MATRIX_DT_INST_DEFINE(0); + static const struct input_kbd_matrix_api npcx_kbd_api = { - .polling_thread = kbd_matrix_polling_thread, + .drive_column = input_npcx_kbd_drive_column, + .read_row = input_npcx_kbd_read_row, + .set_detect_mode = input_npcx_kbd_set_detect_mode, }; static const struct input_npcx_kbd_config npcx_kbd_cfg = { @@ -493,10 +218,6 @@ static const struct input_npcx_kbd_config npcx_kbd_cfg = { .irq = DT_INST_IRQN(0), .wui_size = NPCX_DT_WUI_ITEMS_LEN(0), .wui_maps = NPCX_DT_WUI_ITEMS_LIST(0), - .row_size = KSCAN_ROW_SIZE, - .col_size = KSCAN_COL_SIZE, - .deb_time_press = DT_INST_PROP(0, debounce_down_ms), - .deb_time_rel = DT_INST_PROP(0, debounce_up_ms), }; static struct input_npcx_kbd_data npcx_kbd_data; @@ -507,3 +228,5 @@ DEVICE_DT_INST_DEFINE(0, input_npcx_kbd_init, NULL, BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "only one nuvoton,npcx-kbd compatible node can be supported"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, row_size), 1, 8), "invalid row-size"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, col_size), 1, 18), "invalid col-size"); diff --git a/dts/bindings/input/kbd-matrix-common.yaml b/dts/bindings/input/kbd-matrix-common.yaml index 87dbec147b4..53efd29dc9f 100644 --- a/dts/bindings/input/kbd-matrix-common.yaml +++ b/dts/bindings/input/kbd-matrix-common.yaml @@ -4,3 +4,55 @@ description: Keyboard matrix device include: base.yaml + +properties: + row-size: + type: int + required: true + description: | + The number of rows in the keyboard matrix. + + col-size: + type: int + required: true + description: | + The number of column in the keyboard matrix. + + poll-period-ms: + type: int + default: 5 + description: | + Defines the poll period in msecs between between matrix scans. Defaults + to 5ms if unsepcified. + + poll-timeout-ms: + type: int + default: 100 + description: | + How long to wait before going from polling back to idle state. Defaults + to 100ms if unspecified. + + debounce-down-ms: + type: int + default: 10 + description: | + Debouncing time for a key press event. Defaults to 10ms if unspecified. + + debounce-up-ms: + type: int + default: 20 + description: | + Debouncing time for a key release event. Defaults to 20ms if unspecified. + + settle-time-us: + type: int + default: 50 + description: | + Delay between setting column output and reading the row values. Defaults + to 50us if unspecified. + + no-ghostkey-check: + type: boolean + description: | + Ignore the ghost key checking in the driver if the diodes are used + in the matrix hardware. diff --git a/dts/bindings/input/nuvoton,npcx-kbd.yaml b/dts/bindings/input/nuvoton,npcx-kbd.yaml index 130a003d1a4..7ba9956cb6b 100644 --- a/dts/bindings/input/nuvoton,npcx-kbd.yaml +++ b/dts/bindings/input/nuvoton,npcx-kbd.yaml @@ -29,35 +29,3 @@ properties: For example the WUI mapping on 8 KSI pads would be wui-maps = <&wui_io30 &wui_io31 &wui_io27 &wui_io26 &wui_io25 &wui_io24 &wui_io23 &wui_io22>; - - row-size: - type: int - default: 8 - required: true - description: | - The row size is used in the keyboard matrix. - valid range: 1 - 8 - - col-size: - type: int - default: 18 - required: true - description: | - The column size is used in the keyboard matrix. - valid range: 1 - 18 - - debounce-down-ms: - type: int - default: 10 - description: Determines the time in msecs for debouncing a key press. - - debounce-up-ms: - type: int - default: 20 - description: Determines the time in msecs for debouncing a key release. - - no-ghostkey-check: - type: boolean - description: | - Ignore the ghost key checking in the driver if the diodes are used - in the matrix hardware. From e5dbb26c723894d05bd548f9ea38ffc1c44df381 Mon Sep 17 00:00:00 2001 From: Daniel Istvan Nemeth Date: Wed, 8 Nov 2023 00:34:26 +0100 Subject: [PATCH 3457/4498] samples: drivers: led_ws2812: nRF5340DK support New config files to support nrf5340-based boards Signed-off-by: Daniel Istvan Nemeth --- samples/drivers/led_ws2812/README.rst | 2 ++ .../led_ws2812/boards/nrf5340dk_nrf5340.conf | 5 +++ .../boards/nrf5340dk_nrf5340.overlay | 36 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.conf create mode 100644 samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.overlay diff --git a/samples/drivers/led_ws2812/README.rst b/samples/drivers/led_ws2812/README.rst index 5529604b0a8..183875520f2 100644 --- a/samples/drivers/led_ws2812/README.rst +++ b/samples/drivers/led_ws2812/README.rst @@ -102,6 +102,8 @@ This sample uses different drivers depending on the selected board: I2S driver: - thingy52_nrf52832 +- nrf5340dk_nrf5340 (3.3V logic level, a logic level shifter may be required) + - should work for other boards featuring an nRF5340 host processor SPI driver: diff --git a/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.conf b/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.conf new file mode 100644 index 00000000000..f5d64aaf5da --- /dev/null +++ b/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.conf @@ -0,0 +1,5 @@ +CONFIG_SPI=n + +CONFIG_I2S=y +CONFIG_WS2812_STRIP=y +CONFIG_WS2812_STRIP_I2S=y diff --git a/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.overlay b/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.overlay new file mode 100644 index 00000000000..738e7911532 --- /dev/null +++ b/samples/drivers/led_ws2812/boards/nrf5340dk_nrf5340.overlay @@ -0,0 +1,36 @@ +#include + +&pinctrl { + i2s0_default_alt: i2s0_default_alt { + group1 { + /* Default I2S config for the nRF5340, P1.13 is the output */ + psels = , + , + , + ; + }; + }; +}; + +i2s_led: &i2s0 { + status = "okay"; + pinctrl-0 = <&i2s0_default_alt>; + pinctrl-names = "default"; +}; + +/ { + led_strip: ws2812 { + compatible = "worldsemi,ws2812-i2s"; + + i2s-dev = <&i2s_led>; + chain-length = <42>; /* arbitrary; change at will */ + color-mapping = ; + reset-delay = <500>; + }; + + aliases { + led-strip = &led_strip; + }; +}; From 8aba7740b8b190a95daf2ec145fba6a3f78139a5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 6 Nov 2023 16:47:05 +0100 Subject: [PATCH 3458/4498] net: lwm2m: Fix core objects version reporting Core objects version reporting was broken for LwM2M version 1.1, as the default object version not necessarily matches the LwM2M version. Therefore, implement a table with default object versions for particular LwM2M version, which can be looked up when determining whether it's needed to include object version or not during Registration/Discovery. Signed-off-by: Robert Lubos --- include/zephyr/net/lwm2m.h | 1 + subsys/net/lib/lwm2m/lwm2m_registry.c | 53 +++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index 6262f6d103d..a57b5542f88 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -49,6 +49,7 @@ #define LWM2M_OBJECT_PORTFOLIO_ID 16 /**< Portfolio object */ #define LWM2M_OBJECT_BINARYAPPDATACONTAINER_ID 19 /**< Binary App Data Container object */ #define LWM2M_OBJECT_EVENT_LOG_ID 20 /**< Event Log object */ +#define LWM2M_OBJECT_OSCORE_ID 21 /**< OSCORE object */ #define LWM2M_OBJECT_GATEWAY_ID 25 /**< Gateway object */ /* clang-format on */ diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index fc297149d84..210c5525756 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -50,6 +50,41 @@ void lwm2m_registry_unlock(void) { (void)k_mutex_unlock(®istry_lock); } + +/* Default core object version */ +struct default_obj_version { + uint16_t obj_id; + uint8_t version_major; + uint8_t version_minor; +}; + +/* Based on Appendix E of the respective LwM2M specification. */ +static const struct default_obj_version default_obj_versions[] = { +#if defined(CONFIG_LWM2M_VERSION_1_0) + { LWM2M_OBJECT_SECURITY_ID, 1, 0 }, + { LWM2M_OBJECT_SERVER_ID, 1, 0 }, + { LWM2M_OBJECT_ACCESS_CONTROL_ID, 1, 0 }, + { LWM2M_OBJECT_DEVICE_ID, 1, 0 }, + { LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID, 1, 0 }, + { LWM2M_OBJECT_FIRMWARE_ID, 1, 0 }, + { LWM2M_OBJECT_LOCATION_ID, 1, 0 }, + { LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID, 1, 0 }, +#elif defined(CONFIG_LWM2M_VERSION_1_1) + { LWM2M_OBJECT_SECURITY_ID, 1, 1 }, + { LWM2M_OBJECT_SERVER_ID, 1, 1 }, + { LWM2M_OBJECT_ACCESS_CONTROL_ID, 1, 0 }, + { LWM2M_OBJECT_DEVICE_ID, 1, 1 }, + { LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID, 1, 2 }, + { LWM2M_OBJECT_FIRMWARE_ID, 1, 0 }, + { LWM2M_OBJECT_LOCATION_ID, 1, 0 }, + { LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID, 1, 0 }, + /* OSCORE object not implemented yet, but include it for completeness */ + { LWM2M_OBJECT_OSCORE_ID, 1, 0 }, +#else +#error "Default core object versions not defined for LwM2M version" +#endif +}; + /* Resources */ static sys_slist_t engine_obj_list; static sys_slist_t engine_obj_inst_list; @@ -1975,12 +2010,22 @@ struct lwm2m_engine_res_inst *lwm2m_engine_get_res_inst(const struct lwm2m_obj_p bool lwm2m_engine_shall_report_obj_version(const struct lwm2m_engine_obj *obj) { - if (obj->is_core) { - return obj->version_major != LWM2M_PROTOCOL_VERSION_MAJOR || - obj->version_minor != LWM2M_PROTOCOL_VERSION_MINOR; + /* For non-core objects, report version other than 1.0 */ + if (!obj->is_core) { + return obj->version_major != 1 || obj->version_minor != 0; } - return obj->version_major != 1 || obj->version_minor != 0; + /* For core objects, report version based on default version array. */ + for (size_t i = 0; i < ARRAY_SIZE(default_obj_versions); i++) { + if (obj->obj_id != default_obj_versions[i].obj_id) { + continue; + } + + return obj->version_major != default_obj_versions[i].version_major || + obj->version_minor != default_obj_versions[i].version_minor; + } + + return true; } #if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT) From e338299bd4ad2324d882e15c1f7ebb8096f0b44d Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Fri, 3 Nov 2023 19:55:25 +1100 Subject: [PATCH 3459/4498] drivers: adc: adc_ads114s0x: fix incorrect type Affected CONFIG_ADC_ADS114S0X_GPIO=y build. register_addresses was wrong type for ads114s0x_write_multiple_registers() Signed-off-by: Nick Ward --- drivers/adc/adc_ads114s0x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/adc/adc_ads114s0x.c b/drivers/adc/adc_ads114s0x.c index 4ad78c7246a..e5ab699bcbd 100644 --- a/drivers/adc/adc_ads114s0x.c +++ b/drivers/adc/adc_ads114s0x.c @@ -1080,7 +1080,7 @@ static int ads114s0x_gpio_write_config(const struct device *dev) { struct ads114s0x_data *data = dev->data; const struct ads114s0x_config *config = dev->config; - uint8_t register_addresses[2]; + enum ads114s0x_register register_addresses[2]; uint8_t register_values[ARRAY_SIZE(register_addresses)]; uint8_t gpio_dat = 0; uint8_t gpio_con = 0; From 2612aa02ced24ea6b6407c569495d212660177f9 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Fri, 3 Nov 2023 19:58:51 +1100 Subject: [PATCH 3460/4498] tests: drivers: build_all: gpio: add ads1145s0x testcase This fixes multiple CI issues for the ads1145s0x driver. Having a special testcase for the driver limits the CONFIG_ADC=y and CONFIG_ADC_INIT_PRIORITY adjustment requirements. Also fixes address not matching warning for pcal6416a@2 Signed-off-by: Nick Ward --- .../build_all/gpio/adc_ads1145s0x_gpio.conf | 3 +++ .../gpio/adc_ads1145s0x_gpio.overlay | 21 +++++++++++++++ tests/drivers/build_all/gpio/app.overlay | 26 +++---------------- tests/drivers/build_all/gpio/prj.conf | 1 - tests/drivers/build_all/gpio/testcase.yaml | 11 ++++++++ 5 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.conf create mode 100644 tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.overlay diff --git a/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.conf b/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.conf new file mode 100644 index 00000000000..64290a4a491 --- /dev/null +++ b/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.conf @@ -0,0 +1,3 @@ +CONFIG_ADC=y +CONFIG_ADC_ADS114S0X_GPIO=y +CONFIG_ADC_INIT_PRIORITY=80 diff --git a/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.overlay b/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.overlay new file mode 100644 index 00000000000..60078a4efff --- /dev/null +++ b/tests/drivers/build_all/gpio/adc_ads1145s0x_gpio.overlay @@ -0,0 +1,21 @@ +&test_spi { + test_spi_ads114s08: ads114s08@0 { + compatible = "ti,ads114s08"; + status = "okay"; + spi-max-frequency = <10000000>; + reg = <0x00>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + reset-gpios = <&test_gpio 0 0>; + drdy-gpios = <&test_gpio 0 0>; + start-sync-gpios = <&test_gpio 0 0>; + + test_spi_ads114s08_gpio: ads114s0x_gpio { + compatible = "ti,ads114s0x-gpio"; + gpio-controller; + ngpios = <4>; + #gpio-cells = <2>; + }; + }; +}; diff --git a/tests/drivers/build_all/gpio/app.overlay b/tests/drivers/build_all/gpio/app.overlay index 715480a94f0..231d05a792f 100644 --- a/tests/drivers/build_all/gpio/app.overlay +++ b/tests/drivers/build_all/gpio/app.overlay @@ -51,7 +51,7 @@ test_i2c_pcal6416a: pcal6416a@2 { compatible = "nxp,pcal6416a"; - reg = <0x1>; + reg = <0x2>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -244,30 +244,10 @@ reset-gpios = <&test_gpio 0 0>; }; - test_spi_ads114s08: ads114s08@3 { - compatible = "ti,ads114s08"; - status = "okay"; - spi-max-frequency = <10000000>; - reg = <0x03>; - #address-cells = <1>; - #size-cells = <0>; - #io-channel-cells = <1>; - reset-gpios = <&test_gpio 0 0>; - drdy-gpios = <&test_gpio 0 0>; - start-sync-gpios = <&test_gpio 0 0>; - - test_spi_ads114s08_gpio: ads114s0x_gpio { - compatible = "ti,ads114s0x-gpio"; - gpio-controller; - ngpios = <4>; - #gpio-cells = <2>; - }; - }; - - test_spi_ad5592: ad5592@4 { + test_spi_ad5592: ad5592@3 { compatible = "adi,ad5592"; status = "okay"; - reg = <0x04>; + reg = <0x03>; spi-max-frequency = <0>; reset-gpios = <&test_gpio 0 0>; diff --git a/tests/drivers/build_all/gpio/prj.conf b/tests/drivers/build_all/gpio/prj.conf index 1517e7a4b76..6e24ab48c84 100644 --- a/tests/drivers/build_all/gpio/prj.conf +++ b/tests/drivers/build_all/gpio/prj.conf @@ -4,4 +4,3 @@ CONFIG_TEST_USERSPACE=y CONFIG_I2C=y CONFIG_GPIO_PCA95XX_INTERRUPT=y CONFIG_SPI=y -CONFIG_ADC_ADS114S0X_GPIO=y diff --git a/tests/drivers/build_all/gpio/testcase.yaml b/tests/drivers/build_all/gpio/testcase.yaml index a95b4625725..88d62c5b770 100644 --- a/tests/drivers/build_all/gpio/testcase.yaml +++ b/tests/drivers/build_all/gpio/testcase.yaml @@ -23,3 +23,14 @@ tests: platform_allow: niosv_m niosv_g depends_on: gpio extra_args: DTC_OVERLAY_FILE="altera.overlay" + + drivers.gpio.build.adc_ads1145s0x_gpio: + min_ram: 32 + platform_allow: m5stack_core2 nrf52840dk_nrf52840 + depends_on: + - gpio + - adc + - spi + extra_args: + - DTC_OVERLAY_FILE="app.overlay;adc_ads1145s0x_gpio.overlay" + - CONF_FILE="adc_ads1145s0x_gpio.conf" From 89612932b028c06977325ca5d40ac8792b0bc97c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 7 Nov 2023 13:46:46 +0100 Subject: [PATCH 3461/4498] tests: Bluetooth: Enable passing CAP AC 441 tests Enable some previously disabled CAP AC tests for 44.1 KHz, as they are now passing. Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh | 4 ++-- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh | 4 ++-- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh | 4 ++-- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh | 4 ++-- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh | 4 ++-- tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh index 070c0f72820..199b0144b34 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_1.sh @@ -40,8 +40,8 @@ Execute_AC_1 24_1_1 Execute_AC_1 24_2_1 Execute_AC_1 32_1_1 Execute_AC_1 32_2_1 -# Execute_AC_1 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_1 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_1 441_1_1 +Execute_AC_1 441_2_1 Execute_AC_1 48_1_1 Execute_AC_1 48_2_1 Execute_AC_1 48_3_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh index 2a2179b7b36..af35c7ad66b 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_10.sh @@ -40,8 +40,8 @@ Execute_AC_10 24_1_1 Execute_AC_10 24_2_1 Execute_AC_10 32_1_1 Execute_AC_10 32_2_1 -# Execute_AC_10 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_10 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_10 441_1_1 +Execute_AC_10 441_2_1 Execute_AC_10 48_1_1 Execute_AC_10 48_2_1 Execute_AC_10 48_3_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh index dae30f9dead..76a9b762fd1 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_2.sh @@ -41,8 +41,8 @@ Execute_AC_2 24_1_1 Execute_AC_2 24_2_1 Execute_AC_2 32_1_1 Execute_AC_2 32_2_1 -# Execute_AC_2 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_2 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_2 441_1_1 +Execute_AC_2 441_2_1 Execute_AC_2 48_1_1 Execute_AC_2 48_2_1 Execute_AC_2 48_3_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh index 4d51d8e3a08..e4682d10197 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_3.sh @@ -41,8 +41,8 @@ Execute_AC_3 24_1_1 24_1_1 Execute_AC_3 24_2_1 24_2_1 Execute_AC_3 32_1_1 32_1_1 Execute_AC_3 32_2_1 32_2_1 -# Execute_AC_3 441_1_1 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_3 441_2_1 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_3 441_1_1 441_1_1 +Execute_AC_3 441_2_1 441_2_1 Execute_AC_3 48_1_1 48_1_1 Execute_AC_3 48_2_1 48_2_1 Execute_AC_3 48_3_1 48_3_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh index 251e87e0382..a863b359252 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_4.sh @@ -38,8 +38,8 @@ Execute_AC_4 24_1_1 Execute_AC_4 24_2_1 Execute_AC_4 32_1_1 Execute_AC_4 32_2_1 -# Execute_AC_4 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_4 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_4 441_1_1 +Execute_AC_4 441_2_1 Execute_AC_4 48_1_1 Execute_AC_4 48_2_1 Execute_AC_4 48_3_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh index af439378c20..279322562ed 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_7_i.sh @@ -40,8 +40,8 @@ Execute_AC_7_I 24_1_1 24_1_1 Execute_AC_7_I 24_2_1 24_2_1 Execute_AC_7_I 32_1_1 32_1_1 Execute_AC_7_I 32_2_1 32_2_1 -# Execute_AC_7_I 441_1_1 441_1_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] -# Execute_AC_7_I 441_2_1 441_2_1 # ASSERTION FAIL [iso_interval_us >= cig->c_sdu_interval] +Execute_AC_7_I 441_1_1 441_1_1 +Execute_AC_7_I 441_2_1 441_2_1 Execute_AC_7_I 48_1_1 48_1_1 Execute_AC_7_I 48_2_1 48_2_1 Execute_AC_7_I 48_3_1 48_3_1 From b89095cf12f3ac1660411709117995835891f840 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 9 Nov 2023 11:03:40 +0800 Subject: [PATCH 3462/4498] tests: logging: log_syst: set backend ctx to its cb ctx when enable Set the backend's context to its control block's context instead of NULL when doing `log_backend_enable`, as the log backend UART uses that later. Signed-off-by: Yong Cong Sin --- tests/subsys/logging/log_syst/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/logging/log_syst/src/main.c b/tests/subsys/logging/log_syst/src/main.c index 45b7f34bf1a..bc0e6b2c556 100644 --- a/tests/subsys/logging/log_syst/src/main.c +++ b/tests/subsys/logging/log_syst/src/main.c @@ -152,7 +152,7 @@ static void after(void *unused) if (backend == &log_backend_mock) { log_backend_disable(backend); } else { - log_backend_enable(backend, NULL, 4); + log_backend_enable(backend, backend->cb->ctx, 4); } } } From c0064f1de88a04146b55e059ae40dc4ebf1eb0a9 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Wed, 8 Nov 2023 17:29:26 +0800 Subject: [PATCH 3463/4498] logging: uart: support multiple instances Extends the log_backend_uart to support logging to multiple UART instances. Signed-off-by: Christopher Friedt --- doc/build/dts/api/api.rst | 3 + dts/bindings/misc/zephyr,log-uart.yaml | 16 +++ subsys/logging/backends/log_backend_uart.c | 115 +++++++++++++++------ 3 files changed, 103 insertions(+), 31 deletions(-) create mode 100644 dts/bindings/misc/zephyr,log-uart.yaml diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index f452d0f5281..44b87653cc3 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -424,6 +424,9 @@ device. interprocess-communication (IPC) * - zephyr,itcm - Instruction Tightly Coupled Memory node on some Arm SoCs + * - zephyr,log-uart + - Sets the UART device(s) used by the logging subsystem's UART backend. + If defined, the UART log backend would output to the devices listed in this node. * - zephyr,ocm - On-chip memory node on Xilinx Zynq-7000 and ZynqMP SoCs * - zephyr,osdp-uart diff --git a/dts/bindings/misc/zephyr,log-uart.yaml b/dts/bindings/misc/zephyr,log-uart.yaml new file mode 100644 index 00000000000..2e0a065e3b2 --- /dev/null +++ b/dts/bindings/misc/zephyr,log-uart.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +description: Log Backend UART + +compatible: "zephyr,log-uart" + +include: [base.yaml] + +properties: + + uarts: + type: phandles + required: true + description: | + UART devices to be used by the UART log backend. diff --git a/subsys/logging/backends/log_backend_uart.c b/subsys/logging/backends/log_backend_uart.c index 5bfcbdd89b1..7c58ea1774e 100644 --- a/subsys/logging/backends/log_backend_uart.c +++ b/subsys/logging/backends/log_backend_uart.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2023 Meta * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,32 +19,43 @@ #include LOG_MODULE_REGISTER(log_uart); +struct lbu_data { + struct k_sem sem; + uint32_t log_format_current; + volatile bool in_panic; + bool use_async; +}; + +struct lbu_cb_ctx { + const struct log_output *output; + const struct device *device; + struct lbu_data *data; +}; + /* Fixed size to avoid auto-added trailing '\0'. * Used if CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX. */ static const char LOG_HEX_SEP[10] = "##ZLOGV1##"; -static const struct device *const uart_dev = - DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); -static struct k_sem sem; -static volatile bool in_panic; -static bool use_async; -static uint32_t log_format_current = CONFIG_LOG_BACKEND_UART_OUTPUT_DEFAULT; - static void uart_callback(const struct device *dev, struct uart_event *evt, void *user_data) { + const struct lbu_cb_ctx *ctx = user_data; + struct lbu_data *data = ctx->data; + + ARG_UNUSED(dev); + switch (evt->type) { case UART_TX_DONE: - k_sem_give(&sem); + k_sem_give(&data->sem); break; default: break; } } -static void dict_char_out_hex(uint8_t *data, size_t length) +static void dict_char_out_hex(const struct device *uart_dev, uint8_t *data, size_t length) { for (size_t i = 0; i < length; i++) { char c; @@ -63,8 +75,10 @@ static void dict_char_out_hex(uint8_t *data, size_t length) static int char_out(uint8_t *data, size_t length, void *ctx) { - ARG_UNUSED(ctx); int err; + const struct lbu_cb_ctx *cb_ctx = ctx; + struct lbu_data *lb_data = cb_ctx->data; + const struct device *uart_dev = cb_ctx->device; if (pm_device_runtime_is_enabled(uart_dev) && !k_is_in_isr()) { if (pm_device_runtime_get(uart_dev) < 0) { @@ -76,11 +90,12 @@ static int char_out(uint8_t *data, size_t length, void *ctx) } if (IS_ENABLED(CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX)) { - dict_char_out_hex(data, length); + dict_char_out_hex(uart_dev, data, length); goto cleanup; } - if (!IS_ENABLED(CONFIG_LOG_BACKEND_UART_ASYNC) || in_panic || !use_async) { + if (!IS_ENABLED(CONFIG_LOG_BACKEND_UART_ASYNC) || lb_data->in_panic || + !lb_data->use_async) { for (size_t i = 0; i < length; i++) { uart_poll_out(uart_dev, data[i]); } @@ -90,7 +105,7 @@ static int char_out(uint8_t *data, size_t length, void *ctx) err = uart_tx(uart_dev, data, length, SYS_FOREVER_US); __ASSERT_NO_MSG(err == 0); - err = k_sem_take(&sem, K_FOREVER); + err = k_sem_take(&lb_data->sem, K_FOREVER); __ASSERT_NO_MSG(err == 0); (void)err; @@ -103,29 +118,37 @@ static int char_out(uint8_t *data, size_t length, void *ctx) return length; } -static uint8_t uart_output_buf[CONFIG_LOG_BACKEND_UART_BUFFER_SIZE]; -LOG_OUTPUT_DEFINE(log_output_uart, char_out, uart_output_buf, sizeof(uart_output_buf)); - static void process(const struct log_backend *const backend, union log_msg_generic *msg) { + const struct lbu_cb_ctx *ctx = backend->cb->ctx; + struct lbu_data *data = ctx->data; uint32_t flags = log_backend_std_get_flags(); + log_format_func_t log_output_func = log_format_func_t_get(data->log_format_current); - log_format_func_t log_output_func = log_format_func_t_get(log_format_current); - - log_output_func(&log_output_uart, &msg->log, flags); + log_output_func(ctx->output, &msg->log, flags); } static int format_set(const struct log_backend *const backend, uint32_t log_type) { - log_format_current = log_type; + const struct lbu_cb_ctx *ctx = backend->cb->ctx; + struct lbu_data *data = ctx->data; + + data->log_format_current = log_type; + return 0; } static void log_backend_uart_init(struct log_backend const *const backend) { + const struct lbu_cb_ctx *ctx = backend->cb->ctx; + const struct device *uart_dev = ctx->device; + struct lbu_data *data = ctx->data; + __ASSERT_NO_MSG(device_is_ready(uart_dev)); + log_output_ctx_set(ctx->output, (void *)ctx); + if (IS_ENABLED(CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX)) { /* Print a separator so the output can be fed into * log parser directly. This is useful when capturing @@ -140,20 +163,25 @@ static void log_backend_uart_init(struct log_backend const *const backend) } if (IS_ENABLED(CONFIG_LOG_BACKEND_UART_ASYNC)) { - int err = uart_callback_set(uart_dev, uart_callback, NULL); + int err = uart_callback_set(uart_dev, uart_callback, (void *)ctx); if (err == 0) { - use_async = true; - k_sem_init(&sem, 0, 1); + data->use_async = true; + k_sem_init(&data->sem, 0, 1); } else { LOG_WRN("Failed to initialize asynchronous mode (err:%d). " - "Fallback to polling.", err); + "Fallback to polling.", + err); } } } static void panic(struct log_backend const *const backend) { + const struct lbu_cb_ctx *ctx = backend->cb->ctx; + struct lbu_data *data = ctx->data; + const struct device *uart_dev = ctx->device; + /* Ensure that the UART device is in active mode */ #if defined(CONFIG_PM_DEVICE_RUNTIME) if (pm_device_runtime_is_enabled(uart_dev)) { @@ -172,20 +200,22 @@ static void panic(struct log_backend const *const backend) if ((rc == 0) && (pm_state == PM_DEVICE_STATE_SUSPENDED)) { pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME); } +#else + ARG_UNUSED(uart_dev); #endif /* CONFIG_PM_DEVICE */ - in_panic = true; - log_backend_std_panic(&log_output_uart); + data->in_panic = true; + log_backend_std_panic(ctx->output); } static void dropped(const struct log_backend *const backend, uint32_t cnt) { - ARG_UNUSED(backend); + const struct lbu_cb_ctx *ctx = backend->cb->ctx; if (IS_ENABLED(CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY)) { - log_dict_output_dropped_process(&log_output_uart, cnt); + log_dict_output_dropped_process(ctx->output, cnt); } else { - log_backend_std_dropped(&log_output_uart, cnt); + log_backend_std_dropped(ctx->output, cnt); } } @@ -197,5 +227,28 @@ const struct log_backend_api log_backend_uart_api = { .format_set = format_set, }; -LOG_BACKEND_DEFINE(log_backend_uart, log_backend_uart_api, - IS_ENABLED(CONFIG_LOG_BACKEND_UART_AUTOSTART)); +#define LBU_DEFINE(node_id, idx) \ + static uint8_t lbu_buffer_##idx[CONFIG_LOG_BACKEND_UART_BUFFER_SIZE]; \ + LOG_OUTPUT_DEFINE(lbu_output_##idx, char_out, lbu_buffer_##idx, \ + CONFIG_LOG_BACKEND_UART_BUFFER_SIZE); \ + \ + static struct lbu_data lbu_data_##idx = { \ + .log_format_current = CONFIG_LOG_BACKEND_UART_OUTPUT_DEFAULT, \ + }; \ + \ + static const struct lbu_cb_ctx lbu_cb_ctx_##idx = { \ + .output = &lbu_output_##idx, \ + .device = DEVICE_DT_GET(node_id), \ + .data = &lbu_data_##idx, \ + }; \ + \ + LOG_BACKEND_DEFINE(log_backend_uart##idx, log_backend_uart_api, \ + IS_ENABLED(CONFIG_LOG_BACKEND_UART_AUTOSTART), \ + (void *)&lbu_cb_ctx_##idx); + +#if DT_HAS_CHOSEN(zephyr_log_uart) +#define LBU_PHA_FN(node_id, prop, idx) LBU_DEFINE(DT_PHANDLE_BY_IDX(node_id, prop, idx), idx) +DT_FOREACH_PROP_ELEM_SEP(DT_CHOSEN(zephyr_log_uart), uarts, LBU_PHA_FN, ()); +#else +LBU_DEFINE(DT_CHOSEN(zephyr_console), 0); +#endif From 6d9fcd83a940938a06baf625d7c5c40d32a6f9ab Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 8 Nov 2023 17:31:23 +0800 Subject: [PATCH 3464/4498] test: logging: add testcase for multi-instance log backend uart Add testcase for the multi-instance log backend uart using emulated uart. Signed-off-by: Yong Cong Sin --- .../logging/log_backend_uart/CMakeLists.txt | 9 +++ tests/subsys/logging/log_backend_uart/Kconfig | 8 ++ .../logging/log_backend_uart/multi.overlay | 32 ++++++++ .../subsys/logging/log_backend_uart/prj.conf | 11 +++ .../logging/log_backend_uart/single.overlay | 24 ++++++ .../logging/log_backend_uart/src/main.c | 73 +++++++++++++++++++ .../logging/log_backend_uart/testcase.yaml | 14 ++++ 7 files changed, 171 insertions(+) create mode 100644 tests/subsys/logging/log_backend_uart/CMakeLists.txt create mode 100644 tests/subsys/logging/log_backend_uart/Kconfig create mode 100644 tests/subsys/logging/log_backend_uart/multi.overlay create mode 100644 tests/subsys/logging/log_backend_uart/prj.conf create mode 100644 tests/subsys/logging/log_backend_uart/single.overlay create mode 100644 tests/subsys/logging/log_backend_uart/src/main.c create mode 100644 tests/subsys/logging/log_backend_uart/testcase.yaml diff --git a/tests/subsys/logging/log_backend_uart/CMakeLists.txt b/tests/subsys/logging/log_backend_uart/CMakeLists.txt new file mode 100644 index 00000000000..055b71fd748 --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(log_backend_uart_test) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/logging/log_backend_uart/Kconfig b/tests/subsys/logging/log_backend_uart/Kconfig new file mode 100644 index 00000000000..89a0fefa76f --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +module = SAMPLE_MODULE +module-str = Test logging API +source "subsys/logging/Kconfig.template.log_config" + +source "Kconfig.zephyr" diff --git a/tests/subsys/logging/log_backend_uart/multi.overlay b/tests/subsys/logging/log_backend_uart/multi.overlay new file mode 100644 index 00000000000..799a4602cf9 --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/multi.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,log-uart = &log_uarts; + }; + + log_uarts: log_uarts { + compatible = "zephyr,log-uart"; + uarts = <&euart0 &euart1>; + }; + + euart0: uart-emul0 { + compatible = "zephyr,uart-emul"; + status = "okay"; + current-speed = <0>; + rx-fifo-size = <256>; + tx-fifo-size = <256>; + }; + + euart1: uart-emul1 { + compatible = "zephyr,uart-emul"; + status = "okay"; + current-speed = <0>; + rx-fifo-size = <256>; + tx-fifo-size = <256>; + }; +}; diff --git a/tests/subsys/logging/log_backend_uart/prj.conf b/tests/subsys/logging/log_backend_uart/prj.conf new file mode 100644 index 00000000000..ef6894f355e --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/prj.conf @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_ASSERT=y +CONFIG_TEST_LOGGING_DEFAULTS=n + +CONFIG_LOG=y +CONFIG_LOG_BACKEND_UART=y +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_LOG_PRINTK=n diff --git a/tests/subsys/logging/log_backend_uart/single.overlay b/tests/subsys/logging/log_backend_uart/single.overlay new file mode 100644 index 00000000000..3bdcff1c882 --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/single.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,log-uart = &log_uarts; + }; + + log_uarts: log_uarts { + compatible = "zephyr,log-uart"; + uarts = <&euart0>; + }; + + euart0: uart-emul0 { + compatible = "zephyr,uart-emul"; + status = "okay"; + current-speed = <0>; + rx-fifo-size = <256>; + tx-fifo-size = <256>; + }; +}; diff --git a/tests/subsys/logging/log_backend_uart/src/main.c b/tests/subsys/logging/log_backend_uart/src/main.c new file mode 100644 index 00000000000..078d2e02f63 --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/src/main.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(test, CONFIG_SAMPLE_MODULE_LOG_LEVEL); + +#define EMUL_UART_NUM DT_NUM_INST_STATUS_OKAY(zephyr_uart_emul) +#define EMUL_UART_NODE(i) DT_NODELABEL(euart##i) +#define EMUL_UART_DEV_INIT(i, _) DEVICE_DT_GET(EMUL_UART_NODE(i)) +#define EMUL_UART_TX_FIFO_SIZE(i) DT_PROP(EMUL_UART_NODE(i), tx_fifo_size) +#define SAMPLE_DATA_SIZE EMUL_UART_TX_FIFO_SIZE(0) + +#define TEST_DATA "0123456789ABCDEF" +BUILD_ASSERT(strlen(TEST_DATA) < SAMPLE_DATA_SIZE); + +struct log_backend_uart_fixture { + const struct device *dev[EMUL_UART_NUM]; +}; + +static void *uart_emul_setup(void) +{ + static struct log_backend_uart_fixture fixture = { + .dev = {LISTIFY(EMUL_UART_NUM, EMUL_UART_DEV_INIT, (,))}}; + + for (size_t i = 0; i < EMUL_UART_NUM; i++) { + zassert_not_null(fixture.dev[i]); + } + + return &fixture; +} + +static void uart_emul_before(void *f) +{ + struct log_backend_uart_fixture *fixture = f; + + for (size_t i = 0; i < EMUL_UART_NUM; i++) { + uart_irq_tx_disable(fixture->dev[i]); + uart_irq_rx_disable(fixture->dev[i]); + + uart_emul_flush_rx_data(fixture->dev[i]); + uart_emul_flush_tx_data(fixture->dev[i]); + + uart_err_check(fixture->dev[i]); + } +} + +ZTEST_F(log_backend_uart, test_log_backend_uart_multi_instance) +{ + zassert_equal(log_backend_count_get(), EMUL_UART_NUM, "Unexpected number of instance(s)"); + + LOG_RAW(TEST_DATA); + + for (size_t i = 0; i < EMUL_UART_NUM; i++) { + uint8_t tx_content[SAMPLE_DATA_SIZE] = {0}; + size_t tx_len; + + tx_len = uart_emul_get_tx_data(fixture->dev[i], tx_content, sizeof(tx_content)); + zassert_equal(tx_len, strlen(TEST_DATA), + "%d: TX buffer length does not match. Expected %d, got %d", + i, strlen(TEST_DATA), tx_len); + zassert_mem_equal(tx_content, TEST_DATA, strlen(tx_content)); + } +} + +ZTEST_SUITE(log_backend_uart, NULL, uart_emul_setup, uart_emul_before, NULL, NULL); diff --git a/tests/subsys/logging/log_backend_uart/testcase.yaml b/tests/subsys/logging/log_backend_uart/testcase.yaml new file mode 100644 index 00000000000..70eb49920f1 --- /dev/null +++ b/tests/subsys/logging/log_backend_uart/testcase.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +common: + tags: + - logging + - backend + - uart + platform_allow: qemu_x86 +tests: + logging.backend.uart.single: + extra_args: DTC_OVERLAY_FILE="./single.overlay" + logging.backend.uart.multi: + extra_args: DTC_OVERLAY_FILE="./multi.overlay" From 28c5b1d76daa2d7510477532d0bd3260a110f6ef Mon Sep 17 00:00:00 2001 From: Yves Vandervennet Date: Tue, 7 Nov 2023 10:18:41 -0500 Subject: [PATCH 3465/4498] west: linkserver: update to reflect logging changes in 1.3.15 NXP released the linkserver update 1.3.15, which corrects an issue with logging that by default went out to stderr when flashing. Signed-off-by: Yves Vandervennet --- scripts/west_commands/runners/linkserver.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/runners/linkserver.py b/scripts/west_commands/runners/linkserver.py index 5108d780aeb..a4ae5c622d4 100644 --- a/scripts/west_commands/runners/linkserver.py +++ b/scripts/west_commands/runners/linkserver.py @@ -111,7 +111,7 @@ def linkserver_version_str(self): if not hasattr(self, '_linkserver_version'): linkserver_version_cmd=[self.linkserver, "-v"] ls_output=self.check_output(linkserver_version_cmd) - self.linkserver_version = str(ls_output.split()[1].decode()) + self.linkserver_version = str(ls_output.split()[1].decode()).lower() return self.linkserver_version @@ -214,5 +214,9 @@ def flash(self, **kwargs): self.logger.debug("flash command = " + str(linkserver_cmd)) kwargs = {} if not self.logger.isEnabledFor(logging.DEBUG): - kwargs['stderr'] = subprocess.DEVNULL + if self.linkserver_version_str < "v1.3.15": + kwargs['stderr'] = subprocess.DEVNULL + else: + kwargs['stdout'] = subprocess.DEVNULL + self.check_call(linkserver_cmd, **kwargs) From 6c4b89cb007cf7b8337c4a310cc51089ee57214f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 9 Nov 2023 18:16:52 +0000 Subject: [PATCH 3466/4498] mgmt: mcumgr: grp: os_mgmt: Add datetime get/set functions Adds datetime set and get functions which allow for setting and getting the current time to/from the rtc alias device Signed-off-by: Jamie McCrae --- .../zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h | 6 + include/zephyr/mgmt/mcumgr/mgmt/callbacks.h | 6 + subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig | 21 ++ subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 268 ++++++++++++++++++ 4 files changed, 301 insertions(+) diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h index e1ac45e6389..505ee655474 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h @@ -41,6 +41,12 @@ enum os_mgmt_err_code_t { /** Query was not recognized. */ OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER, + + /** RTC is not set */ + OS_MGMT_ERR_RTC_NOT_SET, + + /** RTC command failed */ + OS_MGMT_ERR_RTC_COMMAND_FAILED, }; /* Bitmask values used by the os info command handler. Note that the width of this variable is diff --git a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h index c3a9a5687d8..43ee5ed6f95 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h @@ -197,6 +197,12 @@ enum os_mgmt_group_events { /** Callback when an info command needs to output data, data is os_mgmt_info_append. */ MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), + /** Callback when a datetime get command has been received. */ + MGMT_EVT_OP_OS_MGMT_DATETIME_GET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 3), + + /** Callback when a datetime set command has been received, data is struct rtc_time(). */ + MGMT_EVT_OP_OS_MGMT_DATETIME_SET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 4), + /** Used to enable all os_mgmt_group events. */ MGMT_EVT_OP_OS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_OS), }; diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index fa743b53caf..62245760a47 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -135,6 +135,27 @@ config MCUMGR_GRP_OS_ECHO default y select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 +config MCUMGR_GRP_OS_DATETIME + bool "Support for datetime command" + depends on RTC + depends on $(dt_alias_enabled,rtc) + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 + help + Enables support for the datetime get and set functions, this allows for using the + `rtc` alias device as a timesource from which the current time can be written or read. + +config MCUMGR_GRP_OS_DATETIME_MS + bool "Support millisecond field in datetime commands" + depends on MCUMGR_GRP_OS_DATETIME + +config MCUMGR_GRP_OS_DATETIME_HOOK + bool "Datetime hook" + depends on MCUMGR_GRP_OS_DATETIME + depends on MCUMGR_MGMT_NOTIFICATION_HOOKS + help + Allows applications to control and get notifications of when a datetime set/get + command has been issued via an MCUmgr command. + config MCUMGR_GRP_OS_MCUMGR_PARAMS bool "MCUMGR Parameters retrieval command" diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index a42e2f4022f..13de45f02a9 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -33,6 +33,11 @@ #include #endif +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME +#include +#include +#endif + #if defined(CONFIG_MCUMGR_GRP_OS_INFO) || defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) #include #include @@ -78,6 +83,52 @@ struct thread_iterator_info { }; #endif +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME +/* Iterator for extracting values from the provided datetime string, min and max values are + * checked against the provided value, then the offset is added after. If the value is not + * within the min and max values, the set operation will be aborted. + */ +struct datetime_parser { + int *value; + int min_value; + int max_value; + int offset; +}; + +/* RTC device alias to use for datetime functions, "rtc" */ +#define RTC_DEVICE DEVICE_DT_GET(DT_ALIAS(rtc)) + +#define RTC_DATETIME_YEAR_OFFSET 1900 +#define RTC_DATETIME_MONTH_OFFSET 1 +#define RTC_DATETIME_NUMERIC_BASE 10 +#define RTC_DATETIME_MS_TO_NS 1000000 +#define RTC_DATETIME_YEAR_MIN 1900 +#define RTC_DATETIME_YEAR_MAX 11899 +#define RTC_DATETIME_MONTH_MIN 1 +#define RTC_DATETIME_MONTH_MAX 12 +#define RTC_DATETIME_DAY_MIN 1 +#define RTC_DATETIME_DAY_MAX 31 +#define RTC_DATETIME_HOUR_MIN 0 +#define RTC_DATETIME_HOUR_MAX 23 +#define RTC_DATETIME_MINUTE_MIN 0 +#define RTC_DATETIME_MINUTE_MAX 59 +#define RTC_DATETIME_SECOND_MIN 0 +#define RTC_DATETIME_SECOND_MAX 59 +#define RTC_DATETIME_MILLISECOND_MIN 0 +#define RTC_DATETIME_MILLISECOND_MAX 999 + +/* Size used for datetime creation buffer */ +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS +#define RTC_DATETIME_STRING_SIZE 32 +#else +#define RTC_DATETIME_STRING_SIZE 26 +#endif + +/* Minimum/maximum size of a datetime string that a client can provide */ +#define RTC_DATETIME_MIN_STRING_SIZE 19 +#define RTC_DATETIME_MAX_STRING_SIZE 26 +#endif + /* Specifies what the "all" ('a') of info parameter shows */ #define OS_MGMT_INFO_FORMAT_ALL \ OS_MGMT_INFO_FORMAT_KERNEL_NAME | OS_MGMT_INFO_FORMAT_NODE_NAME | \ @@ -744,6 +795,210 @@ static int os_mgmt_info(struct smp_streamer *ctxt) } #endif +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME +/** + * Command handler: os datetime get + */ +static int os_mgmt_datetime_read(struct smp_streamer *ctxt) +{ + zcbor_state_t *zse = ctxt->writer->zs; + struct rtc_time current_time; + char date_string[RTC_DATETIME_STRING_SIZE]; + int rc; + bool ok; + +#if defined(CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK) + enum mgmt_cb_return status; + int32_t err_rc; + uint16_t err_group; + + status = mgmt_callback_notify(MGMT_EVT_OP_OS_MGMT_DATETIME_GET, NULL, 0, &err_rc, + &err_group); + + if (status != MGMT_CB_OK) { + if (status == MGMT_CB_ERROR_RC) { + return err_rc; + } + + ok = smp_add_cmd_err(zse, err_group, (uint16_t)err_rc); + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; + } +#endif + + rc = rtc_get_time(RTC_DEVICE, ¤t_time); + + if (rc == -ENODATA) { + /* RTC not set */ + ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_OS, OS_MGMT_ERR_RTC_NOT_SET); + goto finished; + } else if (rc != 0) { + /* Other RTC error */ + ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_OS, OS_MGMT_ERR_RTC_COMMAND_FAILED); + goto finished; + } + + sprintf(date_string, "%4d-%02d-%02dT%02d:%02d:%02d" +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS + ".%d" +#endif + , (uint16_t)(current_time.tm_year + RTC_DATETIME_YEAR_OFFSET), + (uint8_t)(current_time.tm_mon + RTC_DATETIME_MONTH_OFFSET), + (uint8_t)current_time.tm_mday, (uint8_t)current_time.tm_hour, + (uint8_t)current_time.tm_min, (uint8_t)current_time.tm_sec +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS + , (uint16_t)(current_time.tm_nsec / RTC_DATETIME_MS_TO_NS) +#endif + ); + + ok = zcbor_tstr_put_lit(zse, "datetime") && + zcbor_tstr_encode_ptr(zse, date_string, strlen(date_string)); + +finished: + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; +} + +/** + * Command handler: os datetime set + */ +static int os_mgmt_datetime_write(struct smp_streamer *ctxt) +{ + zcbor_state_t *zsd = ctxt->reader->zs; + zcbor_state_t *zse = ctxt->writer->zs; + size_t decoded; + struct zcbor_string datetime = { 0 }; + int rc; + uint8_t i = 0; + bool ok = true; + char *pos; + char *new_pos; + char date_string[RTC_DATETIME_MAX_STRING_SIZE]; + struct rtc_time new_time = { + .tm_wday = -1, + .tm_yday = -1, + .tm_isdst = -1, + .tm_nsec = 0, + }; + struct datetime_parser parser[] = { + { + .value = &new_time.tm_year, + .min_value = RTC_DATETIME_YEAR_MIN, + .max_value = RTC_DATETIME_YEAR_MAX, + .offset = -RTC_DATETIME_YEAR_OFFSET, + }, + { + .value = &new_time.tm_mon, + .min_value = RTC_DATETIME_MONTH_MIN, + .max_value = RTC_DATETIME_MONTH_MAX, + .offset = -RTC_DATETIME_MONTH_OFFSET, + }, + { + .value = &new_time.tm_mday, + .min_value = RTC_DATETIME_DAY_MIN, + .max_value = RTC_DATETIME_DAY_MAX, + }, + { + .value = &new_time.tm_hour, + .min_value = RTC_DATETIME_HOUR_MIN, + .max_value = RTC_DATETIME_HOUR_MAX, + }, + { + .value = &new_time.tm_min, + .min_value = RTC_DATETIME_MINUTE_MIN, + .max_value = RTC_DATETIME_MINUTE_MAX, + }, + { + .value = &new_time.tm_sec, + .min_value = RTC_DATETIME_SECOND_MIN, + .max_value = RTC_DATETIME_SECOND_MAX, + }, + }; + +#if defined(CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK) + enum mgmt_cb_return status; + int32_t err_rc; + uint16_t err_group; +#endif + + struct zcbor_map_decode_key_val datetime_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &datetime), + }; + + if (zcbor_map_decode_bulk(zsd, datetime_decode, ARRAY_SIZE(datetime_decode), &decoded)) { + return MGMT_ERR_EINVAL; + } else if (datetime.len < RTC_DATETIME_MIN_STRING_SIZE || + datetime.len >= RTC_DATETIME_MAX_STRING_SIZE) { + return MGMT_ERR_EINVAL; + } + + memcpy(date_string, datetime.value, datetime.len); + date_string[datetime.len] = '\0'; + + pos = date_string; + + while (i < ARRAY_SIZE(parser)) { + if (pos == (date_string + datetime.len)) { + /* Encountered end of string early, this is invalid */ + return MGMT_ERR_EINVAL; + } + + *parser[i].value = strtol(pos, &new_pos, RTC_DATETIME_NUMERIC_BASE); + + if (pos == new_pos) { + /* Missing or unable to convert field */ + return MGMT_ERR_EINVAL; + } + + if (*parser[i].value < parser[i].min_value || + *parser[i].value > parser[i].max_value) { + /* Value is not within the allowed bounds of this field */ + return MGMT_ERR_EINVAL; + } + + *parser[i].value += parser[i].offset; + + /* Skip a character as there is always a delimiter between the fields */ + ++i; + pos = new_pos + 1; + } + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS + if (*(pos - 1) == '.' && *pos != '\0') { + /* Provided value has a ms value, extract it */ + new_time.tm_nsec = strtol(pos, &new_pos, RTC_DATETIME_NUMERIC_BASE); + + if (new_time.tm_nsec < RTC_DATETIME_MILLISECOND_MIN || + new_time.tm_nsec > RTC_DATETIME_MILLISECOND_MAX) { + return MGMT_ERR_EINVAL; + } + + new_time.tm_nsec *= RTC_DATETIME_MS_TO_NS; + } +#endif + +#if defined(CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK) + status = mgmt_callback_notify(MGMT_EVT_OP_OS_MGMT_DATETIME_SET, &new_time, + sizeof(new_time), &err_rc, &err_group); + + if (status != MGMT_CB_OK) { + if (status == MGMT_CB_ERROR_RC) { + return err_rc; + } + + ok = smp_add_cmd_err(zse, err_group, (uint16_t)err_rc); + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; + } +#endif + + rc = rtc_set_time(RTC_DEVICE, &new_time); + + if (rc != 0) { + ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_OS, OS_MGMT_ERR_RTC_COMMAND_FAILED); + } + + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; +} +#endif + #ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL /* * @brief Translate OS mgmt group error code into MCUmgr error code @@ -761,7 +1016,13 @@ static int os_mgmt_translate_error_code(uint16_t err) rc = MGMT_ERR_EINVAL; break; + case OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER: + case OS_MGMT_ERR_RTC_NOT_SET: + rc = MGMT_ERR_ENOENT; + break; + case OS_MGMT_ERR_UNKNOWN: + case OS_MGMT_ERR_RTC_COMMAND_FAILED: default: rc = MGMT_ERR_EUNKNOWN; } @@ -781,6 +1042,13 @@ static const struct mgmt_handler os_mgmt_group_handlers[] = { os_mgmt_taskstat_read, NULL }, #endif + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME + [OS_MGMT_ID_DATETIME_STR] = { + os_mgmt_datetime_read, os_mgmt_datetime_write + }, +#endif + #ifdef CONFIG_REBOOT [OS_MGMT_ID_RESET] = { NULL, os_mgmt_reset From 1855fd16f795a91b296e02dd4e6b2a44fa6e84b4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 9 Nov 2023 18:17:08 +0000 Subject: [PATCH 3467/4498] tests: mgmt: mcumgr: Add os_mgmt_datetime test Adds a test which tests datetime set/get and hook callbacks Signed-off-by: Jamie McCrae --- .../mcumgr/os_mgmt_datetime/CMakeLists.txt | 17 + .../boards/native_posix.overlay | 14 + .../boards/qemu_arc_hs6x.overlay | 14 + .../boards/qemu_cortex_m0.overlay | 14 + .../boards/qemu_leon3.overlay | 14 + .../boards/qemu_malta.overlay | 14 + .../os_mgmt_datetime/boards/qemu_riscv64.conf | 1 + .../boards/qemu_riscv64.overlay | 14 + .../boards/qemu_riscv64_smp.conf | 1 + .../boards/qemu_riscv64_smp.overlay | 14 + .../mgmt/mcumgr/os_mgmt_datetime/prj.conf | 21 + .../mgmt/mcumgr/os_mgmt_datetime/src/main.c | 1495 +++++++++++++++++ .../os_mgmt_datetime/src/smp_test_util.c | 77 + .../os_mgmt_datetime/src/smp_test_util.h | 35 + .../mcumgr/os_mgmt_datetime/testcase.yaml | 19 + 15 files changed, 1764 insertions(+) create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/CMakeLists.txt create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/native_posix.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_arc_hs6x.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_cortex_m0.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_leon3.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_malta.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.conf create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.conf create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.overlay create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/prj.conf create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.c create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.h create mode 100644 tests/subsys/mgmt/mcumgr/os_mgmt_datetime/testcase.yaml diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/CMakeLists.txt new file mode 100644 index 00000000000..5f75eeb5bfa --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(os_mgmt_info) + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/mgmt/mcumgr/grp/os_mgmt/include/) diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/native_posix.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/native_posix.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/native_posix.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_arc_hs6x.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_arc_hs6x.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_arc_hs6x.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_cortex_m0.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_cortex_m0.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_cortex_m0.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_leon3.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_leon3.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_leon3.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_malta.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_malta.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_malta.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.conf b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.conf new file mode 100644 index 00000000000..1ede042960b --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.conf @@ -0,0 +1 @@ +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.conf b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.conf new file mode 100644 index 00000000000..1ede042960b --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.conf @@ -0,0 +1 @@ +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.overlay b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.overlay new file mode 100644 index 00000000000..4021ce2ae86 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/boards/qemu_riscv64_smp.overlay @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; + + rtc: rtc { + status = "okay"; + compatible = "zephyr,rtc-emul"; + }; +}; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/prj.conf b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/prj.conf new file mode 100644 index 00000000000..0cf01e6335b --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/prj.conf @@ -0,0 +1,21 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_ZTEST=y +CONFIG_RTC=y +CONFIG_NET_BUF=y +CONFIG_BASE64=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +CONFIG_MCUMGR=y +CONFIG_MCUMGR_TRANSPORT_DUMMY=y +CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256 +CONFIG_MCUMGR_GRP_OS=y +CONFIG_MCUMGR_GRP_OS_ECHO=n +CONFIG_MCUMGR_GRP_OS_DATETIME=y +CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK=y +CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y +CONFIG_ZTEST_STACK_SIZE=2048 +CONFIG_REBOOT=n diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c new file mode 100644 index 00000000000..c387c3b4812 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c @@ -0,0 +1,1495 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright (c) 2023 Jamie M. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smp_test_util.h" + +#define SMP_RESPONSE_WAIT_TIME 3 +#define ZCBOR_BUFFER_SIZE 256 +#define OUTPUT_BUFFER_SIZE 256 +#define ZCBOR_HISTORY_ARRAY_SIZE 4 + +/* Test sets */ +enum { + OS_MGMT_DATETIME_TEST_SET_TIME_NOT_SET = 0, + OS_MGMT_DATETIME_TEST_SET_TIME_SET, +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK + OS_MGMT_DATETIME_TEST_SET_HOOKS, +#endif + + OS_MGMT_DATETIME_TEST_SET_COUNT +}; + +static struct net_buf *nb; + +struct state { + uint8_t test_set; +}; + +static struct state test_state = { + .test_set = 0, +}; + +static struct rtc_time valid_time = { + .tm_sec = 13, + .tm_min = 40, + .tm_hour = 4, + .tm_mday = 4, + .tm_mon = 8, + .tm_year = 2023, +}; + +static struct rtc_time valid_time2 = { + .tm_sec = 5, + .tm_min = 4, + .tm_hour = 3, + .tm_mday = 2, + .tm_mon = 1, + .tm_year = 2001, +}; + +static const char valid_time_string[] = "2023-08-04T04:40:13"; +static const char valid_time2_string[] = "2001-01-02T03:04:05"; +static const char invalid_time_string[] = "abcdefghij"; +static const char invalid_time2_string[] = "20a1-b1-aTbb:dd:qq"; +static const char invalid_time3_string[] = "1820-01-02T03:04:05"; + +struct group_error { + uint16_t group; + uint16_t rc; + bool found; +}; + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK +static bool hook_get_ran; +static bool hook_set_ran; +static bool hook_other_ran; +static uint8_t hook_set_data_size; +static uint8_t hook_set_data[64]; +#endif + +static void cleanup_test(void *p); + +static bool mcumgr_ret_decode(zcbor_state_t *state, struct group_error *result) +{ + bool ok; + size_t decoded; + uint32_t tmp_group; + uint32_t tmp_rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("group", zcbor_uint32_decode, &tmp_group), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_uint32_decode, &tmp_rc), + }; + + result->found = false; + + ok = zcbor_map_decode_bulk(state, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + + if (ok && + zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), "group") && + zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), "rc")) { + result->group = (uint16_t)tmp_group; + result->rc = (uint16_t)tmp_rc; + result->found = true; + } + + return ok; +} + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK +static enum mgmt_cb_return os_mgmt_datetime_callback(uint32_t event, + enum mgmt_cb_return prev_status, int32_t *rc, + uint16_t *group, bool *abort_more, + void *data, size_t data_size) +{ + if (event == MGMT_EVT_OP_OS_MGMT_DATETIME_GET) { + hook_get_ran = true; + + *rc = MGMT_ERR_EBUSY; + return MGMT_CB_ERROR_RC; + } else if (event == MGMT_EVT_OP_OS_MGMT_DATETIME_SET) { + hook_set_ran = true; + hook_set_data_size = data_size; + memcpy(hook_set_data, data, data_size); + + *rc = MGMT_ERR_EACCESSDENIED; + return MGMT_CB_ERROR_RC; + } + + hook_other_ran = true; + return MGMT_CB_OK; +} + +static struct mgmt_callback os_datetime_callbacks = { + .callback = os_mgmt_datetime_callback, + .event_id = (MGMT_EVT_OP_OS_MGMT_DATETIME_GET | MGMT_EVT_OP_OS_MGMT_DATETIME_SET), +}; +#endif + +ZTEST(os_mgmt_datetime_not_set, test_datetime_get_not_set_v1) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(rc, MGMT_ERR_ENOENT, "Expected 'rc' to be no entity"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_get_not_set_v2) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, true, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(group_error.group, MGMT_GROUP_ID_OS, "Expected 'err' -> 'group' to be OS"); + zassert_equal(group_error.rc, OS_MGMT_ERR_RTC_NOT_SET, + "Expected 'err' -> 'rc' to be RTC not set"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_1) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, false, invalid_time_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(rc, MGMT_ERR_ENOENT, "Expected 'rc' to be no entity"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_2) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, false, invalid_time2_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(rc, MGMT_ERR_ENOENT, "Expected 'rc' to be no entity"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_3) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, false, invalid_time3_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(rc, MGMT_ERR_ENOENT, "Expected 'rc' to be no entity"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_1) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, true, invalid_time2_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, true, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(group_error.group, MGMT_GROUP_ID_OS, "Expected 'err' -> 'group' to be OS"); + zassert_equal(group_error.rc, OS_MGMT_ERR_RTC_NOT_SET, + "Expected 'err' -> 'rc' to be RTC not set"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_2) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, true, invalid_time2_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, true, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(group_error.group, MGMT_GROUP_ID_OS, "Expected 'err' -> 'group' to be OS"); + zassert_equal(group_error.rc, OS_MGMT_ERR_RTC_NOT_SET, + "Expected 'err' -> 'rc' to be RTC not set"); +} + +ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_3) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet_str(zse, true, invalid_time3_string, buffer, + buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EINVAL, "Expected 'rc' to be invalid value"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, true, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Expected to receive err element"); + zassert_equal(group_error.group, MGMT_GROUP_ID_OS, "Expected 'err' -> 'group' to be OS"); + zassert_equal(group_error.rc, OS_MGMT_ERR_RTC_NOT_SET, + "Expected 'err' -> 'rc' to be RTC not set"); +} + +ZTEST(os_mgmt_datetime_set, test_datetime_set_v1) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet(zse, false, &valid_time, buffer, buffer_out, + &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 0, "Did not expect to receive any decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Expected to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expected to receive err element"); + + /* Check that the date/time is as expected */ + zassert_equal(output.len, strlen(valid_time_string), + "Expected received datetime length mismatch"); + zassert_mem_equal(output.value, valid_time_string, strlen(valid_time_string), + "Expected received datetime value mismatch"); +} + +ZTEST(os_mgmt_datetime_set, test_datetime_set_v2) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet(zse, true, &valid_time2, buffer, buffer_out, + &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 0, "Did not expect to receive any decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Expected to receive datetime element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Did not expect to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expected to receive err element"); + + /* Check that the date/time is as expected */ + zassert_equal(output.len, strlen(valid_time2_string), + "Expected received datetime length mismatch"); + zassert_mem_equal(output.value, valid_time2_string, strlen(valid_time2_string), + "Expected received datetime value mismatch"); +} + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK +static void *setup_os_datetime_callbacks(void) +{ + mgmt_callback_register(&os_datetime_callbacks); + return NULL; +} + +static void destroy_os_datetime_callbacks(void *p) +{ + mgmt_callback_unregister(&os_datetime_callbacks); +} + +ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v1) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + struct rtc_time *hook_data; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet(zse, false, &valid_time2, buffer, buffer_out, + &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EACCESSDENIED, "Expected 'rc' to be access denied"); + + /* Check hook actions are as expected */ + hook_data = (struct rtc_time *)hook_set_data; + zassert_false(hook_get_ran, "Did not expect get hook to run"); + zassert_true(hook_set_ran, "Expected set hook to run"); + zassert_false(hook_other_ran, "Did not expect other hooks to run"); + zassert_equal(hook_set_data_size, sizeof(valid_time2), + "Expected data size to match time struct size"); + zassert_equal(valid_time2.tm_sec, hook_data->tm_sec, "Expected value mismatch"); + zassert_equal(valid_time2.tm_min, hook_data->tm_min, "Expected value mismatch"); + zassert_equal(valid_time2.tm_hour, hook_data->tm_hour, "Expected value mismatch"); + zassert_equal(valid_time2.tm_mday, hook_data->tm_mday, "Expected value mismatch"); + zassert_equal(valid_time2.tm_mon, (hook_data->tm_mon + 1), "Expected value mismatch"); + zassert_equal(valid_time2.tm_year, (hook_data->tm_year + 1900), + "Expected value mismatch"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, false, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EBUSY, "Expected 'rc' to be busy"); + + /* Check hook actions are as expected */ + zassert_true(hook_get_ran, "Expected get hook to run"); + zassert_false(hook_set_ran, "Did not expect set hook to run"); + zassert_false(hook_other_ran, "Did not expect other hooks to run"); + zassert_equal(hook_set_data_size, 0, "Expected data size to be 0"); +} + +ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v2) +{ + uint8_t buffer[ZCBOR_BUFFER_SIZE]; + uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; + bool ok; + uint16_t buffer_size; + zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; + bool received; + struct zcbor_string output = { 0 }; + size_t decoded = 0; + struct group_error group_error; + int rc; + struct rtc_time *hook_data; + + struct zcbor_map_decode_key_val output_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("datetime", zcbor_tstr_decode, &output), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc), + ZCBOR_MAP_DECODE_KEY_DECODER("err", mcumgr_ret_decode, &group_error), + }; + + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + + zcbor_new_encode_state(zse, 4, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_set_packet(zse, true, &valid_time2, buffer, buffer_out, + &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EACCESSDENIED, "Expected 'rc' to be access denied"); + + /* Check hook actions are as expected */ + hook_data = (struct rtc_time *)hook_set_data; + zassert_false(hook_get_ran, "Did not expect get hook to run"); + zassert_true(hook_set_ran, "Expected set hook to run"); + zassert_false(hook_other_ran, "Did not expect other hooks to run"); + zassert_equal(hook_set_data_size, sizeof(valid_time2), + "Expected data size to match time struct size"); + zassert_equal(valid_time2.tm_sec, hook_data->tm_sec, "Expected value mismatch"); + zassert_equal(valid_time2.tm_min, hook_data->tm_min, "Expected value mismatch"); + zassert_equal(valid_time2.tm_hour, hook_data->tm_hour, "Expected value mismatch"); + zassert_equal(valid_time2.tm_mday, hook_data->tm_mday, "Expected value mismatch"); + zassert_equal(valid_time2.tm_mon, (hook_data->tm_mon + 1), "Expected value mismatch"); + zassert_equal(valid_time2.tm_year, (hook_data->tm_year + 1900), "Expected value mismatch"); + + /* Clean up test */ + cleanup_test(NULL); + memset(buffer, 0, sizeof(buffer)); + memset(buffer_out, 0, sizeof(buffer_out)); + buffer_size = 0; + memset(zse, 0, sizeof(zse)); + memset(zsd, 0, sizeof(zsd)); + output_decode[0].found = false; + output_decode[1].found = false; + output_decode[2].found = false; + + /* Query time and ensure it is not set */ + zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); + ok = create_mcumgr_datetime_get_packet(zse, true, buffer, buffer_out, &buffer_size); + zassert_true(ok, "Expected packet creation to be successful"); + + /* Enable dummy SMP backend and ready for usage */ + smp_dummy_enable(); + smp_dummy_clear_state(); + + /* Send query command to dummy SMP backend */ + (void)smp_dummy_tx_pkt(buffer_out, buffer_size); + smp_dummy_add_data(); + + /* For a short duration to see if response has been received */ + received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); + zassert_true(received, "Expected to receive data but timed out"); + + /* Retrieve response buffer and ensure validity */ + nb = smp_dummy_get_outgoing(); + smp_dummy_disable(); + + /* Process received data by removing header */ + (void)net_buf_pull(nb, sizeof(struct smp_hdr)); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; + zassert_true(ok, "Expected decode to be successful"); + zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "datetime"), "Did not expect to receive datetime element"); + zassert_true(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "rc"), "Expected to receive rc element"); + zassert_false(zcbor_map_decode_bulk_key_found(output_decode, ARRAY_SIZE(output_decode), + "err"), "Did not expect to receive err element"); + zassert_equal(rc, MGMT_ERR_EBUSY, "Expected 'rc' to be busy"); + + /* Check hook actions are as expected */ + zassert_true(hook_get_ran, "Expected get hook to run"); + zassert_false(hook_set_ran, "Did not expect set hook to run"); + zassert_false(hook_other_ran, "Did not expect other hooks to run"); + zassert_equal(hook_set_data_size, 0, "Expected data size to be 0"); +} +#endif + +static void cleanup_test(void *p) +{ + if (nb != NULL) { + net_buf_unref(nb); + nb = NULL; + } + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK + hook_get_ran = false; + hook_set_ran = false; + hook_other_ran = false; + hook_set_data_size = 0; + hook_set_data[0] = 0; +#endif +} + +void test_main(void) +{ + while (test_state.test_set < OS_MGMT_DATETIME_TEST_SET_COUNT) { + ztest_run_all(&test_state); + ++test_state.test_set; + } + + ztest_verify_all_test_suites_ran(); +} + +static bool time_not_set_predicate(const void *state) +{ + return ((struct state *)state)->test_set == OS_MGMT_DATETIME_TEST_SET_TIME_NOT_SET; +} + +static bool time_set_predicate(const void *state) +{ + return ((struct state *)state)->test_set == OS_MGMT_DATETIME_TEST_SET_TIME_SET; +} + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK +static bool hooks_predicate(const void *state) +{ + return ((struct state *)state)->test_set == OS_MGMT_DATETIME_TEST_SET_HOOKS; +} +#endif + +/* Time not set test set */ +ZTEST_SUITE(os_mgmt_datetime_not_set, time_not_set_predicate, NULL, NULL, cleanup_test, NULL); + +#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_HOOK +/* Hook test set */ +ZTEST_SUITE(os_mgmt_datetime_hook, hooks_predicate, setup_os_datetime_callbacks, NULL, + cleanup_test, destroy_os_datetime_callbacks); +#endif + +/* Time set test set */ +ZTEST_SUITE(os_mgmt_datetime_set, time_set_predicate, NULL, NULL, cleanup_test, NULL); diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.c b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.c new file mode 100644 index 00000000000..927089c3ee3 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2023 Jamie M. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "smp_test_util.h" +#include +#include +#include +#include + +/* SMP header function for generating os_mgmt datetime command header with sequence number set + * to 1 + */ +void smp_make_hdr(struct smp_hdr *rsp_hdr, size_t len, bool version2, bool write) +{ + *rsp_hdr = (struct smp_hdr) { + .nh_len = sys_cpu_to_be16(len), + .nh_flags = 0, + .nh_version = (version2 == true ? SMP_MCUMGR_VERSION_2 : SMP_MCUMGR_VERSION_1), + .nh_op = (write == true ? MGMT_OP_WRITE : MGMT_OP_READ), + .nh_group = sys_cpu_to_be16(MGMT_GROUP_ID_OS), + .nh_seq = 1, + .nh_id = OS_MGMT_ID_DATETIME_STR, + }; +} + +/* Function for creating an os_mgmt datetime get command */ +bool create_mcumgr_datetime_get_packet(zcbor_state_t *zse, bool version2, uint8_t *buffer, + uint8_t *output_buffer, uint16_t *buffer_size) +{ + bool ok; + + ok = zcbor_map_start_encode(zse, 2) && + zcbor_map_end_encode(zse, 2); + + *buffer_size = (zse->payload_mut - buffer); + smp_make_hdr((struct smp_hdr *)output_buffer, *buffer_size, version2, false); + memcpy(&output_buffer[sizeof(struct smp_hdr)], buffer, *buffer_size); + *buffer_size += sizeof(struct smp_hdr); + + return ok; +} + +/* Functions for creating an os_mgmt datetime set command */ +bool create_mcumgr_datetime_set_packet_str(zcbor_state_t *zse, bool version2, const char *data, + uint8_t *buffer, uint8_t *output_buffer, + uint16_t *buffer_size) +{ + bool ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "datetime") && + zcbor_tstr_put_term(zse, data) && + zcbor_map_end_encode(zse, 2); + + *buffer_size = (zse->payload_mut - buffer); + smp_make_hdr((struct smp_hdr *)output_buffer, *buffer_size, version2, true); + memcpy(&output_buffer[sizeof(struct smp_hdr)], buffer, *buffer_size); + *buffer_size += sizeof(struct smp_hdr); + + return ok; +} + +bool create_mcumgr_datetime_set_packet(zcbor_state_t *zse, bool version2, struct rtc_time *a_time, + uint8_t *buffer, uint8_t *output_buffer, + uint16_t *buffer_size) +{ + char tmp_str[32]; + + sprintf(tmp_str, "%4d-%02d-%02dT%02d:%02d:%02d", (uint16_t)a_time->tm_year, + (uint8_t)a_time->tm_mon, (uint8_t)a_time->tm_mday, (uint8_t)a_time->tm_hour, + (uint8_t)a_time->tm_min, (uint8_t)a_time->tm_sec); + + return create_mcumgr_datetime_set_packet_str(zse, version2, tmp_str, buffer, + output_buffer, buffer_size); +} diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.h b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.h new file mode 100644 index 00000000000..958ccfdd5ad --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/smp_test_util.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2023 Jamie M. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_SMP_TEST_UTIL_ +#define H_SMP_TEST_UTIL_ + +#include +#include +#include +#include +#include + +/* SMP header function for generating os_mgmt datetime command header with sequence number set + * to 1 + */ +void smp_make_hdr(struct smp_hdr *rsp_hdr, size_t len, bool version2, bool write); + +/* Function for creating an os_mgmt datetime get command */ +bool create_mcumgr_datetime_get_packet(zcbor_state_t *zse, bool version2, uint8_t *buffer, + uint8_t *output_buffer, uint16_t *buffer_size); + +/* Function for creating an os_mgmt datetime set command */ +bool create_mcumgr_datetime_set_packet_str(zcbor_state_t *zse, bool version2, const char *data, + uint8_t *buffer, uint8_t *output_buffer, + uint16_t *buffer_size); + +bool create_mcumgr_datetime_set_packet(zcbor_state_t *zse, bool version2, struct rtc_time *a_time, + uint8_t *buffer, uint8_t *output_buffer, + uint16_t *buffer_size); + +#endif diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/testcase.yaml b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/testcase.yaml new file mode 100644 index 00000000000..013a371c9a0 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/testcase.yaml @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +common: + tags: + - mcumgr + - os_mgmt_datetime + platform_allow: + - native_posix + - qemu_cortex_m0 + - qemu_riscv64 + - qemu_riscv64_smp + - qemu_malta + - qemu_arc_hs6x + - qemu_leon3 +tests: + mgmt.mcumgr.os.datetime: {} From 20f0e37413863986064a2c00241afb09232761d0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 9 Nov 2023 18:18:57 +0000 Subject: [PATCH 3468/4498] doc: release: 3.6: Add note on MCUmgr OS mgmt datetime Adds a note that datetime support has been added to MCUmgr Signed-off-by: Jamie McCrae --- doc/releases/release-notes-3.6.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst index 3c1248222ee..676e16fa77c 100644 --- a/doc/releases/release-notes-3.6.rst +++ b/doc/releases/release-notes-3.6.rst @@ -247,6 +247,9 @@ Libraries / Subsystems * Fixed an issue in MCUmgr which would cause a user data buffer overflow if the UDP transport was enabled on IPv4 only but IPv6 support was enabled in the kernel. + * Implemented datetime functionality in MCUmgr OS management group, this makes use of the RTC + driver API. + * File systems * Modem modules From 5c05b61ecde1fa407173ba936fab94b151ca5400 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 10 Nov 2023 08:02:45 +0000 Subject: [PATCH 3469/4498] doc: mgmt: mcumgr: Remove OS mgmt datetime unimplemented note This functionality is now implemented Signed-off-by: Jamie McCrae --- doc/services/device_mgmt/smp_groups/smp_group_0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index ba15ac22a1d..7fb91463e33 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -20,7 +20,7 @@ OS management group defines following commands: +-------------------+-----------------------------------------------+ | ``3`` | Memory pool statistics | +-------------------+-----------------------------------------------+ - | ``4`` | Date-time string; unimplemented by Zephyr | + | ``4`` | Date-time string | +-------------------+-----------------------------------------------+ | ``5`` | System reset | +-------------------+-----------------------------------------------+ From 1032fe3b5c18e52c952a705014f91327a0ce3928 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Tue, 7 Nov 2023 18:57:11 +0100 Subject: [PATCH 3470/4498] tests: coredump: Extend backends test coverage Extend coredump_backend tests: * fix COREDUMP_CMD_VERIFY_STORED_DUMP test was not executed. * add tests for these coredump commands: - COREDUMP_QUERY_GET_STORED_DUMP_SIZE, - COREDUMP_CMD_INVALIDATE_STORED_DUMP, - COREDUMP_CMD_ERASE_STORED_DUMP, - COREDUMP_CMD_CLEAR_ERROR. * extend the out-of-the-treee example 'empty' backend to execute the new tests. * fix the test's cmake project name. Signed-off-by: Dmitrii Golovanov --- .../debug/coredump_backends/CMakeLists.txt | 2 +- tests/subsys/debug/coredump_backends/Kconfig | 17 ++ .../src/coredump_backend_empty.c | 11 + .../subsys/debug/coredump_backends/src/main.c | 198 ++++++++++++++++-- .../debug/coredump_backends/testcase.yaml | 6 + 5 files changed, 217 insertions(+), 17 deletions(-) create mode 100644 tests/subsys/debug/coredump_backends/Kconfig diff --git a/tests/subsys/debug/coredump_backends/CMakeLists.txt b/tests/subsys/debug/coredump_backends/CMakeLists.txt index a7d48d53d4f..5ae2b1f792c 100644 --- a/tests/subsys/debug/coredump_backends/CMakeLists.txt +++ b/tests/subsys/debug/coredump_backends/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(hello_world) +project(debug_coredump_backends) target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/debug/coredump_backends/Kconfig b/tests/subsys/debug/coredump_backends/Kconfig new file mode 100644 index 00000000000..dc02b1341a2 --- /dev/null +++ b/tests/subsys/debug/coredump_backends/Kconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config TEST_STORED_COREDUMP + bool "Expected backend has coredump storage." + help + Set if the test expects coredump backend with storage. + +config TEST_STORED_DUMP_SIZE + int "Expected backend's coredump storage size." + default 0 + help + Test expects coredump backend storage with the size given. + If zero, then it is ignored and not compared with the actual size. diff --git a/tests/subsys/debug/coredump_backends/src/coredump_backend_empty.c b/tests/subsys/debug/coredump_backends/src/coredump_backend_empty.c index 82cee0b70d9..ce3229bbeba 100644 --- a/tests/subsys/debug/coredump_backends/src/coredump_backend_empty.c +++ b/tests/subsys/debug/coredump_backends/src/coredump_backend_empty.c @@ -42,6 +42,9 @@ static int coredump_empty_backend_query(enum coredump_query_id query_id, ret = 1; } break; + case COREDUMP_QUERY_GET_STORED_DUMP_SIZE: + ret = 0; + break; default: ret = -ENOTSUP; break; @@ -66,6 +69,14 @@ static int coredump_empty_backend_cmd(enum coredump_cmd_id cmd_id, ret = 1; } break; + case COREDUMP_CMD_INVALIDATE_STORED_DUMP: + is_valid = false; + ret = 0; + break; + case COREDUMP_CMD_ERASE_STORED_DUMP: + is_valid = false; + ret = 0; + break; default: ret = -ENOTSUP; break; diff --git a/tests/subsys/debug/coredump_backends/src/main.c b/tests/subsys/debug/coredump_backends/src/main.c index f855d047751..8b7636edbd9 100644 --- a/tests/subsys/debug/coredump_backends/src/main.c +++ b/tests/subsys/debug/coredump_backends/src/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. + * Copyright (c) 2020-2023, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,7 +35,7 @@ void dump_entry(void *p1, void *p2, void *p3) irq_unlock(key); } -static void check_errors(void) +void check_error(void) { int ret; @@ -45,10 +46,23 @@ static void check_errors(void) } } -void test_coredump(void) +void clear_error(void) +{ + int ret; + + /* Clear backend error if backend supports this query */ + ret = coredump_cmd(COREDUMP_CMD_CLEAR_ERROR, NULL); + if (ret != -ENOTSUP) { + zassert_equal(ret, 0, "Error encountered! (%d)", ret); + } +} + +static void *raise_coredump(void) { k_tid_t tid; + clear_error(); + /* Create a thread that crashes */ tid = k_thread_create(&dump_thread, dump_stack, K_THREAD_STACK_SIZEOF(dump_stack), @@ -57,28 +71,46 @@ void test_coredump(void) k_thread_join(tid, K_FOREVER); - check_errors(); + return &dump_thread; } -void test_query_stored_dump(void) +void test_has_stored_dump(bool is_expected) { int ret; /* Cannot proceed with previous errors */ - check_errors(); + check_error(); /* There should be a stored coredump now if backend has storage */ ret = coredump_query(COREDUMP_QUERY_HAS_STORED_DUMP, NULL); if (ret == -ENOTSUP) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Can't query stored dump: unexpectedly not supported.\n"); + ztest_test_fail(); +#else + TC_PRINT("Can't query stored dump: expectedly not supported.\n"); ztest_test_skip(); +#endif } else if (ret == 1) { - check_errors(); +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); + zassert_true(is_expected, "Unexpected coredump found.\n"); ztest_test_pass(); +#else + TC_ERROR("Can't have a stored dump: not supported.\n"); + ztest_test_fail(); +#endif } else if (ret == 0) { - TC_PRINT("Should have stored dump!\n"); +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); + zassert_false(is_expected, "Should have stored dump!\n"); + ztest_test_pass(); +#else + TC_ERROR("Can't have an empty stored dump: not supported.\n"); ztest_test_fail(); +#endif } else { - TC_PRINT("Error reading stored dump! (%d)\n", ret); + TC_ERROR("Error reading stored dump! (%d)\n", ret); ztest_test_fail(); } } @@ -88,28 +120,162 @@ void test_verify_stored_dump(void) int ret; /* Cannot proceed with previous errors */ - check_errors(); + check_error(); /* There should be a stored coredump now if backend has storage */ ret = coredump_cmd(COREDUMP_CMD_VERIFY_STORED_DUMP, NULL); if (ret == -ENOTSUP) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Can't verify stored dump: unexpectedly not supported.\n"); + ztest_test_fail(); +#else + TC_PRINT("Can't verify stored dump: expectedly not supported.\n"); ztest_test_skip(); +#endif } else if (ret == 1) { - check_errors(); +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); ztest_test_pass(); +#else + TC_ERROR("Can't have a stored dump: not supported.\n"); + ztest_test_fail(); +#endif + } else if (ret == 0) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Verification of stored dump failed!\n"); + ztest_test_fail(); +#else + TC_ERROR("Can't have a stored dump: not supported.\n"); + ztest_test_fail(); +#endif + } else { + TC_ERROR("Error reading stored dump! (%d)\n", ret); + ztest_test_fail(); + } +} + +void test_invalidate_stored_dump(void) +{ + int ret; + + /* Cannot proceed with previous errors */ + check_error(); + + /* There should be a stored coredump now if backend has storage */ + ret = coredump_cmd(COREDUMP_CMD_INVALIDATE_STORED_DUMP, NULL); + if (ret == -ENOTSUP) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Can't invalidate stored dump: unexpectedly not supported.\n"); + ztest_test_fail(); +#else + TC_PRINT("Can't invalidate stored dump: expectedly not supported.\n"); + ztest_test_skip(); +#endif } else if (ret == 0) { - TC_PRINT("Verification of stored dump failed!\n"); +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); + ztest_test_pass(); +#else + TC_ERROR("Can't invalidate the stored dump: not supported.\n"); ztest_test_fail(); +#endif } else { - TC_PRINT("Error reading stored dump! (%d)\n", ret); + TC_ERROR("Error invalidating stored dump! (%d)\n", ret); ztest_test_fail(); } } -ZTEST(coredump_backends, test_coredump_backend) { - test_coredump(); - test_query_stored_dump(); +void test_erase_stored_dump(void) +{ + int ret; + + /* Cannot proceed with previous errors */ + check_error(); + + /* There should be a stored coredump now if backend has storage */ + ret = coredump_cmd(COREDUMP_CMD_ERASE_STORED_DUMP, NULL); + if (ret == -ENOTSUP) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Can't erase stored dump: unexpectedly not supported.\n"); + ztest_test_fail(); +#else + TC_PRINT("Can't erase stored dump: expectedly not supported.\n"); + ztest_test_skip(); +#endif + } else if (ret == 0) { +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); + ztest_test_pass(); +#else + TC_ERROR("Can't erase the stored dump: not supported.\n"); + ztest_test_fail(); +#endif + } else { + TC_ERROR("Error erasing stored dump! (%d)\n", ret); + ztest_test_fail(); + } +} + +void test_get_stored_dump_size(int size_expected) +{ + int ret; + + /* Cannot proceed with previous errors */ + check_error(); + + ret = coredump_query(COREDUMP_QUERY_GET_STORED_DUMP_SIZE, NULL); + if (ret == -ENOTSUP) { +#ifdef CONFIG_TEST_STORED_COREDUMP + TC_ERROR("Can't query stored dump size: unexpectedly not supported.\n"); + ztest_test_fail(); +#else + TC_PRINT("Can't query stored dump size: expectedly not supported.\n"); + ztest_test_skip(); +#endif + } else if (ret >= 0) { +#ifdef CONFIG_TEST_STORED_COREDUMP + check_error(); + if (size_expected > 0) { + zassert_equal(ret, size_expected, + "Coredump size %d != %d size expected.\n", + ret, size_expected); + } + ztest_test_pass(); +#else + TC_ERROR("Can't have a stored dump: not supported.\n"); + ztest_test_fail(); +#endif + } else { + TC_ERROR("Error reading stored dump size! (%d)\n", ret); + ztest_test_fail(); + } +} + +/* Excecute tests in exact sequence with the stored core dump. */ + +ZTEST(coredump_backends, test_coredump_0_ready) { + check_error(); + ztest_test_pass(); +} + +ZTEST(coredump_backends, test_coredump_1_stored) { + test_has_stored_dump(true); +} + +ZTEST(coredump_backends, test_coredump_2_size) { + test_get_stored_dump_size(CONFIG_TEST_STORED_DUMP_SIZE); +} + +ZTEST(coredump_backends, test_coredump_3_verify) { test_verify_stored_dump(); } -ZTEST_SUITE(coredump_backends, NULL, NULL, NULL, NULL, NULL); +ZTEST(coredump_backends, test_coredump_4_invalidate) { + test_invalidate_stored_dump(); +} + +ZTEST(coredump_backends, test_coredump_5_erase) { + test_erase_stored_dump(); +} + +ZTEST_SUITE(coredump_backends, NULL, raise_coredump, NULL, NULL, NULL); diff --git a/tests/subsys/debug/coredump_backends/testcase.yaml b/tests/subsys/debug/coredump_backends/testcase.yaml index 6055c52906e..b8fc6078f78 100644 --- a/tests/subsys/debug/coredump_backends/testcase.yaml +++ b/tests/subsys/debug/coredump_backends/testcase.yaml @@ -10,6 +10,8 @@ tests: debug.coredump.backends.logging: filter: CONFIG_ARCH_SUPPORTS_COREDUMP platform_exclude: acrn_ehl_crb + extra_configs: + - CONFIG_TEST_STORED_COREDUMP=n harness: console harness_config: type: multi_line @@ -20,6 +22,8 @@ tests: debug.coredump.backends.flash: filter: CONFIG_ARCH_SUPPORTS_COREDUMP extra_args: CONF_FILE=prj_flash_partition.conf + extra_configs: + - CONFIG_TEST_STORED_COREDUMP=y platform_allow: - qemu_x86 - esp32_devkitc_wroom @@ -30,4 +34,6 @@ tests: debug.coredump.backends.other: filter: CONFIG_ARCH_SUPPORTS_COREDUMP extra_args: CONF_FILE=prj_backend_other.conf + extra_configs: + - CONFIG_TEST_STORED_COREDUMP=y platform_exclude: acrn_ehl_crb From 4d394f9d23438681d01aac60e932f472e52a70e5 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Wed, 8 Nov 2023 12:11:15 +0100 Subject: [PATCH 3471/4498] tests: coredump: Fix backend.logging test misconfig The debug.coredump.backends.logging testcase did use 'console' Twister harness whereas the test suite itself and the rest of the testcases are implemented as Ztest. This misalignment allowed to check basic output expected from the logging backend, but caused inconsistency of the test suite results because the 'console' Twister Harness can't use test cases' ID provided by the 'Ztest' Twister Handler. It is decided to focus the debug.coredump.backends.* suite on the coredump backend API testing with Ztest. The logging backend's resulting output should be tested by its dedicated test suite debug.coredump.logging_backend (tests/subsys/debug/coredump). Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/coredump_backends/testcase.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/subsys/debug/coredump_backends/testcase.yaml b/tests/subsys/debug/coredump_backends/testcase.yaml index b8fc6078f78..d7b5f722f37 100644 --- a/tests/subsys/debug/coredump_backends/testcase.yaml +++ b/tests/subsys/debug/coredump_backends/testcase.yaml @@ -12,13 +12,6 @@ tests: platform_exclude: acrn_ehl_crb extra_configs: - CONFIG_TEST_STORED_COREDUMP=n - harness: console - harness_config: - type: multi_line - regex: - - "E: #CD:BEGIN#" - - "E: #CD:5([aA])45([0-9a-fA-F]+)" - - "E: #CD:END#" debug.coredump.backends.flash: filter: CONFIG_ARCH_SUPPORTS_COREDUMP extra_args: CONF_FILE=prj_flash_partition.conf From 39eb124c81e88a6b2da3d42c9f76a91f29fbbb28 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Wed, 8 Nov 2023 15:45:30 +0100 Subject: [PATCH 3472/4498] drivers: add MAX20335 charger driver Add a MAX20335 MFD subdriver for the built-in battery charger. Signed-off-by: Bartosz Bilas --- drivers/charger/CMakeLists.txt | 1 + drivers/charger/Kconfig | 1 + drivers/charger/Kconfig.max20335 | 11 + drivers/charger/charger_max20335.c | 287 ++++++++++++++++++ .../charger/maxim,max20335-charger.yaml | 8 + tests/drivers/build_all/charger/i2c.dtsi | 13 + 6 files changed, 321 insertions(+) create mode 100644 drivers/charger/Kconfig.max20335 create mode 100644 drivers/charger/charger_max20335.c create mode 100644 dts/bindings/charger/maxim,max20335-charger.yaml diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt index 894561982a3..ce70f0590c6 100644 --- a/drivers/charger/CMakeLists.txt +++ b/drivers/charger/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_library() zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) zephyr_library_sources_ifdef(CONFIG_CHARGER_BQ24190 charger_bq24190.c) +zephyr_library_sources_ifdef(CONFIG_CHARGER_MAX20335 charger_max20335.c) zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig index 4a6071fd8f8..9c7873168a5 100644 --- a/drivers/charger/Kconfig +++ b/drivers/charger/Kconfig @@ -21,5 +21,6 @@ config CHARGER_INIT_PRIORITY source "drivers/charger/Kconfig.sbs_charger" source "drivers/charger/Kconfig.bq24190" +source "drivers/charger/Kconfig.max20335" endif # CHARGER diff --git a/drivers/charger/Kconfig.max20335 b/drivers/charger/Kconfig.max20335 new file mode 100644 index 00000000000..7104e5daab6 --- /dev/null +++ b/drivers/charger/Kconfig.max20335 @@ -0,0 +1,11 @@ +# Copyright 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +config CHARGER_MAX20335 + bool "MAX20335 battery charger driver" + default y + depends on DT_HAS_MAXIM_MAX20335_CHARGER_ENABLED + select I2C + select MFD + help + Enable the MAX20335 battery charger driver. diff --git a/drivers/charger/charger_max20335.c b/drivers/charger/charger_max20335.c new file mode 100644 index 00000000000..75eae16f888 --- /dev/null +++ b/drivers/charger/charger_max20335.c @@ -0,0 +1,287 @@ +/* + * Copyright 2023 Grinn + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT maxim_max20335_charger + +#include +#include +#include +#include +#include +#include + +#include "zephyr/logging/log.h" +LOG_MODULE_REGISTER(max20335_charger); + +#define MAX20335_REG_STATUS_A 0x02 +#define MAX20335_REG_ILIMCNTL 0x09 +#define MAX20335_REG_CHG_CNTL_A 0x0A +#define MAX20335_CHGCNTLA_BAT_REG_CFG_MASK GENMASK(4, 1) +#define MAX20335_ILIMCNTL_MASK GENMASK(1, 0) +#define MAX20335_STATUS_A_CHG_STAT_MASK GENMASK(2, 0) +#define MAX20335_CHRG_EN_MASK BIT(0) +#define MAX20335_CHRG_EN BIT(0) +#define MAX20335_REG_CVC_VREG_MIN_UV 4050000U +#define MAX20335_REG_CVC_VREG_STEP_UV 50000U +#define MAX20335_REG_CVC_VREG_MIN_IDX 0x0U +#define MAX20335_REG_CVC_VREG_MAX_IDX 0x0CU + +struct charger_max20335_config { + struct i2c_dt_spec bus; + uint32_t max_ichg_ua; + uint32_t max_vreg_uv; +}; + +enum { + MAX20335_CHARGER_OFF, + MAX20335_CHARGING_SUSPENDED_DUE_TO_TEMPERATURE, + MAX20335_PRE_CHARGE_IN_PROGRESS, + MAX20335_FAST_CHARGE_IN_PROGRESS_1, + MAX20335_FAST_CHARGE_IN_PROGRESS_2, + MAX20335_MAINTAIN_CHARGE_IN_PROGRESS, + MAX20335_MAIN_CHARGER_TIMER_DONE, + MAX20335_CHARGER_FAULT_CONDITION, +}; + +static const struct linear_range charger_uv_range = + LINEAR_RANGE_INIT(MAX20335_REG_CVC_VREG_MIN_UV, + MAX20335_REG_CVC_VREG_STEP_UV, + MAX20335_REG_CVC_VREG_MIN_IDX, + MAX20335_REG_CVC_VREG_MAX_IDX); + +static int max20335_get_status(const struct device *dev, enum charger_status *status) +{ + const struct charger_max20335_config *const config = dev->config; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_STATUS_A, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(MAX20335_STATUS_A_CHG_STAT_MASK, val); + + switch (val) { + case MAX20335_CHARGER_OFF: + __fallthrough; + case MAX20335_CHARGING_SUSPENDED_DUE_TO_TEMPERATURE: + __fallthrough; + case MAX20335_CHARGER_FAULT_CONDITION: + *status = CHARGER_STATUS_NOT_CHARGING; + break; + case MAX20335_PRE_CHARGE_IN_PROGRESS: + __fallthrough; + case MAX20335_FAST_CHARGE_IN_PROGRESS_1: + __fallthrough; + case MAX20335_FAST_CHARGE_IN_PROGRESS_2: + __fallthrough; + case MAX20335_MAINTAIN_CHARGE_IN_PROGRESS: + *status = CHARGER_STATUS_CHARGING; + break; + case MAX20335_MAIN_CHARGER_TIMER_DONE: + *status = CHARGER_STATUS_FULL; + break; + default: + *status = CHARGER_STATUS_UNKNOWN; + break; + }; + + return 0; +} + +static int max20335_set_constant_charge_voltage(const struct device *dev, + uint32_t voltage_uv) +{ + const struct charger_max20335_config *const config = dev->config; + uint16_t idx; + uint8_t val; + int ret; + + if (voltage_uv > config->max_vreg_uv) { + LOG_WRN("Exceeded max constant charge voltage!"); + return -EINVAL; + } + + ret = linear_range_get_index(&charger_uv_range, voltage_uv, &idx); + if (ret == -EINVAL) { + return ret; + } + + val = FIELD_PREP(MAX20335_CHGCNTLA_BAT_REG_CFG_MASK, idx); + + return i2c_reg_update_byte_dt(&config->bus, + MAX20335_REG_CHG_CNTL_A, + MAX20335_CHGCNTLA_BAT_REG_CFG_MASK, + val); +} + +static int max20335_set_constant_charge_current(const struct device *dev, + uint32_t current_ua) +{ + const struct charger_max20335_config *const config = dev->config; + uint8_t val; + + if (current_ua > config->max_ichg_ua) { + LOG_WRN("Exceeded max constant charge current!"); + return -EINVAL; + } + + switch (current_ua) { + case 0: + val = 0x00; + break; + case 100000: + val = 0x01; + break; + case 500000: + val = 0x02; + break; + case 1000000: + val = 0x03; + break; + default: + return -ENOTSUP; + }; + + val = FIELD_PREP(MAX20335_ILIMCNTL_MASK, val); + + return i2c_reg_update_byte_dt(&config->bus, + MAX20335_REG_ILIMCNTL, + MAX20335_ILIMCNTL_MASK, + val); +} + +static int max20335_get_constant_charge_current(const struct device *dev, + uint32_t *current_ua) +{ + const struct charger_max20335_config *const config = dev->config; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_ILIMCNTL, &val); + if (ret) { + return ret; + } + + switch (val) { + case 0x00: + *current_ua = 0; + break; + case 0x01: + *current_ua = 100000; + break; + case 0x02: + *current_ua = 500000; + break; + case 0x03: + *current_ua = 1000000; + break; + default: + return -ENOTSUP; + }; + + return 0; +} + +static int max20335_get_constant_charge_voltage(const struct device *dev, + uint32_t *current_uv) +{ + const struct charger_max20335_config *const config = dev->config; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_CHG_CNTL_A, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(MAX20335_CHGCNTLA_BAT_REG_CFG_MASK, val); + + return linear_range_get_value(&charger_uv_range, val, current_uv); +} + +static int max20335_set_enabled(const struct device *dev, bool enable) +{ + const struct charger_max20335_config *const config = dev->config; + + return i2c_reg_update_byte_dt(&config->bus, + MAX20335_REG_CHG_CNTL_A, + MAX20335_CHRG_EN_MASK, + enable ? MAX20335_CHRG_EN : 0); +} + +static int max20335_get_prop(const struct device *dev, charger_prop_t prop, + union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_STATUS: + return max20335_get_status(dev, &val->status); + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return max20335_get_constant_charge_current(dev, + &val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return max20335_get_constant_charge_voltage(dev, + &val->const_charge_voltage_uv); + default: + return -ENOTSUP; + } +} + +static int max20335_set_prop(const struct device *dev, charger_prop_t prop, + const union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_STATUS: + switch (val->status) { + case CHARGER_STATUS_CHARGING: + return max20335_set_enabled(dev, true); + case CHARGER_STATUS_NOT_CHARGING: + return max20335_set_enabled(dev, false); + default: + return -ENOTSUP; + } + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return max20335_set_constant_charge_current(dev, + val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return max20335_set_constant_charge_voltage(dev, + val->const_charge_voltage_uv); + default: + return -ENOTSUP; + } + +} + +static int max20335_init(const struct device *dev) +{ + const struct charger_max20335_config *config = dev->config; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + return 0; +} + +static const struct charger_driver_api max20335_driver_api = { + .get_property = max20335_get_prop, + .set_property = max20335_set_prop, +}; + +#define MAX20335_DEFINE(inst) \ + static const struct charger_max20335_config charger_max20335_config_##inst = { \ + .bus = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)), \ + .max_ichg_ua = DT_INST_PROP(inst, constant_charge_current_max_microamp), \ + .max_vreg_uv = DT_INST_PROP(inst, constant_charge_voltage_max_microvolt), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &max20335_init, NULL, NULL, \ + &charger_max20335_config_##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + &max20335_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MAX20335_DEFINE) diff --git a/dts/bindings/charger/maxim,max20335-charger.yaml b/dts/bindings/charger/maxim,max20335-charger.yaml new file mode 100644 index 00000000000..45b7cc87997 --- /dev/null +++ b/dts/bindings/charger/maxim,max20335-charger.yaml @@ -0,0 +1,8 @@ +# Copyright (c), 2023 Grinn +# SPDX -License-Identifier: Apache-2.0 + +description: Maxim MAX20335 battery charger + +include: battery.yaml + +compatible: "maxim,max20335-charger" diff --git a/tests/drivers/build_all/charger/i2c.dtsi b/tests/drivers/build_all/charger/i2c.dtsi index 53cbcf0e59b..c30efdcfcb8 100644 --- a/tests/drivers/build_all/charger/i2c.dtsi +++ b/tests/drivers/build_all/charger/i2c.dtsi @@ -15,3 +15,16 @@ bq24190@0 { constant-charge-current-max-microamp = <1000000>; constant-charge-voltage-max-microvolt = <4208000>; }; + +max20335@1 { + compatible = "maxim,max20335"; + reg = <0x01>; + status = "okay"; + + charger: charger { + compatible = "maxim,max20335-charger"; + + constant-charge-current-max-microamp = <100000>; + constant-charge-voltage-max-microvolt = <4050000>; + }; +}; From 18a0660be084bfe3525d448af3d849960eb8f7cf Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 9 Nov 2023 02:36:25 +0700 Subject: [PATCH 3473/4498] samples/tests: skip samples/tests disable MPU for s32ze series On SoC series s32ze, Zephyr application cannot run with MPU disabled, skipping relevant samples/tests Signed-off-by: Dat Nguyen Duy --- samples/subsys/llext/shell_loader/sample.yaml | 2 +- tests/subsys/llext/testcase.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/subsys/llext/shell_loader/sample.yaml b/samples/subsys/llext/shell_loader/sample.yaml index 5ef2a080286..acb30def4da 100644 --- a/samples/subsys/llext/shell_loader/sample.yaml +++ b/samples/subsys/llext/shell_loader/sample.yaml @@ -5,7 +5,7 @@ tests: sample.llext.shell: tags: shell llext harness: keyboard - filter: not CONFIG_CPU_HAS_MMU + filter: not CONFIG_CPU_HAS_MMU and not CONFIG_SOC_SERIES_S32ZE_R52 arch_allow: arm extra_configs: - CONFIG_ARM_MPU=n diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index 6d493276b93..79d8f5a1fd9 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -2,7 +2,7 @@ common: tags: llext tests: llext.simple.arm: - filter: not CONFIG_CPU_HAS_MMU + filter: not CONFIG_CPU_HAS_MMU and not CONFIG_SOC_SERIES_S32ZE_R52 arch_allow: arm extra_configs: - CONFIG_ARM_MPU=n From b3f950c64858c384a677f6b4d59229e2c1cb3496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 5 Oct 2023 14:51:26 +0700 Subject: [PATCH 3474/4498] drivers: mdio: nxp_s32_netc: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles --- drivers/mdio/mdio_nxp_s32_netc.c | 51 +++++++++++++++++++------------- soc/arm/nxp_s32/s32ze/soc.h | 3 ++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/mdio/mdio_nxp_s32_netc.c b/drivers/mdio/mdio_nxp_s32_netc.c index c8ce0e731b3..ff8a561d974 100644 --- a/drivers/mdio/mdio_nxp_s32_netc.c +++ b/drivers/mdio/mdio_nxp_s32_netc.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_netc_emdio + #include #include #include @@ -12,11 +14,9 @@ LOG_MODULE_REGISTER(nxp_s32_emdio, CONFIG_MDIO_LOG_LEVEL); #include -#define MDIO_NODE DT_NODELABEL(emdio) -#define NETC_SWT_IDX 0 - struct nxp_s32_mdio_config { const struct pinctrl_dev_config *pincfg; + uint8_t instance; }; struct nxp_s32_mdio_data { @@ -26,11 +26,12 @@ struct nxp_s32_mdio_data { static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *regval) { + const struct nxp_s32_mdio_config *cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; k_mutex_lock(&data->rw_mutex, K_FOREVER); - status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); + status = Netc_EthSwt_Ip_ReadTrcvRegister(cfg->instance, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); return status == E_OK ? 0 : -EIO; @@ -39,11 +40,12 @@ static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t regval) { + const struct nxp_s32_mdio_config *cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; k_mutex_lock(&data->rw_mutex, K_FOREVER); - status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); + status = Netc_EthSwt_Ip_WriteTrcvRegister(cfg->instance, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); return status == E_OK ? 0 : -EIO; @@ -78,19 +80,26 @@ static const struct mdio_driver_api nxp_s32_mdio_api = { .bus_disable = nxp_s32_mdio_noop, }; -PINCTRL_DT_DEFINE(MDIO_NODE); - -static struct nxp_s32_mdio_data nxp_s32_mdio0_data; - -static const struct nxp_s32_mdio_config nxp_s32_mdio0_cfg = { - .pincfg = PINCTRL_DT_DEV_CONFIG_GET(MDIO_NODE), -}; - -DEVICE_DT_DEFINE(MDIO_NODE, - &nxp_s32_mdio_initialize, - NULL, - &nxp_s32_mdio0_data, - &nxp_s32_mdio0_cfg, - POST_KERNEL, - CONFIG_MDIO_INIT_PRIORITY, - &nxp_s32_mdio_api); +#define NXP_S32_MDIO_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_NETC_EMDIO_##n##_BASE) ? i : 0) + +#define NXP_S32_MDIO_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET NETC_F1_INSTANCE_COUNT, NXP_S32_MDIO_HW_INSTANCE_CHECK, (|), n) + +#define NXP_S32_MDIO_INSTANCE_DEFINE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct nxp_s32_mdio_data nxp_s32_mdio##n##_data; \ + static const struct nxp_s32_mdio_config nxp_s32_mdio##n##_cfg = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .instance = NXP_S32_MDIO_HW_INSTANCE(n), \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + &nxp_s32_mdio_initialize, \ + NULL, \ + &nxp_s32_mdio##n##_data, \ + &nxp_s32_mdio##n##_cfg, \ + POST_KERNEL, \ + CONFIG_MDIO_INIT_PRIORITY, \ + &nxp_s32_mdio_api); + +DT_INST_FOREACH_STATUS_OKAY(NXP_S32_MDIO_INSTANCE_DEFINE) diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index a6a7ca51ced..17289511f7d 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -48,4 +48,7 @@ #define IP_STM_11_BASE IP_SMU__STM_0_BASE #define IP_STM_12_BASE IP_SMU__STM_2_BASE +/* NETC */ +#define IP_NETC_EMDIO_0_BASE IP_NETC__EMDIO_BASE_BASE + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From 250ff71c64f8067bd81cd21c22016e107a71e304 Mon Sep 17 00:00:00 2001 From: Marcus Penate Date: Thu, 9 Nov 2023 15:17:15 -0500 Subject: [PATCH 3475/4498] zbus: Fix parameter order of net buf pool fixed define Fixed order of pool-size and data-size parameters in use of `NET_BUF_POOL_FIXED_DEFINE()` Signed-off-by: Marcus Penate --- subsys/zbus/zbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/zbus/zbus.c b/subsys/zbus/zbus.c index 4ea2d986a3f..b1178b1fea7 100644 --- a/subsys/zbus/zbus.c +++ b/subsys/zbus/zbus.c @@ -29,8 +29,8 @@ static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, si #else NET_BUF_POOL_FIXED_DEFINE(_zbus_msg_subscribers_pool, - (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE), (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE), + (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE), sizeof(struct zbus_channel *), NULL); static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, size_t size, From 61c392c5b13fbc448ca0e4c047848c72c3096a07 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 10 Nov 2023 10:23:34 +0100 Subject: [PATCH 3476/4498] net: iface: Introduce TX mutex locking A recent iface lock removal in ed17320c3d2e43c76b09dc359d3b371e9d23732d exposed issues with concurrent access on TX to drivers that are not re-entrant. Reverting that commit does not really solve the problem, as it would still exist if multiple Traffic Class queues are in use. Therefore, introduce a separate mutex for TX data path, protecting the L2/driver from concurrent transfers from several threads. Signed-off-by: Robert Lubos --- include/zephyr/net/net_if.h | 29 +++++++++++++++++++++++++++++ subsys/net/ip/net_if.c | 3 +++ subsys/net/l2/ethernet/arp.c | 2 ++ 3 files changed, 34 insertions(+) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 79fc2c79b31..ab056d05e15 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -212,6 +212,9 @@ enum net_if_flag { /** IPv6 Multicast Listener Discovery disabled. */ NET_IF_IPV6_NO_MLD, + /** Mutex locking on TX data path disabled on the interface. */ + NET_IF_NO_TX_LOCK, + /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ NET_IF_NUM_FLAGS @@ -613,6 +616,7 @@ struct net_if { #endif struct k_mutex lock; + struct k_mutex tx_lock; }; static inline void net_if_lock(struct net_if *iface) @@ -629,6 +633,31 @@ static inline void net_if_unlock(struct net_if *iface) k_mutex_unlock(&iface->lock); } +static inline bool net_if_flag_is_set(struct net_if *iface, + enum net_if_flag value); + +static inline void net_if_tx_lock(struct net_if *iface) +{ + NET_ASSERT(iface); + + if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) { + return; + } + + (void)k_mutex_lock(&iface->tx_lock, K_FOREVER); +} + +static inline void net_if_tx_unlock(struct net_if *iface) +{ + NET_ASSERT(iface); + + if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) { + return; + } + + k_mutex_unlock(&iface->tx_lock); +} + /** * @brief Set a value in network interface flags * diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 099618b8476..dbf20af3cc0 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -254,7 +254,9 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) } } + net_if_tx_lock(iface); status = net_if_l2(iface)->send(iface, pkt); + net_if_tx_unlock(iface); if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) { uint32_t end_tick = k_cycle_get_32(); @@ -426,6 +428,7 @@ static inline void init_iface(struct net_if *iface) #endif k_mutex_init(&iface->lock); + k_mutex_init(&iface->tx_lock); api->init(iface); } diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 35a2ec63a64..39a06ed64a0 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -534,7 +534,9 @@ static void arp_update(struct net_if *iface, * the pkt are not counted twice and the packet filter * callbacks are only called once. */ + net_if_tx_lock(iface); ret = net_if_l2(iface)->send(iface, pkt); + net_if_tx_unlock(iface); if (ret < 0) { net_pkt_unref(pkt); } From 592292c182d5d0d978d22c55e48071e9f6aec958 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Fri, 10 Nov 2023 12:27:42 +0200 Subject: [PATCH 3477/4498] drivers: sensor: adxl367: use explicit conditions Make the adxl367 compliant with the Zephyr code guidelines by using explicit conditions. Signed-off-by: Antoniu Miclaus --- drivers/sensor/adxl367/adxl367.c | 102 +++++++++++++-------------- drivers/sensor/adxl367/adxl367_i2c.c | 4 +- drivers/sensor/adxl367/adxl367_spi.c | 6 +- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c index 2979b945b62..020ee476b2b 100644 --- a/drivers/sensor/adxl367/adxl367.c +++ b/drivers/sensor/adxl367/adxl367.c @@ -46,13 +46,13 @@ static int adxl367_setup_activity_detection(const struct device *dev, FIELD_PREP(ADXL367_ACT_INACT_CTL_ACT_EN_MSK, th->enable) | FIELD_PREP(ADXL367_ACT_INACT_CTL_ACT_REF_MSK, th->referenced)); - if (ret) { + if (ret != 0) { return ret; } ret = data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_ACT_H, ADXL367_THRESH_H_MSK, FIELD_PREP(ADXL367_THRESH_H_MSK, th->value >> 6)); - if (ret) { + if (ret != 0) { return ret; } @@ -84,13 +84,13 @@ static int adxl367_setup_inactivity_detection(const struct device *dev, th->enable) | FIELD_PREP(ADXL367_ACT_INACT_CTL_INACT_REF_MSK, th->referenced)); - if (ret) { + if (ret != 0) { return ret; } ret = data->hw_tf->write_reg_mask(dev, ADXL367_THRESH_INACT_H, ADXL367_THRESH_H_MSK, FIELD_PREP(ADXL367_THRESH_H_MSK, th->value >> 6)); - if (ret) { + if (ret != 0) { return ret; } @@ -117,7 +117,7 @@ static int adxl367_set_op_mode(const struct device *dev, ret = data->hw_tf->write_reg_mask(dev, ADXL367_POWER_CTL, ADXL367_POWER_CTL_MEASURE_MSK, FIELD_PREP(ADXL367_POWER_CTL_MEASURE_MSK, op_mode)); - if (ret) { + if (ret != 0) { return ret; } @@ -259,7 +259,7 @@ static int adxl367_set_inactivity_time(const struct device *dev, struct adxl367_data *data = dev->data; ret = data->hw_tf->write_reg(dev, ADXL367_TIME_INACT_H, time >> 8); - if (ret) { + if (ret != 0) { return ret; } @@ -281,13 +281,13 @@ int adxl367_self_test(const struct device *dev) uint8_t read_val[2]; ret = adxl367_set_op_mode(dev, ADXL367_MEASURE); - if (ret) { + if (ret != 0) { return ret; } ret = data->hw_tf->write_reg_mask(dev, ADXL367_SELF_TEST, ADXL367_SELF_TEST_ST_MSK, FIELD_PREP(ADXL367_SELF_TEST_ST_MSK, 1)); - if (ret) { + if (ret != 0) { return ret; } @@ -295,21 +295,21 @@ int adxl367_self_test(const struct device *dev) k_sleep(K_MSEC(40)); ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); - if (ret) { + if (ret != 0) { return ret; } x_axis_1 = ((int16_t)read_val[0] << 6) + (read_val[1] >> 2); /* extend sign to 16 bits */ - if (x_axis_1 & BIT(13)) { + if ((x_axis_1 & BIT(13)) != 0) { x_axis_1 |= GENMASK(15, 14); } ret = data->hw_tf->write_reg_mask(dev, ADXL367_SELF_TEST, ADXL367_SELF_TEST_ST_FORCE_MSK, FIELD_PREP(ADXL367_SELF_TEST_ST_FORCE_MSK, 1)); - if (ret) { + if (ret != 0) { return ret; } @@ -317,18 +317,18 @@ int adxl367_self_test(const struct device *dev) k_sleep(K_MSEC(40)); ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); - if (ret) { + if (ret != 0) { return ret; } x_axis_2 = ((int16_t)read_val[0] << 6) + (read_val[1] >> 2); /* extend sign to 16 bits */ - if (x_axis_2 & BIT(13)) + if ((x_axis_2 & BIT(13)) != 0) x_axis_2 |= GENMASK(15, 14); ret = adxl367_set_op_mode(dev, ADXL367_STANDBY); - if (ret) { + if (ret != 0) { return ret; } @@ -336,7 +336,7 @@ int adxl367_self_test(const struct device *dev) ADXL367_SELF_TEST_ST_MSK, FIELD_PREP(ADXL367_SELF_TEST_ST_FORCE_MSK, 0) | FIELD_PREP(ADXL367_SELF_TEST_ST_MSK, 0)); - if (ret) { + if (ret != 0) { return ret; } @@ -395,7 +395,7 @@ int adxl367_set_fifo_sample_sets_nb(const struct device *dev, ADXL367_FIFO_CONTROL_FIFO_SAMPLES_MSK, FIELD_PREP(ADXL367_FIFO_CONTROL_FIFO_SAMPLES_MSK, fifo_samples_msb)); - if (ret) { + if (ret != 0) { return ret; } @@ -478,7 +478,7 @@ int adxl367_set_fifo_format(const struct device *dev, ADXL367_FIFO_CONTROL, ADXL367_FIFO_CONTROL_FIFO_CHANNEL_MSK, FIELD_PREP(ADXL367_FIFO_CONTROL_FIFO_CHANNEL_MSK, format)); - if (ret) { + if (ret != 0) { return ret; } @@ -551,17 +551,17 @@ int adxl367_fifo_setup(const struct device *dev, int ret; ret = adxl367_set_fifo_mode(dev, mode); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_fifo_format(dev, format); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_fifo_sample_sets_nb(dev, sets_nb); - if (ret) { + if (ret != 0) { return ret; } @@ -581,13 +581,13 @@ static int adxl367_reset(const struct device *dev) struct adxl367_data *data = dev->data; ret = adxl367_set_op_mode(dev, ADXL367_STANDBY); - if (ret) { + if (ret != 0) { return ret; } /* Writing code 0x52 resets the device */ ret = data->hw_tf->write_reg(dev, ADXL367_SOFT_RESET, ADXL367_RESET_CODE); - if (ret) { + if (ret != 0) { return ret; } @@ -614,19 +614,19 @@ int adxl367_get_accel_data(const struct device *dev, uint8_t reg_data, nready = 1U; struct adxl367_data *data = dev->data; - while (nready) { + while (nready != 0) { ret = data->hw_tf->read_reg(dev, ADXL367_STATUS, ®_data); - if (ret) { + if (ret != 0) { return ret; } - if (reg_data & ADXL367_STATUS_DATA_RDY) { + if ((reg_data & ADXL367_STATUS_DATA_RDY) != 0) { nready = 0U; } } ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, xyz_values, 6); - if (ret) { + if (ret != 0) { return ret; } @@ -636,15 +636,15 @@ int adxl367_get_accel_data(const struct device *dev, accel_data->z = ((int16_t)xyz_values[4] << 6) + (xyz_values[5] >> 2); /* extend sign to 16 bits */ - if (accel_data->x & BIT(13)) { + if ((accel_data->x & BIT(13)) != 0) { accel_data->x |= GENMASK(15, 14); } - if (accel_data->y & BIT(13)) { + if ((accel_data->y & BIT(13)) != 0) { accel_data->y |= GENMASK(15, 14); } - if (accel_data->z & BIT(13)) { + if ((accel_data->z & BIT(13)) != 0) { accel_data->z |= GENMASK(15, 14); } @@ -667,25 +667,25 @@ int adxl367_get_temp_data(const struct device *dev, int16_t *raw_temp) uint8_t reg_data, nready = 1U; struct adxl367_data *data = dev->data; - while (nready) { + while (nready != 0) { ret = data->hw_tf->read_reg(dev, ADXL367_STATUS, ®_data); - if (ret) { + if (ret != 0) { return ret; } - if (reg_data & ADXL367_STATUS_DATA_RDY) { + if ((reg_data & ADXL367_STATUS_DATA_RDY) != 0) { nready = 0U; } } ret = data->hw_tf->read_reg_multiple(dev, ADXL367_TEMP_H, temp, 2); - if (ret) { + if (ret != 0) { return ret; } *raw_temp = ((int16_t)temp[0] << 6) + (temp[1] >> 2); /* extend sign to 16 bits */ - if (*raw_temp & BIT(13)) { + if ((*raw_temp & BIT(13)) != 0) { *raw_temp |= GENMASK(15, 14); } @@ -785,7 +785,7 @@ static int adxl367_sample_fetch(const struct device *dev, int ret; ret = adxl367_get_accel_data(dev, &data->sample); - if (ret) { + if (ret != 0) { return ret; } @@ -859,16 +859,16 @@ static int adxl367_probe(const struct device *dev) int ret; ret = adxl367_reset(dev); - if (ret) { + if (ret != 0) { return ret; } ret = data->hw_tf->read_reg(dev, ADXL367_DEVID, &dev_id); - if (ret) { + if (ret != 0) { return ret; } ret = data->hw_tf->read_reg(dev, ADXL367_PART_ID, &part_id); - if (ret) { + if (ret != 0) { return ret; } @@ -886,47 +886,47 @@ static int adxl367_probe(const struct device *dev) #endif ret = adxl367_self_test(dev); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_temp_read_en(dev, cfg->temp_en); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_autosleep(dev, cfg->autosleep); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_low_noise(dev, cfg->low_noise); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_setup_activity_detection(dev, &cfg->activity_th); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_setup_inactivity_detection(dev, &cfg->inactivity_th); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_activity_time(dev, cfg->activity_time); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_inactivity_time(dev, cfg->inactivity_time); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_output_rate(dev, cfg->odr); - if (ret) { + if (ret != 0) { return ret; } @@ -934,7 +934,7 @@ static int adxl367_probe(const struct device *dev) cfg->fifo_config.fifo_format, cfg->fifo_config.fifo_read_mode, cfg->fifo_config.fifo_samples); - if (ret) { + if (ret != 0) { return ret; } @@ -947,12 +947,12 @@ if (IS_ENABLED(CONFIG_ADXL367_TRIGGER)) { } ret = adxl367_set_op_mode(dev, cfg->op_mode); - if (ret) { + if (ret != 0) { return ret; } ret = adxl367_set_range(dev, data->range); - if (ret) { + if (ret != 0) { return ret; } @@ -965,7 +965,7 @@ static int adxl367_init(const struct device *dev) const struct adxl367_dev_config *cfg = dev->config; ret = cfg->bus_init(dev); - if (ret) { + if (ret != 0) { LOG_ERR("Failed to initialize sensor bus\n"); return ret; } diff --git a/drivers/sensor/adxl367/adxl367_i2c.c b/drivers/sensor/adxl367/adxl367_i2c.c index 2c7d168c224..762334ad8da 100644 --- a/drivers/sensor/adxl367/adxl367_i2c.c +++ b/drivers/sensor/adxl367/adxl367_i2c.c @@ -23,7 +23,7 @@ static int adxl367_bus_access(const struct device *dev, uint8_t reg, { const struct adxl367_dev_config *config = dev->config; - if (reg & ADXL367_READ) { + if ((reg & ADXL367_READ) != 0) { return i2c_burst_read_dt(&config->i2c, ADXL367_TO_REG(reg), (uint8_t *) data, length); @@ -70,7 +70,7 @@ int adxl367_i2c_reg_write_mask(const struct device *dev, uint8_t tmp; ret = adxl367_i2c_reg_read(dev, reg_addr, &tmp); - if (ret) { + if (ret != 0) { return ret; } diff --git a/drivers/sensor/adxl367/adxl367_spi.c b/drivers/sensor/adxl367/adxl367_spi.c index 174fcf0bf0a..a5b9c633b68 100644 --- a/drivers/sensor/adxl367/adxl367_spi.c +++ b/drivers/sensor/adxl367/adxl367_spi.c @@ -24,7 +24,7 @@ static int adxl367_bus_access(const struct device *dev, uint8_t reg, const struct adxl367_dev_config *config = dev->config; uint8_t rw_reg, addr_reg; - if (reg & ADXL367_READ) { + if ((reg & ADXL367_READ) != 0) { rw_reg = ADXL367_SPI_READ_REG; } else { rw_reg = ADXL367_SPI_WRITE_REG; @@ -49,7 +49,7 @@ static int adxl367_bus_access(const struct device *dev, uint8_t reg, .buffers = buf, }; - if (reg & ADXL367_READ) { + if ((reg & ADXL367_READ) != 0) { const struct spi_buf_set rx = { .buffers = buf, .count = 3 @@ -97,7 +97,7 @@ int adxl367_spi_reg_write_mask(const struct device *dev, uint8_t tmp; ret = adxl367_spi_reg_read(dev, reg_addr, &tmp); - if (ret) { + if (ret != 0) { return ret; } From cbf9680f962041e1bedd335603ef5810fcecf793 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 10 Nov 2023 12:21:55 +0100 Subject: [PATCH 3478/4498] net: lib: coap: Add coap_find_observer Add a function to the public CoAP API to find and return the unique observer based on the address and token. Signed-off-by: Pieter De Gendt --- include/zephyr/net/coap.h | 24 ++++++++++++++++++++++++ subsys/net/lib/coap/coap.c | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index ef9eb660ff4..a907d1311e1 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -934,6 +934,24 @@ bool coap_register_observer(struct coap_resource *resource, bool coap_remove_observer(struct coap_resource *resource, struct coap_observer *observer); +/** + * @brief Returns the observer that matches address @a addr + * and has token @a token. + * + * @param observers Pointer to the array of observers + * @param len Size of the array of observers + * @param addr Address of the endpoint observing a resource + * @param token Pointer to the token + * @param token_len Length of valid bytes in the token + * + * @return A pointer to a observer if a match is found, NULL + * otherwise. + */ +struct coap_observer *coap_find_observer( + struct coap_observer *observers, size_t len, + const struct sockaddr *addr, + const uint8_t *token, uint8_t token_len); + /** * @brief Returns the observer that matches address @a addr. * @@ -941,6 +959,9 @@ bool coap_remove_observer(struct coap_resource *resource, * @param len Size of the array of observers * @param addr Address of the endpoint observing a resource * + * @note The function coap_find_observer() should be preferred + * if both the observer's address and token are known. + * * @return A pointer to a observer if a match is found, NULL * otherwise. */ @@ -956,6 +977,9 @@ struct coap_observer *coap_find_observer_by_addr( * @param token Pointer to the token * @param token_len Length of valid bytes in the token * + * @note The function coap_find_observer() should be preferred + * if both the observer's address and token are known. + * * @return A pointer to a observer if a match is found, NULL * otherwise. */ diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 9747e33fc56..3ecc077aa64 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1913,6 +1913,28 @@ static bool sockaddr_equal(const struct sockaddr *a, return false; } +struct coap_observer *coap_find_observer( + struct coap_observer *observers, size_t len, + const struct sockaddr *addr, + const uint8_t *token, uint8_t token_len) +{ + if (token_len == 0U || token_len > COAP_TOKEN_MAX_LEN) { + return NULL; + } + + for (size_t i = 0; i < len; i++) { + struct coap_observer *o = &observers[i]; + + if (o->tkl == token_len && + memcmp(o->token, token, token_len) == 0 && + sockaddr_equal(&o->addr, addr)) { + return o; + } + } + + return NULL; +} + struct coap_observer *coap_find_observer_by_addr( struct coap_observer *observers, size_t len, const struct sockaddr *addr) From 655c72c52e1d16f4414bd84513074ddeeb4378e8 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 10 Nov 2023 12:23:51 +0100 Subject: [PATCH 3479/4498] net: lib: coap: coap_server: Allow clients to refresh observe requests A CoAP client can re-issue an observe request (same endpoint and token) to refresh it's subscription. No new observer should be registered in this case. Signed-off-by: Pieter De Gendt --- subsys/net/lib/coap/coap_server.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/coap/coap_server.c b/subsys/net/lib/coap/coap_server.c index fbcbe1721b2..4b4f1719f46 100644 --- a/subsys/net/lib/coap/coap_server.c +++ b/subsys/net/lib/coap/coap_server.c @@ -91,8 +91,11 @@ static int coap_service_remove_observer(const struct coap_service *service, { struct coap_observer *obs; - /* Prefer token to find the observer */ - if (tkl > 0 && token != NULL) { + if (tkl > 0 && addr != NULL) { + /* Prefer addr+token to find the observer */ + obs = coap_find_observer(service->data->observers, MAX_OBSERVERS, addr, token, tkl); + } else if (tkl > 0) { + /* Then try to to find the observer by token */ obs = coap_find_observer_by_token(service->data->observers, MAX_OBSERVERS, token, tkl); } else if (addr != NULL) { @@ -550,6 +553,8 @@ int coap_resource_parse_observe(struct coap_resource *resource, const struct coa { const struct coap_service *service = NULL; int ret; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; if (!coap_packet_is_request(request)) { return -EINVAL; @@ -572,11 +577,25 @@ int coap_resource_parse_observe(struct coap_resource *resource, const struct coa return -ENOENT; } + tkl = coap_header_get_token(request, token); + if (tkl == 0) { + return -EINVAL; + } + (void)k_mutex_lock(&lock, K_FOREVER); if (ret == 0) { struct coap_observer *observer; + /* RFC7641 section 4.1 - Check if the current observer already exists */ + observer = coap_find_observer(service->data->observers, MAX_OBSERVERS, addr, token, + tkl); + if (observer != NULL) { + /* Client refresh */ + goto unlock; + } + + /* New client */ observer = coap_observer_next_unused(service->data->observers, MAX_OBSERVERS); if (observer == NULL) { ret = -ENOMEM; @@ -586,10 +605,6 @@ int coap_resource_parse_observe(struct coap_resource *resource, const struct coa coap_observer_init(observer, request, addr); coap_register_observer(resource, observer); } else if (ret == 1) { - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t tkl; - - tkl = coap_header_get_token(request, token); ret = coap_service_remove_observer(service, resource, addr, token, tkl); if (ret < 0) { LOG_WRN("Failed to remove observer (%d)", ret); From f9e0a3dbd025e8ca3c47b333af75d2d05d6d5494 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:07:10 +0100 Subject: [PATCH 3480/4498] doc: pytest: Correct native device type name The native device type name is "native", "native posix" is just one of the possible target boards (which is going to be deprecated in the next release). Signed-off-by: Alberto Escolar Piedras --- doc/develop/test/pytest.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 087c45bcce8..e644882191e 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -67,7 +67,7 @@ Give access to a DeviceAdapter type object, that represents Device Under Test. This fixture is the core of pytest harness plugin. It is required to launch DUT (initialize logging, flash device, connect serial etc). This fixture yields a device prepared according to the requested type -(native posix, qemu, hardware, etc.). All types of devices share the same API. +(``native``, ``qemu``, ``hardware``, etc.). All types of devices share the same API. This allows for writing tests which are device-type-agnostic. Scope of this fixture is determined by the ``pytest_dut_scope`` keyword placed under ``harness_config`` section. From 64e1d0c3be487f2d6765050d8056bf9fdfd2afaa Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 10 Nov 2023 14:50:41 +0100 Subject: [PATCH 3481/4498] bluetooth: mesh: Don't write to const value `bt_mesh_default_key` is declared as const and thus located in flash. `bt_mesh_cdb_subnet_key_export` tries to copy to that address which results in a Bus Fault. Use separate array for storing net_key. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/shell/shell.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index 6ee825d4c09..c1bad5d24ad 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -944,7 +944,7 @@ static int cmd_provision_adv(const struct shell *sh, size_t argc, static int cmd_provision_local(const struct shell *sh, size_t argc, char *argv[]) { - uint8_t *net_key = (uint8_t *)bt_mesh_shell_default_key; + uint8_t net_key[16]; uint16_t net_idx, addr; uint32_t iv_index; int err = 0; @@ -963,6 +963,8 @@ static int cmd_provision_local(const struct shell *sh, size_t argc, char *argv[] return err; } + memcpy(net_key, bt_mesh_shell_default_key, sizeof(net_key)); + if (IS_ENABLED(CONFIG_BT_MESH_CDB)) { struct bt_mesh_cdb_subnet *sub; From 171cecb1d6b3fcf765d5d793f6a6d0ee4432715f Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 10 Nov 2023 11:10:27 -0500 Subject: [PATCH 3482/4498] riscv: FPU trap: test case comment typo fix Test case comment typo fix. Signed-off-by: Nicolas Pitre --- tests/arch/riscv/fpu_sharing/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/arch/riscv/fpu_sharing/src/main.c b/tests/arch/riscv/fpu_sharing/src/main.c index 1884adde313..55ab1a2e4a0 100644 --- a/tests/arch/riscv/fpu_sharing/src/main.c +++ b/tests/arch/riscv/fpu_sharing/src/main.c @@ -425,7 +425,7 @@ ZTEST(riscv_fpu_sharing, test_fp_insn_trap) TEST_TRAP("fcvt.w.s %0, fa0"); zassert_true(reg == 12812820, "got %ld instead", reg); - /* NMSUB major opcode space */ + /* MSUB major opcode space */ reg = 1234; TEST_TRAP("fcvt.s.w fa1, %0"); TEST_TRAP("fmsub.s fa0, fa1, fa1, fa0"); From 498888d764d4bec3ad92c72555e4cd2071e53bb7 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Fri, 10 Nov 2023 15:18:36 +0100 Subject: [PATCH 3483/4498] samples: sockets: echo_client: assume connected without connmgr When connection manager (CONFIG_NET_CONNECTION_MANAGER) is disabled, application starts right away. Scenario that it covers is when static networking is used, like with emulators (QEMU, Native Sim, ...). Since 'connected' flag was not set in such scenario, the internal loop inside start_client() has ended up early and stop_udp_and_tcp() was called quickly after starting TCP and UDP clients. Set 'connected = true', when connection manager is disabled, so that it is assumed that connection is working for the whole duration of the echo-client sample. Signed-off-by: Marcin Niestroj --- samples/net/sockets/echo_client/src/echo-client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/sockets/echo_client/src/echo-client.c b/samples/net/sockets/echo_client/src/echo-client.c index c78b14952e6..3e4aff0f2d0 100644 --- a/samples/net/sockets/echo_client/src/echo-client.c +++ b/samples/net/sockets/echo_client/src/echo-client.c @@ -320,6 +320,7 @@ int main(void) * app only after we have a connection, then we can start * it right away. */ + connected = true; k_sem_give(&run_app); } From c30c9b97b46a86db5ea2d5d8c5c87ba565a10037 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Fri, 10 Nov 2023 15:26:09 +0100 Subject: [PATCH 3484/4498] drivers: eth: cmake: narrow scope of 'native_posix_source_files' 'native_posix_source_files' is used only when CONFIG_NATIVE_APPLICATION=y, but it was set unconditionally regardless of this Kconfig option. Set 'native_posix_source_files' under CONFIG_NATIVE_APPLICATION=y to narrow scope of this variable. Signed-off-by: Marcin Niestroj --- drivers/ethernet/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index 1ae6ef58e82..8c8795509fd 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -46,12 +46,12 @@ zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_GMAC eth_nxp_s32_gmac.c) zephyr_library_sources_ifdef(CONFIG_ETH_NUMAKER eth_numaker.c) if(CONFIG_ETH_NATIVE_POSIX) - set(native_posix_source_files eth_native_posix.c eth_native_posix_adapt.c) - set_source_files_properties(${native_posix_source_files} - PROPERTIES COMPILE_DEFINITIONS - "NO_POSIX_CHEATS;_BSD_SOURCE;_DEFAULT_SOURCE" - ) if (CONFIG_NATIVE_APPLICATION) + set(native_posix_source_files eth_native_posix.c eth_native_posix_adapt.c) + set_source_files_properties(${native_posix_source_files} + PROPERTIES COMPILE_DEFINITIONS + "NO_POSIX_CHEATS;_BSD_SOURCE;_DEFAULT_SOURCE" + ) zephyr_library_sources(${native_posix_source_files}) else() zephyr_library_sources(eth_native_posix.c) From 31200fb33d38631614d4aaa383ce7d10f2d14f85 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 11 Nov 2023 14:52:21 +1000 Subject: [PATCH 3485/4498] scripts: twister: config_parser: copy common values Create copys of the common configuration values when constructing test scenarios, to avoid mutating the common value with test specific appends. Signed-off-by: Jordan Yates --- scripts/pylib/twister/twisterlib/config_parser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index f431e2d57c2..53732876247 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -3,6 +3,7 @@ # Copyright (c) 2018-2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +import copy import scl import warnings from typing import Union @@ -176,7 +177,8 @@ def get_scenario(self, name): {"CONF_FILE", "OVERLAY_CONFIG", "DTC_OVERLAY_FILE"}, v ) else: - d[k] = v + # Copy common value to avoid mutating it with test specific values below + d[k] = copy.copy(v) for k, v in self.scenarios[name].items(): if k == "extra_args": From 8b7c8b09ecc083bdff676e1bf1a29a0c255c6389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Sat, 11 Nov 2023 11:02:43 +0100 Subject: [PATCH 3486/4498] lorawan: rename lorawan_set_battery_level_callback and make it void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the lorawan_set_battery_level_callback to lorawan_register_battery_level_callback to make it consistent with other functions for downlink and data rate changed callbacks. Also making the function void for consistency. The get_battery_level already checks if the callback is NULL before invoking it. Signed-off-by: Martin Jäger --- doc/releases/migration-guide-3.6.rst | 8 ++++++++ include/zephyr/lorawan/lorawan.h | 4 +--- subsys/lorawan/lorawan.c | 8 +------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 42a485d633e..6afd6969452 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -73,6 +73,14 @@ Bluetooth been renamed, from ``samples/bluetooth/hci_rpmsg`` to ``samples/bluetooth/hci_ipc``. +LoRaWAN +======= + +* The API to register a callback to provide battery level information to the LoRaWAN stack has been + renamed from ``lorawan_set_battery_level_callback`` to + :c:func:`lorawan_register_battery_level_callback` and the return type is now ``void``. This + is more consistent with similar functions for downlink and data rate changed callbacks. + Networking ========== diff --git a/include/zephyr/lorawan/lorawan.h b/include/zephyr/lorawan/lorawan.h index 519e6e4bea1..5ce84f6f727 100644 --- a/include/zephyr/lorawan/lorawan.h +++ b/include/zephyr/lorawan/lorawan.h @@ -187,10 +187,8 @@ struct lorawan_downlink_cb { * Should no callback be provided the lorawan backend will report 255. * * @param battery_lvl_cb Pointer to the battery level function - * - * @return 0 if successful, negative errno code if failure */ -int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void)); +void lorawan_register_battery_level_callback(uint8_t (*battery_lvl_cb)(void)); /** * @brief Register a callback to be run on downlink packets diff --git a/subsys/lorawan/lorawan.c b/subsys/lorawan/lorawan.c index d73691cfde8..b325ffc87d8 100644 --- a/subsys/lorawan/lorawan.c +++ b/subsys/lorawan/lorawan.c @@ -621,15 +621,9 @@ int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, return ret; } -int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void)) +void lorawan_register_battery_level_callback(uint8_t (*battery_lvl_cb)(void)) { - if (battery_lvl_cb == NULL) { - return -EINVAL; - } - get_battery_level_user = battery_lvl_cb; - - return 0; } void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb) From c72b9f5048b0c4d523a40043248ef089d5b9363f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Sat, 11 Nov 2023 11:09:46 +0100 Subject: [PATCH 3487/4498] lorawan: use callback function signature typedefs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids duplication of the function signature in several places and makes the API documentation more clean. Signed-off-by: Martin Jäger --- include/zephyr/lorawan/lorawan.h | 35 ++++++++++++++++++++------------ subsys/lorawan/lorawan.c | 24 +++++++++++----------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/include/zephyr/lorawan/lorawan.h b/include/zephyr/lorawan/lorawan.h index 5ce84f6f727..2e07e99d694 100644 --- a/include/zephyr/lorawan/lorawan.h +++ b/include/zephyr/lorawan/lorawan.h @@ -175,20 +175,32 @@ struct lorawan_downlink_cb { }; /** - * @brief Add battery level callback function. + * @brief Defines the battery level callback handler function signature. + * + * @retval 0 if the node is connected to an external power source + * @retval 1..254 battery level, where 1 is the minimum and 254 is the maximum value + * @retval 255 if the node was not able to measure the battery level + */ +typedef uint8_t (*lorawan_battery_level_cb_t)(void); + +/** + * @brief Defines the datarate changed callback handler function signature. + * + * @param dr Updated datarate. + */ +typedef void (*lorawan_dr_changed_cb_t)(enum lorawan_datarate dr); + +/** + * @brief Register a battery level callback function. * * Provide the LoRaWAN stack with a function to be called whenever a battery - * level needs to be read. As per LoRaWAN specification the callback needs to - * return "0: node is connected to an external power source, - * 1..254: battery level, where 1 is the minimum and 254 is the maximum - * value, - * 255: the node was not able to measure the battery level" + * level needs to be read. * * Should no callback be provided the lorawan backend will report 255. * - * @param battery_lvl_cb Pointer to the battery level function + * @param cb Pointer to the battery level function */ -void lorawan_register_battery_level_callback(uint8_t (*battery_lvl_cb)(void)); +void lorawan_register_battery_level_callback(lorawan_battery_level_cb_t cb); /** * @brief Register a callback to be run on downlink packets @@ -203,12 +215,9 @@ void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb); * The callback is called once upon successfully joining a network and again * each time the datarate changes due to ADR. * - * The callback function takes one parameter: - * - dr - updated datarate - * - * @param dr_cb Pointer to datarate update callback + * @param cb Pointer to datarate update callback */ -void lorawan_register_dr_changed_callback(void (*dr_cb)(enum lorawan_datarate)); +void lorawan_register_dr_changed_callback(lorawan_dr_changed_cb_t cb); /** * @brief Join the LoRaWAN network diff --git a/subsys/lorawan/lorawan.c b/subsys/lorawan/lorawan.c index b325ffc87d8..56731dfc454 100644 --- a/subsys/lorawan/lorawan.c +++ b/subsys/lorawan/lorawan.c @@ -72,8 +72,8 @@ static LoRaMacEventInfoStatus_t last_mlme_indication_status; static LoRaMacRegion_t selected_region = DEFAULT_LORAWAN_REGION; -static uint8_t (*get_battery_level_user)(void); -static void (*dr_change_cb)(enum lorawan_datarate dr); +static lorawan_battery_level_cb_t battery_level_cb; +static lorawan_dr_changed_cb_t dr_changed_cb; /* implementation required by the soft-se (software secure element) */ void BoardGetUniqueId(uint8_t *id) @@ -83,11 +83,11 @@ void BoardGetUniqueId(uint8_t *id) static uint8_t get_battery_level(void) { - if (get_battery_level_user != NULL) { - return get_battery_level_user(); + if (battery_level_cb != NULL) { + return battery_level_cb(); + } else { + return 255; } - - return 255; } static void mac_process_notify(void) @@ -105,8 +105,8 @@ static void datarate_observe(bool force_notification) if ((mib_req.Param.ChannelsDatarate != current_datarate) || (force_notification)) { current_datarate = mib_req.Param.ChannelsDatarate; - if (dr_change_cb) { - dr_change_cb(current_datarate); + if (dr_changed_cb != NULL) { + dr_changed_cb(current_datarate); } LOG_INF("Datarate changed: DR_%d", current_datarate); } @@ -621,9 +621,9 @@ int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, return ret; } -void lorawan_register_battery_level_callback(uint8_t (*battery_lvl_cb)(void)) +void lorawan_register_battery_level_callback(lorawan_battery_level_cb_t cb) { - get_battery_level_user = battery_lvl_cb; + battery_level_cb = cb; } void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb) @@ -631,9 +631,9 @@ void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb) sys_slist_append(&dl_callbacks, &cb->node); } -void lorawan_register_dr_changed_callback(void (*cb)(enum lorawan_datarate)) +void lorawan_register_dr_changed_callback(lorawan_dr_changed_cb_t cb) { - dr_change_cb = cb; + dr_changed_cb = cb; } int lorawan_start(void) From 679d82c48411973a477da05d4e77fca875902e73 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Sat, 11 Nov 2023 09:35:49 +1300 Subject: [PATCH 3488/4498] libc: Add GCC fno-builtin-malloc flag to common stdlib compilation This prevents the compiler from optimizing calloc into an infinite recursive call. For example a call to malloc + memset zero at GCC -O2 will be replaced by a call to calloc. This causes infinite recursion if the function being implemented *is* calloc. fno-builtin-malloc forces the compiler to avoid this optimization. Signed-off-by: Grant Ramsay --- lib/libc/common/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index 48372158ea5..3aa869379d5 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -6,3 +6,6 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ABORT source/stdlib/abort.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) + +# Prevent compiler from optimizing calloc into an infinite recursive call +zephyr_library_cc_option(-fno-builtin-malloc) From a3ff19a39eb18bc10ae38698f5c91ad50c5748d7 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Mon, 13 Nov 2023 09:34:50 +1300 Subject: [PATCH 3489/4498] cmake: compiler: Add compiler property for no-builtin Abstracts these flags for multiple toolchain support Signed-off-by: Grant Ramsay --- arch/posix/CMakeLists.txt | 4 ++-- cmake/compiler/arcmwdt/compiler_flags.cmake | 3 +++ cmake/compiler/compiler_flags_template.cmake | 4 ++++ cmake/compiler/gcc/compiler_flags.cmake | 3 +++ lib/libc/common/CMakeLists.txt | 2 +- lib/libc/minimal/CMakeLists.txt | 2 +- modules/openthread/CMakeLists.txt | 6 ++++-- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index 86cf051ccde..1573ef82ea1 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -94,12 +94,12 @@ elseif (CONFIG_NATIVE_LIBRARY) # Do not use the C library from this compiler/host, # but still use the basic compiler headers - # -fno-builtin to avoid the compiler using builtin replacements for std library functions + # no_builtin to avoid the compiler using builtin replacements for std library functions zephyr_compile_options( -nostdinc -isystem ${COMPILER_OWN_INCLUDE_PATH} $ - -fno-builtin + $ ) endif() endif() diff --git a/cmake/compiler/arcmwdt/compiler_flags.cmake b/cmake/compiler/arcmwdt/compiler_flags.cmake index 8eeaf2fa37a..7ab83ba507d 100644 --- a/cmake/compiler/arcmwdt/compiler_flags.cmake +++ b/cmake/compiler/arcmwdt/compiler_flags.cmake @@ -206,3 +206,6 @@ endif() # Remove after testing that -Wshadow works set_compiler_property(PROPERTY warning_shadow_variables) + +set_compiler_property(PROPERTY no_builtin -fno-builtin) +set_compiler_property(PROPERTY no_builtin_malloc -fno-builtin-malloc) diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index 1476c45e851..53e37287b9f 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -133,3 +133,7 @@ set_compiler_property(PROPERTY no_global_merge) # Compiler flag for warning about shadow variables set_compiler_property(PROPERTY warning_shadow_variables) + +# Compiler flags to avoid recognizing built-in functions +set_compiler_property(PROPERTY no_builtin) +set_compiler_property(PROPERTY no_builtin_malloc) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index b77dfa4123f..5b1dbde49c6 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -227,3 +227,6 @@ set_compiler_property(PROPERTY no_position_independent set_compiler_property(PROPERTY no_global_merge "") set_compiler_property(PROPERTY warning_shadow_variables -Wshadow) + +set_compiler_property(PROPERTY no_builtin -fno-builtin) +set_compiler_property(PROPERTY no_builtin_malloc -fno-builtin-malloc) diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index 3aa869379d5..04897751186 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -8,4 +8,4 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) # Prevent compiler from optimizing calloc into an infinite recursive call -zephyr_library_cc_option(-fno-builtin-malloc) +zephyr_library_compile_options($) diff --git a/lib/libc/minimal/CMakeLists.txt b/lib/libc/minimal/CMakeLists.txt index 71a404e7870..abcab108e52 100644 --- a/lib/libc/minimal/CMakeLists.txt +++ b/lib/libc/minimal/CMakeLists.txt @@ -7,7 +7,7 @@ zephyr_library() set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) set(STRERROR_TABLE_H ${GEN_DIR}/libc/minimal/strerror_table.h) -zephyr_library_cc_option(-fno-builtin) +zephyr_library_compile_options($) zephyr_library_sources( source/stdlib/atoi.c diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index bad6d131771..2b2b593f82f 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -547,7 +547,8 @@ target_compile_definitions(ot-config INTERFACE # libraries do not include this header. So we add the defines to all # OpenThread files through the gcc flag -imacros instead. target_compile_options(ot-config INTERFACE - $ -fno-builtin + $ + $ -imacros ${AUTOCONF_H} ) @@ -600,7 +601,8 @@ endif() if(CONFIG_OPENTHREAD_SETTINGS_RAM) target_compile_options(openthread-platform-utils PRIVATE - $ -fno-builtin) + $ + $) add_dependencies(openthread-platform-utils syscall_list_h_target) list(APPEND ot_libs openthread-platform-utils-static) From 28df44946f09c02c5b967927710bebafa28f6a6a Mon Sep 17 00:00:00 2001 From: Dominik Kilian Date: Thu, 9 Nov 2023 11:41:07 +0100 Subject: [PATCH 3490/4498] ipc: add dynamically allocated buffers to icmsg The icmsg and icmsg_me backends has limitations in context of concurrent access to single instance. Some limitations are: * sending by more thread at the same time may cause -EBUSY * allocating TX buffer will cause errors in other threads that want to allocate before first thread sent the message, * during no-copy receive, when RX buffer is on hold receiving is totally blocked. This backend resolves those limitations by adding dynamically allocated buffers on shared memory next to ICmsg circular buffer. The data is passed using those buffers, so concurrency is not a problem. The ICmsg is used only to pass short 2-byte messages containing references to those buffers. The backend also supports multiple endpoint. The ipc/icmsg_me sample was modified to support this backend. Signed-off-by: Dominik Kilian --- .../backends/ipc_service_icbmsg.rst | 83 ++ doc/services/ipc/ipc_service/ipc_service.rst | 1 + dts/bindings/ipc/zephyr,ipc-icbmsg.yaml | 22 + include/zephyr/ipc/pbuf.h | 10 + .../ipc/ipc_service/backends/CMakeLists.txt | 1 + subsys/ipc/ipc_service/backends/Kconfig | 1 + .../ipc/ipc_service/backends/Kconfig.icbmsg | 31 + subsys/ipc/ipc_service/backends/ipc_icbmsg.c | 1303 +++++++++++++++++ 8 files changed, 1452 insertions(+) create mode 100644 doc/services/ipc/ipc_service/backends/ipc_service_icbmsg.rst create mode 100644 dts/bindings/ipc/zephyr,ipc-icbmsg.yaml create mode 100644 subsys/ipc/ipc_service/backends/Kconfig.icbmsg create mode 100644 subsys/ipc/ipc_service/backends/ipc_icbmsg.c diff --git a/doc/services/ipc/ipc_service/backends/ipc_service_icbmsg.rst b/doc/services/ipc/ipc_service/backends/ipc_service_icbmsg.rst new file mode 100644 index 00000000000..26b9006ae81 --- /dev/null +++ b/doc/services/ipc/ipc_service/backends/ipc_service_icbmsg.rst @@ -0,0 +1,83 @@ +.. _ipc_service_backend_icbmsg: + +ICMsg with dynamically allocated buffers backend +################################################ + +This backend is built on top of the :ref:`ipc_service_backend_icmsg`. +Data transferred over this backend travels in dynamically allocated buffers on shared memory. +The ICMsg just sends references to the buffers. +It also supports multiple endpoints. + +This architecture allows for overcoming some common problems with other backends (mostly related to multithread access and zero-copy). +This backend provides an alternative with no significant limitations. + +Overview +======== + +The shared memory is divided into two parts. +One is reserved for the ICMsg and the other contains equal-sized blocks. +The number of blocks is configured in the devicetree. + +The data sending process is following: + +* The sender allocates one or more blocks. + If there are not enough sequential blocks, it waits using the timeout provided in the parameter that also includes K_FOREVER and K_NO_WAIT. +* The allocated blocks are filled with data. + For the zero-copy case, this is done by the caller, otherwise, it is copied automatically. + During this time other threads are not blocked in any way as long as there are enough free blocks for them. + They can allocate, send data and receive data. +* A message containing the block index is sent over ICMsg to the receiver. + The size of the ICMsg queue is large enough to hold messages for all blocks, so it will never overflow. +* The receiver can hold the data as long as desired. + Again, other threads are not blocked as long as there are enough free blocks for them. +* When data is no longer needed, the backend sends a release message over ICMsg. +* When the backend receives this message, it deallocates all blocks. + It is done internally by the backend and it is invisible to the caller. + +Configuration +============= + +The backend is configured using Kconfig and devicetree. +When configuring the backend, do the following: + +* Define two memory regions and assign them to ``tx-region`` and ``rx-region`` of an instance. + Ensure that the memory regions used for data exchange are unique (not overlapping any other region) and accessible by both domains (or CPUs). +* Define the number of allocable blocks for each region with ``tx-blocks`` and ``rx-blocks``. +* Define MBOX devices for sending a signal that informs the other domain (or CPU) of the written data. + Ensure that the other domain (or CPU) can receive the signal. + +See the following configuration example for one of the instances: + +.. code-block:: devicetree + + reserved-memory { + tx: memory@20070000 { + reg = <0x20070000 0x0800>; + }; + + rx: memory@20078000 { + reg = <0x20078000 0x0800>; + }; + }; + + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&tx>; + rx-region = <&rx>; + tx-blocks = <16>; + rx-blocks = <32>; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "tx", "rx"; + status = "okay"; + }; + }; + + +You must provide a similar configuration for the other side of the communication (domain or CPU). +Swap the MBOX channels, memory regions (``tx-region`` and ``rx-region``), and block count (``tx-blocks`` and ``rx-blocks``). + +Samples +======= + +* :ref:`ipc_multi_endpoint_sample` diff --git a/doc/services/ipc/ipc_service/ipc_service.rst b/doc/services/ipc/ipc_service/ipc_service.rst index 35cdfbf1dde..286ded75801 100644 --- a/doc/services/ipc/ipc_service/ipc_service.rst +++ b/doc/services/ipc/ipc_service/ipc_service.rst @@ -185,6 +185,7 @@ backend. :maxdepth: 1 backends/ipc_service_icmsg.rst + backends/ipc_service_icbmsg.rst API Reference ************* diff --git a/dts/bindings/ipc/zephyr,ipc-icbmsg.yaml b/dts/bindings/ipc/zephyr,ipc-icbmsg.yaml new file mode 100644 index 00000000000..0fc6be01a49 --- /dev/null +++ b/dts/bindings/ipc/zephyr,ipc-icbmsg.yaml @@ -0,0 +1,22 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Inter-core messaging backend with dynamically allocated buffers + +compatible: "zephyr,ipc-icbmsg" + +include: zephyr,ipc-icmsg.yaml + +properties: + tx-blocks: + description: number of allocable TX blocks + required: true + type: int + + rx-blocks: + description: number of allocable RX blocks + required: true + type: int diff --git a/include/zephyr/ipc/pbuf.h b/include/zephyr/ipc/pbuf.h index f8eff0b1ad1..5f953522d3b 100644 --- a/include/zephyr/ipc/pbuf.h +++ b/include/zephyr/ipc/pbuf.h @@ -116,6 +116,16 @@ struct pbuf { .dcache_alignment = (dcache_align), \ } +/** + * @brief Macro calculates memory overhead taken by the header in shared memory. + * + * It contains the read index, write index and padding. + * + * @param dcache_align Data cache alignment. + */ +#define PBUF_HEADER_OVERHEAD(dcache_align) \ + (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE) + /** * @brief Statically define and initialize pbuf. * diff --git a/subsys/ipc/ipc_service/backends/CMakeLists.txt b/subsys/ipc/ipc_service/backends/CMakeLists.txt index 0f5629a14c5..d6ca8fb76c3 100644 --- a/subsys/ipc/ipc_service/backends/CMakeLists.txt +++ b/subsys/ipc/ipc_service/backends/CMakeLists.txt @@ -3,4 +3,5 @@ zephyr_sources_ifdef(CONFIG_IPC_SERVICE_BACKEND_ICMSG ipc_icmsg.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_INITIATOR ipc_icmsg_me_initiator.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_FOLLOWER ipc_icmsg_me_follower.c) +zephyr_sources_ifdef(CONFIG_IPC_SERVICE_BACKEND_ICBMSG ipc_icbmsg.c) zephyr_sources_ifdef(CONFIG_IPC_SERVICE_BACKEND_RPMSG ipc_rpmsg_static_vrings.c) diff --git a/subsys/ipc/ipc_service/backends/Kconfig b/subsys/ipc/ipc_service/backends/Kconfig index 61d113aac3f..8230465e246 100644 --- a/subsys/ipc/ipc_service/backends/Kconfig +++ b/subsys/ipc/ipc_service/backends/Kconfig @@ -49,4 +49,5 @@ config IPC_SERVICE_BACKEND_ICMSG_ME_FOLLOWER role. rsource "Kconfig.icmsg_me" +rsource "Kconfig.icbmsg" rsource "Kconfig.rpmsg" diff --git a/subsys/ipc/ipc_service/backends/Kconfig.icbmsg b/subsys/ipc/ipc_service/backends/Kconfig.icbmsg new file mode 100644 index 00000000000..e31b5cadd77 --- /dev/null +++ b/subsys/ipc/ipc_service/backends/Kconfig.icbmsg @@ -0,0 +1,31 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menuconfig IPC_SERVICE_BACKEND_ICBMSG + bool "ICMSG backend with dynamically allocated buffers" + default y + depends on MBOX + depends on DT_HAS_ZEPHYR_IPC_ICBMSG_ENABLED + select IPC_SERVICE_ICMSG + help + Choosing this backend results in multi endpoint implementation based + on dynamically allocated buffers. References to them are send over + ICMsg circular buffer. + +if IPC_SERVICE_BACKEND_ICBMSG + +config IPC_SERVICE_BACKEND_ICBMSG_NUM_EP + int "Endpoints count" + range 1 254 + default 4 + help + Number of endpoints supported by the ICBMsg IPC service + backend. The number of endpoints are applied to all the instances, + so this value should be maximum number among all the instances. + +module = IPC_SERVICE_BACKEND_ICBMSG +module-str = ICMSG backend with separate buffers +module-help = Sets log level for ICMsg backend with buffers +source "subsys/logging/Kconfig.template.log_config" + +endif # IPC_SERVICE_BACKEND_ICBMSG diff --git a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c new file mode 100644 index 00000000000..cb4d91d7e8a --- /dev/null +++ b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c @@ -0,0 +1,1303 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * ICBMsg backend. + * + * This is an IPC service backend that dynamically allocates buffers for data storage + * and uses ICMsg to send references to them. + * + * Shared memory organization + * -------------------------- + * + * Single channel (RX or TX) of the shared memory is divided into two areas: ICMsg area + * followed by Blocks area. ICMsg is used to send and receive short 3-byte messages. + * Blocks area is evenly divided into aligned blocks. Blocks are used to allocate + * buffers containing actual data. Data buffers can span multiple blocks. The first block + * starts with the size of the following data. + * + * +------------+-------------+ + * | ICMsg area | Blocks area | + * +------------+-------------+ + * _______/ \_________________________________________ + * / \ + * +-----------+-----------+-----------+-----------+- -+-----------+ + * | Block 0 | Block 1 | Block 2 | Block 3 | ... | Block N-1 | + * +-----------+-----------+-----------+-----------+- -+-----------+ + * _____/ \_____ + * / \ + * +------+--------------------------------+---------+ + * | size | data_buffer[size] ... | padding | + * +------+--------------------------------+---------+ + * + * The sender holds information about reserved blocks using bitarray and it is responsible + * for allocating and releasing the blocks. The receiver just tells the sender that it + * does not need a specific buffer anymore. + * + * Control messages + * ---------------- + * + * ICMsg is used to send and receive small 3-byte control messages. + * + * - Send data + * | MSG_DATA | endpoint address | block index | + * This message is used to send data buffer to specific endpoint. + * + * - Release data + * | MSG_RELEASE_DATA | 0 | block index | + * This message is a response to the "Send data" message and it is used to inform that + * specific buffer is not used anymore and can be released. Endpoint addresses does + * not matter here, so it is zero. + * + * - Bound endpoint + * | MSG_BOUND | endpoint address | block index | + * This message starts the bounding of the endpoint. The buffer contains a + * null-terminated endpoint name. + * + * - Release bound endpoint + * | MSG_RELEASE_BOUND | endpoint address | block index | + * This message is a response to the "Bound endpoint" message and it is used to inform + * that a specific buffer (starting at "block index") is not used anymore and + * a the endpoint is bounded and can now receive a data. + * + * Bounding endpoints + * ------------------ + * + * When ICMsg is bounded and user registers an endpoint on initiator side, the backend + * sends "Bound endpoint". Endpoint address is assigned by the initiator. When follower + * gets the message and user on follower side also registered the same endpoint, + * the backend calls "bound" callback and sends back "Release bound endpoint". + * The follower saves the endpoint address. The follower's endpoint is ready to send + * and receive data. When the initiator gets "Release bound endpoint" message or any + * data messages, it calls bound endpoint and it is ready to send data. + */ + +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ipc_icbmsg, + CONFIG_IPC_SERVICE_BACKEND_ICBMSG_LOG_LEVEL); + +#define DT_DRV_COMPAT zephyr_ipc_icbmsg + +/** Allowed number of endpoints. */ +#define NUM_EPT CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP + +/** Special endpoint address indicating invalid (or empty) entry. */ +#define EPT_ADDR_INVALID 0xFF + +/** Special value for empty entry in bound message waiting table. */ +#define WAITING_BOUND_MSG_EMPTY 0xFFFF + +/** Size of the header (size field) of the block. */ +#define BLOCK_HEADER_SIZE (sizeof(struct block_header)) + +/** Flag indicating that ICMsg was bounded for this instance. */ +#define CONTROL_BOUNDED BIT(31) + +/** Registered endpoints count mask in flags. */ +#define FLAG_EPT_COUNT_MASK 0xFFFF + +enum msg_type { + MSG_DATA = 0, /* Data message. */ + MSG_RELEASE_DATA, /* Release data buffer message. */ + MSG_BOUND, /* Endpoint bounding message. */ + MSG_RELEASE_BOUND, /* Release endpoint bound message. + * This message is also indicator for the receiving side + * that the endpoint bounding was fully processed on + * the sender side. + */ +}; + +enum ept_bounding_state { + EPT_UNCONFIGURED = 0, /* Endpoint in not configured (initial state). */ + EPT_CONFIGURED, /* Endpoint is configured, waiting for work queue to + * start bounding process. + */ + EPT_BOUNDING, /* Only on initiator. Bound message was send, + * but bound callback was not called yet, because + * we are waiting for any incoming messages. + */ + EPT_READY, /* Bounding is done. Bound callback was called. */ +}; + +struct channel_config { + uint8_t *blocks_ptr; /* Address where the blocks start. */ + size_t block_size; /* Size of one block. */ + size_t block_count; /* Number of blocks. */ +}; + +struct icbmsg_config { + struct icmsg_config_t control_config; /* Configuration of the ICMsg. */ + struct channel_config rx; /* RX channel config. */ + struct channel_config tx; /* TX channel config. */ + sys_bitarray_t *tx_usage_bitmap; /* Bit is set when TX block is in use */ + sys_bitarray_t *rx_hold_bitmap; /* Bit is set, if the buffer starting at + * this block should be kept after exit + * from receive handler. + */ +}; + +struct ept_data { + const struct ipc_ept_cfg *cfg; /* Endpoint configuration. */ + atomic_t state; /* Bounding state. */ + uint8_t addr; /* Endpoint address. */ +}; + +struct backend_data { + const struct icbmsg_config *conf;/* Backend instance config. */ + struct icmsg_data_t control_data;/* ICMsg data. */ + struct k_mutex mutex; /* Mutex to protect: ICMsg send call and + * waiting_bound field. + */ + struct k_work ep_bound_work; /* Work item for bounding processing. */ + struct k_sem block_wait_sem; /* Semaphore for waiting for free blocks. */ + struct ept_data ept[NUM_EPT]; /* Array of registered endpoints. */ + uint8_t ept_map[NUM_EPT]; /* Array that maps endpoint address to index. */ + uint16_t waiting_bound[NUM_EPT];/* The bound messages waiting to be registered. */ + atomic_t flags; /* Flags on higher bits, number of registered + * endpoints on lower. + */ + bool is_initiator; /* This side has an initiator role. */ +}; + +struct block_header { + volatile size_t size; /* Size of the data field. It must be volatile, because + * when this value is read and validated for security + * reasons, compiler cannot generate code that reads + * it again after validation. + */ +}; + +struct block_content { + struct block_header header; + uint8_t data[]; /* Buffer data. */ +}; + +struct control_message { + uint8_t msg_type; /* Message type. */ + uint8_t ept_addr; /* Endpoint address or zero for MSG_RELEASE_DATA. */ + uint8_t block_index; /* Block index to send or release. */ +}; + +BUILD_ASSERT(NUM_EPT <= EPT_ADDR_INVALID, "Too many endpoints"); + +/** + * Calculate pointer to block from its index and channel configuration (RX or TX). + * No validation is performed. + */ +static struct block_content *block_from_index(const struct channel_config *ch_conf, + size_t block_index) +{ + return (struct block_content *)(ch_conf->blocks_ptr + + block_index * ch_conf->block_size); +} + +/** + * Calculate pointer to data buffer from block index and channel configuration (RX or TX). + * Also validate the index and optionally the buffer size allocated on the this block. + * + * @param[in] ch_conf The channel + * @param[in] block_index Block index + * @param[out] size Size of the buffer allocated on the block if not NULL. + * The size is also checked if it fits in the blocks area. + * If it is NULL, no size validation is performed. + * @param[in] invalidate_cache If size is not NULL, invalidates cache for entire buffer + * (all blocks). Otherwise, it is ignored. + * @return Pointer to data buffer or NULL if validation failed. + */ +static uint8_t *buffer_from_index_validate(const struct channel_config *ch_conf, + size_t block_index, size_t *size, + bool invalidate_cache) +{ + size_t allocable_size; + size_t buffer_size; + uint8_t *end_ptr; + struct block_content *block; + + if (block_index >= ch_conf->block_count) { + LOG_ERR("Block index invalid"); + return NULL; + } + + block = block_from_index(ch_conf, block_index); + + if (size != NULL) { + if (invalidate_cache) { + sys_cache_data_invd_range(block, BLOCK_HEADER_SIZE); + __sync_synchronize(); + } + allocable_size = ch_conf->block_count * ch_conf->block_size; + end_ptr = ch_conf->blocks_ptr + allocable_size; + buffer_size = block->header.size; + + if ((buffer_size > allocable_size - BLOCK_HEADER_SIZE) || + (&block->data[buffer_size] > end_ptr)) { + LOG_ERR("Block corrupted"); + return NULL; + } + + *size = buffer_size; + if (invalidate_cache) { + sys_cache_data_invd_range(block->data, buffer_size); + __sync_synchronize(); + } + } + + return block->data; +} + +/** + * Calculate block index based on data buffer pointer and validate it. + * + * @param[in] ch_conf The channel + * @param[in] buffer Pointer to data buffer + * @param[out] size Size of the allocated buffer if not NULL. + * The size is also checked if it fits in the blocks area. + * If it is NULL, no size validation is performed. + * @return Block index or negative error code + * @retval -EINVAL The buffer is not correct + */ +static int buffer_to_index_validate(const struct channel_config *ch_conf, + const uint8_t *buffer, size_t *size) +{ + size_t block_index; + uint8_t *expected; + + block_index = (buffer - ch_conf->blocks_ptr) / ch_conf->block_size; + + expected = buffer_from_index_validate(ch_conf, block_index, size, false); + + if (expected == NULL || expected != buffer) { + LOG_ERR("Pointer invalid"); + return -EINVAL; + } + + return block_index; +} + +/** + * Allocate buffer for transmission + * + * @param[in,out] size Required size of the buffer. If zero, first available block is + * allocated and all subsequent available blocks. Size actually + * allocated which is not less than requested. + * @param[out] buffer Allocated buffer data. + * @param[in] timeout Timeout. + * + * @return Positive index of the first allocated block or negative error. + * @retval -EINVAL If requested size is bigger than entire allocable space. + * @retval -ENOSPC If timeout was K_NO_WAIT and there was not enough space. + * @retval -EAGAIN If timeout occurred. + */ +static int alloc_tx_buffer(struct backend_data *dev_data, uint32_t *size, + uint8_t **buffer, k_timeout_t timeout) +{ + const struct icbmsg_config *conf = dev_data->conf; + size_t total_size = *size + BLOCK_HEADER_SIZE; + size_t num_blocks = DIV_ROUND_UP(total_size, conf->tx.block_size); + struct block_content *block; + bool sem_taken = false; + size_t tx_block_index; + size_t next_bit; + int prev_bit_val; + int r; + + do { + /* Try to allocate specified number of blocks. */ + r = sys_bitarray_alloc(conf->tx_usage_bitmap, num_blocks, + &tx_block_index); + if (r == -ENOSPC && !K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + /* Wait for releasing if there is no enough space and exit loop + * on timeout. + */ + r = k_sem_take(&dev_data->block_wait_sem, timeout); + if (r < 0) { + break; + } + sem_taken = true; + } else { + /* Exit loop if space was allocated or other error occurred. */ + break; + } + } while (true); + + /* If semaphore was taken, give it back because this thread does not + * necessary took all available space, so other thread may need it. + */ + if (sem_taken) { + k_sem_give(&dev_data->block_wait_sem); + } + + if (r < 0) { + if (r != -ENOSPC && r != -EAGAIN) { + LOG_ERR("Failed to allocate buffer, err: %d", r); + /* Only -EINVAL is allowed in this place. Any other code + * indicates something wrong with the logic. + */ + __ASSERT_NO_MSG(r == -EINVAL); + } + + if (r == -ENOSPC || r == -EINVAL) { + /* IPC service require -ENOMEM error in case of no memory. */ + r = -ENOMEM; + } + return r; + } + + /* If size is 0 try to allocate more blocks after already allocated. */ + if (*size == 0) { + prev_bit_val = 0; + for (next_bit = tx_block_index + 1; next_bit < conf->tx.block_count; + next_bit++) { + r = sys_bitarray_test_and_set_bit(conf->tx_usage_bitmap, next_bit, + &prev_bit_val); + /** Setting bit should always success. */ + __ASSERT_NO_MSG(r == 0); + if (prev_bit_val) { + break; + } + } + num_blocks = next_bit - tx_block_index; + } + + /* Get block pointer and adjust size to actually allocated space. */ + *size = conf->tx.block_size * num_blocks - BLOCK_HEADER_SIZE; + block = block_from_index(&conf->tx, tx_block_index); + block->header.size = *size; + *buffer = block->data; + return tx_block_index; +} + +/** + * Release all or part of the blocks occupied by the buffer. + * + * @param[in] tx_block_index First block index to release, no validation is performed, + * so caller is responsible for passing valid index. + * @param[in] size Size of data buffer, no validation is performed, + * so caller is responsible for passing valid size. + * @param[in] new_size If less than zero, release all blocks, otherwise reduce + * size to this value and update size in block header. + * + * @returns Positive block index where the buffer starts or negative error. + * @retval -EINVAL If invalid buffer was provided or size is greater than already + * allocated size. + */ +static int release_tx_blocks(struct backend_data *dev_data, size_t tx_block_index, + size_t size, int new_size) +{ + const struct icbmsg_config *conf = dev_data->conf; + struct block_content *block; + size_t num_blocks; + size_t total_size; + size_t new_total_size; + size_t new_num_blocks; + size_t release_index; + int r; + + /* Calculate number of blocks. */ + total_size = size + BLOCK_HEADER_SIZE; + num_blocks = DIV_ROUND_UP(total_size, conf->tx.block_size); + + if (new_size >= 0) { + /* Calculate and validate new values. */ + new_total_size = new_size + BLOCK_HEADER_SIZE; + new_num_blocks = DIV_ROUND_UP(new_total_size, conf->tx.block_size); + if (new_num_blocks > num_blocks) { + LOG_ERR("Requested %d blocks, allocated %d", new_num_blocks, + num_blocks); + return -EINVAL; + } + /* Update actual buffer size and number of blocks to release. */ + block = block_from_index(&conf->tx, tx_block_index); + block->header.size = new_size; + release_index = tx_block_index + new_num_blocks; + num_blocks = num_blocks - new_num_blocks; + } else { + /* If size is negative, release all blocks. */ + release_index = tx_block_index; + } + + if (num_blocks > 0) { + /* Free bits in the bitmap. */ + r = sys_bitarray_free(conf->tx_usage_bitmap, num_blocks, + release_index); + if (r < 0) { + LOG_ERR("Cannot free bits, err %d", r); + return r; + } + + /* Wake up all waiting threads. */ + k_sem_give(&dev_data->block_wait_sem); + } + + return tx_block_index; +} + +/** + * Release all or part of the blocks occupied by the buffer. + * + * @param[in] buffer Buffer to release. + * @param[in] new_size If less than zero, release all blocks, otherwise reduce size to + * this value and update size in block header. + * + * @returns Positive block index where the buffer starts or negative error. + * @retval -EINVAL If invalid buffer was provided or size is greater than already + * allocated size. + */ +static int release_tx_buffer(struct backend_data *dev_data, const uint8_t *buffer, + int new_size) +{ + const struct icbmsg_config *conf = dev_data->conf; + size_t size; + int tx_block_index; + + tx_block_index = buffer_to_index_validate(&conf->tx, buffer, &size); + if (tx_block_index < 0) { + return tx_block_index; + } + + return release_tx_blocks(dev_data, tx_block_index, size, new_size); +} + +/** + * Send control message over ICMsg with mutex locked. Mutex must be locked because + * ICMsg may return error on concurrent invocations even when there is enough space + * in queue. + */ +static int send_control_message(struct backend_data *dev_data, enum msg_type msg_type, + uint8_t ept_addr, uint8_t block_index) +{ + const struct icbmsg_config *conf = dev_data->conf; + const struct control_message message = { + .msg_type = (uint8_t)msg_type, + .ept_addr = ept_addr, + .block_index = block_index, + }; + int r; + + k_mutex_lock(&dev_data->mutex, K_FOREVER); + r = icmsg_send(&conf->control_config, &dev_data->control_data, &message, + sizeof(message)); + k_mutex_unlock(&dev_data->mutex); + if (r < 0) { + LOG_ERR("Cannot send over ICMsg, err %d", r); + } + return r; +} + +/** + * Release received buffer. This function will just send release control message. + * + * @param[in] buffer Buffer to release. + * @param[in] msg_type Message type: MSG_RELEASE_BOUND or MSG_RELEASE_DATA. + * @param[in] ept_addr Endpoint address or zero for MSG_RELEASE_DATA. + * + * @return zero or ICMsg send error. + */ +static int send_release(struct backend_data *dev_data, const uint8_t *buffer, + enum msg_type msg_type, uint8_t ept_addr) +{ + const struct icbmsg_config *conf = dev_data->conf; + int rx_block_index; + + rx_block_index = buffer_to_index_validate(&conf->rx, buffer, NULL); + if (rx_block_index < 0) { + return rx_block_index; + } + + return send_control_message(dev_data, msg_type, ept_addr, rx_block_index); +} + +/** + * Send data contained in specified block. It will adjust data size and flush cache + * if necessary. If sending failed, allocated blocks will be released. + * + * @param[in] msg_type Message type: MSG_BOUND or MSG_DATA. + * @param[in] ept_addr Endpoints address. + * @param[in] tx_block_index Index of first block containing data, it is not validated, + * so caller is responsible for passing only valid index. + * @param[in] size Actual size of the data, can be smaller than allocated, + * but it cannot change number of required blocks. + * + * @return O or negative error code. + */ +static int send_block(struct backend_data *dev_data, enum msg_type msg_type, + uint8_t ept_addr, size_t tx_block_index, size_t size) +{ + struct block_content *block; + int r; + + block = block_from_index(&dev_data->conf->tx, tx_block_index); + + block->header.size = size; + __sync_synchronize(); + sys_cache_data_flush_range(block, size + BLOCK_HEADER_SIZE); + + r = send_control_message(dev_data, msg_type, ept_addr, tx_block_index); + if (r < 0) { + release_tx_blocks(dev_data, tx_block_index, size, -1); + } + + return r; +} + +/** + * Find endpoint that was registered with name that matches name + * contained in the endpoint bound message received from remote. + * + * @param[in] name Endpoint name, it must be in a received block. + * + * @return Found endpoint index or -ENOENT if not found. + */ +static int find_ept_by_name(struct backend_data *dev_data, const char *name) +{ + const struct channel_config *rx_conf = &dev_data->conf->rx; + const char *buffer_end = (const char *)rx_conf->blocks_ptr + + rx_conf->block_count * rx_conf->block_size; + struct ept_data *ept; + size_t name_size; + size_t i; + + /* Requested name is in shared memory, so we have to assume that it + * can be corrupted. Extra care must be taken to avoid out of + * bounds reads. + */ + name_size = strnlen(name, buffer_end - name - 1) + 1; + + for (i = 0; i < NUM_EPT; i++) { + ept = &dev_data->ept[i]; + if (atomic_get(&ept->state) == EPT_CONFIGURED && + strncmp(ept->cfg->name, name, name_size) == 0) { + return i; + } + } + + return -ENOENT; +} + +/** + * Find registered endpoint that matches given "bound endpoint" message. When found, + * the "release bound endpoint" message is send. + * + * @param[in] rx_block_index Block containing the "bound endpoint" message. + * @param[in] ept_addr Endpoint address. + * + * @return negative error code or non-negative search result. + * @retval 0 match not found. + * @retval 1 match found and processing was successful. + */ +static int match_bound_msg(struct backend_data *dev_data, size_t rx_block_index, + uint8_t ept_addr) +{ + const struct icbmsg_config *conf = dev_data->conf; + struct block_content *block; + uint8_t *buffer; + int ept_index; + struct ept_data *ept; + int r; + bool valid_state; + + /* Find endpoint that matches requested name. */ + block = block_from_index(&conf->rx, rx_block_index); + buffer = block->data; + ept_index = find_ept_by_name(dev_data, buffer); + if (ept_index < 0) { + return 0; + } + + /* Set endpoint address and mapping. Move it to "ready" state. */ + ept = &dev_data->ept[ept_index]; + ept->addr = ept_addr; + dev_data->ept_map[ept->addr] = ept_index; + valid_state = atomic_cas(&ept->state, EPT_CONFIGURED, EPT_READY); + if (!valid_state) { + LOG_ERR("Unexpected bounding from remote on endpoint %d", ept_addr); + return -EINVAL; + } + + /* Endpoint is ready to send messages, so call bound callback. */ + if (ept->cfg->cb.bound != NULL) { + ept->cfg->cb.bound(ept->cfg->priv); + } + + /* Release the bound message and inform remote that we are ready to receive. */ + r = send_release(dev_data, buffer, MSG_RELEASE_BOUND, ept_addr); + if (r < 0) { + return r; + } + + return 1; +} + +/** + * Send bound message on specified endpoint. + * + * @param[in] ept Endpoint to use. + * + * @return O or negative error code. + */ +static int send_bound_message(struct backend_data *dev_data, struct ept_data *ept) +{ + size_t msg_len; + uint32_t alloc_size; + uint8_t *buffer; + int r; + + msg_len = strlen(ept->cfg->name) + 1; + alloc_size = msg_len; + r = alloc_tx_buffer(dev_data, &alloc_size, &buffer, K_FOREVER); + if (r >= 0) { + strcpy(buffer, ept->cfg->name); + r = send_block(dev_data, MSG_BOUND, ept->addr, r, msg_len); + } + + return r; +} + +/** + * Put endpoint bound processing into system workqueue. + */ +static void schedule_ept_bound_process(struct backend_data *dev_data) +{ + k_work_submit(&dev_data->ep_bound_work); +} + +/** + * Work handler that is responsible to start bounding when ICMsg is bound. + */ +static void ept_bound_process(struct k_work *item) +{ + struct backend_data *dev_data = CONTAINER_OF(item, struct backend_data, + ep_bound_work); + struct ept_data *ept = NULL; + size_t i; + int r = 0; + bool matching_state; + + /* Skip processing if ICMsg was not bounded yet. */ + if (!(atomic_get(&dev_data->flags) & CONTROL_BOUNDED)) { + return; + } + + if (dev_data->is_initiator) { + /* Initiator just sends bound message after endpoint was registered. */ + for (i = 0; i < NUM_EPT; i++) { + ept = &dev_data->ept[i]; + matching_state = atomic_cas(&ept->state, EPT_CONFIGURED, + EPT_BOUNDING); + if (matching_state) { + r = send_bound_message(dev_data, ept); + if (r < 0) { + atomic_set(&ept->state, EPT_UNCONFIGURED); + LOG_ERR("Failed to send bound, err %d", r); + } + } + } + } else { + /* Walk over all waiting bound messages and match to local endpoints. */ + k_mutex_lock(&dev_data->mutex, K_FOREVER); + for (i = 0; i < NUM_EPT; i++) { + if (dev_data->waiting_bound[i] != WAITING_BOUND_MSG_EMPTY) { + k_mutex_unlock(&dev_data->mutex); + r = match_bound_msg(dev_data, + dev_data->waiting_bound[i], i); + k_mutex_lock(&dev_data->mutex, K_FOREVER); + if (r != 0) { + dev_data->waiting_bound[i] = + WAITING_BOUND_MSG_EMPTY; + if (r < 0) { + LOG_ERR("Failed bound, err %d", r); + } + } + } + } + k_mutex_unlock(&dev_data->mutex); + } +} + +/** + * Get endpoint from endpoint address. Also validates if the address is correct and + * endpoint is in correct state for receiving. If bounding callback was not called yet, + * then call it. + */ +static struct ept_data *get_ept_and_rx_validate(struct backend_data *dev_data, + uint8_t ept_addr) +{ + struct ept_data *ept; + enum ept_bounding_state state; + + if (ept_addr >= NUM_EPT || dev_data->ept_map[ept_addr] >= NUM_EPT) { + LOG_ERR("Received invalid endpoint addr %d", ept_addr); + return NULL; + } + + ept = &dev_data->ept[dev_data->ept_map[ept_addr]]; + + state = atomic_get(&ept->state); + + if (state == EPT_READY) { + /* Valid state - nothing to do. */ + } else if (state == EPT_BOUNDING) { + /* Endpoint bound callback was not called yet - call it. */ + atomic_set(&ept->state, EPT_READY); + if (ept->cfg->cb.bound != NULL) { + ept->cfg->cb.bound(ept->cfg->priv); + } + } else { + LOG_ERR("Invalid state %d of receiving endpoint %d", state, ept->addr); + return NULL; + } + + return ept; +} + +/** + * Data message received. + */ +static int received_data(struct backend_data *dev_data, size_t rx_block_index, + uint8_t ept_addr) +{ + const struct icbmsg_config *conf = dev_data->conf; + uint8_t *buffer; + struct ept_data *ept; + size_t size; + int bit_val; + + /* Validate. */ + buffer = buffer_from_index_validate(&conf->rx, rx_block_index, &size, true); + ept = get_ept_and_rx_validate(dev_data, ept_addr); + if (buffer == NULL || ept == NULL) { + LOG_ERR("Received invalid block index %d or addr %d", rx_block_index, + ept_addr); + return -EINVAL; + } + + /* Clear bit. If cleared, specific block will not be hold after the callback. */ + sys_bitarray_clear_bit(conf->rx_hold_bitmap, rx_block_index); + + /* Call the endpoint callback. It can set the hold bit. */ + ept->cfg->cb.received(buffer, size, ept->cfg->priv); + + /* If the bit is still cleared, request release of the buffer. */ + sys_bitarray_test_bit(conf->rx_hold_bitmap, rx_block_index, &bit_val); + if (!bit_val) { + send_release(dev_data, buffer, MSG_RELEASE_DATA, 0); + } + + return 0; +} + +/** + * Release data message received. + */ +static int received_release_data(struct backend_data *dev_data, size_t tx_block_index) +{ + const struct icbmsg_config *conf = dev_data->conf; + uint8_t *buffer; + size_t size; + int r; + + /* Validate. */ + buffer = buffer_from_index_validate(&conf->tx, tx_block_index, &size, false); + if (buffer == NULL) { + LOG_ERR("Received invalid block index %d", tx_block_index); + return -EINVAL; + } + + /* Release. */ + r = release_tx_blocks(dev_data, tx_block_index, size, -1); + if (r < 0) { + return r; + } + + return r; +} + +/** + * Bound endpoint message received. + */ +static int received_bound(struct backend_data *dev_data, size_t rx_block_index, + uint8_t ept_addr) +{ + const struct icbmsg_config *conf = dev_data->conf; + size_t size; + uint8_t *buffer; + + /* Validate */ + buffer = buffer_from_index_validate(&conf->rx, rx_block_index, &size, true); + if (buffer == NULL) { + LOG_ERR("Received invalid block index %d", rx_block_index); + return -EINVAL; + } + + /* Put message to waiting array. */ + k_mutex_lock(&dev_data->mutex, K_FOREVER); + dev_data->waiting_bound[ept_addr] = rx_block_index; + k_mutex_unlock(&dev_data->mutex); + + /* Schedule processing the message. */ + schedule_ept_bound_process(dev_data); + + return 0; +} + +/** + * Callback called by ICMsg that handles message (data or endpoint bound) received + * from the remote. + * + * @param[in] data Message received from the ICMsg. + * @param[in] len Number of bytes of data. + * @param[in] priv Opaque pointer to device instance. + */ +static void control_received(const void *data, size_t len, void *priv) +{ + const struct device *instance = priv; + struct backend_data *dev_data = instance->data; + const struct control_message *message = (const struct control_message *)data; + struct ept_data *ept; + uint8_t ept_addr; + int r = 0; + + /* Allow messages longer than 3 bytes, e.g. for future protocol versions. */ + if (len < sizeof(struct control_message)) { + r = -EINVAL; + goto exit; + } + + ept_addr = message->ept_addr; + if (ept_addr >= NUM_EPT) { + r = -EINVAL; + goto exit; + } + + switch (message->msg_type) { + case MSG_RELEASE_DATA: + r = received_release_data(dev_data, message->block_index); + break; + case MSG_RELEASE_BOUND: + r = received_release_data(dev_data, message->block_index); + if (r >= 0) { + ept = get_ept_and_rx_validate(dev_data, ept_addr); + if (ept == NULL) { + r = -EINVAL; + } + } + break; + case MSG_BOUND: + r = received_bound(dev_data, message->block_index, ept_addr); + break; + case MSG_DATA: + r = received_data(dev_data, message->block_index, ept_addr); + break; + default: + /* Silently ignore other messages types. They can be used in future + * protocol version. + */ + break; + } + +exit: + if (r < 0) { + LOG_ERR("Failed to receive, err %d", r); + } +} + +/** + * Callback called when ICMsg is bound. + */ +static void control_bound(void *priv) +{ + const struct device *instance = priv; + struct backend_data *dev_data = instance->data; + + /* Set flag that ICMsg is bounded and now, endpoint bounding may start. */ + atomic_or(&dev_data->flags, CONTROL_BOUNDED); + schedule_ept_bound_process(dev_data); +} + +/** + * Open the backend instance callback. + */ +static int open(const struct device *instance) +{ + const struct icbmsg_config *conf = instance->config; + struct backend_data *dev_data = instance->data; + + static const struct ipc_service_cb cb = { + .bound = control_bound, + .received = control_received, + .error = NULL, + }; + + LOG_DBG("Open instance 0x%08X, initiator=%d", (uint32_t)instance, + dev_data->is_initiator ? 1 : 0); + LOG_DBG(" TX %d blocks of %d bytes at 0x%08X, max allocable %d bytes", + (uint32_t)conf->tx.block_count, + (uint32_t)conf->tx.block_size, + (uint32_t)conf->tx.blocks_ptr, + (uint32_t)(conf->tx.block_size * conf->tx.block_count - + BLOCK_HEADER_SIZE)); + LOG_DBG(" RX %d blocks of %d bytes at 0x%08X, max allocable %d bytes", + (uint32_t)conf->rx.block_count, + (uint32_t)conf->rx.block_size, + (uint32_t)conf->rx.blocks_ptr, + (uint32_t)(conf->rx.block_size * conf->rx.block_count - + BLOCK_HEADER_SIZE)); + + return icmsg_open(&conf->control_config, &dev_data->control_data, &cb, + (void *)instance); +} + +/** + * Endpoint send callback function (with copy). + */ +static int send(const struct device *instance, void *token, const void *msg, size_t len) +{ + struct backend_data *dev_data = instance->data; + struct ept_data *ept = token; + uint32_t alloc_size; + uint8_t *buffer; + int r; + + /* Allocate the buffer. */ + alloc_size = len; + r = alloc_tx_buffer(dev_data, &alloc_size, &buffer, K_NO_WAIT); + if (r < 0) { + return r; + } + + /* Copy data to allocated buffer. */ + memcpy(buffer, msg, len); + + /* Send data message. */ + return send_block(dev_data, MSG_DATA, ept->addr, r, len); +} + +/** + * Backend endpoint registration callback. + */ +static int register_ept(const struct device *instance, void **token, + const struct ipc_ept_cfg *cfg) +{ + struct backend_data *dev_data = instance->data; + struct ept_data *ept = NULL; + int ept_index; + int r = 0; + + /* Reserve new endpoint index. */ + ept_index = atomic_inc(&dev_data->flags) & FLAG_EPT_COUNT_MASK; + if (ept_index >= NUM_EPT) { + LOG_ERR("Too many endpoints"); + __ASSERT_NO_MSG(false); + return -ENOMEM; + } + + /* Add new endpoint. */ + ept = &dev_data->ept[ept_index]; + ept->cfg = cfg; + if (dev_data->is_initiator) { + ept->addr = ept_index; + dev_data->ept_map[ept->addr] = ept->addr; + } + atomic_set(&ept->state, EPT_CONFIGURED); + + /* Keep endpoint address in token. */ + *token = ept; + + /* Rest of the bounding will be done in the system workqueue. */ + schedule_ept_bound_process(dev_data); + + return r; +} + +/** + * Returns maximum TX buffer size. + */ +static int get_tx_buffer_size(const struct device *instance, void *token) +{ + const struct icbmsg_config *conf = instance->config; + + return conf->tx.block_size * conf->tx.block_count - BLOCK_HEADER_SIZE; +} + +/** + * Endpoint TX buffer allocation callback for nocopy sending. + */ +static int get_tx_buffer(const struct device *instance, void *token, void **data, + uint32_t *user_len, k_timeout_t wait) +{ + struct backend_data *dev_data = instance->data; + int r; + + r = alloc_tx_buffer(dev_data, user_len, (uint8_t **)data, wait); + if (r < 0) { + return r; + } + return 0; +} + +/** + * Endpoint TX buffer release callback for nocopy sending. + */ +static int drop_tx_buffer(const struct device *instance, void *token, const void *data) +{ + struct backend_data *dev_data = instance->data; + int r; + + r = release_tx_buffer(dev_data, data, -1); + if (r < 0) { + return r; + } + + return 0; +} + +/** + * Endpoint nocopy sending. + */ +static int send_nocopy(const struct device *instance, void *token, const void *data, + size_t len) +{ + struct backend_data *dev_data = instance->data; + struct ept_data *ept = token; + int r; + + /* Actual size may be smaller than requested, so shrink if possible. */ + r = release_tx_buffer(dev_data, data, len); + if (r < 0) { + release_tx_buffer(dev_data, data, -1); + return r; + } + + return send_block(dev_data, MSG_DATA, ept->addr, r, len); +} + +/** + * Holding RX buffer for nocopy receiving. + */ +static int hold_rx_buffer(const struct device *instance, void *token, void *data) +{ + const struct icbmsg_config *conf = instance->config; + int rx_block_index; + uint8_t *buffer = data; + + /* Calculate block index and set associated bit. */ + rx_block_index = buffer_to_index_validate(&conf->rx, buffer, NULL); + __ASSERT_NO_MSG(rx_block_index >= 0); + return sys_bitarray_set_bit(conf->rx_hold_bitmap, rx_block_index); +} + +/** + * Release RX buffer that was previously held. + */ +static int release_rx_buffer(const struct device *instance, void *token, void *data) +{ + struct backend_data *dev_data = instance->data; + + return send_release(dev_data, (uint8_t *)data, MSG_RELEASE_DATA, 0); +} + +/** + * Backend device initialization. + */ +static int backend_init(const struct device *instance) +{ + const struct icbmsg_config *conf = instance->config; + struct backend_data *dev_data = instance->data; + + dev_data->conf = conf; + dev_data->is_initiator = (conf->rx.blocks_ptr < conf->tx.blocks_ptr); + k_mutex_init(&dev_data->mutex); + k_work_init(&dev_data->ep_bound_work, ept_bound_process); + k_sem_init(&dev_data->block_wait_sem, 0, 1); + memset(&dev_data->waiting_bound, 0xFF, sizeof(dev_data->waiting_bound)); + memset(&dev_data->ept_map, EPT_ADDR_INVALID, sizeof(dev_data->ept_map)); + return 0; +} + +/** + * IPC service backend callbacks. + */ +const static struct ipc_service_backend backend_ops = { + .open_instance = open, + .close_instance = NULL, /* not implemented */ + .send = send, + .register_endpoint = register_ept, + .deregister_endpoint = NULL, /* not implemented */ + .get_tx_buffer_size = get_tx_buffer_size, + .get_tx_buffer = get_tx_buffer, + .drop_tx_buffer = drop_tx_buffer, + .send_nocopy = send_nocopy, + .hold_rx_buffer = hold_rx_buffer, + .release_rx_buffer = release_rx_buffer, +}; + +/** + * Number of bytes per each ICMsg message. It is used to calculate size of ICMsg area. + */ +#define BYTES_PER_ICMSG_MESSAGE (ROUND_UP(sizeof(struct control_message), \ + sizeof(void *)) + PBUF_PACKET_LEN_SZ) + +/** + * Maximum ICMsg overhead. It is used to calculate size of ICMsg area. + */ +#define ICMSG_BUFFER_OVERHEAD(i) \ + (PBUF_HEADER_OVERHEAD(GET_CACHE_ALIGNMENT(i)) + 2 * BYTES_PER_ICMSG_MESSAGE) + +/** + * Returns required block alignment for instance "i". + */ +#define GET_CACHE_ALIGNMENT(i) \ + MAX(sizeof(uint32_t), DT_INST_PROP_OR(i, dcache_alignment, 0)) + +/** + * Calculates minimum size required for ICMsg region for specific number of local + * and remote blocks. The minimum size ensures that ICMsg queue is will never overflow + * because it can hold data message for each local block and release message + * for each remote block. + */ +#define GET_ICMSG_MIN_SIZE(i, local_blocks, remote_blocks) \ + (ICMSG_BUFFER_OVERHEAD(i) + BYTES_PER_ICMSG_MESSAGE * \ + (local_blocks + remote_blocks)) + +/** + * Calculate aligned block size by evenly dividing remaining space after removing + * the space for ICMsg. + */ +#define GET_BLOCK_SIZE(i, total_size, local_blocks, remote_blocks) ROUND_DOWN( \ + ((total_size) - GET_ICMSG_MIN_SIZE(i, (local_blocks), (remote_blocks))) / \ + (local_blocks), GET_CACHE_ALIGNMENT(i)) + +/** + * Calculate offset where area for blocks starts which is just after the ICMsg. + */ +#define GET_BLOCKS_OFFSET(i, total_size, local_blocks, remote_blocks) \ + ((total_size) - GET_BLOCK_SIZE(i, (total_size), (local_blocks), \ + (remote_blocks)) * (local_blocks)) + +/** + * Return shared memory start address aligned to block alignment and cache line. + */ +#define GET_MEM_ADDR_INST(i, direction) \ + ROUND_UP(DT_REG_ADDR(DT_INST_PHANDLE(i, direction##_region)), \ + GET_CACHE_ALIGNMENT(i)) + +/** + * Return shared memory end address aligned to block alignment and cache line. + */ +#define GET_MEM_END_INST(i, direction) \ + ROUND_DOWN(DT_REG_ADDR(DT_INST_PHANDLE(i, direction##_region)) + \ + DT_REG_SIZE(DT_INST_PHANDLE(i, direction##_region)), \ + GET_CACHE_ALIGNMENT(i)) + +/** + * Return shared memory size aligned to block alignment and cache line. + */ +#define GET_MEM_SIZE_INST(i, direction) \ + (GET_MEM_END_INST(i, direction) - GET_MEM_ADDR_INST(i, direction)) + +/** + * Returns GET_ICMSG_SIZE, but for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_ICMSG_SIZE_INST(i, loc, rem) \ + GET_BLOCKS_OFFSET( \ + i, \ + GET_MEM_SIZE_INST(i, loc), \ + DT_INST_PROP(i, loc##_blocks), \ + DT_INST_PROP(i, rem##_blocks)) + +/** + * Returns address where area for blocks starts for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_BLOCKS_ADDR_INST(i, loc, rem) \ + GET_MEM_ADDR_INST(i, loc) + \ + GET_BLOCKS_OFFSET( \ + i, \ + GET_MEM_SIZE_INST(i, loc), \ + DT_INST_PROP(i, loc##_blocks), \ + DT_INST_PROP(i, rem##_blocks)) + +/** + * Returns block size for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_BLOCK_SIZE_INST(i, loc, rem) \ + GET_BLOCK_SIZE( \ + i, \ + GET_MEM_SIZE_INST(i, loc), \ + DT_INST_PROP(i, loc##_blocks), \ + DT_INST_PROP(i, rem##_blocks)) + +#define DEFINE_BACKEND_DEVICE(i) \ + SYS_BITARRAY_DEFINE_STATIC(tx_usage_bitmap_##i, DT_INST_PROP(i, tx_blocks)); \ + SYS_BITARRAY_DEFINE_STATIC(rx_hold_bitmap_##i, DT_INST_PROP(i, rx_blocks)); \ + PBUF_DEFINE(tx_icbmsg_pb_##i, \ + GET_MEM_ADDR_INST(i, tx), \ + GET_ICMSG_SIZE_INST(i, tx, rx), \ + GET_CACHE_ALIGNMENT(i)); \ + PBUF_DEFINE(rx_icbmsg_pb_##i, \ + GET_MEM_ADDR_INST(i, rx), \ + GET_ICMSG_SIZE_INST(i, rx, tx), \ + GET_CACHE_ALIGNMENT(i)); \ + static struct backend_data backend_data_##i = { \ + .control_data = { \ + .tx_pb = &tx_icbmsg_pb_##i, \ + .rx_pb = &rx_icbmsg_pb_##i, \ + } \ + }; \ + static const struct icbmsg_config backend_config_##i = \ + { \ + .control_config = { \ + .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ + .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ + }, \ + .tx = { \ + .blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, tx, rx), \ + .block_count = DT_INST_PROP(i, tx_blocks), \ + .block_size = GET_BLOCK_SIZE_INST(i, tx, rx), \ + }, \ + .rx = { \ + .blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, rx, tx), \ + .block_count = DT_INST_PROP(i, rx_blocks), \ + .block_size = GET_BLOCK_SIZE_INST(i, rx, tx), \ + }, \ + .tx_usage_bitmap = &tx_usage_bitmap_##i, \ + .rx_hold_bitmap = &rx_hold_bitmap_##i, \ + }; \ + BUILD_ASSERT(IS_POWER_OF_TWO(GET_CACHE_ALIGNMENT(i)), \ + "This module supports only power of two cache alignment"); \ + BUILD_ASSERT((GET_BLOCK_SIZE_INST(i, tx, rx) > GET_CACHE_ALIGNMENT(i)) && \ + (GET_BLOCK_SIZE_INST(i, tx, rx) < \ + GET_MEM_SIZE_INST(i, tx)), \ + "TX region is too small for provided number of blocks"); \ + BUILD_ASSERT((GET_BLOCK_SIZE_INST(i, rx, tx) > GET_CACHE_ALIGNMENT(i)) && \ + (GET_BLOCK_SIZE_INST(i, rx, tx) < \ + GET_MEM_SIZE_INST(i, rx)), \ + "RX region is too small for provided number of blocks"); \ + BUILD_ASSERT(DT_INST_PROP(i, rx_blocks) <= 256, "Too many RX blocks"); \ + BUILD_ASSERT(DT_INST_PROP(i, tx_blocks) <= 256, "Too many TX blocks"); \ + DEVICE_DT_INST_DEFINE(i, \ + &backend_init, \ + NULL, \ + &backend_data_##i, \ + &backend_config_##i, \ + POST_KERNEL, \ + CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY, \ + &backend_ops); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE) From 23254f2a160e8e955a4545c1cd098b0085a9fac9 Mon Sep 17 00:00:00 2001 From: Dominik Kilian Date: Thu, 9 Nov 2023 12:00:34 +0100 Subject: [PATCH 3491/4498] samples: ipc: Modify icmsg_me sample allowing any multiendpoint backend There are more ipc_service backends that supports multiple endpoint. This sample can be used for any of those backends, so this commits makes the sample more generic. The default backend it still icmsg_me, but now, the sample has files and instructions for icmsg_with_buf backend. Signed-off-by: Dominik Kilian --- .../ipc/ipc_service/icmsg_me/sample.yaml | 10 --- .../CMakeLists.txt | 2 - .../Kconfig.sysbuild | 0 .../ipc/ipc_service/multi_endpoint/README.rst | 73 +++++++++++++++++++ .../boards/nrf5340dk_nrf5340_cpuapp.conf | 0 .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 0 .../nrf5340dk_nrf5340_cpuapp_icbmsg.overlay | 57 +++++++++++++++ .../{icmsg_me => multi_endpoint}/prj.conf | 1 + .../remote/CMakeLists.txt | 0 .../boards/nrf5340dk_nrf5340_cpunet.conf | 0 .../boards/nrf5340dk_nrf5340_cpunet.overlay | 0 .../nrf5340dk_nrf5340_cpunet_icbmsg.overlay | 57 +++++++++++++++ .../remote/prj.conf | 1 + .../remote/src/main.c | 0 .../ipc_service/multi_endpoint/sample.yaml | 19 +++++ .../{icmsg_me => multi_endpoint}/src/main.c | 0 .../sysbuild.cmake | 0 17 files changed, 208 insertions(+), 12 deletions(-) delete mode 100644 samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/CMakeLists.txt (93%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/Kconfig.sysbuild (100%) create mode 100644 samples/subsys/ipc/ipc_service/multi_endpoint/README.rst rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/boards/nrf5340dk_nrf5340_cpuapp.conf (100%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/boards/nrf5340dk_nrf5340_cpuapp.overlay (100%) create mode 100644 samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/prj.conf (83%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/remote/CMakeLists.txt (100%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/remote/boards/nrf5340dk_nrf5340_cpunet.conf (100%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/remote/boards/nrf5340dk_nrf5340_cpunet.overlay (100%) create mode 100644 samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/remote/prj.conf (83%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/remote/src/main.c (100%) create mode 100644 samples/subsys/ipc/ipc_service/multi_endpoint/sample.yaml rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/src/main.c (100%) rename samples/subsys/ipc/ipc_service/{icmsg_me => multi_endpoint}/sysbuild.cmake (100%) diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml deleted file mode 100644 index 2fe7f79ef40..00000000000 --- a/samples/subsys/ipc/ipc_service/icmsg_me/sample.yaml +++ /dev/null @@ -1,10 +0,0 @@ -sample: - name: IPC Service example integration (icmsg multi endpoint backend) -tests: - sample.ipc.icmsg_me: - platform_allow: nrf5340dk_nrf5340_cpuapp - integration_platforms: - - nrf5340dk_nrf5340_cpuapp - tags: ipc - sysbuild: true - harness: remote diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt b/samples/subsys/ipc/ipc_service/multi_endpoint/CMakeLists.txt similarity index 93% rename from samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt rename to samples/subsys/ipc/ipc_service/multi_endpoint/CMakeLists.txt index 18a138548cf..b342f550616 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/CMakeLists.txt @@ -15,5 +15,3 @@ endif() project(ipc_service) target_sources(app PRIVATE src/main.c) - -include(ExternalProject) diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/multi_endpoint/Kconfig.sysbuild similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/Kconfig.sysbuild rename to samples/subsys/ipc/ipc_service/multi_endpoint/Kconfig.sysbuild diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/README.rst b/samples/subsys/ipc/ipc_service/multi_endpoint/README.rst new file mode 100644 index 00000000000..faff69e007f --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/README.rst @@ -0,0 +1,73 @@ +.. _ipc_multi_endpoint_sample: + +IPC Service - Multi-endpoint Sample Application +############################################### + +This application demonstrates how to use IPC Service with multiple endpoints. +By default, it uses the ``icmsg_me`` backend. +You can also configure it to use the ``icbmsg`` backend. + +Building the application for nrf5340dk_nrf5340_cpuapp +***************************************************** + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/ipc/ipc_service/multi_endpoint + :board: nrf5340dk_nrf5340_cpuapp + :goals: debug + +Open a serial terminal (for example Minicom or PuTTY) and connect the board with the following settings: + +* Speed: 115200 +* Data: 8 bits +* Parity: None +* Stop bits: 1 + +After resetting the board, the following message will appear on the corresponding +serial port: + +.. code-block:: console + + *** Booting Zephyr OS build v3.4.0-rc1-108-gccfbac8b0721 *** + IPC-service HOST [INST 0 - ENDP A] demo started + IPC-service HOST [INST 0 - ENDP B] demo started + IPC-service HOST [INST 1] demo started + HOST [0A]: 1 + HOST [0A]: 3 + HOST [0B]: 1 + HOST [1]: 1 + ... + HOST [0A]: 99 + IPC-service HOST [INST 0 - ENDP A] demo ended. + HOST [0B]: 99 + IPC-service HOST [INST 0 - ENDP B] demo ended. + HOST [1]: 99 + IPC-service HOST [INST 1] demo ended. + +.. code-block:: console + + *** Booting Zephyr OS build v3.4.0-rc1-108-gccfbac8b0721 *** + IPC-service REMOTE [INST 0 - ENDP A] demo started + IPC-service REMOTE [INST 0 - ENDP B] demo started + IPC-service REMOTE [INST 1] demo started + REMOTE [0A]: 0 + REMOTE [0A]: 2 + ... + REMOTE [0A]: 98 + IPC-service REMOTE [INST 0 - ENDP A] demo ended. + REMOTE [0B]: 98 + IPC-service REMOTE [INST 0 - ENDP B] demo ended. + REMOTE [1]: 98 + IPC-service REMOTE [INST 1] demo ended. + + +Changing the backend +******************** + +To change the backend to ``icbmsg``, switch the devicetree +overlay files as follows: + +.. code-block:: console + + west build -b nrf5340dk_nrf5340_cpuapp --sysbuild -- \ + -DDTC_OVERLAY_FILE=boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay \ + -Dremote_DTC_OVERLAY_FILE=boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.conf similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/boards/nrf5340dk_nrf5340_cpuapp.conf rename to samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.conf diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/boards/nrf5340dk_nrf5340_cpuapp.overlay rename to samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay new file mode 100644 index 00000000000..3db9db032f4 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /delete-property/ zephyr,ipc_shm; + }; + + reserved-memory { + /delete-node/ memory@20070000; + + sram_ipc0_tx: memory@20070000 { + reg = <0x20070000 0x4000>; + }; + + sram_ipc0_rx: memory@20074000 { + reg = <0x20074000 0x4000>; + }; + + sram_ipc1_tx: memory@20078000 { + reg = <0x20078000 0x4000>; + }; + + sram_ipc1_rx: memory@2007C000 { + reg = <0x2007C000 0x4000>; + }; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_ipc0_tx>; + rx-region = <&sram_ipc0_rx>; + tx-blocks = <16>; + rx-blocks = <24>; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "tx", "rx"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_ipc1_tx>; + rx-region = <&sram_ipc1_rx>; + tx-blocks = <32>; + rx-blocks = <48>; + mboxes = <&mbox 2>, <&mbox 3>; + mbox-names = "tx", "rx"; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/prj.conf similarity index 83% rename from samples/subsys/ipc/ipc_service/icmsg_me/prj.conf rename to samples/subsys/ipc/ipc_service/multi_endpoint/prj.conf index 4c5326d1397..3d2c799c4eb 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/prj.conf +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/prj.conf @@ -1,4 +1,5 @@ CONFIG_PRINTK=y +CONFIG_LOG_PRINTK=n CONFIG_IPC_SERVICE=y CONFIG_MBOX=y diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/CMakeLists.txt b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/CMakeLists.txt similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/remote/CMakeLists.txt rename to samples/subsys/ipc/ipc_service/multi_endpoint/remote/CMakeLists.txt diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/boards/nrf5340dk_nrf5340_cpunet.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet.conf similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/remote/boards/nrf5340dk_nrf5340_cpunet.conf rename to samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet.conf diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/boards/nrf5340dk_nrf5340_cpunet.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet.overlay similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/remote/boards/nrf5340dk_nrf5340_cpunet.overlay rename to samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet.overlay diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay new file mode 100644 index 00000000000..6247ed812aa --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /delete-property/ zephyr,ipc_shm; + }; + + reserved-memory { + /delete-node/ memory@20070000; + + sram_ipc0_rx: memory@20070000 { + reg = <0x20070000 0x4000>; + }; + + sram_ipc0_tx: memory@20074000 { + reg = <0x20074000 0x4000>; + }; + + sram_ipc1_rx: memory@20078000 { + reg = <0x20078000 0x4000>; + }; + + sram_ipc1_tx: memory@2007C000 { + reg = <0x2007C000 0x4000>; + }; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_ipc0_tx>; + rx-region = <&sram_ipc0_rx>; + tx-blocks = <24>; + rx-blocks = <16>; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_ipc1_tx>; + rx-region = <&sram_ipc1_rx>; + tx-blocks = <48>; + rx-blocks = <32>; + mboxes = <&mbox 2>, <&mbox 3>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/prj.conf similarity index 83% rename from samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf rename to samples/subsys/ipc/ipc_service/multi_endpoint/remote/prj.conf index 4c5326d1397..3d2c799c4eb 100644 --- a/samples/subsys/ipc/ipc_service/icmsg_me/remote/prj.conf +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/prj.conf @@ -1,4 +1,5 @@ CONFIG_PRINTK=y +CONFIG_LOG_PRINTK=n CONFIG_IPC_SERVICE=y CONFIG_MBOX=y diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/remote/src/main.c rename to samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/sample.yaml b/samples/subsys/ipc/ipc_service/multi_endpoint/sample.yaml new file mode 100644 index 00000000000..fdb3c707d8e --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/sample.yaml @@ -0,0 +1,19 @@ +sample: + name: IPC Service example integration (icmsg multi endpoint backend) +tests: + sample.ipc.multi_endpoint: + platform_allow: nrf5340dk_nrf5340_cpuapp + integration_platforms: + - nrf5340dk_nrf5340_cpuapp + tags: ipc + sysbuild: true + harness: remote + sample.ipc.multi_endpoint.icbmsg: + platform_allow: nrf5340dk_nrf5340_cpuapp + integration_platforms: + - nrf5340dk_nrf5340_cpuapp + tags: ipc + sysbuild: true + extra_args: + DTC_OVERLAY_FILE=boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay + remote_DTC_OVERLAY_FILE=boards/nrf5340dk_nrf5340_cpunet_icbmsg.overlay diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/src/main.c rename to samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c diff --git a/samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake b/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.cmake similarity index 100% rename from samples/subsys/ipc/ipc_service/icmsg_me/sysbuild.cmake rename to samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.cmake From 8334f1d3854a9c6bd5031e1e46196da946823d83 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 13 Nov 2023 08:42:08 +0000 Subject: [PATCH 3492/4498] doc: migration-guide: 3.6: Fix spurious character Fixes a spurious tilde character at the end of a change Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-3.6.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 6afd6969452..aaad9dfea3f 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -99,7 +99,7 @@ Other Subsystems * Touchscreen drivers :dtcompatible:`focaltech,ft5336` and :dtcompatible:`goodix,gt911` were using the incorrect polarity for the respective ``reset-gpios``. This has been fixed so those signals now have to - be flagged as :c:macro:`GPIO_ACTIVE_LOW` in the devicetree.` + be flagged as :c:macro:`GPIO_ACTIVE_LOW` in the devicetree. Recommended Changes ******************* From 78acf5e64876d5c26cb005bf74795672b62c8eb5 Mon Sep 17 00:00:00 2001 From: Tim Guite Date: Fri, 3 Nov 2023 21:12:41 +0000 Subject: [PATCH 3493/4498] board: mimxrt1170_evk Add pyOCD runner to docs Added a short paragraph explaining how to use pyOCD to flash and debug this board, as well as a disclaimer requested by NXP Signed-off-by: Tim Guite --- boards/arm/mimxrt1170_evk/doc/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index 1582861ffc9..15a66875d31 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -349,6 +349,11 @@ Use the ``-r linkserver`` option with West to use the LinkServer runner. west flash -r linkserver +Alternatively, pyOCD can be used to flash and debug the board by using the +``-r pyocd`` option with West. pyOCD is installed when you complete the +:ref:`gs_python_deps` step in the Getting Started Guide. The runners supported +by NXP are LinkServer and JLink. pyOCD is another potential option, but NXP +does not test or support the pyOCD runner. Configuring a Console ===================== From a2ad2d71f64b785a10e43f4feb81bf5f45503577 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 3 Oct 2023 11:44:53 +0300 Subject: [PATCH 3494/4498] drivers: sensor: adxl372: fix define comment Replace unrelated part name with the actual driver name in the adxl372.h header file. Fixes: a3e7cea ("adxl372: Add driver for ADXL372 high-g accelerometer") Signed-off-by: Antoniu Miclaus --- drivers/sensor/adxl372/adxl372.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/adxl372/adxl372.h b/drivers/sensor/adxl372/adxl372.h index 39d1959b220..c8914130882 100644 --- a/drivers/sensor/adxl372/adxl372.h +++ b/drivers/sensor/adxl372/adxl372.h @@ -373,6 +373,6 @@ int adxl372_trigger_set(const struct device *dev, sensor_trigger_handler_t handler); int adxl372_init_interrupt(const struct device *dev); -#endif /* CONFIG_ADT7420_TRIGGER */ +#endif /* CONFIG_ADXL372_TRIGGER */ #endif /* ZEPHYR_DRIVERS_SENSOR_ADXL372_ADXL372_H_ */ From d6ff5122fded8380688ffa875ee6be99f2cc5fd3 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Sat, 14 Oct 2023 23:24:39 +0530 Subject: [PATCH 3495/4498] dts: x86: intel: raptor_lake: Remove unavailable UARTs Remove unavailable UART instances on RPL platform. Signed-off-by: Anisetti Avinash Krishna --- dts/x86/intel/raptor_lake.dtsi | 48 ---------------------------------- 1 file changed, 48 deletions(-) diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index c479d54dd9e..797a3fa0e54 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -307,54 +307,6 @@ current-speed = <115200>; status = "disabled"; }; - - uart3: uart3 { - compatible = "ns16550"; - vendor-id = <0x8086>; - device-id = <0x7adc>; - reg-shift = <2>; - clock-frequency = <1843200>; - interrupts = ; - interrupt-parent = <&intc>; - current-speed = <115200>; - status = "disabled"; - }; - - uart4: uart4 { - compatible = "ns16550"; - vendor-id = <0x8086>; - device-id = <0x7add>; - reg-shift = <2>; - clock-frequency = <1843200>; - interrupts = ; - interrupt-parent = <&intc>; - current-speed = <115200>; - status = "disabled"; - }; - - uart5: uart5 { - compatible = "ns16550"; - vendor-id = <0x8086>; - device-id = <0x7ade>; - reg-shift = <2>; - clock-frequency = <1843200>; - interrupts = ; - interrupt-parent = <&intc>; - current-speed = <115200>; - status = "disabled"; - }; - - uart6: uart6 { - compatible = "ns16550"; - vendor-id = <0x8086>; - device-id = <0x7adf>; - reg-shift = <2>; - clock-frequency = <1843200>; - interrupts = ; - interrupt-parent = <&intc>; - current-speed = <115200>; - status = "disabled"; - }; }; soc { From 316707b7cdd43dff6b391744b40950b4864878b2 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 13 Oct 2023 15:50:46 +0530 Subject: [PATCH 3496/4498] drivers: dma: dma_intel_lpss: Enhance LPSS DMA to support UART Enhance LPSS DMA to support UART and I2C DMA transfer by enabling init priority of DMA based on dependency on parent device. Signed-off-by: Anisetti Avinash Krishna --- drivers/dma/dma_intel_lpss.c | 41 ++++++++++++++++----- include/zephyr/drivers/dma/dma_intel_lpss.h | 3 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/dma/dma_intel_lpss.c b/drivers/dma/dma_intel_lpss.c index b76d0820815..c39fb9dd5ac 100644 --- a/drivers/dma/dma_intel_lpss.c +++ b/drivers/dma/dma_intel_lpss.c @@ -27,22 +27,36 @@ struct dma_intel_lpss_cfg { const struct device *parent; }; +int dma_intel_lpss_setup(const struct device *dev) +{ + struct dma_intel_lpss_cfg *dev_cfg = (struct dma_intel_lpss_cfg *)dev->config; + + if (dev_cfg->dw_cfg.base != 0) { + return dw_dma_setup(dev); + } + + return 0; +} + +void dma_intel_lpss_set_base(const struct device *dev, uintptr_t base) +{ + struct dma_intel_lpss_cfg *dev_cfg = (struct dma_intel_lpss_cfg *)dev->config; + + dev_cfg->dw_cfg.base = base; +} + static int dma_intel_lpss_init(const struct device *dev) { struct dma_intel_lpss_cfg *dev_cfg = (struct dma_intel_lpss_cfg *)dev->config; uint32_t base; int ret; - if (!device_is_ready(dev_cfg->parent)) { - LOG_ERR("LPSS DMA parent not ready"); - ret = -ENODEV; - goto out; + if (device_is_ready(dev_cfg->parent)) { + base = DEVICE_MMIO_GET(dev_cfg->parent) + DMA_INTEL_LPSS_OFFSET; + dev_cfg->dw_cfg.base = base; } - base = DEVICE_MMIO_GET(dev_cfg->parent) + DMA_INTEL_LPSS_OFFSET; - dev_cfg->dw_cfg.base = base; - - ret = dw_dma_setup(dev); + ret = dma_intel_lpss_setup(dev); if (ret != 0) { LOG_ERR("failed to initialize LPSS DMA %s", dev->name); @@ -64,6 +78,12 @@ static const struct dma_driver_api dma_intel_lpss_driver_api = { .stop = dw_dma_stop, }; +#define DMA_LPSS_INIT_VAL_0 49 /* When parent device depends on DMA */ +#define DMA_LPSS_INIT_VAL_1 80 /* When DMA device depends on parent */ + +#define DMA_LPSS_INIT_VAL(n)\ + _CONCAT(DMA_LPSS_INIT_VAL_, DT_INST_NODE_HAS_PROP(n, dma_parent)) + #define DMA_INTEL_LPSS_INIT(n) \ \ static struct dw_drv_plat_data dma_intel_lpss##n = { \ @@ -82,7 +102,8 @@ static const struct dma_driver_api dma_intel_lpss_driver_api = { .dw_cfg = { \ .base = 0, \ }, \ - .parent = DEVICE_DT_GET(DT_INST_PHANDLE(n, dma_parent)),\ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, dma_parent), \ + (.parent = DEVICE_DT_GET(DT_INST_PHANDLE(n, dma_parent)),))\ }; \ \ static struct dw_dma_dev_data dma_intel_lpss##n##_data = { \ @@ -94,7 +115,7 @@ static const struct dma_driver_api dma_intel_lpss_driver_api = { NULL, \ &dma_intel_lpss##n##_data, \ &dma_intel_lpss##n##_config, POST_KERNEL, \ - DMA_INTEL_LPSS_INIT_PRIORITY, \ + DMA_LPSS_INIT_VAL(n), \ &dma_intel_lpss_driver_api); \ DT_INST_FOREACH_STATUS_OKAY(DMA_INTEL_LPSS_INIT) diff --git a/include/zephyr/drivers/dma/dma_intel_lpss.h b/include/zephyr/drivers/dma/dma_intel_lpss.h index c3cf3bef81e..8ef05b688f9 100644 --- a/include/zephyr/drivers/dma/dma_intel_lpss.h +++ b/include/zephyr/drivers/dma/dma_intel_lpss.h @@ -7,7 +7,6 @@ #ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_INTEL_LPSS_H_ #define ZEPHYR_INCLUDE_DRIVERS_DMA_INTEL_LPSS_H_ -#define DMA_INTEL_LPSS_INIT_PRIORITY 80 #define DMA_INTEL_LPSS_OFFSET 0x800 #define DMA_INTEL_LPSS_REMAP_LOW 0x240 #define DMA_INTEL_LPSS_REMAP_HI 0x244 @@ -16,5 +15,7 @@ #define DMA_INTEL_LPSS_ADDR_RIGHT_SHIFT 32 void dma_intel_lpss_isr(const struct device *dev); +int dma_intel_lpss_setup(const struct device *dev); +void dma_intel_lpss_set_base(const struct device *dev, uintptr_t base); #endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_INTEL_LPSS_H_ */ From 3306eb7d912ad0ceac89561b9e19284dc1c2743b Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 13 Oct 2023 16:25:36 +0530 Subject: [PATCH 3497/4498] drivers: dma: dma_intel_lpss: Enable dma_status and dma_reload Enable dma_get_status and dma_reload features for LPSS DMA. Signed-off-by: Anisetti Avinash Krishna --- drivers/dma/dma_intel_lpss.c | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/dma/dma_intel_lpss.c b/drivers/dma/dma_intel_lpss.c index c39fb9dd5ac..7d0fec20045 100644 --- a/drivers/dma/dma_intel_lpss.c +++ b/drivers/dma/dma_intel_lpss.c @@ -67,6 +67,81 @@ static int dma_intel_lpss_init(const struct device *dev) return ret; } +int dma_intel_lpss_reload(const struct device *dev, uint32_t channel, + uint64_t src, uint64_t dst, size_t size) +{ + struct dw_dma_dev_data *const dev_data = dev->data; + struct dma_intel_lpss_cfg *lpss_dev_cfg = (struct dma_intel_lpss_cfg *)dev->config; + struct dw_dma_dev_cfg *const dev_cfg = &lpss_dev_cfg->dw_cfg; + struct dw_dma_chan_data *chan_data; + uint32_t ctrl_hi = 0; + + if (channel >= DW_MAX_CHAN) { + return -EINVAL; + } + + chan_data = &dev_data->chan[channel]; + + chan_data->lli_current->sar = src; + chan_data->lli_current->dar = dst; + chan_data->ptr_data.current_ptr = dst; + chan_data->ptr_data.buffer_bytes = size; + + ctrl_hi = dw_read(dev_cfg->base, DW_CTRL_HIGH(channel)); + ctrl_hi &= ~(DW_CTLH_DONE(1) | DW_CTLH_BLOCK_TS_MASK); + ctrl_hi |= size & DW_CTLH_BLOCK_TS_MASK; + + chan_data->lli_current->ctrl_hi = ctrl_hi; + chan_data->ptr_data.start_ptr = DW_DMA_LLI_ADDRESS(chan_data->lli_current, + chan_data->direction); + chan_data->ptr_data.end_ptr = chan_data->ptr_data.start_ptr + + chan_data->ptr_data.buffer_bytes; + chan_data->ptr_data.hw_ptr = chan_data->ptr_data.start_ptr; + + chan_data->state = DW_DMA_PREPARED; + + return 0; +} + +int dma_intel_lpss_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + struct dma_intel_lpss_cfg *lpss_dev_cfg = (struct dma_intel_lpss_cfg *)dev->config; + struct dw_dma_dev_cfg *const dev_cfg = &lpss_dev_cfg->dw_cfg; + struct dw_dma_dev_data *const dev_data = dev->data; + struct dw_dma_chan_data *chan_data; + uint32_t ctrl_hi; + size_t current_length; + bool done; + + if (channel >= DW_CHAN_COUNT) { + return -EINVAL; + } + + chan_data = &dev_data->chan[channel]; + ctrl_hi = dw_read(dev_cfg->base, DW_CTRL_HIGH(channel)); + current_length = ctrl_hi & DW_CTLH_BLOCK_TS_MASK; + done = ctrl_hi & DW_CTLH_DONE(1); + + if (!(dw_read(dev_cfg->base, DW_DMA_CHAN_EN) & DW_CHAN(channel))) { + stat->busy = false; + stat->pending_length = chan_data->ptr_data.buffer_bytes; + return 0; + } + stat->busy = true; + + if (done) { + stat->pending_length = 0; + } else if (current_length == chan_data->ptr_data.buffer_bytes) { + stat->pending_length = chan_data->ptr_data.buffer_bytes; + } else { + stat->pending_length = + chan_data->ptr_data.buffer_bytes - current_length; + } + + return 0; +} + void dma_intel_lpss_isr(const struct device *dev) { dw_dma_isr(dev); @@ -75,6 +150,8 @@ void dma_intel_lpss_isr(const struct device *dev) static const struct dma_driver_api dma_intel_lpss_driver_api = { .config = dw_dma_config, .start = dw_dma_start, + .reload = dma_intel_lpss_reload, + .get_status = dma_intel_lpss_get_status, .stop = dw_dma_stop, }; From 2c19de53bc3b0d31d2f338d48c8eccfbd7463118 Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Fri, 13 Oct 2023 16:28:57 +0530 Subject: [PATCH 3498/4498] drivers: dma: dma_dw_common: Corrected compare value of dma_is_enabled Corrected comapare value of dma_is_enabled as it is compare with wrong macro to check if channel is enabled or not. Signed-off-by: Anisetti Avinash Krishna --- drivers/dma/dma_dw_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dma_dw_common.c b/drivers/dma/dma_dw_common.c index bb000298385..0a5040980b2 100644 --- a/drivers/dma/dma_dw_common.c +++ b/drivers/dma/dma_dw_common.c @@ -434,7 +434,7 @@ bool dw_dma_is_enabled(const struct device *dev, uint32_t channel) { const struct dw_dma_dev_cfg *const dev_cfg = dev->config; - return dw_read(dev_cfg->base, DW_DMA_CHAN_EN) & DW_CHAN_MASK(channel); + return dw_read(dev_cfg->base, DW_DMA_CHAN_EN) & DW_CHAN(channel); } int dw_dma_start(const struct device *dev, uint32_t channel) From 0d9654670f564fc5fa7dd080f60dbbdfdbe196b2 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Sat, 11 Nov 2023 10:26:59 +0100 Subject: [PATCH 3499/4498] drivers: i3c: add dummy driver for vnd,i3c It is just used to be able to DEVICE_DT_GET() bus devices from tests/drivers/build_all in an upcoming commit. Signed-off-by: Armando Visconti --- drivers/i3c/CMakeLists.txt | 5 ++++ drivers/i3c/Kconfig | 1 + drivers/i3c/Kconfig.test | 11 +++++++++ drivers/i3c/i3c_test.c | 47 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 drivers/i3c/Kconfig.test create mode 100644 drivers/i3c/i3c_test.c diff --git a/drivers/i3c/CMakeLists.txt b/drivers/i3c/CMakeLists.txt index 2645dbeabb5..71a7dc6eb27 100644 --- a/drivers/i3c/CMakeLists.txt +++ b/drivers/i3c/CMakeLists.txt @@ -30,3 +30,8 @@ zephyr_library_sources_ifdef( CONFIG_I3C_CADENCE i3c_cdns.c ) + +zephyr_library_sources_ifdef( + CONFIG_I3C_TEST + i3c_test.c +) diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index f4a343632ab..2b524c2bf9d 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -100,5 +100,6 @@ comment "Device Drivers" rsource "Kconfig.nxp" rsource "Kconfig.cdns" +rsource "Kconfig.test" endif # I3C diff --git a/drivers/i3c/Kconfig.test b/drivers/i3c/Kconfig.test new file mode 100644 index 00000000000..3b28d596980 --- /dev/null +++ b/drivers/i3c/Kconfig.test @@ -0,0 +1,11 @@ +# Copyright (c) 2021, Commonwealth Scientific and Industrial Research +# Organisation (CSIRO) ABN 41 687 119 230. +# Copyright (c) 2023 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 + +# Hidden option for turning on the dummy driver for vnd,i3c devices +# used in testing. +config I3C_TEST + def_bool DT_HAS_VND_I3C_ENABLED + depends on DT_HAS_VND_I3C_ENABLED diff --git a/drivers/i3c/i3c_test.c b/drivers/i3c/i3c_test.c new file mode 100644 index 00000000000..165449747d8 --- /dev/null +++ b/drivers/i3c/i3c_test.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This is not a real I3C driver. It is used to instantiate struct + * devices for the "vnd,i3c" devicetree compatible used in test code. + */ + +#define DT_DRV_COMPAT vnd_i3c + +#include +#include +#include + +static int vnd_i3c_configure(const struct device *dev, + enum i3c_config_type type, void *config) +{ + return -ENOTSUP; +} + +static int vnd_i3c_config_get(const struct device *dev, + enum i3c_config_type type, void *config) +{ + return -ENOTSUP; +} + +static int vnd_i3c_recover_bus(const struct device *dev) +{ + return -ENOTSUP; +} + +static const struct i3c_driver_api vnd_i3c_api = { + .configure = vnd_i3c_configure, + .config_get = vnd_i3c_config_get, + .recover_bus = vnd_i3c_recover_bus, +}; + +#define VND_I3C_INIT(n) \ + DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, \ + POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &vnd_i3c_api); + +DT_INST_FOREACH_STATUS_OKAY(VND_I3C_INIT) From 0973531c94062e8bca78dfc8e1212a36e4fbc88a Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Sat, 11 Nov 2023 10:44:35 +0100 Subject: [PATCH 3500/4498] tests: drivers: build_all: sensor: add I3C test framework Add framework to test sensor drivers I3C conditional checkings. Signed-off-by: Armando Visconti --- tests/drivers/build_all/sensor/app.overlay | 11 +++++++++++ tests/drivers/build_all/sensor/i3c.dtsi | 18 ++++++++++++++++++ tests/drivers/build_all/sensor/prj.conf | 1 + .../build_all/sensor/src/generic_test.c | 1 + 4 files changed, 31 insertions(+) create mode 100644 tests/drivers/build_all/sensor/i3c.dtsi diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 23b732e9db4..fb039a8ebac 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -143,6 +143,17 @@ #include "w1.dtsi" }; + + test_i3c: i3c@f0cacc1a { + #address-cells = <3>; + #size-cells = <0>; + compatible = "vnd,i3c"; + reg = <0xf0cacc1a 0x1000>; + status = "okay"; + + #include "i3c.dtsi" + }; + }; }; diff --git a/tests/drivers/build_all/sensor/i3c.dtsi b/tests/drivers/build_all/sensor/i3c.dtsi new file mode 100644 index 00000000000..005c21fdff2 --- /dev/null +++ b/tests/drivers/build_all/sensor/i3c.dtsi @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for i3c devices + */ + +/**************************************** + * PLEASE KEEP REG ADDRESSES SEQUENTIAL * + ***************************************/ + +test_i3c_lps22hh: lps22hh@100000803E0000001 { + compatible = "st,lps22hh"; + reg = <0x1 0x00000803 0xE0000001>; + assigned-address = <0x1>; + drdy-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/sensor/prj.conf b/tests/drivers/build_all/sensor/prj.conf index b29c11a64bb..67172951b7d 100644 --- a/tests/drivers/build_all/sensor/prj.conf +++ b/tests/drivers/build_all/sensor/prj.conf @@ -6,6 +6,7 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 CONFIG_ADC=y CONFIG_GPIO=y CONFIG_I2C=y +CONFIG_I3C=y CONFIG_SERIAL=y CONFIG_SPI=y CONFIG_W1=y diff --git a/tests/drivers/build_all/sensor/src/generic_test.c b/tests/drivers/build_all/sensor/src/generic_test.c index 42ac57e8f37..9a1dc537535 100644 --- a/tests/drivers/build_all/sensor/src/generic_test.c +++ b/tests/drivers/build_all/sensor/src/generic_test.c @@ -282,6 +282,7 @@ static void run_generic_test(const struct device *dev) /* Iterate through each of the emulated buses and create a test for each device. */ DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(test_i2c), DECLARE_ZTEST_PER_DEVICE) +DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(test_i3c), DECLARE_ZTEST_PER_DEVICE) DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(test_spi), DECLARE_ZTEST_PER_DEVICE) ZTEST_SUITE(generic, NULL, NULL, before, NULL, NULL); From f1f7e4712c38e0c4e13652fe45af000b6a2c37c1 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Mon, 28 Aug 2023 16:15:41 +0200 Subject: [PATCH 3501/4498] drivers/sensor: add support to LPS22DF pressure sensor The LPS22DF is an ultracompact, piezoresistive, absolute pressure sensor that functions as a digital output barometer. The LPS22DF provides lower power consumption, achieving lower pressure noise than its predecessor. This driver is based on stmemsc HAL i/f v2.3 https://www.st.com/en/datasheet/lps22df.pdf Signed-off-by: Armando Visconti --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/lps22df/CMakeLists.txt | 12 + drivers/sensor/lps22df/Kconfig | 59 +++ drivers/sensor/lps22df/lps22df.c | 338 ++++++++++++++++++ drivers/sensor/lps22df/lps22df.h | 99 +++++ drivers/sensor/lps22df/lps22df_trigger.c | 251 +++++++++++++ dts/bindings/sensor/st,lps22df-common.yaml | 88 +++++ dts/bindings/sensor/st,lps22df-i2c.yaml | 10 + dts/bindings/sensor/st,lps22df-i3c.yaml | 10 + dts/bindings/sensor/st,lps22df-spi.yaml | 10 + modules/Kconfig.st | 3 + tests/drivers/build_all/sensor/app.overlay | 3 +- tests/drivers/build_all/sensor/i2c.dtsi | 7 + tests/drivers/build_all/sensor/i3c.dtsi | 7 + .../sensor/sensors_trigger_global.conf | 1 + .../sensor/sensors_trigger_none.conf | 1 + .../build_all/sensor/sensors_trigger_own.conf | 1 + tests/drivers/build_all/sensor/spi.dtsi | 8 + 19 files changed, 909 insertions(+), 1 deletion(-) create mode 100644 drivers/sensor/lps22df/CMakeLists.txt create mode 100644 drivers/sensor/lps22df/Kconfig create mode 100644 drivers/sensor/lps22df/lps22df.c create mode 100644 drivers/sensor/lps22df/lps22df.h create mode 100644 drivers/sensor/lps22df/lps22df_trigger.c create mode 100644 dts/bindings/sensor/st,lps22df-common.yaml create mode 100644 dts/bindings/sensor/st,lps22df-i2c.yaml create mode 100644 dts/bindings/sensor/st,lps22df-i3c.yaml create mode 100644 dts/bindings/sensor/st,lps22df-spi.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 8ac3da6c937..0bace9305b9 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -71,6 +71,7 @@ add_subdirectory_ifdef(CONFIG_LIS2MDL lis2mdl) add_subdirectory_ifdef(CONFIG_LIS3MDL lis3mdl) add_subdirectory_ifdef(CONFIG_LM75 lm75) add_subdirectory_ifdef(CONFIG_LM77 lm77) +add_subdirectory_ifdef(CONFIG_LPS22DF lps22df) add_subdirectory_ifdef(CONFIG_LPS22HB lps22hb) add_subdirectory_ifdef(CONFIG_LPS22HH lps22hh) add_subdirectory_ifdef(CONFIG_LPS25HB lps25hb) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 000c4bb1a35..e334617cf0b 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -144,6 +144,7 @@ source "drivers/sensor/lis2mdl/Kconfig" source "drivers/sensor/lis3mdl/Kconfig" source "drivers/sensor/lm75/Kconfig" source "drivers/sensor/lm77/Kconfig" +source "drivers/sensor/lps22df/Kconfig" source "drivers/sensor/lps22hb/Kconfig" source "drivers/sensor/lps22hh/Kconfig" source "drivers/sensor/lps25hb/Kconfig" diff --git a/drivers/sensor/lps22df/CMakeLists.txt b/drivers/sensor/lps22df/CMakeLists.txt new file mode 100644 index 00000000000..bb5194cf9ba --- /dev/null +++ b/drivers/sensor/lps22df/CMakeLists.txt @@ -0,0 +1,12 @@ +# ST Microelectronics LPS22DF pressure and temperature sensor +# +# Copyright (c) 2023 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# +zephyr_library() + +zephyr_library_sources(lps22df.c) +zephyr_library_sources_ifdef(CONFIG_LPS22DF_TRIGGER lps22df_trigger.c) + +zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/lps22df/Kconfig b/drivers/sensor/lps22df/Kconfig new file mode 100644 index 00000000000..843c6e755c4 --- /dev/null +++ b/drivers/sensor/lps22df/Kconfig @@ -0,0 +1,59 @@ +# ST Microelectronics LPS22DF pressure and temperature sensor + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +menuconfig LPS22DF + bool "LPS22DF pressure and temperature" + default y + depends on DT_HAS_ST_LPS22DF_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),i2c) + select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),i3c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),spi) + select HAS_STMEMSC + select USE_STDC_LPS22DF + help + Enable driver for LPS22DF I2C-based pressure and temperature + sensor. + +if LPS22DF + +choice LPS22DF_TRIGGER_MODE + prompt "Trigger mode" + default LPS22DF_TRIGGER_GLOBAL_THREAD + help + Specify the type of triggering to be used by the driver. + +config LPS22DF_TRIGGER_NONE + bool "No trigger" + +config LPS22DF_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select LPS22DF_TRIGGER + +config LPS22DF_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select LPS22DF_TRIGGER + +endchoice # LPS22DF_TRIGGER_MODE + +config LPS22DF_TRIGGER + bool + +config LPS22DF_THREAD_PRIORITY + int "Thread priority" + depends on LPS22DF_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config LPS22DF_THREAD_STACK_SIZE + int "Thread stack size" + depends on LPS22DF_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +endif # LPS22DF diff --git a/drivers/sensor/lps22df/lps22df.c b/drivers/sensor/lps22df/lps22df.c new file mode 100644 index 00000000000..a74ef75c245 --- /dev/null +++ b/drivers/sensor/lps22df/lps22df.c @@ -0,0 +1,338 @@ +/* ST Microelectronics LPS22DF pressure and temperature sensor + * + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lps22df.pdf + */ + +#define DT_DRV_COMPAT st_lps22df + +#include +#include +#include +#include +#include +#include +#include + +#include "lps22df.h" + +#define LPS22DF_SWRESET_WAIT_TIME 50 + +LOG_MODULE_REGISTER(LPS22DF, CONFIG_SENSOR_LOG_LEVEL); + +static inline int lps22df_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lps22df_config * const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_md_t md; + + md.odr = odr; + md.avg = cfg->avg; + md.lpf = cfg->lpf; + + return lps22df_mode_set(ctx, &md); +} + +static int lps22df_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct lps22df_data *data = dev->data; + const struct lps22df_config * const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_data_t raw_data; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + + if (lps22df_data_get(ctx, &raw_data) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + + data->sample_press = raw_data.pressure.raw; + data->sample_temp = raw_data.heat.raw; + + return 0; +} + +static inline void lps22df_press_convert(struct sensor_value *val, + int32_t raw_val) +{ + int32_t press_tmp = raw_val >> 8; /* raw value is left aligned (24 msb) */ + + /* Pressure sensitivity is 4096 LSB/hPa */ + /* Also convert hPa into kPa */ + + val->val1 = press_tmp / 40960; + + /* For the decimal part use (3125 / 128) as a factor instead of + * (1000000 / 40960) to avoid int32 overflow + */ + val->val2 = (press_tmp % 40960) * 3125 / 128; +} + +static inline void lps22df_temp_convert(struct sensor_value *val, + int16_t raw_val) +{ + /* Temperature sensitivity is 100 LSB/deg C */ + val->val1 = raw_val / 100; + val->val2 = ((int32_t)raw_val % 100) * 10000; +} + +static int lps22df_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct lps22df_data *data = dev->data; + + if (chan == SENSOR_CHAN_PRESS) { + lps22df_press_convert(val, data->sample_press); + } else if (chan == SENSOR_CHAN_AMBIENT_TEMP) { + lps22df_temp_convert(val, data->sample_temp); + } else { + return -ENOTSUP; + } + + return 0; +} + +static const uint16_t lps22df_map[] = {0, 1, 4, 10, 25, 50, 75, 100, 200}; + +static int lps22df_odr_set(const struct device *dev, uint16_t freq) +{ + int odr; + + for (odr = 0; odr < ARRAY_SIZE(lps22df_map); odr++) { + if (freq == lps22df_map[odr]) { + break; + } + } + + if (odr == ARRAY_SIZE(lps22df_map)) { + LOG_DBG("bad frequency"); + return -EINVAL; + } + + if (lps22df_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set sampling rate"); + return -EIO; + } + + return 0; +} + +static int lps22df_attr_set(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + if (chan != SENSOR_CHAN_ALL) { + LOG_WRN("attr_set() not supported on this channel."); + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return lps22df_odr_set(dev, val->val1); + default: + LOG_DBG("operation not supported."); + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api lps22df_driver_api = { + .attr_set = lps22df_attr_set, + .sample_fetch = lps22df_sample_fetch, + .channel_get = lps22df_channel_get, +#if CONFIG_LPS22DF_TRIGGER + .trigger_set = lps22df_trigger_set, +#endif +}; + +static int lps22df_init_chip(const struct device *dev) +{ + const struct lps22df_config * const cfg = dev->config; + __maybe_unused struct lps22df_data *data = dev->data; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_id_t id; + lps22df_stat_t status; + uint8_t tries = 10; + int ret; + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + data->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (data->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + + if (lps22df_id_get(ctx, &id) < 0) { + LOG_ERR("%s: Not able to read dev id", dev->name); + return -EIO; + } + + if (id.whoami != LPS22DF_ID) { + LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, id.whoami); + return -EIO; + } + + LOG_DBG("%s: chip id 0x%x", dev->name, id.whoami); + + /* Restore default configuration */ + if (lps22df_init_set(ctx, LPS22DF_RESET) < 0) { + LOG_ERR("%s: Not able to reset device", dev->name); + return -EIO; + } + + do { + if (!--tries) { + LOG_DBG("sw reset timed out"); + return -ETIMEDOUT; + } + k_usleep(LPS22DF_SWRESET_WAIT_TIME); + + if (lps22df_status_get(ctx, &status) < 0) { + return -EIO; + } + } while (status.sw_reset); + + /* Set bdu and if_inc recommended for driver usage */ + if (lps22df_init_set(ctx, LPS22DF_DRV_RDY) < 0) { + LOG_ERR("%s: Not able to set device to ready state", dev->name); + return -EIO; + } + + if (ON_I3C_BUS(cfg)) { + lps22df_bus_mode_t bus_mode; + + /* Select bus interface */ + bus_mode.filter = LPS22DF_AUTO; + bus_mode.interface = LPS22DF_SEL_BY_HW; + lps22df_bus_mode_set(ctx, &bus_mode); + + } + + /* set sensor default odr */ + LOG_DBG("%s: odr: %d", dev->name, cfg->odr); + ret = lps22df_set_odr_raw(dev, cfg->odr); + if (ret < 0) { + LOG_ERR("%s: Failed to set odr %d", dev->name, cfg->odr); + return ret; + } + + return 0; +} + +static int lps22df_init(const struct device *dev) +{ + if (lps22df_init_chip(dev) < 0) { + LOG_DBG("Failed to initialize chip"); + return -EIO; + } + +#ifdef CONFIG_LPS22DF_TRIGGER + if (lps22df_init_interrupt(dev) < 0) { + LOG_ERR("Failed to initialize interrupt."); + return -EIO; + } +#endif + + return 0; +} + +/* + * Instantiation macros used when a device is on a SPI bus. + */ + +#ifdef CONFIG_LPS22DF_TRIGGER +#define LPS22DF_CFG_IRQ(inst) \ + .gpio_int = GPIO_DT_SPEC_INST_GET(inst, drdy_gpios), +#else +#define LPS22DF_CFG_IRQ(inst) +#endif /* CONFIG_LPS22DF_TRIGGER */ + +#define LPS22DF_CONFIG_COMMON(inst) \ + .odr = DT_INST_PROP(inst, odr), \ + .lpf = DT_INST_PROP(inst, lpf), \ + .avg = DT_INST_PROP(inst, avg), \ + .drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, drdy_gpios), \ + (LPS22DF_CFG_IRQ(inst)), ()) + +#define LPS22DF_SPI_OPERATION (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | \ + SPI_MODE_CPOL | SPI_MODE_CPHA) \ + +#define LPS22DF_CONFIG_SPI(inst) \ + { \ + STMEMSC_CTX_SPI(&lps22df_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, \ + LPS22DF_SPI_OPERATION, \ + 0), \ + }, \ + LPS22DF_CONFIG_COMMON(inst) \ + } + +/* + * Instantiation macros used when a device is on an I2C bus. + */ + +#define LPS22DF_CONFIG_I2C(inst) \ + { \ + STMEMSC_CTX_I2C(&lps22df_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }, \ + LPS22DF_CONFIG_COMMON(inst) \ + } + +/* + * Instantiation macros used when a device is on an I#C bus. + */ + +#define LPS22DF_CONFIG_I3C(inst) \ + { \ + STMEMSC_CTX_I3C(&lps22df_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .i3c = &lps22df_data_##inst.i3c_dev, \ + }, \ + .i3c.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .i3c.dev_id = I3C_DEVICE_ID_DT_INST(inst), \ + LPS22DF_CONFIG_COMMON(inst) \ + } + +#define LPS22DF_CONFIG_I3C_OR_I2C(inst) \ + COND_CODE_0(DT_INST_PROP_BY_IDX(inst, reg, 1), \ + (LPS22DF_CONFIG_I2C(inst)), \ + (LPS22DF_CONFIG_I3C(inst))) + +/* + * Main instantiation macro. Use of COND_CODE_1() selects the right + * bus-specific macro at preprocessor time. + */ + +#define LPS22DF_DEFINE(inst) \ + static struct lps22df_data lps22df_data_##inst; \ + static const struct lps22df_config lps22df_config_##inst = \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (LPS22DF_CONFIG_SPI(inst)), \ + (COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \ + (LPS22DF_CONFIG_I3C_OR_I2C(inst)), \ + (LPS22DF_CONFIG_I2C(inst))))); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, lps22df_init, NULL, &lps22df_data_##inst, \ + &lps22df_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &lps22df_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(LPS22DF_DEFINE) diff --git a/drivers/sensor/lps22df/lps22df.h b/drivers/sensor/lps22df/lps22df.h new file mode 100644 index 00000000000..044c08cbd93 --- /dev/null +++ b/drivers/sensor/lps22df/lps22df.h @@ -0,0 +1,99 @@ +/* ST Microelectronics LPS22DF pressure and temperature sensor + * + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lps22df.pdf + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_LPS22DF_LPS22DF_H_ +#define ZEPHYR_DRIVERS_SENSOR_LPS22DF_LPS22DF_H_ + +#include +#include +#include "lps22df_reg.h" + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + #define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) +#else + #define ON_I3C_BUS(cfg) (false) +#endif + +struct lps22df_config { + stmdev_ctx_t ctx; + union { +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + const struct i2c_dt_spec i2c; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) + const struct spi_dt_spec spi; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc **i3c; +#endif + } stmemsc_cfg; + uint8_t odr; + uint8_t lpf; + uint8_t avg; + uint8_t drdy_pulsed; +#ifdef CONFIG_LPS22DF_TRIGGER + struct gpio_dt_spec gpio_int; +#endif + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct { + const struct device *bus; + const struct i3c_device_id dev_id; + } i3c; +#endif +}; + +struct lps22df_data { + int32_t sample_press; + int16_t sample_temp; + +#ifdef CONFIG_LPS22DF_TRIGGER + struct gpio_callback gpio_cb; + + const struct sensor_trigger *data_ready_trigger; + sensor_trigger_handler_t handler_drdy; + const struct device *dev; + +#if defined(CONFIG_LPS22DF_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LPS22DF_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem intr_sem; +#elif defined(CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif + +#endif /* CONFIG_LPS22DF_TRIGGER */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc *i3c_dev; +#endif +}; + +#ifdef CONFIG_LPS22DF_TRIGGER +int lps22df_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int lps22df_init_interrupt(const struct device *dev); +#endif + +#endif /* ZEPHYR_DRIVERS_SENSOR_LPS22DF_LPS22DF_H_ */ diff --git a/drivers/sensor/lps22df/lps22df_trigger.c b/drivers/sensor/lps22df/lps22df_trigger.c new file mode 100644 index 00000000000..c5d6a91dba8 --- /dev/null +++ b/drivers/sensor/lps22df/lps22df_trigger.c @@ -0,0 +1,251 @@ +/* ST Microelectronics LPS22DF pressure and temperature sensor + * + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lps22df.pdf + */ + +#define DT_DRV_COMPAT st_lps22df + +#include +#include +#include +#include + +#include "lps22df.h" + +LOG_MODULE_DECLARE(LPS22DF, CONFIG_SENSOR_LOG_LEVEL); + +/** + * lps22df_enable_int - enable selected int pin to generate interrupt + */ +static int lps22df_enable_int(const struct device *dev, int enable) +{ + const struct lps22df_config * const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_pin_int_route_t int_route; + + /* set interrupt */ + lps22df_pin_int_route_get(ctx, &int_route); + int_route.drdy_pres = enable; + return lps22df_pin_int_route_set(ctx, &int_route); +} + +/** + * lps22df_trigger_set - link external trigger to event data ready + */ +int lps22df_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + struct lps22df_data *lps22df = dev->data; + const struct lps22df_config * const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_data_t raw_data; + + if (trig->chan != SENSOR_CHAN_ALL) { + LOG_WRN("trigger set not supported on this channel."); + return -ENOTSUP; + } + + lps22df->handler_drdy = handler; + lps22df->data_ready_trigger = trig; + if (handler) { + /* dummy read: re-trigger interrupt */ + if (lps22df_data_get(ctx, &raw_data) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + return lps22df_enable_int(dev, 1); + } else { + return lps22df_enable_int(dev, 0); + } + + return -ENOTSUP; +} + +/** + * lps22df_handle_interrupt - handle the drdy event + * read data and call handler if registered any + */ +static void lps22df_handle_interrupt(const struct device *dev) +{ + int ret; + struct lps22df_data *lps22df = dev->data; + const struct lps22df_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_all_sources_t status; + + if (lps22df_all_sources_get(ctx, &status) < 0) { + LOG_DBG("failed reading status reg"); + goto exit; + } + + if (status.drdy_pres == 0) { + goto exit; /* spurious interrupt */ + } + + if (lps22df->handler_drdy != NULL) { + lps22df->handler_drdy(dev, lps22df->data_ready_trigger); + } + + if (ON_I3C_BUS(cfg)) { + /* + * I3C IBI does not rely on GPIO. + * So no need to enable GPIO pin for interrupt trigger. + */ + return; + } + +exit: + ret = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } +} + +static void lps22df_intr_callback(struct lps22df_data *lps22df) +{ +#if defined(CONFIG_LPS22DF_TRIGGER_OWN_THREAD) + k_sem_give(&lps22df->intr_sem); +#elif defined(CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD) + k_work_submit(&lps22df->work); +#endif /* CONFIG_LPS22DF_TRIGGER_OWN_THREAD */ +} + +static void lps22df_gpio_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + struct lps22df_data *lps22df = + CONTAINER_OF(cb, struct lps22df_data, gpio_cb); + + ARG_UNUSED(pins); + const struct lps22df_config *cfg = lps22df->dev->config; + int ret; + + ret = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } + + lps22df_intr_callback(lps22df); +} + +#ifdef CONFIG_LPS22DF_TRIGGER_OWN_THREAD +static void lps22df_thread(struct lps22df_data *lps22df) +{ + while (1) { + k_sem_take(&lps22df->intr_sem, K_FOREVER); + lps22df_handle_interrupt(lps22df->dev); + } +} +#endif /* CONFIG_LPS22DF_TRIGGER_OWN_THREAD */ + +#ifdef CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD +static void lps22df_work_cb(struct k_work *work) +{ + struct lps22df_data *lps22df = + CONTAINER_OF(work, struct lps22df_data, work); + + lps22df_handle_interrupt(lps22df->dev); +} +#endif /* CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) +static int lps22df_ibi_cb(struct i3c_device_desc *target, + struct i3c_ibi_payload *payload) +{ + const struct device *dev = target->dev; + struct lps22df_data *lps22df = dev->data; + + ARG_UNUSED(payload); + + lps22df_intr_callback(lps22df); + + return 0; +} +#endif + +int lps22df_init_interrupt(const struct device *dev) +{ + struct lps22df_data *lps22df = dev->data; + const struct lps22df_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_int_mode_t mode; + int ret; + + /* setup data ready gpio interrupt */ + if (!gpio_is_ready_dt(&cfg->gpio_int) && !ON_I3C_BUS(cfg)) { + if (cfg->gpio_int.port) { + LOG_ERR("%s: device %s is not ready", dev->name, + cfg->gpio_int.port->name); + return -ENODEV; + } + + LOG_DBG("%s: gpio_int not defined in DT", dev->name); + return 0; + } + + lps22df->dev = dev; + +#if defined(CONFIG_LPS22DF_TRIGGER_OWN_THREAD) + k_sem_init(&lps22df->intr_sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&lps22df->thread, lps22df->thread_stack, + CONFIG_LPS22DF_THREAD_STACK_SIZE, + (k_thread_entry_t)lps22df_thread, lps22df, + NULL, NULL, K_PRIO_COOP(CONFIG_LPS22DF_THREAD_PRIORITY), + 0, K_NO_WAIT); +#elif defined(CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD) + lps22df->work.handler = lps22df_work_cb; +#endif /* CONFIG_LPS22DF_TRIGGER_OWN_THREAD */ + + if (!ON_I3C_BUS(cfg)) { + ret = gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure gpio"); + return ret; + } + + LOG_INF("%s: int on %s.%02u", dev->name, cfg->gpio_int.port->name, + cfg->gpio_int.pin); + + gpio_init_callback(&lps22df->gpio_cb, + lps22df_gpio_callback, + BIT(cfg->gpio_int.pin)); + + ret = gpio_add_callback(cfg->gpio_int.port, &lps22df->gpio_cb); + if (ret < 0) { + LOG_ERR("Could not set gpio callback"); + return ret; + } + } + + /* enable drdy in pulsed/latched mode */ + LOG_DBG("drdy_pulsed is %d", (int)cfg->drdy_pulsed); + mode.drdy_latched = ~cfg->drdy_pulsed; + if (lps22df_interrupt_mode_set(ctx, &mode) < 0) { + return -EIO; + } + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* I3C IBI does not utilize GPIO interrupt. */ + lps22df->i3c_dev->ibi_cb = lps22df_ibi_cb; + + if (i3c_ibi_enable(lps22df->i3c_dev) != 0) { + LOG_DBG("Could not enable I3C IBI"); + return -EIO; + } + + return 0; + } +#endif + + return gpio_pin_interrupt_configure_dt(&cfg->gpio_int, + GPIO_INT_EDGE_TO_ACTIVE); +} diff --git a/dts/bindings/sensor/st,lps22df-common.yaml b/dts/bindings/sensor/st,lps22df-common.yaml new file mode 100644 index 00000000000..7a1f21573b2 --- /dev/null +++ b/dts/bindings/sensor/st,lps22df-common.yaml @@ -0,0 +1,88 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +include: sensor-device.yaml + +properties: + drdy-gpios: + type: phandle-array + description: | + DRDY pin + + This pin defaults to active high when produced by the sensor. + The property value should ensure the flags properly describe + the signal that is presented to the driver. + + drdy-pulsed: + type: boolean + description: | + Selects the pulsed mode for data-ready interrupt when enabled, + and the latched mode when disabled. + + odr: + type: int + default: 0 + description: | + Specify the output data rate expressed in samples per second (Hz). + The default is the power-on reset value. + + 0 = Power-Down + 1 = 1Hz + 2 = 4Hz + 3 = 10Hz + 4 = 25Hz + 5 = 50Hz + 6 = 75Hz + 7 = 100Hz + 8 = 200Hz + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + + lpf: + type: int + default: 0 + description: | + Specify the low pass filter value to be applied to pressure data. + The default is the power-on reset value. + + 0 = Low Pass Filter disabled + 1 = Low Pass Filter set to ODR/4 + 3 = Low Pass Filter set to ODR/9 + enum: + - 0 + - 1 + - 3 + + avg: + type: int + default: 0 + description: | + Specify the average filter value (i.e. number of samples) to be applied + to pressure and temperature data. + The default is the power-on reset value. + + 0 = Average of 4 data samples + 1 = Average of 8 data samples + 2 = Average of 16 data samples + 3 = Average of 32 data samples + 4 = Average of 64 data samples + 5 = Average of 128 data samples + 6 = Average of 256 data samples + 7 = Average of 512 data samples + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 diff --git a/dts/bindings/sensor/st,lps22df-i2c.yaml b/dts/bindings/sensor/st,lps22df-i2c.yaml new file mode 100644 index 00000000000..11074528cf3 --- /dev/null +++ b/dts/bindings/sensor/st,lps22df-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to I2C + bus + +compatible: "st,lps22df" + +include: ["i2c-device.yaml", "st,lps22df-common.yaml"] diff --git a/dts/bindings/sensor/st,lps22df-i3c.yaml b/dts/bindings/sensor/st,lps22df-i3c.yaml new file mode 100644 index 00000000000..6bba397e0be --- /dev/null +++ b/dts/bindings/sensor/st,lps22df-i3c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to I3C + bus + +compatible: "st,lps22df" + +include: ["i3c-device.yaml", "st,lps22df-common.yaml"] diff --git a/dts/bindings/sensor/st,lps22df-spi.yaml b/dts/bindings/sensor/st,lps22df-spi.yaml new file mode 100644 index 00000000000..219738d0e95 --- /dev/null +++ b/dts/bindings/sensor/st,lps22df-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to SPI + bus + +compatible: "st,lps22df" + +include: ["spi-device.yaml", "st,lps22df-common.yaml"] diff --git a/modules/Kconfig.st b/modules/Kconfig.st index 2db03e18f77..fd90aee0b17 100644 --- a/modules/Kconfig.st +++ b/modules/Kconfig.st @@ -115,6 +115,9 @@ config USE_STDC_LIS3DSH config USE_STDC_LIS3MDL bool +config USE_STDC_LPS22DF + bool + config USE_STDC_LPS22HB bool diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index fb039a8ebac..9f7c604bf30 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -121,7 +121,8 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, /* 0x25 */ - <&test_gpio 0 0>; /* 0x26 */ + <&test_gpio 0 0>, /* 0x26 */ + <&test_gpio 0 0>; /* 0x27 */ #include "spi.dtsi" }; diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index eda5bff0ff7..42beeab095e 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -800,3 +800,10 @@ test_i2c_tsl2561: tsl2561@78 { compatible = "ams,tsl2561"; reg = <0x78>; }; + +test_i2c_lps22df: lps22df@78 { + compatible = "st,lps22df"; + reg = <0x78>; + drdy-gpios = <&test_gpio 0 0>; + status = "okay"; +}; diff --git a/tests/drivers/build_all/sensor/i3c.dtsi b/tests/drivers/build_all/sensor/i3c.dtsi index 005c21fdff2..42adb3fb175 100644 --- a/tests/drivers/build_all/sensor/i3c.dtsi +++ b/tests/drivers/build_all/sensor/i3c.dtsi @@ -16,3 +16,10 @@ test_i3c_lps22hh: lps22hh@100000803E0000001 { assigned-address = <0x1>; drdy-gpios = <&test_gpio 0 0>; }; + +test_i3c_lps22df: lps22df@200000803E0000002 { + compatible = "st,lps22df"; + reg = <0x2 0x00000803 0xE0000002>; + assigned-address = <0x2>; + drdy-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index 74ba8f20239..c42b4fa951e 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -36,6 +36,7 @@ CONFIG_LIS2DS12_TRIGGER_GLOBAL_THREAD=y CONFIG_LIS2DW12_TRIGGER_GLOBAL_THREAD=y CONFIG_LIS2MDL_TRIGGER_GLOBAL_THREAD=y CONFIG_LIS3MDL_TRIGGER_GLOBAL_THREAD=y +CONFIG_LPS22DF_TRIGGER_GLOBAL_THREAD=y CONFIG_LPS22HH_TRIGGER_GLOBAL_THREAD=y CONFIG_LSM6DSL_TRIGGER_GLOBAL_THREAD=y CONFIG_LSM6DSO_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index 905907928f5..9c46cb3637e 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -36,6 +36,7 @@ CONFIG_LIS2DS12_TRIGGER_NONE=y CONFIG_LIS2DW12_TRIGGER_NONE=y CONFIG_LIS2MDL_TRIGGER_NONE=y CONFIG_LIS3MDL_TRIGGER_NONE=y +CONFIG_LPS22DF_TRIGGER_NONE=y CONFIG_LPS22HH_TRIGGER_NONE=y CONFIG_LSM6DSL_TRIGGER_NONE=y CONFIG_LSM6DSO_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index 92504b6c2f4..5ecacb03d9a 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -34,6 +34,7 @@ CONFIG_LIS2DS12_TRIGGER_OWN_THREAD=y CONFIG_LIS2DW12_TRIGGER_OWN_THREAD=y CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y CONFIG_LIS3MDL_TRIGGER_OWN_THREAD=y +CONFIG_LPS22DF_TRIGGER_OWN_THREAD=y CONFIG_LPS22HH_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSL_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSO_TRIGGER_OWN_THREAD=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index d026e244f88..cd7bf1b66ec 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -304,3 +304,11 @@ test_spi_adxl367: adxl367@26 { odr = <4>; int1-gpios = <&test_gpio 0 0>; }; + +test_spi_lps22df: lps22df@27 { + compatible = "st,lps22df"; + reg = <0x27>; + spi-max-frequency = <0>; + drdy-gpios = <&test_gpio 0 0>; + status = "okay"; +}; From 92704d7f263bbc9d884f17be1ff006e7ed568098 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Mon, 6 Nov 2023 16:38:33 +0100 Subject: [PATCH 3502/4498] boards: arm: sensortile_box_pro: extend with lps22df Extend sensortile_box_pro with lps22df. Signed-off-by: Armando Visconti --- boards/arm/sensortile_box_pro/doc/index.rst | 5 +++++ boards/arm/sensortile_box_pro/sensortile_box_pro.dts | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/boards/arm/sensortile_box_pro/doc/index.rst b/boards/arm/sensortile_box_pro/doc/index.rst index c5f8eed3a37..bba5a4cb288 100644 --- a/boards/arm/sensortile_box_pro/doc/index.rst +++ b/boards/arm/sensortile_box_pro/doc/index.rst @@ -159,6 +159,8 @@ Motion and environmental sensors (`lsm6dsv16x datasheet`_) - **LIS2MDL** 3-axis magnetometer (`lis2mdl datasheet`_) + - **LPS22DF** Altimeter / pressure sensor + (`lps22df datasheet`_) - **LIS2DU12** 3-axis accelerometer (`lis2du12 datasheet`_) - **HTS221** Humidity sensor @@ -362,6 +364,9 @@ References .. _lis2mdl datasheet: https://www.st.com/en/mems-and-sensors/lis2mdl.html +.. _lps22df datasheet: + https://www.st.com/en/mems-and-sensors/lps22df.html + .. _lis2du12 datasheet: https://www.st.com/en/mems-and-sensors/lis2du12.html diff --git a/boards/arm/sensortile_box_pro/sensortile_box_pro.dts b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts index 8f5999d2aef..485ec6b6e7d 100644 --- a/boards/arm/sensortile_box_pro/sensortile_box_pro.dts +++ b/boards/arm/sensortile_box_pro/sensortile_box_pro.dts @@ -215,6 +215,13 @@ status = "okay"; }; + lps22df@5d { + compatible = "st,lps22df"; + reg = <0x5d>; + drdy-gpios = <&gpioe 8 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + lis2mdl@1e { compatible = "st,lis2mdl"; reg = <0x1e>; From 6dd2336a50849ead9241fec80d8b65b8e53445c4 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Mon, 6 Nov 2023 16:47:51 +0100 Subject: [PATCH 3503/4498] sample: board: sensortile_box_pro: extend with lps22df Extend sensor sample reading also lps22df data. Signed-off-by: Armando Visconti --- .../sensors-on-board/README.rst | 3 + .../sensors-on-board/prj.conf | 1 + .../sensors-on-board/src/main.c | 62 +++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/README.rst b/samples/boards/sensortile_box_pro/sensors-on-board/README.rst index 16d5deca353..f65294f2aa8 100644 --- a/samples/boards/sensortile_box_pro/sensors-on-board/README.rst +++ b/samples/boards/sensortile_box_pro/sensors-on-board/README.rst @@ -13,6 +13,7 @@ periodically reads and displays data on the console from the following sensors: - HTS221: ambient temperature and relative humidity +- LPS22DF: ambient temperature and atmospheric pressure - LSM6DSV16X: 6-Axis acceleration and angular velocity Requirements @@ -62,6 +63,8 @@ The sample code outputs sensors data on the SensorTile.box Pro console. HTS221: Temperature: 26.4 C HTS221: Relative Humidity: 60.5% + LPS22DF: Temperature: 28.4 C + LPS22DF: Pressure:99.694 kpa LSM6DSV16X: Accel (m.s-2): x: -0.158, y: 0.158, z: 9.811 LSM6DSV16X: GYro (dps): x: 0.003, y: 0.000, z: -0.005 1:: lsm6dsv16x acc trig 836 diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf b/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf index 82c6af865c9..a7c57f2f746 100644 --- a/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf +++ b/samples/boards/sensortile_box_pro/sensors-on-board/prj.conf @@ -8,6 +8,7 @@ CONFIG_GPIO=y CONFIG_SENSOR=y CONFIG_SENSOR_LOG_LEVEL_DBG=y CONFIG_HTS221_TRIGGER_NONE=y +CONFIG_LPS22DF_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD=y CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y diff --git a/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c b/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c index 8bb24ccc7d6..7aab1f36b13 100644 --- a/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c +++ b/samples/boards/sensortile_box_pro/sensors-on-board/src/main.c @@ -15,6 +15,17 @@ #include +#ifdef CONFIG_LPS22DF_TRIGGER +static int lps22df_trig_cnt; + +static void lps22df_trigger_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS); + lps22df_trig_cnt++; +} +#endif + #ifdef CONFIG_LSM6DSV16X_TRIGGER static int lsm6dsv16x_acc_trig_cnt; static int lsm6dsv16x_gyr_trig_cnt; @@ -53,6 +64,29 @@ static void lis2mdl_trigger_handler(const struct device *dev, } #endif +static void lps22df_config(const struct device *lps22df) +{ + struct sensor_value odr_attr; + + /* set LPS22DF sampling frequency to 50 Hz */ + odr_attr.val1 = 50; + odr_attr.val2 = 0; + + if (sensor_attr_set(lps22df, SENSOR_CHAN_ALL, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for LPS22DF\n"); + return; + } + +#ifdef CONFIG_LPS22DF_TRIGGER + struct sensor_trigger trig; + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_ALL; + sensor_trigger_set(lps22df, &trig, lps22df_trigger_handler); +#endif +} + static void lsm6dsv16x_config(const struct device *lsm6dsv16x) { struct sensor_value odr_attr, fs_attr; @@ -199,6 +233,7 @@ int main(void) printk("SensorTile.box Pro sensor test\n"); const struct device *const hts221 = DEVICE_DT_GET_ONE(st_hts221); + const struct device *const lps22df = DEVICE_DT_GET_ONE(st_lps22df); const struct device *const lsm6dsv16x = DEVICE_DT_GET_ONE(st_lsm6dsv16x); const struct device *const lis2mdl = DEVICE_DT_GET_ONE(st_lis2mdl); @@ -206,6 +241,10 @@ int main(void) printk("%s: device not ready.\n", hts221->name); return 0; } + if (!device_is_ready(lps22df)) { + printk("%s: device not ready.\n", lps22df->name); + return 0; + } if (!device_is_ready(lsm6dsv16x)) { printk("%s: device not ready.\n", lsm6dsv16x->name); return 0; @@ -216,10 +255,12 @@ int main(void) } lis2mdl_config(lis2mdl); + lps22df_config(lps22df); lsm6dsv16x_config(lsm6dsv16x); while (1) { struct sensor_value hts221_hum, hts221_temp; + struct sensor_value lps22df_press, lps22df_temp; struct sensor_value lsm6dsv16x_accel[3], lsm6dsv16x_gyro[3]; struct sensor_value lis2mdl_magn[3]; struct sensor_value lis2mdl_temp; @@ -237,6 +278,13 @@ int main(void) } #endif +#ifndef CONFIG_LPS22DF_TRIGGER + if (sensor_sample_fetch(lps22df) < 0) { + printf("LPS22DF Sensor sample update error\n"); + return 0; + } +#endif + #ifndef CONFIG_LIS2MDL_TRIGGER if (sensor_sample_fetch(lis2mdl) < 0) { printf("LIS2MDL Magn Sensor sample update error\n"); @@ -246,6 +294,8 @@ int main(void) sensor_channel_get(hts221, SENSOR_CHAN_HUMIDITY, &hts221_hum); sensor_channel_get(hts221, SENSOR_CHAN_AMBIENT_TEMP, &hts221_temp); + sensor_channel_get(lps22df, SENSOR_CHAN_AMBIENT_TEMP, &lps22df_temp); + sensor_channel_get(lps22df, SENSOR_CHAN_PRESS, &lps22df_press); sensor_channel_get(lsm6dsv16x, SENSOR_CHAN_ACCEL_XYZ, lsm6dsv16x_accel); sensor_channel_get(lsm6dsv16x, SENSOR_CHAN_GYRO_XYZ, lsm6dsv16x_gyro); sensor_channel_get(lis2mdl, SENSOR_CHAN_MAGN_XYZ, lis2mdl_magn); @@ -266,6 +316,14 @@ int main(void) printf("HTS221: Relative Humidity: %.1f%%\n", sensor_value_to_double(&hts221_hum)); + /* temperature */ + printf("LPS22DF: Temperature: %.1f C\n", + sensor_value_to_double(&lps22df_temp)); + + /* pressure */ + printf("LPS22DF: Pressure: %.3f kpa\n", + sensor_value_to_double(&lps22df_press)); + printf("LSM6DSV16X: Accel (m.s-2): x: %.3f, y: %.3f, z: %.3f\n", sensor_value_to_double(&lsm6dsv16x_accel[0]), sensor_value_to_double(&lsm6dsv16x_accel[1]), @@ -285,6 +343,10 @@ int main(void) printf("LIS2MDL: Temperature: %.1f C\n", sensor_value_to_double(&lis2mdl_temp)); +#ifdef CONFIG_LPS22DF_TRIGGER + printk("%d:: lps22df trig %d\n", cnt, lps22df_trig_cnt); +#endif + #ifdef CONFIG_LSM6DSV16X_TRIGGER printk("%d:: lsm6dsv16x acc trig %d\n", cnt, lsm6dsv16x_acc_trig_cnt); printk("%d:: lsm6dsv16x gyr trig %d\n", cnt, lsm6dsv16x_gyr_trig_cnt); From f9d0a4c5cf0ff90287cd902c81de882010700689 Mon Sep 17 00:00:00 2001 From: Lucas Denefle Date: Thu, 2 Nov 2023 16:23:02 +0000 Subject: [PATCH 3504/4498] drivers: modem: add Quectel EG25-G This commit introduces support for the modem EG25-G from Quectel. Signed-off-by: Lucas Denefle --- drivers/modem/Kconfig.cellular | 3 +- drivers/modem/modem_cellular.c | 73 +++++++++++++++++++++++++ dts/bindings/modem/quectel,eg25-g.yaml | 16 ++++++ tests/drivers/build_all/modem/uart.dtsi | 6 ++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/modem/quectel,eg25-g.yaml diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index 767879ccf0e..7817fb599e3 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -13,7 +13,8 @@ config MODEM_CELLULAR select NET_L2_PPP_OPTION_MRU depends on (DT_HAS_QUECTEL_BG95_ENABLED || DT_HAS_ZEPHYR_GSM_PPP_ENABLED || \ DT_HAS_SIMCOM_SIM7080_ENABLED || DT_HAS_U_BLOX_SARA_R4_ENABLED || \ - DT_HAS_SWIR_HL7800_ENABLED || DT_HAS_TELIT_ME910G1_ENABLED) + DT_HAS_SWIR_HL7800_ENABLED || DT_HAS_TELIT_ME910G1_ENABLED || \ + DT_HAS_QUECTEL_EG25_G_ENABLED) help This driver uses the generic 3gpp AT commands, along with the standard protocols CMUX and PPP, to configure diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 7564283417a..c3b97f0b618 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1356,6 +1356,47 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script, modem_cellular_chat_callback_handler, 4); #endif +#if DT_HAS_COMPAT_STATUS_OKAY(quectel_eg25_g) +MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_init_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", + 100)); + +MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_init_chat_script, quectel_eg25_g_init_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_dial_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\"," + "\""CONFIG_MODEM_CELLULAR_APN"\"", + ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),); + +MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_dial_chat_script, quectel_eg25_g_dial_chat_script_cmds, + dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_periodic_chat_script, + quectel_eg25_g_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); +#endif + #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_gsm_ppp) MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), @@ -1625,6 +1666,34 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, &MODEM_CELLULAR_INST_NAME(data, inst), \ &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); +#define MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = {'\r'}, \ + .chat_filter = {'\n'}, \ + .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + }; \ + \ + static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 500, \ + .startup_time_ms = 15000, \ + .shutdown_time_ms = 5000, \ + .init_chat_script = &quectel_eg25_g_init_chat_script, \ + .dial_chat_script = &quectel_eg25_g_dial_chat_script, \ + .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ + &MODEM_CELLULAR_INST_NAME(data, inst), \ + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL); + #define MODEM_CELLULAR_DEVICE_GSM_PPP(inst) \ MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ @@ -1769,6 +1838,10 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95) #undef DT_DRV_COMPAT +#define DT_DRV_COMPAT quectel_eg25_g +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G) +#undef DT_DRV_COMPAT + #define DT_DRV_COMPAT zephyr_gsm_ppp DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_GSM_PPP) #undef DT_DRV_COMPAT diff --git a/dts/bindings/modem/quectel,eg25-g.yaml b/dts/bindings/modem/quectel,eg25-g.yaml new file mode 100644 index 00000000000..45284ddf174 --- /dev/null +++ b/dts/bindings/modem/quectel,eg25-g.yaml @@ -0,0 +1,16 @@ +description: Quectel EG25-G modem + +compatible: "quectel,eg25-g" + +include: uart-device.yaml + +properties: + mdm-reset-gpios: + type: phandle-array + required: true + + mdm-dtr-gpios: + type: phandle-array + + mdm-wdisable-gpios: + type: phandle-array diff --git a/tests/drivers/build_all/modem/uart.dtsi b/tests/drivers/build_all/modem/uart.dtsi index 985f60dba69..3d649a2ff60 100644 --- a/tests/drivers/build_all/modem/uart.dtsi +++ b/tests/drivers/build_all/modem/uart.dtsi @@ -47,6 +47,12 @@ test_quectel_bg9x: quectel_bg9x { mdm-reset-gpios = <&test_gpio 0 0>; }; +test_quectel_eg25_g: quectel_eg25_g { + compatible = "quectel,eg25-g"; + + mdm-reset-gpios = <&test_gpio 0 0>; +}; + test_gsm_ppp: gsm_ppp { compatible = "zephyr,gsm-ppp"; }; From 85888c673da009f0c4767b8ec11c4c2b4600d785 Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Fri, 10 Nov 2023 13:52:00 +0800 Subject: [PATCH 3505/4498] manifest: Bump up hal_nxp revision Bump up hal_nxp revision to contain the clock frequency array initialization code of i.MX 93 Signed-off-by: Chekhov Ma --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 62194f60c19..639f5566de0 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: d5e5358e56542b94bc65b6483396f50ed8f3172d + revision: 73620197038d7ba80fb1f9abd001828b9dd6a27e path: modules/hal/nxp groups: - hal From 4e99da8599616eff73de2bce9f7cae56838aa858 Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Fri, 10 Nov 2023 11:21:08 +0800 Subject: [PATCH 3506/4498] imx93: change ccm driver to "imx-ccm-rev2" i.MX93 share similiar register layout with i.MX RT11xx. Change ccm driver to align with i.MX RT11xx, and make it easier to enable other drivers. Signed-off-by: Chekhov Ma --- drivers/clock_control/clock_control_mcux_ccm_rev2.c | 9 ++++++--- dts/arm64/nxp/nxp_mimx93_a55.dtsi | 8 ++++---- soc/arm64/nxp_imx/mimx9/Kconfig.soc | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/clock_control/clock_control_mcux_ccm_rev2.c b/drivers/clock_control/clock_control_mcux_ccm_rev2.c index 626402d73df..9a88a36823a 100644 --- a/drivers/clock_control/clock_control_mcux_ccm_rev2.c +++ b/drivers/clock_control/clock_control_mcux_ccm_rev2.c @@ -6,7 +6,6 @@ #define DT_DRV_COMPAT nxp_imx_ccm_rev2 #include -#include #include #include #include @@ -31,7 +30,7 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, clock_control_subsys_t sub_system, uint32_t *rate) { - uint32_t clock_name = (uint32_t) sub_system; + uint32_t clock_name = (size_t) sub_system; uint32_t clock_root, peripheral, instance; peripheral = (clock_name & IMX_CCM_PERIPHERAL_MASK); @@ -51,6 +50,7 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, #ifdef CONFIG_UART_MCUX_LPUART case IMX_CCM_LPUART1_CLK: + case IMX_CCM_LPUART2_CLK: clock_root = kCLOCK_Root_Lpuart1 + instance; break; #endif @@ -106,8 +106,11 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, default: return -EINVAL; } - +#ifdef CONFIG_SOC_MIMX93_A55 + *rate = CLOCK_GetIpFreq(clock_root); +#else *rate = CLOCK_GetRootClockFreq(clock_root); +#endif return 0; } diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index e064233e46f..22a61e2dfca 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include / { @@ -70,7 +70,7 @@ }; ccm: ccm@44450000 { - compatible = "nxp,imx-ccm"; + compatible = "nxp,imx-ccm-rev2"; reg = <0x44450000 DT_SIZE_K(64)>; #clock-cells = <3>; }; @@ -81,7 +81,7 @@ interrupts = ; interrupt-names = "irq_0"; interrupt-parent = <&gic>; - clocks = <&ccm IMX_CCM_LPUART_CLK 0x6c 24>; + clocks = <&ccm IMX_CCM_LPUART1_CLK 0x6c 24>; status = "disabled"; }; @@ -91,7 +91,7 @@ interrupts = ; interrupt-names = "irq_0"; interrupt-parent = <&gic>; - clocks = <&ccm IMX_CCM_LPUART_CLK 0x6c 24>; + clocks = <&ccm IMX_CCM_LPUART2_CLK 0x6c 24>; status = "disabled"; }; }; diff --git a/soc/arm64/nxp_imx/mimx9/Kconfig.soc b/soc/arm64/nxp_imx/mimx9/Kconfig.soc index 01ba9896874..3f38d40131f 100644 --- a/soc/arm64/nxp_imx/mimx9/Kconfig.soc +++ b/soc/arm64/nxp_imx/mimx9/Kconfig.soc @@ -11,7 +11,7 @@ config SOC_MIMX93_A55 select CPU_CORTEX_A55 select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS select HAS_MCUX if CLOCK_CONTROL - select HAS_MCUX_CCM if CLOCK_CONTROL + select HAS_MCUX_CCM_REV2 if CLOCK_CONTROL select HAS_MCUX_IOMUXC if PINCTRL endchoice From 5078265213e1afb06f530ea5d301882350724282 Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Mon, 23 Oct 2023 15:40:41 +0800 Subject: [PATCH 3507/4498] Revert "drivers: mcux_ccm: add support for lpuart on imx93" This reverts commit d963900dbd56fc3663881cf54f64b81e6dcc30fb. Since i.MX 93 is supported by mcux_ccm_rev2, remove i.MX 93 support from mcux_ccm driver. Signed-off-by: Chekhov Ma --- .../clock_control/clock_control_mcux_ccm.c | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/drivers/clock_control/clock_control_mcux_ccm.c b/drivers/clock_control/clock_control_mcux_ccm.c index 77736caa1c9..ab90602d2a4 100644 --- a/drivers/clock_control/clock_control_mcux_ccm.c +++ b/drivers/clock_control/clock_control_mcux_ccm.c @@ -43,18 +43,6 @@ static const clock_ip_name_t uart_clocks[] = { kCLOCK_Uart4, }; #endif -#if defined(CONFIG_UART_MCUX_LPUART) && defined(CONFIG_SOC_MIMX93_A55) -static const clock_root_t lpuart_clk_root[] = { - kCLOCK_Root_Lpuart1, - kCLOCK_Root_Lpuart2, - kCLOCK_Root_Lpuart3, - kCLOCK_Root_Lpuart4, - kCLOCK_Root_Lpuart5, - kCLOCK_Root_Lpuart6, - kCLOCK_Root_Lpuart7, - kCLOCK_Root_Lpuart8, -}; -#endif #ifdef CONFIG_UART_MCUX_LPUART @@ -203,28 +191,6 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, *rate = CLOCK_GetIpFreq(lpuart_clocks[instance]); break; -#elif defined(CONFIG_SOC_MIMX93_A55) - case IMX_CCM_LPUART1_CLK: - case IMX_CCM_LPUART2_CLK: - case IMX_CCM_LPUART3_CLK: - case IMX_CCM_LPUART4_CLK: - case IMX_CCM_LPUART5_CLK: - case IMX_CCM_LPUART6_CLK: - case IMX_CCM_LPUART7_CLK: - case IMX_CCM_LPUART8_CLK: - { - uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK; - clock_root_t clk_root = lpuart_clk_root[instance]; - uint32_t uart_mux = CLOCK_GetRootClockMux(clk_root); - uint32_t divider = CLOCK_GetRootClockDiv(clk_root); - - if (uart_mux == 0) - *rate = MHZ(24) / divider; - else - LOG_ERR("LPUART Clock is not supported\r\n"); - - } break; - #else case IMX_CCM_LPUART_CLK: if (CLOCK_GetMux(kCLOCK_UartMux) == 0) { From b654b6169944054e4a72be483c824c6d22ac7763 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 3 Oct 2023 13:00:45 +0300 Subject: [PATCH 3508/4498] drivers: sensor: adxl372: remove unused function After the merge of 9dda350 the `adxl327_reg_write_mask` function is no longer used. Signed-off-by: Antoniu Miclaus --- drivers/sensor/adxl372/adxl372.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/sensor/adxl372/adxl372.h b/drivers/sensor/adxl372/adxl372.h index c8914130882..13b4d93454b 100644 --- a/drivers/sensor/adxl372/adxl372.h +++ b/drivers/sensor/adxl372/adxl372.h @@ -365,9 +365,6 @@ int adxl372_i2c_init(const struct device *dev); int adxl372_get_status(const struct device *dev, uint8_t *status1, uint8_t *status2, uint16_t *fifo_entries); -int adxl372_reg_write_mask(const struct device *dev, - uint8_t reg_addr, uint32_t mask, uint8_t data); - int adxl372_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler); From 461cc8c136c0d8055255fe404edc8aeb7184963b Mon Sep 17 00:00:00 2001 From: Maxin John Date: Fri, 20 Oct 2023 18:16:52 +0300 Subject: [PATCH 3509/4498] samples: sensor: dht: add longan_nano overlay Add an overlay to use DHT11 temperature/humidity sensor in Longan Nano. Signed-off-by: Maxin John --- samples/sensor/dht/boards/longan_nano.overlay | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 samples/sensor/dht/boards/longan_nano.overlay diff --git a/samples/sensor/dht/boards/longan_nano.overlay b/samples/sensor/dht/boards/longan_nano.overlay new file mode 100644 index 00000000000..a50cd9b9404 --- /dev/null +++ b/samples/sensor/dht/boards/longan_nano.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + dht22 { + compatible = "aosong,dht"; + status = "okay"; + dio-gpios = <&gpiob 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; +}; From 774bf6b50e09ca07f91159ab66034129d7de503c Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Wed, 25 Oct 2023 16:46:42 +0300 Subject: [PATCH 3510/4498] drivers: sensor: adxl367: update self test delay The wait times in the self test procedure, according to the datasheet are 4 / ODR (current set value). Update the self test procedure by using the delay corresponding to the current ODR value that is set, instead of default ODR. Signed-off-by: Antoniu Miclaus --- drivers/sensor/adxl367/adxl367.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c index 020ee476b2b..f63b8f73a32 100644 --- a/drivers/sensor/adxl367/adxl367.c +++ b/drivers/sensor/adxl367/adxl367.c @@ -277,9 +277,30 @@ int adxl367_self_test(const struct device *dev) { int ret; struct adxl367_data *data = dev->data; + const struct adxl367_dev_config *cfg = dev->config; int16_t x_axis_1, x_axis_2, dif, min, max; uint8_t read_val[2]; + uint32_t st_delay_ms; + + /* 4 / ODR value in ms */ + switch (cfg->odr) { + case ADXL367_ODR_12P5HZ: + st_delay_ms = 320; + case ADXL367_ODR_25HZ: + st_delay_ms = 160; + case ADXL367_ODR_50HZ: + st_delay_ms = 80; + case ADXL367_ODR_100HZ: + st_delay_ms = 40; + case ADXL367_ODR_200HZ: + st_delay_ms = 20; + case ADXL367_ODR_400HZ: + st_delay_ms = 10; + default: + return -EINVAL; + } + ret = adxl367_set_op_mode(dev, ADXL367_MEASURE); if (ret != 0) { return ret; @@ -291,8 +312,8 @@ int adxl367_self_test(const struct device *dev) return ret; } - /* 4 / default ODR = 40ms */ - k_sleep(K_MSEC(40)); + /* 4 / ODR */ + k_sleep(K_MSEC(st_delay_ms)); ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); if (ret != 0) { @@ -313,8 +334,8 @@ int adxl367_self_test(const struct device *dev) return ret; } - /* 4 / default ODR = 40ms */ - k_sleep(K_MSEC(40)); + /* 4 / ODR */ + k_sleep(K_MSEC(st_delay_ms)); ret = data->hw_tf->read_reg_multiple(dev, ADXL367_X_DATA_H, read_val, 2); if (ret != 0) { From dcf882af03b84bd9e8319be652cf2824eaf2999c Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Thu, 26 Oct 2023 15:29:17 +0200 Subject: [PATCH 3511/4498] dts: bindings: Add gss vendor prefix Add vendor prefix for Gas Sensing Solutions Ltd. Signed-off-by: Jeppe Odgaard --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index e426bef99bd..5515ea53ebe 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -243,6 +243,7 @@ google Google, Inc. greeled GreeLed Electronic Ltd. grinn Grinn grmn Garmin Limited +gss Gas Sensing Solutions Ltd. gumstix Gumstix, Inc. hamamatsu Hamamatsu Photonics K.K. hannstar HannStar Display Corporation From 128f80db7dde84b4a60a5a5d749ad01c140e3093 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Thu, 26 Oct 2023 15:50:09 +0200 Subject: [PATCH 3512/4498] dts: bindings: add explorir_m support Add bindings for the ExplorIR-M CO2 sensor. Signed-off-by: Jeppe Odgaard --- dts/bindings/sensor/gss,explorir-m.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 dts/bindings/sensor/gss,explorir-m.yaml diff --git a/dts/bindings/sensor/gss,explorir-m.yaml b/dts/bindings/sensor/gss,explorir-m.yaml new file mode 100644 index 00000000000..62de081c1be --- /dev/null +++ b/dts/bindings/sensor/gss,explorir-m.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023, Vitrolife A/S +# SPDX-License-Identifier: Apache-2.0 + +description: Gas Sensing Solutions CO2 sensor + +compatible: "gss,explorir-m" + +include: [sensor-device.yaml, uart-device.yaml] From b0fdbce4df43f0b1ebccbd110c83ebd5d553e214 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Fri, 27 Oct 2023 15:17:44 +0200 Subject: [PATCH 3513/4498] drivers: sensors: add explorir_m co2 sensor Add driver for Gas Sensing Solutions' ExplorIR-M CO2 sensor. Signed-off-by: Jeppe Odgaard --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/explorir_m/CMakeLists.txt | 5 + drivers/sensor/explorir_m/Kconfig | 13 + drivers/sensor/explorir_m/explorir_m.c | 387 +++++++++++++++++++++ include/zephyr/drivers/sensor/explorir_m.h | 25 ++ 6 files changed, 432 insertions(+) create mode 100644 drivers/sensor/explorir_m/CMakeLists.txt create mode 100644 drivers/sensor/explorir_m/Kconfig create mode 100644 drivers/sensor/explorir_m/explorir_m.c create mode 100644 include/zephyr/drivers/sensor/explorir_m.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 0bace9305b9..ff1cf9ec4eb 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -36,6 +36,7 @@ add_subdirectory_ifdef(CONFIG_DPS310 dps310) add_subdirectory_ifdef(CONFIG_DS18B20 ds18b20) add_subdirectory_ifdef(CONFIG_ENS210 ens210) add_subdirectory_ifdef(CONFIG_ESP32_TEMP esp32_temp) +add_subdirectory_ifdef(CONFIG_EXPLORIR_M explorir_m) add_subdirectory_ifdef(CONFIG_F75303 f75303) add_subdirectory_ifdef(CONFIG_FDC2X1X fdc2x1x) add_subdirectory_ifdef(CONFIG_FXAS21002 fxas21002) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index e334617cf0b..55ef3ffec51 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -109,6 +109,7 @@ source "drivers/sensor/dps310/Kconfig" source "drivers/sensor/ds18b20/Kconfig" source "drivers/sensor/ens210/Kconfig" source "drivers/sensor/esp32_temp/Kconfig" +source "drivers/sensor/explorir_m/Kconfig" source "drivers/sensor/f75303/Kconfig" source "drivers/sensor/fdc2x1x/Kconfig" source "drivers/sensor/fxas21002/Kconfig" diff --git a/drivers/sensor/explorir_m/CMakeLists.txt b/drivers/sensor/explorir_m/CMakeLists.txt new file mode 100644 index 00000000000..71125b505f3 --- /dev/null +++ b/drivers/sensor/explorir_m/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(explorir_m.c) diff --git a/drivers/sensor/explorir_m/Kconfig b/drivers/sensor/explorir_m/Kconfig new file mode 100644 index 00000000000..02806bf82a8 --- /dev/null +++ b/drivers/sensor/explorir_m/Kconfig @@ -0,0 +1,13 @@ +# ExplorIR-M CO2 sensor configuration options + +# Copyright (c) 2023, Vitrolife A/S +# SPDX-License-Identifier: Apache-2.0 + +config EXPLORIR_M + bool "ExplorIR-M CO2 Sensor" + default y + depends on DT_HAS_GSS_EXPLORIR_M_ENABLED + depends on UART_INTERRUPT_DRIVEN + select UART + help + Enable driver for ExplorIR-M CO2 Sensor. diff --git a/drivers/sensor/explorir_m/explorir_m.c b/drivers/sensor/explorir_m/explorir_m.c new file mode 100644 index 00000000000..058c43faf2b --- /dev/null +++ b/drivers/sensor/explorir_m/explorir_m.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2023, Vitrolife A/S + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.gassensing.co.uk/wp-content/uploads/2023/05/ExplorIR-M-Data-Sheet-Rev-4.13_3.pdf + * + */ + +#define DT_DRV_COMPAT gss_explorir_m + +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(explorir_m_sensor, CONFIG_SENSOR_LOG_LEVEL); + +#define EXPLORIR_M_BEGIN_CHAR ' ' + +#define EXPLORIR_M_SET_FILTER_CHAR 'A' +#define EXPLORIR_M_GET_FILTER_CHAR 'a' +#define EXPLORIR_M_MODE_CHAR 'K' +#define EXPLORIR_M_CO2_FILTERED_CHAR 'Z' +#define EXPLORIR_M_SCALING_CHAR '.' +#define EXPLORIR_M_NOT_RECOGNISED_CHAR '?' + +#define EXPLORIR_M_SEPARATOR_CHAR ' ' +#define EXPLORIR_M_PRE_END_CHAR '\r' +#define EXPLORIR_M_END_CHAR '\n' + +#define EXPLORIR_M_TYPE_INDEX 1 +#define EXPLORIR_M_VALUE_INDEX 3 + +#define EXPLORIR_M_BUFFER_LENGTH 16 + +#define EXPLORIR_M_MAX_RESPONSE_DELAY 200 /* Add margin to the specified 100 in datasheet */ +#define EXPLORIR_M_CO2_VALID_DELAY 1200 + +struct explorir_m_data { + struct k_mutex uart_mutex; + struct k_sem uart_rx_sem; + uint16_t filtered; + uint16_t scaling; + uint8_t read_index; + uint8_t read_buffer[EXPLORIR_M_BUFFER_LENGTH]; +}; + +struct explorir_m_cfg { + const struct device *uart_dev; + uart_irq_callback_user_data_t cb; +}; + +enum explorir_m_uart_set_usage { + EXPLORIR_M_SET_NONE, + EXPLORIR_M_SET_VAL_ONE, + EXPLORIR_M_SET_VAL_ONE_TWO, +}; + +enum EXPLORIR_M_MODE { + EXPLORIR_M_MODE_COMMAND, + EXPLORIR_M_MODE_STREAM, + EXPLORIR_M_MODE_POLL, +}; + +static void explorir_m_uart_flush(const struct device *uart_dev) +{ + uint8_t tmp; + + while (uart_fifo_read(uart_dev, &tmp, 1) > 0) { + continue; + } +} + +static void explorir_m_uart_flush_until_end(const struct device *uart_dev) +{ + uint8_t tmp; + uint32_t uptime; + + uptime = k_uptime_get_32(); + do { + uart_poll_in(uart_dev, &tmp); + } while (tmp != EXPLORIR_M_END_CHAR && + k_uptime_get_32() - uptime < EXPLORIR_M_MAX_RESPONSE_DELAY); +} + +static void explorir_m_buffer_reset(struct explorir_m_data *data) +{ + memset(data->read_buffer, 0, data->read_index); + data->read_index = 0; +} + +static int explorir_m_buffer_verify(const struct explorir_m_data *data, char type) +{ + char buffer_type = data->read_buffer[EXPLORIR_M_TYPE_INDEX]; + + if (data->read_buffer[0] == EXPLORIR_M_NOT_RECOGNISED_CHAR) { + LOG_WRN("Sensor did not recognise the command"); + return -EIO; + } + + if (buffer_type != type) { + LOG_WRN("Expected type %c but got %c", type, buffer_type); + return -EIO; + } + + if (data->read_buffer[0] != EXPLORIR_M_BEGIN_CHAR || + data->read_buffer[2] != EXPLORIR_M_SEPARATOR_CHAR || + data->read_buffer[data->read_index - 2] != EXPLORIR_M_PRE_END_CHAR) { + LOG_HEXDUMP_WRN(data->read_buffer, data->read_index, "Invalid buffer"); + return -EIO; + } + + return 0; +} + +static int explorir_m_buffer_process(struct explorir_m_data *data, char type, + struct sensor_value *val) +{ + if (explorir_m_buffer_verify(data, type) != 0) { + return -EIO; + } + + switch (type) { + case EXPLORIR_M_SET_FILTER_CHAR: + case EXPLORIR_M_MODE_CHAR: + break; + + case EXPLORIR_M_CO2_FILTERED_CHAR: + data->scaling = strtol(&data->read_buffer[EXPLORIR_M_VALUE_INDEX], NULL, 10); + break; + + case EXPLORIR_M_SCALING_CHAR: + data->filtered = strtol(&data->read_buffer[EXPLORIR_M_VALUE_INDEX], NULL, 10); + break; + + case EXPLORIR_M_GET_FILTER_CHAR: + val->val1 = strtol(&data->read_buffer[EXPLORIR_M_VALUE_INDEX], NULL, 10); + break; + + default: + LOG_ERR("Unknown type %c/0x%02x", type, type); + return -EIO; + } + + return 0; +} + +static void explorir_m_uart_isr(const struct device *uart_dev, void *user_data) +{ + const struct device *dev = user_data; + struct explorir_m_data *data = dev->data; + int rc, read_len; + + if (!device_is_ready(uart_dev)) { + LOG_DBG("UART device is not ready"); + return; + } + + if (!uart_irq_update(uart_dev)) { + LOG_DBG("Unable to process interrupts"); + return; + } + + if (!uart_irq_rx_ready(uart_dev)) { + LOG_DBG("No RX data"); + return; + } + + read_len = EXPLORIR_M_BUFFER_LENGTH - data->read_index; + rc = uart_fifo_read(uart_dev, &data->read_buffer[data->read_index], read_len); + + if (rc < 0 || rc == read_len) { + LOG_ERR("UART read failed: %d", rc < 0 ? rc : -ERANGE); + explorir_m_uart_flush(uart_dev); + LOG_HEXDUMP_WRN(data->read_buffer, data->read_index, "Discarding"); + explorir_m_buffer_reset(data); + } else { + data->read_index += rc; + + if (data->read_buffer[data->read_index - 1] != EXPLORIR_M_END_CHAR) { + return; + } + } + + k_sem_give(&data->uart_rx_sem); +} + +static void explorir_m_uart_terminate(const struct device *uart_dev) +{ + uart_poll_out(uart_dev, EXPLORIR_M_PRE_END_CHAR); + uart_poll_out(uart_dev, EXPLORIR_M_END_CHAR); +} + +static int explorir_m_await_receive(struct explorir_m_data *data) +{ + int rc = k_sem_take(&data->uart_rx_sem, K_MSEC(EXPLORIR_M_MAX_RESPONSE_DELAY)); + + /* Reset semaphore if sensor did not respond within maximum specified response time */ + if (rc == -EAGAIN) { + k_sem_reset(&data->uart_rx_sem); + } + + return rc; +} + +static int explorir_m_uart_transceive(const struct device *dev, char type, struct sensor_value *val, + enum explorir_m_uart_set_usage set) +{ + const struct explorir_m_cfg *cfg = dev->config; + struct explorir_m_data *data = dev->data; + char buf[EXPLORIR_M_BUFFER_LENGTH]; + int rc, len; + + if (val == NULL && set != EXPLORIR_M_SET_NONE) { + LOG_ERR("val is NULL but set is not NONE"); + return -EINVAL; + } + + k_mutex_lock(&data->uart_mutex, K_FOREVER); + + explorir_m_buffer_reset(data); + + uart_poll_out(cfg->uart_dev, type); + + if (set == EXPLORIR_M_SET_VAL_ONE) { + len = snprintf(buf, EXPLORIR_M_BUFFER_LENGTH, "%c%u", EXPLORIR_M_SEPARATOR_CHAR, + val->val1); + } else if (set == EXPLORIR_M_SET_VAL_ONE_TWO) { + len = snprintf(buf, EXPLORIR_M_BUFFER_LENGTH, "%c%u%c%u", EXPLORIR_M_SEPARATOR_CHAR, + val->val1, EXPLORIR_M_SEPARATOR_CHAR, val->val2); + } else { + len = 0; + } + + if (len == EXPLORIR_M_BUFFER_LENGTH) { + LOG_WRN("Set value truncated"); + } + for (int i = 0; i != len; i++) { + uart_poll_out(cfg->uart_dev, buf[i]); + } + + explorir_m_uart_terminate(cfg->uart_dev); + + rc = explorir_m_await_receive(data); + if (rc != 0) { + LOG_WRN("%c did not receive a response: %d", type, rc); + } + + if (rc == 0) { + rc = explorir_m_buffer_process(data, type, val); + } + + k_mutex_unlock(&data->uart_mutex); + + return rc; +} + +static int explorir_m_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + if (chan != SENSOR_CHAN_CO2) { + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_EXPLORIR_M_FILTER: + return explorir_m_uart_transceive(dev, EXPLORIR_M_GET_FILTER_CHAR, val, + EXPLORIR_M_SET_NONE); + default: + return -ENOTSUP; + } +} + +static int explorir_m_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + if (chan != SENSOR_CHAN_CO2) { + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_EXPLORIR_M_FILTER: + if (val->val1 < 0 || val->val1 > 255) { + return -ERANGE; + } + return explorir_m_uart_transceive(dev, EXPLORIR_M_SET_FILTER_CHAR, + (struct sensor_value *)val, + EXPLORIR_M_SET_VAL_ONE); + default: + return -ENOTSUP; + } +} + +static int explorir_m_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + if (chan != SENSOR_CHAN_CO2 && chan != SENSOR_CHAN_ALL) { + return -ENOTSUP; + } + + return explorir_m_uart_transceive(dev, EXPLORIR_M_CO2_FILTERED_CHAR, NULL, + EXPLORIR_M_SET_NONE); +} + +static int explorir_m_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct explorir_m_data *data = dev->data; + + if (chan != SENSOR_CHAN_CO2) { + return -ENOTSUP; + } + + if (k_uptime_get() < EXPLORIR_M_CO2_VALID_DELAY) { + return -EAGAIN; + } + + val->val1 = data->filtered * data->scaling; + val->val2 = 0; + + return 0; +} + +static const struct sensor_driver_api explorir_m_api_funcs = { + .attr_set = explorir_m_attr_set, + .attr_get = explorir_m_attr_get, + .sample_fetch = explorir_m_sample_fetch, + .channel_get = explorir_m_channel_get, +}; + +static int explorir_m_init(const struct device *dev) +{ + const struct explorir_m_cfg *cfg = dev->config; + struct explorir_m_data *data = dev->data; + struct sensor_value val; + int rc; + + LOG_DBG("Initializing %s", dev->name); + + if (!device_is_ready(cfg->uart_dev)) { + return -ENODEV; + } + + k_mutex_init(&data->uart_mutex); + k_sem_init(&data->uart_rx_sem, 0, 1); + + uart_irq_rx_disable(cfg->uart_dev); + uart_irq_tx_disable(cfg->uart_dev); + + rc = uart_irq_callback_user_data_set(cfg->uart_dev, cfg->cb, (void *)dev); + if (rc != 0) { + LOG_ERR("UART IRQ setup failed: %d", rc); + return rc; + } + + /* Terminate garbled tx due to GPIO setup or crash during unfinished send */ + explorir_m_uart_terminate(cfg->uart_dev); + explorir_m_uart_flush_until_end(cfg->uart_dev); + + uart_irq_rx_enable(cfg->uart_dev); + + val.val1 = EXPLORIR_M_MODE_POLL; + explorir_m_uart_transceive(dev, EXPLORIR_M_MODE_CHAR, &val, EXPLORIR_M_SET_VAL_ONE); + explorir_m_uart_transceive(dev, EXPLORIR_M_SCALING_CHAR, NULL, EXPLORIR_M_SET_NONE); + + return rc; +} + +#define EXPLORIR_M_INIT(n) \ + \ + static struct explorir_m_data explorir_m_data_##n; \ + \ + static const struct explorir_m_cfg explorir_m_cfg_##n = { \ + .uart_dev = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .cb = explorir_m_uart_isr, \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, explorir_m_init, NULL, &explorir_m_data_##n, \ + &explorir_m_cfg_##n, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &explorir_m_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(EXPLORIR_M_INIT) diff --git a/include/zephyr/drivers/sensor/explorir_m.h b/include/zephyr/drivers/sensor/explorir_m.h new file mode 100644 index 00000000000..efef562447c --- /dev/null +++ b/include/zephyr/drivers/sensor/explorir_m.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023, Vitrolife A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_EXPLORIR_M_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_EXPLORIR_M_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum sensor_attribute_explorir_m { + /* Sensor integrated low-pass filter. Values 16, 32, 64, and 128 is allowed */ + SENSOR_ATTR_EXPLORIR_M_FILTER = SENSOR_ATTR_PRIV_START, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_EXPLORIR_M_H_ */ From 171dbd0435a0fd50303523bb147896f473d412b3 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Fri, 27 Oct 2023 15:23:46 +0200 Subject: [PATCH 3514/4498] samples: sensors: add generic co2 sensor polling Add polling sample for any CO2 sensor. Signed-off-by: Jeppe Odgaard --- samples/sensor/co2_polling/CMakeLists.txt | 7 ++++ samples/sensor/co2_polling/README.rst | 30 +++++++++++++++++ .../co2_polling/boards/nucleo_h563zi.conf | 1 + .../co2_polling/boards/nucleo_h563zi.overlay | 15 +++++++++ samples/sensor/co2_polling/prj.conf | 7 ++++ samples/sensor/co2_polling/sample.yaml | 8 +++++ samples/sensor/co2_polling/src/main.c | 33 +++++++++++++++++++ 7 files changed, 101 insertions(+) create mode 100644 samples/sensor/co2_polling/CMakeLists.txt create mode 100644 samples/sensor/co2_polling/README.rst create mode 100644 samples/sensor/co2_polling/boards/nucleo_h563zi.conf create mode 100644 samples/sensor/co2_polling/boards/nucleo_h563zi.overlay create mode 100644 samples/sensor/co2_polling/prj.conf create mode 100644 samples/sensor/co2_polling/sample.yaml create mode 100644 samples/sensor/co2_polling/src/main.c diff --git a/samples/sensor/co2_polling/CMakeLists.txt b/samples/sensor/co2_polling/CMakeLists.txt new file mode 100644 index 00000000000..ae467b6d2aa --- /dev/null +++ b/samples/sensor/co2_polling/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(co2_polling) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/sensor/co2_polling/README.rst b/samples/sensor/co2_polling/README.rst new file mode 100644 index 00000000000..c0436b363ac --- /dev/null +++ b/samples/sensor/co2_polling/README.rst @@ -0,0 +1,30 @@ +.. co2: + +Generic CO2 polling sample +########################## + +Overview +******** + +A sensor sample that demonstrates how to poll a CO2 sensor. + +Building and Running +******************** + +This sample reads the CO2 sensor and print the values continuously. + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/co2_polling + :board: + :goals: build flash + :compact: + +Sample Output +============= + +.. code-block:: console + + CO2 940 ppm + CO2 950 ppm + + diff --git a/samples/sensor/co2_polling/boards/nucleo_h563zi.conf b/samples/sensor/co2_polling/boards/nucleo_h563zi.conf new file mode 100644 index 00000000000..86df0aff3e6 --- /dev/null +++ b/samples/sensor/co2_polling/boards/nucleo_h563zi.conf @@ -0,0 +1 @@ +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/samples/sensor/co2_polling/boards/nucleo_h563zi.overlay b/samples/sensor/co2_polling/boards/nucleo_h563zi.overlay new file mode 100644 index 00000000000..549e3492699 --- /dev/null +++ b/samples/sensor/co2_polling/boards/nucleo_h563zi.overlay @@ -0,0 +1,15 @@ +/ { + aliases { + co2 = &explorir_m; + }; +}; + +&lpuart1 { + status = "okay"; + current-speed = <9600>; + + explorir_m: explorir_m { + compatible = "gss,explorir-m"; + status = "okay"; + }; +}; diff --git a/samples/sensor/co2_polling/prj.conf b/samples/sensor/co2_polling/prj.conf new file mode 100644 index 00000000000..fe480d2b794 --- /dev/null +++ b/samples/sensor/co2_polling/prj.conf @@ -0,0 +1,7 @@ +CONFIG_STDOUT_CONSOLE=y +CONFIG_LOG=y +CONFIG_SHELL=y +CONFIG_SENSOR_SHELL=y +CONFIG_SERIAL=y +CONFIG_SENSOR=y +CONFIG_SENSOR_LOG_LEVEL_DBG=y diff --git a/samples/sensor/co2_polling/sample.yaml b/samples/sensor/co2_polling/sample.yaml new file mode 100644 index 00000000000..13b4ffa6dfb --- /dev/null +++ b/samples/sensor/co2_polling/sample.yaml @@ -0,0 +1,8 @@ +sample: + name: CO2 sensor sample +tests: + sample.sensor.co2: + harness: sensor + tags: sensors + filter: dt_alias_exists("co2") + depends_on: serial uart_interrupt_driven diff --git a/samples/sensor/co2_polling/src/main.c b/samples/sensor/co2_polling/src/main.c new file mode 100644 index 00000000000..4f184527453 --- /dev/null +++ b/samples/sensor/co2_polling/src/main.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Vitrolife A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +LOG_MODULE_REGISTER(MAIN); + +int main(void) +{ + struct sensor_value value; + const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(co2)); + + if (!device_is_ready(dev)) { + LOG_ERR("%s is not ready", dev->name); + return 0; + } + + while (1) { + if (sensor_sample_fetch(dev) == 0 && + sensor_channel_get(dev, SENSOR_CHAN_CO2, &value) == 0) { + LOG_INF("CO2 %d ppm", value.val1); + } + + k_msleep(1000); + } + + return 0; +} From a1b16d3151c061af270744bc44e09e6b8ec2e7b6 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Thu, 26 Oct 2023 15:59:37 +0200 Subject: [PATCH 3515/4498] tests: build_all: sensor: i2c: add explorir_m Add ExplorIR-M uart node in the build_all tests. Signed-off-by: Jeppe Odgaard --- tests/drivers/build_all/sensor/uart.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/drivers/build_all/sensor/uart.dtsi b/tests/drivers/build_all/sensor/uart.dtsi index 11b08dd99eb..05a2634f24a 100644 --- a/tests/drivers/build_all/sensor/uart.dtsi +++ b/tests/drivers/build_all/sensor/uart.dtsi @@ -30,3 +30,7 @@ grow_r502a { test_uart_a01nyub: a01nyub { compatible = "dfrobot,a01nyub"; }; + +test_uart_explorir_m: explorir-m { + compatible = "gss,explorir-m"; +}; From a2a18e3fa4196e45edb006153da1959f854ec134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 7 Nov 2023 17:51:33 +0100 Subject: [PATCH 3516/4498] doc: pdf: Add Glossary of Terms to PDF output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the Glossary page to the PDF so that :term: roles are properly resolved. Signed-off-by: Benjamin Cabé --- doc/index-tex.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/index-tex.rst b/doc/index-tex.rst index 09ef9e9459e..9c0527ae73a 100644 --- a/doc/index-tex.rst +++ b/doc/index-tex.rst @@ -24,3 +24,4 @@ Zephyr Project Documentation project/index.rst security/index.rst safety/index.rst + glossary.rst From 434a40470c904cb40b8e1b128e5f1a180a993bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 9 Nov 2023 18:00:57 +0700 Subject: [PATCH 3517/4498] drivers: mbox: nxp_s32: use instance-based DT macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles --- drivers/mbox/mbox_nxp_s32_mru.c | 91 ++++++++++++--------------------- soc/arm/nxp_s32/s32ze/soc.h | 10 ++++ 2 files changed, 44 insertions(+), 57 deletions(-) diff --git a/drivers/mbox/mbox_nxp_s32_mru.c b/drivers/mbox/mbox_nxp_s32_mru.c index 287ba89eff8..8981e260d50 100644 --- a/drivers/mbox/mbox_nxp_s32_mru.c +++ b/drivers/mbox/mbox_nxp_s32_mru.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT nxp_s32_mru + #include #include #include @@ -19,22 +21,11 @@ LOG_MODULE_REGISTER(nxp_s32_mru); #define MRU_MBOX_SIZE 4 #define MRU_CHANNEL_OFFSET 0x1000 -#define MRU_NODE(n) DT_NODELABEL(mru##n) -#define MRU_BASE(n) ((RTU_MRU_Type *)DT_REG_ADDR(MRU_NODE(n))) -#define MRU_RX_CHANNELS(n) DT_PROP_OR(MRU_NODE(n), rx_channels, 0) -#define MRU_MBOX_ADDR(n, ch, mb) \ - (DT_REG_ADDR(MRU_NODE(n)) + ((ch + 1) * MRU_CHANNEL_OFFSET) + (MRU_MBOX_SIZE * mb)) - /* Utility macros to convert from GIC index to interrupt group index */ #define _MRU_IRQ_17 MRU_IP_INT_GROUP_0 #define _MRU_IRQ_18 MRU_IP_INT_GROUP_1 #define MRU_INT_GROUP(irq) _CONCAT(_MRU_IRQ_, irq) -#define _CONCAT7(...) DT_CAT7(__VA_ARGS__) -#define MRU_ISR_FUNC(n) \ - _CONCAT7(Mru_Ip_RTU, CONFIG_NXP_S32_RTU_INDEX, _MRU, n, _Int, \ - MRU_INT_GROUP(DT_IRQN(MRU_NODE(n))), _IRQHandler) - struct nxp_s32_mru_data { mbox_callback_t cb[MRU_MAX_CHANNELS]; void *user_data[MRU_MAX_CHANNELS]; @@ -44,6 +35,7 @@ struct nxp_s32_mru_config { RTU_MRU_Type *base; Mru_Ip_ConfigType hw_cfg; void (*config_irq)(void); + uint8_t irq_group; }; static inline bool is_rx_channel_valid(const struct device *dev, uint32_t ch) @@ -178,6 +170,13 @@ static int nxp_s32_mru_init(const struct device *dev) return 0; } +void nxp_s32_mru_isr(const struct device *dev) +{ + const struct nxp_s32_mru_config *config = dev->config; + + Mru_Ip_IrqHandler(config->hw_cfg.InstanceId, config->irq_group); +} + static const struct mbox_driver_api nxp_s32_mru_driver_api = { .send = nxp_s32_mru_send, .register_callback = nxp_s32_mru_register_callback, @@ -186,18 +185,26 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { .set_enabled = nxp_s32_mru_set_enabled, }; -#define MRU_ISR_FUNC_DECLARE(n) extern void MRU_ISR_FUNC(n)(void) +#define MRU_BASE(n) ((RTU_MRU_Type *)DT_INST_REG_ADDR(n)) +#define MRU_RX_CHANNELS(n) DT_INST_PROP_OR(n, rx_channels, 0) +#define MRU_MBOX_ADDR(n, ch, mb) \ + (DT_INST_REG_ADDR(n) + ((ch + 1) * MRU_CHANNEL_OFFSET) + (MRU_MBOX_SIZE * mb)) + +#define MRU_HW_INSTANCE_CHECK(i, n) \ + ((DT_INST_REG_ADDR(n) == IP_MRU_##i##_BASE) ? i : 0) + +#define MRU_HW_INSTANCE(n) \ + LISTIFY(__DEBRACKET RTU_MRU_INSTANCE_COUNT, MRU_HW_INSTANCE_CHECK, (|), n) #define MRU_INIT_IRQ_FUNC(n) \ - MRU_ISR_FUNC_DECLARE(n); \ static void nxp_s32_mru_##n##_init_irq(void) \ { \ - IRQ_CONNECT(DT_IRQN(MRU_NODE(n)), \ - DT_IRQ(MRU_NODE(n), priority), \ - MRU_ISR_FUNC(n), \ - NULL, \ - DT_IRQ(MRU_NODE(n), flags)); \ - irq_enable(DT_IRQN(MRU_NODE(n))); \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + nxp_s32_mru_isr, \ + DEVICE_DT_INST_GET(n), \ + DT_INST_IRQ(n, flags)); \ + irq_enable(DT_INST_IRQN(n)); \ } #define MRU_CH_RX_CFG(i, n) \ @@ -208,7 +215,6 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { static uint32_t nxp_s32_mru_##n##_ch_##i##_buf[MRU_MAX_MBOX_PER_CHAN]; \ static const Mru_Ip_ReceiveChannelType nxp_s32_mru_##n##_ch_##i##_rx_cfg = { \ .ChannelId = i, \ - .InstanceId = n, \ .ChannelIndex = i, \ .NumRxMB = MRU_MAX_MBOX_PER_CHAN, \ .MBAddList = nxp_s32_mru_##n##_ch_##i##_rx_mbox_addr, \ @@ -224,7 +230,7 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { #define MRU_CH_RX_LINK_CFG(i, n) \ static const Mru_Ip_MBLinkReceiveChannelType \ nxp_s32_mru_##n##_ch_##i##_rx_link_cfg[MRU_MAX_MBOX_PER_CHAN][MRU_MAX_INT_GROUPS] = {\ - MRU_CH_RX_LINK_CFG_MBOX(0, n, i, MRU_INT_GROUP(DT_IRQN(MRU_NODE(n)))) \ + MRU_CH_RX_LINK_CFG_MBOX(0, n, i, MRU_INT_GROUP(DT_INST_IRQN(n))) \ } #define MRU_CH_CFG(i, n) \ @@ -232,7 +238,7 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { .ChCFG0Add = &MRU_BASE(n)->CHXCONFIG[i].CH_CFG0, \ .ChCFG0 = RTU_MRU_CH_CFG0_IE(0) | RTU_MRU_CH_CFG0_MBE0(0), \ .ChCFG1Add = &MRU_BASE(n)->CHXCONFIG[i].CH_CFG1, \ - .ChCFG1 = RTU_MRU_CH_CFG1_MBIC0(MRU_INT_GROUP(DT_IRQN(MRU_NODE(n)))), \ + .ChCFG1 = RTU_MRU_CH_CFG1_MBIC0(MRU_INT_GROUP(DT_INST_IRQN(n))), \ .ChMBSTATAdd = &MRU_BASE(n)->CHXCONFIG[i].CH_MBSTAT, \ .NumMailbox = MRU_MAX_MBOX_PER_CHAN, \ .MBLinkReceiveChCfg = nxp_s32_mru_##n##_ch_##i##_rx_link_cfg \ @@ -242,7 +248,7 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { #define MRU_CALLBACK_WRAPPER_FUNC(n) \ void nxp_s32_mru_##n##_cb(uint8_t channel, const uint32_t *buf, uint8_t mbox_count) \ { \ - const struct device *dev = DEVICE_DT_GET(MRU_NODE(n)); \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ struct nxp_s32_mru_data *data = dev->data; \ \ if (is_rx_channel_valid(dev, channel)) { \ @@ -271,7 +277,7 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { static struct nxp_s32_mru_config nxp_s32_mru_##n##_config = { \ .base = MRU_BASE(n), \ .hw_cfg = { \ - .InstanceId = n, \ + .InstanceId = MRU_HW_INSTANCE(n), \ .StateIndex = n, \ .NumChannel = MRU_RX_CHANNELS(n), \ .ChannelCfg = COND_CODE_0(MRU_RX_CHANNELS(n), \ @@ -281,43 +287,14 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { &MRU_BASE(n)->NOTIFY1 \ }, \ }, \ + .irq_group = MRU_INT_GROUP(DT_INST_IRQN(n)), \ .config_irq = COND_CODE_0(MRU_RX_CHANNELS(n), \ (NULL), (nxp_s32_mru_##n##_init_irq)), \ }; \ \ - DEVICE_DT_DEFINE(MRU_NODE(n), nxp_s32_mru_init, NULL, \ + DEVICE_DT_INST_DEFINE(n, nxp_s32_mru_init, NULL, \ &nxp_s32_mru_##n##_data, &nxp_s32_mru_##n##_config, \ POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY, \ - &nxp_s32_mru_driver_api) - -#if DT_NODE_HAS_STATUS(MRU_NODE(0), okay) -MRU_INSTANCE_DEFINE(0); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(1), okay) -MRU_INSTANCE_DEFINE(1); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(2), okay) -MRU_INSTANCE_DEFINE(2); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(3), okay) -MRU_INSTANCE_DEFINE(3); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(4), okay) -MRU_INSTANCE_DEFINE(4); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(5), okay) -MRU_INSTANCE_DEFINE(5); -#endif - -#if DT_NODE_HAS_STATUS(MRU_NODE(6), okay) -MRU_INSTANCE_DEFINE(6); -#endif + &nxp_s32_mru_driver_api); -#if DT_NODE_HAS_STATUS(MRU_NODE(7), okay) -MRU_INSTANCE_DEFINE(7); -#endif +DT_INST_FOREACH_STATUS_OKAY(MRU_INSTANCE_DEFINE) diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index 17289511f7d..1a3ea631173 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -51,4 +51,14 @@ /* NETC */ #define IP_NETC_EMDIO_0_BASE IP_NETC__EMDIO_BASE_BASE +/* MRU */ +#define IP_MRU_0_BASE IP_RTU0__MRU_0_BASE +#define IP_MRU_1_BASE IP_RTU0__MRU_1_BASE +#define IP_MRU_2_BASE IP_RTU0__MRU_2_BASE +#define IP_MRU_3_BASE IP_RTU0__MRU_3_BASE +#define IP_MRU_4_BASE IP_RTU1__MRU_0_BASE +#define IP_MRU_5_BASE IP_RTU1__MRU_1_BASE +#define IP_MRU_6_BASE IP_RTU1__MRU_2_BASE +#define IP_MRU_7_BASE IP_RTU1__MRU_3_BASE + #endif /* _NXP_S32_S32ZE_SOC_H_ */ From c9e6ac54d63875bfd463cf8f1eb3d3710de141a4 Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Sat, 11 Nov 2023 11:05:09 -0300 Subject: [PATCH 3518/4498] samples: maxim_ds3231: increase variable size in min_alarm_handler Change the variable name from **us** to **ms** and increase its size to **uint16_t** within the min_alarm_handler function. This update allows the function to correctly handle the millisecond values in the range of 0 to 999. Signed-off-by: Charles Dias --- samples/drivers/counter/maxim_ds3231/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/drivers/counter/maxim_ds3231/src/main.c b/samples/drivers/counter/maxim_ds3231/src/main.c index 32c37c17188..992283ef343 100644 --- a/samples/drivers/counter/maxim_ds3231/src/main.c +++ b/samples/drivers/counter/maxim_ds3231/src/main.c @@ -105,7 +105,7 @@ static void min_alarm_handler(const struct device *dev, (void)counter_get_value(dev, &time); uint32_t uptime = k_uptime_get_32(); - uint8_t us = uptime % 1000U; + uint16_t ms = uptime % 1000U; uptime /= 1000U; uint8_t se = uptime % 60U; @@ -143,7 +143,7 @@ static void min_alarm_handler(const struct device *dev, printk("%s: adj %d.%09lu, uptime %u:%02u:%02u.%03u, clk err %d ppm\n", format_time(time, -1), (uint32_t)(ts->tv_sec - time), ts->tv_nsec, - hr, mn, se, us, err_ppm); + hr, mn, se, ms, err_ppm); } struct maxim_ds3231_alarm sec_alarm; From 56dd8f90cd4d49c3bef04d3176fc83cb29e85752 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Tue, 31 Oct 2023 16:29:23 +0100 Subject: [PATCH 3519/4498] tests: drivers: i2c: i2c_target_api add stm32f3_disco Adds stm32f3_disco in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- tests/drivers/i2c/i2c_target_api/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index a6113986274..fe3531dde65 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -14,6 +14,7 @@ tests: - nucleo_g474re - nucleo_f091rc - stm32f072b_disco + - stm32f3_disco - nucleo_g071rb - nucleo_f207zg - nucleo_f429zi From c19ba8ffe9e9d5becd12ae14f568bf9c4c543ef0 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Tue, 31 Oct 2023 16:31:48 +0100 Subject: [PATCH 3520/4498] tests: drivers: i2c: i2c_target_api add stm32f3_disco Adds necessary overlay stm32f3_disco in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- .../i2c_target_api/boards/stm32f3_disco.conf | 2 ++ .../boards/stm32f3_disco.overlay | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.conf create mode 100644 tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.conf b/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.conf new file mode 100644 index 00000000000..34b2571d125 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.conf @@ -0,0 +1,2 @@ +CONFIG_I2C_STM32_INTERRUPT=y +CONFIG_I2C_VIRTUAL=n diff --git a/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.overlay b/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.overlay new file mode 100644 index 00000000000..b23520b04ac --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/stm32f3_disco.overlay @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* I2C bus pins are exposed on the ST P2 connector. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB7 P2:21 PB6 P2:22 + * i2c2 PA10 P2:43 PA9 P2:44 + * + * Short Pin PB7 to PA10, and PB6 to PA9, for the test to pass. + */ + + + +&i2c1 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <1024>; + }; +}; + +&i2c2 { + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <1024>; + }; + +}; From 04e18f093fde6ed2671f52c3f373edf546259783 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 10 Nov 2023 13:19:07 +0000 Subject: [PATCH 3521/4498] drivers: regulator: Added startup and off/on delay to common driver A configurable delay during regulator switch on is currently only supported by the GPIO and fixed regulator drivers. This functionality has been moved to the common driver, so it can be easily added to any regulator driver. Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_common.c | 22 ++++++++++++++----- drivers/regulator/regulator_fixed.c | 15 ------------- drivers/regulator/regulator_gpio.c | 11 ---------- .../regulator/nordic,npm1300-regulator.yaml | 2 ++ dts/bindings/regulator/regulator-fixed.yaml | 12 ++-------- dts/bindings/regulator/regulator-gpio.yaml | 5 +---- dts/bindings/regulator/regulator.yaml | 8 +++++++ include/zephyr/drivers/regulator.h | 6 +++++ 8 files changed, 36 insertions(+), 45 deletions(-) diff --git a/drivers/regulator/regulator_common.c b/drivers/regulator/regulator_common.c index adbacddac12..7f33040d2d9 100644 --- a/drivers/regulator/regulator_common.c +++ b/drivers/regulator/regulator_common.c @@ -3,8 +3,20 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include +static void regulator_delay(uint32_t delay_us) +{ + if (delay_us > 0U) { +#ifdef CONFIG_MULTITHREADING + k_sleep(K_USEC(delay_us)); +#else + k_busy_wait(delay_us); +#endif + } +} + void regulator_common_data_init(const struct device *dev) { struct regulator_common_data *data = dev->data; @@ -67,6 +79,7 @@ int regulator_common_init(const struct device *dev, bool is_enabled) return ret; } + regulator_delay(config->startup_delay_us); data->refcnt++; } @@ -94,12 +107,11 @@ int regulator_enable(const struct device *dev) (void)k_mutex_lock(&data->lock, K_FOREVER); #endif - data->refcnt++; - - if (data->refcnt == 1) { + if (data->refcnt == 0) { ret = api->enable(dev); - if (ret < 0) { - data->refcnt--; + if (ret == 0) { + data->refcnt++; + regulator_delay(config->off_on_delay_us); } } diff --git a/drivers/regulator/regulator_fixed.c b/drivers/regulator/regulator_fixed.c index 4526b6d2378..c0b58273987 100644 --- a/drivers/regulator/regulator_fixed.c +++ b/drivers/regulator/regulator_fixed.c @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -18,8 +17,6 @@ LOG_MODULE_REGISTER(regulator_fixed, CONFIG_REGULATOR_LOG_LEVEL); struct regulator_fixed_config { struct regulator_common_config common; - uint32_t startup_delay_us; - uint32_t off_on_delay_us; struct gpio_dt_spec enable; }; @@ -41,14 +38,6 @@ static int regulator_fixed_enable(const struct device *dev) return ret; } - if (cfg->off_on_delay_us > 0U) { -#ifdef CONFIG_MULTITHREADING - k_sleep(K_USEC(cfg->off_on_delay_us)); -#else - k_busy_wait(cfg->off_on_delay_us); -#endif - } - return 0; } @@ -113,8 +102,6 @@ static int regulator_fixed_init(const struct device *dev) if (ret < 0) { return ret; } - - k_busy_wait(cfg->startup_delay_us); } else { ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT_INACTIVE); if (ret < 0) { @@ -134,8 +121,6 @@ static int regulator_fixed_init(const struct device *dev) \ static const struct regulator_fixed_config config##inst = { \ .common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst), \ - .startup_delay_us = DT_INST_PROP(inst, startup_delay_us), \ - .off_on_delay_us = DT_INST_PROP(inst, off_on_delay_us), \ .enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}), \ }; \ \ diff --git a/drivers/regulator/regulator_gpio.c b/drivers/regulator/regulator_gpio.c index e752a9ad457..49d373897b3 100644 --- a/drivers/regulator/regulator_gpio.c +++ b/drivers/regulator/regulator_gpio.c @@ -7,7 +7,6 @@ #include -#include #include #include #include @@ -24,7 +23,6 @@ struct regulator_gpio_config { uint8_t states_cnt; const struct gpio_dt_spec enable; - int32_t startup_delay_us; }; struct regulator_gpio_data { @@ -73,14 +71,6 @@ static int regulator_gpio_enable(const struct device *dev) return ret; } - if (cfg->startup_delay_us > 0U) { -#ifdef CONFIG_MULTITHREADING - k_sleep(K_USEC(cfg->startup_delay_us)); -#else - k_busy_wait(cfg->startup_delay_us); -#endif - } - return 0; } @@ -233,7 +223,6 @@ static int regulator_gpio_init(const struct device *dev) .enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}), \ .states = ((const int[])DT_INST_PROP(inst, states)), \ .states_cnt = DT_INST_PROP_LEN(inst, states) / 2, \ - .startup_delay_us = DT_INST_PROP_OR(inst, startup_delay_us, 0), \ }; \ DEVICE_DT_INST_DEFINE(inst, regulator_gpio_init, NULL, &data##inst, &config##inst, \ POST_KERNEL, CONFIG_REGULATOR_GPIO_INIT_PRIORITY, \ diff --git a/dts/bindings/regulator/nordic,npm1300-regulator.yaml b/dts/bindings/regulator/nordic,npm1300-regulator.yaml index cbd62671f15..c5364a49fe0 100644 --- a/dts/bindings/regulator/nordic,npm1300-regulator.yaml +++ b/dts/bindings/regulator/nordic,npm1300-regulator.yaml @@ -60,6 +60,8 @@ child-binding: - regulator-initial-mode - regulator-min-microamp - regulator-max-microamp + - startup-delay-us + - off-on-delay-us properties: retention-microvolt: diff --git a/dts/bindings/regulator/regulator-fixed.yaml b/dts/bindings/regulator/regulator-fixed.yaml index 1033d333f08..4f3236d8c6c 100644 --- a/dts/bindings/regulator/regulator-fixed.yaml +++ b/dts/bindings/regulator/regulator-fixed.yaml @@ -13,6 +13,8 @@ include: - regulator-always-on - regulator-min-microvolt - regulator-max-microvolt + - startup-delay-us + - off-on-delay-us compatible: "regulator-fixed" @@ -29,13 +31,3 @@ properties: provide the GPIO polarity and open-drain status in the phandle selector. The Linux enable-active-high and gpio-open-drain properties are not valid for Zephyr devicetree files. - - startup-delay-us: - type: int - default: 0 - description: Startup time, in microseconds - - off-on-delay-us: - type: int - default: 0 - description: Off delay time, in microseconds diff --git a/dts/bindings/regulator/regulator-gpio.yaml b/dts/bindings/regulator/regulator-gpio.yaml index aa7aeb44eee..15c419a0043 100644 --- a/dts/bindings/regulator/regulator-gpio.yaml +++ b/dts/bindings/regulator/regulator-gpio.yaml @@ -34,6 +34,7 @@ include: - regulator-max-microvolt - regulator-always-on - regulator-boot-on + - startup-delay-us compatible: "regulator-gpio" @@ -70,7 +71,3 @@ properties: Example: enable-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; - - startup-delay-us: - type: int - description: startup time in microseconds diff --git a/dts/bindings/regulator/regulator.yaml b/dts/bindings/regulator/regulator.yaml index 067133aa97e..167355d9224 100644 --- a/dts/bindings/regulator/regulator.yaml +++ b/dts/bindings/regulator/regulator.yaml @@ -256,3 +256,11 @@ properties: description: | Maximum difference between current and target voltages that can be changed safely in a single step. + + startup-delay-us: + type: int + description: Startup time, in microseconds + + off-on-delay-us: + type: int + description: Off to on delay time, in microseconds diff --git a/include/zephyr/drivers/regulator.h b/include/zephyr/drivers/regulator.h index 77dd6d76b60..bad9de28239 100644 --- a/include/zephyr/drivers/regulator.h +++ b/include/zephyr/drivers/regulator.h @@ -140,6 +140,10 @@ struct regulator_common_config { int32_t min_ua; /** Maximum allowed current, in microamps. */ int32_t max_ua; + /** Startup delay, in microseconds. */ + uint32_t startup_delay_us; + /** Off to on delay, in microseconds. */ + uint32_t off_on_delay_us; /** Allowed modes */ const regulator_mode_t *allowed_modes; /** Number of allowed modes */ @@ -167,6 +171,8 @@ struct regulator_common_config { INT32_MIN), \ .max_ua = DT_PROP_OR(node_id, regulator_max_microamp, \ INT32_MAX), \ + .startup_delay_us = DT_PROP_OR(node_id, startup_delay_us, 0), \ + .off_on_delay_us = DT_PROP_OR(node_id, off_on_delay_us, 0), \ .allowed_modes = (const regulator_mode_t []) \ DT_PROP_OR(node_id, regulator_allowed_modes, {}), \ .allowed_modes_cnt = \ From 6de2900eec7ebb7d897c9d6dc388a5080d94b45d Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 30 Oct 2023 10:15:22 +0100 Subject: [PATCH 3522/4498] boards: arm: b_u585i_iot02a: add i2c Adds i2c on b_u585i_iot02a to use the i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml index 9faefebf0bc..27ba601cae5 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.yaml @@ -22,4 +22,5 @@ supported: - backup_sram - pwm - counter + - i2c vendor: st From 619d2fd887ca0c5492a3da2e3d352e59b4821fdc Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 30 Oct 2023 10:19:36 +0100 Subject: [PATCH 3523/4498] tests: drivers: i2c: i2c_target_api add b_u585i_iot02a Adds b_u585i_iot02a in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- tests/drivers/i2c/i2c_target_api/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index fe3531dde65..3254e3d74f2 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -10,6 +10,7 @@ common: tests: drivers.i2c.target_api.dual_role: platform_allow: + - b_u585i_iot02a - nucleo_f746zg - nucleo_g474re - nucleo_f091rc From c1a6cfdf9bd8c3aa1f5af589f5181ec5dfefe3af Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 30 Oct 2023 10:21:48 +0100 Subject: [PATCH 3524/4498] tests: drivers: i2c: i2c_target_api add b_u585i_iot02a Adds necessary overlay b_u585i_iot02a in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- .../i2c_target_api/boards/b_u585i_iot02a.conf | 2 ++ .../boards/b_u585i_iot02a.overlay | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.conf create mode 100644 tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.conf b/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.conf new file mode 100644 index 00000000000..34b2571d125 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.conf @@ -0,0 +1,2 @@ +CONFIG_I2C_STM32_INTERRUPT=y +CONFIG_I2C_VIRTUAL=n diff --git a/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.overlay b/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.overlay new file mode 100644 index 00000000000..f07d43230e9 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/b_u585i_iot02a.overlay @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* I2C bus pins are exposed on the STMod+. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB9 CN3:10 PB8 CN3:7 + * i2c2 PH5 CN2:10 PH4 CN2:7 + * + * Short Pin PB9 to PH5, and PB8 to PH4, for the test to pass. + */ + +&i2c1 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <1024>; + }; +}; + +&i2c2 { + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <1024>; + }; +}; From aa0b8af577e390ce3b4ea6a8365b0cbabb16693e Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Fri, 27 Oct 2023 22:25:49 +0000 Subject: [PATCH 3525/4498] drivers: dma: mcux_mcux_lpc: support hardware triggering The LPC DMA IP offers hardware triggering via a series of SOC-specific signals, often including sources like GPIO pins or hardware timers. Support hardware triggers via the "dma_slot" field of the DMA configuration structure. Currently support is offered for setting the following: - Trigger polarity - Trigger level/edge mode - burst mode - burst length - peripheral request Signed-off-by: Daniel DeGrasse --- drivers/dma/dma_mcux_lpc.c | 26 ++++++++++- include/zephyr/drivers/dma/dma_mcux_lpc.h | 56 +++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 include/zephyr/drivers/dma/dma_mcux_lpc.h diff --git a/drivers/dma/dma_mcux_lpc.c b/drivers/dma/dma_mcux_lpc.c index eb44d4fb5fc..cd45211e678 100644 --- a/drivers/dma/dma_mcux_lpc.c +++ b/drivers/dma/dma_mcux_lpc.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DT_DRV_COMPAT nxp_lpc_dma @@ -554,7 +555,30 @@ static int dma_mcux_lpc_configure(const struct device *dev, uint32_t channel, data->descriptors_queued = true; } - if (is_periph) { + if (config->dma_slot) { + uint32_t cfg_reg = 0; + + /* User supplied manual trigger configuration */ + if (config->dma_slot & LPC_DMA_PERIPH_REQ_EN) { + cfg_reg |= DMA_CHANNEL_CFG_PERIPHREQEN_MASK; + } + if (config->dma_slot & LPC_DMA_HWTRIG_EN) { + /* Setup hardware trigger */ + cfg_reg |= DMA_CHANNEL_CFG_HWTRIGEN_MASK; + if (config->dma_slot & LPC_DMA_TRIGTYPE_LEVEL) { + cfg_reg |= DMA_CHANNEL_CFG_TRIGTYPE_MASK; + } + if (config->dma_slot & LPC_DMA_TRIGPOL_HIGH_RISING) { + cfg_reg |= DMA_CHANNEL_CFG_TRIGPOL_MASK; + } + if (config->dma_slot & LPC_DMA_TRIGBURST) { + cfg_reg |= DMA_CHANNEL_CFG_TRIGBURST_MASK; + cfg_reg |= DMA_CHANNEL_CFG_BURSTPOWER( + LPC_DMA_GET_BURSTPOWER(config->dma_slot)); + } + } + p_handle->base->CHANNEL[p_handle->channel].CFG = cfg_reg; + } else if (is_periph) { DMA_EnableChannelPeriphRq(p_handle->base, p_handle->channel); } else { DMA_DisableChannelPeriphRq(p_handle->base, p_handle->channel); diff --git a/include/zephyr/drivers/dma/dma_mcux_lpc.h b/include/zephyr/drivers/dma/dma_mcux_lpc.h new file mode 100644 index 00000000000..5bae1f8f39e --- /dev/null +++ b/include/zephyr/drivers/dma/dma_mcux_lpc.h @@ -0,0 +1,56 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_DMA_MCUX_LPC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_DMA_DMA_MCUX_LPC_H_ + +/* + * LPC DMA engine channel hardware trigger attributes. + * These attributes can be set to the "dma_slot" field + * in a dma_config structure to configure a channel for + * hardware triggering. + */ + +/* Peripheral request enable. When set, the peripheral + * request line associated with this channel is used to pace DMA transfers. + */ +#define LPC_DMA_PERIPH_REQ_EN BIT(0) + +/* Hardware trigger enable. When set, the hardware trigger connected to this + * channel via INPUTMUX can be used to trigger a transfer + */ +#define LPC_DMA_HWTRIG_EN BIT(1) + +/* HW trigger polarity. When this bit is set, the trigger will be active + * high or rising edge triggered, based on TRIG_TYPE selection + */ +#define LPC_DMA_TRIGPOL_HIGH_RISING BIT(2) + +/* HW trigger type. When this bit is set, the trigger will be level triggered. + * When it is cleared, the hardware trigger will be edge triggered. + */ +#define LPC_DMA_TRIGTYPE_LEVEL BIT(3) + +/* HW trigger burst mode. When set, the hardware trigger will cause a burst + * transfer to occur, the length of which is determined by BURST_POWER. + * When cleared, a single transfer (of the width selected by XFERCFG register) + * will occur. + */ +#define LPC_DMA_TRIGBURST BIT(4) + +/* HW trigger burst power. Note that due to the size limit of the dma_slot + * field, the maximum transfer burst possible is 128. The hardware supports + * up to 1024 transfers in BURSTPOWER. The value set here will result in + * 2^BURSTPOWER transfers occurring. So for BURSTPOWER=3, 8 transfers would + * occur. + */ +#define LPC_DMA_BURSTPOWER(pwr) (((pwr) & 0x7) << 5) + + +/* Used by driver to extract burstpower setting */ +#define LPC_DMA_GET_BURSTPOWER(slot) (((slot) & 0xE0) >> 5) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_DMA_MCUX_LPC_H_ */ From 3548ffe053992e268008f817ddd57d8cdc863378 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 30 Oct 2023 16:12:35 +0100 Subject: [PATCH 3526/4498] tests: drivers: i2c: i2c_target_api add nucleo_wb55rg Adds nucleo_wb55rg in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- tests/drivers/i2c/i2c_target_api/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index 3254e3d74f2..d3c5a408495 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -22,6 +22,7 @@ tests: - nucleo_wl55jc - nucleo_l073rz - nucleo_l152re + - nucleo_wb55rg - rpi_pico - efr32bg22_brd4184a - mr_canhubk3 From 32e1d06a3ccca4149616e824314c235519ed90c5 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 30 Oct 2023 16:15:18 +0100 Subject: [PATCH 3527/4498] tests: drivers: i2c: i2c_target_api add nucleo_wb55rg Adds necessary overlay nucleo_wb55rg in i2c_target_api test case to enables the board. Signed-off-by: Marc Desvaux --- .../i2c_target_api/boards/nucleo_wb55rg.conf | 2 ++ .../boards/nucleo_wb55rg.overlay | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.conf create mode 100644 tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.conf b/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.conf new file mode 100644 index 00000000000..34b2571d125 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.conf @@ -0,0 +1,2 @@ +CONFIG_I2C_STM32_INTERRUPT=y +CONFIG_I2C_VIRTUAL=n diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.overlay b/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.overlay new file mode 100644 index 00000000000..121265cad7c --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_wb55rg.overlay @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* I2C bus pins are exposed on the Arduino Shield Connectors and Morpho connectors. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB9 CN5:9 PB8 CN5:10 + * i2c3 PA7 CN5:4 PB14 CN10:28 + * + * Short Pin PB9 to PA7, and PB8 to PB14, for the test to pass. + */ + +&i2c1 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <1024>; + }; +}; + +&i2c3 { + pinctrl-0 = <&i2c3_scl_pa7 &i2c3_sda_pb14>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <1024>; + }; +}; From 4fe2605160fd535980924a7ea09080c5984fe896 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Sun, 9 Apr 2023 08:47:13 +1200 Subject: [PATCH 3528/4498] drivers: serial: Fix pinctrl usage in NS16550 driver pinctrl-0 property should not be directly referenced in this driver Signed-off-by: Grant Ramsay --- drivers/serial/uart_ns16550.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 5adf0eca645..a41cdca7843 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1371,8 +1371,8 @@ static const struct uart_driver_api uart_ns16550_driver_api = { IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pcp), \ (.pcp = DT_INST_PROP_OR(n, pcp, 0),)) \ .reg_interval = (1 << DT_INST_PROP(n, reg_shift)), \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ - (.pincfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(n)),)) \ + IF_ENABLED(CONFIG_PINCTRL, \ + (.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),)) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, resets), \ (.reset_spec = RESET_DT_SPEC_INST_GET(n),)) @@ -1390,8 +1390,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define UART_NS16550_DEVICE_IO_MMIO_INIT(n) \ UART_NS16550_IRQ_FUNC_DECLARE(n); \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ - (PINCTRL_DT_INST_DEFINE(n))); \ + IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(n))); \ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \ (.port = DT_INST_REG_ADDR(n),), \ @@ -1413,8 +1412,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define UART_NS16550_DEVICE_PCIE_INIT(n) \ UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n); \ DEVICE_PCIE_INST_DECLARE(n); \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ - (PINCTRL_DT_INST_DEFINE(n))); \ + IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(n))); \ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \ DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) \ From 327f75ec3554603c54ed2c6484975dbf2f986f4c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:51:02 +0100 Subject: [PATCH 3529/4498] tests/bluetooth/tester: Enable in native_sim Enable this test in the native_sim target. Signed-off-by: Alberto Escolar Piedras --- tests/bluetooth/tester/boards/native_sim.conf | 3 +++ tests/bluetooth/tester/testcase.yaml | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 tests/bluetooth/tester/boards/native_sim.conf diff --git a/tests/bluetooth/tester/boards/native_sim.conf b/tests/bluetooth/tester/boards/native_sim.conf new file mode 100644 index 00000000000..30abfdbc3d9 --- /dev/null +++ b/tests/bluetooth/tester/boards/native_sim.conf @@ -0,0 +1,3 @@ +CONFIG_UART_PIPE=n +CONFIG_SERIAL=y +CONFIG_UART_NATIVE_POSIX=y diff --git a/tests/bluetooth/tester/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index dba67716af1..8c36291b30f 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -4,6 +4,7 @@ tests: platform_allow: - qemu_x86 - native_posix + - native_sim - nrf52840dk_nrf52840 tags: bluetooth harness: bluetooth @@ -12,6 +13,7 @@ tests: platform_allow: - qemu_x86 - native_posix + - native_sim - nrf5340dk_nrf5340_cpuapp extra_args: OVERLAY_CONFIG="overlay-le-audio.conf" tags: bluetooth @@ -21,6 +23,7 @@ tests: platform_allow: - qemu_x86 - native_posix + - native_sim - nrf52840dk_nrf52840 extra_args: OVERLAY_CONFIG="overlay-mesh.conf" tags: bluetooth @@ -30,6 +33,7 @@ tests: platform_allow: - qemu_x86 - native_posix + - native_sim - nrf52840dk_nrf52840 extra_args: OVERLAY_CONFIG="overlay-mesh.conf;overlay-mesh-v1d1.conf" tags: bluetooth From e444f495406d34f29f4d37305f9d0266e73ff17a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:56:26 +0100 Subject: [PATCH 3530/4498] samples/bluetooth/hap_ha: Enable in native_sim Enable this test in the native_sim target Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/hap_ha/boards/native_sim.conf | 7 +++++++ samples/bluetooth/hap_ha/sample.yaml | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 samples/bluetooth/hap_ha/boards/native_sim.conf diff --git a/samples/bluetooth/hap_ha/boards/native_sim.conf b/samples/bluetooth/hap_ha/boards/native_sim.conf new file mode 100644 index 00000000000..abce1c1111e --- /dev/null +++ b/samples/bluetooth/hap_ha/boards/native_sim.conf @@ -0,0 +1,7 @@ +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_BT_TINYCRYPT_ECC=y + +# For LE-audio at 10ms intervals we need the tick counter to occur more frequently +# than every 10 ms as each PDU for some reason takes 2 ticks to process. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/bluetooth/hap_ha/sample.yaml b/samples/bluetooth/hap_ha/sample.yaml index c9fcfda90ca..3b0fcd53a51 100644 --- a/samples/bluetooth/hap_ha/sample.yaml +++ b/samples/bluetooth/hap_ha/sample.yaml @@ -4,25 +4,33 @@ sample: tests: sample.bluetooth.hap_ha.monaural: harness: bluetooth - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: bluetooth build_only: true sample.bluetooth.hap_ha.monaural_no_presets: harness: bluetooth - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: bluetooth build_only: true extra_configs: - CONFIG_BT_HAS_PRESET_COUNT=0 sample.bluetooth.hap_ha.banded: harness: bluetooth - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: bluetooth extra_args: OVERLAY_CONFIG="banded.conf" build_only: true sample.bluetooth.hap_ha.binaural: harness: bluetooth - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: bluetooth extra_args: OVERLAY_CONFIG="binaural.conf" build_only: true From 49bccb58392ce2780e9d36d04f14edd883b91481 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 14:11:26 +0100 Subject: [PATCH 3531/4498] samples/bluetooth/tmap*: Enable in native_sim Let's enable these samples in the native_sim target. Signed-off-by: Alberto Escolar Piedras --- samples/bluetooth/tmap_bmr/boards/native_sim.conf | 10 ++++++++++ samples/bluetooth/tmap_bmr/sample.yaml | 5 ++++- samples/bluetooth/tmap_bms/boards/native_sim.conf | 10 ++++++++++ samples/bluetooth/tmap_bms/sample.yaml | 5 ++++- samples/bluetooth/tmap_central/boards/native_sim.conf | 10 ++++++++++ samples/bluetooth/tmap_central/sample.yaml | 5 ++++- .../bluetooth/tmap_peripheral/boards/native_sim.conf | 10 ++++++++++ samples/bluetooth/tmap_peripheral/sample.yaml | 10 ++++++++-- 8 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 samples/bluetooth/tmap_bmr/boards/native_sim.conf create mode 100644 samples/bluetooth/tmap_bms/boards/native_sim.conf create mode 100644 samples/bluetooth/tmap_central/boards/native_sim.conf create mode 100644 samples/bluetooth/tmap_peripheral/boards/native_sim.conf diff --git a/samples/bluetooth/tmap_bmr/boards/native_sim.conf b/samples/bluetooth/tmap_bmr/boards/native_sim.conf new file mode 100644 index 00000000000..e06b2999381 --- /dev/null +++ b/samples/bluetooth/tmap_bmr/boards/native_sim.conf @@ -0,0 +1,10 @@ +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_BT_TINYCRYPT_ECC=y + +CONFIG_LIBLC3=y +CONFIG_FPU=y + +# For LE-audio at 10ms intervals we need the tick counter to occur more frequently +# than every 10 ms as each PDU for some reason takes 2 ticks to process. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/bluetooth/tmap_bmr/sample.yaml b/samples/bluetooth/tmap_bmr/sample.yaml index 2427ef9ca82..aaaa5296149 100644 --- a/samples/bluetooth/tmap_bmr/sample.yaml +++ b/samples/bluetooth/tmap_bmr/sample.yaml @@ -4,7 +4,10 @@ sample: tests: sample.bluetooth.tmap_bmr: harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/tmap_bms/boards/native_sim.conf b/samples/bluetooth/tmap_bms/boards/native_sim.conf new file mode 100644 index 00000000000..e06b2999381 --- /dev/null +++ b/samples/bluetooth/tmap_bms/boards/native_sim.conf @@ -0,0 +1,10 @@ +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_BT_TINYCRYPT_ECC=y + +CONFIG_LIBLC3=y +CONFIG_FPU=y + +# For LE-audio at 10ms intervals we need the tick counter to occur more frequently +# than every 10 ms as each PDU for some reason takes 2 ticks to process. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/bluetooth/tmap_bms/sample.yaml b/samples/bluetooth/tmap_bms/sample.yaml index 83bdc86a9a2..fc4410eac0e 100644 --- a/samples/bluetooth/tmap_bms/sample.yaml +++ b/samples/bluetooth/tmap_bms/sample.yaml @@ -4,7 +4,10 @@ sample: tests: sample.bluetooth.tmap_bms: harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/tmap_central/boards/native_sim.conf b/samples/bluetooth/tmap_central/boards/native_sim.conf new file mode 100644 index 00000000000..e06b2999381 --- /dev/null +++ b/samples/bluetooth/tmap_central/boards/native_sim.conf @@ -0,0 +1,10 @@ +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_BT_TINYCRYPT_ECC=y + +CONFIG_LIBLC3=y +CONFIG_FPU=y + +# For LE-audio at 10ms intervals we need the tick counter to occur more frequently +# than every 10 ms as each PDU for some reason takes 2 ticks to process. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/bluetooth/tmap_central/sample.yaml b/samples/bluetooth/tmap_central/sample.yaml index 3d0e1e8a08b..cf4dd362938 100644 --- a/samples/bluetooth/tmap_central/sample.yaml +++ b/samples/bluetooth/tmap_central/sample.yaml @@ -4,7 +4,10 @@ sample: tests: sample.bluetooth.tmap_central: harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 diff --git a/samples/bluetooth/tmap_peripheral/boards/native_sim.conf b/samples/bluetooth/tmap_peripheral/boards/native_sim.conf new file mode 100644 index 00000000000..e06b2999381 --- /dev/null +++ b/samples/bluetooth/tmap_peripheral/boards/native_sim.conf @@ -0,0 +1,10 @@ +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_BT_TINYCRYPT_ECC=y + +CONFIG_LIBLC3=y +CONFIG_FPU=y + +# For LE-audio at 10ms intervals we need the tick counter to occur more frequently +# than every 10 ms as each PDU for some reason takes 2 ticks to process. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/bluetooth/tmap_peripheral/sample.yaml b/samples/bluetooth/tmap_peripheral/sample.yaml index 69f399c5b23..a2762635968 100644 --- a/samples/bluetooth/tmap_peripheral/sample.yaml +++ b/samples/bluetooth/tmap_peripheral/sample.yaml @@ -4,13 +4,19 @@ sample: tests: sample.bluetooth.tmap_peripheral: harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - native_sim tags: bluetooth integration_platforms: - qemu_cortex_m3 sample.bluetooth.tmap_peripheral.duo: harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - native_sim tags: bluetooth extra_args: OVERLAY_CONFIG="duo.conf" extra_configs: From d427169845e6c2b46266965da0d8b732fdfb7576 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 10:48:15 +0100 Subject: [PATCH 3532/4498] docs: bluetooth: Replace reference to native_posix w native_sim Let's replace the references to native_posix with native_sim, Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- .../bluetooth/autopts/autopts-linux.rst | 8 +++---- doc/connectivity/bluetooth/bluetooth-dev.rst | 16 ++++++------- .../bluetooth/bluetooth-tools.rst | 24 +++++++++---------- samples/bluetooth/bluetooth.rst | 4 ++-- samples/bluetooth/hci_uart/README.rst | 8 +++---- samples/bluetooth/hci_uart_async/README.rst | 8 +++---- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/doc/connectivity/bluetooth/autopts/autopts-linux.rst b/doc/connectivity/bluetooth/autopts/autopts-linux.rst index 6388673f025..eac940e9737 100644 --- a/doc/connectivity/bluetooth/autopts/autopts-linux.rst +++ b/doc/connectivity/bluetooth/autopts/autopts-linux.rst @@ -16,11 +16,11 @@ Supported methods to test zephyr bluetooth host: - Testing Zephyr Host Stack on QEMU -- Testing Zephyr Host Stack on native posix +- Testing Zephyr Host Stack on :ref:`native_sim ` - Testing Zephyr combined (controller + host) build on Real hardware (such as nRF52) -For running with QEMU or native posix, see :ref:`bluetooth_qemu_posix`. +For running with QEMU or :ref:`native_sim `, see :ref:`bluetooth_qemu_native`. Setup Linux =========================== @@ -293,14 +293,14 @@ Testing Zephyr Host Stack on QEMU: ~/zephyrproject/build/zephyr/zephyr.elf -i SERVER_IP -l LOCAL_IP -Testing Zephyr Host Stack on native posix: +Testing Zephyr Host Stack on :ref:`native_sim `: .. code-block:: # A Bluetooth controller needs to be mounted. # For running with HCI UART, please visit: https://docs.zephyrproject.org/latest/samples/bluetooth/hci_uart/README.html#bluetooth-hci-uart - west build -b native_posix zephyr/tests/bluetooth/tester/ -DEXTRA_CONF_FILE=overlay-native.conf + west build -b native_sim zephyr/tests/bluetooth/tester/ -DEXTRA_CONF_FILE=overlay-native.conf sudo python ./autoptsclient-zephyr.py "C:\Users\USER_NAME\Documents\Profile Tuning Suite\PTS_PROJECT\PTS_PROJECT.pqw6" \ ~/zephyrproject/build/zephyr/zephyr.exe -i SERVER_IP -l LOCAL_IP --hci 0 diff --git a/doc/connectivity/bluetooth/bluetooth-dev.rst b/doc/connectivity/bluetooth/bluetooth-dev.rst index dd3c2058c2c..49daefe43b9 100644 --- a/doc/connectivity/bluetooth/bluetooth-dev.rst +++ b/doc/connectivity/bluetooth/bluetooth-dev.rst @@ -33,7 +33,7 @@ There are 4 possible hardware setups to use with Zephyr and Bluetooth: #. Embedded #. QEMU with an external Controller -#. Native POSIX with an external Controller +#. :ref:`native_sim ` with an external Controller #. Simulated nRF52 with BabbleSim Embedded @@ -90,7 +90,7 @@ This setup relies on a "dual-chip" :ref:`configuration ` which is comprised of the following devices: #. A :ref:`Host-only ` application running in the - :ref:`QEMU ` emulator or the ``native_posix`` native + :ref:`QEMU ` emulator or the :ref:`native_sim ` native port of Zephyr #. A Controller, which can be one of the following types: @@ -117,23 +117,23 @@ QEMU You can run the Zephyr Host on the :ref:`QEMU emulator` and have it interact with a physical external Bluetooth Controller. -Refer to :ref:`bluetooth_qemu_posix` for full instructions on how to build and +Refer to :ref:`bluetooth_qemu_native` for full instructions on how to build and run an application in this setup. -Native POSIX ------------- +native_sim +---------- .. note:: This is currently only available on GNU/Linux -The :ref:`Native POSIX ` target builds your Zephyr application +The :ref:`native_sim ` target builds your Zephyr application with the Zephyr kernel, and some minimal HW emulation as a native Linux executable. This executable is a normal Linux program, which can be debugged and instrumented like any other, and it communicates with a physical or virtual external Controller. -Refer to :ref:`bluetooth_qemu_posix` for full instructions on how to build and +Refer to :ref:`bluetooth_qemu_native` for full instructions on how to build and run an application with a physical controller. For the virtual controller refer to :ref:`bluetooth_virtual_posix`. @@ -152,7 +152,7 @@ This board, uses: * The POSIX arch to emulate the processor. * `Models of the nrf52 HW `_ -Just like with the ``native_posix`` target, the build result is a normal Linux +Just like with the :ref:`native_sim ` target, the build result is a normal Linux executable. You can find more information on how to run simulations with one or several devices in diff --git a/doc/connectivity/bluetooth/bluetooth-tools.rst b/doc/connectivity/bluetooth/bluetooth-tools.rst index 35453dd5f67..daa8107e0f3 100644 --- a/doc/connectivity/bluetooth/bluetooth-tools.rst +++ b/doc/connectivity/bluetooth/bluetooth-tools.rst @@ -74,13 +74,13 @@ Finally, reload and restart the daemon: sudo systemctl daemon-reload sudo systemctl restart bluetooth -.. _bluetooth_qemu_posix: +.. _bluetooth_qemu_native: -Running on QEMU and Native POSIX -******************************** +Running on QEMU or native_sim +***************************** It's possible to run Bluetooth applications using either the :ref:`QEMU -emulator` or :ref:`Native POSIX `. +emulator` or :ref:`native_sim `. In either case, a Bluetooth controller needs to be exported from the host OS (Linux) to the emulator. For this purpose you will need some tools described in the :ref:`bluetooth_bluez` section. @@ -94,14 +94,14 @@ The host OS's Bluetooth controller is connected in the following manner: with the help of the QEMU option :literal:`-serial unix:/tmp/bt-server-bredr`. This option gets passed to QEMU through :makevar:`QEMU_EXTRA_FLAGS` automatically whenever an application has enabled Bluetooth support. -* To a serial port in Native POSIX through the use of a command-line option - passed to the Native POSIX executable: ``--bt-dev=hci0`` +* To a serial port in :ref:`native_sim ` through the use of a command-line option + passed to the native_sim executable: ``--bt-dev=hci0`` On the host side, BlueZ allows you to export its Bluetooth controller -through a so-called user channel for QEMU and Native POSIX to use. +through a so-called user channel for QEMU and :ref:`native_sim ` to use. .. note:: - You only need to run ``btproxy`` when using QEMU. Native POSIX handles + You only need to run ``btproxy`` when using QEMU. native_sim handles the UNIX socket proxying automatically If you are using QEMU, in order to make the Controller available you will need @@ -142,12 +142,12 @@ building and running a sample: the :literal:`bt-server-bredr` UNIX socket, letting the application access the Bluetooth controller. -* To run a Bluetooth application in Native POSIX, first build it: +* To run a Bluetooth application in :ref:`native_sim `, first build it: .. zephyr-app-commands:: :zephyr-app: samples/bluetooth/ :host-os: unix - :board: native_posix + :board: native_sim :goals: build :compact: @@ -180,8 +180,8 @@ In order to see those logs, you can use the built-in ``btmon`` tool from BlueZ: .. _bluetooth_virtual_posix: -Running on a Virtual Controller and Native POSIX -************************************************* +Running on a Virtual Controller and native_sim +********************************************** An alternative to a Bluetooth physical controller is the use of a virtual controller. This controller can be connected over an HCI TCP server. diff --git a/samples/bluetooth/bluetooth.rst b/samples/bluetooth/bluetooth.rst index b96637d0c4e..0b59b9626b4 100644 --- a/samples/bluetooth/bluetooth.rst +++ b/samples/bluetooth/bluetooth.rst @@ -6,13 +6,13 @@ Bluetooth samples To build any of the Bluetooth samples, follow the same steps as building any other Zephyr application. Refer to :ref:`bluetooth-dev` for more information. -Many Bluetooth samples can be run on QEMU or Native POSIX with support for +Many Bluetooth samples can be run on QEMU or :ref:`native_sim ` with support for external Bluetooth Controllers. Refer to the :ref:`bluetooth-hw-setup` section for further details. Several of the bluetooth samples will build a Zephyr-based Controller that can then be used with any external Host (including Zephyr running natively or with -QEMU or Native POSIX), those are named accordingly with an "HCI" prefix in the +QEMU or ``native_sim``), those are named accordingly with an "HCI" prefix in the documentation and are prefixed with :literal:`hci_` in their folder names. .. note:: diff --git a/samples/bluetooth/hci_uart/README.rst b/samples/bluetooth/hci_uart/README.rst index 83004cd544f..0beb105035d 100644 --- a/samples/bluetooth/hci_uart/README.rst +++ b/samples/bluetooth/hci_uart/README.rst @@ -55,10 +55,10 @@ For example, to build for the nRF52832 Development Kit: .. _bluetooth-hci-uart-qemu-posix: -Using the controller with QEMU and Native POSIX -=============================================== +Using the controller with QEMU or native_sim +============================================ -In order to use the HCI UART controller with QEMU or Native POSIX you will need +In order to use the HCI UART controller with QEMU or :ref:`native_sim ` you will need to attach it to the Linux Host first. To do so simply build the sample and connect the UART to the Linux machine, and then attach it with this command: @@ -84,7 +84,7 @@ If you are running :file:`btmon` you should see a brief log showing how the Linux kernel identifies the attached controller. Once the controller is attached follow the instructions in the -:ref:`bluetooth_qemu_posix` section to use QEMU with it. +:ref:`bluetooth_qemu_native` section to use QEMU with it. .. _bluetooth-hci-uart-bluez: diff --git a/samples/bluetooth/hci_uart_async/README.rst b/samples/bluetooth/hci_uart_async/README.rst index 75bf586868d..f5caf0f965d 100644 --- a/samples/bluetooth/hci_uart_async/README.rst +++ b/samples/bluetooth/hci_uart_async/README.rst @@ -52,10 +52,10 @@ For example, to build for the nRF52832 Development Kit: .. _bluetooth-hci-uart-async-qemu-posix: -Using the controller with QEMU and Native POSIX -=============================================== +Using the controller with QEMU or native_sim +============================================ -In order to use the HCI UART controller with QEMU or Native POSIX you will need +In order to use the HCI UART controller with QEMU or :ref:`native_sim ` you will need to attach it to the Linux Host first. To do so simply build the sample and connect the UART to the Linux machine, and then attach it with this command: @@ -77,7 +77,7 @@ If you are running :file:`btmon` you should see a brief log showing how the Linux kernel identifies the attached controller. Once the controller is attached follow the instructions in the -:ref:`bluetooth_qemu_posix` section to use QEMU with it. +:ref:`bluetooth_qemu_native` section to use QEMU with it. .. _bluetooth-hci-uart-async-bluez: From fc4967e71fe3252d7ba196b11b44f30ace626df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 13 Nov 2023 16:09:22 +0100 Subject: [PATCH 3533/4498] samples: lz4: reduce malloc arena size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #63332 introduced a change to the LZ4 sample that set the malloc arena to an unnecessarily large size. After testing on native_posix, qemu_m3, and esp32s3_devkitm_appcpu, it would appear 24K is a much more reasonable (and sufficient) size. Signed-off-by: Benjamin Cabé --- samples/compression/lz4/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/compression/lz4/prj.conf b/samples/compression/lz4/prj.conf index a3228945546..d4f2049eb89 100644 --- a/samples/compression/lz4/prj.conf +++ b/samples/compression/lz4/prj.conf @@ -1,4 +1,4 @@ CONFIG_LZ4=y CONFIG_REQUIRES_FULL_LIBC=y CONFIG_HEAP_MEM_POOL_SIZE=16384 -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=65536 +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=24576 From e74676223ae85f608cbb97737d1a19070b85bd00 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 9 Oct 2023 11:24:11 +1000 Subject: [PATCH 3534/4498] bluetooth: host: gatt: statically init callback list Statically initialise the callback list so that subscriptions can be registered before the call to `bt_enable`. Signed-off-by: Jordan Yates --- doc/releases/migration-guide-3.6.rst | 4 ++++ include/zephyr/bluetooth/gatt.h | 3 ++- subsys/bluetooth/host/gatt.c | 4 +--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index aaad9dfea3f..77a0c1b76f7 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -72,6 +72,10 @@ Bluetooth Devicetree chosen is now ``zephyr,bt-hci-ipc``. The existing sample has also been renamed, from ``samples/bluetooth/hci_rpmsg`` to ``samples/bluetooth/hci_ipc``. +* The BT GATT callback list, appended to by :c:func:`bt_gatt_cb_register`, is no longer + cleared on :c:func:`bt_enable`. Callbacks can now be registered before the initial + call to :c:func:`bt_enable`, and should no longer be re-registered after a :c:func:`bt_disable` + :c:func:`bt_enable` cycle. LoRaWAN ======= diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index c50bfb25c3d..c53422648f0 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -370,7 +370,8 @@ struct bt_gatt_cpf { /** @brief Register GATT callbacks. * - * Register callbacks to monitor the state of GATT. + * Register callbacks to monitor the state of GATT. The callback struct + * must remain valid for the remainder of the program. * * @param cb Callback struct. */ diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 8266fe36dae..11c292f159e 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -80,7 +80,7 @@ struct gatt_sub { * <=> (subscriptions[x].peer == BT_ADDR_LE_ANY). */ static struct gatt_sub subscriptions[SUB_MAX]; -static sys_slist_t callback_list; +static sys_slist_t callback_list = SYS_SLIST_STATIC_INIT(&callback_list); #if defined(CONFIG_BT_GATT_DYNAMIC_DB) static sys_slist_t db; @@ -1464,8 +1464,6 @@ void bt_gatt_init(void) bt_gatt_service_init(); - sys_slist_init(&callback_list); - #if defined(CONFIG_BT_GATT_CACHING) k_work_init_delayable(&db_hash.work, db_hash_process); From 165bd2a7808108d926d5ad8e09a01b4a752e9bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 16 Oct 2023 07:29:41 +0200 Subject: [PATCH 3535/4498] drivers: serial: Add uart_async_rx module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add module which can handle RX path of UART asynchronous RX API. Module can be utilized in cases where processing of received data is not performed directly in the event context but it is delayed. At least two use cases has been identified (shell async UART backend, asynchronous to interrupt driven adaptation layer). Signed-off-by: Krzysztof Chruściński --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 8 + drivers/serial/uart_async_rx.c | 134 +++++++++++++ include/zephyr/drivers/serial/uart_async_rx.h | 176 ++++++++++++++++++ 4 files changed, 319 insertions(+) create mode 100644 drivers/serial/uart_async_rx.c create mode 100644 include/zephyr/drivers/serial/uart_async_rx.h diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 62336a8980e..be0cbfd394b 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -91,3 +91,4 @@ if(CONFIG_UART_NATIVE_TTY) endif() zephyr_library_sources_ifdef(CONFIG_SERIAL_TEST serial_test.c) +zephyr_library_sources_ifdef(CONFIG_UART_ASYNC_RX_HELPER uart_async_rx.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 4a42a81aadd..22916527ca1 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -125,6 +125,14 @@ config UART_PIPE data (as contrary to console UART driver) and all aspects of received protocol data are handled by application provided callback. +config UART_ASYNC_RX_HELPER + bool "Helper for UART asynchronous reception" + help + Module implements handling of reception of variable length data using + Asynchronous UART API. It can be used in cases where received data processing + is delayed. Module implements zero-copy approach with multiple reception + buffers. + comment "Serial Drivers" source "drivers/serial/Kconfig.b91" diff --git a/drivers/serial/uart_async_rx.c b/drivers/serial/uart_async_rx.c new file mode 100644 index 00000000000..68e17691c3e --- /dev/null +++ b/drivers/serial/uart_async_rx.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static uint8_t inc(struct uart_async_rx *rx_data, uint8_t val) +{ + return (val + 1) & (rx_data->config->buf_cnt - 1); +} + +static struct uart_async_rx_buf *get_buf(struct uart_async_rx *rx_data, uint8_t idx) +{ + uint8_t *p = rx_data->config->buffer; + + p += idx * (rx_data->buf_len + sizeof(struct uart_async_rx_buf)); + + return (struct uart_async_rx_buf *)p; +} + +uint8_t *uart_async_rx_buf_req(struct uart_async_rx *rx_data) +{ + uint8_t *data = NULL; + + if (rx_data->free_buf_cnt != 0) { + struct uart_async_rx_buf *buf = get_buf(rx_data, rx_data->drv_buf_idx); + + data = buf->buffer; + rx_data->drv_buf_idx = inc(rx_data, rx_data->drv_buf_idx); + + atomic_dec(&rx_data->free_buf_cnt); + } + + return data; +} + +void uart_async_rx_on_rdy(struct uart_async_rx *rx_data, uint8_t *buffer, size_t length) +{ + /* Cannot use CONTAINER_OF because validation fails due to type mismatch: + * uint8_t * vs uint8_t []. + */ + struct uart_async_rx_buf *rx_buf = + (struct uart_async_rx_buf *)(buffer - offsetof(struct uart_async_rx_buf, buffer)); + + rx_buf->wr_idx += length; + __ASSERT_NO_MSG(rx_buf->wr_idx <= rx_data->buf_len); + + atomic_add(&rx_data->pending_bytes, length); +} + +static void buf_reset(struct uart_async_rx_buf *buf) +{ + buf->rd_idx = 0; + buf->wr_idx = 0; + buf->completed = 0; +} +static void usr_rx_buf_release(struct uart_async_rx *rx_data, struct uart_async_rx_buf *buf) +{ + buf_reset(buf); + rx_data->rd_buf_idx = inc(rx_data, rx_data->rd_buf_idx); + atomic_inc(&rx_data->free_buf_cnt); + __ASSERT_NO_MSG(rx_data->free_buf_cnt <= rx_data->config->buf_cnt); +} + +void uart_async_rx_on_buf_rel(struct uart_async_rx *rx_data, uint8_t *buffer) +{ + /* Cannot use CONTAINER_OF because validation fails due to type mismatch: + * uint8_t * vs uint8_t []. + */ + struct uart_async_rx_buf *rx_buf = + (struct uart_async_rx_buf *)(buffer - offsetof(struct uart_async_rx_buf, buffer)); + + rx_buf->completed = 1; + rx_data->wr_buf_idx = inc(rx_data, rx_data->wr_buf_idx); +} + +size_t uart_async_rx_data_claim(struct uart_async_rx *rx_data, uint8_t **data, size_t length) +{ + struct uart_async_rx_buf *buf; + int rem; + + if ((rx_data->pending_bytes == 0) || (length == 0)) { + return 0; + } + + do { + buf = get_buf(rx_data, rx_data->rd_buf_idx); + if ((buf->rd_idx == buf->wr_idx) && (buf->completed == 1)) { + usr_rx_buf_release(rx_data, buf); + } else { + break; + } + } while (1); + + *data = &buf->buffer[buf->rd_idx]; + rem = buf->wr_idx - buf->rd_idx; + + return MIN(length, rem); +} + +void uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length) +{ + struct uart_async_rx_buf *buf = get_buf(rx_data, rx_data->rd_buf_idx); + + buf->rd_idx += length; + + atomic_sub(&rx_data->pending_bytes, length); + + __ASSERT_NO_MSG(buf->rd_idx <= buf->wr_idx); +} + +void uart_async_rx_reset(struct uart_async_rx *rx_data) +{ + rx_data->free_buf_cnt = rx_data->config->buf_cnt; + for (uint8_t i = 0; i < rx_data->config->buf_cnt; i++) { + buf_reset(get_buf(rx_data, i)); + } +} + +int uart_async_rx_init(struct uart_async_rx *rx_data, + const struct uart_async_rx_config *config) +{ + __ASSERT_NO_MSG(config->length / config->buf_cnt <= UINT8_MAX); + memset(rx_data, 0, sizeof(*rx_data)); + rx_data->config = config; + rx_data->buf_len = (config->length / config->buf_cnt) - UART_ASYNC_RX_BUF_OVERHEAD; + uart_async_rx_reset(rx_data); + + return 0; +} diff --git a/include/zephyr/drivers/serial/uart_async_rx.h b/include/zephyr/drivers/serial/uart_async_rx.h new file mode 100644 index 00000000000..646a2befc94 --- /dev/null +++ b/include/zephyr/drivers/serial/uart_async_rx.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Helper module for receiving using UART Asynchronous API. + */ + +#ifndef ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_RX_H_ +#define ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_RX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* @brief RX buffer structure which holds the buffer and its state. */ +struct uart_async_rx_buf { + /* Write index which is incremented whenever new data is reported to be + * received to that buffer. + */ + uint8_t wr_idx; + + /* Read index which is incremented whenever data is consumed from the buffer. + * Read index cannot be higher than the write index. + */ + uint8_t rd_idx; + + /* Set to one if buffer is released by the driver. */ + uint8_t completed; + + /* Location which is passed to the UART driver. */ + uint8_t buffer[]; +}; + +/** @brief UART asynchronous RX helper structure. */ +struct uart_async_rx { + /* Pointer to the configuration structure. Structure must be persistent. */ + const struct uart_async_rx_config *config; + + /* Total amount of pending bytes. Bytes may be spread across multiple RX buffers. */ + atomic_t pending_bytes; + + /* Number of buffers which are free. */ + atomic_t free_buf_cnt; + + /* Single buffer size. */ + uint8_t buf_len; + + /* Index of the next buffer to be provided to the driver. */ + uint8_t drv_buf_idx; + + /* Current buffer to which data is written. */ + uint8_t wr_buf_idx; + + /* Current buffer from which data is being consumed. */ + uint8_t rd_buf_idx; +}; + +/** @brief UART asynchronous RX helper configuration structure. */ +struct uart_async_rx_config { + /* Pointer to the buffer. */ + uint8_t *buffer; + + /* Buffer length. */ + size_t length; + + /* Number of buffers into provided space shall be split. */ + uint8_t buf_cnt; +}; + +/** @brief Get RX buffer length. + * + * @param async_rx Pointer to the helper instance. + * + * @return Buffer length. + */ +static inline uint8_t uart_async_rx_get_buf_len(struct uart_async_rx *async_rx) +{ + return async_rx->buf_len; +} + +/** @brief Get amount of space dedicated for managing each buffer state. + * + * User buffer provided during the initialization is split into chunks and each + * chunk has overhead. This overhead can be used to calculate actual space used + * for UART data. + * + * @return Overhead space in bytes. + */ +#define UART_ASYNC_RX_BUF_OVERHEAD offsetof(struct uart_async_rx_buf, buffer) + +/** @brief Initialize the helper instance. + * + * @param async_rx Pointer to the helper instance. + * @param config Configuration. Must be persistent. + * + * @retval 0 on successful initialization. + */ +int uart_async_rx_init(struct uart_async_rx *async_rx, + const struct uart_async_rx_config *config); + +/** @brief Reset state of the helper instance. + * + * Helper can be reset after RX abort to discard all received data and bring + * the helper to its initial state. + * + * @param async_rx Pointer to the helper instance. + */ +void uart_async_rx_reset(struct uart_async_rx *async_rx); + +/** @brief Indicate received data. + * + * Function shall be called from @ref UART_RX_RDY context. + * + * @param async_rx Pointer to the helper instance. + * @param buffer Buffer received in the UART driver event. + * @param length Length received in the UART driver event. + */ +void uart_async_rx_on_rdy(struct uart_async_rx *async_rx, uint8_t *buffer, size_t length); + +/** @brief Get next RX buffer. + * + * Returned pointer shall be provided to @ref uart_rx_buf_rsp or @ref uart_rx_enable. + * If null is returned that indicates that there are no available buffers since all + * buffers are used by the driver or contain not consumed data. + * + * @param async_rx Pointer to the helper instance. + * + * @return Pointer to the next RX buffer or null if no buffer available. + */ +uint8_t *uart_async_rx_buf_req(struct uart_async_rx *async_rx); + +/** @brief Indicate that buffer is no longer used by the UART driver. + * + * Function shall be called on @ref UART_RX_BUF_RELEASED event. + * + * @param async_rx Pointer to the helper instance. + * @param buf Buffer pointer received in the UART driver event. + */ +void uart_async_rx_on_buf_rel(struct uart_async_rx *async_rx, uint8_t *buf); + +/** @brief Claim received data for processing. + * + * Helper module works in the zero copy mode. It provides a pointer to the buffer + * that was directly used by the UART driver. Since received data is spread across + * multiple buffers there is no possibility to read all data at once. It can only be + * consumed in chunks. After data is processed, @ref uart_async_rx_data_consume is + * used to indicate that data is consumed. + * + * @param async_rx Pointer to the helper instance. + * @param data Location where address to the buffer is written. Untouched if no data to claim. + * @param length Amount of requested data. + * + * @return Amount valid of data in the @p data buffer. 0 is returned when there is no data. + */ +size_t uart_async_rx_data_claim(struct uart_async_rx *async_rx, uint8_t **data, size_t length); + +/** @brief Consume claimed data. + * + * It pairs with @ref uart_async_rx_data_claim. + * + * @param async_rx Pointer to the helper instance. + * @param length Amount of data to consume. It must be less or equal than amount of claimed data. + */ +void uart_async_rx_data_consume(struct uart_async_rx *async_rx, size_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_RX_H_ */ From 8ba4249ef72c468dc94697ed959471333576da34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 16 Oct 2023 07:31:22 +0200 Subject: [PATCH 3536/4498] tests: drivers: uart: Add test for uart_async_rx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test for helper module for handling asynchronous RX. Signed-off-by: Krzysztof Chruściński --- .../drivers/uart/uart_async_rx/CMakeLists.txt | 9 + tests/drivers/uart/uart_async_rx/prj.conf | 4 + tests/drivers/uart/uart_async_rx/src/main.c | 327 ++++++++++++++++++ .../drivers/uart/uart_async_rx/testcase.yaml | 15 + 4 files changed, 355 insertions(+) create mode 100644 tests/drivers/uart/uart_async_rx/CMakeLists.txt create mode 100644 tests/drivers/uart/uart_async_rx/prj.conf create mode 100644 tests/drivers/uart/uart_async_rx/src/main.c create mode 100644 tests/drivers/uart/uart_async_rx/testcase.yaml diff --git a/tests/drivers/uart/uart_async_rx/CMakeLists.txt b/tests/drivers/uart/uart_async_rx/CMakeLists.txt new file mode 100644 index 00000000000..9cb2446f3c6 --- /dev/null +++ b/tests/drivers/uart/uart_async_rx/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(uart_async_rx) + +target_sources(app PRIVATE + src/main.c +) diff --git a/tests/drivers/uart/uart_async_rx/prj.conf b/tests/drivers/uart/uart_async_rx/prj.conf new file mode 100644 index 00000000000..e10bf49c4d1 --- /dev/null +++ b/tests/drivers/uart/uart_async_rx/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTRESS=y +CONFIG_UART_ASYNC_RX_HELPER=y diff --git a/tests/drivers/uart/uart_async_rx/src/main.c b/tests/drivers/uart/uart_async_rx/src/main.c new file mode 100644 index 00000000000..d95c6a69066 --- /dev/null +++ b/tests/drivers/uart/uart_async_rx/src/main.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(test); + +static void mem_fill(uint8_t *buf, uint8_t init, size_t len) +{ + for (size_t i = 0; i < len; i++) { + buf[i] = init + i; + } +} + +static bool mem_check(uint8_t *buf, uint8_t init, size_t len) +{ + for (size_t i = 0; i < len; i++) { + if (buf[i] != init + i) { + return false; + } + } + + return true; +} + +ZTEST(uart_async_rx, test_rx) +{ + int err; + uint8_t buf[40]; + static const int buf_cnt = 4; + size_t aloc_len; + size_t claim_len; + uint8_t *claim_buf; + uint8_t *aloc_buf; + struct uart_async_rx async_rx; + const struct uart_async_rx_config config = { + .buffer = buf, + .length = sizeof(buf), + .buf_cnt = buf_cnt + }; + + err = uart_async_rx_init(&async_rx, &config); + zassert_equal(err, 0); + + aloc_len = uart_async_rx_get_buf_len(&async_rx); + aloc_buf = uart_async_rx_buf_req(&async_rx); + + mem_fill(aloc_buf, 0, aloc_len - 2); + + /* No data to read. */ + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 1); + zassert_equal(claim_len, 0); + + /* Simulate partial write */ + uart_async_rx_on_rdy(&async_rx, aloc_buf, aloc_len - 4); + + /* There is at least 1 byte available */ + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 1); + zassert_equal(claim_len, 1); + zassert_equal(claim_buf, aloc_buf); + zassert_true(mem_check(claim_buf, 0, 1)); + + /* All received data is available */ + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100); + zassert_equal(claim_len, aloc_len - 4); + zassert_equal(claim_buf, aloc_buf); + zassert_true(mem_check(claim_buf, 0, aloc_len - 4)); + + /* Simulate 2 bytes received to the same buffer. */ + uart_async_rx_on_rdy(&async_rx, aloc_buf, 2); + + /* Indicate and of the current buffer. */ + uart_async_rx_on_buf_rel(&async_rx, aloc_buf); + + /* Claim all data received so far */ + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100); + zassert_equal(claim_len, aloc_len - 2); + zassert_equal(claim_buf, aloc_buf); + zassert_true(mem_check(claim_buf, 0, aloc_len - 2)); + + /* Consume first 2 bytes. */ + uart_async_rx_data_consume(&async_rx, 2); + + /* Now claim will return buffer taking into account that first 2 bytes are + * consumed. + */ + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100); + zassert_equal(claim_len, aloc_len - 4); + zassert_equal(claim_buf, &aloc_buf[2]); + zassert_true(mem_check(claim_buf, 2, aloc_len - 4)); + + /* Consume rest of data. Get indication that it was end of the buffer. */ + uart_async_rx_data_consume(&async_rx, aloc_len - 4); +} + +ZTEST(uart_async_rx, test_rx_late_consume) +{ + int err; + uint8_t buf[40] __aligned(4); + static const int buf_cnt = 4; + size_t aloc_len; + size_t claim_len; + uint8_t *claim_buf; + uint8_t *aloc_buf; + struct uart_async_rx async_rx; + const struct uart_async_rx_config config = { + .buffer = buf, + .length = sizeof(buf), + .buf_cnt = buf_cnt + }; + + err = uart_async_rx_init(&async_rx, &config); + zassert_equal(err, 0); + + aloc_len = uart_async_rx_get_buf_len(&async_rx); + for (int i = 0; i < buf_cnt; i++) { + aloc_buf = uart_async_rx_buf_req(&async_rx); + + aloc_buf[0] = (uint8_t)i; + uart_async_rx_on_rdy(&async_rx, aloc_buf, 1); + uart_async_rx_on_buf_rel(&async_rx, aloc_buf); + } + + for (int i = 0; i < buf_cnt; i++) { + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100); + zassert_equal(claim_len, 1); + zassert_equal(claim_buf[0], (uint8_t)i); + + uart_async_rx_data_consume(&async_rx, 1); + } + + claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100); + zassert_equal(claim_len, 0); +} + +struct test_async_rx { + struct uart_async_rx async_rx; + atomic_t pending_req; + atomic_t total_pending_req; + bool in_chunks; + uint8_t exp_consume; + uint32_t byte_cnt; + uint8_t curr_len; + uint8_t *curr_buf; + uint8_t *next_buf; + struct k_spinlock lock; +}; + +static bool producer_no_chunks(void *user_data, uint32_t cnt, bool last, int prio) +{ + struct test_async_rx *test_data = (struct test_async_rx *)user_data; + struct uart_async_rx *async_rx = &test_data->async_rx; + uint32_t r = sys_rand32_get(); + uint32_t len = MAX(1, MIN(uart_async_rx_get_buf_len(async_rx), r & 0x7)); + + if (test_data->curr_buf) { + + for (int i = 0; i < len; i++) { + test_data->curr_buf[i] = (uint8_t)test_data->byte_cnt; + test_data->byte_cnt++; + } + uart_async_rx_on_rdy(async_rx, test_data->curr_buf, len); + uart_async_rx_on_buf_rel(async_rx, test_data->curr_buf); + test_data->curr_buf = test_data->next_buf; + test_data->next_buf = NULL; + + uint8_t *buf = uart_async_rx_buf_req(async_rx); + + if (buf) { + if (test_data->curr_buf == NULL) { + test_data->curr_buf = buf; + } else { + test_data->next_buf = buf; + } + } else { + atomic_inc(&test_data->pending_req); + atomic_inc(&test_data->total_pending_req); + } + } + + return true; +} + +static bool consumer(void *user_data, uint32_t cnt, bool last, int prio) +{ + struct test_async_rx *test_data = (struct test_async_rx *)user_data; + struct uart_async_rx *async_rx = &test_data->async_rx; + uint32_t r = sys_rand32_get(); + uint32_t rpt = MAX(1, r & 0x7); + + r >>= 3; + + for (uint32_t i = 0; i < rpt; i++) { + size_t claim_len = MAX(1, r & 0x7); + size_t len; + uint8_t *buf; + + r >>= 3; + len = uart_async_rx_data_claim(async_rx, &buf, claim_len); + + if (len == 0) { + return true; + } + + for (int j = 0; j < len; j++) { + zassert_equal(buf[j], test_data->exp_consume, + "%02x (exp:%02x) len:%d, total:%d", + buf[j], test_data->exp_consume, len, test_data->byte_cnt); + test_data->exp_consume++; + } + + uart_async_rx_data_consume(async_rx, len); + + if (test_data->pending_req) { + buf = uart_async_rx_buf_req(async_rx); + if (buf) { + atomic_dec(&test_data->pending_req); + } + k_spinlock_key_t key = k_spin_lock(&test_data->lock); + + if (test_data->curr_buf == NULL) { + test_data->curr_buf = buf; + } else if (test_data->next_buf == NULL) { + test_data->next_buf = buf; + } else { + zassert_true(false); + } + k_spin_unlock(&test_data->lock, key); + } + } + + return true; +} + +static bool producer_in_chunks(void *user_data, uint32_t cnt, bool last, int prio) +{ + struct test_async_rx *test_data = (struct test_async_rx *)user_data; + struct uart_async_rx *async_rx = &test_data->async_rx; + uint32_t r = sys_rand32_get(); + uint32_t rem = uart_async_rx_get_buf_len(async_rx) - test_data->curr_len; + uint32_t len = MAX(1, MIN(uart_async_rx_get_buf_len(async_rx), r & 0x7)); + + len = MIN(rem, len); + + if (test_data->curr_buf) { + for (int i = 0; i < len; i++) { + test_data->curr_buf[test_data->curr_len + i] = (uint8_t)test_data->byte_cnt; + test_data->byte_cnt++; + } + uart_async_rx_on_rdy(async_rx, test_data->curr_buf, len); + test_data->curr_len += len; + + if ((test_data->curr_len == uart_async_rx_get_buf_len(async_rx)) || (r & BIT(31))) { + test_data->curr_len = 0; + uart_async_rx_on_buf_rel(async_rx, test_data->curr_buf); + + test_data->curr_buf = test_data->next_buf; + test_data->next_buf = NULL; + + uint8_t *buf = uart_async_rx_buf_req(async_rx); + + if (buf) { + if (test_data->curr_buf == NULL) { + test_data->curr_buf = buf; + } else { + test_data->next_buf = buf; + } + } else { + atomic_inc(&test_data->pending_req); + } + } + } + + return true; +} + +static void stress_test(bool in_chunks) +{ + int err; + uint8_t buf[40]; + static const int buf_cnt = 4; + int preempt = 1000; + int timeout = 5000; + struct test_async_rx test_data; + const struct uart_async_rx_config config = { + .buffer = buf, + .length = sizeof(buf), + .buf_cnt = buf_cnt + }; + + memset(&test_data, 0, sizeof(test_data)); + + err = uart_async_rx_init(&test_data.async_rx, &config); + zassert_equal(err, 0); + + test_data.in_chunks = in_chunks; + test_data.curr_buf = uart_async_rx_buf_req(&test_data.async_rx); + + ztress_set_timeout(K_MSEC(timeout)); + + ZTRESS_EXECUTE(ZTRESS_THREAD(in_chunks ? producer_in_chunks : producer_no_chunks, + &test_data, 0, 0, Z_TIMEOUT_TICKS(20)), + ZTRESS_THREAD(consumer, &test_data, 0, preempt, Z_TIMEOUT_TICKS(20))); + + TC_PRINT("total bytes: %d\n", test_data.byte_cnt); + ztress_set_timeout(K_NO_WAIT); +} + +ZTEST(uart_async_rx, test_rx_ztress_no_chunks) +{ + stress_test(false); +} + +ZTEST(uart_async_rx, test_rx_ztress_with_chunks) +{ + stress_test(true); +} + +ZTEST_SUITE(uart_async_rx, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/uart/uart_async_rx/testcase.yaml b/tests/drivers/uart/uart_async_rx/testcase.yaml new file mode 100644 index 00000000000..64311dc1eb7 --- /dev/null +++ b/tests/drivers/uart/uart_async_rx/testcase.yaml @@ -0,0 +1,15 @@ +tests: + drivers.uart.async_rx: + filter: CONFIG_SERIAL + tags: drivers uart + integration_platforms: + - native_posix + drivers.uart.async_rx.ztress: + filter: CONFIG_SERIAL + tags: drivers uart + platform_allow: > + qemu_cortex_m3 qemu_x86 qemu_x86_64 qemu_riscv32 + integration_platforms: + - qemu_x86 + extra_configs: + - CONFIG_SYS_CLOCK_TICKS_PER_SEC=10000 From 5e4e944cc0c09066ac67fa485f0c18998a396acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 16 Oct 2023 07:49:32 +0200 Subject: [PATCH 3537/4498] shell: backends: uart: Rework and add support for async API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework UART backend to clearly use single instance approach as before it was a bit messy with some parts of implementation indicating multi-instance approach and some single instance. Backend has been around for years and multi-instance requirement never came. Added support for UART asynchronous API which is more efficient in terms of power consumption and performance. Asynchronous API support is using uart_async_rx helper module for handling data received asynchronously. Signed-off-by: Krzysztof Chruściński --- include/zephyr/shell/shell_uart.h | 70 +--- subsys/shell/backends/Kconfig.backends | 60 +++- subsys/shell/backends/shell_uart.c | 441 +++++++++++++++++++------ 3 files changed, 400 insertions(+), 171 deletions(-) diff --git a/include/zephyr/shell/shell_uart.h b/include/zephyr/shell/shell_uart.h index adf8a4044aa..2b157aac6e7 100644 --- a/include/zephyr/shell/shell_uart.h +++ b/include/zephyr/shell/shell_uart.h @@ -8,81 +8,15 @@ #define SHELL_UART_H__ #include -#include -#include -#include #ifdef __cplusplus extern "C" { #endif -extern const struct shell_transport_api shell_uart_transport_api; - -/** @brief Shell UART transport instance control block (RW data). */ -struct shell_uart_ctrl_blk { - const struct device *dev; - shell_transport_handler_t handler; - void *context; - atomic_t tx_busy; - bool blocking_tx; -#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL - struct smp_shell_data smp; -#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ -}; - -#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN -#define Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _size) \ - RING_BUF_DECLARE(_name##_tx_ringbuf, _size) - -#define Z_UART_SHELL_RX_TIMER_DECLARE(_name) /* Empty */ -#define Z_UART_SHELL_TX_RINGBUF_PTR(_name) (&_name##_tx_ringbuf) - -#define Z_UART_SHELL_RX_TIMER_PTR(_name) NULL - -#define Z_UART_SHELL_DTR_TIMER_DECLARE(_name) static struct k_timer _name##_dtr_timer -#define Z_UART_SHELL_DTR_TIMER_PTR(_name) (&_name##_dtr_timer) - -#else /* CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN */ -#define Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _size) /* Empty */ -#define Z_UART_SHELL_RX_TIMER_DECLARE(_name) static struct k_timer _name##_timer -#define Z_UART_SHELL_TX_RINGBUF_PTR(_name) NULL -#define Z_UART_SHELL_RX_TIMER_PTR(_name) (&_name##_timer) -#define Z_UART_SHELL_DTR_TIMER_DECLARE(_name) /* Empty */ -#define Z_UART_SHELL_DTR_TIMER_PTR(_name) NULL -#endif /* CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN */ - -/** @brief Shell UART transport instance structure. */ -struct shell_uart { - struct shell_uart_ctrl_blk *ctrl_blk; - struct k_timer *timer; - struct k_timer *dtr_timer; - struct ring_buf *tx_ringbuf; - struct ring_buf *rx_ringbuf; -}; - -/** @brief Macro for creating shell UART transport instance. */ -#define SHELL_UART_DEFINE(_name, _tx_ringbuf_size, _rx_ringbuf_size) \ - static struct shell_uart_ctrl_blk _name##_ctrl_blk; \ - Z_UART_SHELL_RX_TIMER_DECLARE(_name); \ - Z_UART_SHELL_DTR_TIMER_DECLARE(_name); \ - Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _tx_ringbuf_size); \ - RING_BUF_DECLARE(_name##_rx_ringbuf, _rx_ringbuf_size); \ - static const struct shell_uart _name##_shell_uart = { \ - .ctrl_blk = &_name##_ctrl_blk, \ - .timer = Z_UART_SHELL_RX_TIMER_PTR(_name), \ - .dtr_timer = Z_UART_SHELL_DTR_TIMER_PTR(_name), \ - .tx_ringbuf = Z_UART_SHELL_TX_RINGBUF_PTR(_name), \ - .rx_ringbuf = &_name##_rx_ringbuf, \ - }; \ - struct shell_transport _name = { \ - .api = &shell_uart_transport_api, \ - .ctx = (struct shell_uart *)&_name##_shell_uart \ - } - /** - * @brief This function provides pointer to shell uart backend instance. + * @brief This function provides pointer to the shell UART backend instance. * - * Function returns pointer to the shell uart instance. This instance can be + * Function returns pointer to the shell UART instance. This instance can be * next used with shell_execute_cmd function in order to test commands behavior. * * @returns Pointer to the shell instance. diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index 1d30bee2305..7c81030cb20 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -42,23 +42,44 @@ config SHELL_PROMPT_UART Displayed prompt name for UART backend. If prompt is set, the shell will send two newlines during initialization. -# Internal config to enable UART interrupts if supported. config SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN bool "Interrupt driven" - default y + depends on SERIAL_SUPPORT_INTERRUPT + +choice SHELL_BACKEND_SERIAL_API + prompt "Mode" + default SHELL_BACKEND_SERIAL_API_ASYNC if SERIAL_SUPPORT_ASYNC + default SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN if SERIAL_SUPPORT_INTERRUPT + default SHELL_BACKEND_SERIAL_API_POLLING + +config SHELL_BACKEND_SERIAL_API_POLLING + prompt "Polling" + +config SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN + bool "Interrupt driven" depends on SERIAL_SUPPORT_INTERRUPT select UART_INTERRUPT_DRIVEN + +config SHELL_BACKEND_SERIAL_API_ASYNC + bool "Asynchronous" + depends on SERIAL_SUPPORT_ASYNC + select UART_ASYNC_RX_HELPER + select UART_ASYNC_API + +endchoice + config SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE int "Set TX ring buffer size" default 8 - depends on SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN + depends on SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN help If UART is utilizing DMA transfers then increasing ring buffer size increases transfers length and reduces number of interrupts. config SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE int "Set RX ring buffer size" + depends on SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN || SHELL_BACKEND_SERIAL_API_POLLING default 256 if MCUMGR_TRANSPORT_SHELL default 64 help @@ -68,16 +89,45 @@ config SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE escape sequences). However, if bulk data is transferred it may be required to increase it. +if SHELL_BACKEND_SERIAL_API_ASYNC + +config SHELL_BACKEND_SERIAL_ASYNC_RX_TIMEOUT + int "RX inactivity timeout (in microseconds)" + default 10000 + help + Inactivity timeout after which received data is reported. + +config SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT + int "Number of RX buffers" + default 4 + range 2 64 + help + Number of RX buffers. Some UART driver implementations changes buffers + on timeout so this number should be big enough to cover handling on + time incoming data. 4 should be enough for almost all the cases unless + CPU load is high and there is very high shell thread latency. + +config SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE + int "Size of the RX buffer" + default 16 + help + Size of a single RX buffer. Together with buffer count it defines the + space that can hold RX data. It may be decreased if shell input is + slow and may need to be increased if long messages are pasted directly + to the shell prompt. + +endif # SHELL_BACKEND_SERIAL_API_ASYNC + config SHELL_BACKEND_SERIAL_RX_POLL_PERIOD int "RX polling period (in milliseconds)" default 10 - depends on !SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN + depends on SHELL_BACKEND_SERIAL_API_POLLING help Determines how often UART is polled for RX byte. config SHELL_BACKEND_SERIAL_CHECK_DTR bool "Check DTR signal before TX" - depends on SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN + depends on SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN depends on UART_LINE_CTRL help Check DTR signal before TX. diff --git a/subsys/shell/backends/shell_uart.c b/subsys/shell/backends/shell_uart.c index ce52eb15d8c..f64438c0b59 100644 --- a/subsys/shell/backends/shell_uart.c +++ b/subsys/shell/backends/shell_uart.c @@ -4,8 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include #include #include +#include #include #include #include @@ -19,34 +23,122 @@ LOG_MODULE_REGISTER(shell_uart); #define RX_POLL_PERIOD K_NO_WAIT #endif +#ifndef CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE +#define CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE 0 +#endif + +#ifndef CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE +#define CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE 0 +#endif + +#ifndef CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT +#define CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT 0 +#endif + +#ifndef CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE +#define CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE 0 +#endif + +#define ASYNC_RX_BUF_SIZE (CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT * \ + (CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE + \ + UART_ASYNC_RX_BUF_OVERHEAD)) + +struct shell_uart_common { + const struct device *dev; + shell_transport_handler_t handler; + void *context; + bool blocking_tx; +#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL + struct smp_shell_data smp; +#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ +}; + +struct shell_uart_int_driven { + struct shell_uart_common common; + struct ring_buf tx_ringbuf; + struct ring_buf rx_ringbuf; + struct k_timer dtr_timer; + atomic_t tx_busy; +}; + +struct shell_uart_async { + struct shell_uart_common common; + struct k_sem tx_sem; + struct uart_async_rx async_rx; + atomic_t pending_rx_req; +}; + +struct shell_uart_polling { + struct shell_uart_common common; + struct ring_buf rx_ringbuf; + struct k_timer rx_timer; +}; + +static uint8_t __noinit async_rx_data[ASYNC_RX_BUF_SIZE]; +static uint8_t __noinit rx_ringbuf_data[CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE]; +static uint8_t __noinit tx_ringbuf_data[CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE]; + +static struct shell_uart_int_driven shell_uart_i; +static struct shell_uart_async shell_uart_a; +static struct shell_uart_polling shell_uart_p; + #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL NET_BUF_POOL_DEFINE(smp_shell_rx_pool, CONFIG_MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT, SMP_SHELL_RX_BUF_SIZE, 0, NULL); #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ -SHELL_UART_DEFINE(shell_transport_uart, - CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE, - CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE); -SHELL_DEFINE(shell_uart, CONFIG_SHELL_PROMPT_UART, &shell_transport_uart, - CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_SIZE, - CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_TIMEOUT, - SHELL_FLAG_OLF_CRLF); +static void async_callback(const struct device *dev, struct uart_event *evt, void *user_data) +{ + struct shell_uart_async *sh_uart = (struct shell_uart_async *)user_data; + + switch (evt->type) { + case UART_TX_DONE: + k_sem_give(&sh_uart->tx_sem); + break; + case UART_RX_RDY: + uart_async_rx_on_rdy(&sh_uart->async_rx, evt->data.rx.buf, evt->data.rx.len); + sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context); + break; + case UART_RX_BUF_REQUEST: + { + uint8_t *buf = uart_async_rx_buf_req(&sh_uart->async_rx); + size_t len = uart_async_rx_get_buf_len(&sh_uart->async_rx); + + if (buf) { + int err = uart_rx_buf_rsp(dev, buf, len); + + if (err < 0) { + uart_async_rx_on_buf_rel(&sh_uart->async_rx, buf); + } + } else { + atomic_inc(&sh_uart->pending_rx_req); + } -#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN -static void uart_rx_handle(const struct device *dev, - const struct shell_uart *sh_uart) + break; + } + case UART_RX_BUF_RELEASED: + uart_async_rx_on_buf_rel(&sh_uart->async_rx, evt->data.rx_buf.buf); + break; + case UART_RX_DISABLED: + break; + default: + break; + }; +} + +static void uart_rx_handle(const struct device *dev, struct shell_uart_int_driven *sh_uart) { uint8_t *data; uint32_t len; uint32_t rd_len; bool new_data = false; #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL - struct smp_shell_data *const smp = &sh_uart->ctrl_blk->smp; + struct smp_shell_data *const smp = &sh_uart->common.smp; #endif do { - len = ring_buf_put_claim(sh_uart->rx_ringbuf, &data, - sh_uart->rx_ringbuf->size); + len = ring_buf_put_claim(&sh_uart->rx_ringbuf, &data, + sh_uart->rx_ringbuf.size); if (len > 0) { rd_len = uart_fifo_read(dev, data, len); @@ -72,8 +164,7 @@ static void uart_rx_handle(const struct device *dev, } } #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ - int err = ring_buf_put_finish(sh_uart->rx_ringbuf, - rd_len); + int err = ring_buf_put_finish(&sh_uart->rx_ringbuf, rd_len); (void)err; __ASSERT_NO_MSG(err == 0); } else { @@ -87,8 +178,7 @@ static void uart_rx_handle(const struct device *dev, /* If successful in getting byte from the fifo, try * feeding it to SMP as a part of mcumgr frame. */ - if ((rd_len != 0) && - (smp_shell_rx_bytes(smp, &dummy, 1) == 1)) { + if ((rd_len != 0) && (smp_shell_rx_bytes(smp, &dummy, 1) == 1)) { new_data = true; } #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ @@ -96,8 +186,7 @@ static void uart_rx_handle(const struct device *dev, } while (rd_len && (rd_len == len)); if (new_data) { - sh_uart->ctrl_blk->handler(SHELL_TRANSPORT_EVT_RX_RDY, - sh_uart->ctrl_blk->context); + sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context); } } @@ -123,19 +212,18 @@ static bool uart_dtr_check(const struct device *dev) static void dtr_timer_handler(struct k_timer *timer) { - const struct shell_uart *sh_uart = k_timer_user_data_get(timer); + struct shell_uart_int_driven *sh_uart = k_timer_user_data_get(timer); - if (!uart_dtr_check(sh_uart->ctrl_blk->dev)) { + if (!uart_dtr_check(sh_uart->common.dev)) { return; } /* DTR is active, stop timer and start TX */ k_timer_stop(timer); - uart_irq_tx_enable(sh_uart->ctrl_blk->dev); + uart_irq_tx_enable(sh_uart->common.dev); } -static void uart_tx_handle(const struct device *dev, - const struct shell_uart *sh_uart) +static void uart_tx_handle(const struct device *dev, struct shell_uart_int_driven *sh_uart) { uint32_t len; const uint8_t *data; @@ -143,31 +231,30 @@ static void uart_tx_handle(const struct device *dev, if (!uart_dtr_check(dev)) { /* Wait for DTR signal before sending anything to output. */ uart_irq_tx_disable(dev); - k_timer_start(sh_uart->dtr_timer, K_MSEC(100), K_MSEC(100)); + k_timer_start(&sh_uart->dtr_timer, K_MSEC(100), K_MSEC(100)); return; } - len = ring_buf_get_claim(sh_uart->tx_ringbuf, (uint8_t **)&data, - sh_uart->tx_ringbuf->size); + len = ring_buf_get_claim(&sh_uart->tx_ringbuf, (uint8_t **)&data, + sh_uart->tx_ringbuf.size); if (len) { int err; len = uart_fifo_fill(dev, data, len); - err = ring_buf_get_finish(sh_uart->tx_ringbuf, len); + err = ring_buf_get_finish(&sh_uart->tx_ringbuf, len); __ASSERT_NO_MSG(err == 0); ARG_UNUSED(err); } else { uart_irq_tx_disable(dev); - sh_uart->ctrl_blk->tx_busy = 0; + sh_uart->tx_busy = 0; } - sh_uart->ctrl_blk->handler(SHELL_TRANSPORT_EVT_TX_RDY, - sh_uart->ctrl_blk->context); + sh_uart->common.handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->common.context); } static void uart_callback(const struct device *dev, void *user_data) { - const struct shell_uart *sh_uart = (struct shell_uart *)user_data; + struct shell_uart_int_driven *sh_uart = (struct shell_uart_int_driven *)user_data; uart_irq_update(dev); @@ -179,80 +266,135 @@ static void uart_callback(const struct device *dev, void *user_data) uart_tx_handle(dev, sh_uart); } } -#endif /* CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN */ -static void uart_irq_init(const struct shell_uart *sh_uart) +static void irq_init(struct shell_uart_int_driven *sh_uart) { -#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN - const struct device *dev = sh_uart->ctrl_blk->dev; + const struct device *dev = sh_uart->common.dev; - ring_buf_reset(sh_uart->tx_ringbuf); - ring_buf_reset(sh_uart->rx_ringbuf); - sh_uart->ctrl_blk->tx_busy = 0; + ring_buf_init(&sh_uart->rx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE, + rx_ringbuf_data); + ring_buf_init(&sh_uart->tx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE, + tx_ringbuf_data); + sh_uart->tx_busy = 0; uart_irq_callback_user_data_set(dev, uart_callback, (void *)sh_uart); uart_irq_rx_enable(dev); if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR)) { - k_timer_init(sh_uart->dtr_timer, dtr_timer_handler, NULL); - k_timer_user_data_set(sh_uart->dtr_timer, (void *)sh_uart); + k_timer_init(&sh_uart->dtr_timer, dtr_timer_handler, NULL); + k_timer_user_data_set(&sh_uart->dtr_timer, (void *)sh_uart); } -#endif } -static void timer_handler(struct k_timer *timer) +static int rx_enable(const struct device *dev, uint8_t *buf, size_t len) +{ + return uart_rx_enable(dev, buf, len, 10000); +} + +static void async_init(struct shell_uart_async *sh_uart) +{ + static const struct uart_async_rx_config async_rx_config = { + .buffer = async_rx_data, + .length = sizeof(async_rx_data), + .buf_cnt = CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT + }; + const struct device *dev = sh_uart->common.dev; + struct uart_async_rx *async_rx = &sh_uart->async_rx; + int err; + + k_sem_init(&sh_uart->tx_sem, 0, 1); + + err = uart_async_rx_init(async_rx, &async_rx_config); + (void)err; + __ASSERT_NO_MSG(err == 0); + + uint8_t *buf = uart_async_rx_buf_req(async_rx); + + err = uart_callback_set(dev, async_callback, (void *)sh_uart); + (void)err; + __ASSERT_NO_MSG(err == 0); + + err = rx_enable(dev, buf, uart_async_rx_get_buf_len(async_rx)); + (void)err; + __ASSERT_NO_MSG(err == 0); +} + +static void polling_rx_timeout_handler(struct k_timer *timer) { uint8_t c; - const struct shell_uart *sh_uart = k_timer_user_data_get(timer); + struct shell_uart_polling *sh_uart = k_timer_user_data_get(timer); - while (uart_poll_in(sh_uart->ctrl_blk->dev, &c) == 0) { - if (ring_buf_put(sh_uart->rx_ringbuf, &c, 1) == 0U) { + while (uart_poll_in(sh_uart->common.dev, &c) == 0) { + if (ring_buf_put(&sh_uart->rx_ringbuf, &c, 1) == 0U) { /* ring buffer full. */ LOG_WRN("RX ring buffer full."); } - sh_uart->ctrl_blk->handler(SHELL_TRANSPORT_EVT_RX_RDY, - sh_uart->ctrl_blk->context); + sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context); } } +static void polling_init(struct shell_uart_polling *sh_uart) +{ + k_timer_init(&sh_uart->rx_timer, polling_rx_timeout_handler, NULL); + k_timer_user_data_set(&sh_uart->rx_timer, (void *)sh_uart); + k_timer_start(&sh_uart->rx_timer, RX_POLL_PERIOD, RX_POLL_PERIOD); + + ring_buf_init(&sh_uart->rx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE, + rx_ringbuf_data); +} + static int init(const struct shell_transport *transport, const void *config, shell_transport_handler_t evt_handler, void *context) { - const struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; + struct shell_uart_common *common = (struct shell_uart_common *)transport->ctx; - sh_uart->ctrl_blk->dev = (const struct device *)config; - sh_uart->ctrl_blk->handler = evt_handler; - sh_uart->ctrl_blk->context = context; + common->dev = (const struct device *)config; + common->handler = evt_handler; + common->context = context; #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL - sh_uart->ctrl_blk->smp.buf_pool = &smp_shell_rx_pool; - k_fifo_init(&sh_uart->ctrl_blk->smp.buf_ready); + common->smp.buf_pool = &smp_shell_rx_pool; + k_fifo_init(&common->smp.buf_ready); #endif - if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN)) { - uart_irq_init(sh_uart); + if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) { + async_init((struct shell_uart_async *)transport->ctx); + } else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) { + irq_init((struct shell_uart_int_driven *)transport->ctx); } else { - k_timer_init(sh_uart->timer, timer_handler, NULL); - k_timer_user_data_set(sh_uart->timer, (void *)sh_uart); - k_timer_start(sh_uart->timer, RX_POLL_PERIOD, RX_POLL_PERIOD); + polling_init((struct shell_uart_polling *)transport->ctx); } return 0; } -static int uninit(const struct shell_transport *transport) +static void irq_uninit(struct shell_uart_int_driven *sh_uart) { - const struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; + const struct device *dev = sh_uart->common.dev; - if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN)) { - const struct device *dev = sh_uart->ctrl_blk->dev; + k_timer_stop(&sh_uart->dtr_timer); + uart_irq_tx_disable(dev); + uart_irq_rx_disable(dev); +} - k_timer_stop(sh_uart->dtr_timer); - uart_irq_tx_disable(dev); - uart_irq_rx_disable(dev); +static void async_uninit(struct shell_uart_async *sh_uart) +{ +} + +static void polling_uninit(struct shell_uart_polling *sh_uart) +{ + k_timer_stop(&sh_uart->rx_timer); +} + +static int uninit(const struct shell_transport *transport) +{ + if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) { + async_uninit((struct shell_uart_async *)transport->ctx); + } else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) { + irq_uninit((struct shell_uart_int_driven *)transport->ctx); } else { - k_timer_stop(sh_uart->timer); + polling_uninit((struct shell_uart_polling *)transport->ctx); } return 0; @@ -260,70 +402,161 @@ static int uninit(const struct shell_transport *transport) static int enable(const struct shell_transport *transport, bool blocking_tx) { - const struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; + struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx; - sh_uart->ctrl_blk->blocking_tx = blocking_tx; + sh_uart->blocking_tx = blocking_tx; - if (blocking_tx) { -#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN - uart_irq_tx_disable(sh_uart->ctrl_blk->dev); -#endif + if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN) && blocking_tx) { + uart_irq_tx_disable(sh_uart->dev); } return 0; } -static void irq_write(const struct shell_uart *sh_uart, const void *data, - size_t length, size_t *cnt) +static int polling_write(struct shell_uart_common *sh_uart, + const void *data, size_t length, size_t *cnt) { - *cnt = ring_buf_put(sh_uart->tx_ringbuf, data, length); + const uint8_t *data8 = (const uint8_t *)data; - if (atomic_set(&sh_uart->ctrl_blk->tx_busy, 1) == 0) { -#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN - uart_irq_tx_enable(sh_uart->ctrl_blk->dev); -#endif + for (size_t i = 0; i < length; i++) { + uart_poll_out(sh_uart->dev, data8[i]); } + + *cnt = length; + + sh_uart->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->context); + + return 0; +} + +static int irq_write(struct shell_uart_int_driven *sh_uart, + const void *data, size_t length, size_t *cnt) +{ + *cnt = ring_buf_put(&sh_uart->tx_ringbuf, data, length); + + if (atomic_set(&sh_uart->tx_busy, 1) == 0) { + uart_irq_tx_enable(sh_uart->common.dev); + } + + return 0; +} + +static int async_write(struct shell_uart_async *sh_uart, + const void *data, size_t length, size_t *cnt) +{ + int err; + + err = uart_tx(sh_uart->common.dev, data, length, SYS_FOREVER_US); + if (err < 0) { + *cnt = 0; + return err; + } + + err = k_sem_take(&sh_uart->tx_sem, K_FOREVER); + *cnt = length; + + sh_uart->common.handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->common.context); + + return err; } static int write(const struct shell_transport *transport, const void *data, size_t length, size_t *cnt) { - const struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; - const uint8_t *data8 = (const uint8_t *)data; + struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx; - if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN) && - !sh_uart->ctrl_blk->blocking_tx) { - irq_write(sh_uart, data, length, cnt); + if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_POLLING) || sh_uart->blocking_tx) { + return polling_write(sh_uart, data, length, cnt); + } else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) { + return irq_write((struct shell_uart_int_driven *)transport->ctx, data, length, cnt); } else { - for (size_t i = 0; i < length; i++) { - uart_poll_out(sh_uart->ctrl_blk->dev, data8[i]); - } + return async_write((struct shell_uart_async *)transport->ctx, data, length, cnt); + } +} - *cnt = length; +static int irq_read(struct shell_uart_int_driven *sh_uart, + void *data, size_t length, size_t *cnt) +{ + *cnt = ring_buf_get(&sh_uart->rx_ringbuf, data, length); - sh_uart->ctrl_blk->handler(SHELL_TRANSPORT_EVT_TX_RDY, - sh_uart->ctrl_blk->context); - } + return 0; +} + +static int polling_read(struct shell_uart_polling *sh_uart, + void *data, size_t length, size_t *cnt) +{ + *cnt = ring_buf_get(&sh_uart->rx_ringbuf, data, length); return 0; } -static int read(const struct shell_transport *transport, - void *data, size_t length, size_t *cnt) +static int async_read(struct shell_uart_async *sh_uart, + void *data, size_t length, size_t *cnt) { - struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; + uint8_t *buf; + size_t blen; + struct uart_async_rx *async_rx = &sh_uart->async_rx; + + blen = uart_async_rx_data_claim(async_rx, &buf, length); +#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL + struct smp_shell_data *const smp = &sh_uart->common.smp; + size_t sh_cnt = 0; + + for (size_t i = 0; i < blen; i++) { + if (smp_shell_rx_bytes(smp, &buf[i], 1) == 0) { + data[sh_cnt++] = buf[i]; + } + } +#else + size_t sh_cnt = blen; - *cnt = ring_buf_get(sh_uart->rx_ringbuf, data, length); + memcpy(data, buf, blen); +#endif + uart_async_rx_data_consume(async_rx, sh_cnt); + *cnt = sh_cnt; + + if (sh_uart->pending_rx_req) { + uint8_t *buf = uart_async_rx_buf_req(async_rx); + + if (buf) { + int err; + size_t len = uart_async_rx_get_buf_len(async_rx); + + atomic_dec(&sh_uart->pending_rx_req); + err = uart_rx_buf_rsp(sh_uart->common.dev, buf, len); + /* If it is too late and RX is disabled then re-enable it. */ + if (err < 0) { + if (err == -EACCES) { + sh_uart->pending_rx_req = 0; + err = rx_enable(sh_uart->common.dev, buf, len); + } else { + return err; + } + } + } + } return 0; } +static int read(const struct shell_transport *transport, + void *data, size_t length, size_t *cnt) +{ + if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) { + return irq_read((struct shell_uart_int_driven *)transport->ctx, data, length, cnt); + } else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) { + return async_read((struct shell_uart_async *)transport->ctx, data, length, cnt); + } else { + return polling_read((struct shell_uart_polling *)transport->ctx, data, length, cnt); + } +} + #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL static void update(const struct shell_transport *transport) { - struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx; + struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx; - smp_shell_process(&sh_uart->ctrl_blk->smp); + smp_shell_process(&sh_uart->smp); } #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ @@ -338,6 +571,18 @@ const struct shell_transport_api shell_uart_transport_api = { #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */ }; +struct shell_transport shell_transport_uart = { + .api = &shell_uart_transport_api, + .ctx = IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_POLLING) ? (void *)&shell_uart_p : + (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC) ? (void *)&shell_uart_a : + (void *)&shell_uart_i) +}; + +SHELL_DEFINE(shell_uart, CONFIG_SHELL_PROMPT_UART, &shell_transport_uart, + CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_SIZE, + CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_TIMEOUT, + SHELL_FLAG_OLF_CRLF); + static int enable_shell_uart(void) { const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); From 8b98acb77b764d2909b25832e435b414f6c36d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 25 Oct 2023 18:39:59 +0200 Subject: [PATCH 3538/4498] boards: esp32: Add support for M5Stack AtomS3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces support for the ESP32S3 based M5Stack AtomS3. Signed-off-by: Benjamin Cabé --- boards/xtensa/m5stack_atoms3/Kconfig.board | 12 ++ .../xtensa/m5stack_atoms3/Kconfig.defconfig | 29 +++ boards/xtensa/m5stack_atoms3/board.cmake | 9 + .../doc/img/m5stack_atoms3.webp | Bin 0 -> 20380 bytes boards/xtensa/m5stack_atoms3/doc/index.rst | 136 +++++++++++++ .../m5stack_atoms3/grove_connectors.dtsi | 17 ++ .../m5stack_atoms3-pinctrl.dtsi | 54 +++++ .../xtensa/m5stack_atoms3/m5stack_atoms3.dts | 186 ++++++++++++++++++ .../xtensa/m5stack_atoms3/m5stack_atoms3.yaml | 21 ++ .../m5stack_atoms3/m5stack_atoms3_defconfig | 13 ++ 10 files changed, 477 insertions(+) create mode 100644 boards/xtensa/m5stack_atoms3/Kconfig.board create mode 100644 boards/xtensa/m5stack_atoms3/Kconfig.defconfig create mode 100644 boards/xtensa/m5stack_atoms3/board.cmake create mode 100644 boards/xtensa/m5stack_atoms3/doc/img/m5stack_atoms3.webp create mode 100644 boards/xtensa/m5stack_atoms3/doc/index.rst create mode 100644 boards/xtensa/m5stack_atoms3/grove_connectors.dtsi create mode 100644 boards/xtensa/m5stack_atoms3/m5stack_atoms3-pinctrl.dtsi create mode 100644 boards/xtensa/m5stack_atoms3/m5stack_atoms3.dts create mode 100644 boards/xtensa/m5stack_atoms3/m5stack_atoms3.yaml create mode 100644 boards/xtensa/m5stack_atoms3/m5stack_atoms3_defconfig diff --git a/boards/xtensa/m5stack_atoms3/Kconfig.board b/boards/xtensa/m5stack_atoms3/Kconfig.board new file mode 100644 index 00000000000..726e31773e2 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/Kconfig.board @@ -0,0 +1,12 @@ +# M5Stack AtomS3 board configuration + +# Copyright (c) 2023 Benjamin Cabé +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_M5STACK_ATOMS3 + bool "M5Stack AtomS3 Development Board" + depends on SOC_SERIES_ESP32S3 + +choice SOC_PART_NUMBER + default SOC_ESP32S3_FN8 +endchoice diff --git a/boards/xtensa/m5stack_atoms3/Kconfig.defconfig b/boards/xtensa/m5stack_atoms3/Kconfig.defconfig new file mode 100644 index 00000000000..b9bd2641458 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/Kconfig.defconfig @@ -0,0 +1,29 @@ +# M5Stack AtomS3 board configuration +# Copyright (c) 2023 Benjamin Cabé +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_M5STACK_ATOMS3 + +config BOARD + default "m5stack_atoms3" + depends on BOARD_M5STACK_ATOMS3 + +config ENTROPY_GENERATOR + default y + +config HEAP_MEM_POOL_SIZE + default 98304 if WIFI + default 65536 if BT + default 4096 + +config KERNEL_MEM_POOL + default y + +choice BT_HCI_BUS_TYPE + default BT_ESP32 if BT +endchoice + +config LV_COLOR_16_SWAP + default y if LVGL + +endif # BOARD_M5STACK_ATOMS3 diff --git a/boards/xtensa/m5stack_atoms3/board.cmake b/boards/xtensa/m5stack_atoms3/board.cmake new file mode 100644 index 00000000000..2f04d1fe886 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/xtensa/m5stack_atoms3/doc/img/m5stack_atoms3.webp b/boards/xtensa/m5stack_atoms3/doc/img/m5stack_atoms3.webp new file mode 100644 index 0000000000000000000000000000000000000000..b4b964069b4159da55ee04a2a0c113a2bb24be9d GIT binary patch literal 20380 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 Tk0jSdS{ni>0fYd=_3!-;A|r<= literal 0 HcmV?d00001 diff --git a/boards/xtensa/m5stack_atoms3/doc/index.rst b/boards/xtensa/m5stack_atoms3/doc/index.rst new file mode 100644 index 00000000000..2dd229be436 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/doc/index.rst @@ -0,0 +1,136 @@ +.. _m5stack_atoms3: + +M5Stack AtomS3 +############## + +Overview +******** + +M5Stack AtomS3 is an ESP32-based development board from M5Stack. + +It features the following integrated components: + +- ESP32-S3FN8 chip (240MHz dual core, Wi-Fi/BLE 5.0) +- 512KB of SRAM +- 384KB of ROM +- 8MB of Flash +- LCD IPS TFT 0.85", 128x128 px screen (ST7789 compatible) +- 6-axis IMU MPU6886 +- Infrared emitter + + +.. figure:: img/m5stack_atoms3.webp + :align: center + :alt: M5Stack AtomS3 + + M5Stack AtomS3 + + +Supported Features +================== + +The Zephyr m5stack_atoms3 board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtc | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| DAC | on-chip | dac | ++-----------+------------+-------------------------------------+ +| die-temp | on-chip | die temperature sensor | ++-----------+------------+-------------------------------------+ + + +Start Application Development +***************************** + +Before powering up your M5Stack AtomS3, please make sure that the board is in good +condition with no obvious signs of damage. + +System requirements +=================== + +Prerequisites +------------- + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: shell + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +------------------- + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: m5stack_atoms3 + :goals: build + +The usual ``flash`` target will work with the ``m5stack_atoms3`` board +configuration. Here is an example for the :ref:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: m5stack_atoms3 + :goals: flash + +The baud rate of 921600bps is set by default. If experiencing issues when flashing, +try using different values by using ``--esp-baud-rate `` option during +``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). + +You can also open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! m5stack_atoms3 + +Debugging +--------- + +M5Stack AtomS3 debugging is not supported due to pinout limitations. + +Related Documents +***************** + +- `M5Stack AtomS3 schematic `_ +- `ESP32S3 Datasheet `_ diff --git a/boards/xtensa/m5stack_atoms3/grove_connectors.dtsi b/boards/xtensa/m5stack_atoms3/grove_connectors.dtsi new file mode 100644 index 00000000000..798c40cf296 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/grove_connectors.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Benjamin Cabé + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + grove_header: grove_header { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 1 0>, + <1 0 &gpio0 2 0>; + }; +}; + +grove_i2c1: &i2c1 {}; diff --git a/boards/xtensa/m5stack_atoms3/m5stack_atoms3-pinctrl.dtsi b/boards/xtensa/m5stack_atoms3/m5stack_atoms3-pinctrl.dtsi new file mode 100644 index 00000000000..0f59b0bc6a8 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/m5stack_atoms3-pinctrl.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Benjamin Cabé + * + * 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; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + ; + }; + group2 { + pinmux = ; + output-low; + }; + + }; +}; diff --git a/boards/xtensa/m5stack_atoms3/m5stack_atoms3.dts b/boards/xtensa/m5stack_atoms3/m5stack_atoms3.dts new file mode 100644 index 00000000000..abbff8bbbfd --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/m5stack_atoms3.dts @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2023 Benjamin Cabé + * + * SPDX-License-Identifier: Apache-2.0 + */ +/dts-v1/; + +#include +#include "m5stack_atoms3-pinctrl.dtsi" +#include "grove_connectors.dtsi" +#include + +/ { + model = "M5Stack AtomS3"; + compatible = "m5stack,atoms3"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + zephyr,display = &st7789v; + }; + + aliases { + sw0 = &user_button_0; + watchdog0 = &wdt0; + accel0 = &mpu6886; + }; + + gpio_keys { + compatible = "gpio-keys"; + + /* This is the button that's underneath the LCD display */ + user_button_0: button_0 { + label = "User button 0"; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; // G42 + zephyr,code = ; + }; + }; + + /* Regulators */ + lcd_backlight_en { + compatible = "regulator-fixed"; + regulator-name = "lcd_backlight_enable"; + enable-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; + +}; + +&cpu0 { + clock-frequency = ; +}; + +&cpu1 { + clock-frequency = ; +}; + +&usb_serial { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + + mpu6886: mpu6886@68 { + compatible = "invensense,mpu6050"; + reg = <0x68>; + status = "okay"; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; +}; + +&trng0 { + status = "okay"; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; + + st7789v: st7789v@0 { + compatible = "sitronix,st7789v"; + reg = <0>; + spi-max-frequency = <27000000>; + cmd-data-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; /* G33 */ + reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* G34 */ + + width = <128>; + height = <128>; + x-offset = <2>; + y-offset = <1>; + + vcom = <0x28>; + gctrl = <0x35>; + vrhs = <0x10>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x55>; + lcm = <0x0c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 00]; + pwctrl1-param = [a4 a1]; + pvgam-param = [d0 00 02 07 0a 28 32 44 42 06 0e 12 14 17]; + nvgam-param = [d0 00 02 07 0a 28 31 54 47 0e 1c 17 1b 1e]; + ram-param = [00 E0]; + rgb-param = [40 02 14]; + }; + +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&flash0 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000F000>; + read-only; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; diff --git a/boards/xtensa/m5stack_atoms3/m5stack_atoms3.yaml b/boards/xtensa/m5stack_atoms3/m5stack_atoms3.yaml new file mode 100644 index 00000000000..ed34b2f551d --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/m5stack_atoms3.yaml @@ -0,0 +1,21 @@ +identifier: m5stack_atoms3 +name: M5Stack AtomS3 +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - i2c + - spi + - watchdog + - regulator + - uart + - pinmux + - nvs + - display +testing: + ignore_tags: + - net + - bluetooth +vendor: m5stack diff --git a/boards/xtensa/m5stack_atoms3/m5stack_atoms3_defconfig b/boards/xtensa/m5stack_atoms3/m5stack_atoms3_defconfig new file mode 100644 index 00000000000..1000271dbe5 --- /dev/null +++ b/boards/xtensa/m5stack_atoms3/m5stack_atoms3_defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOARD_M5STACK_ATOMS3=y +CONFIG_SOC_SERIES_ESP32S3=y + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_GPIO=y +CONFIG_REGULATOR=y # for LCD backlight + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y From 1fbcccd2fc0325c13e8f133a717d09c921444e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 10 Nov 2023 10:14:17 +0100 Subject: [PATCH 3539/4498] boards: xtensa: Set M5Stack vendor for M5Stack boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s/espressif/extensa/ for the couple M5Stack boards in-tree that had the wrong vendor set. Signed-off-by: Benjamin Cabé --- boards/xtensa/m5stack_core2/m5stack_core2.dts | 4 ++-- boards/xtensa/m5stack_core2/m5stack_core2.yaml | 2 +- boards/xtensa/m5stickc_plus/m5stickc_plus.dts | 4 ++-- boards/xtensa/m5stickc_plus/m5stickc_plus.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.dts b/boards/xtensa/m5stack_core2/m5stack_core2.dts index 5fb6f0cc495..41ccb5be074 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.dts +++ b/boards/xtensa/m5stack_core2/m5stack_core2.dts @@ -13,8 +13,8 @@ #include / { - model = "esp32"; - compatible = "espressif,esp32"; + model = "M5Stack Core2"; + compatible = "m5stack,core2"; aliases { pwr-led = &pwr_led; diff --git a/boards/xtensa/m5stack_core2/m5stack_core2.yaml b/boards/xtensa/m5stack_core2/m5stack_core2.yaml index 35dd0c12b46..78b361e8834 100644 --- a/boards/xtensa/m5stack_core2/m5stack_core2.yaml +++ b/boards/xtensa/m5stack_core2/m5stack_core2.yaml @@ -17,4 +17,4 @@ testing: ignore_tags: - net - bluetooth -vendor: espressif +vendor: m5stack diff --git a/boards/xtensa/m5stickc_plus/m5stickc_plus.dts b/boards/xtensa/m5stickc_plus/m5stickc_plus.dts index 0254d82003d..8cdd4170ba5 100644 --- a/boards/xtensa/m5stickc_plus/m5stickc_plus.dts +++ b/boards/xtensa/m5stickc_plus/m5stickc_plus.dts @@ -10,8 +10,8 @@ #include / { - model = "esp32"; - compatible = "espressif,esp32"; + model = "M5StickC Plus"; + compatible = "m5stack,m5stickc-plus"; aliases { led0 = &red_led; diff --git a/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml b/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml index dbd09151be1..821770c2be4 100644 --- a/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml +++ b/boards/xtensa/m5stickc_plus/m5stickc_plus.yaml @@ -16,4 +16,4 @@ testing: ignore_tags: - net - bluetooth -vendor: espressif +vendor: m5stack From 78714b193a56182998dd8c0a6c4415b16d79d819 Mon Sep 17 00:00:00 2001 From: Lars Knudsen Date: Tue, 31 Oct 2023 07:56:12 +0100 Subject: [PATCH 3540/4498] samples: Add USB Audio to broadcast audio source Adds support for using a connected host to broadcast audio via USB Audio. Offload LC3 encoding to separate thread. Signed-off-by: Lars Knudsen --- .../bluetooth/broadcast_audio_source/Kconfig | 9 + .../nrf5340_audio_dk_nrf5340_cpuapp.conf | 10 +- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 3 - .../bluetooth/broadcast_audio_source/prj.conf | 2 - .../broadcast_audio_source/src/main.c | 353 ++++++++++++++---- 5 files changed, 297 insertions(+), 80 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig b/samples/bluetooth/broadcast_audio_source/Kconfig index cc3e714ded7..d88378d0848 100644 --- a/samples/bluetooth/broadcast_audio_source/Kconfig +++ b/samples/bluetooth/broadcast_audio_source/Kconfig @@ -28,4 +28,13 @@ config ENABLE_LC3 select LIBLC3 select FPU +config USE_USB_AUDIO_INPUT + bool "Use USB Audio as input" + # By default, use the USB Audio path is disabled. + default n + depends on ENABLE_LC3 + select USB_DEVICE_STACK + select USB_DEVICE_AUDIO + select RING_BUFFER + source "Kconfig.zephyr" diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 8d28a7031d2..ff8004f0dc0 100644 --- a/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,4 +1,8 @@ -# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence -# inctease stack size for that thread. -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 + +# Use USB Audio as input +CONFIG_USE_USB_AUDIO_INPUT=y +CONFIG_USB_DEVICE_PRODUCT="Zephyr Broadcast Source" + +# Two streams in one subgroup (stereo) +CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=1 diff --git a/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf index 8d28a7031d2..5df721fba26 100644 --- a/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/broadcast_audio_source/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,4 +1 @@ -# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence -# inctease stack size for that thread. -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/bluetooth/broadcast_audio_source/prj.conf b/samples/bluetooth/broadcast_audio_source/prj.conf index 2e0fcb778de..d74cbbe50ce 100644 --- a/samples/bluetooth/broadcast_audio_source/prj.conf +++ b/samples/bluetooth/broadcast_audio_source/prj.conf @@ -13,5 +13,3 @@ CONFIG_BT_ISO_TX_BUF_COUNT=4 CONFIG_BT_ISO_TX_MTU=60 CONFIG_BT_DEVICE_NAME="Broadcast Audio Source" - -CONFIG_BT_TINYCRYPT_ECC=y diff --git a/samples/bluetooth/broadcast_audio_source/src/main.c b/samples/bluetooth/broadcast_audio_source/src/main.c index f9a2a5330b2..8a129e3f361 100644 --- a/samples/bluetooth/broadcast_audio_source/src/main.c +++ b/samples/bluetooth/broadcast_audio_source/src/main.c @@ -35,19 +35,93 @@ BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED, #if defined(CONFIG_BAP_BROADCAST_16_2_1) static struct bt_bap_lc3_preset preset_active = BT_BAP_LC3_BROADCAST_PRESET_16_2_1( - BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT, + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +#define BROADCAST_SAMPLE_RATE 16000 #elif defined(CONFIG_BAP_BROADCAST_24_2_1) static struct bt_bap_lc3_preset preset_active = BT_BAP_LC3_BROADCAST_PRESET_24_2_1( - BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT, + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +#define BROADCAST_SAMPLE_RATE 24000 + +#endif +#if defined(CONFIG_BAP_BROADCAST_16_2_1) +#define MAX_SAMPLE_RATE 16000 +#elif defined(CONFIG_BAP_BROADCAST_24_2_1) +#define MAX_SAMPLE_RATE 24000 #endif +#define MAX_FRAME_DURATION_US 10000 +#define MAX_NUM_SAMPLES ((MAX_FRAME_DURATION_US * MAX_SAMPLE_RATE) / USEC_PER_SEC) + +#if defined(CONFIG_LIBLC3) +#include "lc3.h" + +#if defined(CONFIG_USB_DEVICE_AUDIO) +#include +#include +#include + +/* USB Audio Data is downsampled from 48kHz to match broadcast preset when receiving data */ +#define USB_SAMPLE_RATE 48000 +#define USB_DOWNSAMPLE_RATE BROADCAST_SAMPLE_RATE +#define USB_FRAME_DURATION_US 1000 +#define USB_NUM_SAMPLES ((USB_FRAME_DURATION_US * USB_DOWNSAMPLE_RATE) / USEC_PER_SEC) +#define USB_BYTES_PER_SAMPLE 2 +#define USB_CHANNELS 2 + +#define RING_BUF_USB_FRAMES 20 +#define AUDIO_RING_BUF_BYTES USB_NUM_SAMPLES * USB_BYTES_PER_SAMPLE * RING_BUF_USB_FRAMES +#else /* !defined(CONFIG_USB_DEVICE_AUDIO) */ + +#include + +#define AUDIO_VOLUME (INT16_MAX - 3000) /* codec does clipping above INT16_MAX - 3000 */ +#define AUDIO_TONE_FREQUENCY_HZ 400 + +/** + * Use the math lib to generate a sine-wave using 16 bit samples into a buffer. + * + * @param buf Destination buffer + * @param length_us Length of the buffer in microseconds + * @param frequency_hz frequency in Hz + * @param sample_rate_hz sample-rate in Hz. + */ +static void fill_audio_buf_sin(int16_t *buf, int length_us, int frequency_hz, int sample_rate_hz) +{ + const int sine_period_samples = sample_rate_hz / frequency_hz; + const unsigned int num_samples = (length_us * sample_rate_hz) / USEC_PER_SEC; + const float step = 2 * 3.1415f / sine_period_samples; + + for (unsigned int i = 0; i < num_samples; i++) { + const float sample = sin(i * step); + + buf[i] = (int16_t)(AUDIO_VOLUME * sample); + } +} +#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_LIBLC3) */ static struct broadcast_source_stream { struct bt_bap_stream stream; uint16_t seq_num; size_t sent_cnt; +#if defined(CONFIG_LIBLC3) + lc3_encoder_t lc3_encoder; +#if defined(CONFIG_BAP_BROADCAST_16_2_1) + lc3_encoder_mem_16k_t lc3_encoder_mem; +#elif defined(CONFIG_BAP_BROADCAST_24_2_1) + lc3_encoder_mem_48k_t lc3_encoder_mem; +#endif +#if defined(CONFIG_USB_DEVICE_AUDIO) + struct ring_buf audio_ring_buf; + uint8_t _ring_buffer_memory[AUDIO_RING_BUF_BYTES]; +#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_LIBLC3) */ } streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; static struct bt_bap_broadcast_source *broadcast_source; @@ -55,10 +129,8 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); -#define MAX_SAMPLE_RATE 16000 -#define MAX_FRAME_DURATION_US 10000 -#define MAX_NUM_SAMPLES ((MAX_FRAME_DURATION_US * MAX_SAMPLE_RATE) / USEC_PER_SEC) -static int16_t mock_data[MAX_NUM_SAMPLES]; + +static int16_t send_pcm_data[MAX_NUM_SAMPLES]; static uint16_t seq_num; static bool stopping; @@ -68,17 +140,80 @@ static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); #define BROADCAST_SOURCE_LIFETIME 120U /* seconds */ #if defined(CONFIG_LIBLC3) - -#include "lc3.h" - -static lc3_encoder_t lc3_encoder; -static lc3_encoder_mem_16k_t lc3_encoder_mem; static int freq_hz; static int frame_duration_us; static int frames_per_sdu; static int octets_per_frame; -static void init_lc3(void) +static K_SEM_DEFINE(lc3_encoder_sem, 0U, ARRAY_SIZE(streams)); +#endif + +static void send_data(struct broadcast_source_stream *source_stream) +{ + struct bt_bap_stream *stream = &source_stream->stream; + struct net_buf *buf; + int ret; + + if (stopping) { + return; + } + + buf = net_buf_alloc(&tx_pool, K_FOREVER); + if (buf == NULL) { + printk("Could not allocate buffer when sending on %p\n", + stream); + return; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); +#if defined(CONFIG_LIBLC3) + uint8_t lc3_encoded_buffer[preset_active.qos.sdu]; + + if (source_stream->lc3_encoder == NULL) { + printk("LC3 encoder not setup, cannot encode data.\n"); + return; + } + +#if defined(CONFIG_USB_DEVICE_AUDIO) + uint32_t size = ring_buf_get(&source_stream->audio_ring_buf, + (uint8_t *)send_pcm_data, sizeof(send_pcm_data)); + + if (size < sizeof(send_pcm_data)) { + const size_t padding_size = sizeof(send_pcm_data) - size; + + printk("Not enough bytes ready, padding %d!\n", padding_size); + memset(&((uint8_t *)send_pcm_data)[size], 0, padding_size); + } +#endif + + ret = lc3_encode(source_stream->lc3_encoder, LC3_PCM_FORMAT_S16, + send_pcm_data, 1, octets_per_frame, lc3_encoded_buffer); + if (ret == -1) { + printk("LC3 encoder failed - wrong parameters?: %d", ret); + return; + } + + net_buf_add_mem(buf, lc3_encoded_buffer, preset_active.qos.sdu); +#else + net_buf_add_mem(buf, send_pcm_data, preset_active.qos.sdu); +#endif /* defined(CONFIG_LIBLC3) */ + + ret = bt_bap_stream_send(stream, buf, source_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + /* This will end broadcasting on this stream. */ + printk("Unable to broadcast data on %p: %d\n", stream, ret); + net_buf_unref(buf); + return; + } + + source_stream->sent_cnt++; + if ((source_stream->sent_cnt % 1000U) == 0U) { + printk("Stream %p: Sent %u total ISO packets\n", stream, source_stream->sent_cnt); + } +} + +#if defined(CONFIG_LIBLC3) +static void init_lc3_thread(void *arg1, void *arg2, void *arg3) { const struct bt_audio_codec_cfg *codec_cfg = &preset_active.codec_cfg; int ret; @@ -116,14 +251,95 @@ static void init_lc3(void) return; } +#if !defined(CONFIG_USB_DEVICE_AUDIO) + /* If USB is not used as a sound source, generate a sine wave */ + fill_audio_buf_sin(send_pcm_data, frame_duration_us, AUDIO_TONE_FREQUENCY_HZ, freq_hz); +#endif + /* Create the encoder instance. This shall complete before stream_started() is called. */ - lc3_encoder = lc3_setup_encoder(frame_duration_us, freq_hz, 0, /* No resampling */ - &lc3_encoder_mem); + for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + printk("Initializing lc3 encoder for stream %zu\n", i); + streams[i].lc3_encoder = lc3_setup_encoder(frame_duration_us, freq_hz, + 0, &streams[i].lc3_encoder_mem); - if (lc3_encoder == NULL) { - printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); + if (streams[i].lc3_encoder == NULL) { + printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); + } + } + + while (true) { + for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + k_sem_take(&lc3_encoder_sem, K_FOREVER); + } + for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + send_data(&streams[i]); + } } } + +#define LC3_ENCODER_STACK_SIZE 4 * 4096 +#define LC3_ENCODER_PRIORITY 5 + +K_THREAD_DEFINE(encoder, LC3_ENCODER_STACK_SIZE, init_lc3_thread, + NULL, NULL, NULL, LC3_ENCODER_PRIORITY, 0, -1); + +#if defined(CONFIG_USB_DEVICE_AUDIO) +static void data_received(const struct device *dev, + struct net_buf *buffer, + size_t size) +{ + static int count; + int16_t *pcm; + int nsamples, ratio; + int16_t usb_pcm_data[USB_CHANNELS][USB_NUM_SAMPLES]; + + if (!buffer) { + return; + } + + if (!size) { + net_buf_unref(buffer); + return; + } + + pcm = (int16_t *)net_buf_pull_mem(buffer, size); + + /* 'size' is in bytes, containing 1ms, 48kHz, stereo, 2 bytes per sample. + * Take left channel and do a simple downsample to 16kHz/24Khz + * matching the broadcast preset. + */ + + ratio = USB_SAMPLE_RATE / USB_DOWNSAMPLE_RATE; + nsamples = size / (sizeof(int16_t) * USB_CHANNELS * ratio); + for (size_t i = 0, j = 0; i < nsamples; i++, j += USB_CHANNELS * ratio) { + usb_pcm_data[0][i] = pcm[j]; + usb_pcm_data[1][i] = pcm[j + 1]; + } + + for (size_t i = 0U; i < MIN(ARRAY_SIZE(streams), 2); i++) { + const uint32_t size_put = ring_buf_put(&(streams[i].audio_ring_buf), + (uint8_t *)(usb_pcm_data[i]), nsamples * USB_BYTES_PER_SAMPLE); + if (size_put < nsamples * USB_BYTES_PER_SAMPLE) { + printk("Not enough room for samples in %s buffer: %u < %u, total capacity: %u\n", + i == 0 ? "left" : "right", + size_put, + nsamples * USB_BYTES_PER_SAMPLE, + ring_buf_capacity_get(&(streams[i].audio_ring_buf))); + } + } + + count++; + if ((count % 1000) == 0) { + printk("USB Data received (count = %d)\n", count); + } + + net_buf_unref(buffer); +} + +static const struct usb_audio_ops ops = { + .data_received_cb = data_received +}; +#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ #endif /* defined(CONFIG_LIBLC3) */ static void stream_started_cb(struct bt_bap_stream *stream) @@ -143,57 +359,15 @@ static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) static void stream_sent_cb(struct bt_bap_stream *stream) { - struct broadcast_source_stream *source_stream = - CONTAINER_OF(stream, struct broadcast_source_stream, stream); - struct net_buf *buf; - int ret; - - if (stopping) { - return; - } - - buf = net_buf_alloc(&tx_pool, K_FOREVER); - if (buf == NULL) { - printk("Could not allocate buffer when sending on %p\n", - stream); - return; - } - - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); #if defined(CONFIG_LIBLC3) - int lc3_ret; - uint8_t lc3_encoder_buffer[preset_active.qos.sdu]; - - if (lc3_encoder == NULL) { - printk("LC3 encoder not setup, cannot encode data.\n"); - return; - } - - lc3_ret = lc3_encode(lc3_encoder, LC3_PCM_FORMAT_S16, mock_data, 1, octets_per_frame, - lc3_encoder_buffer); - - if (lc3_ret == -1) { - printk("LC3 encoder failed - wrong parameters?: %d", lc3_ret); - return; - } - - net_buf_add_mem(buf, lc3_encoder_buffer, preset_active.qos.sdu); + k_sem_give(&lc3_encoder_sem); #else - net_buf_add_mem(buf, mock_data, preset_active.qos.sdu); -#endif /* defined(CONFIG_LIBLC3) */ - - ret = bt_bap_stream_send(stream, buf, source_stream->seq_num++, BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - /* This will end broadcasting on this stream. */ - printk("Unable to broadcast data on %p: %d\n", stream, ret); - net_buf_unref(buf); - return; - } + /* If no LC3 encoder is used, just send mock data directly */ + struct broadcast_source_stream *source_stream = + CONTAINER_OF(stream, struct broadcast_source_stream, stream); - source_stream->sent_cnt++; - if ((source_stream->sent_cnt % 1000U) == 0U) { - printk("Stream %p: Sent %u total ISO packets\n", stream, source_stream->sent_cnt); - } + send_data(source_stream); +#endif } static struct bt_bap_stream_ops stream_ops = { @@ -210,10 +384,12 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) subgroup_param[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; struct bt_bap_broadcast_source_param create_param; const size_t streams_per_subgroup = ARRAY_SIZE(stream_params) / ARRAY_SIZE(subgroup_param); + uint8_t left[] = {BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, + BT_BYTES_LIST_LE32(BT_AUDIO_LOCATION_FRONT_LEFT))}; + uint8_t right[] = {BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, + BT_BYTES_LIST_LE32(BT_AUDIO_LOCATION_FRONT_RIGHT))}; int err; - (void)memset(streams, 0, sizeof(streams)); - for (size_t i = 0U; i < ARRAY_SIZE(subgroup_param); i++) { subgroup_param[i].params_count = streams_per_subgroup; subgroup_param[i].params = stream_params + i * streams_per_subgroup; @@ -222,8 +398,8 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) for (size_t j = 0U; j < ARRAY_SIZE(stream_params); j++) { stream_params[j].stream = &streams[j].stream; - stream_params[j].data = NULL; - stream_params[j].data_len = 0U; + stream_params[j].data = j == 0 ? left : right; + stream_params[j].data_len = j == 0 ? sizeof(left) : sizeof(right); bt_bap_stream_cb_register(stream_params[j].stream, &stream_ops); } @@ -258,13 +434,43 @@ int main(void) } printk("Bluetooth initialized\n"); - for (size_t i = 0U; i < ARRAY_SIZE(mock_data); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(send_pcm_data); i++) { /* Initialize mock data */ - mock_data[i] = i; + send_pcm_data[i] = i; } #if defined(CONFIG_LIBLC3) - init_lc3(); +#if defined(CONFIG_USB_DEVICE_AUDIO) + const struct device *hs_dev; + + hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0)); + + if (!device_is_ready(hs_dev)) { + printk("Device USB Headset is not ready\n"); + return 0; + } + + printk("Found USB Headset Device\n"); + + (void)memset(streams, 0, sizeof(streams)); + + for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { + ring_buf_init(&(streams[i].audio_ring_buf), + sizeof(streams[i]._ring_buffer_memory), + streams[i]._ring_buffer_memory); + printk("Initialized ring buf %zu: capacity: %u\n", i, + ring_buf_capacity_get(&(streams[i].audio_ring_buf))); + } + + usb_audio_register(hs_dev, &ops); + + err = usb_enable(NULL); + if (err) { + printk("Failed to enable USB"); + return 0; + } +#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ + k_thread_start(encoder); #endif /* defined(CONFIG_LIBLC3) */ while (true) { @@ -372,10 +578,13 @@ int main(void) } } +#if defined(CONFIG_LIBLC3) && defined(CONFIG_USB_DEVICE_AUDIO) + /* Never stop streaming when using USB Audio as input */ + k_sleep(K_FOREVER); +#endif /* defined(CONFIG_LIBLC3) && defined(CONFIG_USB_DEVICE_AUDIO) */ printk("Waiting %u seconds before stopped\n", BROADCAST_SOURCE_LIFETIME); k_sleep(K_SECONDS(BROADCAST_SOURCE_LIFETIME)); - printk("Stopping broadcast source\n"); stopping = true; err = bt_bap_broadcast_source_stop(broadcast_source); From f6d6742ca1d17c07309132d06d96c75405ccab07 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Thu, 2 Nov 2023 11:52:07 +0100 Subject: [PATCH 3541/4498] bluetooth: id: make sharing RPA between adv sets optional Added a Kconfig option that makes the RPA sharing feature optional. By default, the Zephyr Bluetooth stack now uses the RPA rotation policy that was active before the introduction of the RPA sharing functionality in the following PR: https://github.com/zephyrproject-rtos/zephyr/pull/55449 The new Kconfig option configures the advertising sets linked with the same Bluetooth identity to use the same Resolvable Private Address in a given rotation period. After the RPA timeout, the new RPA is generated and shared between the advertising sets in the subsequent rotation period. When this option is disabled, the generated RPAs of the advertising sets differ from each other in a given rotation period. Signed-off-by: Kamil Piszczek --- subsys/bluetooth/host/Kconfig | 12 ++++ subsys/bluetooth/host/hci_core.h | 2 + subsys/bluetooth/host/id.c | 61 ++++++++++++++----- .../id/bt_id_set_adv_private_addr/src/main.c | 2 +- .../host/privacy/peripheral/src/tester.c | 17 +++++- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index f09d8a14d72..c5c73be39a2 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -469,6 +469,18 @@ config BT_RPA_TIMEOUT_DYNAMIC This option allows the user to override the default value of the Resolvable Private Address timeout using dedicated APIs. +config BT_RPA_SHARING + bool "Share the Resolvable Private Address between advertising sets" + depends on BT_PRIVACY && BT_EXT_ADV + help + This option configures the advertising sets linked with the same + Bluetooth identity to use the same Resolvable Private Address in + a given rotation period. After the RPA timeout, the new RPA is + generated and shared between the advertising sets in the subsequent + rotation period. When this option is disabled, the generated RPAs + of the advertising sets differ from each other in a given rotation + period. + config BT_SIGNING bool "Data signing support" help diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 65466cae740..ce4fc5a9b63 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -381,8 +381,10 @@ struct bt_dev { /* Local Identity Resolving Key */ uint8_t irk[CONFIG_BT_ID_MAX][16]; +#if defined(CONFIG_BT_RPA_SHARING) /* Only 1 RPA per identity */ bt_addr_t rpa[CONFIG_BT_ID_MAX]; +#endif /* Work used for RPA rotation */ struct k_work_delayable rpa_update; diff --git a/subsys/bluetooth/host/id.c b/subsys/bluetooth/host/id.c index cf07418dd02..6b5fcbd5d17 100644 --- a/subsys/bluetooth/host/id.c +++ b/subsys/bluetooth/host/id.c @@ -207,13 +207,14 @@ static void adv_rpa_expired(struct bt_le_ext_adv *adv) if (atomic_test_bit(adv->flags, BT_ADV_RPA_VALID) && adv->cb && adv->cb->rpa_expired) { rpa_invalid = adv->cb->rpa_expired(adv); - if (rpa_invalid) { - bt_addr_copy(&bt_dev.rpa[adv->id], BT_ADDR_NONE); - } } #endif if (rpa_invalid) { atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID); + +#if defined(CONFIG_BT_RPA_SHARING) + bt_addr_copy(&bt_dev.rpa[adv->id], BT_ADDR_NONE); +#endif } } @@ -321,8 +322,39 @@ int bt_id_set_private_addr(uint8_t id) return 0; } +#if defined(CONFIG_BT_RPA_SHARING) +static int adv_rpa_get(struct bt_le_ext_adv *adv, bt_addr_t *rpa) +{ + int err; + + if (bt_addr_eq(&bt_dev.rpa[adv->id], BT_ADDR_NONE)) { + err = bt_rpa_create(bt_dev.irk[adv->id], &bt_dev.rpa[adv->id]); + if (err) { + return err; + } + } + + bt_addr_copy(rpa, &bt_dev.rpa[adv->id]); + + return 0; +} +#else +static int adv_rpa_get(struct bt_le_ext_adv *adv, bt_addr_t *rpa) +{ + int err; + + err = bt_rpa_create(bt_dev.irk[adv->id], rpa); + if (err) { + return err; + } + + return 0; +} +#endif /* defined(CONFIG_BT_RPA_SHARING) */ + int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv) { + bt_addr_t rpa; int err; CHECKIF(adv == NULL) { @@ -373,16 +405,12 @@ int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv) return 0; } - if (bt_addr_eq(&bt_dev.rpa[adv->id], BT_ADDR_NONE)) { - err = bt_rpa_create(bt_dev.irk[adv->id], &bt_dev.rpa[adv->id]); - if (err) { - return err; - } - } - - err = bt_id_set_adv_random_addr(adv, &bt_dev.rpa[adv->id]); + err = adv_rpa_get(adv, &rpa); if (!err) { - atomic_set_bit(adv->flags, BT_ADV_RPA_VALID); + err = bt_id_set_adv_random_addr(adv, &rpa); + if (!err) { + atomic_set_bit(adv->flags, BT_ADV_RPA_VALID); + } } if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED)) { @@ -394,7 +422,7 @@ int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv) } if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) { - LOG_INF("RPA: %s", bt_addr_str(&bt_dev.rpa[adv->id])); + LOG_INF("RPA: %s", bt_addr_str(&rpa)); } return 0; @@ -1230,7 +1258,10 @@ static int id_create(uint8_t id, bt_addr_le_t *addr, uint8_t *irk) memcpy(irk, &bt_dev.irk[id], 16); } } + +#if defined(CONFIG_BT_RPA_SHARING) bt_addr_copy(&bt_dev.rpa[id], BT_ADDR_NONE); +#endif } #endif /* Only store if stack was already initialized. Before initialization @@ -2064,10 +2095,12 @@ int bt_id_init(void) int err; #if defined(CONFIG_BT_PRIVACY) + k_work_init_delayable(&bt_dev.rpa_update, rpa_timeout); +#if defined(CONFIG_BT_RPA_SHARING) for (uint8_t id = 0U; id < ARRAY_SIZE(bt_dev.rpa); id++) { bt_addr_copy(&bt_dev.rpa[id], BT_ADDR_NONE); } - k_work_init_delayable(&bt_dev.rpa_update, rpa_timeout); +#endif #endif if (!IS_ENABLED(CONFIG_BT_SETTINGS) && !bt_dev.id_count) { diff --git a/tests/bluetooth/host/id/bt_id_set_adv_private_addr/src/main.c b/tests/bluetooth/host/id/bt_id_set_adv_private_addr/src/main.c index b8c4974c03f..73f51ad4bf2 100644 --- a/tests/bluetooth/host/id/bt_id_set_adv_private_addr/src/main.c +++ b/tests/bluetooth/host/id/bt_id_set_adv_private_addr/src/main.c @@ -24,7 +24,7 @@ static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixt { memset(&bt_dev, 0x00, sizeof(struct bt_dev)); bt_addr_le_copy(&bt_dev.random_addr, &bt_addr_le_none); -#if defined(CONFIG_BT_PRIVACY) +#if defined(CONFIG_BT_RPA_SHARING) bt_addr_copy(&bt_dev.rpa[BT_ID_DEFAULT], BT_ADDR_NONE); #endif diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c index deaa001ddbe..db363cd6ea0 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c +++ b/tests/bsim/bluetooth/host/privacy/peripheral/src/tester.c @@ -41,9 +41,20 @@ static void validate_rpa_addr_generated_for_adv_sets(void) return; } } - /* First two adv sets have same address as they use same ID and third adv set use diff ID */ - if (!bt_addr_le_eq(&adv_set_data[0].old_addr, &adv_set_data[1].old_addr)) { - FAIL("RPA not same for adv sets with same id\n"); + if (bt_addr_le_eq(&adv_set_data[0].old_addr, &adv_set_data[1].old_addr)) { + /* With RPA sharing mode disabled, the first two adv sets should have + * a different address even though they use the same Bluetooth ID. + */ + if (!IS_ENABLED(CONFIG_BT_RPA_SHARING)) { + FAIL("RPA same for adv sets with same id and RPA sharing disabled\n"); + } + } else { + /* In the RPA sharing mode, the first two adv sets should have + * the same address as they use the same Bluetooth ID. + */ + if (IS_ENABLED(CONFIG_BT_RPA_SHARING)) { + FAIL("RPA not same for adv sets with same id and RPA sharing enabled\n"); + } } if (bt_addr_le_eq(&adv_set_data[0].old_addr, &adv_set_data[3].old_addr)) { FAIL("RPA same for adv sets with different id's\n"); From ae05c5ea30ef4a2447c038e99e8ce230ef57efff Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Mon, 13 Nov 2023 09:33:09 +0100 Subject: [PATCH 3542/4498] tests: bsim: bluetooth: host: privacy: peripheral: test rpa sharing mode Added a new configuration to the BabbleSim Bluetooth Peripheral Privacy test to cover the code path for the RPA sharing mode. Signed-off-by: Kamil Piszczek --- tests/bsim/bluetooth/host/compile.sh | 1 + .../privacy/peripheral/prj_rpa_sharing.conf | 26 +++++++++++ .../privacy/peripheral/test_scripts/_env.sh | 3 ++ .../test_scripts/run_test_rpa_sharing.sh | 46 +++++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 tests/bsim/bluetooth/host/privacy/peripheral/prj_rpa_sharing.conf create mode 100755 tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_rpa_sharing.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 9840083305c..ff42fd27adf 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -71,6 +71,7 @@ app=tests/bsim/bluetooth/host/misc/disconnect/tester compile app=tests/bsim/bluetooth/host/privacy/central compile app=tests/bsim/bluetooth/host/privacy/peripheral compile +app=tests/bsim/bluetooth/host/privacy/peripheral conf_file=prj_rpa_sharing.conf compile app=tests/bsim/bluetooth/host/privacy/device compile app=tests/bsim/bluetooth/host/privacy/legacy compile diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj_rpa_sharing.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj_rpa_sharing.conf new file mode 100644 index 00000000000..bebce9933ca --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj_rpa_sharing.conf @@ -0,0 +1,26 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_SMP=y +CONFIG_ASSERT=y + +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PRIVACY=y +CONFIG_BT_RPA_TIMEOUT=10 +CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=3 +CONFIG_BT_ID_MAX=3 + +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y + +# Increased stack due to settings API usage +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# Enable the RPA sharing mode +CONFIG_BT_RPA_SHARING=y diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh index 13cf18ceec4..3c86078a7a6 100755 --- a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/_env.sh @@ -9,3 +9,6 @@ bsim_bin="${BSIM_OUT_PATH}/bin" BOARD="${BOARD:-nrf52_bsim}" central_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_peripheral_prj_conf" peripheral_exe="${central_exe}" +central_exe_rpa_sharing="\ +${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_privacy_peripheral_prj_rpa_sharing_conf" +peripheral_exe_rpa_sharing="${central_exe_rpa_sharing}" diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_rpa_sharing.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_rpa_sharing.sh new file mode 100755 index 00000000000..2b0d5e4c4b7 --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_rpa_sharing.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +source "${bash_source_dir}/_env.sh" +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +verbosity_level=2 +simulation_id="$(basename "$(realpath "$bash_source_dir/..")")" +simulation_id="${simulation_id}_rpa_sharing" +EXECUTE_TIMEOUT=30 + +cd ${BSIM_OUT_PATH}/bin + +Execute "$central_exe_rpa_sharing" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" + + +Execute "$peripheral_exe_rpa_sharing" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" + + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs + +Execute "$central_exe_rpa_sharing" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_rm + + +Execute "$peripheral_exe_rpa_sharing" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_rm + + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs From 4cc12cb112c40a86769223b44ab7b92a9c877dc7 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 8 Nov 2023 16:14:51 -0600 Subject: [PATCH 3543/4498] include: mipi_dsi: add MIPI DSI detach API Add MIPI DSI detach API. This API allows the DSI controller to detach from the DSI device, and power down the DSI PHY. The primary goal of this API is to provide power savings for DSI devices when the display they are driving is not active. Signed-off-by: Daniel DeGrasse --- include/zephyr/drivers/mipi_dsi.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/zephyr/drivers/mipi_dsi.h b/include/zephyr/drivers/mipi_dsi.h index d26854fc1a6..e6ac1e0a787 100644 --- a/include/zephyr/drivers/mipi_dsi.h +++ b/include/zephyr/drivers/mipi_dsi.h @@ -18,6 +18,7 @@ * @ingroup io_interfaces * @{ */ +#include #include #include #include @@ -247,6 +248,8 @@ __subsystem struct mipi_dsi_driver_api { const struct mipi_dsi_device *mdev); ssize_t (*transfer)(const struct device *dev, uint8_t channel, struct mipi_dsi_msg *msg); + int (*detach)(const struct device *dev, uint8_t channel, + const struct mipi_dsi_device *mdev); }; /** @@ -342,6 +345,29 @@ ssize_t mipi_dsi_dcs_read(const struct device *dev, uint8_t channel, ssize_t mipi_dsi_dcs_write(const struct device *dev, uint8_t channel, uint8_t cmd, const void *buf, size_t len); + +/** + * @brief Detach a device from the MIPI-DSI bus + * + * @param dev MIPI-DSI host device. + * @param channel Device channel (VID). + * @param mdev MIPI-DSI device description. + * + * @return 0 on success, negative on error + */ +static inline int mipi_dsi_detach(const struct device *dev, + uint8_t channel, + const struct mipi_dsi_device *mdev) +{ + const struct mipi_dsi_driver_api *api = (const struct mipi_dsi_driver_api *)dev->api; + + if (api->detach == NULL) { + return -ENOSYS; + } + + return api->detach(dev, channel, mdev); +} + #ifdef __cplusplus } #endif From 5854821b65ea8ba893e7e255a0d1e32684f3ef4f Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 8 Nov 2023 16:17:14 -0600 Subject: [PATCH 3544/4498] drivers: mipi_dsi: add support for mipi_dsi_detach to dsi_mcux_2l Add support for mipi_dsi_detach API to dsi_mcux_2l driver, and update RT5xx SOC interface to enable halting clocks for the MIPI DPHY. Signed-off-by: Daniel DeGrasse --- drivers/mipi_dsi/dsi_mcux_2l.c | 23 +++++++++++++++++++++-- soc/arm/nxp_imx/rt5xx/soc.c | 11 +++++++++++ soc/arm/nxp_imx/rt5xx/soc.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index de73d10e8ac..62ab1400a22 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -227,6 +227,8 @@ static int dsi_mcux_attach(const struct device *dev, dsi_config.autoInsertEoTp = config->auto_insert_eotp; dsi_config.enableNonContinuousHsClk = config->noncontinuous_hs_clk; + imxrt_pre_init_display_interface(); + /* Init the DSI module. */ DSI_Init(config->base, &dsi_config); @@ -344,6 +346,24 @@ static int dsi_mcux_attach(const struct device *dev, return 0; } +static int dsi_mcux_detach(const struct device *dev, uint8_t channel, + const struct mipi_dsi_device *mdev) +{ + const struct mcux_mipi_dsi_config *config = dev->config; + + /* Enable DPHY auto power down */ + DSI_DeinitDphy(config->base); + /* Fully power off DPHY */ + config->base->PD_DPHY = 0x1; + /* Deinit MIPI */ + DSI_Deinit(config->base); + /* Call IMX RT clock function to gate clocks and power at SOC level */ + imxrt_deinit_display_interface(); + return 0; +} + + + static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, struct mipi_dsi_msg *msg) { @@ -434,6 +454,7 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, static struct mipi_dsi_driver_api dsi_mcux_api = { .attach = dsi_mcux_attach, + .detach = dsi_mcux_detach, .transfer = dsi_mcux_transfer, }; @@ -449,8 +470,6 @@ static int mcux_mipi_dsi_init(const struct device *dev) k_sem_init(&data->transfer_sem, 0, 1); - imxrt_pre_init_display_interface(); - if (!device_is_ready(config->bit_clk_dev) || !device_is_ready(config->esc_clk_dev) || !device_is_ready(config->pixel_clk_dev)) { diff --git a/soc/arm/nxp_imx/rt5xx/soc.c b/soc/arm/nxp_imx/rt5xx/soc.c index f6af227b17c..d834d3e55bc 100644 --- a/soc/arm/nxp_imx/rt5xx/soc.c +++ b/soc/arm/nxp_imx/rt5xx/soc.c @@ -473,6 +473,17 @@ void __weak imxrt_post_init_display_interface(void) /* Deassert MIPI DPHY reset. */ RESET_ClearPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn); } + +void __weak imxrt_deinit_display_interface(void) +{ + /* Assert MIPI DPHY and DSI reset */ + RESET_SetPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn); + RESET_SetPeripheralReset(kMIPI_DSI_CTRL_RST_SHIFT_RSTn); + /* Remove clock from DPHY */ + CLOCK_AttachClk(kNONE_to_MIPI_DPHY_CLK); +} + + #endif /** diff --git a/soc/arm/nxp_imx/rt5xx/soc.h b/soc/arm/nxp_imx/rt5xx/soc.h index c2ebff0369d..eefef70ff82 100644 --- a/soc/arm/nxp_imx/rt5xx/soc.h +++ b/soc/arm/nxp_imx/rt5xx/soc.h @@ -80,6 +80,8 @@ void imxrt_pre_init_display_interface(void); void imxrt_post_init_display_interface(void); + +void imxrt_deinit_display_interface(void); #endif #endif From 5997f3d00d31f312bb50aa68b6e57d20b637a748 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 8 Nov 2023 16:18:46 -0600 Subject: [PATCH 3545/4498] drivers: display: rm67162: add device level power management Add device level power management to rm67162 display. Device level power management for this controller calls the MIPI DSI detach API, in order to power down the MIPI DPHY when the display is not active. Signed-off-by: Daniel DeGrasse --- drivers/display/display_rm67162.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/display/display_rm67162.c b/drivers/display/display_rm67162.c index edf9d6eb55d..5516e57789d 100644 --- a/drivers/display/display_rm67162.c +++ b/drivers/display/display_rm67162.c @@ -13,6 +13,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(rm67162, CONFIG_DISPLAY_LOG_LEVEL); @@ -568,6 +569,31 @@ static int rm67162_set_orientation(const struct device *dev, return -ENOTSUP; } +#ifdef CONFIG_PM_DEVICE + +static int rm67162_pm_action(const struct device *dev, + enum pm_device_action action) +{ + const struct rm67162_config *config = dev->config; + struct rm67162_data *data = dev->data; + struct mipi_dsi_device mdev = {0}; + + mdev.data_lanes = config->num_of_lanes; + mdev.pixfmt = data->pixel_format; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + /* Detach from the MIPI DSI controller */ + return mipi_dsi_detach(config->mipi_dsi, config->channel, &mdev); + case PM_DEVICE_ACTION_RESUME: + return mipi_dsi_attach(config->mipi_dsi, config->channel, &mdev); + default: + return -ENOTSUP; + } +} + +#endif /* CONFIG_PM_DEVICE */ + static const struct display_driver_api rm67162_api = { .blanking_on = rm67162_blanking_on, .blanking_off = rm67162_blanking_off, @@ -593,9 +619,10 @@ static const struct display_driver_api rm67162_api = { static struct rm67162_data rm67162_data_##id = { \ .pixel_format = DT_INST_PROP(id, pixel_format), \ }; \ + PM_DEVICE_DT_INST_DEFINE(id, rm67162_pm_action); \ DEVICE_DT_INST_DEFINE(id, \ &rm67162_init, \ - NULL, \ + PM_DEVICE_DT_INST_GET(id), \ &rm67162_data_##id, \ &rm67162_config_##id, \ POST_KERNEL, \ From d6d3f9f16a400ab01c0617a30114f9af1ec7bb10 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Wed, 8 Nov 2023 16:24:04 -0600 Subject: [PATCH 3546/4498] boards: shields: add support for low power on G1120B0MIPI using RT595 Add support for low power mode on the G1120B0MIPI using the RT595. This configuration is tested via a testcase in samples/drivers/display, which should validate that the display can be driven by the RT595 when CONFIG_PM and CONFIG_PM_DEVICE are set. Signed-off-by: Daniel DeGrasse --- .../g1120b0mipi/boards/mimxrt595_evk_cm33.overlay | 15 +++++++++++++++ samples/drivers/display/sample.yaml | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.overlay diff --git a/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.overlay b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.overlay new file mode 100644 index 00000000000..7503627d99d --- /dev/null +++ b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_cm33.overlay @@ -0,0 +1,15 @@ +/* + * Copyright 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Change deep sleep config for suspend mode to keep SMARTDMA ram powered, + * so the SMARTDMA will continue functioning after deep sleep + */ +&suspend { + deep-sleep-config = <0xC800>, + <0x80030004>, + <0xFFFFFFFF>, + <0>; +}; diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index f2cc9d0a89d..00725caedb5 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -131,3 +131,14 @@ tests: harness: console harness_config: fixture: fixture_display + sample.display.g1120b0mipi: + platform_allow: mimxrt595_evk_cm33 + tags: display + harness: console + extra_args: SHIELD=g1120b0mipi + extra_configs: + - CONFIG_PM=y + - CONFIG_PM_DEVICE=y + - CONFIG_IDLE_STACK_SIZE=400 + harness_config: + fixture: fixture_display From 07b5f51cdcba07b8b135f3714a1e05161710efab Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 9 Nov 2023 15:17:55 +0200 Subject: [PATCH 3547/4498] boards: up_squared_pro_7000: Add new board definition Add board definition for UP Squared Pro 7000. The board is powered by Intel Alder Lake N (N-series Intel Platform). Signed-off-by: Andrei Emeltchenko --- boards/x86/intel_adl/Kconfig.board | 6 ++++++ boards/x86/intel_adl/Kconfig.defconfig | 5 +++-- boards/x86/intel_adl/up_squared_pro_7000.dts | 21 +++++++++++++++++++ boards/x86/intel_adl/up_squared_pro_7000.yaml | 17 +++++++++++++++ .../intel_adl/up_squared_pro_7000_defconfig | 15 +++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 boards/x86/intel_adl/up_squared_pro_7000.dts create mode 100644 boards/x86/intel_adl/up_squared_pro_7000.yaml create mode 100644 boards/x86/intel_adl/up_squared_pro_7000_defconfig diff --git a/boards/x86/intel_adl/Kconfig.board b/boards/x86/intel_adl/Kconfig.board index 997b5a30504..591da3261f2 100644 --- a/boards/x86/intel_adl/Kconfig.board +++ b/boards/x86/intel_adl/Kconfig.board @@ -12,3 +12,9 @@ config BOARD_INTEL_ADL_RVP depends on SOC_ALDER_LAKE select X86_64 select HAS_COVERAGE_SUPPORT + +config BOARD_UP_SQUARED_PRO_7000 + bool "UP SQUARED PRO 7000 board" + depends on SOC_ALDER_LAKE + select X86_64 + select HAS_COVERAGE_SUPPORT diff --git a/boards/x86/intel_adl/Kconfig.defconfig b/boards/x86/intel_adl/Kconfig.defconfig index 247b8f7a0cb..cc9e3882ec4 100644 --- a/boards/x86/intel_adl/Kconfig.defconfig +++ b/boards/x86/intel_adl/Kconfig.defconfig @@ -1,11 +1,12 @@ # Copyright (c) 2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -if BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP +if BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP || BOARD_UP_SQUARED_PRO_7000 config BOARD default "intel_adl_crb" if BOARD_INTEL_ADL_CRB default "intel_adl_rvp" if BOARD_INTEL_ADL_RVP + default "up_squared_pro_7000" if BOARD_UP_SQUARED_PRO_7000 config BUILD_OUTPUT_STRIPPED default y @@ -45,4 +46,4 @@ config SHELL_STACK_SIZE endif # SHELL endif # ACPI -endif # BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP +endif # BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP || BOARD_UP_SQUARED_PRO_7000 diff --git a/boards/x86/intel_adl/up_squared_pro_7000.dts b/boards/x86/intel_adl/up_squared_pro_7000.dts new file mode 100644 index 00000000000..06d6f8e2330 --- /dev/null +++ b/boards/x86/intel_adl/up_squared_pro_7000.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "intel_adl.dts" + +/ { + model = "UP Squared Pro 7000 board"; + compatible = "aaeon,up_squared_pro_7000"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + }; +}; + +&uart1 { + status = "okay"; +}; diff --git a/boards/x86/intel_adl/up_squared_pro_7000.yaml b/boards/x86/intel_adl/up_squared_pro_7000.yaml new file mode 100644 index 00000000000..e1673112309 --- /dev/null +++ b/boards/x86/intel_adl/up_squared_pro_7000.yaml @@ -0,0 +1,17 @@ +identifier: up_squared_pro_7000 +name: UP SQUARED PRO 7000 board +type: mcu +arch: x86 +toolchain: + - zephyr +ram: 2048 +supported: + - acpi + - smp + - watchdog +testing: + timeout_multiplier: 4 + ignore_tags: + - net + - bluetooth +vendor: UP diff --git a/boards/x86/intel_adl/up_squared_pro_7000_defconfig b/boards/x86/intel_adl/up_squared_pro_7000_defconfig new file mode 100644 index 00000000000..211ce9f24e1 --- /dev/null +++ b/boards/x86/intel_adl/up_squared_pro_7000_defconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_ALDER_LAKE=y +CONFIG_BOARD_UP_SQUARED_PRO_7000=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_X2APIC=y +CONFIG_SMP=y +CONFIG_BUILD_OUTPUT_EFI=y +CONFIG_BUILD_NO_GAP_FILL=y +CONFIG_UART_NS16550_PARENT_INIT_LEVEL=y From c99fe31f8333a9e2003e6bbd607a98ed9d482e79 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 9 Nov 2023 16:00:19 +0200 Subject: [PATCH 3548/4498] boards: up_squared_pro_7000: Add board documentation Add documentation for UP Squared Pro 7000 board. Signed-off-by: Andrei Emeltchenko --- .../x86/intel_adl/doc/up_squared_pro_7000.rst | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 boards/x86/intel_adl/doc/up_squared_pro_7000.rst diff --git a/boards/x86/intel_adl/doc/up_squared_pro_7000.rst b/boards/x86/intel_adl/doc/up_squared_pro_7000.rst new file mode 100644 index 00000000000..8f322080d96 --- /dev/null +++ b/boards/x86/intel_adl/doc/up_squared_pro_7000.rst @@ -0,0 +1,67 @@ +:orphan: + +.. _up_squared_pro_7000_board: + +UP SQUARED PRO 7000 board +######################### + +Overview +******** + +UP Squared Pro 7000 is the 3rd generation of palm-sized developer board of +UP Boards series. UP Squared Pro 7000 is powered by Intel Alder Lake N +(Intel N-series Platform). + +For more information about Intel N-series Platform please refer to +:ref:`intel_adl_n`. + +This board configuration enables kernel support for the UP Squared Pro 7000 boards. + +Hardware +******** + +General information about the board can be found at the `UP_SQUARED_PRO_7000`_ website. + +Connections and IOs +=================== + +Refer to the `UP_SQUARED_PRO_7000`_ website for more information. + +Programming and Debugging +************************* +Use the following procedures for booting an image for an UP SQUARED PRO 7000 board. + +.. contents:: + :depth: 1 + :local: + :backlinks: top + +Build Zephyr application +======================== + +#. Build a Zephyr application; for instance, to build the ``hello_world`` + application for UP SQUARED PRO 7000 board: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: up_squared_pro_7000 + :goals: build + + .. note:: + + A Zephyr EFI image file named :file:`zephyr.efi` is automatically + created in the build directory after the application is built. + +Booting the UP Squared Pro 7000 Board using UEFI +================================================ + +.. include:: ../../common/efi_boot.rst + :start-after: start_include_here + +Booting the UP Squared Pro 7000 Board over network +================================================== + +.. include:: ../../common/net_boot.rst + :start-after: start_include_here + +.. _UP_SQUARED_PRO_7000: https://up-board.org/up-squared-pro-7000/ From 0dab1e848233be8593d922070e1fd58ae8769df0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 9 Nov 2023 17:31:04 +0200 Subject: [PATCH 3549/4498] doc: x86: Modify x86 TOC include Modify toctree glob to exclude common directory which keeps rst helpers. This allows to include several boards documentation from the common board directory. Signed-off-by: Andrei Emeltchenko --- boards/x86/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/x86/index.rst b/boards/x86/index.rst index d51c2551c4f..f7321566591 100644 --- a/boards/x86/index.rst +++ b/boards/x86/index.rst @@ -7,4 +7,4 @@ x86 Boards :maxdepth: 1 :glob: - **/index + [!common]*/**/* From 25ac2fa064187835946e8ba39a739bf5e82f3ec0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 10 Nov 2023 12:13:47 +0200 Subject: [PATCH 3550/4498] dts: vendor-prefixes: Add AAEON Add AAEON Technology Inc prefix. Signed-off-by: Andrei Emeltchenko --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 5515ea53ebe..29a7b78aa70 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -10,6 +10,7 @@ # # +aaeon AAEON Technology Inc. abb ABB abilis Abilis Systems abracon Abracon Corporation From 81923652981b3362031e85d848a57c0d532f806e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 10 Nov 2023 12:39:29 +0200 Subject: [PATCH 3551/4498] boards: up_squared: Correct vendor Correct vendor name for up_squared board, the same as for UP 7000 board. Signed-off-by: Andrei Emeltchenko --- boards/x86/up_squared/up_squared.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/x86/up_squared/up_squared.dts b/boards/x86/up_squared/up_squared.dts index 22303e0ef16..e4977160db6 100644 --- a/boards/x86/up_squared/up_squared.dts +++ b/boards/x86/up_squared/up_squared.dts @@ -14,7 +14,7 @@ / { model = "up_squared"; - compatible = "up_board,up_squared"; + compatible = "aaeon,up_squared"; aliases { i2c-0 = &i2c0; From a3ff8d5b90bd3bb0a6c7f3786f0852ed855b9344 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Sat, 11 Nov 2023 15:21:27 +0200 Subject: [PATCH 3552/4498] tests: samples: Add up_squared_pro_7000 overlay Add up_squared_pro_7000 overlay for watchdog test and sample. Signed-off-by: Andrei Emeltchenko --- .../drivers/watchdog/boards/up_squared_pro_7000.overlay | 9 +++++++++ .../wdt_basic_api/boards/up_squared_pro_7000.overlay | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 samples/drivers/watchdog/boards/up_squared_pro_7000.overlay create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/up_squared_pro_7000.overlay diff --git a/samples/drivers/watchdog/boards/up_squared_pro_7000.overlay b/samples/drivers/watchdog/boards/up_squared_pro_7000.overlay new file mode 100644 index 00000000000..660b55c0512 --- /dev/null +++ b/samples/drivers/watchdog/boards/up_squared_pro_7000.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tco_wdt { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/up_squared_pro_7000.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/up_squared_pro_7000.overlay new file mode 100644 index 00000000000..660b55c0512 --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/up_squared_pro_7000.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tco_wdt { + status = "okay"; +}; From 8ebbd0227d76c430bc897ecf89ec687e6098b1df Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Fri, 10 Nov 2023 16:15:47 +0100 Subject: [PATCH 3553/4498] sensors: tests: adi: increase coverage This commit adds tests for various configurations of adltc2990 Signed-off-by: Jilay Pandya --- .../adltc2990/boards/native_posix.overlay | 40 +++++- tests/drivers/sensor/adltc2990/src/main.c | 130 ++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/tests/drivers/sensor/adltc2990/boards/native_posix.overlay b/tests/drivers/sensor/adltc2990/boards/native_posix.overlay index 9497214ad44..a3f7ae3ed7b 100644 --- a/tests/drivers/sensor/adltc2990/boards/native_posix.overlay +++ b/tests/drivers/sensor/adltc2990/boards/native_posix.overlay @@ -4,9 +4,21 @@ */ &i2c0 { - adltc2990_1_3: adltc2990_1_3@c { + adltc2990_0_0: adltc2990_0_0@1 { compatible = "adi,adltc2990"; - reg = <0xc>; + reg = <0x1>; + measurement-mode = <0 0>; + pins-v1-v2-current-resistor = <0>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <500 1000>; + pin-v2-voltage-divider-resistors = <110000 100000>; + pin-v3-voltage-divider-resistors = <7000 1000>; + pin-v4-voltage-divider-resistors = <500 1000>; + }; + + adltc2990_1_3: adltc2990_1_3@b { + compatible = "adi,adltc2990"; + reg = <0xb>; temperature-format = <0>; acquistion-format = <1>; measurement-mode = <1 3>; @@ -18,6 +30,18 @@ pin-v4-voltage-divider-resistors = <0 1>; }; + adltc2990_4_3: adltc2990_4_3@c { + compatible = "adi,adltc2990"; + reg = <0xc>; + measurement-mode = <4 3>; + pins-v1-v2-current-resistor = <1000000>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <0 1>; + pin-v2-voltage-divider-resistors = <0 1>; + pin-v3-voltage-divider-resistors = <0 1>; + pin-v4-voltage-divider-resistors = <0 1>; + }; + adltc2990_5_3: adltc2990_5_3@d { compatible = "adi,adltc2990"; reg = <0xd>; @@ -59,4 +83,16 @@ pin-v3-voltage-divider-resistors = <7000 1000>; pin-v4-voltage-divider-resistors = <500 1000>; }; + + adltc2990_incorrect: adltc2990_incorrect@0 { + compatible = "adi,adltc2990"; + reg = <0x0>; + measurement-mode = <8 4>; + pins-v1-v2-current-resistor = <0>; + pins-v3-v4-current-resistor = <0>; + pin-v1-voltage-divider-resistors = <500 1000>; + pin-v2-voltage-divider-resistors = <110000 100000>; + pin-v3-voltage-divider-resistors = <7000 1000>; + pin-v4-voltage-divider-resistors = <500 1000>; + }; }; diff --git a/tests/drivers/sensor/adltc2990/src/main.c b/tests/drivers/sensor/adltc2990/src/main.c index 2f55ed38489..fabeb8ab0dc 100644 --- a/tests/drivers/sensor/adltc2990/src/main.c +++ b/tests/drivers/sensor/adltc2990/src/main.c @@ -49,6 +49,84 @@ "expected %f, got %f", expected_temperature, \ sensor_val[index].val1 + (float)sensor_val[index].val2 / 1000000); +/*** TEST-SUITE: ADLTC2990 Measurement Mode 0 0***/ + +struct adltc2990_0_0_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_0_0_setup(void) +{ + static struct adltc2990_0_0_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_0_0)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_0_0)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_0_0_before(void *f) +{ + struct adltc2990_0_0_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_0_0, NULL, adltc2990_0_0_setup, adltc2990_0_0_before, NULL, NULL); + +ZTEST_F(adltc2990_0_0, test_measure_mode_internal_temperature_only) +{ + struct sensor_value value[1]; + + zassert_equal(-ENOTSUP, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_MAGN_X)); + zassert_equal(-ENOTSUP, sensor_channel_get(fixture->dev, SENSOR_CHAN_MAGN_Z, value)); + zassert_equal(-EINVAL, sensor_channel_get(fixture->dev, SENSOR_CHAN_CURRENT, value)); + zassert_equal(-EINVAL, sensor_channel_get(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP, value)); +} + +/*** TEST-SUITE: ADLTC2990 Measurement Mode 4 3***/ + +struct adltc2990_4_3_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_4_3_setup(void) +{ + static struct adltc2990_4_3_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_4_3)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_4_3)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_4_3_before(void *f) +{ + struct adltc2990_4_3_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_4_3, NULL, adltc2990_4_3_setup, adltc2990_4_3_before, NULL, NULL); + +ZTEST_F(adltc2990_4_3, test_available_channels) +{ + struct sensor_value value[3]; + + zassert_equal(0, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE)); + zassert_equal(0, sensor_channel_get(fixture->dev, SENSOR_CHAN_VOLTAGE, value)); + zassert_equal(0, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP)); + zassert_equal(0, sensor_channel_get(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP, value)); + zassert_equal(0, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT)); + zassert_equal(0, sensor_channel_get(fixture->dev, SENSOR_CHAN_CURRENT, value)); +} + /*** TEST-SUITE: ADLTC2990 Measurement Mode 1 3***/ struct adltc2990_1_3_fixture { @@ -98,6 +176,7 @@ ZTEST_F(adltc2990_1_3, test_die_temperature) CHECK_TEMPERATURE(temp_value, 0, -40.00, SENSOR_CHAN_DIE_TEMP); } + ZTEST_F(adltc2990_1_3, test_ambient_temperature) { /* 0b00000001 0b10010001 +25.0625 */ @@ -300,6 +379,17 @@ ZTEST_F(adltc2990_7_3, test_available_channels) zassert_equal(-EINVAL, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT)); } +ZTEST_F(adltc2990_7_3, test_is_device_busy) +{ + uint8_t is_busy = BIT(0); + + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_STATUS, &is_busy); + zassert_equal(-EBUSY, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_ALL)); + is_busy = 0; + adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_STATUS, &is_busy); + zassert_equal(0, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_ALL)); +} + ZTEST_F(adltc2990_7_3, test_die_temperature) { /* The following values are taken from datasheet and should translate to 398.1250K */ @@ -309,6 +399,11 @@ ZTEST_F(adltc2990_7_3, test_die_temperature) adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_MSB, &msb); adltc2990_emul_set_reg(fixture->target, ADLTC2990_REG_INTERNAL_TEMP_LSB, &lsb); + struct sensor_value *die_temp_value_null = (struct sensor_value *)NULL; + + zassert_equal(-EINVAL, + sensor_channel_get(fixture->dev, SENSOR_CHAN_ALL, die_temp_value_null)); + struct sensor_value die_temp_value[1]; CHECK_TEMPERATURE(die_temp_value, 0, 398.1250, SENSOR_CHAN_DIE_TEMP); @@ -372,3 +467,38 @@ ZTEST_F(adltc2990_7_3, test_V1_V2_V3_V4_VCC) zassert_equal(6, voltage_values[4].val1); } + +/*** TEST-SUITE: ADLTC2990 Measurement Mode Incorrect***/ +struct adltc2990_incorrect_fixture { + const struct device *dev; + const struct emul *target; +}; + +static void *adltc2990_incorrect_setup(void) +{ + static struct adltc2990_incorrect_fixture fixture = { + .dev = DEVICE_DT_GET(DT_NODELABEL(adltc2990_incorrect)), + .target = EMUL_DT_GET(DT_NODELABEL(adltc2990_incorrect)), + }; + + zassert_not_null(fixture.dev); + zassert_not_null(fixture.target); + return &fixture; +} + +static void adltc2990_incorrect_before(void *f) +{ + struct adltc2990_incorrect_fixture *fixture = f; + + adltc2990_emul_reset(fixture->target); +} + +ZTEST_SUITE(adltc2990_incorrect, NULL, adltc2990_incorrect_setup, adltc2990_incorrect_before, NULL, + NULL); + +ZTEST_F(adltc2990_incorrect, test_current_cannot_be_measured) +{ + struct sensor_value current[1]; + + zassert_equal(-EINVAL, sensor_channel_get(fixture->dev, SENSOR_CHAN_CURRENT, current)); +} From aa25fe06a5b73efb78dda530a57efadbccd6696b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 11 Nov 2023 19:47:24 +0000 Subject: [PATCH 3554/4498] ci: compliance: undef list few configs used in optional modules The Kconfig check fails when running the script locally for undefined symbols if the checkout does not include optional modules (the default behavior). Add these symbol to the Kconfig undef list. Signed-off-by: Fabio Baltieri --- scripts/ci/check_compliance.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index cbbd0da9b66..8779fddda66 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -643,6 +643,8 @@ def check_no_undef_outside_kconfig(self, kconf): "BTTESTER_LOG_LEVEL", # Used in tests/bluetooth/tester "BTTESTER_LOG_LEVEL_DBG", # Used in tests/bluetooth/tester "CDC_ACM_PORT_NAME_", + "CHRE", # Optional module + "CHRE_LOG_LEVEL_DBG", # Optional module "CLOCK_STM32_SYSCLK_SRC_", "CMU", "COMPILER_RT_RTLIB", @@ -689,6 +691,7 @@ def check_no_undef_outside_kconfig(self, kconf): "PEDO_THS_MIN", "REG1", "REG2", + "RIMAGE_SIGNING_SCHEMA", # Optional module "SAMPLE_MODULE_LOG_LEVEL", # Used as an example in samples/subsys/logging "SAMPLE_MODULE_LOG_LEVEL_DBG", # Used in tests/subsys/logging/log_api "LOG_BACKEND_MOCK_OUTPUT_DEFAULT", #Referenced in tests/subsys/logging/log_syst From 09521832be405b5732494ad8be9417923d7d6150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sun, 12 Nov 2023 14:35:54 +0700 Subject: [PATCH 3555/4498] drivers: pinctrl: kinetis: use clock control API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the direct use of the HAL API to configure clocks and use Zephyr's clock control API instead. Currently the PORT peripherals of the Kinetis family are either clocked by PCC in the case of KE1xF devices, or by SIM for the rest of the devices. PCC clock driver converts internally the subsys clock name into the clock gate address. SIM clock driver expects this conversion to be done by the caller. Signed-off-by: Manuel Argüelles --- drivers/pinctrl/pinctrl_kinetis.c | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl_kinetis.c b/drivers/pinctrl/pinctrl_kinetis.c index 5fdb07a8ced..45ac0ebe3cf 100644 --- a/drivers/pinctrl/pinctrl_kinetis.c +++ b/drivers/pinctrl/pinctrl_kinetis.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 NXP + * Copyright (c) 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,9 +7,13 @@ #define DT_DRV_COMPAT nxp_kinetis_pinmux +#include #include +#include #include +LOG_MODULE_REGISTER(pinctrl_kinetis, CONFIG_PINCTRL_LOG_LEVEL); + /* Port register addresses. */ static PORT_Type *ports[] = { (PORT_Type *)DT_REG_ADDR(DT_NODELABEL(porta)), @@ -28,7 +32,8 @@ static PORT_Type *ports[] = { #define PINCFG(mux) ((mux) & Z_PINCTRL_KINETIS_PCR_MASK) struct pinctrl_mcux_config { - clock_ip_name_t clock_ip_name; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; }; int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, @@ -51,24 +56,36 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, static int pinctrl_mcux_init(const struct device *dev) { const struct pinctrl_mcux_config *config = dev->config; + int err; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } - CLOCK_EnableClock(config->clock_ip_name); + err = clock_control_on(config->clock_dev, config->clock_subsys); + if (err) { + LOG_ERR("failed to enable clock (err %d)", err); + return -EINVAL; + } return 0; } -#if DT_NODE_HAS_STATUS(DT_INST(0, nxp_kinetis_ke1xf_sim), okay) -#define INST_DT_CLOCK_IP_NAME(n) \ - DT_REG_ADDR(DT_INST_PHANDLE(n, clocks)) + DT_INST_CLOCKS_CELL(n, name) -#else -#define INST_DT_CLOCK_IP_NAME(n) \ +#if DT_NODE_HAS_STATUS(DT_INST(0, nxp_kinetis_sim), okay) +#define PINCTRL_MCUX_DT_INST_CLOCK_SUBSYS(n) \ CLK_GATE_DEFINE(DT_INST_CLOCKS_CELL(n, offset), \ DT_INST_CLOCKS_CELL(n, bits)) +#else +#define PINCTRL_MCUX_DT_INST_CLOCK_SUBSYS(n) \ + DT_INST_CLOCKS_CELL(n, name) #endif #define PINCTRL_MCUX_INIT(n) \ static const struct pinctrl_mcux_config pinctrl_mcux_##n##_config = {\ - .clock_ip_name = INST_DT_CLOCK_IP_NAME(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t) \ + PINCTRL_MCUX_DT_INST_CLOCK_SUBSYS(n), \ }; \ \ DEVICE_DT_INST_DEFINE(n, \ From 9e29c70a1f0e70ed020265f4d965b8cd89649f00 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Mon, 13 Nov 2023 12:00:47 +0900 Subject: [PATCH 3556/4498] arch: riscv: fix hangup in boot if hart0 is not boot hart This patch changes the section of riscv_cpu_wake_flag variable to noinit from bss to fix hangup of RISC-V multicore boot if hart0 is not boot hart (CONFIG_RV_BOOT_HART != 0). Current boot sequence initializes a riscv_cpu_wake_flag to -1 but this variable is unintentionally changed to 0 by boot hart. This is because the variable is placed in bss section so this patch changes the section of the variable to noinit. Signed-off-by: Katsuhiro Suzuki --- arch/riscv/core/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index a5499d4e16b..6154450e58d 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -16,7 +16,7 @@ volatile struct { void *arg; } riscv_cpu_init[CONFIG_MP_MAX_NUM_CPUS]; -volatile uintptr_t riscv_cpu_wake_flag; +volatile uintptr_t __noinit riscv_cpu_wake_flag; volatile uintptr_t riscv_cpu_boot_flag; volatile void *riscv_cpu_sp; From d9a30c1f0a60f540d7362e377f9c0eea431b07c2 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 13 Nov 2023 15:30:26 -0600 Subject: [PATCH 3557/4498] docs: Remove out of date examples The examples in the RTIO docs were nice but continuously became out of date without being updated. This is unfortunately the downside of doc-only samples like this. Some real, buildable, samples right be better but will take a little time to write up. In the meantime drop the examples in the docs to avoid confusion. Signed-off-by: Tom Burdick --- doc/services/rtio/index.rst | 208 ------------------------------------ 1 file changed, 208 deletions(-) diff --git a/doc/services/rtio/index.rst b/doc/services/rtio/index.rst index b82972d7f68..88c5f29a075 100644 --- a/doc/services/rtio/index.rst +++ b/doc/services/rtio/index.rst @@ -212,214 +212,6 @@ There is a small cost to each RTIO context and iodev. This cost could be weighed against using a thread for each concurrent I/O operation or custom queues and threads per peripheral. RTIO is much lower cost than that. -Examples -******** - -Examples speak loudly about the intended uses and goals of an API. So several key -examples are presented below. Some are entirely plausible today without a -big leap. Others (the sensor example) would require additional work in other -APIs outside of RTIO as a sub system and are theoretical. - -Chained Blocking Requests -========================= - -A common scenario is needing to write the register address to then read from. -This can be accomplished by chaining a write into a read operation. - -The transaction on i2c is implicit for each operation chain. - -.. code-block:: C - - RTIO_I2C_IODEV(i2c_dev, I2C_DT_SPEC_INST(n)); - RTIO_DEFINE(ez_io, 4, 4); - static uint16_t reg_addr; - static uint8_t buf[32]; - - int do_some_io(void) - { - struct rtio_sqe *write_sqe = rtio_spsc_acquire(ez_io.sq); - struct rtio_sqe *read_sqe = rtio_spsc_acquire(ez_io.sq); - - rtio_sqe_prep_write(write_sqe, i2c_dev, RTIO_PRIO_LOW, ®_addr, 2); - write_sqe->flags = RTIO_SQE_CHAINED; /* the next item in the queue will wait on this one */ - - rtio_sqe_prep_read(read_sqe, i2c_dev, RTIO_PRIO_LOW, buf, 32); - - rtio_submit(rtio_inplace_executor, &ez_io, 2); - - struct rtio_cqe *read_cqe = rtio_spsc_consume(ez_io.cq); - struct rtio_cqe *write_cqe = rtio_spsc_consume(ez_io.cq); - - if(read_cqe->result < 0) { - LOG_ERR("read failed!"); - } - - if(write_cqe->result < 0) { - LOG_ERR("write failed!"); - } - - rtio_spsc_release(ez_io.cq); - rtio_spsc_release(ez_io.cq); - } - -Non blocking device to device -============================= - -Imagine wishing to read from one device on an I2C bus and then write the same -buffer to a device on a SPI bus without blocking the thread or setting up -callbacks or other IPC notification mechanisms. - -Perhaps an I2C temperature sensor and a SPI lowrawan module. The following is a -simplified version of that potential operation chain. - -.. code-block:: C - - RTIO_I2C_IODEV(i2c_dev, I2C_DT_SPEC_INST(n)); - RTIO_SPI_IODEV(spi_dev, SPI_DT_SPEC_INST(m)); - - RTIO_DEFINE(ez_io, 4, 4); - static uint8_t buf[32]; - - int do_some_io(void) - { - uint32_t read, write; - struct rtio_sqe *read_sqe = rtio_spsc_acquire(ez_io.sq); - rtio_sqe_prep_read(read_sqe, i2c_dev, RTIO_PRIO_LOW, buf, 32); - read_sqe->flags = RTIO_SQE_CHAINED; /* the next item in the queue will wait on this one */ - - /* Safe to do as the chained operation *ensures* that if one fails all subsequent ops fail */ - struct rtio_sqe *write_sqe = rtio_spsc_acquire(ez_io.sq); - rtio_sqe_prep_write(write_sqe, spi_dev, RTIO_PRIO_LOW, buf, 32); - - /* call will return immediately without blocking if possible */ - rtio_submit(rtio_inplace_executor, &ez_io, 0); - - /* These calls might return NULL if the operations have not yet completed! */ - for (int i = 0; i < 2; i++) { - struct rtio_cqe *cqe = rtio_spsc_consume(ez_io.cq); - while(cqe == NULL) { - cqe = rtio_spsc_consume(ez_io.cq); - k_yield(); - } - if(cqe->userdata == &read && cqe->result < 0) { - LOG_ERR("read from i2c failed!"); - } - if(cqe->userdata == &write && cqe->result < 0) { - LOG_ERR("write to spi failed!"); - } - /* Must release the completion queue event after consume */ - rtio_spsc_release(ez_io.cq); - } - } - -Nested iodevs for Devices on Buses (Sensors), Theoretical -========================================================= - -Consider a device like a sensor or audio codec sitting on a bus. - -Its useful to consider that the sensor driver can use RTIO to do I/O on the SPI -bus, while also being an RTIO device itself. The sensor iodev can set aside a -small portion of the buffer in front or in back to store some metadata describing -the format of the data. This metadata could then be used in creating a sensor -readings iterator which lazily lets you map over each reading, doing -calculations such as FIR/IIR filtering, or perhaps translating the readings into -other numerical formats with useful measurement units such as SI. RTIO is a -common movement API and allows for such uses while not deciding the mechanism. - -This same sort of setup could be done for other data streams such as audio or -video. - -.. code-block:: C - - /* Note that the sensor device itself can use RTIO to get data over I2C/SPI - * potentially with DMA, but we don't need to worry about that here - * All we need to know is the device tree node_id and that it can be an iodev - */ - RTIO_SENSOR_IODEV(sensor_dev, DEVICE_DT_GET(DT_NODE(super6axis)); - - RTIO_DEFINE(ez_io, 4, 4); - - - /* The sensor driver decides the minimum buffer size for us, we decide how - * many bufs. This could be a typical multiple of a fifo packet the sensor - * produces, ICM42688 for example produces a FIFO packet of 20 bytes in - * 20bit mode at 32KHz so perhaps we'd like to get 4 buffers of 4ms of data - * each in this setup to process on. and its already been defined here for us. - */ - #include - static uint8_t bufs[4][ICM42688_RTIO_BUF_SIZE]; - - int do_some_sensors(void) { - /* Obtain a dmac executor from the DMA device */ - struct device *dma = DEVICE_DT_GET(DT_NODE(dma0)); - const struct rtio_executor *rtio_dma_exec = - dma_rtio_executor(dma); - - /* - * Set the executor for our queue context - */ - rtio_set_executor(ez_io, rtio_dma_exec); - - /* Mostly we want to feed the sensor driver enough buffers to fill while - * we wait and process! Small enough to process quickly with low latency, - * big enough to not spend all the time setting transfers up. - * - * It's assumed here that the sensor has been configured already - * and each FIFO watermark interrupt that occurs it attempts - * to pull from the queue, fill the buffer with a small metadata - * offset using its own rtio request to the SPI bus using DMA. - */ - for(int i = 0; i < 4; i++) { - struct rtio_sqe *read_sqe = rtio_spsc_acquire(ez_io.sq); - - rtio_sqe_prep_read(read_sqe, sensor_dev, RTIO_PRIO_HIGH, bufs[i], ICM42688_RTIO_BUF_SIZE); - } - struct device *sensor = DEVICE_DT_GET(DT_NODE(super6axis)); - struct sensor_reader reader; - struct sensor_channels channels[4] = { - SENSOR_TIMESTAMP_CHANNEL, - SENSOR_CHANNEL(int32_t, SENSOR_ACC_X, 0, SENSOR_RAW), - SENSOR_CHANNEL(int32_t SENSOR_ACC_Y, 0, SENSOR_RAW), - SENSOR_CHANNEL(int32_t, SENSOR_ACC_Z, 0, SENSOR_RAW), - }; - while (true) { - /* call will wait for one completion event */ - rtio_submit(ez_io, 1); - struct rtio_cqe *cqe = rtio_spsc_consume(ez_io.cq); - if(cqe->result < 0) { - LOG_ERR("read failed!"); - goto next; - } - - /* Bytes read into the buffer */ - int32_t bytes_read = cqe->result; - - /* Retrieve soon to be reusable buffer pointer from completion */ - uint8_t *buf = cqe->userdata; - - - /* Get an iterator (reader) that obtains sensor readings in integer - * form, 16 bit signed values in the native sensor reading format - */ - res = sensor_reader(sensor, buf, cqe->result, &reader, channels, - sizeof(channels)); - __ASSERT(res == 0); - while(sensor_reader_next(&reader)) { - printf("time(raw): %d, acc (x,y,z): (%d, %d, %d)\n", - channels[0].value.u32, channels[1].value.i32, - channels[2].value.i32, channels[3].value.i32); - } - - next: - /* Release completion queue event */ - rtio_spsc_release(ez_io.cq); - - /* resubmit a read request with the newly freed buffer to the sensor */ - struct rtio_sqe *read_sqe = rtio_spsc_acquire(ez_io.sq); - rtio_sqe_prep_read(read_sqe, sensor_dev, RTIO_PRIO_HIGH, buf, ICM20649_RTIO_BUF_SIZE); - } - } - API Reference ************* From 09c69731cd0e5f68c5b3352dfeb5fc9ad6fd8bc7 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 7 Nov 2023 12:41:04 +0100 Subject: [PATCH 3558/4498] Bluetooth: Controller: Reduce RTN for requested Max Transport Latency Add implementation to reduce CIG's CIS retransmissions so as to meet the Host requested Maximum Transport Latency. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/ull_central_iso.c | 28 +++++++++++++++++-- .../audio/test_scripts/cap_unicast_ac_11_i.sh | 2 +- .../test_scripts/cap_unicast_ac_11_ii.sh | 2 +- .../audio/test_scripts/cap_unicast_ac_5.sh | 2 +- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 474b8d0dbe9..b0eac97a80c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -147,7 +147,6 @@ uint8_t ll_cis_parameters_set(uint8_t cis_id, } /* TODO: - * - Drop retransmissions to stay within Max_Transmission_Latency instead of asserting * - Calculate ISO_Interval to allow SDU_Interval < ISO_Interval */ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) @@ -311,6 +310,8 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) } num_cis = cig->lll.num_cis; + +ll_cig_parameters_commit_retry: handle_iter = UINT16_MAX; /* 1) Acquire CIS instances and initialize instance data. @@ -520,8 +521,29 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) if (!cig->central.test) { /* Make sure specified Max_Transport_Latency is not exceeded */ - LL_ASSERT(c_latency <= cig->c_latency); - LL_ASSERT(p_latency <= cig->p_latency); + if ((c_latency > cig->c_latency) || (p_latency > cig->p_latency)) { + /* Check if we can reduce RTN to meet requested latency */ + if (!cis->central.c_rtn && !cis->central.p_rtn) { + /* Actual latency exceeds the Max. Transport Latency */ + err = BT_HCI_ERR_INVALID_PARAM; + + /* Release allocated resources and exit */ + goto ll_cig_parameters_commit_cleanup; + } + + /* Reduce the RTN to meet host requested latency. + * NOTE: Both central and peripheral retransmission is reduced for + * simplicity. + */ + if (cis->central.c_rtn) { + cis->central.c_rtn--; + } + if (cis->central.p_rtn) { + cis->central.p_rtn--; + } + + goto ll_cig_parameters_commit_retry; + } } c_max_latency = MAX(c_max_latency, c_latency); diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh index 1fac51ec6c2..0356cd0b594 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_i.sh @@ -46,5 +46,5 @@ Execute_AC_11_I 48_1_1 48_1_1 Execute_AC_11_I 48_2_1 48_2_1 Execute_AC_11_I 48_3_1 48_3_1 Execute_AC_11_I 48_4_1 48_4_1 -# Execute_AC_11_I 48_5_1 48_5_1 # ASSERTION FAIL [c_latency <= cig->c_latency] +Execute_AC_11_I 48_5_1 48_5_1 Execute_AC_11_I 48_6_1 48_6_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh index 1908be1110b..c83bdc8c4be 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_11_ii.sh @@ -50,5 +50,5 @@ Execute_AC_11_II 48_1_1 48_1_1 Execute_AC_11_II 48_2_1 48_2_1 Execute_AC_11_II 48_3_1 48_3_1 Execute_AC_11_II 48_4_1 48_4_1 -# Execute_AC_11_II 48_5_1 48_5_1 # Controller assert: ASSERTION FAIL [c_latency <= cig->c_latency] +Execute_AC_11_II 48_5_1 48_5_1 Execute_AC_11_II 48_6_1 48_6_1 diff --git a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh index 33b186a7fc3..5eb9f6f5e30 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/cap_unicast_ac_5.sh @@ -46,4 +46,4 @@ Execute_AC_5 48_2_1 48_2_1 Execute_AC_5 48_3_1 48_3_1 Execute_AC_5 48_4_1 48_4_1 Execute_AC_5 48_5_1 48_5_1 -# Execute_AC_5 48_6_1 48_6_1 # ASSERTION FAIL [c_latency <= cig->c_latency] +Execute_AC_5 48_6_1 48_6_1 From dd27dff492e12c83431e1a20ff843ad0754c1127 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 27 Aug 2023 13:56:31 -0400 Subject: [PATCH 3559/4498] tests: lib: c_lib: separate libc tests into smaller suites C library testing is mainly there to support what is necessary to support Zephyr. We do test a variety of libcs currently, which is where YAML comes in handy. However, the main libc testsuite can be overkill for testing some things, and might not be suitable for testing optional features. Create a 'common' subdirectory for common libc tests. Signed-off-by: Christopher Friedt --- tests/lib/c_lib/{ => common}/CMakeLists.txt | 2 +- tests/lib/c_lib/{ => common}/README.txt | 0 tests/lib/c_lib/{ => common}/prj.conf | 0 tests/lib/c_lib/{ => common}/src/main.c | 68 +++++++++---------- tests/lib/c_lib/{ => common}/src/test_qsort.c | 4 +- tests/lib/c_lib/{ => common}/src/test_sqrt.c | 4 +- tests/lib/c_lib/common/testcase.yaml | 45 ++++++++++++ tests/lib/c_lib/strerror/CMakeLists.txt | 8 +++ tests/lib/c_lib/{ => strerror}/Kconfig | 0 tests/lib/c_lib/strerror/prj.conf | 2 + .../test_strerror.c => strerror/src/main.c} | 6 +- tests/lib/c_lib/{ => strerror}/testcase.yaml | 46 ++++++------- 12 files changed, 121 insertions(+), 64 deletions(-) rename tests/lib/c_lib/{ => common}/CMakeLists.txt (90%) rename tests/lib/c_lib/{ => common}/README.txt (100%) rename tests/lib/c_lib/{ => common}/prj.conf (100%) rename tests/lib/c_lib/{ => common}/src/main.c (96%) rename tests/lib/c_lib/{ => common}/src/test_qsort.c (98%) rename tests/lib/c_lib/{ => common}/src/test_sqrt.c (99%) create mode 100644 tests/lib/c_lib/common/testcase.yaml create mode 100644 tests/lib/c_lib/strerror/CMakeLists.txt rename tests/lib/c_lib/{ => strerror}/Kconfig (100%) create mode 100644 tests/lib/c_lib/strerror/prj.conf rename tests/lib/c_lib/{src/test_strerror.c => strerror/src/main.c} (95%) rename tests/lib/c_lib/{ => strerror}/testcase.yaml (74%) diff --git a/tests/lib/c_lib/CMakeLists.txt b/tests/lib/c_lib/common/CMakeLists.txt similarity index 90% rename from tests/lib/c_lib/CMakeLists.txt rename to tests/lib/c_lib/common/CMakeLists.txt index 2d5c65a0329..1731374ae7c 100644 --- a/tests/lib/c_lib/CMakeLists.txt +++ b/tests/lib/c_lib/common/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(c_lib) +project(libc_common) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) diff --git a/tests/lib/c_lib/README.txt b/tests/lib/c_lib/common/README.txt similarity index 100% rename from tests/lib/c_lib/README.txt rename to tests/lib/c_lib/common/README.txt diff --git a/tests/lib/c_lib/prj.conf b/tests/lib/c_lib/common/prj.conf similarity index 100% rename from tests/lib/c_lib/prj.conf rename to tests/lib/c_lib/common/prj.conf diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/common/src/main.c similarity index 96% rename from tests/lib/c_lib/src/main.c rename to tests/lib/c_lib/common/src/main.c index 2347dfebce1..986dba55f8e 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/common/src/main.c @@ -55,7 +55,7 @@ #pragma GCC diagnostic ignored "-Wstringop-truncation" #endif -ZTEST_SUITE(test_c_lib, NULL, NULL, NULL, NULL, NULL); +ZTEST_SUITE(libc_common, NULL, NULL, NULL, NULL, NULL); /* * variables used during limits library testing; must be marked as "volatile" @@ -74,7 +74,7 @@ volatile long long_one = 1L; * */ -ZTEST(test_c_lib, test_limits) +ZTEST(libc_common, test_limits) { zassert_true((long_max + long_one == LONG_MIN)); @@ -85,7 +85,7 @@ static ssize_t foobar(void) return -1; } -ZTEST(test_c_lib, test_ssize_t) +ZTEST(libc_common, test_ssize_t) { zassert_true(foobar() < 0); } @@ -95,7 +95,7 @@ ZTEST(test_c_lib, test_ssize_t) * @brief Test boolean types and values library * */ -ZTEST(test_c_lib, test_stdbool) +ZTEST(libc_common, test_stdbool) { zassert_true((true == 1), "true value"); @@ -115,7 +115,7 @@ volatile size_t size_of_long_variable = sizeof(long_variable); * @brief Test standard type definitions library * */ -ZTEST(test_c_lib, test_stddef) +ZTEST(libc_common, test_stddef) { #ifdef CONFIG_64BIT zassert_true((size_of_long_variable == 8), "sizeof"); @@ -137,7 +137,7 @@ volatile uint32_t unsigned_int = 0xffffff00; * @brief Test integer types library * */ -ZTEST(test_c_lib, test_stdint) +ZTEST(libc_common, test_stdint) { zassert_true((unsigned_int + unsigned_byte + 1u == 0U)); @@ -162,7 +162,7 @@ ZTEST(test_c_lib, test_stdint) * @brief Test time_t to make sure it is at least 64 bits * */ -ZTEST(test_c_lib, test_time_t) +ZTEST(libc_common, test_time_t) { #ifdef CONFIG_EXTERNAL_LIBC ztest_test_skip(); @@ -184,7 +184,7 @@ char buffer[BUFSIZE]; * @brief Test string memset * */ -ZTEST(test_c_lib, test_memset) +ZTEST(libc_common, test_memset) { int i, ret; const char set = 'a'; @@ -206,7 +206,7 @@ ZTEST(test_c_lib, test_memset) * @see strlen(), strnlen(). * */ -ZTEST(test_c_lib, test_strlen) +ZTEST(libc_common, test_strlen) { (void)memset(buffer, '\0', BUFSIZE); (void)memset(buffer, 'b', 5); /* 5 is BUFSIZE / 2 */ @@ -223,7 +223,7 @@ ZTEST(test_c_lib, test_strlen) * @see strcmp(), strncasecmp(). * */ -ZTEST(test_c_lib, test_strcmp) +ZTEST(libc_common, test_strcmp) { strcpy(buffer, "eeeee"); char test = 0; @@ -244,7 +244,7 @@ ZTEST(test_c_lib, test_strcmp) * * @see strncmp(). */ -ZTEST(test_c_lib, test_strncmp) +ZTEST(libc_common, test_strncmp) { static const char pattern[] = "eeeeeeeeeeee"; @@ -271,7 +271,7 @@ ZTEST(test_c_lib, test_strncmp) * * @see strcpy(). */ -ZTEST(test_c_lib, test_strcpy) +ZTEST(libc_common, test_strcpy) { (void)memset(buffer, '\0', BUFSIZE); strcpy(buffer, "10 chars!\0"); @@ -285,7 +285,7 @@ ZTEST(test_c_lib, test_strcpy) * * @see strncpy(). */ -ZTEST(test_c_lib, test_strncpy) +ZTEST(libc_common, test_strncpy) { int ret; @@ -304,7 +304,7 @@ ZTEST(test_c_lib, test_strncpy) * * @see strchr(). */ -ZTEST(test_c_lib, test_strchr) +ZTEST(libc_common, test_strchr) { char *rs = NULL; int ret; @@ -328,7 +328,7 @@ ZTEST(test_c_lib, test_strchr) * * @see strspn(),strcspn(). */ -ZTEST(test_c_lib, test_strxspn) +ZTEST(libc_common, test_strxspn) { const char *empty = ""; const char *cset = "abc"; @@ -352,7 +352,7 @@ ZTEST(test_c_lib, test_strxspn) * * @see memcmp() */ -ZTEST(test_c_lib, test_memcmp) +ZTEST(libc_common, test_memcmp) { int ret; unsigned char m1[] = "a\0$def"; @@ -383,7 +383,7 @@ int cmp_func(const void *a, const void *b) return (*(int *)a - *(int *)b); } -ZTEST(test_c_lib, test_bsearch) +ZTEST(libc_common, test_bsearch) { void *result = NULL; int arr[5] = { 2, 5, 20, 50, 60 }; @@ -404,7 +404,7 @@ ZTEST(test_c_lib, test_bsearch) * * @see abs() */ -ZTEST(test_c_lib, test_abs) +ZTEST(libc_common, test_abs) { int val = -5, value = 5; @@ -418,7 +418,7 @@ ZTEST(test_c_lib, test_abs) * * @see atoi() */ -ZTEST(test_c_lib, test_atoi) +ZTEST(libc_common, test_atoi) { zassert_equal(atoi("123"), 123, "atoi error"); zassert_equal(atoi("2c5"), 2, "atoi error"); @@ -442,7 +442,7 @@ ZTEST(test_c_lib, test_atoi) * isprint(), isspace(), isupper(), isxdigit(). * */ -ZTEST(test_c_lib, test_checktype) +ZTEST(libc_common, test_checktype) { static const char exp_alnum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -537,7 +537,7 @@ ZTEST(test_c_lib, test_checktype) * * @see memchr(). */ -ZTEST(test_c_lib, test_memchr) +ZTEST(libc_common, test_memchr) { static const char str[] = "testfunction"; @@ -556,7 +556,7 @@ ZTEST(test_c_lib, test_memchr) * * @see memcpy(). */ -ZTEST(test_c_lib, test_memcpy) +ZTEST(libc_common, test_memcpy) { /* make sure the buffer is word aligned */ uintptr_t mem_dest[4] = {0}; @@ -606,7 +606,7 @@ ZTEST(test_c_lib, test_memcpy) * * @see memmove(). */ -ZTEST(test_c_lib, test_memmove) +ZTEST(libc_common, test_memmove) { char move_buffer[6] = "12123"; char move_new[6] = {0}; @@ -632,7 +632,7 @@ ZTEST(test_c_lib, test_memmove) * @see strcat(), strcspn(), strncat(). * */ -ZTEST(test_c_lib, test_str_operate) +ZTEST(libc_common, test_str_operate) { char str1[10] = "aabbcc", ncat[10] = "ddee"; char *str2 = "b"; @@ -684,7 +684,7 @@ ZTEST(test_c_lib, test_str_operate) * @see strtol(). * */ -ZTEST(test_c_lib, test_strtol) +ZTEST(libc_common, test_strtol) { static const char buf1[] = "+10379aegi"; static const char buf2[] = " -10379aegi"; @@ -773,7 +773,7 @@ ZTEST(test_c_lib, test_strtol) * @see strtoul(). * */ -ZTEST(test_c_lib, test_strtoul) +ZTEST(libc_common, test_strtoul) { static const char buf1[] = "+10379aegi"; static const char buf2[] = " -10379aegi"; @@ -1012,7 +1012,7 @@ void test_strtoull(void) * @brief test convert function * */ -ZTEST(test_c_lib, test_tolower_toupper) +ZTEST(libc_common, test_tolower_toupper) { static const char test[] = "Az09Za{#!"; static const char toup[] = "AZ09ZA{#!"; @@ -1056,7 +1056,7 @@ void test_strtok_r_do(char *str, char *sep, int tlen, } } -ZTEST(test_c_lib, test_strtok_r) +ZTEST(libc_common, test_strtok_r) { static const char * const tc01[] = { "1", "2", "3", "4", "5" }; @@ -1077,7 +1077,7 @@ ZTEST(test_c_lib, test_strtok_r) * * @see gmtime(),gmtime_r(). */ -ZTEST(test_c_lib, test_time) +ZTEST(libc_common, test_time) { time_t tests1 = 0; time_t tests2 = -5; @@ -1099,7 +1099,7 @@ ZTEST(test_c_lib, test_time) * @brief Test rand function * */ -ZTEST(test_c_lib, test_rand) +ZTEST(libc_common, test_rand) { #ifdef CONFIG_MINIMAL_LIBC int a; @@ -1117,7 +1117,7 @@ ZTEST(test_c_lib, test_rand) * @brief Test srand function * */ -ZTEST(test_c_lib, test_srand) +ZTEST(libc_common, test_srand) { #ifdef CONFIG_MINIMAL_LIBC int a; @@ -1151,7 +1151,7 @@ ZTEST(test_c_lib, test_srand) * @brief Test rand function for reproducibility * */ -ZTEST(test_c_lib, test_rand_reproducibility) +ZTEST(libc_common, test_rand_reproducibility) { #ifdef CONFIG_MINIMAL_LIBC int a; @@ -1218,7 +1218,7 @@ ZTEST(test_c_lib, test_rand_reproducibility) * * @see abort(). */ -ZTEST(test_c_lib, test_abort) +ZTEST(libc_common, test_abort) { #ifdef CONFIG_EXTERNAL_LIBC ztest_test_skip(); @@ -1247,7 +1247,7 @@ static struct k_thread tdata; #endif -ZTEST(test_c_lib, test_exit) +ZTEST(libc_common, test_exit) { #ifdef CONFIG_EXTERNAL_LIBC ztest_test_skip(); diff --git a/tests/lib/c_lib/src/test_qsort.c b/tests/lib/c_lib/common/src/test_qsort.c similarity index 98% rename from tests/lib/c_lib/src/test_qsort.c rename to tests/lib/c_lib/common/src/test_qsort.c index 9cfddc396c9..37db119803f 100644 --- a/tests/lib/c_lib/src/test_qsort.c +++ b/tests/lib/c_lib/common/src/test_qsort.c @@ -22,7 +22,7 @@ static int compare_ints(const void *a, const void *b) * @brief Test qsort function * */ -ZTEST(test_c_lib, test_qsort) +ZTEST(libc_common, test_qsort) { { int actual_int[] = { 1, 3, 2 }; @@ -138,7 +138,7 @@ static int compare_ints_with_boolp_arg(const void *a, const void *b, void *argp) return (aa > bb) - (aa < bb); } -ZTEST(test_c_lib, test_qsort_r) +ZTEST(libc_common, test_qsort_r) { bool arg = false; diff --git a/tests/lib/c_lib/src/test_sqrt.c b/tests/lib/c_lib/common/src/test_sqrt.c similarity index 99% rename from tests/lib/c_lib/src/test_sqrt.c rename to tests/lib/c_lib/common/src/test_sqrt.c index 99af27717af..59edad9c193 100644 --- a/tests/lib/c_lib/src/test_sqrt.c +++ b/tests/lib/c_lib/common/src/test_sqrt.c @@ -94,7 +94,7 @@ static int isnanf(float x) #define MAX_FLOAT_ERROR_PERCENT (3.5e-5) #define MAX_DOUBLE_ERROR_PERCENT (4.5e-14) -ZTEST(test_c_lib, test_sqrtf) +ZTEST(libc_common, test_sqrtf) { int i; float exponent, resf, square, root_squared; @@ -164,7 +164,7 @@ int32_t *p_root_squared = (int32_t *)&root_squared; TC_PRINT("test_sqrtf max error %d counts\n", max_error); } -ZTEST(test_c_lib, test_sqrt) +ZTEST(libc_common, test_sqrt) { int i; double resd, error, square, root_squared, exponent; diff --git a/tests/lib/c_lib/common/testcase.yaml b/tests/lib/c_lib/common/testcase.yaml new file mode 100644 index 00000000000..28a7d54194c --- /dev/null +++ b/tests/lib/c_lib/common/testcase.yaml @@ -0,0 +1,45 @@ +common: + tags: + - clib + ignore_faults: true + integration_platforms: + - mps2_an385 +tests: + libraries.libc.common: {} + libraries.libc.common.minimal: + filter: CONFIG_MINIMAL_LIBC_SUPPORTED + tags: minimal_libc + extra_configs: + - CONFIG_MINIMAL_LIBC=y + - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y + - CONFIG_MINIMAL_LIBC_RAND=y + libraries.libc.common.newlib: + filter: CONFIG_NEWLIB_LIBC_SUPPORTED + min_ram: 32 + tags: newlib + extra_configs: + - CONFIG_NEWLIB_LIBC=y + libraries.libc.common.newlib_nano: + filter: CONFIG_NEWLIB_LIBC_SUPPORTED and CONFIG_HAS_NEWLIB_LIBC_NANO + tags: newlib + extra_configs: + - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_NANO=y + libraries.libc.common.picolibc: + filter: CONFIG_PICOLIBC_SUPPORTED + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + libraries.libc.common.picolibc.module: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + libraries.libc.common.picolibc.notls: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + - CONFIG_THREAD_LOCAL_STORAGE=n diff --git a/tests/lib/c_lib/strerror/CMakeLists.txt b/tests/lib/c_lib/strerror/CMakeLists.txt new file mode 100644 index 00000000000..350d76aa6d7 --- /dev/null +++ b/tests/lib/c_lib/strerror/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(c_lib_strerror) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/lib/c_lib/Kconfig b/tests/lib/c_lib/strerror/Kconfig similarity index 100% rename from tests/lib/c_lib/Kconfig rename to tests/lib/c_lib/strerror/Kconfig diff --git a/tests/lib/c_lib/strerror/prj.conf b/tests/lib/c_lib/strerror/prj.conf new file mode 100644 index 00000000000..e39776e7067 --- /dev/null +++ b/tests/lib/c_lib/strerror/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_TEST_USERSPACE=y diff --git a/tests/lib/c_lib/src/test_strerror.c b/tests/lib/c_lib/strerror/src/main.c similarity index 95% rename from tests/lib/c_lib/src/test_strerror.c rename to tests/lib/c_lib/strerror/src/main.c index 9b7dde334d8..8bfd06bbff5 100644 --- a/tests/lib/c_lib/src/test_strerror.c +++ b/tests/lib/c_lib/strerror/src/main.c @@ -13,7 +13,7 @@ #include -ZTEST(test_c_lib, test_strerror) +ZTEST(libc_strerror, test_strerror) { const char *expected; const char *actual; @@ -55,7 +55,7 @@ ZTEST(test_c_lib, test_strerror) } } -ZTEST(test_c_lib, test_strerror_r) +ZTEST(libc_strerror, test_strerror_r) { const char *expected; char actual[] = {'1', 'n', 'v', 'a', '1', '1', 'd', ' ', 'a', @@ -96,3 +96,5 @@ ZTEST(test_c_lib, test_strerror_r) /* do not change errno on failure */ zassert_equal(0, errno, ""); } + +ZTEST_SUITE(libc_strerror, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/lib/c_lib/testcase.yaml b/tests/lib/c_lib/strerror/testcase.yaml similarity index 74% rename from tests/lib/c_lib/testcase.yaml rename to tests/lib/c_lib/strerror/testcase.yaml index eb42925958a..2475c3e31ec 100644 --- a/tests/lib/c_lib/testcase.yaml +++ b/tests/lib/c_lib/strerror/testcase.yaml @@ -2,50 +2,50 @@ common: tags: - clib integration_platforms: - - mps2_an385 + - qemu_x86 tests: - libraries.libc: - ignore_faults: true - libraries.libc.picolibc: - filter: CONFIG_PICOLIBC_SUPPORTED - tags: picolibc - ignore_faults: true + libraries.libc.strerror.minimal.strerror_table: + filter: CONFIG_MINIMAL_LIBC_SUPPORTED + tags: minimal_libc extra_configs: - - CONFIG_PICOLIBC=y - libraries.libc.newlib: + - CONFIG_MINIMAL_LIBC=y + - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=y + - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y + libraries.libc.strerror.minimal.no_strerror_table: + filter: CONFIG_MINIMAL_LIBC_SUPPORTED + tags: minimal_libc + extra_configs: + - CONFIG_MINIMAL_LIBC=y + - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=n + - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y + libraries.libc.strerror.newlib: filter: CONFIG_NEWLIB_LIBC_SUPPORTED min_ram: 32 tags: newlib ignore_faults: true extra_configs: - CONFIG_NEWLIB_LIBC=y - libraries.libc.newlib_nano: + libraries.libc.strerror.newlib_nano: filter: CONFIG_NEWLIB_LIBC_SUPPORTED and CONFIG_HAS_NEWLIB_LIBC_NANO tags: newlib ignore_faults: true extra_configs: - CONFIG_NEWLIB_LIBC=y - CONFIG_NEWLIB_LIBC_NANO=y - libraries.libc.minimal.strerror_table: - filter: CONFIG_MINIMAL_LIBC_SUPPORTED - tags: minimal_libc - extra_configs: - - CONFIG_MINIMAL_LIBC=y - - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=y - libraries.libc.minimal.no_strerror_table: - filter: CONFIG_MINIMAL_LIBC_SUPPORTED - tags: minimal_libc + libraries.libc.strerror.picolibc: + filter: CONFIG_PICOLIBC_SUPPORTED + tags: picolibc + ignore_faults: true extra_configs: - - CONFIG_MINIMAL_LIBC=y - - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=n - libraries.libc.picolibc.module: + - CONFIG_PICOLIBC=y + libraries.libc.strerror.picolibc.module: filter: CONFIG_ZEPHYR_PICOLIBC_MODULE tags: picolibc ignore_faults: true extra_configs: - CONFIG_PICOLIBC=y - CONFIG_PICOLIBC_USE_MODULE=y - libraries.libc.picolibc.notls: + libraries.libc.strerror.picolibc.notls: filter: CONFIG_ZEPHYR_PICOLIBC_MODULE tags: picolibc ignore_faults: true From 97668b8b09c310eea4f383c48a78e55e6cec8163 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Mon, 24 Jul 2023 20:51:00 -0400 Subject: [PATCH 3560/4498] libc: common: add support for iso c11 threads This change capitalizes on newly added support for dynamic thread stacks and the existing pthread support to provide an implementation of the ISO C11 `` API. Signed-off-by: Christopher Friedt --- include/zephyr/posix/sys/stat.h | 2 +- lib/libc/common/CMakeLists.txt | 3 + lib/libc/common/Kconfig | 10 +++ lib/libc/common/include/machine/_threads.h | 20 +++++ lib/libc/common/include/threads.h | 47 ++++++++++++ lib/libc/common/source/thrd/thrd.c | 85 ++++++++++++++++++++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 lib/libc/common/include/machine/_threads.h create mode 100644 lib/libc/common/include/threads.h create mode 100644 lib/libc/common/source/thrd/thrd.c diff --git a/include/zephyr/posix/sys/stat.h b/include/zephyr/posix/sys/stat.h index 01251c65ace..2d19df29700 100644 --- a/include/zephyr/posix/sys/stat.h +++ b/include/zephyr/posix/sys/stat.h @@ -114,7 +114,7 @@ struct stat { #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec #if defined(__linux) && defined(__x86_64__) - __uint64_t __glibc_reserved[3]; + uint64_t __glibc_reserved[3]; #endif #else #if defined(__rtems__) diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index 04897751186..c65b6a1aa12 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -1,11 +1,14 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_system_include_directories(include) + zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ABORT source/stdlib/abort.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) +zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/thrd.c) # Prevent compiler from optimizing calloc into an infinite recursive call zephyr_library_compile_options($) diff --git a/lib/libc/common/Kconfig b/lib/libc/common/Kconfig index 56ac8f7b22b..dc22d0c2108 100644 --- a/lib/libc/common/Kconfig +++ b/lib/libc/common/Kconfig @@ -67,3 +67,13 @@ config COMMON_LIBC_STRNLEN bool help common implementation of strnlen(). + +config COMMON_LIBC_THRD + bool "C11 API support" + depends on DYNAMIC_THREAD + # Note: the POSIX_API dependency is only necessary until common elements + # of C11 threads and POSIX API can be abstracted out to a common library. + depends on POSIX_API + default y + help + Common implementation of C11 API. diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h new file mode 100644 index 00000000000..2c61ac0d81a --- /dev/null +++ b/lib/libc/common/include/machine/_threads.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_COMMON_INCLUDE_MACHINE__THREADS_H_ +#define ZEPHYR_LIB_LIBC_COMMON_INCLUDE_MACHINE__THREADS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int thrd_t; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LIB_LIBC_COMMON_INCLUDE_MACHINE__THREADS_H_ */ diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h new file mode 100644 index 00000000000..f045a23830c --- /dev/null +++ b/lib/libc/common/include/threads.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_COMMON_INCLUDE_THREADS_H_ +#define ZEPHYR_LIB_LIBC_COMMON_INCLUDE_THREADS_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*thrd_start_t)(void *arg); + +enum { + thrd_success, +#define thrd_success thrd_success + thrd_nomem, +#define thrd_nomem thrd_nomem + thrd_timedout, +#define thrd_timedout thrd_timedout + thrd_busy, +#define thrd_busy thrd_busy + thrd_error, +#define thrd_error thrd_error +}; + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); +int thrd_equal(thrd_t lhs, thrd_t rhs); +thrd_t thrd_current(void); +int thrd_sleep(const struct timespec *duration, struct timespec *remaining); +void thrd_yield(void); +_Noreturn void thrd_exit(int res); +int thrd_detach(thrd_t thr); +int thrd_join(thrd_t thr, int *res); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LIB_LIBC_COMMON_INCLUDE_THREADS_H_ */ diff --git a/lib/libc/common/source/thrd/thrd.c b/lib/libc/common/source/thrd/thrd.c new file mode 100644 index 00000000000..d811fe31ce6 --- /dev/null +++ b/lib/libc/common/source/thrd/thrd.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include + +struct thrd_trampoline_arg { + thrd_start_t func; + void *arg; +}; + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ + typedef void *(*pthread_func_t)(void *arg); + + pthread_func_t pfunc = (pthread_func_t)func; + + switch (pthread_create(thr, NULL, pfunc, arg)) { + case 0: + return thrd_success; + case EAGAIN: + return thrd_nomem; + default: + return thrd_error; + } +} + +int thrd_equal(thrd_t lhs, thrd_t rhs) +{ + return pthread_equal(lhs, rhs); +} + +thrd_t thrd_current(void) +{ + return pthread_self(); +} + +int thrd_sleep(const struct timespec *duration, struct timespec *remaining) +{ + return nanosleep(duration, remaining); +} + +void thrd_yield(void) +{ + (void)sched_yield(); +} + +FUNC_NORETURN void thrd_exit(int res) +{ + pthread_exit(INT_TO_POINTER(res)); + + CODE_UNREACHABLE; +} + +int thrd_detach(thrd_t thr) +{ + switch (pthread_detach(thr)) { + case 0: + return thrd_success; + default: + return thrd_error; + } +} + +int thrd_join(thrd_t thr, int *res) +{ + void *ret; + + switch (pthread_join(thr, &ret)) { + case 0: + if (res != NULL) { + *res = POINTER_TO_INT(ret); + } + return thrd_success; + default: + return thrd_error; + } +} From ded97fd5b31f1d135543598a89e00ea1c6ae7f89 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Mon, 24 Jul 2023 20:52:20 -0400 Subject: [PATCH 3561/4498] tests: libc: add tests for iso c11 threads Add tests to verify functionality of the C11 `` API. Signed-off-by: Christopher Friedt --- tests/lib/c_lib/thrd/CMakeLists.txt | 9 ++ tests/lib/c_lib/thrd/prj.conf | 9 ++ tests/lib/c_lib/thrd/src/thrd.c | 167 ++++++++++++++++++++++++++++ tests/lib/c_lib/thrd/src/thrd.h | 31 ++++++ tests/lib/c_lib/thrd/testcase.yaml | 52 +++++++++ 5 files changed, 268 insertions(+) create mode 100644 tests/lib/c_lib/thrd/CMakeLists.txt create mode 100644 tests/lib/c_lib/thrd/prj.conf create mode 100644 tests/lib/c_lib/thrd/src/thrd.c create mode 100644 tests/lib/c_lib/thrd/src/thrd.h create mode 100644 tests/lib/c_lib/thrd/testcase.yaml diff --git a/tests/lib/c_lib/thrd/CMakeLists.txt b/tests/lib/c_lib/thrd/CMakeLists.txt new file mode 100644 index 00000000000..795545f0cb9 --- /dev/null +++ b/tests/lib/c_lib/thrd/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(c11_threads) + +FILE(GLOB app_sources src/*.c) + +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/lib/c_lib/thrd/prj.conf b/tests/lib/c_lib/thrd/prj.conf new file mode 100644 index 00000000000..dfa2820de7c --- /dev/null +++ b/tests/lib/c_lib/thrd/prj.conf @@ -0,0 +1,9 @@ +CONFIG_ZTEST=y +CONFIG_TEST_USERSPACE=y +CONFIG_ZTEST_FATAL_HOOK=y + +CONFIG_POSIX_API=y +CONFIG_THREAD_STACK_INFO=y +CONFIG_DYNAMIC_THREAD=y +CONFIG_DYNAMIC_THREAD_POOL_SIZE=2 +CONFIG_COMMON_LIBC_THRD=y diff --git a/tests/lib/c_lib/thrd/src/thrd.c b/tests/lib/c_lib/thrd/src/thrd.c new file mode 100644 index 00000000000..55cd1841c13 --- /dev/null +++ b/tests/lib/c_lib/thrd/src/thrd.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "thrd.h" + +#include +#include + +#include +#include + +ZTEST(libc_thrd, test_thrd_sleep) +{ + int64_t end; + int64_t start; + struct timespec duration = {0}; + struct timespec remaining; + const uint16_t delay_ms[] = {0, 100, 200, 400}; + + zassert_not_equal(0, thrd_sleep(NULL, NULL)); + zassert_ok(thrd_sleep(&duration, NULL)); + zassert_ok(thrd_sleep(&duration, &duration)); + + for (int i = 0; i < ARRAY_SIZE(delay_ms); ++i) { + duration = (struct timespec){.tv_nsec = delay_ms[i] * NSEC_PER_MSEC}; + remaining = (struct timespec){.tv_sec = 4242, .tv_nsec = 4242}; + + printk("sleeping %d ms\n", delay_ms[i]); + start = k_uptime_get(); + zassert_ok(thrd_sleep(&duration, &remaining)); + end = k_uptime_get(); + zassert_equal(remaining.tv_sec, 0); + zassert_equal(remaining.tv_nsec, 0); + zassert_true(end - start >= delay_ms[i]); + } +} + +static int thrd_create_join_fn(void *arg) +{ + uintptr_t *x = (uintptr_t *)arg; + + if (x != NULL) { + *x = BIOS_FOOD; + } + + return FORTY_TWO; +} + +ZTEST(libc_thrd, test_thrd_create_join) +{ + thrd_t thr; + int res = 0; + uintptr_t x = 0; + thrd_start_t fun = thrd_create_join_fn; + + if (false) { + /* pthread_create() is not hardened for degenerate cases like this */ + zassert_equal(thrd_error, thrd_create(NULL, NULL, NULL)); + zassert_equal(thrd_error, thrd_create(NULL, NULL, &x)); + zassert_equal(thrd_error, thrd_create(NULL, fun, NULL)); + zassert_equal(thrd_error, thrd_create(NULL, fun, &x)); + zassert_equal(thrd_error, thrd_create(&thr, NULL, NULL)); + zassert_equal(thrd_error, thrd_create(&thr, NULL, &x)); + } + + zassert_equal(thrd_success, thrd_create(&thr, fun, NULL)); + zassert_equal(thrd_success, thrd_join(thr, NULL)); + + zassert_equal(thrd_success, thrd_create(&thr, fun, &x)); + zassert_equal(thrd_success, thrd_join(thr, &res)); + zassert_equal(BIOS_FOOD, x, "expected: %d actual: %d", BIOS_FOOD, x); + zassert_equal(FORTY_TWO, res); +} + +static int thrd_exit_fn(void *arg) +{ + uintptr_t *x = (uintptr_t *)arg; + + *x = BIOS_FOOD; + + thrd_exit(SEVENTY_THREE); + + return FORTY_TWO; + + CODE_UNREACHABLE; +} + +ZTEST(libc_thrd, test_thrd_exit) +{ + thrd_t thr; + int res = 0; + uintptr_t x = 0; + + zassert_equal(thrd_success, thrd_create(&thr, thrd_exit_fn, &x)); + zassert_equal(thrd_success, thrd_join(thr, &res)); + zassert_equal(BIOS_FOOD, x); + zassert_equal(SEVENTY_THREE, res); +} + +ZTEST(libc_thrd, test_thrd_yield) +{ + thrd_yield(); +} + +static thrd_t child; +static thrd_t parent; + +static int thrd_current_equal_fn(void *arg) +{ + ARG_UNUSED(arg); + + zassert_equal(thrd_current(), child); + zassert_not_equal(child, parent); + + zassert_true(thrd_equal(thrd_current(), child)); + zassert_false(thrd_equal(child, parent)); + + return 0; +} + +ZTEST(libc_thrd, test_thrd_current_equal) +{ + parent = thrd_current(); + + zassert_equal(thrd_success, thrd_create(&child, thrd_current_equal_fn, NULL)); + zassert_equal(thrd_success, thrd_join(child, NULL)); +} + +static bool detached_thread_is_probably_done; + +static int thrd_detach_fn(void *arg) +{ + ARG_UNUSED(arg); + + detached_thread_is_probably_done = true; + return SEVENTY_THREE; +} + +ZTEST(libc_thrd, test_thrd_detach) +{ + thrd_t thr; + + zassert_equal(thrd_success, thrd_create(&thr, thrd_detach_fn, NULL)); + zassert_equal(thrd_success, thrd_detach(thr)); + zassert_equal(thrd_error, thrd_join(thr, NULL)); + + do { + k_msleep(100); + } while (!detached_thread_is_probably_done); + + zassert_equal(thrd_error, thrd_join(thr, NULL)); +} + +ZTEST(libc_thrd, test_thrd_reuse) +{ + thrd_t thr; + + for (int i = 0; i < FORTY_TWO; ++i) { + zassert_equal(thrd_success, thrd_create(&thr, thrd_create_join_fn, NULL)); + zassert_equal(thrd_success, thrd_join(thr, NULL)); + } +} + +ZTEST_SUITE(libc_thrd, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/lib/c_lib/thrd/src/thrd.h b/tests/lib/c_lib/thrd/src/thrd.h new file mode 100644 index 00000000000..02861b2ac6e --- /dev/null +++ b/tests/lib/c_lib/thrd/src/thrd.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TESTS_LIB_CLIB_SRC_TEST_THRD_H_ +#define TESTS_LIB_CLIB_SRC_TEST_THRD_H_ + +#include + +#include +#include + +/* arbitrary magic numbers used for testing */ +#define BIOS_FOOD 0xb105f00d +#define FORTY_TWO 42 +#define SEVENTY_THREE 73 +#define DONT_CARE 0x370ca2e5 + +static inline void timespec_add_ms(struct timespec *ts, uint32_t ms) +{ + bool oflow; + + ts->tv_nsec += ms * NSEC_PER_MSEC; + oflow = ts->tv_nsec >= NSEC_PER_SEC; + ts->tv_sec += oflow; + ts->tv_nsec -= oflow * NSEC_PER_SEC; +} + +#endif diff --git a/tests/lib/c_lib/thrd/testcase.yaml b/tests/lib/c_lib/thrd/testcase.yaml new file mode 100644 index 00000000000..ecba688407f --- /dev/null +++ b/tests/lib/c_lib/thrd/testcase.yaml @@ -0,0 +1,52 @@ +common: + tags: + - clib c11 threads + filter: not CONFIG_NATIVE_APPLICATION + integration_platforms: + - qemu_x86 + platform_exclude: + - native_posix + - native_posix_64 +tests: + libraries.libc.c11_threads.minimal: + tags: minimal_libc + filter: CONFIG_MINIMAL_LIBC_SUPPORTED + extra_configs: + - CONFIG_MINIMAL_LIBC=y + - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y + - CONFIG_MINIMAL_LIBC_RAND=y + libraries.libc.c11_threads.picolibc: + filter: CONFIG_PICOLIBC_SUPPORTED + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + libraries.libc.c11_threads.picolibc.module: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + - CONFIG_THREAD_LOCAL_STORAGE=y + libraries.libc.c11_threads.picolibc.notls: + filter: CONFIG_ZEPHYR_PICOLIBC_MODULE + tags: picolibc + extra_configs: + - CONFIG_PICOLIBC=y + - CONFIG_PICOLIBC_USE_MODULE=y + - CONFIG_THREAD_LOCAL_STORAGE=n + libraries.libc.c11_threads.newlib: + filter: CONFIG_NEWLIB_LIBC_SUPPORTED + arch_exclude: + - posix + min_ram: 32 + tags: newlib + extra_configs: + - CONFIG_NEWLIB_LIBC=y + libraries.libc.c11_threads.newlib_nano: + filter: CONFIG_NEWLIB_LIBC_SUPPORTED and CONFIG_HAS_NEWLIB_LIBC_NANO + arch_exclude: + - posix + tags: newlib + extra_configs: + - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_NANO=y From 576ae7f677919bd1236f5e1b2f428122838cefa7 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Wed, 2 Aug 2023 10:38:45 -0400 Subject: [PATCH 3562/4498] lib: libc: common: add C11 mutex implementation Add support for C11 mutexes to go with C11 threads. Signed-off-by: Christopher Friedt --- lib/libc/common/CMakeLists.txt | 5 +- lib/libc/common/include/machine/_threads.h | 1 + lib/libc/common/include/threads.h | 16 ++++ lib/libc/common/source/thrd/mtx.c | 99 ++++++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 lib/libc/common/source/thrd/mtx.c diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index c65b6a1aa12..2a78574715c 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -8,7 +8,10 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ABORT source/stdlib/abort.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) -zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/thrd.c) +zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD + source/thrd/mtx.c + source/thrd/thrd.c + ) # Prevent compiler from optimizing calloc into an infinite recursive call zephyr_library_compile_options($) diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h index 2c61ac0d81a..e0360410a47 100644 --- a/lib/libc/common/include/machine/_threads.h +++ b/lib/libc/common/include/machine/_threads.h @@ -11,6 +11,7 @@ extern "C" { #endif +typedef int mtx_t; typedef int thrd_t; #ifdef __cplusplus diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h index f045a23830c..13e57cc9a8d 100644 --- a/lib/libc/common/include/threads.h +++ b/lib/libc/common/include/threads.h @@ -40,6 +40,22 @@ _Noreturn void thrd_exit(int res); int thrd_detach(thrd_t thr); int thrd_join(thrd_t thr, int *res); +enum { + mtx_plain, +#define mtx_plain mtx_plain + mtx_timed, +#define mtx_timed mtx_timed + mtx_recursive, +#define mtx_recursive mtx_recursive +}; + +int mtx_init(mtx_t *mutex, int type); +void mtx_destroy(mtx_t *mutex); +int mtx_lock(mtx_t *mutex); +int mtx_timedlock(mtx_t *ZRESTRICT mutex, const struct timespec *ZRESTRICT time_point); +int mtx_trylock(mtx_t *mutex); +int mtx_unlock(mtx_t *mutex); + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/thrd/mtx.c b/lib/libc/common/source/thrd/mtx.c new file mode 100644 index 00000000000..9746ea64fe6 --- /dev/null +++ b/lib/libc/common/source/thrd/mtx.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +int mtx_init(mtx_t *mutex, int type) +{ + int ret; + pthread_mutexattr_t attr; + pthread_mutexattr_t *attrp = NULL; + + switch (type) { + case mtx_plain: + case mtx_timed: + break; + case mtx_plain | mtx_recursive: + case mtx_timed | mtx_recursive: + attrp = &attr; + ret = pthread_mutexattr_init(attrp); + __ASSERT_NO_MSG(ret == 0); + + ret = pthread_mutexattr_settype(attrp, PTHREAD_MUTEX_RECURSIVE); + __ASSERT_NO_MSG(ret == 0); + break; + default: + return thrd_error; + } + + switch (pthread_mutex_init(mutex, attrp)) { + case 0: + ret = thrd_success; + break; + default: + ret = thrd_error; + break; + } + + if (attrp != NULL) { + (void)pthread_mutexattr_destroy(attrp); + } + + return ret; +} + +void mtx_destroy(mtx_t *mutex) +{ + (void)pthread_mutex_destroy(mutex); +} + +int mtx_lock(mtx_t *mutex) +{ + switch (pthread_mutex_lock(mutex)) { + case 0: + return thrd_success; + default: + return thrd_error; + } +} + +int mtx_timedlock(mtx_t *restrict mutex, const struct timespec *restrict time_point) +{ + switch (pthread_mutex_timedlock(mutex, time_point)) { + case 0: + return thrd_success; + case ETIMEDOUT: + return thrd_timedout; + default: + return thrd_error; + } +} + +int mtx_trylock(mtx_t *mutex) +{ + switch (pthread_mutex_trylock(mutex)) { + case 0: + return thrd_success; + case EBUSY: + return thrd_busy; + default: + return thrd_error; + } +} + +int mtx_unlock(mtx_t *mutex) +{ + switch (pthread_mutex_unlock(mutex)) { + case 0: + return thrd_success; + default: + return thrd_error; + } +} From 0c2da383d33933a6557646ec8827311de7441b30 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Wed, 2 Aug 2023 10:40:41 -0400 Subject: [PATCH 3563/4498] tests: lib: c_lib: add tests for C11 mutexes Add tests to cover C11 mutexes Signed-off-by: Christopher Friedt --- tests/lib/c_lib/thrd/src/mtx.c | 177 +++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 tests/lib/c_lib/thrd/src/mtx.c diff --git a/tests/lib/c_lib/thrd/src/mtx.c b/tests/lib/c_lib/thrd/src/mtx.c new file mode 100644 index 00000000000..433ea0e64e4 --- /dev/null +++ b/tests/lib/c_lib/thrd/src/mtx.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "thrd.h" + +#include +#include + +#include +#include + +static const int valid_mtx_types[] = { + mtx_plain, + mtx_timed, + mtx_plain | mtx_recursive, + mtx_timed | mtx_recursive, +}; + +ZTEST(libc_mtx, test_mtx_init) +{ + mtx_t mutex; + + zassert_not_equal(thrd_success, mtx_init(NULL, FORTY_TWO)); + zassert_not_equal(thrd_success, mtx_init(&mutex, FORTY_TWO)); + + if (false) { + /* pthread_mutexattr_init() is not hardened against this */ + zassert_not_equal(thrd_success, mtx_init(NULL, mtx_plain)); + zassert_not_equal(thrd_success, mtx_init((mtx_t *)BIOS_FOOD, FORTY_TWO)); + } + + for (size_t i = 0; i < ARRAY_SIZE(valid_mtx_types); ++i) { + int type = valid_mtx_types[i]; + + zassert_equal(thrd_success, mtx_init(&mutex, type)); + mtx_destroy(&mutex); + } +} + +ZTEST(libc_mtx, test_mtx_destroy) +{ + mtx_t mutex; + + if (false) { + /* degenerate cases */ + /* pthread_mutex_destroy() is not hardened against these */ + mtx_destroy(NULL); + mtx_destroy((mtx_t *)BIOS_FOOD); + } + + zassert_equal(thrd_success, mtx_init(&mutex, mtx_plain)); + mtx_destroy(&mutex); +} + +ZTEST(libc_mtx, test_mtx_lock) +{ + mtx_t mutex; + + if (false) { + /* pthread_mutex_lock() is not hardened against this */ + zassert_not_equal(thrd_success, mtx_lock(NULL)); + zassert_not_equal(thrd_success, mtx_lock((mtx_t *)BIOS_FOOD)); + } + + /* test plain mutex */ + for (size_t i = 0; i < ARRAY_SIZE(valid_mtx_types); ++i) { + int type = valid_mtx_types[i]; + + zassert_equal(thrd_success, mtx_init(&mutex, type)); + zassert_equal(thrd_success, mtx_lock(&mutex)); + if ((type & mtx_recursive) == 0) { + if (false) { + /* pthread_mutex_lock() is not hardened against this */ + zassert_not_equal(thrd_success, mtx_lock((&mutex))); + } + } else { + zassert_equal(thrd_success, mtx_lock(&mutex)); + zassert_equal(thrd_success, mtx_unlock(&mutex)); + } + zassert_equal(thrd_success, mtx_unlock(&mutex)); + mtx_destroy(&mutex); + } +} + +#define TIMEDLOCK_TIMEOUT_MS 200 +#define TIMEDLOCK_TIMEOUT_DELAY_MS 100 + +BUILD_ASSERT(TIMEDLOCK_TIMEOUT_DELAY_MS >= 100, "TIMEDLOCK_TIMEOUT_DELAY_MS too small"); +BUILD_ASSERT(TIMEDLOCK_TIMEOUT_MS >= 2 * TIMEDLOCK_TIMEOUT_DELAY_MS, + "TIMEDLOCK_TIMEOUT_MS too small"); + +static int mtx_timedlock_fn(void *arg) +{ + struct timespec time_point; + mtx_t *mutex = (mtx_t *)arg; + + zassume_ok(clock_gettime(CLOCK_MONOTONIC, &time_point)); + timespec_add_ms(&time_point, TIMEDLOCK_TIMEOUT_MS); + + return mtx_timedlock(mutex, &time_point); +} + +ZTEST(libc_mtx, test_mtx_timedlock) +{ + int ret; + thrd_t th; + mtx_t mutex; + + /* + * mtx_timed here is technically unnecessary, because all pthreads can + * be used for timed locks, but that is sort of peeking into the + * implementation + */ + zassert_equal(thrd_success, mtx_init(&mutex, mtx_timed)); + + printk("Expecting timedlock with timeout of %d ms to fail\n", TIMEDLOCK_TIMEOUT_MS); + zassert_equal(thrd_success, mtx_lock(&mutex)); + zassert_equal(thrd_success, thrd_create(&th, mtx_timedlock_fn, &mutex)); + zassert_equal(thrd_success, thrd_join(th, &ret)); + /* ensure timeout occurs */ + zassert_equal(thrd_timedout, ret); + + printk("Expecting timedlock with timeout of %d ms to succeed after 100ms\n", + TIMEDLOCK_TIMEOUT_MS); + zassert_equal(thrd_success, thrd_create(&th, mtx_timedlock_fn, &mutex)); + /* unlock before timeout expires */ + k_msleep(TIMEDLOCK_TIMEOUT_DELAY_MS); + zassert_equal(thrd_success, mtx_unlock(&mutex)); + zassert_equal(thrd_success, thrd_join(th, &ret)); + /* ensure lock is successful, in spite of delay */ + zassert_equal(thrd_success, ret); + + mtx_destroy(&mutex); +} + +static int mtx_trylock_fn(void *arg) +{ + mtx_t *mutex = (mtx_t *)arg; + + return mtx_trylock(mutex); +} + +ZTEST(libc_mtx, test_mtx_trylock) +{ + int ret; + thrd_t th; + mtx_t mutex; + + zassert_equal(thrd_success, mtx_init(&mutex, mtx_plain)); + + /* ensure trylock fails when lock is held */ + zassert_equal(thrd_success, mtx_lock(&mutex)); + zassert_equal(thrd_success, thrd_create(&th, mtx_trylock_fn, &mutex)); + zassert_equal(thrd_success, thrd_join(th, &ret)); + /* ensure lock fails */ + zassert_equal(thrd_busy, ret); + + mtx_destroy(&mutex); +} + +ZTEST(libc_mtx, test_mtx_unlock) +{ + mtx_t mutex = (mtx_t)BIOS_FOOD; + + /* degenerate case */ + zassert_not_equal(thrd_success, mtx_unlock(&mutex)); + + zassert_equal(thrd_success, mtx_init(&mutex, mtx_plain)); + zassert_equal(thrd_success, mtx_lock(&mutex)); + zassert_equal(thrd_success, mtx_unlock(&mutex)); + mtx_destroy(&mutex); +} + +ZTEST_SUITE(libc_mtx, NULL, NULL, NULL, NULL, NULL); From 7e539e2706a7cc33d79bc2b528795f1b6c407843 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Thu, 3 Aug 2023 21:45:50 -0400 Subject: [PATCH 3564/4498] libc: common: support for C11 condition variables Add C11 condition variable support to go with C11 threads and mutexes. Signed-off-by: Christopher Friedt --- lib/libc/common/CMakeLists.txt | 1 + lib/libc/common/include/machine/_threads.h | 1 + lib/libc/common/include/threads.h | 7 +++ lib/libc/common/source/thrd/cnd.c | 71 ++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 lib/libc/common/source/thrd/cnd.c diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index 2a78574715c..a52d8dc8d42 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD + source/thrd/cnd.c source/thrd/mtx.c source/thrd/thrd.c ) diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h index e0360410a47..0b82b876505 100644 --- a/lib/libc/common/include/machine/_threads.h +++ b/lib/libc/common/include/machine/_threads.h @@ -11,6 +11,7 @@ extern "C" { #endif +typedef int cnd_t; typedef int mtx_t; typedef int thrd_t; diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h index 13e57cc9a8d..f4a52f74b13 100644 --- a/lib/libc/common/include/threads.h +++ b/lib/libc/common/include/threads.h @@ -56,6 +56,13 @@ int mtx_timedlock(mtx_t *ZRESTRICT mutex, const struct timespec *ZRESTRICT time_ int mtx_trylock(mtx_t *mutex); int mtx_unlock(mtx_t *mutex); +int cnd_init(cnd_t *cond); +int cnd_wait(cnd_t *cond, mtx_t *mtx); +int cnd_timedwait(cnd_t *ZRESTRICT cond, mtx_t *ZRESTRICT mtx, const struct timespec *ZRESTRICT ts); +int cnd_signal(cnd_t *cond); +int cnd_broadcast(cnd_t *cond); +void cnd_destroy(cnd_t *cond); + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/thrd/cnd.c b/lib/libc/common/source/thrd/cnd.c new file mode 100644 index 00000000000..aea6f5cb78a --- /dev/null +++ b/lib/libc/common/source/thrd/cnd.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +int cnd_broadcast(cnd_t *cond) +{ + switch (pthread_cond_broadcast(cond)) { + case 0: + return thrd_success; + default: + return thrd_error; + } +} + +void cnd_destroy(cnd_t *cond) +{ + (void)pthread_cond_destroy(cond); +} + +int cnd_init(cnd_t *cond) +{ + switch (pthread_cond_init(cond, NULL)) { + case 0: + return thrd_success; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +int cnd_signal(cnd_t *cond) +{ + switch (pthread_cond_signal(cond)) { + case 0: + return thrd_success; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, const struct timespec *restrict ts) +{ + switch (pthread_cond_timedwait(cond, mtx, ts)) { + case 0: + return thrd_success; + case ETIMEDOUT: + return thrd_timedout; + default: + return thrd_error; + } +} + +int cnd_wait(cnd_t *cond, mtx_t *mtx) +{ + switch (pthread_cond_wait(cond, mtx)) { + case 0: + return thrd_success; + default: + return thrd_error; + } +} From 70b03111ebaef374c9699418ef2883340de9cee3 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Thu, 3 Aug 2023 21:46:46 -0400 Subject: [PATCH 3565/4498] tests: lib: c_lib: tests for C11 condition variables Add tests for C11 condition variables. Signed-off-by: Christopher Friedt --- tests/lib/c_lib/thrd/src/cnd.c | 172 +++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 tests/lib/c_lib/thrd/src/cnd.c diff --git a/tests/lib/c_lib/thrd/src/cnd.c b/tests/lib/c_lib/thrd/src/cnd.c new file mode 100644 index 00000000000..aaf00f9cb7b --- /dev/null +++ b/tests/lib/c_lib/thrd/src/cnd.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "thrd.h" + +#include +#include + +#include + +#define WAIT_TIME_MS 100 + +static struct libc_cnd_fixture { + /* shared between threads in tests */ + cnd_t cond; + mtx_t mutex; + + /* de-duplicate local variables in test cases */ + int res1; + int res2; + thrd_t thrd1; + thrd_t thrd2; + bool do_timedwait; + bool is_broadcast; + struct timespec time_point; +} _libc_cnd_fixture; + +ZTEST_F(libc_cnd, test_cnd_init_destroy) +{ + /* degenerate cases */ + if (false) { + /* pthread_cond_init() pthread_cond_destroy() are not hardened against these */ + zassert_equal(thrd_error, cnd_init(NULL)); + zassert_equal(thrd_error, cnd_init((cnd_t *)BIOS_FOOD)); + cnd_destroy(NULL); + cnd_destroy((cnd_t *)BIOS_FOOD); + } + + /* happy path tested in before() / after() */ +} + +ZTEST_F(libc_cnd, test_cnd_errors) +{ + /* degenerate test cases */ + if (false) { + /* pthread_cond_*() are not hardened against these */ + zassert_equal(thrd_error, cnd_signal(NULL)); + zassert_equal(thrd_error, cnd_broadcast(NULL)); + zassert_equal(thrd_error, cnd_wait(NULL, NULL)); + zassert_equal(thrd_error, cnd_wait(NULL, &fixture->mutex)); + zassert_equal(thrd_error, cnd_wait(&fixture->cond, NULL)); + zassert_equal(thrd_error, cnd_timedwait(NULL, NULL, NULL)); + zassert_equal(thrd_error, cnd_timedwait(NULL, NULL, &fixture->time_point)); + zassert_equal(thrd_error, cnd_timedwait(NULL, &fixture->mutex, NULL)); + zassert_equal(thrd_error, + cnd_timedwait(NULL, &fixture->mutex, &fixture->time_point)); + zassert_equal(thrd_error, cnd_timedwait(&fixture->cond, NULL, NULL)); + zassert_equal(thrd_error, + cnd_timedwait(&fixture->cond, NULL, &fixture->time_point)); + zassert_equal(thrd_error, cnd_timedwait(&fixture->cond, &fixture->mutex, NULL)); + } +} + +static int test_cnd_thread_fn(void *arg) +{ + int res = thrd_success; + struct timespec time_point; + struct libc_cnd_fixture *const fixture = arg; + + if (fixture->do_timedwait) { + zassume_ok(clock_gettime(CLOCK_MONOTONIC, &time_point)); + timespec_add_ms(&time_point, WAIT_TIME_MS); + res = cnd_timedwait(&fixture->cond, &fixture->mutex, &time_point); + } else { + res = cnd_wait(&fixture->cond, &fixture->mutex); + } + + if (fixture->is_broadcast) { + /* re-signal so that the next thread wakes up too */ + zassert_equal(thrd_success, cnd_signal(&fixture->cond)); + } + + (void)mtx_unlock(&fixture->mutex); + + return res; +} + +static void tst_cnd_common(struct libc_cnd_fixture *fixture, size_t wait_ms, bool th2, int exp1, + int exp2) +{ + zassert_equal(thrd_success, mtx_lock(&fixture->mutex)); + + zassert_equal(thrd_success, thrd_create(&fixture->thrd1, test_cnd_thread_fn, fixture)); + if (th2) { + zassert_equal(thrd_success, + thrd_create(&fixture->thrd2, test_cnd_thread_fn, fixture)); + } + + k_msleep(wait_ms); + + if (fixture->is_broadcast) { + zassert_equal(thrd_success, cnd_broadcast(&fixture->cond)); + } else { + zassert_equal(thrd_success, cnd_signal(&fixture->cond)); + } + + zassert_equal(thrd_success, mtx_unlock(&fixture->mutex)); + + zassert_equal(thrd_success, thrd_join(fixture->thrd1, &fixture->res1)); + if (th2) { + zassert_equal(thrd_success, thrd_join(fixture->thrd2, &fixture->res2)); + } + + zassert_equal(exp1, fixture->res1); + if (th2) { + zassert_equal(exp2, fixture->res2); + } +} + +ZTEST_F(libc_cnd, test_cnd_signal_wait) +{ + tst_cnd_common(fixture, WAIT_TIME_MS / 2, false, thrd_success, DONT_CARE); +} + +ZTEST_F(libc_cnd, test_cnd_signal_timedwait) +{ + fixture->do_timedwait = true; + tst_cnd_common(fixture, WAIT_TIME_MS / 2, false, thrd_success, DONT_CARE); +} + +ZTEST_F(libc_cnd, test_cnd_timedwait_timeout) +{ + fixture->do_timedwait = true; + tst_cnd_common(fixture, WAIT_TIME_MS * 2, false, thrd_timedout, DONT_CARE); +} + +ZTEST_F(libc_cnd, test_cnd_broadcast_wait) +{ + fixture->is_broadcast = true; + tst_cnd_common(fixture, WAIT_TIME_MS, true, thrd_success, thrd_success); +} + +static void *setup(void) +{ + return &_libc_cnd_fixture; +} + +static void before(void *arg) +{ + struct libc_cnd_fixture *const fixture = arg; + + *fixture = (struct libc_cnd_fixture){ + .res1 = FORTY_TWO, + .res2 = SEVENTY_THREE, + }; + + zassert_equal(thrd_success, mtx_init(&fixture->mutex, mtx_plain)); + zassert_equal(thrd_success, cnd_init(&fixture->cond)); +} + +static void after(void *arg) +{ + struct libc_cnd_fixture *const fixture = arg; + + cnd_destroy(&fixture->cond); + mtx_destroy(&fixture->mutex); +} + +ZTEST_SUITE(libc_cnd, NULL, setup, before, after, NULL); From b9db7df628a6a81a436e0afb1a699cb73aa4cf5b Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 25 Aug 2023 07:30:54 -0400 Subject: [PATCH 3566/4498] libc: common: support for C11 thread-specific storage Add C11 thread-specific storage (tss) support to go with C11 threads and mutexes. Signed-off-by: Christopher Friedt --- lib/libc/common/CMakeLists.txt | 1 + lib/libc/common/include/machine/_threads.h | 1 + lib/libc/common/include/threads.h | 11 +++++ lib/libc/common/source/thrd/tss.c | 47 ++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 lib/libc/common/source/thrd/tss.c diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index a52d8dc8d42..a99ec825a00 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/cnd.c source/thrd/mtx.c source/thrd/thrd.c + source/thrd/tss.c ) # Prevent compiler from optimizing calloc into an infinite recursive call diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h index 0b82b876505..2742384599c 100644 --- a/lib/libc/common/include/machine/_threads.h +++ b/lib/libc/common/include/machine/_threads.h @@ -14,6 +14,7 @@ extern "C" { typedef int cnd_t; typedef int mtx_t; typedef int thrd_t; +typedef int tss_t; #ifdef __cplusplus } diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h index f4a52f74b13..c7d23144444 100644 --- a/lib/libc/common/include/threads.h +++ b/lib/libc/common/include/threads.h @@ -63,6 +63,17 @@ int cnd_signal(cnd_t *cond); int cnd_broadcast(cnd_t *cond); void cnd_destroy(cnd_t *cond); +#ifndef thread_local +#define thread_local _Thread_local +#endif + +typedef void (*tss_dtor_t)(void *val); + +int tss_create(tss_t *key, tss_dtor_t destructor); +void *tss_get(tss_t key); +int tss_set(tss_t key, void *val); +void tss_delete(tss_t key); + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/thrd/tss.c b/lib/libc/common/source/thrd/tss.c new file mode 100644 index 00000000000..4b110d17170 --- /dev/null +++ b/lib/libc/common/source/thrd/tss.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +int tss_create(tss_t *key, tss_dtor_t destructor) +{ + switch (pthread_key_create(key, destructor)) { + case 0: + return thrd_success; + case EAGAIN: + return thrd_busy; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +void *tss_get(tss_t key) +{ + return pthread_getspecific(key); +} + +int tss_set(tss_t key, void *val) +{ + switch (pthread_setspecific(key, val)) { + case 0: + return thrd_success; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +void tss_delete(tss_t key) +{ + (void)pthread_key_delete(key); +} From 44a431bbba3de1aedf3ee7f18a9c6b3b4b114d9c Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 25 Aug 2023 07:32:59 -0400 Subject: [PATCH 3567/4498] tests: lib: c_lib: tests for C11 thread-specific storage Add tests for C11 thread-specific storage. Signed-off-by: Christopher Friedt --- tests/lib/c_lib/thrd/src/tss.c | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/lib/c_lib/thrd/src/tss.c diff --git a/tests/lib/c_lib/thrd/src/tss.c b/tests/lib/c_lib/thrd/src/tss.c new file mode 100644 index 00000000000..d68a6489dc5 --- /dev/null +++ b/tests/lib/c_lib/thrd/src/tss.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "thrd.h" + +#include +#include + +#include + +static tss_t key; +static int32_t destroyed_values[2]; +static const int32_t forty_two = FORTY_TWO; +static const int32_t seventy_three = SEVENTY_THREE; + +static void destroy_fn(void *arg) +{ + int32_t val = *(int32_t *)arg; + + switch (val) { + case FORTY_TWO: + destroyed_values[0] = FORTY_TWO; + break; + case SEVENTY_THREE: + destroyed_values[1] = SEVENTY_THREE; + break; + default: + zassert_true(val == FORTY_TWO || val == SEVENTY_THREE, "unexpected val %d", val); + } +} + +ZTEST(libc_tss, test_tss_create_delete) +{ + /* degenerate test cases */ + if (false) { + /* pthread_key_create() has not been hardened against this */ + zassert_equal(thrd_error, tss_create(NULL, NULL)); + zassert_equal(thrd_error, tss_create(NULL, destroy_fn)); + } + tss_delete(BIOS_FOOD); + + /* happy path tested in before() / after() */ +} + +static int thread_fn(void *arg) +{ + int32_t val = *(int32_t *)arg; + + zassert_equal(tss_get(key), NULL); + tss_set(key, arg); + zassert_equal(tss_get(key), arg); + + return val; +} + +/* test out separate threads doing tss_get() / tss_set() */ +ZTEST(libc_tss, test_tss_get_set) +{ + thrd_t thread1; + thrd_t thread2; + int res1 = BIOS_FOOD; + int res2 = BIOS_FOOD; + + /* degenerate test cases */ + zassert_is_null(tss_get(BIOS_FOOD)); + zassert_not_equal(thrd_success, tss_set(FORTY_TWO, (void *)BIOS_FOOD)); + zassert_is_null(tss_get(FORTY_TWO)); + + zassert_equal(thrd_success, thrd_create(&thread1, thread_fn, (void *)&forty_two)); + zassert_equal(thrd_success, thrd_create(&thread2, thread_fn, (void *)&seventy_three)); + + zassert_equal(thrd_success, thrd_join(thread1, &res1)); + zassert_equal(thrd_success, thrd_join(thread2, &res2)); + zassert_equal(FORTY_TWO, res1); + zassert_equal(SEVENTY_THREE, res2); + + zassert_equal(destroyed_values[0], FORTY_TWO); + zassert_equal(destroyed_values[1], SEVENTY_THREE); +} + +static void before(void *arg) +{ + destroyed_values[0] = 0; + destroyed_values[1] = 0; + + zassert_equal(thrd_success, tss_create(&key, destroy_fn)); +} + +static void after(void *arg) +{ + tss_delete(key); +} + +ZTEST_SUITE(libc_tss, NULL, NULL, before, after, NULL); From 4c58c6b4c4f02bbaf97e49f94397cd91f5587093 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 25 Aug 2023 08:02:46 -0400 Subject: [PATCH 3568/4498] libc: common: support for C11 call_once() Add C11 call_once() support to go with C11 threads and mutexes. Signed-off-by: Christopher Friedt --- lib/libc/common/CMakeLists.txt | 1 + lib/libc/common/include/machine/_threads.h | 9 +++++++++ lib/libc/common/include/threads.h | 2 ++ lib/libc/common/source/thrd/once.c | 16 ++++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 lib/libc/common/source/thrd/once.c diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index a99ec825a00..4b101d8b84b 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/cnd.c source/thrd/mtx.c + source/thrd/once.c source/thrd/thrd.c source/thrd/tss.c ) diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h index 2742384599c..578536ca5c6 100644 --- a/lib/libc/common/include/machine/_threads.h +++ b/lib/libc/common/include/machine/_threads.h @@ -11,10 +11,19 @@ extern "C" { #endif +#define ONCE_FLAG_INIT \ + { \ + 1, 0 \ + } + typedef int cnd_t; typedef int mtx_t; typedef int thrd_t; typedef int tss_t; +typedef struct { + int is_initialized; + int init_executed; +} once_flag; #ifdef __cplusplus } diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h index c7d23144444..b2a8c738389 100644 --- a/lib/libc/common/include/threads.h +++ b/lib/libc/common/include/threads.h @@ -74,6 +74,8 @@ void *tss_get(tss_t key); int tss_set(tss_t key, void *val); void tss_delete(tss_t key); +void call_once(once_flag *flag, void (*func)(void)); + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/thrd/once.c b/lib/libc/common/source/thrd/once.c new file mode 100644 index 00000000000..7cfd9983df8 --- /dev/null +++ b/lib/libc/common/source/thrd/once.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +void call_once(once_flag *flag, void (*func)(void)) +{ + (void)pthread_once((pthread_once_t *)flag, func); +} From 2fc19aa033c43aab45e11d0c802ebce68d3953f7 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 25 Aug 2023 08:03:33 -0400 Subject: [PATCH 3569/4498] tests: lib: c_lib: tests for C11 call_once() Add tests for C11 call_once(). Signed-off-by: Christopher Friedt --- tests/lib/c_lib/thrd/src/once.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/lib/c_lib/thrd/src/once.c diff --git a/tests/lib/c_lib/thrd/src/once.c b/tests/lib/c_lib/thrd/src/once.c new file mode 100644 index 00000000000..e239206d9b4 --- /dev/null +++ b/tests/lib/c_lib/thrd/src/once.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "thrd.h" + +#include +#include + +#include + +static size_t number_of_calls; +static once_flag flag = ONCE_FLAG_INIT; + +static void once_func(void) +{ + number_of_calls++; +} + +ZTEST(libc_once, test_call_once) +{ + zassert_equal(number_of_calls, 0); + + call_once(&flag, once_func); + call_once(&flag, once_func); + call_once(&flag, once_func); + + zassert_equal(number_of_calls, 1); +} + +ZTEST_SUITE(libc_once, NULL, NULL, NULL, NULL, NULL); From 8366c1adb48c8f03f4c78adefbe9ad3ad49fb0d4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 12:55:36 +0100 Subject: [PATCH 3570/4498] doc/hardware: Replace references to native_posix w native_sim Replace the references to native_posix with native_sim. Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- doc/hardware/emulator/index.rst | 18 +++++++++--------- doc/hardware/peripherals/rtc.rst | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/hardware/emulator/index.rst b/doc/hardware/emulator/index.rst index 23ed94a192a..686f2b60342 100644 --- a/doc/hardware/emulator/index.rst +++ b/doc/hardware/emulator/index.rst @@ -32,7 +32,7 @@ This is the ultimate application we want to run. :alt: Emulator architecture showing tests, emulators and drivers Below that are peripheral drivers, such as the AT24 EEPROM driver. We can test -peripheral drivers using an emulation driver connected via a native_posix I2C +peripheral drivers using an emulation driver connected via a native_sim I2C controller/emulator which passes I2C traffic from the AT24 driver to the AT24 simulator. @@ -41,12 +41,12 @@ tests. These require some sort of device attached to the bus, but with this, we can validate much of the driver functionality. Putting the two together, we can test the application and peripheral code -entirely on native_posix. Since we know that the I2C driver on the real hardware +entirely on native_sim. Since we know that the I2C driver on the real hardware works, we should expect the application and peripheral drivers to work on the real hardware also. Using the above framework we can test an entire application (e.g. Embedded -Controller) on native_posix using emulators for all non-chip drivers: +Controller) on native_sim using emulators for all non-chip drivers: .. figure:: img/app.png :align: center @@ -68,7 +68,7 @@ With this approach we can: All of this can work in the emulated environment or on real hardware. * Write a complex application that ties together all of these pieces and runs on - native_posix. We can develop on a host, use source-level debugging, etc. + native_sim. We can develop on a host, use source-level debugging, etc. * Transfer the application to any board which provides the required features (e.g. I2C, enough GPIOs), by adding Kconfig and devicetree fragments. @@ -110,9 +110,9 @@ device-class. The real code is shown in green, while the emulator code is shown in yellow. -The ``bus_api`` connects the BC1.2 emulators to the ``native_posix`` I2C +The ``bus_api`` connects the BC1.2 emulators to the ``native_sim`` I2C controller. The real BC1.2 drivers are unchanged and operate exactly as if there -was a physical I2C controller present in the system. The ``native_posix`` I2C +was a physical I2C controller present in the system. The ``native_sim`` I2C controller uses the ``bus_api`` to initiate register reads and writes to the emulator. @@ -164,14 +164,14 @@ Here are some examples present in Zephyr: .. zephyr-app-commands:: :app: tests/drivers/sensor/accel/ - :board: native_posix + :board: native_sim :goals: build #. Simple test of the EEPROM emulator: .. zephyr-app-commands:: :app: tests/drivers/eeprom - :board: native_posix + :board: native_sim :goals: build #. The same test has a second EEPROM which is an Atmel AT24 EEPROM driver @@ -179,7 +179,7 @@ Here are some examples present in Zephyr: .. zephyr-app-commands:: :app: tests/drivers/eeprom - :board: native_posix + :board: native_sim :goals: build API Reference diff --git a/doc/hardware/peripherals/rtc.rst b/doc/hardware/peripherals/rtc.rst index c279c7c7913..d2552d078ee 100644 --- a/doc/hardware/peripherals/rtc.rst +++ b/doc/hardware/peripherals/rtc.rst @@ -84,9 +84,9 @@ and clock calibration, these must be enabled by selecting :kconfig:option:`CONFIG_RTC_ALARM`, :kconfig:option:`CONFIG_RTC_UPDATE` and :kconfig:option:`CONFIG_RTC_CALIBRATION`. -The following examples build the test suite for the ``native_posix`` +The following examples build the test suite for the ``native_sim`` board. To build the test suite for a different board, replace the -``native_posix`` board with your board. +``native_sim`` board with your board. To build the test application with the default configuration, testing only the mandatory features, the following command can be used for @@ -95,7 +95,7 @@ reference: .. zephyr-app-commands:: :tool: west :host-os: unix - :board: native_posix + :board: native_sim :zephyr-app: tests/drivers/rtc/rtc_api :goals: build @@ -106,7 +106,7 @@ following command can be used for reference: .. zephyr-app-commands:: :tool: west :host-os: unix - :board: native_posix + :board: native_sim :zephyr-app: tests/drivers/rtc/rtc_api :goals: menuconfig @@ -115,7 +115,7 @@ Then build the test application using the following command: .. zephyr-app-commands:: :tool: west :host-os: unix - :board: native_posix + :board: native_sim :zephyr-app: tests/drivers/rtc/rtc_api :maybe-skip-config: :goals: build From 8d4d5184c6ca3fec7fbf3cf89ef168443d93e8b9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 15:24:54 +0100 Subject: [PATCH 3571/4498] tests/drivers/accel: Switch from native_posix to native_sim Switch the overlays and default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- .../sensor/accel/boards/{native_posix.conf => native_sim.conf} | 0 .../accel/boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/accel/testcase.yaml | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/accel/boards/{native_posix.conf => native_sim.conf} (100%) rename tests/drivers/sensor/accel/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/accel/boards/native_posix.conf b/tests/drivers/sensor/accel/boards/native_sim.conf similarity index 100% rename from tests/drivers/sensor/accel/boards/native_posix.conf rename to tests/drivers/sensor/accel/boards/native_sim.conf diff --git a/tests/drivers/sensor/accel/boards/native_posix.overlay b/tests/drivers/sensor/accel/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/accel/boards/native_posix.overlay rename to tests/drivers/sensor/accel/boards/native_sim.overlay diff --git a/tests/drivers/sensor/accel/testcase.yaml b/tests/drivers/sensor/accel/testcase.yaml index becbd1a03f4..fd18df000da 100644 --- a/tests/drivers/sensor/accel/testcase.yaml +++ b/tests/drivers/sensor/accel/testcase.yaml @@ -4,4 +4,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From 74d22a4b35cc9528deb7f8d9aa17b94fe3787014 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 16:50:20 +0100 Subject: [PATCH 3572/4498] tests/drivers/eeprom: Several fixes and improvements * Fix app path in documentation * Move the at24 emulator overlays to be general instead of native_posix specific * Switch default test platform from native_posix to native_sim * From build only test, exclude platforms which are used in the build and run test. Signed-off-by: Alberto Escolar Piedras --- doc/hardware/emulator/index.rst | 7 +++--- .../native_posix.conf => at2x_emul.conf} | 0 ...native_posix.overlay => at2x_emul.overlay} | 0 tests/drivers/eeprom/api/testcase.yaml | 22 +++++++++++++++++++ tests/drivers/eeprom/shell/testcase.yaml | 4 ++-- 5 files changed, 28 insertions(+), 5 deletions(-) rename tests/drivers/eeprom/api/{boards/native_posix.conf => at2x_emul.conf} (100%) rename tests/drivers/eeprom/api/{boards/native_posix.overlay => at2x_emul.overlay} (100%) diff --git a/doc/hardware/emulator/index.rst b/doc/hardware/emulator/index.rst index 686f2b60342..4373480a3e0 100644 --- a/doc/hardware/emulator/index.rst +++ b/doc/hardware/emulator/index.rst @@ -170,17 +170,18 @@ Here are some examples present in Zephyr: #. Simple test of the EEPROM emulator: .. zephyr-app-commands:: - :app: tests/drivers/eeprom + :app: tests/drivers/eeprom/api :board: native_sim :goals: build -#. The same test has a second EEPROM which is an Atmel AT24 EEPROM driver +#. The same test can be built with a second EEPROM which is an Atmel AT24 EEPROM driver connected via I2C an emulator: .. zephyr-app-commands:: - :app: tests/drivers/eeprom + :app: tests/drivers/eeprom/api :board: native_sim :goals: build + :gen-args: -DDTC_OVERLAY_FILE=at2x_emul.overlay -DOVERLAY_CONFIG=at2x_emul.conf API Reference ************* diff --git a/tests/drivers/eeprom/api/boards/native_posix.conf b/tests/drivers/eeprom/api/at2x_emul.conf similarity index 100% rename from tests/drivers/eeprom/api/boards/native_posix.conf rename to tests/drivers/eeprom/api/at2x_emul.conf diff --git a/tests/drivers/eeprom/api/boards/native_posix.overlay b/tests/drivers/eeprom/api/at2x_emul.overlay similarity index 100% rename from tests/drivers/eeprom/api/boards/native_posix.overlay rename to tests/drivers/eeprom/api/at2x_emul.overlay diff --git a/tests/drivers/eeprom/api/testcase.yaml b/tests/drivers/eeprom/api/testcase.yaml index 5735d63da65..8bc76b3e9e6 100644 --- a/tests/drivers/eeprom/api/testcase.yaml +++ b/tests/drivers/eeprom/api/testcase.yaml @@ -9,9 +9,31 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 - qemu_x86 - nucleo_l152re - nucleo_l073rz + integration_platforms: + - qemu_x86 + drivers.eeprom.api.w_at2x_emul: + # Tests overwrite EEPROM content, only run on select boards + extra_args: + - DTC_OVERLAY_FILE=at2x_emul.overlay + - OVERLAY_CONFIG=at2x_emul.conf + platform_allow: + - native_posix + - native_posix_64 + - native_sim + - native_sim_64 + integration_platforms: + - native_sim drivers.eeprom.api.build: # Build-only test for boards with EEPROMs build_only: true + platform_exclude: + - native_sim + - native_sim_64 + - qemu_x86 + - nucleo_l152re + - nucleo_l073rz diff --git a/tests/drivers/eeprom/shell/testcase.yaml b/tests/drivers/eeprom/shell/testcase.yaml index e9bdafceda5..fd78ec2c70f 100644 --- a/tests/drivers/eeprom/shell/testcase.yaml +++ b/tests/drivers/eeprom/shell/testcase.yaml @@ -1,8 +1,8 @@ tests: drivers.eeprom.shell: integration_platforms: - - native_posix - - native_posix_64 + - native_sim + - native_sim_64 tags: - drivers - eeprom From 15cbe0f890a26b9c4d98a528293f9cf32588c2b9 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 14 Nov 2023 10:37:15 +0100 Subject: [PATCH 3573/4498] tests: Remove use of CONFIG_ZTEST_NEW_API The test was enabling CONFIG_ZTEST_NEW_API which was recently removed. Signed-off-by: Emil Gydesen --- tests/drivers/uart/uart_async_rx/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/drivers/uart/uart_async_rx/prj.conf b/tests/drivers/uart/uart_async_rx/prj.conf index e10bf49c4d1..eb88c509ea7 100644 --- a/tests/drivers/uart/uart_async_rx/prj.conf +++ b/tests/drivers/uart/uart_async_rx/prj.conf @@ -1,4 +1,3 @@ CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y CONFIG_ZTRESS=y CONFIG_UART_ASYNC_RX_HELPER=y From 21505c2c283f4c8e1ceaec90ecdd0b37968cf08d Mon Sep 17 00:00:00 2001 From: Diogo Correia Date: Mon, 21 Aug 2023 16:06:09 +0100 Subject: [PATCH 3574/4498] winc1500: WIFI_DISCONNECT request doesn't raise DISCONNECT_RESULT event Internal flag (w1500_data.connecting) was not being set to false after connection. Interface raises NET_EVENT_WIFI_CONNECT_RESULT event with error status instead of NET_EVENT_WIFI_DISCONNECT_RESULT when disconnection is manually requested (NET_REQUEST_WIFI_DISCONNECT). Signed-off-by: Diogo Correia --- drivers/wifi/winc1500/wifi_winc1500.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 0a93ef0fa27..95d97fcfeaa 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -639,6 +639,7 @@ static void handle_wifi_con_state_changed(void *pvMsg) LOG_DBG("Connected (%u)", pstrWifiState->u8ErrCode); w1500_data.connected = true; + w1500_data.connecting = false; wifi_mgmt_raise_connect_result_event(w1500_data.iface, 0); break; From 16bd8a82a688bbc5c77ef84e8f17e0c7ef1f9149 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 26 Sep 2023 16:31:18 -0700 Subject: [PATCH 3575/4498] net: tls_credentials: credential_digest Adds an internal credential_digest for generating a string digest of credentials. Such digests would allow users of a prospective TLS credentials shell to verify the contents of a given credential without directly accessing those contents. Offloading the digest process to the underlying backend allows backends for which private portions are not directly accessible to be eventually supported. Signed-off-by: Georges Oates_Larsen --- subsys/net/lib/tls_credentials/CMakeLists.txt | 3 + .../net/lib/tls_credentials/tls_credentials.c | 6 ++ .../tls_credentials_digest_raw.c | 92 +++++++++++++++++++ .../tls_credentials_digest_raw.h | 20 ++++ .../tls_credentials/tls_credentials_trusted.c | 6 ++ subsys/net/lib/tls_credentials/tls_internal.h | 15 ++- 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 subsys/net/lib/tls_credentials/tls_credentials_digest_raw.c create mode 100644 subsys/net/lib/tls_credentials/tls_credentials_digest_raw.h diff --git a/subsys/net/lib/tls_credentials/CMakeLists.txt b/subsys/net/lib/tls_credentials/CMakeLists.txt index 8df3593b994..dc08debc5fa 100644 --- a/subsys/net/lib/tls_credentials/CMakeLists.txt +++ b/subsys/net/lib/tls_credentials/CMakeLists.txt @@ -1,9 +1,12 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) + zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_VOLATILE tls_credentials.c + tls_credentials_digest_raw.c ) zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE tls_credentials_trusted.c + tls_credentials_digest_raw.c ) diff --git a/subsys/net/lib/tls_credentials/tls_credentials.c b/subsys/net/lib/tls_credentials/tls_credentials.c index 133d2967160..b15397ed697 100644 --- a/subsys/net/lib/tls_credentials/tls_credentials.c +++ b/subsys/net/lib/tls_credentials/tls_credentials.c @@ -9,6 +9,7 @@ #include #include "tls_internal.h" +#include "tls_credentials_digest_raw.h" /* Global pool of credentials shared among TLS contexts. */ static struct tls_credential credentials[CONFIG_TLS_MAX_CREDENTIALS_NUMBER]; @@ -74,6 +75,11 @@ struct tls_credential *credential_next_get(sec_tag_t tag, return NULL; } +int credential_digest(struct tls_credential *credential, void *dest, size_t *len) +{ + return credential_digest_raw(credential, dest, len); +} + void credentials_lock(void) { k_mutex_lock(&credential_lock, K_FOREVER); diff --git a/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.c b/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.c new file mode 100644 index 00000000000..2013c5d52fb --- /dev/null +++ b/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +/* This file provides an (internal-use-only) credential digest function that backends storing + * raw credentials can use. + */ + +#include + +#include +#include +#include "tls_internal.h" +#include "tls_credentials_digest_raw.h" + +/* Grab mbedTLS headers if they are available so that we can check whether SHA256 is supported */ + +#if defined(CONFIG_MBEDTLS) +#if !defined(CONFIG_MBEDTLS_CFG_FILE) +#include "mbedtls/config.h" +#else +#include CONFIG_MBEDTLS_CFG_FILE +#endif /* CONFIG_MBEDTLS_CFG_FILE */ +#endif /* CONFIG_MBEDTLS */ + +#if defined(CONFIG_TINYCRYPT_SHA256) && defined(CONFIG_BASE64) + +#include +#include + +int credential_digest_raw(struct tls_credential *credential, void *dest, size_t *len) +{ + int err = 0; + size_t written = 0; + struct tc_sha256_state_struct sha_state; + uint8_t digest_buf[TC_SHA256_DIGEST_SIZE]; + + /* Compute digest. */ + (void)tc_sha256_init(&sha_state); + (void)tc_sha256_update(&sha_state, credential->buf, credential->len); + (void)tc_sha256_final(digest_buf, &sha_state); + + /* Attempt to encode digest to destination. + * Will return -ENOMEM if there is not enough space in the destination buffer. + */ + err = base64_encode(dest, *len, &written, digest_buf, sizeof(digest_buf)); + *len = err ? 0 : written; + + /* Clean up. */ + memset(&sha_state, 0, sizeof(sha_state)); + memset(digest_buf, 0, sizeof(digest_buf)); + return err; +} + +#elif defined(MBEDTLS_SHA256_C) && defined(CONFIG_BASE64) + +#include +#include + +int credential_digest_raw(struct tls_credential *credential, void *dest, size_t *len) +{ + int err = 0; + size_t written = 0; + uint8_t digest_buf[32]; + + /* Compute digest. The '0' indicates to mbedtls to use SHA256 instead of 224. */ + mbedtls_sha256(credential->buf, credential->len, digest_buf, 0); + + /* Attempt to encode digest to destination. + * Will return -ENOMEM if there is not enough space in the destination buffer. + */ + err = base64_encode(dest, *len, &written, digest_buf, sizeof(digest_buf)); + *len = err ? 0 : written; + + /* Clean up. */ + memset(digest_buf, 0, sizeof(digest_buf)); + + return err; +} + +#else + +int credential_digest_raw(struct tls_credential *credential, void *dest, size_t *len) +{ + *len = 0; + return -ENOTSUP; +} + +#endif diff --git a/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.h b/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.h new file mode 100644 index 00000000000..8b39a9cba98 --- /dev/null +++ b/subsys/net/lib/tls_credentials/tls_credentials_digest_raw.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Internal helper function for generating digests for raw credentials. + */ + +#ifndef __TLS_DIGEST_RAW_H +#define __TLS_DIGEST_RAW_H + +#include +#include "tls_internal.h" + +/* Common version of credential_digest that raw credentials backends can use. */ +int credential_digest_raw(struct tls_credential *credential, void *dest, size_t *len); + +#endif /* __TLS_DIGEST_RAW_H */ diff --git a/subsys/net/lib/tls_credentials/tls_credentials_trusted.c b/subsys/net/lib/tls_credentials/tls_credentials_trusted.c index ef105715b07..99f53ebddb4 100644 --- a/subsys/net/lib/tls_credentials/tls_credentials_trusted.c +++ b/subsys/net/lib/tls_credentials/tls_credentials_trusted.c @@ -12,6 +12,7 @@ #include #include "tls_internal.h" +#include "tls_credentials_digest_raw.h" LOG_MODULE_REGISTER(tls_credentials_trusted, CONFIG_TLS_CREDENTIALS_LOG_LEVEL); @@ -262,6 +263,11 @@ struct tls_credential *credential_next_get(sec_tag_t tag, return NULL; } +int credential_digest(struct tls_credential *credential, void *dest, size_t *len) +{ + return credential_digest_raw(credential, dest, len); +} + void credentials_lock(void) { k_mutex_lock(&credential_lock, K_FOREVER); diff --git a/subsys/net/lib/tls_credentials/tls_internal.h b/subsys/net/lib/tls_credentials/tls_internal.h index b825b6890d8..e92584d0c85 100644 --- a/subsys/net/lib/tls_credentials/tls_internal.h +++ b/subsys/net/lib/tls_credentials/tls_internal.h @@ -42,7 +42,6 @@ void credentials_unlock(void); struct tls_credential *credential_get(sec_tag_t tag, enum tls_credential_type type); - /* Function for iterating over credentials by tag. * * Note, that to assure thread safety, credential access should be locked with @@ -51,4 +50,18 @@ struct tls_credential *credential_get(sec_tag_t tag, struct tls_credential *credential_next_get(sec_tag_t tag, struct tls_credential *iter); +/* Writes a (NULL-terminated, printable) string digest of the contents of the provided credential + * to the provided destination buffer. + * + * Digest format/type is up to the tls_credentials backend in use. + * + * len pointer should be set to the amount of space available in the destination buffer prior to + * calling, and will be set to the amount written to the destination buffer after calling + * (excluding the NULL terminator). + * + * Note, that to assure thread safety, credential access should be locked with + * credentials_lock before calling this function. + */ +int credential_digest(struct tls_credential *credential, void *dest, size_t *len); + #endif /* __TLS_INTERNAL_H */ From f5d12102a04a17ea4726f40c3018a631e4315148 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 26 Sep 2023 17:18:49 -0700 Subject: [PATCH 3576/4498] net: tls_credentials: sectag iterators Add (internal) support for sectag iterating. Also officially marks negative sectag values as reserved for internal use. This will allow a prospective TLS credentials shell to iterate over all available credentials. Signed-off-by: Georges Oates_Larsen --- include/zephyr/net/tls_credentials.h | 2 ++ .../net/lib/tls_credentials/tls_credentials.c | 26 ++++++++++++++ .../tls_credentials/tls_credentials_trusted.c | 35 +++++++++++++++++++ subsys/net/lib/tls_credentials/tls_internal.h | 14 ++++++++ 4 files changed, 77 insertions(+) diff --git a/include/zephyr/net/tls_credentials.h b/include/zephyr/net/tls_credentials.h index 8436774ec65..77e2a230852 100644 --- a/include/zephyr/net/tls_credentials.h +++ b/include/zephyr/net/tls_credentials.h @@ -66,6 +66,8 @@ enum tls_credential_type { * - TLS_CREDENTIAL_PSK with TLS_CREDENTIAL_PSK_ID. * Such pairs of credentials must be assigned the same secure tag to be * correctly handled in the system. + * + * @note Negative values are reserved for internal use. */ typedef int sec_tag_t; diff --git a/subsys/net/lib/tls_credentials/tls_credentials.c b/subsys/net/lib/tls_credentials/tls_credentials.c index b15397ed697..94f4d9c5cd5 100644 --- a/subsys/net/lib/tls_credentials/tls_credentials.c +++ b/subsys/net/lib/tls_credentials/tls_credentials.c @@ -75,6 +75,32 @@ struct tls_credential *credential_next_get(sec_tag_t tag, return NULL; } +sec_tag_t credential_next_tag_get(sec_tag_t iter) +{ + int i; + sec_tag_t lowest = TLS_SEC_TAG_NONE; + + /* Scan all slots and find lowest sectag greater than iter */ + for (i = 0; i < ARRAY_SIZE(credentials); i++) { + /* Skip empty slots. */ + if (credentials[i].type == TLS_CREDENTIAL_NONE) { + continue; + } + + /* Skip any slots containing sectags not greater than iter */ + if (credentials[i].tag <= iter && iter != TLS_SEC_TAG_NONE) { + continue; + } + + /* Find the lowest of such slots */ + if (lowest == TLS_SEC_TAG_NONE || credentials[i].tag < lowest) { + lowest = credentials[i].tag; + } + } + + return lowest; +} + int credential_digest(struct tls_credential *credential, void *dest, size_t *len) { return credential_digest_raw(credential, dest, len); diff --git a/subsys/net/lib/tls_credentials/tls_credentials_trusted.c b/subsys/net/lib/tls_credentials/tls_credentials_trusted.c index 99f53ebddb4..0b77e52f558 100644 --- a/subsys/net/lib/tls_credentials/tls_credentials_trusted.c +++ b/subsys/net/lib/tls_credentials/tls_credentials_trusted.c @@ -263,6 +263,41 @@ struct tls_credential *credential_next_get(sec_tag_t tag, return NULL; } +sec_tag_t credential_next_tag_get(sec_tag_t iter) +{ + unsigned int slot; + psa_storage_uid_t uid; + sec_tag_t lowest_candidate = TLS_SEC_TAG_NONE; + sec_tag_t candidate; + + /* Scan all slots and find lowest sectag greater than iter */ + for (slot = 0; slot < CRED_MAX_SLOTS; slot++) { + uid = credentials_toc[slot]; + + /* Skip empty slots. */ + if (uid == 0) { + continue; + } + if (tls_credential_uid_to_type(uid) == TLS_CREDENTIAL_NONE) { + continue; + } + + candidate = tls_credential_uid_to_tag(uid); + + /* Skip any slots containing sectags not greater than iter */ + if (candidate <= iter && iter != TLS_SEC_TAG_NONE) { + continue; + } + + /* Find the lowest of such slots */ + if (lowest_candidate == TLS_SEC_TAG_NONE || candidate < lowest_candidate) { + lowest_candidate = candidate; + } + } + + return lowest_candidate; +} + int credential_digest(struct tls_credential *credential, void *dest, size_t *len) { return credential_digest_raw(credential, dest, len); diff --git a/subsys/net/lib/tls_credentials/tls_internal.h b/subsys/net/lib/tls_credentials/tls_internal.h index e92584d0c85..e7cfc0a1c0b 100644 --- a/subsys/net/lib/tls_credentials/tls_internal.h +++ b/subsys/net/lib/tls_credentials/tls_internal.h @@ -28,6 +28,11 @@ struct tls_credential { size_t len; }; +/* + * Special sec_tag value indicating none or invalid sec_tag. For internal use only for now. + */ +#define TLS_SEC_TAG_NONE -1 + /* Lock TLS credential access. */ void credentials_lock(void); @@ -50,6 +55,15 @@ struct tls_credential *credential_get(sec_tag_t tag, struct tls_credential *credential_next_get(sec_tag_t tag, struct tls_credential *iter); +/* Function for iterating over occupied sec tags. + * + * Returns the next occupied sec tag after the one provided, or TLS_SEC_TAG_NONE if there are no + * more. + * + * Provide TLS_SEC_TAG_NONE to start from the first available sec tag. + */ +sec_tag_t credential_next_tag_get(sec_tag_t iter); + /* Writes a (NULL-terminated, printable) string digest of the contents of the provided credential * to the provided destination buffer. * From 9f093ab7317a3290e4c6dce56f47845112a2620b Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 26 Sep 2023 16:09:30 -0700 Subject: [PATCH 3577/4498] net: tls_credetials: Add TLS Credentials shell Adds a shell interface for TLS Credentials, allowing management of credentials via the Zephyr shell Signed-off-by: Georges Oates_Larsen --- doc/connectivity/networking/api/sockets.rst | 2 + .../networking/api/system_mgmt.rst | 1 + .../networking/api/tls_credentials_shell.rst | 259 ++++++ subsys/net/lib/tls_credentials/CMakeLists.txt | 3 + subsys/net/lib/tls_credentials/Kconfig | 2 + subsys/net/lib/tls_credentials/Kconfig.shell | 35 + .../tls_credentials/tls_credentials_shell.c | 811 ++++++++++++++++++ 7 files changed, 1113 insertions(+) create mode 100644 doc/connectivity/networking/api/tls_credentials_shell.rst create mode 100644 subsys/net/lib/tls_credentials/Kconfig.shell create mode 100644 subsys/net/lib/tls_credentials/tls_credentials_shell.c diff --git a/doc/connectivity/networking/api/sockets.rst b/doc/connectivity/networking/api/sockets.rst index 3f632e3bea9..720bebeb820 100644 --- a/doc/connectivity/networking/api/sockets.rst +++ b/doc/connectivity/networking/api/sockets.rst @@ -73,6 +73,8 @@ To enable secure sockets, set the :kconfig:option:`CONFIG_NET_SOCKETS_SOCKOPT_TL option. To enable DTLS support, use :kconfig:option:`CONFIG_NET_SOCKETS_ENABLE_DTLS` option. +.. _sockets_tls_credentials_subsys: + TLS credentials subsystem ========================= diff --git a/doc/connectivity/networking/api/system_mgmt.rst b/doc/connectivity/networking/api/system_mgmt.rst index 59aab16d3b7..a09ed2b2787 100644 --- a/doc/connectivity/networking/api/system_mgmt.rst +++ b/doc/connectivity/networking/api/system_mgmt.rst @@ -18,3 +18,4 @@ Network System Management traffic-class.rst net_pkt_filter.rst net_shell.rst + tls_credentials_shell.rst diff --git a/doc/connectivity/networking/api/tls_credentials_shell.rst b/doc/connectivity/networking/api/tls_credentials_shell.rst new file mode 100644 index 00000000000..69749a8f972 --- /dev/null +++ b/doc/connectivity/networking/api/tls_credentials_shell.rst @@ -0,0 +1,259 @@ +.. _tls_credentials_shell: + +TLS Credentials Shell +##################### + +The TLS Credentials shell provides a command-line interface for managing installed TLS credentials. + +Commands +******** + +.. _tls_credentials_shell_buf_cred: + +Buffer Credential (``buf``) +=========================== + +Buffer data incrementaly into the credential buffer so that it can be added using the :ref:`tls_credentials_shell_add_cred` command. + +Alternatively, clear the credential buffer. + +Usage +----- + +To append ```` to the credential buffer, use: + +.. code-block:: shell + + cred buf + +Use this as many times as needed to load the full credential into the credential buffer, then use the :ref:`tls_credentials_shell_add_cred` command to store it. + +To clear the credential buffer, use: + +.. code-block:: shell + + cred buf clear + +Arguments +--------- + +.. csv-table:: + :header: "Argument", "Description" + :widths: 15 85 + + "````", "Text data to be appended to credential buffer. It can be either text, or base64-encoded binary. See :ref:`tls_credentials_shell_add_cred` and :ref:`tls_credentials_shell_data_formats` for details." + +.. _tls_credentials_shell_add_cred: + +Add Credential (``add``) +========================= + +Add a TLS credential to the TLS Credential store. + +Credential contents can be provided in-line with the call to ``cred add``, or will otherwise be sourced from the credential buffer. + +Usage +----- + +To add a TLS credential using the data from the credential buffer, use: + +.. code-block:: shell + + cred add + +To add a TLS credential using data provided with the same command, use: + +.. code-block:: shell + + cred add + + +Arguments +--------- + +.. csv-table:: + :header: "Argument", "Description" + :widths: 15 85 + + "````", "The sectag to use for the new credential. Can be any non-negative integer." + "````", "The type of credential to add. See :ref:`tls_credentials_shell_cred_types` for valid values." + "````", "Reserved. Must always be ``DEFAULT`` (case-insensitive)." + "````", "Specifies the storage format of the provided credential. See :ref:`tls_credentials_shell_data_formats` for valid values." + "````", "If provided, this argument will be used as the credential data, instead of any data in the credential buffer. Can be either text, or base64-encoded binary." + +.. _tls_credentials_shell_del_cred: + +Delete Credential (``del``) +=========================== + +Delete a specified credential from the credential store. + +Usage +----- + +To delete a credential matching a specified sectag and credential type (if it exists), use: + +.. code-block:: shell + + cred del + +Arguments +--------- + +.. csv-table:: + :header: "Argument", "Description" + :widths: 15 85 + + "````", "The sectag of the credential to delete. Can be any non-negative integer." + "````", "The type of credential to delete. See :ref:`tls_credentials_shell_cred_types` for valid values." + +.. _tls_credentials_shell_get_cred: + +Get Credential Contents (``get``) +================================= + +Retrieve and print the contents of a specified credential. + +Usage +----- + +To retrieve and print a credential matching a specified sectag and credential type (if it exists), use: + +.. code-block:: shell + + cred get + +Arguments +--------- + +.. csv-table:: + :header: "Argument", "Description" + :widths: 15 85 + + "````", "The sectag of the credential to get. Can be any non-negative integer." + "````", "The type of credential to get. See :ref:`tls_credentials_shell_cred_types` for valid values." + "````", "Specifies the retrieval format for the provided credential. See :ref:`tls_credentials_shell_data_formats` for valid values." + +.. _tls_credentials_shell_list_cred: + +List Credentials (``list``) +=========================== + +List TLS credentials in the credential store. + +Usage +----- + +To list all available credentials, use: + +.. code-block:: shell + + cred list + +To list all credentials with a specified sectag, use: + +.. code-block:: shell + + cred list + +To list all credentials with a specified credential type, use: + +.. code-block:: shell + + cred list any + +To list all credentials with a specified credential type and sectag, use: + +.. code-block:: shell + + cred list + + +Arguments +--------- + +.. csv-table:: + :header: "Argument", "Description" + :widths: 15 85 + + "````", "Optional. If provided, only list credentials with this sectag. Pass ``any`` or omit to allow any sectag. Otherwise, can be any non-negative integer." + "````", "Optional. If provided, only list credentials with this credential type. Pass ``any`` or omit to allow any credential type. Otherwise, see :ref:`tls_credentials_shell_cred_types` for valid values." + + +Output +------ + +The command outputs all matching credentials in the following (CSV-compliant) format: + +.. code-block:: shell + + ,,, + +Where: + +.. csv-table:: + :header: "Symbol", "Value" + :widths: 15 85 + + "````", "The sectag of the listed credential. A non-negative integer." + "````", "Credential type short-code (see :ref:`tls_credentials_shell_cred_types` for details) of the listed credential." + "````", "A string digest representing the credential contents. The exact nature of this digest may vary depending on credentials storage backend, but currently for all backends this is a base64 encoded SHA256 hash of the raw credential contents (so different storage formats for essentially identical credentials will have different digests)." + "````", "Status code indicating success or failure with generating a digest of the listed credential. 0 if successful, negative error code specific to the storage backend otherwise. Lines for which status is not zero will be printed with error formatting." + +After the list is printed, a final summary of the found credentials will be printed in the form: + +.. code-block:: shell + + credentials found. + +Where `` is the number of credentials found, and is zero if none are found. + +.. _tls_credentials_shell_cred_types: + +Credential Types +**************** + +The following keywords (case-insensitive) may be used to specify a credential type: + +.. csv-table:: + :header: "Keyword(s)", "Meaning" + :widths: 15 85 + + "``CA_CERT``, ``CA``", "A trusted CA certificate." + "``SERVER_CERT``, ``SELF_CERT``, ``CLIENT_CERT``, ``CLIENT``, ``SELF``, ``SERV``", "Self or server certificate." + "``PRIVATE_KEY``, ``PK``", "A private key." + "``PRE_SHARED_KEY``, ``PSK``", "A pre-shared key." + "``PRE_SHARED_KEY_ID``, ``PSK_ID``", "ID for pre-shared key." + +.. _tls_credentials_shell_data_formats: + +Storage/Retrieval Formats +************************* + +The :ref:`tls_credentials ` module treats stored credentials as arbitrary binary buffers. + +For convenience, the TLS credentials shell offers four formats for providing and later retrieving these buffers using the shell. + +These formats and their (case-insensitive) keywords are as follows: + +.. csv-table:: + :header: "Keyword", "Meaning", "Behavior during storage (``cred add``)", "Behavior during retrieval (``cred get``)" + :widths: 3, 32, 34, 34 + + "``BIN``", "Credential is handled by shell as base64 and stored without NULL termination.", "Data entered into shell will be decoded from base64 into raw binary before storage. No terminator will be appended.", "Stored data will be encoded into base64 before being printed." + "``BINT``", "Credential is handled by shell as base64 and stored with NULL termination.", "Data entered into shell will be decoded from base64 into raw binary and a NULL terminator will be appended before storage.", "NULL terminator will be truncated from stored data before said data is encoded into base64 and then printed." + "``STR``", "Credential is handled by shell as literal string and stored without NULL termination.", "Text data entered into shell will be passed into storage as-written, without a NULL terminator.", "Stored data will be printed as text. Non-printable characters will be printed as ``?``" + "``STRT``", "Credential is handled by shell as literal string and stored with NULL-termination.", "Text data entered into shell will be passed into storage as-written, with a NULL terminator.", "NULL terminator will be truncated from stored data before said data is printed as text. Non-printable characters will be printed as ``?``" + +The ``BIN`` format can be used to install credentials of any type, since base64 can be used to encode any concievable binary buffer. +The remaining three formats are provided for convenience in special use-cases. + +For example: + +- To install printable pre-shared-keys, use ``STR`` to enter the PSK without first encoding it. + This ensures it is stored without a NULL terminator. +- To install DER-formatted X.509 certificates (or other raw-binary credentials, such as non-printable PSKs) base64-encode the binary and use the ``BIN`` format. +- To install PEM-formatted X.509 certificates or certificate chains, base64 encode the full PEM string (including new-lines and ``----BEGIN X ----`` / ``----END X----`` markers), and then use the ``BINT`` format to make sure the stored string is NULL-terminated. + This is required because Zephyr does not support multi-line strings in the shell. + Otherwise, the ``STRT`` format could be used for this purpose without base64 encoding. + It is possible to use ``BIN`` instead if you manually encode a NULL terminator into the base64. diff --git a/subsys/net/lib/tls_credentials/CMakeLists.txt b/subsys/net/lib/tls_credentials/CMakeLists.txt index dc08debc5fa..8acb4a5f4f1 100644 --- a/subsys/net/lib/tls_credentials/CMakeLists.txt +++ b/subsys/net/lib/tls_credentials/CMakeLists.txt @@ -10,3 +10,6 @@ zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE tls_credentials_trusted.c tls_credentials_digest_raw.c ) +zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_SHELL + tls_credentials_shell.c +) diff --git a/subsys/net/lib/tls_credentials/Kconfig b/subsys/net/lib/tls_credentials/Kconfig index 94ecc8287c6..58ec0949d47 100644 --- a/subsys/net/lib/tls_credentials/Kconfig +++ b/subsys/net/lib/tls_credentials/Kconfig @@ -54,4 +54,6 @@ config TLS_CREDENTIAL_FILENAMES This option is currently only available for secure socket offload devices. +source "subsys/net/lib/tls_credentials/Kconfig.shell" + endif # TLS_CREDENTIALS diff --git a/subsys/net/lib/tls_credentials/Kconfig.shell b/subsys/net/lib/tls_credentials/Kconfig.shell new file mode 100644 index 00000000000..3e20f6e7717 --- /dev/null +++ b/subsys/net/lib/tls_credentials/Kconfig.shell @@ -0,0 +1,35 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menuconfig TLS_CREDENTIALS_SHELL + bool "TLS credentials management shell" + depends on TLS_CREDENTIALS + depends on SHELL + depends on BASE64 + help + Enable shell commands to manage TLS credentials. + +if TLS_CREDENTIALS_SHELL + +config TLS_CREDENTIALS_SHELL_CRED_BUF_SIZE + int "Size of buffer used for storing and retrieving credentials, measured in bytes." + default 1024 + help + The amount of preallocated buffer (in bytes) used for storing and retrieving credentials. + +config TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH + int "Credential output line width (characters)" + default 32 + help + This setting specifies how long (in characters) contiguous lines of base64 credential + output should be. Must be a multiple of 4. Applies only to ??? mode. + +config TLS_CREDENTIALS_SHELL_DIGEST_BUF_SIZE + int "Buffer for generating credentials digests" + default 48 + help + The amount of preallocated buffer (in bytes) for temporarily storing credential digests. + + Also used to print error messages if digest generation fails. + +endif # TLS_CREDENTIALS_SHELL diff --git a/subsys/net/lib/tls_credentials/tls_credentials_shell.c b/subsys/net/lib/tls_credentials/tls_credentials_shell.c new file mode 100644 index 00000000000..1b06520466b --- /dev/null +++ b/subsys/net/lib/tls_credentials/tls_credentials_shell.c @@ -0,0 +1,811 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(tls_credentials_shell, CONFIG_TLS_CREDENTIALS_LOG_LEVEL); + +#include +#include +#include +#include +#include "tls_internal.h" +#include +#include +#include + +enum cred_storage_fmt { + /* Credential is stored as a string and will be passed between the shell and storage + * unmodified. + */ + CRED_STORAGE_FMT_STRING, + + /* Credential is stored as raw binary, and is parsed from base64 before storage and encoded + * back into base64 when retrieved via the shell. + */ + CRED_STORAGE_FMT_BINARY, +}; + +struct cred_type_string { + char *name; + enum tls_credential_type type; +}; + +/* The first entry in each credential type group will be used for human-readable shell + * output. The last will be used for compact shell output. The rest are accepted synonyms. + */ +static const struct cred_type_string type_strings[] = { + {"CA_CERT", TLS_CREDENTIAL_CA_CERTIFICATE}, + {"CA", TLS_CREDENTIAL_CA_CERTIFICATE}, + + {"SERVER_CERT", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + {"CLIENT_CERT", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + {"SELF_CERT", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + {"SELF", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + {"CLIENT", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + {"SERV", TLS_CREDENTIAL_SERVER_CERTIFICATE}, + + {"PRIVATE_KEY", TLS_CREDENTIAL_PRIVATE_KEY}, + {"PK", TLS_CREDENTIAL_PRIVATE_KEY}, + + {"PRE_SHARED_KEY", TLS_CREDENTIAL_PSK}, + {"PSK", TLS_CREDENTIAL_PSK}, + + {"PRE_SHARED_KEY_ID", TLS_CREDENTIAL_PSK_ID}, + {"PSK_ID", TLS_CREDENTIAL_PSK_ID} +}; + +#define ANY_KEYWORD "any" + +/* This is so that we can output base64 in chunks of this length if necessary */ +BUILD_ASSERT( + (CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH % 4) == 0, + "CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH must be a multiple of 4." +); + +/* Output buffers used for printing credentials and digests. + * One extra byte included for NULL termination. + */ +static char cred_out_buf[CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH + 1]; +static char cred_digest_buf[CONFIG_TLS_CREDENTIALS_SHELL_DIGEST_BUF_SIZE + 1]; + +/* Internal buffer used for storing and retrieving credentials. + * +1 byte for potential NULL termination. + */ +static char cred_buf[CONFIG_TLS_CREDENTIALS_SHELL_CRED_BUF_SIZE + 1]; +static size_t cred_written; + +/* Some backends (namely, the volatile backend) store a reference rather than a copy of passed-in + * credentials. For these backends, we need to copy incoming credentials onto the heap before + * attempting to store them. + * + * Since the backend in use is determined at build time by KConfig, so is this behavior. + * If multi/dynamic-backend support is ever added, this will need to be updated. + */ +#define COPY_CREDENTIALS_TO_HEAP CONFIG_TLS_CREDENTIALS_BACKEND_VOLATILE + +/* Used to track credentials that have been copied permanently to the heap, in case they are + * ever deleted and need to be freed. + */ +static void *cred_refs[CONFIG_TLS_MAX_CREDENTIALS_NUMBER]; + +/* Find an empty slot in the cred_refs array, or return -1 if none exists. + * Pass NULL to find an unused slot. + */ +static int find_ref_slot(const void *const cred) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cred_refs); i++) { + if (cred_refs[i] == cred) { + return i; + } + } + + return -1; +} + +/* Helpers */ + +/* Filter out non-printable characters from a passed-in string of known length */ +static int filter_nonprint(char *buf, size_t len, char inval) +{ + int i; + int ret = 0; + + for (i = 0; i < len; i++) { + if (!isprint((int)buf[i])) { + buf[i] = inval; + ret = -EINVAL; + } + } + + return ret; +} + +/* Verify that a provided string consists only of the characters 0-9*/ +static bool check_numeric(char *str) +{ + int i; + int len = strlen(str); + + for (i = 0; i < len; i++) { + if (!isdigit((int)str[i])) { + return false; + } + } + + return true; +} + +/* Clear the credential write buffer, returns true if anything was actually cleared. */ +static bool cred_buf_clear(void) +{ + bool cleared = cred_written != 0; + + (void)memset(cred_buf, 0, sizeof(cred_buf)); + cred_written = 0; + + return cleared; +} + +/* Parse a (possibly incomplete) chunk into the credential buffer */ +static int cred_buf_write(char *chunk) +{ + char *writehead = cred_buf + cred_written; + size_t chunk_len = strlen(chunk); + + /* Verify that there is room for the incoming chunk */ + if ((writehead + chunk_len) >= (cred_buf + sizeof(cred_buf) - 1)) { + return -ENOMEM; + } + + /* Append chunk to the credential buffer. + * Deliberately do not copy NULL terminator. + */ + memcpy(writehead, chunk, chunk_len); + cred_written += chunk_len; + + return chunk_len; +} + +/* Get the human-readable name of a TLS credential type */ +static const char *cred_type_name(enum tls_credential_type type) +{ + /* Scan over predefined type strings, and return the name + * of the first one of matching type. + */ + for (int i = 0; i < ARRAY_SIZE(type_strings); i++) { + if (type_strings[i].type == type) { + return type_strings[i].name; + } + } + + /* No matches found, it's invalid. */ + return "INVALID"; +} + +/* Get the compact name of a TLS credential type*/ +static const char *cred_type_name_compact(enum tls_credential_type type) +{ + /* Scan over predefined type strings, and return the name + * of the last one of matching type. + */ + for (int i = ARRAY_SIZE(type_strings) - 1; i >= 0; i--) { + if (type_strings[i].type == type) { + return type_strings[i].name; + } + } + + /* No matches found, it's invalid. */ + return "INV"; +} + +/* Shell interface routines */ + +/* Attempt to parse a command line argument into a sectag. + * TLS_SEC_TAG_NONE is returned if ANY_KEYWORD is provided. + */ +static int shell_parse_cred_sectag(const struct shell *sh, char *arg, sec_tag_t *out, + bool allow_any) +{ + unsigned long sectag_value; + int err = 0; + + /* Check for "ANY" special keyword if desired. */ + if (allow_any && strcasecmp(arg, ANY_KEYWORD) == 0) { + *out = TLS_SEC_TAG_NONE; + return 0; + } + + /* Otherwise, verify that the sectag is purely numeric */ + if (!check_numeric(arg)) { + err = -EINVAL; + goto error; + } + + /* Use strtoul because it has nicer validation features than atoi */ + sectag_value = shell_strtoul(arg, 10, &err); + + if (!err) { + *out = (sec_tag_t)sectag_value; + return 0; + } + +error: + shell_fprintf(sh, SHELL_ERROR, "%s is not a valid sectag.\n", arg); + return err; +} + +/* Attempt to parse a command line argument into a credential type. + * TLS_CREDENTIAL_NONE is returned if ANY_KEYWORD is provided. + */ +static int shell_parse_cred_type(const struct shell *sh, char *arg, enum tls_credential_type *out, + bool allow_any) +{ + /* Check for "ANY" special keyword if desired. */ + if (allow_any && strcasecmp(arg, ANY_KEYWORD) == 0) { + *out = TLS_CREDENTIAL_NONE; + return 0; + } + + /* Otherwise, scan over predefined type strings, and return the corresponding + * credential type if one is found + */ + for (int i = 0; i < ARRAY_SIZE(type_strings); i++) { + if (strcasecmp(arg, type_strings[i].name) == 0) { + *out = type_strings[i].type; + return 0; + } + } + + /* No matches found, it's invalid. */ + shell_fprintf(sh, SHELL_ERROR, "%s is not a valid credential type.\n", arg); + + return -EINVAL; +} + +/* Parse a backend specifier argument + * Right now, only a single backend is supported, so this is serving simply as a reserved argument. + * As such, the only valid input is "default" + */ +static int shell_parse_cred_backend(const struct shell *sh, char *arg) +{ + if (strcasecmp(arg, "default") == 0) { + return 0; + } + + shell_fprintf(sh, SHELL_ERROR, "%s is not a valid backend.\n", arg); + + return -EINVAL; +} + +/* Parse an input type specifier */ +static int shell_parse_cred_storage_format(const struct shell *sh, char *arg, + enum cred_storage_fmt *out, bool *terminated) +{ + if (strcasecmp(arg, "bin") == 0) { + *out = CRED_STORAGE_FMT_BINARY; + *terminated = false; + return 0; + } + + if (strcasecmp(arg, "bint") == 0) { + *out = CRED_STORAGE_FMT_BINARY; + *terminated = true; + return 0; + } + + if (strcasecmp(arg, "str") == 0) { + *out = CRED_STORAGE_FMT_STRING; + *terminated = false; + return 0; + } + + if (strcasecmp(arg, "strt") == 0) { + *out = CRED_STORAGE_FMT_STRING; + *terminated = true; + return 0; + } + + shell_fprintf(sh, SHELL_ERROR, "%s is not a valid storage format.\n", arg); + + return -EINVAL; +} + +/* Clear credential buffer, with shell feedback */ +static void shell_clear_cred_buf(const struct shell *sh) +{ + /* We will only print a message if some data was actually wiped. */ + if (cred_buf_clear()) { + shell_fprintf(sh, SHELL_NORMAL, "Credential buffer cleared.\n"); + } +} + +/* Write data into the credential buffer, with shell feedback. */ +static int shell_write_cred_buf(const struct shell *sh, char *chunk) +{ + int res = cred_buf_write(chunk); + + /* Report results. */ + + if (res == -ENOMEM) { + shell_fprintf(sh, SHELL_ERROR, "Not enough room in credential buffer for " + "provided data. Increase " + "CONFIG_TLS_CREDENTIALS_SHELL_CRED_BUF_SIZE.\n"); + shell_clear_cred_buf(sh); + return -ENOMEM; + } + + shell_fprintf(sh, SHELL_NORMAL, "Stored %d bytes.\n", res); + + return 0; +} + +/* Adds a credential to the credential store */ +static int tls_cred_cmd_add(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + sec_tag_t sectag; + enum cred_storage_fmt format; + bool terminated; + enum tls_credential_type type; + void *cred_copy = NULL; + void *cred_chosen = NULL; + bool keep_copy = false; + int ref_slot = -1; + + /* Lock credentials so that we can interact with them directly. + * Mainly this is required by credential_get. + */ + + credentials_lock(); + + err = shell_parse_cred_sectag(sh, argv[1], §ag, false); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_type(sh, argv[2], &type, false); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_backend(sh, argv[3]); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_storage_format(sh, argv[4], &format, &terminated); + if (err) { + goto cleanup; + } + + if (argc == 6) { + /* Credential was passed, clear credential buffer and then use the passed-in + * credential. + */ + shell_clear_cred_buf(sh); + err = shell_write_cred_buf(sh, argv[5]); + if (err) { + goto cleanup; + } + } + + /* Make sure the credential buffer isn't empty. */ + if (cred_written == 0) { + shell_fprintf(sh, SHELL_ERROR, "Please provide a credential to add.\n"); + err = -ENOENT; + goto cleanup; + } + + /* Check whether a credential of this type and sectag already exists. */ + if (credential_get(sectag, type)) { + shell_fprintf(sh, SHELL_ERROR, "TLS credential with sectag %d and type %s " + "already exists.\n", sectag, cred_type_name(type)); + err = -EEXIST; + goto cleanup; + } + + /* If binary format was specified, decode from base64. */ + if (format == CRED_STORAGE_FMT_BINARY) { + /* base64_decode can handle in-place operation. + * Pass &cred_written as olen so that it is updated to match the size of the base64 + * encoding. + * + * We use sizeof(cred_buf) - 1 since we want to keep room fors a NULL terminator. + * Though, technically, this is not actually needed since the output of + * base64_decode is always shorter than its input. + */ + err = base64_decode(cred_buf, sizeof(cred_buf) - 1, &cred_written, + cred_buf, cred_written); + if (err) { + shell_fprintf(sh, SHELL_ERROR, "Could not decode input from base64, " + "error: %d\n", err); + err = -EINVAL; + goto cleanup; + } + } + + /* If NULL termination was requested, append one. + * We are always guaranteed to have room in the buffer for this. + */ + if (terminated) { + cred_buf[cred_written] = 0; + cred_written += 1; + } + + /* Default to using cred_buf directly. */ + cred_chosen = cred_buf; + + /* If the currently active TLS Credentials backend stores credentials by reference, + * copy the incoming credentials off to the heap, and then use this copy instead. + */ + if (IS_ENABLED(COPY_CREDENTIALS_TO_HEAP)) { + /* Before copying the credential to heap, make sure we are able to store a + * reference to it so that it can be freed if the credential is ever deleted. + */ + + ref_slot = find_ref_slot(NULL); + + if (ref_slot < 0) { + shell_fprintf(sh, SHELL_ERROR, "No reference slot available, cannot copy " + "credential to heap. Credential will not be " + "stored\n"); + err = -ENOMEM; + goto cleanup; + } + + cred_copy = k_malloc(cred_written); + if (!cred_copy) { + shell_fprintf(sh, SHELL_ERROR, "Not enough heap for TLS credential of " + "size %d.\n", cred_written); + err = -ENOMEM; + goto cleanup; + } + + memset(cred_copy, 0, cred_written); + memcpy(cred_copy, cred_buf, cred_written); + + shell_fprintf(sh, SHELL_WARNING, "Credential has been copied to heap. Memory will " + "be leaked if this credential is deleted without " + "using the shell.\n"); + + cred_chosen = cred_copy; + } + + /* Finally, store the credential in whatever credentials backend is active. */ + err = tls_credential_add(sectag, type, cred_chosen, cred_written); + if (err) { + shell_fprintf(sh, SHELL_ERROR, "Failed to add TLS credential with sectag %d and " + "type %s. Error: %d\n.", sectag, + cred_type_name(type), err); + goto cleanup; + } + + /* Do not free the copied key during cleanup, since it was successfully written. */ + keep_copy = true; + + shell_fprintf(sh, SHELL_NORMAL, "Added TLS credential of type %s, sectag %d, and length %d " + "bytes.\n", cred_type_name(type), sectag, cred_written); + +cleanup: + /* Unlock credentials since we are done interacting with internal state. */ + credentials_unlock(); + + /* We are also done with the credentials buffer, so clear it for good measure. */ + shell_clear_cred_buf(sh); + + /* If we copied the credential, make sure it is eventually freed. */ + if (cred_copy) { + if (keep_copy) { + /* If the credential was successfully stored, keep a reference to it in case + * it is ever deleted and needs to be freed. + */ + cred_refs[ref_slot] = cred_copy; + } else { + /* Otherwise, clear and free it immediately */ + memset(cred_copy, 0, cred_written); + (void)k_free(cred_copy); + } + } + + return err; +} + +/* Buffers credential data into the credential buffer. */ +static int tls_cred_cmd_buf(const struct shell *sh, size_t argc, char *argv[]) +{ + /* If the "clear" keyword is provided, clear the buffer rather than write to it. */ + if (strcmp(argv[1], "clear") == 0) { + shell_clear_cred_buf(sh); + return 0; + } + + /* Otherwise, assume provided arg is base64 and attempt to write it into the credential + * buffer. + */ + return shell_write_cred_buf(sh, argv[1]); +} + +/* Deletes a credential from the credential store */ +static int tls_cred_cmd_del(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + sec_tag_t sectag; + enum tls_credential_type type; + struct tls_credential *cred = NULL; + int ref_slot = -1; + + /* Lock credentials so that we can safely use internal access functions. */ + credentials_lock(); + + err = shell_parse_cred_sectag(sh, argv[1], §ag, false); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_type(sh, argv[2], &type, false); + if (err) { + goto cleanup; + } + + /* Check whether a credential of this type and sectag actually exists. */ + cred = credential_get(sectag, type); + if (!cred) { + shell_fprintf(sh, SHELL_ERROR, "There is no TLS credential with sectag %d and " + "type %s.\n", sectag, cred_type_name(type)); + err = -ENOENT; + goto cleanup; + } + + ref_slot = find_ref_slot(cred->buf); + if (ref_slot >= 0) { + /* This was a credential we copied to heap. Clear and free it. */ + memset((void *)cred_buf, 0, cred->len); + k_free((void *)cred_buf); + cred->buf = NULL; + + /* Clear the reference slot so it can be used again. */ + cred_refs[ref_slot] = NULL; + + shell_fprintf(sh, SHELL_NORMAL, "Stored credential freed.\n"); + } + + /* Attempt to delete. */ + err = tls_credential_delete(sectag, type); + if (err) { + shell_fprintf(sh, SHELL_ERROR, "Deleting TLS credential with sectag %d and " + "type %s failed with error: %d.\n", sectag, + cred_type_name(type), err); + goto cleanup; + } + + shell_fprintf(sh, SHELL_NORMAL, "Deleted TLS credential with sectag %d and type %s.\n", + sectag, cred_type_name(type)); + +cleanup: + /* Unlock credentials since we are done interacting with internal state. */ + credentials_unlock(); + + return err; +} + +/* Retrieves credential data from credential store. */ +static int tls_cred_cmd_get(const struct shell *sh, size_t argc, char *argv[]) +{ + int i; + int remaining; + int written; + int err = 0; + size_t cred_len; + sec_tag_t sectag; + enum tls_credential_type type; + enum cred_storage_fmt format; + bool terminated; + + size_t line_length; + + /* Lock credentials so that we can safely use internal access functions. */ + credentials_lock(); + + err = shell_parse_cred_sectag(sh, argv[1], §ag, false); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_type(sh, argv[2], &type, false); + if (err) { + goto cleanup; + } + + err = shell_parse_cred_storage_format(sh, argv[3], &format, &terminated); + if (err) { + goto cleanup; + } + + line_length = CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH; + + /* If the credential is stored as binary, adjust line length so that the output + * base64 has width CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH + */ + if (format == CRED_STORAGE_FMT_BINARY) { + line_length = CONFIG_TLS_CREDENTIALS_SHELL_CRED_OUTPUT_WIDTH / 4 * 3; + } + + /* Check whether a credential of this type and sectag actually exists. */ + if (!credential_get(sectag, type)) { + shell_fprintf(sh, SHELL_ERROR, "There is no TLS credential with sectag %d and " + "type %s.\n", sectag, cred_type_name(type)); + err = -ENOENT; + goto cleanup; + } + + /* Clear the credential buffer before use. */ + shell_clear_cred_buf(sh); + + /* Load the credential into the credential buffer */ + cred_len = sizeof(cred_buf); + err = tls_credential_get(sectag, type, cred_buf, &cred_len); + if (err == -EFBIG) { + shell_fprintf(sh, SHELL_ERROR, "Not enough room in the credential buffer to " + "retrieve credential with sectag %d and type %s. " + "Increase TLS_CREDENTIALS_SHELL_MAX_CRED_LEN.\n", + sectag, cred_type_name(type)); + err = -ENOMEM; + goto cleanup; + } else if (err) { + shell_fprintf(sh, SHELL_ERROR, "Could not retrieve TLS credential with sectag %d " + "and type %s due to error: %d.\n", sectag, + cred_type_name(type), err); + goto cleanup; + } + + /* Update the credential buffer writehead. + * Keeping this accurate ensures that a "Buffer Cleared" message is eventually printed. + */ + cred_written = cred_len; + + /* If the stored credential is NULL-terminated, do not include NULL termination in output */ + if (terminated) { + if (cred_buf[cred_written - 1] != 0) { + shell_fprintf(sh, SHELL_ERROR, "The stored credential isn't " + "NULL-terminated, but a NULL-terminated " + "format was specified.\n"); + + err = -EINVAL; + goto cleanup; + } + cred_written -= 1; + } + + /* Print the credential out in lines. */ + for (i = 0; i < cred_written; i += line_length) { + /* Print either a full line, or however much credential data is left. */ + remaining = MIN(line_length, cred_written - i); + + /* Read out a line of data. */ + memset(cred_out_buf, 0, sizeof(cred_out_buf)); + if (format == CRED_STORAGE_FMT_BINARY) { + (void)base64_encode(cred_out_buf, sizeof(cred_out_buf), + &written, &cred_buf[i], remaining); + } else if (format == CRED_STORAGE_FMT_STRING) { + memcpy(cred_out_buf, &cred_buf[i], remaining); + if (filter_nonprint(cred_out_buf, remaining, '?')) { + err = -EBADF; + } + } + + /* Print the line. */ + shell_fprintf(sh, SHELL_NORMAL, "%s\n", cred_out_buf); + } + + if (err) { + shell_fprintf(sh, SHELL_WARNING, "Non-printable characters were included in the " + "output and filtered. Have you selected the " + "correct storage format?\n"); + } + +cleanup: + /* Unlock credentials since we are done interacting with internal state. */ + credentials_unlock(); + + /* Clear buffers when done. */ + memset(cred_out_buf, 0, sizeof(cred_out_buf)); + shell_clear_cred_buf(sh); + + return err; +} + +/* Lists credentials in credential store. */ +static int tls_cred_cmd_list(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + size_t digest_size; + sec_tag_t sectag = TLS_SEC_TAG_NONE; + struct tls_credential *cred; + int count = 0; + + sec_tag_t sectag_filter = TLS_SEC_TAG_NONE; + enum tls_credential_type type_filter = TLS_CREDENTIAL_NONE; + + /* Lock credentials so that we can safely use internal access functions. */ + credentials_lock(); + + /* Sectag filter was provided, parse it. */ + if (argc >= 2) { + err = shell_parse_cred_sectag(sh, argv[1], §ag_filter, true); + if (err) { + goto cleanup; + } + } + + /* Credential type filter was provided, parse it. */ + if (argc >= 3) { + err = shell_parse_cred_type(sh, argv[2], &type_filter, true); + if (err) { + goto cleanup; + } + } + + /* Scan through all occupied sectags */ + while ((sectag = credential_next_tag_get(sectag)) != TLS_SEC_TAG_NONE) { + /* Filter by sectag if requested. */ + if (sectag_filter != TLS_SEC_TAG_NONE && sectag != sectag_filter) { + continue; + } + + cred = NULL; + /* Scan through all credentials within each sectag */ + while ((cred = credential_next_get(sectag, cred)) != NULL) { + /* Filter by credential type if requested. */ + if (type_filter != TLS_CREDENTIAL_NONE && cred->type != type_filter) { + continue; + } + count++; + + /* Generate a digest of the credential */ + memset(cred_digest_buf, 0, sizeof(cred_digest_buf)); + strcpy(cred_digest_buf, "N/A"); + digest_size = sizeof(cred_digest_buf); + err = credential_digest(cred, cred_digest_buf, &digest_size); + + /* Print digest and sectag/type info */ + shell_fprintf(sh, err ? SHELL_ERROR : SHELL_NORMAL, "%d,%s,%s,%d\n", + sectag, cred_type_name_compact(cred->type), + err ? "ERROR" : cred_digest_buf, err); + + err = 0; + } + }; + + shell_fprintf(sh, SHELL_NORMAL, "%d credentials found.\n", count); + +cleanup: + /* Unlock credentials since we are done interacting with internal state. */ + credentials_unlock(); + + /* Clear digest buffer afterwards for good measure. */ + memset(cred_digest_buf, 0, sizeof(cred_digest_buf)); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(tls_cred_cmds, + SHELL_CMD_ARG(buf, NULL, "Buffer in credential data so it can be added.", + tls_cred_cmd_buf, 2, 0), + SHELL_CMD_ARG(add, NULL, "Add a TLS credential.", + tls_cred_cmd_add, 5, 1), + SHELL_CMD_ARG(del, NULL, "Delete a TLS credential.", + tls_cred_cmd_del, 3, 0), + SHELL_CMD_ARG(get, NULL, "Retrieve the contents of a TLS credential", + tls_cred_cmd_get, 4, 0), + SHELL_CMD_ARG(list, NULL, "List stored TLS credentials, optionally filtering by type " + "or sectag.", + tls_cred_cmd_list, 1, 2), + SHELL_SUBCMD_SET_END +); + +SHELL_CMD_REGISTER(cred, &tls_cred_cmds, "TLS Credentials Commands", NULL); From d1e91686f3263b4cc8d07fa4e0363a33c15dd475 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 17:00:17 +0100 Subject: [PATCH 3578/4498] twister: Replace native_posix with native_sim * Replace native_posix references with native_sim in arguments help messages * For the seed parameter, correct platform check to accept native_sim * Use native_sim in twister tests Signed-off-by: Alberto Escolar Piedras --- scripts/pylib/twister/twisterlib/environment.py | 10 +++++----- scripts/pylib/twister/twisterlib/handlers.py | 2 +- scripts/pylib/twister/twisterlib/runner.py | 2 +- scripts/tests/twister/test_runner.py | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index f84749d547c..86965f1f9cf 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -220,7 +220,7 @@ def add_parse_arguments(parser = None): "--enable-valgrind", action="store_true", help="""Run binary through valgrind and check for several memory access errors. Valgrind needs to be installed on the host. This option only - works with host binaries such as those generated for the native_posix + works with host binaries such as those generated for the native_sim configuration and is mutual exclusive with --enable-asan. """) @@ -228,7 +228,7 @@ def add_parse_arguments(parser = None): "--enable-asan", action="store_true", help="""Enable address sanitizer to check for several memory access errors. Libasan needs to be installed on the host. This option only - works with host binaries such as those generated for the native_posix + works with host binaries such as those generated for the native_sim configuration and is mutual exclusive with --enable-valgrind. """) @@ -349,7 +349,7 @@ def add_parse_arguments(parser = None): "--enable-lsan", action="store_true", help="""Enable leak sanitizer to check for heap memory leaks. Libasan needs to be installed on the host. This option only - works with host binaries such as those generated for the native_posix + works with host binaries such as those generated for the native_sim configuration and when --enable-asan is given. """) @@ -358,7 +358,7 @@ def add_parse_arguments(parser = None): help="""Enable undefined behavior sanitizer to check for undefined behaviour during program execution. It uses an optional runtime library to provide better error diagnostics. This option only works with host - binaries such as those generated for the native_posix configuration. + binaries such as those generated for the native_sim configuration. """) parser.add_argument("--enable-size-report", action="store_true", @@ -586,7 +586,7 @@ def add_parse_arguments(parser = None): parser.add_argument( "--seed", type=int, - help="Seed for native posix pseudo-random number generator") + help="Seed for native_sim pseudo-random number generator") parser.add_argument( "--short-build-path", diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 2ffeb4bfc19..a39e68741aa 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -246,7 +246,7 @@ def _create_command(self, robot_test): "--track-origins=yes", ] + command - # Only valid for native_posix + # Only valid for native_sim if self.seed is not None: command.append(f"--seed={self.seed}") if self.extra_test_args is not None: diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 94c24a837d8..2e9c31bb715 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1059,7 +1059,7 @@ def run(self): if instance.handler.type_str == "device": instance.handler.duts = self.duts - if(self.options.seed is not None and instance.platform.name.startswith("native_posix")): + if(self.options.seed is not None and instance.platform.name.startswith("native_")): self.parse_generated() if('CONFIG_FAKE_ENTROPY_NATIVE_POSIX' in self.defconfig and self.defconfig['CONFIG_FAKE_ENTROPY_NATIVE_POSIX'] == 'y'): diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 50732bf4228..f0c2cbb50cf 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -2100,7 +2100,7 @@ def test_projectbuilder_build(mocked_jobserver): True, 'device', 234, - 'native_posix', + 'native_sim', 'posix', {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, 'pytest', @@ -2115,7 +2115,7 @@ def test_projectbuilder_build(mocked_jobserver): True, 'not device', None, - 'native_posix', + 'native_sim', 'not posix', {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, 'not pytest', @@ -2130,7 +2130,7 @@ def test_projectbuilder_build(mocked_jobserver): False, 'device', 234, - 'native_posix', + 'native_sim', 'posix', {'CONFIG_FAKE_ENTROPY_NATIVE_POSIX': 'y'}, 'pytest', From 373f2d21c121e523a5a062312c0401a87b7bb16d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 12:29:28 +0100 Subject: [PATCH 3579/4498] doc/develop/test: Replace references to native_posix w native_sim Replace the references to native_posix with native_sim. Signed-off-by: Alberto Escolar Piedras --- doc/develop/test/bsim.rst | 2 +- doc/develop/test/coverage.rst | 4 ++-- doc/develop/test/twister.rst | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/develop/test/bsim.rst b/doc/develop/test/bsim.rst index be06fad434f..d52bbc6fcfd 100644 --- a/doc/develop/test/bsim.rst +++ b/doc/develop/test/bsim.rst @@ -32,7 +32,7 @@ Tests without radio activity: bsim tests with twister The :ref:`bsim boards` can be used without radio activity, and in that case, it is not necessary to connect them to a phyisical layer simulation. Thanks to this, this target boards can -be used just like :ref:`native_posix` with :ref:`twister `, +be used just like :ref:`native_sim` with :ref:`twister `, to run all standard Zephyr twister tests, but with models of a real SOC HW, and their drivers. Tests with radio activity diff --git a/doc/develop/test/coverage.rst b/doc/develop/test/coverage.rst index f911c74287c..84eadad1a21 100644 --- a/doc/develop/test/coverage.rst +++ b/doc/develop/test/coverage.rst @@ -109,7 +109,7 @@ You may postprocess these with your preferred tools. For example: :zephyr-app: samples/hello_world :gen-args: -DCONFIG_COVERAGE=y :host-os: unix - :board: native_posix + :board: native_sim :goals: build :compact: @@ -140,7 +140,7 @@ For example, you may invoke:: or:: - $ twister --coverage -p native_posix -T tests/bluetooth + $ twister --coverage -p native_sim -T tests/bluetooth which will produce ``twister-out/coverage/index.html`` with the report. diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 14cffac9e50..b4cc35f3cb3 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -19,7 +19,7 @@ tests for different boards and different configurations to help keep the complete code tree buildable. When using (at least) one ``-v`` option, twister's console output -shows for every test how the test is run (qemu, native_posix, etc.) or +shows for every test how the test is run (qemu, native_sim, etc.) or whether the binary was just built. There are a few reasons why twister only builds a test and doesn't run it: @@ -1118,7 +1118,7 @@ An example of entries in a quarantine yaml: - kernel.common.nano64 platforms: - .*_cortex_.* - - native_posix + - native_sim To exclude a platform, use the following syntax: @@ -1272,7 +1272,7 @@ Running in Tests in Random Order ******************************** Enable ZTEST framework's :kconfig:option:`CONFIG_ZTEST_SHUFFLE` config option to run your tests in random order. This can be beneficial for identifying -dependencies between test cases. For native_posix platforms, you can provide +dependencies between test cases. For native_sim platforms, you can provide the seed to the random number generator by providing ``-seed=value`` as an argument to twister. See :ref:`Shuffling Test Sequence ` for more details. From fd281f5ea26969e6b4d504598f714377bf2c6e3f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:20:23 +0100 Subject: [PATCH 3580/4498] samples native_tty docs: Replace references to native_posix w native_sim Let's replace the references to native_posix with native_sim Signed-off-by: Alberto Escolar Piedras --- samples/drivers/uart/native_tty/README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/drivers/uart/native_tty/README.rst b/samples/drivers/uart/native_tty/README.rst index 8571ad1c538..6b6e2a3175e 100644 --- a/samples/drivers/uart/native_tty/README.rst +++ b/samples/drivers/uart/native_tty/README.rst @@ -15,7 +15,7 @@ The source code for this sample application can be found at: :zephyr_file:`samples/drivers/uart/native-tty`. You can learn more about the Native TTY UART driver in the -:ref:`TTY UART ` section of the Native posix board +:ref:`TTY UART ` section of the native_sim board documentation. Requirements @@ -34,12 +34,12 @@ Requirements Building and Running ******************** -This application can be built and executed on Native Posix as follows: +This application can be built and executed on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/drivers/uart/native_tty :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: From 277746185841c08bf900a02077512133f062012a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:24:37 +0100 Subject: [PATCH 3581/4498] samples kernel: Replace references to native_posix w native_sim Let's replace the references to native_posix with native_sim in the documentation, and enable this tests by default in native_sim. Signed-off-by: Alberto Escolar Piedras --- samples/kernel/condition_variables/condvar/README.rst | 6 +++--- samples/kernel/condition_variables/condvar/sample.yaml | 2 +- samples/kernel/condition_variables/simple/README.rst | 6 +++--- samples/kernel/condition_variables/simple/sample.yaml | 2 +- samples/kernel/metairq_dispatch/README.rst | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/samples/kernel/condition_variables/condvar/README.rst b/samples/kernel/condition_variables/condvar/README.rst index 51f4cf0beb2..bd84d54854a 100644 --- a/samples/kernel/condition_variables/condvar/README.rst +++ b/samples/kernel/condition_variables/condvar/README.rst @@ -20,16 +20,16 @@ the console. Building and Running ******************** -This application can be built and executed on Native Posix as follows: +This application can be built and executed on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/kernel/condition_variables/condvar :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: -To build for another board, change "native_posix" above to that board's name. +To build for another board, change ``native_sim`` above to that board's name. Sample Output ============= diff --git a/samples/kernel/condition_variables/condvar/sample.yaml b/samples/kernel/condition_variables/condvar/sample.yaml index a6e1515c67b..d2a68fbdce4 100644 --- a/samples/kernel/condition_variables/condvar/sample.yaml +++ b/samples/kernel/condition_variables/condvar/sample.yaml @@ -1,7 +1,7 @@ tests: sample.kernel.cond_var: integration_platforms: - - native_posix + - native_sim tags: - kernel - condition_variables diff --git a/samples/kernel/condition_variables/simple/README.rst b/samples/kernel/condition_variables/simple/README.rst index 42199d31c5b..2977b72cc97 100644 --- a/samples/kernel/condition_variables/simple/README.rst +++ b/samples/kernel/condition_variables/simple/README.rst @@ -19,16 +19,16 @@ the console. Building and Running ******************** -This application can be built and executed on Native Posix as follows: +This application can be built and executed on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/kernel/condition_variables/simple :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: -To build for another board, change "native_posix" above to that board's name. +To build for another board, change ``native_sim`` above to that board's name. Sample Output ============= diff --git a/samples/kernel/condition_variables/simple/sample.yaml b/samples/kernel/condition_variables/simple/sample.yaml index 556fc8e9f03..0b260a8a7e3 100644 --- a/samples/kernel/condition_variables/simple/sample.yaml +++ b/samples/kernel/condition_variables/simple/sample.yaml @@ -1,7 +1,7 @@ tests: sample.kernel.cond_var.simple: integration_platforms: - - native_posix + - native_sim tags: - kernel - condition_variables diff --git a/samples/kernel/metairq_dispatch/README.rst b/samples/kernel/metairq_dispatch/README.rst index ef7e96afa17..1e9fda7927c 100644 --- a/samples/kernel/metairq_dispatch/README.rst +++ b/samples/kernel/metairq_dispatch/README.rst @@ -60,7 +60,7 @@ kHz). Note that because the test is fundamentally measuring thread preemption behavior, it does not run without modification on -native_posix platforms. In that emulation environment, threads will +native_sim platforms. In that emulation environment, threads will not be preempted except at specific instrumentation points (e.g. in k_busy_wait()) where they will voluntarily release the CPU. From bf02cbc51f170d0236a4c74c11969ca7ca82c82f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:34:44 +0100 Subject: [PATCH 3582/4498] samples display: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim Enable native_sim in the tests, and replace native_posix as integration platform. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/display/README.rst | 4 ++-- samples/drivers/display/sample.yaml | 8 ++++++-- samples/subsys/display/lvgl/README.rst | 10 +++++----- samples/subsys/display/lvgl/sample.yaml | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/samples/drivers/display/README.rst b/samples/drivers/display/README.rst index 02ec21f3eda..872a0b5f5d2 100644 --- a/samples/drivers/display/README.rst +++ b/samples/drivers/display/README.rst @@ -30,12 +30,12 @@ Below is an example on how to build for a :ref:`nrf52840dk_nrf52840` board with :shield: adafruit_2_8_tft_touch_v2 :compact: -For testing purpose without the need of any hardware, the :ref:`native_posix` +For testing purpose without the need of any hardware, the :ref:`native_sim ` board is also supported and can be built as follows; .. zephyr-app-commands:: :zephyr-app: samples/drivers/display - :board: native_posix + :board: native_sim :goals: build :compact: diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index 00725caedb5..ba93efd5c2e 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -103,10 +103,14 @@ tests: fixture: fixture_display sample.display.sdl: build_only: true - platform_allow: native_posix_64 + platform_allow: + - native_posix_64 + - native_sim_64 tags: display sample.display.dummy: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim extra_args: DTC_OVERLAY_FILE="dummy_dc.overlay" extra_configs: - CONFIG_DUMMY_DISPLAY=y diff --git a/samples/subsys/display/lvgl/README.rst b/samples/subsys/display/lvgl/README.rst index e7312a2791b..84bb5fdb40b 100644 --- a/samples/subsys/display/lvgl/README.rst +++ b/samples/subsys/display/lvgl/README.rst @@ -27,9 +27,9 @@ or a board with an integrated display: - :ref:`esp_wrover_kit` -or a simulated display environment in a native Posix application: +or a simulated display environment in a :ref:`native_sim ` application: -- :ref:`native_posix` +- :ref:`native_sim` - `SDL2`_ or @@ -53,15 +53,15 @@ Example building for :ref:`nrf52840dk_nrf52840`: :shield: adafruit_2_8_tft_touch_v2 :goals: build flash -Example building for :ref:`native_posix`: +Example building for :ref:`native_sim `: .. zephyr-app-commands:: :zephyr-app: samples/subsys/display/lvgl - :board: native_posix + :board: native_sim :goals: build run Alternatively, if building from a 64-bit host machine, the previous target -board argument may also be replaced by ``native_posix_64``. +board argument may also be replaced by ``native_sim_64``. References ********** diff --git a/samples/subsys/display/lvgl/sample.yaml b/samples/subsys/display/lvgl/sample.yaml index d53bc36aaa7..c57ab87122b 100644 --- a/samples/subsys/display/lvgl/sample.yaml +++ b/samples/subsys/display/lvgl/sample.yaml @@ -19,7 +19,7 @@ tests: modules: - lvgl integration_platforms: - - native_posix_64 + - native_sim_64 sample.display.lvgl.rk055hdmipi4m: # This sample is intended to test the RT1170 and RT595, which require # a display shield to work with LVGL From d800634515b7fc889f1145f4fa2b96e25095949e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:36:34 +0100 Subject: [PATCH 3583/4498] samples sensing: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim. And switch the overlays and default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/sensing/simple/README.rst | 8 ++++---- .../simple/boards/{native_posix.conf => native_sim.conf} | 0 .../boards/{native_posix.overlay => native_sim.overlay} | 0 samples/subsys/sensing/simple/sample.yaml | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) rename samples/subsys/sensing/simple/boards/{native_posix.conf => native_sim.conf} (100%) rename samples/subsys/sensing/simple/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/samples/subsys/sensing/simple/README.rst b/samples/subsys/sensing/simple/README.rst index b24d4868585..f8ff0857b31 100644 --- a/samples/subsys/sensing/simple/README.rst +++ b/samples/subsys/sensing/simple/README.rst @@ -26,14 +26,14 @@ The program runs in the following sequence: Building and Running ******************** -This application can be built and executed on native_posix as follows: +This application can be built and executed on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/subsys/sensing/simple :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: -To build for another board, change "native_posix" above to that board's name. -At the current stage, it only support native posix +To build for another board, change "native_sim" above to that board's name. +At the current stage, it only support native sim. diff --git a/samples/subsys/sensing/simple/boards/native_posix.conf b/samples/subsys/sensing/simple/boards/native_sim.conf similarity index 100% rename from samples/subsys/sensing/simple/boards/native_posix.conf rename to samples/subsys/sensing/simple/boards/native_sim.conf diff --git a/samples/subsys/sensing/simple/boards/native_posix.overlay b/samples/subsys/sensing/simple/boards/native_sim.overlay similarity index 100% rename from samples/subsys/sensing/simple/boards/native_posix.overlay rename to samples/subsys/sensing/simple/boards/native_sim.overlay diff --git a/samples/subsys/sensing/simple/sample.yaml b/samples/subsys/sensing/simple/sample.yaml index b930aff274b..e8b33b417d9 100644 --- a/samples/subsys/sensing/simple/sample.yaml +++ b/samples/subsys/sensing/simple/sample.yaml @@ -4,7 +4,7 @@ sample: common: tags: sensing integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: multi_line @@ -12,5 +12,6 @@ common: - "sensing subsystem run successfully" tests: sample.subsys.sensing.simple: - platform_allow: native_posix + platform_allow: + - native_sim tags: sensing From 388f82f6b38ec5c418a683187f969682cfa259b5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:00:25 +0100 Subject: [PATCH 3584/4498] samples/basic: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim. And switch the default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/basic/hash_map/README.rst | 6 +++--- samples/basic/sys_heap/README.rst | 8 ++++---- samples/basic/sys_heap/sample.yaml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/basic/hash_map/README.rst b/samples/basic/hash_map/README.rst index 403ef297923..0c5d91a3dae 100644 --- a/samples/basic/hash_map/README.rst +++ b/samples/basic/hash_map/README.rst @@ -16,16 +16,16 @@ This is a simple example that repeatedly: Building ******** -This application can be built on native_posix as follows: +This application can be built on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/basic/hash_map :host-os: unix - :board: native_posix + :board: native_sim :goals: build :compact: -To build for another board, change "native_posix" above to that board's name. +To build for another board, change "native_sim" above to that board's name. Additionally, it is possible to use one of the other Hashmap implementations by specifying diff --git a/samples/basic/sys_heap/README.rst b/samples/basic/sys_heap/README.rst index 2b124400cde..74eb2b9e332 100644 --- a/samples/basic/sys_heap/README.rst +++ b/samples/basic/sys_heap/README.rst @@ -10,18 +10,18 @@ A simple sample that can be used with any :ref:`supported board ` and prints system heap usage to the console. Building -******************** +******** -This application can be built on native_posix as follows: +This application can be built on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/basic/sys_heap :host-os: unix - :board: native_posix + :board: native_sim :goals: build :compact: -To build for another board, change "native_posix" above to that board's name. +To build for another board, change "native_sim" above to that board's name. Running ******* diff --git a/samples/basic/sys_heap/sample.yaml b/samples/basic/sys_heap/sample.yaml index 9e9f45c90ca..d6179247991 100644 --- a/samples/basic/sys_heap/sample.yaml +++ b/samples/basic/sys_heap/sample.yaml @@ -3,7 +3,7 @@ sample: name: Basic system heap sample common: integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: multi_line From 374ecf706d570c205df8bcf9460422960fa6b9fd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:02:22 +0100 Subject: [PATCH 3585/4498] samples drivers eeprom: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim. Enable this test in natives_sim. And switch the default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/eeprom/README.rst | 4 ++-- samples/drivers/eeprom/sample.yaml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/samples/drivers/eeprom/README.rst b/samples/drivers/eeprom/README.rst index 25007274a05..079a3ebb469 100644 --- a/samples/drivers/eeprom/README.rst +++ b/samples/drivers/eeprom/README.rst @@ -15,12 +15,12 @@ Building and Running In case the target board has defined an EEPROM with alias ``eeprom-0`` the sample can be built without further ado. This applies for example to the -:ref:`native_posix` board: +:ref:`native_sim` board: .. zephyr-app-commands:: :zephyr-app: samples/drivers/eeprom :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: diff --git a/samples/drivers/eeprom/sample.yaml b/samples/drivers/eeprom/sample.yaml index b971faf9ba5..c9dfa7dd071 100644 --- a/samples/drivers/eeprom/sample.yaml +++ b/samples/drivers/eeprom/sample.yaml @@ -8,8 +8,10 @@ tests: - gd32f450i_eval - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix_64 + - native_sim_64 harness: console harness_config: type: one_line From 32000aafa1048c0198276916a1a466cb7a111f88 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:04:45 +0100 Subject: [PATCH 3586/4498] samples/modules/lvgl: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim. And switch the default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/modules/lvgl/accelerometer_chart/README.rst | 2 +- samples/modules/lvgl/accelerometer_chart/sample.yaml | 2 +- samples/modules/lvgl/demos/README.rst | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/modules/lvgl/accelerometer_chart/README.rst b/samples/modules/lvgl/accelerometer_chart/README.rst index 95d7287c89e..69f90b4f4de 100644 --- a/samples/modules/lvgl/accelerometer_chart/README.rst +++ b/samples/modules/lvgl/accelerometer_chart/README.rst @@ -45,7 +45,7 @@ custom value of 20 Hz): .. zephyr-app-commands:: :zephyr-app: samples/modules/lvgl/accelerometer_chart :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_SAMPLE_ACCEL_SAMPLING_RATE=20 :goals: run :compact: diff --git a/samples/modules/lvgl/accelerometer_chart/sample.yaml b/samples/modules/lvgl/accelerometer_chart/sample.yaml index cca7fe07ffe..943a242d00c 100644 --- a/samples/modules/lvgl/accelerometer_chart/sample.yaml +++ b/samples/modules/lvgl/accelerometer_chart/sample.yaml @@ -15,4 +15,4 @@ tests: modules: - lvgl integration_platforms: - - native_posix_64 + - native_sim_64 diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst index 1e12b8d77f8..cbc97616808 100644 --- a/samples/modules/lvgl/demos/README.rst +++ b/samples/modules/lvgl/demos/README.rst @@ -31,7 +31,7 @@ These demos can be built as follows: .. zephyr-app-commands:: :zephyr-app: samples/modules/lvgl/demos :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_LV_Z_DEMO_MUSIC=y :goals: run :compact: @@ -39,7 +39,7 @@ These demos can be built as follows: .. zephyr-app-commands:: :zephyr-app: samples/modules/lvgl/demos :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_LV_Z_DEMO_BENCHMARK=y :goals: run :compact: @@ -47,7 +47,7 @@ These demos can be built as follows: .. zephyr-app-commands:: :zephyr-app: samples/modules/lvgl/demos :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_LV_Z_DEMO_STRESS=y :goals: run :compact: @@ -55,7 +55,7 @@ These demos can be built as follows: .. zephyr-app-commands:: :zephyr-app: samples/modules/lvgl/demos :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_LV_Z_DEMO_WIDGETS=y :goals: run :compact: From 6e2deeebbc2e376cddb796acfb76b1fa18c8987e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 13:05:22 +0100 Subject: [PATCH 3587/4498] samples/modules/chre: Switch from native_posix to native_sim In the docs replace the references to native_posix with native_sim. And switch the default test platform to native_sim from native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/modules/chre/README.rst | 2 +- samples/modules/chre/sample.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/modules/chre/README.rst b/samples/modules/chre/README.rst index 54b9244d3dc..22a43a58432 100644 --- a/samples/modules/chre/README.rst +++ b/samples/modules/chre/README.rst @@ -31,7 +31,7 @@ To build the sample use the following west command: .. zephyr-app-commands:: :zephyr-app: samples/modules/chre - :board: native_posix + :board: native_sim :goals: build Once built and run, the sample application should: diff --git a/samples/modules/chre/sample.yaml b/samples/modules/chre/sample.yaml index 65f64e9453d..9442decc83d 100644 --- a/samples/modules/chre/sample.yaml +++ b/samples/modules/chre/sample.yaml @@ -24,5 +24,5 @@ tests: - "EchoApp::nanoappEnd\\(\\)" - "I: Exiting EventLoop.*" integration_platforms: - - native_posix + - native_sim filter: CONFIG_FULL_LIBC_SUPPORTED From b4d0791d1ab727e376924a97acb5f647431fa406 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 12:58:13 +0100 Subject: [PATCH 3588/4498] services/tracing doc & samples: Replace native_posix w native_sim In the docs replace the references to native_posix with native_sim. In the sample, add overlays for native_sim, and add native_sim to filter and as default integration platform. Signed-off-by: Alberto Escolar Piedras --- doc/services/tracing/index.rst | 12 ++++++------ samples/subsys/tracing/README.rst | 7 +++---- samples/subsys/tracing/boards/native_sim.conf | 5 +++++ ...tive_posix_ctf.conf => prj_native_ctf.conf} | 0 samples/subsys/tracing/sample.yaml | 18 +++++++++++++----- 5 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 samples/subsys/tracing/boards/native_sim.conf rename samples/subsys/tracing/{prj_native_posix_ctf.conf => prj_native_ctf.conf} (100%) diff --git a/doc/services/tracing/index.rst b/doc/services/tracing/index.rst index 74212d2f5a1..eb32d385b31 100644 --- a/doc/services/tracing/index.rst +++ b/doc/services/tracing/index.rst @@ -181,7 +181,7 @@ The following backends are currently supported: * UART * USB -* File (Using native posix port) +* File (Using the native port with POSIX architecture based targets) * RTT (With SystemView) * RAM (buffer to be retrieved by a debugger) @@ -191,14 +191,14 @@ Using Tracing The sample :zephyr_file:`samples/subsys/tracing` demonstrates tracing with different formats and backends. -To get started, the simplest way is to use the CTF format with the ``native_posix`` +To get started, the simplest way is to use the CTF format with the :ref:`native_sim ` port, build the sample as follows: .. zephyr-app-commands:: :tool: all :app: samples/subsys/tracing - :board: native_posix - :gen-args: -DCONF_FILE=prj_native_posix_ctf.conf + :board: native_sim + :gen-args: -DCONF_FILE=prj_native_ctf.conf :goals: build You can then run the resulting binary with the option ``-trace-file`` to generate @@ -343,14 +343,14 @@ Locking may not be needed if multiple independent channels are available. ``emit(a,thread_id); emit(b,thread_id); emit(c,thread_id);`` - The system has atomic write but one shared channel - E.g. ``native_posix`` or board with DMA. May or may not need locking. + E.g. ``native_sim`` or board with DMA. May or may not need locking. ``emit(a ## b ## c); /* Concat to buffer */`` ``lock(); emit(a); emit(b); emit(c); release(); /* No extra mem */`` - The system has atomic write and many channels - E.g. native_posix or board with multi-channel DMA. Lock-free. + E.g. native_sim or board with multi-channel DMA. Lock-free. ``emit(a ## b ## c, thread_id);`` diff --git a/samples/subsys/tracing/README.rst b/samples/subsys/tracing/README.rst index 5214e35ce48..299ab0a751d 100644 --- a/samples/subsys/tracing/README.rst +++ b/samples/subsys/tracing/README.rst @@ -83,8 +83,7 @@ Build a POSIX-tracing image with: .. zephyr-app-commands:: :zephyr-app: samples/subsys/tracing - :board: native_posix - :conf: "prj_native_posix.conf" + :board: native_sim :goals: build :compact: @@ -92,8 +91,8 @@ or: .. zephyr-app-commands:: :zephyr-app: samples/subsys/tracing - :board: native_posix - :conf: "prj_native_posix_ctf.conf" + :board: native_sim + :conf: "prj_native_ctf.conf" :goals: build :compact: diff --git a/samples/subsys/tracing/boards/native_sim.conf b/samples/subsys/tracing/boards/native_sim.conf new file mode 100644 index 00000000000..2a60b33a767 --- /dev/null +++ b/samples/subsys/tracing/boards/native_sim.conf @@ -0,0 +1,5 @@ +CONFIG_TRACING=y +CONFIG_TRACING_TEST=y +CONFIG_TRACING_SYNC=y +CONFIG_TRACING_BACKEND_POSIX=y +CONFIG_TRACING_PACKET_MAX_SIZE=64 diff --git a/samples/subsys/tracing/prj_native_posix_ctf.conf b/samples/subsys/tracing/prj_native_ctf.conf similarity index 100% rename from samples/subsys/tracing/prj_native_posix_ctf.conf rename to samples/subsys/tracing/prj_native_ctf.conf diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index dda98638a58..23db8876cee 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -60,11 +60,19 @@ tests: platform_allow: sam_e70_xplained depends_on: usb_device extra_args: CONF_FILE="prj_usb_ctf.conf" - sample.tracing.transport.native_posix: - platform_allow: native_posix - sample.tracing.transport.native_posix.ctf: - platform_allow: native_posix - extra_args: CONF_FILE="prj_native_posix_ctf.conf" + sample.tracing.transport.native: + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim + sample.tracing.transport.native.ctf: + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim + extra_args: CONF_FILE="prj_native_ctf.conf" sample.tracing.percepio: platform_allow: frdm_k64f extra_args: CONF_FILE="prj_percepio.conf" From 90aee7d65cffba0d0f681e46093c318e70481aee Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Sun, 1 Oct 2023 19:57:20 +0800 Subject: [PATCH 3589/4498] imx93: update iomuxc refs to match new pinctrl.dtsi Update iomuxc references to match the changes of `mimx9352cvuxk-pinctrl.dtsi` in hal/nxp. Signed-off-by: Chekhov Ma --- boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi | 4 ++-- west.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi b/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi index 50186a49b0a..947fbb502a0 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi +++ b/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi @@ -9,8 +9,8 @@ &pinctrl { uart2_default: uart2_default { group0 { - pinmux = <&iomuxc_uart2_rxd_uart_rx_uart2_rx>, - <&iomuxc_uart2_txd_uart_tx_uart2_tx>; + pinmux = <&iomuxc1_uart2_rxd_lpuart_rx_lpuart2_rx>, + <&iomuxc1_uart2_txd_lpuart_tx_lpuart2_tx>; bias-pull-up; slew-rate = "slightly_fast"; drive-strength = "x5"; diff --git a/west.yml b/west.yml index 639f5566de0..f7b40860645 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 73620197038d7ba80fb1f9abd001828b9dd6a27e + revision: 78d1912dbc2b5f6e114d7fd19a31053716a3b01d path: modules/hal/nxp groups: - hal From 2c13e53081774db4bd5a2772be5a605af07a9a97 Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Mon, 25 Sep 2023 10:28:15 +0800 Subject: [PATCH 3590/4498] imx93: add lpuart1 imx93: add dts node and mmu region for lpuart1 Signed-off-by: Chekhov Ma --- boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi | 10 ++++++++++ boards/arm64/mimx93_evk/mimx93_evk_a55.dts | 8 ++++++++ soc/arm64/nxp_imx/mimx9/mmu_regions.c | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi b/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi index 947fbb502a0..83070adf93f 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi +++ b/boards/arm64/mimx93_evk/mimx93_evk-pinctrl.dtsi @@ -7,6 +7,16 @@ #include &pinctrl { + uart1_default: uart1_default { + group0 { + pinmux = <&iomuxc1_uart1_rxd_lpuart_rx_lpuart1_rx>, + <&iomuxc1_uart1_txd_lpuart_tx_lpuart1_tx>; + bias-pull-up; + slew-rate = "slightly_fast"; + drive-strength = "x5"; + }; + }; + uart2_default: uart2_default { group0 { pinmux = <&iomuxc1_uart2_rxd_lpuart_rx_lpuart2_rx>, diff --git a/boards/arm64/mimx93_evk/mimx93_evk_a55.dts b/boards/arm64/mimx93_evk/mimx93_evk_a55.dts index 4ace0665671..375bb2f7a0e 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk_a55.dts +++ b/boards/arm64/mimx93_evk/mimx93_evk_a55.dts @@ -30,6 +30,14 @@ }; }; +&lpuart1 { + status = "disabled"; + current-speed = <115200>; + /* clocks = <&ccm IMX_CCM_UART4_CLK 0x6c 24>; */ + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + &lpuart2 { status = "okay"; current-speed = <115200>; diff --git a/soc/arm64/nxp_imx/mimx9/mmu_regions.c b/soc/arm64/nxp_imx/mimx9/mmu_regions.c index fb53c54e7f3..6dd767c2c9c 100644 --- a/soc/arm64/nxp_imx/mimx9/mmu_regions.c +++ b/soc/arm64/nxp_imx/mimx9/mmu_regions.c @@ -30,6 +30,11 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_SIZE(DT_NODELABEL(ana_pll)), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + MMU_REGION_FLAT_ENTRY("UART1", + DT_REG_ADDR(DT_NODELABEL(lpuart1)), + DT_REG_SIZE(DT_NODELABEL(lpuart1)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + MMU_REGION_FLAT_ENTRY("UART2", DT_REG_ADDR(DT_NODELABEL(lpuart2)), DT_REG_SIZE(DT_NODELABEL(lpuart2)), From 2b6c861f0c6ec686cfec4a000bfe01c8febd67fe Mon Sep 17 00:00:00 2001 From: Chekhov Ma Date: Tue, 25 Apr 2023 17:19:55 +0800 Subject: [PATCH 3591/4498] imx93: increase mmu region count to 64 The default mmu region count is not enough when more drivers are added. Signed-off-by: Chekhov Ma --- boards/arm64/mimx93_evk/mimx93_evk_a55_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm64/mimx93_evk/mimx93_evk_a55_defconfig b/boards/arm64/mimx93_evk/mimx93_evk_a55_defconfig index 2bcf6198a10..53cb74f825c 100644 --- a/boards/arm64/mimx93_evk/mimx93_evk_a55_defconfig +++ b/boards/arm64/mimx93_evk/mimx93_evk_a55_defconfig @@ -7,6 +7,9 @@ CONFIG_AARCH64_IMAGE_HEADER=y CONFIG_ARMV8_A_NS=y +# MMU Options +CONFIG_MAX_XLAT_TABLES=64 + # Cache Options CONFIG_CACHE_MANAGEMENT=y CONFIG_DCACHE_LINE_SIZE_DETECT=y From c05b81bd9cad4d42334cc0807e12d6f175c900d7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 09:30:53 +0100 Subject: [PATCH 3592/4498] docs: native_sim/posix: Swap documentation from native_posix to native_sim During this release native_sim is replacing native_posix as the main host test/development platform. Therefore, instead of basing the native_sim documentation in native_posix's one, let's do it the other way around. This commit mostly moves documentation from the native_posix page into the native_sim one, changing the board and renaming labels. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_posix/doc/index.rst | 510 ++-------------------- boards/posix/native_sim/doc/index.rst | 530 +++++++++++++++++++++-- boards/posix/nrf_bsim/doc/nrf52_bsim.rst | 4 +- 3 files changed, 536 insertions(+), 508 deletions(-) diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 92827acbacf..e096e8c5483 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -11,14 +11,28 @@ Native POSIX execution (native_posix) Overview ******** -This is a :ref:`POSIX architecture` based board. -With it, a Zephyr application can be compiled together with -the Zephyr kernel, creating a normal Linux executable. +``native_posix`` is the predecessor of :ref:`native_sim`. +Just like with :ref:`native_sim` you can build your Zephyr application +with the Zephyr kernel, creating a normal Linux executable with your host tooling, +and can debug and instrument it like any other Linux program. + +But unlike with :ref:`native_sim` you are limited to only using the host C library. +:ref:`native_sim` supports all ``native_posix`` use cases. + +.. note:: + + | If you are a new user, you are encouraged to use :ref:`native_sim` directly. + | If you have been using native_posix you are recommended to start using + :ref:`native_sim` instead. + | If needed, :ref:`native_sim` includes a compatibility mode + :kconfig:option:`CONFIG_NATIVE_SIM_NATIVE_POSIX_COMPAT`, + which will set its configuration to mimic a native_posix's like configuration. This board does not intend to simulate any particular HW, but it provides a few peripherals such as an Ethernet driver, display, UART, etc., to enable developing and testing application code which would require them. -See `Peripherals`_ for more information. +This board supports the same :ref:`peripherals` +:ref:`and backends as native_sim`. .. _native_posix_deps: @@ -36,15 +50,16 @@ Important limitations This board inherits :ref:`the limitations of its architecture` +Moreover, being limited to build only with the host C library, it is not possible to build +applications with the :ref:`Zephyr POSIX OS abstraction`, as there would be symbol +collisions between the host OS and this abstraction layer. + .. _native_posix_how_to_use: How to use it ************* -Compiling -========= - -Specify the native_posix board target to build a native POSIX application: +To build, simply specify the ``native_posix`` board as target: .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -53,92 +68,20 @@ Specify the native_posix board target to build a native POSIX application: :goals: build :compact: -Running -======= - -The result of the compilation is an executable (zephyr.exe) placed in the -zephyr/ subdirectory of the build folder. -Run the zephyr.exe executable as you would any other Linux console application. - -.. code-block:: console - - $ ./build/zephyr/zephyr.exe - # Press Ctrl+C to exit - -This executable accepts several command line options depending on the -compilation configuration. -You can run it with the ``--help`` command line switch to get a list of -available options:: - - $ ./build/zephyr/zephyr.exe --help - -Note that the Zephyr kernel does not actually exit once the application is -finished. It simply goes into the idle loop forever. -Therefore you must stop the application manually (Ctrl+C in Linux). - -Application tests using the ``ztest`` framework will exit after all -tests have completed. - -If you want your application to gracefully finish when it reaches some point, -you may add a conditionally compiled (:kconfig:option:`CONFIG_ARCH_POSIX`) call to -``posix_exit(int status)`` at that point. - -.. _native_posix_debug: - -Debugging -========= - -Since the Zephyr executable is a native application, it can be debugged and -instrumented as any other native program. The program is compiled with debug -information, so it can be run directly in, for example, ``gdb`` or instrumented -with ``valgrind``. - -Because the execution of your Zephyr application is normally deterministic -(there are no asynchronous or random components), you can execute the -code multiple times and get the exact same result. Instrumenting the -code does not affect its execution. - -To ease debugging you may want to compile your code without optimizations -(e.g., -O0) by setting :kconfig:option:`CONFIG_NO_OPTIMIZATIONS`. - -.. _native_posix_asan: - -Address Sanitizer (ASan) -======================== - -You can also build Zephyr with the `Address Sanitizer`_. To do this, set -:kconfig:option:`CONFIG_ASAN`, for example, in the application project file, or in the -``west build`` or ``cmake`` command line invocation. - -Note that you will need the ASan library installed in your system. -In Debian/Ubuntu this is ``libasan1``. - -.. _Address Sanitizer: - https://github.com/google/sanitizers/wiki/AddressSanitizer - -Undefined Behavior Sanitizer (UBSan) -==================================== - -You can also build Zephyr with the `Undefined Behavior Sanitizer`_. To do this, set -:kconfig:option:`CONFIG_UBSAN`, for example, in the application project file, or in the -``west build`` or ``cmake`` command line invocation. - -.. _Undefined Behavior Sanitizer: - https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html - -Coverage reports -================ - -See -:ref:`coverage reports using the POSIX architecture`. +Now you have a Linux executable, ``./build/zephyr/zephyr.exe``, you can use just like any +other Linux program. +You can run, debug, build it with sanitizers or with coverage just like with +:ref:`native_sim`. +Please check :ref:`native_sim's how to` for more info. .. _native_posix32_64: 32 and 64bit versions ********************* -native_posix comes with two targets: A 32 bit and 64 bit version. +Just like :ref:`native_sim`, ``native_posix comes`` with two targets: +A 32 bit and 64 bit version. The 32 bit version, ``native_posix``, is the default target, which will compile your code for the ILP32 ABI (i386 in a x86 or x86_64 system) where pointers and longs are 32 bits. @@ -151,396 +94,3 @@ one with a 32bit userspace. The 64 bit version, ``native_posix_64``, compiles your code targeting the LP64 ABI (x86-64 in x86 systems), where pointers and longs are 64 bits. You can use this target if you cannot compile or run 32 bit binaries. - -If you are using another 32 bit POSIX arch target you may also override its ABI -target and pointer bit width by setting :kconfig:option:`CONFIG_64BIT`. - - -Rationale for this port and comparison with other options -********************************************************* - -The native_posix board shares the overall -:ref:`intent of the POSIX architecture`, -while being a HW agnostic test platform which in some cases utilizes the host -OS peripherals. -It does not intend to model any particular HW, and as such can only be used -to develop and test application code which is far decoupled from the HW. - -For developing and testing SW which requires specific HW, while retaining the -benefits of the POSIX architecture other solutions like the -:ref:`bsim boards` -should be considered. - -Check the :ref:`POSIX architecture comparison ` -with other development and test options for more insights. - -.. _native_posix_architecture: - -Architecture -************ - -This board is based on the POSIX architecture port of Zephyr and shares -:ref:`its basic architecture` regarding threading -and CPU/HW scheduling. - -This board does not try to emulate any particular embedded CPU or SOC. -The code is compiled natively for the host system (typically x86). - -About time in native_posix -========================== - -Normally simulated time runs fully decoupled from the real host time -and as fast as the host compute power would allow. -This is desirable when running in a debugger or testing in batch, but not if -interacting with external interfaces based on the real host time. - -The Zephyr kernel is only aware of the simulated time as provided by the -HW models. Therefore any normal Zephyr thread will also know only about -simulated time. - -The only link between the simulated time and the real/host time, if any, -is created by the clock and timer model. - -This model can be configured to slow down the execution of native_posix to -real time. -You can do this with the ``--rt`` and ``--no-rt`` options from the command line. -The default behavior is set with -:kconfig:option:`CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME`. -Note that all this model does is wait before raising the -next system tick interrupt until the corresponding real/host time. -If, for some reason, native_posix runs slower than real time, all this -model can do is "catch up" as soon as possible by not delaying the -following ticks. -So if the host load is too high, or you are running in a debugger, you will -see simulated time lagging behind the real host time. -This solution ensures that normal runs are still deterministic while -providing an illusion of real timeness to the observer. - -When locked to real time, simulated time can also be set to run faster or -slower than real time. -This can be controlled with the ``--rt-ratio=`` and ``-rt-drift=`` -command line options. Note that both of these options control the same -underlying mechanism, and that ``drift`` is by definition equal to -``ratio - 1``. -It is also possible to adjust this clock speed on the fly with -:c:func:`native_rtc_adjust_clock()`. - -In this way if, for example, ``--rt-ratio=2`` is given, the simulated time -will advance at twice the real time speed. -Similarly if ``--rt-drift=-100e-6`` is given, the simulated time will progress -100ppm slower than real time. -Note that these 2 options have no meaning when running in non real-time -mode. - -How simulated time and real time relate to each other ------------------------------------------------------ - -Simulated time (``st``) can be calculated from real time (``rt``) as - -``st = (rt - last_rt) * ratio + last_st`` - -And vice-versa: - -``rt = (st - last_st) / ratio + last_rt`` - -Where ``last_rt`` and ``last_st`` are respectively the real time and the -simulated time when the last clock ratio adjustment took place. - -All times are kept in microseconds. - -.. _native_posix_peripherals: - -Peripherals -*********** - -The following peripherals are currently provided with this board: - -**Interrupt controller**: - A simple yet generic interrupt controller is provided. It can nest interrupts - and provides interrupt priorities. Interrupts can be individually masked or - unmasked. SW interrupts are also supported. - -**Clock, timer and system tick model** - This model provides the system tick timer. By default - :kconfig:option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` configures it to tick every 10ms. - - This peripheral driver also provides the needed functionality for this - architecture-specific :c:func:`k_busy_wait`. - - Please refer to the section `About time in native_posix`_ for more - information. - -**UART/Serial** - Two optional native UART drivers are available: - - **PTTY driver (UART_NATIVE_POSIX)** - With this driver, one or two Zephyr UART devices can be created. These - can be connected to the Linux process stdin/stdout or a newly created - pseudo-tty. For more information refer to the section `PTTY UART`_. - - **TTY driver (UART_NATIVE_TTY)** - An UART driver for interacting with host-attached serial port devices - (eg. USB to UART dongles). For more information refer to the section - `TTY UART`_. - -**Real time clock** - The real time clock model provides a model of a constantly powered clock. - By default this is initialized to the host time at boot. - - This RTC can also be set to start from time 0 with the ``--rtc-reset`` command - line option. - - It is possible to offset the RTC clock value at boot with the - ``--rtc-offset=`` option, - or to adjust it dynamically with the function :c:func:`native_rtc_offset`. - - After start, this RTC advances with the simulated time, and is therefore - affected by the simulated time speed ratio. - See `About time in native_posix`_ for more information. - - The time can be queried with the functions :c:func:`native_rtc_gettime_us` - and :c:func:`native_rtc_gettime`. Both accept as parameter the clock source: - - - ``RTC_CLOCK_BOOT``: It counts the simulated time passed since boot. - It is not subject to offset adjustments - - ``RTC_CLOCK_REALTIME``: RTC persistent time. It is affected by - offset adjustments. - - ``RTC_CLOCK_PSEUDOHOSTREALTIME``: A version of the real host time, - as if the host was also affected by the clock speed ratio and offset - adjustments performed to the simulated clock and this RTC. Normally - this value will be a couple of hundredths of microseconds ahead of the - simulated time, depending on the host execution speed. - This clock source should be used with care, as depending on the actual - execution speed of native_posix and the host load, - it may return a value considerably ahead of the simulated time. - -**Entropy device**: - An entropy device based on the host :c:func:`random` API. - This device will generate the same sequence of random numbers if initialized - with the same random seed. - You can change this random seed value by using the command line option: - ``--seed=`` where the value specified is a 32-bit integer - such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal). - -**Ethernet driver**: - A simple TAP based ethernet driver is provided. The driver expects that the - **zeth** network interface already exists in the host system. The **zeth** - network interface can be created by the ``net-setup.sh`` script found in - the `net-tools`_ zephyr project repository. User can communicate with the - Zephyr instance via the **zeth** network interface. Multiple TAP based - network interfaces can be created if needed. The IP address configuration - can be specified for each network interface instance. - - Note that this device can only be used with Linux hosts. - -.. _net-tools: - https://github.com/zephyrproject-rtos/net-tools - - -**Bluetooth controller**: - It's possible to use the host's Bluetooth adapter as a Bluetooth - controller for Zephyr. To do this the HCI device needs to be passed as - a command line option to ``zephyr.exe``. For example, to use ``hci0``, - use ``sudo zephyr.exe --bt-dev=hci0``. Using the device requires root - privileges (or the CAP_NET_ADMIN POSIX capability, to be exact) so - ``zephyr.exe`` needs to be run through ``sudo``. The chosen HCI device - must be powered down and support Bluetooth Low Energy (i.e. support the - Bluetooth specification version 4.0 or greater). - - Another possibility is to use a HCI TCP server which acts as a - :ref:`virtual Bluetooth controller` over TCP. - To connect to a HCI TCP server its IP address and port number must - be specified. For example, to connect to a HCI TCP server with IP - address 127.0.0.0 and port number 1020 use ``zephyr.exe --bt-dev=127.0.0.1:1020``. - This alternative option is mainly aimed for testing Bluetooth connectivity over - a virtual Bluetooth controller that does not depend on the Linux Bluetooth - stack and its HCI interface. - -**USB controller**: - It's possible to use the Virtual USB controller working over USB/IP - protocol. More information can be found in - :ref:`Testing USB over USP/IP in native_posix `. - -**Display driver**: - A display driver is provided that creates a window on the host machine to - render display content. - - This driver requires a 32-bit version of the `SDL2`_ library on the host - machine and ``pkg-config`` settings to correctly pickup the SDL2 install path - and compiler flags. - - On a Ubuntu 18.04 host system, for example, install the ``pkg-config`` and - ``libsdl2-dev:i386`` packages, and configure the pkg-config search path with - these commands:: - - $ sudo apt-get install pkg-config libsdl2-dev:i386 - $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig - -.. _SDL2: - https://www.libsdl.org/download-2.0.php - -**Flash driver**: - A flash driver is provided that accesses all flash data through a binary file - on the host file system. The behavior of the flash device can be configured - through the native POSIX board devicetree or Kconfig settings under - :kconfig:option:`CONFIG_FLASH_SIMULATOR`. - - By default the binary data is located in the file *flash.bin* in the current - working directory. The location of this file can be changed through the - command line parameter *--flash*. The flash data will be stored in raw format - and the file will be truncated to match the size specified in the devicetree - configuration. In case the file does not exists the driver will take care of - creating the file, else the existing file is used. - - The flash content can be accessed from the host system, as explained in the - `Host based flash access`_ section. - -PTTY UART -********* - -This driver can be configured with :kconfig:option:`CONFIG_UART_NATIVE_POSIX` -to instantiate up to two UARTs. By default only one UART is enabled. -With :kconfig:option:`CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE` -you can enable the second one. - -For the first UART, it can link it to a new -pseudoterminal (i.e. ``/dev/pts``), or map the UART input and -output to the executable's ``stdin`` and ``stdout``. -This is chosen by selecting either -:kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or -:kconfig:option:`CONFIG_NATIVE_UART_0_ON_STDINOUT` -For interactive use with the :ref:`shell_api`, choose the first (OWN_PTY) option. -The second (STDINOUT) option can be used with the shell for automated -testing, such as when piping other processes' output to control it. -This is because the shell subsystem expects access to a raw terminal, -which (by default) a normal Linux terminal is not. - -When :kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` is chosen, the name of the -newly created UART pseudo-terminal will be displayed in the console. -If you want to interact with it manually, you should attach a terminal emulator -to it. This can be done, for example with the command:: - - $ xterm -e screen /dev/ & - -where ``/dev/`` should be replaced with the actual TTY device. - -You may also chose to automatically attach a terminal emulator to the first UART -by passing the command line option ``-attach_uart`` to the executable. -The command used for attaching to the new shell can be set with the command line -option ``-attach_uart_cmd=<"cmd">``. Where the default command is given by -:kconfig:option:`CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD`. -Note that the default command assumes both ``xterm`` and ``screen`` are -installed in the system. - -This driver only supports poll mode. Interrupt and async mode are not supported. -Neither runtime configuration or line control are supported. - -.. _native_tty_uart: - -TTY UART -******** - -With this driver an application can use the polling UART API (``uart_poll_out``, -``uart_poll_in``) to write and read characters to and from a connected serial -port device. - -This driver is automatically enabled when a devicetree contains a node -with ``"zephyr,native-tty-uart"`` compatible property and ``okay`` status, such -as one below:: - - uart { - status = "okay"; - compatible = "zephyr,native-tty-uart"; - serial-port = "/dev/ttyUSB0"; - current-speed = <115200>; - }; - -Interaction with serial ports can be configured in several different ways: - -* The default serial port and baud rate can be set via the device tree - properties ``serial-port`` and ``current-speed`` respectively. The - ``serial-port`` property is optional. -* Serial port and baud rate can also be set via command line options ``X_port`` - and ``X_baud`` respectively, where ``X`` is a name of a node. Command line - options override values from the devicetree. -* The rest of the configuration options such as number of data and stop bits, - parity, as well as baud rate can be set at runtime with ``uart_configure``. - -Multiple instances of such uart drivers are supported. - -The :zephyr:code-sample:`uart-native-tty` sample app provides a working example of the -driver. - -This driver only supports poll mode. Interrupt and async mode are not supported. -It has runtime configuration support, but no line control support. - -Subsystems backends -******************* - -Apart from its own peripherals, the native_posix board also has some dedicated -backends for some of Zephyr's subsystems. These backends are designed to ease -development by integrating more seamlessly with the host operating system: - -**Console backend**: - A console backend which by default is configured to - redirect any :c:func:`printk` write to the native host application's - ``stdout``. - - This driver is selected by default if the `PTTY UART`_ is not compiled in. - Otherwise :kconfig:option:`CONFIG_UART_CONSOLE` will be set to select the UART as - console backend. - -**Logger backend**: - A backend which prints all logger output to the process ``stdout``. - It supports timestamping, which can be enabled with - :kconfig:option:`CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP`; and colored output which can - be enabled with :kconfig:option:`CONFIG_LOG_BACKEND_SHOW_COLOR` and controlled - with the command line options ``--color``, ``--no-color`` and - ``--force-color``. - - In native_posix, by default, the logger is configured with - :kconfig:option:`CONFIG_LOG_MODE_IMMEDIATE`. - - This backend can be selected with :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX` - and is enabled by default unless the native_posix UART is compiled in. - In this later case, by default, the logger is set to output to the - `PTTY UART`_. - -**Tracing**: - A backend/"bottom" for Zephyr's CTF tracing subsystem which writes the tracing - data to a file in the host filesystem. - More information can be found in :ref:`Common Tracing Format ` - -Host based flash access -*********************** - -If a flash device is present, the file system partitions on the flash -device can be exposed through the host file system by enabling -:kconfig:option:`CONFIG_FUSE_FS_ACCESS`. This option enables a FUSE -(File system in User space) layer that maps the Zephyr file system calls to -the required UNIX file system calls, and provides access to the flash file -system partitions with normal operating system commands such as ``cd``, -``ls`` and ``mkdir``. - -By default the partitions are exposed through the directory *flash* in the -current working directory. This directory can be changed via the command line -option *--flash-mount*. As this directory operates as a mount point for FUSE -you have to ensure that it exists before starting the native POSIX board. - -On exit, the native POSIX board application will take care of unmounting the -directory. In the unfortunate case that the native POSIX board application -crashes, you can cleanup the stale mount point by using the program -``fusermount``:: - - $ fusermount -u flash - -Note that this feature requires a 32-bit version of the FUSE library, with a -minimal version of 2.6, on the host system and ``pkg-config`` settings to -correctly pickup the FUSE install path and compiler flags. - -On a Ubuntu 18.04 host system, for example, install the ``pkg-config`` and -``libfuse-dev:i386`` packages, and configure the pkg-config search path with -these commands:: - - $ sudo apt-get install pkg-config libfuse-dev:i386 - $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index bd332c1e081..00c8fa682ba 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -3,18 +3,33 @@ Native simulator - native_sim ############################# +.. contents:: + :depth: 1 + :backlinks: entry + :local: + Overview ******** -The native_sim board is an evolution of :ref:`native_posix`. -Just like with :ref:`native_posix` you can build your Zephyr application -with the Zephyr kernel, creating a normal Linux executable with your host tooling, -and can debug and instrument it like any other Linux program. +The ``native_sim`` board is a :ref:`POSIX architecture` based board. +With it, a Zephyr application can be compiled together with +the Zephyr kernel, and libraries, creating a normal Linux executable. -native_sim is based on the +``native_sim`` is based on the `native simulator `_ and the :ref:`POSIX architecture`. +This board does not intend to simulate any particular HW, but it provides +a few peripherals such as an Ethernet driver, display, UART, etc., to enable +developing and testing application code which would require them. +See `Peripherals`_ for more information. + +.. note:: + + | ``native_sim`` is an evolution of the older :ref:`native_posix`. + | Some components, code, options names, and documentation will still use the old native_posix + names. But all components which worked with native_posix will work with native_sim. + Host system dependencies ************************ @@ -26,13 +41,18 @@ Please check the Important limitations ********************* -Native_sim is based on the :ref:`POSIX architecture`, and therefore +``native_sim`` is based on the :ref:`POSIX architecture`, and therefore :ref:`its limitations ` and considerations apply to it. +.. _native_sim_how_to_use: + How to use it ************* -To build, simply specify the native_sim board as target: +Compiling +========= + +To build, simply specify the ``native_sim`` board as target: .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -41,17 +61,94 @@ To build, simply specify the native_sim board as target: :goals: build :compact: -Now you have a Linux executable, ``./build/zephyr/zephyr.exe``, you can use just like any -other Linux program. +Running +======= + +The result of the compilation is an executable (``zephyr.exe``) placed in the +``zephyr/`` subdirectory of the ``build`` folder. +Run the ``zephyr.exe`` executable as you would any other Linux console application. + +.. code-block:: console + + $ ./build/zephyr/zephyr.exe + # Press Ctrl+C to exit + +This executable accepts several command line options depending on the +compilation configuration. +You can run it with the ``--help`` command line switch to get a list of +available options:: + + $ ./build/zephyr/zephyr.exe --help + +Note that the Zephyr kernel does not actually exit once the application is +finished. It simply goes into the idle loop forever. +Therefore you must stop the application manually (Ctrl+C in Linux). + +Application tests using the :ref:`ztest framework` will exit after all +tests have completed. + +If you want your application to gracefully finish when it reaches some point, +you may add a conditionally compiled (:kconfig:option:`CONFIG_ARCH_POSIX`) call to +``nsi_exit(int status)`` at that point. + +.. _native_sim_debug: + +Debugging +========= + +Since the Zephyr executable is a native application, it can be debugged and +instrumented as any other native program. The program is compiled with debug +information, so it can be run directly in, for example, ``gdb`` or instrumented +with ``valgrind``. + +Because the execution of your Zephyr application is normally deterministic +(there are no asynchronous or random components), you can execute the +code multiple times and get the exact same result. Instrumenting the +code does not affect its execution. + +To ease debugging you may want to compile your code without optimizations +(e.g., ``-O0``) by setting :kconfig:option:`CONFIG_NO_OPTIMIZATIONS`. + +For ease of debugging consider using an IDE as GUI for your debugger. + +.. _native_sim_asan: + +Address Sanitizer (ASan) +======================== + +You can also build Zephyr with the `Address Sanitizer`_. To do this, set +:kconfig:option:`CONFIG_ASAN`, for example, in the application project file, or in the +``west build`` or ``cmake`` command line invocation. + +Note that you will need the ASan library installed in your system. +In Debian/Ubuntu this is ``libasan1``. + +.. _Address Sanitizer: + https://github.com/google/sanitizers/wiki/AddressSanitizer + +Undefined Behavior Sanitizer (UBSan) +==================================== + +You can also build Zephyr with the `Undefined Behavior Sanitizer`_. To do this, set +:kconfig:option:`CONFIG_UBSAN`, for example, in the application project file, or in the +``west build`` or ``cmake`` command line invocation. + +.. _Undefined Behavior Sanitizer: + https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html + +Coverage reports +================ + +See +:ref:`coverage reports using the POSIX architecture`. -You can run, debug, build it with sanitizers or with coverage just like with -:ref:`native_posix `. -Please check :ref:`native_posix's how to` for more info. + +.. _native_sim32_64: 32 and 64bit versions ********************* -Just like native_posix, native_sim comes with two targets: A 32 bit and 64 bit version. +native_sim comes with two targets: A 32 bit and 64 bit version. The 32 bit version, ``native_sim``, is the default target, which will compile your code for the ILP32 ABI (i386 in a x86 or x86_64 system) where pointers and longs are 32 bits. @@ -70,38 +167,419 @@ You can use this target if you cannot compile or run 32 bit binaries. C library choice **************** -Unlike native_posix, native_sim may be compiled with a choice of C libraries. +native_sim may be compiled with a choice of C libraries. By default it will be compiled with the host C library (:kconfig:option:`CONFIG_EXTERNAL_LIBC`), but you can also select to build it with :kconfig:option:`CONFIG_MINIMAL_LIBC` or with :kconfig:option:`CONFIG_PICOLIBC`. +If you select some feature which are not compatible with the host C library, +:ref:`Picolibc ` will be selected by default instead. -When building with either :ref:`MINIMAL` or :ref:`PICO` libC +When building with either :ref:`minimal ` or :ref:`Picolibc` you will build your code in a more similar way as when building for the embedded target, you will be able to test your code interacting with that C library, and there will be no conflicts with the :ref:`POSIX OS abstraction` shim, but, accessing the host for test purposes from your embedded code will be more difficult, and you will have a limited choice of -:ref:`drivers and backends to chose from`. +:ref:`drivers and backends to chose from`. + +Rationale for this port and comparison with other options +********************************************************* + +The native_sim board shares the overall +:ref:`intent of the POSIX architecture`, +while being a HW agnostic test platform which in some cases utilizes the host +OS peripherals. +It does not intend to model any particular HW, and as such can only be used +to develop and test application code which is far decoupled from the HW. + +For developing and testing SW which requires specific HW, while retaining the +benefits of the POSIX architecture other solutions like the +:ref:`bsim boards` +should be considered. + +Check the :ref:`POSIX architecture comparison ` +with other development and test options for more insights. + +.. _native_sim_architecture: Architecture ************ -:ref:`native_posix's architecture description` as well as the -:ref:`POSIX architecture description` are directly -applicable to native_sim. +This board is based on the POSIX architecture port of Zephyr and shares +:ref:`its basic architecture` regarding threading +and CPU/HW scheduling. -If you are interested on the inner workigns of the native simulator itself, you can check +If you are interested on the inner workings of the native simulator itself, you can check `its documentation `_. +This board does not try to emulate any particular embedded CPU or SOC. +The code is compiled natively for the host system (typically x86). + +About time in native_sim +======================== + +Normally simulated time runs fully decoupled from the real host time +and as fast as the host compute power would allow. +This is desirable when running in a debugger or testing in batch, but not if +interacting with external interfaces based on the real host time. + +The Zephyr kernel is only aware of the simulated time as provided by the +HW models. Therefore any normal Zephyr thread will also know only about +simulated time. + +The only link between the simulated time and the real/host time, if any, +is created by the clock and timer model. + +This model can be configured to slow down the execution of native_sim to +real time. +You can do this with the ``--rt`` and ``--no-rt`` options from the command line. +The default behavior is set with +:kconfig:option:`CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME`. +Note that all this model does is wait before raising the +next system tick interrupt until the corresponding real/host time. +If, for some reason, native_sim runs slower than real time, all this +model can do is "catch up" as soon as possible by not delaying the +following ticks. +So if the host load is too high, or you are running in a debugger, you will +see simulated time lagging behind the real host time. +This solution ensures that normal runs are still deterministic while +providing an illusion of real timeness to the observer. + +When locked to real time, simulated time can also be set to run faster or +slower than real time. +This can be controlled with the ``--rt-ratio=`` and ``-rt-drift=`` +command line options. Note that both of these options control the same +underlying mechanism, and that ``drift`` is by definition equal to +``ratio - 1``. +It is also possible to adjust this clock speed on the fly with +:c:func:`native_rtc_adjust_clock()`. + +In this way if, for example, ``--rt-ratio=2`` is given, the simulated time +will advance at twice the real time speed. +Similarly if ``--rt-drift=-100e-6`` is given, the simulated time will progress +100ppm slower than real time. +Note that these 2 options have no meaning when running in non real-time +mode. + +How simulated time and real time relate to each other +----------------------------------------------------- + +Simulated time (``st``) can be calculated from real time (``rt``) as + +``st = (rt - last_rt) * ratio + last_st`` + +And vice-versa: + +``rt = (st - last_st) / ratio + last_rt`` + +Where ``last_rt`` and ``last_st`` are respectively the real time and the +simulated time when the last clock ratio adjustment took place. + +All times are kept in microseconds. + .. _native_sim_peripherals: -Peripherals, subsystems backends and host based flash access -************************************************************ +Peripherals +*********** + +The following peripherals are currently provided with this board: + +**Interrupt controller**: + A simple yet generic interrupt controller is provided. It can nest interrupts + and provides interrupt priorities. Interrupts can be individually masked or + unmasked. SW interrupts are also supported. + +**Clock, timer and system tick model** + This model provides the system tick timer. By default + :kconfig:option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` configures it to tick every 10ms. + + Please refer to the section `About time in native_sim`_ for more + information. + +**UART/Serial** + Two optional native UART drivers are available: + + **PTTY driver (UART_NATIVE_POSIX)** + With this driver, one or two Zephyr UART devices can be created. These + can be connected to the Linux process stdin/stdout or a newly created + pseudo-tty. For more information refer to the section `PTTY UART`_. + + **TTY driver (UART_NATIVE_TTY)** + An UART driver for interacting with host-attached serial port devices + (eg. USB to UART dongles). For more information refer to the section + `TTY UART`_. + +**Real time clock** + The real time clock model provides a model of a constantly powered clock. + By default this is initialized to the host time at boot. + + This RTC can also be set to start from time 0 with the ``--rtc-reset`` command + line option. + + It is possible to offset the RTC clock value at boot with the + ``--rtc-offset=`` option, + or to adjust it dynamically with the function :c:func:`native_rtc_offset`. + + After start, this RTC advances with the simulated time, and is therefore + affected by the simulated time speed ratio. + See `About time in native_sim`_ for more information. + + The time can be queried with the functions :c:func:`native_rtc_gettime_us` + and :c:func:`native_rtc_gettime`. Both accept as parameter the clock source: + + - ``RTC_CLOCK_BOOT``: It counts the simulated time passed since boot. + It is not subject to offset adjustments + - ``RTC_CLOCK_REALTIME``: RTC persistent time. It is affected by + offset adjustments. + - ``RTC_CLOCK_PSEUDOHOSTREALTIME``: A version of the real host time, + as if the host was also affected by the clock speed ratio and offset + adjustments performed to the simulated clock and this RTC. Normally + this value will be a couple of hundredths of microseconds ahead of the + simulated time, depending on the host execution speed. + This clock source should be used with care, as depending on the actual + execution speed of native_sim and the host load, + it may return a value considerably ahead of the simulated time. + +**Entropy device**: + An entropy device based on the host :c:func:`random` API. + This device will generate the same sequence of random numbers if initialized + with the same random seed. + You can change this random seed value by using the command line option: + ``--seed=`` where the value specified is a 32-bit integer + such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal). + +**Ethernet driver**: + A simple TAP based ethernet driver is provided. The driver expects that the + **zeth** network interface already exists in the host system. The **zeth** + network interface can be created by the ``net-setup.sh`` script found in + the `net-tools`_ zephyr project repository. User can communicate with the + Zephyr instance via the **zeth** network interface. Multiple TAP based + network interfaces can be created if needed. The IP address configuration + can be specified for each network interface instance. + + Note that this device can only be used with Linux hosts. + +.. _net-tools: + https://github.com/zephyrproject-rtos/net-tools + + +**Bluetooth controller**: + It's possible to use the host's Bluetooth adapter as a Bluetooth + controller for Zephyr. To do this the HCI device needs to be passed as + a command line option to ``zephyr.exe``. For example, to use ``hci0``, + use ``sudo zephyr.exe --bt-dev=hci0``. Using the device requires root + privileges (or the CAP_NET_ADMIN POSIX capability, to be exact) so + ``zephyr.exe`` needs to be run through ``sudo``. The chosen HCI device + must be powered down and support Bluetooth Low Energy (i.e. support the + Bluetooth specification version 4.0 or greater). + + Another possibility is to use a HCI TCP server which acts as a + :ref:`virtual Bluetooth controller` over TCP. + To connect to a HCI TCP server its IP address and port number must + be specified. For example, to connect to a HCI TCP server with IP + address 127.0.0.0 and port number 1020 use ``zephyr.exe --bt-dev=127.0.0.1:1020``. + This alternative option is mainly aimed for testing Bluetooth connectivity over + a virtual Bluetooth controller that does not depend on the Linux Bluetooth + stack and its HCI interface. + +**USB controller**: + It's possible to use the Virtual USB controller working over USB/IP + protocol. More information can be found in + :ref:`Testing USB over USP/IP in native_posix `. + +**Display driver**: + A display driver is provided that creates a window on the host machine to + render display content. + + This driver requires a 32-bit version of the `SDL2`_ library on the host + machine and ``pkg-config`` settings to correctly pickup the SDL2 install path + and compiler flags. + + On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and + ``libsdl2-dev:i386`` packages, and configure the pkg-config search path with + these commands:: + + $ sudo apt-get install pkg-config libsdl2-dev:i386 + $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig + +.. _SDL2: + https://www.libsdl.org/download-2.0.php + +**Flash driver**: + A flash driver is provided that accesses all flash data through a binary file + on the host file system. The behavior of the flash device can be configured + through the native_sim board devicetree or Kconfig settings under + :kconfig:option:`CONFIG_FLASH_SIMULATOR`. + + By default the binary data is located in the file *flash.bin* in the current + working directory. The location of this file can be changed through the + command line parameter *--flash*. The flash data will be stored in raw format + and the file will be truncated to match the size specified in the devicetree + configuration. In case the file does not exists the driver will take care of + creating the file, else the existing file is used. + + The flash content can be accessed from the host system, as explained in the + `Host based flash access`_ section. + +PTTY UART +********* + +This driver can be configured with :kconfig:option:`CONFIG_UART_NATIVE_POSIX` +to instantiate up to two UARTs. By default only one UART is enabled. +With :kconfig:option:`CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE` +you can enable the second one. + +For the first UART, it can link it to a new +pseudoterminal (i.e. ``/dev/pts``), or map the UART input and +output to the executable's ``stdin`` and ``stdout``. +This is chosen by selecting either +:kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or +:kconfig:option:`CONFIG_NATIVE_UART_0_ON_STDINOUT` +For interactive use with the :ref:`shell_api`, choose the first (OWN_PTY) option. +The second (STDINOUT) option can be used with the shell for automated +testing, such as when piping other processes' output to control it. +This is because the shell subsystem expects access to a raw terminal, +which (by default) a normal Linux terminal is not. + +When :kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` is chosen, the name of the +newly created UART pseudo-terminal will be displayed in the console. +If you want to interact with it manually, you should attach a terminal emulator +to it. This can be done, for example with the command:: + + $ xterm -e screen /dev/ & + +where ``/dev/`` should be replaced with the actual TTY device. + +You may also chose to automatically attach a terminal emulator to the first UART +by passing the command line option ``-attach_uart`` to the executable. +The command used for attaching to the new shell can be set with the command line +option ``-attach_uart_cmd=<"cmd">``. Where the default command is given by +:kconfig:option:`CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD`. +Note that the default command assumes both ``xterm`` and ``screen`` are +installed in the system. + +This driver only supports poll mode. Interrupt and async mode are not supported. +Neither runtime configuration or line control are supported. + +.. _native_tty_uart: + +TTY UART +******** + +With this driver an application can use the polling UART API (``uart_poll_out``, +``uart_poll_in``) to write and read characters to and from a connected serial +port device. + +This driver is automatically enabled when a devicetree contains a node +with ``"zephyr,native-tty-uart"`` compatible property and ``okay`` status, such +as one below:: + + uart { + status = "okay"; + compatible = "zephyr,native-tty-uart"; + serial-port = "/dev/ttyUSB0"; + current-speed = <115200>; + }; + +Interaction with serial ports can be configured in several different ways: + +* The default serial port and baud rate can be set via the device tree + properties ``serial-port`` and ``current-speed`` respectively. The + ``serial-port`` property is optional. +* Serial port and baud rate can also be set via command line options ``X_port`` + and ``X_baud`` respectively, where ``X`` is a name of a node. Command line + options override values from the devicetree. +* The rest of the configuration options such as number of data and stop bits, + parity, as well as baud rate can be set at runtime with ``uart_configure``. + +Multiple instances of such uart drivers are supported. + +The :zephyr:code-sample:`uart-native-tty` sample app provides a working example of the +driver. + +This driver only supports poll mode. Interrupt and async mode are not supported. +It has runtime configuration support, but no line control support. + +.. _native_sim_backends: + +Subsystems backends +******************* + +Apart from its own peripherals, the native_sim board also has some dedicated +backends for some of Zephyr's subsystems. These backends are designed to ease +development by integrating more seamlessly with the host operating system: + +**Console backend**: + A console backend which by default is configured to + redirect any :c:func:`printk` write to the native host application's + ``stdout``. + + This driver is selected by default if the `PTTY UART`_ is not compiled in. + Otherwise :kconfig:option:`CONFIG_UART_CONSOLE` will be set to select the UART as + console backend. + +**Logger backend**: + A backend which prints all logger output to the process ``stdout``. + It supports timestamping, which can be enabled with + :kconfig:option:`CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP`; and colored output which can + be enabled with :kconfig:option:`CONFIG_LOG_BACKEND_SHOW_COLOR` and controlled + with the command line options ``--color``, ``--no-color`` and + ``--force-color``. + + In native_sim, by default, the logger is configured with + :kconfig:option:`CONFIG_LOG_MODE_IMMEDIATE`. + + This backend can be selected with :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX` + and is enabled by default unless the PTTY UART is compiled in. + In this later case, by default, the logger is set to output to the + `PTTY UART`_. + +**Tracing**: + A backend/"bottom" for Zephyr's CTF tracing subsystem which writes the tracing + data to a file in the host filesystem. + More information can be found in :ref:`Common Tracing Format ` + +Host based flash access +*********************** + +If a flash device is present, the file system partitions on the flash +device can be exposed through the host file system by enabling +:kconfig:option:`CONFIG_FUSE_FS_ACCESS`. This option enables a FUSE +(File system in User space) layer that maps the Zephyr file system calls to +the required UNIX file system calls, and provides access to the flash file +system partitions with normal operating system commands such as ``cd``, +``ls`` and ``mkdir``. + +By default the partitions are exposed through the directory *flash* in the +current working directory. This directory can be changed via the command line +option *--flash-mount*. As this directory operates as a mount point for FUSE +you have to ensure that it exists before starting the native_sim board. + +On exit, the native_sim board application will take care of unmounting the +directory. In the unfortunate case that the native_sim board application +crashes, you can cleanup the stale mount point by using the program +``fusermount``:: + + $ fusermount -u flash + +Note that this feature requires a 32-bit version of the FUSE library, with a +minimal version of 2.6, on the host system and ``pkg-config`` settings to +correctly pickup the FUSE install path and compiler flags. + +On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and +``libfuse-dev:i386`` packages, and configure the pkg-config search path with +these commands:: + + $ sudo apt-get install pkg-config libfuse-dev:i386 + $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig + +.. _native_sim_peripherals_c_compat: + +Peripherals and backends C library compatibility +************************************************ -Today, native_sim supports the exact same -:ref:`peripherals and backends as native_posix`, -with the only caveat that some of these are, so far, only available when compiling with the -host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). +Today, some native_sim peripherals and backends are, so far, only available when compiling with the +host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`): .. csv-table:: Drivers/backends vs libC choice :header: Driver class, driver name, driver kconfig, libC choices diff --git a/boards/posix/nrf_bsim/doc/nrf52_bsim.rst b/boards/posix/nrf_bsim/doc/nrf52_bsim.rst index f8b7cad6628..da1212e3367 100644 --- a/boards/posix/nrf_bsim/doc/nrf52_bsim.rst +++ b/boards/posix/nrf_bsim/doc/nrf52_bsim.rst @@ -182,7 +182,7 @@ Check the :ref:`native simulator C library choice section`, the resulting +Just like with :ref:`native_sim`, the resulting executables are Linux native applications. Therefore they can be debugged or instrumented with the same tools as any other native application, like for example ``gdb`` or ``valgrind``. @@ -191,7 +191,7 @@ The same :ref:`code coverage analysis means from the POSIX arch` are inherited in this board. Similarly, the -:ref:`address and undefined behavior sanitizers can be used as in native_posix`. +:ref:`address and undefined behavior sanitizers can be used as in native_sim`. Note that BabbleSim will run fine if one or several of its components are From c3d863f864d1398a5a6295816aa6d45021087735 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 10:26:46 +0100 Subject: [PATCH 3593/4498] docs: boards posix: Replace reference to native_posix w native_sim Let's replace the references to native_posix with native_sim, Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- boards/posix/doc/arch_soc.rst | 8 ++++---- boards/posix/doc/bsim_boards_design.rst | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/boards/posix/doc/arch_soc.rst b/boards/posix/doc/arch_soc.rst index cac21706293..ff1f947e483 100644 --- a/boards/posix/doc/arch_soc.rst +++ b/boards/posix/doc/arch_soc.rst @@ -65,9 +65,9 @@ This port is designed and tested to run in Linux. The 32 bit version of this port does not directly work in Windows Subsystem for Linux (WSL) because WSL does not support native 32-bit binaries. - You may want to consider WSL2, or, if using native_posix, - you can also just use the native_posix_64 - target: Check :ref:`32 and 64bit versions`. + You may want to consider WSL2, or, if using :ref:`native_sim `, + you can also just use the ``native_sim_64`` + target: Check :ref:`32 and 64bit versions`. Otherwise `with some tinkering `_ it should be possible to make it work. @@ -391,7 +391,7 @@ Busy waits ========== Busy waits work thanks to provided board functionality. -This does not need to be the same for all boards, but both native_posix and the +This does not need to be the same for all boards, but both native_sim and the nrf52_bsim board work similarly thru the combination of a board specific `arch_busy_wait()` and a special fake HW timer (provided by the board). diff --git a/boards/posix/doc/bsim_boards_design.rst b/boards/posix/doc/bsim_boards_design.rst index f69a27a5761..bb510f58351 100644 --- a/boards/posix/doc/bsim_boards_design.rst +++ b/boards/posix/doc/bsim_boards_design.rst @@ -52,7 +52,7 @@ These tests are run in workstation, that is, without using real embedded HW. The intention being to be able to run tests much faster than real time, without the need for real HW, and in a deterministic/reproducible fashion. -Unlike native_posix, bsim boards do not interact directly with any host +Unlike :ref:`native_sim `, bsim boards do not interact directly with any host peripherals, and their execution is independent of the host load, or timing. .. _bsim_boards_tests: @@ -95,13 +95,13 @@ to these boards. an special driver that handles the EDTT communication (its RPC transport) and an embedded application that handles the RPC calls themselves, while the python test scripts provide the test logic. - - Using Zephyr's native_posix board: It also allows integration testing of + - Using Zephyr's :ref:`native_sim ` board: It also allows integration testing of the embedded code, but without any specific HW. In that way, many embedded components which are dependent on the HW would not be suited for testing in that platform. Just like the bsim boards, this Zephyr target board can be used with or without Zephyr's ztest system and twister. - The native_posix board shares the :ref:`POSIX architecture` - with the bsim boards. + The :ref:`native_sim ` board shares the :ref:`POSIX architecture`, + and native simulator runner with the bsim boards. - Zephyr's ztest infrastructure and Zephyr's twister: Based on dedicated embedded test applications build with the code under test. From 85b54358a135eabdd875fb6f84b85705822c09fc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:11:44 +0100 Subject: [PATCH 3594/4498] docs: Introduction: Replace references to native_posix w native_sim Let's replace the references to native_posix with native_sim, in the introduction and beyond the getting started guide. Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- doc/develop/beyond-GSG.rst | 20 ++++++++++---------- doc/introduction/index.rst | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/develop/beyond-GSG.rst b/doc/develop/beyond-GSG.rst index 41269c12634..1b9aab82644 100644 --- a/doc/develop/beyond-GSG.rst +++ b/doc/develop/beyond-GSG.rst @@ -177,7 +177,8 @@ Build and Run an Application You can build, flash, and run Zephyr applications on real hardware using a supported host system. Depending on your operating system, -you can also run it in emulation with QEMU, or as a native POSIX application. +you can also run it in emulation with QEMU, or as a native application with +:ref:`native_sim `. Additional information about building applications can be found in the :ref:`build_an_application` section. @@ -291,22 +292,21 @@ To exit QEMU, type :kbd:`Ctrl-a`, then :kbd:`x`. Use ``qemu_cortex_m3`` to target an emulated Arm Cortex-M3 sample. -.. _gs_posix: +.. _gs_native: -Run a Sample Application natively (POSIX OS) -============================================ +Run a Sample Application natively (Linux) +========================================= -You can compile some samples to run as host processes -on a POSIX OS. This is currently only tested on Linux hosts. See -:ref:`native_posix` for more information. On 64-bit host operating systems, you -need to install a 32-bit C library; see :ref:`native_posix_deps` for details. +You can compile some samples to run as host programs +on Linux. See :ref:`native_sim` for more information. On 64-bit host operating systems, you +need to install a 32-bit C library, or build targeting :ref:`native_sim_64 `. -First, build Hello World for ``native_posix``. +First, build Hello World for ``native_sim``. .. zephyr-app-commands:: :zephyr-app: samples/hello_world :host-os: unix - :board: native_posix + :board: native_sim :goals: build Next, run the application. diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index 5444694dd21..85968ca456a 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -144,8 +144,8 @@ Zephyr offers a large and ever growing number of features including: **Native Linux, macOS, and Windows Development** A command-line CMake build environment runs on popular developer OS - systems. A native POSIX port lets you build and run Zephyr as a native - application on Linux and other OSes, aiding development and testing. + systems. A native port (:ref:`native_sim `) lets you build and run Zephyr as a native + application on Linux, aiding development and testing. **Virtual File System Interface with ext2, FatFs, and LittleFS Support** ext2, LittleFS and FatFS support; FCB (Flash Circular Buffer) for memory constrained @@ -170,9 +170,9 @@ Zephyr offers a large and ever growing number of features including: NVS allows storage of binary blobs, strings, integers, longs, and any combination of these. -**Native POSIX port** - Supports running Zephyr as a Linux application with support for various - subsystems and networking. +**Native port** + :ref:`Native sim ` allows running Zephyr as a Linux application with support + for various subsystems and networking. .. include:: ../../README.rst From 86db69956487275aa078e8a0f1dd5e37f80bdd3b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 12:50:04 +0100 Subject: [PATCH 3595/4498] docs: native_sim: Polish documentation Polish the native_sim documentation a bit. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_posix/doc/index.rst | 2 +- boards/posix/native_sim/doc/index.rst | 87 +++++++++++++++---------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index e096e8c5483..61e6c164327 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -80,7 +80,7 @@ Please check :ref:`native_sim's how to` for more info. 32 and 64bit versions ********************* -Just like :ref:`native_sim`, ``native_posix comes`` with two targets: +Just like :ref:`native_sim`, ``native_posix`` comes with two targets: A 32 bit and 64 bit version. The 32 bit version, ``native_posix``, is the default target, which will compile your code for the ILP32 ABI (i386 in a x86 or x86_64 system) where pointers diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 00c8fa682ba..94eb8d43580 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -76,7 +76,9 @@ Run the ``zephyr.exe`` executable as you would any other Linux console applicati This executable accepts several command line options depending on the compilation configuration. You can run it with the ``--help`` command line switch to get a list of -available options:: +available options. + +.. code-block:: console $ ./build/zephyr/zephyr.exe --help @@ -146,7 +148,7 @@ See .. _native_sim32_64: 32 and 64bit versions -********************* +===================== native_sim comes with two targets: A 32 bit and 64 bit version. The 32 bit version, ``native_sim``, is the default target, which will compile @@ -235,6 +237,7 @@ real time. You can do this with the ``--rt`` and ``--no-rt`` options from the command line. The default behavior is set with :kconfig:option:`CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME`. + Note that all this model does is wait before raising the next system tick interrupt until the corresponding real/host time. If, for some reason, native_sim runs slower than real time, all this @@ -266,11 +269,13 @@ How simulated time and real time relate to each other Simulated time (``st``) can be calculated from real time (``rt``) as -``st = (rt - last_rt) * ratio + last_st`` +.. math:: + st = (rt - last\_rt) \times ratio + last\_st And vice-versa: -``rt = (st - last_st) / ratio + last_rt`` +.. math:: + rt = (st - last\_st) / ratio + last\_rt Where ``last_rt`` and ``last_st`` are respectively the real time and the simulated time when the last clock ratio adjustment took place. @@ -284,7 +289,7 @@ Peripherals The following peripherals are currently provided with this board: -**Interrupt controller**: +**Interrupt controller** A simple yet generic interrupt controller is provided. It can nest interrupts and provides interrupt priorities. Interrupts can be individually masked or unmasked. SW interrupts are also supported. @@ -340,15 +345,15 @@ The following peripherals are currently provided with this board: execution speed of native_sim and the host load, it may return a value considerably ahead of the simulated time. -**Entropy device**: +**Entropy device** An entropy device based on the host :c:func:`random` API. This device will generate the same sequence of random numbers if initialized with the same random seed. You can change this random seed value by using the command line option: - ``--seed=`` where the value specified is a 32-bit integer + :samp:`--seed={}` where the value specified is a 32-bit integer such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal). -**Ethernet driver**: +**Ethernet driver** A simple TAP based ethernet driver is provided. The driver expects that the **zeth** network interface already exists in the host system. The **zeth** network interface can be created by the ``net-setup.sh`` script found in @@ -363,7 +368,7 @@ The following peripherals are currently provided with this board: https://github.com/zephyrproject-rtos/net-tools -**Bluetooth controller**: +**Bluetooth controller** It's possible to use the host's Bluetooth adapter as a Bluetooth controller for Zephyr. To do this the HCI device needs to be passed as a command line option to ``zephyr.exe``. For example, to use ``hci0``, @@ -382,12 +387,12 @@ The following peripherals are currently provided with this board: a virtual Bluetooth controller that does not depend on the Linux Bluetooth stack and its HCI interface. -**USB controller**: +**USB controller** It's possible to use the Virtual USB controller working over USB/IP protocol. More information can be found in :ref:`Testing USB over USP/IP in native_posix `. -**Display driver**: +**Display driver** A display driver is provided that creates a window on the host machine to render display content. @@ -397,23 +402,25 @@ The following peripherals are currently provided with this board: On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and ``libsdl2-dev:i386`` packages, and configure the pkg-config search path with - these commands:: + these commands: - $ sudo apt-get install pkg-config libsdl2-dev:i386 - $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig + .. code-block:: console + + $ sudo apt-get install pkg-config libsdl2-dev:i386 + $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig .. _SDL2: https://www.libsdl.org/download-2.0.php -**Flash driver**: +**Flash driver** A flash driver is provided that accesses all flash data through a binary file on the host file system. The behavior of the flash device can be configured through the native_sim board devicetree or Kconfig settings under :kconfig:option:`CONFIG_FLASH_SIMULATOR`. - By default the binary data is located in the file *flash.bin* in the current + By default the binary data is located in the file :file:`flash.bin` in the current working directory. The location of this file can be changed through the - command line parameter *--flash*. The flash data will be stored in raw format + command line parameter ``--flash``. The flash data will be stored in raw format and the file will be truncated to match the size specified in the devicetree configuration. In case the file does not exists the driver will take care of creating the file, else the existing file is used. @@ -422,7 +429,7 @@ The following peripherals are currently provided with this board: `Host based flash access`_ section. PTTY UART -********* +========= This driver can be configured with :kconfig:option:`CONFIG_UART_NATIVE_POSIX` to instantiate up to two UARTs. By default only one UART is enabled. @@ -430,7 +437,7 @@ With :kconfig:option:`CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE` you can enable the second one. For the first UART, it can link it to a new -pseudoterminal (i.e. ``/dev/pts``), or map the UART input and +pseudoterminal (i.e. :file:`/dev/pts{}`), or map the UART input and output to the executable's ``stdin`` and ``stdout``. This is chosen by selecting either :kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or @@ -444,11 +451,13 @@ which (by default) a normal Linux terminal is not. When :kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` is chosen, the name of the newly created UART pseudo-terminal will be displayed in the console. If you want to interact with it manually, you should attach a terminal emulator -to it. This can be done, for example with the command:: +to it. This can be done, for example with the command: + +.. code-block:: console $ xterm -e screen /dev/ & -where ``/dev/`` should be replaced with the actual TTY device. +where :file:`/dev/tty{}` should be replaced with the actual TTY device. You may also chose to automatically attach a terminal emulator to the first UART by passing the command line option ``-attach_uart`` to the executable. @@ -464,7 +473,7 @@ Neither runtime configuration or line control are supported. .. _native_tty_uart: TTY UART -******** +======== With this driver an application can use the polling UART API (``uart_poll_out``, ``uart_poll_in``) to write and read characters to and from a connected serial @@ -472,14 +481,16 @@ port device. This driver is automatically enabled when a devicetree contains a node with ``"zephyr,native-tty-uart"`` compatible property and ``okay`` status, such -as one below:: +as one below. - uart { - status = "okay"; - compatible = "zephyr,native-tty-uart"; - serial-port = "/dev/ttyUSB0"; - current-speed = <115200>; - }; +.. code-block:: dts + + uart { + status = "okay"; + compatible = "zephyr,native-tty-uart"; + serial-port = "/dev/ttyUSB0"; + current-speed = <115200>; + }; Interaction with serial ports can be configured in several different ways: @@ -550,17 +561,19 @@ the required UNIX file system calls, and provides access to the flash file system partitions with normal operating system commands such as ``cd``, ``ls`` and ``mkdir``. -By default the partitions are exposed through the directory *flash* in the +By default the partitions are exposed through the directory :file:`flash/` in the current working directory. This directory can be changed via the command line -option *--flash-mount*. As this directory operates as a mount point for FUSE +option ``--flash-mount``. As this directory operates as a mount point for FUSE you have to ensure that it exists before starting the native_sim board. On exit, the native_sim board application will take care of unmounting the directory. In the unfortunate case that the native_sim board application crashes, you can cleanup the stale mount point by using the program -``fusermount``:: +``fusermount``: - $ fusermount -u flash +.. code-block:: console + + $ fusermount -u flash Note that this feature requires a 32-bit version of the FUSE library, with a minimal version of 2.6, on the host system and ``pkg-config`` settings to @@ -568,10 +581,12 @@ correctly pickup the FUSE install path and compiler flags. On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and ``libfuse-dev:i386`` packages, and configure the pkg-config search path with -these commands:: +these commands: + +.. code-block:: console - $ sudo apt-get install pkg-config libfuse-dev:i386 - $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig + $ sudo apt-get install pkg-config libfuse-dev:i386 + $ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig .. _native_sim_peripherals_c_compat: From 8b6f447ef8e946a582e313b1fb3a32ede206bcd7 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Thu, 12 Oct 2023 17:06:04 +0200 Subject: [PATCH 3596/4498] twister: harness: Fix Console unordered pattern matching for ztest Fix the Twister Console harness unordered pattern matching to treat the ztest as failed when not all of the expected patterns were found in the console output, but the ztest application itself reports 'PROJECT EXECUTION SUCCESSFUL'. Unify debug logging on pattern match for ordered and unordered patterns. Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/harness.py | 26 +++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index ef24ef57720..312ac943cef 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -174,13 +174,16 @@ def configure(self, instance): def handle(self, line): if self.type == "one_line": if self.pattern.search(line): - logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED({self.next_pattern}):'{self.pattern.pattern}'") + logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED:" + f"'{self.pattern.pattern}'") self.next_pattern += 1 self.state = "passed" elif self.type == "multi_line" and self.ordered: if (self.next_pattern < len(self.patterns) and self.patterns[self.next_pattern].search(line)): - logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED({self.next_pattern}):'{self.patterns[self.next_pattern].pattern}'") + logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED(" + f"{self.next_pattern + 1}/{self.patterns_expected}):" + f"'{self.patterns[self.next_pattern].pattern}'") self.next_pattern += 1 if self.next_pattern >= len(self.patterns): self.state = "passed" @@ -189,6 +192,9 @@ def handle(self, line): r = self.regex[i] if pattern.search(line) and not r in self.matches: self.matches[r] = line + logger.debug(f"HARNESS:{self.__class__.__name__}:EXPECTED(" + f"{len(self.matches)}/{self.patterns_expected}):" + f"'{pattern.pattern}'") if len(self.matches) == len(self.regex): self.state = "passed" else: @@ -218,16 +224,22 @@ def handle(self, line): self.recording.append(csv) self.process_test(line) - # Reset the resulting test state to 'failed' for 'one_line' and - # ordered 'multi_line' patterns when not all of these patterns were + # Reset the resulting test state to 'failed' when not all of the patterns were # found in the output, but just ztest's 'PROJECT EXECUTION SUCCESSFUL'. # It might happen because of the pattern sequence diverged from the # test code, the test platform has console issues, or even some other # test image was executed. - # TODO: Introduce explicit match policy type either to reject - # unexpected console output, or to allow missing patterns. + # TODO: Introduce explicit match policy type to reject + # unexpected console output, allow missing patterns, deny duplicates. if self.state == "passed" and self.ordered and self.next_pattern < self.patterns_expected: - logger.error(f"HARNESS:{self.__class__.__name__}: failed with only {self.next_pattern} matched patterns from expected {self.patterns_expected}") + logger.error(f"HARNESS:{self.__class__.__name__}: failed with" + f" {self.next_pattern} of {self.patterns_expected}" + f" expected ordered patterns.") + self.state = "failed" + if self.state == "passed" and not self.ordered and len(self.matches) < self.patterns_expected: + logger.error(f"HARNESS:{self.__class__.__name__}: failed with" + f" {len(self.matches)} of {self.patterns_expected}" + f" expected unordered patterns.") self.state = "failed" tc = self.instance.get_case_or_create(self.id) From 00d260af96844eb60ef271f00f3493b32d7497c8 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 13 Oct 2023 20:42:59 +0200 Subject: [PATCH 3597/4498] twister: harness: Check Console harness configuration If Console Harness 'harness_config' properties have no 'regex' patterns or no correct 'type' set, then ConfigurationError exception is raised, handled, and the test instance error is accounted in the summary results. Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/harness.py | 18 ++++++++++++++++++ scripts/pylib/twister/twisterlib/runner.py | 11 +++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 312ac943cef..cb3460a8849 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -13,6 +13,7 @@ import threading import time +from twisterlib.error import ConfigurationError from twisterlib.environment import ZEPHYR_BASE, PYTEST_PLUGIN_INSTALLED from twisterlib.handlers import Handler, terminate_process, SUPPORTED_SIMS_IN_PYTEST from twisterlib.testinstance import TestInstance @@ -162,6 +163,14 @@ class Console(Harness): def configure(self, instance): super(Console, self).configure(instance) + if self.regex is None or len(self.regex) == 0: + self.state = "failed" + tc = self.instance.set_case_status_by_name( + self.id, + "failed", + f"HARNESS:{self.__class__.__name__}:no regex patterns configured." + ) + raise ConfigurationError(self.instance.name, tc.reason) if self.type == "one_line": self.pattern = re.compile(self.regex[0]) self.patterns_expected = 1 @@ -170,6 +179,15 @@ def configure(self, instance): for r in self.regex: self.patterns.append(re.compile(r)) self.patterns_expected = len(self.patterns) + else: + self.state = "failed" + tc = self.instance.set_case_status_by_name( + self.id, + "failed", + f"HARNESS:{self.__class__.__name__}:incorrect type={self.type}" + ) + raise ConfigurationError(self.instance.name, tc.reason) + # def handle(self, line): if self.type == "one_line": diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 2e9c31bb715..3471f6bf702 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -25,7 +25,7 @@ from domains import Domains from twisterlib.cmakecache import CMakeCache from twisterlib.environment import canonical_zephyr_base -from twisterlib.error import BuildError +from twisterlib.error import BuildError, ConfigurationError import elftools from elftools.elf.elffile import ELFFile @@ -1069,7 +1069,14 @@ def run(self): instance.handler.extra_test_args = self.options.extra_test_args harness = HarnessImporter.get_harness(instance.testsuite.harness.capitalize()) - harness.configure(instance) + try: + harness.configure(instance) + except ConfigurationError as error: + instance.status = "error" + instance.reason = str(error) + logger.error(instance.reason) + return + # if isinstance(harness, Pytest): harness.pytest_run(instance.handler.get_test_timeout()) else: From 7d0d3f83cbc53c8e791afb4141fd62931fed7683 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 13 Oct 2023 20:54:47 +0200 Subject: [PATCH 3598/4498] twister: harness: Fix TestCase id at Console for Ztest Implement a workaround for Console harness to compose TestCase identifier correctly when a Ztest suite with a single testcase uses this harness type. Normally, a Ztest suite should use the Ztest Twister harness. Without this workaround each Ztest TestCase result on Console is duplicated (and written into twister.json) with its 'identifier' attribute set to TestSuite id only, no TestCase suffix added; the resulting entry with the full TestCase id is also stored, but its values are empty with defaults. Signed-off-by: Dmitrii Golovanov --- scripts/pylib/twister/twisterlib/harness.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index cb3460a8849..052def7162a 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -161,12 +161,25 @@ def run_robot_test(self, command, handler): class Console(Harness): + def get_testcase_name(self): + ''' + Get current TestCase name. + + Console Harness id has only TestSuite id without TestCase name suffix. + Only the first TestCase name might be taken if available when a Ztest with + a single test case is configured to use this harness type for simplified + output parsing instead of the Ztest harness as Ztest suite should do. + ''' + if self.instance and len(self.instance.testcases) == 1: + return self.instance.testcases[0].name + return self.id + def configure(self, instance): super(Console, self).configure(instance) if self.regex is None or len(self.regex) == 0: self.state = "failed" tc = self.instance.set_case_status_by_name( - self.id, + self.get_testcase_name(), "failed", f"HARNESS:{self.__class__.__name__}:no regex patterns configured." ) @@ -182,7 +195,7 @@ def configure(self, instance): else: self.state = "failed" tc = self.instance.set_case_status_by_name( - self.id, + self.get_testcase_name(), "failed", f"HARNESS:{self.__class__.__name__}:incorrect type={self.type}" ) @@ -260,7 +273,7 @@ def handle(self, line): f" expected unordered patterns.") self.state = "failed" - tc = self.instance.get_case_or_create(self.id) + tc = self.instance.get_case_or_create(self.get_testcase_name()) if self.state == "passed": tc.status = "passed" else: From d6a3fd7cf00656a3e8b62f4e6968736820a00cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 14 Nov 2023 12:36:08 +0100 Subject: [PATCH 3599/4498] shell: uart: Add missing casting of the data pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing compilation failure due to treating void pointer as uint8_t array. Added missing casting. Signed-off-by: Krzysztof Chruściński --- subsys/shell/backends/shell_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/shell/backends/shell_uart.c b/subsys/shell/backends/shell_uart.c index f64438c0b59..b06cc4a09b8 100644 --- a/subsys/shell/backends/shell_uart.c +++ b/subsys/shell/backends/shell_uart.c @@ -504,7 +504,7 @@ static int async_read(struct shell_uart_async *sh_uart, for (size_t i = 0; i < blen; i++) { if (smp_shell_rx_bytes(smp, &buf[i], 1) == 0) { - data[sh_cnt++] = buf[i]; + ((uint8_t *)data)[sh_cnt++] = buf[i]; } } #else From 6d2e3b59a5d1ae0d6ca6e94ee95dc68459b5fea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 14 Nov 2023 12:39:28 +0100 Subject: [PATCH 3600/4498] mgmt: mcumgr: smp_shell: Change the way shell uart device is fetched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SMP shell was looking into internal shell uart structures to get uart device. This structures are now internal to the shell and cannot be used. Using device tree chosen instead. Signed-off-by: Krzysztof Chruściński --- subsys/mgmt/mcumgr/transport/src/smp_shell.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subsys/mgmt/mcumgr/transport/src/smp_shell.c b/subsys/mgmt/mcumgr/transport/src/smp_shell.c index c30874070ba..fc04bcd75c4 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_shell.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_shell.c @@ -213,13 +213,11 @@ static uint16_t smp_shell_get_mtu(const struct net_buf *nb) static int smp_shell_tx_raw(const void *data, int len) { - const struct shell *const sh = shell_backend_uart_get_ptr(); - const struct shell_uart *const su = sh->iface->ctx; - const struct shell_uart_ctrl_blk *const scb = su->ctrl_blk; + static const struct device *const sh_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); const uint8_t *out = data; while ((out != NULL) && (len != 0)) { - uart_poll_out(scb->dev, *out); + uart_poll_out(sh_dev, *out); ++out; --len; } From e6e6515972d56b30c71f2379838724fc39d77ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 14 Nov 2023 13:10:37 +0100 Subject: [PATCH 3601/4498] shell: uart: Rework Kconfig dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When UART asynchronous API support was added to shell it was set up to be the default one and was turning on asynchronous API if it was supported. However, it may lead to complation failures if device requires additional setup for asynchronous UART (e.g DMA in device tree). Becuase of that, it is reverted back to use interrupt driven API and use asynchronous API if it is already enabled in the application. Signed-off-by: Krzysztof Chruściński --- subsys/shell/backends/Kconfig.backends | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index 7c81030cb20..e4e826b0316 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -44,12 +44,13 @@ config SHELL_PROMPT_UART config SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN bool "Interrupt driven" + default y depends on SERIAL_SUPPORT_INTERRUPT choice SHELL_BACKEND_SERIAL_API prompt "Mode" - default SHELL_BACKEND_SERIAL_API_ASYNC if SERIAL_SUPPORT_ASYNC - default SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN if SERIAL_SUPPORT_INTERRUPT + default SHELL_BACKEND_SERIAL_API_ASYNC if UART_ASYNC_API + default SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN if SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN default SHELL_BACKEND_SERIAL_API_POLLING config SHELL_BACKEND_SERIAL_API_POLLING @@ -65,7 +66,6 @@ config SHELL_BACKEND_SERIAL_API_ASYNC bool "Asynchronous" depends on SERIAL_SUPPORT_ASYNC select UART_ASYNC_RX_HELPER - select UART_ASYNC_API endchoice From 2171f8b7a1770f5818fce0083175c8360004672c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 14 Nov 2023 14:34:45 +0000 Subject: [PATCH 3602/4498] ci: compliance: only run sorted check on text files The sorted check code crashes on binary files. Add a check on file type and only process text ones. Signed-off-by: Fabio Baltieri --- scripts/ci/check_compliance.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 8779fddda66..0a2da6bc9ca 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1177,6 +1177,11 @@ class KeepSorted(ComplianceTest): MARKER = "zephyr-keep-sorted" def check_file(self, file, fp): + mime_type = magic.from_file(file, mime=True) + + if not mime_type.startswith("text/"): + return + lines = [] in_block = False From a0b746ed74f373192dc524333b8a496f7d3dae99 Mon Sep 17 00:00:00 2001 From: Thien Nguyen Date: Mon, 2 Oct 2023 15:10:08 +0200 Subject: [PATCH 3603/4498] doc: drivers: deprecate driver init levels Remove deprecated driver initialization levels in the docs. Signed-off-by: Thien Nguyen --- doc/kernel/drivers/index.rst | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/kernel/drivers/index.rst b/doc/kernel/drivers/index.rst index 3d3c1715b9f..51b31de006f 100644 --- a/doc/kernel/drivers/index.rst +++ b/doc/kernel/drivers/index.rst @@ -343,13 +343,6 @@ allow the user to specify at what time during the boot sequence the init function will be executed. Any driver will specify one of four initialization levels: -``EARLY`` - Used very early in the boot process, right after entering the C domain - (``z_cstart()``). This can be used in architectures and SoCs that extend - or implement architecture code and use drivers or system services that - have to be initialized before the Kernel calls any architecture specific - initialization code. - ``PRE_KERNEL_1`` Used for devices that have no dependencies, such as those that rely solely on hardware present in the processor/SOC. These devices cannot @@ -368,12 +361,6 @@ initialization levels: Used for devices that require kernel services during configuration. Init functions at this level run in context of the kernel main task. -``APPLICATION`` - Used for application components (i.e. non-kernel components) that need - automatic configuration. These devices can use all services provided by - the kernel during configuration. Init functions at this level run on - the kernel main task. - Within each initialization level you may specify a priority level, relative to other devices in the same initialization level. The priority level is specified as an integer value in the range 0 to 99; lower values indicate earlier From 1b4a647950da1422e7add603ee65a5b319b0a09b Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 14 Nov 2023 11:12:06 +0800 Subject: [PATCH 3604/4498] logging: backend: uart: append index conditionally for compatibility Updated the `LBU_DEFINE` so that the index is appended only when given to improve backward compatibility. When it is depending on the `zephyr,console` node, the backend is defined as `log_backend_uart`. When it is depending on the new `zephyr,log-uart` node, the backend is defined as `log_backend_uart0`, `log_backend_uart1`, and so on. Updated the names of the internal variables to follow the same naming convention. Signed-off-by: Yong Cong Sin --- subsys/logging/backends/log_backend_uart.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/subsys/logging/backends/log_backend_uart.c b/subsys/logging/backends/log_backend_uart.c index 7c58ea1774e..fbfdcc365a6 100644 --- a/subsys/logging/backends/log_backend_uart.c +++ b/subsys/logging/backends/log_backend_uart.c @@ -227,28 +227,28 @@ const struct log_backend_api log_backend_uart_api = { .format_set = format_set, }; -#define LBU_DEFINE(node_id, idx) \ - static uint8_t lbu_buffer_##idx[CONFIG_LOG_BACKEND_UART_BUFFER_SIZE]; \ - LOG_OUTPUT_DEFINE(lbu_output_##idx, char_out, lbu_buffer_##idx, \ +#define LBU_DEFINE(node_id, ...) \ + static uint8_t lbu_buffer##__VA_ARGS__[CONFIG_LOG_BACKEND_UART_BUFFER_SIZE]; \ + LOG_OUTPUT_DEFINE(lbu_output##__VA_ARGS__, char_out, lbu_buffer##__VA_ARGS__, \ CONFIG_LOG_BACKEND_UART_BUFFER_SIZE); \ \ - static struct lbu_data lbu_data_##idx = { \ + static struct lbu_data lbu_data##__VA_ARGS__ = { \ .log_format_current = CONFIG_LOG_BACKEND_UART_OUTPUT_DEFAULT, \ }; \ \ - static const struct lbu_cb_ctx lbu_cb_ctx_##idx = { \ - .output = &lbu_output_##idx, \ + static const struct lbu_cb_ctx lbu_cb_ctx##__VA_ARGS__ = { \ + .output = &lbu_output##__VA_ARGS__, \ .device = DEVICE_DT_GET(node_id), \ - .data = &lbu_data_##idx, \ + .data = &lbu_data##__VA_ARGS__, \ }; \ \ - LOG_BACKEND_DEFINE(log_backend_uart##idx, log_backend_uart_api, \ + LOG_BACKEND_DEFINE(log_backend_uart##__VA_ARGS__, log_backend_uart_api, \ IS_ENABLED(CONFIG_LOG_BACKEND_UART_AUTOSTART), \ - (void *)&lbu_cb_ctx_##idx); + (void *)&lbu_cb_ctx##__VA_ARGS__); #if DT_HAS_CHOSEN(zephyr_log_uart) #define LBU_PHA_FN(node_id, prop, idx) LBU_DEFINE(DT_PHANDLE_BY_IDX(node_id, prop, idx), idx) DT_FOREACH_PROP_ELEM_SEP(DT_CHOSEN(zephyr_log_uart), uarts, LBU_PHA_FN, ()); #else -LBU_DEFINE(DT_CHOSEN(zephyr_console), 0); +LBU_DEFINE(DT_CHOSEN(zephyr_console)); #endif From f5a27bcfe3ea37c391f349c8500f2c05f2d57a54 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 14 Nov 2023 13:18:22 +0800 Subject: [PATCH 3605/4498] tests: logging: uart: increase test coverage The test should work on any boards with UART console, so increase the test coverage by adding `CONFIG_UART_CONSOLE` filter and using `qemu_x86` as `integration_platforms` instead of `platform_allow`. Signed-off-by: Yong Cong Sin --- tests/subsys/logging/log_backend_uart/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/subsys/logging/log_backend_uart/testcase.yaml b/tests/subsys/logging/log_backend_uart/testcase.yaml index 70eb49920f1..05a4626ba62 100644 --- a/tests/subsys/logging/log_backend_uart/testcase.yaml +++ b/tests/subsys/logging/log_backend_uart/testcase.yaml @@ -6,7 +6,9 @@ common: - logging - backend - uart - platform_allow: qemu_x86 + filter: CONFIG_UART_CONSOLE + integration_platforms: + - qemu_x86 tests: logging.backend.uart.single: extra_args: DTC_OVERLAY_FILE="./single.overlay" From 2049aa8d16a891cbb2684d28599a0639734e4307 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 14 Nov 2023 14:21:35 +0800 Subject: [PATCH 3606/4498] logging: backend: uart: variable shouldn't have the same name as struct Rename the `device` variable in the `struct lbu_cb_ctx` to `uart_dev`, as it is a convention in Zephyr to not have the struct variable name after the struct. Signed-off-by: Yong Cong Sin --- subsys/logging/backends/log_backend_uart.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/logging/backends/log_backend_uart.c b/subsys/logging/backends/log_backend_uart.c index fbfdcc365a6..869ba869e75 100644 --- a/subsys/logging/backends/log_backend_uart.c +++ b/subsys/logging/backends/log_backend_uart.c @@ -28,7 +28,7 @@ struct lbu_data { struct lbu_cb_ctx { const struct log_output *output; - const struct device *device; + const struct device *uart_dev; struct lbu_data *data; }; @@ -78,7 +78,7 @@ static int char_out(uint8_t *data, size_t length, void *ctx) int err; const struct lbu_cb_ctx *cb_ctx = ctx; struct lbu_data *lb_data = cb_ctx->data; - const struct device *uart_dev = cb_ctx->device; + const struct device *uart_dev = cb_ctx->uart_dev; if (pm_device_runtime_is_enabled(uart_dev) && !k_is_in_isr()) { if (pm_device_runtime_get(uart_dev) < 0) { @@ -142,7 +142,7 @@ static int format_set(const struct log_backend *const backend, uint32_t log_type static void log_backend_uart_init(struct log_backend const *const backend) { const struct lbu_cb_ctx *ctx = backend->cb->ctx; - const struct device *uart_dev = ctx->device; + const struct device *uart_dev = ctx->uart_dev; struct lbu_data *data = ctx->data; __ASSERT_NO_MSG(device_is_ready(uart_dev)); @@ -180,7 +180,7 @@ static void panic(struct log_backend const *const backend) { const struct lbu_cb_ctx *ctx = backend->cb->ctx; struct lbu_data *data = ctx->data; - const struct device *uart_dev = ctx->device; + const struct device *uart_dev = ctx->uart_dev; /* Ensure that the UART device is in active mode */ #if defined(CONFIG_PM_DEVICE_RUNTIME) @@ -238,7 +238,7 @@ const struct log_backend_api log_backend_uart_api = { \ static const struct lbu_cb_ctx lbu_cb_ctx##__VA_ARGS__ = { \ .output = &lbu_output##__VA_ARGS__, \ - .device = DEVICE_DT_GET(node_id), \ + .uart_dev = DEVICE_DT_GET(node_id), \ .data = &lbu_data##__VA_ARGS__, \ }; \ \ From aa71ed4a1f556c03c4b1f5a8ffd1c8b0685881d1 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 14 Nov 2023 14:36:50 +0800 Subject: [PATCH 3607/4498] logging: backend: uart: compile the `uart_dev` pointer conditionally Compile the `uart_dev` pointer only when necessary (when `zephyr,log-uart` is used), this saves 4 bytes in 32-bit systems and 8 bytes in 64-bit systems. Signed-off-by: Yong Cong Sin --- subsys/logging/backends/log_backend_uart.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/subsys/logging/backends/log_backend_uart.c b/subsys/logging/backends/log_backend_uart.c index 869ba869e75..46fa12b92e1 100644 --- a/subsys/logging/backends/log_backend_uart.c +++ b/subsys/logging/backends/log_backend_uart.c @@ -28,10 +28,16 @@ struct lbu_data { struct lbu_cb_ctx { const struct log_output *output; +#if DT_HAS_CHOSEN(zephyr_log_uart) const struct device *uart_dev; +#endif struct lbu_data *data; }; +#define LBU_UART_DEV(ctx) \ + COND_CODE_1(DT_HAS_CHOSEN(zephyr_log_uart), (ctx->uart_dev), \ + (DEVICE_DT_GET(DT_CHOSEN(zephyr_console)))) + /* Fixed size to avoid auto-added trailing '\0'. * Used if CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX. */ @@ -78,7 +84,7 @@ static int char_out(uint8_t *data, size_t length, void *ctx) int err; const struct lbu_cb_ctx *cb_ctx = ctx; struct lbu_data *lb_data = cb_ctx->data; - const struct device *uart_dev = cb_ctx->uart_dev; + const struct device *uart_dev = LBU_UART_DEV(cb_ctx); if (pm_device_runtime_is_enabled(uart_dev) && !k_is_in_isr()) { if (pm_device_runtime_get(uart_dev) < 0) { @@ -142,7 +148,7 @@ static int format_set(const struct log_backend *const backend, uint32_t log_type static void log_backend_uart_init(struct log_backend const *const backend) { const struct lbu_cb_ctx *ctx = backend->cb->ctx; - const struct device *uart_dev = ctx->uart_dev; + const struct device *uart_dev = LBU_UART_DEV(ctx); struct lbu_data *data = ctx->data; __ASSERT_NO_MSG(device_is_ready(uart_dev)); @@ -180,7 +186,7 @@ static void panic(struct log_backend const *const backend) { const struct lbu_cb_ctx *ctx = backend->cb->ctx; struct lbu_data *data = ctx->data; - const struct device *uart_dev = ctx->uart_dev; + const struct device *uart_dev = LBU_UART_DEV(ctx); /* Ensure that the UART device is in active mode */ #if defined(CONFIG_PM_DEVICE_RUNTIME) @@ -238,7 +244,8 @@ const struct log_backend_api log_backend_uart_api = { \ static const struct lbu_cb_ctx lbu_cb_ctx##__VA_ARGS__ = { \ .output = &lbu_output##__VA_ARGS__, \ - .uart_dev = DEVICE_DT_GET(node_id), \ + COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), (), \ + (.uart_dev = DEVICE_DT_GET(node_id),)) \ .data = &lbu_data##__VA_ARGS__, \ }; \ \ From 56f73bde0fb086fae38cfb5afb2f2500a340b39b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 14 Nov 2023 22:01:15 +0000 Subject: [PATCH 3608/4498] ci: testplan: fix mcumgr path fix path for mcumgr in tags.yaml, we were skipping tests due to wrong path. Signed-off-by: Anas Nashif --- scripts/ci/tags.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/tags.yaml b/scripts/ci/tags.yaml index b9152b10d68..f66745fb208 100644 --- a/scripts/ci/tags.yaml +++ b/scripts/ci/tags.yaml @@ -72,7 +72,7 @@ cmsis_dsp: mcumgr: files: - - subsys/mcumgr/ + - subsys/mgmt/mcumgr/ - tests/subsys/mgmt/mcumgr/ - samples/subsys/mgmt/mcumgr/ - include/zephyr/mgmt/mcumgr/ From 1200fce75c6396fe6138659e802f92d43365259c Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 13 Nov 2023 14:28:07 -0800 Subject: [PATCH 3609/4498] drivers: i2s: mcux_flexcomm: Change LOG_INF to LOG_DBG in init Reduce log verboseness during init. Signed-off-by: Mike J. Chen --- drivers/i2s/i2s_mcux_flexcomm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2s/i2s_mcux_flexcomm.c b/drivers/i2s/i2s_mcux_flexcomm.c index d1dda99a5f2..4155bd24b62 100644 --- a/drivers/i2s/i2s_mcux_flexcomm.c +++ b/drivers/i2s/i2s_mcux_flexcomm.c @@ -901,7 +901,7 @@ static int i2s_mcux_init(const struct device *dev) data->tx.state = I2S_STATE_NOT_READY; data->rx.state = I2S_STATE_NOT_READY; - LOG_INF("Device %s inited", dev->name); + LOG_DBG("Device %s inited", dev->name); return 0; } From 5fee1b17d5deef03bd1064215280da69603a91ef Mon Sep 17 00:00:00 2001 From: MD Peace Date: Wed, 15 Nov 2023 11:52:09 +1100 Subject: [PATCH 3610/4498] drivers: gnss: Fix typo in __ASSERT statement str is being checking the __ASSERT where nano should be being checked Signed-off-by: MD Peace --- drivers/gnss/gnss_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gnss/gnss_parse.c b/drivers/gnss/gnss_parse.c index 5cde6a630a9..29808dd74f2 100644 --- a/drivers/gnss/gnss_parse.c +++ b/drivers/gnss/gnss_parse.c @@ -26,7 +26,7 @@ int gnss_parse_dec_to_nano(const char *str, int64_t *nano) int64_t increment; __ASSERT(str != NULL, "str argument must be provided"); - __ASSERT(str != NULL, "nano argument must be provided"); + __ASSERT(nano != NULL, "nano argument must be provided"); /* Find decimal */ while (str[pos] != '\0') { From 5c6402e76b5b775700b4ff6d75198e1a51a68623 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Tue, 14 Nov 2023 15:11:27 +0100 Subject: [PATCH 3611/4498] drivers: ieee802154: add `IEEE802154_RX_ON_WHEN_IDLE` capability Introduce `IEEE802154_RX_ON_WHEN_IDLE` capability. Signed-off-by: Eduardo Montoya --- include/zephyr/net/ieee802154_radio.h | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 71519dfe839..59608fac391 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -515,13 +515,16 @@ enum ieee802154_hw_caps { /** TX security supported (key management, encryption and authentication) */ IEEE802154_HW_TX_SEC = BIT(11), + /** RxOnWhenIdle handling supported */ + IEEE802154_RX_ON_WHEN_IDLE = BIT(12), + /* Note: Update also IEEE802154_HW_CAPS_BITS_COMMON_COUNT when changing * the ieee802154_hw_caps type. */ }; /** @brief Number of bits used by ieee802154_hw_caps type. */ -#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (12) +#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (13) /** @brief This and higher values are specific to the protocol- or driver-specific extensions. */ #define IEEE802154_HW_CAPS_BITS_PRIV_START IEEE802154_HW_CAPS_BITS_COMMON_COUNT @@ -1057,6 +1060,35 @@ enum ieee802154_config_type { */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, + /** + * Enable/disable RxOnWhenIdle MAC PIB attribute (Table 8-94). + * + * Since there is no clear guidance in IEEE 802.15.4 specification about the definition of + * an "idle period", this implementation expects that drivers use the RxOnWhenIdle attribute + * to determine next radio state (false --> off, true --> receive) in the following + * scenarios: + * - Finalization of a regular frame reception task, provided that: + * - The frame is received without errors and passes the filtering and it's not an + * spurious ACK. + * - ACK is not requested or transmission of ACK is not possible due to internal + * conditions. + * - Finalization of a frame transmission or transmission of an ACK frame, when ACK is not + * requested in the transmitted frame. + * - Finalization of the reception operation of a requested ACK due to: + * - ACK timeout expiration. + * - Reception of an invalid ACK or not an ACK frame. + * - Reception of the proper ACK, unless the transmitted frame was a Data Request Command + * and the frame pending bit on the received ACK is set to true. In this case the radio + * platform implementation SHOULD keep the receiver on until a determined timeout which + * triggers an idle period start. + * - Finalization of a stand alone CCA task. + * - Finalization of a CCA operation with busy result during CSMA/CA procedure. + * - Finalization of an Energy Detection task. + * - Finalization of a scheduled radio reception window + * (see @ref IEEE802154_CONFIG_RX_SLOT). + */ + IEEE802154_CONFIG_RX_ON_WHEN_IDLE, + /** Number of types defined in ieee802154_config_type. */ IEEE802154_CONFIG_COMMON_COUNT, @@ -1103,6 +1135,9 @@ struct ieee802154_config { /** see @ref IEEE802154_CONFIG_PROMISCUOUS */ bool promiscuous; + /** see @ref IEEE802154_CONFIG_RX_ON_WHEN_IDLE */ + bool rx_on_when_idle; + /** see @ref IEEE802154_CONFIG_EVENT_HANDLER */ ieee802154_event_cb_t event_handler; From b406024148e8619188c72a77cf3d523794af19b2 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Tue, 14 Nov 2023 14:57:02 +0100 Subject: [PATCH 3612/4498] net: openthread: implement `otPlatRadioSetRxOnWhenIdle` OpenThread upmerge to commit `193e77e`. Implement `otPlatRadioSetRxOnWhenIdle` radio platform API. Signed-off-by: Eduardo Montoya --- modules/openthread/platform/radio.c | 17 +++++++++++++++++ west.yml | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 391ffba395d..9c5de3c9d69 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -890,9 +890,26 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) caps |= OT_RADIO_CAPS_RECEIVE_TIMING; } + if (radio_caps & IEEE802154_RX_ON_WHEN_IDLE) { + caps |= OT_RADIO_CAPS_RX_ON_WHEN_IDLE; + } + return caps; } +void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aRxOnWhenIdle) +{ + struct ieee802154_config config = { + .rx_on_when_idle = aRxOnWhenIdle + }; + + ARG_UNUSED(aInstance); + + LOG_DBG("RxOnWhenIdle=%d", aRxOnWhenIdle ? 1 : 0); + + radio_api->configure(radio_dev, IEEE802154_CONFIG_RX_ON_WHEN_IDLE, &config); +} + bool otPlatRadioGetPromiscuous(otInstance *aInstance) { ARG_UNUSED(aInstance); diff --git a/west.yml b/west.yml index f7b40860645..3c50603e8c8 100644 --- a/west.yml +++ b/west.yml @@ -301,7 +301,7 @@ manifest: revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread - revision: 6edb06e4e0472411200ce2a084a783eaf3faffe3 + revision: 193e77e40ec2387d458eaebd1e03902d86f484a5 path: modules/lib/openthread - name: percepio path: modules/debug/percepio From 909c087521ce435a30ea74811f5c43211ce39334 Mon Sep 17 00:00:00 2001 From: Patryk Lipinski Date: Mon, 13 Nov 2023 15:13:27 +0100 Subject: [PATCH 3613/4498] fs: Changes in the macro statements Changes in the macro statements that allows to build with -Wudef flag enebaled, without errors. Signed-off-by: Patryk Lipinski --- include/zephyr/fs/fs_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/fs/fs_interface.h b/include/zephyr/fs/fs_interface.h index 2692ea168a7..5db637635b9 100644 --- a/include/zephyr/fs/fs_interface.h +++ b/include/zephyr/fs/fs_interface.h @@ -13,7 +13,7 @@ extern "C" { #endif -#if (CONFIG_FILE_SYSTEM_MAX_FILE_NAME - 0) > 0 +#if defined(CONFIG_FILE_SYSTEM_MAX_FILE_NAME) && (CONFIG_FILE_SYSTEM_MAX_FILE_NAME - 0) > 0 #define MAX_FILE_NAME CONFIG_FILE_SYSTEM_MAX_FILE_NAME #else /* CONFIG_FILE_SYSTEM_MAX_FILE_NAME */ From 4a522114329b5b0356e0e4b8f7bdf2e86a0c67e0 Mon Sep 17 00:00:00 2001 From: Patryk Lipinski Date: Mon, 13 Nov 2023 15:15:49 +0100 Subject: [PATCH 3614/4498] logging: Changes in the macro statements Changes in the macro statements that allows to build with -Wudef flag enebaled, without errors. Signed-off-by: Patryk Lipinski --- include/zephyr/logging/log_msg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index c04b00cdd98..c35a69d85cc 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -79,7 +79,7 @@ struct log_msg_hdr { const void *source; log_timestamp_t timestamp; #endif -#if CONFIG_LOG_THREAD_ID_PREFIX +#if defined(CONFIG_LOG_THREAD_ID_PREFIX) void *tid; #endif }; @@ -807,7 +807,7 @@ static inline log_timestamp_t log_msg_get_timestamp(struct log_msg *msg) */ static inline void *log_msg_get_tid(struct log_msg *msg) { -#if CONFIG_LOG_THREAD_ID_PREFIX +#if defined(CONFIG_LOG_THREAD_ID_PREFIX) return msg->hdr.tid; #else ARG_UNUSED(msg); From 14827aad6526985d02dc17737cbff8dd710da3ac Mon Sep 17 00:00:00 2001 From: Patryk Lipinski Date: Mon, 13 Nov 2023 15:16:26 +0100 Subject: [PATCH 3615/4498] modules: hal_nordic: nrfx_glue: Changes in the macro statements Changes in the macro statements that allows to build with -Wudef flag enebaled, without errors. Signed-off-by: Patryk Lipinski --- modules/hal_nordic/nrfx/nrfx_glue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_nordic/nrfx/nrfx_glue.h b/modules/hal_nordic/nrfx/nrfx_glue.h index 786004c05c3..2257ea879a3 100644 --- a/modules/hal_nordic/nrfx/nrfx_glue.h +++ b/modules/hal_nordic/nrfx/nrfx_glue.h @@ -357,7 +357,7 @@ void nrfx_busy_wait(uint32_t usec_to_wait); #define NRFX_PPI_GROUPS_USED_BY_MPSL 0 #endif -#if NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL +#if defined(NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL) BUILD_ASSERT( (NRFX_PPI_CHANNELS_USED_BY_802154_DRV & NRFX_PPI_CHANNELS_USED_BY_MPSL) == 0, "PPI channels used by the IEEE802.15.4 radio driver overlap with those " From 2deea4eeeec18eb880682f3d0c50d0e5a8e111fc Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 25 Oct 2023 04:54:52 +0100 Subject: [PATCH 3616/4498] twister: Fix failure on MacOS On MacOS, ps utils raises a `NoSuchProcess` error rather than a `ProcessLookupError` when a pid no longer exists. Signed-off-by: Wilfried Chauveau --- .../src/twister_harness/device/utils.py | 2 +- scripts/pylib/twister/twisterlib/handlers.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/utils.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/utils.py index 5b89d1ad7a8..60ee2537bb8 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/utils.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/utils.py @@ -44,7 +44,7 @@ def terminate_process(proc: subprocess.Popen) -> None: for child in psutil.Process(proc.pid).children(recursive=True): try: os.kill(child.pid, signal.SIGTERM) - except ProcessLookupError: + except (ProcessLookupError, psutil.NoSuchProcess): pass proc.terminate() # sleep for a while before attempting to kill diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index a39e68741aa..3c6498a6ea4 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -56,7 +56,7 @@ def terminate_process(proc): for child in psutil.Process(proc.pid).children(recursive=True): try: os.kill(child.pid, signal.SIGTERM) - except ProcessLookupError: + except (ProcessLookupError, psutil.NoSuchProcess): pass proc.terminate() # sleep for a while before attempting to kill @@ -182,7 +182,7 @@ def try_kill_process_by_pid(self): self.pid_fn = None # clear so we don't try to kill the binary twice try: os.kill(pid, signal.SIGKILL) - except ProcessLookupError: + except (ProcessLookupError, psutil.NoSuchProcess): pass def _output_reader(self, proc): @@ -805,7 +805,7 @@ def _thread_close_files(fifo_in, fifo_out, pid, out_fp, in_fp, log_out_fp): try: if pid: os.kill(pid, signal.SIGTERM) - except ProcessLookupError: + except (ProcessLookupError, psutil.NoSuchProcess): # Oh well, as long as it's dead! User probably sent Ctrl-C pass @@ -864,6 +864,8 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, if cpu_time < timeout and not out_state: timeout_time = time.time() + (timeout - cpu_time) continue + except psutil.NoSuchProcess: + pass except ProcessLookupError: out_state = "failed" break From 321c5e865665eb7c843db5cdb111b9b5ff0d9e07 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 23 Mar 2023 08:53:27 +0100 Subject: [PATCH 3617/4498] drivers: entropy: stm32: Move irq_lock at init Perform clock check inside irq_lock in order to exit cleanly if failing. Signed-off-by: Erwan Gouriou --- drivers/entropy/entropy_stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 3dd8f82e8a5..0abedb1940c 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -235,6 +235,8 @@ static int random_byte_get(void) unsigned int key; RNG_TypeDef *rng = entropy_stm32_rng_data.rng; + key = irq_lock(); + if (IS_ENABLED(CONFIG_ENTROPY_STM32_CLK_CHECK) && !k_is_pre_kernel()) { /* CECS bit signals that a clock configuration issue is detected, * which may lead to generation of non truly random data. @@ -244,8 +246,6 @@ static int random_byte_get(void) "\tSee ref man and update target clock configuration."); } - key = irq_lock(); - if (LL_RNG_IsActiveFlag_SEIS(rng) && (recover_seed_error(rng) < 0)) { retval = -EIO; goto out; From 8ed4876bed99314ee20a46394532b5b2675cfa37 Mon Sep 17 00:00:00 2001 From: Greter Raffael Date: Thu, 9 Nov 2023 10:34:46 +0000 Subject: [PATCH 3618/4498] tests: kernel: also move the test_isr_dynamic to new ztest API `test_isr_dynamic` for `CONFIG_GEN_SW_ISR_TABLE=n` was somehow overlooked in commit b7f1e9872495ee29d223cd7b5c2f8fb5eceab2cd. I'm disabling the irq at the end of the test. The babblesim for the `nrf5340bsim_*` target walked into a timeout otherwise. Signed-off-by: Greter Raffael --- tests/kernel/interrupt/src/dynamic_isr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/kernel/interrupt/src/dynamic_isr.c b/tests/kernel/interrupt/src/dynamic_isr.c index 35f42220fb8..d697fda32e8 100644 --- a/tests/kernel/interrupt/src/dynamic_isr.c +++ b/tests/kernel/interrupt/src/dynamic_isr.c @@ -73,7 +73,7 @@ ZTEST(interrupt_feature, test_isr_dynamic) #define TEST_IRQ_DYN_LINE 5 #endif -void test_isr_dynamic(void) +ZTEST(interrupt_feature, test_isr_dynamic) { int vector_num; @@ -118,5 +118,6 @@ extern const void *x86_irq_args[]; "interrupt triggered but handler has not run(%d)", handler_has_run); + irq_disable(TEST_IRQ_DYN_LINE); } #endif /* CONFIG_GEN_SW_ISR_TABLE */ From 7029c79ef250b28ed1710e6cb7ae6a33daae8933 Mon Sep 17 00:00:00 2001 From: Paszkiet Kamil Date: Thu, 9 Nov 2023 13:41:55 +0100 Subject: [PATCH 3619/4498] scripts: tests: twister_blackbox: Add test test_hardwaremap.py add tests to hardwaremap tests: - generate_hardware_map (different ways) Signed-off-by: Paszkiet Kamil --- .../twister_blackbox/test_hardwaremap.py | 301 ++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 scripts/tests/twister_blackbox/test_hardwaremap.py diff --git a/scripts/tests/twister_blackbox/test_hardwaremap.py b/scripts/tests/twister_blackbox/test_hardwaremap.py new file mode 100644 index 00000000000..c5dbd990377 --- /dev/null +++ b/scripts/tests/twister_blackbox/test_hardwaremap.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +""" +Blackbox tests for twister's command line functions +""" +import logging +import importlib +import mock +import os +import pytest +import sys + +from conftest import ZEPHYR_BASE, testsuite_filename_mock +from twisterlib.testplan import TestPlan + +sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister/twisterlib")) + +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +class TestHardwaremap: + TESTDATA_1 = [ + ( + [ + 'ARM', + 'SEGGER', + 'MBED' + ], + [ + 'DAPLink CMSIS-DAP', + 'MBED CMSIS-DAP' + ], + [1234, 'abcd'], + 'pyocd' + ), + ( + [ + 'STMicroelectronics', + 'Atmel Corp.' + ], + [ + 'J-Link', + 'J-Link OB' + ], + [1234, 'abcd'], + 'jlink' + ), + ( + [ + 'Silicon Labs', + 'NXP Semiconductors', + 'Microchip Technology Inc.' + ], + [ + 'STM32 STLink', + '^XDS110.*', + 'STLINK-V3' + ], + [1234, 'abcd'], + 'openocd' + ), + ( + [ + 'FTDI', + 'Digilent', + 'Microsoft' + ], + [ + 'TTL232R-3V3', + 'MCP2200 USB Serial Port Emulator' + ], + [1234, 'abcd'], + 'dediprog' + ) + ] + TESTDATA_2 = [ + ( + 'FTDI', + 'DAPLink CMSIS-DAP', + 1234, + 'pyocd' + ) + ] + TESTDATA_3 = [ + ( + 'Texas Instruments', + 'DAPLink CMSIS-DAP', + 'abcd', 'las' + ), + ( + 'Texas Instruments', + 'DAPLink CMSIS-DAP', + 'abcd', 'dse0' + ) + ] + + @classmethod + def setup_class(cls): + apath = os.path.join(ZEPHYR_BASE, 'scripts', 'twister') + cls.loader = importlib.machinery.SourceFileLoader('__main__', apath) + cls.spec = importlib.util.spec_from_loader(cls.loader.name, cls.loader) + cls.twister_module = importlib.util.module_from_spec(cls.spec) + + @classmethod + def teardown_class(cls): + pass + + @pytest.mark.usefixtures("clear_log") + @pytest.mark.parametrize( + ('manufacturer', 'product', 'serial', 'runner'), + TESTDATA_1, + ) + def test_generate(self, capfd, manufacturer, product, serial, runner): + file_name = "test-map.yaml" + path = os.path.join(ZEPHYR_BASE, file_name) + args = ['--generate-hardware-map', file_name] + + if os.path.exists(path): + os.remove(path) + + def mocked_comports(): + return [ + mock.Mock(device='/dev/ttyUSB23', + manufacturer=id_man, + product=id_pro, + serial_number=id_serial + ) + ] + + for id_man in manufacturer: + for id_pro in product: + for id_serial in serial: + with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ + mock.patch('serial.tools.list_ports.comports', + side_effect=mocked_comports), \ + pytest.raises(SystemExit) as sys_exit: + self.loader.exec_module(self.twister_module) + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert os.path.exists(path) + + expected_data = '- connected: true\n' \ + f' id: {id_serial}\n' \ + ' platform: unknown\n' \ + f' product: {id_pro}\n' \ + f' runner: {runner}\n' \ + ' serial: /dev/ttyUSB23\n' + + load_data = open(path).read() + assert load_data == expected_data + + if os.path.exists(path): + os.remove(path) + + assert str(sys_exit.value) == '0' + loggers = [logging.getLogger()] + \ + list(logging.Logger.manager.loggerDict.values()) + \ + [logging.getLogger(name) for \ + name in logging.root.manager.loggerDict] + for logger in loggers: + handlers = getattr(logger, 'handlers', []) + for handler in handlers: + logger.removeHandler(handler) + + @pytest.mark.usefixtures("clear_log") + @pytest.mark.parametrize( + ('manufacturer', 'product', 'serial', 'runner'), + TESTDATA_2, + ) + def test_few_generate(self, capfd, manufacturer, product, serial, runner): + file_name = "test-map.yaml" + path = os.path.join(ZEPHYR_BASE, file_name) + args = ['--generate-hardware-map', file_name] + + if os.path.exists(path): + os.remove(path) + + def mocked_comports(): + return [ + mock.Mock(device='/dev/ttyUSB23', + manufacturer=manufacturer, + product=product, + serial_number=serial + ), + mock.Mock(device='/dev/ttyUSB24', + manufacturer=manufacturer, + product=product, + serial_number=serial + 1 + ), + mock.Mock(device='/dev/ttyUSB24', + manufacturer=manufacturer, + product=product, + serial_number=serial + 2 + ), + mock.Mock(device='/dev/ttyUSB25', + manufacturer=manufacturer, + product=product, + serial_number=serial + 3 + ) + ] + + with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ + mock.patch('serial.tools.list_ports.comports', + side_effect=mocked_comports), \ + pytest.raises(SystemExit) as sys_exit: + self.loader.exec_module(self.twister_module) + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert os.path.exists(path) + + expected_data = '- connected: true\n' \ + f' id: {serial}\n' \ + ' platform: unknown\n' \ + f' product: {product}\n' \ + f' runner: {runner}\n' \ + ' serial: /dev/ttyUSB23\n' \ + '- connected: true\n' \ + f' id: {serial + 1}\n' \ + ' platform: unknown\n' \ + f' product: {product}\n' \ + f' runner: {runner}\n' \ + ' serial: /dev/ttyUSB24\n' \ + '- connected: true\n' \ + f' id: {serial + 2}\n' \ + ' platform: unknown\n' \ + f' product: {product}\n' \ + f' runner: {runner}\n' \ + ' serial: /dev/ttyUSB24\n' \ + '- connected: true\n' \ + f' id: {serial + 3}\n' \ + ' platform: unknown\n' \ + f' product: {product}\n' \ + f' runner: {runner}\n' \ + ' serial: /dev/ttyUSB25\n' + + load_data = open(path).read() + assert load_data == expected_data + + if os.path.exists(path): + os.remove(path) + + assert str(sys_exit.value) == '0' + + @pytest.mark.usefixtures("clear_log") + @pytest.mark.parametrize( + ('manufacturer', 'product', 'serial', 'location'), + TESTDATA_3, + ) + def test_texas_exeption(self, capfd, manufacturer, product, serial, location): + file_name = "test-map.yaml" + path = os.path.join(ZEPHYR_BASE, file_name) + args = ['--generate-hardware-map', file_name] + + if os.path.exists(path): + os.remove(path) + + def mocked_comports(): + return [ + mock.Mock(device='/dev/ttyUSB23', + manufacturer=manufacturer, + product=product, + serial_number=serial, + location=location + ) + ] + + with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ + mock.patch('serial.tools.list_ports.comports', + side_effect=mocked_comports), \ + pytest.raises(SystemExit) as sys_exit: + self.loader.exec_module(self.twister_module) + + out, err = capfd.readouterr() + sys.stdout.write(out) + sys.stderr.write(err) + + assert os.path.exists(path) + + expected_data = '- connected: true\n' \ + f' id: {serial}\n' \ + ' platform: unknown\n' \ + f' product: {product}\n' \ + ' runner: pyocd\n' \ + ' serial: /dev/ttyUSB23\n' + expected_data2 = '[]\n' + + load_data = open(path).read() + if location.endswith('0'): + assert load_data == expected_data + else: + assert load_data == expected_data2 + if os.path.exists(path): + os.remove(path) + + assert str(sys_exit.value) == '0' From 1f4dacad08e859ea5ad82dc3f7d99ea753019b05 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 10 Nov 2023 10:48:28 +0800 Subject: [PATCH 3620/4498] Bluetooth: Mesh: Remove relay sets config for adv Separate queue should also used for lagecy adv, due to when local queue has adv buf, k_poll will process local queue. Signed-off-by: Lingao Meng --- subsys/bluetooth/mesh/adv.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index b24523aacf3..548e7f3fe15 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -157,7 +157,6 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, tag, xmit, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE static struct net_buf *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { @@ -186,12 +185,15 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) K_POLL_MODE_NOTIFY_ONLY, &bt_mesh_adv_queue, 0), -#if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) +#if defined(CONFIG_BT_MESH_RELAY) && \ + (defined(CONFIG_BT_MESH_ADV_LEGACY) || \ + defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) || \ + !(CONFIG_BT_MESH_RELAY_ADV_SETS)) K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &bt_mesh_relay_queue, 0), -#endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ +#endif }; err = k_poll(events, ARRAY_SIZE(events), timeout); @@ -209,27 +211,13 @@ struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_time return net_buf_get(&bt_mesh_friend_queue, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS - if (!(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { + if (IS_ENABLED(CONFIG_BT_MESH_RELAY) && + !(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { return net_buf_get(&bt_mesh_relay_queue, timeout); } -#endif return bt_mesh_adv_buf_get(timeout); } -#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ -struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) -{ - return net_buf_get(&bt_mesh_adv_queue, timeout); -} - -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) -{ - ARG_UNUSED(tags); - - return bt_mesh_adv_buf_get(timeout); -} -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ void bt_mesh_adv_buf_get_cancel(void) { @@ -237,9 +225,9 @@ void bt_mesh_adv_buf_get_cancel(void) k_fifo_cancel_wait(&bt_mesh_adv_queue); -#if CONFIG_BT_MESH_RELAY_ADV_SETS - k_fifo_cancel_wait(&bt_mesh_relay_queue); -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ + if (IS_ENABLED(CONFIG_BT_MESH_RELAY)) { + k_fifo_cancel_wait(&bt_mesh_relay_queue); + } if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { k_fifo_cancel_wait(&bt_mesh_friend_queue); @@ -267,15 +255,14 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, return; } -#if CONFIG_BT_MESH_RELAY_ADV_SETS - if (BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY || + if ((IS_ENABLED(CONFIG_BT_MESH_RELAY) && + BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY) || (IS_ENABLED(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) && BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV)) { net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); bt_mesh_adv_buf_relay_ready(); return; } -#endif net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf)); bt_mesh_adv_buf_local_ready(); From e1d4451976b925ae0daacacce44e782daae98d64 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 10 Nov 2023 14:36:57 +0800 Subject: [PATCH 3621/4498] bsim: bluetooth: mesh: Increase Net Transmit Count value on the node This is to increase probability of reception of responses (Config Status messages) from the node when the provisioner sends a Set message and the node response with a Status message at the same time so that the message collide. Signed-off-by: Lingao Meng --- tests/bsim/bluetooth/mesh/src/test_provision.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 54258746524..24e1f627382 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -1572,6 +1572,9 @@ static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_sim { uint8_t page_rsp; + /* Let complete advertising of the transaction to prevent collisions. */ + k_sleep(K_SECONDS(3)); + net_buf_simple_reset(comp); ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page, &page_rsp, comp)); ASSERT_EQUAL(page, page_rsp); From 4c33323c056f47119630acd39370c1bff4681663 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 10 Nov 2023 12:34:33 +0100 Subject: [PATCH 3622/4498] drivers: can: shell: add support for setting raw timing values Add support for setting raw timing values. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_shell.c | 105 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index 4faf11aae4e..46dac3fb06a 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -519,6 +519,102 @@ static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv return 0; } +static int can_shell_parse_timing(const struct shell *sh, size_t argc, char **argv, + struct can_timing *timing) +{ + char *endptr; + + timing->sjw = (uint32_t)strtoul(argv[2], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse sjw"); + return -EINVAL; + } + + timing->prop_seg = (uint32_t)strtoul(argv[3], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse prop_seg"); + return -EINVAL; + } + + timing->phase_seg1 = (uint32_t)strtoul(argv[4], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse phase_seg1"); + return -EINVAL; + } + + timing->phase_seg2 = (uint32_t)strtoul(argv[5], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse phase_seg2"); + return -EINVAL; + } + + timing->prescaler = (uint32_t)strtoul(argv[6], &endptr, 10); + if (*endptr != '\0') { + shell_error(sh, "failed to parse prescaler"); + return -EINVAL; + } + + return 0; +} + +static int cmd_can_timing_set(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev = device_get_binding(argv[1]); + struct can_timing timing = { 0 }; + int err; + + if (!device_is_ready(dev)) { + shell_error(sh, "device %s not ready", argv[1]); + return -ENODEV; + } + + err = can_shell_parse_timing(sh, argc, argv, &timing); + if (err < 0) { + return err; + } + + shell_print(sh, "setting timing to sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, " + "prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1, + timing.phase_seg2, timing.prescaler); + + err = can_set_timing(dev, &timing); + if (err != 0) { + shell_error(sh, "failed to set timing (err %d)", err); + return err; + } + + return 0; +} + +static int cmd_can_dtiming_set(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev = device_get_binding(argv[1]); + struct can_timing timing = { 0 }; + int err; + + if (!device_is_ready(dev)) { + shell_error(sh, "device %s not ready", argv[1]); + return -ENODEV; + } + + err = can_shell_parse_timing(sh, argc, argv, &timing); + if (err < 0) { + return err; + } + + shell_print(sh, "setting data phase timing to sjw %u, prop_seg %u, phase_seg1 %u, " + "phase_seg2 %u, prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1, + timing.phase_seg2, timing.prescaler); + + err = can_set_timing_data(dev, &timing); + if (err != 0) { + shell_error(sh, "failed to set data phase timing (err %d)", err); + return err; + } + + return 0; +} + static int cmd_can_mode_set(const struct shell *sh, size_t argc, char **argv) { const struct device *dev = device_get_binding(argv[1]); @@ -942,6 +1038,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_cmds, "Set CAN controller data phase bitrate (sample point and SJW optional)\n" "Usage: can dbitrate [sample point] [sjw]", cmd_can_dbitrate_set, 3, 2), + SHELL_CMD_ARG(timing, &dsub_can_device_name, + "Set CAN controller timing\n" + "Usage: can timing ", + cmd_can_timing_set, 7, 0), + SHELL_COND_CMD_ARG(CONFIG_CAN_FD_MODE, + dtiming, &dsub_can_device_name, + "Set CAN controller data phase timing\n" + "Usage: can dtiming ", + cmd_can_dtiming_set, 7, 0), SHELL_CMD_ARG(mode, &dsub_can_device_name_mode, "Set CAN controller mode\n" "Usage: can mode [mode] [mode] [...]", From c56bfb9d06a909429070eace0286a6394e2b0ae6 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 10 Nov 2023 12:35:49 +0100 Subject: [PATCH 3623/4498] tests: drivers: can: shell: add tests for setting raw timing Add CAN shell tests for the "timing" and "dtiming" subcommands. Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/shell/src/main.c | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/drivers/can/shell/src/main.c b/tests/drivers/can/shell/src/main.c index 8b7ec053c5a..61bd80ec72f 100644 --- a/tests/drivers/can/shell/src/main.c +++ b/tests/drivers/can/shell/src/main.c @@ -206,6 +206,75 @@ ZTEST(can_shell, test_can_dbitrate_sample_point) can_shell_test_dbitrate("can dbitrate " FAKE_CAN_NAME " 1000000 875", 1000000, 875); } +ZTEST(can_shell, test_can_timing) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + struct can_timing expected = { + .sjw = 1U, + .prop_seg = 2U, + .phase_seg1 = 3U, + .phase_seg2 = 4U, + .prescaler = 5U, + }; + int err; + + fake_can_set_timing_fake.custom_fake = can_shell_test_capture_timing; + + err = shell_execute_cmd(sh, "can timing " FAKE_CAN_NAME " 1 2 3 4 5"); + zassert_ok(err, "failed to execute shell command (err %d)", err); + zassert_equal(fake_can_set_timing_fake.call_count, 1, "set_timing function not called"); + zassert_equal(fake_can_set_timing_fake.arg0_val, fake_can_dev, "wrong device pointer"); + assert_can_timing_equal(&expected, &timing_capture); +} + +ZTEST(can_shell, test_can_timing_missing_value) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int err; + + Z_TEST_SKIP_IFNDEF(CONFIG_CAN_FD_MODE); + + err = shell_execute_cmd(sh, "can timing " FAKE_CAN_NAME); + zassert_not_equal(err, 0, " executed shell command without timing"); + zassert_equal(fake_can_set_timing_fake.call_count, 0, + "set_timing function called"); +} + +ZTEST(can_shell, test_can_dtiming) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + struct can_timing expected = { + .sjw = 1U, + .prop_seg = 2U, + .phase_seg1 = 3U, + .phase_seg2 = 4U, + .prescaler = 5U, + }; + int err; + + fake_can_set_timing_data_fake.custom_fake = can_shell_test_capture_timing; + + err = shell_execute_cmd(sh, "can dtiming " FAKE_CAN_NAME " 1 2 3 4 5"); + zassert_ok(err, "failed to execute shell command (err %d)", err); + zassert_equal(fake_can_set_timing_data_fake.call_count, 1, + "set_timing_data function not called"); + zassert_equal(fake_can_set_timing_data_fake.arg0_val, fake_can_dev, "wrong device pointer"); + assert_can_timing_equal(&expected, &timing_capture); +} + +ZTEST(can_shell, test_can_dtiming_missing_value) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int err; + + Z_TEST_SKIP_IFNDEF(CONFIG_CAN_FD_MODE); + + err = shell_execute_cmd(sh, "can dtiming " FAKE_CAN_NAME); + zassert_not_equal(err, 0, " executed shell command without dtiming"); + zassert_equal(fake_can_set_timing_data_fake.call_count, 0, + "set_timing_data function called"); +} + ZTEST(can_shell, test_can_mode_missing_value) { const struct shell *sh = shell_backend_dummy_get_ptr(); From 63ceeb3bba7c113a4f3cb6b4cfdef4c4d42bdc5b Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Sat, 11 Nov 2023 14:38:54 -0300 Subject: [PATCH 3624/4498] soc: arm: st_stm32: add support for stm32h7b0xx and stm32h7b0xxQ Add Kconfig SoC configurations. Signed-off-by: Charles Dias --- .../stm32h7/Kconfig.defconfig.stm32h7b0xx | 15 +++++++++++++++ soc/arm/st_stm32/stm32h7/Kconfig.soc | 10 ++++++++++ 2 files changed, 25 insertions(+) create mode 100644 soc/arm/st_stm32/stm32h7/Kconfig.defconfig.stm32h7b0xx diff --git a/soc/arm/st_stm32/stm32h7/Kconfig.defconfig.stm32h7b0xx b/soc/arm/st_stm32/stm32h7/Kconfig.defconfig.stm32h7b0xx new file mode 100644 index 00000000000..10502135014 --- /dev/null +++ b/soc/arm/st_stm32/stm32h7/Kconfig.defconfig.stm32h7b0xx @@ -0,0 +1,15 @@ +# ST STM32H7B0XX MCU configuration options + +# Copyright (c) 2023 Charles Dias +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32H7B0XX || SOC_STM32H7B0XXQ + +config SOC + default "stm32h7b0xxQ" if SOC_STM32H7B0XXQ + default "stm32h7b0xx" if SOC_STM32H7B0XX + +config NUM_IRQS + default 155 + +endif # SOC_STM32H7B0XX || SOC_STM32H7B0XXQ diff --git a/soc/arm/st_stm32/stm32h7/Kconfig.soc b/soc/arm/st_stm32/stm32h7/Kconfig.soc index 46f101f0e14..7856c52652a 100644 --- a/soc/arm/st_stm32/stm32h7/Kconfig.soc +++ b/soc/arm/st_stm32/stm32h7/Kconfig.soc @@ -73,6 +73,16 @@ config SOC_STM32H7A3XXQ select CPU_CORTEX_M7 select CPU_HAS_FPU_DOUBLE_PRECISION +config SOC_STM32H7B0XX + bool "STM32H7B0XX" + select CPU_CORTEX_M7 + select CPU_HAS_FPU_DOUBLE_PRECISION + +config SOC_STM32H7B0XXQ + bool "STM32H7B0XXQ" + select CPU_CORTEX_M7 + select CPU_HAS_FPU_DOUBLE_PRECISION + config SOC_STM32H7B3XX bool "STM32H7B3XX" select CPU_CORTEX_M7 From de51fca769bb7e99a9b00fb8b8af954180d291af Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Sun, 12 Nov 2023 12:32:04 -0300 Subject: [PATCH 3625/4498] drivers: clock_control: define clock freq for STM32H7B0 Define max SYSCLK and AHB clock frequencies as 280 MHz, max APB frequency as 140 MHz, and enable semaphore clock. Signed-off-by: Charles Dias --- drivers/clock_control/clock_stm32_ll_h7.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index c95d8ab1294..dc9127d277d 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -107,6 +107,7 @@ #define AHB_FREQ_MAX 275000000UL #define APBx_FREQ_MAX 137500000UL #elif defined(CONFIG_SOC_STM32H7A3XX) || defined(CONFIG_SOC_STM32H7A3XXQ) ||\ + defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) ||\ defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ) #define SYSCLK_FREQ_MAX 280000000UL #define AHB_FREQ_MAX 280000000UL @@ -829,6 +830,7 @@ int stm32_clock_control_init(const struct device *dev) /* HW semaphore Clock enable */ #if defined(CONFIG_SOC_STM32H7A3XX) || defined(CONFIG_SOC_STM32H7A3XXQ) || \ + defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) || \ defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ) LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_HSEM); #else From d15f5bbcc72bbec26be448477d7c6fe647c66531 Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Sun, 12 Nov 2023 12:33:57 -0300 Subject: [PATCH 3626/4498] dts: arm: st: h7: add support for stm32h7b0 Add device tree support for STM32H7B0 line. Signed-off-by: Charles Dias --- dts/arm/st/h7/stm32h7b0.dtsi | 27 +++++++++++++++++++++++++++ dts/arm/st/h7/stm32h7b0Xb.dtsi | 17 +++++++++++++++++ dts/arm/st/h7/stm32h7b3.dtsi | 14 ++------------ 3 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 dts/arm/st/h7/stm32h7b0.dtsi create mode 100644 dts/arm/st/h7/stm32h7b0Xb.dtsi diff --git a/dts/arm/st/h7/stm32h7b0.dtsi b/dts/arm/st/h7/stm32h7b0.dtsi new file mode 100644 index 00000000000..043c3fee302 --- /dev/null +++ b/dts/arm/st/h7/stm32h7b0.dtsi @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * STM32H7B0 line contains the same peripherals as STM32H7A3, + * with addition of CRYPTO/HASH and OTFDEC peripherals. + */ +/ { + soc { + compatible = "st,stm32h7b0", "st,stm32h7", "simple-bus"; + + cryp: cryp@48021000 { + compatible = "st,stm32-cryp"; + reg = <0x48021000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00000010>; + interrupts = <79 0>; + interrupt-names = "cryp"; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h7b0Xb.dtsi b/dts/arm/st/h7/stm32h7b0Xb.dtsi new file mode 100644 index 00000000000..884e22edc8e --- /dev/null +++ b/dts/arm/st/h7/stm32h7b0Xb.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(128)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h7b3.dtsi b/dts/arm/st/h7/stm32h7b3.dtsi index a104f58a192..f8b583b9d75 100644 --- a/dts/arm/st/h7/stm32h7b3.dtsi +++ b/dts/arm/st/h7/stm32h7b3.dtsi @@ -5,23 +5,13 @@ */ #include -#include +#include /* - * STM32H7B3 line contains the same peripherals as STM32H7A3, - * with addition of CRYPTO/HASH and OTFDEC peripherals + * STM32H7B3 line contains the same peripherals as STM32H7B0. */ / { soc { compatible = "st,stm32h7b3", "st,stm32h7", "simple-bus"; - - cryp: cryp@48021000 { - compatible = "st,stm32-cryp"; - reg = <0x48021000 0x400>; - clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00000010>; - interrupts = <79 0>; - interrupt-names = "cryp"; - status = "disabled"; - }; }; }; From 1f0320441b7c888f788e1cb7ba15ebf1feaa7fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:40:14 +0100 Subject: [PATCH 3627/4498] drivers: bluetooth: hci: cyw43xxx: Add dependency to UART runtime config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for CYW43XXX. Signed-off-by: Krzysztof Chruściński --- drivers/bluetooth/hci/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 835b90edd54..0f792b58b08 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -141,6 +141,7 @@ menuconfig BT_AIROC bool "AIROC BT connectivity" default y select BT_HCI_SETUP + select UART_USE_RUNTIME_CONFIGURE depends on GPIO depends on DT_HAS_INFINEON_CYW43XXX_BT_HCI_ENABLED depends on BT_H4 From c674eafe7501c1610c15b67826a16d7a1ce9e803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:40:59 +0100 Subject: [PATCH 3628/4498] drivers: i2c: sc18im704: Add dependency to UART runtime config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for sc18im704. Signed-off-by: Krzysztof Chruściński --- drivers/i2c/Kconfig.sc18im704 | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/Kconfig.sc18im704 b/drivers/i2c/Kconfig.sc18im704 index 15cdbd43d4d..f38c0e67d23 100644 --- a/drivers/i2c/Kconfig.sc18im704 +++ b/drivers/i2c/Kconfig.sc18im704 @@ -5,6 +5,7 @@ config I2C_SC18IM704 bool "NXP SC18IM704 I2C controller driver" default y depends on DT_HAS_NXP_SC18IM704_I2C_ENABLED + select UART_USE_RUNTIME_CONFIGURE help Enables NXP SC18IM704 I2C controller driver From 3bb4cd813aea44f678156cf4ccedb1aad023bb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:41:43 +0100 Subject: [PATCH 3629/4498] drivers: sensor: a01nyub: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for A01NYUB. Signed-off-by: Krzysztof Chruściński --- drivers/sensor/a01nyub/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sensor/a01nyub/Kconfig b/drivers/sensor/a01nyub/Kconfig index ff40a6f0682..5f137e0358a 100644 --- a/drivers/sensor/a01nyub/Kconfig +++ b/drivers/sensor/a01nyub/Kconfig @@ -6,5 +6,6 @@ config A01NYUB default y depends on DT_HAS_DFROBOT_A01NYUB_ENABLED depends on UART_INTERRUPT_DRIVEN + select UART_USE_RUNTIME_CONFIGURE help Enable driver for the DFRobot A01NYUB distance sensor. From a47c7dd79330ed18525a5294ad03a787c75c6f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:42:40 +0100 Subject: [PATCH 3630/4498] drivers: w1: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for 1-wire serial driver. Signed-off-by: Krzysztof Chruściński --- drivers/w1/Kconfig.zephyr_serial | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/w1/Kconfig.zephyr_serial b/drivers/w1/Kconfig.zephyr_serial index 9555fb43a92..10eb274ee1e 100644 --- a/drivers/w1/Kconfig.zephyr_serial +++ b/drivers/w1/Kconfig.zephyr_serial @@ -8,6 +8,7 @@ config W1_ZEPHYR_SERIAL select SERIAL default y depends on DT_HAS_ZEPHYR_W1_SERIAL_ENABLED + select UART_USE_RUNTIME_CONFIGURE help This option enables the Zephyr serial 1-Wire master driver. From 0f79f3a4c00d2864a8c5f9491a03e7a8a9eeb350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:44:08 +0100 Subject: [PATCH 3631/4498] drivers: wifi: esp_at: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for ESP AT driver. Signed-off-by: Krzysztof Chruściński --- drivers/wifi/esp_at/Kconfig.esp_at | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/wifi/esp_at/Kconfig.esp_at b/drivers/wifi/esp_at/Kconfig.esp_at index afe02931ee6..9b7e38045d9 100644 --- a/drivers/wifi/esp_at/Kconfig.esp_at +++ b/drivers/wifi/esp_at/Kconfig.esp_at @@ -11,6 +11,7 @@ menuconfig WIFI_ESP_AT select MODEM_IFACE_UART select NET_L2_WIFI_MGMT select WIFI_OFFLOAD + imply UART_USE_RUNTIME_CONFIGURE help Enable Espressif AT Command offloaded WiFi driver. It is supported on any serial capable platform and communicates with Espressif chips From 6022a413d644a1682aa5a61c705de0b8fe342a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:45:18 +0100 Subject: [PATCH 3632/4498] samples: drivers: uart: native_tty: Add dependency to UART runtime conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration in the sample. Signed-off-by: Krzysztof Chruściński --- samples/drivers/uart/native_tty/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/drivers/uart/native_tty/prj.conf b/samples/drivers/uart/native_tty/prj.conf index ef2861c789f..7958f8c58bf 100644 --- a/samples/drivers/uart/native_tty/prj.conf +++ b/samples/drivers/uart/native_tty/prj.conf @@ -1 +1,2 @@ CONFIG_SERIAL=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y From 7778b7d46d526aebed515d3c409dde361b6d6fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:46:51 +0100 Subject: [PATCH 3633/4498] debug: gdbstub: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for GDBSTUB. Signed-off-by: Krzysztof Chruściński --- subsys/debug/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/debug/Kconfig b/subsys/debug/Kconfig index f9468ff5e0c..54d83f18ff6 100644 --- a/subsys/debug/Kconfig +++ b/subsys/debug/Kconfig @@ -397,6 +397,7 @@ endmenu config GDBSTUB bool "GDB remote serial protocol support [EXPERIMENTAL]" depends on ARCH_HAS_GDBSTUB + select UART_USE_RUNTIME_CONFIGURE select EXPERIMENTAL help This option enable support the target using GDB, or any other From b0323820119fb30e2e5a35cabae62bb7ab01fa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:47:24 +0100 Subject: [PATCH 3634/4498] modbus: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for modbus serial. Signed-off-by: Krzysztof Chruściński --- subsys/modbus/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/modbus/Kconfig b/subsys/modbus/Kconfig index 614afdd8341..38c7d761c07 100644 --- a/subsys/modbus/Kconfig +++ b/subsys/modbus/Kconfig @@ -44,6 +44,7 @@ config MODBUS_SERIAL default y depends on SERIAL && SERIAL_HAS_DRIVER depends on DT_HAS_ZEPHYR_MODBUS_SERIAL_ENABLED + select UART_USE_RUNTIME_CONFIGURE help Enable Modbus over serial line support. From 1ec05c4431988c6dcaa895fb84912c3a8ed288e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 11:20:40 +0100 Subject: [PATCH 3635/4498] tests: drivers: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration in UART tests. Signed-off-by: Krzysztof Chruściński --- tests/drivers/uart/uart_async_api/prj.conf | 1 + tests/drivers/uart/uart_basic_api/prj.conf | 1 + tests/drivers/uart/uart_basic_api/prj_poll.conf | 1 + tests/drivers/uart/uart_basic_api/prj_shell.conf | 1 + 4 files changed, 4 insertions(+) diff --git a/tests/drivers/uart/uart_async_api/prj.conf b/tests/drivers/uart/uart_async_api/prj.conf index ef0d6054812..39c50952d48 100644 --- a/tests/drivers/uart/uart_async_api/prj.conf +++ b/tests/drivers/uart/uart_async_api/prj.conf @@ -1,4 +1,5 @@ CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y diff --git a/tests/drivers/uart/uart_basic_api/prj.conf b/tests/drivers/uart/uart_basic_api/prj.conf index d12c995df09..4234fa73398 100644 --- a/tests/drivers/uart/uart_basic_api/prj.conf +++ b/tests/drivers/uart/uart_basic_api/prj.conf @@ -1,4 +1,5 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y CONFIG_ZTEST=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/drivers/uart/uart_basic_api/prj_poll.conf b/tests/drivers/uart/uart_basic_api/prj_poll.conf index 772072f1c4d..7b1c9273665 100644 --- a/tests/drivers/uart/uart_basic_api/prj_poll.conf +++ b/tests/drivers/uart/uart_basic_api/prj_poll.conf @@ -1,3 +1,4 @@ CONFIG_SERIAL=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y CONFIG_ZTEST=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/drivers/uart/uart_basic_api/prj_shell.conf b/tests/drivers/uart/uart_basic_api/prj_shell.conf index 6ecbf8931a4..f4ce1d0334c 100644 --- a/tests/drivers/uart/uart_basic_api/prj_shell.conf +++ b/tests/drivers/uart/uart_basic_api/prj_shell.conf @@ -1,5 +1,6 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y CONFIG_ZTEST=y CONFIG_SHELL_CMD_BUFF_SIZE=90 CONFIG_SHELL=y From d31424e040c49c750e089182378aa52b5d14445f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 13 Nov 2023 09:51:14 +0100 Subject: [PATCH 3636/4498] mgmt: osdp: Add dependency to UART runtime configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force enabling of the UART runtime configuration for OSDP. Signed-off-by: Krzysztof Chruściński --- subsys/mgmt/osdp/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/mgmt/osdp/Kconfig b/subsys/mgmt/osdp/Kconfig index 2d19d796043..c04abbc6df6 100644 --- a/subsys/mgmt/osdp/Kconfig +++ b/subsys/mgmt/osdp/Kconfig @@ -9,6 +9,7 @@ menuconfig OSDP select RING_BUFFER imply SERIAL_SUPPORT_INTERRUPT imply UART_INTERRUPT_DRIVEN + imply UART_USE_RUNTIME_CONFIGURE select CRC help Add support for Open Supervised Device Protocol (OSDP) From b5f4d8374a6c5e9535515dbf2379188637502046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Mon, 13 Nov 2023 12:45:56 +0100 Subject: [PATCH 3637/4498] net: buf: Preserve buffer pointer in destroy callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use case is to have a netbuf pool that is used exclusively with net_buf_alloc_with_data() where the destroy callback takes care of freeing the actual data buffer pointed to by __buf. Signed-off-by: Tomasz Moń --- include/zephyr/net/buf.h | 7 +++++++ subsys/net/buf.c | 16 ---------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/include/zephyr/net/buf.h b/include/zephyr/net/buf.h index 91d0f601183..f7378fc3962 100644 --- a/include/zephyr/net/buf.h +++ b/include/zephyr/net/buf.h @@ -1358,6 +1358,13 @@ static inline void net_buf_destroy(struct net_buf *buf) { struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id); + if (buf->__buf) { + if (!(buf->flags & NET_BUF_EXTERNAL_DATA)) { + pool->alloc->cb->unref(buf, buf->__buf); + } + buf->__buf = NULL; + } + k_lifo_put(&pool->free, buf); } diff --git a/subsys/net/buf.c b/subsys/net/buf.c index da8c75f32f2..09f937da59d 100644 --- a/subsys/net/buf.c +++ b/subsys/net/buf.c @@ -221,17 +221,6 @@ static uint8_t *data_ref(struct net_buf *buf, uint8_t *data) return pool->alloc->cb->ref(buf, data); } -static void data_unref(struct net_buf *buf, uint8_t *data) -{ - struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id); - - if (buf->flags & NET_BUF_EXTERNAL_DATA) { - return; - } - - pool->alloc->cb->unref(buf, data); -} - #if defined(CONFIG_NET_BUF_LOG) struct net_buf *net_buf_alloc_len_debug(struct net_buf_pool *pool, size_t size, k_timeout_t timeout, const char *func, @@ -484,11 +473,6 @@ void net_buf_unref(struct net_buf *buf) return; } - if (buf->__buf) { - data_unref(buf, buf->__buf); - buf->__buf = NULL; - } - buf->data = NULL; buf->frags = NULL; From 341e571cfb9c4d1826ffde0e448870eca84c46e3 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 13 Nov 2023 13:02:07 +0100 Subject: [PATCH 3638/4498] tests: audio: mocks: Add k_work_schedule mock implementation This adds k_work_schedule mock implementation that will be used in bluetooth audio unit tests. Signed-off-by: Mariusz Skamra --- .../audio/mocks/include/mock_kernel.h | 1 - tests/bluetooth/audio/mocks/src/kernel.c | 37 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/tests/bluetooth/audio/mocks/include/mock_kernel.h b/tests/bluetooth/audio/mocks/include/mock_kernel.h index 8da6a064cda..360ff79f416 100644 --- a/tests/bluetooth/audio/mocks/include/mock_kernel.h +++ b/tests/bluetooth/audio/mocks/include/mock_kernel.h @@ -15,7 +15,6 @@ void mock_kernel_init(void); void mock_kernel_cleanup(void); DECLARE_FAKE_VALUE_FUNC(k_ticks_t, z_timeout_remaining, const struct _timeout *); -DECLARE_FAKE_VALUE_FUNC(int, k_work_schedule, struct k_work_delayable *, k_timeout_t); DECLARE_FAKE_VALUE_FUNC(bool, k_work_cancel_delayable_sync, struct k_work_delayable *, struct k_work_sync *); DECLARE_FAKE_VALUE_FUNC(int, k_sem_take, struct k_sem *, k_timeout_t); diff --git a/tests/bluetooth/audio/mocks/src/kernel.c b/tests/bluetooth/audio/mocks/src/kernel.c index 03dc2cf582d..5cd8bbbd852 100644 --- a/tests/bluetooth/audio/mocks/src/kernel.c +++ b/tests/bluetooth/audio/mocks/src/kernel.c @@ -6,6 +6,7 @@ */ #include +#include #include #include "mock_kernel.h" @@ -13,14 +14,12 @@ /* List of fakes used by this unit tester */ #define FFF_FAKES_LIST(FAKE) \ FAKE(z_timeout_remaining) \ - FAKE(k_work_schedule) \ FAKE(k_work_cancel_delayable_sync) \ /* List of k_work items to be worked. */ static sys_slist_t work_pending; DEFINE_FAKE_VALUE_FUNC(k_ticks_t, z_timeout_remaining, const struct _timeout *); -DEFINE_FAKE_VALUE_FUNC(int, k_work_schedule, struct k_work_delayable *, k_timeout_t); DEFINE_FAKE_VALUE_FUNC(bool, k_work_cancel_delayable_sync, struct k_work_delayable *, struct k_work_sync *); DEFINE_FAKE_VALUE_FUNC(int, k_sem_take, struct k_sem *, k_timeout_t); @@ -32,19 +31,49 @@ void k_work_init_delayable(struct k_work_delayable *dwork, k_work_handler_t hand } int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) +{ + bool on_list = false; + struct k_work *work; + + dwork->timeout.dticks = delay.ticks; + + /* Determine whether the work item is queued already. */ + SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) { + on_list = work == &dwork->work; + if (on_list) { + break; + } + } + + if (dwork->timeout.dticks == 0) { + dwork->work.handler(&dwork->work); + if (on_list) { + (void)sys_slist_remove(&work_pending, NULL, &dwork->work.node); + } + } else if (!on_list) { + sys_slist_append(&work_pending, &dwork->work.node); + } + + return 0; +} + +int k_work_schedule(struct k_work_delayable *dwork, k_timeout_t delay) { struct k_work *work; /* Determine whether the work item is queued already. */ SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) { if (work == &dwork->work) { - dwork->timeout.dticks = delay.ticks; return 0; } } dwork->timeout.dticks = delay.ticks; - sys_slist_append(&work_pending, &dwork->work.node); + if (dwork->timeout.dticks == 0) { + dwork->work.handler(&dwork->work); + } else { + sys_slist_append(&work_pending, &dwork->work.node); + } return 0; } From ba6142050493eb5f6b0f1233cf4a313eb4d162b5 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 13 Nov 2023 10:44:15 +0100 Subject: [PATCH 3639/4498] Bluetooth: audio: ascs: Retry ASE state notifications on error This adds retry logic for ASE state notifications if failed due to insufficient number of buffers to send ATT PDU. The state transition is retried after connection interval delay. Fixes: #64574 Signed-off-by: Mariusz Skamra --- .../bluetooth/unicast_audio_server/prj.conf | 4 - subsys/bluetooth/audio/ascs.c | 236 +++++++++++------- 2 files changed, 143 insertions(+), 97 deletions(-) diff --git a/samples/bluetooth/unicast_audio_server/prj.conf b/samples/bluetooth/unicast_audio_server/prj.conf index 6fd0c501585..3aec74ddbcc 100644 --- a/samples/bluetooth/unicast_audio_server/prj.conf +++ b/samples/bluetooth/unicast_audio_server/prj.conf @@ -14,7 +14,3 @@ CONFIG_BT_ATT_PREPARE_COUNT=1 CONFIG_BT_EXT_ADV=y CONFIG_BT_DEVICE_NAME="Unicast Audio Server" - -# Due to https://github.com/zephyrproject-rtos/zephyr/issues/64574 we need to increase the number -# of L2CAP buffers -CONFIG_BT_L2CAP_TX_BUF_COUNT=4 diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 94cff37f6b7..116071d4c0f 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -61,7 +61,7 @@ static struct bt_ascs_ase { struct bt_bap_ep ep; const struct bt_gatt_attr *attr; struct k_work_delayable disconnect_work; - struct k_work state_transition_work; + struct k_work_delayable state_transition_work; enum bt_bap_ep_state state_pending; bool unexpected_iso_link_loss; } ase_pool[CONFIG_BT_ASCS_MAX_ACTIVE_ASES]; @@ -124,56 +124,51 @@ static void ase_free(struct bt_ascs_ase *ase) bt_conn_unref(ase->conn); ase->conn = NULL; - (void)k_work_cancel(&ase->state_transition_work); + (void)k_work_cancel_delayable(&ase->disconnect_work); + (void)k_work_cancel_delayable(&ase->state_transition_work); } -static void ase_status_changed(struct bt_ascs_ase *ase, uint8_t state) +static int ase_state_notify(struct bt_ascs_ase *ase) { + const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ struct bt_conn *conn = ase->conn; + struct bt_conn_info conn_info; + uint16_t max_ntf_size; + uint16_t ntf_size; + int err; - LOG_DBG("ase %p id 0x%02x %s -> %s", ase, ase->ep.status.id, - bt_bap_ep_state_str(ascs_ep_get_state(&ase->ep)), bt_bap_ep_state_str(state)); - - ase->ep.status.state = state; + __ASSERT_NO_MSG(conn != NULL); - if (conn != NULL) { - struct bt_conn_info conn_info; - int err; + err = bt_conn_get_info(conn, &conn_info); + __ASSERT_NO_MSG(err == 0); - err = bt_conn_get_info(conn, &conn_info); - if (err != 0) { - LOG_ERR("Failed to get conn %p info: %d", (void *)conn, err); + if (conn_info.state != BT_CONN_STATE_CONNECTED || + !bt_gatt_is_subscribed(conn, ase->attr, BT_GATT_CCC_NOTIFY)) { + return 0; + } - return; - } + err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT); + if (err != 0) { + LOG_WRN("Failed to take ase_buf_sem: %d", err); - if (conn_info.state == BT_CONN_STATE_CONNECTED && - bt_gatt_is_subscribed(conn, ase->attr, BT_GATT_CCC_NOTIFY)) { - const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ - const uint16_t max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; - uint16_t ntf_size; + return err; + } - err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT); - if (err != 0) { - LOG_DBG("Failed to take ase_buf_sem: %d", err); + ascs_ep_get_status(&ase->ep, &ase_buf); - return; - } + max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; - ascs_ep_get_status(&ase->ep, &ase_buf); + ntf_size = MIN(max_ntf_size, ase_buf.len); + if (ntf_size < ase_buf.len) { + LOG_DBG("Sending truncated notification (%u / %u)", + ntf_size, ase_buf.len); + } - ntf_size = MIN(max_ntf_size, ase_buf.len); - if (ntf_size < ase_buf.len) { - LOG_DBG("Sending truncated notification (%u / %u)", - ntf_size, ase_buf.len); - } + err = bt_gatt_notify(conn, ase->attr, ase_buf.data, ntf_size); - err = bt_gatt_notify(conn, ase->attr, ase_buf.data, ntf_size); - __ASSERT_NO_MSG(err == 0); + k_sem_give(&ase_buf_sem); - k_sem_give(&ase_buf_sem); - } - } + return err; } static void ascs_disconnect_stream_work_handler(struct k_work *work) @@ -243,7 +238,7 @@ static int ascs_disconnect_stream(struct bt_bap_stream *stream) K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY)); } -static void ase_set_state_idle(struct bt_ascs_ase *ase) +static void ase_enter_state_idle(struct bt_ascs_ase *ase) { struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; @@ -252,8 +247,6 @@ static void ase_set_state_idle(struct bt_ascs_ase *ase) ase->ep.receiver_ready = false; - ase_status_changed(ase, BT_BAP_EP_STATE_IDLE); - if (stream->conn != NULL) { bt_conn_unref(stream->conn); stream->conn = NULL; @@ -267,7 +260,7 @@ static void ase_set_state_idle(struct bt_ascs_ase *ase) ase_free(ase); } -static void ase_set_state_codec_configured(struct bt_ascs_ase *ase) +static void ase_enter_state_codec_configured(struct bt_ascs_ase *ase) { struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; @@ -276,15 +269,13 @@ static void ase_set_state_codec_configured(struct bt_ascs_ase *ase) ase->ep.receiver_ready = false; - ase_status_changed(ase, BT_BAP_EP_STATE_CODEC_CONFIGURED); - ops = stream->ops; if (ops != NULL && ops->configured != NULL) { ops->configured(stream, &ase->ep.qos_pref); } } -static void ase_set_state_qos_configured(struct bt_ascs_ase *ase) +static void ase_enter_state_qos_configured(struct bt_ascs_ase *ase) { struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; @@ -293,29 +284,22 @@ static void ase_set_state_qos_configured(struct bt_ascs_ase *ase) ase->ep.receiver_ready = false; - ase_status_changed(ase, BT_BAP_EP_STATE_QOS_CONFIGURED); - ops = stream->ops; if (ops != NULL && ops->qos_set != NULL) { ops->qos_set(stream); } } -static void ase_set_state_enabling(struct bt_ascs_ase *ase) +static void ase_enter_state_enabling(struct bt_ascs_ase *ase) { - const bool state_changed = ascs_ep_get_state(&ase->ep) != BT_BAP_EP_STATE_ENABLING; struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; __ASSERT_NO_MSG(stream != NULL); - ase_status_changed(ase, BT_BAP_EP_STATE_ENABLING); - ops = stream->ops; - if (state_changed && ops != NULL && ops->enabled != NULL) { + if (ops != NULL && ops->enabled != NULL) { ops->enabled(stream); - } else if (!state_changed && ops != NULL && ops->metadata_updated != NULL) { - ops->metadata_updated(stream); } /* SINK ASEs can autonomously go into the streaming state if the CIS is connected */ @@ -325,34 +309,61 @@ static void ase_set_state_enabling(struct bt_ascs_ase *ase) } } -static void ase_set_state_streaming(struct bt_ascs_ase *ase) +static void ase_enter_state_streaming(struct bt_ascs_ase *ase) { - const bool state_changed = ascs_ep_get_state(&ase->ep) != BT_BAP_EP_STATE_STREAMING; struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; __ASSERT_NO_MSG(stream != NULL); - ase_status_changed(ase, BT_BAP_EP_STATE_STREAMING); - ops = stream->ops; - if (state_changed && ops != NULL && ops->started != NULL) { + if (ops != NULL && ops->started != NULL) { ops->started(stream); - } else if (!state_changed && ops != NULL && ops->metadata_updated != NULL) { + } +} + +static void ase_metadata_updated(struct bt_ascs_ase *ase) +{ + struct bt_bap_stream *stream = ase->ep.stream; + struct bt_bap_stream_ops *ops; + + __ASSERT_NO_MSG(stream != NULL); + + ops = stream->ops; + if (ops != NULL && ops->metadata_updated != NULL) { ops->metadata_updated(stream); } } -static void ase_set_state_disabling(struct bt_ascs_ase *ase) +static void ase_exit_state_streaming(struct bt_ascs_ase *ase) { struct bt_bap_stream *stream = ase->ep.stream; struct bt_bap_stream_ops *ops; + uint8_t reason = ase->ep.reason; __ASSERT_NO_MSG(stream != NULL); - ase->ep.receiver_ready = false; + if (reason == BT_HCI_ERR_SUCCESS) { + /* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */ + reason = BT_HCI_ERR_UNSPECIFIED; + } + + ops = stream->ops; + if (ops != NULL && ops->stopped != NULL) { + ops->stopped(stream, reason); + } else { + LOG_WRN("No callback for stopped set"); + } +} - ase_status_changed(ase, BT_BAP_EP_STATE_DISABLING); +static void ase_enter_state_disabling(struct bt_ascs_ase *ase) +{ + struct bt_bap_stream *stream = ase->ep.stream; + struct bt_bap_stream_ops *ops; + + __ASSERT_NO_MSG(stream != NULL); + + ase->ep.receiver_ready = false; ops = stream->ops; if (ops != NULL && ops->disabled != NULL) { @@ -360,7 +371,7 @@ static void ase_set_state_disabling(struct bt_ascs_ase *ase) } } -static void ase_set_state_releasing(struct bt_ascs_ase *ase) +static void ase_enter_state_releasing(struct bt_ascs_ase *ase) { struct bt_bap_stream *stream = ase->ep.stream; @@ -368,8 +379,6 @@ static void ase_set_state_releasing(struct bt_ascs_ase *ase) ase->ep.receiver_ready = false; - ase_status_changed(ase, BT_BAP_EP_STATE_RELEASING); - /* Either the client or the server may disconnect the CISes when entering the releasing * state. */ @@ -387,52 +396,88 @@ static void ase_set_state_releasing(struct bt_ascs_ase *ase) static void state_transition_work_handler(struct k_work *work) { - struct bt_ascs_ase *ase = CONTAINER_OF(work, struct bt_ascs_ase, state_transition_work); + struct k_work_delayable *d_work = k_work_delayable_from_work(work); + struct bt_ascs_ase *ase = CONTAINER_OF(d_work, struct bt_ascs_ase, state_transition_work); const enum bt_bap_ep_state old_state = ascs_ep_get_state(&ase->ep); const enum bt_bap_ep_state new_state = ase->state_pending; - struct bt_bap_stream *stream = ase->ep.stream; - struct bt_bap_ep *ep = &ase->ep; + int err; - __ASSERT_NO_MSG(stream != NULL); + ase->ep.status.state = new_state; + + /* Notify ASE state */ + if (ase->conn != NULL) { + err = ase_state_notify(ase); + if (err == -ENOMEM) { + struct bt_conn_info info; + uint32_t retry_delay_ms; - /* We left the streaming state, let the upper layers know that the stream is stopped */ - if (old_state != new_state && old_state == BT_BAP_EP_STATE_STREAMING) { - struct bt_bap_stream_ops *ops = stream->ops; - uint8_t reason = ep->reason; + /* Revert back to old state */ + ase->ep.status.state = old_state; + + err = bt_conn_get_info(ase->conn, &info); + __ASSERT_NO_MSG(err == 0); + + retry_delay_ms = BT_CONN_INTERVAL_TO_MS(info.le.interval); + + /* Reschedule the state transition */ + err = k_work_reschedule(d_work, K_MSEC(retry_delay_ms)); + if (err >= 0) { + LOG_WRN("Out of buffers for ase state notification. " + "Will retry in %dms", retry_delay_ms); + return; + } + } - if (reason == BT_HCI_ERR_SUCCESS) { - /* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */ - reason = BT_HCI_ERR_UNSPECIFIED; + if (err < 0) { + LOG_ERR("Failed to notify ASE state (err %d)", err); } + } - if (ops != NULL && ops->stopped != NULL) { - ops->stopped(stream, reason); - } else { - LOG_WRN("No callback for stopped set"); + LOG_DBG("ase %p id 0x%02x %s -> %s", ase, ase->ep.status.id, + bt_bap_ep_state_str(old_state), bt_bap_ep_state_str(new_state)); + + if (old_state == new_state) { + switch (new_state) { + case BT_BAP_EP_STATE_ENABLING: + case BT_BAP_EP_STATE_STREAMING: + ase_metadata_updated(ase); + return; + default: + break; } } + /* Actions needed for exiting the old state */ + switch (old_state) { + case BT_BAP_EP_STATE_STREAMING: + ase_exit_state_streaming(ase); + break; + default: + break; + } + + /* Actions needed for entering the new state */ switch (new_state) { case BT_BAP_EP_STATE_IDLE: - ase_set_state_idle(ase); + ase_enter_state_idle(ase); break; case BT_BAP_EP_STATE_CODEC_CONFIGURED: - ase_set_state_codec_configured(ase); + ase_enter_state_codec_configured(ase); break; case BT_BAP_EP_STATE_QOS_CONFIGURED: - ase_set_state_qos_configured(ase); + ase_enter_state_qos_configured(ase); break; case BT_BAP_EP_STATE_ENABLING: - ase_set_state_enabling(ase); + ase_enter_state_enabling(ase); break; case BT_BAP_EP_STATE_STREAMING: - ase_set_state_streaming(ase); + ase_enter_state_streaming(ase); break; case BT_BAP_EP_STATE_DISABLING: - ase_set_state_disabling(ase); + ase_enter_state_disabling(ase); break; case BT_BAP_EP_STATE_RELEASING: - ase_set_state_releasing(ase); + ase_enter_state_releasing(ase); break; default: __ASSERT_PRINT("Invalid state %d", new_state); @@ -533,9 +578,9 @@ int ascs_ep_set_state(struct bt_bap_ep *ep, uint8_t state) ase->state_pending = state; - err = k_work_submit(&ase->state_transition_work); + err = k_work_schedule(&ase->state_transition_work, K_NO_WAIT); if (err < 0) { - LOG_ERR("Failed to submit state transition work err %d", err); + LOG_ERR("Failed to schedule state transition work err %d", err); return err; } @@ -1020,6 +1065,12 @@ static int ase_release(struct bt_ascs_ase *ase, uint8_t reason, struct bt_bap_as int bt_ascs_release_ase(struct bt_bap_ep *ep) { struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep); + const enum bt_bap_ep_state state = ascs_ep_get_state(&ase->ep); + + if (state == BT_BAP_EP_STATE_IDLE) { + ase_free(ase); + return 0; + } return ase_release(ase, BT_HCI_ERR_LOCALHOST_TERM_CONN, BT_BAP_ASCS_RSP_NULL); } @@ -1103,12 +1154,12 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) * should expect there to be only a single reference to the bt_conn pointer * from the stack. * We trigger the work handler directly rather than e.g. calling - * ase_set_state_idle to trigger "regular" state change behavior (such) as + * ase_enter_state_idle to trigger "regular" state change behavior (such) as * calling stream->stopped when leaving the streaming state. */ ase->ep.reason = reason; ase->state_pending = BT_BAP_EP_STATE_IDLE; - state_transition_work_handler(&ase->state_transition_work); + state_transition_work_handler(&ase->state_transition_work.work); /* At this point, `ase` object have been free'd */ } } @@ -1205,9 +1256,8 @@ static void ase_init(struct bt_ascs_ase *ase, struct bt_conn *conn, uint8_t id) __ASSERT(ase->attr, "ASE characteristic not found\n"); - k_work_init_delayable(&ase->disconnect_work, - ascs_disconnect_stream_work_handler); - k_work_init(&ase->state_transition_work, state_transition_work_handler); + k_work_init_delayable(&ase->disconnect_work, ascs_disconnect_stream_work_handler); + k_work_init_delayable(&ase->state_transition_work, state_transition_work_handler); } static struct bt_ascs_ase *ase_new(struct bt_conn *conn, uint8_t id) From 71494dd98fff653125e5002a35d7ef98e3f9a666 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 13 Nov 2023 14:26:42 +0100 Subject: [PATCH 3640/4498] tests: bluetooth: ascs: Add test for ASE notificaion retry This adds test for ASE state notification retry. The test verifies whether the state transition is repeated if failed due to notification error. Signed-off-by: Mariusz Skamra --- tests/bluetooth/audio/ascs/src/main.c | 81 ++++++++++++++++++++ tests/bluetooth/audio/ascs/src/test_common.c | 1 + tests/bluetooth/audio/mocks/src/gatt.c | 44 ++++++++++- 3 files changed, 122 insertions(+), 4 deletions(-) diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index 126c82d63bb..2937bd6d916 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -648,3 +648,84 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state_client_retries) bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); } + +static struct bt_bap_stream *stream_allocated; +static const struct bt_audio_codec_qos_pref qos_pref = + BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000); + +static int unicast_server_cb_config_custom_fake(struct bt_conn *conn, const struct bt_bap_ep *ep, + enum bt_audio_dir dir, + const struct bt_audio_codec_cfg *codec_cfg, + struct bt_bap_stream **stream, + struct bt_audio_codec_qos_pref *const pref, + struct bt_bap_ascs_rsp *rsp) +{ + *stream = stream_allocated; + *pref = qos_pref; + *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE); + + bt_bap_stream_cb_register(*stream, &mock_bap_stream_ops); + + return 0; +} + +ZTEST_F(ascs_test_suite, test_ase_state_notification_retry) +{ + struct bt_bap_stream *stream = &fixture->stream; + struct bt_conn *conn = &fixture->conn; + const struct bt_gatt_attr *ase, *cp; + struct bt_conn_info info; + uint8_t ase_id; + int err; + + if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) { + ase = fixture->ase_snk.attr; + ase_id = fixture->ase_snk.id; + } else { + ase = fixture->ase_src.attr; + ase_id = fixture->ase_src.id; + } + + zexpect_not_null(ase); + zassert_not_equal(ase_id, 0x00); + + cp = test_ase_control_point_get(); + zexpect_not_null(cp); + + bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); + + stream_allocated = stream; + mock_bap_unicast_server_cb_config_fake.custom_fake = unicast_server_cb_config_custom_fake; + + /* Mock out of buffers case */ + mock_bt_gatt_notify_cb_fake.return_val = -ENOMEM; + + const uint8_t buf[] = { + 0x01, /* Opcode = Config Codec */ + 0x01, /* Number_of_ASEs */ + ase_id, /* ASE_ID[0] */ + 0x01, /* Target_Latency[0] = Target low latency */ + 0x02, /* Target_PHY[0] = LE 2M PHY */ + 0x06, /* Codec_ID[0].Coding_Format = LC3 */ + 0x00, 0x00, /* Codec_ID[0].Company_ID */ + 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */ + 0x00, /* Codec_Specific_Configuration_Length[0] */ + }; + + cp->write(conn, cp, (void *)buf, sizeof(buf), 0, 0); + + /* Verification */ + expect_bt_bap_stream_ops_configured_not_called(); + + mock_bt_gatt_notify_cb_fake.return_val = 0; + + err = bt_conn_get_info(conn, &info); + zassert_equal(err, 0); + + /* Wait for ASE state notification retry */ + k_sleep(K_MSEC(BT_CONN_INTERVAL_TO_MS(info.le.interval))); + + expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + + bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); +} diff --git a/tests/bluetooth/audio/ascs/src/test_common.c b/tests/bluetooth/audio/ascs/src/test_common.c index 941cbc98f02..17f5bf71e2b 100644 --- a/tests/bluetooth/audio/ascs/src/test_common.c +++ b/tests/bluetooth/audio/ascs/src/test_common.c @@ -68,6 +68,7 @@ void test_conn_init(struct bt_conn *conn) conn->info.security.level = BT_SECURITY_L2; conn->info.security.enc_key_size = BT_ENC_KEY_SIZE_MAX; conn->info.security.flags = BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC; + conn->info.le.interval = BT_GAP_INIT_CONN_INT_MIN; } const struct bt_gatt_attr *test_ase_control_point_get(void) diff --git a/tests/bluetooth/audio/mocks/src/gatt.c b/tests/bluetooth/audio/mocks/src/gatt.c index d020306b04d..29ab2ee2b0d 100644 --- a/tests/bluetooth/audio/mocks/src/gatt.c +++ b/tests/bluetooth/audio/mocks/src/gatt.c @@ -60,12 +60,38 @@ void mock_bt_gatt_init(void) mock_bt_gatt_is_subscribed_fake.return_val = true; } -static void notify_params_deep_copy_destroy(void) +static void notify_params_deep_copy_destroy(struct bt_gatt_notify_params *params) { struct bt_gatt_notify_params *copy; for (unsigned int i = 0; i < mock_bt_gatt_notify_cb_fake.call_count; i++) { copy = mock_bt_gatt_notify_cb_fake.arg1_history[i]; + if (copy != params) { + continue; + } + + /* Free UUID deep copy */ + if (copy->uuid) { + free((void *)copy->uuid); + } + + free(copy); + + mock_bt_gatt_notify_cb_fake.arg1_history[i] = NULL; + + break; + } +} + +static void notify_params_deep_copy_destroy_all(void) +{ + struct bt_gatt_notify_params *copy; + + for (unsigned int i = 0; i < mock_bt_gatt_notify_cb_fake.call_count; i++) { + copy = mock_bt_gatt_notify_cb_fake.arg1_history[i]; + if (copy == NULL) { + continue; + } /* Free UUID deep copy */ if (copy->uuid) { @@ -78,7 +104,7 @@ static void notify_params_deep_copy_destroy(void) void mock_bt_gatt_cleanup(void) { - notify_params_deep_copy_destroy(); + notify_params_deep_copy_destroy_all(); } static struct bt_uuid *uuid_deep_copy(const struct bt_uuid *uuid) @@ -126,6 +152,9 @@ static struct bt_gatt_notify_params *notify_params_deep_copy(struct bt_gatt_noti int bt_gatt_notify_cb(struct bt_conn *conn, struct bt_gatt_notify_params *params) { + struct bt_gatt_notify_params *copy; + int err; + zassert_not_null(params, "'%s()' was called with incorrect '%s' value", __func__, "params"); /* Either params->uuid, params->attr, or both has to be provided */ @@ -133,12 +162,19 @@ int bt_gatt_notify_cb(struct bt_conn *conn, struct bt_gatt_notify_params *params "'%s()' was called with incorrect '%s' value", __func__, "params->uuid or params->attr"); - return mock_bt_gatt_notify_cb(conn, notify_params_deep_copy(params)); + copy = notify_params_deep_copy(params); + + err = mock_bt_gatt_notify_cb(conn, copy); + if (err != 0) { + notify_params_deep_copy_destroy(copy); + } + + return err; } void bt_gatt_notify_cb_reset(void) { - notify_params_deep_copy_destroy(); + notify_params_deep_copy_destroy_all(); RESET_FAKE(mock_bt_gatt_notify_cb); } From 51ce9c583cd4b4314ed3a35d0c31d1349e3fdb1c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 16:37:18 +0100 Subject: [PATCH 3641/4498] samples/net/lwm2m_client: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Provide an overlay for native_sim * Enable native_sim in the test yaml Signed-off-by: Alberto Escolar Piedras --- samples/net/lwm2m_client/README.rst | 2 +- samples/net/lwm2m_client/boards/native_sim.conf | 5 +++++ samples/net/lwm2m_client/sample.yaml | 10 ++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 samples/net/lwm2m_client/boards/native_sim.conf diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index 4e231ba0051..50e22c30887 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -68,7 +68,7 @@ Build the lwm2m-client sample application like this: :compact: The easiest way to setup this sample application is to build and run it -as native POSIX application or as a QEMU target using the default configuration :file:`prj.conf`. +as a native_sim application or as a QEMU target using the default configuration :file:`prj.conf`. This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_posix`. Download and run the latest build of the Leshan Demo Server: diff --git a/samples/net/lwm2m_client/boards/native_sim.conf b/samples/net/lwm2m_client/boards/native_sim.conf new file mode 100644 index 00000000000..3e21f837f7c --- /dev/null +++ b/samples/net/lwm2m_client/boards/native_sim.conf @@ -0,0 +1,5 @@ +CONFIG_DNS_RESOLVER=y +CONFIG_DNS_SERVER_IP_ADDRESSES=y +CONFIG_DNS_SERVER1="192.0.2.2" +CONFIG_LWM2M_DNS_SUPPORT=y +CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" diff --git a/samples/net/lwm2m_client/sample.yaml b/samples/net/lwm2m_client/sample.yaml index 8faf0e613e5..9c0cada2c1f 100644 --- a/samples/net/lwm2m_client/sample.yaml +++ b/samples/net/lwm2m_client/sample.yaml @@ -10,6 +10,7 @@ tests: - frdm_k64f - pinnacle_100_dvk - mg100 + - native_sim integration_platforms: - qemu_x86 tags: @@ -18,7 +19,9 @@ tests: sample.net.lwm2m_client.all_objects: harness: net depends_on: netif - platform_allow: qemu_x86 + platform_allow: + - qemu_x86 + - native_sim integration_platforms: - qemu_x86 tags: @@ -43,6 +46,7 @@ tests: - frdm_k64f - pinnacle_100_dvk - mg100 + - native_sim integration_platforms: - qemu_x86 tags: @@ -63,7 +67,9 @@ tests: harness: net depends_on: netif extra_args: OVERLAY_CONFIG=overlay-queue.conf - platform_allow: qemu_x86 + platform_allow: + - qemu_x86 + - native_sim integration_platforms: - qemu_x86 tags: From f4a63aa7aea71b4365c75cf2357daaec0516e1a6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 16:39:56 +0100 Subject: [PATCH 3642/4498] samples/net/tftp_client: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Provide an overlay for native_sim * Enable native_sim in the test yaml Signed-off-by: Alberto Escolar Piedras --- samples/net/tftp_client/README.rst | 8 ++++---- samples/net/tftp_client/boards/native_sim.conf | 3 +++ samples/net/tftp_client/sample.yaml | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 samples/net/tftp_client/boards/native_sim.conf diff --git a/samples/net/tftp_client/README.rst b/samples/net/tftp_client/README.rst index 40da21adcf6..aaf8444a804 100644 --- a/samples/net/tftp_client/README.rst +++ b/samples/net/tftp_client/README.rst @@ -41,15 +41,15 @@ Build the tftp-client sample application like this: :compact: The easiest way to setup this sample application is to build and run it -as native POSIX application or as a QEMU target using the default configuration :file:`prj.conf`. +as a native_sim application or as a QEMU target using the default configuration :file:`prj.conf`. This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_posix`. -Build the tftp-client sample application for native_posix like this: +Build the tftp-client sample application for :ref:`native_sim ` like this: .. zephyr-app-commands:: :zephyr-app: samples/net/tftp_client :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: @@ -70,7 +70,7 @@ configurations in ``prj.conf``:: Sample output ================================== -Sample run on native_posix platform with TFTP server on host machine +Sample run on native_sim platform with TFTP server on host machine Launch net-setup.sh in net-tools .. code-block:: console diff --git a/samples/net/tftp_client/boards/native_sim.conf b/samples/net/tftp_client/boards/native_sim.conf new file mode 100644 index 00000000000..1e9e27b074e --- /dev/null +++ b/samples/net/tftp_client/boards/native_sim.conf @@ -0,0 +1,3 @@ +CONFIG_DNS_RESOLVER=y +CONFIG_DNS_SERVER_IP_ADDRESSES=y +CONFIG_DNS_SERVER1="192.0.2.2" diff --git a/samples/net/tftp_client/sample.yaml b/samples/net/tftp_client/sample.yaml index baabc4790b4..3ccedecafe9 100644 --- a/samples/net/tftp_client/sample.yaml +++ b/samples/net/tftp_client/sample.yaml @@ -7,8 +7,9 @@ tests: depends_on: netif platform_allow: - native_posix + - native_sim integration_platforms: - - native_posix + - native_sim tags: - net - tftp From e44c43cc2c240885f68d9ff61ec41a23f07946e3 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:54:11 +0100 Subject: [PATCH 3643/4498] docs: Networking with native_posix: Rename Rename Networking with native_posix to Networking with native_sim replace all links to this page accordingly and replace its references to native_posix with native_sim. Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- ...e_posix_setup.rst => native_sim_setup.rst} | 24 +++++++++---------- .../networking/networking_with_host.rst | 4 ++-- samples/net/gptp/README.rst | 4 ++-- samples/net/lwm2m_client/README.rst | 4 ++-- samples/net/tftp_client/README.rst | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) rename doc/connectivity/networking/{native_posix_setup.rst => native_sim_setup.rst} (73%) diff --git a/doc/connectivity/networking/native_posix_setup.rst b/doc/connectivity/networking/native_sim_setup.rst similarity index 73% rename from doc/connectivity/networking/native_posix_setup.rst rename to doc/connectivity/networking/native_sim_setup.rst index cc94c9f790b..166ff707c89 100644 --- a/doc/connectivity/networking/native_posix_setup.rst +++ b/doc/connectivity/networking/native_sim_setup.rst @@ -1,18 +1,18 @@ -.. _networking_with_native_posix: +.. _networking_with_native_sim: -Networking with native_posix board -################################## +Networking with native_sim board +################################ .. contents:: :local: :depth: 2 This page describes how to set up a virtual network between a (Linux) host -and a Zephyr application running in a native_posix board. +and a Zephyr application running in a :ref:`native_sim ` board. In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from -the Zephyr source distribution is run in native_posix board. The Zephyr -native_posix board instance is connected to a Linux host using a tuntap device +the Zephyr source distribution is run in native_sim board. The Zephyr +native_sim board instance is connected to a Linux host using a tuntap device which is modeled in Linux as an Ethernet network interface. Prerequisites @@ -35,13 +35,13 @@ For the steps below, you will need three terminal windows: directory (``cd net-tools``) * Terminal #2 is your usual Zephyr development terminal, with the Zephyr environment initialized. -* Terminal #3 is the console to the running Zephyr native_posix +* Terminal #3 is the console to the running Zephyr native_sim instance (optional). Step 1 - Create Ethernet interface ================================== -Before starting native_posix with network emulation, a network interface +Before starting native_sim with network emulation, a network interface should be created. In terminal #1, type: @@ -58,8 +58,8 @@ by running ``net-setup.sh`` like this: ./net-setup.sh --help -Step 2 - Start app in native_posix board -======================================== +Step 2 - Start app in native_sim board +====================================== Build and start the ``echo_server`` sample application. @@ -68,7 +68,7 @@ In terminal #2, type: .. zephyr-app-commands:: :zephyr-app: samples/net/sockets/echo_server :host-os: unix - :board: native_posix + :board: native_sim :goals: run :compact: @@ -78,7 +78,7 @@ Step 3 - Connect to console (optional) The console window should be launched automatically when the Zephyr instance is started but if it does not show up, you can manually connect to the console. -The native_posix board will print a string like this when it starts: +The native_sim board will print a string like this when it starts: .. code-block:: console diff --git a/doc/connectivity/networking/networking_with_host.rst b/doc/connectivity/networking/networking_with_host.rst index 063e065730a..07288b2cb2b 100644 --- a/doc/connectivity/networking/networking_with_host.rst +++ b/doc/connectivity/networking/networking_with_host.rst @@ -7,7 +7,7 @@ Networking with the host system :maxdepth: 1 :hidden: - native_posix_setup.rst + native_sim_setup.rst qemu_eth_setup.rst qemu_setup.rst usbnet_setup.rst @@ -60,7 +60,7 @@ possible: can attach host debugger directly to the running Zephyr instance. This requires that there is an adaptation driver in Zephyr for interfacing with the host system. An Ethernet driver exists in Zephyr for this purpose. - See :ref:`networking_with_native_posix` for details. + See :ref:`networking_with_native_sim` for details. * USB device networking. diff --git a/samples/net/gptp/README.rst b/samples/net/gptp/README.rst index a2c8696d95a..08dd668c795 100644 --- a/samples/net/gptp/README.rst +++ b/samples/net/gptp/README.rst @@ -19,13 +19,13 @@ Requirements ************ For generic host connectivity, that can be used for debugging purposes, see -:ref:`networking_with_native_posix` for details. +:ref:`networking_with_native_sim` for details. Building and Running ******************** A good way to run this sample is to run this gPTP application inside -native_posix board as described in :ref:`networking_with_native_posix` or with +native_posix board as described in :ref:`networking_with_native_sim` or with embedded device like NXP FRDM-K64F, Nucleo-H743-ZI, Nucleo-H745ZI-Q, Nucleo-F767ZI or Atmel SAM-E70 Xplained. Note that gPTP is only supported for boards that have an Ethernet port and which has support for collecting diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index 50e22c30887..2225f789c0c 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -25,7 +25,7 @@ The source code for this sample application can be found at: Requirements ************ -- :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` or :ref:`networking_with_native_posix` +- :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` or :ref:`networking_with_native_sim` - Linux machine - Leshan Demo Server (https://eclipse.org/leshan/) @@ -69,7 +69,7 @@ Build the lwm2m-client sample application like this: The easiest way to setup this sample application is to build and run it as a native_sim application or as a QEMU target using the default configuration :file:`prj.conf`. -This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_posix`. +This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_sim`. Download and run the latest build of the Leshan Demo Server: diff --git a/samples/net/tftp_client/README.rst b/samples/net/tftp_client/README.rst index aaf8444a804..a6c684da5b0 100644 --- a/samples/net/tftp_client/README.rst +++ b/samples/net/tftp_client/README.rst @@ -19,7 +19,7 @@ The source code for this sample application can be found at: Requirements ************ -- :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` or :ref:`networking_with_native_posix` +- :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` or :ref:`networking_with_native_sim` - Linux machine Building and Running @@ -42,7 +42,7 @@ Build the tftp-client sample application like this: The easiest way to setup this sample application is to build and run it as a native_sim application or as a QEMU target using the default configuration :file:`prj.conf`. -This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_posix`. +This requires a small amount of setup described in :ref:`networking_with_eth_qemu`, :ref:`networking_with_qemu` and :ref:`networking_with_native_sim`. Build the tftp-client sample application for :ref:`native_sim ` like this: From d0f554dd6a5f2dc8bc8e19943595557710591943 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 12:07:22 +0100 Subject: [PATCH 3644/4498] docs: networing: Replace references to native_posix w native_sim Let's replace the references to native_posix with native_sim. Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- doc/connectivity/networking/api/gptp.rst | 2 +- doc/connectivity/networking/network_monitoring.rst | 6 +++--- .../networking/networking_with_host.rst | 4 ++-- .../networking_with_multiple_instances.rst | 14 +++++++------- samples/net/sockets/coap_client/README.rst | 2 +- samples/net/sockets/net_mgmt/README.rst | 4 ++-- samples/net/stats/README.rst | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/connectivity/networking/api/gptp.rst b/doc/connectivity/networking/api/gptp.rst index 12dedeaab0b..58788ee003d 100644 --- a/doc/connectivity/networking/api/gptp.rst +++ b/doc/connectivity/networking/api/gptp.rst @@ -40,7 +40,7 @@ Boards supported: - :ref:`nucleo_h745zi_q_board` - :ref:`nucleo_f767zi_board` - :ref:`sam_e70_xplained` -- :ref:`native_posix` (only usable for simple testing, limited capabilities +- :ref:`native_sim` (only usable for simple testing, limited capabilities due to lack of hardware clock) - :ref:`qemu_x86` (emulated, limited capabilities due to lack of hardware clock) diff --git a/doc/connectivity/networking/network_monitoring.rst b/doc/connectivity/networking/network_monitoring.rst index b0a20b287d0..a5f2dcfee71 100644 --- a/doc/connectivity/networking/network_monitoring.rst +++ b/doc/connectivity/networking/network_monitoring.rst @@ -104,7 +104,7 @@ need to terminate the network connection like this. Zephyr Configuration ******************** -In this example, we use ``native_posix`` board. You can also use any other board +In this example, we use the ``native_sim`` board. You can also use any other board that supports networking. In terminal #3, type: @@ -112,7 +112,7 @@ In terminal #3, type: .. zephyr-app-commands:: :zephyr-app: samples/net/capture :host-os: unix - :board: native_posix + :board: native_sim :gen-args: -DCONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD=\""gnome-terminal -- screen %s"\" :goals: build :compact: @@ -189,7 +189,7 @@ Then we need to enable the network packet monitoring like this: net capture enable 2 The ``2`` tells the network interface which traffic we want to capture. In -this example, the ``2`` is the ``native_posix`` board Ethernet interface. +this example, the ``2`` is the ``native_sim`` board Ethernet interface. Note that we send the network traffic to the same interface that we are monitoring in this example. The monitoring system avoids to capture already captured network traffic as that would lead to recursion. diff --git a/doc/connectivity/networking/networking_with_host.rst b/doc/connectivity/networking/networking_with_host.rst index 07288b2cb2b..995e7dc0f80 100644 --- a/doc/connectivity/networking/networking_with_host.rst +++ b/doc/connectivity/networking/networking_with_host.rst @@ -53,7 +53,7 @@ possible: the host on which the model is running. See :ref:`networking_with_armfvp` for details. -* native_posix board. +* native_sim board. * The Zephyr instance can be executed as a user space process in the host system. This is the most convenient way to debug the Zephyr system as one @@ -70,7 +70,7 @@ possible: * Connecting multiple Zephyr instances together. - * If you have multiple Zephyr instances, either QEMU or native_posix ones, + * If you have multiple Zephyr instances, either QEMU or native_sim ones, and want to create a connection between them, see :ref:`networking_with_multiple_instances` for details. diff --git a/doc/connectivity/networking/networking_with_multiple_instances.rst b/doc/connectivity/networking/networking_with_multiple_instances.rst index c83f7e04ed6..6489db45551 100644 --- a/doc/connectivity/networking/networking_with_multiple_instances.rst +++ b/doc/connectivity/networking/networking_with_multiple_instances.rst @@ -9,7 +9,7 @@ Networking with multiple Zephyr instances This page describes how to set up a virtual network between multiple Zephyr instances. The Zephyr instances could be running inside QEMU -or could be native_posix board processes. The Linux host can be used +or could be native_sim board processes. The Linux host can be used to route network traffic between these systems. Prerequisites @@ -34,10 +34,10 @@ For the steps below, you will need five terminal windows: with the Zephyr environment initialized. As there are multiple ways to setup the Zephyr network, the example below uses -``qemu_x86`` board with ``e1000`` Ethernet controller and native_posix board +``qemu_x86`` board with ``e1000`` Ethernet controller and native_sim board to simplify the setup instructions. You can use other QEMU boards and drivers if needed, see :ref:`networking_with_eth_qemu` for details. You can also use -two or more native_posix board Zephyr instances and connect them together. +two or more native_sim board Zephyr instances and connect them together. Step 1 - Create configuration files @@ -141,11 +141,11 @@ In terminal #4, if you are using QEMU, type this: -DCONFIG_ETH_QEMU_IFACE_NAME=\"zeth.1\" \ -DCONFIG_ETH_QEMU_EXTRA_ARGS=\"mac=00:00:5e:00:53:01\" -or if you want to use native_posix board, type this: +or if you want to use native_sim board, type this: .. code-block:: console - west build -d build/server -b native_posix -t run \ + west build -d build/server -b native_sim -t run \ samples/net/sockets/echo_server -- \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"198.51.100.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"203.0.113.1\" \ @@ -172,11 +172,11 @@ In terminal #5, if you are using QEMU, type this: -DCONFIG_ETH_QEMU_IFACE_NAME=\"zeth.2\" \ -DCONFIG_ETH_QEMU_EXTRA_ARGS=\"mac=00:00:5e:00:53:02\" -or if you want to use native_posix board, type this: +or if you want to use native_sim board, type this: .. code-block:: console - west build -d build/client -b native_posix -t run \ + west build -d build/client -b native_sim -t run \ samples/net/sockets/echo_client -- \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"203.0.113.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"198.51.100.1\" \ diff --git a/samples/net/sockets/coap_client/README.rst b/samples/net/sockets/coap_client/README.rst index a26d632772b..ffcd81978cc 100644 --- a/samples/net/sockets/coap_client/README.rst +++ b/samples/net/sockets/coap_client/README.rst @@ -29,7 +29,7 @@ be obtained by using a tool such as tcpdump or wireshark. See the `net-tools`_ project for more details. -This sample can be built and executed on QEMU or native_posix board as described +This sample can be built and executed on QEMU or native_sim board as described in :ref:`networking_with_host`. Sample output diff --git a/samples/net/sockets/net_mgmt/README.rst b/samples/net/sockets/net_mgmt/README.rst index 92d6d8524c7..c59b8170e31 100644 --- a/samples/net/sockets/net_mgmt/README.rst +++ b/samples/net/sockets/net_mgmt/README.rst @@ -34,12 +34,12 @@ Build net-mgmt socket sample application like this: :goals: build :compact: -Example building for the native_posix board: +Example building for the native_sim board: .. zephyr-app-commands:: :zephyr-app: samples/net/sockets/net_mgmt :host-os: unix - :board: native_posix + :board: native_sim :conf: prj.conf :goals: run :compact: diff --git a/samples/net/stats/README.rst b/samples/net/stats/README.rst index 84204d46131..b8a2016c83f 100644 --- a/samples/net/stats/README.rst +++ b/samples/net/stats/README.rst @@ -21,7 +21,7 @@ Requirements Building and Running ******************** -A good way to run this sample application is with QEMU or native_posix board +A good way to run this sample application is with QEMU or native_sim board as described in :ref:`networking_with_host`. Follow these steps to build the network statistics sample application: From 01ae8079e5c3400738679b6fe6f541244c56f85e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 16:53:57 +0100 Subject: [PATCH 3645/4498] samples/net/gptp: Move from native_posix to native_sim * In the sample doc and shell script, replace native_posix references with native_sim * Provide overlays for native_sim(_64) * Enable native_sim in the test yaml Signed-off-by: Alberto Escolar Piedras --- samples/net/gptp/README.rst | 16 ++++++++-------- samples/net/gptp/boards/native_sim.conf | 8 ++++++++ samples/net/gptp/boards/native_sim_64.conf | 8 ++++++++ samples/net/gptp/docker-test.sh | 2 +- samples/net/gptp/sample.yaml | 2 ++ 5 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 samples/net/gptp/boards/native_sim.conf create mode 100644 samples/net/gptp/boards/native_sim_64.conf diff --git a/samples/net/gptp/README.rst b/samples/net/gptp/README.rst index 08dd668c795..f0c1b39e958 100644 --- a/samples/net/gptp/README.rst +++ b/samples/net/gptp/README.rst @@ -25,7 +25,7 @@ Building and Running ******************** A good way to run this sample is to run this gPTP application inside -native_posix board as described in :ref:`networking_with_native_sim` or with +native_sim board as described in :ref:`networking_with_native_sim` or with embedded device like NXP FRDM-K64F, Nucleo-H743-ZI, Nucleo-H745ZI-Q, Nucleo-F767ZI or Atmel SAM-E70 Xplained. Note that gPTP is only supported for boards that have an Ethernet port and which has support for collecting @@ -51,7 +51,7 @@ Setting up Linux Host If you need VLAN support in your network, then the :zephyr_file:`samples/net/vlan/vlan-setup-linux.sh` provides a script that can be executed on the Linux host. It creates two VLANs on the Linux host and creates -routes to Zephyr. If you are using native_posix board, then +routes to Zephyr. If you are using native_sim board, then the ``net-setup.sh`` will create VLAN setup automatically with this command: .. code-block:: console @@ -61,9 +61,9 @@ the ``net-setup.sh`` will create VLAN setup automatically with this command: The OpenAVNU repository at https://github.com/AVnu contains gPTP daemon that can be run in Linux host and which can act as a grandmaster for the IEEE 801.1AS network. Note that OpenAVNU will not work with -native_posix board as that board only supports software timestamping and +native_sim board as that board only supports software timestamping and OpenAVNU only supports hardware timestamping. See instructions at the end -of this chapter how to run linuxptp daemon with native_posix board. +of this chapter how to run linuxptp daemon with native_sim board. Get OpenAvnu/gPTP project sources @@ -126,7 +126,7 @@ By default gPTP in Zephyr will not print any gPTP debug messages to console. One can enable debug prints by setting :kconfig:option:`CONFIG_NET_GPTP_LOG_LEVEL_DBG` in the config file. -For native_posix board, use ``linuxptp`` project as that supports +For native_sim board, use ``linuxptp`` project as that supports software timestamping. Get linuxptp project sources @@ -150,7 +150,7 @@ Multiport Setup If you set :kconfig:option:`CONFIG_NET_GPTP_NUM_PORTS` larger than 1, then gPTP sample will create multiple TSN ports. This configuration is currently only supported -in native_posix board. +in native_sim board. You need to enable the ports in the net-tools. If the number of ports is set to 2, then give following commands to create the network interfaces in host @@ -163,7 +163,7 @@ side: After that you can start ptp4l daemon for both interfaces. Please use two terminals when starting ptp4l daemon. Note that you must use ptp4l as OpenAVNU -does not work with software clock available in native_posix. +does not work with software clock available in native_sim. .. code-block:: console @@ -175,7 +175,7 @@ Compile Zephyr application. .. zephyr-app-commands:: :zephyr-app: samples/net/gptp - :board: native_posix + :board: native_sim :goals: build :compact: diff --git a/samples/net/gptp/boards/native_sim.conf b/samples/net/gptp/boards/native_sim.conf new file mode 100644 index 00000000000..c514520186c --- /dev/null +++ b/samples/net/gptp/boards/native_sim.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_NET_GPTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/gptp/boards/native_sim_64.conf b/samples/net/gptp/boards/native_sim_64.conf new file mode 100644 index 00000000000..c514520186c --- /dev/null +++ b/samples/net/gptp/boards/native_sim_64.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_NET_GPTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/gptp/docker-test.sh b/samples/net/gptp/docker-test.sh index 03ab0f48aa7..bc791584c0b 100644 --- a/samples/net/gptp/docker-test.sh +++ b/samples/net/gptp/docker-test.sh @@ -14,7 +14,7 @@ start_docker \ "/usr/local/sbin/ptp4l -2 -f /etc/gptp.cfg -m -q -l 6 -S -i eth0" \ || return $? -# For native_posix gPTP run, the delay threshold needs to be huge +# For native_sim gPTP run, the delay threshold needs to be huge start_zephyr "$overlay" "-DCONFIG_NET_SAMPLE_RUN_DURATION=10" \ "-DCONFIG_NET_GPTP_NEIGHBOR_PROP_DELAY_THR=12000000" diff --git a/samples/net/gptp/sample.yaml b/samples/net/gptp/sample.yaml index 0184353569e..a668d6325a5 100644 --- a/samples/net/gptp/sample.yaml +++ b/samples/net/gptp/sample.yaml @@ -13,6 +13,8 @@ tests: - sam_e70_xplained - native_posix - native_posix_64 + - native_sim + - native_sim_64 - nucleo_f767zi - nucleo_h743zi - nucleo_h745zi_q_m7 From 2cadcb3df4c924d13f009d2b01178303dc807b81 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 17:01:54 +0100 Subject: [PATCH 3646/4498] samples/net/mqtt_sn_publisher: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Provide overlays for native_sim * Enable native_sim in the test yaml Signed-off-by: Alberto Escolar Piedras --- samples/net/mqtt_sn_publisher/README.rst | 2 +- samples/net/mqtt_sn_publisher/boards/native_sim.conf | 1 + samples/net/mqtt_sn_publisher/boards/native_sim_64.conf | 1 + samples/net/mqtt_sn_publisher/sample.yaml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 samples/net/mqtt_sn_publisher/boards/native_sim.conf create mode 100644 samples/net/mqtt_sn_publisher/boards/native_sim_64.conf diff --git a/samples/net/mqtt_sn_publisher/README.rst b/samples/net/mqtt_sn_publisher/README.rst index 425160e8892..48b8dab5dec 100644 --- a/samples/net/mqtt_sn_publisher/README.rst +++ b/samples/net/mqtt_sn_publisher/README.rst @@ -67,7 +67,7 @@ Then, locate your zephyr directory and type: .. zephyr-app-commands:: :zephyr-app: samples/net/mqtt_sn_publisher - :board: native_posix_64 + :board: native_sim_64 :goals: run :compact: diff --git a/samples/net/mqtt_sn_publisher/boards/native_sim.conf b/samples/net/mqtt_sn_publisher/boards/native_sim.conf new file mode 100644 index 00000000000..0843e94acbd --- /dev/null +++ b/samples/net/mqtt_sn_publisher/boards/native_sim.conf @@ -0,0 +1 @@ +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/net/mqtt_sn_publisher/boards/native_sim_64.conf b/samples/net/mqtt_sn_publisher/boards/native_sim_64.conf new file mode 100644 index 00000000000..0843e94acbd --- /dev/null +++ b/samples/net/mqtt_sn_publisher/boards/native_sim_64.conf @@ -0,0 +1 @@ +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/samples/net/mqtt_sn_publisher/sample.yaml b/samples/net/mqtt_sn_publisher/sample.yaml index 5d37a430ba1..ca11e3e96f3 100644 --- a/samples/net/mqtt_sn_publisher/sample.yaml +++ b/samples/net/mqtt_sn_publisher/sample.yaml @@ -13,5 +13,6 @@ tests: - qemu_x86 - pinnacle_100_dvk - mg100 + - native_sim_64 integration_platforms: - qemu_x86 From 3e4b3939090963f7f78b82a511429b69a8963989 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 17:08:18 +0100 Subject: [PATCH 3647/4498] samples coap_server: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Provide overlays for native_sim * Enable native_sim in the sample yaml * Remove native_posix from the sample yaml platform_allow as it was filtered out by the host libC Signed-off-by: Alberto Escolar Piedras --- samples/net/sockets/coap_server/README.rst | 2 +- samples/net/sockets/coap_server/boards/native_sim.conf | 4 ++++ samples/net/sockets/coap_server/boards/native_sim_64.conf | 4 ++++ samples/net/sockets/coap_server/sample.yaml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 samples/net/sockets/coap_server/boards/native_sim.conf create mode 100644 samples/net/sockets/coap_server/boards/native_sim_64.conf diff --git a/samples/net/sockets/coap_server/README.rst b/samples/net/sockets/coap_server/README.rst index 89490ad399b..a2962b941be 100644 --- a/samples/net/sockets/coap_server/README.rst +++ b/samples/net/sockets/coap_server/README.rst @@ -44,7 +44,7 @@ or wireshark. See the `net-tools`_ project for more details -This sample can be built and executed on QEMU or native_posix board as +This sample can be built and executed on QEMU or native_sim board as described in :ref:`networking_with_host`. Use this command on the host to run the `libcoap`_ implementation of diff --git a/samples/net/sockets/coap_server/boards/native_sim.conf b/samples/net/sockets/coap_server/boards/native_sim.conf new file mode 100644 index 00000000000..ac091ebe5db --- /dev/null +++ b/samples/net/sockets/coap_server/boards/native_sim.conf @@ -0,0 +1,4 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_UART_0_ON_STDINOUT=y +CONFIG_PICOLIBC=y diff --git a/samples/net/sockets/coap_server/boards/native_sim_64.conf b/samples/net/sockets/coap_server/boards/native_sim_64.conf new file mode 100644 index 00000000000..ac091ebe5db --- /dev/null +++ b/samples/net/sockets/coap_server/boards/native_sim_64.conf @@ -0,0 +1,4 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_UART_0_ON_STDINOUT=y +CONFIG_PICOLIBC=y diff --git a/samples/net/sockets/coap_server/sample.yaml b/samples/net/sockets/coap_server/sample.yaml index 3c0cfe475db..2fcf9b63287 100644 --- a/samples/net/sockets/coap_server/sample.yaml +++ b/samples/net/sockets/coap_server/sample.yaml @@ -10,5 +10,5 @@ tests: - net - socket platform_allow: - - native_posix + - native_sim - qemu_x86 From 1d6cfc0543e2755967827e5a09191563096f6fd1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 17:18:37 +0100 Subject: [PATCH 3648/4498] samples coap_server: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Enable native_sim in the sample yaml, and switch integration_platform Signed-off-by: Alberto Escolar Piedras --- samples/net/sockets/packet/README.rst | 2 +- samples/net/sockets/packet/sample.yaml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/net/sockets/packet/README.rst b/samples/net/sockets/packet/README.rst index ea096be0a23..b9429215061 100644 --- a/samples/net/sockets/packet/README.rst +++ b/samples/net/sockets/packet/README.rst @@ -23,7 +23,7 @@ sent and received packets. See the `net-tools`_ project for more details. -This sample can be built and executed on QEMU or native_posix board as +This sample can be built and executed on QEMU or native_sim board as described in :ref:`networking_with_host`. .. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools diff --git a/samples/net/sockets/packet/sample.yaml b/samples/net/sockets/packet/sample.yaml index 66deae9f335..d02c03c7d68 100644 --- a/samples/net/sockets/packet/sample.yaml +++ b/samples/net/sockets/packet/sample.yaml @@ -7,8 +7,10 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim tags: - net - sockets From eae281bb338f7c6da201c114f58ce31df3b19ce5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 17:23:38 +0100 Subject: [PATCH 3649/4498] samples sntp_client: Move from native_posix to native_sim * In the sample doc, replace native_posix references with native_sim * Enable native_sim in the sample yaml Signed-off-by: Alberto Escolar Piedras --- samples/net/sockets/sntp_client/README.rst | 2 +- samples/net/sockets/sntp_client/sample.yaml | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/samples/net/sockets/sntp_client/README.rst b/samples/net/sockets/sntp_client/README.rst index 1e061c36a70..f9a1aacd4b8 100644 --- a/samples/net/sockets/sntp_client/README.rst +++ b/samples/net/sockets/sntp_client/README.rst @@ -24,7 +24,7 @@ printed. See the `net-tools`_ project for more details. -This sample can be built and executed on QEMU or native_posix board as +This sample can be built and executed on QEMU or native_sim board as described in :ref:`networking_with_qemu`. .. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools diff --git a/samples/net/sockets/sntp_client/sample.yaml b/samples/net/sockets/sntp_client/sample.yaml index 3a87d5995e2..65d4f2f3b2c 100644 --- a/samples/net/sockets/sntp_client/sample.yaml +++ b/samples/net/sockets/sntp_client/sample.yaml @@ -6,13 +6,19 @@ common: tags: net tests: sample.net.sockets.sntp_client: - platform_allow: qemu_x86 + platform_allow: + - qemu_x86 + - native_sim sample.net.sockets.sntp_client.posix_names: - platform_allow: qemu_x86 + platform_allow: + - qemu_x86 + - native_sim extra_configs: - CONFIG_NET_SOCKETS_POSIX_NAMES=y sample.net.sockets.sntp_client.posix: - platform_allow: qemu_x86 + platform_allow: + - qemu_x86 + - native_sim extra_configs: - CONFIG_NET_SOCKETS_POSIX_NAMES=n - CONFIG_POSIX_API=y From b32e57391b32e7d76e0548d56634ab57098ba7a8 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 13 Nov 2023 17:24:55 +0100 Subject: [PATCH 3650/4498] samples/net: Move from native_posix to native_sim For several samples that today have native_sim enabled, enable them also for native_sim. And set native_sim as default integration_platform instead of native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/net/ipv4_autoconf/sample.yaml | 4 +++- samples/net/lldp/sample.yaml | 4 +++- samples/net/sockets/txtime/sample.yaml | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/samples/net/ipv4_autoconf/sample.yaml b/samples/net/ipv4_autoconf/sample.yaml index bb1f529ef4b..07260fee0ad 100644 --- a/samples/net/ipv4_autoconf/sample.yaml +++ b/samples/net/ipv4_autoconf/sample.yaml @@ -7,8 +7,10 @@ common: - qemu_x86 - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim sample: description: Test IPv4 autoconf functionality name: IPv4 autoconf sample app diff --git a/samples/net/lldp/sample.yaml b/samples/net/lldp/sample.yaml index 78b61768ee6..4daf567dca2 100644 --- a/samples/net/lldp/sample.yaml +++ b/samples/net/lldp/sample.yaml @@ -11,6 +11,8 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim depends_on: netif diff --git a/samples/net/sockets/txtime/sample.yaml b/samples/net/sockets/txtime/sample.yaml index 98488b70e94..189f6901bfc 100644 --- a/samples/net/sockets/txtime/sample.yaml +++ b/samples/net/sockets/txtime/sample.yaml @@ -5,10 +5,12 @@ common: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 - qemu_x86 - qemu_x86_64 integration_platforms: - - native_posix + - native_sim sample: description: Socket SO_TXTIME sample name: txtime-socket From b4ce96d161d45310a1a553ab31aa7c72a8ef787e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 13 Nov 2023 15:32:09 +0000 Subject: [PATCH 3651/4498] soc: arm: nordic_nrf: Imply XIP instead of select This allows XIP to be disabled for applications that execute in RAM, which do not need XIP support from flash Signed-off-by: Jamie McCrae --- soc/arm/nordic_nrf/nrf51/Kconfig.series | 2 +- soc/arm/nordic_nrf/nrf52/Kconfig.series | 2 +- soc/arm/nordic_nrf/nrf53/Kconfig.series | 2 +- soc/arm/nordic_nrf/nrf91/Kconfig.series | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.series index e7028b02190..c484d44fc30 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.series @@ -9,7 +9,7 @@ config SOC_SERIES_NRF51X select ARM select CPU_CORTEX_M0 select SOC_FAMILY_NRF - select XIP + imply XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_POWEROFF diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.series index f11bd5cd59f..d47089cd595 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.series @@ -10,7 +10,7 @@ config SOC_SERIES_NRF52X select CPU_CORTEX_M4 select CPU_HAS_ARM_MPU select SOC_FAMILY_NRF - select XIP + imply XIP select HAS_NRFX select HAS_NORDIC_DRIVERS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.series b/soc/arm/nordic_nrf/nrf53/Kconfig.series index 8ab81ad310b..28d1c10fc1e 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.series @@ -11,7 +11,7 @@ config SOC_SERIES_NRF53X select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU select SOC_FAMILY_NRF - select XIP + imply XIP select HAS_NRFX select HAS_NORDIC_DRIVERS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index fd8f5b04d7a..c30132c7bac 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -13,7 +13,7 @@ config SOC_SERIES_NRF91X select CPU_HAS_FPU select ARMV8_M_DSP select SOC_FAMILY_NRF - select XIP + imply XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_POWEROFF From a36d4beafa210fa597b6a504a756c4c2b2d1a103 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 13 Nov 2023 14:26:05 -0800 Subject: [PATCH 3652/4498] drivers: dma: mcux_lpc: support channel priority Set DMA channel priority in dma_mcux_lpc_configure(). Signed-off-by: Mike J. Chen --- drivers/dma/dma_mcux_lpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/dma_mcux_lpc.c b/drivers/dma/dma_mcux_lpc.c index cd45211e678..ef0a164d4af 100644 --- a/drivers/dma/dma_mcux_lpc.c +++ b/drivers/dma/dma_mcux_lpc.c @@ -583,6 +583,7 @@ static int dma_mcux_lpc_configure(const struct device *dev, uint32_t channel, } else { DMA_DisableChannelPeriphRq(p_handle->base, p_handle->channel); } + DMA_SetChannelPriority(p_handle->base, p_handle->channel, config->channel_priority); data->busy = false; if (config->dma_callback) { From e8c5ca50ccb44335ab55ae8330b0613c5be287e6 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Tue, 14 Nov 2023 18:03:17 -0300 Subject: [PATCH 3653/4498] zbus: make ZBUS_CHANNEL_DECLARE compatible with C++ The current implementation of ZBUS_CHAN_DECLARE is not compatible with C++. It fixes the bug by adding the extern keyword at the channel definition which will work for both C and C++. Signed-off-by: Rodrigo Peixoto --- include/zephyr/zbus/zbus.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index 7e5557ef84e..8b2aa05175b 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -304,6 +304,7 @@ struct zbus_channel_observation { static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \ .observers_start_idx = -1, .observers_end_idx = -1}; \ static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \ + IF_ENABLED(CONFIG_CPP, (extern)) \ const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \ ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \ .message = &_CONCAT(_zbus_message_, _name), \ From f2f81361d8b33a03da8a180e8012888f50e6950f Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Tue, 14 Nov 2023 21:47:43 -0500 Subject: [PATCH 3654/4498] doc: extensions: kconfig: allow paste event to trigger search The "keyup" event is not triggered when pasting with mouse (right click, paste) or when pasting on a phone/tablet. Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com> --- doc/_extensions/zephyr/kconfig/static/kconfig.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs index ae27532ab6a..6c94845a107 100644 --- a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs +++ b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs @@ -491,7 +491,7 @@ function setupKconfigSearch() { doSearchFromURL(); /* install event listeners */ - input.addEventListener('keyup', () => { + input.addEventListener('input', () => { searchOffset = 0; doSearch(); }); From 2e97e5daa8851387abab4bb284bce77bbe2daf47 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 14 Nov 2023 16:24:00 +0100 Subject: [PATCH 3655/4498] doc: mpsc: Add missed 'end' Adds missed 'end' in the 'Internals' chapter. Signed-off-by: Andrej Butok --- doc/kernel/data_structures/mpsc_pbuf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/kernel/data_structures/mpsc_pbuf.rst b/doc/kernel/data_structures/mpsc_pbuf.rst index 4ecef5b62e4..73780d6a426 100644 --- a/doc/kernel/data_structures/mpsc_pbuf.rst +++ b/doc/kernel/data_structures/mpsc_pbuf.rst @@ -54,7 +54,7 @@ Header state: +-------+------+----------------------+ Packet buffer space contains free space, valid user packets and internal skip -packets. Internal skip packets indicates padding, e.g. at the of the buffer. +packets. Internal skip packets indicates padding, e.g. at the end of the buffer. Allocation ^^^^^^^^^^ From 15e92d5e5cf32d98311daf61b0c2014fe95dff57 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 11:40:47 +0000 Subject: [PATCH 3656/4498] input: kbd: make row and col size optional add extra macro Change the row-count and col-count to be optional in the generic binding, add a second pair of macro to allow the implementation to specify the numbers from a different property. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.h | 70 +++++++++++++++++------ dts/bindings/input/kbd-matrix-common.yaml | 2 - dts/bindings/input/nuvoton,npcx-kbd.yaml | 6 ++ 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/drivers/input/input_kbd_matrix.h b/drivers/input/input_kbd_matrix.h index ec286ab5520..400505562bd 100644 --- a/drivers/input/input_kbd_matrix.h +++ b/drivers/input/input_kbd_matrix.h @@ -56,23 +56,36 @@ struct input_kbd_matrix_common_config { _CONCAT(__input_kbd_matrix_, \ _CONCAT(name, DEVICE_DT_NAME_GET(node_id))) +/** + * @brief Defines the common keyboard matrix support data from devicetree, + * specify row and col count. + */ +#define INPUT_KBD_MATRIX_DT_DEFINE_ROW_COL(node_id, _row_size, _col_size) \ + BUILD_ASSERT(IN_RANGE(_row_size, 1, 8), "invalid row-size"); \ + BUILD_ASSERT(IN_RANGE(_col_size, 1, UINT8_MAX), "invalid col-size"); \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME(node_id, stable_state)[_col_size]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME(node_id, unstable_state)[_col_size]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME(node_id, previous_state)[_col_size]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME(node_id, new_state)[_col_size]; \ + static uint8_t INPUT_KBD_MATRIX_DATA_NAME(node_id, scan_cycle_idx)[_row_size * _col_size]; + /** * @brief Defines the common keyboard matrix support data from devicetree. */ #define INPUT_KBD_MATRIX_DT_DEFINE(node_id) \ - BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, row_size), 1, 8), "invalid row-size"); \ - BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, col_size), 1, UINT8_MAX), "invalid col-size"); \ - static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ - node_id, stable_state)[DT_PROP(node_id, col_size)]; \ - static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ - node_id, unstable_state)[DT_PROP(node_id, col_size)]; \ - static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ - node_id, previous_state)[DT_PROP(node_id, col_size)]; \ - static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ - node_id, new_state)[DT_PROP(node_id, col_size)]; \ - static uint8_t INPUT_KBD_MATRIX_DATA_NAME( \ - node_id, scan_cycle_idx)[DT_PROP(node_id, row_size) * \ - DT_PROP(node_id, col_size)]; + INPUT_KBD_MATRIX_DT_DEFINE_ROW_COL( \ + node_id, DT_PROP(node_id, row_size), DT_PROP(node_id, col_size)) + +/** + * @brief Defines the common keyboard matrix support data from devicetree + * instance, specify row and col count. + * + * @param inst Instance. + * @param row_size The matrix row count. + * @param col_size The matrix column count. + */ +#define INPUT_KBD_MATRIX_DT_INST_DEFINE_ROW_COL(inst, row_size, col_size) \ + INPUT_KBD_MATRIX_DT_DEFINE_ROW_COL(DT_DRV_INST(inst), row_size, col_size) /** * @brief Defines the common keyboard matrix support data from devicetree instance. @@ -83,15 +96,17 @@ struct input_kbd_matrix_common_config { INPUT_KBD_MATRIX_DT_DEFINE(DT_DRV_INST(inst)) /** - * @brief Initialize common keyboard matrix config from devicetree. + * @brief Initialize common keyboard matrix config from devicetree, specify row and col count. * * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + * @param row_size The matrix row count. + * @param col_size The matrix column count. */ -#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, _api) \ +#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT_ROW_COL(node_id, _api, _row_size, _col_size) \ { \ .api = _api, \ - .row_size = DT_PROP(node_id, row_size), \ - .col_size = DT_PROP(node_id, col_size), \ + .row_size = _row_size, \ + .col_size = _col_size, \ .poll_period_us = DT_PROP(node_id, poll_period_ms) * USEC_PER_MSEC, \ .poll_timeout_ms = DT_PROP(node_id, poll_timeout_ms), \ .debounce_down_ms = DT_PROP(node_id, debounce_down_ms), \ @@ -106,6 +121,27 @@ struct input_kbd_matrix_common_config { .scan_cycle_idx = INPUT_KBD_MATRIX_DATA_NAME(node_id, scan_cycle_idx), \ } +/** + * @brief Initialize common keyboard matrix config from devicetree. + * + * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + */ +#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, _api) \ + INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT_ROW_COL( \ + node_id, _api, DT_PROP(node_id, row_size), DT_PROP(node_id, col_size)) + +/** + * @brief Initialize common keyboard matrix config from devicetree instance, + * specify row and col count. + * + * @param inst Instance. + * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + * @param row_size The matrix row count. + * @param col_size The matrix column count. + */ +#define INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT_ROW_COL(inst, api, row_size, col_size) \ + INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT_ROW_COL(DT_DRV_INST(inst), api, row_size, col_size) + /** * @brief Initialize common keyboard matrix config from devicetree instance. * diff --git a/dts/bindings/input/kbd-matrix-common.yaml b/dts/bindings/input/kbd-matrix-common.yaml index 53efd29dc9f..e399bd4431f 100644 --- a/dts/bindings/input/kbd-matrix-common.yaml +++ b/dts/bindings/input/kbd-matrix-common.yaml @@ -8,13 +8,11 @@ include: base.yaml properties: row-size: type: int - required: true description: | The number of rows in the keyboard matrix. col-size: type: int - required: true description: | The number of column in the keyboard matrix. diff --git a/dts/bindings/input/nuvoton,npcx-kbd.yaml b/dts/bindings/input/nuvoton,npcx-kbd.yaml index 7ba9956cb6b..b7c30c5388f 100644 --- a/dts/bindings/input/nuvoton,npcx-kbd.yaml +++ b/dts/bindings/input/nuvoton,npcx-kbd.yaml @@ -29,3 +29,9 @@ properties: For example the WUI mapping on 8 KSI pads would be wui-maps = <&wui_io30 &wui_io31 &wui_io27 &wui_io26 &wui_io25 &wui_io24 &wui_io23 &wui_io22>; + + row-size: + required: true + + col-size: + required: true From 0c00b6e0ab6de34045e04b11a62881a75b7242d6 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 14:16:57 +0000 Subject: [PATCH 3657/4498] input: kbd_matrix: make the api field a pointer The API field of input_kbd_matrix_common_config should have been a pointer from the start, clang-16 caught this with a compiler warning. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 4 ++-- drivers/input/input_kbd_matrix.h | 2 +- drivers/input/input_npcx_kbd.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index d6da7764f73..b642e59b800 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -74,7 +74,7 @@ static bool input_kbd_matrix_ghosting(const struct device *dev) static bool input_kbd_matrix_scan(const struct device *dev) { const struct input_kbd_matrix_common_config *cfg = dev->config; - const struct input_kbd_matrix_api *api = &cfg->api; + const struct input_kbd_matrix_api *api = cfg->api; int row; uint8_t key_event = 0U; @@ -264,7 +264,7 @@ static void input_kbd_matrix_polling_thread(void *arg1, void *unused2, void *unu { const struct device *dev = arg1; const struct input_kbd_matrix_common_config *cfg = dev->config; - const struct input_kbd_matrix_api *api = &cfg->api; + const struct input_kbd_matrix_api *api = cfg->api; struct input_kbd_matrix_common_data *data = dev->data; ARG_UNUSED(unused2); diff --git a/drivers/input/input_kbd_matrix.h b/drivers/input/input_kbd_matrix.h index 400505562bd..93aabdd84c8 100644 --- a/drivers/input/input_kbd_matrix.h +++ b/drivers/input/input_kbd_matrix.h @@ -34,7 +34,7 @@ struct input_kbd_matrix_api { * This structure **must** be placed first in the driver's config structure. */ struct input_kbd_matrix_common_config { - struct input_kbd_matrix_api api; + const struct input_kbd_matrix_api *api; uint8_t row_size; uint8_t col_size; uint32_t poll_period_us; diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index 65ef7747875..8cb408d621a 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -211,7 +211,7 @@ static const struct input_kbd_matrix_api npcx_kbd_api = { }; static const struct input_npcx_kbd_config npcx_kbd_cfg = { - .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, npcx_kbd_api), + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, &npcx_kbd_api), .base = (struct kbs_reg *)DT_INST_REG_ADDR(0), .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .clk_cfg = NPCX_DT_CLK_CFG_ITEM(0), From 297c41031bb9cec893a9d02257016a699ea2f4de Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 17:23:22 +0000 Subject: [PATCH 3658/4498] doc: input: add a input_kbd_matrix group, fix few missing doc entries Add a input_kbd_matrix doxygen group and add this to the other Input APIs page, add few missing argument documentation entries. Signed-off-by: Fabio Baltieri --- doc/services/input/index.rst | 5 +++ drivers/input/input_kbd_matrix.h | 52 +++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/doc/services/input/index.rst b/doc/services/input/index.rst index 03851d795c0..b18c57beb30 100644 --- a/doc/services/input/index.rst +++ b/doc/services/input/index.rst @@ -87,3 +87,8 @@ Input Event Definitions *********************** .. doxygengroup:: input_events + +Keyboard Matrix API Reference +***************************** + +.. doxygengroup:: input_kbd_matrix diff --git a/drivers/input/input_kbd_matrix.h b/drivers/input/input_kbd_matrix.h index 93aabdd84c8..06f29889028 100644 --- a/drivers/input/input_kbd_matrix.h +++ b/drivers/input/input_kbd_matrix.h @@ -4,6 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @brief Keyboard Matrix API + * @defgroup input_kbd_matrix Keyboard Matrix API + * @ingroup io_interfaces + * @{ + */ + #include #include #include @@ -23,8 +30,33 @@ * @brief Keyboard matrix internal APIs. */ struct input_kbd_matrix_api { + /** + * @brief Request to drive a specific column. + * + * Request to drive a specific matrix column, or none, or all. + * + * @param dev Pointer to the keyboard matrix device. + * @param col The column to drive, or + * @ref INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE or + * @ref INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL. + */ void (*drive_column)(const struct device *dev, int col); + /** + * @brief Read the matrix row. + * + * @param dev Pointer to the keyboard matrix device. + */ int (*read_row)(const struct device *dev); + /** + * @brief Request to put the matrix in detection mode. + * + * Request to put the driver in detection mode, this is called after a + * request to drive all the column and typically involves reenabling + * interrupts row pin changes. + * + * @param dev Pointer to the keyboard matrix device. + * @param enable Whether detection mode has to be enabled or disabled. + */ void (*set_detect_mode)(const struct device *dev, bool enabled); }; @@ -98,9 +130,10 @@ struct input_kbd_matrix_common_config { /** * @brief Initialize common keyboard matrix config from devicetree, specify row and col count. * - * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. - * @param row_size The matrix row count. - * @param col_size The matrix column count. + * @param node_id The devicetree node identifier. + * @param _api Pointer to a @ref input_kbd_matrix_api structure. + * @param _row_size The matrix row count. + * @param _col_size The matrix column count. */ #define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT_ROW_COL(node_id, _api, _row_size, _col_size) \ { \ @@ -124,18 +157,19 @@ struct input_kbd_matrix_common_config { /** * @brief Initialize common keyboard matrix config from devicetree. * - * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + * @param node_id The devicetree node identifier. + * @param api Pointer to a @ref input_kbd_matrix_api structure. */ -#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, _api) \ +#define INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(node_id, api) \ INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT_ROW_COL( \ - node_id, _api, DT_PROP(node_id, row_size), DT_PROP(node_id, col_size)) + node_id, api, DT_PROP(node_id, row_size), DT_PROP(node_id, col_size)) /** * @brief Initialize common keyboard matrix config from devicetree instance, * specify row and col count. * * @param inst Instance. - * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + * @param api Pointer to a @ref input_kbd_matrix_api structure. * @param row_size The matrix row count. * @param col_size The matrix column count. */ @@ -146,7 +180,7 @@ struct input_kbd_matrix_common_config { * @brief Initialize common keyboard matrix config from devicetree instance. * * @param inst Instance. - * @param api Pointer to a :c:struct:`input_kbd_matrix_api` structure. + * @param api Pointer to a @ref input_kbd_matrix_api structure. */ #define INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(inst, api) \ INPUT_KBD_MATRIX_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst), api) @@ -202,3 +236,5 @@ void input_kbd_matrix_poll_start(const struct device *dev); * @retval -errno Negative errno in case of failure. */ int input_kbd_matrix_common_init(const struct device *dev); + +/** @} */ From be5cb7af7cab7c23e59648b95c00b1fa54ed588e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 18:18:29 +0000 Subject: [PATCH 3659/4498] input: kbd_matrix: move the header to the project wide include directory Move the input_kbd_matrix.h header out of drivers/ and into include/, this allows external drivers to use it and doxygen to pick it up. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 3 +-- drivers/input/input_npcx_kbd.c | 2 +- {drivers => include/zephyr}/input/input_kbd_matrix.h | 5 +++++ 3 files changed, 7 insertions(+), 3 deletions(-) rename {drivers => include/zephyr}/input/input_kbd_matrix.h (98%) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index b642e59b800..f4c49d29d51 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -15,8 +16,6 @@ #define LOG_LEVEL CONFIG_INPUT_LOG_LEVEL LOG_MODULE_REGISTER(input_kbd_matrix); -#include "input_kbd_matrix.h" - #define INPUT_KBD_MATRIX_ROW_MASK UINT8_MAX void input_kbd_matrix_poll_start(const struct device *dev) diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index 8cb408d621a..1de14726a6d 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -8,10 +8,10 @@ #define DT_DRV_COMPAT nuvoton_npcx_kbd #include "soc_miwu.h" -#include "input_kbd_matrix.h" #include #include +#include #include #include #include diff --git a/drivers/input/input_kbd_matrix.h b/include/zephyr/input/input_kbd_matrix.h similarity index 98% rename from drivers/input/input_kbd_matrix.h rename to include/zephyr/input/input_kbd_matrix.h index 06f29889028..0566f14d2cd 100644 --- a/drivers/input/input_kbd_matrix.h +++ b/include/zephyr/input/input_kbd_matrix.h @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_INCLUDE_INPUT_KBD_MATRIX_H_ +#define ZEPHYR_INCLUDE_INPUT_KBD_MATRIX_H_ + /** * @brief Keyboard Matrix API * @defgroup input_kbd_matrix Keyboard Matrix API @@ -238,3 +241,5 @@ void input_kbd_matrix_poll_start(const struct device *dev); int input_kbd_matrix_common_init(const struct device *dev); /** @} */ + +#endif /* ZEPHYR_INCLUDE_INPUT_KBD_MATRIX_H_ */ From 256bc860cfd387e3b5cc7700bf81fbf55d507183 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 6 Nov 2023 23:31:44 +0000 Subject: [PATCH 3660/4498] input: add a gpio based keyboard matrix driver Add a GPIO based keyboard matrix driver using the generic keyboard matrix code. Signed-off-by: Fabio Baltieri --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.gpio_kbd_matrix | 10 ++ drivers/input/input_gpio_kbd_matrix.c | 198 ++++++++++++++++++++++ dts/bindings/input/gpio-kbd-matrix.yaml | 43 +++++ tests/drivers/build_all/input/app.overlay | 9 + 6 files changed, 262 insertions(+) create mode 100644 drivers/input/Kconfig.gpio_kbd_matrix create mode 100644 drivers/input/input_gpio_kbd_matrix.c create mode 100644 dts/bindings/input/gpio-kbd-matrix.yaml diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 96f85ba0e72..d63dc2ae797 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_INPUT_CAP1203 input_cap1203.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CST816S input_cst816s.c) zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KBD_MATRIX input_gpio_kbd_matrix.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KEYS input_gpio_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_QDEC input_gpio_qdec.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GT911 input_gt911.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 2a0f8ac8526..afab00d4259 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -9,6 +9,7 @@ menu "Input drivers" source "drivers/input/Kconfig.cap1203" source "drivers/input/Kconfig.cst816s" source "drivers/input/Kconfig.ft5336" +source "drivers/input/Kconfig.gpio_kbd_matrix" source "drivers/input/Kconfig.gpio_keys" source "drivers/input/Kconfig.gpio_qdec" source "drivers/input/Kconfig.gt911" diff --git a/drivers/input/Kconfig.gpio_kbd_matrix b/drivers/input/Kconfig.gpio_kbd_matrix new file mode 100644 index 00000000000..1ded27c1258 --- /dev/null +++ b/drivers/input/Kconfig.gpio_kbd_matrix @@ -0,0 +1,10 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_GPIO_KBD_MATRIX + bool "GPIO based keyboard matrix input driver" + default y + depends on DT_HAS_GPIO_KBD_MATRIX_ENABLED + select INPUT_KBD_MATRIX + help + GPIO keyboard matrix input driver. diff --git a/drivers/input/input_gpio_kbd_matrix.c b/drivers/input/input_gpio_kbd_matrix.c new file mode 100644 index 00000000000..9d532bfd0af --- /dev/null +++ b/drivers/input/input_gpio_kbd_matrix.c @@ -0,0 +1,198 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT gpio_kbd_matrix + +#include +#include + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(input_gpio_kbd_matrix, CONFIG_INPUT_LOG_LEVEL); + +struct gpio_kbd_matrix_config { + struct input_kbd_matrix_common_config common; + const struct gpio_dt_spec *row_gpio; + const struct gpio_dt_spec *col_gpio; + struct gpio_callback *gpio_cb; + gpio_callback_handler_t handler; +}; + +struct gpio_kbd_matrix_data { + struct input_kbd_matrix_common_data common; + uint32_t last_col_state; +}; + +INPUT_KBD_STRUCT_CHECK(struct gpio_kbd_matrix_config, + struct gpio_kbd_matrix_data); + +static void gpio_kbd_matrix_drive_column(const struct device *dev, int col) +{ + const struct gpio_kbd_matrix_config *cfg = dev->config; + const struct input_kbd_matrix_common_config *common = &cfg->common; + struct gpio_kbd_matrix_data *data = dev->data; + int state; + + if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { + state = 0; + } else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) { + state = BIT_MASK(common->col_size); + } else { + state = BIT(col); + } + + for (int i = 0; i < common->col_size; i++) { + const struct gpio_dt_spec *gpio = &cfg->col_gpio[i]; + + if ((data->last_col_state ^ state) & BIT(i)) { + if (state & BIT(i)) { + gpio_pin_configure_dt(gpio, GPIO_OUTPUT_ACTIVE); + } else { + gpio_pin_configure_dt(gpio, GPIO_INPUT); + } + } + } + + data->last_col_state = state; +} + +static int gpio_kbd_matrix_read_row(const struct device *dev) +{ + const struct gpio_kbd_matrix_config *cfg = dev->config; + const struct input_kbd_matrix_common_config *common = &cfg->common; + int val = 0; + + for (int i = 0; i < common->row_size; i++) { + const struct gpio_dt_spec *gpio = &cfg->row_gpio[i]; + + if (gpio_pin_get_dt(gpio)) { + val |= BIT(i); + } + } + + return val; +} + +static void gpio_kbd_matrix_set_detect_mode(const struct device *dev, bool enabled) +{ + const struct gpio_kbd_matrix_config *cfg = dev->config; + const struct input_kbd_matrix_common_config *common = &cfg->common; + unsigned int flags = enabled ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE; + int ret; + + for (int i = 0; i < common->row_size; i++) { + const struct gpio_dt_spec *gpio = &cfg->row_gpio[i]; + + ret = gpio_pin_interrupt_configure_dt(gpio, flags); + if (ret != 0) { + LOG_ERR("Pin %d interrupt configuration failed: %d", i, ret); + return; + } + } +} + +static int gpio_kbd_matrix_init(const struct device *dev) +{ + const struct gpio_kbd_matrix_config *cfg = dev->config; + const struct input_kbd_matrix_common_config *common = &cfg->common; + int ret; + int i; + + for (i = 0; i < common->col_size; i++) { + const struct gpio_dt_spec *gpio = &cfg->col_gpio[i]; + + if (!gpio_is_ready_dt(gpio)) { + LOG_ERR("%s is not ready", gpio->port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(gpio, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Pin %d configuration failed: %d", i, ret); + return ret; + } + } + + for (i = 0; i < common->row_size; i++) { + const struct gpio_dt_spec *gpio = &cfg->row_gpio[i]; + struct gpio_callback *gpio_cb = &cfg->gpio_cb[i]; + + if (!gpio_is_ready_dt(gpio)) { + LOG_ERR("%s is not ready", gpio->port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(gpio, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Pin %d configuration failed: %d", i, ret); + return ret; + } + + gpio_init_callback(gpio_cb, cfg->handler, BIT(gpio->pin)); + + ret = gpio_add_callback_dt(gpio, gpio_cb); + if (ret < 0) { + LOG_ERR("Could not set gpio callback"); + return ret; + } + } + + gpio_kbd_matrix_set_detect_mode(dev, true); + + return input_kbd_matrix_common_init(dev); +} + +static const struct input_kbd_matrix_api gpio_kbd_matrix_api = { + .drive_column = gpio_kbd_matrix_drive_column, + .read_row = gpio_kbd_matrix_read_row, + .set_detect_mode = gpio_kbd_matrix_set_detect_mode, +}; + +#define INPUT_GPIO_KBD_MATRIX_INIT(n) \ + BUILD_ASSERT(DT_INST_PROP_LEN(n, col_gpios) <= 32, "invalid col-size"); \ + \ + INPUT_KBD_MATRIX_DT_INST_DEFINE_ROW_COL( \ + n, DT_INST_PROP_LEN(n, row_gpios), DT_INST_PROP_LEN(n, col_gpios)); \ + \ + static void gpio_kbd_matrix_cb_##n(const struct device *gpio_dev, \ + struct gpio_callback *cb, uint32_t pins) \ + { \ + input_kbd_matrix_poll_start(DEVICE_DT_INST_GET(n)); \ + } \ + \ + static const struct gpio_dt_spec gpio_kbd_matrix_row_gpio_##n[DT_INST_PROP_LEN( \ + n, row_gpios)] = { \ + DT_INST_FOREACH_PROP_ELEM_SEP(n, row_gpios, GPIO_DT_SPEC_GET_BY_IDX, (,)) \ + }; \ + static const struct gpio_dt_spec gpio_kbd_matrix_col_gpio_##n[DT_INST_PROP_LEN( \ + n, col_gpios)] = { \ + DT_INST_FOREACH_PROP_ELEM_SEP(n, col_gpios, GPIO_DT_SPEC_GET_BY_IDX, (,)) \ + }; \ + static struct gpio_callback gpio_kbd_matrix_gpio_cb_##n[DT_INST_PROP_LEN(n, row_gpios)];\ + \ + static const struct gpio_kbd_matrix_config gpio_kbd_matrix_cfg_##n = { \ + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT_ROW_COL( \ + n, &gpio_kbd_matrix_api, \ + DT_INST_PROP_LEN(n, row_gpios), DT_INST_PROP_LEN(n, col_gpios)), \ + .row_gpio = gpio_kbd_matrix_row_gpio_##n, \ + .col_gpio = gpio_kbd_matrix_col_gpio_##n, \ + .gpio_cb = gpio_kbd_matrix_gpio_cb_##n, \ + .handler = gpio_kbd_matrix_cb_##n, \ + }; \ + \ + static struct gpio_kbd_matrix_data gpio_kbd_matrix_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_kbd_matrix_init, NULL, \ + &gpio_kbd_matrix_data_##n, &gpio_kbd_matrix_cfg_##n, \ + POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(INPUT_GPIO_KBD_MATRIX_INIT) diff --git a/dts/bindings/input/gpio-kbd-matrix.yaml b/dts/bindings/input/gpio-kbd-matrix.yaml new file mode 100644 index 00000000000..ef08ebaa44e --- /dev/null +++ b/dts/bindings/input/gpio-kbd-matrix.yaml @@ -0,0 +1,43 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO based keyboard matrix input device + + Implement an input device for a GPIO based keyboard matrix. + + Example configuration: + + kbd-matrix { + compatible = "gpio-kbd-matrix"; + row-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>, + <&gpio0 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + col-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>, + <&gpio0 3 GPIO_ACTIVE_LOW>, + <&gpio0 4 GPIO_ACTIVE_LOW>; + no-ghostkey-check; + }; + +compatible: "gpio-kbd-matrix" + +include: + - name: kbd-matrix-common.yaml + property-blocklist: + - row-size + - col-size + +properties: + row-gpios: + type: phandle-array + required: true + description: | + GPIO for the keyboard matrix rows, up to 8 different GPIOs. All row GPIO + pins must have interrupt support. + + col-gpios: + type: phandle-array + required: true + description: | + GPIO for the keyboard matrix columns, supports up to 32 different GPIOs. + The pins will be driven according to the GPIO_ACTIVE_HIGH or + GPIO_ACTIVE_LOW flags when selected, high impedance when not selected. diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index 71f1d9a212a..f065aadd5f3 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -26,6 +26,15 @@ }; }; + kbd-matrix { + compatible = "gpio-kbd-matrix"; + row-gpios = <&test_gpio 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>, + <&test_gpio 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + col-gpios = <&test_gpio 2 GPIO_ACTIVE_LOW>, + <&test_gpio 3 GPIO_ACTIVE_LOW>, + <&test_gpio 4 GPIO_ACTIVE_LOW>; + }; + qdec-gpio { compatible = "gpio-qdec"; gpios = <&test_gpio 0 0>, <&test_gpio 1 0>; From b1c83c0335d7e16538e24e2ffe60d1fc8eef053e Mon Sep 17 00:00:00 2001 From: Wojciech Sipak Date: Fri, 4 Aug 2023 17:46:37 +0200 Subject: [PATCH 3661/4498] soc: Add support for RZ/T2M This adds a new SoC: SOC_RENESAS_RZT2M and a new board: rzt2m_startek_kit Signed-off-by: Wojciech Sipak Co-authored-by: Roman Dobrodii --- boards/arm/rzt2m_starterkit/Kconfig.board | 6 ++ boards/arm/rzt2m_starterkit/Kconfig.defconfig | 9 ++ boards/arm/rzt2m_starterkit/board.cmake | 11 ++ boards/arm/rzt2m_starterkit/doc/index.rst | 95 ++++++++++++++++++ .../rzt2m_starterkit/doc/rzt2m_starterkit.png | Bin 0 -> 96455 bytes .../rzt2m_starterkit/rzt2m_starter_kit.dts | 17 ++++ .../rzt2m_starterkit/rzt2m_starter_kit.yaml | 15 +++ .../rzt2m_starter_kit_defconfig | 5 + dts/arm/renesas/rzt2m.dtsi | 92 +++++++++++++++++ soc/arm/renesas_rzt2m/CMakeLists.txt | 6 ++ soc/arm/renesas_rzt2m/Kconfig | 15 +++ soc/arm/renesas_rzt2m/Kconfig.defconfig | 24 +++++ soc/arm/renesas_rzt2m/Kconfig.soc | 12 +++ soc/arm/renesas_rzt2m/linker.ld | 7 ++ soc/arm/renesas_rzt2m/soc.c | 76 ++++++++++++++ soc/arm/renesas_rzt2m/soc.h | 41 ++++++++ 16 files changed, 431 insertions(+) create mode 100644 boards/arm/rzt2m_starterkit/Kconfig.board create mode 100644 boards/arm/rzt2m_starterkit/Kconfig.defconfig create mode 100644 boards/arm/rzt2m_starterkit/board.cmake create mode 100644 boards/arm/rzt2m_starterkit/doc/index.rst create mode 100644 boards/arm/rzt2m_starterkit/doc/rzt2m_starterkit.png create mode 100644 boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts create mode 100644 boards/arm/rzt2m_starterkit/rzt2m_starter_kit.yaml create mode 100644 boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig create mode 100644 dts/arm/renesas/rzt2m.dtsi create mode 100644 soc/arm/renesas_rzt2m/CMakeLists.txt create mode 100644 soc/arm/renesas_rzt2m/Kconfig create mode 100644 soc/arm/renesas_rzt2m/Kconfig.defconfig create mode 100644 soc/arm/renesas_rzt2m/Kconfig.soc create mode 100644 soc/arm/renesas_rzt2m/linker.ld create mode 100644 soc/arm/renesas_rzt2m/soc.c create mode 100644 soc/arm/renesas_rzt2m/soc.h diff --git a/boards/arm/rzt2m_starterkit/Kconfig.board b/boards/arm/rzt2m_starterkit/Kconfig.board new file mode 100644 index 00000000000..9fddcf006a4 --- /dev/null +++ b/boards/arm/rzt2m_starterkit/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RZT2M_STARTER_KIT + bool "RZ/T2M Starter Kit Board" + depends on SOC_RENESAS_RZT2M diff --git a/boards/arm/rzt2m_starterkit/Kconfig.defconfig b/boards/arm/rzt2m_starterkit/Kconfig.defconfig new file mode 100644 index 00000000000..9699b23963c --- /dev/null +++ b/boards/arm/rzt2m_starterkit/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RZT2M_STARTER_KIT + +config BOARD + default "rzt2m_starter_kit" + +endif diff --git a/boards/arm/rzt2m_starterkit/board.cmake b/boards/arm/rzt2m_starterkit/board.cmake new file mode 100644 index 00000000000..dd92d0e905a --- /dev/null +++ b/boards/arm/rzt2m_starterkit/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Antmicro +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_set_debugger_ifnset(jlink) +board_set_flasher_ifnset(jlink) + +board_runner_args(jlink "--device=R9A07G075M2") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/rzt2m_starterkit/doc/index.rst b/boards/arm/rzt2m_starterkit/doc/index.rst new file mode 100644 index 00000000000..e965585f6cb --- /dev/null +++ b/boards/arm/rzt2m_starterkit/doc/index.rst @@ -0,0 +1,95 @@ +.. _rzt2m_starterkit: + +Renesas Starter Kit+ for RZ/T2M +=============================== + +Overview +******** + +The Renesas Starter Kit+ for RZ/T2M is an evaluation and development kit for the RZ/T2M MPU. +The board is powered through a 5V input via a DC Power Jack or USB Type-C Connector. + +.. figure:: rzt2m_starterkit.png + :width: 800px + :align: center + :alt: Starter Kit+ for RZ/T2M + + Starter Kit+ for RZ/T2M (Credit: Renesas) + +Hardware +******** + +The board utilizes the SoC of part no. R9A07G075M24GBG, with 2MB of RAM. + +It has several on-board memory components: +* SDRAM (256MBit), +* NOR Flash (256MBit), +* Octa Flash (512MBit), +* HyperRAM (512Mbit), +* QSPI Serial Flash (512Mbit), +* I2C EEPROM (32Kbit). + +The communication interfaces include: +* Debug interfaces (J-Link, MIPI-10, MIPI-20), +* Ethernet, +* CAN, +* USB, +* RS485, +* UART, +* I2C, +* SPI. + +Supported Features +================== + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| PINCTRL | on-chip | pinctrl | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +By default, the board is configured for use with: +* UART0 connected to the USB serial port (pins K18, K19), +* UART3 connected to the PMOD Header (J25, pins H16, G20), +* LEDs defined as `led0`, `led1`, `led2` and `led3`, + +The Zephyr console uses UART0. + +Programming and Debugging +************************* + +Debugging +========= + +Connect to the board using the J-Link On-board USB connector. +Use `west` to start the debug server: + +.. code-block:: console + + west debugserver + +Connect GDB to the server and load an application: + +.. code-block:: + + target remote :2331 + file build/zephyr/zephyr.elf + load + +References +********** + +.. _RZT2M Product page: https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzt2m-high-performance-multi-function-mpu-realizing-high-speed-processing-and-high-precision-control diff --git a/boards/arm/rzt2m_starterkit/doc/rzt2m_starterkit.png b/boards/arm/rzt2m_starterkit/doc/rzt2m_starterkit.png new file mode 100644 index 0000000000000000000000000000000000000000..960df4fdbb58c5328a40628bccf53048a47b0a98 GIT binary patch literal 96455 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%0A`eb`M$F?kEaPqr%8HB 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�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 + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "RZT/2M Starter Kit"; + compatible = "renesas,rzt2m_starter_kit"; + + chosen { + zephyr,sram = &cpu0_atcm; + }; +}; diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.yaml b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.yaml new file mode 100644 index 00000000000..5d091d0fddb --- /dev/null +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +identifier: rzt2m_starter_kit +name: Renesas RZ/T2M Starter Kit+ +type: mcu +arch: arm +ram: 2048 +toolchain: + - zephyr +supported: + - counter + - uart + - gpio +vendor: renesas diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig new file mode 100644 index 00000000000..09e5e1d50a5 --- /dev/null +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_RENESAS_RZT2M=y +CONFIG_BOARD_RZT2M_STARTER_KIT=y diff --git a/dts/arm/renesas/rzt2m.dtsi b/dts/arm/renesas/rzt2m.dtsi new file mode 100644 index 00000000000..44e045014a9 --- /dev/null +++ b/dts/arm/renesas/rzt2m.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "renesas,rzt2m-dev"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-r52"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-r52"; + reg = <1>; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + }; + + soc { + compatible = "renesas,rzt2m-soc"; + + interrupt-parent = <&gic>; + + gic: interrupt-controller@94000000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x94000000 0x10000>, + <0x94100000 0x80000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + cpu0_atcm: memory@0 { + compatible = "mmio-sram"; + reg = <0x00000000 DT_SIZE_K(512)>; + }; + + cpu0_btcm: memory@100000 { + compatible = "mmio-sram"; + reg = <0x00100000 DT_SIZE_K(64)>; + }; + + sram0: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x10000000 DT_SIZE_M(2)>; + }; + + gsc: gsc@c0060000 { + /* Global System Counter */ + compatible = "syscon"; + reg = <0xc0060000 0x30>; + reg-io-width = <4>; + }; + + prcrn: prcrn@80281a10 { + /* Non-safety area */ + compatible = "syscon"; + reg = <0x80281a10 0x10>; + reg-io-width = <4>; + }; + + prcrs: prcrs@81281a00 { + /* Safety area */ + compatible = "syscon"; + reg = <0x81281a00 0x10>; + reg-io-width = <4>; + }; + }; +}; diff --git a/soc/arm/renesas_rzt2m/CMakeLists.txt b/soc/arm/renesas_rzt2m/CMakeLists.txt new file mode 100644 index 00000000000..05fd66ec83c --- /dev/null +++ b/soc/arm/renesas_rzt2m/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + soc.c + ) diff --git a/soc/arm/renesas_rzt2m/Kconfig b/soc/arm/renesas_rzt2m/Kconfig new file mode 100644 index 00000000000..fc2f6e81c4e --- /dev/null +++ b/soc/arm/renesas_rzt2m/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RENESAS_RZT2M + bool + +if SOC_RENESAS_RZT2M + +config SOC_PART_NUMBER_R9A07G075 + bool + +config SOC_PART_NUMBER + default SOC_PART_NUMBER_R9A07G075 + +endif # SOC_RENESAS_RZT2M diff --git a/soc/arm/renesas_rzt2m/Kconfig.defconfig b/soc/arm/renesas_rzt2m/Kconfig.defconfig new file mode 100644 index 00000000000..72f828d4351 --- /dev/null +++ b/soc/arm/renesas_rzt2m/Kconfig.defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RENESAS_RZT2M + +config SOC + default "renesas_rzt2m" + +config NUM_IRQS + default 994 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 20000000 + +config FPU + default y + +config FLASH_SIZE + default 0 + +config FLASH_BASE_ADDRESS + default 0 + +endif # SOC_RENESAS_RZT2M diff --git a/soc/arm/renesas_rzt2m/Kconfig.soc b/soc/arm/renesas_rzt2m/Kconfig.soc new file mode 100644 index 00000000000..0275833b792 --- /dev/null +++ b/soc/arm/renesas_rzt2m/Kconfig.soc @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RENESAS_RZT2M + bool "Renesas RZ/T2M MCU" + select ARM + select CPU_CORTEX_R52 + select CPU_HAS_ARM_MPU + select GIC_V3 + select GIC_SINGLE_SECURITY_STATE + select ARM_ARCH_TIMER + select SYSCON diff --git a/soc/arm/renesas_rzt2m/linker.ld b/soc/arm/renesas_rzt2m/linker.ld new file mode 100644 index 00000000000..3a016555ba9 --- /dev/null +++ b/soc/arm/renesas_rzt2m/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/arm/renesas_rzt2m/soc.c b/soc/arm/renesas_rzt2m/soc.c new file mode 100644 index 00000000000..5a854090229 --- /dev/null +++ b/soc/arm/renesas_rzt2m/soc.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "soc.h" +#include + +static const struct device *const prcrn_dev = DEVICE_DT_GET(DT_NODELABEL(prcrn)); +static const struct device *const prcrs_dev = DEVICE_DT_GET(DT_NODELABEL(prcrs)); + +void rzt2m_unlock_prcrn(uint32_t mask) +{ + uint32_t prcrn; + + syscon_read_reg(prcrn_dev, 0, &prcrn); + prcrn |= PRC_KEY_CODE | mask; + + syscon_write_reg(prcrn_dev, 0, prcrn); +} + +void rzt2m_lock_prcrn(uint32_t mask) +{ + uint32_t prcrn; + + syscon_read_reg(prcrn_dev, 0, &prcrn); + prcrn &= ~mask; + prcrn |= PRC_KEY_CODE; + + syscon_write_reg(prcrn_dev, 0, prcrn); +} + +void rzt2m_unlock_prcrs(uint32_t mask) +{ + uint32_t prcrs; + + syscon_read_reg(prcrs_dev, 0, &prcrs); + prcrs |= PRC_KEY_CODE | mask; + + syscon_write_reg(prcrs_dev, 0, prcrs); +} + +void rzt2m_lock_prcrs(uint32_t mask) +{ + uint32_t prcrs; + + syscon_read_reg(prcrs_dev, 0, &prcrs); + prcrs &= ~mask; + prcrs |= PRC_KEY_CODE; + + syscon_write_reg(prcrs_dev, 0, prcrs); +} + +void rzt2m_enable_counters(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(gsc)); + + syscon_write_reg(dev, 0, CNTCR_EN); +} + +static int rzt2m_init(void) +{ + /* Unlock the Protect Registers + * so that device drivers can access configuration registers of peripherals. + */ + /* After the device drivers are done, lock the Protect Registers. */ + + rzt2m_enable_counters(); + return 0; +} + +SYS_INIT(rzt2m_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/renesas_rzt2m/soc.h b/soc/arm/renesas_rzt2m/soc.h new file mode 100644 index 00000000000..02bd03b69a1 --- /dev/null +++ b/soc/arm/renesas_rzt2m/soc.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +/* Do not let CMSIS to handle GIC and Timer */ +#include +#define __GIC_PRESENT 0 +#define __TIM_PRESENT 0 + +/* Global system counter */ +#define CNTCR_EN BIT(0) +#define CNTCR_HDBG BIT(1) + +/* Safety area protect register */ +#define PRCRS_CLK BIT(0) +#define PRCRS_LPC_RESET BIT(1) +#define PRCRS_GPIO BIT(2) +#define PRCRS_SYS_CTRL BIT(3) + +/* Non-safety area protect register */ +#define PRCRN_PRC0 BIT(0) +#define PRCRN_PRC1 BIT(1) +#define PRCRN_PRC2 BIT(2) + +/* PRC Key Code - this value is required to allow any write operation + * to the PRCRS / PRCRN registers. + * See section 10.2 of the RZ/T2M User's Manual: Hardware. + */ +#define PRC_KEY_CODE 0xa500 + +void rzt2m_unlock_prcrn(uint32_t mask); +void rzt2m_lock_prcrn(uint32_t mask); +void rzt2m_unlock_prcrs(uint32_t mask); +void rzt2m_lock_prcrs(uint32_t mask); + +#endif /* _SOC__H_ */ From 4e35d0e3545c37473c6f11ff43282c9648483dc2 Mon Sep 17 00:00:00 2001 From: Wojciech Sipak Date: Thu, 10 Aug 2023 14:49:35 +0200 Subject: [PATCH 3662/4498] drivers: serial: add RZT2M uart driver This adds a UART driver for the Renesas RZ/T2M Serial Communication Interface. The driver implements: * Polling API, * Interrupt-driven API. Signed-off-by: Wojciech Sipak --- .../rzt2m_starterkit/rzt2m_starter_kit.dts | 10 + .../rzt2m_starter_kit_defconfig | 5 + drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 2 + drivers/serial/Kconfig.rzt2m | 11 + drivers/serial/uart_rzt2m.c | 435 ++++++++++++++++++ drivers/serial/uart_rzt2m.h | 124 +++++ dts/arm/renesas/rzt2m.dtsi | 25 + dts/bindings/serial/renesas,rzt2m-uart.yaml | 26 ++ 9 files changed, 639 insertions(+) create mode 100644 drivers/serial/Kconfig.rzt2m create mode 100644 drivers/serial/uart_rzt2m.c create mode 100644 drivers/serial/uart_rzt2m.h create mode 100644 dts/bindings/serial/renesas,rzt2m-uart.yaml diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts index 06b47819a1d..a9cb6bcf65a 100644 --- a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts @@ -13,5 +13,15 @@ chosen { zephyr,sram = &cpu0_atcm; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; }; }; + +&uart0 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig index 09e5e1d50a5..8b994e00082 100644 --- a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit_defconfig @@ -3,3 +3,8 @@ CONFIG_SOC_RENESAS_RZT2M=y CONFIG_BOARD_RZT2M_STARTER_KIT=y + +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index be0cbfd394b..bfc38603864 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -67,6 +67,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_INTEL_LW uart_intel_lw.c) zephyr_library_sources_ifdef(CONFIG_UART_RA uart_ra.c) +zephyr_library_sources_ifdef(CONFIG_UART_RZT2M uart_rzt2m.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 22916527ca1..5eb183c9a3e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -255,4 +255,6 @@ source "drivers/serial/Kconfig.intel_lw" source "drivers/serial/Kconfig.ra" +source "drivers/serial/Kconfig.rzt2m" + endif # SERIAL diff --git a/drivers/serial/Kconfig.rzt2m b/drivers/serial/Kconfig.rzt2m new file mode 100644 index 00000000000..bda26d628ad --- /dev/null +++ b/drivers/serial/Kconfig.rzt2m @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config UART_RZT2M + bool "Renesas RZ/T2M UART Driver" + default y + depends on DT_HAS_RENESAS_RZT2M_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + Enable Renesas RZ/T2M UART Driver. diff --git a/drivers/serial/uart_rzt2m.c b/drivers/serial/uart_rzt2m.c new file mode 100644 index 00000000000..afd012d5a8b --- /dev/null +++ b/drivers/serial/uart_rzt2m.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "uart_rzt2m.h" +#include "zephyr/spinlock.h" +#include "zephyr/sys/printk.h" +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT renesas_rzt2m_uart + +LOG_MODULE_REGISTER(uart_renesas_rzt2m, CONFIG_UART_LOG_LEVEL); + +struct rzt2m_device_config { + mm_reg_t base; + uart_irq_config_func_t irq_config_func; +}; + +struct rzt2m_device_data { + struct uart_config uart_cfg; + struct k_spinlock lock; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *callback_data; +#endif +}; + +static int rzt2m_poll_in(const struct device *dev, unsigned char *c) +{ + if (!dev || !dev->config || !dev->data) { + return -ENODEV; + } + + const struct rzt2m_device_config *config = dev->config; + struct rzt2m_device_data *data = dev->data; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (FRSR_R(*FRSR(config->base)) == 0) { + k_spin_unlock(&data->lock, key); + return -1; + } + *c = *RDR(config->base) & RDR_MASK_RDAT; + *CFCLR(config->base) |= CFCLR_MASK_RDRFC; + + if (FRSR_R(*FRSR(config->base)) == 0) { + *FFCLR(config->base) |= FFCLR_MASK_DRC; + } + + k_spin_unlock(&data->lock, key); + return 0; +} + +static void rzt2m_poll_out(const struct device *dev, unsigned char c) +{ + if (!dev || !dev->config || !dev->data) { + return; + } + + const struct rzt2m_device_config *config = dev->config; + struct rzt2m_device_data *data = dev->data; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + int fifo_count = FTSR_T(*FTSR(config->base)); + + while (fifo_count == MAX_FIFO_DEPTH) { + fifo_count = FTSR_T(*FTSR(config->base)); + } + + *TDR(config->base) = c; + + /* Clear `Transmit data empty flag`. */ + *CFCLR(config->base) |= CFCLR_MASK_TDREC; + + k_spin_unlock(&data->lock, key); +} + +static int rzt2m_err_check(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + + uint32_t status = *CSR(config->base); + uint32_t retval = 0; + + if (status & CSR_MASK_ORER) { + retval |= UART_ERROR_OVERRUN; + } + if (status & CSR_MASK_FER) { + retval |= UART_ERROR_FRAMING; + } + if (status & CSR_MASK_PER) { + retval |= UART_ERROR_PARITY; + } + + return retval; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static int uart_rzt2m_irq_tx_ready(const struct device *dev); + +static int rzt2m_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + struct rzt2m_device_data *data = dev->data; + const struct rzt2m_device_config *config = dev->config; + int num_tx = 0; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + while ((size - num_tx > 0) && uart_rzt2m_irq_tx_ready(dev)) { + *TDR(config->base) = (uint8_t)tx_data[num_tx++]; + } + + k_spin_unlock(&data->lock, key); + return num_tx; +} + +static int rzt2m_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + struct rzt2m_device_data *data = dev->data; + const struct rzt2m_device_config *config = dev->config; + int num_rx = 0; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + while (num_rx < size && (FRSR_R(*FRSR(config->base)))) { + rx_data[num_rx++] = *RDR(config->base); + } + *CFCLR(config->base) = CFCLR_MASK_RDRFC; + *FFCLR(config->base) = FFCLR_MASK_DRC; + k_spin_unlock(&data->lock, key); + return num_rx; +} + +static void uart_rzt2m_irq_rx_enable(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + *CCR0(config->base) |= CCR0_MASK_RIE | CCR0_MASK_RE; +} + +static void uart_rzt2m_irq_rx_disable(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + *CCR0(config->base) &= ~CCR0_MASK_RIE; +} + +static void uart_rzt2m_irq_tx_enable(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + /* These bits must be set simultaneously. */ + *CCR0(config->base) |= CCR0_MASK_TE | CCR0_MASK_TIE | CCR0_MASK_TEIE; +} + +static void uart_rzt2m_irq_tx_disable(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + *CCR0(config->base) &= ~(CCR0_MASK_TIE | CCR0_MASK_TEIE); +} + +static int uart_rzt2m_irq_tx_ready(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + + if (FTSR_T(*FTSR(config->base)) == MAX_FIFO_DEPTH || + ((*CCR0(config->base) & CCR0_MASK_TIE) == 0)) { + return 0; + } + + return 1; +} + +static int uart_rzt2m_irq_rx_ready(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + + if (FRSR_R(*FRSR(config->base))) { + return 1; + } + + return 0; +} + +static int uart_rzt2m_irq_is_pending(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + + if ((*CSR(config->base) & (CSR_MASK_RDRF)) || (*FRSR(config->base) & FRSR_MASK_DR)) { + return 1; + } + return 0; +} + +static void uart_rzt2m_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct rzt2m_device_data *data = dev->data; + + data->callback = cb; + data->callback_data = cb_data; +} + +static int uart_rzt2m_irq_update(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + + *CFCLR(config->base) = CFCLR_MASK_RDRFC; + *FFCLR(config->base) = FFCLR_MASK_DRC; + return 1; +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api rzt2m_uart_api = { + .poll_in = rzt2m_poll_in, + .poll_out = rzt2m_poll_out, + .err_check = rzt2m_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = rzt2m_fifo_fill, + .fifo_read = rzt2m_fifo_read, + .irq_rx_enable = uart_rzt2m_irq_rx_enable, + .irq_rx_disable = uart_rzt2m_irq_rx_disable, + .irq_tx_enable = uart_rzt2m_irq_tx_enable, + .irq_tx_disable = uart_rzt2m_irq_tx_disable, + .irq_tx_ready = uart_rzt2m_irq_tx_ready, + .irq_rx_ready = uart_rzt2m_irq_rx_ready, + .irq_is_pending = uart_rzt2m_irq_is_pending, + .irq_callback_set = uart_rzt2m_irq_callback_set, + .irq_update = uart_rzt2m_irq_update, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +static int rzt2m_module_start(const struct device *dev) +{ + if (!dev || !dev->config || !dev->data) { + return -ENODEV; + } + + const struct rzt2m_device_config *config = dev->config; + struct rzt2m_device_data *data = dev->data; + int interface_id = BASE_TO_IFACE_ID(config->base); + unsigned int irqkey = irq_lock(); + volatile uint32_t dummy; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (interface_id < 5) { + /* Dummy-read at least one time as stated in 8.3.1 of the User's Manual: Hardware */ + *MSTPCRA &= ~(MSTPCRA_MASK_SCIx(interface_id)); + dummy = *MSTPCRA; + } else { + LOG_ERR("SCI modules in the secure domain on RZT2M are not supported."); + return -ENOTSUP; + } + + /* Dummy-read at least five times as stated in 8.3.1 of the User's Manual: Hardware */ + dummy = *RDR(config->base); + dummy = *RDR(config->base); + dummy = *RDR(config->base); + dummy = *RDR(config->base); + dummy = *RDR(config->base); + + k_spin_unlock(&data->lock, key); + irq_unlock(irqkey); + return 0; +} + +static int rzt2m_uart_init(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; + struct rzt2m_device_data *data = dev->data; + uint32_t baud_setting = 0; + uint32_t baud_settings[] = {CCR2_BAUD_SETTING_9600, CCR2_BAUD_SETTING_115200}; + + rzt2m_unlock_prcrs(PRCRS_GPIO); + rzt2m_unlock_prcrn(PRCRN_PRC1 | PRCRN_PRC2); + + /* The module needs to be started + * to allow any operation on the registers of Serial Communications Interface. + */ + int ret = rzt2m_module_start(dev); + + if (ret) { + return ret; + } + + /* Disable transmitter, receiver, interrupts. */ + *CCR0(config->base) = CCR0_DEFAULT_VALUE; + while (*CCR0(config->base) & (CCR0_MASK_RE | CCR0_MASK_TE)) { + } + + *CCR1(config->base) = CCR1_DEFAULT_VALUE; + *CCR2(config->base) = CCR2_DEFAULT_VALUE; + *CCR3(config->base) = CCR3_DEFAULT_VALUE; + *CCR4(config->base) = CCR4_DEFAULT_VALUE; + + *CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR; + *FFCLR(config->base) = FFCLR_MASK_DRC; + + /* Use FIFO mode. */ + *CCR3(config->base) |= (CCR3_MASK_FM); + + switch (data->uart_cfg.stop_bits) { + case UART_CFG_STOP_BITS_1: + /* Default value, already set. */ + break; + case UART_CFG_STOP_BITS_2: + *CCR3(config->base) |= CCR3_MASK_STP; + break; + default: + LOG_ERR("Selected bit stop length is not supported: %u.", data->uart_cfg.stop_bits); + return -ENOTSUP; + } + + switch (data->uart_cfg.data_bits) { + case UART_CFG_DATA_BITS_7: + *CCR3(config->base) |= CCR3_CHR_7BIT; + break; + case UART_CFG_DATA_BITS_8: + *CCR3(config->base) |= CCR3_CHR_8BIT; + break; + default: + LOG_ERR("Selected number of data bits is not supported: %u.", + data->uart_cfg.data_bits); + return -ENOTSUP; + } + + if (data->uart_cfg.baudrate > ARRAY_SIZE(baud_settings)) { + LOG_ERR("Selected baudrate variant is not supported: %u.", data->uart_cfg.baudrate); + return -ENOTSUP; + } + baud_setting = baud_settings[data->uart_cfg.baudrate]; + + *CCR2(config->base) &= ~(CCR2_MASK_BAUD_SETTING); + *CCR2(config->base) |= (baud_setting & CCR2_MASK_BAUD_SETTING); + + *CCR1(config->base) |= (CCR1_MASK_NFEN | CCR1_MASK_SPB2DT | CCR1_MASK_SPB2IO); + + switch (data->uart_cfg.parity) { + case UART_CFG_PARITY_NONE: + /* Default value, already set. */ + break; + case UART_CFG_PARITY_EVEN: + *CCR1(config->base) |= CCR1_MASK_PE; + break; + case UART_CFG_PARITY_ODD: + *CCR1(config->base) |= (CCR1_MASK_PE | CCR1_MASK_PM); + break; + default: + LOG_ERR("Unsupported parity: %u", data->uart_cfg.parity); + } + + /* Specify trigger thresholds and clear FIFOs. */ + *FCR(config->base) = FCR_MASK_TFRST | FCR_MASK_RFRST | FCR_TTRG_15 | FCR_RTRG_15; + + /* Enable the clock. */ + *CCR3(config->base) &= ~CCR3_MASK_CKE; + *CCR3(config->base) |= CCR3_CKE_ENABLE; + + /* Clear status flags. */ + *CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR; + *FFCLR(config->base) = FFCLR_MASK_DRC; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + config->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + /* Start trasmitter and receiver. */ + *CCR0(config->base) |= (CCR0_MASK_TE | CCR0_MASK_RE); + while (!(*CCR0(config->base) & CCR0_MASK_RE)) { + } + while (!(*CCR0(config->base) & CCR0_MASK_TE)) { + } + + rzt2m_lock_prcrs(PRCRS_GPIO); + rzt2m_lock_prcrn(PRCRN_PRC1 | PRCRN_PRC2); + + return 0; +} + +static void uart_rzt2m_isr(const struct device *dev) +{ + const struct rzt2m_device_config *config = dev->config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + struct rzt2m_device_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->callback_data); + } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + *CFCLR(config->base) = CFCLR_MASK_RDRFC; + *FFCLR(config->base) = FFCLR_MASK_DRC; +} + +#define UART_RZT2M_IRQ_CONNECT(n, irq_name) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, irq_name, irq), \ + DT_INST_IRQ_BY_NAME(n, irq_name, priority), uart_rzt2m_isr, \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ_BY_NAME(n, irq_name, flags)); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, irq_name, irq)); \ + } while (false) + +#define UART_RZT2M_CONFIG_FUNC(n) \ + static void uart##n##_rzt2m_irq_config(const struct device *port) \ + { \ + UART_RZT2M_IRQ_CONNECT(n, rx_err); \ + UART_RZT2M_IRQ_CONNECT(n, rx); \ + UART_RZT2M_IRQ_CONNECT(n, tx); \ + UART_RZT2M_IRQ_CONNECT(n, tx_end); \ + } + +#define UART_RZT2M_INIT(n) \ + static struct rzt2m_device_data rzt2m_uart_##n##data = { \ + .uart_cfg = \ + { \ + .baudrate = DT_INST_ENUM_IDX(n, current_speed), \ + .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + .stop_bits = \ + DT_INST_ENUM_IDX_OR(n, stop_bits, UART_CFG_STOP_BITS_1), \ + .data_bits = \ + DT_INST_ENUM_IDX_OR(n, data_bits, UART_CFG_DATA_BITS_8), \ + }, \ + }; \ + UART_RZT2M_CONFIG_FUNC(n); \ + static const struct rzt2m_device_config rzt2m_uart_##n##_config = { \ + .base = DT_INST_REG_ADDR(n), .irq_config_func = uart##n##_rzt2m_irq_config}; \ + DEVICE_DT_INST_DEFINE(n, &rzt2m_uart_init, NULL, &rzt2m_uart_##n##data, \ + &rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &rzt2m_uart_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_RZT2M_INIT) diff --git a/drivers/serial/uart_rzt2m.h b/drivers/serial/uart_rzt2m.h new file mode 100644 index 00000000000..829064857b0 --- /dev/null +++ b/drivers/serial/uart_rzt2m.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SERIAL_UART_RZT2M_H_ +#define ZEPHYR_DRIVERS_SERIAL_UART_RZT2M_H_ + +#include + +#define MAX_FIFO_DEPTH 16 + +#define RDR(base) ((volatile uint32_t *)(base)) +#define TDR(base) ((volatile uint32_t *)(base + 0x04)) +#define CCR0(base) ((volatile uint32_t *)(base + 0x08)) +#define CCR1(base) ((volatile uint32_t *)(base + 0x0c)) +#define CCR2(base) ((volatile uint32_t *)(base + 0x10)) +#define CCR3(base) ((volatile uint32_t *)(base + 0x14)) +#define CCR4(base) ((volatile uint32_t *)(base + 0x18)) +#define FCR(base) ((volatile uint32_t *)(base + 0x24)) +#define CSR(base) ((volatile uint32_t *)(base + 0x48)) +#define FRSR(base) ((volatile uint32_t *)(base + 0x50)) +#define FTSR(base) ((volatile uint32_t *)(base + 0x54)) +#define CFCLR(base) ((volatile uint32_t *)(base + 0x68)) +#define FFCLR(base) ((volatile uint32_t *)(base + 0x70)) + +#define CCR0_DEFAULT_VALUE 0x0 +#define CCR1_DEFAULT_VALUE 0x00000010 +#define CCR2_DEFAULT_VALUE 0xff00ff04 +#define CCR3_DEFAULT_VALUE 0x00001203 +#define CCR4_DEFAULT_VALUE 0x0 + +#define RDR_MASK_RDAT GENMASK(8, 0) + +#define CCR0_MASK_RE BIT(0) +#define CCR0_MASK_TE BIT(4) +#define CCR0_MASK_DCME BIT(9) +#define CCR0_MASK_IDSEL BIT(10) +#define CCR0_MASK_RIE BIT(16) +#define CCR0_MASK_TIE BIT(20) +#define CCR0_MASK_TEIE BIT(21) +#define CCR0_MASK_SSE BIT(24) + +#define CCR1_MASK_CTSE BIT(0) +#define CCR1_MASK_SPB2DT BIT(4) +#define CCR1_MASK_SPB2IO BIT(5) +#define CCR1_MASK_PE BIT(8) +#define CCR1_MASK_PM BIT(9) +#define CCR1_MASK_NFEN BIT(28) + +#define CCR2_MASK_BGDM BIT(4) +#define CCR2_MASK_ABCS BIT(5) +#define CCR2_MASK_ABCSE BIT(6) +#define CCR2_MASK_BRR GENMASK(15, 8) +#define CCR2_MASK_BRME BIT(16) +#define CCR2_MASK_CKS GENMASK(21, 20) +#define CCR2_MASK_MDDR GENMASK(31, 24) +#define CCR2_MASK_BAUD_SETTING \ + (CCR2_MASK_BRME | CCR2_MASK_ABCSE | CCR2_MASK_ABCS | CCR2_MASK_BGDM | CCR2_MASK_CKS | \ + CCR2_MASK_BRR | CCR2_MASK_MDDR) + +#define CCR3_MASK_STP BIT(14) +#define CCR3_MASK_MP BIT(19) +#define CCR3_MASK_FM BIT(20) +#define CCR3_MASK_CKE (BIT(24) | BIT(25)) +#define CCR3_CKE_ENABLE BIT(24) +#define CCR3_CHR_7BIT (BIT(8) | BIT(9)) +#define CCR3_CHR_8BIT BIT(9) + +#define CCR4_MASK_ASEN BIT(16) +#define CCR4_MASK_ATEN BIT(17) + +#define FCR_MASK_TFRST BIT(15) +#define FCR_MASK_RFRST BIT(23) +#define FCR_MASK_TTRG GENMASK(12, 8) +#define FCR_MASK_RTRG GENMASK(20, 16) +#define FCR_TTRG_15 (15 << 8) +#define FCR_RTRG_15 (15 << 16) + +#define CSR_MASK_ORER BIT(24) +#define CSR_MASK_PER BIT(27) +#define CSR_MASK_FER BIT(28) +#define CSR_MASK_TDRE BIT(29) +#define CSR_MASK_TEND BIT(30) +#define CSR_MASK_RDRF BIT(31) + +#define FRSR_MASK_DR BIT(0) +#define FRSR_R(val) ((val >> 7) & 0x3f) + +#define FTSR_T(val) (val & 0x3f) + +#define CFCLR_MASK_ERSC BIT(4) +#define CFCLR_MASK_DCMFC BIT(16) +#define CFCLR_MASK_DPERC BIT(17) +#define CFCLR_MASK_DFERC BIT(18) +#define CFCLR_MASK_ORERC BIT(24) +#define CFCLR_MASK_MFFC BIT(26) +#define CFCLR_MASK_PERC BIT(27) +#define CFCLR_MASK_FERC BIT(28) +#define CFCLR_MASK_TDREC BIT(29) +#define CFCLR_MASK_RDRFC BIT(31) +#define CFCLR_ALL_FLAG_CLEAR \ + (CFCLR_MASK_ERSC | CFCLR_MASK_DCMFC | CFCLR_MASK_DPERC | CFCLR_MASK_DFERC | \ + CFCLR_MASK_ORERC | CFCLR_MASK_MFFC | CFCLR_MASK_PERC | CFCLR_MASK_FERC | \ + CFCLR_MASK_TDREC | CFCLR_MASK_RDRFC) + +#define FFCLR_MASK_DRC BIT(0) + +#define MSTPCRA (volatile uint32_t *)(0x80280000 + 0x300) +#define MSTPCRA_MASK_SCIx(x) BIT(x + 8) +#define BASE_TO_IFACE_ID(base) ((base & 0x1000000) ? 5 : ((base & 0xff00) >> 10) - 4) + +#define CCR2_MDDR_128 BIT(31) +#define CCR2_CKS_0 0 +#define CCR2_BRME_0 0 +#define CCR2_BRR_243 (0xf3 << 8) +#define CCR2_BRR_39 (0x27 << 8) +#define CCR2_BGDM_1 BIT(4) + +#define CCR2_BAUD_SETTING_9600 (CCR2_MDDR_128 | CCR2_BRR_243) +#define CCR2_BAUD_SETTING_115200 (CCR2_MDDR_128 | CCR2_BRR_39 | CCR2_BGDM_1) + +#endif /* ZEPHYR_DRIVERS_SERIAL_UART_RZT2M_H_ */ diff --git a/dts/arm/renesas/rzt2m.dtsi b/dts/arm/renesas/rzt2m.dtsi index 44e045014a9..7ac60cdf99c 100644 --- a/dts/arm/renesas/rzt2m.dtsi +++ b/dts/arm/renesas/rzt2m.dtsi @@ -88,5 +88,30 @@ reg = <0x81281a00 0x10>; reg-io-width = <4>; }; + + uart0: serial@80001000 { + compatible = "renesas,rzt2m-uart"; + reg = <0x80001000 0x1000>; + current-speed = <115200>; + interrupts = , + , + , + ; + interrupt-names = "rx_err", "rx", "tx", "tx_end"; + status = "disabled"; + }; + + uart3: serial@80001c00 { + compatible = "renesas,rzt2m-uart"; + reg = <0x80001c00 0x1000>; + current-speed = <115200>; + interrupts = , + , + , + ; + interrupt-names = "rx_err", "rx", "tx", "tx_end"; + status = "disabled"; + }; + }; }; diff --git a/dts/bindings/serial/renesas,rzt2m-uart.yaml b/dts/bindings/serial/renesas,rzt2m-uart.yaml new file mode 100644 index 00000000000..967972ac7c8 --- /dev/null +++ b/dts/bindings/serial/renesas,rzt2m-uart.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ/T2M UART + +compatible: "renesas,rzt2m-uart" + +include: + - name: uart-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + current-speed: + required: true + description: | + Initial baud rate setting for UART. Only a fixed set of baud + rates is currently supported. + enum: + - 9600 + - 115200 + + interrupts: + required: true From 9e44f59e9a27f44d0ac9dd428536914e00b82ad4 Mon Sep 17 00:00:00 2001 From: Wojciech Sipak Date: Wed, 4 Oct 2023 15:38:30 +0200 Subject: [PATCH 3663/4498] drivers: pinctrl: add RZT2M driver This adds a new driver for Renesas RZ/T2M. The driver allows configuration of pin direction, pull up/down resistors, drive strength and slew rate, and selection of function for a pin. Signed-off-by: Wojciech Sipak --- .../rzt2m_starterkit/rzt2m_starter_kit.dts | 27 ++++++ drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.rzt2m | 9 ++ drivers/pinctrl/pinctrl_rzt2m.c | 63 +++++++++++++ drivers/serial/Kconfig.rzt2m | 1 + drivers/serial/uart_rzt2m.c | 13 ++- dts/arm/renesas/rzt2m.dtsi | 5 + .../pinctrl/renesas,rzt2m-pinctrl.yaml | 93 +++++++++++++++++++ .../pinctrl/renesas-rzt2m-pinctrl.h | 18 ++++ soc/arm/renesas_rzt2m/pinctrl_soc.h | 57 ++++++++++++ 11 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/Kconfig.rzt2m create mode 100644 drivers/pinctrl/pinctrl_rzt2m.c create mode 100644 dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h create mode 100644 soc/arm/renesas_rzt2m/pinctrl_soc.h diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts index a9cb6bcf65a..ddada360b99 100644 --- a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts @@ -5,6 +5,7 @@ */ /dts-v1/; +#include #include / { @@ -18,10 +19,36 @@ }; }; + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + uart3_default: uart3_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; +}; + &uart0 { status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; }; &uart3 { status = "okay"; + pinctrl-0 = <&uart3_default>; + pinctrl-names = "default"; }; diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index ba49a637689..9455b6e7c78 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -37,3 +37,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M pinctrl_rzt2m.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b7dc6c2fa69..8a165725e4d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -65,5 +65,6 @@ source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" source "drivers/pinctrl/Kconfig.ra" +source "drivers/pinctrl/Kconfig.rzt2m" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.rzt2m b/drivers/pinctrl/Kconfig.rzt2m new file mode 100644 index 00000000000..236afdcf55e --- /dev/null +++ b/drivers/pinctrl/Kconfig.rzt2m @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_RZT2M + bool "Renesas RZ/T2M pin controller driver" + default y + depends on DT_HAS_RENESAS_RZT2M_PINCTRL_ENABLED + help + Renesas RZ/T2M pinctrl driver diff --git a/drivers/pinctrl/pinctrl_rzt2m.c b/drivers/pinctrl/pinctrl_rzt2m.c new file mode 100644 index 00000000000..0dff4461903 --- /dev/null +++ b/drivers/pinctrl/pinctrl_rzt2m.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rzt2m_pinctrl + +#include +#include +#include + +#define PORT_NSR DT_INST_REG_ADDR_BY_NAME(0, port_nsr) +#define PTADR DT_INST_REG_ADDR_BY_NAME(0, ptadr) + +/* Port m mode control register */ +#define PMC(port) (PORT_NSR + 0x400 + port) +/* Port m function control register */ +#define PFC(port) (PORT_NSR + 0x600 + (0x4 * port)) +/* IO Buffer m function switching register */ +#define DRCTL(port, pin) (PORT_NSR + 0xa00 + (0x8 * port) + pin) +/* Port m region select register */ +#define RSELP(port) (PTADR + port) + +#define DRCTL_DRIVE_STRENGTH(val) (val & 0x3) +#define DRCTL_PULL_UP_DOWN(val) ((val & 0x3) << 2) +#define DRCTL_SCHMITT(val) ((val & 0x1) << 4) +#define DRCTL_SLEW_RATE(val) ((val & 0x1) << 5) +#define DRCTL_CONFIG(drive, pull, schmitt, slew) \ + (DRCTL_DRIVE_STRENGTH(drive) | DRCTL_PULL_UP_DOWN(pull) | DRCTL_SCHMITT(schmitt) | \ + DRCTL_SLEW_RATE(slew)) +#define PFC_FUNC_MASK(pin) (0xf << (pin * 4)) + +static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint8_t rselp = sys_read8(RSELP(pin->port)); + uint32_t pfc = sys_read32(PFC(pin->port)) & ~(PFC_FUNC_MASK(pin->pin)); + uint8_t pmc = sys_read8(PMC(pin->port)); + + /* Set proper bit in the RSELP register to use as non-safety domain. */ + sys_write8(rselp | BIT(pin->pin), RSELP(pin->port)); + sys_write8(DRCTL_CONFIG( + pin->drive_strength, (pin->pull_up == 1 ? 1U : (pin->pull_down == 1 ? 2U : 0)), + pin->schmitt_enable, pin->slew_rate), + DRCTL(pin->port, pin->pin)); + + /* Select function for the pin. */ + sys_write32(pfc | pin->func << (pin->pin * 4), PFC(pin->port)); + + /* Set proper bit in the PMC register to use the pin as a peripheral IO. */ + sys_write8(pmc | BIT(pin->pin), PMC(pin->port)); +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinctrl_configure_pin(pins++); + } + + return 0; +} diff --git a/drivers/serial/Kconfig.rzt2m b/drivers/serial/Kconfig.rzt2m index bda26d628ad..2561499a5b5 100644 --- a/drivers/serial/Kconfig.rzt2m +++ b/drivers/serial/Kconfig.rzt2m @@ -7,5 +7,6 @@ config UART_RZT2M depends on DT_HAS_RENESAS_RZT2M_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL help Enable Renesas RZ/T2M UART Driver. diff --git a/drivers/serial/uart_rzt2m.c b/drivers/serial/uart_rzt2m.c index afd012d5a8b..e4ebe251f21 100644 --- a/drivers/serial/uart_rzt2m.c +++ b/drivers/serial/uart_rzt2m.c @@ -8,6 +8,7 @@ #include "zephyr/spinlock.h" #include "zephyr/sys/printk.h" #include +#include #include #include #include @@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(uart_renesas_rzt2m, CONFIG_UART_LOG_LEVEL); struct rzt2m_device_config { mm_reg_t base; + const struct pinctrl_dev_config *pin_config; uart_irq_config_func_t irq_config_func; }; @@ -297,6 +299,12 @@ static int rzt2m_uart_init(const struct device *dev) *CCR3(config->base) = CCR3_DEFAULT_VALUE; *CCR4(config->base) = CCR4_DEFAULT_VALUE; + /* Configure pinmuxes */ + ret = pinctrl_apply_state(config->pin_config, PINCTRL_STATE_DEFAULT); + if (ret) { + return ret; + } + *CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR; *FFCLR(config->base) = FFCLR_MASK_DRC; @@ -414,6 +422,7 @@ static void uart_rzt2m_isr(const struct device *dev) } #define UART_RZT2M_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ static struct rzt2m_device_data rzt2m_uart_##n##data = { \ .uart_cfg = \ { \ @@ -427,7 +436,9 @@ static void uart_rzt2m_isr(const struct device *dev) }; \ UART_RZT2M_CONFIG_FUNC(n); \ static const struct rzt2m_device_config rzt2m_uart_##n##_config = { \ - .base = DT_INST_REG_ADDR(n), .irq_config_func = uart##n##_rzt2m_irq_config}; \ + .base = DT_INST_REG_ADDR(n), \ + .irq_config_func = uart##n##_rzt2m_irq_config, \ + .pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \ DEVICE_DT_INST_DEFINE(n, &rzt2m_uart_init, NULL, &rzt2m_uart_##n##data, \ &rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ &rzt2m_uart_api); diff --git a/dts/arm/renesas/rzt2m.dtsi b/dts/arm/renesas/rzt2m.dtsi index 7ac60cdf99c..dada6ea55c7 100644 --- a/dts/arm/renesas/rzt2m.dtsi +++ b/dts/arm/renesas/rzt2m.dtsi @@ -113,5 +113,10 @@ status = "disabled"; }; + pinctrl: pinctrl@800a0000 { + compatible = "renesas,rzt2m-pinctrl"; + reg = <0x800a0000 0x1000 0x81030c00 0x1000>; + reg-names = "port_nsr", "ptadr"; + }; }; }; diff --git a/dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml new file mode 100644 index 00000000000..82016017201 --- /dev/null +++ b/dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml @@ -0,0 +1,93 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Renesas RZ/T2M pin controller is a node responsible for controlling + pin function selection and pin properties, such as routing the TX and RX of UART0 + to pin 5 and pin 6 of port 16. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as shown in this example: + + /* You can put this in places like a board-pinctrl.dtsi file in + * your board directory, or a devicetree overlay in your application. + */ + + /* include pre-defined combinations for the SoC variant used by the board */ + #include + + &pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + }; + + The 'uart0_default' child node encodes the pin configurations for a + particular state of a device; in this case, the default (that is, active) + state. + + As shown, pin configurations are organized in groups within each child node. + Each group can specify a list of pin function selections in the 'pinmux' + property. + + A group can also specify shared pin properties common to all the specified + pins, such as the 'input-enable' property in group 2. + +compatible: "renesas,rzt2m-pinctrl" + +include: base.yaml + +child-binding: + description: | + Definitions for a pinctrl state. + child-binding: + + include: + - name: pincfg-node.yaml + property-allowlist: + - input-enable + - bias-pull-up + - bias-pull-down + - bias-high-impedance + - input-schmitt-enable + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. Each + element of the array is an integer constructed from the + pin number and the alternative function of the pin. + drive-strength: + type: string + enum: + - "low" + - "middle" + - "high" + - "ultrahigh" + default: "low" + description: | + The drive strength of a pin, relative to full-driver strength. + The default value is "low", which is the reset value. + slew-rate: + type: string + enum: + - "slow" + - "fast" + default: "slow" + description: | + Select slew rate for a pin. The default is slow, which is the reset value. diff --git a/include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h new file mode 100644 index 00000000000..ed1cbf7ee96 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RENESAS_RZT2M_PINCTRL_H__ +#define __RENESAS_RZT2M_PINCTRL_H__ + +#define RZT2M_PINMUX(port, pin, func) ((port << 16) | (pin << 8) | func) + +#define UART0TX_P16_5 RZT2M_PINMUX(16, 5, 1) +#define UART0RX_P16_6 RZT2M_PINMUX(16, 6, 2) + +#define UART3TX_P18_0 RZT2M_PINMUX(18, 0, 4) +#define UART3RX_P17_7 RZT2M_PINMUX(17, 7, 4) + +#endif /* __RENESAS_RZT2M_PINCTRL_H__ */ diff --git a/soc/arm/renesas_rzt2m/pinctrl_soc.h b/soc/arm/renesas_rzt2m/pinctrl_soc.h new file mode 100644 index 00000000000..d740d6c115e --- /dev/null +++ b/soc/arm/renesas_rzt2m/pinctrl_soc.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_ +#define ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pinctrl_soc_pin_t { + uint32_t port; + uint32_t pin; + uint32_t func; + uint32_t input_enable: 1; + uint32_t output_enable: 1; + uint32_t pull_up: 1; + uint32_t pull_down: 1; + uint32_t high_impedance: 1; + uint32_t slew_rate: 2; + uint8_t drive_strength; + uint32_t schmitt_enable: 1; +} pinctrl_soc_pin_t; + +#define RZT2M_GET_PORT(pinctrl) ((pinctrl >> 16) & 0xff) +#define RZT2M_GET_PIN(pinctrl) ((pinctrl >> 8) & 0xff) +#define RZT2M_GET_FUNC(pinctrl) (pinctrl & 0xff) + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .port = RZT2M_GET_PORT(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .pin = RZT2M_GET_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .func = RZT2M_GET_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .input_enable = DT_PROP(node_id, input_enable), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .high_impedance = DT_PROP(node_id, bias_high_impedance), \ + .slew_rate = DT_ENUM_IDX(node_id, slew_rate), \ + .drive_strength = DT_ENUM_IDX(node_id, drive_strength), \ + .schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_ */ From 9265d2de0cd6f72e96e609ab0adbb9e6976bb09a Mon Sep 17 00:00:00 2001 From: Jakub Michalski Date: Tue, 3 Oct 2023 12:42:32 +0200 Subject: [PATCH 3664/4498] drivers: gpio: add rzt2m gpio driver Add Renesas rzt2m gpio driver with basic functionality. It supports pin mode configuration and writing/reading to/from gpio ports. Includes dts changes to build blinky sample. Signed-off-by: Jakub Michalski --- .../rzt2m_starterkit/rzt2m_starter_kit.dts | 24 ++ drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.rzt2m | 9 + drivers/gpio/gpio_rzt2m.c | 233 ++++++++++++++++++ dts/arm/renesas/rzt2m.dtsi | 26 ++ dts/bindings/gpio/renesas,rzt2m-gpio.yaml | 18 ++ .../dt-bindings/gpio/renesas-rzt2m-gpio.h | 39 +++ 8 files changed, 352 insertions(+) create mode 100644 drivers/gpio/Kconfig.rzt2m create mode 100644 drivers/gpio/gpio_rzt2m.c create mode 100644 dts/bindings/gpio/renesas,rzt2m-gpio.yaml create mode 100644 include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h diff --git a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts index ddada360b99..2568a542b5e 100644 --- a/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts +++ b/boards/arm/rzt2m_starterkit/rzt2m_starter_kit.dts @@ -17,6 +17,30 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; }; + + aliases { + led0 = &led0; + }; + + leds { + compatible = "gpio-leds"; + led0: led0 { + gpios = <&gpio19 6 0>; + label = "led0"; + }; + led1: led1 { + gpios = <&gpio19 4 0>; + label = "led1"; + }; + led2: led2 { + gpios = <&gpio20 0 0>; + label = "led2"; + }; + led3: led3 { + gpios = <&gpio23 4 0>; + label = "led3"; + }; + }; }; diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 19c9d3e976c..0e94d78dba3 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -87,6 +87,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RA gpio_ra.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_RZT2M gpio_rzt2m.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 92d7b0587e9..7ae1a8d0d93 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -214,4 +214,6 @@ source "drivers/gpio/Kconfig.bcm2711" source "drivers/gpio/Kconfig.ra" +source "drivers/gpio/Kconfig.rzt2m" + endif # GPIO diff --git a/drivers/gpio/Kconfig.rzt2m b/drivers/gpio/Kconfig.rzt2m new file mode 100644 index 00000000000..d9cb6b1e867 --- /dev/null +++ b/drivers/gpio/Kconfig.rzt2m @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_RZT2M + bool "Renesas RZT2M GPIO" + default y + depends on DT_HAS_RENESAS_RZT2M_GPIO_ENABLED + help + Enable Renesas RZT2M GPIO driver. diff --git a/drivers/gpio/gpio_rzt2m.c b/drivers/gpio/gpio_rzt2m.c new file mode 100644 index 00000000000..c2bfd1a4acd --- /dev/null +++ b/drivers/gpio/gpio_rzt2m.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rzt2m_gpio + +#include +#include +#include +#include +#include +#include +#include + +#define PMm_OFFSET 0x200 +#define PINm_OFFSET 0x800 +#define DRCTLm_OFFSET 0xa00 + +#define DRIVE_SHIFT 0 +#define SCHMITT_TRIGGER_SHIFT 4 +#define SLEW_RATE_SHIFT 5 + +#define PULL_SHIFT 2 +#define PULL_NONE (0 << PULL_SHIFT) +#define PULL_UP (1 << PULL_SHIFT) +#define PULL_DOWN (2 << PULL_SHIFT) + +struct rzt2m_gpio_config { + struct gpio_driver_config common; + uint8_t *port_nsr; + uint8_t *ptadr; + uint8_t port; +}; + +struct rzt2m_gpio_data { + struct gpio_driver_data common; +}; + +static void rzt2m_gpio_unlock(void) +{ + rzt2m_unlock_prcrn(PRCRN_PRC1); + rzt2m_unlock_prcrs(PRCRS_GPIO); +} + +static void rzt2m_gpio_lock(void) +{ + rzt2m_lock_prcrn(PRCRN_PRC1); + rzt2m_lock_prcrs(PRCRS_GPIO); +} + +/* Port m output data store */ +static volatile uint8_t *rzt2m_gpio_get_p_reg(const struct device *dev) +{ + const struct rzt2m_gpio_config *config = dev->config; + + return (volatile uint8_t *)(config->port_nsr + config->port); +} + +/* Port m input data store */ +static volatile uint8_t *rzt2m_gpio_get_pin_reg(const struct device *dev) +{ + const struct rzt2m_gpio_config *config = dev->config; + + return (volatile uint8_t *)(config->port_nsr + PINm_OFFSET + config->port); +} + +/* Port m mode register */ +static volatile uint16_t *rzt2m_gpio_get_pm_reg(const struct device *dev) +{ + const struct rzt2m_gpio_config *config = dev->config; + + return (volatile uint16_t *)(config->port_nsr + PMm_OFFSET + 0x2 * config->port); +} + +/* IO Buffer m function switching register */ +static volatile uint64_t *rzt2m_gpio_get_drctl_reg(const struct device *dev) +{ + const struct rzt2m_gpio_config *config = dev->config; + + return (volatile uint64_t *)(config->port_nsr + DRCTLm_OFFSET + 0x8 * config->port); +} + +/* Port m region select register */ +static volatile uint8_t *rzt2m_gpio_get_rselp_reg(const struct device *dev) +{ + const struct rzt2m_gpio_config *config = dev->config; + + return (volatile uint8_t *)(config->ptadr + config->port); +} + +static int rzt2m_gpio_init(const struct device *dev) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *rselp_reg = rzt2m_gpio_get_rselp_reg(dev); + *rselp_reg = 0xFF; + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_gpio_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *pin_reg = rzt2m_gpio_get_pin_reg(dev); + *value = *pin_reg; + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev); + *p_reg = (*p_reg & ~mask) | (value & mask); + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev); + *p_reg |= pins; + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev); + *p_reg &= ~pins; + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_gpio_toggle(const struct device *dev, gpio_port_pins_t pins) +{ + rzt2m_gpio_unlock(); + + volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev); + *p_reg ^= pins; + + rzt2m_gpio_lock(); + + return 0; +} + +static int rzt2m_gpio_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + volatile uint16_t *pm_reg = rzt2m_gpio_get_pm_reg(dev); + volatile uint64_t *drctl_reg = rzt2m_gpio_get_drctl_reg(dev); + + rzt2m_gpio_unlock(); + + WRITE_BIT(*pm_reg, pin * 2, flags & GPIO_INPUT); + WRITE_BIT(*pm_reg, pin * 2 + 1, flags & GPIO_OUTPUT); + + if (flags & GPIO_OUTPUT) { + if (flags & GPIO_OUTPUT_INIT_LOW) { + rzt2m_port_clear_bits_raw(dev, 1 << pin); + } else if (flags & GPIO_OUTPUT_INIT_HIGH) { + rzt2m_port_set_bits_raw(dev, 1 << pin); + } + } + + if (flags & GPIO_PULL_UP && flags & GPIO_PULL_DOWN) { + rzt2m_gpio_lock(); + return -EINVAL; + } + + uint8_t drctl_pin_config = 0; + + if (flags & GPIO_PULL_UP) { + drctl_pin_config |= PULL_UP; + } else if (flags & GPIO_PULL_DOWN) { + drctl_pin_config |= PULL_DOWN; + } else { + drctl_pin_config |= PULL_NONE; + } + + drctl_pin_config |= + (flags & RZT2M_GPIO_DRIVE_MASK) >> (RZT2M_GPIO_DRIVE_OFFSET - DRIVE_SHIFT); + drctl_pin_config |= (flags & RZT2M_GPIO_SCHMITT_TRIGGER_MASK) >> + (RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET - SCHMITT_TRIGGER_SHIFT); + drctl_pin_config |= (flags & RZT2M_GPIO_SLEW_RATE_MASK) >> + (RZT2M_GPIO_SLEW_RATE_OFFSET - SLEW_RATE_SHIFT); + + uint64_t drctl_pin_value = *drctl_reg & ~(0xFFULL << (pin * 8)); + *drctl_reg = drctl_pin_value | ((uint64_t)drctl_pin_config << (pin * 8)); + + rzt2m_gpio_lock(); + + return 0; +} + +static const struct gpio_driver_api rzt2m_gpio_driver_api = { + .pin_configure = rzt2m_gpio_configure, + .port_get_raw = rzt2m_gpio_get_raw, + .port_set_masked_raw = rzt2m_port_set_masked_raw, + .port_set_bits_raw = rzt2m_port_set_bits_raw, + .port_clear_bits_raw = rzt2m_port_clear_bits_raw, + .port_toggle_bits = rzt2m_gpio_toggle}; + +#define RZT2M_GPIO_DEFINE(inst) \ + static struct rzt2m_gpio_data rzt2m_gpio_data##inst; \ + static struct rzt2m_gpio_config rzt2m_gpio_config##inst = { \ + .port_nsr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_PARENT(inst), port_nsr), \ + .ptadr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_PARENT(inst), ptadr), \ + .port = DT_INST_REG_ADDR(inst), \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)}}; \ + DEVICE_DT_INST_DEFINE(inst, rzt2m_gpio_init, NULL, &rzt2m_gpio_data##inst, \ + &rzt2m_gpio_config##inst, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &rzt2m_gpio_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RZT2M_GPIO_DEFINE) diff --git a/dts/arm/renesas/rzt2m.dtsi b/dts/arm/renesas/rzt2m.dtsi index dada6ea55c7..9c6c1688d63 100644 --- a/dts/arm/renesas/rzt2m.dtsi +++ b/dts/arm/renesas/rzt2m.dtsi @@ -117,6 +117,32 @@ compatible = "renesas,rzt2m-pinctrl"; reg = <0x800a0000 0x1000 0x81030c00 0x1000>; reg-names = "port_nsr", "ptadr"; + #address-cells = <1>; + #size-cells = <0>; + + gpio19: gpio@13 { + compatible = "renesas,rzt2m-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x13>; + }; + + gpio20: gpio@14 { + compatible = "renesas,rzt2m-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x14>; + }; + + gpio23: gpio@17 { + compatible = "renesas,rzt2m-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x17>; + }; }; }; }; diff --git a/dts/bindings/gpio/renesas,rzt2m-gpio.yaml b/dts/bindings/gpio/renesas,rzt2m-gpio.yaml new file mode 100644 index 00000000000..e099c81753e --- /dev/null +++ b/dts/bindings/gpio/renesas,rzt2m-gpio.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 +description: Renesas RZT2M GPIO + +compatible: "renesas,rzt2m-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h b/include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h new file mode 100644 index 00000000000..8bd26d46434 --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_ +#include + +#define RZT2M_GPIO_DRIVE_OFFSET 8 +#define RZT2M_GPIO_DRIVE_MASK GENMASK(RZT2M_GPIO_DRIVE_OFFSET + 2, RZT2M_GPIO_DRIVE_OFFSET) + +/** + * @brief Select GPIO pin drive strength + */ +#define RZT2M_GPIO_DRIVE_LOW (0U << RZT2M_GPIO_DRIVE_OFFSET) +#define RZT2M_GPIO_DRIVE_MIDDLE (1U << RZT2M_GPIO_DRIVE_OFFSET) +#define RZT2M_GPIO_DRIVE_HIGH (2U << RZT2M_GPIO_DRIVE_OFFSET) +#define RZT2M_GPIO_DRIVE_ULTRA_HIGH (3U << RZT2M_GPIO_DRIVE_OFFSET) + +#define RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET 10 +#define RZT2M_GPIO_SCHMITT_TRIGGER_MASK BIT(RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET) + +/** + * @brief Enable GPIO pin schmitt trigger + */ +#define RZT2M_GPIO_SCHMITT_TRIGGER BIT(RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET) + +#define RZT2M_GPIO_SLEW_RATE_OFFSET 11 +#define RZT2M_GPIO_SLEW_RATE_MASK BIT(RZT2M_GPIO_SLEW_RATE_OFFSET) + +/** + * @brief Select GPIO pin slew rate + */ +#define RZT2M_GPIO_SLEW_RATE_SLOW 0U +#define RZT2M_GPIO_SLEW_RATE_FAST BIT(RZT2M_GPIO_SLEW_RATE_OFFSET) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_ */ From 8fe2c958079e7ce0480b09de0846b493c34cc208 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 31 Aug 2023 16:39:29 +0800 Subject: [PATCH 3665/4498] soc: arm64: mimx8m & 9: define SOC name followed by Core name In hal driver, MCUX_DEVICE is defined from CONFIG_SOC, so unify MCUX_DEVICE definition with mcux-sdk. Signed-off-by: Jiafei Pan --- soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mm | 4 ++-- soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mn | 4 ++-- soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mp | 4 ++-- soc/arm64/nxp_imx/mimx9/Kconfig.defconfig.mimx93 | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mm b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mm index a35ff4951ef..a77d9f837df 100644 --- a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mm +++ b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mm @@ -1,10 +1,10 @@ -# Copyright 2020-2022 NXP +# Copyright 2020-2023 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_MIMX8MM_A53 config SOC - default "mimx8mm6" + default "mimx8mm6_ca53" # Workaround for not being able to have commas in macro arguments DT_CHOSEN_Z_FLASH := zephyr,flash diff --git a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mn b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mn index 9c5e7bfe041..c6c2837d74d 100644 --- a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mn +++ b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mn @@ -1,10 +1,10 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_MIMX8MN_A53 config SOC - default "mimx8mn6" + default "mimx8mn6_ca53" # Workaround for not being able to have commas in macro arguments DT_CHOSEN_Z_FLASH := zephyr,flash diff --git a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mp b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mp index 5a99f354e5d..ebdfa764a69 100644 --- a/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mp +++ b/soc/arm64/nxp_imx/mimx8m/Kconfig.defconfig.mimx8mp @@ -1,10 +1,10 @@ -# Copyright 2021-2022 NXP +# Copyright 2021-2023 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_MIMX8MP_A53 config SOC - default "mimx8ml8" + default "mimx8ml8_ca53" # Workaround for not being able to have commas in macro arguments DT_CHOSEN_Z_FLASH := zephyr,flash diff --git a/soc/arm64/nxp_imx/mimx9/Kconfig.defconfig.mimx93 b/soc/arm64/nxp_imx/mimx9/Kconfig.defconfig.mimx93 index 59277175063..45e67de35ed 100644 --- a/soc/arm64/nxp_imx/mimx9/Kconfig.defconfig.mimx93 +++ b/soc/arm64/nxp_imx/mimx9/Kconfig.defconfig.mimx93 @@ -1,10 +1,10 @@ -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_MIMX93_A55 config SOC - default "mimx9352" + default "mimx9352_ca55" # Workaround for not being able to have commas in macro arguments DT_CHOSEN_Z_FLASH := zephyr,flash From 5b99d826b2e415ed74f3c3b134a2443731fa78a3 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 31 Aug 2023 17:04:15 +0800 Subject: [PATCH 3666/4498] west.yml: update hal_nxp commit Update to 03bd989de4d2de151470e8b6068bc5686f3fc84c Signed-off-by: Jiafei Pan --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3c50603e8c8..8bd52981664 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 78d1912dbc2b5f6e114d7fd19a31053716a3b01d + revision: 03bd989de4d2de151470e8b6068bc5686f3fc84c path: modules/hal/nxp groups: - hal From 6bd52ae87fa4dee0e4df1572a2f59efb0bd8106a Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Mon, 13 Nov 2023 11:06:54 +0100 Subject: [PATCH 3667/4498] doc: dlist: Add "container struct type pointer" description Add "container struct type pointer" description to SYS_DLIST_FOR_EACH_CONTAINER() and SYS_DLIST_FOR_EACH_CONTAINER_SAFE(). Signed-off-by: Andrej Butok --- include/zephyr/sys/dlist.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/dlist.h b/include/zephyr/sys/dlist.h index 4c330c8f04e..03f2a5e94c8 100644 --- a/include/zephyr/sys/dlist.h +++ b/include/zephyr/sys/dlist.h @@ -165,7 +165,7 @@ typedef struct _dnode sys_dnode_t; * } * * @param __dl A pointer on a sys_dlist_t to iterate on - * @param __cn A pointer to peek each entry of the list + * @param __cn A container struct type pointer to peek each entry of the list * @param __n The field name of sys_dnode_t within the container struct */ #define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \ @@ -184,8 +184,8 @@ typedef struct _dnode sys_dnode_t; * } * * @param __dl A pointer on a sys_dlist_t to iterate on - * @param __cn A pointer to peek each entry of the list - * @param __cns A pointer for the loop to run safely + * @param __cn A container struct type pointer to peek each entry of the list + * @param __cns A container struct type pointer for the loop to run safely * @param __n The field name of sys_dnode_t within the container struct */ #define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \ From 6348a973c38eeed5e18e6821dcb38a1c2f78ac76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 10 Nov 2023 16:15:56 +0100 Subject: [PATCH 3668/4498] soc: arm: Remove CPU_HAS_NRF_IDAU's dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPU_HAS_NRF_IDAU is depending on SOC_SERIES_NRF91X and SOC_NRF5340_CPUAPP. This makes it more difficult to have an out-of-tree nrf SOC. It is also an unnecessary dependency. There is no prompt for CPU_HAS_NRF_IDAU, so it will not show up in menuconfig and it won't be possible to enable it from a users Kconfig fragment. The only way to enable it is to select it, and those that select this option can themselves make sure that they only do so when appropriate. Also, move NRF_SPU options out to SOC Kconfig files to also make out-of-tree SoCs possible. With the added benefit of not polluting the common soc/arm/Kconfig. Signed-off-by: Sebastian Bøe --- soc/arm/Kconfig | 16 ---------------- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 12 ++++++++++++ soc/arm/nordic_nrf/nrf91/Kconfig.series | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/soc/arm/Kconfig b/soc/arm/Kconfig index 443a0031189..461f0b41f84 100644 --- a/soc/arm/Kconfig +++ b/soc/arm/Kconfig @@ -34,28 +34,12 @@ config CPU_HAS_ARM_SAU config CPU_HAS_NRF_IDAU bool - depends on SOC_SERIES_NRF91X || SOC_NRF5340_CPUAPP select CPU_HAS_TEE help MCU implements the nRF (vendor-specific) Security Attribution Unit. (IDAU: "Implementation-Defined Attribution Unit", in accordance with ARM terminology). -if CPU_HAS_NRF_IDAU -config NRF_SPU_FLASH_REGION_SIZE - hex - default 0x8000 if SOC_SERIES_NRF91X - default 0x4000 if SOC_NRF5340_CPUAPP - help - FLASH region size for the NRF_SPU peripheral - -config NRF_SPU_RAM_REGION_SIZE - hex - default 0x2000 if SOC_SERIES_NRF91X || SOC_NRF5340_CPUAPP - help - RAM region size for the NRF_SPU peripheral -endif - config HAS_SWO bool help diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index f6a2c019f5f..3afcd96f70d 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -98,6 +98,18 @@ config SOC_DCDC_NRF53X_HV help Enable nRF53 series System on Chip High Voltage DC/DC converter. +config NRF_SPU_FLASH_REGION_SIZE + hex + default 0x4000 + help + FLASH region size for the NRF_SPU peripheral + +config NRF_SPU_RAM_REGION_SIZE + hex + default 0x2000 + help + RAM region size for the NRF_SPU peripheral + config SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 bool depends on NRF_SOC_SECURE_SUPPORTED diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index c30132c7bac..1be69c377e5 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -19,3 +19,17 @@ config SOC_SERIES_NRF91X select HAS_POWEROFF help Enable support for NRF91 MCU series + +if SOC_SERIES_NRF91X +config NRF_SPU_FLASH_REGION_SIZE + hex + default 0x8000 + help + FLASH region size for the NRF_SPU peripheral + +config NRF_SPU_RAM_REGION_SIZE + hex + default 0x2000 + help + RAM region size for the NRF_SPU peripheral +endif From fd9a4644954b73563d29ee4068fa267e7b7ba4cb Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 14:58:46 +0000 Subject: [PATCH 3669/4498] toolchain: llvm: use the "none" vendor triplet This was submitted with "cros" in 77dde5dc9f, it was meant to be "none". Signed-off-by: Fabio Baltieri --- cmake/toolchain/llvm/target.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/toolchain/llvm/target.cmake b/cmake/toolchain/llvm/target.cmake index 38097229125..5c06af5f25f 100644 --- a/cmake/toolchain/llvm/target.cmake +++ b/cmake/toolchain/llvm/target.cmake @@ -16,7 +16,7 @@ if("${ARCH}" STREQUAL "arm") elseif(DEFINED CONFIG_ARMV7_M_ARMV8_M_MAINLINE) # ARMV7_M_ARMV8_M_MAINLINE means that ARMv7-M or backward compatible ARMv8-M # processor is used. - set(triple armv7m-cros-eabi) + set(triple armv7m-none-eabi) elseif(DEFINED CONFIG_ARMV6_M_ARMV8_M_BASELINE) # ARMV6_M_ARMV8_M_BASELINE means that ARMv6-M or ARMv8-M supporting the # Baseline implementation processor is used. From 093f9a9df2934329d366896227f0e3deb578ac7f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:25:32 -0500 Subject: [PATCH 3670/4498] tests: adc: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- .../boards/stm32/power_mgmt/adc/sample.yaml | 2 +- samples/drivers/adc/sample.yaml | 3 ++- samples/drivers/soc_flash_nrf/sample.yaml | 3 +-- tests/drivers/build_all/adc/testcase.yaml | 23 ------------------- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/samples/boards/stm32/power_mgmt/adc/sample.yaml b/samples/boards/stm32/power_mgmt/adc/sample.yaml index e27cc5b268d..e3892df7b5c 100644 --- a/samples/boards/stm32/power_mgmt/adc/sample.yaml +++ b/samples/boards/stm32/power_mgmt/adc/sample.yaml @@ -3,7 +3,7 @@ sample: tests: sample.boards.stm32.power_mgmt.adc: tags: - - ADC + - adc - power harness: console harness_config: diff --git a/samples/drivers/adc/sample.yaml b/samples/drivers/adc/sample.yaml index 0af996a8bab..2ed1681a0e0 100644 --- a/samples/drivers/adc/sample.yaml +++ b/samples/drivers/adc/sample.yaml @@ -2,7 +2,8 @@ sample: name: ADC driver sample tests: sample.drivers.adc: - tags: ADC + tags: + - adc depends_on: adc platform_allow: - nucleo_l073rz diff --git a/samples/drivers/soc_flash_nrf/sample.yaml b/samples/drivers/soc_flash_nrf/sample.yaml index 6557988b6e3..b8a59328be4 100644 --- a/samples/drivers/soc_flash_nrf/sample.yaml +++ b/samples/drivers/soc_flash_nrf/sample.yaml @@ -10,8 +10,7 @@ tests: - nrf52dk_nrf52832 tags: - flash - - nrf52 - - nrf9160 + - drivers harness: console harness_config: fixture: external_flash diff --git a/tests/drivers/build_all/adc/testcase.yaml b/tests/drivers/build_all/adc/testcase.yaml index c8a6fe5e3a7..a8102364b60 100644 --- a/tests/drivers/build_all/adc/testcase.yaml +++ b/tests/drivers/build_all/adc/testcase.yaml @@ -9,53 +9,30 @@ tests: platform_allow: - native_posix - native_posix_64 - tags: - - adc_mcp302x - - adc_lmp90xxx - - adc_ads1x1x - - adc_ads1119 - - adc_ads1112 - - adc_ads114s08 - - adc_emul - - adc_max1125x - - adc_ltc2451 extra_args: "CONFIG_GPIO=y" drivers.adc.cc32xx.build: platform_allow: cc3220sf_launchxl - tags: adc_cc32xx drivers.adc.ite.it8xxx2.build: platform_allow: it8xxx2_evb - tags: adc_ite_it8xxx2 drivers.adc.mcux.adc12.build: platform_allow: twr_ke18f - tags: adc_mcux_adc12 drivers.adc.mcux.adc16.build: platform_allow: frdm_k22f - tags: adc_mcux_adc16 drivers.adc.mcux.lpadc.build: platform_allow: lpcxpresso55s28 - tags: adc_mcux_lpadc drivers.adc.npcx.build: platform_allow: npcx7m6fb_evb - tags: adc_npcx drivers.adc.nrf.build: platform_allow: nrf51dk_nrf51422 - tags: adc_nrfx_adc drivers.adc.nrf.saadc.build: platform_allow: nrf21540dk_nrf52840 - tags: adc_nrfx_saadc drivers.adc.sam0.build: platform_allow: atsame54_xpro - tags: adc_sam0 drivers.adc.sam.afec.build: platform_allow: sam_e70_xplained - tags: adc_sam_afec drivers.adc.stm32.build: platform_allow: disco_l475_iot1 - tags: adc_stm32 drivers.adc.xec.build: platform_allow: mec15xxevb_assy6853 - tags: adc_xec drivers.adc.test.build: platform_allow: qemu_cortex_m3 - tags: adc_test From 9ff81c154169babcca29611fb4eb2a90c6073da3 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:26:47 -0500 Subject: [PATCH 3671/4498] tests: pwm: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- tests/drivers/build_all/pwm/testcase.yaml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/tests/drivers/build_all/pwm/testcase.yaml b/tests/drivers/build_all/pwm/testcase.yaml index 5a4477374ff..61d93f789d0 100644 --- a/tests/drivers/build_all/pwm/testcase.yaml +++ b/tests/drivers/build_all/pwm/testcase.yaml @@ -6,73 +6,51 @@ common: tests: drivers.pwm.cc13xx_cc26xx_timer.build: platform_allow: cc1352p1_launchxl - tags: pwm_cc13xx_cc26xx_timer drivers.pwm.gecko.build: platform_allow: efr32_radio_brd4250b - tags: pwm_gecko drivers.pwm.imx.build: platform_allow: colibri_imx7d_m4 - tags: pwm_imx drivers.pwm.litex.build: platform_allow: litex_vexriscv - tags: pwm_litex drivers.pwm.mcux.ftm.build: platform_allow: frdm_k22f - tags: pwm_mcux_ftm drivers.pwm.mcux.pwt.build: platform_allow: twr_ke18f - tags: pwm_mcux_pwt extra_configs: - CONFIG_PWM_CAPTURE=y drivers.pwm.mcux.tpm.build: platform_allow: frdm_kw41z - tags: pwm_mcux_tpm drivers.pwm.mcux.build: platform_allow: mimxrt1064_evk - tags: pwm_mcux drivers.pwm.mcux.sctimer.build: platform_allow: mimxrt685_evk_cm33 - tags: pwm_mcux_sctimer drivers.pwm.rv32m1.tpm.build: platform_allow: rv32m1_vega_ri5cy - tags: pwm_rv32m1_tpm drivers.pwm.sifive.build: platform_allow: hifive1_revb - tags: pwm_sifive drivers.pwm.npcx.build: platform_allow: npcx7m6fb_evb - tags: pwm_npcx drivers.pwm.nrf.sw.build: platform_allow: nrf51dk_nrf51422 - tags: pwm_nrf5_sw drivers.pwm.nrf.build: platform_allow: nrf52840dk_nrf52840 - tags: pwm_nrfx drivers.pwm.pca9685.build: platform_allow: nrf52840dk_nrf52840 extra_args: SHIELD=adafruit_pca9685 - tags: pwm_pca9685 drivers.pwm.sam0.tcc.build: platform_allow: atsame54_xpro - tags: pwm_sam0_tcc drivers.pwm.build.sam: platform_allow: - sam_e70_xplained - sam_v71b_xult - tags: pwm_sam drivers.pwm.stm32.build: platform_allow: disco_l475_iot1 - tags: pwm_stm32 drivers.pwm.xec.build: platform_allow: mec15xxevb_assy6853 - tags: pwm_xec drivers.pwm.build.xlnx: platform_allow: arty_a7_arm_designstart_m1 - tags: pwm_xlnx_axi_timer drivers.pwm.build.test: platform_allow: qemu_cortex_m3 - tags: pwm_test drivers.pwm.max31790.build: platform_allow: nucleo_f429zi extra_args: DTC_OVERLAY_FILE=max31790.overlay - tags: pwm_max31790 From d9d7e6a2f4e12908206090d8794addf8fd0e47ce Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:27:44 -0500 Subject: [PATCH 3672/4498] tests: watchdog: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- tests/drivers/build_all/watchdog/testcase.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/drivers/build_all/watchdog/testcase.yaml b/tests/drivers/build_all/watchdog/testcase.yaml index 3102453a740..82f8cd027bd 100644 --- a/tests/drivers/build_all/watchdog/testcase.yaml +++ b/tests/drivers/build_all/watchdog/testcase.yaml @@ -1,9 +1,10 @@ common: build_only: true - tags: drivers watchdog + tags: + - drivers + - watchdog tests: drivers.watchdog.build: # will cover drivers without in-tree boards platform_allow: qemu_cortex_m3 - tags: wdt_xilinx_axi extra_args: "CONFIG_WATCHDOG=y" From 131aa569003a83e24ad0849dd845dffa1f117e60 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:28:23 -0500 Subject: [PATCH 3673/4498] tests: i2c: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- tests/drivers/build_all/i2c/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/drivers/build_all/i2c/testcase.yaml b/tests/drivers/build_all/i2c/testcase.yaml index 36513e230a2..3c672c12167 100644 --- a/tests/drivers/build_all/i2c/testcase.yaml +++ b/tests/drivers/build_all/i2c/testcase.yaml @@ -7,5 +7,4 @@ tests: drivers.i2c.build: # will cover drivers without in-tree boards platform_allow: qemu_cortex_m3 - tags: i2c_xilinx_axi extra_args: "CONFIG_I2C=y" From 743564e89ef9dcd7d12691e1a693b4d933f6080c Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:29:48 -0500 Subject: [PATCH 3674/4498] tests: dac: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- tests/drivers/build_all/dac/testcase.yaml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/drivers/build_all/dac/testcase.yaml b/tests/drivers/build_all/dac/testcase.yaml index 5796038ef9d..12252b8661f 100644 --- a/tests/drivers/build_all/dac/testcase.yaml +++ b/tests/drivers/build_all/dac/testcase.yaml @@ -7,23 +7,12 @@ tests: drivers.dac.build: # will cover I2C, SPI based drivers platform_allow: native_posix - tags: - - dac_dacx0508 - - dac_dacx3608 - - dac_mcp4725 - - dac_mcp4728 - - dac_ltc1660 - - dac_ltc1665 extra_args: "CONFIG_GPIO=y" drivers.dac.mcux.build: platform_allow: frdm_k22f - tags: dac_mcux drivers.dac.mcux32.build: platform_allow: twr_ke18f - tags: dac_mcux32 drivers.dac.sam0.build: platform_allow: atsamd21_xpro - tags: dac_sam0 drivers.dac.stm32.build: platform_allow: nucleo_f091rc - tags: dac_stm32 From 153e6d9dc79e839f2f54f8008b2aaabc4af7a567 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 12:38:54 -0500 Subject: [PATCH 3675/4498] tests: uart: cleanup test tags Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- tests/drivers/build_all/uart/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/drivers/build_all/uart/testcase.yaml b/tests/drivers/build_all/uart/testcase.yaml index c652d1cb767..6c69f06e720 100644 --- a/tests/drivers/build_all/uart/testcase.yaml +++ b/tests/drivers/build_all/uart/testcase.yaml @@ -7,6 +7,5 @@ tests: drivers.uart.build: # will cover drivers without in-tree boards platform_allow: qemu_cortex_m3 - tags: uart_cdns extra_configs: - CONFIG_SERIAL=y From d94bdafda669fdc2807e7664073a6686bebc4b96 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 9 Nov 2023 13:12:56 -0500 Subject: [PATCH 3676/4498] tests: clock_control: cleanup test tags and unify them Remove platform specific tags and be consistent. Signed-off-by: Anas Nashif --- samples/drivers/clock_control_litex/sample.yaml | 4 +--- tests/drivers/clock_control/adsp_clock/testcase.yaml | 2 +- tests/drivers/clock_control/clock_control_api/testcase.yaml | 4 ++-- .../drivers/clock_control/nrf_clock_calibration/testcase.yaml | 2 +- tests/drivers/clock_control/nrf_lf_clock_start/testcase.yaml | 2 +- tests/drivers/clock_control/nrf_onoff_and_bt/testcase.yaml | 2 +- tests/drivers/clock_control/onoff/testcase.yaml | 2 +- .../stm32_clock_configuration/stm32_common_core/testcase.yaml | 3 ++- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/samples/drivers/clock_control_litex/sample.yaml b/samples/drivers/clock_control_litex/sample.yaml index 5c9ae55424f..cf5618313c5 100644 --- a/samples/drivers/clock_control_litex/sample.yaml +++ b/samples/drivers/clock_control_litex/sample.yaml @@ -4,7 +4,5 @@ tests: sample.driver.clock_control_litex: platform_allow: litex_vexriscv tags: - - clock - - litex - - vexriscv + - clock_control - mmcm diff --git a/tests/drivers/clock_control/adsp_clock/testcase.yaml b/tests/drivers/clock_control/adsp_clock/testcase.yaml index 5abe4765022..48df05a8462 100644 --- a/tests/drivers/clock_control/adsp_clock/testcase.yaml +++ b/tests/drivers/clock_control/adsp_clock/testcase.yaml @@ -2,7 +2,7 @@ tests: drivers.clock.adsp_clock_control: tags: - drivers - - clock + - clock_control platform_allow: intel_adsp_cavs25 integration_platforms: - intel_adsp_cavs25 diff --git a/tests/drivers/clock_control/clock_control_api/testcase.yaml b/tests/drivers/clock_control/clock_control_api/testcase.yaml index 18d75385551..be789c8382a 100644 --- a/tests/drivers/clock_control/clock_control_api/testcase.yaml +++ b/tests/drivers/clock_control/clock_control_api/testcase.yaml @@ -2,7 +2,7 @@ tests: drivers.clock.clock_control_nrf5: tags: - drivers - - cloc + - clock_control platform_allow: - nrf51dk_nrf51422 - nrf52dk_nrf52832 @@ -13,7 +13,7 @@ tests: drivers.clock.clock_control_nrf5_lfclk_rc: tags: - drivers - - clock + - clock_control platform_allow: - nrf51dk_nrf51422 - nrf52dk_nrf52832 diff --git a/tests/drivers/clock_control/nrf_clock_calibration/testcase.yaml b/tests/drivers/clock_control/nrf_clock_calibration/testcase.yaml index e7ac90ec7b9..092471d30e4 100644 --- a/tests/drivers/clock_control/nrf_clock_calibration/testcase.yaml +++ b/tests/drivers/clock_control/nrf_clock_calibration/testcase.yaml @@ -2,7 +2,7 @@ tests: drivers.clock.nrf5_clock_calibration: tags: - drivers - - clock + - clock_control platform_allow: - nrf51dk_nrf51422 - nrf52dk_nrf52832 diff --git a/tests/drivers/clock_control/nrf_lf_clock_start/testcase.yaml b/tests/drivers/clock_control/nrf_lf_clock_start/testcase.yaml index 01ba725e780..f4940d79896 100644 --- a/tests/drivers/clock_control/nrf_lf_clock_start/testcase.yaml +++ b/tests/drivers/clock_control/nrf_lf_clock_start/testcase.yaml @@ -1,7 +1,7 @@ common: tags: - drivers - - clock + - clock_control integration_platforms: - nrf51dk_nrf51422 tests: diff --git a/tests/drivers/clock_control/nrf_onoff_and_bt/testcase.yaml b/tests/drivers/clock_control/nrf_onoff_and_bt/testcase.yaml index 04c107da954..19c77496933 100644 --- a/tests/drivers/clock_control/nrf_onoff_and_bt/testcase.yaml +++ b/tests/drivers/clock_control/nrf_onoff_and_bt/testcase.yaml @@ -2,7 +2,7 @@ tests: drivers.clock.nrf_onoff_and_bt: tags: - drivers - - clock + - clock_control platform_allow: - nrf51dk_nrf51422 - nrf52dk_nrf52832 diff --git a/tests/drivers/clock_control/onoff/testcase.yaml b/tests/drivers/clock_control/onoff/testcase.yaml index abedf82f2a4..a6e03d9a0ec 100644 --- a/tests/drivers/clock_control/onoff/testcase.yaml +++ b/tests/drivers/clock_control/onoff/testcase.yaml @@ -2,7 +2,7 @@ tests: drivers.clock.clock_control_onoff: tags: - drivers - - clock + - clock_control platform_allow: - nrf51dk_nrf51422 - nrf52dk_nrf52832 diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml index da7df163972..563108bfe91 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml @@ -6,7 +6,8 @@ # - add the fixture in map file common: timeout: 5 - tags: clock-control + tags: + - clock_control tests: drivers.clock.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_48_msi_4: extra_args: From c7ac9216408e096116578503864cd5cd3cdfccbb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 15 Nov 2023 09:18:31 +0100 Subject: [PATCH 3677/4498] net: loopback: Register IPv4 netmask A proper netmask should be set on the loopback interface, so that source address selection work properly when there are multiple interfaces in the system. Signed-off-by: Robert Lubos --- drivers/net/loopback.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index cd9a0ee3e1b..d8ae5ca1b05 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -42,12 +42,15 @@ static void loopback_init(struct net_if *iface) if (IS_ENABLED(CONFIG_NET_IPV4)) { struct in_addr ipv4_loopback = INADDR_LOOPBACK_INIT; + struct in_addr netmask = { { { 255, 0, 0, 0 } } }; ifaddr = net_if_ipv4_addr_add(iface, &ipv4_loopback, NET_ADDR_AUTOCONF, 0); if (!ifaddr) { LOG_ERR("Failed to register IPv4 loopback address"); } + + net_if_ipv4_set_netmask(iface, &netmask); } if (IS_ENABLED(CONFIG_NET_IPV6)) { From 92560ac0951a70da53ea1fcb28fcbd9bcce0d3a3 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Thu, 2 Nov 2023 18:22:25 +0100 Subject: [PATCH 3678/4498] manifest: update LVGL to add Kconfig guard Related to zephyrproject-rtos/lvgl#48 Signed-off-by: Fabian Blatz --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 8bd52981664..59ee67c81f6 100644 --- a/west.yml +++ b/west.yml @@ -274,7 +274,7 @@ manifest: revision: 842413c5fb98707eb5f26e619e8e792453877897 path: modules/lib/loramac-node - name: lvgl - revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd + revision: 7c61a4cec26402d20c845c95dcad0e39dcd319f8 path: modules/lib/gui/lvgl - name: mbedtls revision: 7053083b0cff8462464e3cbb826e87852fc03da6 From 84c7f2fe0afa2e718c421302a280110b66dda111 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Wed, 25 Oct 2023 19:35:48 +0200 Subject: [PATCH 3679/4498] modules: lvgl: Fix usage of LVGL log levels Introduces a Kconfig symbol `LV_Z_LOG_LEVEL` because contrary to Zephyr the numerical value of log levels in LVGL increases with severity. Also support for the `LV_LOG_LEVEL_USER` is added. Resolves issue #64351. Signed-off-by: Fabian Blatz --- modules/lvgl/Kconfig | 30 +++++++++++++++++++++++++ modules/lvgl/input/lvgl_button_input.c | 2 +- modules/lvgl/input/lvgl_common_input.c | 2 +- modules/lvgl/input/lvgl_encoder_input.c | 2 +- modules/lvgl/input/lvgl_pointer_input.c | 2 +- modules/lvgl/input/lvgl_pointer_kscan.c | 2 +- modules/lvgl/lvgl.c | 12 +++++----- 7 files changed, 42 insertions(+), 10 deletions(-) diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig index 9b73705ddb0..4bd00b1bc55 100644 --- a/modules/lvgl/Kconfig +++ b/modules/lvgl/Kconfig @@ -22,6 +22,36 @@ config LV_CONF_SKIP bool default n +config LV_USE_LOG + bool + +config LV_LOG_LEVEL_NONE + bool + +config LV_LOG_LEVEL_ERROR + bool + +config LV_LOG_LEVEL_WARN + bool + +config LV_LOG_LEVEL_INFO + bool + +config LV_LOG_LEVEL_USER + bool + +config LV_LOG_LEVEL_TRACE + bool + +config LV_Z_LOG_LEVEL + int + default 0 if LV_LOG_LEVEL_NONE || !LV_USE_LOG + default 1 if LV_LOG_LEVEL_ERROR + default 2 if LV_LOG_LEVEL_WARN + default 3 if LV_LOG_LEVEL_INFO + default 3 if LV_LOG_LEVEL_USER + default 4 if LV_LOG_LEVEL_TRACE + config APP_LINK_WITH_LVGL bool "Link 'app' with LVGL" default y diff --git a/modules/lvgl/input/lvgl_button_input.c b/modules/lvgl/input/lvgl_button_input.c index f9c9d59f4d5..8ac96b7fed5 100644 --- a/modules/lvgl/input/lvgl_button_input.c +++ b/modules/lvgl/input/lvgl_button_input.c @@ -11,7 +11,7 @@ #include -LOG_MODULE_DECLARE(lvgl); +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); struct lvgl_button_input_config { struct lvgl_common_input_config common_config; /* Needs to be first member */ diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c index f91b01bacd3..2894538c62b 100644 --- a/modules/lvgl/input/lvgl_common_input.c +++ b/modules/lvgl/input/lvgl_common_input.c @@ -13,7 +13,7 @@ #include "lvgl_button_input.h" #include "lvgl_encoder_input.h" -LOG_MODULE_DECLARE(lvgl); +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); lv_indev_t *lvgl_input_get_indev(const struct device *dev) { diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c index a49f1eeca29..b68ca67b871 100644 --- a/modules/lvgl/input/lvgl_encoder_input.c +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -11,7 +11,7 @@ #include -LOG_MODULE_DECLARE(lvgl); +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); struct lvgl_encoder_input_config { struct lvgl_common_input_config common_config; /* Needs to be first member */ diff --git a/modules/lvgl/input/lvgl_pointer_input.c b/modules/lvgl/input/lvgl_pointer_input.c index 19c71eb1972..1abfd69d29a 100644 --- a/modules/lvgl/input/lvgl_pointer_input.c +++ b/modules/lvgl/input/lvgl_pointer_input.c @@ -12,7 +12,7 @@ #include #include -LOG_MODULE_DECLARE(lvgl); +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); struct lvgl_pointer_input_config { struct lvgl_common_input_config common_config; /* Needs to be first member */ diff --git a/modules/lvgl/input/lvgl_pointer_kscan.c b/modules/lvgl/input/lvgl_pointer_kscan.c index 197106e4f2c..43c309349ed 100644 --- a/modules/lvgl/input/lvgl_pointer_kscan.c +++ b/modules/lvgl/input/lvgl_pointer_kscan.c @@ -10,7 +10,7 @@ #include "lvgl_display.h" #include -LOG_MODULE_DECLARE(lvgl); +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); static lv_indev_drv_t indev_drv; #define KSCAN_NODE DT_CHOSEN(zephyr_keyboard_scan) diff --git a/modules/lvgl/lvgl.c b/modules/lvgl/lvgl.c index 0f4c24e9a34..76df359e7fc 100644 --- a/modules/lvgl/lvgl.c +++ b/modules/lvgl/lvgl.c @@ -17,9 +17,8 @@ #endif #include LV_MEM_CUSTOM_INCLUDE -#define LOG_LEVEL CONFIG_LV_LOG_LEVEL #include -LOG_MODULE_REGISTER(lvgl); +LOG_MODULE_REGISTER(lvgl, CONFIG_LV_Z_LOG_LEVEL); static lv_disp_drv_t disp_drv; struct lvgl_disp_data disp_data = { @@ -61,7 +60,7 @@ static uint8_t buf1[BUFFER_SIZE] #endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */ -#if CONFIG_LV_LOG_LEVEL != 0 +#if CONFIG_LV_Z_LOG_LEVEL != 0 /* * In LVGLv8 the signature of the logging callback has changes and it no longer * takes the log level as an integer argument. Instead, the log level is now @@ -83,7 +82,7 @@ static void lvgl_log(const char *buf) LOG_ERR("%s", buf + strlen("[Error] ")); break; case 'W': - LOG_WRN("%s", buf + strlen("Warn] ")); + LOG_WRN("%s", buf + strlen("[Warn] ")); break; case 'I': LOG_INF("%s", buf + strlen("[Info] ")); @@ -91,6 +90,9 @@ static void lvgl_log(const char *buf) case 'T': LOG_DBG("%s", buf + strlen("[Trace] ")); break; + case 'U': + LOG_INF("%s", buf + strlen("[User] ")); + break; } } #endif @@ -207,7 +209,7 @@ static int lvgl_init(void) lvgl_heap_init(); #endif -#if CONFIG_LV_LOG_LEVEL != 0 +#if CONFIG_LV_Z_LOG_LEVEL != 0 lv_log_register_print_cb(lvgl_log); #endif From 7fc83e36a3930246826693768f36c74807381f22 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Mon, 13 Nov 2023 17:20:12 +0100 Subject: [PATCH 3680/4498] doc: gsg: macOS: Do not require wget, use curl instead macOS ships with curl by default. There's no need to add additional tools to the installation when a perfectly good one ships with the OS. Signed-off-by: Carles Cufi --- doc/develop/getting_started/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 495a3792b94..201b2896d24 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -132,7 +132,7 @@ The current minimum required version for the main dependencies are: .. code-block:: bash - brew install cmake ninja gperf python3 ccache qemu dtc wget libmagic + brew install cmake ninja gperf python3 ccache qemu dtc libmagic #. Add the Homebrew Python folder to the path, in order to be able to execute ``python`` and ``pip`` as well ``python3`` and ``pip3``. @@ -580,8 +580,8 @@ that are used to emulate, flash and debug Zephyr applications. .. code-block:: bash cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing + curl -L -O https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz + curl -L https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. From e91040917c4ea23008df0b544f3837705086985b Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 14 Nov 2023 16:58:58 +0100 Subject: [PATCH 3681/4498] doc: Reuse the same Zephyr SDK installation instructions Instead of keeping 2 copies of the same Zephyr SDK installation instructions, reuse a single copy by including it in the getting stated guide from the Zephyr SDK doc page. Signed-off-by: Carles Cufi --- doc/develop/getting_started/index.rst | 157 +------------------ doc/develop/toolchains/zephyr_sdk.rst | 210 ++++++++++++++------------ 2 files changed, 120 insertions(+), 247 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 201b2896d24..d95651121bf 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -500,8 +500,8 @@ additional Python dependencies. pip3 install -r %HOMEPATH%\zephyrproject\zephyr\scripts\requirements.txt -Install Zephyr SDK -****************** +Install the Zephyr SDK +********************** The :ref:`Zephyr Software Development Kit (SDK) ` contains toolchains for each of Zephyr's supported architectures, which @@ -511,156 +511,9 @@ Zephyr applications. It also contains additional host tools, such as custom QEMU and OpenOCD builds that are used to emulate, flash and debug Zephyr applications. -.. tabs:: - - .. group-tab:: Ubuntu - - .. _ubuntu_zephyr_sdk: - - #. Download and verify the `Zephyr SDK bundle - `_: - - .. code-block:: bash - - cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing - - If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace ``x86_64`` - with ``aarch64`` in order to download the 64-bit ARM Linux SDK. - - #. Extract the Zephyr SDK bundle archive: - - .. code-block:: bash - - tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz - - .. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following locations: - - * ``$HOME`` - * ``$HOME/.local`` - * ``$HOME/.local/opt`` - * ``$HOME/bin`` - * ``/opt`` - * ``/usr/local`` - - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.3``. - - #. Run the Zephyr SDK bundle setup script: - - .. code-block:: bash - - cd zephyr-sdk-0.16.3 - ./setup.sh - - .. note:: - You only need to run the setup script once after extracting the Zephyr SDK bundle. - - You must rerun the setup script if you relocate the Zephyr SDK bundle directory after - the initial setup. - - #. Install `udev `_ rules, which - allow you to flash most Zephyr boards as a regular user: - - .. code-block:: bash - - sudo cp ~/zephyr-sdk-0.16.3/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d - sudo udevadm control --reload - - .. group-tab:: macOS - - .. _macos_zephyr_sdk: - - #. Download and verify the `Zephyr SDK bundle - `_: - - .. code-block:: bash - - cd ~ - curl -L -O https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz - curl -L https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing - - If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace - ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. - - #. Extract the Zephyr SDK bundle archive: - - .. code-block:: bash - - tar xvf zephyr-sdk-0.16.3_macos-x86_64.tar.xz - - .. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following locations: - - * ``$HOME`` - * ``$HOME/.local`` - * ``$HOME/.local/opt`` - * ``$HOME/bin`` - * ``/opt`` - * ``/usr/local`` - - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.3``. - - #. Run the Zephyr SDK bundle setup script: - - .. code-block:: bash - - cd zephyr-sdk-0.16.3 - ./setup.sh - - .. note:: - You only need to run the setup script once after extracting the Zephyr SDK bundle. - - You must rerun the setup script if you relocate the Zephyr SDK bundle directory after - the initial setup. - - .. group-tab:: Windows - - .. _windows_zephyr_sdk: - - #. Open a ``cmd.exe`` terminal window **as a regular user** - - #. Download the `Zephyr SDK bundle - `_: - - .. code-block:: bat - - cd %HOMEPATH% - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z - - #. Extract the Zephyr SDK bundle archive: - - .. code-block:: bat - - 7z x zephyr-sdk-0.16.3_windows-x86_64.7z - - .. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following locations: - - * ``%HOMEPATH%`` - * ``%PROGRAMFILES%`` - - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``%HOMEPATH%``, the resulting installation path will be - ``%HOMEPATH%\zephyr-sdk-0.16.3``. - - #. Run the Zephyr SDK bundle setup script: - - .. code-block:: bat - - cd zephyr-sdk-0.16.3 - setup.cmd - - .. note:: - You only need to run the setup script once after extracting the Zephyr SDK bundle. - - You must rerun the setup script if you relocate the Zephyr SDK bundle directory after - the initial setup. +.. include:: ../toolchains/zephyr_sdk.rst + :start-after: toolchain_zephyr_sdk_install_start + :end-before: toolchain_zephyr_sdk_install_end .. _getting_started_run_sample: diff --git a/doc/develop/toolchains/zephyr_sdk.rst b/doc/develop/toolchains/zephyr_sdk.rst index c128708f508..fc6add9d3eb 100644 --- a/doc/develop/toolchains/zephyr_sdk.rst +++ b/doc/develop/toolchains/zephyr_sdk.rst @@ -67,153 +67,173 @@ the recommended version for the corresponding Zephyr version. For the full list of compatible Zephyr and Zephyr SDK versions, refer to the `Zephyr SDK Version Compatibility Matrix`_. -.. _toolchain_zephyr_sdk_install_linux: +.. _toolchain_zephyr_sdk_install: -Install Zephyr SDK on Linux -*************************** +Zephyr SDK installation +*********************** + +.. toolchain_zephyr_sdk_install_start + +.. note:: You can change ``0.16.3`` to another version in the instructions below + if needed; the `Zephyr SDK Releases`_ page contains all available + SDK releases. + +.. note:: If you want to uninstall the SDK, you may simply remove the directory + where you installed it. + +.. tabs:: -#. Download and verify the `Zephyr SDK bundle`_: + .. group-tab:: Ubuntu - .. code-block:: bash + .. _ubuntu_zephyr_sdk: - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing + #. Download and verify the `Zephyr SDK bundle + `_: - You can change ``0.16.3`` to another version if needed; the `Zephyr SDK - Releases`_ page contains all available SDK releases. + .. code-block:: bash - If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace - ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM Linux SDK. + cd ~ + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz + wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing -#. Extract the Zephyr SDK bundle archive: + If your host architecture is 64-bit ARM (for example, Raspberry Pi), replace ``x86_64`` + with ``aarch64`` in order to download the 64-bit ARM Linux SDK. - .. code-block:: bash + #. Extract the Zephyr SDK bundle archive: - cd - tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz + .. code-block:: bash -#. Run the Zephyr SDK bundle setup script: + tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz - .. code-block:: bash + .. note:: + It is recommended to extract the Zephyr SDK bundle at one of the following locations: - cd zephyr-sdk-0.16.3 - ./setup.sh + * ``$HOME`` + * ``$HOME/.local`` + * ``$HOME/.local/opt`` + * ``$HOME/bin`` + * ``/opt`` + * ``/usr/local`` - If this fails, make sure Zephyr's dependencies were installed as described - in :ref:`Install Requirements and Dependencies `. + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when + extracted under ``$HOME``, the resulting installation path will be + ``$HOME/zephyr-sdk-0.16.3``. -If you want to uninstall the SDK, remove the directory where you installed it. -If you relocate the SDK directory, you need to re-run the setup script. + #. Run the Zephyr SDK bundle setup script: -.. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following - default locations: + .. code-block:: bash - * ``$HOME`` - * ``$HOME/.local`` - * ``$HOME/.local/opt`` - * ``$HOME/bin`` - * ``/opt`` - * ``/usr/local`` + cd zephyr-sdk-0.16.3 + ./setup.sh - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.3``. + .. note:: + You only need to run the setup script once after extracting the Zephyr SDK bundle. -.. _toolchain_zephyr_sdk_install_macos: + You must rerun the setup script if you relocate the Zephyr SDK bundle directory after + the initial setup. -Install Zephyr SDK on macOS -*************************** + #. Install `udev `_ rules, which + allow you to flash most Zephyr boards as a regular user: -#. Download and verify the `Zephyr SDK bundle`_: + .. code-block:: bash - .. code-block:: bash + sudo cp ~/zephyr-sdk-0.16.3/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d + sudo udevadm control --reload - cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz - wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing + .. group-tab:: macOS - If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace - ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. + .. _macos_zephyr_sdk: -#. Extract the Zephyr SDK bundle archive: + #. Download and verify the `Zephyr SDK bundle + `_: - .. code-block:: bash + .. code-block:: bash - tar xvf zephyr-sdk-0.16.3_macos-x86_64.tar.xz + cd ~ + curl -L -O https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_macos-x86_64.tar.xz + curl -L https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing - .. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following - default locations: + If your host architecture is 64-bit ARM (Apple Silicon, also known as M1), replace + ``x86_64`` with ``aarch64`` in order to download the 64-bit ARM macOS SDK. - * ``$HOME`` - * ``$HOME/.local`` - * ``$HOME/.local/opt`` - * ``$HOME/bin`` - * ``/opt`` - * ``/usr/local`` + #. Extract the Zephyr SDK bundle archive: - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``$HOME``, the resulting installation path will be - ``$HOME/zephyr-sdk-0.16.3``. + .. code-block:: bash -#. Run the Zephyr SDK bundle setup script: + tar xvf zephyr-sdk-0.16.3_macos-x86_64.tar.xz - .. code-block:: bash + .. note:: + It is recommended to extract the Zephyr SDK bundle at one of the following locations: - cd zephyr-sdk-0.16.3 - ./setup.sh + * ``$HOME`` + * ``$HOME/.local`` + * ``$HOME/.local/opt`` + * ``$HOME/bin`` + * ``/opt`` + * ``/usr/local`` - .. note:: - You only need to run the setup script once after extracting the Zephyr SDK bundle. + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when + extracted under ``$HOME``, the resulting installation path will be + ``$HOME/zephyr-sdk-0.16.3``. - You must rerun the setup script if you relocate the Zephyr SDK bundle directory after - the initial setup. + #. Run the Zephyr SDK bundle setup script: -.. _toolchain_zephyr_sdk_install_windows: + .. code-block:: bash -Install Zephyr SDK on Windows -***************************** + cd zephyr-sdk-0.16.3 + ./setup.sh -#. Open a ``cmd.exe`` window by pressing the Windows key typing "cmd.exe". + .. note:: + You only need to run the setup script once after extracting the Zephyr SDK bundle. -#. Download the `Zephyr SDK bundle`_: + You must rerun the setup script if you relocate the Zephyr SDK bundle directory after + the initial setup. - .. code-block:: console + .. group-tab:: Windows - cd %HOMEPATH% - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z + .. _windows_zephyr_sdk: -#. Extract the Zephyr SDK bundle archive: + #. Open a ``cmd.exe`` terminal window **as a regular user** - .. code-block:: console + #. Download the `Zephyr SDK bundle + `_: - 7z x zephyr-sdk-0.16.3_windows-x86_64.7z + .. code-block:: bat - .. note:: - It is recommended to extract the Zephyr SDK bundle at one of the following - default locations: + cd %HOMEPATH% + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_windows-x86_64.7z - * ``%HOMEPATH%`` - * ``%PROGRAMFILES%`` + #. Extract the Zephyr SDK bundle archive: - The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when - extracted under ``%HOMEPATH%``, the resulting installation path will be - ``%HOMEPATH%\zephyr-sdk-0.16.3``. + .. code-block:: bat -#. Run the Zephyr SDK bundle setup script: + 7z x zephyr-sdk-0.16.3_windows-x86_64.7z - .. code-block:: console + .. note:: + It is recommended to extract the Zephyr SDK bundle at one of the following locations: - cd zephyr-sdk-0.16.3 - setup.cmd + * ``%HOMEPATH%`` + * ``%PROGRAMFILES%`` - .. note:: - You only need to run the setup script once after extracting the Zephyr SDK bundle. + The Zephyr SDK bundle archive contains the ``zephyr-sdk-0.16.3`` directory and, when + extracted under ``%HOMEPATH%``, the resulting installation path will be + ``%HOMEPATH%\zephyr-sdk-0.16.3``. - You must rerun the setup script if you relocate the Zephyr SDK bundle directory after - the initial setup. + #. Run the Zephyr SDK bundle setup script: + + .. code-block:: bat + + cd zephyr-sdk-0.16.3 + setup.cmd + + .. note:: + You only need to run the setup script once after extracting the Zephyr SDK bundle. + + You must rerun the setup script if you relocate the Zephyr SDK bundle directory after + the initial setup. .. _Zephyr SDK bundle: https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.3 .. _Zephyr SDK Releases: https://github.com/zephyrproject-rtos/sdk-ng/tags .. _Zephyr SDK Version Compatibility Matrix: https://github.com/zephyrproject-rtos/sdk-ng/wiki/Zephyr-SDK-Version-Compatibility-Matrix + +.. toolchain_zephyr_sdk_install_end From a88facacaa7791472106dd9275b7d2533d324f3a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 28 Sep 2023 09:43:27 +0200 Subject: [PATCH 3682/4498] llext: clarify the use of loop variables, simplify code Several cosmetic changes with no change in functionality: The pos variable in multiple functions is used as a loop variable - it's initialised before the loop starts and then it's incremented for each loop iteration. Move it to the loop header for readability. "return ret" is clearer than "goto out" where the "out" label does nothing but "out: return ret" because one sees immediately that the function is terminated at that location with no further actions without the need to check the "out" label. k_heap_free(heap, NULL) is valid, no need to check the address to be freed for NULL. Object counters can be simple (unsigned) integers, no need to make them size_t or elf_word. "return 0" is simpler than "return ret" because it shows the return value immediately without the need to check what it can be at that location. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 129 +++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 72 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 93c03d18aba..8e1b03128ec 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -90,8 +90,8 @@ const void * const llext_find_sym(const struct llext_symtable *sym_table, const */ static int llext_find_tables(struct llext_loader *ldr) { - int ret = 0; - size_t pos = ldr->hdr.e_shoff; + int str_cnt, i, ret; + size_t pos; elf_shdr_t shdr; ldr->sects[LLEXT_SECT_SHSTRTAB] = @@ -99,21 +99,21 @@ static int llext_find_tables(struct llext_loader *ldr) ldr->sects[LLEXT_SECT_SYMTAB] = (elf_shdr_t){0}; /* Find symbol and string tables */ - for (int i = 0, str_cnt = 0; i < ldr->hdr.e_shnum && str_cnt < 3; i++) { + for (i = 0, str_cnt = 0, pos = ldr->hdr.e_shoff; + i < ldr->hdr.e_shnum && str_cnt < 3; + i++, pos += ldr->hdr.e_shentsize) { ret = llext_seek(ldr, pos); if (ret != 0) { LOG_ERR("failed seeking to position %u\n", pos); - goto out; + return ret; } ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); if (ret != 0) { LOG_ERR("failed reading section header at position %u\n", pos); - goto out; + return ret; } - pos += ldr->hdr.e_shentsize; - LOG_DBG("section %d at %x: name %d, type %d, flags %x, addr %x, size %d", i, ldr->hdr.e_shoff + i * ldr->hdr.e_shentsize, @@ -152,11 +152,10 @@ static int llext_find_tables(struct llext_loader *ldr) !ldr->sects[LLEXT_SECT_STRTAB].sh_type || !ldr->sects[LLEXT_SECT_SYMTAB].sh_type) { LOG_ERR("Some sections are missing or present multiple times!"); - ret = -ENOENT; + return -ENOENT; } -out: - return ret; + return 0; } static const char *llext_string(struct llext_loader *ldr, struct llext *ext, @@ -170,24 +169,24 @@ static const char *llext_string(struct llext_loader *ldr, struct llext *ext, */ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; - size_t pos = ldr->hdr.e_shoff; + int i, ret; + size_t pos; elf_shdr_t shdr; const char *name; - for (int i = 0; i < ldr->hdr.e_shnum; i++) { + for (i = 0, pos = ldr->hdr.e_shoff; + i < ldr->hdr.e_shnum; + i++, pos += ldr->hdr.e_shentsize) { ret = llext_seek(ldr, pos); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); if (ret != 0) { - goto out; + return ret; } - pos += ldr->hdr.e_shentsize; - name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr.sh_name); LOG_DBG("section %d name %s", i, name); @@ -211,8 +210,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) ldr->sect_map[i] = sect_idx; } -out: - return ret; + return 0; } static inline enum llext_section llext_sect_from_mem(enum llext_mem m) @@ -325,29 +323,29 @@ static int llext_copy_sections(struct llext_loader *ldr, struct llext *ext) static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; - elf_sym_t sym; size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; - size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; - size_t sym_cnt = syms_size / sizeof(elf_sym_t); + int sym_cnt = syms_size / sizeof(elf_sym_t); const char *name; + elf_sym_t sym; + int i, ret; + size_t pos; LOG_DBG("symbol count %u", sym_cnt); - for (int i = 0; i < sym_cnt; i++) { + for (i = 0, pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; + i < sym_cnt; + i++, pos += ent_size) { ret = llext_seek(ldr, pos); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &sym, ent_size); if (ret != 0) { - goto out; + return ret; } - pos += ent_size; - uint32_t stt = ELF_ST_TYPE(sym.st_info); uint32_t stb = ELF_ST_BIND(sym.st_info); uint32_t sect = sym.st_shndx; @@ -364,8 +362,7 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) } } -out: - return ret; + return 0; } static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) @@ -384,27 +381,26 @@ static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext * static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; - elf_sym_t sym; size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; - size_t pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; - size_t sym_cnt = syms_size / sizeof(elf_sym_t); - int i, j = 0; + int sym_cnt = syms_size / sizeof(elf_sym_t); + elf_sym_t sym; + int i, j, ret; + size_t pos; - for (i = 0; i < sym_cnt; i++) { + for (i = 0, pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset, j = 0; + i < sym_cnt; + i++, pos += ent_size) { ret = llext_seek(ldr, pos); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &sym, ent_size); if (ret != 0) { - goto out; + return ret; } - pos += ent_size; - uint32_t stt = ELF_ST_TYPE(sym.st_info); uint32_t stb = ELF_ST_BIND(sym.st_info); uint32_t sect = sym.st_shndx; @@ -422,8 +418,7 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext } } -out: - return ret; + return 0; } __weak void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval) @@ -432,28 +427,28 @@ __weak void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval static int llext_link(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; uintptr_t loc = 0; elf_shdr_t shdr; elf_rela_t rel; elf_sym_t sym; - size_t pos = ldr->hdr.e_shoff; elf_word rel_cnt = 0; const char *name; + int i, ret; + size_t pos; - for (int i = 0; i < ldr->hdr.e_shnum - 1; i++) { + for (i = 0, pos = ldr->hdr.e_shoff; + i < ldr->hdr.e_shnum - 1; + i++, pos += ldr->hdr.e_shentsize) { ret = llext_seek(ldr, pos); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &shdr, sizeof(elf_shdr_t)); if (ret != 0) { - goto out; + return ret; } - pos += ldr->hdr.e_shentsize; - /* find relocation sections */ if (shdr.sh_type != SHT_REL && shdr.sh_type != SHT_RELA) { continue; @@ -481,24 +476,24 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) /* get each relocation entry */ ret = llext_seek(ldr, shdr.sh_offset + j * sizeof(elf_rel_t)); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &rel, sizeof(elf_rel_t)); if (ret != 0) { - goto out; + return ret; } /* get corresponding symbol */ ret = llext_seek(ldr, ldr->sects[LLEXT_SECT_SYMTAB].sh_offset + ELF_R_SYM(rel.r_info) * sizeof(elf_sym_t)); if (ret != 0) { - goto out; + return ret; } ret = llext_read(ldr, &sym, sizeof(elf_sym_t)); if (ret != 0) { - goto out; + return ret; } name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); @@ -521,8 +516,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) LOG_ERR("Undefined symbol with no entry in " "symbol table %s, offset %d, link section %d", name, rel.r_offset, shdr.sh_link); - ret = -ENODATA; - goto out; + return -ENODATA; } else { op_code = (uintptr_t)(loc + rel.r_offset); @@ -556,8 +550,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) } } -out: - return ret; + return 0; } /* @@ -640,9 +633,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) } out: - if (ldr->sect_map != NULL) { - k_heap_free(&llext_heap, ldr->sect_map); - } + k_heap_free(&llext_heap, ldr->sect_map); if (ret != 0) { LOG_DBG("Failed to load extension, freeing memory..."); @@ -668,20 +659,19 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) ret = llext_seek(ldr, 0); if (ret != 0) { LOG_ERR("Failed to seek for ELF header"); - goto out; + return ret; } ret = llext_read(ldr, &ehdr, sizeof(ehdr)); if (ret != 0) { LOG_ERR("Failed to read ELF header"); - goto out; + return ret; } /* check whether this is an valid elf file */ if (memcmp(ehdr.e_ident, ELF_MAGIC, sizeof(ELF_MAGIC)) != 0) { LOG_HEXDUMP_ERR(ehdr.e_ident, 16, "Invalid ELF, magic does not match"); - ret = -EINVAL; - goto out; + return -EINVAL; } switch (ehdr.e_type) { @@ -691,8 +681,7 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) *ext = k_heap_alloc(&llext_heap, sizeof(struct llext), K_NO_WAIT); if (*ext == NULL) { LOG_ERR("Not enough memory for extension metadata"); - ret = -ENOMEM; - goto out; + return -ENOMEM; } memset(*ext, 0, sizeof(struct llext)); @@ -706,8 +695,7 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) default: LOG_ERR("Unsupported elf file type %x", ehdr.e_type); *ext = NULL; - ret = -EINVAL; - goto out; + return -EINVAL; } if (ret == 0) { @@ -717,7 +705,6 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) LOG_INF("Loaded extension %s", (*ext)->name); } -out: return ret; } @@ -735,9 +722,7 @@ void llext_unload(struct llext *ext) } } - if (ext->sym_tab.syms != NULL) { - k_heap_free(&llext_heap, ext->sym_tab.syms); - } + k_heap_free(&llext_heap, ext->sym_tab.syms); k_heap_free(&llext_heap, ext); } From 68b4898b7ebb63cda2b8ea952a5b232ab4ff320f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 7 Sep 2023 17:38:12 +0200 Subject: [PATCH 3683/4498] llext: skip first dummy symbol table entry The first entry in the symbol table is empty, skip it. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 8e1b03128ec..4f55a3dd14f 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -336,6 +336,11 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) for (i = 0, pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset; i < sym_cnt; i++, pos += ent_size) { + if (!i) { + /* A dummy entry */ + continue; + } + ret = llext_seek(ldr, pos); if (ret != 0) { return ret; @@ -391,6 +396,11 @@ static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext for (i = 0, pos = ldr->sects[LLEXT_SECT_SYMTAB].sh_offset, j = 0; i < sym_cnt; i++, pos += ent_size) { + if (!i) { + /* A dummy entry */ + continue; + } + ret = llext_seek(ldr, pos); if (ret != 0) { return ret; From 6058512b06d0bb435cc25573a1a8e4ec03ac43f5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 22 Sep 2023 15:35:49 +0200 Subject: [PATCH 3684/4498] llext: use provided size for more generic code Use .sh_entsize instead of sizeof(elf_rel_t) to make code suitable for both REL and RELA types. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 4f55a3dd14f..4d0cedef01e 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -464,7 +464,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) continue; } - rel_cnt = shdr.sh_size / sizeof(elf_rel_t); + rel_cnt = shdr.sh_size / shdr.sh_entsize; name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr.sh_name); @@ -484,12 +484,12 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) for (int j = 0; j < rel_cnt; j++) { /* get each relocation entry */ - ret = llext_seek(ldr, shdr.sh_offset + j * sizeof(elf_rel_t)); + ret = llext_seek(ldr, shdr.sh_offset + j * shdr.sh_entsize); if (ret != 0) { return ret; } - ret = llext_read(ldr, &rel, sizeof(elf_rel_t)); + ret = llext_read(ldr, &rel, shdr.sh_entsize); if (ret != 0) { return ret; } From 6246caa643bf0be8be1bcdabd7522f9b82aa8c98 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 15 Nov 2023 10:36:47 +0100 Subject: [PATCH 3685/4498] llext: (cosmetic) rename a variable to match its role str_cnt in llext_find_tables() is actually used to count sections, rename it to better match that usage. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 4d0cedef01e..fcaa2317c41 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -90,7 +90,7 @@ const void * const llext_find_sym(const struct llext_symtable *sym_table, const */ static int llext_find_tables(struct llext_loader *ldr) { - int str_cnt, i, ret; + int sect_cnt, i, ret; size_t pos; elf_shdr_t shdr; @@ -99,8 +99,8 @@ static int llext_find_tables(struct llext_loader *ldr) ldr->sects[LLEXT_SECT_SYMTAB] = (elf_shdr_t){0}; /* Find symbol and string tables */ - for (i = 0, str_cnt = 0, pos = ldr->hdr.e_shoff; - i < ldr->hdr.e_shnum && str_cnt < 3; + for (i = 0, sect_cnt = 0, pos = ldr->hdr.e_shoff; + i < ldr->hdr.e_shnum && sect_cnt < 3; i++, pos += ldr->hdr.e_shentsize) { ret = llext_seek(ldr, pos); if (ret != 0) { @@ -129,7 +129,7 @@ static int llext_find_tables(struct llext_loader *ldr) LOG_DBG("symtab at %d", i); ldr->sects[LLEXT_SECT_SYMTAB] = shdr; ldr->sect_map[i] = LLEXT_SECT_SYMTAB; - str_cnt++; + sect_cnt++; break; case SHT_STRTAB: if (ldr->hdr.e_shstrndx == i) { @@ -141,7 +141,7 @@ static int llext_find_tables(struct llext_loader *ldr) ldr->sects[LLEXT_SECT_STRTAB] = shdr; ldr->sect_map[i] = LLEXT_SECT_STRTAB; } - str_cnt++; + sect_cnt++; break; default: break; From 350747cd099a8db6af8d004eed66710bd9fe0840 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 13 Nov 2023 12:29:24 +0100 Subject: [PATCH 3686/4498] dts: bq24190: make constant-charge-current/voltage properties required There are no default values for those properties in the driver so let's make them required. Signed-off-by: Bartosz Bilas --- dts/bindings/charger/ti,bq24190.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/bindings/charger/ti,bq24190.yaml b/dts/bindings/charger/ti,bq24190.yaml index 34d271754f3..6ff662c9c58 100644 --- a/dts/bindings/charger/ti,bq24190.yaml +++ b/dts/bindings/charger/ti,bq24190.yaml @@ -6,3 +6,10 @@ description: Texas Instruments family of BQ24190 of charging ICs include: [battery.yaml, i2c-device.yaml] compatible: "ti,bq24190" + +properties: + constant-charge-current-max-microamp: + required: true + + constant-charge-voltage-max-microvolt: + required: true From 24b004faee153843f0f7b76ae5cae5cb142ab467 Mon Sep 17 00:00:00 2001 From: Bartosz Bilas Date: Mon, 13 Nov 2023 12:31:07 +0100 Subject: [PATCH 3687/4498] dts: max20335-charger: make constant-charge-current/voltage props required There are no default values for those properties in the driver so let's make them required. Signed-off-by: Bartosz Bilas --- dts/bindings/charger/maxim,max20335-charger.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/bindings/charger/maxim,max20335-charger.yaml b/dts/bindings/charger/maxim,max20335-charger.yaml index 45b7cc87997..f830e03cec5 100644 --- a/dts/bindings/charger/maxim,max20335-charger.yaml +++ b/dts/bindings/charger/maxim,max20335-charger.yaml @@ -6,3 +6,10 @@ description: Maxim MAX20335 battery charger include: battery.yaml compatible: "maxim,max20335-charger" + +properties: + constant-charge-current-max-microamp: + required: true + + constant-charge-voltage-max-microvolt: + required: true From 6bb46c7fe7069ed5b67f5d8ee0ba2909ac329921 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 13 Nov 2023 15:41:23 -0800 Subject: [PATCH 3688/4498] ipc: pbuf: fix incorrect doxygen group The ipc/pbuf was tagged as kernel API, which is not correct. As this is for IPC, move it under IPC doxygen group and also give it its own subgroup. So now the packed buffer API appears under IPC in API doc. Signed-off-by: Daniel Leung --- include/zephyr/ipc/pbuf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/zephyr/ipc/pbuf.h b/include/zephyr/ipc/pbuf.h index 5f953522d3b..7e61950c808 100644 --- a/include/zephyr/ipc/pbuf.h +++ b/include/zephyr/ipc/pbuf.h @@ -16,7 +16,8 @@ extern "C" { /** * @brief Packed buffer API - * @ingroup kernel_apis + * @defgroup pbuf Packed Buffer API + * @ingroup ipc * @{ */ From 287b30eb78e5163cd2b56c3e889385d4048e5a1d Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Wed, 15 Nov 2023 11:10:16 +0100 Subject: [PATCH 3689/4498] doc: Fix double 'the' Fix double 'the' in all .rst documentation. Signed-off-by: Andrej Butok --- boards/arm/96b_aerocore2/doc/index.rst | 2 +- boards/arm/96b_carbon/doc/index.rst | 2 +- boards/arm/96b_nitrogen/doc/index.rst | 2 +- boards/arm/adafruit_feather_nrf52840/doc/index.rst | 2 +- boards/arm/arduino_nano_33_ble/doc/index.rst | 2 +- boards/arm/bl5340_dvk/doc/index.rst | 2 +- boards/arm/cc1352p1_launchxl/doc/index.rst | 2 +- boards/arm/cc1352r1_launchxl/doc/index.rst | 2 +- boards/arm/cc26x2r1_launchxl/doc/index.rst | 2 +- boards/arm/lpcxpresso11u68/doc/index.rst | 2 +- boards/arm/nrf9160_innblue21/doc/index.rst | 2 +- boards/arm/nrf9160_innblue22/doc/index.rst | 2 +- .../doc/olimex_lora_stm32wl_devkit.rst | 2 +- boards/posix/doc/arch_soc.rst | 2 +- boards/riscv/rv32m1_vega/doc/index.rst | 2 +- boards/x86/common/net_boot.rst | 2 +- doc/connectivity/networking/overview.rst | 2 +- doc/contribute/guidelines.rst | 4 ++-- doc/develop/manifest/index.rst | 2 +- doc/develop/modules.rst | 2 +- doc/develop/test/twister.rst | 2 +- doc/develop/west/manifest.rst | 4 ++-- doc/glossary.rst | 2 +- doc/kernel/data_structures/rbtree.rst | 2 +- doc/releases/release-notes-3.2.rst | 2 +- doc/releases/release-notes-3.3.rst | 2 +- 26 files changed, 28 insertions(+), 28 deletions(-) diff --git a/boards/arm/96b_aerocore2/doc/index.rst b/boards/arm/96b_aerocore2/doc/index.rst index 79bac17ad27..6d56911c2f1 100644 --- a/boards/arm/96b_aerocore2/doc/index.rst +++ b/boards/arm/96b_aerocore2/doc/index.rst @@ -330,7 +330,7 @@ Replace :code:`` with the port where the board 96Boards Aerocore2 can be found. For example, under Linux, :code:`/dev/ttyUSB0`. The ``-b`` option sets baud rate ignoring the value from config. -Press the Reset button and you should see the the following message in your +Press the Reset button and you should see the following message in your terminal: .. code-block:: console diff --git a/boards/arm/96b_carbon/doc/index.rst b/boards/arm/96b_carbon/doc/index.rst index b4a37cc985d..7b63bb20de9 100644 --- a/boards/arm/96b_carbon/doc/index.rst +++ b/boards/arm/96b_carbon/doc/index.rst @@ -318,7 +318,7 @@ Replace :code:`` with the port where the board 96Boards Carbon can be found. For example, under Linux, :code:`/dev/ttyUSB0`. The ``-b`` option sets baud rate ignoring the value from config. -Press the Reset button and you should see the the following message in your +Press the Reset button and you should see the following message in your terminal: .. code-block:: console diff --git a/boards/arm/96b_nitrogen/doc/index.rst b/boards/arm/96b_nitrogen/doc/index.rst index 86e08e96ccf..ea971f093a8 100644 --- a/boards/arm/96b_nitrogen/doc/index.rst +++ b/boards/arm/96b_nitrogen/doc/index.rst @@ -292,7 +292,7 @@ Replace :code:`` with the port where the board 96Boards Nitrogen can be found. For example, under Linux, :code:`/dev/ttyACM0`. The ``-b`` option sets baud rate ignoring the value from config. -Press the Reset button and you should see the the following message in your +Press the Reset button and you should see the following message in your terminal: .. code-block:: console diff --git a/boards/arm/adafruit_feather_nrf52840/doc/index.rst b/boards/arm/adafruit_feather_nrf52840/doc/index.rst index a36bbdd7e3a..6d4af8ca296 100644 --- a/boards/arm/adafruit_feather_nrf52840/doc/index.rst +++ b/boards/arm/adafruit_feather_nrf52840/doc/index.rst @@ -129,7 +129,7 @@ Flash the image. :goals: flash :compact: -You should see the the red LED blink. +You should see the red LED blink. References ********** diff --git a/boards/arm/arduino_nano_33_ble/doc/index.rst b/boards/arm/arduino_nano_33_ble/doc/index.rst index ede09b85979..05c0605b464 100644 --- a/boards/arm/arduino_nano_33_ble/doc/index.rst +++ b/boards/arm/arduino_nano_33_ble/doc/index.rst @@ -126,7 +126,7 @@ and there should be a pulsing orange LED near the USB port. Then, you can flash the image using the above script. -You should see the the red LED blink. +You should see the red LED blink. Debugging ========= diff --git a/boards/arm/bl5340_dvk/doc/index.rst b/boards/arm/bl5340_dvk/doc/index.rst index 4a9fe7b1207..544250baa84 100644 --- a/boards/arm/bl5340_dvk/doc/index.rst +++ b/boards/arm/bl5340_dvk/doc/index.rst @@ -290,7 +290,7 @@ described below. .. note:: - By default the the Secure image for BL5340's application core is + By default the Secure image for BL5340's application core is built using TF-M. Building the Secure firmware with TF-M diff --git a/boards/arm/cc1352p1_launchxl/doc/index.rst b/boards/arm/cc1352p1_launchxl/doc/index.rst index 5e9690fefbd..a5f88cc19ff 100644 --- a/boards/arm/cc1352p1_launchxl/doc/index.rst +++ b/boards/arm/cc1352p1_launchxl/doc/index.rst @@ -133,7 +133,7 @@ Programming and Debugging ************************* Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers -are in place. Also place jumpers on the the TXD and RXD signals for a serial +are in place. Also place jumpers on the TXD and RXD signals for a serial console using the XDS110 application serial port. Prerequisites: diff --git a/boards/arm/cc1352r1_launchxl/doc/index.rst b/boards/arm/cc1352r1_launchxl/doc/index.rst index b3c999a1494..0002b1e1c6f 100644 --- a/boards/arm/cc1352r1_launchxl/doc/index.rst +++ b/boards/arm/cc1352r1_launchxl/doc/index.rst @@ -132,7 +132,7 @@ Programming and Debugging ************************* Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers -are in place. Also place jumpers on the the TXD and RXD signals for a serial +are in place. Also place jumpers on the TXD and RXD signals for a serial console using the XDS110 application serial port. Prerequisites: diff --git a/boards/arm/cc26x2r1_launchxl/doc/index.rst b/boards/arm/cc26x2r1_launchxl/doc/index.rst index 89bdb035a31..8177df13ae3 100644 --- a/boards/arm/cc26x2r1_launchxl/doc/index.rst +++ b/boards/arm/cc26x2r1_launchxl/doc/index.rst @@ -138,7 +138,7 @@ Programming and Debugging ************************* Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers -are in place. Also place jumpers on the the TXD and RXD signals for a serial +are in place. Also place jumpers on the TXD and RXD signals for a serial console using the XDS110 application serial port. Prerequisites: diff --git a/boards/arm/lpcxpresso11u68/doc/index.rst b/boards/arm/lpcxpresso11u68/doc/index.rst index 75a4b7f15a5..23198a359ea 100644 --- a/boards/arm/lpcxpresso11u68/doc/index.rst +++ b/boards/arm/lpcxpresso11u68/doc/index.rst @@ -107,7 +107,7 @@ Flashing The LPCXpresso11U68 board can be flashed by using the on-board LPC-Link2 debug probe (based on a NXP LPC43xx MCU). This MCU provides either a CMSIS-DAP or a J-Link interface. It depends on the embedded firmware image. The default -OpenOCD configuration supports the the CMSIS-DAP interface. If you want to +OpenOCD configuration supports the CMSIS-DAP interface. If you want to switch to J-Link, then you need to edit the ``boards/arm/lpcxpresso11u68/support/openocd.cfg`` file and to replace:: diff --git a/boards/arm/nrf9160_innblue21/doc/index.rst b/boards/arm/nrf9160_innblue21/doc/index.rst index 9ded085dc6f..c0f9e33cd75 100644 --- a/boards/arm/nrf9160_innblue21/doc/index.rst +++ b/boards/arm/nrf9160_innblue21/doc/index.rst @@ -95,7 +95,7 @@ Building Secure/Non-Secure Zephyr applications The process requires the following steps: 1. Build the Secure Zephyr application using ``-DBOARD=nrf9160_innblue21`` and - ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the the application project configuration file. + ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the application project configuration file. 2. Build the Non-Secure Zephyr application using ``-DBOARD=nrf9160_innblue21_ns``. 3. Merge the two binaries together. diff --git a/boards/arm/nrf9160_innblue22/doc/index.rst b/boards/arm/nrf9160_innblue22/doc/index.rst index 06f6b6326f8..0f2f83bcfe1 100644 --- a/boards/arm/nrf9160_innblue22/doc/index.rst +++ b/boards/arm/nrf9160_innblue22/doc/index.rst @@ -95,7 +95,7 @@ Building Secure/Non-Secure Zephyr applications The process requires the following steps: 1. Build the Secure Zephyr application using ``-DBOARD=nrf9160_innblue22`` and - ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the the application project configuration file. + ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the application project configuration file. 2. Build the Non-Secure Zephyr application using ``-DBOARD=nrf9160_innblue22_ns``. 3. Merge the two binaries together. diff --git a/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst b/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst index be63585fbb1..cd7d3436296 100644 --- a/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst +++ b/boards/arm/olimex_lora_stm32wl_devkit/doc/olimex_lora_stm32wl_devkit.rst @@ -126,7 +126,7 @@ CON1 pin header. :goals: build flash Run a serial terminal to connect with your board. By default, ``usart1`` is -accessible via the the built-in USB to UART converter. +accessible via the built-in USB to UART converter. .. code-block:: console diff --git a/boards/posix/doc/arch_soc.rst b/boards/posix/doc/arch_soc.rst index ff1f947e483..f0e469308ab 100644 --- a/boards/posix/doc/arch_soc.rst +++ b/boards/posix/doc/arch_soc.rst @@ -323,7 +323,7 @@ SOC and board layers This description applies to all current POSIX arch based boards on tree, but it is not a requirement for another board to follow what is described here. -When the executable process is started (that is the the board +When the executable process is started (that is the board :c:func:`main`, which is the linux executable C :c:func:`main`), first, early initialization steps are taken care of (command line argument parsing, initialization of the HW models, etc). diff --git a/boards/riscv/rv32m1_vega/doc/index.rst b/boards/riscv/rv32m1_vega/doc/index.rst index 867a86a2c69..a2f3d107224 100644 --- a/boards/riscv/rv32m1_vega/doc/index.rst +++ b/boards/riscv/rv32m1_vega/doc/index.rst @@ -126,7 +126,7 @@ BLE Software Link Layer experimental support ================================================== This is an experimental feature supported on the Zephyr's RI5CY configuration, ``rv32m1_vega_ri5cy``. It uses the Software Link Layer -framework by Nordic Semi to enable the the on-SoC radio and transceiver for +framework by Nordic Semi to enable the on-SoC radio and transceiver for implementing a software defined BLE controller. By using both the controller and the host stack available in Zephyr, the following BLE samples can be used with this board: diff --git a/boards/x86/common/net_boot.rst b/boards/x86/common/net_boot.rst index ae301bea0c4..e00dea8312c 100644 --- a/boards/x86/common/net_boot.rst +++ b/boards/x86/common/net_boot.rst @@ -69,7 +69,7 @@ Booting the board .. note:: Use a baud rate of 115200. -#. Power on the the board. +#. Power on the board. #. Verify that the board got an IP address. Run from the Linux host: diff --git a/doc/connectivity/networking/overview.rst b/doc/connectivity/networking/overview.rst index f271bcd8a8c..c1de9a1ab67 100644 --- a/doc/connectivity/networking/overview.rst +++ b/doc/connectivity/networking/overview.rst @@ -56,7 +56,7 @@ can be disabled if not needed. * **TCP** Transmission Control Protocol (`RFC 793 `_) is supported. Both server - and client roles can be used the the application. The amount of TCP sockets + and client roles can be used the application. The amount of TCP sockets that are available to applications can be configured at build time. * **BSD Sockets API** Support for a subset of a diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index c4ef5ce6bb1..ac88fa768ab 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -316,7 +316,7 @@ Pull Requests and Issues Before starting on a patch, first check in our issues `Zephyr Project Issues`_ system to see what's been reported on the issue you'd like to address. Have a -conversation on the `Zephyr devel mailing list`_ (or the the `Zephyr Discord +conversation on the `Zephyr devel mailing list`_ (or the `Zephyr Discord Server`_) to see what others think of your issue (and proposed solution). You may find others that have encountered the issue you're finding, or that have similar ideas for changes or additions. Send a message to the `Zephyr devel @@ -360,7 +360,7 @@ gitlint When you submit a pull request to the project, a series of checks are performed to verify your commit messages meet the requirements. The same step -done during the CI process can be performed locally using the the ``gitlint`` +done during the CI process can be performed locally using the ``gitlint`` command. Run ``gitlint`` locally in your tree and branch where your patches have been diff --git a/doc/develop/manifest/index.rst b/doc/develop/manifest/index.rst index 2dba5d817dc..4c6d8f99117 100644 --- a/doc/develop/manifest/index.rst +++ b/doc/develop/manifest/index.rst @@ -30,7 +30,7 @@ Inactive and Optional Projects/Modules The projects below are optional and will not be downloaded when you -call `west update`. You can add any of the the projects or modules listed below +call `west update`. You can add any of the projects or modules listed below and use them to write application code and extend your workspace with the added functionality. diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index 45167585cd6..42d10c32e98 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -818,7 +818,7 @@ to the path containing the CMake file. To include a module's Kconfig file, set the variable ``ZEPHYR__KCONFIG`` to the path to the Kconfig file. -The following is an example on how to add support the the ``FOO`` module. +The following is an example on how to add support the ``FOO`` module. Create the following structure diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index b4cc35f3cb3..122e9c3871b 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -1050,7 +1050,7 @@ example: id: 000683290670 notes: An nrf5340dk_nrf5340 is detected as an nrf52840dk_nrf52840 with no serial port, and three serial ports with an unknown platform. The board id of the serial - ports is not the same as the board id of the the development kit. If you regenerate + ports is not the same as the board id of the development kit. If you regenerate this file you will need to update serial to reference the third port, and platform to nrf5340dk_nrf5340_cpuapp or another supported board target. platform: nrf52840dk_nrf52840 diff --git a/doc/develop/west/manifest.rst b/doc/develop/west/manifest.rst index bb057272b01..ba0f9f29706 100644 --- a/doc/develop/west/manifest.rst +++ b/doc/develop/west/manifest.rst @@ -248,7 +248,7 @@ next. remote Git repository. If the project has neither, the ``defaults`` section must specify a - ``remote``, which will be used as the the project's remote. Otherwise, + ``remote``, which will be used as the project's remote. Otherwise, the manifest is invalid. * - ``repo-path`` @@ -2049,7 +2049,7 @@ The ultimate outcomes of resolving manifest imports are: - a ``projects`` list, which is produced by combining the ``projects`` defined in the top-level file with those defined in imported files -- a set of extension commands, which are drawn from the the ``west-commands`` +- a set of extension commands, which are drawn from the ``west-commands`` keys in in the top-level file and any imported files - a ``group-filter`` list, which is produced by combining the top-level and any diff --git a/doc/glossary.rst b/doc/glossary.rst index 95781c665f6..eafda9410fc 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -51,7 +51,7 @@ Glossary of Terms device runtime power management Device Runtime Power Management (PM) refers the capability of devices to - save energy independently of the the system power state. Devices will keep + save energy independently of the system power state. Devices will keep reference of their usage and will automatically be suspended or resumed. This feature is enabled via the :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME` Kconfig option. diff --git a/doc/kernel/data_structures/rbtree.rst b/doc/kernel/data_structures/rbtree.rst index 135960200f8..aac446cbad6 100644 --- a/doc/kernel/data_structures/rbtree.rst +++ b/doc/kernel/data_structures/rbtree.rst @@ -27,7 +27,7 @@ the algorithm to work correctly. As with the slist and dlist containers, nodes within an rbtree are represented as a :c:struct:`rbnode` structure which exists in -user-managed memory, typically embedded within the the data structure +user-managed memory, typically embedded within the data structure being tracked in the tree. Unlike the list code, the data within an rbnode is entirely opaque. It is not possible for the user to extract the binary tree topology and "manually" traverse the tree as it is for diff --git a/doc/releases/release-notes-3.2.rst b/doc/releases/release-notes-3.2.rst index e9e4bd647db..d902ac4481b 100644 --- a/doc/releases/release-notes-3.2.rst +++ b/doc/releases/release-notes-3.2.rst @@ -335,7 +335,7 @@ Bluetooth payload updates with the Resolvable Private Address (RPA) rotations when the :kconfig:option:`CONFIG_BT_PRIVACY` is enabled. * Added a new :c:func:`bt_le_set_rpa_timeout()` API call to dynamically change - the the Resolvable Private Address (RPA) timeout when the + the Resolvable Private Address (RPA) timeout when the :kconfig:option:`CONFIG_BT_RPA_TIMEOUT_DYNAMIC` is enabled. * Added :c:func:`bt_conn_auth_cb_overlay` to overlay authentication callbacks for a Bluetooth LE connection. diff --git a/doc/releases/release-notes-3.3.rst b/doc/releases/release-notes-3.3.rst index 93be4649b1e..312ad1e4754 100644 --- a/doc/releases/release-notes-3.3.rst +++ b/doc/releases/release-notes-3.3.rst @@ -811,7 +811,7 @@ Drivers and Sensors * Added new API :c:func:`pcie_scan` to scan for devices. - * This iterates through the the buses and devices which are expected to + * This iterates through the buses and devices which are expected to exist. The old method was to try all possible combination of buses and devices to determine if there is a device there. :c:func:`pci_init` and :c:func:`pcie_bdf_lookup` have been updated to From 72fea5df56849abd11e8751e9dea3623297d753b Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 15 Nov 2023 17:51:46 +0800 Subject: [PATCH 3690/4498] shell: backends: uart: add public function to access smp shell data `smp_shell_input_timeout_handler`. Create a public function in the `shell_uart.c` for it to get the pointer to the `smp_shell_data` and fix the compilation error. Signed-off-by: Yong Cong Sin --- include/zephyr/shell/shell_uart.h | 8 ++++++++ subsys/mgmt/mcumgr/transport/src/smp_shell.c | 5 +---- subsys/shell/backends/shell_uart.c | 13 +++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/zephyr/shell/shell_uart.h b/include/zephyr/shell/shell_uart.h index 2b157aac6e7..5032c56f65e 100644 --- a/include/zephyr/shell/shell_uart.h +++ b/include/zephyr/shell/shell_uart.h @@ -7,6 +7,7 @@ #ifndef SHELL_UART_H__ #define SHELL_UART_H__ +#include #include #ifdef __cplusplus @@ -23,6 +24,13 @@ extern "C" { */ const struct shell *shell_backend_uart_get_ptr(void); +/** + * @brief This function provides pointer to the smp shell data of the UART shell transport. + * + * @returns Pointer to the smp shell data. + */ +struct smp_shell_data *shell_uart_smp_shell_data_get_ptr(void); + #ifdef __cplusplus } #endif diff --git a/subsys/mgmt/mcumgr/transport/src/smp_shell.c b/subsys/mgmt/mcumgr/transport/src/smp_shell.c index fc04bcd75c4..527ab2e47fa 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_shell.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_shell.c @@ -59,13 +59,10 @@ enum smp_shell_mcumgr_state { }; #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT -extern struct shell_transport shell_transport_uart; - static void smp_shell_input_timeout_handler(struct k_timer *timer) { ARG_UNUSED(timer); - struct shell_uart *sh_uart = (struct shell_uart *)shell_transport_uart.ctx; - struct smp_shell_data *const data = &sh_uart->ctrl_blk->smp; + struct smp_shell_data *const data = shell_uart_smp_shell_data_get_ptr(); atomic_clear_bit(&data->esc_state, ESC_MCUMGR_PKT_1); atomic_clear_bit(&data->esc_state, ESC_MCUMGR_PKT_2); diff --git a/subsys/shell/backends/shell_uart.c b/subsys/shell/backends/shell_uart.c index b06cc4a09b8..5e4e3bd2c95 100644 --- a/subsys/shell/backends/shell_uart.c +++ b/subsys/shell/backends/shell_uart.c @@ -554,6 +554,10 @@ static int read(const struct shell_transport *transport, #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL static void update(const struct shell_transport *transport) { + /* + * This is dependent on the fact that `struct shell_uart_common` + * is always the first member, regardless of the UART configuration + */ struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx; smp_shell_process(&sh_uart->smp); @@ -583,6 +587,15 @@ SHELL_DEFINE(shell_uart, CONFIG_SHELL_PROMPT_UART, &shell_transport_uart, CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_TIMEOUT, SHELL_FLAG_OLF_CRLF); +#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL +struct smp_shell_data *shell_uart_smp_shell_data_get_ptr(void) +{ + struct shell_uart_common *common = (struct shell_uart_common *)shell_transport_uart.ctx; + + return &common->smp; +} +#endif + static int enable_shell_uart(void) { const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); From 589f3f435b634fbdb5e223fae69ad6b6a37b1178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sat, 21 Oct 2023 16:46:13 +0700 Subject: [PATCH 3691/4498] soc: nxp_s32: rename s32k to s32k3 for series alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To accommodate support for S32K1 devices, it is necessary to rename the existing `s32k` directory, which currently houses support for the S32K3 series, to align with the respective series names. This adjustment is necessary given the distinct differences in core architecture, MPU, peripherals, and other key aspects between the two series. Signed-off-by: Manuel Argüelles --- soc/arm/nxp_s32/{s32k => s32k3}/CMakeLists.txt | 0 soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.defconfig.s32k344 | 0 soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.defconfig.series | 4 ++-- soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.series | 0 soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.soc | 0 soc/arm/nxp_s32/{s32k => s32k3}/linker.ld | 0 soc/arm/nxp_s32/{s32k => s32k3}/mpu_regions.c | 0 soc/arm/nxp_s32/{s32k => s32k3}/s32k3xx_startup.S | 0 soc/arm/nxp_s32/{s32k => s32k3}/sections.ld | 0 soc/arm/nxp_s32/{s32k => s32k3}/soc.c | 0 soc/arm/nxp_s32/{s32k => s32k3}/soc.h | 0 11 files changed, 2 insertions(+), 2 deletions(-) rename soc/arm/nxp_s32/{s32k => s32k3}/CMakeLists.txt (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.defconfig.s32k344 (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.defconfig.series (87%) rename soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.series (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/Kconfig.soc (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/linker.ld (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/mpu_regions.c (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/s32k3xx_startup.S (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/sections.ld (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/soc.c (100%) rename soc/arm/nxp_s32/{s32k => s32k3}/soc.h (100%) diff --git a/soc/arm/nxp_s32/s32k/CMakeLists.txt b/soc/arm/nxp_s32/s32k3/CMakeLists.txt similarity index 100% rename from soc/arm/nxp_s32/s32k/CMakeLists.txt rename to soc/arm/nxp_s32/s32k3/CMakeLists.txt diff --git a/soc/arm/nxp_s32/s32k/Kconfig.defconfig.s32k344 b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 similarity index 100% rename from soc/arm/nxp_s32/s32k/Kconfig.defconfig.s32k344 rename to soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 diff --git a/soc/arm/nxp_s32/s32k/Kconfig.defconfig.series b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series similarity index 87% rename from soc/arm/nxp_s32/s32k/Kconfig.defconfig.series rename to soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series index 93786720698..ed002e941ef 100644 --- a/soc/arm/nxp_s32/s32k/Kconfig.defconfig.series +++ b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series @@ -6,7 +6,7 @@ if SOC_SERIES_S32K3_M7 config SOC_SERIES - default "s32k" + default "s32k3" config SYS_CLOCK_HW_CYCLES_PER_SEC default 2000000 @@ -32,6 +32,6 @@ config NET_UDP_CHECKSUM endif # NET_L2_ETHERNET -source "soc/arm/nxp_s32/s32k/Kconfig.defconfig.s32k*" +source "soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k*" endif # SOC_SERIES_S32K_M7 diff --git a/soc/arm/nxp_s32/s32k/Kconfig.series b/soc/arm/nxp_s32/s32k3/Kconfig.series similarity index 100% rename from soc/arm/nxp_s32/s32k/Kconfig.series rename to soc/arm/nxp_s32/s32k3/Kconfig.series diff --git a/soc/arm/nxp_s32/s32k/Kconfig.soc b/soc/arm/nxp_s32/s32k3/Kconfig.soc similarity index 100% rename from soc/arm/nxp_s32/s32k/Kconfig.soc rename to soc/arm/nxp_s32/s32k3/Kconfig.soc diff --git a/soc/arm/nxp_s32/s32k/linker.ld b/soc/arm/nxp_s32/s32k3/linker.ld similarity index 100% rename from soc/arm/nxp_s32/s32k/linker.ld rename to soc/arm/nxp_s32/s32k3/linker.ld diff --git a/soc/arm/nxp_s32/s32k/mpu_regions.c b/soc/arm/nxp_s32/s32k3/mpu_regions.c similarity index 100% rename from soc/arm/nxp_s32/s32k/mpu_regions.c rename to soc/arm/nxp_s32/s32k3/mpu_regions.c diff --git a/soc/arm/nxp_s32/s32k/s32k3xx_startup.S b/soc/arm/nxp_s32/s32k3/s32k3xx_startup.S similarity index 100% rename from soc/arm/nxp_s32/s32k/s32k3xx_startup.S rename to soc/arm/nxp_s32/s32k3/s32k3xx_startup.S diff --git a/soc/arm/nxp_s32/s32k/sections.ld b/soc/arm/nxp_s32/s32k3/sections.ld similarity index 100% rename from soc/arm/nxp_s32/s32k/sections.ld rename to soc/arm/nxp_s32/s32k3/sections.ld diff --git a/soc/arm/nxp_s32/s32k/soc.c b/soc/arm/nxp_s32/s32k3/soc.c similarity index 100% rename from soc/arm/nxp_s32/s32k/soc.c rename to soc/arm/nxp_s32/s32k3/soc.c diff --git a/soc/arm/nxp_s32/s32k/soc.h b/soc/arm/nxp_s32/s32k3/soc.h similarity index 100% rename from soc/arm/nxp_s32/s32k/soc.h rename to soc/arm/nxp_s32/s32k3/soc.h From 8ca4f5b4a1fdad39c99c13d763480df05982531d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Mon, 6 Nov 2023 22:49:27 +0700 Subject: [PATCH 3692/4498] soc: nxp_s32: s32k3: drop `M7` suffix from options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing S32K3 Kconfig options employ the `M7` suffix, which is redundant given that all cores in this series utilize an Arm Cortex-M7 core. Therefore, we should remove it. Signed-off-by: Manuel Argüelles --- boards/arm/mr_canhubk3/Kconfig.board | 2 +- boards/arm/mr_canhubk3/mr_canhubk3_defconfig | 4 ++-- drivers/can/Kconfig.mcux | 4 ++-- drivers/dma/Kconfig.mcux_edma | 4 ++-- soc/arm/nxp_s32/Kconfig | 2 +- soc/arm/nxp_s32/common/CMakeLists.txt | 2 +- soc/arm/nxp_s32/common/osif.c | 2 +- soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 | 6 +++--- soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series | 6 +++--- soc/arm/nxp_s32/s32k3/Kconfig.series | 9 +++++---- soc/arm/nxp_s32/s32k3/Kconfig.soc | 13 ++++++------- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/boards/arm/mr_canhubk3/Kconfig.board b/boards/arm/mr_canhubk3/Kconfig.board index 3cea453a2a2..9c3f4e917b2 100644 --- a/boards/arm/mr_canhubk3/Kconfig.board +++ b/boards/arm/mr_canhubk3/Kconfig.board @@ -3,5 +3,5 @@ config BOARD_MR_CANHUBK3 bool "mr_canhubk3" - depends on SOC_SERIES_S32K3_M7 + depends on SOC_SERIES_S32K3XX select SOC_PART_NUMBER_S32K344 diff --git a/boards/arm/mr_canhubk3/mr_canhubk3_defconfig b/boards/arm/mr_canhubk3/mr_canhubk3_defconfig index 68613d22f11..d8182ce8327 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3_defconfig +++ b/boards/arm/mr_canhubk3/mr_canhubk3_defconfig @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_BOARD_MR_CANHUBK3=y -CONFIG_SOC_S32K344_M7=y -CONFIG_SOC_SERIES_S32K3_M7=y +CONFIG_SOC_S32K344=y +CONFIG_SOC_SERIES_S32K3XX=y CONFIG_BUILD_OUTPUT_HEX=y # Use Systick as system clock diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index e584996d7c0..5983be36c8a 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -31,7 +31,7 @@ config CAN_MCUX_FLEXCAN_WAIT_TIMEOUT config CAN_MAX_MB int "Maximum number of message buffers for concurrent active instances" default 16 - depends on SOC_SERIES_S32K3_M7 + depends on SOC_SERIES_S32K3XX range 1 96 help Defines maximum number of message buffers for concurrent active instances. @@ -42,7 +42,7 @@ config CAN_MAX_FILTER range 1 15 if SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_KINETIS_K6X range 1 13 if SOC_SERIES_IMX_RT && CAN_MCUX_FLEXCAN_FD range 1 63 if SOC_SERIES_IMX_RT - range 1 96 if SOC_SERIES_S32K3_M7 + range 1 96 if SOC_SERIES_S32K3XX help Defines maximum number of concurrent active RX filters diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index 0362a5faad6..d1e513e3c13 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -28,10 +28,10 @@ config DMA_TCD_QUEUE_SIZE config DMA_MCUX_TEST_SLOT_START int "test slot start num" - depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_S32K3_M7) + depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_S32K3XX) default 58 if SOC_SERIES_KINETIS_K6X default 60 if SOC_SERIES_KINETIS_KE1XF - default 62 if SOC_SERIES_S32K3_M7 + default 62 if SOC_SERIES_S32K3XX help test slot start num diff --git a/soc/arm/nxp_s32/Kconfig b/soc/arm/nxp_s32/Kconfig index 5a33f2065ff..e991957c03e 100644 --- a/soc/arm/nxp_s32/Kconfig +++ b/soc/arm/nxp_s32/Kconfig @@ -37,6 +37,6 @@ source "soc/arm/nxp_s32/*/Kconfig.soc" config SOC_PART_NUMBER default SOC_PART_NUMBER_S32ZE_R52 if SOC_SERIES_S32ZE_R52 - default SOC_PART_NUMBER_S32K3 if SOC_SERIES_S32K3_M7 + default SOC_PART_NUMBER_S32K3 if SOC_SERIES_S32K3XX endif # SOC_FAMILY_NXP_S32 diff --git a/soc/arm/nxp_s32/common/CMakeLists.txt b/soc/arm/nxp_s32/common/CMakeLists.txt index 13ec5b28101..6142be7ab64 100644 --- a/soc/arm/nxp_s32/common/CMakeLists.txt +++ b/soc/arm/nxp_s32/common/CMakeLists.txt @@ -3,4 +3,4 @@ zephyr_include_directories(.) zephyr_sources(osif.c) -zephyr_sources_ifdef(CONFIG_SOC_SERIES_S32K3_M7 power_soc.c) +zephyr_sources_ifdef(CONFIG_SOC_SERIES_S32K3XX power_soc.c) diff --git a/soc/arm/nxp_s32/common/osif.c b/soc/arm/nxp_s32/common/osif.c index 344a1416ee8..52de7a38b7f 100644 --- a/soc/arm/nxp_s32/common/osif.c +++ b/soc/arm/nxp_s32/common/osif.c @@ -9,7 +9,7 @@ #if defined(CONFIG_SOC_S32Z27_R52) #include -#elif defined(CONFIG_SOC_S32K344_M7) +#elif defined(CONFIG_SOC_S32K344) #include #endif diff --git a/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 index 3dfab760337..b1b534f6102 100644 --- a/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 +++ b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k344 @@ -1,9 +1,9 @@ -# S32K344 +# NXP S32K344 # Copyright 2023 NXP # SPDX-License-Identifier: Apache-2.0 -if SOC_S32K344_M7 +if SOC_S32K344 config SOC default "s32k344" @@ -11,4 +11,4 @@ config SOC config FPU default y -endif # SOC_S32K344_M7 +endif # SOC_S32K344 diff --git a/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series index ed002e941ef..04d54fdc666 100644 --- a/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series +++ b/soc/arm/nxp_s32/s32k3/Kconfig.defconfig.series @@ -1,9 +1,9 @@ -# S32 K M7 core series +# NXP S32K3XX MCU series # Copyright 2023 NXP # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_S32K3_M7 +if SOC_SERIES_S32K3XX config SOC_SERIES default "s32k3" @@ -34,4 +34,4 @@ endif # NET_L2_ETHERNET source "soc/arm/nxp_s32/s32k3/Kconfig.defconfig.s32k*" -endif # SOC_SERIES_S32K_M7 +endif # SOC_SERIES_S32K3XX diff --git a/soc/arm/nxp_s32/s32k3/Kconfig.series b/soc/arm/nxp_s32/s32k3/Kconfig.series index 3567b562cd7..50be01fe690 100644 --- a/soc/arm/nxp_s32/s32k3/Kconfig.series +++ b/soc/arm/nxp_s32/s32k3/Kconfig.series @@ -1,13 +1,14 @@ -# NXP S32K3 MCUs family +# NXP S32K3XX MCU series # Copyright 2023 NXP # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_S32K3_M7 - bool "S32K3 M7 Core Series" +config SOC_SERIES_S32K3XX + bool "NXP S32K3XX MCU series" select ARM select CPU_CORTEX_M7 select SOC_FAMILY_NXP_S32 + select HAS_NXP_S32_HAL select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS @@ -21,4 +22,4 @@ config SOC_SERIES_S32K3_M7 select HAS_MCUX_LPSPI select HAS_MCUX_CACHE help - Enable support for NXP S32K3 MCUs family on Cortex-M7 cores + Enable support for NXP S32K3XX MCU series. diff --git a/soc/arm/nxp_s32/s32k3/Kconfig.soc b/soc/arm/nxp_s32/s32k3/Kconfig.soc index 978c5daf65a..298477f71c2 100644 --- a/soc/arm/nxp_s32/s32k3/Kconfig.soc +++ b/soc/arm/nxp_s32/s32k3/Kconfig.soc @@ -1,19 +1,18 @@ -# NXP S32K MCUs family +# NXP S32K3XX MCU series # Copyright 2023 NXP # SPDX-License-Identifier: Apache-2.0 choice - prompt "NXP S32K MCUs family SoC Selection" - depends on SOC_SERIES_S32K3_M7 + prompt "NXP S32K3XX MCU selection" + depends on SOC_SERIES_S32K3XX -config SOC_S32K344_M7 - bool "SOC_S32K_M7" - select HAS_NXP_S32_HAL +config SOC_S32K344 + bool "s32k344" endchoice -if SOC_SERIES_S32K3_M7 +if SOC_SERIES_S32K3XX config SOC_PART_NUMBER_S32K344 bool From 1a05cfc03a87f65e6450f06925e00b44554c168d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 14 Nov 2023 20:45:38 +0700 Subject: [PATCH 3693/4498] soc: nxp_s32: consolidate part number options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the NXP S32 SoCs have three redundant Kconfig hidden options to define the part number. To streamline this, we will retain `CONFIG_SOC_PART_NUMBER` to store the part number as a string and `CONFIG_SOC_PART_NUMBER_` that can be selected by the boards. Furthermore, for drivers requiring conditional code compilation based on the target SoC, they should utilize the series or SoC config option as applicable, instead of the part number config. Signed-off-by: Manuel Argüelles --- boards/arm/mr_canhubk3/Kconfig.board | 2 +- drivers/ethernet/eth_nxp_s32_gmac.c | 4 ++-- soc/arm/nxp_s32/Kconfig | 4 ---- soc/arm/nxp_s32/common/power_soc.c | 2 +- soc/arm/nxp_s32/s32k3/Kconfig.soc | 6 +++--- soc/arm/nxp_s32/s32ze/Kconfig.soc | 4 ++-- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/boards/arm/mr_canhubk3/Kconfig.board b/boards/arm/mr_canhubk3/Kconfig.board index 9c3f4e917b2..af9a09391cd 100644 --- a/boards/arm/mr_canhubk3/Kconfig.board +++ b/boards/arm/mr_canhubk3/Kconfig.board @@ -4,4 +4,4 @@ config BOARD_MR_CANHUBK3 bool "mr_canhubk3" depends on SOC_SERIES_S32K3XX - select SOC_PART_NUMBER_S32K344 + select SOC_PART_NUMBER_PS32K344EHVPBS diff --git a/drivers/ethernet/eth_nxp_s32_gmac.c b/drivers/ethernet/eth_nxp_s32_gmac.c index 428a57c6065..71e3e94c176 100644 --- a/drivers/ethernet/eth_nxp_s32_gmac.c +++ b/drivers/ethernet/eth_nxp_s32_gmac.c @@ -78,7 +78,7 @@ static inline struct net_if *get_iface(struct eth_nxp_s32_data *ctx, uint16_t vl #endif } -#if defined(CONFIG_SOC_PART_NUMBER_S32K3) +#if defined(CONFIG_SOC_SERIES_S32K3XX) static int select_phy_interface(Gmac_Ip_MiiModeType mode) { uint32_t regval; @@ -105,7 +105,7 @@ static int select_phy_interface(Gmac_Ip_MiiModeType mode) } #else #error "SoC not supported" -#endif /* CONFIG_SOC_PART_NUMBER_S32K3 */ +#endif /* CONFIG_SOC_SERIES_S32K3XX */ static int eth_nxp_s32_init(const struct device *dev) { diff --git a/soc/arm/nxp_s32/Kconfig b/soc/arm/nxp_s32/Kconfig index e991957c03e..d014315e4d7 100644 --- a/soc/arm/nxp_s32/Kconfig +++ b/soc/arm/nxp_s32/Kconfig @@ -35,8 +35,4 @@ config NXP_S32_DEST_RESET_THRESHOLD source "soc/arm/nxp_s32/*/Kconfig.soc" -config SOC_PART_NUMBER - default SOC_PART_NUMBER_S32ZE_R52 if SOC_SERIES_S32ZE_R52 - default SOC_PART_NUMBER_S32K3 if SOC_SERIES_S32K3XX - endif # SOC_FAMILY_NXP_S32 diff --git a/soc/arm/nxp_s32/common/power_soc.c b/soc/arm/nxp_s32/common/power_soc.c index eef489ee8df..3e277155cb8 100644 --- a/soc/arm/nxp_s32/common/power_soc.c +++ b/soc/arm/nxp_s32/common/power_soc.c @@ -71,7 +71,7 @@ static int nxp_s32_power_init(void) }; const Power_Ip_PMC_ConfigType pmc_cfg = { -#ifdef CONFIG_SOC_PART_NUMBER_S32K3 +#ifdef CONFIG_SOC_SERIES_S32K3XX /* PMC Configuration Register (CONFIG) */ .ConfigRegister = PMC_CONFIG_LMEN(IS_ENABLED(CONFIG_NXP_S32_PMC_LMEN)) | PMC_CONFIG_LMBCTLEN(IS_ENABLED(CONFIG_NXP_S32_PMC_LMBCTLEN)), diff --git a/soc/arm/nxp_s32/s32k3/Kconfig.soc b/soc/arm/nxp_s32/s32k3/Kconfig.soc index 298477f71c2..6b8f4e3a883 100644 --- a/soc/arm/nxp_s32/s32k3/Kconfig.soc +++ b/soc/arm/nxp_s32/s32k3/Kconfig.soc @@ -14,12 +14,12 @@ endchoice if SOC_SERIES_S32K3XX -config SOC_PART_NUMBER_S32K344 +config SOC_PART_NUMBER_PS32K344EHVPBS bool -config SOC_PART_NUMBER_S32K3 +config SOC_PART_NUMBER string - default "S32K344" if SOC_PART_NUMBER_S32K344 + default "PS32K344EHVPBS" if SOC_PART_NUMBER_PS32K344EHVPBS help This string holds the full part number of the SoC. It is a hidden option that you should not set directly. The part number selection choice defines diff --git a/soc/arm/nxp_s32/s32ze/Kconfig.soc b/soc/arm/nxp_s32/s32ze/Kconfig.soc index 757b4096634..790751362d3 100644 --- a/soc/arm/nxp_s32/s32ze/Kconfig.soc +++ b/soc/arm/nxp_s32/s32ze/Kconfig.soc @@ -1,6 +1,6 @@ # NXP S32Z/E MCUs family -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # SPDX-License-Identifier: Apache-2.0 choice @@ -18,7 +18,7 @@ if SOC_SERIES_S32ZE_R52 config SOC_PART_NUMBER_S32Z27 bool -config SOC_PART_NUMBER_S32ZE_R52 +config SOC_PART_NUMBER string default "S32Z27" if SOC_PART_NUMBER_S32Z27 help From 7433a203ef606d5ccb8b6cb16371e00c90906d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 15 Nov 2023 16:12:12 +0100 Subject: [PATCH 3694/4498] doc: boards: Clean up repeated words MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed a bunch from repeated words across board READMEs. Signed-off-by: Benjamin Cabé --- boards/arm/arduino_nano_33_iot/doc/index.rst | 2 +- boards/arm/dragino_lsn50/doc/index.rst | 2 +- boards/arm/dragino_nbsn95/doc/index.rst | 2 +- boards/arm/faze/doc/index.rst | 2 +- boards/arm/reel_board/doc/index.rst | 3 +-- boards/arm/ronoth_lodev/doc/index.rst | 2 +- boards/arm/twr_ke18f/doc/index.rst | 2 +- boards/arm64/mimx93_evk/doc/index.rst | 2 +- boards/shields/atmel_rf2xx/doc/index.rst | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/boards/arm/arduino_nano_33_iot/doc/index.rst b/boards/arm/arduino_nano_33_iot/doc/index.rst index dfcf2a6bbcb..62353ecbe1e 100644 --- a/boards/arm/arduino_nano_33_iot/doc/index.rst +++ b/boards/arm/arduino_nano_33_iot/doc/index.rst @@ -6,7 +6,7 @@ Arduino Nano 33 IOT Overview ******** -The Arduino Nano 33 IOT is a a small form factor development board with USB, +The Arduino Nano 33 IOT is a small form factor development board with USB, Wifi, Bluetooth, a 6 axis IMU, and secure element. .. image:: img/nano_33_iot.jpg diff --git a/boards/arm/dragino_lsn50/doc/index.rst b/boards/arm/dragino_lsn50/doc/index.rst index 7931d8f9db8..732e0ec1394 100644 --- a/boards/arm/dragino_lsn50/doc/index.rst +++ b/boards/arm/dragino_lsn50/doc/index.rst @@ -85,7 +85,7 @@ More information about STM32L072CZ can be found here: Supported Features ================== -The Zephyr Dragino LSN50 Board board configuration supports the following hardware features: +The Zephyr Dragino LSN50 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | diff --git a/boards/arm/dragino_nbsn95/doc/index.rst b/boards/arm/dragino_nbsn95/doc/index.rst index 71e9f2c9711..ca0b3d8cc1d 100644 --- a/boards/arm/dragino_nbsn95/doc/index.rst +++ b/boards/arm/dragino_nbsn95/doc/index.rst @@ -84,7 +84,7 @@ More information about STM32L072CZ can be found here: Supported Features ================== -The Zephyr Dragino NBSN95 Board board configuration supports the following hardware features: +The Zephyr Dragino NBSN95 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | diff --git a/boards/arm/faze/doc/index.rst b/boards/arm/faze/doc/index.rst index ed432753fd7..1d61d997cd0 100644 --- a/boards/arm/faze/doc/index.rst +++ b/boards/arm/faze/doc/index.rst @@ -31,7 +31,7 @@ Hardware - External devices connected to the NXP LPC11U67 MCU: - ASMedia ASM2364 USB-to-PCIe bridge (I2C master on port O). - - 6 RGB LEDs connected connected to a TI LP5030 LED controller (I2C device on + - 6 RGB LEDs connected to a TI LP5030 LED controller (I2C device on port 1). - 1 white LED (SSD activity blinking). diff --git a/boards/arm/reel_board/doc/index.rst b/boards/arm/reel_board/doc/index.rst index dc490249abd..dec81bd88ec 100644 --- a/boards/arm/reel_board/doc/index.rst +++ b/boards/arm/reel_board/doc/index.rst @@ -462,8 +462,7 @@ Meaning of the Power Source Switch positions: X9 or X5. USB - link board BASE is powered from from USB connector - (via DCDC converter). + link board BASE is powered from USB connector (via DCDC converter). RB link board BASE is powered from reel board. The available power is diff --git a/boards/arm/ronoth_lodev/doc/index.rst b/boards/arm/ronoth_lodev/doc/index.rst index f1c60567a99..58f0756ecb3 100644 --- a/boards/arm/ronoth_lodev/doc/index.rst +++ b/boards/arm/ronoth_lodev/doc/index.rst @@ -8,7 +8,7 @@ Overview ======== The Ronoth_ LoDev_ is a small open source board containing a `AcSIP S76S`_ SiP from AcSIP_. -The `full LoDev design details`_ are available on on GitHub. The LoDev_ board can be purchased +The `full LoDev design details`_ are available on GitHub. The LoDev_ board can be purchased from Ronoth_ or from CrowdSupply_. The S76S contains an STMicro STM32L073RZ MCU, a `Semtech SX1276`_ LoRaWAN transceiver, diff --git a/boards/arm/twr_ke18f/doc/index.rst b/boards/arm/twr_ke18f/doc/index.rst index fd2c8c803d8..04aa94f0dfe 100644 --- a/boards/arm/twr_ke18f/doc/index.rst +++ b/boards/arm/twr_ke18f/doc/index.rst @@ -113,7 +113,7 @@ accelerometer and magnetometer for sensor values (``CONFIG_FXOS8700_TRIGGER_NONE=y``). In order to support FXOS8700 triggers (interrupts) the 0 ohm resistors -``R47`` and and ``R57`` must be mounted on the TWR-KE18F board. The +``R47`` and ``R57`` must be mounted on the TWR-KE18F board. The devicetree must also be modified to describe the FXOS8700 interrupt GPIOs: diff --git a/boards/arm64/mimx93_evk/doc/index.rst b/boards/arm64/mimx93_evk/doc/index.rst index 7ff38891d22..67997a3fbbe 100644 --- a/boards/arm64/mimx93_evk/doc/index.rst +++ b/boards/arm64/mimx93_evk/doc/index.rst @@ -168,7 +168,7 @@ Firstly, we need to explain a few Jailhouse concepts that will be referred to la cell can utilize. * **Root cell**: refers to the cell in which Linux is running. This is the main cell which - will contain all the hardware resources that Linux will utilize and will be used used to assign + will contain all the hardware resources that Linux will utilize and will be used to assign resources to the inmates. The inmates CANNOT use resources such as the CPU that haven't been assigned to the root cell. diff --git a/boards/shields/atmel_rf2xx/doc/index.rst b/boards/shields/atmel_rf2xx/doc/index.rst index dbcdccbd3e8..e9d2777fafe 100644 --- a/boards/shields/atmel_rf2xx/doc/index.rst +++ b/boards/shields/atmel_rf2xx/doc/index.rst @@ -179,7 +179,7 @@ Pins Assignment of the Arduino Shield Modules MikroBus Shields ================ -MikroBus header is available available without advanced features. It is +MikroBus header is available without advanced features. It is enabled selecting `atmel_rf2xx_mikrobus`_ variant option. Pins Assignment of the MikroBus Shield Modules From 18d28ea1449f905f8cbdce824c342086caafc12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 15 Nov 2023 13:09:18 +0100 Subject: [PATCH 3695/4498] linker: common-rom-logging: Use DEVNULL_REGION only if it exists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Log string removal is by default enabled for RISCV and Cortex-M and support is added to the default linker template. However, if SoC is not using default linker template then DEVNULL_REGION is not defined. In that case string removal cannot be used. Signed-off-by: Krzysztof Chruściński --- include/zephyr/linker/common-rom/common-rom-logging.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/linker/common-rom/common-rom-logging.ld b/include/zephyr/linker/common-rom/common-rom-logging.ld index 4e146375b43..9bb3e34626c 100644 --- a/include/zephyr/linker/common-rom/common-rom-logging.ld +++ b/include/zephyr/linker/common-rom/common-rom-logging.ld @@ -2,7 +2,7 @@ #include -#ifdef CONFIG_LOG_FMT_SECTION_STRIP +#if defined(CONFIG_LOG_FMT_SECTION_STRIP) && defined(DEVNULL_REGION) SECTION_PROLOGUE(log_strings,(COPY),SUBALIGN(4)) { Z_LINK_ITERABLE(log_strings); From 447f12d942c39439d1f0446a2d6c50328185562e Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 15 Nov 2023 11:52:12 -0600 Subject: [PATCH 3696/4498] drivers: nxp_flexram: Fix GPR 17 calculation GPR17 calculation for configuration of RAM banks is incorrect, bit shift should be 2 per idx, not 1, this is major bug that needs correcting, currently all RT boards are affected with wrong configuration. Signed-off-by: Declan Snyder --- drivers/memc/memc_nxp_flexram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memc/memc_nxp_flexram.h b/drivers/memc/memc_nxp_flexram.h index 34f606e6b86..397b60bf55d 100644 --- a/drivers/memc/memc_nxp_flexram.h +++ b/drivers/memc/memc_nxp_flexram.h @@ -44,7 +44,7 @@ void memc_flexram_register_callback(flexram_callback_t callback, void *user_data * call from platform_init to set up flexram if using runtime map * must be inlined because cannot use stack */ -#define GPR17_REG_FILL(node_id, prop, idx) + (DT_PROP_BY_IDX(node_id, prop, idx) << idx) +#define GPR17_REG_FILL(node_id, prop, idx) + (DT_PROP_BY_IDX(node_id, prop, idx) << (2*idx)) static inline void memc_flexram_dt_partition(void) { /* iomuxc_gpr must be const (in ROM region) because used in reconfiguring ram */ From ad3b3a9b9330bf6b3214fc96bfc8d0201aa25713 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 15 Nov 2023 14:00:33 -0600 Subject: [PATCH 3697/4498] drivers: memc_nxp_flexram: Use nodelabel for GPR Get GPR base address using nodelabel as this will align for all the current in tree platforms. Currently inst 0 of the compat gets wrong node and base address on RT11xx. Signed-off-by: Declan Snyder --- drivers/memc/memc_nxp_flexram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memc/memc_nxp_flexram.h b/drivers/memc/memc_nxp_flexram.h index 397b60bf55d..5ea2e89d0cc 100644 --- a/drivers/memc/memc_nxp_flexram.h +++ b/drivers/memc/memc_nxp_flexram.h @@ -8,7 +8,7 @@ #include #define FLEXRAM_DT_NODE DT_INST(0, nxp_flexram) -#define IOMUXC_GPR_DT_NODE DT_INST(0, nxp_imx_gpr) +#define IOMUXC_GPR_DT_NODE DT_NODELABEL(iomuxcgpr) #if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) || \ defined(CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT) From 78afda36f120c1cf2c58088b8e252b0c66a3c5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 15 Nov 2023 15:34:31 +0100 Subject: [PATCH 3698/4498] scripts: Add "the the" as a common typo in spellchecker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Somehow this is seems to be a very common typo. Adding it to spelling.txt to catch it as part of compliance check. Signed-off-by: Benjamin Cabé --- scripts/spelling.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/spelling.txt b/scripts/spelling.txt index fd3c5170303..84e4d944a77 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -1080,6 +1080,7 @@ targetting||targeting teh||the temorary||temporary temproarily||temporarily +the the||the therfore||therefore thier||their threds||threads From 05e6e1ce15835d791f47aa1b138b69d9110cf973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 15 Nov 2023 17:04:10 +0100 Subject: [PATCH 3699/4498] scripts: sync spelling.txt with version from Linux kernel v6.7-rc1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync the spelling.txt file with a recent version of the one found in Linux kernel. List sorting was preserved (however inconsistent it might be) to simplify future syncs. Signed-off-by: Benjamin Cabé --- scripts/spelling.txt | 529 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 527 insertions(+), 2 deletions(-) diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 84e4d944a77..ffa9e7cb8e3 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -9,7 +9,12 @@ # abandonning||abandoning abigious||ambiguous +abitrary||arbitrary abitrate||arbitrate +abnornally||abnormally +abnrormal||abnormal +abord||abort +aboslute||absolute abov||above abreviated||abbreviated absense||absence @@ -17,6 +22,8 @@ absolut||absolute absoulte||absolute acccess||access acceess||access +accelaration||acceleration +accelearion||acceleration acceleratoin||acceleration accelleration||acceleration accesing||accessing @@ -25,6 +32,7 @@ accessable||accessible accesss||access accidentaly||accidentally accidentually||accidentally +acclerated||accelerated accoding||according accomodate||accommodate accomodates||accommodates @@ -34,8 +42,11 @@ accout||account accquire||acquire accquired||acquired accross||across +accumalate||accumulate +accumalator||accumulator acessable||accessible acess||access +acessing||accessing achitecture||architecture acient||ancient acitions||actions @@ -48,24 +59,36 @@ acording||according activete||activate actived||activated actualy||actually +actvie||active acumulating||accumulating +acumulative||accumulative acumulator||accumulator +acutally||actually adapater||adapter +adderted||asserted addional||additional additionaly||additionally +additonal||additional addres||address +adddress||address addreses||addresses addresss||address +addrress||address aditional||additional aditionally||additionally aditionaly||additionally adminstrative||administrative adress||address adresses||addresses +adrresses||addresses +advertisment||advertisement adviced||advised afecting||affecting againt||against agaist||against +aggreataon||aggregation +aggreation||aggregation +ajust||adjust albumns||albums alegorical||allegorical algined||aligned @@ -73,15 +96,19 @@ algorith||algorithm algorithmical||algorithmically algoritm||algorithm algoritms||algorithms +algorithmn||algorithm algorrithm||algorithm algorritm||algorithm aligment||alignment alignement||alignment allign||align alligned||aligned +alllocate||allocate +alloated||allocated allocatote||allocate allocatrd||allocated allocte||allocate +allocted||allocated allpication||application alocate||allocate alogirhtms||algorithms @@ -89,11 +116,17 @@ alogrithm||algorithm alot||a lot alow||allow alows||allows +alreay||already +alredy||already altough||although alue||value ambigious||ambiguous +ambigous||ambiguous amoung||among +amount of times||number of times amout||amount +amplifer||amplifier +amplifyer||amplifier an union||a union an user||a user an userspace||a userspace @@ -122,35 +155,56 @@ aquired||acquired aquisition||acquisition arbitary||arbitrary architechture||architecture +archtecture||architecture arguement||argument arguements||arguments +arithmatic||arithmetic aritmetic||arithmetic arne't||aren't arraival||arrival artifical||artificial artillary||artillery asign||assign +asser||assert assertation||assertion +assertting||asserting +assgined||assigned assiged||assigned assigment||assignment assigments||assignments assistent||assistant +assocaited||associated +assocating||associating assocation||association associcated||associated assotiated||associated +asssert||assert assum||assume assumtpion||assumption asuming||assuming asycronous||asynchronous +asychronous||asynchronous asynchnous||asynchronous +asynchronus||asynchronous +asynchromous||asynchronous +asymetric||asymmetric +asymmeric||asymmetric +atleast||at least atomatically||automatically atomicly||atomically atempt||attempt +atrributes||attributes attachement||attachment +attatch||attach attched||attached +attemp||attempt attemps||attempts +attemping||attempting +attepmpt||attempt +attnetion||attention attruibutes||attributes authentification||authentication +authenicated||authenticated automaticaly||automatically automaticly||automatically automatize||automate @@ -164,10 +218,12 @@ avaible||available availabe||available availabled||available availablity||availability +availaible||available availale||available availavility||availability availble||available availiable||available +availible||available avalable||available avaliable||available aysnc||async @@ -181,6 +237,7 @@ baloons||balloons bandwith||bandwidth banlance||balance batery||battery +battey||battery beacuse||because becasue||because becomming||becoming @@ -192,30 +249,57 @@ beter||better betweeen||between bianries||binaries bitmast||bitmask +bitwiedh||bitwidth boardcast||broadcast borad||board boundry||boundary brievely||briefly +brigde||bridge +broadcase||broadcast broadcat||broadcast +bufer||buffer +bufferred||buffered +bufufer||buffer cacluated||calculated +caculate||calculate caculation||calculation +cadidate||candidate +cahces||caches calender||calendar +calescing||coalescing calle||called callibration||calibration +callled||called +callser||caller calucate||calculate calulate||calculate cancelation||cancellation +cancle||cancel +cant||can't +cant'||can't +canot||cannot +cann't||can't +cannnot||cannot +capabiity||capability capabilites||capabilities +capabilties||capabilities +capabilty||capability capabitilies||capabilities +capablity||capability capatibilities||capabilities +capapbilities||capabilities +caputure||capture carefuly||carefully cariage||carriage +casued||caused catagory||category cehck||check challange||challenge challanges||challenges +chache||cache chanell||channel changable||changeable +chanined||chained channle||channel channnel||channel charachter||character @@ -226,6 +310,7 @@ charaters||characters charcter||character chcek||check chck||check +checksumed||checksummed checksuming||checksumming childern||children childs||children @@ -233,6 +318,7 @@ chiled||child chked||checked chnage||change chnages||changes +chnange||change chnnel||channel choosen||chosen chouse||chose @@ -241,6 +327,9 @@ claread||cleared clared||cleared closeing||closing clustred||clustered +cnfiguration||configuration +coexistance||coexistence +colescing||coalescing collapsable||collapsible colorfull||colorful comand||command @@ -251,14 +340,18 @@ comminucation||communication commited||committed commiting||committing committ||commit +commnunication||communication commoditiy||commodity comsume||consume comsumer||consumer comsuming||consuming +comaptible||compatible compability||compatibility compaibility||compatibility +comparsion||comparison compatability||compatibility compatable||compatible +compatibililty||compatibility compatibiliy||compatibility compatibilty||compatibility compatiblity||compatibility @@ -269,16 +362,29 @@ completition||completion completly||completely complient||compliant componnents||components +compoment||component +comppatible||compatible compres||compress compresion||compression +compresser||compressor comression||compression +comsumed||consumed +comunicate||communicate comunication||communication conbination||combination concurent||concurrent conditionaly||conditionally +conditon||condition +condtion||condition +condtional||conditional conected||connected connecetd||connected +conector||connector +configration||configuration +configred||configured configuartion||configuration +configuation||configuration +configued||configured configuratoin||configuration configuraton||configuration configuretion||configuration @@ -286,6 +392,7 @@ configutation||configuration conider||consider conjuction||conjunction connectinos||connections +connetor||connector connnection||connection connnections||connections consistancy||consistency @@ -295,10 +402,13 @@ containts||contains contaisn||contains contant||contact contence||contents +contiguos||contiguous +continious||continuous continous||continuous continously||continuously continueing||continuing contraints||constraints +contruct||construct contol||control contoller||controller controled||controlled @@ -316,22 +426,35 @@ correponding||corresponding correponds||corresponds correspoding||corresponding cotrol||control +cound||could couter||counter coutner||counter +creationg||creating cryptocraphic||cryptographic +cummulative||cumulative cunter||counter curent||current curently||currently cylic||cyclic dafault||default +deactive||deactivate deafult||default deamon||daemon +debouce||debounce +decendant||descendant +decendants||descendants decompres||decompress +decsribed||described decription||description +dectected||detected defailt||default +deferal||deferral +deffered||deferred defferred||deferred definate||definite definately||definitely +definiation||definition +definiton||definition defintion||definition defintions||definitions defualt||default @@ -345,25 +468,38 @@ delare||declare delares||declares delaring||declaring delemiter||delimiter +delibrately||deliberately +delievered||delivered +demodualtor||demodulator +demension||dimension dependancies||dependencies dependancy||dependency dependant||dependent +dependend||dependent depreacted||deprecated depreacte||deprecate desactivate||deactivate desciptor||descriptor desciptors||descriptors +descripto||descriptor descripton||description descrition||description descritptor||descriptor desctiptor||descriptor desriptor||descriptor desriptors||descriptors +desination||destination +destionation||destination +destoried||destroyed destory||destroy destoryed||destroyed destorys||destroys destroied||destroyed detabase||database +deteced||detected +detecion||detection +detectt||detect +detroyed||destroyed develope||develop developement||development developped||developed @@ -373,43 +509,77 @@ developpment||development deveolpment||development devided||divided deviece||device +devision||division diable||disable +diabled||disabled +dicline||decline dictionnary||dictionary didnt||didn't diferent||different differrence||difference diffrent||different +differenciate||differentiate +diffreential||differential diffrentiate||differentiate difinition||definition +digial||digital +dimention||dimension +dimesions||dimensions +diconnected||disconnected +disabed||disabled +disasembler||disassembler +disgest||digest +disired||desired +dispalying||displaying +dissable||disable diplay||display +directon||direction +direcly||directly direectly||directly +diregard||disregard disassocation||disassociation disapear||disappear disapeared||disappeared disappared||disappeared +disbale||disable +disbaled||disabled disble||disable disbled||disabled disconnet||disconnect discontinous||discontinuous +disharge||discharge +disnabled||disabled dispertion||dispersion dissapears||disappears +dissconect||disconnect distiction||distinction +divisable||divisible +divsiors||divisors +dsiabled||disabled docuentation||documentation documantation||documentation documentaion||documentation documment||document doesnt||doesn't +donwload||download +donwloading||downloading dorp||drop dosen||doesn downlad||download downlads||downloads +droped||dropped +droput||dropout druing||during +dyanmic||dynamic dynmaic||dynamic +eanable||enable +eanble||enable easilly||easily ecspecially||especially edditable||editable editting||editing efective||effective +effectivness||effectiveness efficently||efficiently ehther||ether eigth||eight @@ -417,14 +587,23 @@ elementry||elementary eletronic||electronic embeded||embedded enabledi||enabled +enbale||enable +enble||enable enchanced||enhanced encorporating||incorporating encrupted||encrypted encrypiton||encryption +encryptio||encryption endianess||endianness +enpoint||endpoint enhaced||enhanced enlightnment||enlightenment +enqueing||enqueuing +entires||entries +entites||entities +entrys||entries enocded||encoded +enought||enough enterily||entirely enviroiment||environment enviroment||environment @@ -435,19 +614,37 @@ equiped||equipped equivelant||equivalent equivilant||equivalent eror||error +errorr||error +errror||error estbalishment||establishment etsablishment||establishment etsbalishment||establishment +evalute||evaluate +evalutes||evaluates +evalution||evaluation excecutable||executable +excceed||exceed exceded||exceeded +exceds||exceeds +exceeed||exceed excellant||excellent +exchnage||exchange +execeeded||exceeded +execeeds||exceeds +exeed||exceed +exeeds||exceeds +exeuction||execution existance||existence existant||existent exixt||exist +exsits||exists exlcude||exclude +exlcuding||excluding exlcusive||exclusive +exlusive||exclusive exmaple||example expecially||especially +experies||expires explicite||explicit explicitely||explicitly explict||explicit @@ -456,47 +653,69 @@ explictly||explicitly expresion||expression exprimental||experimental extened||extended +exteneded||extended extensability||extensibility extention||extension +extenstion||extension extracter||extractor -falied||failed +faied||failed +faield||failed faild||failed +failded||failed +failer||failure faill||fail failied||failed faillure||failure failue||failure failuer||failure +failng||failing faireness||fairness falied||failed faliure||failure +fallbck||fallback familar||familiar fatser||faster feauture||feature feautures||features fetaure||feature fetaures||features +fetcing||fetching fileystem||filesystem +fimrware||firmware fimware||firmware +firmare||firmware +firmaware||firmware +firtly||firstly +firware||firmware +firwmare||firmware finanize||finalize findn||find finilizes||finalizes finsih||finish +fliter||filter flusing||flushing folloing||following followign||following followings||following follwing||following +fonud||found forseeable||foreseeable forse||force fortan||fortran forwardig||forwarding +frambuffer||framebuffer framming||framing framwork||framework +frequence||frequency frequncy||frequency +frequancy||frequency frome||from +fronend||frontend fucntion||function fuction||function fuctions||functions +fullill||fulfill +funcation||function funcion||function functionallity||functionality functionaly||functionally @@ -507,41 +726,64 @@ funtions||functions furthur||further futhermore||furthermore futrue||future +gatable||gateable +gateing||gating +gauage||gauge gaurenteed||guaranteed generiously||generously genereate||generate +genereted||generated genric||generic +gerenal||general +geting||getting globel||global grabing||grabbing grahical||graphical grahpical||graphical +granularty||granularity grapic||graphic +grranted||granted guage||gauge guarenteed||guaranteed guarentee||guarantee halfs||halves hander||handler handfull||handful +hanlde||handle hanled||handled happend||happened +hardare||hardware harware||hardware +hardward||hardware +havind||having heirarchically||hierarchically +heirarchy||hierarchy helpfull||helpful +hearbeat||heartbeat +heterogenous||heterogeneous +hexdecimal||hexadecimal +hybernate||hibernate hierachy||hierarchy hierarchie||hierarchy +homogenous||homogeneous howver||however hsould||should hypervior||hypervisor hypter||hyper +idel||idle identidier||identifier iligal||illegal illigal||illegal +illgal||illegal +iomaped||iomapped imblance||imbalance immeadiately||immediately immedaite||immediate +immedate||immediate immediatelly||immediately immediatly||immediately immidiate||immediate +immutible||immutable impelentation||implementation impementated||implemented implemantation||implementation @@ -549,24 +791,34 @@ implemenation||implementation implementaiton||implementation implementated||implemented implemention||implementation +implementd||implemented implemetation||implementation implemntation||implementation implentation||implementation implmentation||implementation implmenting||implementing +incative||inactive incomming||incoming +incompaitiblity||incompatibility incompatabilities||incompatibilities incompatable||incompatible +incompatble||incompatible inconsistant||inconsistent increas||increase +incremeted||incremented incrment||increment +incuding||including +inculde||include indendation||indentation indended||intended independant||independent independantly||independently independed||independent indiate||indicate +indicat||indicate inexpect||inexpected +inferface||interface +infinit||infinite infomation||information informatiom||information informations||information @@ -581,27 +833,41 @@ initalize||initialize initation||initiation initators||initiators initialiazation||initialization +initializationg||initialization initializiation||initialization +initialze||initialize initialzed||initialized +initialzing||initializing initilization||initialization initilize||initialize +initliaze||initialize +initilized||initialized inofficial||unofficial +inrerface||interface insititute||institute +instace||instance instal||install +instanciate||instantiate instanciated||instantiated +instuments||instruments +insufficent||insufficient inteface||interface integreated||integrated integrety||integrity integrey||integrity intendet||intended intented||intended +interal||internal interanl||internal interchangable||interchangeable interferring||interfering interger||integer +intergrated||integrated intermittant||intermittent internel||internal interoprability||interoperability +interuupt||interrupt +interupts||interrupts interrface||interface interrrupt||interrupt interrup||interrupt @@ -609,6 +875,7 @@ interrups||interrupts interruptted||interrupted interupted||interrupted interupt||interrupt +intiailized||initialized intial||initial intialisation||initialisation intialised||initialised @@ -617,24 +884,35 @@ intialization||initialization intialized||initialized intialize||initialize intregral||integral +intrerrupt||interrupt intrrupt||interrupt intterrupt||interrupt intuative||intuitive +inavlid||invalid invaid||invalid +invaild||invalid +invailid||invalid +invald||invalid invalde||invalid invalide||invalid +invalidiate||invalidate invalud||invalid invididual||individual invokation||invocation invokations||invocations +ireelevant||irrelevant irrelevent||irrelevant isnt||isn't isssue||issue +issus||issues +iteraions||iterations iternations||iterations itertation||iteration itslef||itself +ivalid||invalid jave||java jeffies||jiffies +jumpimng||jumping juse||just jus||just kown||known @@ -644,6 +922,7 @@ langauge||language langugage||language lauch||launch layed||laid +legnth||length leightweight||lightweight lengh||length lenght||length @@ -654,40 +933,66 @@ libary||library librairies||libraries libraris||libraries licenceing||licencing +limted||limited +logaritmic||logarithmic loggging||logging loggin||login logile||logfile +loobpack||loopback loosing||losing losted||lost +maangement||management machinary||machinery +maibox||mailbox maintainance||maintenance maintainence||maintenance maintan||maintain makeing||making +mailformed||malformed malplaced||misplaced malplace||misplace managable||manageable +managament||management managment||management mangement||management +manger||manager manoeuvering||maneuvering +manufaucturing||manufacturing mappping||mapping +maping||mapping +matchs||matches mathimatical||mathematical mathimatic||mathematic mathimatics||mathematics +maxmium||maximum +maximium||maximum maxium||maximum mechamism||mechanism +mechanim||mechanism meetign||meeting +memeory||memory +memmber||member +memoery||memory +memroy||memory ment||meant mergable||mergeable mesage||message +mesages||messages messags||messages messgaes||messages messsage||message messsages||messages +metdata||metadata +micropone||microphone microprocesspr||microprocessor +migrateable||migratable +millenium||millennium milliseonds||milliseconds +minimim||minimum minium||minimum minimam||minimum +minimun||minimum +miniumum||minimum minumum||minimum misalinged||misaligned miscelleneous||miscellaneous @@ -695,21 +1000,35 @@ misformed||malformed mispelled||misspelled mispelt||misspelt mising||missing +mismactch||mismatch +missign||missing +missmanaged||mismanaged +missmatch||mismatch +misssing||missing miximum||maximum mmnemonic||mnemonic mnay||many +modfiy||modify +modifer||modifier +modul||module modulues||modules momery||memory +memomry||memory +monitring||monitoring monochorome||monochrome monochromo||monochrome monocrome||monochrome mopdule||module mroe||more mulitplied||multiplied +muliple||multiple +multipler||multiplier multidimensionnal||multidimensional +multipe||multiple multple||multiple mumber||number muticast||multicast +mutilcast||multicast mutiple||multiple mutli||multi nams||names @@ -726,45 +1045,67 @@ negotation||negotiation nerver||never nescessary||necessary nessessary||necessary +none existent||non-existent noticable||noticeable +notication||notification notications||notifications +notifcations||notifications notifed||notified +notity||notify +nubmer||number numebr||number +numer||number numner||number +nunber||number obtaion||obtain +obusing||abusing occassionally||occasionally occationally||occasionally occurance||occurrence occurances||occurrences -occured||occurred +occurd||occurred occurence||occurrence occure||occurred occured||occurred occuring||occurring +ocurrence||occurrence +offser||offset offet||offset +offlaod||offload +offloded||offloaded +offseting||offsetting +oflload||offload omited||omitted omiting||omitting omitt||omit ommiting||omitting ommitted||omitted onself||oneself +onthe||on the ony||only +openning||opening operatione||operation opertaions||operations +opportunies||opportunities optionnal||optional optmizations||optimizations orientatied||orientated orientied||oriented orignal||original +originial||original otherise||otherwise ouput||output oustanding||outstanding overaall||overall overhread||overhead overlaping||overlapping +oveflow||overflow +overflw||overflow +overlfow||overflow overide||override overrided||overridden overriden||overridden +overrrun||overrun overun||overrun overwritting||overwriting overwriten||overwritten @@ -775,8 +1116,10 @@ packege||package packge||package packtes||packets pakage||package +paket||packet pallette||palette paln||plan +palne||plane paramameters||parameters paramaters||parameters paramater||parameter @@ -784,22 +1127,36 @@ parametes||parameters parametised||parametrised paramter||parameter paramters||parameters +parmaters||parameters particuarly||particularly particularily||particularly +partion||partition +partions||partitions partiton||partition pased||passed passin||passing pathes||paths +pattrns||patterns pecularities||peculiarities peformance||performance +peforming||performing peice||piece pendantic||pedantic peprocessor||preprocessor +perfomance||performance perfoming||performing +perfomring||performing +periperal||peripheral +peripherial||peripheral permissons||permissions +permited||permitted peroid||period persistance||persistence persistant||persistent +phoneticly||phonetically +plaform||platform +plalform||platform +platfoem||platform platfrom||platform plattform||platform pleaes||please @@ -811,7 +1168,12 @@ poiter||pointer posible||possible positon||position possibilites||possibilities +potocol||protocol powerfull||powerful +pramater||parameter +preamle||preamble +preample||preamble +preapre||prepare preceeded||preceded preceeding||preceding preceed||precede @@ -820,17 +1182,28 @@ precission||precision preemptable||preemptible prefered||preferred prefferably||preferably +prefitler||prefilter +preform||perform premption||preemption prepaired||prepared +prepate||prepare +preperation||preparation +preprare||prepare pressre||pressure +presuambly||presumably +previosuly||previously +previsously||previously primative||primitive princliple||principle priorty||priority +priting||printing privilaged||privileged privilage||privilege priviledge||privilege priviledges||privileges +privleges||privileges probaly||probably +probabalistic||probabilistic procceed||proceed proccesors||processors procesed||processed @@ -843,12 +1216,17 @@ processsed||processed processsing||processing procteted||protected prodecure||procedure +progamming||programming progams||programs progess||progress +programable||programmable programers||programmers programm||program programms||programs +progres||progress progresss||progress +prohibitted||prohibited +prohibitting||prohibiting promiscous||promiscuous promps||prompts pronnounced||pronounced @@ -858,34 +1236,45 @@ pronunce||pronounce propery||property propigate||propagate propigation||propagation +propogation||propagation propogate||propagate prosess||process protable||portable protcol||protocol protecion||protection +protedcted||protected protocoll||protocol promixity||proximity psudo||pseudo psuedo||pseudo psychadelic||psychedelic +purgable||purgeable pwoer||power +queing||queuing quering||querying +queus||queues +randomally||randomly raoming||roaming reasearcher||researcher reasearchers||researchers reasearch||research +receieve||receive recepient||recipient +recevied||received receving||receiving +recievd||received recieved||received recieve||receive reciever||receiver recieves||receives +recieving||receiving recogniced||recognised recognizeable||recognizable recommanded||recommended recyle||recycle redircet||redirect redirectrion||redirection +redundacy||redundancy reename||rename refcounf||refcount refence||reference @@ -895,8 +1284,12 @@ refering||referring refernces||references refernnce||reference refrence||reference +regiser||register +registed||registered registerd||registered +registeration||registration registeresd||registered +registerred||registered registes||registers registraration||registration regsiter||register @@ -907,6 +1300,7 @@ regulamentations||regulations reigstration||registration releated||related relevent||relevant +reloade||reload remoote||remote remore||remote removeable||removable @@ -917,29 +1311,45 @@ replys||replies reponse||response representaion||representation reqeust||request +reqister||register +requed||requeued requestied||requested requiere||require requirment||requirement requred||required requried||required requst||request +requsted||requested +reregisteration||reregistration reseting||resetting +reseved||reserved +reseverd||reserved resizeable||resizable +resotre||restore +resouce||resource resouces||resources resoures||resources responce||response +resrouce||resource ressizes||resizes ressource||resource ressources||resources +restesting||retesting +resumbmitting||resubmitting retransmited||retransmitted retreived||retrieved retreive||retrieve +retreiving||retrieving retrive||retrieve +retrived||retrieved +retrun||return +retun||return retuned||returned reudce||reduce reuest||request reuqest||request reutnred||returned +revsion||revision rmeoved||removed rmeove||remove rmeoves||removes @@ -948,20 +1358,29 @@ routins||routines rquest||request runing||running runned||ran +runnnig||running runnning||running runtine||runtime sacrifying||sacrificing safly||safely safty||safety +satify||satisfy +satisifed||satisfied savable||saveable +scaleing||scaling scaned||scanned scaning||scanning scarch||search +schdule||schedule seach||search searchs||searches +secion||section secquence||sequence secund||second segement||segment +seleted||selected +semaphone||semaphore +senario||scenario senarios||scenarios sentivite||sensitive separatly||separately @@ -973,11 +1392,19 @@ seperate||separate seperatly||separately seperator||separator sepperate||separate +seqeunce||sequence +seqeuncer||sequencer +seqeuencer||sequencer sequece||sequence +sequemce||sequence sequencial||sequential +serivce||service serveral||several +servive||service setts||sets settting||setting +shapshot||snapshot +shoft||shift shotdown||shutdown shoud||should shouldnt||shouldn't @@ -985,24 +1412,35 @@ shoule||should shrinked||shrunk siginificantly||significantly signabl||signal +significanly||significantly similary||similarly similiar||similar simlar||similar simliar||similar simpified||simplified +simultaneusly||simultaneously +simultanous||simultaneous singaled||signaled singal||signal singed||signed +slect||select sleeped||slept +sliped||slipped +softwade||software softwares||software +soley||solely +souce||source speach||speech specfic||specific +specfield||specified speciefied||specified specifc||specific specifed||specified specificatin||specification specificaton||specification +specificed||specified specifing||specifying +specifiy||specify specifiying||specifying speficied||specified speicify||specify @@ -1019,8 +1457,12 @@ staion||station standardss||standards standartization||standardization standart||standard +standy||standby +stardard||standard staticly||statically +statuss||status stoped||stopped +stoping||stopping stoppped||stopped straming||streaming struc||struct @@ -1032,12 +1474,18 @@ sturcture||structure subdirectoires||subdirectories suble||subtle substract||subtract +submited||submitted +submition||submission +succeded||succeeded +suceed||succeed +succesfuly||successfully succesfully||successfully succesful||successful successed||succeeded successfull||successful successfuly||successfully sucessfully||successfully +sucessful||successful sucess||success superflous||superfluous superseeded||superseded @@ -1046,14 +1494,18 @@ suported||supported suport||support supportet||supported suppored||supported +supporing||supporting supportin||supporting suppoted||supported suppported||supported suppport||support +supprot||support supress||suppress +surpressed||suppressed surpresses||suppresses susbsystem||subsystem suspeneded||suspended +suspsend||suspend suspicously||suspiciously swaping||swapping switchs||switches @@ -1064,9 +1516,14 @@ swithced||switched swithcing||switching swithed||switched swithing||switching +swtich||switch +syfs||sysfs symetric||symmetric synax||syntax synchonized||synchronized +sychronization||synchronization +sychronously||synchronously +synchronuously||synchronously syncronize||synchronize syncronized||synchronized syncronizing||synchronizing @@ -1075,43 +1532,78 @@ syste||system sytem||system sythesis||synthesis taht||that +tained||tainted +tarffic||traffic +tansmit||transmit targetted||targeted targetting||targeting +taskelt||tasklet teh||the +temeprature||temperature temorary||temporary temproarily||temporarily +temperture||temperature the the||the +theads||threads therfore||therefore thier||their threds||threads +threee||three threshhold||threshold +thresold||threshold throught||through +tansition||transition +trackling||tracking +troughput||throughput +trys||tries thses||these +tiggers||triggers tiggered||triggered tipically||typically +timeing||timing timout||timeout tmis||this +toogle||toggle torerable||tolerable +torlence||tolerance +traget||target +traking||tracking tramsmitted||transmitted tramsmit||transmit +tranasction||transaction +tranceiver||transceiver tranfer||transfer +tranmission||transmission +transcevier||transceiver transciever||transceiver transferd||transferred transfered||transferred transfering||transferring transision||transition +transistioned||transitioned transmittd||transmitted transormed||transformed +trasfer||transfer trasmission||transmission treshold||threshold +triggerd||triggered +trigerred||triggered trigerring||triggering trun||turn +tunning||tuning ture||true tyep||type udpate||update +updtes||updates uesd||used +unknwon||unknown +uknown||unknown +usccess||success uncommited||uncommitted +uncompatible||incompatible unconditionaly||unconditionally +undeflow||underflow +undelying||underlying underun||underrun unecessary||unnecessary unexecpted||unexpected @@ -1122,31 +1614,52 @@ unexpeted||unexpected unexpexted||unexpected unfortunatelly||unfortunately unifiy||unify +uniterrupted||uninterrupted +uninterruptable||uninterruptible unintialized||uninitialized +unitialized||uninitialized unkmown||unknown unknonw||unknown +unknouwn||unknown unknow||unknown unkown||unknown +unamed||unnamed +uneeded||unneeded unneded||unneeded +unneccecary||unnecessary +unneccesary||unnecessary +unneccessary||unnecessary +unnecesary||unnecessary unneedingly||unnecessarily unnsupported||unsupported +unuspported||unsupported unmached||unmatched +unprecise||imprecise +unpriviledged||unprivileged +unpriviliged||unprivileged unregester||unregister unresgister||unregister unrgesiter||unregister unsinged||unsigned unstabel||unstable +unsolicted||unsolicited unsolicitied||unsolicited unsuccessfull||unsuccessful unsuported||unsupported untill||until +ununsed||unused unuseful||useless +unvalid||invalid upate||update +upsupported||unsupported +upto||up to +useable||usable usefule||useful usefull||useful usege||usage usera||users usualy||usually +usupported||unsupported utilites||utilities utillities||utilities utilties||utilities @@ -1161,8 +1674,12 @@ varible||variable varient||variant vaule||value verbse||verbose +veify||verify +verfication||verification +veriosn||version verisons||versions verison||version +veritical||vertical verson||version vicefersa||vice-versa virtal||virtual @@ -1170,7 +1687,12 @@ virtaul||virtual virtiual||virtual visiters||visitors vitual||virtual +vunerable||vulnerable +wakeus||wakeups +was't||wasn't +wathdog||watchdog wating||waiting +wiat||wait wether||whether whataver||whatever whcih||which @@ -1178,12 +1700,15 @@ whenver||whenever wheter||whether whe||when wierd||weird +wihout||without wiil||will wirte||write withing||within wnat||want +wont||won't workarould||workaround writeing||writing writting||writing +wtih||with zombe||zombie zomebie||zombie From 155420522b403f42b5f1943cb33ca90f04bffd2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 15 Nov 2023 16:29:08 +0100 Subject: [PATCH 3700/4498] doc: Fix occurrences of repeated words MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another round of repeated words cleanup. This commit tries to keep the diff minimal and line wrapping was mostly left intact in the touched files, as having them consistent across the documentation is probably the topic of a future tree-wide cleanup (or not) Signed-off-by: Benjamin Cabé --- doc/build/cmake/index.rst | 2 +- doc/build/dts/intro-syntax-structure.rst | 2 +- doc/build/kconfig/setting.rst | 3 +-- doc/connectivity/bluetooth/api/gatt.rst | 2 +- doc/connectivity/bluetooth/api/shell/cap.rst | 2 +- doc/connectivity/bluetooth/api/shell/csip.rst | 2 +- doc/connectivity/bluetooth/api/shell/mcp.rst | 3 +-- doc/connectivity/bluetooth/api/shell/tmap.rst | 2 +- doc/connectivity/bluetooth/bluetooth-tools.rst | 2 +- doc/connectivity/networking/api/lwm2m.rst | 2 +- doc/connectivity/networking/conn_mgr/main.rst | 2 +- doc/develop/getting_started/installation_linux.rst | 2 +- doc/develop/languages/c/newlib.rst | 2 +- doc/develop/west/manifest.rst | 4 ++-- doc/develop/west/release-notes.rst | 2 +- doc/develop/west/sign.rst | 2 +- doc/glossary.rst | 2 +- doc/hardware/peripherals/auxdisplay.rst | 2 +- doc/hardware/peripherals/bc12.rst | 2 +- doc/kernel/services/synchronization/events.rst | 8 ++++---- doc/services/device_mgmt/smp_groups/smp_group_1.rst | 4 ++-- doc/services/device_mgmt/smp_groups/smp_group_3.rst | 6 +++--- doc/services/sensing/index.rst | 2 +- 23 files changed, 30 insertions(+), 32 deletions(-) diff --git a/doc/build/cmake/index.rst b/doc/build/cmake/index.rst index 479e044b68e..534c3ff34e1 100644 --- a/doc/build/cmake/index.rst +++ b/doc/build/cmake/index.rst @@ -108,7 +108,7 @@ Devicetree :ref:`dt-guide`. Kconfig - :file:`Kconfig` files define available configuration options for for the + :file:`Kconfig` files define available configuration options for the target architecture, SoC, board, and application, as well as dependencies between options. diff --git a/doc/build/dts/intro-syntax-structure.rst b/doc/build/dts/intro-syntax-structure.rst index f3b7c6cebd7..1fd7eead9f8 100644 --- a/doc/build/dts/intro-syntax-structure.rst +++ b/doc/build/dts/intro-syntax-structure.rst @@ -370,7 +370,7 @@ curious about details, see the devicetree specification. Additional notes on the above: - The values in the ``phandle``, ``phandles``, and ``phandle-array`` types are - are described further in :ref:`dt-phandles` + described further in :ref:`dt-phandles` - Boolean properties are true if present. They should not have a value. A boolean property is only false if it is completely missing in the DTS. diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 041aed5fc36..57dd7828978 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -373,5 +373,4 @@ The :ref:`kconfig_tips_and_tricks` page has some tips for writing Kconfig files. The :zephyr_file:`kconfiglib.py ` docstring -docstring (at the top of the file) goes over how symbol values are calculated -in detail. +(at the top of the file) goes over how symbol values are calculated in detail. diff --git a/doc/connectivity/bluetooth/api/gatt.rst b/doc/connectivity/bluetooth/api/gatt.rst index 3cc1af64387..bb4487f57dd 100644 --- a/doc/connectivity/bluetooth/api/gatt.rst +++ b/doc/connectivity/bluetooth/api/gatt.rst @@ -56,7 +56,7 @@ respective operations. thus it is not recommended to block for long periods of time in them. Attribute value changes can be notified using :c:func:`bt_gatt_notify` API, -alternatively there is :c:func:`bt_gatt_notify_cb` where is is possible to +alternatively there is :c:func:`bt_gatt_notify_cb` where it is possible to pass a callback to be called when it is necessary to know the exact instant when the data has been transmitted over the air. Indications are supported by :c:func:`bt_gatt_indicate` API. diff --git a/doc/connectivity/bluetooth/api/shell/cap.rst b/doc/connectivity/bluetooth/api/shell/cap.rst index 74bf5bac72f..5ab57a8d320 100644 --- a/doc/connectivity/bluetooth/api/shell/cap.rst +++ b/doc/connectivity/bluetooth/api/shell/cap.rst @@ -14,7 +14,7 @@ Using the CAP Acceptor ====================== When the Bluetooth stack has been initialized (:code:`bt init`), the Acceptor can be registered by -by calling :code:`cap_acceptor init`, which will register the CAS and CSIS services, as well as +calling :code:`cap_acceptor init`, which will register the CAS and CSIS services, as well as register callbacks. .. code-block:: console diff --git a/doc/connectivity/bluetooth/api/shell/csip.rst b/doc/connectivity/bluetooth/api/shell/csip.rst index e2daf744cac..d0fddaa61f3 100644 --- a/doc/connectivity/bluetooth/api/shell/csip.rst +++ b/doc/connectivity/bluetooth/api/shell/csip.rst @@ -14,7 +14,7 @@ or a laptop. The client is able to lock and release members of a coordinated set. While the coordinated set is locked, no other clients may lock the set. To lock a set, the client must connect to each of the set members it wants to -lock. This implementation will always try to to connect to all the members of +lock. This implementation will always try to connect to all the members of the set, and at the same time. Thus if the set size is 3, then :code:`BT_MAX_CONN` shall be at least 3. diff --git a/doc/connectivity/bluetooth/api/shell/mcp.rst b/doc/connectivity/bluetooth/api/shell/mcp.rst index a48ef50685c..e0930852e10 100644 --- a/doc/connectivity/bluetooth/api/shell/mcp.rst +++ b/doc/connectivity/bluetooth/api/shell/mcp.rst @@ -27,8 +27,7 @@ Also note that this documentation does not list all shell commands, it just shows examples of some of them. The set of commands is explorable from the mcc shell and the mpl shell, by typing :code:`mcc` or :code:`mpl` and pressing TAB. A help text for each command can be -found by doing :code:`mcc help` or or :code:`mpl -help`. +found by doing :samp:`mcc {} help` or :samp:`mpl {} help`. Overview ******** diff --git a/doc/connectivity/bluetooth/api/shell/tmap.rst b/doc/connectivity/bluetooth/api/shell/tmap.rst index 416644b3069..8a562a81361 100644 --- a/doc/connectivity/bluetooth/api/shell/tmap.rst +++ b/doc/connectivity/bluetooth/api/shell/tmap.rst @@ -10,7 +10,7 @@ Using the TMAP Shell ******************** When the Bluetooth stack has been initialized (:code:`bt init`), the TMAS can be registered by -by calling :code:`tmap init`. +calling :code:`tmap init`. .. code-block:: console diff --git a/doc/connectivity/bluetooth/bluetooth-tools.rst b/doc/connectivity/bluetooth/bluetooth-tools.rst index daa8107e0f3..9da5c5feb1e 100644 --- a/doc/connectivity/bluetooth/bluetooth-tools.rst +++ b/doc/connectivity/bluetooth/bluetooth-tools.rst @@ -212,7 +212,7 @@ To connect your application to the Android Emulator follow the next steps: #. Build your Zephyr application and disable the HCI ACL flow control (i.e. ``CONFIG_BT_HCI_ACL_FLOW_CONTROL=n``) as the - the virtual controller from android does not support it at the moment. + virtual controller from android does not support it at the moment. #. Install Android Emulator version >= 33.1.4.0. The easiest way to do this is by installing the latest `Android Studio Preview`_ version. diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index b8c4756b5d6..8a36adf8860 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -478,7 +478,7 @@ Support for time series data LwM2M version 1.1 adds support for SenML CBOR and SenML JSON data formats. These data formats add support for time series data. Time series formats can be used for READ, NOTIFY and SEND operations. When data cache is enabled for a resource, each write will create a timestamped entry in a cache, -and its content is then returned as a content in in READ, NOTIFY or SEND operation for a given +and its content is then returned as a content in READ, NOTIFY or SEND operation for a given resource. Data cache is only supported for resources with a fixed data size. diff --git a/doc/connectivity/networking/conn_mgr/main.rst b/doc/connectivity/networking/conn_mgr/main.rst index 4bde856f0ce..675be831418 100644 --- a/doc/connectivity/networking/conn_mgr/main.rst +++ b/doc/connectivity/networking/conn_mgr/main.rst @@ -421,7 +421,7 @@ There are a few actions related to connectivity that are (by default at least) p By default, Connection Manager will automatically take any bound iface admin-down if it has given up on associating. - Applications can disable this for all ifaces by disabling the :kconfig:option:`CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN` Kconfig option, or for individual ifaces by setting the :c:enumerator:`~conn_mgr_if_flag.CONN_MGR_IF_NO_AUTO_DOWN` connectivity flag with with :c:func:`conn_mgr_if_set_flag`. + Applications can disable this for all ifaces by disabling the :kconfig:option:`CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN` Kconfig option, or for individual ifaces by setting the :c:enumerator:`~conn_mgr_if_flag.CONN_MGR_IF_NO_AUTO_DOWN` connectivity flag with :c:func:`conn_mgr_if_set_flag`. .. _conn_mgr_control_api: diff --git a/doc/develop/getting_started/installation_linux.rst b/doc/develop/getting_started/installation_linux.rst index d9598f4170d..f507a8d823c 100644 --- a/doc/develop/getting_started/installation_linux.rst +++ b/doc/develop/getting_started/installation_linux.rst @@ -303,7 +303,7 @@ toolchains for all Zephyr target architectures, and does not require any extra flags when building applications or running tests. In addition to cross-compilers, the Zephyr SDK also provides prebuilt host tools. It is, however, possible to build without the SDK's toolchain by using another -toolchain as as described in the :ref:`toolchains` section. +toolchain as described in the :ref:`toolchains` section. As already noted above, the SDK also includes prebuilt host tools. To use the SDK's prebuilt host tools with a toolchain from another source, you must set the diff --git a/doc/develop/languages/c/newlib.rst b/doc/develop/languages/c/newlib.rst index f79d00c01e2..a0daba2b971 100644 --- a/doc/develop/languages/c/newlib.rst +++ b/doc/develop/languages/c/newlib.rst @@ -31,7 +31,7 @@ The Newlib full variant (:file:`libc.a` and :file:`libm.a`) is the most capable variant of the Newlib available in the Zephyr SDK, and supports almost all standard C library features. It is optimized for performance (prefers performance over code size) and its footprint is significantly larger than the -the nano variant. +nano variant. This variant can be enabled by selecting the :kconfig:option:`CONFIG_NEWLIB_LIBC` and de-selecting the diff --git a/doc/develop/west/manifest.rst b/doc/develop/west/manifest.rst index ba0f9f29706..f989cdcae1e 100644 --- a/doc/develop/west/manifest.rst +++ b/doc/develop/west/manifest.rst @@ -1124,7 +1124,7 @@ recursively update the project's Git submodules whenever it updates the project itself. If it's ``false`` or missing, it has no effect. For example, let's say you have a source code repository ``foo``, which has -some submodules, and you want ``west update`` to keep all of them them in sync, +some submodules, and you want ``west update`` to keep all of them in sync, along with another project named ``bar`` in the same workspace. You can do that with this manifest file: @@ -2050,7 +2050,7 @@ The ultimate outcomes of resolving manifest imports are: in the top-level file with those defined in imported files - a set of extension commands, which are drawn from the ``west-commands`` - keys in in the top-level file and any imported files + keys in the top-level file and any imported files - a ``group-filter`` list, which is produced by combining the top-level and any imported filters diff --git a/doc/develop/west/release-notes.rst b/doc/develop/west/release-notes.rst index 49dcc0a3116..951cc4c3e37 100644 --- a/doc/develop/west/release-notes.rst +++ b/doc/develop/west/release-notes.rst @@ -669,7 +669,7 @@ The developer-visible changes to the :ref:`west-apis` are: West now requires Python 3.6 or later. Additionally, some features may rely on Python dictionaries being insertion-ordered; this is only an implementation -detail in CPython 3.6, but is is part of the language specification as of +detail in CPython 3.6, but it is part of the language specification as of Python 3.7. v0.6.3 diff --git a/doc/develop/west/sign.rst b/doc/develop/west/sign.rst index 44193d4611f..8cc55ffeea4 100644 --- a/doc/develop/west/sign.rst +++ b/doc/develop/west/sign.rst @@ -40,7 +40,7 @@ Notes on the above commands: - ``YOUR_BOARD`` should be changed to match your board - The ``CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`` value is the insecure default - provided and used by by MCUboot for development and testing + provided and used by MCUboot for development and testing - You can change the ``hello_world`` application directory to any other application that can be loaded by MCUboot, such as the :zephyr:code-sample:`smp-svr` sample. diff --git a/doc/glossary.rst b/doc/glossary.rst index eafda9410fc..8571f4b6d49 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -89,7 +89,7 @@ Glossary of Terms system power state System power states describe the power consumption of the system as a - whole. System power states are are represented by :c:enum:`pm_state`. + whole. System power states are represented by :c:enum:`pm_state`. west A multi-repo meta-tool developed for the Zephyr project. See :ref:`west`. diff --git a/doc/hardware/peripherals/auxdisplay.rst b/doc/hardware/peripherals/auxdisplay.rst index b3cb6cbae5b..913b43f2779 100644 --- a/doc/hardware/peripherals/auxdisplay.rst +++ b/doc/hardware/peripherals/auxdisplay.rst @@ -9,7 +9,7 @@ Overview Auxiliary Displays are text-based displays that have simple interfaces for displaying textual, numeric or alphanumeric data, as opposed to the :ref:`display_api`, auxiliary displays do not support custom -graphical output to displays (and and most often monochrome), the most +graphical output to displays (and most often monochrome), the most advanced custom feature supported is generation of custom characters. These inexpensive displays are commonly found with various configurations and sizes, a common display size is 16 characters by 2 lines. diff --git a/doc/hardware/peripherals/bc12.rst b/doc/hardware/peripherals/bc12.rst index 00c9bcdb677..a612a403dbb 100644 --- a/doc/hardware/peripherals/bc12.rst +++ b/doc/hardware/peripherals/bc12.rst @@ -74,7 +74,7 @@ Charging port mode is used by the application when the USB port is configured as a downstream facing port, i.e. a USB host port. For charging port mode, the BC1.2 driver powers up the detection chip and configures the charger type specified by a devicetree property. If the driver supports detection of plug and -and unplug events, the BC1.2 driver notifies the callback registered with +unplug events, the BC1.2 driver notifies the callback registered with ``bc12_set_result_cb()`` to indicate the current connection state of the portable device partner. diff --git a/doc/kernel/services/synchronization/events.rst b/doc/kernel/services/synchronization/events.rst index 7182803883a..cbb86894723 100644 --- a/doc/kernel/services/synchronization/events.rst +++ b/doc/kernel/services/synchronization/events.rst @@ -33,10 +33,10 @@ conditions of multiple threads waiting on the event object. All threads whose match conditions have been met are made active at the same time. Threads may wait on one or more events. They may either wait for all of the -the requested events, or for any of them. Furthermore, threads making a wait -request have the option of resetting the current set of events tracked by the -event object prior to waiting. Care must be taken with this option when -multiple threads wait on the same event object. +requested events, or for any of them. Furthermore, threads making a wait request +have the option of resetting the current set of events tracked by the event +object prior to waiting. Care must be taken with this option when multiple +threads wait on the same event object. .. note:: The kernel does allow an ISR to query an event object, however the ISR must diff --git a/doc/services/device_mgmt/smp_groups/smp_group_1.rst b/doc/services/device_mgmt/smp_groups/smp_group_1.rst index 819d8330149..2a1d1f27086 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_1.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_1.rst @@ -3,7 +3,7 @@ Application/software image management group ########################################### -Application/software image management management group defines following commands: +Application/software image management group defines following commands: .. table:: :align: center @@ -75,7 +75,7 @@ Get state of images request header fields: | ``0`` | ``1`` | ``0`` | +--------+--------------+----------------+ -The command sends sends empty CBOR map as data. +The command sends an empty CBOR map as data. .. _mcumgr_smp_protocol_op_1_grp_1_cmd_0: diff --git a/doc/services/device_mgmt/smp_groups/smp_group_3.rst b/doc/services/device_mgmt/smp_groups/smp_group_3.rst index a6f1ee73b7a..c70897809e1 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_3.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_3.rst @@ -333,7 +333,7 @@ Commit settings request header fields: | ``2`` | ``3`` | ``2`` | +--------+--------------+----------------+ -The command sends sends empty CBOR map as data. +The command sends an empty CBOR map as data. Commit settings response ======================== @@ -409,7 +409,7 @@ Load settings request header fields: | ``0`` | ``3`` | ``3`` | +--------+--------------+----------------+ -The command sends sends empty CBOR map as data. +The command sends an empty CBOR map as data. Load settings response ====================== @@ -479,7 +479,7 @@ Save settings request header fields: | ``2`` | ``3`` | ``3`` | +--------+--------------+----------------+ -The command sends sends empty CBOR map as data. +The command sends an empty CBOR map as data. Save settings response ====================== diff --git a/doc/services/sensing/index.rst b/doc/services/sensing/index.rst index 99fdc48d6b7..d0ae0bea5ee 100644 --- a/doc/services/sensing/index.rst +++ b/doc/services/sensing/index.rst @@ -197,7 +197,7 @@ Sensor Sample Value The ``header`` defines a **base_timestamp**, and each element in the **readings[]** array defines **timestamp_delta**. - The **timestamp_delta** is is in relation to the previous **readings** (or the **base_timestamp**) + The **timestamp_delta** is in relation to the previous **readings** (or the **base_timestamp**) For example: From 483dd8a40a143215c03b634eb3bb87e7265c933d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 14 Nov 2023 14:03:04 -0800 Subject: [PATCH 3701/4498] doc: doxygen: move mpsc and spsc under data structure API group Both MPSC and SPSC should be under data structure API group instead of kernel API group. So move them, and fix some doxygen cosmetic grouping issues for SPSC. Signed-off-by: Daniel Leung --- include/zephyr/sys/mpsc_pbuf.h | 2 +- include/zephyr/sys/spsc_pbuf.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/zephyr/sys/mpsc_pbuf.h b/include/zephyr/sys/mpsc_pbuf.h index a80cc2db464..72f6e99515b 100644 --- a/include/zephyr/sys/mpsc_pbuf.h +++ b/include/zephyr/sys/mpsc_pbuf.h @@ -19,7 +19,7 @@ extern "C" { /** * @brief Multi producer, single consumer packet buffer API * @defgroup mpsc_buf MPSC (Multi producer, single consumer) packet buffer API - * @ingroup kernel_apis + * @ingroup datastructure_apis * @{ */ diff --git a/include/zephyr/sys/spsc_pbuf.h b/include/zephyr/sys/spsc_pbuf.h index 682d610e34b..0e7f018fa63 100644 --- a/include/zephyr/sys/spsc_pbuf.h +++ b/include/zephyr/sys/spsc_pbuf.h @@ -16,11 +16,12 @@ extern "C" { /** * @brief Single producer, single consumer packet buffer API - * @ingroup kernel_apis + * @defgroup spsc_buf SPSC (Single producer, single consumer) packet buffer API + * @ingroup datastructure_apis * @{ */ -/**@defgroup SPSC_PBUF_FLAGS MPSC packet buffer flags +/**@defgroup SPSC_PBUF_FLAGS SPSC packet buffer flags * @{ */ From 76b0aab6cc263701cc42652f25d0fb78092f958e Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Tue, 14 Nov 2023 19:20:32 -0800 Subject: [PATCH 3702/4498] soc: arm: npcx: fix clock reference of APB4/FIU1 buses This CL fixes the clock reference of APB4/FIU1 buses by introducing new Kconfig options. Signed-off-by: Mulin Chao --- drivers/clock_control/Kconfig.npcx | 12 ++++++++++++ soc/arm/nuvoton_npcx/common/soc_clock.h | 16 ++++++++++++++++ soc/arm/nuvoton_npcx/npcx4/soc.h | 12 ------------ soc/arm/nuvoton_npcx/npcx9/soc.h | 6 ------ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/clock_control/Kconfig.npcx b/drivers/clock_control/Kconfig.npcx index b4b91d5f8d3..76e5acf985a 100644 --- a/drivers/clock_control/Kconfig.npcx +++ b/drivers/clock_control/Kconfig.npcx @@ -18,3 +18,15 @@ config CLOCK_CONTROL_NPCX_EXTERNAL_SRC is generated by the on-chip Crystal Oscillator (XTOSC). This includes an on-chip oscillator, to which an external crystal and the related passive components are connected. + +config CLOCK_CONTROL_NPCX_SUPP_APB4 + bool "Indicates that the clock controller supports APB4 bus" + default y if !SOC_SERIES_NPCX7 + help + Selected if NPCX series supports APB4 bus. + +config CLOCK_CONTROL_NPCX_SUPP_FIU1 + bool "Indicates that the clock controller supports FIU1 bus" + default y if SOC_SERIES_NPCX4 + help + Selected if NPCX series supports FIU1 bus. diff --git a/soc/arm/nuvoton_npcx/common/soc_clock.h b/soc/arm/nuvoton_npcx/common/soc_clock.h index 6b302f2e885..d43a70d4529 100644 --- a/soc/arm/nuvoton_npcx/common/soc_clock.h +++ b/soc/arm/nuvoton_npcx/common/soc_clock.h @@ -42,6 +42,14 @@ struct npcx_clk_cfg { #define APB2DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb2_prescaler) - 1) /* APB3 clock divider */ #define APB3DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb3_prescaler) - 1) +/* APB4 clock divider if supported */ +#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) +#if defined(CONFIG_CLOCK_CONTROL_NPCX_SUPP_APB4) /* Supported in NPCX9 and later series */ +#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) +#else +#error "APB4 clock divider is not supported but defined in pcc node!" +#endif /* CONFIG_CLOCK_CONTROL_NPCX_SUPP_APB4 */ +#endif /* Construct a uint8_t array from 'pwdwn-ctl-val' prop for PWDWN_CTL initialization. */ #define NPCX_PWDWN_CTL_ITEMS_INIT(node, prop, idx) DT_PROP_BY_IDX(node, prop, idx), @@ -89,6 +97,14 @@ struct npcx_clk_cfg { #define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */ #endif +#if defined(CONFIG_CLOCK_CONTROL_NPCX_SUPP_FIU1) +#if (CORE_CLK > (MAX_OFMCLK / 2)) +#define FIU1DIV_VAL 1 /* FIU1_CLK = CORE_CLK/2 */ +#else +#define FIU1DIV_VAL 0 /* FIU1_CLK = CORE_CLK */ +#endif +#endif /* CONFIG_CLOCK_CONTROL_NPCX_SUPP_FIU1 */ + /* Get APB clock freq */ #define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1)) diff --git a/soc/arm/nuvoton_npcx/npcx4/soc.h b/soc/arm/nuvoton_npcx/npcx4/soc.h index 5c3f7cf5927..a9d4e88424b 100644 --- a/soc/arm/nuvoton_npcx/npcx4/soc.h +++ b/soc/arm/nuvoton_npcx/npcx4/soc.h @@ -58,16 +58,4 @@ #include #include -/* NPCX4 Clock definitions */ -#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) -/* APB4 clock divider if supported */ -#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) -#endif - -#if (CORE_CLK > (MAX_OFMCLK / 2)) -#define FIU1DIV_VAL 1 /* If CORE_CLK > MAX_OFMCLK / 2, FIU1_CLK = CORE_CLK/2 */ -#else -#define FIU1DIV_VAL 0 /* Else, FIU1_CLK = CORE_CLK */ -#endif - #endif /* _NUVOTON_NPCX_SOC_H_ */ diff --git a/soc/arm/nuvoton_npcx/npcx9/soc.h b/soc/arm/nuvoton_npcx/npcx9/soc.h index 0e9e23cda36..6b6c3f30a44 100644 --- a/soc/arm/nuvoton_npcx/npcx9/soc.h +++ b/soc/arm/nuvoton_npcx/npcx9/soc.h @@ -56,10 +56,4 @@ #include #include -/* NPCX9 Clock definitions */ -#if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) -/* APB4 clock divider if supported */ -#define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) -#endif - #endif /* _NUVOTON_NPCX_SOC_H_ */ From d17b1c8cbbcbebb0fc3b90472924a8a99d595e6a Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Wed, 15 Nov 2023 18:19:16 +0100 Subject: [PATCH 3703/4498] tests: build_all: sensor: fix i2c.dtsi typo Fix lps22df i2c address in order to be unique. Signed-off-by: Armando Visconti --- tests/drivers/build_all/sensor/i2c.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 42beeab095e..ebafddab96c 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -801,9 +801,9 @@ test_i2c_tsl2561: tsl2561@78 { reg = <0x78>; }; -test_i2c_lps22df: lps22df@78 { +test_i2c_lps22df: lps22df@79 { compatible = "st,lps22df"; - reg = <0x78>; + reg = <0x79>; drdy-gpios = <&test_gpio 0 0>; status = "okay"; }; From 5a4e0af54a20c9c1ec1059206e79086790dd1f17 Mon Sep 17 00:00:00 2001 From: Vilem Gottwald Date: Tue, 3 Oct 2023 14:01:07 +0200 Subject: [PATCH 3704/4498] samples: synchronization: fix comments & structure This commit has no functional changes. It makes the comments up to date with the code and changes the code structure to ensure consistency. These inconsistencies were introduced when the static thread definition was replaced with dynamic, but the comments remained unchanged. - Fixed outdated comments about the static approach that were not corresponding to the code. - Rearrange thread definitions, to obtain similar code structure for both threads. Signed-off-by: Vilem Gottwald --- samples/synchronization/src/main.c | 36 +++++++++++++----------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/samples/synchronization/src/main.c b/samples/synchronization/src/main.c index 027abd1ed96..cf535773741 100644 --- a/samples/synchronization/src/main.c +++ b/samples/synchronization/src/main.c @@ -1,4 +1,4 @@ -/* main.c - Hello World demo */ +/* main.c - Synchronization demo */ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. @@ -10,10 +10,10 @@ #include /* - * The hello world demo has two threads that utilize semaphores and sleeping + * The synchronization demo has two threads that utilize semaphores and sleeping * to take turns printing a greeting message at a controlled rate. The demo - * shows both the static and dynamic approaches for spawning a thread; a real - * world application would likely use the static approach for both threads. + * shows only the dynamic approach for spawning a thread. Alternatively, + * a thread can be declared at compile time by calling K_THREAD_DEFINE. */ #define PIN_THREADS (IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_SCHED_CPU_MASK)) @@ -34,7 +34,7 @@ * @param other_sem other thread's semaphore */ void helloLoop(const char *my_name, - struct k_sem *my_sem, struct k_sem *other_sem) + struct k_sem *my_sem, struct k_sem *other_sem) { const char *tname; uint8_t cpu; @@ -68,41 +68,37 @@ void helloLoop(const char *my_name, } /* define semaphores */ - K_SEM_DEFINE(threadA_sem, 1, 1); /* starts off "available" */ K_SEM_DEFINE(threadB_sem, 0, 1); /* starts off "not available" */ - -/* threadB is a dynamic thread that is spawned by threadA */ - -void threadB(void *dummy1, void *dummy2, void *dummy3) +/* threadA is a dynamic thread that is spawned in main */ +void threadA(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); - /* invoke routine to ping-pong hello messages with threadA */ - helloLoop(__func__, &threadB_sem, &threadA_sem); + /* invoke routine to ping-pong hello messages with threadB */ + helloLoop(__func__, &threadA_sem, &threadB_sem); } -K_THREAD_STACK_DEFINE(threadA_stack_area, STACKSIZE); -static struct k_thread threadA_data; - K_THREAD_STACK_DEFINE(threadB_stack_area, STACKSIZE); static struct k_thread threadB_data; -/* threadA is a static thread that is spawned automatically */ - -void threadA(void *dummy1, void *dummy2, void *dummy3) +/* threadB is a dynamic thread that is spawned in main */ +void threadB(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); - /* invoke routine to ping-pong hello messages with threadB */ - helloLoop(__func__, &threadA_sem, &threadB_sem); + /* invoke routine to ping-pong hello messages with threadA */ + helloLoop(__func__, &threadB_sem, &threadA_sem); } +K_THREAD_STACK_DEFINE(threadA_stack_area, STACKSIZE); +static struct k_thread threadA_data; + int main(void) { k_thread_create(&threadA_data, threadA_stack_area, From 1c7eb9ee729cce326f724b373dfb06745bd1a214 Mon Sep 17 00:00:00 2001 From: Vilem Gottwald Date: Tue, 3 Oct 2023 14:01:30 +0200 Subject: [PATCH 3705/4498] samples: synchronization: add static thread Replace one of the dynamic threads with a static thread to show the all the possible ways of creating threads. Signed-off-by: Vilem Gottwald --- samples/synchronization/src/main.c | 62 +++++++++++++----------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/samples/synchronization/src/main.c b/samples/synchronization/src/main.c index cf535773741..e72eea92f92 100644 --- a/samples/synchronization/src/main.c +++ b/samples/synchronization/src/main.c @@ -12,8 +12,8 @@ /* * The synchronization demo has two threads that utilize semaphores and sleeping * to take turns printing a greeting message at a controlled rate. The demo - * shows only the dynamic approach for spawning a thread. Alternatively, - * a thread can be declared at compile time by calling K_THREAD_DEFINE. + * shows both the static and dynamic approaches for spawning a thread; a real + * world application would likely use the static approach for both threads. */ #define PIN_THREADS (IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_SCHED_CPU_MASK)) @@ -33,7 +33,7 @@ * @param my_sem thread's own semaphore * @param other_sem other thread's semaphore */ -void helloLoop(const char *my_name, +void hello_loop(const char *my_name, struct k_sem *my_sem, struct k_sem *other_sem) { const char *tname; @@ -68,62 +68,52 @@ void helloLoop(const char *my_name, } /* define semaphores */ -K_SEM_DEFINE(threadA_sem, 1, 1); /* starts off "available" */ -K_SEM_DEFINE(threadB_sem, 0, 1); /* starts off "not available" */ +K_SEM_DEFINE(thread_a_sem, 1, 1); /* starts off "available" */ +K_SEM_DEFINE(thread_b_sem, 0, 1); /* starts off "not available" */ -/* threadA is a dynamic thread that is spawned in main */ -void threadA(void *dummy1, void *dummy2, void *dummy3) +/* thread_a is a dynamic thread that is spawned in main */ +void thread_a_entry_point(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); - /* invoke routine to ping-pong hello messages with threadB */ - helloLoop(__func__, &threadA_sem, &threadB_sem); + /* invoke routine to ping-pong hello messages with thread_b */ + hello_loop(__func__, &thread_a_sem, &thread_b_sem); } +K_THREAD_STACK_DEFINE(thread_a_stack_area, STACKSIZE); +static struct k_thread thread_a_data; -K_THREAD_STACK_DEFINE(threadB_stack_area, STACKSIZE); -static struct k_thread threadB_data; - -/* threadB is a dynamic thread that is spawned in main */ -void threadB(void *dummy1, void *dummy2, void *dummy3) +/* thread_b is a static thread spawned immediately */ +void thread_b_entry_point(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); - /* invoke routine to ping-pong hello messages with threadA */ - helloLoop(__func__, &threadB_sem, &threadA_sem); + /* invoke routine to ping-pong hello messages with thread_a */ + hello_loop(__func__, &thread_b_sem, &thread_a_sem); } - -K_THREAD_STACK_DEFINE(threadA_stack_area, STACKSIZE); -static struct k_thread threadA_data; +K_THREAD_DEFINE(thread_b, STACKSIZE, + thread_b_entry_point, NULL, NULL, NULL, + PRIORITY, 0, 0); +extern const k_tid_t thread_b; int main(void) { - k_thread_create(&threadA_data, threadA_stack_area, - K_THREAD_STACK_SIZEOF(threadA_stack_area), - threadA, NULL, NULL, NULL, + k_thread_create(&thread_a_data, thread_a_stack_area, + K_THREAD_STACK_SIZEOF(thread_a_stack_area), + thread_a_entry_point, NULL, NULL, NULL, PRIORITY, 0, K_FOREVER); - k_thread_name_set(&threadA_data, "thread_a"); -#if PIN_THREADS - if (arch_num_cpus() > 1) { - k_thread_cpu_pin(&threadA_data, 0); - } -#endif + k_thread_name_set(&thread_a_data, "thread_a"); - k_thread_create(&threadB_data, threadB_stack_area, - K_THREAD_STACK_SIZEOF(threadB_stack_area), - threadB, NULL, NULL, NULL, - PRIORITY, 0, K_FOREVER); - k_thread_name_set(&threadB_data, "thread_b"); #if PIN_THREADS if (arch_num_cpus() > 1) { - k_thread_cpu_pin(&threadB_data, 1); + k_thread_cpu_pin(&thread_a_data, 0); + k_thread_cpu_pin(thread_b, 1); } #endif - k_thread_start(&threadA_data); - k_thread_start(&threadB_data); + k_thread_start(&thread_a_data); return 0; } From eceb27c6c819b3467b1178e8bf505d03433f1832 Mon Sep 17 00:00:00 2001 From: Gabriel Freitas Date: Mon, 30 Oct 2023 11:34:09 -0300 Subject: [PATCH 3706/4498] dts: add support for uart1 usage on imx8ml_m7 devicetree include file Add support for UART1 usage by adding uart1 node and configuration to the i.MX 8ML devicetree include. Signed-off-by: Gabriel Freitas --- dts/arm/nxp/nxp_imx8ml_m7.dtsi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dts/arm/nxp/nxp_imx8ml_m7.dtsi b/dts/arm/nxp/nxp_imx8ml_m7.dtsi index 4afe8e138a6..41f22deb991 100644 --- a/dts/arm/nxp/nxp_imx8ml_m7.dtsi +++ b/dts/arm/nxp/nxp_imx8ml_m7.dtsi @@ -155,10 +155,6 @@ status = "disabled"; }; - /* - * For now only UART4 is supported and - * tested with the serial driver - */ uart4: uart@30a60000 { compatible = "nxp,imx-iuart"; reg = <0x30a60000 0x10000>; @@ -167,6 +163,14 @@ status = "disabled"; }; + uart1: uart@30860000 { + compatible = "nxp,imx-iuart"; + reg = <0x30860000 0x10000>; + interrupts = <26 3>; + clocks = <&ccm IMX_CCM_UART1_CLK 0x7c 24>; + status = "disabled"; + }; + mailbox0: mailbox@30ab0000 { compatible = "nxp,imx-mu"; reg = <0x30ab0000 DT_SIZE_K(64)>; From eaec581fb9fa4d88971009a9c8e310354e581ba3 Mon Sep 17 00:00:00 2001 From: Gabriel Freitas Date: Mon, 21 Aug 2023 13:44:22 -0300 Subject: [PATCH 3707/4498] boards: arm: add toradex verdin imx8m plus board Add Verdin iMX8M Plus board with i.MX8MP SoC and ARM Cortex-M7 processor. Add two targets (DDR and ITCM) for the iMX8M Plus board. Port and documentation are based on NXP MIMX8MM EVK board. This code is intented to be used with the Cortex-M7. Signed-off-by: Gabriel Freitas --- boards/arm/verdin_imx8mp_m7/Kconfig.board | 9 + boards/arm/verdin_imx8mp_m7/Kconfig.defconfig | 18 ++ boards/arm/verdin_imx8mp_m7/board.cmake | 11 + boards/arm/verdin_imx8mp_m7/doc/index.rst | 290 ++++++++++++++++++ .../doc/verdin_imx8mp_front.jpg | Bin 0 -> 101622 bytes .../verdin_imx8mp_m7-pinctrl.dtsi | 28 ++ .../verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.dts | 46 +++ .../verdin_imx8mp_m7_ddr.yaml | 18 ++ .../verdin_imx8mp_m7_ddr_defconfig | 16 + .../verdin_imx8mp_m7_itcm.dts | 46 +++ .../verdin_imx8mp_m7_itcm.yaml | 18 ++ .../verdin_imx8mp_m7_itcm_defconfig | 16 + dts/arm/nxp/nxp_imx8ml_m7.dtsi | 12 +- 13 files changed, 522 insertions(+), 6 deletions(-) create mode 100644 boards/arm/verdin_imx8mp_m7/Kconfig.board create mode 100644 boards/arm/verdin_imx8mp_m7/Kconfig.defconfig create mode 100644 boards/arm/verdin_imx8mp_m7/board.cmake create mode 100644 boards/arm/verdin_imx8mp_m7/doc/index.rst create mode 100644 boards/arm/verdin_imx8mp_m7/doc/verdin_imx8mp_front.jpg create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7-pinctrl.dtsi create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.dts create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.yaml create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.dts create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.yaml create mode 100644 boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig diff --git a/boards/arm/verdin_imx8mp_m7/Kconfig.board b/boards/arm/verdin_imx8mp_m7/Kconfig.board new file mode 100644 index 00000000000..fb86601179c --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/Kconfig.board @@ -0,0 +1,9 @@ +# VERDIN_IMX8MP_M7 board + +# Copyright (c) 2023 Toradex +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_VERDIN_IMX8MP_M7 + bool "Toradex iMX8M Plus M7" + depends on SOC_SERIES_IMX8ML_M7 + select SOC_PART_NUMBER_MIMX8ML8DVNLZ diff --git a/boards/arm/verdin_imx8mp_m7/Kconfig.defconfig b/boards/arm/verdin_imx8mp_m7/Kconfig.defconfig new file mode 100644 index 00000000000..3c3ab2db770 --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/Kconfig.defconfig @@ -0,0 +1,18 @@ +# VERDIN_IMX8MP_M7 board defconfig + +# Copyright (c) 2023 Toradex +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_VERDIN_IMX8MP_M7 + +config BOARD + default "verdin_imx8mp_m7" + +if !XIP +config FLASH_SIZE + default 0 +config FLASH_BASE_ADDRESS + default 0 +endif + +endif # BOARD_VERDIN_IMX8MP_M7 diff --git a/boards/arm/verdin_imx8mp_m7/board.cmake b/boards/arm/verdin_imx8mp_m7/board.cmake new file mode 100644 index 00000000000..546ba82f8a9 --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023, Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_set_debugger_ifnset(jlink) +board_set_flasher_ifnset(jlink) + +board_runner_args(jlink "--device=MIMX8ML8_M7") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/verdin_imx8mp_m7/doc/index.rst b/boards/arm/verdin_imx8mp_m7/doc/index.rst new file mode 100644 index 00000000000..6a35534a99f --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/doc/index.rst @@ -0,0 +1,290 @@ +.. _verdin_imx8mp_m7: + +Toradex Verdin iMX8M Plus SoM + +############################################ + +Overview +******** + +The Verdin iMX8M Plus is a Computer on Module (CoM) developed by Toradex. It is based on the NXP® i.MX 8M Plus family of +processors (or System on Chips - SoCs). + +The Verdin iMX8M Plus family consists of: + ++-------------------------------------------------+-----------------------+ +| CoM | SoC | ++=================================================+=======================+ +| Verdin iMX8M Plus Quad 8GB Wi-Fi / Bluetooth IT | i.MX 8M Plus Quad | ++-------------------------------------------------+-----------------------+ +| Verdin iMX8M Plus Quad 4GB Wi-Fi / Bluetooth IT | i.MX 8M Plus Quad | ++-------------------------------------------------+-----------------------+ +| Verdin iMX8M Plus Quad 4GB IT | i.MX 8M Plus Quad | ++-------------------------------------------------+-----------------------+ +| Verdin iMX8M Plus Quad 2GB Wi-Fi / Bluetooth IT | i.MX 8M Plus Quad | ++-------------------------------------------------+-----------------------+ +| Verdin iMX8M Plus QuadLite 1GB IT | i.MX 8M Plus QuadLite | ++-------------------------------------------------+-----------------------+ + +Quoting NXP + +:: + + The i.MX 8M Plus family focuses on machine learning and vision, advanced multimedia, and industrial automation with high reliability. + It is built to meet the needs of Smart Home, Building, City and Industry 4.0 applications. + +The Verdin iMX8M Plus integrates a total of 4 Arm Cortex™-A53 CPUs, operating at 1.6 GHz, alongside a single Arm Cortex™-M7F microcontroller operating at 800 MHz. + +.. image:: verdin_imx8mp_front.jpg + :align: center + :alt: Toradex Verdin iMX8M Plus (Credit: Toradex) + +Regarding the Cortex-A53 cluster, it employs the ARMv8-A architecture as a mid-range and energy-efficient processor. With four cores in this cluster, each core is +equipped with its own L1 memory system. Moreover, the cluster incorporates a unified L2 cache that offers supplementary functions. This cache is housed within a single APR region. +Facilitating debugging processes, the cores support both real-time trace through the ETM system and static debugging via JTAG. Furthermore, the platform features support for real-time trace +capabilities, achieved through ARM's CoreSight ETM modules, and also enables cross-triggering by utilizing CTI and CTM modules. + +The Arm® Cortex®-M7 microcontroller is indicated for Real-time control, combining high-performance with a minimal interrupt latency. +It stands out for its compatibility with existing Cortex-M profile processors. The microcontroller employs an efficient in-order super-scalar pipeline, +allowing dual-issued instructions such as load/load and load/store pairs, thanks to its multiple memory interfaces. These interfaces encompass Tightly-Coupled Memory (TCM), Harvard caches, and an AXI master interface. +The Arm Cortex-M7 Platform boasts features like a 32 KB L1 Instruction Cache, 32 KB L1 Data Cache, Floating Point Unit (FPU) with FPv5 architecture support, and an Internal Trace (TRC) mechanism. +Furthermore, the chip supports 160 IRQs, and integrates crucial Arm CoreSight components including ETM and CTI, dedicated to facilitating debug and trace functions. + +Hardware +******** + +- SoC name: NXP® i.MX 8M Plus +- CPU Type: 4x Arm Cortex™-A53 (1.6 GHz) +- Microcontroller: 1x Arm Cortex™-M7F (800 MHz) + +- Memory: + + - RAM -> A53: 1GB, 2GB, 4GB or 8GB + - RAM -> M7: 3x32KB (TCML, TCMU, OCRAM_S), 1x128KB (OCRAM) and 1x256MB (DDR) + - Flash -> A53: Up to 32GB eMMC + +- Connectivity: + + - USB 3.1: 1x Host / 1x OTG (Gen 1) + - USB 2.0: 1x Host / 1x OTG + - Ethernet Gigabit with TSN (+2nd RGMII) + - Wi-Fi Dual-band 802.11ac 2x2 MU-MIMO + - Bluetooth 5 + - 5x I2C + - 3x SPI + - 1 QSPI + - 4x UART + - Up to 92 GPIO + - 4x Analog Input + - 2x CAN (FlexCAN) + +- Multimedia: + + - Neural Processing Unit (NPU) + - Image Signal Processor (ISP) + - 2D and 3D acceleration + - HDMI, MIPI-DSI and MIPI-CSI interface + +For more information about the Verdin iMX8M Plus and the i.MX 8M Plus SoC refer to these links: + +- `i.MX 8M Plus Applications Processor page`_ +- `Verdin iMX8M Plus homepage`_ +- `Verdin iMX8M Plus developer page`_ +- `Verdin Development Board developer page`_ +- `Verdin iMX8M Plus Datasheet`_ +- `Verdin Development Board Datasheet`_ + +Supported Features +================== + +The Zephyr verdin_imx8mp_m7 board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | GPIO output | +| | | GPIO input | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + +- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig`, if you choose to use the ITCM memory. + +- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig`, if you choose to use the DDR memory. + +It is recommended to disable peripherals used by the M7 core on the Linux host. + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +UART: + +Zephyr is configured to use the UART4 by default, which is connected to the FTDI +USB converter on most Toradex carrier boards. + +This is also the UART connected to WiFi/BT chip in modules that have the WiFi/BT +chip. Therefore, if UART4 is used, WiFI/BT will not work properly. + +If the WiFi/BT is needed, then another UART should be used for Zephyr (UART1 for +example). You can change the UART by changing the ``zephyr,console`` and +``zephyr,shell-uart`` in the :zephyr_file:`boards/arm/verdin_imx8mp_m7_itcm.dts` or :zephyr_file:`boards/arm/verdin_imx8mp_m7_ddr.dts` file. + ++---------------+-----------------+---------------------------+ +| Board Name | SoC Name | Usage | ++===============+=================+===========================+ +| UART_1 | UART1 | General purpose UART | ++---------------+-----------------+---------------------------+ +| UART_4 | UART4 | Cortex-M4 debug UART | ++---------------+-----------------+---------------------------+ + +GPIO: + +All the GPIO banks available are enabled in the :zephyr_file:`dts/arm/nxp/nxp_imx8ml_m7.dtsi`. + +System Clock +============ + +The M7 Core is configured to run at a 800 MHz clock speed. + +Serial Port +=========== + +The i.MX8M Plus SoC has four UARTs. UART_4 is configured for the console and +the remaining are not used/tested. + +Programming and Debugging +************************* + +The Verdin iMX8M Plus board doesn't have QSPI flash for the M7, and it needs +to be started by the A53 core. The A53 core is responsible to load the M7 binary +application into the RAM, put the M7 in reset, set the M7 Program Counter and +Stack Pointer, and get the M7 out of reset. The A53 can perform these steps at +bootloader level or after the Linux system has booted. + +The M7 can use up to 3 different RAMs (currently, only two configurations are +supported: ITCM and DDR). These are the memory mapping for A53 and M7: + ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| Region | Cortex-A53 | Cortex-M7 (System Bus) | Cortex-M7 (Code Bus) | Size | ++============+=========================+========================+=======================+======================+ +| OCRAM | 0x00900000-0x0098FFFF | 0x20200000-0x2028FFFF | 0x00900000-0x0098FFFF | 576KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| DTCM | 0x00800000-0x0081FFFF | 0x20000000-0x2001FFFF | | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| ITCM | 0x007E0000-0x007FFFFF | | 0x00000000-0x0001FFFF | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| OCRAM_S | 0x00180000-0x00188FFF | 0x20180000-0x20188FFF | 0x00180000-0x00188FFF | 36KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| DDR | 0x80000000-0x803FFFFF | 0x80200000-0x803FFFFF | 0x80000000-0x801FFFFF | 2MB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ + +For more information about memory mapping see the +`i.MX 8M Plus Applications Processor Reference Manual`_ (section 2.1 to 2.3) + +At compilation time you have to choose which RAM will be used. To facilitate this process, there are two targets available: + +- verdin_imx8mp_m7_itcm, which uses the ITCM configuration. +- verdin_imx8mp_m7_ddr, which uses the DDR configuration. + + +Starting the Cortex-M7 via U-Boot +================================= + +Load and run Zephyr on M7 from A53 using u-boot by copying the compiled +``zephyr.bin`` to the first FAT partition of the SD card and plug the SD +card into the board. Power it up and stop the u-boot execution at prompt. + +Load the M7 binary onto the desired memory and start its execution using: + +ITCM +=== + +Loading the binary from an EXT4 partition: + +.. code-block:: console + + ext4load mmc 2:2 ${loadaddr} //zephyr.bin + cp.b ${loadaddr} 0x7e0000 + bootaux 0x7e0000 + +DDR +=== + +Loading the binary from an EXT4 partition: + +.. code-block:: console + + ext4load mmc 2:2 ${loadaddr} //zephyr.bin + cp.b ${loadaddr} 0x80000000 + bootaux 0x80000000 + +Debugging +========= + +Toradex Verdin iMX8M Plus SoM can be debugged by connecting an external JLink JTAG debugger to the X56 debug connector and to the PC, or simply connecting a USB-C to X66 on the Verdin Development Board. +Then, the application can be debugged using the usual way. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: verdin_imx8mp_m7 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.4.0-2300-g03905f7e55d2 *** + Hello World! verdin_imx8mp_m7 + +References +========== + +- `How to Load Compiled Binaries into Cortex-M`_ +- `Cortex-M JTAG Debugging`_ +- `NXP website`_ + +.. _NXP website: + https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-plus-applications-processor:8MPLUSLPD4-EVK + +.. _i.MX 8M Plus Applications Processor Reference Manual: + https://www.nxp.com/webapp/Download?colCode=IMX8MPRM + +.. _How to Load Compiled Binaries into Cortex-M: + https://developer.toradex.com/software/real-time/cortex-m/how-to-load-binaries + +.. _Cortex-M JTAG Debugging: + https://developer.toradex.com/software/real-time/cortex-m/cortexm-jtag-debugging/ + +.. _i.MX 8M Plus Applications Processor page: + https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8m-plus-arm-cortex-a53-machine-learning-vision-multimedia-and-industrial-iot:IMX8MPLUS + +.. _Verdin iMX8M Plus homepage: + https://www.toradex.com/computer-on-modules/verdin-arm-family/nxp-imx-8m-plus + +.. _Verdin iMX8M Plus developer page: + https://developer.toradex.com/hardware/verdin-som-family/modules/verdin-imx8m-plus + +.. _Verdin Development Board developer page: + https://developer.toradex.com/hardware/verdin-som-family/carrier-boards/verdin-development-board/ + +.. _Verdin iMX8M Plus Datasheet: + https://docs.toradex.com/110977-verdin_imx8m_plus_v1.1_datasheet.pdf + +.. _Verdin Development Board Datasheet: + https://docs.toradex.com/109463-verdin_development_board_datasheet_v1.1.pdf diff --git a/boards/arm/verdin_imx8mp_m7/doc/verdin_imx8mp_front.jpg b/boards/arm/verdin_imx8mp_m7/doc/verdin_imx8mp_front.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5089eace4b0e24e8ce74d154edfd7fc855928ff GIT binary patch literal 101622 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 z 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 + +&pinctrl { + uart1_default: uart1_default { + group0 { + drive-strength = "x1"; + pinmux = <&iomuxc_uart1_rxd_uart_rx_uart1_rx>, + <&iomuxc_uart1_txd_uart_tx_uart1_tx>; + slew-rate = "slow"; + }; + }; + + uart4_default: uart4_default { + group0 { + bias-pull-up; + drive-strength = "x1"; + pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, + <&iomuxc_uart4_txd_uart_tx_uart4_tx>; + slew-rate = "slow"; + }; + }; +}; diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.dts b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.dts new file mode 100644 index 00000000000..861077246fd --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.dts @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Toradex + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "verdin_imx8mp_m7-pinctrl.dtsi" +#include + +/ { + model = "Toradex Verdin iMX8M Plus M7"; + compatible = "nxp,mimx8mp_evk"; + + chosen { + /* DDR */ + zephyr,flash = &ddr_code; + zephyr,sram = &ddr_sys; + + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; +}; + +&gpio3 { + status = "okay"; +}; + +&mailbox0 { + status = "okay"; +}; + +&uart1 { + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + +&uart4 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart4_default>; + pinctrl-names = "default"; +}; diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.yaml b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.yaml new file mode 100644 index 00000000000..fc64d8c3db8 --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr.yaml @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: verdin_imx8mp_m7_ddr +name: Toradex Verdin iMX8M Plus (DDR) +type: mcu +arch: arm +ram: 2048 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - uart diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig new file mode 100644 index 00000000000..7c0d4073679 --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_IMX8ML_M7=y +CONFIG_SOC_MIMX8ML8=y +CONFIG_BOARD_VERDIN_IMX8MP_M7=y +CONFIG_CLOCK_CONTROL=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_XIP=y +CONFIG_CODE_DDR=y +CONFIG_PINCTRL=y diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.dts b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.dts new file mode 100644 index 00000000000..5744928f8a7 --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.dts @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Toradex + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "verdin_imx8mp_m7-pinctrl.dtsi" +#include + +/ { + model = "Toradex Verdin iMX8M Plus M7"; + compatible = "nxp,mimx8mp_evk"; + + chosen { + /* TCM */ + zephyr,flash = &itcm; + zephyr,sram = &dtcm; + + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; +}; + +&gpio3 { + status = "okay"; +}; + +&mailbox0 { + status = "okay"; +}; + +&uart1 { + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + +&uart4 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart4_default>; + pinctrl-names = "default"; +}; diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.yaml b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.yaml new file mode 100644 index 00000000000..8db4c170c5d --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm.yaml @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: verdin_imx8mp_m7_itcm +name: Toradex Verdin iMX8M Plus (ITCM) +type: mcu +arch: arm +ram: 128 +flash: 128 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - uart diff --git a/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig new file mode 100644 index 00000000000..52c354abc1f --- /dev/null +++ b/boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_IMX8ML_M7=y +CONFIG_SOC_MIMX8ML8=y +CONFIG_BOARD_VERDIN_IMX8MP_M7=y +CONFIG_CLOCK_CONTROL=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_XIP=y +CONFIG_CODE_ITCM=y +CONFIG_PINCTRL=y diff --git a/dts/arm/nxp/nxp_imx8ml_m7.dtsi b/dts/arm/nxp/nxp_imx8ml_m7.dtsi index 41f22deb991..f9406fc7546 100644 --- a/dts/arm/nxp/nxp_imx8ml_m7.dtsi +++ b/dts/arm/nxp/nxp_imx8ml_m7.dtsi @@ -164,12 +164,12 @@ }; uart1: uart@30860000 { - compatible = "nxp,imx-iuart"; - reg = <0x30860000 0x10000>; - interrupts = <26 3>; - clocks = <&ccm IMX_CCM_UART1_CLK 0x7c 24>; - status = "disabled"; - }; + compatible = "nxp,imx-iuart"; + reg = <0x30860000 0x10000>; + interrupts = <26 3>; + clocks = <&ccm IMX_CCM_UART1_CLK 0x7c 24>; + status = "disabled"; + }; mailbox0: mailbox@30ab0000 { compatible = "nxp,imx-mu"; From 8246d14742501bdd1c857e0f8b90e8453941f5b0 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Thu, 28 Sep 2023 17:51:57 -0400 Subject: [PATCH 3708/4498] drivers: xmc4xxx: spi: Update buffers before transmitting data In the interrupt driven spi, spi_context_update_tx() is called once from the calling thread and then once in spi_xmc4xxx_isr() after each new byte is received. This actually means that there is one extra call to spi_context_update_tx(). This is fine if spi_context_update_tx() complete it's call in the calling thread before the interrupt fires, however, this cannot be guaranteed especially if the calling thread is pre-emptive and has a low priority. Fix this by calling spi_context_update_tx() in the calling thread before transmitting the first byte. Signed-off-by: Andriy Gelman --- drivers/spi/spi_xmc4xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c index 9c48fb05098..d6aa60a527f 100644 --- a/drivers/spi/spi_xmc4xxx.c +++ b/drivers/spi/spi_xmc4xxx.c @@ -123,10 +123,10 @@ static void spi_xmc4xxx_shift_frames(const struct device *dev) XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION | XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION); - XMC_SPI_CH_Transmit(config->spi, tx_data, XMC_SPI_CH_MODE_STANDARD); - spi_context_update_tx(ctx, 1, 1); + XMC_SPI_CH_Transmit(config->spi, tx_data, XMC_SPI_CH_MODE_STANDARD); + #if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) return; #endif From a34d4d1ce9d96ddb2ed67686d5c30b8a0930734e Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Thu, 28 Sep 2023 18:55:51 -0400 Subject: [PATCH 3709/4498] drivers: spi: xmc4xxx: Fix potential runtime error Fixes an unhandled interrupt runtime crash if CONFIG_SPI_XMC4XXX_DMA=y and CONFIG_SPI_XMC4XXX_INTERRUPT=n. The unhandled interrupt error is triggered because irq_enable() was called without calling IRQ_CONNECT() when CONFIG_SPI_XMC4XXX_INTERRUPT=n. Signed-off-by: Andriy Gelman --- drivers/spi/spi_xmc4xxx.c | 2 ++ tests/drivers/spi/spi_loopback/boards/xmc45_relax_kit.conf | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c index d6aa60a527f..1706572bddb 100644 --- a/drivers/spi/spi_xmc4xxx.c +++ b/drivers/spi/spi_xmc4xxx.c @@ -468,7 +468,9 @@ static int spi_xmc4xxx_transceive_dma(const struct device *dev, const struct spi spi_context_cs_control(ctx, false); } +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) irq_enable(config->irq_num_rx); +#endif spi_context_release(ctx, ret); return ret; diff --git a/tests/drivers/spi/spi_loopback/boards/xmc45_relax_kit.conf b/tests/drivers/spi/spi_loopback/boards/xmc45_relax_kit.conf index d066213b5da..3f96b399e0e 100644 --- a/tests/drivers/spi/spi_loopback/boards/xmc45_relax_kit.conf +++ b/tests/drivers/spi/spi_loopback/boards/xmc45_relax_kit.conf @@ -1,3 +1,2 @@ -CONFIG_SPI_XMC4XXX_INTERRUPT=y CONFIG_SPI_XMC4XXX_DMA=y CONFIG_SPI_LOOPBACK_MODE_LOOP=y From 325e28218f22f932f49b26836b6cea5d95322125 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Thu, 28 Sep 2023 19:04:54 -0400 Subject: [PATCH 3710/4498] drivers: spi: xmc4xxx: Fix compiler warning with debug flags enabled Fixes warning when CONFIG_DEBUG_OPTIMIZATION=y: zephyrproject/modules/hal/infineon/XMCLib/drivers/inc/xmc_usic.h:2132:18: warning: 'clock_settings' may be used uninitialized [-Wmaybe-uninitialized] 2132 | (uint32_t)passive_level | | ^~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Andriy Gelman --- drivers/spi/spi_xmc4xxx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c index 1706572bddb..97b32f20e04 100644 --- a/drivers/spi/spi_xmc4xxx.c +++ b/drivers/spi/spi_xmc4xxx.c @@ -195,7 +195,8 @@ static int spi_xmc4xxx_configure(const struct device *dev, const struct spi_conf bool CPOL = SPI_MODE_GET(settings) & SPI_MODE_CPOL; bool CPHA = SPI_MODE_GET(settings) & SPI_MODE_CPHA; XMC_SPI_CH_CONFIG_t usic_cfg = {.baudrate = spi_cfg->frequency}; - XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_t clock_settings; + XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_t clock_settings = + XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED; if (spi_context_configured(ctx, spi_cfg)) { return 0; From 415b6fc945fd3748d2c8c5191abbc484fe551cad Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Fri, 22 Sep 2023 09:08:17 +0200 Subject: [PATCH 3711/4498] drivers: watchdog: wdt_nrfx: Implement disable API nRF5340 SoC has `TASK_STOP` this patch implements disabling watchdog for that SoC. Changed body of `wdt_nrf_setup()` to utilize `nrfx_wdt_reconfigure()` driver API. Signed-off-by: Adam Wojasinski --- drivers/watchdog/wdt_nrfx.c | 41 +++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 8d61f11d6fb..5d2e036a213 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -28,29 +28,32 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) { const struct wdt_nrfx_config *config = dev->config; struct wdt_nrfx_data *data = dev->data; - uint32_t behaviour; + nrfx_err_t err_code; /* Activate all available options. Run in all cases. */ - behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + config->config.behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | +#if NRF_WDT_HAS_STOP + NRF_WDT_BEHAVIOUR_STOP_ENABLE_MASK | +#endif + NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; /* Deactivate running in sleep mode. */ if (options & WDT_OPT_PAUSE_IN_SLEEP) { - behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; + config->config.behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; } /* Deactivate running when debugger is attached. */ if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) { - behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + config->config.behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; } - nrf_wdt_behaviour_set(config->wdt.p_reg, behaviour); - /* The watchdog timer is driven by the LFCLK clock running at 32768 Hz. - * The timeout value given in milliseconds needs to be converted here - * to watchdog ticks.*/ - nrf_wdt_reload_value_set( - config->wdt.p_reg, - (uint32_t)(((uint64_t)data->m_timeout * 32768U) - / 1000)); + config->config.reload_value = data->m_timeout; + + err_code = nrfx_wdt_reconfigure(&config->wdt, &config->config); + + if (err_code != NRFX_SUCCESS) { + return -EBUSY; + } nrfx_wdt_enable(&config->wdt); @@ -59,9 +62,21 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) static int wdt_nrf_disable(const struct device *dev) { - /* Started watchdog cannot be stopped on nRF devices. */ +#if NRFX_WDT_HAS_STOP + const struct wdt_nrfx_config *config = dev->config; + nrfx_err_t err_code; + + err_code = nrfx_wdt_stop(&config->wdt); + + if (err_code != NRFX_SUCCESS) { + return -ENOTSUP; + } + + return 0; +#else ARG_UNUSED(dev); return -EPERM; +#endif } static int wdt_nrf_install_timeout(const struct device *dev, From a13364112ee634af5ad4c1f185897740d54f0213 Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Tue, 31 Oct 2023 12:29:27 -0400 Subject: [PATCH 3712/4498] boards: arm: adafruit_feather_nrf52840: add voltage divider for battery This allows firmware to read the voltage for LiPoly battery. Schematic: https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/downloads Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com> --- .../adafruit_feather_nrf52840.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts index 284a4d24542..2333e5becbe 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts @@ -47,6 +47,13 @@ }; }; + vbatt { + compatible = "voltage-divider"; + io-channels = <&adc 5>; + output-ohms = <100000>; + full-ohms = <(100000 + 100000)>; + }; + /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; From ea2185dd1cc83fe844cb5ea35720b91e0da064a5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 12:35:19 +0100 Subject: [PATCH 3713/4498] arm arch: Replace use of TOSTR with STRINGIFY One of the ARM architure files, defined since long ago TOSTR having the exact same purpose as Zephyr's STRINGIFY. Remove the use of this macro in the tree (only used in another ARM header file) in favour of STRINGIFY. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/arch/arm/asm_inline_gcc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/zephyr/arch/arm/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h index 61f8a9f088d..3b8e8e19c92 100644 --- a/include/zephyr/arch/arm/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -18,6 +18,7 @@ #ifndef _ASMLANGUAGE +#include #include #include @@ -68,7 +69,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) || defined(CONFIG_ARMV7_A) __asm__ volatile( "mrs %0, cpsr;" - "and %0, #" TOSTR(I_BIT) ";" + "and %0, #" STRINGIFY(I_BIT) ";" "cpsid i;" : "=r" (key) : From e92021b7b581f4d43c23585da8796037d06ef94d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 12:38:10 +0100 Subject: [PATCH 3714/4498] arm arch: Remove definition of CONCAT and TOSTR One of the ARM architure files, defined since long ago CONCAT and TOSTR having the exact same purpose as Zephyr's _CONCAT & STRINGIFY. This arm header file is included thru dependencies into almost all code built for ARM, which leads to these macros being usable everywhere. This can easily make developers belive the macros are provided by Zephyr itself, and use them, leading to code which is not portable between architectures. Remove this macros definitions from the architecture headers. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/arch/arm/irq.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/zephyr/arch/arm/irq.h b/include/zephyr/arch/arm/irq.h index e363b963803..357c91a83ae 100644 --- a/include/zephyr/arch/arm/irq.h +++ b/include/zephyr/arch/arm/irq.h @@ -75,14 +75,6 @@ extern void z_arm_int_exit(void); extern void z_arm_interrupt_init(void); -/* macros convert value of its argument to a string */ -#define DO_TOSTR(s) #s -#define TOSTR(s) DO_TOSTR(s) - -/* concatenate the values of the arguments into one */ -#define DO_CONCAT(x, y) x ## y -#define CONCAT(x, y) DO_CONCAT(x, y) - /* Flags for use with IRQ_CONNECT() */ /** * Set this interrupt up as a zero-latency IRQ. If CONFIG_ZERO_LATENCY_LEVELS From f9685cd347fc9a5f1a01f0cee23f96ab5bab95cc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 7 Nov 2023 12:47:54 +0100 Subject: [PATCH 3715/4498] include: util: Add CONCAT as a general Zephyr utility macro Provide the CONCAT macro as a general Zephyr utility macro to paste two tokens during the preprocessor pass. Note that this macro is based on the _CONCAT macro defined in toolchain/common.h. This toolchain header needs a CONCAT like macro, but requires minimal include dependencies. So we leave _CONCAT where it is. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/sys/util.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index b3cbb917b46..a812ee4d37e 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -250,6 +250,15 @@ extern "C" { ((type *)(((char *)(ptr)) - offsetof(type, field))); \ }) +/** + * @brief Concatenate two tokens into one + * + * Concatenate two tokens, @p x and @p y, into a combined token during the preprocessor pass. + * This can be used to, for ex., build an identifier out of two parts, + * where one of those parts may be, for ex, a number, another macro, or a macro argument. + */ +#define CONCAT(x, y) _DO_CONCAT(x, y) + /** * @brief Value of @p x rounded up to the next multiple of @p align. */ From da35f117a44c03318bc183f174b05b4b09d1e02d Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Tue, 7 Nov 2023 08:55:19 +0700 Subject: [PATCH 3716/4498] dt-bindings: clock: update clock to RTD 1.0.0 Update clock sources Signed-off-by: Cong Nguyen Huu --- .../dt-bindings/clock/nxp_s32z2_clock.h | 201 +++++++++--------- 1 file changed, 102 insertions(+), 99 deletions(-) diff --git a/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h b/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h index 47eb060c545..6471a2c5406 100644 --- a/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h +++ b/include/zephyr/dt-bindings/clock/nxp_s32z2_clock.h @@ -39,7 +39,7 @@ #define NXP_S32_LFAST0_PLL_PH0_CLK 30U #define NXP_S32_LFAST1_PLL_PH0_CLK 31U #define NXP_S32_ETH_RGMII_REF_CLK 32U -#define NXP_S32_ETH_EXT_TS_CLK 33U +#define NXP_S32_TMR_1588_CLK 33U #define NXP_S32_ETH0_EXT_RX_CLK 34U #define NXP_S32_ETH0_EXT_TX_CLK 35U #define NXP_S32_ETH1_EXT_RX_CLK 36U @@ -188,110 +188,113 @@ #define NXP_S32_ETH0_RX_MII_CLK 180U #define NXP_S32_ETH0_RX_RGMII_CLK 181U #define NXP_S32_ETH0_TX_RGMII_CLK 182U -#define NXP_S32_ETH0_TX_RGMII_LPBK_CLK 183U +#define NXP_S32_ETH0_PS_TX_CLK 183U #define NXP_S32_ETH1_REF_RMII_CLK 184U #define NXP_S32_ETH1_RX_MII_CLK 185U #define NXP_S32_ETH1_RX_RGMII_CLK 186U #define NXP_S32_ETH1_TX_MII_CLK 187U #define NXP_S32_ETH1_TX_RGMII_CLK 188U -#define NXP_S32_ETH1_TX_RGMII_LPBK_CLK 189U +#define NXP_S32_ETH1_PS_TX_CLK 189U #define NXP_S32_P1_LFAST0_REF_CLK 190U #define NXP_S32_P1_LFAST1_REF_CLK 191U -#define NXP_S32_P1_LFAST_DFT_CLK 192U -#define NXP_S32_P1_NETC_AXI_CLK 193U -#define NXP_S32_P1_LIN_CLK 194U -#define NXP_S32_P1_REG_INTF_CLK 195U -#define NXP_S32_P2_DBG_ATB_CLK 196U -#define NXP_S32_P2_REG_INTF_CLK 197U -#define NXP_S32_P3_AES_CLK 198U -#define NXP_S32_P3_CLKOUT_SRC_CLK 199U -#define NXP_S32_P3_DBG_TS_CLK 200U -#define NXP_S32_P3_REG_INTF_CLK 201U -#define NXP_S32_P3_SYS_MON1_CLK 202U -#define NXP_S32_P3_SYS_MON2_CLK 203U -#define NXP_S32_P3_SYS_MON3_CLK 204U -#define NXP_S32_P4_CLKOUT_SRC_CLK 205U -#define NXP_S32_P4_DSPI60_CLK 206U -#define NXP_S32_P4_EMIOS_LCU_CLK 207U -#define NXP_S32_P4_LIN_CLK 208U -#define NXP_S32_P4_PSI5_125K_CLK 209U -#define NXP_S32_P4_PSI5_189K_CLK 210U -#define NXP_S32_P4_PSI5_S_BAUD_CLK 211U -#define NXP_S32_P4_PSI5_S_CORE_CLK 212U -#define NXP_S32_P4_PSI5_S_TRIG0_CLK 213U -#define NXP_S32_P4_PSI5_S_TRIG1_CLK 214U -#define NXP_S32_P4_PSI5_S_TRIG2_CLK 215U -#define NXP_S32_P4_PSI5_S_TRIG3_CLK 216U -#define NXP_S32_P4_PSI5_S_UART_CLK 217U -#define NXP_S32_P4_PSI5_S_WDOG0_CLK 218U -#define NXP_S32_P4_PSI5_S_WDOG1_CLK 219U -#define NXP_S32_P4_PSI5_S_WDOG2_CLK 220U -#define NXP_S32_P4_PSI5_S_WDOG3_CLK 221U -#define NXP_S32_P4_QSPI0_2X_CLK 222U -#define NXP_S32_P4_QSPI0_1X_CLK 223U -#define NXP_S32_P4_QSPI1_2X_CLK 224U -#define NXP_S32_P4_QSPI1_1X_CLK 225U -#define NXP_S32_P4_REG_INTF_2X_CLK 226U -#define NXP_S32_P4_REG_INTF_CLK 227U -#define NXP_S32_P4_SDHC_IP_CLK 228U -#define NXP_S32_P4_SDHC_IP_DIV2_CLK 229U -#define NXP_S32_P5_DIPORT_CLK 230U -#define NXP_S32_P5_AE_CLK 231U -#define NXP_S32_P5_CANXL_PE_CLK 232U -#define NXP_S32_P5_CANXL_CHI_CLK 233U -#define NXP_S32_P5_CLKOUT_SRC_CLK 234U -#define NXP_S32_P5_LIN_CLK 235U -#define NXP_S32_P5_REG_INTF_CLK 236U -#define NXP_S32_P6_REG_INTF_CLK 237U -#define NXP_S32_PIT0_CLK 238U -#define NXP_S32_PIT1_CLK 239U -#define NXP_S32_PIT4_CLK 240U -#define NXP_S32_PIT5_CLK 241U -#define NXP_S32_P0_PSI5_1US_CLK 242U -#define NXP_S32_PSI5_0_CLK 243U -#define NXP_S32_P4_PSI5_1US_CLK 244U -#define NXP_S32_PSI5_1_CLK 245U -#define NXP_S32_PSI5S_0_CLK 246U -#define NXP_S32_PSI5S_1_CLK 247U -#define NXP_S32_QSPI0_CLK 248U -#define NXP_S32_QSPI1_CLK 249U -#define NXP_S32_RTU0_CORE_MON1_CLK 250U -#define NXP_S32_RTU0_CORE_MON2_CLK 251U -#define NXP_S32_RTU0_CORE_DIV2_MON1_CLK 252U -#define NXP_S32_RTU0_CORE_DIV2_MON2_CLK 253U -#define NXP_S32_RTU0_CORE_DIV2_MON3_CLK 254U -#define NXP_S32_RTU0_REG_INTF_CLK 255U -#define NXP_S32_RTU1_CORE_MON1_CLK 256U -#define NXP_S32_RTU1_CORE_MON2_CLK 257U -#define NXP_S32_RTU1_CORE_DIV2_MON1_CLK 258U -#define NXP_S32_RTU1_CORE_DIV2_MON2_CLK 259U -#define NXP_S32_RTU1_CORE_DIV2_MON3_CLK 260U -#define NXP_S32_RTU1_REG_INTF_CLK 261U -#define NXP_S32_P4_SDHC_CLK 262U -#define NXP_S32_RXLUT_CLK 263U -#define NXP_S32_SDHC0_CLK 264U -#define NXP_S32_SINC_CLK 265U -#define NXP_S32_SIPI0_CLK 266U -#define NXP_S32_SIPI1_CLK 267U -#define NXP_S32_SIUL2_0_CLK 268U -#define NXP_S32_SIUL2_1_CLK 269U -#define NXP_S32_SIUL2_4_CLK 270U -#define NXP_S32_SIUL2_5_CLK 271U -#define NXP_S32_P0_DSPI_CLK 272U -#define NXP_S32_SPI0_CLK 273U -#define NXP_S32_SPI1_CLK 274U -#define NXP_S32_P1_DSPI_CLK 275U -#define NXP_S32_SPI2_CLK 276U -#define NXP_S32_SPI3_CLK 277U -#define NXP_S32_SPI4_CLK 278U -#define NXP_S32_P4_DSPI_CLK 279U -#define NXP_S32_SPI5_CLK 280U -#define NXP_S32_SPI6_CLK 281U -#define NXP_S32_SPI7_CLK 282U -#define NXP_S32_P5_DSPI_CLK 283U -#define NXP_S32_SPI8_CLK 284U -#define NXP_S32_SPI9_CLK 285U -#define NXP_S32_SRX0_CLK 286U -#define NXP_S32_SRX1_CLK 287U +#define NXP_S32_P1_NETC_AXI_CLK 192U +#define NXP_S32_P1_LIN_CLK 193U +#define NXP_S32_P1_REG_INTF_CLK 194U +#define NXP_S32_P2_DBG_ATB_CLK 195U +#define NXP_S32_P2_REG_INTF_CLK 196U +#define NXP_S32_P3_AES_CLK 197U +#define NXP_S32_P3_CLKOUT_SRC_CLK 198U +#define NXP_S32_P3_DBG_TS_CLK 199U +#define NXP_S32_P3_REG_INTF_CLK 200U +#define NXP_S32_P3_SYS_MON1_CLK 201U +#define NXP_S32_P3_SYS_MON2_CLK 202U +#define NXP_S32_P3_SYS_MON3_CLK 203U +#define NXP_S32_P4_CLKOUT_SRC_CLK 204U +#define NXP_S32_P4_DSPI60_CLK 205U +#define NXP_S32_P4_EMIOS_LCU_CLK 206U +#define NXP_S32_P4_LIN_CLK 207U +#define NXP_S32_P4_PSI5_125K_CLK 208U +#define NXP_S32_P4_PSI5_189K_CLK 209U +#define NXP_S32_P4_PSI5_S_BAUD_CLK 210U +#define NXP_S32_P4_PSI5_S_CORE_CLK 211U +#define NXP_S32_P4_PSI5_S_TRIG0_CLK 212U +#define NXP_S32_P4_PSI5_S_TRIG1_CLK 213U +#define NXP_S32_P4_PSI5_S_TRIG2_CLK 214U +#define NXP_S32_P4_PSI5_S_TRIG3_CLK 215U +#define NXP_S32_P4_PSI5_S_UART_CLK 216U +#define NXP_S32_P4_PSI5_S_WDOG0_CLK 217U +#define NXP_S32_P4_PSI5_S_WDOG1_CLK 218U +#define NXP_S32_P4_PSI5_S_WDOG2_CLK 219U +#define NXP_S32_P4_PSI5_S_WDOG3_CLK 220U +#define NXP_S32_P4_QSPI0_2X_CLK 221U +#define NXP_S32_P4_QSPI0_1X_CLK 222U +#define NXP_S32_P4_QSPI1_2X_CLK 223U +#define NXP_S32_P4_QSPI1_1X_CLK 224U +#define NXP_S32_P4_REG_INTF_2X_CLK 225U +#define NXP_S32_P4_REG_INTF_CLK 226U +#define NXP_S32_P4_SDHC_IP_CLK 227U +#define NXP_S32_P4_SDHC_IP_DIV2_CLK 228U +#define NXP_S32_P5_DIPORT_CLK 229U +#define NXP_S32_P5_AE_CLK 230U +#define NXP_S32_P5_CANXL_PE_CLK 231U +#define NXP_S32_P5_CANXL_CHI_CLK 232U +#define NXP_S32_P5_CLKOUT_SRC_CLK 233U +#define NXP_S32_P5_LIN_CLK 234U +#define NXP_S32_P5_REG_INTF_CLK 235U +#define NXP_S32_P6_REG_INTF_CLK 236U +#define NXP_S32_PIT0_CLK 237U +#define NXP_S32_PIT1_CLK 238U +#define NXP_S32_PIT4_CLK 239U +#define NXP_S32_PIT5_CLK 240U +#define NXP_S32_P0_PSI5_1US_CLK 241U +#define NXP_S32_PSI5_0_CLK 242U +#define NXP_S32_P4_PSI5_1US_CLK 243U +#define NXP_S32_PSI5_1_CLK 244U +#define NXP_S32_PSI5S_0_CLK 245U +#define NXP_S32_PSI5S_1_CLK 246U +#define NXP_S32_QSPI0_CLK 247U +#define NXP_S32_QSPI1_CLK 248U +#define NXP_S32_RTU0_CORE_MON1_CLK 249U +#define NXP_S32_RTU0_CORE_MON2_CLK 250U +#define NXP_S32_RTU0_CORE_DIV2_MON1_CLK 251U +#define NXP_S32_RTU0_CORE_DIV2_MON2_CLK 252U +#define NXP_S32_RTU0_CORE_DIV2_MON3_CLK 253U +#define NXP_S32_RTU0_REG_INTF_CLK 254U +#define NXP_S32_RTU1_CORE_MON1_CLK 255U +#define NXP_S32_RTU1_CORE_MON2_CLK 256U +#define NXP_S32_RTU1_CORE_DIV2_MON1_CLK 257U +#define NXP_S32_RTU1_CORE_DIV2_MON2_CLK 258U +#define NXP_S32_RTU1_CORE_DIV2_MON3_CLK 259U +#define NXP_S32_RTU1_REG_INTF_CLK 260U +#define NXP_S32_P4_SDHC_CLK 261U +#define NXP_S32_RXLUT_CLK 262U +#define NXP_S32_SDHC0_CLK 263U +#define NXP_S32_SINC_CLK 264U +#define NXP_S32_SIPI0_CLK 265U +#define NXP_S32_SIPI1_CLK 266U +#define NXP_S32_SIUL2_0_CLK 267U +#define NXP_S32_SIUL2_1_CLK 268U +#define NXP_S32_SIUL2_4_CLK 269U +#define NXP_S32_SIUL2_5_CLK 270U +#define NXP_S32_P0_DSPI_CLK 271U +#define NXP_S32_SPI0_CLK 272U +#define NXP_S32_SPI1_CLK 273U +#define NXP_S32_P1_DSPI_CLK 274U +#define NXP_S32_SPI2_CLK 275U +#define NXP_S32_SPI3_CLK 276U +#define NXP_S32_SPI4_CLK 277U +#define NXP_S32_P4_DSPI_CLK 278U +#define NXP_S32_SPI5_CLK 279U +#define NXP_S32_SPI6_CLK 280U +#define NXP_S32_SPI7_CLK 281U +#define NXP_S32_P5_DSPI_CLK 282U +#define NXP_S32_SPI8_CLK 283U +#define NXP_S32_SPI9_CLK 284U +#define NXP_S32_SRX0_CLK 285U +#define NXP_S32_SRX1_CLK 286U +#define NXP_S32_CORE_PLL_REFCLKOUT 287U +#define NXP_S32_CORE_PLL_FBCLKOUT 288U +#define NXP_S32_PERIPH_PLL_REFCLKOUT 289U +#define NXP_S32_PERIPH_PLL_FBCLKOUT 290U #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32Z2_CLOCK_H_ */ From 2a932ccab163ca5a249a3bdbf14533d69afe9790 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Tue, 7 Nov 2023 08:57:31 +0700 Subject: [PATCH 3717/4498] drivers: uart_nxp_s32_linflexed: update to RTD 1.0.0 Set default configuration BaudRateDivisor = 16U. Signed-off-by: Cong Nguyen Huu --- drivers/serial/uart_nxp_s32_linflexd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/serial/uart_nxp_s32_linflexd.c b/drivers/serial/uart_nxp_s32_linflexd.c index 9a8d8fe3790..4fa6badb796 100644 --- a/drivers/serial/uart_nxp_s32_linflexd.c +++ b/drivers/serial/uart_nxp_s32_linflexd.c @@ -347,6 +347,7 @@ static const struct uart_driver_api uart_nxp_s32_driver_api = { { \ .BaudRate = 115200, \ .BaudRateMantissa = 26U, \ + .BaudRateDivisor = 16U, \ .BaudRateFractionalDivisor = 1U, \ .ParityCheck = false, \ .ParityType = LINFLEXD_UART_IP_PARITY_EVEN, \ From e02c27aeb836fab20bf1a817fc53ed552f834cca Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Tue, 7 Nov 2023 09:13:03 +0700 Subject: [PATCH 3718/4498] drivers: counter_nxp_s32_sys_timer: update to RTD 1.0.0 Rename function Stm_Ip_GetInterruptFlag to Stm_Ip_GetInterruptStatusFlag. Signed-off-by: Cong Nguyen Huu --- drivers/counter/counter_nxp_s32_sys_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/counter/counter_nxp_s32_sys_timer.c b/drivers/counter/counter_nxp_s32_sys_timer.c index b6c7f8a1d96..47c1d0e3c3e 100644 --- a/drivers/counter/counter_nxp_s32_sys_timer.c +++ b/drivers/counter/counter_nxp_s32_sys_timer.c @@ -116,7 +116,7 @@ static uint32_t nxp_s32_sys_timer_get_pending_int(const struct device *dev) uint8_t i; for (i = 0; i < counter_get_num_of_channels(dev); i++) { - flags = Stm_Ip_GetInterruptFlag(config->instance, i); + flags = Stm_Ip_GetInterruptStatusFlag(config->instance, i); if (flags) { break; } From 5095d9d9e796a9ec5548060c1d1e9b7ef7d44f54 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Tue, 7 Nov 2023 09:18:47 +0700 Subject: [PATCH 3719/4498] drivers: mbox_nxp_s32_mru: update to RTD 1.0.0 Update NOTIFYAdd configuration Signed-off-by: Cong Nguyen Huu --- drivers/mbox/mbox_nxp_s32_mru.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mbox/mbox_nxp_s32_mru.c b/drivers/mbox/mbox_nxp_s32_mru.c index 8981e260d50..2c6246d8dce 100644 --- a/drivers/mbox/mbox_nxp_s32_mru.c +++ b/drivers/mbox/mbox_nxp_s32_mru.c @@ -283,8 +283,8 @@ static const struct mbox_driver_api nxp_s32_mru_driver_api = { .ChannelCfg = COND_CODE_0(MRU_RX_CHANNELS(n), \ (NULL), (nxp_s32_mru_##n##_ch_cfg)), \ .NOTIFYAdd = { \ - &MRU_BASE(n)->NOTIFY0, \ - &MRU_BASE(n)->NOTIFY1 \ + &MRU_BASE(n)->NOTIFY[0], \ + &MRU_BASE(n)->NOTIFY[1] \ }, \ }, \ .irq_group = MRU_INT_GROUP(DT_INST_IRQN(n)), \ From 8dcd61e36e2fe0eaa38b197e614f5267c8d260b8 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Thu, 9 Nov 2023 15:16:03 +0700 Subject: [PATCH 3720/4498] soc: nxp_s32: pinctrl: update to RTD 1.0.0 Add alias "FEATURE_SIUL2_MAX_NUMBER_OF_INPUT" for compatibility with with previous RTD versions. Signed-off-by: Cong Nguyen Huu --- soc/arm/nxp_s32/common/pinctrl_soc.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/arm/nxp_s32/common/pinctrl_soc.h b/soc/arm/nxp_s32/common/pinctrl_soc.h index 46c1c77bfd1..60c609497aa 100644 --- a/soc/arm/nxp_s32/common/pinctrl_soc.h +++ b/soc/arm/nxp_s32/common/pinctrl_soc.h @@ -19,6 +19,11 @@ /** @brief Type for NXP S32 pin configuration. */ typedef Siul2_Port_Ip_PinSettingsConfig pinctrl_soc_pin_t; +/* Alias for compatibility with previous RTD versions */ +#if !defined(FEATURE_SIUL2_MAX_NUMBER_OF_INPUT) && defined(FEATURE_SIUL2_MAX_NUMBER_OF_INPUT_U8) +#define FEATURE_SIUL2_MAX_NUMBER_OF_INPUT FEATURE_SIUL2_MAX_NUMBER_OF_INPUT_U8 +#endif + #if defined(SIUL2_PORT_IP_MULTIPLE_SIUL2_INSTANCES) #define NXP_S32_SIUL2_IDX(n) \ n == 0 ? IP_SIUL2_0 : (n == 1 ? IP_SIUL2_1 : ( \ From e59991abfe0da173eac3c5266ab9c74e612d5379 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Thu, 9 Nov 2023 14:10:31 +0700 Subject: [PATCH 3721/4498] drivers: spi_nxp_s32: update StateIndex configuration Set Spi StateIndex equal to index of DT Spi node. Because number of State array is set base on number of DT Spi node used. If StateIndex is set equal to Spi instance, StateIndex can be over array. Signed-off-by: Cong Nguyen Huu --- drivers/spi/spi_nxp_s32.c | 2 +- west.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_nxp_s32.c b/drivers/spi/spi_nxp_s32.c index 5acfa1c68a8..ae238407967 100644 --- a/drivers/spi/spi_nxp_s32.c +++ b/drivers/spi/spi_nxp_s32.c @@ -671,7 +671,7 @@ static const struct spi_driver_api spi_nxp_s32_driver_api = { SPI_MCR_PCSIS(BIT_MASK(SPI_NXP_S32_NUM_CS(n))) | \ SPI_MCR_MDIS(0U) | SPI_MCR_XSPI(1U) | SPI_MCR_HALT(1U)), \ .TransferMode = SPI_IP_POLLING, \ - .StateIndex = SPI_NXP_S32_HW_INSTANCE(n), \ + .StateIndex = n, \ SPI_NXP_S32_SET_SLAVE(n) \ } diff --git a/west.yml b/west.yml index 59ee67c81f6..3e7d49affec 100644 --- a/west.yml +++ b/west.yml @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 03bd989de4d2de151470e8b6068bc5686f3fc84c + revision: 69046233b7a7fac3138ae4dd5bcf6158e82529bb path: modules/hal/nxp groups: - hal From 85fb2873e4e20594e9955aaf09a54bda2a97787a Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 13 Nov 2023 14:23:48 -0800 Subject: [PATCH 3722/4498] logging: log_core: support CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD value of 1 Previous implementation didn't work if CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD was set to 1. Minmimum value that worked was 2. A value of 1 would just be ignored and act like 0 with threshold triggerring disabled. Signed-off-by: Mike J. Chen --- subsys/logging/log_core.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index 8f5e33e1e1e..de96cfe2fb3 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -163,19 +163,30 @@ static void z_log_msg_post_finalize(void) k_spin_unlock(&process_lock, key); } else if (proc_tid != NULL) { - if (cnt == 0) { - k_timer_start(&log_process_thread_timer, - K_MSEC(CONFIG_LOG_PROCESS_THREAD_SLEEP_MS), - K_NO_WAIT); - } else if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD && - (cnt + 1) == CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) { - k_timer_stop(&log_process_thread_timer); - k_sem_give(&log_process_thread_sem); + /* + * If CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1, + * timer is never needed. We release the processing + * thread after every message is posted. + */ + if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1) { + if (cnt == 0) { + k_sem_give(&log_process_thread_sem); + } } else { - /* No action needed. Message processing will be triggered by the - * timeout or when number of upcoming messages exceeds the - * threshold. - */ + if (cnt == 0) { + k_timer_start(&log_process_thread_timer, + K_MSEC(CONFIG_LOG_PROCESS_THREAD_SLEEP_MS), + K_NO_WAIT); + } else if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD && + (cnt + 1) == CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) { + k_timer_stop(&log_process_thread_timer); + k_sem_give(&log_process_thread_sem); + } else { + /* No action needed. Message processing will be triggered by the + * timeout or when number of upcoming messages exceeds the + * threshold. + */ + } } } } From c9da68290aecee508bd0c5b5f07e99d8ba9bbe79 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 14 Nov 2023 12:00:43 +0100 Subject: [PATCH 3723/4498] modules: canopennode: use zephyr/dsp/types.h for float32_t/float64_t Include the zephyr/dsp/types.h header for float32_t/float64_t type definitions to avoid conflicts with other subsystems including this header. Add compile-time asserts to ensure the typedefs meet the requirements of the CANopenNode module. Fixes: #63896 Signed-off-by: Henrik Brix Andersen --- modules/canopennode/CO_driver_target.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/canopennode/CO_driver_target.h b/modules/canopennode/CO_driver_target.h index 3e76b5290b0..27b1f1caa9d 100644 --- a/modules/canopennode/CO_driver_target.h +++ b/modules/canopennode/CO_driver_target.h @@ -22,6 +22,7 @@ extern "C" { #include #include #include +#include /* float32_t, float64_t */ /* Use static variables instead of calloc() */ #define CO_USE_GLOBALS @@ -46,12 +47,13 @@ extern "C" { #endif typedef bool bool_t; -typedef float float32_t; -typedef long double float64_t; typedef char char_t; typedef unsigned char oChar_t; typedef unsigned char domain_t; +BUILD_ASSERT(sizeof(float32_t) >= 4); +BUILD_ASSERT(sizeof(float64_t) >= 8); + typedef struct canopen_rx_msg { uint8_t data[8]; uint16_t ident; From afe1ca6847851f24cd72c7efc60730726ab4b684 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 14 Nov 2023 13:21:02 +0100 Subject: [PATCH 3724/4498] linker: allow tagging variables with __nocache_noinit Allow tagging variables with __nocach_noinit. With CONFIG_NOCACHE_MEMORY=y, this will resolve to __nocache, which implies __noinit. With CONFIG_NOCACHE_MEMORY=n, this simply resolves to __noinit. Signed-off-by: Henrik Brix Andersen --- include/zephyr/linker/section_tags.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/linker/section_tags.h b/include/zephyr/linker/section_tags.h index d0ef2ecf126..5678a07325b 100644 --- a/include/zephyr/linker/section_tags.h +++ b/include/zephyr/linker/section_tags.h @@ -49,8 +49,10 @@ #if defined(CONFIG_NOCACHE_MEMORY) #define __nocache __in_section_unique(_NOCACHE_SECTION_NAME) +#define __nocache_noinit __nocache #else #define __nocache +#define __nocache_noinit __noinit #endif /* CONFIG_NOCACHE_MEMORY */ #if defined(CONFIG_KERNEL_COHERENCE) From 58e1963c6b7a7d6966244be9b89fb099aa6d66d7 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 14 Nov 2023 13:23:13 +0100 Subject: [PATCH 3725/4498] drivers: can: mcan: use __nocache_noinit for MRAM data variables Use __nocache_noinit for the Bosch M_CAN MRAM data variables on SoCs without dedicated MRAM. Fixes: #64691 Signed-off-by: Henrik Brix Andersen --- include/zephyr/drivers/can/can_mcan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/drivers/can/can_mcan.h b/include/zephyr/drivers/can/can_mcan.h index 6cc632fb13e..b29adc857f7 100644 --- a/include/zephyr/drivers/can/can_mcan.h +++ b/include/zephyr/drivers/can/can_mcan.h @@ -640,7 +640,7 @@ enum can_mcan_psr_lec { */ #define CAN_MCAN_DT_MRAM_DEFINE(node_id, _name) \ BUILD_ASSERT(CAN_MCAN_DT_MRAM_OFFSET(node_id) == 0, "offset must be 0"); \ - static char __noinit __nocache __aligned(4) _name[CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)]; + static char __nocache_noinit __aligned(4) _name[CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)]; /** * @brief Assert that the Message RAM configuration meets the Bosch M_CAN IP core restrictions From d10e0e524735a7875b1129dde7bb472bd582f831 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 14 Nov 2023 16:59:01 +0200 Subject: [PATCH 3726/4498] MAINTAINERS: Fixes to Networking Buffers section Add a missing c-file (buf_simple.c) and use a dedicated label for Networking Buffers. Also add explicit excludes of the same files to the Networking section. Without the dedicated label it seems that the wrong maintainer gets set as assignee for pull requests. Signed-off-by: Johan Hedberg --- MAINTAINERS.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b65679cb6a1..7562f3587c7 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2032,10 +2032,12 @@ Networking: - include/zephyr/net/gptp.h - include/zephyr/net/ieee802154*.h - include/zephyr/net/wifi*.h + - include/zephyr/net/buf.h - samples/net/gptp/ - samples/net/sockets/coap_*/ - samples/net/lwm2m_client/ - samples/net/wifi/ + - subsys/net/buf*.c - subsys/net/l2/ethernet/gptp/ - subsys/net/l2/ieee802154/ - subsys/net/l2/wifi/ @@ -2070,10 +2072,10 @@ Networking: - jukkar files: - include/zephyr/net/buf.h - - subsys/net/buf.c + - subsys/net/buf*.c - tests/net/buf/ labels: - - "area: Networking" + - "area: Networking Buffers" "Networking: Connection Manager": status: maintained From 8c745831256aea8d3cdc2973b27833a4f7f291c3 Mon Sep 17 00:00:00 2001 From: David Brown Date: Tue, 14 Nov 2023 08:14:43 -0700 Subject: [PATCH 3727/4498] boards: stm32h747i_disco: Add Segger JLink support Add configuration lines to be able to use the jlink debugger with this board. The disco board leaves the debug lines tri-stated until connecting to stlink, so it is safe to just plug in the jlink and use it. Signed-off-by: David Brown --- boards/arm/stm32h747i_disco/board.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm/stm32h747i_disco/board.cmake b/boards/arm/stm32h747i_disco/board.cmake index b0b8e824858..ac0e473e57d 100644 --- a/boards/arm/stm32h747i_disco/board.cmake +++ b/boards/arm/stm32h747i_disco/board.cmake @@ -1,11 +1,14 @@ # SPDX-License-Identifier: Apache-2.0 if(CONFIG_BOARD_STM32H747I_DISCO_M7) +board_runner_args(jlink "--device=STM32H747ZI_M7") board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd_stm32h747i_disco_m7.cfg") board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) elseif(CONFIG_BOARD_STM32H747I_DISCO_M4) +board_runner_args(jlink "--device=STM32H747ZI_M4") board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd_stm32h747i_disco_m4.cfg") board_runner_args(openocd --target-handle=_CHIPNAME.cpu1) endif() include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) From 16629cbabd66134bc3fe3a835599a3587ad1772e Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 14 Nov 2023 12:09:29 -0300 Subject: [PATCH 3728/4498] tests: coredump: Remove matching pattern On xtensa architectures the string "ZEPHYR FATAL ERROR" comes after the coredump itself. The ordered regex will incorrectly fail for this arch. Signed-off-by: Lucas Tamborrino --- tests/subsys/debug/coredump/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/subsys/debug/coredump/testcase.yaml b/tests/subsys/debug/coredump/testcase.yaml index 5b7dde692b1..0f9e2ecead2 100644 --- a/tests/subsys/debug/coredump/testcase.yaml +++ b/tests/subsys/debug/coredump/testcase.yaml @@ -14,7 +14,6 @@ tests: type: multi_line regex: - "Coredump: (.*)" - - ">>> ZEPHYR FATAL ERROR " - "E: #CD:BEGIN#" - "E: #CD:5([aA])45([0-9a-fA-F]+)" - "E: #CD:41([0-9a-fA-F]+)" From a089fa241f6e93ed0aa14271b5d4aecb2185cdf4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 14 Nov 2023 17:11:17 +0000 Subject: [PATCH 3729/4498] input: npcx: drop the input_ prefix from the internal functions Drop the input_ prefix fromthe internal functions. Trying to unify the input drivers to use the same style for function naming, this makes it a bit more compact and makes it easier to distinguish the common keyboard structures and functions from the driver ones. Signed-off-by: Fabio Baltieri --- drivers/input/input_npcx_kbd.c | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index 1de14726a6d..e703bd65f3f 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(input_npcx_kbd); #define ROW_SIZE DT_INST_PROP(0, row_size) /* Driver config */ -struct input_npcx_kbd_config { +struct npcx_kbd_config { struct input_kbd_matrix_common_config common; /* Keyboard scan controller base address */ struct kbs_reg *base; @@ -40,24 +40,24 @@ struct input_npcx_kbd_config { struct npcx_wui wui_maps[]; }; -struct input_npcx_kbd_data { +struct npcx_kbd_data { struct input_kbd_matrix_common_data common; struct miwu_callback ksi_callback[ROW_SIZE]; }; -INPUT_KBD_STRUCT_CHECK(struct input_npcx_kbd_config, struct input_npcx_kbd_data); +INPUT_KBD_STRUCT_CHECK(struct npcx_kbd_config, struct npcx_kbd_data); /* Keyboard scan local functions */ -static void input_npcx_kbd_ksi_isr(const struct device *dev, struct npcx_wui *wui) +static void npcx_kbd_ksi_isr(const struct device *dev, struct npcx_wui *wui) { ARG_UNUSED(wui); input_kbd_matrix_poll_start(dev); } -static void input_npcx_kbd_set_detect_mode(const struct device *dev, bool enabled) +static void npcx_kbd_set_detect_mode(const struct device *dev, bool enabled) { - const struct input_npcx_kbd_config *const config = dev->config; + const struct npcx_kbd_config *const config = dev->config; if (enabled) { irq_enable(config->irq); @@ -66,9 +66,9 @@ static void input_npcx_kbd_set_detect_mode(const struct device *dev, bool enable } } -static void input_npcx_kbd_drive_column(const struct device *dev, int col) +static void npcx_kbd_drive_column(const struct device *dev, int col) { - const struct input_npcx_kbd_config *config = dev->config; + const struct npcx_kbd_config *config = dev->config; const struct input_kbd_matrix_common_config *common = &config->common; struct kbs_reg *const inst = config->base; uint32_t mask; @@ -98,9 +98,9 @@ static void input_npcx_kbd_drive_column(const struct device *dev, int col) inst->KBSOUT1 = ((mask >> 16) & 0x03); } -static int input_npcx_kbd_read_row(const struct device *dev) +static int npcx_kbd_read_row(const struct device *dev) { - const struct input_npcx_kbd_config *config = dev->config; + const struct npcx_kbd_config *config = dev->config; const struct input_kbd_matrix_common_config *common = &config->common; struct kbs_reg *const inst = config->base; int val; @@ -113,10 +113,10 @@ static int input_npcx_kbd_read_row(const struct device *dev) return val; } -static void input_npcx_kbd_init_ksi_wui_callback(const struct device *dev, - struct miwu_callback *callback, - const struct npcx_wui *wui, - miwu_dev_callback_handler_t handler) +static void npcx_kbd_init_ksi_wui_callback(const struct device *dev, + struct miwu_callback *callback, + const struct npcx_wui *wui, + miwu_dev_callback_handler_t handler) { /* KSI signal which has no wake-up input source */ if (wui->table == NPCX_MIWU_TABLE_NONE) { @@ -132,12 +132,12 @@ static void input_npcx_kbd_init_ksi_wui_callback(const struct device *dev, npcx_miwu_irq_enable(wui); } -static int input_npcx_kbd_init(const struct device *dev) +static int npcx_kbd_init(const struct device *dev) { const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE); - const struct input_npcx_kbd_config *const config = dev->config; + const struct npcx_kbd_config *const config = dev->config; const struct input_kbd_matrix_common_config *common = &config->common; - struct input_npcx_kbd_data *const data = dev->data; + struct npcx_kbd_data *const data = dev->data; struct kbs_reg *const inst = config->base; int ret; @@ -176,7 +176,7 @@ static int input_npcx_kbd_init(const struct device *dev) } /* Drive all column lines to low for detection any key press */ - input_npcx_kbd_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE); + npcx_kbd_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE); if (common->row_size != ROW_SIZE) { LOG_ERR("Unexpected ROW_SIZE: %d != %d", common->row_size, ROW_SIZE); @@ -185,9 +185,9 @@ static int input_npcx_kbd_init(const struct device *dev) /* Configure wake-up input and callback for keyboard input signal */ for (int i = 0; i < common->row_size; i++) { - input_npcx_kbd_init_ksi_wui_callback( + npcx_kbd_init_ksi_wui_callback( dev, &data->ksi_callback[i], &config->wui_maps[i], - input_npcx_kbd_ksi_isr); + npcx_kbd_ksi_isr); } /* Configure pin-mux for keyboard scan device */ @@ -205,12 +205,12 @@ PINCTRL_DT_INST_DEFINE(0); INPUT_KBD_MATRIX_DT_INST_DEFINE(0); static const struct input_kbd_matrix_api npcx_kbd_api = { - .drive_column = input_npcx_kbd_drive_column, - .read_row = input_npcx_kbd_read_row, - .set_detect_mode = input_npcx_kbd_set_detect_mode, + .drive_column = npcx_kbd_drive_column, + .read_row = npcx_kbd_read_row, + .set_detect_mode = npcx_kbd_set_detect_mode, }; -static const struct input_npcx_kbd_config npcx_kbd_cfg = { +static const struct npcx_kbd_config npcx_kbd_cfg_0 = { .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, &npcx_kbd_api), .base = (struct kbs_reg *)DT_INST_REG_ADDR(0), .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), @@ -220,10 +220,10 @@ static const struct input_npcx_kbd_config npcx_kbd_cfg = { .wui_maps = NPCX_DT_WUI_ITEMS_LIST(0), }; -static struct input_npcx_kbd_data npcx_kbd_data; +static struct npcx_kbd_data npcx_kbd_data_0; -DEVICE_DT_INST_DEFINE(0, input_npcx_kbd_init, NULL, - &npcx_kbd_data, &npcx_kbd_cfg, +DEVICE_DT_INST_DEFINE(0, npcx_kbd_init, NULL, + &npcx_kbd_data_0, &npcx_kbd_cfg_0, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, From 1af78e04810f2fcbfd3b29cd23d4d7acc2910f1b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 14 Nov 2023 13:29:01 +0200 Subject: [PATCH 3730/4498] boards: up_squared_pro_7000: Update documentation Add chapter describing serial console connection and cleanup. Signed-off-by: Andrei Emeltchenko --- .../x86/intel_adl/doc/up_squared_pro_7000.rst | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/boards/x86/intel_adl/doc/up_squared_pro_7000.rst b/boards/x86/intel_adl/doc/up_squared_pro_7000.rst index 8f322080d96..762340e1049 100644 --- a/boards/x86/intel_adl/doc/up_squared_pro_7000.rst +++ b/boards/x86/intel_adl/doc/up_squared_pro_7000.rst @@ -2,8 +2,8 @@ .. _up_squared_pro_7000_board: -UP SQUARED PRO 7000 board -######################### +UP Squared Pro 7000 +################### Overview ******** @@ -20,16 +20,17 @@ This board configuration enables kernel support for the UP Squared Pro 7000 boar Hardware ******** -General information about the board can be found at the `UP_SQUARED_PRO_7000`_ website. +General information about the board can be found at the `UP Squared Pro 7000`_ website. Connections and IOs =================== -Refer to the `UP_SQUARED_PRO_7000`_ website for more information. +Refer to the `UP Squared Pro 7000`_ website for more information. Programming and Debugging ************************* -Use the following procedures for booting an image for an UP SQUARED PRO 7000 board. + +Use the following procedures for booting an image for an UP Squared Pro 7000 board. .. contents:: :depth: 1 @@ -40,7 +41,7 @@ Build Zephyr application ======================== #. Build a Zephyr application; for instance, to build the ``hello_world`` - application for UP SQUARED PRO 7000 board: + application for UP Squared Pro 7000 board: .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -52,6 +53,16 @@ Build Zephyr application A Zephyr EFI image file named :file:`zephyr.efi` is automatically created in the build directory after the application is built. +Connect Serial Console +====================== + +Current board configuration assumes that serial console is connected to +connector ``CN14 USB 2.0/UART 1x10P Wafer``. Refer to `User Manual`_ for +description of the connector and location on the board. + +Refer to `UP Serial Console`_ for additional information about serial +connection setup. + Booting the UP Squared Pro 7000 Board using UEFI ================================================ @@ -64,4 +75,11 @@ Booting the UP Squared Pro 7000 Board over network .. include:: ../../common/net_boot.rst :start-after: start_include_here -.. _UP_SQUARED_PRO_7000: https://up-board.org/up-squared-pro-7000/ +References +********** + +.. target-notes:: + +.. _UP Squared Pro 7000: https://up-board.org/up-squared-pro-7000/ +.. _User Manual: https://downloads.up-community.org/download/up-squared-pro-7000-user-manual/ +.. _UP Serial Console: https://github.com/up-board/up-community/wiki/Serial-Console From 1c8b668d2388c141f645cf64a19bfea2cb22ced9 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 15 Nov 2023 18:04:28 +0100 Subject: [PATCH 3731/4498] tfm: Fix include order between platform_ns and tfm_api_ns libraries Fix include order between platform_ns and tfm_api_ns libraries. platform_ns functions may depend on tfm_api_ns. This would typically be platform specific IOCTL services added to the platform_ns library requiring the tfm_platform_ioctl from the TF-M platform partition exposed in tfm_platform_api.c Signed-off-by: Joakim Andersson --- modules/trusted-firmware-m/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index f00116cda2c..177a47e28d6 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -435,8 +435,8 @@ if (CONFIG_BUILD_WITH_TFM) else() zephyr_library_link_libraries( - ${TFM_API_NS_PATH} ${PLATFORM_NS_FILE} + ${TFM_API_NS_PATH} ) endif() From e7123253a3211897016be148d9aee72cb2837bb6 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Wed, 15 Nov 2023 12:41:16 +0100 Subject: [PATCH 3732/4498] boards: arm: nrf9131ek: add docs This patch adds a readme file for the nRF9131-EK. Signed-off-by: Maximilian Deubel --- .../doc/img/nrf9131ek_nrf9131.webp | Bin 0 -> 75800 bytes boards/arm/nrf9131ek_nrf9131/doc/index.rst | 228 ++++++++++++++++++ .../nrf9131ek_nrf9131_common.dtsi | 4 +- 3 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp create mode 100644 boards/arm/nrf9131ek_nrf9131/doc/index.rst diff --git a/boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp b/boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp new file mode 100644 index 0000000000000000000000000000000000000000..056296ebbbcab5b514be7a6f30771f3b12167bc3 GIT binary patch literal 75800 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 -b 115200 + +Replace :code:`` with the port where the nRF9131 EK +can be found. For example, under Linux, :code:`/dev/ttyACM0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf9131ek_nrf9131 + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + + +Testing the LEDs and buttons in the nRF9131 EK +********************************************** + +There are 2 samples that allow you to test that the button and LED on +the board are working properly with Zephyr: + +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi`. + +References +********** + +.. target-notes:: + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi index 35314cd0784..2c3b8481d2a 100644 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi @@ -20,7 +20,7 @@ compatible = "gpio-leds"; led0: led_0 { gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - label = "Green LED 1"; + label = "Red LED 1"; }; led1: led_1 { gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; @@ -28,7 +28,7 @@ }; led2: led_2 { gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; - label = "Green LED 3"; + label = "Blue LED 3"; }; }; From 9fe225d2b8a467b62ea652cbf181b65c3427229e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 12:24:32 +0100 Subject: [PATCH 3733/4498] doc/connectivity/usb: Replace references to native_posix w native_sim Replace the references to native_posix with native_sim, and update link names accordingly. Background: during this release native_sim is replacing native_posix as the main host test/development platform. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_sim/doc/index.rst | 2 +- doc/connectivity/usb/device/usb_device.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 94eb8d43580..5cd060930e4 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -390,7 +390,7 @@ The following peripherals are currently provided with this board: **USB controller** It's possible to use the Virtual USB controller working over USB/IP protocol. More information can be found in - :ref:`Testing USB over USP/IP in native_posix `. + :ref:`Testing USB over USP/IP in native_sim `. **Display driver** A display driver is provided that creates a window on the host machine to diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index 3362f07840f..134ec5972cd 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -445,14 +445,14 @@ the vendor requests: The class driver waits for the :makevar:`USB_DC_CONFIGURED` device status code before transmitting any data. -.. _testing_USB_native_posix: +.. _testing_USB_native_sim: -Testing over USPIP in native_posix -*********************************** +Testing over USPIP in native_sim +******************************** A virtual USB controller implemented through USBIP might be used to test the USB device stack. Follow the general build procedure to build the USB sample for -the native_posix configuration. +the :ref:`native_sim ` configuration. Run built sample with: From 5776d74943b7b561b1e6a6cfd4efce793c599906 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 13:35:59 +0100 Subject: [PATCH 3734/4498] samples/subsys/usb/console: Remove platform_exclude native_posix and native_sim are already excluded thru the lack of required tags. Let's remove the platform exclude instead of adding also native_sim to it explicitly. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/usb/console/sample.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/samples/subsys/usb/console/sample.yaml b/samples/subsys/usb/console/sample.yaml index f7fc8c03c0e..0a291d23a67 100644 --- a/samples/subsys/usb/console/sample.yaml +++ b/samples/subsys/usb/console/sample.yaml @@ -6,9 +6,6 @@ tests: - usb_device - usb_cdc tags: usb - platform_exclude: - - native_posix - - native_posix_64 harness: console harness_config: fixture: fixture_usb_cdc From 5bf7109767c128a877bdbac7b46ff76454167689 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 13:37:12 +0100 Subject: [PATCH 3735/4498] samples/subsys/usb/cdc_acm: Enable for native_sim Allow this sample in native_sim, and set it as default integration platform instead of native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/usb/cdc_acm/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/usb/cdc_acm/sample.yaml b/samples/subsys/usb/cdc_acm/sample.yaml index 19e645174f7..61b72fa41ef 100644 --- a/samples/subsys/usb/cdc_acm/sample.yaml +++ b/samples/subsys/usb/cdc_acm/sample.yaml @@ -41,4 +41,4 @@ tests: arch_allow: posix build_only: true integration_platforms: - - native_posix + - native_sim From 063ce9caf54fa656f02ae48f3c9d537659a10dec Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 13:37:48 +0100 Subject: [PATCH 3736/4498] samples/subsys/usb/hid: Enable for native_sim Allow this sample in native_sim, and set it as default integration platform instead of native_posix. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/usb/hid/sample.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/subsys/usb/hid/sample.yaml b/samples/subsys/usb/hid/sample.yaml index 7f63562bbf7..ba6cf22a2d4 100644 --- a/samples/subsys/usb/hid/sample.yaml +++ b/samples/subsys/usb/hid/sample.yaml @@ -17,6 +17,8 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 build_only: true integration_platforms: - - native_posix + - native_sim From feb6742a8e2ef2579efa5c236bfd338fdbf0eb35 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 15 Nov 2023 08:49:32 -0500 Subject: [PATCH 3737/4498] CODEOWNERS: cleanup and remove duplicates Remove anything that would be covered by MAINTAINERS.yml leaving only mostly instances that are not covered. Signed-off-by: Anas Nashif --- CODEOWNERS | 469 ----------------------------------------------------- 1 file changed, 469 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 1db37fb9dd5..ab9197825c5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -13,23 +13,6 @@ # Do not use wildcard on all source yet # * @galak @nashif -/.github/ @nashif @stephanosio -/.github/workflows/ @galak @nashif -/MAINTAINERS.yml @MaureenHelm -/arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev -/arch/arm/ @MaureenHelm @galak @ioannisg -/arch/arm/core/cortex_m/cmse/ @ioannisg -/arch/arm/include/cortex_m/cmse.h @ioannisg -/arch/arm/core/cortex_a_r/ @MaureenHelm @galak @ioannisg @bbolen @stephanosio -/arch/arm64/ @carlocaione -/arch/arm64/core/cortex_r/ @povergoing -/arch/arm64/core/xen/ @lorc @firscity -/arch/common/ @ioannisg @andyross -/arch/mips/ @frantony -/soc/arc/snps_*/ @abrodkin @ruuddw @evgeniy-paltsev -/soc/nios2/ @nashif -/soc/arm/ @MaureenHelm @galak @ioannisg -/soc/arm/arm/mps2/ @fvincenzo /soc/arm/aspeed/ @aspeeddylan /soc/arm/atmel_sam/common/*_sam4l_*.c @nandojve /soc/arm/atmel_sam/sam3x/ @ioannisg @@ -38,18 +21,9 @@ /soc/arm/atmel_sam/sam4s/ @fallrisk /soc/arm/atmel_sam/same70/ @nandojve /soc/arm/atmel_sam/samv71/ @nandojve -/soc/arm/cypress/ @ifyall @npal-cy /soc/arm/bcm*/ @sbranden -/soc/arm/gigadevice/ @nandojve /soc/arm/infineon_cat1/ @ifyall @npal-cy /soc/arm/infineon_xmc/ @parthitce -/soc/arm/nxp*/ @mmahadevan108 @dleach02 -/soc/arm/nxp_s32/ @manuargue -/soc/arm/nordic_nrf/ @anangl -/soc/arm/nuvoton_npcx/ @MulinChao @ChiHuaL -/soc/arm/nuvoton_numicro/ @ssekar15 -/soc/arm/quicklogic_eos_s3/ @fkokosinski @kgugala -/soc/arm/rpi_pico/ @yonsch /soc/arm/silabs_exx32/efm32pg1b/ @rdmeneze /soc/arm/silabs_exx32/efr32mg21/ @l-alfred /soc/arm/st_stm32/ @erwango @@ -63,37 +37,11 @@ /soc/arm/xilinx_zynq7000/ @ibirnbaum /soc/arm/xilinx_zynqmp/ @stephanosio /soc/arm/renesas_rcar/ @aaillet -/soc/arm64/ @carlocaione -/soc/arm64/qemu_cortex_a53/ @carlocaione -/soc/arm64/bcm_vk/ @abhishek-brcm -/soc/arm64/nxp_layerscape/ @JiafeiPan -/soc/arm64/xenvm/ @lorc @firscity -/soc/arm64/nxp_imx/ @MrVan @JiafeiPan -/soc/arm64/arm/ @povergoing -/soc/arm64/arm/fvp_aemv8a/ @carlocaione -/soc/arm64/intel_socfpga/* @siclim -/soc/arm64/renesas_rcar/ @lorc @xakep-amatop -/soc/Kconfig @tejlmand @galak @nashif @nordicjm -/submanifests/* @mbolivar-ampere -/arch/x86/ @jhedberg @nashif -/arch/nios2/ @nashif -/arch/posix/ @aescolar @daor-oti -/arch/riscv/ @kgugala @pgielda -/soc/mips/ @frantony -/soc/posix/ @aescolar @daor-oti -/soc/riscv/ @kgugala @pgielda /soc/riscv/openisa*/ @dleach02 /soc/riscv/riscv-privileged/andes_v5/ @cwshu @kevinwang821020 @jimmyzhe /soc/riscv/riscv-privileged/neorv32/ @henrikbrixandersen /soc/riscv/riscv-privileged/gd32vf103/ @soburi /soc/riscv/riscv-privileged/niosv/ @sweeaun -/soc/x86/ @dcpleung @nashif -/arch/xtensa/ @dcpleung @andyross @nashif -/soc/xtensa/ @dcpleung @andyross @nashif -/arch/sparc/ @julius-barendt -/soc/sparc/ @julius-barendt -/boards/arc/ @abrodkin @ruuddw @evgeniy-paltsev -/boards/arm/ @MaureenHelm @galak /boards/arm/96b_argonkey/ @avisconti /boards/arm/96b_avenger96/ @Mani-Sadhasivam /boards/arm/96b_carbon/ @idlethread @@ -102,7 +50,6 @@ /boards/arm/96b_neonkey/ @Mani-Sadhasivam /boards/arm/96b_stm32_sensor_mez/ @Mani-Sadhasivam /boards/arm/96b_wistrio/ @Mani-Sadhasivam -/boards/arm/arduino_due/ @ioannisg /boards/arm/acn52832/ @sven-hm /boards/arm/arduino_mkrzero/ @soburi /boards/arm/bbc_microbit_v2/ @LingaoM @@ -168,15 +115,7 @@ /boards/arm/rcar_*/ @aaillet /boards/arm/ubx_bmd345eval_nrf52840/ @Navin-Sankar @brec-u-blox /boards/arm/nrf5340_audio_dk_nrf5340 @koffes @alexsven @erikrobstad @rick1082 @gWacey -/boards/common/ @mbolivar-ampere -/boards/deprecated.cmake @tejlmand -/boards/mips/ @frantony -/boards/nios2/ @nashif -/boards/nios2/altera_max10/ @nashif /boards/arm/stm32_min_dev/ @sidcha -/boards/posix/ @aescolar @daor-oti -/boards/posix/nrf52_bsim/ @aescolar @wopu-ot -/boards/riscv/ @kgugala @pgielda /boards/riscv/rv32m1_vega/ @dleach02 /boards/riscv/adp_xc7k_ae350/ @cwshu @kevinwang821020 @jimmyzhe /boards/riscv/longan_nano/ @soburi @@ -184,16 +123,11 @@ /boards/riscv/niosv*/ @sweeaun /boards/riscv/sparkfun_red_v_things_plus/ @soburi /boards/riscv/stamp_c3/ @soburi -/boards/shields/ @erwango /boards/shields/atmel_rf2xx/ @nandojve /boards/shields/esp_8266/ @nandojve /boards/shields/inventek_eswifi/ @nandojve -/boards/x86/ @dcpleung @nashif -/boards/x86/acrn/ @enjiamai -/boards/xtensa/ @nashif @dcpleung /boards/xtensa/odroid_go/ @ydamigos /boards/xtensa/nxp_adsp_imx8/ @iuliana-prodan @dbaluta -/boards/sparc/ @julius-barendt /boards/arm64/qemu_cortex_a53/ @carlocaione /boards/arm64/bcm958402m2_a72/ @abhishek-brcm /boards/arm64/mimx8mm_evk/ @MrVan @JiafeiPan @@ -207,25 +141,13 @@ /boards/arm64/intel_socfpga_agilex_socdk/ @siclim @ngboonkhai /boards/arm64/intel_socfpga_agilex5_socdk/ @chongteikheng /boards/arm64/rcar_*/ @lorc @xakep-amatop -/boards/Kconfig @tejlmand @galak @nashif @nordicjm # All cmake related files -/cmake/ @tejlmand @nashif -/cmake/*/arcmwdt/ @abrodkin @evgeniy-paltsev @tejlmand -/CMakeLists.txt @tejlmand @nashif -/doc/ @carlescufi /doc/develop/tools/coccinelle.rst @himanshujha199640 @JuliaLawall /doc/services/device_mgmt/smp_protocol.rst @de-nordic @nordicjm /doc/services/device_mgmt/smp_groups/ @de-nordic @nordicjm /doc/services/sensing/ @lixuzha @ghu0510 @qianruh /doc/CMakeLists.txt @carlescufi /doc/_scripts/ @carlescufi -/doc/connectivity/bluetooth/ @alwa-nordic @jhedberg @Vudentz -/doc/connectivity/networking/conn_mgr @carlescufi @glarsennordic -/doc/build/dts/ @galak @mbolivar-ampere -/doc/build/sysbuild/ @tejlmand @nordicjm -/doc/hardware/peripherals/canbus/ @alexanderwachter @henrikbrixandersen -/doc/security/ @ceolin @d3zd3z -/drivers/debug/ @nashif /drivers/*/*sam4l* @nandojve /drivers/*/*cc13xx_cc26xx* @bwitherspoon /drivers/*/*gd32* @nandojve @@ -239,7 +161,6 @@ /drivers/*/*ifx_cat1* @ifyall @npal-cy /drivers/*/*neorv32* @henrikbrixandersen /drivers/*/*_s32* @manuargue -/drivers/adc/ @anangl /drivers/adc/adc_ads1x1x.c @XenuIsWatching /drivers/adc/adc_stm32.c @cybertale /drivers/adc/adc_rpi_pico.c @soburi @@ -252,16 +173,12 @@ /drivers/bbram/* @yperess @sjg20 @jackrosenthal /drivers/bluetooth/ @alwa-nordic @jhedberg @Vudentz /drivers/bluetooth/hci/hci_esp32.c @sylvioalves -/drivers/cache/ @carlocaione -/drivers/syscon/ @carlocaione @yperess -/drivers/can/ @alexanderwachter @henrikbrixandersen /drivers/can/*mcp2515* @karstenkoenig /drivers/can/*rcar* @aaillet /drivers/clock_control/*agilex* @siclim @gdengi /drivers/clock_control/*nrf* @nordic-krch /drivers/clock_control/*esp32* @extremegtx @sylvioalves /drivers/clock_control/*cpg_mssr* @aaillet -/drivers/counter/ @nordic-krch /drivers/console/ipm_console.c @finikorg /drivers/console/semihost_console.c @luozhongyao /drivers/console/jailhouse_debug_console.c @MrVan @@ -273,7 +190,6 @@ /drivers/crypto/*nrf_ecb* @maciekfabia @anangl /drivers/display/*rm68200* @mmahadevan108 /drivers/display/display_ili9342c.* @extremegtx -/drivers/dac/ @martinjaeger /drivers/dac/*ad56xx* @benediktibk /drivers/dac/dac_ad5592.c @bbilas /drivers/dai/ @kv2019i @marcinszkudlinski @abonislawski @@ -290,15 +206,11 @@ /drivers/dma/*intel_adsp* @teburd @abonislawski /drivers/dma/*rpi_pico* @soburi /drivers/dma/*xmc4xxx* @talih0 -/drivers/edac/ @finikorg -/drivers/eeprom/ @henrikbrixandersen /drivers/eeprom/eeprom_stm32.c @KwonTae-young /drivers/entropy/*b91* @andy-liu-telink /drivers/entropy/*bt_hci* @JordanYates /drivers/entropy/*rv32m1* @dleach02 /drivers/entropy/*litex* @mateusz-holenko @kgugala @pgielda -/drivers/espi/ @albertofloyd @franciscomunoz @sjvasanth1 -/drivers/ethernet/ @tbursztyka @jukkar /drivers/ethernet/*dwmac* @npitre /drivers/ethernet/*stm32* @Nukersson @lochej /drivers/ethernet/*w5500* @parthitce @@ -309,17 +221,13 @@ /drivers/ethernet/*lan865x* @lmajewski /drivers/ethernet/phy/ @rlubos @tbursztyka @arvinf @jukkar /drivers/ethernet/phy/*adin2111* @GeorgeCGV -/drivers/mdio/ @rlubos @tbursztyka @arvinf /drivers/mdio/*adin2111* @GeorgeCGV -/drivers/flash/ @nashif @de-nordic /drivers/flash/*stm32_qspi* @lmajewski /drivers/flash/*b91* @andy-liu-telink /drivers/flash/*cadence* @ngboonkhai /drivers/flash/*cc13xx_cc26xx* @pepe2k /drivers/flash/*nrf* @de-nordic /drivers/flash/*esp32* @sylvioalves -/drivers/fpga/ @tgorochowik @kgugala -/drivers/gpio/ @mnkp /drivers/gpio/*b91* @andy-liu-telink /drivers/gpio/*lmp90xxx* @henrikbrixandersen /drivers/gpio/*nct38xx* @MulinChao @ChiHuaL @@ -334,7 +242,6 @@ /drivers/gpio/*pcal64xxa* @benediktibk /drivers/gpio/gpio_altera_pio.c @shilinte /drivers/gpio/gpio_ad5592.c @bbilas -/drivers/hwinfo/ @alexanderwachter /drivers/i2c/i2c_common.c @sjg20 /drivers/i2c/i2c_emul.c @sjg20 /drivers/i2c/i2c_ite_enhance.c @GTLin08 @@ -349,7 +256,6 @@ /drivers/i2s/*litex* @mateusz-holenko @kgugala @pgielda /drivers/i2s/i2s_ll_stm32* @avisconti /drivers/i2s/*nrfx* @anangl -/drivers/i3c/ @dcpleung /drivers/i3c/i3c_cdns.c @XenuIsWatching /drivers/ieee802154/ @rlubos @tbursztyka @jukkar @fgrandel /drivers/ieee802154/*b91* @andy-liu-telink @@ -370,33 +276,22 @@ /drivers/ipm/ipm_stm32_hsem.c @cameled /drivers/ipm/ipm_esp32.c @uLipe /drivers/ipm/ipm_ivshmem.c @uLipe -/drivers/kscan/ @VenkatKotakonda @franciscomunoz @sjvasanth1 /drivers/kscan/*xec* @franciscomunoz @sjvasanth1 /drivers/kscan/*ft5336* @MaureenHelm /drivers/kscan/*ht16k33* @henrikbrixandersen -/drivers/led/ @Mani-Sadhasivam /drivers/led_strip/ @mbolivar-ampere -/drivers/lora/ @Mani-Sadhasivam -/drivers/mbox/ @carlocaione /drivers/mfd/mfd_ad5592.c @bbilas /drivers/mfd/mfd_max20335.c @bbilas -/drivers/misc/ @tejlmand /drivers/misc/ft8xx/ @hubertmis -/drivers/mm/ @dcpleung /drivers/modem/hl7800.c @rerickson1 /drivers/modem/simcom-sim7080.c @lgehreke /drivers/modem/simcom-sim7080.h @lgehreke /drivers/modem/Kconfig.hl7800 @rerickson1 /drivers/modem/Kconfig.simcom-sim7080 @lgehreke -/drivers/pcie/ @dcpleung @nashif @jhedberg -/drivers/peci/ @albertofloyd @franciscomunoz @sjvasanth1 -/drivers/pinctrl/ @gmarull /drivers/pinctrl/*esp32* @sylvioalves /drivers/pinctrl/*it8xxx2* @ite -/drivers/pm_cpu_ops/ @carlocaione @gdengi /drivers/pm_cpu_ops/psci_shell.c @nbalabak @gdengi /drivers/power_domain/ @ceolin -/drivers/ps2/ @franciscomunoz @sjvasanth1 /drivers/ps2/*xec* @franciscomunoz @sjvasanth1 /drivers/ps2/*npcx* @MulinChao @ChiHuaL /drivers/pwm/*b91* @andy-liu-telink @@ -418,10 +313,8 @@ /drivers/regulator/regulator_pca9420.c @danieldegrasse /drivers/regulator/regulator_rpi_pico.c @soburi /drivers/regulator/regulator_shell.c @danieldegrasse -/drivers/reset/ @andrei-edward-popa /drivers/reset/reset_intel_socfpga.c @nbalabak /drivers/reset/Kconfig.intel_socfpga @nbalabak -/drivers/sensor/ @MaureenHelm /drivers/sensor/ams_iAQcore/ @alexanderwachter /drivers/sensor/ens210/ @alexanderwachter /drivers/sensor/grow_r502a/ @DineshDK03 @@ -452,29 +345,19 @@ /drivers/serial/*numicro* @ssekar15 /drivers/serial/*apbuart* @julius-barendt /drivers/serial/*rcar* @aaillet -/drivers/serial/Kconfig.test @str4t0m -/drivers/serial/serial_test.c @str4t0m /drivers/serial/Kconfig.xen @lorc @firscity /drivers/serial/uart_hvc_xen.c @lorc @firscity /drivers/serial/uart_hvc_xen_consoleio.c @lorc @firscity /drivers/serial/Kconfig.it8xxx2 @GTLin08 /drivers/serial/uart_ite_it8xxx2.c @GTLin08 /drivers/serial/*intel_lw* @shilinte -/drivers/smbus/ @finikorg -/drivers/sip_svc/ @maheshraotm -/drivers/disk/ @jfischer-no /drivers/disk/sdmmc_sdhc.h @JunYangNXP /drivers/disk/sdmmc_stm32.c @anthonybrandon -/drivers/net/ @rlubos @tbursztyka @jukkar /drivers/ptp_clock/ @tbursztyka @jukkar -/drivers/spi/ @tbursztyka /drivers/spi/*b91* @andy-liu-telink /drivers/spi/spi_rv32m1_lpspi* @karstenkoenig /drivers/spi/*esp32* @sylvioalves /drivers/spi/*pl022* @soburi -/drivers/sdhc/ @danieldegrasse -/drivers/timer/*apic* @dcpleung @nashif -/drivers/timer/apic_tsc.c @andyross /drivers/timer/*arm_arch* @carlocaione /drivers/timer/*cortex_m_systick* @anangl /drivers/timer/*altera_avalon* @nashif @@ -494,10 +377,7 @@ /drivers/timer/*rv32m1_lptmr* @mbolivar /drivers/timer/*nrf_rtc* @anangl /drivers/timer/*hpet* @dcpleung -/drivers/usb/ @jfischer-no /drivers/usb/device/usb_dc_stm32.c @ydamigos @loicpoulain -/drivers/usb_c/ @sambhurst -/drivers/video/ @loicpoulain /drivers/i2c/*b91* @andy-liu-telink /drivers/i2c/i2c_ll_stm32* @ydamigos /drivers/i2c/i2c_rv32m1_lpi2c* @henrikbrixandersen @@ -505,7 +385,6 @@ /drivers/i2c/i2c_dw* @dcpleung /drivers/i2c/*tca954x* @kurddt /drivers/*/*xec* @franciscomunoz @albertofloyd @sjvasanth1 -/drivers/w1/ @str4t0m /drivers/watchdog/*gecko* @oanerer /drivers/watchdog/*sifive* @katsuster /drivers/watchdog/wdt_handlers.c @dcpleung @nashif @@ -516,12 +395,10 @@ /drivers/watchdog/*rpi_pico* @thedjnK /drivers/watchdog/*dw* @softwarecki /drivers/watchdog/*ifx* @sreeramIfx -/drivers/wifi/ @rlubos @tbursztyka @jukkar /drivers/wifi/esp_at/ @mniestroj /drivers/wifi/eswifi/ @loicpoulain @nandojve /drivers/wifi/winc1500/ @kludentwo /drivers/virtualization/ @tbursztyka -/drivers/xen/ @lorc @firscity /dts/arc/ @abrodkin @ruuddw @iriszzw @evgeniy-paltsev /dts/arm/acsip/ @NorthernDean /dts/arm/aspeed/ @aspeeddylan @@ -537,7 +414,6 @@ /dts/arm/gigadevice/ @nandojve /dts/arm/infineon/xmc4* @parthitce @ifyall @npal-cy /dts/arm/infineon/psoc6/ @ifyall @npal-cy -/dts/arm64/ @carlocaione /dts/arm64/armv8-r.dtsi @povergoing /dts/arm64/intel/*intel_socfpga* @siclim /dts/arm64/nxp/ @JiafeiPan @@ -564,7 +440,6 @@ /dts/arm/silabs/efm32pg1b* @rdmeneze /dts/arm/silabs/efr32mg21* @l-alfred /dts/arm/silabs/efr32fg13* @yonsch -/dts/riscv/ @kgugala @pgielda /dts/riscv/ite/ @ite /dts/riscv/microchip/microchip-miv.dtsi @galak /dts/riscv/openisa/rv32m1* @dleach02 @@ -577,13 +452,10 @@ /dts/arm/armv7-r.dtsi @bbolen @stephanosio /dts/arm/xilinx/ @bbolen @stephanosio /dts/arm/renesas/rcar/ @aaillet -/dts/x86/ @jhedberg /dts/xtensa/xtensa.dtsi @ydamigos /dts/xtensa/intel/ @dcpleung /dts/xtensa/espressif/ @sylvioalves /dts/xtensa/nxp/ @iuliana-prodan @dbaluta -/dts/sparc/ @julius-barendt -/dts/bindings/ @galak /dts/bindings/can/ @alexanderwachter @henrikbrixandersen /dts/bindings/i2c/zephyr*i2c-emul*.yaml @sjg20 /dts/bindings/adc/st*stm32-adc.yaml @cybertale @@ -615,7 +487,6 @@ /dts/bindings/ethernet/*gem.yaml @ibirnbaum /dts/bindings/auxdisplay/*pt6314.yaml @xingrz /dts/bindings/auxdisplay/* @thedjnK -/dts/posix/ @aescolar @daor-oti /dts/bindings/sensor/*bme680* @BoschSensortec /dts/bindings/sensor/*ina23* @bbilas /dts/bindings/sensor/st* @avisconti @@ -630,343 +501,3 @@ /dts/bindings/gpio/*ads114s0x* @benediktibk /dts/bindings/pwm/*max31790* @benediktibk /dts/bindings/dac/*ad56* @benediktibk -/dts/common/ @galak -/include/ @nashif @carlescufi @galak @MaureenHelm -/include/zephyr/drivers/*/*litex* @mateusz-holenko @kgugala @pgielda -/include/zephyr/drivers/adc.h @anangl -/include/zephyr/drivers/adc/ads114s0x.h @benediktibk -/include/zephyr/drivers/auxdisplay.h @thedjnK -/include/zephyr/drivers/can.h @alexanderwachter @henrikbrixandersen -/include/zephyr/drivers/can/ @alexanderwachter @henrikbrixandersen -/include/zephyr/drivers/counter.h @nordic-krch -/include/zephyr/drivers/dac.h @martinjaeger -/include/zephyr/drivers/espi.h @albertofloyd @franciscomunoz @sjvasanth1 -/include/zephyr/drivers/bluetooth/ @alwa-nordic @jhedberg @Vudentz -/include/zephyr/drivers/flash.h @nashif @carlescufi @galak @MaureenHelm @de-nordic -/include/zephyr/drivers/i2c_emul.h @sjg20 -/include/zephyr/drivers/i3c.h @dcpleung -/include/zephyr/drivers/i3c/ @dcpleung -/include/zephyr/drivers/led/ht16k33.h @henrikbrixandersen -/include/zephyr/drivers/interrupt_controller/ @dcpleung @nashif -/include/zephyr/drivers/interrupt_controller/gic.h @stephanosio -/include/zephyr/drivers/modem/hl7800.h @rerickson1 -/include/zephyr/drivers/pcie/ @dcpleung -/include/zephyr/drivers/hwinfo.h @alexanderwachter -/include/zephyr/drivers/led.h @Mani-Sadhasivam -/include/zephyr/drivers/led_strip.h @mbolivar-ampere -/include/zephyr/drivers/sensor.h @MaureenHelm -/include/zephyr/drivers/smbus.h @finikorg -/include/zephyr/drivers/spi.h @tbursztyka -/include/zephyr/drivers/sip_svc/ @maheshraotm -/include/zephyr/drivers/lora.h @Mani-Sadhasivam -/include/zephyr/drivers/peci.h @albertofloyd @franciscomunoz @sjvasanth1 -/include/zephyr/drivers/pm_cpu_ops.h @carlocaione -/include/zephyr/drivers/pm_cpu_ops/ @carlocaione -/include/zephyr/drivers/w1.h @str4t0m -/include/zephyr/drivers/pwm/max31790.h @benediktibk -/include/zephyr/app_memory/ @dcpleung -/include/zephyr/arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev -/include/zephyr/arch/arc/arch.h @abrodkin @ruuddw @evgeniy-paltsev -/include/zephyr/arch/arc/v2/irq.h @abrodkin @ruuddw @evgeniy-paltsev -/include/zephyr/arch/arm @MaureenHelm @galak @ioannisg -/include/zephyr/arch/arm/cortex_a_r/ @stephanosio -/include/zephyr/arch/arm64/ @carlocaione -/include/zephyr/arch/arm64/cortex_r/ @povergoing -/include/zephyr/arch/arm/irq.h @carlocaione -/include/zephyr/arch/mips/ @frantony -/include/zephyr/arch/nios2/ @nashif -/include/zephyr/arch/nios2/arch.h @nashif -/include/zephyr/arch/posix/ @aescolar @daor-oti -/include/zephyr/arch/riscv/ @kgugala @pgielda -/include/zephyr/arch/x86/ @jhedberg @dcpleung -/include/zephyr/arch/common/ @andyross @nashif -/include/zephyr/arch/xtensa/ @andyross @dcpleung -/include/zephyr/arch/sparc/ @julius-barendt -/include/zephyr/sys/atomic.h @andyross -/include/zephyr/bluetooth/ @alwa-nordic @jhedberg @Vudentz @sjanc -/include/zephyr/bluetooth/audio/ @jhedberg @Vudentz @Thalley -/include/zephyr/cache.h @carlocaione @andyross -/include/zephyr/canbus/ @alexanderwachter @henrikbrixandersen -/include/zephyr/tracing/ @nashif -/include/zephyr/debug/ @nashif -/include/zephyr/debug/coredump.h @dcpleung -/include/zephyr/debug/gdbstub.h @ceolin -/include/zephyr/device.h @tbursztyka @nashif -/include/zephyr/devicetree.h @galak -/include/zephyr/devicetree/can.h @henrikbrixandersen -/include/zephyr/dt-bindings/clock/kinetis_mcg.h @henrikbrixandersen -/include/zephyr/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen -/include/zephyr/dt-bindings/ethernet/xlnx_gem.h @ibirnbaum -/include/zephyr/dt-bindings/pcie/ @dcpleung -/include/zephyr/dt-bindings/pinctrl/esp* @sylvioalves -/include/zephyr/dt-bindings/pwm/*it8xxx2* @RuibinChang -/include/zephyr/dt-bindings/usb/usb.h @galak -/include/zephyr/dt-bindings/adc/ads114s0x_adc.h @benediktibk -/include/zephyr/drivers/emul.h @sjg20 -/include/zephyr/data/ @d3zd3z -/include/zephyr/fs/ @nashif @de-nordic -/include/zephyr/init.h @nashif @andyross -/include/zephyr/irq.h @dcpleung @nashif @andyross -/include/zephyr/irq_offload.h @dcpleung @nashif @andyross -/include/zephyr/kernel.h @dcpleung @nashif @andyross -/include/zephyr/kernel_version.h @dcpleung @nashif @andyross -/include/zephyr/linker/app_smem*.ld @dcpleung @nashif -/include/zephyr/linker/ @dcpleung @nashif @andyross -/include/zephyr/logging/ @nordic-krch -/include/zephyr/lorawan/lorawan.h @Mani-Sadhasivam -/include/zephyr/mgmt/osdp.h @sidcha -/include/zephyr/mgmt/mcumgr/ @nordicjm -/include/zephyr/net/ @rlubos @tbursztyka @jukkar -/include/zephyr/net/buf.h @jhedberg @tbursztyka @rlubos @jukkar -/include/zephyr/net/coap*.h @rlubos -/include/zephyr/net/conn_mgr*.h @rlubos @glarsennordic @jukkar -/include/zephyr/net/gptp.h @rlubos @jukkar @fgrandel -/include/zephyr/net/ieee802154*.h @rlubos @tbursztyka @jukkar @fgrandel -/include/zephyr/net/lwm2m*.h @rlubos -/include/zephyr/net/mqtt.h @rlubos -/include/zephyr/net/mqtt_sn.h @rlubos @BeckmaR -/include/zephyr/net/net_pkt_filter.h @npitre -/include/zephyr/posix/ @cfreidt -/include/zephyr/pm/pm.h @nashif @ceolin -/include/zephyr/drivers/ptp_clock.h @tbursztyka @jukkar -/include/zephyr/rtio/ @teburd -/include/zephyr/sensing/ @lixuzha @ghu0510 @qianruh -/include/zephyr/shared_irq.h @dcpleung @nashif @andyross -/include/zephyr/shell/ @jakub-uC @nordic-krch -/include/zephyr/shell/shell_mqtt.h @ycsin -/include/zephyr/sw_isr_table.h @dcpleung @nashif @andyross -/include/zephyr/sd/ @danieldegrasse -/include/zephyr/sip_svc/ @maheshraotm -/include/zephyr/sys_clock.h @dcpleung @nashif @andyross -/include/zephyr/sys/sys_io.h @dcpleung @nashif @andyross -/include/zephyr/sys/kobject.h @dcpleung @nashif -/include/zephyr/toolchain.h @dcpleung @andyross @nashif -/include/zephyr/toolchain/ @dcpleung @nashif @andyross -/include/zephyr/zephyr.h @dcpleung @nashif @andyross -/kernel/ @dcpleung @nashif @andyross -/lib/cpp/ @stephanosio -/lib/smf/ @sambhurst -/lib/util/ @carlescufi @jakub-uC -/lib/util/fnmatch/ @carlescufi @jakub-uC -/lib/open-amp/ @arnopo -/lib/os/ @dcpleung @nashif @andyross -/lib/os/cbprintf_packaged.c @npitre -/lib/os/json.c @d3zd3z -/lib/posix/ @cfriedt -/lib/posix/getopt/ @jakub-uC -/subsys/portability/ @nashif -/subsys/sensing/ @lixuzha @ghu0510 @qianruh -/lib/libc/ @nashif -/lib/libc/arcmwdt/ @abrodkin @ruuddw @evgeniy-paltsev -/misc/ @tejlmand -/modules/ @nashif -/modules/canopennode/ @henrikbrixandersen -/modules/mbedtls/ @ceolin @d3zd3z -/modules/hal_gigadevice/ @nandojve -/modules/hal_nordic/nrf_802154/ @jciupis -/modules/trusted-firmware-m/ @microbuilder -/kernel/device.c @andyross @nashif -/kernel/idle.c @andyross @nashif -/samples/ @nashif -/samples/application_development/sysbuild/ @tejlmand @nordicjm -/samples/basic/minimal/ @carlescufi -/samples/basic/servo_motor/boards/*microbit* @jhe -/samples/bluetooth/ @jhedberg @Vudentz @alwa-nordic @sjanc -/samples/compression/ @Navin-Sankar -/samples/drivers/can/ @alexanderwachter @henrikbrixandersen -/samples/drivers/clock_control_litex/ @mateusz-holenko @kgugala @pgielda -/samples/drivers/eeprom/ @henrikbrixandersen -/samples/drivers/ht16k33/ @henrikbrixandersen -/samples/drivers/lora/ @Mani-Sadhasivam -/samples/drivers/smbus/ @finikorg -/samples/subsys/lorawan/ @Mani-Sadhasivam -/samples/modules/canopennode/ @henrikbrixandersen -/samples/net/ @rlubos @tbursztyka @jukkar -/samples/net/cloud/tagoio_http_post/ @nandojve -/samples/net/dns_resolve/ @rlubos @tbursztyka @jukkar -/samples/net/gptp/ @rlubos @jukkar @fgrandel -/samples/net/lwm2m_client/ @rlubos -/samples/net/mqtt_publisher/ @rlubos -/samples/net/mqtt_sn_publisher/ @rlubos @BeckmaR -/samples/net/sockets/coap_*/ @rlubos -/samples/net/sockets/ @rlubos @tbursztyka @jukkar -/samples/sensor/ @MaureenHelm -/samples/shields/ @avisconti -/samples/subsys/ipc/ipc_service/icmsg @emob-nordic -/samples/subsys/logging/ @nordic-krch @jakub-uC -/samples/subsys/logging/syst/ @dcpleung -/samples/subsys/shell/ @jakub-uC @nordic-krch @gdengi -/samples/subsys/sip_svc/ @maheshraotm -/samples/subsys/mgmt/mcumgr/ @de-nordic @nordicjm -/samples/subsys/mgmt/updatehub/ @nandojve @otavio -/samples/subsys/mgmt/osdp/ @sidcha -/samples/subsys/usb/ @jfischer-no -/samples/subsys/usb_c/ @sambhurst -/samples/subsys/pm/ @nashif @ceolin -/samples/subsys/sensing/ @lixuzha @ghu0510 @qianruh -/samples/tfm_integration/ @microbuilder -/samples/userspace/ @dcpleung @nashif -/scripts/release/bug_bash.py @cfriedt -/scripts/coccicheck @himanshujha199640 @JuliaLawall -/scripts/coccinelle/ @himanshujha199640 @JuliaLawall -/scripts/coredump/ @dcpleung -/scripts/footprint/ @nashif -/scripts/kconfig/ @ulfalizer -/scripts/logging/dictionary/ @dcpleung -/scripts/native_simulator/ @aescolar -/scripts/pylib/twister/expr_parser.py @nashif -/scripts/schemas/twister/ @nashif -/scripts/build/gen_app_partitions.py @dcpleung @nashif -scripts/build/gen_image_info.py @tejlmand -/scripts/get_maintainer.py @nashif -/scripts/dts/ @mbolivar-ampere @galak -/scripts/release/ @nashif -/scripts/ci/ @nashif -/scripts/ci/check_compliance.py @nashif @carlescufi -/arch/x86/gen_gdt.py @dcpleung @nashif -/arch/x86/gen_idt.py @dcpleung @nashif -/scripts/build/gen_kobject_list.py @dcpleung @nashif -/scripts/build/gen_kobject_placeholders.py @dcpleung -/scripts/build/gen_syscalls.py @dcpleung @nashif -/scripts/list_boards.py @mbolivar-ampere -/scripts/build/process_gperf.py @dcpleung @nashif -/scripts/build/gen_relocate_app.py @dcpleung -/scripts/generate_usb_vif/ @madhurimaparuchuri -/scripts/requirements*.txt @mbolivar-ampere @galak @nashif -/scripts/tests/build/test_subfolder_list.py @rmstoi -/scripts/tracing/ @nashif -/scripts/pylib/twister/ @nashif -/scripts/twister @nashif -/scripts/series-push-hook.sh @erwango -/scripts/utils/pinctrl_nrf_migrate.py @gmarull -/scripts/utils/migrate_mcumgr_kconfigs.py @de-nordic -/scripts/west_commands/ @mbolivar-ampere -/scripts/west_commands/blobs.py @carlescufi -/scripts/west_commands/fetchers/ @carlescufi -/scripts/west_commands/runners/gd32isp.py @mbolivar-ampere @nandojve -/scripts/west_commands/tests/test_gd32isp.py @mbolivar-ampere @nandojve -/scripts/west-commands.yml @mbolivar-ampere -/scripts/zephyr_module.py @tejlmand -/scripts/build/uf2conv.py @petejohanson -/scripts/build/user_wordsize.py @cfriedt -/scripts/valgrind.supp @aescolar @daor-oti -/share/sysbuild/ @tejlmand @nordicjm -/share/zephyr-package/ @tejlmand -/share/zephyrunittest-package/ @tejlmand -/subsys/bluetooth/ @alwa-nordic @jhedberg @Vudentz -/subsys/bluetooth/audio/ @jhedberg @Vudentz @Thalley @sjanc -/subsys/bluetooth/controller/ @carlescufi @cvinayak @thoh-ot @kruithofa -/subsys/bluetooth/host/ @alwa-nordic @jhedberg @Vudentz @sjanc -/subsys/bluetooth/mesh/ @jhedberg @PavelVPV @Vudentz @LingaoM -/subsys/canbus/ @alexanderwachter @henrikbrixandersen -/subsys/debug/ @nashif -/subsys/debug/coredump/ @dcpleung -/subsys/debug/gdbstub/ @ceolin -/subsys/debug/gdbstub.c @ceolin -/subsys/dfu/ @de-nordic @nordicjm -/subsys/disk/ @jfischer-no -/subsys/dsp/ @yperess -/subsys/tracing/ @nashif -/subsys/debug/asan_hacks.c @aescolar @daor-oti -/subsys/demand_paging/ @dcpleung @nashif -/subsys/emul/ @sjg20 -/subsys/fb/ @jfischer-no -/subsys/fs/ @nashif -/subsys/fs/nvs/ @Laczen -/subsys/ipc/ @carlocaione -/subsys/ipc/ipc_service/*/*icmsg* @emob-nordic -/subsys/jwt/ @d3zd3z -/subsys/logging/ @nordic-krch -/subsys/logging/backends/log_backend_net.c @nordic-krch @rlubos @jukkar -/subsys/lorawan/ @Mani-Sadhasivam -/subsys/mgmt/ec_host_cmd/ @jettr -/subsys/mgmt/mcumgr/ @carlescufi @de-nordic @nordicjm -/subsys/mgmt/hawkbit/ @Navin-Sankar -/subsys/mgmt/updatehub/ @nandojve @otavio -/subsys/mgmt/osdp/ @sidcha -/subsys/modbus/ @jfischer-no -/subsys/net/buf.c @jhedberg @tbursztyka @rlubos @jukkar -/subsys/net/conn_mgr/ @rlubos @glarsennordic @jukkar -/subsys/net/ip/ @rlubos @tbursztyka @jukkar -/subsys/net/lib/ @rlubos @tbursztyka @jukkar -/subsys/net/lib/dns/ @rlubos @tbursztyka @cfriedt @jukkar -/subsys/net/lib/lwm2m/ @rlubos -/subsys/net/lib/config/ @rlubos @tbursztyka @jukkar -/subsys/net/lib/mqtt/ @rlubos -/subsys/net/lib/mqtt_sn/ @rlubos @BeckmaR -/subsys/net/lib/coap/ @rlubos -/subsys/net/lib/sockets/socketpair.c @cfriedt -/subsys/net/lib/sockets/ @rlubos @tbursztyka @jukkar -/subsys/net/lib/tls_credentials/ @rlubos -/subsys/net/l2/ @rlubos @tbursztyka @jukkar -/subsys/net/l2/ethernet/gptp/ @rlubos @jukkar @fgrandel -/subsys/net/l2/ieee802154/ @rlubos @tbursztyka @jukkar @fgrandel -/subsys/net/l2/canbus/ @alexanderwachter -/subsys/net/pkt_filter/ @npitre -/subsys/net/*/openthread/ @rlubos -/subsys/pm/ @nashif @ceolin -/subsys/random/ @dleach02 -/subsys/shell/ @jakub-uC @nordic-krch -/subsys/shell/backends/shell_mqtt.c @ycsin -/subsys/sd/ @danieldegrasse -/subsys/sip_svc/ @maheshraotm -/subsys/task_wdt/ @martinjaeger -/subsys/testsuite/ @nashif -/subsys/testsuite/ztest/*/ztress* @nordic-krch -/subsys/timing/ @nashif @dcpleung -/subsys/usb/ @jfischer-no -/subsys/usb/usb_c/ @sambhurst -/tests/ @nashif -/tests/arch/arm/ @ioannisg @stephanosio -/tests/benchmarks/cmsis_dsp/ @stephanosio -/tests/boards/native_posix/ @aescolar @daor-oti -/tests/bluetooth/ @alwa-nordic @jhedberg @Vudentz @sjanc -/tests/bluetooth/audio/ @jhedberg @Vudentz @wopu-ot @Thalley -/tests/bluetooth/controller/ @cvinayak @thoh-ot @kruithofa @erbr-ot @sjanc @ppryga -/tests/bsim/bluetooth/ @alwa-nordic @jhedberg @Vudentz @wopu-ot -/tests/bsim/bluetooth/audio/ @jhedberg @Vudentz @wopu-ot @Thalley -/tests/bsim/bluetooth/mesh/ @jhedberg @Vudentz @wopu-ot @PavelVPV -/tests/bluetooth/mesh_shell/ @jhedberg @Vudentz @sjanc @PavelVPV -/tests/bluetooth/tester/ @alwa-nordic @jhedberg @Vudentz @sjanc -/tests/posix/ @cfriedt -/tests/crypto/ @ceolin -/tests/crypto/mbedtls/ @nashif @ceolin @d3zd3z -/tests/drivers/can/ @alexanderwachter @henrikbrixandersen -/tests/drivers/counter/ @nordic-krch -/tests/drivers/eeprom/ @henrikbrixandersen @sjg20 -/tests/drivers/flash_simulator/ @de-nordic -/tests/drivers/gpio/ @mnkp -/tests/drivers/hwinfo/ @alexanderwachter -/tests/drivers/smbus/ @finikorg -/tests/drivers/spi/ @tbursztyka -/tests/drivers/uart/uart_async_api/ @anangl -/tests/drivers/w1/ @str4t0m -/tests/kernel/ @dcpleung @andyross @nashif -/tests/lib/ @nashif -/tests/lib/cmsis_dsp/ @stephanosio -/tests/lib/json/ @d3zd3z -/tests/net/ @rlubos @tbursztyka @jukkar -/tests/net/buf/ @jhedberg @tbursztyka @jukkar -/tests/net/conn_mgr_monitor/ @rlubos @glarsennordic @jukkar -/tests/net/conn_mgr_conn/ @rlubos @glarsennordic @jukkar -/tests/net/ieee802154/l2/ @rlubos @tbursztyka @jukkar @fgrandel -/tests/net/lib/ @rlubos @tbursztyka @jukkar -/tests/net/lib/http_header_fields/ @rlubos @tbursztyka @jukkar -/tests/net/lib/mqtt_packet/ @rlubos -/tests/net/lib/mqtt_sn_packet/ @rlubos @BeckmaR -/tests/net/lib/mqtt_sn_client/ @rlubos @BeckmaR -/tests/net/lib/coap/ @rlubos -/tests/net/npf/ @npitre -/tests/net/socket/socketpair/ @cfriedt -/tests/net/socket/ @rlubos @tbursztyka @jukkar -/tests/subsys/debug/coredump/ @dcpleung -/tests/subsys/fs/ @nashif @de-nordic -/tests/subsys/jwt/ @d3zd3z -/tests/subsys/mgmt/mcumgr/ @de-nordic @nordicjm -/tests/subsys/sd/ @danieldegrasse -/tests/subsys/rtio/ @teburd -/tests/subsys/shell/ @jakub-uC @nordic-krch -# Get all docs reviewed -*.rst @nashif -/doc/kernel/ @andyross @nashif -*posix*.rst @aescolar @daor-oti From 538abf3332e411de916670f538445385b2aff4a4 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 15 Nov 2023 11:40:00 -0500 Subject: [PATCH 3738/4498] doc: clarify role of CODEOWNERS and MAINTAINERS files Change docs to use MAINTAINERS file as the main file for managing code areas and 'ownership'. Signed-off-by: Anas Nashif --- CODEOWNERS | 7 ++++++- doc/contribute/guidelines.rst | 4 ++-- doc/project/dev_env_and_tools.rst | 9 +++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index ab9197825c5..54f2b65933a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -11,7 +11,12 @@ # add others as needed. # Do not use wildcard on all source yet -# * @galak @nashif +# +# +++++++++++ NOTE ++++++++++++++++ +# +# Please use the MAINTAINERS file to add yourself in an area or to add a new +# component or code. This file is going to be deprecated and currently only had +# entries that are not covered by the MAINTAINERS file. /soc/arm/aspeed/ @aspeeddylan /soc/arm/atmel_sam/common/*_sam4l_*.c @nandojve diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index ac88fa768ab..b3dd735dd42 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -651,8 +651,8 @@ workflow here: request for the ``main`` branch. The title and message from your commit message should appear as well. -#. GitHub will assign one or more suggested reviewers (based on the - CODEOWNERS file in the repo). If you are a project member, you can +#. A bot will assign one or more suggested reviewers (based on the + MAINTAINERS file in the repo). If you are a project member, you can select additional reviewers now too. #. Click on the submit button and your pull request is sent and awaits diff --git a/doc/project/dev_env_and_tools.rst b/doc/project/dev_env_and_tools.rst index 37356ec3232..8269e891d43 100644 --- a/doc/project/dev_env_and_tools.rst +++ b/doc/project/dev_env_and_tools.rst @@ -20,10 +20,11 @@ and linked to any relevant :ref:`bug or feature tracking issues` The Zephyr project uses GitHub for code reviews and Git tree management. When submitting a change or an enhancement to any Zephyr component, a developer -should use GitHub. GitHub automatically assigns a responsible reviewer on a -component basis, as defined in the :zephyr_file:`CODEOWNERS` file stored with the code -tree in the Zephyr project repository. A limited set of release managers are -allowed to merge a pull request into the main branch once reviews are complete. +should use GitHub. GitHub Actions automatically assigns a responsible reviewer +on a component basis, as defined in the :zephyr_file:`MAINTAINERS.yml` file +stored with the code tree in the Zephyr project repository. A limited set of +release managers are allowed to merge a pull request into the main branch once +reviews are complete. .. _review_time: From a48e68441ba47d179ab3a04f673d103c8d7ef305 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 14 Nov 2023 05:20:47 +0000 Subject: [PATCH 3739/4498] logging: Remove syscall for z_log_msg_runtime_vcreate This syscall is completely problematic in userspace, it does not check ANY parameter that is given and it uses variadic argument that are not copied / checked before being used in the implementation, instead it just pass a pointer to user stack with unknown data is blindly consumed by the kernel. Signed-off-by: Flavio Ceolin --- include/zephyr/logging/log_msg.h | 10 +++++----- subsys/logging/log_msg.c | 14 +------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index c35a69d85cc..fabc7a16b0c 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -679,11 +679,11 @@ __syscall void z_log_msg_static_create(const void *source, * * @param ap Variable list of string arguments. */ -__syscall void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, - uint8_t level, const void *data, - size_t dlen, uint32_t package_flags, - const char *fmt, - va_list ap); +void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, + uint8_t level, const void *data, + size_t dlen, uint32_t package_flags, + const char *fmt, + va_list ap); /** @brief Create message at runtime. * diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index a28f1ddc10a..8023cefbf8c 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -281,7 +281,7 @@ static inline void z_vrfy_z_log_msg_static_create(const void *source, #include #endif -void z_impl_z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, +void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, uint8_t level, const void *data, size_t dlen, uint32_t package_flags, const char *fmt, va_list ap) { @@ -330,15 +330,3 @@ void z_impl_z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source, z_log_msg_finalize(msg, source, desc, data); } } - -#ifdef CONFIG_USERSPACE -static inline void z_vrfy_z_log_msg_runtime_vcreate(uint8_t domain_id, - const void *source, - uint8_t level, const void *data, size_t dlen, - uint32_t package_flags, const char *fmt, va_list ap) -{ - return z_impl_z_log_msg_runtime_vcreate(domain_id, source, level, data, - dlen, package_flags, fmt, ap); -} -#include -#endif From d027d26298ba2dd7dd8924d5de84cf706633e997 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 14 Nov 2023 05:12:06 +0000 Subject: [PATCH 3740/4498] logging: LOG_PRINTK disabled in userspace LOG_PRINTK needs to run in supervisor mode and since there is no syscall that allows it to be called from userspace, this option has to be disabled when userspace is selected. Signed-off-by: Flavio Ceolin --- subsys/logging/Kconfig.processing | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/logging/Kconfig.processing b/subsys/logging/Kconfig.processing index 9051b6e3b46..bc553aa239c 100644 --- a/subsys/logging/Kconfig.processing +++ b/subsys/logging/Kconfig.processing @@ -7,6 +7,7 @@ if !LOG_MODE_MINIMAL config LOG_PRINTK bool "Process printk messages" + depends on !USERSPACE default y if PRINTK help If enabled, printk messages are redirected to the logging subsystem. From df7114456e17c8ff208f8f315286cea586d1a3c7 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 16 Nov 2023 12:05:04 +0100 Subject: [PATCH 3741/4498] tfm: Change default TF-M model for profile small to match profile conf Change the default TF-M model for small profile to match the configuration set in the profile small configuration file. Otherwise we would be overriding the profile default. Signed-off-by: Joakim Andersson --- modules/trusted-firmware-m/Kconfig.tfm | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 2a5edb64343..d29b7093de0 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -302,6 +302,7 @@ endif # TFM_BL2 choice TFM_MODEL prompt "TF-M Firmware Framework model" + default TFM_SFN if TFM_PROFILE_TYPE_SMALL default TFM_IPC help The Firmware Framework M (FF-M) provides different programming models From ab08f34fd939a06daa5712e2a03e4b7d3b8da358 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Tue, 14 Nov 2023 12:00:30 +0800 Subject: [PATCH 3742/4498] Bluetooth: Mesh: Make bt_mesh_model as rodata Since model struct most of member should not change at run time, so mark as const will be suitable and safely. Signed-off-by: Lingao Meng --- .../bluetooth/api/mesh/blob_cli.rst | 2 +- .../bluetooth/api/mesh/blob_srv.rst | 2 +- include/zephyr/bluetooth/mesh/access.h | 89 ++++--- include/zephyr/bluetooth/mesh/blob_cli.h | 2 +- include/zephyr/bluetooth/mesh/blob_srv.h | 2 +- include/zephyr/bluetooth/mesh/cfg_cli.h | 2 +- include/zephyr/bluetooth/mesh/dfd_srv.h | 2 +- include/zephyr/bluetooth/mesh/dfu_cli.h | 2 +- include/zephyr/bluetooth/mesh/dfu_srv.h | 2 +- include/zephyr/bluetooth/mesh/health_cli.h | 2 +- include/zephyr/bluetooth/mesh/health_srv.h | 14 +- .../bluetooth/mesh/large_comp_data_cli.h | 2 +- .../zephyr/bluetooth/mesh/od_priv_proxy_cli.h | 2 +- .../zephyr/bluetooth/mesh/priv_beacon_cli.h | 2 +- include/zephyr/bluetooth/mesh/rpr_cli.h | 2 +- include/zephyr/bluetooth/mesh/sar_cfg_cli.h | 2 +- .../zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h | 2 +- include/zephyr/bluetooth/testing.h | 4 +- samples/bluetooth/mesh/src/main.c | 16 +- samples/bluetooth/mesh_demo/src/main.c | 10 +- samples/bluetooth/mesh_provisioner/src/main.c | 2 +- samples/boards/nrf/mesh/onoff-app/src/main.c | 34 +-- .../src/mesh/device_composition.c | 168 ++++++------ .../src/mesh/device_composition.h | 20 +- .../boards/reel_board/mesh_badge/src/mesh.c | 34 +-- subsys/bluetooth/host/testing.c | 4 +- subsys/bluetooth/host/testing.h | 4 +- subsys/bluetooth/mesh/access.c | 251 +++++++++--------- subsys/bluetooth/mesh/access.h | 22 +- subsys/bluetooth/mesh/blob_cli.c | 24 +- subsys/bluetooth/mesh/blob_srv.c | 44 +-- subsys/bluetooth/mesh/cfg_cli.c | 58 ++-- subsys/bluetooth/mesh/cfg_srv.c | 182 ++++++------- subsys/bluetooth/mesh/dfd_srv.c | 76 +++--- subsys/bluetooth/mesh/dfu_cli.c | 27 +- subsys/bluetooth/mesh/dfu_srv.c | 36 +-- subsys/bluetooth/mesh/foundation.h | 2 +- subsys/bluetooth/mesh/health_cli.c | 24 +- subsys/bluetooth/mesh/health_srv.c | 56 ++-- subsys/bluetooth/mesh/large_comp_data_cli.c | 12 +- subsys/bluetooth/mesh/large_comp_data_srv.c | 12 +- subsys/bluetooth/mesh/main.c | 6 +- subsys/bluetooth/mesh/msg.c | 4 +- subsys/bluetooth/mesh/msg.h | 4 +- subsys/bluetooth/mesh/od_priv_proxy_cli.c | 8 +- subsys/bluetooth/mesh/od_priv_proxy_srv.c | 22 +- subsys/bluetooth/mesh/op_agg.h | 4 +- subsys/bluetooth/mesh/op_agg_cli.c | 8 +- subsys/bluetooth/mesh/op_agg_srv.c | 8 +- subsys/bluetooth/mesh/priv_beacon_cli.c | 12 +- subsys/bluetooth/mesh/priv_beacon_srv.c | 28 +- subsys/bluetooth/mesh/rpr_cli.c | 40 +-- subsys/bluetooth/mesh/rpr_srv.c | 28 +- subsys/bluetooth/mesh/sar_cfg_cli.c | 16 +- subsys/bluetooth/mesh/sar_cfg_srv.c | 27 +- subsys/bluetooth/mesh/shell/blob.c | 20 +- subsys/bluetooth/mesh/shell/dfd.c | 22 +- subsys/bluetooth/mesh/shell/dfu.c | 30 +-- subsys/bluetooth/mesh/shell/health.c | 16 +- subsys/bluetooth/mesh/shell/rpr.c | 22 +- subsys/bluetooth/mesh/shell/shell.c | 12 +- subsys/bluetooth/mesh/shell/utils.c | 10 +- subsys/bluetooth/mesh/shell/utils.h | 4 +- subsys/bluetooth/mesh/sol_pdu_rpl_cli.c | 6 +- subsys/bluetooth/mesh/sol_pdu_rpl_srv.c | 10 +- tests/bluetooth/mesh/basic/src/main.c | 14 +- tests/bluetooth/mesh_shell/src/main.c | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 20 +- tests/bsim/bluetooth/mesh/src/mesh_test.c | 24 +- tests/bsim/bluetooth/mesh/src/mesh_test.h | 6 +- tests/bsim/bluetooth/mesh/src/test_access.c | 48 ++-- tests/bsim/bluetooth/mesh/src/test_blob.c | 4 +- tests/bsim/bluetooth/mesh/src/test_cdp1.c | 26 +- tests/bsim/bluetooth/mesh/src/test_dfu.c | 8 +- tests/bsim/bluetooth/mesh/src/test_lcd.c | 13 +- tests/bsim/bluetooth/mesh/src/test_op_agg.c | 7 +- .../bluetooth/mesh/src/test_persistence.c | 8 +- .../bsim/bluetooth/mesh/src/test_provision.c | 6 +- tests/bsim/bluetooth/mesh/src/test_sar.c | 8 +- 79 files changed, 929 insertions(+), 887 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst index 2232153f549..25b90c281c4 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst @@ -25,7 +25,7 @@ The BLOB Transfer Client is instantiated on an element with a set of event handl .cb = &blob_cb, }; - static struct bt_mesh_model models[] = { + static const struct bt_mesh_model models[] = { BT_MESH_MODEL_BLOB_CLI(&blob_cli), }; diff --git a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst index a76ac34d6fb..918b9493ff9 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst @@ -35,7 +35,7 @@ The BLOB Transfer Server is instantiated on an element with a set of event handl .cb = &blob_cb, }; - static struct bt_mesh_model models[] = { + static const struct bt_mesh_model models[] = { BT_MESH_MODEL_BLOB_SRV(&blob_srv), }; diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 5272abe5645..aa623549814 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -30,6 +30,13 @@ #define BT_MESH_MODEL_UUIDS_UNASSIGNED() #endif +#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS +#define BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .next = (const struct bt_mesh_model *[]){ NULL }, +#else +#define BT_MESH_MODEL_NEXT_UNASSIGNED() +#endif + /** * @brief Access layer * @defgroup bt_mesh_access Access layer @@ -159,9 +166,9 @@ struct bt_mesh_elem { const uint8_t vnd_model_count; /** The list of SIG models in this element */ - struct bt_mesh_model * const models; + const struct bt_mesh_model * const models; /** The list of vendor models in this element */ - struct bt_mesh_model * const vnd_models; + const struct bt_mesh_model * const vnd_models; }; /** @@ -370,7 +377,7 @@ struct bt_mesh_model_op { * * @return Zero on success or (negative) error code otherwise. */ - int (*const func)(struct bt_mesh_model *model, + int (*const func)(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); }; @@ -403,7 +410,7 @@ struct bt_mesh_model_op { * This macro uses compound literal feature of C99 standard and thus is available only from C, * not C++. */ -#define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){}) +#define BT_MESH_MODEL_NONE ((const struct bt_mesh_model []){}) /** * @brief Composition data SIG model entry with callback functions @@ -425,6 +432,9 @@ struct bt_mesh_model_op { #define BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, _keys, _grps, _cb) \ { \ .id = (_id), \ + .elem_idx = (uint8_t []) { 0 }, \ + .mod_idx = (uint8_t []) { 0 }, \ + .flags = (uint16_t []) { 0 }, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \ .keys_cnt = _keys, \ @@ -433,7 +443,8 @@ struct bt_mesh_model_op { BT_MESH_MODEL_UUIDS_UNASSIGNED() \ .op = _op, \ .cb = _cb, \ - .user_data = _user_data, \ + BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .user_data = (void *[]){ _user_data }, \ } /** @@ -458,6 +469,9 @@ struct bt_mesh_model_op { { \ .vnd.company = (_company), \ .vnd.id = (_id), \ + .elem_idx = (uint8_t []) { 0 }, \ + .mod_idx = (uint8_t []) { 0 }, \ + .flags = (uint16_t []) { 0 }, \ .op = _op, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \ @@ -465,7 +479,8 @@ struct bt_mesh_model_op { .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \ .groups_cnt = _grps, \ BT_MESH_MODEL_UUIDS_UNASSIGNED() \ - .user_data = _user_data, \ + BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .user_data = (void *[]){ _user_data }, \ .cb = _cb, \ } @@ -505,6 +520,9 @@ struct bt_mesh_model_op { #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \ { \ .id = (_id), \ + .elem_idx = (uint8_t []) { 0 }, \ + .mod_idx = (uint8_t []) { 0 }, \ + .flags = (uint16_t []) { 0 }, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \ .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \ @@ -513,7 +531,8 @@ struct bt_mesh_model_op { BT_MESH_MODEL_UUIDS_UNASSIGNED() \ .op = _op, \ .cb = _cb, \ - .user_data = _user_data, \ + BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .user_data = (void *[]){ _user_data }, \ .metadata = _metadata, \ } #else @@ -559,6 +578,9 @@ struct bt_mesh_model_op { { \ .vnd.company = (_company), \ .vnd.id = (_id), \ + .elem_idx = (uint8_t []) { 0 }, \ + .mod_idx = (uint8_t []) { 0 }, \ + .flags = (uint16_t []) { 0 }, \ .op = _op, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \ @@ -566,7 +588,8 @@ struct bt_mesh_model_op { .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \ .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \ BT_MESH_MODEL_UUIDS_UNASSIGNED() \ - .user_data = _user_data, \ + BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .user_data = (void *[]){ _user_data }, \ .cb = _cb, \ .metadata = _metadata, \ } @@ -690,7 +713,7 @@ struct bt_mesh_model_op { */ struct bt_mesh_model_pub { /** The model the context belongs to. Initialized by the stack. */ - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; uint16_t addr; /**< Publish Address. */ const uint8_t *uuid; /**< Label UUID if Publish Address is Virtual Address. */ @@ -735,7 +758,7 @@ struct bt_mesh_model_pub { * * @return Zero on success or (negative) error code otherwise. */ - int (*update)(struct bt_mesh_model *mod); + int (*update)(const struct bt_mesh_model *mod); /** Publish Period Timer. Only for stack-internal use. */ struct k_work_delayable timer; @@ -805,7 +828,7 @@ struct bt_mesh_model_cb { * * @return 0 on success, error otherwise. */ - int (*const settings_set)(struct bt_mesh_model *model, + int (*const settings_set)(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg); @@ -821,7 +844,7 @@ struct bt_mesh_model_cb { * * @return 0 on success, error otherwise. */ - int (*const start)(struct bt_mesh_model *model); + int (*const start)(const struct bt_mesh_model *model); /** @brief Model init callback. * @@ -835,7 +858,7 @@ struct bt_mesh_model_cb { * * @return 0 on success, error otherwise. */ - int (*const init)(struct bt_mesh_model *model); + int (*const init)(const struct bt_mesh_model *model); /** @brief Model reset callback. * @@ -847,7 +870,7 @@ struct bt_mesh_model_cb { * * @param model Model this callback belongs to. */ - void (*const reset)(struct bt_mesh_model *model); + void (*const reset)(const struct bt_mesh_model *model); /** @brief Callback used to store pending model's user data. * @@ -857,7 +880,7 @@ struct bt_mesh_model_cb { * * @param model Model this callback belongs to. */ - void (*const pending_store)(struct bt_mesh_model *model); + void (*const pending_store)(const struct bt_mesh_model *model); }; /** Vendor model ID */ @@ -878,9 +901,9 @@ struct bt_mesh_model { }; /* Internal information, mainly for persistent storage */ - uint8_t elem_idx; /* Belongs to Nth element */ - uint8_t mod_idx; /* Is the Nth model in the element */ - uint16_t flags; /* Model flags for internal bookkeeping */ + uint8_t * const elem_idx; /* Belongs to Nth element */ + uint8_t * const mod_idx; /* Is the Nth model in the element */ + uint16_t * const flags; /* Model flags for internal bookkeeping */ /** Model Publication */ struct bt_mesh_model_pub * const pub; @@ -906,7 +929,7 @@ struct bt_mesh_model { #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS /* Pointer to the next model in a model extension list. */ - struct bt_mesh_model *next; + const struct bt_mesh_model ** const next; #endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) || defined(__DOXYGEN__) @@ -915,7 +938,7 @@ struct bt_mesh_model { #endif /** Model-specific user data */ - void *user_data; + void ** const user_data; }; /** Callback structure for monitoring model message sending */ @@ -952,7 +975,7 @@ struct bt_mesh_send_cb { * * @return 0 on success, or (negative) error code on failure. */ -int bt_mesh_model_send(struct bt_mesh_model *model, +int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, @@ -971,7 +994,7 @@ int bt_mesh_model_send(struct bt_mesh_model *model, * * @return 0 on success, or (negative) error code on failure. */ -int bt_mesh_model_publish(struct bt_mesh_model *model); +int bt_mesh_model_publish(const struct bt_mesh_model *model); /** @brief Check if a message is being retransmitted. * @@ -992,7 +1015,7 @@ static inline bool bt_mesh_model_pub_is_retransmission(const struct bt_mesh_mode * * @return Pointer to the element that the given model belongs to. */ -struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod); +struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod); /** @brief Find a SIG model. * @@ -1002,7 +1025,7 @@ struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod); * @return A pointer to the Mesh model matching the given parameters, or NULL * if no SIG model with the given ID exists in the given element. */ -struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, +const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, uint16_t id); /** @brief Find a vendor model. @@ -1014,7 +1037,7 @@ struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, * @return A pointer to the Mesh model matching the given parameters, or NULL * if no vendor model with the given ID exists in the given element. */ -struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, +const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, uint16_t company, uint16_t id); /** @brief Get whether the model is in the primary element of the device. @@ -1025,7 +1048,7 @@ struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, */ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) { - return (mod->elem_idx == 0); + return (*(mod->elem_idx) == 0); } /** @brief Immediately store the model's user data in persistent storage. @@ -1039,7 +1062,7 @@ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) * * @return 0 on success, or (negative) error code on failure. */ -int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, +int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len); @@ -1054,7 +1077,7 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, * * @param mod Mesh model. */ -void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod); +void bt_mesh_model_data_store_schedule(const struct bt_mesh_model *mod); /** @brief Let a model extend another. * @@ -1079,8 +1102,8 @@ void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod); * * @retval 0 Successfully extended the base_mod model. */ -int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, - struct bt_mesh_model *base_mod); +int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod, + const struct bt_mesh_model *base_mod); /** @brief Let a model correspond to another. * @@ -1102,8 +1125,8 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, * @retval -ENOTSUP Composition Data Page 1 is not supported. */ -int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, - struct bt_mesh_model *base_mod); +int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod, + const struct bt_mesh_model *base_mod); /** @brief Check if model is extended by another model. * @@ -1111,7 +1134,7 @@ int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, * * @retval true If model is extended by another model, otherwise false */ -bool bt_mesh_model_is_extended(struct bt_mesh_model *model); +bool bt_mesh_model_is_extended(const struct bt_mesh_model *model); /** @brief Indicate that the composition data will change on next bootup. * diff --git a/include/zephyr/bluetooth/mesh/blob_cli.h b/include/zephyr/bluetooth/mesh/blob_cli.h index 3bf65beae39..8e239b31457 100644 --- a/include/zephyr/bluetooth/mesh/blob_cli.h +++ b/include/zephyr/bluetooth/mesh/blob_cli.h @@ -291,7 +291,7 @@ struct bt_mesh_blob_cli { const struct bt_mesh_blob_cli_cb *cb; /* Runtime state */ - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct { struct bt_mesh_blob_target *target; diff --git a/include/zephyr/bluetooth/mesh/blob_srv.h b/include/zephyr/bluetooth/mesh/blob_srv.h index 57237f1d4bb..bf807bad92f 100644 --- a/include/zephyr/bluetooth/mesh/blob_srv.h +++ b/include/zephyr/bluetooth/mesh/blob_srv.h @@ -136,7 +136,7 @@ struct bt_mesh_blob_srv { const struct bt_mesh_blob_io *io; struct k_work_delayable rx_timeout; struct bt_mesh_blob_block block; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; enum bt_mesh_blob_xfer_phase phase; struct bt_mesh_blob_srv_state { diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index 1a7c8ed7e2c..0e8c26131ff 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -332,7 +332,7 @@ struct bt_mesh_cfg_cli_cb { /** Mesh Configuration Client Model Context */ struct bt_mesh_cfg_cli { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Optional callback for Mesh Configuration Client Status messages. */ const struct bt_mesh_cfg_cli_cb *cb; diff --git a/include/zephyr/bluetooth/mesh/dfd_srv.h b/include/zephyr/bluetooth/mesh/dfd_srv.h index 666e0d8ad3d..f15768080d7 100644 --- a/include/zephyr/bluetooth/mesh/dfd_srv.h +++ b/include/zephyr/bluetooth/mesh/dfd_srv.h @@ -210,7 +210,7 @@ struct bt_mesh_dfd_srv_cb { /** Firmware Distribution Server instance. */ struct bt_mesh_dfd_srv { const struct bt_mesh_dfd_srv_cb *cb; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_dfu_cli dfu; struct bt_mesh_dfu_target targets[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX]; struct bt_mesh_blob_target_pull pull_ctxs[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX]; diff --git a/include/zephyr/bluetooth/mesh/dfu_cli.h b/include/zephyr/bluetooth/mesh/dfu_cli.h index 51f534f2828..3cbc220d825 100644 --- a/include/zephyr/bluetooth/mesh/dfu_cli.h +++ b/include/zephyr/bluetooth/mesh/dfu_cli.h @@ -190,7 +190,7 @@ struct bt_mesh_dfu_cli { /* runtime state */ uint32_t op; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct { const struct bt_mesh_dfu_slot *slot; diff --git a/include/zephyr/bluetooth/mesh/dfu_srv.h b/include/zephyr/bluetooth/mesh/dfu_srv.h index 53d9144713c..e136701e664 100644 --- a/include/zephyr/bluetooth/mesh/dfu_srv.h +++ b/include/zephyr/bluetooth/mesh/dfu_srv.h @@ -184,7 +184,7 @@ struct bt_mesh_dfu_srv { size_t img_count; /* Runtime state */ - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct { /* Effect of transfer, @see bt_mesh_dfu_effect. */ uint8_t effect; diff --git a/include/zephyr/bluetooth/mesh/health_cli.h b/include/zephyr/bluetooth/mesh/health_cli.h index 2f13dd88ccf..2d8904ea6f2 100644 --- a/include/zephyr/bluetooth/mesh/health_cli.h +++ b/include/zephyr/bluetooth/mesh/health_cli.h @@ -26,7 +26,7 @@ extern "C" { /** Health Client Model Context */ struct bt_mesh_health_cli { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Publication structure instance */ struct bt_mesh_model_pub pub; diff --git a/include/zephyr/bluetooth/mesh/health_srv.h b/include/zephyr/bluetooth/mesh/health_srv.h index 9665e3bc62a..bb1e48004b9 100644 --- a/include/zephyr/bluetooth/mesh/health_srv.h +++ b/include/zephyr/bluetooth/mesh/health_srv.h @@ -53,7 +53,7 @@ struct bt_mesh_health_srv_cb { * * @return 0 on success, or (negative) error code otherwise. */ - int (*fault_get_cur)(struct bt_mesh_model *model, uint8_t *test_id, + int (*fault_get_cur)(const struct bt_mesh_model *model, uint8_t *test_id, uint16_t *company_id, uint8_t *faults, uint8_t *fault_count); @@ -79,7 +79,7 @@ struct bt_mesh_health_srv_cb { * * @return 0 on success, or (negative) error code otherwise. */ - int (*fault_get_reg)(struct bt_mesh_model *model, uint16_t company_id, + int (*fault_get_reg)(const struct bt_mesh_model *model, uint16_t company_id, uint8_t *test_id, uint8_t *faults, uint8_t *fault_count); @@ -91,7 +91,7 @@ struct bt_mesh_health_srv_cb { * * @return 0 on success, or (negative) error code otherwise. */ - int (*fault_clear)(struct bt_mesh_model *model, uint16_t company_id); + int (*fault_clear)(const struct bt_mesh_model *model, uint16_t company_id); /** @brief Run a self-test. * @@ -108,7 +108,7 @@ struct bt_mesh_health_srv_cb { * (negative) error code otherwise. Note that the fault array will not * be reported back to the client if the test execution didn't start. */ - int (*fault_test)(struct bt_mesh_model *model, uint8_t test_id, + int (*fault_test)(const struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id); /** @brief Start calling attention to the device. @@ -125,7 +125,7 @@ struct bt_mesh_health_srv_cb { * * @param model Health Server model to start the attention state of. */ - void (*attn_on)(struct bt_mesh_model *model); + void (*attn_on)(const struct bt_mesh_model *model); /** @brief Stop the attention state. * @@ -134,7 +134,7 @@ struct bt_mesh_health_srv_cb { * * @param model */ - void (*attn_off)(struct bt_mesh_model *model); + void (*attn_off)(const struct bt_mesh_model *model); }; /** @@ -149,7 +149,7 @@ struct bt_mesh_health_srv_cb { /** Mesh Health Server Model Context */ struct bt_mesh_health_srv { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Optional callback struct */ const struct bt_mesh_health_srv_cb *cb; diff --git a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h index b7ed0776204..520fcb3a6b5 100644 --- a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h +++ b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h @@ -69,7 +69,7 @@ struct bt_mesh_large_comp_data_cli_cb { /** Large Composition Data Client model context */ struct bt_mesh_large_comp_data_cli { /** Model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Internal parameters for tracking message responses. */ struct bt_mesh_msg_ack_ctx ack_ctx; diff --git a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h index f9734d78d3e..0234158b046 100644 --- a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h +++ b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h @@ -22,7 +22,7 @@ extern "C" { /** On-Demand Private Proxy Client Model Context */ struct bt_mesh_od_priv_proxy_cli { /** Solicitation PDU RPL model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /* Internal parameters for tracking message responses. */ struct bt_mesh_msg_ack_ctx ack_ctx; diff --git a/include/zephyr/bluetooth/mesh/priv_beacon_cli.h b/include/zephyr/bluetooth/mesh/priv_beacon_cli.h index 835dc38c773..24fba6f67be 100644 --- a/include/zephyr/bluetooth/mesh/priv_beacon_cli.h +++ b/include/zephyr/bluetooth/mesh/priv_beacon_cli.h @@ -90,7 +90,7 @@ struct bt_mesh_priv_beacon_cli_cb { /** Mesh Private Beacon Client model */ struct bt_mesh_priv_beacon_cli { - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /* Internal parameters for tracking message responses. */ struct bt_mesh_msg_ack_ctx ack_ctx; diff --git a/include/zephyr/bluetooth/mesh/rpr_cli.h b/include/zephyr/bluetooth/mesh/rpr_cli.h index 5c0374fecc3..414e2887bdf 100644 --- a/include/zephyr/bluetooth/mesh/rpr_cli.h +++ b/include/zephyr/bluetooth/mesh/rpr_cli.h @@ -91,7 +91,7 @@ struct bt_mesh_rpr_cli { enum bt_mesh_rpr_link_state state; } link; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; }; /** @brief Get scanning capabilities of Remote Provisioning Server. diff --git a/include/zephyr/bluetooth/mesh/sar_cfg_cli.h b/include/zephyr/bluetooth/mesh/sar_cfg_cli.h index 7882174512e..5e8409d3841 100644 --- a/include/zephyr/bluetooth/mesh/sar_cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/sar_cfg_cli.h @@ -27,7 +27,7 @@ extern "C" { /** Mesh SAR Configuration Client Model Context */ struct bt_mesh_sar_cfg_cli { /** Access model pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /* Publication structure instance */ struct bt_mesh_model_pub pub; diff --git a/include/zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h b/include/zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h index 5a3dcdd784d..5a6c49bd211 100644 --- a/include/zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h +++ b/include/zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h @@ -22,7 +22,7 @@ extern "C" { /** Solicitation PDU RPL Client Model Context */ struct bt_mesh_sol_pdu_rpl_cli { /** Solicitation PDU RPL model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /* Internal parameters for tracking message responses. */ struct bt_mesh_msg_ack_ctx ack_ctx; diff --git a/include/zephyr/bluetooth/testing.h b/include/zephyr/bluetooth/testing.h index 9cfda4e1177..58aae9726ff 100644 --- a/include/zephyr/bluetooth/testing.h +++ b/include/zephyr/bluetooth/testing.h @@ -39,9 +39,9 @@ struct bt_test_cb { const void *payload, size_t payload_len); void (*mesh_model_recv)(uint16_t src, uint16_t dst, const void *payload, size_t payload_len); - void (*mesh_model_bound)(uint16_t addr, struct bt_mesh_model *model, + void (*mesh_model_bound)(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx); - void (*mesh_model_unbound)(uint16_t addr, struct bt_mesh_model *model, + void (*mesh_model_unbound)(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx); void (*mesh_prov_invalid_bearer)(uint8_t opcode); void (*mesh_trans_incomp_timer_exp)(void); diff --git a/samples/bluetooth/mesh/src/main.c b/samples/bluetooth/mesh/src/main.c index 6914c4fc409..5555edef9bb 100644 --- a/samples/bluetooth/mesh/src/main.c +++ b/samples/bluetooth/mesh/src/main.c @@ -25,12 +25,12 @@ #define OP_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03) #define OP_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04) -static void attention_on(struct bt_mesh_model *mod) +static void attention_on(const struct bt_mesh_model *mod) { board_led_set(true); } -static void attention_off(struct bt_mesh_model *mod) +static void attention_off(const struct bt_mesh_model *mod) { board_led_set(false); } @@ -102,7 +102,7 @@ static inline uint8_t model_time_encode(int32_t ms) return 0x3f; } -static int onoff_status_send(struct bt_mesh_model *model, +static int onoff_status_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { uint32_t remaining; @@ -151,7 +151,7 @@ static void onoff_timeout(struct k_work *work) /* Generic OnOff Server message handlers */ -static int gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -159,7 +159,7 @@ static int gen_onoff_get(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -202,7 +202,7 @@ static int gen_onoff_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -221,7 +221,7 @@ static const struct bt_mesh_model_op gen_onoff_srv_op[] = { /* Generic OnOff Client */ -static int gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -248,7 +248,7 @@ static const struct bt_mesh_model_op gen_onoff_cli_op[] = { }; /* This application only needs one element to contain its models */ -static struct bt_mesh_model models[] = { +static const struct bt_mesh_model models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, NULL, diff --git a/samples/bluetooth/mesh_demo/src/main.c b/samples/bluetooth/mesh_demo/src/main.c index 642cce1d18e..08d6a1aae9b 100644 --- a/samples/bluetooth/mesh_demo/src/main.c +++ b/samples/bluetooth/mesh_demo/src/main.c @@ -50,14 +50,14 @@ static void heartbeat(const struct bt_mesh_hb_sub *sub, uint8_t hops, static struct bt_mesh_cfg_cli cfg_cli = { }; -static void attention_on(struct bt_mesh_model *model) +static void attention_on(const struct bt_mesh_model *model) { printk("attention_on()\n"); board_attention(true); board_play("100H100C100H100C100H100C"); } -static void attention_off(struct bt_mesh_model *model) +static void attention_off(const struct bt_mesh_model *model) { printk("attention_off()\n"); board_attention(false); @@ -74,13 +74,13 @@ static struct bt_mesh_health_srv health_srv = { BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0); -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), }; -static int vnd_button_pressed(struct bt_mesh_model *model, +static int vnd_button_pressed(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -101,7 +101,7 @@ static const struct bt_mesh_model_op vnd_ops[] = { BT_MESH_MODEL_OP_END, }; -static struct bt_mesh_model vnd_models[] = { +static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, MOD_LF, vnd_ops, NULL, NULL), }; diff --git a/samples/bluetooth/mesh_provisioner/src/main.c b/samples/bluetooth/mesh_provisioner/src/main.c index 42eaa31207b..057087a2e8a 100644 --- a/samples/bluetooth/mesh_provisioner/src/main.c +++ b/samples/bluetooth/mesh_provisioner/src/main.c @@ -53,7 +53,7 @@ static struct bt_mesh_health_cli health_cli = { .current_status = health_current_status, }; -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_CLI(&health_cli), diff --git a/samples/boards/nrf/mesh/onoff-app/src/main.c b/samples/boards/nrf/mesh/onoff-app/src/main.c index 9e8788d4642..817d2c023a6 100644 --- a/samples/boards/nrf/mesh/onoff-app/src/main.c +++ b/samples/boards/nrf/mesh/onoff-app/src/main.c @@ -54,19 +54,19 @@ #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03) #define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04) -static int gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); -static int gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); -static int gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); -static int gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); @@ -167,7 +167,7 @@ static struct led_onoff_state led_onoff_states[] = { * Element 0 Root Models */ -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), @@ -181,7 +181,7 @@ static struct bt_mesh_model root_models[] = { * Element 1 Models */ -static struct bt_mesh_model secondary_0_models[] = { +static const struct bt_mesh_model secondary_0_models[] = { BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv_s_0, &led_onoff_states[1]), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, @@ -192,7 +192,7 @@ static struct bt_mesh_model secondary_0_models[] = { * Element 2 Models */ -static struct bt_mesh_model secondary_1_models[] = { +static const struct bt_mesh_model secondary_1_models[] = { BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv_s_1, &led_onoff_states[2]), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, @@ -203,7 +203,7 @@ static struct bt_mesh_model secondary_1_models[] = { * Element 3 Models */ -static struct bt_mesh_model secondary_2_models[] = { +static const struct bt_mesh_model secondary_2_models[] = { BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv_s_2, &led_onoff_states[3]), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, @@ -214,7 +214,7 @@ static struct bt_mesh_model secondary_2_models[] = { * Button to Client Model Assignments */ -struct bt_mesh_model *mod_cli_sw[] = { +const struct bt_mesh_model *mod_cli_sw[] = { &root_models[4], &secondary_0_models[1], &secondary_1_models[1], @@ -225,7 +225,7 @@ struct bt_mesh_model *mod_cli_sw[] = { * LED to Server Model Assignments */ -struct bt_mesh_model *mod_srv_sw[] = { +const struct bt_mesh_model *mod_srv_sw[] = { &root_models[3], &secondary_0_models[0], &secondary_1_models[0], @@ -281,12 +281,12 @@ static uint16_t primary_net_idx; * */ -static int gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); - struct led_onoff_state *onoff_state = model->user_data; + struct led_onoff_state *onoff_state = *(model->user_data); printk("addr 0x%04x onoff 0x%02x\n", bt_mesh_model_elem(model)->addr, onoff_state->current); @@ -300,12 +300,12 @@ static int gen_onoff_get(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct net_buf_simple *msg = model->pub->msg; - struct led_onoff_state *onoff_state = model->user_data; + struct led_onoff_state *onoff_state = *(model->user_data); int err; onoff_state->current = net_buf_simple_pull_u8(buf); @@ -340,7 +340,7 @@ static int gen_onoff_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -352,7 +352,7 @@ static int gen_onoff_set(struct bt_mesh_model *model, return 0; } -static int gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -465,7 +465,7 @@ static void button_cnt_timer(struct k_timer *work) static void button_pressed_worker(struct k_work *work) { - struct bt_mesh_model *mod_cli, *mod_srv; + const struct bt_mesh_model *mod_cli, *mod_srv; struct bt_mesh_model_pub *pub_cli, *pub_srv; struct switch_data *button_sw = CONTAINER_OF(work, struct switch_data, button_work); int err; diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 2cf7abc3048..54a5a2c8af7 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -68,7 +68,7 @@ static struct bt_mesh_elem elements[]; /* message handlers (Start) */ /* Generic OnOff Server message handlers */ -static int gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -95,7 +95,7 @@ static int gen_onoff_get(struct bt_mesh_model *model, return 0; } -void gen_onoff_publish(struct bt_mesh_model *model) +void gen_onoff_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -119,7 +119,7 @@ void gen_onoff_publish(struct bt_mesh_model *model) } } -static int gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -188,7 +188,7 @@ static int gen_onoff_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -261,7 +261,7 @@ static int gen_onoff_set(struct bt_mesh_model *model, } /* Generic OnOff Client message handlers */ -static int gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -277,7 +277,7 @@ static int gen_onoff_status(struct bt_mesh_model *model, } /* Generic Level (LIGHTNESS) Server message handlers */ -static int gen_level_get(struct bt_mesh_model *model, +static int gen_level_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -304,7 +304,7 @@ static int gen_level_get(struct bt_mesh_model *model, return 0; } -void gen_level_publish(struct bt_mesh_model *model) +void gen_level_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -328,7 +328,7 @@ void gen_level_publish(struct bt_mesh_model *model) } } -static int gen_level_set_unack(struct bt_mesh_model *model, +static int gen_level_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -394,7 +394,7 @@ static int gen_level_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_level_set(struct bt_mesh_model *model, +static int gen_level_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -463,7 +463,7 @@ static int gen_level_set(struct bt_mesh_model *model, return 0; } -static int gen_delta_set_unack(struct bt_mesh_model *model, +static int gen_delta_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -545,7 +545,7 @@ static int gen_delta_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_delta_set(struct bt_mesh_model *model, +static int gen_delta_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -630,7 +630,7 @@ static int gen_delta_set(struct bt_mesh_model *model, return 0; } -static int gen_move_set_unack(struct bt_mesh_model *model, +static int gen_move_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -705,7 +705,7 @@ static int gen_move_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_move_set(struct bt_mesh_model *model, +static int gen_move_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t tid, tt, delay; @@ -783,7 +783,7 @@ static int gen_move_set(struct bt_mesh_model *model, } /* Generic Level Client message handlers */ -static int gen_level_status(struct bt_mesh_model *model, +static int gen_level_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -799,7 +799,7 @@ static int gen_level_status(struct bt_mesh_model *model, } /* Generic Default Transition Time Server message handlers */ -static int gen_def_trans_time_get(struct bt_mesh_model *model, +static int gen_def_trans_time_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -815,7 +815,7 @@ static int gen_def_trans_time_get(struct bt_mesh_model *model, return 0; } -static void gen_def_trans_time_publish(struct bt_mesh_model *model) +static void gen_def_trans_time_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -833,7 +833,7 @@ static void gen_def_trans_time_publish(struct bt_mesh_model *model) } } -static int gen_def_trans_time_set_unack(struct bt_mesh_model *model, +static int gen_def_trans_time_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -855,7 +855,7 @@ static int gen_def_trans_time_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_def_trans_time_set(struct bt_mesh_model *model, +static int gen_def_trans_time_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -881,7 +881,7 @@ static int gen_def_trans_time_set(struct bt_mesh_model *model, } /* Generic Default Transition Time Client message handlers */ -static int gen_def_trans_time_status(struct bt_mesh_model *model, +static int gen_def_trans_time_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -892,7 +892,7 @@ static int gen_def_trans_time_status(struct bt_mesh_model *model, } /* Generic Power OnOff Server message handlers */ -static int gen_onpowerup_get(struct bt_mesh_model *model, +static int gen_onpowerup_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -909,7 +909,7 @@ static int gen_onpowerup_get(struct bt_mesh_model *model, } /* Generic Power OnOff Client message handlers */ -static int gen_onpowerup_status(struct bt_mesh_model *model, +static int gen_onpowerup_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -921,7 +921,7 @@ static int gen_onpowerup_status(struct bt_mesh_model *model, /* Generic Power OnOff Setup Server message handlers */ -static void gen_onpowerup_publish(struct bt_mesh_model *model) +static void gen_onpowerup_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -939,7 +939,7 @@ static void gen_onpowerup_publish(struct bt_mesh_model *model) } } -static int gen_onpowerup_set_unack(struct bt_mesh_model *model, +static int gen_onpowerup_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -961,7 +961,7 @@ static int gen_onpowerup_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_onpowerup_set(struct bt_mesh_model *model, +static int gen_onpowerup_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -987,11 +987,11 @@ static int gen_onpowerup_set(struct bt_mesh_model *model, } /* Vendor Model message handlers*/ -static int vnd_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int vnd_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct net_buf_simple *msg = NET_BUF_SIMPLE(3 + 6 + 4); - struct vendor_state *state = model->user_data; + struct vendor_state *state = *(model->user_data); /* This is dummy response for demo purpose */ state->response = 0xA578FEB3; @@ -1007,14 +1007,14 @@ static int vnd_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int vnd_set_unack(struct bt_mesh_model *model, +static int vnd_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t tid; int current; int64_t now; - struct vendor_state *state = model->user_data; + struct vendor_state *state = *(model->user_data); current = net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); @@ -1040,7 +1040,7 @@ static int vnd_set_unack(struct bt_mesh_model *model, return 0; } -static int vnd_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int vnd_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { (void)vnd_set_unack(model, ctx, buf); @@ -1049,7 +1049,7 @@ static int vnd_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int vnd_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int vnd_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { printk("Acknowledgement from Vendor\n"); @@ -1060,7 +1060,7 @@ static int vnd_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } /* Light Lightness Server message handlers */ -static int light_lightness_get(struct bt_mesh_model *model, +static int light_lightness_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1087,7 +1087,7 @@ static int light_lightness_get(struct bt_mesh_model *model, return 0; } -void light_lightness_publish(struct bt_mesh_model *model) +void light_lightness_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1111,7 +1111,7 @@ void light_lightness_publish(struct bt_mesh_model *model) } } -static int light_lightness_set_unack(struct bt_mesh_model *model, +static int light_lightness_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1177,7 +1177,7 @@ static int light_lightness_set_unack(struct bt_mesh_model *model, return 0; } -static int light_lightness_set(struct bt_mesh_model *model, +static int light_lightness_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1246,7 +1246,7 @@ static int light_lightness_set(struct bt_mesh_model *model, return 0; } -static int light_lightness_linear_get(struct bt_mesh_model *model, +static int light_lightness_linear_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1274,7 +1274,7 @@ static int light_lightness_linear_get(struct bt_mesh_model *model, return 0; } -void light_lightness_linear_publish(struct bt_mesh_model *model) +void light_lightness_linear_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1299,7 +1299,7 @@ void light_lightness_linear_publish(struct bt_mesh_model *model) } } -static int light_lightness_linear_set_unack(struct bt_mesh_model *model, +static int light_lightness_linear_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1365,7 +1365,7 @@ static int light_lightness_linear_set_unack(struct bt_mesh_model *model, return 0; } -static int light_lightness_linear_set(struct bt_mesh_model *model, +static int light_lightness_linear_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1434,7 +1434,7 @@ static int light_lightness_linear_set(struct bt_mesh_model *model, return 0; } -static int light_lightness_last_get(struct bt_mesh_model *model, +static int light_lightness_last_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1450,7 +1450,7 @@ static int light_lightness_last_get(struct bt_mesh_model *model, return 0; } -static int light_lightness_default_get(struct bt_mesh_model *model, +static int light_lightness_default_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1467,7 +1467,7 @@ static int light_lightness_default_get(struct bt_mesh_model *model, return 0; } -static int light_lightness_range_get(struct bt_mesh_model *model, +static int light_lightness_range_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1489,7 +1489,7 @@ static int light_lightness_range_get(struct bt_mesh_model *model, /* Light Lightness Setup Server message handlers */ -static void light_lightness_default_publish(struct bt_mesh_model *model) +static void light_lightness_default_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1508,7 +1508,7 @@ static void light_lightness_default_publish(struct bt_mesh_model *model) } } -static int light_lightness_default_set_unack(struct bt_mesh_model *model, +static int light_lightness_default_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1527,7 +1527,7 @@ static int light_lightness_default_set_unack(struct bt_mesh_model *model, return 0; } -static int light_lightness_default_set(struct bt_mesh_model *model, +static int light_lightness_default_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1549,7 +1549,7 @@ static int light_lightness_default_set(struct bt_mesh_model *model, return 0; } -static void light_lightness_range_publish(struct bt_mesh_model *model) +static void light_lightness_range_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1569,7 +1569,7 @@ static void light_lightness_range_publish(struct bt_mesh_model *model) } } -static int light_lightness_range_set_unack(struct bt_mesh_model *model, +static int light_lightness_range_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1603,7 +1603,7 @@ static int light_lightness_range_set_unack(struct bt_mesh_model *model, return 0; } -static int light_lightness_range_set(struct bt_mesh_model *model, +static int light_lightness_range_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1641,7 +1641,7 @@ static int light_lightness_range_set(struct bt_mesh_model *model, } /* Light Lightness Client message handlers */ -static int light_lightness_status(struct bt_mesh_model *model, +static int light_lightness_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1657,7 +1657,7 @@ static int light_lightness_status(struct bt_mesh_model *model, return 0; } -static int light_lightness_linear_status(struct bt_mesh_model *model, +static int light_lightness_linear_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1673,7 +1673,7 @@ static int light_lightness_linear_status(struct bt_mesh_model *model, return 0; } -static int light_lightness_last_status(struct bt_mesh_model *model, +static int light_lightness_last_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1683,7 +1683,7 @@ static int light_lightness_last_status(struct bt_mesh_model *model, return 0; } -static int light_lightness_default_status(struct bt_mesh_model *model, +static int light_lightness_default_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1693,7 +1693,7 @@ static int light_lightness_default_status(struct bt_mesh_model *model, return 0; } -static int light_lightness_range_status(struct bt_mesh_model *model, +static int light_lightness_range_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1706,7 +1706,7 @@ static int light_lightness_range_status(struct bt_mesh_model *model, } /* Light CTL Server message handlers */ -static int light_ctl_get(struct bt_mesh_model *model, +static int light_ctl_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1736,7 +1736,7 @@ static int light_ctl_get(struct bt_mesh_model *model, return 0; } -void light_ctl_publish(struct bt_mesh_model *model) +void light_ctl_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1766,7 +1766,7 @@ void light_ctl_publish(struct bt_mesh_model *model) } } -static int light_ctl_set_unack(struct bt_mesh_model *model, +static int light_ctl_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1845,7 +1845,7 @@ static int light_ctl_set_unack(struct bt_mesh_model *model, return 0; } -static int light_ctl_set(struct bt_mesh_model *model, +static int light_ctl_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1927,7 +1927,7 @@ static int light_ctl_set(struct bt_mesh_model *model, return 0; } -static int light_ctl_temp_range_get(struct bt_mesh_model *model, +static int light_ctl_temp_range_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1947,7 +1947,7 @@ static int light_ctl_temp_range_get(struct bt_mesh_model *model, return 0; } -static int light_ctl_default_get(struct bt_mesh_model *model, +static int light_ctl_default_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1967,7 +1967,7 @@ static int light_ctl_default_get(struct bt_mesh_model *model, /* Light CTL Setup Server message handlers */ -static void light_ctl_default_publish(struct bt_mesh_model *model) +static void light_ctl_default_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -1987,7 +1987,7 @@ static void light_ctl_default_publish(struct bt_mesh_model *model) } } -static int light_ctl_default_set_unack(struct bt_mesh_model *model, +static int light_ctl_default_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2018,7 +2018,7 @@ static int light_ctl_default_set_unack(struct bt_mesh_model *model, return 0; } -static int light_ctl_default_set(struct bt_mesh_model *model, +static int light_ctl_default_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2052,7 +2052,7 @@ static int light_ctl_default_set(struct bt_mesh_model *model, return 0; } -static void light_ctl_temp_range_publish(struct bt_mesh_model *model) +static void light_ctl_temp_range_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -2072,7 +2072,7 @@ static void light_ctl_temp_range_publish(struct bt_mesh_model *model) } } -static int light_ctl_temp_range_set_unack(struct bt_mesh_model *model, +static int light_ctl_temp_range_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2108,7 +2108,7 @@ static int light_ctl_temp_range_set_unack(struct bt_mesh_model *model, return 0; } -static int light_ctl_temp_range_set(struct bt_mesh_model *model, +static int light_ctl_temp_range_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2148,7 +2148,7 @@ static int light_ctl_temp_range_set(struct bt_mesh_model *model, } /* Light CTL Client message handlers */ -static int light_ctl_status(struct bt_mesh_model *model, +static int light_ctl_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2168,7 +2168,7 @@ static int light_ctl_status(struct bt_mesh_model *model, return 0; } -static int light_ctl_temp_range_status(struct bt_mesh_model *model, +static int light_ctl_temp_range_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2180,7 +2180,7 @@ static int light_ctl_temp_range_status(struct bt_mesh_model *model, return 0; } -static int light_ctl_temp_status(struct bt_mesh_model *model, +static int light_ctl_temp_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2201,7 +2201,7 @@ static int light_ctl_temp_status(struct bt_mesh_model *model, return 0; } -static int light_ctl_default_status(struct bt_mesh_model *model, +static int light_ctl_default_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2214,7 +2214,7 @@ static int light_ctl_default_status(struct bt_mesh_model *model, } /* Light CTL Temp. Server message handlers */ -static int light_ctl_temp_get(struct bt_mesh_model *model, +static int light_ctl_temp_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2244,7 +2244,7 @@ static int light_ctl_temp_get(struct bt_mesh_model *model, return 0; } -void light_ctl_temp_publish(struct bt_mesh_model *model) +void light_ctl_temp_publish(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -2270,7 +2270,7 @@ void light_ctl_temp_publish(struct bt_mesh_model *model) } } -static int light_ctl_temp_set_unack(struct bt_mesh_model *model, +static int light_ctl_temp_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2345,7 +2345,7 @@ static int light_ctl_temp_set_unack(struct bt_mesh_model *model, return 0; } -static int light_ctl_temp_set(struct bt_mesh_model *model, +static int light_ctl_temp_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2424,7 +2424,7 @@ static int light_ctl_temp_set(struct bt_mesh_model *model, } /* Generic Level (TEMPERATURE) Server message handlers */ -static int gen_level_get_temp(struct bt_mesh_model *model, +static int gen_level_get_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2451,7 +2451,7 @@ static int gen_level_get_temp(struct bt_mesh_model *model, return 0; } -void gen_level_publish_temp(struct bt_mesh_model *model) +void gen_level_publish_temp(const struct bt_mesh_model *model) { int err; struct net_buf_simple *msg = model->pub->msg; @@ -2475,7 +2475,7 @@ void gen_level_publish_temp(struct bt_mesh_model *model) } } -static int gen_level_set_unack_temp(struct bt_mesh_model *model, +static int gen_level_set_unack_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2541,7 +2541,7 @@ static int gen_level_set_unack_temp(struct bt_mesh_model *model, return 0; } -static int gen_level_set_temp(struct bt_mesh_model *model, +static int gen_level_set_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2610,7 +2610,7 @@ static int gen_level_set_temp(struct bt_mesh_model *model, return 0; } -static int gen_delta_set_unack_temp(struct bt_mesh_model *model, +static int gen_delta_set_unack_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2692,7 +2692,7 @@ static int gen_delta_set_unack_temp(struct bt_mesh_model *model, return 0; } -static int gen_delta_set_temp(struct bt_mesh_model *model, +static int gen_delta_set_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2777,7 +2777,7 @@ static int gen_delta_set_temp(struct bt_mesh_model *model, return 0; } -static int gen_move_set_unack_temp(struct bt_mesh_model *model, +static int gen_move_set_unack_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2852,7 +2852,7 @@ static int gen_move_set_unack_temp(struct bt_mesh_model *model, return 0; } -static int gen_move_set_temp(struct bt_mesh_model *model, +static int gen_move_set_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2931,7 +2931,7 @@ static int gen_move_set_temp(struct bt_mesh_model *model, } /* Generic Level (TEMPERATURE) Client message handlers */ -static int gen_level_status_temp(struct bt_mesh_model *model, +static int gen_level_status_temp(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -3112,7 +3112,7 @@ static const struct bt_mesh_model_op gen_level_cli_op_temp[] = { BT_MESH_MODEL_OP_END, }; -struct bt_mesh_model root_models[] = { +const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), @@ -3172,12 +3172,12 @@ struct bt_mesh_model root_models[] = { NULL), }; -struct bt_mesh_model vnd_models[] = { +const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(CID_ZEPHYR, 0x4321, vnd_ops, &vnd_pub, &vnd_user_data), }; -struct bt_mesh_model s0_models[] = { +const struct bt_mesh_model s0_models[] = { BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, gen_level_srv_op_temp, &gen_level_srv_pub_s0, NULL), diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h index 2bc4c836926..108075379b0 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h @@ -93,18 +93,18 @@ struct light_ctl_state { extern struct vendor_state vnd_user_data; extern struct light_ctl_state *const ctl; -extern struct bt_mesh_model root_models[]; -extern struct bt_mesh_model vnd_models[]; -extern struct bt_mesh_model s0_models[]; +extern const struct bt_mesh_model root_models[]; +extern const struct bt_mesh_model vnd_models[]; +extern const struct bt_mesh_model s0_models[]; extern const struct bt_mesh_comp comp; -void gen_onoff_publish(struct bt_mesh_model *model); -void gen_level_publish(struct bt_mesh_model *model); -void light_lightness_publish(struct bt_mesh_model *model); -void light_lightness_linear_publish(struct bt_mesh_model *model); -void light_ctl_publish(struct bt_mesh_model *model); -void light_ctl_temp_publish(struct bt_mesh_model *model); -void gen_level_publish_temp(struct bt_mesh_model *model); +void gen_onoff_publish(const struct bt_mesh_model *model); +void gen_level_publish(const struct bt_mesh_model *model); +void light_lightness_publish(const struct bt_mesh_model *model); +void light_lightness_linear_publish(const struct bt_mesh_model *model); +void light_ctl_publish(const struct bt_mesh_model *model); +void light_ctl_temp_publish(const struct bt_mesh_model *model); +void gen_level_publish_temp(const struct bt_mesh_model *model); #endif diff --git a/samples/boards/reel_board/mesh_badge/src/mesh.c b/samples/boards/reel_board/mesh_badge/src/mesh.c index d2916d141e6..ae219387cf5 100644 --- a/samples/boards/reel_board/mesh_badge/src/mesh.c +++ b/samples/boards/reel_board/mesh_badge/src/mesh.c @@ -159,12 +159,12 @@ static struct bt_mesh_cfg_cli cfg_cli = { .cb = &cfg_cli_cb, }; -static void attention_on(struct bt_mesh_model *model) +static void attention_on(const struct bt_mesh_model *model) { board_show_text("Attention!", false, K_SECONDS(2)); } -static void attention_off(struct bt_mesh_model *model) +static void attention_off(const struct bt_mesh_model *model) { board_refresh_display(); } @@ -179,12 +179,12 @@ static struct bt_mesh_health_srv health_srv = { }; /* Generic OnOff Server message handlers */ -static int gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); - struct led_onoff_state *state = model->user_data; + struct led_onoff_state *state = *(model->user_data); printk("addr 0x%04x onoff 0x%02x\n", bt_mesh_model_elem(model)->addr, state->current); @@ -198,12 +198,12 @@ static int gen_onoff_get(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct net_buf_simple *msg = model->pub->msg; - struct led_onoff_state *state = model->user_data; + struct led_onoff_state *state = *(model->user_data); int err; uint8_t tid, onoff; int64_t now; @@ -263,7 +263,7 @@ static int gen_onoff_set_unack(struct bt_mesh_model *model, return 0; } -static int gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -273,7 +273,7 @@ static int gen_onoff_set(struct bt_mesh_model *model, return 0; } -static int sensor_desc_get(struct bt_mesh_model *model, +static int sensor_desc_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -333,7 +333,7 @@ static void sensor_create_status(uint16_t id, struct net_buf_simple *msg) } } -static int sensor_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int sensor_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, 1 + MAX_SENS_STATUS_LEN + 4); @@ -349,7 +349,7 @@ static int sensor_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int sensor_col_get(struct bt_mesh_model *model, +static int sensor_col_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -357,7 +357,7 @@ static int sensor_col_get(struct bt_mesh_model *model, return 0; } -static int sensor_series_get(struct bt_mesh_model *model, +static int sensor_series_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -385,7 +385,7 @@ static const struct bt_mesh_model_op sensor_srv_op[] = { { BT_MESH_MODEL_OP_SENS_SERIES_GET, BT_MESH_LEN_EXACT(2), sensor_series_get }, }; -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), @@ -396,7 +396,7 @@ static struct bt_mesh_model root_models[] = { sensor_srv_op, NULL, NULL), }; -static int vnd_hello(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int vnd_hello(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { char str[32]; @@ -423,7 +423,7 @@ static int vnd_hello(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int vnd_baduser(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int vnd_baduser(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { char str[32]; @@ -448,7 +448,7 @@ static int vnd_baduser(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int vnd_heartbeat(struct bt_mesh_model *model, +static int vnd_heartbeat(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -477,7 +477,7 @@ static const struct bt_mesh_model_op vnd_ops[] = { BT_MESH_MODEL_OP_END, }; -static int pub_update(struct bt_mesh_model *mod) +static int pub_update(const struct bt_mesh_model *mod) { struct net_buf_simple *msg = mod->pub->msg; @@ -491,7 +491,7 @@ static int pub_update(struct bt_mesh_model *mod) BT_MESH_MODEL_PUB_DEFINE(vnd_pub, pub_update, 3 + 1); -static struct bt_mesh_model vnd_models[] = { +static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, MOD_LF, vnd_ops, &vnd_pub, NULL), }; diff --git a/subsys/bluetooth/host/testing.c b/subsys/bluetooth/host/testing.c index 3c118c51e0f..5e2f507bb58 100644 --- a/subsys/bluetooth/host/testing.c +++ b/subsys/bluetooth/host/testing.c @@ -56,7 +56,7 @@ void bt_test_mesh_model_recv(uint16_t src, uint16_t dst, const void *payload, } } -void bt_test_mesh_model_bound(uint16_t addr, struct bt_mesh_model *model, +void bt_test_mesh_model_bound(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx) { struct bt_test_cb *cb; @@ -68,7 +68,7 @@ void bt_test_mesh_model_bound(uint16_t addr, struct bt_mesh_model *model, } } -void bt_test_mesh_model_unbound(uint16_t addr, struct bt_mesh_model *model, +void bt_test_mesh_model_unbound(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx) { struct bt_test_cb *cb; diff --git a/subsys/bluetooth/host/testing.h b/subsys/bluetooth/host/testing.h index 0e6cfbaf785..8ed1fa61e46 100644 --- a/subsys/bluetooth/host/testing.h +++ b/subsys/bluetooth/host/testing.h @@ -14,9 +14,9 @@ void bt_test_mesh_net_recv(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len); void bt_test_mesh_model_recv(uint16_t src, uint16_t dst, const void *payload, size_t payload_len); -void bt_test_mesh_model_bound(uint16_t addr, struct bt_mesh_model *model, +void bt_test_mesh_model_bound(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx); -void bt_test_mesh_model_unbound(uint16_t addr, struct bt_mesh_model *model, +void bt_test_mesh_model_unbound(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx); void bt_test_mesh_prov_invalid_bearer(uint8_t opcode); void bt_test_mesh_trans_incomp_timer_exp(void); diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 4f1941a9e66..2911a42c7af 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -92,12 +92,12 @@ static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE]; (idx)++) #define IS_MOD_BASE(mod, idx, offset) \ - (mod_rel_list[(idx)].elem_base == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_base == (mod)->mod_idx + (offset)) + (mod_rel_list[(idx)].elem_base == *((mod)->elem_idx) && \ + mod_rel_list[(idx)].idx_base == *((mod)->mod_idx) + (offset)) #define IS_MOD_EXTENSION(mod, idx, offset) \ - (mod_rel_list[(idx)].elem_ext == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_ext == (mod)->mod_idx + (offset)) + (mod_rel_list[(idx)].elem_ext == *((mod)->elem_idx) && \ + mod_rel_list[(idx)].idx_ext == *((mod)->mod_idx) + (offset)) #define RELATION_TYPE_EXT 0xFF @@ -114,7 +114,7 @@ static const struct { #endif }; -void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, +void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data), @@ -126,13 +126,13 @@ void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem = &dev_comp->elem[i]; for (j = 0; j < elem->model_count; j++) { - struct bt_mesh_model *model = &elem->models[j]; + const struct bt_mesh_model *model = &elem->models[j]; func(model, elem, false, i == 0, user_data); } for (j = 0; j < elem->vnd_model_count; j++) { - struct bt_mesh_model *model = &elem->vnd_models[j]; + const struct bt_mesh_model *model = &elem->vnd_models[j]; func(model, elem, true, i == 0, user_data); } @@ -181,7 +181,7 @@ static void data_buf_add_mem_offset(struct net_buf_simple *buf, uint8_t *data, s *offset = 0; } -static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void comp_add_model(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, void *user_data) { struct comp_foreach_model_arg *arg = user_data; @@ -196,7 +196,7 @@ static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) -static size_t metadata_model_size(struct bt_mesh_model *mod, +static size_t metadata_model_size(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd) { const struct bt_mesh_models_metadata_entry *entry; @@ -237,13 +237,13 @@ size_t bt_mesh_metadata_page_0_size(void) sizeof(elem->vnd_model_count); for (j = 0; j < elem->model_count; j++) { - struct bt_mesh_model *model = &elem->models[j]; + const struct bt_mesh_model *model = &elem->models[j]; size += metadata_model_size(model, elem, false); } for (j = 0; j < elem->vnd_model_count; j++) { - struct bt_mesh_model *model = &elem->vnd_models[j]; + const struct bt_mesh_model *model = &elem->vnd_models[j]; size += metadata_model_size(model, elem, true); } @@ -252,7 +252,7 @@ size_t bt_mesh_metadata_page_0_size(void) return size; } -static int metadata_add_model(struct bt_mesh_model *mod, +static int metadata_add_model(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, void *user_data) { @@ -322,7 +322,7 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) vnd_count_ptr = data_buf_add_u8_offset(buf, 0, &offset); for (j = 0; j < elem->model_count; j++) { - struct bt_mesh_model *model = &elem->models[j]; + const struct bt_mesh_model *model = &elem->models[j]; if (!model->metadata) { continue; @@ -339,7 +339,7 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) } for (j = 0; j < elem->vnd_model_count; j++) { - struct bt_mesh_model *model = &elem->vnd_models[j]; + const struct bt_mesh_model *model = &elem->vnd_models[j]; if (!model->metadata) { continue; @@ -396,13 +396,13 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, data_buf_add_u8_offset(buf, elem->vnd_model_count, offset); for (i = 0; i < elem->model_count; i++) { - struct bt_mesh_model *model = &elem->models[i]; + const struct bt_mesh_model *model = &elem->models[i]; comp_add_model(model, elem, false, &arg); } for (i = 0; i < elem->vnd_model_count; i++) { - struct bt_mesh_model *model = &elem->vnd_models[i]; + const struct bt_mesh_model *model = &elem->vnd_models[i]; comp_add_model(model, elem, true, &arg); } @@ -452,7 +452,8 @@ int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset) return 0; } -static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset, uint8_t sig_offset) +static uint8_t count_mod_ext(const struct bt_mesh_model *mod, + uint8_t *max_offset, uint8_t sig_offset) { int i; uint8_t extensions = 0; @@ -476,7 +477,7 @@ static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset, uin return extensions; } -static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t sig_offset) +static bool is_cor_present(const struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t sig_offset) { int i; @@ -494,8 +495,9 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t s return false; } -static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t *mod_cnt, - struct net_buf_simple *buf, size_t *offset, uint8_t sig_offset) +static void prep_model_item_header(const struct bt_mesh_model *mod, uint8_t *cor_id, + uint8_t *mod_cnt, struct net_buf_simple *buf, + size_t *offset, uint8_t sig_offset) { uint8_t ext_mod_cnt; bool cor_present; @@ -522,7 +524,7 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, u memset(mod_cnt, ext_mod_cnt, sizeof(uint8_t)); } -static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod, +static void add_items_to_page(struct net_buf_simple *buf, const struct bt_mesh_model *mod, uint8_t ext_mod_cnt, size_t *offset, uint8_t sig_offset) { int i, elem_offset; @@ -531,7 +533,7 @@ static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model * MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i, sig_offset) && mod_rel_list[i].type == RELATION_TYPE_EXT) { - elem_offset = mod->elem_idx - mod_rel_list[i].elem_base; + elem_offset = *(mod->elem_idx) - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && elem_offset < 4 && @@ -555,7 +557,7 @@ static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model * } } -static size_t mod_items_size(struct bt_mesh_model *mod, uint8_t sig_offset) +static size_t mod_items_size(const struct bt_mesh_model *mod, uint8_t sig_offset) { int i, offset; size_t temp_size = 0; @@ -567,7 +569,7 @@ static size_t mod_items_size(struct bt_mesh_model *mod, uint8_t sig_offset) MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i, sig_offset)) { - offset = mod->elem_idx - mod_rel_list[i].elem_base; + offset = *(mod->elem_idx) - mod_rel_list[i].elem_base; temp_size += (ext_mod_cnt < 32 && offset < 4 && offset > -5) ? 1 : 2; } } @@ -701,7 +703,7 @@ static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offse return 0; } -int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) +int32_t bt_mesh_model_pub_period_get(const struct bt_mesh_model *mod) { int32_t period; @@ -741,7 +743,7 @@ int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) } } -static int32_t next_period(struct bt_mesh_model *mod) +static int32_t next_period(const struct bt_mesh_model *mod) { struct bt_mesh_model_pub *pub = mod->pub; uint32_t period = 0; @@ -782,7 +784,7 @@ static int32_t next_period(struct bt_mesh_model *mod) static void publish_sent(int err, void *user_data) { - struct bt_mesh_model *mod = user_data; + const struct bt_mesh_model *mod = user_data; int32_t delay; LOG_DBG("err %d, time %u", err, k_uptime_get_32()); @@ -812,7 +814,7 @@ static const struct bt_mesh_send_cb pub_sent_cb = { .end = publish_sent, }; -static int publish_transmit(struct bt_mesh_model *mod) +static int publish_transmit(const struct bt_mesh_model *mod) { NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX); struct bt_mesh_model_pub *pub = mod->pub; @@ -825,7 +827,7 @@ static int publish_transmit(struct bt_mesh_model *mod) net_buf_simple_add_mem(&sdu, pub->msg->data, pub->msg->len); - return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, mod); + return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, (void *)mod); } static int pub_period_start(struct bt_mesh_model_pub *pub) @@ -846,7 +848,7 @@ static int pub_period_start(struct bt_mesh_model_pub *pub) /* Skip this publish attempt. */ LOG_DBG("Update failed, skipping publish (err: %d)", err); pub->count = 0; - publish_sent(err, pub->mod); + publish_sent(err, (void *)pub->mod); return err; } @@ -878,7 +880,7 @@ static void mod_publish(struct k_work *work) bt_mesh_model_pub_is_retransmission(pub->mod)) { err = pub->update(pub->mod); if (err) { - publish_sent(err, pub->mod); + publish_sent(err, (void *)pub->mod); return; } } @@ -893,16 +895,16 @@ static void mod_publish(struct k_work *work) err = publish_transmit(pub->mod); if (err) { LOG_ERR("Failed to publish (err %d)", err); - publish_sent(err, pub->mod); + publish_sent(err, (void *)pub->mod); } } -struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod) +struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod) { - return &dev_comp->elem[mod->elem_idx]; + return &dev_comp->elem[*(mod->elem_idx)]; } -struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx) +const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx) { struct bt_mesh_elem *elem; @@ -931,7 +933,7 @@ struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_ } #if defined(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) -static int bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model *mod) +static int bt_mesh_vnd_mod_msg_cid_check(const struct bt_mesh_model *mod) { uint16_t cid; const struct bt_mesh_model_op *op; @@ -954,7 +956,7 @@ static int bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model *mod) } #endif -static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void mod_init(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { int i; @@ -973,9 +975,9 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, mod->keys[i] = BT_MESH_KEY_UNUSED; } - mod->elem_idx = elem - dev_comp->elem; + *(mod->elem_idx) = elem - dev_comp->elem; if (vnd) { - mod->mod_idx = mod - elem->vnd_models; + *(mod->mod_idx) = mod - elem->vnd_models; if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)) { *err = bt_mesh_vnd_mod_msg_cid_check(mod); @@ -985,7 +987,7 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } } else { - mod->mod_idx = mod - elem->models; + *(mod->mod_idx) = mod - elem->models; } if (mod->cb && mod->cb->init) { @@ -1082,7 +1084,7 @@ uint16_t bt_mesh_primary_addr(void) return dev_primary_addr; } -static uint16_t *model_group_get(struct bt_mesh_model *mod, uint16_t addr) +static uint16_t *model_group_get(const struct bt_mesh_model *mod, uint16_t addr) { int i; @@ -1097,15 +1099,15 @@ static uint16_t *model_group_get(struct bt_mesh_model *mod, uint16_t addr) struct find_group_visitor_ctx { uint16_t *entry; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; uint16_t addr; }; -static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, void *user_data) +static enum bt_mesh_walk find_group_mod_visitor(const struct bt_mesh_model *mod, void *user_data) { struct find_group_visitor_ctx *ctx = user_data; - if (mod->elem_idx != ctx->mod->elem_idx) { + if (*(mod->elem_idx) != *(ctx->mod->elem_idx)) { return BT_MESH_WALK_CONTINUE; } @@ -1118,7 +1120,7 @@ static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, void return BT_MESH_WALK_CONTINUE; } -uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr) +uint16_t *bt_mesh_model_find_group(const struct bt_mesh_model **mod, uint16_t addr) { struct find_group_visitor_ctx ctx = { .mod = *mod, @@ -1133,7 +1135,7 @@ uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr) } #if CONFIG_BT_MESH_LABEL_COUNT > 0 -static const uint8_t **model_uuid_get(struct bt_mesh_model *mod, const uint8_t *uuid) +static const uint8_t **model_uuid_get(const struct bt_mesh_model *mod, const uint8_t *uuid) { int i; @@ -1155,15 +1157,15 @@ static const uint8_t **model_uuid_get(struct bt_mesh_model *mod, const uint8_t * struct find_uuid_visitor_ctx { const uint8_t **entry; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; const uint8_t *uuid; }; -static enum bt_mesh_walk find_uuid_mod_visitor(struct bt_mesh_model *mod, void *user_data) +static enum bt_mesh_walk find_uuid_mod_visitor(const struct bt_mesh_model *mod, void *user_data) { struct find_uuid_visitor_ctx *ctx = user_data; - if (mod->elem_idx != ctx->mod->elem_idx) { + if (*(mod->elem_idx) != *(ctx->mod->elem_idx)) { return BT_MESH_WALK_CONTINUE; } @@ -1177,7 +1179,7 @@ static enum bt_mesh_walk find_uuid_mod_visitor(struct bt_mesh_model *mod, void * } #endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */ -const uint8_t **bt_mesh_model_find_uuid(struct bt_mesh_model **mod, const uint8_t *uuid) +const uint8_t **bt_mesh_model_find_uuid(const struct bt_mesh_model **mod, const uint8_t *uuid) { #if CONFIG_BT_MESH_LABEL_COUNT > 0 struct find_uuid_visitor_ctx ctx = { @@ -1195,10 +1197,10 @@ const uint8_t **bt_mesh_model_find_uuid(struct bt_mesh_model **mod, const uint8_ #endif } -static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, +static const struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, uint16_t group_addr) { - struct bt_mesh_model *model; + const struct bt_mesh_model *model; uint16_t *match; int i; @@ -1295,7 +1297,7 @@ uint8_t bt_mesh_elem_count(void) return dev_comp->elem_count; } -bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key) +bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key) { int i; @@ -1310,14 +1312,14 @@ bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key) return false; } -static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst, const uint8_t *uuid) +static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const uint8_t *uuid) { if (BT_MESH_ADDR_IS_UNICAST(dst)) { - return (dev_comp->elem[mod->elem_idx].addr == dst); + return (dev_comp->elem[*(mod->elem_idx)].addr == dst); } else if (BT_MESH_ADDR_IS_VIRTUAL(dst)) { return !!bt_mesh_model_find_uuid(&mod, uuid); } else if (BT_MESH_ADDR_IS_GROUP(dst) || - (BT_MESH_ADDR_IS_FIXED_GROUP(dst) && mod->elem_idx != 0)) { + (BT_MESH_ADDR_IS_FIXED_GROUP(dst) && *(mod->elem_idx) != 0)) { return !!bt_mesh_model_find_group(&mod, dst); } @@ -1325,17 +1327,17 @@ static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst, const uint8_t * the lower layers have already confirmed that we are subscribing to * it. All models on the primary element should receive the message. */ - return mod->elem_idx == 0; + return *(mod->elem_idx) == 0; } static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem, - uint32_t opcode, struct bt_mesh_model **model) + uint32_t opcode, const struct bt_mesh_model **model) { uint8_t i; uint8_t count; /* This value shall not be used in shipping end products. */ uint32_t cid = UINT32_MAX; - struct bt_mesh_model *models; + const struct bt_mesh_model *models; /* SIG models cannot contain 3-byte (vendor) OpCodes, and * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so @@ -1416,7 +1418,7 @@ static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple struct bt_mesh_elem *elem, uint32_t opcode) { const struct bt_mesh_model_op *op; - struct bt_mesh_model *model; + const struct bt_mesh_model *model; struct net_buf_simple_state state; int err; @@ -1502,7 +1504,7 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) return err; } -int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data) { @@ -1520,7 +1522,7 @@ int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->addr, cb, cb_data); } -int bt_mesh_model_publish(struct bt_mesh_model *model) +int bt_mesh_model_publish(const struct bt_mesh_model *model) { struct bt_mesh_model_pub *pub = model->pub; @@ -1560,7 +1562,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) return 0; } -struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, +const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, uint16_t company, uint16_t id) { uint8_t i; @@ -1575,7 +1577,7 @@ struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, return NULL; } -struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, +const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, uint16_t id) { uint8_t i; @@ -1594,8 +1596,8 @@ const struct bt_mesh_comp *bt_mesh_comp_get(void) return dev_comp; } -void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, - enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, +void bt_mesh_model_extensions_walk(const struct bt_mesh_model *model, + enum bt_mesh_walk (*cb)(const struct bt_mesh_model *mod, void *user_data), void *user_data) { @@ -1603,14 +1605,14 @@ void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, (void)cb(model, user_data); return; #else - struct bt_mesh_model *it; + const struct bt_mesh_model *it; - if (cb(model, user_data) == BT_MESH_WALK_STOP || !model->next) { + if (cb(model, user_data) == BT_MESH_WALK_STOP || !*(model->next)) { return; } /* List is circular. Step through all models until we reach the start: */ - for (it = model->next; it != model; it = it->next) { + for (it = *(model->next); it != model; it = *(it->next)) { if (cb(it, user_data) == BT_MESH_WALK_STOP) { return; } @@ -1622,7 +1624,7 @@ void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, /* For vendor models, determine the offset within the model relation list * by counting the number of standard SIG models in the associated element. */ -static uint8_t get_sig_offset(struct bt_mesh_model *mod) +static uint8_t get_sig_offset(const struct bt_mesh_model *mod) { const struct bt_mesh_elem *elem = bt_mesh_model_elem(mod); uint8_t i; @@ -1635,16 +1637,16 @@ static uint8_t get_sig_offset(struct bt_mesh_model *mod) return 0; } -static int mod_rel_register(struct bt_mesh_model *base, - struct bt_mesh_model *ext, +static int mod_rel_register(const struct bt_mesh_model *base, + const struct bt_mesh_model *ext, uint8_t type) { LOG_DBG(""); struct mod_relation extension = { - base->elem_idx, - base->mod_idx + get_sig_offset(base), - ext->elem_idx, - ext->mod_idx + get_sig_offset(ext), + *(base->elem_idx), + *(base->mod_idx) + get_sig_offset(base), + *(ext->elem_idx), + *(ext->mod_idx) + get_sig_offset(ext), type, }; int i; @@ -1663,22 +1665,23 @@ static int mod_rel_register(struct bt_mesh_model *base, return -ENOMEM; } -int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_model *base_mod) +int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod, + const struct bt_mesh_model *base_mod) { - struct bt_mesh_model *a = extending_mod; - struct bt_mesh_model *b = base_mod; - struct bt_mesh_model *a_next = a->next; - struct bt_mesh_model *b_next = b->next; - struct bt_mesh_model *it; + const struct bt_mesh_model *a = extending_mod; + const struct bt_mesh_model *b = base_mod; + const struct bt_mesh_model *a_next = *(a->next); + const struct bt_mesh_model *b_next = *(b->next); + const struct bt_mesh_model *it; - base_mod->flags |= BT_MESH_MOD_EXTENDED; + *(base_mod->flags) |= BT_MESH_MOD_EXTENDED; if (a == b) { return 0; } /* Check if a's list contains b */ - for (it = a; (it != NULL) && (it->next != a); it = it->next) { + for (it = a; (it != NULL) && (*(it->next) != a); it = *(it->next)) { if (it == b) { goto register_extension; } @@ -1686,15 +1689,15 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod /* Merge lists */ if (a_next) { - b->next = a_next; + *(b->next) = a_next; } else { - b->next = a; + *(b->next) = a; } if (b_next) { - a->next = b_next; + *(a->next) = b_next; } else { - a->next = b; + *(a->next) = b; } register_extension: @@ -1705,8 +1708,8 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod return 0; } -int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, - struct bt_mesh_model *base_mod) +int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod, + const struct bt_mesh_model *base_mod) { int i, err; uint8_t cor_id = 0; @@ -1740,12 +1743,12 @@ int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, } #endif /* CONFIG_BT_MESH_MODEL_EXTENSIONS */ -bool bt_mesh_model_is_extended(struct bt_mesh_model *model) +bool bt_mesh_model_is_extended(const struct bt_mesh_model *model) { - return model->flags & BT_MESH_MOD_EXTENDED; + return *(model->flags) & BT_MESH_MOD_EXTENDED; } -static int mod_set_bind(struct bt_mesh_model *mod, size_t len_rd, +static int mod_set_bind(const struct bt_mesh_model *mod, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { ssize_t len; @@ -1773,7 +1776,7 @@ static int mod_set_bind(struct bt_mesh_model *mod, size_t len_rd, return 0; } -static int mod_set_sub(struct bt_mesh_model *mod, size_t len_rd, +static int mod_set_sub(const struct bt_mesh_model *mod, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { size_t size = mod->groups_cnt * sizeof(mod->groups[0]); @@ -1820,7 +1823,7 @@ static int mod_set_sub(struct bt_mesh_model *mod, size_t len_rd, return 0; } -static int mod_set_sub_va(struct bt_mesh_model *mod, size_t len_rd, +static int mod_set_sub_va(const struct bt_mesh_model *mod, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { #if CONFIG_BT_MESH_LABEL_COUNT > 0 @@ -1857,7 +1860,7 @@ static int mod_set_sub_va(struct bt_mesh_model *mod, size_t len_rd, return 0; } -static int mod_set_pub(struct bt_mesh_model *mod, size_t len_rd, +static int mod_set_pub(const struct bt_mesh_model *mod, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { struct mod_pub_val pub; @@ -1927,7 +1930,7 @@ static int mod_set_pub(struct bt_mesh_model *mod, size_t len_rd, return 0; } -static int mod_data_set(struct bt_mesh_model *mod, +static int mod_data_set(const struct bt_mesh_model *mod, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { @@ -1946,7 +1949,7 @@ static int mod_data_set(struct bt_mesh_model *mod, static int mod_set(bool vnd, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; uint8_t elem_idx, mod_idx; uint16_t mod_key; int len; @@ -2035,10 +2038,10 @@ static int comp_set(const char *name, size_t len_rd, settings_read_cb read_cb, } BT_MESH_SETTINGS_DEFINE(comp, "cmp", comp_set); -static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, +static void encode_mod_path(const struct bt_mesh_model *mod, bool vnd, const char *key, char *path, size_t path_len) { - uint16_t mod_key = (((uint16_t)mod->elem_idx << 8) | mod->mod_idx); + uint16_t mod_key = (((uint16_t)*(mod->elem_idx) << 8) | *(mod->mod_idx)); if (vnd) { snprintk(path, path_len, "bt/mesh/v/%x/%s", mod_key, key); @@ -2047,7 +2050,7 @@ static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, } } -static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) +static void store_pending_mod_bind(const struct bt_mesh_model *mod, bool vnd) { uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; char path[20]; @@ -2075,7 +2078,7 @@ static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) } } -static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) +static void store_pending_mod_sub(const struct bt_mesh_model *mod, bool vnd) { uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; char path[20]; @@ -2102,7 +2105,7 @@ static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) } } -static void store_pending_mod_sub_va(struct bt_mesh_model *mod, bool vnd) +static void store_pending_mod_sub_va(const struct bt_mesh_model *mod, bool vnd) { #if CONFIG_BT_MESH_LABEL_COUNT > 0 uint16_t uuidxs[CONFIG_BT_MESH_LABEL_COUNT]; @@ -2134,7 +2137,7 @@ static void store_pending_mod_sub_va(struct bt_mesh_model *mod, bool vnd) #endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */ } -static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) +static void store_pending_mod_pub(const struct bt_mesh_model *mod, bool vnd) { struct mod_pub_val pub = {0}; char path[20]; @@ -2167,32 +2170,32 @@ static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) } } -static void store_pending_mod(struct bt_mesh_model *mod, +static void store_pending_mod(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { - if (!mod->flags) { + if (!*(mod->flags)) { return; } - if (mod->flags & BT_MESH_MOD_BIND_PENDING) { - mod->flags &= ~BT_MESH_MOD_BIND_PENDING; + if (*(mod->flags) & BT_MESH_MOD_BIND_PENDING) { + *(mod->flags) &= ~BT_MESH_MOD_BIND_PENDING; store_pending_mod_bind(mod, vnd); } - if (mod->flags & BT_MESH_MOD_SUB_PENDING) { - mod->flags &= ~BT_MESH_MOD_SUB_PENDING; + if (*(mod->flags) & BT_MESH_MOD_SUB_PENDING) { + *(mod->flags) &= ~BT_MESH_MOD_SUB_PENDING; store_pending_mod_sub(mod, vnd); store_pending_mod_sub_va(mod, vnd); } - if (mod->flags & BT_MESH_MOD_PUB_PENDING) { - mod->flags &= ~BT_MESH_MOD_PUB_PENDING; + if (*(mod->flags) & BT_MESH_MOD_PUB_PENDING) { + *(mod->flags) &= ~BT_MESH_MOD_PUB_PENDING; store_pending_mod_pub(mod, vnd); } - if (mod->flags & BT_MESH_MOD_DATA_PENDING) { - mod->flags &= ~BT_MESH_MOD_DATA_PENDING; + if (*(mod->flags) & BT_MESH_MOD_DATA_PENDING) { + *(mod->flags) &= ~BT_MESH_MOD_DATA_PENDING; mod->cb->pending_store(mod); } } @@ -2202,21 +2205,21 @@ void bt_mesh_model_pending_store(void) bt_mesh_model_foreach(store_pending_mod, NULL); } -void bt_mesh_model_bind_store(struct bt_mesh_model *mod) +void bt_mesh_model_bind_store(const struct bt_mesh_model *mod) { - mod->flags |= BT_MESH_MOD_BIND_PENDING; + *(mod->flags) |= BT_MESH_MOD_BIND_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } -void bt_mesh_model_sub_store(struct bt_mesh_model *mod) +void bt_mesh_model_sub_store(const struct bt_mesh_model *mod) { - mod->flags |= BT_MESH_MOD_SUB_PENDING; + *(mod->flags) |= BT_MESH_MOD_SUB_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } -void bt_mesh_model_pub_store(struct bt_mesh_model *mod) +void bt_mesh_model_pub_store(const struct bt_mesh_model *mod) { - mod->flags |= BT_MESH_MOD_PUB_PENDING; + *(mod->flags) |= BT_MESH_MOD_PUB_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } @@ -2401,7 +2404,7 @@ int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page) return 0; } -int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, +int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len) { @@ -2550,7 +2553,7 @@ int bt_mesh_models_metadata_change_prepare(void) #endif } -static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void commit_mod(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update && @@ -2579,9 +2582,9 @@ void bt_mesh_model_settings_commit(void) bt_mesh_model_foreach(commit_mod, NULL); } -void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod) +void bt_mesh_model_data_store_schedule(const struct bt_mesh_model *mod) { - mod->flags |= BT_MESH_MOD_DATA_PENDING; + *(mod->flags) |= BT_MESH_MOD_DATA_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index f58c6f1d449..663f99c84d2 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -32,23 +32,23 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); bool bt_mesh_has_addr(uint16_t addr); -bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key); +bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key); -void bt_mesh_model_extensions_walk(struct bt_mesh_model *root, - enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, +void bt_mesh_model_extensions_walk(const struct bt_mesh_model *root, + enum bt_mesh_walk (*cb)(const struct bt_mesh_model *mod, void *user_data), void *user_data); -uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr); -const uint8_t **bt_mesh_model_find_uuid(struct bt_mesh_model **mod, const uint8_t *uuid); +uint16_t *bt_mesh_model_find_group(const struct bt_mesh_model **mod, uint16_t addr); +const uint8_t **bt_mesh_model_find_uuid(const struct bt_mesh_model **mod, const uint8_t *uuid); -void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, +void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data), void *user_data); -int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod); +int32_t bt_mesh_model_pub_period_get(const struct bt_mesh_model *mod); void bt_mesh_comp_provision(uint16_t addr); void bt_mesh_comp_unprovision(void); @@ -57,7 +57,7 @@ uint16_t bt_mesh_primary_addr(void); const struct bt_mesh_comp *bt_mesh_comp_get(void); -struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx); +const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx); int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); @@ -74,9 +74,9 @@ void bt_mesh_comp_data_clear(void); int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t offset); void bt_mesh_model_pending_store(void); -void bt_mesh_model_bind_store(struct bt_mesh_model *mod); -void bt_mesh_model_sub_store(struct bt_mesh_model *mod); -void bt_mesh_model_pub_store(struct bt_mesh_model *mod); +void bt_mesh_model_bind_store(const struct bt_mesh_model *mod); +void bt_mesh_model_sub_store(const struct bt_mesh_model *mod); +void bt_mesh_model_pub_store(const struct bt_mesh_model *mod); void bt_mesh_model_settings_commit(void); /** @brief Register a callback function hook for mesh model messages. diff --git a/subsys/bluetooth/mesh/blob_cli.c b/subsys/bluetooth/mesh/blob_cli.c index 0effbf61be7..4fd0fe7bac9 100644 --- a/subsys/bluetooth/mesh/blob_cli.c +++ b/subsys/bluetooth/mesh/blob_cli.c @@ -1204,10 +1204,10 @@ static void rx_block_status(struct bt_mesh_blob_cli *cli, blob_cli_broadcast_rsp(cli, target); } -static int handle_xfer_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_xfer_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); enum bt_mesh_blob_xfer_phase expected_phase; struct bt_mesh_blob_target *target; struct bt_mesh_blob_xfer_info info = { 0 }; @@ -1276,10 +1276,10 @@ static int handle_xfer_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_block_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_block_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); struct block_status status = { .status = BT_MESH_BLOB_SUCCESS, .block.number = cli->block.number, @@ -1330,10 +1330,10 @@ static int handle_block_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_block_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_block_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); struct bt_mesh_blob_target *target; struct block_status status = { 0 }; uint8_t status_and_format; @@ -1401,10 +1401,10 @@ static int handle_block_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_info_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); struct bt_mesh_blob_cli_caps caps; enum bt_mesh_blob_status status; struct bt_mesh_blob_target *target; @@ -1458,9 +1458,9 @@ const struct bt_mesh_model_op _bt_mesh_blob_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int blob_cli_init(struct bt_mesh_model *mod) +static int blob_cli_init(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); cli->mod = mod; @@ -1471,9 +1471,9 @@ static int blob_cli_init(struct bt_mesh_model *mod) return 0; } -static void blob_cli_reset(struct bt_mesh_model *mod) +static void blob_cli_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_cli *cli = mod->user_data; + struct bt_mesh_blob_cli *cli = *(mod->user_data); cli_state_reset(cli); } diff --git a/subsys/bluetooth/mesh/blob_srv.c b/subsys/bluetooth/mesh/blob_srv.c index 1e6cb9bc91a..2fee121415d 100644 --- a/subsys/bluetooth/mesh/blob_srv.c +++ b/subsys/bluetooth/mesh/blob_srv.c @@ -415,10 +415,10 @@ static void block_status_rsp(struct bt_mesh_blob_srv *srv, (void)bt_mesh_model_send(srv->mod, ctx, &buf, NULL, NULL); } -static int handle_xfer_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_xfer_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); LOG_DBG(""); @@ -435,10 +435,10 @@ static int handle_xfer_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct return 0; } -static int handle_xfer_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_xfer_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); enum bt_mesh_blob_status status; enum bt_mesh_blob_xfer_mode mode; uint64_t id; @@ -566,11 +566,11 @@ static int handle_xfer_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } -static int handle_xfer_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_xfer_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { enum bt_mesh_blob_status status = BT_MESH_BLOB_SUCCESS; - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); uint64_t id; id = net_buf_simple_pull_le64(buf); @@ -594,11 +594,11 @@ static int handle_xfer_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_block_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_block_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { enum bt_mesh_blob_status status; - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); switch (srv->phase) { case BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK: @@ -625,10 +625,10 @@ static int handle_block_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *c return 0; } -static int handle_block_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_block_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); enum bt_mesh_blob_status status; uint16_t block_number, chunk_size; int err; @@ -720,10 +720,10 @@ static int handle_block_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_chunk(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); struct bt_mesh_blob_chunk chunk; size_t expected_size = 0; uint16_t idx; @@ -810,10 +810,10 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_info_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_info_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); LOG_DBG(""); @@ -847,9 +847,9 @@ const struct bt_mesh_model_op _bt_mesh_blob_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int blob_srv_init(struct bt_mesh_model *mod) +static int blob_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); srv->mod = mod; srv->state.ttl = BT_MESH_TTL_DEFAULT; @@ -861,11 +861,11 @@ static int blob_srv_init(struct bt_mesh_model *mod) return 0; } -static int blob_srv_settings_set(struct bt_mesh_model *mod, const char *name, +static int blob_srv_settings_set(const struct bt_mesh_model *mod, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); ssize_t len; if (len_rd < offsetof(struct bt_mesh_blob_srv_state, blocks)) { @@ -903,9 +903,9 @@ static int blob_srv_settings_set(struct bt_mesh_model *mod, const char *name, return 0; } -static int blob_srv_start(struct bt_mesh_model *mod) +static int blob_srv_start(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); int err = -ENOTSUP; if (srv->phase == BT_MESH_BLOB_XFER_PHASE_INACTIVE) { @@ -931,9 +931,9 @@ static int blob_srv_start(struct bt_mesh_model *mod) return 0; } -static void blob_srv_reset(struct bt_mesh_model *mod) +static void blob_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = mod->user_data; + struct bt_mesh_blob_srv *srv = *(mod->user_data); phase_set(srv, BT_MESH_BLOB_XFER_PHASE_INACTIVE); srv->state.xfer.mode = BT_MESH_BLOB_XFER_MODE_NONE; diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 7ee3a590cd0..2f05fea2f15 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -48,7 +48,7 @@ static int32_t msg_timeout; static struct bt_mesh_cfg_cli *cli; -static int comp_data_status(struct bt_mesh_model *model, +static int comp_data_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -85,7 +85,7 @@ static int comp_data_status(struct bt_mesh_model *model, return 0; } -static uint8_t state_status_u8(struct bt_mesh_model *model, +static uint8_t state_status_u8(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint32_t expect_status) @@ -111,7 +111,7 @@ static uint8_t state_status_u8(struct bt_mesh_model *model, return status; } -static int beacon_status(struct bt_mesh_model *model, +static int beacon_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -126,7 +126,7 @@ static int beacon_status(struct bt_mesh_model *model, return 0; } -static int ttl_status(struct bt_mesh_model *model, +static int ttl_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -141,7 +141,7 @@ static int ttl_status(struct bt_mesh_model *model, return 0; } -static int friend_status(struct bt_mesh_model *model, +static int friend_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -156,7 +156,7 @@ static int friend_status(struct bt_mesh_model *model, return 0; } -static int gatt_proxy_status(struct bt_mesh_model *model, +static int gatt_proxy_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -178,7 +178,7 @@ struct krp_param { uint8_t *phase; }; -static int krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int krp_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { int err = 0; @@ -223,7 +223,7 @@ struct relay_param { uint8_t *transmit; }; -static int relay_status(struct bt_mesh_model *model, +static int relay_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -257,7 +257,7 @@ static int relay_status(struct bt_mesh_model *model, return 0; } -static int net_transmit_status(struct bt_mesh_model *model, +static int net_transmit_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -277,7 +277,7 @@ struct net_key_param { uint16_t net_idx; }; -static int net_key_status(struct bt_mesh_model *model, +static int net_key_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -345,7 +345,7 @@ int bt_mesh_key_idx_unpack_list(struct net_buf_simple *buf, uint16_t *dst_arr, return buf->len > 0 ? -EMSGSIZE : 0; } -static int net_key_list(struct bt_mesh_model *model, +static int net_key_list(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -381,7 +381,7 @@ static int net_key_list(struct bt_mesh_model *model, return err; } -static int node_reset_status(struct bt_mesh_model *model, +static int node_reset_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -412,7 +412,7 @@ struct app_key_param { uint16_t app_idx; }; -static int app_key_status(struct bt_mesh_model *model, +static int app_key_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -461,7 +461,7 @@ struct app_key_list_param { size_t *key_cnt; }; -static int app_key_list(struct bt_mesh_model *model, +static int app_key_list(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -521,7 +521,7 @@ struct mod_app_param { uint16_t cid; }; -static int mod_app_status(struct bt_mesh_model *model, +static int mod_app_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -695,7 +695,7 @@ static int mod_app_list_handle(struct bt_mesh_msg_ctx *ctx, struct net_buf_simpl return err; } -static int mod_app_list(struct bt_mesh_model *model, +static int mod_app_list(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, @@ -704,7 +704,7 @@ static int mod_app_list(struct bt_mesh_model *model, return mod_app_list_handle(ctx, buf, OP_SIG_MOD_APP_LIST, false); } -static int mod_app_list_vnd(struct bt_mesh_model *model, +static int mod_app_list_vnd(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -722,7 +722,7 @@ struct mod_pub_param { struct bt_mesh_cfg_cli_mod_pub *pub; }; -static int mod_pub_status(struct bt_mesh_model *model, +static int mod_pub_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -807,7 +807,7 @@ struct mod_sub_param { uint16_t cid; }; -static int mod_sub_status(struct bt_mesh_model *model, +static int mod_sub_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -866,7 +866,7 @@ static int mod_sub_status(struct bt_mesh_model *model, return err; } -static int mod_sub_list(struct bt_mesh_model *model, +static int mod_sub_list(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, @@ -875,7 +875,7 @@ static int mod_sub_list(struct bt_mesh_model *model, return mod_sub_list_handle(ctx, buf, OP_MOD_SUB_LIST, false); } -static int mod_sub_list_vnd(struct bt_mesh_model *model, +static int mod_sub_list_vnd(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -890,7 +890,7 @@ struct hb_sub_param { struct bt_mesh_cfg_cli_hb_sub *sub; }; -static int hb_sub_status(struct bt_mesh_model *model, +static int hb_sub_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -934,7 +934,7 @@ struct hb_pub_param { struct bt_mesh_cfg_cli_hb_pub *pub; }; -static int hb_pub_status(struct bt_mesh_model *model, +static int hb_pub_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -979,7 +979,7 @@ struct node_idt_param { uint8_t *identity; }; -static int node_identity_status(struct bt_mesh_model *model, +static int node_identity_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1020,7 +1020,7 @@ struct lpn_timeout_param { int32_t *polltimeout; }; -static int lpn_timeout_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int lpn_timeout_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct lpn_timeout_param *param; @@ -1087,19 +1087,19 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int cfg_cli_init(struct bt_mesh_model *model) +static int cfg_cli_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Configuration Client only allowed in primary element"); return -EINVAL; } - if (!model->user_data) { + if (!*(model->user_data)) { LOG_ERR("No Configuration Client context provided"); return -EINVAL; } - cli = model->user_data; + cli = *(model->user_data); cli->model = model; msg_timeout = CONFIG_BT_MESH_CFG_CLI_TIMEOUT; @@ -1108,7 +1108,7 @@ static int cfg_cli_init(struct bt_mesh_model *model) * and remote keys are allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_ANY; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 1684748ba83..5920ecd6dc1 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -48,7 +48,7 @@ static void node_reset_pending_handler(struct k_work *work) static K_WORK_DEFINE(node_reset_pending, node_reset_pending_handler); -static int dev_comp_data_get(struct bt_mesh_model *model, +static int dev_comp_data_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -86,7 +86,7 @@ static int dev_comp_data_get(struct bt_mesh_model *model, return err; } -static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, +static const struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, struct net_buf_simple *buf, bool *vnd) { if (buf->len < 4) { @@ -113,9 +113,9 @@ static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, } } -static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, const uint8_t *uuid, - uint16_t app_idx, uint8_t cred_flag, uint8_t ttl, uint8_t period, - uint8_t retransmit, bool store) +static uint8_t _mod_pub_set(const struct bt_mesh_model *model, uint16_t pub_addr, + const uint8_t *uuid, uint16_t app_idx, uint8_t cred_flag, + uint8_t ttl, uint8_t period, uint8_t retransmit, bool store) { if (!model->pub) { return STATUS_NVAL_PUB_PARAM; @@ -199,7 +199,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, cons return STATUS_SUCCESS; } -static uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx) +static uint8_t mod_bind(const struct bt_mesh_model *model, uint16_t key_idx) { int i; @@ -232,7 +232,7 @@ static uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx) return STATUS_INSUFF_RESOURCES; } -static uint8_t mod_unbind(struct bt_mesh_model *model, uint16_t key_idx, bool store) +static uint8_t mod_unbind(const struct bt_mesh_model *model, uint16_t key_idx, bool store) { int i; @@ -284,7 +284,7 @@ static void key_idx_pack_list(struct net_buf_simple *buf, uint16_t *arr, size_t } -static int send_app_key_status(struct bt_mesh_model *model, +static int send_app_key_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t status, uint16_t app_idx, uint16_t net_idx) @@ -302,7 +302,7 @@ static int send_app_key_status(struct bt_mesh_model *model, return 0; } -static int app_key_add(struct bt_mesh_model *model, +static int app_key_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -318,7 +318,7 @@ static int app_key_add(struct bt_mesh_model *model, return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); } -static int app_key_update(struct bt_mesh_model *model, +static int app_key_update(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -335,7 +335,7 @@ static int app_key_update(struct bt_mesh_model *model, return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); } -static void mod_app_key_del(struct bt_mesh_model *mod, +static void mod_app_key_del(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { @@ -354,7 +354,7 @@ static void app_key_evt(uint16_t app_idx, uint16_t net_idx, BT_MESH_APP_KEY_CB_DEFINE(app_key_evt); -static int app_key_del(struct bt_mesh_model *model, +static int app_key_del(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -373,7 +373,7 @@ static int app_key_del(struct bt_mesh_model *model, /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */ #define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2) -static int app_key_get(struct bt_mesh_model *model, +static int app_key_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -422,7 +422,7 @@ static int app_key_get(struct bt_mesh_model *model, return 0; } -static int beacon_get(struct bt_mesh_model *model, +static int beacon_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -441,7 +441,7 @@ static int beacon_get(struct bt_mesh_model *model, return 0; } -static int beacon_set(struct bt_mesh_model *model, +static int beacon_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -467,7 +467,7 @@ static int beacon_set(struct bt_mesh_model *model, return 0; } -static int default_ttl_get(struct bt_mesh_model *model, +static int default_ttl_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -486,7 +486,7 @@ static int default_ttl_get(struct bt_mesh_model *model, return 0; } -static int default_ttl_set(struct bt_mesh_model *model, +static int default_ttl_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -512,7 +512,7 @@ static int default_ttl_set(struct bt_mesh_model *model, return 0; } -static int send_gatt_proxy_status(struct bt_mesh_model *model, +static int send_gatt_proxy_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1); @@ -527,7 +527,7 @@ static int send_gatt_proxy_status(struct bt_mesh_model *model, return 0; } -static int gatt_proxy_get(struct bt_mesh_model *model, +static int gatt_proxy_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -537,7 +537,7 @@ static int gatt_proxy_get(struct bt_mesh_model *model, return send_gatt_proxy_status(model, ctx); } -static int gatt_proxy_set(struct bt_mesh_model *model, +static int gatt_proxy_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -561,7 +561,7 @@ static int gatt_proxy_set(struct bt_mesh_model *model, return send_gatt_proxy_status(model, ctx); } -static int net_transmit_get(struct bt_mesh_model *model, +static int net_transmit_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -580,7 +580,7 @@ static int net_transmit_get(struct bt_mesh_model *model, return 0; } -static int net_transmit_set(struct bt_mesh_model *model, +static int net_transmit_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -604,7 +604,7 @@ static int net_transmit_set(struct bt_mesh_model *model, return 0; } -static int relay_get(struct bt_mesh_model *model, +static int relay_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -624,7 +624,7 @@ static int relay_get(struct bt_mesh_model *model, return 0; } -static int relay_set(struct bt_mesh_model *model, +static int relay_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -651,10 +651,10 @@ static int relay_set(struct bt_mesh_model *model, return 0; } -static int send_mod_pub_status(struct bt_mesh_model *cfg_mod, +static int send_mod_pub_status(const struct bt_mesh_model *cfg_mod, struct bt_mesh_msg_ctx *ctx, uint16_t elem_addr, uint16_t pub_addr, bool vnd, - struct bt_mesh_model *mod, uint8_t status, + const struct bt_mesh_model *mod, uint8_t status, uint8_t *mod_id) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14); @@ -691,11 +691,11 @@ static int send_mod_pub_status(struct bt_mesh_model *cfg_mod, return 0; } -static int mod_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mod_pub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint16_t elem_addr, pub_addr = 0U; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -742,13 +742,13 @@ static int mod_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, status, mod_id); } -static int mod_pub_set(struct bt_mesh_model *model, +static int mod_pub_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t retransmit, status, pub_ttl, pub_period, cred_flag; uint16_t elem_addr, pub_addr, pub_app_idx; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id; bool vnd; @@ -807,7 +807,7 @@ static int mod_pub_set(struct bt_mesh_model *model, status, mod_id); } -static size_t mod_sub_list_clear(struct bt_mesh_model *mod) +static size_t mod_sub_list_clear(const struct bt_mesh_model *mod) { size_t clear_count; int i; @@ -838,7 +838,7 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) return clear_count; } -static int mod_pub_va_set(struct bt_mesh_model *model, +static int mod_pub_va_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -846,7 +846,7 @@ static int mod_pub_va_set(struct bt_mesh_model *model, uint8_t retransmit, status, pub_ttl, pub_period, cred_flag; uint16_t elem_addr, pub_app_idx; uint16_t pub_addr = 0U; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; @@ -915,7 +915,7 @@ static int mod_pub_va_set(struct bt_mesh_model *model, status, mod_id); } -static int send_mod_sub_status(struct bt_mesh_model *model, +static int send_mod_sub_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t status, uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id, bool vnd) @@ -943,12 +943,12 @@ static int send_mod_sub_status(struct bt_mesh_model *model, return 0; } -static int mod_sub_add(struct bt_mesh_model *model, +static int mod_sub_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint16_t elem_addr, sub_addr; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id; uint8_t status; @@ -1021,12 +1021,12 @@ static int mod_sub_add(struct bt_mesh_model *model, mod_id, vnd); } -static int mod_sub_del(struct bt_mesh_model *model, +static int mod_sub_del(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint16_t elem_addr, sub_addr; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id; uint16_t *match; @@ -1092,7 +1092,7 @@ static int mod_sub_del(struct bt_mesh_model *model, mod_id, vnd); } -static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, void *user_data) +static enum bt_mesh_walk mod_sub_clear_visitor(const struct bt_mesh_model *mod, void *user_data) { if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { bt_mesh_lpn_group_del(mod->groups, mod->groups_cnt); @@ -1103,12 +1103,12 @@ static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, void * return BT_MESH_WALK_CONTINUE; } -static int mod_sub_overwrite(struct bt_mesh_model *model, +static int mod_sub_overwrite(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint16_t elem_addr, sub_addr; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id; uint8_t status; @@ -1174,11 +1174,11 @@ static int mod_sub_overwrite(struct bt_mesh_model *model, mod_id, vnd); } -static int mod_sub_del_all(struct bt_mesh_model *model, +static int mod_sub_del_all(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint16_t elem_addr; uint8_t *mod_id; @@ -1232,13 +1232,13 @@ struct mod_sub_list_ctx { struct net_buf_simple *msg; }; -static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, void *ctx) +static enum bt_mesh_walk mod_sub_list_visitor(const struct bt_mesh_model *mod, void *ctx) { struct mod_sub_list_ctx *visit = ctx; int count = 0; int i; - if (mod->elem_idx != visit->elem_idx) { + if (*(mod->elem_idx) != visit->elem_idx) { return BT_MESH_WALK_CONTINUE; } @@ -1257,18 +1257,18 @@ static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, void *c count++; } - LOG_DBG("sublist: model %u:%x: %u groups", mod->elem_idx, mod->id, count); + LOG_DBG("sublist: model %u:%x: %u groups", *(mod->elem_idx), mod->id, count); return BT_MESH_WALK_CONTINUE; } -static int mod_sub_get(struct bt_mesh_model *model, +static int mod_sub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint16_t addr, id; @@ -1306,7 +1306,7 @@ static int mod_sub_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&msg, id); visit_ctx.msg = &msg; - visit_ctx.elem_idx = mod->elem_idx; + visit_ctx.elem_idx = *(mod->elem_idx); bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: @@ -1317,13 +1317,13 @@ static int mod_sub_get(struct bt_mesh_model *model, return 0; } -static int mod_sub_get_vnd(struct bt_mesh_model *model, +static int mod_sub_get_vnd(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint16_t company, addr, id; @@ -1365,7 +1365,7 @@ static int mod_sub_get_vnd(struct bt_mesh_model *model, net_buf_simple_add_le16(&msg, id); visit_ctx.msg = &msg; - visit_ctx.elem_idx = mod->elem_idx; + visit_ctx.elem_idx = *(mod->elem_idx); bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: @@ -1376,13 +1376,13 @@ static int mod_sub_get_vnd(struct bt_mesh_model *model, return 0; } -static int mod_sub_va_add(struct bt_mesh_model *model, +static int mod_sub_va_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; @@ -1478,13 +1478,13 @@ static int mod_sub_va_add(struct bt_mesh_model *model, mod_id, vnd); } -static int mod_sub_va_del(struct bt_mesh_model *model, +static int mod_sub_va_del(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; @@ -1562,13 +1562,13 @@ static int mod_sub_va_del(struct bt_mesh_model *model, mod_id, vnd); } -static int mod_sub_va_overwrite(struct bt_mesh_model *model, +static int mod_sub_va_overwrite(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; @@ -1638,7 +1638,7 @@ static int mod_sub_va_overwrite(struct bt_mesh_model *model, mod_id, vnd); } -static int send_net_key_status(struct bt_mesh_model *model, +static int send_net_key_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint16_t idx, uint8_t status) { @@ -1656,7 +1656,7 @@ static int send_net_key_status(struct bt_mesh_model *model, return 0; } -static int net_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int net_key_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t status; @@ -1675,7 +1675,7 @@ static int net_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return send_net_key_status(model, ctx, idx, status); } -static int net_key_update(struct bt_mesh_model *model, +static int net_key_update(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1693,7 +1693,7 @@ static int net_key_update(struct bt_mesh_model *model, return send_net_key_status(model, ctx, idx, status); } -static int net_key_del(struct bt_mesh_model *model, +static int net_key_del(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1720,7 +1720,7 @@ static int net_key_del(struct bt_mesh_model *model, return send_net_key_status(model, ctx, del_idx, STATUS_SUCCESS); } -static int net_key_get(struct bt_mesh_model *model, +static int net_key_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1745,7 +1745,7 @@ static int net_key_get(struct bt_mesh_model *model, return 0; } -static int send_node_id_status(struct bt_mesh_model *model, +static int send_node_id_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t status, uint16_t net_idx, uint8_t node_id) @@ -1764,7 +1764,7 @@ static int send_node_id_status(struct bt_mesh_model *model, return 0; } -static int node_identity_get(struct bt_mesh_model *model, +static int node_identity_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1786,7 +1786,7 @@ static int node_identity_get(struct bt_mesh_model *model, return send_node_id_status(model, ctx, status, idx, node_id); } -static int node_identity_set(struct bt_mesh_model *model, +static int node_identity_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1824,7 +1824,7 @@ static int node_identity_set(struct bt_mesh_model *model, } static void create_mod_app_status(struct net_buf_simple *msg, - struct bt_mesh_model *mod, bool vnd, + const struct bt_mesh_model *mod, bool vnd, uint16_t elem_addr, uint16_t app_idx, uint8_t status, uint8_t *mod_id) { @@ -1841,13 +1841,13 @@ static void create_mod_app_status(struct net_buf_simple *msg, } } -static int mod_app_bind(struct bt_mesh_model *model, +static int mod_app_bind(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -1881,7 +1881,7 @@ static int mod_app_bind(struct bt_mesh_model *model, } /* Some models only allow device key based access */ - if (mod->flags & BT_MESH_MOD_DEVKEY_ONLY) { + if (*(mod->flags) & BT_MESH_MOD_DEVKEY_ONLY) { LOG_ERR("Client tried to bind AppKey to DevKey based model"); status = STATUS_CANNOT_BIND; goto send_status; @@ -1905,13 +1905,13 @@ static int mod_app_bind(struct bt_mesh_model *model, return 0; } -static int mod_app_unbind(struct bt_mesh_model *model, +static int mod_app_unbind(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -1964,7 +1964,7 @@ static int mod_app_unbind(struct bt_mesh_model *model, #define KEY_LIST_LEN (CONFIG_BT_MESH_MODEL_KEY_COUNT * 2) -static int mod_app_get(struct bt_mesh_model *model, +static int mod_app_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1973,7 +1973,7 @@ static int mod_app_get(struct bt_mesh_model *model, 9 + KEY_LIST_LEN), BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, 9 + KEY_LIST_LEN))); - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint8_t *mod_id, status; uint16_t elem_addr; @@ -2050,7 +2050,7 @@ static void reset_send_end(int err, void *cb_data) k_work_submit(&node_reset_pending); } -static int node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int node_reset(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { static const struct bt_mesh_send_cb reset_cb = { @@ -2072,7 +2072,7 @@ static int node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int send_friend_status(struct bt_mesh_model *model, +static int send_friend_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1); @@ -2087,7 +2087,7 @@ static int send_friend_status(struct bt_mesh_model *model, return 0; } -static int friend_get(struct bt_mesh_model *model, +static int friend_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2097,7 +2097,7 @@ static int friend_get(struct bt_mesh_model *model, return send_friend_status(model, ctx); } -static int friend_set(struct bt_mesh_model *model, +static int friend_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2114,7 +2114,7 @@ static int friend_set(struct bt_mesh_model *model, return send_friend_status(model, ctx); } -static int lpn_timeout_get(struct bt_mesh_model *model, +static int lpn_timeout_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2160,7 +2160,7 @@ static int lpn_timeout_get(struct bt_mesh_model *model, return 0; } -static int send_krp_status(struct bt_mesh_model *model, +static int send_krp_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint16_t idx, uint8_t phase, uint8_t status) { @@ -2179,7 +2179,7 @@ static int send_krp_status(struct bt_mesh_model *model, return 0; } -static int krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int krp_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t kr_phase, status; @@ -2198,7 +2198,7 @@ static int krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return send_krp_status(model, ctx, idx, kr_phase, status); } -static int krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int krp_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t phase, status; @@ -2254,7 +2254,7 @@ struct hb_pub_param { uint16_t net_idx; } __packed; -static int hb_pub_send_status(struct bt_mesh_model *model, +static int hb_pub_send_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t status, const struct bt_mesh_hb_pub *pub) { @@ -2284,7 +2284,7 @@ static int hb_pub_send_status(struct bt_mesh_model *model, return 0; } -static int heartbeat_pub_get(struct bt_mesh_model *model, +static int heartbeat_pub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2297,7 +2297,7 @@ static int heartbeat_pub_get(struct bt_mesh_model *model, return hb_pub_send_status(model, ctx, STATUS_SUCCESS, &pub); } -static int heartbeat_pub_set(struct bt_mesh_model *model, +static int heartbeat_pub_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2357,7 +2357,7 @@ static int heartbeat_pub_set(struct bt_mesh_model *model, return hb_pub_send_status(model, ctx, status, &pub); } -static int hb_sub_send_status(struct bt_mesh_model *model, +static int hb_sub_send_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_hb_sub *sub) { @@ -2382,7 +2382,7 @@ static int hb_sub_send_status(struct bt_mesh_model *model, return 0; } -static int heartbeat_sub_get(struct bt_mesh_model *model, +static int heartbeat_sub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2395,7 +2395,7 @@ static int heartbeat_sub_get(struct bt_mesh_model *model, return hb_sub_send_status(model, ctx, &sub); } -static int heartbeat_sub_set(struct bt_mesh_model *model, +static int heartbeat_sub_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -2508,7 +2508,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int cfg_srv_init(struct bt_mesh_model *model) +static int cfg_srv_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Configuration Server only allowed in primary element"); @@ -2520,7 +2520,7 @@ static int cfg_srv_init(struct bt_mesh_model *model) * device-key is allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_LOCAL; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } @@ -2529,7 +2529,7 @@ const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = { .init = cfg_srv_init, }; -static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void mod_reset(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { size_t clear_count; diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 0a9ecba6cec..245052b58f8 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -112,11 +112,11 @@ static void receivers_status_rsp(struct bt_mesh_dfd_srv *srv, bt_mesh_model_send(srv->mod, ctx, &buf, NULL, NULL); } -static int handle_receivers_add(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_receivers_add(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { enum bt_mesh_dfd_status status = BT_MESH_DFD_SUCCESS; - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); if (buf->len % 3) { return -EINVAL; @@ -143,20 +143,20 @@ static int handle_receivers_add(struct bt_mesh_model *mod, struct bt_mesh_msg_ct return 0; } -static int handle_receivers_delete_all(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_receivers_delete_all(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); receivers_status_rsp(srv, ctx, bt_mesh_dfd_srv_receivers_delete_all(srv)); return 0; } -static int handle_receivers_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_receivers_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); uint16_t first, cnt; uint8_t progress; int i; @@ -206,7 +206,7 @@ static enum bt_mesh_dfu_iter slot_space_cb(const struct bt_mesh_dfu_slot *slot, return BT_MESH_DFU_ITER_CONTINUE; } -static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { size_t size = 0; @@ -226,7 +226,7 @@ static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg net_buf_simple_add_le32(&rsp, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE - size); #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); if (srv->oob_schemes.count > 0) { net_buf_simple_add_u8(&rsp, 1); @@ -268,20 +268,20 @@ static void status_rsp(struct bt_mesh_dfd_srv *srv, struct bt_mesh_msg_ctx *ctx, bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } -static int handle_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); return 0; } -static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); struct bt_mesh_dfd_start_params params; uint8_t byte; @@ -310,31 +310,31 @@ static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_suspend(struct bt_mesh_model *mod, +static int handle_suspend(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); status_rsp(srv, ctx, bt_mesh_dfd_srv_suspend(srv)); return 0; } -static int handle_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); bt_mesh_dfd_srv_cancel(srv, ctx); return 0; } -static int handle_apply(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_apply(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); status_rsp(srv, ctx, bt_mesh_dfd_srv_apply(srv)); @@ -393,10 +393,10 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, upload_status_rsp_with_progress(srv, ctx, status, progress); } -static int handle_upload_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_upload_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); @@ -438,10 +438,10 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms return err; } -static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); size_t meta_len, fwid_len, size; const uint8_t *meta, *fwid; uint16_t timeout_base; @@ -560,10 +560,10 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); uint8_t uri_len; uint8_t *uri; uint16_t fwid_len; @@ -651,10 +651,10 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg return 0; } -static int handle_upload_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_upload_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD @@ -690,10 +690,10 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv, bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } -static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_fw_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); struct bt_mesh_dfu_slot *slot; const uint8_t *fwid; size_t fwid_len; @@ -714,10 +714,10 @@ static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_fw_get_by_index(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_fw_get_by_index(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); const struct bt_mesh_dfu_slot *slot; uint16_t idx; @@ -735,10 +735,10 @@ static int handle_fw_get_by_index(struct bt_mesh_model *mod, struct bt_mesh_msg_ return 0; } -static int handle_fw_delete(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_fw_delete(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); const uint8_t *fwid; size_t fwid_len; @@ -764,10 +764,10 @@ static enum bt_mesh_dfu_iter slot_del_cb(const struct bt_mesh_dfu_slot *slot, return BT_MESH_DFU_ITER_CONTINUE; } -static int handle_fw_delete_all(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_fw_delete_all(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); fw_status_rsp(srv, ctx, bt_mesh_dfd_srv_fw_delete_all(srv), 0xffff, NULL, 0); @@ -923,9 +923,9 @@ const struct bt_mesh_blob_srv_cb _bt_mesh_dfd_srv_blob_cb = { .suspended = upload_timeout, }; -static int dfd_srv_init(struct bt_mesh_model *mod) +static int dfd_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); srv->mod = mod; @@ -936,9 +936,9 @@ static int dfd_srv_init(struct bt_mesh_model *mod) return 0; } -static void dfd_srv_reset(struct bt_mesh_model *mod) +static void dfd_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfd_srv *srv = mod->user_data; + struct bt_mesh_dfd_srv *srv = *(mod->user_data); dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE); srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; diff --git a/subsys/bluetooth/mesh/dfu_cli.c b/subsys/bluetooth/mesh/dfu_cli.c index 3adb63644d0..70b03f4e814 100644 --- a/subsys/bluetooth/mesh/dfu_cli.c +++ b/subsys/bluetooth/mesh/dfu_cli.c @@ -305,8 +305,9 @@ static void tx_end(int err, void *cb_data) blob_cli_broadcast_tx_complete(&cli->blob); } -static int tx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, - const struct bt_mesh_send_cb *cb, struct bt_mesh_dfu_cli *cli) +static int tx(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, const struct bt_mesh_send_cb *cb, + struct bt_mesh_dfu_cli *cli) { int err; @@ -698,10 +699,10 @@ static void cancelled(struct bt_mesh_blob_cli *b) * Message handlers ******************************************************************************/ -static int handle_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = mod->user_data; + struct bt_mesh_dfu_cli *cli = *(mod->user_data); enum bt_mesh_dfu_status status; enum bt_mesh_dfu_phase phase; struct bt_mesh_dfu_target *target; @@ -824,10 +825,10 @@ static int handle_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_info_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = mod->user_data; + struct bt_mesh_dfu_cli *cli = *(mod->user_data); struct bt_mesh_dfu_target *target; enum bt_mesh_dfu_iter it = BT_MESH_DFU_ITER_CONTINUE; uint8_t img_cnt, idx; @@ -923,10 +924,10 @@ static int handle_info_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_metadata_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_metadata_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = mod->user_data; + struct bt_mesh_dfu_cli *cli = *(mod->user_data); struct bt_mesh_dfu_metadata_status *rsp = cli->req.params; uint8_t hdr, idx; @@ -960,11 +961,11 @@ const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int dfu_cli_init(struct bt_mesh_model *mod) +static int dfu_cli_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_cli *cli = mod->user_data; + struct bt_mesh_dfu_cli *cli = *(mod->user_data); - if (mod->elem_idx != 0) { + if (*(mod->elem_idx) != 0) { LOG_ERR("DFU update client must be instantiated on first elem"); return -EINVAL; } @@ -980,9 +981,9 @@ static int dfu_cli_init(struct bt_mesh_model *mod) return 0; } -static void dfu_cli_reset(struct bt_mesh_model *mod) +static void dfu_cli_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_cli *cli = mod->user_data; + struct bt_mesh_dfu_cli *cli = *(mod->user_data); cli->req.type = REQ_NONE; cli->req.addr = BT_MESH_ADDR_UNASSIGNED; diff --git a/subsys/bluetooth/mesh/dfu_srv.c b/subsys/bluetooth/mesh/dfu_srv.c index 462a777b46c..edd61e6da40 100644 --- a/subsys/bluetooth/mesh/dfu_srv.c +++ b/subsys/bluetooth/mesh/dfu_srv.c @@ -125,10 +125,10 @@ static void verify(struct bt_mesh_dfu_srv *srv) } } -static int handle_info_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_info_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); uint8_t idx, limit; if (srv->update.phase == BT_MESH_DFU_PHASE_APPLYING) { @@ -187,10 +187,10 @@ static int handle_info_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct return 0; } -static int handle_metadata_check(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_metadata_check(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); enum bt_mesh_dfu_status status; enum bt_mesh_dfu_effect effect; uint8_t idx; @@ -239,10 +239,10 @@ static void update_status_rsp(struct bt_mesh_dfu_srv *srv, bt_mesh_model_send(srv->mod, ctx, &buf, send_cb, srv); } -static int handle_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); LOG_DBG(""); @@ -262,10 +262,10 @@ static inline bool is_active_update(struct bt_mesh_dfu_srv *srv, uint8_t idx, srv->update.meta != meta_checksum); } -static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); const struct bt_mesh_blob_io *io; uint16_t timeout_base, meta_checksum; enum bt_mesh_dfu_status status; @@ -371,10 +371,10 @@ static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); if (srv->update.idx == UPDATE_IDX_NONE) { goto rsp; @@ -392,10 +392,10 @@ static int handle_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int handle_apply(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_apply(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); static const struct bt_mesh_send_cb send_cb = { .start = apply_rsp_sending, .end = apply_rsp_sent, @@ -435,9 +435,9 @@ const struct bt_mesh_model_op _bt_mesh_dfu_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int dfu_srv_init(struct bt_mesh_model *mod) +static int dfu_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); srv->mod = mod; srv->update.idx = UPDATE_IDX_NONE; @@ -455,11 +455,11 @@ static int dfu_srv_init(struct bt_mesh_model *mod) return 0; } -static int dfu_srv_settings_set(struct bt_mesh_model *mod, const char *name, +static int dfu_srv_settings_set(const struct bt_mesh_model *mod, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); ssize_t len; if (len_rd < sizeof(srv->update)) { @@ -484,9 +484,9 @@ static int dfu_srv_settings_set(struct bt_mesh_model *mod, const char *name, return 0; } -static void dfu_srv_reset(struct bt_mesh_model *mod) +static void dfu_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_srv *srv = mod->user_data; + struct bt_mesh_dfu_srv *srv = *(mod->user_data); srv->update.phase = BT_MESH_DFU_PHASE_IDLE; erase_state(srv); diff --git a/subsys/bluetooth/mesh/foundation.h b/subsys/bluetooth/mesh/foundation.h index 01cbf93c39e..8a9beef642e 100644 --- a/subsys/bluetooth/mesh/foundation.h +++ b/subsys/bluetooth/mesh/foundation.h @@ -150,7 +150,7 @@ void bt_mesh_model_reset(void); -void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time); +void bt_mesh_attention(const struct bt_mesh_model *model, uint8_t time); #include diff --git a/subsys/bluetooth/mesh/health_cli.c b/subsys/bluetooth/mesh/health_cli.c index 924005f4882..d34d869e243 100644 --- a/subsys/bluetooth/mesh/health_cli.c +++ b/subsys/bluetooth/mesh/health_cli.c @@ -36,11 +36,11 @@ struct health_fault_param { size_t *fault_count; }; -static int health_fault_status(struct bt_mesh_model *model, +static int health_fault_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); struct health_fault_param *param; uint8_t test_id; uint16_t cid; @@ -89,11 +89,11 @@ static int health_fault_status(struct bt_mesh_model *model, return 0; } -static int health_current_status(struct bt_mesh_model *model, +static int health_current_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); uint8_t test_id; uint16_t cid; @@ -117,11 +117,11 @@ struct health_period_param { uint8_t *divisor; }; -static int health_period_status(struct bt_mesh_model *model, +static int health_period_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); struct health_period_param *param; uint8_t divisor; @@ -151,11 +151,11 @@ struct health_attention_param { uint8_t *attention; }; -static int health_attention_status(struct bt_mesh_model *model, +static int health_attention_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); struct health_attention_param *param; uint8_t attention; @@ -402,9 +402,9 @@ void bt_mesh_health_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } -static int health_cli_init(struct bt_mesh_model *model) +static int health_cli_init(const struct bt_mesh_model *model) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); LOG_DBG("primary %u", bt_mesh_model_in_primary(model)); @@ -423,9 +423,9 @@ static int health_cli_init(struct bt_mesh_model *model) return 0; } -static void health_cli_reset(struct bt_mesh_model *model) +static void health_cli_reset(const struct bt_mesh_model *model) { - struct bt_mesh_health_cli *cli = model->user_data; + struct bt_mesh_health_cli *cli = *(model->user_data); net_buf_simple_reset(cli->pub.msg); } diff --git a/subsys/bluetooth/mesh/health_srv.c b/subsys/bluetooth/mesh/health_srv.c index bfab40b6ef9..4ae55266ebf 100644 --- a/subsys/bluetooth/mesh/health_srv.c +++ b/subsys/bluetooth/mesh/health_srv.c @@ -31,11 +31,11 @@ LOG_MODULE_REGISTER(bt_mesh_health_srv); /* Health Server context of the primary element */ struct bt_mesh_health_srv *health_srv; -static void health_get_registered(struct bt_mesh_model *mod, +static void health_get_registered(const struct bt_mesh_model *mod, uint16_t company_id, struct net_buf_simple *msg) { - struct bt_mesh_health_srv *srv = mod->user_data; + struct bt_mesh_health_srv *srv = *(mod->user_data); uint8_t *test_id; LOG_DBG("Company ID 0x%04x", company_id); @@ -64,10 +64,10 @@ static void health_get_registered(struct bt_mesh_model *mod, } } -static size_t health_get_current(struct bt_mesh_model *mod, +static size_t health_get_current(const struct bt_mesh_model *mod, struct net_buf_simple *msg) { - struct bt_mesh_health_srv *srv = mod->user_data; + struct bt_mesh_health_srv *srv = *(mod->user_data); const struct bt_mesh_comp *comp; uint8_t *test_id, *company_ptr; uint16_t company_id; @@ -105,7 +105,7 @@ static size_t health_get_current(struct bt_mesh_model *mod, return fault_count; } -static int health_fault_get(struct bt_mesh_model *model, +static int health_fault_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -125,11 +125,11 @@ static int health_fault_get(struct bt_mesh_model *model, return 0; } -static int health_fault_clear_unrel(struct bt_mesh_model *model, +static int health_fault_clear_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); uint16_t company_id; company_id = net_buf_simple_pull_le16(buf); @@ -143,12 +143,12 @@ static int health_fault_clear_unrel(struct bt_mesh_model *model, return 0; } -static int health_fault_clear(struct bt_mesh_model *model, +static int health_fault_clear(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX); - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); uint16_t company_id; company_id = net_buf_simple_pull_le16(buf); @@ -173,11 +173,11 @@ static int health_fault_clear(struct bt_mesh_model *model, return 0; } -static int health_fault_test_unrel(struct bt_mesh_model *model, +static int health_fault_test_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); uint16_t company_id; uint8_t test_id; @@ -193,12 +193,12 @@ static int health_fault_test_unrel(struct bt_mesh_model *model, return 0; } -static int health_fault_test(struct bt_mesh_model *model, +static int health_fault_test(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX); - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); uint16_t company_id; uint8_t test_id; @@ -228,12 +228,12 @@ static int health_fault_test(struct bt_mesh_model *model, return 0; } -static int send_attention_status(struct bt_mesh_model *model, +static int send_attention_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1); - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); uint8_t time; time = k_ticks_to_ms_floor32( @@ -251,7 +251,7 @@ static int send_attention_status(struct bt_mesh_model *model, return 0; } -static int attention_get(struct bt_mesh_model *model, +static int attention_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -260,7 +260,7 @@ static int attention_get(struct bt_mesh_model *model, return send_attention_status(model, ctx); } -static int attention_set_unrel(struct bt_mesh_model *model, +static int attention_set_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -275,7 +275,7 @@ static int attention_set_unrel(struct bt_mesh_model *model, return 0; } -static int attention_set(struct bt_mesh_model *model, +static int attention_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -291,7 +291,7 @@ static int attention_set(struct bt_mesh_model *model, return send_attention_status(model, ctx); } -static int send_health_period_status(struct bt_mesh_model *model, +static int send_health_period_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ @@ -308,7 +308,7 @@ static int send_health_period_status(struct bt_mesh_model *model, return 0; } -static int health_period_get(struct bt_mesh_model *model, +static int health_period_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -317,7 +317,7 @@ static int health_period_get(struct bt_mesh_model *model, return send_health_period_status(model, ctx); } -static int health_period_set_unrel(struct bt_mesh_model *model, +static int health_period_set_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -336,7 +336,7 @@ static int health_period_set_unrel(struct bt_mesh_model *model, return 0; } -static int health_period_set(struct bt_mesh_model *model, +static int health_period_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -367,7 +367,7 @@ const struct bt_mesh_model_op bt_mesh_health_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int health_pub_update(struct bt_mesh_model *mod) +static int health_pub_update(const struct bt_mesh_model *mod) { struct bt_mesh_model_pub *pub = mod->pub; size_t count; @@ -386,7 +386,7 @@ static int health_pub_update(struct bt_mesh_model *mod) int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem) { - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; mod = bt_mesh_model_find(elem, BT_MESH_MODEL_ID_HEALTH_SRV); if (!mod) { @@ -418,9 +418,9 @@ static void attention_off(struct k_work *work) } } -static int health_srv_init(struct bt_mesh_model *model) +static int health_srv_init(const struct bt_mesh_model *model) { - struct bt_mesh_health_srv *srv = model->user_data; + struct bt_mesh_health_srv *srv = *(model->user_data); if (!srv) { LOG_ERR("No Health Server context provided"); @@ -449,7 +449,7 @@ const struct bt_mesh_model_cb bt_mesh_health_srv_cb = { .init = health_srv_init, }; -void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time) +void bt_mesh_attention(const struct bt_mesh_model *model, uint8_t time) { struct bt_mesh_health_srv *srv; @@ -462,7 +462,7 @@ void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time) model = srv->model; } else { - srv = model->user_data; + srv = *(model->user_data); } if ((time > 0) && srv->cb && srv->cb->attn_on) { diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index 614569d54ae..dc1152f415f 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -33,7 +33,7 @@ LOG_MODULE_REGISTER(bt_mesh_large_comp_data_cli); static struct bt_mesh_large_comp_data_cli *cli; static int32_t msg_timeout; -static int data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int data_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint32_t op, void (*cb)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, struct bt_mesh_large_comp_data_rsp *rsp)) @@ -78,7 +78,7 @@ static int data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return 0; } -static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int large_comp_data_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { return data_status(model, ctx, buf, OP_LARGE_COMP_DATA_STATUS, @@ -86,7 +86,7 @@ static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_ms cli->cb->large_comp_data_status : NULL)); } -static int models_metadata_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int models_metadata_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { return data_status(model, ctx, buf, OP_MODELS_METADATA_STATUS, @@ -100,7 +100,7 @@ const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int large_comp_data_cli_init(struct bt_mesh_model *model) +static int large_comp_data_cli_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Large Comp Data Client only allowed in primary element"); @@ -108,9 +108,9 @@ static int large_comp_data_cli_init(struct bt_mesh_model *model) } model->keys[0] = BT_MESH_KEY_DEV_ANY; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; - cli = model->user_data; + cli = *(model->user_data); cli->model = model; msg_timeout = 5000; diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 4ee591d9efd..5d724b9f083 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -37,10 +37,11 @@ LOG_MODULE_REGISTER(bt_mesh_large_comp_data_srv); /** Mesh Large Composition Data Server Model Context */ static struct bt_mesh_large_comp_data_srv { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; } srv; -static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int handle_large_comp_data_get(const struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(rsp, OP_LARGE_COMP_DATA_STATUS, @@ -101,7 +102,8 @@ static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mes return 0; } -static int handle_models_metadata_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int handle_models_metadata_get(const struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(rsp, OP_MODELS_METADATA_STATUS, @@ -166,7 +168,7 @@ const struct bt_mesh_model_op _bt_mesh_large_comp_data_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int large_comp_data_srv_init(struct bt_mesh_model *model) +static int large_comp_data_srv_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Large Composition Data Server only allowed in primary element"); @@ -175,7 +177,7 @@ static int large_comp_data_srv_init(struct bt_mesh_model *model) /* Large Composition Data Server model shall use the device key */ model->keys[0] = BT_MESH_KEY_DEV; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; srv.model = model; diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index fb70eef669a..3aedf19af48 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -419,7 +419,7 @@ bool bt_mesh_is_provisioned(void) return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID); } -static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_suspend(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update) { @@ -463,7 +463,7 @@ int bt_mesh_suspend(void) return 0; } -static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_resume(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update) { @@ -552,7 +552,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, return 0; } -static void model_start(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_start(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->cb && mod->cb->start) { diff --git a/subsys/bluetooth/mesh/msg.c b/subsys/bluetooth/mesh/msg.c index 458b387539f..6ba497be0c0 100644 --- a/subsys/bluetooth/mesh/msg.c +++ b/subsys/bluetooth/mesh/msg.c @@ -87,7 +87,7 @@ bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, return true; } -int bt_mesh_msg_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +int bt_mesh_msg_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { if (!ctx && !model->pub) { @@ -104,7 +104,7 @@ int bt_mesh_msg_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return bt_mesh_model_publish(model); } -int bt_mesh_msg_ackd_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +int bt_mesh_msg_ackd_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, const struct bt_mesh_msg_rsp_ctx *rsp) { int err; diff --git a/subsys/bluetooth/mesh/msg.h b/subsys/bluetooth/mesh/msg.h index a5d75949130..ff52260b626 100644 --- a/subsys/bluetooth/mesh/msg.h +++ b/subsys/bluetooth/mesh/msg.h @@ -18,7 +18,7 @@ * @retval -EADDRNOTAVAIL A message context was not provided and publishing is not configured. * @retval -EAGAIN The device has not been provisioned. */ -int bt_mesh_msg_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +int bt_mesh_msg_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); /** @@ -51,5 +51,5 @@ struct bt_mesh_msg_rsp_ctx { * @retval -EAGAIN The device has not been provisioned. * @retval -ETIMEDOUT The request timed out without a response. */ -int bt_mesh_msg_ackd_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +int bt_mesh_msg_ackd_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, const struct bt_mesh_msg_rsp_ctx *rsp); diff --git a/subsys/bluetooth/mesh/od_priv_proxy_cli.c b/subsys/bluetooth/mesh/od_priv_proxy_cli.c index 67f5ac961ad..f2844d2ecc6 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_cli.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_cli.c @@ -20,7 +20,7 @@ static struct bt_mesh_od_priv_proxy_cli *cli; static int32_t msg_timeout; -static int handle_proxy_status(struct bt_mesh_model *mod, +static int handle_proxy_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -93,17 +93,17 @@ void bt_mesh_od_priv_proxy_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } -static int on_demand_proxy_cli_init(struct bt_mesh_model *mod) +static int on_demand_proxy_cli_init(const struct bt_mesh_model *mod) { if (!bt_mesh_model_in_primary(mod)) { LOG_ERR("On-Demand Private Proxy client not in primary element"); return -EINVAL; } - cli = mod->user_data; + cli = *(mod->user_data); cli->model = mod; mod->keys[0] = BT_MESH_KEY_DEV_ANY; - mod->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; msg_timeout = CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/od_priv_proxy_srv.c b/subsys/bluetooth/mesh/od_priv_proxy_srv.c index b18a8ec7530..e671a80e9de 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_srv.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_srv.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(bt_mesh_od_priv_proxy_srv); -static struct bt_mesh_model *od_priv_proxy_srv; +static const struct bt_mesh_model *od_priv_proxy_srv; static uint8_t on_demand_state; static int od_priv_proxy_store(bool delete) @@ -31,7 +31,7 @@ static int od_priv_proxy_store(bool delete) return bt_mesh_model_data_store(od_priv_proxy_srv, false, "pp", data, len); } -static int proxy_status_rsp(struct bt_mesh_model *mod, +static int proxy_status_rsp(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(buf, OP_OD_PRIV_PROXY_STATUS, 1); @@ -44,7 +44,7 @@ static int proxy_status_rsp(struct bt_mesh_model *mod, return 0; } -static int handle_proxy_get(struct bt_mesh_model *mod, +static int handle_proxy_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -55,7 +55,7 @@ static int handle_proxy_get(struct bt_mesh_model *mod, return 0; } -static int handle_proxy_set(struct bt_mesh_model *mod, +static int handle_proxy_set(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -79,13 +79,13 @@ const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_srv_op[] = { BT_MESH_MODEL_OP_END }; -static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) +static int od_priv_proxy_srv_init(const struct bt_mesh_model *mod) { od_priv_proxy_srv = mod; - struct bt_mesh_model *priv_beacon_srv = bt_mesh_model_find( + const struct bt_mesh_model *priv_beacon_srv = bt_mesh_model_find( bt_mesh_model_elem(mod), BT_MESH_MODEL_ID_PRIV_BEACON_SRV); - struct bt_mesh_model *sol_pdu_rpl_srv = bt_mesh_model_find( + const struct bt_mesh_model *sol_pdu_rpl_srv = bt_mesh_model_find( bt_mesh_model_elem(mod), BT_MESH_MODEL_ID_SOL_PDU_RPL_SRV); if (priv_beacon_srv == NULL) { @@ -98,7 +98,7 @@ static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) } mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - mod->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; if (IS_ENABLED(CONFIG_BT_MESH_MODEL_EXTENSIONS)) { bt_mesh_model_extend(mod, priv_beacon_srv); @@ -108,14 +108,14 @@ static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) return 0; } -static void od_priv_proxy_srv_reset(struct bt_mesh_model *model) +static void od_priv_proxy_srv_reset(const struct bt_mesh_model *model) { on_demand_state = 0; od_priv_proxy_store(true); } #ifdef CONFIG_BT_SETTINGS -static int od_priv_proxy_srv_settings_set(struct bt_mesh_model *model, const char *name, +static int od_priv_proxy_srv_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_data) { int err; @@ -135,7 +135,7 @@ static int od_priv_proxy_srv_settings_set(struct bt_mesh_model *model, const cha return 0; } -static void od_priv_proxy_srv_pending_store(struct bt_mesh_model *model) +static void od_priv_proxy_srv_pending_store(const struct bt_mesh_model *model) { on_demand_state = bt_mesh_od_priv_proxy_get(); od_priv_proxy_store(false); diff --git a/subsys/bluetooth/mesh/op_agg.h b/subsys/bluetooth/mesh/op_agg.h index 8bb3d6c97ba..a56a30ccd31 100644 --- a/subsys/bluetooth/mesh/op_agg.h +++ b/subsys/bluetooth/mesh/op_agg.h @@ -19,8 +19,8 @@ struct op_agg_ctx { int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf); int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf); -int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg); +int bt_mesh_op_agg_cli_send(const struct bt_mesh_model *model, struct net_buf_simple *msg); int bt_mesh_op_agg_cli_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); -int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg); +int bt_mesh_op_agg_srv_send(const struct bt_mesh_model *model, struct net_buf_simple *msg); int bt_mesh_op_agg_srv_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); bool bt_mesh_op_agg_is_op_agg_msg(struct net_buf_simple *buf); diff --git a/subsys/bluetooth/mesh/op_agg_cli.c b/subsys/bluetooth/mesh/op_agg_cli.c index 612843a98cc..b74b8245cfd 100644 --- a/subsys/bluetooth/mesh/op_agg_cli.c +++ b/subsys/bluetooth/mesh/op_agg_cli.c @@ -24,7 +24,7 @@ NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); /** Mesh Opcodes Aggregator Client Model Context */ static struct bt_mesh_op_agg_cli { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Acknowledge context. */ struct bt_mesh_msg_ack_ctx ack_ctx; /** List of source element addresses. @@ -39,7 +39,7 @@ static struct bt_mesh_op_agg_cli { static int32_t msg_timeout; -static int handle_status(struct bt_mesh_model *model, +static int handle_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -102,7 +102,7 @@ const struct bt_mesh_model_op _bt_mesh_op_agg_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int op_agg_cli_init(struct bt_mesh_model *model) +static int op_agg_cli_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Opcodes Aggregator Client only allowed in primary element"); @@ -203,7 +203,7 @@ void bt_mesh_op_agg_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } -int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg) +int bt_mesh_op_agg_cli_send(const struct bt_mesh_model *model, struct net_buf_simple *msg) { uint16_t src = bt_mesh_model_elem(model)->addr; diff --git a/subsys/bluetooth/mesh/op_agg_srv.c b/subsys/bluetooth/mesh/op_agg_srv.c index a6e5f666411..9bbe01384e2 100644 --- a/subsys/bluetooth/mesh/op_agg_srv.c +++ b/subsys/bluetooth/mesh/op_agg_srv.c @@ -22,7 +22,7 @@ NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); /** Mesh Opcodes Aggragator Server Model Context */ static struct bt_mesh_op_agg_srv { /** Composition data model entry pointer. */ - struct bt_mesh_model *model; + const struct bt_mesh_model *model; /** Response error code. */ int rsp_err; /** Indicates that the received aggregated message @@ -33,7 +33,7 @@ static struct bt_mesh_op_agg_srv { struct op_agg_ctx ctx; } srv = {.ctx.sdu = &sdu}; -static int handle_sequence(struct bt_mesh_model *model, +static int handle_sequence(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -114,7 +114,7 @@ const struct bt_mesh_model_op _bt_mesh_op_agg_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int op_agg_srv_init(struct bt_mesh_model *model) +static int op_agg_srv_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Opcodes Aggregator Server only allowed in primary element"); @@ -131,7 +131,7 @@ static int op_agg_srv_init(struct bt_mesh_model *model) return 0; } -int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg) +int bt_mesh_op_agg_srv_send(const struct bt_mesh_model *model, struct net_buf_simple *msg) { int err; diff --git a/subsys/bluetooth/mesh/priv_beacon_cli.c b/subsys/bluetooth/mesh/priv_beacon_cli.c index d14454c7cf5..fd48ef0583b 100644 --- a/subsys/bluetooth/mesh/priv_beacon_cli.c +++ b/subsys/bluetooth/mesh/priv_beacon_cli.c @@ -18,7 +18,7 @@ static struct bt_mesh_priv_beacon_cli *cli; static int32_t msg_timeout; -static int handle_beacon_status(struct bt_mesh_model *model, +static int handle_beacon_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -56,7 +56,7 @@ static int handle_beacon_status(struct bt_mesh_model *model, return 0; } -static int handle_gatt_proxy_status(struct bt_mesh_model *model, +static int handle_gatt_proxy_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -86,7 +86,7 @@ static int handle_gatt_proxy_status(struct bt_mesh_model *model, return 0; } -static int handle_node_id_status(struct bt_mesh_model *model, +static int handle_node_id_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -134,18 +134,18 @@ const struct bt_mesh_model_op bt_mesh_priv_beacon_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int priv_beacon_cli_init(struct bt_mesh_model *model) +static int priv_beacon_cli_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Private Beacon Client only allowed in primary element"); return -EINVAL; } - cli = model->user_data; + cli = *(model->user_data); cli->model = model; msg_timeout = 2 * MSEC_PER_SEC; model->keys[0] = BT_MESH_KEY_DEV_ANY; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index 377703e8352..5b5e62f1736 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -17,7 +17,7 @@ #include LOG_MODULE_REGISTER(bt_mesh_priv_beacon_srv); -static struct bt_mesh_model *priv_beacon_srv; +static const struct bt_mesh_model *priv_beacon_srv; /* Private Beacon configuration server model states */ struct { @@ -38,7 +38,7 @@ static int priv_beacon_store(bool delete) return bt_mesh_model_data_store(priv_beacon_srv, false, "pb", data, len); } -static int beacon_status_rsp(struct bt_mesh_model *mod, +static int beacon_status_rsp(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_BEACON_STATUS, 2); @@ -52,7 +52,7 @@ static int beacon_status_rsp(struct bt_mesh_model *mod, return 0; } -static int handle_beacon_get(struct bt_mesh_model *mod, +static int handle_beacon_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -63,7 +63,7 @@ static int handle_beacon_get(struct bt_mesh_model *mod, return 0; } -static int handle_beacon_set(struct bt_mesh_model *mod, +static int handle_beacon_set(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -90,7 +90,7 @@ static int handle_beacon_set(struct bt_mesh_model *mod, return 0; } -static void gatt_proxy_status_rsp(struct bt_mesh_model *mod, +static void gatt_proxy_status_rsp(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_GATT_PROXY_STATUS, 1); @@ -101,7 +101,7 @@ static void gatt_proxy_status_rsp(struct bt_mesh_model *mod, bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); } -static int handle_gatt_proxy_get(struct bt_mesh_model *mod, +static int handle_gatt_proxy_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -112,7 +112,7 @@ static int handle_gatt_proxy_get(struct bt_mesh_model *mod, return 0; } -static int handle_gatt_proxy_set(struct bt_mesh_model *mod, +static int handle_gatt_proxy_set(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -134,7 +134,7 @@ static int handle_gatt_proxy_set(struct bt_mesh_model *mod, return 0; } -static void node_id_status_rsp(struct bt_mesh_model *mod, +static void node_id_status_rsp(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, uint8_t status, uint16_t net_idx, uint8_t node_id) { @@ -148,7 +148,7 @@ static void node_id_status_rsp(struct bt_mesh_model *mod, bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); } -static int handle_node_id_get(struct bt_mesh_model *mod, +static int handle_node_id_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -163,7 +163,7 @@ static int handle_node_id_get(struct bt_mesh_model *mod, return 0; } -static int handle_node_id_set(struct bt_mesh_model *mod, +static int handle_node_id_set(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -194,7 +194,7 @@ const struct bt_mesh_model_op bt_mesh_priv_beacon_srv_op[] = { BT_MESH_MODEL_OP_END }; -static int priv_beacon_srv_init(struct bt_mesh_model *mod) +static int priv_beacon_srv_init(const struct bt_mesh_model *mod) { if (!bt_mesh_model_in_primary(mod)) { LOG_ERR("Priv beacon server not in primary element"); @@ -207,14 +207,14 @@ static int priv_beacon_srv_init(struct bt_mesh_model *mod) return 0; } -static void priv_beacon_srv_reset(struct bt_mesh_model *model) +static void priv_beacon_srv_reset(const struct bt_mesh_model *model) { (void)memset(&priv_beacon_state, 0, sizeof(priv_beacon_state)); priv_beacon_store(true); } #ifdef CONFIG_BT_SETTINGS -static int priv_beacon_srv_settings_set(struct bt_mesh_model *model, const char *name, +static int priv_beacon_srv_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_data) { int err; @@ -236,7 +236,7 @@ static int priv_beacon_srv_settings_set(struct bt_mesh_model *model, const char return 0; } -static void priv_beacon_srv_pending_store(struct bt_mesh_model *model) +static void priv_beacon_srv_pending_store(const struct bt_mesh_model *model) { priv_beacon_state.state = bt_mesh_priv_beacon_get(); priv_beacon_state.interval = bt_mesh_priv_beacon_update_interval_get(); diff --git a/subsys/bluetooth/mesh/rpr_cli.c b/subsys/bluetooth/mesh/rpr_cli.c index 3ebd3afcd6a..7a1dd493b87 100644 --- a/subsys/bluetooth/mesh/rpr_cli.c +++ b/subsys/bluetooth/mesh/rpr_cli.c @@ -90,11 +90,11 @@ static void tx_complete(struct bt_mesh_rpr_cli *cli, int err, void *cb_data) } } -static int handle_extended_scan_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_extended_scan_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_rpr_node srv = RPR_NODE(ctx); - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_unprov dev = { 0 }; enum bt_mesh_rpr_status status; bool found_dev = false; @@ -123,11 +123,11 @@ static int handle_extended_scan_report(struct bt_mesh_model *mod, struct bt_mesh return 0; } -static int handle_link_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_link_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_rpr_node srv = RPR_NODE(ctx); - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_link link; uint8_t reason = PROV_BEARER_LINK_STATUS_SUCCESS; @@ -161,10 +161,10 @@ static int handle_link_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_link_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_link_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_link *rsp; struct bt_mesh_rpr_link link; @@ -195,10 +195,10 @@ static int handle_link_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_pdu_outbound_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_pdu_outbound_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_node srv = RPR_NODE(ctx); void *cb_data; uint8_t num; @@ -226,10 +226,10 @@ static int handle_pdu_outbound_report(struct bt_mesh_model *mod, struct bt_mesh_ return 0; } -static int handle_pdu_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_pdu_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct pb_remote_ctx cb_ctx = { cli, @@ -257,10 +257,10 @@ static int handle_pdu_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } -static int handle_scan_caps_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_caps_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_caps *caps; @@ -281,10 +281,10 @@ static int handle_scan_caps_status(struct bt_mesh_model *mod, struct bt_mesh_msg return 0; } -static int handle_scan_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_unprov dev = { 0 }; @@ -313,10 +313,10 @@ static int handle_scan_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } -static int handle_scan_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); struct bt_mesh_rpr_scan_status *status; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); @@ -361,15 +361,15 @@ static void link_timeout(struct k_work *work) } } -static int rpr_cli_init(struct bt_mesh_model *mod) +static int rpr_cli_init(const struct bt_mesh_model *mod) { - if (mod->elem_idx) { + if (*(mod->elem_idx)) { LOG_ERR("Remote provisioning client must be initialized " "on first element"); return -EINVAL; } - struct bt_mesh_rpr_cli *cli = mod->user_data; + struct bt_mesh_rpr_cli *cli = *(mod->user_data); cli->mod = mod; cli->link.time = LINK_TIMEOUT_SECONDS_DEFAULT; @@ -378,7 +378,7 @@ static int rpr_cli_init(struct bt_mesh_model *mod) bt_mesh_msg_ack_ctx_init(&cli->prov_ack_ctx); k_work_init_delayable(&cli->link.timeout, link_timeout); mod->keys[0] = BT_MESH_KEY_DEV_ANY; - mod->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index fb2b57fad2e..e008aa0a8b1 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -47,7 +47,7 @@ enum { /** Remote provisioning server instance. */ static struct { - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; ATOMIC_DEFINE(flags, RPR_SRV_NUM_FLAGS); @@ -536,7 +536,7 @@ static const struct prov_bearer_cb prov_bearer_cb = { * Message handlers ******************************************************************************/ -static int handle_scan_caps_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_caps_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_SCAN_CAPS_STATUS, 2); @@ -549,7 +549,7 @@ static int handle_scan_caps_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ct return 0; } -static int handle_scan_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { scan_status_send(ctx, BT_MESH_RPR_SUCCESS); @@ -557,7 +557,7 @@ static int handle_scan_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct return 0; } -static int handle_scan_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_rpr_node cli = RPR_NODE(ctx); @@ -621,7 +621,7 @@ static int handle_scan_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } -static int handle_extended_scan_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_extended_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_EXTENDED_SCAN_REPORT, @@ -784,7 +784,7 @@ static int handle_extended_scan_start(struct bt_mesh_model *mod, struct bt_mesh_ return 0; } -static int handle_scan_stop(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_scan_stop(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { if (atomic_test_bit(srv.flags, SCANNING)) { @@ -797,7 +797,7 @@ static int handle_scan_stop(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *c return 0; } -static int handle_link_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_link_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_DBG(""); @@ -807,7 +807,7 @@ static int handle_link_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct return 0; } -static int handle_link_open(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_link_open(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { bool is_refresh_procedure = (buf->len == 1); @@ -938,7 +938,7 @@ static int handle_link_open(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *c return 0; } -static int handle_link_close(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_link_close(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_rpr_node cli = RPR_NODE(ctx); @@ -975,7 +975,7 @@ static int handle_link_close(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } -static int handle_pdu_send(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int handle_pdu_send(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_rpr_node cli = RPR_NODE(ctx); @@ -1303,9 +1303,9 @@ static struct bt_le_scan_cb scan_cb = { .recv = scan_packet_recv, }; -static int rpr_srv_init(struct bt_mesh_model *mod) +static int rpr_srv_init(const struct bt_mesh_model *mod) { - if (mod->elem_idx || srv.mod) { + if (*(mod->elem_idx) || srv.mod) { LOG_ERR("Remote provisioning server must be initialized " "on first element"); return -EINVAL; @@ -1320,12 +1320,12 @@ static int rpr_srv_init(struct bt_mesh_model *mod) k_work_init(&srv.link.report, link_report_send_and_clear); bt_le_scan_cb_register(&scan_cb); mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - mod->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } -static void rpr_srv_reset(struct bt_mesh_model *mod) +static void rpr_srv_reset(const struct bt_mesh_model *mod) { cli_link_clear(); cli_scan_clear(); diff --git a/subsys/bluetooth/mesh/sar_cfg_cli.c b/subsys/bluetooth/mesh/sar_cfg_cli.c index b5a33b975e5..aaf07451e1d 100644 --- a/subsys/bluetooth/mesh/sar_cfg_cli.c +++ b/subsys/bluetooth/mesh/sar_cfg_cli.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(bt_mesh_sar_cfg_cli); static struct bt_mesh_sar_cfg_cli *cli; -static int transmitter_status(struct bt_mesh_model *model, +static int transmitter_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -45,7 +45,7 @@ static int transmitter_status(struct bt_mesh_model *model, return 0; } -static int receiver_status(struct bt_mesh_model *model, +static int receiver_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -87,35 +87,35 @@ void bt_mesh_sar_cfg_cli_timeout_set(int32_t timeout) cli->timeout = timeout; } -static int bt_mesh_sar_cfg_cli_init(struct bt_mesh_model *model) +static int bt_mesh_sar_cfg_cli_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("SAR Configuration Client only allowed in primary element"); return -EINVAL; } - if (!model->user_data) { + if (!*(model->user_data)) { LOG_ERR("No SAR Configuration Client context provided"); return -EINVAL; } - cli = model->user_data; + cli = *(model->user_data); cli->model = model; cli->timeout = 2 * MSEC_PER_SEC; model->keys[0] = BT_MESH_KEY_DEV_ANY; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); return 0; } -static void bt_mesh_sar_cfg_cli_reset(struct bt_mesh_model *model) +static void bt_mesh_sar_cfg_cli_reset(const struct bt_mesh_model *model) { struct bt_mesh_sar_cfg_cli *model_cli; - model_cli = model->user_data; + model_cli = *(model->user_data); bt_mesh_msg_ack_ctx_clear(&model_cli->ack_ctx); } diff --git a/subsys/bluetooth/mesh/sar_cfg_srv.c b/subsys/bluetooth/mesh/sar_cfg_srv.c index e05489ee0cf..59ec36907c5 100644 --- a/subsys/bluetooth/mesh/sar_cfg_srv.c +++ b/subsys/bluetooth/mesh/sar_cfg_srv.c @@ -27,7 +27,7 @@ #include LOG_MODULE_REGISTER(bt_mesh_sar_cfg_srv); -static int sar_rx_store(struct bt_mesh_model *model, bool delete) +static int sar_rx_store(const struct bt_mesh_model *model, bool delete) { const void *data = delete ? NULL : &bt_mesh.sar_rx; size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_rx); @@ -35,7 +35,7 @@ static int sar_rx_store(struct bt_mesh_model *model, bool delete) return bt_mesh_model_data_store(model, false, "sar_rx", data, len); } -static int sar_tx_store(struct bt_mesh_model *model, bool delete) +static int sar_tx_store(const struct bt_mesh_model *model, bool delete) { const void *data = delete ? NULL : &bt_mesh.sar_tx; size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_tx); @@ -43,7 +43,7 @@ static int sar_tx_store(struct bt_mesh_model *model, bool delete) return bt_mesh_model_data_store(model, false, "sar_tx", data, len); } -static void transmitter_status(struct bt_mesh_model *model, +static void transmitter_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_STATUS, BT_MESH_SAR_TX_LEN); @@ -63,7 +63,7 @@ static void transmitter_status(struct bt_mesh_model *model, } } -static void receiver_status(struct bt_mesh_model *model, +static void receiver_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_STATUS, BT_MESH_SAR_RX_LEN); @@ -81,7 +81,7 @@ static void receiver_status(struct bt_mesh_model *model, } } -static int transmitter_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int transmitter_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_DBG("src 0x%04x", ctx->addr); @@ -91,7 +91,7 @@ static int transmitter_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx * return 0; } -static int transmitter_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int transmitter_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_sar_tx *tx = &bt_mesh.sar_tx; @@ -108,7 +108,7 @@ static int transmitter_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx * return 0; } -static int receiver_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int receiver_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_DBG("src 0x%04x", ctx->addr); @@ -118,7 +118,7 @@ static int receiver_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx return 0; } -static int receiver_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int receiver_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_sar_rx *rx = &bt_mesh.sar_rx; @@ -143,7 +143,7 @@ const struct bt_mesh_model_op bt_mesh_sar_cfg_srv_op[] = { BT_MESH_MODEL_OP_END, }; -static int sar_cfg_srv_init(struct bt_mesh_model *model) +static int sar_cfg_srv_init(const struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { LOG_ERR("Configuration Server only allowed in primary element"); @@ -155,12 +155,12 @@ static int sar_cfg_srv_init(struct bt_mesh_model *model) * device-key is allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_LOCAL; - model->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } -static void sar_cfg_srv_reset(struct bt_mesh_model *model) +static void sar_cfg_srv_reset(const struct bt_mesh_model *model) { struct bt_mesh_sar_tx sar_tx = BT_MESH_SAR_TX_INIT; struct bt_mesh_sar_rx sar_rx = BT_MESH_SAR_RX_INIT; @@ -175,8 +175,9 @@ static void sar_cfg_srv_reset(struct bt_mesh_model *model) } #ifdef CONFIG_BT_SETTINGS -static int sar_cfg_srv_settings_set(struct bt_mesh_model *model, const char *name, size_t len_rd, - settings_read_cb read_cb, void *cb_data) +static int sar_cfg_srv_settings_set(const struct bt_mesh_model *model, const char *name, + size_t len_rd, settings_read_cb read_cb, + void *cb_data) { if (!strncmp(name, "sar_rx", 5)) { return bt_mesh_settings_set(read_cb, cb_data, &bt_mesh.sar_rx, diff --git a/subsys/bluetooth/mesh/shell/blob.c b/subsys/bluetooth/mesh/shell/blob.c index a3ecdee241e..ed0f4fbd458 100644 --- a/subsys/bluetooth/mesh/shell/blob.c +++ b/subsys/bluetooth/mesh/shell/blob.c @@ -271,7 +271,7 @@ static int cmd_flash_stream_unset(const struct shell *sh, size_t argc, char *arg #if defined(CONFIG_BT_MESH_SHELL_BLOB_CLI) -static struct bt_mesh_model *mod_cli; +static const struct bt_mesh_model *mod_cli; static void blob_cli_inputs_prepare(uint16_t group) { @@ -351,7 +351,7 @@ static int cmd_tx(const struct shell *sh, size_t argc, char *argv[]) "pull", blob_cli_xfer.xfer.size, group); - err = bt_mesh_blob_cli_send((struct bt_mesh_blob_cli *)mod_cli->user_data, + err = bt_mesh_blob_cli_send((struct bt_mesh_blob_cli *)*(mod_cli->user_data), &blob_cli_xfer.inputs, &blob_cli_xfer.xfer, bt_mesh_shell_blob_io); if (err) { @@ -421,7 +421,7 @@ static int cmd_caps(const struct shell *sh, size_t argc, char *argv[]) blob_cli_inputs_prepare(group); - err = bt_mesh_blob_cli_caps_get((struct bt_mesh_blob_cli *)mod_cli->user_data, + err = bt_mesh_blob_cli_caps_get((struct bt_mesh_blob_cli *)*(mod_cli->user_data), &blob_cli_xfer.inputs); if (err) { shell_print(sh, "Boundary check start failed (err: %d)", err); @@ -438,7 +438,7 @@ static int cmd_tx_cancel(const struct shell *sh, size_t argc, } shell_print(sh, "Cancelling transfer"); - bt_mesh_blob_cli_cancel((struct bt_mesh_blob_cli *)mod_cli->user_data); + bt_mesh_blob_cli_cancel((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); return 0; } @@ -465,7 +465,7 @@ static int cmd_tx_get(const struct shell *sh, size_t argc, char *argv[]) blob_cli_inputs_prepare(group); - err = bt_mesh_blob_cli_xfer_progress_get((struct bt_mesh_blob_cli *)mod_cli->user_data, + err = bt_mesh_blob_cli_xfer_progress_get((struct bt_mesh_blob_cli *)*(mod_cli->user_data), &blob_cli_xfer.inputs); if (err) { shell_print(sh, "ERR %d", err); @@ -482,7 +482,7 @@ static int cmd_tx_suspend(const struct shell *sh, size_t argc, } shell_print(sh, "Suspending transfer"); - bt_mesh_blob_cli_suspend((struct bt_mesh_blob_cli *)mod_cli->user_data); + bt_mesh_blob_cli_suspend((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); return 0; } @@ -494,7 +494,7 @@ static int cmd_tx_resume(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Resuming transfer"); - bt_mesh_blob_cli_resume((struct bt_mesh_blob_cli *)mod_cli->user_data); + bt_mesh_blob_cli_resume((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); return 0; } @@ -503,7 +503,7 @@ static int cmd_tx_resume(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_BT_MESH_SHELL_BLOB_SRV) -static struct bt_mesh_model *mod_srv; +static const struct bt_mesh_model *mod_srv; static int cmd_rx(const struct shell *sh, size_t argc, char *argv[]) { @@ -530,7 +530,7 @@ static int cmd_rx(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Receive BLOB 0x%x", id); - err = bt_mesh_blob_srv_recv((struct bt_mesh_blob_srv *)mod_srv->user_data, + err = bt_mesh_blob_srv_recv((struct bt_mesh_blob_srv *)*(mod_srv->user_data), id, bt_mesh_shell_blob_io, BT_MESH_TTL_MAX, timeout_base); if (err) { shell_print(sh, "BLOB RX setup failed (%d)", err); @@ -548,7 +548,7 @@ static int cmd_rx_cancel(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Cancelling BLOB rx"); - err = bt_mesh_blob_srv_cancel((struct bt_mesh_blob_srv *)mod_srv->user_data); + err = bt_mesh_blob_srv_cancel((struct bt_mesh_blob_srv *)*(mod_srv->user_data)); if (err) { shell_print(sh, "BLOB cancel failed (%d)", err); } diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index 0415929dfec..464a5340342 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -14,7 +14,7 @@ #include "../dfd_srv_internal.h" #include "../access.h" -static struct bt_mesh_model *mod; +static const struct bt_mesh_model *mod; static void print_receivers_status(const struct shell *sh, struct bt_mesh_dfd_srv *srv, enum bt_mesh_dfd_status status) @@ -70,7 +70,7 @@ static int cmd_dfd_receivers_add(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); if (bt_mesh_dfu_cli_is_busy(&dfd_srv->dfu)) { print_receivers_status(sh, dfd_srv, @@ -122,7 +122,7 @@ static int cmd_dfd_receivers_delete_all(const struct shell *sh, size_t argc, cha return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_receivers_delete_all( dfd_srv); @@ -142,7 +142,7 @@ static int cmd_dfd_receivers_get(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); int err = 0; uint16_t first = shell_strtoul(argv[1], 0, &err); @@ -197,7 +197,7 @@ static int cmd_dfd_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); print_dfd_status(sh, dfd_srv, BT_MESH_DFD_SUCCESS); @@ -210,7 +210,7 @@ static int cmd_dfd_start(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); struct bt_mesh_dfd_start_params params; int err = 0; @@ -267,7 +267,7 @@ static int cmd_dfd_suspend(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_suspend(dfd_srv); @@ -285,7 +285,7 @@ static int cmd_dfd_cancel(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_cancel(dfd_srv, NULL); @@ -303,7 +303,7 @@ static int cmd_dfd_apply(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_apply(dfd_srv); @@ -364,7 +364,7 @@ static int cmd_dfd_fw_delete(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); uint8_t fwid_buf[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; size_t hexlen = strlen(argv[1]); @@ -394,7 +394,7 @@ static int cmd_dfd_fw_delete_all(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = mod->user_data; + struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_fw_delete_all(dfd_srv); diff --git a/subsys/bluetooth/mesh/shell/dfu.c b/subsys/bluetooth/mesh/shell/dfu.c index 8d7fc96e014..22c60dc17c8 100644 --- a/subsys/bluetooth/mesh/shell/dfu.c +++ b/subsys/bluetooth/mesh/shell/dfu.c @@ -505,7 +505,7 @@ static int cmd_dfu_slot_get(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_BT_MESH_SHELL_DFU_CLI) -static struct bt_mesh_model *mod_cli; +static const struct bt_mesh_model *mod_cli; static struct { struct bt_mesh_dfu_target targets[32]; @@ -587,7 +587,7 @@ static int cmd_dfu_target_state(const struct shell *sh, size_t argc, char *argv[ return -ENODEV; } - err = bt_mesh_dfu_cli_status_get((struct bt_mesh_dfu_cli *)mod_cli->user_data, + err = bt_mesh_dfu_cli_status_get((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), &ctx, &rsp); if (err) { shell_print(sh, "Failed getting target status (err: %d)", @@ -654,7 +654,7 @@ static int cmd_dfu_target_imgs(const struct shell *sh, size_t argc, char *argv[] shell_print(sh, "Requesting DFU images in 0x%04x", bt_mesh_shell_target_ctx.dst); - err = bt_mesh_dfu_cli_imgs_get((struct bt_mesh_dfu_cli *)mod_cli->user_data, + err = bt_mesh_dfu_cli_imgs_get((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), &ctx, dfu_img_cb, NULL, img_cnt); if (err) { shell_print(sh, "Request failed (err: %d)", err); @@ -694,7 +694,7 @@ static int cmd_dfu_target_check(const struct shell *sh, size_t argc, char *argv[ return 0; } - err = bt_mesh_dfu_cli_metadata_check((struct bt_mesh_dfu_cli *)mod_cli->user_data, + err = bt_mesh_dfu_cli_metadata_check((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), &ctx, img_idx, slot, &rsp); if (err) { shell_print(sh, "Metadata check failed. err: %d", err); @@ -765,7 +765,7 @@ static int cmd_dfu_send(const struct shell *sh, size_t argc, char *argv[]) dfu_tx.inputs.app_idx = bt_mesh_shell_target_ctx.app_idx; dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT; - err = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)mod_cli->user_data, + err = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), &dfu_tx.inputs, bt_mesh_shell_blob_io, &xfer); if (err) { shell_print(sh, "Failed (err: %d)", err); @@ -800,7 +800,7 @@ static int cmd_dfu_tx_cancel(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Cancelling DFU"); } - err = bt_mesh_dfu_cli_cancel((struct bt_mesh_dfu_cli *)mod_cli->user_data, + err = bt_mesh_dfu_cli_cancel((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), (argc == 2) ? &ctx : NULL); if (err) { shell_print(sh, "Failed (err: %d)", err); @@ -819,7 +819,7 @@ static int cmd_dfu_apply(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Applying DFU"); - err = bt_mesh_dfu_cli_apply((struct bt_mesh_dfu_cli *)mod_cli->user_data); + err = bt_mesh_dfu_cli_apply((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -837,7 +837,7 @@ static int cmd_dfu_confirm(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Confirming DFU"); - err = bt_mesh_dfu_cli_confirm((struct bt_mesh_dfu_cli *)mod_cli->user_data); + err = bt_mesh_dfu_cli_confirm((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -855,7 +855,7 @@ static int cmd_dfu_suspend(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Suspending DFU"); - err = bt_mesh_dfu_cli_suspend((struct bt_mesh_dfu_cli *)mod_cli->user_data); + err = bt_mesh_dfu_cli_suspend((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -873,7 +873,7 @@ static int cmd_dfu_resume(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Resuming DFU"); - err = bt_mesh_dfu_cli_resume((struct bt_mesh_dfu_cli *)mod_cli->user_data); + err = bt_mesh_dfu_cli_resume((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -888,7 +888,7 @@ static int cmd_dfu_tx_progress(const struct shell *sh, size_t argc, char *argv[] } shell_print(sh, "DFU progress: %u %%", - bt_mesh_dfu_cli_progress((struct bt_mesh_dfu_cli *)mod_cli->user_data)); + bt_mesh_dfu_cli_progress((struct bt_mesh_dfu_cli *)*(mod_cli->user_data))); return 0; } @@ -896,7 +896,7 @@ static int cmd_dfu_tx_progress(const struct shell *sh, size_t argc, char *argv[] #if defined(CONFIG_BT_MESH_SHELL_DFU_SRV) -static struct bt_mesh_model *mod_srv; +static const struct bt_mesh_model *mod_srv; static int cmd_dfu_applied(const struct shell *sh, size_t argc, char *argv[]) { @@ -904,7 +904,7 @@ static int cmd_dfu_applied(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)mod_srv->user_data); + bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)*(mod_srv->user_data)); return 0; } @@ -914,7 +914,7 @@ static int cmd_dfu_rx_cancel(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)mod_srv->user_data); + bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)*(mod_srv->user_data)); return 0; } @@ -925,7 +925,7 @@ static int cmd_dfu_rx_progress(const struct shell *sh, size_t argc, char *argv[] } shell_print(sh, "DFU progress: %u %%", - bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)mod_srv->user_data)); + bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)*(mod_srv->user_data))); return 0; } diff --git a/subsys/bluetooth/mesh/shell/health.c b/subsys/bluetooth/mesh/shell/health.c index efc7eb84e62..a0ca150ae15 100644 --- a/subsys/bluetooth/mesh/shell/health.c +++ b/subsys/bluetooth/mesh/shell/health.c @@ -13,7 +13,7 @@ #include "utils.h" #include -static struct bt_mesh_model *mod; +static const struct bt_mesh_model *mod; static void show_faults(const struct shell *sh, uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) @@ -40,7 +40,7 @@ static int cmd_fault_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t faults[32]; @@ -74,7 +74,7 @@ static int fault_clear(const struct shell *sh, size_t argc, char *argv[], bool a return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t test_id; @@ -126,7 +126,7 @@ static int fault_test(const struct shell *sh, size_t argc, char *argv[], bool ac return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t test_id; @@ -179,7 +179,7 @@ static int cmd_period_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t divisor; @@ -201,7 +201,7 @@ static int period_set(const struct shell *sh, size_t argc, char *argv[], bool ac return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t divisor; @@ -251,7 +251,7 @@ static int cmd_attention_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t attention; @@ -273,7 +273,7 @@ static int attention_set(const struct shell *sh, size_t argc, char *argv[], bool return -ENODEV; } - struct bt_mesh_health_cli *cli = mod->user_data; + struct bt_mesh_health_cli *cli = *(mod->user_data); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t attention; diff --git a/subsys/bluetooth/mesh/shell/rpr.c b/subsys/bluetooth/mesh/shell/rpr.c index c8f05817104..1ddb11f497d 100644 --- a/subsys/bluetooth/mesh/shell/rpr.c +++ b/subsys/bluetooth/mesh/shell/rpr.c @@ -11,7 +11,7 @@ #include "utils.h" -static struct bt_mesh_model *mod; +static const struct bt_mesh_model *mod; /*************************************************************************************************** * Implementation of the model's instance @@ -108,7 +108,7 @@ static int cmd_scan(const struct shell *sh, size_t argc, char *argv[]) hex2bin(argv[2], strlen(argv[2]), uuid, 16); } - err = bt_mesh_rpr_scan_start((struct bt_mesh_rpr_cli *)mod->user_data, + err = bt_mesh_rpr_scan_start((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, argc > 2 ? uuid : NULL, timeout, BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &rsp); if (err) { @@ -153,7 +153,7 @@ static int cmd_scan_ext(const struct shell *sh, size_t argc, char *argv[]) return err; } - err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)mod->user_data, + err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, uuid, timeout, ad_types, (argc - 3)); if (err) { @@ -189,7 +189,7 @@ static int cmd_scan_srv(const struct shell *sh, size_t argc, char *argv[]) return err; } - err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)mod->user_data, + err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, NULL, 0, ad_types, (argc - 1)); if (err) { shell_print(sh, "Scan start failed: %d", err); @@ -213,7 +213,7 @@ static int cmd_scan_caps(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_caps_get((struct bt_mesh_rpr_cli *)mod->user_data, &srv, &caps); + err = bt_mesh_rpr_scan_caps_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &caps); if (err) { shell_print(sh, "Scan capabilities get failed: %d", err); return err; @@ -241,7 +241,7 @@ static int cmd_scan_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_get((struct bt_mesh_rpr_cli *)mod->user_data, &srv, &rsp); + err = bt_mesh_rpr_scan_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); if (err) { shell_print(sh, "Scan get failed: %d", err); return err; @@ -269,7 +269,7 @@ static int cmd_scan_stop(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_stop((struct bt_mesh_rpr_cli *)mod->user_data, &srv, &rsp); + err = bt_mesh_rpr_scan_stop((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); if (err || rsp.status) { shell_print(sh, "Scan stop failed: %d %u", err, rsp.status); return err; @@ -294,7 +294,7 @@ static int cmd_link_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_link_get((struct bt_mesh_rpr_cli *)mod->user_data, &srv, &rsp); + err = bt_mesh_rpr_link_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); if (err) { shell_print(sh, "Link get failed: %d %u", err, rsp.status); return err; @@ -316,7 +316,7 @@ static int cmd_link_close(const struct shell *sh, size_t argc, char *argv[]) }; int err; - err = bt_mesh_rpr_link_close((struct bt_mesh_rpr_cli *)mod->user_data, &srv, &rsp); + err = bt_mesh_rpr_link_close((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); if (err) { shell_print(sh, "Link close failed: %d %u", err, rsp.status); return err; @@ -355,7 +355,7 @@ static int cmd_provision_remote(const struct shell *sh, size_t argc, char *argv[ return err; } - err = bt_mesh_provision_remote((struct bt_mesh_rpr_cli *)mod->user_data, + err = bt_mesh_provision_remote((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, uuid, net_idx, addr); if (err) { shell_print(sh, "Prov remote start failed: %d", err); @@ -396,7 +396,7 @@ static int cmd_reprovision_remote(const struct shell *sh, size_t argc, char *arg return err; } - err = bt_mesh_reprovision_remote((struct bt_mesh_rpr_cli *)mod->user_data, + err = bt_mesh_reprovision_remote((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, addr, composition_changed); if (err) { shell_print(sh, "Reprovisioning failed: %d", err); diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index c1bad5d24ad..3a28829877b 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -68,7 +68,7 @@ static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8 } } -static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, +static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id, uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) { shell_print_ctx("Sending current faults"); @@ -81,7 +81,7 @@ static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, return 0; } -static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid, +static int fault_get_reg(const struct bt_mesh_model *model, uint16_t cid, uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) { if (cid != CONFIG_BT_COMPANY_ID) { @@ -99,7 +99,7 @@ static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid, return 0; } -static int fault_clear(struct bt_mesh_model *model, uint16_t cid) +static int fault_clear(const struct bt_mesh_model *model, uint16_t cid) { if (cid != CONFIG_BT_COMPANY_ID) { return -EINVAL; @@ -110,7 +110,7 @@ static int fault_clear(struct bt_mesh_model *model, uint16_t cid) return 0; } -static int fault_test(struct bt_mesh_model *model, uint8_t test_id, +static int fault_test(const struct bt_mesh_model *model, uint8_t test_id, uint16_t cid) { if (cid != CONFIG_BT_COMPANY_ID) { @@ -124,12 +124,12 @@ static int fault_test(struct bt_mesh_model *model, uint8_t test_id, return 0; } -static void attention_on(struct bt_mesh_model *model) +static void attention_on(const struct bt_mesh_model *model) { shell_print_ctx("Attention On"); } -static void attention_off(struct bt_mesh_model *model) +static void attention_off(const struct bt_mesh_model *model) { shell_print_ctx("Attention Off"); } diff --git a/subsys/bluetooth/mesh/shell/utils.c b/subsys/bluetooth/mesh/shell/utils.c index 8b7ca740663..1d8ab79951d 100644 --- a/subsys/bluetooth/mesh/shell/utils.c +++ b/subsys/bluetooth/mesh/shell/utils.c @@ -13,7 +13,7 @@ #include "mesh/access.h" #include "utils.h" -bool bt_mesh_shell_mdl_first_get(uint16_t id, struct bt_mesh_model **mod) +bool bt_mesh_shell_mdl_first_get(uint16_t id, const struct bt_mesh_model **mod) { const struct bt_mesh_comp *comp = bt_mesh_comp_get(); @@ -27,10 +27,10 @@ bool bt_mesh_shell_mdl_first_get(uint16_t id, struct bt_mesh_model **mod) return false; } -int bt_mesh_shell_mdl_instance_set(const struct shell *sh, struct bt_mesh_model **mod, +int bt_mesh_shell_mdl_instance_set(const struct shell *sh, const struct bt_mesh_model **mod, uint16_t mod_id, uint8_t elem_idx) { - struct bt_mesh_model *mod_temp; + const struct bt_mesh_model *mod_temp; const struct bt_mesh_comp *comp = bt_mesh_comp_get(); if (elem_idx >= comp->elem_count) { @@ -53,14 +53,14 @@ int bt_mesh_shell_mdl_instance_set(const struct shell *sh, struct bt_mesh_model int bt_mesh_shell_mdl_print_all(const struct shell *sh, uint16_t mod_id) { const struct bt_mesh_comp *comp = bt_mesh_comp_get(); - struct bt_mesh_model *mod; + const struct bt_mesh_model *mod; for (int i = 0; i < comp->elem_count; i++) { mod = bt_mesh_model_find(&comp->elem[i], mod_id); if (mod) { shell_print(sh, "Client model instance found at addr 0x%.4X. Element index: %d", - comp->elem[i].addr, mod->elem_idx); + comp->elem[i].addr, *(mod->elem_idx)); } } diff --git a/subsys/bluetooth/mesh/shell/utils.h b/subsys/bluetooth/mesh/shell/utils.h index 222f1f29360..83d025d47ea 100644 --- a/subsys/bluetooth/mesh/shell/utils.h +++ b/subsys/bluetooth/mesh/shell/utils.h @@ -34,9 +34,9 @@ 0), \ SHELL_SUBCMD_SET_END); -bool bt_mesh_shell_mdl_first_get(uint16_t id, struct bt_mesh_model **mod); +bool bt_mesh_shell_mdl_first_get(uint16_t id, const struct bt_mesh_model **mod); -int bt_mesh_shell_mdl_instance_set(const struct shell *sh, struct bt_mesh_model **mod, +int bt_mesh_shell_mdl_instance_set(const struct shell *sh, const struct bt_mesh_model **mod, uint16_t mod_id, uint8_t elem_idx); int bt_mesh_shell_mdl_print_all(const struct shell *sh, uint16_t mod_id); diff --git a/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c b/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c index 3b8f6799b28..05457eff338 100644 --- a/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c +++ b/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c @@ -22,7 +22,7 @@ struct sol_rpl_param { uint8_t *len; }; -static int handle_status(struct bt_mesh_model *mod, +static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -160,7 +160,7 @@ void bt_mesh_sol_pdu_rpl_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } -static int sol_pdu_rpl_cli_init(struct bt_mesh_model *mod) +static int sol_pdu_rpl_cli_init(const struct bt_mesh_model *mod) { if (!bt_mesh_model_in_primary(mod)) { LOG_ERR("Solicitation PDU RPL Configuration client not in primary element"); @@ -169,7 +169,7 @@ static int sol_pdu_rpl_cli_init(struct bt_mesh_model *mod) msg_timeout = CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT; - cli = mod->user_data; + cli = *(mod->user_data); cli->model = mod; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); return 0; diff --git a/subsys/bluetooth/mesh/sol_pdu_rpl_srv.c b/subsys/bluetooth/mesh/sol_pdu_rpl_srv.c index e0fff397640..547494be3be 100644 --- a/subsys/bluetooth/mesh/sol_pdu_rpl_srv.c +++ b/subsys/bluetooth/mesh/sol_pdu_rpl_srv.c @@ -14,7 +14,7 @@ #include LOG_MODULE_REGISTER(bt_mesh_sol_pdu_rpl_srv); -static void sol_rpl_status_rsp(struct bt_mesh_model *mod, +static void sol_rpl_status_rsp(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, uint16_t range, uint8_t len) @@ -32,7 +32,7 @@ static void sol_rpl_status_rsp(struct bt_mesh_model *mod, bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); } -static int item_clear(struct bt_mesh_model *mod, +static int item_clear(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool acked) @@ -78,14 +78,14 @@ static int item_clear(struct bt_mesh_model *mod, return 0; } -static int handle_item_clear(struct bt_mesh_model *mod, +static int handle_item_clear(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { return item_clear(mod, ctx, buf, true); } -static int handle_item_clear_unacked(struct bt_mesh_model *mod, +static int handle_item_clear_unacked(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -99,7 +99,7 @@ const struct bt_mesh_model_op _bt_mesh_sol_pdu_rpl_srv_op[] = { BT_MESH_MODEL_OP_END }; -static int sol_pdu_rpl_srv_init(struct bt_mesh_model *mod) +static int sol_pdu_rpl_srv_init(const struct bt_mesh_model *mod) { if (!bt_mesh_model_in_primary(mod)) { LOG_ERR("Solicitation PDU RPL Configuration server not in primary element"); diff --git a/tests/bluetooth/mesh/basic/src/main.c b/tests/bluetooth/mesh/basic/src/main.c index 8c6c1796c02..34f94d486c3 100644 --- a/tests/bluetooth/mesh/basic/src/main.c +++ b/tests/bluetooth/mesh/basic/src/main.c @@ -15,7 +15,7 @@ static bool has_reg_fault = true; -static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, +static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id, uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) { uint8_t reg_faults[MAX_FAULT] = { [0 ... (MAX_FAULT - 1)] = 0xff }; @@ -30,7 +30,7 @@ static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, return 0; } -static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, +static int fault_get_reg(const struct bt_mesh_model *model, uint16_t company_id, uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) { if (company_id != BT_COMP_ID_LF) { @@ -53,7 +53,7 @@ static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, return 0; } -static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) +static int fault_clear(const struct bt_mesh_model *model, uint16_t company_id) { if (company_id != BT_COMP_ID_LF) { return -EINVAL; @@ -64,7 +64,7 @@ static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) return 0; } -static int fault_test(struct bt_mesh_model *model, uint8_t test_id, +static int fault_test(const struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id) { if (company_id != BT_COMP_ID_LF) { @@ -90,12 +90,12 @@ static struct bt_mesh_health_srv health_srv = { BT_MESH_HEALTH_PUB_DEFINE(health_pub, MAX_FAULT); -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), }; -static int vnd_publish(struct bt_mesh_model *mod) +static int vnd_publish(const struct bt_mesh_model *mod) { printk("Vendor publish\n"); return 0; @@ -109,7 +109,7 @@ static const struct bt_mesh_model_op vnd_ops[] = { BT_MESH_MODEL_OP_END, }; -static struct bt_mesh_model vnd_models[] = { +static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, 0x1234, vnd_ops, &vnd_pub, NULL), BT_MESH_MODEL_VND(BT_COMP_ID_LF, 0x4321, vnd_ops, &vnd_pub2, NULL), }; diff --git a/tests/bluetooth/mesh_shell/src/main.c b/tests/bluetooth/mesh_shell/src/main.c index 60863f7455a..b562e428d11 100644 --- a/tests/bluetooth/mesh_shell/src/main.c +++ b/tests/bluetooth/mesh_shell/src/main.c @@ -43,7 +43,7 @@ struct bt_mesh_large_comp_data_cli large_comp_data_cli; BT_MESH_SHELL_HEALTH_PUB_DEFINE(health_pub); -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&bt_mesh_shell_health_srv, &health_pub), diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index bdc37c2f2e5..36e627abe8c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -454,7 +454,7 @@ static struct bt_mesh_dfu_srv dfu_srv = #define AUTH_METHOD_INPUT 0x03 static struct model_data { - struct bt_mesh_model *model; + const struct bt_mesh_model *model; uint16_t addr; uint16_t appkey_idx; } model_bound[MODEL_BOUNDS_MAX]; @@ -587,7 +587,7 @@ static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8 } } -static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, +static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id, uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) { LOG_DBG(""); @@ -600,7 +600,7 @@ static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, return 0; } -static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, +static int fault_get_reg(const struct bt_mesh_model *model, uint16_t company_id, uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) { LOG_DBG("company_id 0x%04x", company_id); @@ -616,7 +616,7 @@ static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, return 0; } -static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) +static int fault_clear(const struct bt_mesh_model *model, uint16_t company_id) { LOG_DBG("company_id 0x%04x", company_id); @@ -629,7 +629,7 @@ static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) return 0; } -static int fault_test(struct bt_mesh_model *model, uint8_t test_id, +static int fault_test(const struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id) { LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id); @@ -1024,7 +1024,7 @@ static uint8_t proxy_solicit(const void *cmd, uint16_t cmd_len, } #endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */ -static struct bt_mesh_model root_models[] = { +static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), @@ -1091,7 +1091,7 @@ struct model_data *lookup_model_bound(uint16_t id) return NULL; } -static struct bt_mesh_model vnd_models[] = { +static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, NULL), }; @@ -1715,7 +1715,7 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, { const struct btp_mesh_model_send_cmd *cp = cmd; NET_BUF_SIMPLE_DEFINE(msg, UINT8_MAX); - struct bt_mesh_model *model = NULL; + const struct bt_mesh_model *model = NULL; uint16_t src; int err; @@ -5228,7 +5228,7 @@ void model_recv_ev(uint16_t src, uint16_t dst, const void *payload, tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_MODEL_RECV, buf.data, buf.len); } -static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, +static void model_bound_cb(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx) { int i; @@ -5249,7 +5249,7 @@ static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, LOG_ERR("model_bound is full"); } -static void model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, +static void model_unbound_cb(uint16_t addr, const struct bt_mesh_model *model, uint16_t key_idx) { int i; diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.c b/tests/bsim/bluetooth/mesh/src/mesh_test.c index 538af49109e..ea209d9609c 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.c +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.c @@ -27,7 +27,7 @@ struct bt_mesh_test_stats test_stats; struct bt_mesh_msg_ctx test_send_ctx; static void (*ra_cb)(uint8_t *, size_t); -static int msg_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int msg_rx(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { size_t len = buf->len + BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1); @@ -75,7 +75,7 @@ static int msg_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static int ra_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, +static int ra_rx(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_INF("\tlen: %d bytes", buf->len); @@ -97,19 +97,19 @@ static const struct bt_mesh_model_op model_op[] = { BT_MESH_MODEL_OP_END }; -int __weak test_model_pub_update(struct bt_mesh_model *mod) +int __weak test_model_pub_update(const struct bt_mesh_model *mod) { return -1; } -int __weak test_model_settings_set(struct bt_mesh_model *model, +int __weak test_model_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { return -1; } -void __weak test_model_reset(struct bt_mesh_model *model) +void __weak test_model_reset(const struct bt_mesh_model *model) { /* No-op. */ } @@ -128,19 +128,19 @@ static const struct bt_mesh_model_op vnd_model_op[] = { BT_MESH_MODEL_OP_END, }; -int __weak test_vnd_model_pub_update(struct bt_mesh_model *mod) +int __weak test_vnd_model_pub_update(const struct bt_mesh_model *mod) { return -1; } -int __weak test_vnd_model_settings_set(struct bt_mesh_model *model, +int __weak test_vnd_model_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { return -1; } -void __weak test_vnd_model_reset(struct bt_mesh_model *model) +void __weak test_vnd_model_reset(const struct bt_mesh_model *model) { /* No-op. */ } @@ -174,7 +174,7 @@ static struct bt_mesh_priv_beacon_cli priv_beacon_cli; static struct bt_mesh_od_priv_proxy_cli priv_proxy_cli; #endif -static struct bt_mesh_model models[] = { +static const struct bt_mesh_model models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_CB(TEST_MOD_ID, model_op, &pub, NULL, &test_model_cb), @@ -195,14 +195,14 @@ static struct bt_mesh_model models[] = { #endif }; -struct bt_mesh_model *test_model = &models[2]; +const struct bt_mesh_model *test_model = &models[2]; -static struct bt_mesh_model vnd_models[] = { +static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MOD_ID, vnd_model_op, &vnd_pub, NULL, &test_vnd_model_cb), }; -struct bt_mesh_model *test_vnd_model = &vnd_models[0]; +const struct bt_mesh_model *test_vnd_model = &vnd_models[0]; static struct bt_mesh_elem elems[] = { BT_MESH_ELEM(0, models, vnd_models), diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index 08cf2177796..a5c8694947b 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -31,7 +31,7 @@ #define TEST_VND_COMPANY_ID 0x1234 #define TEST_VND_MOD_ID 0x5678 -#define MODEL_LIST(...) ((struct bt_mesh_model[]){ __VA_ARGS__ }) +#define MODEL_LIST(...) ((const struct bt_mesh_model[]){ __VA_ARGS__ }) #define FAIL(msg, ...) \ do { \ @@ -171,8 +171,8 @@ struct bt_mesh_test_sync_ctx { extern enum bst_result_t bst_result; extern const struct bt_mesh_test_cfg *cfg; -extern struct bt_mesh_model *test_model; -extern struct bt_mesh_model *test_vnd_model; +extern const struct bt_mesh_model *test_model; +extern const struct bt_mesh_model *test_vnd_model; extern const uint8_t test_net_key[16]; extern const uint8_t test_app_key[16]; extern const uint8_t test_va_uuid[16]; diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index 9bddf0e8058..dacc30c741e 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -35,15 +35,15 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define RX_JITTER_MAX (10 + CONFIG_BT_MESH_NETWORK_TRANSMIT_COUNT * \ (CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL + 10)) -static int model1_init(struct bt_mesh_model *model); -static int model2_init(struct bt_mesh_model *model); -static int model3_init(struct bt_mesh_model *model); -static int model4_init(struct bt_mesh_model *model); -static int model5_init(struct bt_mesh_model *model); -static int test_msg_handler(struct bt_mesh_model *model, +static int model1_init(const struct bt_mesh_model *model); +static int model2_init(const struct bt_mesh_model *model); +static int model3_init(const struct bt_mesh_model *model); +static int model4_init(const struct bt_mesh_model *model); +static int model5_init(const struct bt_mesh_model *model); +static int test_msg_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); -static int test_msg_ne_handler(struct bt_mesh_model *model, +static int test_msg_ne_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); @@ -99,7 +99,7 @@ static const struct { static struct k_sem publish_sem; static bool publish_allow; -static int model1_update(struct bt_mesh_model *model) +static int model1_update(const struct bt_mesh_model *model) { model->pub->msg->data[1]++; @@ -108,7 +108,7 @@ static int model1_update(struct bt_mesh_model *model) return publish_allow ? k_sem_give(&publish_sem), 0 : -1; } -static int test_msgf_handler(struct bt_mesh_model *model, +static int test_msgf_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -204,7 +204,7 @@ static const struct bt_mesh_model_op model_ne_op5[] = { static struct bt_mesh_cfg_cli cfg_cli; /* do not change model sequence. it will break pointer arithmetic. */ -static struct bt_mesh_model models[] = { +static const struct bt_mesh_model models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_op1, &model_pub1, NULL, &test_model1_cb), @@ -215,7 +215,7 @@ static struct bt_mesh_model models[] = { }; /* do not change model sequence. it will break pointer arithmetic. */ -static struct bt_mesh_model models_ne[] = { +static const struct bt_mesh_model models_ne[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_ne_op1, NULL, NULL, &test_model1_cb), BT_MESH_MODEL_CB(TEST_MODEL_ID_2, model_ne_op2, NULL, NULL, &test_model2_cb), BT_MESH_MODEL_CB(TEST_MODEL_ID_3, model_ne_op3, NULL, NULL, &test_model3_cb), @@ -223,7 +223,7 @@ static struct bt_mesh_model models_ne[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_5, model_ne_op5, NULL, NULL, &test_model5_cb), }; -static struct bt_mesh_model vnd_models[] = {}; +static const struct bt_mesh_model vnd_models[] = {}; static struct bt_mesh_elem elems[] = { BT_MESH_ELEM(0, models, vnd_models), @@ -246,43 +246,43 @@ const struct bt_mesh_comp local_comp = { * m4 mne4 */ -static int model1_init(struct bt_mesh_model *model) +static int model1_init(const struct bt_mesh_model *model) { return 0; } -static int model2_init(struct bt_mesh_model *model) +static int model2_init(const struct bt_mesh_model *model) { return 0; } -static int model3_init(struct bt_mesh_model *model) +static int model3_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, model - 2)); ASSERT_OK(bt_mesh_model_extend(model, model - 1)); - if (model->elem_idx == 1) { + if (*(model->elem_idx) == 1) { ASSERT_OK(bt_mesh_model_extend(model, &models[4])); } return 0; } -static int model4_init(struct bt_mesh_model *model) +static int model4_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, model - 1)); return 0; } -static int model5_init(struct bt_mesh_model *model) +static int model5_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, model - 4)); return 0; } -static int test_msg_handler(struct bt_mesh_model *model, +static int test_msg_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -292,7 +292,7 @@ static int test_msg_handler(struct bt_mesh_model *model, return 0; } -static int test_msg_ne_handler(struct bt_mesh_model *model, +static int test_msg_ne_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -515,7 +515,7 @@ static void pub_param_set(uint8_t period, uint8_t transmit) static void msgf_publish(void) { - struct bt_mesh_model *model = &models[2]; + const struct bt_mesh_model *model = &models[2]; bt_mesh_model_msg_init(model->pub->msg, TEST_MESSAGE_OP_F); net_buf_simple_add_u8(model->pub->msg, 1); @@ -591,7 +591,7 @@ static void recv_jitter_check(int32_t interval, uint8_t count) */ static void test_tx_period(void) { - struct bt_mesh_model *model = &models[2]; + const struct bt_mesh_model *model = &models[2]; bt_mesh_test_cfg_set(NULL, 60); bt_mesh_device_setup(&prov, &local_comp); @@ -647,7 +647,7 @@ static void test_rx_period(void) */ static void test_tx_transmit(void) { - struct bt_mesh_model *model = &models[2]; + const struct bt_mesh_model *model = &models[2]; uint8_t status; int err; @@ -719,7 +719,7 @@ static void test_rx_transmit(void) */ static void test_tx_cancel(void) { - struct bt_mesh_model *model = &models[2]; + const struct bt_mesh_model *model = &models[2]; int err; bt_mesh_test_cfg_set(NULL, 20); diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index e3c564d9739..f9661fa0be0 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -261,7 +261,7 @@ static const struct bt_mesh_comp cli_comp = { static struct k_sem info_get_sem; -static int mock_handle_info_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_handle_info_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { k_sem_give(&info_get_sem); @@ -1310,7 +1310,7 @@ static void test_srv_fail_on_block_get(void) PASS(); } -static int dummy_xfer_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int dummy_xfer_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { return 0; diff --git a/tests/bsim/bluetooth/mesh/src/test_cdp1.c b/tests/bsim/bluetooth/mesh/src/test_cdp1.c index 7884ef17437..03b71dce970 100644 --- a/tests/bsim/bluetooth/mesh/src/test_cdp1.c +++ b/tests/bsim/bluetooth/mesh/src/test_cdp1.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define TEST_VND_MODEL_ID_1 0x3a3a #define TEST_MODEL_DECLARE(number) \ - static int model_##number##_init(struct bt_mesh_model *model); \ + static int model_##number##_init(const struct bt_mesh_model *model); \ static const struct bt_mesh_model_cb test_model_##number##_cb = { \ .init = model_##number##_init, \ }; \ @@ -56,7 +56,7 @@ static const struct bt_mesh_test_cfg node_1_cfg = { static struct bt_mesh_prov prov; static struct bt_mesh_cfg_cli cfg_cli; -static struct bt_mesh_model models_1[] = { +static const struct bt_mesh_model models_1[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_op_1, NULL, NULL, &test_model_1_cb), @@ -64,19 +64,19 @@ static struct bt_mesh_model models_1[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_3, model_op_3, NULL, NULL, &test_model_3_cb), }; -static struct bt_mesh_model models_2[] = { +static const struct bt_mesh_model models_2[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_4, model_op_4, NULL, NULL, &test_model_4_cb), }; -static struct bt_mesh_model models_3[] = { +static const struct bt_mesh_model models_3[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_5, model_op_5, NULL, NULL, &test_model_5_cb), }; -static struct bt_mesh_model models_4[] = { +static const struct bt_mesh_model models_4[] = { BT_MESH_MODEL_CB(TEST_MODEL_ID_6, model_op_6, NULL, NULL, &test_model_6_cb), }; -static struct bt_mesh_model models_vnd1[] = { +static const struct bt_mesh_model models_vnd1[] = { BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MODEL_ID_1, model_op_vnd1, NULL, NULL, &test_model_vnd1_cb), }; @@ -106,41 +106,41 @@ static const struct bt_mesh_comp comp = { * M2 on E0 and M4 on E1 corresponds. * M6 on E4 extends M1 on E0 */ -static int model_1_init(struct bt_mesh_model *model) +static int model_1_init(const struct bt_mesh_model *model) { return 0; } -static int model_2_init(struct bt_mesh_model *model) +static int model_2_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); return 0; } -static int model_3_init(struct bt_mesh_model *model) +static int model_3_init(const struct bt_mesh_model *model) { return 0; } -static int model_4_init(struct bt_mesh_model *model) +static int model_4_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(bt_mesh_model_find(&elems[0], TEST_MODEL_ID_3), model)); ASSERT_OK(bt_mesh_model_correspond(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_2))); return 0; } -static int model_5_init(struct bt_mesh_model *model) +static int model_5_init(const struct bt_mesh_model *model) { return 0; } -static int model_6_init(struct bt_mesh_model *model) +static int model_6_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); return 0; } -static int model_vnd1_init(struct bt_mesh_model *model) +static int model_vnd1_init(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_extend(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_1))); ASSERT_OK(bt_mesh_model_correspond(model, bt_mesh_model_find(&elems[0], TEST_MODEL_ID_3))); diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 0eed5d1478d..83037ea6e73 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -1309,7 +1309,7 @@ static void test_cli_stop(void) static struct k_sem caps_get_sem; -static int mock_handle_caps_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_handle_caps_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_WRN("Rejecting BLOB Information Get message"); @@ -1340,7 +1340,7 @@ static const struct bt_mesh_comp srv_caps_broken_comp = { .elem_count = 1, }; -static int mock_handle_chunks(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_handle_chunks(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_WRN("Skipping receiving block"); @@ -1373,7 +1373,7 @@ static const struct bt_mesh_comp broken_target_comp = { static struct k_sem update_get_sem; -static int mock_handle_update_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_handle_update_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_WRN("Rejecting Firmware Update Get message"); @@ -1406,7 +1406,7 @@ static const struct bt_mesh_comp srv_update_get_broken_comp = { static struct k_sem update_apply_sem; -static int mock_handle_update_apply(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_handle_update_apply(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { LOG_WRN("Rejecting Firmware Update Apply message"); diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index c4b64447987..7e1d9ffca3c 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -31,9 +31,19 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); LCD_STATUS_FIELDS_LEN - \ BT_MESH_MIC_SHORT) /* 378 bytes */ +#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS +#define BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .next = (const struct bt_mesh_model *[]){ NULL }, +#else +#define BT_MESH_MODEL_NEXT_UNASSIGNED() +#endif + #define TEST_MODEL_CNT_CB(_dummy_op, _metadata) \ { \ .id = 0x1234, \ + .elem_idx = (uint8_t []) { 0 }, \ + .mod_idx = (uint8_t []) { 0 }, \ + .flags = (uint16_t []) { 0 }, \ .pub = NULL, \ .keys = NULL, \ .keys_cnt = 0, \ @@ -41,7 +51,8 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); .groups_cnt = 0, \ .op = _dummy_op, \ .cb = NULL, \ - .user_data = NULL, \ + BT_MESH_MODEL_NEXT_UNASSIGNED() \ + .user_data = (void *[]){ NULL }, \ .metadata = _metadata, \ } diff --git a/tests/bsim/bluetooth/mesh/src/test_op_agg.c b/tests/bsim/bluetooth/mesh/src/test_op_agg.c index d8bb50b3fd3..8735bdf524d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_op_agg.c +++ b/tests/bsim/bluetooth/mesh/src/test_op_agg.c @@ -54,7 +54,7 @@ static uint8_t cli_sent_array[TEST_SEND_ITR], cli_rcvd_array[TEST_SEND_ITR]; static struct bt_mesh_prov prov; static struct bt_mesh_cfg_cli cfg_cli; -static int get_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int get_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t seq = net_buf_simple_pull_u8(buf); @@ -78,7 +78,7 @@ static int get_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return bt_mesh_model_send(model, ctx, &msg, NULL, NULL); } -static int status_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int status_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { uint8_t seq = net_buf_simple_pull_u8(buf); @@ -93,7 +93,8 @@ static int status_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *c return 0; } -static int dummy_vnd_mod_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t seq) +static int dummy_vnd_mod_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + uint8_t seq) { BT_MESH_MODEL_BUF_DEFINE(msg, BT_MESH_DUMMY_VND_MOD_GET_OP, BT_MESH_DUMMY_VND_MOD_MSG_MAXLEN); diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 17244be15fe..df3eaa19989 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -338,7 +338,7 @@ static void check_mod_pub_params(const struct bt_mesh_cfg_cli_mod_pub *expected, ASSERT_EQUAL(expected->transmit, got->transmit); } -int test_model_settings_set(struct bt_mesh_model *model, +int test_model_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { @@ -364,12 +364,12 @@ int test_model_settings_set(struct bt_mesh_model *model, return 0; } -void test_model_reset(struct bt_mesh_model *model) +void test_model_reset(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_data_store(test_model, false, TEST_MOD_DATA_NAME, NULL, 0)); } -int test_vnd_model_settings_set(struct bt_mesh_model *model, +int test_vnd_model_settings_set(const struct bt_mesh_model *model, const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) { @@ -395,7 +395,7 @@ int test_vnd_model_settings_set(struct bt_mesh_model *model, return 0; } -void test_vnd_model_reset(struct bt_mesh_model *model) +void test_vnd_model_reset(const struct bt_mesh_model *model) { ASSERT_OK(bt_mesh_model_data_store(test_vnd_model, true, TEST_VND_MOD_DATA_NAME, NULL, 0)); } diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 24e1f627382..80eb9ff38cd 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -152,7 +152,7 @@ static const struct bt_mesh_comp rpr_cli_srv_comp = { .elem_count = 1, }; -static int mock_pdu_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int mock_pdu_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { /* Device becomes unresponsive and doesn't communicate with other nodes anymore */ @@ -168,10 +168,10 @@ static const struct bt_mesh_model_op model_rpr_op1[] = { BT_MESH_MODEL_OP_END }; -static int mock_model_init(struct bt_mesh_model *mod) +static int mock_model_init(const struct bt_mesh_model *mod) { mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - mod->flags |= BT_MESH_MOD_DEVKEY_ONLY; + *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/tests/bsim/bluetooth/mesh/src/test_sar.c b/tests/bsim/bluetooth/mesh/src/test_sar.c index a928d973a25..7214366247d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_sar.c +++ b/tests/bsim/bluetooth/mesh/src/test_sar.c @@ -91,7 +91,7 @@ static void data_integrity_check(struct net_buf_simple *buf) net_buf_simple_restore(buf, &state); } -static int get_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int get_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { data_integrity_check(buf); @@ -104,7 +104,7 @@ static int get_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return bt_mesh_model_send(model, ctx, &msg, NULL, NULL); } -static int status_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int status_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { data_integrity_check(buf); @@ -112,7 +112,7 @@ static int status_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *c return 0; } -static int dummy_vnd_mod_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int dummy_vnd_mod_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t msg[]) { BT_MESH_MODEL_BUF_DEFINE(buf, DUMMY_VND_MOD_GET_OP, MAX_SDU_MSG_LEN); @@ -185,7 +185,7 @@ static void array_random_fill(uint8_t array[], uint16_t len, int seed) static void cli_max_len_sdu_send(struct bt_mesh_sar_rx *sar_rx_config, struct bt_mesh_sar_tx *sar_tx_config) { - struct bt_mesh_model *dummy_vnd_mod = &elements[0].vnd_models[0]; + const struct bt_mesh_model *dummy_vnd_mod = &elements[0].vnd_models[0]; bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &comp); From 2cd8d40b97c8bb9d9c1fabe9088c1970a11667f6 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Wed, 15 Nov 2023 18:03:40 +0800 Subject: [PATCH 3743/4498] Bluetooth: Mesh: Split Model Structure Split Model Variables to separate structue. Signed-off-by: Lingao Meng --- include/zephyr/bluetooth/mesh/access.h | 58 +++++------- samples/boards/nrf/mesh/onoff-app/src/main.c | 4 +- .../src/mesh/device_composition.c | 4 +- .../boards/reel_board/mesh_badge/src/mesh.c | 4 +- subsys/bluetooth/mesh/access.c | 88 +++++++++---------- subsys/bluetooth/mesh/blob_cli.c | 12 +-- subsys/bluetooth/mesh/blob_srv.c | 22 ++--- subsys/bluetooth/mesh/cfg_cli.c | 6 +- subsys/bluetooth/mesh/cfg_srv.c | 12 +-- subsys/bluetooth/mesh/dfd_srv.c | 38 ++++---- subsys/bluetooth/mesh/dfu_cli.c | 12 +-- subsys/bluetooth/mesh/dfu_srv.c | 18 ++-- subsys/bluetooth/mesh/health_cli.c | 12 +-- subsys/bluetooth/mesh/health_srv.c | 18 ++-- subsys/bluetooth/mesh/large_comp_data_cli.c | 4 +- subsys/bluetooth/mesh/large_comp_data_srv.c | 2 +- subsys/bluetooth/mesh/od_priv_proxy_cli.c | 4 +- subsys/bluetooth/mesh/od_priv_proxy_srv.c | 2 +- subsys/bluetooth/mesh/priv_beacon_cli.c | 4 +- subsys/bluetooth/mesh/rpr_cli.c | 22 ++--- subsys/bluetooth/mesh/rpr_srv.c | 4 +- subsys/bluetooth/mesh/sar_cfg_cli.c | 8 +- subsys/bluetooth/mesh/sar_cfg_srv.c | 2 +- subsys/bluetooth/mesh/shell/blob.c | 16 ++-- subsys/bluetooth/mesh/shell/dfd.c | 20 ++--- subsys/bluetooth/mesh/shell/dfu.c | 26 +++--- subsys/bluetooth/mesh/shell/health.c | 14 +-- subsys/bluetooth/mesh/shell/rpr.c | 20 ++--- subsys/bluetooth/mesh/shell/utils.c | 2 +- subsys/bluetooth/mesh/sol_pdu_rpl_cli.c | 2 +- tests/bsim/bluetooth/mesh/src/test_access.c | 2 +- tests/bsim/bluetooth/mesh/src/test_lcd.c | 13 +-- .../bsim/bluetooth/mesh/src/test_provision.c | 2 +- 33 files changed, 226 insertions(+), 251 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index aa623549814..45042b87d9b 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -31,10 +31,11 @@ #endif #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS -#define BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .next = (const struct bt_mesh_model *[]){ NULL }, +#define BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ + .rt = (void *)(void *[]){ NULL, NULL, (_user_data) }, #else -#define BT_MESH_MODEL_NEXT_UNASSIGNED() +#define BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ + .rt = (void *)(void *[]){ NULL, (_user_data) }, #endif /** @@ -432,9 +433,7 @@ struct bt_mesh_model_op { #define BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, _keys, _grps, _cb) \ { \ .id = (_id), \ - .elem_idx = (uint8_t []) { 0 }, \ - .mod_idx = (uint8_t []) { 0 }, \ - .flags = (uint16_t []) { 0 }, \ + BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \ .keys_cnt = _keys, \ @@ -443,8 +442,6 @@ struct bt_mesh_model_op { BT_MESH_MODEL_UUIDS_UNASSIGNED() \ .op = _op, \ .cb = _cb, \ - BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .user_data = (void *[]){ _user_data }, \ } /** @@ -469,9 +466,7 @@ struct bt_mesh_model_op { { \ .vnd.company = (_company), \ .vnd.id = (_id), \ - .elem_idx = (uint8_t []) { 0 }, \ - .mod_idx = (uint8_t []) { 0 }, \ - .flags = (uint16_t []) { 0 }, \ + BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ .op = _op, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \ @@ -479,8 +474,6 @@ struct bt_mesh_model_op { .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \ .groups_cnt = _grps, \ BT_MESH_MODEL_UUIDS_UNASSIGNED() \ - BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .user_data = (void *[]){ _user_data }, \ .cb = _cb, \ } @@ -520,9 +513,7 @@ struct bt_mesh_model_op { #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \ { \ .id = (_id), \ - .elem_idx = (uint8_t []) { 0 }, \ - .mod_idx = (uint8_t []) { 0 }, \ - .flags = (uint16_t []) { 0 }, \ + BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \ .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \ @@ -531,8 +522,6 @@ struct bt_mesh_model_op { BT_MESH_MODEL_UUIDS_UNASSIGNED() \ .op = _op, \ .cb = _cb, \ - BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .user_data = (void *[]){ _user_data }, \ .metadata = _metadata, \ } #else @@ -578,9 +567,7 @@ struct bt_mesh_model_op { { \ .vnd.company = (_company), \ .vnd.id = (_id), \ - .elem_idx = (uint8_t []) { 0 }, \ - .mod_idx = (uint8_t []) { 0 }, \ - .flags = (uint16_t []) { 0 }, \ + BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ .op = _op, \ .pub = _pub, \ .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \ @@ -588,8 +575,6 @@ struct bt_mesh_model_op { .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \ .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \ BT_MESH_MODEL_UUIDS_UNASSIGNED() \ - BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .user_data = (void *[]){ _user_data }, \ .cb = _cb, \ .metadata = _metadata, \ } @@ -900,10 +885,19 @@ struct bt_mesh_model { const struct bt_mesh_mod_id_vnd vnd; }; - /* Internal information, mainly for persistent storage */ - uint8_t * const elem_idx; /* Belongs to Nth element */ - uint8_t * const mod_idx; /* Is the Nth model in the element */ - uint16_t * const flags; /* Model flags for internal bookkeeping */ + /* Model runtime information */ + struct { + uint8_t elem_idx; /* Belongs to Nth element */ + uint8_t mod_idx; /* Is the Nth model in the element */ + uint16_t flags; /* Model flags for internal bookkeeping */ + +#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS + /* Pointer to the next model in a model extension list. */ + const struct bt_mesh_model *next; +#endif + /** Model-specific user data */ + void *user_data; + } * const rt; /** Model Publication */ struct bt_mesh_model_pub * const pub; @@ -927,18 +921,10 @@ struct bt_mesh_model { /** Model callback structure. */ const struct bt_mesh_model_cb * const cb; -#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS - /* Pointer to the next model in a model extension list. */ - const struct bt_mesh_model ** const next; -#endif - #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) || defined(__DOXYGEN__) /* Pointer to the array of model metadata entries. */ struct bt_mesh_models_metadata_entry **metadata; #endif - - /** Model-specific user data */ - void ** const user_data; }; /** Callback structure for monitoring model message sending */ @@ -1048,7 +1034,7 @@ const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *el */ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) { - return (*(mod->elem_idx) == 0); + return (mod->rt->elem_idx == 0); } /** @brief Immediately store the model's user data in persistent storage. diff --git a/samples/boards/nrf/mesh/onoff-app/src/main.c b/samples/boards/nrf/mesh/onoff-app/src/main.c index 817d2c023a6..71b787fe497 100644 --- a/samples/boards/nrf/mesh/onoff-app/src/main.c +++ b/samples/boards/nrf/mesh/onoff-app/src/main.c @@ -286,7 +286,7 @@ static int gen_onoff_get(const struct bt_mesh_model *model, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); - struct led_onoff_state *onoff_state = *(model->user_data); + struct led_onoff_state *onoff_state = model->rt->user_data; printk("addr 0x%04x onoff 0x%02x\n", bt_mesh_model_elem(model)->addr, onoff_state->current); @@ -305,7 +305,7 @@ static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct net_buf_simple *buf) { struct net_buf_simple *msg = model->pub->msg; - struct led_onoff_state *onoff_state = *(model->user_data); + struct led_onoff_state *onoff_state = model->rt->user_data; int err; onoff_state->current = net_buf_simple_pull_u8(buf); diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 54a5a2c8af7..775c793bb37 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -991,7 +991,7 @@ static int vnd_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct struct net_buf_simple *buf) { struct net_buf_simple *msg = NET_BUF_SIMPLE(3 + 6 + 4); - struct vendor_state *state = *(model->user_data); + struct vendor_state *state = model->rt->user_data; /* This is dummy response for demo purpose */ state->response = 0xA578FEB3; @@ -1014,7 +1014,7 @@ static int vnd_set_unack(const struct bt_mesh_model *model, uint8_t tid; int current; int64_t now; - struct vendor_state *state = *(model->user_data); + struct vendor_state *state = model->rt->user_data; current = net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); diff --git a/samples/boards/reel_board/mesh_badge/src/mesh.c b/samples/boards/reel_board/mesh_badge/src/mesh.c index ae219387cf5..61af8cc0b6d 100644 --- a/samples/boards/reel_board/mesh_badge/src/mesh.c +++ b/samples/boards/reel_board/mesh_badge/src/mesh.c @@ -184,7 +184,7 @@ static int gen_onoff_get(const struct bt_mesh_model *model, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); - struct led_onoff_state *state = *(model->user_data); + struct led_onoff_state *state = model->rt->user_data; printk("addr 0x%04x onoff 0x%02x\n", bt_mesh_model_elem(model)->addr, state->current); @@ -203,7 +203,7 @@ static int gen_onoff_set_unack(const struct bt_mesh_model *model, struct net_buf_simple *buf) { struct net_buf_simple *msg = model->pub->msg; - struct led_onoff_state *state = *(model->user_data); + struct led_onoff_state *state = model->rt->user_data; int err; uint8_t tid, onoff; int64_t now; diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 2911a42c7af..4b6a45ae5c8 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -92,12 +92,12 @@ static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE]; (idx)++) #define IS_MOD_BASE(mod, idx, offset) \ - (mod_rel_list[(idx)].elem_base == *((mod)->elem_idx) && \ - mod_rel_list[(idx)].idx_base == *((mod)->mod_idx) + (offset)) + (mod_rel_list[(idx)].elem_base == mod->rt->elem_idx && \ + mod_rel_list[(idx)].idx_base == mod->rt->mod_idx + (offset)) #define IS_MOD_EXTENSION(mod, idx, offset) \ - (mod_rel_list[(idx)].elem_ext == *((mod)->elem_idx) && \ - mod_rel_list[(idx)].idx_ext == *((mod)->mod_idx) + (offset)) + (mod_rel_list[(idx)].elem_ext == mod->rt->elem_idx && \ + mod_rel_list[(idx)].idx_ext == mod->rt->mod_idx + (offset)) #define RELATION_TYPE_EXT 0xFF @@ -533,7 +533,7 @@ static void add_items_to_page(struct net_buf_simple *buf, const struct bt_mesh_m MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i, sig_offset) && mod_rel_list[i].type == RELATION_TYPE_EXT) { - elem_offset = *(mod->elem_idx) - mod_rel_list[i].elem_base; + elem_offset = mod->rt->elem_idx - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && elem_offset < 4 && @@ -569,7 +569,7 @@ static size_t mod_items_size(const struct bt_mesh_model *mod, uint8_t sig_offset MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i, sig_offset)) { - offset = *(mod->elem_idx) - mod_rel_list[i].elem_base; + offset = mod->rt->elem_idx - mod_rel_list[i].elem_base; temp_size += (ext_mod_cnt < 32 && offset < 4 && offset > -5) ? 1 : 2; } } @@ -901,7 +901,7 @@ static void mod_publish(struct k_work *work) struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod) { - return &dev_comp->elem[*(mod->elem_idx)]; + return &dev_comp->elem[mod->rt->elem_idx]; } const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx) @@ -975,9 +975,9 @@ static void mod_init(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, mod->keys[i] = BT_MESH_KEY_UNUSED; } - *(mod->elem_idx) = elem - dev_comp->elem; + mod->rt->elem_idx = elem - dev_comp->elem; if (vnd) { - *(mod->mod_idx) = mod - elem->vnd_models; + mod->rt->mod_idx = mod - elem->vnd_models; if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)) { *err = bt_mesh_vnd_mod_msg_cid_check(mod); @@ -987,7 +987,7 @@ static void mod_init(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } } else { - *(mod->mod_idx) = mod - elem->models; + mod->rt->mod_idx = mod - elem->models; } if (mod->cb && mod->cb->init) { @@ -1107,7 +1107,7 @@ static enum bt_mesh_walk find_group_mod_visitor(const struct bt_mesh_model *mod, { struct find_group_visitor_ctx *ctx = user_data; - if (*(mod->elem_idx) != *(ctx->mod->elem_idx)) { + if (mod->rt->elem_idx != ctx->mod->rt->elem_idx) { return BT_MESH_WALK_CONTINUE; } @@ -1165,7 +1165,7 @@ static enum bt_mesh_walk find_uuid_mod_visitor(const struct bt_mesh_model *mod, { struct find_uuid_visitor_ctx *ctx = user_data; - if (*(mod->elem_idx) != *(ctx->mod->elem_idx)) { + if (mod->rt->elem_idx != ctx->mod->rt->elem_idx) { return BT_MESH_WALK_CONTINUE; } @@ -1315,11 +1315,11 @@ bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key) static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const uint8_t *uuid) { if (BT_MESH_ADDR_IS_UNICAST(dst)) { - return (dev_comp->elem[*(mod->elem_idx)].addr == dst); + return (dev_comp->elem[mod->rt->elem_idx].addr == dst); } else if (BT_MESH_ADDR_IS_VIRTUAL(dst)) { return !!bt_mesh_model_find_uuid(&mod, uuid); } else if (BT_MESH_ADDR_IS_GROUP(dst) || - (BT_MESH_ADDR_IS_FIXED_GROUP(dst) && *(mod->elem_idx) != 0)) { + (BT_MESH_ADDR_IS_FIXED_GROUP(dst) && mod->rt->elem_idx != 0)) { return !!bt_mesh_model_find_group(&mod, dst); } @@ -1327,7 +1327,7 @@ static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const u * the lower layers have already confirmed that we are subscribing to * it. All models on the primary element should receive the message. */ - return *(mod->elem_idx) == 0; + return mod->rt->elem_idx == 0; } static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem, @@ -1607,12 +1607,12 @@ void bt_mesh_model_extensions_walk(const struct bt_mesh_model *model, #else const struct bt_mesh_model *it; - if (cb(model, user_data) == BT_MESH_WALK_STOP || !*(model->next)) { + if (cb(model, user_data) == BT_MESH_WALK_STOP || !model->rt->next) { return; } /* List is circular. Step through all models until we reach the start: */ - for (it = *(model->next); it != model; it = *(it->next)) { + for (it = model->rt->next; it != model; it = it->rt->next) { if (cb(it, user_data) == BT_MESH_WALK_STOP) { return; } @@ -1643,10 +1643,10 @@ static int mod_rel_register(const struct bt_mesh_model *base, { LOG_DBG(""); struct mod_relation extension = { - *(base->elem_idx), - *(base->mod_idx) + get_sig_offset(base), - *(ext->elem_idx), - *(ext->mod_idx) + get_sig_offset(ext), + base->rt->elem_idx, + base->rt->mod_idx + get_sig_offset(base), + ext->rt->elem_idx, + ext->rt->mod_idx + get_sig_offset(ext), type, }; int i; @@ -1670,18 +1670,18 @@ int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod, { const struct bt_mesh_model *a = extending_mod; const struct bt_mesh_model *b = base_mod; - const struct bt_mesh_model *a_next = *(a->next); - const struct bt_mesh_model *b_next = *(b->next); + const struct bt_mesh_model *a_next = a->rt->next; + const struct bt_mesh_model *b_next = b->rt->next; const struct bt_mesh_model *it; - *(base_mod->flags) |= BT_MESH_MOD_EXTENDED; + base_mod->rt->flags |= BT_MESH_MOD_EXTENDED; if (a == b) { return 0; } /* Check if a's list contains b */ - for (it = a; (it != NULL) && (*(it->next) != a); it = *(it->next)) { + for (it = a; (it != NULL) && (it->rt->next != a); it = it->rt->next) { if (it == b) { goto register_extension; } @@ -1689,15 +1689,15 @@ int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod, /* Merge lists */ if (a_next) { - *(b->next) = a_next; + b->rt->next = a_next; } else { - *(b->next) = a; + b->rt->next = a; } if (b_next) { - *(a->next) = b_next; + a->rt->next = b_next; } else { - *(a->next) = b; + a->rt->next = b; } register_extension: @@ -1745,7 +1745,7 @@ int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod, bool bt_mesh_model_is_extended(const struct bt_mesh_model *model) { - return *(model->flags) & BT_MESH_MOD_EXTENDED; + return model->rt->flags & BT_MESH_MOD_EXTENDED; } static int mod_set_bind(const struct bt_mesh_model *mod, size_t len_rd, @@ -2041,7 +2041,7 @@ BT_MESH_SETTINGS_DEFINE(comp, "cmp", comp_set); static void encode_mod_path(const struct bt_mesh_model *mod, bool vnd, const char *key, char *path, size_t path_len) { - uint16_t mod_key = (((uint16_t)*(mod->elem_idx) << 8) | *(mod->mod_idx)); + uint16_t mod_key = (((uint16_t)mod->rt->elem_idx << 8) | mod->rt->mod_idx); if (vnd) { snprintk(path, path_len, "bt/mesh/v/%x/%s", mod_key, key); @@ -2174,28 +2174,28 @@ static void store_pending_mod(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { - if (!*(mod->flags)) { + if (!mod->rt->flags) { return; } - if (*(mod->flags) & BT_MESH_MOD_BIND_PENDING) { - *(mod->flags) &= ~BT_MESH_MOD_BIND_PENDING; + if (mod->rt->flags & BT_MESH_MOD_BIND_PENDING) { + mod->rt->flags &= ~BT_MESH_MOD_BIND_PENDING; store_pending_mod_bind(mod, vnd); } - if (*(mod->flags) & BT_MESH_MOD_SUB_PENDING) { - *(mod->flags) &= ~BT_MESH_MOD_SUB_PENDING; + if (mod->rt->flags & BT_MESH_MOD_SUB_PENDING) { + mod->rt->flags &= ~BT_MESH_MOD_SUB_PENDING; store_pending_mod_sub(mod, vnd); store_pending_mod_sub_va(mod, vnd); } - if (*(mod->flags) & BT_MESH_MOD_PUB_PENDING) { - *(mod->flags) &= ~BT_MESH_MOD_PUB_PENDING; + if (mod->rt->flags & BT_MESH_MOD_PUB_PENDING) { + mod->rt->flags &= ~BT_MESH_MOD_PUB_PENDING; store_pending_mod_pub(mod, vnd); } - if (*(mod->flags) & BT_MESH_MOD_DATA_PENDING) { - *(mod->flags) &= ~BT_MESH_MOD_DATA_PENDING; + if (mod->rt->flags & BT_MESH_MOD_DATA_PENDING) { + mod->rt->flags &= ~BT_MESH_MOD_DATA_PENDING; mod->cb->pending_store(mod); } } @@ -2207,19 +2207,19 @@ void bt_mesh_model_pending_store(void) void bt_mesh_model_bind_store(const struct bt_mesh_model *mod) { - *(mod->flags) |= BT_MESH_MOD_BIND_PENDING; + mod->rt->flags |= BT_MESH_MOD_BIND_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } void bt_mesh_model_sub_store(const struct bt_mesh_model *mod) { - *(mod->flags) |= BT_MESH_MOD_SUB_PENDING; + mod->rt->flags |= BT_MESH_MOD_SUB_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } void bt_mesh_model_pub_store(const struct bt_mesh_model *mod) { - *(mod->flags) |= BT_MESH_MOD_PUB_PENDING; + mod->rt->flags |= BT_MESH_MOD_PUB_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } @@ -2584,7 +2584,7 @@ void bt_mesh_model_settings_commit(void) void bt_mesh_model_data_store_schedule(const struct bt_mesh_model *mod) { - *(mod->flags) |= BT_MESH_MOD_DATA_PENDING; + mod->rt->flags |= BT_MESH_MOD_DATA_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } diff --git a/subsys/bluetooth/mesh/blob_cli.c b/subsys/bluetooth/mesh/blob_cli.c index 4fd0fe7bac9..f96a9af0653 100644 --- a/subsys/bluetooth/mesh/blob_cli.c +++ b/subsys/bluetooth/mesh/blob_cli.c @@ -1207,7 +1207,7 @@ static void rx_block_status(struct bt_mesh_blob_cli *cli, static int handle_xfer_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; enum bt_mesh_blob_xfer_phase expected_phase; struct bt_mesh_blob_target *target; struct bt_mesh_blob_xfer_info info = { 0 }; @@ -1279,7 +1279,7 @@ static int handle_xfer_status(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_block_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; struct block_status status = { .status = BT_MESH_BLOB_SUCCESS, .block.number = cli->block.number, @@ -1333,7 +1333,7 @@ static int handle_block_report(const struct bt_mesh_model *mod, struct bt_mesh_m static int handle_block_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; struct bt_mesh_blob_target *target; struct block_status status = { 0 }; uint8_t status_and_format; @@ -1404,7 +1404,7 @@ static int handle_block_status(const struct bt_mesh_model *mod, struct bt_mesh_m static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; struct bt_mesh_blob_cli_caps caps; enum bt_mesh_blob_status status; struct bt_mesh_blob_target *target; @@ -1460,7 +1460,7 @@ const struct bt_mesh_model_op _bt_mesh_blob_cli_op[] = { static int blob_cli_init(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; cli->mod = mod; @@ -1473,7 +1473,7 @@ static int blob_cli_init(const struct bt_mesh_model *mod) static void blob_cli_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_cli *cli = *(mod->user_data); + struct bt_mesh_blob_cli *cli = mod->rt->user_data; cli_state_reset(cli); } diff --git a/subsys/bluetooth/mesh/blob_srv.c b/subsys/bluetooth/mesh/blob_srv.c index 2fee121415d..3773a17e9af 100644 --- a/subsys/bluetooth/mesh/blob_srv.c +++ b/subsys/bluetooth/mesh/blob_srv.c @@ -418,7 +418,7 @@ static void block_status_rsp(struct bt_mesh_blob_srv *srv, static int handle_xfer_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; LOG_DBG(""); @@ -438,7 +438,7 @@ static int handle_xfer_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_c static int handle_xfer_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; enum bt_mesh_blob_status status; enum bt_mesh_blob_xfer_mode mode; uint64_t id; @@ -570,7 +570,7 @@ static int handle_xfer_cancel(const struct bt_mesh_model *mod, struct bt_mesh_ms struct net_buf_simple *buf) { enum bt_mesh_blob_status status = BT_MESH_BLOB_SUCCESS; - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; uint64_t id; id = net_buf_simple_pull_le64(buf); @@ -598,7 +598,7 @@ static int handle_block_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ struct net_buf_simple *buf) { enum bt_mesh_blob_status status; - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; switch (srv->phase) { case BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK: @@ -628,7 +628,7 @@ static int handle_block_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ static int handle_block_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; enum bt_mesh_blob_status status; uint16_t block_number, chunk_size; int err; @@ -723,7 +723,7 @@ static int handle_block_start(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_chunk(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; struct bt_mesh_blob_chunk chunk; size_t expected_size = 0; uint16_t idx; @@ -813,7 +813,7 @@ static int handle_chunk(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_info_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; LOG_DBG(""); @@ -849,7 +849,7 @@ const struct bt_mesh_model_op _bt_mesh_blob_srv_op[] = { static int blob_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; srv->mod = mod; srv->state.ttl = BT_MESH_TTL_DEFAULT; @@ -865,7 +865,7 @@ static int blob_srv_settings_set(const struct bt_mesh_model *mod, const char *na size_t len_rd, settings_read_cb read_cb, void *cb_arg) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; ssize_t len; if (len_rd < offsetof(struct bt_mesh_blob_srv_state, blocks)) { @@ -905,7 +905,7 @@ static int blob_srv_settings_set(const struct bt_mesh_model *mod, const char *na static int blob_srv_start(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; int err = -ENOTSUP; if (srv->phase == BT_MESH_BLOB_XFER_PHASE_INACTIVE) { @@ -933,7 +933,7 @@ static int blob_srv_start(const struct bt_mesh_model *mod) static void blob_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_blob_srv *srv = *(mod->user_data); + struct bt_mesh_blob_srv *srv = mod->rt->user_data; phase_set(srv, BT_MESH_BLOB_XFER_PHASE_INACTIVE); srv->state.xfer.mode = BT_MESH_BLOB_XFER_MODE_NONE; diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 2f05fea2f15..aa762e9b906 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -1094,12 +1094,12 @@ static int cfg_cli_init(const struct bt_mesh_model *model) return -EINVAL; } - if (!*(model->user_data)) { + if (!model->rt->user_data) { LOG_ERR("No Configuration Client context provided"); return -EINVAL; } - cli = *(model->user_data); + cli = model->rt->user_data; cli->model = model; msg_timeout = CONFIG_BT_MESH_CFG_CLI_TIMEOUT; @@ -1108,7 +1108,7 @@ static int cfg_cli_init(const struct bt_mesh_model *model) * and remote keys are allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_ANY; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 5920ecd6dc1..04374977421 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -1238,7 +1238,7 @@ static enum bt_mesh_walk mod_sub_list_visitor(const struct bt_mesh_model *mod, v int count = 0; int i; - if (*(mod->elem_idx) != visit->elem_idx) { + if (mod->rt->elem_idx != visit->elem_idx) { return BT_MESH_WALK_CONTINUE; } @@ -1257,7 +1257,7 @@ static enum bt_mesh_walk mod_sub_list_visitor(const struct bt_mesh_model *mod, v count++; } - LOG_DBG("sublist: model %u:%x: %u groups", *(mod->elem_idx), mod->id, count); + LOG_DBG("sublist: model %u:%x: %u groups", mod->rt->elem_idx, mod->id, count); return BT_MESH_WALK_CONTINUE; } @@ -1306,7 +1306,7 @@ static int mod_sub_get(const struct bt_mesh_model *model, net_buf_simple_add_le16(&msg, id); visit_ctx.msg = &msg; - visit_ctx.elem_idx = *(mod->elem_idx); + visit_ctx.elem_idx = mod->rt->elem_idx; bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: @@ -1365,7 +1365,7 @@ static int mod_sub_get_vnd(const struct bt_mesh_model *model, net_buf_simple_add_le16(&msg, id); visit_ctx.msg = &msg; - visit_ctx.elem_idx = *(mod->elem_idx); + visit_ctx.elem_idx = mod->rt->elem_idx; bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: @@ -1881,7 +1881,7 @@ static int mod_app_bind(const struct bt_mesh_model *model, } /* Some models only allow device key based access */ - if (*(mod->flags) & BT_MESH_MOD_DEVKEY_ONLY) { + if (mod->rt->flags & BT_MESH_MOD_DEVKEY_ONLY) { LOG_ERR("Client tried to bind AppKey to DevKey based model"); status = STATUS_CANNOT_BIND; goto send_status; @@ -2520,7 +2520,7 @@ static int cfg_srv_init(const struct bt_mesh_model *model) * device-key is allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_LOCAL; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 245052b58f8..54184acd9b8 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -116,7 +116,7 @@ static int handle_receivers_add(const struct bt_mesh_model *mod, struct bt_mesh_ struct net_buf_simple *buf) { enum bt_mesh_dfd_status status = BT_MESH_DFD_SUCCESS; - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; if (buf->len % 3) { return -EINVAL; @@ -146,7 +146,7 @@ static int handle_receivers_add(const struct bt_mesh_model *mod, struct bt_mesh_ static int handle_receivers_delete_all(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; receivers_status_rsp(srv, ctx, bt_mesh_dfd_srv_receivers_delete_all(srv)); @@ -156,7 +156,7 @@ static int handle_receivers_delete_all(const struct bt_mesh_model *mod, struct b static int handle_receivers_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; uint16_t first, cnt; uint8_t progress; int i; @@ -226,7 +226,7 @@ static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_me net_buf_simple_add_le32(&rsp, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE - size); #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; if (srv->oob_schemes.count > 0) { net_buf_simple_add_u8(&rsp, 1); @@ -271,7 +271,7 @@ static void status_rsp(struct bt_mesh_dfd_srv *srv, struct bt_mesh_msg_ctx *ctx, static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); @@ -281,7 +281,7 @@ static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *c static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; struct bt_mesh_dfd_start_params params; uint8_t byte; @@ -314,7 +314,7 @@ static int handle_suspend(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; status_rsp(srv, ctx, bt_mesh_dfd_srv_suspend(srv)); @@ -324,7 +324,7 @@ static int handle_suspend(const struct bt_mesh_model *mod, static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; bt_mesh_dfd_srv_cancel(srv, ctx); @@ -334,7 +334,7 @@ static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_apply(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; status_rsp(srv, ctx, bt_mesh_dfd_srv_apply(srv)); @@ -396,7 +396,7 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, static int handle_upload_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); @@ -441,7 +441,7 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; size_t meta_len, fwid_len, size; const uint8_t *meta, *fwid; uint16_t timeout_base; @@ -563,7 +563,7 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; uint8_t uri_len; uint8_t *uri; uint16_t fwid_len; @@ -654,7 +654,7 @@ static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_me static int handle_upload_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD @@ -693,7 +693,7 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv, static int handle_fw_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; struct bt_mesh_dfu_slot *slot; const uint8_t *fwid; size_t fwid_len; @@ -717,7 +717,7 @@ static int handle_fw_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_fw_get_by_index(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; const struct bt_mesh_dfu_slot *slot; uint16_t idx; @@ -738,7 +738,7 @@ static int handle_fw_get_by_index(const struct bt_mesh_model *mod, struct bt_mes static int handle_fw_delete(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; const uint8_t *fwid; size_t fwid_len; @@ -767,7 +767,7 @@ static enum bt_mesh_dfu_iter slot_del_cb(const struct bt_mesh_dfu_slot *slot, static int handle_fw_delete_all(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; fw_status_rsp(srv, ctx, bt_mesh_dfd_srv_fw_delete_all(srv), 0xffff, NULL, 0); @@ -925,7 +925,7 @@ const struct bt_mesh_blob_srv_cb _bt_mesh_dfd_srv_blob_cb = { static int dfd_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; srv->mod = mod; @@ -938,7 +938,7 @@ static int dfd_srv_init(const struct bt_mesh_model *mod) static void dfd_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfd_srv *srv = *(mod->user_data); + struct bt_mesh_dfd_srv *srv = mod->rt->user_data; dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE); srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; diff --git a/subsys/bluetooth/mesh/dfu_cli.c b/subsys/bluetooth/mesh/dfu_cli.c index 70b03f4e814..2345ef8e33b 100644 --- a/subsys/bluetooth/mesh/dfu_cli.c +++ b/subsys/bluetooth/mesh/dfu_cli.c @@ -702,7 +702,7 @@ static void cancelled(struct bt_mesh_blob_cli *b) static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = *(mod->user_data); + struct bt_mesh_dfu_cli *cli = mod->rt->user_data; enum bt_mesh_dfu_status status; enum bt_mesh_dfu_phase phase; struct bt_mesh_dfu_target *target; @@ -828,7 +828,7 @@ static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = *(mod->user_data); + struct bt_mesh_dfu_cli *cli = mod->rt->user_data; struct bt_mesh_dfu_target *target; enum bt_mesh_dfu_iter it = BT_MESH_DFU_ITER_CONTINUE; uint8_t img_cnt, idx; @@ -927,7 +927,7 @@ static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_metadata_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_cli *cli = *(mod->user_data); + struct bt_mesh_dfu_cli *cli = mod->rt->user_data; struct bt_mesh_dfu_metadata_status *rsp = cli->req.params; uint8_t hdr, idx; @@ -963,9 +963,9 @@ const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[] = { static int dfu_cli_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_cli *cli = *(mod->user_data); + struct bt_mesh_dfu_cli *cli = mod->rt->user_data; - if (*(mod->elem_idx) != 0) { + if (mod->rt->elem_idx != 0) { LOG_ERR("DFU update client must be instantiated on first elem"); return -EINVAL; } @@ -983,7 +983,7 @@ static int dfu_cli_init(const struct bt_mesh_model *mod) static void dfu_cli_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_cli *cli = *(mod->user_data); + struct bt_mesh_dfu_cli *cli = mod->rt->user_data; cli->req.type = REQ_NONE; cli->req.addr = BT_MESH_ADDR_UNASSIGNED; diff --git a/subsys/bluetooth/mesh/dfu_srv.c b/subsys/bluetooth/mesh/dfu_srv.c index edd61e6da40..f8e87e29da9 100644 --- a/subsys/bluetooth/mesh/dfu_srv.c +++ b/subsys/bluetooth/mesh/dfu_srv.c @@ -128,7 +128,7 @@ static void verify(struct bt_mesh_dfu_srv *srv) static int handle_info_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; uint8_t idx, limit; if (srv->update.phase == BT_MESH_DFU_PHASE_APPLYING) { @@ -190,7 +190,7 @@ static int handle_info_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_c static int handle_metadata_check(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; enum bt_mesh_dfu_status status; enum bt_mesh_dfu_effect effect; uint8_t idx; @@ -242,7 +242,7 @@ static void update_status_rsp(struct bt_mesh_dfu_srv *srv, static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; LOG_DBG(""); @@ -265,7 +265,7 @@ static inline bool is_active_update(struct bt_mesh_dfu_srv *srv, uint8_t idx, static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; const struct bt_mesh_blob_io *io; uint16_t timeout_base, meta_checksum; enum bt_mesh_dfu_status status; @@ -374,7 +374,7 @@ static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; if (srv->update.idx == UPDATE_IDX_NONE) { goto rsp; @@ -395,7 +395,7 @@ static int handle_cancel(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx static int handle_apply(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; static const struct bt_mesh_send_cb send_cb = { .start = apply_rsp_sending, .end = apply_rsp_sent, @@ -437,7 +437,7 @@ const struct bt_mesh_model_op _bt_mesh_dfu_srv_op[] = { static int dfu_srv_init(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; srv->mod = mod; srv->update.idx = UPDATE_IDX_NONE; @@ -459,7 +459,7 @@ static int dfu_srv_settings_set(const struct bt_mesh_model *mod, const char *nam size_t len_rd, settings_read_cb read_cb, void *cb_arg) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; ssize_t len; if (len_rd < sizeof(srv->update)) { @@ -486,7 +486,7 @@ static int dfu_srv_settings_set(const struct bt_mesh_model *mod, const char *nam static void dfu_srv_reset(const struct bt_mesh_model *mod) { - struct bt_mesh_dfu_srv *srv = *(mod->user_data); + struct bt_mesh_dfu_srv *srv = mod->rt->user_data; srv->update.phase = BT_MESH_DFU_PHASE_IDLE; erase_state(srv); diff --git a/subsys/bluetooth/mesh/health_cli.c b/subsys/bluetooth/mesh/health_cli.c index d34d869e243..16d2a79a53a 100644 --- a/subsys/bluetooth/mesh/health_cli.c +++ b/subsys/bluetooth/mesh/health_cli.c @@ -40,7 +40,7 @@ static int health_fault_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; struct health_fault_param *param; uint8_t test_id; uint16_t cid; @@ -93,7 +93,7 @@ static int health_current_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; uint8_t test_id; uint16_t cid; @@ -121,7 +121,7 @@ static int health_period_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; struct health_period_param *param; uint8_t divisor; @@ -155,7 +155,7 @@ static int health_attention_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; struct health_attention_param *param; uint8_t attention; @@ -404,7 +404,7 @@ void bt_mesh_health_cli_timeout_set(int32_t timeout) static int health_cli_init(const struct bt_mesh_model *model) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; LOG_DBG("primary %u", bt_mesh_model_in_primary(model)); @@ -425,7 +425,7 @@ static int health_cli_init(const struct bt_mesh_model *model) static void health_cli_reset(const struct bt_mesh_model *model) { - struct bt_mesh_health_cli *cli = *(model->user_data); + struct bt_mesh_health_cli *cli = model->rt->user_data; net_buf_simple_reset(cli->pub.msg); } diff --git a/subsys/bluetooth/mesh/health_srv.c b/subsys/bluetooth/mesh/health_srv.c index 4ae55266ebf..5292967d469 100644 --- a/subsys/bluetooth/mesh/health_srv.c +++ b/subsys/bluetooth/mesh/health_srv.c @@ -35,7 +35,7 @@ static void health_get_registered(const struct bt_mesh_model *mod, uint16_t company_id, struct net_buf_simple *msg) { - struct bt_mesh_health_srv *srv = *(mod->user_data); + struct bt_mesh_health_srv *srv = mod->rt->user_data; uint8_t *test_id; LOG_DBG("Company ID 0x%04x", company_id); @@ -67,7 +67,7 @@ static void health_get_registered(const struct bt_mesh_model *mod, static size_t health_get_current(const struct bt_mesh_model *mod, struct net_buf_simple *msg) { - struct bt_mesh_health_srv *srv = *(mod->user_data); + struct bt_mesh_health_srv *srv = mod->rt->user_data; const struct bt_mesh_comp *comp; uint8_t *test_id, *company_ptr; uint16_t company_id; @@ -129,7 +129,7 @@ static int health_fault_clear_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; uint16_t company_id; company_id = net_buf_simple_pull_le16(buf); @@ -148,7 +148,7 @@ static int health_fault_clear(const struct bt_mesh_model *model, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX); - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; uint16_t company_id; company_id = net_buf_simple_pull_le16(buf); @@ -177,7 +177,7 @@ static int health_fault_test_unrel(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; uint16_t company_id; uint8_t test_id; @@ -198,7 +198,7 @@ static int health_fault_test(const struct bt_mesh_model *model, struct net_buf_simple *buf) { NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX); - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; uint16_t company_id; uint8_t test_id; @@ -233,7 +233,7 @@ static int send_attention_status(const struct bt_mesh_model *model, { /* Needed size: opcode (2 bytes) + msg + MIC */ BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1); - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; uint8_t time; time = k_ticks_to_ms_floor32( @@ -420,7 +420,7 @@ static void attention_off(struct k_work *work) static int health_srv_init(const struct bt_mesh_model *model) { - struct bt_mesh_health_srv *srv = *(model->user_data); + struct bt_mesh_health_srv *srv = model->rt->user_data; if (!srv) { LOG_ERR("No Health Server context provided"); @@ -462,7 +462,7 @@ void bt_mesh_attention(const struct bt_mesh_model *model, uint8_t time) model = srv->model; } else { - srv = *(model->user_data); + srv = model->rt->user_data; } if ((time > 0) && srv->cb && srv->cb->attn_on) { diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index dc1152f415f..3aa688523f9 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -108,9 +108,9 @@ static int large_comp_data_cli_init(const struct bt_mesh_model *model) } model->keys[0] = BT_MESH_KEY_DEV_ANY; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; - cli = *(model->user_data); + cli = model->rt->user_data; cli->model = model; msg_timeout = 5000; diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 5d724b9f083..f47947b9b92 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -177,7 +177,7 @@ static int large_comp_data_srv_init(const struct bt_mesh_model *model) /* Large Composition Data Server model shall use the device key */ model->keys[0] = BT_MESH_KEY_DEV; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; srv.model = model; diff --git a/subsys/bluetooth/mesh/od_priv_proxy_cli.c b/subsys/bluetooth/mesh/od_priv_proxy_cli.c index f2844d2ecc6..bd4e796b8e2 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_cli.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_cli.c @@ -100,10 +100,10 @@ static int on_demand_proxy_cli_init(const struct bt_mesh_model *mod) return -EINVAL; } - cli = *(mod->user_data); + cli = mod->rt->user_data; cli->model = mod; mod->keys[0] = BT_MESH_KEY_DEV_ANY; - *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; msg_timeout = CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/od_priv_proxy_srv.c b/subsys/bluetooth/mesh/od_priv_proxy_srv.c index e671a80e9de..e54ed88fa0c 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_srv.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_srv.c @@ -98,7 +98,7 @@ static int od_priv_proxy_srv_init(const struct bt_mesh_model *mod) } mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; if (IS_ENABLED(CONFIG_BT_MESH_MODEL_EXTENSIONS)) { bt_mesh_model_extend(mod, priv_beacon_srv); diff --git a/subsys/bluetooth/mesh/priv_beacon_cli.c b/subsys/bluetooth/mesh/priv_beacon_cli.c index fd48ef0583b..0611aeb7705 100644 --- a/subsys/bluetooth/mesh/priv_beacon_cli.c +++ b/subsys/bluetooth/mesh/priv_beacon_cli.c @@ -141,11 +141,11 @@ static int priv_beacon_cli_init(const struct bt_mesh_model *model) return -EINVAL; } - cli = *(model->user_data); + cli = model->rt->user_data; cli->model = model; msg_timeout = 2 * MSEC_PER_SEC; model->keys[0] = BT_MESH_KEY_DEV_ANY; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); diff --git a/subsys/bluetooth/mesh/rpr_cli.c b/subsys/bluetooth/mesh/rpr_cli.c index 7a1dd493b87..cbb92e75b40 100644 --- a/subsys/bluetooth/mesh/rpr_cli.c +++ b/subsys/bluetooth/mesh/rpr_cli.c @@ -94,7 +94,7 @@ static int handle_extended_scan_report(const struct bt_mesh_model *mod, struct b struct net_buf_simple *buf) { struct bt_mesh_rpr_node srv = RPR_NODE(ctx); - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_unprov dev = { 0 }; enum bt_mesh_rpr_status status; bool found_dev = false; @@ -127,7 +127,7 @@ static int handle_link_report(const struct bt_mesh_model *mod, struct bt_mesh_ms struct net_buf_simple *buf) { struct bt_mesh_rpr_node srv = RPR_NODE(ctx); - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_link link; uint8_t reason = PROV_BEARER_LINK_STATUS_SUCCESS; @@ -164,7 +164,7 @@ static int handle_link_report(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_link_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_link *rsp; struct bt_mesh_rpr_link link; @@ -198,7 +198,7 @@ static int handle_link_status(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_pdu_outbound_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); void *cb_data; uint8_t num; @@ -229,7 +229,7 @@ static int handle_pdu_outbound_report(const struct bt_mesh_model *mod, struct bt static int handle_pdu_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct pb_remote_ctx cb_ctx = { cli, @@ -260,7 +260,7 @@ static int handle_pdu_report(const struct bt_mesh_model *mod, struct bt_mesh_msg static int handle_scan_caps_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_caps *caps; @@ -284,7 +284,7 @@ static int handle_scan_caps_status(const struct bt_mesh_model *mod, struct bt_me static int handle_scan_report(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); struct bt_mesh_rpr_unprov dev = { 0 }; @@ -316,7 +316,7 @@ static int handle_scan_report(const struct bt_mesh_model *mod, struct bt_mesh_ms static int handle_scan_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; struct bt_mesh_rpr_scan_status *status; struct bt_mesh_rpr_node srv = RPR_NODE(ctx); @@ -363,13 +363,13 @@ static void link_timeout(struct k_work *work) static int rpr_cli_init(const struct bt_mesh_model *mod) { - if (*(mod->elem_idx)) { + if (mod->rt->elem_idx) { LOG_ERR("Remote provisioning client must be initialized " "on first element"); return -EINVAL; } - struct bt_mesh_rpr_cli *cli = *(mod->user_data); + struct bt_mesh_rpr_cli *cli = mod->rt->user_data; cli->mod = mod; cli->link.time = LINK_TIMEOUT_SECONDS_DEFAULT; @@ -378,7 +378,7 @@ static int rpr_cli_init(const struct bt_mesh_model *mod) bt_mesh_msg_ack_ctx_init(&cli->prov_ack_ctx); k_work_init_delayable(&cli->link.timeout, link_timeout); mod->keys[0] = BT_MESH_KEY_DEV_ANY; - *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index e008aa0a8b1..9813842a367 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -1305,7 +1305,7 @@ static struct bt_le_scan_cb scan_cb = { static int rpr_srv_init(const struct bt_mesh_model *mod) { - if (*(mod->elem_idx) || srv.mod) { + if (mod->rt->elem_idx || srv.mod) { LOG_ERR("Remote provisioning server must be initialized " "on first element"); return -EINVAL; @@ -1320,7 +1320,7 @@ static int rpr_srv_init(const struct bt_mesh_model *mod) k_work_init(&srv.link.report, link_report_send_and_clear); bt_le_scan_cb_register(&scan_cb); mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/subsys/bluetooth/mesh/sar_cfg_cli.c b/subsys/bluetooth/mesh/sar_cfg_cli.c index aaf07451e1d..52239c95be4 100644 --- a/subsys/bluetooth/mesh/sar_cfg_cli.c +++ b/subsys/bluetooth/mesh/sar_cfg_cli.c @@ -94,17 +94,17 @@ static int bt_mesh_sar_cfg_cli_init(const struct bt_mesh_model *model) return -EINVAL; } - if (!*(model->user_data)) { + if (!model->rt->user_data) { LOG_ERR("No SAR Configuration Client context provided"); return -EINVAL; } - cli = *(model->user_data); + cli = model->rt->user_data; cli->model = model; cli->timeout = 2 * MSEC_PER_SEC; model->keys[0] = BT_MESH_KEY_DEV_ANY; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); @@ -115,7 +115,7 @@ static void bt_mesh_sar_cfg_cli_reset(const struct bt_mesh_model *model) { struct bt_mesh_sar_cfg_cli *model_cli; - model_cli = *(model->user_data); + model_cli = model->rt->user_data; bt_mesh_msg_ack_ctx_clear(&model_cli->ack_ctx); } diff --git a/subsys/bluetooth/mesh/sar_cfg_srv.c b/subsys/bluetooth/mesh/sar_cfg_srv.c index 59ec36907c5..2943ce02ddd 100644 --- a/subsys/bluetooth/mesh/sar_cfg_srv.c +++ b/subsys/bluetooth/mesh/sar_cfg_srv.c @@ -155,7 +155,7 @@ static int sar_cfg_srv_init(const struct bt_mesh_model *model) * device-key is allowed to access this model. */ model->keys[0] = BT_MESH_KEY_DEV_LOCAL; - *(model->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } diff --git a/subsys/bluetooth/mesh/shell/blob.c b/subsys/bluetooth/mesh/shell/blob.c index ed0f4fbd458..a6888da4270 100644 --- a/subsys/bluetooth/mesh/shell/blob.c +++ b/subsys/bluetooth/mesh/shell/blob.c @@ -351,7 +351,7 @@ static int cmd_tx(const struct shell *sh, size_t argc, char *argv[]) "pull", blob_cli_xfer.xfer.size, group); - err = bt_mesh_blob_cli_send((struct bt_mesh_blob_cli *)*(mod_cli->user_data), + err = bt_mesh_blob_cli_send((struct bt_mesh_blob_cli *)mod_cli->rt->user_data, &blob_cli_xfer.inputs, &blob_cli_xfer.xfer, bt_mesh_shell_blob_io); if (err) { @@ -421,7 +421,7 @@ static int cmd_caps(const struct shell *sh, size_t argc, char *argv[]) blob_cli_inputs_prepare(group); - err = bt_mesh_blob_cli_caps_get((struct bt_mesh_blob_cli *)*(mod_cli->user_data), + err = bt_mesh_blob_cli_caps_get((struct bt_mesh_blob_cli *)mod_cli->rt->user_data, &blob_cli_xfer.inputs); if (err) { shell_print(sh, "Boundary check start failed (err: %d)", err); @@ -438,7 +438,7 @@ static int cmd_tx_cancel(const struct shell *sh, size_t argc, } shell_print(sh, "Cancelling transfer"); - bt_mesh_blob_cli_cancel((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); + bt_mesh_blob_cli_cancel((struct bt_mesh_blob_cli *)mod_cli->rt->user_data); return 0; } @@ -465,7 +465,7 @@ static int cmd_tx_get(const struct shell *sh, size_t argc, char *argv[]) blob_cli_inputs_prepare(group); - err = bt_mesh_blob_cli_xfer_progress_get((struct bt_mesh_blob_cli *)*(mod_cli->user_data), + err = bt_mesh_blob_cli_xfer_progress_get((struct bt_mesh_blob_cli *)mod_cli->rt->user_data, &blob_cli_xfer.inputs); if (err) { shell_print(sh, "ERR %d", err); @@ -482,7 +482,7 @@ static int cmd_tx_suspend(const struct shell *sh, size_t argc, } shell_print(sh, "Suspending transfer"); - bt_mesh_blob_cli_suspend((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); + bt_mesh_blob_cli_suspend((struct bt_mesh_blob_cli *)mod_cli->rt->user_data); return 0; } @@ -494,7 +494,7 @@ static int cmd_tx_resume(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Resuming transfer"); - bt_mesh_blob_cli_resume((struct bt_mesh_blob_cli *)*(mod_cli->user_data)); + bt_mesh_blob_cli_resume((struct bt_mesh_blob_cli *)mod_cli->rt->user_data); return 0; } @@ -530,7 +530,7 @@ static int cmd_rx(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Receive BLOB 0x%x", id); - err = bt_mesh_blob_srv_recv((struct bt_mesh_blob_srv *)*(mod_srv->user_data), + err = bt_mesh_blob_srv_recv((struct bt_mesh_blob_srv *)mod_srv->rt->user_data, id, bt_mesh_shell_blob_io, BT_MESH_TTL_MAX, timeout_base); if (err) { shell_print(sh, "BLOB RX setup failed (%d)", err); @@ -548,7 +548,7 @@ static int cmd_rx_cancel(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Cancelling BLOB rx"); - err = bt_mesh_blob_srv_cancel((struct bt_mesh_blob_srv *)*(mod_srv->user_data)); + err = bt_mesh_blob_srv_cancel((struct bt_mesh_blob_srv *)mod_srv->rt->user_data); if (err) { shell_print(sh, "BLOB cancel failed (%d)", err); } diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index 464a5340342..4b3d4970282 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -70,7 +70,7 @@ static int cmd_dfd_receivers_add(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; if (bt_mesh_dfu_cli_is_busy(&dfd_srv->dfu)) { print_receivers_status(sh, dfd_srv, @@ -122,7 +122,7 @@ static int cmd_dfd_receivers_delete_all(const struct shell *sh, size_t argc, cha return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_receivers_delete_all( dfd_srv); @@ -142,7 +142,7 @@ static int cmd_dfd_receivers_get(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; int err = 0; uint16_t first = shell_strtoul(argv[1], 0, &err); @@ -197,7 +197,7 @@ static int cmd_dfd_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; print_dfd_status(sh, dfd_srv, BT_MESH_DFD_SUCCESS); @@ -210,7 +210,7 @@ static int cmd_dfd_start(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; struct bt_mesh_dfd_start_params params; int err = 0; @@ -267,7 +267,7 @@ static int cmd_dfd_suspend(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_suspend(dfd_srv); @@ -285,7 +285,7 @@ static int cmd_dfd_cancel(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_cancel(dfd_srv, NULL); @@ -303,7 +303,7 @@ static int cmd_dfd_apply(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_apply(dfd_srv); @@ -364,7 +364,7 @@ static int cmd_dfd_fw_delete(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; uint8_t fwid_buf[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; size_t hexlen = strlen(argv[1]); @@ -394,7 +394,7 @@ static int cmd_dfd_fw_delete_all(const struct shell *sh, size_t argc, char *argv return -ENODEV; } - struct bt_mesh_dfd_srv *dfd_srv = *(mod->user_data); + struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data; enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_fw_delete_all(dfd_srv); diff --git a/subsys/bluetooth/mesh/shell/dfu.c b/subsys/bluetooth/mesh/shell/dfu.c index 22c60dc17c8..6b7df4a8bd4 100644 --- a/subsys/bluetooth/mesh/shell/dfu.c +++ b/subsys/bluetooth/mesh/shell/dfu.c @@ -587,7 +587,7 @@ static int cmd_dfu_target_state(const struct shell *sh, size_t argc, char *argv[ return -ENODEV; } - err = bt_mesh_dfu_cli_status_get((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), + err = bt_mesh_dfu_cli_status_get((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data, &ctx, &rsp); if (err) { shell_print(sh, "Failed getting target status (err: %d)", @@ -654,7 +654,7 @@ static int cmd_dfu_target_imgs(const struct shell *sh, size_t argc, char *argv[] shell_print(sh, "Requesting DFU images in 0x%04x", bt_mesh_shell_target_ctx.dst); - err = bt_mesh_dfu_cli_imgs_get((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), + err = bt_mesh_dfu_cli_imgs_get((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data, &ctx, dfu_img_cb, NULL, img_cnt); if (err) { shell_print(sh, "Request failed (err: %d)", err); @@ -694,7 +694,7 @@ static int cmd_dfu_target_check(const struct shell *sh, size_t argc, char *argv[ return 0; } - err = bt_mesh_dfu_cli_metadata_check((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), + err = bt_mesh_dfu_cli_metadata_check((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data, &ctx, img_idx, slot, &rsp); if (err) { shell_print(sh, "Metadata check failed. err: %d", err); @@ -765,7 +765,7 @@ static int cmd_dfu_send(const struct shell *sh, size_t argc, char *argv[]) dfu_tx.inputs.app_idx = bt_mesh_shell_target_ctx.app_idx; dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT; - err = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), + err = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data, &dfu_tx.inputs, bt_mesh_shell_blob_io, &xfer); if (err) { shell_print(sh, "Failed (err: %d)", err); @@ -800,7 +800,7 @@ static int cmd_dfu_tx_cancel(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Cancelling DFU"); } - err = bt_mesh_dfu_cli_cancel((struct bt_mesh_dfu_cli *)*(mod_cli->user_data), + err = bt_mesh_dfu_cli_cancel((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data, (argc == 2) ? &ctx : NULL); if (err) { shell_print(sh, "Failed (err: %d)", err); @@ -819,7 +819,7 @@ static int cmd_dfu_apply(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Applying DFU"); - err = bt_mesh_dfu_cli_apply((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); + err = bt_mesh_dfu_cli_apply((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -837,7 +837,7 @@ static int cmd_dfu_confirm(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Confirming DFU"); - err = bt_mesh_dfu_cli_confirm((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); + err = bt_mesh_dfu_cli_confirm((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -855,7 +855,7 @@ static int cmd_dfu_suspend(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Suspending DFU"); - err = bt_mesh_dfu_cli_suspend((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); + err = bt_mesh_dfu_cli_suspend((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -873,7 +873,7 @@ static int cmd_dfu_resume(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Resuming DFU"); - err = bt_mesh_dfu_cli_resume((struct bt_mesh_dfu_cli *)*(mod_cli->user_data)); + err = bt_mesh_dfu_cli_resume((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data); if (err) { shell_print(sh, "Failed (err: %d)", err); } @@ -888,7 +888,7 @@ static int cmd_dfu_tx_progress(const struct shell *sh, size_t argc, char *argv[] } shell_print(sh, "DFU progress: %u %%", - bt_mesh_dfu_cli_progress((struct bt_mesh_dfu_cli *)*(mod_cli->user_data))); + bt_mesh_dfu_cli_progress((struct bt_mesh_dfu_cli *)mod_cli->rt->user_data)); return 0; } @@ -904,7 +904,7 @@ static int cmd_dfu_applied(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)*(mod_srv->user_data)); + bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)mod_srv->rt->user_data); return 0; } @@ -914,7 +914,7 @@ static int cmd_dfu_rx_cancel(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)*(mod_srv->user_data)); + bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)mod_srv->rt->user_data); return 0; } @@ -925,7 +925,7 @@ static int cmd_dfu_rx_progress(const struct shell *sh, size_t argc, char *argv[] } shell_print(sh, "DFU progress: %u %%", - bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)*(mod_srv->user_data))); + bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)mod_srv->rt->user_data)); return 0; } diff --git a/subsys/bluetooth/mesh/shell/health.c b/subsys/bluetooth/mesh/shell/health.c index a0ca150ae15..21480c6a66e 100644 --- a/subsys/bluetooth/mesh/shell/health.c +++ b/subsys/bluetooth/mesh/shell/health.c @@ -40,7 +40,7 @@ static int cmd_fault_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t faults[32]; @@ -74,7 +74,7 @@ static int fault_clear(const struct shell *sh, size_t argc, char *argv[], bool a return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t test_id; @@ -126,7 +126,7 @@ static int fault_test(const struct shell *sh, size_t argc, char *argv[], bool ac return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t test_id; @@ -179,7 +179,7 @@ static int cmd_period_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t divisor; @@ -201,7 +201,7 @@ static int period_set(const struct shell *sh, size_t argc, char *argv[], bool ac return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t divisor; @@ -251,7 +251,7 @@ static int cmd_attention_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t attention; @@ -273,7 +273,7 @@ static int attention_set(const struct shell *sh, size_t argc, char *argv[], bool return -ENODEV; } - struct bt_mesh_health_cli *cli = *(mod->user_data); + struct bt_mesh_health_cli *cli = mod->rt->user_data; struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(bt_mesh_shell_target_ctx.app_idx, bt_mesh_shell_target_ctx.dst); uint8_t attention; diff --git a/subsys/bluetooth/mesh/shell/rpr.c b/subsys/bluetooth/mesh/shell/rpr.c index 1ddb11f497d..870fc7c5d37 100644 --- a/subsys/bluetooth/mesh/shell/rpr.c +++ b/subsys/bluetooth/mesh/shell/rpr.c @@ -108,7 +108,7 @@ static int cmd_scan(const struct shell *sh, size_t argc, char *argv[]) hex2bin(argv[2], strlen(argv[2]), uuid, 16); } - err = bt_mesh_rpr_scan_start((struct bt_mesh_rpr_cli *)*(mod->user_data), + err = bt_mesh_rpr_scan_start((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, argc > 2 ? uuid : NULL, timeout, BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &rsp); if (err) { @@ -153,7 +153,7 @@ static int cmd_scan_ext(const struct shell *sh, size_t argc, char *argv[]) return err; } - err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)*(mod->user_data), + err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, uuid, timeout, ad_types, (argc - 3)); if (err) { @@ -189,7 +189,7 @@ static int cmd_scan_srv(const struct shell *sh, size_t argc, char *argv[]) return err; } - err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)*(mod->user_data), + err = bt_mesh_rpr_scan_start_ext((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, NULL, 0, ad_types, (argc - 1)); if (err) { shell_print(sh, "Scan start failed: %d", err); @@ -213,7 +213,7 @@ static int cmd_scan_caps(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_caps_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &caps); + err = bt_mesh_rpr_scan_caps_get((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, &caps); if (err) { shell_print(sh, "Scan capabilities get failed: %d", err); return err; @@ -241,7 +241,7 @@ static int cmd_scan_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); + err = bt_mesh_rpr_scan_get((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, &rsp); if (err) { shell_print(sh, "Scan get failed: %d", err); return err; @@ -269,7 +269,7 @@ static int cmd_scan_stop(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_scan_stop((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); + err = bt_mesh_rpr_scan_stop((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, &rsp); if (err || rsp.status) { shell_print(sh, "Scan stop failed: %d %u", err, rsp.status); return err; @@ -294,7 +294,7 @@ static int cmd_link_get(const struct shell *sh, size_t argc, char *argv[]) return -ENODEV; } - err = bt_mesh_rpr_link_get((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); + err = bt_mesh_rpr_link_get((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, &rsp); if (err) { shell_print(sh, "Link get failed: %d %u", err, rsp.status); return err; @@ -316,7 +316,7 @@ static int cmd_link_close(const struct shell *sh, size_t argc, char *argv[]) }; int err; - err = bt_mesh_rpr_link_close((struct bt_mesh_rpr_cli *)*(mod->user_data), &srv, &rsp); + err = bt_mesh_rpr_link_close((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, &rsp); if (err) { shell_print(sh, "Link close failed: %d %u", err, rsp.status); return err; @@ -355,7 +355,7 @@ static int cmd_provision_remote(const struct shell *sh, size_t argc, char *argv[ return err; } - err = bt_mesh_provision_remote((struct bt_mesh_rpr_cli *)*(mod->user_data), + err = bt_mesh_provision_remote((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, uuid, net_idx, addr); if (err) { shell_print(sh, "Prov remote start failed: %d", err); @@ -396,7 +396,7 @@ static int cmd_reprovision_remote(const struct shell *sh, size_t argc, char *arg return err; } - err = bt_mesh_reprovision_remote((struct bt_mesh_rpr_cli *)*(mod->user_data), + err = bt_mesh_reprovision_remote((struct bt_mesh_rpr_cli *)mod->rt->user_data, &srv, addr, composition_changed); if (err) { shell_print(sh, "Reprovisioning failed: %d", err); diff --git a/subsys/bluetooth/mesh/shell/utils.c b/subsys/bluetooth/mesh/shell/utils.c index 1d8ab79951d..1ccb0e25212 100644 --- a/subsys/bluetooth/mesh/shell/utils.c +++ b/subsys/bluetooth/mesh/shell/utils.c @@ -60,7 +60,7 @@ int bt_mesh_shell_mdl_print_all(const struct shell *sh, uint16_t mod_id) if (mod) { shell_print(sh, "Client model instance found at addr 0x%.4X. Element index: %d", - comp->elem[i].addr, *(mod->elem_idx)); + comp->elem[i].addr, mod->rt->elem_idx); } } diff --git a/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c b/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c index 05457eff338..dd809b59996 100644 --- a/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c +++ b/subsys/bluetooth/mesh/sol_pdu_rpl_cli.c @@ -169,7 +169,7 @@ static int sol_pdu_rpl_cli_init(const struct bt_mesh_model *mod) msg_timeout = CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT; - cli = *(mod->user_data); + cli = mod->rt->user_data; cli->model = mod; bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); return 0; diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index dacc30c741e..14ee6b03428 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -261,7 +261,7 @@ static int model3_init(const struct bt_mesh_model *model) ASSERT_OK(bt_mesh_model_extend(model, model - 2)); ASSERT_OK(bt_mesh_model_extend(model, model - 1)); - if (*(model->elem_idx) == 1) { + if (model->rt->elem_idx == 1) { ASSERT_OK(bt_mesh_model_extend(model, &models[4])); } diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index 7e1d9ffca3c..337edaddc54 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -31,19 +31,10 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); LCD_STATUS_FIELDS_LEN - \ BT_MESH_MIC_SHORT) /* 378 bytes */ -#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS -#define BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .next = (const struct bt_mesh_model *[]){ NULL }, -#else -#define BT_MESH_MODEL_NEXT_UNASSIGNED() -#endif - #define TEST_MODEL_CNT_CB(_dummy_op, _metadata) \ { \ .id = 0x1234, \ - .elem_idx = (uint8_t []) { 0 }, \ - .mod_idx = (uint8_t []) { 0 }, \ - .flags = (uint16_t []) { 0 }, \ + BT_MESH_MODEL_RUNTIME_INIT(NULL) \ .pub = NULL, \ .keys = NULL, \ .keys_cnt = 0, \ @@ -51,8 +42,6 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); .groups_cnt = 0, \ .op = _dummy_op, \ .cb = NULL, \ - BT_MESH_MODEL_NEXT_UNASSIGNED() \ - .user_data = (void *[]){ NULL }, \ .metadata = _metadata, \ } diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 80eb9ff38cd..63b8d89416c 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -171,7 +171,7 @@ static const struct bt_mesh_model_op model_rpr_op1[] = { static int mock_model_init(const struct bt_mesh_model *mod) { mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; - *(mod->flags) |= BT_MESH_MOD_DEVKEY_ONLY; + mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY; return 0; } From d896213ef4b98a6afba5cdb94834713f554e1b84 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Thu, 16 Nov 2023 12:11:21 +0800 Subject: [PATCH 3744/4498] doc/release: Add incompatible change for bt mesh https://github.com/zephyrproject-rtos/zephyr/issues/57267 Signed-off-by: Lingao Meng --- doc/releases/migration-guide-3.6.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 77a0c1b76f7..dfd3fdb3cf6 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -76,6 +76,10 @@ Bluetooth cleared on :c:func:`bt_enable`. Callbacks can now be registered before the initial call to :c:func:`bt_enable`, and should no longer be re-registered after a :c:func:`bt_disable` :c:func:`bt_enable` cycle. +* The Bluetooth Mesh ``model`` declaration has been changed to add prefix ``const``. + The ``model->user_data``, ``model->elem_idx`` and ``model->mod_idx`` field has been changed to + the new runtime structure, replaced by ``model->rt->user_data``, ``model->rt->elem_idx`` and + ``model->rt->mod_idx`` separately. LoRaWAN ======= From b911694f9bedd648664245b90c9fce8c21e868de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Sun, 12 Nov 2023 14:30:44 +0700 Subject: [PATCH 3745/4498] dts: pinctrl: kinetis: make slew-rate optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting slew-rate property is not supported on Kinetis KE series and the value will not have effect, so this property should not be required. We are also planning to reuse the Kinetis pin control binding and associated driver for NXP S32K1xx devices, which doesn't support setting the slew-rate rate as well. Signed-off-by: Manuel Argüelles --- dts/bindings/pinctrl/nxp,kinetis-pinctrl.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dts/bindings/pinctrl/nxp,kinetis-pinctrl.yaml b/dts/bindings/pinctrl/nxp,kinetis-pinctrl.yaml index ccc36d4f167..c5b2f5d6020 100644 --- a/dts/bindings/pinctrl/nxp,kinetis-pinctrl.yaml +++ b/dts/bindings/pinctrl/nxp,kinetis-pinctrl.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NXP +# Copyright (c) 2022-2023, NXP # SPDX-License-Identifier: Apache-2.0 description: | @@ -63,7 +63,6 @@ child-binding: 0 DSE_0- low drive strength when pin is configured as output 1 DSE_1- high drive strength when pin is configured as output slew-rate: - required: true type: string enum: - "fast" From de4fc8bf75aabf023f1b5831cd92102c1d17e61e Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Wed, 8 Nov 2023 22:11:49 +0200 Subject: [PATCH 3746/4498] boards: arm: CY8CPROTO-062-4343W: update bias for i2c Update pin control bias mode for i2c3 pins: &p6_0_scb3_i2c_scl { drive-open-drain; input-enable; }; &p6_1_scb3_i2c_sda { drive-open-drain; input-enable; }; Signed-off-by: Nazar Palamar --- .../cy8cproto_062_4343w-pinctrl.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi index 14202d8fbcd..fcf6655e5d6 100644 --- a/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi +++ b/boards/arm/cy8cproto_062_4343w/cy8cproto_062_4343w-pinctrl.dtsi @@ -29,6 +29,17 @@ input-enable; }; +/* Configure pin control bias mode for i2c3 pins */ +&p6_0_scb3_i2c_scl { + drive-open-drain; + input-enable; +}; + +&p6_1_scb3_i2c_sda { + drive-open-drain; + input-enable; +}; + &pinctrl { /* Configure pin control bias mode for SDIO */ p2_5_sdio_clk: p2_5_sdio_clk { From 47ad8f047cd61e9cacbdd394f18ed31472b7aa52 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Wed, 8 Nov 2023 22:15:12 +0200 Subject: [PATCH 3747/4498] dts: binding: i2c: Update description for Infineon CAT1 i2c driver - added example of usage Infineon CAT1 i2c driver - added note that pinctrl nodes need to be configured as open-drain and input-enable. Signed-off-by: Nazar Palamar --- dts/bindings/i2c/infineon,cat1-i2c.yaml | 37 ++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/dts/bindings/i2c/infineon,cat1-i2c.yaml b/dts/bindings/i2c/infineon,cat1-i2c.yaml index fa7ca1b8f4a..ef287709b76 100644 --- a/dts/bindings/i2c/infineon,cat1-i2c.yaml +++ b/dts/bindings/i2c/infineon,cat1-i2c.yaml @@ -3,7 +3,42 @@ # # SPDX-License-Identifier: Apache-2.0 -description: Infineon CAT1 I2C +description: | + Infineon CAT1 I2C driver + + This driver configures the SCB as an I2C device. + + Example devicetree configuration with vl53l0x Time-of-Flight (ToF) + ranging sensor connected on the bus: + + i2c3: &scb3 { + compatible = "infineon,cat1-i2c"; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&p6_0_scb3_i2c_scl &p6_1_scb3_i2c_sda>; + pinctrl-names = "default"; + + vl53l0x@29 { + compatible = "st,vl53l0x"; + reg = <0x29>; + }; + }; + + The pinctrl nodes need to be configured as open-drain and + input-enable: + + &p6_0_scb3_i2c_scl { + drive-open-drain; + input-enable; + }; + + &p6_1_scb3_i2c_sda { + drive-open-drain; + input-enable; + }; compatible: "infineon,cat1-i2c" From 3b5fd5fc929bdc958c1acd435726d28c0ecf3f8e Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 10 Oct 2023 14:26:32 +0200 Subject: [PATCH 3748/4498] boards: arm: LPC55Sx6: Enable LinkServer and PyOCD runners. Enable LinkerServer and PyOCD runners for LPC55Sx6 EVKs, where it is supported. It was tested on a real HW. Signed-off-by: Andrej Butok --- boards/arm/lpcxpresso55s06/board.cmake | 3 +++ boards/arm/lpcxpresso55s16/board.cmake | 5 +++++ boards/arm/lpcxpresso55s36/board.cmake | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/boards/arm/lpcxpresso55s06/board.cmake b/boards/arm/lpcxpresso55s06/board.cmake index 32f7be75b33..305ed963f21 100644 --- a/boards/arm/lpcxpresso55s06/board.cmake +++ b/boards/arm/lpcxpresso55s06/board.cmake @@ -1,9 +1,12 @@ # # Copyright (c) 2022 metraTec +# Copyright 2023 NXP # # SPDX-License-Identifier: Apache-2.0 # +board_runner_args(linkserver "--device=LPC55S06:LPCXpresso55S06") board_runner_args(jlink "--device=LPC55S06" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/lpcxpresso55s16/board.cmake b/boards/arm/lpcxpresso55s16/board.cmake index 7daaf7d25c1..45ca5dcfe1c 100644 --- a/boards/arm/lpcxpresso55s16/board.cmake +++ b/boards/arm/lpcxpresso55s16/board.cmake @@ -1,9 +1,14 @@ # # Copyright (c) 2020 Henrik Brix Andersen +# Copyright 2023 NXP # # SPDX-License-Identifier: Apache-2.0 # +board_runner_args(linkserver "--device=LPC55S16:LPCXpresso55S16") board_runner_args(jlink "--device=LPC55S16" "--reset-after-load") +board_runner_args(pyocd "--target=lpc55s16") +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/lpcxpresso55s36/board.cmake b/boards/arm/lpcxpresso55s36/board.cmake index 2aceb6ca675..b1e16906bd5 100644 --- a/boards/arm/lpcxpresso55s36/board.cmake +++ b/boards/arm/lpcxpresso55s36/board.cmake @@ -1,11 +1,13 @@ # -# Copyright 2022 NXP +# Copyright 2022-2023 NXP # # SPDX-License-Identifier: Apache-2.0 # +board_runner_args(linkserver "--device=LPC55S36:LPCXpresso55S36") board_runner_args(jlink "--device=LPC55S36" "--reset-after-load") board_runner_args(pyocd "--target=lpc55s36") +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) From faf8bb0696931eccb1ed46baff2e663ab7099e19 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 09:58:43 +0100 Subject: [PATCH 3749/4498] boards nrf5340_bsim doc: IPC and MUTEX peripherals are now supported Update this board docs to reflect that these 2 peripherals are now supported. Signed-off-by: Alberto Escolar Piedras --- boards/posix/nrf_bsim/doc/nrf5340bsim.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst index 36dbf1d2adc..f2ece408e08 100644 --- a/boards/posix/nrf_bsim/doc/nrf5340bsim.rst +++ b/boards/posix/nrf_bsim/doc/nrf5340bsim.rst @@ -28,29 +28,26 @@ core on the simulated nRF5340 SOC. These boards include models of some of the nRF5340 SOC peripherals: -* Radio -* Timers * AAR (Accelerated Address Resolver) * AES CCM & AES ECB encryption HW * CLOCK (Clock control) * DPPI (Distributed Programmable Peripheral Interconnect) * EGU (Event Generator Unit) * FICR (Factory Information Configuration Registers) +* IPC (Interprocessor communication) +* MUTEX (Mutual exclusive peripheral) * NVMC (Non-Volatile Memory Controller / Flash) +* RADIO * RNG (Random Number Generator) * RTC (Real Time Counter) * TEMP (Temperature sensor) +* TIMER * UICR (User Information Configuration Registers) and will use the same drivers as the nrf5340dk targets for these. For more information on what is modelled to which level of detail, check the `HW models implementation status`_. -.. note:: - - The IPC and MUTEX peripherals are not yet present in these models. Therefore communication - between the cores using Zephyr's IPC driver is not yet possible. - Note that unlike a real nrf5340 device, the nrf5340bsim boards have unlimited RAM and flash for code. From ceba001bad770694e8915f981daf232aa0eb7d62 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 15:18:13 +0100 Subject: [PATCH 3750/4498] bsim boards doc: Update general bsim boards documentation Polish and correct the documentation to reflect the use of the native_simulator, and the fact that we have now more than one bsim board in tree. Signed-off-by: Alberto Escolar Piedras --- boards/posix/doc/bsim_boards_design.rst | 82 ++-- boards/posix/doc/layering_natsim.svg | 582 ++++++++++++++++++++++++ 2 files changed, 631 insertions(+), 33 deletions(-) create mode 100644 boards/posix/doc/layering_natsim.svg diff --git a/boards/posix/doc/bsim_boards_design.rst b/boards/posix/doc/bsim_boards_design.rst index bb510f58351..9b6bcfc0bca 100644 --- a/boards/posix/doc/bsim_boards_design.rst +++ b/boards/posix/doc/bsim_boards_design.rst @@ -3,21 +3,27 @@ Bsim boards ########### -This page covers the design, architecture and rationale, of the -:ref:`nrf52_bsim`, :ref:`nrf5340bsim` and other similar bsim boards. -Particular details on the nRF52 and nRF5340 simulation boards, including how to use them, -can be found in their respective documentation. -These boards are postfixed with `_bsim` as they use BabbleSim_ -(shortened bsim). +**Available bsim boards** -These boards use the `native simulator`_ and the :ref:`POSIX architecture` to build -and execute the embedded code natively on Linux. +* :ref:`Simulated nRF52833 (nrf52_bsim)` +* :ref:`Simulated nRF5340 (nrf5340bsim)` -.. contents:: +.. contents:: Table of contents :depth: 2 :backlinks: entry :local: +This page covers the design, architecture and rationale, of the +nrf5x_bsim boards and other similar bsim boards. +These boards are postfixed with `_bsim` as they use BabbleSim_ +(shortened bsim), to simulate the radio environment. +These boards use the `native simulator`_ and the :ref:`POSIX architecture` to build +and execute the embedded code natively on Linux. + +Particular details on the :ref:`nRF52` and :ref:`nRF5340` +simulation boards, including how to use them, +can be found in their respective documentation. + .. _BabbleSim: https://BabbleSim.github.io @@ -55,6 +61,9 @@ without the need for real HW, and in a deterministic/reproducible fashion. Unlike :ref:`native_sim `, bsim boards do not interact directly with any host peripherals, and their execution is independent of the host load, or timing. +These boards are also designed to be used as prototyping and development environments, +which can help developing applications or communication stacks. + .. _bsim_boards_tests: Different types of tests and how the bsim boards relate to them @@ -120,35 +129,37 @@ Layering: Zephyr's arch, soc and board layers The basic architecture layering of these boards is as follows: +- The `native simulator`_ runner is used to execute the code in your host. - The architecture, SOC and board components of Zephyr are replaced with simulation specific ones. - The architecture (arch) is the Zephyr :ref:`POSIX architecture` layer. - The SOC layer is the soc_inf layer. And the board layer is dependent on + The SOC layer is `inf_clock`. And the board layer is dependent on the specific device we are simulating. - The POSIX architecture provides an adaptation from the Zephyr arch API - (which handles mostly the thread context switching) to the Linux kernel. + (which handles mostly the thread context switching) to the native simulator + CPU thread emulation. See :ref:`POSIX arch architecture` -- The soc_inf layer provides the overall CPU "simulation" and the handling of - control between the "CPU simulation" (Zephyr threads) and the HW models thread - ( See `Threading`_ ) +- The SOC `inf_clock` layer provides an adaptation to the native simulator CPU "simulation" + and the handling of control between the "CPU simulation" (Zephyr threads) and the + HW models thread ( See `Threading`_ ). - The board layer provides all SOC/ IC specific content, including - (or linking to) HW models, IRQ handling, busy wait API - (see :ref:`posix_busy_wait`), and Zephyr's printk backend. + selecting the HW models which are built in the native simulator runner context, IRQ handling, + busy wait API (see :ref:`posix_busy_wait`), and Zephyr's printk backend. Note that in a normal Zephyr target interrupt handling and a custom busy wait would be provided by the SOC layer, but abusing Zephyr's layering, and for the - soc_inf layer to be generic, these were delegated to the board. + `inf_clock` layer to be generic, these were delegated to the board. The board layer provides other test specific functionality like bs_tests hooks, trace control, etc, and - by means of the native simulator, provides the :c:func:`main` entry point for the linux + by means of the native simulator, provides the :c:func:`main` entry point for the Linux program, command line argument handling, and the overall time scheduling of the simulated device. - Note that the POSIX arch and soc_inf expect a set of APIs being provided by + Note that the POSIX arch and `inf_clock` soc expect a set of APIs being provided by the board. This includes the busy wait API, a basic tracing API, the interrupt controller and interrupt handling APIs, :c:func:`posix_exit`, - and :c:func:`posix_get_hw_cycle` (see posix_board_if.h and posix_soc_if.h ). + and :c:func:`posix_get_hw_cycle` (see :file:`posix_board_if.h` and :file:`posix_soc_if.h`). -.. figure:: layering.svg +.. figure:: layering_natsim.svg :align: center :alt: Zephyr layering in native & bsim builds :figclass: align-center @@ -161,7 +172,7 @@ Important limitations All native and bsim boards share the same set of :ref:`important limitations which` -are inherited from the POSIX arch and soc_inf design. +are inherited from the POSIX arch and `inf_clock` design. .. _Threading: @@ -228,7 +239,7 @@ can use to exchange data. About using Zephyr APIs ======================= -Note that even though bsim board code is linked with the Zephyr kernel, +Note that even though part of the bsim board code is linked with the Zephyr kernel, one should in general not call Zephyr APIs from the board code itself. In particular, one should not call Zephyr APIs from the original/HW models thread as the Zephyr code would be called from the wrong context, @@ -242,13 +253,14 @@ which relies on the bs_trace API. Instead, for tracing the bs_trace API should be used directly. The same applies to other Zephyr APIs, including the entropy API, etc. -posix_print backend -=================== +posix_print and nsi_print backends +================================== + +The bsim board provides a backend for the ``posix_print`` API which is expected by the posix +ARCH and `inf_clock` code, and for the ``nsi_print`` API expected by the native simulator. -The bsim board provides a backend for the posix_print API which is expected by the posix ARCH -and soc inf (POSIX) code. -It simply routes the printk strings to the bs_trace bsim API. -Any message printed to the posix_print API, which is also the default printk backend, +These simply route this API calls into the ``bs_trace`` bsim API. +Any message printed to these APIs, and by extension by default to Zephyr's ``printk``, will be printed to the console (stdout) together with all other device messages. .. _bsim_boards_bs_tests: @@ -271,12 +283,12 @@ callbacks are assigned to the respective hooks. There is a set of one time hooks at different levels of initialization of the HW and Zephyr OS, a hook to process possible command line arguments, and, a hook that can be used to sniff or capture interrupts. -bs_tests also provides a hook which will be called from the embedded application +`bs_tests` also provides a hook which will be called from the embedded application :c:func:`main`, but this will only work if the main application supports it, that is, if the main app is a version for simulation which calls :c:func:`bst_main` when running in the bsim board. -Apart from these hooks, the bs_tests system provides facilities to build a +Apart from these hooks, the `bs_tests` system provides facilities to build a dedicated test "task". This will be executed in the HW models thread context, but will have access to all SW variables. This task will be driven with a special timer which can be configured to produce either periodic or one time @@ -286,12 +298,16 @@ at specific points in time. This can be combined with Babblesim's tb_defs macros to build quite complex test tasks which can wait for a given amount of time, for conditions to be fulfilled, etc. -Note: When writing the tests with bs_tests one needs to be aware that other +Note when writing the tests with `bs_tests` one needs to be aware that other bs tests will probably be built with the same application, and that therefore the tests should not be registering initialization or callback functions using NATIVE_TASKS or Zephyr's PRE/POST kernel driver initialization APIs as this will execute even if the test is not selected. -Instead the equivalent bs_tests provided hooks should be used. +Instead the equivalent `bs_tests` provided hooks should be used. + +Note also that, for AMP targets like the :ref:`nrf5340bsim `, each embedded MCU has +its own separate `bs_tests` built with that MCU. You can select if and what test is used +for each MCU separatedly with the command line options. Command line argument parsing ============================= diff --git a/boards/posix/doc/layering_natsim.svg b/boards/posix/doc/layering_natsim.svg new file mode 100644 index 00000000000..535ad934e5e --- /dev/null +++ b/boards/posix/doc/layering_natsim.svg @@ -0,0 +1,582 @@ + + + + + + + + + + + + + Sheet.1 + CPU/SOC + + + + CPU/SOC + Sheet.2 + HW peripherals + + + + HW peripherals + Sheet.3 + Drivers + + + + Drivers + Sheet.4 + Architecture/SOC dependent layer + + + + Architecture/SOC dependent layer + Sheet.5 + Zephyr Kernel + + + + ZephyrKernel + Sheet.6 + Application + + + + Application + Sheet.7 + Host OS Kernel (i.e. Linux) + + + + Host OS Kernel (i.e. Linux) Sheet.7Host OS Kernel (i.e. Linux)Overall scheduler & entry pointCPUemulationSheet.8HW models / host HW API adaptationPOSIX archand SOC + Sheet.9 + Drivers + + + + Drivers + Sheet.11 + Zephyr Kernel + + + + ZephyrKernel + Sheet.12 + Application + + + + Application + Sheet.13 + Normal Zephyr layering + + + + Normal Zephyr layering native simulator runner contextEmbedded CPU SW (Zephyr) context +native_sim & _bsimboards Zephyr layeringHW models /Host APIadaptation From 05c03eb2587af0240e77bb3d15ad9266e0f72eb5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 16:43:18 +0100 Subject: [PATCH 3751/4498] bluetooth dev doc: Update with nrf5340bsim info Now that we also have this target board, we have some more options. Update the docs to reflect these. Signed-off-by: Alberto Escolar Piedras --- doc/connectivity/bluetooth/bluetooth-dev.rst | 25 +++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/connectivity/bluetooth/bluetooth-dev.rst b/doc/connectivity/bluetooth/bluetooth-dev.rst index 49daefe43b9..865eb22d049 100644 --- a/doc/connectivity/bluetooth/bluetooth-dev.rst +++ b/doc/connectivity/bluetooth/bluetooth-dev.rst @@ -34,7 +34,7 @@ There are 4 possible hardware setups to use with Zephyr and Bluetooth: #. Embedded #. QEMU with an external Controller #. :ref:`native_sim ` with an external Controller -#. Simulated nRF52 with BabbleSim +#. Simulated nRF5x with BabbleSim Embedded ======== @@ -137,32 +137,35 @@ Refer to :ref:`bluetooth_qemu_native` for full instructions on how to build and run an application with a physical controller. For the virtual controller refer to :ref:`bluetooth_virtual_posix`. -Simulated nRF52 with BabbleSim +Simulated nRF5x with BabbleSim ============================== .. note:: This is currently only available on GNU/Linux -The :ref:`nrf52_bsim board `, is a simulated target board -which emulates the necessary peripherals of a nrf52 SOC to be able to develop +The :ref:`nrf52_bsim ` and :ref:`nrf5340bsim ` boards, +are simulated target boards +which emulate the necessary peripherals of a nRF52/53 SOC to be able to develop and test BLE applications. -This board, uses: +These boards, use: - * `BabbleSim`_ to simulate the nrf52 modem and the radio environment. - * The POSIX arch to emulate the processor. - * `Models of the nrf52 HW `_ + * `BabbleSim`_ to simulate the nRF5x modem and the radio environment. + * The POSIX arch and native simulator to emulate the processor, and run natively on your host. + * `Models of the nrf5x HW `_ Just like with the :ref:`native_sim ` target, the build result is a normal Linux executable. You can find more information on how to run simulations with one or several -devices in -:ref:`this board's documentation ` +devices in either of :ref:`these boards's documentation `. -Currently, only :ref:`Combined builds +With the :ref:`nrf52_bsim `, only :ref:`Combined builds ` are possible, as this board does not yet have any models of a UART, or USB which could be used for an HCI interface towards another real or simulated device. +With the :ref:`nrf5340bsim `, you can build with either, both controller and host +on its network core, or, with the network core running only the controller, the application +core running the host and your application, and the HCI transport over IPC. Initialization ************** From b9977592a505cb1c29da58132e0ffbb953adf7bf Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 16:44:47 +0100 Subject: [PATCH 3752/4498] doc/develop/test/bsim: Update with nrf5340bsim info Update this page to account for the fact that now we have several bsim boards in tree. Signed-off-by: Alberto Escolar Piedras --- doc/develop/test/bsim.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/develop/test/bsim.rst b/doc/develop/test/bsim.rst index d52bbc6fcfd..c785f88c1ee 100644 --- a/doc/develop/test/bsim.rst +++ b/doc/develop/test/bsim.rst @@ -12,7 +12,7 @@ including the BLE stack, 802.15.4, and some of the networking stack. BabbleSim_ is a physical layer simulator, which in combination with the Zephyr :ref:`bsim boards` can be used to simulate a network of BLE and 15.4 devices. -When we build Zephyr targeting an :ref:`nrf52_bsim` board we produce a Linux +When we build Zephyr targeting a :ref:`bsim board` we produce a Linux executable, which includes the application, Zephyr OS, and models of the HW. When there is radio activity, this Linux executable will connect to the BabbleSim Phy simulation @@ -21,8 +21,9 @@ to simulate the radio channel. In the BabbleSim documentation you can find more information on how to `get `_ and `build `_ the simulator. -In the :ref:`nrf52_bsim` board documentation you can find more information about how -to build Zephyr targeting that particular board, and a few examples. +In the :ref:`nrf52_bsim` and :ref:`nrf5340bsim` boards documentation +you can find more information about how to build Zephyr targeting thesee particular boards, +and a few examples. Types of tests ************** @@ -31,7 +32,7 @@ Tests without radio activity: bsim tests with twister ----------------------------------------------------- The :ref:`bsim boards` can be used without radio activity, and in that case, it is not -necessary to connect them to a phyisical layer simulation. Thanks to this, this target boards can +necessary to connect them to a physical layer simulation. Thanks to this, these target boards can be used just like :ref:`native_sim` with :ref:`twister `, to run all standard Zephyr twister tests, but with models of a real SOC HW, and their drivers. @@ -62,8 +63,8 @@ found in the :ref:`bsim boards tests section`. Test coverage and BabbleSim *************************** -As the :ref:`nrf52_bsim` is based on the POSIX architecture, you can easily collect test -coverage information. +As the :ref:`nrf52_bsim` and :ref:`nrf5340bsim` boards are based on the +POSIX architecture, you can easily collect test coverage information. You can use the script :code:`tests/bsim/generate_coverage_report.sh` to generate an html coverage report from tests. From 927445325c78157a9f4b35a5fd8431fd7f390688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 14 Nov 2023 21:16:33 +0700 Subject: [PATCH 3753/4498] soc: nxp_s32: s32ze: include device headers in soc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To simplify the inclusion of device headers in common code for NXP S32 devices, make sure all SoCs are including their respective device headers. This PR adds the missing headers for S32Z/E. Signed-off-by: Manuel Argüelles --- soc/arm/nxp_s32/s32ze/soc.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/soc/arm/nxp_s32/s32ze/soc.h b/soc/arm/nxp_s32/s32ze/soc.h index 1a3ea631173..f7c96aa2ed9 100644 --- a/soc/arm/nxp_s32/s32ze/soc.h +++ b/soc/arm/nxp_s32/s32ze/soc.h @@ -10,6 +10,12 @@ /* Do not let CMSIS to handle GIC */ #define __GIC_PRESENT 0 +#if defined(CONFIG_SOC_S32Z27_R52) +#include +#else +#error "SoC not supported" +#endif + /* Aliases for peripheral base addresses */ /* SIUL2 */ From 2c9255fbba64f6d33fe75d0ca1dc3f876eaed1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 14 Nov 2023 21:16:46 +0700 Subject: [PATCH 3754/4498] soc: nxp_s32: include soc.h instead of individual headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SoC header already includes the necessary device headers for all SoC variants supported. Signed-off-by: Manuel Argüelles --- soc/arm/nxp_s32/common/osif.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/soc/arm/nxp_s32/common/osif.c b/soc/arm/nxp_s32/common/osif.c index 52de7a38b7f..970e127fe13 100644 --- a/soc/arm/nxp_s32/common/osif.c +++ b/soc/arm/nxp_s32/common/osif.c @@ -4,15 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include -#if defined(CONFIG_SOC_S32Z27_R52) -#include -#elif defined(CONFIG_SOC_S32K344) -#include -#endif - /* Required by OsIf timer initialization but not used with Zephyr, so no values configured */ static const OsIf_ConfigType osif_config; const OsIf_ConfigType *const OsIf_apxPredefinedConfig[OSIF_MAX_COREIDX_SUPPORTED] = { From 24c1b42741e2c641f0886c6f6e4f9fc7deec8739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Tue, 14 Nov 2023 21:18:18 +0700 Subject: [PATCH 3755/4498] drivers: ethernet: nxp_s32: include soc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SoC header already includes the necessary device headers for all SoC variants supported. Signed-off-by: Manuel Argüelles --- drivers/ethernet/eth_nxp_s32_netc.c | 2 +- drivers/ethernet/eth_nxp_s32_netc_psi.c | 2 +- drivers/ethernet/eth_nxp_s32_netc_vsi.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ethernet/eth_nxp_s32_netc.c b/drivers/ethernet/eth_nxp_s32_netc.c index c452a4b398f..f5a3994a9c4 100644 --- a/drivers/ethernet/eth_nxp_s32_netc.c +++ b/drivers/ethernet/eth_nxp_s32_netc.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(nxp_s32_eth); #include #include -#include +#include #include #include #include diff --git a/drivers/ethernet/eth_nxp_s32_netc_psi.c b/drivers/ethernet/eth_nxp_s32_netc_psi.c index f35eb73ba28..8a3242be911 100644 --- a/drivers/ethernet/eth_nxp_s32_netc_psi.c +++ b/drivers/ethernet/eth_nxp_s32_netc_psi.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(nxp_s32_eth_psi); #include #include -#include +#include #include #include #include diff --git a/drivers/ethernet/eth_nxp_s32_netc_vsi.c b/drivers/ethernet/eth_nxp_s32_netc_vsi.c index b262250c226..1a159529814 100644 --- a/drivers/ethernet/eth_nxp_s32_netc_vsi.c +++ b/drivers/ethernet/eth_nxp_s32_netc_vsi.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(nxp_s32_eth_vsi); #include #include -#include +#include #include #include #include From e87ded3f03798b2f2f348984f673489542a127cc Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 16:27:01 +0000 Subject: [PATCH 3756/4498] input: it8xxx2: use the generic keyboard code Split the common keyboard scanning code out of the ITE specific driver and use the generic code instead. Note that this changes few timing defaults, the change is not significant though so I suspect there's no difference in practice. Signed-off-by: Fabio Baltieri --- boards/riscv/it82xx2_evb/it82xx2_evb.dts | 2 + boards/riscv/it8xxx2_evb/it8xxx2_evb.dts | 2 + drivers/input/Kconfig.it8xxx2 | 40 +-- drivers/input/input_ite_it8xxx2_kbd.c | 436 ++++------------------- dts/bindings/input/ite,it8xxx2-kbd.yaml | 8 +- 5 files changed, 90 insertions(+), 398 deletions(-) diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.dts b/boards/riscv/it82xx2_evb/it82xx2_evb.dts index 3110363d88a..1d1bb23eeb6 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb.dts +++ b/boards/riscv/it82xx2_evb/it82xx2_evb.dts @@ -189,6 +189,8 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index 73f7ec1b1de..c111e9092aa 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -173,6 +173,8 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/drivers/input/Kconfig.it8xxx2 b/drivers/input/Kconfig.it8xxx2 index bbd9699decc..6e729b27c3a 100644 --- a/drivers/input/Kconfig.it8xxx2 +++ b/drivers/input/Kconfig.it8xxx2 @@ -1,47 +1,11 @@ # Copyright (c) 2021 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -menuconfig INPUT_ITE_IT8XXX2_KBD +config INPUT_ITE_IT8XXX2_KBD bool "ITE keyboard scanning driver" default y depends on DT_HAS_ITE_IT8XXX2_KBD_ENABLED + select INPUT_KBD_MATRIX select MULTITHREADING help This option enables the ITE keyboard scan driver. - -if INPUT_ITE_IT8XXX2_KBD - -config INPUT_ITE_IT8XXX2_COLUMN_SIZE - int "INPUT_ITE_IT8XXX2_COLUMN_SIZE" - range 16 18 - default 16 - help - Adjust the value to your keyboard columns. The maximum - column size for the ITE family is 18. - -config INPUT_ITE_IT8XXX2_ROW_SIZE - int "INPUT_ITE_IT8XXX2_ROW_SIZE" - default 8 - help - Adjust the value to your keyboard rows. The maximum - row size for the ITE family is 8. - -config INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN - int "INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN" - default 9 - help - Determines the time in msecs for debouncing a key press. - -config INPUT_ITE_IT8XXX2_DEBOUNCE_UP - int "INPUT_ITE_IT8XXX2_DEBOUNCE_UP" - default 30 - help - Determines the time in msecs for debouncing a key release. - -config INPUT_ITE_IT8XXX2_POLL_PERIOD - int "INPUT_ITE_IT8XXX2_POLL_PERIOD" - default 3 - help - Defines the poll period in msecs between matrix scans. - -endif diff --git a/drivers/input/input_ite_it8xxx2_kbd.c b/drivers/input/input_ite_it8xxx2_kbd.c index 560f4fdd7d9..6f16fba1d6e 100644 --- a/drivers/input/input_ite_it8xxx2_kbd.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -14,40 +14,30 @@ #include #include #include +#include #include #include #include LOG_MODULE_REGISTER(input_ite_it8xxx2_kbd); -#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) -#define KEYBOARD_COLUMN_DRIVE_ALL -2 -#define KEYBOARD_COLUMN_DRIVE_NONE -1 -/* Free run timer counts transform to micro-seconds (clock source is 32768Hz) */ -#define CLOCK_32K_HW_CYCLES_TO_US(X) \ - (uint32_t)((((uint64_t)(X) * 1000000U) / \ - sys_clock_hw_cycles_per_sec())) -/* Milli-second transform to micro-second */ -#define MS_TO_US 1000U -/* Number of tracked scan times */ -#define SCAN_OCURRENCES 30U -/* Thread stack size */ -#define TASK_STACK_SIZE 1024 - -struct input_it8xxx2_kbd_wuc_map_cfg { +#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) + +struct it8xxx2_kbd_wuc_map_cfg { /* WUC control device structure */ const struct device *wucs; /* WUC pin mask */ uint8_t mask; }; -struct input_it8xxx2_kbd_config { +struct it8xxx2_kbd_config { + struct input_kbd_matrix_common_config common; /* Keyboard scan controller base address */ struct kscan_it8xxx2_regs *base; /* Keyboard scan input (KSI) wake-up irq */ int irq; /* KSI[7:0] wake-up input source configuration list */ - const struct input_it8xxx2_kbd_wuc_map_cfg *wuc_map_list; + const struct it8xxx2_kbd_wuc_map_cfg *wuc_map_list; /* KSI[7:0]/KSO[17:0] keyboard scan alternate configuration */ const struct pinctrl_dev_config *pcfg; /* KSO16 GPIO cells */ @@ -56,44 +46,26 @@ struct input_it8xxx2_kbd_config { struct gpio_dt_spec kso17_gpios; }; -/* Device data */ -struct input_it8xxx2_kbd_data { - /* Variables in usec units */ - uint32_t deb_time_press; - uint32_t deb_time_rel; - int32_t poll_timeout; - uint32_t poll_period; - uint8_t matrix_stable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_unstable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_previous_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - /* Index in to the scan_clock_cycle to indicate start of debouncing */ - uint8_t scan_cycle_idx[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] - [CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE]; - /* - * Track previous "elapsed clock cycles" per matrix scan. This - * is used to calculate the debouncing time for every key - */ - uint8_t scan_clk_cycle[SCAN_OCURRENCES]; - struct k_sem poll_lock; - uint8_t scan_cycles_idx; - struct k_thread thread; +struct it8xxx2_kbd_data { + struct input_kbd_matrix_common_data common; /* KSI[7:0] wake-up interrupt status mask */ uint8_t ksi_pin_mask; - - K_KERNEL_STACK_MEMBER(thread_stack, TASK_STACK_SIZE); }; -static void drive_keyboard_column(const struct device *dev, int col) +INPUT_KBD_STRUCT_CHECK(struct it8xxx2_kbd_config, struct it8xxx2_kbd_data); + +static void it8xxx2_kbd_drive_column(const struct device *dev, int col) { - const struct input_it8xxx2_kbd_config *const config = dev->config; + const struct it8xxx2_kbd_config *const config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; struct kscan_it8xxx2_regs *const inst = config->base; int mask; /* Tri-state all outputs */ - if (col == KEYBOARD_COLUMN_DRIVE_NONE) { + if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { mask = 0x3ffff; /* Assert all outputs */ - } else if (col == KEYBOARD_COLUMN_DRIVE_ALL) { + } else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) { mask = 0; /* Assert a single output */ } else { @@ -103,86 +75,24 @@ static void drive_keyboard_column(const struct device *dev, int col) /* Set KSO[17:0] output data */ inst->KBS_KSOL = (uint8_t) (mask & 0xff); inst->KBS_KSOH1 = (uint8_t) ((mask >> 8) & 0xff); -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff); -#endif + if (common->col_size > 16) { + inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff); + } } -static uint8_t read_keyboard_row(const struct device *dev) +static int it8xxx2_kbd_read_row(const struct device *dev) { - const struct input_it8xxx2_kbd_config *const config = dev->config; + const struct it8xxx2_kbd_config *const config = dev->config; struct kscan_it8xxx2_regs *const inst = config->base; /* Bits are active-low, so toggle it (return 1 means key pressed) */ return (inst->KBS_KSI ^ 0xff); } -static bool is_matrix_ghosting(const uint8_t *state) -{ - /* - * Matrix keyboard designs are susceptible to ghosting. - * An extra key appears to be pressed when 3 keys - * belonging to the same block are pressed. - * for example, in the following block - * - * . . w . q . - * . . . . . . - * . . . . . . - * . . m . a . - * - * the key m would look as pressed if the user pressed keys - * w, q and a simultaneously. A block can also be formed, - * with not adjacent columns. - */ - for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { - if (!state[c]) - continue; - - for (int c_n = c + 1; c_n < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c_n++) { - /* - * We AND the columns to detect a "block". - * this is an indication of ghosting, due to current - * flowing from a key which was never pressed. in our - * case, current flowing is a bit set to 1 as we - * flipped the bits when the matrix was scanned. - * now we OR the columns using z&(z-1) which is - * non-zero only if z has more than one bit set. - */ - uint8_t common_row_bits = state[c] & state[c_n]; - - if (common_row_bits & (common_row_bits - 1)) - return true; - } - } - - return false; -} - -static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state) -{ - uint8_t row; - uint8_t key_event = 0U; - - for (int col = 0; col < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; col++) { - /* Drive specific column low and others high */ - drive_keyboard_column(dev, col); - /* Allow the matrix to stabilize before reading it */ - k_busy_wait(50U); - row = read_keyboard_row(dev); - new_state[col] = row; - - key_event |= row; - } - - drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_NONE); - - return key_event != 0U ? true : false; -} - -static void keyboard_raw_interrupt(const struct device *dev) +static void it8xxx2_kbd_isr(const struct device *dev) { - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + struct it8xxx2_kbd_data *data = dev->data; /* * W/C wakeup interrupt status of KSI[7:0] pins @@ -196,14 +106,13 @@ static void keyboard_raw_interrupt(const struct device *dev) /* W/C interrupt status of KSI[7:0] pins */ ite_intc_isr_clear(config->irq); - /* Release poll lock semaphore */ - k_sem_give(&data->poll_lock); + input_kbd_matrix_poll_start(dev); } -void keyboard_raw_enable_interrupt(const struct device *dev, int enable) +static void it8xxx2_kbd_set_detect_mode(const struct device *dev, bool enable) { - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + struct it8xxx2_kbd_data *data = dev->data; if (enable) { /* @@ -224,217 +133,33 @@ void keyboard_raw_enable_interrupt(const struct device *dev, int enable) } } -static bool check_key_events(const struct device *dev) +static int it8xxx2_kbd_init(const struct device *dev) { - struct input_it8xxx2_kbd_data *data = dev->data; - uint8_t matrix_new_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] = {0U}; - bool key_pressed = false; - uint32_t cycles_now = k_cycle_get_32(); - uint8_t row_changed = 0U; - uint8_t deb_col; - - if (++data->scan_cycles_idx >= SCAN_OCURRENCES) { - data->scan_cycles_idx = 0U; - } - - data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now; - - /* Scan the matrix */ - key_pressed = read_keyboard_matrix(dev, matrix_new_state); - - /* Abort if ghosting is detected */ - if (is_matrix_ghosting(matrix_new_state)) { - return false; - } - - /* - * The intent of this loop is to gather information related to key - * changes - */ - for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { - /* Check if there was an update from the previous scan */ - row_changed = matrix_new_state[c] ^ - data->matrix_previous_state[c]; - - if (!row_changed) - continue; - - for (int r = 0; r < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; r++) { - /* - * Index all they keys that changed for each row - * in order to debounce each key in terms of it - */ - if (row_changed & BIT(r)) - data->scan_cycle_idx[c][r] = - data->scan_cycles_idx; - } - - data->matrix_unstable_state[c] |= row_changed; - data->matrix_previous_state[c] = matrix_new_state[c]; - } - - for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { - deb_col = data->matrix_unstable_state[c]; - - if (!deb_col) - continue; - - /* Debouncing for each row key occurs here */ - for (int r = 0; r < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; r++) { - uint8_t mask = BIT(r); - uint8_t row_bit = matrix_new_state[c] & mask; - - /* Continue if we already debounce a key */ - if (!(deb_col & mask)) - continue; - - /* Convert the clock cycle differences to usec */ - uint32_t debt = CLOCK_32K_HW_CYCLES_TO_US(cycles_now - - data->scan_clk_cycle[data->scan_cycle_idx[c][r]]); - - /* Does the key requires more time to be debounced ? */ - if (debt < (row_bit ? data->deb_time_press : - data->deb_time_rel)) { - /* Need more time to debounce */ - continue; - } - - data->matrix_unstable_state[c] &= ~row_bit; - - /* Check if there was a change in the stable state */ - if ((data->matrix_stable_state[c] & mask) == row_bit) { - /* Key state did not change */ - continue; - } - - /* - * The current row has been debounced, therefore update - * the stable state. Then, proceed to notify the - * application about the keys pressed. - */ - data->matrix_stable_state[c] ^= mask; - - input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER); - input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER); - input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); - } - } - - return key_pressed; -} - -/** - * @brief Determine if a timer is expired. - * - * @param start_cycles The starting time of HW cycle. - * @param timeout Pointer to the period time. - * - * @retval true If timer is expired; - * false If timer isn't expired. - */ -static bool poll_expired(uint32_t start_cycles, int32_t *timeout) -{ - uint32_t now_cycles; - uint32_t microsecs_spent; - - now_cycles = k_cycle_get_32(); - microsecs_spent = CLOCK_32K_HW_CYCLES_TO_US(now_cycles - start_cycles); - - /* Update the timeout value */ - *timeout -= microsecs_spent; - - return !(*timeout >= 0); -} - -void polling_task(const struct device *dev, void *dummy2, void *dummy3) -{ - struct input_it8xxx2_kbd_data *data = dev->data; - int32_t local_poll_timeout = data->poll_timeout; - uint32_t current_cycles; - uint32_t cycles_delta; - uint32_t wait_period; - - ARG_UNUSED(dummy2); - ARG_UNUSED(dummy3); - - while (true) { - /* Init all KSO output low */ - drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_ALL); - /* Enable wakeup and interrupt of KSI pins */ - keyboard_raw_enable_interrupt(dev, 1); - /* Wait poll lock semaphore */ - k_sem_take(&data->poll_lock, K_FOREVER); - /* Disable wakeup and interrupt of KSI pins after fired */ - keyboard_raw_enable_interrupt(dev, 0); - - uint32_t start_poll_cycles = k_cycle_get_32(); - - while (true) { - uint32_t start_period_cycles = k_cycle_get_32(); - - if (check_key_events(dev)) { - start_poll_cycles = k_cycle_get_32(); - } else if (poll_expired(start_poll_cycles, - &local_poll_timeout)) { - break; - } - - /* - * Subtract the time invested from the sleep period - * in order to compensate for the time invested - * in debouncing a key - */ - current_cycles = k_cycle_get_32(); - cycles_delta = current_cycles - start_period_cycles; - wait_period = data->poll_period - - CLOCK_32K_HW_CYCLES_TO_US(cycles_delta); - - /* Override wait_period in case it's less than 1000 us */ - if (wait_period < MS_TO_US) { - wait_period = MS_TO_US; - } - - /* - * Wait period results in a larger number when - * current cycles counter wrap. In this case, the - * whole poll period is used - */ - if (wait_period > data->poll_period) { - LOG_DBG("wait_period : %u", wait_period); - wait_period = data->poll_period; - } - - /* Allow other threads to run while we sleep */ - k_usleep(wait_period); - } - } -} - -static int input_it8xxx2_kbd_init(const struct device *dev) -{ - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; + struct it8xxx2_kbd_data *data = dev->data; struct kscan_it8xxx2_regs *const inst = config->base; int status; /* Disable wakeup and interrupt of KSI pins before configuring */ - keyboard_raw_enable_interrupt(dev, 0); + it8xxx2_kbd_set_detect_mode(dev, false); -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - /* - * For KSO[16] and KSO[17]: - * 1.GPOTRC: - * Bit[x] = 1b: Enable the open-drain mode of KSO pin - * 2.GPCRCx: - * Bit[7:6] = 00b: Select alternate KSO function - * Bit[2] = 1b: Enable the internal pull-up of KSO pin - * - * NOTE: Set input temporarily for gpio_pin_configure(), after that - * pinctrl_apply_state() set to alternate function immediately. - */ - gpio_pin_configure_dt(&config->kso16_gpios, GPIO_INPUT); - gpio_pin_configure_dt(&config->kso17_gpios, GPIO_INPUT); -#endif + if (common->col_size > 16) { + /* + * For KSO[16] and KSO[17]: + * 1.GPOTRC: + * Bit[x] = 1b: Enable the open-drain mode of KSO pin + * 2.GPCRCx: + * Bit[7:6] = 00b: Select alternate KSO function + * Bit[2] = 1b: Enable the internal pull-up of KSO pin + * + * NOTE: Set input temporarily for gpio_pin_configure(), after + * that pinctrl_apply_state() set to alternate function + * immediately. + */ + gpio_pin_configure_dt(&config->kso16_gpios, GPIO_INPUT); + gpio_pin_configure_dt(&config->kso17_gpios, GPIO_INPUT); + } /* * Enable the internal pull-up and kbs mode of the KSI[7:0] pins. * Enable the internal pull-up and kbs mode of the KSO[15:0] pins. @@ -449,9 +174,9 @@ static int input_it8xxx2_kbd_init(const struct device *dev) /* KSO[17:0] pins output low */ inst->KBS_KSOL = 0x00; inst->KBS_KSOH1 = 0x00; -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - inst->KBS_KSOH2 = 0x00; -#endif + if (common->col_size > 16) { + inst->KBS_KSOH2 = 0x00; + } for (int i = 0; i < KEYBOARD_KSI_PIN_COUNT; i++) { /* Select wakeup interrupt falling-edge triggered of KSI[7:0] pins */ @@ -469,10 +194,8 @@ static int input_it8xxx2_kbd_init(const struct device *dev) * We want to clear KSI[7:0] pins status at a time when wakeup * interrupt fire, so gather the KSI[7:0] pin mask value here. */ - if (IS_ENABLED(CONFIG_LOG)) { - if (config->wuc_map_list[i].wucs != config->wuc_map_list[0].wucs) { - LOG_ERR("KSI%d pin isn't in the same wuc node!", i); - } + if (config->wuc_map_list[i].wucs != config->wuc_map_list[0].wucs) { + LOG_ERR("KSI%d pin isn't in the same wuc node!", i); } data->ksi_pin_mask |= config->wuc_map_list[i].mask; } @@ -480,48 +203,43 @@ static int input_it8xxx2_kbd_init(const struct device *dev) /* W/C interrupt status of KSI[7:0] pins */ ite_intc_isr_clear(config->irq); - /* Kconfig.it8xxx2 time figures are transformed from msec to usec */ - data->deb_time_press = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN * MS_TO_US); - data->deb_time_rel = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_UP * MS_TO_US); - data->poll_period = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_POLL_PERIOD * MS_TO_US); - data->poll_timeout = 100 * MS_TO_US; - - /* Create poll lock semaphore */ - k_sem_init(&data->poll_lock, 0, 1); - irq_connect_dynamic(DT_INST_IRQN(0), 0, - (void (*)(const void *))keyboard_raw_interrupt, + (void (*)(const void *))it8xxx2_kbd_isr, (const void *)dev, 0); - /* Create keyboard scan task */ - k_thread_create(&data->thread, data->thread_stack, - TASK_STACK_SIZE, - (void (*)(void *, void *, void *))polling_task, - (void *)dev, NULL, NULL, - K_PRIO_COOP(4), 0, K_NO_WAIT); - - return 0; + return input_kbd_matrix_common_init(dev); } -static const struct input_it8xxx2_kbd_wuc_map_cfg - input_it8xxx2_kbd_wuc[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = IT8XXX2_DT_WUC_ITEMS_LIST(0); +static const struct it8xxx2_kbd_wuc_map_cfg + it8xxx2_kbd_wuc[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = IT8XXX2_DT_WUC_ITEMS_LIST(0); PINCTRL_DT_INST_DEFINE(0); -static const struct input_it8xxx2_kbd_config input_it8xxx2_kbd_cfg = { +INPUT_KBD_MATRIX_DT_INST_DEFINE(0); + +static const struct input_kbd_matrix_api it8xxx2_kbd_api = { + .drive_column = it8xxx2_kbd_drive_column, + .read_row = it8xxx2_kbd_read_row, + .set_detect_mode = it8xxx2_kbd_set_detect_mode, +}; + +static const struct it8xxx2_kbd_config it8xxx2_kbd_cfg_0 = { + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, &it8xxx2_kbd_api), .base = (struct kscan_it8xxx2_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0), .irq = DT_INST_IRQN(0), - .wuc_map_list = input_it8xxx2_kbd_wuc, + .wuc_map_list = it8xxx2_kbd_wuc, .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .kso16_gpios = GPIO_DT_SPEC_INST_GET(0, kso16_gpios), .kso17_gpios = GPIO_DT_SPEC_INST_GET(0, kso17_gpios), }; -static struct input_it8xxx2_kbd_data input_it8xxx2_kbd_kbd_data; +static struct it8xxx2_kbd_data it8xxx2_kbd_data_0; -DEVICE_DT_INST_DEFINE(0, &input_it8xxx2_kbd_init, NULL, - &input_it8xxx2_kbd_kbd_data, &input_it8xxx2_kbd_cfg, +DEVICE_DT_INST_DEFINE(0, &it8xxx2_kbd_init, NULL, + &it8xxx2_kbd_data_0, &it8xxx2_kbd_cfg_0, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, + "only one ite,it8xxx2-kbd compatible node can be supported"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, row_size), 1, 8), "invalid row-size"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, col_size), 16, 18), "invalid col-size"); diff --git a/dts/bindings/input/ite,it8xxx2-kbd.yaml b/dts/bindings/input/ite,it8xxx2-kbd.yaml index 1aec1e1e7a9..d809f41fbbc 100644 --- a/dts/bindings/input/ite,it8xxx2-kbd.yaml +++ b/dts/bindings/input/ite,it8xxx2-kbd.yaml @@ -5,7 +5,7 @@ description: ITE it8xxx2 keyboard matrix controller compatible: "ite,it8xxx2-kbd" -include: [kscan.yaml, pinctrl-device.yaml] +include: [kbd-matrix-common.yaml, pinctrl-device.yaml] properties: reg: @@ -40,3 +40,9 @@ properties: pinctrl-names: required: true + + row-size: + required: true + + col-size: + required: true From 11857e350907875772bda13485675048b724a54e Mon Sep 17 00:00:00 2001 From: Girisha Dengi Date: Tue, 14 Nov 2023 15:04:44 +0000 Subject: [PATCH 3757/4498] MAINTAINERS: Update maintainers/codeowners for Intel Agilex boards Corrected/Updated proper github account names for maintainers and codeowners file. Signed-off-by: Girisha Dengi --- CODEOWNERS | 2 +- MAINTAINERS.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 54f2b65933a..8872e7381c5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -144,7 +144,7 @@ /boards/arm64/fvp_baser_aemv8r/ @povergoing /boards/arm64/fvp_base_revc_2xaemv8a/ @carlocaione /boards/arm64/intel_socfpga_agilex_socdk/ @siclim @ngboonkhai -/boards/arm64/intel_socfpga_agilex5_socdk/ @chongteikheng +/boards/arm64/intel_socfpga_agilex5_socdk/ @teikheng @gdengi /boards/arm64/rcar_*/ @lorc @xakep-amatop # All cmake related files /doc/develop/tools/coccinelle.rst @himanshujha199640 @JuliaLawall diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 7562f3587c7..32a1d1efb54 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2634,7 +2634,7 @@ Intel Platforms (Agilex): - gdengi collaborators: - nbalabak - - chongteikheng + - teikheng files: - boards/arm64/intel_*/ - soc/arm64/intel_*/ From 256adeebd934b80358c78d6fb6600fed09f25fa4 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 16 Nov 2023 18:20:05 +0100 Subject: [PATCH 3758/4498] Revert "drivers: watchdog: wdt_nrfx: Implement disable API" This reverts commit 415b6fc945fd3748d2c8c5191abbc484fe551cad. This does not even compile as it attempts to do assignment to a read-only object (config->config.behaviour). Signed-off-by: Henrik Brix Andersen --- drivers/watchdog/wdt_nrfx.c | 41 ++++++++++++------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 5d2e036a213..8d61f11d6fb 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -28,32 +28,29 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) { const struct wdt_nrfx_config *config = dev->config; struct wdt_nrfx_data *data = dev->data; - nrfx_err_t err_code; + uint32_t behaviour; /* Activate all available options. Run in all cases. */ - config->config.behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | -#if NRF_WDT_HAS_STOP - NRF_WDT_BEHAVIOUR_STOP_ENABLE_MASK | -#endif - NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; /* Deactivate running in sleep mode. */ if (options & WDT_OPT_PAUSE_IN_SLEEP) { - config->config.behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; + behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; } /* Deactivate running when debugger is attached. */ if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) { - config->config.behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; } - config->config.reload_value = data->m_timeout; - - err_code = nrfx_wdt_reconfigure(&config->wdt, &config->config); - - if (err_code != NRFX_SUCCESS) { - return -EBUSY; - } + nrf_wdt_behaviour_set(config->wdt.p_reg, behaviour); + /* The watchdog timer is driven by the LFCLK clock running at 32768 Hz. + * The timeout value given in milliseconds needs to be converted here + * to watchdog ticks.*/ + nrf_wdt_reload_value_set( + config->wdt.p_reg, + (uint32_t)(((uint64_t)data->m_timeout * 32768U) + / 1000)); nrfx_wdt_enable(&config->wdt); @@ -62,21 +59,9 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) static int wdt_nrf_disable(const struct device *dev) { -#if NRFX_WDT_HAS_STOP - const struct wdt_nrfx_config *config = dev->config; - nrfx_err_t err_code; - - err_code = nrfx_wdt_stop(&config->wdt); - - if (err_code != NRFX_SUCCESS) { - return -ENOTSUP; - } - - return 0; -#else + /* Started watchdog cannot be stopped on nRF devices. */ ARG_UNUSED(dev); return -EPERM; -#endif } static int wdt_nrf_install_timeout(const struct device *dev, From 21366fea1979f76fce9f9c84cc4c3eb25630f90f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 16 Nov 2023 21:50:08 +0000 Subject: [PATCH 3759/4498] ci: do not mark coverity issues as stale Coverity issues need to be resolved and closed by owners, not by the bot. Other wise we will continue scanning them and reporting them over and over. Signed-off-by: Anas Nashif --- .github/workflows/stale_issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale_issue.yml b/.github/workflows/stale_issue.yml index d93aa1f381d..8dc31370125 100644 --- a/.github/workflows/stale_issue.yml +++ b/.github/workflows/stale_issue.yml @@ -24,5 +24,5 @@ jobs: stale-issue-label: 'Stale' stale-pr-label: 'Stale' exempt-pr-labels: 'Blocked,In progress' - exempt-issue-labels: 'In progress,Enhancement,Feature,Feature Request,RFC,Meta,Process' + exempt-issue-labels: 'In progress,Enhancement,Feature,Feature Request,RFC,Meta,Process,Coverity' operations-per-run: 400 From 37637373264d707705afbdb72162251904337b76 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 1 Nov 2023 15:26:14 -0700 Subject: [PATCH 3760/4498] smbus: Remove syscalls with callbacks Remove syscalls that allows user threads to set callbacks that will be invoked by the kernel. Userspace is not trusted we can't allow a user thread set callbacks that will be invoked by the kernel and run with supervisor privileges. Signed-off-by: Flavio Ceolin --- drivers/smbus/smbus_handlers.c | 18 ------------------ include/zephyr/drivers/smbus.h | 14 ++++---------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/drivers/smbus/smbus_handlers.c b/drivers/smbus/smbus_handlers.c index 4762ccf1e90..b9c45e76cf7 100644 --- a/drivers/smbus/smbus_handlers.c +++ b/drivers/smbus/smbus_handlers.c @@ -144,15 +144,6 @@ static inline int z_vrfy_smbus_block_pcall(const struct device *dev, } #include -static inline int z_vrfy_smbus_smbalert_set_cb(const struct device *dev, - struct smbus_callback *cb) -{ - K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - - return z_impl_smbus_smbalert_set_cb(dev, cb); -} -#include - static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, struct smbus_callback *cb) { @@ -162,15 +153,6 @@ static inline int z_vrfy_smbus_smbalert_remove_cb(const struct device *dev, } #include -static inline int z_vrfy_smbus_host_notify_set_cb(const struct device *dev, - struct smbus_callback *cb) -{ - K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SMBUS)); - - return z_impl_smbus_host_notify_set_cb(dev, cb); -} -#include - static inline int z_vrfy_smbus_host_notify_remove_cb(const struct device *dev, struct smbus_callback *cb) { diff --git a/include/zephyr/drivers/smbus.h b/include/zephyr/drivers/smbus.h index ccb67a14d4a..c4995febb7b 100644 --- a/include/zephyr/drivers/smbus.h +++ b/include/zephyr/drivers/smbus.h @@ -611,11 +611,8 @@ static inline int z_impl_smbus_get_config(const struct device *dev, * @retval -ENOSYS If function smbus_smbalert_set_cb() is not implemented * by the driver. */ -__syscall int smbus_smbalert_set_cb(const struct device *dev, - struct smbus_callback *cb); - -static inline int z_impl_smbus_smbalert_set_cb(const struct device *dev, - struct smbus_callback *cb) +static inline int smbus_smbalert_set_cb(const struct device *dev, + struct smbus_callback *cb) { const struct smbus_driver_api *api = (const struct smbus_driver_api *)dev->api; @@ -665,11 +662,8 @@ static inline int z_impl_smbus_smbalert_remove_cb(const struct device *dev, * @retval -ENOSYS If function smbus_host_notify_set_cb() is not implemented * by the driver. */ -__syscall int smbus_host_notify_set_cb(const struct device *dev, - struct smbus_callback *cb); - -static inline int z_impl_smbus_host_notify_set_cb(const struct device *dev, - struct smbus_callback *cb) +static inline int smbus_host_notify_set_cb(const struct device *dev, + struct smbus_callback *cb) { const struct smbus_driver_api *api = (const struct smbus_driver_api *)dev->api; From eb323be088d80773ef85360190578aea19361863 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 2 Nov 2023 18:44:53 -0700 Subject: [PATCH 3761/4498] tests: smbus: Fix user mode usage APIs that set callback don't have syscalls and their tests have to run in supervisor mode. Signed-off-by: Flavio Ceolin --- tests/drivers/smbus/smbus_api/src/test_smbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/smbus/smbus_api/src/test_smbus.c b/tests/drivers/smbus/smbus_api/src/test_smbus.c index 5642bd664a6..5d1dd9ca49a 100644 --- a/tests/drivers/smbus/smbus_api/src/test_smbus.c +++ b/tests/drivers/smbus/smbus_api/src/test_smbus.c @@ -45,7 +45,7 @@ ZTEST_USER(test_smbus_general, test_smbus_basic_api) * The test is run in userspace only if CONFIG_USERSPACE option is * enabled, otherwise it is the same as ZTEST() */ -ZTEST_USER(test_smbus_general, test_smbus_smbalert_api) +ZTEST(test_smbus_general, test_smbus_smbalert_api) { const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0)); void *dummy; /* For the dummy function pointer use this */ @@ -90,7 +90,7 @@ ZTEST_USER(test_smbus_general, test_smbus_smbalert_api) * The test is run in userspace only if CONFIG_USERSPACE option is * enabled, otherwise it is the same as ZTEST() */ -ZTEST_USER(test_smbus_general, test_smbus_host_notify_api) +ZTEST(test_smbus_general, test_smbus_host_notify_api) { const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0)); void *dummy; /* For the dummy function pointer use this */ From 3441fee460d9ea90262d3d89a0d4e79e314772cc Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Tue, 7 Nov 2023 16:12:10 +0100 Subject: [PATCH 3762/4498] drivers: spi: Implement workaround for unreliable busy flag For some STM32 MCUs the busy flag of SPI is unreliable. This is a known issue of the device and described in the device errata. As a fix implement a configurable timeout which ensures that a call to spi_transceive will eventually return. Fixes #64927 Signed-off-by: Benedikt Schmidt --- drivers/spi/Kconfig.stm32 | 17 +++++++++++++++++ drivers/spi/spi_ll_stm32.c | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/spi/Kconfig.stm32 b/drivers/spi/Kconfig.stm32 index 8baa5880192..6a53f30cbc4 100644 --- a/drivers/spi/Kconfig.stm32 +++ b/drivers/spi/Kconfig.stm32 @@ -32,5 +32,22 @@ config SPI_STM32_USE_HW_SS help Use Slave Select pin instead of software Slave Select. +config SPI_STM32F7_ERRATA_BUSY + bool + default y + depends on SOC_STM32F745XX || SOC_STM32F746XX || \ + SOC_STM32F750XX || SOC_STM32F756XX + help + Handles erratum "BSY bit may stay high at the end of a data + transfer in Slave mode". + Seen in Errata Sheet 0290 §2.11.2 + +if SPI_STM32F7_ERRATA_BUSY + +config SPI_STM32_BUSY_FLAG_TIMEOUT + int "timeout in us for the STM32 busy flag workaround" + default 10000 + +endif # SPI_STM32F7_ERRATA_BUSY endif # SPI_STM32 diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index e62a763a3f9..0241dbde254 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -902,9 +902,15 @@ static int transceive_dma(const struct device *dev, } #endif +#ifdef CONFIG_SPI_STM32F7_ERRATA_BUSY + WAIT_FOR(ll_func_spi_dma_busy(spi) != 0, + CONFIG_SPI_STM32_BUSY_FLAG_TIMEOUT, + k_yield()); +#else /* wait until spi is no more busy (spi TX fifo is really empty) */ while (ll_func_spi_dma_busy(spi) == 0) { } +#endif #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) /* toggle the DMA transfer request */ From 100836ee9e38bd16281b3a42d318621476d143f3 Mon Sep 17 00:00:00 2001 From: Rodrigo Peixoto Date: Wed, 15 Nov 2023 08:30:52 -0300 Subject: [PATCH 3763/4498] zbus: fix warning messages when mixing C and C++ files After some further investigation, I could find the current solution to enable zbus channels (by using ZBUS_CHAN_DECLARE) to be used in C++ files, which generates a warning when we mix C and C++ code. This fixes the issue by using an approach to add the extern keyword only when the file is being compiled with a C++ compiler. Signed-off-by: Rodrigo Peixoto --- include/zephyr/zbus/zbus.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index 8b2aa05175b..285338d4732 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -148,6 +148,12 @@ struct zbus_channel_observation { const struct zbus_observer *const obs; }; +#ifdef __cplusplus +#define _ZBUS_CPP_EXTERN extern +#else +#define _ZBUS_CPP_EXTERN +#endif /* __cplusplus */ + #if defined(CONFIG_ZBUS_ASSERT_MOCK) #define _ZBUS_ASSERT(_cond, _fmt, ...) \ do { \ @@ -304,8 +310,7 @@ struct zbus_channel_observation { static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \ .observers_start_idx = -1, .observers_end_idx = -1}; \ static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \ - IF_ENABLED(CONFIG_CPP, (extern)) \ - const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \ + _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \ ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \ .message = &_CONCAT(_zbus_message_, _name), \ .message_size = sizeof(_type), .user_data = _user_data, .validator = (_validator), \ From 8cfede8f2e2063028635efd9bc3efd08cf483b6e Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 15 Nov 2023 13:40:38 +0200 Subject: [PATCH 3764/4498] net: lwm2m: Support DTLS Connection Identifier DTLS Connection Identifier support requires DTLS stack that supports it. MbedTLS support in Zephyr is already ported in, also some offloaded sockets support it. Signed-off-by: Seppo Takalo --- doc/connectivity/networking/api/lwm2m.rst | 5 +++++ samples/net/lwm2m_client/overlay-dtls.conf | 3 +++ subsys/net/lib/lwm2m/Kconfig | 7 +++++++ subsys/net/lib/lwm2m/lwm2m_engine.c | 12 ++++++++++++ 4 files changed, 27 insertions(+) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 8a36adf8860..3baa4516c5d 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -404,6 +404,11 @@ NoSec In all modes, Server URI resource (ID 0) must contain the full URI for the target server. When DNS names are used, the DNS resolver must be enabled. +When DTLS is used, following options are recommended to reduce DTLS handshake traffic when connection is re-established: + +* :kconfig:option:`CONFIG_LWM2M_DTLS_CID` enables DTLS Connection Identifier support. When server supports it, this completely removes the handshake when device resumes operation after long idle period. Greatly helps when NAT mappings have timed out. +* :kconfig:option:`CONFIG_LWM2M_TLS_SESSION_CACHING` uses session cache when before falling back to full DTLS handshake. Reduces few packets from handshake, when session is still cached on server side. Most significant effect is to avoid full registration. + LwM2M stack provides callbacks in the :c:struct:`lwm2m_ctx` structure. They are used to feed keys from the LwM2M security object into the TLS credential subsystem. By default, these callbacks can be left as NULL pointers, in which case default callbacks are used. diff --git a/samples/net/lwm2m_client/overlay-dtls.conf b/samples/net/lwm2m_client/overlay-dtls.conf index d9cf838ddc5..930230d8ba4 100644 --- a/samples/net/lwm2m_client/overlay-dtls.conf +++ b/samples/net/lwm2m_client/overlay-dtls.conf @@ -1,9 +1,12 @@ +# Enable DTLS with Connection Identifier CONFIG_LWM2M_DTLS_SUPPORT=y +CONFIG_LWM2M_DTLS_CID=y CONFIG_LWM2M_PEER_PORT=5684 # Select Zephyr mbedtls CONFIG_MBEDTLS=y CONFIG_MBEDTLS_TLS_VERSION_1_2=y +CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y # Special MbedTLS changes CONFIG_MBEDTLS_ENABLE_HEAP=y diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index 1f5b83f47d0..dd3c0c45618 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -115,6 +115,13 @@ config LWM2M_TLS_SESSION_CACHING help Enabling this only when feature is supported in TLS library. +config LWM2M_DTLS_CID + bool "DTLS Connection Identifier support" + default y if MBEDTLS_SSL_DTLS_CONNECTION_ID + help + Request TLS stack to enable DTLS Connection identifier. This requires stack that support it + and actual effect depends on the target server as well. + config LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP bool "Bootstrap support" help diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index befc8826e0c..8fceecf9335 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -987,6 +987,18 @@ int lwm2m_set_default_sockopt(struct lwm2m_ctx *ctx) return ret; } } + if (IS_ENABLED(CONFIG_LWM2M_DTLS_CID)) { + /* Enable CID */ + int cid = TLS_DTLS_CID_ENABLED; + + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_CID, &cid, + sizeof(cid)); + if (ret) { + ret = -errno; + LOG_ERR("Failed to enable TLS_DTLS_CID: %d", ret); + /* Not fatal, continue. */ + } + } if (ctx->hostname_verify && (ctx->desthostname != NULL)) { /** store character at len position */ From 22d470e6a5c50513ac184a8ba84d8c62a279fd3d Mon Sep 17 00:00:00 2001 From: Ibe Van de Veire Date: Wed, 15 Nov 2023 14:40:35 +0100 Subject: [PATCH 3765/4498] drivers: eth_mcux: Add net_if_mcast_cb for IPv4 Added ability to receive mcast callbacks for both IPv4 and IPv6 instead of only IPv6. Signed-off-by: Ibe Van de Veire --- drivers/ethernet/eth_mcux.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/ethernet/eth_mcux.c b/drivers/ethernet/eth_mcux.c index b4e244ae304..f9ab95db9aa 100644 --- a/drivers/ethernet/eth_mcux.c +++ b/drivers/ethernet/eth_mcux.c @@ -1163,7 +1163,6 @@ static int eth_init(const struct device *dev) return 0; } -#if defined(CONFIG_NET_IPV6) static void net_if_mcast_cb(struct net_if *iface, const struct net_addr *addr, bool is_joined) @@ -1172,30 +1171,29 @@ static void net_if_mcast_cb(struct net_if *iface, struct eth_context *context = dev->data; struct net_eth_addr mac_addr; - if (addr->family != AF_INET6) { + if (IS_ENABLED(CONFIG_NET_IPV4) && addr->family == AF_INET) { + net_eth_ipv4_mcast_to_mac_addr(&addr->in_addr, &mac_addr); + } else if (IS_ENABLED(CONFIG_NET_IPV6) && addr->family == AF_INET6) { + net_eth_ipv6_mcast_to_mac_addr(&addr->in6_addr, &mac_addr); + } else { return; } - net_eth_ipv6_mcast_to_mac_addr(&addr->in6_addr, &mac_addr); - if (is_joined) { ENET_AddMulticastGroup(context->base, mac_addr.addr); } else { ENET_LeaveMulticastGroup(context->base, mac_addr.addr); } } -#endif /* CONFIG_NET_IPV6 */ static void eth_iface_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); struct eth_context *context = dev->data; -#if defined(CONFIG_NET_IPV6) static struct net_if_mcast_monitor mon; net_if_mcast_mon_register(&mon, iface, net_if_mcast_cb); -#endif /* CONFIG_NET_IPV6 */ net_if_set_link_addr(iface, context->mac_addr, sizeof(context->mac_addr), From ebd70f959f1642c99416f625cff76925f55e1802 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 14:29:55 +0100 Subject: [PATCH 3766/4498] flash host fuse access: Fix for native_sim For native_sim we need to have the fuse library linked with the native simulator runner, not with the embedded code. Let's fix it. Signed-off-by: Alberto Escolar Piedras --- subsys/fs/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/fs/CMakeLists.txt b/subsys/fs/CMakeLists.txt index 0c1bce7425f..e6c66d304ce 100644 --- a/subsys/fs/CMakeLists.txt +++ b/subsys/fs/CMakeLists.txt @@ -31,7 +31,11 @@ if(CONFIG_FUSE_FS_ACCESS) find_package(PkgConfig REQUIRED) pkg_search_module(FUSE REQUIRED fuse) zephyr_include_directories(${FUSE_INCLUDE_DIR}) - zephyr_link_libraries(${FUSE_LIBRARIES}) + if (CONFIG_NATIVE_LIBRARY) + target_link_options(native_simulator INTERFACE "-l${FUSE_LIBRARIES}") + else() + zephyr_link_libraries(${FUSE_LIBRARIES}) + endif() zephyr_library_compile_definitions(_FILE_OFFSET_BITS=64) zephyr_library_sources(fuse_fs_access.c) endif() From 65fd7d42467225c3c9df013fb710587a62bbf874 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 10 Nov 2023 11:42:39 +0100 Subject: [PATCH 3767/4498] samples shell/fs docs: Enable for native_sim Instead of always enabling fuse for native_posix, let's give users instructions on how to enable it while building. In the documentation: replace the references to native_posix with native_sim, improve the links, mention the flash simulator, and provide a separate subsection for FUSE access. Add a separate test for the sample with fuse access enabled and be sure it is possible to run both this and the basic one with native_sim (was filtered out before for native_posix) Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_sim/doc/index.rst | 4 ++ samples/subsys/shell/fs/README.rst | 39 +++++++++++++++---- .../subsys/shell/fs/boards/native_posix.conf | 1 - .../shell/fs/boards/native_posix_64.conf | 1 - samples/subsys/shell/fs/sample.yaml | 21 ++++++---- 5 files changed, 49 insertions(+), 17 deletions(-) delete mode 100644 samples/subsys/shell/fs/boards/native_posix.conf delete mode 100644 samples/subsys/shell/fs/boards/native_posix_64.conf diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 5cd060930e4..5d4ab7b8b8c 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -428,6 +428,8 @@ The following peripherals are currently provided with this board: The flash content can be accessed from the host system, as explained in the `Host based flash access`_ section. +.. _native_ptty_uart: + PTTY UART ========= @@ -550,6 +552,8 @@ development by integrating more seamlessly with the host operating system: data to a file in the host filesystem. More information can be found in :ref:`Common Tracing Format ` +.. _native_fuse_flash: + Host based flash access *********************** diff --git a/samples/subsys/shell/fs/README.rst b/samples/subsys/shell/fs/README.rst index d8bdecae6cd..f3d86083225 100644 --- a/samples/subsys/shell/fs/README.rst +++ b/samples/subsys/shell/fs/README.rst @@ -17,12 +17,38 @@ A board with LittleFS file system support and UART console Building ******** -Native Posix -============ +native_sim +========== + +You can build this sample for :ref:`native_sim ` with: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/shell/fs + :board: native_sim + :goals: build + :compact: + +Which by default will use the flash simulator. The flash simulator will use a file, +:file:`flash.bin`, in the current directory to keep the flash content. +You have several options to control this. You can check them with: + +.. code-block:: console + + zephyr/zephyr.exe -help + +Check the :ref:`native_sim UART documentation ` for information on how to connect +to the UART. + +With FUSE access in the host filesystem +--------------------------------------- + +If you enable the :ref:`host FUSE filsystem access ` +you will also have the flash filesystem mounted and accessible from your Linux host filesystem. Before starting a build, make sure that the i386 pkgconfig directory is in your search path and that a 32-bit version of libfuse is installed. For more -background information on this requirement see :ref:`native_posix`. +background information on this requirement check +:ref:`the native_sim documentation `. .. code-block:: console @@ -30,12 +56,11 @@ background information on this requirement see :ref:`native_posix`. .. zephyr-app-commands:: :zephyr-app: samples/subsys/shell/fs - :board: native_posix + :board: native_sim + :gen-args: -DCONFIG_FUSE_FS_ACCESS=y :goals: build :compact: -See :ref:`native_posix` on how to connect to the UART. - Reel Board ========== @@ -198,7 +223,7 @@ Remove a file or directory Flash Host Access ================= -For the Native POSIX board the flash partitions can be accessed from the host +For the :ref:`native sim board ` the flash partitions can be accessed from the host Linux system. By default the flash partitions are accessible through the directory *flash* diff --git a/samples/subsys/shell/fs/boards/native_posix.conf b/samples/subsys/shell/fs/boards/native_posix.conf deleted file mode 100644 index 80357cdf245..00000000000 --- a/samples/subsys/shell/fs/boards/native_posix.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FUSE_FS_ACCESS=y diff --git a/samples/subsys/shell/fs/boards/native_posix_64.conf b/samples/subsys/shell/fs/boards/native_posix_64.conf deleted file mode 100644 index 80357cdf245..00000000000 --- a/samples/subsys/shell/fs/boards/native_posix_64.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FUSE_FS_ACCESS=y diff --git a/samples/subsys/shell/fs/sample.yaml b/samples/subsys/shell/fs/sample.yaml index e66f984e929..2f30aad68bb 100644 --- a/samples/subsys/shell/fs/sample.yaml +++ b/samples/subsys/shell/fs/sample.yaml @@ -1,25 +1,30 @@ sample: description: FS shell sample name: FS shell +common: + tags: + - shell + - filesystem + harness: keyboard tests: sample.filesystem.shell: - tags: - - shell - - filesystem - harness: keyboard platform_allow: - reel_board - mimxrt1060_evk - mr_canhubk3 + - native_sim integration_platforms: - reel_board - + sample.filesystem.shell.fuse: + platform_allow: + - native_sim + extra_configs: + - CONFIG_FUSE_FS_ACCESS=y + # This test cannot be run in CI as we lack the fuse library + skip: true sample.filesystem.shell.flash_load: tags: - - shell - - filesystem - flash_load - harness: keyboard platform_allow: nrf52dk_nrf52832 extra_args: CONF_FILE=prj_flash_load.conf integration_platforms: From e2927426d109f624d262e0b7104d3a690599a3d3 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 15:08:43 +0100 Subject: [PATCH 3768/4498] samples shell_module: Replace native_posix w native_sim Replace native_posix with native_sim as the default integration platform. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/shell/shell_module/sample.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/subsys/shell/shell_module/sample.yaml b/samples/subsys/shell/shell_module/sample.yaml index 7aac79eac90..95ac36bc6b3 100644 --- a/samples/subsys/shell/shell_module/sample.yaml +++ b/samples/subsys/shell/shell_module/sample.yaml @@ -7,7 +7,7 @@ tests: harness: keyboard min_ram: 40 integration_platforms: - - native_posix + - native_sim - intel_socfpga_agilex5_socdk sample.shell.shell_module.usb: depends_on: usb_device @@ -20,14 +20,14 @@ tests: - OVERLAY_CONFIG="overlay-usb.conf" - DTC_OVERLAY_FILE="usb.overlay" integration_platforms: - - native_posix + - native_sim sample.shell.shell_module.minimal: filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") tags: shell harness: keyboard extra_args: CONF_FILE="prj_minimal.conf" integration_platforms: - - native_posix + - native_sim sample.shell.shell_module.getopt: integration_platforms: - qemu_x86 @@ -51,7 +51,7 @@ tests: min_ram: 40 extra_args: CONF_FILE="prj_login.conf" integration_platforms: - - native_posix + - native_sim sample.shell.shell_module.robot: harness: robot harness_config: From 78eebda134fa06dfae2f23dd759f68527a1f6ef9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 15 Nov 2023 15:10:31 +0100 Subject: [PATCH 3769/4498] samples shell/devmem_load: Replace native_posix w native_sim In the docs replace references to native_posix with native_sim Switch the default test platform to native_sim from native_posix Signed-off-by: Alberto Escolar Piedras --- samples/subsys/shell/devmem_load/README.md | 2 +- samples/subsys/shell/devmem_load/sample.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/subsys/shell/devmem_load/README.md b/samples/subsys/shell/devmem_load/README.md index e4c457bf6a9..98b4059dcaf 100644 --- a/samples/subsys/shell/devmem_load/README.md +++ b/samples/subsys/shell/devmem_load/README.md @@ -20,7 +20,7 @@ west flash Building for boards without UART interrupt support: ```bash -west build -b native_posix -- -DOVERLAY_CONFIG=prj_poll.conf samples/subsys/shell/devmem_load +west build -b native_sim -- -DOVERLAY_CONFIG=prj_poll.conf samples/subsys/shell/devmem_load ``` ## Running After connecting to the UART console you should see the following output: diff --git a/samples/subsys/shell/devmem_load/sample.yaml b/samples/subsys/shell/devmem_load/sample.yaml index eca1e1f65cd..2d59490a0eb 100644 --- a/samples/subsys/shell/devmem_load/sample.yaml +++ b/samples/subsys/shell/devmem_load/sample.yaml @@ -9,7 +9,7 @@ common: tests: sample.devmem_load.polled: integration_platforms: - - native_posix + - native_sim extra_args: OVERLAY_CONFIG="prj_poll.conf" sample.devmem_load.uart.interrupt: integration_platforms: From 958cd4ff53982175a74041abda01694fdc381c92 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 6 Nov 2023 23:31:44 +0000 Subject: [PATCH 3770/4498] input: kbd_matrix,npcx: drop explicit LOG_LEVEL define Use the LOG_MODULE_REGISTER argument instead. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 3 +-- drivers/input/input_npcx_kbd.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index f4c49d29d51..9c73296ec8a 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -13,8 +13,7 @@ #include #include -#define LOG_LEVEL CONFIG_INPUT_LOG_LEVEL -LOG_MODULE_REGISTER(input_kbd_matrix); +LOG_MODULE_REGISTER(input_kbd_matrix, CONFIG_INPUT_LOG_LEVEL); #define INPUT_KBD_MATRIX_ROW_MASK UINT8_MAX diff --git a/drivers/input/input_npcx_kbd.c b/drivers/input/input_npcx_kbd.c index e703bd65f3f..64cde93bda9 100644 --- a/drivers/input/input_npcx_kbd.c +++ b/drivers/input/input_npcx_kbd.c @@ -18,8 +18,7 @@ #include #include -#define LOG_LEVEL CONFIG_INPUT_LOG_LEVEL -LOG_MODULE_REGISTER(input_npcx_kbd); +LOG_MODULE_REGISTER(input_npcx_kbd, CONFIG_INPUT_LOG_LEVEL); #define ROW_SIZE DT_INST_PROP(0, row_size) From c639ab8e5709b95654f6b85cdbe599b852c892d4 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 11:03:06 +0000 Subject: [PATCH 3771/4498] input: kbd_matrix: clean debug logs Tweak a couple of debug log entries. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 9c73296ec8a..16c0d8b0a31 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -197,7 +197,8 @@ static bool input_kbd_matrix_check_key_events(const struct device *dev) key_pressed = input_kbd_matrix_scan(dev); for (int c = 0; c < cfg->col_size; c++) { - LOG_DBG("U%x, P%x, N%x", + LOG_DBG("c=%2d u=%02x p=%02x n=%02x", + c, cfg->matrix_unstable_state[c], cfg->matrix_previous_state[c], cfg->matrix_new_state[c]); @@ -273,7 +274,7 @@ static void input_kbd_matrix_polling_thread(void *arg1, void *unused2, void *unu api->set_detect_mode(dev, true); k_sem_take(&data->poll_lock, K_FOREVER); - LOG_DBG("Start KB scan"); + LOG_DBG("scan start"); /* Disable interrupt of KSI pins and start polling */ api->set_detect_mode(dev, false); From 2cf9d32b29288110b94a518a1bbd4cb554094456 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 11:04:37 +0000 Subject: [PATCH 3772/4498] input: kbd_matrix: use CLAMP instead of two ifs Replace the wait_period_us clamping functions using a single CLAMP, reposition the debug log as well. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 16c0d8b0a31..2518df1291f 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -12,6 +12,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(input_kbd_matrix, CONFIG_INPUT_LOG_LEVEL); @@ -239,20 +240,10 @@ static void input_kbd_matrix_poll(const struct device *dev) cycles_diff = current_cycles - start_period_cycles; wait_period_us = cfg->poll_period_us - k_cyc_to_us_floor32(cycles_diff); - /* Wait for at least 1ms */ - if (wait_period_us < USEC_PER_MSEC) { - wait_period_us = USEC_PER_MSEC; - } + wait_period_us = CLAMP(wait_period_us, + USEC_PER_MSEC, cfg->poll_period_us); - /* - * Wait period results in a larger number when current cycles - * counter wrap. In this case, the whole poll period is used - */ - if (wait_period_us > cfg->poll_period_us) { - LOG_DBG("wait_period_us: %u", wait_period_us); - - wait_period_us = cfg->poll_period_us; - } + LOG_DBG("wait_period_us: %d", wait_period_us); /* Allow other threads to run while we sleep */ k_usleep(wait_period_us); From eaac842b82013ecb764b5b5f4c901eb704d7d824 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 11:05:39 +0000 Subject: [PATCH 3773/4498] input: kbd_matrix: move scan_cycles_idx increment Move the scan_cycles_idx increment in input_kbd_matrix_update_state as it's only used there, use a modulo operation rather than the if to handle the index wrapping condition. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 2518df1291f..0b44677f2be 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -182,18 +182,15 @@ static void input_kbd_matrix_update_state(const struct device *dev) input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); } } + + data->scan_cycles_idx = (data->scan_cycles_idx + 1) % INPUT_KBD_MATRIX_SCAN_OCURRENCES; } static bool input_kbd_matrix_check_key_events(const struct device *dev) { const struct input_kbd_matrix_common_config *cfg = dev->config; - struct input_kbd_matrix_common_data *data = dev->data; bool key_pressed; - if (++data->scan_cycles_idx >= INPUT_KBD_MATRIX_SCAN_OCURRENCES) { - data->scan_cycles_idx = 0U; - } - /* Scan the matrix */ key_pressed = input_kbd_matrix_scan(dev); From 716281b5c9084421df79d4c99c8abe20cd99704e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 11:07:57 +0000 Subject: [PATCH 3774/4498] input: kbd_matrix: move few assignment off the declaration area Move a couple of automatic variable assignment off the declaration block, leaves only structure aliases there, makes it a bit easier to read. Signed-off-by: Fabio Baltieri --- drivers/input/input_kbd_matrix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 0b44677f2be..6005a76b3b3 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -98,10 +98,12 @@ static void input_kbd_matrix_update_state(const struct device *dev) const struct input_kbd_matrix_common_config *cfg = dev->config; struct input_kbd_matrix_common_data *data = dev->data; uint8_t *matrix_new_state = cfg->matrix_new_state; - uint32_t cycles_now = k_cycle_get_32(); + uint32_t cycles_now; uint8_t row_changed; uint8_t deb_col; + cycles_now = k_cycle_get_32(); + data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now; /* @@ -215,11 +217,13 @@ static bool input_kbd_matrix_check_key_events(const struct device *dev) static void input_kbd_matrix_poll(const struct device *dev) { const struct input_kbd_matrix_common_config *cfg = dev->config; - k_timepoint_t poll_time_end = sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms)); + k_timepoint_t poll_time_end; uint32_t current_cycles; uint32_t cycles_diff; uint32_t wait_period_us; + poll_time_end = sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms)); + while (true) { uint32_t start_period_cycles = k_cycle_get_32(); From 3452f9fa4ef4afc32a5a9306a2dc34c7669e72db Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 15:27:11 +0000 Subject: [PATCH 3775/4498] input: it8xxx2_kbd: drop unnecessary include Drop the atomic.h included, this does not use any atomic anymore. Signed-off-by: Fabio Baltieri --- drivers/input/input_ite_it8xxx2_kbd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/input_ite_it8xxx2_kbd.c b/drivers/input/input_ite_it8xxx2_kbd.c index 6f16fba1d6e..8d688d42db1 100644 --- a/drivers/input/input_ite_it8xxx2_kbd.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -16,7 +16,6 @@ #include #include #include -#include #include LOG_MODULE_REGISTER(input_ite_it8xxx2_kbd); From bf2f06587642302bf38eef87bb3ffd07ba1eeef9 Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Wed, 15 Nov 2023 16:16:24 +0100 Subject: [PATCH 3776/4498] Bluetooth: Host: Remove ifdef around `sc_indicate` Instead, `sc_indicate` is defined as a no-op when if would previously not be defined. Signed-off-by: Aleksander Wasaznik --- subsys/bluetooth/host/gatt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 11c292f159e..103229ea245 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -854,9 +854,7 @@ static void db_hash_gen(void) atomic_set_bit(gatt_sc.flags, DB_HASH_VALID); } -#if defined(CONFIG_BT_SETTINGS) static void sc_indicate(uint16_t start, uint16_t end); -#endif static void do_db_hash(void) { @@ -1515,10 +1513,10 @@ void bt_gatt_init(void) #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */ } -#if defined(CONFIG_BT_GATT_DYNAMIC_DB) || \ - (defined(CONFIG_BT_GATT_CACHING) && defined(CONFIG_BT_SETTINGS)) static void sc_indicate(uint16_t start, uint16_t end) { +#if defined(CONFIG_BT_GATT_DYNAMIC_DB) || \ + (defined(CONFIG_BT_GATT_CACHING) && defined(CONFIG_BT_SETTINGS)) LOG_DBG("start 0x%04x end 0x%04x", start, end); if (!atomic_test_and_set_bit(gatt_sc.flags, SC_RANGE_CHANGED)) { @@ -1539,8 +1537,8 @@ static void sc_indicate(uint16_t start, uint16_t end) /* Reschedule since the range has changed */ sc_work_submit(SC_TIMEOUT); -} #endif /* BT_GATT_DYNAMIC_DB || (BT_GATT_CACHING && BT_SETTINGS) */ +} void bt_gatt_cb_register(struct bt_gatt_cb *cb) { @@ -5757,14 +5755,12 @@ void bt_gatt_encrypt_change(struct bt_conn *conn) bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data); -#if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_GATT_SERVICE_CHANGED) if (!bt_gatt_change_aware(conn, false)) { /* Send a Service Changed indication if the current peer is * marked as change-unaware. */ sc_indicate(0x0001, 0xffff); } -#endif /* CONFIG_BT_SETTINGS && CONFIG_BT_GATT_SERVICE_CHANGED */ } bool bt_gatt_change_aware(struct bt_conn *conn, bool req) From fef999c06f892418d8238700335ea27f6d3b418f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 9 Nov 2023 13:56:06 +0100 Subject: [PATCH 3777/4498] llext: (cosmetic) remove "inline" in llext.c Let the compiler decide which functions to inline. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index fcaa2317c41..f7b0885ece5 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -213,7 +213,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) return 0; } -static inline enum llext_section llext_sect_from_mem(enum llext_mem m) +static enum llext_section llext_sect_from_mem(enum llext_mem m) { enum llext_section s; @@ -370,7 +370,7 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) return 0; } -static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) +static int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) { int ret = 0; size_t syms_size = ldr->sym_cnt * sizeof(struct llext_symbol); @@ -384,7 +384,7 @@ static inline int llext_allocate_symtab(struct llext_loader *ldr, struct llext * return ret; } -static inline int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) +static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) { size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; From 60aef84cad218c60cb58f17ce800cb7c137a6565 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 9 Nov 2023 14:06:03 +0100 Subject: [PATCH 3778/4498] llext: (cosmetic) use a local variable Simplify llext_copy_symbols() by using a local variable to store a pointer. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index f7b0885ece5..772abb386a6 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -374,11 +374,11 @@ static int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) { int ret = 0; size_t syms_size = ldr->sym_cnt * sizeof(struct llext_symbol); + struct llext_symtable *sym_tab = &ext->sym_tab; - ext->sym_tab.syms = k_heap_alloc(&llext_heap, syms_size, - K_NO_WAIT); - ext->sym_tab.sym_cnt = ldr->sym_cnt; - memset(ext->sym_tab.syms, 0, ldr->sym_cnt * sizeof(struct llext_symbol)); + sym_tab->syms = k_heap_alloc(&llext_heap, syms_size, K_NO_WAIT); + sym_tab->sym_cnt = ldr->sym_cnt; + memset(sym_tab->syms, 0, ldr->sym_cnt * sizeof(struct llext_symbol)); ext->mem_size += syms_size; return ret; @@ -389,6 +389,7 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) size_t ent_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_entsize; size_t syms_size = ldr->sects[LLEXT_SECT_SYMTAB].sh_size; int sym_cnt = syms_size / sizeof(elf_sym_t); + struct llext_symtable *sym_tab = &ext->sym_tab; elf_sym_t sym; int i, j, ret; size_t pos; @@ -418,12 +419,14 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) { const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); - ext->sym_tab.syms[j].name = name; - ext->sym_tab.syms[j].addr = + __ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j); + + sym_tab->syms[j].name = name; + sym_tab->syms[j].addr = (void *)((uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]] + sym.st_value); LOG_DBG("function symbol %d name %s addr %p", - j, name, ext->sym_tab.syms[j].addr); + j, name, sym_tab->syms[j].addr); j++; } } From db43d35f617a581b6c2952847a82a504e750eb87 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 9 Nov 2023 15:11:26 +0100 Subject: [PATCH 3779/4498] llext: (cosmetic) remove an unused variable op_code in llext_link() is unused, remove it. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 772abb386a6..428c142454d 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -517,7 +517,7 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) rel.r_offset, name, ELF_ST_TYPE(sym.st_info), ELF_ST_BIND(sym.st_info), sym.st_shndx); - uintptr_t link_addr, op_loc, op_code; + uintptr_t link_addr, op_loc; op_loc = loc + rel.r_offset; @@ -530,11 +530,6 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) "symbol table %s, offset %d, link section %d", name, rel.r_offset, shdr.sh_link); return -ENODATA; - } else { - op_code = (uintptr_t)(loc + rel.r_offset); - - LOG_INF("found symbol %s at 0x%lx, updating op code 0x%lx", - name, link_addr, op_code); } } else if (ELF_ST_TYPE(sym.st_info) == STT_SECTION) { /* Current relocation location holds an offset into the section */ From fb92636056fa4e4a15ec914b1030f4fbc7639d8c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 9 Nov 2023 13:04:21 +0100 Subject: [PATCH 3780/4498] llext: remove a symbol count copy The symbol count in struct llext_loader is redundant, we already have one in struct llext_symtable, accessible via struct llext. Remove the redundant copy. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/loader.h | 1 - subsys/llext/llext.c | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index 915a6278a44..5bcfb1e908b 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -92,7 +92,6 @@ struct llext_loader { elf_shdr_t sects[LLEXT_SECT_COUNT]; uint32_t *sect_map; uint32_t sect_cnt; - uint32_t sym_cnt; /** @endcond */ }; diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 428c142454d..02ed0e17ed7 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -360,7 +360,7 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) if (stt == STT_FUNC && stb == STB_GLOBAL) { LOG_DBG("function symbol %d, name %s, type tag %d, bind %d, sect %d", i, name, stt, stb, sect); - ldr->sym_cnt++; + ext->sym_tab.sym_cnt++; } else { LOG_DBG("unhandled symbol %d, name %s, type tag %d, bind %d, sect %d", i, name, stt, stb, sect); @@ -372,16 +372,14 @@ static int llext_count_export_syms(struct llext_loader *ldr, struct llext *ext) static int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) { - int ret = 0; - size_t syms_size = ldr->sym_cnt * sizeof(struct llext_symbol); struct llext_symtable *sym_tab = &ext->sym_tab; + size_t syms_size = sym_tab->sym_cnt * sizeof(struct llext_symbol); sym_tab->syms = k_heap_alloc(&llext_heap, syms_size, K_NO_WAIT); - sym_tab->sym_cnt = ldr->sym_cnt; - memset(sym_tab->syms, 0, ldr->sym_cnt * sizeof(struct llext_symbol)); + memset(sym_tab->syms, 0, syms_size); ext->mem_size += syms_size; - return ret; + return 0; } static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) @@ -570,7 +568,6 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) memset(ldr->sects, 0, sizeof(ldr->sects)); ldr->sect_cnt = 0; - ldr->sym_cnt = 0; size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(uint32_t); From eb3071ebe8512e287f6e9294955784c4f7547178 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 9 Nov 2023 13:48:16 +0100 Subject: [PATCH 3781/4498] llext: check for an allocation failure Add a missing allocation failure check in llext_export_symbols(). Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 02ed0e17ed7..6c85a633072 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -376,6 +376,9 @@ static int llext_allocate_symtab(struct llext_loader *ldr, struct llext *ext) size_t syms_size = sym_tab->sym_cnt * sizeof(struct llext_symbol); sym_tab->syms = k_heap_alloc(&llext_heap, syms_size, K_NO_WAIT); + if (!sym_tab->syms) { + return -ENOMEM; + } memset(sym_tab->syms, 0, syms_size); ext->mem_size += syms_size; From 21cea07b8c97674032b1457f8430e80a5d4bcdc4 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 14 Nov 2023 12:51:27 +0100 Subject: [PATCH 3782/4498] llext: fix a confusion between section indices A common pattern is used throughout llext.c: ext->mem[ldr->sect_map[sym.st_shndx]] where ldr->sect_map[sym.st_shndx] actually contains indices from enum llext_section but ext->mem[] is indexed, using enum llext_mem values. Fix this by changing ldr->sect_map[] to actually contain enum llext_mem values. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 1 + include/zephyr/llext/loader.h | 4 +++- subsys/llext/llext.c | 25 +++++++++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index e0ceece0cf8..a4458a05468 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -33,6 +33,7 @@ enum llext_mem { LLEXT_MEM_DATA, LLEXT_MEM_RODATA, LLEXT_MEM_BSS, + LLEXT_MEM_SYMTAB, LLEXT_MEM_STRTAB, LLEXT_MEM_SHSTRTAB, diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index 5bcfb1e908b..3cc53da7d88 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -42,6 +42,8 @@ enum llext_section { LLEXT_SECT_COUNT, }; +enum llext_mem; + /** * @brief Linkable loadable extension loader context */ @@ -90,7 +92,7 @@ struct llext_loader { /** @cond ignore */ elf_ehdr_t hdr; elf_shdr_t sects[LLEXT_SECT_COUNT]; - uint32_t *sect_map; + enum llext_mem *sect_map; uint32_t sect_cnt; /** @endcond */ }; diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 6c85a633072..84c38765d95 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -128,18 +128,18 @@ static int llext_find_tables(struct llext_loader *ldr) case SHT_DYNSYM: LOG_DBG("symtab at %d", i); ldr->sects[LLEXT_SECT_SYMTAB] = shdr; - ldr->sect_map[i] = LLEXT_SECT_SYMTAB; + ldr->sect_map[i] = LLEXT_MEM_SYMTAB; sect_cnt++; break; case SHT_STRTAB: if (ldr->hdr.e_shstrndx == i) { LOG_DBG("shstrtab at %d", i); ldr->sects[LLEXT_SECT_SHSTRTAB] = shdr; - ldr->sect_map[i] = LLEXT_SECT_SHSTRTAB; + ldr->sect_map[i] = LLEXT_MEM_SHSTRTAB; } else { LOG_DBG("strtab at %d", i); ldr->sects[LLEXT_SECT_STRTAB] = shdr; - ldr->sect_map[i] = LLEXT_SECT_STRTAB; + ldr->sect_map[i] = LLEXT_MEM_STRTAB; } sect_cnt++; break; @@ -192,22 +192,27 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) LOG_DBG("section %d name %s", i, name); enum llext_section sect_idx; + enum llext_mem mem_idx; if (strcmp(name, ".text") == 0) { sect_idx = LLEXT_SECT_TEXT; + mem_idx = LLEXT_MEM_TEXT; } else if (strcmp(name, ".data") == 0) { sect_idx = LLEXT_SECT_DATA; + mem_idx = LLEXT_MEM_DATA; } else if (strcmp(name, ".rodata") == 0) { sect_idx = LLEXT_SECT_RODATA; + mem_idx = LLEXT_MEM_RODATA; } else if (strcmp(name, ".bss") == 0) { sect_idx = LLEXT_SECT_BSS; + mem_idx = LLEXT_MEM_BSS; } else { LOG_DBG("Not copied section %s", name); continue; } ldr->sects[sect_idx] = shdr; - ldr->sect_map[i] = sect_idx; + ldr->sect_map[i] = mem_idx; } return 0; @@ -230,6 +235,9 @@ static enum llext_section llext_sect_from_mem(enum llext_mem m) case LLEXT_MEM_TEXT: s = LLEXT_SECT_TEXT; break; + case LLEXT_MEM_SYMTAB: + s = LLEXT_SECT_SYMTAB; + break; case LLEXT_MEM_STRTAB: s = LLEXT_SECT_STRTAB; break; @@ -415,17 +423,18 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) uint32_t stt = ELF_ST_TYPE(sym.st_info); uint32_t stb = ELF_ST_BIND(sym.st_info); - uint32_t sect = sym.st_shndx; + unsigned int sect = sym.st_shndx; if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) { + enum llext_mem mem = ldr->sect_map[sect]; + enum llext_section sect_idx = llext_sect_from_mem(mem); const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); __ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j); sym_tab->syms[j].name = name; - sym_tab->syms[j].addr = - (void *)((uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]] - + sym.st_value); + sym_tab->syms[j].addr = (void *)((uintptr_t)ext->mem[mem] + + sym.st_value); LOG_DBG("function symbol %d name %s addr %p", j, name, sym_tab->syms[j].addr); j++; From e0ea44cbfa6003c29a1dff785c3d629fda0324cd Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 28 Sep 2023 13:56:54 +0200 Subject: [PATCH 3783/4498] llext: fix symbol address calculation for ET_DYN Symbopl tables of ELF objects of type ET_REL contain offsets instead of addresses as for ET_DYN. Signed-off-by: Guennadi Liakhovetski --- subsys/llext/llext.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 84c38765d95..3d99c8af4fa 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -433,8 +433,10 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) __ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j); sym_tab->syms[j].name = name; - sym_tab->syms[j].addr = (void *)((uintptr_t)ext->mem[mem] - + sym.st_value); + sym_tab->syms[j].addr = (void *)((uintptr_t)ext->mem[mem] + + sym.st_value - + (ldr->hdr.e_type == ET_REL ? 0 : + ldr->sects[sect_idx].sh_addr)); LOG_DBG("function symbol %d name %s addr %p", j, name, sym_tab->syms[j].addr); j++; From 530e845f927caa7c2f19aa172f2dbafbf1c731a7 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Thu, 16 Nov 2023 09:00:43 +0100 Subject: [PATCH 3784/4498] Revert "Bluetooth: att: don't re-use the ATT buffer for confirmations" This reverts commit 4cd0748a407b118145916393a954231ee11abb1e. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/att.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index cb8c17983cb..aa7cab49f07 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -677,12 +677,10 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t switch (att_op_get_type(op)) { case ATT_RESPONSE: - /* Use a timeout only when responding */ - timeout = BT_ATT_TIMEOUT; - re_use = true; - break; case ATT_CONFIRMATION: + /* Use a timeout only when responding/confirming */ timeout = BT_ATT_TIMEOUT; + re_use = true; break; default: timeout = K_FOREVER; @@ -710,7 +708,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t * This is better than an assert as an assert would * allow a peer to DoS us. */ - LOG_ERR("already processing a REQ/RSP on chan %p", chan); + LOG_ERR("already processing a transaction on chan %p", chan); return NULL; } From bd9c35b4966bf56d908c3416ab2c192781f37ed8 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Thu, 16 Nov 2023 09:01:35 +0100 Subject: [PATCH 3785/4498] Revert "Bluetooth: att: re-use REQ buf for RSP" This reverts commit aa7954bd4725bbd46e974a03c0d0312b7e9a483f. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/att.c | 65 +++++---------------------- subsys/bluetooth/host/buf.c | 5 +-- subsys/bluetooth/host/conn_internal.h | 11 +++++ subsys/bluetooth/host/hci_core.c | 28 +++++------- 4 files changed, 36 insertions(+), 73 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index aa7cab49f07..031396fa34d 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -103,7 +103,6 @@ struct bt_att_chan { ATOMIC_DEFINE(flags, ATT_NUM_FLAGS); struct bt_att_req *req; struct k_fifo tx_queue; - struct net_buf *rsp_buf; struct bt_att_tx_meta_data rsp_meta; struct k_work_delayable timeout_work; sys_snode_t node; @@ -667,7 +666,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t struct net_buf *buf; struct bt_att_tx_meta_data *data; k_timeout_t timeout; - bool re_use = false; + bool is_rsp = false; if (len + sizeof(op) > bt_att_mtu(chan)) { LOG_WRN("ATT MTU exceeded, max %u, wanted %zu", bt_att_mtu(chan), @@ -680,23 +679,19 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t case ATT_CONFIRMATION: /* Use a timeout only when responding/confirming */ timeout = BT_ATT_TIMEOUT; - re_use = true; + is_rsp = true; break; default: timeout = K_FOREVER; } - if (IS_ENABLED(CONFIG_BT_GATT_READ_MULTIPLE) && - (op == BT_ATT_OP_READ_MULT_RSP || - op == BT_ATT_OP_READ_MULT_VL_RSP)) { - /* We can't re-use the REQ buffer (see below) for these two - * opcodes, as the handler will read from it _after_ allocating - * the RSP buffer. - */ - re_use = false; + buf = bt_l2cap_create_pdu_timeout(NULL, 0, timeout); + if (!buf) { + LOG_ERR("Unable to allocate buffer for op 0x%02x", op); + return NULL; } - if (re_use) { + if (is_rsp) { /* There can only ever be one transaction at a time on a * bearer/channel. Use a dedicated channel meta-data to ensure * we can always queue an (error) RSP for each REQ. The ATT @@ -713,27 +708,8 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t return NULL; } data = &chan->rsp_meta; - - /* Re-use REQ buf to avoid dropping the REQ and timing out. - * This only works if the bearer used to RX REQs is the same as - * for sending the RSP. That should always be the case - * (per-spec). - */ - __ASSERT_NO_MSG(chan->rsp_buf); - buf = net_buf_ref(chan->rsp_buf); - - net_buf_reset(buf); - net_buf_reserve(buf, BT_L2CAP_BUF_SIZE(0)); - - LOG_DBG("re-using REQ buf %p for RSP", buf); + LOG_INF("alloc rsp meta"); } else { - LOG_DBG("alloc buf & meta from global pools"); - buf = bt_l2cap_create_pdu_timeout(NULL, 0, timeout); - if (!buf) { - LOG_ERR("Unable to allocate buffer for op 0x%02x", op); - return NULL; - } - data = tx_meta_data_alloc(timeout); if (!data) { LOG_WRN("Unable to allocate ATT TX meta"); @@ -817,7 +793,6 @@ static void send_err_rsp(struct bt_att_chan *chan, uint8_t req, uint16_t handle, buf = bt_att_chan_create_pdu(chan, BT_ATT_OP_ERROR_RSP, sizeof(*rsp)); if (!buf) { - LOG_ERR("unable to allocate buf for error response"); return; } @@ -2916,20 +2891,6 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) } } - /* Thread-local variable, shouldn't be used by anything else */ - __ASSERT_NO_MSG(!att_chan->rsp_buf); - - /* Mark buffer free for re-use by the opcode handler. - * - * This allows ATT to always be able to send a RSP (or err RSP) - * to the peer, regardless of the TX buffer usage by other stack - * users (e.g. GATT notifications, L2CAP using global pool, SMP, - * etc..), avoiding an ATT timeout due to resource usage. - * - * The ref is taken by `bt_att_chan_create_pdu`. - */ - att_chan->rsp_buf = net_buf_ref(buf); - if (!handler) { LOG_WRN("Unhandled ATT code 0x%02x", hdr->code); if (att_op_get_type(hdr->code) != ATT_COMMAND && @@ -2937,19 +2898,19 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) send_err_rsp(att_chan, hdr->code, 0, BT_ATT_ERR_NOT_SUPPORTED); } - goto exit; + return 0; } if (IS_ENABLED(CONFIG_BT_ATT_ENFORCE_FLOW)) { if (handler->type == ATT_REQUEST && atomic_test_and_set_bit(att_chan->flags, ATT_PENDING_RSP)) { LOG_WRN("Ignoring unexpected request"); - goto exit; + return 0; } else if (handler->type == ATT_INDICATION && atomic_test_and_set_bit(att_chan->flags, ATT_PENDING_CFM)) { LOG_WRN("Ignoring unexpected indication"); - goto exit; + return 0; } } @@ -2965,10 +2926,6 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) send_err_rsp(att_chan, hdr->code, 0, err); } -exit: - net_buf_unref(att_chan->rsp_buf); - att_chan->rsp_buf = NULL; - return 0; } diff --git a/subsys/bluetooth/host/buf.c b/subsys/bluetooth/host/buf.c index ff9620766fe..50b567d31b7 100644 --- a/subsys/bluetooth/host/buf.c +++ b/subsys/bluetooth/host/buf.c @@ -43,15 +43,14 @@ NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT, #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BT_BUF_ACL_RX_COUNT, BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE), - MAX(sizeof(struct bt_buf_data), CONFIG_BT_CONN_TX_USER_DATA_SIZE), - bt_hci_host_num_completed_packets); + sizeof(struct acl_data), bt_hci_host_num_completed_packets); NET_BUF_POOL_FIXED_DEFINE(evt_pool, CONFIG_BT_BUF_EVT_RX_COUNT, BT_BUF_EVT_RX_SIZE, 8, NULL); #else NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT, - BT_BUF_RX_SIZE, CONFIG_BT_CONN_TX_USER_DATA_SIZE, + BT_BUF_RX_SIZE, 8, NULL); #endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index e3fd60da34e..7741e259a61 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -146,6 +146,17 @@ struct bt_conn_tx { uint32_t pending_no_cb; }; +struct acl_data { + /* Extend the bt_buf user data */ + struct bt_buf_data buf_data; + + /* Index into the bt_conn storage array */ + uint8_t index; + + /** ACL connection handle */ + uint16_t handle; +}; + struct bt_conn { uint16_t handle; enum bt_conn_type type; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 51f9ac8d211..de4fb637b49 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -111,16 +111,8 @@ struct cmd_data { static struct cmd_data cmd_data[CONFIG_BT_BUF_CMD_TX_COUNT]; -#if defined(CONFIG_BT_CONN) -struct acl_data { - uint16_t acl_handle; -}; - -static struct acl_data acl_data[CONFIG_BT_BUF_ACL_RX_COUNT]; -#endif - #define cmd(buf) (&cmd_data[net_buf_id(buf)]) -#define acl(buf) (&acl_data[net_buf_id(buf)]) +#define acl(buf) ((struct acl_data *)net_buf_user_data(buf)) void bt_hci_cmd_state_set_init(struct net_buf *buf, struct bt_hci_cmd_state_set *state, @@ -209,9 +201,10 @@ void bt_hci_host_num_completed_packets(struct net_buf *buf) { struct bt_hci_cp_host_num_completed_packets *cp; - uint16_t handle = acl(buf)->acl_handle; + uint16_t handle = acl(buf)->handle; struct bt_hci_handle_count *hc; struct bt_conn *conn; + uint8_t index = acl(buf)->index; net_buf_destroy(buf); @@ -220,9 +213,9 @@ void bt_hci_host_num_completed_packets(struct net_buf *buf) return; } - conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL); + conn = bt_conn_lookup_index(index); if (!conn) { - LOG_WRN("Unable to look up conn with ACL handle %u", handle); + LOG_WRN("Unable to look up conn with index 0x%02x", index); return; } @@ -519,9 +512,10 @@ static void hci_acl(struct net_buf *buf) handle = sys_le16_to_cpu(hdr->handle); flags = bt_acl_flags(handle); - acl(buf)->acl_handle = bt_acl_handle(handle); + acl(buf)->handle = bt_acl_handle(handle); + acl(buf)->index = BT_CONN_INDEX_INVALID; - LOG_DBG("handle %u len %u flags %u", acl(buf)->acl_handle, len, flags); + LOG_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags); if (buf->len != len) { LOG_ERR("ACL data length mismatch (%u != %u)", buf->len, len); @@ -529,13 +523,15 @@ static void hci_acl(struct net_buf *buf) return; } - conn = bt_conn_lookup_handle(acl(buf)->acl_handle, BT_CONN_TYPE_ALL); + conn = bt_conn_lookup_handle(acl(buf)->handle, BT_CONN_TYPE_ALL); if (!conn) { - LOG_ERR("Unable to find conn for handle %u", acl(buf)->acl_handle); + LOG_ERR("Unable to find conn for handle %u", acl(buf)->handle); net_buf_unref(buf); return; } + acl(buf)->index = bt_conn_index(conn); + bt_conn_recv(conn, buf, flags); bt_conn_unref(conn); } From dfd762427066dfc7b5a140ec27e34b5c7d0f890a Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Thu, 16 Nov 2023 09:03:53 +0100 Subject: [PATCH 3786/4498] Revert "Bluetooth: att: use a dedicated metadata struct for RSP PDUs" This reverts commit 14858d96d87d33ebb593d61380f4607e14107287. Signed-off-by: Jonathan Rico --- subsys/bluetooth/host/att.c | 72 ++++++++++--------------------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 031396fa34d..130b4ab0853 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -83,18 +83,6 @@ enum { ATT_NUM_FLAGS, }; -struct bt_att_tx_meta_data { - struct bt_att_chan *att_chan; - uint16_t attr_count; - bt_gatt_complete_func_t func; - void *user_data; - enum bt_att_chan_opt chan_opt; -}; - -struct bt_att_tx_meta { - struct bt_att_tx_meta_data *data; -}; - /* ATT channel specific data */ struct bt_att_chan { /* Connection this channel is associated with */ @@ -103,7 +91,6 @@ struct bt_att_chan { ATOMIC_DEFINE(flags, ATT_NUM_FLAGS); struct bt_att_req *req; struct k_fifo tx_queue; - struct bt_att_tx_meta_data rsp_meta; struct k_work_delayable timeout_work; sys_snode_t node; }; @@ -172,6 +159,18 @@ static struct bt_att_req cancel; */ static k_tid_t att_handle_rsp_thread; +struct bt_att_tx_meta_data { + struct bt_att_chan *att_chan; + uint16_t attr_count; + bt_gatt_complete_func_t func; + void *user_data; + enum bt_att_chan_opt chan_opt; +}; + +struct bt_att_tx_meta { + struct bt_att_tx_meta_data *data; +}; + #define bt_att_tx_meta_data(buf) (((struct bt_att_tx_meta *)net_buf_user_data(buf))->data) static struct bt_att_tx_meta_data tx_meta_data[CONFIG_BT_CONN_TX_MAX]; @@ -193,22 +192,9 @@ static struct bt_att_tx_meta_data *tx_meta_data_alloc(k_timeout_t timeout) static inline void tx_meta_data_free(struct bt_att_tx_meta_data *data) { __ASSERT_NO_MSG(data); - bool alloc_from_global = PART_OF_ARRAY(tx_meta_data, data); - - if (data == &data->att_chan->rsp_meta) { - /* "Free-ness" is kept by remote: There can only ever be one - * transaction per-bearer. - */ - __ASSERT_NO_MSG(!alloc_from_global); - } else { - __ASSERT_NO_MSG(alloc_from_global); - } (void)memset(data, 0, sizeof(*data)); - - if (alloc_from_global) { - k_fifo_put(&free_att_tx_meta_data, data); - } + k_fifo_put(&free_att_tx_meta_data, data); } static int bt_att_chan_send(struct bt_att_chan *chan, struct net_buf *buf); @@ -666,7 +652,6 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t struct net_buf *buf; struct bt_att_tx_meta_data *data; k_timeout_t timeout; - bool is_rsp = false; if (len + sizeof(op) > bt_att_mtu(chan)) { LOG_WRN("ATT MTU exceeded, max %u, wanted %zu", bt_att_mtu(chan), @@ -679,7 +664,6 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t case ATT_CONFIRMATION: /* Use a timeout only when responding/confirming */ timeout = BT_ATT_TIMEOUT; - is_rsp = true; break; default: timeout = K_FOREVER; @@ -691,31 +675,11 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t return NULL; } - if (is_rsp) { - /* There can only ever be one transaction at a time on a - * bearer/channel. Use a dedicated channel meta-data to ensure - * we can always queue an (error) RSP for each REQ. The ATT - * module can then reschedule the RSP if it is not able to send - * it immediately. - */ - if (chan->rsp_meta.att_chan) { - /* Returning a NULL here will trigger an ATT timeout. - * This is better than an assert as an assert would - * allow a peer to DoS us. - */ - LOG_ERR("already processing a transaction on chan %p", chan); - - return NULL; - } - data = &chan->rsp_meta; - LOG_INF("alloc rsp meta"); - } else { - data = tx_meta_data_alloc(timeout); - if (!data) { - LOG_WRN("Unable to allocate ATT TX meta"); - net_buf_unref(buf); - return NULL; - } + data = tx_meta_data_alloc(timeout); + if (!data) { + LOG_WRN("Unable to allocate ATT TX meta"); + net_buf_unref(buf); + return NULL; } if (IS_ENABLED(CONFIG_BT_EATT)) { From 3b96c2421ee4b374cac813c6f2144711bc2982db Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Thu, 16 Nov 2023 11:16:24 +0100 Subject: [PATCH 3787/4498] MAINTAINERS: add the PLIC interrupt controller driver to the RISC-V area This commit adds the RISC-V Platform-Level Interrupt Controller driver to the RISC-V area of maintenance. Signed-off-by: Filip Kokosinski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 32a1d1efb54..aa4fbaadced 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2290,6 +2290,7 @@ RISCV arch: - soc/riscv/ - tests/arch/riscv/ - doc/hardware/arch/risc-v.rst + - drivers/interrupt_controller/intc_plic.c labels: - "area: RISCV" From 190f0dde266c222fd822030f4bc52b0e3d1a25dd Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 16:35:41 +0000 Subject: [PATCH 3788/4498] doc: migration-guide: annotate various entry with the PR numbers Add a PR number reference to various migration guide entries. Signed-off-by: Fabio Baltieri --- doc/releases/migration-guide-3.6.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index dfd3fdb3cf6..ddf42b6dc3a 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -26,7 +26,7 @@ Optional Modules The following modules have been made optional and are not downloaded with `west update` by default anymore: -* ``canopennode`` +* ``canopennode`` (:github:`64139`) To enable them again use the ``west config manifest.project-filter -- +`` command, or ``west config manifest.group-filter -- +optional`` to @@ -53,6 +53,8 @@ Device Drivers and Device Tree }; }; + (:github:`62994`) + Power Management ================ @@ -61,7 +63,7 @@ Bootloader * MCUboot's deprecated ``CONFIG_ZEPHYR_TRY_MASS_ERASE`` Kconfig option has been removed. If an erase is needed when flashing MCUboot, this should now be provided directly to the ``west`` - command e.g. ``west flash --erase``. + command e.g. ``west flash --erase``. (:github:`64703`) Bluetooth ========= @@ -71,15 +73,15 @@ Bluetooth :kconfig:option:`CONFIG_BT_HCI_IPC`, and the ``zephyr,bt-hci-rpmsg-ipc`` Devicetree chosen is now ``zephyr,bt-hci-ipc``. The existing sample has also been renamed, from ``samples/bluetooth/hci_rpmsg`` to - ``samples/bluetooth/hci_ipc``. + ``samples/bluetooth/hci_ipc``. (:github:`64391`) * The BT GATT callback list, appended to by :c:func:`bt_gatt_cb_register`, is no longer cleared on :c:func:`bt_enable`. Callbacks can now be registered before the initial call to :c:func:`bt_enable`, and should no longer be re-registered after a :c:func:`bt_disable` - :c:func:`bt_enable` cycle. + :c:func:`bt_enable` cycle. (:github:`63693`) * The Bluetooth Mesh ``model`` declaration has been changed to add prefix ``const``. The ``model->user_data``, ``model->elem_idx`` and ``model->mod_idx`` field has been changed to the new runtime structure, replaced by ``model->rt->user_data``, ``model->rt->elem_idx`` and - ``model->rt->mod_idx`` separately. + ``model->rt->mod_idx`` separately. (:github:`65152`) LoRaWAN ======= @@ -88,6 +90,7 @@ LoRaWAN renamed from ``lorawan_set_battery_level_callback`` to :c:func:`lorawan_register_battery_level_callback` and the return type is now ``void``. This is more consistent with similar functions for downlink and data rate changed callbacks. + (:github:`65103`) Networking ========== @@ -96,18 +99,19 @@ Networking :c:func:`coap_remove_observer` now returns a result if the observer was removed. This change is used by the newly introduced :ref:`coap_server_interface` subsystem. Also, the ``request`` argument for :c:func:`coap_well_known_core_get` is made ``const``. + (:github:`64265`) Other Subsystems ================ * MCUmgr applications that make use of serial transports (shell or UART) must now select :kconfig:option:`CONFIG_CRC`, this was previously erroneously selected if MCUmgr was enabled, - when for non-serial transports it was not needed. + when for non-serial transports it was not needed. (:github:`64078`) * Touchscreen drivers :dtcompatible:`focaltech,ft5336` and :dtcompatible:`goodix,gt911` were using the incorrect polarity for the respective ``reset-gpios``. This has been fixed so those signals now have to - be flagged as :c:macro:`GPIO_ACTIVE_LOW` in the devicetree. + be flagged as :c:macro:`GPIO_ACTIVE_LOW` in the devicetree. (:github:`64800`) Recommended Changes ******************* From f25e2201a4ca248348d3948dc1210ac7dbbe740d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 15 Nov 2023 14:20:03 +0000 Subject: [PATCH 3789/4498] tests: fix various test identifiers Fix a few inconsistent test identifiers. Signed-off-by: Anas Nashif --- samples/subsys/sensing/simple/sample.yaml | 2 +- samples/subsys/task_wdt/sample.yaml | 7 ++++--- tests/arch/arc/arc_dsp_sharing/testcase.yaml | 4 ++-- tests/arch/arm/arm_hardfault_validation/testcase.yaml | 2 +- tests/arch/arm/arm_interrupt/testcase.yaml | 6 +++--- tests/arch/arm/arm_runtime_nmi/testcase.yaml | 2 +- tests/drivers/build_all/can/testcase.yaml | 6 +++--- tests/drivers/build_all/fpga/testcase.yaml | 2 +- tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml | 2 +- tests/drivers/virtualization/ivshmem/plain/testcase.yaml | 2 +- tests/net/conn_mgr_conn/testcase.yaml | 2 +- tests/net/conn_mgr_monitor/testcase.yaml | 4 ++-- 12 files changed, 21 insertions(+), 20 deletions(-) diff --git a/samples/subsys/sensing/simple/sample.yaml b/samples/subsys/sensing/simple/sample.yaml index e8b33b417d9..de2508c0d49 100644 --- a/samples/subsys/sensing/simple/sample.yaml +++ b/samples/subsys/sensing/simple/sample.yaml @@ -11,7 +11,7 @@ common: regex: - "sensing subsystem run successfully" tests: - sample.subsys.sensing.simple: + sample.sensing.simple: platform_allow: - native_sim tags: sensing diff --git a/samples/subsys/task_wdt/sample.yaml b/samples/subsys/task_wdt/sample.yaml index 1c9c300a878..334d6e3a24f 100644 --- a/samples/subsys/task_wdt/sample.yaml +++ b/samples/subsys/task_wdt/sample.yaml @@ -1,8 +1,9 @@ sample: name: Task Watchdog Subsytem Sample common: - tags: subsys harness: console + tags: + - task_wdt harness_config: type: multi_line ordered: true @@ -19,10 +20,10 @@ common: - s32z270dc2_rtu0_r52 - s32z270dc2_rtu1_r52 tests: - sample.subsys.task_wdt: + sample.task_wdt: integration_platforms: - nucleo_g474re - sample.subsys.task_wdt.no_hw_fallback: + sample.task_wdt.no_hw_fallback: extra_args: CONF_FILE="prj_no_hw_fallback.conf" platform_allow: - mr_canhubk3 diff --git a/tests/arch/arc/arc_dsp_sharing/testcase.yaml b/tests/arch/arc/arc_dsp_sharing/testcase.yaml index 09ac8efa789..21cb221e059 100644 --- a/tests/arch/arc/arc_dsp_sharing/testcase.yaml +++ b/tests/arch/arc/arc_dsp_sharing/testcase.yaml @@ -1,8 +1,8 @@ tests: - dsp_sharing.test_load_store: + arch.arc.dsp_sharing.test_load_store: filter: CONFIG_ISA_ARCV2 and CONFIG_ARC_HAS_DSP platform_allow: nsim_em11d - dsp_sharing.test_calculation: + arch.arc.dsp_sharing.test_calculation: filter: CONFIG_ISA_ARCV2 and CONFIG_ARC_HAS_DSP toolchain_allow: arcmwdt platform_allow: nsim_em11d diff --git a/tests/arch/arm/arm_hardfault_validation/testcase.yaml b/tests/arch/arm/arm_hardfault_validation/testcase.yaml index 3294ff9c305..f65fbfdb32a 100644 --- a/tests/arch/arm/arm_hardfault_validation/testcase.yaml +++ b/tests/arch/arm/arm_hardfault_validation/testcase.yaml @@ -1,5 +1,5 @@ tests: - arch.interrupt.arm.hardfault_validation: + arch.arm.interrupt.hardfault_validation: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE and CONFIG_ARMV7_M_ARMV8_M_MAINLINE arch_allow: arm tags: arm diff --git a/tests/arch/arm/arm_interrupt/testcase.yaml b/tests/arch/arm/arm_interrupt/testcase.yaml index 9c92b947631..4895e2a90cc 100644 --- a/tests/arch/arm/arm_interrupt/testcase.yaml +++ b/tests/arch/arm/arm_interrupt/testcase.yaml @@ -7,16 +7,16 @@ common: ignore_faults: true arch_allow: arm tests: - arch.interrupt.arm: + arch.arm.interrupt: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE - arch.interrupt.no_optimizations: + arch.arm.interrupt.no_optimizations: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE extra_configs: - CONFIG_NO_OPTIMIZATIONS=y - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_IDLE_STACK_SIZE=512 - CONFIG_MAIN_STACK_SIZE=2048 - arch.interrupt.extra_exception_info: + arch.arm.interrupt.extra_exception_info: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE extra_configs: - CONFIG_EXTRA_EXCEPTION_INFO=y diff --git a/tests/arch/arm/arm_runtime_nmi/testcase.yaml b/tests/arch/arm/arm_runtime_nmi/testcase.yaml index 34e95fe6f74..55706b0fedd 100644 --- a/tests/arch/arm/arm_runtime_nmi/testcase.yaml +++ b/tests/arch/arm/arm_runtime_nmi/testcase.yaml @@ -1,5 +1,5 @@ tests: - arch.interrupt.arm.nmi: + arch.arm.interrupt.nmi: filter: CONFIG_ARMV6_M_ARMV8_M_BASELINE or CONFIG_ARMV7_M_ARMV8_M_MAINLINE and not CONFIG_BUILD_WITH_TFM arch_allow: arm diff --git a/tests/drivers/build_all/can/testcase.yaml b/tests/drivers/build_all/can/testcase.yaml index 749da969f76..c276b24c652 100644 --- a/tests/drivers/build_all/can/testcase.yaml +++ b/tests/drivers/build_all/can/testcase.yaml @@ -4,18 +4,18 @@ common: - drivers - can tests: - drivers.build_all.can.mcp2515: + drivers.can.build_all.mcp2515: depends_on: - arduino_spi - arduino_gpio extra_args: SHIELD=dfrobot_can_bus_v2_0 platform_allow: frdm_k64f - drivers.build_all.can.tcan4x5x: + drivers.can.build_all.tcan4x5x: depends_on: - arduino_spi - arduino_gpio extra_args: SHIELD=tcan4550evm platform_allow: frdm_k64f - drivers.build_all.can.mcp251xfd: + drivers.can.build_all.mcp251xfd: extra_args: SHIELD=mikroe_mcp2518fd_click platform_allow: lpcxpresso55s28 diff --git a/tests/drivers/build_all/fpga/testcase.yaml b/tests/drivers/build_all/fpga/testcase.yaml index 75821c7a1a7..33cccf76dde 100644 --- a/tests/drivers/build_all/fpga/testcase.yaml +++ b/tests/drivers/build_all/fpga/testcase.yaml @@ -5,5 +5,5 @@ common: platform_allow: native_posix build_only: true tests: - fpga.build: + drivers.fpga.build: tags: fpga diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml b/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml index c4512d95326..9411b3d83ff 100644 --- a/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml +++ b/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml @@ -1,3 +1,3 @@ tests: - net.eth_ivshmem_queue: + net.ethernet.eth_ivshmem_queue: platform_allow: qemu_cortex_a53 diff --git a/tests/drivers/virtualization/ivshmem/plain/testcase.yaml b/tests/drivers/virtualization/ivshmem/plain/testcase.yaml index 37208f9367f..26330e1b133 100644 --- a/tests/drivers/virtualization/ivshmem/plain/testcase.yaml +++ b/tests/drivers/virtualization/ivshmem/plain/testcase.yaml @@ -1,5 +1,5 @@ tests: - virtualization.ivshmem: + drivers.virtualization.ivshmem: arch_allow: - x86 - arm64 diff --git a/tests/net/conn_mgr_conn/testcase.yaml b/tests/net/conn_mgr_conn/testcase.yaml index 07bb325cb0a..ff78e1dc721 100644 --- a/tests/net/conn_mgr_conn/testcase.yaml +++ b/tests/net/conn_mgr_conn/testcase.yaml @@ -2,7 +2,7 @@ common: min_ram: 16 depends_on: netif tests: - net.conn_mgr_conn: + net.conn_mgr.conn: tags: - net - iface diff --git a/tests/net/conn_mgr_monitor/testcase.yaml b/tests/net/conn_mgr_monitor/testcase.yaml index 64ce1efacec..ac6b5ad3c61 100644 --- a/tests/net/conn_mgr_monitor/testcase.yaml +++ b/tests/net/conn_mgr_monitor/testcase.yaml @@ -3,9 +3,9 @@ common: depends_on: netif tags: net iface tests: - net.conn_mgr_nodad: + net.conn_mgr.nodad: extra_configs: - CONFIG_NET_IPV6_DAD=n - net.conn_mgr_dad: + net.conn_mgr.dad: extra_configs: - CONFIG_NET_IPV6_DAD=y From 968916572c01165115abb370241d315ab3fbb106 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 16 Nov 2023 10:56:03 +0100 Subject: [PATCH 3790/4498] drivers: watchdog: wdt_nrfx: Remove config field from config structure The field config of `nrfx_wdt_config_t` type is redundant in device config structure. Instead of that local variable is used in the setup function. Signed-off-by: Adam Wojasinski --- drivers/watchdog/wdt_nrfx.c | 44 ++++++++++++++----------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 8d61f11d6fb..ff5fd0179f8 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -20,37 +20,32 @@ struct wdt_nrfx_data { }; struct wdt_nrfx_config { - nrfx_wdt_t wdt; - nrfx_wdt_config_t config; + nrfx_wdt_t wdt; }; static int wdt_nrf_setup(const struct device *dev, uint8_t options) { const struct wdt_nrfx_config *config = dev->config; - struct wdt_nrfx_data *data = dev->data; - uint32_t behaviour; + const struct wdt_nrfx_data *data = dev->data; + nrfx_err_t err_code; - /* Activate all available options. Run in all cases. */ - behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + nrfx_wdt_config_t wdt_config = { + .reload_value = data->m_timeout + }; - /* Deactivate running in sleep mode. */ - if (options & WDT_OPT_PAUSE_IN_SLEEP) { - behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; + if (!(options & WDT_OPT_PAUSE_IN_SLEEP)) { + wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; } - /* Deactivate running when debugger is attached. */ - if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) { - behaviour &= ~NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; + if (!(options & WDT_OPT_PAUSE_HALTED_BY_DBG)) { + wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_HALT_MASK; } - nrf_wdt_behaviour_set(config->wdt.p_reg, behaviour); - /* The watchdog timer is driven by the LFCLK clock running at 32768 Hz. - * The timeout value given in milliseconds needs to be converted here - * to watchdog ticks.*/ - nrf_wdt_reload_value_set( - config->wdt.p_reg, - (uint32_t)(((uint64_t)data->m_timeout * 32768U) - / 1000)); + err_code = nrfx_wdt_reconfigure(&config->wdt, &wdt_config); + + if (err_code != NRFX_SUCCESS) { + return -EBUSY; + } nrfx_wdt_enable(&config->wdt); @@ -162,8 +157,8 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) IRQ_CONNECT(DT_IRQN(WDT(idx)), DT_IRQ(WDT(idx), priority), \ nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0); \ err_code = nrfx_wdt_init(&config->wdt, \ - &config->config, \ - wdt_##idx##_event_handler); \ + NULL, \ + wdt_##idx##_event_handler); \ if (err_code != NRFX_SUCCESS) { \ return -EBUSY; \ } \ @@ -175,11 +170,6 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) }; \ static const struct wdt_nrfx_config wdt_##idx##z_config = { \ .wdt = NRFX_WDT_INSTANCE(idx), \ - .config = { \ - .behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK | \ - NRF_WDT_BEHAVIOUR_RUN_HALT_MASK, \ - .reload_value = 2000, \ - } \ }; \ DEVICE_DT_DEFINE(WDT(idx), \ wdt_##idx##_init, \ From 599bcb1e5d470e4fafce7418ff6516f0573f6d03 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Fri, 22 Sep 2023 09:08:17 +0200 Subject: [PATCH 3791/4498] drivers: watchdog: wdt_nrfx: Implement disable API nRF5340 SoC has `TASK_STOP` this patch implements disabling watchdog for that SoC and enables allowing WDT to STOP in WDT setup. Signed-off-by: Adam Wojasinski --- drivers/watchdog/wdt_nrfx.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index ff5fd0179f8..98fcb713b81 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -33,6 +33,10 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) .reload_value = data->m_timeout }; +#if NRF_WDT_HAS_STOP + wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_STOP_ENABLE_MASK; +#endif + if (!(options & WDT_OPT_PAUSE_IN_SLEEP)) { wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK; } @@ -54,9 +58,21 @@ static int wdt_nrf_setup(const struct device *dev, uint8_t options) static int wdt_nrf_disable(const struct device *dev) { - /* Started watchdog cannot be stopped on nRF devices. */ +#if NRFX_WDT_HAS_STOP + const struct wdt_nrfx_config *config = dev->config; + nrfx_err_t err_code; + + err_code = nrfx_wdt_stop(&config->wdt); + + if (err_code != NRFX_SUCCESS) { + return -ENOTSUP; + } + + return 0; +#else ARG_UNUSED(dev); return -EPERM; +#endif } static int wdt_nrf_install_timeout(const struct device *dev, From 31ee2e678d2be4f47918c073f615129ed37bbfb3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:36:10 +0200 Subject: [PATCH 3792/4498] net: context: Allow binding to different interfaces Allow user to bind to different network interface. This is useful if binding a multicast address to a certain network interface. Signed-off-by: Jukka Rissanen --- subsys/net/ip/net_context.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index ef9fc640f08..9cdcaadc822 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -121,7 +121,8 @@ static inline bool is_in_tcp_time_wait_state(struct net_context *context) #endif } -static int check_used_port(enum net_ip_protocol proto, +static int check_used_port(struct net_if *iface, + enum net_ip_protocol proto, uint16_t local_port, const struct sockaddr *local_addr, bool reuseaddr_set, @@ -140,6 +141,12 @@ static int check_used_port(enum net_ip_protocol proto, continue; } + if (net_context_is_bound_to_iface(&contexts[i])) { + if (iface != NULL && iface != net_context_get_iface(&contexts[i])) { + continue; + } + } + if (IS_ENABLED(CONFIG_NET_IPV6) && local_addr->sa_family == AF_INET6) { if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL || @@ -271,7 +278,7 @@ static uint16_t find_available_port(struct net_context *context, do { local_port = sys_rand32_get() | 0x8000; - } while (check_used_port(net_context_get_proto(context), + } while (check_used_port(NULL, net_context_get_proto(context), htons(local_port), addr, false, false) == -EEXIST); return htons(local_port); @@ -285,7 +292,7 @@ bool net_context_port_in_use(enum net_ip_protocol proto, uint16_t local_port, const struct sockaddr *local_addr) { - return check_used_port(proto, htons(local_port), local_addr, false, false) != 0; + return check_used_port(NULL, proto, htons(local_port), local_addr, false, false) != 0; } #if defined(CONFIG_NET_CONTEXT_CHECK) @@ -742,7 +749,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, ret = 0; if (addr6->sin6_port) { - ret = check_used_port(context->proto, + ret = check_used_port(iface, + context->proto, addr6->sin6_port, addr, net_context_is_reuseaddr_set(context), @@ -750,6 +758,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, if (ret != 0) { NET_ERR("Port %d is in use!", ntohs(addr6->sin6_port)); + NET_DBG("Interface %d (%p)", + iface ? net_if_get_by_iface(iface) : 0, iface); ret = -EADDRINUSE; goto unlock_ipv6; } else { @@ -839,7 +849,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, ret = 0; if (addr4->sin_port) { - ret = check_used_port(context->proto, + ret = check_used_port(iface, + context->proto, addr4->sin_port, addr, net_context_is_reuseaddr_set(context), @@ -848,6 +859,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr, NET_ERR("Port %d is in use!", ntohs(addr4->sin_port)); ret = -EADDRINUSE; + NET_DBG("Interface %d (%p)", + iface ? net_if_get_by_iface(iface) : 0, iface); goto unlock_ipv4; } else { net_sin_ptr(&context->local)->sin_port = From 8157b487342cb5502101d51d62c06ebc923421d4 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:39:14 +0200 Subject: [PATCH 3793/4498] net: context: Add function to bound to a network interface Helper function that marks the net_context to bound to a network interface. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_context.h | 17 +++++++++++++++++ subsys/net/lib/sockets/sockets.c | 3 +-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/net_context.h b/include/zephyr/net/net_context.h index 6c0453a3d2b..ea116a24846 100644 --- a/include/zephyr/net/net_context.h +++ b/include/zephyr/net/net_context.h @@ -672,6 +672,23 @@ static inline void net_context_set_iface(struct net_context *context, context->iface = net_if_get_by_iface(iface); } +/** + * @brief Bind network interface to this context. + * + * @details This function binds network interface to this context. + * + * @param context Network context. + * @param iface Network interface. + */ +static inline void net_context_bind_iface(struct net_context *context, + struct net_if *iface) +{ + NET_ASSERT(iface); + + context->flags |= NET_CONTEXT_BOUND_TO_IFACE; + net_context_set_iface(context, iface); +} + static inline uint8_t net_context_get_ipv4_ttl(struct net_context *context) { return context->ipv4_ttl; diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 9dadc452a26..b10b9136272 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2421,8 +2421,7 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, } } - net_context_set_iface(ctx, iface); - ctx->flags |= NET_CONTEXT_BOUND_TO_IFACE; + net_context_bind_iface(ctx, iface); return 0; } From 3f891ced3a718171162b0e93b4d7d1dbbeb73b21 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:40:22 +0200 Subject: [PATCH 3794/4498] net: conn: Check also network interface for duplicates When verifying if there are duplicate connections, check also network interface. Signed-off-by: Jukka Rissanen --- subsys/net/ip/connection.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 35ef208a609..e32747bc38f 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -154,7 +154,8 @@ static void conn_set_unused(struct net_conn *conn) } /* Check if we already have identical connection handler installed. */ -static struct net_conn *conn_find_handler(uint16_t proto, uint8_t family, +static struct net_conn *conn_find_handler(struct net_if *iface, + uint16_t proto, uint8_t family, const struct sockaddr *remote_addr, const struct sockaddr *local_addr, uint16_t remote_port, @@ -252,6 +253,13 @@ static struct net_conn *conn_find_handler(uint16_t proto, uint8_t family, continue; } + if (conn->context != NULL && iface != NULL && + net_context_is_bound_to_iface(conn->context)) { + if (iface != net_context_get_iface(conn->context)) { + continue; + } + } + k_mutex_unlock(&conn_lock); return conn; } @@ -273,7 +281,8 @@ int net_conn_register(uint16_t proto, uint8_t family, struct net_conn *conn; uint8_t flags = 0U; - conn = conn_find_handler(proto, family, remote_addr, local_addr, + conn = conn_find_handler(context != NULL ? net_context_get_iface(context) : NULL, + proto, family, remote_addr, local_addr, remote_port, local_port, context != NULL ? net_context_is_reuseport_set(context) : From dd2a222086bcd6a633d4247ab066da3a659b699f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:42:21 +0200 Subject: [PATCH 3795/4498] net: if: Add helper to calculate number of interfaces Add a helper macro that can be used at runtime to return the number of network interfaces in the system. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_if.h | 14 ++++++++++++++ subsys/net/ip/net_if.c | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index ab056d05e15..788c3316391 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -3022,6 +3022,20 @@ struct net_if_api { #define NET_DEVICE_DT_INST_OFFLOAD_DEFINE(inst, ...) \ NET_DEVICE_DT_OFFLOAD_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) +/** + * @brief Count the number of network interfaces. + * + * @param[out] _dst Pointer to location where result is written. + */ +#define NET_IFACE_COUNT(_dst) \ + do { \ + extern struct net_if _net_if_list_start[]; \ + extern struct net_if _net_if_list_end[]; \ + *(_dst) = ((uintptr_t)_net_if_list_end - \ + (uintptr_t)_net_if_list_start) / \ + sizeof(struct net_if); \ + } while (0) + #ifdef __cplusplus } #endif diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index dbf20af3cc0..00c9c74495d 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4876,6 +4876,16 @@ void net_if_init(void) goto out; } +#if defined(CONFIG_ASSERT) + /* Do extra check that verifies that interface count is properly + * done. + */ + int count_if; + + NET_IFACE_COUNT(&count_if); + NET_ASSERT(count_if == if_count); +#endif + iface_ipv6_init(if_count); iface_ipv4_init(if_count); iface_router_init(); From 5049a049dba231c7b99642fe32bb699b8f1b3cc9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:44:10 +0200 Subject: [PATCH 3796/4498] net: mdns: Create a listener to all available network interfaces Instead of just listening first network interface in the system, install a multicast listener to all available network interfaces. Fixes #18748 Signed-off-by: Jukka Rissanen --- subsys/net/lib/dns/mdns_responder.c | 97 ++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/subsys/net/lib/dns/mdns_responder.c b/subsys/net/lib/dns/mdns_responder.c index 4a61992e506..5a724faf136 100644 --- a/subsys/net/lib/dns/mdns_responder.c +++ b/subsys/net/lib/dns/mdns_responder.c @@ -38,11 +38,17 @@ LOG_MODULE_REGISTER(net_mdns_responder, CONFIG_MDNS_RESPONDER_LOG_LEVEL); #define MDNS_TTL CONFIG_MDNS_RESPONDER_TTL /* In seconds */ #if defined(CONFIG_NET_IPV4) -static struct net_context *ipv4; +#define MAX_IPV4_IFACE_COUNT CONFIG_NET_IF_MAX_IPV4_COUNT +static struct net_context *ipv4[MAX_IPV4_IFACE_COUNT]; static struct sockaddr_in local_addr4; +#else +#define MAX_IPV4_IFACE_COUNT 0 #endif #if defined(CONFIG_NET_IPV6) -static struct net_context *ipv6; +#define MAX_IPV6_IFACE_COUNT CONFIG_NET_IF_MAX_IPV6_COUNT +static struct net_context *ipv6[MAX_IPV6_IFACE_COUNT]; +#else +#define MAX_IPV6_IFACE_COUNT 0 #endif static struct net_mgmt_event_callback mgmt_cb; @@ -645,55 +651,100 @@ static void setup_ipv4_addr(struct sockaddr_in *local_addr) static int init_listener(void) { - int ret, ok = 0; + int ret, ok = 0, i; + struct net_if *iface; + int iface_count; + + NET_IFACE_COUNT(&iface_count); + NET_DBG("Setting mDNS listener to %d interface%s", iface_count, + iface_count > 1 ? "s" : ""); + + if ((iface_count > MAX_IPV6_IFACE_COUNT && MAX_IPV6_IFACE_COUNT > 0) || + (iface_count > MAX_IPV4_IFACE_COUNT && MAX_IPV4_IFACE_COUNT > 0)) { + NET_WARN("You have %d interfaces configured but there " + "are %d network interfaces in the system.", + MAX(MAX_IPV6_IFACE_COUNT, + MAX_IPV6_IFACE_COUNT), iface_count); + } #if defined(CONFIG_NET_IPV6) - do { - static struct sockaddr_in6 local_addr; + struct sockaddr_in6 local_addr6; + struct net_context *v6; - setup_ipv6_addr(&local_addr); + setup_ipv6_addr(&local_addr6); - ipv6 = get_ctx(AF_INET6); + for (i = 0; i < MAX_IPV6_IFACE_COUNT; i++) { + v6 = get_ctx(AF_INET6); + if (v6 == NULL) { + NET_ERR("Cannot get %s context out of %d. Max contexts is %d", + "IPv6", MAX_IPV6_IFACE_COUNT, CONFIG_NET_MAX_CONTEXTS); + continue; + } - ret = bind_ctx(ipv6, (struct sockaddr *)&local_addr, - sizeof(local_addr)); + iface = net_if_get_by_index(i + 1); + if (iface == NULL) { + net_context_unref(v6); + continue; + } + + net_context_bind_iface(v6, iface); + + ret = bind_ctx(v6, (struct sockaddr *)&local_addr6, + sizeof(local_addr6)); if (ret < 0) { - net_context_put(ipv6); + net_context_put(v6); goto ipv6_out; } - ret = net_context_recv(ipv6, recv_cb, K_NO_WAIT, ipv6); + ret = net_context_recv(v6, recv_cb, K_NO_WAIT, v6); if (ret < 0) { - NET_WARN("Cannot receive IPv6 mDNS data (%d)", ret); - net_context_put(ipv6); + NET_WARN("Cannot receive %s mDNS data (%d)", "IPv6", ret); + net_context_put(v6); } else { + ipv6[i] = v6; ok++; } - } while (0); + } ipv6_out: #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) - do { - setup_ipv4_addr(&local_addr4); + struct net_context *v4; - ipv4 = get_ctx(AF_INET); + setup_ipv4_addr(&local_addr4); - ret = bind_ctx(ipv4, (struct sockaddr *)&local_addr4, + for (i = 0; i < MAX_IPV4_IFACE_COUNT; i++) { + v4 = get_ctx(AF_INET); + if (v4 == NULL) { + NET_ERR("Cannot get %s context out of %d. Max contexts is %d", + "IPv4", MAX_IPV4_IFACE_COUNT, CONFIG_NET_MAX_CONTEXTS); + continue; + } + + iface = net_if_get_by_index(i + 1); + if (iface == NULL) { + net_context_unref(v4); + continue; + } + + net_context_bind_iface(v4, iface); + + ret = bind_ctx(v4, (struct sockaddr *)&local_addr4, sizeof(local_addr4)); if (ret < 0) { - net_context_put(ipv4); + net_context_put(v4); goto ipv4_out; } - ret = net_context_recv(ipv4, recv_cb, K_NO_WAIT, ipv4); + ret = net_context_recv(v4, recv_cb, K_NO_WAIT, v4); if (ret < 0) { - NET_WARN("Cannot receive IPv4 mDNS data (%d)", ret); - net_context_put(ipv4); + NET_WARN("Cannot receive %s mDNS data (%d)", "IPv4", ret); + net_context_put(v4); } else { + ipv4[i] = v4; ok++; } - } while (0); + } ipv4_out: #endif /* CONFIG_NET_IPV4 */ From 9246d98a6a2533177a06e91eca76fec93c7df1a3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 15 Nov 2023 17:47:06 +0200 Subject: [PATCH 3797/4498] samples: net: mdns_responder: Add VLAN support Add virtual LAN support to the sample so that it is easier to test the multiple mDNS listener feature implemented in previous commit. Signed-off-by: Jukka Rissanen --- samples/net/mdns_responder/CMakeLists.txt | 5 +- samples/net/mdns_responder/Kconfig | 56 ++++++++ samples/net/mdns_responder/overlay-e1000.conf | 6 + samples/net/mdns_responder/overlay-vlan.conf | 34 +++++ samples/net/mdns_responder/src/main.c | 10 ++ samples/net/mdns_responder/src/vlan.c | 135 ++++++++++++++++++ 6 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 samples/net/mdns_responder/Kconfig create mode 100644 samples/net/mdns_responder/overlay-e1000.conf create mode 100644 samples/net/mdns_responder/overlay-vlan.conf create mode 100644 samples/net/mdns_responder/src/vlan.c diff --git a/samples/net/mdns_responder/CMakeLists.txt b/samples/net/mdns_responder/CMakeLists.txt index 21efc955050..5c4e88178a9 100644 --- a/samples/net/mdns_responder/CMakeLists.txt +++ b/samples/net/mdns_responder/CMakeLists.txt @@ -4,7 +4,8 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(mdns_responder) -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) +target_sources(app PRIVATE src/main.c) +target_sources(app PRIVATE src/service.c) +target_sources_ifdef(CONFIG_NET_VLAN app PRIVATE src/vlan.c) include(${ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/samples/net/mdns_responder/Kconfig b/samples/net/mdns_responder/Kconfig new file mode 100644 index 00000000000..53cc3d2153d --- /dev/null +++ b/samples/net/mdns_responder/Kconfig @@ -0,0 +1,56 @@ +# Private config options for mDNS responder sample app + +# Copyright (c) 2023 NordicNordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Networking mDNS responder sample application" + +config NET_SAMPLE_IFACE2_MY_IPV6_ADDR + string "My IPv6 address for second interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE2_MY_IPV4_ADDR + string "My IPv4 address for second interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE2_MY_IPV4_NETMASK + string "My IPv4 netmask for second interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE2_VLAN_TAG + int "VLAN tag for second interface" + default 100 + range 0 4094 + depends on NET_VLAN + help + Set VLAN (virtual LAN) tag (id) that is used in the sample + application. + +config NET_SAMPLE_IFACE3_MY_IPV6_ADDR + string "My IPv6 address for third interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE3_MY_IPV4_ADDR + string "My IPv4 address for third interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE3_MY_IPV4_NETMASK + string "My IPv4 netmask for third interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE3_VLAN_TAG + int "VLAN tag for third interface" + default 200 + range 0 4094 + depends on NET_VLAN + help + Set VLAN (virtual LAN) tag (id) that is used in the sample + application. + +source "Kconfig.zephyr" diff --git a/samples/net/mdns_responder/overlay-e1000.conf b/samples/net/mdns_responder/overlay-e1000.conf new file mode 100644 index 00000000000..d2880bd3587 --- /dev/null +++ b/samples/net/mdns_responder/overlay-e1000.conf @@ -0,0 +1,6 @@ +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_QEMU_ETHERNET=y + +CONFIG_PCIE=y + +#CONFIG_ETHERNET_LOG_LEVEL_DBG=y diff --git a/samples/net/mdns_responder/overlay-vlan.conf b/samples/net/mdns_responder/overlay-vlan.conf new file mode 100644 index 00000000000..5dfe0f9b8f7 --- /dev/null +++ b/samples/net/mdns_responder/overlay-vlan.conf @@ -0,0 +1,34 @@ +CONFIG_NET_VLAN=y + +# We have one non-vlan interface and two VLAN interfaces +CONFIG_NET_VLAN_COUNT=3 + +# There will be three network interfaces. + +# First ethernet interface will use these settings +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +# Second ethernet interface will have these settings +CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR="2001:db8:100::1" +# TEST-NET-2 from RFC 5737 +CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR="198.51.100.1" +CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_NETMASK="255.255.255.0" +# VLAN tag for the second interface +CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG=100 + +# Settings for the third network interface +CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR="2001:db8:200::1" +# TEST-NET-3 from RFC 5737 +CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR="203.0.113.1" +CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_NETMASK="255.255.255.0" +# VLAN tag for the second interface +CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG=200 + +# Each interface needs at least 2 context. So if we have three +# interfaces we need minimum 6 context but allocate more so that +# we do not run out of them. +CONFIG_NET_MAX_CONTEXTS=10 +CONFIG_NET_MAX_CONN=10 diff --git a/samples/net/mdns_responder/src/main.c b/samples/net/mdns_responder/src/main.c index 6a4ec48a4ab..112f9e93931 100644 --- a/samples/net/mdns_responder/src/main.c +++ b/samples/net/mdns_responder/src/main.c @@ -14,6 +14,15 @@ LOG_MODULE_REGISTER(net_mdns_responder_sample, LOG_LEVEL_DBG); extern void service(void); +#if defined(CONFIG_NET_VLAN) +int init_vlan(void); +#else +static inline int init_vlan(void) +{ + return 0; +} +#endif /* CONFIG_NET_VLAN */ + /* * Note that mDNS support requires no application interaction with zephyr, * beyond optional runtime hostname configuration calls and setting @@ -26,6 +35,7 @@ extern void service(void); int main(void) { LOG_INF("Waiting mDNS queries..."); + init_vlan(); service(); return 0; } diff --git a/samples/net/mdns_responder/src/vlan.c b/samples/net/mdns_responder/src/vlan.c new file mode 100644 index 00000000000..534662c3c64 --- /dev/null +++ b/samples/net/mdns_responder/src/vlan.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_mdns_responder_sample, LOG_LEVEL_DBG); + +#include + +#include + +/* User data for the interface callback */ +struct ud { + struct net_if *first; + struct net_if *second; + struct net_if *third; +}; + +static void iface_cb(struct net_if *iface, void *user_data_param) +{ + struct ud *user_data = user_data_param; + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + return; + } + + if (!user_data->first) { + user_data->first = iface; + return; + } + + if (!user_data->second) { + user_data->second = iface; + return; + } + + if (!user_data->third) { + user_data->third = iface; + return; + } +} + +static int setup_iface(struct net_if *iface, const char *ipv6_addr, + const char *ipv4_addr, const char *netmask, + uint16_t vlan_tag) +{ + struct net_if_addr *ifaddr; + struct in_addr addr4; + struct in6_addr addr6; + int ret; + + ret = net_eth_vlan_enable(iface, vlan_tag); + if (ret < 0) { + LOG_ERR("Cannot enable VLAN for tag %d (%d)", vlan_tag, ret); + } + + if (IS_ENABLED(CONFIG_NET_IPV6)) { + if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) { + LOG_ERR("Invalid address: %s", ipv6_addr); + return -EINVAL; + } + + ifaddr = net_if_ipv6_addr_add(iface, &addr6, + NET_ADDR_MANUAL, 0); + if (!ifaddr) { + LOG_ERR("Cannot add %s to interface %p", + ipv6_addr, iface); + return -EINVAL; + } + } + + if (IS_ENABLED(CONFIG_NET_IPV4)) { + if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) { + LOG_ERR("Invalid address: %s", ipv4_addr); + return -EINVAL; + } + + ifaddr = net_if_ipv4_addr_add(iface, &addr4, + NET_ADDR_MANUAL, 0); + if (!ifaddr) { + LOG_ERR("Cannot add %s to interface %p", + ipv4_addr, iface); + return -EINVAL; + } + + if (netmask && netmask[0]) { + if (net_addr_pton(AF_INET, netmask, &addr4)) { + LOG_ERR("Invalid netmask: %s", ipv4_addr); + return -EINVAL; + } + + net_if_ipv4_set_netmask(iface, &addr4); + } + } + + LOG_DBG("Interface %p VLAN tag %d setup done.", iface, vlan_tag); + + return 0; +} + +int init_vlan(void) +{ + struct ud user_data; + int ret; + + memset(&user_data, 0, sizeof(user_data)); + + net_if_foreach(iface_cb, &user_data); + + /* This sample has two VLANs. For the second one we need to manually + * create IP address for this test. But first the VLAN needs to be + * added to the interface so that IPv6 DAD can work properly. + */ + ret = setup_iface(user_data.second, + CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR, + CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR, + CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_NETMASK, + CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG); + if (ret < 0) { + return ret; + } + + ret = setup_iface(user_data.third, + CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR, + CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR, + CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_NETMASK, + CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG); + if (ret < 0) { + return ret; + } + + return 0; +} From 5209666539bcd4dea30faaf39f700339e075d14d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 16 Nov 2023 21:40:56 +0200 Subject: [PATCH 3798/4498] net: mdns: Fix compile error when using clang No issues with gcc but clang gives this error for the *v4 variable few lines below. .../lib/dns/mdns_responder.c:712:2: error: expected expression struct net_context *v4; Signed-off-by: Jukka Rissanen --- subsys/net/lib/dns/mdns_responder.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/net/lib/dns/mdns_responder.c b/subsys/net/lib/dns/mdns_responder.c index 5a724faf136..04acbabbecd 100644 --- a/subsys/net/lib/dns/mdns_responder.c +++ b/subsys/net/lib/dns/mdns_responder.c @@ -706,6 +706,9 @@ static int init_listener(void) } } ipv6_out: + ; /* Added ";" to avoid clang compile error because of + * the "struct net_context *v4" after it. + */ #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) From 7a83724e0f18d7f2400517407150f9e9a1ecd6e6 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 10:44:38 +1100 Subject: [PATCH 3799/4498] boards: nrf52840dk_nrf52840: add gpio reserved ranges and line names Add gpio-reserved-ranges and gpio-line-names properties. Signed-off-by: Nick Ward --- boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index 96006ec4722..dcee7b0db5f 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -149,10 +149,18 @@ &gpio0 { status = "okay"; + gpio-reserved-ranges = <0 11>, <17 7>, <26 6>; + gpio-line-names = "", "", "", "", "", "", "", "", + "", "", "", "BUTTON1", "BUTTON2", "LED1", "LED2", "LED3", + "LED4", "", "", "", "", "", "", "", + "BUTTON3", "BUTTON4", "", "", "", "", "", ""; }; &gpio1 { status = "okay"; + gpio-reserved-ranges = <0 1>, <9 1>, <12 4>; + gpio-line-names = "", "D0", "D1", "D2", "D3", "D4", "D5", "D6", + "D7", "", "D8", "D9", "", "", "", ""; }; &uart0 { From 0df794e31656ae2360f241487bbff84076134f66 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 11:34:30 +1100 Subject: [PATCH 3800/4498] drivers: gpio: shell: improve tab complete/suggestion support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements this enhancement: https://github.com/zephyrproject-rtos/zephyr/issues/63018 The forms of the gpio commands are now: gpio conf device pin ol0 gpio set device pin 1 gpio get device pin gpio blink device pin Device name and pin subcommands now are suggested/completed when tab is used. Pin names are suggested with numbers and line names if available from the gpio controller’s Devicetree node. GPIO pin command is now limited to pins that are not assigned as reserved. Signed-off-by: Nick Ward --- drivers/gpio/gpio_shell.c | 488 +++++++++++++++++++++++++++++--------- 1 file changed, 371 insertions(+), 117 deletions(-) diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index b444288953b..e7dea06538f 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -1,187 +1,441 @@ /* * Copyright (c) 2018 Intel Corporation * Copyright (c) 2021 Dennis Ruffer + * Copyright (c) 2023 Nick Ward * * SPDX-License-Identifier: Apache-2.0 - * - * Use "device list" command for GPIO port names */ -#include +#include #include -#include -#include + #include -#include -#include -#include -#include -#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#define ARGV_DEV 1 +#define ARGV_PIN 2 +#define ARGV_CONF 3 +#define ARGV_VALUE 3 -LOG_MODULE_REGISTER(gpio_shell); +#define NGPIOS_UNKNOWN -1 +#define PIN_NOT_FOUND UINT8_MAX -struct args_index { - uint8_t port; - uint8_t index; - uint8_t mode; - uint8_t value; +/* Pin syntax maximum length */ +#define PIN_SYNTAX_MAX 32 +#define PIN_NUM_MAX 4 + +struct gpio_ctrl { + const struct device *dev; + int8_t ngpios; + gpio_port_pins_t reserved_mask; + const char **line_names; + uint8_t line_names_len; + const union shell_cmd_entry *subcmd; }; -static const struct args_index args_indx = { - .port = 1, - .index = 2, - .mode = 3, - .value = 3, +struct sh_gpio { + const struct device *dev; + gpio_pin_t pin; }; -static int cmd_gpio_conf(const struct shell *sh, size_t argc, char **argv) +/* + * Find idx-th pin reference from the set of non reserved + * pin numbers and provided line names. + */ +static void port_pin_get(gpio_port_pins_t reserved_mask, const char **line_names, + uint8_t line_names_len, size_t idx, struct shell_static_entry *entry) { - uint8_t index = 0U; - int type = GPIO_OUTPUT; - const struct device *dev; + static char pin_syntax[PIN_SYNTAX_MAX]; + static char pin_num[PIN_NUM_MAX]; + const char *name; + gpio_pin_t pin; + bool reserved; + + entry->handler = NULL; + + /* Find allowed numeric pin reference */ + for (pin = 0; pin < GPIO_MAX_PINS_PER_PORT; pin++) { + reserved = ((BIT64(pin) & reserved_mask) != 0); + if (!reserved) { + if (idx == 0) { + break; + } + idx--; + } + } - if (isdigit((unsigned char)argv[args_indx.index][0]) != 0 && - isalpha((unsigned char)argv[args_indx.mode][0]) != 0) { - index = (uint8_t)atoi(argv[args_indx.index]); - if (!strcmp(argv[args_indx.mode], "in")) { - type = GPIO_INPUT; - } else if (!strcmp(argv[args_indx.mode], "inu")) { - type = GPIO_INPUT | GPIO_PULL_UP; - } else if (!strcmp(argv[args_indx.mode], "ind")) { - type = GPIO_INPUT | GPIO_PULL_DOWN; - } else if (!strcmp(argv[args_indx.mode], "out")) { - type = GPIO_OUTPUT; + if (pin < GPIO_MAX_PINS_PER_PORT) { + sprintf(pin_num, "%u", pin); + if ((pin < line_names_len) && (strlen(line_names[pin]) > 0)) { + /* pin can be specified by line name */ + name = line_names[pin]; + for (int i = 0; i < (sizeof(pin_syntax) - 1); i++) { + /* + * For line-name tab completion to work replace any + * space characters with '_'. + */ + pin_syntax[i] = (name[i] != ' ') ? name[i] : '_'; + if (name[i] == '\0') { + break; + } + } + pin_syntax[sizeof(pin_syntax) - 1] = '\0'; + entry->syntax = pin_syntax; + entry->help = pin_num; } else { - return 0; + /* fallback to pin specified by pin number */ + entry->syntax = pin_num; + entry->help = NULL; } } else { - shell_error(sh, "Wrong parameters for conf"); - return -ENOTSUP; + /* No more pins */ + entry->syntax = NULL; + entry->help = NULL; } +} - dev = device_get_binding(argv[args_indx.port]); +#define GPIO_DT_RESERVED_RANGES_NGPIOS_SHELL(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, ngpios), \ + (GPIO_DT_RESERVED_RANGES_NGPIOS(node_id, DT_PROP(node_id, ngpios))), \ + (GPIO_MAX_PINS_PER_PORT)) - if (dev != NULL) { - index = (uint8_t)atoi(argv[args_indx.index]); - shell_print(sh, "Configuring %s pin %d", - argv[args_indx.port], index); - gpio_pin_configure(dev, index, type); +#define GPIO_CTRL_PIN_GET_FN(node_id) \ + static const char *node_id##line_names[] = DT_PROP_OR(node_id, gpio_line_names, {NULL}); \ + \ + static void node_id##cmd_gpio_pin_get(size_t idx, struct shell_static_entry *entry); \ + \ + SHELL_DYNAMIC_CMD_CREATE(node_id##sub_gpio_pin, node_id##cmd_gpio_pin_get); \ + \ + static void node_id##cmd_gpio_pin_get(size_t idx, struct shell_static_entry *entry) \ + { \ + gpio_port_pins_t reserved_mask = GPIO_DT_RESERVED_RANGES_NGPIOS_SHELL(node_id); \ + uint8_t line_names_len = DT_PROP_LEN_OR(node_id, gpio_line_names, 0); \ + \ + port_pin_get(reserved_mask, node_id##line_names, line_names_len, idx, entry); \ + entry->subcmd = NULL; \ } - return 0; +#define IS_GPIO_CTRL_PIN_GET(node_id) \ + COND_CODE_1(DT_PROP(node_id, gpio_controller), (GPIO_CTRL_PIN_GET_FN(node_id)), ()) + +DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_PIN_GET) + +#define GPIO_CTRL_LIST_ENTRY(node_id) \ + { \ + .dev = DEVICE_DT_GET(node_id), \ + .ngpios = DT_PROP_OR(node_id, ngpios, NGPIOS_UNKNOWN), \ + .reserved_mask = GPIO_DT_RESERVED_RANGES_NGPIOS_SHELL(node_id), \ + .line_names = node_id##line_names, \ + .line_names_len = DT_PROP_LEN_OR(node_id, gpio_line_names, 0), \ + .subcmd = &node_id##sub_gpio_pin, \ + }, + +#define IS_GPIO_CTRL_LIST(node_id) \ + COND_CODE_1(DT_PROP(node_id, gpio_controller), (GPIO_CTRL_LIST_ENTRY(node_id)), ()) + +static const struct gpio_ctrl gpio_list[] = {DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_LIST)}; + +static const struct gpio_ctrl *get_gpio_ctrl(char *name) +{ + const struct device *dev = device_get_binding(name); + size_t i; + + for (i = 0; i < ARRAY_SIZE(gpio_list); i++) { + if (gpio_list[i].dev == dev) { + return &gpio_list[i]; + } + } + return NULL; } -static int cmd_gpio_get(const struct shell *sh, - size_t argc, char **argv) +int line_cmp(const char *input, const char *line_name) { - const struct device *dev; - uint8_t index = 0U; - int rc; + int i = 0; - if (isdigit((unsigned char)argv[args_indx.index][0]) != 0) { - index = (uint8_t)atoi(argv[args_indx.index]); - } else { - shell_error(sh, "Wrong parameters for get"); + while (true) { + if ((input[i] == '_') && (line_name[i] == ' ')) { + /* Allow input underscore to match line_name space */ + } else if (input[i] != line_name[i]) { + return (input[i] > line_name[i]) ? 1 : -1; + } else if (line_name[i] == '\0') { + return 0; + } + i++; + } +} + +static int get_gpio_pin(const struct shell *sh, const struct gpio_ctrl *ctrl, char *line_name) +{ + gpio_pin_t pin = PIN_NOT_FOUND; + gpio_pin_t i; + int result; + + for (i = 0; i < ctrl->ngpios; i++) { + result = line_cmp(line_name, ctrl->line_names[i]); + if (result == 0) { + if ((BIT64(i) & ctrl->reserved_mask) != 0) { + shell_error(sh, "Reserved pin"); + return -EACCES; + } else if (pin == PIN_NOT_FOUND) { + pin = i; + } else { + shell_error(sh, "Line name ambiguous"); + return -EFAULT; + } + } + } + + if (pin == PIN_NOT_FOUND) { + shell_error(sh, "Line name not found: '%s'", line_name); + return -ENOENT; + } + + return pin; +} + +static int get_sh_gpio(const struct shell *sh, char **argv, struct sh_gpio *gpio) +{ + const struct gpio_ctrl *ctrl; + int ret = 0; + int pin; + + ctrl = get_gpio_ctrl(argv[ARGV_DEV]); + if (ctrl == NULL) { + shell_error(sh, "unknown gpio controller: %s", argv[ARGV_DEV]); return -EINVAL; } + gpio->dev = ctrl->dev; + pin = shell_strtoul(argv[ARGV_PIN], 0, &ret); + if (ret != 0) { + pin = get_gpio_pin(sh, ctrl, argv[ARGV_PIN]); + if (pin < 0) { + return pin; + } + } else if ((BIT64(pin) & ctrl->reserved_mask) != 0) { + shell_error(sh, "Reserved pin"); + return -EACCES; + } + gpio->pin = pin; + + return 0; +} + +static int cmd_gpio_conf(const struct shell *sh, size_t argc, char **argv, void *data) +{ + gpio_flags_t flags = 0; + struct sh_gpio gpio; + int ret = 0; + + ret = get_sh_gpio(sh, argv, &gpio); + if (ret != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } - dev = device_get_binding(argv[args_indx.port]); + for (int i = 0; i < strlen(argv[ARGV_CONF]); i++) { + switch (argv[ARGV_CONF][i]) { + case 'i': + flags |= GPIO_INPUT; + break; + case 'o': + flags |= GPIO_OUTPUT; + break; + case 'u': + flags |= GPIO_PULL_UP; + break; + case 'd': + flags |= GPIO_PULL_DOWN; + break; + case 'h': + flags |= GPIO_ACTIVE_HIGH; + break; + case 'l': + flags |= GPIO_ACTIVE_LOW; + break; + case '0': + flags |= GPIO_OUTPUT_INIT_LOGICAL | GPIO_OUTPUT_INIT_LOW; + break; + case '1': + flags |= GPIO_OUTPUT_INIT_LOGICAL | GPIO_OUTPUT_INIT_HIGH; + break; + default: + shell_error(sh, "Unknown: '%c'", argv[ARGV_CONF][i]); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } - if (dev != NULL) { - index = (uint8_t)atoi(argv[2]); - shell_print(sh, "Reading %s pin %d", - argv[args_indx.port], index); - rc = gpio_pin_get(dev, index); - if (rc >= 0) { - shell_print(sh, "Value %d", rc); - } else { - shell_error(sh, "Error %d reading value", rc); - return -EIO; + if (((flags & GPIO_INPUT) != 0) == ((flags & GPIO_OUTPUT) != 0)) { + shell_error(sh, "must be either input or output"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if (((flags & GPIO_PULL_UP) != 0) && ((flags & GPIO_PULL_DOWN) != 0)) { + shell_error(sh, "cannot be pull up and pull down"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if (((flags & GPIO_ACTIVE_LOW) != 0) && ((flags & GPIO_ACTIVE_HIGH) != 0)) { + shell_error(sh, "cannot be active low and active high"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if ((flags & GPIO_OUTPUT) != 0) { + /* Default to active high if not specified */ + if ((flags & (GPIO_ACTIVE_LOW | GPIO_ACTIVE_HIGH)) == 0) { + flags |= GPIO_ACTIVE_HIGH; } + /* Default to initialisation to logic 0 if not specified */ + if ((flags & GPIO_OUTPUT_INIT_LOGICAL) == 0) { + flags |= GPIO_OUTPUT_INIT_LOGICAL | GPIO_OUTPUT_INIT_LOW; + } + } + + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT_INIT_LOGICAL) != 0)) { + shell_error(sh, "an input cannot be initialised to a logic level"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if (((flags & GPIO_OUTPUT_INIT_LOW) != 0) && ((flags & GPIO_OUTPUT_INIT_HIGH) != 0)) { + shell_error(sh, "cannot initialise to logic 0 and logic 1"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + ret = gpio_pin_configure(gpio.dev, gpio.pin, flags); + if (ret != 0) { + shell_error(sh, "error: %d", ret); + return ret; } return 0; } -static int cmd_gpio_set(const struct shell *sh, - size_t argc, char **argv) +static int cmd_gpio_get(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev; - uint8_t index = 0U; - uint8_t value = 0U; + struct sh_gpio gpio; + int value; + int ret; - if (isdigit((unsigned char)argv[args_indx.index][0]) != 0 && - isdigit((unsigned char)argv[args_indx.value][0]) != 0) { - index = (uint8_t)atoi(argv[args_indx.index]); - value = (uint8_t)atoi(argv[args_indx.value]); - } else { - shell_print(sh, "Wrong parameters for set"); - return -EINVAL; + ret = get_sh_gpio(sh, argv, &gpio); + if (ret != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; } - dev = device_get_binding(argv[args_indx.port]); - if (dev != NULL) { - index = (uint8_t)atoi(argv[2]); - shell_print(sh, "Writing to %s pin %d", - argv[args_indx.port], index); - gpio_pin_set(dev, index, value); + value = gpio_pin_get(gpio.dev, gpio.pin); + if (value >= 0) { + shell_print(sh, "%u", value); + } else { + shell_error(sh, "error: %d", value); + return value; } return 0; } +static int cmd_gpio_set(const struct shell *sh, size_t argc, char **argv) +{ + struct sh_gpio gpio; + unsigned long value; + int ret = 0; + + ret = get_sh_gpio(sh, argv, &gpio); + if (ret != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + value = shell_strtoul(argv[ARGV_VALUE], 0, &ret); + if (ret != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + ret = gpio_pin_set(gpio.dev, gpio.pin, value != 0); + if (ret != 0) { + shell_error(sh, "error: %d", ret); + return ret; + } + + return 0; +} /* 500 msec = 1/2 sec */ #define SLEEP_TIME_MS 500 -static int cmd_gpio_blink(const struct shell *sh, - size_t argc, char **argv) +static int cmd_gpio_blink(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev; - uint8_t index = 0U; - uint8_t value = 0U; + struct sh_gpio gpio; size_t count = 0; + int value = 0; char data; + int ret; - if (isdigit((unsigned char)argv[args_indx.index][0]) != 0) { - index = (uint8_t)atoi(argv[args_indx.index]); - } else { - shell_error(sh, "Wrong parameters for blink"); - return -EINVAL; + ret = get_sh_gpio(sh, argv, &gpio); + if (ret != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; } - dev = device_get_binding(argv[args_indx.port]); - if (dev != NULL) { - index = (uint8_t)atoi(argv[2]); - shell_fprintf(sh, SHELL_NORMAL, "Blinking port %s index %d.", argv[1], index); - shell_fprintf(sh, SHELL_NORMAL, " Hit any key to exit"); + shell_fprintf(sh, SHELL_NORMAL, "Blinking port %s pin %u.", argv[ARGV_DEV], gpio.pin); + shell_fprintf(sh, SHELL_NORMAL, " Hit any key to exit"); - /* dummy read to clear any pending input */ - (void)sh->iface->api->read(sh->iface, &data, sizeof(data), &count); + /* dummy read to clear any pending input */ + (void)sh->iface->api->read(sh->iface, &data, sizeof(data), &count); - while (true) { - (void)sh->iface->api->read(sh->iface, &data, sizeof(data), &count); - if (count != 0) { - break; - } - gpio_pin_set(dev, index, value); - value = !value; - k_msleep(SLEEP_TIME_MS); + while (true) { + (void)sh->iface->api->read(sh->iface, &data, sizeof(data), &count); + if (count != 0) { + break; } - - shell_fprintf(sh, SHELL_NORMAL, "\n"); + gpio_pin_set(gpio.dev, gpio.pin, value); + value = !value; + k_msleep(SLEEP_TIME_MS); } + shell_fprintf(sh, SHELL_NORMAL, "\n"); + return 0; } +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + if (idx >= ARRAY_SIZE(gpio_list)) { + entry->syntax = NULL; + return; + } + + entry->syntax = gpio_list[idx].dev->name; + entry->handler = NULL; + entry->help = "Device"; + entry->subcmd = gpio_list[idx].subcmd; +} + +SHELL_DYNAMIC_CMD_CREATE(sub_gpio_dev, device_name_get); + SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, - SHELL_CMD_ARG(conf, NULL, "Configure GPIO", cmd_gpio_conf, 4, 0), - SHELL_CMD_ARG(get, NULL, "Get GPIO value", cmd_gpio_get, 3, 0), - SHELL_CMD_ARG(set, NULL, "Set GPIO", cmd_gpio_set, 4, 0), - SHELL_CMD_ARG(blink, NULL, "Blink GPIO", cmd_gpio_blink, 3, 0), - SHELL_SUBCMD_SET_END /* Array terminated. */ - ); + SHELL_CMD_ARG(conf, &sub_gpio_dev, + "Configure GPIO pin\n" + "Usage: gpio conf [u|d][h|l][0|1]>\n" + " - input|output\n" + "[u|d] - pull up|pull down, otherwise open\n" + "[h|l] - active high|active low, otherwise defaults to active high\n" + "[0|1] - initialise to logic 0|logic 1, otherwise defaults to logic 0", + cmd_gpio_conf, 4, 0), + SHELL_CMD_ARG(get, &sub_gpio_dev, + "Get GPIO pin value\n" + "Usage: gpio get ", cmd_gpio_get, 3, 0), + SHELL_CMD_ARG(set, &sub_gpio_dev, + "Set GPIO pin value\n" + "Usage: gpio set ", cmd_gpio_set, 4, 0), + SHELL_CMD_ARG(blink, &sub_gpio_dev, + "Blink GPIO pin\n" + "Usage: gpio blink ", cmd_gpio_blink, 3, 0), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); SHELL_CMD_REGISTER(gpio, &sub_gpio, "GPIO commands", NULL); From 695a0ac503a7d5ee2bbeb4f8a1a1af8d1ad007e1 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 15:37:53 +1100 Subject: [PATCH 3801/4498] drivers: gpio: shell: add info command Usage: gpio info [device] The new command prints gpio controller information for a specific device if specified or if no device is specified it prints out all controller information ordered by line name. Also added Kconfig option so this command can be removed if resources need to be conserved. Signed-off-by: Nick Ward --- drivers/gpio/Kconfig | 9 +++ drivers/gpio/gpio_shell.c | 147 +++++++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7ae1a8d0d93..51e86b026bb 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -20,6 +20,15 @@ config GPIO_SHELL help Enable GPIO Shell for testing. +config GPIO_SHELL_INFO_CMD + bool "GPIO Shell info command" + default y + depends on GPIO_SHELL + help + Enable GPIO Shell information command. + This command provides a shell user extra information about gpio + controller reserved pins and line names. + config GPIO_INIT_PRIORITY int "GPIO init priority" default KERNEL_INIT_PRIORITY_DEFAULT diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index e7dea06538f..6f867b65b8b 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -36,7 +36,6 @@ struct sh_gpio { const struct device *dev; gpio_pin_t pin; }; - /* * Find idx-th pin reference from the set of non reserved * pin numbers and provided line names. @@ -417,6 +416,149 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) SHELL_DYNAMIC_CMD_CREATE(sub_gpio_dev, device_name_get); +struct pin_info { + const struct device *dev; + bool reserved; + gpio_pin_t pin; + const char *line_name; +}; + +struct pin_order_user_data { + const struct shell *sh; + struct pin_info prev; + struct pin_info next; +}; + +typedef void (*pin_foreach_func_t)(const struct pin_info *info, void *user_data); + +static void print_gpio_ctrl_info(const struct shell *sh, const struct gpio_ctrl *ctrl) +{ + gpio_pin_t pin; + bool reserved; + + shell_print(sh, " ngpios: %u", ctrl->ngpios); + shell_print(sh, " Reserved pin mask: 0x%08X", ctrl->reserved_mask); + + shell_print(sh, ""); + + shell_print(sh, " Reserved Pin Line Name"); + for (pin = 0; pin < GPIO_MAX_PINS_PER_PORT; pin++) { + if ((pin >= ctrl->ngpios) && (pin >= ctrl->line_names_len)) { + /* Out of info */ + break; + } + reserved = (BIT64(pin) & ctrl->reserved_mask) != 0; + shell_print(sh, " %c %2u %s", reserved ? '*' : ' ', + pin, ctrl->line_names[pin]); + } +} + +static void foreach_pin(pin_foreach_func_t func, void *user_data) +{ + gpio_port_pins_t reserved_mask; + struct pin_info info; + gpio_pin_t pin; + size_t i; + + for (i = 0; i < ARRAY_SIZE(gpio_list); i++) { + for (pin = 0; pin < gpio_list[i].ngpios; pin++) { + info.dev = gpio_list[i].dev; + reserved_mask = gpio_list[i].reserved_mask; + info.reserved = (BIT64(pin) & reserved_mask) != 0; + info.pin = pin; + if (pin < gpio_list[i].line_names_len) { + info.line_name = gpio_list[i].line_names[pin]; + } else { + info.line_name = ""; + } + func(&info, user_data); + } + } +} + +static int pin_cmp(const struct pin_info *a, const struct pin_info *b) +{ + int result = strcmp(a->line_name, b->line_name); + + if (result != 0) { + return result; + } + result = strcmp(a->dev->name, b->dev->name); + if (result != 0) { + return result; + } + result = (int)a->pin - (int)b->pin; + + return result; +} + +static void pin_get_next(const struct pin_info *info, void *user_data) +{ + struct pin_order_user_data *data = user_data; + int result; + + if (data->prev.line_name != NULL) { + result = pin_cmp(info, &data->prev); + } else { + result = 1; + } + if (result > 0) { + if (data->next.line_name == NULL) { + data->next = *info; + return; + } + result = pin_cmp(info, &data->next); + if (result < 0) { + data->next = *info; + } + } +} + +static void pin_ordered(const struct pin_info *info, void *user_data) +{ + struct pin_order_user_data *data = user_data; + + ARG_UNUSED(info); + + foreach_pin(pin_get_next, data); + + shell_print(data->sh, " %-12s %-8c %-16s %2u", + data->next.line_name, + data->next.reserved ? '*' : ' ', + data->next.dev->name, + data->next.pin); + + data->prev = data->next; + data->next.line_name = NULL; +} + +static void print_ordered_info(const struct shell *sh) +{ + struct pin_order_user_data data = {0}; + + data.sh = sh; + + shell_print(sh, " %-12s %-8s %-16s %-3s", + "Line", "Reserved", "Device", "Pin"); + + foreach_pin(pin_ordered, &data); +} + +static int cmd_gpio_info(const struct shell *sh, size_t argc, char **argv) +{ + const struct gpio_ctrl *ctrl = get_gpio_ctrl(argv[ARGV_DEV]); + + if (ctrl == NULL) { + /* No device specified */ + print_ordered_info(sh); + return 0; + } + + print_gpio_ctrl_info(sh, ctrl); + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, SHELL_CMD_ARG(conf, &sub_gpio_dev, "Configure GPIO pin\n" @@ -435,6 +577,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, SHELL_CMD_ARG(blink, &sub_gpio_dev, "Blink GPIO pin\n" "Usage: gpio blink ", cmd_gpio_blink, 3, 0), + SHELL_COND_CMD_ARG(CONFIG_GPIO_SHELL_INFO_CMD, info, &sub_gpio_dev, + "GPIO Information\n" + "Usage: gpio info [device]", cmd_gpio_info, 1, 1), SHELL_SUBCMD_SET_END /* Array terminated. */ ); From 45509fdc0ed30d4590b65661d7d1da385c28095a Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 18:00:35 +1100 Subject: [PATCH 3802/4498] drivers: gpio: shell: make blink command optional Adds CONFIG_GPIO_SHELL_BLINK_CMD symbol. Saves around 300 bytes when command is disabled. Signed-off-by: Nick Ward --- drivers/gpio/Kconfig | 9 +++++++++ drivers/gpio/gpio_shell.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 51e86b026bb..07c3d6b47da 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -29,6 +29,15 @@ config GPIO_SHELL_INFO_CMD This command provides a shell user extra information about gpio controller reserved pins and line names. +config GPIO_SHELL_BLINK_CMD + bool "GPIO Shell blink command" + default y + depends on GPIO_SHELL + help + Enable GPIO Shell blink command. + This command provides a shell user the ability to 'blink' a pin + at 1Hz. + config GPIO_INIT_PRIORITY int "GPIO init priority" default KERNEL_INIT_PRIORITY_DEFAULT diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index 6f867b65b8b..ec5c0263702 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -574,7 +574,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, SHELL_CMD_ARG(set, &sub_gpio_dev, "Set GPIO pin value\n" "Usage: gpio set ", cmd_gpio_set, 4, 0), - SHELL_CMD_ARG(blink, &sub_gpio_dev, + SHELL_COND_CMD_ARG(CONFIG_GPIO_SHELL_BLINK_CMD, blink, &sub_gpio_dev, "Blink GPIO pin\n" "Usage: gpio blink ", cmd_gpio_blink, 3, 0), SHELL_COND_CMD_ARG(CONFIG_GPIO_SHELL_INFO_CMD, info, &sub_gpio_dev, From 738a1517b191850cc897fd14f47b1764246014a2 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sun, 22 Oct 2023 18:20:04 +1100 Subject: [PATCH 3803/4498] drivers: gpio: shell: optimise blink command Use gpio toggle api instead of manually toggling. Remove redundant text. Print error and break from blinking if it occurs. Only print 'how to exit' text if first toggle is successful. Saves roughly 40 bytes. Signed-off-by: Nick Ward --- drivers/gpio/gpio_shell.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index ec5c0263702..2c37a8ffcbf 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -368,9 +368,9 @@ static int cmd_gpio_set(const struct shell *sh, size_t argc, char **argv) static int cmd_gpio_blink(const struct shell *sh, size_t argc, char **argv) { + bool msg_one_shot = true; struct sh_gpio gpio; - size_t count = 0; - int value = 0; + size_t count; char data; int ret; @@ -380,9 +380,6 @@ static int cmd_gpio_blink(const struct shell *sh, size_t argc, char **argv) return SHELL_CMD_HELP_PRINTED; } - shell_fprintf(sh, SHELL_NORMAL, "Blinking port %s pin %u.", argv[ARGV_DEV], gpio.pin); - shell_fprintf(sh, SHELL_NORMAL, " Hit any key to exit"); - /* dummy read to clear any pending input */ (void)sh->iface->api->read(sh->iface, &data, sizeof(data), &count); @@ -391,13 +388,17 @@ static int cmd_gpio_blink(const struct shell *sh, size_t argc, char **argv) if (count != 0) { break; } - gpio_pin_set(gpio.dev, gpio.pin, value); - value = !value; + ret = gpio_pin_toggle(gpio.dev, gpio.pin); + if (ret != 0) { + shell_error(sh, "%d", ret); + break; + } else if (msg_one_shot) { + msg_one_shot = false; + shell_print(sh, "Hit any key to exit"); + } k_msleep(SLEEP_TIME_MS); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); - return 0; } From cd9f307e7169b5164b005895c37885e31210ba86 Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Mon, 23 Oct 2023 22:40:02 +1100 Subject: [PATCH 3804/4498] drivers: gpio: shell: add vendor specific flags argument Allow the optional setting of vendor specific flags in the conf command. Signed-off-by: Nick Ward --- drivers/gpio/gpio_shell.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index 2c37a8ffcbf..48d7e95f7a7 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -15,6 +15,7 @@ #define ARGV_PIN 2 #define ARGV_CONF 3 #define ARGV_VALUE 3 +#define ARGV_VENDOR_SPECIFIC 4 #define NGPIOS_UNKNOWN -1 #define PIN_NOT_FOUND UINT8_MAX @@ -221,6 +222,7 @@ static int get_sh_gpio(const struct shell *sh, char **argv, struct sh_gpio *gpio static int cmd_gpio_conf(const struct shell *sh, size_t argc, char **argv, void *data) { gpio_flags_t flags = 0; + gpio_flags_t vendor_specific; struct sh_gpio gpio; int ret = 0; @@ -304,6 +306,22 @@ static int cmd_gpio_conf(const struct shell *sh, size_t argc, char **argv, void return SHELL_CMD_HELP_PRINTED; } + if (argc == 5) { + vendor_specific = shell_strtoul(argv[ARGV_VENDOR_SPECIFIC], 0, &ret); + if ((ret == 0) && ((vendor_specific & ~(0xFF00U)) == 0)) { + flags |= vendor_specific; + } else { + /* + * See include/zephyr/dt-bindings/gpio/ for the + * available flags for your vendor. + */ + shell_error(sh, "vendor specific flags must be within " + "the mask 0xFF00"); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + ret = gpio_pin_configure(gpio.dev, gpio.pin, flags); if (ret != 0) { shell_error(sh, "error: %d", ret); @@ -563,12 +581,14 @@ static int cmd_gpio_info(const struct shell *sh, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, SHELL_CMD_ARG(conf, &sub_gpio_dev, "Configure GPIO pin\n" - "Usage: gpio conf [u|d][h|l][0|1]>\n" + "Usage: gpio conf [u|d][h|l][0|1]> [vendor specific]\n" " - input|output\n" "[u|d] - pull up|pull down, otherwise open\n" "[h|l] - active high|active low, otherwise defaults to active high\n" - "[0|1] - initialise to logic 0|logic 1, otherwise defaults to logic 0", - cmd_gpio_conf, 4, 0), + "[0|1] - initialise to logic 0|logic 1, otherwise defaults to logic 0\n" + "[vendor specific] - configuration flags within the mask 0xFF00\n" + " see include/zephyr/dt-bindings/gpio/", + cmd_gpio_conf, 4, 1), SHELL_CMD_ARG(get, &sub_gpio_dev, "Get GPIO pin value\n" "Usage: gpio get ", cmd_gpio_get, 3, 0), From 19d250e1dcaa2e764c258a416891582db13ec87c Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 13 Nov 2023 13:36:44 +0100 Subject: [PATCH 3805/4498] sysbuild: create sysbuild_cache function Create dedicated function, sysbuild_cache(), for handling sysbuild's image specific cache file. This provides a cleaner handling of said cache file, and provides a mechanism for updating the cache file at later sysbuild CMake stages. Signed-off-by: Torsten Rasmussen --- .../cmake/modules/sysbuild_extensions.cmake | 124 ++++++++++++------ 1 file changed, 82 insertions(+), 42 deletions(-) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index a3838415eee..9250c209c50 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -107,6 +107,87 @@ function(sysbuild_get variable) endif() endfunction() +# Usage: +# sysbuild_cache(CREATE APPLICATION [CMAKE_RERUN]) +# +# This function works on the sysbuild cache for sysbuild managed applications. +# +# Arguments: +# CREATE : Create or update existing sysbuild cache file for the application. +# The sysbuild cache is only updated if it contain changes. +# APPLICATION : Name of the application. +# CMAKE_RERUN : Force a CMake rerun for the application during next build +# invocation if the sysbuild cache has changed. It is +# advised to always use this flag. Not using this flag can +# reduce build time, but only do so if application is +# guranteed to be up-to-date. +# +function(sysbuild_cache) + cmake_parse_arguments(SB_CACHE "CREATE;CMAKE_RERUN" "APPLICATION" "" ${ARGN}) + zephyr_check_arguments_required(sysbuild_cache SB_CACHE APPLICATION) + zephyr_check_flags_required(sysbuild_cache SB_CACHE CREATE) + + get_target_property(${SB_CACHE_APPLICATION}_MAIN_APP ${SB_CACHE_APPLICATION} MAIN_APP) + get_cmake_property(sysbuild_cache CACHE_VARIABLES) + + foreach(var_name ${sysbuild_cache}) + if(NOT "${var_name}" MATCHES "^(CMAKE_.*|BOARD)$") + # Perform a dummy read to prevent a false warning about unused variables + # being emitted due to a cmake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/24555 + set(unused_tmp_var ${${var_name}}) + + # We don't want to pass internal CMake variables. + # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be + # passed using `-D` on command invocation. + get_property(var_type CACHE ${var_name} PROPERTY TYPE) + set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}") + string(REPLACE ";" "\;" cache_entry "${cache_entry}") + list(APPEND sysbuild_cache_strings "${cache_entry}\n") + endif() + endforeach() + if(DEFINED BOARD_REVISION) + list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n") + else() + list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n") + endif() + list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${SB_CACHE_APPLICATION}\n") + + if(${SB_CACHE_APPLICATION}_MAIN_APP) + list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") + endif() + + if(${SB_CACHE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${SB_CACHE_APPLICATION}_BOARD}) + # Only set image specific board if provided. + # The sysbuild BOARD is exported through sysbuild cache, and will be used + # unless _BOARD is defined. + list(APPEND sysbuild_cache_strings + "${SB_CACHE_APPLICATION}_BOARD:STRING=${${SB_CACHE_APPLICATION}_BOARD}\n" + ) + endif() + + get_target_property(${SB_CACHE_APPLICATION}_CACHE_FILE ${SB_CACHE_APPLICATION} CACHE_FILE) + file(WRITE ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings}) + if(SB_CACHE_CMAKE_RERUN) + execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files + ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp + ${${SB_CACHE_APPLICATION}_CACHE_FILE} + RESULT_VARIABLE compare_res + ) + if(NOT compare_res EQUAL 0) + zephyr_file_copy(${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp + ${${SB_CACHE_APPLICATION}_CACHE_FILE} + ) + ExternalProject_Get_Property(${SB_CACHE_APPLICATION} BINARY_DIR) + file(TOUCH_NOCREATE ${BINARY_DIR}/CMakeCache.txt) + endif() + else() + zephyr_file_copy(${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp + ${${SB_CACHE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT + ) + endif() + +endfunction() + # Usage: # ExternalZephyrProject_Add(APPLICATION # SOURCE_DIR

    @@ -372,9 +453,7 @@ function(ExternalZephyrProject_Cmake) ) ExternalProject_Get_Property(${ZCMAKE_APPLICATION} SOURCE_DIR BINARY_DIR CMAKE_ARGS) - get_target_property(${ZCMAKE_APPLICATION}_CACHE_FILE ${ZCMAKE_APPLICATION} CACHE_FILE) get_target_property(${ZCMAKE_APPLICATION}_BOARD ${ZCMAKE_APPLICATION} BOARD) - get_target_property(${ZCMAKE_APPLICATION}_MAIN_APP ${ZCMAKE_APPLICATION} MAIN_APP) get_property(${ZCMAKE_APPLICATION}_CONF_SCRIPT TARGET ${ZCMAKE_APPLICATION} PROPERTY IMAGE_CONF_SCRIPT @@ -390,46 +469,7 @@ function(ExternalZephyrProject_Cmake) endif() endforeach() - get_cmake_property(sysbuild_cache CACHE_VARIABLES) - foreach(var_name ${sysbuild_cache}) - if(NOT "${var_name}" MATCHES "^(CMAKE_.*|BOARD)$") - # Perform a dummy read to prevent a false warning about unused variables - # being emitted due to a cmake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/24555 - set(unused_tmp_var ${${var_name}}) - - # We don't want to pass internal CMake variables. - # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be - # passed using `-D` on command invocation. - get_property(var_type CACHE ${var_name} PROPERTY TYPE) - set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}") - string(REPLACE ";" "\;" cache_entry "${cache_entry}") - list(APPEND sysbuild_cache_strings "${cache_entry}\n") - endif() - endforeach() - if(DEFINED BOARD_REVISION) - list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n") - else() - list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n") - endif() - list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${ZCMAKE_APPLICATION}\n") - - if(${ZCMAKE_APPLICATION}_MAIN_APP) - list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") - endif() - - if(${ZCMAKE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${ZCMAKE_APPLICATION}_BOARD}) - # Only set image specific board if provided. - # The sysbuild BOARD is exported through sysbuild cache, and will be used - # unless _BOARD is defined. - list(APPEND sysbuild_cache_strings - "${ZCMAKE_APPLICATION}_BOARD:STRING=${${ZCMAKE_APPLICATION}_BOARD}\n" - ) - endif() - - file(WRITE ${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings}) - zephyr_file_copy(${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp - ${${ZCMAKE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT - ) + sysbuild_cache(CREATE APPLICATION ${ZCMAKE_APPLICATION}) foreach(script ${${ZCMAKE_APPLICATION}_CONF_SCRIPT}) include(${script}) From bc08e801c6b1416dcbbc679f5e25f801d438a531 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 14 Nov 2023 15:23:55 +0100 Subject: [PATCH 3806/4498] native_sim build: Fix for APPLICATION_BINARY_DIR!=CMAKE_BINARY_DIR In some cases, the APPLICATION_BINARY_DIR does not match the CMAKE_BINARY_DIR, in those cases the native simulator build would not find the zephyr elf file. Fix it by using the correct variable. Signed-off-by: Alberto Escolar Piedras --- CMakeLists.txt | 2 +- boards/posix/common/natsim_config.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c29fa6885a4..164d82fde0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1762,7 +1762,7 @@ if(CONFIG_BUILD_OUTPUT_EXE) COMMENT "Building native simulator runner, and linking final executable" COMMAND ${MAKE} -f ${ZEPHYR_BASE}/scripts/native_simulator/Makefile all --warn-undefined-variables - -r NSI_CONFIG_FILE=${CMAKE_BINARY_DIR}/zephyr/NSI/nsi_config + -r NSI_CONFIG_FILE=${APPLICATION_BINARY_DIR}/zephyr/NSI/nsi_config # nsi_config is created by the board cmake file DEPENDS ${logical_target_for_zephyr_elf} BYPRODUCTS ${KERNEL_EXE_NAME} diff --git a/boards/posix/common/natsim_config.cmake b/boards/posix/common/natsim_config.cmake index 576e4b9b637..2ab155af105 100644 --- a/boards/posix/common/natsim_config.cmake +++ b/boards/posix/common/natsim_config.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -set(zephyr_build_path ${CMAKE_BINARY_DIR}/zephyr) +set(zephyr_build_path ${APPLICATION_BINARY_DIR}/zephyr) get_property(CCACHE GLOBAL PROPERTY RULE_LAUNCH_COMPILE) target_link_options(native_simulator INTERFACE From 2dce408bc3237e8b5a7e8cd026a6dfc2a929b97a Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Thu, 12 Oct 2023 12:58:40 +0200 Subject: [PATCH 3807/4498] drivers: serial: uart_liteuart: fix interrupt-driven mode Interrupt-driven mode was not working, and disabled by default. When it was forced on, the behavior was to only have a few bytes: as many as min(CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE, 9). After the hardware FIFO was filled by software and emptied by hardware, no interrupt occured, and enqueuing more data did never happen. By letting the events enabled for TX (only), then interrupts are still generated after the first transfer, and the software can then add the subsequent transfers until all data is print: the UART works. It does not generate endless interrupts either, which was tested by adding litex_write8('%', UART_RXTX_ADDR) in liteuart_uart_irq_handler() to log all interrupts events, and when there is nothing to print, no interrupt is fired. It was tested with the Zephyr shell. Fixes #63794 Signed-off-by: Josuah Demangeon --- drivers/serial/uart_liteuart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/serial/uart_liteuart.c b/drivers/serial/uart_liteuart.c index 073d565770e..d23b68b7c5c 100644 --- a/drivers/serial/uart_liteuart.c +++ b/drivers/serial/uart_liteuart.c @@ -273,8 +273,8 @@ static void liteuart_uart_irq_handler(const struct device *dev) data->callback(dev, data->cb_data); } - /* clear events */ - litex_write8(UART_EV_TX | UART_EV_RX, UART_EV_PENDING_ADDR); + /* Clear RX events, TX events still needed to enqueue the next transfer */ + litex_write8(UART_EV_RX, UART_EV_PENDING_ADDR); irq_unlock(key); } From ce3ba0dfd2620e3566face861d2c22ff5765e137 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 17 Nov 2023 09:47:18 +0000 Subject: [PATCH 3808/4498] modules: openthread: platform: radio: Rename missed type Fixes an issue whereby a rename of a variable type has been forgotten in an instance, which now uses the correct type name Signed-off-by: Jamie McCrae --- modules/openthread/platform/radio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 9c5de3c9d69..98eab182aad 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -1431,7 +1431,7 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a header_ie_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, aLinkMetrics.mRssi, header_ie_buf); - config.ack_ie.header_ie = (struct ieee802154_ie_header *)header_ie_buf; + config.ack_ie.header_ie = (struct ieee802154_header_ie *)header_ie_buf; result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); return result ? OT_ERROR_FAILED : OT_ERROR_NONE; From 4c92419546abf0d9193009a2b622f93d572d4b6b Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Fri, 22 Sep 2023 17:23:29 -0700 Subject: [PATCH 3809/4498] drivers: sensor: hs300x: Add driver for Renesas HS300x sensors Adds support for Renesas HS3001 and HS3003 temperature/humidity sensors connected via an I2C bus. Signed-off-by: Ian Morris --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/hs300x/CMakeLists.txt | 5 + drivers/sensor/hs300x/Kconfig | 12 ++ drivers/sensor/hs300x/hs300x.c | 160 ++++++++++++++++++++++++ dts/bindings/sensor/renesas,hs300x.yaml | 10 ++ tests/drivers/build_all/sensor/i2c.dtsi | 5 + 7 files changed, 194 insertions(+) create mode 100644 drivers/sensor/hs300x/CMakeLists.txt create mode 100644 drivers/sensor/hs300x/Kconfig create mode 100644 drivers/sensor/hs300x/hs300x.c create mode 100644 dts/bindings/sensor/renesas,hs300x.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index ff1cf9ec4eb..2fa37289ac2 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -47,6 +47,7 @@ add_subdirectory_ifdef(CONFIG_HAS_STMEMSC stmemsc) add_subdirectory_ifdef(CONFIG_HM330X hm330x) add_subdirectory_ifdef(CONFIG_HMC5883L hmc5883l) add_subdirectory_ifdef(CONFIG_HP206C hp206c) +add_subdirectory_ifdef(CONFIG_HS300X hs300x) add_subdirectory_ifdef(CONFIG_HTS221 hts221) add_subdirectory_ifdef(CONFIG_I3G4250D i3g4250d) add_subdirectory_ifdef(CONFIG_ICM42605 icm42605) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 55ef3ffec51..25af39bde4c 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -119,6 +119,7 @@ source "drivers/sensor/grow_r502a/Kconfig" source "drivers/sensor/hm330x/Kconfig" source "drivers/sensor/hmc5883l/Kconfig" source "drivers/sensor/hp206c/Kconfig" +source "drivers/sensor/hs300x/Kconfig" source "drivers/sensor/hts221/Kconfig" source "drivers/sensor/i3g4250d/Kconfig" source "drivers/sensor/icm42605/Kconfig" diff --git a/drivers/sensor/hs300x/CMakeLists.txt b/drivers/sensor/hs300x/CMakeLists.txt new file mode 100644 index 00000000000..f937e6bb6f1 --- /dev/null +++ b/drivers/sensor/hs300x/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(hs300x.c) diff --git a/drivers/sensor/hs300x/Kconfig b/drivers/sensor/hs300x/Kconfig new file mode 100644 index 00000000000..53060cb5c21 --- /dev/null +++ b/drivers/sensor/hs300x/Kconfig @@ -0,0 +1,12 @@ +# Renesas HS300x temperature and humidity sensor configuration options + +# Copyright (c) 2023 Ian Morris +# SPDX-License-Identifier: Apache-2.0 + +config HS300X + bool "HS300x Temperature and Humidity Sensor" + default y + depends on DT_HAS_RENESAS_HS300X_ENABLED + select I2C + help + Enable driver for HS300x temperature and humidity sensors. diff --git a/drivers/sensor/hs300x/hs300x.c b/drivers/sensor/hs300x/hs300x.c new file mode 100644 index 00000000000..9faabbb1e35 --- /dev/null +++ b/drivers/sensor/hs300x/hs300x.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2023 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_hs300x + +#include +#include +#include +#include +#include +#include +#include + +#define HS300X_STATUS_MASK (BIT(0) | BIT(1)) + +LOG_MODULE_REGISTER(HS300X, CONFIG_SENSOR_LOG_LEVEL); + +struct hs300x_config { + struct i2c_dt_spec bus; +}; + +struct hs300x_data { + int16_t t_sample; + uint16_t rh_sample; +}; + +static int hs300x_read_sample(const struct device *dev, uint16_t *t_sample, uint16_t *rh_sample) +{ + const struct hs300x_config *cfg = dev->config; + uint8_t rx_buf[4]; + int rc; + + rc = i2c_read_dt(&cfg->bus, rx_buf, sizeof(rx_buf)); + if (rc < 0) { + LOG_ERR("Failed to read data from device."); + return rc; + } + + if ((rx_buf[3] & HS300X_STATUS_MASK) != 0) { + LOG_ERR("Stale data"); + return -EIO; + } + + *rh_sample = sys_get_be16(rx_buf); + *t_sample = sys_get_be16(&rx_buf[2]); + + /* Remove status bits (only present in temperature value)*/ + *t_sample >>= 2; + + return 0; +} + +static int hs300x_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct hs300x_data *data = dev->data; + const struct hs300x_config *cfg = dev->config; + int rc; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP && + chan != SENSOR_CHAN_HUMIDITY) { + return -ENOTSUP; + } + + /* + * Initiate a measurement simply by sending 7-bit address followed + * by an eighth bit set to 0 (write) and NO data. + */ + rc = i2c_write_dt(&cfg->bus, NULL, 0); + if (rc < 0) { + LOG_ERR("Failed to start measurement."); + return rc; + } + + /* + * According to datasheet maximum time to make temperature and humidity + * measurements is 33ms, add a little safety margin... + */ + k_msleep(50); + + rc = hs300x_read_sample(dev, &data->t_sample, &data->rh_sample); + if (rc < 0) { + LOG_ERR("Failed to fetch data."); + return rc; + } + + return 0; +} + +static void hs300x_temp_convert(struct sensor_value *val, int16_t raw) +{ + int32_t micro_c; + + /* + * Convert to micro Celsius. See datasheet "Calculating Humidity and + * Temperature Output" section for more details on processing sample data. + */ + micro_c = (((int64_t)raw * 165000000) / 16383) - 40000000; + + val->val1 = micro_c / 1000000; + val->val2 = micro_c % 1000000; +} + +static void hs300x_rh_convert(struct sensor_value *val, uint16_t raw) +{ + int32_t micro_rh; + + /* + * Convert to micro %RH. See datasheet "Calculating Humidity and + * Temperature Output" section for more details on processing sample data. + */ + micro_rh = ((uint64_t)raw * 100000000) / 16383; + + val->val1 = micro_rh / 1000000; + val->val2 = micro_rh % 1000000; +} + +static int hs300x_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + const struct hs300x_data *data = dev->data; + + if (chan == SENSOR_CHAN_AMBIENT_TEMP) { + hs300x_temp_convert(val, data->t_sample); + } else if (chan == SENSOR_CHAN_HUMIDITY) { + hs300x_rh_convert(val, data->rh_sample); + } else { + return -ENOTSUP; + } + + return 0; +} + +static int hs300x_init(const struct device *dev) +{ + const struct hs300x_config *cfg = dev->config; + + if (!i2c_is_ready_dt(&cfg->bus)) { + LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name); + return -ENODEV; + } + + return 0; +} + +static const struct sensor_driver_api hs300x_driver_api = {.sample_fetch = hs300x_sample_fetch, + .channel_get = hs300x_channel_get}; + +#define DEFINE_HS300X(n) \ + static struct hs300x_data hs300x_data_##n; \ + \ + static const struct hs300x_config hs300x_config_##n = {.bus = I2C_DT_SPEC_INST_GET(n)}; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, hs300x_init, NULL, &hs300x_data_##n, &hs300x_config_##n, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &hs300x_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_HS300X) diff --git a/dts/bindings/sensor/renesas,hs300x.yaml b/dts/bindings/sensor/renesas,hs300x.yaml new file mode 100644 index 00000000000..cd24b67da74 --- /dev/null +++ b/dts/bindings/sensor/renesas,hs300x.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023 Ian Morris +# +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas HS300x humidity and temperature sensor + +compatible: "renesas,hs300x" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index ebafddab96c..ce22576c48a 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -807,3 +807,8 @@ test_i2c_lps22df: lps22df@79 { drdy-gpios = <&test_gpio 0 0>; status = "okay"; }; + +test_i2c_hs300x: hs300x@79 { + compatible = "renesas,hs300x"; + reg = <0x79>; +}; From dfc747d53a07b1219c7a962ca64a8edadf05f5f2 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Fri, 22 Sep 2023 17:38:07 -0700 Subject: [PATCH 3810/4498] samples: sensor: dht_polling: Add generic dht sample application This simple application periodically prints the temperature and humidity measured by one or more digital humidity/temperature sensors. Signed-off-by: Ian Morris --- samples/sensor/dht_polling/CMakeLists.txt | 9 +++ samples/sensor/dht_polling/README.rst | 49 +++++++++++++++ .../dht_polling/boards/nucleo_f401re.overlay | 22 +++++++ samples/sensor/dht_polling/prj.conf | 2 + samples/sensor/dht_polling/sample.yaml | 20 ++++++ samples/sensor/dht_polling/src/main.c | 62 +++++++++++++++++++ 6 files changed, 164 insertions(+) create mode 100644 samples/sensor/dht_polling/CMakeLists.txt create mode 100644 samples/sensor/dht_polling/README.rst create mode 100644 samples/sensor/dht_polling/boards/nucleo_f401re.overlay create mode 100644 samples/sensor/dht_polling/prj.conf create mode 100644 samples/sensor/dht_polling/sample.yaml create mode 100644 samples/sensor/dht_polling/src/main.c diff --git a/samples/sensor/dht_polling/CMakeLists.txt b/samples/sensor/dht_polling/CMakeLists.txt new file mode 100644 index 00000000000..31b4352da9d --- /dev/null +++ b/samples/sensor/dht_polling/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Ian Morris +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(dht_polling) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/dht_polling/README.rst b/samples/sensor/dht_polling/README.rst new file mode 100644 index 00000000000..09550b255d0 --- /dev/null +++ b/samples/sensor/dht_polling/README.rst @@ -0,0 +1,49 @@ +.. _dht_polling: + +Generic Digital Humidity Temperature sensor polling sample +########################################################## + +Overview +******** + +This sample application demonstrates how to use digital humidity temperature +sensors. + +Building and Running +******************** + +This sample supports up to 10 humidity/temperature sensors. Each sensor needs to +be aliased as ``dhtN`` where ``N`` goes from ``0`` to ``9``. For example: + +.. code-block:: devicetree + + / { + aliases { + dht0 = &hs300x; + }; + }; + +Make sure the aliases are in devicetree, then build and run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/dht_polling + :board: + :goals: build flash + :compact: + +Sample Output +============= + +.. code-block:: console + + hs300x@44: temp is 25.31 °C humidity is 30.39 %RH + hs300x@44: temp is 25.51 °C humidity is 30.44 %RH + hs300x@44: temp is 25.51 °C humidity is 30.37 %RH + hs300x@44: temp is 25.51 °C humidity is 30.39 %RH + hs300x@44: temp is 25.31 °C humidity is 30.37 %RH + hs300x@44: temp is 25.31 °C humidity is 30.35 %RH + hs300x@44: temp is 25.51 °C humidity is 30.37 %RH + hs300x@44: temp is 25.51 °C humidity is 30.37 %RH + hs300x@44: temp is 25.51 °C humidity is 30.39 %RH + hs300x@44: temp is 25.51 °C humidity is 30.44 %RH + hs300x@44: temp is 25.51 °C humidity is 30.53 %RH diff --git a/samples/sensor/dht_polling/boards/nucleo_f401re.overlay b/samples/sensor/dht_polling/boards/nucleo_f401re.overlay new file mode 100644 index 00000000000..cb381b5ba3a --- /dev/null +++ b/samples/sensor/dht_polling/boards/nucleo_f401re.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + dht0 = &hs300x; + }; +}; + + &i2c1 { + status = "okay"; + + hs300x: hs300x@44 { + compatible = "renesas,hs300x"; + reg = <0x44>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/samples/sensor/dht_polling/prj.conf b/samples/sensor/dht_polling/prj.conf new file mode 100644 index 00000000000..7d668be1f0b --- /dev/null +++ b/samples/sensor/dht_polling/prj.conf @@ -0,0 +1,2 @@ +CONFIG_STDOUT_CONSOLE=y +CONFIG_SENSOR=y diff --git a/samples/sensor/dht_polling/sample.yaml b/samples/sensor/dht_polling/sample.yaml new file mode 100644 index 00000000000..8177e636d21 --- /dev/null +++ b/samples/sensor/dht_polling/sample.yaml @@ -0,0 +1,20 @@ +# +# Copyright (c) 2023 Ian Morris +# +# SPDX-License-Identifier: Apache-2.0 +# + +sample: + description: Digital Humidity Temperature polling sample + name: DHT polling sample +tests: + sample.sensor.dht_polling: + tags: sensors + filter: dt_alias_exists("dht0") + integration_platforms: + - nucleo_f401re + harness: console + harness_config: + type: one_line + regex: + - "[0-9A-Za-z_,+-.]*@[0-9A-Fa-f]*: temp is (.*) °C humidity is (.*) %RH" diff --git a/samples/sensor/dht_polling/src/main.c b/samples/sensor/dht_polling/src/main.c new file mode 100644 index 00000000000..8ff26b5ab9b --- /dev/null +++ b/samples/sensor/dht_polling/src/main.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include + +#define DHT_ALIAS(i) DT_ALIAS(_CONCAT(dht, i)) +#define DHT_DEVICE(i, _) \ + IF_ENABLED(DT_NODE_EXISTS(DHT_ALIAS(i)), (DEVICE_DT_GET(DHT_ALIAS(i)),)) + +/* Support up to 10 temperature/humidity sensors */ +static const struct device *const sensors[] = {LISTIFY(10, DHT_DEVICE, ())}; + +int main(void) +{ + int rc; + + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + if (!device_is_ready(sensors[i])) { + printk("sensor: device %s not ready.\n", sensors[i]->name); + return 0; + } + } + + while (1) { + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + struct device *dev = (struct device *)sensors[i]; + + rc = sensor_sample_fetch(dev); + if (rc < 0) { + printk("%s: sensor_sample_fetch() failed: %d\n", dev->name, rc); + return rc; + } + + struct sensor_value temp; + struct sensor_value hum; + + rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); + if (rc == 0) { + rc = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &hum); + } + if (rc != 0) { + printf("get failed: %d\n", rc); + break; + } + + printk("%16s: temp is %d.%02d °C humidity is %d.%02d %%RH\n", + dev->name, temp.val1, temp.val2 / 10000, + hum.val1, hum.val2 / 10000); + } + k_msleep(1000); + } + return 0; +} From 4cfd4b5379ee200e76358e17e90aabe0a55f5365 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Mon, 30 Oct 2023 15:14:12 +0800 Subject: [PATCH 3811/4498] driver: timer: npcx: fix announce/set timer timeout tick The timer driver doesn't annouce/set the timeout at the tick boundary but at the absolute next expiration time. It will cause the accumatlation of the tick drift and cannot pass the kernel/timer/timer_behavior test suite. This commit fixes the tick drift problem by annouce the time at the tick bouandry. Fixes #59594 Signed-off-by: Jun Lin --- drivers/timer/npcx_itim_timer.c | 38 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/timer/npcx_itim_timer.c b/drivers/timer/npcx_itim_timer.c index a54db566d9e..fba2bc2b3c1 100644 --- a/drivers/timer/npcx_itim_timer.c +++ b/drivers/timer/npcx_itim_timer.c @@ -58,6 +58,7 @@ LOG_MODULE_REGISTER(itim, LOG_LEVEL_ERR); #define NPCX_ITIM_CLK_SEL_DELAY 92 /* Delay for clock selection (Unit:us) */ /* Timeout for enabling ITIM module: 100us (Unit:cycles) */ #define NPCX_ITIM_EN_TIMEOUT_CYCLES (100 * SYS_CYCLES_PER_USEC) +#define SYS_CYC_PER_EVT_CYC (sys_clock_hw_cycles_per_sec() / EVT_CYCLES_PER_SEC) /* Instance of system and event timers */ static struct itim64_reg *const sys_tmr = (struct itim64_reg *) @@ -70,6 +71,9 @@ static const struct npcx_clk_cfg itim_clk_cfg[] = NPCX_DT_CLK_CFG_ITEMS_LIST(0); static struct k_spinlock lock; /* Announced cycles in system timer before executing sys_clock_announce() */ static uint64_t cyc_sys_announced; +static uint64_t last_ticks; +static uint32_t last_elapsed; + /* Current target cycles of time-out signal in event timer */ static uint32_t cyc_evt_timeout; /* Total cycles of system timer stopped in "sleep/deep sleep" mode */ @@ -136,18 +140,33 @@ static inline void npcx_itim_evt_disable(void) /* ITIM local functions */ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) { + k_spinlock_key_t key = k_spin_lock(&lock); + /* * Get desired cycles of event timer from the requested ticks which * round up to next tick boundary. */ + if (ticks == K_TICKS_FOREVER) { cyc_evt_timeout = NPCX_ITIM32_MAX_CNT; } else { + uint64_t next_cycs; + uint64_t curr = npcx_itim_get_sys_cyc64(); + uint32_t dcycles; + if (ticks <= 0) { ticks = 1; } - cyc_evt_timeout = MIN(EVT_CYCLES_FROM_TICKS(ticks), - NPCX_ITIM32_MAX_CNT); + + next_cycs = (last_ticks + last_elapsed + ticks) * SYS_CYCLES_PER_TICK; + if (unlikely(next_cycs <= curr)) { + cyc_evt_timeout = 1; + } else { + dcycles = next_cycs - curr; + cyc_evt_timeout = + CLAMP((dcycles / SYS_CYC_PER_EVT_CYC), 1, NPCX_ITIM32_MAX_CNT); + } + } LOG_DBG("ticks %x, cyc_evt_timeout %x", ticks, cyc_evt_timeout); @@ -159,9 +178,9 @@ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) /* Upload counter of event timer */ evt_tmr->ITCNT32 = MAX(cyc_evt_timeout - 1, 1); + k_spin_unlock(&lock, key); /* Enable event timer and start ticking */ return npcx_itim_evt_enable(); - } static void npcx_itim_evt_isr(const struct device *dev) @@ -175,11 +194,12 @@ static void npcx_itim_evt_isr(const struct device *dev) if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { k_spinlock_key_t key = k_spin_lock(&lock); - uint32_t delta_ticks = (uint32_t)((npcx_itim_get_sys_cyc64() - - cyc_sys_announced) / SYS_CYCLES_PER_TICK); + uint64_t curr = npcx_itim_get_sys_cyc64(); + uint32_t delta_ticks = (uint32_t)((curr - cyc_sys_announced) / SYS_CYCLES_PER_TICK); - /* Store announced cycles of system timer */ - cyc_sys_announced = npcx_itim_get_sys_cyc64(); + cyc_sys_announced += delta_ticks * SYS_CYCLES_PER_TICK; + last_ticks += delta_ticks; + last_elapsed = 0; k_spin_unlock(&lock, key); /* Informs kernel that specified number of ticks have elapsed */ @@ -252,11 +272,13 @@ uint32_t sys_clock_elapsed(void) k_spinlock_key_t key = k_spin_lock(&lock); uint64_t delta_cycle = npcx_itim_get_sys_cyc64() - cyc_sys_announced; + uint32_t delta_ticks = (uint32_t)delta_cycle / SYS_CYCLES_PER_TICK; + last_elapsed = delta_ticks; k_spin_unlock(&lock, key); /* Return how many ticks elapsed since last sys_clock_announce() call */ - return (uint32_t)(delta_cycle / SYS_CYCLES_PER_TICK); + return delta_ticks; } uint32_t sys_clock_cycle_get_32(void) From 317d0702221d281fb498ac763baacd882b23f746 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Thu, 2 Nov 2023 11:06:15 +0800 Subject: [PATCH 3812/4498] tests: timer_behavior: increase stdev tolerance for npcx timer Change the stdev tolerance stdev from 10 to 33 when npcx timer is used. This is because the clock source of npcx event timer, which is used to generate the timeout interrupt, is running at 32.768 KHz. (i.e. 1 count = ~30.5 us.) The conversion from the absolute system timer to the event timer count might have -30.5 ~ 30.5 deviation. The tolerance setting is under the assumption that test sampes are evenly located at 1030.5 and 969.5 for the worst case. Fixes #59594 Signed-off-by: Jun Lin --- tests/kernel/timer/timer_behavior/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/kernel/timer/timer_behavior/Kconfig b/tests/kernel/timer/timer_behavior/Kconfig index 9e5d80532f1..ba5f18e969e 100644 --- a/tests/kernel/timer/timer_behavior/Kconfig +++ b/tests/kernel/timer/timer_behavior/Kconfig @@ -23,6 +23,7 @@ config TIMER_TEST_PERIOD config TIMER_TEST_MAX_STDDEV int "Maximum standard deviation in microseconds allowed" + default 33 if NPCX_ITIM_TIMER default 10 config TIMER_TEST_MAX_DRIFT From da3d9197a650977a08dbb2ba409feca6b00f5996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 16 Nov 2023 23:45:19 +0700 Subject: [PATCH 3813/4498] include: arm: nxp_mpu: remove redundant HAL include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inclusion of `fsl_common.h` solely for defining `NXP_MPU_BASE` is redundant, as this symbol is not used. Consequently, this unnecessary inclusion leads to the pervasive inclusion of HAL headers through kernel headers. The needed HAL definitions are already included into the NXP MPU driver implementation via the SoC header. Signed-off-by: Manuel Argüelles --- include/zephyr/arch/arm/mpu/nxp_mpu.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/zephyr/arch/arm/mpu/nxp_mpu.h b/include/zephyr/arch/arm/mpu/nxp_mpu.h index 2b40050afa4..d1f5882bfed 100644 --- a/include/zephyr/arch/arm/mpu/nxp_mpu.h +++ b/include/zephyr/arch/arm/mpu/nxp_mpu.h @@ -8,10 +8,6 @@ #ifndef _ASMLANGUAGE -#include - -#define NXP_MPU_BASE SYSMPU_BASE - #define NXP_MPU_REGION_NUMBER 12 /* Bus Master User Mode Access */ From 92fb8b223825bb3d8714017743c453a225eb6dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Arg=C3=BCelles?= Date: Thu, 16 Nov 2023 21:13:31 +0700 Subject: [PATCH 3814/4498] arm: nxp_mpu: enable module's clock only when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NXP SYSMPU is used in other SoCs besides the Kinetis series. For devices like S32K1xx, its bus interface clock lacks of clock gating and it's driven by the system clock. Hence, only enable the module clock for the Kinetis series. Signed-off-by: Manuel Argüelles --- arch/arm/core/mpu/nxp_mpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index f3d3bd715ae..39d7cde6f8f 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -37,8 +37,10 @@ static uint8_t static_regions_num; /* Global MPU configuration at system initialization. */ static void mpu_init(void) { +#if defined(CONFIG_SOC_FAMILY_KINETIS) /* Enable clock for the Memory Protection Unit (MPU). */ CLOCK_EnableClock(kCLOCK_Sysmpu0); +#endif } /** From 21d885535e7da4fe658056205b06493a687cf66f Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 17 Nov 2023 11:29:45 -0500 Subject: [PATCH 3815/4498] MAINTAINERS: declare myself as a RISC-V collaborator ... given that 62.5% of the code in arch/riscv/core/* is mine. Signed-off-by: Nicolas Pitre --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index aa4fbaadced..f03d141e475 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2281,6 +2281,7 @@ RISCV arch: - katsuster - edersondisouza - carlocaione + - npitre files: - arch/riscv/ - boards/riscv/ From b485cd717bea008f66cc3452f65f2b45bd1cc1ab Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 17 Nov 2023 10:31:14 -0800 Subject: [PATCH 3816/4498] xtensa: remove unused z_mp_entry declaration z_mp_entry has been removed from Xtensa architecture. So there is no need for a function declaration. Remove it. Signed-off-by: Daniel Leung --- arch/xtensa/core/crt1.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/xtensa/core/crt1.S b/arch/xtensa/core/crt1.S index 1f9cc148ab5..0fa3ad23099 100644 --- a/arch/xtensa/core/crt1.S +++ b/arch/xtensa/core/crt1.S @@ -23,7 +23,6 @@ .global __start .type z_cstart, @function -.type z_mp_entry, @function #ifdef CONFIG_XTENSA_MMU .type z_xtensa_mmu_init, @function From 0d1fa268bb598033de961d9a0130d9cb2c16bebd Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Sun, 11 Jun 2023 17:07:42 -0400 Subject: [PATCH 3817/4498] drivers: clock_control: Add PWM clock device Adds a clock control device for a PWM node, allowing the PWM to be controlled using the clock control API. It is a similar idea to the device driver in linux: linux/Documentation/devicetree/bindings/clock/pwm-clock.yaml Signed-off-by: Andriy Gelman --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.pwm | 18 ++ drivers/clock_control/clock_control_pwm.c | 159 ++++++++++++++++++ dts/bindings/clock/pwm-clock.yaml | 54 ++++++ .../clock_control/pwm_clock/CMakeLists.txt | 7 + .../pwm_clock/boards/sam_v71_xult.overlay | 25 +++ .../pwm_clock/boards/xmc45_relax_kit.overlay | 26 +++ .../pwm_clock/boards/xmc47_relax_kit.overlay | 26 +++ .../test-clock-control-clock-pwm.yaml | 10 ++ .../drivers/clock_control/pwm_clock/prj.conf | 2 + .../clock_control/pwm_clock/src/main.c | 74 ++++++++ .../clock_control/pwm_clock/testcase.yaml | 7 + 13 files changed, 411 insertions(+) create mode 100644 drivers/clock_control/Kconfig.pwm create mode 100644 drivers/clock_control/clock_control_pwm.c create mode 100644 dts/bindings/clock/pwm-clock.yaml create mode 100644 tests/drivers/clock_control/pwm_clock/CMakeLists.txt create mode 100644 tests/drivers/clock_control/pwm_clock/boards/sam_v71_xult.overlay create mode 100644 tests/drivers/clock_control/pwm_clock/boards/xmc45_relax_kit.overlay create mode 100644 tests/drivers/clock_control/pwm_clock/boards/xmc47_relax_kit.overlay create mode 100644 tests/drivers/clock_control/pwm_clock/dts/bindings/test-clock-control-clock-pwm.yaml create mode 100644 tests/drivers/clock_control/pwm_clock/prj.conf create mode 100644 tests/drivers/clock_control/pwm_clock/src/main.c create mode 100644 tests/drivers/clock_control/pwm_clock/testcase.yaml diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 0f7a1c4dd4a..a1f553fc134 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -28,6 +28,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RA clock_control_ra.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_PWM clock_control_pwm.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index a380b9a9c12..37cbb2e2895 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -84,4 +84,6 @@ source "drivers/clock_control/Kconfig.ra" source "drivers/clock_control/Kconfig.ambiq" +source "drivers/clock_control/Kconfig.pwm" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.pwm b/drivers/clock_control/Kconfig.pwm new file mode 100644 index 00000000000..eed5a91c17b --- /dev/null +++ b/drivers/clock_control/Kconfig.pwm @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_PWM + bool "Generic PWM clock" + default y + depends on DT_HAS_PWM_CLOCK_ENABLED + select PWM + help + Enable generic PWM clock. + +config CLOCK_CONTROL_PWM_INIT_PRIORITY + int "Initialization priority of the pwm clock device" + default 51 + depends on CLOCK_CONTROL_PWM + help + Initialization priority of the PWM clock device. Must be + lower priority than PWM. diff --git a/drivers/clock_control/clock_control_pwm.c b/drivers/clock_control/clock_control_pwm.c new file mode 100644 index 00000000000..1936e3ab6cc --- /dev/null +++ b/drivers/clock_control/clock_control_pwm.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT pwm_clock + +#include + +#include +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_CLOCK_CONTROL_LOG_LEVEL +#include +LOG_MODULE_REGISTER(clock_control_pwm); + +BUILD_ASSERT(CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY > CONFIG_PWM_INIT_PRIORITY, + "PWM must have a higher priority than PWM clock control"); + +#define NUM_PWM_CLOCKS 1 + +struct clock_control_pwm_config { + const struct pwm_dt_spec pwm_dt; + const uint16_t pwm_on_delay; +}; + +struct clock_control_pwm_data { + uint32_t clock_frequency; + bool is_enabled; +}; + +static int clock_control_pwm_on(const struct device *dev, clock_control_subsys_t sys) +{ + struct clock_control_pwm_data *data = dev->data; + const struct clock_control_pwm_config *config = dev->config; + const struct pwm_dt_spec *spec; + int id = (int)sys; + int ret; + + if (id >= NUM_PWM_CLOCKS) { + return -EINVAL; + } + + spec = &config->pwm_dt; + if (data->clock_frequency == 0) { + ret = pwm_set_dt(spec, spec->period, spec->period / 2); + } else { + uint64_t cycles_per_sec; + uint32_t period_cycles; + + ret = pwm_get_cycles_per_sec(spec->dev, spec->channel, &cycles_per_sec); + if (ret) { + return ret; + } + + if (cycles_per_sec % data->clock_frequency > 0) { + LOG_WRN("Target clock frequency cannot be expressed in PWM clock ticks"); + } + + period_cycles = cycles_per_sec / data->clock_frequency; + ret = pwm_set_cycles(spec->dev, spec->channel, period_cycles, period_cycles / 2, + spec->flags); + } + + if (ret) { + return ret; + } + + k_busy_wait(config->pwm_on_delay); + + data->is_enabled = true; + + return 0; +} + +static int clock_control_pwm_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + struct clock_control_pwm_data *data = dev->data; + const struct clock_control_pwm_config *config = dev->config; + int id = (int)sys; + + if (id >= NUM_PWM_CLOCKS) { + return -EINVAL; + } + + if (data->clock_frequency > 0) { + *rate = data->clock_frequency; + } else { + *rate = NSEC_PER_SEC / config->pwm_dt.period; + } + + return 0; +} + +static int clock_control_pwm_set_rate(const struct device *dev, clock_control_subsys_rate_t sys, + clock_control_subsys_rate_t rate) +{ + struct clock_control_pwm_data *data = dev->data; + uint32_t rate_hz = (uint32_t)rate; + int id = (int)sys; + + if (id >= NUM_PWM_CLOCKS) { + return -EINVAL; + } + + if (data->clock_frequency == rate_hz && data->is_enabled) { + return -EALREADY; + } + + data->clock_frequency = rate_hz; + + return clock_control_pwm_on(dev, sys); +} + +static int clock_control_pwm_init(const struct device *dev) +{ + const struct clock_control_pwm_config *config = dev->config; + + if (!device_is_ready(config->pwm_dt.dev)) { + return -ENODEV; + } + + return 0; +} + +static struct clock_control_driver_api clock_control_pwm_api = { + .on = clock_control_pwm_on, + .get_rate = clock_control_pwm_get_rate, + .set_rate = clock_control_pwm_set_rate, +}; + +#define PWM_CLOCK_INIT(i) \ + \ + BUILD_ASSERT(DT_INST_PROP_LEN(i, pwms) <= 1, \ + "One PWM per clock control node is supported"); \ + \ + BUILD_ASSERT(DT_INST_PROP(i, pwm_on_delay) <= UINT16_MAX, \ + "Maximum pwm-on-delay is 65535 usec"); \ + \ + static const struct clock_control_pwm_config clock_control_pwm_config_##i = { \ + .pwm_dt = PWM_DT_SPEC_INST_GET(i), \ + .pwm_on_delay = DT_INST_PROP(i, pwm_on_delay), \ + }; \ + \ + static struct clock_control_pwm_data clock_control_pwm_data_##i = { \ + .clock_frequency = DT_INST_PROP_OR(i, clock_frequency, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(i, clock_control_pwm_init, NULL, &clock_control_pwm_data_##i, \ + &clock_control_pwm_config_##i, POST_KERNEL, \ + CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY, &clock_control_pwm_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_CLOCK_INIT) diff --git a/dts/bindings/clock/pwm-clock.yaml b/dts/bindings/clock/pwm-clock.yaml new file mode 100644 index 00000000000..5e19a245809 --- /dev/null +++ b/dts/bindings/clock/pwm-clock.yaml @@ -0,0 +1,54 @@ +# Copyright (c) 2023 Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +description: | + An external clock signal driven by a PWM pin. + + The devicetree must define a clock node: + + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + #clock-cells = <1>; + pwms = <&pwm_ccu40 2 PWM_HZ(1000000) PWM_POLARITY_NORMAL>; + }; + + This will create a device node with a clock-controller + API. Internally the device node will use PWM API to start the + clock signals at 1MHz. Note that the PWM_HZ() macro converts the + frequency to time (nanoseconds units). This may result in rounding + errors if the clock frequency is not an integer number of nanoseconds. + The clock frequency can be explicitly set using the clock-frequency + property. + + The PWM node may need to be properly configured to generate + the target period (i.e. using prescaler options). See the documention + for the target PWM driver. + +compatible: "pwm-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + pwms: + type: phandle-array + required: true + + clock-frequency: + type: int + description: | + Exact output frequency, in case the PWM period is not exact + but was rounded to nanoseconds. This property is optional. + + pwm-on-delay: + type: int + default: 0 + description: + Optional blocking delay in micro seconds to make sure that the PWM + clock has started after returning from clock_control_on(). + + "#clock-cells": + const: 1 + +clock-cells: + - id diff --git a/tests/drivers/clock_control/pwm_clock/CMakeLists.txt b/tests/drivers/clock_control/pwm_clock/CMakeLists.txt new file mode 100644 index 00000000000..c6217f1aabf --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(pwm_clock) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/clock_control/pwm_clock/boards/sam_v71_xult.overlay b/tests/drivers/clock_control/pwm_clock/boards/sam_v71_xult.overlay new file mode 100644 index 00000000000..f744dc9f0e5 --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/boards/sam_v71_xult.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + #clock-cells = <1>; + clock-frequency = <1000000>; + pwms = <&pwm0 0 PWM_KHZ(1000) PWM_POLARITY_NORMAL>; + }; + + samplenode: samplenode { + status = "okay"; + compatible = "test-clock-control-pwm-clock"; + clocks = <&pwmclock 0>; + }; +}; + +&pwm0 { + prescaler = <1>; +}; diff --git a/tests/drivers/clock_control/pwm_clock/boards/xmc45_relax_kit.overlay b/tests/drivers/clock_control/pwm_clock/boards/xmc45_relax_kit.overlay new file mode 100644 index 00000000000..16218f42596 --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/boards/xmc45_relax_kit.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + #clock-cells = <1>; + clock-frequency = <1000000>; + pwms = <&pwm_ccu40 2 PWM_KHZ(1000) PWM_POLARITY_NORMAL>; + }; + + samplenode: samplenode { + status = "okay"; + compatible = "test-clock-control-pwm-clock"; + clocks = <&pwmclock 0>; + }; +}; + +&pwm_ccu40 { + status = "okay"; + slice-prescaler = <0 0 0 0>; +}; diff --git a/tests/drivers/clock_control/pwm_clock/boards/xmc47_relax_kit.overlay b/tests/drivers/clock_control/pwm_clock/boards/xmc47_relax_kit.overlay new file mode 100644 index 00000000000..880430e4c68 --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/boards/xmc47_relax_kit.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + #clock-cells = <1>; + clock-frequency = <1000000>; + pwms = <&pwm_ccu80 0 PWM_KHZ(1000) PWM_POLARITY_NORMAL>; + }; + + samplenode: samplenode { + status = "okay"; + compatible = "test-clock-control-pwm-clock"; + clocks = <&pwmclock 0>; + }; +}; + +&pwm_ccu80 { + status = "okay"; + slice-prescaler = <0 0 0 0>; +}; diff --git a/tests/drivers/clock_control/pwm_clock/dts/bindings/test-clock-control-clock-pwm.yaml b/tests/drivers/clock_control/pwm_clock/dts/bindings/test-clock-control-clock-pwm.yaml new file mode 100644 index 00000000000..078e3bc39cd --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/dts/bindings/test-clock-control-clock-pwm.yaml @@ -0,0 +1,10 @@ +description: Example binding for a node using a PWM clock + +compatible: "test-clock-control-pwm-clock" + +include: base.yaml + +properties: + clocks: + required: true + description: Clock phandle array diff --git a/tests/drivers/clock_control/pwm_clock/prj.conf b/tests/drivers/clock_control/pwm_clock/prj.conf new file mode 100644 index 00000000000..903dc40185b --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_CLOCK_CONTROL=y diff --git a/tests/drivers/clock_control/pwm_clock/src/main.c b/tests/drivers/clock_control/pwm_clock/src/main.c new file mode 100644 index 00000000000..87fa8601473 --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/src/main.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define NODELABEL DT_NODELABEL(samplenode) +static const struct device *clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(NODELABEL)); + +static void *pwm_clock_setup(void) +{ + int ret; + uint32_t clock_rate; + uint32_t clock_rate_dt = DT_PROP_BY_PHANDLE(NODELABEL, clocks, clock_frequency); + + zassert_equal(device_is_ready(clk_dev), true, "%s: PWM clock device is not ready", + clk_dev->name); + + ret = clock_control_get_rate(clk_dev, 0, &clock_rate); + zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate", + clk_dev->name, ret); + + zassert_equal(clock_rate_dt, clock_rate, + "%s: devicetree clock rate mismatch. Expected %dHz Fetched %dHz", + clk_dev->name, clock_rate_dt, clock_rate); + + ret = clock_control_on(clk_dev, 0); + zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_on", clk_dev->name, ret); + + return NULL; +} + +ZTEST(pwm_clock, test_clock_control_get_rate) +{ + int ret; + uint32_t clock_rate; + + ret = clock_control_get_rate(clk_dev, 0, &clock_rate); + zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate", + clk_dev->name, ret); +} + +ZTEST(pwm_clock, test_clock_control_set_rate) +{ + int ret; + uint32_t clock_rate, clock_rate_new; + + ret = clock_control_get_rate(clk_dev, 0, &clock_rate); + zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate", + clk_dev->name, ret); + + clock_rate /= 2; + + ret = clock_control_set_rate(clk_dev, 0, (clock_control_subsys_rate_t)clock_rate); + zassert_equal(0, ret, "%s: unexpected err (%d) from clock_control_set_rate", + clk_dev->name, ret); + + ret = clock_control_get_rate(clk_dev, 0, &clock_rate_new); + zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate", + clk_dev->name, ret); + + zassert_equal(clock_rate, clock_rate_new, + "%s: Clock rate mismatch. Expected %dHz Fetched %dHz", clk_dev->name, + clock_rate, clock_rate_new); +} + +ZTEST_SUITE(pwm_clock, NULL, pwm_clock_setup, NULL, NULL, NULL); diff --git a/tests/drivers/clock_control/pwm_clock/testcase.yaml b/tests/drivers/clock_control/pwm_clock/testcase.yaml new file mode 100644 index 00000000000..0789fcf0722 --- /dev/null +++ b/tests/drivers/clock_control/pwm_clock/testcase.yaml @@ -0,0 +1,7 @@ +tests: + drivers.clock.pwm_clock: + filter: dt_compat_enabled("pwm-clock") and dt_compat_enabled("test-clock-control-pwm-clock") + tags: + - drivers + - clock + - pwm From 524ed5dbc1610d47bf0a45e3d080fa113b6f9a60 Mon Sep 17 00:00:00 2001 From: Flavia Caforio Date: Wed, 8 Nov 2023 17:48:58 +0100 Subject: [PATCH 3818/4498] drivers: counter: nrf_timer: Add event clear to set_top_value At present, if you want to set a periodic timer again with set_top_value, the last triggered event is not cleared. This could result in an old event being served at the next interrupt activation. The solution proposed in this patch adds the nrf_timer_event_clear function into set_top_value to prevent this from happening in the above case. Signed-off-by: Flavia Caforio --- drivers/counter/counter_nrfx_timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index df5b6175257..caf2c5852e4 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -253,6 +253,7 @@ static int set_top_value(const struct device *dev, nrf_timer_int_disable(timer, COUNTER_TOP_INT_MASK); nrf_timer_cc_set(timer, TOP_CH, cfg->ticks); + nrf_timer_event_clear(timer, COUNTER_TOP_EVT); nrf_timer_shorts_enable(timer, COUNTER_OVERFLOW_SHORT); data->top_cb = cfg->callback; From c972ef1a0f82d254c9a8ff2437b73ebe368ba9c4 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 13 Nov 2023 15:12:45 -0800 Subject: [PATCH 3819/4498] kernel: mm: move kernel mm functions under kernel includes This moves the k_* memory management functions from sys/ into kernel/ includes, as there are kernel public APIs. The z_* functions are further separated into the kernel internal header directory. Also made a quick change to doxygen to group sys_mem_* into the OS Memory Management group so they will appear in doc. Signed-off-by: Daniel Leung --- MAINTAINERS.yml | 2 + arch/arm/core/mmu/arm_mmu.c | 6 +- arch/x86/core/efi.c | 2 +- arch/x86/core/ia32/crt0.S | 2 +- arch/x86/core/ia32/fatal.c | 2 +- arch/x86/core/ia32/userspace.S | 2 +- arch/x86/core/intel64/locore.S | 2 +- arch/x86/core/intel64/userspace.S | 2 +- arch/x86/core/x86_mmu.c | 2 +- arch/x86/include/x86_mmu.h | 2 +- arch/xtensa/core/mem_manage.c | 2 +- arch/xtensa/core/xtensa_mmu.c | 2 +- boards/x86/qemu_x86/qemu_x86_tiny.ld | 2 +- drivers/ethernet/eth_dwmac_mmu.c | 2 +- drivers/mm/mm_drv_intel_adsp.h | 2 +- drivers/mm/mm_drv_intel_adsp_tlb.c | 2 +- drivers/pcie/host/msi.c | 2 +- include/zephyr/arch/arm64/arm_mem.h | 2 +- include/zephyr/arch/x86/ia32/linker.ld | 2 +- include/zephyr/arch/x86/memory.ld | 2 +- include/zephyr/kernel/internal/mm.h | 214 ++++++ include/zephyr/kernel/mm.h | 528 ++++++++++++++ include/zephyr/kernel/thread.h | 2 +- include/zephyr/linker/linker-tool-gcc.h | 2 +- include/zephyr/sys/device_mmio.h | 2 +- include/zephyr/sys/mem_manage.h | 683 +----------------- kernel/CMakeLists.txt | 1 + kernel/include/mmu.h | 2 +- kernel/paging/statistics.c | 2 +- lib/libc/common/source/stdlib/malloc.c | 2 +- lib/libc/newlib/libc-hooks.c | 2 +- lib/libc/picolibc/libc-hooks.c | 2 +- tests/kernel/fatal/exception/src/main.c | 2 +- .../mem_heap/shared_multi_heap/src/main.c | 2 +- .../mem_protect/demand_paging/src/main.c | 2 +- tests/kernel/mem_protect/mem_map/src/main.c | 2 +- 36 files changed, 780 insertions(+), 714 deletions(-) create mode 100644 include/zephyr/kernel/internal/mm.h create mode 100644 include/zephyr/kernel/mm.h diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f03d141e475..02ff92cb9f8 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3136,6 +3136,8 @@ Userspace: - scripts/build/gen_relocate_app.py - include/zephyr/sys/kobject.h - include/zephyr/sys/mem_manage.h + - include/zephyr/kernel/mm.h + - include/zephyr/kernel/internal/mm.h labels: - "area: Userspace" diff --git a/arch/arm/core/mmu/arm_mmu.c b/arch/arm/core/mmu/arm_mmu.c index 5281d265cd0..77c79fdfc3d 100644 --- a/arch/arm/core/mmu/arm_mmu.c +++ b/arch/arm/core/mmu/arm_mmu.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -861,7 +861,7 @@ int z_arm_mmu_init(void) * @param phys 32-bit physical address. * @param size Size (in bytes) of the memory area to map. * @param flags Memory attributes & permissions. Comp. K_MEM_... - * flags in sys/mem_manage.h. + * flags in kernel/mm.h. * @retval 0 on success, -EINVAL if an invalid parameter is detected. */ static int __arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flags) @@ -939,7 +939,7 @@ static int __arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flag * @param phys 32-bit physical address. * @param size Size (in bytes) of the memory area to map. * @param flags Memory attributes & permissions. Comp. K_MEM_... - * flags in sys/mem_manage.h. + * flags in kernel/mm.h. */ void arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flags) { diff --git a/arch/x86/core/efi.c b/arch/x86/core/efi.c index 00bcff8d47c..425b0dcde86 100644 --- a/arch/x86/core/efi.c +++ b/arch/x86/core/efi.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include "../zefi/efi.h" /* ZEFI not on include path */ #include #include diff --git a/arch/x86/core/ia32/crt0.S b/arch/x86/core/ia32/crt0.S index d42a99d5f56..75a5402a4b2 100644 --- a/arch/x86/core/ia32/crt0.S +++ b/arch/x86/core/ia32/crt0.S @@ -21,7 +21,7 @@ #include #include #include -#include +#include /* exports (private APIs) */ diff --git a/arch/x86/core/ia32/fatal.c b/arch/x86/core/ia32/fatal.c index 9c9ab5f3a63..38cf180e0bc 100644 --- a/arch/x86/core/ia32/fatal.c +++ b/arch/x86/core/ia32/fatal.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/arch/x86/core/ia32/userspace.S b/arch/x86/core/ia32/userspace.S index adba32c78b2..bf21a0cc1a2 100644 --- a/arch/x86/core/ia32/userspace.S +++ b/arch/x86/core/ia32/userspace.S @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include /* Exports */ diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index f69545cc64a..dd541921742 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -13,7 +13,7 @@ #include #include #include -#include +#include /* * Definitions/macros for enabling paging diff --git a/arch/x86/core/intel64/userspace.S b/arch/x86/core/intel64/userspace.S index 747c6183c3c..ab09381c7af 100644 --- a/arch/x86/core/intel64/userspace.S +++ b/arch/x86/core/intel64/userspace.S @@ -8,7 +8,7 @@ #include #include #include -#include +#include #ifdef CONFIG_X86_KPTI /* Copy interrupt return stack context to the trampoline stack, switch back diff --git a/arch/x86/core/x86_mmu.c b/arch/x86/core/x86_mmu.c index 119179b72ae..71aafe5cad9 100644 --- a/arch/x86/core/x86_mmu.c +++ b/arch/x86/core/x86_mmu.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/include/x86_mmu.h b/arch/x86/include/x86_mmu.h index 14c5b053c65..b5b319a64e4 100644 --- a/arch/x86/include/x86_mmu.h +++ b/arch/x86/include/x86_mmu.h @@ -14,7 +14,7 @@ #include #include -#include +#include #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define XD_SUPPORTED diff --git a/arch/xtensa/core/mem_manage.c b/arch/xtensa/core/mem_manage.c index ee2d162c835..e43bf4b75d6 100644 --- a/arch/xtensa/core/mem_manage.c +++ b/arch/xtensa/core/mem_manage.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include __weak bool sys_mm_is_phys_addr_in_range(uintptr_t phys) { diff --git a/arch/xtensa/core/xtensa_mmu.c b/arch/xtensa/core/xtensa_mmu.c index c84d01b8337..e50c51a3848 100644 --- a/arch/xtensa/core/xtensa_mmu.c +++ b/arch/xtensa/core/xtensa_mmu.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/boards/x86/qemu_x86/qemu_x86_tiny.ld b/boards/x86/qemu_x86/qemu_x86_tiny.ld index c53e2a7b409..44e8ff85358 100644 --- a/boards/x86/qemu_x86/qemu_x86_tiny.ld +++ b/boards/x86/qemu_x86/qemu_x86_tiny.ld @@ -10,7 +10,7 @@ #include #include #include -#include +#include /* Bounds of physical RAM from DTS */ diff --git a/drivers/ethernet/eth_dwmac_mmu.c b/drivers/ethernet/eth_dwmac_mmu.c index 38e8a99c435..b78fbbc035d 100644 --- a/drivers/ethernet/eth_dwmac_mmu.c +++ b/drivers/ethernet/eth_dwmac_mmu.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DT_DRV_COMPAT snps_designware_ethernet #include -#include +#include #include #include #include diff --git a/drivers/mm/mm_drv_intel_adsp.h b/drivers/mm/mm_drv_intel_adsp.h index b62e7ceb27d..8de9ccc42ca 100644 --- a/drivers/mm/mm_drv_intel_adsp.h +++ b/drivers/mm/mm_drv_intel_adsp.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/mm/mm_drv_intel_adsp_tlb.c b/drivers/mm/mm_drv_intel_adsp_tlb.c index 26d69371a2d..315496be8e0 100644 --- a/drivers/mm/mm_drv_intel_adsp_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_tlb.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pcie/host/msi.c b/drivers/pcie/host/msi.c index fc04fdccfa1..f78f5b171a6 100644 --- a/drivers/pcie/host/msi.c +++ b/drivers/pcie/host/msi.c @@ -38,7 +38,7 @@ static uint32_t pcie_msi_base(pcie_bdf_t bdf, bool *msi) #ifdef CONFIG_PCIE_MSI_MULTI_VECTOR -#include +#include __weak uint8_t arch_pcie_msi_vectors_allocate(unsigned int priority, msi_vector_t *vectors, diff --git a/include/zephyr/arch/arm64/arm_mem.h b/include/zephyr/arch/arm64/arm_mem.h index 23569f6c345..110f85a24ca 100644 --- a/include/zephyr/arch/arm64/arm_mem.h +++ b/include/zephyr/arch/arm64/arm_mem.h @@ -8,7 +8,7 @@ /* * Define ARM specific memory flags used by z_phys_map() - * followed public definitions in include/sys/mem_manage.h. + * followed public definitions in include/kernel/mm.h. */ /* For ARM64, K_MEM_CACHE_NONE is nGnRnE. */ #define K_MEM_ARM_DEVICE_nGnRnE K_MEM_CACHE_NONE diff --git a/include/zephyr/arch/x86/ia32/linker.ld b/include/zephyr/arch/x86/ia32/linker.ld index 4d3ebe03f85..a0e2f5c6732 100644 --- a/include/zephyr/arch/x86/ia32/linker.ld +++ b/include/zephyr/arch/x86/ia32/linker.ld @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include diff --git a/include/zephyr/arch/x86/memory.ld b/include/zephyr/arch/x86/memory.ld index 8cc19fd6484..72b400dd079 100644 --- a/include/zephyr/arch/x86/memory.ld +++ b/include/zephyr/arch/x86/memory.ld @@ -29,7 +29,7 @@ #include #include -#include +#include /* Bounds of physical RAM from DTS */ #define PHYS_RAM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) diff --git a/include/zephyr/kernel/internal/mm.h b/include/zephyr/kernel/internal/mm.h new file mode 100644 index 00000000000..c859e939234 --- /dev/null +++ b/include/zephyr/kernel/internal/mm.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H +#define ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H + +#include +#include + +/** + * @defgroup kernel_mm_internal_apis Kernel Memory Management Internal APIs + * @ingroup internal_api + * @{ + */ + +/* + * This is the offset to subtract from a virtual address mapped in the + * kernel's permanent mapping of RAM, to obtain its physical address. + * + * virt_addr = phys_addr + Z_MEM_VM_OFFSET + * + * This only works for virtual addresses within the interval + * [CONFIG_KERNEL_VM_BASE, CONFIG_KERNEL_VM_BASE + (CONFIG_SRAM_SIZE * 1024)). + * + * These macros are intended for assembly, linker code, and static initializers. + * Use with care. + * + * Note that when demand paging is active, these will only work with page + * frames that are pinned to their virtual mapping at boot. + * + * TODO: This will likely need to move to an arch API or need additional + * constraints defined. + */ +#ifdef CONFIG_MMU +#define Z_MEM_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ + (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) +#else +#define Z_MEM_VM_OFFSET 0 +#endif + +#define Z_MEM_PHYS_ADDR(virt) ((virt) - Z_MEM_VM_OFFSET) +#define Z_MEM_VIRT_ADDR(phys) ((phys) + Z_MEM_VM_OFFSET) + +#if Z_MEM_VM_OFFSET != 0 +#define Z_VM_KERNEL 1 +#ifdef CONFIG_XIP +#error "XIP and a virtual memory kernel are not allowed" +#endif +#endif + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include + +/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */ +static inline uintptr_t z_mem_phys_addr(void *virt) +{ + uintptr_t addr = (uintptr_t)virt; + +#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) + __ASSERT(sys_mm_is_virt_addr_in_range(virt), + "address %p not in permanent mappings", virt); +#elif defined(CONFIG_MMU) + __ASSERT( +#if CONFIG_KERNEL_VM_BASE != 0 + (addr >= CONFIG_KERNEL_VM_BASE) && +#endif +#if (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE) != 0 + (addr < (CONFIG_KERNEL_VM_BASE + + (CONFIG_KERNEL_VM_SIZE))), +#else + false, +#endif + "address %p not in permanent mappings", virt); +#else + /* Should be identity-mapped */ + __ASSERT( +#if CONFIG_SRAM_BASE_ADDRESS != 0 + (addr >= CONFIG_SRAM_BASE_ADDRESS) && +#endif +#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 + (addr < (CONFIG_SRAM_BASE_ADDRESS + + (CONFIG_SRAM_SIZE * 1024UL))), +#else + false, +#endif + "physical address 0x%lx not in RAM", + (unsigned long)addr); +#endif /* CONFIG_MMU */ + + /* TODO add assertion that this page is pinned to boot mapping, + * the above checks won't be sufficient with demand paging + */ + + return Z_MEM_PHYS_ADDR(addr); +} + +/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */ +static inline void *z_mem_virt_addr(uintptr_t phys) +{ +#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) + __ASSERT(sys_mm_is_phys_addr_in_range(phys), + "physical address 0x%lx not in RAM", (unsigned long)phys); +#else + __ASSERT( +#if CONFIG_SRAM_BASE_ADDRESS != 0 + (phys >= CONFIG_SRAM_BASE_ADDRESS) && +#endif +#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 + (phys < (CONFIG_SRAM_BASE_ADDRESS + + (CONFIG_SRAM_SIZE * 1024UL))), +#else + false, +#endif + "physical address 0x%lx not in RAM", (unsigned long)phys); +#endif + + /* TODO add assertion that this page frame is pinned to boot mapping, + * the above check won't be sufficient with demand paging + */ + + return (void *)Z_MEM_VIRT_ADDR(phys); +} + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Map a physical memory region into the kernel's virtual address space + * + * This function is intended for mapping memory-mapped I/O regions into + * the virtual address space. Given a physical address and a size, return a + * linear address representing the base of where the physical region is mapped + * in the virtual address space for the Zephyr kernel. + * + * This function alters the active page tables in the area reserved + * for the kernel. This function will choose the virtual address + * and return it to the caller. + * + * Portable code should never assume that phys_addr and linear_addr will + * be equal. + * + * Caching and access properties are controlled by the 'flags' parameter. + * Unused bits in 'flags' are reserved for future expansion. + * A caching mode must be selected. By default, the region is read-only + * with user access and code execution forbidden. This policy is changed + * by passing K_MEM_CACHE_* and K_MEM_PERM_* macros into the 'flags' parameter. + * + * If there is insufficient virtual address space for the mapping this will + * generate a kernel panic. + * + * This API is only available if CONFIG_MMU is enabled. + * + * It is highly discouraged to use this function to map system RAM page + * frames. It may conflict with anonymous memory mappings and demand paging + * and produce undefined behavior. Do not use this for RAM unless you know + * exactly what you are doing. If you need a chunk of memory, use k_mem_map(). + * If you need a contiguous buffer of physical memory, statically declare it + * and pin it at build time, it will be mapped when the system boots. + * + * This API is part of infrastructure still under development and may + * change. + * + * @param virt [out] Output virtual address storage location + * @param phys Physical address base of the memory region + * @param size Size of the memory region + * @param flags Caching mode and access flags, see K_MAP_* macros + */ +void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, + uint32_t flags); + +/** + * Unmap a virtual memory region from kernel's virtual address space. + * + * This function is intended to be used by drivers and early boot routines + * where temporary memory mappings need to be made. This allows these + * memory mappings to be discarded once they are no longer needed. + * + * This function alters the active page tables in the area reserved + * for the kernel. + * + * This will align the input parameters to page boundaries so that + * this can be used with the virtual address as returned by + * z_phys_map(). + * + * This API is only available if CONFIG_MMU is enabled. + * + * It is highly discouraged to use this function to unmap memory mappings. + * It may conflict with anonymous memory mappings and demand paging and + * produce undefined behavior. Do not use this unless you know exactly + * what you are doing. + * + * This API is part of infrastructure still under development and may + * change. + * + * @param virt Starting address of the virtual address region to be unmapped. + * @param size Size of the virtual address region + */ +void z_phys_unmap(uint8_t *virt, size_t size); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* !_ASMLANGUAGE */ +#endif /* ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H */ diff --git a/include/zephyr/kernel/mm.h b/include/zephyr/kernel/mm.h new file mode 100644 index 00000000000..b277449ea3e --- /dev/null +++ b/include/zephyr/kernel/mm.h @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_KERNEL_MM_H +#define ZEPHYR_INCLUDE_KERNEL_MM_H + +#include +#include +#if defined(CONFIG_ARM_MMU) && defined(CONFIG_ARM64) +#include +#endif + +#include + +/** + * @brief Kernel Memory Management + * @defgroup kernel_memory_management Kernel Memory Management + * @ingroup kernel_apis + * @{ + * @} + */ + +/* + * Caching mode definitions. These are mutually exclusive. + */ + +/** No caching. Most drivers want this. */ +#define K_MEM_CACHE_NONE 2 + +/** Write-through caching. Used by certain drivers. */ +#define K_MEM_CACHE_WT 1 + +/** Full write-back caching. Any RAM mapped wants this. */ +#define K_MEM_CACHE_WB 0 + +/* + * ARM64 Specific flags are defined in arch/arm64/arm_mem.h, + * pay attention to be not conflicted when updating these flags. + */ + +/** Reserved bits for cache modes in k_map() flags argument */ +#define K_MEM_CACHE_MASK (BIT(3) - 1) + +/* + * Region permission attributes. Default is read-only, no user, no exec + */ + +/** Region will have read/write access (and not read-only) */ +#define K_MEM_PERM_RW BIT(3) + +/** Region will be executable (normally forbidden) */ +#define K_MEM_PERM_EXEC BIT(4) + +/** Region will be accessible to user mode (normally supervisor-only) */ +#define K_MEM_PERM_USER BIT(5) + +/* + * Region mapping behaviour attributes + */ + +/** Region will be mapped to 1:1 virtual and physical address */ +#define K_MEM_DIRECT_MAP BIT(6) + +#ifndef _ASMLANGUAGE +#include +#include +#include + +struct k_mem_paging_stats_t { +#ifdef CONFIG_DEMAND_PAGING_STATS + struct { + /** Number of page faults */ + unsigned long cnt; + + /** Number of page faults with IRQ locked */ + unsigned long irq_locked; + + /** Number of page faults with IRQ unlocked */ + unsigned long irq_unlocked; + +#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ + /** Number of page faults while in ISR */ + unsigned long in_isr; +#endif + } pagefaults; + + struct { + /** Number of clean pages selected for eviction */ + unsigned long clean; + + /** Number of dirty pages selected for eviction */ + unsigned long dirty; + } eviction; +#endif /* CONFIG_DEMAND_PAGING_STATS */ +}; + +struct k_mem_paging_histogram_t { +#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM + /* Counts for each bin in timing histogram */ + unsigned long counts[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; + + /* Bounds for the bins in timing histogram, + * excluding the first and last (hence, NUM_SLOTS - 1). + */ + unsigned long bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; +#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * k_mem_map() control flags + */ + +/** + * @brief The mapped region is not guaranteed to be zeroed. + * + * This may improve performance. The associated page frames may contain + * indeterminate data, zeroes, or even sensitive information. + * + * This may not be used with K_MEM_PERM_USER as there are no circumstances + * where this is safe. + */ +#define K_MEM_MAP_UNINIT BIT(16) + +/** + * Region will be pinned in memory and never paged + * + * Such memory is guaranteed to never produce a page fault due to page-outs + * or copy-on-write once the mapping call has returned. Physical page frames + * will be pre-fetched as necessary and pinned. + */ +#define K_MEM_MAP_LOCK BIT(17) + +/** + * Return the amount of free memory available + * + * The returned value will reflect how many free RAM page frames are available. + * If demand paging is enabled, it may still be possible to allocate more. + * + * The information reported by this function may go stale immediately if + * concurrent memory mappings or page-ins take place. + * + * @return Free physical RAM, in bytes + */ +size_t k_mem_free_get(void); + +/** + * Map anonymous memory into Zephyr's address space + * + * This function effectively increases the data space available to Zephyr. + * The kernel will choose a base virtual address and return it to the caller. + * The memory will have access permissions for all contexts set per the + * provided flags argument. + * + * If user thread access control needs to be managed in any way, do not enable + * K_MEM_PERM_USER flags here; instead manage the region's permissions + * with memory domain APIs after the mapping has been established. Setting + * K_MEM_PERM_USER here will allow all user threads to access this memory + * which is usually undesirable. + * + * Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed. + * + * The mapped region is not guaranteed to be physically contiguous in memory. + * Physically contiguous buffers should be allocated statically and pinned + * at build time. + * + * Pages mapped in this way have write-back cache settings. + * + * The returned virtual memory pointer will be page-aligned. The size + * parameter, and any base address for re-mapping purposes must be page- + * aligned. + * + * Note that the allocation includes two guard pages immediately before + * and after the requested region. The total size of the allocation will be + * the requested size plus the size of these two guard pages. + * + * Many K_MEM_MAP_* flags have been implemented to alter the behavior of this + * function, with details in the documentation for these flags. + * + * @param size Size of the memory mapping. This must be page-aligned. + * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags. + * @return The mapped memory location, or NULL if insufficient virtual address + * space, insufficient physical memory to establish the mapping, + * or insufficient memory for paging structures. + */ +void *k_mem_map(size_t size, uint32_t flags); + +/** + * Un-map mapped memory + * + * This removes a memory mapping for the provided page-aligned region. + * Associated page frames will be free and the kernel may re-use the associated + * virtual address region. Any paged out data pages may be discarded. + * + * Calling this function on a region which was not mapped to begin with is + * undefined behavior. + * + * @param addr Page-aligned memory region base virtual address + * @param size Page-aligned memory region size + */ +void k_mem_unmap(void *addr, size_t size); + +/** + * Given an arbitrary region, provide a aligned region that covers it + * + * The returned region will have both its base address and size aligned + * to the provided alignment value. + * + * @param aligned_addr [out] Aligned address + * @param aligned_size [out] Aligned region size + * @param addr Region base address + * @param size Region size + * @param align What to align the address and size to + * @retval offset between aligned_addr and addr + */ +size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size, + uintptr_t addr, size_t size, size_t align); + +/** + * @defgroup demand_paging Demand Paging + * @ingroup kernel_memory_management + */ +/** + * @defgroup mem-demand-paging Demand Paging APIs + * @ingroup demand_paging + * @{ + */ + +/** + * Evict a page-aligned virtual memory region to the backing store + * + * Useful if it is known that a memory region will not be used for some time. + * All the data pages within the specified region will be evicted to the + * backing store if they weren't already, with their associated page frames + * marked as available for mappings or page-ins. + * + * None of the associated page frames mapped to the provided region should + * be pinned. + * + * Note that there are no guarantees how long these pages will be evicted, + * they could take page faults immediately. + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + * @retval 0 Success + * @retval -ENOMEM Insufficient space in backing store to satisfy request. + * The region may be partially paged out. + */ +int k_mem_page_out(void *addr, size_t size); + +/** + * Load a virtual data region into memory + * + * After the function completes, all the page frames associated with this + * function will be paged in. However, they are not guaranteed to stay there. + * This is useful if the region is known to be used soon. + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_page_in(void *addr, size_t size); + +/** + * Pin an aligned virtual data region, paging in as necessary + * + * After the function completes, all the page frames associated with this + * region will be resident in memory and pinned such that they stay that way. + * This is a stronger version of z_mem_page_in(). + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_pin(void *addr, size_t size); + +/** + * Un-pin an aligned virtual data region + * + * After the function completes, all the page frames associated with this + * region will be no longer marked as pinned. This does not evict the region, + * follow this with z_mem_page_out() if you need that. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_unpin(void *addr, size_t size); + +/** + * Get the paging statistics since system startup + * + * This populates the paging statistics struct being passed in + * as argument. + * + * @param[in,out] stats Paging statistics struct to be filled. + */ +__syscall void k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats); + +struct k_thread; +/** + * Get the paging statistics since system startup for a thread + * + * This populates the paging statistics struct being passed in + * as argument for a particular thread. + * + * @param[in] thread Thread + * @param[in,out] stats Paging statistics struct to be filled. + */ +__syscall +void k_mem_paging_thread_stats_get(struct k_thread *thread, + struct k_mem_paging_stats_t *stats); + +/** + * Get the eviction timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_eviction_get( + struct k_mem_paging_histogram_t *hist); + +/** + * Get the backing store page-in timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_backing_store_page_in_get( + struct k_mem_paging_histogram_t *hist); + +/** + * Get the backing store page-out timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_backing_store_page_out_get( + struct k_mem_paging_histogram_t *hist); + +#include + +/** @} */ + +/** + * Eviction algorithm APIs + * + * @defgroup mem-demand-paging-eviction Eviction Algorithm APIs + * @ingroup demand_paging + * @{ + */ + +/** + * Select a page frame for eviction + * + * The kernel will invoke this to choose a page frame to evict if there + * are no free page frames. + * + * This function will never be called before the initial + * k_mem_paging_eviction_init(). + * + * This function is invoked with interrupts locked. + * + * @param [out] dirty Whether the page to evict is dirty + * @return The page frame to evict + */ +struct z_page_frame *k_mem_paging_eviction_select(bool *dirty); + +/** + * Initialization function + * + * Called at POST_KERNEL to perform any necessary initialization tasks for the + * eviction algorithm. k_mem_paging_eviction_select() is guaranteed to never be + * called until this has returned, and this will only be called once. + */ +void k_mem_paging_eviction_init(void); + +/** @} */ + +/** + * Backing store APIs + * + * @defgroup mem-demand-paging-backing-store Backing Store APIs + * @ingroup demand_paging + * @{ + */ + +/** + * Reserve or fetch a storage location for a data page loaded into a page frame + * + * The returned location token must be unique to the mapped virtual address. + * This location will be used in the backing store to page out data page + * contents for later retrieval. The location value must be page-aligned. + * + * This function may be called multiple times on the same data page. If its + * page frame has its Z_PAGE_FRAME_BACKED bit set, it is expected to return + * the previous backing store location for the data page containing a cached + * clean copy. This clean copy may be updated on page-out, or used to + * discard clean pages without needing to write out their contents. + * + * If the backing store is full, some other backing store location which caches + * a loaded data page may be selected, in which case its associated page frame + * will have the Z_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). + * + * pf->addr will indicate the virtual address the page is currently mapped to. + * Large, sparse backing stores which can contain the entire address space + * may simply generate location tokens purely as a function of pf->addr with no + * other management necessary. + * + * This function distinguishes whether it was called on behalf of a page + * fault. A free backing store location must always be reserved in order for + * page faults to succeed. If the page_fault parameter is not set, this + * function should return -ENOMEM even if one location is available. + * + * This function is invoked with interrupts locked. + * + * @param pf Virtual address to obtain a storage location + * @param [out] location storage location token + * @param page_fault Whether this request was for a page fault + * @return 0 Success + * @return -ENOMEM Backing store is full + */ +int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, + uintptr_t *location, + bool page_fault); + +/** + * Free a backing store location + * + * Any stored data may be discarded, and the location token associated with + * this address may be re-used for some other data page. + * + * This function is invoked with interrupts locked. + * + * @param location Location token to free + */ +void k_mem_paging_backing_store_location_free(uintptr_t location); + +/** + * Copy a data page from Z_SCRATCH_PAGE to the specified location + * + * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * to the intended source page frame for the calling context. + * + * Calls to this and k_mem_paging_backing_store_page_in() will always be + * serialized, but interrupts may be enabled. + * + * @param location Location token for the data page, for later retrieval + */ +void k_mem_paging_backing_store_page_out(uintptr_t location); + +/** + * Copy a data page from the provided location to Z_SCRATCH_PAGE. + * + * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * to the intended destination page frame for the calling context. + * + * Calls to this and k_mem_paging_backing_store_page_out() will always be + * serialized, but interrupts may be enabled. + * + * @param location Location token for the data page + */ +void k_mem_paging_backing_store_page_in(uintptr_t location); + +/** + * Update internal accounting after a page-in + * + * This is invoked after k_mem_paging_backing_store_page_in() and interrupts + * have been* re-locked, making it safe to access the z_page_frame data. + * The location value will be the same passed to + * k_mem_paging_backing_store_page_in(). + * + * The primary use-case for this is to update custom fields for the backing + * store in the page frame, to reflect where the data should be evicted to + * if it is paged out again. This may be a no-op in some implementations. + * + * If the backing store caches paged-in data pages, this is the appropriate + * time to set the Z_PAGE_FRAME_BACKED bit. The kernel only skips paging + * out clean data pages if they are noted as clean in the page tables and the + * Z_PAGE_FRAME_BACKED bit is set in their associated page frame. + * + * @param pf Page frame that was loaded in + * @param location Location of where the loaded data page was retrieved + */ +void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, + uintptr_t location); + +/** + * Backing store initialization function. + * + * The implementation may expect to receive page in/out calls as soon as this + * returns, but not before that. Called at POST_KERNEL. + * + * This function is expected to do two things: + * - Initialize any internal data structures and accounting for the backing + * store. + * - If the backing store already contains all or some loaded kernel data pages + * at boot time, Z_PAGE_FRAME_BACKED should be appropriately set for their + * associated page frames, and any internal accounting set up appropriately. + */ +void k_mem_paging_backing_store_init(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_ASMLANGUAGE */ +#endif /* ZEPHYR_INCLUDE_KERNEL_MM_H */ diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 20d88bba250..b152dfb909a 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -8,7 +8,7 @@ #define ZEPHYR_INCLUDE_KERNEL_THREAD_H_ #ifdef CONFIG_DEMAND_PAGING_THREAD_STATS -#include +#include #endif #include diff --git a/include/zephyr/linker/linker-tool-gcc.h b/include/zephyr/linker/linker-tool-gcc.h index e5364b5a3d9..ab8a3ad7f9a 100644 --- a/include/zephyr/linker/linker-tool-gcc.h +++ b/include/zephyr/linker/linker-tool-gcc.h @@ -15,7 +15,7 @@ #ifndef ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_GCC_H_ #define ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_GCC_H_ -#include +#include #if defined(CONFIG_ARM) #if defined(CONFIG_BIG_ENDIAN) diff --git a/include/zephyr/sys/device_mmio.h b/include/zephyr/sys/device_mmio.h index 4aee3c30131..c50a12782ee 100644 --- a/include/zephyr/sys/device_mmio.h +++ b/include/zephyr/sys/device_mmio.h @@ -45,7 +45,7 @@ #ifndef _ASMLANGUAGE #include #include -#include +#include #include #ifdef DEVICE_MMIO_IS_IN_RAM diff --git a/include/zephyr/sys/mem_manage.h b/include/zephyr/sys/mem_manage.h index 2e150110f7d..850a1376eaf 100644 --- a/include/zephyr/sys/mem_manage.h +++ b/include/zephyr/sys/mem_manage.h @@ -7,141 +7,18 @@ #ifndef ZEPHYR_INCLUDE_SYS_MEM_MANAGE_H #define ZEPHYR_INCLUDE_SYS_MEM_MANAGE_H -#include -#include -#if defined(CONFIG_ARM_MMU) && defined(CONFIG_ARM64) -#include -#endif +#include /** * @brief Memory Management * @defgroup memory_management Memory Management * @ingroup os_services * @{ - * @} */ -/* - * Caching mode definitions. These are mutually exclusive. - */ - -/** No caching. Most drivers want this. */ -#define K_MEM_CACHE_NONE 2 - -/** Write-through caching. Used by certain drivers. */ -#define K_MEM_CACHE_WT 1 - -/** Full write-back caching. Any RAM mapped wants this. */ -#define K_MEM_CACHE_WB 0 - -/* - * ARM64 Specific flags are defined in arch/arm64/arm_mem.h, - * pay attention to be not conflicted when updating these flags. - */ - -/** Reserved bits for cache modes in k_map() flags argument */ -#define K_MEM_CACHE_MASK (BIT(3) - 1) - -/* - * Region permission attributes. Default is read-only, no user, no exec - */ - -/** Region will have read/write access (and not read-only) */ -#define K_MEM_PERM_RW BIT(3) - -/** Region will be executable (normally forbidden) */ -#define K_MEM_PERM_EXEC BIT(4) - -/** Region will be accessible to user mode (normally supervisor-only) */ -#define K_MEM_PERM_USER BIT(5) - -/* - * Region mapping behaviour attributes - */ - -/** Region will be mapped to 1:1 virtual and physical address */ -#define K_MEM_DIRECT_MAP BIT(6) - -/* - * This is the offset to subtract from a virtual address mapped in the - * kernel's permanent mapping of RAM, to obtain its physical address. - * - * virt_addr = phys_addr + Z_MEM_VM_OFFSET - * - * This only works for virtual addresses within the interval - * [CONFIG_KERNEL_VM_BASE, CONFIG_KERNEL_VM_BASE + (CONFIG_SRAM_SIZE * 1024)). - * - * These macros are intended for assembly, linker code, and static initializers. - * Use with care. - * - * Note that when demand paging is active, these will only work with page - * frames that are pinned to their virtual mapping at boot. - * - * TODO: This will likely need to move to an arch API or need additional - * constraints defined. - */ -#ifdef CONFIG_MMU -#define Z_MEM_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ - (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) -#else -#define Z_MEM_VM_OFFSET 0 -#endif - -#define Z_MEM_PHYS_ADDR(virt) ((virt) - Z_MEM_VM_OFFSET) -#define Z_MEM_VIRT_ADDR(phys) ((phys) + Z_MEM_VM_OFFSET) - -#if Z_MEM_VM_OFFSET != 0 -#define Z_VM_KERNEL 1 -#ifdef CONFIG_XIP -#error "XIP and a virtual memory kernel are not allowed" -#endif -#endif - #ifndef _ASMLANGUAGE +#include #include -#include -#include -#include - -struct k_mem_paging_stats_t { -#ifdef CONFIG_DEMAND_PAGING_STATS - struct { - /** Number of page faults */ - unsigned long cnt; - - /** Number of page faults with IRQ locked */ - unsigned long irq_locked; - - /** Number of page faults with IRQ unlocked */ - unsigned long irq_unlocked; - -#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ - /** Number of page faults while in ISR */ - unsigned long in_isr; -#endif - } pagefaults; - - struct { - /** Number of clean pages selected for eviction */ - unsigned long clean; - - /** Number of dirty pages selected for eviction */ - unsigned long dirty; - } eviction; -#endif /* CONFIG_DEMAND_PAGING_STATS */ -}; - -struct k_mem_paging_histogram_t { -#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM - /* Counts for each bin in timing histogram */ - unsigned long counts[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; - - /* Bounds for the bins in timing histogram, - * excluding the first and last (hence, NUM_SLOTS - 1). - */ - unsigned long bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; -#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ -}; /** * @brief Check if a physical address is within range of physical memory. @@ -181,563 +58,7 @@ bool sys_mm_is_phys_addr_in_range(uintptr_t phys); */ bool sys_mm_is_virt_addr_in_range(void *virt); -/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */ -static inline uintptr_t z_mem_phys_addr(void *virt) -{ - uintptr_t addr = (uintptr_t)virt; - -#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) - __ASSERT(sys_mm_is_virt_addr_in_range(virt), - "address %p not in permanent mappings", virt); -#elif defined(CONFIG_MMU) - __ASSERT( -#if CONFIG_KERNEL_VM_BASE != 0 - (addr >= CONFIG_KERNEL_VM_BASE) && -#endif -#if (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE) != 0 - (addr < (CONFIG_KERNEL_VM_BASE + - (CONFIG_KERNEL_VM_SIZE))), -#else - false, -#endif - "address %p not in permanent mappings", virt); -#else - /* Should be identity-mapped */ - __ASSERT( -#if CONFIG_SRAM_BASE_ADDRESS != 0 - (addr >= CONFIG_SRAM_BASE_ADDRESS) && -#endif -#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 - (addr < (CONFIG_SRAM_BASE_ADDRESS + - (CONFIG_SRAM_SIZE * 1024UL))), -#else - false, -#endif - "physical address 0x%lx not in RAM", - (unsigned long)addr); -#endif /* CONFIG_MMU */ - - /* TODO add assertion that this page is pinned to boot mapping, - * the above checks won't be sufficient with demand paging - */ - - return Z_MEM_PHYS_ADDR(addr); -} - -/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */ -static inline void *z_mem_virt_addr(uintptr_t phys) -{ -#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) - __ASSERT(sys_mm_is_phys_addr_in_range(phys), - "physical address 0x%lx not in RAM", (unsigned long)phys); -#else - __ASSERT( -#if CONFIG_SRAM_BASE_ADDRESS != 0 - (phys >= CONFIG_SRAM_BASE_ADDRESS) && -#endif -#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 - (phys < (CONFIG_SRAM_BASE_ADDRESS + - (CONFIG_SRAM_SIZE * 1024UL))), -#else - false, -#endif - "physical address 0x%lx not in RAM", (unsigned long)phys); -#endif - - /* TODO add assertion that this page frame is pinned to boot mapping, - * the above check won't be sufficient with demand paging - */ - - return (void *)Z_MEM_VIRT_ADDR(phys); -} - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Map a physical memory region into the kernel's virtual address space - * - * This function is intended for mapping memory-mapped I/O regions into - * the virtual address space. Given a physical address and a size, return a - * linear address representing the base of where the physical region is mapped - * in the virtual address space for the Zephyr kernel. - * - * This function alters the active page tables in the area reserved - * for the kernel. This function will choose the virtual address - * and return it to the caller. - * - * Portable code should never assume that phys_addr and linear_addr will - * be equal. - * - * Caching and access properties are controlled by the 'flags' parameter. - * Unused bits in 'flags' are reserved for future expansion. - * A caching mode must be selected. By default, the region is read-only - * with user access and code execution forbidden. This policy is changed - * by passing K_MEM_CACHE_* and K_MEM_PERM_* macros into the 'flags' parameter. - * - * If there is insufficient virtual address space for the mapping this will - * generate a kernel panic. - * - * This API is only available if CONFIG_MMU is enabled. - * - * It is highly discouraged to use this function to map system RAM page - * frames. It may conflict with anonymous memory mappings and demand paging - * and produce undefined behavior. Do not use this for RAM unless you know - * exactly what you are doing. If you need a chunk of memory, use k_mem_map(). - * If you need a contiguous buffer of physical memory, statically declare it - * and pin it at build time, it will be mapped when the system boots. - * - * This API is part of infrastructure still under development and may - * change. - * - * @param virt [out] Output virtual address storage location - * @param phys Physical address base of the memory region - * @param size Size of the memory region - * @param flags Caching mode and access flags, see K_MAP_* macros - */ -void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, - uint32_t flags); - -/** - * Unmap a virtual memory region from kernel's virtual address space. - * - * This function is intended to be used by drivers and early boot routines - * where temporary memory mappings need to be made. This allows these - * memory mappings to be discarded once they are no longer needed. - * - * This function alters the active page tables in the area reserved - * for the kernel. - * - * This will align the input parameters to page boundaries so that - * this can be used with the virtual address as returned by - * z_phys_map(). - * - * This API is only available if CONFIG_MMU is enabled. - * - * It is highly discouraged to use this function to unmap memory mappings. - * It may conflict with anonymous memory mappings and demand paging and - * produce undefined behavior. Do not use this unless you know exactly - * what you are doing. - * - * This API is part of infrastructure still under development and may - * change. - * - * @param virt Starting address of the virtual address region to be unmapped. - * @param size Size of the virtual address region - */ -void z_phys_unmap(uint8_t *virt, size_t size); - -/* - * k_mem_map() control flags - */ - -/** - * @brief The mapped region is not guaranteed to be zeroed. - * - * This may improve performance. The associated page frames may contain - * indeterminate data, zeroes, or even sensitive information. - * - * This may not be used with K_MEM_PERM_USER as there are no circumstances - * where this is safe. - */ -#define K_MEM_MAP_UNINIT BIT(16) - -/** - * Region will be pinned in memory and never paged - * - * Such memory is guaranteed to never produce a page fault due to page-outs - * or copy-on-write once the mapping call has returned. Physical page frames - * will be pre-fetched as necessary and pinned. - */ -#define K_MEM_MAP_LOCK BIT(17) - -/** - * Return the amount of free memory available - * - * The returned value will reflect how many free RAM page frames are available. - * If demand paging is enabled, it may still be possible to allocate more. - * - * The information reported by this function may go stale immediately if - * concurrent memory mappings or page-ins take place. - * - * @return Free physical RAM, in bytes - */ -size_t k_mem_free_get(void); - -/** - * Map anonymous memory into Zephyr's address space - * - * This function effectively increases the data space available to Zephyr. - * The kernel will choose a base virtual address and return it to the caller. - * The memory will have access permissions for all contexts set per the - * provided flags argument. - * - * If user thread access control needs to be managed in any way, do not enable - * K_MEM_PERM_USER flags here; instead manage the region's permissions - * with memory domain APIs after the mapping has been established. Setting - * K_MEM_PERM_USER here will allow all user threads to access this memory - * which is usually undesirable. - * - * Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed. - * - * The mapped region is not guaranteed to be physically contiguous in memory. - * Physically contiguous buffers should be allocated statically and pinned - * at build time. - * - * Pages mapped in this way have write-back cache settings. - * - * The returned virtual memory pointer will be page-aligned. The size - * parameter, and any base address for re-mapping purposes must be page- - * aligned. - * - * Note that the allocation includes two guard pages immediately before - * and after the requested region. The total size of the allocation will be - * the requested size plus the size of these two guard pages. - * - * Many K_MEM_MAP_* flags have been implemented to alter the behavior of this - * function, with details in the documentation for these flags. - * - * @param size Size of the memory mapping. This must be page-aligned. - * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags. - * @return The mapped memory location, or NULL if insufficient virtual address - * space, insufficient physical memory to establish the mapping, - * or insufficient memory for paging structures. - */ -void *k_mem_map(size_t size, uint32_t flags); - -/** - * Un-map mapped memory - * - * This removes a memory mapping for the provided page-aligned region. - * Associated page frames will be free and the kernel may re-use the associated - * virtual address region. Any paged out data pages may be discarded. - * - * Calling this function on a region which was not mapped to begin with is - * undefined behavior. - * - * @param addr Page-aligned memory region base virtual address - * @param size Page-aligned memory region size - */ -void k_mem_unmap(void *addr, size_t size); - -/** - * Given an arbitrary region, provide a aligned region that covers it - * - * The returned region will have both its base address and size aligned - * to the provided alignment value. - * - * @param aligned_addr [out] Aligned address - * @param aligned_size [out] Aligned region size - * @param addr Region base address - * @param size Region size - * @param align What to align the address and size to - * @retval offset between aligned_addr and addr - */ -size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size, - uintptr_t addr, size_t size, size_t align); - -/** - * @defgroup demand_paging Demand Paging - * @ingroup memory_management - */ -/** - * @defgroup mem-demand-paging Demand Paging APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Evict a page-aligned virtual memory region to the backing store - * - * Useful if it is known that a memory region will not be used for some time. - * All the data pages within the specified region will be evicted to the - * backing store if they weren't already, with their associated page frames - * marked as available for mappings or page-ins. - * - * None of the associated page frames mapped to the provided region should - * be pinned. - * - * Note that there are no guarantees how long these pages will be evicted, - * they could take page faults immediately. - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - * @retval 0 Success - * @retval -ENOMEM Insufficient space in backing store to satisfy request. - * The region may be partially paged out. - */ -int k_mem_page_out(void *addr, size_t size); - -/** - * Load a virtual data region into memory - * - * After the function completes, all the page frames associated with this - * function will be paged in. However, they are not guaranteed to stay there. - * This is useful if the region is known to be used soon. - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_page_in(void *addr, size_t size); - -/** - * Pin an aligned virtual data region, paging in as necessary - * - * After the function completes, all the page frames associated with this - * region will be resident in memory and pinned such that they stay that way. - * This is a stronger version of z_mem_page_in(). - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_pin(void *addr, size_t size); - -/** - * Un-pin an aligned virtual data region - * - * After the function completes, all the page frames associated with this - * region will be no longer marked as pinned. This does not evict the region, - * follow this with z_mem_page_out() if you need that. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_unpin(void *addr, size_t size); - -/** - * Get the paging statistics since system startup - * - * This populates the paging statistics struct being passed in - * as argument. - * - * @param[in,out] stats Paging statistics struct to be filled. - */ -__syscall void k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats); - -struct k_thread; -/** - * Get the paging statistics since system startup for a thread - * - * This populates the paging statistics struct being passed in - * as argument for a particular thread. - * - * @param[in] thread Thread - * @param[in,out] stats Paging statistics struct to be filled. - */ -__syscall -void k_mem_paging_thread_stats_get(struct k_thread *thread, - struct k_mem_paging_stats_t *stats); - -/** - * Get the eviction timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_eviction_get( - struct k_mem_paging_histogram_t *hist); - -/** - * Get the backing store page-in timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_backing_store_page_in_get( - struct k_mem_paging_histogram_t *hist); - -/** - * Get the backing store page-out timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_backing_store_page_out_get( - struct k_mem_paging_histogram_t *hist); - -#include - -/** @} */ - -/** - * Eviction algorithm APIs - * - * @defgroup mem-demand-paging-eviction Eviction Algorithm APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Select a page frame for eviction - * - * The kernel will invoke this to choose a page frame to evict if there - * are no free page frames. - * - * This function will never be called before the initial - * k_mem_paging_eviction_init(). - * - * This function is invoked with interrupts locked. - * - * @param [out] dirty Whether the page to evict is dirty - * @return The page frame to evict - */ -struct z_page_frame *k_mem_paging_eviction_select(bool *dirty); - -/** - * Initialization function - * - * Called at POST_KERNEL to perform any necessary initialization tasks for the - * eviction algorithm. k_mem_paging_eviction_select() is guaranteed to never be - * called until this has returned, and this will only be called once. - */ -void k_mem_paging_eviction_init(void); - -/** @} */ - -/** - * Backing store APIs - * - * @defgroup mem-demand-paging-backing-store Backing Store APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Reserve or fetch a storage location for a data page loaded into a page frame - * - * The returned location token must be unique to the mapped virtual address. - * This location will be used in the backing store to page out data page - * contents for later retrieval. The location value must be page-aligned. - * - * This function may be called multiple times on the same data page. If its - * page frame has its Z_PAGE_FRAME_BACKED bit set, it is expected to return - * the previous backing store location for the data page containing a cached - * clean copy. This clean copy may be updated on page-out, or used to - * discard clean pages without needing to write out their contents. - * - * If the backing store is full, some other backing store location which caches - * a loaded data page may be selected, in which case its associated page frame - * will have the Z_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). - * - * pf->addr will indicate the virtual address the page is currently mapped to. - * Large, sparse backing stores which can contain the entire address space - * may simply generate location tokens purely as a function of pf->addr with no - * other management necessary. - * - * This function distinguishes whether it was called on behalf of a page - * fault. A free backing store location must always be reserved in order for - * page faults to succeed. If the page_fault parameter is not set, this - * function should return -ENOMEM even if one location is available. - * - * This function is invoked with interrupts locked. - * - * @param pf Virtual address to obtain a storage location - * @param [out] location storage location token - * @param page_fault Whether this request was for a page fault - * @return 0 Success - * @return -ENOMEM Backing store is full - */ -int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, - uintptr_t *location, - bool page_fault); - -/** - * Free a backing store location - * - * Any stored data may be discarded, and the location token associated with - * this address may be re-used for some other data page. - * - * This function is invoked with interrupts locked. - * - * @param location Location token to free - */ -void k_mem_paging_backing_store_location_free(uintptr_t location); - -/** - * Copy a data page from Z_SCRATCH_PAGE to the specified location - * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write - * to the intended source page frame for the calling context. - * - * Calls to this and k_mem_paging_backing_store_page_in() will always be - * serialized, but interrupts may be enabled. - * - * @param location Location token for the data page, for later retrieval - */ -void k_mem_paging_backing_store_page_out(uintptr_t location); - -/** - * Copy a data page from the provided location to Z_SCRATCH_PAGE. - * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write - * to the intended destination page frame for the calling context. - * - * Calls to this and k_mem_paging_backing_store_page_out() will always be - * serialized, but interrupts may be enabled. - * - * @param location Location token for the data page - */ -void k_mem_paging_backing_store_page_in(uintptr_t location); - -/** - * Update internal accounting after a page-in - * - * This is invoked after k_mem_paging_backing_store_page_in() and interrupts - * have been* re-locked, making it safe to access the z_page_frame data. - * The location value will be the same passed to - * k_mem_paging_backing_store_page_in(). - * - * The primary use-case for this is to update custom fields for the backing - * store in the page frame, to reflect where the data should be evicted to - * if it is paged out again. This may be a no-op in some implementations. - * - * If the backing store caches paged-in data pages, this is the appropriate - * time to set the Z_PAGE_FRAME_BACKED bit. The kernel only skips paging - * out clean data pages if they are noted as clean in the page tables and the - * Z_PAGE_FRAME_BACKED bit is set in their associated page frame. - * - * @param pf Page frame that was loaded in - * @param location Location of where the loaded data page was retrieved - */ -void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, - uintptr_t location); - -/** - * Backing store initialization function. - * - * The implementation may expect to receive page in/out calls as soon as this - * returns, but not before that. Called at POST_KERNEL. - * - * This function is expected to do two things: - * - Initialize any internal data structures and accounting for the backing - * store. - * - If the backing store already contains all or some loaded kernel data pages - * at boot time, Z_PAGE_FRAME_BACKED should be appropriately set for their - * associated page frames, and any internal accounting set up appropriately. - */ -void k_mem_paging_backing_store_init(void); - /** @} */ -#ifdef __cplusplus -} -#endif - #endif /* !_ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_SYS_MEM_MANAGE_H */ diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index e628cfec669..367b83ab04a 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_syscall_header_ifdef( zephyr_syscall_header_ifdef( CONFIG_MMU + ${ZEPHYR_BASE}/include/zephyr/kernel/mm.h ${ZEPHYR_BASE}/include/zephyr/sys/mem_manage.h ) diff --git a/kernel/include/mmu.h b/kernel/include/mmu.h index f51c0adeda0..cd290100e40 100644 --- a/kernel/include/mmu.h +++ b/kernel/include/mmu.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include /* diff --git a/kernel/paging/statistics.c b/kernel/paging/statistics.c index b2f343c9fcb..e8972738135 100644 --- a/kernel/paging/statistics.c +++ b/kernel/paging/statistics.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include extern struct k_mem_paging_stats_t paging_stats; diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 6762c38e927..e3a5db6f7d5 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -18,7 +18,7 @@ #include #include #ifdef CONFIG_MMU -#include +#include #endif #define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index 88a83742a50..7e066a2817f 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #define LIBC_BSS K_APP_BMEM(z_libc_partition) diff --git a/lib/libc/picolibc/libc-hooks.c b/lib/libc/picolibc/libc-hooks.c index ab90ab8b047..d00b53d1e8a 100644 --- a/lib/libc/picolibc/libc-hooks.c +++ b/lib/libc/picolibc/libc-hooks.c @@ -20,7 +20,7 @@ #include #include #ifdef CONFIG_MMU -#include +#include #endif #define LIBC_BSS K_APP_BMEM(z_libc_partition) diff --git a/tests/kernel/fatal/exception/src/main.c b/tests/kernel/fatal/exception/src/main.c index 79c793ebf11..ea4ffaa7c34 100644 --- a/tests/kernel/fatal/exception/src/main.c +++ b/tests/kernel/fatal/exception/src/main.c @@ -13,7 +13,7 @@ #include #if defined(CONFIG_USERSPACE) -#include +#include #include #include "test_syscalls.h" #endif diff --git a/tests/kernel/mem_heap/shared_multi_heap/src/main.c b/tests/kernel/mem_heap/shared_multi_heap/src/main.c index bee594c56f3..a9883ecc1c9 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/src/main.c +++ b/tests/kernel/mem_heap/shared_multi_heap/src/main.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/kernel/mem_protect/demand_paging/src/main.c b/tests/kernel/mem_protect/demand_paging/src/main.c index ed90e0fbe97..a453c06a573 100644 --- a/tests/kernel/mem_protect/demand_paging/src/main.c +++ b/tests/kernel/mem_protect/demand_paging/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/tests/kernel/mem_protect/mem_map/src/main.c b/tests/kernel/mem_protect/mem_map/src/main.c index 6db32356440..45ca0aa1cf3 100644 --- a/tests/kernel/mem_protect/mem_map/src/main.c +++ b/tests/kernel/mem_protect/mem_map/src/main.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include From f12d49d7efa88e0ac116f7c79646dc2ecc0135fa Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 13 Nov 2023 17:59:14 -0800 Subject: [PATCH 3820/4498] kernel: mm: separate demand paging headers into its own file This separates demand paging related headers into its own file instead of being stuffed inside the main kernel memory management header file. Signed-off-by: Daniel Leung --- MAINTAINERS.yml | 1 + include/zephyr/kernel/mm.h | 339 +-------------------- include/zephyr/kernel/mm/demand_paging.h | 369 +++++++++++++++++++++++ kernel/CMakeLists.txt | 5 + 4 files changed, 376 insertions(+), 338 deletions(-) create mode 100644 include/zephyr/kernel/mm/demand_paging.h diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 02ff92cb9f8..b5718196750 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3138,6 +3138,7 @@ Userspace: - include/zephyr/sys/mem_manage.h - include/zephyr/kernel/mm.h - include/zephyr/kernel/internal/mm.h + - include/zephyr/kernel/mm/demand_paging.h labels: - "area: Userspace" diff --git a/include/zephyr/kernel/mm.h b/include/zephyr/kernel/mm.h index b277449ea3e..1056857c4fd 100644 --- a/include/zephyr/kernel/mm.h +++ b/include/zephyr/kernel/mm.h @@ -14,6 +14,7 @@ #endif #include +#include /** * @brief Kernel Memory Management @@ -69,46 +70,6 @@ #include #include -struct k_mem_paging_stats_t { -#ifdef CONFIG_DEMAND_PAGING_STATS - struct { - /** Number of page faults */ - unsigned long cnt; - - /** Number of page faults with IRQ locked */ - unsigned long irq_locked; - - /** Number of page faults with IRQ unlocked */ - unsigned long irq_unlocked; - -#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ - /** Number of page faults while in ISR */ - unsigned long in_isr; -#endif - } pagefaults; - - struct { - /** Number of clean pages selected for eviction */ - unsigned long clean; - - /** Number of dirty pages selected for eviction */ - unsigned long dirty; - } eviction; -#endif /* CONFIG_DEMAND_PAGING_STATS */ -}; - -struct k_mem_paging_histogram_t { -#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM - /* Counts for each bin in timing histogram */ - unsigned long counts[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; - - /* Bounds for the bins in timing histogram, - * excluding the first and last (hence, NUM_SLOTS - 1). - */ - unsigned long bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; -#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ -}; - #ifdef __cplusplus extern "C" { #endif @@ -222,304 +183,6 @@ void k_mem_unmap(void *addr, size_t size); size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size, uintptr_t addr, size_t size, size_t align); -/** - * @defgroup demand_paging Demand Paging - * @ingroup kernel_memory_management - */ -/** - * @defgroup mem-demand-paging Demand Paging APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Evict a page-aligned virtual memory region to the backing store - * - * Useful if it is known that a memory region will not be used for some time. - * All the data pages within the specified region will be evicted to the - * backing store if they weren't already, with their associated page frames - * marked as available for mappings or page-ins. - * - * None of the associated page frames mapped to the provided region should - * be pinned. - * - * Note that there are no guarantees how long these pages will be evicted, - * they could take page faults immediately. - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - * @retval 0 Success - * @retval -ENOMEM Insufficient space in backing store to satisfy request. - * The region may be partially paged out. - */ -int k_mem_page_out(void *addr, size_t size); - -/** - * Load a virtual data region into memory - * - * After the function completes, all the page frames associated with this - * function will be paged in. However, they are not guaranteed to stay there. - * This is useful if the region is known to be used soon. - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_page_in(void *addr, size_t size); - -/** - * Pin an aligned virtual data region, paging in as necessary - * - * After the function completes, all the page frames associated with this - * region will be resident in memory and pinned such that they stay that way. - * This is a stronger version of z_mem_page_in(). - * - * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be - * called by ISRs as the backing store may be in-use. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_pin(void *addr, size_t size); - -/** - * Un-pin an aligned virtual data region - * - * After the function completes, all the page frames associated with this - * region will be no longer marked as pinned. This does not evict the region, - * follow this with z_mem_page_out() if you need that. - * - * @param addr Base page-aligned virtual address - * @param size Page-aligned data region size - */ -void k_mem_unpin(void *addr, size_t size); - -/** - * Get the paging statistics since system startup - * - * This populates the paging statistics struct being passed in - * as argument. - * - * @param[in,out] stats Paging statistics struct to be filled. - */ -__syscall void k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats); - -struct k_thread; -/** - * Get the paging statistics since system startup for a thread - * - * This populates the paging statistics struct being passed in - * as argument for a particular thread. - * - * @param[in] thread Thread - * @param[in,out] stats Paging statistics struct to be filled. - */ -__syscall -void k_mem_paging_thread_stats_get(struct k_thread *thread, - struct k_mem_paging_stats_t *stats); - -/** - * Get the eviction timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_eviction_get( - struct k_mem_paging_histogram_t *hist); - -/** - * Get the backing store page-in timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_backing_store_page_in_get( - struct k_mem_paging_histogram_t *hist); - -/** - * Get the backing store page-out timing histogram - * - * This populates the timing histogram struct being passed in - * as argument. - * - * @param[in,out] hist Timing histogram struct to be filled. - */ -__syscall void k_mem_paging_histogram_backing_store_page_out_get( - struct k_mem_paging_histogram_t *hist); - -#include - -/** @} */ - -/** - * Eviction algorithm APIs - * - * @defgroup mem-demand-paging-eviction Eviction Algorithm APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Select a page frame for eviction - * - * The kernel will invoke this to choose a page frame to evict if there - * are no free page frames. - * - * This function will never be called before the initial - * k_mem_paging_eviction_init(). - * - * This function is invoked with interrupts locked. - * - * @param [out] dirty Whether the page to evict is dirty - * @return The page frame to evict - */ -struct z_page_frame *k_mem_paging_eviction_select(bool *dirty); - -/** - * Initialization function - * - * Called at POST_KERNEL to perform any necessary initialization tasks for the - * eviction algorithm. k_mem_paging_eviction_select() is guaranteed to never be - * called until this has returned, and this will only be called once. - */ -void k_mem_paging_eviction_init(void); - -/** @} */ - -/** - * Backing store APIs - * - * @defgroup mem-demand-paging-backing-store Backing Store APIs - * @ingroup demand_paging - * @{ - */ - -/** - * Reserve or fetch a storage location for a data page loaded into a page frame - * - * The returned location token must be unique to the mapped virtual address. - * This location will be used in the backing store to page out data page - * contents for later retrieval. The location value must be page-aligned. - * - * This function may be called multiple times on the same data page. If its - * page frame has its Z_PAGE_FRAME_BACKED bit set, it is expected to return - * the previous backing store location for the data page containing a cached - * clean copy. This clean copy may be updated on page-out, or used to - * discard clean pages without needing to write out their contents. - * - * If the backing store is full, some other backing store location which caches - * a loaded data page may be selected, in which case its associated page frame - * will have the Z_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). - * - * pf->addr will indicate the virtual address the page is currently mapped to. - * Large, sparse backing stores which can contain the entire address space - * may simply generate location tokens purely as a function of pf->addr with no - * other management necessary. - * - * This function distinguishes whether it was called on behalf of a page - * fault. A free backing store location must always be reserved in order for - * page faults to succeed. If the page_fault parameter is not set, this - * function should return -ENOMEM even if one location is available. - * - * This function is invoked with interrupts locked. - * - * @param pf Virtual address to obtain a storage location - * @param [out] location storage location token - * @param page_fault Whether this request was for a page fault - * @return 0 Success - * @return -ENOMEM Backing store is full - */ -int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, - uintptr_t *location, - bool page_fault); - -/** - * Free a backing store location - * - * Any stored data may be discarded, and the location token associated with - * this address may be re-used for some other data page. - * - * This function is invoked with interrupts locked. - * - * @param location Location token to free - */ -void k_mem_paging_backing_store_location_free(uintptr_t location); - -/** - * Copy a data page from Z_SCRATCH_PAGE to the specified location - * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write - * to the intended source page frame for the calling context. - * - * Calls to this and k_mem_paging_backing_store_page_in() will always be - * serialized, but interrupts may be enabled. - * - * @param location Location token for the data page, for later retrieval - */ -void k_mem_paging_backing_store_page_out(uintptr_t location); - -/** - * Copy a data page from the provided location to Z_SCRATCH_PAGE. - * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write - * to the intended destination page frame for the calling context. - * - * Calls to this and k_mem_paging_backing_store_page_out() will always be - * serialized, but interrupts may be enabled. - * - * @param location Location token for the data page - */ -void k_mem_paging_backing_store_page_in(uintptr_t location); - -/** - * Update internal accounting after a page-in - * - * This is invoked after k_mem_paging_backing_store_page_in() and interrupts - * have been* re-locked, making it safe to access the z_page_frame data. - * The location value will be the same passed to - * k_mem_paging_backing_store_page_in(). - * - * The primary use-case for this is to update custom fields for the backing - * store in the page frame, to reflect where the data should be evicted to - * if it is paged out again. This may be a no-op in some implementations. - * - * If the backing store caches paged-in data pages, this is the appropriate - * time to set the Z_PAGE_FRAME_BACKED bit. The kernel only skips paging - * out clean data pages if they are noted as clean in the page tables and the - * Z_PAGE_FRAME_BACKED bit is set in their associated page frame. - * - * @param pf Page frame that was loaded in - * @param location Location of where the loaded data page was retrieved - */ -void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, - uintptr_t location); - -/** - * Backing store initialization function. - * - * The implementation may expect to receive page in/out calls as soon as this - * returns, but not before that. Called at POST_KERNEL. - * - * This function is expected to do two things: - * - Initialize any internal data structures and accounting for the backing - * store. - * - If the backing store already contains all or some loaded kernel data pages - * at boot time, Z_PAGE_FRAME_BACKED should be appropriately set for their - * associated page frames, and any internal accounting set up appropriately. - */ -void k_mem_paging_backing_store_init(void); - -/** @} */ - #ifdef __cplusplus } #endif diff --git a/include/zephyr/kernel/mm/demand_paging.h b/include/zephyr/kernel/mm/demand_paging.h new file mode 100644 index 00000000000..fb20a2c734f --- /dev/null +++ b/include/zephyr/kernel/mm/demand_paging.h @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_KERNEL_MM_DEMAND_PAGING_H +#define ZEPHYR_INCLUDE_KERNEL_MM_DEMAND_PAGING_H + +#include + +#include +#include + +/** + * @defgroup demand_paging Demand Paging + * @ingroup kernel_memory_management + */ + +/** + * @defgroup mem-demand-paging Demand Paging APIs + * @ingroup demand_paging + * @{ + */ + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include + +struct k_mem_paging_stats_t { +#ifdef CONFIG_DEMAND_PAGING_STATS + struct { + /** Number of page faults */ + unsigned long cnt; + + /** Number of page faults with IRQ locked */ + unsigned long irq_locked; + + /** Number of page faults with IRQ unlocked */ + unsigned long irq_unlocked; + +#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ + /** Number of page faults while in ISR */ + unsigned long in_isr; +#endif + } pagefaults; + + struct { + /** Number of clean pages selected for eviction */ + unsigned long clean; + + /** Number of dirty pages selected for eviction */ + unsigned long dirty; + } eviction; +#endif /* CONFIG_DEMAND_PAGING_STATS */ +}; + +struct k_mem_paging_histogram_t { +#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM + /* Counts for each bin in timing histogram */ + unsigned long counts[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; + + /* Bounds for the bins in timing histogram, + * excluding the first and last (hence, NUM_SLOTS - 1). + */ + unsigned long bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; +#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Evict a page-aligned virtual memory region to the backing store + * + * Useful if it is known that a memory region will not be used for some time. + * All the data pages within the specified region will be evicted to the + * backing store if they weren't already, with their associated page frames + * marked as available for mappings or page-ins. + * + * None of the associated page frames mapped to the provided region should + * be pinned. + * + * Note that there are no guarantees how long these pages will be evicted, + * they could take page faults immediately. + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + * @retval 0 Success + * @retval -ENOMEM Insufficient space in backing store to satisfy request. + * The region may be partially paged out. + */ +int k_mem_page_out(void *addr, size_t size); + +/** + * Load a virtual data region into memory + * + * After the function completes, all the page frames associated with this + * function will be paged in. However, they are not guaranteed to stay there. + * This is useful if the region is known to be used soon. + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_page_in(void *addr, size_t size); + +/** + * Pin an aligned virtual data region, paging in as necessary + * + * After the function completes, all the page frames associated with this + * region will be resident in memory and pinned such that they stay that way. + * This is a stronger version of z_mem_page_in(). + * + * If CONFIG_DEMAND_PAGING_ALLOW_IRQ is enabled, this function may not be + * called by ISRs as the backing store may be in-use. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_pin(void *addr, size_t size); + +/** + * Un-pin an aligned virtual data region + * + * After the function completes, all the page frames associated with this + * region will be no longer marked as pinned. This does not evict the region, + * follow this with z_mem_page_out() if you need that. + * + * @param addr Base page-aligned virtual address + * @param size Page-aligned data region size + */ +void k_mem_unpin(void *addr, size_t size); + +/** + * Get the paging statistics since system startup + * + * This populates the paging statistics struct being passed in + * as argument. + * + * @param[in,out] stats Paging statistics struct to be filled. + */ +__syscall void k_mem_paging_stats_get(struct k_mem_paging_stats_t *stats); + +struct k_thread; +/** + * Get the paging statistics since system startup for a thread + * + * This populates the paging statistics struct being passed in + * as argument for a particular thread. + * + * @param[in] thread Thread + * @param[in,out] stats Paging statistics struct to be filled. + */ +__syscall +void k_mem_paging_thread_stats_get(struct k_thread *thread, + struct k_mem_paging_stats_t *stats); + +/** + * Get the eviction timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_eviction_get( + struct k_mem_paging_histogram_t *hist); + +/** + * Get the backing store page-in timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_backing_store_page_in_get( + struct k_mem_paging_histogram_t *hist); + +/** + * Get the backing store page-out timing histogram + * + * This populates the timing histogram struct being passed in + * as argument. + * + * @param[in,out] hist Timing histogram struct to be filled. + */ +__syscall void k_mem_paging_histogram_backing_store_page_out_get( + struct k_mem_paging_histogram_t *hist); + +#include + +/** @} */ + +/** + * Eviction algorithm APIs + * + * @defgroup mem-demand-paging-eviction Eviction Algorithm APIs + * @ingroup demand_paging + * @{ + */ + +/** + * Select a page frame for eviction + * + * The kernel will invoke this to choose a page frame to evict if there + * are no free page frames. + * + * This function will never be called before the initial + * k_mem_paging_eviction_init(). + * + * This function is invoked with interrupts locked. + * + * @param [out] dirty Whether the page to evict is dirty + * @return The page frame to evict + */ +struct z_page_frame *k_mem_paging_eviction_select(bool *dirty); + +/** + * Initialization function + * + * Called at POST_KERNEL to perform any necessary initialization tasks for the + * eviction algorithm. k_mem_paging_eviction_select() is guaranteed to never be + * called until this has returned, and this will only be called once. + */ +void k_mem_paging_eviction_init(void); + +/** @} */ + +/** + * Backing store APIs + * + * @defgroup mem-demand-paging-backing-store Backing Store APIs + * @ingroup demand_paging + * @{ + */ + +/** + * Reserve or fetch a storage location for a data page loaded into a page frame + * + * The returned location token must be unique to the mapped virtual address. + * This location will be used in the backing store to page out data page + * contents for later retrieval. The location value must be page-aligned. + * + * This function may be called multiple times on the same data page. If its + * page frame has its Z_PAGE_FRAME_BACKED bit set, it is expected to return + * the previous backing store location for the data page containing a cached + * clean copy. This clean copy may be updated on page-out, or used to + * discard clean pages without needing to write out their contents. + * + * If the backing store is full, some other backing store location which caches + * a loaded data page may be selected, in which case its associated page frame + * will have the Z_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). + * + * pf->addr will indicate the virtual address the page is currently mapped to. + * Large, sparse backing stores which can contain the entire address space + * may simply generate location tokens purely as a function of pf->addr with no + * other management necessary. + * + * This function distinguishes whether it was called on behalf of a page + * fault. A free backing store location must always be reserved in order for + * page faults to succeed. If the page_fault parameter is not set, this + * function should return -ENOMEM even if one location is available. + * + * This function is invoked with interrupts locked. + * + * @param pf Virtual address to obtain a storage location + * @param [out] location storage location token + * @param page_fault Whether this request was for a page fault + * @return 0 Success + * @return -ENOMEM Backing store is full + */ +int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, + uintptr_t *location, + bool page_fault); + +/** + * Free a backing store location + * + * Any stored data may be discarded, and the location token associated with + * this address may be re-used for some other data page. + * + * This function is invoked with interrupts locked. + * + * @param location Location token to free + */ +void k_mem_paging_backing_store_location_free(uintptr_t location); + +/** + * Copy a data page from Z_SCRATCH_PAGE to the specified location + * + * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * to the intended source page frame for the calling context. + * + * Calls to this and k_mem_paging_backing_store_page_in() will always be + * serialized, but interrupts may be enabled. + * + * @param location Location token for the data page, for later retrieval + */ +void k_mem_paging_backing_store_page_out(uintptr_t location); + +/** + * Copy a data page from the provided location to Z_SCRATCH_PAGE. + * + * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * to the intended destination page frame for the calling context. + * + * Calls to this and k_mem_paging_backing_store_page_out() will always be + * serialized, but interrupts may be enabled. + * + * @param location Location token for the data page + */ +void k_mem_paging_backing_store_page_in(uintptr_t location); + +/** + * Update internal accounting after a page-in + * + * This is invoked after k_mem_paging_backing_store_page_in() and interrupts + * have been* re-locked, making it safe to access the z_page_frame data. + * The location value will be the same passed to + * k_mem_paging_backing_store_page_in(). + * + * The primary use-case for this is to update custom fields for the backing + * store in the page frame, to reflect where the data should be evicted to + * if it is paged out again. This may be a no-op in some implementations. + * + * If the backing store caches paged-in data pages, this is the appropriate + * time to set the Z_PAGE_FRAME_BACKED bit. The kernel only skips paging + * out clean data pages if they are noted as clean in the page tables and the + * Z_PAGE_FRAME_BACKED bit is set in their associated page frame. + * + * @param pf Page frame that was loaded in + * @param location Location of where the loaded data page was retrieved + */ +void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, + uintptr_t location); + +/** + * Backing store initialization function. + * + * The implementation may expect to receive page in/out calls as soon as this + * returns, but not before that. Called at POST_KERNEL. + * + * This function is expected to do two things: + * - Initialize any internal data structures and accounting for the backing + * store. + * - If the backing store already contains all or some loaded kernel data pages + * at boot time, Z_PAGE_FRAME_BACKED should be appropriately set for their + * associated page frames, and any internal accounting set up appropriately. + */ +void k_mem_paging_backing_store_init(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_ASMLANGUAGE */ +#endif /* ZEPHYR_INCLUDE_KERNEL_MM_DEMAND_PAGING_H */ diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 367b83ab04a..bec410968cc 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -25,6 +25,11 @@ zephyr_syscall_header_ifdef( ${ZEPHYR_BASE}/include/zephyr/sys/mem_manage.h ) +zephyr_syscall_header_ifdef( + CONFIG_DEMAND_PAGING + ${ZEPHYR_BASE}/include/zephyr/kernel/mm/demand_paging.h +) + # If a pre-built static library containing kernel code exists in # this directory, libkernel.a, link it with the application code # instead of building from source. From f52f76fd6b96472478663d498dce3562b93641e6 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 13 Nov 2023 15:49:44 -0800 Subject: [PATCH 3821/4498] doc: kernel/mm: some doxygen works () Some kernel memory management functions were previously not in any group. So put them under the kernel memory management group, and now they appear in API doc. () Group things together when appropriate. () Add doc if none exists before. Signed-off-by: Daniel Leung --- include/zephyr/kernel/mm.h | 39 ++++++++++++++++++------ include/zephyr/kernel/mm/demand_paging.h | 12 ++++++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/zephyr/kernel/mm.h b/include/zephyr/kernel/mm.h index 1056857c4fd..392dc4b7cde 100644 --- a/include/zephyr/kernel/mm.h +++ b/include/zephyr/kernel/mm.h @@ -21,11 +21,14 @@ * @defgroup kernel_memory_management Kernel Memory Management * @ingroup kernel_apis * @{ - * @} */ -/* - * Caching mode definitions. These are mutually exclusive. +/** + * @name Caching mode definitions. + * + * These are mutually exclusive. + * + * @{ */ /** No caching. Most drivers want this. */ @@ -45,8 +48,14 @@ /** Reserved bits for cache modes in k_map() flags argument */ #define K_MEM_CACHE_MASK (BIT(3) - 1) -/* - * Region permission attributes. Default is read-only, no user, no exec +/** @} */ + +/** + * @name Region permission attributes. + * + * Default is read-only, no user, no exec + * + * @{ */ /** Region will have read/write access (and not read-only) */ @@ -58,13 +67,19 @@ /** Region will be accessible to user mode (normally supervisor-only) */ #define K_MEM_PERM_USER BIT(5) -/* - * Region mapping behaviour attributes +/** @} */ + +/** + * @name Region mapping behaviour attributes + * + * @{ */ /** Region will be mapped to 1:1 virtual and physical address */ #define K_MEM_DIRECT_MAP BIT(6) +/** @} */ + #ifndef _ASMLANGUAGE #include #include @@ -74,8 +89,10 @@ extern "C" { #endif -/* - * k_mem_map() control flags +/** + * @name k_mem_map() control flags + * + * @{ */ /** @@ -98,6 +115,8 @@ extern "C" { */ #define K_MEM_MAP_LOCK BIT(17) +/** @} */ + /** * Return the amount of free memory available * @@ -187,5 +206,7 @@ size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size, } #endif +/** @} */ + #endif /* !_ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_KERNEL_MM_H */ diff --git a/include/zephyr/kernel/mm/demand_paging.h b/include/zephyr/kernel/mm/demand_paging.h index fb20a2c734f..10412d3a766 100644 --- a/include/zephyr/kernel/mm/demand_paging.h +++ b/include/zephyr/kernel/mm/demand_paging.h @@ -29,8 +29,11 @@ #include #include +/** + * Paging Statistics. + */ struct k_mem_paging_stats_t { -#ifdef CONFIG_DEMAND_PAGING_STATS +#if defined(CONFIG_DEMAND_PAGING_STATS) || defined(__DOXYGEN__) struct { /** Number of page faults */ unsigned long cnt; @@ -41,7 +44,7 @@ struct k_mem_paging_stats_t { /** Number of page faults with IRQ unlocked */ unsigned long irq_unlocked; -#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ +#if !defined(CONFIG_DEMAND_PAGING_ALLOW_IRQ) || defined(__DOXYGEN__) /** Number of page faults while in ISR */ unsigned long in_isr; #endif @@ -57,8 +60,11 @@ struct k_mem_paging_stats_t { #endif /* CONFIG_DEMAND_PAGING_STATS */ }; +/** + * Paging Statistics Histograms. + */ struct k_mem_paging_histogram_t { -#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM +#if defined(CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM) || defined(__DOXYGEN__) /* Counts for each bin in timing histogram */ unsigned long counts[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]; From 58152eb93803c06da250a1a2778cdbfa45776bb2 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 15 Nov 2023 09:35:06 +0100 Subject: [PATCH 3822/4498] cmake: modules: Add zephyr_library_add_dependencies extension Add a CMake zephyr library extension for add_dependencies, similar to the target_ functions. This avoids using ${ZEPHYR_CURRENT_LIBRARY} directly. Signed-off-by: Pieter De Gendt --- cmake/modules/extensions.cmake | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 061ed7747c1..6bdd55433eb 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -528,6 +528,10 @@ function(zephyr_library_cc_option) endforeach() endfunction() +function(zephyr_library_add_dependencies) + add_dependencies(${ZEPHYR_CURRENT_LIBRARY} ${ARGN}) +endfunction() + # Add the existing CMake library 'library' to the global list of # Zephyr CMake libraries. This is done automatically by the # constructor but must be called explicitly on CMake libraries that do @@ -1819,6 +1823,12 @@ function(zephyr_linker_sources_ifdef feature_toggle) endif() endfunction() +function(zephyr_library_add_dependencies_ifdef feature_toggle) + if(${${feature_toggle}}) + zephyr_library_add_dependencies(${ARGN}) + endif() +endfunction() + macro(list_append_ifdef feature_toggle list) if(${${feature_toggle}}) list(APPEND ${list} ${ARGN}) @@ -1965,6 +1975,12 @@ function(zephyr_linker_sources_ifndef feature_toggle) endif() endfunction() +function(zephyr_library_add_dependencies_ifndef feature_toggle) + if(NOT ${feature_toggle}) + zephyr_library_add_dependencies(${ARGN}) + endif() +endfunction() + macro(list_append_ifndef feature_toggle list) if(NOT ${feature_toggle}) list(APPEND ${list} ${ARGN}) From 8f8a77abc9f99aee430ce58501a391d2c7203667 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 17 Nov 2023 09:33:44 +0100 Subject: [PATCH 3823/4498] modules: hal_rpi_pico: Use zephyr_library_add_dependencies Replace usage of add_dependencies(${ZEPHYR_CURRENT_LIBRARY} ...) Signed-off-by: Pieter De Gendt --- modules/hal_rpi_pico/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_rpi_pico/CMakeLists.txt b/modules/hal_rpi_pico/CMakeLists.txt index 3ae107449ae..3281528d73f 100644 --- a/modules/hal_rpi_pico/CMakeLists.txt +++ b/modules/hal_rpi_pico/CMakeLists.txt @@ -42,7 +42,7 @@ if(CONFIG_HAS_RPI_PICO) BUILD_ALWAYS TRUE ) - add_dependencies(${ZEPHYR_CURRENT_LIBRARY} second_stage_bootloader) + zephyr_library_add_dependencies(second_stage_bootloader) zephyr_library_sources(${rp2_bootloader_asm}) endif() From 015659322187b7ac9df9f27eace5ff2a72e8ddeb Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 17 Nov 2023 09:34:53 +0100 Subject: [PATCH 3824/4498] bindesc: Use zephyr_library_add_dependencies Replace usage of add_dependencies(${ZEPHYR_CURRENT_LIBRARY} ...) Signed-off-by: Pieter De Gendt --- subsys/bindesc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bindesc/CMakeLists.txt b/subsys/bindesc/CMakeLists.txt index 7419a78e5a9..9dcb467208d 100644 --- a/subsys/bindesc/CMakeLists.txt +++ b/subsys/bindesc/CMakeLists.txt @@ -66,7 +66,7 @@ if(CONFIG_BINDESC_DEFINE_BUILD_TIME) bindesc_time_force_rebuild COMMAND ${CMAKE_COMMAND} ${CMAKE_BINARY_DIR} ) - add_dependencies(${ZEPHYR_CURRENT_LIBRARY} bindesc_time_force_rebuild) + zephyr_library_add_dependencies(bindesc_time_force_rebuild) endif() endif() From d7d11ef09f37449026436252c211d82f7513ee9e Mon Sep 17 00:00:00 2001 From: Natalia Pluta Date: Mon, 14 Aug 2023 11:36:56 +0200 Subject: [PATCH 3825/4498] soc: arm: nordic_nrf: Add Kconfig symbols for QDEC instances Add QDEC instances 20, 21, 130, 131 Signed-off-by: Natalia Pluta --- soc/arm/nordic_nrf/Kconfig.peripherals | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index d62238f1c8b..285b92d3dda 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -129,6 +129,18 @@ config HAS_HW_NRF_QDEC0 config HAS_HW_NRF_QDEC1 def_bool $(dt_nodelabel_enabled_with_compat,qdec1,$(DT_COMPAT_NORDIC_NRF_QDEC)) +config HAS_HW_NRF_QDEC20 + def_bool $(dt_nodelabel_enabled_with_compat,qdec20,$(DT_COMPAT_NORDIC_NRF_QDEC)) + +config HAS_HW_NRF_QDEC21 + def_bool $(dt_nodelabel_enabled_with_compat,qdec21,$(DT_COMPAT_NORDIC_NRF_QDEC)) + +config HAS_HW_NRF_QDEC130 + def_bool $(dt_nodelabel_enabled_with_compat,qdec130,$(DT_COMPAT_NORDIC_NRF_QDEC)) + +config HAS_HW_NRF_QDEC131 + def_bool $(dt_nodelabel_enabled_with_compat,qdec131,$(DT_COMPAT_NORDIC_NRF_QDEC)) + config HAS_HW_NRF_QSPI def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_QSPI)) From f5658254e8aac7b8def932b9c1b43999731434d2 Mon Sep 17 00:00:00 2001 From: Natalia Pluta Date: Mon, 14 Aug 2023 11:29:24 +0200 Subject: [PATCH 3826/4498] modules: hal_nordic: Add QDEC Kconfig symbols and translation to nrfx Add Kconfig symbols for QDEC instances (20, 21, 130, 131) and translation symbols used in nrfx drivers. Signed-off-by: Natalia Pluta --- modules/hal_nordic/nrfx/Kconfig | 20 ++++++++++++++++++++ modules/hal_nordic/nrfx/nrfx_config.h | 12 ++++++++++++ 2 files changed, 32 insertions(+) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 78d9671b3c4..53a77e60175 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -154,6 +154,26 @@ config NRFX_QDEC1 depends on $(dt_nodelabel_has_compat,qdec1,$(DT_COMPAT_NORDIC_NRF_QDEC)) select NRFX_QDEC +config NRFX_QDEC20 + bool "QDEC20 driver instance" + depends on $(dt_nodelabel_has_compat,qdec20,$(DT_COMPAT_NORDIC_NRF_QDEC)) + select NRFX_QDEC + +config NRFX_QDEC21 + bool "QDEC21 driver instance" + depends on $(dt_nodelabel_has_compat,qdec21,$(DT_COMPAT_NORDIC_NRF_QDEC)) + select NRFX_QDEC + +config NRFX_QDEC130 + bool "QDEC130 driver instance" + depends on $(dt_nodelabel_has_compat,qdec130,$(DT_COMPAT_NORDIC_NRF_QDEC)) + select NRFX_QDEC + +config NRFX_QDEC131 + bool "QDEC131 driver instance" + depends on $(dt_nodelabel_has_compat,qdec131,$(DT_COMPAT_NORDIC_NRF_QDEC)) + select NRFX_QDEC + config NRFX_QSPI bool "QSPI driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_QSPI)) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 04be67a7b43..f799c4207d5 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -244,6 +244,18 @@ #ifdef CONFIG_NRFX_QDEC1 #define NRFX_QDEC1_ENABLED 1 #endif +#ifdef CONFIG_NRFX_QDEC20 +#define NRFX_QDEC20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC21 +#define NRFX_QDEC21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC130 +#define NRFX_QDEC130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC131 +#define NRFX_QDEC131_ENABLED 1 +#endif #ifdef CONFIG_NRFX_QSPI #define NRFX_QSPI_ENABLED 1 From 8b2c5120aa1239bb09cddc451f0989fa8c2b5adf Mon Sep 17 00:00:00 2001 From: Natalia Pluta Date: Wed, 28 Jun 2023 11:41:07 +0200 Subject: [PATCH 3827/4498] drivers: sensor: qdec_nrfx: Add support for new QDEC instances Introducing support for new QDEC instances in the driver. Signed-off-by: Natalia Pluta --- drivers/sensor/qdec_nrfx/Kconfig | 4 ++++ drivers/sensor/qdec_nrfx/qdec_nrfx.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/sensor/qdec_nrfx/Kconfig b/drivers/sensor/qdec_nrfx/Kconfig index 64d91d6ba6f..71c3ab1d5b0 100644 --- a/drivers/sensor/qdec_nrfx/Kconfig +++ b/drivers/sensor/qdec_nrfx/Kconfig @@ -7,6 +7,10 @@ config QDEC_NRFX depends on DT_HAS_NORDIC_NRF_QDEC_ENABLED select NRFX_QDEC0 if HAS_HW_NRF_QDEC0 select NRFX_QDEC1 if HAS_HW_NRF_QDEC1 + select NRFX_QDEC20 if HAS_HW_NRF_QDEC20 + select NRFX_QDEC21 if HAS_HW_NRF_QDEC21 + select NRFX_QDEC130 if HAS_HW_NRF_QDEC130 + select NRFX_QDEC131 if HAS_HW_NRF_QDEC131 select PINCTRL help Enable support for nrfx QDEC driver for nRF MCU series. diff --git a/drivers/sensor/qdec_nrfx/qdec_nrfx.c b/drivers/sensor/qdec_nrfx/qdec_nrfx.c index b11ce70fb9c..10035e0a103 100644 --- a/drivers/sensor/qdec_nrfx/qdec_nrfx.c +++ b/drivers/sensor/qdec_nrfx/qdec_nrfx.c @@ -299,3 +299,19 @@ SENSOR_NRFX_QDEC_DEVICE(0); #ifdef CONFIG_HAS_HW_NRF_QDEC1 SENSOR_NRFX_QDEC_DEVICE(1); #endif + +#ifdef CONFIG_HAS_HW_NRF_QDEC20 +SENSOR_NRFX_QDEC_DEVICE(20); +#endif + +#ifdef CONFIG_HAS_HW_NRF_QDEC21 +SENSOR_NRFX_QDEC_DEVICE(21); +#endif + +#ifdef CONFIG_HAS_HW_NRF_QDEC130 +SENSOR_NRFX_QDEC_DEVICE(130); +#endif + +#ifdef CONFIG_HAS_HW_NRF_QDEC131 +SENSOR_NRFX_QDEC_DEVICE(131); +#endif From 43a0839c6c6bc9b06c00c6175d048e7d9c28aad2 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 3 Oct 2023 11:10:34 +0300 Subject: [PATCH 3828/4498] drivers: dma: Add SOF host DMA driver This commit introduces the SOF host DMA driver. This driver is used by NXP platforms in the context of SOF's host component to copy data from the host memory to the firmware (local) memory. This is possible because NXP platforms can access the host memory directly w/o an actual DMA engine. Signed-off-by: Laurentiu Mihalcea --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 3 + drivers/dma/Kconfig.nxp_sof_host_dma | 34 +++ drivers/dma/dma_nxp_sof_host_dma.c | 284 +++++++++++++++++++++++++ dts/bindings/dma/nxp,sof-host-dma.yaml | 12 ++ 5 files changed, 334 insertions(+) create mode 100644 drivers/dma/Kconfig.nxp_sof_host_dma create mode 100644 drivers/dma/dma_nxp_sof_host_dma.c create mode 100644 dts/bindings/dma/nxp,sof-host-dma.yaml diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 271ddf19ff0..e65c3726622 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -37,3 +37,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) zephyr_library_sources_ifdef(CONFIG_DMA_SEDI dma_sedi.c) zephyr_library_sources_ifdef(CONFIG_DMA_SMARTBOND dma_smartbond.c) +zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SOF_HOST_DMA dma_nxp_sof_host_dma.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 5a2ce5bdced..e24386558cd 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -69,4 +69,7 @@ source "drivers/dma/Kconfig.andes_atcdmac300" source "drivers/dma/Kconfig.sedi" source "drivers/dma/Kconfig.smartbond" + +source "drivers/dma/Kconfig.nxp_sof_host_dma" + endif # DMA diff --git a/drivers/dma/Kconfig.nxp_sof_host_dma b/drivers/dma/Kconfig.nxp_sof_host_dma new file mode 100644 index 00000000000..f909612f3aa --- /dev/null +++ b/drivers/dma/Kconfig.nxp_sof_host_dma @@ -0,0 +1,34 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config DMA_NXP_SOF_HOST_DMA + bool "NXP DMA driver used by SOF's host component" + default y + depends on DT_HAS_NXP_SOF_HOST_DMA_ENABLED + help + Enable NXP's DMA driver used by + SOF (Sound Open Firmware) host + component. Specifically, this driver + is used by the SOF host component to + perform transfers between the host + memory and firmware (local) memory, which + can be accessed without an actual + DMA engine. + +if DMA_NXP_SOF_HOST_DMA + +config DMA_NXP_SOF_HOST_DMA_ALIGN + int "Alignment (in bytes) required for memory regions passed to this driver" + default 8 + help + Use this to set the alignment (in bytes) + which shall be used by entities employing + this driver to adjust a memory region's size + and base address. Since this driver doesn't + actually have any hardware to back it up this + configuration doesn't make much sense as there's + no alignment restrictions imposed by memcpy. + Nevertheless, this is needed because this driver + needs to act as if it controls a DMA engine. + +endif # DMA_NXP_SOF_HOST_DMA diff --git a/drivers/dma/dma_nxp_sof_host_dma.c b/drivers/dma/dma_nxp_sof_host_dma.c new file mode 100644 index 00000000000..6c03d84418c --- /dev/null +++ b/drivers/dma/dma_nxp_sof_host_dma.c @@ -0,0 +1,284 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* used for driver binding */ +#define DT_DRV_COMPAT nxp_sof_host_dma + +/* macros used to parse DTS properties */ +#define IDENTITY_VARGS(V, ...) IDENTITY(V) + +#define _SOF_HOST_DMA_CHANNEL_INDEX_ARRAY(inst)\ + LISTIFY(DT_INST_PROP_OR(inst, dma_channels, 0), IDENTITY_VARGS, (,)) + +#define _SOF_HOST_DMA_CHANNEL_DECLARE(idx) {} + +#define SOF_HOST_DMA_CHANNELS_DECLARE(inst)\ + FOR_EACH(_SOF_HOST_DMA_CHANNEL_DECLARE,\ + (,), _SOF_HOST_DMA_CHANNEL_INDEX_ARRAY(inst)) + +LOG_MODULE_REGISTER(nxp_sof_host_dma); + +/* note: This driver doesn't attempt to provide + * a generic software-based DMA engine implementation. + * As its name suggests, its only usage is in SOF + * (Sound Open Firmware) for NXP plaforms which are + * able to access the host memory directly from the + * core on which the firmware is running. + */ + +enum channel_state { + CHAN_STATE_INIT = 0, + CHAN_STATE_CONFIGURED, +}; + +struct sof_host_dma_channel { + uint32_t src; + uint32_t dest; + uint32_t size; + uint32_t direction; + enum channel_state state; +}; + +struct sof_host_dma_data { + /* this needs to be first */ + struct dma_context ctx; + atomic_t channel_flags; + struct sof_host_dma_channel *channels; +}; + +static int channel_change_state(struct sof_host_dma_channel *chan, + enum channel_state next) +{ + enum channel_state prev = chan->state; + + /* validate transition */ + switch (prev) { + case CHAN_STATE_INIT: + case CHAN_STATE_CONFIGURED: + if (next != CHAN_STATE_CONFIGURED) { + return -EPERM; + } + break; + default: + LOG_ERR("invalid channel previous state: %d", prev); + return -EINVAL; + } + + chan->state = next; + + return 0; +} + +static int sof_host_dma_reload(const struct device *dev, uint32_t chan_id, + uint32_t src, uint32_t dst, size_t size) +{ + ARG_UNUSED(src); + ARG_UNUSED(dst); + ARG_UNUSED(size); + + struct sof_host_dma_data *data; + struct sof_host_dma_channel *chan; + int ret; + + data = dev->data; + + if (chan_id >= data->ctx.dma_channels) { + LOG_ERR("channel %d is not a valid channel ID", chan_id); + return -EINVAL; + } + + /* fetch channel data */ + chan = &data->channels[chan_id]; + + /* validate state */ + if (chan->state != CHAN_STATE_CONFIGURED) { + LOG_ERR("attempting to reload unconfigured DMA channel %d", chan_id); + return -EINVAL; + } + + if (chan->direction == HOST_TO_MEMORY) { + /* the host may have modified the region we're about to copy + * to local memory. In this case, the data cache holds stale + * data so invalidate it to force a read from the main memory. + */ + ret = sys_cache_data_invd_range(UINT_TO_POINTER(chan->src), + chan->size); + if (ret < 0) { + LOG_ERR("failed to invalidate data cache range"); + return ret; + } + } + + memcpy(UINT_TO_POINTER(chan->dest), UINT_TO_POINTER(chan->src), chan->size); + + if (chan->direction == MEMORY_TO_HOST) { + /* force range to main memory so that host doesn't read any + * stale data. + */ + ret = sys_cache_data_flush_range(UINT_TO_POINTER(chan->dest), + chan->size); + if (ret < 0) { + LOG_ERR("failed to flush data cache range"); + return ret; + } + } + + return 0; +} + + +static int sof_host_dma_config(const struct device *dev, uint32_t chan_id, + struct dma_config *config) +{ + struct sof_host_dma_data *data; + struct sof_host_dma_channel *chan; + int ret; + + data = dev->data; + + if (chan_id >= data->ctx.dma_channels) { + LOG_ERR("channel %d is not a valid channel ID", chan_id); + return -EINVAL; + } + + /* fetch channel data */ + chan = &data->channels[chan_id]; + + /* attempt a state transition */ + ret = channel_change_state(chan, CHAN_STATE_CONFIGURED); + if (ret < 0) { + LOG_ERR("failed to change channel %d's state to CONFIGURED", chan_id); + return ret; + } + + /* SG configurations are not currently supported */ + if (config->block_count != 1) { + LOG_ERR("invalid number of blocks: %d", config->block_count); + return -EINVAL; + } + + if (!config->head_block->source_address) { + LOG_ERR("got NULL source address"); + return -EINVAL; + } + + if (!config->head_block->dest_address) { + LOG_ERR("got NULL destination address"); + return -EINVAL; + } + + if (!config->head_block->block_size) { + LOG_ERR("got 0 bytes to copy"); + return -EINVAL; + } + + /* for now, only H2M and M2H transfers are supported */ + if (config->channel_direction != HOST_TO_MEMORY && + config->channel_direction != MEMORY_TO_HOST) { + LOG_ERR("invalid channel direction: %d", + config->channel_direction); + return -EINVAL; + } + + /* latch onto the passed configuration */ + chan->src = config->head_block->source_address; + chan->dest = config->head_block->dest_address; + chan->size = config->head_block->block_size; + chan->direction = config->channel_direction; + + LOG_DBG("configured channel %d with SRC 0x%x DST 0x%x SIZE 0x%x", + chan_id, chan->src, chan->dest, chan->size); + + return 0; +} + +static int sof_host_dma_start(const struct device *dev, uint32_t chan_id) +{ + /* nothing to be done here */ + return 0; +} + +static int sof_host_dma_stop(const struct device *dev, uint32_t chan_id) +{ + /* nothing to be done here */ + return 0; +} + +static int sof_host_dma_suspend(const struct device *dev, uint32_t chan_id) +{ + /* nothing to be done here */ + return 0; +} + +static int sof_host_dma_resume(const struct device *dev, uint32_t chan_id) +{ + /* nothing to be done here */ + return 0; +} + +static int sof_host_dma_get_status(const struct device *dev, + uint32_t chan_id, struct dma_status *stat) +{ + /* nothing to be done here */ + return 0; +} + +static int sof_host_dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *val) +{ + switch (type) { + case DMA_ATTR_COPY_ALIGNMENT: + case DMA_ATTR_BUFFER_SIZE_ALIGNMENT: + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *val = CONFIG_DMA_NXP_SOF_HOST_DMA_ALIGN; + break; + default: + LOG_ERR("invalid attribute type: %d", type); + return -EINVAL; + } + + return 0; +} + +static const struct dma_driver_api sof_host_dma_api = { + .reload = sof_host_dma_reload, + .config = sof_host_dma_config, + .start = sof_host_dma_start, + .stop = sof_host_dma_stop, + .suspend = sof_host_dma_suspend, + .resume = sof_host_dma_resume, + .get_status = sof_host_dma_get_status, + .get_attribute = sof_host_dma_get_attribute, +}; + +static int sof_host_dma_init(const struct device *dev) +{ + struct sof_host_dma_data *data = dev->data; + + data->channel_flags = ATOMIC_INIT(0); + data->ctx.atomic = &data->channel_flags; + + return 0; +} + +static struct sof_host_dma_channel channels[] = { + SOF_HOST_DMA_CHANNELS_DECLARE(0), +}; + +static struct sof_host_dma_data sof_host_dma_data = { + .ctx.magic = DMA_MAGIC, + .ctx.dma_channels = ARRAY_SIZE(channels), + .channels = channels, +}; + +/* assumption: only 1 SOF_HOST_DMA instance */ +DEVICE_DT_INST_DEFINE(0, sof_host_dma_init, NULL, + &sof_host_dma_data, NULL, + PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, + &sof_host_dma_api); diff --git a/dts/bindings/dma/nxp,sof-host-dma.yaml b/dts/bindings/dma/nxp,sof-host-dma.yaml new file mode 100644 index 00000000000..ebb03c46d8b --- /dev/null +++ b/dts/bindings/dma/nxp,sof-host-dma.yaml @@ -0,0 +1,12 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP SOF host DMA node + +compatible: "nxp,sof-host-dma" + +include: [base.yaml, dma-controller.yaml] + +properties: + dma-channels: + required: true From 3ef34ff6d1c60df8a620b8e9e453b1f8ee931a32 Mon Sep 17 00:00:00 2001 From: Piotr Wojnarowski Date: Thu, 16 Nov 2023 16:17:50 +0100 Subject: [PATCH 3829/4498] drivers: intc: plic: Make function names and types consistent `get_claim_complete_offset` and `get_threshold_priority_offset` actually return addresses directly. Rename them to `_addr` for consistency within the driver. Also change their return type to `mem_addr_t`. Signed-off-by: Piotr Wojnarowski --- drivers/interrupt_controller/intc_plic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 41ee75823b0..fa11faca91e 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -71,14 +71,14 @@ static inline uint32_t get_plic_enabled_size(const struct device *dev) return local_irq_to_reg_offset(config->num_irqs) + 1; } -static inline uint32_t get_claim_complete_offset(const struct device *dev) +static inline mem_addr_t get_claim_complete_addr(const struct device *dev) { const struct plic_config *config = dev->config; return config->reg + PLIC_REG_REGS_CLAIM_COMPLETE_OFFSET; } -static inline uint32_t get_threshold_priority_offset(const struct device *dev) +static inline mem_addr_t get_threshold_priority_addr(const struct device *dev) { const struct plic_config *config = dev->config; @@ -240,7 +240,7 @@ const struct device *riscv_plic_get_dev(void) static void plic_irq_handler(const struct device *dev) { const struct plic_config *config = dev->config; - mem_addr_t claim_complete_addr = get_claim_complete_offset(dev); + mem_addr_t claim_complete_addr = get_claim_complete_addr(dev); struct _isr_table_entry *ite; int edge_irq; @@ -305,7 +305,7 @@ static int plic_init(const struct device *dev) const struct plic_config *config = dev->config; mem_addr_t en_addr = config->irq_en; mem_addr_t prio_addr = config->prio; - mem_addr_t thres_prio_addr = get_threshold_priority_offset(dev); + mem_addr_t thres_prio_addr = get_threshold_priority_addr(dev); /* Ensure that all interrupts are disabled initially */ for (uint32_t i = 0; i < get_plic_enabled_size(dev); i++) { From 3afe238926affaed74f6fab4fc964d1e68fc4eef Mon Sep 17 00:00:00 2001 From: Piotr Wojnarowski Date: Thu, 16 Nov 2023 16:18:11 +0100 Subject: [PATCH 3830/4498] drivers: intc: plic: Fix memory-mapped register offset calculation Previously, the PLIC's registers were accessed through uint32_t *, so all calculated offsets were effectively multiplied by sizeof(uint32_t). Do the same manuallly now that we have mem_addr_t/sys_read32. Signed-off-by: Piotr Wojnarowski --- drivers/interrupt_controller/intc_plic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index fa11faca91e..20422f23433 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -59,16 +59,21 @@ struct plic_config { static uint32_t save_irq; static const struct device *save_dev; -static inline uint32_t local_irq_to_reg_offset(uint32_t local_irq) +static inline uint32_t local_irq_to_reg_index(uint32_t local_irq) { return local_irq >> LOG2(PLIC_REG_SIZE); } +static inline uint32_t local_irq_to_reg_offset(uint32_t local_irq) +{ + return local_irq_to_reg_index(local_irq) * sizeof(uint32_t); +} + static inline uint32_t get_plic_enabled_size(const struct device *dev) { const struct plic_config *config = dev->config; - return local_irq_to_reg_offset(config->num_irqs) + 1; + return local_irq_to_reg_index(config->num_irqs) + 1; } static inline mem_addr_t get_claim_complete_addr(const struct device *dev) From 6670dbe8348b6eb50be1c28cb9712bfd5908ffe3 Mon Sep 17 00:00:00 2001 From: Piotr Wojnarowski Date: Fri, 17 Nov 2023 15:36:44 +0100 Subject: [PATCH 3831/4498] tests: drivers: intc_plic: Add tests for register index and offset Add a test to verify that the regression from ffb8f31bffd39b3a21e99e31deb7555d0585d81c is fixed. Signed-off-by: Piotr Wojnarowski --- drivers/interrupt_controller/intc_plic.c | 10 ++++-- .../intc_plic/CMakeLists.txt | 8 +++++ .../interrupt_controller/intc_plic/Kconfig | 10 ++++++ .../interrupt_controller/intc_plic/prj.conf | 1 + .../interrupt_controller/intc_plic/src/main.c | 31 +++++++++++++++++++ .../intc_plic/testcase.yaml | 7 +++++ 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/interrupt_controller/intc_plic/CMakeLists.txt create mode 100644 tests/drivers/interrupt_controller/intc_plic/Kconfig create mode 100644 tests/drivers/interrupt_controller/intc_plic/prj.conf create mode 100644 tests/drivers/interrupt_controller/intc_plic/src/main.c create mode 100644 tests/drivers/interrupt_controller/intc_plic/testcase.yaml diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 20422f23433..51ce1769396 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -45,6 +45,12 @@ #define PLIC_REG_SIZE 32 #define PLIC_REG_MASK BIT_MASK(LOG2(PLIC_REG_SIZE)) +#ifdef CONFIG_TEST_INTC_PLIC +#define INTC_PLIC_STATIC +#else +#define INTC_PLIC_STATIC static inline +#endif + typedef void (*riscv_plic_irq_config_func_t)(void); struct plic_config { mem_addr_t prio; @@ -59,12 +65,12 @@ struct plic_config { static uint32_t save_irq; static const struct device *save_dev; -static inline uint32_t local_irq_to_reg_index(uint32_t local_irq) +INTC_PLIC_STATIC uint32_t local_irq_to_reg_index(uint32_t local_irq) { return local_irq >> LOG2(PLIC_REG_SIZE); } -static inline uint32_t local_irq_to_reg_offset(uint32_t local_irq) +INTC_PLIC_STATIC uint32_t local_irq_to_reg_offset(uint32_t local_irq) { return local_irq_to_reg_index(local_irq) * sizeof(uint32_t); } diff --git a/tests/drivers/interrupt_controller/intc_plic/CMakeLists.txt b/tests/drivers/interrupt_controller/intc_plic/CMakeLists.txt new file mode 100644 index 00000000000..59fd0a3bb2f --- /dev/null +++ b/tests/drivers/interrupt_controller/intc_plic/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(intc_plic) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/interrupt_controller/intc_plic/Kconfig b/tests/drivers/interrupt_controller/intc_plic/Kconfig new file mode 100644 index 00000000000..53ccc573482 --- /dev/null +++ b/tests/drivers/interrupt_controller/intc_plic/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config TEST_INTC_PLIC + bool + default y + help + Declare some intc_plic.c functions in the global scope for verification. + +source "Kconfig" diff --git a/tests/drivers/interrupt_controller/intc_plic/prj.conf b/tests/drivers/interrupt_controller/intc_plic/prj.conf new file mode 100644 index 00000000000..9467c292689 --- /dev/null +++ b/tests/drivers/interrupt_controller/intc_plic/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/drivers/interrupt_controller/intc_plic/src/main.c b/tests/drivers/interrupt_controller/intc_plic/src/main.c new file mode 100644 index 00000000000..631e0e8915a --- /dev/null +++ b/tests/drivers/interrupt_controller/intc_plic/src/main.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +uint32_t local_irq_to_reg_index(uint32_t local_irq); +uint32_t local_irq_to_reg_offset(uint32_t local_irq); + +ZTEST_SUITE(intc_plic, NULL, NULL, NULL, NULL, NULL); + +/* Test calculating the register index from a local IRQ number */ +ZTEST(intc_plic, test_local_irq_to_reg_index) +{ + zassert_equal(0, local_irq_to_reg_index(0x1f)); + zassert_equal(1, local_irq_to_reg_index(0x20)); + zassert_equal(1, local_irq_to_reg_index(0x3f)); + zassert_equal(2, local_irq_to_reg_index(0x40)); +} + +/* Test calculating the register offset from a local IRQ number */ +ZTEST(intc_plic, test_local_irq_to_reg_offset) +{ + zassert_equal(0, local_irq_to_reg_offset(0x1f)); + zassert_equal(4, local_irq_to_reg_offset(0x20)); + zassert_equal(4, local_irq_to_reg_offset(0x3f)); + zassert_equal(8, local_irq_to_reg_offset(0x40)); +} diff --git a/tests/drivers/interrupt_controller/intc_plic/testcase.yaml b/tests/drivers/interrupt_controller/intc_plic/testcase.yaml new file mode 100644 index 00000000000..11c1f74fa39 --- /dev/null +++ b/tests/drivers/interrupt_controller/intc_plic/testcase.yaml @@ -0,0 +1,7 @@ +tests: + drivers.interrupt_controller.intc_plic: + tags: + - drivers + - interrupt + - plic + platform_allow: qemu_riscv64 From 07ae06f8feb8d66b63d9df630aedc0149b917aba Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Thu, 16 Nov 2023 12:46:47 +0200 Subject: [PATCH 3832/4498] mgmt: mcumgr: Doxygen tags update Added a missing defgroup and ingroup for mcmumgr client and smp client. Signed-off-by: Juha Heiskanen --- .../zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h | 11 +++++++++++ .../zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h | 11 +++++++++++ include/zephyr/mgmt/mcumgr/smp/smp_client.h | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h index 8cede40d64e..61e12afb164 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h @@ -11,6 +11,13 @@ #include #include +/** + * @brief MCUmgr Image management client API + * @defgroup mcumgr_img_mgmt_client MCUmgr img_mgmt_client API + * @ingroup mcumgr + * @{ + */ + #ifdef __cplusplus extern "C" { #endif @@ -186,6 +193,10 @@ int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_ima int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h index 12e8abde246..0b12ccdb684 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h @@ -10,6 +10,13 @@ #include #include +/** + * @brief MCUmgr OS management client API + * @defgroup mcumgr_os_mgmt_client MCUmgr os_mgmt_client API + * @ingroup mcumgr + * @{ + */ + #ifdef __cplusplus extern "C" { #endif @@ -54,6 +61,10 @@ int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string); */ int os_mgmt_client_reset(struct os_mgmt_client *client); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/mgmt/mcumgr/smp/smp_client.h b/include/zephyr/mgmt/mcumgr/smp/smp_client.h index 88b2af701b0..2e0eee2cfe6 100644 --- a/include/zephyr/mgmt/mcumgr/smp/smp_client.h +++ b/include/zephyr/mgmt/mcumgr/smp/smp_client.h @@ -13,6 +13,13 @@ #include #include +/** + * @brief MCUmgr SMP client API + * @defgroup mcumgr_smp_client SMP client API + * @ingroup mcumgr + * @{ + */ + /** * @brief SMP client object */ @@ -102,6 +109,10 @@ void smp_client_buf_free(struct net_buf *nb); int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb, smp_client_res_fn cb, void *user_data, int timeout_in_sec); +/** + * @} + */ + #ifdef __cplusplus } #endif From 1d6d24b6effa22bd750b2704801910cd57692395 Mon Sep 17 00:00:00 2001 From: Benjamin Lindqvist Date: Thu, 16 Nov 2023 11:14:07 +0100 Subject: [PATCH 3833/4498] net: lwm2m: don't load credentials on plaintext context Since lwm2m_load_tls_credentials(ctx) will assume that the ctx has a valid security object assigned to it, it should not be called at all when ctx.use_dtls == false. This solves a major bug where LwM2M comms are DTLS encrypted but FOTA is allowed to be plain-text. Signed-off-by: Benjamin Lindqvist --- subsys/net/lib/lwm2m/lwm2m_engine.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 8fceecf9335..45d3822bdbb 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -1073,13 +1073,15 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) int ret; #if defined(CONFIG_LWM2M_DTLS_SUPPORT) - if (client_ctx->load_credentials) { - ret = client_ctx->load_credentials(client_ctx); - } else { - ret = lwm2m_load_tls_credentials(client_ctx); - } - if (ret < 0) { - return ret; + if (client_ctx->use_dtls) { + if (client_ctx->load_credentials) { + ret = client_ctx->load_credentials(client_ctx); + } else { + ret = lwm2m_load_tls_credentials(client_ctx); + } + if (ret < 0) { + return ret; + } } #endif /* CONFIG_LWM2M_DTLS_SUPPORT */ From 95bf611ac663ea84f4e9dec5f2f0d9bd590d4f17 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 12:58:30 +0100 Subject: [PATCH 3834/4498] tests/drivers sbs_gauge: Switch from native_posix to native_sim Switch from native_posix to native_sim as native test platform Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/sbs_gauge/testcase.yaml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/drivers/sensor/sbs_gauge/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/sbs_gauge/boards/native_posix.overlay b/tests/drivers/sensor/sbs_gauge/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/sbs_gauge/boards/native_posix.overlay rename to tests/drivers/sensor/sbs_gauge/boards/native_sim.overlay diff --git a/tests/drivers/sensor/sbs_gauge/testcase.yaml b/tests/drivers/sensor/sbs_gauge/testcase.yaml index b19fffaab42..e585ed6f807 100644 --- a/tests/drivers/sensor/sbs_gauge/testcase.yaml +++ b/tests/drivers/sensor/sbs_gauge/testcase.yaml @@ -15,10 +15,10 @@ tests: - sensors filter: dt_compat_enabled("sbs,sbs-gauge") platform_allow: - - native_posix + - native_sim - qemu_cortex_a9 - qemu_arc_hs integration_platforms: - - native_posix + - native_sim extra_configs: - CONFIG_EMUL=y From 3175a81da59082a175159221fa1a2a761d8d1d89 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:00:14 +0100 Subject: [PATCH 3835/4498] tests/drivers adltc2990: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/adltc2990/testcase.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/adltc2990/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/adltc2990/boards/native_posix.overlay b/tests/drivers/sensor/adltc2990/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/adltc2990/boards/native_posix.overlay rename to tests/drivers/sensor/adltc2990/boards/native_sim.overlay diff --git a/tests/drivers/sensor/adltc2990/testcase.yaml b/tests/drivers/sensor/adltc2990/testcase.yaml index 09b0519416d..2bf6dcfe5c8 100644 --- a/tests/drivers/sensor/adltc2990/testcase.yaml +++ b/tests/drivers/sensor/adltc2990/testcase.yaml @@ -7,4 +7,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From 5dbb71cc6f50be52a4bafd49b158723eaa8e1792 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:02:37 +0100 Subject: [PATCH 3836/4498] tests/drivers icm42688: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/icm42688/testcase.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/icm42688/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/icm42688/boards/native_posix.overlay b/tests/drivers/sensor/icm42688/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/icm42688/boards/native_posix.overlay rename to tests/drivers/sensor/icm42688/boards/native_sim.overlay diff --git a/tests/drivers/sensor/icm42688/testcase.yaml b/tests/drivers/sensor/icm42688/testcase.yaml index f8f5929078c..6f886cb6191 100644 --- a/tests/drivers/sensor/icm42688/testcase.yaml +++ b/tests/drivers/sensor/icm42688/testcase.yaml @@ -7,4 +7,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From 75006ad9af52829e59a39b97b06251db7b002fd1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:04:30 +0100 Subject: [PATCH 3837/4498] tests/drivers akm09918c: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/akm09918c/testcase.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/akm09918c/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/akm09918c/boards/native_posix.overlay b/tests/drivers/sensor/akm09918c/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/akm09918c/boards/native_posix.overlay rename to tests/drivers/sensor/akm09918c/boards/native_sim.overlay diff --git a/tests/drivers/sensor/akm09918c/testcase.yaml b/tests/drivers/sensor/akm09918c/testcase.yaml index 4ccafdfbec9..bc5167fda4b 100644 --- a/tests/drivers/sensor/akm09918c/testcase.yaml +++ b/tests/drivers/sensor/akm09918c/testcase.yaml @@ -7,4 +7,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From 5327ba38e5fb6e3cd6a6f1341fdfedf052457f33 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:05:42 +0100 Subject: [PATCH 3838/4498] tests/drivers ina230: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../ina230/boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/ina230/testcase.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/ina230/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/ina230/boards/native_posix.overlay b/tests/drivers/sensor/ina230/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/ina230/boards/native_posix.overlay rename to tests/drivers/sensor/ina230/boards/native_sim.overlay diff --git a/tests/drivers/sensor/ina230/testcase.yaml b/tests/drivers/sensor/ina230/testcase.yaml index a0f962e4a6c..9ead4ab22b1 100644 --- a/tests/drivers/sensor/ina230/testcase.yaml +++ b/tests/drivers/sensor/ina230/testcase.yaml @@ -7,4 +7,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From 1846fa6f2c563c159e5062347702daaf1c5b1457 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:07:41 +0100 Subject: [PATCH 3839/4498] tests/drivers ina237: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../ina237/boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/sensor/ina237/testcase.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/sensor/ina237/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/sensor/ina237/boards/native_posix.overlay b/tests/drivers/sensor/ina237/boards/native_sim.overlay similarity index 100% rename from tests/drivers/sensor/ina237/boards/native_posix.overlay rename to tests/drivers/sensor/ina237/boards/native_sim.overlay diff --git a/tests/drivers/sensor/ina237/testcase.yaml b/tests/drivers/sensor/ina237/testcase.yaml index afad2c5726c..3c9f97d7604 100644 --- a/tests/drivers/sensor/ina237/testcase.yaml +++ b/tests/drivers/sensor/ina237/testcase.yaml @@ -7,4 +7,5 @@ tests: - drivers - sensor - subsys - platform_allow: native_posix + platform_allow: + - native_sim From b85aef003cde55b8d0c27c01afe6a28a91ccacc7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:09:50 +0100 Subject: [PATCH 3840/4498] tests/drivers/build_all/sensor: Enable for native_sim And switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/drivers/build_all/sensor/testcase.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/drivers/build_all/sensor/testcase.yaml b/tests/drivers/build_all/sensor/testcase.yaml index eeca799df94..2bf581e58da 100644 --- a/tests/drivers/build_all/sensor/testcase.yaml +++ b/tests/drivers/build_all/sensor/testcase.yaml @@ -2,7 +2,11 @@ common: tags: - drivers - sensors - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim build_only: true tests: sensors.build.sensorhub: From 7d5772d2d66c85eb3234adb92378473468ffd469 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:12:23 +0100 Subject: [PATCH 3841/4498] tests/drivers/pinctrl/api: Enable for native_sim Enable for native_sim. and switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/drivers/pinctrl/api/testcase.yaml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/drivers/pinctrl/api/testcase.yaml b/tests/drivers/pinctrl/api/testcase.yaml index dc23dadafe9..90a6f48a496 100644 --- a/tests/drivers/pinctrl/api/testcase.yaml +++ b/tests/drivers/pinctrl/api/testcase.yaml @@ -1,23 +1,21 @@ # Copyright (c) 2021 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +common: + platform_allow: + - native_posix + - native_posix_64 + - native_sim + - native_sim_64 + integration_platforms: + - native_sim tests: drivers.pinctrl.api: tags: - drivers - pinctrl - platform_allow: - - native_posix - - native_posix_64 - integration_platforms: - - native_posix drivers.pinctrl.api_reg: tags: - drivers - pinctrl - platform_allow: - - native_posix - - native_posix_64 extra_args: CONF_FILE="prj.conf;reg.conf" - integration_platforms: - - native_posix From be8f4e104b00814b0ecafb50cac255aa2e15fd67 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:15:01 +0100 Subject: [PATCH 3842/4498] tests/drivers espi: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../espi/boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/espi/testcase.yaml | 5 +++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename tests/drivers/espi/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/espi/boards/native_posix.overlay b/tests/drivers/espi/boards/native_sim.overlay similarity index 100% rename from tests/drivers/espi/boards/native_posix.overlay rename to tests/drivers/espi/boards/native_sim.overlay diff --git a/tests/drivers/espi/testcase.yaml b/tests/drivers/espi/testcase.yaml index 89f1c45c2bc..d8d55bb2e33 100644 --- a/tests/drivers/espi/testcase.yaml +++ b/tests/drivers/espi/testcase.yaml @@ -8,6 +8,7 @@ tests: - espi filter: dt_compat_enabled("zephyr,espi-emul-controller") harness: ztest - platform_allow: native_posix + platform_allow: + - native_sim integration_platforms: - - native_posix + - native_sim From 64cb9a4540d2c3eb5156253a3551e653cb6ce0dd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:16:21 +0100 Subject: [PATCH 3843/4498] tests/drivers/regulator/api: Enable for native_sim Enable for native_sim. and switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/drivers/regulator/api/testcase.yaml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/drivers/regulator/api/testcase.yaml b/tests/drivers/regulator/api/testcase.yaml index 95a27f73d64..6aa48cc3aa2 100644 --- a/tests/drivers/regulator/api/testcase.yaml +++ b/tests/drivers/regulator/api/testcase.yaml @@ -1,24 +1,22 @@ # Copyright (c) 2022 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +common: + platform_allow: + - native_posix + - native_posix_64 + - native_sim + - native_sim_64 + integration_platforms: + - native_sim tests: drivers.regulator.api: tags: - drivers - regulator - platform_allow: - - native_posix - - native_posix_64 - integration_platforms: - - native_posix drivers.regulator.api.nothreadsaferefcnt: tags: - drivers - regulator - platform_allow: - - native_posix - - native_posix_64 - integration_platforms: - - native_posix extra_configs: - CONFIG_REGULATOR_THREAD_SAFE_REFCNT=n From c6f5dbe8a75effc6689f9288ba28375905fcd253 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:24:55 +0100 Subject: [PATCH 3844/4498] tests fuel_gauge/bq27z746: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../bq27z746/boards/{native_posix.conf => native_sim.conf} | 0 .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/fuel_gauge/bq27z746/testcase.yaml | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/fuel_gauge/bq27z746/boards/{native_posix.conf => native_sim.conf} (100%) rename tests/drivers/fuel_gauge/bq27z746/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf b/tests/drivers/fuel_gauge/bq27z746/boards/native_sim.conf similarity index 100% rename from tests/drivers/fuel_gauge/bq27z746/boards/native_posix.conf rename to tests/drivers/fuel_gauge/bq27z746/boards/native_sim.conf diff --git a/tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay b/tests/drivers/fuel_gauge/bq27z746/boards/native_sim.overlay similarity index 100% rename from tests/drivers/fuel_gauge/bq27z746/boards/native_posix.overlay rename to tests/drivers/fuel_gauge/bq27z746/boards/native_sim.overlay diff --git a/tests/drivers/fuel_gauge/bq27z746/testcase.yaml b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml index 21f149d4da2..3bf2755af76 100644 --- a/tests/drivers/fuel_gauge/bq27z746/testcase.yaml +++ b/tests/drivers/fuel_gauge/bq27z746/testcase.yaml @@ -3,4 +3,5 @@ tests: tags: - fuel_gauge filter: dt_compat_enabled("ti,bq27z746") - platform_allow: native_posix + platform_allow: + - native_sim From 3ff73f22a434d5d8b96695acf4236e6968d2e927 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:26:05 +0100 Subject: [PATCH 3845/4498] tests fuel_gauge/max17048: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../max17048/boards/{native_posix.conf => native_sim.conf} | 0 .../boards/{native_posix.overlay => native_sim.overlay} | 0 tests/drivers/fuel_gauge/max17048/testcase.yaml | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename tests/drivers/fuel_gauge/max17048/boards/{native_posix.conf => native_sim.conf} (100%) rename tests/drivers/fuel_gauge/max17048/boards/{native_posix.overlay => native_sim.overlay} (100%) diff --git a/tests/drivers/fuel_gauge/max17048/boards/native_posix.conf b/tests/drivers/fuel_gauge/max17048/boards/native_sim.conf similarity index 100% rename from tests/drivers/fuel_gauge/max17048/boards/native_posix.conf rename to tests/drivers/fuel_gauge/max17048/boards/native_sim.conf diff --git a/tests/drivers/fuel_gauge/max17048/boards/native_posix.overlay b/tests/drivers/fuel_gauge/max17048/boards/native_sim.overlay similarity index 100% rename from tests/drivers/fuel_gauge/max17048/boards/native_posix.overlay rename to tests/drivers/fuel_gauge/max17048/boards/native_sim.overlay diff --git a/tests/drivers/fuel_gauge/max17048/testcase.yaml b/tests/drivers/fuel_gauge/max17048/testcase.yaml index 33c8def4195..3f187d27cd7 100644 --- a/tests/drivers/fuel_gauge/max17048/testcase.yaml +++ b/tests/drivers/fuel_gauge/max17048/testcase.yaml @@ -3,4 +3,5 @@ tests: tags: - fuel_gauge filter: dt_compat_enabled("maxim,max17048") - platform_allow: native_posix + platform_allow: + - native_sim From e13acd2f29dd5d4de4b8dcab88ff38f628c35af1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:27:02 +0100 Subject: [PATCH 3846/4498] tests fuel_gauge/sbs_gauge: Enable for native_sim Enable for native_sim Signed-off-by: Alberto Escolar Piedras --- tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml index 66e3dde18df..97d25b26a05 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml +++ b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml @@ -5,7 +5,7 @@ tests: - fuel_gauge filter: > dt_compat_enabled("sbs,sbs-gauge-new-api") and - (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_SIM) extra_args: - CONF_FILE="prj.conf;boards/emulated_board.conf" - DTC_OVERLAY_FILE="boards/emulated_board.overlay" @@ -26,7 +26,7 @@ tests: - fuel_gauge filter: > dt_compat_enabled("sbs,sbs-gauge-new-api") and - (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_SIM) platform_allow: - hifive_unmatched - qemu_cortex_a53 @@ -52,4 +52,5 @@ tests: - CONFIG_USERSPACE=y platform_allow: - native_posix + - native_sim - qemu_x86 From ef346c2505cffea0029f31dece886946fe9db2ec Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:36:53 +0100 Subject: [PATCH 3847/4498] tests input/gpio_keys: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- .../boards/{native_posix.overlay => native_sim.overlay} | 0 .../{native_posix_64.overlay => native_sim_64.overlay} | 2 +- tests/drivers/input/gpio_keys/testcase.yaml | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) rename tests/drivers/input/gpio_keys/boards/{native_posix.overlay => native_sim.overlay} (100%) rename tests/drivers/input/gpio_keys/boards/{native_posix_64.overlay => native_sim_64.overlay} (70%) diff --git a/tests/drivers/input/gpio_keys/boards/native_posix.overlay b/tests/drivers/input/gpio_keys/boards/native_sim.overlay similarity index 100% rename from tests/drivers/input/gpio_keys/boards/native_posix.overlay rename to tests/drivers/input/gpio_keys/boards/native_sim.overlay diff --git a/tests/drivers/input/gpio_keys/boards/native_posix_64.overlay b/tests/drivers/input/gpio_keys/boards/native_sim_64.overlay similarity index 70% rename from tests/drivers/input/gpio_keys/boards/native_posix_64.overlay rename to tests/drivers/input/gpio_keys/boards/native_sim_64.overlay index 166e6f02e82..a906fce7488 100644 --- a/tests/drivers/input/gpio_keys/boards/native_posix_64.overlay +++ b/tests/drivers/input/gpio_keys/boards/native_sim_64.overlay @@ -3,4 +3,4 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "native_posix.overlay" +#include "native_sim.overlay" diff --git a/tests/drivers/input/gpio_keys/testcase.yaml b/tests/drivers/input/gpio_keys/testcase.yaml index b8fd702d96a..be4cb2b17e9 100644 --- a/tests/drivers/input/gpio_keys/testcase.yaml +++ b/tests/drivers/input/gpio_keys/testcase.yaml @@ -6,7 +6,7 @@ tests: - drivers - input platform_allow: - - native_posix - - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim From 6bba2d955b967eb8daf10d017eb0b3508bb86d08 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:48:22 +0100 Subject: [PATCH 3848/4498] tests/net/traffic_class: Enable for native_sim Enable these tests in native_sim and switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/traffic_class/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/net/traffic_class/testcase.yaml b/tests/net/traffic_class/testcase.yaml index b8a56acbb27..a69fe29edcb 100644 --- a/tests/net/traffic_class/testcase.yaml +++ b/tests/net/traffic_class/testcase.yaml @@ -2,8 +2,10 @@ common: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix_64 + - native_sim_64 tags: - net - traffic_class From 18d27f0a290c85c3edb134c2f74454b94ed21ce2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:50:41 +0100 Subject: [PATCH 3849/4498] tests ieee802154: Enable for native_sim Enable these tests for native_sim and switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/ieee802154/6lo_fragment/testcase.yaml | 4 +++- tests/net/ieee802154/custom_l2/testcase.yaml | 4 +++- tests/net/ieee802154/l2/testcase.yaml | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/net/ieee802154/6lo_fragment/testcase.yaml b/tests/net/ieee802154/6lo_fragment/testcase.yaml index 547a34c3a62..dad5d24d7b2 100644 --- a/tests/net/ieee802154/6lo_fragment/testcase.yaml +++ b/tests/net/ieee802154/6lo_fragment/testcase.yaml @@ -3,8 +3,10 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim tags: - net - ieee802154 diff --git a/tests/net/ieee802154/custom_l2/testcase.yaml b/tests/net/ieee802154/custom_l2/testcase.yaml index 4a289e924d8..97c58a16ba1 100644 --- a/tests/net/ieee802154/custom_l2/testcase.yaml +++ b/tests/net/ieee802154/custom_l2/testcase.yaml @@ -3,8 +3,10 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim tags: - net - ieee802154 diff --git a/tests/net/ieee802154/l2/testcase.yaml b/tests/net/ieee802154/l2/testcase.yaml index 2be38d93d24..795bd13304c 100644 --- a/tests/net/ieee802154/l2/testcase.yaml +++ b/tests/net/ieee802154/l2/testcase.yaml @@ -2,8 +2,10 @@ common: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 integration_platforms: - - native_posix + - native_sim tags: - net - ieee802154 From eae99c1035051599058ddf3f00eb0ea473024790 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:52:30 +0100 Subject: [PATCH 3850/4498] tests net/ptp/clock: Enable for native_sim Enable these tests for native_sim and switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/ptp/clock/testcase.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/net/ptp/clock/testcase.yaml b/tests/net/ptp/clock/testcase.yaml index d37134a9301..1d724695337 100644 --- a/tests/net/ptp/clock/testcase.yaml +++ b/tests/net/ptp/clock/testcase.yaml @@ -5,8 +5,9 @@ common: - frdm_k64f - sam_e70_xplained - native_posix + - native_sim integration_platforms: - - native_posix + - native_sim tests: net.ptp.clock: min_ram: 32 From c64f33a6486293d1d9f97cb18933477c12eaab17 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:56:05 +0100 Subject: [PATCH 3851/4498] tests/net lwm2m_rd_client: Switch from native_posix to native_sim Switch these tests from native_posix to native_sim Signed-off-by: Alberto Escolar Piedras --- .../net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf | 1 - tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_sim.conf | 1 + tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c | 6 +++--- tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf create mode 100644 tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_sim.conf diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf b/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf deleted file mode 100644 index eb56d825c96..00000000000 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_sim.conf b/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_sim.conf new file mode 100644 index 00000000000..0843e94acbd --- /dev/null +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_sim.conf @@ -0,0 +1 @@ +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 03d0dce7f49..931f6f15904 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -9,8 +9,8 @@ #include #include #include -#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) -#include "timer_model.h" +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) +#include "nsi_timer_model.h" #endif #include @@ -141,7 +141,7 @@ static void lwm2m_observe_cb(enum lwm2m_observe_event event, struct lwm2m_obj_pa static void my_suite_before(void *data) { -#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) /* It is enough that some slow-down is happening on sleeps, it does not have to be * real time */ diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml index 80c5bee1131..df49b3c7342 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml @@ -5,7 +5,7 @@ common: - lwm2m - net platform_allow: - - native_posix + - native_sim tests: net.lwm2m.lwm2m_rd_client: extra_args: EXTRA_CFLAGS="" From f7b8ded41ae26bdf4ea8f9409ed0e77123b188cf Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 13:59:16 +0100 Subject: [PATCH 3852/4498] tests/net/lib/coap_client/: Enable for native_sim Enable this test for native_sim Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/coap_client/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/net/lib/coap_client/testcase.yaml b/tests/net/lib/coap_client/testcase.yaml index 923e1380f01..18e64f08df5 100644 --- a/tests/net/lib/coap_client/testcase.yaml +++ b/tests/net/lib/coap_client/testcase.yaml @@ -2,5 +2,7 @@ common: depends_on: netif tests: net.coap.client: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tags: coap net From 0de923e2b0ef25e5c2a2a2138b729438763ee233 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:05:20 +0100 Subject: [PATCH 3853/4498] tests/net/lib/lwm2m/interop: Switch from native_posix to native_sim Switch support of native_posix to native_sim Signed-off-by: Alberto Escolar Piedras --- .../interop/boards/{native_posix.conf => native_sim.conf} | 2 +- tests/net/lib/lwm2m/interop/testcase.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename tests/net/lib/lwm2m/interop/boards/{native_posix.conf => native_sim.conf} (82%) diff --git a/tests/net/lib/lwm2m/interop/boards/native_posix.conf b/tests/net/lib/lwm2m/interop/boards/native_sim.conf similarity index 82% rename from tests/net/lib/lwm2m/interop/boards/native_posix.conf rename to tests/net/lib/lwm2m/interop/boards/native_sim.conf index 422e2c1bde4..2dc86f3d484 100644 --- a/tests/net/lib/lwm2m/interop/boards/native_posix.conf +++ b/tests/net/lib/lwm2m/interop/boards/native_sim.conf @@ -3,6 +3,6 @@ CONFIG_DNS_SERVER_IP_ADDRESSES=y CONFIG_DNS_SERVER1="192.0.2.2" CONFIG_LWM2M_DNS_SUPPORT=y CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" -CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y CONFIG_NATIVE_UART_0_ON_STDINOUT=y CONFIG_ASAN=y diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml index 42bd53814bf..06390472269 100644 --- a/tests/net/lib/lwm2m/interop/testcase.yaml +++ b/tests/net/lib/lwm2m/interop/testcase.yaml @@ -7,9 +7,9 @@ tests: pytest_dut_scope: module pytest_args: [] integration_platforms: - - native_posix + - native_sim platform_allow: - - native_posix + - native_sim - qemu_cortex_m3 - qemu_x86 tags: From 640b926b0afaebc477d2dc1e4099c9154402b790 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:07:16 +0100 Subject: [PATCH 3854/4498] tests/net/lib lwm2m_engine: Switch from native_posix to native_sim Switch support of native_posix to native_sim Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/lwm2m/lwm2m_engine/boards/native_posix.conf | 1 - tests/net/lib/lwm2m/lwm2m_engine/boards/native_sim.conf | 1 + tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 tests/net/lib/lwm2m/lwm2m_engine/boards/native_posix.conf create mode 100644 tests/net/lib/lwm2m/lwm2m_engine/boards/native_sim.conf diff --git a/tests/net/lib/lwm2m/lwm2m_engine/boards/native_posix.conf b/tests/net/lib/lwm2m/lwm2m_engine/boards/native_posix.conf deleted file mode 100644 index eb56d825c96..00000000000 --- a/tests/net/lib/lwm2m/lwm2m_engine/boards/native_posix.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y diff --git a/tests/net/lib/lwm2m/lwm2m_engine/boards/native_sim.conf b/tests/net/lib/lwm2m/lwm2m_engine/boards/native_sim.conf new file mode 100644 index 00000000000..0843e94acbd --- /dev/null +++ b/tests/net/lib/lwm2m/lwm2m_engine/boards/native_sim.conf @@ -0,0 +1 @@ +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y diff --git a/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml index a7f628405eb..2f765ac0dc1 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim From a86e0a8da9eec1bb0acb7e49cac0c1b63a9a7383 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:08:11 +0100 Subject: [PATCH 3855/4498] tests/net/lib/lwm2m/*: Switch integation_platforms to native_sim Switch integation_platforms from native_posix to native_sim Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/lwm2m/block_transfer/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_json/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_link_format/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_plain_text/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml | 2 +- tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml | 2 +- tests/net/lib/lwm2m/engine/testcase.yaml | 2 +- tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/net/lib/lwm2m/block_transfer/testcase.yaml b/tests/net/lib/lwm2m/block_transfer/testcase.yaml index 66f145fd18f..4ad71f29ef0 100644 --- a/tests/net/lib/lwm2m/block_transfer/testcase.yaml +++ b/tests/net/lib/lwm2m/block_transfer/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_json/testcase.yaml b/tests/net/lib/lwm2m/content_json/testcase.yaml index a283ce908ef..f933ec6d684 100644 --- a/tests/net/lib/lwm2m/content_json/testcase.yaml +++ b/tests/net/lib/lwm2m/content_json/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_link_format/testcase.yaml b/tests/net/lib/lwm2m/content_link_format/testcase.yaml index 5448cf68fd0..0b7d965d0f0 100644 --- a/tests/net/lib/lwm2m/content_link_format/testcase.yaml +++ b/tests/net/lib/lwm2m/content_link_format/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml b/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml index 2bf877f7353..dee42fcc503 100644 --- a/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml +++ b/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_plain_text/testcase.yaml b/tests/net/lib/lwm2m/content_plain_text/testcase.yaml index bd70dd790b3..96fc1726794 100644 --- a/tests/net/lib/lwm2m/content_plain_text/testcase.yaml +++ b/tests/net/lib/lwm2m/content_plain_text/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml b/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml index 9fc90f109bc..4580a2538ca 100644 --- a/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml +++ b/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml b/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml index 55cd89a9f51..1bca0ca15eb 100644 --- a/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml +++ b/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/engine/testcase.yaml b/tests/net/lib/lwm2m/engine/testcase.yaml index 3263441b418..b13ecef4753 100644 --- a/tests/net/lib/lwm2m/engine/testcase.yaml +++ b/tests/net/lib/lwm2m/engine/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim diff --git a/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml index ca0f06f58b5..a994dd72ad8 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml @@ -6,4 +6,4 @@ tests: - lwm2m - net integration_platforms: - - native_posix + - native_sim From 0a81ea5406c95f13980e97b7531dc4804fea200e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:16:33 +0100 Subject: [PATCH 3856/4498] tests/net/socket/can: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/socket/can/testcase.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/net/socket/can/testcase.yaml b/tests/net/socket/can/testcase.yaml index 251c541c0c2..6d5a2a495da 100644 --- a/tests/net/socket/can/testcase.yaml +++ b/tests/net/socket/can/testcase.yaml @@ -1,8 +1,8 @@ tests: net.socket.can: integration_platforms: - - native_posix - - native_posix_64 + - native_sim + - native_sim_64 tags: - net - can From 8991e0176c96d2d1a7890af68485f6fc7f738e2e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:17:05 +0100 Subject: [PATCH 3857/4498] tests/net/lib/coap_server: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/coap_server/common/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/net/lib/coap_server/common/testcase.yaml b/tests/net/lib/coap_server/common/testcase.yaml index c36e9646270..513d3c4a0e4 100644 --- a/tests/net/lib/coap_server/common/testcase.yaml +++ b/tests/net/lib/coap_server/common/testcase.yaml @@ -5,7 +5,7 @@ common: - coap - server integration_platforms: - - native_posix + - native_sim tests: net.coap.server.common: {} From c5e0f6c0ffabb64479866618744b0f10bb5c9389 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:17:22 +0100 Subject: [PATCH 3858/4498] tests/net/lib/http_server: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/http_server/common/testcase.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/net/lib/http_server/common/testcase.yaml b/tests/net/lib/http_server/common/testcase.yaml index 951f5d7c582..b86f2dc0c95 100644 --- a/tests/net/lib/http_server/common/testcase.yaml +++ b/tests/net/lib/http_server/common/testcase.yaml @@ -5,7 +5,7 @@ common: - http - server integration_platforms: - - native_posix + - native_sim tests: net.http.server.common: {} From f345378db1f8852753811c0bac8ae7858e55b331 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Thu, 16 Nov 2023 15:03:07 +0100 Subject: [PATCH 3859/4498] doc: application: Fix application build comment Fix the application build comment to make it valid for both ninja and make build tools. It generated the wrong "ninja" comment for "make". Signed-off-by: Andrej Butok --- doc/_extensions/zephyr/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/application.py b/doc/_extensions/zephyr/application.py index e24d1bf7647..969e3290a59 100644 --- a/doc/_extensions/zephyr/application.py +++ b/doc/_extensions/zephyr/application.py @@ -415,7 +415,7 @@ def _generate_cmake(self, **kwargs): cmake_args, source_dir)) if not compact: content.extend(['', - '# Now run ninja on the generated build system:']) + '# Now run the build tool on the generated build system:']) if 'build' in goals: content.append('{}{}{}'.format(generator, tool_build_dir, From c0c895273917a156e2cd9e743c607aeea820650e Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 16 Nov 2023 15:09:40 +0100 Subject: [PATCH 3860/4498] shell: do not enable subsystem/driver shell modules by default Do not enable subsystem/driver shell modules by default and stop abusing CONFIG_SHELL_MINIMAL, which is internal to the shell subsystem, to decide when to enable a driver shell. The list of shell modules has grown considerably through the years. Enabling CONFIG_SHELL for doing e.g. an interactive debug session leads to a large number of shell modules also being enabled unless explicitly disabled, which again leads to non-negligible increases in RAM/ROM usage. This commit attempts to establish a policy of subsystem/driver shell modules being disabled by default, requiring the user/application to explicitly enable only those needed. Signed-off-by: Henrik Brix Andersen --- drivers/adc/Kconfig | 1 - drivers/audio/Kconfig | 1 - drivers/can/Kconfig | 1 - drivers/clock_control/Kconfig.nrf | 1 - drivers/dac/Kconfig | 1 - drivers/edac/Kconfig | 1 - drivers/eeprom/Kconfig | 1 - drivers/flash/Kconfig | 1 - drivers/hwinfo/Kconfig | 1 - drivers/i2c/Kconfig | 1 - drivers/lora/Kconfig | 1 - drivers/mdio/Kconfig | 1 - drivers/pcie/host/Kconfig | 1 - drivers/pm_cpu_ops/Kconfig | 1 - drivers/pwm/Kconfig | 1 - drivers/regulator/Kconfig | 1 - drivers/sensor/Kconfig | 1 - drivers/smbus/Kconfig | 1 - drivers/w1/Kconfig | 1 - drivers/watchdog/Kconfig.shell | 1 - lib/acpi/Kconfig | 1 - samples/drivers/smbus/prj.conf | 1 + samples/shields/npm1300_ek/prj.conf | 1 + samples/shields/npm6001_ek/prj.conf | 1 + subsys/debug/coredump/Kconfig | 1 - subsys/dfu/Kconfig | 1 - subsys/logging/Kconfig.misc | 1 - subsys/net/l2/openthread/Kconfig | 1 - subsys/stats/Kconfig | 1 - subsys/usb/device_next/Kconfig | 1 - subsys/usb/host/Kconfig | 1 - 31 files changed, 3 insertions(+), 28 deletions(-) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index b52183c2b47..6dd41582bd0 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -17,7 +17,6 @@ if ADC config ADC_SHELL bool "ADC Shell" - default y depends on SHELL help Enable ADC Shell for testing. diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index 308bbb3172a..a9d11331676 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -27,7 +27,6 @@ config AUDIO_CODEC_INIT_PRIORITY config AUDIO_CODEC_SHELL bool "Audio Codec shell" - default y depends on SHELL help Enable the Audio Codec shell with Audio Codec related commands. diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index f12bbebf6fa..ed0818d3508 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -25,7 +25,6 @@ config CAN_INIT_PRIORITY config CAN_SHELL bool "CAN shell" - default y depends on SHELL select POLL help diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index 64e31b1ad16..453aac5b5d0 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -25,7 +25,6 @@ if CLOCK_CONTROL_NRF config CLOCK_CONTROL_NRF_SHELL bool "Shell commands" depends on SHELL - default y if SHELL choice CLOCK_CONTROL_NRF_SOURCE prompt "32KHz clock source" diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index 553d9f05355..3735a11aa2a 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -19,7 +19,6 @@ source "subsys/logging/Kconfig.template.log_config" config DAC_SHELL bool "DAC shell" - default y depends on SHELL help Enable DAC related shell commands. diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 45e499a749a..e5029ce470f 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -19,7 +19,6 @@ config EDAC_ERROR_INJECT config EDAC_SHELL bool "EDAC Shell" depends on SHELL - default y if SHELL help Enable EDAC shell for debugging EDAC. diff --git a/drivers/eeprom/Kconfig b/drivers/eeprom/Kconfig index 745d274ff1e..29405f4ed65 100644 --- a/drivers/eeprom/Kconfig +++ b/drivers/eeprom/Kconfig @@ -24,7 +24,6 @@ config EEPROM_INIT_PRIORITY config EEPROM_SHELL bool "EEPROM shell" - default y depends on SHELL help Enable the EEPROM shell with EEPROM related commands. diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 5b47c75c20e..698190e7780 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -53,7 +53,6 @@ config FLASH_SHELL bool "Flash shell" depends on SHELL && FLASH_PAGE_LAYOUT select MPU_ALLOW_FLASH_WRITE if ARM_MPU - default y help Enable the flash shell with flash related commands such as test, write, read and erase. diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 6971315b6b8..7c4cc7f0805 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -16,7 +16,6 @@ source "subsys/logging/Kconfig.template.log_config" config HWINFO_SHELL bool "HWINFO Shell" - default y depends on SHELL help Enable hwinfo Shell for testing. diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 2523877c851..233879167c6 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -15,7 +15,6 @@ if I2C config I2C_SHELL bool "I2C Shell" - default y depends on SHELL help Enable I2C Shell. diff --git a/drivers/lora/Kconfig b/drivers/lora/Kconfig index ddc1e50e625..585f122c3d6 100644 --- a/drivers/lora/Kconfig +++ b/drivers/lora/Kconfig @@ -21,7 +21,6 @@ source "subsys/logging/Kconfig.template.log_config" config LORA_SHELL bool "LoRa Shell" - default y depends on SHELL help Enable LoRa Shell for testing. diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index ddca38359fa..b3831b2c2d7 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -15,7 +15,6 @@ if MDIO config MDIO_SHELL bool "MDIO Shell" - default y depends on SHELL help Enable MDIO Shell. diff --git a/drivers/pcie/host/Kconfig b/drivers/pcie/host/Kconfig index 2dcb9bba612..515ef89ce28 100644 --- a/drivers/pcie/host/Kconfig +++ b/drivers/pcie/host/Kconfig @@ -82,7 +82,6 @@ config PCIE_PRT config PCIE_SHELL bool "PCIe/new PCI Shell" - default y depends on SHELL help Enable commands for debugging PCI(e) using the built-in shell. diff --git a/drivers/pm_cpu_ops/Kconfig b/drivers/pm_cpu_ops/Kconfig index c38c6779fa1..43d549f59bd 100644 --- a/drivers/pm_cpu_ops/Kconfig +++ b/drivers/pm_cpu_ops/Kconfig @@ -32,7 +32,6 @@ config PM_CPU_OPS_PSCI config PSCI_SHELL bool "Support for PSCI interface shell commands" - default y depends on SHELL && PM_CPU_OPS_PSCI help Say Y here if you need to enable PSCI interface shell commands diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index ff9856d9d57..8942ebd89b0 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -22,7 +22,6 @@ config PWM_INIT_PRIORITY config PWM_SHELL bool "PWM shell" - default y depends on SHELL help Enable the PWM related shell commands. diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ebf13261cbf..c35ae389669 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -17,7 +17,6 @@ config REGULATOR_THREAD_SAFE_REFCNT config REGULATOR_SHELL bool "Regulator shell" - default y depends on SHELL help Enable regulator shell framework, for interacting with regulators via diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 25af39bde4c..08d04774dcd 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -32,7 +32,6 @@ config SENSOR_SHELL depends on SHELL select CBPRINTF_FP_SUPPORT select SENSOR_ASYNC_API - default y if !SHELL_MINIMAL help This shell provides access to basic sensor data. diff --git a/drivers/smbus/Kconfig b/drivers/smbus/Kconfig index b80e1df2dd9..88eff8b0030 100644 --- a/drivers/smbus/Kconfig +++ b/drivers/smbus/Kconfig @@ -12,7 +12,6 @@ if SMBUS config SMBUS_SHELL bool "SMBus Shell" - default y depends on SHELL help Enable SMBus Shell. diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig index 2fabe874b6d..a63a5741981 100644 --- a/drivers/w1/Kconfig +++ b/drivers/w1/Kconfig @@ -26,7 +26,6 @@ config W1_INIT_PRIORITY config W1_SHELL bool "1-Wire Shell" depends on SHELL - default y if !SHELL_MINIMAL help Enable 1-Wire Shell for testing. diff --git a/drivers/watchdog/Kconfig.shell b/drivers/watchdog/Kconfig.shell index 5f5a97a6bda..11503277e93 100644 --- a/drivers/watchdog/Kconfig.shell +++ b/drivers/watchdog/Kconfig.shell @@ -3,7 +3,6 @@ config WDT_SHELL bool "Watchdog (WDT) shell" - default y depends on SHELL help Enable WDT shell. diff --git a/lib/acpi/Kconfig b/lib/acpi/Kconfig index 6c29b77875d..42b35725c70 100644 --- a/lib/acpi/Kconfig +++ b/lib/acpi/Kconfig @@ -32,7 +32,6 @@ endif # PCIE_PRT config ACPI_SHELL bool "ACPI command Shell" - default y depends on SHELL help Enable commands for debugging ACPI using the built-in shell. diff --git a/samples/drivers/smbus/prj.conf b/samples/drivers/smbus/prj.conf index a02baae7ec9..8ed31bb9e29 100644 --- a/samples/drivers/smbus/prj.conf +++ b/samples/drivers/smbus/prj.conf @@ -1,4 +1,5 @@ CONFIG_SMBUS=y +CONFIG_SMBUS_SHELL=y CONFIG_SMBUS_INTEL_PCH=y CONFIG_SMBUS_LOG_LEVEL_DBG=y CONFIG_USERSPACE=y diff --git a/samples/shields/npm1300_ek/prj.conf b/samples/shields/npm1300_ek/prj.conf index 7b134995827..c8421d9bf0c 100644 --- a/samples/shields/npm1300_ek/prj.conf +++ b/samples/shields/npm1300_ek/prj.conf @@ -5,5 +5,6 @@ CONFIG_SHELL=y CONFIG_LOG=y CONFIG_GPIO=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_SHELL=y CONFIG_SENSOR=y CONFIG_LED=y diff --git a/samples/shields/npm6001_ek/prj.conf b/samples/shields/npm6001_ek/prj.conf index bfacbe8b14b..94da7cfdaef 100644 --- a/samples/shields/npm6001_ek/prj.conf +++ b/samples/shields/npm6001_ek/prj.conf @@ -7,4 +7,5 @@ CONFIG_GETOPT=y CONFIG_GETOPT_LONG=y CONFIG_GPIO=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_SHELL=y CONFIG_WATCHDOG=y diff --git a/subsys/debug/coredump/Kconfig b/subsys/debug/coredump/Kconfig index 7b7de222784..63126a28372 100644 --- a/subsys/debug/coredump/Kconfig +++ b/subsys/debug/coredump/Kconfig @@ -71,7 +71,6 @@ endchoice config DEBUG_COREDUMP_SHELL bool "Coredump shell" - default y depends on SHELL help This shell provides access to coredump and its backends. diff --git a/subsys/dfu/Kconfig b/subsys/dfu/Kconfig index 121fa3964f6..e320185dfef 100644 --- a/subsys/dfu/Kconfig +++ b/subsys/dfu/Kconfig @@ -33,7 +33,6 @@ endchoice config MCUBOOT_SHELL bool "MCUboot shell" - default y depends on MCUBOOT_IMG_MANAGER depends on SHELL help diff --git a/subsys/logging/Kconfig.misc b/subsys/logging/Kconfig.misc index 0dc5831e528..ce34bdae0a0 100644 --- a/subsys/logging/Kconfig.misc +++ b/subsys/logging/Kconfig.misc @@ -15,7 +15,6 @@ config LOG_CMDS bool "Shell commands" depends on SHELL depends on !LOG_FRONTEND_ONLY && !LOG_MODE_MINIMAL - default y if SHELL config LOG_TEST_CLEAR_MESSAGE_SPACE bool "Clear message after allocation" diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index 70c7d642674..98113975797 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -151,7 +151,6 @@ endmenu # "Zephyr optimizations" config OPENTHREAD_SHELL bool "OpenThread shell" depends on SHELL - default y config MBEDTLS_PROMPTLESS bool diff --git a/subsys/stats/Kconfig b/subsys/stats/Kconfig index 1c6d138e1df..417d5db0213 100644 --- a/subsys/stats/Kconfig +++ b/subsys/stats/Kconfig @@ -20,7 +20,6 @@ config STATS_NAMES config STATS_SHELL bool "Statistics Shell Command" - default y depends on STATS && SHELL imply STATS_NAMES help diff --git a/subsys/usb/device_next/Kconfig b/subsys/usb/device_next/Kconfig index d6ccd4d7bd6..90a774a9e36 100644 --- a/subsys/usb/device_next/Kconfig +++ b/subsys/usb/device_next/Kconfig @@ -18,7 +18,6 @@ source "subsys/logging/Kconfig.template.log_config" config USBD_SHELL bool "USB device shell" - default y depends on SHELL help Enable USB device shell. diff --git a/subsys/usb/host/Kconfig b/subsys/usb/host/Kconfig index bdedc6a4aa4..e3055e0026c 100644 --- a/subsys/usb/host/Kconfig +++ b/subsys/usb/host/Kconfig @@ -17,7 +17,6 @@ source "subsys/logging/Kconfig.template.log_config" config USBH_SHELL bool "USB host shell" - default y depends on SHELL help Shell commands for USB host support. From 62f2ae1c5ed9a07c7cc307fe72d7eb91343e2863 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 16 Nov 2023 15:20:53 +0100 Subject: [PATCH 3861/4498] docs: releases: migration: 3.6: change in defaults for shell modules Mention the change in the default value for subsystem/driver shell module Kconfigs. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-3.6.rst | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index ddf42b6dc3a..bff8df17703 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -58,6 +58,41 @@ Device Drivers and Device Tree Power Management ================ +Shell +===== + +* The following subsystem and driver shell modules are now disabled by default. Each required shell + module must now be explicitly enabled via Kconfig (:github:`65307`): + + * :kconfig:option:`CONFIG_ACPI_SHELL` + * :kconfig:option:`CONFIG_ADC_SHELL` + * :kconfig:option:`CONFIG_AUDIO_CODEC_SHELL` + * :kconfig:option:`CONFIG_CAN_SHELL` + * :kconfig:option:`CONFIG_CLOCK_CONTROL_NRF_SHELL` + * :kconfig:option:`CONFIG_DAC_SHELL` + * :kconfig:option:`CONFIG_DEBUG_COREDUMP_SHELL` + * :kconfig:option:`CONFIG_EDAC_SHELL` + * :kconfig:option:`CONFIG_EEPROM_SHELL` + * :kconfig:option:`CONFIG_FLASH_SHELL` + * :kconfig:option:`CONFIG_HWINFO_SHELL` + * :kconfig:option:`CONFIG_I2C_SHELL` + * :kconfig:option:`CONFIG_LOG_CMDS` + * :kconfig:option:`CONFIG_LORA_SHELL` + * :kconfig:option:`CONFIG_MCUBOOT_SHELL` + * :kconfig:option:`CONFIG_MDIO_SHELL` + * :kconfig:option:`CONFIG_OPENTHREAD_SHELL` + * :kconfig:option:`CONFIG_PCIE_SHELL` + * :kconfig:option:`CONFIG_PSCI_SHELL` + * :kconfig:option:`CONFIG_PWM_SHELL` + * :kconfig:option:`CONFIG_REGULATOR_SHELL` + * :kconfig:option:`CONFIG_SENSOR_SHELL` + * :kconfig:option:`CONFIG_SMBUS_SHELL` + * :kconfig:option:`CONFIG_STATS_SHELL` + * :kconfig:option:`CONFIG_USBD_SHELL` + * :kconfig:option:`CONFIG_USBH_SHELL` + * :kconfig:option:`CONFIG_W1_SHELL` + * :kconfig:option:`CONFIG_WDT_SHELL` + Bootloader ========== From 92340883067910b6bfe5b52ab4a6d24b623ddb84 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 15:30:24 +0000 Subject: [PATCH 3862/4498] samples: kscan_touch: drop the kscan_touch sample All in-tree touchscreen drivers have been migrated over to input, the compatibility node has been removed from those boards as well, this sample can be dropped now. Signed-off-by: Fabio Baltieri --- MAINTAINERS.yml | 1 - doc/_scripts/redirects.py | 1 + samples/drivers/kscan_touch/CMakeLists.txt | 8 ----- samples/drivers/kscan_touch/README.rst | 27 -------------- samples/drivers/kscan_touch/prj.conf | 3 -- samples/drivers/kscan_touch/sample.yaml | 14 -------- samples/drivers/kscan_touch/src/main.c | 41 ---------------------- 7 files changed, 1 insertion(+), 94 deletions(-) delete mode 100644 samples/drivers/kscan_touch/CMakeLists.txt delete mode 100644 samples/drivers/kscan_touch/README.rst delete mode 100644 samples/drivers/kscan_touch/prj.conf delete mode 100644 samples/drivers/kscan_touch/sample.yaml delete mode 100644 samples/drivers/kscan_touch/src/main.c diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b5718196750..97d0ec0222f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1215,7 +1215,6 @@ Release Notes: - include/zephyr/drivers/kscan.h - samples/drivers/espi/ - samples/drivers/kscan/ - - samples/drivers/kscan_touch/ - tests/drivers/kscan/ - tests/drivers/espi/ - dts/bindings/kscan/ diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index 8c9120e9899..0180d1f5373 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -163,5 +163,6 @@ ('reference/usermode/overview', 'kernel/usermode/overview'), ('reference/usermode/syscalls', 'kernel/usermode/syscalls'), ('reference/util/index', 'kernel/util/index'), + ('samples/drivers/kscan_touch', 'samples/subsys/input/input'), ('samples/net/cloud/google_iot_mqtt', 'samples/net/cloud'), ] diff --git a/samples/drivers/kscan_touch/CMakeLists.txt b/samples/drivers/kscan_touch/CMakeLists.txt deleted file mode 100644 index 1c5812ccffb..00000000000 --- a/samples/drivers/kscan_touch/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(kscan) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/samples/drivers/kscan_touch/README.rst b/samples/drivers/kscan_touch/README.rst deleted file mode 100644 index 52ad2aa7095..00000000000 --- a/samples/drivers/kscan_touch/README.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. zephyr:code-sample:: kscan-touch - :name: KSCAN touch panel - :relevant-api: kscan_interface - - Use the KSCAN API to interface with a touch panel. - -Overview -******** - -This sample demonstrates how to interface with a touch panel. When touches are -detected a log message is output on the console. - -Building and Running -******************** - -The sample can be built and executed on boards with a touch panel for example -stm32f746g_disco or mimxrt1060_evk. The boards dts file should contain an alias -to kscan0 - -Sample output -============= - -.. code-block:: console - - KSCAN test for touch panels. - Note: You are expected to see several callbacks - as you touch the screen. diff --git a/samples/drivers/kscan_touch/prj.conf b/samples/drivers/kscan_touch/prj.conf deleted file mode 100644 index b25816644e9..00000000000 --- a/samples/drivers/kscan_touch/prj.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_STDOUT_CONSOLE=y -CONFIG_PRINTK=y -CONFIG_KSCAN=y diff --git a/samples/drivers/kscan_touch/sample.yaml b/samples/drivers/kscan_touch/sample.yaml deleted file mode 100644 index b555e9f9901..00000000000 --- a/samples/drivers/kscan_touch/sample.yaml +++ /dev/null @@ -1,14 +0,0 @@ -sample: - name: KSCAN touch driver api sample -tests: - sample.drivers.kscan_touch: - tags: - - drivers - - kscan_touch - harness: console - harness_config: - type: multi_line - ordered: true - regex: - - "kb data(.*)" - depends_on: kscan:touch diff --git a/samples/drivers/kscan_touch/src/main.c b/samples/drivers/kscan_touch/src/main.c deleted file mode 100644 index cfec920f732..00000000000 --- a/samples/drivers/kscan_touch/src/main.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 Mark Olsson - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#define LOG_LEVEL LOG_LEVEL_DBG -#include - -LOG_MODULE_REGISTER(main); - -const struct device *const kscan_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_keyboard_scan)); - -static void k_callback(const struct device *dev, uint32_t row, uint32_t col, - bool pressed) -{ - ARG_UNUSED(dev); - if (pressed) { - printk("row = %u col = %u\n", row, col); - } -} - -int main(void) -{ - printk("Kscan touch panel sample application\n"); - - if (!device_is_ready(kscan_dev)) { - LOG_ERR("kscan device %s not ready", kscan_dev->name); - return 0; - } - - kscan_config(kscan_dev, k_callback); - kscan_enable_callback(kscan_dev); - return 0; -} From 9f70cd557bf87cd84a9b19196bcc783e0f595416 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 16 Nov 2023 17:50:00 +0000 Subject: [PATCH 3863/4498] x86: Fix build when optimizations are disabled When building without optimizations and with only one core the linker does not throw away arch_start_cpu and we get an undefined reference to x86_ap_start Signed-off-by: Flavio Ceolin --- arch/x86/core/intel64/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index a522e87de3a..204264cbdf9 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -141,6 +141,7 @@ struct x86_cpuboot x86_cpuboot[] = { void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) { +#if CONFIG_MP_MAX_NUM_CPUS > 1 uint8_t vector = ((unsigned long) x86_ap_start) >> 12; uint8_t apic_id; @@ -166,6 +167,13 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, while (x86_cpuboot[cpu_num].ready == 0) { } +#else + ARG_UNUSED(cpu_num); + ARG_UNUSED(stack); + ARG_UNUSED(sz); + ARG_UNUSED(fn); + ARG_UNUSED(arg); +#endif } /* Per-CPU initialization, C domain. On the first CPU, z_x86_prep_c is the From 7d9c0b9db5cdda0d0941176cc8161bda69d91f59 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Nov 2023 13:23:59 -0500 Subject: [PATCH 3864/4498] lib/os/cbprintf: Picolibc doesn't support several cbprintf options * Picolibc doesn't provide the %a-only mode. * On advice from security experts, who report numerous vulnerabilities caused by %n in printf specifiers, picolibc never supports this feature. * Picolibc doesn't use cbprintf for C-library compatible functions, instead it provides aliases for the *printfcb functions using stdio names. Signed-off-by: Keith Packard --- lib/os/Kconfig.cbprintf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/os/Kconfig.cbprintf b/lib/os/Kconfig.cbprintf index 0180c745dc3..93ffa90ca5d 100644 --- a/lib/os/Kconfig.cbprintf +++ b/lib/os/Kconfig.cbprintf @@ -90,6 +90,7 @@ config CBPRINTF_FP_A_SUPPORT config CBPRINTF_FP_ALWAYS_A bool "Select %a format for all floating point specifications" select CBPRINTF_FP_A_SUPPORT + depends on !PICOLIBC help The %a format for floats requires significantly less code than the standard decimal representations (%f, %e, %g). Selecting this @@ -103,10 +104,12 @@ config CBPRINTF_FP_ALWAYS_A config CBPRINTF_N_SPECIFIER bool "Support %n specifications" depends on CBPRINTF_COMPLETE + depends on !PICOLIBC default y help If selected %n can be used to determine the number of characters emitted. If enabled there is a small increase in code size. + Picolibc does not support this feature for security reasons. # 180: 18% / 138 B (180 / 80) [NANO] config CBPRINTF_LIBC_SUBSTS @@ -120,6 +123,9 @@ config CBPRINTF_LIBC_SUBSTS When used with CBPRINTF_NANO this increases the implementation code size by a small amount. + When used with picolibc, this option generates cbprintf-compatible + functions using stdio, effectively inverting the sense above. + module = CBPRINTF_PACKAGE module-str = cbprintf_package source "subsys/logging/Kconfig.template.log_config" From 9369c6f8e1b651f0cda01e8162a02aae291db462 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Thu, 16 Nov 2023 17:02:15 -0600 Subject: [PATCH 3865/4498] rtio: Make coverity happy Coverity reported (rightfully) a possible divide by zero when trying to allocate from a pool. Return -ENOMEM in such scenarios as it means there is no memory to allocate from. Signed-off-by: Tom Burdick --- include/zephyr/rtio/rtio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 8ad07281cee..fe0f5b72c97 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -674,6 +674,13 @@ static inline int rtio_block_pool_alloc(struct rtio *r, size_t min_sz, const uint32_t block_size = rtio_mempool_block_size(r); uint32_t bytes = max_sz; + /* Not every context has a block pool and the block size may return 0 in + * that case + */ + if (block_size == 0) { + return -ENOMEM; + } + do { size_t num_blks = DIV_ROUND_UP(bytes, block_size); int rc = sys_mem_blocks_alloc_contiguous(r->block_pool, num_blks, (void **)buf); From 5f1c2f199b63c03ea780acbfbfecdd168f399b4f Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 17 Nov 2023 09:36:34 +0800 Subject: [PATCH 3866/4498] Bluetooth: Mesh: Make element as rodata the reason is that the Mesh Profile clearly stipulates that Mesh nodes cannot change their own element definitions. Signed-off-by: Lingao Meng --- include/zephyr/bluetooth/mesh/access.h | 26 ++++--- include/zephyr/bluetooth/mesh/health_srv.h | 2 +- samples/bluetooth/mesh/src/main.c | 2 +- samples/bluetooth/mesh_demo/src/main.c | 4 +- samples/bluetooth/mesh_provisioner/src/main.c | 2 +- samples/boards/nrf/mesh/onoff-app/src/main.c | 8 +-- .../src/mesh/device_composition.c | 4 +- .../boards/reel_board/mesh_badge/src/mesh.c | 16 ++--- subsys/bluetooth/mesh/access.c | 70 +++++++++---------- subsys/bluetooth/mesh/access.h | 6 +- subsys/bluetooth/mesh/cfg_srv.c | 40 +++++------ subsys/bluetooth/mesh/health_srv.c | 2 +- subsys/bluetooth/mesh/main.c | 6 +- subsys/bluetooth/mesh/op_agg_cli.c | 2 +- subsys/bluetooth/mesh/shell/shell.c | 6 +- subsys/bluetooth/mesh/shell/utils.c | 2 +- tests/bluetooth/mesh/basic/src/main.c | 2 +- tests/bluetooth/mesh_shell/src/main.c | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 4 +- tests/bsim/bluetooth/mesh/src/mesh_test.c | 2 +- tests/bsim/bluetooth/mesh/src/test_access.c | 2 +- tests/bsim/bluetooth/mesh/src/test_beacon.c | 2 +- tests/bsim/bluetooth/mesh/src/test_blob.c | 8 +-- tests/bsim/bluetooth/mesh/src/test_cdp1.c | 2 +- tests/bsim/bluetooth/mesh/src/test_dfu.c | 16 ++--- tests/bsim/bluetooth/mesh/src/test_lcd.c | 4 +- tests/bsim/bluetooth/mesh/src/test_op_agg.c | 2 +- .../bsim/bluetooth/mesh/src/test_provision.c | 10 +-- tests/bsim/bluetooth/mesh/src/test_sar.c | 2 +- 29 files changed, 130 insertions(+), 126 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 45042b87d9b..7ae53a7d9ea 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -145,19 +145,23 @@ extern "C" { * @param _mods Array of models. * @param _vnd_mods Array of vendor models. */ -#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \ -{ \ - .loc = (_loc), \ - .model_count = ARRAY_SIZE(_mods), \ - .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ - .models = (_mods), \ - .vnd_models = (_vnd_mods), \ +#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \ +{ \ + .rt = &(struct bt_mesh_elem_rt_ctx) { 0 }, \ + .loc = (_loc), \ + .model_count = ARRAY_SIZE(_mods), \ + .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ + .models = (_mods), \ + .vnd_models = (_vnd_mods), \ } /** Abstraction that describes a Mesh Element */ struct bt_mesh_elem { - /** Unicast Address. Set at runtime during provisioning. */ - uint16_t addr; + /** Mesh Element runtime information */ + struct bt_mesh_elem_rt_ctx { + /** Unicast Address. Set at runtime during provisioning. */ + uint16_t addr; + } * const rt; /** Location Descriptor (GATT Bluetooth Namespace Descriptors) */ const uint16_t loc; @@ -1001,7 +1005,7 @@ static inline bool bt_mesh_model_pub_is_retransmission(const struct bt_mesh_mode * * @return Pointer to the element that the given model belongs to. */ -struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod); +const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod); /** @brief Find a SIG model. * @@ -1147,7 +1151,7 @@ struct bt_mesh_comp { uint16_t vid; /**< Version ID */ size_t elem_count; /**< The number of elements in this device. */ - struct bt_mesh_elem *elem; /**< List of elements. */ + const struct bt_mesh_elem *elem; /**< List of elements. */ }; /** Composition data page 2 record. */ diff --git a/include/zephyr/bluetooth/mesh/health_srv.h b/include/zephyr/bluetooth/mesh/health_srv.h index bb1e48004b9..3eef7e459f7 100644 --- a/include/zephyr/bluetooth/mesh/health_srv.h +++ b/include/zephyr/bluetooth/mesh/health_srv.h @@ -219,7 +219,7 @@ struct bt_mesh_health_srv { * * @return 0 on success, or (negative) error code otherwise. */ -int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem); +int bt_mesh_health_srv_fault_update(const struct bt_mesh_elem *elem); /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op bt_mesh_health_srv_op[]; diff --git a/samples/bluetooth/mesh/src/main.c b/samples/bluetooth/mesh/src/main.c index 5555edef9bb..b220b354fd5 100644 --- a/samples/bluetooth/mesh/src/main.c +++ b/samples/bluetooth/mesh/src/main.c @@ -257,7 +257,7 @@ static const struct bt_mesh_model models[] = { NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, models, BT_MESH_MODEL_NONE), }; diff --git a/samples/bluetooth/mesh_demo/src/main.c b/samples/bluetooth/mesh_demo/src/main.c index 08d6a1aae9b..b405fd06216 100644 --- a/samples/bluetooth/mesh_demo/src/main.c +++ b/samples/bluetooth/mesh_demo/src/main.c @@ -86,7 +86,7 @@ static int vnd_button_pressed(const struct bt_mesh_model *model, { printk("src 0x%04x\n", ctx->addr); - if (ctx->addr == bt_mesh_model_elem(model)->addr) { + if (ctx->addr == bt_mesh_model_elem(model)->rt->addr) { return 0; } @@ -105,7 +105,7 @@ static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, MOD_LF, vnd_ops, NULL, NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vnd_models), }; diff --git a/samples/bluetooth/mesh_provisioner/src/main.c b/samples/bluetooth/mesh_provisioner/src/main.c index 057087a2e8a..472dc020d43 100644 --- a/samples/bluetooth/mesh_provisioner/src/main.c +++ b/samples/bluetooth/mesh_provisioner/src/main.c @@ -59,7 +59,7 @@ static const struct bt_mesh_model root_models[] = { BT_MESH_MODEL_HEALTH_CLI(&health_cli), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE), }; diff --git a/samples/boards/nrf/mesh/onoff-app/src/main.c b/samples/boards/nrf/mesh/onoff-app/src/main.c index 71b787fe497..f0755cb70ab 100644 --- a/samples/boards/nrf/mesh/onoff-app/src/main.c +++ b/samples/boards/nrf/mesh/onoff-app/src/main.c @@ -236,7 +236,7 @@ const struct bt_mesh_model *mod_srv_sw[] = { * Root and Secondary Element Declarations */ -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE), BT_MESH_ELEM(0, secondary_0_models, BT_MESH_MODEL_NONE), BT_MESH_ELEM(0, secondary_1_models, BT_MESH_MODEL_NONE), @@ -289,7 +289,7 @@ static int gen_onoff_get(const struct bt_mesh_model *model, struct led_onoff_state *onoff_state = model->rt->user_data; printk("addr 0x%04x onoff 0x%02x\n", - bt_mesh_model_elem(model)->addr, onoff_state->current); + bt_mesh_model_elem(model)->rt->addr, onoff_state->current); bt_mesh_model_msg_init(&msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS); net_buf_simple_add_u8(&msg, onoff_state->current); @@ -310,7 +310,7 @@ static int gen_onoff_set_unack(const struct bt_mesh_model *model, onoff_state->current = net_buf_simple_pull_u8(buf); printk("addr 0x%02x state 0x%02x\n", - bt_mesh_model_elem(model)->addr, onoff_state->current); + bt_mesh_model_elem(model)->rt->addr, onoff_state->current); gpio_pin_set_dt(&onoff_state->led_device, onoff_state->current); @@ -361,7 +361,7 @@ static int gen_onoff_status(const struct bt_mesh_model *model, state = net_buf_simple_pull_u8(buf); printk("Node 0x%04x OnOff status from 0x%04x with state 0x%02x\n", - bt_mesh_model_elem(model)->addr, ctx->addr, state); + bt_mesh_model_elem(model)->rt->addr, ctx->addr, state); return 0; } diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 775c793bb37..1c59ef8fbd7 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -63,7 +63,7 @@ struct vendor_state vnd_user_data; /* Definitions of models user data (End) */ -static struct bt_mesh_elem elements[]; +static const struct bt_mesh_elem elements[]; /* message handlers (Start) */ @@ -3190,7 +3190,7 @@ const struct bt_mesh_model s0_models[] = { NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vnd_models), BT_MESH_ELEM(0, s0_models, BT_MESH_MODEL_NONE), }; diff --git a/samples/boards/reel_board/mesh_badge/src/mesh.c b/samples/boards/reel_board/mesh_badge/src/mesh.c index 61af8cc0b6d..0b9aff947b0 100644 --- a/samples/boards/reel_board/mesh_badge/src/mesh.c +++ b/samples/boards/reel_board/mesh_badge/src/mesh.c @@ -187,7 +187,7 @@ static int gen_onoff_get(const struct bt_mesh_model *model, struct led_onoff_state *state = model->rt->user_data; printk("addr 0x%04x onoff 0x%02x\n", - bt_mesh_model_elem(model)->addr, state->current); + bt_mesh_model_elem(model)->rt->addr, state->current); bt_mesh_model_msg_init(&msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS); net_buf_simple_add_u8(&msg, state->current); @@ -229,7 +229,7 @@ static int gen_onoff_set_unack(const struct bt_mesh_model *model, state->last_msg_timestamp = now; printk("addr 0x%02x state 0x%02x\n", - bt_mesh_model_elem(model)->addr, state->current); + bt_mesh_model_elem(model)->rt->addr, state->current); if (set_led_state(state->dev_id, onoff)) { printk("Failed to set led state\n"); @@ -404,7 +404,7 @@ static int vnd_hello(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx * printk("Hello message from 0x%04x\n", ctx->addr); - if (ctx->addr == bt_mesh_model_elem(model)->addr) { + if (ctx->addr == bt_mesh_model_elem(model)->rt->addr) { printk("Ignoring message from self\n"); return 0; } @@ -431,7 +431,7 @@ static int vnd_baduser(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx printk("\"Bad user\" message from 0x%04x\n", ctx->addr); - if (ctx->addr == bt_mesh_model_elem(model)->addr) { + if (ctx->addr == bt_mesh_model_elem(model)->rt->addr) { printk("Ignoring message from self\n"); return 0; } @@ -455,7 +455,7 @@ static int vnd_heartbeat(const struct bt_mesh_model *model, uint8_t init_ttl, hops; /* Ignore messages from self */ - if (ctx->addr == bt_mesh_model_elem(model)->addr) { + if (ctx->addr == bt_mesh_model_elem(model)->rt->addr) { return 0; } @@ -495,7 +495,7 @@ static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, MOD_LF, vnd_ops, &vnd_pub, NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vnd_models), }; @@ -638,12 +638,12 @@ void mesh_start(void) bool mesh_is_initialized(void) { - return elements[0].addr != BT_MESH_ADDR_UNASSIGNED; + return elements[0].rt->addr != BT_MESH_ADDR_UNASSIGNED; } uint16_t mesh_get_addr(void) { - return elements[0].addr; + return elements[0].rt->addr; } int mesh_init(void) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 4b6a45ae5c8..dcf7f0f783b 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -115,7 +115,7 @@ static const struct { }; void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, + const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data), void *user_data) @@ -123,7 +123,7 @@ void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod, int i, j; for (i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + const struct bt_mesh_elem *elem = &dev_comp->elem[i]; for (j = 0; j < elem->model_count; j++) { const struct bt_mesh_model *model = &elem->models[j]; @@ -181,7 +181,7 @@ static void data_buf_add_mem_offset(struct net_buf_simple *buf, uint8_t *data, s *offset = 0; } -static void comp_add_model(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void comp_add_model(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, void *user_data) { struct comp_foreach_model_arg *arg = user_data; @@ -197,7 +197,7 @@ static void comp_add_model(const struct bt_mesh_model *mod, struct bt_mesh_elem #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) static size_t metadata_model_size(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, bool vnd) + const struct bt_mesh_elem *elem, bool vnd) { const struct bt_mesh_models_metadata_entry *entry; size_t size = 0; @@ -231,7 +231,7 @@ size_t bt_mesh_metadata_page_0_size(void) comp = bt_mesh_comp_get(); for (i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + const struct bt_mesh_elem *elem = &dev_comp->elem[i]; size += sizeof(elem->model_count) + sizeof(elem->vnd_model_count); @@ -253,7 +253,7 @@ size_t bt_mesh_metadata_page_0_size(void) } static int metadata_add_model(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, bool vnd, + const struct bt_mesh_elem *elem, bool vnd, void *user_data) { const struct bt_mesh_models_metadata_entry *entry; @@ -310,7 +310,7 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) comp = bt_mesh_comp_get(); for (i = 0; i < comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + const struct bt_mesh_elem *elem = &dev_comp->elem[i]; /* Check that the buffer has available tailroom for metadata item counts */ if (net_buf_simple_tailroom(buf) < (((offset == 0) ? 2 : (offset == 1) ? 1 : 0) @@ -360,7 +360,7 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) } #endif -static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, +static int comp_add_elem(struct net_buf_simple *buf, const struct bt_mesh_elem *elem, size_t *offset) { struct comp_foreach_model_arg arg = { @@ -382,7 +382,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, * the element shall not be reported. */ LOG_DBG("Element 0x%04x didn't fit in the Data field", - elem->addr); + elem->rt->addr); return 0; } @@ -577,7 +577,7 @@ static size_t mod_items_size(const struct bt_mesh_model *mod, uint8_t sig_offset return temp_size; } -static size_t page1_elem_size(struct bt_mesh_elem *elem) +static size_t page1_elem_size(const struct bt_mesh_elem *elem) { size_t temp_size = 2; @@ -618,7 +618,7 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse * the element shall not be reported. */ LOG_DBG("Element 0x%04x didn't fit in the Data field", - comp->elem[i].addr); + comp->elem[i].rt->addr); return 0; } @@ -821,7 +821,7 @@ static int publish_transmit(const struct bt_mesh_model *mod) struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_PUB(pub); struct bt_mesh_net_tx tx = { .ctx = &ctx, - .src = bt_mesh_model_elem(mod)->addr, + .src = bt_mesh_model_elem(mod)->rt->addr, .friend_cred = pub->cred, }; @@ -899,14 +899,14 @@ static void mod_publish(struct k_work *work) } } -struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod) +const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod) { return &dev_comp->elem[mod->rt->elem_idx]; } const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx) { - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; if (elem_idx >= dev_comp->elem_count) { LOG_ERR("Invalid element index %u", elem_idx); @@ -956,7 +956,7 @@ static int bt_mesh_vnd_mod_msg_cid_check(const struct bt_mesh_model *mod) } #endif -static void mod_init(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void mod_init(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { int i; @@ -1057,12 +1057,12 @@ void bt_mesh_comp_provision(uint16_t addr) LOG_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count); for (i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + const struct bt_mesh_elem *elem = &dev_comp->elem[i]; - elem->addr = addr++; + elem->rt->addr = addr++; - LOG_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", elem->addr, elem->model_count, - elem->vnd_model_count); + LOG_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", elem->rt->addr, + elem->model_count, elem->vnd_model_count); } } @@ -1073,9 +1073,9 @@ void bt_mesh_comp_unprovision(void) dev_primary_addr = BT_MESH_ADDR_UNASSIGNED; for (int i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + const struct bt_mesh_elem *elem = &dev_comp->elem[i]; - elem->addr = BT_MESH_ADDR_UNASSIGNED; + elem->rt->addr = BT_MESH_ADDR_UNASSIGNED; } } @@ -1197,7 +1197,7 @@ const uint8_t **bt_mesh_model_find_uuid(const struct bt_mesh_model **mod, const #endif } -static const struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, +static const struct bt_mesh_model *bt_mesh_elem_find_group(const struct bt_mesh_elem *elem, uint16_t group_addr) { const struct bt_mesh_model *model; @@ -1225,7 +1225,7 @@ static const struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem * return NULL; } -struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) +const struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) { uint16_t index; @@ -1233,7 +1233,7 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) return NULL; } - index = addr - dev_comp->elem[0].addr; + index = addr - dev_comp->elem[0].rt->addr; if (index >= dev_comp->elem_count) { return NULL; } @@ -1254,7 +1254,7 @@ bool bt_mesh_has_addr(uint16_t addr) } for (index = 0; index < dev_comp->elem_count; index++) { - struct bt_mesh_elem *elem = &dev_comp->elem[index]; + const struct bt_mesh_elem *elem = &dev_comp->elem[index]; if (bt_mesh_elem_find_group(elem, addr)) { return true; @@ -1315,7 +1315,7 @@ bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key) static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const uint8_t *uuid) { if (BT_MESH_ADDR_IS_UNICAST(dst)) { - return (dev_comp->elem[mod->rt->elem_idx].addr == dst); + return (dev_comp->elem[mod->rt->elem_idx].rt->addr == dst); } else if (BT_MESH_ADDR_IS_VIRTUAL(dst)) { return !!bt_mesh_model_find_uuid(&mod, uuid); } else if (BT_MESH_ADDR_IS_GROUP(dst) || @@ -1330,7 +1330,7 @@ static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const u return mod->rt->elem_idx == 0; } -static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem, +static const struct bt_mesh_model_op *find_op(const struct bt_mesh_elem *elem, uint32_t opcode, const struct bt_mesh_model **model) { uint8_t i; @@ -1415,7 +1415,7 @@ static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode) } static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, - struct bt_mesh_elem *elem, uint32_t opcode) + const struct bt_mesh_elem *elem, uint32_t opcode) { const struct bt_mesh_model_op *op; const struct bt_mesh_model *model; @@ -1424,7 +1424,7 @@ static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple op = find_op(elem, opcode, &model); if (!op) { - LOG_ERR("No OpCode 0x%08x for elem 0x%02x", opcode, elem->addr); + LOG_ERR("No OpCode 0x%08x for elem 0x%02x", opcode, elem->rt->addr); return ACCESS_STATUS_WRONG_OPCODE; } @@ -1479,19 +1479,19 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) LOG_DBG("OpCode 0x%08x", opcode); if (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) { - index = ctx->recv_dst - dev_comp->elem[0].addr; + index = ctx->recv_dst - dev_comp->elem[0].rt->addr; if (index >= dev_comp->elem_count) { LOG_ERR("Invalid address 0x%02x", ctx->recv_dst); err = ACCESS_STATUS_INVALID_ADDRESS; } else { - struct bt_mesh_elem *elem = &dev_comp->elem[index]; + const struct bt_mesh_elem *elem = &dev_comp->elem[index]; err = element_model_recv(ctx, buf, elem, opcode); } } else { for (index = 0; index < dev_comp->elem_count; index++) { - struct bt_mesh_elem *elem = &dev_comp->elem[index]; + const struct bt_mesh_elem *elem = &dev_comp->elem[index]; (void)element_model_recv(ctx, buf, elem, opcode); } @@ -1519,7 +1519,7 @@ int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx return -EINVAL; } - return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->addr, cb, cb_data); + return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->rt->addr, cb, cb_data); } int bt_mesh_model_publish(const struct bt_mesh_model *model) @@ -2171,7 +2171,7 @@ static void store_pending_mod_pub(const struct bt_mesh_model *mod, bool vnd) } static void store_pending_mod(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, bool vnd, + const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (!mod->rt->flags) { @@ -2553,7 +2553,7 @@ int bt_mesh_models_metadata_change_prepare(void) #endif } -static void commit_mod(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void commit_mod(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update && diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 663f99c84d2..b7ce1abd0ea 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -20,7 +20,7 @@ enum { BT_MESH_MOD_DATA_PENDING = BIT(5), }; -void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); +void bt_mesh_elem_register(const struct bt_mesh_elem *elem, uint8_t count); uint8_t bt_mesh_elem_count(void); size_t bt_mesh_comp_page_size(uint8_t page); @@ -29,7 +29,7 @@ size_t bt_mesh_metadata_page_0_size(void); int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); /* Find local element based on unicast address */ -struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); +const struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); bool bt_mesh_has_addr(uint16_t addr); bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key); @@ -43,7 +43,7 @@ uint16_t *bt_mesh_model_find_group(const struct bt_mesh_model **mod, uint16_t ad const uint8_t **bt_mesh_model_find_uuid(const struct bt_mesh_model **mod, const uint8_t *uuid); void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, + const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data), void *user_data); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 04374977421..fa6bb48703a 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -86,7 +86,7 @@ static int dev_comp_data_get(const struct bt_mesh_model *model, return err; } -static const struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, +static const struct bt_mesh_model *get_model(const struct bt_mesh_elem *elem, struct net_buf_simple *buf, bool *vnd) { if (buf->len < 4) { @@ -94,7 +94,7 @@ static const struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, id = net_buf_simple_pull_le16(buf); - LOG_DBG("ID 0x%04x addr 0x%04x", id, elem->addr); + LOG_DBG("ID 0x%04x addr 0x%04x", id, elem->rt->addr); *vnd = false; @@ -105,7 +105,7 @@ static const struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, company = net_buf_simple_pull_le16(buf); id = net_buf_simple_pull_le16(buf); - LOG_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, elem->addr); + LOG_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, elem->rt->addr); *vnd = true; @@ -336,7 +336,7 @@ static int app_key_update(const struct bt_mesh_model *model, } static void mod_app_key_del(const struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, bool vnd, bool primary, + const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { uint16_t *app_idx = user_data; @@ -696,7 +696,7 @@ static int mod_pub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx { uint16_t elem_addr, pub_addr = 0U; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -749,7 +749,7 @@ static int mod_pub_set(const struct bt_mesh_model *model, uint8_t retransmit, status, pub_ttl, pub_period, cred_flag; uint16_t elem_addr, pub_addr, pub_app_idx; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id; bool vnd; @@ -847,7 +847,7 @@ static int mod_pub_va_set(const struct bt_mesh_model *model, uint16_t elem_addr, pub_app_idx; uint16_t pub_addr = 0U; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; bool vnd; @@ -949,7 +949,7 @@ static int mod_sub_add(const struct bt_mesh_model *model, { uint16_t elem_addr, sub_addr; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id; uint8_t status; uint16_t *entry; @@ -1027,7 +1027,7 @@ static int mod_sub_del(const struct bt_mesh_model *model, { uint16_t elem_addr, sub_addr; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id; uint16_t *match; uint8_t status; @@ -1109,7 +1109,7 @@ static int mod_sub_overwrite(const struct bt_mesh_model *model, { uint16_t elem_addr, sub_addr; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id; uint8_t status; bool vnd; @@ -1179,7 +1179,7 @@ static int mod_sub_del_all(const struct bt_mesh_model *model, struct net_buf_simple *buf) { const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint16_t elem_addr; uint8_t *mod_id; uint8_t status; @@ -1269,7 +1269,7 @@ static int mod_sub_get(const struct bt_mesh_model *model, NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint16_t addr, id; addr = net_buf_simple_pull_le16(buf); @@ -1324,7 +1324,7 @@ static int mod_sub_get_vnd(const struct bt_mesh_model *model, NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint16_t company, addr, id; addr = net_buf_simple_pull_le16(buf); @@ -1383,7 +1383,7 @@ static int mod_sub_va_add(const struct bt_mesh_model *model, const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; uint16_t *group_entry; @@ -1485,7 +1485,7 @@ static int mod_sub_va_del(const struct bt_mesh_model *model, const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; const uint8_t **label_match; @@ -1569,7 +1569,7 @@ static int mod_sub_va_overwrite(const struct bt_mesh_model *model, const struct bt_mesh_va *va; uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; const uint8_t *uuid; uint8_t *mod_id; uint8_t status; @@ -1848,7 +1848,7 @@ static int mod_app_bind(const struct bt_mesh_model *model, BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -1912,7 +1912,7 @@ static int mod_app_unbind(const struct bt_mesh_model *model, BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; @@ -1974,7 +1974,7 @@ static int mod_app_get(const struct bt_mesh_model *model, BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, 9 + KEY_LIST_LEN))); const struct bt_mesh_model *mod; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; uint8_t *mod_id, status; uint16_t elem_addr; bool vnd; @@ -2529,7 +2529,7 @@ const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = { .init = cfg_srv_init, }; -static void mod_reset(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void mod_reset(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { size_t clear_count; diff --git a/subsys/bluetooth/mesh/health_srv.c b/subsys/bluetooth/mesh/health_srv.c index 5292967d469..8611e1004f6 100644 --- a/subsys/bluetooth/mesh/health_srv.c +++ b/subsys/bluetooth/mesh/health_srv.c @@ -384,7 +384,7 @@ static int health_pub_update(const struct bt_mesh_model *mod) return 0; } -int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem) +int bt_mesh_health_srv_fault_update(const struct bt_mesh_elem *elem) { const struct bt_mesh_model *mod; diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index 3aedf19af48..2c78ea227de 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -419,7 +419,7 @@ bool bt_mesh_is_provisioned(void) return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID); } -static void model_suspend(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_suspend(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update) { @@ -463,7 +463,7 @@ int bt_mesh_suspend(void) return 0; } -static void model_resume(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_resume(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->pub && mod->pub->update) { @@ -552,7 +552,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, return 0; } -static void model_start(const struct bt_mesh_model *mod, struct bt_mesh_elem *elem, +static void model_start(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { if (mod->cb && mod->cb->start) { diff --git a/subsys/bluetooth/mesh/op_agg_cli.c b/subsys/bluetooth/mesh/op_agg_cli.c index b74b8245cfd..1e44ba36f54 100644 --- a/subsys/bluetooth/mesh/op_agg_cli.c +++ b/subsys/bluetooth/mesh/op_agg_cli.c @@ -205,7 +205,7 @@ void bt_mesh_op_agg_cli_timeout_set(int32_t timeout) int bt_mesh_op_agg_cli_send(const struct bt_mesh_model *model, struct net_buf_simple *msg) { - uint16_t src = bt_mesh_model_elem(model)->addr; + uint16_t src = bt_mesh_model_elem(model)->rt->addr; if (net_buf_simple_tailroom(&srcs) < 2) { return -ENOMEM; diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index 3a28829877b..a169bb16422 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -1070,7 +1070,7 @@ static int cmd_rpl_clear(const struct shell *sh, size_t argc, char *argv[]) } #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE) -static struct bt_mesh_elem *primary_element(void) +static const struct bt_mesh_elem *primary_element(void) { const struct bt_mesh_comp *comp = bt_mesh_comp_get(); @@ -1085,7 +1085,7 @@ static int cmd_add_fault(const struct shell *sh, size_t argc, char *argv[]) { uint8_t fault_id; uint8_t i; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; int err = 0; elem = primary_element(); @@ -1138,7 +1138,7 @@ static int cmd_del_fault(const struct shell *sh, size_t argc, char *argv[]) { uint8_t fault_id; uint8_t i; - struct bt_mesh_elem *elem; + const struct bt_mesh_elem *elem; int err = 0; elem = primary_element(); diff --git a/subsys/bluetooth/mesh/shell/utils.c b/subsys/bluetooth/mesh/shell/utils.c index 1ccb0e25212..7ae09f943ca 100644 --- a/subsys/bluetooth/mesh/shell/utils.c +++ b/subsys/bluetooth/mesh/shell/utils.c @@ -60,7 +60,7 @@ int bt_mesh_shell_mdl_print_all(const struct shell *sh, uint16_t mod_id) if (mod) { shell_print(sh, "Client model instance found at addr 0x%.4X. Element index: %d", - comp->elem[i].addr, mod->rt->elem_idx); + comp->elem[i].rt->addr, mod->rt->elem_idx); } } diff --git a/tests/bluetooth/mesh/basic/src/main.c b/tests/bluetooth/mesh/basic/src/main.c index 34f94d486c3..d48a012bb2a 100644 --- a/tests/bluetooth/mesh/basic/src/main.c +++ b/tests/bluetooth/mesh/basic/src/main.c @@ -114,7 +114,7 @@ static const struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, 0x4321, vnd_ops, &vnd_pub2, NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vnd_models), }; diff --git a/tests/bluetooth/mesh_shell/src/main.c b/tests/bluetooth/mesh_shell/src/main.c index b562e428d11..f5dbdc41b40 100644 --- a/tests/bluetooth/mesh_shell/src/main.c +++ b/tests/bluetooth/mesh_shell/src/main.c @@ -107,7 +107,7 @@ static const struct bt_mesh_model root_models[] = { #endif }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE), }; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 36e627abe8c..96ce410eed8 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1096,7 +1096,7 @@ static const struct bt_mesh_model vnd_models[] = { NULL), }; -static struct bt_mesh_elem elements[] = { +static const struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vnd_models), }; @@ -1739,7 +1739,7 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, /* Lookup source address */ for (int i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (bt_mesh_model_elem(model_bound[i].model)->addr == src) { + if (bt_mesh_model_elem(model_bound[i].model)->rt->addr == src) { model = model_bound[i].model; ctx.app_idx = model_bound[i].appkey_idx; diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.c b/tests/bsim/bluetooth/mesh/src/mesh_test.c index ea209d9609c..5dce0c8dc9d 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.c +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.c @@ -204,7 +204,7 @@ static const struct bt_mesh_model vnd_models[] = { const struct bt_mesh_model *test_vnd_model = &vnd_models[0]; -static struct bt_mesh_elem elems[] = { +static const struct bt_mesh_elem elems[] = { BT_MESH_ELEM(0, models, vnd_models), }; diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index 14ee6b03428..b8b10fd7634 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -225,7 +225,7 @@ static const struct bt_mesh_model models_ne[] = { static const struct bt_mesh_model vnd_models[] = {}; -static struct bt_mesh_elem elems[] = { +static const struct bt_mesh_elem elems[] = { BT_MESH_ELEM(0, models, vnd_models), BT_MESH_ELEM(1, models_ne, vnd_models), }; diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index b80d777ba01..ef1ce8b9f74 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -79,7 +79,7 @@ static struct bt_mesh_priv_beacon_cli priv_beacon_cli; static const struct bt_mesh_comp prb_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index f9661fa0be0..4258ff77c62 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -233,7 +233,7 @@ static struct bt_mesh_sar_cfg_cli sar_cfg_cli; static const struct bt_mesh_comp srv_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -247,7 +247,7 @@ static const struct bt_mesh_comp srv_comp = { static const struct bt_mesh_comp cli_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -275,7 +275,7 @@ static const struct bt_mesh_model_op model_op1[] = { static const struct bt_mesh_comp none_rsp_srv_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -1328,7 +1328,7 @@ static const struct bt_mesh_model_op model_op2[] = { */ static const struct bt_mesh_comp srv_broken_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), diff --git a/tests/bsim/bluetooth/mesh/src/test_cdp1.c b/tests/bsim/bluetooth/mesh/src/test_cdp1.c index 03b71dce970..35befdea95b 100644 --- a/tests/bsim/bluetooth/mesh/src/test_cdp1.c +++ b/tests/bsim/bluetooth/mesh/src/test_cdp1.c @@ -81,7 +81,7 @@ static const struct bt_mesh_model models_vnd1[] = { &test_model_vnd1_cb), }; -static struct bt_mesh_elem elems[] = { +static const struct bt_mesh_elem elems[] = { BT_MESH_ELEM(0, models_1, models_vnd1), BT_MESH_ELEM(1, models_2, BT_MESH_MODEL_NONE), BT_MESH_ELEM(2, models_3, BT_MESH_MODEL_NONE), diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 83037ea6e73..06f7248a6ad 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -290,7 +290,7 @@ static struct bt_mesh_dfu_srv dfu_srv = BT_MESH_DFU_SRV_INIT(&dfu_handlers, dfu_ static const struct bt_mesh_comp dist_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -304,7 +304,7 @@ static const struct bt_mesh_comp dist_comp = { static const struct bt_mesh_comp dist_comp_self_update = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -325,7 +325,7 @@ static const struct bt_mesh_model_op model_dummy_op[] = { static const struct bt_mesh_comp target_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -941,7 +941,7 @@ static struct bt_mesh_dfu_cli dfu_cli = BT_MESH_DFU_CLI_INIT(&dfu_cli_cb); static const struct bt_mesh_comp cli_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -1326,7 +1326,7 @@ static const struct bt_mesh_model_op model_caps_op1[] = { static const struct bt_mesh_comp srv_caps_broken_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -1357,7 +1357,7 @@ static const struct bt_mesh_model_op model_caps_op2[] = { static const struct bt_mesh_comp broken_target_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -1389,7 +1389,7 @@ static const struct bt_mesh_model_op model_update_get_op1[] = { static const struct bt_mesh_comp srv_update_get_broken_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -1422,7 +1422,7 @@ static const struct bt_mesh_model_op model_update_apply_op1[] = { static const struct bt_mesh_comp srv_update_apply_broken_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index 337edaddc54..e1c7adde730 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -107,7 +107,7 @@ static struct bt_mesh_cfg_cli cfg_cli; static struct bt_mesh_large_comp_data_cli lcd_cli; /* Creates enough composition data to send a max SDU comp status message + 1 byte */ -static struct bt_mesh_elem elements_1[] = { +static const struct bt_mesh_elem elements_1[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -118,7 +118,7 @@ static struct bt_mesh_elem elements_1[] = { }; /* Creates enough metadata to send a max SDU metadata status message + 1 byte */ -static struct bt_mesh_elem elements_2[] = { +static const struct bt_mesh_elem elements_2[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), diff --git a/tests/bsim/bluetooth/mesh/src/test_op_agg.c b/tests/bsim/bluetooth/mesh/src/test_op_agg.c index 8735bdf524d..fe15219246f 100644 --- a/tests/bsim/bluetooth/mesh/src/test_op_agg.c +++ b/tests/bsim/bluetooth/mesh/src/test_op_agg.c @@ -119,7 +119,7 @@ const struct bt_mesh_model_op _dummy_vnd_mod_op[] = { BT_MESH_MODEL_OP_END, }; -static struct bt_mesh_elem elements[] = {BT_MESH_ELEM( +static const struct bt_mesh_elem elements[] = {BT_MESH_ELEM( 0, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_OP_AGG_SRV, BT_MESH_MODEL_OP_AGG_CLI), diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 63b8d89416c..f2c98778a3b 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -118,7 +118,7 @@ static struct bt_mesh_rpr_cli rpr_cli = { static const struct bt_mesh_comp rpr_cli_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}), @@ -130,7 +130,7 @@ static const struct bt_mesh_comp rpr_cli_comp = { static const struct bt_mesh_comp rpr_srv_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_RPR_SRV), @@ -141,7 +141,7 @@ static const struct bt_mesh_comp rpr_srv_comp = { static const struct bt_mesh_comp rpr_cli_srv_comp = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}), @@ -182,7 +182,7 @@ const struct bt_mesh_model_cb mock_model_cb = { static const struct bt_mesh_comp rpr_srv_comp_unresponsive = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CB(IMPOSTER_MODEL_ID, @@ -221,7 +221,7 @@ static const struct bt_mesh_comp2 comp_p2_2 = {.record_cnt = 2, .record = comp_r static const struct bt_mesh_comp rpr_srv_comp_2_elem = { .elem = - (struct bt_mesh_elem[]){ + (const struct bt_mesh_elem[]){ BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_RPR_SRV), diff --git a/tests/bsim/bluetooth/mesh/src/test_sar.c b/tests/bsim/bluetooth/mesh/src/test_sar.c index 7214366247d..61c7946235d 100644 --- a/tests/bsim/bluetooth/mesh/src/test_sar.c +++ b/tests/bsim/bluetooth/mesh/src/test_sar.c @@ -131,7 +131,7 @@ static const struct bt_mesh_model_op _dummy_vnd_mod_op[] = { uint16_t dummy_keys[CONFIG_BT_MESH_MODEL_KEY_COUNT] = { 0 }; -static struct bt_mesh_elem elements[] = {BT_MESH_ELEM( +static const struct bt_mesh_elem elements[] = {BT_MESH_ELEM( 0, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), From 7fcc3f0696edd251aaa927d533fb9d54839e6dea Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 17 Nov 2023 10:15:50 +0800 Subject: [PATCH 3867/4498] doc/migartion: Add migration guide for element The Bluetooth Mesh ``element`` declaration has been changed to add prefix ``const``. The ``elem->addr``field has been changed to the new runtime structure, replaced by ``elem->rt->addr``. Signed-off-by: Lingao Meng --- doc/releases/migration-guide-3.6.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index bff8df17703..5728d339984 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -117,6 +117,9 @@ Bluetooth The ``model->user_data``, ``model->elem_idx`` and ``model->mod_idx`` field has been changed to the new runtime structure, replaced by ``model->rt->user_data``, ``model->rt->elem_idx`` and ``model->rt->mod_idx`` separately. (:github:`65152`) +* The Bluetooth Mesh ``element`` declaration has been changed to add prefix ``const``. + The ``elem->addr`` field has been changed to the new runtime structure, replaced by + ``elem->rt->addr``. (:github:`65388`) LoRaWAN ======= From 1c280c5327697bacc4ad43bd37ce9025835e2b5a Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Fri, 17 Nov 2023 17:18:55 +0800 Subject: [PATCH 3868/4498] Bluetooth: Mesh: Add missing struct name Add name for inner-struct. Signed-off-by: Lingao Meng --- include/zephyr/bluetooth/mesh/access.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 7ae53a7d9ea..817fba918ef 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -30,13 +30,8 @@ #define BT_MESH_MODEL_UUIDS_UNASSIGNED() #endif -#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS -#define BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ - .rt = (void *)(void *[]){ NULL, NULL, (_user_data) }, -#else #define BT_MESH_MODEL_RUNTIME_INIT(_user_data) \ - .rt = (void *)(void *[]){ NULL, (_user_data) }, -#endif + .rt = &(struct bt_mesh_model_rt_ctx){ .user_data = (_user_data) }, /** * @brief Access layer @@ -890,7 +885,7 @@ struct bt_mesh_model { }; /* Model runtime information */ - struct { + struct bt_mesh_model_rt_ctx { uint8_t elem_idx; /* Belongs to Nth element */ uint8_t mod_idx; /* Is the Nth model in the element */ uint16_t flags; /* Model flags for internal bookkeeping */ From 8861bc0671ec3ba780f9c7cacbdaa329ddee5203 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Fri, 17 Nov 2023 09:13:49 +0100 Subject: [PATCH 3869/4498] modules: lvgl: Force fullsize render buffer on full refresh Changes the default of `LV_Z_VDB_SIZE` to 100 percent if `LV_Z_FULL_REFRESH` is set. Reason is that LVGL will reset the full refresh flag if the buffer is not equal to the screen size. Signed-off-by: Fabian Blatz --- modules/lvgl/Kconfig.memory | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lvgl/Kconfig.memory b/modules/lvgl/Kconfig.memory index efd74540466..fc59eccb2e3 100644 --- a/modules/lvgl/Kconfig.memory +++ b/modules/lvgl/Kconfig.memory @@ -40,6 +40,7 @@ config LV_Z_MEM_POOL_SIZE config LV_Z_VDB_SIZE int "Rendering buffer size" + default 100 if LV_Z_FULL_REFRESH default 10 range 1 100 help From 79c677c0ef37e81298ce9afe795989f5c21d9c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 10:30:06 +0100 Subject: [PATCH 3870/4498] net: lib: coap: Fix NULL pointer dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As reported by Coverity, cpkt was being used before checking it's not NULL. Fixes #65372 / CID: 323075 Signed-off-by: Benjamin Cabé --- subsys/net/lib/coap/coap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 3ecc077aa64..9fe62730b47 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -658,10 +658,10 @@ static int remove_middle_option(struct coap_packet *cpkt, } int coap_packet_remove_option(struct coap_packet *cpkt, uint16_t code) { - uint16_t offset = cpkt->hdr_len; + uint16_t offset = 0; uint16_t opt_delta = 0; uint16_t opt_len = 0; - uint16_t previous_offset = cpkt->hdr_len; + uint16_t previous_offset = 0; uint16_t previous_code = 0; struct coap_option option; int r; @@ -678,6 +678,9 @@ int coap_packet_remove_option(struct coap_packet *cpkt, uint16_t code) return 0; } + offset = cpkt->hdr_len; + previous_offset = cpkt->hdr_len; + /* Find the requested option */ while (offset < cpkt->hdr_len + cpkt->opt_len) { r = parse_option(cpkt->data, offset, &offset, cpkt->hdr_len + cpkt->opt_len, From e702ecc8fb18adc0507ac7f9315ab32054a04751 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 10:10:48 +0100 Subject: [PATCH 3871/4498] net: dhcpv6: Verify net_pkt_skip() return value Verify the return value of net_pkt_skip() function, in case the parser ignores the unrecognized options, so that in case the option was malformed and the actual provided option length exceeds the packet length, it is recognize (net_pkt_skip() should fail then). Signed-off-by: Robert Lubos --- subsys/net/ip/dhcpv6.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index 3d464c92954..5e596a95e5b 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -892,8 +892,13 @@ static int dhcpv6_parse_option_iaaddr(struct net_pkt *pkt, uint16_t length, break; default: - net_pkt_skip(pkt, sublen); NET_DBG("Unexpected option %d length %d", code, sublen); + + ret = net_pkt_skip(pkt, sublen); + if (ret < 0) { + return ret; + } + break; } @@ -980,8 +985,13 @@ static int dhcpv6_parse_option_ia_na(struct net_pkt *pkt, uint16_t length, break; default: - net_pkt_skip(pkt, sublen); NET_DBG("Unexpected option %d length %d", code, sublen); + + ret = net_pkt_skip(pkt, sublen); + if (ret < 0) { + return ret; + } + break; } @@ -1058,8 +1068,13 @@ static int dhcpv6_parse_option_iaprefix(struct net_pkt *pkt, uint16_t length, break; default: - net_pkt_skip(pkt, sublen); NET_DBG("Unexpected option %d length %d", code, sublen); + + ret = net_pkt_skip(pkt, sublen); + if (ret < 0) { + return ret; + } + break; } @@ -1145,8 +1160,13 @@ static int dhcpv6_parse_option_ia_pd(struct net_pkt *pkt, uint16_t length, break; default: - net_pkt_skip(pkt, sublen); NET_DBG("Unexpected option %d length %d", code, sublen); + + ret = net_pkt_skip(pkt, sublen); + if (ret < 0) { + return ret; + } + break; } @@ -1161,6 +1181,7 @@ static int dhcpv6_find_option(struct net_pkt *pkt, enum dhcpv6_option_code opt_c { uint16_t length; uint16_t code; + int ret; while (net_pkt_read_be16(pkt, &code) == 0) { if (net_pkt_read_be16(pkt, &length) < 0) { @@ -1172,7 +1193,10 @@ static int dhcpv6_find_option(struct net_pkt *pkt, enum dhcpv6_option_code opt_c return 0; } - net_pkt_skip(pkt, length); + ret = net_pkt_skip(pkt, length); + if (ret < 0) { + return ret; + } } return -ENOENT; From f3b85ad92c69d87a7b87ee2c214aab447f33d3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 10:59:21 +0100 Subject: [PATCH 3872/4498] drivers: modem: fix for possible non-null terminated string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix handling of strncpy in cgnsinf parsing function to avoid potentially getting a non-null terminated string. Fixes #58573 / CID: 248403 Signed-off-by: Benjamin Cabé --- drivers/modem/simcom-sim7080.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/modem/simcom-sim7080.c b/drivers/modem/simcom-sim7080.c index b6a159e519d..f0b31a1d1b6 100644 --- a/drivers/modem/simcom-sim7080.c +++ b/drivers/modem/simcom-sim7080.c @@ -1466,7 +1466,7 @@ static int parse_cgnsinf(char *gps_buf) gnss_data.run_status = 1; gnss_data.fix_status = 1; - strncpy(gnss_data.utc, utc, sizeof(gnss_data.utc)); + strncpy(gnss_data.utc, utc, sizeof(gnss_data.utc) - 1); ret = gnss_split_on_dot(lat, &number, &fraction); if (ret != 0) { From 6a5d082cc5aaeb486ddfd89c36736e6624cd7949 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 17 Nov 2023 09:33:16 +0100 Subject: [PATCH 3873/4498] Bluetooth: Mesh: Ignore return value of settings_delete This suppresses warning from Coverity. Coverity-CID: 330638 Fixes #65330 Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/dfu_slot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/mesh/dfu_slot.c b/subsys/bluetooth/mesh/dfu_slot.c index 097d5abcc82..c11c16d44fc 100644 --- a/subsys/bluetooth/mesh/dfu_slot.c +++ b/subsys/bluetooth/mesh/dfu_slot.c @@ -95,9 +95,9 @@ static void slot_erase(struct slot *slot_to_erase) uint16_t idx = ARRAY_INDEX(slots, slot_to_erase); char buf[SLOT_ENTRY_BUFLEN]; - settings_delete(slot_entry_encode(idx, buf, PROP_HEADER)); - settings_delete(slot_entry_encode(idx, buf, PROP_FWID)); - settings_delete(slot_entry_encode(idx, buf, PROP_METADATA)); + (void)settings_delete(slot_entry_encode(idx, buf, PROP_HEADER)); + (void)settings_delete(slot_entry_encode(idx, buf, PROP_FWID)); + (void)settings_delete(slot_entry_encode(idx, buf, PROP_METADATA)); } static void slot_index_defrag(void) From b15611eb28cf4e187453cdd5eaf911d4abbf65df Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 17 Nov 2023 09:40:25 +0100 Subject: [PATCH 3874/4498] Bluetooth: Mesh: Check return value of bt_conn_get_info Coverity-CID: 323094 Fixes #65366 Coverity-CID: 323081 Fixes #65370 Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/gatt_cli.c | 9 +++++---- subsys/bluetooth/mesh/pb_gatt_srv.c | 14 ++++++++------ subsys/bluetooth/mesh/proxy_srv.c | 14 ++++++++------ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/subsys/bluetooth/mesh/gatt_cli.c b/subsys/bluetooth/mesh/gatt_cli.c index 59407458de2..bff9b567011 100644 --- a/subsys/bluetooth/mesh/gatt_cli.c +++ b/subsys/bluetooth/mesh/gatt_cli.c @@ -176,8 +176,8 @@ static void gatt_connected(struct bt_conn *conn, uint8_t conn_err) struct bt_conn_info info; int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_CENTRAL || + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_CENTRAL || !server->gatt) { return; } @@ -214,9 +214,10 @@ static void gatt_disconnected(struct bt_conn *conn, uint8_t reason) { struct bt_conn_info info; struct bt_mesh_gatt_server *server = get_server(conn); + int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_CENTRAL || + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_CENTRAL || !server->gatt) { return; } diff --git a/subsys/bluetooth/mesh/pb_gatt_srv.c b/subsys/bluetooth/mesh/pb_gatt_srv.c index d5ad2f9711d..f6d9298fc78 100644 --- a/subsys/bluetooth/mesh/pb_gatt_srv.c +++ b/subsys/bluetooth/mesh/pb_gatt_srv.c @@ -94,27 +94,29 @@ static ssize_t gatt_recv(struct bt_conn *conn, return bt_mesh_proxy_msg_recv(conn, buf, len); } -static void gatt_connected(struct bt_conn *conn, uint8_t err) +static void gatt_connected(struct bt_conn *conn, uint8_t conn_err) { struct bt_conn_info info; + int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || bt_mesh_is_provisioned() || info.id != BT_ID_DEFAULT || cli) { return; } cli = bt_mesh_proxy_role_setup(conn, gatt_send, proxy_msg_recv); - LOG_DBG("conn %p err 0x%02x", (void *)conn, err); + LOG_DBG("conn %p err 0x%02x", (void *)conn, conn_err); } static void gatt_disconnected(struct bt_conn *conn, uint8_t reason) { struct bt_conn_info info; + int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || info.id != BT_ID_DEFAULT || !cli || cli->conn != conn) { return; } diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 2943afdca93..3a2bad0851e 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -1057,18 +1057,19 @@ static void solicitation_reset(struct bt_mesh_subnet *sub) #endif } -static void gatt_connected(struct bt_conn *conn, uint8_t err) +static void gatt_connected(struct bt_conn *conn, uint8_t conn_err) { struct bt_mesh_proxy_client *client; struct bt_conn_info info; + int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered || info.id != BT_ID_DEFAULT) { return; } - LOG_DBG("conn %p err 0x%02x", (void *)conn, err); + LOG_DBG("conn %p err 0x%02x", (void *)conn, conn_err); client = find_client(conn); @@ -1107,9 +1108,10 @@ static void gatt_disconnected(struct bt_conn *conn, uint8_t reason) { struct bt_conn_info info; struct bt_mesh_proxy_client *client; + int err; - bt_conn_get_info(conn, &info); - if (info.role != BT_CONN_ROLE_PERIPHERAL || info.id != BT_ID_DEFAULT) { + err = bt_conn_get_info(conn, &info); + if (err || info.role != BT_CONN_ROLE_PERIPHERAL || info.id != BT_ID_DEFAULT) { return; } From 3bc17d1d18d778ee90ebd98a8001c5384502bb28 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 17 Nov 2023 10:27:22 +0100 Subject: [PATCH 3875/4498] Bluetooth: Mesh: Fix async behavior of Private Beacon Client API The Private Beacon Client API requires a response argument to allow to call the API in the asynchronous manner (https://github.com/zephyrproject-rtos/zephyr/pull/56426). Because the removal of the EXPERIMENTAL tag for this API was not released yet, it should be OK to change this API. The EXPERIMENTAL tag has been removed here: https://github.com/zephyrproject-rtos/zephyr/pull/64866 Coverity-CID: 330039 Coverity-CID: 330029 Coverity-CID: 329977 Fixes #65336 Fixes #65338 Fixes #65354 Signed-off-by: Pavel Vasilyev --- .../zephyr/bluetooth/mesh/priv_beacon_cli.h | 31 ++++++++++++++----- subsys/bluetooth/mesh/priv_beacon_cli.c | 29 +++++++++-------- subsys/bluetooth/mesh/shell/priv_beacon.c | 6 ++-- tests/bluetooth/tester/src/btp_mesh.c | 6 ++-- tests/bsim/bluetooth/mesh/src/test_beacon.c | 14 ++++----- .../bluetooth/mesh/src/test_persistence.c | 6 ++-- 6 files changed, 56 insertions(+), 36 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/priv_beacon_cli.h b/include/zephyr/bluetooth/mesh/priv_beacon_cli.h index 24fba6f67be..ac77b45839f 100644 --- a/include/zephyr/bluetooth/mesh/priv_beacon_cli.h +++ b/include/zephyr/bluetooth/mesh/priv_beacon_cli.h @@ -101,14 +101,20 @@ struct bt_mesh_priv_beacon_cli { /** @brief Set the target's Private Beacon state. * + * This method can be used asynchronously by setting @p rsp as NULL. + * This way the method will not wait for response and will return + * immediately after sending the command. + * @param net_idx Network index to encrypt with. * @param addr Target node address. - * @param val New Private Beacon value. Returns response status on success. + * @param val New Private Beacon value. + * @param rsp If set, returns response status on success. * * @return 0 on success, or (negative) error code otherwise. */ int bt_mesh_priv_beacon_cli_set(uint16_t net_idx, uint16_t addr, - struct bt_mesh_priv_beacon *val); + struct bt_mesh_priv_beacon *val, + struct bt_mesh_priv_beacon *rsp); /** @brief Get the target's Private Beacon state. * @@ -122,16 +128,20 @@ int bt_mesh_priv_beacon_cli_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_priv_beacon *val); /** @brief Set the target's Private GATT Proxy state. + * + * This method can be used asynchronously by setting @p rsp as NULL. + * This way the method will not wait for response and will return + * immediately after sending the command. * * @param net_idx Network index to encrypt with. * @param addr Target node address. - * @param val New Private GATT Proxy value. Returns response status on - * success. + * @param val New Private GATT Proxy value. + * @param rsp If set, returns response status on success. * * @return 0 on success, or (negative) error code otherwise. */ int bt_mesh_priv_beacon_cli_gatt_proxy_set(uint16_t net_idx, uint16_t addr, - uint8_t *val); + uint8_t val, uint8_t *rsp); /** @brief Get the target's Private GATT Proxy state. * @@ -145,16 +155,21 @@ int bt_mesh_priv_beacon_cli_gatt_proxy_get(uint16_t net_idx, uint16_t addr, uint8_t *val); /** @brief Set the target's Private Node Identity state. + * + * This method can be used asynchronously by setting @p rsp as NULL. + * This way the method will not wait for response and will return + * immediately after sending the command. * * @param net_idx Network index to encrypt with. * @param addr Target node address. - * @param val New Private Node Identity value. Returns response status on - * success. + * @param val New Private Node Identity value. + * @param rsp If set, returns response status on success. * * @return 0 on success, or (negative) error code otherwise. */ int bt_mesh_priv_beacon_cli_node_id_set(uint16_t net_idx, uint16_t addr, - struct bt_mesh_priv_node_id *val); + struct bt_mesh_priv_node_id *val, + struct bt_mesh_priv_node_id *rsp); /** @brief Get the target's Private Node Identity state. * diff --git a/subsys/bluetooth/mesh/priv_beacon_cli.c b/subsys/bluetooth/mesh/priv_beacon_cli.c index 0611aeb7705..7d679f0e322 100644 --- a/subsys/bluetooth/mesh/priv_beacon_cli.c +++ b/subsys/bluetooth/mesh/priv_beacon_cli.c @@ -156,13 +156,14 @@ const struct bt_mesh_model_cb bt_mesh_priv_beacon_cli_cb = { .init = priv_beacon_cli_init, }; -int bt_mesh_priv_beacon_cli_set(uint16_t net_idx, uint16_t addr, struct bt_mesh_priv_beacon *val) +int bt_mesh_priv_beacon_cli_set(uint16_t net_idx, uint16_t addr, struct bt_mesh_priv_beacon *val, + struct bt_mesh_priv_beacon *rsp) { struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp_ctx = { .ack = &cli->ack_ctx, .op = OP_PRIV_BEACON_STATUS, - .user_data = val, + .user_data = rsp, .timeout = msg_timeout, }; @@ -174,7 +175,7 @@ int bt_mesh_priv_beacon_cli_set(uint16_t net_idx, uint16_t addr, struct bt_mesh_ net_buf_simple_add_u8(&buf, val->rand_interval); } - return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, val ? &rsp_ctx : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, rsp ? &rsp_ctx : NULL); } int bt_mesh_priv_beacon_cli_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_priv_beacon *val) @@ -193,27 +194,28 @@ int bt_mesh_priv_beacon_cli_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_ return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, val ? &rsp_ctx : NULL); } -int bt_mesh_priv_beacon_cli_gatt_proxy_set(uint16_t net_idx, uint16_t addr, uint8_t *val) +int bt_mesh_priv_beacon_cli_gatt_proxy_set(uint16_t net_idx, uint16_t addr, uint8_t val, + uint8_t *rsp) { struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp_ctx = { .ack = &cli->ack_ctx, .op = OP_PRIV_GATT_PROXY_STATUS, - .user_data = val, + .user_data = rsp, .timeout = msg_timeout, }; - if (!val || (*val != BT_MESH_GATT_PROXY_DISABLED && - *val != BT_MESH_GATT_PROXY_ENABLED)) { + if ((val != BT_MESH_GATT_PROXY_DISABLED && + val != BT_MESH_GATT_PROXY_ENABLED)) { return -EINVAL; } BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_GATT_PROXY_SET, 1); bt_mesh_model_msg_init(&buf, OP_PRIV_GATT_PROXY_SET); - net_buf_simple_add_u8(&buf, *val); + net_buf_simple_add_u8(&buf, val); - return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, val ? &rsp_ctx : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, rsp ? &rsp_ctx : NULL); } int bt_mesh_priv_beacon_cli_gatt_proxy_get(uint16_t net_idx, uint16_t addr, uint8_t *val) @@ -233,17 +235,18 @@ int bt_mesh_priv_beacon_cli_gatt_proxy_get(uint16_t net_idx, uint16_t addr, uint } int bt_mesh_priv_beacon_cli_node_id_set(uint16_t net_idx, uint16_t addr, - struct bt_mesh_priv_node_id *val) + struct bt_mesh_priv_node_id *val, + struct bt_mesh_priv_node_id *rsp) { struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp_ctx = { .ack = &cli->ack_ctx, .op = OP_PRIV_NODE_ID_STATUS, - .user_data = val, + .user_data = rsp, .timeout = msg_timeout, }; - if (!val || val->net_idx > 0xfff || + if (val->net_idx > 0xfff || (val->state != BT_MESH_NODE_IDENTITY_STOPPED && val->state != BT_MESH_NODE_IDENTITY_RUNNING)) { return -EINVAL; @@ -255,7 +258,7 @@ int bt_mesh_priv_beacon_cli_node_id_set(uint16_t net_idx, uint16_t addr, net_buf_simple_add_le16(&buf, val->net_idx); net_buf_simple_add_u8(&buf, val->state); - return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, val ? &rsp_ctx : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &buf, rsp ? &rsp_ctx : NULL); } int bt_mesh_priv_beacon_cli_node_id_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, diff --git a/subsys/bluetooth/mesh/shell/priv_beacon.c b/subsys/bluetooth/mesh/shell/priv_beacon.c index 296d96b114e..71b0da91e50 100644 --- a/subsys/bluetooth/mesh/shell/priv_beacon.c +++ b/subsys/bluetooth/mesh/shell/priv_beacon.c @@ -48,7 +48,7 @@ static int cmd_priv_beacon_set(const struct shell *sh, size_t argc, char *argv[] err = bt_mesh_priv_beacon_cli_set(bt_mesh_shell_target_ctx.net_idx, bt_mesh_shell_target_ctx.dst, - &val); + &val, &val); if (err) { shell_error(sh, "Failed to send Private Beacon Set (err %d)", err); return 0; @@ -86,7 +86,7 @@ static int cmd_priv_gatt_proxy_set(const struct shell *sh, size_t argc, char *ar } err = bt_mesh_priv_beacon_cli_gatt_proxy_set(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, &state); + bt_mesh_shell_target_ctx.dst, state, &state); if (err) { shell_error(sh, "Failed to send Private GATT Proxy Set (err %d)", err); return 0; @@ -130,7 +130,7 @@ static int cmd_priv_node_id_set(const struct shell *sh, size_t argc, char *argv[ } err = bt_mesh_priv_beacon_cli_node_id_set(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, &val); + bt_mesh_shell_target_ctx.dst, &val, &val); if (err) { shell_error(sh, "Failed to send Private Node Identity Set (err %d)", err); return 0; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 96ce410eed8..ab5fcf515bd 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -820,7 +820,7 @@ static uint8_t priv_beacon_set(const void *cmd, uint16_t cmd_len, val.enabled = cp->enabled; val.rand_interval = cp->rand_interval; - err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val); + err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val, &val); if (err) { LOG_ERR("Failed to send Private Beacon Set (err %d)", err); return BTP_STATUS_FAILED; @@ -857,7 +857,7 @@ static uint8_t priv_gatt_proxy_set(const void *cmd, uint16_t cmd_len, state = cp->state; - err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, &state); + err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, state, &state); if (err) { LOG_ERR("Failed to send Private GATT Proxy Set (err %d)", err); return BTP_STATUS_FAILED; @@ -896,7 +896,7 @@ static uint8_t priv_node_id_set(const void *cmd, uint16_t cmd_len, val.net_idx = cp->net_idx; val.state = cp->state; - err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val); + err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val, &val); if (err) { LOG_ERR("Failed to send Private Node Identity Set (err %d)", err); return BTP_STATUS_FAILED; diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index ef1ce8b9f74..e93c2301e46 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -1131,7 +1131,7 @@ static void tx_priv_setup(void) FAIL("Beacon set failed (err %d, status %u)", err, status); } - err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1169,7 +1169,7 @@ static void test_tx_priv_adv(void) val.enabled = 1; val.rand_interval = 1; - err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1178,7 +1178,7 @@ static void test_tx_priv_adv(void) val.rand_interval = 0; - err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1187,7 +1187,7 @@ static void test_tx_priv_adv(void) val.rand_interval = 0; - err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1196,7 +1196,7 @@ static void test_tx_priv_adv(void) val.rand_interval = 3; - err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, tx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1328,7 +1328,7 @@ static void test_rx_priv_invalid(void) FAIL("Beacon set failed (err %d, status %u)", err, status); } - err = bt_mesh_priv_beacon_cli_set(0, rx_cfg.addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, rx_cfg.addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } @@ -1361,7 +1361,7 @@ static void toggle_priv_beacon(uint16_t addr, uint8_t enabled) val.enabled = enabled; val.rand_interval = 1; - err = bt_mesh_priv_beacon_cli_set(0, addr, &val); + err = bt_mesh_priv_beacon_cli_set(0, addr, &val, &val); if (err) { FAIL("Failed to enable Private Beacon (err=%d)", err); } diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index df3eaa19989..4bf1f9faa93 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -953,14 +953,16 @@ static void test_cfg_save(void) .rand_interval = current_stack_cfg->priv_beacon_int, }; - err = bt_mesh_priv_beacon_cli_set(test_netkey_idx, TEST_ADDR, &priv_beacon_state); + err = bt_mesh_priv_beacon_cli_set(test_netkey_idx, TEST_ADDR, &priv_beacon_state, + &priv_beacon_state); if (err) { FAIL("Failed to enable Private Beacon (err %d)", err); } uint8_t priv_beacon_gatt = current_stack_cfg->priv_beacon_gatt; - err = bt_mesh_priv_beacon_cli_gatt_proxy_set(test_netkey_idx, TEST_ADDR, &priv_beacon_gatt); + err = bt_mesh_priv_beacon_cli_gatt_proxy_set(test_netkey_idx, TEST_ADDR, priv_beacon_gatt, + &priv_beacon_gatt); if (err) { FAIL("Failed to enable Private Beacon GATT proxy (err %d)", err); } From 07848a4456b035b08a41218dcb98f3f7db359a2e Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Fri, 17 Nov 2023 11:14:48 +0100 Subject: [PATCH 3876/4498] Bluetooth: Mesh: Fix integer overflow Fix potential integer overflow by casting one of operands to int64_t. Coverity-CID: 329961 Fixes #65356 Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/proxy_srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 3a2bad0851e..571144ceaed 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -697,7 +697,8 @@ static void gatt_proxy_solicited(struct bt_mesh_subnet *sub) int32_t remaining; if (sub->priv_net_id_sent > 0) { - timeout = sub->priv_net_id_sent + MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); + timeout = sub->priv_net_id_sent + + MSEC_PER_SEC * (int64_t) bt_mesh_od_priv_proxy_get(); remaining = MIN(timeout - now, INT32_MAX); } else { remaining = MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); From 4f1823c61636a69964b6d0c3305e9874ee52264a Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Fri, 17 Nov 2023 09:59:55 +0100 Subject: [PATCH 3877/4498] soc: arm: nordic_nrf: Add Kconfig symbol for new I2S instance Add I2S 20 instance Signed-off-by: Adam Wojasinski --- soc/arm/nordic_nrf/Kconfig.peripherals | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index 285b92d3dda..3aacc35a08a 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -75,6 +75,9 @@ config HAS_HW_NRF_GPIOTE config HAS_HW_NRF_I2S0 def_bool $(dt_nodelabel_enabled_with_compat,i2s0,$(DT_COMPAT_NORDIC_NRF_I2S)) +config HAS_HW_NRF_I2S20 + def_bool $(dt_nodelabel_enabled_with_compat,i2s20,$(DT_COMPAT_NORDIC_NRF_I2S)) + config HAS_HW_NRF_IPC def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_IPC)) From cac170d2b9c49943347b8288175bd5784b2b5bd7 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Fri, 17 Nov 2023 10:16:23 +0100 Subject: [PATCH 3878/4498] modules: hal_nordic: Add I2S Kconfig symbols and translation to nrfx Add Kconfig symbols for I2S 20 instance and translation symbols used in nrfx drivers. Signed-off-by: Adam Wojasinski --- modules/hal_nordic/nrfx/Kconfig | 5 +++++ modules/hal_nordic/nrfx/nrfx_config.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 53a77e60175..5dcda73c9be 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -82,6 +82,11 @@ config NRFX_I2S0 depends on $(dt_nodelabel_has_compat,i2s0,$(DT_COMPAT_NORDIC_NRF_I2S)) select NRFX_I2S +config NRFX_I2S20 + bool "I2S20 driver instance" + depends on $(dt_nodelabel_has_compat,i2s20,$(DT_COMPAT_NORDIC_NRF_I2S)) + select NRFX_I2S + config NRFX_IPC bool "IPC driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_IPC)) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index f799c4207d5..aaf31751004 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -141,6 +141,9 @@ #ifdef CONFIG_NRFX_I2S0 #define NRFX_I2S0_ENABLED 1 #endif +#ifdef CONFIG_NRFX_I2S20 +#define NRFX_I2S20_ENABLED 1 +#endif #ifdef CONFIG_NRFX_IPC #define NRFX_IPC_ENABLED 1 From dd36592aa47208903123c92808fd9078c11e25f2 Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Thu, 24 Aug 2023 15:50:55 +0200 Subject: [PATCH 3879/4498] drivers: i2s: i2s_nrfx: Add support for new instance Add support for new I2S 20 instance. Signed-off-by: Adam Kondraciuk --- drivers/i2s/Kconfig.nrfx | 1 + drivers/i2s/i2s_nrfx.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/i2s/Kconfig.nrfx b/drivers/i2s/Kconfig.nrfx index 1cb023a2b2e..b36f3eb9c64 100644 --- a/drivers/i2s/Kconfig.nrfx +++ b/drivers/i2s/Kconfig.nrfx @@ -6,6 +6,7 @@ menuconfig I2S_NRFX default y depends on DT_HAS_NORDIC_NRF_I2S_ENABLED select NRFX_I2S0 if HAS_HW_NRF_I2S0 + select NRFX_I2S20 if HAS_HW_NRF_I2S20 select PINCTRL help Enable support for nrfx I2S driver for nRF MCU series. diff --git a/drivers/i2s/i2s_nrfx.c b/drivers/i2s/i2s_nrfx.c index 57910c464ab..e1b3684c4f7 100644 --- a/drivers/i2s/i2s_nrfx.c +++ b/drivers/i2s/i2s_nrfx.c @@ -955,5 +955,10 @@ static const struct i2s_driver_api i2s_nrf_drv_api = { POST_KERNEL, CONFIG_I2S_INIT_PRIORITY, \ &i2s_nrf_drv_api); -/* Existing SoCs only have one I2S instance. */ +#ifdef CONFIG_HAS_HW_NRF_I2S0 I2S_NRFX_DEVICE(0); +#endif + +#ifdef CONFIG_HAS_HW_NRF_I2S20 +I2S_NRFX_DEVICE(20); +#endif From ec50e5393c98156729870167cb18645b13845d9f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 11:48:01 +0100 Subject: [PATCH 3880/4498] net: lwm2m: shell: Add error check for string to float conversion The result of string to float conversion in LwM2M shell write command was not verified, which could result in incorrect data being written to the resource. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_shell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index a4807d517f2..a4cedf8cd62 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -328,8 +328,10 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) } else if (strcmp(dtype, "-f") == 0) { double new = 0; - lwm2m_atof(value, &new); /* Convert string -> float */ - ret = lwm2m_set_f64(&path, new); + ret = lwm2m_atof(value, &new); /* Convert string -> float */ + if (ret == 0) { + ret = lwm2m_set_f64(&path, new); + } } else { /* All the types using stdlib funcs*/ char *e; From 7f7d019b25b0d663142f44cc335e66d36095692c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 12:02:13 +0100 Subject: [PATCH 3881/4498] net: lwm2m: Add error checks for option encoding in BS registration Add missing error checks when encoding CoAP options for Bootstrap Register message Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index ca539fcded6..d9f2e229edd 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -770,16 +770,20 @@ static int sm_send_bootstrap_registration(void) goto cleanup; } - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH, - "bs", strlen("bs")); + ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH, + "bs", strlen("bs")); + if (ret < 0) { + goto cleanup; + } snprintk(query_buffer, sizeof(query_buffer) - 1, "ep=%s", client.ep_name); - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, - query_buffer, strlen(query_buffer)); + ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, + query_buffer, strlen(query_buffer)); + if (ret < 0) { + goto cleanup; + } if (IS_ENABLED(CONFIG_LWM2M_VERSION_1_1)) { int pct = LWM2M_FORMAT_OMA_TLV; From a3362d969dfc62f52b91afa50bf06a1a54e0a1a6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 12:05:27 +0100 Subject: [PATCH 3882/4498] net: lwm2m: Explicitly initialize path_list_size variable To get rid of compiler warning about potential use of uninitialized variable. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_observation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 7933ebd8fd3..9ee1fa6eda1 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -529,7 +529,7 @@ struct observe_node *engine_observe_node_discover(sys_slist_t *observe_node_list const uint8_t *token, uint8_t tkl) { struct observe_node *obs; - int obs_list_size, path_list_size; + int obs_list_size, path_list_size = 0; if (lwm2m_path_list) { path_list_size = engine_path_list_size(lwm2m_path_list); From 69e6b3a56371bf7a9f1cae679e84d5b9faf49ee6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 12:40:46 +0100 Subject: [PATCH 3883/4498] net: tftp: Log transmit error There's not really much to do when the transmission of the error reply fails, but we can at least log the failure. Signed-off-by: Robert Lubos --- subsys/net/lib/tftp/tftp_client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/tftp/tftp_client.c b/subsys/net/lib/tftp/tftp_client.c index fc3cd2b70d9..12f3d9e0346 100644 --- a/subsys/net/lib/tftp/tftp_client.c +++ b/subsys/net/lib/tftp/tftp_client.c @@ -293,7 +293,10 @@ int tftp_get(struct tftpc *client, const char *remote_file, const char *mode) if (client->callback == NULL) { LOG_ERR("No callback defined."); - send_err(sock, client, TFTP_ERROR_DISK_FULL, NULL); + if (send_err(sock, client, TFTP_ERROR_DISK_FULL, NULL) < 0) { + LOG_ERR("Failed to send error response, err: %d", + -errno); + } ret = TFTPC_BUFFER_OVERFLOW; goto get_end; } From 59544d58efdcb31e3318cc28d3b0621562f0af2e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 12:44:52 +0100 Subject: [PATCH 3884/4498] net: tftp: Verify connect return value Verify that connect() succeeded before reporting success. Signed-off-by: Robert Lubos --- subsys/net/lib/tftp/tftp_client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/tftp/tftp_client.c b/subsys/net/lib/tftp/tftp_client.c index 12f3d9e0346..776135866a3 100644 --- a/subsys/net/lib/tftp/tftp_client.c +++ b/subsys/net/lib/tftp/tftp_client.c @@ -222,7 +222,11 @@ static int send_request(int sock, struct tftpc *client, } /* Limit communication to the specific address:port */ - connect(sock, &from_addr, from_addr_len); + if (connect(sock, &from_addr, from_addr_len) < 0) { + ret = -errno; + LOG_ERR("connect failed, err %d", ret); + break; + } break; From f0247131bffbaf0417fa35a1d1a0a6f720f8272e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 12:53:38 +0100 Subject: [PATCH 3885/4498] net: tftp: Ensure the error message fits into transmit buffer Make sure that the error message does not overflow the transmit buffer when copying the error message string. Signed-off-by: Robert Lubos --- subsys/net/lib/tftp/tftp_client.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/tftp/tftp_client.c b/subsys/net/lib/tftp/tftp_client.c index 776135866a3..c6f9a371d6b 100644 --- a/subsys/net/lib/tftp/tftp_client.c +++ b/subsys/net/lib/tftp/tftp_client.c @@ -155,8 +155,14 @@ static inline int send_err(int sock, struct tftpc *client, int err_code, char *e /* Copy the Error String. */ if (err_msg != NULL) { - strcpy(client->tftp_buf + req_size, err_msg); - req_size += strlen(err_msg); + size_t copy_len = strlen(err_msg); + + if (copy_len > sizeof(client->tftp_buf) - req_size) { + copy_len = sizeof(client->tftp_buf) - req_size; + } + + memcpy(client->tftp_buf + req_size, err_msg, copy_len); + req_size += copy_len; } /* Send Error to server. */ From e72baabe910934564b4bac2c4a8ec59867b84701 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 10:56:20 +0100 Subject: [PATCH 3886/4498] dt-bindings: sensor: lsm6dsv16x: add macros for DT properties setting Add macros for setting in a clear way lsm6dsv16x DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lsm6dsv16x-common.yaml | 188 ++++++++++-------- .../zephyr/dt-bindings/sensor/lsm6dsv16x.h | 58 ++++++ tests/drivers/build_all/sensor/i2c.dtsi | 6 + 3 files changed, 173 insertions(+), 79 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dsv16x.h diff --git a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml index 619669bf545..99167a6506d 100644 --- a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml @@ -1,6 +1,23 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include st_lsm6dsv16x.h and use the macros + defined there. + + Example: + #include + + lsm6dsv16x: lsm6dsv16x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + include: sensor-device.yaml properties: @@ -41,11 +58,13 @@ properties: default: 0 description: | Range in g. Default is power-up configuration. - enum: - - 0 # 2g (0.061 mg/LSB) - - 1 # 4g (0.122 mg/LSB) - - 2 # 8g (0.244 mg/LSB) - - 3 # 16g (0.488 mg/LSB) + + - 0 # LSM6DSV16X_DT_FS_2G (0.061 mg/LSB) + - 1 # LSM6DSV16X_DT_FS_4G (0.122 mg/LSB) + - 2 # LSM6DSV16X_DT_FS_8G (0.244 mg/LSB) + - 3 # LSM6DSV16X_DT_FS_16G (0.488 mg/LSB) + + enum: [0, 1, 2, 3] accel-odr: type: int @@ -56,53 +75,59 @@ properties: module. Please note that this values will not change the operating mode, which will remain High Performance (device default) Default is power-up configuration. - enum: - - 0x00 # Power-Down - - 0x01 # 1Hz875 - - 0x02 # 7Hz5 - - 0x03 # 15Hz - - 0x04 # 30Hz - - 0x05 # 60Hz - - 0x06 # 120Hz - - 0x07 # 240Hz - - 0x08 # 480Hz - - 0x09 # 960Hz - - 0x0a # 1920Hz - - 0x0b # 3840Hz - - 0x0c # 7680Hz - - 0x13 # 15Hz625 (High Accuracy 1) - - 0x14 # 31Hz25 (High Accuracy 1) - - 0x15 # 62Hz5 (High Accuracy 1) - - 0x16 # 125Hz (High Accuracy 1) - - 0x17 # 250Hz (High Accuracy 1) - - 0x18 # 500Hz (High Accuracy 1) - - 0x19 # 1000Hz (High Accuracy 1) - - 0x1a # 2000Hz (High Accuracy 1) - - 0x1b # 4000Hz (High Accuracy 1) - - 0x1c # 8000Hz (High Accuracy 1) - - 0x23 # 12Hz5 (High Accuracy 2) - - 0x24 # 25Hz (High Accuracy 2) - - 0x25 # 50Hz (High Accuracy 2) - - 0x26 # 100Hz (High Accuracy 2) - - 0x27 # 200Hz (High Accuracy 2) - - 0x28 # 400Hz (High Accuracy 2) - - 0x29 # 800Hz (High Accuracy 2) - - 0x2a # 1600Hz (High Accuracy 2) - - 0x2b # 3200Hz (High Accuracy 2) - - 0x2c # 6400Hz (High Accuracy 2) + + - 0x00 # LSM6DSV16X_DT_ODR_OFF + - 0x01 # LSM6DSV16X_DT_ODR_AT_1Hz875 + - 0x02 # LSM6DSV16X_DT_ODR_AT_7Hz5 + - 0x03 # LSM6DSV16X_DT_ODR_AT_15Hz + - 0x04 # LSM6DSV16X_DT_ODR_AT_30Hz + - 0x05 # LSM6DSV16X_DT_ODR_AT_60Hz + - 0x06 # LSM6DSV16X_DT_ODR_AT_120Hz + - 0x07 # LSM6DSV16X_DT_ODR_AT_240Hz + - 0x08 # LSM6DSV16X_DT_ODR_AT_480Hz + - 0x09 # LSM6DSV16X_DT_ODR_AT_960Hz + - 0x0a # LSM6DSV16X_DT_ODR_AT_1920Hz + - 0x0b # LSM6DSV16X_DT_ODR_AT_3840Hz + - 0x0c # LSM6DSV16X_DT_ODR_AT_7680Hz + - 0x13 # LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 + - 0x14 # LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 + - 0x15 # LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 + - 0x16 # LSM6DSV16X_DT_ODR_HA01_AT_125Hz + - 0x17 # LSM6DSV16X_DT_ODR_HA01_AT_250Hz + - 0x18 # LSM6DSV16X_DT_ODR_HA01_AT_500Hz + - 0x19 # LSM6DSV16X_DT_ODR_HA01_AT_1000Hz + - 0x1a # LSM6DSV16X_DT_ODR_HA01_AT_2000Hz + - 0x1b # LSM6DSV16X_DT_ODR_HA01_AT_4000Hz + - 0x1c # LSM6DSV16X_DT_ODR_HA01_AT_8000Hz + - 0x23 # LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 + - 0x24 # LSM6DSV16X_DT_ODR_HA02_AT_25Hz + - 0x25 # LSM6DSV16X_DT_ODR_HA02_AT_50Hz + - 0x26 # LSM6DSV16X_DT_ODR_HA02_AT_100Hz + - 0x27 # LSM6DSV16X_DT_ODR_HA02_AT_200Hz + - 0x28 # LSM6DSV16X_DT_ODR_HA02_AT_400Hz + - 0x29 # LSM6DSV16X_DT_ODR_HA02_AT_800Hz + - 0x2a # LSM6DSV16X_DT_ODR_HA02_AT_1600Hz + - 0x2b # LSM6DSV16X_DT_ODR_HA02_AT_3200Hz + - 0x2c # LSM6DSV16X_DT_ODR_HA02_AT_6400Hz + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c] gyro-range: type: int default: 0 description: | Range in dps. Default is power-up configuration. - enum: - - 0 # 125 dps (4.375 mdps/LSB) - - 1 # 250 dps (8.75 mdps/LSB) - - 2 # 500 dps (17.50 mdps/LSB) - - 3 # 1000 dps (35 mdps/LSB) - - 4 # 2000 dps (70 mdps/LSB) - - 5 # 4000 dps (140 mdps/LSB) + + - 0x0 # LSM6DSV16X_DT_FS_125DPS (4.375 mdps/LSB) + - 0x1 # LSM6DSV16X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # LSM6DSV16X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # LSM6DSV16X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # LSM6DSV16X_DT_FS_2000DPS (70 mdps/LSB) + - 0xc # LSM6DSV16X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0xc] gyro-odr: type: int @@ -115,39 +140,44 @@ properties: DT are the only way to specifiy the odr accuracy even at runtime with SENSOR_ATTR_SAMPLING_FREQUENCY. Default is power-up configuration. - enum: - - 0x00 # Power-Down - - 0x02 # 7Hz5 - - 0x03 # 15Hz - - 0x04 # 30Hz - - 0x05 # 60Hz - - 0x06 # 120Hz - - 0x07 # 240Hz - - 0x08 # 480Hz - - 0x09 # 960Hz - - 0x0a # 1920Hz - - 0x0b # 3840Hz - - 0x0c # 7680Hz - - 0x13 # 15Hz625 (High Accuracy 1) - - 0x14 # 31Hz25 (High Accuracy 1) - - 0x15 # 62Hz5 (High Accuracy 1) - - 0x16 # 125Hz (High Accuracy 1) - - 0x17 # 250Hz (High Accuracy 1) - - 0x18 # 500Hz (High Accuracy 1) - - 0x19 # 1000Hz (High Accuracy 1) - - 0x1a # 2000Hz (High Accuracy 1) - - 0x1b # 4000Hz (High Accuracy 1) - - 0x1c # 8000Hz (High Accuracy 1) - - 0x23 # 12Hz5 (High Accuracy 2) - - 0x24 # 25Hz (High Accuracy 2) - - 0x25 # 50Hz (High Accuracy 2) - - 0x26 # 100Hz (High Accuracy 2) - - 0x27 # 200Hz (High Accuracy 2) - - 0x28 # 400Hz (High Accuracy 2) - - 0x29 # 800Hz (High Accuracy 2) - - 0x2a # 1600Hz (High Accuracy 2) - - 0x2b # 3200Hz (High Accuracy 2) - - 0x2c # 6400Hz (High Accuracy 2) + + - 0x00 # LSM6DSV16X_DT_ODR_OFF + - 0x01 # LSM6DSV16X_DT_ODR_AT_1Hz875 + - 0x02 # LSM6DSV16X_DT_ODR_AT_7Hz5 + - 0x03 # LSM6DSV16X_DT_ODR_AT_15Hz + - 0x04 # LSM6DSV16X_DT_ODR_AT_30Hz + - 0x05 # LSM6DSV16X_DT_ODR_AT_60Hz + - 0x06 # LSM6DSV16X_DT_ODR_AT_120Hz + - 0x07 # LSM6DSV16X_DT_ODR_AT_240Hz + - 0x08 # LSM6DSV16X_DT_ODR_AT_480Hz + - 0x09 # LSM6DSV16X_DT_ODR_AT_960Hz + - 0x0a # LSM6DSV16X_DT_ODR_AT_1920Hz + - 0x0b # LSM6DSV16X_DT_ODR_AT_3840Hz + - 0x0c # LSM6DSV16X_DT_ODR_AT_7680Hz + - 0x13 # LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 + - 0x14 # LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 + - 0x15 # LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 + - 0x16 # LSM6DSV16X_DT_ODR_HA01_AT_125Hz + - 0x17 # LSM6DSV16X_DT_ODR_HA01_AT_250Hz + - 0x18 # LSM6DSV16X_DT_ODR_HA01_AT_500Hz + - 0x19 # LSM6DSV16X_DT_ODR_HA01_AT_1000Hz + - 0x1a # LSM6DSV16X_DT_ODR_HA01_AT_2000Hz + - 0x1b # LSM6DSV16X_DT_ODR_HA01_AT_4000Hz + - 0x1c # LSM6DSV16X_DT_ODR_HA01_AT_8000Hz + - 0x23 # LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 + - 0x24 # LSM6DSV16X_DT_ODR_HA02_AT_25Hz + - 0x25 # LSM6DSV16X_DT_ODR_HA02_AT_50Hz + - 0x26 # LSM6DSV16X_DT_ODR_HA02_AT_100Hz + - 0x27 # LSM6DSV16X_DT_ODR_HA02_AT_200Hz + - 0x28 # LSM6DSV16X_DT_ODR_HA02_AT_400Hz + - 0x29 # LSM6DSV16X_DT_ODR_HA02_AT_800Hz + - 0x2a # LSM6DSV16X_DT_ODR_HA02_AT_1600Hz + - 0x2b # LSM6DSV16X_DT_ODR_HA02_AT_3200Hz + - 0x2c # LSM6DSV16X_DT_ODR_HA02_AT_6400Hz + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c] drdy-pulsed: type: boolean diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h new file mode 100644 index 00000000000..533dd5e3feb --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ + +/* Accel range */ +#define LSM6DSV16X_DT_FS_2G 0 +#define LSM6DSV16X_DT_FS_4G 1 +#define LSM6DSV16X_DT_FS_8G 2 +#define LSM6DSV16X_DT_FS_16G 3 + +/* Gyro range */ +#define LSM6DSV16X_DT_FS_125DPS 0x0 +#define LSM6DSV16X_DT_FS_250DPS 0x1 +#define LSM6DSV16X_DT_FS_500DPS 0x2 +#define LSM6DSV16X_DT_FS_1000DPS 0x3 +#define LSM6DSV16X_DT_FS_2000DPS 0x4 +#define LSM6DSV16X_DT_FS_4000DPS 0xc + +/* Accel and Gyro Data rates */ +#define LSM6DSV16X_DT_ODR_OFF 0x0 +#define LSM6DSV16X_DT_ODR_AT_1Hz875 0x1 +#define LSM6DSV16X_DT_ODR_AT_7Hz5 0x2 +#define LSM6DSV16X_DT_ODR_AT_15Hz 0x3 +#define LSM6DSV16X_DT_ODR_AT_30Hz 0x4 +#define LSM6DSV16X_DT_ODR_AT_60Hz 0x5 +#define LSM6DSV16X_DT_ODR_AT_120Hz 0x6 +#define LSM6DSV16X_DT_ODR_AT_240Hz 0x7 +#define LSM6DSV16X_DT_ODR_AT_480Hz 0x8 +#define LSM6DSV16X_DT_ODR_AT_960Hz 0x9 +#define LSM6DSV16X_DT_ODR_AT_1920Hz 0xA +#define LSM6DSV16X_DT_ODR_AT_3840Hz 0xB +#define LSM6DSV16X_DT_ODR_AT_7680Hz 0xC +#define LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 0x13 +#define LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 0x14 +#define LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 0x15 +#define LSM6DSV16X_DT_ODR_HA01_AT_125Hz 0x16 +#define LSM6DSV16X_DT_ODR_HA01_AT_250Hz 0x17 +#define LSM6DSV16X_DT_ODR_HA01_AT_500Hz 0x18 +#define LSM6DSV16X_DT_ODR_HA01_AT_1000Hz 0x19 +#define LSM6DSV16X_DT_ODR_HA01_AT_2000Hz 0x1A +#define LSM6DSV16X_DT_ODR_HA01_AT_4000Hz 0x1B +#define LSM6DSV16X_DT_ODR_HA01_AT_8000Hz 0x1C +#define LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 0x23 +#define LSM6DSV16X_DT_ODR_HA02_AT_25Hz 0x24 +#define LSM6DSV16X_DT_ODR_HA02_AT_50Hz 0x25 +#define LSM6DSV16X_DT_ODR_HA02_AT_100Hz 0x26 +#define LSM6DSV16X_DT_ODR_HA02_AT_200Hz 0x27 +#define LSM6DSV16X_DT_ODR_HA02_AT_400Hz 0x28 +#define LSM6DSV16X_DT_ODR_HA02_AT_800Hz 0x29 +#define LSM6DSV16X_DT_ODR_HA02_AT_1600Hz 0x2A +#define LSM6DSV16X_DT_ODR_HA02_AT_3200Hz 0x2B +#define LSM6DSV16X_DT_ODR_HA02_AT_6400Hz 0x2C + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index ce22576c48a..6dfad3e8a4f 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -6,6 +6,8 @@ * Application overlay for i2c devices */ +#include + /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * ***************************************/ @@ -697,6 +699,10 @@ test_i2c_lsm6dsv16x: lsm6dsv16x@69 { reg = <0x69>; int1-gpios = <&test_gpio 0 0>; int2-gpios = <&test_gpio 0 0>; + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; }; test_i2c_mcp9600: mcp9600@6a { From 0c3057edf471dad786f0071cf4e6e118237eb7ea Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 10:59:11 +0100 Subject: [PATCH 3887/4498] dt-bindings: sensor: lsm6dso: add macros for DT properties setting Add macros for setting in a clear way lsm6dso DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lsm6dso-common.yaml | 116 +++++++++++++------- include/zephyr/dt-bindings/sensor/lsm6dso.h | 45 ++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 7 ++ 3 files changed, 126 insertions(+), 42 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dso.h diff --git a/dts/bindings/sensor/st,lsm6dso-common.yaml b/dts/bindings/sensor/st,lsm6dso-common.yaml index e8de1e9a75d..0b4b17df720 100644 --- a/dts/bindings/sensor/st,lsm6dso-common.yaml +++ b/dts/bindings/sensor/st,lsm6dso-common.yaml @@ -1,6 +1,25 @@ # Copyright (c) 2021 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-pm, accel-range, accel-odr, gyro-pm, gyro-range, + gyro-odr properties in a .dts or .dtsi file you may include st_lsm6dso.h + and use the macros defined there. + + Example: + #include + + lsm6dso: lsm6dso@0 { + ... + + accel-pm = ; + accel-range = ; + accel-odr = ; + gyro-pm = ; + gyro-range = ; + gyro-odr = ; + }; + include: sensor-device.yaml properties: @@ -33,21 +52,25 @@ properties: description: | Specify the accelerometer power mode. Default is power-up configuration. - enum: - - 0 # High Performance mode (default) - - 1 # Low/Normal Power mode - - 2 # Ultra Low Power mode + + - 0 # LSM6DSO_DT_XL_HP_MODE + - 1 # LSM6DSO_DT_XL_LP_NORMAL_MODE + - 2 # LSM6DSO_DT_XL_ULP_MODE + + enum: [0, 1, 2] accel-range: type: int default: 0 description: | Range in g. Default is power-up configuration. - enum: - - 0 # 2g (0.061 mg/LSB) (LSM6DSO32 will be double these values) - - 1 # 16g (0.488 mg/LSB) - - 2 # 4g (0.122 mg/LSB) - - 3 # 8g (0.244 mg/LSB) + + - 0 # LSM6DSO_DT_FS_2G (0.061 mg/LSB) (LSM6DSO32 will be double these values) + - 1 # LSM6DSO_DT_FS_16G (0.488 mg/LSB) + - 2 # LSM6DSO_DT_FS_4G (0.122 mg/LSB) + - 3 # LSM6DSO_DT_FS_8G (0.244 mg/LSB) + + enum: [0, 1, 2, 3] accel-odr: type: int @@ -55,18 +78,21 @@ properties: description: | Specify the default accelerometer output data rate expressed in samples per second (Hz). Default is power-up configuration. - enum: - - 0 # Power-Down - - 1 # 12.5Hz - - 2 # 26Hz - - 3 # 52Hz - - 4 # 104Hz - - 5 # 208Hz - - 6 # 417Hz - - 7 # 833Hz - - 8 # 1667Hz - - 9 # 3333Hz - - 10 # 6667Hz + + - 0 # LSM6DSO_DT_ODR_OFF + - 1 # LSM6DSO_DT_ODR_12Hz5 + - 2 # LSM6DSO_DT_ODR_26H + - 3 # LSM6DSO_DT_ODR_52Hz + - 4 # LSM6DSO_DT_ODR_104Hz + - 5 # LSM6DSO_DT_ODR_208Hz + - 6 # LSM6DSO_DT_ODR_417Hz + - 7 # LSM6DSO_DT_ODR_833Hz + - 8 # LSM6DSO_DT_ODR_1667Hz + - 9 # LSM6DSO_DT_ODR_3333Hz + - 10 # LSM6DSO_DT_ODR_6667Hz + - 11 # LSM6DSO_DT_ODR_1Hz6 + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] gyro-pm: type: int @@ -74,21 +100,25 @@ properties: description: | Specify the gyrometer power mode. Default is power-up configuration. - enum: - - 0 # High Performance mode (default) - - 1 # Low/Normal Power mode + + - 0 # LSM6DSO_DT_GY_HP_MODE + - 1 # LSM6DSO_DT_GY_NORMAL_MODE + + enum: [0, 1] gyro-range: type: int default: 0 description: | Range in dps. Default is power-up configuration. - enum: - - 0 # 250 dps (8.75 mdps/LSB) - - 1 # 125 dps (4.375 mdps/LSB) - - 2 # 500 dps (17.50 mdps/LSB) - - 4 # 1000 dps (35 mdps/LSB) - - 6 # 2000 dps (70 mdps/LSB) + + - 0 # LSM6DSO_DT_FS_250DPS (8.75 mdps/LSB) + - 1 # LSM6DSO_DT_FS_125DPS (4.375 mdps/LSB) + - 2 # LSM6DSO_DT_FS_500DPS (17.50 mdps/LSB) + - 4 # LSM6DSO_DT_FS_1000DPS (35 mdps/LSB) + - 6 # LSM6DSO_DT_FS_2000DPS (70 mdps/LSB) + + enum: [0, 1, 2, 4, 6] gyro-odr: type: int @@ -96,18 +126,20 @@ properties: description: | Specify the default gyro output data rate expressed in samples per second (Hz). Default is power-up configuration. - enum: - - 0 # Power-Down - - 1 # 12.5Hz - - 2 # 26Hz - - 3 # 52Hz - - 4 # 104Hz - - 5 # 208Hz - - 6 # 417Hz - - 7 # 833Hz - - 8 # 1667Hz - - 9 # 3333Hz - - 10 # 6667Hz + + - 0 # LSM6DSO_DT_ODR_OFF + - 1 # LSM6DSO_DT_ODR_12Hz5 + - 2 # LSM6DSO_DT_ODR_26H + - 3 # LSM6DSO_DT_ODR_52Hz + - 4 # LSM6DSO_DT_ODR_104Hz + - 5 # LSM6DSO_DT_ODR_208Hz + - 6 # LSM6DSO_DT_ODR_417Hz + - 7 # LSM6DSO_DT_ODR_833Hz + - 8 # LSM6DSO_DT_ODR_1667Hz + - 9 # LSM6DSO_DT_ODR_3333Hz + - 10 # LSM6DSO_DT_ODR_6667Hz + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] drdy-pulsed: type: boolean diff --git a/include/zephyr/dt-bindings/sensor/lsm6dso.h b/include/zephyr/dt-bindings/sensor/lsm6dso.h new file mode 100644 index 00000000000..7d3775bae3d --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dso.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO_H_ + +/* Accel power-modes */ +#define LSM6DSO_DT_XL_HP_MODE 0 +#define LSM6DSO_DT_XL_LP_NORMAL_MODE 1 +#define LSM6DSO_DT_XL_ULP_MODE 2 + +/* Gyro power-modes */ +#define LSM6DSO_DT_GY_HP_MODE 0 +#define LSM6DSO_DT_GY_NORMAL_MODE 1 + +/* Accel range */ +#define LSM6DSO_DT_FS_2G 0 +#define LSM6DSO_DT_FS_16G 1 +#define LSM6DSO_DT_FS_4G 2 +#define LSM6DSO_DT_FS_8G 3 + +/* Gyro range */ +#define LSM6DSO_DT_FS_250DPS 0 +#define LSM6DSO_DT_FS_125DPS 1 +#define LSM6DSO_DT_FS_500DPS 2 +#define LSM6DSO_DT_FS_1000DPS 4 +#define LSM6DSO_DT_FS_2000DPS 6 + +/* Accel and Gyro Data rates */ +#define LSM6DSO_DT_ODR_OFF 0x0 +#define LSM6DSO_DT_ODR_12Hz5 0x1 +#define LSM6DSO_DT_ODR_26H 0x2 +#define LSM6DSO_DT_ODR_52Hz 0x3 +#define LSM6DSO_DT_ODR_104Hz 0x4 +#define LSM6DSO_DT_ODR_208Hz 0x5 +#define LSM6DSO_DT_ODR_417Hz 0x6 +#define LSM6DSO_DT_ODR_833Hz 0x7 +#define LSM6DSO_DT_ODR_1667Hz 0x8 +#define LSM6DSO_DT_ODR_3333Hz 0x9 +#define LSM6DSO_DT_ODR_6667Hz 0xa +#define LSM6DSO_DT_ODR_1Hz6 0xb + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 6dfad3e8a4f..2441a3cb9b9 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -7,6 +7,7 @@ */ #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -364,6 +365,12 @@ test_i2c_lsm6dso: lsm6dso@39 { compatible = "st,lsm6dso"; reg = <0x39>; irq-gpios = <&test_gpio 0 0>; + accel-pm = ; + accel-range = ; + accel-odr = ; + gyro-pm = ; + gyro-range = ; + gyro-odr = ; }; test_i2c_lsm9ds0_gyro: lsm9ds0-gyro@3a { From 1fbd157c6156c4c5e28a50e7e60b05333a2c6a0a Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:19:33 +0100 Subject: [PATCH 3888/4498] dt-bindings: sensor: lsm6dso16is: add macros for DT properties setting Add macros for setting in a clear way lsm6dso16is DT properties. Signed-off-by: Armando Visconti --- .../sensor/st,lsm6dso16is-common.yaml | 139 +++++++++++------- .../zephyr/dt-bindings/sensor/lsm6dso16is.h | 46 ++++++ tests/drivers/build_all/sensor/i2c.dtsi | 5 + 3 files changed, 134 insertions(+), 56 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dso16is.h diff --git a/dts/bindings/sensor/st,lsm6dso16is-common.yaml b/dts/bindings/sensor/st,lsm6dso16is-common.yaml index 16304b5692c..49f7fd187fb 100644 --- a/dts/bindings/sensor/st,lsm6dso16is-common.yaml +++ b/dts/bindings/sensor/st,lsm6dso16is-common.yaml @@ -1,6 +1,23 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include st_lsm6dso16is.h and use the macros + defined there. + + Example: + #include + + lsm6dso16is: lsm6dso16is@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + include: sensor-device.yaml properties: @@ -32,11 +49,13 @@ properties: default: 0 description: | Range in g. Default is power-up configuration. - enum: - - 0 # 2g (0.061 mg/LSB) - - 1 # 16g (0.488 mg/LSB) - - 2 # 4g (0.122 mg/LSB) - - 3 # 8g (0.244 mg/LSB) + + - 0 # LSM6DSO16IS_DT_FS_2G (0.061 mg/LSB) + - 1 # LSM6DSO16IS_DT_FS_16G (0.488 mg/LSB) + - 2 # LSM6DSO16IS_DT_FS_4G (0.122 mg/LSB) + - 3 # LSM6DSO16IS_DT_FS_8G (0.244 mg/LSB) + + enum: [0, 1, 2, 3] accel-odr: type: int @@ -46,41 +65,46 @@ properties: The values are taken in accordance to lsm6dso16is_xl_data_rate_t enumerative in hal/st module. Default is power-up configuration. - enum: - - 0x00 # Power-Down - - 0x01 # 12.5Hz High Performance - - 0x02 # 26Hz High Performance - - 0x03 # 52Hz High Performance - - 0x04 # 104Hz High Performance - - 0x05 # 208Hz High Performance - - 0x06 # 417Hz High Performance - - 0x07 # 833Hz High Performance - - 0x08 # 1667Hz High Performance - - 0x09 # 3333Hz High Performance - - 0x0a # 6667Hz High Performance - - 0x11 # 12.5Hz Low Power - - 0x12 # 26Hz Low Power - - 0x13 # 52Hz Low Power - - 0x14 # 104Hz Low Power - - 0x15 # 208Hz Low Power - - 0x16 # 417Hz Low Power - - 0x17 # 833Hz Low Power - - 0x18 # 1667Hz Low Power - - 0x19 # 3333Hz Low Power - - 0x1a # 6667Hz Low Power - - 0x1b # 1Hz6 Low Power + + - 0x00 # LSM6DSO16IS_DT_ODR_OFF + - 0x01 # LSM6DSO16IS_DT_ODR_12Hz5_HP + - 0x02 # LSM6DSO16IS_DT_ODR_26H_HP + - 0x03 # LSM6DSO16IS_DT_ODR_52Hz_HP + - 0x04 # LSM6DSO16IS_DT_ODR_104Hz_HP + - 0x05 # LSM6DSO16IS_DT_ODR_208Hz_HP + - 0x06 # LSM6DSO16IS_DT_ODR_416Hz_HP + - 0x07 # LSM6DSO16IS_DT_ODR_833Hz_HP + - 0x08 # LSM6DSO16IS_DT_ODR_1667Hz_HP + - 0x09 # LSM6DSO16IS_DT_ODR_3333Hz_HP + - 0x0a # LSM6DSO16IS_DT_ODR_6667Hz_HP + - 0x11 # LSM6DSO16IS_DT_ODR_12Hz5_LP + - 0x12 # LSM6DSO16IS_DT_ODR_26H_LP + - 0x13 # LSM6DSO16IS_DT_ODR_52Hz_LP + - 0x14 # LSM6DSO16IS_DT_ODR_104Hz_LP + - 0x15 # LSM6DSO16IS_DT_ODR_208Hz_LP + - 0x16 # LSM6DSO16IS_DT_ODR_416Hz_LP + - 0x17 # LSM6DSO16IS_DT_ODR_833Hz_LP + - 0x18 # LSM6DSO16IS_DT_ODR_1667Hz_LP + - 0x19 # LSM6DSO16IS_DT_ODR_3333Hz_LP + - 0x1a # LSM6DSO16IS_DT_ODR_6667Hz_LP + - 0x1b # LSM6DSO16IS_DT_ODR_1Hz6_LP + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b] gyro-range: type: int default: 0 description: | Range in dps. Default is power-up configuration. - enum: - - 0 # 250 dps (8.75 mdps/LSB) - - 1 # 125 dps (4.375 mdps/LSB) - - 2 # 500 dps (17.50 mdps/LSB) - - 4 # 1000 dps (35 mdps/LSB) - - 6 # 2000 dps (70 mdps/LSB) + + - 0x0 # LSM6DSO16IS_DT_FS_250DPS (8.75 mdps/LSB) + - 0x1 # LSM6DSO16IS_DT_FS_500DPS (17.50 mdps/LSB) + - 0x2 # LSM6DSO16IS_DT_FS_1000DPS (35 mdps/LSB) + - 0x3 # LSM6DSO16IS_DT_FS_2000DPS (70 mdps/LSB) + - 0x10 # LSM6DSO16IS_DT_FS_125DPS (4.375 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x10] gyro-odr: type: int @@ -90,28 +114,31 @@ properties: The values are taken in accordance to lsm6dso16is_gy_data_rate_t enumerative in hal/st module. Default is power-up configuration. - enum: - - 0x00 # Power-Down - - 0x01 # 12.5Hz High Performance - - 0x02 # 26Hz High Performance - - 0x03 # 52Hz High Performance - - 0x04 # 104Hz High Performance - - 0x05 # 208Hz High Performance - - 0x06 # 417Hz High Performance - - 0x07 # 833Hz High Performance - - 0x08 # 1667Hz High Performance - - 0x09 # 3333Hz High Performance - - 0x0a # 6667Hz High Performance - - 0x11 # 12.5Hz Low Power - - 0x12 # 26Hz Low Power - - 0x13 # 52Hz Low Power - - 0x14 # 104Hz Low Power - - 0x15 # 208Hz Low Power - - 0x16 # 417Hz Low Power - - 0x17 # 833Hz Low Power - - 0x18 # 1667Hz Low Power - - 0x19 # 3333Hz Low Power - - 0x1a # 6667Hz Low Power + + - 0x00 # LSM6DSO16IS_DT_ODR_OFF + - 0x01 # LSM6DSO16IS_DT_ODR_12Hz5_HP + - 0x02 # LSM6DSO16IS_DT_ODR_26H_HP + - 0x03 # LSM6DSO16IS_DT_ODR_52Hz_HP + - 0x04 # LSM6DSO16IS_DT_ODR_104Hz_HP + - 0x05 # LSM6DSO16IS_DT_ODR_208Hz_HP + - 0x06 # LSM6DSO16IS_DT_ODR_416Hz_HP + - 0x07 # LSM6DSO16IS_DT_ODR_833Hz_HP + - 0x08 # LSM6DSO16IS_DT_ODR_1667Hz_HP + - 0x09 # LSM6DSO16IS_DT_ODR_3333Hz_HP + - 0x0a # LSM6DSO16IS_DT_ODR_6667Hz_HP + - 0x11 # LSM6DSO16IS_DT_ODR_12Hz5_LP + - 0x12 # LSM6DSO16IS_DT_ODR_26H_LP + - 0x13 # LSM6DSO16IS_DT_ODR_52Hz_LP + - 0x14 # LSM6DSO16IS_DT_ODR_104Hz_LP + - 0x15 # LSM6DSO16IS_DT_ODR_208Hz_LP + - 0x16 # LSM6DSO16IS_DT_ODR_416Hz_LP + - 0x17 # LSM6DSO16IS_DT_ODR_833Hz_LP + - 0x18 # LSM6DSO16IS_DT_ODR_1667Hz_LP + - 0x19 # LSM6DSO16IS_DT_ODR_3333Hz_LP + - 0x1a # LSM6DSO16IS_DT_ODR_6667Hz_LP + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a] drdy-pulsed: type: boolean diff --git a/include/zephyr/dt-bindings/sensor/lsm6dso16is.h b/include/zephyr/dt-bindings/sensor/lsm6dso16is.h new file mode 100644 index 00000000000..385f41145cf --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dso16is.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO16IS_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO16IS_H_ + +/* Accel range */ +#define LSM6DSO16IS_DT_FS_2G 0 +#define LSM6DSO16IS_DT_FS_16G 1 +#define LSM6DSO16IS_DT_FS_4G 2 +#define LSM6DSO16IS_DT_FS_8G 3 + +/* Gyro range */ +#define LSM6DSO16IS_DT_FS_250DPS 0x0 +#define LSM6DSO16IS_DT_FS_500DPS 0x1 +#define LSM6DSO16IS_DT_FS_1000DPS 0x2 +#define LSM6DSO16IS_DT_FS_2000DPS 0x3 +#define LSM6DSO16IS_DT_FS_125DPS 0x10 + +/* Accel and Gyro Data rates */ +#define LSM6DSO16IS_DT_ODR_OFF 0x0 +#define LSM6DSO16IS_DT_ODR_12Hz5_HP 0x1 +#define LSM6DSO16IS_DT_ODR_26H_HP 0x2 +#define LSM6DSO16IS_DT_ODR_52Hz_HP 0x3 +#define LSM6DSO16IS_DT_ODR_104Hz_HP 0x4 +#define LSM6DSO16IS_DT_ODR_208Hz_HP 0x5 +#define LSM6DSO16IS_DT_ODR_416Hz_HP 0x6 +#define LSM6DSO16IS_DT_ODR_833Hz_HP 0x7 +#define LSM6DSO16IS_DT_ODR_1667Hz_HP 0x8 +#define LSM6DSO16IS_DT_ODR_3333Hz_HP 0x9 +#define LSM6DSO16IS_DT_ODR_6667Hz_HP 0xa +#define LSM6DSO16IS_DT_ODR_12Hz5_LP 0x11 +#define LSM6DSO16IS_DT_ODR_26H_LP 0x12 +#define LSM6DSO16IS_DT_ODR_52Hz_LP 0x13 +#define LSM6DSO16IS_DT_ODR_104Hz_LP 0x14 +#define LSM6DSO16IS_DT_ODR_208Hz_LP 0x15 +#define LSM6DSO16IS_DT_ODR_416Hz_LP 0x16 +#define LSM6DSO16IS_DT_ODR_833Hz_LP 0x17 +#define LSM6DSO16IS_DT_ODR_1667Hz_LP 0x18 +#define LSM6DSO16IS_DT_ODR_3333Hz_LP 0x19 +#define LSM6DSO16IS_DT_ODR_6667Hz_LP 0x1a +#define LSM6DSO16IS_DT_ODR_1Hz6_LP 0x1b + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSO16IS_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 2441a3cb9b9..6c00025d8dd 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -8,6 +8,7 @@ #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -699,6 +700,10 @@ test_i2c_lsm6dso16is: lsm6dso16is@68 { compatible = "st,lsm6dso16is"; reg = <0x68>; irq-gpios = <&test_gpio 0 0>; + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; }; test_i2c_lsm6dsv16x: lsm6dsv16x@69 { From b0f22dbafdc4b7eb6dd5a25dbca7b8918c40101f Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:21:36 +0100 Subject: [PATCH 3889/4498] dt-bindings: sensor: lps22hh: add macros for DT properties setting Add macros for setting in a clear way lps22hh DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lps22hh-common.yaml | 33 +++++++++++++++------ include/zephyr/dt-bindings/sensor/lps22hh.h | 19 ++++++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 2 ++ 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lps22hh.h diff --git a/dts/bindings/sensor/st,lps22hh-common.yaml b/dts/bindings/sensor/st,lps22hh-common.yaml index a704eac46ae..eeeffe25f96 100644 --- a/dts/bindings/sensor/st,lps22hh-common.yaml +++ b/dts/bindings/sensor/st,lps22hh-common.yaml @@ -1,6 +1,19 @@ # Copyright (c) 2021 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the odr property in a .dts or .dtsi file you may include + st_lps22hh.h and use the macros defined there. + + Example: + #include + + lps22hh: lps22hh@0 { + ... + + odr = ; + }; + include: sensor-device.yaml properties: @@ -19,12 +32,14 @@ properties: description: | Specify the default output data rate expressed in samples per second (Hz). The default is the power-on reset value. - enum: - - 0 # Power-Down - - 1 # 1Hz - - 2 # 10Hz - - 3 # 25Hz - - 4 # 50Hz - - 5 # 75Hz - - 6 # 100Hz - - 7 # 200Hz + + - 0 # LPS22HH_DT_ODR_POWER_DOWN + - 1 # LPS22HH_DT_ODR_1HZ + - 2 # LPS22HH_DT_ODR_10HZ + - 3 # LPS22HH_DT_ODR_25HZ + - 4 # LPS22HH_DT_ODR_50HZ + - 5 # LPS22HH_DT_ODR_75HZ + - 6 # LPS22HH_DT_ODR_100HZ + - 7 # LPS22HH_DT_ODR_200HZ + + enum: [0, 1, 2, 3, 4, 5, 6, 7] diff --git a/include/zephyr/dt-bindings/sensor/lps22hh.h b/include/zephyr/dt-bindings/sensor/lps22hh.h new file mode 100644 index 00000000000..728f872bc37 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lps22hh.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22HH_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22HH_H_ + +/* Data rate */ +#define LPS22HH_DT_ODR_POWER_DOWN 0 +#define LPS22HH_DT_ODR_1HZ 1 +#define LPS22HH_DT_ODR_10HZ 2 +#define LPS22HH_DT_ODR_25HZ 3 +#define LPS22HH_DT_ODR_50HZ 4 +#define LPS22HH_DT_ODR_75HZ 5 +#define LPS22HH_DT_ODR_100HZ 6 +#define LPS22HH_DT_ODR_200HZ 7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22HH_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 6c00025d8dd..b8bbc74b886 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -323,6 +324,7 @@ test_i2c_lps22hh: lps22hh@32 { compatible = "st,lps22hh"; reg = <0x32>; drdy-gpios = <&test_gpio 0 0>; + odr = ; }; test_i2c_lps25hb_press: lps25hb-press@33 { From a6cfa0bc15bf5578cd07e0aec169b9c48c71b13b Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:23:14 +0100 Subject: [PATCH 3890/4498] dt-bindings: sensor: lps22df: add macros for DT properties setting Add macros for setting in a clear way lps22df DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lps22df-common.yaml | 84 ++++++++++----------- include/zephyr/dt-bindings/sensor/lps22df.h | 35 +++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 4 + 3 files changed, 80 insertions(+), 43 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lps22df.h diff --git a/dts/bindings/sensor/st,lps22df-common.yaml b/dts/bindings/sensor/st,lps22df-common.yaml index 7a1f21573b2..cc3f11c106f 100644 --- a/dts/bindings/sensor/st,lps22df-common.yaml +++ b/dts/bindings/sensor/st,lps22df-common.yaml @@ -1,6 +1,21 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the odr, lpf, avg properties in a .dts or .dtsi file + you may include st_lps22df.h and use the macros defined there. + + Example: + #include + + lps22df@5d { + ... + + odr = ; + lpf = ; + avg = ; + }; + include: sensor-device.yaml properties: @@ -26,25 +41,17 @@ properties: Specify the output data rate expressed in samples per second (Hz). The default is the power-on reset value. - 0 = Power-Down - 1 = 1Hz - 2 = 4Hz - 3 = 10Hz - 4 = 25Hz - 5 = 50Hz - 6 = 75Hz - 7 = 100Hz - 8 = 200Hz - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 + - 0 # LPS22DF_DT_ODR_POWER_DOWN + - 1 # LPS22DF_DT_ODR_1HZ + - 2 # LPS22DF_DT_ODR_4HZ + - 3 # LPS22DF_DT_ODR_10HZ + - 4 # LPS22DF_DT_ODR_25HZ + - 5 # LPS22DF_DT_ODR_50HZ + - 6 # LPS22DF_DT_ODR_75HZ + - 7 # LPS22DF_DT_ODR_100HZ + - 8 # LPS22DF_DT_ODR_200HZ + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] lpf: type: int @@ -53,13 +60,11 @@ properties: Specify the low pass filter value to be applied to pressure data. The default is the power-on reset value. - 0 = Low Pass Filter disabled - 1 = Low Pass Filter set to ODR/4 - 3 = Low Pass Filter set to ODR/9 - enum: - - 0 - - 1 - - 3 + - 0 # LPS22DF_DT_LP_FILTER_OFF + - 1 # LPS22DF_DT_LP_FILTER_ODR_4 + - 3 # LPS22DF_DT_LP_FILTER_ODR_9 + + enum: [0, 1, 3] avg: type: int @@ -69,20 +74,13 @@ properties: to pressure and temperature data. The default is the power-on reset value. - 0 = Average of 4 data samples - 1 = Average of 8 data samples - 2 = Average of 16 data samples - 3 = Average of 32 data samples - 4 = Average of 64 data samples - 5 = Average of 128 data samples - 6 = Average of 256 data samples - 7 = Average of 512 data samples - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 + - 0 # LPS22DF_DT_AVG_4_SAMPLES + - 1 # LPS22DF_DT_AVG_8_SAMPLES + - 2 # LPS22DF_DT_AVG_16_SAMPLES + - 3 # LPS22DF_DT_AVG_32_SAMPLES + - 4 # LPS22DF_DT_AVG_64_SAMPLES + - 5 # LPS22DF_DT_AVG_128_SAMPLES + - 6 # LPS22DF_DT_AVG_256_SAMPLES + - 7 # LPS22DF_DT_AVG_512_SAMPLES + + enum: [0, 1, 2, 3, 4, 5, 6, 7] diff --git a/include/zephyr/dt-bindings/sensor/lps22df.h b/include/zephyr/dt-bindings/sensor/lps22df.h new file mode 100644 index 00000000000..95668ae6390 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lps22df.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22DF_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22DF_H_ + +/* Data rate */ +#define LPS22DF_DT_ODR_POWER_DOWN 0 +#define LPS22DF_DT_ODR_1HZ 1 +#define LPS22DF_DT_ODR_4HZ 2 +#define LPS22DF_DT_ODR_10HZ 3 +#define LPS22DF_DT_ODR_25HZ 4 +#define LPS22DF_DT_ODR_50HZ 5 +#define LPS22DF_DT_ODR_75HZ 6 +#define LPS22DF_DT_ODR_100HZ 7 +#define LPS22DF_DT_ODR_200HZ 8 + +/* Low Pass filter */ +#define LPS22DF_DT_LP_FILTER_OFF 0 +#define LPS22DF_DT_LP_FILTER_ODR_4 1 +#define LPS22DF_DT_LP_FILTER_ODR_9 3 + +/* Average (number of samples) filter */ +#define LPS22DF_DT_AVG_4_SAMPLES 0 +#define LPS22DF_DT_AVG_8_SAMPLES 1 +#define LPS22DF_DT_AVG_16_SAMPLES 2 +#define LPS22DF_DT_AVG_32_SAMPLES 3 +#define LPS22DF_DT_AVG_64_SAMPLES 4 +#define LPS22DF_DT_AVG_128_SAMPLES 5 +#define LPS22DF_DT_AVG_256_SAMPLES 6 +#define LPS22DF_DT_AVG_512_SAMPLES 7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22DF_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b8bbc74b886..ca8eefd5e68 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -826,6 +827,9 @@ test_i2c_lps22df: lps22df@79 { reg = <0x79>; drdy-gpios = <&test_gpio 0 0>; status = "okay"; + odr = ; + lpf = ; + avg = ; }; test_i2c_hs300x: hs300x@79 { From 2fe89c1076f8096ecec0c8db0ec599e0df3eff3d Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:26:04 +0100 Subject: [PATCH 3891/4498] dt-bindings: sensor: lis2ds12: add macros for DT properties setting Add macros for setting in a clear way lis2ds12 DT properties. Signed-off-by: Armando Visconti --- drivers/sensor/lis2ds12/lis2ds12.c | 6 ++- dts/bindings/sensor/st,lis2ds12-common.yaml | 56 +++++++++++++------- include/zephyr/dt-bindings/sensor/lis2ds12.h | 29 ++++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 3 ++ 4 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lis2ds12.h diff --git a/drivers/sensor/lis2ds12/lis2ds12.c b/drivers/sensor/lis2ds12/lis2ds12.c index ae7fa9eb81f..c9634b2179f 100644 --- a/drivers/sensor/lis2ds12/lis2ds12.c +++ b/drivers/sensor/lis2ds12/lis2ds12.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "lis2ds12.h" @@ -40,8 +41,9 @@ static int lis2ds12_set_odr(const struct device *dev, uint8_t odr) * 12,5Hz <= odr <= 800Hz are available in LP and HR mode only * odr == 1Hz is available in LP mode only */ - if ((odr >= 9 && cfg->pm != 3) || (odr < 9 && cfg->pm == 3) || - (odr == 1 && cfg->pm != 1)) { + if ((odr >= LIS2DS12_DT_ODR_1600Hz && cfg->pm != LIS2DS12_DT_HIGH_FREQUENCY) || + (odr < LIS2DS12_DT_ODR_1600Hz && cfg->pm == LIS2DS12_DT_HIGH_FREQUENCY) || + (odr == LIS2DS12_DT_ODR_1Hz_LP && cfg->pm != LIS2DS12_DT_LOW_POWER)) { LOG_ERR("%s: bad odr and pm combination", dev->name); return -ENOTSUP; } diff --git a/dts/bindings/sensor/st,lis2ds12-common.yaml b/dts/bindings/sensor/st,lis2ds12-common.yaml index 4a5926c42ad..4ac18b40a55 100644 --- a/dts/bindings/sensor/st,lis2ds12-common.yaml +++ b/dts/bindings/sensor/st,lis2ds12-common.yaml @@ -1,6 +1,20 @@ # Copyright (c) 2021 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the odr and power-mode properties in a .dts or .dtsi file you may include + st_lis2ds12.h and use the macros defined there. + + Example: + #include + + lis2ds12: lis2ds12@0 { + ... + + power-mode = ; + odr = ; + }; + include: sensor-device.yaml properties: @@ -19,23 +33,25 @@ properties: description: | Range in g. Default is power-up configuration. - enum: - 16 # 16g (0.488 mg/LSB) - 8 # 8g (0.244 mg/LSB) - 4 # 4g (0.122 mg/LSB) - 2 # 2g (0.061 mg/LSB) + enum: [16, 8, 4, 2] + power-mode: type: int default: 0 description: | Specify the sensor power mode. Default is power-down mode - enum: - - 0 # Power Down (PD) - - 1 # Low Power (LP) - - 2 # High Resolution (HR) - - 3 # High Frequency (HF) + - 0 # LIS2DS12_DT_POWER_DOWN + - 1 # LIS2DS12_DT_LOW_POWER + - 2 # LIS2DS12_DT_HIGH_RESOLUTION + - 3 # LIS2DS12_DT_HIGH_FREQUENCY + + enum: [0, 1, 2, 3] odr: type: int @@ -43,16 +59,18 @@ properties: description: | Specify the default output data rate expressed in samples per second (Hz). Default is power-down mode - enum: - - 0 # Power-Down - - 1 # 1Hz (available in LP mode only) - - 2 # 12.5Hz (available in LP and HR mode) - - 3 # 25Hz (available in LP and HR mode) - - 4 # 50Hz (available in LP and HR mode) - - 5 # 100Hz (available in LP and HR mode) - - 6 # 200Hz (available in LP and HR mode) - - 7 # 400Hz (available in LP and HR mode) - - 8 # 800Hz (available in LP and HR mode) - - 9 # 1600Hz (available in HF mode only) - - 10 # 3200Hz (available in HF mode only) - - 11 # 6400Hz (available in HF mode only) + + - 0 # LIS2DS12_DT_ODR_OFF + - 1 # LIS2DS12_DT_ODR_1Hz_LP + - 2 # LIS2DS12_DT_ODR_12Hz5 + - 3 # LIS2DS12_DT_ODR_25Hz + - 4 # LIS2DS12_DT_ODR_50Hz + - 5 # LIS2DS12_DT_ODR_100Hz + - 6 # LIS2DS12_DT_ODR_200Hz + - 7 # LIS2DS12_DT_ODR_400Hz + - 8 # LIS2DS12_DT_ODR_800Hz + - 9 # LIS2DS12_DT_ODR_1600Hz + - 10 # LIS2DS12_DT_ODR_3200Hz_HF + - 11 # LIS2DS12_DT_ODR_6400Hz_HF + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] diff --git a/include/zephyr/dt-bindings/sensor/lis2ds12.h b/include/zephyr/dt-bindings/sensor/lis2ds12.h new file mode 100644 index 00000000000..04d808bfa72 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lis2ds12.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DS12_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DS12_H_ + +/* power-modes */ +#define LIS2DS12_DT_POWER_DOWN 0 +#define LIS2DS12_DT_LOW_POWER 1 +#define LIS2DS12_DT_HIGH_RESOLUTION 2 +#define LIS2DS12_DT_HIGH_FREQUENCY 3 + +/* Data rate */ +#define LIS2DS12_DT_ODR_OFF 0 +#define LIS2DS12_DT_ODR_1Hz_LP 1 /* available in LP mode only */ +#define LIS2DS12_DT_ODR_12Hz5 2 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_25Hz 3 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_50Hz 4 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_100Hz 5 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_200Hz 6 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_400Hz 7 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_800Hz 8 /* available in LP and HR mode */ +#define LIS2DS12_DT_ODR_1600Hz 9 /* available in HF mode only */ +#define LIS2DS12_DT_ODR_3200Hz_HF 10 /* available in HF mode only */ +#define LIS2DS12_DT_ODR_6400Hz_HF 11 /* available in HF mode only */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DS12_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index ca8eefd5e68..85313f211f2 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -289,6 +290,8 @@ test_i2c_lis2ds12: lis2ds12@2c { compatible = "st,lis2ds12"; reg = <0x2c>; irq-gpios = <&test_gpio 0 0>; + power-mode = ; + odr = ; }; test_i2c_lis2dw12: lis2dw12@2d { From 0b46f387f4a48bb9ff969e2ebd46d118dd0a23f9 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:28:05 +0100 Subject: [PATCH 3892/4498] dt-bindings: sensor: lis2dw12: add macros for DT properties setting Add macros for setting in a clear way lis2dw12 DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lis2dw12-common.yaml | 119 ++++++++----------- include/zephyr/dt-bindings/sensor/lis2dw12.h | 42 +++++++ tests/drivers/build_all/sensor/i2c.dtsi | 6 + 3 files changed, 100 insertions(+), 67 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lis2dw12.h diff --git a/dts/bindings/sensor/st,lis2dw12-common.yaml b/dts/bindings/sensor/st,lis2dw12-common.yaml index 364e4320849..0c9f8dcee67 100644 --- a/dts/bindings/sensor/st,lis2dw12-common.yaml +++ b/dts/bindings/sensor/st,lis2dw12-common.yaml @@ -1,6 +1,23 @@ # Copyright (c) 2021 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the odr property in a .dts or .dtsi file you may include + st_lis2dw12.h and use the macros defined there. + + Example: + #include + + lis2dw12: lis2dw12@0 { + ... + + wakeup-duration = ; + ff-threshold = ; + tap-mode = ; + power-mode = ; + bw-filt = ; + }; + include: sensor-device.yaml properties: @@ -16,9 +33,8 @@ properties: int-pin: type: int default: 1 - enum: - - 1 - - 2 + enum: [1, 2] + description: | Select DRDY pin number (1 or 2). @@ -41,11 +57,7 @@ properties: 4 # 4g (0.488 mg/LSB) 2 # 2g (0.244 mg/LSB) - enum: - - 16 - - 8 - - 4 - - 2 + enum: [16, 8, 4, 2] odr: type: int @@ -56,17 +68,7 @@ properties: If 0 selected as the odr, the accelerometer initializes into power off state. - enum: - - 0 - - 1 - - 12 - - 25 - - 50 - - 100 - - 200 - - 400 - - 800 - - 1600 + enum: [0, 1, 12, 25, 50, 100, 200, 400, 800, 1600] bw-filt: type: int @@ -74,16 +76,12 @@ properties: description: | Digital filtering cutoff bandwidth. Default is power-up configuration. - 3 # ODR/20 (HP/LP) - 2 # ODR/10 (HP/LP) - 1 # ODR/ 4 (HP/LP) - 0 # ODR/ 2 (up to ODR = 800 Hz, 400 Hz when ODR = 1600 Hz) + - 0 # LIS2DW12_DT_FILTER_BW_ODR_DIV_2 + - 1 # LIS2DW12_DT_FILTER_BW_ODR_DIV_4 + - 2 # LIS2DW12_DT_FILTER_BW_ODR_DIV_10 + - 3 # LIS2DW12_DT_FILTER_BW_ODR_DIV_20 - enum: - - 3 - - 2 - - 1 - - 0 + enum: [0, 1, 2, 3] power-mode: type: int @@ -91,18 +89,13 @@ properties: description: | Specify the sensor power mode. Default is power-up configuration. - 0 # Low Power M1 - 1 # Low Power M2 - 2 # Low Power M3 - 3 # Low Power M4 - 4 # High Performance + - 0 # LIS2DW12_DT_LP_M1 + - 1 # LIS2DW12_DT_LP_M2 + - 2 # LIS2DW12_DT_LP_M3 + - 3 # LIS2DW12_DT_LP_M4 + - 4 # LIS2DW12_DT_HP_MODE - enum: - - 0 - - 1 - - 2 - - 3 - - 4 + enum: [0, 1, 2, 3, 4] # tap and tap-tap configuration section # All default values are selected to match the power-up values. @@ -114,12 +107,10 @@ properties: description: | Tap mode. Default is power-up configuration. - 0 # Only Single Tap - 1 # Single and Double Tap + - 0 # LIS2DW12_DT_SINGLE_TAP + - 1 # LIS2DW12_DT_SINGLE_DOUBLE_TAP - enum: - - 0 - - 1 + enum: [0, 1] tap-threshold: type: array @@ -228,24 +219,17 @@ properties: than the freefall threshold value for the freefall duration long, then a freefall trigger occurs. This value is 3 bits long. Default value chosen 3 (312 mg) refer to ST DT0100 design tip document. - 0 # ~156mg - 1 # ~219mg - 2 # ~250mg - 3 # ~312mg - 4 # ~344mg - 5 # ~406mg - 6 # ~469mg - 7 # ~500mg - - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 + + - 0 # LIS2DW12_DT_FF_THRESHOLD_156_mg + - 1 # LIS2DW12_DT_FF_THRESHOLD_219_mg + - 2 # LIS2DW12_DT_FF_THRESHOLD_250_mg + - 3 # LIS2DW12_DT_FF_THRESHOLD_312_mg + - 4 # LIS2DW12_DT_FF_THRESHOLD_344_mg + - 5 # LIS2DW12_DT_FF_THRESHOLD_406_mg + - 6 # LIS2DW12_DT_FF_THRESHOLD_469_mg + - 7 # LIS2DW12_DT_FF_THRESHOLD_500_mg + + enum: [0, 1, 2, 3, 4, 5, 6, 7] wakeup-duration: type: int @@ -257,8 +241,9 @@ properties: then a wakeup trigger occurs. This value is 2 bits long in the register and 1 LSB = 1 * 1/ODR. - enum: - - 0 - - 1 - - 2 - - 3 + - 0 # LIS2DW12_DT_WAKEUP_1_ODR + - 1 # LIS2DW12_DT_WAKEUP_2_ODR + - 2 # LIS2DW12_DT_WAKEUP_3_ODR + - 3 # LIS2DW12_DT_WAKEUP_4_ODR + + enum: [0, 1, 2, 3] diff --git a/include/zephyr/dt-bindings/sensor/lis2dw12.h b/include/zephyr/dt-bindings/sensor/lis2dw12.h new file mode 100644 index 00000000000..9e5892ec0a5 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lis2dw12.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DW12_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DW12_H_ + +/* power-modes */ +#define LIS2DW12_DT_LP_M1 0 +#define LIS2DW12_DT_LP_M2 1 +#define LIS2DW12_DT_LP_M3 2 +#define LIS2DW12_DT_LP_M4 3 +#define LIS2DW12_DT_HP_MODE 4 + +/* Filter bandwidth */ +#define LIS2DW12_DT_FILTER_BW_ODR_DIV_2 0 +#define LIS2DW12_DT_FILTER_BW_ODR_DIV_4 1 +#define LIS2DW12_DT_FILTER_BW_ODR_DIV_10 2 +#define LIS2DW12_DT_FILTER_BW_ODR_DIV_20 3 + +/* Tap mode */ +#define LIS2DW12_DT_SINGLE_TAP 0 +#define LIS2DW12_DT_SINGLE_DOUBLE_TAP 1 + +/* Free-Fall threshold */ +#define LIS2DW12_DT_FF_THRESHOLD_156_mg 0 +#define LIS2DW12_DT_FF_THRESHOLD_219_mg 1 +#define LIS2DW12_DT_FF_THRESHOLD_250_mg 2 +#define LIS2DW12_DT_FF_THRESHOLD_312_mg 3 +#define LIS2DW12_DT_FF_THRESHOLD_344_mg 4 +#define LIS2DW12_DT_FF_THRESHOLD_406_mg 5 +#define LIS2DW12_DT_FF_THRESHOLD_469_mg 6 +#define LIS2DW12_DT_FF_THRESHOLD_500_mg 7 + +/* wakeup duration */ +#define LIS2DW12_DT_WAKEUP_1_ODR 0 +#define LIS2DW12_DT_WAKEUP_2_ODR 1 +#define LIS2DW12_DT_WAKEUP_3_ODR 2 +#define LIS2DW12_DT_WAKEUP_4_ODR 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DW12_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 85313f211f2..2f686677162 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -298,6 +299,11 @@ test_i2c_lis2dw12: lis2dw12@2d { compatible = "st,lis2dw12"; reg = <0x2d>; irq-gpios = <&test_gpio 0 0>; + wakeup-duration = ; + ff-threshold = ; + tap-mode = ; + power-mode = ; + bw-filt = ; }; test_i2c_lis2mdl: lis2mdl@2e { From 0d68d9e493efe784c227a1eb1cd38178de27d836 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:29:40 +0100 Subject: [PATCH 3893/4498] dt-bindings: sensor: ism330dhcx: add macros for DT properties setting Add macros for setting in a clear way ism330dhcx DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,ism330dhcx-common.yaml | 128 ++++++++---------- .../zephyr/dt-bindings/sensor/ism330dhcx.h | 23 ++++ tests/drivers/build_all/sensor/i2c.dtsi | 3 + 3 files changed, 81 insertions(+), 73 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/ism330dhcx.h diff --git a/dts/bindings/sensor/st,ism330dhcx-common.yaml b/dts/bindings/sensor/st,ism330dhcx-common.yaml index 93d9be0890e..f00f37c1700 100644 --- a/dts/bindings/sensor/st,ism330dhcx-common.yaml +++ b/dts/bindings/sensor/st,ism330dhcx-common.yaml @@ -1,6 +1,20 @@ # Copyright (c) 2021 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-odr and gyro-odr properties in a .dts or .dtsi file you may include + st_ism330dhcx.h and use the macros defined there. + + Example: + #include + + ism330dhcx: ism330dhcx@0 { + ... + + accel-odr = ; + gyro-odr = ; + }; + include: sensor-device.yaml properties: @@ -27,9 +41,7 @@ properties: (INT1 or INT2) the drdy line is attached to. This property is not mandatory and if not present it defaults to 1 which is the configuration at power-up. - enum: - - 1 - - 2 + enum: [1, 2] accel-odr: type: int @@ -38,30 +50,20 @@ properties: Specify the default accelerometer output data rate expressed in samples per second (Hz). Default is power-up configuration. - Selection - 0 Power-Down - 1 12.5Hz - 2 26Hz - 3 52Hz - 4 104Hz - 5 208Hz - 6 416Hz - 7 833Hz - 8 1660Hz - 9 3330Hz - 10 6660Hz - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9 - - 10 + - 0 # ISM330DHCX_DT_ODR_OFF + - 1 # ISM330DHCX_DT_ODR_12Hz5 + - 2 # ISM330DHCX_DT_ODR_26H + - 3 # ISM330DHCX_DT_ODR_52Hz + - 4 # ISM330DHCX_DT_ODR_104Hz + - 5 # ISM330DHCX_DT_ODR_208Hz + - 6 # ISM330DHCX_DT_ODR_416Hz + - 7 # ISM330DHCX_DT_ODR_833Hz + - 8 # ISM330DHCX_DT_ODR_1666Hz + - 9 # ISM330DHCX_DT_ODR_3332Hz + - 10 # ISM330DHCX_DT_ODR_6667Hz + - 11 # ISM330DHCX_DT_ODR_1Hz6 + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] accel-range: type: int @@ -69,16 +71,12 @@ properties: description: | Range in g. Default is power-up configuration. - Selection - 16 16g (0.488 mg/LSB) - 8 8g (0.244 mg/LSB) - 4 4g (0.122 mg/LSB) - 2 2g (0.061 mg/LSB) - enum: - - 16 - - 8 - - 4 - - 2 + - 16 # 16g (0.488 mg/LSB) + - 8 # 8g (0.244 mg/LSB) + - 4 # 4g (0.122 mg/LSB) + - 2 # 2g (0.061 mg/LSB) + + enum: [16, 8, 4, 2] gyro-odr: type: int @@ -87,30 +85,19 @@ properties: Specify the default gyro output data rate expressed in samples per second (Hz). Default is power-up configuration. - Selection - 0 Power-Down - 1 12.5Hz - 2 26Hz - 3 52Hz - 4 104Hz - 5 208Hz - 6 416Hz - 7 833Hz - 8 1660Hz - 9 3330Hz - 10 6660Hz - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9 - - 10 + - 0 # ISM330DHCX_DT_ODR_OFF + - 1 # ISM330DHCX_DT_ODR_12Hz5 + - 2 # ISM330DHCX_DT_ODR_26H + - 3 # ISM330DHCX_DT_ODR_52Hz + - 4 # ISM330DHCX_DT_ODR_104Hz + - 5 # ISM330DHCX_DT_ODR_208Hz + - 6 # ISM330DHCX_DT_ODR_416Hz + - 7 # ISM330DHCX_DT_ODR_833Hz + - 8 # ISM330DHCX_DT_ODR_1666Hz + - 9 # ISM330DHCX_DT_ODR_3332Hz + - 10 # ISM330DHCX_DT_ODR_6667Hz + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] gyro-range: type: int @@ -118,15 +105,10 @@ properties: description: | Range in dps. Default is power-up configuration. - Selection - 125 +/- 125dps - 250 +/- 250dps - 500 +/- 500dps - 1000 +/- 1000dps - 2000 +/- 2000dps - enum: - - 125 - - 250 - - 500 - - 1000 - - 2000 + - 125 # +/- 125dps + - 250 # +/- 250dps + - 500 # +/- 500dps + - 1000 # +/- 1000dps + - 2000 # +/- 2000dps + + enum: [125, 250, 500, 1000, 2000] diff --git a/include/zephyr/dt-bindings/sensor/ism330dhcx.h b/include/zephyr/dt-bindings/sensor/ism330dhcx.h new file mode 100644 index 00000000000..7d857eb165a --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/ism330dhcx.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM330DHCX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM330DHCX_H_ + +/* Accel and Gyro Data rates */ +#define ISM330DHCX_DT_ODR_OFF 0x0 +#define ISM330DHCX_DT_ODR_12Hz5 0x1 +#define ISM330DHCX_DT_ODR_26H 0x2 +#define ISM330DHCX_DT_ODR_52Hz 0x3 +#define ISM330DHCX_DT_ODR_104Hz 0x4 +#define ISM330DHCX_DT_ODR_208Hz 0x5 +#define ISM330DHCX_DT_ODR_416Hz 0x6 +#define ISM330DHCX_DT_ODR_833Hz 0x7 +#define ISM330DHCX_DT_ODR_1666Hz 0x8 +#define ISM330DHCX_DT_ODR_3332Hz 0x9 +#define ISM330DHCX_DT_ODR_6667Hz 0xa +#define ISM330DHCX_DT_ODR_1Hz6 0xb + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM330DHCX_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 2f686677162..b054a0b2def 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -271,6 +272,8 @@ test_i2c_ism330dhcx: ism330dhcx@29 { compatible = "st,ism330dhcx"; reg = <0x29>; drdy-gpios = <&test_gpio 0 0>; + accel-odr = ; + gyro-odr = ; }; test_i2c_lis2dh: lis2dh@2a { From 6e09f91fec00c0bcdfc8ea4a9be5529c6453d3ec Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 11:31:10 +0100 Subject: [PATCH 3894/4498] dt-bindings: sensor: iis2dlpc: add macros for DT properties setting Add macros for setting in a clear way iis2dlpc DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,iis2dlpc-common.yaml | 59 ++++++++++++++------ include/zephyr/dt-bindings/sensor/iis2dlpc.h | 42 ++++++++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 3 + 3 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/iis2dlpc.h diff --git a/dts/bindings/sensor/st,iis2dlpc-common.yaml b/dts/bindings/sensor/st,iis2dlpc-common.yaml index 36c258df4b1..997b0b189f0 100644 --- a/dts/bindings/sensor/st,iis2dlpc-common.yaml +++ b/dts/bindings/sensor/st,iis2dlpc-common.yaml @@ -1,6 +1,20 @@ # Copyright (c) 2018 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the odr property in a .dts or .dtsi file you may include + st_iis2dlpc.h and use the macros defined there. + + Example: + #include + + iis2dlpc: iis2dlpc@0 { + ... + + tap-mode = ; + power-mode = ; + }; + include: sensor-device.yaml properties: @@ -16,36 +30,44 @@ properties: drdy-int: type: int default: 1 - enum: - - 1 # drdy is generated from INT1 - - 2 # drdy is generated from INT2 - description: Select DRDY pin number (1 or 2). + enum: [1, 2] + description: | + Select DRDY pin number (1 or 2). This number represents which of the two interrupt pins (INT1 or INT2) the drdy line is attached to. This property is not mandatory and if not present it defaults to 1 which is the configuration at power-up. + - 1 # drdy is generated from INT1 + - 2 # drdy is generated from INT2 + range: type: int default: 2 - description: Range in g. Default is power-up configuration. - enum: + description: | + Range in g. Default is power-up configuration. + - 16 # 16g (1.952 mg/LSB) - 8 # 8g (0.976 mg/LSB) - 4 # 4g (0.488 mg/LSB) - 2 # 2g (0.244 mg/LSB) + enum: [16, 8, 4, 2] + power-mode: type: int default: 0 - description: Specify the sensor power mode. Default is power-up configuration. - enum: - - 0 # Low Power M1 - - 1 # Low Power M2 - - 2 # Low Power M3 - - 3 # Low Power M4 - - 4 # High Performance + description: | + Specify the sensor power mode. Default is power-up configuration. + + - 0 # IIS2DLPC_DT_LP_M1 + - 1 # IIS2DLPC_DT_LP_M2 + - 2 # IIS2DLPC_DT_LP_M3 + - 3 # IIS2DLPC_DT_LP_M4 + - 4 # IIS2DLPC_DT_HP_MODE + + enum: [0, 1, 2, 3, 4] # tap and tap-tap configuration section # All default values are selected to match the power-up values. @@ -54,10 +76,13 @@ properties: tap-mode: type: int default: 0 - description: Tap mode. Default is power-up configuration. - enum: - - 0 # Only Single Tap - - 1 # Single and Double Tap + description: | + Tap mode. Default is power-up configuration. + + - 0 # IIS2DLPC_DT_SINGLE_TAP + - 1 # IIS2DLPC_DT_SINGLE_DOUBLE_TAP + + enum: [0, 1] tap-threshold: type: array diff --git a/include/zephyr/dt-bindings/sensor/iis2dlpc.h b/include/zephyr/dt-bindings/sensor/iis2dlpc.h new file mode 100644 index 00000000000..abf6df1cc44 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/iis2dlpc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2DLPC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2DLPC_H_ + +/* power-modes */ +#define IIS2DLPC_DT_LP_M1 0 +#define IIS2DLPC_DT_LP_M2 1 +#define IIS2DLPC_DT_LP_M3 2 +#define IIS2DLPC_DT_LP_M4 3 +#define IIS2DLPC_DT_HP_MODE 4 + +/* Filter bandwidth */ +#define IIS2DLPC_DT_FILTER_BW_ODR_DIV_2 0 +#define IIS2DLPC_DT_FILTER_BW_ODR_DIV_4 1 +#define IIS2DLPC_DT_FILTER_BW_ODR_DIV_10 2 +#define IIS2DLPC_DT_FILTER_BW_ODR_DIV_20 3 + +/* Tap mode */ +#define IIS2DLPC_DT_SINGLE_TAP 0 +#define IIS2DLPC_DT_SINGLE_DOUBLE_TAP 1 + +/* Free-Fall threshold */ +#define IIS2DLPC_DT_FF_THRESHOLD_156_mg 0 +#define IIS2DLPC_DT_FF_THRESHOLD_219_mg 1 +#define IIS2DLPC_DT_FF_THRESHOLD_250_mg 2 +#define IIS2DLPC_DT_FF_THRESHOLD_312_mg 3 +#define IIS2DLPC_DT_FF_THRESHOLD_344_mg 4 +#define IIS2DLPC_DT_FF_THRESHOLD_406_mg 5 +#define IIS2DLPC_DT_FF_THRESHOLD_469_mg 6 +#define IIS2DLPC_DT_FF_THRESHOLD_500_mg 7 + +/* wakeup duration */ +#define IIS2DLPC_DT_WAKEUP_1_ODR 0 +#define IIS2DLPC_DT_WAKEUP_2_ODR 1 +#define IIS2DLPC_DT_WAKEUP_3_ODR 2 +#define IIS2DLPC_DT_WAKEUP_4_ODR 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2DLPC_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b054a0b2def..a10717f8e37 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -260,6 +261,8 @@ test_i2c_iis2dlpc: iis2dlpc@27 { compatible = "st,iis2dlpc"; reg = <0x27>; drdy-gpios = <&test_gpio 0 0>; + tap-mode = ; + power-mode = ; }; test_i2c_iis2mdc: iis2mdc@28 { From 273475804e2152b7697f318abb55cd2e135e5742 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 12:21:55 +0100 Subject: [PATCH 3895/4498] dt-bindings: sensor: lis2dh: add macros for DT properties setting Add macros for setting in a clear way lis2dh DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,lis2dh-common.yaml | 72 ++++++++++++---------- include/zephyr/dt-bindings/sensor/lis2dh.h | 22 +++++++ tests/drivers/build_all/sensor/i2c.dtsi | 4 ++ 3 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lis2dh.h diff --git a/dts/bindings/sensor/st,lis2dh-common.yaml b/dts/bindings/sensor/st,lis2dh-common.yaml index 7ba07fc4b12..351fa0dc97f 100644 --- a/dts/bindings/sensor/st,lis2dh-common.yaml +++ b/dts/bindings/sensor/st,lis2dh-common.yaml @@ -1,6 +1,21 @@ # Copyright (c) 2018 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the int1-gpio-config/int2-gpio-config and anym-mode properties + in a .dts or .dtsi file you may include st_lis2dh.h and use the macros defined there. + + Example: + #include + + lis2dh: lis2dh@0 { + ... + + int1-gpio-config = ; + int2-gpio-config = ; + anym-mode = ; + }; + include: sensor-device.yaml properties: @@ -16,20 +31,16 @@ properties: description: | Select the interrupt configuration for INT1 gpio. - 0 = GPIO_INT_EDGE - 1 = GPIO_INT_EDGE_RISING - 2 = GPIO_INT_EDGE_FALLING - 3 = GPIO_INT_LEVEL_HIGH - 4 = GPIO_INT_LEVEL_LOW - The default of 0 is the most common situation to avoid multiple interrupts to be triggered by same event. - enum: - - 0 - - 1 - - 2 - - 3 - - 4 + + - 0 # LIS2DH_DT_GPIO_INT_EDGE + - 1 # LIS2DH_DT_GPIO_INT_EDGE_RISING + - 2 # LIS2DH_DT_GPIO_INT_EDGE_FALLING + - 3 # LIS2DH_DT_GPIO_INT_LEVEL_HIGH + - 4 # LIS2DH_DT_GPIO_INT_LEVEL_LOW + + enum: [0, 1, 2, 3, 4] int2-gpio-config: type: int @@ -37,20 +48,16 @@ properties: description: | Select the interrupt configuration for INT2 gpio. - 0 = GPIO_INT_EDGE - 1 = GPIO_INT_EDGE_RISING - 2 = GPIO_INT_EDGE_FALLING - 3 = GPIO_INT_LEVEL_HIGH - 4 = GPIO_INT_LEVEL_LOW - The default of 0 is the most common situation to avoid multiple interrupts to be triggered by same event. - enum: - - 0 - - 1 - - 2 - - 3 - - 4 + + - 0 # LIS2DH_DT_GPIO_INT_EDGE + - 1 # LIS2DH_DT_GPIO_INT_EDGE_RISING + - 2 # LIS2DH_DT_GPIO_INT_EDGE_FALLING + - 3 # LIS2DH_DT_GPIO_INT_LEVEL_HIGH + - 4 # LIS2DH_DT_GPIO_INT_LEVEL_LOW + + enum: [0, 1, 2, 3, 4] disconnect-sdo-sa0-pull-up: type: boolean @@ -78,14 +85,11 @@ properties: description: | Select the interrupt mode for any movement. - 0 = OR combination of interrupt events - 1 = 6D movement recognition - 2 = AND combination of interrupt events - 3 = 6D position recognition - The default of 0 is the power-on-reset value. - enum: - - 0 - - 1 - - 2 - - 3 + + - 0 # LIS2DH_DT_ANYM_OR_COMBINATION + - 1 # LIS2DH_DT_ANYM_6D_MOVEMENT + - 2 # LIS2DH_DT_ANYM_AND_COMBINATION + - 3 # LIS2DH_DT_ANYM_6D_POSITION + + enum: [0, 1, 2, 3] diff --git a/include/zephyr/dt-bindings/sensor/lis2dh.h b/include/zephyr/dt-bindings/sensor/lis2dh.h new file mode 100644 index 00000000000..a697f34cc80 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lis2dh.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DH_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DH_H_ + +/* GPIO interrupt configuration */ +#define LIS2DH_DT_GPIO_INT_EDGE 0 +#define LIS2DH_DT_GPIO_INT_EDGE_RISING 1 +#define LIS2DH_DT_GPIO_INT_EDGE_FALLING 2 +#define LIS2DH_DT_GPIO_INT_LEVEL_HIGH 3 +#define LIS2DH_DT_GPIO_INT_LEVEL_LOW 4 + +/* Any Motion mode */ +#define LIS2DH_DT_ANYM_OR_COMBINATION 0 +#define LIS2DH_DT_ANYM_6D_MOVEMENT 1 +#define LIS2DH_DT_ANYM_AND_COMBINATION 2 +#define LIS2DH_DT_ANYM_6D_POSITION 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DH_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index a10717f8e37..b858e9bbb2f 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -15,6 +15,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -284,6 +285,9 @@ test_i2c_lis2dh: lis2dh@2a { reg = <0x2a>; irq-gpios = <&test_gpio 0 0>; /* disconnect-sdo-sa0-pull-up; */ + int1-gpio-config = ; + int2-gpio-config = ; + anym-mode = ; }; test_i2c_lis2dh12: lis2dh12@2b { From 194ee015f92b7d069c16cc8badf95225712b6b59 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 12:41:22 +0100 Subject: [PATCH 3896/4498] dt-bindings: sensor: iis2iclx: add macros for DT property setting Add macros for setting in a clear way iis2iclx DT properties. Signed-off-by: Armando Visconti --- dts/bindings/sensor/st,iis2iclx-common.yaml | 67 +++++++++++++------- include/zephyr/dt-bindings/sensor/iis2iclx.h | 25 ++++++++ tests/drivers/build_all/sensor/i2c.dtsi | 3 + 3 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/iis2iclx.h diff --git a/dts/bindings/sensor/st,iis2iclx-common.yaml b/dts/bindings/sensor/st,iis2iclx-common.yaml index 9551c274ae1..0a312824c98 100644 --- a/dts/bindings/sensor/st,iis2iclx-common.yaml +++ b/dts/bindings/sensor/st,iis2iclx-common.yaml @@ -1,12 +1,27 @@ # Copyright (c) 2020 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the range, odr properties in a .dts or .dtsi file you may + include st_iis2iclx.h and use the macros defined there. + + Example: + #include + + iis2iclx: iis2iclx@0 { + ... + + range = ; + odr = ; + }; + include: sensor-device.yaml properties: drdy-gpios: type: phandle-array - description: DRDY pin + description: | + DRDY pin This pin defaults to active high when produced by the sensor. The property value should ensure the flags properly describe @@ -15,41 +30,45 @@ properties: int-pin: type: int default: 1 - enum: - - 1 # drdy is generated from INT1 - - 2 # drdy is generated from INT2 - description: Select DRDY pin number (1 or 2). + enum: [1, 2] + description: | + Select DRDY pin number (1 or 2). This number represents which of the two interrupt pins (INT1 or INT2) the drdy line is attached to. This property is not mandatory and if not present it defaults to 1 which is the configuration at power-up. + - 1 # drdy is generated from INT1 + - 2 # drdy is generated from INT2 + range: type: int default: 3 - description: Range in g. Default is power-up configuration. - enum: - - 0 # 500mg (0.015 mg/LSB) - - 1 # 3g (0.122 mg/LSB) - - 2 # 1g (0.031 mg/LSB) - - 3 # 2g (0.061 mg/LSB) + description: | + Range in g. Default is power-up configuration. + + - 0 # IIS2ICLX_DT_FS_500mG (0.015 mg/LSB) + - 1 # IIS2ICLX_DT_FS_3G (0.122 mg/LSB) + - 2 # IIS2ICLX_DT_FS_1G (0.031 mg/LSB) + - 3 # IIS2ICLX_DT_FS_2G (0.061 mg/LSB) + + enum: [0, 1, 2, 3] odr: type: int default: 0 - description: + description: | Specify the default accelerometer output data rate expressed in samples per second (Hz). Default is power-up configuration. - enum: - - 0 # Power-Down - - 1 # 12.5Hz - - 2 # 26Hz - - 3 # 52Hz - - 4 # 104Hz - - 5 # 208Hz - - 6 # 416Hz - - 7 # 833Hz - - 8 # 1660Hz - - 9 # 3330Hz - - 10 # 6660Hz + + - 0 # IIS2ICLX_DT_ODR_OFF + - 1 # IIS2ICLX_DT_ODR_12Hz5 + - 2 # IIS2ICLX_DT_ODR_26H + - 3 # IIS2ICLX_DT_ODR_52Hz + - 4 # IIS2ICLX_DT_ODR_104Hz + - 5 # IIS2ICLX_DT_ODR_208Hz + - 6 # IIS2ICLX_DT_ODR_416Hz + - 7 # IIS2ICLX_DT_ODR_833Hz + + enum: [0, 1, 2, 3, 4, 5, 6, 7] diff --git a/include/zephyr/dt-bindings/sensor/iis2iclx.h b/include/zephyr/dt-bindings/sensor/iis2iclx.h new file mode 100644 index 00000000000..544486e0984 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/iis2iclx.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2ICLX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2ICLX_H_ + +/* Accel range */ +#define IIS2ICLX_DT_FS_500mG 0 +#define IIS2ICLX_DT_FS_3G 1 +#define IIS2ICLX_DT_FS_1G 2 +#define IIS2ICLX_DT_FS_2G 3 + +/* Accel Data rates */ +#define IIS2ICLX_DT_ODR_OFF 0x0 +#define IIS2ICLX_DT_ODR_12Hz5 0x1 +#define IIS2ICLX_DT_ODR_26H 0x2 +#define IIS2ICLX_DT_ODR_52Hz 0x3 +#define IIS2ICLX_DT_ODR_104Hz 0x4 +#define IIS2ICLX_DT_ODR_208Hz 0x5 +#define IIS2ICLX_DT_ODR_416Hz 0x6 +#define IIS2ICLX_DT_ODR_833Hz 0x7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_IIS2ICLX_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b858e9bbb2f..6ad5ac8703e 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -16,6 +16,7 @@ #include #include #include +#include /**************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * @@ -504,6 +505,8 @@ test_i2c_iis2iclx: iis2iclx@4c { reg = <0x4c>; drdy-gpios = <&test_gpio 0 0>; int-pin = <1>; + range = ; + odr = ; }; test_i2c_wsen_hids: wsen_hids@4d { From 237891973bcc95bd4bdfb7f2a5acc32250f29add Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Fri, 17 Nov 2023 17:35:27 +0100 Subject: [PATCH 3897/4498] doc: migration-guide-3.6.rst: recommend use of DT macros for ST sensors Recommend use of DT macros for ST sensors as described in #65410. Signed-off-by: Armando Visconti --- doc/releases/migration-guide-3.6.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index 5728d339984..c4b93e5f150 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -153,3 +153,7 @@ Other Subsystems Recommended Changes ******************* + +* New macros available for ST sensor DT properties setting. These macros have a self-explanatory + name that helps in recognizing what the property setting means (e.g. LSM6DSV16X_DT_ODR_AT_60Hz). + (:github:`65410`) From 8a75a4b9dbba7442c21a579f1a5f3cdf6e5d74bb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 Nov 2023 14:09:50 +0100 Subject: [PATCH 3898/4498] net: shell: Fix array indexing with dynamic iface command Network interface numbering starts from 1, therefore when accessing help/index array, the interface index should not be used directly, but rather decremented by 1, to avoid out-of-bound access on those arrays. Signed-off-by: Robert Lubos --- subsys/net/lib/shell/iface_dynamic.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/net/lib/shell/iface_dynamic.h b/subsys/net/lib/shell/iface_dynamic.h index df62ad1eb36..d10e25e1c1b 100644 --- a/subsys/net/lib/shell/iface_dynamic.h +++ b/subsys/net/lib/shell/iface_dynamic.h @@ -32,9 +32,9 @@ static char *set_iface_index_buffer(size_t idx) return NULL; } - snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%d", (uint8_t)idx); + snprintk(iface_index_buffer[idx - 1], MAX_IFACE_STR_LEN, "%d", (uint8_t)idx); - return iface_index_buffer[idx]; + return iface_index_buffer[idx - 1]; } static char *set_iface_index_help(size_t idx) @@ -56,14 +56,14 @@ static char *set_iface_index_help(size_t idx) net_if_get_name(iface, name, CONFIG_NET_INTERFACE_NAME_LEN); name[CONFIG_NET_INTERFACE_NAME_LEN] = '\0'; - snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + snprintk(iface_help_buffer[idx - 1], MAX_IFACE_HELP_STR_LEN, "%s [%s] (%p)", name, iface2str(iface, NULL), iface); #else - snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN, + snprintk(iface_help_buffer[idx - 1], MAX_IFACE_HELP_STR_LEN, "[%s] (%p)", iface2str(iface, NULL), iface); #endif - return iface_help_buffer[idx]; + return iface_help_buffer[idx - 1]; } static void iface_index_get(size_t idx, struct shell_static_entry *entry) From 0aa6f3f3ffda64af4733c13b3d8c234deaac283c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Sat, 18 Nov 2023 11:41:58 +0100 Subject: [PATCH 3899/4498] modem: cmux: Fix coverity issues Possible NULL pointer dereferences where discovered by static code analysis, they are addressed in this commit. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/modem_cmux.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 19df0509d6c..9c95e124fc2 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -805,6 +805,10 @@ static void modem_cmux_connect_handler(struct k_work *item) struct k_work_delayable *dwork = k_work_delayable_from_work(item); struct modem_cmux *cmux = CONTAINER_OF(dwork, struct modem_cmux, connect_work); + if (cmux == NULL) { + return; + } + cmux->state = MODEM_CMUX_STATE_CONNECTING; struct modem_cmux_frame frame = { @@ -914,6 +918,10 @@ static void modem_cmux_dlci_open_handler(struct k_work *item) struct k_work_delayable *dwork = k_work_delayable_from_work(item); struct modem_cmux_dlci *dlci = CONTAINER_OF(dwork, struct modem_cmux_dlci, open_work); + if (dlci == NULL) { + return; + } + dlci->state = MODEM_CMUX_DLCI_STATE_OPENING; struct modem_cmux_frame frame = { @@ -935,6 +943,10 @@ static void modem_cmux_dlci_close_handler(struct k_work *item) struct modem_cmux_dlci *dlci = CONTAINER_OF(dwork, struct modem_cmux_dlci, close_work); struct modem_cmux *cmux = dlci->cmux; + if (cmux == NULL) { + return; + } + dlci->state = MODEM_CMUX_DLCI_STATE_CLOSING; struct modem_cmux_frame frame = { From 8c607bf401775424b3af6f4194ba38522bb2b3ed Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Fri, 13 Oct 2023 15:20:35 -0400 Subject: [PATCH 3900/4498] drivers: can: mcp251xfd: Increase max filters and change filter usage type The mcp251xfd supports upto 32 filters. Also store the filter usage in uint32_t instead of uint64_t. Signed-off-by: Andriy Gelman --- drivers/can/Kconfig.mcp251xfd | 2 +- drivers/can/can_mcp251xfd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/can/Kconfig.mcp251xfd b/drivers/can/Kconfig.mcp251xfd index 8e6cb5ad91c..128becf8e95 100644 --- a/drivers/can/Kconfig.mcp251xfd +++ b/drivers/can/Kconfig.mcp251xfd @@ -54,7 +54,7 @@ config CAN_MCP251XFD_READ_CRC_RETRIES config CAN_MAX_FILTER int "Maximum number of concurrent active filters" default 5 - range 1 31 + range 1 32 help Maximum number of filters supported by the can_add_rx_callback() API call. diff --git a/drivers/can/can_mcp251xfd.h b/drivers/can/can_mcp251xfd.h index f0414103bed..b87c6ae53dd 100644 --- a/drivers/can/can_mcp251xfd.h +++ b/drivers/can/can_mcp251xfd.h @@ -496,7 +496,7 @@ struct mcp251xfd_data { struct mcp251xfd_mailbox mailbox[CONFIG_CAN_MCP251XFD_MAX_TX_QUEUE]; /* Filter Data */ - uint64_t filter_usage; + uint32_t filter_usage; struct can_filter filter[CONFIG_CAN_MAX_FILTER]; can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; void *cb_arg[CONFIG_CAN_MAX_FILTER]; From 1282194ac549fea1990ea0a028af4ecc870093fc Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Fri, 13 Oct 2023 15:33:01 -0400 Subject: [PATCH 3901/4498] drivers: can: mcp251xfd: Skip payload in spi transfer when RTR flag is set There's no need to transfer the payload bytes when the RTR flag set. Signed-off-by: Andriy Gelman --- drivers/can/can_mcp251xfd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c index 3f94ed52319..7b788ec2b6c 100644 --- a/drivers/can/can_mcp251xfd.c +++ b/drivers/can/can_mcp251xfd.c @@ -191,8 +191,10 @@ static int mcp251xfd_fifo_write(const struct device *dev, int mailbox_idx, txobj = mcp251xfd_get_spi_buf_ptr(dev); mcp251xfd_canframe_to_txobj(msg, mailbox_idx, txobj); - tx_len = MCP251XFD_OBJ_HEADER_SIZE + - ROUND_UP(can_dlc_to_bytes(msg->dlc), MCP251XFD_RAM_ALIGNMENT); + tx_len = MCP251XFD_OBJ_HEADER_SIZE; + if ((msg->flags & CAN_FRAME_RTR) == 0) { + tx_len += ROUND_UP(can_dlc_to_bytes(msg->dlc), MCP251XFD_RAM_ALIGNMENT); + } ret = mcp251xfd_write(dev, address, tx_len); if (ret < 0) { From 85a1124d5d30a43634870004ca7c42db726c9157 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Thu, 9 Nov 2023 18:50:28 +0200 Subject: [PATCH 3902/4498] soc: xtensa: imx8m: Remove unused file Remove platform.h since is no longer used for SOF. Move memory.h to include folder and modify the linker to reflect this. Signed-off-by: Iuliana Prodan --- .../nxp_adsp/imx8m/include/{soc => }/memory.h | 0 .../nxp_adsp/imx8m/include/soc/platform.h | 21 ------------------- soc/xtensa/nxp_adsp/imx8m/linker.ld | 4 ++-- 3 files changed, 2 insertions(+), 23 deletions(-) rename soc/xtensa/nxp_adsp/imx8m/include/{soc => }/memory.h (100%) delete mode 100644 soc/xtensa/nxp_adsp/imx8m/include/soc/platform.h diff --git a/soc/xtensa/nxp_adsp/imx8m/include/soc/memory.h b/soc/xtensa/nxp_adsp/imx8m/include/memory.h similarity index 100% rename from soc/xtensa/nxp_adsp/imx8m/include/soc/memory.h rename to soc/xtensa/nxp_adsp/imx8m/include/memory.h diff --git a/soc/xtensa/nxp_adsp/imx8m/include/soc/platform.h b/soc/xtensa/nxp_adsp/imx8m/include/soc/platform.h deleted file mode 100644 index 2af652c0cc8..00000000000 --- a/soc/xtensa/nxp_adsp/imx8m/include/soc/platform.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2021 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __PLATFORM_PLATFORM_H__ -#define __PLATFORM_PLATFORM_H__ - -#define PLATFORM_PRIMARY_CORE_ID 0 - -#define MAX_CORE_COUNT 1 - -#if PLATFORM_CORE_COUNT > MAX_CORE_COUNT -#error "Invalid core count - exceeding core limit" -/* IPC Interrupt */ -#define PLATFORM_IPC_INTERRUPT IRQ_NUM_MU -#define PLATFORM_IPC_INTERRUPT_NAME NULL -#endif - -#endif /* __PLATFORM_PLATFORM_H__ */ diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index aab0a0b6548..235e5a6f264 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 NXP + * Copyright 2021, 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ OUTPUT_ARCH(xtensa) #include #include -#include +#include #include #include From afc3606116b319dd27ef75f8f6ebc679a4a62d8f Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Thu, 9 Nov 2023 19:06:23 +0200 Subject: [PATCH 3903/4498] soc: xtensa: imx8m: Remove unused definitions Remove unused macro definitions. While here, use Zephyr's convention for include guard. Signed-off-by: Iuliana Prodan --- soc/xtensa/nxp_adsp/imx8m/include/memory.h | 63 +++------------------- 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/soc/xtensa/nxp_adsp/imx8m/include/memory.h b/soc/xtensa/nxp_adsp/imx8m/include/memory.h index e93617addb5..e882f49a435 100644 --- a/soc/xtensa/nxp_adsp/imx8m/include/memory.h +++ b/soc/xtensa/nxp_adsp/imx8m/include/memory.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2021 NXP + * Copyright 2021, 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __INC_MEMORY_H -#define __INC_MEMORY_H +#ifndef ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ +#define ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ #define PLATFORM_CORE_COUNT 1 @@ -163,56 +163,7 @@ #define SRAM_TRACE_OFFSET (SRAM_STREAM_OFFSET + SRAM_STREAM_SIZE) #define SOF_MAILBOX_SIZE (SRAM_INBOX_SIZE + SRAM_OUTBOX_SIZE \ - + SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE \ - + SRAM_STREAM_SIZE + SRAM_TRACE_SIZE) - -/* Heap section sizes for module pool */ -#define HEAP_RT_COUNT8 0 -#define HEAP_RT_COUNT16 48 -#define HEAP_RT_COUNT32 48 -#define HEAP_RT_COUNT64 32 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 32 -#define HEAP_RT_COUNT512 4 -#define HEAP_RT_COUNT1024 4 -#define HEAP_RT_COUNT2048 4 -#define HEAP_RT_COUNT4096 4 - -/* Heap section sizes for system runtime heap */ -#define HEAP_SYS_RT_COUNT64 128 -#define HEAP_SYS_RT_COUNT512 16 -#define HEAP_SYS_RT_COUNT1024 8 - -/* Heap configuration */ -#define HEAP_SYSTEM_BASE SDRAM1_BASE + SOF_MAILBOX_SIZE -#define HEAP_SYSTEM_SIZE 0xe000 -#define HEAP_SYSTEM_0_BASE HEAP_SYSTEM_BASE - -#define HEAP_SYS_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) -#define HEAP_SYS_RUNTIME_SIZE \ - (HEAP_SYS_RT_COUNT64 * 64 + HEAP_SYS_RT_COUNT512 * 512 + \ - HEAP_SYS_RT_COUNT1024 * 1024) - -#define HEAP_RUNTIME_BASE (HEAP_SYS_RUNTIME_BASE + HEAP_SYS_RUNTIME_SIZE) -#define HEAP_RUNTIME_SIZE \ - (HEAP_RT_COUNT8 * 8 + HEAP_RT_COUNT16 * 16 + \ - HEAP_RT_COUNT32 * 32 + HEAP_RT_COUNT64 * 64 + \ - HEAP_RT_COUNT128 * 128 + HEAP_RT_COUNT256 * 256 + \ - HEAP_RT_COUNT512 * 512 + HEAP_RT_COUNT1024 * 1024 + \ - HEAP_RT_COUNT2048 * 2048 + HEAP_RT_COUNT4096 * 4096) - -#define HEAP_BUFFER_BASE (HEAP_RUNTIME_BASE + HEAP_RUNTIME_SIZE) -#define HEAP_BUFFER_SIZE \ - (SDRAM1_SIZE - SOF_MAILBOX_SIZE - HEAP_RUNTIME_SIZE - SOF_STACK_TOTAL_SIZE -\ - HEAP_SYS_RUNTIME_SIZE - HEAP_SYSTEM_SIZE) - -/* Stack configuration */ -#define SOF_STACK_SIZE 0x1000 -#define SOF_STACK_TOTAL_SIZE SOF_STACK_SIZE -#define SOF_STACK_BASE (SDRAM1_BASE + SDRAM1_SIZE) -#define SOF_STACK_END (SOF_STACK_BASE - SOF_STACK_TOTAL_SIZE) - -/* Host page size */ -#define HOST_PAGE_SIZE 4096 - -#endif /* __INC_MEMORY_H */ + + SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE \ + + SRAM_STREAM_SIZE + SRAM_TRACE_SIZE) + +#endif /* ZEPHYR_SOC_NXP_ADSP_MEMORY_H_ */ From edc0b7f3527834b0a8bdb2716fb088d7146f1c4a Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Thu, 9 Nov 2023 19:17:41 +0200 Subject: [PATCH 3904/4498] board: xtensa: imx8m: Remove unnecessary configs Remove unnecessary configs. Some were moved to Kconfig.series from soc/. Signed-off-by: Iuliana Prodan --- .../xtensa/nxp_adsp_imx8m/Kconfig.defconfig | 12 +----------- .../nxp_adsp_imx8m/nxp_adsp_imx8m_defconfig | 19 +++++-------------- .../nxp_adsp/imx8m/Kconfig.defconfig.series | 11 +++++++---- soc/xtensa/nxp_adsp/imx8m/Kconfig.series | 2 ++ 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/boards/xtensa/nxp_adsp_imx8m/Kconfig.defconfig b/boards/xtensa/nxp_adsp_imx8m/Kconfig.defconfig index 628c8bfd0b4..344449dd744 100644 --- a/boards/xtensa/nxp_adsp_imx8m/Kconfig.defconfig +++ b/boards/xtensa/nxp_adsp_imx8m/Kconfig.defconfig @@ -1,4 +1,4 @@ -# Copyright (c) 2021 NXP +# Copyright 2021, 2023 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -7,14 +7,4 @@ if BOARD_NXP_ADSP_IMX8M config BOARD default "nxp_adsp_imx8m" -config DUMMY_DMA - bool - default y - depends on DMA - -config IMX_SDMA - bool - default y - depends on DMA - endif # BOARD_NXP_ADSP_IMX8M diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_defconfig b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_defconfig index f3b4ca76cbe..72ccd09f55a 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_defconfig +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_defconfig @@ -1,27 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=3072 - CONFIG_SOC_SERIES_NXP_IMX8M=y CONFIG_SOC_MIMX8M_ADSP=y CONFIG_BOARD_NXP_ADSP_IMX8M=y -CONFIG_GEN_ISR_TABLES=y -CONFIG_GEN_IRQ_VECTOR_TABLE=n - -CONFIG_XTENSA_RESET_VECTOR=y - -CONFIG_XTENSA_USE_CORE_CRT1=y - -CONFIG_XTENSA_SMALL_VECTOR_TABLE_ENTRY=y +# size of stack for initialization and main thread +CONFIG_MAIN_STACK_SIZE=3072 -CONFIG_MULTI_LEVEL_INTERRUPTS=n -CONFIG_2ND_LEVEL_INTERRUPTS=n +# enable logger +CONFIG_LOG=y +# no need for a "raw" binary zephyr/zephyr.bin in the build directory CONFIG_BUILD_OUTPUT_BIN=n -CONFIG_DCACHE_LINE_SIZE=128 - # enable uart driver CONFIG_SERIAL=y diff --git a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series index d0fc446b4b0..2d00a5e93d9 100644 --- a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series @@ -11,7 +11,7 @@ config SOC_TOOLCHAIN_NAME string default "nxp_imx8m_adsp" -# if SOC_MIMX8M_ADSP +if SOC_MIMX8M_ADSP config SOC string @@ -23,12 +23,15 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config SYS_CLOCK_TICKS_PER_SEC default 50000 +config DCACHE_LINE_SIZE + default 128 + config DYNAMIC_INTERRUPTS default y -config LOG - default y +config GEN_IRQ_VECTOR_TABLE + default n -# endif # SOC_MIMX8M_ADSP +endif # SOC_MIMX8M_ADSP endif # SOC_SERIES_NXP_IMX8M diff --git a/soc/xtensa/nxp_adsp/imx8m/Kconfig.series b/soc/xtensa/nxp_adsp/imx8m/Kconfig.series index eda7d03ae5e..3847f52d2da 100644 --- a/soc/xtensa/nxp_adsp/imx8m/Kconfig.series +++ b/soc/xtensa/nxp_adsp/imx8m/Kconfig.series @@ -9,5 +9,7 @@ config SOC_SERIES_NXP_IMX8M select XTENSA_RESET_VECTOR select XTENSA_USE_CORE_CRT1 select ATOMIC_OPERATIONS_BUILTIN + select GEN_ISR_TABLES + select XTENSA_SMALL_VECTOR_TABLE_ENTRY help Enable support for NXP i.MX8M Audio DSP From 7c55eb5dfa10f01e4464abb4264770e65a291093 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:00:00 +0200 Subject: [PATCH 3905/4498] board: xtensa: imx8m: Remove unnecessary keyword Remove /omit-if-no-ref/ since it doesn't apply here. This is used for pre-generated nodes. Signed-off-by: Iuliana Prodan --- boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts index bc5b663f57d..6a0d7508deb 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 NXP + * Copyright 2021, 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ }; &pinctrl { - /omit-if-no-ref/ uart4_default: uart4_default { + uart4_default: uart4_default { group0 { pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, <&iomuxc_uart4_txd_uart_tx_uart4_tx>; From 24f2d2e136dbd48c5bd4e39b26b5941e3bd8c694 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:09:46 +0200 Subject: [PATCH 3906/4498] nxp_adsp: linker: Rename text area variables Use Zephyr's convention for text region start and end. Signed-off-by: Iuliana Prodan --- soc/xtensa/nxp_adsp/imx8/linker.ld | 4 ++-- soc/xtensa/nxp_adsp/imx8m/linker.ld | 4 ++-- soc/xtensa/nxp_adsp/rt5xx/linker.ld | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/soc/xtensa/nxp_adsp/imx8/linker.ld b/soc/xtensa/nxp_adsp/imx8/linker.ld index 7e5829c8d13..52d3a46b238 100644 --- a/soc/xtensa/nxp_adsp/imx8/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8/linker.ld @@ -346,7 +346,7 @@ SECTIONS .text : ALIGN(4) { _stext = .; - _text_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); KEEP (*(.ResetVector.text)) *(.ResetVector.literal) *(.entry.text) @@ -356,7 +356,7 @@ SECTIONS *(.fini.literal) KEEP(*(.fini)) *(.gnu.version) - _text_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); _etext = .; } >sdram0 :sdram0_phdr diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index 235e5a6f264..7df19644ce9 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -352,7 +352,7 @@ SECTIONS .text : ALIGN(4) { _stext = .; - _text_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); KEEP (*(.ResetVector.text)) *(.ResetVector.literal) *(.entry.text) @@ -362,7 +362,7 @@ SECTIONS *(.fini.literal) KEEP(*(.fini)) *(.gnu.version) - _text_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); _etext = .; } >sdram0 :sdram0_phdr diff --git a/soc/xtensa/nxp_adsp/rt5xx/linker.ld b/soc/xtensa/nxp_adsp/rt5xx/linker.ld index 582c4a7fbf8..adc8b87fb62 100644 --- a/soc/xtensa/nxp_adsp/rt5xx/linker.ld +++ b/soc/xtensa/nxp_adsp/rt5xx/linker.ld @@ -307,7 +307,7 @@ SECTIONS .text : ALIGN(4) { _stext = .; - _text_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); KEEP (*(.ResetVector.text)) *(.ResetVector.literal) *(.entry.text) @@ -317,7 +317,7 @@ SECTIONS *(.fini.literal) KEEP(*(.fini)) *(.gnu.version) - _text_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); _etext = .; } >iram_text_start :iram_text_start_phdr From 23c49e554a75c27e6b3fd01cb42aff5bcda27091 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:18:02 +0200 Subject: [PATCH 3907/4498] nxp_adsp: linker: Update linker scripts for C++ build When linking, in crtbegin.o for C++ exception support, we pull in the .tm_clone_table section. Update the linker scripts to handle this, otherwise we get a "warning: orphan section `.tm_clone_table'". Signed-off-by: Iuliana Prodan --- soc/xtensa/nxp_adsp/imx8m/linker.ld | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index 7df19644ce9..feee4b288c7 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -415,6 +415,11 @@ SECTIONS #include + /* Used for C++ build */ + .tm_clone_table : { + *(.tm_clone_table) + } >sdram0 :sdram0_phdr + .bss (NOLOAD) : ALIGN(8) { . = ALIGN (8); From 9cac089f8c51b3c47b1b42bd0b99766f69b296db Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:31:10 +0200 Subject: [PATCH 3908/4498] nxp_adsp: linker: Fix _heap_sentry reference Add _heap_sentry value to fix build errors for newlib, like: "undefined reference to `_heap_sentry'" Signed-off-by: Iuliana Prodan --- soc/xtensa/nxp_adsp/imx8m/linker.ld | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index feee4b288c7..b9d9303e96b 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -453,6 +453,8 @@ SECTIONS _end = ALIGN (8); PROVIDE(end = ALIGN (8)); + /* Mostly unused, though newlib likes them */ + _heap_sentry = .; __stack = SDRAM1_BASE + SDRAM1_SIZE; .comment 0 : { *(.comment) } .debug 0 : { *(.debug) } From 9af682587489263d1b55c7ce1c82fa52e6d45313 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Tue, 14 Nov 2023 00:56:35 +0200 Subject: [PATCH 3909/4498] nxp_adsp: linker: Add snippets to linker script The xtensa/nxp_adsp_imx8m linker script is missing the necessary include statements for linker snippets. So we need to add them. This fixes compile warnings like: orphan section `.unstable_id' from `modules/chre/lib..__modules__lib__chre__platform__zephyr.a (version.cc.obj)' being placed in section `.unstable_id'. Signed-off-by: Iuliana Prodan --- soc/xtensa/nxp_adsp/imx8m/linker.ld | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index b9d9303e96b..9687b604d6c 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -527,4 +527,6 @@ SECTIONS KEEP (*(.fw_metadata)) . = ALIGN(_EXT_MAN_ALIGN_); } >fw_metadata_seg :metadata_entries_phdr + + #include } From aba55686f5f376053eb279adffc5f1294c2be5a6 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:42:07 +0200 Subject: [PATCH 3910/4498] dts: nxp_adsp_imx8m: Add interrupt to fix compilation Add dummy interrupt id until we can support UART interuppt on i.MX8MP in order to fix compilation warnings. Signed-off-by: Iuliana Prodan --- dts/xtensa/nxp/nxp_imx8m.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dts/xtensa/nxp/nxp_imx8m.dtsi b/dts/xtensa/nxp/nxp_imx8m.dtsi index f354c8303ea..21a094c0461 100644 --- a/dts/xtensa/nxp/nxp_imx8m.dtsi +++ b/dts/xtensa/nxp/nxp_imx8m.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 NXP + * Copyright 2021, 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,6 +64,10 @@ uart4: uart@30a60000 { compatible = "nxp,imx-iuart"; reg = <0x30a60000 0x10000>; + /* TODO: This INTID is just a dummy + * until we can support UART interrupts + */ + interrupts = <29 0>; clocks = <&ccm IMX_CCM_UART4_CLK 0x6c 24>; status = "disabled"; }; From 8446c5877779b69c42bd14262f7b5a6604b94e61 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:45:28 +0200 Subject: [PATCH 3911/4498] board: xtensa: imx8m: Enable more tests Update yaml to run more tests. Signed-off-by: Iuliana Prodan --- boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml index 675db668f13..b5b62df24f8 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml @@ -3,11 +3,13 @@ name: NXP i.MX8M Plus EVK Audio DSP type: mcu arch: xtensa toolchain: + - xcc + - xt-clang - zephyr -testing: - only_tags: - - kernel - - sof - - ipm supported: - uart +testing: + ignore_tags: + - net + - bluetooth + - mcumgr From 5879803d155f03f75b954774438390d3221c02c7 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Sat, 11 Nov 2023 01:47:16 +0200 Subject: [PATCH 3912/4498] board: xtensa: nxp: Add vendor Add vendor for NXP boards. Signed-off-by: Iuliana Prodan --- boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.yaml | 1 + boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml | 1 + boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.yaml | 1 + boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.yaml b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.yaml index 60aa0482822..b2ab9b227a9 100644 --- a/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.yaml +++ b/boards/xtensa/nxp_adsp_imx8/nxp_adsp_imx8.yaml @@ -8,3 +8,4 @@ testing: only_tags: - kernel - sof +vendor: nxp diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml index b5b62df24f8..ef0bbdfe0ff 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml @@ -13,3 +13,4 @@ testing: - net - bluetooth - mcumgr +vendor: nxp diff --git a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.yaml b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.yaml index 3277fffc7d6..a343b8843c8 100644 --- a/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.yaml +++ b/boards/xtensa/nxp_adsp_imx8x/nxp_adsp_imx8x.yaml @@ -8,3 +8,4 @@ testing: only_tags: - kernel - sof +vendor: nxp diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml index ca3e0c21252..09f61405d94 100644 --- a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml @@ -7,3 +7,4 @@ toolchain: testing: only_tags: - kernel +vendor: nxp From 17b39baa6168758c1fe32e3902676f550274a4e3 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Fri, 15 Sep 2023 17:10:57 +0200 Subject: [PATCH 3913/4498] bluetooth: tester: Add support for BASS Support for BAP/BASS and BASS test cases. Signed-off-by: Magdalena Kasenberg --- tests/bluetooth/tester/overlay-le-audio.conf | 9 + tests/bluetooth/tester/src/btp/btp_ascs.h | 2 +- tests/bluetooth/tester/src/btp/btp_bap.h | 119 ++- tests/bluetooth/tester/src/btp/btp_gap.h | 3 +- tests/bluetooth/tester/src/btp/btp_pacs.h | 2 +- tests/bluetooth/tester/src/btp_bap.c | 761 +++++++++++++++++-- tests/bluetooth/tester/src/btp_core.c | 21 +- tests/bluetooth/tester/src/btp_gap.c | 20 +- 8 files changed, 858 insertions(+), 79 deletions(-) diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 530558c1308..4a7fc4e606c 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -31,6 +31,7 @@ CONFIG_BT_BAP_BROADCAST_SOURCE=y CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2 CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2 CONFIG_BT_ISO_TX_BUF_COUNT=4 +CONFIG_BT_BAP_BROADCAST_ASSISTANT=y # Broadcast Sink CONFIG_BT_BAP_SCAN_DELEGATOR=y @@ -38,6 +39,14 @@ CONFIG_BT_BAP_BROADCAST_SINK=y CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 +# BASS +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y +CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN=255 +CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y +# BASS notifications need higher MTU +CONFIG_BT_L2CAP_TX_MTU=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 + # ASCS CONFIG_BT_ASCS_ASE_SNK_COUNT=2 CONFIG_BT_ASCS_ASE_SRC_COUNT=2 diff --git a/tests/bluetooth/tester/src/btp/btp_ascs.h b/tests/bluetooth/tester/src/btp/btp_ascs.h index f14cb5de3d4..739e8c7d824 100644 --- a/tests/bluetooth/tester/src/btp/btp_ascs.h +++ b/tests/bluetooth/tester/src/btp/btp_ascs.h @@ -1,4 +1,4 @@ -/* btp_bap.h - Bluetooth tester headers */ +/* btp_ascs.h - Bluetooth tester headers */ /* * Copyright (c) 2023 Codecoup diff --git a/tests/bluetooth/tester/src/btp/btp_bap.h b/tests/bluetooth/tester/src/btp/btp_bap.h index ede3448f2cf..d094d536390 100644 --- a/tests/bluetooth/tester/src/btp/btp_bap.h +++ b/tests/bluetooth/tester/src/btp/btp_bap.h @@ -6,6 +6,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + /* BAP commands */ #define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 struct btp_bap_read_supported_commands_rp { @@ -50,32 +52,32 @@ struct btp_bap_broadcast_source_setup_cmd { } __packed; struct btp_bap_broadcast_source_setup_rp { uint32_t gap_settings; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 struct btp_bap_broadcast_source_release_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_ADV_START 0x06 struct btp_bap_broadcast_adv_start_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_ADV_STOP 0x07 struct btp_bap_broadcast_adv_stop_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_START 0x08 struct btp_bap_broadcast_source_start_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 struct btp_bap_broadcast_source_stop_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SINK_SETUP 0x0a @@ -97,16 +99,81 @@ struct btp_bap_broadcast_scan_stop_cmd { #define BTP_BAP_BROADCAST_SINK_SYNC 0x0e struct btp_bap_broadcast_sink_sync_cmd { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t advertiser_sid; uint16_t skip; uint16_t sync_timeout; + uint8_t past_avail; + uint8_t src_id; } __packed; #define BTP_BAP_BROADCAST_SINK_STOP 0x0f struct btp_bap_broadcast_sink_stop_cmd { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 +struct btp_bap_broadcast_sink_bis_sync_cmd { + bt_addr_le_t address; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint32_t requested_bis_sync; +} __packed; + +#define BTP_BAP_DISCOVER_SCAN_DELEGATORS 0x11 +struct btp_bap_discover_scan_delegators_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 +struct btp_bap_broadcast_assistant_scan_start_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP 0x13 +struct btp_bap_broadcast_assistant_scan_stop_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_ADD_BROADCAST_SRC 0x14 +struct btp_bap_add_broadcast_src_cmd { + bt_addr_le_t address; + bt_addr_le_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_REMOVE_BROADCAST_SRC 0x15 +struct btp_bap_remove_broadcast_src_cmd { + bt_addr_le_t address; + uint8_t src_id; +} __packed; + +#define BTP_BAP_MODIFY_BROADCAST_SRC 0x16 +struct btp_bap_modify_broadcast_src_cmd { + bt_addr_le_t address; + uint8_t src_id; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_SET_BROADCAST_CODE 0x17 +struct btp_bap_set_broadcast_code_cmd { + bt_addr_le_t address; + uint8_t src_id; + uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +} __packed; + +#define BTP_BAP_SEND_PAST 0x18 +struct btp_bap_send_past_cmd { + bt_addr_le_t address; + uint8_t src_id; } __packed; /* BAP events */ @@ -145,7 +212,7 @@ struct btp_bap_stream_received_ev { #define BTP_BAP_EV_BAA_FOUND 0x84 struct btp_bap_baa_found_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t advertiser_sid; uint16_t padv_interval; } __packed; @@ -153,7 +220,7 @@ struct btp_bap_baa_found_ev { #define BTP_BAP_EV_BIS_FOUND 0x85 struct btp_bap_bis_found_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t presentation_delay[3]; uint8_t subgroup_id; uint8_t bis_id; @@ -167,15 +234,43 @@ struct btp_bap_bis_found_ev { #define BTP_BAP_EV_BIS_SYNCED 0x86 struct btp_bap_bis_syned_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t bis_id; } __packed; #define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 struct btp_bap_bis_stream_received_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t bis_id; uint8_t data_len; uint8_t data[]; } __packed; + +#define BTP_BAP_EV_SCAN_DELEGATOR_FOUND 0x88 +struct btp_bap_scan_delegator_found_ev { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_EV_BROADCAST_RECEIVE_STATE 0x89 +struct btp_bap_broadcast_receive_state_ev { + bt_addr_le_t address; + uint8_t src_id; + bt_addr_le_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t pa_sync_state; + uint8_t big_encryption; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_EV_PA_SYNC_REQ 0x8a +struct btp_bap_pa_sync_req_ev { + bt_addr_le_t address; + uint8_t src_id; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t past_avail; + uint16_t pa_interval; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index 960d810e025..a727ffce4e4 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -456,5 +456,6 @@ int tester_gap_padv_configure(const struct bt_le_per_adv_param *param); int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len); int tester_gap_padv_start(void); int tester_gap_padv_stop(void); -int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params); +int tester_gap_padv_create_sync(struct bt_le_per_adv_sync_param *create_params); +int tester_gap_padv_stop_sync(void); #endif /* defined(CONFIG_BT_EXT_ADV) */ diff --git a/tests/bluetooth/tester/src/btp/btp_pacs.h b/tests/bluetooth/tester/src/btp/btp_pacs.h index 91f9596e869..7403feee762 100644 --- a/tests/bluetooth/tester/src/btp/btp_pacs.h +++ b/tests/bluetooth/tester/src/btp/btp_pacs.h @@ -1,4 +1,4 @@ -/* btp_bap.h - Bluetooth tester headers */ +/* btp_pacs.h - Bluetooth tester headers */ /* * Copyright (c) 2023 Codecoup diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index a35950b9cc5..d6149d2c3ac 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "bap_endpoint.h" #include @@ -118,7 +119,15 @@ static struct bt_bap_stream *sink_streams[MAX_STREAMS_COUNT]; /* A mask for the maximum BIS we can sync to. +1 since the BIS indexes start from 1. */ static const uint32_t bis_index_mask = BIT_MASK(MAX_STREAMS_COUNT + 1); static uint32_t bis_index_bitfield; +static uint32_t requested_bis_sync; #define INVALID_BROADCAST_ID (BT_AUDIO_BROADCAST_ID_MAX + 1) +#define SYNC_RETRY_COUNT 6 /* similar to retries for connections */ +#define PA_SYNC_SKIP 5 +/* Sample assumes that we only have a single Scan Delegator receive state */ +static const struct bt_bap_scan_delegator_recv_state *sink_recv_state; +static const struct bt_bap_scan_delegator_recv_state *broadcast_recv_state; +static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +static struct bt_bap_scan_delegator_subgroup delegator_subgroups[BROADCAST_SNK_SUBGROUP_CNT]; static bool print_cb(struct bt_data *data, void *user_data) { @@ -237,10 +246,8 @@ static void btp_send_ascs_operation_completed_ev(struct bt_conn *conn, uint8_t a uint8_t opcode, uint8_t status) { struct btp_ascs_operation_completed_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ase_id; ev.opcode = opcode; ev.status = status; @@ -252,10 +259,8 @@ static void btp_send_ascs_operation_completed_ev(struct bt_conn *conn, uint8_t a static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase_id, uint8_t state) { struct btp_ascs_ase_state_changed_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ase_id; ev.state = state; @@ -487,18 +492,15 @@ static void btp_send_stream_received_ev(struct bt_conn *conn, struct bt_bap_ep * uint8_t data_len, uint8_t *data) { struct btp_bap_stream_received_ev *ev; - struct bt_conn_info info; LOG_DBG("Stream received, ep %d, dir %d, len %d", ep->status.id, ep->dir, data_len); - (void)bt_conn_get_info(conn, &info); - net_buf_simple_init(rx_ev_buf, 0); ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev)); - bt_addr_le_copy(&ev->address, info.le.dst); + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); ev->ase_id = ep->status.id; ev->data_len = data_len; @@ -680,6 +682,7 @@ static void stream_started(struct bt_bap_stream *stream) } if (a_stream->broadcast) { + a_stream->bis_synced = true; btp_send_bis_syced_ev(&broadcaster_addr, broadcaster_broadcast_id, a_stream->bis_id); } else { @@ -701,6 +704,8 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) if (!a_stream->broadcast) { btp_send_ascs_operation_completed_ev(stream->conn, a_stream->ase_id, BT_ASCS_STOP_OP, BTP_STATUS_SUCCESS); + } else { + a_stream->bis_synced = false; } } @@ -747,10 +752,8 @@ static struct bt_bap_stream_ops stream_ops = { static void btp_send_discovery_completed_ev(struct bt_conn *conn, uint8_t status) { struct btp_bap_discovery_completed_ev ev; - struct bt_conn_info info; - (void) bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.status = status; tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_DISCOVERY_COMPLETED, &ev, sizeof(ev)); @@ -807,11 +810,9 @@ static void btp_send_pac_codec_found_ev(struct bt_conn *conn, enum bt_audio_dir dir) { struct btp_bap_codec_cap_found_ev ev; - struct bt_conn_info info; const uint8_t *data; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.dir = dir; ev.coding_format = codec_cap->id; @@ -838,10 +839,8 @@ static void btp_send_pac_codec_found_ev(struct bt_conn *conn, static void btp_send_ase_found_ev(struct bt_conn *conn, struct bt_bap_ep *ep) { struct btp_ascs_ase_found_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ep->status.id; ev.dir = ep->dir; @@ -1418,6 +1417,8 @@ static uint8_t broadcast_source_stop(const void *cmd, uint16_t cmd_len, static int broadcast_sink_reset(void) { bis_index_bitfield = 0U; + sink_recv_state = NULL; + (void)memset(sink_broadcast_code, 0, sizeof(sink_broadcast_code)); (void)memset(&broadcaster_addr, 0, sizeof(broadcaster_addr)); (void)memset(broadcaster, 0, sizeof(*broadcaster)); broadcaster_broadcast_id = INVALID_BROADCAST_ID; @@ -1433,18 +1434,20 @@ static void btp_send_baa_found_ev(const bt_addr_le_t *address, uint32_t broadcas bt_addr_le_copy(&ev.address, address); sys_put_le24(broadcast_id, ev.broadcast_id); ev.advertiser_sid = sid; - ev.padv_interval = interval; + ev.padv_interval = sys_cpu_to_le16(interval); tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BAA_FOUND, &ev, sizeof(ev)); } -static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) +static bool baa_check(struct bt_data *data, void *user_data) { const struct bt_le_scan_recv_info *info = user_data; char le_addr[BT_ADDR_LE_STR_LEN]; struct bt_uuid_16 adv_uuid; uint32_t broadcast_id; + /* Parse the scanned Broadcast Audio Announcement */ + if (data->type != BT_DATA_SVC_DATA16) { return true; } @@ -1465,8 +1468,8 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - LOG_DBG("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X", broadcast_id, - le_addr, info->sid); + LOG_DBG("Found BAA with ID 0x%06X, addr %s, sid 0x%02X, interval 0x%04X", + broadcast_id, le_addr, info->sid, info->interval); btp_send_baa_found_ev(info->addr, broadcast_id, info->sid, info->interval); @@ -1478,7 +1481,7 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct { /* If 0 there is no periodic advertising. */ if (info->interval != 0U) { - bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info); + bt_data_parse(ad, baa_check, (void *)info); } } @@ -1526,8 +1529,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap return; } - LOG_DBG("Received BASE with %u subgroups from broadcast sink %p", base->subgroup_count, - sink); + LOG_DBG("Received BASE: broadcast sink %p subgroups %u", sink, base->subgroup_count); for (size_t i = 0U; i < base->subgroup_count; i++) { for (size_t j = 0U; j < base->subgroups[i].bis_count; j++) { @@ -1546,15 +1548,29 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap } bis_index_bitfield = base_bis_index_bitfield & bis_index_mask; + LOG_DBG("bis_index_bitfield 0x%08x", bis_index_bitfield); } static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted) { int err; + uint32_t index_bitfield; - LOG_DBG(""); + LOG_DBG("PA found, encrypted %d, requested_bis_sync %d", encrypted, requested_bis_sync); + + if (encrypted) { + /* Wait for Set Broadcast Code and start sync at broadcast_code_cb */ + return; + } - err = bt_bap_broadcast_sink_sync(broadcast_sink, bis_index_bitfield, sink_streams, NULL); + if (!requested_bis_sync) { + /* No sync with any BIS was requested yet */ + return; + } + + index_bitfield = bis_index_bitfield & requested_bis_sync; + err = bt_bap_broadcast_sink_sync(broadcast_sink, index_bitfield, sink_streams, + sink_broadcast_code); if (err != 0) { LOG_DBG("Unable to sync to broadcast source: %d", err); } @@ -1565,21 +1581,36 @@ static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { .syncable = syncable_cb, }; +static void pa_timer_handler(struct k_work *work) +{ + if (broadcast_recv_state != NULL) { + enum bt_bap_pa_state pa_state; + + if (broadcast_recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { + pa_state = BT_BAP_PA_STATE_NO_PAST; + } else { + pa_state = BT_BAP_PA_STATE_FAILED; + } + + bt_bap_scan_delegator_set_pa_state(broadcast_recv_state->src_id, + pa_state); + } + + LOG_DBG("PA timeout"); +} + +static K_WORK_DELAYABLE_DEFINE(pa_timer, pa_timer_handler); + static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) { int err; - struct bt_le_per_adv_sync *pa_sync; - LOG_DBG(""); + LOG_DBG("Sync info: service_data 0x%04X", info->service_data); - pa_sync = tester_gap_padv_get(); + k_work_cancel_delayable(&pa_timer); - if (sync != pa_sync) { - return; - } - - err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, &broadcast_sink); + err = bt_bap_broadcast_sink_create(sync, broadcaster_broadcast_id, &broadcast_sink); if (err != 0) { LOG_DBG("Failed to create broadcast sink: ID 0x%06X, err %d", broadcaster_broadcast_id, err); @@ -1590,6 +1621,203 @@ static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = { .synced = bap_pa_sync_synced_cb, }; +static void btp_send_pas_sync_req_ev(struct bt_conn *conn, uint8_t src_id, + uint8_t advertiser_sid, uint32_t broadcast_id, + bool past_avail, uint16_t pa_interval) +{ + struct btp_bap_pa_sync_req_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.src_id = src_id; + ev.advertiser_sid = advertiser_sid; + sys_put_le24(broadcast_id, ev.broadcast_id); + ev.past_avail = past_avail; + ev.pa_interval = sys_cpu_to_le16(pa_interval); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_PA_SYNC_REQ, &ev, sizeof(ev)); +} + +static void btp_send_scan_delegator_found_ev(struct bt_conn *conn) +{ + struct btp_bap_scan_delegator_found_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_SCAN_DELEGATOR_FOUND, &ev, sizeof(ev)); +} + +static void btp_send_broadcast_receive_state_ev(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *state) +{ + struct btp_bap_broadcast_receive_state_ev *ev; + size_t len; + uint8_t *ptr; + + tester_rsp_buffer_lock(); + tester_rsp_buffer_allocate(sizeof(*ev) + BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS * + sizeof(struct bt_bap_scan_delegator_subgroup), (uint8_t **)&ev); + + if (conn) { + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); + } else { + (void)memset(&ev->address, 0, sizeof(ev->address)); + } + + ev->src_id = state->src_id; + bt_addr_le_copy(&ev->broadcaster_address, &state->addr); + ev->advertiser_sid = state->adv_sid; + sys_put_le24(state->broadcast_id, ev->broadcast_id); + ev->pa_sync_state = state->pa_sync_state; + ev->big_encryption = state->encrypt_state; + ev->num_subgroups = state->num_subgroups; + + ptr = ev->subgroups; + for (uint8_t i = 0; i < ev->num_subgroups; i++) { + const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i]; + + sys_put_le32(subgroup->bis_sync >> 1, ptr); + ptr += sizeof(subgroup->bis_sync); + *ptr = subgroup->metadata_len; + ptr += sizeof(subgroup->metadata_len); + memcpy(ptr, subgroup->metadata, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + len = sizeof(*ev) + ptr - ev->subgroups; + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BROADCAST_RECEIVE_STATE, ev, len); + + tester_rsp_buffer_free(); + tester_rsp_buffer_unlock(); +} + +static int pa_sync_past(struct bt_conn *conn, uint16_t sync_timeout) +{ + struct bt_le_per_adv_sync_transfer_param param = { 0 }; + int err; + + param.skip = PA_SYNC_SKIP; + param.timeout = sync_timeout; + + err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m); + if (err != 0) { + LOG_DBG("Could not do PAST subscribe: %d", err); + } else { + LOG_DBG("Syncing with PAST: %d", err); + (void)k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10)); + } + + return err; +} + +static int pa_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + bool past_avail, uint16_t pa_interval) +{ + LOG_DBG("sync state %d ", recv_state->pa_sync_state); + + sink_recv_state = recv_state; + broadcast_recv_state = recv_state; + + btp_send_pas_sync_req_ev(conn, recv_state->src_id, recv_state->adv_sid, + recv_state->broadcast_id, past_avail, pa_interval); + + return 0; +} + +static int pa_sync_term_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state) +{ + LOG_DBG(""); + + sink_recv_state = recv_state; + + tester_gap_padv_stop_sync(); + + return 0; +} + +static void broadcast_code_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + const uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]) +{ + int err; + uint32_t index_bitfield; + + LOG_DBG("Broadcast code received for %p", recv_state); + + sink_recv_state = recv_state; + + (void)memcpy(sink_broadcast_code, broadcast_code, BT_AUDIO_BROADCAST_CODE_SIZE); + + if (!requested_bis_sync) { + return; + } + + index_bitfield = bis_index_bitfield & requested_bis_sync; + err = bt_bap_broadcast_sink_sync(broadcast_sink, index_bitfield, sink_streams, + sink_broadcast_code); + if (err != 0) { + LOG_DBG("Unable to sync to broadcast source: %d", err); + } +} + +static int bis_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + const uint32_t bis_sync_req[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS]) +{ + bool bis_synced = false; + + LOG_DBG("BIS sync request received for %p: 0x%08x", recv_state, bis_sync_req[0]); + + for (int i = 0; i < MAX_STREAMS_COUNT; i++) { + if (broadcaster->streams[i].bis_synced) { + bis_synced = true; + break; + } + } + + /* We only care about a single subgroup in this sample */ + if (bis_synced) { + /* If the BIS sync request is received while we are already + * synced, it means that the requested BIS sync has changed. + */ + int err; + + /* The stream stopped callback will be called as part of this, + * and we do not need to wait for any events from the + * controller. Thus, when this returns, the `bis_synced` + * is back to false. + */ + err = bt_bap_broadcast_sink_stop(broadcast_sink); + if (err != 0) { + LOG_DBG("Failed to stop Broadcast Sink: %d", err); + + return err; + } + } + + requested_bis_sync = bis_sync_req[0]; + broadcaster_broadcast_id = recv_state->broadcast_id; + + return 0; +} + +static void recv_state_updated_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state) +{ + LOG_DBG("Receive state with ID %u updated", recv_state->src_id); + + btp_send_broadcast_receive_state_ev(conn, recv_state); +} + +static struct bt_bap_scan_delegator_cb scan_delegator_cbs = { + .recv_state_updated = recv_state_updated_cb, + .pa_sync_req = pa_sync_req_cb, + .pa_sync_term_req = pa_sync_term_req_cb, + .broadcast_code = broadcast_code_cb, + .bis_sync_req = bis_sync_req_cb, +}; + static uint8_t broadcast_sink_setup(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1608,8 +1836,14 @@ static uint8_t broadcast_sink_setup(const void *cmd, uint16_t cmd_len, sink_streams[i]->ops = &stream_ops; } + /* For Scan Delegator role */ + bt_bap_scan_delegator_register_cb(&scan_delegator_cbs); + + /* For Broadcast Sink role */ bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs); bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb); + + /* For Broadcast Sink or Broadcast Assistant role */ bt_le_scan_cb_register(&bap_scan_cb); return BTP_STATUS_SUCCESS; @@ -1668,35 +1902,36 @@ static uint8_t broadcast_sink_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { int err; + struct bt_conn *conn; const struct btp_bap_broadcast_sink_sync_cmd *cp = cmd; struct bt_le_per_adv_sync_param create_params = {0}; LOG_DBG(""); - /* Sink Sync steps: - * 1. bt_le_per_adv_sync_create() - * 2. bap_pa_sync_synced_cb() - * 3. bt_bap_broadcast_sink_create() - * 4. - base_recv_cb() - * - syncable_cb() - * - broadcast_code_cb() <- only with scan delegator - * - bis_sync_req_cb() <- only for scan delegator - * 5. bt_bap_broadcast_sink_sync() - * 6. stream_started() - * 7. stream_recv_cb() - * 8. bap_pa_sync_terminated_cb() - * 9. stream_stopped_cb() - */ - broadcaster_broadcast_id = sys_get_le24(cp->broadcast_id); bt_addr_le_copy(&broadcaster_addr, &cp->address); - bt_addr_le_copy(&create_params.addr, &cp->address); - create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; - create_params.sid = cp->advertiser_sid; - create_params.skip = cp->skip; - create_params.timeout = cp->sync_timeout; - err = tester_padv_create_sync(&create_params); + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) && cp->past_avail) { + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_scan_delegator_set_pa_state(cp->src_id, BT_BAP_PA_STATE_INFO_REQ); + if (err != 0) { + LOG_DBG("Failed to set INFO_REQ state: %d", err); + } + + err = pa_sync_past(conn, cp->sync_timeout); + } else { + bt_addr_le_copy(&create_params.addr, &cp->address); + create_params.options = 0; + create_params.sid = cp->advertiser_sid; + create_params.skip = cp->skip; + create_params.timeout = cp->sync_timeout; + err = tester_gap_padv_create_sync(&create_params); + } + if (err != 0) { return BTP_STATUS_FAILED; } @@ -1711,6 +1946,8 @@ static uint8_t broadcast_sink_stop(const void *cmd, uint16_t cmd_len, LOG_DBG(""); + requested_bis_sync = 0; + err = bt_bap_broadcast_sink_stop(broadcast_sink); if (err != 0) { LOG_DBG("Unable to sync to broadcast source: %d", err); @@ -1718,6 +1955,368 @@ static uint8_t broadcast_sink_stop(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } + err = tester_gap_padv_stop_sync(); + if (err != 0) { + LOG_DBG("Failed to stop PA sync, %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_sink_bis_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_bap_broadcast_sink_bis_sync_cmd *cp = cmd; + + LOG_DBG(""); + + if (cp->requested_bis_sync == BT_BAP_BIS_SYNC_NO_PREF) { + requested_bis_sync = sys_le32_to_cpu(cp->requested_bis_sync); + } else { + /* For semantic purposes Zephyr API uses BIS Index bitfield + * where BIT(1) means BIS Index 1 + */ + requested_bis_sync = sys_le32_to_cpu(cp->requested_bis_sync) << 1; + } + + err = bt_bap_broadcast_sink_sync(broadcast_sink, requested_bis_sync, sink_streams, + sink_broadcast_code); + if (err != 0) { + LOG_DBG("Unable to sync to BISes, req_bis_sync %d, err %d", requested_bis_sync, + err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err, + uint8_t recv_state_count) +{ + LOG_DBG("err %d", err); + + if (err != 0) { + LOG_DBG("BASS discover failed (%d)", err); + } else { + LOG_DBG("BASS discover done with %u recv states", recv_state_count); + + btp_send_scan_delegator_found_ev(conn); + } +} + +static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info, + uint32_t broadcast_id) +{ + char le_addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + LOG_DBG("[DEVICE]: %s, broadcast_id 0x%06X, interval (ms) %u), SID 0x%x, RSSI %i", le_addr, + broadcast_id, BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval), info->sid, info->rssi); +} + +static void bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err, + const struct bt_bap_scan_delegator_recv_state *state) +{ + LOG_DBG("err: %d", err); + + if (err != 0 || state == NULL) { + return; + } + + btp_send_broadcast_receive_state_ev(conn, state); +} + +static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, int err, + uint8_t src_id) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static struct bt_bap_broadcast_assistant_cb broadcast_assistant_cb = { + .discover = bap_broadcast_assistant_discover_cb, + .scan = bap_broadcast_assistant_scan_cb, + .recv_state = bap_broadcast_assistant_recv_state_cb, + .recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb, + .scan_start = bap_broadcast_assistant_scan_start_cb, + .scan_stop = bap_broadcast_assistant_scan_stop_cb, + .add_src = bap_broadcast_assistant_add_src_cb, + .mod_src = bap_broadcast_assistant_mod_src_cb, + .broadcast_code = bap_broadcast_assistant_broadcast_code_cb, + .rem_src = bap_broadcast_assistant_rem_src_cb, +}; + +static uint8_t broadcast_discover_scan_delegators(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_discover_scan_delegators_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_discover(conn); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_scan_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_broadcast_assistant_scan_start_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_scan_start(conn, true); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_scan_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_broadcast_assistant_scan_stop_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_scan_stop(conn); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_add_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const uint8_t *ptr; + struct bt_conn *conn; + const struct btp_bap_add_broadcast_src_cmd *cp = cmd; + struct bt_bap_broadcast_assistant_add_src_param param = { 0 }; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + memset(delegator_subgroups, 0, sizeof(delegator_subgroups)); + bt_addr_le_copy(¶m.addr, &cp->broadcaster_address); + param.adv_sid = cp->advertiser_sid; + param.pa_sync = cp->padv_sync > 0 ? true : false; + param.broadcast_id = sys_get_le24(cp->broadcast_id); + param.pa_interval = sys_le16_to_cpu(cp->padv_interval); + param.num_subgroups = MIN(cp->num_subgroups, BROADCAST_SNK_SUBGROUP_CNT); + param.subgroups = delegator_subgroups; + + ptr = cp->subgroups; + for (uint8_t i = 0; i < param.num_subgroups; i++) { + struct bt_bap_scan_delegator_subgroup *subgroup = &delegator_subgroups[i]; + + subgroup->bis_sync = sys_get_le32(ptr); + ptr += sizeof(subgroup->bis_sync); + subgroup->metadata_len = *ptr; + ptr += sizeof(subgroup->metadata_len); + memcpy(subgroup->metadata, ptr, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + err = bt_bap_broadcast_assistant_add_src(conn, ¶m); + if (err != 0) { + LOG_DBG("err %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_remove_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_remove_broadcast_src_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_rem_src(conn, cp->src_id); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_modify_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const uint8_t *ptr; + struct bt_conn *conn; + const struct btp_bap_modify_broadcast_src_cmd *cp = cmd; + struct bt_bap_broadcast_assistant_mod_src_param param = { 0 }; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + memset(delegator_subgroups, 0, sizeof(delegator_subgroups)); + param.src_id = cp->src_id; + param.pa_sync = cp->padv_sync > 0 ? true : false; + param.pa_interval = sys_le16_to_cpu(cp->padv_interval); + param.num_subgroups = MIN(cp->num_subgroups, BROADCAST_SNK_SUBGROUP_CNT); + param.subgroups = delegator_subgroups; + + ptr = cp->subgroups; + for (uint8_t i = 0; i < param.num_subgroups; i++) { + struct bt_bap_scan_delegator_subgroup *subgroup = &delegator_subgroups[i]; + + subgroup->bis_sync = sys_get_le32(ptr); + ptr += sizeof(subgroup->bis_sync); + subgroup->metadata_len = *ptr; + ptr += sizeof(subgroup->metadata_len); + memcpy(subgroup->metadata, ptr, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + err = bt_bap_broadcast_assistant_mod_src(conn, ¶m); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_set_broadcast_code(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_set_broadcast_code_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_set_broadcast_code(conn, cp->src_id, cp->broadcast_code); + if (err != 0) { + LOG_DBG("err %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_send_past(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + uint16_t service_data; + struct bt_conn *conn; + struct bt_le_per_adv_sync *pa_sync; + const struct btp_bap_send_past_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + pa_sync = tester_gap_padv_get(); + if (!pa_sync) { + LOG_DBG("Could not send PAST to Scan Delegator"); + + return BTP_STATUS_FAILED; + } + + LOG_DBG("Sending PAST"); + + /* If octet 0 is set to 0, it means AdvA in PAST matches AdvA in ADV_EXT_IND. + * Octet 1 shall be set to Source_ID. + */ + service_data = cp->src_id << 8; + + err = bt_le_per_adv_sync_transfer(pa_sync, conn, service_data); + if (err != 0) { + LOG_DBG("Could not transfer periodic adv sync: %d", err); + + return BTP_STATUS_FAILED; + } + return BTP_STATUS_SUCCESS; } @@ -2698,6 +3297,51 @@ static const struct btp_handler bap_handlers[] = { .expect_len = sizeof(struct btp_bap_broadcast_sink_stop_cmd), .func = broadcast_sink_stop, }, + { + .opcode = BTP_BAP_BROADCAST_SINK_BIS_SYNC, + .expect_len = sizeof(struct btp_bap_broadcast_sink_bis_sync_cmd), + .func = broadcast_sink_bis_sync, + }, + { + .opcode = BTP_BAP_DISCOVER_SCAN_DELEGATORS, + .expect_len = sizeof(struct btp_bap_discover_scan_delegators_cmd), + .func = broadcast_discover_scan_delegators, + }, + { + .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_START, + .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_start_cmd), + .func = broadcast_assistant_scan_start, + }, + { + .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_stop_cmd), + .func = broadcast_assistant_scan_stop, + }, + { + .opcode = BTP_BAP_ADD_BROADCAST_SRC, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_assistant_add_src, + }, + { + .opcode = BTP_BAP_REMOVE_BROADCAST_SRC, + .expect_len = sizeof(struct btp_bap_remove_broadcast_src_cmd), + .func = broadcast_assistant_remove_src, + }, + { + .opcode = BTP_BAP_MODIFY_BROADCAST_SRC, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_assistant_modify_src, + }, + { + .opcode = BTP_BAP_SET_BROADCAST_CODE, + .expect_len = sizeof(struct btp_bap_set_broadcast_code_cmd), + .func = broadcast_assistant_set_broadcast_code, + }, + { + .opcode = BTP_BAP_SEND_PAST, + .expect_len = sizeof(struct btp_bap_send_past_cmd), + .func = broadcast_assistant_send_past, + }, }; uint8_t tester_init_pacs(void) @@ -2767,6 +3411,9 @@ uint8_t tester_init_bap(void) return BTP_STATUS_FAILED; } + /* For Broadcast Assistant role */ + bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cb); + k_work_queue_init(&iso_data_work_q); k_work_queue_start(&iso_data_work_q, iso_data_thread_stack_area, K_THREAD_STACK_SIZEOF(iso_data_thread_stack_area), diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 1840d2d5d0b..8c157a5eccb 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -156,7 +156,8 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_ias(); break; #endif /* CONFIG_BT_IAS */ -#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) +#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \ + defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK) case BTP_SERVICE_ID_PACS: status = tester_init_pacs(); break; @@ -166,7 +167,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; -#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ +#endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \ + * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK + */ #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) case BTP_SERVICE_ID_MICP: status = tester_init_micp(); @@ -265,7 +268,8 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_ias(); break; #endif /* CONFIG_BT_IAS */ -#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) +#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \ + defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK) case BTP_SERVICE_ID_PACS: status = tester_unregister_pacs(); break; @@ -275,10 +279,17 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_unregister_bap(); break; - case BTP_SERVICE_ID_MICP: +#endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \ + * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK + */ +#if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) + case BTP_SERVICE_ID_MICP: status = tester_unregister_micp(); break; -#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ + case BTP_SERVICE_ID_MICS: + status = tester_unregister_mics(); + break; +#endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: status = tester_unregister_has(); diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 2191da79534..e09e90a06e1 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -1539,7 +1539,7 @@ static uint8_t padv_set_data(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) +int tester_gap_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) { int err; @@ -1556,6 +1556,22 @@ int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) return err; } +int tester_gap_padv_stop_sync(void) +{ + int err; + + if (pa_sync == NULL) { + return -EALREADY; + } + + err = bt_le_per_adv_sync_delete(pa_sync); + if (err != 0) { + LOG_DBG("Unable to stop sync to PA: %d", err); + } + + return err; +} + static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1569,7 +1585,7 @@ static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len, create_params.skip = cp->skip; create_params.timeout = cp->sync_timeout; - err = tester_padv_create_sync(&create_params); + err = tester_gap_padv_create_sync(&create_params); if (err != 0) { return BTP_STATUS_FAILED; } From 71387ca165424958bc132d00fe6ed18f56973642 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 13:53:54 +0800 Subject: [PATCH 3914/4498] arch/soc: introduce config for custom arch_cpu_idle implementation Each arch platform may has a general arch_cpu_idle implementation but each vendor may has a custom one, so this config will be used for vendor to override it. Some workarounds were introduced for intel cavs2.5 platform bring up. It is not general so move them to platform code. Signed-off-by: Rander Wang --- arch/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 0a108702ad9..5e3b96f414d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -978,3 +978,10 @@ config TOOLCHAIN_HAS_BUILTIN_FFS default y if !(64BIT && RISCV) help Hidden option to signal that toolchain has __builtin_ffs*(). + +config ARCH_CPU_IDLE_CUSTOM + bool "Custom arch_cpu_idle implementation" + default n + help + This options allows applications to override the default arch idle implementation with + a custom one. From 0c27d772f68926cfa1a7127280956dd6e57e6e48 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 14:13:37 +0800 Subject: [PATCH 3915/4498] soc: intel_adsp/cavs: add arch_cpu_idle support Cavs platforms starts from Apllolake to Raptorlake. Some of them need some workaround for arch_cpu_idle so create a bespoken one. Each workaround is configured by kconfig setting. Signed-off-by: Rander Wang --- soc/xtensa/intel_adsp/cavs/power.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index bc955b3cb90..c0a75f5c0ec 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -180,6 +180,51 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) } #endif /* CONFIG_PM */ +#ifdef CONFIG_ARCH_CPU_IDLE_CUSTOM +/* xt-clang removes any NOPs more than 8. So we need to set + * no optimization to avoid those NOPs from being removed. + * + * This function is simply enough and full of hand written + * assembly that optimization is not really meaningful + * anyway. So we can skip optimization unconditionally. + * Re-evalulate its use and add #ifdef if this assumption + * is no longer valid. + */ +__no_optimization +void arch_cpu_idle(void) +{ + sys_trace_idle(); + + /* Just spin forever with interrupts unmasked, for platforms + * where WAITI can't be used or where its behavior is + * complicated (Intel DSPs will power gate on idle entry under + * some circumstances) + */ + if (IS_ENABLED(CONFIG_XTENSA_CPU_IDLE_SPIN)) { + __asm__ volatile("rsil a0, 0"); + __asm__ volatile("loop_forever: j loop_forever"); + return; + } + + /* Cribbed from SOF: workaround for a bug in some versions of + * the LX6 IP. Preprocessor ugliness avoids the need to + * figure out how to get the compiler to unroll a loop. + */ + if (IS_ENABLED(CONFIG_XTENSA_WAITI_BUG)) { +#define NOP4 __asm__ volatile("nop; nop; nop; nop"); +#define NOP32 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 +#define NOP128() NOP32 NOP32 NOP32 NOP32 + NOP128(); +#undef NOP128 +#undef NOP32 +#undef NOP4 + __asm__ volatile("isync; extw"); + } + +__asm__ volatile ("waiti 0"); +} +#endif + __imr void power_init(void) { /* Request HP ring oscillator and From 954901296c9735edc6414abb8ac0b81dbe1549b5 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 13:53:54 +0800 Subject: [PATCH 3916/4498] arch/xtensa: clean up arch_cpu_idle function Some workarounds were introduced for intel cavs2.5 platform bring up. It is not general so move them to platform code. Signed-off-by: Rander Wang --- arch/xtensa/Kconfig | 12 ----------- arch/xtensa/core/cpu_idle.c | 39 ++--------------------------------- soc/xtensa/intel_adsp/Kconfig | 12 +++++++++++ 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 29c06667f55..a1517f17ed0 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -50,18 +50,6 @@ config XTENSA_ENABLE_BACKTRACE help Enable this config option to print backtrace on panic exception -config XTENSA_CPU_IDLE_SPIN - bool "Use busy loop for k_cpu_idle" - help - Use a spin loop instead of WAITI for the CPU idle state. - -config XTENSA_WAITI_BUG - bool "Workaround sequence for WAITI bug on LX6" - help - SOF traditionally contains this workaround on its ADSP - platforms which prefixes a WAITI entry with 128 NOP - instructions followed by an ISYNC and EXTW. - config XTENSA_SMALL_VECTOR_TABLE_ENTRY bool "Workaround for small vector table entries" help diff --git a/arch/xtensa/core/cpu_idle.c b/arch/xtensa/core/cpu_idle.c index fa9384d8445..dae79f023ff 100644 --- a/arch/xtensa/core/cpu_idle.c +++ b/arch/xtensa/core/cpu_idle.c @@ -6,48 +6,13 @@ #include #include -/* xt-clang removes any NOPs more than 8. So we need to set - * no optimization to avoid those NOPs from being removed. - * - * This function is simply enough and full of hand written - * assembly that optimization is not really meaningful - * anyway. So we can skip optimization unconditionally. - * Re-evalulate its use and add #ifdef if this assumption - * is no longer valid. - */ -__no_optimization +#ifndef CONFIG_ARCH_CPU_IDLE_CUSTOM void arch_cpu_idle(void) { sys_trace_idle(); - - /* Just spin forever with interrupts unmasked, for platforms - * where WAITI can't be used or where its behavior is - * complicated (Intel DSPs will power gate on idle entry under - * some circumstances) - */ - if (IS_ENABLED(CONFIG_XTENSA_CPU_IDLE_SPIN)) { - __asm__ volatile("rsil a0, 0"); - __asm__ volatile("loop_forever: j loop_forever"); - return; - } - - /* Cribbed from SOF: workaround for a bug in some versions of - * the LX6 IP. Preprocessor ugliness avoids the need to - * figure out how to get the compiler to unroll a loop. - */ - if (IS_ENABLED(CONFIG_XTENSA_WAITI_BUG)) { -#define NOP4 __asm__ volatile("nop; nop; nop; nop"); -#define NOP32 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 -#define NOP128() NOP32 NOP32 NOP32 NOP32 - NOP128(); -#undef NOP128 -#undef NOP32 -#undef NOP4 - __asm__ volatile("isync; extw"); - } - __asm__ volatile ("waiti 0"); } +#endif void arch_cpu_atomic_idle(unsigned int key) { diff --git a/soc/xtensa/intel_adsp/Kconfig b/soc/xtensa/intel_adsp/Kconfig index f04286ccae1..a3d93d976ea 100644 --- a/soc/xtensa/intel_adsp/Kconfig +++ b/soc/xtensa/intel_adsp/Kconfig @@ -113,4 +113,16 @@ config ADSP_IMR_CONTEXT_SAVE entering D3 state. Later this context can be used to FW restore when Host power up DSP again. +config XTENSA_CPU_IDLE_SPIN + bool "Use busy loop for k_cpu_idle" + help + Use a spin loop instead of WAITI for the CPU idle state. + +config XTENSA_WAITI_BUG + bool "Workaround sequence for WAITI bug on LX6" + help + SOF traditionally contains this workaround on its ADSP + platforms which prefixes a WAITI entry with 128 NOP + instructions followed by an ISYNC and EXTW. + endif # SOC_FAMILY_INTEL_ADSP From b0940e6e2587a3b2de397ca90ec86812514bdc9b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 18:07:51 +0000 Subject: [PATCH 3917/4498] tests: build_all: input: unify the gpio definitions Clean up few build all device instances to use the test_gpio node and different gpio numbers. Makes them somewhat more representative of what an actual instance would look like. Signed-off-by: Fabio Baltieri --- tests/drivers/build_all/input/app.overlay | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index f065aadd5f3..2dcef76e2ae 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -70,28 +70,28 @@ gt911@1 { compatible = "goodix,gt911"; reg = <0x1>; - irq-gpios = <&gpio0 0 0>; - reset-gpios = <&gpio0 0 0>; + irq-gpios = <&test_gpio 0 0>; + reset-gpios = <&test_gpio 1 0>; }; cst816s: cst816s@2 { compatible = "hynitron,cst816s"; reg = <0x2>; - irq-gpios = <&gpio0 0 0>; - rst-gpios = <&gpio0 0 0>; + irq-gpios = <&test_gpio 0 0>; + rst-gpios = <&test_gpio 1 0>; }; cap1203@3 { compatible = "microchip,cap1203"; reg = <0x3>; - int-gpios = <&gpio0 0 0>; + int-gpios = <&test_gpio 0 0>; input-codes = <0 1 2>; }; stmpe811@4 { compatible = "st,stmpe811"; reg = <0x4>; - int-gpios = <&gpio0 0 0>; + int-gpios = <&test_gpio 0 0>; panel-driver-settling-time-us = <10>; touch-detect-delay-us = <10>; touch-average-control = <1>; From b6a996d00a6a5950a995bb4477a50eadf7d15835 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 16 Nov 2023 10:03:31 +0000 Subject: [PATCH 3918/4498] tests: build_all: input: drop a device nodelabel Other entires don't have it, keep it uniform. Signed-off-by: Fabio Baltieri --- tests/drivers/build_all/input/app.overlay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index 2dcef76e2ae..cf826cfe4fa 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -74,7 +74,7 @@ reset-gpios = <&test_gpio 1 0>; }; - cst816s: cst816s@2 { + cst816s@2 { compatible = "hynitron,cst816s"; reg = <0x2>; irq-gpios = <&test_gpio 0 0>; From 4d554dd30cfb07863a135caace44fcd25802f480 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Mon, 17 Jul 2023 16:29:20 +0200 Subject: [PATCH 3919/4498] dts: bindings: gpio: add TLE9104 Add binding for the powertrain switch TLE9104. Signed-off-by: Benedikt Schmidt --- dts/bindings/gpio/infineon,tle9104.yaml | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 dts/bindings/gpio/infineon,tle9104.yaml diff --git a/dts/bindings/gpio/infineon,tle9104.yaml b/dts/bindings/gpio/infineon,tle9104.yaml new file mode 100644 index 00000000000..5893f1a355a --- /dev/null +++ b/dts/bindings/gpio/infineon,tle9104.yaml @@ -0,0 +1,50 @@ +# +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Infineon TLE9104 4-channel powertrain switch + +compatible: "infineon,tle9104" + +include: [gpio-controller.yaml, spi-device.yaml] + +properties: + "#gpio-cells": + const: 2 + + ngpios: + type: int + required: true + const: 4 + description: Number of GPIOs supported + + en-gpios: + type: phandle-array + description: "GPIO for enable" + + resn-gpios: + type: phandle-array + required: true + description: "GPIO for reset" + + in1-gpios: + type: phandle-array + description: "GPIO for controlling OUT1" + + in2-gpios: + type: phandle-array + description: "GPIO for controlling OUT2" + + in3-gpios: + type: phandle-array + description: "GPIO for controlling OUT3" + + in4-gpios: + type: phandle-array + description: "GPIO for controlling OUT4" + +gpio-cells: + - pin + - flags From bfb8eda025819395bd2f8c81783c0a0d2ec13f14 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Tue, 18 Jul 2023 11:12:31 +0200 Subject: [PATCH 3920/4498] drivers: gpio: implement driver for TLE9104 Implement a driver for the powertrain switch TLE9104. Signed-off-by: Benedikt Schmidt --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.tle9104 | 19 ++ drivers/gpio/gpio_tle9104.c | 535 +++++++++++++++++++++++++++++++++++ 4 files changed, 557 insertions(+) create mode 100644 drivers/gpio/Kconfig.tle9104 create mode 100644 drivers/gpio/gpio_tle9104.c diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 0e94d78dba3..b1cd06978bb 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -84,6 +84,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_TLE9104 gpio_tle9104.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RA gpio_ra.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 07c3d6b47da..c49e2aa1167 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -226,6 +226,8 @@ source "drivers/gpio/Kconfig.efinix_sapphire" source "drivers/gpio/Kconfig.davinci" source "drivers/gpio/Kconfig.sedi" +source "drivers/gpio/Kconfig.tle9104" + source "drivers/gpio/Kconfig.altera" source "drivers/gpio/Kconfig.bcm2711" diff --git a/drivers/gpio/Kconfig.tle9104 b/drivers/gpio/Kconfig.tle9104 new file mode 100644 index 00000000000..fd12710a5f5 --- /dev/null +++ b/drivers/gpio/Kconfig.tle9104 @@ -0,0 +1,19 @@ +# TLE9104 GPIO configuration options + +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_TLE9104 + bool "TLE9104 SPI-based powertrain switch" + default y + depends on DT_HAS_INFINEON_TLE9104_ENABLED + depends on SPI + help + Enable driver for TLE9104 SPI-based powertrain switch. + +config GPIO_TLE9104_INIT_PRIORITY + int "Init priority" + default 75 + depends on GPIO_TLE9104 + help + Device driver initialization priority. diff --git a/drivers/gpio/gpio_tle9104.c b/drivers/gpio/gpio_tle9104.c new file mode 100644 index 00000000000..072828dec88 --- /dev/null +++ b/drivers/gpio/gpio_tle9104.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_tle9104 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(gpio_tle9104, CONFIG_GPIO_LOG_LEVEL); + +/* + * The values for the defines below as well as the register definitions were + * taken from the datasheet, which can be found at: + * https://www.infineon.com/dgdl/Infineon-TLE9104SH-DataSheet-v01_31-EN.pdf?fileId=5546d462766cbe86017676144d76581b + */ +#define TLE9104_RESET_DURATION_TIME_US 10 +#define TLE9104_RESET_DURATION_WAIT_TIME_SAFETY_MARGIN_US 200 +#define TLE9104_RESET_DURATION_WAIT_TIME_US 10 +#define TLE9104_GPIO_COUNT 4 +#define TLE9104_INITIALIZATION_TIMEOUT_MS 1 +#define TLE9104_ICVERSIONID 0xB1 + +#define TLE9104_FRAME_RW_POS 15 +#define TLE9104_FRAME_PARITY_POS 14 +#define TLE9104_FRAME_FAULTCOMMUNICATION_POS 13 +#define TLE9104_FRAME_FAULTGLOBAL_POS 12 +#define TLE9104_FRAME_ADDRESS_POS 8 +#define TLE9104_FRAME_DATA_POS 0 + +#define TLE9104_CFG_CWDTIME_LENGTH 2 +#define TLE9104_CFG_CWDTIME_POS 6 + +#define TLE9104_CTRL_OUT1ONS_BIT BIT(1) +#define TLE9104_CTRL_OUT1ONC_BIT BIT(0) +#define TLE9104_CFG_OUT1DD_BIT BIT(0) +#define TLE9104_GLOBALSTATUS_OUTEN_BIT BIT(7) +#define TLE9104_GLOBALSTATUS_POR_LATCH_BIT BIT(0) +#define TLE9104_SPIFRAME_FAULTCOMMUNICATION_BIT BIT(13) + +enum tle9104_register { + TLE9104REGISTER_CTRL = 0x00, + TLE9104REGISTER_CFG = 0x01, + TLE9104REGISTER_GLOBALSTATUS = 0x07, + TLE9104REGISTER_ICVID = 0x08, +}; + +struct tle9104_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + + struct spi_dt_spec bus; + const struct gpio_dt_spec gpio_reset; + const struct gpio_dt_spec gpio_enable; + const struct gpio_dt_spec gpio_control[TLE9104_GPIO_COUNT]; +}; + +struct tle9104_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* each bit is one output channel, bit 0 = OUT1, ... */ + uint8_t state; + /* same as state, just kept for checking what has to be updated */ + uint8_t previous_state; + /* each bit defines if the output channel is configured, see state */ + uint8_t configured; + struct k_mutex lock; +}; + +static void tle9104_set_cfg_cwdtime(uint8_t *destination, uint8_t value) +{ + uint8_t length = TLE9104_CFG_CWDTIME_LENGTH; + uint8_t pos = TLE9104_CFG_CWDTIME_POS; + + *destination &= ~GENMASK(pos + length - 1, pos); + *destination |= FIELD_PREP(GENMASK(pos + length - 1, pos), value); +} + +static int tle9104_calculate_parity(uint16_t value) +{ + int parity = 1 + POPCOUNT(value); + + if ((value & BIT(TLE9104_FRAME_PARITY_POS)) != 0) { + parity--; + } + + return parity % 2; +} + +static void tle9104_apply_parity(uint16_t *value) +{ + int parity = tle9104_calculate_parity(*value); + + WRITE_BIT(*value, TLE9104_FRAME_PARITY_POS, parity); +} + +static bool tle9104_check_parity(uint16_t value) +{ + int parity = tle9104_calculate_parity(value); + + return ((value & BIT(TLE9104_FRAME_PARITY_POS)) >> TLE9104_FRAME_PARITY_POS) == parity; +} + +static int tle9104_transceive_frame(const struct device *dev, bool write, + enum tle9104_register write_reg, uint8_t write_data, + enum tle9104_register *read_reg, uint8_t *read_data) +{ + const struct tle9104_config *config = dev->config; + uint16_t write_frame; + uint16_t read_frame; + int result; + uint8_t buffer_tx[2]; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + write_frame = write_data << TLE9104_FRAME_DATA_POS; + write_frame |= write_reg << TLE9104_FRAME_ADDRESS_POS; + WRITE_BIT(write_frame, TLE9104_FRAME_RW_POS, write); + tle9104_apply_parity(&write_frame); + sys_put_be16(write_frame, buffer_tx); + LOG_DBG("writing in register 0x%02X of TLE9104 value 0x%02X, complete frame 0x%04X", + write_reg, write_data, write_frame); + + result = spi_transceive_dt(&config->bus, &tx, &rx); + if (result != 0) { + LOG_ERR("spi_write failed with error %i", result); + return result; + } + + read_frame = sys_get_be16(buffer_rx); + LOG_DBG("received complete frame 0x%04X", read_frame); + + if (!tle9104_check_parity(read_frame)) { + LOG_ERR("parity check for received frame of TLE9104 failed"); + return -EIO; + } + + if ((TLE9104_SPIFRAME_FAULTCOMMUNICATION_BIT & read_frame) != 0) { + LOG_WRN("communication fault reported by TLE9104"); + } + + *read_reg = FIELD_GET(GENMASK(TLE9104_FRAME_FAULTGLOBAL_POS - 1, TLE9104_FRAME_ADDRESS_POS), + read_frame); + *read_data = FIELD_GET(GENMASK(TLE9104_FRAME_ADDRESS_POS - 1, TLE9104_FRAME_DATA_POS), + read_frame); + + return 0; +} + +static int tle9104_write_register(const struct device *dev, enum tle9104_register reg, + uint8_t value) +{ + enum tle9104_register read_reg; + uint8_t read_data; + + return tle9104_transceive_frame(dev, true, reg, value, &read_reg, &read_data); +} + +static int tle9104_write_state(const struct device *dev) +{ + const struct tle9104_config *config = dev->config; + struct tle9104_data *data = dev->data; + bool spi_update_required = false; + uint8_t register_ctrl = 0x00; + int result; + + LOG_DBG("writing state 0x%02X to TLE9104", data->state); + + for (size_t i = 0; i < TLE9104_GPIO_COUNT; ++i) { + uint8_t mask = GENMASK(i, i); + bool current_value = (data->state & mask) != 0; + bool previous_value = (data->previous_state & mask) != 0; + + /* + * Setting the OUTx_ON bits results in a high impedance output, + * clearing them pulls the output to ground. Therefore the + * meaning here is intentionally inverted, as this will then turn + * out for a low active open drain output to be pulled to ground + * if set to off. + */ + if (current_value == 0) { + register_ctrl |= TLE9104_CTRL_OUT1ONS_BIT << (2 * i); + } else { + register_ctrl |= TLE9104_CTRL_OUT1ONC_BIT << (2 * i); + } + + if (current_value == previous_value) { + continue; + } + + if (config->gpio_control[i].port == NULL) { + spi_update_required = true; + continue; + } + + result = gpio_pin_set_dt(&config->gpio_control[i], current_value); + if (result != 0) { + LOG_ERR("unable to set control GPIO"); + return result; + } + } + + if (spi_update_required) { + result = tle9104_write_register(dev, TLE9104REGISTER_CTRL, register_ctrl); + if (result != 0) { + LOG_ERR("unable to set control register"); + return result; + } + } + + data->previous_state = data->state; + + return 0; +} + +static int tle9104_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + struct tle9104_data *data = dev->data; + int result; + + /* cannot execute a bus operation in an ISR context */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + if (pin >= TLE9104_GPIO_COUNT) { + LOG_ERR("invalid pin nummber %i", pin); + return -EINVAL; + } + + if ((flags & GPIO_INPUT) != 0) { + LOG_ERR("cannot configure pin as input"); + return -ENOTSUP; + } + + if ((flags & GPIO_OUTPUT) == 0) { + LOG_ERR("pin must be configured as an output"); + return -ENOTSUP; + } + + if ((flags & GPIO_SINGLE_ENDED) == 0) { + LOG_ERR("pin must be configured as single ended"); + return -ENOTSUP; + } + + if ((flags & GPIO_LINE_OPEN_DRAIN) == 0) { + LOG_ERR("pin must be configured as open drain"); + return -ENOTSUP; + } + + if ((flags & GPIO_PULL_UP) != 0) { + LOG_ERR("pin cannot have a pull up configured"); + return -ENOTSUP; + } + + if ((flags & GPIO_PULL_DOWN) != 0) { + LOG_ERR("pin cannot have a pull down configured"); + return -ENOTSUP; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + WRITE_BIT(data->state, pin, 0); + } else if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + WRITE_BIT(data->state, pin, 1); + } + + WRITE_BIT(data->configured, pin, 1); + result = tle9104_write_state(dev); + k_mutex_unlock(&data->lock); + + return result; +} + +static int tle9104_port_get_raw(const struct device *dev, uint32_t *value) +{ + ARG_UNUSED(dev); + ARG_UNUSED(value); + + LOG_ERR("input pins are not available"); + return -ENOTSUP; +} + +static int tle9104_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) +{ + struct tle9104_data *data = dev->data; + int result; + + /* cannot execute a bus operation in an ISR context */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_mutex_lock(&data->lock, K_FOREVER); + data->state = (data->state & ~mask) | (mask & value); + result = tle9104_write_state(dev); + k_mutex_unlock(&data->lock); + + return result; +} + +static int tle9104_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + return tle9104_port_set_masked_raw(dev, mask, mask); +} + +static int tle9104_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + return tle9104_port_set_masked_raw(dev, mask, 0); +} + +static int tle9104_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + struct tle9104_data *data = dev->data; + int result; + + /* cannot execute a bus operation in an ISR context */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_mutex_lock(&data->lock, K_FOREVER); + data->state ^= mask; + result = tle9104_write_state(dev); + k_mutex_unlock(&data->lock); + + return result; +} + +static int tle9104_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + return -ENOTSUP; +} + +static const struct gpio_driver_api api_table = { + .pin_configure = tle9104_pin_configure, + .port_get_raw = tle9104_port_get_raw, + .port_set_masked_raw = tle9104_port_set_masked_raw, + .port_set_bits_raw = tle9104_port_set_bits_raw, + .port_clear_bits_raw = tle9104_port_clear_bits_raw, + .port_toggle_bits = tle9104_port_toggle_bits, + .pin_interrupt_configure = tle9104_pin_interrupt_configure, +}; + +static int tle9104_init(const struct device *dev) +{ + const struct tle9104_config *config = dev->config; + struct tle9104_data *data = dev->data; + uint8_t register_cfg; + uint8_t register_globalstatus; + uint8_t register_icvid; + enum tle9104_register read_reg; + int result; + + LOG_DBG("initialize TLE9104 instance %s", dev->name); + + result = k_mutex_init(&data->lock); + if (result != 0) { + LOG_ERR("unable to initialize mutex"); + return result; + } + + if (!spi_is_ready_dt(&config->bus)) { + LOG_ERR("SPI bus %s is not ready", config->bus.bus->name); + return -ENODEV; + } + + register_cfg = 0x00; + + for (int i = 0; i < TLE9104_GPIO_COUNT; ++i) { + const struct gpio_dt_spec *current = config->gpio_control + i; + + if (current->port == NULL) { + LOG_DBG("got no control port for output %i, will control it via SPI", i); + continue; + } + + register_cfg |= TLE9104_CFG_OUT1DD_BIT << i; + + if (!device_is_ready(current->port)) { + LOG_ERR("control GPIO %s is not ready", current->port->name); + return -ENODEV; + } + + result = gpio_pin_configure_dt(current, GPIO_OUTPUT_INACTIVE); + if (result != 0) { + LOG_ERR("failed to initialize control GPIO %i", i); + return result; + } + } + + if (config->gpio_enable.port != NULL) { + if (!device_is_ready(config->gpio_enable.port)) { + LOG_ERR("enable GPIO %s is not ready", config->gpio_enable.port->name); + return -ENODEV; + } + + result = gpio_pin_configure_dt(&config->gpio_enable, GPIO_OUTPUT_ACTIVE); + if (result != 0) { + LOG_ERR("failed to enable TLE9104"); + return result; + } + } + + result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); + if (result != 0) { + LOG_ERR("failed to initialize GPIO for reset"); + return result; + } + + k_busy_wait(TLE9104_RESET_DURATION_TIME_US); + gpio_pin_set_dt(&config->gpio_reset, 0); + k_busy_wait(TLE9104_RESET_DURATION_WAIT_TIME_US + + TLE9104_RESET_DURATION_WAIT_TIME_SAFETY_MARGIN_US); + + /* + * The first read value should be the ICVID, this acts also as the setup of the + * global status register address. + */ + result = tle9104_transceive_frame(dev, false, TLE9104REGISTER_GLOBALSTATUS, 0x00, &read_reg, + ®ister_icvid); + if (result != 0) { + return result; + } + + if (read_reg != TLE9104REGISTER_ICVID) { + LOG_ERR("expected to read register ICVID, got instead 0x%02X", read_reg); + return -EIO; + } + + if (register_icvid != TLE9104_ICVERSIONID) { + LOG_ERR("got unexpected IC version id 0x%02X", register_icvid); + return -EIO; + } + + result = tle9104_transceive_frame(dev, false, TLE9104REGISTER_GLOBALSTATUS, 0x00, &read_reg, + ®ister_globalstatus); + if (result != 0) { + return result; + } + + if (read_reg != TLE9104REGISTER_GLOBALSTATUS) { + LOG_ERR("expected to read register GLOBALSTATUS, got instead 0x%02X", read_reg); + return -EIO; + } + + if ((register_globalstatus & TLE9104_GLOBALSTATUS_POR_LATCH_BIT) == 0) { + LOG_ERR("no power on reset detected"); + return -EIO; + } + + result = tle9104_write_register(dev, TLE9104REGISTER_CFG, register_cfg); + if (result != 0) { + LOG_ERR("unable to write configuration"); + return result; + } + + register_globalstatus = 0x00; + /* disable communication watchdog */ + tle9104_set_cfg_cwdtime(®ister_cfg, 0); + /* enable outputs */ + register_globalstatus |= TLE9104_GLOBALSTATUS_OUTEN_BIT; + + result = tle9104_write_register(dev, TLE9104REGISTER_GLOBALSTATUS, register_globalstatus); + if (result != 0) { + LOG_ERR("unable to write global status"); + return result; + } + + return 0; +} + +BUILD_ASSERT(CONFIG_GPIO_TLE9104_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, + "TLE9104 must be initialized after SPI"); + +#define TLE9104_INIT_GPIO_FIELDS(inst, gpio) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, gpio), \ + (GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), gpio, 0)), ({0})) + +#define TLE9104_INIT(inst) \ + static const struct tle9104_config tle9104_##inst##_config = { \ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ + }, \ + .bus = SPI_DT_SPEC_INST_GET( \ + inst, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ + .gpio_enable = TLE9104_INIT_GPIO_FIELDS(inst, en_gpios), \ + .gpio_reset = GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), resn_gpios, 0), \ + .gpio_control = { \ + TLE9104_INIT_GPIO_FIELDS(inst, in1_gpios), \ + TLE9104_INIT_GPIO_FIELDS(inst, in2_gpios), \ + TLE9104_INIT_GPIO_FIELDS(inst, in3_gpios), \ + TLE9104_INIT_GPIO_FIELDS(inst, in4_gpios), \ + }, \ + }; \ + \ + static struct tle9104_data tle9104_##inst##_drvdata; \ + \ + /* This has to be initialized after the SPI peripheral. */ \ + DEVICE_DT_INST_DEFINE(inst, tle9104_init, NULL, &tle9104_##inst##_drvdata, \ + &tle9104_##inst##_config, POST_KERNEL, \ + CONFIG_GPIO_TLE9104_INIT_PRIORITY, &api_table); + +DT_INST_FOREACH_STATUS_OKAY(TLE9104_INIT) From 003c132de6799bb583afb2eca8243fc0a217792f Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Tue, 18 Jul 2023 11:17:02 +0200 Subject: [PATCH 3921/4498] tests: drivers: gpio: add TLE9104 to the build_all tests Add an instance of the TLE9104 to the build_all tests. Signed-off-by: Benedikt Schmidt --- tests/drivers/build_all/gpio/app.overlay | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/drivers/build_all/gpio/app.overlay b/tests/drivers/build_all/gpio/app.overlay index 231d05a792f..375b3ab25dc 100644 --- a/tests/drivers/build_all/gpio/app.overlay +++ b/tests/drivers/build_all/gpio/app.overlay @@ -258,6 +258,17 @@ ngpios = <8>; }; }; + + test_spi_tle9104: tle9104@4 { + compatible = "infineon,tle9104"; + spi-max-frequency = <0>; + reg = <0x04>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + resn-gpios = <&test_gpio 0 0>; + en-gpios = <&test_gpio 0 0>; + }; }; }; }; From 299a10e0db4d571a1526fd5971e752d20abbf8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 18:29:21 +0100 Subject: [PATCH 3922/4498] boards: doc: fix Toradex Verdin iMX8M title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The title for this board README was very broken, messing up not only this board's README but also the boards TOC. Signed-off-by: Benjamin Cabé --- boards/arm/verdin_imx8mp_m7/doc/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boards/arm/verdin_imx8mp_m7/doc/index.rst b/boards/arm/verdin_imx8mp_m7/doc/index.rst index 6a35534a99f..52eeebf3578 100644 --- a/boards/arm/verdin_imx8mp_m7/doc/index.rst +++ b/boards/arm/verdin_imx8mp_m7/doc/index.rst @@ -1,8 +1,7 @@ .. _verdin_imx8mp_m7: Toradex Verdin iMX8M Plus SoM - -############################################ +############################# Overview ******** From bdbf928b62f0778df92abbaaf61c60cc49f4be03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 18:35:32 +0100 Subject: [PATCH 3923/4498] boards: doc: fix Toradex Verdin iMX8M typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several fixes to this board's readme including broken build instructions. Signed-off-by: Benjamin Cabé --- boards/arm/verdin_imx8mp_m7/doc/index.rst | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/boards/arm/verdin_imx8mp_m7/doc/index.rst b/boards/arm/verdin_imx8mp_m7/doc/index.rst index 52eeebf3578..6dd483a0a63 100644 --- a/boards/arm/verdin_imx8mp_m7/doc/index.rst +++ b/boards/arm/verdin_imx8mp_m7/doc/index.rst @@ -25,18 +25,18 @@ The Verdin iMX8M Plus family consists of: | Verdin iMX8M Plus QuadLite 1GB IT | i.MX 8M Plus QuadLite | +-------------------------------------------------+-----------------------+ -Quoting NXP - -:: +Quoting NXP: The i.MX 8M Plus family focuses on machine learning and vision, advanced multimedia, and industrial automation with high reliability. It is built to meet the needs of Smart Home, Building, City and Industry 4.0 applications. The Verdin iMX8M Plus integrates a total of 4 Arm Cortex™-A53 CPUs, operating at 1.6 GHz, alongside a single Arm Cortex™-M7F microcontroller operating at 800 MHz. -.. image:: verdin_imx8mp_front.jpg +.. figure:: verdin_imx8mp_front.jpg :align: center - :alt: Toradex Verdin iMX8M Plus (Credit: Toradex) + :alt: Toradex Verdin iMX8M Plus + + Toradex Verdin iMX8M Plus (Credit: Toradex) Regarding the Cortex-A53 cluster, it employs the ARMv8-A architecture as a mid-range and energy-efficient processor. With four cores in this cluster, each core is equipped with its own L1 memory system. Moreover, the cluster incorporates a unified L2 cache that offers supplementary functions. This cache is housed within a single APR region. @@ -129,7 +129,8 @@ Other hardware features are not currently supported by the port. Connections and IOs =================== -UART: +UART +---- Zephyr is configured to use the UART4 by default, which is connected to the FTDI USB converter on most Toradex carrier boards. @@ -149,7 +150,8 @@ example). You can change the UART by changing the ``zephyr,console`` and | UART_4 | UART4 | Cortex-M4 debug UART | +---------------+-----------------+---------------------------+ -GPIO: +GPIO +---- All the GPIO banks available are enabled in the :zephyr_file:`dts/arm/nxp/nxp_imx8ml_m7.dtsi`. @@ -195,8 +197,8 @@ For more information about memory mapping see the At compilation time you have to choose which RAM will be used. To facilitate this process, there are two targets available: -- verdin_imx8mp_m7_itcm, which uses the ITCM configuration. -- verdin_imx8mp_m7_ddr, which uses the DDR configuration. +- ``verdin_imx8mp_m7_itcm``, which uses the ITCM configuration. +- ``verdin_imx8mp_m7_ddr``, which uses the DDR configuration. Starting the Cortex-M7 via U-Boot @@ -209,11 +211,11 @@ card into the board. Power it up and stop the u-boot execution at prompt. Load the M7 binary onto the desired memory and start its execution using: ITCM -=== +==== Loading the binary from an EXT4 partition: -.. code-block:: console +.. code-block:: shell ext4load mmc 2:2 ${loadaddr} //zephyr.bin cp.b ${loadaddr} 0x7e0000 @@ -224,7 +226,7 @@ DDR Loading the binary from an EXT4 partition: -.. code-block:: console +.. code-block:: shell ext4load mmc 2:2 ${loadaddr} //zephyr.bin cp.b ${loadaddr} 0x80000000 @@ -240,7 +242,7 @@ Here is an example for the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: verdin_imx8mp_m7 + :board: verdin_imx8mp_m7_ddr :goals: debug Open a serial terminal, step through the application in your debugger, and you @@ -249,7 +251,7 @@ should see the following message in the terminal: .. code-block:: console *** Booting Zephyr OS build zephyr-v3.4.0-2300-g03905f7e55d2 *** - Hello World! verdin_imx8mp_m7 + Hello World! verdin_imx8mp_m7_ddr References ========== From 3c8333ac107ee84dfb1fd28a131a03f49fb8b16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 18:39:06 +0100 Subject: [PATCH 3924/4498] boards: doc: fix Toradex Verdin iMX8M line length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documentation .rst files should wrap at 100 characters. Signed-off-by: Benjamin Cabé --- boards/arm/verdin_imx8mp_m7/doc/index.rst | 95 +++++++++++++---------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/boards/arm/verdin_imx8mp_m7/doc/index.rst b/boards/arm/verdin_imx8mp_m7/doc/index.rst index 6dd483a0a63..455acb8c290 100644 --- a/boards/arm/verdin_imx8mp_m7/doc/index.rst +++ b/boards/arm/verdin_imx8mp_m7/doc/index.rst @@ -6,8 +6,8 @@ Toradex Verdin iMX8M Plus SoM Overview ******** -The Verdin iMX8M Plus is a Computer on Module (CoM) developed by Toradex. It is based on the NXP® i.MX 8M Plus family of -processors (or System on Chips - SoCs). +The Verdin iMX8M Plus is a Computer on Module (CoM) developed by Toradex. It is based on the NXP® +i.MX 8M Plus family of processors (or System on Chips - SoCs). The Verdin iMX8M Plus family consists of: @@ -27,10 +27,12 @@ The Verdin iMX8M Plus family consists of: Quoting NXP: - The i.MX 8M Plus family focuses on machine learning and vision, advanced multimedia, and industrial automation with high reliability. - It is built to meet the needs of Smart Home, Building, City and Industry 4.0 applications. + The i.MX 8M Plus family focuses on machine learning and vision, advanced multimedia, and + industrial automation with high reliability. It is built to meet the needs of Smart Home, + Building, City and Industry 4.0 applications. -The Verdin iMX8M Plus integrates a total of 4 Arm Cortex™-A53 CPUs, operating at 1.6 GHz, alongside a single Arm Cortex™-M7F microcontroller operating at 800 MHz. +The Verdin iMX8M Plus integrates a total of 4 Arm Cortex™-A53 CPUs, operating at 1.6 GHz, alongside +a single Arm Cortex™-M7F microcontroller operating at 800 MHz. .. figure:: verdin_imx8mp_front.jpg :align: center @@ -38,16 +40,23 @@ The Verdin iMX8M Plus integrates a total of 4 Arm Cortex™-A53 CPUs, operating Toradex Verdin iMX8M Plus (Credit: Toradex) -Regarding the Cortex-A53 cluster, it employs the ARMv8-A architecture as a mid-range and energy-efficient processor. With four cores in this cluster, each core is -equipped with its own L1 memory system. Moreover, the cluster incorporates a unified L2 cache that offers supplementary functions. This cache is housed within a single APR region. -Facilitating debugging processes, the cores support both real-time trace through the ETM system and static debugging via JTAG. Furthermore, the platform features support for real-time trace -capabilities, achieved through ARM's CoreSight ETM modules, and also enables cross-triggering by utilizing CTI and CTM modules. - -The Arm® Cortex®-M7 microcontroller is indicated for Real-time control, combining high-performance with a minimal interrupt latency. -It stands out for its compatibility with existing Cortex-M profile processors. The microcontroller employs an efficient in-order super-scalar pipeline, -allowing dual-issued instructions such as load/load and load/store pairs, thanks to its multiple memory interfaces. These interfaces encompass Tightly-Coupled Memory (TCM), Harvard caches, and an AXI master interface. -The Arm Cortex-M7 Platform boasts features like a 32 KB L1 Instruction Cache, 32 KB L1 Data Cache, Floating Point Unit (FPU) with FPv5 architecture support, and an Internal Trace (TRC) mechanism. -Furthermore, the chip supports 160 IRQs, and integrates crucial Arm CoreSight components including ETM and CTI, dedicated to facilitating debug and trace functions. +Regarding the Cortex-A53 cluster, it employs the ARMv8-A architecture as a mid-range and +energy-efficient processor. With four cores in this cluster, each core is equipped with its own L1 +memory system. Moreover, the cluster incorporates a unified L2 cache that offers supplementary +functions. This cache is housed within a single APR region. Facilitating debugging processes, the +cores support both real-time trace through the ETM system and static debugging via JTAG. +Furthermore, the platform features support for real-time trace capabilities, achieved through ARM's +CoreSight ETM modules, and also enables cross-triggering by utilizing CTI and CTM modules. + +The Arm® Cortex®-M7 microcontroller is indicated for Real-time control, combining high-performance +with a minimal interrupt latency. It stands out for its compatibility with existing Cortex-M profile +processors. The microcontroller employs an efficient in-order super-scalar pipeline, allowing +dual-issued instructions such as load/load and load/store pairs, thanks to its multiple memory +interfaces. These interfaces encompass Tightly-Coupled Memory (TCM), Harvard caches, and an AXI +master interface. The Arm Cortex-M7 Platform boasts features like a 32 KB L1 Instruction Cache, 32 +KB L1 Data Cache, Floating Point Unit (FPU) with FPv5 architecture support, and an Internal Trace +(TRC) mechanism. Furthermore, the chip supports 160 IRQs, and integrates crucial Arm CoreSight +components including ETM and CTI, dedicated to facilitating debug and trace functions. Hardware ******** @@ -118,9 +127,11 @@ The Zephyr verdin_imx8mp_m7 board configuration supports the following hardware The default configuration can be found in the defconfig file: -- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig`, if you choose to use the ITCM memory. +- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_itcm_defconfig`, if you choose to use + the ITCM memory. -- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig`, if you choose to use the DDR memory. +- :zephyr_file:`boards/arm/verdin_imx8mp_m7/verdin_imx8mp_m7_ddr_defconfig`, if you choose to use + the DDR memory. It is recommended to disable peripherals used by the M7 core on the Linux host. @@ -132,15 +143,16 @@ Connections and IOs UART ---- -Zephyr is configured to use the UART4 by default, which is connected to the FTDI -USB converter on most Toradex carrier boards. +Zephyr is configured to use the UART4 by default, which is connected to the FTDI USB converter on +most Toradex carrier boards. -This is also the UART connected to WiFi/BT chip in modules that have the WiFi/BT -chip. Therefore, if UART4 is used, WiFI/BT will not work properly. +This is also the UART connected to WiFi/BT chip in modules that have the WiFi/BT chip. Therefore, if +UART4 is used, WiFI/BT will not work properly. -If the WiFi/BT is needed, then another UART should be used for Zephyr (UART1 for -example). You can change the UART by changing the ``zephyr,console`` and -``zephyr,shell-uart`` in the :zephyr_file:`boards/arm/verdin_imx8mp_m7_itcm.dts` or :zephyr_file:`boards/arm/verdin_imx8mp_m7_ddr.dts` file. +If the WiFi/BT is needed, then another UART should be used for Zephyr (UART1 for example). You can +change the UART by changing the ``zephyr,console`` and ``zephyr,shell-uart`` in the +:zephyr_file:`boards/arm/verdin_imx8mp_m7_itcm.dts` or +:zephyr_file:`boards/arm/verdin_imx8mp_m7_ddr.dts` file. +---------------+-----------------+---------------------------+ | Board Name | SoC Name | Usage | @@ -163,20 +175,19 @@ The M7 Core is configured to run at a 800 MHz clock speed. Serial Port =========== -The i.MX8M Plus SoC has four UARTs. UART_4 is configured for the console and -the remaining are not used/tested. +The i.MX8M Plus SoC has four UARTs. UART_4 is configured for the console and the remaining are not +used/tested. Programming and Debugging ************************* -The Verdin iMX8M Plus board doesn't have QSPI flash for the M7, and it needs -to be started by the A53 core. The A53 core is responsible to load the M7 binary -application into the RAM, put the M7 in reset, set the M7 Program Counter and -Stack Pointer, and get the M7 out of reset. The A53 can perform these steps at -bootloader level or after the Linux system has booted. +The Verdin iMX8M Plus board doesn't have QSPI flash for the M7, and it needs to be started by the +A53 core. The A53 core is responsible to load the M7 binary application into the RAM, put the M7 in +reset, set the M7 Program Counter and Stack Pointer, and get the M7 out of reset. The A53 can +perform these steps at bootloader level or after the Linux system has booted. -The M7 can use up to 3 different RAMs (currently, only two configurations are -supported: ITCM and DDR). These are the memory mapping for A53 and M7: +The M7 can use up to 3 different RAMs (currently, only two configurations are supported: ITCM and +DDR). These are the memory mapping for A53 and M7: +------------+-------------------------+------------------------+-----------------------+----------------------+ | Region | Cortex-A53 | Cortex-M7 (System Bus) | Cortex-M7 (Code Bus) | Size | @@ -192,10 +203,11 @@ supported: ITCM and DDR). These are the memory mapping for A53 and M7: | DDR | 0x80000000-0x803FFFFF | 0x80200000-0x803FFFFF | 0x80000000-0x801FFFFF | 2MB | +------------+-------------------------+------------------------+-----------------------+----------------------+ -For more information about memory mapping see the -`i.MX 8M Plus Applications Processor Reference Manual`_ (section 2.1 to 2.3) +For more information about memory mapping see the `i.MX 8M Plus Applications Processor Reference +Manual`_ (section 2.1 to 2.3) -At compilation time you have to choose which RAM will be used. To facilitate this process, there are two targets available: +At compilation time you have to choose which RAM will be used. To facilitate this process, there are +two targets available: - ``verdin_imx8mp_m7_itcm``, which uses the ITCM configuration. - ``verdin_imx8mp_m7_ddr``, which uses the DDR configuration. @@ -204,9 +216,9 @@ At compilation time you have to choose which RAM will be used. To facilitate thi Starting the Cortex-M7 via U-Boot ================================= -Load and run Zephyr on M7 from A53 using u-boot by copying the compiled -``zephyr.bin`` to the first FAT partition of the SD card and plug the SD -card into the board. Power it up and stop the u-boot execution at prompt. +Load and run Zephyr on M7 from A53 using u-boot by copying the compiled ``zephyr.bin`` to the first +FAT partition of the SD card and plug the SD card into the board. Power it up and stop the u-boot +execution at prompt. Load the M7 binary onto the desired memory and start its execution using: @@ -235,8 +247,9 @@ Loading the binary from an EXT4 partition: Debugging ========= -Toradex Verdin iMX8M Plus SoM can be debugged by connecting an external JLink JTAG debugger to the X56 debug connector and to the PC, or simply connecting a USB-C to X66 on the Verdin Development Board. -Then, the application can be debugged using the usual way. +Toradex Verdin iMX8M Plus SoM can be debugged by connecting an external JLink JTAG debugger to the +X56 debug connector and to the PC, or simply connecting a USB-C to X66 on the Verdin Development +Board. Then, the application can be debugged using the usual way. Here is an example for the :ref:`hello_world` application. From 97b9bce995c0df59fe7390650e13fba5b062e5d9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 09:25:13 +0100 Subject: [PATCH 3925/4498] doc/services/sensing: Refer to native_sim overlay instead of native_posix Refer to the native_sim overlay instead of the native_posix one, as native_posix is going to be deprecated soon. Signed-off-by: Alberto Escolar Piedras --- doc/services/sensing/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/services/sensing/index.rst b/doc/services/sensing/index.rst index d0ae0bea5ee..fac113a1772 100644 --- a/doc/services/sensing/index.rst +++ b/doc/services/sensing/index.rst @@ -241,7 +241,7 @@ Device Tree Configuration Sensing subsystem using device tree to configuration all sensor instances and their properties, reporting relationships. -See the example :zephyr_file:`samples/subsys/sensing/simple/boards/native_posix.overlay` +See the example :zephyr_file:`samples/subsys/sensing/simple/boards/native_sim.overlay` API Reference ************* From 196ceaf2f4ca984a1d84dc570926e793ff6a1f3e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 09:27:59 +0100 Subject: [PATCH 3926/4498] samples/drivers/uart/native_tty: Swap native_posix and sim overlay Refer to the native_sim overlay instead of the native_posix one, as native_posix is going to be deprecated soon. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/uart/native_tty/README.rst | 2 +- .../uart/native_tty/boards/native_posix.overlay | 16 +--------------- .../uart/native_tty/boards/native_sim.overlay | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/samples/drivers/uart/native_tty/README.rst b/samples/drivers/uart/native_tty/README.rst index 6b6e2a3175e..78c101dea1f 100644 --- a/samples/drivers/uart/native_tty/README.rst +++ b/samples/drivers/uart/native_tty/README.rst @@ -28,7 +28,7 @@ Requirements ``/dev/ttyUSB0`` and ``/dev/ttyUSB1`` in the system. You can check what they are in your system by running the command ``ls -l /dev/tty*``. If that is not the case on your machine you can either change the ``serial-port`` properties - in the ``boards/native_posix.overlay`` file or using the command line options + in the ``boards/native_sim.overlay`` file or using the command line options ``-uart_port`` and ``-uart_port2``. Building and Running diff --git a/samples/drivers/uart/native_tty/boards/native_posix.overlay b/samples/drivers/uart/native_tty/boards/native_posix.overlay index 24f1bd95705..6a3daca3241 100644 --- a/samples/drivers/uart/native_tty/boards/native_posix.overlay +++ b/samples/drivers/uart/native_tty/boards/native_posix.overlay @@ -1,15 +1 @@ -/ { - uart0: uart { - status = "okay"; - compatible = "zephyr,native-tty-uart"; - current-speed = <115200>; - serial-port = "/dev/ttyUSB0"; - }; - - uart2: uart2 { - status = "okay"; - compatible = "zephyr,native-tty-uart"; - current-speed = <115200>; - serial-port = "/dev/ttyUSB1"; - }; -}; +#include "native_sim.overlay" diff --git a/samples/drivers/uart/native_tty/boards/native_sim.overlay b/samples/drivers/uart/native_tty/boards/native_sim.overlay index 2b055bf3de6..24f1bd95705 100644 --- a/samples/drivers/uart/native_tty/boards/native_sim.overlay +++ b/samples/drivers/uart/native_tty/boards/native_sim.overlay @@ -1 +1,15 @@ -#include "native_posix.overlay" +/ { + uart0: uart { + status = "okay"; + compatible = "zephyr,native-tty-uart"; + current-speed = <115200>; + serial-port = "/dev/ttyUSB0"; + }; + + uart2: uart2 { + status = "okay"; + compatible = "zephyr,native-tty-uart"; + current-speed = <115200>; + serial-port = "/dev/ttyUSB1"; + }; +}; From bf466da69fba5096aa1120d0c8cbcc90e6a6a63f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 09:35:01 +0100 Subject: [PATCH 3927/4498] samples zbus: Swap native_posix with native_sim In the docs replace references to native_posix with native_sim Switch the default test platform to native_sim from native_posix Signed-off-by: Alberto Escolar Piedras --- samples/subsys/zbus/remote_mock/README.rst | 10 +++++++--- samples/subsys/zbus/remote_mock/sample.yaml | 2 +- samples/subsys/zbus/uart_bridge/README.rst | 10 +++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/samples/subsys/zbus/remote_mock/README.rst b/samples/subsys/zbus/remote_mock/README.rst index c1a098839de..f599783e0fa 100644 --- a/samples/subsys/zbus/remote_mock/README.rst +++ b/samples/subsys/zbus/remote_mock/README.rst @@ -16,12 +16,12 @@ Building and Running ******************** This project outputs to the console. It can be built and executed -on native_posix as follows: +on :ref:`native_sim ` as follows: .. zephyr-app-commands:: :zephyr-app: samples/subsys/zbus/remote_mock :host-os: unix - :board: native_posix + :board: native_sim :goals: run Sample Output @@ -63,7 +63,11 @@ The :file:`remote_mock.py` script can be executed using the following command: python3.8 samples/subsys/zbus/remote_mock/remote_mock.py /dev/pts/2 -Note the run command above prints the value of pts port because it is running in ``native_posix``. Look at the line indicating ``uart_1 connected to pseudotty: /dev/pts/2``. It can be different in your case. If you are using a board, read the documentation to get the correct port destination (in Linux is something like ``/dev/tty...`` or in Windows ``COM...``). +Note the run command above prints the value of pts port because it is running in +:ref:`native_sim `. +Look at the line indicating ``uart_1 connected to pseudotty: /dev/pts/2``. +It can be different in your case. If you are using a board, read the documentation to get the +correct port destination (in Linux is something like ``/dev/tty...`` or in Windows ``COM...``). From the remote mock (Python script), you would see something like this: diff --git a/samples/subsys/zbus/remote_mock/sample.yaml b/samples/subsys/zbus/remote_mock/sample.yaml index 3e49a6e2b03..1b632901ed2 100644 --- a/samples/subsys/zbus/remote_mock/sample.yaml +++ b/samples/subsys/zbus/remote_mock/sample.yaml @@ -9,4 +9,4 @@ tests: - native_sim - hifive1_revb integration_platforms: - - native_posix + - native_sim diff --git a/samples/subsys/zbus/uart_bridge/README.rst b/samples/subsys/zbus/uart_bridge/README.rst index c14c0e8d64d..a0101fa45b2 100644 --- a/samples/subsys/zbus/uart_bridge/README.rst +++ b/samples/subsys/zbus/uart_bridge/README.rst @@ -14,12 +14,12 @@ Building and Running ******************** This project outputs to the console. It can be built and executed -on native_posix as follows: +on native_sim as follows: .. zephyr-app-commands:: :zephyr-app: samples/subsys/zbus/uart_bridge :host-os: unix - :board: native_posix + :board: native_sim :goals: run Sample Output @@ -68,7 +68,11 @@ The :file:`decoder.py` script can be executed using the following command: python3.8 samples/subsys/zbus/uart_bridge/decoder.py /dev/pts/2 -Note the run command above prints the value of pts port because it is running in ``native_posix``. Look at the line indicating ``uart_1 connected to pseudotty: /dev/pts/2``. It can be different in your case. If you are using a board, read the documentation to get the correct port destination (in Linux is something like ``/dev/tty...`` or in Windows ``COM...``). +Note the run command above prints the value of pts port because it is running in +:ref:`native_sim `. +Look at the line indicating ``uart_1 connected to pseudotty: /dev/pts/2``. +It can be different in your case. If you are using a board, read the documentation to get the +correct port destination (in Linux is something like ``/dev/tty...`` or in Windows ``COM...``). From the serial decoder (Python script), you would see something like this: From c93cef0996c19abeef50c40d2893b99347bb6b21 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 09:43:51 +0100 Subject: [PATCH 3928/4498] docs: Sample definition: Replace native_posix with native_sim As native_posix is going to be deprecated soon. Signed-off-by: Alberto Escolar Piedras --- samples/sample_definition_and_criteria.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sample_definition_and_criteria.rst b/samples/sample_definition_and_criteria.rst index be0c9dfc3ef..8e69fe4a63a 100644 --- a/samples/sample_definition_and_criteria.rst +++ b/samples/sample_definition_and_criteria.rst @@ -38,7 +38,7 @@ Sample Criteria tests: sample.kernel.cond_var: integration_platforms: - - native_posix + - native_sim tags: kernel condition_variables harness: console harness_config: From 0ce4de8eec25a986a27db57f1731174eb023db39 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 09:50:30 +0100 Subject: [PATCH 3929/4498] pytest sample & docs: Replace native_posix with native_sim In the docs replace references to native_posix with native_sim Switch the default test platform to native_sim from native_posix Signed-off-by: Alberto Escolar Piedras --- samples/subsys/testsuite/pytest/basic/testcase.yaml | 6 ++++-- samples/subsys/testsuite/pytest/shell/testcase.yaml | 2 +- scripts/pylib/pytest-twister-harness/README.rst | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/samples/subsys/testsuite/pytest/basic/testcase.yaml b/samples/subsys/testsuite/pytest/basic/testcase.yaml index a7c28cafc3b..6dc504cd64c 100644 --- a/samples/subsys/testsuite/pytest/basic/testcase.yaml +++ b/samples/subsys/testsuite/pytest/basic/testcase.yaml @@ -1,6 +1,8 @@ tests: sample.twister.pytest: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim harness: pytest harness_config: pytest_args: ["--custom-pytest-arg", "foo", "--cmdopt", "."] @@ -8,4 +10,4 @@ tests: - test_framework - pytest integration_platforms: - - native_posix + - native_sim diff --git a/samples/subsys/testsuite/pytest/shell/testcase.yaml b/samples/subsys/testsuite/pytest/shell/testcase.yaml index 02a3bcf9620..86b9314f444 100644 --- a/samples/subsys/testsuite/pytest/shell/testcase.yaml +++ b/samples/subsys/testsuite/pytest/shell/testcase.yaml @@ -6,7 +6,7 @@ tests: extra_configs: - arch:posix:CONFIG_NATIVE_UART_0_ON_STDINOUT=y integration_platforms: - - native_posix + - native_sim - qemu_cortex_m3 tags: - test_framework diff --git a/scripts/pylib/pytest-twister-harness/README.rst b/scripts/pylib/pytest-twister-harness/README.rst index 814282fc57b..860b7cd645d 100644 --- a/scripts/pylib/pytest-twister-harness/README.rst +++ b/scripts/pylib/pytest-twister-harness/README.rst @@ -20,8 +20,8 @@ Run exemplary test shell application by Twister: cd ${ZEPHYR_BASE} - # native_posix & QEMU - ./scripts/twister -p native_posix -p qemu_x86 -T samples/subsys/testsuite/pytest/shell + # native_sim & QEMU + ./scripts/twister -p native_sim -p qemu_x86 -T samples/subsys/testsuite/pytest/shell # hardware ./scripts/twister -p nrf52840dk_nrf52840 --device-testing --device-serial /dev/ttyACM0 -T samples/subsys/testsuite/pytest/shell @@ -34,8 +34,8 @@ or build shell application by west and call pytest directly: cd ${ZEPHYR_BASE}/samples/subsys/testsuite/pytest/shell - # native_posix - west build -p -b native_posix -- -DCONFIG_NATIVE_UART_0_ON_STDINOUT=y + # native_sim + west build -p -b native_sim -- -DCONFIG_NATIVE_UART_0_ON_STDINOUT=y pytest --twister-harness --device-type=native --build-dir=build -p twister_harness.plugin # QEMU From 4a0dec6a5a16f16c5c88ea60af4796079be267fd Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 10:05:29 +0100 Subject: [PATCH 3930/4498] subsys/bindesc: Fix kconfig dependency BINDESC can be used with any POSIX arch based target, not just native_posix. Fix the kconfig filter and the sample yaml filter. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/bindesc/hello_bindesc/sample.yaml | 3 +-- subsys/bindesc/Kconfig | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/subsys/bindesc/hello_bindesc/sample.yaml b/samples/subsys/bindesc/hello_bindesc/sample.yaml index e923744c3d8..adea05379a2 100644 --- a/samples/subsys/bindesc/hello_bindesc/sample.yaml +++ b/samples/subsys/bindesc/hello_bindesc/sample.yaml @@ -3,7 +3,6 @@ sample: tests: sample.bindesc: tags: bindesc - filter: CONFIG_ARCH_SUPPORTS_ROM_START - build_only: true + filter: CONFIG_ARCH_SUPPORTS_ROM_START or CONFIG_ARCH_POSIX integration_platforms: - native_posix diff --git a/subsys/bindesc/Kconfig b/subsys/bindesc/Kconfig index 0f55564d460..e8c158b8c84 100644 --- a/subsys/bindesc/Kconfig +++ b/subsys/bindesc/Kconfig @@ -3,7 +3,7 @@ menuconfig BINDESC bool "Binary Descriptors" - depends on ARCH_SUPPORTS_ROM_START || BOARD_NATIVE_POSIX + depends on ARCH_SUPPORTS_ROM_START || ARCH_POSIX help Binary Descriptors - constant data accessible outside of the executable image From b2a84eaf12b1619d334f8182a18ba0ef4719e8ac Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 10:06:43 +0100 Subject: [PATCH 3931/4498] samples bindesc: Add runtime test and change default to native_sim * In the docs replace references to native_posix with native_sim * Switch the default test platform to native_sim from native_posix * Add a runtime check for this sample Signed-off-by: Alberto Escolar Piedras --- samples/subsys/bindesc/hello_bindesc/README.rst | 2 +- samples/subsys/bindesc/hello_bindesc/sample.yaml | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/samples/subsys/bindesc/hello_bindesc/README.rst b/samples/subsys/bindesc/hello_bindesc/README.rst index f2cd9e2d16e..0596639b518 100644 --- a/samples/subsys/bindesc/hello_bindesc/README.rst +++ b/samples/subsys/bindesc/hello_bindesc/README.rst @@ -27,6 +27,6 @@ To dump all binary descriptors in the image, run: west bindesc dump build/zephyr/zephyr.bin (Note: you can also dump the contents of ``zephyr.elf``, if your build system -does not produce a ``*.bin`` file, e.g. compiling for ``native_posix``.) +does not produce a ``*.bin`` file, e.g. compiling for ``native_sim``.) For more details see :ref:`binary_descriptors` and :ref:`west-bindesc`. diff --git a/samples/subsys/bindesc/hello_bindesc/sample.yaml b/samples/subsys/bindesc/hello_bindesc/sample.yaml index adea05379a2..2725b9ab241 100644 --- a/samples/subsys/bindesc/hello_bindesc/sample.yaml +++ b/samples/subsys/bindesc/hello_bindesc/sample.yaml @@ -5,4 +5,16 @@ tests: tags: bindesc filter: CONFIG_ARCH_SUPPORTS_ROM_START or CONFIG_ARCH_POSIX integration_platforms: - - native_posix + - native_sim + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "Zephyr version: " + - "App version: 1.0.0" + - "Build time: " + - "Compiler: " + - "my_string: Hello world!" + - "my_int: 5" + - "my_bytes: 01 02 03 04" From 0b3a7bc7d4b7c1e242956b67449fca933444a4e4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 11:26:22 +0100 Subject: [PATCH 3932/4498] tests/ztest/fail: Fix build for native_sim The final executable output from the native_sim (or native_posix) build is zephyr.exe (in native_posix zephyr.elf happened to be just a copy of the exe, but in native_sim it is an intermediate build step) So we need to use the exe instead. Note: As the exe is generated with a custom target, we need to install it using install(FILES), which also requires the destination and permissions to be listed manually. The permissions set are just the cmake default permissions for install(PROGRAMS). Signed-off-by: Alberto Escolar Piedras --- tests/ztest/fail/CMakeLists.txt | 4 ++-- tests/ztest/fail/core/CMakeLists.txt | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/ztest/fail/CMakeLists.txt b/tests/ztest/fail/CMakeLists.txt index f7a07037774..c4a88639433 100644 --- a/tests/ztest/fail/CMakeLists.txt +++ b/tests/ztest/fail/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.20.0) include(ExternalProject) -# Add the sources and set up the build for either unit testing or native_posix +# Add the sources and set up the build for either unit testing or native_sim list(APPEND SOURCES src/main.cpp) if(BOARD STREQUAL unit_testing) find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE}) @@ -17,7 +17,7 @@ else() set(target app) # Set the target binary for the 'core' external project. The path to this must match the one set # below in ExternalProject_Add's CMAKE_INSTALL_PREFIX - add_compile_definitions(FAIL_TARGET_BINARY="${CMAKE_BINARY_DIR}/core/bin/zephyr.elf") + add_compile_definitions(FAIL_TARGET_BINARY="${CMAKE_BINARY_DIR}/core/bin/zephyr.exe") endif() # Create the project and set the sources for the target diff --git a/tests/ztest/fail/core/CMakeLists.txt b/tests/ztest/fail/core/CMakeLists.txt index cf56362b9ee..7ba86d28082 100644 --- a/tests/ztest/fail/core/CMakeLists.txt +++ b/tests/ztest/fail/core/CMakeLists.txt @@ -35,5 +35,9 @@ else() target_sources(app PRIVATE ${SOURCES}) target_include_directories(app PRIVATE include) - install(TARGETS ${logical_target_for_zephyr_elf}) + install(FILES ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_EXE_NAME} + DESTINATION bin/ + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ + ) endif() From 641784cd59c07ba2c9deb294e8f3e5f2810b7dc7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 11:38:39 +0100 Subject: [PATCH 3933/4498] tests/ztest/fail: Replace native_posix with native_sim In the docs replace references to native_posix with native_sim Switch the default test platform to native_sim from native_posix Signed-off-by: Alberto Escolar Piedras --- doc/develop/test/ztest.rst | 2 ++ tests/ztest/fail/README.rst | 5 +++-- tests/ztest/fail/testcase.yaml | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/develop/test/ztest.rst b/doc/develop/test/ztest.rst index c7d3d23911e..f9255ecad2a 100644 --- a/doc/develop/test/ztest.rst +++ b/doc/develop/test/ztest.rst @@ -340,6 +340,8 @@ it needs to report either a pass or fail. For example: ZTEST_SUITE(common, NULL, NULL, NULL, NULL, NULL); +.. _ztest_unit_testing: + Quick start - Unit testing ************************** diff --git a/tests/ztest/fail/README.rst b/tests/ztest/fail/README.rst index 3ed70d5229a..ab5788ba821 100644 --- a/tests/ztest/fail/README.rst +++ b/tests/ztest/fail/README.rst @@ -7,8 +7,9 @@ Overview ******** In order to test the actual framework's failure cases, this test suite has to do something unique. -There's a subdirectory to this test called 'core'. This project builds a sample ``native_posix`` or -``unit_testing`` binary which is expected to fail by calling one of the following: +There's a subdirectory to this test called 'core'. This project builds a sample as a +:ref:`native_sim ` or `:ref:unit_testing ` +binary which is expected to fail by calling one of the following: - ``ztest_test_fail()`` during either the ``after`` or ``teardown`` phase of the test suite - ``ztest_test_skip()`` during either the ``after`` or ``teardown`` phase of the test suite - ``ztest_test_pass()`` during either the ``after`` or ``teardown`` phase of the test suite diff --git a/tests/ztest/fail/testcase.yaml b/tests/ztest/fail/testcase.yaml index 5295847a0cb..2a0820fa85e 100644 --- a/tests/ztest/fail/testcase.yaml +++ b/tests/ztest/fail/testcase.yaml @@ -5,7 +5,12 @@ common: tags: - test_framework # test has dependencies on host libc - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + - native_sim_64 + integration_platforms: + - native_sim tests: testing.fail.unit.assert_after: extra_configs: From 0d1045e0936980e9ef4b0c85e66c041e15580e0c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 11:39:38 +0100 Subject: [PATCH 3934/4498] tests/ztest: Swap native_posix with native_sim Switch the default test platform to native_sim from native_posix Signed-off-by: Alberto Escolar Piedras --- tests/ztest/base/testcase.yaml | 13 +++++++++---- tests/ztest/zexpect/testcase.yaml | 6 ++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/ztest/base/testcase.yaml b/tests/ztest/base/testcase.yaml index 4ac55a1dc55..ee566d5dd8a 100644 --- a/tests/ztest/base/testcase.yaml +++ b/tests/ztest/base/testcase.yaml @@ -6,11 +6,16 @@ tests: type: unit testing.ztest.base.cpp: extra_args: CONF_FILE=prj_cpp.conf - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + - native_sim_64 + integration_platforms: + - native_sim testing.ztest.base.verbose_0: extra_args: CONF_FILE=prj_verbose_0.conf integration_platforms: - - native_posix + - native_sim testing.ztest.base.verbose_0_userspace: filter: CONFIG_USERSPACE extra_args: CONF_FILE=prj_verbose_0.conf @@ -23,8 +28,8 @@ tests: testing.ztest.base.verbose_1: extra_args: CONF_FILE=prj_verbose_1.conf integration_platforms: - - native_posix + - native_sim testing.ztest.base.verbose_2: extra_args: CONF_FILE=prj_verbose_2.conf integration_platforms: - - native_posix + - native_sim diff --git a/tests/ztest/zexpect/testcase.yaml b/tests/ztest/zexpect/testcase.yaml index f2679fb9a6f..6928a5f4198 100644 --- a/tests/ztest/zexpect/testcase.yaml +++ b/tests/ztest/zexpect/testcase.yaml @@ -3,17 +3,15 @@ common: integration_platforms: - - native_posix + - native_sim tags: - test_framework tests: testing.ztest.expect: integration_platforms: - - native_posix + - native_sim testing.ztest.expect_cpp: extra_configs: - CONFIG_CPLUSPLUS=y - integration_platforms: - - native_posix testing.ztest.expect.unit: type: unit From 39bf042086366e67886b4e282a8ab83c2c598aaf Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 12:34:15 +0100 Subject: [PATCH 3935/4498] samples/subsys/pm/latency: Switch to native_sim Switch from native_posix to native_sim as default test platform. Signed-off-by: Alberto Escolar Piedras --- .../pm/latency/boards/native_posix.overlay | 32 +------------------ .../pm/latency/boards/native_sim.overlay | 31 ++++++++++++++++++ samples/subsys/pm/latency/sample.yaml | 6 ++-- 3 files changed, 36 insertions(+), 33 deletions(-) create mode 100644 samples/subsys/pm/latency/boards/native_sim.overlay diff --git a/samples/subsys/pm/latency/boards/native_posix.overlay b/samples/subsys/pm/latency/boards/native_posix.overlay index c718cbdd1ff..6a3daca3241 100644 --- a/samples/subsys/pm/latency/boards/native_posix.overlay +++ b/samples/subsys/pm/latency/boards/native_posix.overlay @@ -1,31 +1 @@ -/* - * Copyright (c) 2022 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - power-states { - runtime_idle: runtime-idle { - compatible = "zephyr,power-state"; - power-state-name = "runtime-idle"; - min-residency-us = <1000000>; - exit-latency-us = <10000>; - }; - suspend_to_idle: suspend-to-idle { - compatible = "zephyr,power-state"; - power-state-name = "suspend-to-idle"; - min-residency-us = <1100000>; - exit-latency-us = <20000>; - }; - standby: standby { - compatible = "zephyr,power-state"; - power-state-name = "standby"; - min-residency-us = <1200000>; - exit-latency-us = <30000>; - }; - }; -}; - -&cpu0 { - cpu-power-states = <&runtime_idle &suspend_to_idle &standby>; -}; +#include "native_sim.overlay" diff --git a/samples/subsys/pm/latency/boards/native_sim.overlay b/samples/subsys/pm/latency/boards/native_sim.overlay new file mode 100644 index 00000000000..c718cbdd1ff --- /dev/null +++ b/samples/subsys/pm/latency/boards/native_sim.overlay @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + power-states { + runtime_idle: runtime-idle { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <1000000>; + exit-latency-us = <10000>; + }; + suspend_to_idle: suspend-to-idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1100000>; + exit-latency-us = <20000>; + }; + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <1200000>; + exit-latency-us = <30000>; + }; + }; +}; + +&cpu0 { + cpu-power-states = <&runtime_idle &suspend_to_idle &standby>; +}; diff --git a/samples/subsys/pm/latency/sample.yaml b/samples/subsys/pm/latency/sample.yaml index 4989a63dbe7..2d6f68879c3 100644 --- a/samples/subsys/pm/latency/sample.yaml +++ b/samples/subsys/pm/latency/sample.yaml @@ -2,9 +2,11 @@ sample: name: Demonstrate usage of the PM policy latency APIs tests: sample.pm.latency: - platform_allow: native_posix - integration_platforms: + platform_allow: - native_posix + - native_sim + integration_platforms: + - native_sim tags: pm harness: console harness_config: From cb270a7ecfc410aebde38f75dd1544ea01d56f1e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 12:36:02 +0100 Subject: [PATCH 3936/4498] samples canbus: Add native_sim to platform_allow Add native_sim in these samples platform_allow filtering. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/canbus/isotp/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/subsys/canbus/isotp/sample.yaml b/samples/subsys/canbus/isotp/sample.yaml index 9bb24251656..0036552b67b 100644 --- a/samples/subsys/canbus/isotp/sample.yaml +++ b/samples/subsys/canbus/isotp/sample.yaml @@ -25,6 +25,8 @@ tests: platform_allow: - native_posix - native_posix_64 + - native_sim + - native_sim_64 harness: console harness_config: type: one_line From 33a36df60b0e65d7f8595ef26eca072c1b0887d9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 12:46:12 +0100 Subject: [PATCH 3937/4498] samples/subsys/settings: Switch from native_posix to native_sim Switch from native_posix to native_sim as default test platform Add conf and DT overlays for native_sim. Signed-off-by: Alberto Escolar Piedras --- .../settings/boards/native_posix.overlay | 23 +------------------ .../settings/boards/native_posix_64.overlay | 23 +------------------ .../subsys/settings/boards/native_sim.conf | 5 ++++ .../subsys/settings/boards/native_sim.overlay | 22 ++++++++++++++++++ .../subsys/settings/boards/native_sim_64.conf | 5 ++++ .../settings/boards/native_sim_64.overlay | 1 + samples/subsys/settings/sample.yaml | 4 +++- 7 files changed, 38 insertions(+), 45 deletions(-) create mode 100644 samples/subsys/settings/boards/native_sim.conf create mode 100644 samples/subsys/settings/boards/native_sim.overlay create mode 100644 samples/subsys/settings/boards/native_sim_64.conf create mode 100644 samples/subsys/settings/boards/native_sim_64.overlay diff --git a/samples/subsys/settings/boards/native_posix.overlay b/samples/subsys/settings/boards/native_posix.overlay index 0e4839ad026..6a3daca3241 100644 --- a/samples/subsys/settings/boards/native_posix.overlay +++ b/samples/subsys/settings/boards/native_posix.overlay @@ -1,22 +1 @@ -/* - * Copyright (c) 2019 Jan Van Winkel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; - -&flash0 { - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - storage_partition: partition@70000 { - label = "storage"; - reg = <0x00070000 0x8000>; - }; - }; -}; +#include "native_sim.overlay" diff --git a/samples/subsys/settings/boards/native_posix_64.overlay b/samples/subsys/settings/boards/native_posix_64.overlay index 0e4839ad026..6a3daca3241 100644 --- a/samples/subsys/settings/boards/native_posix_64.overlay +++ b/samples/subsys/settings/boards/native_posix_64.overlay @@ -1,22 +1 @@ -/* - * Copyright (c) 2019 Jan Van Winkel - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; - -&flash0 { - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - storage_partition: partition@70000 { - label = "storage"; - reg = <0x00070000 0x8000>; - }; - }; -}; +#include "native_sim.overlay" diff --git a/samples/subsys/settings/boards/native_sim.conf b/samples/subsys/settings/boards/native_sim.conf new file mode 100644 index 00000000000..21877f886f3 --- /dev/null +++ b/samples/subsys/settings/boards/native_sim.conf @@ -0,0 +1,5 @@ +# Enable the LittleFS file system. +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_SETTINGS_FILE=y +CONFIG_SETTINGS_FILE_PATH="/ff/settings/run" diff --git a/samples/subsys/settings/boards/native_sim.overlay b/samples/subsys/settings/boards/native_sim.overlay new file mode 100644 index 00000000000..0e4839ad026 --- /dev/null +++ b/samples/subsys/settings/boards/native_sim.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 Jan Van Winkel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@70000 { + label = "storage"; + reg = <0x00070000 0x8000>; + }; + }; +}; diff --git a/samples/subsys/settings/boards/native_sim_64.conf b/samples/subsys/settings/boards/native_sim_64.conf new file mode 100644 index 00000000000..21877f886f3 --- /dev/null +++ b/samples/subsys/settings/boards/native_sim_64.conf @@ -0,0 +1,5 @@ +# Enable the LittleFS file system. +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_SETTINGS_FILE=y +CONFIG_SETTINGS_FILE_PATH="/ff/settings/run" diff --git a/samples/subsys/settings/boards/native_sim_64.overlay b/samples/subsys/settings/boards/native_sim_64.overlay new file mode 100644 index 00000000000..6a3daca3241 --- /dev/null +++ b/samples/subsys/settings/boards/native_sim_64.overlay @@ -0,0 +1 @@ +#include "native_sim.overlay" diff --git a/samples/subsys/settings/sample.yaml b/samples/subsys/settings/sample.yaml index 47276f1e697..2cd51d1405d 100644 --- a/samples/subsys/settings/sample.yaml +++ b/samples/subsys/settings/sample.yaml @@ -9,9 +9,11 @@ tests: - qemu_x86 - native_posix - native_posix_64 + - native_sim + - native_sim_64 - mr_canhubk3 integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: multi_line From ab7682ea06b8d9d6af34bdcbc5892eedd1e242a0 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:55:20 +0100 Subject: [PATCH 3938/4498] samples/kernel/metairq_dispatch: Correct comment Clarify comment about why this samples is skipped in posix arch based targets. Signed-off-by: Alberto Escolar Piedras --- samples/kernel/metairq_dispatch/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/kernel/metairq_dispatch/sample.yaml b/samples/kernel/metairq_dispatch/sample.yaml index 201166f7e78..82090751b33 100644 --- a/samples/kernel/metairq_dispatch/sample.yaml +++ b/samples/kernel/metairq_dispatch/sample.yaml @@ -14,7 +14,7 @@ common: regex: - "MetaIRQ Test Complete" -# Note that native_posix architectures are filtered, they require +# Note that boards based on the POSIX architecture are filtered as they require # instrumentation (e.g. a k_busy_wait()) inside the worker threads # "busy" loops in order for the interrupts to fire on time, and the # sample is designed to demonstrate completely arbitrary CPU work. From 868489b98e495820fb97821434c6cc04059c7846 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:57:35 +0100 Subject: [PATCH 3939/4498] samples: Enable any which runs in native_posix also in native_sim Enable the remaining samples which run now in native_posix also in native_sim. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/fs/format/sample.yaml | 2 ++ samples/subsys/fs/littlefs/sample.yaml | 1 + samples/subsys/testsuite/integration/testcase.yaml | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/samples/subsys/fs/format/sample.yaml b/samples/subsys/fs/format/sample.yaml index ca93e00f075..aafe86f7989 100644 --- a/samples/subsys/fs/format/sample.yaml +++ b/samples/subsys/fs/format/sample.yaml @@ -4,12 +4,14 @@ tests: sample.filesystem.format.littlefs: platform_allow: - native_posix + - native_sim - nrf52dk_nrf52832 build_only: true tags: filesystem sample.filesystem.format.fat_fs: platform_allow: - native_posix + - native_sim - mimxrt1064_evk build_only: true extra_args: diff --git a/samples/subsys/fs/littlefs/sample.yaml b/samples/subsys/fs/littlefs/sample.yaml index 6ffbc14d35f..cee42827173 100644 --- a/samples/subsys/fs/littlefs/sample.yaml +++ b/samples/subsys/fs/littlefs/sample.yaml @@ -16,6 +16,7 @@ tests: - mimxrt1064_evk - qemu_x86 - native_posix + - native_sim - mimxrt1160_evk_cm7 - lpcxpresso55s69_cpu0 - mr_canhubk3 diff --git a/samples/subsys/testsuite/integration/testcase.yaml b/samples/subsys/testsuite/integration/testcase.yaml index 8a4c9743b75..1cc0ad1c8ee 100644 --- a/samples/subsys/testsuite/integration/testcase.yaml +++ b/samples/subsys/testsuite/integration/testcase.yaml @@ -2,7 +2,9 @@ tests: # section.subsection sample.testing.ztest: build_only: true - platform_allow: native_posix - integration_platforms: + platform_allow: - native_posix + - native_sim + integration_platforms: + - native_sim tags: test_framework From 196341c18b95ae24f3fbc11d630ad26346284245 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 16 Nov 2023 14:58:47 +0100 Subject: [PATCH 3940/4498] samples: Switch integration_platforms from native_posix to native_sim For all remaining samples which now set their integration platform as native_posix(_64) switch them to native_sim(_64) Signed-off-by: Alberto Escolar Piedras --- samples/application_development/external_lib/sample.yaml | 2 +- samples/drivers/can/babbling/sample.yaml | 2 +- samples/drivers/can/counter/sample.yaml | 2 +- samples/drivers/crypto/sample.yaml | 4 ++-- samples/hello_world/sample.yaml | 2 +- samples/modules/nanopb/sample.yaml | 4 ++-- samples/philosophers/sample.yaml | 2 +- samples/subsys/input/input_dump/sample.yaml | 2 +- samples/subsys/logging/logger/sample.yaml | 2 +- .../subsys/portability/cmsis_rtos_v1/philosophers/sample.yaml | 2 +- .../cmsis_rtos_v1/timer_synchronization/sample.yaml | 2 +- .../subsys/portability/cmsis_rtos_v2/philosophers/sample.yaml | 2 +- .../cmsis_rtos_v2/timer_synchronization/sample.yaml | 2 +- samples/subsys/rtio/sensor_batch_processing/sample.yaml | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/samples/application_development/external_lib/sample.yaml b/samples/application_development/external_lib/sample.yaml index dc06cb4c903..69cbd486e23 100644 --- a/samples/application_development/external_lib/sample.yaml +++ b/samples/application_development/external_lib/sample.yaml @@ -3,7 +3,7 @@ sample: tests: sample.app_dev.external_lib: integration_platforms: - - native_posix + - native_sim tags: external harness: console harness_config: diff --git a/samples/drivers/can/babbling/sample.yaml b/samples/drivers/can/babbling/sample.yaml index 8a52e4f59cb..2e7a8320dae 100644 --- a/samples/drivers/can/babbling/sample.yaml +++ b/samples/drivers/can/babbling/sample.yaml @@ -6,7 +6,7 @@ tests: depends_on: can filter: dt_chosen_enabled("zephyr,canbus") integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: one_line diff --git a/samples/drivers/can/counter/sample.yaml b/samples/drivers/can/counter/sample.yaml index 20f609d0c36..579fc82a069 100644 --- a/samples/drivers/can/counter/sample.yaml +++ b/samples/drivers/can/counter/sample.yaml @@ -5,7 +5,7 @@ tests: tags: can depends_on: can integration_platforms: - - native_posix + - native_sim filter: dt_chosen_enabled("zephyr,canbus") and not dt_compat_enabled("kvaser,pcican") harness: console harness_config: diff --git a/samples/drivers/crypto/sample.yaml b/samples/drivers/crypto/sample.yaml index d63e7a4a68a..c969bafa67c 100644 --- a/samples/drivers/crypto/sample.yaml +++ b/samples/drivers/crypto/sample.yaml @@ -12,7 +12,7 @@ tests: harness: console extra_args: EXTRA_CONF_FILE=prj_tinycrypt_shim.conf integration_platforms: - - native_posix + - native_sim harness_config: type: multi_line regex: @@ -26,7 +26,7 @@ tests: harness: console extra_args: EXTRA_CONF_FILE=prj_mtls_shim.conf integration_platforms: - - native_posix + - native_sim harness_config: type: multi_line regex: diff --git a/samples/hello_world/sample.yaml b/samples/hello_world/sample.yaml index 60cbe49360f..1bcb7db62f2 100644 --- a/samples/hello_world/sample.yaml +++ b/samples/hello_world/sample.yaml @@ -5,7 +5,7 @@ sample: common: tags: introduction integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: one_line diff --git a/samples/modules/nanopb/sample.yaml b/samples/modules/nanopb/sample.yaml index 2ea497b0f10..eb990848d18 100644 --- a/samples/modules/nanopb/sample.yaml +++ b/samples/modules/nanopb/sample.yaml @@ -15,5 +15,5 @@ tests: - samples - nanopb integration_platforms: - - native_posix - - native_posix_64 + - native_sim + - native_sim_64 diff --git a/samples/philosophers/sample.yaml b/samples/philosophers/sample.yaml index d072f2c6887..2db2c1563f4 100644 --- a/samples/philosophers/sample.yaml +++ b/samples/philosophers/sample.yaml @@ -8,7 +8,7 @@ common: harness: console min_ram: 16 integration_platforms: - - native_posix + - native_sim harness_config: type: multi_line ordered: false diff --git a/samples/subsys/input/input_dump/sample.yaml b/samples/subsys/input/input_dump/sample.yaml index 04a867b8a07..1fb4d9d30a9 100644 --- a/samples/subsys/input/input_dump/sample.yaml +++ b/samples/subsys/input/input_dump/sample.yaml @@ -5,4 +5,4 @@ tests: tags: input build_only: true integration_platforms: - - native_posix + - native_sim diff --git a/samples/subsys/logging/logger/sample.yaml b/samples/subsys/logging/logger/sample.yaml index 131c9ea9fb5..2364dabd6b4 100644 --- a/samples/subsys/logging/logger/sample.yaml +++ b/samples/subsys/logging/logger/sample.yaml @@ -4,7 +4,7 @@ sample: tests: sample.logger.basic: integration_platforms: - - native_posix + - native_sim tags: logging harness: console harness_config: diff --git a/samples/subsys/portability/cmsis_rtos_v1/philosophers/sample.yaml b/samples/subsys/portability/cmsis_rtos_v1/philosophers/sample.yaml index 4f4fe6cf366..64fd5053d85 100644 --- a/samples/subsys/portability/cmsis_rtos_v1/philosophers/sample.yaml +++ b/samples/subsys/portability/cmsis_rtos_v1/philosophers/sample.yaml @@ -2,7 +2,7 @@ sample: name: CMSIS_RTOS_V1 Dining Philosophers common: integration_platforms: - - native_posix + - native_sim extra_args: DEBUG_PRINTF=1 tags: cmsis_rtos min_ram: 32 diff --git a/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/sample.yaml b/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/sample.yaml index 2d8df98d770..e87d8449938 100644 --- a/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/sample.yaml +++ b/samples/subsys/portability/cmsis_rtos_v1/timer_synchronization/sample.yaml @@ -3,7 +3,7 @@ sample: tests: sample.portability.cmsis_rtos_v1.timer_synchronization: integration_platforms: - - native_posix + - native_sim tags: cmsis_rtos min_ram: 32 min_flash: 34 diff --git a/samples/subsys/portability/cmsis_rtos_v2/philosophers/sample.yaml b/samples/subsys/portability/cmsis_rtos_v2/philosophers/sample.yaml index 5f15a4d1ce0..af5a69f0af7 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/philosophers/sample.yaml +++ b/samples/subsys/portability/cmsis_rtos_v2/philosophers/sample.yaml @@ -2,7 +2,7 @@ sample: name: CMSIS_RTOS_V2 Dining Philosophers common: integration_platforms: - - native_posix + - native_sim extra_args: DEBUG_PRINTF=1 tags: cmsis_rtos min_ram: 32 diff --git a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml index 7b7103cfb9e..f4a8ad690cf 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml +++ b/samples/subsys/portability/cmsis_rtos_v2/timer_synchronization/sample.yaml @@ -3,7 +3,7 @@ sample: tests: sample.portability.cmsis_rtos_v2.timer_synchronization: integration_platforms: - - native_posix + - native_sim platform_exclude: - qemu_arc_hs5x # See issue #62405 tags: cmsis_rtos diff --git a/samples/subsys/rtio/sensor_batch_processing/sample.yaml b/samples/subsys/rtio/sensor_batch_processing/sample.yaml index 956af3a567a..99732a25574 100644 --- a/samples/subsys/rtio/sensor_batch_processing/sample.yaml +++ b/samples/subsys/rtio/sensor_batch_processing/sample.yaml @@ -4,7 +4,7 @@ tests: sample.rtio.sensor_batch_processing: tags: rtio integration_platforms: - - native_posix + - native_sim harness: console harness_config: type: multi_line From 47e09806c804fdb9bb4abfa1523593263b852ab4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Sep 2023 23:46:30 -0700 Subject: [PATCH 3941/4498] lib/os: With CBPRINTF_NANO, picolibc long-long printf isn't required CBPRINTF_FULL_INTEGRAL doesn't happen to explicitly conflict with CBPRINTF_NANO, but when CBPRINTF_NANO is enabled, there's no long long I/O support provided. Allow picolibc long-long I/O support to also be elided when CBPRINTF_NANO is enabled to save similar amounts of space. Signed-off-by: Keith Packard --- lib/os/Kconfig.cbprintf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/os/Kconfig.cbprintf b/lib/os/Kconfig.cbprintf index 93ffa90ca5d..777cd7d9cf6 100644 --- a/lib/os/Kconfig.cbprintf +++ b/lib/os/Kconfig.cbprintf @@ -31,7 +31,7 @@ choice CBPRINTF_INTEGRAL_CONV # 01: 0% / 0 B (01 / 00) config CBPRINTF_FULL_INTEGRAL bool "Convert the full range of integer values" - select PICOLIBC_IO_LONG_LONG if PICOLIBC + select PICOLIBC_IO_LONG_LONG if PICOLIBC && !CBPRINTF_NANO help Build cbprintf with buffers sized to support converting the full range of all integral and pointer values. From 35e83d20e4f469a5b3899140205ee812c8f2626e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2023 18:13:38 -0700 Subject: [PATCH 3942/4498] west: Update picolibc to version 1.8.5 Picolibc version 1.8.5 offers additional memory savings and new long-long and minimal printf variants which can be selected from either the SDK or module version of the library. This needed a patch to the Zephyr cmake support bits to enable one of the new picolibc 1.8.5 features. Signed-off-by: Keith Packard --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3e7d49affec..20c01f42637 100644 --- a/west.yml +++ b/west.yml @@ -310,7 +310,7 @@ manifest: - debug - name: picolibc path: modules/lib/picolibc - revision: d07c38ff051386f8e09a143ea0a6c1d6d66dd1d8 + revision: 1a5c603b9f8e228f9459bdafedad15ea28efc700 - name: segger revision: 9d0191285956cef43daf411edc2f1a7788346def path: modules/debug/segger From 5347a834af36e2d01f805a7f4e86932ae5738516 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Sep 2023 23:49:38 -0700 Subject: [PATCH 3943/4498] libc/picolibc: Support picolibc's assert-verbose option This option in picolibc switches the assert macro between a chatty version and one which provides no information at all. This latter mode avoids placing the associated strings in memory. The Zephyr option is PICOLIBC_ASSERT_VERBOSE and it is disable by default. Signed-off-by: Keith Packard --- lib/libc/picolibc/Kconfig | 9 +++++++++ lib/libc/picolibc/libc-hooks.c | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig index 21c6fc38501..6adc9fd0b71 100644 --- a/lib/libc/picolibc/Kconfig +++ b/lib/libc/picolibc/Kconfig @@ -88,6 +88,15 @@ config PICOLIBC_FAST_STRCMP This provides a faster strcmp version even when libc is built in space-optimized mode +config PICOLIBC_ASSERT_VERBOSE + bool "assert provides verbose information" + help + The usual picolibc assert helper, __assert_func, takes file, line, + function and expression information to make the presented message + more helpful. These all require storage in the image. Unselecting + this option eliminates all of that information, making the results + less helpful but also making them consume less memory. + config PICOLIBC_IO_C99_FORMATS bool "support C99 format additions in printf/scanf" default y diff --git a/lib/libc/picolibc/libc-hooks.c b/lib/libc/picolibc/libc-hooks.c index d00b53d1e8a..e7539bc5dfe 100644 --- a/lib/libc/picolibc/libc-hooks.c +++ b/lib/libc/picolibc/libc-hooks.c @@ -206,6 +206,27 @@ void __retarget_lock_release(_LOCK_T lock) #endif /* CONFIG_MULTITHREADING */ +#ifdef CONFIG_PICOLIBC_ASSERT_VERBOSE + +FUNC_NORETURN void __assert_func(const char *file, int line, + const char *function, const char *expression) +{ + __ASSERT(0, "assertion \"%s\" failed: file \"%s\", line %d%s%s\n", + expression, file, line, + function ? ", function: " : "", function ? function : ""); + CODE_UNREACHABLE; +} + +#else + +FUNC_NORETURN void __assert_no_args(void) +{ + __ASSERT_NO_MSG(0); + CODE_UNREACHABLE; +} + +#endif + /* This function gets called if static buffer overflow detection is enabled on * stdlib side (Picolibc here), in case such an overflow is detected. Picolibc * provides an implementation not suitable for us, so we override it here. From 7a5fcb8c60e2e6ba26704fabc28fe2d4e0106513 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Sep 2023 23:51:33 -0700 Subject: [PATCH 3944/4498] libc/picolibc: Support 'long long' and 'minimal' printf variants Picolibc's 'minimal' printf mode reduces functionality and size even more than the 'integer' mode. Use this where memory is at a premium and where the application knows that it does not require exact printf semantics. 1.8.5 adds two more printf variants, 'long long' and 'minimal'. The 'long long' variant is the same as the 'integer' variant but with long long support enabled. The 'minimal' variant reduces functionality and size even more than the 'integer' mode. Applications can use this where memory is at a premium and where the application does not require exact printf semantics. With these two added variants, the SDK has enough options so that all of the cbprintf modes can be supported with the pre-compiled bits: 1. CBPRINTF_NANO - picolibc's 'minimal' variant 2. CBPRINTF_REDUCED_INTEGRAL - picolibc's 'integer' variant 3. CBPRINTF_FULL_INTEGRAL - picolibc's 'long long' variant 4. CBPRINTF_FB_SUPPORT - picolibc's 'double' variant This patch makes the cbprintf Kconfig values drive the default picolibc variant, disables picolibc variants not capable of supporting the required cbprintf level, but allows applications to select more functionality in picolibc than cbprintf requires. Note that this depends on the SDK including picolibc 1.8.5. Without that, selecting the 'minimal' or 'long long' variant in Zephyr will end up with the default variant from picolibc, which is the full version with floating point support. When using the module things will work as specified. Signed-off-by: Keith Packard --- lib/libc/Kconfig | 1 - lib/libc/picolibc/CMakeLists.txt | 6 +++ lib/libc/picolibc/Kconfig | 66 ++++++++++++++++++++++++++------ lib/os/Kconfig.cbprintf | 3 +- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index c9678adf2c2..8b71808ff54 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -12,7 +12,6 @@ config REQUIRES_FULL_LIBC config REQUIRES_FLOAT_PRINTF bool "Requires floating point support in printf" - select PICOLIBC_IO_FLOAT if PICOLIBC select CBPRINTF_FP_SUPPORT if MINIMAL_LIBC select NEWLIB_LIBC_FLOAT_PRINTF if NEWLIB_LIBC help diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt index 3bbe8128a1f..232e4ba8fc1 100644 --- a/lib/libc/picolibc/CMakeLists.txt +++ b/lib/libc/picolibc/CMakeLists.txt @@ -17,6 +17,12 @@ if(NOT CONFIG_PICOLIBC_USE_MODULE) if(CONFIG_PICOLIBC_IO_FLOAT) zephyr_compile_definitions(PICOLIBC_DOUBLE_PRINTF_SCANF) zephyr_link_libraries(-DPICOLIBC_DOUBLE_PRINTF_SCANF) + elseif(CONFIG_PICOLIBC_IO_MINIMAL) + zephyr_compile_definitions(PICOLIBC_MINIMAL_PRINTF_SCANF) + zephyr_link_libraries(-DPICOLIBC_MINIMAL_PRINTF_SCANF) + elseif(CONFIG_PICOLIBC_IO_LONG_LONG) + zephyr_compile_definitions(PICOLIBC_LONG_LONG_PRINTF_SCANF) + zephyr_link_libraries(-DPICOLIBC_LONG_LONG_PRINTF_SCANF) else() zephyr_compile_definitions(PICOLIBC_INTEGER_PRINTF_SCANF) zephyr_link_libraries(-DPICOLIBC_INTEGER_PRINTF_SCANF) diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig index 6adc9fd0b71..fa6ae7e6e9b 100644 --- a/lib/libc/picolibc/Kconfig +++ b/lib/libc/picolibc/Kconfig @@ -31,16 +31,42 @@ config PICOLIBC_HEAP_SIZE If set to -2, then the value of COMMON_LIBC_MALLOC_ARENA_SIZE will be used. -config PICOLIBC_IO_LONG_LONG - bool "support for long long in integer-only printf/scanf" +choice PICOLIBC_IO_LEVEL + prompt "Picolibc printf/scanf level" + default PICOLIBC_IO_MINIMAL if CBPRINTF_NANO + default PICOLIBC_IO_LONG_LONG if CBPRINTF_FULL_INTEGRAL + default PICOLIBC_IO_INTEGER help - Includes support for long long in integer-only printf/scanf. long long - types are always supported in the floating-point versions. + Selects the level of printf and scanf support config PICOLIBC_IO_FLOAT - bool "support for floating point values in printf/scanf" + bool "full support for integer/floating point values in printf/scanf" + help + Include full floating point and integer support in printf/scanf + functions. + +config PICOLIBC_IO_LONG_LONG + bool "full support for integer values, including long long, in printf/scanf" + depends on !REQUIRES_FLOAT_PRINTF && (!CBPRINTF_FP_SUPPORT || CBPRINTF_NANO) + help + Includes full integer with long long, but no floating + point in printf/scanf. + +config PICOLIBC_IO_INTEGER + bool "full support for integer values, other than long long, in printf/scanf" + depends on !REQUIRES_FLOAT_PRINTF && ((!CBPRINTF_FP_SUPPORT && !CBPRINTF_FULL_INTEGRAL) || CBPRINTF_NANO) + help + Include full integer other than long long, but no floating point + in printf/scanf. + +config PICOLIBC_IO_MINIMAL + bool "limited support for integer values in printf/scanf" + depends on !REQUIRES_FLOAT_PRINTF && CBPRINTF_NANO help - Include floating point support in printf/scanf functions. + Include limited integer and no floating point support in + printf/scanf. + +endchoice if PICOLIBC_USE_MODULE @@ -101,17 +127,18 @@ config PICOLIBC_IO_C99_FORMATS bool "support C99 format additions in printf/scanf" default y help - Includes support for hex floats (in floating-point version) and j, z, - t size modifiers. + Includes C99 printf and scanf support for j, z, t size + modifiers. C99 support is always included in the floating-point + variant config PICOLIBC_IO_POS_ARGS bool "Support POSIX positional args (e.g. %$1d) in printf/scanf" default y - depends on !PICOLIBC_IO_FLOAT + depends on !PICOLIBC_IO_MINIMAL help - Includes support for positional args (e.g. $1) in integer-only printf - and scanf. Positional args are always supported in the floating-point - versions. + Includes support for positional args (e.g. $1) in integer-only + printf and scanf. Positional args are always supported in the + floating-point variant. config PICOLIBC_IO_FLOAT_EXACT bool "support for exact float/string conversion" @@ -121,6 +148,21 @@ config PICOLIBC_IO_FLOAT_EXACT This ensures that printf values with enough digits can be fed to scanf and generate exactly the same binary value. +config PICOLIBC_IO_SMALL_ULTOA + bool "avoid soft division in printf" + default y + help + Replaces division and modulus by 10 with shifts and adds when + doing binary to decimal conversion in printf for 64-bit + values on 32-bit targets. + +config PICOLIBC_IO_MINIMAL_LONG_LONG + bool "Include long long support in minimal printf" + depends on PICOLIBC_IO_MINIMAL + default y if CBPRINTF_FULL_INTEGRAL + help + Include long long support in the minimal picolibc printf code + config PICOLIBC_LOCALE_INFO bool "support locales in libc functions" help diff --git a/lib/os/Kconfig.cbprintf b/lib/os/Kconfig.cbprintf index 777cd7d9cf6..54ba8ccfa50 100644 --- a/lib/os/Kconfig.cbprintf +++ b/lib/os/Kconfig.cbprintf @@ -31,7 +31,7 @@ choice CBPRINTF_INTEGRAL_CONV # 01: 0% / 0 B (01 / 00) config CBPRINTF_FULL_INTEGRAL bool "Convert the full range of integer values" - select PICOLIBC_IO_LONG_LONG if PICOLIBC && !CBPRINTF_NANO + select PICOLIBC_IO_MINIMAL_LONG_LONG if PICOLIBC_IO_MINIMAL && PICOLIBC_USE_MODULE help Build cbprintf with buffers sized to support converting the full range of all integral and pointer values. @@ -67,7 +67,6 @@ config CBPRINTF_FP_SUPPORT bool "Floating point formatting in cbprintf" default y if FPU depends on CBPRINTF_COMPLETE - select PICOLIBC_IO_FLOAT if PICOLIBC help Build the cbprintf utility function with support for floating point format specifiers. Selecting this increases stack size From d04c834c0fc4d97cb83ca73af9b123700a0c3b63 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Sep 2023 14:34:14 -0700 Subject: [PATCH 3945/4498] tests/kernel: Fix test printk output for new printf variants In minimal mode, format modifiers are not supported, leading to a lack of width and precision support. long long values are presented correctly in either long long or floating mode. Signed-off-by: Keith Packard --- tests/kernel/common/src/printk.c | 71 +++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/tests/kernel/common/src/printk.c b/tests/kernel/common/src/printk.c index 35e91eb960c..85a0ccbb4d3 100644 --- a/tests/kernel/common/src/printk.c +++ b/tests/kernel/common/src/printk.c @@ -17,16 +17,61 @@ int (*_old_char_out)(int); #if defined(CONFIG_PICOLIBC) +#define ZEPHYR_PICOLIBC_VERSION (__PICOLIBC__ * 10000 + \ + __PICOLIBC_MINOR__ * 100 + \ + __PICOLIBC_PATCHLEVEL__) + +#ifdef CONFIG_PICOLIBC_IO_MINIMAL +/* + * If picolibc is >= 1.8.4, then minimal printf is available. Otherwise, + * we're going to get the floating point version when the minimal one is + * selected. + */ +#if ZEPHYR_PICOLIBC_VERSION >= 10804 +#define HAS_PICOLIBC_IO_MINIMAL +#else +#define HAS_PICOLIBC_IO_FLOAT +#endif +#endif + +#ifdef CONFIG_PICOLIBC_IO_LONG_LONG +/* + * If picolibc is >= 1.8.5, then long long printf is available. Otherwise, + * we're going to get the floating point version when the long long one is + * selected. + */ +#if ZEPHYR_PICOLIBC_VERSION >= 10805 +#define HAS_PICOLIBC_IO_LONG_LONG +#else +#define HAS_PICOLIBC_IO_FLOAT +#endif +#endif + +#ifdef CONFIG_PICOLIBC_IO_FLOAT +#define HAS_PICOLIBC_IO_FLOAT +#endif + /* - * Picolibc long long support is present if the picolibc _WANT_IO_LONG_LONG - * symbol is defined or if the Zephyr configuration has enabled floating - * point support. Note that CONFIG_PICOLIBC_IO_LONG_LONG is only useful - * when using the picolibc module as it cannot affect picolibc included - * with the toolchain + * Picolibc long long support is present if Zephyr configuration has + * enabled long long or floating point support. */ char expected_32[] = "22 113 10000 32768 40000 22\n" "p 112 -10000 -32768 -40000 -22\n" +#if defined(HAS_PICOLIBC_IO_MINIMAL) + "0x1 0x1 0x1 0x1 0x1\n" + "0x1 0x1 0x1 0x1\n" + "42 42 42 42\n" + "-42 -42 -42 -42\n" + "42 42 42 42\n" + "42 42 42 42\n" + "25542abcdef 42\n" +#if defined(_WANT_MINIMAL_IO_LONG_LONG) + "68719476735 -1 18446744073709551615 ffffffffffffffff\n" +#else + "-1 -1 4294967295 ffffffff\n" +#endif +#else "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n" "0x1 0x 1 0x 1 0x 1\n" "42 42 0042 00000042\n" @@ -34,15 +79,26 @@ char expected_32[] = "22 113 10000 32768 40000 22\n" "42 42 42 42\n" "42 42 0042 00000042\n" "255 42 abcdef 42\n" -#if defined(_WANT_IO_LONG_LONG) || defined(CONFIG_PICOLIBC_IO_FLOAT) +#if defined(HAS_PICOLIBC_IO_LONG_LONG) || defined(HAS_PICOLIBC_IO_FLOAT) "68719476735 -1 18446744073709551615 ffffffffffffffff\n" #else "-1 -1 4294967295 ffffffff\n" +#endif #endif "0xcafebabe 0xbeef 0x2a\n" ; + char expected_64[] = "22 113 10000 32768 40000 22\n" "p 112 -10000 -32768 -40000 -22\n" +#if defined(HAS_PICOLIBC_IO_MINIMAL) + "0x1 0x1 0x1 0x1 0x1\n" + "0x1 0x1 0x1 0x1\n" + "42 42 42 42\n" + "-42 -42 -42 -42\n" + "42 42 42 42\n" + "42 42 42 42\n" + "25542abcdef 42\n" +#else "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n" "0x1 0x 1 0x 1 0x 1\n" "42 42 0042 00000042\n" @@ -50,6 +106,7 @@ char expected_64[] = "22 113 10000 32768 40000 22\n" "42 42 42 42\n" "42 42 0042 00000042\n" "255 42 abcdef 42\n" +#endif "68719476735 -1 18446744073709551615 ffffffffffffffff\n" "0xcafebabe 0xbeef 0x2a\n" ; @@ -161,6 +218,8 @@ ZTEST(printk, test_printk) printk("0x%x %p %-2p\n", hex, ptr, (char *)42); pk_console[pos] = '\0'; + __printk_hook_install(_old_char_out); + printk("expected '%s'\n", expected); zassert_true((strcmp(pk_console, expected) == 0), "printk failed"); (void)memset(pk_console, 0, sizeof(pk_console)); From 6c95f23d81e6256c42c5afd20e3076e8a8dd5ce2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 27 Sep 2023 10:25:50 -0700 Subject: [PATCH 3946/4498] samples/code_relocation_nocopy: Increase fake flash size When linking with the 0.16.3 SDK version of picolibc, using long long cbprintf support pulls in the full floating point printf which is much larger than the integer-only version. This ends up overflowing the memory region available for it. Increase the size of that by bumping the start of the fake region by 8kB. Signed-off-by: Keith Packard --- .../code_relocation_nocopy/linker_arm_nocopy.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld index 916b1efe7fa..7ead7f6bae4 100644 --- a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld +++ b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld @@ -32,7 +32,7 @@ * Add another fake portion of FLASH to simulate a secondary or external FLASH * that we can do XIP from. */ -#define EXTFLASH_ADDR 0x5000 +#define EXTFLASH_ADDR 0x7000 #define EXTFLASH_SIZE (CONFIG_FLASH_SIZE * 1K - EXTFLASH_ADDR) #endif From a4a8120b6992bb671b15e22b55301dd39feb6371 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2023 22:06:27 -0700 Subject: [PATCH 3947/4498] doc: Update picolibc section in 3.5 migration guide for 1.8.5 Picolibc 1.8.5 includes more control over printf capabilities, document those in the migration guide. Signed-off-by: Keith Packard --- doc/releases/migration-guide-3.5.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index d9b81c62106..cda3602f19f 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -70,6 +70,16 @@ C Library compiler will now warn about declarations of `main` which don't conform to the Zephyr required type -- ``int main(void)``. + * Picolibc has four different printf/scanf variants supported in Zephyr, + 'double', 'long long', 'integer', and 'minimal. 'double' offers a + complete printf implementation with exact floating point in decimal and + hexidecimal formats, full integer support including long long, C99 + integer size specifiers (j, z, t) and POSIX positional arguments. 'long + long' mode removes float support, 'integer' removes long long support + while 'minimal' mode also removes support for format modifiers and + positional arguments. Building the library as a module allows finer + control over the feature set provided at each level. + * Picolibc's default floating point input/output code is larger than the minimal C library version (this is necessary to conform with the C language "round trip" requirements for these operations). If you use From 8e4c588eab9828e99ca0bf696982c1275bb13229 Mon Sep 17 00:00:00 2001 From: Henning Fleddermann Date: Tue, 19 Sep 2023 14:00:41 +0200 Subject: [PATCH 3948/4498] net: lib: lwm2m: Use int16_t for signal quality RSRQ is the ratio between send and received signal strength and usually understood/expected to be represented as a ratio in dB and as such always has a negative range. So to allow RSRQ to be represented correctly the resource must allow negative values, but currently it's limited to unsigned 8bit integers. Signed-off-by: Henning Fleddermann --- subsys/net/lib/lwm2m/lwm2m_obj_connmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c b/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c index acdd33ee21e..70309a0d3d6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c @@ -93,7 +93,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* resource state variables */ static int8_t net_bearer; static int16_t rss; -static uint8_t link_quality; +static int16_t link_quality; static uint32_t cellid; static uint16_t mnc; static uint16_t mcc; @@ -113,7 +113,7 @@ static struct lwm2m_engine_obj_field fields[] = { OBJ_FIELD_DATA(CONNMON_NETWORK_BEARER_ID, R, U8), OBJ_FIELD_DATA(CONNMON_AVAIL_NETWORK_BEARER_ID, R, U8), OBJ_FIELD_DATA(CONNMON_RADIO_SIGNAL_STRENGTH, R, S16), - OBJ_FIELD_DATA(CONNMON_LINK_QUALITY, R, U8), + OBJ_FIELD_DATA(CONNMON_LINK_QUALITY, R, S16), OBJ_FIELD_DATA(CONNMON_IP_ADDRESSES, R, STRING), OBJ_FIELD_DATA(CONNMON_ROUTER_IP_ADDRESSES, R_OPT, STRING), OBJ_FIELD_DATA(CONNMON_LINK_UTILIZATION, R_OPT, U8), From 6f91fd858cea07655928c3920539acb1c1646235 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Tue, 3 Oct 2023 10:37:10 +0200 Subject: [PATCH 3949/4498] dts: arm: silabs: Configure hfxo in dtsi This commit moves configuration of hfxo from headers defined on board level to device trees of SoCs. Signed-off-by: Franciszek Zdobylak --- boards/arm/efr32_radio/CMakeLists.txt | 2 -- boards/arm/efr32_thunderboard/CMakeLists.txt | 2 -- .../sl_device_init_hfxo_config.h | 14 -------------- boards/arm/efr32xg24_dk2601b/CMakeLists.txt | 5 ----- .../efr32xg24_dk2601b/sl_device_init_hfxo_config.h | 14 -------------- dts/arm/silabs/efr32bg2x.dtsi | 10 ++++++++++ dts/arm/silabs/efr32mg24.dtsi | 10 ++++++++++ dts/bindings/clock/silabs,hfxo.yaml | 9 +++++++++ .../common}/sl_device_init_hfxo_config.h | 8 +++----- 9 files changed, 32 insertions(+), 42 deletions(-) delete mode 100644 boards/arm/efr32_radio/CMakeLists.txt delete mode 100644 boards/arm/efr32_thunderboard/sl_device_init_hfxo_config.h delete mode 100644 boards/arm/efr32xg24_dk2601b/CMakeLists.txt delete mode 100644 boards/arm/efr32xg24_dk2601b/sl_device_init_hfxo_config.h create mode 100644 dts/bindings/clock/silabs,hfxo.yaml rename {boards/arm/efr32_radio => soc/arm/silabs_exx32/common}/sl_device_init_hfxo_config.h (58%) diff --git a/boards/arm/efr32_radio/CMakeLists.txt b/boards/arm/efr32_radio/CMakeLists.txt deleted file mode 100644 index 77a7880c491..00000000000 --- a/boards/arm/efr32_radio/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(.) diff --git a/boards/arm/efr32_thunderboard/CMakeLists.txt b/boards/arm/efr32_thunderboard/CMakeLists.txt index 17faf560add..ca93e65ac91 100644 --- a/boards/arm/efr32_thunderboard/CMakeLists.txt +++ b/boards/arm/efr32_thunderboard/CMakeLists.txt @@ -5,5 +5,3 @@ if(CONFIG_UART_GECKO) zephyr_library() zephyr_library_sources(board.c) endif() - -zephyr_include_directories(.) diff --git a/boards/arm/efr32_thunderboard/sl_device_init_hfxo_config.h b/boards/arm/efr32_thunderboard/sl_device_init_hfxo_config.h deleted file mode 100644 index 1b803c74f3d..00000000000 --- a/boards/arm/efr32_thunderboard/sl_device_init_hfxo_config.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2022 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H -#define SL_DEVICE_INIT_HFXO_CONFIG_H - -#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal -#define SL_DEVICE_INIT_HFXO_FREQ 38400000 -#define SL_DEVICE_INIT_HFXO_CTUNE 120 - -#endif /* SL_DEVICE_INIT_HFXO_CONFIG_H */ diff --git a/boards/arm/efr32xg24_dk2601b/CMakeLists.txt b/boards/arm/efr32xg24_dk2601b/CMakeLists.txt deleted file mode 100644 index 7997d692379..00000000000 --- a/boards/arm/efr32xg24_dk2601b/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2021 Sateesh Kotapati -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() -zephyr_library_sources(board.c) diff --git a/boards/arm/efr32xg24_dk2601b/sl_device_init_hfxo_config.h b/boards/arm/efr32xg24_dk2601b/sl_device_init_hfxo_config.h deleted file mode 100644 index 7f9e211748e..00000000000 --- a/boards/arm/efr32xg24_dk2601b/sl_device_init_hfxo_config.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H -#define SL_DEVICE_INIT_HFXO_CONFIG_H - -#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal -#define SL_DEVICE_INIT_HFXO_FREQ 39000000 -#define SL_DEVICE_INIT_HFXO_CTUNE 140 - -#endif /* SL_DEVICE_INIT_HFXO_CONFIG_H */ diff --git a/dts/arm/silabs/efr32bg2x.dtsi b/dts/arm/silabs/efr32bg2x.dtsi index e1f3726e429..5202acd350a 100644 --- a/dts/arm/silabs/efr32bg2x.dtsi +++ b/dts/arm/silabs/efr32bg2x.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { chosen { @@ -17,6 +18,15 @@ zephyr,entropy = &trng; }; + clocks { + clk_hfxo: clk-hfxo { + #clock-cells = <0>; + compatible = "silabs,hfxo"; + clock-frequency = ; + ctune = <120>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/silabs/efr32mg24.dtsi b/dts/arm/silabs/efr32mg24.dtsi index 1ee015b7334..b42b775397f 100644 --- a/dts/arm/silabs/efr32mg24.dtsi +++ b/dts/arm/silabs/efr32mg24.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { chosen { @@ -17,6 +18,15 @@ zephyr,entropy = &se; }; + clocks { + clk_hfxo: clk-hfxo { + #clock-cells = <0>; + compatible = "silabs,hfxo"; + clock-frequency = ; + ctune = <140>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/bindings/clock/silabs,hfxo.yaml b/dts/bindings/clock/silabs,hfxo.yaml new file mode 100644 index 00000000000..cd0d3ad1742 --- /dev/null +++ b/dts/bindings/clock/silabs,hfxo.yaml @@ -0,0 +1,9 @@ +compatible: "silabs,hfxo" + +include: fixed-clock.yaml + +properties: + ctune: + type: int + required: true + description: Load capacitance configuration diff --git a/boards/arm/efr32_radio/sl_device_init_hfxo_config.h b/soc/arm/silabs_exx32/common/sl_device_init_hfxo_config.h similarity index 58% rename from boards/arm/efr32_radio/sl_device_init_hfxo_config.h rename to soc/arm/silabs_exx32/common/sl_device_init_hfxo_config.h index c410e7c4093..533a591fbde 100644 --- a/boards/arm/efr32_radio/sl_device_init_hfxo_config.h +++ b/soc/arm/silabs_exx32/common/sl_device_init_hfxo_config.h @@ -7,12 +7,10 @@ #ifndef SL_DEVICE_INIT_HFXO_CONFIG_H #define SL_DEVICE_INIT_HFXO_CONFIG_H -#ifdef CONFIG_BOARD_EFR32_RADIO_BRD4187C +#include #define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal -#define SL_DEVICE_INIT_HFXO_FREQ 39000000 -#define SL_DEVICE_INIT_HFXO_CTUNE 140 - -#endif /* CONFIG_BOARD_EFR32_RADIO_BRD4187C */ +#define SL_DEVICE_INIT_HFXO_FREQ DT_PROP(DT_NODELABEL(clk_hfxo), clock_frequency) +#define SL_DEVICE_INIT_HFXO_CTUNE DT_PROP(DT_NODELABEL(clk_hfxo), ctune) #endif /* SL_DEVICE_INIT_HFXO_CONFIG_H */ From 1d01f5c6b9bd82f90be91f3b40e4d5ffe7002d08 Mon Sep 17 00:00:00 2001 From: Franciszek Zdobylak Date: Mon, 16 Oct 2023 12:08:03 +0200 Subject: [PATCH 3950/4498] dts: arm: silabs: Move gpio gecko header include Move the include to places where it is actually used. Signed-off-by: Franciszek Zdobylak --- boards/arm/efr32_thunderboard/thunderboard.dtsi | 1 + dts/arm/silabs/efr32bg2x-pinctrl.dtsi | 1 + dts/arm/silabs/efr32bg2x.dtsi | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/arm/efr32_thunderboard/thunderboard.dtsi b/boards/arm/efr32_thunderboard/thunderboard.dtsi index 31387b87609..be2401138ad 100644 --- a/boards/arm/efr32_thunderboard/thunderboard.dtsi +++ b/boards/arm/efr32_thunderboard/thunderboard.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { chosen { diff --git a/dts/arm/silabs/efr32bg2x-pinctrl.dtsi b/dts/arm/silabs/efr32bg2x-pinctrl.dtsi index 388423e10d0..fb5fc1b8484 100644 --- a/dts/arm/silabs/efr32bg2x-pinctrl.dtsi +++ b/dts/arm/silabs/efr32bg2x-pinctrl.dtsi @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include &pinctrl { diff --git a/dts/arm/silabs/efr32bg2x.dtsi b/dts/arm/silabs/efr32bg2x.dtsi index 5202acd350a..2f50f1bcbda 100644 --- a/dts/arm/silabs/efr32bg2x.dtsi +++ b/dts/arm/silabs/efr32bg2x.dtsi @@ -5,7 +5,6 @@ */ #include -#include #include #include #include From 7cf2b0fc9dfe395c002df6a6e13b93062a4d68ab Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 13 Nov 2023 10:55:46 +0100 Subject: [PATCH 3951/4498] modem: backend: uart_async: Extend "closed" requisites The current implementation only waits for the RX disabled event to determine if the UART is closed. It should wait for all RX buffers to be released, and the TX to be done as well. We now also call uart_tx_abort() when closing the pipe. Signed-off-by: Bjarki Arge Andreasen --- .../modem/backends/modem_backend_uart_async.c | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index 9c4e904ef9e..636f543166f 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -13,9 +13,10 @@ LOG_MODULE_DECLARE(modem_backend_uart); #include #define MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT (0) -#define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT (1) -#define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT (2) -#define MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT (3) +#define MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT (1) +#define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT (2) +#define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT (3) +#define MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT (4) static void modem_backend_uart_async_flush(struct modem_backend_uart *backend) { @@ -26,6 +27,22 @@ static void modem_backend_uart_async_flush(struct modem_backend_uart *backend) } } +static bool modem_backend_uart_async_is_closed(struct modem_backend_uart *backend) +{ + if (!atomic_test_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT) && + !atomic_test_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT) && + !atomic_test_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT) && + !atomic_test_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT)) { + return true; + } + + return false; +} + static uint8_t modem_backend_uart_async_rx_rbuf_used_index(struct modem_backend_uart *backend) { return atomic_test_bit(&backend->async.state, @@ -122,7 +139,8 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, break; case UART_RX_DISABLED: - k_work_submit(&backend->async.rx_disabled_work); + atomic_clear_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT); break; case UART_RX_STOPPED: @@ -132,6 +150,10 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, default: break; } + + if (modem_backend_uart_async_is_closed(backend)) { + k_work_submit(&backend->async.rx_disabled_work); + } } static int modem_backend_uart_async_open(void *data) @@ -159,6 +181,9 @@ static int modem_backend_uart_async_open(void *data) return ret; } + atomic_set_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT); + modem_pipe_notify_opened(&backend->pipe); return 0; } @@ -229,6 +254,7 @@ static int modem_backend_uart_async_close(void *data) { struct modem_backend_uart *backend = (struct modem_backend_uart *)data; + uart_tx_abort(backend->uart); uart_rx_disable(backend->uart); return 0; } From 6f1d49e7b3a3455599a5a892ae87fce6f4fb9b4e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 13 Nov 2023 19:15:30 +0100 Subject: [PATCH 3952/4498] modem: backend: uart_async: Use single ring buffer Use single ring buffer and protect it with a spinlock as it is shared between backend and UART thread (ISR). This is simpler than the double ring buffer setup. The receive idle timeout has also been made configurable instead of being a hardcoded value. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/backend/uart.h | 3 +- subsys/modem/backends/Kconfig | 4 + .../modem/backends/modem_backend_uart_async.c | 77 ++++++------------- 3 files changed, 28 insertions(+), 56 deletions(-) diff --git a/include/zephyr/modem/backend/uart.h b/include/zephyr/modem/backend/uart.h index 1aebe9e2030..0ddef4df734 100644 --- a/include/zephyr/modem/backend/uart.h +++ b/include/zephyr/modem/backend/uart.h @@ -31,7 +31,8 @@ struct modem_backend_uart_isr { struct modem_backend_uart_async { uint8_t *receive_bufs[2]; uint32_t receive_buf_size; - struct ring_buf receive_rdb[2]; + struct ring_buf receive_rb; + struct k_spinlock receive_rb_lock; uint8_t *transmit_buf; uint32_t transmit_buf_size; struct k_work rx_disabled_work; diff --git a/subsys/modem/backends/Kconfig b/subsys/modem/backends/Kconfig index 417566966a2..317f9d26aa8 100644 --- a/subsys/modem/backends/Kconfig +++ b/subsys/modem/backends/Kconfig @@ -28,6 +28,10 @@ config MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS int "Modem UART async transmit timeout in milliseconds" default 100 +config MODEM_BACKEND_UART_ASYNC_RECEIVE_IDLE_TIMEOUT_MS + int "Modem UART async receive idle timeout in milliseconds" + default 30 + endif endif # MODEM_BACKEND_UART diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index 636f543166f..7c59a749e2e 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -16,7 +16,6 @@ LOG_MODULE_DECLARE(modem_backend_uart); #define MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT (1) #define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT (2) #define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT (3) -#define MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT (4) static void modem_backend_uart_async_flush(struct modem_backend_uart *backend) { @@ -43,31 +42,11 @@ static bool modem_backend_uart_async_is_closed(struct modem_backend_uart *backen return false; } -static uint8_t modem_backend_uart_async_rx_rbuf_used_index(struct modem_backend_uart *backend) -{ - return atomic_test_bit(&backend->async.state, - MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT); -} - -static void modem_backend_uart_async_rx_rbuf_used_swap(struct modem_backend_uart *backend) -{ - uint8_t rx_rbuf_index = modem_backend_uart_async_rx_rbuf_used_index(backend); - - if (rx_rbuf_index) { - atomic_clear_bit(&backend->async.state, - MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT); - } else { - atomic_set_bit(&backend->async.state, - MODEM_BACKEND_UART_ASYNC_STATE_RX_RBUF_USED_INDEX_BIT); - } -} - static void modem_backend_uart_async_event_handler(const struct device *dev, struct uart_event *evt, void *user_data) { struct modem_backend_uart *backend = (struct modem_backend_uart *) user_data; - - uint8_t receive_rb_used_index; + k_spinlock_key_t key; uint32_t received; switch (evt->type) { @@ -123,18 +102,19 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, break; case UART_RX_RDY: - receive_rb_used_index = modem_backend_uart_async_rx_rbuf_used_index(backend); - - received = ring_buf_put(&backend->async.receive_rdb[receive_rb_used_index], - &evt->data.rx.buf[evt->data.rx.offset], - evt->data.rx.len); + key = k_spin_lock(&backend->async.receive_rb_lock); + received = ring_buf_put(&backend->async.receive_rb, + &evt->data.rx.buf[evt->data.rx.offset], + evt->data.rx.len); if (received < evt->data.rx.len) { - ring_buf_reset(&backend->async.receive_rdb[receive_rb_used_index]); + ring_buf_reset(&backend->async.receive_rb); + k_spin_unlock(&backend->async.receive_rb_lock, key); LOG_WRN("Receive buffer overrun"); break; } + k_spin_unlock(&backend->async.receive_rb_lock, key); k_work_submit(&backend->receive_ready_work); break; @@ -163,8 +143,7 @@ static int modem_backend_uart_async_open(void *data) atomic_set(&backend->async.state, 0); modem_backend_uart_async_flush(backend); - ring_buf_reset(&backend->async.receive_rdb[0]); - ring_buf_reset(&backend->async.receive_rdb[1]); + ring_buf_reset(&backend->async.receive_rb); /* Reserve receive buffer 0 */ atomic_set_bit(&backend->async.state, @@ -175,7 +154,8 @@ static int modem_backend_uart_async_open(void *data) * used to store received data. */ ret = uart_rx_enable(backend->uart, backend->async.receive_bufs[0], - backend->async.receive_buf_size, 3000); + backend->async.receive_buf_size, + CONFIG_MODEM_BACKEND_UART_ASYNC_RECEIVE_IDLE_TIMEOUT_MS * 1000L); if (ret < 0) { return ret; @@ -224,29 +204,19 @@ static int modem_backend_uart_async_transmit(void *data, const uint8_t *buf, siz static int modem_backend_uart_async_receive(void *data, uint8_t *buf, size_t size) { struct modem_backend_uart *backend = (struct modem_backend_uart *)data; - + k_spinlock_key_t key; uint32_t received; - uint8_t receive_rdb_unused; + bool empty; - received = 0; - receive_rdb_unused = modem_backend_uart_async_rx_rbuf_used_index(backend) ? 0 : 1; + key = k_spin_lock(&backend->async.receive_rb_lock); + received = ring_buf_get(&backend->async.receive_rb, buf, size); + empty = ring_buf_is_empty(&backend->async.receive_rb); + k_spin_unlock(&backend->async.receive_rb_lock, key); - /* Read data from unused ring double buffer first */ - received += ring_buf_get(&backend->async.receive_rdb[receive_rdb_unused], buf, size); - - if (ring_buf_is_empty(&backend->async.receive_rdb[receive_rdb_unused]) == false) { - return (int)received; + if (!empty) { + k_work_submit(&backend->receive_ready_work); } - /* Swap receive ring double buffer */ - modem_backend_uart_async_rx_rbuf_used_swap(backend); - - /* Read data from previously used buffer */ - receive_rdb_unused = modem_backend_uart_async_rx_rbuf_used_index(backend) ? 0 : 1; - - received += ring_buf_get(&backend->async.receive_rdb[receive_rdb_unused], - &buf[received], (size - received)); - return (int)received; } @@ -288,18 +258,15 @@ void modem_backend_uart_async_init(struct modem_backend_uart *backend, { uint32_t receive_buf_size_quarter = config->receive_buf_size / 4; - /* Split receive buffer into 4 buffers, use 2 parts for UART receive double buffer */ + /* Use half the receive buffer for UART receive buffers */ backend->async.receive_buf_size = receive_buf_size_quarter; backend->async.receive_bufs[0] = &config->receive_buf[0]; backend->async.receive_bufs[1] = &config->receive_buf[receive_buf_size_quarter]; - /* Use remaining 2 parts for receive double ring buffer */ - ring_buf_init(&backend->async.receive_rdb[0], receive_buf_size_quarter, + /* Use half the receive buffer for the received data ring buffer */ + ring_buf_init(&backend->async.receive_rb, (receive_buf_size_quarter * 2), &config->receive_buf[receive_buf_size_quarter * 2]); - ring_buf_init(&backend->async.receive_rdb[1], receive_buf_size_quarter, - &config->receive_buf[receive_buf_size_quarter * 3]); - backend->async.transmit_buf = config->transmit_buf; backend->async.transmit_buf_size = config->transmit_buf_size; k_work_init(&backend->async.rx_disabled_work, modem_backend_uart_async_notify_closed); From 8128a726a4f1e67cb8bed0da63d3a78a1bed466e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 14 Nov 2023 19:28:59 +0100 Subject: [PATCH 3953/4498] modem: backend: uart_async: Remove UART flush The UART flush is not relevant for the async UART implementation. UART drivers should handle this internally. Signed-off-by: Bjarki Arge Andreasen --- subsys/modem/backends/modem_backend_uart_async.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index 7c59a749e2e..bd18edbd2f5 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -17,15 +17,6 @@ LOG_MODULE_DECLARE(modem_backend_uart); #define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT (2) #define MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT (3) -static void modem_backend_uart_async_flush(struct modem_backend_uart *backend) -{ - uint8_t c; - - while (uart_fifo_read(backend->uart, &c, 1) > 0) { - continue; - } -} - static bool modem_backend_uart_async_is_closed(struct modem_backend_uart *backend) { if (!atomic_test_bit(&backend->async.state, @@ -142,7 +133,6 @@ static int modem_backend_uart_async_open(void *data) int ret; atomic_set(&backend->async.state, 0); - modem_backend_uart_async_flush(backend); ring_buf_reset(&backend->async.receive_rb); /* Reserve receive buffer 0 */ From d3f100355fd299c0b9d01e244a9f02b33780fec9 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 14 Nov 2023 20:48:23 +0100 Subject: [PATCH 3954/4498] tests: modem: backends: uart: Add UART backend test suite The UART backend test suite performs 9 iterations of: 1. Open UART backend pipe 2. Transmit 8192 bytes of pseudo random data 3. Receive and validate bytes 4. close UART backend pipe The test is run on real hardware, with the TX/RX pins connected to each other to provide loopback functionality. The test suite has been run on a STM32 and an nRF5340 board. The test suite tests both the UART interrupt driven and async APIs. Signed-off-by: Bjarki Arge Andreasen --- .../subsys/modem/backends/uart/CMakeLists.txt | 8 + .../uart/boards/b_u585i_iot02a.overlay | 34 +++ .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 37 +++ tests/subsys/modem/backends/uart/prj.conf | 10 + tests/subsys/modem/backends/uart/src/main.c | 210 ++++++++++++++++++ .../subsys/modem/backends/uart/testcase.yaml | 21 ++ 6 files changed, 320 insertions(+) create mode 100644 tests/subsys/modem/backends/uart/CMakeLists.txt create mode 100644 tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay create mode 100644 tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 tests/subsys/modem/backends/uart/prj.conf create mode 100644 tests/subsys/modem/backends/uart/src/main.c create mode 100644 tests/subsys/modem/backends/uart/testcase.yaml diff --git a/tests/subsys/modem/backends/uart/CMakeLists.txt b/tests/subsys/modem/backends/uart/CMakeLists.txt new file mode 100644 index 00000000000..c5e208dfd74 --- /dev/null +++ b/tests/subsys/modem/backends/uart/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(modem_backend_uart_test) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay new file mode 100644 index 00000000000..394facef7bb --- /dev/null +++ b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay @@ -0,0 +1,34 @@ +/* + * Pins 2 and 3 must be connected to each other on the STMOD+1 connector to + * loopback RX/TX. + */ + +/ { + aliases { + test-uart = &usart2; + }; +}; + +&gpioh { + misc_fixed_usart2 { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&gpdma1 { + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3 &usart2_rts_pa1 &usart2_cts_pa0>; + pinctrl-names = "default"; + current-speed = <115200>; + + dmas = <&gpdma1 0 27 STM32_DMA_PERIPH_TX + &gpdma1 1 26 STM32_DMA_PERIPH_RX>; + dma-names = "tx", "rx"; + + status = "okay"; +}; diff --git a/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..2d47b0f0744 --- /dev/null +++ b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,37 @@ +/* + * Pins P1.10 and P1.11 must be connected to each other to loopback RX/TX. + */ + +/ { + aliases { + test-uart = &uart1; + }; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + hw-flow-control; + pinctrl-names = "default", "sleep"; +}; + +&pinctrl { + uart1_default: uart1_default { + group1 { + psels = ; + }; + group2 { + psels = ; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; diff --git a/tests/subsys/modem/backends/uart/prj.conf b/tests/subsys/modem/backends/uart/prj.conf new file mode 100644 index 00000000000..fd93accbb08 --- /dev/null +++ b/tests/subsys/modem/backends/uart/prj.conf @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MODEM_MODULES=y +CONFIG_MODEM_BACKEND_UART=y +CONFIG_SERIAL=y +CONFIG_ZTEST=y +CONFIG_LOG=y +CONFIG_ZTEST_SHUFFLE=y +CONFIG_ZTEST_SHUFFLE_TEST_REPEAT_COUNT=3 diff --git a/tests/subsys/modem/backends/uart/src/main.c b/tests/subsys/modem/backends/uart/src/main.c new file mode 100644 index 00000000000..8a6c4c2813a --- /dev/null +++ b/tests/subsys/modem/backends/uart/src/main.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This test suite sets up a modem_backend_uart instance connected to a UART which has its + * RX and TX pins wired together to provide loopback functionality. A large number of bytes + * containing a sequence of pseudo random numbers are then transmitted, received, and validated. + * + * The test suite repeats three times, opening and clsoing the modem_pipe attached to the + * modem_backend_uart instance before and after the tests respectively. + */ + +/*************************************************************************************************/ +/* Dependencies */ +/*************************************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include + +/*************************************************************************************************/ +/* Mock pipe */ +/*************************************************************************************************/ +static const struct device *uart = DEVICE_DT_GET(DT_ALIAS(test_uart)); +static struct modem_backend_uart uart_backend; +static struct modem_pipe *pipe; +K_SEM_DEFINE(receive_ready_sem, 0, 1); + +/*************************************************************************************************/ +/* Buffers */ +/*************************************************************************************************/ +static uint8_t backend_receive_buffer[4096]; +static uint8_t backend_transmit_buffer[4096]; +RING_BUF_DECLARE(transmit_ring_buf, 4096); +static uint8_t receive_buffer[4096]; + +/*************************************************************************************************/ +/* Modem pipe callback */ +/*************************************************************************************************/ +static void modem_pipe_callback_handler(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + switch (event) { + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_sem_give(&receive_ready_sem); + break; + default: + break; + } +} + +/*************************************************************************************************/ +/* Helpers */ +/*************************************************************************************************/ +static uint32_t transmit_prng_state = 1234; +static uint32_t receive_prng_state = 1234; +static uint32_t transmit_size_prng_state; + +static uint8_t transmit_prng_random(void) +{ + transmit_prng_state = ((1103515245 * transmit_prng_state) + 12345) % (1U << 31); + return (uint8_t)(transmit_prng_state & 0xFF); +} + +static uint8_t receive_prng_random(void) +{ + receive_prng_state = ((1103515245 * receive_prng_state) + 12345) % (1U << 31); + return (uint8_t)(receive_prng_state & 0xFF); +} + +static void prng_reset(void) +{ + transmit_prng_state = 1234; + receive_prng_state = 1234; + transmit_size_prng_state = 0; +} + +static void fill_transmit_ring_buf(void) +{ + uint32_t space = ring_buf_space_get(&transmit_ring_buf); + uint8_t data; + + for (uint32_t i = 0; i < space; i++) { + data = transmit_prng_random(); + ring_buf_put(&transmit_ring_buf, &data, 1); + } +} + +static uint32_t transmit_size_prng_random(void) +{ + uint32_t size = 1; + + for (uint8_t i = 0; i < transmit_size_prng_state; i++) { + size = size * 2; + } + + transmit_size_prng_state = transmit_size_prng_state == 11 + ? 0 + : transmit_size_prng_state + 1; + + return size; +} + +static int transmit_prng(uint32_t remaining) +{ + uint8_t *reserved; + uint32_t reserved_size; + uint32_t transmit_size; + int ret; + + fill_transmit_ring_buf(); + reserved_size = ring_buf_get_claim(&transmit_ring_buf, &reserved, UINT32_MAX); + transmit_size = MIN(transmit_size_prng_random(), reserved_size); + transmit_size = MIN(remaining, transmit_size); + ret = modem_pipe_transmit(pipe, reserved, transmit_size); + if (ret < 0) { + return ret; + } + printk("TX: %u,%u\n", transmit_size, (uint32_t)ret); + __ASSERT(ret <= remaining, "Impossible number of bytes sent %u", (uint32_t)ret); + ring_buf_get_finish(&transmit_ring_buf, ret); + return ret; +} + +static int receive_prng(void) +{ + int ret = 0; + + if (k_sem_take(&receive_ready_sem, K_NO_WAIT) == 0) { + ret = modem_pipe_receive(pipe, receive_buffer, sizeof(receive_buffer)); + if (ret < 0) { + return -EFAULT; + } + for (uint32_t i = 0; i < (uint32_t)ret; i++) { + if (receive_prng_random() != receive_buffer[i]) { + return -EFAULT; + } + } + printk("RX: %u\n", (uint32_t)ret); + } + + return ret; +} + +/*************************************************************************************************/ +/* Test setup */ +/*************************************************************************************************/ +static void *test_modem_backend_uart_setup(void) +{ + const struct modem_backend_uart_config config = { + .uart = uart, + .receive_buf = backend_receive_buffer, + .receive_buf_size = 1024, + .transmit_buf = backend_transmit_buffer, + .transmit_buf_size = 1024, + }; + + pipe = modem_backend_uart_init(&uart_backend, &config); + modem_pipe_attach(pipe, modem_pipe_callback_handler, NULL); + return NULL; +} + +static void test_modem_backend_uart_before(void *f) +{ + prng_reset(); + ring_buf_reset(&transmit_ring_buf); + k_sem_reset(&receive_ready_sem); + __ASSERT_NO_MSG(modem_pipe_open(pipe) == 0); +} + +static void test_modem_backend_uart_after(void *f) +{ + __ASSERT_NO_MSG(modem_pipe_close(pipe) == 0); +} + +/*************************************************************************************************/ +/* Tests */ +/*************************************************************************************************/ +ZTEST(modem_backend_uart_suite, test_transmit_receive) +{ + int32_t remaining = 8192; + uint32_t received = 0; + uint32_t transmitted = 0; + int ret; + + while ((remaining != 0) || (received < 8192)) { + ret = transmit_prng(remaining); + zassert(ret > -1, "Failed to transmit data"); + remaining -= (uint32_t)ret; + transmitted += (uint32_t)ret; + printk("TX ACC: %u\n", transmitted); + + while (received < transmitted) { + ret = receive_prng(); + zassert(ret > -1, "Received data is corrupted"); + received += (uint32_t)ret; + k_yield(); + } + } +} + +ZTEST_SUITE(modem_backend_uart_suite, NULL, test_modem_backend_uart_setup, + test_modem_backend_uart_before, test_modem_backend_uart_after, NULL); diff --git a/tests/subsys/modem/backends/uart/testcase.yaml b/tests/subsys/modem/backends/uart/testcase.yaml new file mode 100644 index 00000000000..626ca639f75 --- /dev/null +++ b/tests/subsys/modem/backends/uart/testcase.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +tests: + modem.backends.uart.async: + tags: modem_backend + harness: ztest + platform_allow: + - b_u585i_iot02a + - nrf5340dk_nrf5340_cpuapp + extra_configs: + - CONFIG_UART_ASYNC_API=y + + modem.backends.uart.isr: + tags: modem_backend + harness: ztest + platform_allow: + - b_u585i_iot02a + - nrf5340dk_nrf5340_cpuapp + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y From ad788ad51173c08dc237653df132d500b0e40d26 Mon Sep 17 00:00:00 2001 From: Franciszek Pindel Date: Thu, 12 Oct 2023 12:57:37 +0200 Subject: [PATCH 3955/4498] gecko: pinctrl: Add missing configuration for Gecko Series usarts This commit adds missing pinctrl configuration for USARTs in efm32gg_slwstk6121a, efm32gg_stk3701a and efr32_radio boards and enables PINCTRL for efr32_radio_brd4180a and efr32_radio_brd4187c boards. Signed-off-by: Franciszek Pindel Signed-off-by: Mateusz Holenko --- .../efm32gg_slwstk6121a-pinctrl.dtsi | 19 +++++++++++++ .../efm32gg_slwstk6121a.dts | 5 ++-- .../efm32gg_stk3701a-pinctrl.dtsi | 28 +++++++++++++++++++ .../arm/efm32gg_stk3701a/efm32gg_stk3701a.dts | 9 +++--- .../arm/efr32_radio/efr32_radio-pinctrl.dtsi | 19 +++++++++++++ boards/arm/efr32_radio/efr32_radio.dtsi | 5 ++-- .../efr32_radio_brd4180a_defconfig | 1 + .../efr32_radio_brd4187c_defconfig | 1 + 8 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi create mode 100644 boards/arm/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi create mode 100644 boards/arm/efr32_radio/efr32_radio-pinctrl.dtsi diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi new file mode 100644 index 00000000000..ade31fddfd8 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for usart0 device, default state - operating as UART */ + usart0_default: usart0_default { + group1 { + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts index a45d13f7183..10912535b2d 100644 --- a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts @@ -9,6 +9,7 @@ /dts-v1/; #include #include +#include "efm32gg_slwstk6121a-pinctrl.dtsi" / { model = "Silicon Labs EFM32GG SLWSTK6121A board"; @@ -62,8 +63,8 @@ /* Connected to the WSTK VCOM */ &usart0 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi new file mode 100644 index 00000000000..8bb7025f4b2 --- /dev/null +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for usart0 device, default state - operating as UART */ + usart0_default: usart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + usart4_default: usart4_default { + group1 { + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts index 970cbafa1a2..1c457890f91 100644 --- a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts @@ -8,6 +8,7 @@ /dts-v1/; #include #include +#include "efm32gg_stk3701a-pinctrl.dtsi" / { model = "Silicon Labs EFM32GG STK3701A board"; @@ -60,15 +61,15 @@ &usart0 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; status = "okay"; }; &usart4 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart4_default>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/boards/arm/efr32_radio/efr32_radio-pinctrl.dtsi b/boards/arm/efr32_radio/efr32_radio-pinctrl.dtsi new file mode 100644 index 00000000000..ade31fddfd8 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio-pinctrl.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for usart0 device, default state - operating as UART */ + usart0_default: usart0_default { + group1 { + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/efr32_radio/efr32_radio.dtsi b/boards/arm/efr32_radio/efr32_radio.dtsi index a82081de469..361b66b72df 100644 --- a/boards/arm/efr32_radio/efr32_radio.dtsi +++ b/boards/arm/efr32_radio/efr32_radio.dtsi @@ -5,6 +5,7 @@ */ #include +#include "efr32_radio-pinctrl.dtsi" / { chosen { @@ -57,8 +58,8 @@ &usart0 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig b/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig index 79da19d5462..0db69e5d9e1 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig +++ b/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig @@ -9,3 +9,4 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 CONFIG_CMU_HFCLK_HFXO=y +CONFIG_PINCTRL=y diff --git a/boards/arm/efr32_radio/efr32_radio_brd4187c_defconfig b/boards/arm/efr32_radio/efr32_radio_brd4187c_defconfig index ce32a6638c3..046f8acfaed 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4187c_defconfig +++ b/boards/arm/efr32_radio/efr32_radio_brd4187c_defconfig @@ -10,6 +10,7 @@ CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=78000000 CONFIG_SOC_GECKO_EMU_DCDC=y CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y +CONFIG_PINCTRL=y # Use BURTC as system clock source CONFIG_GECKO_BURTC_TIMER=y From 26fd55e0a750305fbd5d9db750225d7e707458ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 16 Nov 2023 09:42:06 +0100 Subject: [PATCH 3956/4498] drivers: serial: nrfx_uarte: Rework Kconfig to use instance template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework Kconfig to improve handling of multiple UART instances by using Kconfig template file. Signed-off-by: Krzysztof Chruściński --- drivers/serial/Kconfig.nrfx | 309 +--------------------- drivers/serial/Kconfig.nrfx_uart_instance | 77 ++++++ drivers/serial/uart_nrfx_uarte.c | 14 +- 3 files changed, 101 insertions(+), 299 deletions(-) create mode 100644 drivers/serial/Kconfig.nrfx_uart_instance diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 1775b598c35..53553e3d06e 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -36,291 +36,25 @@ config UART_ASYNC_TX_CACHE_SIZE in RAM, because EasyDMA in UARTE peripherals can only transfer data from RAM. -# ----------------- port 0 ----------------- if HAS_HW_NRF_UART0 || HAS_HW_NRF_UARTE0 +nrfx_uart_num = 0 +rsource "Kconfig.nrfx_uart_instance" +endif -config UART_0_ENHANCED_POLL_OUT - bool "Efficient poll out on port 0" - default y - depends on HAS_HW_NRF_UARTE0 - help - When enabled, polling out does not trigger interrupt which stops TX. - Feature uses a PPI channel. - -config UART_0_INTERRUPT_DRIVEN - bool "Interrupt support on port 0" - depends on UART_INTERRUPT_DRIVEN - default y - help - This option enables UART interrupt support on port 0. - -config UART_0_ASYNC - bool "Asynchronous API support on port 0" - depends on UART_ASYNC_API && !UART_0_INTERRUPT_DRIVEN - default y - help - This option enables UART Asynchronous API support on port 0. - -config UART_0_NRF_PARITY_BIT - bool "Parity bit" - help - Enable parity bit. - -config UART_0_NRF_TX_BUFFER_SIZE - int "Size of RAM buffer" - depends on HAS_HW_NRF_UARTE0 - range 1 65535 - default 32 - help - Size of the transmit buffer for API function: fifo_fill. - This value is limited by range of TXD.MAXCNT register for - particular SoC. - -config UART_0_NRF_HW_ASYNC - bool "Use hardware RX byte counting" - depends on HAS_HW_NRF_UARTE0 - depends on UART_ASYNC_API - help - If default driver uses interrupts to count incoming bytes, it is possible - that with higher speeds and/or high cpu load some data can be lost. - It is recommended to use hardware byte counting in such scenarios. - Hardware RX byte counting requires timer instance and one PPI channel - -config UART_0_NRF_ASYNC_LOW_POWER - bool "Low power mode" - depends on HAS_HW_NRF_UARTE0 - depends on UART_ASYNC_API - help - When enabled, UARTE is enabled before each TX or RX usage and disabled - when not used. Disabling UARTE while in idle allows to achieve lowest - power consumption. It is only feasible if receiver is not always on. - -config UART_0_NRF_HW_ASYNC_TIMER - int "Timer instance" - depends on UART_0_NRF_HW_ASYNC - -config UART_0_GPIO_MANAGEMENT - bool "GPIO management on port 0" - depends on PM_DEVICE - default y - help - If enabled, the driver will configure the GPIOs used by the uart to - their default configuration when device is powered down. The GPIOs - will be configured back to correct state when UART is powered up. - -endif # HAS_HW_NRF_UART0 || HAS_HW_NRF_UARTE0 - -# ----------------- port 1 ----------------- if HAS_HW_NRF_UARTE1 +nrfx_uart_num = 1 +rsource "Kconfig.nrfx_uart_instance" +endif -config UART_1_INTERRUPT_DRIVEN - bool "Interrupt support on port 1" - depends on UART_INTERRUPT_DRIVEN - default y - help - This option enables UART interrupt support on port 1. - -config UART_1_ASYNC - bool "Asynchronous API support on port 1" - depends on UART_ASYNC_API && !UART_1_INTERRUPT_DRIVEN - default y - help - This option enables UART Asynchronous API support on port 1. - -config UART_1_ENHANCED_POLL_OUT - bool "Efficient poll out on port 1" - default y - help - When enabled, polling out does not trigger interrupt which stops TX. - Feature uses a PPI channel. - -config UART_1_NRF_PARITY_BIT - bool "Parity bit" - help - Enable parity bit. - -config UART_1_NRF_TX_BUFFER_SIZE - int "Size of RAM buffer" - depends on UART_INTERRUPT_DRIVEN - range 1 65535 - default 32 - help - Size of the transmit buffer for API function: fifo_fill. - This value is limited by range of TXD.MAXCNT register for - particular SoC. - -config UART_1_NRF_HW_ASYNC - bool "Use hardware RX byte counting" - depends on UART_1_ASYNC - help - If default driver uses interrupts to count incoming bytes, it is possible - that with higher speeds and/or high cpu load some data can be lost. - It is recommended to use hardware byte counting in such scenarios. - Hardware RX byte counting requires timer instance and one PPI channel - -config UART_1_NRF_ASYNC_LOW_POWER - bool "Low power mode" - depends on UART_ASYNC_API - help - When enabled, UARTE is enabled before each TX or RX usage and disabled - when not used. Disabling UARTE while in idle allows to achieve lowest - power consumption. It is only feasible if receiver is not always on. - -config UART_1_NRF_HW_ASYNC_TIMER - int "Timer instance" - depends on UART_1_NRF_HW_ASYNC - -config UART_1_GPIO_MANAGEMENT - bool "GPIO management on port 1" - depends on PM_DEVICE - default y - help - If enabled, the driver will configure the GPIOs used by the uart to - their default configuration when device is powered down. The GPIOs - will be configured back to correct state when UART is powered up. - -endif # HAS_HW_NRF_UARTE1 - -# ----------------- port 2 ----------------- if HAS_HW_NRF_UARTE2 +nrfx_uart_num = 2 +rsource "Kconfig.nrfx_uart_instance" +endif -config UART_2_INTERRUPT_DRIVEN - bool "Interrupt support on port 2" - depends on UART_INTERRUPT_DRIVEN - default y - help - This option enables UART interrupt support on port 2. - -config UART_2_ASYNC - bool "Asynchronous API support on port 2" - depends on UART_ASYNC_API && !UART_2_INTERRUPT_DRIVEN - default y - help - This option enables UART Asynchronous API support on port 2. - -config UART_2_ENHANCED_POLL_OUT - bool "Efficient poll out on port 2" - default y - help - When enabled, polling out does not trigger interrupt which stops TX. - Feature uses a PPI channel. - -config UART_2_NRF_PARITY_BIT - bool "Parity bit" - help - Enable parity bit. - -config UART_2_NRF_TX_BUFFER_SIZE - int "Size of RAM buffer" - range 1 65535 - default 32 - help - Size of the transmit buffer for API function: fifo_fill. - This value is limited by range of TXD.MAXCNT register for - particular SoC. - -config UART_2_NRF_HW_ASYNC - bool "Use hardware RX byte counting" - depends on UART_2_ASYNC - help - If default driver uses interrupts to count incoming bytes, it is possible - that with higher speeds and/or high cpu load some data can be lost. - It is recommended to use hardware byte counting in such scenarios. - Hardware RX byte counting requires timer instance and one PPI channel - -config UART_2_NRF_ASYNC_LOW_POWER - bool "Low power mode" - depends on UART_ASYNC_API - help - When enabled, UARTE is enabled before each TX or RX usage and disabled - when not used. Disabling UARTE while in idle allows to achieve lowest - power consumption. It is only feasible if receiver is not always on. - -config UART_2_NRF_HW_ASYNC_TIMER - int "Timer instance" - depends on UART_2_NRF_HW_ASYNC - -config UART_2_GPIO_MANAGEMENT - bool "GPIO management on port 2" - depends on PM_DEVICE - default y - help - If enabled, the driver will configure the GPIOs used by the uart to - their default configuration when device is powered down. The GPIOs - will be configured back to correct state when UART is powered up. - -endif # HAS_HW_NRF_UARTE2 - -# ----------------- port 3 ----------------- if HAS_HW_NRF_UARTE3 - -config UART_3_INTERRUPT_DRIVEN - bool "Interrupt support on port 3" - depends on UART_INTERRUPT_DRIVEN - default y - help - This option enables UART interrupt support on port 3. - -config UART_3_ASYNC - bool "Asynchronous API support on port 3" - depends on UART_ASYNC_API && !UART_3_INTERRUPT_DRIVEN - default y - help - This option enables UART Asynchronous API support on port 3. - -config UART_3_ENHANCED_POLL_OUT - bool "Efficient poll out on port 3" - default y - help - When enabled, polling out does not trigger interrupt which stops TX. - Feature uses a PPI channel. - -config UART_3_NRF_PARITY_BIT - bool "Parity bit" - help - Enable parity bit. - -config UART_3_NRF_TX_BUFFER_SIZE - int "Size of RAM buffer" - range 1 65535 - default 32 - help - Size of the transmit buffer for API function: fifo_fill. - This value is limited by range of TXD.MAXCNT register for - particular SoC. - -config UART_3_NRF_HW_ASYNC - bool "Use hardware RX byte counting" - depends on UART_3_ASYNC - help - If default driver uses interrupts to count incoming bytes, it is possible - that with higher speeds and/or high cpu load some data can be lost. - It is recommended to use hardware byte counting in such scenarios. - Hardware RX byte counting requires timer instance and one PPI channel - -config UART_3_NRF_ASYNC_LOW_POWER - bool "Low power mode" - depends on UART_ASYNC_API - help - When enabled, UARTE is enabled before each TX or RX usage and disabled - when not used. Disabling UARTE while in idle allows to achieve lowest - power consumption. It is only feasible if receiver is not always on. - -config UART_3_NRF_HW_ASYNC_TIMER - int "Timer instance" - depends on UART_3_NRF_HW_ASYNC - -config UART_3_GPIO_MANAGEMENT - bool "GPIO management on port 3" - depends on PM_DEVICE - default y - help - If enabled, the driver will configure the GPIOs used by the uart to - their default configuration when device is powered down. The GPIOs - will be configured back to correct state when UART is powered up. - -endif # HAS_HW_NRF_UARTE3 - +nrfx_uart_num = 3 +rsource "Kconfig.nrfx_uart_instance" +endif config NRFX_TIMER0 default y @@ -357,23 +91,4 @@ config NRFX_TIMER4 || UART_2_NRF_HW_ASYNC_TIMER = 4 \ || UART_3_NRF_HW_ASYNC_TIMER = 4 - -config UARTE_NRF_HW_ASYNC - def_bool y - depends on UART_0_NRF_HW_ASYNC \ - || UART_1_NRF_HW_ASYNC \ - || UART_2_NRF_HW_ASYNC \ - || UART_3_NRF_HW_ASYNC - select NRFX_PPI if HAS_HW_NRF_PPI - select NRFX_DPPI if HAS_HW_NRF_DPPIC - -config UART_ENHANCED_POLL_OUT - def_bool y - depends on UART_0_ENHANCED_POLL_OUT \ - || UART_1_ENHANCED_POLL_OUT \ - || UART_2_ENHANCED_POLL_OUT \ - || UART_3_ENHANCED_POLL_OUT - select NRFX_PPI if HAS_HW_NRF_PPI - select NRFX_DPPI if HAS_HW_NRF_DPPIC - endif # UART_NRFX diff --git a/drivers/serial/Kconfig.nrfx_uart_instance b/drivers/serial/Kconfig.nrfx_uart_instance new file mode 100644 index 00000000000..39e774e2544 --- /dev/null +++ b/drivers/serial/Kconfig.nrfx_uart_instance @@ -0,0 +1,77 @@ +#nRF UART(E) instance configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + bool "Interrupt support on port $(nrfx_uart_num)" + depends on UART_INTERRUPT_DRIVEN + default y + help + This option enables UART interrupt support on port $(nrfx_uart_num). + +config UART_$(nrfx_uart_num)_ASYNC + bool "Asynchronous API support on port $(nrfx_uart_num)" + depends on UART_ASYNC_API && !UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + default y + help + This option enables UART Asynchronous API support on port $(nrfx_uart_num). + +config UART_$(nrfx_uart_num)_ENHANCED_POLL_OUT + bool "Efficient poll out on port $(nrfx_uart_num)" + default y + depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + select NRFX_PPI if HAS_HW_NRF_PPI + select NRFX_DPPI if HAS_HW_NRF_DPPIC + help + When enabled, polling out does not trigger interrupt which stops TX. + Feature uses a PPI channel. + +config UART_$(nrfx_uart_num)_NRF_PARITY_BIT + bool "Parity bit" + help + Enable parity bit. + +config UART_$(nrfx_uart_num)_NRF_TX_BUFFER_SIZE + int "Size of RAM buffer" + depends on UART_INTERRUPT_DRIVEN + range 1 65535 + default 32 + help + Size of the transmit buffer for API function: fifo_fill. + This value is limited by range of TXD.MAXCNT register for + particular SoC. + +config UART_$(nrfx_uart_num)_NRF_HW_ASYNC + bool "Use hardware RX byte counting" + depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on UART_ASYNC_API + select NRFX_PPI if HAS_HW_NRF_PPI + select NRFX_DPPI if HAS_HW_NRF_DPPIC + help + If default driver uses interrupts to count incoming bytes, it is possible + that with higher speeds and/or high cpu load some data can be lost. + It is recommended to use hardware byte counting in such scenarios. + Hardware RX byte counting requires timer instance and one PPI channel. + +config UART_$(nrfx_uart_num)_NRF_ASYNC_LOW_POWER + bool "Low power mode" + depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on UART_ASYNC_API + help + When enabled, UARTE is enabled before each TX or RX usage and disabled + when not used. Disabling UARTE while in idle allows to achieve lowest + power consumption. It is only feasible if receiver is not always on. + +config UART_$(nrfx_uart_num)_NRF_HW_ASYNC_TIMER + int "Timer instance" + depends on UART_$(nrfx_uart_num)_NRF_HW_ASYNC + +config UART_$(nrfx_uart_num)_GPIO_MANAGEMENT + bool "GPIO management on port $(nrfx_uart_num)" + depends on PM_DEVICE + default y + help + If enabled, the driver will configure the GPIOs used by the uart to + their default configuration when device is powered down. The GPIOs + will be configured back to correct state when UART is powered up. diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index dc577ea9fc4..3a62057a47a 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -65,6 +65,16 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); #define UARTE_ANY_ASYNC 1 #endif +#if defined(CONFIG_UART_0_NRF_HW_ASYNC) || defined(CONFIG_UART_1_NRF_HW_ASYNC) || \ + defined(CONFIG_UART_2_NRF_HW_ASYNC) || defined(CONFIG_UART_3_NRF_HW_ASYNC) +#define UARTE_HW_ASYNC 1 +#endif + +#if defined(CONFIG_UART_0_ENHANCED_POLL_OUT) || defined(CONFIG_UART_1_ENHANCED_POLL_OUT) || \ + defined(CONFIG_UART_2_ENHANCED_POLL_OUT) || defined(CONFIG_UART_3_ENHANCED_POLL_OUT) +#define UARTE_ENHANCED_POLL_OUT 1 +#endif + /* * RX timeout is divided into time slabs, this define tells how many divisions * should be made. More divisions - higher timeout accuracy and processor usage. @@ -498,7 +508,7 @@ static int wait_tx_ready(const struct device *dev) * where static inline fails on linking. */ #define HW_RX_COUNTING_ENABLED(data) \ - (IS_ENABLED(CONFIG_UARTE_NRF_HW_ASYNC) ? data->async->hw_rx_counting : false) + (IS_ENABLED(UARTE_HW_ASYNC) ? data->async->hw_rx_counting : false) #endif /* UARTE_ANY_ASYNC */ @@ -1745,7 +1755,7 @@ static int uarte_instance_init(const struct device *dev, return err; } - if (IS_ENABLED(CONFIG_UART_ENHANCED_POLL_OUT) && + if (IS_ENABLED(UARTE_ENHANCED_POLL_OUT) && cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX) { err = endtx_stoptx_ppi_init(uarte, data); if (err < 0) { From f9b42bc911c30fcbf4a096b20c6eca83da750c39 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 16 Nov 2023 20:39:39 +0100 Subject: [PATCH 3957/4498] drivers: serial: uart_stm32.c: RxDataFlush on async_rx_enable When enabling async RX the first time after boot, there is an additional byte received with the first RX_DATA_RDY event, which seems to be caused by the RX data not being flushed before enabling the UART RX DMA. Adding a request to flush the RX data register before enabling the RX DMA, solves the issue. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/uart_stm32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 6c41d0f0a2e..fa2371cc1df 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -1579,6 +1579,13 @@ static int uart_stm32_async_rx_enable(const struct device *dev, return -EFAULT; } + /* Flush RX data buffer */ +#ifdef USART_SR_RXNE + LL_USART_ClearFlag_RXNE(config->usart); +#else + LL_USART_RequestRxDataFlush(config->usart); +#endif /* USART_SR_RXNE */ + /* Enable RX DMA requests */ uart_stm32_dma_rx_enable(dev); From fedd23f97041f3315f76ed76f67c25003fee18d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 17 Nov 2023 17:16:00 +0100 Subject: [PATCH 3958/4498] bluetooth: a2dp: Add missing Doxygen comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added missing Doxygen comments to various macros. Signed-off-by: Benjamin Cabé --- include/zephyr/bluetooth/a2dp-codec.h | 82 ++++++++++++++++++++------- include/zephyr/bluetooth/a2dp.h | 2 +- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/include/zephyr/bluetooth/a2dp-codec.h b/include/zephyr/bluetooth/a2dp-codec.h index 9e4e5ea3479..3da36420dcd 100644 --- a/include/zephyr/bluetooth/a2dp-codec.h +++ b/include/zephyr/bluetooth/a2dp-codec.h @@ -26,36 +26,76 @@ extern "C" { #endif -/* Sampling Frequency */ -#define A2DP_SBC_SAMP_FREQ_16000 BIT(7) -#define A2DP_SBC_SAMP_FREQ_32000 BIT(6) -#define A2DP_SBC_SAMP_FREQ_44100 BIT(5) -#define A2DP_SBC_SAMP_FREQ_48000 BIT(4) +/** + * @name Sampling Frequency + * @{ + */ +#define A2DP_SBC_SAMP_FREQ_16000 BIT(7) /**< 16 kHz */ +#define A2DP_SBC_SAMP_FREQ_32000 BIT(6) /**< 32 kHz */ +#define A2DP_SBC_SAMP_FREQ_44100 BIT(5) /**< 44.1 kHz */ +#define A2DP_SBC_SAMP_FREQ_48000 BIT(4) /**< 48 kHz */ +/** @} */ -/* Channel Mode */ -#define A2DP_SBC_CH_MODE_MONO BIT(3) -#define A2DP_SBC_CH_MODE_DUAL BIT(2) -#define A2DP_SBC_CH_MODE_STREO BIT(1) -#define A2DP_SBC_CH_MODE_JOINT BIT(0) +/** + * @name Channel Mode + * @{ + */ +#define A2DP_SBC_CH_MODE_MONO BIT(3) /**< Mono */ +#define A2DP_SBC_CH_MODE_DUAL BIT(2) /**< Dual Channel */ +#define A2DP_SBC_CH_MODE_STREO BIT(1) /**< Stereo */ +#define A2DP_SBC_CH_MODE_JOINT BIT(0) /**< Joint Stereo */ +/** @} */ -/* Block Length */ -#define A2DP_SBC_BLK_LEN_4 BIT(7) -#define A2DP_SBC_BLK_LEN_8 BIT(6) -#define A2DP_SBC_BLK_LEN_12 BIT(5) -#define A2DP_SBC_BLK_LEN_16 BIT(4) +/** + * @name Block Length + * @{ + */ +#define A2DP_SBC_BLK_LEN_4 BIT(7) /**< 4 blocks */ +#define A2DP_SBC_BLK_LEN_8 BIT(6) /**< 8 blocks */ +#define A2DP_SBC_BLK_LEN_12 BIT(5) /**< 12 blocks */ +#define A2DP_SBC_BLK_LEN_16 BIT(4) /**< 16 blocks */ +/** @} */ -/* Subbands */ -#define A2DP_SBC_SUBBAND_4 BIT(3) -#define A2DP_SBC_SUBBAND_8 BIT(2) +/** + * @name Subbands + * @{ + */ +#define A2DP_SBC_SUBBAND_4 BIT(3) /**< 4 subbands */ +#define A2DP_SBC_SUBBAND_8 BIT(2) /**< 8 subbands */ +/** @} */ -/* Allocation Method */ -#define A2DP_SBC_ALLOC_MTHD_SNR BIT(1) -#define A2DP_SBC_ALLOC_MTHD_LOUDNESS BIT(0) +/** + * @name Bit pool Allocation Method + * @{ + */ +#define A2DP_SBC_ALLOC_MTHD_SNR BIT(1) /**< Allocate based on loudness of the subband signal */ +#define A2DP_SBC_ALLOC_MTHD_LOUDNESS BIT(0) /**< Allocate based on the signal-to-noise ratio */ +/** @} */ +/** + * Gets the sampling rate from a codec preset + * @param preset Codec preset + */ #define BT_A2DP_SBC_SAMP_FREQ(preset) ((preset->config[0] >> 4) & 0x0f) +/** + * Gets the channel mode from a codec preset + * @param preset Codec preset + */ #define BT_A2DP_SBC_CHAN_MODE(preset) ((preset->config[0]) & 0x0f) +/** + * Gets the block length from a codec preset + * @param preset Codec preset + */ #define BT_A2DP_SBC_BLK_LEN(preset) ((preset->config[1] >> 4) & 0x0f) +/** + * Gets the number subbands from a codec preset + * @param preset Codec preset + */ #define BT_A2DP_SBC_SUB_BAND(preset) ((preset->config[1] >> 2) & 0x03) +/** + * Gets the bitpool allocation method from a codec preset + * @param preset Codec preset + */ #define BT_A2DP_SBC_ALLOC_MTHD(preset) ((preset->config[1]) & 0x03) /** @brief SBC Codec */ diff --git a/include/zephyr/bluetooth/a2dp.h b/include/zephyr/bluetooth/a2dp.h index 3df6db1a6fd..f7e8ff35ea1 100644 --- a/include/zephyr/bluetooth/a2dp.h +++ b/include/zephyr/bluetooth/a2dp.h @@ -1,5 +1,5 @@ /** @file - * @brief Advance Audio Distribution Profile header. + * @brief Advanced Audio Distribution Profile header. */ /* From 5ed8bb74d424a094cd295b8d0aa4ea2caf4cefa4 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 17 Nov 2023 15:12:31 +0100 Subject: [PATCH 3959/4498] tests: coredump: Adjust logging backend patterns to xtensa Adjust tests/subsys/debug/coredump logging backend's output matching pattern to Xtensa fatal errors handler's call sequence difference. Signed-off-by: Dmitrii Golovanov --- tests/subsys/debug/coredump/testcase.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/subsys/debug/coredump/testcase.yaml b/tests/subsys/debug/coredump/testcase.yaml index 0f9e2ecead2..004217f36b7 100644 --- a/tests/subsys/debug/coredump/testcase.yaml +++ b/tests/subsys/debug/coredump/testcase.yaml @@ -7,6 +7,7 @@ tests: platform_exclude: acrn_ehl_crb arch_exclude: - posix + - xtensa integration_platforms: - qemu_x86 harness: console @@ -14,6 +15,7 @@ tests: type: multi_line regex: - "Coredump: (.*)" + - ">>> ZEPHYR FATAL ERROR " - "E: #CD:BEGIN#" - "E: #CD:5([aA])45([0-9a-fA-F]+)" - "E: #CD:41([0-9a-fA-F]+)" @@ -21,3 +23,24 @@ tests: - "E: #CD:4([dD])([0-9a-fA-F]+)" - "E: #CD:END#" - "k_sys_fatal_error_handler" + + debug.coredump.logging_backend_xtensa: + tags: coredump + ignore_faults: true + ignore_qemu_crash: true + filter: CONFIG_ARCH_SUPPORTS_COREDUMP + arch_allow: + - xtensa + harness: console + harness_config: + type: multi_line + regex: + - "Coredump: (.*)" + - "E: #CD:BEGIN#" + - "E: #CD:5([aA])45([0-9a-fA-F]+)" + - "E: #CD:41([0-9a-fA-F]+)" + - "E: #CD:4([dD])([0-9a-fA-F]+)" + - "E: #CD:4([dD])([0-9a-fA-F]+)" + - "E: #CD:END#" + - ">>> ZEPHYR FATAL ERROR " + - "k_sys_fatal_error_handler" From 23324fc5bae43a40024fdde05c893c75f3a73fff Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Fri, 17 Nov 2023 15:24:08 +0100 Subject: [PATCH 3960/4498] boards: qemu_xtensa: coredump: Enable coredump Enable coredump on qemu_xtensa and qemu_xtensa_mmu. Signed-off-by: Dmitrii Golovanov --- boards/xtensa/qemu_xtensa/Kconfig.board | 2 ++ tests/subsys/debug/coredump/src/main.c | 1 + tests/subsys/debug/coredump/testcase.yaml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/boards/xtensa/qemu_xtensa/Kconfig.board b/boards/xtensa/qemu_xtensa/Kconfig.board index 4695b26396c..34cdf44a15c 100644 --- a/boards/xtensa/qemu_xtensa/Kconfig.board +++ b/boards/xtensa/qemu_xtensa/Kconfig.board @@ -7,9 +7,11 @@ config BOARD_QEMU_XTENSA bool "Xtensa emulation using QEMU" depends on SOC_XTENSA_DC233C select QEMU_TARGET + select ARCH_SUPPORTS_COREDUMP config BOARD_QEMU_XTENSA_MMU bool "Xtensa emulation using QEMU with MMU" depends on SOC_XTENSA_DC233C select QEMU_TARGET + select ARCH_SUPPORTS_COREDUMP select XTENSA_MMU diff --git a/tests/subsys/debug/coredump/src/main.c b/tests/subsys/debug/coredump/src/main.c index ddad60f9230..d5e11f2148d 100644 --- a/tests/subsys/debug/coredump/src/main.c +++ b/tests/subsys/debug/coredump/src/main.c @@ -31,6 +31,7 @@ void func_3(uint32_t *addr) defined(CONFIG_BOARD_HIFIVE1) || \ defined(CONFIG_BOARD_LONGAN_NANO) || \ defined(CONFIG_BOARD_LONGAN_NANO_LITE) || \ + defined(CONFIG_BOARD_QEMU_XTENSA) || \ defined(CONFIG_SOC_FAMILY_INTEL_ADSP) ARG_UNUSED(addr); /* Call k_panic() directly so Renode doesn't pause execution. diff --git a/tests/subsys/debug/coredump/testcase.yaml b/tests/subsys/debug/coredump/testcase.yaml index 004217f36b7..150c07600a1 100644 --- a/tests/subsys/debug/coredump/testcase.yaml +++ b/tests/subsys/debug/coredump/testcase.yaml @@ -31,6 +31,8 @@ tests: filter: CONFIG_ARCH_SUPPORTS_COREDUMP arch_allow: - xtensa + integration_platforms: + - qemu_xtensa harness: console harness_config: type: multi_line From 1829cf4324074be15737632d6f8a9f55f7dc8f17 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 29 Sep 2023 16:32:46 +0200 Subject: [PATCH 3961/4498] Bluetooth: Audio: Add set functions for codec meta Add set function for all metadata types for both codec_cfg and codec_cap. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 361 +++++++++++++- subsys/bluetooth/audio/codec.c | 621 ++++++++++++++++++++++++- tests/bluetooth/audio/codec/src/main.c | 466 +++++++++++++++++++ 3 files changed, 1428 insertions(+), 20 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 597e49ade9c..17bac991f18 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -788,8 +788,8 @@ int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec * @param[out] data Pointer to the data-pointer to update when item is found * @return Length of found @p data or 0 if not found */ -uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t **data); +uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t **data); /** * @brief Set or add a specific codec configuration value @@ -803,8 +803,9 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u * @retval -EINVAL if arguments are invalid * @retval -ENOMEM if the new value could not set or added due to memory */ -int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t *data, size_t data_len); +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t *data, + size_t data_len); /** @brief Lookup a specific metadata value based on type * @@ -820,6 +821,22 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data); +/** + * @brief Set or add a specific codec configuration metadata value. + * + * @param codec_cfg The codec configuration to set the value in. + * @param type The type id to set. + * @param data Pointer to the data-pointer to set. + * @param data_len Length of @p data. + * + * @retval The meta_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len); + /** @brief Extract preferred contexts * * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. @@ -833,6 +850,19 @@ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, */ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the preferred context of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ctx The preferred context to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx); + /** @brief Extract stream contexts * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. @@ -846,6 +876,19 @@ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *co */ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the stream context of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ctx The stream context to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx); + /** @brief Extract program info * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. @@ -860,6 +903,20 @@ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info); +/** + * @brief Set the program info of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param program_info The program info to set. + * @param program_info_len The length of @p program_info. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info, size_t program_info_len); + /** @brief Extract stream language * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. @@ -873,6 +930,19 @@ int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *co */ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the stream language of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param stream_lang The 24-bit stream language to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_stream_lang(struct bt_audio_codec_cfg *codec_cfg, + uint32_t stream_lang); + /** @brief Extract CCID list * * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. @@ -887,6 +957,20 @@ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *cod int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **ccid_list); +/** + * @brief Set the CCID list of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ccid_list The program info to set. + * @param ccid_list_len The length of @p ccid_list. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *ccid_list, size_t ccid_list_len); + /** @brief Extract parental rating * * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. @@ -900,6 +984,19 @@ int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec */ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the parental rating of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param parental_rating The parental rating to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_parental_rating parental_rating); + /** @brief Extract program info URI * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. @@ -914,6 +1011,21 @@ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info_uri); +/** + * @brief Set the program info URI of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param program_info_uri The program info URI to set. + * @param program_info_uri_len The length of @p program_info_uri. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info_uri, + size_t program_info_uri_len); + /** @brief Extract audio active state * * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. @@ -927,6 +1039,19 @@ int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg */ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the audio active state of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param state The audio active state to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_active_state state); + /** @brief Extract broadcast audio immediate rendering flag * * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. @@ -940,6 +1065,18 @@ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_c int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the broadcast audio immediate rendering flag of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cfg *codec_cfg); + /** @brief Extract extended metadata * * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. @@ -954,6 +1091,20 @@ int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **extended_meta); +/** + * @brief Set the extended metadata of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param extended_meta The extended metadata to set. + * @param extended_meta_len The length of @p extended_meta. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *extended_meta, size_t extended_meta_len); + /** @brief Extract vendor specific metadata * * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. @@ -967,6 +1118,20 @@ int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_ */ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **vendor_meta); + +/** + * @brief Set the vendor specific metadata of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param vendor_meta The vendor specific metadata to set. + * @param vendor_meta_len The length of @p vendor_meta. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *vendor_meta, size_t vendor_meta_len); /** @} */ /* End of bt_audio_codec_cfg */ /** @@ -982,14 +1147,30 @@ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cf /** * @brief Lookup a specific value based on type * - * @param[in] codec_cap The codec data to search in. - * @param[in] type The type id to look for + * @param[in] codec_cap The codec data to search in. + * @param[in] type The type id to look for * @param[out] data Pointer to the data-pointer to update when item is found * * @return Length of found @p data or 0 if not found */ -uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, - const uint8_t **data); +uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t **data); + +/** + * @brief Set or add a specific codec capability value + * + * @param codec_cap The codec data to set the value in. + * @param type The type id to set + * @param data Pointer to the data-pointer to set + * @param data_len Length of @p data + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t *data, + size_t data_len); /** * @brief Extract the frequency from a codec capability. @@ -1133,6 +1314,22 @@ int bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap *c int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, const uint8_t **data); +/** + * @brief Set or add a specific codec capability metadata value. + * + * @param codec_cap The codec capability to set the value in. + * @param type The type id to set. + * @param data Pointer to the data-pointer to set. + * @param data_len Length of @p data. + * + * @retval The meta_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len); + /** @brief Extract preferred contexts * * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. @@ -1146,6 +1343,19 @@ int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, */ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the preferred context of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ctx The preferred context to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx); + /** @brief Extract stream contexts * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. @@ -1159,6 +1369,19 @@ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *co */ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the stream context of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ctx The stream context to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx); + /** @brief Extract program info * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. @@ -1173,6 +1396,20 @@ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info); +/** + * @brief Set the program info of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param program_info The program info to set. + * @param program_info_len The length of @p program_info. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info, size_t program_info_len); + /** @brief Extract stream language * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. @@ -1186,6 +1423,19 @@ int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *co */ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the stream language of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param stream_lang The 24-bit stream language to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_stream_lang(struct bt_audio_codec_cap *codec_cap, + uint32_t stream_lang); + /** @brief Extract CCID list * * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. @@ -1200,6 +1450,20 @@ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *cod int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, const uint8_t **ccid_list); +/** + * @brief Set the CCID list of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ccid_list The program info to set. + * @param ccid_list_len The length of @p ccid_list. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap *codec_cap, + const uint8_t *ccid_list, size_t ccid_list_len); + /** @brief Extract parental rating * * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. @@ -1213,6 +1477,19 @@ int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec */ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the parental rating of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param parental_rating The parental rating to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_parental_rating parental_rating); + /** @brief Extract program info URI * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. @@ -1227,6 +1504,21 @@ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info_uri); +/** + * @brief Set the program info URI of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param program_info_uri The program info URI to set. + * @param program_info_uri_len The length of @p program_info_uri. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info_uri, + size_t program_info_uri_len); + /** @brief Extract audio active state * * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. @@ -1240,6 +1532,19 @@ int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap */ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the audio active state of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param state The audio active state to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_active_state state); + /** @brief Extract broadcast audio immediate rendering flag * * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. @@ -1253,6 +1558,18 @@ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_c int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the broadcast audio immediate rendering flag of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cap *codec_cap); + /** @brief Extract extended metadata * * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. @@ -1267,6 +1584,20 @@ int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, const uint8_t **extended_meta); +/** + * @brief Set the extended metadata of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param extended_meta The extended metadata to set. + * @param extended_meta_len The length of @p extended_meta. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap *codec_cap, + const uint8_t *extended_meta, size_t extended_meta_len); + /** @brief Extract vendor specific metadata * * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. @@ -1281,6 +1612,20 @@ int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, const uint8_t **vendor_meta); +/** + * @brief Set the vendor specific metadata of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param vendor_meta The vendor specific metadata to set. + * @param vendor_meta_len The length of @p vendor_meta. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap, + const uint8_t *vendor_meta, size_t vendor_meta_len); + /** @} */ /* End of bt_audio_codec_cap */ #ifdef __cplusplus diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 382c6f370b0..38b1ef7d22b 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -238,12 +238,12 @@ static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf, buf->len = codec_cfg->data_len; } -uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t **data) +uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t **data) { struct search_type_param param = { .found = false, - .type = type, + .type = (uint8_t)type, .data_len = 0, .data = data, }; @@ -275,8 +275,9 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u return param.data_len; } -int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t *data, size_t data_len) +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t *data, + size_t data_len) { struct net_buf_simple buf; int ret; @@ -519,10 +520,20 @@ int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 +static void init_net_buf_simple_from_meta(struct net_buf_simple *buf, uint8_t meta[], + size_t meta_len, size_t meta_size) +{ + buf->__buf = meta; + buf->data = meta; + buf->size = meta_size; + buf->len = meta_len; +} + static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type, const uint8_t **data) { struct search_type_param param = { + .found = false, .type = type, .data_len = 0, .data = data, @@ -555,6 +566,32 @@ static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t typ return param.data_len; } +static int codec_meta_set_val(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + struct net_buf_simple buf; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(data == NULL && data_len != 0) { + LOG_DBG("data is NULL"); + return -EINVAL; + } + + CHECKIF(data_len > UINT8_MAX) { + LOG_DBG("Invalid data_len %zu", data_len); + return -EINVAL; + } + + init_net_buf_simple_from_meta(&buf, meta, meta_len, meta_size); + + return ltv_set_val(&buf, (uint8_t)type, data, data_len); +} + static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -577,6 +614,27 @@ static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) return sys_get_le16(data); } +static int codec_meta_set_pref_context(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_context ctx) +{ + uint16_t ctx_le16; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) { + LOG_DBG("Invalid ctx value: %d", ctx); + return -EINVAL; + } + + ctx_le16 = sys_cpu_to_le16((uint16_t)ctx); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + (const uint8_t *)&ctx_le16, sizeof(ctx_le16)); +} + static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -599,6 +657,27 @@ static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) return sys_get_le16(data); } +static int codec_meta_set_stream_context(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_context ctx) +{ + uint16_t ctx_le16; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) { + LOG_DBG("Invalid ctx value: %d", ctx); + return -EINVAL; + } + + ctx_le16 = sys_cpu_to_le16((uint16_t)ctx); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + (const uint8_t *)&ctx_le16, sizeof(ctx_le16)); +} + static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, const uint8_t **program_info) { @@ -625,6 +704,23 @@ static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_program_info(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *program_info, size_t program_info_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + program_info, program_info_len); +} + static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -647,6 +743,27 @@ static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) return sys_get_le24(data); } +static int codec_meta_set_stream_lang(uint8_t meta[], size_t meta_len, size_t meta_size, + uint32_t stream_lang) +{ + uint8_t stream_lang_le[3]; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((stream_lang & 0xFFFFFFU) != stream_lang) { + LOG_DBG("Invalid stream_lang value: %d", stream_lang); + return -EINVAL; + } + + sys_put_le24(stream_lang, stream_lang_le); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_STREAM_LANG, + stream_lang_le, sizeof(stream_lang_le)); +} + static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, const uint8_t **ccid_list) { @@ -673,6 +790,23 @@ static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_ccid_list(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(ccid_list == NULL) { + LOG_DBG("ccid_list is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_CCID_LIST, + ccid_list, ccid_list_len); +} + static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -695,6 +829,27 @@ static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) return data[0]; } +static int codec_meta_set_parental_rating(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_parental_rating parental_rating) +{ + uint8_t parental_rating_u8; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if (parental_rating > BT_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE) { + LOG_DBG("Invalid parental_rating value: %d", parental_rating); + return -EINVAL; + } + + parental_rating_u8 = (uint8_t)parental_rating; + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + &parental_rating_u8, sizeof(parental_rating_u8)); +} + static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, const uint8_t **program_info_uri) { @@ -721,6 +876,25 @@ static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len return ret; } +static int codec_meta_set_program_info_uri(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info_uri == NULL) { + LOG_DBG("program_info_uri is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, + BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, program_info_uri, + program_info_uri_len); +} + static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -743,6 +917,27 @@ static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_l return data[0]; } +static int codec_meta_set_audio_active_state(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_active_state state) +{ + uint8_t state_u8; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if (state != BT_AUDIO_ACTIVE_STATE_DISABLED && state != BT_AUDIO_ACTIVE_STATE_ENABLED) { + LOG_DBG("Invalid state value: %d", state); + return -EINVAL; + } + + state_u8 = (uint8_t)state; + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + &state_u8, sizeof(state_u8)); +} + static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -756,6 +951,18 @@ static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], &data); } +static int codec_meta_set_bcast_audio_immediate_rend_flag(uint8_t meta[], size_t meta_len, + size_t meta_size) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, + BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, NULL, 0); +} + static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len, const uint8_t **extended_meta) { @@ -782,6 +989,23 @@ static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_extended(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *extended, size_t extended_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(extended == NULL) { + LOG_DBG("extended is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_EXTENDED, + extended, extended_len); +} + static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta) { const uint8_t *data; @@ -807,6 +1031,23 @@ static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const ui return ret; } +static int codec_meta_set_vendor(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *vendor, size_t vendor_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(vendor == NULL) { + LOG_DBG("vendor is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_VENDOR, vendor, + vendor_len); +} + #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data) @@ -819,6 +1060,26 @@ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, return codec_meta_get_val(codec_cfg->meta, codec_cfg->meta_len, type, data); } +int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + int ret; + + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + ret = codec_meta_set_val(codec_cfg->meta, codec_cfg->meta_len, ARRAY_SIZE(codec_cfg->meta), + type, data, data_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -829,6 +1090,20 @@ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *co return codec_meta_get_pref_context(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_pref_context(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ctx); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -839,6 +1114,20 @@ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * return codec_meta_get_stream_context(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_stream_context(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ctx); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info) { @@ -850,6 +1139,21 @@ int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *co return codec_meta_get_program_info(codec_cfg->meta, codec_cfg->meta_len, program_info); } +int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info, size_t program_info_len) +{ + int ret; + + ret = codec_meta_set_program_info(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), program_info, + program_info_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -860,6 +1164,20 @@ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *cod return codec_meta_get_stream_lang(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_stream_lang(struct bt_audio_codec_cfg *codec_cfg, + uint32_t stream_lang) +{ + int ret; + + ret = codec_meta_set_stream_lang(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), stream_lang); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **ccid_list) { @@ -871,6 +1189,20 @@ int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec return codec_meta_get_ccid_list(codec_cfg->meta, codec_cfg->meta_len, ccid_list); } +int bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + int ret; + + ret = codec_meta_set_ccid_list(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ccid_list, ccid_list_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -881,6 +1213,20 @@ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg return codec_meta_get_parental_rating(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_parental_rating parental_rating) +{ + int ret; + + ret = codec_meta_set_parental_rating(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), parental_rating); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info_uri) { @@ -893,6 +1239,22 @@ int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg program_info_uri); } +int bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + int ret; + + ret = codec_meta_set_program_info_uri(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), program_info_uri, + program_info_uri_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -903,6 +1265,20 @@ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_c return codec_meta_get_audio_active_state(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_active_state state) +{ + int ret; + + ret = codec_meta_set_audio_active_state(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), state); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cfg *codec_cfg) { @@ -911,11 +1287,23 @@ int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( return -EINVAL; } - LOG_ERR("codec_cfg->meta_len %zu", codec_cfg->meta_len); - return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cfg *codec_cfg) +{ + int ret; + + ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta)); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **extended_meta) { @@ -927,6 +1315,21 @@ int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_ return codec_meta_get_extended(codec_cfg->meta, codec_cfg->meta_len, extended_meta); } +int bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *extended_meta, size_t extended_meta_len) +{ + int ret; + + ret = codec_meta_set_extended(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), extended_meta, + extended_meta_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **vendor_meta) { @@ -937,6 +1340,20 @@ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cf return codec_meta_get_vendor(codec_cfg->meta, codec_cfg->meta_len, vendor_meta); } + +int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *vendor_meta, size_t vendor_meta_len) +{ + int ret; + + ret = codec_meta_set_vendor(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), vendor_meta, vendor_meta_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 @@ -951,6 +1368,26 @@ int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, return codec_meta_get_val(codec_cap->meta, codec_cap->meta_len, type, data); } +int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + int ret; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + ret = codec_meta_set_val(codec_cap->meta, codec_cap->meta_len, ARRAY_SIZE(codec_cap->meta), + type, data, data_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -961,6 +1398,20 @@ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *co return codec_meta_get_pref_context(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_pref_context(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ctx); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -971,6 +1422,20 @@ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * return codec_meta_get_stream_context(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_stream_context(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ctx); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info) { @@ -982,6 +1447,21 @@ int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *co return codec_meta_get_program_info(codec_cap->meta, codec_cap->meta_len, program_info); } +int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info, size_t program_info_len) +{ + int ret; + + ret = codec_meta_set_program_info(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), program_info, + program_info_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -992,6 +1472,20 @@ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *cod return codec_meta_get_stream_lang(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_stream_lang(struct bt_audio_codec_cap *codec_cap, + uint32_t stream_lang) +{ + int ret; + + ret = codec_meta_set_stream_lang(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), stream_lang); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, const uint8_t **ccid_list) { @@ -1003,6 +1497,20 @@ int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec return codec_meta_get_ccid_list(codec_cap->meta, codec_cap->meta_len, ccid_list); } +int bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap *codec_cap, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + int ret; + + ret = codec_meta_set_ccid_list(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ccid_list, ccid_list_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -1013,6 +1521,20 @@ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap return codec_meta_get_parental_rating(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_parental_rating parental_rating) +{ + int ret; + + ret = codec_meta_set_parental_rating(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), parental_rating); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info_uri) { @@ -1025,6 +1547,22 @@ int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap program_info_uri); } +int bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + int ret; + + ret = codec_meta_set_program_info_uri(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), program_info_uri, + program_info_uri_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -1035,6 +1573,20 @@ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_c return codec_meta_get_audio_active_state(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_active_state state) +{ + int ret; + + ret = codec_meta_set_audio_active_state(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), state); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cap *codec_cap) { @@ -1046,6 +1598,20 @@ int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cap *codec_cap) +{ + int ret; + + ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta)); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, const uint8_t **extended_meta) { @@ -1057,6 +1623,21 @@ int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_ return codec_meta_get_extended(codec_cap->meta, codec_cap->meta_len, extended_meta); } +int bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap *codec_cap, + const uint8_t *extended_meta, size_t extended_meta_len) +{ + int ret; + + ret = codec_meta_set_extended(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), extended_meta, + extended_meta_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, const uint8_t **vendor_meta) { @@ -1067,6 +1648,20 @@ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_ca return codec_meta_get_vendor(codec_cap->meta, codec_cap->meta_len, vendor_meta); } + +int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap, + const uint8_t *vendor_meta, size_t vendor_meta_len) +{ + int ret; + + ret = codec_meta_set_vendor(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), vendor_meta, vendor_meta_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */ #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ @@ -1083,11 +1678,12 @@ static void init_net_buf_simple_from_codec_cap(struct net_buf_simple *buf, buf->len = codec_cap->data_len; } -uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, - const uint8_t **data) +uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t **data) { struct search_type_param param = { - .type = type, + .found = false, + .type = (uint8_t)type, .data_len = 0, .data = data, }; @@ -1119,8 +1715,9 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, u return param.data_len; } -int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, uint8_t type, - const uint8_t *data, size_t data_len) +int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t *data, + size_t data_len) { struct net_buf_simple buf; int ret; diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 99d5d6f21fd..386ef40e7f7 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -228,6 +228,27 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_pref_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_pref_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const enum bt_audio_context new_ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_pref_context(&codec_cfg); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_pref_context(&codec_cfg, new_ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_pref_context(&codec_cfg); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_context) { const enum bt_audio_context ctx = @@ -242,6 +263,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_stream_context) +{ + enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_stream_context(&codec_cfg); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + ret = bt_audio_codec_cfg_meta_set_stream_context(&codec_cfg, ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_stream_context(&codec_cfg); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info) { const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', @@ -259,6 +300,31 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info) zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', + 'm', ' ', 'I', 'n', 'f', 'o'}; + const uint8_t new_expected_data[] = {'N', 'e', 'w', ' ', 'i', 'n', 'f', 'o'}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, 'P', 'r', 'o', 'g', 'r', + 'a', 'm', ' ', 'I', 'n', 'f', 'o')}); + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_cfg_meta_get_program_info(&codec_cfg, &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_program_info(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_program_info(&codec_cfg, &program_data); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_data, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_lang) { const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); @@ -271,6 +337,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_lang) zassert_equal(ret, expected_data, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); + const uint32_t new_stream_lang = sys_le32_to_cpu(new_expected_data); + int ret; + + ret = bt_audio_codec_cfg_meta_get_stream_lang(&codec_cfg); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_stream_lang(&codec_cfg, new_stream_lang); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_stream_lang(&codec_cfg); + zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; @@ -285,6 +371,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_cfg_meta_get_ccid_list(&codec_cfg, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_ccid_list(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_ccid_list(&codec_cfg, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, ccid_list, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_parental_rating) { const struct bt_audio_codec_cfg codec_cfg = @@ -297,6 +406,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_parental_rating) zassert_equal(ret, 0x07, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_parental_rating) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_parental_rating(&codec_cfg, + BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x0a, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info_uri) { const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; @@ -312,6 +440,30 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info_uri) zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const uint8_t new_expected_data[] = {'n', 'e', 'w', '.', 'c', 'o', 'm'}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, 'e', 'x', 'a', 'm', + 'p', 'l', 'e', '.', 'c', 'o', 'm')}); + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_cfg_meta_get_program_info_uri(&codec_cfg, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_program_info_uri(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_program_info_uri(&codec_cfg, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_info_uri, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_audio_active_state) { const struct bt_audio_codec_cfg codec_cfg = @@ -324,6 +476,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_audio_active_stat zassert_equal(ret, 0x01, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_audio_active_state) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_audio_active_state(&codec_cfg); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_audio_active_state(&codec_cfg, + BT_AUDIO_ACTIVE_STATE_DISABLED); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_audio_active_state(&codec_cfg); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag) { const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( @@ -335,6 +506,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_bcast_audio_immed zassert_equal(ret, 0, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, {}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_equal(ret, -ENODATA, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -349,6 +536,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended) zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cfg_meta_get_extended(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_extended(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_extended(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_vendor) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -363,6 +573,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_vendor) zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05, 0x06, 0x07, 0x08}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cfg_meta_get_vendor(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_vendor(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_vendor(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_freq) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( @@ -553,6 +786,27 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_pref_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_pref_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const enum bt_audio_context new_ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_pref_context(&codec_cap); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_pref_context(&codec_cap, new_ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_pref_context(&codec_cap); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_context) { const enum bt_audio_context ctx = @@ -567,6 +821,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_stream_context) +{ + enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_context(&codec_cap); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + ret = bt_audio_codec_cap_meta_set_stream_context(&codec_cap, ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_stream_context(&codec_cap); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info) { const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', @@ -584,6 +858,31 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info) zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', + 'm', ' ', 'I', 'n', 'f', 'o'}; + const uint8_t new_expected_data[] = {'N', 'e', 'w', ' ', 'i', 'n', 'f', 'o'}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, 'P', 'r', 'o', 'g', 'r', + 'a', 'm', ' ', 'I', 'n', 'f', 'o')}); + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info(&codec_cap, &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_program_info(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_program_info(&codec_cap, &program_data); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_data, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_lang) { const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); @@ -596,6 +895,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_lang) zassert_equal(ret, expected_data, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); + const uint32_t new_stream_lang = sys_le32_to_cpu(new_expected_data); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_lang(&codec_cap); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_stream_lang(&codec_cap, new_stream_lang); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_stream_lang(&codec_cap); + zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; @@ -610,6 +929,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_cap_meta_get_ccid_list(&codec_cap, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_ccid_list(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_ccid_list(&codec_cap, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, ccid_list, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_parental_rating) { const struct bt_audio_codec_cap codec_cap = @@ -622,6 +964,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_parental_rating) zassert_equal(ret, 0x07, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_parental_rating) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_parental_rating(&codec_cap); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_parental_rating(&codec_cap, + BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_parental_rating(&codec_cap); + zassert_equal(ret, 0x0a, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info_uri) { const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; @@ -637,6 +998,30 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info_uri) zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const uint8_t new_expected_data[] = {'n', 'e', 'w', '.', 'c', 'o', 'm'}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, 'e', 'x', 'a', 'm', + 'p', 'l', 'e', '.', 'c', 'o', 'm')}); + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info_uri(&codec_cap, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_program_info_uri(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_program_info_uri(&codec_cap, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_info_uri, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_audio_active_state) { const struct bt_audio_codec_cap codec_cap = @@ -649,6 +1034,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_audio_active_stat zassert_equal(ret, 0x01, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_audio_active_state) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_audio_active_state(&codec_cap); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_audio_active_state(&codec_cap, + BT_AUDIO_ACTIVE_STATE_DISABLED); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_audio_active_state(&codec_cap); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( @@ -660,6 +1064,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_bcast_audio_immed zassert_equal(ret, 0, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, {}); + int ret; + + ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_equal(ret, -ENODATA, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -674,6 +1094,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended) zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_extended(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_extended(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_extended(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_vendor) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -687,3 +1130,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_vendor) zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05, 0x06, 0x07, 0x08}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_vendor(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_vendor(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_vendor(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} From 176d433b98a28c8b455ead93cbe71b448246930c Mon Sep 17 00:00:00 2001 From: Adrien Bruant Date: Tue, 17 Oct 2023 15:13:51 +0200 Subject: [PATCH 3962/4498] drivers: bbram: stm32-bbram: port to stm32wl On STM32WL, the backup memory is defined as part of the TAMP peripheral. This seems to be a deviation from the stm32 family where this memory is defined as part of the RTC. The STM32WL reference manual shows that tamp_pclk is connected to rtc_pclk. This means that the clock required to run the TAMP peripheral is the same as the RTC's. A quick port of BBRAM on STM32WL is achieved by instanciating the bbram device as a child of the RTC and by modifying the address offset to the first backup register from the rtc base address. Signed-off-by: Adrien Bruant --- drivers/bbram/bbram_stm32.c | 9 ++++++++- dts/arm/st/wl/stm32wl.dtsi | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/bbram/bbram_stm32.c b/drivers/bbram/bbram_stm32.c index 30bc2c5edaa..0ba429d66f8 100644 --- a/drivers/bbram/bbram_stm32.c +++ b/drivers/bbram/bbram_stm32.c @@ -14,7 +14,14 @@ LOG_MODULE_REGISTER(bbram, CONFIG_BBRAM_LOG_LEVEL); #define STM32_BKP_REG_BYTES 4 -#define STM32_BKP_REG_OFFSET 0x50 +#ifdef TAMP +/* If a SoC has a TAMP peripherals, then the backup registers are defined there, + * not in the RTC. + */ +#define STM32_BKP_REG_OFFSET (TAMP_BASE + offsetof(TAMP_TypeDef, BKP0R) - RTC_BASE) +#else +#define STM32_BKP_REG_OFFSET offsetof(RTC_TypeDef, BKP0R) +#endif #define STM32_BKP_REG_INDEX(offset) ((offset) >> 2) #define STM32_BKP_REG_BYTE_INDEX(offset) ((offset)&0x3UL) #define STM32_BKP_REG(i) (((volatile uint32_t *)config->base_addr)[(i)]) diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index 85c40256e51..cc4b4dc31c9 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -207,6 +207,18 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>; prescaler = <32768>; status = "disabled"; + + /* In STM32WL, the backup registers are defined as part of the TAMP + * peripheral. This peripheral is not implemented in Zephyr yet, however, + * the reference manual states that tamp_pclk is connected to rtc_pclk. + * It makes sense to have BBRAM instantiated as a child of RTC, so that + * the driver can verify that its parent device (RTC) is ready. + */ + bbram: backup_regs { + compatible = "st,stm32-bbram"; + st,backup-regs = <20>; + status = "disabled"; + }; }; iwdg: watchdog@40003000 { From 8021cde6dee36d5229d92236c71fcd370f6a30c4 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 17 Oct 2023 14:21:08 -0700 Subject: [PATCH 3963/4498] mm: polish doxygen on memory management driver APIs Makes the HTML document on the MM driver APIs a bit more easier to navigate (hopefully). Signed-off-by: Daniel Leung --- include/zephyr/drivers/mm/system_mm.h | 112 ++++++++++++++++++++------ 1 file changed, 89 insertions(+), 23 deletions(-) diff --git a/include/zephyr/drivers/mm/system_mm.h b/include/zephyr/drivers/mm/system_mm.h index c76f1097f65..d523b706723 100644 --- a/include/zephyr/drivers/mm/system_mm.h +++ b/include/zephyr/drivers/mm/system_mm.h @@ -26,12 +26,20 @@ extern "C" { /** * @brief Memory Management Driver APIs * @defgroup mm_drv_apis Memory Management Driver APIs + * + * This contains APIs for a system-wide memory management + * driver. Only one instance is permitted on the system. + * * @ingroup memory_management * @{ */ -/* - * Caching mode definitions. These are mutually exclusive. +/** + * @name Caching mode definitions. + * + * These are mutually exclusive. + * + * @{ */ /** No caching */ @@ -46,9 +54,16 @@ extern "C" { /** Reserved bits for cache modes */ #define SYS_MM_MEM_CACHE_MASK (BIT(3) - 1) -/* - * Region permission attributes. +/** + * @} + */ + +/** + * @name Region permission attributes. + * * Default should be read-only, no user, no exec. + * + * @{ */ /** Region will have read/write access (and not read-only) */ @@ -60,6 +75,18 @@ extern "C" { /** Region will be accessible to user mode (normally supervisor-only) */ #define SYS_MM_MEM_PERM_USER BIT(5) +/** + * @} + */ + +/** + * @name Memory Mapping and Unmapping + * + * On mapping and unmapping of memory. + * + * @{ + */ + /** * @brief Map one physical page into the virtual address space * @@ -177,25 +204,6 @@ int sys_mm_drv_unmap_page(void *virt); */ int sys_mm_drv_unmap_region(void *virt, size_t size); -/** - * @brief Get the mapped physical memory address from virtual address. - * - * The function queries the translation tables to find the physical - * memory address of a mapped virtual address. - * - * Behavior when providing unaligned address is undefined, this - * is assumed to be page aligned. - * - * @param virt Page-aligned virtual address - * @param[out] phys Mapped physical address (can be NULL if only checking - * if virtual address is mapped) - * - * @retval 0 if mapping is found and valid - * @retval -EINVAL if invalid arguments are provided - * @retval -EFAULT if virtual address is not mapped - */ -int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys); - /** * @brief Remap virtual pages into new address * @@ -225,6 +233,18 @@ int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys); */ int sys_mm_drv_remap_region(void *virt_old, size_t size, void *virt_new); +/** + * @} + */ + +/** + * @name Memory Moving + * + * On moving already mapped memory. + * + * @{ + */ + /** * @brief Physically move memory, with copy * @@ -294,6 +314,17 @@ int sys_mm_drv_move_region(void *virt_old, size_t size, void *virt_new, int sys_mm_drv_move_array(void *virt_old, size_t size, void *virt_new, uintptr_t *phys_new, size_t phys_cnt); +/** + * @} + */ + +/** + * @name Memory Mapping Attributes + * + * On manipulating attributes of already mapped memory. + * + * @{ + */ /** * @brief Update memory page flags @@ -340,6 +371,37 @@ int sys_mm_drv_update_page_flags(void *virt, uint32_t flags); int sys_mm_drv_update_region_flags(void *virt, size_t size, uint32_t flags); +/** + * @} + */ + +/** + * @name Memory Mappings Query + * + * On querying information on memory mappings. + * + * @{ + */ + +/** + * @brief Get the mapped physical memory address from virtual address. + * + * The function queries the translation tables to find the physical + * memory address of a mapped virtual address. + * + * Behavior when providing unaligned address is undefined, this + * is assumed to be page aligned. + * + * @param virt Page-aligned virtual address + * @param[out] phys Mapped physical address (can be NULL if only checking + * if virtual address is mapped) + * + * @retval 0 if mapping is found and valid + * @retval -EINVAL if invalid arguments are provided + * @retval -EFAULT if virtual address is not mapped + */ +int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys); + /** * @brief Represents an available memory region. * @@ -387,6 +449,10 @@ const struct sys_mm_drv_region *sys_mm_drv_query_memory_regions(void); */ void sys_mm_drv_query_memory_regions_free(const struct sys_mm_drv_region *regions); +/** + * @} + */ + /** * @} */ From ca1aae618349f67d5fb6eb0596d9fa3660da0c7a Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 17 Oct 2023 14:30:19 -0700 Subject: [PATCH 3964/4498] mm: intel_adsp_mtl_tlb: move SRAM_BANK_PAGE_NUM in driver The macro SRAM_BANK_PAGE_NUM is specfic to the mtl_tlb driver and is not universal. So move that from public header into the driver. Signed-off-by: Daniel Leung --- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 2 ++ include/zephyr/drivers/mm/mm_drv_bank.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index 55a9b1776a1..dfe8d86ee7d 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -27,6 +27,8 @@ #include #include +#define SRAM_BANK_PAGE_NUM (SRAM_BANK_SIZE / CONFIG_MM_DRV_PAGE_SIZE) + static struct k_spinlock tlb_lock; extern struct k_spinlock sys_mm_drv_common_lock; diff --git a/include/zephyr/drivers/mm/mm_drv_bank.h b/include/zephyr/drivers/mm/mm_drv_bank.h index 9e1a51ebcbf..8b1402c94e7 100644 --- a/include/zephyr/drivers/mm/mm_drv_bank.h +++ b/include/zephyr/drivers/mm/mm_drv_bank.h @@ -21,8 +21,6 @@ #include #include -#define SRAM_BANK_PAGE_NUM (SRAM_BANK_SIZE / CONFIG_MM_DRV_PAGE_SIZE) - struct mem_drv_bank { uint32_t unmapped_pages; uint32_t mapped_pages; From 9a6e32f87c2cf4cdbc8077124beac37b76e47b52 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 17 Oct 2023 14:36:33 -0700 Subject: [PATCH 3965/4498] mm: rename struct mem_drv_bank to sys_mm_drv_bank Simply to put them into correct namespace as the struct is part of public API. Signed-off-by: Daniel Leung --- drivers/mm/mm_drv_bank.c | 10 +++++----- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 2 +- include/zephyr/drivers/mm/mm_drv_bank.h | 12 ++++++------ tests/drivers/mm/sys_mm_drv_bank/src/main.c | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/mm/mm_drv_bank.c b/drivers/mm/mm_drv_bank.c index 03209ffec41..ca9ad9d051b 100644 --- a/drivers/mm/mm_drv_bank.c +++ b/drivers/mm/mm_drv_bank.c @@ -18,14 +18,14 @@ #include #include -void sys_mm_drv_bank_init(struct mem_drv_bank *bank, uint32_t bank_pages) +void sys_mm_drv_bank_init(struct sys_mm_drv_bank *bank, uint32_t bank_pages) { bank->unmapped_pages = 0; bank->mapped_pages = bank_pages; bank->max_mapped_pages = bank_pages; } -uint32_t sys_mm_drv_bank_page_mapped(struct mem_drv_bank *bank) +uint32_t sys_mm_drv_bank_page_mapped(struct sys_mm_drv_bank *bank) { bank->unmapped_pages--; bank->mapped_pages++; @@ -35,14 +35,14 @@ uint32_t sys_mm_drv_bank_page_mapped(struct mem_drv_bank *bank) return bank->mapped_pages; } -uint32_t sys_mm_drv_bank_page_unmapped(struct mem_drv_bank *bank) +uint32_t sys_mm_drv_bank_page_unmapped(struct sys_mm_drv_bank *bank) { bank->unmapped_pages++; bank->mapped_pages--; return bank->unmapped_pages; } -void sys_mm_drv_bank_stats_get(struct mem_drv_bank *bank, +void sys_mm_drv_bank_stats_get(struct sys_mm_drv_bank *bank, struct sys_memory_stats *stats) { stats->free_bytes = bank->unmapped_pages * @@ -53,7 +53,7 @@ void sys_mm_drv_bank_stats_get(struct mem_drv_bank *bank, CONFIG_MM_DRV_PAGE_SIZE; } -void sys_mm_drv_bank_stats_reset_max(struct mem_drv_bank *bank) +void sys_mm_drv_bank_stats_reset_max(struct sys_mm_drv_bank *bank) { bank->max_mapped_pages = bank->mapped_pages; } diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index dfe8d86ee7d..ea3bb385b3b 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -32,7 +32,7 @@ static struct k_spinlock tlb_lock; extern struct k_spinlock sys_mm_drv_common_lock; -static struct mem_drv_bank hpsram_bank[L2_SRAM_BANK_NUM]; +static struct sys_mm_drv_bank hpsram_bank[L2_SRAM_BANK_NUM]; #ifdef CONFIG_SOC_INTEL_COMM_WIDGET #include diff --git a/include/zephyr/drivers/mm/mm_drv_bank.h b/include/zephyr/drivers/mm/mm_drv_bank.h index 8b1402c94e7..5fc06989dc8 100644 --- a/include/zephyr/drivers/mm/mm_drv_bank.h +++ b/include/zephyr/drivers/mm/mm_drv_bank.h @@ -21,7 +21,7 @@ #include #include -struct mem_drv_bank { +struct sys_mm_drv_bank { uint32_t unmapped_pages; uint32_t mapped_pages; uint32_t max_mapped_pages; @@ -39,7 +39,7 @@ struct mem_drv_bank { * @param bank Pointer to the memory bank structure used for tracking * @param bank_pages Number of pages in the memory bank */ -void sys_mm_drv_bank_init(struct mem_drv_bank *bank, uint32_t bank_pages); +void sys_mm_drv_bank_init(struct sys_mm_drv_bank *bank, uint32_t bank_pages); /** * @brief Track the mapping of a page in the specified memory bank @@ -51,7 +51,7 @@ void sys_mm_drv_bank_init(struct mem_drv_bank *bank, uint32_t bank_pages); * * @return The number of pages mapped within the memory bank */ -uint32_t sys_mm_drv_bank_page_mapped(struct mem_drv_bank *bank); +uint32_t sys_mm_drv_bank_page_mapped(struct sys_mm_drv_bank *bank); /** * @brief Track the unmapping of a page in the specified memory bank @@ -63,7 +63,7 @@ uint32_t sys_mm_drv_bank_page_mapped(struct mem_drv_bank *bank); * * @return The number of unmapped pages within the memory bank */ -uint32_t sys_mm_drv_bank_page_unmapped(struct mem_drv_bank *bank); +uint32_t sys_mm_drv_bank_page_unmapped(struct sys_mm_drv_bank *bank); /** * @brief Reset the max number of pages mapped in the bank @@ -74,7 +74,7 @@ uint32_t sys_mm_drv_bank_page_unmapped(struct mem_drv_bank *bank); * * @param bank Pointer to the memory bank's data structure */ -void sys_mm_drv_bank_stats_reset_max(struct mem_drv_bank *bank); +void sys_mm_drv_bank_stats_reset_max(struct sys_mm_drv_bank *bank); /** * @brief Retrieve the memory usage stats for the specified memory bank @@ -84,7 +84,7 @@ void sys_mm_drv_bank_stats_reset_max(struct mem_drv_bank *bank); * @param bank Pointer to the memory bank's data structure * @param stats Pointer to memory into which to copy the system memory stats */ -void sys_mm_drv_bank_stats_get(struct mem_drv_bank *bank, +void sys_mm_drv_bank_stats_get(struct sys_mm_drv_bank *bank, struct sys_memory_stats *stats); #endif /* ZEPHYR_INCLUDE_DRIVERS_MM_DRV_BANK_H */ diff --git a/tests/drivers/mm/sys_mm_drv_bank/src/main.c b/tests/drivers/mm/sys_mm_drv_bank/src/main.c index dfde79302d2..882d57cb1f5 100644 --- a/tests/drivers/mm/sys_mm_drv_bank/src/main.c +++ b/tests/drivers/mm/sys_mm_drv_bank/src/main.c @@ -11,7 +11,7 @@ #define EXPECTED(x) ((x) * CONFIG_MM_DRV_PAGE_SIZE) -static struct mem_drv_bank bank_data = {0x123, 0x234, 0x345}; +static struct sys_mm_drv_bank bank_data = {0x123, 0x234, 0x345}; static void test_stats(const char *error_string, struct sys_memory_stats *stats, From 9c90ed6f61ac12a1884fb49f43746c9db5a88107 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 17 Oct 2023 14:45:54 -0700 Subject: [PATCH 3966/4498] mm: polish doxygen doc on memory banks driver APIs () Put the memory bank APIs under the memory management group. () Document the struct sys_mm_drv_bank. () Put proper in,out for function parameters. Signed-off-by: Daniel Leung --- include/zephyr/drivers/mm/mm_drv_bank.h | 47 +++++++++++++++++++------ 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/include/zephyr/drivers/mm/mm_drv_bank.h b/include/zephyr/drivers/mm/mm_drv_bank.h index 5fc06989dc8..75fb57467ce 100644 --- a/include/zephyr/drivers/mm/mm_drv_bank.h +++ b/include/zephyr/drivers/mm/mm_drv_bank.h @@ -9,9 +9,10 @@ * @brief Memory Banks Driver APIs * * This contains generic APIs to be used by a system-wide memory management - * driver to track page usage within memory banks. It is incumbent upon the - * caller to ensure that proper locking is used to protect the data when - * using these APIs. + * driver to track page usage within memory banks. + * + * @note The caller of these functions needs to ensure proper locking + * to protect the data when using these APIs. */ #ifndef ZEPHYR_INCLUDE_DRIVERS_MM_DRV_BANK_H @@ -21,9 +22,31 @@ #include #include +/** + * @brief Memory Banks Driver APIs + * @defgroup mm_drv_bank_apis Memory Banks Driver APIs + * + * This contains APIs for a system-wide memory management driver to + * track page usage within memory banks. + * + * @note The caller of these functions needs to ensure proper locking + * to protect the data when using these APIs. + * + * @ingroup memory_management + * @{ + */ + +/** + * @brief Information about memory banks. + */ struct sys_mm_drv_bank { + /** Number of unmapped pages. */ uint32_t unmapped_pages; + + /** Number of mapped pages. */ uint32_t mapped_pages; + + /** Maximum number of mapped pages since last counter reset. */ uint32_t max_mapped_pages; }; @@ -36,8 +59,8 @@ struct sys_mm_drv_bank { * it will start with all pages mapped. In next phase of driver initialization * unused pages will be unmapped. * - * @param bank Pointer to the memory bank structure used for tracking - * @param bank_pages Number of pages in the memory bank + * @param[in,out] bank Pointer to the memory bank structure used for tracking + * @param[in] bank_pages Number of pages in the memory bank */ void sys_mm_drv_bank_init(struct sys_mm_drv_bank *bank, uint32_t bank_pages); @@ -47,7 +70,7 @@ void sys_mm_drv_bank_init(struct sys_mm_drv_bank *bank, uint32_t bank_pages); * This function is used to update the number of mapped pages within the * specified memory bank. * - * @param bank Pointer to the memory bank's data structure + * @param[in,out] bank Pointer to the memory bank's data structure * * @return The number of pages mapped within the memory bank */ @@ -59,7 +82,7 @@ uint32_t sys_mm_drv_bank_page_mapped(struct sys_mm_drv_bank *bank); * This function is used to update the number of unmapped pages within the * specified memory bank. * - * @param bank Pointer to the memory bank's data structure + * @param[in,out] bank Pointer to the memory bank's data structure * * @return The number of unmapped pages within the memory bank */ @@ -72,7 +95,7 @@ uint32_t sys_mm_drv_bank_page_unmapped(struct sys_mm_drv_bank *bank); * the specified memory bank to the current number of pages mapped in * that memory bank. * - * @param bank Pointer to the memory bank's data structure + * @param[in,out] bank Pointer to the memory bank's data structure */ void sys_mm_drv_bank_stats_reset_max(struct sys_mm_drv_bank *bank); @@ -81,10 +104,14 @@ void sys_mm_drv_bank_stats_reset_max(struct sys_mm_drv_bank *bank); * * This routine extracts the system memory stats from the memory bank. * - * @param bank Pointer to the memory bank's data structure - * @param stats Pointer to memory into which to copy the system memory stats + * @param[in] bank Pointer to the memory bank's data structure + * @param[in,out] stats Pointer to memory into which to copy the system memory stats */ void sys_mm_drv_bank_stats_get(struct sys_mm_drv_bank *bank, struct sys_memory_stats *stats); +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_MM_DRV_BANK_H */ From f8a9d95549692849e8e8931945d8bf0809198034 Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Wed, 8 Nov 2023 10:32:01 +0100 Subject: [PATCH 3967/4498] soc: arm: st_stm32: stm32u5: Add STM32U5A9 support Add support for STM32U5A9XX SoC series Signed-off-by: Abderrahmane Jarmouni --- .../st_stm32/stm32u5/Kconfig.defconfig.stm32u5a9xx | 14 ++++++++++++++ soc/arm/st_stm32/stm32u5/Kconfig.soc | 4 ++++ 2 files changed, 18 insertions(+) create mode 100644 soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a9xx diff --git a/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a9xx b/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a9xx new file mode 100644 index 00000000000..0553382acb1 --- /dev/null +++ b/soc/arm/st_stm32/stm32u5/Kconfig.defconfig.stm32u5a9xx @@ -0,0 +1,14 @@ +# STMicroelectronics STM32U5A9XX MCU + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32U5A9XX + +config SOC + default "stm32u5a9xx" + +config NUM_IRQS + default 139 + +endif # SOC_STM32U5A9XX diff --git a/soc/arm/st_stm32/stm32u5/Kconfig.soc b/soc/arm/st_stm32/stm32u5/Kconfig.soc index 8308c64372f..ec8c964ad3e 100644 --- a/soc/arm/st_stm32/stm32u5/Kconfig.soc +++ b/soc/arm/st_stm32/stm32u5/Kconfig.soc @@ -2,6 +2,7 @@ # Copyright (c) 2021 Linaro Limited # Copyright (c) 2023 PSICONTROL nv +# Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 choice @@ -23,4 +24,7 @@ config SOC_STM32U599XX config SOC_STM32U5A5XX bool "STM32U5A5XX" +config SOC_STM32U5A9XX + bool "STM32U5A9XX" + endchoice From 236ba6bf5ab0a0915083c460e5e826a85bd3bbda Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Wed, 8 Nov 2023 10:36:27 +0100 Subject: [PATCH 3968/4498] dt-bindings: clock: Add STM32U5A9 clk sel helpers Add clock selection helpers specific to STM32U59x/5Ax & STM32U5Fx/5Gx SoCs Signed-off-by: Abderrahmane Jarmouni --- .../zephyr/dt-bindings/clock/stm32u5_clock.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/include/zephyr/dt-bindings/clock/stm32u5_clock.h b/include/zephyr/dt-bindings/clock/stm32u5_clock.h index 900f77620f8..ca4b774d802 100644 --- a/include/zephyr/dt-bindings/clock/stm32u5_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32u5_clock.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Linaro Limited + * Copyright (c) 2023 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ @@ -87,8 +88,8 @@ #define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR1_REG) #define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR1_REG) #define USART3_SEL(val) STM32_CLOCK(val, 3, 4, CCIPR1_REG) -#define USART4_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR1_REG) -#define USART5_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR1_REG) +#define UART4_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR1_REG) +#define UART5_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR1_REG) #define I2C1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR1_REG) #define I2C2_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR1_REG) #define I2C4_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR1_REG) @@ -106,7 +107,14 @@ #define SAE_SEL(val) STM32_CLOCK(val, 1, 11, CCIPR2_REG) #define RNG_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR2_REG) #define SDMMC_SEL(val) STM32_CLOCK(val, 1, 14, CCIPR2_REG) +#define DSIHOST_SEL(val) STM32_CLOCK(val, 1, 15, CCIPR2_REG) +#define USART6_SEL(val) STM32_CLOCK(val, 1, 16, CCIPR2_REG) +#define LTDC_SEL(val) STM32_CLOCK(val, 1, 18, CCIPR2_REG) #define OCTOSPI_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR2_REG) +#define HSPI_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR2_REG) +#define I2C5_SEL(val) STM32_CLOCK(val, 3, 24, CCIPR2_REG) +#define I2C6_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR2_REG) +#define USBPHYC_SEL(val) STM32_CLOCK(val, 3, 30, CCIPR2_REG) /** CCIPR3 devices */ #define LPUART1_SEL(val) STM32_CLOCK(val, 7, 0, CCIPR3_REG) #define SPI3_SEL(val) STM32_CLOCK(val, 3, 3, CCIPR3_REG) @@ -118,5 +126,10 @@ #define ADF1_SEL(val) STM32_CLOCK(val, 7, 16, CCIPR3_REG) /** BDCR devices */ #define RTC_SEL(val) STM32_CLOCK(val, 3, 8, BDCR_REG) +/** + * Dummy: Add a specifier when no selection is possible, value may not occur + * in used RCC regs + */ +#define NO_SEL 0xFF #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32U5_CLOCK_H_ */ From aeb1e8ed3407509e2de251dc54052e9a43e9123a Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Wed, 8 Nov 2023 10:42:39 +0100 Subject: [PATCH 3969/4498] dts: arm: st: add STM32U5A9 support add STM32U5A9XJ device trees. Also add ADC2 & ADC1_2 dual mode nodes Signed-off-by: Abderrahmane Jarmouni --- dts/arm/st/u5/stm32u595.dtsi | 38 ++++++++++++++++++++++++++++++++++ dts/arm/st/u5/stm32u5a9.dtsi | 13 ++++++++++++ dts/arm/st/u5/stm32u5a9Xj.dtsi | 28 +++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 dts/arm/st/u5/stm32u5a9.dtsi create mode 100644 dts/arm/st/u5/stm32u5a9Xj.dtsi diff --git a/dts/arm/st/u5/stm32u595.dtsi b/dts/arm/st/u5/stm32u595.dtsi index 401aa5ace79..db489205f95 100644 --- a/dts/arm/st/u5/stm32u595.dtsi +++ b/dts/arm/st/u5/stm32u595.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 PSICONTROl nv + * Copyright (c) 2023 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,5 +59,42 @@ interrupt-names = "event", "error"; status = "disabled"; }; + + /* Available in STM32U59x/5Ax/5Fx/5Gx SoCs */ + adc2: adc@42028100 { + compatible = "st,stm32-adc"; + reg = <0x42028100 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00000400>; + interrupts = <37 0>; + status = "disabled"; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <5 6 12 20 36 68 391 814>; + st,adc-clock-source = ; + st,adc-sequencer = ; + }; + + /* + * Available in STM32U59x/5Ax/5Fx/5Gx SoCs + * dual mode: adc1 and adc2 coupled + */ + adc1_2: adc@42028300 { + compatible = "st,stm32-adc"; + reg = <0x42028300 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00000400>; + interrupts = <37 0>; + status = "disabled"; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <5 6 12 20 36 68 391 814>; + st,adc-clock-source = ; + st,adc-sequencer = ; + }; }; }; diff --git a/dts/arm/st/u5/stm32u5a9.dtsi b/dts/arm/st/u5/stm32u5a9.dtsi new file mode 100644 index 00000000000..13cd1e1401d --- /dev/null +++ b/dts/arm/st/u5/stm32u5a9.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32u5a9", "st,stm32u5", "simple-bus"; + }; +}; diff --git a/dts/arm/st/u5/stm32u5a9Xj.dtsi b/dts/arm/st/u5/stm32u5a9Xj.dtsi new file mode 100644 index 00000000000..1b9b7cadd75 --- /dev/null +++ b/dts/arm/st/u5/stm32u5a9Xj.dtsi @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + /* SRAM1 + SRAM2 + SRAM3 + SRAM5 */ + /* 768K + 64K + 832K + 832K */ + reg = <0x20000000 DT_SIZE_K(2496)>; + }; + sram1: memory@28000000 { + /* SRAM4, low-power background autonomous mode */ + reg = <0x28000000 DT_SIZE_K(16)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(4)>; + }; + }; + }; +}; From 2df99b10c5cd27618b81cf2bdf9bab44fcd62628 Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Wed, 8 Nov 2023 13:17:05 +0100 Subject: [PATCH 3970/4498] boards: arm: stm32u5a9j-dk: Add initial support Add initial support of STM32U5A9J-DK discovery kit Signed-off-by: Abderrahmane Jarmouni --- boards/arm/stm32u5a9j_dk/Kconfig.board | 8 + boards/arm/stm32u5a9j_dk/Kconfig.defconfig | 11 + boards/arm/stm32u5a9j_dk/board.cmake | 7 + .../arm/stm32u5a9j_dk/doc/img/bottom_view.jpg | Bin 0 -> 79341 bytes boards/arm/stm32u5a9j_dk/doc/img/top_view.jpg | Bin 0 -> 77907 bytes boards/arm/stm32u5a9j_dk/doc/index.rst | 186 +++++++++++ boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.dts | 299 ++++++++++++++++++ boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.yaml | 23 ++ .../arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig | 28 ++ 9 files changed, 562 insertions(+) create mode 100644 boards/arm/stm32u5a9j_dk/Kconfig.board create mode 100644 boards/arm/stm32u5a9j_dk/Kconfig.defconfig create mode 100644 boards/arm/stm32u5a9j_dk/board.cmake create mode 100644 boards/arm/stm32u5a9j_dk/doc/img/bottom_view.jpg create mode 100644 boards/arm/stm32u5a9j_dk/doc/img/top_view.jpg create mode 100644 boards/arm/stm32u5a9j_dk/doc/index.rst create mode 100644 boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.dts create mode 100644 boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.yaml create mode 100644 boards/arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig diff --git a/boards/arm/stm32u5a9j_dk/Kconfig.board b/boards/arm/stm32u5a9j_dk/Kconfig.board new file mode 100644 index 00000000000..8482aa58f04 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/Kconfig.board @@ -0,0 +1,8 @@ +# STM32U5A9J Discovery Kit board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32U5A9J_DK + bool "STM32U5A9J Discovery Kit Development Board" + depends on SOC_STM32U5A9XX diff --git a/boards/arm/stm32u5a9j_dk/Kconfig.defconfig b/boards/arm/stm32u5a9j_dk/Kconfig.defconfig new file mode 100644 index 00000000000..8124e022740 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/Kconfig.defconfig @@ -0,0 +1,11 @@ +# STM32U5A9J DISCOVERY KIT board configuration + +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_STM32U5A9J_DK + +config BOARD + default "stm32u5a9j_dk" + +endif # BOARD_STM32U5A9J_DK diff --git a/boards/arm/stm32u5a9j_dk/board.cmake b/boards/arm/stm32u5a9j_dk/board.cmake new file mode 100644 index 00000000000..597c0c8b676 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +# FIXME: openocd runner not yet available. diff --git a/boards/arm/stm32u5a9j_dk/doc/img/bottom_view.jpg b/boards/arm/stm32u5a9j_dk/doc/img/bottom_view.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d1c1dca173bbc36d5c47bc8ae9edf80baec8e74 GIT binary patch literal 79341 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⪼Qe`oP^T`VFHsg z5na>=3v;9ql+TKB+^x&il<_5Ue}SO9Ei^d13z2Q`=tGYB5Pfx%svz~KA%>u>nMwiP~P5&-k-8q z;j$(_KQpQH@^37od8EToUgOaAQY0j8+jod*fNgM!G!hPAUTwJi*1iL9S|wlcdPJ7R zUP6GI3;8z}a#slTs_^Ej@Rl;cJ=;JY-X2OVN|9@y zH_BddG^MMkJJ0g~!}XtH8S@b%&l%=)y|DURWubdeqzrDP_$FTFd87n}XzG?Nl4xaX zU*+cNa;<}08W3R^xzOuiJbIR@lQBU?Ai-Ofmv(z};B0s`g|15%fs|aQ&Us@Hy0ly= zTq?h(?6EMyV>)T>W@J@xnRZBK`cVR_&mw9+GnZiVWjtP%M8@V2B|#9)PM}rV{z+my zNP$6MZ%W~~u|LvX{4yyVwOS*Lsh`l&QOg3W8uxo<3?Uz^x4M2x{1(HXy#!6z1hbpfQv#a1K^_YPjB{N^UoEn z;~=3zSDms19(r)7_~*c+0{y}HfH?U01sQncaf}&w1!{#>M`&}`h{N*aD5ML5ShEKr z9V6>O_)p5)=oiCjnQ%s}cv#<#DWac=ul8Gc-eapAeQsP}djX+Myzqid|!TFS+wu zV`m)$lU}Co_x6Z#e;|Unv?X#D!*Wr+Y>8Ev#r2K<3nu=?6A$(j@MYqJ}ZZtd@E}%TUc`g+-bD=GEb?~61rQI?d()n++^FvI| zov%fe=_h%t1}P93S~+z2fnQ1Yk3JtE+^=gzQIQDB7$~5a# zGPG>yBvnv6zw7%E^)=2FR8yQt_q1Lw_p6ZN)d*f`@z&hH?uzmz zIAWiXA|E)AHo>klTZk&@Y&_Dz+!IMD`q`-$SP3)D$LdN zWYXeM4ig;<+(=!rclLXLFHGI4m_UUiF*&Ml1lO~w`_@Q`6?@OYaMQY*Wpdy&QC1`n ze&bv)y83b!3kwG;;78pAom7@##W zAs2ec+>C-IM_o>+rPI}@SS45co6MR!v0kfO(Sdq=vAv_;(8=hq9idhFpZgO^^FA#( z2;+zLO&qDTHrmmWH_6Q;v3sv{7{~ih)bx<5A3d8Fq2)4|`Vt-q8=NqH_PSksUO&^> z#FsYrLRpm(kHys;%V!VuvFvVqqXI*BTYn{u>0p{L`9}sFTvs}`khzp-s*>goW03fi z!lr73^o&8b%XK7ps5Lg=4W5(f)5n@_g3cZqS4MnC6L#R6@V9e4tVHL@(EfKVa{D@w z+Ty+&yBb~*lLiSMLk)O;=ynA8fZFK4oyvd7t7Ln{MF(0N4B5HK3FT@745H3w27ge! zH~;#pv@$#h#DoJK|8H0i>2Gc=mLvhwE)4>R4b%vZU+r}#}7uooay3xV%eB?Kt}1gfT~^#;Tn<1`aU&} zc>0-Mb3OcYVaThBP00eMnXaE+MQPA;ib!r(&GbIl3`Z2`#%7N-r(HjT$ z59mT6VBuea(t=Usr9`Yv*R%-%SkFG=Z|Z-j5wzhbtLHH3`_P3~3Lf98hnKvrqaz7B zNj|R~UErItJYSyMiRB@$;bB6-&#kZewwctuWF&%8lJn*9Qo|+G5SJjUTZqWpz3<15 z$vkZ9hPhS6la;)KLqUgNW5npozELtC_`QYR9F$&^rXwxZY2+~?-y4zcFmWJ=OWcZ* z*um;HxT_(?Cf85FZ0%{^9w)zv?H z53j)tq@L-}YWC}M$Mu;dS(&>Ds~eH>`_cT_t0jxPb&gd3YHXkLL4R z>&utjYUgID!VfPb{)-<9dIFXebQi#e?!xEP!--!LnJ$J%`0BC)zV-yH?BTh;DGAa@ zr^%`MArb3^bxIK{$_9o>6O{Vk3qk`K<}nR-wZ(h0)$)Gn&lEZVZtOO)O=BlSz2(poEtP&J<~cD&Ip`m_MHMSB z+GsJoW^a1)b94{;_%>n6gv(CMb9j1pVX%n= z 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 literal 0 HcmV?d00001 diff --git a/boards/arm/stm32u5a9j_dk/doc/index.rst b/boards/arm/stm32u5a9j_dk/doc/index.rst new file mode 100644 index 00000000000..166dc21676e --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/doc/index.rst @@ -0,0 +1,186 @@ +.. _stm32u5a9j_dk_board: + +ST STM32U5A9J Discovery Kit +########################### + +Overview +******** + +The STM32U5A9J-DK Discovery kit is a complete demonstration and development +platform for the STM32U5A9NJH6Q microcontroller, featuring an Arm® Cortex®-M33 +core with Arm® TrustZone®. + +Leveraging the innovative ultra-low-power oriented features, 2.5 Mbytes of +embedded SRAM, 4 Mbytes of embedded flash memory, and rich graphics features, +the STM32U5A9J-DK Discovery kit enables users to easily prototype applications +with state-of-the-art energy efficiency, as well as providing stunning and +optimized graphics rendering with the support of the 2.5D NeoChrom Accelerator, +Chrom-ART Accelerator, and Chrom-GRC™ MMU. + +The full range of hardware features available on the board helps users to +enhance their application development by an evaluation of all the peripherals +such as a 2.47-inch RGB 480x480 pixels TFT round LCD module with MIPI DSI® +interface and capacitive touch panel, USB Type-C® HS, Octo-SPI flash memory +device, Hexadeca-SPI PSRAM memory device, eMMC flash memory device, +Time-of-Flight and gesture detection sensor, temperature sensor, and two 2.54 mm +pitch double-row flexible expansion connectors for easy prototyping with +daughterboards for specific applications (USART, LPUART, two SPIs, SAI, three +I2C, SDMMC, ADCs, timers, and GPIOs). + +The STM32U5A9J-DK Discovery kit integrates an STLINK-V3E embedded in-circuit +debugger and programmer for the STM32 microcontroller with a USB Virtual COM +port bridge and comes with the STM32CubeU5 MCU Package, which provides an STM32 +comprehensive software HAL library as well as various software examples. + +.. image:: img/top_view.jpg + :align: center + :alt: STM32U5A9J-DK Top View + +.. image:: img/bottom_view.jpg + :align: center + :alt: STM32U5A9J-DK Bottom View + +More information about the board can be found at the `STM32U5A9J-DK website`_. +More information about STM32U5A9NJH6Q can be found here: + +- `STM32U5A9NJ on www.st.com`_ +- `STM32U5 Series reference manual`_ +- `STM32U5Axxx datasheet`_ + +Supported Features +================== + +The current Zephyr stm32u5a9j_dk board configuration supports the following +hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| LPUART | on-chip | low power uart | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| SDMMC | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ + +Other hardware features have not been enabled yet for this board. + +The default configuration per core can be found in the defconfig file: +``boards/arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig`` + +Pin Mapping +=========== + +For mode details please refer to `STM32U5A9J-DK board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- USART_1 TX/RX : PA9/PA10 (ST-Link Virtual Port Com) +- LD3 : PE0 +- LD4 : PE1 +- User Button: PC13 +- USART_3 TX/RX : PB10/PB11 +- LPUART_1 TX/RX : PG7/PG8 +- I2C1 SCL/SDA : PG14/PG13 +- I2C2 SCL/SDA : PF1/PF0 +- I2C6 SCL/SDA : PD1/PD0 +- SPI2 SCK/MISO/MOSI/CS : PB13/PD3/PD4/PB12 +- SPI3 SCK/MISO/MOSI/CS : PG9/PG10/PG11/PG15 +- ADC1 : channel5 PA0, channel14 PC5 +- ADC2 : channel9 PA4 +- ADC4 : channel5 PF14 + +System Clock +============ + +The STM32U5A9J-DK Discovery kit relies on an HSE oscillator (16 MHz crystal) +and an LSE oscillator (32.768 kHz crystal) as clock references. +Using the HSE (instead of HSI) is mandatory to manage the DSI interface for +the LCD module and the USB high‑speed interface. + +Serial Port +=========== + +The STM32U5A9J Discovery kit has up to 4 USARTs, 2 UARTs, and 1 LPUART. +The Zephyr console output is assigned to USART1 which connected to the onboard +ST-LINK/V3.0. Virtual COM port interface. Default communication settings are +115200 8N1. + + +Programming +*********** + +STM32U5A9J Discovery kit includes an ST-LINK/V3 embedded debug tool interface. +This probe allows to flash the board using various tools. + +Flashing +======== + +Board is configured to be flashed using west STM32CubeProgrammer runner. +Installation of `STM32CubeProgrammer`_ is then required to flash the board., + +Connect the STM32U5A9J Discovery board to your host computer using the USB +port, then run a serial host program to connect with your Discovery +board. For example: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 -b 115200 + +Then, build and flash in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32u5a9j_dk + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! stm32u5a9j_dk + + +.. _STM32U5A9J-DK website: + https://www.st.com/en/evaluation-tools/stm32u5a9j-dk.html + +.. _STM32U5A9J-DK board User Manual: + https://www.st.com/resource/en/user_manual/um2967-discovery-kit-with-stm32u5a9nj-mcu-stmicroelectronics.pdf + +.. _STM32U5A9NJ on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32u5a9nj.html + +.. _STM32U5 Series reference manual: + https://www.st.com/resource/en/reference_manual/rm0456-stm32u5-series-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32U5Axxx datasheet: + https://www.st.com/resource/en/datasheet/stm32u5a9nj.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _STM32U5A9J_DK board schematics: + https://www.st.com/resource/en/schematic_pack/mb1829-u5a9njq-b01-schematic.pdf diff --git a/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.dts b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.dts new file mode 100644 index 00000000000..f236354c6f2 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.dts @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "STMicroelectronics STM32U5A9J DISCOVERY KIT board"; + compatible = "st,stm32u5a9j-dk"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + green_led_0: led_3 { + gpios = <&gpioe 0 GPIO_ACTIVE_HIGH>; + label = "User LD3"; + }; + red_led_0: led_4 { + gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>; + label = "User LD4"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button_0 { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + dsi_lcd_qsh_030: connector_dsi_lcd { + compatible = "st,dsi-lcd-qsh-030"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <4 0 &gpioe 8 0>, /* TOUCH_INT */ + <22 0 &gpiod 8 0>, /* SPI chip SEL */ + <24 0 &gpiob 13 0>, /* SPI CLK */ + <26 0 &gpiod 4 0>, /* SPI MOSI */ + <28 0 &gpiod 11 0>, /* SPI DCX */ + <35 0 &gpioe 5 0>, /* SCLK/MCLK */ + <37 0 &gpioe 4 0>, /* LRCLK */ + <40 0 &gpioh 4 0>, /* I2C5_SDA */ + <43 0 &gpioi 7 0>, /* SWIRE */ + <44 0 &gpioh 5 0>, /* I2C5_SCL */ + <49 0 &gpiof 11 0>, /* DSI_TE */ + <53 0 &gpioi 6 0>, /* LCD_BL_CTRL */ + <57 0 &gpiod 5 0>; /* DSI_RESET */ + }; + + aliases { + led0 = &green_led_0; + led1 = &red_led_0; + sw0 = &user_button; + sdhc0 = &sdmmc1; + watchdog0 = &iwdg; + die-temp0 = &die_temp; + volt-sensor0 = &vref1; + volt-sensor1 = &vbat4; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&clk_msis { + status = "okay"; + msi-range = <4>; /* 4MHz (reset value) */ + msi-pll-mode; +}; + +&pll1 { + div-m = <1>; + mul-n = <80>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_msis>; + status = "okay"; +}; + +&rcc { + clocks = <&pll1>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +uart0: &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; + pinctrl-names = "default"; + current-speed = <9600>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pg14 &i2c1_sda_pg13>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pf1 &i2c2_sda_pf0>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&i2c6 { + pinctrl-0 = <&i2c6_scl_pd1 &i2c6_sda_pd0>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pd3 &spi2_mosi_pd4>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + status = "okay"; +}; + +&spi3 { + pinctrl-0 = <&spi3_sck_pg9 &spi3_miso_pg10 &spi3_mosi_pg11>; + pinctrl-names = "default"; + cs-gpios = <&gpiog 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + status = "okay"; +}; + +&timers1 { + st,prescaler = <1>; + status = "okay"; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch2_pe11>; + pinctrl-names = "default"; + }; +}; + +&timers2 { + st,prescaler = <1>; + status = "okay"; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch4_pa3>; + pinctrl-names = "default"; + }; +}; + +&sdmmc1 { + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_d4_pb8 &sdmmc1_d5_pb9 + &sdmmc1_d6_pc6 &sdmmc1_d7_pc7 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sdmmc2 { + pinctrl-0 = <&sdmmc2_d0_pb14 &sdmmc2_d1_pb15 + &sdmmc2_d2_pb3 &sdmmc2_d3_pb4 + &sdmmc2_ck_pd6 &sdmmc2_cmd_pd7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in5_pa0 &adc1_in14_pc5>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <1>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@5 { + reg = <0x5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@e { + reg = <0xe>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; +}; + +&adc4 { + pinctrl-0 = <&adc4_in5_pf14>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <1>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@5 { + reg = <0x5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Following flash partition is dedicated to the use of bootloader + */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(1952)>; + }; + slot1_partition: partition@1f8000 { + label = "image-1"; + reg = <0x001f8000 DT_SIZE_K(1960)>; + }; + storage_partition: partition@3e2000 { + label = "storage"; + reg = <0x003e2000 DT_SIZE_K(120)>; + }; + }; +}; + +&iwdg { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vref1 { + status = "okay"; +}; + +&vbat4 { + status = "okay"; +}; diff --git a/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.yaml b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.yaml new file mode 100644 index 00000000000..82ada8651e9 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk.yaml @@ -0,0 +1,23 @@ +identifier: stm32u5a9j_dk +name: ST STM32U5A9J-DK Discovery Kit +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - led + - button + - adc + - uart + - usart + - lpuart + - watchdog + - spi + - i2c + - flash + - sdmmc +ram: 2496 +flash: 4096 +vendor: st diff --git a/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig new file mode 100644 index 00000000000..71e92cf0450 --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/stm32u5a9j_dk_defconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# Set SoC present on the board +CONFIG_SOC_SERIES_STM32U5X=y +CONFIG_SOC_STM32U5A9XX=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable serial +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable clocks +CONFIG_CLOCK_CONTROL=y + +# Enable pinctrl +CONFIG_PINCTRL=y From ebf67b2cef9157c5d02d3b0ca387f7e1b9f9d884 Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Wed, 8 Nov 2023 15:02:50 +0100 Subject: [PATCH 3971/4498] test: drivers: adc_api: add overlay for STM32U5A9J Add overlay for STM32U5A9J board to pass test in CI Signed-off-by: Abderrahmane Jarmouni --- .../drivers/adc/adc_api/boards/stm32u5a9j_dk.overlay | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/stm32u5a9j_dk.overlay diff --git a/tests/drivers/adc/adc_api/boards/stm32u5a9j_dk.overlay b/tests/drivers/adc/adc_api/boards/stm32u5a9j_dk.overlay new file mode 100644 index 00000000000..83335cd9aa4 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/stm32u5a9j_dk.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 5>; + }; +}; From 053c6b29cc8589120eda54f78f7beff5f966c91a Mon Sep 17 00:00:00 2001 From: Abderrahmane Jarmouni Date: Fri, 10 Nov 2023 18:00:47 +0100 Subject: [PATCH 3972/4498] boards: arm: stm32u5a9j-dk: add OpenOCD support Add support for debugging with OpenOCD and GDB Signed-off-by: Abderrahmane Jarmouni --- boards/arm/stm32u5a9j_dk/board.cmake | 6 ++- boards/arm/stm32u5a9j_dk/doc/index.rst | 18 ++++++-- boards/arm/stm32u5a9j_dk/support/openocd.cfg | 46 ++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 boards/arm/stm32u5a9j_dk/support/openocd.cfg diff --git a/boards/arm/stm32u5a9j_dk/board.cmake b/boards/arm/stm32u5a9j_dk/board.cmake index 597c0c8b676..dadc06c643e 100644 --- a/boards/arm/stm32u5a9j_dk/board.cmake +++ b/boards/arm/stm32u5a9j_dk/board.cmake @@ -3,5 +3,9 @@ board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(openocd "--tcl-port=6666") +board_runner_args(openocd --cmd-pre-init "gdb_report_data_abort enable") +board_runner_args(openocd "--no-halt") + include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) -# FIXME: openocd runner not yet available. +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/stm32u5a9j_dk/doc/index.rst b/boards/arm/stm32u5a9j_dk/doc/index.rst index 166dc21676e..6e3e44c5942 100644 --- a/boards/arm/stm32u5a9j_dk/doc/index.rst +++ b/boards/arm/stm32u5a9j_dk/doc/index.rst @@ -129,11 +129,11 @@ ST-LINK/V3.0. Virtual COM port interface. Default communication settings are 115200 8N1. -Programming -*********** +Programming and Debugging +************************* STM32U5A9J Discovery kit includes an ST-LINK/V3 embedded debug tool interface. -This probe allows to flash the board using various tools. +This probe allows to flash and debug the board using various tools. Flashing ======== @@ -163,6 +163,18 @@ You should see the following message on the console: Hello World! stm32u5a9j_dk +Debugging +========= + +Default debugger for this board is openocd. It could be used in the usual way +with "west debug" command. +Here is an example for the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: stm32u5a9j_dk + :goals: debug + .. _STM32U5A9J-DK website: https://www.st.com/en/evaluation-tools/stm32u5a9j-dk.html diff --git a/boards/arm/stm32u5a9j_dk/support/openocd.cfg b/boards/arm/stm32u5a9j_dk/support/openocd.cfg new file mode 100644 index 00000000000..23e2409440f --- /dev/null +++ b/boards/arm/stm32u5a9j_dk/support/openocd.cfg @@ -0,0 +1,46 @@ +source [find interface/stlink-dap.cfg] + +set WORKAREASIZE 0x8000 + +transport select "dapdirect_swd" + +set CHIPNAME STM32U5A9NJHxQ +set BOARDNAME STM32U5A9J_DK + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# STlink Debug clock frequency +set CLOCK_FREQ 8000 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +reset_config srst_only srst_nogate connect_assert_srst +set CONNECT_UNDER_RESET 1 +set CORE_RESET 0 + +# ACCESS PORT NUMBER +set AP_NUM 0 +# GDB PORT +set GDB_PORT 3333 + +# BCTM CPU variables + +source [find target/stm32u5x.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +gdb_memory_map disable From 43ef398614a765f04271680bbc46511bfbc71dba Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 7 Nov 2023 08:49:45 +0100 Subject: [PATCH 3973/4498] pm: add power management for stm32f4x Add soc power management for the STM32F4x chips. One low power state is added supported by all chips from the family - the Stop mode with voltage regulator in low-power mode. The Stop mode for STM32F chips has to work with the IDLE timer - CORTEX_M_SYSTICK_IDLE_TIMER, because PLL and HSI are disabled in the Stop mode (Systick is not clocked). The only possible wakeup source is RTC, which works as a IDLE timer for the Systick. The exit latency may need to be adjusted per system, depending on the system tick frequency and other variables. Signed-off-by: Dawid Niedzwiecki --- dts/arm/st/f4/stm32f4.dtsi | 18 +++- soc/arm/st_stm32/stm32f4/CMakeLists.txt | 4 + .../st_stm32/stm32f4/Kconfig.defconfig.series | 4 + soc/arm/st_stm32/stm32f4/Kconfig.series | 1 + soc/arm/st_stm32/stm32f4/power.c | 89 +++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 soc/arm/st_stm32/stm32f4/power.c diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index 36cbd9c8fed..f53c9cdf228 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -28,10 +28,26 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-m4f"; reg = <0>; + cpu-power-states = <&stop>; + }; + + power-states { + stop: stop { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + /* It is really hard to establish these numbers precisely. + * We are basing on RTC as a wakeup source with 62,5us tick. + * It requires a proper margin. Additionally, sys_clock_announce + * works within system tick boundaries (100us by default), + * which also introduces some shift. + */ + min-residency-us = <400>; + exit-latency-us = <300>; + }; }; }; diff --git a/soc/arm/st_stm32/stm32f4/CMakeLists.txt b/soc/arm/st_stm32/stm32f4/CMakeLists.txt index e02052e3946..021708b9d02 100644 --- a/soc/arm/st_stm32/stm32f4/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32f4/CMakeLists.txt @@ -6,3 +6,7 @@ zephyr_sources( ) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + +zephyr_sources_ifdef(CONFIG_PM + power.c + ) diff --git a/soc/arm/st_stm32/stm32f4/Kconfig.defconfig.series b/soc/arm/st_stm32/stm32f4/Kconfig.defconfig.series index 14dea5bf4d2..28ed9cc3a55 100644 --- a/soc/arm/st_stm32/stm32f4/Kconfig.defconfig.series +++ b/soc/arm/st_stm32/stm32f4/Kconfig.defconfig.series @@ -17,4 +17,8 @@ config TASK_WDT_HW_FALLBACK_DELAY depends on TASK_WDT_HW_FALLBACK default 200 +config PM + select COUNTER + select COUNTER_RTC_STM32_SUBSECONDS + endif # SOC_SERIES_STM32F4X diff --git a/soc/arm/st_stm32/stm32f4/Kconfig.series b/soc/arm/st_stm32/stm32f4/Kconfig.series index 6b8fdf80c7b..a4e65c97784 100644 --- a/soc/arm/st_stm32/stm32f4/Kconfig.series +++ b/soc/arm/st_stm32/stm32f4/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_STM32F4X select HAS_STM32CUBE select CPU_HAS_ARM_MPU select HAS_SWO + select HAS_PM help Enable support for STM32F4 MCU series diff --git a/soc/arm/st_stm32/stm32f4/power.c b/soc/arm/st_stm32/stm32f4/power.c new file mode 100644 index 00000000000..02b645ee9f1 --- /dev/null +++ b/soc/arm/st_stm32/stm32f4/power.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +BUILD_ASSERT(DT_SAME_NODE(DT_CHOSEN(zephyr_cortex_m_idle_timer), DT_NODELABEL(rtc)), + "STM32Fx series needs RTC as an additional IDLE timer for power management"); + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + LL_LPM_DisableEventOnPend(); + LL_PWR_ClearFlag_WU(); + /* According to datasheet (DS11139 Rev 8,Table 38.), wakeup with regulator in + * low-power mode takes typically 8us, max 13us more time than with the main + * regulator. We are using RTC as a wakeup source, which has a tick 62,5us. + * It means we have to add significant margin to the exit-latency anyway, + * so it is worth always using the low-power regulator. + */ + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_LPREGU); + LL_LPM_EnableDeepSleep(); + + k_cpu_idle(); + + break; + default: + LOG_DBG("Unsupported power state %u", state); + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + LL_LPM_DisableSleepOnExit(); + LL_LPM_EnableSleep(); + + /* Restore the clock setup. */ + stm32_clock_control_init(NULL); + break; + default: + LOG_DBG("Unsupported power substate-id %u", state); + break; + } + + /* + * System is now in active mode. Reenable interrupts which were + * disabled when OS started idling code. + */ + irq_unlock(0); +} + +static int stm32_power_init(void) +{ + /* Enable Power clock. It should by done by default, but make sure to + * enable it for all STM32F4x chips. + */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); + + /* Enabling debug during STOP mode is done by the common STM32 configuration */ + return 0; +} + +SYS_INIT(stm32_power_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); From e6c7a4c968f143673ccb63236353bd3a319ace52 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Fri, 10 Nov 2023 15:43:55 +0100 Subject: [PATCH 3974/4498] tests: pm: add soc pm tests and sample for stm32f4x chip Add soc power management test and blinky sample for the nucleo_f429zi board. Signed-off-by: Dawid Niedzwiecki --- .../stm32/power_mgmt/blinky/boards/nucleo_f429zi.conf | 2 ++ .../power_mgmt/blinky/boards/nucleo_f429zi.overlay | 11 +++++++++++ samples/boards/stm32/power_mgmt/blinky/sample.yaml | 4 +++- .../pm/power_mgmt_soc/boards/nucleo_f429zi.overlay | 11 +++++++++++ tests/subsys/pm/power_mgmt_soc/testcase.yaml | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.conf create mode 100644 samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.overlay create mode 100644 tests/subsys/pm/power_mgmt_soc/boards/nucleo_f429zi.overlay diff --git a/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.conf b/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.conf new file mode 100644 index 00000000000..2035eb8c955 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.conf @@ -0,0 +1,2 @@ +# Increase IDLE stack for the IDLE timer +CONFIG_IDLE_STACK_SIZE=640 diff --git a/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.overlay b/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.overlay new file mode 100644 index 00000000000..859c69df414 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/blinky/boards/nucleo_f429zi.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,cortex-m-idle-timer = &rtc; + }; +}; diff --git a/samples/boards/stm32/power_mgmt/blinky/sample.yaml b/samples/boards/stm32/power_mgmt/blinky/sample.yaml index 103f204a189..04054268228 100644 --- a/samples/boards/stm32/power_mgmt/blinky/sample.yaml +++ b/samples/boards/stm32/power_mgmt/blinky/sample.yaml @@ -12,7 +12,9 @@ tests: - "Device ready" filter: dt_compat_enabled("zephyr,power-state") and dt_enabled_alias_with_parent_compat("led0", "gpio-leds") and - dt_compat_enabled("st,stm32-lptim") + (dt_compat_enabled("st,stm32-lptim") or + dt_chosen_enabled("zephyr,cortex-m-idle-timer")) extra_args: "CONFIG_DEBUG=y" integration_platforms: - nucleo_wb55rg + - nucleo_f429zi diff --git a/tests/subsys/pm/power_mgmt_soc/boards/nucleo_f429zi.overlay b/tests/subsys/pm/power_mgmt_soc/boards/nucleo_f429zi.overlay new file mode 100644 index 00000000000..859c69df414 --- /dev/null +++ b/tests/subsys/pm/power_mgmt_soc/boards/nucleo_f429zi.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,cortex-m-idle-timer = &rtc; + }; +}; diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 5d160d70b91..8fe974f0bfa 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -5,6 +5,7 @@ tests: - cc1352r1_launchxl - mec15xxevb_assy6853 - mec1501modular_assy6885 + - nucleo_f429zi - nucleo_wb55rg - nucleo_l476rg - twr_ke18f From 16fd744c13a99be705cd2aa90bb1e6c1c931a2e3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 14 Nov 2023 14:31:37 +0100 Subject: [PATCH 3975/4498] net: pkt: Add function for allocating buffers w/o preconditions Add new function to allocate additional buffers for net_pkt, w/o any additional preconditions/checks. Just allocate what was requested. Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 25 +++++++++++++++ subsys/net/ip/net_pkt.c | 61 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 4f67249f15b..c5878213a02 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -1707,6 +1707,13 @@ int net_pkt_alloc_buffer_debug(struct net_pkt *pkt, net_pkt_alloc_buffer_debug(_pkt, _size, _proto, _timeout, \ __func__, __LINE__) +int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size, + k_timeout_t timeout, + const char *caller, int line); +#define net_pkt_alloc_buffer_raw(_pkt, _size, _timeout) \ + net_pkt_alloc_buffer_raw_debug(_pkt, _size, _timeout, \ + __func__, __LINE__) + struct net_pkt *net_pkt_alloc_with_buffer_debug(struct net_if *iface, size_t size, sa_family_t family, @@ -1821,6 +1828,24 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt, k_timeout_t timeout); #endif +/** + * @brief Allocate buffer for a net_pkt, of specified size, w/o any additional + * preconditions + * + * @details: The actual buffer size may be larger than requested one if fixed + * size buffers are in use. + * + * @param pkt The network packet requiring buffer to be allocated. + * @param size The size of buffer being requested. + * @param timeout Maximum time to wait for an allocation. + * + * @return 0 on success, negative errno code otherwise. + */ +#if !defined(NET_PKT_DEBUG_ENABLED) +int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size, + k_timeout_t timeout); +#endif + /** * @brief Allocate a network packet and buffer at once * diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index ea60060abe5..38fc288d8f5 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1197,6 +1197,67 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt, return 0; } + +#if NET_LOG_LEVEL >= LOG_LEVEL_DBG +int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size, + k_timeout_t timeout, const char *caller, + int line) +#else +int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size, + k_timeout_t timeout) +#endif +{ + struct net_buf_pool *pool = NULL; + struct net_buf *buf; + + if (size == 0) { + return 0; + } + + if (k_is_in_isr()) { + timeout = K_NO_WAIT; + } + + NET_DBG("Data allocation size %zu", size); + + if (pkt->context) { + pool = get_data_pool(pkt->context); + } + + if (!pool) { + pool = pkt->slab == &tx_pkts ? &tx_bufs : &rx_bufs; + } + +#if NET_LOG_LEVEL >= LOG_LEVEL_DBG + buf = pkt_alloc_buffer(pool, size, timeout, caller, line); +#else + buf = pkt_alloc_buffer(pool, size, timeout); +#endif + + if (!buf) { +#if NET_LOG_LEVEL >= LOG_LEVEL_DBG + NET_ERR("Data buffer (%zd) allocation failed (%s:%d)", + size, caller, line); +#else + NET_ERR("Data buffer (%zd) allocation failed.", size); +#endif + return -ENOMEM; + } + + net_pkt_append_buffer(pkt, buf); + +#if IS_ENABLED(CONFIG_NET_BUF_FIXED_DATA_SIZE) + /* net_buf allocators shrink the buffer size to the requested size. + * We don't want this behavior here, so restore the real size of the + * last fragment. + */ + buf = net_buf_frag_last(buf); + buf->size = CONFIG_NET_BUF_DATA_SIZE; +#endif + + return 0; +} + #if NET_LOG_LEVEL >= LOG_LEVEL_DBG static struct net_pkt *pkt_alloc(struct k_mem_slab *slab, k_timeout_t timeout, const char *caller, int line) From 9976ebb24b0c169c70d63a1ea0c6458376e85694 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 14 Nov 2023 12:40:49 +0100 Subject: [PATCH 3976/4498] net: tcp: Rework data queueing API Rework how data is queued for the TCP connections: * net_context no longer allocates net_pkt for TCP connections. This was not only inefficient (net_context has no knowledge of the TX window size), but also error-prone in certain configuration (for example when IP fragmentation was enabled, net_context may attempt to allocate enormous packet, instead of let the data be fragmented for the TCP stream. * Instead, implement already defined `net_tcp_queue()` API, which takes raw buffer and length. This allows to take TX window into account and also better manage the allocated net_buf's (like for example avoid allocation if there's still room in the buffer). In result, the TCP stack will not only no longer exceed the TX window, but also prevent empty gaps in allocated net_buf's, which should lead to less out-of-mem issues with the stack. * As net_pkt-based `net_tcp_queue_data()` is no longer in use, it was removed. Signed-off-by: Robert Lubos --- subsys/net/ip/net_context.c | 27 +++--- subsys/net/ip/tcp.c | 166 +++++++++++++++++++++-------------- subsys/net/ip/tcp.h | 15 +--- subsys/net/ip/tcp_internal.h | 20 +++-- 4 files changed, 132 insertions(+), 96 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 9cdcaadc822..a628297f650 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1726,7 +1726,7 @@ static int context_sendto(struct net_context *context, { const struct msghdr *msghdr = NULL; struct net_if *iface; - struct net_pkt *pkt; + struct net_pkt *pkt = NULL; size_t tmp_len; int ret; @@ -1948,6 +1948,15 @@ static int context_sendto(struct net_context *context, return -ENETDOWN; } + context->send_cb = cb; + context->user_data = user_data; + + if (IS_ENABLED(CONFIG_NET_TCP) && + net_context_get_proto(context) == IPPROTO_TCP && + !net_if_is_ip_offloaded(net_context_get_iface(context))) { + goto skip_alloc; + } + pkt = context_alloc_pkt(context, len, PKT_WAIT_TIME); if (!pkt) { NET_ERR("Failed to allocate net_pkt"); @@ -1966,9 +1975,6 @@ static int context_sendto(struct net_context *context, len = tmp_len; } - context->send_cb = cb; - context->user_data = user_data; - if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { uint8_t priority; @@ -1990,6 +1996,7 @@ static int context_sendto(struct net_context *context, } } +skip_alloc: if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(net_context_get_iface(context))) { ret = context_write_data(pkt, buf, len, msghdr); @@ -2021,16 +2028,12 @@ static int context_sendto(struct net_context *context, } else if (IS_ENABLED(CONFIG_NET_TCP) && net_context_get_proto(context) == IPPROTO_TCP) { - ret = context_write_data(pkt, buf, len, msghdr); + ret = net_tcp_queue(context, buf, len, msghdr); if (ret < 0) { goto fail; } - net_pkt_cursor_init(pkt); - ret = net_tcp_queue_data(context, pkt); - if (ret < 0) { - goto fail; - } + len = ret; ret = net_tcp_send_data(context, cb, user_data); } else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && @@ -2086,7 +2089,9 @@ static int context_sendto(struct net_context *context, return len; fail: - net_pkt_unref(pkt); + if (pkt != NULL) { + net_pkt_unref(pkt); + } return ret; } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 82faa777694..2d0f753ca91 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1347,6 +1347,49 @@ static int tcp_pkt_peek(struct net_pkt *to, struct net_pkt *from, size_t pos, return net_pkt_copy(to, from, len); } +static int tcp_pkt_append(struct net_pkt *pkt, const uint8_t *data, size_t len) +{ + size_t alloc_len = len; + struct net_buf *buf = NULL; + int ret = 0; + + if (pkt->buffer) { + buf = net_buf_frag_last(pkt->buffer); + + if (len > net_buf_tailroom(buf)) { + alloc_len -= net_buf_tailroom(buf); + } else { + alloc_len = 0; + } + } + + if (alloc_len > 0) { + ret = net_pkt_alloc_buffer_raw(pkt, alloc_len, + TCP_PKT_ALLOC_TIMEOUT); + if (ret < 0) { + return -ENOBUFS; + } + } + + if (buf == NULL) { + buf = pkt->buffer; + } + + while (buf != NULL && len > 0) { + size_t write_len = MIN(len, net_buf_tailroom(buf)); + + net_buf_add_mem(buf, data, write_len); + + data += write_len; + len -= write_len; + buf = buf->frags; + } + + NET_ASSERT(len == 0, "Not all bytes written"); + + return ret; +} + static bool tcp_window_full(struct tcp *conn) { bool window_full = (conn->send_data_total >= conn->send_win); @@ -3229,13 +3272,12 @@ int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta) return ret; } -/* net_context queues the outgoing data for the TCP connection */ -int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt) +int net_tcp_queue(struct net_context *context, const void *data, size_t len, + const struct msghdr *msg) { struct tcp *conn = context->tcp; - struct net_buf *orig_buf = NULL; + size_t queued_len = 0; int ret = 0; - size_t len; if (!conn || conn->state != TCP_ESTABLISHED) { return -ENOTCONN; @@ -3252,72 +3294,69 @@ int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt) goto out; } - len = net_pkt_get_len(pkt); + if (msg) { + len = 0; - if (conn->send_data->buffer) { - orig_buf = net_buf_frag_last(conn->send_data->buffer); + for (int i = 0; i < msg->msg_iovlen; i++) { + len += msg->msg_iov[i].iov_len; + } } - net_pkt_append_buffer(conn->send_data, pkt->buffer); - conn->send_data_total += len; - NET_DBG("conn: %p Queued %zu bytes (total %zu)", conn, len, - conn->send_data_total); - pkt->buffer = NULL; + /* Queue no more than TX window permits. It's guaranteed at this point + * that conn->send_data_total is less than conn->send_win, as it was + * verified in tcp_window_full() check above. As the connection mutex + * is held, their values shall not change since. + */ + len = MIN(conn->send_win - conn->send_data_total, len); + + if (msg) { + for (int i = 0; i < msg->msg_iovlen; i++) { + int iovlen = MIN(msg->msg_iov[i].iov_len, len); + + ret = tcp_pkt_append(conn->send_data, + msg->msg_iov[i].iov_base, + iovlen); + if (ret < 0) { + if (queued_len == 0) { + goto out; + } else { + break; + } + } + queued_len += iovlen; + len -= iovlen; + + if (len == 0) { + break; + } + } + } else { + ret = tcp_pkt_append(conn->send_data, data, len); + if (ret < 0) { + goto out; + } + + queued_len = len; + } + + conn->send_data_total += queued_len; + + /* Successfully queued data for transmission. Even if there's a transmit + * failure now (out-of-buf case), it can be ignored for now, retransmit + * timer will take care of queued data retransmission. + */ ret = tcp_send_queued_data(conn); if (ret < 0 && ret != -ENOBUFS) { tcp_conn_close(conn, ret); goto out; } - if ((ret == -ENOBUFS) && - (conn->send_data_total < (conn->unacked_len + len))) { - /* Some of the data has been sent, we cannot remove the - * whole chunk, the remainder portion is already - * in the send_data and will be transmitted upon a - * received ack or the next send call - * - * Set the return code back to 0 to pretend we just - * transmitted the chunk - */ - ret = 0; + if (tcp_window_full(conn)) { + (void)k_sem_take(&conn->tx_sem, K_NO_WAIT); } - if (ret == -ENOBUFS) { - /* Restore the original data so that we do not resend the pkt - * data multiple times. - */ - conn->send_data_total -= len; - - if (orig_buf) { - pkt->buffer = orig_buf->frags; - orig_buf->frags = NULL; - } else { - pkt->buffer = conn->send_data->buffer; - conn->send_data->buffer = NULL; - } - - /* If we have out-of-bufs case, and the send_data buffer has - * become empty, till the retransmit timer, as there is no - * data to retransmit. - * The socket layer will catch this and resend data if needed. - * Only perform this when it is just the newly added packet, - * otherwise it can disrupt any pending transmission - */ - if (conn->send_data_total == 0) { - NET_DBG("No bufs, cancelling retransmit timer"); - k_work_cancel_delayable(&conn->send_data_timer); - } - } else { - if (tcp_window_full(conn)) { - (void)k_sem_take(&conn->tx_sem, K_NO_WAIT); - } - - /* We should not free the pkt if there was an error. It will be - * freed in net_context.c:context_sendto() - */ - tcp_pkt_unref(pkt); - } + ret = queued_len; out: k_mutex_unlock(&conn->lock); @@ -3674,7 +3713,9 @@ static size_t tp_tcp_recv_cb(struct tcp *conn, struct net_pkt *pkt) net_pkt_pull(up, net_pkt_get_len(up) - len); - net_tcp_queue_data(conn->context, up); + for (struct net_buf *buf = pkt->buffer; buf != NULL; buf = buf->frags) { + net_tcp_queue(conn->context, buf->data, buf->len); + } return len; } @@ -3817,12 +3858,7 @@ enum net_verdict tp_input(struct net_conn *net_conn, responded = true; NET_DBG("tcp_send(\"%s\")", tp->data); { - struct net_pkt *data_pkt; - - data_pkt = tcp_pkt_alloc(conn, len); - net_pkt_write(data_pkt, buf, len); - net_pkt_cursor_init(data_pkt); - net_tcp_queue_data(conn->context, data_pkt); + net_tcp_queue(conn->context, buf, len); } } break; diff --git a/subsys/net/ip/tcp.h b/subsys/net/ip/tcp.h index 77d5c5634a6..975f2a97624 100644 --- a/subsys/net/ip/tcp.h +++ b/subsys/net/ip/tcp.h @@ -31,6 +31,7 @@ extern "C" { #endif +#include #include /** @@ -72,18 +73,7 @@ int net_tcp_listen(struct net_context *context); */ int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb, void *user_data); -/** - * @brief Enqueue data for transmission - * - * @param context Network context - * @param buf Pointer to the data - * @param len Number of bytes - * @param msghdr Data for a vector array operation - * - * @return 0 if ok, < 0 if error - */ -int net_tcp_queue(struct net_context *context, const void *buf, size_t len, - const struct msghdr *msghdr); + /* TODO: split into 2 functions, conn -> context, queue -> send? */ /* The following functions are provided solely for the compatibility @@ -112,7 +102,6 @@ void net_tcp_init(void); #define net_tcp_init(...) #endif int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta); -int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt); int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum); #if defined(CONFIG_NET_TEST_PROTOCOL) diff --git a/subsys/net/ip/tcp_internal.h b/subsys/net/ip/tcp_internal.h index 49edae13f68..1dd3f235532 100644 --- a/subsys/net/ip/tcp_internal.h +++ b/subsys/net/ip/tcp_internal.h @@ -283,21 +283,27 @@ struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt, #endif /** - * @brief Enqueue a single packet for transmission + * @brief Enqueue data for transmission * - * @param context TCP context - * @param pkt Packet + * @param context Network context + * @param data Pointer to the data + * @param len Number of bytes + * @param msg Data for a vector array operation * * @return 0 if ok, < 0 if error */ #if defined(CONFIG_NET_NATIVE_TCP) -int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt); +int net_tcp_queue(struct net_context *context, const void *data, size_t len, + const struct msghdr *msg); #else -static inline int net_tcp_queue_data(struct net_context *context, - struct net_pkt *pkt) +static inline int net_tcp_queue(struct net_context *context, const void *data, + size_t len, const struct msghdr *msg) { ARG_UNUSED(context); - ARG_UNUSED(pkt); + ARG_UNUSED(data); + ARG_UNUSED(len); + ARG_UNUSED(msg); + return -EPROTONOSUPPORT; } #endif From 3a38ec1aaac77224f826a44150cde7118660a49f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 15 Nov 2023 16:32:22 +0100 Subject: [PATCH 3977/4498] net: tcp: Feed TX semaphore on connection close Otherwise, if the application was for example blocked on poll() pending POLLOUT, it won't be notified. Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 2d0f753ca91..6ffd688a20f 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -638,6 +638,8 @@ static int tcp_conn_close(struct tcp *conn, int status) status, conn->recv_user_data); } + k_sem_give(&conn->tx_sem); + return tcp_conn_unref(conn); } From e6d90b409bba74c198c82db5f3882f5e996c7dcc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 15 Nov 2023 16:33:24 +0100 Subject: [PATCH 3978/4498] net: sockets: tls: Set errno on TX waiting error In case underlying socket reported error while waiting for TX, the errno value was not set accordingly. This commit fixes this. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 14b1de26af3..c83d2c18b80 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2230,10 +2230,9 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, timeout_ms = timeout_to_ms(&timeout); ret = wait_for_reason(ctx->sock, timeout_ms, ret); if (ret != 0) { - /* Retry. */ + errno = -ret; break; } - } else { (void)tls_mbedtls_reset(ctx); errno = EIO; From aa6f698d310c37c97d29ec33b7c9730a0c880039 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 15 Nov 2023 17:49:00 +0100 Subject: [PATCH 3979/4498] net: zperf: Fix TCP packet counting Make sure we send the entire packet buffer before bumping the packet counter, send() does not guarantee that all of the requested data will be sent at once with STREAM socket. Signed-off-by: Robert Lubos --- subsys/net/lib/zperf/zperf_tcp_uploader.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/zperf/zperf_tcp_uploader.c b/subsys/net/lib/zperf/zperf_tcp_uploader.c index 3e72f81e54b..5fcc0530c5c 100644 --- a/subsys/net/lib/zperf/zperf_tcp_uploader.c +++ b/subsys/net/lib/zperf/zperf_tcp_uploader.c @@ -20,6 +20,22 @@ static char sample_packet[PACKET_SIZE_MAX]; static struct zperf_async_upload_context tcp_async_upload_ctx; +static ssize_t sendall(int sock, const void *buf, size_t len) +{ + while (len) { + ssize_t out_len = zsock_send(sock, buf, len, 0); + + if (out_len < 0) { + return out_len; + } + + buf = (const char *)buf + out_len; + len -= out_len; + } + + return 0; +} + static int tcp_upload(int sock, unsigned int duration_in_ms, unsigned int packet_size, @@ -50,7 +66,7 @@ static int tcp_upload(int sock, do { /* Send the packet */ - ret = zsock_send(sock, sample_packet, packet_size, 0); + ret = sendall(sock, sample_packet, packet_size); if (ret < 0) { if (nb_errors == 0 && ret != -ENOMEM) { NET_ERR("Failed to send the packet (%d)", errno); From 7c72d4a2d6335ba0a37babfba34abad363b0932d Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 16 Nov 2023 15:03:17 -0600 Subject: [PATCH 3980/4498] net: Fix CMakeLists Fix the CMakeLists of the tls_credentials and sockets folders to link/interface to the net library instead of the zephyr library. This fixes issues where some files are not found in the link interface when compiling the sources in this folder. Signed-off-by: Declan Snyder --- subsys/net/lib/sockets/CMakeLists.txt | 28 +++++++++---------- subsys/net/lib/tls_credentials/CMakeLists.txt | 10 ++++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 2a87ef1c449..7ffd6dc476b 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -5,37 +5,37 @@ zephyr_syscall_header( ${ZEPHYR_BASE}/include/zephyr/net/socket_select.h ) -zephyr_include_directories(.) +zephyr_library_include_directories(.) -zephyr_sources( +zephyr_library_sources( getaddrinfo.c sockets.c sockets_select.c ) if(NOT CONFIG_NET_SOCKETS_OFFLOAD) -zephyr_sources( +zephyr_library_sources( getnameinfo.c sockets_misc.c ) endif() -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_CAN sockets_can.c) -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_PACKET sockets_packet.c) -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c) -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c) -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER socket_dispatcher.c) -zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OBJ_CORE socket_obj_core.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_CAN sockets_can.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_PACKET sockets_packet.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER socket_dispatcher.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OBJ_CORE socket_obj_core.c) if(CONFIG_NET_SOCKETS_NET_MGMT) - zephyr_sources(sockets_net_mgmt.c) - zephyr_include_directories(${ZEPHYR_BASE}/subsys/net/ip) + zephyr_library_sources(sockets_net_mgmt.c) + zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) endif() if(CONFIG_SOCKS) - zephyr_include_directories(${ZEPHYR_BASE}/subsys/net/lib/socks) + zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/lib/socks) endif() -zephyr_sources_ifdef(CONFIG_NET_SOCKETPAIR socketpair.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETPAIR socketpair.c) -zephyr_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) +zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/subsys/net/lib/tls_credentials/CMakeLists.txt b/subsys/net/lib/tls_credentials/CMakeLists.txt index 8acb4a5f4f1..490a558953d 100644 --- a/subsys/net/lib/tls_credentials/CMakeLists.txt +++ b/subsys/net/lib/tls_credentials/CMakeLists.txt @@ -1,15 +1,17 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(.) +zephyr_library_include_directories(.) -zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_VOLATILE +zephyr_library_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_VOLATILE tls_credentials.c tls_credentials_digest_raw.c ) -zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE +zephyr_library_sources_ifdef(CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE tls_credentials_trusted.c tls_credentials_digest_raw.c ) -zephyr_sources_ifdef(CONFIG_TLS_CREDENTIALS_SHELL +zephyr_library_sources_ifdef(CONFIG_TLS_CREDENTIALS_SHELL tls_credentials_shell.c ) + +zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) From cf42b8b2fbda3bdade4aabada9d4ebbdd91813c9 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 17 Nov 2023 09:58:05 -0600 Subject: [PATCH 3981/4498] net: sockets: fix shadowing warning Fix compiler local variable shadowing warning Rename ret to bytes_sent in offending funciton Signed-off-by: Declan Snyder --- subsys/net/lib/sockets/sockets.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index b10b9136272..d35317352c9 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -847,13 +847,13 @@ ssize_t zsock_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, ssize_t z_impl_zsock_sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { - int ret; + int bytes_sent; - ret = VTABLE_CALL(sendto, sock, buf, len, flags, dest_addr, addrlen); + bytes_sent = VTABLE_CALL(sendto, sock, buf, len, flags, dest_addr, addrlen); - sock_obj_core_update_send_stats(sock, ret); + sock_obj_core_update_send_stats(sock, bytes_sent); - return ret; + return bytes_sent; } #ifdef CONFIG_USERSPACE @@ -932,13 +932,13 @@ ssize_t zsock_sendmsg_ctx(struct net_context *ctx, const struct msghdr *msg, ssize_t z_impl_zsock_sendmsg(int sock, const struct msghdr *msg, int flags) { - int ret; + int bytes_sent; - ret = VTABLE_CALL(sendmsg, sock, msg, flags); + bytes_sent = VTABLE_CALL(sendmsg, sock, msg, flags); - sock_obj_core_update_send_stats(sock, ret); + sock_obj_core_update_send_stats(sock, bytes_sent); - return ret; + return bytes_sent; } #ifdef CONFIG_USERSPACE @@ -1498,13 +1498,13 @@ ssize_t zsock_recvfrom_ctx(struct net_context *ctx, void *buf, size_t max_len, ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { - int ret; + int bytes_received; - ret = VTABLE_CALL(recvfrom, sock, buf, max_len, flags, src_addr, addrlen); + bytes_received = VTABLE_CALL(recvfrom, sock, buf, max_len, flags, src_addr, addrlen); - sock_obj_core_update_recv_stats(sock, ret); + sock_obj_core_update_recv_stats(sock, bytes_received); - return ret; + return bytes_received; } #ifdef CONFIG_USERSPACE From bc8b5b3813d0836e93af076a7f8ae31d0758de0d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 20 Nov 2023 13:36:27 +0200 Subject: [PATCH 3982/4498] mgmt: updatehub: Fix CMakeLists.txt file Fix the CMakeLists of the updatehub to link with mbedtls. Signed-off-by: Jukka Rissanen --- subsys/mgmt/updatehub/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/mgmt/updatehub/CMakeLists.txt b/subsys/mgmt/updatehub/CMakeLists.txt index b71f17fab1b..067e6168d97 100644 --- a/subsys/mgmt/updatehub/CMakeLists.txt +++ b/subsys/mgmt/updatehub/CMakeLists.txt @@ -23,3 +23,5 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE updatehub_handlers.c) zephyr_include_directories( ${ZEPHYR_BASE}/subsys/mgmt/updatehub/include ) + +zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) From f70e4c0f6803724d9fc5205fc77daa5a61ce0f0a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 20 Nov 2023 13:46:00 +0200 Subject: [PATCH 3983/4498] drivers: modem: Fix include paths Set the include paths properly and unconditionally to needed networking directories. Signed-off-by: Jukka Rissanen --- drivers/modem/CMakeLists.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/modem/CMakeLists.txt b/drivers/modem/CMakeLists.txt index 96a10be34fb..a97568dfc65 100644 --- a/drivers/modem/CMakeLists.txt +++ b/drivers/modem/CMakeLists.txt @@ -12,33 +12,30 @@ zephyr_library_sources_ifdef(CONFIG_MODEM_IFACE_UART_ASYNC modem_iface_uart_asyn zephyr_library_sources_ifdef(CONFIG_MODEM_CMD_HANDLER modem_cmd_handler.c) zephyr_library_sources_ifdef(CONFIG_MODEM_SOCKET modem_socket.c) +zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) +zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/lib/sockets) + if(CONFIG_MODEM_UBLOX_SARA) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(ublox-sara-r4.c) endif() if(CONFIG_MODEM_QUECTEL_BG9X) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(quectel-bg9x.c) endif() if(CONFIG_MODEM_WNCM14A2A) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(wncm14a2a.c) endif() if(CONFIG_MODEM_GSM_PPP) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(gsm_ppp.c) endif() if (CONFIG_MODEM_HL7800) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(hl7800.c) endif() if (CONFIG_MODEM_SIM7080) - zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) zephyr_library_sources(simcom-sim7080.c) endif() From 4cc80097d3c2c90aa0e58164df024b5a62eeb887 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Mon, 20 Nov 2023 10:06:14 -0600 Subject: [PATCH 3984/4498] drivers: wifi: include sockets headers Some wifi drivers need internal sockets headers included to build, put this in CMakeLists Signed-off-by: Declan Snyder --- drivers/wifi/eswifi/CMakeLists.txt | 1 + drivers/wifi/simplelink/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/wifi/eswifi/CMakeLists.txt b/drivers/wifi/eswifi/CMakeLists.txt index 7b324a27b13..9b3dae623af 100644 --- a/drivers/wifi/eswifi/CMakeLists.txt +++ b/drivers/wifi/eswifi/CMakeLists.txt @@ -5,6 +5,7 @@ if(CONFIG_WIFI_ESWIFI) zephyr_library_include_directories( # IP headers ${ZEPHYR_BASE}/subsys/net/ip + ${ZEPHYR_BASE}/subsys/net/lib/sockets ) zephyr_library_sources( diff --git a/drivers/wifi/simplelink/CMakeLists.txt b/drivers/wifi/simplelink/CMakeLists.txt index 8e9a24b7c82..3dbe2a2807f 100644 --- a/drivers/wifi/simplelink/CMakeLists.txt +++ b/drivers/wifi/simplelink/CMakeLists.txt @@ -3,6 +3,7 @@ if(CONFIG_WIFI_SIMPLELINK) zephyr_library_include_directories( ${ZEPHYR_BASE}/subsys/net/lib/tls_credentials + ${ZEPHYR_BASE}/subsys/net/lib/sockets ) zephyr_library_sources( simplelink_support.c From 81c5727f27701e52c6d7934b2f1fdae74668dc76 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Sun, 19 Nov 2023 17:18:50 +0100 Subject: [PATCH 3985/4498] drivers: wifi: airoc: drop default shell and sysworkq stack sizes Those configuration settings should never be part of driver Kconfig file. Drop them, since they can easily result in Kconfig symbol circular dependency error. Signed-off-by: Marcin Niestroj --- drivers/wifi/infineon/Kconfig.airoc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc index 993fbdad212..a3eac53862d 100644 --- a/drivers/wifi/infineon/Kconfig.airoc +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -17,14 +17,6 @@ menuconfig WIFI_AIROC if WIFI_AIROC -if SHELL -config SHELL_STACK_SIZE - default 4096 -endif # SHELL - -config SYSTEM_WORKQUEUE_STACK_SIZE - default 4096 - config AIROC_WIFI_EVENT_TASK_STACK_SIZE int "Event Task Stack Size" default 4096 From 84d588e01327ca0c20135a129c87863e74baab21 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 11 Oct 2023 22:33:01 +0100 Subject: [PATCH 3986/4498] boards: arm: add support for WeAct STM32G431 Core Add support for the WeAct Studio STM32G431 Core Board. Tested with: - `samples/basic/blinky` - `samples/basic/button` Flashed samples using dfu-util. Signed-off-by: Andreas Sandberg --- boards/arm/weact_stm32g431_core/Kconfig.board | 9 + .../weact_stm32g431_core/Kconfig.defconfig | 12 ++ boards/arm/weact_stm32g431_core/board.cmake | 11 ++ boards/arm/weact_stm32g431_core/doc/index.rst | 147 ++++++++++++++ .../weact_stm32g431_core/support/openocd.cfg | 7 + .../weact_stm32g431_core.dts | 186 ++++++++++++++++++ .../weact_stm32g431_core.yaml | 20 ++ .../weact_stm32g431_core_defconfig | 24 +++ 8 files changed, 416 insertions(+) create mode 100644 boards/arm/weact_stm32g431_core/Kconfig.board create mode 100644 boards/arm/weact_stm32g431_core/Kconfig.defconfig create mode 100644 boards/arm/weact_stm32g431_core/board.cmake create mode 100644 boards/arm/weact_stm32g431_core/doc/index.rst create mode 100644 boards/arm/weact_stm32g431_core/support/openocd.cfg create mode 100644 boards/arm/weact_stm32g431_core/weact_stm32g431_core.dts create mode 100644 boards/arm/weact_stm32g431_core/weact_stm32g431_core.yaml create mode 100644 boards/arm/weact_stm32g431_core/weact_stm32g431_core_defconfig diff --git a/boards/arm/weact_stm32g431_core/Kconfig.board b/boards/arm/weact_stm32g431_core/Kconfig.board new file mode 100644 index 00000000000..9886fd64702 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/Kconfig.board @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023 Andreas Sandberg +# +# SPDX-License-Identifier: Apache-2.0 +# + +config BOARD_WEACT_STM32G431_CORE + bool "WeAct Studio STM32G431 Core Board" + depends on SOC_STM32G431XX diff --git a/boards/arm/weact_stm32g431_core/Kconfig.defconfig b/boards/arm/weact_stm32g431_core/Kconfig.defconfig new file mode 100644 index 00000000000..25d65455013 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/Kconfig.defconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2023 Andreas Sandberg +# +# SPDX-License-Identifier: Apache-2.0 +# + +if BOARD_WEACT_STM32G431_CORE + +config BOARD + default "weact_stm32g431_core" + +endif diff --git a/boards/arm/weact_stm32g431_core/board.cmake b/boards/arm/weact_stm32g431_core/board.cmake new file mode 100644 index 00000000000..5ef1ab31d07 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Andreas Sandberg +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/arm/weact_stm32g431_core/doc/index.rst b/boards/arm/weact_stm32g431_core/doc/index.rst new file mode 100644 index 00000000000..2d367ba2808 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/doc/index.rst @@ -0,0 +1,147 @@ +.. _weact_stm32g431_core: + +WeAct Studio STM32G431 Core Board +################################# + +The WeAct STM32G431 Core Board is a low-cost bare-bones STM32G431-based development +board. See the `STM32G431CB website`_ for more information about the MCU. More information +about the board, including schematics, is available from the `WeAct GitHub`_. + +Modifications USB-C Power Delivery +********************************** + +The board does not support USB-C PD in its standard configuration. To enable USB-C PD, CC1 +and CC2 need to be disconnected from their pull-down resistors and be connected to PB6 and +PB4 respectively. Dead battery support requires PA9 and PA10 to be routed to CC1 and +CC2. VBUS also needs to be connected to the MCU through a voltage divider. + +The pull-downs are disconnected by removing the zero-Ohm resistors on SB8 and SB9 next to +the USB-C connector. SB3, SB5, SB6, and SB7 then need to be closed to connect the CCx +lines to the MCU. The voltage divider is connected to PB2 by closing SB4. + +After these modifications have been made, PA9, PA10, PB2, PB4, and PB6 should be +considered reserved for USB-C and not available for other applications. + +.. warning:: + The internal USB DFU boot loader may not work correctly with machines that respect USB + PD signaling unless dead battery support has been enabled. A USB-C to USB-A adapter or + programming using the SWD port can be used as a workaround. + + +Supported Features +================== + +The Zephyr weact_stm32g431_core board configuration supports the following hardware +features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| ADC | on-chip | ADC Controller | ++------------+------------+-------------------------------------+ +| USB | on-chip | USB device | ++------------+------------+-------------------------------------+ +| UCPD | on-chip | ucpd | ++------------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/weact_stm32g431_core/weact_stm32g431_core_defconfig`` + +Pin Mapping +=========== + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_2 TX/RX : PA2/PA3 +- UCPD1 CCx : PB6/PB4 (not connected by default) +- UCPD1 DBCCx : PA9/PA10 (not connected by default) +- BUTTON (User) : PC13 +- BUTTON (BOOT0) : PB8 +- LED0 : PC6 +- ADC (VBUS) : PB2 + +The ADC is disabled by default since the VBUS voltage divider is not connected in the +board's standard configuration. + + +Hardware Configuration +---------------------- ++---------------+---------+-----------------------------------------------+ +| Solder bridge | Default | Description | ++===============+=========+===============================================+ +| SB1/SB2 | Open | Route PC14/PC15 (LSE) to header | ++---------------+---------+-----------------------------------------------+ +| SB6/SB7 | Open | Connect PB4/PB6 (UCPD1_CCx) to USB-C CCx pins | ++---------------+---------+-----------------------------------------------+ +| SB3/SB5 | Open | Connect PA9/PA10 (UCPD1_DBCCx) to to PB6/PB4 | ++---------------+---------+-----------------------------------------------+ +| SB4 | Open | Connect PB2 to VBUS voltage divider | ++---------------+---------+-----------------------------------------------+ +| SB8/SB9 | Closed | Connect USB-CCx to pull-down resistors | ++---------------+---------+-----------------------------------------------+ +| SB10 | Open | VBUS protection diode bypass | ++---------------+---------+-----------------------------------------------+ + + +Clock Sources +------------- + +The board has two external oscillators. The frequency of the slow clock (LSE) is 32.768 +kHz. The frequency of the main clock (HSE) is 8 MHz. + +The default configuration sources the system clock from the PLL, which is derived from +HSE, and is set at 144 MHz. The 48 MHz clock used by the USB interface is derived from the +PLL instead of the internal 48 MHz oscillator. + +Programming and Debugging +************************* + +The MCU is normally programmed using the ROM bootloader or the exposed SWD port. + +Please note that some laptops may not detect the ROM bootloader correctly if the CCx +pull-downs have been disconnected by opening SB8 and SB9 unless dead battery support has +been enabled by closing SB3 and SB5. A USB-C to USB-A adapter can be used as a workaround +if this is a problem. + +Flashing an Application +======================= + +Connect a USB-C cable and the board should power ON. Force the board into DFU mode by +keeping the BOOT0 switch pressed while pressing and releasing the NRST switch. + +The dfu-util runner is supported on this board and so a sample can be built and tested +easily. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: weact_stm32g431_core + :goals: build flash + +Debugging +========= + +The board can be debugged by installing the included 100 mil (0.1 inch) header, and +attaching an SWD debugger to the 3V3 (3.3V), GND, SCK, and DIO pins on that header. + + +References +********** + +.. target-notes:: + +.. _WeAct GitHub: + https://github.com/WeActStudio/WeActStudio.STM32G431CoreBoard + +.. _STM32G431CB website: + https://www.st.com/en/microcontrollers-microprocessors/stm32g431cb.html + +.. _STM32F401x reference manual: + https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/arm/weact_stm32g431_core/support/openocd.cfg b/boards/arm/weact_stm32g431_core/support/openocd.cfg new file mode 100644 index 00000000000..d936f7d3534 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/support/openocd.cfg @@ -0,0 +1,7 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32g4x.cfg] + +reset_config srst_only diff --git a/boards/arm/weact_stm32g431_core/weact_stm32g431_core.dts b/boards/arm/weact_stm32g431_core/weact_stm32g431_core.dts new file mode 100644 index 00000000000..cdfe959b3fd --- /dev/null +++ b/boards/arm/weact_stm32g431_core/weact_stm32g431_core.dts @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2023 Andreas Sandberg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include + +/ { + model = "WeAct Studio STM32G431 Core Board"; + compatible = "weact,stm32g431-core"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &led_0; + mcuboot-button0 = &button_0; + mcuboot-led0 = &led_0; + sw0 = &button_0; + sw1 = &button_1; + usbc-port0 = &usbc1; + watchdog0 = &iwdg; + }; + + leds { + compatible = "gpio-leds"; + led_0: led0 { + gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; + label = "Status LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + button_0: button0 { + label = "User"; + gpios = <&gpioc 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + zephyr,code = ; + }; + button_1: button1 { + label = "Boot0"; + gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + vbus1: vbus { + compatible = "zephyr,usb-c-vbus-adc"; + status = "disabled"; + io-channels = <&adc2 12>; + output-ohms = <10000>; + full-ohms = <(100000 + 10000)>; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + usbc1: usbc-port@1 { + compatible = "usb-c-connector"; + status = "disabled"; + reg = <1>; + tcpc = <&ucpd1>; + vbus = <&vbus1>; + data-role = "device"; + power-role = "sink"; + sink-pdos = ; + }; + }; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&pll { + status = "okay"; + div-m = <2>; + mul-n = <72>; + div-p = <2>; + div-q = <6>; + div-r = <2>; + clocks = <&clk_hse>; +}; + +&rtc { + status = "okay"; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; +}; + +&lptim1 { + status = "okay"; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 4KiB of storage at the end of the 128KiB FLASH */ + storage_partition: partition@1f000 { + label = "storage"; + reg = <0x0001f000 DT_SIZE_K(4)>; + }; + }; +}; + +&iwdg { + status = "okay"; +}; + +&usart2 { + status = "okay"; + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + + current-speed = <115200>; +}; + +&adc2 { + pinctrl-0 = <&adc2_in12_pb2>; + pinctrl-names = "default"; + st,adc-clock-source = ; + st,adc-prescaler = <4>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@c { + reg = <12>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + zephyr,vref-mv = <3300>; + }; +}; + +&ucpd1 { + psc-ucpdclk = <1>; + hbitclkdiv = <27>; + pinctrl-0 = <&ucpd1_cc1_pb6 &ucpd1_cc2_pb4>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + pinctrl-names = "default"; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00800000>, + <&rcc STM32_SRC_PLL_Q CLK48_SEL(2)>; + status = "okay"; +}; diff --git a/boards/arm/weact_stm32g431_core/weact_stm32g431_core.yaml b/boards/arm/weact_stm32g431_core/weact_stm32g431_core.yaml new file mode 100644 index 00000000000..91886ad0ea5 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/weact_stm32g431_core.yaml @@ -0,0 +1,20 @@ +identifier: weact_stm32g431_core +name: WeAct Studio STM32G431 Core Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 32 +flash: 128 +supported: + - counter + - gpio + - nvs + - pinctrl + - tcpc + - uart + - usb_device + - watchdog +vendor: weact diff --git a/boards/arm/weact_stm32g431_core/weact_stm32g431_core_defconfig b/boards/arm/weact_stm32g431_core/weact_stm32g431_core_defconfig new file mode 100644 index 00000000000..aa9e67db821 --- /dev/null +++ b/boards/arm/weact_stm32g431_core/weact_stm32g431_core_defconfig @@ -0,0 +1,24 @@ +# +# Copyright (c) 2023 Andreas Sandberg +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_STM32G4X=y +CONFIG_SOC_STM32G431XX=y + +CONFIG_CLOCK_CONTROL=y +CONFIG_PINCTRL=y + +# LSE defined as LPTIM clock source by the DTS +CONFIG_STM32_LPTIM_CLOCK_LSE=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_GPIO=y + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y From b544855ba595b27db28b965d282623de086d52a9 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 11 Oct 2023 22:39:39 +0100 Subject: [PATCH 3987/4498] samples: usb-c: sink: Add support for WeAct STM32G431 core Add support for the WeAct Studio STM32G431 Core board. Note that this board does not support USB-C PD in its default configuration. See the board documentation for the necessary hardware reconfiguration. Signed-off-by: Andreas Sandberg --- .../sink/boards/weact_stm32g431_core.overlay | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 samples/subsys/usb_c/sink/boards/weact_stm32g431_core.overlay diff --git a/samples/subsys/usb_c/sink/boards/weact_stm32g431_core.overlay b/samples/subsys/usb_c/sink/boards/weact_stm32g431_core.overlay new file mode 100644 index 00000000000..1b951a5ef77 --- /dev/null +++ b/samples/subsys/usb_c/sink/boards/weact_stm32g431_core.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Andreas Sandberg + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +&adc2 { + status = "okay"; +}; + +&vbus1 { + status = "okay"; +}; + +&usbc1 { + status = "okay"; +}; + +&clk_hsi { + /* The HSI is used by ucpd1 */ + status = "okay"; +}; + +&ucpd1 { + status = "okay"; + dead-battery; +}; From 3467a25fff805b2f8c4e295f71b7e8ce4b25ad9f Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 16 Nov 2023 14:29:55 +0100 Subject: [PATCH 3988/4498] tfm: Change SFN and FP_HARDABI dependency TF-M only suports floating point in IPC model, not the SFN model. Since floating point is a basic feature of the architecture and TF-M has the limitation it makes more sense for the dependency to exist in TF-M and and limit the TF-M model choice instead of limiting the option to enable floating point. Signed-off-by: Joakim Andersson --- arch/arm/core/Kconfig | 1 - modules/trusted-firmware-m/Kconfig.tfm | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index 524bd86ff4c..75a64ea90eb 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -271,7 +271,6 @@ config FP_HARDABI # TF-M build system does not build the NS app and libraries correctly with Hard ABI. # This limitation should be removed in the next TF-M synchronization. depends on !TFM_BUILD_NS - depends on !(BUILD_WITH_TFM && !TFM_IPC) help This option selects the Floating point ABI in which hardware floating point instructions are generated and uses FPU-specific calling diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index d29b7093de0..b635347b6e1 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -324,6 +324,7 @@ config TFM_IPC config TFM_SFN bool "SFN model" + depends on !FP_HARDABI help Use the SFN Model as the SPM backend for the PSA API. The SFN model supports the SFN Partition model, and isolation level 1. From 32c3173fabae92217739743bf6098f0e5c4d86df Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 20 Nov 2023 14:38:25 +0100 Subject: [PATCH 3989/4498] tests: mcuboot: Enable mcuboot shell command Some shell modules were disabled in one of previous commits. Tests in this folder requires mcuboot shell command. Enable it with CONFIG_MCUBOOT_SHELL. Signed-off-by: Grzegorz Chwierut --- tests/boot/with_mcumgr/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/boot/with_mcumgr/prj.conf b/tests/boot/with_mcumgr/prj.conf index 5d09b05144a..3ddf7a4a45d 100644 --- a/tests/boot/with_mcumgr/prj.conf +++ b/tests/boot/with_mcumgr/prj.conf @@ -9,6 +9,7 @@ CONFIG_FLASH_MAP=y # Enable the shell MCUmgr transport. CONFIG_BASE64=y CONFIG_SHELL=y +CONFIG_MCUBOOT_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_MCUMGR_TRANSPORT_SHELL=y From 934a09550dd17406426ac92aac89761cbe506520 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Mon, 20 Nov 2023 14:05:19 +0100 Subject: [PATCH 3990/4498] samples: Bluetooth: Make broadcaster_multiple run on other controllers `CONFIG_BT_CTLR_ADV_DATA_CHAIN` is a Zephyr Controller exclusive. Use the max length instead to decide if we should add more data. The motivation for the change is that tests/bsim/bluetooth/host/adv/chain does not pass with Nordic's Softdevice Controller because of this. Signed-off-by: Jonathan Rico --- .../bluetooth/broadcaster_multiple/src/broadcaster_multiple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c index 30fe35d3dec..d4ce51c4f25 100644 --- a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c +++ b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c @@ -56,7 +56,7 @@ static uint8_t mfg_data[BT_MFG_DATA_LEN] = { 0xFF, 0xFF, }; static const struct bt_data ad[] = { BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), -#if defined(CONFIG_BT_CTLR_ADV_DATA_CHAIN) +#if CONFIG_BT_CTLR_ADV_DATA_LEN_MAX > 255 BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), #endif }; From 23cf38934c0f68861e403b22bc3dd0ce6efbfa39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 20 Nov 2023 16:15:42 +0100 Subject: [PATCH 3991/4498] manifest: Update hal_nordic revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull in a fix in the watchdog driver initialization. Signed-off-by: Andrzej Głąbek --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 20c01f42637..14847109194 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 2ff8ce6e6ca131d87699dba260f3c0cc4a6cc365 + revision: 56e0b052dff311c2f8eb08c6804e60fc79feb56f path: modules/hal/nordic groups: - hal From 2cdab8eaaa0c16157babb37661655103740af2a2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:12 +0000 Subject: [PATCH 3992/4498] Revert "[nrf fromlist] wifi: shell: Add a shell command to list stations" This reverts commit 3dab922e5d0561d37823058b0fa5fad18376cb33. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/Kconfig | 8 --- subsys/net/l2/wifi/wifi_shell.c | 90 --------------------------------- 2 files changed, 98 deletions(-) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 2816be56d74..134448aa57f 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -64,14 +64,6 @@ config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL There are approximately 100 channels allocated across the three supported bands. The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. -config WIFI_SHELL_MAX_AP_STA - int "Maximum number of APs and STAs that can be managed in Wi-Fi shell" - range 1 5 - default 1 - help - This option defines the maximum number of APs and STAs that can be managed - in Wi-Fi shell. - config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 1ee94304781..045fbed197e 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -24,7 +24,6 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include -#include #include "net_private.h" @@ -65,13 +64,6 @@ static uint32_t scan_result; static struct net_mgmt_event_callback wifi_shell_mgmt_cb; -static K_MUTEX_DEFINE(wifi_ap_sta_list_lock); -struct wifi_ap_sta_node { - bool valid; - struct wifi_ap_sta_info sta_info; -}; -static struct wifi_ap_sta_node sta_list[CONFIG_WIFI_SHELL_MAX_AP_STA]; - #define print(sh, level, fmt, ...) \ do { \ if (sh) { \ @@ -336,10 +328,6 @@ static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) } else { print(context.sh, SHELL_NORMAL, "AP disabled\n"); } - - k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); - memset(&sta_list, 0, sizeof(sta_list)); - k_mutex_unlock(&wifi_ap_sta_list_lock); } static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) @@ -347,25 +335,10 @@ static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) const struct wifi_ap_sta_info *sta_info = (const struct wifi_ap_sta_info *)cb->info; uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - int i; print(context.sh, SHELL_NORMAL, "Station connected: %s\n", net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf))); - - k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); - for (i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { - if (!sta_list[i].valid) { - sta_list[i].sta_info = *sta_info; - sta_list[i].valid = true; - break; - } - } - if (i == CONFIG_WIFI_SHELL_MAX_AP_STA) { - print(context.sh, SHELL_WARNING, "No space to store station info: " - "Increase CONFIG_WIFI_SHELL_MAX_AP_STA\n"); - } - k_mutex_unlock(&wifi_ap_sta_list_lock); } static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) @@ -377,20 +350,6 @@ static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) print(context.sh, SHELL_NORMAL, "Station disconnected: %s\n", net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf))); - - k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); - for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { - if (!sta_list[i].valid) { - continue; - } - - if (!memcmp(sta_list[i].sta_info.mac, sta_info->mac, - WIFI_MAC_ADDR_LEN)) { - sta_list[i].valid = false; - break; - } - } - k_mutex_unlock(&wifi_ap_sta_list_lock); } static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, @@ -1210,8 +1169,6 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, context.sh = sh; - k_mutex_init(&wifi_ap_sta_list_lock); - ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, iface, &cnx_params, sizeof(struct wifi_connect_req_params)); if (ret) { @@ -1240,49 +1197,6 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, return 0; } -static int cmd_wifi_ap_stations(const struct shell *sh, size_t argc, - char *argv[]) -{ - size_t id = 1; - - ARG_UNUSED(argv); - ARG_UNUSED(argc); - - shell_fprintf(sh, SHELL_NORMAL, "AP stations:\n"); - shell_fprintf(sh, SHELL_NORMAL, "============\n"); - - k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); - for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { - struct wifi_ap_sta_info *sta; - uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - - if (!sta_list[i].valid) { - continue; - } - - sta = &sta_list[i].sta_info; - - shell_fprintf(sh, SHELL_NORMAL, "Station %zu:\n", id++); - shell_fprintf(sh, SHELL_NORMAL, "==========\n"); - shell_fprintf(sh, SHELL_NORMAL, "MAC: %s\n", - net_sprint_ll_addr_buf(sta->mac, - WIFI_MAC_ADDR_LEN, - mac_string_buf, - sizeof(mac_string_buf))); - shell_fprintf(sh, SHELL_NORMAL, "Link mode: %s\n", - wifi_link_mode_txt(sta->link_mode)); - shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", - sta->twt_capable ? "Supported" : "Not supported"); - } - - if (id == 1) { - shell_fprintf(sh, SHELL_NORMAL, "No stations connected\n"); - } - k_mutex_unlock(&wifi_ap_sta_list_lock); - - return 0; -} - static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) @@ -1761,10 +1675,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, ": 0:Disable, 1:Optional, 2:Required.\n", cmd_wifi_ap_enable, 2, 4), - SHELL_CMD_ARG(stations, NULL, - "List stations connected to the AP", - cmd_wifi_ap_stations, - 1, 0), SHELL_SUBCMD_SET_END ); From e646f905a074b7c85ff5078f523ef7f81cd3cb8c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:12 +0000 Subject: [PATCH 3993/4498] Revert "[nrf fromlist] wifi: ap: Add client side events" This reverts commit 81038eb0200a36600381bfd7120c9105111b9cb0. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 38 --------------------------------- subsys/net/l2/wifi/wifi_mgmt.c | 16 -------------- subsys/net/l2/wifi/wifi_shell.c | 32 +-------------------------- 3 files changed, 1 insertion(+), 85 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8f1b145e233..1423cb2817f 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -184,10 +184,6 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT, /** AP mode disable result */ NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, - /** STA connected to AP */ - NET_EVENT_WIFI_CMD_AP_STA_CONNECTED, - /** STA disconnected from AP */ - NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -223,12 +219,6 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_AP_DISABLE_RESULT \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT) -#define NET_EVENT_WIFI_AP_STA_CONNECTED \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) - -#define NET_EVENT_WIFI_AP_STA_DISCONNECTED \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED) - /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -578,18 +568,6 @@ struct wifi_raw_scan_result { }; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ -/** AP mode - connected STA details */ -struct wifi_ap_sta_info { - /** Link mode, see enum wifi_link_mode */ - enum wifi_link_mode link_mode; - /** MAC address */ - uint8_t mac[WIFI_MAC_ADDR_LEN]; - /** MAC address length */ - uint8_t mac_length; - /** is TWT capable ? */ - bool twt_capable; -}; - /* for use in max info size calculations */ union wifi_mgmt_events { struct wifi_scan_result scan_result; @@ -599,7 +577,6 @@ union wifi_mgmt_events { struct wifi_raw_scan_result raw_scan_result; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct wifi_twt_params twt_params; - struct wifi_ap_sta_info ap_sta_info; }; /** Wi-Fi mode setup */ @@ -872,21 +849,6 @@ void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, enum wifi_ap_s */ void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, enum wifi_ap_status status); -/** Wi-Fi management AP mode STA connected event - * - * @param iface Network interface - * @param sta_info STA information - */ -void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, - struct wifi_ap_sta_info *sta_info); - -/** Wi-Fi management AP mode STA disconnected event - * @param iface Network interface - * @param sta_info STA information - */ -void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, - struct wifi_ap_sta_info *sta_info); - /** * @} */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 4a9c3d8a63a..14e361c73fb 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -731,19 +731,3 @@ void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, iface, &cnx_status, sizeof(enum wifi_ap_status)); } - -void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, - struct wifi_ap_sta_info *sta_info) -{ - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED, - iface, sta_info, - sizeof(struct wifi_ap_sta_info)); -} - -void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, - struct wifi_ap_sta_info *sta_info) -{ - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED, - iface, sta_info, - sizeof(struct wifi_ap_sta_info)); -} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 045fbed197e..217e4c703c0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -35,9 +35,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); NET_EVENT_WIFI_TWT |\ NET_EVENT_WIFI_RAW_SCAN_RESULT |\ NET_EVENT_WIFI_AP_ENABLE_RESULT |\ - NET_EVENT_WIFI_AP_DISABLE_RESULT |\ - NET_EVENT_WIFI_AP_STA_CONNECTED |\ - NET_EVENT_WIFI_AP_STA_DISCONNECTED) + NET_EVENT_WIFI_AP_DISABLE_RESULT) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY #define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) @@ -330,28 +328,6 @@ static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) } } -static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) -{ - const struct wifi_ap_sta_info *sta_info = - (const struct wifi_ap_sta_info *)cb->info; - uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - - print(context.sh, SHELL_NORMAL, "Station connected: %s\n", - net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, - mac_string_buf, sizeof(mac_string_buf))); -} - -static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) -{ - const struct wifi_ap_sta_info *sta_info = - (const struct wifi_ap_sta_info *)cb->info; - uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - - print(context.sh, SHELL_NORMAL, "Station disconnected: %s\n", - net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, - mac_string_buf, sizeof(mac_string_buf))); -} - static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { @@ -382,12 +358,6 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, case NET_EVENT_WIFI_AP_DISABLE_RESULT: handle_wifi_ap_disable_result(cb); break; - case NET_EVENT_WIFI_AP_STA_CONNECTED: - handle_wifi_ap_sta_connected(cb); - break; - case NET_EVENT_WIFI_AP_STA_DISCONNECTED: - handle_wifi_ap_sta_disconnected(cb); - break; default: break; } From 322d4adeb1f5c73ffb98738272a17f13113ce714 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:12 +0000 Subject: [PATCH 3994/4498] Revert "[nrf fromlist] wifi: ap: Add status events" This reverts commit af9dc97de19890aa30dc04c1dbd889ef43453747. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 47 --------------------------------- subsys/net/l2/wifi/wifi_mgmt.c | 24 ----------------- subsys/net/l2/wifi/wifi_shell.c | 41 +++------------------------- 3 files changed, 4 insertions(+), 108 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 1423cb2817f..d1bf5d43bfd 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -180,10 +180,6 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, /** Disconnect complete */ NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, - /** AP mode enable result */ - NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT, - /** AP mode disable result */ - NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -213,12 +209,6 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) -#define NET_EVENT_WIFI_AP_ENABLE_RESULT \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT) - -#define NET_EVENT_WIFI_AP_DISABLE_RESULT \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT) - /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -361,35 +351,12 @@ enum wifi_disconn_reason { WIFI_REASON_DISCONN_INACTIVITY, }; -/** Wi-Fi AP mode result codes. To be overlaid on top of \ref wifi_status - * in the AP mode enable or disable result event for detailed status. - */ -enum wifi_ap_status { - /** AP mode enable or disable successful */ - WIFI_STATUS_AP_SUCCESS = 0, - /** AP mode enable or disable failed - generic failure */ - WIFI_STATUS_AP_FAIL, - /** AP mode enable failed - channel not supported */ - WIFI_STATUS_AP_CHANNEL_NOT_SUPPORTED, - /** AP mode enable failed - channel not allowed */ - WIFI_STATUS_AP_CHANNEL_NOT_ALLOWED, - /** AP mode enable failed - SSID not allowed */ - WIFI_STATUS_AP_SSID_NOT_ALLOWED, - /** AP mode enable failed - authentication type not supported */ - WIFI_STATUS_AP_AUTH_TYPE_NOT_SUPPORTED, - /** AP mode enable failed - operation not supported */ - WIFI_STATUS_AP_OP_NOT_SUPPORTED, - /** AP mode enable failed - operation not permitted */ - WIFI_STATUS_AP_OP_NOT_PERMITTED, -}; - /** Generic Wi-Fi status for commands and events */ struct wifi_status { union { int status; enum wifi_conn_status conn_status; enum wifi_disconn_reason disconn_reason; - enum wifi_ap_status ap_status; }; }; @@ -835,20 +802,6 @@ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, */ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); -/** Wi-Fi management AP mode enable result event - * - * @param iface Network interface - * @param status AP mode enable result status - */ -void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, enum wifi_ap_status status); - -/** Wi-Fi management AP mode disable result event - * - * @param iface Network interface - * @param status AP mode disable result status - */ -void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, enum wifi_ap_status status); - /** * @} */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 14e361c73fb..cdad7646e02 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -707,27 +707,3 @@ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, iface, &cnx_status, sizeof(struct wifi_status)); } - -void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, - enum wifi_ap_status status) -{ - struct wifi_status cnx_status = { - .status = status, - }; - - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT, - iface, &cnx_status, - sizeof(enum wifi_ap_status)); -} - -void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, - enum wifi_ap_status status) -{ - struct wifi_status cnx_status = { - .status = status, - }; - - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT, - iface, &cnx_status, - sizeof(enum wifi_ap_status)); -} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 217e4c703c0..236e5cd05b8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -33,9 +33,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); NET_EVENT_WIFI_CONNECT_RESULT |\ NET_EVENT_WIFI_DISCONNECT_RESULT | \ NET_EVENT_WIFI_TWT |\ - NET_EVENT_WIFI_RAW_SCAN_RESULT |\ - NET_EVENT_WIFI_AP_ENABLE_RESULT |\ - NET_EVENT_WIFI_AP_DISABLE_RESULT) + NET_EVENT_WIFI_RAW_SCAN_RESULT) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY #define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) @@ -302,32 +300,6 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) } } -static void handle_wifi_ap_enable_result(struct net_mgmt_event_callback *cb) -{ - const struct wifi_status *status = - (const struct wifi_status *)cb->info; - - if (status->status) { - print(context.sh, SHELL_WARNING, - "AP enable request failed (%d)\n", status->status); - } else { - print(context.sh, SHELL_NORMAL, "AP enabled\n"); - } -} - -static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) -{ - const struct wifi_status *status = - (const struct wifi_status *)cb->info; - - if (status->status) { - print(context.sh, SHELL_WARNING, - "AP disable request failed (%d)\n", status->status); - } else { - print(context.sh, SHELL_NORMAL, "AP disabled\n"); - } -} - static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { @@ -352,12 +324,6 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, handle_wifi_raw_scan_result(cb); break; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ - case NET_EVENT_WIFI_AP_ENABLE_RESULT: - handle_wifi_ap_enable_result(cb); - break; - case NET_EVENT_WIFI_AP_DISABLE_RESULT: - handle_wifi_ap_disable_result(cb); - break; default: break; } @@ -1146,7 +1112,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode enable requested\n"); + shell_fprintf(sh, SHELL_NORMAL, "AP mode enabled\n"); return 0; } @@ -1163,7 +1129,8 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode disable requested\n"); + shell_fprintf(sh, SHELL_NORMAL, "AP mode disabled\n"); + return 0; } From 5114f4f6a47898fd0b1879fde95d6d234dae5613 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:13 +0000 Subject: [PATCH 3995/4498] Revert "[nrf fromlist] wifi: Fix duplication" This reverts commit 0646c56102d167a6ef533095d5603e7d411b1f54. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 236e5cd05b8..9bf33e827ec 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -29,17 +29,19 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #define WIFI_SHELL_MODULE "wifi" -#define WIFI_SHELL_MGMT_EVENTS_COMMON (NET_EVENT_WIFI_SCAN_DONE |\ - NET_EVENT_WIFI_CONNECT_RESULT |\ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT |\ - NET_EVENT_WIFI_RAW_SCAN_RESULT) - #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY -#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) +#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT | \ + NET_EVENT_WIFI_SCAN_DONE | \ + NET_EVENT_WIFI_CONNECT_RESULT | \ + NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_TWT) #else -#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON |\ - NET_EVENT_WIFI_SCAN_RESULT) +#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | \ + NET_EVENT_WIFI_SCAN_DONE | \ + NET_EVENT_WIFI_CONNECT_RESULT | \ + NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_TWT | \ + NET_EVENT_WIFI_RAW_SCAN_RESULT) #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ static struct { From 1743c14faf3778ce47155fefab343a9b219f2661 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:13 +0000 Subject: [PATCH 3996/4498] Revert "[nrf fromlist] shell: Add a space after colon" This reverts commit 72453d6a4d48e08ec07e86d2fb5cf38a3fe628df. Signed-off-by: Dominik Ermel --- subsys/shell/shell_help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/shell/shell_help.c b/subsys/shell/shell_help.c index 235e2111032..53bf00953c1 100644 --- a/subsys/shell/shell_help.c +++ b/subsys/shell/shell_help.c @@ -139,7 +139,7 @@ static void help_item_print(const struct shell *sh, const char *item_name, z_cursor_next_line_move(sh); return; } else { - z_shell_fprintf(sh, SHELL_NORMAL, "%s: ", tabulator); + z_shell_fprintf(sh, SHELL_NORMAL, "%s:", tabulator); } /* print option help */ formatted_text_print(sh, item_help, offset, false); From 55e995228073230bd5cb962feae6d1bf113b1c29 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:13 +0000 Subject: [PATCH 3997/4498] Revert "[nrf fromlist] wifi: shell: Fix the inconsistency in commands separation" This reverts commit 1353dd144af6aaaa71649c82db287525a72da343. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 98 ++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9bf33e827ec..a983e5c18f5 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1601,7 +1601,7 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD_ARG(disable, NULL, - "Disable Access Point mode.\n", + "Disable Access Point mode", cmd_wifi_ap_disable, 1, 0), SHELL_CMD_ARG(enable, NULL, @@ -1611,7 +1611,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, "[Security type: valid only for secure SSIDs]\n" "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" - ": 0:Disable, 1:Optional, 2:Required.\n", + ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_ap_enable, 2, 4), SHELL_SUBCMD_SET_END @@ -1619,30 +1619,30 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD_ARG(quick_setup, NULL, " Start a TWT flow with defaults:\n" - " .\n", + " \n", cmd_wifi_twt_setup_quick, 3, 0), SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " - " .\n", + " \n", cmd_wifi_twt_setup, 11, 0), SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " .\n", + " \n", cmd_wifi_twt_teardown, 5, 0), - SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows.\n", + SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows\n", cmd_wifi_twt_teardown_all, 1, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, - SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands.\n", NULL), + SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands", NULL), SHELL_CMD_ARG(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" @@ -1651,108 +1651,108 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[Security type: valid only for secure SSIDs]\n" "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" - ": 0:Disable, 1:Optional, 2:Required.\n", + ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect, 2, 4), - SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP.\n", + SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect, 1, 0), SHELL_CMD_ARG(ps, NULL, "Configure or display Wi-Fi power save state\n" - "[on/off].\n", + "[on/off]\n", cmd_wifi_ps, 1, 1), SHELL_CMD_ARG(ps_mode, NULL, - ".\n", + "\n", cmd_wifi_ps_mode, 2, 0), SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" - "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active\n" - "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz\n" - "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms\n" - "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms\n" - "[-s, --ssid : SSID to scan for. Can be provided multiple times\n" - "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535\n" + "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" + "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" + "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" + "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" + "[-s, --ssid : SSID to scan for. Can be provided multiple times.\n" + "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" - "[-h, --help] : Print out the help for the scan command.\n", + "[-h, --help] : Print out the help for the scan command.", cmd_wifi_scan, 1, 8), - SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics.\n", cmd_wifi_stats, 1, 0), - SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface.\n", cmd_wifi_status, 1, 0), - SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows.\n", NULL), + SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats, 1, 0), + SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status, 1, 0), + SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "[ISO/IEC 3166-1 alpha2]: Regulatory domain\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" - "Note: This may cause regulatory compliance issues, use it at your own risk.\n", + "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, 1, 2), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" - "[-i, --if-index ] : Interface index\n" - "[-s, --sta] : Station mode\n" - "[-m, --monitor] : Monitor mode\n" - "[-p, --promiscuous] : Promiscuous mode\n" - "[-t, --tx-injection] : TX-Injection mode\n" - "[-a, --ap] : AP mode\n" - "[-k, --softap] : Softap mode\n" - "[-h, --help] : Help\n" - "[-g, --get] : Get current mode for a specific interface index\n" + "[-i, --if-index ] : Interface index.\n" + "[-s, --sta] : Station mode.\n" + "[-m, --monitor] : Monitor mode.\n" + "[-p, --promiscuous] : Promiscuous mode.\n" + "[-t, --tx-injection] : TX-Injection mode.\n" + "[-a, --ap] : AP mode.\n" + "[-k, --softap] : Softap mode.\n" + "[-h, --help] : Help.\n" + "[-g, --get] : Get current mode for a specific interface index.\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" - "wifi mode -i1 -sp.\n", + "wifi mode -i1 -sp\n", cmd_wifi_mode, 1, 9), SHELL_CMD_ARG(packet_filter, NULL, "mode filter setting\n" "This command is used to set packet filter setting when\n" - "monitor, TX-Injection and promiscuous mode is enabled\n" + "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" - "[-i, --if-index ] : Interface index\n" + "[-i, --if-index ] : Interface index.\n" "[-a, --all] : Enable all packet filter modes\n" - "[-m, --mgmt] : Enable management packets to allowed up the stack\n" - "[-c, --ctrl] : Enable control packets to be allowed up the stack\n" - "[-d, --data] : Enable Data packets to be allowed up the stack\n" - "[-g, --get] : Get current filter settings for a specific interface index\n" + "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" + "[-c, --ctrl] : Enable control packets to be allowed up the stack.\n" + "[-d, --data] : Enable Data packets to be allowed up the stack.\n" + "[-g, --get] : Get current filter settings for a specific interface index.\n" "[-b, --capture-len ] : Capture length buffer size for each packet to be captured\n" - "[-h, --help] : Help\n" + "[-h, --help] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" - "wifi packet_filter -i1 -md.\n", + "wifi packet_filter -i1 -md\n", cmd_wifi_packet_filter, 1, 8), SHELL_CMD_ARG(channel, NULL, "wifi channel setting\n" "This command is used to set the channel when\n" - "monitor or TX-Injection mode is enabled\n" + "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" - "[-i, --if-index ] : Interface index\n" - "[-c, --channel ] : Set a specific channel number to the lower layer\n" - "[-g, --get] : Get current set channel number from the lower layer\n" - "[-h, --help] : Help\n" + "[-i, --if-index ] : Interface index.\n" + "[-c, --channel ] : Set a specific channel number to the lower layer.\n" + "[-g, --get] : Get current set channel number from the lower layer.\n" + "[-h, --help] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" - "wifi -i1 -c5.\n", + "wifi -i1 -c5\n", cmd_wifi_channel, 1, 4), SHELL_CMD_ARG(ps_timeout, NULL, - " - PS inactivity timer(in ms).\n", + " - PS inactivity timer(in ms)", cmd_wifi_ps_timeout, 2, 0), SHELL_CMD_ARG(ps_listen_interval, NULL, - " - Listen interval in the range of <0-65535>.\n", + " - Listen interval in the range of <0-65535>", cmd_wifi_listen_interval, 2, 0), SHELL_CMD_ARG(ps_wakeup_mode, NULL, - ".\n", + "\n", cmd_wifi_ps_wakeup_mode, 2, 0), From 362be6f3bb02224b96e49088faef6dcb6b920456 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:13 +0000 Subject: [PATCH 3998/4498] Revert "[nrf fromlist] wifi: shell: Remove the unnecessary text" This reverts commit f9f9f83293267465b05927bc3756e1d22accab05. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a983e5c18f5..890bb8f121e 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1691,6 +1691,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 1, 2), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" + "parameters:" "[-i, --if-index ] : Interface index.\n" "[-s, --sta] : Station mode.\n" "[-m, --monitor] : Monitor mode.\n" @@ -1710,6 +1711,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "This command is used to set packet filter setting when\n" "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" + "parameters:" "[-i, --if-index ] : Interface index.\n" "[-a, --all] : Enable all packet filter modes\n" "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" @@ -1728,6 +1730,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "This command is used to set the channel when\n" "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" + "parameters:" "[-i, --if-index ] : Interface index.\n" "[-c, --channel ] : Set a specific channel number to the lower layer.\n" "[-g, --get] : Get current set channel number from the lower layer.\n" From c48512bfc9bd5976192ff1b89e00a4706fa0ed09 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:13 +0000 Subject: [PATCH 3999/4498] Revert "[nrf fromlist] wifi: shell: Fix the help for reg domain" This reverts commit 6be67b3199e68acff52e8d09d231d0f4d5afec4d. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 890bb8f121e..d6d14c86bf1 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1684,7 +1684,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" - "[ISO/IEC 3166-1 alpha2]: Regulatory domain\n" + "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, From 766efac095eab69cb23efaa7cdc18dae1c3a50d4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:14 +0000 Subject: [PATCH 4000/4498] Revert "[nrf fromlist] wifi: shell: Remove the unnecessary text in scan" This reverts commit e8a952b68db6cd8d097e169a56284bf0ff42c2a0. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d6d14c86bf1..6ef745670ab 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1669,6 +1669,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" + "OPTIONAL PARAMETERS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" From 54e353e0f592f2f738106425fa3ea1e647caede8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:14 +0000 Subject: [PATCH 4001/4498] Revert "[nrf fromlist] wifi: shell: Fix help for PS command" This reverts commit 0fc24a59c702c89f6fa04feb552d5bb1eee5e6df. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 6ef745670ab..dbec138fea0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1657,8 +1657,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect, 1, 0), - SHELL_CMD_ARG(ps, NULL, "Configure or display Wi-Fi power save state\n" - "[on/off]\n", + SHELL_CMD_ARG(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", cmd_wifi_ps, 1, 1), SHELL_CMD_ARG(ps_mode, From c78f0fa13b3531def8d6dbad525e300eb0407261 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:14 +0000 Subject: [PATCH 4002/4498] Revert "[nrf fromlist] wifi: shell: Fix optional arg count for connect" This reverts commit 16d86216eb95cbc5e173db576ebee9c7d72d0569. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index dbec138fea0..c3100c9ad2c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1653,7 +1653,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect, - 2, 4), + 2, 5), SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect, 1, 0), From 727fd5058f91f4523877e2b771728ed55398cdbc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:14 +0000 Subject: [PATCH 4003/4498] Revert "[nrf fromlist] wifi: shell: Fix the arg count for reg domain" This reverts commit bf821e930748f94977af135540235b76dad32ee9. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index c3100c9ad2c..3aa674e73b7 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1688,7 +1688,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, - 1, 2), + 1, 1), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" From a81a856ae7d2b088bbd0ad477f05dd7dc1cf0da3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:15 +0000 Subject: [PATCH 4004/4498] Revert "[nrf fromtree] net: wifi_mgmt: update SSID storage type" This reverts commit feb411bac2fb151c8299e47eefa6622d2e66d504. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index d1bf5d43bfd..ab37bd4d878 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -245,7 +245,7 @@ struct wifi_scan_params { uint16_t dwell_time_passive; /** Array of SSID strings to scan. */ - const char *ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX]; + char ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX][WIFI_SSID_MAX_LEN + 1]; /** Specifies the maximum number of scan results to return. These results would be the * BSSIDS with the best RSSI values, in all the scanned channels. This should only be * used to limit the number of returned scan results, and cannot be counted upon to limit From 01aaa7b1f75f69eef134e1b8902f7af8d0c740ab Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:15 +0000 Subject: [PATCH 4005/4498] Revert "[nrf fromtree] net: wifi: re-add `WIFI_MGMT_FORCED_PASSIVE_SCAN`" This reverts commit 339e7dcdcf0baa5169ffda4e805ff6d688220f19. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/Kconfig | 9 --------- subsys/net/l2/wifi/wifi_mgmt.c | 9 --------- 2 files changed, 18 deletions(-) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 134448aa57f..8fbd6aff4d6 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -39,15 +39,6 @@ config WIFI_MGMT_TWT_CHECK_IP even when it is awake intervals. Rejecting TWT setup till Wi-Fi interface has a valid IP address might be desirable in most scenarios. -config WIFI_MGMT_FORCED_PASSIVE_SCAN - bool "Force passive Wi-Fi scanning" - help - Always request a passive scan, regardless of the user supplied parameters. - This is typically used when the underlying hardware is not certified for - RF transmissions. This doesn't guarantee that passive scan will be used, - it depends on the underlying chip implementation to support and honour - scan type. - config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index cdad7646e02..58e14ff02ff 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -327,15 +327,6 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } -#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN - struct wifi_scan_params default_params = {0}; - - if (params == NULL) { - params = &default_params; - } - params->scan_type = WIFI_SCAN_TYPE_PASSIVE; -#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */ - return wifi_mgmt_api->scan(dev, params, scan_result_cb); } From 1b8439206b10dce2a98534b5c4302d3d7ee40e87 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:15 +0000 Subject: [PATCH 4006/4498] Revert "[nrf fromtree] net: wifi: shell: update SSID argument format" This reverts commit 88884a533d602ff2e756f5e91af60cef5fd30a14. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_utils.h | 6 ++--- subsys/net/l2/wifi/wifi_shell.c | 8 +++---- subsys/net/l2/wifi/wifi_utils.c | 41 +++++++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index c9ef9979f91..4284138b6f3 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -63,15 +63,13 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); * as a comma separated string and convert it to an array. * * @param scan_ssids_str List of SSIDs expressed as a comma separated list. - * @param ssids Pointer to an array where the SSIDs pointers are to be stored. - * @param num_ssids Maximum number of SSIDs that can be stored. + * @param ssids Pointer to an array where the parsed SSIDs are to be stored. * * @retval 0 on success. * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, - const char *ssids[], - uint8_t num_ssids); + char ssids[][WIFI_SSID_MAX_LEN + 1]); /** diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3aa674e73b7..65e99204aa7 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -481,7 +481,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"bands", required_argument, 0, 'b'}, {"dwell_time_active", required_argument, 0, 'a'}, {"dwell_time_passive", required_argument, 0, 'p'}, - {"ssid", required_argument, 0, 's'}, + {"ssids", required_argument, 0, 's'}, {"max_bss", required_argument, 0, 'm'}, {"chans", required_argument, 0, 'c'}, {"help", no_argument, 0, 'h'}, @@ -538,9 +538,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 's': - if (wifi_utils_parse_scan_ssids(optarg, - params->ssids, - ARRAY_SIZE(params->ssids))) { + if (wifi_utils_parse_scan_ssids(optarg, params->ssids)) { shell_fprintf(sh, SHELL_ERROR, "Invalid SSID(s)\n"); return -ENOEXEC; } @@ -1673,7 +1671,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" - "[-s, --ssid : SSID to scan for. Can be provided multiple times.\n" + "[-s, --ssids ] : SSID list to scan for.\n" "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" "[-h, --help] : Print out the help for the scan command.", diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 52d25d90566..4c50b817d26 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -263,9 +263,12 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) } int wifi_utils_parse_scan_ssids(char *scan_ssids_str, - const char *ssids[], - uint8_t num_ssids) + char ssids[][WIFI_SSID_MAX_LEN + 1]) { + char parse_str[(WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1)) + 1]; + char *ssid = NULL; + char *ctx = NULL; + uint8_t i = 0; int len; if (!scan_ssids_str) { @@ -273,23 +276,41 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, } len = strlen(scan_ssids_str); - if (len > WIFI_SSID_MAX_LEN) { + + if (len > (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))) { NET_ERR("SSID string (%s) size (%d) exceeds maximum allowed value (%d)", scan_ssids_str, len, - WIFI_SSID_MAX_LEN); + (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))); return -EINVAL; } - for (int i = 0; i < num_ssids; i++) { - if (ssids[i] != NULL) { - continue; + strncpy(parse_str, scan_ssids_str, len); + parse_str[len] = '\0'; + + ssid = strtok_r(parse_str, ",", &ctx); + + while (ssid) { + if (strlen(ssid) > WIFI_SSID_MAX_LEN) { + NET_ERR("SSID length (%zu) exceeds maximum value (%d) for SSID %s", + strlen(ssid), + WIFI_SSID_MAX_LEN, + ssid); + return -EINVAL; + } + + if (i >= WIFI_MGMT_SCAN_SSID_FILT_MAX) { + NET_WARN("Exceeded maximum allowed (%d) SSIDs. Ignoring SSIDs %s onwards", + WIFI_MGMT_SCAN_SSID_FILT_MAX, + ssid); + break; } - ssids[i] = scan_ssids_str; - return 0; + + strcpy(&ssids[i++][0], ssid); + + ssid = strtok_r(NULL, ",", &ctx); } - NET_WARN("Exceeded maximum allowed SSIDs (%d)", num_ssids); return 0; } From fd184f89991928333d7b17be246b033ea5ea481d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:15 +0000 Subject: [PATCH 4007/4498] Revert "[nrf fromtree] net: wifi_mgmt: linearise `scan_params->chan` arrays" This reverts commit 5fa35c899d62e725fa77f74881e7465f3749fb61. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 18 ++++-------------- include/zephyr/net/wifi_utils.h | 4 +--- subsys/net/l2/wifi/Kconfig | 6 +++--- subsys/net/l2/wifi/wifi_shell.c | 4 +--- subsys/net/l2/wifi/wifi_utils.c | 32 ++++++++------------------------ 5 files changed, 17 insertions(+), 47 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ab37bd4d878..81634a7fc62 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -209,16 +209,6 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) -/** - * @brief Wi-Fi structure to uniquely identify a band-channel pair - */ -struct wifi_band_channel { - /** Frequency band */ - uint8_t band; - /** Channel */ - uint8_t channel; -}; - /** * @brief Wi-Fi scan parameters structure. * Used to specify parameters which can control how the Wi-Fi scan @@ -258,9 +248,9 @@ struct wifi_scan_params { * band. * E.g. to scan channel 6 and 11 on the 2.4 GHz band, channel 36 on the 5 GHz band: * @code{.c} - * chan[0] = {WIFI_FREQ_BAND_2_4_GHZ, 6}; - * chan[1] = {WIFI_FREQ_BAND_2_4_GHZ, 11}; - * chan[2] = {WIFI_FREQ_BAND_5_GHZ, 36}; + * chan[WIFI_FREQ_BAND_2_4_GHZ][0] = 6; + * chan[WIFI_FREQ_BAND_2_4_GHZ][1] = 11; + * chan[WIFI_FREQ_BAND_5_GHZ][0] = 36; * @endcode * * This list specifies the channels to be __considered for scan__. The underlying @@ -268,7 +258,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - struct wifi_band_channel band_chan[WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; + uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index 4284138b6f3..b005d075847 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -95,14 +95,12 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, * * @param scan_chan_str List of channels expressed in the format described above. * @param chan Pointer to an array where the parsed channels are to be stored. - * @param max_channels Maximum number of channels to store * * @retval 0 on success. * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_chan(char *scan_chan_str, - struct wifi_band_channel *chan, - uint8_t max_channels); + uint8_t chan[][WIFI_CHANNEL_MAX]); /** * @} diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 8fbd6aff4d6..5644852c2a0 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -48,11 +48,11 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX This can be set based on the underlying chipsets limitations. config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL - int "Maximum number of channels that can be manually specified" - range 1 110 + int "Maximum number of channels that can be manually specified per-band" + range 1 70 default 3 help - There are approximately 100 channels allocated across the three supported bands. + There are currently 60 channels allocated in the largest band (6GHz). The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. config WIFI_NM diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 65e99204aa7..6893e20353e 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -557,9 +557,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'c': - if (wifi_utils_parse_scan_chan(optarg, - params->band_chan, - ARRAY_SIZE(params->band_chan))) { + if (wifi_utils_parse_scan_chan(optarg, params->chan)) { shell_fprintf(sh, SHELL_ERROR, "Invalid band or channel value(s)\n"); diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 4c50b817d26..a77e225bfbf 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -105,7 +105,7 @@ static bool wifi_utils_validate_chan(uint8_t band, static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, uint8_t chan_end, - struct wifi_band_channel *band_chan, + uint8_t chan[][WIFI_CHANNEL_MAX], uint8_t band_idx, uint8_t *chan_idx) { @@ -136,9 +136,7 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, idx = *chan_idx; for (i = chan_start; i <= chan_end; i++) { - band_chan[idx].band = band_idx; - band_chan[idx].channel = i; - idx++; + chan[band_idx][idx++] = i; } *chan_idx = idx; @@ -157,9 +155,7 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, } if (start) { - band_chan[idx].band = band_idx; - band_chan[idx].channel = valid_5g_chans_20mhz[i]; - idx++; + chan[band_idx][idx++] = valid_5g_chans_20mhz[i]; } if (end) { @@ -175,9 +171,7 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, i = chan_start; while (i <= chan_end) { - band_chan[idx].band = band_idx; - band_chan[idx].channel = i; - idx++; + chan[band_idx][idx++] = i; if (i == 1) { i++; @@ -316,8 +310,7 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, int wifi_utils_parse_scan_chan(char *scan_chan_str, - struct wifi_band_channel *band_chan, - uint8_t max_channels) + uint8_t chan[][WIFI_CHANNEL_MAX]) { char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; @@ -356,6 +349,7 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, } i++; + chan_idx = 0; chan_str_start_idx = i; valid_band = true; @@ -389,13 +383,9 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, memset(chan_str, 0, sizeof(chan_str)); if (chan_start) { - if ((chan_idx + (chan_val - chan_start)) >= max_channels) { - NET_ERR("Too many channels specified (%d)", max_channels); - return -EINVAL; - } if (wifi_utils_get_all_chans_in_range(chan_start, chan_val, - band_chan, + chan, band, &chan_idx)) { NET_ERR("Channel range invalid"); @@ -409,14 +399,8 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, NET_ERR("Invalid channel %d", chan_val); return -EINVAL; } - if (chan_idx == max_channels) { - NET_ERR("Too many channels specified (%d)", max_channels); - return -EINVAL; - } - band_chan[chan_idx].band = band; - band_chan[chan_idx].channel = chan_val; - chan_idx++; + chan[band][chan_idx++] = chan_val; } valid_chan = true; From 49dcc6d44359a50364b87e212a51ceab8adbc12b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:16 +0000 Subject: [PATCH 4008/4498] Revert "[nrf fromtree] net: wifi_mgmt: make number of scan channels configurable" This reverts commit 8efaa1633aa03d4444be79b7b029a28c13362a02. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 8 +------- subsys/net/l2/wifi/Kconfig | 8 -------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 81634a7fc62..67a603aea95 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -41,12 +41,6 @@ extern "C" { #define WIFI_MGMT_SCAN_SSID_FILT_MAX 0 #endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ -#ifdef CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL -#define WIFI_MGMT_SCAN_CHAN_MAX_MANUAL CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL -#else -#define WIFI_MGMT_SCAN_CHAN_MAX_MANUAL 1 -#endif /* CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL */ - #define WIFI_MGMT_BAND_STR_SIZE_MAX 8 /** Wi-Fi management commands */ @@ -258,7 +252,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; + uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 5644852c2a0..ccf5ce31ca6 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -47,14 +47,6 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. -config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL - int "Maximum number of channels that can be manually specified per-band" - range 1 70 - default 3 - help - There are currently 60 channels allocated in the largest band (6GHz). - The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. - config WIFI_NM bool "Wi-Fi Network manager support" help From d7b10883a96e64bfcd9035f89598328d71739ab8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:16 +0000 Subject: [PATCH 4009/4498] Revert "[nrf fromtree] net: l2: wifi_mgmt: remove scan kconfig defaults" This reverts commit f76c35a823c2b4909f2306c074267a57f9fff864. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/Kconfig | 67 ++++++++++++++++++++++++++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 55 ++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index ccf5ce31ca6..6623456d84b 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -39,6 +39,40 @@ config WIFI_MGMT_TWT_CHECK_IP even when it is awake intervals. Rejecting TWT setup till Wi-Fi interface has a valid IP address might be desirable in most scenarios. +config WIFI_MGMT_FORCED_PASSIVE_SCAN + bool "Force Passive scan" + help + Force passive scan (typically used to reduce power consumption), + the scan type is always sent as passive. + This doesn't guarantee that passive scan will be used, it depends + on the underlying chip implementation to support and honour scan type. + +config WIFI_MGMT_SCAN_BANDS + string "Frequency bands to scan" + default "" + help + Specifies the frequency bands to scan, as follows: + 2 - 2.4 GHz + 5 - 5 GHz + 6 - 6 GHz + "" - All bands allowed by the regulatory domain. + Multiple bands can be specified as comma separated band values. + Only regulatory domain permitted values are allowed. + +config WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE + int "Active scan dwell time" + default 50 + range 5 1000 + help + Active scan dwell time (in ms) per channel. + +config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE + int "Passive scan dwell time" + default 130 + range 10 1000 + help + Passive scan dwell time (in ms) per channel. + config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 @@ -47,6 +81,39 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. +config WIFI_MGMT_SCAN_SSID_FILT + string "Scan for specific SSIDs" + default "" + help + String of comma separated SSID values to scan for. The number of SSID’s + that can be specified depends on WIFI_MGMT_SCAN_MAX_SSIDS. + Use "" to disable SSID filtering. + +config WIFI_MGMT_SCAN_MAX_BSS_CNT + int "Maximum number of scan results to return." + default 0 + range 0 65535 + help + Maximum number of scan results to return. 0 represents unlimited number of BSSes. + +config WIFI_MGMT_SCAN_CHAN + string "Scan on specific channels" + default "" + help + Formatted string which specifies channels to be scanned. The channel string has to be formatted + using the colon (:), comma(,), hyphen (-) and space ( ) delimiters as follows: + - A colon identifies the value preceding it as a band. A band value + (2: 2.4 GHz, 5: 5 GHz 6: 6 GHz) has to precede the channels in that band (e.g. 2: etc) + - Hyphens are used to identify channel ranges (e.g. 2-7, 32-48 etc) + - Commas are used to separate channel values within a band. Channels can be specified + as individual values (2,6,48 etc) or channel ranges using hyphens (1-14, 32-48 etc) + - Spaces are used to specify multiple band-channel sets (e.g. 2:1,2 5:36,40 etc) + - No spaces should be used anywhere else, i.e. before/after commas, + before/after hyphens. + An example channel specification specifying channels in the 2.4 GHz and 5 GHz bands is + as below: + 2:1,5,7,9-11_5:36-48,100,163-167 + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 58e14ff02ff..0751f5d2b8c 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#include #ifdef CONFIG_WIFI_NM #include #endif /* CONFIG_WIFI_NM */ @@ -322,11 +323,65 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct wifi_scan_params *params = data; const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + bool chan_specified = false; + uint8_t i = 0; if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) { return -ENOTSUP; } + if (data && (len == sizeof(*params))) { +#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN + params->scan_type = WIFI_SCAN_TYPE_PASSIVE; +#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */ + + if (!params->bands) { + if (wifi_utils_parse_scan_bands(CONFIG_WIFI_MGMT_SCAN_BANDS, + ¶ms->bands)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_BANDS: %s", + CONFIG_WIFI_MGMT_SCAN_BANDS); + return -EINVAL; + } + } + + if (!params->dwell_time_active) { + params->dwell_time_active = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE; + } + + if (!params->dwell_time_passive) { + params->dwell_time_passive = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE; + } + + if (!strlen(params->ssids[0])) { + if (wifi_utils_parse_scan_ssids(CONFIG_WIFI_MGMT_SCAN_SSID_FILT, + params->ssids)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_SSID_FILT: %s", + CONFIG_WIFI_MGMT_SCAN_SSID_FILT); + return -EINVAL; + } + } + + if (!params->max_bss_cnt) { + params->max_bss_cnt = CONFIG_WIFI_MGMT_SCAN_MAX_BSS_CNT; + } + + for (i = 0; i <= WIFI_FREQ_BAND_MAX; i++) { + if (params->chan[i][0]) { + chan_specified = true; + break; + } + } + + if ((!chan_specified) && strlen(CONFIG_WIFI_MGMT_SCAN_CHAN)) { + if (wifi_utils_parse_scan_chan(CONFIG_WIFI_MGMT_SCAN_CHAN, + params->chan)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_CHAN: %s", + CONFIG_WIFI_MGMT_SCAN_CHAN); + return -EINVAL; + } + } + } + return wifi_mgmt_api->scan(dev, params, scan_result_cb); } From 017a98a048f0c11375983d8fda55dc194b307595 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:16 +0000 Subject: [PATCH 4010/4498] Revert "[nrf fromtree] net: wifi_mgmt: change type of `wifi_scan_params->chan`" This reverts commit 52ce713e771e3c8c9a64c47d52b25825c5c627d8. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 2 +- include/zephyr/net/wifi_utils.h | 2 +- subsys/net/l2/wifi/wifi_utils.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 67a603aea95..1be98b927cb 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -252,7 +252,7 @@ struct wifi_scan_params { * not conforming to regulatory restrictions etc. The invoker of the API should * ensure that the channels specified follow regulatory rules. */ - uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; + uint16_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index b005d075847..86b39ff4660 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -100,7 +100,7 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, * @retval -errno value in case of failure. */ int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint8_t chan[][WIFI_CHANNEL_MAX]); + uint16_t chan[][WIFI_CHANNEL_MAX]); /** * @} diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index a77e225bfbf..ea0e42def47 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -103,13 +103,13 @@ static bool wifi_utils_validate_chan(uint8_t band, } -static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, - uint8_t chan_end, - uint8_t chan[][WIFI_CHANNEL_MAX], +static int wifi_utils_get_all_chans_in_range(uint16_t chan_start, + uint16_t chan_end, + uint16_t chan[][WIFI_CHANNEL_MAX], uint8_t band_idx, uint8_t *chan_idx) { - uint8_t i; + uint16_t i; bool start = false; bool end = false; uint8_t idx; @@ -310,7 +310,7 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, int wifi_utils_parse_scan_chan(char *scan_chan_str, - uint8_t chan[][WIFI_CHANNEL_MAX]) + uint16_t chan[][WIFI_CHANNEL_MAX]) { char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; @@ -318,8 +318,8 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, uint16_t band_str_start_idx = 0; uint16_t chan_str_start_idx = 0; uint8_t chan_idx = 0; - uint8_t chan_start = 0; - uint8_t chan_val = 0; + uint16_t chan_start = 0; + uint16_t chan_val = 0; uint16_t i = 0; bool valid_band = false; bool valid_chan = false; From a7414fa918493c3fbe06c9715d0f1435198e6734 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:16 +0000 Subject: [PATCH 4011/4498] Revert "[nrf fromlist] wifi: shell: Fix arg count for regulatory domain" This reverts commit 426213023e08965311421143ca3abe2ec25b39a4. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 6893e20353e..e1f225bd4e8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1684,7 +1684,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, - 1, 1), + 2, 1), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" From a474929bf203cb00b7acb7d5e8a30b9d4fa9971d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:17 +0000 Subject: [PATCH 4012/4498] Revert "[nrf fromtree] wifi: shell: Display RSSI only for station mode" This reverts commit b65e77cdb79c3deb22395874d3079f850a6dffd0. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index e1f225bd4e8..658dadce6fd 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -656,9 +656,7 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) wifi_security_txt(status.security)); shell_fprintf(sh, SHELL_NORMAL, "MFP: %s\n", wifi_mfp_txt(status.mfp)); - if (status.iface_mode == WIFI_MODE_INFRA) { - shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); - } + shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); shell_fprintf(sh, SHELL_NORMAL, "Beacon Interval: %d\n", status.beacon_interval); shell_fprintf(sh, SHELL_NORMAL, "DTIM: %d\n", status.dtim_period); shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", From 8ea2f1f6e2b07a5484fc557fb1dc25b02b329b73 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:17 +0000 Subject: [PATCH 4013/4498] Revert "[nrf fromtree] wifi: shell: Fix AP argument checks and help" This reverts commit 85a25485d25f7da05e0d6c707b326a487b3a9e6b. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 658dadce6fd..90dbd1588f7 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1598,16 +1598,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, "Disable Access Point mode", cmd_wifi_ap_disable, 1, 0), - SHELL_CMD_ARG(enable, NULL, - "\"\"\n" - "[channel number: 0 means all]\n" - "[PSK: valid only for secure SSIDs]\n" - "[Security type: valid only for secure SSIDs]\n" - "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" - "[MFP (optional: needs security type to be specified)]\n" - ": 0:Disable, 1:Optional, 2:Required", + SHELL_CMD_ARG(enable, NULL, " [channel] [PSK]", cmd_wifi_ap_enable, - 2, 4), + 2, 1), SHELL_SUBCMD_SET_END ); From 35ac56899a427ba128c04075f774d9888975e69d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:17 +0000 Subject: [PATCH 4014/4498] Revert "[nrf fromtree] drivers: nrf_qspi_nor: Fix and refactor driver initialization" This reverts commit 86146714949810fd451dace302bd42ea4ecb3927. Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 125 ++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 45 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index ac055229710..ae990a5d68e 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -599,10 +599,41 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) return rc != 0 ? rc : rc2; } -static int configure_chip(const struct device *dev) +/* Configures QSPI memory for the transfer */ +static int qspi_nrfx_configure(const struct device *dev) { + struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - int rc = 0; + nrfx_err_t res; + int rc; + + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); + rc = qspi_get_zephyr_ret_code(res); + if (rc < 0) { + return rc; + } + +#if DT_INST_NODE_HAS_PROP(0, rx_delay) + if (!nrf53_errata_121()) { + nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); + } +#endif + + /* It may happen that after the flash chip was previously put into + * the DPD mode, the system was reset but the flash chip was not. + * Consequently, the flash chip can be in the DPD mode at this point. + * Some flash chips will just exit the DPD mode on the first CS pulse, + * but some need to receive the dedicated command to do it, so send it. + * This can be the case even if the current image does not have + * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image + * (for example the main image if the currently executing image is the + * bootloader) might have set DPD mode before reboot. As a result, + * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. + */ + rc = exit_dpd(dev); + if (rc < 0) { + return rc; + } /* Set QE to match transfer mode. If not using quad * it's OK to leave QE set, but doing so prevents use @@ -753,6 +784,33 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, #endif /* CONFIG_FLASH_JESD216_API */ +/** + * @brief Retrieve the Flash JEDEC ID and compare it with the one expected + * + * @param dev The device structure + * @return 0 on success, negative errno code otherwise + */ +static inline int qspi_nor_read_id(const struct device *dev) +{ + uint8_t id[SPI_NOR_MAX_ID_LEN]; + int rc = qspi_rdid(dev, id); + + if (rc != 0) { + return -EIO; + } + + const struct qspi_nor_config *qnc = dev->config; + + if (memcmp(qnc->id, id, SPI_NOR_MAX_ID_LEN) != 0) { + LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", + id[0], id[1], id[2], + qnc->id[0], qnc->id[1], qnc->id[2]); + return -ENODEV; + } + + return 0; +} + static inline nrfx_err_t read_non_aligned(const struct device *dev, off_t addr, void *dest, size_t size) @@ -1019,58 +1077,35 @@ static int qspi_nor_write_protection_set(const struct device *dev, return rc; } -static int qspi_init(const struct device *dev) +/** + * @brief Configure the flash + * + * @param dev The flash device structure + * @param info The flash info structure + * @return 0 on success, negative errno code otherwise + */ +static int qspi_nor_configure(const struct device *dev) { - const struct qspi_nor_config *dev_config = dev->config; - uint8_t id[SPI_NOR_MAX_ID_LEN]; - nrfx_err_t res; - int rc; - - res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); - rc = qspi_get_zephyr_ret_code(res); - if (rc < 0) { - return rc; - } - -#if DT_INST_NODE_HAS_PROP(0, rx_delay) - if (!nrf53_errata_121()) { - nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); - } -#endif - - /* It may happen that after the flash chip was previously put into - * the DPD mode, the system was reset but the flash chip was not. - * Consequently, the flash chip can be in the DPD mode at this point. - * Some flash chips will just exit the DPD mode on the first CS pulse, - * but some need to receive the dedicated command to do it, so send it. - * This can be the case even if the current image does not have - * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image - * (for example the main image if the currently executing image is the - * bootloader) might have set DPD mode before reboot. As a result, - * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. - */ - rc = exit_dpd(dev); - if (rc < 0) { - return rc; - } + int rc = qspi_nrfx_configure(dev); - /* Retrieve the Flash JEDEC ID and compare it with the one expected. */ - rc = qspi_rdid(dev, id); - if (rc < 0) { + if (rc != 0) { return rc; } - if (memcmp(dev_config->id, id, SPI_NOR_MAX_ID_LEN) != 0) { - LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", - id[0], id[1], id[2], dev_config->id[0], - dev_config->id[1], dev_config->id[2]); + /* now the spi bus is configured, we can verify the flash id */ + if (qspi_nor_read_id(dev) != 0) { return -ENODEV; } - /* The chip is correct, it can be configured now. */ - return configure_chip(dev); + return 0; } +/** + * @brief Initialize and configure the flash + * + * @param name The flash name + * @return 0 on success, negative errno code otherwise + */ static int qspi_nor_init(const struct device *dev) { const struct qspi_nor_config *dev_config = dev->config; @@ -1086,7 +1121,7 @@ static int qspi_nor_init(const struct device *dev) qspi_clock_div_change(); - rc = qspi_init(dev); + rc = qspi_nor_configure(dev); qspi_clock_div_restore(); From 9b3db0eb21158328f4477b35fccd7b47bde0ecd0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:18 +0000 Subject: [PATCH 4015/4498] Revert "[nrf fromtree] drivers: nrf_qspi_nor: Refactor deactivation and locking access to QSPI" This reverts commit 9a0aca0df38a10f19296c26fe6df9bc5b5b52c29. Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 507 ++++++++++++++++++++++------------- 1 file changed, 314 insertions(+), 193 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index ae990a5d68e..653f8b38f4e 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -26,15 +26,15 @@ LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL); #include struct qspi_nor_data { -#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) - /* A semaphore to control QSPI deactivation. */ - struct k_sem count; -#endif #ifdef CONFIG_MULTITHREADING + /* The semaphore to control exclusive access on write/erase. */ + struct k_sem trans; /* The semaphore to control exclusive access to the device. */ struct k_sem sem; /* The semaphore to indicate that transfer has completed. */ struct k_sem sync; + /* The semaphore to control driver init/uninit. */ + struct k_sem count; #else /* CONFIG_MULTITHREADING */ /* A flag that signals completed transfer when threads are * not enabled. @@ -173,6 +173,12 @@ BUILD_ASSERT(DT_INST_PROP(0, address_size_32), "After entering 4 byte addressing mode, 4 byte addressing is expected"); #endif +#ifndef CONFIG_PM_DEVICE_RUNTIME +static bool qspi_initialized; +#endif + +static int qspi_device_init(const struct device *dev); +static void qspi_device_uninit(const struct device *dev); void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); @@ -239,99 +245,72 @@ static inline int qspi_get_zephyr_ret_code(nrfx_err_t res) static inline void qspi_lock(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; + pm_device_busy_set(dev); + +#ifdef CONFIG_MULTITHREADING k_sem_take(&dev_data->sem, K_FOREVER); +#else /* CONFIG_MULTITHREADING */ + ARG_UNUSED(dev_data); +#endif /* CONFIG_MULTITHREADING */ + + /* + * Change the base clock divider only for the time the driver is locked + * to perform a QSPI operation, otherwise the power consumption would be + * increased also when the QSPI peripheral is idle. + * When XIP is enabled, there is nothing to do here as the changed + * divider is kept all the time. + */ +#if defined(CONFIG_SOC_SERIES_NRF53X) + if (!dev_data->xip_enabled) { + nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); + } #endif } static inline void qspi_unlock(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - k_sem_give(&dev_data->sem); -#endif -} - -static inline void qspi_clock_div_change(void) -{ -#ifdef CONFIG_SOC_SERIES_NRF53X - /* Make sure the base clock divider is changed accordingly - * before a QSPI transfer is performed. +#if defined(CONFIG_SOC_SERIES_NRF53X) + /* Restore the default base clock divider to reduce power consumption. + * Unless XIP is enabled, then the changed divider needs to be kept. */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); + if (!dev_data->xip_enabled) { + nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); + } #endif -} -static inline void qspi_clock_div_restore(void) -{ -#ifdef CONFIG_SOC_SERIES_NRF53X - /* Restore the default base clock divider to reduce power - * consumption when the QSPI peripheral is idle. - */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); +#ifdef CONFIG_MULTITHREADING + k_sem_give(&dev_data->sem); +#else + ARG_UNUSED(dev_data); #endif + + pm_device_busy_clear(dev); } -static void qspi_acquire(const struct device *dev) +static inline void qspi_trans_lock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; -#if defined(CONFIG_PM_DEVICE_RUNTIME) - int rc = pm_device_runtime_get(dev); - - if (rc < 0) { - LOG_ERR("pm_device_runtime_get failed: %d", rc); - } -#elif defined(CONFIG_MULTITHREADING) - /* In multithreading, the driver can call qspi_acquire more than once - * before calling qspi_release. Keeping count, so QSPI is deactivated - * only at the last call (count == 0). - */ - k_sem_give(&dev_data->count); -#endif - - qspi_lock(dev); - - if (!dev_data->xip_enabled) { - qspi_clock_div_change(); - - pm_device_busy_set(dev); - } + k_sem_take(&dev_data->trans, K_FOREVER); +#else /* CONFIG_MULTITHREADING */ + ARG_UNUSED(dev); +#endif /* CONFIG_MULTITHREADING */ } -static void qspi_release(const struct device *dev) +static inline void qspi_trans_unlock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - bool deactivate = true; -#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) - /* The last thread to finish using the driver deactivates the QSPI */ - (void) k_sem_take(&dev_data->count, K_NO_WAIT); - deactivate = (k_sem_count_get(&dev_data->count) == 0); -#endif - - if (!dev_data->xip_enabled) { - qspi_clock_div_restore(); - - if (deactivate && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { - (void) nrfx_qspi_deactivate(); - } - - pm_device_busy_clear(dev); - } - - qspi_unlock(dev); - -#if defined(CONFIG_PM_DEVICE_RUNTIME) - int rc = pm_device_runtime_put(dev); - - if (rc < 0) { - LOG_ERR("pm_device_runtime_put failed: %d", rc); - } -#endif + k_sem_give(&dev_data->trans); +#else /* CONFIG_MULTITHREADING */ + ARG_UNUSED(dev); +#endif /* CONFIG_MULTITHREADING */ } static inline void qspi_wait_for_completion(const struct device *dev, @@ -380,6 +359,89 @@ static void qspi_handler(nrfx_qspi_evt_t event, void *p_context) } } +static int qspi_device_init(const struct device *dev) +{ + struct qspi_nor_data *dev_data = dev->data; + + if (dev_data->xip_enabled) { + return 0; + } + +#ifdef CONFIG_PM_DEVICE_RUNTIME + return pm_device_runtime_get(dev); +#else + nrfx_err_t res; + int rc = 0; + + qspi_lock(dev); + + /* In multithreading, driver can call qspi_device_init more than once + * before calling qspi_device_uninit. Keepping count, so QSPI is + * uninitialized only at the last call (count == 0). + */ +#ifdef CONFIG_MULTITHREADING + k_sem_give(&dev_data->count); +#endif + + if (!qspi_initialized) { + const struct qspi_nor_config *dev_config = dev->config; + + res = nrfx_qspi_init(&dev_config->nrfx_cfg, + qspi_handler, + dev_data); + rc = qspi_get_zephyr_ret_code(res); + qspi_initialized = (rc == 0); + } + + qspi_unlock(dev); + + return rc; +#endif +} + +static void qspi_device_uninit(const struct device *dev) +{ + struct qspi_nor_data *dev_data = dev->data; + + if (dev_data->xip_enabled) { + return; + } + +#ifdef CONFIG_PM_DEVICE_RUNTIME + int rc = pm_device_runtime_put(dev); + + if (rc < 0) { + LOG_ERR("Failed to schedule device sleep: %d", rc); + } +#else + bool last = true; + + qspi_lock(dev); + +#ifdef CONFIG_MULTITHREADING + /* The last thread to finish using the driver uninit the QSPI */ + (void) k_sem_take(&dev_data->count, K_NO_WAIT); + last = (k_sem_count_get(&dev_data->count) == 0); +#endif + + if (last) { + while (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { + if (IS_ENABLED(CONFIG_MULTITHREADING)) { + k_msleep(50); + } else { + k_busy_wait(50000); + } + } + + nrfx_qspi_uninit(); + + qspi_initialized = false; + } + + qspi_unlock(dev); +#endif +} + /* QSPI send custom command. * * If this is used for both send and receive the buffer sizes must be @@ -435,8 +497,11 @@ static int qspi_send_cmd(const struct device *dev, const struct qspi_cmd *cmd, .wren = wren, }; + qspi_lock(dev); + int res = nrfx_qspi_cinstr_xfer(&cinstr_cfg, tx_buf, rx_buf); + qspi_unlock(dev); return qspi_get_zephyr_ret_code(res); } @@ -552,13 +617,29 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) /* QSPI erase */ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) { + /* address must be sector-aligned */ + if ((addr % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } + + /* size must be a non-zero multiple of sectors */ + if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } + const struct qspi_nor_config *params = dev->config; int rc, rc2; + rc = qspi_device_init(dev); + if (rc != 0) { + goto out; + } + qspi_trans_lock(dev); rc = qspi_nor_write_protection_set(dev, false); if (rc != 0) { - return rc; + goto out_trans_unlock; } + qspi_lock(dev); while (size > 0) { nrfx_err_t res = !NRFX_SUCCESS; uint32_t adj = 0; @@ -593,10 +674,20 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) break; } } + qspi_unlock(dev); rc2 = qspi_nor_write_protection_set(dev, true); - return rc != 0 ? rc : rc2; + if (!rc) { + rc = rc2; + } + +out_trans_unlock: + qspi_trans_unlock(dev); + +out: + qspi_device_uninit(dev); + return rc; } /* Configures QSPI memory for the transfer */ @@ -607,7 +698,22 @@ static int qspi_nrfx_configure(const struct device *dev) nrfx_err_t res; int rc; +#if defined(CONFIG_SOC_SERIES_NRF53X) + /* When the QSPI peripheral is activated, during the nrfx_qspi driver + * initialization, it reads the status of the connected flash chip. + * Make sure this transaction is performed with a valid base clock + * divider. + */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); +#endif + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); + +#if defined(CONFIG_SOC_SERIES_NRF53X) + /* Restore the default /4 divider after the QSPI initialization. */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); +#endif + rc = qspi_get_zephyr_ret_code(res); if (rc < 0) { return rc; @@ -708,7 +814,8 @@ static int qspi_nrfx_configure(const struct device *dev) return rc; } -static int qspi_rdid(const struct device *dev, uint8_t *id) +static int qspi_read_jedec_id(const struct device *dev, + uint8_t *id) { const struct qspi_buf rx_buf = { .buf = id, @@ -719,24 +826,18 @@ static int qspi_rdid(const struct device *dev, uint8_t *id) .rx_buf = &rx_buf, }; - return qspi_send_cmd(dev, &cmd, false); -} - -#if defined(CONFIG_FLASH_JESD216_API) + int rc = qspi_device_init(dev); -static int qspi_read_jedec_id(const struct device *dev, uint8_t *id) -{ - int rc; - - qspi_acquire(dev); - - rc = qspi_rdid(dev, id); - - qspi_release(dev); + if (rc == 0) { + rc = qspi_send_cmd(dev, &cmd, false); + } + qspi_device_uninit(dev); return rc; } +#if defined(CONFIG_FLASH_JESD216_API) + static int qspi_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { @@ -754,10 +855,17 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io2_level = true, .io3_level = true, }; - nrfx_err_t res; - qspi_acquire(dev); + int rc = qspi_device_init(dev); + nrfx_err_t res = NRFX_SUCCESS; + + if (rc != 0) { + LOG_DBG("qspi_device_init: %d", rc); + qspi_device_uninit(dev); + return rc; + } + qspi_lock(dev); res = nrfx_qspi_lfm_start(&cinstr_cfg); if (res != NRFX_SUCCESS) { LOG_DBG("lfm_start: %x", res); @@ -777,8 +885,8 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, } out: - qspi_release(dev); - + qspi_unlock(dev); + qspi_device_uninit(dev); return qspi_get_zephyr_ret_code(res); } @@ -793,7 +901,7 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, static inline int qspi_nor_read_id(const struct device *dev) { uint8_t id[SPI_NOR_MAX_ID_LEN]; - int rc = qspi_rdid(dev, id); + int rc = qspi_read_jedec_id(dev, id); if (rc != 0) { return -EIO; @@ -885,9 +993,6 @@ static inline nrfx_err_t read_non_aligned(const struct device *dev, static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, size_t size) { - const struct qspi_nor_config *params = dev->config; - nrfx_err_t res; - if (!dest) { return -EINVAL; } @@ -897,6 +1002,8 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return 0; } + const struct qspi_nor_config *params = dev->config; + /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -906,13 +1013,23 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return -EINVAL; } - qspi_acquire(dev); + int rc = qspi_device_init(dev); + + if (rc != 0) { + goto out; + } - res = read_non_aligned(dev, addr, dest, size); + qspi_lock(dev); - qspi_release(dev); + nrfx_err_t res = read_non_aligned(dev, addr, dest, size); - return qspi_get_zephyr_ret_code(res); + qspi_unlock(dev); + + rc = qspi_get_zephyr_ret_code(res); + +out: + qspi_device_uninit(dev); + return rc; } /* addr aligned, sptr not null, slen less than 4 */ @@ -977,9 +1094,6 @@ static int qspi_nor_write(const struct device *dev, off_t addr, const void *src, size_t size) { - const struct qspi_nor_config *params = dev->config; - int rc, rc2; - if (!src) { return -EINVAL; } @@ -994,6 +1108,9 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } + const struct qspi_nor_config *params = dev->config; + int rc, rc2; + /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1003,9 +1120,15 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - qspi_acquire(dev); + rc = qspi_device_init(dev); + if (rc != 0) { + goto out; + } + + qspi_trans_lock(dev); rc = qspi_nor_write_protection_set(dev, false); + qspi_lock(dev); if (rc == 0) { nrfx_err_t res; @@ -1021,28 +1144,23 @@ static int qspi_nor_write(const struct device *dev, off_t addr, rc = qspi_get_zephyr_ret_code(res); } + qspi_unlock(dev); rc2 = qspi_nor_write_protection_set(dev, true); - qspi_release(dev); + qspi_trans_unlock(dev); + if (rc == 0) { + rc = rc2; + } - return rc != 0 ? rc : rc2; +out: + qspi_device_uninit(dev); + return rc; } static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) { const struct qspi_nor_config *params = dev->config; - int rc; - - /* address must be sector-aligned */ - if ((addr % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } - - /* size must be a non-zero multiple of sectors */ - if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } /* affected region should be within device */ if (addr < 0 || @@ -1053,11 +1171,7 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - qspi_acquire(dev); - - rc = qspi_erase(dev, addr, size); - - qspi_release(dev); + int rc = qspi_erase(dev, addr, size); return rc; } @@ -1092,6 +1206,17 @@ static int qspi_nor_configure(const struct device *dev) return rc; } +#ifdef CONFIG_PM_DEVICE_RUNTIME + rc = pm_device_runtime_enable(dev); + if (rc < 0) { + LOG_ERR("Failed to enable runtime power management: %d", rc); + } else { + LOG_DBG("Runtime power management enabled"); + } +#else + qspi_device_uninit(dev); +#endif + /* now the spi bus is configured, we can verify the flash id */ if (qspi_nor_read_id(dev) != 0) { return -ENODEV; @@ -1119,24 +1244,10 @@ static int qspi_nor_init(const struct device *dev) IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), nrfx_isr, nrfx_qspi_irq_handler, 0); - qspi_clock_div_change(); - rc = qspi_nor_configure(dev); - qspi_clock_div_restore(); - -#ifdef CONFIG_PM_DEVICE_RUNTIME - int rc2 = pm_device_runtime_enable(dev); - - if (rc2 < 0) { - LOG_ERR("Failed to enable runtime power management: %d", rc2); - } else { - LOG_DBG("Runtime power management enabled"); - } -#endif - #ifdef CONFIG_NORDIC_QSPI_NOR_XIP - if (rc == 0) { + if (!rc) { /* Enable XIP mode for QSPI NOR flash, this will prevent the * flash from being powered down */ @@ -1272,97 +1383,108 @@ static int exit_dpd(const struct device *const dev) } #ifdef CONFIG_PM_DEVICE -static int qspi_suspend(const struct device *dev) -{ - const struct qspi_nor_config *dev_config = dev->config; - nrfx_err_t res; - int rc; - - res = nrfx_qspi_mem_busy_check(); - if (res != NRFX_SUCCESS) { - return -EBUSY; - } - - rc = enter_dpd(dev); - if (rc < 0) { - return rc; - } - - nrfx_qspi_uninit(); - - return pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); -} - -static int qspi_resume(const struct device *dev) -{ - const struct qspi_nor_config *dev_config = dev->config; - nrfx_err_t res; - int rc; - - rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - if (rc < 0) { - return rc; - } - - res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); - if (res != NRFX_SUCCESS) { - return -EIO; - } - - return exit_dpd(dev); -} - static int qspi_nor_pm_action(const struct device *dev, enum pm_device_action action) { + struct qspi_nor_data *dev_data = dev->data; + const struct qspi_nor_config *dev_config = dev->config; int rc; + nrfx_err_t res; if (pm_device_is_busy(dev)) { return -EBUSY; } - qspi_lock(dev); - qspi_clock_div_change(); - switch (action) { case PM_DEVICE_ACTION_SUSPEND: - rc = qspi_suspend(dev); +#ifndef CONFIG_PM_DEVICE_RUNTIME + /* If PM_DEVICE_RUNTIME, we don't uninit after RESUME */ + rc = qspi_device_init(dev); + if (rc < 0) { + return rc; + } +#endif + + if (dev_data->xip_enabled) { + return -EBUSY; + } + + if (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { + return -EBUSY; + } + + rc = enter_dpd(dev); + if (rc < 0) { + return rc; + } + + nrfx_qspi_uninit(); + rc = pinctrl_apply_state(dev_config->pcfg, + PINCTRL_STATE_SLEEP); + if (rc < 0) { + return rc; + } break; case PM_DEVICE_ACTION_RESUME: - rc = qspi_resume(dev); + rc = pinctrl_apply_state(dev_config->pcfg, + PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; + } + res = nrfx_qspi_init(&dev_config->nrfx_cfg, + qspi_handler, + dev_data); + if (res != NRFX_SUCCESS) { + return -EIO; + } + + rc = exit_dpd(dev); + if (rc < 0) { + return rc; + } + +#ifndef CONFIG_PM_DEVICE_RUNTIME + /* If PM_DEVICE_RUNTIME, we're immediately going to use the device */ + qspi_device_uninit(dev); +#endif break; default: - rc = -ENOTSUP; + return -ENOTSUP; } - qspi_clock_div_restore(); - qspi_unlock(dev); - - return rc; + return 0; } #endif /* CONFIG_PM_DEVICE */ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { struct qspi_nor_data *dev_data = dev->data; + int rc; if (dev_data->xip_enabled == enable) { return; } - qspi_acquire(dev); + rc = qspi_device_init(dev); + + if (rc != 0) { + LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", rc); + return; + } #if NRF_QSPI_HAS_XIPEN nrf_qspi_xip_set(NRF_QSPI, enable); #endif + qspi_lock(dev); if (enable) { (void)nrfx_qspi_activate(false); } dev_data->xip_enabled = enable; + qspi_unlock(dev); - qspi_release(dev); + qspi_device_uninit(dev); } #ifdef CONFIG_USERSPACE @@ -1380,12 +1502,11 @@ void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) #endif /* CONFIG_USERSPACE */ static struct qspi_nor_data qspi_nor_dev_data = { -#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) - .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), -#endif #ifdef CONFIG_MULTITHREADING + .trans = Z_SEM_INITIALIZER(qspi_nor_dev_data.trans, 1, 1), .sem = Z_SEM_INITIALIZER(qspi_nor_dev_data.sem, 1, 1), .sync = Z_SEM_INITIALIZER(qspi_nor_dev_data.sync, 0, 1), + .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), #endif /* CONFIG_MULTITHREADING */ }; From feb81afcb302368cebe23d1902ef94cb65aed90a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:18 +0000 Subject: [PATCH 4016/4498] Revert "[nrf fromtree] drivers: nrf_qspi_nor: Clean up handling of return values" This reverts commit 72a0fceed9941275c0c5b666363360a99f293d1e. Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 248 +++++++++++++++++------------------ 1 file changed, 123 insertions(+), 125 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 653f8b38f4e..945daa03d84 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -371,7 +371,7 @@ static int qspi_device_init(const struct device *dev) return pm_device_runtime_get(dev); #else nrfx_err_t res; - int rc = 0; + int ret = 0; qspi_lock(dev); @@ -389,13 +389,13 @@ static int qspi_device_init(const struct device *dev) res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - rc = qspi_get_zephyr_ret_code(res); - qspi_initialized = (rc == 0); + ret = qspi_get_zephyr_ret_code(res); + qspi_initialized = (ret == 0); } qspi_unlock(dev); - return rc; + return ret; #endif } @@ -408,10 +408,10 @@ static void qspi_device_uninit(const struct device *dev) } #ifdef CONFIG_PM_DEVICE_RUNTIME - int rc = pm_device_runtime_put(dev); + int ret = pm_device_runtime_put(dev); - if (rc < 0) { - LOG_ERR("Failed to schedule device sleep: %d", rc); + if (ret < 0) { + LOG_ERR("Failed to schedule device sleep: %d", ret); } #else bool last = true; @@ -526,27 +526,27 @@ static int qspi_rdsr(const struct device *dev, uint8_t sr_num) .op_code = opcode, .rx_buf = &sr_buf, }; - int rc = qspi_send_cmd(dev, &cmd, false); + int ret = qspi_send_cmd(dev, &cmd, false); - return (rc < 0) ? rc : sr; + return (ret < 0) ? ret : sr; } /* Wait until RDSR confirms write is not in progress. */ static int qspi_wait_while_writing(const struct device *dev) { - int rc; + int ret; do { - rc = qspi_rdsr(dev, 1); - } while ((rc >= 0) - && ((rc & SPI_NOR_WIP_BIT) != 0U)); + ret = qspi_rdsr(dev, 1); + } while ((ret >= 0) + && ((ret & SPI_NOR_WIP_BIT) != 0U)); - return (rc < 0) ? rc : 0; + return (ret < 0) ? ret : 0; } static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) { - int rc = 0; + int ret = 0; uint8_t opcode = SPI_NOR_CMD_WRSR; uint8_t length = 1; uint8_t sr_array[2] = {0}; @@ -559,12 +559,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) sr_array[0] = sr_val; #if SR1_WRITE_CLEARS_SR2 /* Writing sr1 clears sr2. need to read/modify/write both. */ - rc = qspi_rdsr(dev, 2); - if (rc < 0) { - LOG_ERR("RDSR for WRSR failed: %d", rc); - return rc; + ret = qspi_rdsr(dev, 2); + if (ret < 0) { + LOG_ERR("RDSR for WRSR failed: %d", ret); + return ret; } - sr_array[1] = rc; + sr_array[1] = ret; length = 2; #endif } else { /* sr_num == 2 */ @@ -574,12 +574,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) * Uses standard WRSR opcode */ sr_array[1] = sr_val; - rc = qspi_rdsr(dev, 1); - if (rc < 0) { - LOG_ERR("RDSR for WRSR failed: %d", rc); - return rc; + ret = qspi_rdsr(dev, 1); + if (ret < 0) { + LOG_ERR("RDSR for WRSR failed: %d", ret); + return ret; } - sr_array[0] = rc; + sr_array[0] = ret; length = 2; #elif IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_S2B1v6) /* Writing sr2 uses a dedicated WRSR2 command */ @@ -600,17 +600,17 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) .tx_buf = &sr_buf, }; - rc = qspi_send_cmd(dev, &cmd, true); + ret = qspi_send_cmd(dev, &cmd, true); /* Writing SR can take some time, and further * commands sent while it's happening can be * corrupted. Wait. */ - if (rc == 0) { - rc = qspi_wait_while_writing(dev); + if (ret == 0) { + ret = qspi_wait_while_writing(dev); } - return rc; + return ret; } #endif /* !IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_NONE) */ @@ -627,16 +627,16 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) return -EINVAL; } + int rv = 0; const struct qspi_nor_config *params = dev->config; - int rc, rc2; - rc = qspi_device_init(dev); - if (rc != 0) { + rv = qspi_device_init(dev); + if (rv != 0) { goto out; } qspi_trans_lock(dev); - rc = qspi_nor_write_protection_set(dev, false); - if (rc != 0) { + rv = qspi_nor_write_protection_set(dev, false); + if (rv != 0) { goto out_trans_unlock; } qspi_lock(dev); @@ -670,16 +670,16 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) size -= adj; } else { LOG_ERR("erase error at 0x%lx size %zu", (long)addr, size); - rc = qspi_get_zephyr_ret_code(res); + rv = qspi_get_zephyr_ret_code(res); break; } } qspi_unlock(dev); - rc2 = qspi_nor_write_protection_set(dev, true); + int rv2 = qspi_nor_write_protection_set(dev, true); - if (!rc) { - rc = rc2; + if (!rv) { + rv = rv2; } out_trans_unlock: @@ -687,7 +687,7 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) out: qspi_device_uninit(dev); - return rc; + return rv; } /* Configures QSPI memory for the transfer */ @@ -695,8 +695,6 @@ static int qspi_nrfx_configure(const struct device *dev) { struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - nrfx_err_t res; - int rc; #if defined(CONFIG_SOC_SERIES_NRF53X) /* When the QSPI peripheral is activated, during the nrfx_qspi driver @@ -707,16 +705,18 @@ static int qspi_nrfx_configure(const struct device *dev) nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); #endif - res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); + nrfx_err_t res = nrfx_qspi_init(&dev_config->nrfx_cfg, + qspi_handler, + dev_data); #if defined(CONFIG_SOC_SERIES_NRF53X) /* Restore the default /4 divider after the QSPI initialization. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); #endif - rc = qspi_get_zephyr_ret_code(res); - if (rc < 0) { - return rc; + int ret = qspi_get_zephyr_ret_code(res); + if (ret < 0) { + return ret; } #if DT_INST_NODE_HAS_PROP(0, rx_delay) @@ -736,9 +736,9 @@ static int qspi_nrfx_configure(const struct device *dev) * bootloader) might have set DPD mode before reboot. As a result, * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. */ - rc = exit_dpd(dev); - if (rc < 0) { - return rc; + ret = exit_dpd(dev); + if (ret < 0) { + return ret; } /* Set QE to match transfer mode. If not using quad @@ -769,28 +769,28 @@ static int qspi_nrfx_configure(const struct device *dev) return -EINVAL; #endif - rc = qspi_rdsr(dev, sr_num); - if (rc < 0) { - LOG_ERR("RDSR failed: %d", rc); - return rc; + ret = qspi_rdsr(dev, sr_num); + if (ret < 0) { + LOG_ERR("RDSR failed: %d", ret); + return ret; } - uint8_t sr = (uint8_t)rc; + uint8_t sr = (uint8_t)ret; bool qe_state = ((sr & qe_mask) != 0U); LOG_DBG("RDSR %02x QE %d need %d: %s", sr, qe_state, qe_value, (qe_state != qe_value) ? "updating" : "no-change"); - rc = 0; + ret = 0; if (qe_state != qe_value) { sr ^= qe_mask; - rc = qspi_wrsr(dev, sr, sr_num); + ret = qspi_wrsr(dev, sr, sr_num); } - if (rc < 0) { + if (ret < 0) { LOG_ERR("QE %s failed: %d", qe_value ? "set" : "clear", - rc); - return rc; + ret); + return ret; } #endif @@ -802,16 +802,16 @@ static int qspi_nrfx_configure(const struct device *dev) /* Call will send write enable before instruction if that * requirement is encoded in INST_0_4BA. */ - rc = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); + ret = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); - if (rc < 0) { - LOG_ERR("E4BA cmd issue failed: %d.", rc); + if (ret < 0) { + LOG_ERR("E4BA cmd issue failed: %d.", ret); } else { LOG_DBG("E4BA cmd issued."); } } - return rc; + return ret; } static int qspi_read_jedec_id(const struct device *dev, @@ -826,14 +826,14 @@ static int qspi_read_jedec_id(const struct device *dev, .rx_buf = &rx_buf, }; - int rc = qspi_device_init(dev); + int ret = qspi_device_init(dev); - if (rc == 0) { - rc = qspi_send_cmd(dev, &cmd, false); + if (ret == 0) { + ret = qspi_send_cmd(dev, &cmd, false); } qspi_device_uninit(dev); - return rc; + return ret; } #if defined(CONFIG_FLASH_JESD216_API) @@ -856,13 +856,13 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io3_level = true, }; - int rc = qspi_device_init(dev); + int ret = qspi_device_init(dev); nrfx_err_t res = NRFX_SUCCESS; - if (rc != 0) { - LOG_DBG("qspi_device_init: %d", rc); + if (ret != 0) { + LOG_DBG("qspi_device_init: %d", ret); qspi_device_uninit(dev); - return rc; + return ret; } qspi_lock(dev); @@ -901,9 +901,9 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, static inline int qspi_nor_read_id(const struct device *dev) { uint8_t id[SPI_NOR_MAX_ID_LEN]; - int rc = qspi_read_jedec_id(dev, id); + int ret = qspi_read_jedec_id(dev, id); - if (rc != 0) { + if (ret != 0) { return -EIO; } @@ -1109,7 +1109,6 @@ static int qspi_nor_write(const struct device *dev, off_t addr, } const struct qspi_nor_config *params = dev->config; - int rc, rc2; /* affected region should be within device */ if (addr < 0 || @@ -1120,18 +1119,18 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } + nrfx_err_t res = NRFX_SUCCESS; + + int rc = qspi_device_init(dev); - rc = qspi_device_init(dev); if (rc != 0) { goto out; } qspi_trans_lock(dev); - rc = qspi_nor_write_protection_set(dev, false); + res = qspi_nor_write_protection_set(dev, false); qspi_lock(dev); - if (rc == 0) { - nrfx_err_t res; - + if (!res) { if (size < 4U) { res = write_sub_word(dev, addr, src, size); } else if (!nrfx_is_in_ram(src) || @@ -1141,18 +1140,17 @@ static int qspi_nor_write(const struct device *dev, off_t addr, res = nrfx_qspi_write(src, size, addr); qspi_wait_for_completion(dev, res); } - - rc = qspi_get_zephyr_ret_code(res); } qspi_unlock(dev); - rc2 = qspi_nor_write_protection_set(dev, true); + int res2 = qspi_nor_write_protection_set(dev, true); qspi_trans_unlock(dev); - if (rc == 0) { - rc = rc2; + if (!res) { + res = res2; } + rc = qspi_get_zephyr_ret_code(res); out: qspi_device_uninit(dev); return rc; @@ -1171,24 +1169,24 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - int rc = qspi_erase(dev, addr, size); + int ret = qspi_erase(dev, addr, size); - return rc; + return ret; } static int qspi_nor_write_protection_set(const struct device *dev, bool write_protect) { - int rc = 0; + int ret = 0; struct qspi_cmd cmd = { .op_code = ((write_protect) ? SPI_NOR_CMD_WRDI : SPI_NOR_CMD_WREN), }; if (qspi_send_cmd(dev, &cmd, false) != 0) { - rc = -EIO; + ret = -EIO; } - return rc; + return ret; } /** @@ -1200,16 +1198,16 @@ static int qspi_nor_write_protection_set(const struct device *dev, */ static int qspi_nor_configure(const struct device *dev) { - int rc = qspi_nrfx_configure(dev); + int ret = qspi_nrfx_configure(dev); - if (rc != 0) { - return rc; + if (ret != 0) { + return ret; } #ifdef CONFIG_PM_DEVICE_RUNTIME - rc = pm_device_runtime_enable(dev); - if (rc < 0) { - LOG_ERR("Failed to enable runtime power management: %d", rc); + ret = pm_device_runtime_enable(dev); + if (ret < 0) { + LOG_ERR("Failed to enable runtime power management: %d", ret); } else { LOG_DBG("Runtime power management enabled"); } @@ -1233,12 +1231,12 @@ static int qspi_nor_configure(const struct device *dev) */ static int qspi_nor_init(const struct device *dev) { - const struct qspi_nor_config *dev_config = dev->config; int rc; + const struct qspi_nor_config *dev_config = dev->config; + int ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - if (rc < 0) { - return rc; + if (ret < 0) { + return ret; } IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), @@ -1319,11 +1317,11 @@ static int enter_dpd(const struct device *const dev) .op_code = SPI_NOR_CMD_DPD, }; uint32_t t_enter_dpd = DT_INST_PROP_OR(0, t_enter_dpd, 0); - int rc; + int ret; - rc = qspi_send_cmd(dev, &cmd, false); - if (rc < 0) { - return rc; + ret = qspi_send_cmd(dev, &cmd, false); + if (ret < 0) { + return ret; } if (t_enter_dpd) { @@ -1388,8 +1386,8 @@ static int qspi_nor_pm_action(const struct device *dev, { struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - int rc; - nrfx_err_t res; + int ret; + nrfx_err_t err; if (pm_device_is_busy(dev)) { return -EBUSY; @@ -1399,9 +1397,9 @@ static int qspi_nor_pm_action(const struct device *dev, case PM_DEVICE_ACTION_SUSPEND: #ifndef CONFIG_PM_DEVICE_RUNTIME /* If PM_DEVICE_RUNTIME, we don't uninit after RESUME */ - rc = qspi_device_init(dev); - if (rc < 0) { - return rc; + ret = qspi_device_init(dev); + if (ret < 0) { + return ret; } #endif @@ -1413,35 +1411,35 @@ static int qspi_nor_pm_action(const struct device *dev, return -EBUSY; } - rc = enter_dpd(dev); - if (rc < 0) { - return rc; + ret = enter_dpd(dev); + if (ret < 0) { + return ret; } nrfx_qspi_uninit(); - rc = pinctrl_apply_state(dev_config->pcfg, + ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); - if (rc < 0) { - return rc; + if (ret < 0) { + return ret; } break; case PM_DEVICE_ACTION_RESUME: - rc = pinctrl_apply_state(dev_config->pcfg, + ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - if (rc < 0) { - return rc; + if (ret < 0) { + return ret; } - res = nrfx_qspi_init(&dev_config->nrfx_cfg, + err = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - if (res != NRFX_SUCCESS) { + if (err != NRFX_SUCCESS) { return -EIO; } - rc = exit_dpd(dev); - if (rc < 0) { - return rc; + ret = exit_dpd(dev); + if (ret < 0) { + return ret; } #ifndef CONFIG_PM_DEVICE_RUNTIME @@ -1461,16 +1459,16 @@ static int qspi_nor_pm_action(const struct device *dev, void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { struct qspi_nor_data *dev_data = dev->data; - int rc; + int ret; if (dev_data->xip_enabled == enable) { return; } - rc = qspi_device_init(dev); + ret = qspi_device_init(dev); - if (rc != 0) { - LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", rc); + if (ret != 0) { + LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", ret); return; } From 0ac90e10db2cd2173f701ccbf13c03cbdba4cf75 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:18 +0000 Subject: [PATCH 4017/4498] Revert "[nrf fromtree] drivers: nrf_qspi_nor: Prevent reading status before sending RDPD" This reverts commit 93e398cd1fdd7abb0a6ec347ebaa09f1ff5172ab. Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 945daa03d84..c373a2c8ab7 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1339,34 +1339,15 @@ static int enter_dpd(const struct device *const dev) static int exit_dpd(const struct device *const dev) { if (IS_ENABLED(DT_INST_PROP(0, has_dpd))) { - nrf_qspi_pins_t pins; - nrf_qspi_pins_t disconnected_pins = { - .sck_pin = NRF_QSPI_PIN_NOT_CONNECTED, - .csn_pin = NRF_QSPI_PIN_NOT_CONNECTED, - .io0_pin = NRF_QSPI_PIN_NOT_CONNECTED, - .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, - .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, - .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, - }; struct qspi_cmd cmd = { .op_code = SPI_NOR_CMD_RDPD, }; uint32_t t_exit_dpd = DT_INST_PROP_OR(0, t_exit_dpd, 0); - nrfx_err_t res; - int rc; - - nrf_qspi_pins_get(NRF_QSPI, &pins); - nrf_qspi_pins_set(NRF_QSPI, &disconnected_pins); - res = nrfx_qspi_activate(true); - nrf_qspi_pins_set(NRF_QSPI, &pins); - - if (res != NRFX_SUCCESS) { - return -EIO; - } + int ret; - rc = qspi_send_cmd(dev, &cmd, false); - if (rc < 0) { - return rc; + ret = qspi_send_cmd(dev, &cmd, false); + if (ret < 0) { + return ret; } if (t_exit_dpd) { From aaf9974ce4f577402abe4ff5531b6d653725c0a4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:19 +0000 Subject: [PATCH 4018/4498] Revert "[nrf fromtree] drivers: nrf_qspi_nor: Activate QSPI peripheral when enabling XIP" This reverts commit 7d3f7bbf99454d8903c01490670a5a83d4fbd114. Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index c373a2c8ab7..e2ce6e6a706 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1457,9 +1457,6 @@ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) nrf_qspi_xip_set(NRF_QSPI, enable); #endif qspi_lock(dev); - if (enable) { - (void)nrfx_qspi_activate(false); - } dev_data->xip_enabled = enable; qspi_unlock(dev); From b7cfd8893805e2cbc4e96b85f32e69c8a4b5d447 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:19 +0000 Subject: [PATCH 4019/4498] Revert "[nrf fromtree] tfm: Enforce initial attestation with required key provisioned" This reverts commit 2ac74ca47b0ae06ff19755985e01b07b150f53b5. Signed-off-by: Dominik Ermel --- boards/arm/b_u585i_iot02a/Kconfig.defconfig | 4 ---- modules/trusted-firmware-m/Kconfig.tfm | 8 -------- modules/trusted-firmware-m/Kconfig.tfm.partitions | 1 - 3 files changed, 13 deletions(-) diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index 84e7bdb320a..78c0253fe41 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -22,10 +22,6 @@ config SYS_CLOCK_TICKS_PER_SEC if BUILD_WITH_TFM -# Initial Attestation key provisioned by the BL1 bootloader -config TFM_INITIAL_ATTESTATION_KEY - default y - config TFM_DUMMY_PROVISIONING default n diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index dc2ab24b17d..4fac243cf41 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -179,7 +179,6 @@ config TFM_PARTITION_PLATFORM_CUSTOM_REBOOT config TFM_DUMMY_PROVISIONING bool "Provision with dummy values. NOT to be used in production" - select TFM_INITIAL_ATTESTATION_KEY default y help If this option is enabled (as it is by default), a set of dummy @@ -189,13 +188,6 @@ config TFM_DUMMY_PROVISIONING This option MUST not be used in production hardware, as the keys are insecure. -config TFM_INITIAL_ATTESTATION_KEY - bool - help - Hidden option to mark that the TF-M platform has an initial - attestation key, which is a requirement for the Initial Attestation - partition. - config TFM_BL2_NOT_SUPPORTED bool help diff --git a/modules/trusted-firmware-m/Kconfig.tfm.partitions b/modules/trusted-firmware-m/Kconfig.tfm.partitions index 67b46f5328b..cd9aaadb1ec 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.partitions +++ b/modules/trusted-firmware-m/Kconfig.tfm.partitions @@ -44,7 +44,6 @@ config TFM_PARTITION_CRYPTO config TFM_PARTITION_INITIAL_ATTESTATION bool "Secure partition 'Initial Attestation'" depends on TFM_PARTITION_CRYPTO - depends on TFM_INITIAL_ATTESTATION_KEY default n help Setting this option will cause '-DTFM_PARTITION_INITIAL_ATTESTATION' From 9c2d1803ebd1d6a47c4d8dcfdd77f5b6480bcad6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:19 +0000 Subject: [PATCH 4020/4498] Revert "[nrf fromtree] tfm: Harded build against TF-M built with unsecure keys" This reverts commit ec48dcb2ee4973bee58fbe610750fe62635a0e3f. Signed-off-by: Dominik Ermel --- boards/arm/b_u585i_iot02a/Kconfig.defconfig | 7 ------- modules/trusted-firmware-m/CMakeLists.txt | 17 +---------------- modules/trusted-firmware-m/Kconfig.tfm | 11 ----------- scripts/kconfig/hardened.csv | 1 - 4 files changed, 1 insertion(+), 35 deletions(-) diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index 78c0253fe41..93748d0dcf2 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -20,11 +20,4 @@ config USE_DT_CODE_PARTITION config SYS_CLOCK_TICKS_PER_SEC default 4096 if STM32_LPTIM_TIMER -if BUILD_WITH_TFM - -config TFM_DUMMY_PROVISIONING - default n - -endif # BUILD_WITH_TFM - endif # BOARD_B_U585I_IOT02A diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index ad1109d849b..177a47e28d6 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -95,12 +95,6 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_NUMBER=${CONFIG_TFM_MCUBOOT_IMAGE_NUMBER}) endif() - if (CONFIG_TFM_DUMMY_PROVISIONING) - list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=ON) - else() - list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=OFF) - endif() - if (CONFIG_TFM_EXCEPTION_INFO_DUMP) list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=ON) else() @@ -585,13 +579,4 @@ if (CONFIG_BUILD_WITH_TFM) ${MERGED_FILE} ) endif() - - if(CONFIG_TFM_DUMMY_PROVISIONING) - message(WARNING - "TFM_DUMMY_PROVISIONING is enabled: - The device will be provisioned using dummy keys and is NOT secure! - This is not suitable for production" - ) - endif() - -endif() # CONFIG_BUILD_WITH_TFM +endif() diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 4fac243cf41..2a5edb64343 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -177,17 +177,6 @@ config TFM_PARTITION_PLATFORM_CUSTOM_REBOOT Instead the application will have to override the weak ARM implementation of sys_arch_reset(). -config TFM_DUMMY_PROVISIONING - bool "Provision with dummy values. NOT to be used in production" - default y - help - If this option is enabled (as it is by default), a set of dummy - keys / data will be provisioned. The dummy IAK matches the IAK tested - by the TF-M tests, and the dummy bl2 ROTPKs match the dummy bl2 keys - used by default. - This option MUST not be used in production hardware, as the keys are - insecure. - config TFM_BL2_NOT_SUPPORTED bool help diff --git a/scripts/kconfig/hardened.csv b/scripts/kconfig/hardened.csv index 6a2937df65c..a09defdc756 100644 --- a/scripts/kconfig/hardened.csv +++ b/scripts/kconfig/hardened.csv @@ -39,7 +39,6 @@ TEST_RANDOM_GENERATOR,n TEST_SHELL,n TEST_USERSPACE,n TFM_CMAKE_BUILD_TYPE_DEBUG,n -TFM_DUMMY_PROVISIONING,n THREAD_MONITOR,n THREAD_NAME,n TIMER_RANDOM_GENERATOR,n From 46b6c2666ace17a75ae75ebdbb75b1fa04759622 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:19 +0000 Subject: [PATCH 4021/4498] Revert "[nrf noup] soc: arm: nRF91: Add SPU Flash/RAM alignment" This reverts commit 89be4330a38498731fe612f1343624fc3d0a098e. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf91/Kconfig.series | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 9e0e477e851..1f2f233edb9 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -27,23 +27,9 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral -config NRF_SPU_FLASH_REGION_ALIGNMENT - hex - default 0x8000 - help - FLASH regions must be aligned to this value due to SPU HW - limitations. - config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral - -config NRF_SPU_RAM_REGION_ALIGNMENT - hex - default 0x2000 - help - RAM regions must be aligned to this value due to SPU HW - limitations. endif From 65db981f1cf1b071af160dffa3ca0c07a8e8180c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:20 +0000 Subject: [PATCH 4022/4498] Revert "[nrf noup] soc: arm: nRF53: Add SPU Flash/RAM alignment" This reverts commit 1f49692993f6ad7f1ee1e19ff27d3ff56659b23e. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 1c8527e1716..09b15948da0 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -104,26 +104,12 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral -config NRF_SPU_FLASH_REGION_ALIGNMENT - hex - default 0x4000 - help - FLASH regions must be aligned to this value due to SPU HW - limitations. - config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral -config NRF_SPU_RAM_REGION_ALIGNMENT - hex - default 0x2000 - help - RAM regions must be aligned to this value due to SPU HW - limitations. - config SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 bool depends on NRF_SOC_SECURE_SUPPORTED From 9ea27a5acc420a7fac8cc68f437327ddc708724a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:20 +0000 Subject: [PATCH 4023/4498] Revert "[nrf fromtree] soc: arm: Remove CPU_HAS_NRF_IDAU's dependencies" This reverts commit 92c50d89502df25b5ee0a7b5f0cdf7641d1b59d8. Signed-off-by: Dominik Ermel --- soc/arm/Kconfig | 16 ++++++++++++++++ soc/arm/nordic_nrf/nrf53/Kconfig.soc | 12 ------------ soc/arm/nordic_nrf/nrf91/Kconfig.series | 14 -------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/soc/arm/Kconfig b/soc/arm/Kconfig index 461f0b41f84..443a0031189 100644 --- a/soc/arm/Kconfig +++ b/soc/arm/Kconfig @@ -34,12 +34,28 @@ config CPU_HAS_ARM_SAU config CPU_HAS_NRF_IDAU bool + depends on SOC_SERIES_NRF91X || SOC_NRF5340_CPUAPP select CPU_HAS_TEE help MCU implements the nRF (vendor-specific) Security Attribution Unit. (IDAU: "Implementation-Defined Attribution Unit", in accordance with ARM terminology). +if CPU_HAS_NRF_IDAU +config NRF_SPU_FLASH_REGION_SIZE + hex + default 0x8000 if SOC_SERIES_NRF91X + default 0x4000 if SOC_NRF5340_CPUAPP + help + FLASH region size for the NRF_SPU peripheral + +config NRF_SPU_RAM_REGION_SIZE + hex + default 0x2000 if SOC_SERIES_NRF91X || SOC_NRF5340_CPUAPP + help + RAM region size for the NRF_SPU peripheral +endif + config HAS_SWO bool help diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 09b15948da0..2cd934af324 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -98,18 +98,6 @@ config SOC_DCDC_NRF53X_HV help Enable nRF53 series System on Chip High Voltage DC/DC converter. -config NRF_SPU_FLASH_REGION_SIZE - hex - default 0x4000 - help - FLASH region size for the NRF_SPU peripheral - -config NRF_SPU_RAM_REGION_SIZE - hex - default 0x2000 - help - RAM region size for the NRF_SPU peripheral - config SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 bool depends on NRF_SOC_SECURE_SUPPORTED diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 1f2f233edb9..fd8f5b04d7a 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -19,17 +19,3 @@ config SOC_SERIES_NRF91X select HAS_POWEROFF help Enable support for NRF91 MCU series - -if SOC_SERIES_NRF91X -config NRF_SPU_FLASH_REGION_SIZE - hex - default 0x8000 - help - FLASH region size for the NRF_SPU peripheral - -config NRF_SPU_RAM_REGION_SIZE - hex - default 0x2000 - help - RAM region size for the NRF_SPU peripheral -endif From 37873f0312c9589493cbe836c47f9afbde4abad2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:20 +0000 Subject: [PATCH 4024/4498] Revert "[nrf fromlist] soc: nordic_nrf: Enable the TF-M NS storage partition for nordic boards" This reverts commit 462ad3659295cc639b3c159573136731141a06cc. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/CMakeLists.txt | 4 ---- soc/arm/nordic_nrf/Kconfig | 4 ---- 2 files changed, 8 deletions(-) diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 3b097d73569..47364b35ffb 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -25,8 +25,4 @@ if(CONFIG_BUILD_WITH_TFM) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} ) - - set_property(TARGET zephyr_property_target - APPEND PROPERTY TFM_CMAKE_OPTIONS -DNRF_NS_STORAGE=${CONFIG_TFM_NRF_NS_STORAGE} - ) endif() diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 0372492cd7d..19e49c05454 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -45,10 +45,6 @@ config TFM_LOG_LEVEL_SILENCE Disable TF-M secure output if the uart1 node has not assigned GPIO pins using pinctrl. -config TFM_NRF_NS_STORAGE - bool "TF-M non-secure storage partition" - default y - endif # BUILD_WITH_TFM From 37484cc81d27b05a485d9b660b09ccc0fb59be64 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:20 +0000 Subject: [PATCH 4025/4498] Revert "[nrf fromtree] net: openthread: Openthread upmerge to `4ed44bc`" This reverts commit 919457f5c1d9d491033b23efcf77197d687422a6. Signed-off-by: Dominik Ermel --- modules/openthread/CMakeLists.txt | 6 ------ modules/openthread/Kconfig.features | 3 --- west.yml | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 3796ec8f177..31bff57d776 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -340,12 +340,6 @@ else() set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) endif() -if(CONFIG_OPENTHREAD_MULTIPAN_RCP) - set(OT_MULTIPAN_RCP ON CACHE BOOL "Enable Multi-PAN RCP" FORCE) -else() - set(OT_MULTIPAN_RCP OFF CACHE BOOL "Enable Multi-PAN RCP" FORCE) -endif() - if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 2be5332cde3..bd8a05ed9b9 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -218,9 +218,6 @@ config OPENTHREAD_MLR help Enable Multicast Listener Registration support for Thread 1.2 -config OPENTHREAD_MULTIPAN_RCP - bool "OpenThread multipan rcp" - config OPENTHREAD_MULTIPLE_INSTANCE bool "OpenThread multiple instances" diff --git a/west.yml b/west.yml index 988343a9d10..475e8a7cc25 100644 --- a/west.yml +++ b/west.yml @@ -303,7 +303,7 @@ manifest: revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 path: modules/lib/open-amp - name: openthread - revision: 4ed44bc7d58d9a98c6cca13a50d38129045ab3df + revision: 6edb06e4e0472411200ce2a084a783eaf3faffe3 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 578048f085017b64f49ce07e9eb1222301636168 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:21 +0000 Subject: [PATCH 4026/4498] Revert "[nrf fromlist] manifest: hal_nordic: Update revision with fixed workaround in nrfx_qspi" This reverts commit e0dc936a4af5550f15d9e37ab9b44db5de452ee0. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 475e8a7cc25..93db410ea77 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: b9633ecea67bf52925d4c61455046223b46402b1 + revision: 2ff8ce6e6ca131d87699dba260f3c0cc4a6cc365 path: modules/hal/nordic groups: - hal From 4d28b7510da0a4267a93859d9e2f8d6907e72601 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:21 +0000 Subject: [PATCH 4027/4498] Revert "[nrf fromtree] scripts/pylib/twister/twisterlib: Support multiple `--pytest-args`" This reverts commit ad95bc81b8b9d44431c092a3cee4e7204dfceba4. Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 2 -- .../pylib/twister/twisterlib/environment.py | 3 +-- scripts/pylib/twister/twisterlib/harness.py | 19 +++++++++---------- .../pytest_integration/test_harness_pytest.py | 5 ++--- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 957ff8c773b..e8ad82654c1 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -67,8 +67,6 @@ For instance, one can use a command: --pytest-args='-k test_shell_print_version' -Note that ``--pytest-args`` can be passed multiple times to pass several arguments to the pytest. - Helpers & fixtures ================== diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index d1ce56711c2..89377e8b961 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -211,8 +211,7 @@ def add_parse_arguments(parser = None): and 'fifo_loop' is a name of a function found in main.c without test prefix. """) - parser.add_argument( - "--pytest-args", action="append", + parser.add_argument("--pytest-args", help="""Pass additional arguments to the pytest subprocess. This parameter will override the pytest_args from the harness_config in YAML file. """) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index edb053232b9..203adf4560c 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -262,6 +262,15 @@ def generate_command(self): command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) + if handler.options.pytest_args: + command.append(handler.options.pytest_args) + if pytest_args_yaml: + logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' + 'in the command line will override the pytest_args defined ' + f'in the YAML file {pytest_args_yaml}') + else: + command.extend(pytest_args_yaml) + if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') @@ -281,16 +290,6 @@ def generate_command(self): command.append('--device-type=custom') else: raise PytestHarnessException(f'Handling of handler {handler.type_str} not implemented yet') - - if handler.options.pytest_args: - command.extend(handler.options.pytest_args) - if pytest_args_yaml: - logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' - 'in the command line will override the pytest_args defined ' - f'in the YAML file {pytest_args_yaml}') - else: - command.extend(pytest_args_yaml) - return command def _generate_parameters_for_hardware(self, handler: Handler): diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index befd384be37..fc60b99e0d1 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -71,13 +71,12 @@ def test_pytest_command_extra_args(testinstance: TestInstance): def test_pytest_command_extra_args_in_options(testinstance: TestInstance): pytest_harness = Pytest() pytest_args_from_yaml = '-k test_from_yaml' - pytest_args_from_cmd = ['-k', 'test_from_cmd'] + pytest_args_from_cmd = '-k test_from_cmd' testinstance.testsuite.harness_config['pytest_args'] = [pytest_args_from_yaml] testinstance.handler.options.pytest_args = pytest_args_from_cmd pytest_harness.configure(testinstance) command = pytest_harness.generate_command() - assert pytest_args_from_cmd[0] in command - assert pytest_args_from_cmd[1] in command + assert pytest_args_from_cmd in command assert pytest_args_from_yaml not in command From 36162fec46dc7fd19850c16c55501bfdb5240d50 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:21 +0000 Subject: [PATCH 4028/4498] Revert "[nrf fromtree] twister: pytest: Add --pytest-args to Twister command line" This reverts commit 9566a94fc5175eae833af9ec264f68bcf16bc3f6. Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 10 --- .../pylib/twister/twisterlib/environment.py | 5 -- scripts/pylib/twister/twisterlib/harness.py | 19 ++---- .../pytest_integration/test_harness_pytest.py | 66 ------------------- 4 files changed, 4 insertions(+), 96 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index e8ad82654c1..087c45bcce8 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -56,16 +56,6 @@ Pytest scans the given locations looking for tests, following its default `discovery rules `_ One can also pass some extra arguments to the pytest from yaml file using ``pytest_args`` keyword under ``harness_config``, e.g.: ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. -There is also an option to pass ``--pytest-args`` through Twister command line parameters. -This can be particularly useful when one wants to select a specific testcase from a test suite. -For instance, one can use a command: - -.. code-block:: console - - $ ./scripts/twister --platform native_sim -T samples/subsys/testsuite/pytest/shell \ - -s samples/subsys/testsuite/pytest/shell/sample.pytest.shell \ - --pytest-args='-k test_shell_print_version' - Helpers & fixtures ================== diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 89377e8b961..b5018bc1f01 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -211,11 +211,6 @@ def add_parse_arguments(parser = None): and 'fifo_loop' is a name of a function found in main.c without test prefix. """) - parser.add_argument("--pytest-args", - help="""Pass additional arguments to the pytest subprocess. This parameter - will override the pytest_args from the harness_config in YAML file. - """) - valgrind_asan_group.add_argument( "--enable-valgrind", action="store_true", help="""Run binary through valgrind and check for several memory access diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 203adf4560c..bd86df1b4df 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -245,9 +245,8 @@ def pytest_run(self, timeout): def generate_command(self): config = self.instance.testsuite.harness_config - handler: Handler = self.instance.handler pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] - pytest_args_yaml = config.get('pytest_args', []) if config else [] + pytest_args = config.get('pytest_args', []) if config else [] pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None command = [ 'pytest', @@ -261,19 +260,12 @@ def generate_command(self): ] command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) - - if handler.options.pytest_args: - command.append(handler.options.pytest_args) - if pytest_args_yaml: - logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' - 'in the command line will override the pytest_args defined ' - f'in the YAML file {pytest_args_yaml}') - else: - command.extend(pytest_args_yaml) - + command.extend(pytest_args) if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') + handler: Handler = self.instance.handler + if handler.options.verbose > 1: command.extend([ '--log-cli-level=DEBUG', @@ -433,9 +425,6 @@ def _parse_report_file(self, report): tc.status = 'error' tc.reason = elem.get('message') tc.output = elem.text - else: - self.state = 'skipped' - self.instance.reason = 'No tests collected' class Gtest(Harness): diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index fc60b99e0d1..150980059b3 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -25,7 +25,6 @@ def testinstance() -> TestInstance: testinstance.handler = mock.Mock() testinstance.handler.options = mock.Mock() testinstance.handler.options.verbose = 1 - testinstance.handler.options.pytest_args = None testinstance.handler.type_str = 'native' return testinstance @@ -68,18 +67,6 @@ def test_pytest_command_extra_args(testinstance: TestInstance): assert c in command -def test_pytest_command_extra_args_in_options(testinstance: TestInstance): - pytest_harness = Pytest() - pytest_args_from_yaml = '-k test_from_yaml' - pytest_args_from_cmd = '-k test_from_cmd' - testinstance.testsuite.harness_config['pytest_args'] = [pytest_args_from_yaml] - testinstance.handler.options.pytest_args = pytest_args_from_cmd - pytest_harness.configure(testinstance) - command = pytest_harness.generate_command() - assert pytest_args_from_cmd in command - assert pytest_args_from_yaml not in command - - @pytest.mark.parametrize( ('pytest_root', 'expected'), [ @@ -235,56 +222,3 @@ def test_skip_2(): assert len(testinstance.testcases) == 2 for tc in testinstance.testcases: assert tc.status == "skipped" - - -def test_if_report_with_filter(pytester, testinstance: TestInstance): - test_file_content = textwrap.dedent(""" - import pytest - def test_A(): - pass - def test_B(): - pass - """) - test_file = pytester.path / 'test_filter.py' - test_file.write_text(test_file_content) - report_file = pytester.path / 'report.xml' - result = pytester.runpytest( - str(test_file), - '-k', 'test_B', - f'--junit-xml={str(report_file)}' - ) - result.assert_outcomes(passed=1) - assert report_file.is_file() - - pytest_harness = Pytest() - pytest_harness.configure(testinstance) - pytest_harness.report_file = report_file - pytest_harness._update_test_status() - assert pytest_harness.state == "passed" - assert testinstance.status == "passed" - assert len(testinstance.testcases) == 1 - - -def test_if_report_with_no_collected(pytester, testinstance: TestInstance): - test_file_content = textwrap.dedent(""" - import pytest - def test_A(): - pass - """) - test_file = pytester.path / 'test_filter.py' - test_file.write_text(test_file_content) - report_file = pytester.path / 'report.xml' - result = pytester.runpytest( - str(test_file), - '-k', 'test_B', - f'--junit-xml={str(report_file)}' - ) - result.assert_outcomes(passed=0) - assert report_file.is_file() - - pytest_harness = Pytest() - pytest_harness.configure(testinstance) - pytest_harness.report_file = report_file - pytest_harness._update_test_status() - assert pytest_harness.state == "skipped" - assert testinstance.status == "skipped" From d001b9e71cc2d80e7c6711a17d2f3ddf465d4914 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:21 +0000 Subject: [PATCH 4029/4498] Revert "[nrf fromtree] net: l2: ieee802154: pkt: fix cpp build failure" This reverts commit e97dfe6a6edf3ca0e6b4a1a07c585d2f9be9f6ff. Signed-off-by: Dominik Ermel --- include/zephyr/net/ieee802154_pkt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index a1dca472448..23921467d96 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -92,7 +92,7 @@ static inline void *net_pkt_cb(struct net_pkt *pkt); static inline struct net_pkt_cb_ieee802154 *net_pkt_cb_ieee802154(struct net_pkt *pkt) { - return (struct net_pkt_cb_ieee802154 *)net_pkt_cb(pkt); + return net_pkt_cb(pkt); }; static inline uint8_t net_pkt_ieee802154_lqi(struct net_pkt *pkt) From 0bdf1a8bbab6da0c9acfdf06cfbfd47bea3e2594 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:22 +0000 Subject: [PATCH 4030/4498] Revert "[nrf fromlist] wifi: shell: Add long arguments to help" This reverts commit f721e835805a6e6bae6e7c491f3d4369d64412e4. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 90dbd1588f7..1d7499e11bd 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1271,10 +1271,10 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, {"sta", no_argument, 0, 's'}, {"monitor", no_argument, 0, 'm'}, - {"tx-injection", no_argument, 0, 't'}, + {"TX-injection", no_argument, 0, 't'}, {"promiscuous", no_argument, 0, 'p'}, {"ap", no_argument, 0, 'a'}, {"softap", no_argument, 0, 'k'}, @@ -1381,7 +1381,7 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, {"channel", required_argument, 0, 'c'}, {"get", no_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, @@ -1487,8 +1487,8 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, - {"capture-len", optional_argument, 0, 'b'}, + static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + {"capture_len", optional_argument, 0, 'b'}, {"all", no_argument, 0, 'a'}, {"mgmt", no_argument, 0, 'm'}, {"ctrl", no_argument, 0, 'c'}, @@ -1679,15 +1679,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" - "[-i, --if-index ] : Interface index.\n" - "[-s, --sta] : Station mode.\n" - "[-m, --monitor] : Monitor mode.\n" - "[-p, --promiscuous] : Promiscuous mode.\n" - "[-t, --tx-injection] : TX-Injection mode.\n" - "[-a, --ap] : AP mode.\n" - "[-k, --softap] : Softap mode.\n" - "[-h, --help] : Help.\n" - "[-g, --get] : Get current mode for a specific interface index.\n" + "[-i] : Interface index - optional argument\n" + "[-s] : Station mode.\n" + "[-m] : Monitor mode.\n" + "[-p] : Promiscuous mode.\n" + "[-t] : TX-Injection mode.\n" + "[-a] : AP mode.\n" + "[-k] : Softap mode.\n" + "[-h] : Help.\n" + "[-g] : Get current mode for a specific interface index.\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" @@ -1699,14 +1699,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" "parameters:" - "[-i, --if-index ] : Interface index.\n" - "[-a, --all] : Enable all packet filter modes\n" - "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" - "[-c, --ctrl] : Enable control packets to be allowed up the stack.\n" - "[-d, --data] : Enable Data packets to be allowed up the stack.\n" - "[-g, --get] : Get current filter settings for a specific interface index.\n" - "[-b, --capture-len ] : Capture length buffer size for each packet to be captured\n" - "[-h, --help] : Help.\n" + "[-i] : Interface index - optional argument.\n" + "[-a] : Enable all packet filter modes\n" + "[-m] : Enable management packets to allowed up the stack.\n" + "[-c] : Enable control packets to be allowed up the stack.\n" + "[-d] : Enable Data packets to be allowed up the stack.\n" + "[-g] : Get current filter settings for a specific interface index.\n" + "<-b> : Capture length buffer size for each packet to be captured - optional argument.\n" + "<-h> : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" @@ -1718,10 +1718,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" "parameters:" - "[-i, --if-index ] : Interface index.\n" - "[-c, --channel ] : Set a specific channel number to the lower layer.\n" - "[-g, --get] : Get current set channel number from the lower layer.\n" - "[-h, --help] : Help.\n" + "[-i] : Interface index - optional argument.\n" + "[-c] : Set a specific channel number to the lower layer.\n" + "[-g] : Get current set channel number from the lower layer.\n" + "[-h] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" From 0b1d7f89c717dd25b8d3190168185b2f91239868 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:22 +0000 Subject: [PATCH 4031/4498] Revert "[nrf fromlist] wifi: shell: Enforce argument count checks" This reverts commit bebc385d82e4fd230ac7afd0d580a8045624e921. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 74 +++++++++++++-------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 1d7499e11bd..95c28e5d7e9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1594,43 +1594,37 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg } SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, - SHELL_CMD_ARG(disable, NULL, + SHELL_CMD(disable, NULL, "Disable Access Point mode", - cmd_wifi_ap_disable, - 1, 0), - SHELL_CMD_ARG(enable, NULL, " [channel] [PSK]", - cmd_wifi_ap_enable, - 2, 1), + cmd_wifi_ap_disable), + SHELL_CMD(enable, NULL, " [channel] [PSK]", + cmd_wifi_ap_enable), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, - SHELL_CMD_ARG(quick_setup, NULL, " Start a TWT flow with defaults:\n" + SHELL_CMD(quick_setup, NULL, " Start a TWT flow with defaults:\n" " \n", - cmd_wifi_twt_setup_quick, - 3, 0), - SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" + cmd_wifi_twt_setup_quick), + SHELL_CMD(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " " \n", - cmd_wifi_twt_setup, - 11, 0), - SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" + cmd_wifi_twt_setup), + SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" " \n", - cmd_wifi_twt_teardown, - 5, 0), - SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows\n", - cmd_wifi_twt_teardown_all, - 1, 0), + cmd_wifi_twt_teardown), + SHELL_CMD(teardown_all, NULL, " Teardown all TWT flows\n", + cmd_wifi_twt_teardown_all), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands", NULL), - SHELL_CMD_ARG(connect, NULL, + SHELL_CMD(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" "[channel number: 0 means all]\n" @@ -1639,21 +1633,18 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", - cmd_wifi_connect, - 2, 5), - SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", - cmd_wifi_disconnect, - 1, 0), - SHELL_CMD_ARG(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", - cmd_wifi_ps, - 1, 1), + cmd_wifi_connect), + SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", + cmd_wifi_disconnect), + SHELL_CMD(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", + cmd_wifi_ps), SHELL_CMD_ARG(ps_mode, NULL, "\n", cmd_wifi_ps_mode, 2, 0), - SHELL_CMD_ARG(scan, NULL, + SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs\n" "OPTIONAL PARAMETERS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" @@ -1664,19 +1655,17 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" "[-h, --help] : Print out the help for the scan command.", - cmd_wifi_scan, - 1, 8), - SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats, 1, 0), - SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status, 1, 0), + cmd_wifi_scan), + SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), + SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), - SHELL_CMD_ARG(reg_domain, NULL, + SHELL_CMD(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", - cmd_wifi_reg_domain, - 2, 1), - SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" + cmd_wifi_reg_domain), + SHELL_CMD(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" "[-i] : Interface index - optional argument\n" @@ -1692,9 +1681,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" "wifi mode -i1 -sp\n", - cmd_wifi_mode, - 1, 9), - SHELL_CMD_ARG(packet_filter, NULL, "mode filter setting\n" + cmd_wifi_mode), + SHELL_CMD(packet_filter, NULL, "mode filter setting\n" "This command is used to set packet filter setting when\n" "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" @@ -1711,9 +1699,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" "wifi packet_filter -i1 -md\n", - cmd_wifi_packet_filter, - 1, 8), - SHELL_CMD_ARG(channel, NULL, "wifi channel setting\n" + cmd_wifi_packet_filter), + SHELL_CMD(channel, NULL, "wifi channel setting\n" "This command is used to set the channel when\n" "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" @@ -1726,8 +1713,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" "wifi -i1 -c5\n", - cmd_wifi_channel, - 1, 4), + cmd_wifi_channel), SHELL_CMD_ARG(ps_timeout, NULL, " - PS inactivity timer(in ms)", From 8df851b46fd1f0b3a69904b09ab1b61b345b1583 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:22 +0000 Subject: [PATCH 4032/4498] Revert "[nrf fromlist] wifi: shell: Add missing security options" This reverts commit 7c23186c1282125353cacca44899f030706b2b68. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 95c28e5d7e9..26ea9f50775 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1630,7 +1630,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[channel number: 0 means all]\n" "[PSK: valid only for secure SSIDs]\n" "[Security type: valid only for secure SSIDs]\n" - "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" + "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect), From 0402834fd90dfb0a731fc2ddcf4e3dc11e3c26e0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:23 +0000 Subject: [PATCH 4033/4498] Revert "[nrf fromlist] wifi: shell: Fix PS mode help" This reverts commit 9c2c52a44a28f974fa1280b35f06875b067c69ea. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 26ea9f50775..973fbb63535 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1640,7 +1640,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_ps), SHELL_CMD_ARG(ps_mode, NULL, - "\n", + "\n" + "", cmd_wifi_ps_mode, 2, 0), @@ -1728,7 +1729,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD_ARG(ps_wakeup_mode, NULL, - "\n", + " : Set PS wake up mode to DTIM interval\n" + " : Set PS wake up mode to listen interval", cmd_wifi_ps_wakeup_mode, 2, 0), From 764acfba75beca8f6fb6ba8d9f477125e38cd656 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:23 +0000 Subject: [PATCH 4034/4498] Revert "[nrf fromlist] wifi: shell: Fix brackets type for optional params" This reverts commit ad503caacd6004efb4f386ce526f8f1f8e1952a0. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 973fbb63535..c4d5c3ec657 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1627,11 +1627,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" - "[channel number: 0 means all]\n" - "[PSK: valid only for secure SSIDs]\n" - "[Security type: valid only for secure SSIDs]\n" + "\n" + "\n" + "\n" "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" - "[MFP (optional: needs security type to be specified)]\n" + "\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect), SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", @@ -1663,7 +1663,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" - "[-f]: Force to use this regulatory hint over any other regulatory hints\n" + "-f: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), SHELL_CMD(mode, NULL, "mode operational setting\n" From 16269a6ff9c9ff663fba087b01786baacfa329ed Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:23 +0000 Subject: [PATCH 4035/4498] Revert "[nrf fromlist] wifi: shell: Fix unbalanced braces" This reverts commit e3429fadeece82ab46940a23edf4dc0954d9a718. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index c4d5c3ec657..280ebd90390 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1669,15 +1669,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" - "[-i] : Interface index - optional argument\n" - "[-s] : Station mode.\n" - "[-m] : Monitor mode.\n" - "[-p] : Promiscuous mode.\n" - "[-t] : TX-Injection mode.\n" - "[-a] : AP mode.\n" - "[-k] : Softap mode.\n" - "[-h] : Help.\n" - "[-g] : Get current mode for a specific interface index.\n" + "[-i : Interface index - optional argument\n" + "[-s : Station mode.\n" + "[-m : Monitor mode.\n" + "[-p : Promiscuous mode.\n" + "[-t : TX-Injection mode.\n" + "[-a : AP mode.\n" + "[-k : Softap mode.\n" + "[-h : Help.\n" + "[-g : Get current mode for a specific interface index.\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" @@ -1688,14 +1688,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" "parameters:" - "[-i] : Interface index - optional argument.\n" - "[-a] : Enable all packet filter modes\n" - "[-m] : Enable management packets to allowed up the stack.\n" - "[-c] : Enable control packets to be allowed up the stack.\n" - "[-d] : Enable Data packets to be allowed up the stack.\n" - "[-g] : Get current filter settings for a specific interface index.\n" - "<-b> : Capture length buffer size for each packet to be captured - optional argument.\n" - "<-h> : Help.\n" + "[-i : Interface index - optional argument.\n" + "[-a : Enable all packet filter modes\n" + "[-m : Enable management packets to allowed up the stack.\n" + "[-c : Enable control packets to be allowed up the stack.\n" + "[-d : Enable Data packets to be allowed up the stack.\n" + "[-g : Get current filter settings for a specific interface index.\n" + "<-b : Capture length buffer size for each packet to be captured - optional argument.\n" + "<-h : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" @@ -1706,10 +1706,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" "parameters:" - "[-i] : Interface index - optional argument.\n" - "[-c] : Set a specific channel number to the lower layer.\n" - "[-g] : Get current set channel number from the lower layer.\n" - "[-h] : Help.\n" + "[-i : Interface index - optional argument.\n" + "[-c : Set a specific channel number to the lower layer.\n" + "[-g : Get current set channel number from the lower layer.\n" + "[-h : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" From ab12af686ebf3f3c7a3aa52be3e5029b53f90a70 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:23 +0000 Subject: [PATCH 4036/4498] Revert "[nrf fromlist] net: openthread: Remove waiting for DTR in openthread UART." This reverts commit 0c7fcf3c32a712f5003def83a3607404850dc9e2. Signed-off-by: Dominik Ermel --- modules/openthread/platform/uart.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/openthread/platform/uart.c b/modules/openthread/platform/uart.c index ebf156ded15..dd62d36ee11 100644 --- a/modules/openthread/platform/uart.c +++ b/modules/openthread/platform/uart.c @@ -170,6 +170,7 @@ otError otPlatUartEnable(void) if (DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_ot_uart), zephyr_cdc_acm_uart)) { int ret; + uint32_t dtr = 0U; ret = usb_enable(NULL); if (ret != 0 && ret != -EALREADY) { @@ -177,6 +178,20 @@ otError otPlatUartEnable(void) return OT_ERROR_FAILED; } + LOG_INF("Waiting for host to be ready to communicate"); + + /* Data Terminal Ready - check if host is ready to communicate */ + while (!dtr) { + ret = uart_line_ctrl_get(ot_uart.dev, + UART_LINE_CTRL_DTR, &dtr); + if (ret) { + LOG_ERR("Failed to get Data Terminal Ready line state: %d", + ret); + continue; + } + k_msleep(100); + } + /* Data Carrier Detect Modem - mark connection as established */ (void)uart_line_ctrl_set(ot_uart.dev, UART_LINE_CTRL_DCD, 1); /* Data Set Ready - the NCP SoC is ready to communicate */ From 88094c96dfe30dde23190f772e6706985cc74db3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:24 +0000 Subject: [PATCH 4037/4498] Revert "[nrf fromlist] tfm: Remove limitation of enabling FP when build TF-M NS application" This reverts commit 90a72daae2c8715d760d974a7d294aa2eb6b38c4. Signed-off-by: Dominik Ermel --- arch/arm/core/aarch32/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/core/aarch32/Kconfig b/arch/arm/core/aarch32/Kconfig index c8a48cb7f11..529d143ef8c 100644 --- a/arch/arm/core/aarch32/Kconfig +++ b/arch/arm/core/aarch32/Kconfig @@ -264,6 +264,9 @@ choice config FP_HARDABI bool "Floating point Hard ABI" + # TF-M build system does not build the NS app and libraries correctly with Hard ABI. + # This limitation should be removed in the next TF-M synchronization. + depends on !TFM_BUILD_NS help This option selects the Floating point ABI in which hardware floating point instructions are generated and uses FPU-specific calling From a810007e6e8b3ef3c77fc283d5f60a8390f34d0c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:24 +0000 Subject: [PATCH 4038/4498] Revert "[nrf fromlist] tfm: Remove SFN model FP limitation" This reverts commit 5ba9369a4ed737d05145d892516d44f2f439eba3. Signed-off-by: Dominik Ermel --- arch/arm/core/aarch32/Kconfig | 2 ++ modules/trusted-firmware-m/Kconfig.tfm | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm/core/aarch32/Kconfig b/arch/arm/core/aarch32/Kconfig index 529d143ef8c..58d5253cb94 100644 --- a/arch/arm/core/aarch32/Kconfig +++ b/arch/arm/core/aarch32/Kconfig @@ -272,6 +272,8 @@ config FP_HARDABI point instructions are generated and uses FPU-specific calling conventions. + Note: When building with TF-M enabled only the IPC mode is supported. + config FP_SOFTABI bool "Floating point Soft ABI" help diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 2a5edb64343..c09d922e9fd 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -323,6 +323,7 @@ config TFM_IPC config TFM_SFN bool "SFN model" + depends on !FP_HARDABI help Use the SFN Model as the SPM backend for the PSA API. The SFN model supports the SFN Partition model, and isolation level 1. From 07514687dfc371d7e50f439fafcf2160c4f0ecb3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:24 +0000 Subject: [PATCH 4039/4498] Revert "[nrf fromtree] net: openthread: upmerge to `6edb06e`" This reverts commit f51a3a880d04f082e92dfc478d6dfdbdea8304e3. Signed-off-by: Dominik Ermel --- modules/openthread/CMakeLists.txt | 6 ------ modules/openthread/Kconfig.features | 7 ------- west.yml | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 31bff57d776..83995aba72f 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -154,12 +154,6 @@ else() set(OT_CSL_RECEIVER OFF CACHE BOOL "Enable CSL receiver feature for Thread 1.2" FORCE) endif() -if(CONFIG_OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC) - set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC ON CACHE BOOL "Use local time for CSL sync" FORCE) -else() - set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC OFF CACHE BOOL "Use local time for CSL sync" FORCE) -endif() - if(CONFIG_OPENTHREAD_DATASET_UPDATER) set(OT_DATASET_UPDATER ON CACHE BOOL "Enable Dataset updater" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index bd8a05ed9b9..cd57844370e 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -96,13 +96,6 @@ config OPENTHREAD_CSL_RECEIVER help Enable CSL Receiver support for Thread 1.2 -config OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC - bool "Use local time for CSL synchronization" - help - Use host time rather than radio platform time to track elapsed time - since last CSL synchronization. This reduces the usage of radio API - calls, and it is useful for platforms in which those are costly. - config OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT bool "Device props for leader weight" default n if (OPENTHREAD_THREAD_VERSION_1_1 || \ diff --git a/west.yml b/west.yml index 93db410ea77..1847e94b37c 100644 --- a/west.yml +++ b/west.yml @@ -303,7 +303,7 @@ manifest: revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 path: modules/lib/open-amp - name: openthread - revision: 6edb06e4e0472411200ce2a084a783eaf3faffe3 + revision: d62167ee34b091e7025c9ec2820aae71e17a3944 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From ea6d9e9a143ef21f9616457bd9168c94590a2ca4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:25 +0000 Subject: [PATCH 4040/4498] Revert "[nrf fromlist] net: zperf: Fix TCP packet counting" This reverts commit e8c9775db7c7dbdb833e025038d6067983ae4cad. Signed-off-by: Dominik Ermel --- subsys/net/lib/zperf/zperf_tcp_uploader.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_tcp_uploader.c b/subsys/net/lib/zperf/zperf_tcp_uploader.c index 5fcc0530c5c..3e72f81e54b 100644 --- a/subsys/net/lib/zperf/zperf_tcp_uploader.c +++ b/subsys/net/lib/zperf/zperf_tcp_uploader.c @@ -20,22 +20,6 @@ static char sample_packet[PACKET_SIZE_MAX]; static struct zperf_async_upload_context tcp_async_upload_ctx; -static ssize_t sendall(int sock, const void *buf, size_t len) -{ - while (len) { - ssize_t out_len = zsock_send(sock, buf, len, 0); - - if (out_len < 0) { - return out_len; - } - - buf = (const char *)buf + out_len; - len -= out_len; - } - - return 0; -} - static int tcp_upload(int sock, unsigned int duration_in_ms, unsigned int packet_size, @@ -66,7 +50,7 @@ static int tcp_upload(int sock, do { /* Send the packet */ - ret = sendall(sock, sample_packet, packet_size); + ret = zsock_send(sock, sample_packet, packet_size, 0); if (ret < 0) { if (nb_errors == 0 && ret != -ENOMEM) { NET_ERR("Failed to send the packet (%d)", errno); From 46dfbbbd0131b6a0a8df255cc3be23e7491ec264 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:25 +0000 Subject: [PATCH 4041/4498] Revert "[nrf fromlist] net: sockets: tls: Set errno on TX waiting error" This reverts commit 67fddd31afce6d47ae8645fc40a4479e26d23965. Signed-off-by: Dominik Ermel --- subsys/net/lib/sockets/sockets_tls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index f77bf51d668..20fdc3617af 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2230,9 +2230,10 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, timeout_ms = timeout_to_ms(&timeout); ret = wait_for_reason(ctx->sock, timeout_ms, ret); if (ret != 0) { - errno = -ret; + /* Retry. */ break; } + } else { (void)tls_mbedtls_reset(ctx); errno = EIO; From 673d3d10f684a52523ea782410c78421ac8e1f5d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:25 +0000 Subject: [PATCH 4042/4498] Revert "[nrf fromlist] net: tcp: Feed TX semaphore on connection close" This reverts commit f165bb7517c01c00eb42db01404408d7a2731ce0. Signed-off-by: Dominik Ermel --- subsys/net/ip/tcp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 680fdcecb85..2e70824b8ed 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -621,8 +621,6 @@ static int tcp_conn_close(struct tcp *conn, int status) status, conn->recv_user_data); } - k_sem_give(&conn->tx_sem); - return tcp_conn_unref(conn); } From fb4f07c75a1172d8671a8808936f829f12d52f69 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:25 +0000 Subject: [PATCH 4043/4498] Revert "[nrf fromlist] net: tcp: Rework data queueing API" This reverts commit 2242e9c7569a3651e2a07c11e0e24e2212e3dbd9. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_context.c | 27 +++--- subsys/net/ip/tcp.c | 166 ++++++++++++++--------------------- subsys/net/ip/tcp.h | 15 +++- subsys/net/ip/tcp_internal.h | 20 ++--- 4 files changed, 96 insertions(+), 132 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 6af67103721..1372398185a 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1480,7 +1480,7 @@ static int context_sendto(struct net_context *context, { const struct msghdr *msghdr = NULL; struct net_if *iface; - struct net_pkt *pkt = NULL; + struct net_pkt *pkt; size_t tmp_len; int ret; @@ -1689,15 +1689,6 @@ static int context_sendto(struct net_context *context, return -ENETDOWN; } - context->send_cb = cb; - context->user_data = user_data; - - if (IS_ENABLED(CONFIG_NET_TCP) && - net_context_get_proto(context) == IPPROTO_TCP && - !net_if_is_ip_offloaded(net_context_get_iface(context))) { - goto skip_alloc; - } - pkt = context_alloc_pkt(context, len, PKT_WAIT_TIME); if (!pkt) { NET_ERR("Failed to allocate net_pkt"); @@ -1716,6 +1707,9 @@ static int context_sendto(struct net_context *context, len = tmp_len; } + context->send_cb = cb; + context->user_data = user_data; + if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { uint8_t priority; @@ -1737,7 +1731,6 @@ static int context_sendto(struct net_context *context, } } -skip_alloc: if (IS_ENABLED(CONFIG_NET_OFFLOAD) && net_if_is_ip_offloaded(net_context_get_iface(context))) { ret = context_write_data(pkt, buf, len, msghdr); @@ -1769,12 +1762,16 @@ static int context_sendto(struct net_context *context, } else if (IS_ENABLED(CONFIG_NET_TCP) && net_context_get_proto(context) == IPPROTO_TCP) { - ret = net_tcp_queue(context, buf, len, msghdr); + ret = context_write_data(pkt, buf, len, msghdr); if (ret < 0) { goto fail; } - len = ret; + net_pkt_cursor_init(pkt); + ret = net_tcp_queue_data(context, pkt); + if (ret < 0) { + goto fail; + } ret = net_tcp_send_data(context, cb, user_data); } else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && @@ -1830,9 +1827,7 @@ static int context_sendto(struct net_context *context, return len; fail: - if (pkt != NULL) { - net_pkt_unref(pkt); - } + net_pkt_unref(pkt); return ret; } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 2e70824b8ed..ad9cd1e4c98 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1252,49 +1252,6 @@ static int tcp_pkt_peek(struct net_pkt *to, struct net_pkt *from, size_t pos, return net_pkt_copy(to, from, len); } -static int tcp_pkt_append(struct net_pkt *pkt, const uint8_t *data, size_t len) -{ - size_t alloc_len = len; - struct net_buf *buf = NULL; - int ret = 0; - - if (pkt->buffer) { - buf = net_buf_frag_last(pkt->buffer); - - if (len > net_buf_tailroom(buf)) { - alloc_len -= net_buf_tailroom(buf); - } else { - alloc_len = 0; - } - } - - if (alloc_len > 0) { - ret = net_pkt_alloc_buffer_raw(pkt, alloc_len, - TCP_PKT_ALLOC_TIMEOUT); - if (ret < 0) { - return -ENOBUFS; - } - } - - if (buf == NULL) { - buf = pkt->buffer; - } - - while (buf != NULL && len > 0) { - size_t write_len = MIN(len, net_buf_tailroom(buf)); - - net_buf_add_mem(buf, data, write_len); - - data += write_len; - len -= write_len; - buf = buf->frags; - } - - NET_ASSERT(len == 0, "Not all bytes written"); - - return ret; -} - static bool tcp_window_full(struct tcp *conn) { bool window_full = (conn->send_data_total >= conn->send_win); @@ -3098,12 +3055,13 @@ int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta) return ret; } -int net_tcp_queue(struct net_context *context, const void *data, size_t len, - const struct msghdr *msg) +/* net_context queues the outgoing data for the TCP connection */ +int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt) { struct tcp *conn = context->tcp; - size_t queued_len = 0; + struct net_buf *orig_buf = NULL; int ret = 0; + size_t len; if (!conn || conn->state != TCP_ESTABLISHED) { return -ENOTCONN; @@ -3120,69 +3078,72 @@ int net_tcp_queue(struct net_context *context, const void *data, size_t len, goto out; } - if (msg) { - len = 0; + len = net_pkt_get_len(pkt); - for (int i = 0; i < msg->msg_iovlen; i++) { - len += msg->msg_iov[i].iov_len; - } + if (conn->send_data->buffer) { + orig_buf = net_buf_frag_last(conn->send_data->buffer); } - /* Queue no more than TX window permits. It's guaranteed at this point - * that conn->send_data_total is less than conn->send_win, as it was - * verified in tcp_window_full() check above. As the connection mutex - * is held, their values shall not change since. - */ - len = MIN(conn->send_win - conn->send_data_total, len); - - if (msg) { - for (int i = 0; i < msg->msg_iovlen; i++) { - int iovlen = MIN(msg->msg_iov[i].iov_len, len); - - ret = tcp_pkt_append(conn->send_data, - msg->msg_iov[i].iov_base, - iovlen); - if (ret < 0) { - if (queued_len == 0) { - goto out; - } else { - break; - } - } + net_pkt_append_buffer(conn->send_data, pkt->buffer); + conn->send_data_total += len; + NET_DBG("conn: %p Queued %zu bytes (total %zu)", conn, len, + conn->send_data_total); + pkt->buffer = NULL; - queued_len += iovlen; - len -= iovlen; - - if (len == 0) { - break; - } - } - } else { - ret = tcp_pkt_append(conn->send_data, data, len); - if (ret < 0) { - goto out; - } - - queued_len = len; - } - - conn->send_data_total += queued_len; - - /* Successfully queued data for transmission. Even if there's a transmit - * failure now (out-of-buf case), it can be ignored for now, retransmit - * timer will take care of queued data retransmission. - */ ret = tcp_send_queued_data(conn); if (ret < 0 && ret != -ENOBUFS) { tcp_conn_close(conn, ret); goto out; } - if (tcp_window_full(conn)) { - (void)k_sem_take(&conn->tx_sem, K_NO_WAIT); + if ((ret == -ENOBUFS) && + (conn->send_data_total < (conn->unacked_len + len))) { + /* Some of the data has been sent, we cannot remove the + * whole chunk, the remainder portion is already + * in the send_data and will be transmitted upon a + * received ack or the next send call + * + * Set the return code back to 0 to pretend we just + * transmitted the chunk + */ + ret = 0; } - ret = queued_len; + if (ret == -ENOBUFS) { + /* Restore the original data so that we do not resend the pkt + * data multiple times. + */ + conn->send_data_total -= len; + + if (orig_buf) { + pkt->buffer = orig_buf->frags; + orig_buf->frags = NULL; + } else { + pkt->buffer = conn->send_data->buffer; + conn->send_data->buffer = NULL; + } + + /* If we have out-of-bufs case, and the send_data buffer has + * become empty, till the retransmit timer, as there is no + * data to retransmit. + * The socket layer will catch this and resend data if needed. + * Only perform this when it is just the newly added packet, + * otherwise it can disrupt any pending transmission + */ + if (conn->send_data_total == 0) { + NET_DBG("No bufs, cancelling retransmit timer"); + k_work_cancel_delayable(&conn->send_data_timer); + } + } else { + if (tcp_window_full(conn)) { + (void)k_sem_take(&conn->tx_sem, K_NO_WAIT); + } + + /* We should not free the pkt if there was an error. It will be + * freed in net_context.c:context_sendto() + */ + tcp_pkt_unref(pkt); + } out: k_mutex_unlock(&conn->lock); @@ -3537,9 +3498,7 @@ static size_t tp_tcp_recv_cb(struct tcp *conn, struct net_pkt *pkt) net_pkt_pull(up, net_pkt_get_len(up) - len); - for (struct net_buf *buf = pkt->buffer; buf != NULL; buf = buf->frags) { - net_tcp_queue(conn->context, buf->data, buf->len); - } + net_tcp_queue_data(conn->context, up); return len; } @@ -3682,7 +3641,12 @@ enum net_verdict tp_input(struct net_conn *net_conn, responded = true; NET_DBG("tcp_send(\"%s\")", tp->data); { - net_tcp_queue(conn->context, buf, len); + struct net_pkt *data_pkt; + + data_pkt = tcp_pkt_alloc(conn, len); + net_pkt_write(data_pkt, buf, len); + net_pkt_cursor_init(data_pkt); + net_tcp_queue_data(conn->context, data_pkt); } } break; diff --git a/subsys/net/ip/tcp.h b/subsys/net/ip/tcp.h index 162407710eb..f6f481d5443 100644 --- a/subsys/net/ip/tcp.h +++ b/subsys/net/ip/tcp.h @@ -31,7 +31,6 @@ extern "C" { #endif -#include #include /** @@ -73,7 +72,18 @@ int net_tcp_listen(struct net_context *context); */ int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb, void *user_data); - +/** + * @brief Enqueue data for transmission + * + * @param context Network context + * @param buf Pointer to the data + * @param len Number of bytes + * @param msghdr Data for a vector array operation + * + * @return 0 if ok, < 0 if error + */ +int net_tcp_queue(struct net_context *context, const void *buf, size_t len, + const struct msghdr *msghdr); /* TODO: split into 2 functions, conn -> context, queue -> send? */ /* The following functions are provided solely for the compatibility @@ -102,6 +112,7 @@ void net_tcp_init(void); #define net_tcp_init(...) #endif int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta); +int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt); int net_tcp_finalize(struct net_pkt *pkt); #if defined(CONFIG_NET_TEST_PROTOCOL) diff --git a/subsys/net/ip/tcp_internal.h b/subsys/net/ip/tcp_internal.h index 17d4581aa3d..e76ba859e49 100644 --- a/subsys/net/ip/tcp_internal.h +++ b/subsys/net/ip/tcp_internal.h @@ -282,27 +282,21 @@ struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt, #endif /** - * @brief Enqueue data for transmission + * @brief Enqueue a single packet for transmission * - * @param context Network context - * @param data Pointer to the data - * @param len Number of bytes - * @param msg Data for a vector array operation + * @param context TCP context + * @param pkt Packet * * @return 0 if ok, < 0 if error */ #if defined(CONFIG_NET_NATIVE_TCP) -int net_tcp_queue(struct net_context *context, const void *data, size_t len, - const struct msghdr *msg); +int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt); #else -static inline int net_tcp_queue(struct net_context *context, const void *data, - size_t len, const struct msghdr *msg) +static inline int net_tcp_queue_data(struct net_context *context, + struct net_pkt *pkt) { ARG_UNUSED(context); - ARG_UNUSED(data); - ARG_UNUSED(len); - ARG_UNUSED(msg); - + ARG_UNUSED(pkt); return -EPROTONOSUPPORT; } #endif From 0a160a5a535cf1b02366cb3b0c4a5da958fd5146 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:25 +0000 Subject: [PATCH 4044/4498] Revert "[nrf fromlist] net: pkt: Add function for allocating buffers w/o preconditions" This reverts commit af993b28c1dcde6c52e55517801628b82429ad78. Signed-off-by: Dominik Ermel --- include/zephyr/net/net_pkt.h | 25 --------------- subsys/net/ip/net_pkt.c | 61 ------------------------------------ 2 files changed, 86 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 199f78d2361..d4011d1f582 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -1678,13 +1678,6 @@ int net_pkt_alloc_buffer_debug(struct net_pkt *pkt, net_pkt_alloc_buffer_debug(_pkt, _size, _proto, _timeout, \ __func__, __LINE__) -int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size, - k_timeout_t timeout, - const char *caller, int line); -#define net_pkt_alloc_buffer_raw(_pkt, _size, _timeout) \ - net_pkt_alloc_buffer_raw_debug(_pkt, _size, _timeout, \ - __func__, __LINE__) - struct net_pkt *net_pkt_alloc_with_buffer_debug(struct net_if *iface, size_t size, sa_family_t family, @@ -1799,24 +1792,6 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt, k_timeout_t timeout); #endif -/** - * @brief Allocate buffer for a net_pkt, of specified size, w/o any additional - * preconditions - * - * @details: The actual buffer size may be larger than requested one if fixed - * size buffers are in use. - * - * @param pkt The network packet requiring buffer to be allocated. - * @param size The size of buffer being requested. - * @param timeout Maximum time to wait for an allocation. - * - * @return 0 on success, negative errno code otherwise. - */ -#if !defined(NET_PKT_DEBUG_ENABLED) -int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size, - k_timeout_t timeout); -#endif - /** * @brief Allocate a network packet and buffer at once * diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index fb44490dd2b..57ba0f3bb0d 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -1197,67 +1197,6 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt, return 0; } - -#if NET_LOG_LEVEL >= LOG_LEVEL_DBG -int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size, - k_timeout_t timeout, const char *caller, - int line) -#else -int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size, - k_timeout_t timeout) -#endif -{ - struct net_buf_pool *pool = NULL; - struct net_buf *buf; - - if (size == 0) { - return 0; - } - - if (k_is_in_isr()) { - timeout = K_NO_WAIT; - } - - NET_DBG("Data allocation size %zu", size); - - if (pkt->context) { - pool = get_data_pool(pkt->context); - } - - if (!pool) { - pool = pkt->slab == &tx_pkts ? &tx_bufs : &rx_bufs; - } - -#if NET_LOG_LEVEL >= LOG_LEVEL_DBG - buf = pkt_alloc_buffer(pool, size, timeout, caller, line); -#else - buf = pkt_alloc_buffer(pool, size, timeout); -#endif - - if (!buf) { -#if NET_LOG_LEVEL >= LOG_LEVEL_DBG - NET_ERR("Data buffer (%zd) allocation failed (%s:%d)", - size, caller, line); -#else - NET_ERR("Data buffer (%zd) allocation failed.", size); -#endif - return -ENOMEM; - } - - net_pkt_append_buffer(pkt, buf); - -#if IS_ENABLED(CONFIG_NET_BUF_FIXED_DATA_SIZE) - /* net_buf allocators shrink the buffer size to the requested size. - * We don't want this behavior here, so restore the real size of the - * last fragment. - */ - buf = net_buf_frag_last(buf); - buf->size = CONFIG_NET_BUF_DATA_SIZE; -#endif - - return 0; -} - #if NET_LOG_LEVEL >= LOG_LEVEL_DBG static struct net_pkt *pkt_alloc(struct k_mem_slab *slab, k_timeout_t timeout, const char *caller, int line) From a84b8bcc6b222ab92bc6f756d754453e37011e45 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:26 +0000 Subject: [PATCH 4045/4498] Revert "[nrf fromlist] tfm: Change SFN and FP_HARDABI dependency" This reverts commit 1687aaaac27cce09921a015a3f63c79666ebdc37. Signed-off-by: Dominik Ermel --- arch/arm/core/aarch32/Kconfig | 1 + modules/trusted-firmware-m/Kconfig.tfm | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/core/aarch32/Kconfig b/arch/arm/core/aarch32/Kconfig index 58d5253cb94..a14bcd0cb62 100644 --- a/arch/arm/core/aarch32/Kconfig +++ b/arch/arm/core/aarch32/Kconfig @@ -267,6 +267,7 @@ config FP_HARDABI # TF-M build system does not build the NS app and libraries correctly with Hard ABI. # This limitation should be removed in the next TF-M synchronization. depends on !TFM_BUILD_NS + depends on !(BUILD_WITH_TFM && !TFM_IPC) help This option selects the Floating point ABI in which hardware floating point instructions are generated and uses FPU-specific calling diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index c09d922e9fd..2a5edb64343 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -323,7 +323,6 @@ config TFM_IPC config TFM_SFN bool "SFN model" - depends on !FP_HARDABI help Use the SFN Model as the SPM backend for the PSA API. The SFN model supports the SFN Partition model, and isolation level 1. From 8c6d7f2d5c984cb7ced81a0fb876137cfd397ac6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:26 +0000 Subject: [PATCH 4046/4498] Revert "[nrf fromlist] tfm: Fix include order between platform_ns and tfm_api_ns libraries" This reverts commit b96a183abe7f07a90ba844c7928740d2c1b3c96c. Signed-off-by: Dominik Ermel --- modules/trusted-firmware-m/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 177a47e28d6..f00116cda2c 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -435,8 +435,8 @@ if (CONFIG_BUILD_WITH_TFM) else() zephyr_library_link_libraries( - ${PLATFORM_NS_FILE} ${TFM_API_NS_PATH} + ${PLATFORM_NS_FILE} ) endif() From 0b2fed079a4b7180306a04b849552c9ad809203b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:26 +0000 Subject: [PATCH 4047/4498] Revert "[nrf fromtree] tfm: Enable TFM_EXCEPTION_INFO_DUMP by default" This reverts commit a69bb9315bcd02096bbf27f13038a5c0a1706632. Signed-off-by: Dominik Ermel --- modules/trusted-firmware-m/Kconfig.tfm | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 2a5edb64343..bafa5cf0bab 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -446,7 +446,6 @@ endchoice config TFM_EXCEPTION_INFO_DUMP bool "TF-M exception info dump" - default y help On fatal errors in the secure firmware, capture info about the exception. Print the info if the SPM log level is sufficient. From b4ca83cbbe13ac10a83c52d05e7a3c3e66446733 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:26 +0000 Subject: [PATCH 4048/4498] Revert "[nrf noup] boards: arm: nrf9131ek: fix docs build" This reverts commit 56f475ad3e6fe5583a7478db6dfa47fad3485d35. Signed-off-by: Dominik Ermel --- boards/arm/nrf9131ek_nrf9131/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/arm/nrf9131ek_nrf9131/doc/index.rst b/boards/arm/nrf9131ek_nrf9131/doc/index.rst index ffb066d860d..a72cd1526e3 100644 --- a/boards/arm/nrf9131ek_nrf9131/doc/index.rst +++ b/boards/arm/nrf9131ek_nrf9131/doc/index.rst @@ -210,8 +210,8 @@ Testing the LEDs and buttons in the nRF9131 EK There are 2 samples that allow you to test that the button and LED on the board are working properly with Zephyr: -* :ref:`blinky-sample` -* :ref:`button-sample` +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` You can build and flash the examples to make sure Zephyr is running correctly on your board. The button and LED definitions can be found in From 5d74d40ee6f21bb3549831919ff5b4ab440fb3ea Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:27 +0000 Subject: [PATCH 4049/4498] Revert "[nrf fromlist] boards: arm: nrf9131ek: add docs" This reverts commit b0177d6df95deb539e3ddc95048faa8d0c4b69bd. Signed-off-by: Dominik Ermel --- .../doc/img/nrf9131ek_nrf9131.webp | Bin 75800 -> 0 bytes boards/arm/nrf9131ek_nrf9131/doc/index.rst | 228 ------------------ .../nrf9131ek_nrf9131_common.dtsi | 4 +- 3 files changed, 2 insertions(+), 230 deletions(-) delete mode 100644 boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp delete mode 100644 boards/arm/nrf9131ek_nrf9131/doc/index.rst diff --git a/boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp b/boards/arm/nrf9131ek_nrf9131/doc/img/nrf9131ek_nrf9131.webp deleted file mode 100644 index 056296ebbbcab5b514be7a6f30771f3b12167bc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75800 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 -b 115200 - -Replace :code:`` with the port where the nRF9131 EK -can be found. For example, under Linux, :code:`/dev/ttyACM0`. - -Then build and flash the application in the usual way. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: nrf9131ek_nrf9131 - :goals: build flash - -Debugging -========= - -Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a -Segger IC. - - -Testing the LEDs and buttons in the nRF9131 EK -********************************************** - -There are 2 samples that allow you to test that the button and LED on -the board are working properly with Zephyr: - -* :zephyr:code-sample:`blinky` -* :zephyr:code-sample:`button` - -You can build and flash the examples to make sure Zephyr is running correctly on -your board. The button and LED definitions can be found in -:zephyr_file:`boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi`. - -References -********** - -.. target-notes:: - -.. _IDAU: - https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com -.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi index 2c3b8481d2a..35314cd0784 100644 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi +++ b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi @@ -20,7 +20,7 @@ compatible = "gpio-leds"; led0: led_0 { gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - label = "Red LED 1"; + label = "Green LED 1"; }; led1: led_1 { gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; @@ -28,7 +28,7 @@ }; led2: led_2 { gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; - label = "Blue LED 3"; + label = "Green LED 3"; }; }; From 87123959f5f1fcb3fe6043a2bdbd02634b27287c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:27 +0000 Subject: [PATCH 4050/4498] Revert "[nrf noup] boards: arm: nrf9131ek: enable tfm" This reverts commit 6755c4785640afb19f4973563f9737eece9f57c4. Signed-off-by: Dominik Ermel --- boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig index 378a58fb6e3..0ece4f9a2ac 100644 --- a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig +++ b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig @@ -8,22 +8,6 @@ if BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS config BOARD default "nrf9131ek_nrf9131" - -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_NRF9131EK_NRF9131_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- From 7bc05f3332b557cf89421c203f4d45d110fa713f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:27 +0000 Subject: [PATCH 4051/4498] Revert "[nrf fromtree] boards: arm: add nrf9131ek_nrf9131" This reverts commit e40ab3aeae65a78c7371113cfcb3bcf2d68d1845. Signed-off-by: Dominik Ermel --- boards/arm/nrf9131ek_nrf9131/Kconfig.board | 14 -- .../arm/nrf9131ek_nrf9131/Kconfig.defconfig | 38 --- boards/arm/nrf9131ek_nrf9131/board.cmake | 14 -- .../nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts | 19 -- .../nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml | 17 -- .../nrf9131ek_nrf9131_common-pinctrl.dtsi | 100 -------- .../nrf9131ek_nrf9131_common.dtsi | 227 ------------------ .../nrf9131ek_nrf9131_defconfig | 26 -- .../nrf9131ek_nrf9131_ns.dts | 22 -- .../nrf9131ek_nrf9131_ns.yaml | 15 -- .../nrf9131ek_nrf9131_ns_defconfig | 35 --- .../nrf9131ek_nrf9131_partition_conf.dtsi | 60 ----- .../arm/nrf9131ek_nrf9131/pre_dt_board.cmake | 7 - tests/lib/devicetree/devices/testcase.yaml | 2 - 14 files changed, 596 deletions(-) delete mode 100644 boards/arm/nrf9131ek_nrf9131/Kconfig.board delete mode 100644 boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig delete mode 100644 boards/arm/nrf9131ek_nrf9131/board.cmake delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig delete mode 100644 boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi delete mode 100644 boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.board b/boards/arm/nrf9131ek_nrf9131/Kconfig.board deleted file mode 100644 index 4a237e3fb61..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/Kconfig.board +++ /dev/null @@ -1,14 +0,0 @@ -# nRF9131-EK board configuration - -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -if SOC_NRF9131_LACA - -config BOARD_NRF9131EK_NRF9131 - bool "nRF9131 EK NRF9131" - -config BOARD_NRF9131EK_NRF9131_NS - bool "nRF9131 EK NRF9131 non-secure" - -endif # SOC_NRF9131_LACA diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig deleted file mode 100644 index 0ece4f9a2ac..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig +++ /dev/null @@ -1,38 +0,0 @@ -# nRF9131 EK NRF9131 board configuration - -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS - -config BOARD - default "nrf9131ek_nrf9131" - -# For the secure version of the board the firmware is linked at the beginning -# of the flash, or into the code-partition defined in DT if it is intended to -# be loaded by MCUboot. If the secure firmware is to be combined with a non- -# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always -# be restricted to the size of its code partition. -# For the non-secure version of the board, the firmware -# must be linked into the code-partition (non-secure) defined in DT, regardless. -# Apply this configuration below by setting the Kconfig symbols used by -# the linker according to the information extracted from DT partitions. - -# Workaround for not being able to have commas in macro arguments -DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition - -config FLASH_LOAD_SIZE - default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - depends on BOARD_NRF9131EK_NRF9131 && TRUSTED_EXECUTION_SECURE - -if BOARD_NRF9131EK_NRF9131_NS - -config FLASH_LOAD_OFFSET - default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -config FLASH_LOAD_SIZE - default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -endif # BOARD_NRF9131EK_NRF9131_NS - -endif # BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS diff --git a/boards/arm/nrf9131ek_nrf9131/board.cmake b/boards/arm/nrf9131ek_nrf9131/board.cmake deleted file mode 100644 index 8293a428b40..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/board.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_BOARD_NRF9131EK_NRF9131_NS) - set(TFM_PUBLIC_KEY_FORMAT "full") -endif() - -if(CONFIG_TFM_FLASH_MERGED_BINARY) - set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) -endif() - -# TODO: change to nRF9131_xxAA when such device is available in JLink -board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") -include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts deleted file mode 100644 index 4b66e5348a0..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.dts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; -#include -#include "nrf9131ek_nrf9131_common.dtsi" - -/ { - chosen { - zephyr,sram = &sram0_s; - zephyr,flash = &flash0; - zephyr,code-partition = &slot0_partition; - zephyr,sram-secure-partition = &sram0_s; - zephyr,sram-non-secure-partition = &sram0_ns; - }; -}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml deleted file mode 100644 index d1b04054ce8..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131.yaml +++ /dev/null @@ -1,17 +0,0 @@ -identifier: nrf9131ek_nrf9131 -name: nRF9131-EK-NRF9131 -type: mcu -arch: arm -toolchain: - - gnuarmemb - - xtools - - zephyr -ram: 88 -flash: 1024 -supported: - - gpio - - i2c - - pwm - - spi - - watchdog - - counter diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi deleted file mode 100644 index 419e7c8d70c..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common-pinctrl.dtsi +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor - * SPDX-License-Identifier: Apache-2.0 - */ - -&pinctrl { - uart0_default: uart0_default { - group1 { - psels = , - ; - }; - group2 { - psels = , - ; - bias-pull-up; - }; - }; - - uart0_sleep: uart0_sleep { - group1 { - psels = , - , - , - ; - low-power-enable; - }; - }; - - uart1_default: uart1_default { - group1 { - psels = , - ; - }; - group2 { - psels = , - ; - bias-pull-up; - }; - }; - - uart1_sleep: uart1_sleep { - group1 { - psels = , - , - , - ; - low-power-enable; - }; - }; - - i2c2_default: i2c2_default { - group1 { - psels = , - ; - }; - }; - - i2c2_sleep: i2c2_sleep { - group1 { - psels = , - ; - low-power-enable; - }; - }; - - pwm0_default: pwm0_default { - group1 { - psels = , - , - ; - }; - }; - - pwm0_sleep: pwm0_sleep { - group1 { - psels = , - , - ; - low-power-enable; - }; - }; - - spi3_default: spi3_default { - group1 { - psels = , - , - ; - nordic,drive-mode = ; - }; - }; - - spi3_sleep: spi3_sleep { - group1 { - psels = , - , - ; - low-power-enable; - }; - }; -}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi deleted file mode 100644 index 35314cd0784..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_common.dtsi +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "nrf9131ek_nrf9131_common-pinctrl.dtsi" -#include - -/ { - model = "Nordic nRF9131 EK NRF9131"; - compatible = "nordic,nrf9131-ek-nrf9131"; - - chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,uart-mcumgr = &uart0; - }; - - leds { - compatible = "gpio-leds"; - led0: led_0 { - gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - label = "Green LED 1"; - }; - led1: led_1 { - gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; - label = "Green LED 2"; - }; - led2: led_2 { - gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; - label = "Green LED 3"; - }; - }; - - pwmleds { - compatible = "pwm-leds"; - pwm_led0: pwm_led_0 { - pwms = <&pwm0 0 PWM_MSEC(8) PWM_POLARITY_NORMAL>; - }; - pwm_led1: pwm_led_1 { - pwms = <&pwm0 1 PWM_MSEC(8) PWM_POLARITY_NORMAL>; - }; - pwm_led2: pwm_led_2 { - pwms = <&pwm0 2 PWM_MSEC(8) PWM_POLARITY_NORMAL>; - }; - }; - - buttons { - compatible = "gpio-keys"; - button0: button_0 { - gpios = <&gpio0 28 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Push button 1"; - zephyr,code = ; - }; - }; - - /* These aliases are provided for compatibility with samples */ - aliases { - led0 = &led0; - led1 = &led1; - led2 = &led2; - pwm-led0 = &pwm_led0; - pwm-led1 = &pwm_led1; - pwm-led2 = &pwm_led2; - sw0 = &button0; - bootloader-led0 = &led0; - mcuboot-button0 = &button0; - mcuboot-led0 = &led0; - watchdog0 = &wdt0; - spi-flash0 = &gd25wb256; - }; -}; - -&adc { - status = "okay"; -}; - -&gpiote { - status = "okay"; -}; - -&gpio0 { - status = "okay"; -}; - -&uart0 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&uart0_default>; - pinctrl-1 = <&uart0_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&uart1 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&uart1_default>; - pinctrl-1 = <&uart1_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&i2c2 { - compatible = "nordic,nrf-twim"; - status = "okay"; - pinctrl-0 = <&i2c2_default>; - pinctrl-1 = <&i2c2_sleep>; - pinctrl-names = "default", "sleep"; - clock-frequency = ; - - pmic_main: npm1300@6b { - compatible = "nordic,npm1300"; - reg = <0x6b>; - pmic_charger: charger { - compatible = "nordic,npm1300-charger"; - term-microvolt = <4150000>; - term-warm-microvolt = <4000000>; - current-microamp = <150000>; - dischg-limit-microamp = <1000000>; - vbus-limit-microamp = <500000>; - thermistor-ohms = <10000>; - thermistor-beta = <3380>; - charging-enable; - }; - regulators { - compatible = "nordic,npm1300-regulator"; - BUCK1 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; - BUCK2 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; - }; - }; -}; - -&pwm0 { - status = "okay"; - pinctrl-0 = <&pwm0_default>; - pinctrl-1 = <&pwm0_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&spi3 { - compatible = "nordic,nrf-spim"; - status = "okay"; - cs-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&spi3_default>; - pinctrl-1 = <&spi3_sleep>; - pinctrl-names = "default", "sleep"; - - gd25wb256: gd25wb256e3ir@0 { - compatible = "jedec,spi-nor"; - status = "disabled"; - reg = <0>; - spi-max-frequency = <8000000>; - size = <268435456>; - has-dpd; - t-enter-dpd = <3000>; - t-exit-dpd = <40000>; - sfdp-bfp = [ - e5 20 f3 ff ff ff ff 0f 44 eb 08 6b 08 3b 42 bb - ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 - 10 d8 00 ff 44 7a c9 fe 83 67 26 62 ec 82 18 44 - 7a 75 7a 75 04 c4 d5 5c 00 06 74 00 08 50 00 01 - ]; - jedec-id = [c8 65 19]; - }; -}; - -&flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x10000>; - }; - slot0_partition: partition@10000 { - label = "image-0"; - }; - slot0_ns_partition: partition@50000 { - label = "image-0-nonsecure"; - }; - slot1_partition: partition@85000 { - label = "image-1"; - }; - slot1_ns_partition: partition@c5000 { - label = "image-1-nonsecure"; - }; - storage_partition: partition@fa000 { - label = "storage"; - reg = <0x000fa000 0x00006000>; - }; - }; -}; - - - -/ { - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - }; - - sram0_modem: image_modem@20016000 { - /* Modem (shared) memory */ - }; - - sram0_ns: image_ns@20020000 { - /* Non-Secure image memory */ - }; - }; -}; - -/* Include partition configuration file */ -#include "nrf9131ek_nrf9131_partition_conf.dtsi" diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig deleted file mode 100644 index fc77ffe0d13..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_defconfig +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_SOC_SERIES_NRF91X=y -CONFIG_SOC_NRF9131_LACA=y -CONFIG_BOARD_NRF9131EK_NRF9131=y - -# Enable MPU -CONFIG_ARM_MPU=y - -# Enable hardware stack protection -CONFIG_HW_STACK_PROTECTION=y - -# Enable TrustZone-M -CONFIG_ARM_TRUSTZONE_M=y - -# enable GPIO -CONFIG_GPIO=y - -# Enable uart driver -CONFIG_SERIAL=y - -# enable console -CONFIG_CONSOLE=y -CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts deleted file mode 100644 index 9a652cd0aed..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.dts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; -#include -#include "nrf9131ek_nrf9131_common.dtsi" - -/ { - chosen { - zephyr,flash = &flash0; - zephyr,sram = &sram0_ns; - zephyr,code-partition = &slot0_ns_partition; - }; -}; - -/* Disable UART1, because it is used by default in TF-M */ -&uart1 { - status = "disabled"; -}; diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml deleted file mode 100644 index cf33abd55da..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns.yaml +++ /dev/null @@ -1,15 +0,0 @@ -identifier: nrf9131ek_nrf9131_ns -name: nRF9131-EK-NRF9131-Non-Secure -type: mcu -arch: arm -toolchain: - - gnuarmemb - - xtools - - zephyr -ram: 128 -flash: 212 -supported: - - i2c - - pwm - - watchdog - - netif:modem diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig deleted file mode 100644 index 83af1cf6b74..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_ns_defconfig +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_SOC_SERIES_NRF91X=y -CONFIG_SOC_NRF9131_LACA=y -CONFIG_BOARD_NRF9131EK_NRF9131_NS=y - -# Enable MPU -CONFIG_ARM_MPU=y - -# Enable hardware stack protection -CONFIG_HW_STACK_PROTECTION=y - -# Enable TrustZone-M -CONFIG_ARM_TRUSTZONE_M=y - -# This Board implies building Non-Secure firmware -CONFIG_TRUSTED_EXECUTION_NONSECURE=y - -# enable GPIO -CONFIG_GPIO=y - -# Enable uart driver -CONFIG_SERIAL=y - -# enable console -CONFIG_CONSOLE=y -CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y - -# enable PMIC -CONFIG_I2C=y -CONFIG_REGULATOR=y -CONFIG_SENSOR=y -CONFIG_NPM1300_CHARGER=y diff --git a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi b/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi deleted file mode 100644 index d14d8d95f75..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/nrf9131ek_nrf9131_partition_conf.dtsi +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * Default Flash planning for nRF9131ek_nrf9131. - * - * Zephyr build for nRF9131 with ARM TrustZone-M support, - * implies building Secure and Non-Secure Zephyr images. - * - * Secure image will be placed, by default, in flash0 - * (or in slot0, if MCUboot is present). - * Secure image will use sram0 for system memory. - * - * Non-Secure image will be placed in slot0_ns, and use - * sram0_ns for system memory. - * - * Note that the Secure image only requires knowledge of - * the beginning of the Non-Secure image (not its size). - */ - -&slot0_partition { - reg = <0x00010000 0x40000>; -}; - -&slot0_ns_partition { - reg = <0x00050000 0x35000>; -}; - -&slot1_partition { - reg = <0x00085000 0x40000>; -}; - -&slot1_ns_partition { - reg = <0x000c5000 0x35000>; -}; - -/* Default SRAM planning when building for nRF9131 with - * ARM TrustZone-M support - * - Lowest 88 kB SRAM allocated to Secure image (sram0_s). - * - 40 kB SRAM reserved for and used by the modem library - * (sram0_modem). This memory is Non-Secure. - * - Upper 128 kB allocated to Non-Secure image (sram0_ns). - * When building with TF-M, both sram0_modem and sram0_ns - * are allocated to the Non-Secure image. - */ - -&sram0_s { - reg = <0x20000000 DT_SIZE_K(88)>; -}; - -&sram0_modem { - reg = <0x20016000 DT_SIZE_K(40)>; -}; - -&sram0_ns { - reg = <0x20020000 DT_SIZE_K(128)>; -}; diff --git a/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake b/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake deleted file mode 100644 index c8267afd1b4..00000000000 --- a/boards/arm/nrf9131ek_nrf9131/pre_dt_board.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2021 Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: -# - flash-controller@39000 & kmu@39000 -# - power@5000 & clock@5000 -list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/tests/lib/devicetree/devices/testcase.yaml b/tests/lib/devicetree/devices/testcase.yaml index 673e2319702..b57489b9a11 100644 --- a/tests/lib/devicetree/devices/testcase.yaml +++ b/tests/lib/devicetree/devices/testcase.yaml @@ -15,5 +15,3 @@ tests: - bl5340_dvk_cpuapp - bl5340_dvk_cpuapp_ns - mimxrt595_evk_cm33 - - nrf9131ek_nrf9131 - - nrf9131ek_nrf9131_ns From d962e213c7f14e9d347b49feb20229a5c4493e55 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:27 +0000 Subject: [PATCH 4052/4498] Revert "[nrf fromtree] drivers: uart: nrf: rx_timeout_slab incorrectly set" This reverts commit fda9e48e5d953cf436fa0d0d50f0df9ca0127632. Signed-off-by: Dominik Ermel --- drivers/serial/uart_nrfx_uarte.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index b70af538abf..017efa6a2e5 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -844,7 +844,15 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, } data->async->rx_timeout = timeout; - data->async->rx_timeout_slab = timeout / RX_TIMEOUT_DIV; + /* Set minimum interval to 3 RTC ticks. 3 is used due to RTC limitation + * which cannot set timeout for next tick. Assuming delay in processing + * 3 instead of 2 is used. Note that lower value would work in a similar + * way but timeouts would always occur later than expected, most likely + * after ~3 ticks. + */ + data->async->rx_timeout_slab = + MAX(timeout / RX_TIMEOUT_DIV, + NRFX_CEIL_DIV(3 * 1000000, CONFIG_SYS_CLOCK_TICKS_PER_SEC)); data->async->rx_buf = buf; data->async->rx_buf_len = len; From bd13386470fa0f411292b28a1a9ad1d859860b26 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:28 +0000 Subject: [PATCH 4053/4498] Revert "[nrf fromlist] sysbuild: create sysbuild_cache function" This reverts commit c441a8dc1291faf8972964f2f944dfe2129a5ede. Signed-off-by: Dominik Ermel --- .../cmake/modules/sysbuild_extensions.cmake | 124 ++++++------------ 1 file changed, 42 insertions(+), 82 deletions(-) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index ac8bac25f8c..a3838415eee 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -107,87 +107,6 @@ function(sysbuild_get variable) endif() endfunction() -# Usage: -# sysbuild_cache(CREATE APPLICATION [CMAKE_RERUN]) -# -# This function works on the sysbuild cache for sysbuild managed applications. -# -# Arguments: -# CREATE : Create or update existing sysbuild cache file for the application. -# The sysbuild cache is only updated if it contain changes. -# APPLICATION : Name of the application. -# CMAKE_RERUN : Force a CMake rerun for the application during next build -# invocation if the sysbuild cache has changed. It is -# advised to always use this flag. Not using this flag can -# reduce build time, but only do so if application is -# guranteed to be up-to-date. -# -function(sysbuild_cache) - cmake_parse_arguments(SB_CACHE "CREATE;CMAKE_RERUN" "APPLICATION" "" ${ARGN}) - zephyr_check_arguments_required(sysbuild_cache SB_CACHE APPLICATION) - zephyr_check_flags_required(sysbuild_cache SB_CACHE CREATE) - - get_target_property(${SB_CACHE_APPLICATION}_MAIN_APP ${SB_CACHE_APPLICATION} MAIN_APP) - get_cmake_property(sysbuild_cache CACHE_VARIABLES) - - foreach(var_name ${sysbuild_cache}) - if(NOT "${var_name}" MATCHES "^(CMAKE_.*|BOARD)$") - # Perform a dummy read to prevent a false warning about unused variables - # being emitted due to a cmake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/24555 - set(unused_tmp_var ${${var_name}}) - - # We don't want to pass internal CMake variables. - # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be - # passed using `-D` on command invocation. - get_property(var_type CACHE ${var_name} PROPERTY TYPE) - set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}") - string(REPLACE ";" "\;" cache_entry "${cache_entry}") - list(APPEND sysbuild_cache_strings "${cache_entry}\n") - endif() - endforeach() - if(DEFINED BOARD_REVISION) - list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n") - else() - list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n") - endif() - list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${SB_CACHE_APPLICATION}\n") - - if(${SB_CACHE_APPLICATION}_MAIN_APP) - list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") - endif() - - if(${SB_CACHE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${SB_CACHE_APPLICATION}_BOARD}) - # Only set image specific board if provided. - # The sysbuild BOARD is exported through sysbuild cache, and will be used - # unless _BOARD is defined. - list(APPEND sysbuild_cache_strings - "${SB_CACHE_APPLICATION}_BOARD:STRING=${${SB_CACHE_APPLICATION}_BOARD}\n" - ) - endif() - - get_target_property(${SB_CACHE_APPLICATION}_CACHE_FILE ${SB_CACHE_APPLICATION} CACHE_FILE) - file(WRITE ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings}) - if(SB_CACHE_CMAKE_RERUN) - execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files - ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp - ${${SB_CACHE_APPLICATION}_CACHE_FILE} - RESULT_VARIABLE compare_res - ) - if(NOT compare_res EQUAL 0) - file(COPY_FILE ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp - ${${SB_CACHE_APPLICATION}_CACHE_FILE} - ) - ExternalProject_Get_Property(${SB_CACHE_APPLICATION} BINARY_DIR) - file(TOUCH_NOCREATE ${BINARY_DIR}/CMakeCache.txt) - endif() - else() - zephyr_file_copy(${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp - ${${SB_CACHE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT - ) - endif() - -endfunction() - # Usage: # ExternalZephyrProject_Add(APPLICATION # SOURCE_DIR @@ -453,7 +372,9 @@ function(ExternalZephyrProject_Cmake) ) ExternalProject_Get_Property(${ZCMAKE_APPLICATION} SOURCE_DIR BINARY_DIR CMAKE_ARGS) + get_target_property(${ZCMAKE_APPLICATION}_CACHE_FILE ${ZCMAKE_APPLICATION} CACHE_FILE) get_target_property(${ZCMAKE_APPLICATION}_BOARD ${ZCMAKE_APPLICATION} BOARD) + get_target_property(${ZCMAKE_APPLICATION}_MAIN_APP ${ZCMAKE_APPLICATION} MAIN_APP) get_property(${ZCMAKE_APPLICATION}_CONF_SCRIPT TARGET ${ZCMAKE_APPLICATION} PROPERTY IMAGE_CONF_SCRIPT @@ -469,7 +390,46 @@ function(ExternalZephyrProject_Cmake) endif() endforeach() - sysbuild_cache(CREATE APPLICATION ${ZCMAKE_APPLICATION}) + get_cmake_property(sysbuild_cache CACHE_VARIABLES) + foreach(var_name ${sysbuild_cache}) + if(NOT "${var_name}" MATCHES "^(CMAKE_.*|BOARD)$") + # Perform a dummy read to prevent a false warning about unused variables + # being emitted due to a cmake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/24555 + set(unused_tmp_var ${${var_name}}) + + # We don't want to pass internal CMake variables. + # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be + # passed using `-D` on command invocation. + get_property(var_type CACHE ${var_name} PROPERTY TYPE) + set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}") + string(REPLACE ";" "\;" cache_entry "${cache_entry}") + list(APPEND sysbuild_cache_strings "${cache_entry}\n") + endif() + endforeach() + if(DEFINED BOARD_REVISION) + list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n") + else() + list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n") + endif() + list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${ZCMAKE_APPLICATION}\n") + + if(${ZCMAKE_APPLICATION}_MAIN_APP) + list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") + endif() + + if(${ZCMAKE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${ZCMAKE_APPLICATION}_BOARD}) + # Only set image specific board if provided. + # The sysbuild BOARD is exported through sysbuild cache, and will be used + # unless _BOARD is defined. + list(APPEND sysbuild_cache_strings + "${ZCMAKE_APPLICATION}_BOARD:STRING=${${ZCMAKE_APPLICATION}_BOARD}\n" + ) + endif() + + file(WRITE ${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings}) + zephyr_file_copy(${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp + ${${ZCMAKE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT + ) foreach(script ${${ZCMAKE_APPLICATION}_CONF_SCRIPT}) include(${script}) From e0deb72356e37b3151db12898ee69c1c401e8c06 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:28 +0000 Subject: [PATCH 4054/4498] Revert "[nrf noup] Bluetooth: Mesh: adapt SDC specific api usage" This reverts commit 533baa16b5a6750cf59a7ce7257bc09bcac09637. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/adv_ext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index fe9fc4fd403..525e5ee5066 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -529,8 +529,8 @@ int bt_mesh_adv_enable(void) if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - advs[i].tags == BT_MESH_ADV_TAG_BIT_FRIEND) { - err = set_adv_randomness(advs[i].instance->handle, 0); + adv->tag == BT_MESH_FRIEND_ADV) { + err = set_adv_randomness(adv->instance->handle, 0); if (err) { LOG_ERR("Failed to set zero randomness: %d", err); } From c469abe57050c3322acbe5fb65fb7be8bf1b8019 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:28 +0000 Subject: [PATCH 4055/4498] Revert "[nrf fromlist] Bluetooth: Mesh: no more tinycrypt in ble mesh tfm image" This reverts commit d466b521fbbdf602a32d92c8ff9f9371e624fa51. Signed-off-by: Dominik Ermel --- .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 5 --- .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 5 --- .../boards/nrf5340dk_nrf5340_cpuapp_ns.conf | 3 -- subsys/bluetooth/host/Kconfig | 7 ++-- subsys/bluetooth/mesh/crypto_psa.c | 10 ------ tests/bsim/bluetooth/mesh/overlay_psa.conf | 5 --- tests/bsim/bluetooth/mesh/src/test_dfu.c | 35 +++++++++---------- .../bluetooth/mesh/src/test_persistence.c | 2 +- .../bluetooth/mesh/src/test_replay_cache.c | 8 ----- 9 files changed, 21 insertions(+), 59 deletions(-) diff --git a/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index 4693e4d1f78..c638a292c91 100644 --- a/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,8 +1,3 @@ -# The option adds TinyCrypt based bt_rand. -CONFIG_BT_HOST_CRYPTO=n -# The option adds GATT caching feature that is based on TinyCrypt. -CONFIG_BT_GATT_CACHING=n - # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index 4693e4d1f78..c638a292c91 100644 --- a/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,8 +1,3 @@ -# The option adds TinyCrypt based bt_rand. -CONFIG_BT_HOST_CRYPTO=n -# The option adds GATT caching feature that is based on TinyCrypt. -CONFIG_BT_GATT_CACHING=n - # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index c3d134592fc..c638a292c91 100644 --- a/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -1,6 +1,3 @@ -# The option adds TinyCrypt based bt_rand. -CONFIG_BT_HOST_CRYPTO=n - # Known issue: non secure platforms do not work with settings subsystem. CONFIG_SETTINGS=n CONFIG_BT_SETTINGS=n diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 2e740686b69..a4cf2e0959b 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -163,13 +163,12 @@ rsource "../mesh/Kconfig" rsource "../audio/Kconfig" config BT_HOST_CRYPTO - bool "Use crypto functionality implemented in the Bluetooth host" + # Hidden option that compiles in AES encryption support using TinyCrypt + # library if this is not provided by the controller implementation. + bool default y if !BT_CTLR_CRYPTO select TINYCRYPT select TINYCRYPT_AES - help - The option adds the AES encryption support using TinyCrypt - library if this is not provided by the controller implementation. config BT_HOST_CRYPTO_PRNG bool "Use Tinycrypt library for random number generation" diff --git a/subsys/bluetooth/mesh/crypto_psa.c b/subsys/bluetooth/mesh/crypto_psa.c index 587c367a6bd..450cde679a8 100644 --- a/subsys/bluetooth/mesh/crypto_psa.c +++ b/subsys/bluetooth/mesh/crypto_psa.c @@ -7,7 +7,6 @@ #include #include -#include #define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL #include @@ -511,12 +510,3 @@ int bt_mesh_key_compare(const uint8_t raw_key[16], const struct bt_mesh_key *key return memcmp(out, raw_key, 16); } - -__weak int bt_rand(void *buf, size_t len) -{ - CHECKIF(buf == NULL || len == 0) { - return -EINVAL; - } - - return psa_generate_random(buf, len) == PSA_SUCCESS ? 0 : -EIO; -} diff --git a/tests/bsim/bluetooth/mesh/overlay_psa.conf b/tests/bsim/bluetooth/mesh/overlay_psa.conf index 1957085b7e4..ba81c1e0213 100644 --- a/tests/bsim/bluetooth/mesh/overlay_psa.conf +++ b/tests/bsim/bluetooth/mesh/overlay_psa.conf @@ -1,7 +1,2 @@ -# The option adds TinyCrypt based bt_rand. -CONFIG_BT_HOST_CRYPTO=n -# The option adds GATT caching feature that is based on TinyCrypt. -CONFIG_BT_GATT_CACHING=n - # Enable mbedTLS PSA as a crypto backend CONFIG_BT_MESH_USES_MBEDTLS_PSA=y diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 46ad4cecb41..a235e86eeec 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -23,7 +23,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define TARGET_ADDR 0x0100 #define IMPOSTER_MODEL_ID 0xe000 #define TEST_BLOB_ID 0xaabbccdd -#define SEMAPHORE_TIMEOUT 250 /* seconds */ struct bind_params { uint16_t model_id; @@ -1017,7 +1016,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_ended, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } @@ -1051,7 +1050,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client apply failed (err: %d)", err); } - if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { FAIL("Failed to apply firmware"); } @@ -1064,7 +1063,7 @@ static void test_cli_fail_on_persistency(void) FAIL("DFU Client confirm failed (err: %d)", err); } - if (k_sem_take(&dfu_cli_confirmed_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_cli_confirmed_sem, K_SECONDS(200))) { FAIL("Failed to confirm firmware"); } @@ -1097,7 +1096,7 @@ static void test_cli_all_targets_lost_common(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_ended, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } } @@ -1188,7 +1187,7 @@ static void test_cli_all_targets_lost_on_apply(void) FAIL("DFU Client apply failed (err: %d)", err); } - if (!k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (!k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { FAIL("Apply should not be successful on any target"); } @@ -1219,7 +1218,7 @@ static void test_cli_stop(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_started, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_started, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } @@ -1235,7 +1234,7 @@ static void test_cli_stop(void) FAIL("DFU Client resume failed (err: %d)", err); } - if (k_sem_take(&dfu_verifying, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_verifying, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } ASSERT_EQUAL(BT_MESH_DFU_ERR_INTERNAL, dfu_cli_xfer.targets[0].status); @@ -1254,7 +1253,7 @@ static void test_cli_stop(void) FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_verify_failed, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_verify_failed, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } @@ -1270,12 +1269,12 @@ static void test_cli_stop(void) if (err) { FAIL("DFU Client send failed (err: %d)", err); } - if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_ended, K_SECONDS(200))) { FAIL("Firmware transfer failed"); } bt_mesh_dfu_cli_apply(&dfu_cli); - if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_cli_applied_sem, K_SECONDS(200))) { /* This will time out as target will reboot before applying */ } ASSERT_EQUAL(BT_MESH_DFU_ERR_INTERNAL, dfu_cli_xfer.targets[0].status); @@ -1465,7 +1464,7 @@ static void test_target_fail_on_metadata(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_metadata_check_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_metadata_check_sem, K_SECONDS(200))) { FAIL("Metadata check CB wasn't called"); } @@ -1479,7 +1478,7 @@ static void test_target_fail_on_caps_get(void) common_fail_on_target_init(&srv_caps_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&caps_get_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&caps_get_sem, K_SECONDS(200))) { FAIL("BLOB Info Get msg handler wasn't called"); } @@ -1493,11 +1492,11 @@ static void test_target_fail_on_update_get(void) common_fail_on_target_init(&srv_update_get_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&dfu_verify_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_verify_sem, K_SECONDS(200))) { FAIL("Transfer end CB wasn't triggered"); } - if (k_sem_take(&update_get_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&update_get_sem, K_SECONDS(200))) { FAIL("Firmware Update Get msg handler wasn't called"); } @@ -1512,7 +1511,7 @@ static void test_target_fail_on_verify(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_verify_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_verify_sem, K_SECONDS(200))) { FAIL("Transfer end CB wasn't triggered"); } @@ -1526,7 +1525,7 @@ static void test_target_fail_on_apply(void) common_fail_on_target_init(&srv_update_apply_broken_comp); target_prov_and_conf_with_imposer(); - if (k_sem_take(&update_apply_sem, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&update_apply_sem, K_SECONDS(200))) { FAIL("Firmware Update Apply msg handler wasn't called"); } @@ -1538,7 +1537,7 @@ static void test_target_fail_on_nothing(void) common_fail_on_target_init(&target_comp); target_prov_and_conf_default(); - if (k_sem_take(&dfu_ended, K_SECONDS(SEMAPHORE_TIMEOUT))) { + if (k_sem_take(&dfu_ended, K_SECONDS(200))) { FAIL("DFU failed"); } diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index aab9c6dd185..90bf41f73a6 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -525,7 +525,7 @@ static void node_configure(void) */ uint8_t net_transmit; - net_transmit = BT_MESH_TRANSMIT(3, 50); + net_transmit = BT_MESH_TRANSMIT(3, 20); err = bt_mesh_cfg_cli_net_transmit_set(test_netkey_idx, TEST_ADDR, net_transmit, &status); if (err || status != net_transmit) { FAIL("Net transmit set failed (err %d, transmit %x)", err, status); diff --git a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c index d7c140ab3ed..dbab05661cb 100644 --- a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c +++ b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c @@ -149,8 +149,6 @@ static void test_tx_immediate_replay_attack(void) } ASSERT_TRUE(is_tx_succeeded); - /* Let complete advertising of the previous transaction to prevent collisions. */ - k_sleep(K_SECONDS(1)); } bt_mesh.seq = seq; @@ -167,8 +165,6 @@ static void test_tx_immediate_replay_attack(void) } ASSERT_TRUE(!is_tx_succeeded); - /* Let complete advertising of the previous transaction to prevent collisions. */ - k_sleep(K_SECONDS(1)); } PASS(); @@ -212,8 +208,6 @@ static void test_tx_power_replay_attack(void) } ASSERT_TRUE(!is_tx_succeeded); - /* Let complete advertising of the previous transaction to prevent collisions. */ - k_sleep(K_SECONDS(1)); } for (int i = 0; i < 3; i++) { @@ -228,8 +222,6 @@ static void test_tx_power_replay_attack(void) } ASSERT_TRUE(is_tx_succeeded); - /* Let complete advertising of the previous transaction to prevent collisions. */ - k_sleep(K_SECONDS(1)); } PASS(); From 97f9037e31145ffbb7ef357e34e79355fb4e7ba0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:28 +0000 Subject: [PATCH 4056/4498] Revert "[nrf fromlist] bsim: bluetooth: mesh: Increase Net Transmit Count value on the node" This reverts commit 6dde66941e658d5a73420e49ac96113c457ce072. Signed-off-by: Dominik Ermel --- tests/bsim/bluetooth/mesh/src/test_persistence.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 90bf41f73a6..6c510922330 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -520,17 +520,6 @@ static void node_configure(void) uint16_t va; struct bt_mesh_cfg_cli_mod_pub pub_params; - /* Set Network Transmit Count state on the device greater than on provisioner to increase - * probability of reception responses. - */ - uint8_t net_transmit; - - net_transmit = BT_MESH_TRANSMIT(3, 20); - err = bt_mesh_cfg_cli_net_transmit_set(test_netkey_idx, TEST_ADDR, net_transmit, &status); - if (err || status != net_transmit) { - FAIL("Net transmit set failed (err %d, transmit %x)", err, status); - } - struct test_appkey_t test_appkeys[] = { { .idx = TEST_APPKEY_0_IDX, .key = TEST_APPKEY_0_KEY }, { .idx = TEST_APPKEY_1_IDX, .key = TEST_APPKEY_1_KEY }, From ddc4d2416e86cb54ff717e904a4d4980c3b4a6eb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:29 +0000 Subject: [PATCH 4057/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Move ext adv sector to vector" This reverts commit 9c6d0f8a0bdca74bee70bea3746db945ac9d314a. Signed-off-by: Dominik Ermel --- cmake/linker_script/common/common-ram.cmake | 3 + include/zephyr/linker/common-ram.ld | 4 + subsys/bluetooth/mesh/Kconfig | 38 ++--- subsys/bluetooth/mesh/adv.c | 41 +++-- subsys/bluetooth/mesh/adv.h | 18 +-- subsys/bluetooth/mesh/adv_ext.c | 151 +++++++++--------- subsys/bluetooth/mesh/adv_legacy.c | 5 +- subsys/bluetooth/mesh/provisioner.c | 2 + tests/bluetooth/mesh/basic/multi_ext_adv.conf | 2 +- .../bsim/bluetooth/mesh/src/test_advertiser.c | 2 +- 10 files changed, 137 insertions(+), 129 deletions(-) diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index 9c051477d10..e6ef59eaf29 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -111,6 +111,9 @@ if(CONFIG_UVB) zephyr_iterable_section(NAME uvb_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) endif() +if(CONFIG_BT_MESH_ADV_EXT) + zephyr_iterable_section(NAME bt_mesh_ext_adv GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +endif() if(CONFIG_LOG) zephyr_iterable_section(NAME log_mpsc_pbuf GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index 8ae67c73257..bfaa26ed400 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -12,6 +12,10 @@ #endif #endif /* NETWORKING */ +#if defined(CONFIG_BT_MESH) + ITERABLE_SECTION_RAM(bt_mesh_ext_adv, 4) +#endif + #if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_DYNAMIC_INTERRUPTS) SECTION_DATA_PROLOGUE(sw_isr_table,,) { diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 63749a69d56..cb04b4dedfb 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -103,22 +103,22 @@ menuconfig BT_MESH_ADV_EXT if BT_MESH_ADV_EXT -config BT_MESH_RELAY_ADV_SETS - int "Maximum of simultaneous relay message support" +config BT_MESH_SIMULT_ADV_SETS + int "Maximum number of parallel advertising sets that can be used by the Bluetooth Mesh stack" default 0 range 0 BT_EXT_ADV_MAX_ADV_SET - depends on BT_MESH_RELAY + depends on BT_MESH_RELAY || BT_MESH_PB_ADV help - Maximum of simultaneous relay message support. Requires controller support + Maximum of simultaneous message support. Requires controller support multiple advertising sets. config BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET bool "Use the main advertising set to relay messages" - depends on BT_MESH_RELAY_ADV_SETS > 0 + depends on BT_MESH_SIMULT_ADV_SETS > 0 help When this option is enabled, there is a message that needs to be relayed, all relay advertising sets defined by - CONFIG_BT_MESH_RELAY_ADV_SETS are busy with relaying messages + CONFIG_BT_MESH_SIMULT_ADV_SETS are busy with relaying messages and the main advertising set is not busy with sending local messages, the stack will use the main advertising set to relay the message. This maximizes the utilization efficiency of @@ -192,15 +192,16 @@ config BT_MESH_UNPROV_BEACON_INT if BT_MESH_PB_ADV -config BT_MESH_PB_ADV_USE_RELAY_SETS - bool "Use relay advertising sets to send provisioning PDUs" - depends on BT_MESH_RELAY_ADV_SETS > 0 +config BT_MESH_PB_ADV_RETRANS_TIMEOUT + int "Timeout value of retransmit provisioning PDUs" + default 500 + range 100 800 help - Use relay advertising sets to send provisioning PDUs + Timeout value of retransmit provisioning PDUs. config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT int "Link Open and Transaction PDU retransmit count" - default 7 if BT_MESH_PB_ADV_USE_RELAY_SETS + default 7 if BT_MESH_SIMULT_ADV_SETS > 0 default 0 range 0 7 help @@ -209,28 +210,21 @@ config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT int "Link Ack and Transaction Ack retransmit count" - default 2 + default 0 range 0 7 help - Controls the number of retransmissions of original Link Ack and Transaction Acknowledgment PDU, + Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, in addition to the first transmission. config BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT int "Link Close retransmit count" - default 7 if BT_MESH_PB_ADV_USE_RELAY_SETS + default 7 if BT_MESH_SIMULT_ADV_SETS > 0 default 2 range 0 7 help Controls the number of retransmissions of original Link Close, in addition to the first transmission. -config BT_MESH_PB_ADV_RETRANS_TIMEOUT - int "Timeout value of retransmit provisioning PDUs" - default 500 - range 100 800 - help - Timeout value of retransmit provisioning PDUs. - endif # BT_MESH_PB_ADV if BT_CONN @@ -407,7 +401,7 @@ config BT_MESH_RELAY_BUF_COUNT of packet drops. When considering the message latency, also consider the values of BT_MESH_RELAY_RETRANSMIT_COUNT and BT_MESH_RELAY_RETRANSMIT_INTERVAL. A higher number of - BT_MESH_RELAY_ADV_SETS allows the increase in the number of buffers + BT_MESH_SIMULT_ADV_SETS allows the increase in the number of buffers while maintaining the latency. endif # BT_MESH_RELAY diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index b24523aacf3..c7abcd53d70 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -44,7 +44,7 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { static bool active_scanning; static K_FIFO_DEFINE(bt_mesh_adv_queue); -static K_FIFO_DEFINE(bt_mesh_relay_queue); +static K_FIFO_DEFINE(bt_mesh_simult_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) @@ -157,7 +157,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, tag, xmit, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE +#if CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE static struct net_buf *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { @@ -189,7 +189,7 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &bt_mesh_relay_queue, + &bt_mesh_simult_queue, 0), #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ }; @@ -202,34 +202,34 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return process_events(events, ARRAY_SIZE(events)); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - tags & BT_MESH_ADV_TAG_BIT_FRIEND) { + tags & BT_MESH_ADV_TAG_FRIEND_BIT) { return net_buf_get(&bt_mesh_friend_queue, timeout); } -#if CONFIG_BT_MESH_RELAY_ADV_SETS - if (!(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { - return net_buf_get(&bt_mesh_relay_queue, timeout); + if (tags & BT_MESH_ADV_TAG_LOCAL_BIT) { + return bt_mesh_adv_buf_get(timeout); } -#endif - return bt_mesh_adv_buf_get(timeout); +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + return net_buf_get(&bt_mesh_simult_queue, timeout); +#endif } -#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ +#else /* !(CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) { return net_buf_get(&bt_mesh_adv_queue, timeout); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { ARG_UNUSED(tags); return bt_mesh_adv_buf_get(timeout); } -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ void bt_mesh_adv_buf_get_cancel(void) { @@ -237,9 +237,9 @@ void bt_mesh_adv_buf_get_cancel(void) k_fifo_cancel_wait(&bt_mesh_adv_queue); -#if CONFIG_BT_MESH_RELAY_ADV_SETS - k_fifo_cancel_wait(&bt_mesh_relay_queue); -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + k_fifo_cancel_wait(&bt_mesh_simult_queue); +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { k_fifo_cancel_wait(&bt_mesh_friend_queue); @@ -267,12 +267,11 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, return; } -#if CONFIG_BT_MESH_RELAY_ADV_SETS +#if CONFIG_BT_MESH_SIMULT_ADV_SETS if (BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY || - (IS_ENABLED(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV)) { - net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_relay_ready(); + BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV) { + net_buf_put(&bt_mesh_simult_queue, net_buf_ref(buf)); + bt_mesh_adv_buf_simult_ready(); return; } #endif diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index a80ff7e8d4b..50c5b47604c 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -33,12 +33,12 @@ enum bt_mesh_adv_tag { BT_MESH_ADV_TAG_PROV, }; -enum bt_mesh_adv_tag_bit { - BT_MESH_ADV_TAG_BIT_LOCAL = BIT(BT_MESH_ADV_TAG_LOCAL), - BT_MESH_ADV_TAG_BIT_RELAY = BIT(BT_MESH_ADV_TAG_RELAY), - BT_MESH_ADV_TAG_BIT_PROXY = BIT(BT_MESH_ADV_TAG_PROXY), - BT_MESH_ADV_TAG_BIT_FRIEND = BIT(BT_MESH_ADV_TAG_FRIEND), - BT_MESH_ADV_TAG_BIT_PROV = BIT(BT_MESH_ADV_TAG_PROV), +enum bt_mesh_adv_tags { + BT_MESH_ADV_TAG_LOCAL_BIT = BIT(BT_MESH_ADV_TAG_LOCAL), + BT_MESH_ADV_TAG_RELAY_BIT = BIT(BT_MESH_ADV_TAG_RELAY), + BT_MESH_ADV_TAG_PROXY_BIT = BIT(BT_MESH_ADV_TAG_PROXY), + BT_MESH_ADV_TAG_FRIEND_BIT = BIT(BT_MESH_ADV_TAG_FRIEND), + BT_MESH_ADV_TAG_PROV_BIT = BIT(BT_MESH_ADV_TAG_PROV), }; struct bt_mesh_adv { @@ -66,7 +66,7 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout); +struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); @@ -82,9 +82,9 @@ int bt_mesh_adv_enable(void); void bt_mesh_adv_buf_local_ready(void); -void bt_mesh_adv_buf_relay_ready(void); +void bt_mesh_adv_buf_simult_ready(void); -void bt_mesh_adv_buf_terminate(const struct net_buf *buf); +void bt_mesh_adv_buf_terminate(struct net_buf *buf); void bt_mesh_adv_buf_friend_ready(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 525e5ee5066..2065de372a4 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -33,8 +33,8 @@ LOG_MODULE_REGISTER(bt_mesh_adv_ext); /* Convert from ms to 0.625ms units */ #define ADV_INT_FAST_MS 20 -#ifndef CONFIG_BT_MESH_RELAY_ADV_SETS -#define CONFIG_BT_MESH_RELAY_ADV_SETS 0 +#ifndef CONFIG_BT_MESH_SIMULT_ADV_SETS +#define CONFIG_BT_MESH_SIMULT_ADV_SETS 0 #endif enum { @@ -60,7 +60,7 @@ enum { }; struct bt_mesh_ext_adv { - const enum bt_mesh_adv_tag_bit tags; + enum bt_mesh_adv_tags tags; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; struct net_buf *buf; @@ -72,71 +72,80 @@ struct bt_mesh_ext_adv { static void send_pending_adv(struct k_work *work); static bool schedule_send(struct bt_mesh_ext_adv *adv); -static struct bt_mesh_ext_adv advs[] = { - [0] = { - .tags = ( +static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { + .tags = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_ADV_TAG_BIT_FRIEND | + BT_MESH_ADV_TAG_FRIEND_BIT | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_ADV_TAG_BIT_PROXY | + BT_MESH_ADV_TAG_PROXY_BIT | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_ADV_TAG_BIT_RELAY | + BT_MESH_ADV_TAG_RELAY_BIT | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ -#if defined(CONFIG_BT_MESH_PB_ADV) - BT_MESH_ADV_TAG_BIT_PROV | -#endif /* CONFIG_BT_MESH_PB_ADV */ - BT_MESH_ADV_TAG_BIT_LOCAL - ), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), - }, -#if CONFIG_BT_MESH_RELAY_ADV_SETS - [1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = { + BT_MESH_ADV_TAG_LOCAL_BIT), + + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), +}; + +#if CONFIG_BT_MESH_SIMULT_ADV_SETS +static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_SIMULT_ADV_SETS) = { + [0 ... CONFIG_BT_MESH_SIMULT_ADV_SETS - 1] = { .tags = ( #if defined(CONFIG_BT_MESH_RELAY) - BT_MESH_ADV_TAG_BIT_RELAY | + BT_MESH_ADV_TAG_RELAY_BIT | #endif /* CONFIG_BT_MESH_RELAY */ -#if defined(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) - BT_MESH_ADV_TAG_BIT_PROV | -#endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */ +#if defined(CONFIG_BT_MESH_PB_ADV) + BT_MESH_ADV_TAG_PROV_BIT | +#endif /* CONFIG_BT_MESH_PB_ADV */ 0), + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), - }, -#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ + } +}; +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ + #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - { - .tags = BT_MESH_ADV_TAG_BIT_FRIEND, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), - }, +#define ADV_EXT_FRIEND 1 +static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { + .tags = BT_MESH_ADV_TAG_FRIEND_BIT, + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), +}; +#else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ +#define ADV_EXT_FRIEND 0 #endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ + #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - { - .tags = BT_MESH_ADV_TAG_BIT_PROXY, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), - }, -#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ +#define ADV_EXT_GATT 1 +static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { + .tags = BT_MESH_ADV_TAG_PROXY_BIT, + .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; +#else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ +#define ADV_EXT_GATT 0 +#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ + +#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_SIMULT_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) -BUILD_ASSERT(ARRAY_SIZE(advs) <= CONFIG_BT_EXT_ADV_MAX_ADV_SET, +BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT, "Insufficient adv instances"); static inline struct bt_mesh_ext_adv *relay_adv_get(void) { - if (!!(CONFIG_BT_MESH_RELAY_ADV_SETS)) { - return &advs[1]; - } else { - return &advs[0]; - } +#if CONFIG_BT_MESH_SIMULT_ADV_SETS + return adv_relay; +#else /* !CONFIG_BT_MESH_SIMULT_ADV_SETS */ + return &adv_main; +#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ } static inline struct bt_mesh_ext_adv *gatt_adv_get(void) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)) { - return &advs[ARRAY_SIZE(advs) - 1]; - } else { - return &advs[0]; - } +#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) + return &adv_gatt; +#else /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ + return &adv_main; +#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ } static int set_adv_randomness(uint8_t handle, int rand_us) @@ -319,7 +328,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { + !(adv->tags & BT_MESH_ADV_TAG_PROXY_BIT)) { return; } @@ -363,8 +372,8 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tags & BT_MESH_ADV_TAG_BIT_FRIEND) || - (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_BIT_RELAY)) { + adv->tags & BT_MESH_ADV_TAG_FRIEND_BIT) || + (CONFIG_BT_MESH_SIMULT_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_RELAY_BIT)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. @@ -385,14 +394,14 @@ void bt_mesh_adv_gatt_update(void) void bt_mesh_adv_buf_local_ready(void) { - (void)schedule_send(advs); + (void)schedule_send(&adv_main); } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_buf_simult_ready(void) { struct bt_mesh_ext_adv *adv = relay_adv_get(); - for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { + for (int i = 0; i < CONFIG_BT_MESH_SIMULT_ADV_SETS; i++) { if (schedule_send(&adv[i])) { return; } @@ -400,26 +409,22 @@ void bt_mesh_adv_buf_relay_ready(void) /* Attempt to use the main adv set for the sending of relay messages. */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)) { - (void)schedule_send(advs); + (void)schedule_send(&adv_main); } } void bt_mesh_adv_buf_friend_ready(void) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { - schedule_send(&advs[1 + CONFIG_BT_MESH_RELAY_ADV_SETS]); - } else { - schedule_send(&advs[0]); - } +#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) + (void)schedule_send(&adv_friend); +#endif } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +void bt_mesh_adv_buf_terminate(struct net_buf *buf) { int err; - for (int i = 0; i < ARRAY_SIZE(advs); i++) { - struct bt_mesh_ext_adv *adv = &advs[i]; - + STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { if (adv->buf != buf) { continue; } @@ -441,7 +446,7 @@ void bt_mesh_adv_buf_terminate(const struct net_buf *buf) k_work_submit(&adv->work.work); - return; + break; } } @@ -454,18 +459,17 @@ void bt_mesh_adv_init(void) #if defined(CONFIG_BT_MESH_DEBUG_USE_ID_ADDR) .options = BT_LE_ADV_OPT_USE_IDENTITY, #endif - }; - - for (int i = 0; i < ARRAY_SIZE(advs); i++) { - (void)memcpy(&advs[i].adv_param, &adv_param, sizeof(adv_param)); +}; + STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { + (void)memcpy(&adv->adv_param, &adv_param, sizeof(adv_param)); } } static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance) { - for (int i = 0; i < ARRAY_SIZE(advs); i++) { - if (advs[i].instance == instance) { - return &advs[i]; + STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { + if (adv->instance == instance) { + return adv; } } @@ -515,14 +519,15 @@ int bt_mesh_adv_enable(void) #endif /* CONFIG_BT_MESH_GATT_SERVER */ }; - if (advs[0].instance) { + if (adv_main.instance) { /* Already initialized */ return 0; } - for (int i = 0; i < ARRAY_SIZE(advs); i++) { - err = bt_le_ext_adv_create(&advs[i].adv_param, &adv_cb, - &advs[i].instance); + + STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { + err = bt_le_ext_adv_create(&adv->adv_param, &adv_cb, + &adv->instance); if (err) { return err; } @@ -561,5 +566,5 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len) { - return bt_data_send(advs, num_events, adv_interval, ad, ad_len); + return bt_data_send(&adv_main, num_events, adv_interval, ad, ad_len); } diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index a7d7dd1a320..cb4028662f9 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -195,7 +195,7 @@ void bt_mesh_adv_buf_local_ready(void) /* Will be handled automatically */ } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_buf_simult_ready(void) { /* Will be handled automatically */ } @@ -205,8 +205,9 @@ void bt_mesh_adv_gatt_update(void) bt_mesh_adv_buf_get_cancel(); } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +void bt_mesh_adv_buf_terminate(struct net_buf *buf) { + /* todo */ ARG_UNUSED(buf); } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index a65bd25ab53..6bf759272dd 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -20,6 +20,8 @@ #include "common/bt_str.h" +#include "host/long_wq.h" + #include "crypto.h" #include "adv.h" #include "mesh.h" diff --git a/tests/bluetooth/mesh/basic/multi_ext_adv.conf b/tests/bluetooth/mesh/basic/multi_ext_adv.conf index 610318f847b..0278bd557bd 100644 --- a/tests/bluetooth/mesh/basic/multi_ext_adv.conf +++ b/tests/bluetooth/mesh/basic/multi_ext_adv.conf @@ -51,5 +51,5 @@ CONFIG_BT_MESH_CRYPTO_LOG_LEVEL_DBG=y CONFIG_BT_MESH_ADV_LOG_LEVEL_DBG=y CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 -CONFIG_BT_MESH_RELAY_ADV_SETS=1 +CONFIG_BT_MESH_SIMULT_ADV_SETS=1 CONFIG_BT_MESH_ADV_EXT=y diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 6a171b499bf..911c5772f8b 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -638,7 +638,7 @@ static void test_tx_random_order(void) previous_checker = 0xff; buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n"); + ASSERT_FALSE(!buf[0], "Out of buffers\n"); buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); ASSERT_FALSE(!buf[1], "Out of buffers"); From ca5c21c291658487861ed2fe17d0cc7c068eb31e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:29 +0000 Subject: [PATCH 4058/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Use system workqueue for dhkey gen" This reverts commit d5bb75fa25114593f868352f0b6cfcc5af996a86. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/Kconfig | 2 +- subsys/bluetooth/mesh/prov_device.c | 9 +-------- subsys/bluetooth/mesh/provisioner.c | 11 +---------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index cb04b4dedfb..a05d3917c1d 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -210,7 +210,7 @@ config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT int "Link Ack and Transaction Ack retransmit count" - default 0 + default 2 range 0 7 help Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 6e56519eefb..992bf656202 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -358,13 +358,6 @@ static void prov_dh_key_gen(void) } } -static void prov_dh_key_gen_handler(struct k_work *work) -{ - prov_dh_key_gen(); -} - -static K_WORK_DEFINE(dh_gen_work, prov_dh_key_gen_handler); - static void prov_pub_key(const uint8_t *data) { LOG_DBG("Remote Public Key: %s", bt_hex(data, PUB_KEY_SIZE)); @@ -392,7 +385,7 @@ static void prov_pub_key(const uint8_t *data) PDU_LEN_PUB_KEY); } - k_work_submit(&dh_gen_work); + prov_dh_key_gen(); } static void notify_input_complete(void) diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 6bf759272dd..717cdbee610 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -20,8 +20,6 @@ #include "common/bt_str.h" -#include "host/long_wq.h" - #include "crypto.h" #include "adv.h" #include "mesh.h" @@ -452,13 +450,6 @@ static void prov_dh_key_gen(void) send_confirm(); } -static void prov_dh_key_gen_handler(struct k_work *work) -{ - prov_dh_key_gen(); -} - -static K_WORK_DEFINE(dh_gen_work, prov_dh_key_gen_handler); - static void prov_pub_key(const uint8_t *data) { LOG_DBG("Remote Public Key: %s", bt_hex(data, PUB_KEY_SIZE)); @@ -469,7 +460,7 @@ static void prov_pub_key(const uint8_t *data) memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, PUB_KEY_SIZE); bt_mesh_prov_link.bearer->clear_tx(); - k_work_submit(&dh_gen_work); + prov_dh_key_gen(); } static void notify_input_complete(void) From d50b5bd42ce9b7fc23ae9990dd5e9119bea3cc12 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:29 +0000 Subject: [PATCH 4059/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Rename adv relay to adv simultaneous" This reverts commit 4d33c79aca6fab97c81dfc03228b997028989562. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/Kconfig | 40 ++----- subsys/bluetooth/mesh/adv.c | 44 ++++--- subsys/bluetooth/mesh/adv.h | 22 ++-- subsys/bluetooth/mesh/adv_ext.c | 109 ++++++------------ subsys/bluetooth/mesh/adv_legacy.c | 8 +- subsys/bluetooth/mesh/beacon.c | 6 +- subsys/bluetooth/mesh/friend.c | 2 +- subsys/bluetooth/mesh/net.c | 2 +- subsys/bluetooth/mesh/pb_adv.c | 19 +-- subsys/bluetooth/mesh/statistic.c | 12 +- subsys/bluetooth/mesh/transport.c | 4 +- subsys/bluetooth/mesh/transport_legacy.c | 4 +- tests/bluetooth/mesh/basic/multi_ext_adv.conf | 2 +- .../bsim/bluetooth/mesh/src/test_advertiser.c | 18 +-- 14 files changed, 107 insertions(+), 185 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index a05d3917c1d..605e4608be7 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -103,22 +103,22 @@ menuconfig BT_MESH_ADV_EXT if BT_MESH_ADV_EXT -config BT_MESH_SIMULT_ADV_SETS - int "Maximum number of parallel advertising sets that can be used by the Bluetooth Mesh stack" +config BT_MESH_RELAY_ADV_SETS + int "Maximum of simultaneous relay message support" default 0 range 0 BT_EXT_ADV_MAX_ADV_SET - depends on BT_MESH_RELAY || BT_MESH_PB_ADV + depends on BT_MESH_RELAY help - Maximum of simultaneous message support. Requires controller support + Maximum of simultaneous relay message support. Requires controller support multiple advertising sets. config BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET bool "Use the main advertising set to relay messages" - depends on BT_MESH_SIMULT_ADV_SETS > 0 + depends on BT_MESH_RELAY_ADV_SETS > 0 help When this option is enabled, there is a message that needs to be relayed, all relay advertising sets defined by - CONFIG_BT_MESH_SIMULT_ADV_SETS are busy with relaying messages + CONFIG_BT_MESH_RELAY_ADV_SETS are busy with relaying messages and the main advertising set is not busy with sending local messages, the stack will use the main advertising set to relay the message. This maximizes the utilization efficiency of @@ -199,32 +199,6 @@ config BT_MESH_PB_ADV_RETRANS_TIMEOUT help Timeout value of retransmit provisioning PDUs. -config BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT - int "Link Open and Transaction PDU retransmit count" - default 7 if BT_MESH_SIMULT_ADV_SETS > 0 - default 0 - range 0 7 - help - Controls the number of retransmissions of original Link Open and Transaction PDU, - in addition to the first transmission. - -config BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT - int "Link Ack and Transaction Ack retransmit count" - default 2 - range 0 7 - help - Controls the number of retransmissions of original Link Open and Transaction Acknowledgment PDU, - in addition to the first transmission. - -config BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT - int "Link Close retransmit count" - default 7 if BT_MESH_SIMULT_ADV_SETS > 0 - default 2 - range 0 7 - help - Controls the number of retransmissions of original Link Close, - in addition to the first transmission. - endif # BT_MESH_PB_ADV if BT_CONN @@ -401,7 +375,7 @@ config BT_MESH_RELAY_BUF_COUNT of packet drops. When considering the message latency, also consider the values of BT_MESH_RELAY_RETRANSMIT_COUNT and BT_MESH_RELAY_RETRANSMIT_INTERVAL. A higher number of - BT_MESH_SIMULT_ADV_SETS allows the increase in the number of buffers + BT_MESH_RELAY_ADV_SETS allows the increase in the number of buffers while maintaining the latency. endif # BT_MESH_RELAY diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index c7abcd53d70..e67d96414e7 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -44,7 +44,7 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { static bool active_scanning; static K_FIFO_DEFINE(bt_mesh_adv_queue); -static K_FIFO_DEFINE(bt_mesh_simult_queue); +static K_FIFO_DEFINE(bt_mesh_relay_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) @@ -138,7 +138,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) - if (tag == BT_MESH_ADV_TAG_RELAY) { + if (tag == BT_MESH_RELAY_ADV) { return bt_mesh_adv_create_from_pool(&relay_buf_pool, adv_relay_pool, type, tag, xmit, timeout); @@ -146,7 +146,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - if (tag == BT_MESH_ADV_TAG_FRIEND) { + if (tag == BT_MESH_FRIEND_ADV) { return bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_friend_pool, type, tag, xmit, timeout); @@ -157,7 +157,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, tag, xmit, timeout); } -#if CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE +#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE static struct net_buf *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { @@ -189,7 +189,7 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &bt_mesh_simult_queue, + &bt_mesh_relay_queue, 0), #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ }; @@ -204,20 +204,19 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - tags & BT_MESH_ADV_TAG_FRIEND_BIT) { + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tags & BT_MESH_FRIEND_ADV_BIT) { return net_buf_get(&bt_mesh_friend_queue, timeout); } - if (tags & BT_MESH_ADV_TAG_LOCAL_BIT) { - return bt_mesh_adv_buf_get(timeout); +#if CONFIG_BT_MESH_RELAY_ADV_SETS + if (tags & BT_MESH_RELAY_ADV_BIT) { + return net_buf_get(&bt_mesh_relay_queue, timeout); } - -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - return net_buf_get(&bt_mesh_simult_queue, timeout); #endif + + return bt_mesh_adv_buf_get(timeout); } -#else /* !(CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ +#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) { return net_buf_get(&bt_mesh_adv_queue, timeout); @@ -229,7 +228,7 @@ struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout return bt_mesh_adv_buf_get(timeout); } -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ void bt_mesh_adv_buf_get_cancel(void) { @@ -237,9 +236,9 @@ void bt_mesh_adv_buf_get_cancel(void) k_fifo_cancel_wait(&bt_mesh_adv_queue); -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - k_fifo_cancel_wait(&bt_mesh_simult_queue); -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ +#if CONFIG_BT_MESH_RELAY_ADV_SETS + k_fifo_cancel_wait(&bt_mesh_relay_queue); +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { k_fifo_cancel_wait(&bt_mesh_friend_queue); @@ -261,17 +260,16 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, } if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_FRIEND) { + BT_MESH_ADV(buf)->tag == BT_MESH_FRIEND_ADV) { net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf)); bt_mesh_adv_buf_friend_ready(); return; } -#if CONFIG_BT_MESH_SIMULT_ADV_SETS - if (BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY || - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV) { - net_buf_put(&bt_mesh_simult_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_simult_ready(); +#if CONFIG_BT_MESH_RELAY_ADV_SETS + if (BT_MESH_ADV(buf)->tag == BT_MESH_RELAY_ADV) { + net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); + bt_mesh_adv_buf_relay_ready(); return; } #endif diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 50c5b47604c..22a8e0645e1 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -26,19 +26,17 @@ enum bt_mesh_adv_type { }; enum bt_mesh_adv_tag { - BT_MESH_ADV_TAG_LOCAL, - BT_MESH_ADV_TAG_RELAY, - BT_MESH_ADV_TAG_PROXY, - BT_MESH_ADV_TAG_FRIEND, - BT_MESH_ADV_TAG_PROV, + BT_MESH_LOCAL_ADV, + BT_MESH_RELAY_ADV, + BT_MESH_PROXY_ADV, + BT_MESH_FRIEND_ADV, }; enum bt_mesh_adv_tags { - BT_MESH_ADV_TAG_LOCAL_BIT = BIT(BT_MESH_ADV_TAG_LOCAL), - BT_MESH_ADV_TAG_RELAY_BIT = BIT(BT_MESH_ADV_TAG_RELAY), - BT_MESH_ADV_TAG_PROXY_BIT = BIT(BT_MESH_ADV_TAG_PROXY), - BT_MESH_ADV_TAG_FRIEND_BIT = BIT(BT_MESH_ADV_TAG_FRIEND), - BT_MESH_ADV_TAG_PROV_BIT = BIT(BT_MESH_ADV_TAG_PROV), + BT_MESH_LOCAL_ADV_BIT = BIT(BT_MESH_LOCAL_ADV), + BT_MESH_RELAY_ADV_BIT = BIT(BT_MESH_RELAY_ADV), + BT_MESH_PROXY_ADV_BIT = BIT(BT_MESH_PROXY_ADV), + BT_MESH_FRIEND_ADV_BIT = BIT(BT_MESH_FRIEND_ADV), }; struct bt_mesh_adv { @@ -82,9 +80,7 @@ int bt_mesh_adv_enable(void); void bt_mesh_adv_buf_local_ready(void); -void bt_mesh_adv_buf_simult_ready(void); - -void bt_mesh_adv_buf_terminate(struct net_buf *buf); +void bt_mesh_adv_buf_relay_ready(void); void bt_mesh_adv_buf_friend_ready(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 2065de372a4..d347602ac09 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -33,8 +33,8 @@ LOG_MODULE_REGISTER(bt_mesh_adv_ext); /* Convert from ms to 0.625ms units */ #define ADV_INT_FAST_MS 20 -#ifndef CONFIG_BT_MESH_SIMULT_ADV_SETS -#define CONFIG_BT_MESH_SIMULT_ADV_SETS 0 +#ifndef CONFIG_BT_MESH_RELAY_ADV_SETS +#define CONFIG_BT_MESH_RELAY_ADV_SETS 0 #endif enum { @@ -75,40 +75,32 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv); static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { .tags = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_ADV_TAG_FRIEND_BIT | + BT_MESH_FRIEND_ADV_BIT | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_ADV_TAG_PROXY_BIT | + BT_MESH_PROXY_ADV_BIT | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_ADV_TAG_RELAY_BIT | + BT_MESH_RELAY_ADV_BIT | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ - BT_MESH_ADV_TAG_LOCAL_BIT), + BT_MESH_LOCAL_ADV_BIT), .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; -#if CONFIG_BT_MESH_SIMULT_ADV_SETS -static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_SIMULT_ADV_SETS) = { - [0 ... CONFIG_BT_MESH_SIMULT_ADV_SETS - 1] = { - .tags = ( -#if defined(CONFIG_BT_MESH_RELAY) - BT_MESH_ADV_TAG_RELAY_BIT | -#endif /* CONFIG_BT_MESH_RELAY */ -#if defined(CONFIG_BT_MESH_PB_ADV) - BT_MESH_ADV_TAG_PROV_BIT | -#endif /* CONFIG_BT_MESH_PB_ADV */ - 0), - +#if CONFIG_BT_MESH_RELAY_ADV_SETS +static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_RELAY_ADV_SETS) = { + [0 ... CONFIG_BT_MESH_RELAY_ADV_SETS - 1] = { + .tags = BT_MESH_RELAY_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), } }; -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) #define ADV_EXT_FRIEND 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { - .tags = BT_MESH_ADV_TAG_FRIEND_BIT, + .tags = BT_MESH_FRIEND_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ @@ -118,25 +110,25 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) #define ADV_EXT_GATT 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { - .tags = BT_MESH_ADV_TAG_PROXY_BIT, + .tags = BT_MESH_PROXY_ADV_BIT, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #define ADV_EXT_GATT 0 #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ -#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_SIMULT_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) +#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT) BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT, "Insufficient adv instances"); static inline struct bt_mesh_ext_adv *relay_adv_get(void) { -#if CONFIG_BT_MESH_SIMULT_ADV_SETS +#if CONFIG_BT_MESH_RELAY_ADV_SETS return adv_relay; -#else /* !CONFIG_BT_MESH_SIMULT_ADV_SETS */ +#else /* !CONFIG_BT_MESH_RELAY_ADV_SETS */ return &adv_main; -#endif /* CONFIG_BT_MESH_SIMULT_ADV_SETS */ +#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ } static inline struct bt_mesh_ext_adv *gatt_adv_get(void) @@ -267,13 +259,20 @@ static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) return err; } -static const char * const adv_tag_to_str[] = { - [BT_MESH_ADV_TAG_LOCAL] = "local adv", - [BT_MESH_ADV_TAG_RELAY] = "relay adv", - [BT_MESH_ADV_TAG_PROXY] = "proxy adv", - [BT_MESH_ADV_TAG_FRIEND] = "friend adv", - [BT_MESH_ADV_TAG_PROV] = "prov adv", -}; +static const char *adv_tag_to_str(enum bt_mesh_adv_tags tags) +{ + if (tags & BT_MESH_LOCAL_ADV_BIT) { + return "local adv"; + } else if (tags & BT_MESH_PROXY_ADV_BIT) { + return "proxy adv"; + } else if (tags & BT_MESH_RELAY_ADV_BIT) { + return "relay adv"; + } else if (tags & BT_MESH_FRIEND_ADV_BIT) { + return "friend adv"; + } else { + return "(unknown tags)"; + } +} static void send_pending_adv(struct k_work *work) { @@ -290,9 +289,8 @@ static void send_pending_adv(struct k_work *work) */ int64_t duration = k_uptime_delta(&adv->timestamp); - LOG_DBG("Advertising stopped after %u ms for %s", (uint32_t)duration, - adv->buf ? adv_tag_to_str[BT_MESH_ADV(adv->buf)->tag] : - adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]); + LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tags, + adv_tag_to_str(adv->tags)); atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); @@ -328,7 +326,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_ADV_TAG_PROXY_BIT)) { + !(adv->tags & BT_MESH_RELAY_ADV_BIT)) { return; } @@ -371,9 +369,8 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); - if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tags & BT_MESH_ADV_TAG_FRIEND_BIT) || - (CONFIG_BT_MESH_SIMULT_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_RELAY_BIT)) { + if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tags & BT_MESH_FRIEND_ADV_BIT) || + (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_RELAY_ADV_BIT)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. @@ -397,11 +394,11 @@ void bt_mesh_adv_buf_local_ready(void) (void)schedule_send(&adv_main); } -void bt_mesh_adv_buf_simult_ready(void) +void bt_mesh_adv_buf_relay_ready(void) { struct bt_mesh_ext_adv *adv = relay_adv_get(); - for (int i = 0; i < CONFIG_BT_MESH_SIMULT_ADV_SETS; i++) { + for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { if (schedule_send(&adv[i])) { return; } @@ -420,36 +417,6 @@ void bt_mesh_adv_buf_friend_ready(void) #endif } -void bt_mesh_adv_buf_terminate(struct net_buf *buf) -{ - int err; - - STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) { - if (adv->buf != buf) { - continue; - } - - if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { - return; - } - - err = bt_le_ext_adv_stop(adv->instance); - if (err) { - LOG_ERR("Failed to stop adv %d", err); - return; - } - - /* Do not call `cb:end`, since this user action */ - BT_MESH_ADV(adv->buf)->cb = NULL; - - atomic_set_bit(adv->flags, ADV_FLAG_SENT); - - k_work_submit(&adv->work.work); - - break; - } -} - void bt_mesh_adv_init(void) { struct bt_le_adv_param adv_param = { diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index cb4028662f9..8136aef9f22 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -195,7 +195,7 @@ void bt_mesh_adv_buf_local_ready(void) /* Will be handled automatically */ } -void bt_mesh_adv_buf_simult_ready(void) +void bt_mesh_adv_buf_relay_ready(void) { /* Will be handled automatically */ } @@ -205,12 +205,6 @@ void bt_mesh_adv_gatt_update(void) bt_mesh_adv_buf_get_cancel(); } -void bt_mesh_adv_buf_terminate(struct net_buf *buf) -{ - /* todo */ - ARG_UNUSED(buf); -} - void bt_mesh_adv_init(void) { k_thread_create(&adv_thread_data, adv_thread_stack, diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index afdea5b4c6a..8c0ac3b54e9 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -271,7 +271,7 @@ static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *b return false; } - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV, PROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate beacon buffer"); @@ -335,7 +335,7 @@ static int unprovisioned_beacon_send(void) LOG_DBG(""); - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV, UNPROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate beacon buffer"); @@ -362,7 +362,7 @@ static int unprovisioned_beacon_send(void) if (prov->uri) { size_t len; - buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_LOCAL_ADV, UNPROV_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate URI buffer"); diff --git a/subsys/bluetooth/mesh/friend.c b/subsys/bluetooth/mesh/friend.c index 73b75eadf4f..179755d9706 100644 --- a/subsys/bluetooth/mesh/friend.c +++ b/subsys/bluetooth/mesh/friend.c @@ -1281,7 +1281,7 @@ static void friend_timeout(struct k_work *work) frnd->queue_size--; send_last: - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_FRIEND, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_FRIEND_ADV, FRIEND_XMIT, K_NO_WAIT); if (!buf) { LOG_ERR("Unable to allocate friend adv buffer"); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 61efaeb2c81..2cfc709c648 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -712,7 +712,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, transmit = bt_mesh_net_transmit_get(); } - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_RELAY_ADV, transmit, K_NO_WAIT); if (!buf) { LOG_DBG("Out of relay buffers"); diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index cb5f53f32b7..27d55763298 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -55,11 +55,11 @@ LOG_MODULE_REGISTER(bt_mesh_pb_adv); /* Acked messages, will do retransmissions manually, taking acks into account: */ -#define RETRANSMITS_RELIABLE CONFIG_BT_MESH_PB_ADV_TRANS_PDU_RETRANSMIT_COUNT +#define RETRANSMITS_RELIABLE 0 /* PDU acks: */ -#define RETRANSMITS_ACK CONFIG_BT_MESH_PB_ADV_TRANS_ACK_RETRANSMIT_COUNT +#define RETRANSMITS_ACK 2 /* Link close retransmits: */ -#define RETRANSMITS_LINK_CLOSE CONFIG_BT_MESH_PB_ADV_LINK_CLOSE_RETRANSMIT_COUNT +#define RETRANSMITS_LINK_CLOSE 2 enum { ADV_LINK_ACTIVE, /* Link has been opened */ @@ -178,15 +178,8 @@ static void free_segments(void) } link.tx.buf[i] = NULL; - - /* Terminate active adv */ - if (BT_MESH_ADV(buf)->busy == 0U) { - bt_mesh_adv_buf_terminate(buf); - } else { - /* Mark as canceled */ - BT_MESH_ADV(buf)->busy = 0U; - } - + /* Mark as canceled */ + BT_MESH_ADV(buf)->busy = 0U; net_buf_unref(buf); } } @@ -258,7 +251,7 @@ static struct net_buf *adv_buf_create(uint8_t retransmits) { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, + buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(retransmits, 20), BUF_TIMEOUT); if (!buf) { diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 21c451bee73..046fa3c0eeb 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -24,22 +24,22 @@ void bt_mesh_stat_reset(void) void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (adv->tag == BT_MESH_LOCAL_ADV) { stat.tx_local_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (adv->tag == BT_MESH_RELAY_ADV) { stat.tx_adv_relay_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (adv->tag == BT_MESH_FRIEND_ADV) { stat.tx_friend_planned++; } } void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (adv->tag == BT_MESH_LOCAL_ADV) { stat.tx_local_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (adv->tag == BT_MESH_RELAY_ADV) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (adv->tag == BT_MESH_FRIEND_ADV) { stat.tx_friend_succeeded++; } } diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index f4c49aa6856..0343993e348 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -124,7 +124,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, tx->xmit, BUF_TIMEOUT); if (!buf) { LOG_ERR("Out of network buffers"); @@ -414,7 +414,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, tx->xmit, BUF_TIMEOUT); if (!seg) { LOG_DBG("Allocating segment failed"); diff --git a/subsys/bluetooth/mesh/transport_legacy.c b/subsys/bluetooth/mesh/transport_legacy.c index 23e103b4370..475a0429f75 100644 --- a/subsys/bluetooth/mesh/transport_legacy.c +++ b/subsys/bluetooth/mesh/transport_legacy.c @@ -131,7 +131,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, tx->xmit, BUF_TIMEOUT); if (!buf) { LOG_ERR("Out of network buffers"); @@ -401,7 +401,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, tx->xmit, BUF_TIMEOUT); if (!seg) { LOG_DBG("Allocating segment failed"); diff --git a/tests/bluetooth/mesh/basic/multi_ext_adv.conf b/tests/bluetooth/mesh/basic/multi_ext_adv.conf index 0278bd557bd..610318f847b 100644 --- a/tests/bluetooth/mesh/basic/multi_ext_adv.conf +++ b/tests/bluetooth/mesh/basic/multi_ext_adv.conf @@ -51,5 +51,5 @@ CONFIG_BT_MESH_CRYPTO_LOG_LEVEL_DBG=y CONFIG_BT_MESH_ADV_LOG_LEVEL_DBG=y CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 -CONFIG_BT_MESH_SIMULT_ADV_SETS=1 +CONFIG_BT_MESH_RELAY_ADV_SETS=1 CONFIG_BT_MESH_ADV_EXT=y diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 911c5772f8b..590eed8eebc 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -81,7 +81,7 @@ static void adv_init(void) static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmit) { for (int i = 0; i < num_buf; i++) { - *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); ASSERT_FALSE(!*buf, "Out of buffers"); @@ -94,7 +94,7 @@ static void verify_adv_queue_overflow(void) struct net_buf *dummy_buf; /* Verity Queue overflow */ - dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_TRUE(!dummy_buf, "Unexpected extra buffer"); } @@ -160,7 +160,7 @@ static void realloc_end_cb(int err, void *cb_data) struct net_buf *buf = (struct net_buf *)cb_data; ASSERT_EQUAL(0, err); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_FALSE(!buf, "Out of buffers"); @@ -425,7 +425,7 @@ static void test_tx_cb_single(void) bt_init(); adv_init(); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); ASSERT_FALSE(!buf, "Out of buffers"); @@ -530,7 +530,7 @@ static void test_tx_proxy_mixin(void) * Advertising the proxy service should be resumed after * finishing advertising the message. */ - struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, BT_MESH_TRANSMIT(5, 20), K_NO_WAIT); net_buf_add_mem(buf, txt_msg, sizeof(txt_msg)); bt_mesh_adv_send(buf, NULL, NULL); @@ -636,16 +636,16 @@ static void test_tx_random_order(void) /* Verify random order calls */ num_adv_sent = ARRAY_SIZE(buf); previous_checker = 0xff; - buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); - ASSERT_FALSE(!buf[0], "Out of buffers\n"); - buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + ASSERT_FALSE(!buf[0], "Out of buffers"); + buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); ASSERT_FALSE(!buf[1], "Out of buffers"); send_adv_buf(buf[0], 0, 0xff); - buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV, xmit, K_NO_WAIT); ASSERT_FALSE(!buf[2], "Out of buffers"); From db98744932c00baf43e2bbbddd4faba52df2966d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:29 +0000 Subject: [PATCH 4060/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Remove bits for adv tag" This reverts commit 2c3b9c4f763085faa0c4654bc4cce8baaf32b89c. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/adv.c | 14 +++++------ subsys/bluetooth/mesh/adv.h | 17 ++++--------- subsys/bluetooth/mesh/adv_ext.c | 42 +++++++++++++++---------------- subsys/bluetooth/mesh/statistic.c | 12 ++++----- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index e67d96414e7..2132c14e151 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -138,7 +138,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) - if (tag == BT_MESH_RELAY_ADV) { + if (tag & BT_MESH_RELAY_ADV) { return bt_mesh_adv_create_from_pool(&relay_buf_pool, adv_relay_pool, type, tag, xmit, timeout); @@ -146,7 +146,7 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - if (tag == BT_MESH_FRIEND_ADV) { + if (tag & BT_MESH_FRIEND_ADV) { return bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_friend_pool, type, tag, xmit, timeout); @@ -202,14 +202,14 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return process_events(events, ARRAY_SIZE(events)); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout) { - if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tags & BT_MESH_FRIEND_ADV_BIT) { + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tag & BT_MESH_FRIEND_ADV) { return net_buf_get(&bt_mesh_friend_queue, timeout); } #if CONFIG_BT_MESH_RELAY_ADV_SETS - if (tags & BT_MESH_RELAY_ADV_BIT) { + if (tag & BT_MESH_RELAY_ADV) { return net_buf_get(&bt_mesh_relay_queue, timeout); } #endif @@ -222,9 +222,9 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return net_buf_get(&bt_mesh_adv_queue, timeout); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout) +struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout) { - ARG_UNUSED(tags); + ARG_UNUSED(tag); return bt_mesh_adv_buf_get(timeout); } diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 22a8e0645e1..3d0acf8a7ac 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -26,17 +26,10 @@ enum bt_mesh_adv_type { }; enum bt_mesh_adv_tag { - BT_MESH_LOCAL_ADV, - BT_MESH_RELAY_ADV, - BT_MESH_PROXY_ADV, - BT_MESH_FRIEND_ADV, -}; - -enum bt_mesh_adv_tags { - BT_MESH_LOCAL_ADV_BIT = BIT(BT_MESH_LOCAL_ADV), - BT_MESH_RELAY_ADV_BIT = BIT(BT_MESH_RELAY_ADV), - BT_MESH_PROXY_ADV_BIT = BIT(BT_MESH_PROXY_ADV), - BT_MESH_FRIEND_ADV_BIT = BIT(BT_MESH_FRIEND_ADV), + BT_MESH_LOCAL_ADV = BIT(0), + BT_MESH_RELAY_ADV = BIT(1), + BT_MESH_PROXY_ADV = BIT(2), + BT_MESH_FRIEND_ADV = BIT(3), }; struct bt_mesh_adv { @@ -64,7 +57,7 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tags tags, k_timeout_t timeout); +struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index d347602ac09..5c1a2bc3c32 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -60,7 +60,7 @@ enum { }; struct bt_mesh_ext_adv { - enum bt_mesh_adv_tags tags; + uint8_t tag; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; struct net_buf *buf; @@ -73,17 +73,17 @@ static void send_pending_adv(struct k_work *work); static bool schedule_send(struct bt_mesh_ext_adv *adv); static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { - .tags = ( + .tag = ( #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) - BT_MESH_FRIEND_ADV_BIT | + BT_MESH_FRIEND_ADV | #endif #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) - BT_MESH_PROXY_ADV_BIT | + BT_MESH_PROXY_ADV | #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET) - BT_MESH_RELAY_ADV_BIT | + BT_MESH_RELAY_ADV | #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */ - BT_MESH_LOCAL_ADV_BIT), + BT_MESH_LOCAL_ADV), .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; @@ -91,7 +91,7 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = { #if CONFIG_BT_MESH_RELAY_ADV_SETS static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_RELAY_ADV_SETS) = { [0 ... CONFIG_BT_MESH_RELAY_ADV_SETS - 1] = { - .tags = BT_MESH_RELAY_ADV_BIT, + .tag = BT_MESH_RELAY_ADV, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), } }; @@ -100,7 +100,7 @@ static STRUCT_SECTION_ITERABLE_ARRAY(bt_mesh_ext_adv, adv_relay, CONFIG_BT_MESH_ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) #define ADV_EXT_FRIEND 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { - .tags = BT_MESH_FRIEND_ADV_BIT, + .tag = BT_MESH_FRIEND_ADV, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ @@ -110,7 +110,7 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = { #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) #define ADV_EXT_GATT 1 static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = { - .tags = BT_MESH_PROXY_ADV_BIT, + .tag = BT_MESH_PROXY_ADV, .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), }; #else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ @@ -259,18 +259,18 @@ static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) return err; } -static const char *adv_tag_to_str(enum bt_mesh_adv_tags tags) +static const char *adv_tag_to_str(enum bt_mesh_adv_tag tag) { - if (tags & BT_MESH_LOCAL_ADV_BIT) { + if (tag & BT_MESH_LOCAL_ADV) { return "local adv"; - } else if (tags & BT_MESH_PROXY_ADV_BIT) { + } else if (tag & BT_MESH_PROXY_ADV) { return "proxy adv"; - } else if (tags & BT_MESH_RELAY_ADV_BIT) { + } else if (tag & BT_MESH_RELAY_ADV) { return "relay adv"; - } else if (tags & BT_MESH_FRIEND_ADV_BIT) { + } else if (tag & BT_MESH_FRIEND_ADV) { return "friend adv"; } else { - return "(unknown tags)"; + return "(unknown tag)"; } } @@ -289,8 +289,8 @@ static void send_pending_adv(struct k_work *work) */ int64_t duration = k_uptime_delta(&adv->timestamp); - LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tags, - adv_tag_to_str(adv->tags)); + LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tag, + adv_tag_to_str(adv->tag)); atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); @@ -308,7 +308,7 @@ static void send_pending_adv(struct k_work *work) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED); - while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tags, K_NO_WAIT))) { + while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tag, K_NO_WAIT))) { /* busy == 0 means this was canceled */ if (!BT_MESH_ADV(buf)->busy) { net_buf_unref(buf); @@ -326,7 +326,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_RELAY_ADV_BIT)) { + !(adv->tag & BT_MESH_PROXY_ADV)) { return; } @@ -369,8 +369,8 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv) atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); - if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tags & BT_MESH_FRIEND_ADV_BIT) || - (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_RELAY_ADV_BIT)) { + if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tag & BT_MESH_FRIEND_ADV) || + (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tag == BT_MESH_RELAY_ADV)) { k_work_reschedule(&adv->work, K_NO_WAIT); } else { /* The controller will send the next advertisement immediately. diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 046fa3c0eeb..5b1ffe7e0f5 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -24,22 +24,22 @@ void bt_mesh_stat_reset(void) void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_LOCAL_ADV) { + if (adv->tag & BT_MESH_LOCAL_ADV) { stat.tx_local_planned++; - } else if (adv->tag == BT_MESH_RELAY_ADV) { + } else if (adv->tag & BT_MESH_RELAY_ADV) { stat.tx_adv_relay_planned++; - } else if (adv->tag == BT_MESH_FRIEND_ADV) { + } else if (adv->tag & BT_MESH_FRIEND_ADV) { stat.tx_friend_planned++; } } void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) { - if (adv->tag == BT_MESH_LOCAL_ADV) { + if (adv->tag & BT_MESH_LOCAL_ADV) { stat.tx_local_succeeded++; - } else if (adv->tag == BT_MESH_RELAY_ADV) { + } else if (adv->tag & BT_MESH_RELAY_ADV) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag == BT_MESH_FRIEND_ADV) { + } else if (adv->tag & BT_MESH_FRIEND_ADV) { stat.tx_friend_succeeded++; } } From 2a3c5ddd0c259d34b8b984d43a137bee004a170b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:30 +0000 Subject: [PATCH 4061/4498] Revert "[nrf fromlist] net: iface: Introduce TX mutex locking" This reverts commit 9ed7de1afad3ebc08a3ce379bee0bbbbd9702414. Signed-off-by: Dominik Ermel --- include/zephyr/net/net_if.h | 29 ----------------------------- subsys/net/ip/net_if.c | 3 --- subsys/net/l2/ethernet/arp.c | 2 -- 3 files changed, 34 deletions(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 92a59ad3b73..b06bf74de03 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -212,9 +212,6 @@ enum net_if_flag { /** IPv6 Multicast Listener Discovery disabled. */ NET_IF_IPV6_NO_MLD, - /** Mutex locking on TX data path disabled on the interface. */ - NET_IF_NO_TX_LOCK, - /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ NET_IF_NUM_FLAGS @@ -616,7 +613,6 @@ struct net_if { #endif struct k_mutex lock; - struct k_mutex tx_lock; }; static inline void net_if_lock(struct net_if *iface) @@ -633,31 +629,6 @@ static inline void net_if_unlock(struct net_if *iface) k_mutex_unlock(&iface->lock); } -static inline bool net_if_flag_is_set(struct net_if *iface, - enum net_if_flag value); - -static inline void net_if_tx_lock(struct net_if *iface) -{ - NET_ASSERT(iface); - - if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) { - return; - } - - (void)k_mutex_lock(&iface->tx_lock, K_FOREVER); -} - -static inline void net_if_tx_unlock(struct net_if *iface) -{ - NET_ASSERT(iface); - - if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) { - return; - } - - k_mutex_unlock(&iface->tx_lock); -} - /** * @brief Set a value in network interface flags * diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 026eaa88b48..035e18da74f 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -265,9 +265,7 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) } } - net_if_tx_lock(iface); status = net_if_l2(iface)->send(iface, pkt); - net_if_tx_unlock(iface); if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) { uint32_t end_tick = k_cycle_get_32(); @@ -439,7 +437,6 @@ static inline void init_iface(struct net_if *iface) #endif k_mutex_init(&iface->lock); - k_mutex_init(&iface->tx_lock); api->init(iface); } diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 39a06ed64a0..35a2ec63a64 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -534,9 +534,7 @@ static void arp_update(struct net_if *iface, * the pkt are not counted twice and the packet filter * callbacks are only called once. */ - net_if_tx_lock(iface); ret = net_if_l2(iface)->send(iface, pkt); - net_if_tx_unlock(iface); if (ret < 0) { net_pkt_unref(pkt); } From 17a42452a6f7f4a437377636b4f90ae86f1f7a96 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:30 +0000 Subject: [PATCH 4062/4498] Revert "[nrf fromtree] net: arp: Directly send the queued pkt" This reverts commit a707fc77ef2d80ce5f4bed6e5c9bdd6bc0cc3912. Signed-off-by: Dominik Ermel --- subsys/net/l2/ethernet/arp.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 35a2ec63a64..f26c2f7ba96 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -514,8 +514,6 @@ static void arp_update(struct net_if *iface, sys_slist_prepend(&arp_table, &entry->node); while (!k_fifo_is_empty(&entry->pending_queue)) { - int ret; - pkt = k_fifo_get(&entry->pending_queue, K_FOREVER); /* Set the dst in the pending packet */ @@ -527,17 +525,7 @@ static void arp_update(struct net_if *iface, net_sprint_ipv4_addr(&entry->ip), pkt, pkt->frags); - /* We directly send the packet without first queueing it. - * The pkt has already been queued for sending, once by - * net_if and second time in the ARP queue. We must not - * queue it twice in net_if so that the statistics of - * the pkt are not counted twice and the packet filter - * callbacks are only called once. - */ - ret = net_if_l2(iface)->send(iface, pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } + net_if_queue_tx(iface, pkt); } k_mutex_unlock(&arp_mutex); From 735fc1ef566dab86284cf9f71737ddc8ac747d21 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:30 +0000 Subject: [PATCH 4063/4498] Revert "[nrf fromtree] net: Remove unnecessary lock" This reverts commit 2a8c218f530fcc80ef3209ca49d36dc7a68d2b59. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_if.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 035e18da74f..828e48ecf78 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -448,6 +448,8 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt) enum net_verdict verdict = NET_OK; int status = -EIO; + net_if_lock(iface); + if (!net_if_flag_is_set(iface, NET_IF_LOWER_UP) || net_if_flag_is_set(iface, NET_IF_SUSPENDED)) { /* Drop packet if interface is not up */ @@ -530,6 +532,8 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt) net_if_queue_tx(iface, pkt); } + net_if_unlock(iface); + return verdict; } From c755dc0f0ae81bee520f57398386f1a40c8172a9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:31 +0000 Subject: [PATCH 4064/4498] Revert "[nrf fromtree] doc: gsg: macOS: Include instructions to add homebrew to the path" This reverts commit 196bab5029e3217952429c58f38a2be656dfee94. Signed-off-by: Dominik Ermel --- doc/develop/getting_started/index.rst | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index f7a76a71585..4a1b345ee62 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -118,32 +118,12 @@ The current minimum required version for the main dependencies are: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - #. After the Homebrew installation script completes, follow the on-screen - instructions to add the Homebrew installation to the path. - - * On macOS running on Apple Silicon, this is achieved with: - - .. code-block:: bash - - (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> ~/.zprofile - source ~/.zprofile - - * On macOS running on Intel, use the command for Apple Silicon, but replace ``/opt/homebrew/`` with ``/usr/local/``. - #. Use ``brew`` to install the required dependencies: .. code-block:: bash brew install cmake ninja gperf python3 ccache qemu dtc wget libmagic - #. Add the Homebrew Python folder to the path, in order to be able to - execute ``python`` and ``pip`` as well ``python3`` and ``pip3``. - - .. code-block:: bash - - (echo; echo 'export PATH="'$(brew --prefix)'/opt/python/libexec/bin:$PATH"') >> ~/.zprofile - source ~/.zprofile - .. group-tab:: Windows .. note:: From dabcf79b4eec5cb5ace667bc7e936ec981783aca Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:31 +0000 Subject: [PATCH 4065/4498] Revert "[nrf fromtree] twister: pytest: Improve reporting failed pytest scenarios" This reverts commit ac5a9860b73bdbde2e8ba936fdc35a5e7654189c. Signed-off-by: Dominik Ermel --- .../device/hardware_adapter.py | 1 + scripts/pylib/twister/twisterlib/harness.py | 2 -- scripts/pylib/twister/twisterlib/reports.py | 5 +--- scripts/pylib/twister/twisterlib/runner.py | 26 ++++--------------- .../pytest_integration/test_harness_pytest.py | 2 -- 5 files changed, 7 insertions(+), 29 deletions(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 3b7bf5d8214..403978eed9a 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -116,6 +116,7 @@ def _flash_and_run(self) -> None: stdout_decoded = stdout.decode(errors='ignore') with open(self.device_log_path, 'a+') as log_file: log_file.write(stdout_decoded) + logger.debug(f'Flashing output:\n{stdout_decoded}') if self.device_config.post_flash_script: self._run_custom_script(self.device_config.post_flash_script, self.base_timeout) if process is not None and process.returncode == 0: diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index bd86df1b4df..951a8c40010 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -400,10 +400,8 @@ def _parse_report_file(self, report): if elem_ts := root.find('testsuite'): if elem_ts.get('failures') != '0': self.state = 'failed' - self.instance.reason = f"{elem_ts.get('failures')}/{elem_ts.get('tests')} pytest scenario(s) failed" elif elem_ts.get('errors') != '0': self.state = 'error' - self.instance.reason = 'Error during pytest execution' elif elem_ts.get('skipped') == elem_ts.get('tests'): self.state = 'skipped' else: diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index be1bbb4dbd7..c1f160caad9 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -246,7 +246,6 @@ def json_report(self, filename, version="NA"): for instance in self.instances.values(): suite = {} handler_log = os.path.join(instance.build_dir, "handler.log") - pytest_log = os.path.join(instance.build_dir, "twister_harness.log") build_log = os.path.join(instance.build_dir, "build.log") device_log = os.path.join(instance.build_dir, "device.log") @@ -285,9 +284,7 @@ def json_report(self, filename, version="NA"): suite['status'] = instance.status suite["reason"] = instance.reason # FIXME - if os.path.exists(pytest_log): - suite["log"] = self.process_log(pytest_log) - elif os.path.exists(handler_log): + if os.path.exists(handler_log): suite["log"] = self.process_log(handler_log) elif os.path.exists(device_log): suite["log"] = self.process_log(device_log) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 4dbdb21f882..ef41084cdd4 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -40,9 +40,6 @@ from twisterlib.log_helper import log_command from twisterlib.testinstance import TestInstance -from twisterlib.environment import TwisterEnv -from twisterlib.testsuite import TestSuite -from twisterlib.platform import Platform from twisterlib.testplan import change_skip_to_error_if_integration from twisterlib.harness import HarnessImporter, Pytest @@ -223,7 +220,7 @@ class CMake: config_re = re.compile('(CONFIG_[A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$') dt_re = re.compile('([A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$') - def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_dir, jobserver): + def __init__(self, testsuite, platform, source_dir, build_dir, jobserver): self.cwd = None self.capture_output = True @@ -417,7 +414,7 @@ def run_cmake(self, args="", filter_stages=[]): class FilterBuilder(CMake): - def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_dir, jobserver): + def __init__(self, testsuite, platform, source_dir, build_dir, jobserver): super().__init__(testsuite, platform, source_dir, build_dir, jobserver) self.log = "config-twister.log" @@ -520,7 +517,7 @@ def parse_generated(self, filter_stages=[]): class ProjectBuilder(FilterBuilder): - def __init__(self, instance: TestInstance, env: TwisterEnv, jobserver, **kwargs): + def __init__(self, instance, env, jobserver, **kwargs): super().__init__(instance.testsuite, instance.platform, instance.testsuite.source_dir, instance.build_dir, jobserver) self.log = "build.log" @@ -530,7 +527,8 @@ def __init__(self, instance: TestInstance, env: TwisterEnv, jobserver, **kwargs) self.env = env self.duts = None - def log_info(self, filename, inline_logs, log_testcases=False): + @staticmethod + def log_info(filename, inline_logs): filename = os.path.abspath(os.path.realpath(filename)) if inline_logs: logger.info("{:-^100}".format(filename)) @@ -544,17 +542,6 @@ def log_info(self, filename, inline_logs, log_testcases=False): logger.error(data) logger.info("{:-^100}".format(filename)) - - if log_testcases: - for tc in self.instance.testcases: - if not tc.reason: - continue - logger.info( - f"\n{str(tc.name).center(100, '_')}\n" - f"{tc.reason}\n" - f"{100*'_'}\n" - f"{tc.output}" - ) else: logger.error("see: " + Fore.YELLOW + filename + Fore.RESET) @@ -564,12 +551,9 @@ def log_info_file(self, inline_logs): b_log = "{}/build.log".format(build_dir) v_log = "{}/valgrind.log".format(build_dir) d_log = "{}/device.log".format(build_dir) - pytest_log = "{}/twister_harness.log".format(build_dir) if os.path.exists(v_log) and "Valgrind" in self.instance.reason: self.log_info("{}".format(v_log), inline_logs) - elif os.path.exists(pytest_log) and os.path.getsize(pytest_log) > 0: - self.log_info("{}".format(pytest_log), inline_logs, log_testcases=True) elif os.path.exists(h_log) and os.path.getsize(h_log) > 0: self.log_info("{}".format(h_log), inline_logs) elif os.path.exists(d_log) and os.path.getsize(d_log) > 0: diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index 150980059b3..ab4baf88656 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -188,8 +188,6 @@ def test_err(): assert tc.status == "failed" assert tc.output assert tc.reason - assert testinstance.reason - assert '2/2' in testinstance.reason def test_if_report_with_skip(pytester, testinstance: TestInstance): From ca92a3b99bd4ba58f3974efb9abcb2ddbb3ce937 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:31 +0000 Subject: [PATCH 4066/4498] Revert "[nrf fromtree] twister: pytest: Parametrize scope of the dut fixture" This reverts commit 8186e5cf7cf25d3586896060730eddd6145589c5. Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 9 ++------- doc/develop/test/twister.rst | 5 ----- .../src/twister_harness/fixtures.py | 13 ++++--------- .../src/twister_harness/plugin.py | 5 ----- scripts/pylib/twister/twisterlib/harness.py | 5 +---- scripts/schemas/twister/testsuite-schema.yaml | 8 -------- .../pytest_integration/test_harness_pytest.py | 19 ------------------- 7 files changed, 7 insertions(+), 57 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 087c45bcce8..d0fad4d6be6 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -69,9 +69,6 @@ DUT (initialize logging, flash device, connect serial etc). This fixture yields a device prepared according to the requested type (native posix, qemu, hardware, etc.). All types of devices share the same API. This allows for writing tests which are device-type-agnostic. -Scope of this fixture is determined by the ``pytest_dut_scope`` -keyword placed under ``harness_config`` section. - .. code-block:: python @@ -84,10 +81,8 @@ shell ----- Provide an object with methods used to interact with shell application. -It calls ``wait_for_promt`` method, to not start scenario until DUT is ready. -Note that it uses ``dut`` fixture, so ``dut`` can be skipped when ``shell`` is used. -Scope of this fixture is determined by the ``pytest_dut_scope`` -keyword placed under ``harness_config`` section. +It calls `wait_for_promt` method, to not start scenario until DUT is ready. +Note that it uses `dut` fixture, so `dut` can be skipped when `shell` is used. .. code-block:: python diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index a61744eec6d..4456386b77c 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -501,11 +501,6 @@ harness_config: pytest_args: (default empty) Specify a list of additional arguments to pass to ``pytest``. - pytest_dut_scope: (default function) - The scope for which ``dut`` and ``shell`` pytest fixtures are shared. - If the scope is set to ``function``, DUT is launched for every test case - in python script. For ``session`` scope, DUT is launched only once. - robot_test_path: (default empty) Specify a path to a file containing a Robot Framework test suite to be run. diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py index f2b1b53706c..e2e82674ada 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py @@ -36,16 +36,11 @@ def device_object(twister_harness_config: TwisterHarnessConfig) -> Generator[Dev device_object.close() -def determine_scope(fixture_name, config): - if dut_scope := config.getoption("--dut-scope", None): - return dut_scope - return 'function' - - -@pytest.fixture(scope=determine_scope) +@pytest.fixture(scope='function') def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generator[DeviceAdapter, None, None]: """Return launched device - with run application.""" - device_object.initialize_log_files(request.node.name) + test_name = request.node.name + device_object.initialize_log_files(test_name) try: device_object.launch() yield device_object @@ -53,7 +48,7 @@ def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generat device_object.close() -@pytest.fixture(scope=determine_scope) +@pytest.fixture(scope='function') def shell(dut: DeviceAdapter) -> Shell: """Return ready to use shell interface""" shell = Shell(dut, timeout=20.0) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index dbd3465aba1..076d36d4cc9 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -100,11 +100,6 @@ def pytest_addoption(parser: pytest.Parser): metavar='PATH', help='Script executed after closing serial connection.' ) - twister_harness_group.addoption( - '--dut-scope', - choices=('function', 'class', 'module', 'package', 'session'), - help='The scope for which `dut` and `shell` fixtures are shared.' - ) def pytest_configure(config: pytest.Config): diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 951a8c40010..6ae2622c810 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -247,7 +247,6 @@ def generate_command(self): config = self.instance.testsuite.harness_config pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] pytest_args = config.get('pytest_args', []) if config else [] - pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None command = [ 'pytest', '--twister-harness', @@ -261,8 +260,6 @@ def generate_command(self): command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) command.extend(pytest_args) - if pytest_dut_scope: - command.append(f'--dut-scope={pytest_dut_scope}') handler: Handler = self.instance.handler @@ -409,7 +406,7 @@ def _parse_report_file(self, report): self.instance.execution_time = float(elem_ts.get('time')) for elem_tc in elem_ts.findall('testcase'): - tc = self.instance.add_testcase(f"{self.id}.{elem_tc.get('name')}") + tc = self.instance.get_case_or_create(f"{self.id}.{elem_tc.get('name')}") tc.duration = float(elem_tc.get('time')) elem = elem_tc.find('*') if elem is None: diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 1e198173c72..96a121767a5 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -104,10 +104,6 @@ mapping: required: false sequence: - type: str - "pytest_dut_scope": - type: str - enum: ["function", "class", "module", "package", "session"] - required: false "regex": type: seq required: false @@ -308,10 +304,6 @@ mapping: required: false sequence: - type: str - "pytest_dut_scope": - type: str - enum: ["function", "class", "module", "package", "session"] - required: false "regex": type: seq required: false diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index ab4baf88656..e1b27a0cf02 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -48,25 +48,6 @@ def test_pytest_command(testinstance: TestInstance, device_type): assert c in command -def test_pytest_command_dut_scope(testinstance: TestInstance): - pytest_harness = Pytest() - dut_scope = 'session' - testinstance.testsuite.harness_config['pytest_dut_scope'] = dut_scope - pytest_harness.configure(testinstance) - command = pytest_harness.generate_command() - assert f'--dut-scope={dut_scope}' in command - - -def test_pytest_command_extra_args(testinstance: TestInstance): - pytest_harness = Pytest() - pytest_args = ['-k test1', '-m mark1'] - testinstance.testsuite.harness_config['pytest_args'] = pytest_args - pytest_harness.configure(testinstance) - command = pytest_harness.generate_command() - for c in pytest_args: - assert c in command - - @pytest.mark.parametrize( ('pytest_root', 'expected'), [ From 9f7a516ca14049980948cea8dec827d45462c98d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:31 +0000 Subject: [PATCH 4067/4498] Revert "[nrf fromtree] twister: pytest: Move fixtures to one file" This reverts commit 4a05f790ba8345cc348c2ca2f7fcf84dfa983e8d. Signed-off-by: Dominik Ermel --- .../pytest/shell/pytest/test_shell.py | 12 +++++++++- .../src/twister_harness/__init__.py | 2 +- .../src/twister_harness/fixtures/__init__.py | 8 +++++++ .../{fixtures.py => fixtures/dut.py} | 22 ------------------- .../{helpers => fixtures}/mcumgr.py | 16 ++++++++++++++ .../src/twister_harness/plugin.py | 3 ++- .../tests/fixtures/mcumgr_fixture_test.py | 4 ++-- 7 files changed, 40 insertions(+), 27 deletions(-) create mode 100644 scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py rename scripts/pylib/pytest-twister-harness/src/twister_harness/{fixtures.py => fixtures/dut.py} (72%) rename scripts/pylib/pytest-twister-harness/src/twister_harness/{helpers => fixtures}/mcumgr.py (88%) diff --git a/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py b/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py index 84d16ec1e5a..37efa74795b 100755 --- a/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py +++ b/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py @@ -4,11 +4,21 @@ import logging -from twister_harness import Shell +import pytest +from twister_harness import DeviceAdapter, Shell logger = logging.getLogger(__name__) +@pytest.fixture(scope='function') +def shell(dut: DeviceAdapter) -> Shell: + """Return ready to use shell interface""" + shell = Shell(dut, timeout=20.0) + logger.info('wait for prompt') + assert shell.wait_for_prompt() + return shell + + def test_shell_print_help(shell: Shell): logger.info('send "help" command') lines = shell.exec_command('help') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py index 4897e2cf391..251c5deb672 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/__init__.py @@ -5,7 +5,7 @@ # flake8: noqa from twister_harness.device.device_adapter import DeviceAdapter -from twister_harness.helpers.mcumgr import MCUmgr +from twister_harness.fixtures.mcumgr import MCUmgr from twister_harness.helpers.shell import Shell __all__ = ['DeviceAdapter', 'MCUmgr', 'Shell'] diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py new file mode 100644 index 00000000000..ed61bf17b1c --- /dev/null +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import pytest + +pytest.register_assert_rewrite('twister_harness.fixtures.dut') +pytest.register_assert_rewrite('twister_harness.fixtures.mcumgr') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py similarity index 72% rename from scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py rename to scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py index e2e82674ada..0f34c05b252 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/dut.py @@ -10,8 +10,6 @@ from twister_harness.device.device_adapter import DeviceAdapter from twister_harness.device.factory import DeviceFactory from twister_harness.twister_harness_config import DeviceConfig, TwisterHarnessConfig -from twister_harness.helpers.shell import Shell -from twister_harness.helpers.mcumgr import MCUmgr logger = logging.getLogger(__name__) @@ -46,23 +44,3 @@ def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generat yield device_object finally: # to make sure we close all running processes execution device_object.close() - - -@pytest.fixture(scope='function') -def shell(dut: DeviceAdapter) -> Shell: - """Return ready to use shell interface""" - shell = Shell(dut, timeout=20.0) - logger.info('Wait for prompt') - assert shell.wait_for_prompt() - return shell - - -@pytest.fixture(scope='session') -def is_mcumgr_available() -> None: - if not MCUmgr.is_available(): - pytest.skip('mcumgr not available') - - -@pytest.fixture() -def mcumgr(is_mcumgr_available: None, dut: DeviceAdapter) -> Generator[MCUmgr, None, None]: - yield MCUmgr.create_for_serial(dut.device_config.serial) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py similarity index 88% rename from scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py rename to scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py index b6cab6475c1..e0d85893792 100755 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures/mcumgr.py @@ -3,14 +3,19 @@ # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations +import pytest import logging import re import shlex +from typing import Generator from subprocess import check_output, getstatusoutput from pathlib import Path from dataclasses import dataclass +from twister_harness.device.device_adapter import DeviceAdapter + + logger = logging.getLogger(__name__) @@ -103,3 +108,14 @@ def image_confirm(self, hash: str | None = None): image_list = self.get_image_list() hash = image_list[0].hash self.run_command(f'image confirm {hash}') + + +@pytest.fixture(scope='session') +def is_mcumgr_available() -> None: + if not MCUmgr.is_available(): + pytest.skip('mcumgr not available') + + +@pytest.fixture() +def mcumgr(is_mcumgr_available: None, dut: DeviceAdapter) -> Generator[MCUmgr, None, None]: + yield MCUmgr.create_for_serial(dut.device_config.serial) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index 076d36d4cc9..59bec12955d 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -14,7 +14,8 @@ logger = logging.getLogger(__name__) pytest_plugins = ( - 'twister_harness.fixtures' + 'twister_harness.fixtures.dut', + 'twister_harness.fixtures.mcumgr' ) diff --git a/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py b/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py index f336311143a..f294adba30a 100644 --- a/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/fixtures/mcumgr_fixture_test.py @@ -6,7 +6,7 @@ import textwrap from unittest import mock -from twister_harness.helpers.mcumgr import MCUmgr, MCUmgrException +from twister_harness.fixtures.mcumgr import MCUmgr, MCUmgrException @pytest.fixture(name='mcumgr') @@ -14,7 +14,7 @@ def fixture_mcumgr() -> MCUmgr: return MCUmgr.create_for_serial('SERIAL_PORT') -@mock.patch('twister_harness.helpers.mcumgr.MCUmgr.run_command', return_value='') +@mock.patch('twister_harness.fixtures.mcumgr.MCUmgr.run_command', return_value='') def test_if_mcumgr_fixture_generate_proper_command( patched_run_command: mock.Mock, mcumgr: MCUmgr ) -> None: From 01081ad4a295ed1724e456fe0a30dcfc5fa336e4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:31 +0000 Subject: [PATCH 4068/4498] Revert "[nrf noup] ci: Add CI-run-zephyr-twister test spec" This reverts commit ede86123951b7f824f91f6ebd1ea15f307f9a208. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 789f1a4e235..007f4307aa9 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -1,19 +1,4 @@ # This is the Jenkins ci variant of the .github/labler.yaml - -"CI-run-zephyr-twister": - - any: - - "!.github/**/*" - - "!doc/**/*" - - "!CODEOWNERS" - - "!LICENSE" - - "!**/*.rst" - - "!VERSION" - - "!submanifests/**/*" - - "!MAINTAINERS.yml" - - "!version.h.in" - - "!Jenkinsfile" - - "!**/*.md" - "CI-iot-zephyr-lwm2m-test": - "drivers/console/**/*" - "drivers/flash/**/*" From 75374c44374a2f1d1fcb2432ab67c7686f79badd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:32 +0000 Subject: [PATCH 4069/4498] Revert "[nrf fromtree] Bluetooth: HCI: Add bt_hci_get_ver_str()" This reverts commit 2b912a70f905022a1ef891161b5f6c977980c87a. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/hci.h | 13 ------------- subsys/bluetooth/host/hci_core.c | 10 +++++----- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 258f86519b6..8dd7434e445 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -97,19 +97,6 @@ int bt_hci_get_conn_handle(const struct bt_conn *conn, uint16_t *conn_handle); */ int bt_hci_get_adv_handle(const struct bt_le_ext_adv *adv, uint8_t *adv_handle); -/** @brief Obtain the version string given a core version number. - * - * The core version of a controller can be obtained by issuing - * the HCI Read Local Version Information command. - * - * See also the defines prefixed with BT_HCI_VERSION_. - * - * @param core_version The core version. - * - * @return Version string corresponding to the core version number. - */ -const char *bt_hci_get_ver_str(uint8_t core_version); - /** @typedef bt_hci_vnd_evt_cb_t * @brief Callback type for vendor handling of HCI Vendor-Specific Events. * diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 7cf699aa8cc..40e1b44e960 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3459,15 +3459,15 @@ static int set_event_mask(void) return bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL); } -const char *bt_hci_get_ver_str(uint8_t core_version) +static const char *ver_str(uint8_t ver) { const char * const str[] = { "1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2", "5.3", "5.4" }; - if (core_version < ARRAY_SIZE(str)) { - return str[core_version]; + if (ver < ARRAY_SIZE(str)) { + return str[ver]; } return "unknown"; @@ -3508,9 +3508,9 @@ static void bt_dev_show_info(void) } LOG_INF("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x", - bt_hci_get_ver_str(bt_dev.hci_version), bt_dev.hci_version, bt_dev.hci_revision, + ver_str(bt_dev.hci_version), bt_dev.hci_version, bt_dev.hci_revision, bt_dev.manufacturer); - LOG_INF("LMP: version %s (0x%02x) subver 0x%04x", bt_hci_get_ver_str(bt_dev.lmp_version), + LOG_INF("LMP: version %s (0x%02x) subver 0x%04x", ver_str(bt_dev.lmp_version), bt_dev.lmp_version, bt_dev.lmp_subversion); } From e20e3707f80bd497e6eb720f4639049614d08c17 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:32 +0000 Subject: [PATCH 4070/4498] Revert "[nrf fromtree] scripts: Add test_plan.py to twister_ignore.txt" This reverts commit ac573c04413a1f16faf2a3b63936b0e91720820a. Signed-off-by: Dominik Ermel --- scripts/ci/twister_ignore.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index fb267ed81f7..4a0589f291c 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -24,7 +24,6 @@ doc/* *.md # if we change this file or associated script, it should not trigger a full # twister. -scripts/ci/test_plan.py scripts/ci/twister_ignore.txt scripts/ci/what_changed.py scripts/ci/version_mgr.py From ff9983818e48d88995e623eae647d118441bda9b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:32 +0000 Subject: [PATCH 4071/4498] Revert "[nrf fromtree] twister: bugfix: Fix infinite loop in test_plan.py script" This reverts commit d8af055fc8c45815beaae06947d1625011451c88. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 21cac8e4914..a308abe63ab 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -284,8 +284,6 @@ def find_tests(self): tests.add(os.path.dirname(yaml)) self.resolved_files.append(f) scope_found = True - else: - d = os.path.dirname(d) else: d = os.path.dirname(d) From 22c65ddabe5e0c033b27bb0b59977115b44e563c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:33 +0000 Subject: [PATCH 4072/4498] Revert "[nrf fromtree] scripts: Add workflow for "common" directories in find_tests()" This reverts commit 10ef01ba7924b88c6f3dc9d75409f679486eb4ba. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index a308abe63ab..234d1302731 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -12,7 +12,6 @@ import json import logging import sys -import glob from pathlib import Path from git import Repo from west.manifest import Manifest @@ -265,25 +264,13 @@ def find_tests(self): if f.endswith(".rst"): continue d = os.path.dirname(f) - scope_found = False - while not scope_found and d: - head, tail = os.path.split(d) + while d: if os.path.exists(os.path.join(d, "testcase.yaml")) or \ os.path.exists(os.path.join(d, "sample.yaml")): tests.add(d) # Modified file is treated as resolved, since a matching scope was found self.resolved_files.append(f) - scope_found = True - elif tail == "common": - # Look for yamls in directories collocated with common - - yamls_found = [yaml for yaml in glob.iglob(head + '/**/testcase.yaml', recursive=True)] - yamls_found.extend([yaml for yaml in glob.iglob(head + '/**/sample.yaml', recursive=True)]) - if yamls_found: - for yaml in yamls_found: - tests.add(os.path.dirname(yaml)) - self.resolved_files.append(f) - scope_found = True + break else: d = os.path.dirname(d) From 998a991a0cb55c67ea3487ebbb611cff89365071 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:33 +0000 Subject: [PATCH 4073/4498] Revert "[nrf fromtree] scripts: Make workflow of test_plan.py script more robust" This reverts commit 158f0db91c3ab5455fb79e8fa3f07cb482c43b56. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 39 ++++++++++++++--------------------- scripts/ci/twister_ignore.txt | 19 +++++++++++++++++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 234d1302731..1388250716f 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -97,13 +97,13 @@ def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.testsuite_root = testsuite_root - self.resolved_files = [] self.twister_options = [] self.full_twister = False self.all_tests = [] self.tag_options = [] self.pull_request = pull_request self.platforms = platforms + self.default_run = False self.detailed_test_id = detailed_test_id self.ignore_path = ignore_path self.tag_cfg_file = alt_tags @@ -115,7 +115,11 @@ def process(self): if not self.platforms: self.find_archs() self.find_boards() - self.find_excludes() + + if self.default_run: + self.find_excludes(skip=["tests/*", "boards/*/*/*"]) + else: + self.find_excludes() def get_plan(self, options, integration=False, use_testsuite_root=True): fname = "_test_plan_partial.json" @@ -196,8 +200,6 @@ def find_archs(self): archs.add('riscv64') else: archs.add(p.group(1)) - # Modified file is treated as resolved, since a matching scope was found - self.resolved_files.append(f) _options = [] for arch in archs: @@ -216,7 +218,6 @@ def find_archs(self): def find_boards(self): boards = set() all_boards = set() - resolved = [] for f in self.modified_files: if f.endswith(".rst") or f.endswith(".png") or f.endswith(".jpg"): @@ -224,7 +225,6 @@ def find_boards(self): p = re.match(r"^boards\/[^/]+\/([^/]+)\/", f) if p and p.groups(): boards.add(p.group(1)) - resolved.append(f) roots = [zephyr_base] if repository_path != zephyr_base: @@ -239,16 +239,10 @@ def find_boards(self): if name_re.search(kb.name): all_boards.add(kb.name) - # If modified file is catched by "find_boards" workflow (change in "boards" dir AND board recognized) - # it means a proper testing scope for this file was found and this file can be removed - # from further consideration - for board in all_boards: - self.resolved_files.extend(list(filter(lambda f: board in f, resolved))) - _options = [] if len(all_boards) > 20: logging.warning(f"{len(boards)} boards changed, this looks like a global change, skipping test handling, revert to default.") - self.full_twister = True + self.default_run = True return for board in all_boards: @@ -268,8 +262,6 @@ def find_tests(self): if os.path.exists(os.path.join(d, "testcase.yaml")) or \ os.path.exists(os.path.join(d, "sample.yaml")): tests.add(d) - # Modified file is treated as resolved, since a matching scope was found - self.resolved_files.append(f) break else: d = os.path.dirname(d) @@ -280,7 +272,7 @@ def find_tests(self): if len(tests) > 20: logging.warning(f"{len(tests)} tests changed, this looks like a global change, skipping test handling, revert to default") - self.full_twister = True + self.default_run = True return if _options: @@ -336,22 +328,21 @@ def find_excludes(self, skip=[]): ignores = filter(lambda x: not x.startswith("#"), ignores) found = set() - files_not_resolved = list(filter(lambda x: x not in self.resolved_files, self.modified_files)) + files = list(filter(lambda x: x, self.modified_files)) for pattern in ignores: + if pattern in skip: + continue if pattern: - found.update(fnmatch.filter(files_not_resolved, pattern)) + found.update(fnmatch.filter(files, pattern)) logging.debug(found) - logging.debug(files_not_resolved) + logging.debug(files) - # Full twister run can be ordered by detecting great number of tests/boards changed - # or if not all modified files were resolved (corresponding scope found) - self.full_twister = self.full_twister or sorted(files_not_resolved) != sorted(found) - - if self.full_twister: + if sorted(files) != sorted(found): _options = [] logging.info(f'Need to run full or partial twister...') + self.full_twister = True if self.platforms: for platform in self.platforms: _options.extend(["-p", platform]) diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index 4a0589f291c..59f735495ca 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -17,6 +17,25 @@ CODEOWNERS MAINTAINERS.yml LICENSE Makefile +tests/* +samples/* +boards/*/*/* +arch/xtensa/* +arch/x86/* +arch/posix/* +arch/arc/* +arch/sparc/* +arch/arm/* +arch/nios2/* +arch/riscv/* +include/arch/xtensa/* +include/arch/x86/* +include/arch/posix/* +include/arch/arc/* +include/arch/sparc/* +include/arch/arm/* +include/arch/nios2/* +include/arch/riscv/* doc/* # GH action have no impact on code .github/* From dccdde1cc7d482e464ee36078fd7c5bb1f30ae95 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:33 +0000 Subject: [PATCH 4074/4498] Revert "[nrf fromtree] scripts: Add arg to test_plan.py for alternative test locations" This reverts commit dfbb9972f240c1e55d4e84dcdb941f91af552ea0. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 1388250716f..6ee76b74aae 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,10 +93,8 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, - pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, ignore_path, alt_tags, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files - self.testsuite_root = testsuite_root self.twister_options = [] self.full_twister = False self.all_tests = [] @@ -121,14 +119,11 @@ def process(self): else: self.find_excludes() - def get_plan(self, options, integration=False, use_testsuite_root=True): + def get_plan(self, options, integration=False): fname = "_test_plan_partial.json" cmd = [f"{zephyr_base}/scripts/twister", "-c"] + options + ["--save-tests", fname ] if not self.detailed_test_id: cmd += ["--no-detailed-test-id"] - if self.testsuite_root and use_testsuite_root: - for root in self.testsuite_root: - cmd+=["-T", root] if integration: cmd.append("--integration") @@ -282,7 +277,7 @@ def find_tests(self): _options.extend(["-p", platform]) else: _options.append("--all") - self.get_plan(_options, use_testsuite_root=False) + self.get_plan(_options) def find_tags(self): @@ -385,12 +380,6 @@ def parse_args(): parser.add_argument('--alt-tags', default=os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml'), help="Path to a file describing relations between directories and tags") - parser.add_argument( - "-T", "--testsuite-root", action="append", default=[], - help="Base directory to recursively search for test cases. All " - "testcase.yaml files under here will be processed. May be " - "called multiple times. Defaults to the 'samples/' and " - "'tests/' directories at the base of the Zephyr tree.") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -418,8 +407,7 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.ignore_path, args.alt_tags, args.testsuite_root, - args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.ignore_path, args.alt_tags, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From 9b069d53cf2c32ff2b1223e933c1622c31b24e75 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:33 +0000 Subject: [PATCH 4075/4498] Revert "[nrf fromtree] scripts: Add arg to set_plan.py for alternative tag relation list" This reverts commit bff52954a69905e162abbbb49045b81cf8e7bee1. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 6ee76b74aae..6ebcfc744bc 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,7 +93,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, ignore_path, alt_tags, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -104,7 +104,6 @@ def __init__(self, modified_files, ignore_path, alt_tags, pull_request=False, pl self.default_run = False self.detailed_test_id = detailed_test_id self.ignore_path = ignore_path - self.tag_cfg_file = alt_tags def process(self): self.find_modules() @@ -281,7 +280,8 @@ def find_tests(self): def find_tags(self): - with open(self.tag_cfg_file, 'r') as ymlfile: + tag_cfg_file = os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml') + with open(tag_cfg_file, 'r') as ymlfile: tags_config = yaml.safe_load(ymlfile) tags = {} @@ -377,9 +377,6 @@ def parse_args(): parser.add_argument('--ignore-path', default=os.path.join(zephyr_base, 'scripts', 'ci', 'twister_ignore.txt'), help="Path to a text file with patterns of files to be matched against changed files") - parser.add_argument('--alt-tags', - default=os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml'), - help="Path to a file describing relations between directories and tags") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -407,7 +404,7 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.ignore_path, args.alt_tags, args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.ignore_path, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From a0319c5447d520791127c6f7c377c07a88e311ce Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:33 +0000 Subject: [PATCH 4076/4498] Revert "[nrf fromtree] scripts: Allow using alternative ignore-patters in test_plan.py" This reverts commit bd2c89e4a589eb0ad43c9a617d3308417b4ddda6. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 6ebcfc744bc..9a6f50f57d0 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -93,7 +93,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, pull_request=False, platforms=[], detailed_test_id=True): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -103,7 +103,6 @@ def __init__(self, modified_files, ignore_path, pull_request=False, platforms=[] self.platforms = platforms self.default_run = False self.detailed_test_id = detailed_test_id - self.ignore_path = ignore_path def process(self): self.find_modules() @@ -318,7 +317,7 @@ def find_tags(self): logging.info(f'Potential tag based filters: {exclude_tags}') def find_excludes(self, skip=[]): - with open(self.ignore_path, "r") as twister_ignore: + with open("scripts/ci/twister_ignore.txt", "r") as twister_ignore: ignores = twister_ignore.read().splitlines() ignores = filter(lambda x: not x.startswith("#"), ignores) @@ -374,9 +373,6 @@ def parse_args(): help="Don't put paths into tests' names.") parser.add_argument('-r', '--repo-to-scan', default=None, help="Repo to scan") - parser.add_argument('--ignore-path', - default=os.path.join(zephyr_base, 'scripts', 'ci', 'twister_ignore.txt'), - help="Path to a text file with patterns of files to be matched against changed files") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -404,7 +400,7 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.ignore_path, args.pull_request, args.platform, args.detailed_test_id) + f = Filters(files, args.pull_request, args.platform, args.detailed_test_id) f.process() # remove dupes and filtered cases From 8b5c28a140ca0adba74c344206cafe7eaf2285aa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:34 +0000 Subject: [PATCH 4077/4498] Revert "[nrf fromtree] scripts: Allow test_plan.py to work with other than zephyr repos" This reverts commit 26dfd71e944b74eb2ec73e41689cd26c128f3566. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 9a6f50f57d0..6251104c32e 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -19,17 +19,10 @@ if "ZEPHYR_BASE" not in os.environ: exit("$ZEPHYR_BASE environment variable undefined.") -# These are globaly used variables. They are assigned in __main__ and are visible in further methods -# however, pylint complains that it doesn't recognized them when used (used-before-assignment). -zephyr_base = Path(os.environ['ZEPHYR_BASE']) -repository_path = zephyr_base -repo_to_scan = zephyr_base -args = None - - +repository_path = Path(os.environ['ZEPHYR_BASE']) logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) -sys.path.append(os.path.join(zephyr_base, 'scripts')) +sys.path.append(os.path.join(repository_path, 'scripts')) import list_boards def _get_match_fn(globs, regexes): @@ -119,7 +112,7 @@ def process(self): def get_plan(self, options, integration=False): fname = "_test_plan_partial.json" - cmd = [f"{zephyr_base}/scripts/twister", "-c"] + options + ["--save-tests", fname ] + cmd = ["scripts/twister", "-c"] + options + ["--save-tests", fname ] if not self.detailed_test_id: cmd += ["--no-detailed-test-id"] if integration: @@ -138,7 +131,7 @@ def find_modules(self): if 'west.yml' in self.modified_files: print(f"Manifest file 'west.yml' changed") print("=========") - old_manifest_content = repo_to_scan.git.show(f"{args.commits[:-2]}:west.yml") + old_manifest_content = repo.git.show(f"{args.commits[:-2]}:west.yml") with open("west_old.yml", "w") as manifest: manifest.write(old_manifest_content) old_manifest = Manifest.from_file("west_old.yml") @@ -219,12 +212,8 @@ def find_boards(self): if p and p.groups(): boards.add(p.group(1)) - roots = [zephyr_base] - if repository_path != zephyr_base: - roots.append(repository_path) - - # Look for boards in monitored repositories - lb_args = argparse.Namespace(**{ 'arch_roots': roots, 'board_roots': roots}) + # Limit search to $ZEPHYR_BASE since this is where the changed files are + lb_args = argparse.Namespace(**{ 'arch_roots': [repository_path], 'board_roots': [repository_path] }) known_boards = list_boards.find_boards(lb_args) for b in boards: name_re = re.compile(b) @@ -279,7 +268,7 @@ def find_tests(self): def find_tags(self): - tag_cfg_file = os.path.join(zephyr_base, 'scripts', 'ci', 'tags.yaml') + tag_cfg_file = os.path.join(repository_path, 'scripts', 'ci', 'tags.yaml') with open(tag_cfg_file, 'r') as ymlfile: tags_config = yaml.safe_load(ymlfile) @@ -371,8 +360,6 @@ def parse_args(): help="Include paths to tests' locations in tests' names.") parser.add_argument("--no-detailed-test-id", dest='detailed_test_id', action="store_false", help="Don't put paths into tests' names.") - parser.add_argument('-r', '--repo-to-scan', default=None, - help="Repo to scan") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -385,11 +372,9 @@ def parse_args(): args = parse_args() files = [] errors = 0 - if args.repo_to_scan: - repository_path = Path(args.repo_to_scan) if args.commits: - repo_to_scan = Repo(repository_path) - commit = repo_to_scan.git.diff("--name-only", args.commits) + repo = Repo(repository_path) + commit = repo.git.diff("--name-only", args.commits) files = commit.split("\n") elif args.modified_files: with open(args.modified_files, "r") as fp: From b3fca6aa31b344f7734fbc4b04758f6b96d50d73 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:34 +0000 Subject: [PATCH 4078/4498] Revert "[nrf fromtree] scripts: Add --no-detailed-test-id arg to test_plan.py script" This reverts commit 55257c34d335471c33fc2469f1c562e412efb4ed. Signed-off-by: Dominik Ermel --- scripts/ci/test_plan.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index 6251104c32e..8f2f24b0825 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -86,7 +86,7 @@ def __repr__(self): return "".format(self.name) class Filters: - def __init__(self, modified_files, pull_request=False, platforms=[], detailed_test_id=True): + def __init__(self, modified_files, pull_request=False, platforms=[]): self.modified_files = modified_files self.twister_options = [] self.full_twister = False @@ -95,7 +95,6 @@ def __init__(self, modified_files, pull_request=False, platforms=[], detailed_te self.pull_request = pull_request self.platforms = platforms self.default_run = False - self.detailed_test_id = detailed_test_id def process(self): self.find_modules() @@ -113,8 +112,6 @@ def process(self): def get_plan(self, options, integration=False): fname = "_test_plan_partial.json" cmd = ["scripts/twister", "-c"] + options + ["--save-tests", fname ] - if not self.detailed_test_id: - cmd += ["--no-detailed-test-id"] if integration: cmd.append("--integration") @@ -356,13 +353,6 @@ def parse_args(): help="Number of tests per builder") parser.add_argument('-n', '--default-matrix', default=10, type=int, help="Number of tests per builder") - parser.add_argument('--detailed-test-id', action='store_true', - help="Include paths to tests' locations in tests' names.") - parser.add_argument("--no-detailed-test-id", dest='detailed_test_id', action="store_false", - help="Don't put paths into tests' names.") - - # Include paths in names by default. - parser.set_defaults(detailed_test_id=True) return parser.parse_args() @@ -385,7 +375,8 @@ def parse_args(): print("\n".join(files)) print("=========") - f = Filters(files, args.pull_request, args.platform, args.detailed_test_id) + + f = Filters(files, args.pull_request, args.platform) f.process() # remove dupes and filtered cases From b70cd9bc022b8cdfb9fa22d3fc4086bd1a89b056 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:34 +0000 Subject: [PATCH 4079/4498] Revert "[nrf fromtree] twister: Fix error for --device-testing with not runnable integration" This reverts commit e4052b3643de84d69f5d6fb5656295298d4aac62. Signed-off-by: Dominik Ermel --- scripts/pylib/twister/twisterlib/testplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index ae122862d1e..209b76c65d2 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -740,7 +740,7 @@ def apply_filters(self, **kwargs): instance.add_filter("Not part of requested test plan", Filters.TESTSUITE) if runnable and not instance.run: - instance.add_filter("Not runnable on device", Filters.CMD_LINE) + instance.add_filter("Not runnable on device", Filters.PLATFORM) if self.options.integration and ts.integration_platforms and plat.name not in ts.integration_platforms: instance.add_filter("Not part of integration platforms", Filters.TESTSUITE) From aaa3ae2e31e0dd6d538d8827a739ad232402cba1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:34 +0000 Subject: [PATCH 4080/4498] Revert "[nrf fromtree] twister: Add options deciding if paths be included in tests' names" This reverts commit b19ec69bf9ef2c7ac5d7fa37b6f4d934de6e567d. Signed-off-by: Dominik Ermel --- .../pylib/twister/twisterlib/environment.py | 15 ------- scripts/pylib/twister/twisterlib/reports.py | 10 ++--- .../pylib/twister/twisterlib/testinstance.py | 7 +--- scripts/pylib/twister/twisterlib/testplan.py | 2 +- scripts/pylib/twister/twisterlib/testsuite.py | 16 +++----- scripts/tests/twister/test_harness.py | 1 - scripts/tests/twister/test_testsuite.py | 40 ------------------- 7 files changed, 10 insertions(+), 81 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index b5018bc1f01..160233a66fe 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -437,21 +437,6 @@ def add_parse_arguments(parser = None): help="Re-use the outdir before building. Will result in " "faster compilation since builds will be incremental.") - parser.add_argument( - '--detailed-test-id', action='store_true', - help="Include paths to tests' locations in tests' names. Names will follow " - "PATH_TO_TEST/SCENARIO_NAME schema " - "e.g. samples/hello_world/sample.basic.helloworld") - - parser.add_argument( - "--no-detailed-test-id", dest='detailed_test_id', action="store_false", - help="Don't put paths into tests' names. " - "With this arg a test name will be a scenario name " - "e.g. sample.basic.helloworld.") - - # Include paths in names by default. - parser.set_defaults(detailed_test_id=True) - # To be removed in favor of --detailed-skipped-report parser.add_argument( "--no-skipped-report", action="store_true", diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index c1f160caad9..0b34a5d309b 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -420,7 +420,6 @@ def footprint_reports(self, report, show_footprint, all_deltas, def synopsis(self): cnt = 0 example_instance = None - detailed_test_id = self.env.options.detailed_test_id for instance in self.instances.values(): if instance.status not in ["passed", "filtered", "skipped"]: cnt = cnt + 1 @@ -436,14 +435,11 @@ def synopsis(self): if cnt and example_instance: logger.info("") logger.info("To rerun the tests, call twister using the following commandline:") - extra_parameters = '' if detailed_test_id else ' --no-detailed-test-id' - logger.info(f"west twister -p -s {extra_parameters}, for example:") + logger.info("west twister -p -s , for example:") logger.info("") - logger.info(f"west twister -p {example_instance.platform.name} -s {example_instance.testsuite.name}" - f"{extra_parameters}") + logger.info(f"west twister -p {example_instance.platform.name} -s {example_instance.testsuite.name}") logger.info(f"or with west:") - logger.info(f"west build -p -b {example_instance.platform.name} " - f"{example_instance.testsuite.source_dir_rel} -T {example_instance.testsuite.id}") + logger.info(f"west build -p -b {example_instance.platform.name} -T {example_instance.testsuite.name}") logger.info("-+" * 40) def summary(self, results, unrecognized_sections, duration): diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index b9e7d411cb5..ccfc3cd06d4 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -55,12 +55,7 @@ def __init__(self, testsuite, platform, outdir): self.name = os.path.join(platform.name, testsuite.name) self.run_id = self._get_run_id() self.dut = None - if testsuite.detailed_test_id: - self.build_dir = os.path.join(outdir, platform.name, testsuite.name) - else: - # if suite is not in zephyr, keep only the part after ".." in reconstructed dir structure - source_dir_rel = testsuite.source_dir_rel.rsplit(os.pardir+os.path.sep, 1)[-1] - self.build_dir = os.path.join(outdir, platform.name, source_dir_rel, testsuite.name) + self.build_dir = os.path.join(outdir, platform.name, testsuite.name) self.domains = None diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 209b76c65d2..1d9c625b28a 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -524,7 +524,7 @@ def add_testsuites(self, testsuite_filter=[]): for name in parsed_data.scenarios.keys(): suite_dict = parsed_data.get_scenario(name) - suite = TestSuite(root, suite_path, name, data=suite_dict, detailed_test_id=self.options.detailed_test_id) + suite = TestSuite(root, suite_path, name, data=suite_dict) suite.add_subcases(suite_dict, subcases, ztest_suite_names) if testsuite_filter: if suite.name and suite.name in testsuite_filter: diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index 39c21098718..faacf669c1d 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -348,7 +348,7 @@ class TestSuite(DisablePyTestCollectionMixin): """Class representing a test application """ - def __init__(self, suite_root, suite_path, name, data=None, detailed_test_id=True): + def __init__(self, suite_root, suite_path, name, data=None): """TestSuite constructor. This gets called by TestPlan as it finds and reads test yaml files. @@ -369,14 +369,12 @@ def __init__(self, suite_root, suite_path, name, data=None, detailed_test_id=Tru """ workdir = os.path.relpath(suite_path, suite_root) - - assert self.check_suite_name(name, suite_root, workdir) - self.detailed_test_id = detailed_test_id - self.name = self.get_unique(suite_root, workdir, name) if self.detailed_test_id else name + self.name = self.get_unique(suite_root, workdir, name) self.id = name self.source_dir = suite_path - self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), start=canonical_zephyr_base) + self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), + start=canonical_zephyr_base) self.yamlfile = suite_path self.testcases = [] @@ -429,14 +427,10 @@ def get_unique(testsuite_root, workdir, name): # workdir can be "." unique = os.path.normpath(os.path.join(relative_ts_root, workdir, name)) - return unique - - @staticmethod - def check_suite_name(name, testsuite_root, workdir): check = name.split(".") if len(check) < 2: raise TwisterException(f"""bad test name '{name}' in {testsuite_root}/{workdir}. \ Tests should reference the category and subsystem with a dot as a separator. """ ) - return True + return unique diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 1da2aed3f46..a33d6431ab4 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -40,7 +40,6 @@ def gtest(): mock_platform.name = "mock_platform" mock_testsuite = mock.Mock() mock_testsuite.name = "mock_testsuite" - mock_testsuite.detailed_test_id = True mock_testsuite.id = "id" mock_testsuite.testcases = [] instance = TestInstance(testsuite=mock_testsuite, platform=mock_platform, outdir="") diff --git a/scripts/tests/twister/test_testsuite.py b/scripts/tests/twister/test_testsuite.py index 23e4f8ed034..49f19d0d0f8 100644 --- a/scripts/tests/twister/test_testsuite.py +++ b/scripts/tests/twister/test_testsuite.py @@ -749,43 +749,3 @@ def test_testcase_dunders(): assert case_lesser < case_greater assert str(case_greater) == 'a greater name' assert repr(case_greater) == '' - - -TESTDATA_11 = [ - ( - ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites', - ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/tests/test_a', - 'test_a.check_1', - 'test_a.check_1' - ), - ( - ZEPHYR_BASE, - ZEPHYR_BASE, - 'test_a.check_1', - 'test_a.check_1' - ), - ( - ZEPHYR_BASE, - ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/test_b', - 'test_b.check_1', - 'test_b.check_1' - ), - ( - os.path.join(ZEPHYR_BASE, 'scripts/tests'), - os.path.join(ZEPHYR_BASE, 'scripts/tests'), - 'test_b.check_1', - 'test_b.check_1' - ), - ( - ZEPHYR_BASE, - ZEPHYR_BASE, - 'test_a.check_1.check_2', - 'test_a.check_1.check_2' - ), -] -@pytest.mark.parametrize("testsuite_root, suite_path, name, expected", TESTDATA_11) -def test_get_no_detailed_test_id(testsuite_root, suite_path, name, expected): - '''Test to check if the name without path is given for each testsuite''' - suite = TestSuite(testsuite_root, suite_path, name, detailed_test_id=False) - print(suite.name) - assert suite.name == expected From d7ac4dbf733e24f90bd33e55b00b662e9ab8bf08 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:34 +0000 Subject: [PATCH 4081/4498] Revert "[nrf fromtree] twister: Add "path" entry to json test report" This reverts commit df801013e317c988eb4a1fad2e8a6e2a438c10d5. Signed-off-by: Dominik Ermel --- scripts/pylib/twister/twisterlib/reports.py | 1 - scripts/pylib/twister/twisterlib/testsuite.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index 0b34a5d309b..bd005d4319a 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -258,7 +258,6 @@ def json_report(self, filename, version="NA"): "name": instance.testsuite.name, "arch": instance.platform.arch, "platform": instance.platform.name, - "path": instance.testsuite.source_dir_rel } if instance.run_id: suite['run_id'] = instance.run_id diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index faacf669c1d..3f4a71e4a8c 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -373,8 +373,6 @@ def __init__(self, suite_root, suite_path, name, data=None): self.id = name self.source_dir = suite_path - self.source_dir_rel = os.path.relpath(os.path.realpath(suite_path), - start=canonical_zephyr_base) self.yamlfile = suite_path self.testcases = [] From 6af83b284849c3499c669f1055c5fa1e997c2660 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:35 +0000 Subject: [PATCH 4082/4498] Revert "[nrf fromtree] wifi: shell: Move defaults to beginning" This reverts commit d36ea76f95b7b50cc31b45f207b2716ea4302cb8. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 280ebd90390..fe6f1c9f54c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -341,10 +341,7 @@ static int __wifi_args_to_params(size_t argc, char *argv[], return -EINVAL; } - /* Defaults */ params->band = WIFI_FREQ_BAND_UNKNOWN; - params->channel = WIFI_CHANNEL_ANY; - params->security = WIFI_SECURITY_TYPE_NONE; /* SSID */ params->ssid = argv[0]; @@ -365,6 +362,8 @@ static int __wifi_args_to_params(size_t argc, char *argv[], } idx++; + } else { + params->channel = WIFI_CHANNEL_ANY; } /* PSK (optional) */ @@ -403,6 +402,8 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->psk_length > WIFI_SAE_PSWD_MAX_LEN)) { return -EINVAL; } + } else { + params->security = WIFI_SECURITY_TYPE_NONE; } From 1113813ab6bdc1341cc5ab3a55d8596e40788cf1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:35 +0000 Subject: [PATCH 4083/4498] Revert "[nrf fromtree] wifi: shell: Fix default band value" This reverts commit 902f4a417ae968e3fb1ebd97f72b1795c433a497. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index fe6f1c9f54c..9e521fcf028 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -341,8 +341,6 @@ static int __wifi_args_to_params(size_t argc, char *argv[], return -EINVAL; } - params->band = WIFI_FREQ_BAND_UNKNOWN; - /* SSID */ params->ssid = argv[0]; params->ssid_length = strlen(params->ssid); From 87cfab36ae920eb95ade673914b4dd305d200bf9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:35 +0000 Subject: [PATCH 4084/4498] Revert "[nrf noup] testspec: Add audio" This reverts commit 2b1d418a6c8b17e028204bbefe4500f0286d46d4. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 007f4307aa9..c01ae703adf 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -218,25 +218,3 @@ - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" - "!subsys/bluetooth/audio/**/*" - -"CI-audio-test": - - "boards/arm/nrf5340_audio_dk_nrf5340/**/*" - - "drivers/flash/**/*" - - "drivers/spi/**/*" - - "drivers/gpio/**/*" - - "drivers/i2c/**/*" - - "drivers/watchdog/**/*" - - "include/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/bluetooth/audio/**/*" - - "subsys/bluetooth/host/**/*" - - "subsys/dfu/**/*" - - "subsys/fs/**/*" - - "subsys/mgmt/mcumgr/**/*" - - "subsys/sd/**/*" - - "subsys/storage/**/*" - - "subsys/task_wdt/**/*" - - "subsys/usb/**/*" - - "subsys/zbus/**/*" From 4894aec7879d711064e46b9d7c1c54db242feb9e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:36 +0000 Subject: [PATCH 4085/4498] Revert "[nrf fromtree] net: zperf: Fix the check for IPv6" This reverts commit f0b15a5617adc94c29466827aeac051f5f157e3f. Signed-off-by: Dominik Ermel --- subsys/net/lib/zperf/zperf_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index b61501d0e9e..b32654f44bc 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -1147,7 +1147,7 @@ void zperf_shell_init(void) { int ret; - if (IS_ENABLED(MY_IP6ADDR_SET) && MY_IP6ADDR) { + if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP6ADDR) { ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { From 90070b9bff7141141498d9a9f3747447ba610c2e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:36 +0000 Subject: [PATCH 4086/4498] Revert "[nrf fromtree] net: zperf: By default bind to any IP address" This reverts commit 7ed5a305f4b4e741e855e3dbb89f3af30f2de115. Signed-off-by: Dominik Ermel --- subsys/net/lib/zperf/zperf_common.c | 21 +++++++++++++++++ subsys/net/lib/zperf/zperf_internal.h | 3 +++ subsys/net/lib/zperf/zperf_tcp_receiver.c | 27 ++++++++++++++++------ subsys/net/lib/zperf/zperf_udp_receiver.c | 28 ++++++++++++++++------- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index 29568eeef5b..efe36cf69cd 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -109,6 +109,27 @@ int zperf_get_ipv4_addr(char *host, struct in_addr *addr) return 0; } + +const struct in_addr *zperf_get_default_if_in4_addr(void) +{ +#if CONFIG_NET_IPV4 + return net_if_ipv4_select_src_addr(NULL, + net_ipv4_unspecified_address()); +#else + return NULL; +#endif +} + +const struct in6_addr *zperf_get_default_if_in6_addr(void) +{ +#if CONFIG_NET_IPV6 + return net_if_ipv6_select_src_addr(NULL, + net_ipv6_unspecified_address()); +#else + return NULL; +#endif +} + int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, int priority, int proto) { diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 592424a9446..96dd9ea9123 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -95,6 +95,9 @@ struct sockaddr_in *zperf_get_sin(void); extern void connect_ap(char *ssid); +const struct in_addr *zperf_get_default_if_in4_addr(void); +const struct in6_addr *zperf_get_default_if_in6_addr(void); + int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, int priority, int proto); diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index 6cc3374d0ae..614e1af6d03 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -171,11 +171,18 @@ static void tcp_server_session(void) &in4_addr->sin_addr); if (ret < 0) { NET_WARN("Unable to set IPv4"); - goto use_any_ipv4; + goto use_existing_ipv4; } } else { -use_any_ipv4: - in4_addr->sin_addr.s_addr = INADDR_ANY; +use_existing_ipv4: + /* Use existing IP */ + addr = zperf_get_default_if_in4_addr(); + if (!addr) { + NET_ERR("Unable to get IPv4 by default"); + goto error; + } + memcpy(&in4_addr->sin_addr, addr, + sizeof(struct in_addr)); } in4_addr->sin_port = htons(tcp_server_port); @@ -217,12 +224,18 @@ static void tcp_server_session(void) &in6_addr->sin6_addr); if (ret < 0) { NET_WARN("Unable to set IPv6"); - goto use_any_ipv6; + goto use_existing_ipv6; } } else { -use_any_ipv6: - memcpy(&in6_addr->sin6_addr, net_ipv6_unspecified_address(), - sizeof(struct in6_addr)); +use_existing_ipv6: + /* Use existing IP */ + addr = zperf_get_default_if_in6_addr(); + if (!addr) { + NET_ERR("Unable to get IPv6 by default"); + goto error; + } + memcpy(&in6_addr->sin6_addr, addr, + sizeof(struct in6_addr)); } in6_addr->sin6_port = htons(tcp_server_port); diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index 2724da4b1a9..cf29760e1c6 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -263,11 +263,18 @@ static void udp_server_session(void) &in4_addr_my->sin_addr); if (ret < 0) { NET_WARN("Unable to set IPv4"); - goto use_any_ipv4; + goto use_existing_ipv4; } } else { -use_any_ipv4: - in4_addr_my->sin_addr.s_addr = INADDR_ANY; + use_existing_ipv4: + /* Use existing IP */ + in4_addr = zperf_get_default_if_in4_addr(); + if (!in4_addr) { + NET_ERR("Unable to get IPv4 by default"); + goto error; + } + memcpy(&in4_addr_my->sin_addr, in4_addr, + sizeof(struct in_addr)); } NET_INFO("Binding to %s", @@ -312,13 +319,18 @@ static void udp_server_session(void) &in6_addr_my->sin6_addr); if (ret < 0) { NET_WARN("Unable to set IPv6"); - goto use_any_ipv6; + goto use_existing_ipv6; } } else { -use_any_ipv6: - memcpy(&in6_addr_my->sin6_addr, - net_ipv6_unspecified_address(), - sizeof(struct in6_addr)); + use_existing_ipv6: + /* Use existing IP */ + in6_addr = zperf_get_default_if_in6_addr(); + if (!in6_addr) { + NET_ERR("Unable to get IPv4 by default"); + goto error; + } + memcpy(&in6_addr_my->sin6_addr, in6_addr, + sizeof(struct in6_addr)); } NET_INFO("Binding to %s", From 66d905cbb8facff48abbab5e2ee90761353bf3f6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:36 +0000 Subject: [PATCH 4087/4498] Revert "[nrf fromtree] net: zperf: Add support for bind to host option for tcp/udp download" This reverts commit 5fac2b050b54701f9d73fefaba6ecd585aacbe43. Signed-off-by: Dominik Ermel --- include/zephyr/net/zperf.h | 1 - subsys/net/lib/zperf/zperf_shell.c | 63 +++++------------------ subsys/net/lib/zperf/zperf_tcp_receiver.c | 24 +++------ subsys/net/lib/zperf/zperf_udp_receiver.c | 16 +----- 4 files changed, 20 insertions(+), 84 deletions(-) diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index fc809ae9278..cd86541721e 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -43,7 +43,6 @@ struct zperf_upload_params { struct zperf_download_params { uint16_t port; - struct sockaddr addr; }; struct zperf_results { diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index b32654f44bc..bcf60dcf037 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -178,39 +178,6 @@ static int parse_ipv4_addr(const struct shell *sh, char *host, char *port, return 0; } -static int zperf_bind_host(const struct shell *sh, - size_t argc, char *argv[], - struct zperf_download_params *param) -{ - int ret; - - /* Parse options */ - if (argc >= 2) { - param->port = strtoul(argv[1], NULL, 10); - } else { - param->port = DEF_PORT; - } - - if (argc >= 3) { - char *addr_str = argv[2]; - struct sockaddr addr; - - memset(&addr, 0, sizeof(addr)); - - ret = net_ipaddr_parse(addr_str, strlen(addr_str), &addr); - if (ret < 0) { - shell_fprintf(sh, SHELL_WARNING, - "Cannot parse address \"%s\"\n", - addr_str); - return ret; - } - - memcpy(¶m->addr, &addr, sizeof(struct sockaddr)); - } - - return 0; -} - static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) { int start = 0; @@ -366,12 +333,10 @@ static int cmd_udp_download(const struct shell *sh, size_t argc, struct zperf_download_params param = { 0 }; int ret; - ret = zperf_bind_host(sh, argc, argv, ¶m); - if (ret < 0) { - shell_fprintf(sh, SHELL_WARNING, - "Unable to bind host.\n"); - shell_help(sh); - return -ENOEXEC; + if (argc >= 2) { + param.port = strtoul(argv[1], NULL, 10); + } else { + param.port = DEF_PORT; } ret = zperf_udp_download(¶m, udp_session_cb, (void *)sh); @@ -1107,12 +1072,10 @@ static int cmd_tcp_download(const struct shell *sh, size_t argc, struct zperf_download_params param = { 0 }; int ret; - ret = zperf_bind_host(sh, argc, argv, ¶m); - if (ret < 0) { - shell_fprintf(sh, SHELL_WARNING, - "Unable to bind host.\n"); - shell_help(sh); - return -ENOEXEC; + if (argc >= 2) { + param.port = strtoul(argv[1], NULL, 10); + } else { + param.port = DEF_PORT; } ret = zperf_tcp_download(¶m, tcp_session_cb, (void *)sh); @@ -1245,9 +1208,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, , cmd_tcp_upload2), SHELL_CMD(download, &zperf_cmd_tcp_download, - "[]: Server port to listen on/connect to\n" - "[]: Bind to , an interface address\n" - "Example: tcp download 5001 192.168.0.1\n", + "[]\n" + "Example: tcp download 5001\n", cmd_tcp_download), SHELL_SUBCMD_SET_END ); @@ -1304,9 +1266,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, , cmd_udp_upload2), SHELL_CMD(download, &zperf_cmd_udp_download, - "[]: Server port to listen on/connect to\n" - "[]: Bind to , an interface address\n" - "Example: udp download 5001 192.168.0.1\n", + "[]\n" + "Example: udp download 5001\n", cmd_udp_download), SHELL_SUBCMD_SET_END ); diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index 614e1af6d03..25f9adc3494 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -46,7 +46,6 @@ static void *tcp_user_data; static bool tcp_server_running; static bool tcp_server_stop; static uint16_t tcp_server_port; -static struct sockaddr tcp_server_addr; static K_SEM_DEFINE(tcp_server_run, 0, 1); static void tcp_received(const struct sockaddr *addr, size_t datalen) @@ -151,7 +150,6 @@ static void tcp_server_session(void) if (IS_ENABLED(CONFIG_NET_IPV4)) { struct sockaddr_in *in4_addr = zperf_get_sin(); - const struct in_addr *addr = NULL; fds[SOCK_ID_IPV4_LISTEN].fd = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -160,12 +158,7 @@ static void tcp_server_session(void) goto error; } - addr = &net_sin(&tcp_server_addr)->sin_addr; - - if (!net_ipv4_is_addr_unspecified(addr)) { - memcpy(&in4_addr->sin_addr, addr, - sizeof(struct in_addr)); - } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { /* Use Setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr->sin_addr); @@ -174,8 +167,9 @@ static void tcp_server_session(void) goto use_existing_ipv4; } } else { -use_existing_ipv4: /* Use existing IP */ + const struct in_addr *addr; +use_existing_ipv4: addr = zperf_get_default_if_in4_addr(); if (!addr) { NET_ERR("Unable to get IPv4 by default"); @@ -203,7 +197,6 @@ static void tcp_server_session(void) if (IS_ENABLED(CONFIG_NET_IPV6)) { struct sockaddr_in6 *in6_addr = zperf_get_sin6(); - const struct in6_addr *addr = NULL; fds[SOCK_ID_IPV6_LISTEN].fd = zsock_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); @@ -212,12 +205,7 @@ static void tcp_server_session(void) goto error; } - addr = &net_sin6(&tcp_server_addr)->sin6_addr; - - if (!net_ipv6_is_addr_unspecified(addr)) { - memcpy(&in6_addr->sin6_addr, addr, - sizeof(struct in6_addr)); - } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { /* Use Setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, @@ -227,8 +215,9 @@ static void tcp_server_session(void) goto use_existing_ipv6; } } else { -use_existing_ipv6: /* Use existing IP */ + const struct in6_addr *addr; +use_existing_ipv6: addr = zperf_get_default_if_in6_addr(); if (!addr) { NET_ERR("Unable to get IPv6 by default"); @@ -398,7 +387,6 @@ int zperf_tcp_download(const struct zperf_download_params *param, tcp_server_port = param->port; tcp_server_running = true; tcp_server_stop = false; - memcpy(&tcp_server_addr, ¶m->addr, sizeof(struct sockaddr)); k_sem_give(&tcp_server_run); diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index cf29760e1c6..f96acde6f49 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -48,7 +48,6 @@ static void *udp_user_data; static bool udp_server_running; static bool udp_server_stop; static uint16_t udp_server_port; -static struct sockaddr udp_server_addr; static K_SEM_DEFINE(udp_server_run, 0, 1); static inline void build_reply(struct zperf_udp_datagram *hdr, @@ -252,12 +251,7 @@ static void udp_server_session(void) goto error; } - in4_addr = &net_sin(&udp_server_addr)->sin_addr; - - if (!net_ipv4_is_addr_unspecified(in4_addr)) { - memcpy(&in4_addr_my->sin_addr, in4_addr, - sizeof(struct in_addr)); - } else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { + if (MY_IP4ADDR && strlen(MY_IP4ADDR)) { /* Use setting IP */ ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr_my->sin_addr); @@ -307,12 +301,7 @@ static void udp_server_session(void) goto error; } - in6_addr = &net_sin6(&udp_server_addr)->sin6_addr; - - if (!net_ipv6_is_addr_unspecified(in6_addr)) { - memcpy(&in6_addr_my->sin6_addr, in6_addr, - sizeof(struct in6_addr)); - } else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { + if (MY_IP6ADDR && strlen(MY_IP6ADDR)) { /* Use setting IP */ ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR, @@ -452,7 +441,6 @@ int zperf_udp_download(const struct zperf_download_params *param, udp_server_port = param->port; udp_server_running = true; udp_server_stop = false; - memcpy(&udp_server_addr, ¶m->addr, sizeof(struct sockaddr)); k_sem_give(&udp_server_run); From f65b47c1cecfedee27a5cd312f940159dc45d68f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:36 +0000 Subject: [PATCH 4088/4498] Revert "[nrf fromtree] net: zperf: Set default IP addresses only if configured" This reverts commit b9b5d4751b8e10a932aec3fb8e658c27ac20bda7. Signed-off-by: Dominik Ermel --- subsys/net/lib/zperf/zperf_shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index bcf60dcf037..c1f0c6a4950 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -1110,7 +1110,7 @@ void zperf_shell_init(void) { int ret; - if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP6ADDR) { + if (IS_ENABLED(CONFIG_NET_IPV6) && MY_IP6ADDR) { ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { @@ -1133,7 +1133,7 @@ void zperf_shell_init(void) } } - if (IS_ENABLED(MY_IP4ADDR_SET) && MY_IP4ADDR) { + if (IS_ENABLED(CONFIG_NET_IPV4) && MY_IP4ADDR) { ret = net_addr_pton(AF_INET, MY_IP4ADDR, &in4_addr_my.sin_addr); if (ret < 0) { From 7d06f8422ade289b17a5e366734f795d6bcdd701 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:37 +0000 Subject: [PATCH 4089/4498] Revert "[nrf fromtree] net: zperf: Distinguish between IPv4 and IPv6 address set failures" This reverts commit bbc2731680cc1a7088ea5410d9ff81de4f4fe34a. Signed-off-by: Dominik Ermel --- subsys/net/lib/zperf/zperf_shell.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index c1f0c6a4950..3a8a9c61c4b 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -191,7 +191,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv6_addr(argv[start + 1], argv[start + 2], &shell_ipv6) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set %s address (%s disabled)\n", "IPv6", "IPv4"); + "Unable to set IP\n"); return 0; } @@ -208,7 +208,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv4_addr(argv[start + 1], &shell_ipv4) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set %s address (%s disabled)\n", "IPv4", "IPv6"); + "Unable to set IP\n"); return -ENOEXEC; } @@ -227,7 +227,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv4_addr(argv[start + 1], &shell_ipv4) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set %s address\n", "IPv4"); + "Unable to set IP\n"); return -ENOEXEC; } @@ -243,7 +243,7 @@ static int cmd_setip(const struct shell *sh, size_t argc, char *argv[]) if (zperf_get_ipv6_addr(argv[start + 1], argv[start + 2], &shell_ipv6) < 0) { shell_fprintf(sh, SHELL_WARNING, - "Unable to set %s address\n", "IPv6"); + "Unable to set IP\n"); return -ENOEXEC; } @@ -1114,7 +1114,7 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET6, MY_IP6ADDR, &in6_addr_my.sin6_addr); if (ret < 0) { - NET_WARN("Unable to set %s address\n", "IPv6"); + NET_WARN("Unable to set IP"); } else { NET_INFO("Setting IP address %s", net_sprint_ipv6_addr(&in6_addr_my.sin6_addr)); @@ -1123,10 +1123,9 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET6, DST_IP6ADDR, &in6_addr_dst.sin6_addr); if (ret < 0) { - NET_WARN("Unable to set destination %s address %s", - "IPv6", + NET_WARN("Unable to set IP %s", DST_IP6ADDR ? DST_IP6ADDR - : "(not set)"); + : "(Default IPv6 destination address not set)"); } else { NET_INFO("Setting destination IP address %s", net_sprint_ipv6_addr(&in6_addr_dst.sin6_addr)); @@ -1137,7 +1136,7 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET, MY_IP4ADDR, &in4_addr_my.sin_addr); if (ret < 0) { - NET_WARN("Unable to set %s address\n", "IPv4"); + NET_WARN("Unable to set IP"); } else { NET_INFO("Setting IP address %s", net_sprint_ipv4_addr(&in4_addr_my.sin_addr)); @@ -1146,10 +1145,9 @@ void zperf_shell_init(void) ret = net_addr_pton(AF_INET, DST_IP4ADDR, &in4_addr_dst.sin_addr); if (ret < 0) { - NET_WARN("Unable to set destination %s address %s", - "IPv4", + NET_WARN("Unable to set IP %s", DST_IP4ADDR ? DST_IP4ADDR - : "(not set)"); + : "(Default IPv4 destination address not set)"); } else { NET_INFO("Setting destination IP address %s", net_sprint_ipv4_addr(&in4_addr_dst.sin_addr)); From 536f6e401bda1dbaf58121a0238f2788544c3088 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:37 +0000 Subject: [PATCH 4090/4498] Revert "[nrf fromtree] Bluetooth: BAP: Broadcast sink: Clear pa_sync on PA terminated" This reverts commit 7a9d7daf0af044b352a50feef529a5f45c285b91. Signed-off-by: Dominik Ermel --- subsys/bluetooth/audio/bap_broadcast_sink.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 4fad67ce539..0d92617f329 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -566,16 +566,6 @@ static void pa_recv(struct bt_le_per_adv_sync *sync, bt_data_parse(buf, pa_decode_base, (void *)sink); } -static void pa_term_cb(struct bt_le_per_adv_sync *sync, - const struct bt_le_per_adv_sync_term_info *info) -{ - struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync); - - if (sink != NULL) { - sink->pa_sync = NULL; - } -} - static void update_recv_state_encryption(const struct bt_bap_broadcast_sink *sink) { struct bt_bap_scan_delegator_mod_src_param mod_src_param = { 0 }; @@ -1118,7 +1108,6 @@ static int broadcast_sink_init(void) static struct bt_le_per_adv_sync_cb cb = { .recv = pa_recv, .biginfo = biginfo_recv, - .term = pa_term_cb, }; bt_le_per_adv_sync_cb_register(&cb); From 4fc5455df78502aee6afbbe65e28ef45656e150f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:37 +0000 Subject: [PATCH 4091/4498] Revert "[nrf fromtree] Bluetooth: BAP: Broadcast Sink should not terminate the PA Sync" This reverts commit b552226dbe60943cd46e6ac598fbb81fda366317. Signed-off-by: Dominik Ermel --- subsys/bluetooth/audio/bap_broadcast_sink.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 0d92617f329..9866dfd1c57 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -1076,6 +1076,8 @@ int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink) { + int err; + CHECKIF(sink == NULL) { LOG_DBG("sink is NULL"); return -EINVAL; @@ -1097,6 +1099,17 @@ int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink) } } + if (sink->pa_sync == NULL) { + LOG_DBG("Broadcast sink is already deleted"); + return -EALREADY; + } + + err = bt_le_per_adv_sync_delete(sink->pa_sync); + if (err != 0) { + LOG_DBG("Failed to delete periodic advertising sync (err %d)", err); + return err; + } + /* Reset the broadcast sink */ broadcast_sink_cleanup(sink); From fa755baa411e0d508e5c5c15039ed1feb1908611 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:38 +0000 Subject: [PATCH 4092/4498] Revert "[nrf fromtree] zbus: Add Message subscriber" This reverts commit b715be6b467b45eaa6f3688f2117a39a1e19985a. Signed-off-by: Dominik Ermel --- include/zephyr/zbus/zbus.h | 68 +----------------- subsys/zbus/Kconfig | 30 -------- subsys/zbus/zbus.c | 144 ++++++------------------------------- 3 files changed, 23 insertions(+), 219 deletions(-) diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index 8a4188aa821..466a2ad9dcf 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -92,8 +92,7 @@ struct zbus_channel { */ enum __packed zbus_observer_type { ZBUS_OBSERVER_LISTENER_TYPE, - ZBUS_OBSERVER_SUBSCRIBER_TYPE, - ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, + ZBUS_OBSERVER_SUBSCRIBER_TYPE }; /** @@ -128,13 +127,6 @@ struct zbus_observer { /** Observer callback function. It turns the observer into a listener. */ void (*const callback)(const struct zbus_channel *chan); - -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__) - /** Observer message FIFO. It turns the observer into a message subscriber. It only - * exists if the @kconfig{CONFIG_ZBUS_MSG_SUBSCRIBER} is enabled. - */ - struct k_fifo *const message_fifo; -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ }; }; @@ -164,10 +156,8 @@ struct zbus_channel_observation { #if defined(CONFIG_ZBUS_CHANNEL_NAME) #define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name, -#define _ZBUS_CHAN_NAME(_chan) (_chan)->name #else #define ZBUS_CHANNEL_NAME_INIT(_name) -#define _ZBUS_CHAN_NAME(_chan) "" #endif #if defined(CONFIG_ZBUS_OBSERVER_NAME) @@ -389,37 +379,6 @@ k_timeout_t _zbus_timeout_remainder(uint64_t end_ticks); */ #define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true) -/** - * @brief Define and initialize a message subscriber. - * - * This macro defines an observer of @ref ZBUS_OBSERVER_SUBSCRIBER_TYPE type. It defines a FIFO - * where the subscriber will receive the message asynchronously and initialize the @ref - * zbus_observer defining the subscriber. - * - * @param[in] _name The subscriber's name. - * @param[in] _enable The subscriber's initial state. - */ -#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \ - static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \ - STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \ - ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \ - .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \ - .enabled = _enable, \ - .message_fifo = &_zbus_observer_fifo_##_name, \ - } - -/** - * @brief Define and initialize an enabled message subscriber. - * - * This macro defines an observer of message subscriber type. It defines a FIFO where the - * subscriber will receive the message asynchronously and initialize the @ref - * zbus_observer defining the subscriber. The message subscribers are defined in the enabled state - * with this macro. - - * - * @param[in] _name The subscriber's name. - */ -#define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true) /** * * @brief Publish to a channel @@ -782,31 +741,6 @@ static inline const char *zbus_obs_name(const struct zbus_observer *obs) int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan, k_timeout_t timeout); -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__) - -/** - * @brief Wait for a channel message. - * - * This routine makes the subscriber wait for the new message in case of channel publication. - * - * @param[in] sub The subscriber's reference. - * @param[out] chan The notification channel's reference. - * @param[out] msg A reference to a copy of the published message. - * @param[in] timeout Waiting period for a notification arrival, - * or one of the special values, K_NO_WAIT and K_FOREVER. - * - * @retval 0 Message received. - * @retval -EINVAL The observer is not a subscriber. - * @retval -ENOMSG Could not retrieve the net_buf from the subscriber FIFO. - * @retval -EILSEQ Received an invalid channel reference. - * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The - * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled. - */ -int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg, - k_timeout_t timeout); - -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ - /** * * @brief Iterate over channels. diff --git a/subsys/zbus/Kconfig b/subsys/zbus/Kconfig index f250865b466..622f89641a2 100644 --- a/subsys/zbus/Kconfig +++ b/subsys/zbus/Kconfig @@ -18,36 +18,6 @@ config ZBUS_CHANNEL_NAME config ZBUS_OBSERVER_NAME bool "Observer name field" -config ZBUS_MSG_SUBSCRIBER - select NET_BUF - bool "Message subscribers will receive all messages in sequence." - -if ZBUS_MSG_SUBSCRIBER - -choice - prompt "ZBus msg_subscribers buffer allocation" - -config ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC - bool "Use heap to allocate msg_subscriber buffers data" - -config ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC - bool "Use fixed data size for msg_subscriber buffers pool" - -endchoice - -config ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE - default 16 - int "The count of net_buf available to be used simutaneously." - -if ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC - -config ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE - int "The size of the biggest message used with ZBus." - -endif # ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC - -endif # ZBUS_MSG_SUBSCRIBER - config ZBUS_RUNTIME_OBSERVERS bool "Runtime observers support." default n diff --git a/subsys/zbus/zbus.c b/subsys/zbus/zbus.c index 4ea2d986a3f..abaf92c8641 100644 --- a/subsys/zbus/zbus.c +++ b/subsys/zbus/zbus.c @@ -8,47 +8,11 @@ #include #include #include -#include #include LOG_MODULE_REGISTER(zbus, CONFIG_ZBUS_LOG_LEVEL); -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) - -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC) - -NET_BUF_POOL_HEAP_DEFINE(_zbus_msg_subscribers_pool, CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE, - sizeof(struct zbus_channel *), NULL); -BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE > 0, "MSG_SUBSCRIBER feature requires heap memory pool."); - -static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, size_t size, - k_timeout_t timeout) -{ - return net_buf_alloc_len(&_zbus_msg_subscribers_pool, size, timeout); -} - -#else - -NET_BUF_POOL_FIXED_DEFINE(_zbus_msg_subscribers_pool, - (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE), - (CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_SIZE), - sizeof(struct zbus_channel *), NULL); - -static inline struct net_buf *_zbus_create_net_buf(struct net_buf_pool *pool, size_t size, - k_timeout_t timeout) -{ - __ASSERT(size <= CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE, - "CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_STATIC_DATA_SIZE must be greater or equal to " - "%d", - (int)size); - return net_buf_alloc(&_zbus_msg_subscribers_pool, timeout); -} -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */ - -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ - int _zbus_init(void) { - const struct zbus_channel *curr = NULL; const struct zbus_channel *prev = NULL; @@ -80,62 +44,32 @@ int _zbus_init(void) SYS_INIT(_zbus_init, APPLICATION, CONFIG_ZBUS_CHANNELS_SYS_INIT_PRIORITY); static inline int _zbus_notify_observer(const struct zbus_channel *chan, - const struct zbus_observer *obs, k_timepoint_t end_time, - struct net_buf *buf) + const struct zbus_observer *obs, k_timepoint_t end_time) { - switch (obs->type) { - case ZBUS_OBSERVER_LISTENER_TYPE: { - obs->callback(chan); - break; - } - case ZBUS_OBSERVER_SUBSCRIBER_TYPE: { - return k_msgq_put(obs->queue, &chan, sys_timepoint_timeout(end_time)); - } -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) - case ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE: { - struct net_buf *cloned_buf = net_buf_clone(buf, sys_timepoint_timeout(end_time)); - - if (cloned_buf == NULL) { - return -ENOMEM; - } - memcpy(net_buf_user_data(cloned_buf), &chan, sizeof(struct zbus_channel *)); - - net_buf_put(obs->message_fifo, cloned_buf); + int err = 0; - break; - } -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ + if (obs->type == ZBUS_OBSERVER_LISTENER_TYPE) { + obs->callback(chan); - default: - _ZBUS_ASSERT(false, "Unreachable"); + } else if (obs->type == ZBUS_OBSERVER_SUBSCRIBER_TYPE) { + err = k_msgq_put(obs->queue, &chan, sys_timepoint_timeout(end_time)); + } else { + CODE_UNREACHABLE; } - return 0; + return err; } static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t end_time) { int err = 0; int last_error = 0; - struct net_buf *buf = NULL; + + _ZBUS_ASSERT(chan != NULL, "chan is required"); /* Static observer event dispatcher logic */ struct zbus_channel_observation *observation; struct zbus_channel_observation_mask *observation_mask; -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) - buf = _zbus_create_net_buf(&_zbus_msg_subscribers_pool, zbus_chan_msg_size(chan), - sys_timepoint_timeout(end_time)); - - _ZBUS_ASSERT(buf != NULL, "net_buf zbus_msg_subscribers_pool is " - "unavailable or heap is full"); - - net_buf_add_mem(buf, zbus_chan_msg(chan), zbus_chan_msg_size(chan)); -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ - - LOG_DBG("Notifing %s's observers. Starting VDED:", _ZBUS_CHAN_NAME(chan)); - - int __maybe_unused index = 0; - for (int16_t i = chan->data->observers_start_idx, limit = chan->data->observers_end_idx; i < limit; ++i) { STRUCT_SECTION_GET(zbus_channel_observation, i, &observation); @@ -149,21 +83,15 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t continue; } - err = _zbus_notify_observer(chan, obs, end_time, buf); + err = _zbus_notify_observer(chan, obs, end_time); + + _ZBUS_ASSERT(err == 0, + "could not deliver notification to observer %s. Error code %d", + _ZBUS_OBS_NAME(obs), err); if (err) { last_error = err; - LOG_ERR("could not deliver notification to observer %s. Error code %d", - _ZBUS_OBS_NAME(obs), err); - if (err == -ENOMEM) { - if (IS_ENABLED(CONFIG_ZBUS_MSG_SUBSCRIBER)) { - net_buf_unref(buf); - } - return err; - } } - - LOG_DBG(" %d -> %s", index++, _ZBUS_OBS_NAME(obs)); } #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) @@ -172,13 +100,15 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&chan->data->observers, obs_nd, tmp, node) { + _ZBUS_ASSERT(obs_nd != NULL, "observer node is NULL"); + const struct zbus_observer *obs = obs_nd->obs; if (!obs->enabled) { continue; } - err = _zbus_notify_observer(chan, obs, end_time, buf); + err = _zbus_notify_observer(chan, obs, end_time); if (err) { last_error = err; @@ -186,8 +116,6 @@ static inline int _zbus_vded_exec(const struct zbus_channel *chan, k_timepoint_t } #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */ - IF_ENABLED(CONFIG_ZBUS_MSG_SUBSCRIBER, (net_buf_unref(buf);)) - return last_error; } @@ -287,43 +215,15 @@ int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **c { _ZBUS_ASSERT(!k_is_in_isr(), "zbus cannot be used inside ISRs"); _ZBUS_ASSERT(sub != NULL, "sub is required"); - _ZBUS_ASSERT(sub->type == ZBUS_OBSERVER_SUBSCRIBER_TYPE, "sub must be a SUBSCRIBER"); - _ZBUS_ASSERT(sub->queue != NULL, "sub queue is required"); - _ZBUS_ASSERT(chan != NULL, "chan is required"); - - return k_msgq_get(sub->queue, chan, timeout); -} - -#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) - -int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg, - k_timeout_t timeout) -{ - _ZBUS_ASSERT(!k_is_in_isr(), "zbus subscribers cannot be used inside ISRs"); - _ZBUS_ASSERT(sub != NULL, "sub is required"); - _ZBUS_ASSERT(sub->type == ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, - "sub must be a MSG_SUBSCRIBER"); - _ZBUS_ASSERT(sub->message_fifo != NULL, "sub message_fifo is required"); _ZBUS_ASSERT(chan != NULL, "chan is required"); - _ZBUS_ASSERT(msg != NULL, "msg is required"); - - struct net_buf *buf = net_buf_get(sub->message_fifo, timeout); - if (buf == NULL) { - return -ENOMSG; + if (sub->queue == NULL) { + return -EINVAL; } - *chan = *((struct zbus_channel **)net_buf_user_data(buf)); - - memcpy(msg, net_buf_remove_mem(buf, zbus_chan_msg_size(*chan)), zbus_chan_msg_size(*chan)); - - net_buf_unref(buf); - - return 0; + return k_msgq_get(sub->queue, chan, timeout); } -#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */ - int zbus_obs_set_chan_notification_mask(const struct zbus_observer *obs, const struct zbus_channel *chan, bool masked) { From 80531ddfe0086d320f70df3e153b759a8e7a9431 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:38 +0000 Subject: [PATCH 4093/4498] Revert "[nrf fromtree] tfm: Add BL2 log level configuration and disable it with TFM silent conf" This reverts commit ad501cb7ca3ce9951ea4fb21b4c21291e0680664. Signed-off-by: Dominik Ermel --- modules/trusted-firmware-m/CMakeLists.txt | 19 ------------------- modules/trusted-firmware-m/Kconfig.tfm | 15 --------------- 2 files changed, 34 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index f00116cda2c..0c01858f34d 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -101,25 +101,6 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=OFF) endif() - if (CONFIG_TFM_BL2) - if (CONFIG_TFM_BL2_LOG_LEVEL_DEBUG) - set(TFM_BL2_LOG_LEVEL "DEBUG") - elseif (CONFIG_TFM_BL2_LOG_LEVEL_INFO) - set(TFM_BL2_LOG_LEVEL "INFO") - elseif (CONFIG_TFM_BL2_LOG_LEVEL_WARNING) - set(TFM_BL2_LOG_LEVEL "WARNING") - elseif (CONFIG_TFM_BL2_LOG_LEVEL_ERROR) - set(TFM_BL2_LOG_LEVEL "ERROR") - elseif (CONFIG_TFM_BL2_LOG_LEVEL_OFF OR CONFIG_TFM_LOG_LEVEL_SILENCE) - set(TFM_BL2_LOG_LEVEL "OFF") - endif() - - if (DEFINED TFM_BL2_LOG_LEVEL) - # BL2 uses MCUBOOT_LOG_LEVEL configuration - list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_LOG_LEVEL=${TFM_BL2_LOG_LEVEL}) - endif() - endif() - if (CONFIG_TFM_PARTITION_LOG_LEVEL_DEBUG) set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_DEBUG") elseif (CONFIG_TFM_PARTITION_LOG_LEVEL_INFO) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index bafa5cf0bab..7fd1b348a74 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -397,21 +397,6 @@ config ROM_START_OFFSET needs to be updated if TF-M switches to use a different header size for BL2. -choice TFM_BL2_LOG_LEVEL - prompt "BL2 Log Level" if !TFM_LOG_LEVEL_SILENCE - default TFM_BL2_LOG_LEVEL_INFO - config TFM_BL2_LOG_LEVEL_DEBUG - bool "Debug" - config TFM_BL2_LOG_LEVEL_INFO - bool "Info" - config TFM_BL2_LOG_LEVEL_WARNING - bool "Warning" - config TFM_BL2_LOG_LEVEL_ERROR - bool "Error" - config TFM_BL2_LOG_LEVEL_OFF - bool "Off" -endchoice - endif # !TFM_BL2 # Option to instruct flashing a merged binary consisting of BL2 (optionally), From fc28989dfce2088c049f03817473b9d315561fab Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:38 +0000 Subject: [PATCH 4094/4498] Revert "[nrf fromtree] boards: Fix nrf9160 NS flash partition layout" This reverts commit f189c88320733cefc0dc25bff43bc854809fc81e. Signed-off-by: Dominik Ermel --- .../circuitdojo_feather_nrf9160_common.dtsi | 13 ++++++++----- .../circuitdojo_feather_nrf9160_ns.yaml | 2 +- ...itdojo_feather_nrf9160_partition_conf.dtsi | 8 ++++---- .../nrf9160_innblue21_common.dtsi | 18 +++++++++++------- .../nrf9160_innblue21_ns.yaml | 2 +- .../nrf9160_innblue21_partition_conf.dtsi | 8 ++++---- .../nrf9160_innblue22_common.dtsi | 19 +++++++++++-------- .../nrf9160_innblue22_ns.yaml | 2 +- .../nrf9160_innblue22_partition_conf.dtsi | 8 ++++---- .../sparkfun_thing_plus_nrf9160_common.dtsi | 13 ++++++++----- .../sparkfun_thing_plus_nrf9160_ns.yaml | 2 +- ...fun_thing_plus_nrf9160_partition_conf.dtsi | 8 ++++---- 12 files changed, 58 insertions(+), 45 deletions(-) diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi index 00ce5dcf6c0..33fdba4d865 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dtsi @@ -187,19 +187,22 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@50000 { + slot0_ns_partition: partition@40000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@c0000 { + slot1_ns_partition: partition@b0000 { label = "image-1-nonsecure"; }; - /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ - storage_partition: partition@f8000 { + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000fa000 0x00006000>; }; }; }; diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml index 56905972e9f..c358a1d87fe 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 192 +flash: 256 supported: - i2c - pwm diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi index 007975132d6..e8cb6fc586e 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dtsi @@ -23,19 +23,19 @@ */ &slot0_partition { - reg = <0x00010000 0x40000>; + reg = <0x00010000 0x30000>; }; &slot0_ns_partition { - reg = <0x00050000 0x30000>; + reg = <0x00040000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x40000>; + reg = <0x00080000 0x30000>; }; &slot1_ns_partition { - reg = <0x000c0000 0x30000>; + reg = <0x000b0000 0x40000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi index 0ec5de5dfb1..0abfd4d6b9c 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dtsi @@ -168,23 +168,27 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x10000>; + reg = <0x00000000 0xc000>; }; - slot0_partition: partition@10000 { + slot0_partition: partition@c000 { label = "image-0"; }; - slot0_ns_partition: partition@50000 { + slot0_ns_partition: partition@3e000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@80000 { + slot1_partition: partition@7e000 { label = "image-1"; }; - slot1_ns_partition: partition@c0000 { + slot1_ns_partition: partition@b0000 { label = "image-1-nonsecure"; }; - storage_partition: partition@f8000 { + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000fa000 0x00006000>; }; }; }; diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml index 4584ad0e6a4..096821d8364 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 192 +flash: 256 supported: - i2c - pwm diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi index 2c64ba67a8a..d3a30abdc76 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dtsi @@ -22,19 +22,19 @@ */ &slot0_partition { - reg = <0x00010000 0x40000>; + reg = <0x0000c000 0x30000>; }; &slot0_ns_partition { - reg = <0x00050000 0x30000>; + reg = <0x0003e000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x40000>; + reg = <0x0007e000 0x30000>; }; &slot1_ns_partition { - reg = <0x000c0000 0x30000>; + reg = <0x000b0000 0x40000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi index 4738dd84a63..4582f975f5d 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dtsi @@ -171,24 +171,27 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x10000>; + reg = <0x00000000 0xc000>; }; - slot0_partition: partition@10000 { + slot0_partition: partition@c000 { label = "image-0"; }; - slot0_ns_partition: partition@50000 { + slot0_ns_partition: partition@3e000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@80000 { + slot1_partition: partition@7e000 { label = "image-1"; }; - slot1_ns_partition: partition@c0000 { + slot1_ns_partition: partition@b0000 { label = "image-1-nonsecure"; }; - /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ - storage_partition: partition@f8000 { + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000fa000 0x00006000>; }; }; }; diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml index 0186c26a377..2ce0d6e3db2 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 192 +flash: 256 supported: - i2c - pwm diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi index b14640a02ec..3588a6a7ce1 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dtsi @@ -22,19 +22,19 @@ */ &slot0_partition { - reg = <0x00010000 0x40000>; + reg = <0x0000c000 0x30000>; }; &slot0_ns_partition { - reg = <0x00050000 0x30000>; + reg = <0x0003e000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x40000>; + reg = <0x0007e000 0x30000>; }; &slot1_ns_partition { - reg = <0x000c0000 0x30000>; + reg = <0x000b0000 0x40000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi index 2658ee5eaa4..b85c00ea5b2 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dtsi @@ -185,19 +185,22 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@50000 { + slot0_ns_partition: partition@40000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@c0000 { + slot1_ns_partition: partition@b0000 { label = "image-1-nonsecure"; }; - /* 0xf0000 to 0xf7fff reserved for TF-M partitions */ - storage_partition: partition@f8000 { + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000fa000 0x00006000>; }; }; }; diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml index adbef49e2b0..e667a231774 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 192 +flash: 256 supported: - i2c - pwm diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi index 64591fbf900..2422b2fdc52 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi +++ b/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_partition_conf.dtsi @@ -23,19 +23,19 @@ */ &slot0_partition { - reg = <0x00010000 0x40000>; + reg = <0x00010000 0x30000>; }; &slot0_ns_partition { - reg = <0x00050000 0x30000>; + reg = <0x00040000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x40000>; + reg = <0x00080000 0x30000>; }; &slot1_ns_partition { - reg = <0x000c0000 0x30000>; + reg = <0x000b0000 0x40000>; }; /* Default SRAM planning when building for nRF9160 with From 8f4dc248b507ce3d5c512153809839a62cf516e0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:39 +0000 Subject: [PATCH 4095/4498] Revert "[nrf fromtree] doc: Remove note for missing tf-m/ns target support" This reverts commit 5d85f6db2d5ec50922e809238e3b088da5727dcf. Signed-off-by: Dominik Ermel --- boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst | 3 +++ boards/arm/nrf9160_innblue21/doc/index.rst | 3 +++ boards/arm/nrf9160_innblue22/doc/index.rst | 3 +++ boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst | 3 +++ boards/arm/thingy53_nrf5340/doc/index.rst | 3 +++ 5 files changed, 15 insertions(+) diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst b/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst index 3d8d2413e91..7718258eec2 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst +++ b/boards/arm/nrf5340_audio_dk_nrf5340/doc/index.rst @@ -53,6 +53,9 @@ The nrf5340_audio_dk_nrf5340_cpuapp build target provides support for the applic core on the nRF5340 SoC. The nrf5340_audio_dk_nrf5340_cpunet build target provides support for the network core on the nRF5340 SoC. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. diff --git a/boards/arm/nrf9160_innblue21/doc/index.rst b/boards/arm/nrf9160_innblue21/doc/index.rst index 9ded085dc6f..628166c409c 100644 --- a/boards/arm/nrf9160_innblue21/doc/index.rst +++ b/boards/arm/nrf9160_innblue21/doc/index.rst @@ -104,6 +104,9 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + Building a Secure only application ================================== diff --git a/boards/arm/nrf9160_innblue22/doc/index.rst b/boards/arm/nrf9160_innblue22/doc/index.rst index 06f6b6326f8..ce3eb35d60f 100644 --- a/boards/arm/nrf9160_innblue22/doc/index.rst +++ b/boards/arm/nrf9160_innblue22/doc/index.rst @@ -104,6 +104,9 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + Building a Secure only application ================================== diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst index aa1a0e6279d..44366c49a39 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst +++ b/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.rst @@ -91,6 +91,9 @@ Building an application In most cases you'll want to use the ``ns`` target with any of the Zephyr or Nordic based examples. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + Some of the examples do not use secure mode, so they do not required the ``ns`` suffix. A great example of this is the `hello_world` below. diff --git a/boards/arm/thingy53_nrf5340/doc/index.rst b/boards/arm/thingy53_nrf5340/doc/index.rst index 4544ea7ed79..3a77deee968 100644 --- a/boards/arm/thingy53_nrf5340/doc/index.rst +++ b/boards/arm/thingy53_nrf5340/doc/index.rst @@ -22,6 +22,9 @@ The nrf5340dk_nrf5340_cpuapp build target provides support for the application core on the nRF5340 SoC. The nrf5340dk_nrf5340_cpunet build target provides support for the network core on the nRF5340 SoC. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. From bf18e1b3d0d4ea11860eb0e47abe10da0dd536aa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:39 +0000 Subject: [PATCH 4096/4498] Revert "[nrf fromtree] boards: Enable TF-M by default for nordic SoC NS boards" This reverts commit 4a3c39feef9ad6dcbb8fbe787f4aef5cc57fdbb3. Signed-off-by: Dominik Ermel --- boards/arm/bl5340_dvk/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig | 15 +++++++++++++++ soc/arm/nordic_nrf/Kconfig | 18 +----------------- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/boards/arm/bl5340_dvk/Kconfig.defconfig b/boards/arm/bl5340_dvk/Kconfig.defconfig index e033f718dba..38a06c8b91d 100644 --- a/boards/arm/bl5340_dvk/Kconfig.defconfig +++ b/boards/arm/bl5340_dvk/Kconfig.defconfig @@ -13,6 +13,21 @@ config BOARD config I2C default GPIO || DAC +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_BL5340_DVK_CPUAPP_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # Code Partition: # # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig index 09ebfbf50ba..d337e2f1a1c 100644 --- a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS config BOARD default "nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF5340DK_NRF5340_CPUAPP_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # Code Partition: # # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig b/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig index 7d9046f63b5..cd052dc7a20 100644 --- a/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig +++ b/boards/arm/nrf9160dk_nrf9160/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS config BOARD default "nrf9160dk_nrf9160" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF9160DK_NRF9160_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig index ea7150ede5f..2674e87cad4 100644 --- a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig +++ b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_NRF9161DK_NRF9161 || BOARD_NRF9161DK_NRF9161_NS config BOARD default "nrf9161dk_nrf9161" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF9161DK_NRF9161_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 19e49c05454..0e3b3e4ee6d 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -25,29 +25,13 @@ config NRF_SOC_SECURE_SUPPORTED For non-secure the functions must redirect to secure services exposed by the secure firmware. -config BUILD_WITH_TFM - default y if TRUSTED_EXECUTION_NONSECURE - help - By default, if we build for a Non-Secure version of the board, - enable building with TF-M as the Secure Execution Environment. - -if BUILD_WITH_TFM - -config TFM_FLASH_MERGED_BINARY - default y - help - By default, if we build with TF-M, instruct build system to - flash the combined TF-M (Secure) & Zephyr (Non Secure) image - config TFM_LOG_LEVEL_SILENCE default y if !$(dt_nodelabel_has_prop,uart1,pinctrl-names) + depends on BUILD_WITH_TFM help Disable TF-M secure output if the uart1 node has not assigned GPIO pins using pinctrl. -endif # BUILD_WITH_TFM - - config NRF_MPU_FLASH_REGION_SIZE hex default 0x1000 From 18cf61dae8120d792b83d3d13aaa5296d5cdc366 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:39 +0000 Subject: [PATCH 4097/4498] Revert "[nrf fromtree] tfm: nordic_nrf: Add generic SoC support for nordic SoCs" This reverts commit 9184096bd977feb4c31608ab67a3a47468e748c5. Signed-off-by: Dominik Ermel --- modules/trusted-firmware-m/Kconfig.tfm | 6 +- .../nordic_nrf/CMakeLists.txt | 67 ------------------- .../nordic_nrf/include/RTE_Device.h | 52 -------------- .../nordic_nrf/include/device_cfg.h | 32 --------- .../nordic_nrf/include/tfm_ioctl_api.h | 32 --------- .../include/tfm_peripherals_config.h | 40 ----------- .../nordic_nrf/include/tfm_read_ranges.h | 60 ----------------- .../nordic_nrf/include/util/array.h | 20 ------ .../nordic_nrf/nrf5340_cpuapp/CMakeLists.txt | 12 ---- .../nordic_nrf/nrf5340_cpuapp/config.cmake | 8 --- .../nordic_nrf/nrf5340_cpuapp/preload.cmake | 7 -- .../nordic_nrf/nrf9120/CMakeLists.txt | 12 ---- .../nordic_nrf/nrf9120/config.cmake | 8 --- .../nordic_nrf/nrf9120/preload.cmake | 7 -- .../nordic_nrf/nrf9160/CMakeLists.txt | 12 ---- .../nordic_nrf/nrf9160/config.cmake | 8 --- .../nordic_nrf/nrf9160/preload.cmake | 7 -- .../nordic_nrf/src/tfm_hal_platform.c | 13 ---- .../nordic_nrf/src/tfm_platform_system.c | 38 ----------- soc/arm/nordic_nrf/CMakeLists.txt | 4 -- soc/arm/nordic_nrf/Kconfig | 7 -- 21 files changed, 3 insertions(+), 449 deletions(-) delete mode 100644 modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/include/util/array.h delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake delete mode 100644 modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c delete mode 100644 modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 7fd1b348a74..a7276d79374 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -9,6 +9,9 @@ config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE config TFM_BOARD string + default "nordic_nrf/nrf9160dk_nrf9160" if BOARD_NRF9160DK_NRF9160_NS + default "nordic_nrf/nrf9161dk_nrf9161" if BOARD_NRF9161DK_NRF9161_NS + default "nordic_nrf/nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP_NS default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_CPU0 default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS default "arm/mps3/an547" if BOARD_MPS3_AN547 @@ -18,9 +21,6 @@ config TFM_BOARD default "arm/musca_b1" if BOARD_MUSCA_B1 default "arm/musca_s1" if BOARD_MUSCA_S1 default "lairdconnectivity/bl5340_dvk_cpuapp" if BOARD_BL5340_DVK_CPUAPP_NS - default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf9160" if SOC_NRF9160 - default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf9120" if SOC_NRF9120 - default "${ZEPHYR_BASE}/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp" if SOC_NRF5340_CPUAPP help The board name used for building TFM. Building with TFM requires that TFM has been ported to the given board/SoC. diff --git a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt deleted file mode 100644 index 41dca2f15a9..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -cmake_policy(SET CMP0076 NEW) -set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) - -set(partition_includes - ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/${NRF_SOC_VARIANT}/partition - ${CMAKE_BINARY_DIR}/../zephyr/include/generated -) - -set(board_includes - ${CMAKE_BINARY_DIR}/../zephyr/misc/generated/syscalls_links/include - ${ZEPHYR_BASE}/include -) - -target_include_directories(platform_region_defs - INTERFACE - ${partition_includes} -) - - -target_sources(platform_s - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_platform_system.c> -) - -target_include_directories(platform_s - PUBLIC - services/include - include - ${partition_includes} - ${board_includes} -) - -target_include_directories(platform_ns - PUBLIC - include - include/util - ${partition_includes} - ${board_includes} -) - -if(BL2) - target_include_directories(platform_bl2 - PUBLIC - include - include/util - ${partition_includes} - ${board_includes} - ) -endif() - -if (TFM_PARTITION_PLATFORM) -install(FILES include/tfm_ioctl_api.h - DESTINATION ${TFM_INSTALL_PATH}/interface/include) -endif() - -#========================= tfm_spm ============================================# - -target_sources(tfm_spm - PRIVATE - src/tfm_hal_platform.c -) diff --git a/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h b/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h deleted file mode 100644 index ca886583fa9..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/RTE_Device.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __RTE_DEVICE_H -#define __RTE_DEVICE_H - -#include - -/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */ -#undef ARRAY_SIZE -#include - -#define UART_PIN_INIT(node_id, prop, idx) \ - DT_PROP_BY_IDX(node_id, prop, idx), - -/* Configuration settings for Driver_USART0. */ -#if DOMAIN_NS == 1U - -#define RTE_USART0 1 - -#define RTE_USART0_PINS \ -{ \ - DT_FOREACH_CHILD_VARGS( \ - DT_PINCTRL_BY_NAME(DT_NODELABEL(uart0), default, 0), \ - DT_FOREACH_PROP_ELEM, psels, UART_PIN_INIT \ - ) \ -} - -#endif - -/* Configuration settings for Driver_USART1. */ -#if DT_PINCTRL_HAS_NAME(DT_NODELABEL(uart1), default) && DOMAIN_NS != 1U - -#define RTE_USART1 1 - -#define RTE_USART1_PINS \ -{ \ - DT_FOREACH_CHILD_VARGS( \ - DT_PINCTRL_BY_NAME(DT_NODELABEL(uart1), default, 0), \ - DT_FOREACH_PROP_ELEM, psels, UART_PIN_INIT \ - ) \ -} - -#endif - -/* Configuration settings for Driver_FLASH0. */ -#define RTE_FLASH0 1 - -#endif /* __RTE_DEVICE_H */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h b/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h deleted file mode 100644 index 9b766a35eb9..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/device_cfg.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef DEVICE_CFG_H__ -#define DEVICE_CFG_H__ - -#include - -/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */ -#undef ARRAY_SIZE -#include - -#if DOMAIN_NS == 1U -#define TFM_UART uart0 -#endif - -#if DOMAIN_NS != 1U -#define TFM_UART uart1 -#endif - -#define DEFAULT_UART_BAUDRATE DT_PROP_OR(DT_NODELABEL(TFM_UART), current_speed, 115200) - -#if DT_PROP(DT_NODELABEL(TFM_UART), hw_flow_control) -#define DEFAULT_UART_CONTROL ARM_USART_FLOW_CONTROL_RTS_CTS -#else -#define DEFAULT_UART_CONTROL 0 -#endif - -#endif /* DEVICE_CFG_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h deleted file mode 100644 index c6c36ee927f..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef TFM_IOCTL_API_H__ -#define TFM_IOCTL_API_H__ - -#include -#include -#include -#include - -/* Include core IOCTL services */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Board specific IOCTL services can be added here */ - -#ifdef __cplusplus -} -#endif - -/** - * @} - */ - -#endif /* TFM_IOCTL_API_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h deleted file mode 100644 index 577b583ad03..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/tfm_peripherals_config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef TFM_PERIPHERALS_CONFIG_H__ -#define TFM_PERIPHERALS_CONFIG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef SECURE_UART1 -#define TFM_PERIPHERAL_UARTE1_SECURE 1 -#endif - -#if TEST_NS_SLIH_IRQ || TEST_NS_FLIH_IRQ -#define TFM_PERIPHERAL_TIMER0_SECURE 1 -#endif - -#ifdef PSA_API_TEST_IPC -#define TFM_PERIPHERAL_EGU5_SECURE 1 - -#define TFM_PERIPHERAL_WDT_SECURE 1 -#endif - -#if defined(NRF91_SERIES) - #include -#elif defined(NRF5340_XXAA_APPLICATION) - #include -#else - #error "Unknown device." -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* TFM_PERIPHERAL_CONFIG_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h deleted file mode 100644 index 43468c7fa31..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/tfm_read_ranges.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef TFM_READ_RANGES_H__ -#define TFM_READ_RANGES_H__ - -#include - -#include - -#ifdef NRF_FICR_S_BASE - -#define FICR_BASE NRF_FICR_S_BASE - -#define FICR_INFO_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, INFO)) -#define FICR_INFO_SIZE (sizeof(FICR_INFO_Type)) - -#if defined(FICR_NFC_TAGHEADER0_MFGID_Msk) -#define FICR_NFC_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, NFC)) -#define FICR_NFC_SIZE (sizeof(FICR_NFC_Type)) -#endif - -#if defined(FICR_XOSC32MTRIM_SLOPE_Msk) -#define FICR_XOSC32MTRIM_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, XOSC32MTRIM)) -#define FICR_XOSC32MTRIM_SIZE (sizeof(uint32_t)) -#endif - -/* Used by nrf_erratas.h */ -#define FICR_RESTRICTED_ADDR (FICR_BASE + 0x130) -#define FICR_RESTRICTED_SIZE 0x8 - -#if defined(FICR_SIPINFO_PARTNO_PARTNO_Pos) -#define FICR_SIPINFO_ADDR (FICR_BASE + offsetof(NRF_FICR_Type, SIPINFO)) -#define FICR_SIPINFO_SIZE (sizeof(FICR_SIPINFO_Type)) -#endif - -#endif /* NRF_FICR_S_BASE */ - -static const struct tfm_read_service_range ranges[] = { -#if defined(FICR_INFO_ADDR) - { .start = FICR_INFO_ADDR, .size = FICR_INFO_SIZE }, -#endif -#if defined(FICR_NFC_ADDR) - { .start = FICR_NFC_ADDR, .size = FICR_NFC_SIZE }, -#endif -#if defined(FICR_RESTRICTED_ADDR) - { .start = FICR_RESTRICTED_ADDR, .size = FICR_RESTRICTED_SIZE }, -#endif -#if defined(FICR_XOSC32MTRIM_ADDR) - { .start = FICR_XOSC32MTRIM_ADDR, .size = FICR_XOSC32MTRIM_SIZE }, -#endif -#if defined(FICR_SIPINFO_ADDR) - { .start = FICR_SIPINFO_ADDR, .size = FICR_SIPINFO_SIZE }, -#endif -}; - -#endif /* TFM_READ_RANGES_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/include/util/array.h b/modules/trusted-firmware-m/nordic_nrf/include/util/array.h deleted file mode 100644 index dc9a1f3dddf..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/include/util/array.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __ARRAY_H__ -#define __ARRAY_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef __cplusplus -} -#endif - -#endif /* __ARRAY_H__ */ diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt deleted file mode 100644 index 279ea385996..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf5340) - -add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf5340 nrf5340) - -add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake deleted file mode 100644 index b3e5d74181c..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) -include(${PLATFORM_PATH}/common/nrf5340/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake deleted file mode 100644 index d9bd226eb65..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf5340/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt deleted file mode 100644 index a84c6fd9fd5..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf91) - -add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) - -add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake deleted file mode 100644 index 3f58e7b89eb..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) -include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake deleted file mode 100644 index 4b3c6ee79ab..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf9120/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt deleted file mode 100644 index a84c6fd9fd5..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf91) - -add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) - -add_subdirectory(.. common) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake deleted file mode 100644 index 3f58e7b89eb..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) -include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake deleted file mode 100644 index 364480a6f7f..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf9160/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c b/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c deleted file mode 100644 index 508c1945910..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/src/tfm_hal_platform.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "tfm_hal_defs.h" -#include "tfm_hal_platform_common.h" - -enum tfm_hal_status_t tfm_hal_platform_init(void) -{ - return tfm_hal_platform_common_init(); -} diff --git a/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c b/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c deleted file mode 100644 index b96e1fe1188..00000000000 --- a/modules/trusted-firmware-m/nordic_nrf/src/tfm_platform_system.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "platform/include/tfm_platform_system.h" -#include "cmsis.h" -#include "tfm_platform_hal_ioctl.h" -#include "tfm_ioctl_core_api.h" - -void tfm_platform_hal_system_reset(void) -{ - /* Reset the system */ - NVIC_SystemReset(); -} - -enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request, - psa_invec *in_vec, - psa_outvec *out_vec) -{ - /* Core IOCTL services */ - switch (request) { - case TFM_PLATFORM_IOCTL_READ_SERVICE: - return tfm_platform_hal_read_service(in_vec, out_vec); -#if defined(GPIO_PIN_CNF_MCUSEL_Msk) - case TFM_PLATFORM_IOCTL_GPIO_SERVICE: - return tfm_platform_hal_gpio_service(in_vec, out_vec); -#endif /* defined(GPIO_PIN_CNF_MCUSEL_Msk) */ - - - /* Board specific IOCTL services */ - - /* Not a supported IOCTL service.*/ - default: - return TFM_PLATFORM_ERR_NOT_SUPPORTED; - } -} diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 47364b35ffb..4cfc162f7fd 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -21,8 +21,4 @@ if(CONFIG_BUILD_WITH_TFM) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DHAL_NORDIC_PATH=${ZEPHYR_HAL_NORDIC_MODULE_DIR} ) - - set_property(TARGET zephyr_property_target - APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} - ) endif() diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 0e3b3e4ee6d..c2129db64b3 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -25,13 +25,6 @@ config NRF_SOC_SECURE_SUPPORTED For non-secure the functions must redirect to secure services exposed by the secure firmware. -config TFM_LOG_LEVEL_SILENCE - default y if !$(dt_nodelabel_has_prop,uart1,pinctrl-names) - depends on BUILD_WITH_TFM - help - Disable TF-M secure output if the uart1 node has not assigned GPIO - pins using pinctrl. - config NRF_MPU_FLASH_REGION_SIZE hex default 0x1000 From 8c91a73bf83809029b94068bc1a6be3384b05bff Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:39 +0000 Subject: [PATCH 4098/4498] Revert "[nrf fromtree] boards: Add uart1 pinctrl assignment to nrf5340 Audio DK" This reverts commit cf504c0167559b0ed749e6fee8c07fb153658db9. Signed-off-by: Dominik Ermel --- ...udio_dk_nrf5340_cpuapp_common-pinctrl.dtsi | 22 ------------------- ...rf5340_audio_dk_nrf5340_cpuapp_common.dtsi | 8 ------- 2 files changed, 30 deletions(-) diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi index 5247c04429b..46359082edd 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi @@ -51,28 +51,6 @@ }; }; - uart1_default: uart1_default { - group1 { - psels = , - ; - }; - group2 { - psels = , - ; - bias-pull-up; - }; - }; - - uart1_sleep: uart1_sleep { - group1 { - psels = , - , - , - ; - low-power-enable; - }; - }; - i2c1_default: i2c1_default { group1 { psels = , diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi index df028fb75a2..f529f16fbe8 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi @@ -141,14 +141,6 @@ pinctrl-names = "default", "sleep"; }; -arduino_serial: &uart1 { - compatible = "nordic,nrf-uarte"; - current-speed = <115200>; - pinctrl-0 = <&uart1_default>; - pinctrl-1 = <&uart1_sleep>; - pinctrl-names = "default", "sleep"; -}; - &i2c1 { compatible = "nordic,nrf-twim"; status = "okay"; From 493a47f15958699cea3aa35863b883e6800ffd96 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:40 +0000 Subject: [PATCH 4099/4498] Revert "[nrf fromtree] boards: nrf5340dk_nrf5340: Add default HW flow control pins to uart1" This reverts commit e0fab0305912c36f631b3ad55f4e8ffbf53bb450. Signed-off-by: Dominik Ermel --- .../nrf5340_cpuapp_common-pinctrl.dtsi | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi index f93e3a69402..6db9767c0dc 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common-pinctrl.dtsi @@ -84,12 +84,10 @@ uart1_default: uart1_default { group1 { - psels = , - ; + psels = ; }; group2 { - psels = , - ; + psels = ; bias-pull-up; }; }; @@ -97,9 +95,7 @@ uart1_sleep: uart1_sleep { group1 { psels = , - , - , - ; + ; low-power-enable; }; }; From c8a1b762ef06ab459fc8ed183f95dce92e338bbb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:40 +0000 Subject: [PATCH 4100/4498] Revert "[nrf fromtree] drivers: serial: serial_test.c: Patch 64-bit incompat" This reverts commit f1ee732cab5ebaa83ddf94f0d4c6f734d2684ea7. Signed-off-by: Dominik Ermel --- drivers/serial/serial_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index b1bb46228be..b1661cdfeef 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -404,7 +404,7 @@ static int serial_vnd_rx_enable(const struct device *dev, uint8_t *read_buf, siz { struct serial_vnd_data *data = dev->data; - LOG_WRN("read_size %zd", read_size); + LOG_WRN("read_size %d", read_size); if (data == NULL) { return -ENOTSUP; From 5fbfdf9813cced1aa231178e5ee4b346233fb776 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:40 +0000 Subject: [PATCH 4101/4498] Revert "[nrf fromtree] tests: drivers: modem: Specify targets for cellular" This reverts commit 2370c3921324b0f0a5b85979e4fdb13f5fb03f8a. Signed-off-by: Dominik Ermel --- tests/drivers/build_all/modem/testcase.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 8b42363b4ff..3614cb09655 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -74,9 +74,10 @@ tests: - CONFIG_MODEM_IFACE_UART_ASYNC=y drivers.modem.modem_cellular.build: extra_args: CONF_FILE=modem_cellular.conf - platform_allow: - - native_posix_64 - - native_posix - - qemu_x86 - - qemu_x86_64 + platform_exclude: + - serpente + - particle_boron + - rak5010_nrf52840 + - litex_vexriscv + - ip_k66f min_ram: 36 From 30056531a8c650ffbea101ce50c96d8a814d6726 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:40 +0000 Subject: [PATCH 4102/4498] Revert "[nrf fromtree] drivers: serial: serial_test: Move ring buf dep to Kconfig" This reverts commit 4748e5ed0abaa6e6d9c9e489e16608a9ae2216bf. Signed-off-by: Dominik Ermel --- drivers/serial/Kconfig.test | 1 - drivers/serial/serial_test.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/serial/Kconfig.test b/drivers/serial/Kconfig.test index e7f38edc591..5e7353ba65a 100644 --- a/drivers/serial/Kconfig.test +++ b/drivers/serial/Kconfig.test @@ -8,4 +8,3 @@ config SERIAL_TEST select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select SERIAL_SUPPORT_ASYNC - select RING_BUFFER if (UART_INTERRUPT_DRIVEN || UART_ASYNC_API) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index b1661cdfeef..f18421b00e5 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(mock_serial, CONFIG_LOG_DEFAULT_LEVEL); +BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN) || IS_ENABLED(CONFIG_RING_BUFFER)); +BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_ASYNC_API) || IS_ENABLED(CONFIG_RING_BUFFER)); + #define DT_DRV_COMPAT vnd_serial struct serial_vnd_data { #ifdef CONFIG_RING_BUFFER From 7d8fdbead525a43d8ef6ddbd645091caef8cc978 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:40 +0000 Subject: [PATCH 4103/4498] Revert "[nrf fromtree] drivers: serial: serial_test: Patch irq_isr set to undefined" This reverts commit 757f63ca7660671b008071e7e4eb504660b7c95d. Signed-off-by: Dominik Ermel --- drivers/serial/serial_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index f18421b00e5..2ce4fb50f38 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -318,7 +318,7 @@ static int serial_vnd_callback_set(const struct device *dev, uart_callback_t cal } #if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_INTERRUPT_DRIVEN) - data->irq_isr = NULL; + data->irq_isr = cb; #endif if (callback == NULL && data->read_buf) { From 622a562a00dfff161faaaf6785361caaeafad84f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:41 +0000 Subject: [PATCH 4104/4498] Revert "[nrf fromtree] tests: build_all: modem: Patch dependencies preventing build" This reverts commit 064421793433e85e7df854343f88d725673d3e14. Signed-off-by: Dominik Ermel --- tests/drivers/build_all/modem/modem_cellular.conf | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/drivers/build_all/modem/modem_cellular.conf b/tests/drivers/build_all/modem/modem_cellular.conf index 3366fcf32d4..e541af07e2d 100644 --- a/tests/drivers/build_all/modem/modem_cellular.conf +++ b/tests/drivers/build_all/modem/modem_cellular.conf @@ -1,10 +1,7 @@ CONFIG_TEST=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_NETWORKING=y CONFIG_NET_L2_PPP=y CONFIG_MODEM=y -CONFIG_PM_DEVICE=y -CONFIG_MODEM_CELLULAR=y -CONFIG_UART_ASYNC_API=y -CONFIG_GPIO=y From 3d45163e2e8b09859070024ed4890c4d9d006569 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:41 +0000 Subject: [PATCH 4105/4498] Revert "[nrf fromtree] bluetooth: samples: Add hci_uart_async" This reverts commit 237e871f948cb64089ec9d792d9cc5dd3377b85d. Signed-off-by: Dominik Ermel --- .../bluetooth/hci_uart_async/CMakeLists.txt | 10 - samples/bluetooth/hci_uart_async/README.rst | 158 ------- samples/bluetooth/hci_uart_async/app.overlay | 31 -- .../bluetooth/hci_uart_async/debug.mixin.conf | 15 - samples/bluetooth/hci_uart_async/prj.conf | 25 -- samples/bluetooth/hci_uart_async/sample.yaml | 19 - .../hci_uart_async/src/hci_uart_async.c | 403 ------------------ samples/bluetooth/hci_uart_async/src/main.c | 11 - tests/bluetooth/hci_uart_async/CMakeLists.txt | 15 - tests/bluetooth/hci_uart_async/app.overlay | 11 - .../hci_uart_async/boards/native_posix.conf | 3 - tests/bluetooth/hci_uart_async/prj.conf | 10 - .../hci_uart_async/src/test_hci_uart_async.c | 238 ----------- tests/bluetooth/hci_uart_async/testcase.yaml | 6 - 14 files changed, 955 deletions(-) delete mode 100644 samples/bluetooth/hci_uart_async/CMakeLists.txt delete mode 100644 samples/bluetooth/hci_uart_async/README.rst delete mode 100644 samples/bluetooth/hci_uart_async/app.overlay delete mode 100644 samples/bluetooth/hci_uart_async/debug.mixin.conf delete mode 100644 samples/bluetooth/hci_uart_async/prj.conf delete mode 100644 samples/bluetooth/hci_uart_async/sample.yaml delete mode 100644 samples/bluetooth/hci_uart_async/src/hci_uart_async.c delete mode 100644 samples/bluetooth/hci_uart_async/src/main.c delete mode 100644 tests/bluetooth/hci_uart_async/CMakeLists.txt delete mode 100644 tests/bluetooth/hci_uart_async/app.overlay delete mode 100644 tests/bluetooth/hci_uart_async/boards/native_posix.conf delete mode 100644 tests/bluetooth/hci_uart_async/prj.conf delete mode 100644 tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c delete mode 100644 tests/bluetooth/hci_uart_async/testcase.yaml diff --git a/samples/bluetooth/hci_uart_async/CMakeLists.txt b/samples/bluetooth/hci_uart_async/CMakeLists.txt deleted file mode 100644 index fe45a9cc371..00000000000 --- a/samples/bluetooth/hci_uart_async/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) - -project(hci_uart_async) -target_sources(app PRIVATE - src/hci_uart_async.c - src/main.c -) diff --git a/samples/bluetooth/hci_uart_async/README.rst b/samples/bluetooth/hci_uart_async/README.rst deleted file mode 100644 index 75bf586868d..00000000000 --- a/samples/bluetooth/hci_uart_async/README.rst +++ /dev/null @@ -1,158 +0,0 @@ -.. _bluetooth-hci-uart-async-sample: - -Bluetooth: HCI UART based on ASYNC UART -####################################### - -Expose a Zephyr Bluetooth Controller over a standard Bluetooth HCI UART interface. - -This sample performs the same basic function as the HCI UART sample, but it uses the UART_ASYNC_API -instead of UART_INTERRUPT_DRIVEN API. Not all boards implement both UART APIs, so the board support -of the HCI UART sample may be different. - -Requirements -************ - -* A board with BLE support - -Default UART settings -********************* - -By default the controller builds use the following settings: - -* Baudrate: 1Mbit/s -* 8 bits, no parity, 1 stop bit -* Hardware Flow Control (RTS/CTS) enabled - -Building and Running -******************** - -This sample can be found under :zephyr_file:`samples/bluetooth/hci_uart_async` -in the Zephyr tree and is built as a standard Zephyr application. - -Using the controller with emulators and BlueZ -********************************************* - -The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE -controller and expose it to Linux's BlueZ. - -First, make sure you have a recent BlueZ version installed by following the -instructions in the :ref:`bluetooth_bluez` section. - -Now build and flash the sample for the Nordic nRF5x board of your choice. -All of the Nordic Development Kits come with a Segger IC that provides a -debugger interface and a CDC ACM serial port bridge. More information can be -found in :ref:`nordic_segger`. - -For example, to build for the nRF52832 Development Kit: - -.. zephyr-app-commands:: - :zephyr-app: samples/bluetooth/hci_uart_async - :board: nrf52dk_nrf52832 - :goals: build flash - -.. _bluetooth-hci-uart-async-qemu-posix: - -Using the controller with QEMU and Native POSIX -=============================================== - -In order to use the HCI UART controller with QEMU or Native POSIX you will need -to attach it to the Linux Host first. To do so simply build the sample and -connect the UART to the Linux machine, and then attach it with this command: - -.. code-block:: console - - sudo btattach -B /dev/ttyACM0 -S 1000000 -R - -.. note:: - Depending on the serial port you are using you will need to modify the - ``/dev/ttyACM0`` string to point to the serial device your controller is - connected to. - -.. note:: - The ``-R`` flag passed to ``btattach`` instructs the kernel to avoid - interacting with the controller and instead just be aware of it in order - to proxy it to QEMU later. - -If you are running :file:`btmon` you should see a brief log showing how the -Linux kernel identifies the attached controller. - -Once the controller is attached follow the instructions in the -:ref:`bluetooth_qemu_posix` section to use QEMU with it. - -.. _bluetooth-hci-uart-async-bluez: - -Using the controller with BlueZ -=============================== - -In order to use the HCI UART controller with BlueZ you will need to attach it -to the Linux Host first. To do so simply build the sample and connect the -UART to the Linux machine, and then attach it with this command: - -.. code-block:: console - - sudo btattach -B /dev/ttyACM0 -S 1000000 - -.. note:: - Depending on the serial port you are using you will need to modify the - ``/dev/ttyACM0`` string to point to the serial device your controller is - connected to. - -If you are running :file:`btmon` you should see a comprehensive log showing how -BlueZ loads and initializes the attached controller. - -Once the controller is attached follow the instructions in the -:ref:`bluetooth_ctlr_bluez` section to use BlueZ with it. - -Debugging the controller -======================== - -The sample can be debugged using RTT since the UART is reserved used by this -application. To enable debug over RTT the debug configuration file can be used. - -.. code-block:: console - - west build samples/bluetooth/hci_uart_async -- -DEXTRA_CONFIG='debug.mixin.conf' - -Then attach RTT as described here: :ref:`Using Segger J-Link ` - -Using the controller with the Zephyr host -========================================= - -This describes how to hook up a board running this sample to a board running -an application that uses the Zephyr host. - -On the controller side, the `zephyr,bt-c2h-uart` DTS property (in the `chosen` -block) is used to select which uart device to use. For example if we want to -keep the console logs, we can keep console on uart0 and the HCI on uart1 like -so: - -.. code-block:: dts - - / { - chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,bt-c2h-uart = &uart1; - }; - }; - -On the host application, some config options need to be used to select the H4 -driver instead of the built-in controller: - -.. code-block:: kconfig - - CONFIG_BT_HCI=y - CONFIG_BT_CTLR=n - CONFIG_BT_H4=y - -Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: - -.. code-block:: dts - - / { - chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; - }; - }; diff --git a/samples/bluetooth/hci_uart_async/app.overlay b/samples/bluetooth/hci_uart_async/app.overlay deleted file mode 100644 index e9a282ad78c..00000000000 --- a/samples/bluetooth/hci_uart_async/app.overlay +++ /dev/null @@ -1,31 +0,0 @@ -/* This is the default app device tree overlay. This file is ignored if - * there is a board-specific overlay in `./boards`. - * - * Most boards define a convenient `&uart0`. It's used here to make the - * sample 'just work' automatically for those boards. - */ - -bt_c2h_uart: &uart0 { - status = "okay"; - current-speed = <1000000>; - hw-flow-control; -}; - -/ { - chosen { - zephyr,bt-c2h-uart = &bt_c2h_uart; - }; -}; - -/* Some boards are by default assigning the &uart0 to these other - * functions. Removing the assignments will ensure a compilation error - * instead of accidental interference. - */ -/ { - chosen { - /delete-property/ zephyr,console; - /delete-property/ zephyr,shell-uart; - /delete-property/ zephyr,uart-mcumgr; - /delete-property/ zephyr,bt-mon-uart; - }; -}; diff --git a/samples/bluetooth/hci_uart_async/debug.mixin.conf b/samples/bluetooth/hci_uart_async/debug.mixin.conf deleted file mode 100644 index 3255df74018..00000000000 --- a/samples/bluetooth/hci_uart_async/debug.mixin.conf +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_ASSERT_ON_ERRORS=y -CONFIG_ASSERT=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_OPTIMIZATIONS=y -CONFIG_DEBUG_THREAD_INFO=y - -# Enable RTT console -CONFIG_RTT_CONSOLE=y - -CONFIG_LOG=y -CONFIG_LOG_BUFFER_SIZE=10000 - -# This outputs all HCI traffic to a separate RTT channel. Use `btmon -# --jlink` to read it out. Add `--priority 7` for debug logs. -CONFIG_BT_DEBUG_MONITOR_RTT=y diff --git a/samples/bluetooth/hci_uart_async/prj.conf b/samples/bluetooth/hci_uart_async/prj.conf deleted file mode 100644 index 1de1a46535e..00000000000 --- a/samples/bluetooth/hci_uart_async/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# hci_uart_async -CONFIG_SERIAL=y -CONFIG_UART_ASYNC_API=y - -# hci_raw (dependency of hci_uart) -CONFIG_BT=y -CONFIG_BT_HCI_RAW=y -CONFIG_BT_HCI_RAW_H4=y -CONFIG_BT_HCI_RAW_H4_ENABLE=y - -# Controller configuration. Modify these for your application's needs. -CONFIG_BT_MAX_CONN=16 -CONFIG_BT_BUF_ACL_RX_SIZE=255 -CONFIG_BT_BUF_CMD_TX_SIZE=255 -CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 - -# Send an initial HCI_Command_Complete event on boot without waiting for -# HCI_Reset. Make sure to use the same value for this setting in your -# host application. -#CONFIG_BT_WAIT_NOP=y - -# See `overlay.app`. The 'zephyr,console' chosen node is deleted there -# in case it has a interfering default. Those same boards set this -# config and it must be undone or the build will fail. -CONFIG_UART_CONSOLE=n diff --git a/samples/bluetooth/hci_uart_async/sample.yaml b/samples/bluetooth/hci_uart_async/sample.yaml deleted file mode 100644 index d0db2b90385..00000000000 --- a/samples/bluetooth/hci_uart_async/sample.yaml +++ /dev/null @@ -1,19 +0,0 @@ -sample: - name: Bluetooth HCI UART Async - description: - This sample is a batteries-included example of a Bluetooth HCI UART - connectivity chip. - - It demonstrates a possible implementation of an HCI UART (H4) - interface on top of Zephyr's Bluetooth Raw API, and how to expose it - over a UART. - - This implementation is based on the Zephyr Asynchoronous UART API. -tests: - sample.bluetooth.hci_uart_async.nrf5: - harness: bluetooth - platform_allow: - - nrf52dk_nrf52832 - tags: - - uart - - bluetooth diff --git a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c deleted file mode 100644 index 4d276e42378..00000000000 --- a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c +++ /dev/null @@ -1,403 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -LOG_MODULE_REGISTER(hci_uart_async, LOG_LEVEL_DBG); - -static const struct device *const hci_uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart)); - -static K_THREAD_STACK_DEFINE(h2c_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); -static struct k_thread h2c_thread; - -enum h4_type { - H4_CMD = 0x01, - H4_ACL = 0x02, - H4_SCO = 0x03, - H4_EVT = 0x04, - H4_ISO = 0x05, -}; - -struct k_poll_signal uart_h2c_rx_sig; -struct k_poll_signal uart_c2h_tx_sig; - -static K_FIFO_DEFINE(c2h_queue); - -/** Send raw data on c2h UART. - * - * Blocks until completion. Not thread-safe. - * - * @retval 0 on success - * @retval -EBUSY Another transmission is in progress. This a - * thread-safety violation. - * @retval -errno @ref uart_tx error. - */ -static int uart_c2h_tx(const uint8_t *data, size_t size) -{ - int err; - struct k_poll_signal *sig = &uart_c2h_tx_sig; - struct k_poll_event done[] = { - K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig), - }; - - k_poll_signal_reset(sig); - err = uart_tx(hci_uart_dev, data, size, SYS_FOREVER_US); - - if (err) { - LOG_ERR("uart c2h tx: err %d", err); - return err; - } - - err = k_poll(done, ARRAY_SIZE(done), K_FOREVER); - __ASSERT_NO_MSG(err == 0); - - return 0; -} - -/* Function expects that type is validated and only CMD, ISO or ACL will be used. */ -static uint32_t hci_payload_size(const uint8_t *hdr_buf, enum h4_type type) -{ - switch (type) { - case H4_CMD: - return ((const struct bt_hci_cmd_hdr *)hdr_buf)->param_len; - case H4_ACL: - return sys_le16_to_cpu(((const struct bt_hci_acl_hdr *)hdr_buf)->len); - case H4_ISO: - return bt_iso_hdr_len( - sys_le16_to_cpu(((const struct bt_hci_iso_hdr *)hdr_buf)->len)); - default: - LOG_ERR("Invalid type: %u", type); - return 0; - } -} - -static uint8_t hci_hdr_size(enum h4_type type) -{ - switch (type) { - case H4_CMD: - return sizeof(struct bt_hci_cmd_hdr); - case H4_ACL: - return sizeof(struct bt_hci_acl_hdr); - case H4_ISO: - return sizeof(struct bt_hci_iso_hdr); - default: - LOG_ERR("Unexpected h4 type: %u", type); - return 0; - } -} - -/** Send raw data on c2h UART. - * - * Blocks until either @p size has been received or special UART - * condition occurs on the UART RX line, like an UART break or parity - * error. - * - * Not thread-safe. - * - * @retval 0 on success - * @retval -EBUSY Another transmission is in progress. This a - * thread-safety violation. - * @retval -errno @ref uart_rx_enable error. - * @retval +stop_reason Special condition @ref uart_rx_stop_reason. - */ -static int uart_h2c_rx(uint8_t *dst, size_t size) -{ - int err; - struct k_poll_signal *sig = &uart_h2c_rx_sig; - struct k_poll_event done[] = { - K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig), - }; - - k_poll_signal_reset(sig); - err = uart_rx_enable(hci_uart_dev, dst, size, SYS_FOREVER_US); - - if (err) { - LOG_ERR("uart h2c rx: err %d", err); - return err; - } - - k_poll(done, ARRAY_SIZE(done), K_FOREVER); - return sig->result; -} - -/** Inject a HCI EVT Hardware error into the c2h packet stream. - * - * This uses `bt_recv`, just as if the controller is sending the error. - */ -static void send_hw_error(void) -{ - const uint8_t err_code = 0; - const uint8_t hci_evt_hw_err[] = {BT_HCI_EVT_HARDWARE_ERROR, - sizeof(struct bt_hci_evt_hardware_error), err_code}; - - struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); - - net_buf_add_mem(buf, hci_evt_hw_err, sizeof(hci_evt_hw_err)); - - /* Inject the message into the c2h queue. */ - bt_recv(buf); - - /* The c2h thread will send the message at some point. The host - * will receive it and reset the controller. - */ -} - -static void recover_sync_by_reset_pattern(void) -{ - /* { H4_CMD, le_16(HCI_CMD_OP_RESET), len=0 } */ - const uint8_t h4_cmd_reset[] = {0x01, 0x03, 0x0C, 0x00}; - const uint32_t reset_pattern = sys_get_be32(h4_cmd_reset); - int err; - struct net_buf *h2c_cmd_reset; - uint32_t shift_register = 0; - - LOG_DBG("Looking for reset pattern"); - - while (shift_register != reset_pattern) { - uint8_t read_byte; - - uart_h2c_rx(&read_byte, sizeof(uint8_t)); - LOG_DBG("h2c: 0x%02x", read_byte); - shift_register = (shift_register * 0x100) + read_byte; - } - - LOG_DBG("Pattern found"); - h2c_cmd_reset = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, h4_cmd_reset, sizeof(h4_cmd_reset)); - LOG_DBG("Fowarding reset"); - - err = bt_send(h2c_cmd_reset); - __ASSERT(!err, "Failed to send reset: %d", err); -} - -static void h2c_h4_transport(void) -{ - /* When entering this function, the h2c stream should be - * 'synchronized'. I.e. The stream should be at a H4 packet - * boundary. - * - * This function returns to signal a desynchronization. - * When this happens, the caller should resynchronize before - * entering this function again. It's up to the caller to decide - * how to resynchronize. - */ - - for (;;) { - int err; - struct net_buf *buf; - uint8_t h4_type; - uint8_t hdr_size; - uint8_t *hdr_buf; - uint16_t payload_size; - - LOG_DBG("h2c: listening"); - - /* Read H4 type. */ - err = uart_h2c_rx(&h4_type, sizeof(uint8_t)); - - if (err) { - return; - } - LOG_DBG("h2c: h4_type %d", h4_type); - - /* Allocate buf. */ - buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, &h4_type, sizeof(h4_type)); - LOG_DBG("h2c: buf %p", buf); - - if (!buf) { - /* `h4_type` was invalid. */ - __ASSERT_NO_MSG(hci_hdr_size(h4_type) == 0); - - LOG_WRN("bt_buf_get_tx failed h4_type %d", h4_type); - return; - } - - /* Read HCI header. */ - hdr_size = hci_hdr_size(h4_type); - hdr_buf = net_buf_add(buf, hdr_size); - - err = uart_h2c_rx(hdr_buf, hdr_size); - if (err) { - net_buf_unref(buf); - return; - } - LOG_HEXDUMP_DBG(hdr_buf, hdr_size, "h2c: hci hdr"); - - /* Read HCI payload. */ - payload_size = hci_payload_size(hdr_buf, h4_type); - - LOG_DBG("h2c: payload_size %u", payload_size); - - if (payload_size <= net_buf_tailroom(buf)) { - uint8_t *payload_dst = net_buf_add(buf, payload_size); - - err = uart_h2c_rx(payload_dst, payload_size); - if (err) { - net_buf_unref(buf); - return; - } - LOG_HEXDUMP_DBG(payload_dst, payload_size, "h2c: hci payload"); - } else { - /* Discard oversize packet. */ - uint8_t *discard_dst; - uint16_t discard_size; - - LOG_WRN("h2c: Discarding oversize h4_type %d payload_size %d.", h4_type, - payload_size); - - /* Reset `buf` so all of it is available. */ - net_buf_reset(buf); - discard_dst = net_buf_tail(buf); - discard_size = net_buf_max_len(buf); - - while (payload_size) { - uint16_t read_size = MIN(payload_size, discard_size); - - err = uart_h2c_rx(discard_dst, read_size); - if (err) { - net_buf_unref(buf); - return; - } - - payload_size -= read_size; - } - - net_buf_unref(buf); - buf = NULL; - } - - LOG_DBG("h2c: packet done"); - - /* Route buf to Controller. */ - if (buf) { - err = bt_send(buf); - if (err) { - /* This is not a transport error. */ - LOG_ERR("bt_send err %d", err); - net_buf_unref(buf); - buf = NULL; - } - } - - k_yield(); - } -} - -static void h2c_thread_entry(void *p1, void *p2, void *p3) -{ - k_thread_name_set(k_current_get(), "HCI TX (h2c)"); - - for (;;) { - LOG_DBG("Synchronized"); - h2c_h4_transport(); - LOG_WRN("Desynchronized"); - send_hw_error(); - recover_sync_by_reset_pattern(); - } -} - -void callback(const struct device *dev, struct uart_event *evt, void *user_data) -{ - ARG_UNUSED(user_data); - - if (evt->type == UART_RX_DISABLED) { - (void)k_poll_signal_raise(&uart_h2c_rx_sig, 0); - } else if (evt->type == UART_RX_STOPPED) { - (void)k_poll_signal_raise(&uart_h2c_rx_sig, evt->data.rx_stop.reason); - } else if (evt->type == UART_TX_DONE) { - (void)k_poll_signal_raise(&uart_c2h_tx_sig, 0); - } -} - -static int hci_uart_init(void) -{ - int err; - - k_poll_signal_init(&uart_h2c_rx_sig); - k_poll_signal_init(&uart_c2h_tx_sig); - - LOG_DBG(""); - - if (!device_is_ready(hci_uart_dev)) { - LOG_ERR("HCI UART %s is not ready", hci_uart_dev->name); - return -EINVAL; - } - - BUILD_ASSERT(IS_ENABLED(CONFIG_UART_ASYNC_API)); - err = uart_callback_set(hci_uart_dev, callback, NULL); - - /* Note: Asserts if CONFIG_UART_ASYNC_API is not enabled for `hci_uart_dev`. */ - __ASSERT(!err, "err %d", err); - - return 0; -} - -SYS_INIT(hci_uart_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); - -const struct { - uint8_t h4; - struct bt_hci_evt_hdr hdr; - struct bt_hci_evt_cmd_complete cc; -} __packed cc_evt = { - .h4 = H4_EVT, - .hdr = {.evt = BT_HCI_EVT_CMD_COMPLETE, .len = sizeof(struct bt_hci_evt_cmd_complete)}, - .cc = {.ncmd = 1, .opcode = sys_cpu_to_le16(BT_OP_NOP)}, -}; - -static void c2h_thread_entry(void) -{ - k_thread_name_set(k_current_get(), "HCI RX (c2h)"); - - if (IS_ENABLED(CONFIG_BT_WAIT_NOP)) { - uart_c2h_tx((char *)&cc_evt, sizeof(cc_evt)); - } - - for (;;) { - struct net_buf *buf; - - buf = net_buf_get(&c2h_queue, K_FOREVER); - uart_c2h_tx(buf->data, buf->len); - net_buf_unref(buf); - } -} - -void hci_uart_main(void) -{ - int err; - - err = bt_enable_raw(&c2h_queue); - __ASSERT_NO_MSG(!err); - - /* TX thread. */ - k_thread_create(&h2c_thread, h2c_thread_stack, K_THREAD_STACK_SIZEOF(h2c_thread_stack), - h2c_thread_entry, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); - - /* Reuse current thread as RX thread. */ - c2h_thread_entry(); -} diff --git a/samples/bluetooth/hci_uart_async/src/main.c b/samples/bluetooth/hci_uart_async/src/main.c deleted file mode 100644 index 2d38d83e45c..00000000000 --- a/samples/bluetooth/hci_uart_async/src/main.c +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -extern int hci_uart_main(void); - -int main(void) -{ - hci_uart_main(); - return 0; -} diff --git a/tests/bluetooth/hci_uart_async/CMakeLists.txt b/tests/bluetooth/hci_uart_async/CMakeLists.txt deleted file mode 100644 index 2380f9f1152..00000000000 --- a/tests/bluetooth/hci_uart_async/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -set(EXTRA_CONF_FILE - ../../../samples/bluetooth/hci_uart_async/prj.conf -) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) - -project(test_samples_bluetooth_hci_uart_async) -target_sources(app PRIVATE - ../../../samples/bluetooth/hci_uart_async/src/hci_uart_async.c - src/test_hci_uart_async.c -) diff --git a/tests/bluetooth/hci_uart_async/app.overlay b/tests/bluetooth/hci_uart_async/app.overlay deleted file mode 100644 index d9186722ba6..00000000000 --- a/tests/bluetooth/hci_uart_async/app.overlay +++ /dev/null @@ -1,11 +0,0 @@ -/ { - chosen { - zephyr,bt-c2h-uart = &test_uart; - }; - - test_uart: test_uart { - compatible = "vnd,serial"; - status = "okay"; - buffer-size = <100>; - }; -}; diff --git a/tests/bluetooth/hci_uart_async/boards/native_posix.conf b/tests/bluetooth/hci_uart_async/boards/native_posix.conf deleted file mode 100644 index e638cd6a0ef..00000000000 --- a/tests/bluetooth/hci_uart_async/boards/native_posix.conf +++ /dev/null @@ -1,3 +0,0 @@ -# Print logs and test results on stdout. For some reason, this not the -# default when SERIAL=y. -CONFIG_LOG_BACKEND_NATIVE_POSIX=y diff --git a/tests/bluetooth/hci_uart_async/prj.conf b/tests/bluetooth/hci_uart_async/prj.conf deleted file mode 100644 index b038c7c4312..00000000000 --- a/tests/bluetooth/hci_uart_async/prj.conf +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG_BT_NO_DRIVER=y - -CONFIG_RING_BUFFER=y - -CONFIG_ASSERT=y -CONFIG_LOG=y -CONFIG_TEST=y - -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c b/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c deleted file mode 100644 index 1996aba177a..00000000000 --- a/tests/bluetooth/hci_uart_async/src/test_hci_uart_async.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -LOG_MODULE_REGISTER(test, LOG_LEVEL_DBG); - -/* This is a mock UART. Using `serial_vnd_...` on this simulates - * traffic from the external Host. - */ -static const struct device *const zephyr_bt_c2h_uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart)); - -/* The DUT is Sandwiched between the mock serial interface and a mock - * controller. {{{ - */ -static void serial_vnd_data_callback(const struct device *dev, void *user_data); -static int drv_send(struct net_buf *buf); -static int drv_open(void); -static const struct bt_hci_driver drv = { - .name = "Mock Controller", - .bus = BT_HCI_DRIVER_BUS_VIRTUAL, - .open = drv_open, - .send = drv_send, -}; -static int sys_init_hci_driver_register(void) -{ - serial_vnd_set_callback(zephyr_bt_c2h_uart, serial_vnd_data_callback, NULL); - bt_hci_driver_register(&drv); - return 0; -} -SYS_INIT(sys_init_hci_driver_register, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); -/* }}} */ - -/* Start the DUT "main thread". The settings for this thread are selected as - * true as possible to the real main thread. {{{ - */ -static struct k_thread hci_uart_thread; -static K_THREAD_PINNED_STACK_DEFINE(hci_uart_thread_stack, CONFIG_MAIN_STACK_SIZE); -static void hci_uart_thread_entry(void *p1, void *p2, void *p3) -{ - extern void hci_uart_main(void); - hci_uart_main(); -} -static int sys_init_spawn_hci_uart(void) -{ - k_thread_name_set(&hci_uart_thread, "hci_uart_main"); - k_thread_create(&hci_uart_thread, hci_uart_thread_stack, - K_THREAD_STACK_SIZEOF(hci_uart_thread_stack), hci_uart_thread_entry, NULL, - NULL, NULL, CONFIG_MAIN_THREAD_PRIORITY, 0, K_NO_WAIT); - return 0; -} -SYS_INIT(sys_init_spawn_hci_uart, POST_KERNEL, 64); -/* }}} */ - -/* Mock controller callbacks. {{{ */ - -static int drv_open(void) -{ - LOG_DBG("drv_open"); - return 0; -} - -/** This FIFO holds the references to all h2c packets the DUT has sent - * to the controller using #bt_send. - * - * Each test should mock a controller by calling #net_buf_get on this - * FIFO and simulate a controller's #bt_hci_driver::drv_send. The mocks - * should use #bt_recv to send c2h packets to the DUT. - */ -K_FIFO_DEFINE(drv_send_fifo); /* elem T: net_buf */ -static int drv_send(struct net_buf *buf) -{ - LOG_DBG("buf %p type %d len %u", buf, bt_buf_get_type(buf), buf->len); - LOG_HEXDUMP_DBG(buf->data, buf->len, "buf"); - - __ASSERT_NO_MSG(buf); - net_buf_put(&drv_send_fifo, buf); - return 0; -} - -/* }}} */ - -/* Mock UART c2h TX handler. {{{ */ - -static void serial_vnd_data_callback(const struct device *dev, void *user_data) -{ - uint32_t size = serial_vnd_out_data_size_get(dev); - uint8_t data[size]; - - serial_vnd_read_out_data(dev, data, size); - LOG_HEXDUMP_DBG(data, size, "uart tx"); - - /* If a test needs to look at the c2h UART traffic, it can be - * captured here. - */ -} - -/* }}} */ - -#define HCI_NORMAL_CMD_BUF_COUNT (CONFIG_BT_BUF_CMD_TX_COUNT - 1) -#define TEST_PARAM_HOST_COMPLETE_COUNT 10 -#define TIMEOUT_PRESUME_STUCK K_SECONDS(1) - -/** Corresponds to: - * - #bt_hci_cmd_hdr - */ -const uint8_t h4_msg_cmd_dummy1[] = { - 0x01, /* H4: opcode = CMD */ - 0x01, 0x00, /* H4: CMD: opcode = 1 */ - 0x00, /* H4: CMD: len = 0 */ -}; - -/** Corresponds to: - * - #bt_hci_cmd_hdr - * - #bt_hci_cp_host_num_completed_packets - */ -const uint8_t h4_msg_cmd_host_num_complete[] = { - 0x01, /* H4: opcode = CMD */ - 0x35, 0x0c, /* H4: CMD: opcode = BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS */ - 0x05, /* H4: CMD: len = 5 */ - 0x01, /* H4: CMD: num_handles = 1 */ - 0x00, 0x00, /* H4: CMD: connection_handle = 0 */ - 0x01, 0x00, /* H4: CMD: num_complete = 1 */ -}; - -/** Corresponds to: - * - #bt_hci_evt_hdr - * - #bt_hci_evt_cmd_complete - */ -const uint8_t hci_msg_rx_evt_cmd_complete[] = { - BT_HCI_EVT_CMD_COMPLETE, /* EVT: opcode */ - 0x03, /* EVT: len */ - 0x01, /* EVT: CMDC: ncmd = 1 */ - /* EVT: CMDC: opcode */ - 0x00, - 0x00, -}; - -ZTEST_SUITE(hci_uart, NULL, NULL, NULL, NULL, NULL); -ZTEST(hci_uart, test_h2c_cmd_flow_control) -{ - /* This test assumes the DUT does not care about the contents of - * the HCI messages, other than the HCI type/endpoint and the - * size. This allows the test to cheat and skip the HCI Reset, - * connection setup etc and use dummy command-packets. - */ - - /* Send commands, saturating the controller's command pipeline. */ - for (uint16_t i = 0; i < HCI_NORMAL_CMD_BUF_COUNT; i++) { - int write_size = serial_vnd_queue_in_data(zephyr_bt_c2h_uart, h4_msg_cmd_dummy1, - sizeof(h4_msg_cmd_dummy1)); - __ASSERT_NO_MSG(write_size == sizeof(h4_msg_cmd_dummy1)); - } - - /* At this point, the HCI flow control limit for the cmd - * endpoint has been reached. It will remain so until the - * controller mock has sent a 'HCI Command Complete' event. - * - * But the 'HCI Host Number of Completed Packets' command is - * exempt from HCI flow control. (It's like it has its own - * endpoint, that has no flow control.) - * - * We now send several 'HCI Host Number of Completed Packets' - * packets before handling any commands in the controller. This - * tests whether the DUT is able to engage the lower transport - * flow controller (i.e. UART flow-control) or somehow handle - * the special packets out-of-order in real-time. - */ - for (uint16_t i = 0; i < TEST_PARAM_HOST_COMPLETE_COUNT; i++) { - int write_size = - serial_vnd_queue_in_data(zephyr_bt_c2h_uart, h4_msg_cmd_host_num_complete, - sizeof(h4_msg_cmd_host_num_complete)); - __ASSERT_NO_MSG(write_size == sizeof(h4_msg_cmd_host_num_complete)); - } - - LOG_DBG("All h2c packets queued on UART"); - - /* Then, we check that all packets are delivered without loss. */ - - /* Expect all the normal commands first. */ - for (uint16_t i = 0; i < HCI_NORMAL_CMD_BUF_COUNT; i++) { - /* The mock controller processes a command. */ - { - struct net_buf *buf = net_buf_get(&drv_send_fifo, TIMEOUT_PRESUME_STUCK); - - zassert_not_null(buf); - zassert_equal(buf->len, sizeof(h4_msg_cmd_dummy1) - 1, "Wrong length"); - zassert_mem_equal(buf->data, &h4_msg_cmd_dummy1[1], - sizeof(h4_msg_cmd_dummy1) - 1); - net_buf_unref(buf); - } - - /* The controller sends a HCI Command Complete response. */ - { - int err; - struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT); - - zassert_not_null(buf); - net_buf_add_mem(buf, hci_msg_rx_evt_cmd_complete, - sizeof(hci_msg_rx_evt_cmd_complete)); - err = bt_recv(buf); - zassert_equal(err, 0, "bt_recv failed"); - } - } - - /* Expect all the 'HCI Host Number of Completed Packets'. */ - for (uint16_t i = 0; i < TEST_PARAM_HOST_COMPLETE_COUNT; i++) { - /* The mock controller processes a 'HCI Host Number of Completed Packets'. */ - { - struct net_buf *buf = net_buf_get(&drv_send_fifo, TIMEOUT_PRESUME_STUCK); - - zassert_not_null(buf); - zassert_equal(buf->len, sizeof(h4_msg_cmd_host_num_complete) - 1, - "Wrong length"); - zassert_mem_equal(buf->data, &h4_msg_cmd_host_num_complete[1], - sizeof(h4_msg_cmd_dummy1) - 2); - net_buf_unref(buf); - } - - /* There is no response to 'HCI Host Number of Completed Packets'. */ - } - - LOG_DBG("All h2c packets received by controller."); -} diff --git a/tests/bluetooth/hci_uart_async/testcase.yaml b/tests/bluetooth/hci_uart_async/testcase.yaml deleted file mode 100644 index f7f4a6255eb..00000000000 --- a/tests/bluetooth/hci_uart_async/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -tests: - samples.bluetooth.hci_uart_async: - tags: bluetooth uart - harness: ztest - platform_allow: - - native_posix From 89162d677482a55ee6b1e4df1a0bb5728a5afcfa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:41 +0000 Subject: [PATCH 4106/4498] Revert "[nrf fromtree] drivers: serial_test: Implement interrupt and async APIs" This reverts commit 3c923c5a170c793f8d8582224e7d1c988237247b. Signed-off-by: Dominik Ermel --- drivers/serial/serial_test.c | 319 +--------------------- include/zephyr/drivers/uart/serial_test.h | 2 +- 2 files changed, 3 insertions(+), 318 deletions(-) diff --git a/drivers/serial/serial_test.c b/drivers/serial/serial_test.c index 2ce4fb50f38..95e036e5992 100644 --- a/drivers/serial/serial_test.c +++ b/drivers/serial/serial_test.c @@ -9,21 +9,12 @@ * devices for the "vnd,serial" devicetree compatible used in test code. */ -#include - -#include #include #include #include #include -#include #include -LOG_MODULE_REGISTER(mock_serial, CONFIG_LOG_DEFAULT_LEVEL); - -BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN) || IS_ENABLED(CONFIG_RING_BUFFER)); -BUILD_ASSERT(!IS_ENABLED(CONFIG_UART_ASYNC_API) || IS_ENABLED(CONFIG_RING_BUFFER)); - #define DT_DRV_COMPAT vnd_serial struct serial_vnd_data { #ifdef CONFIG_RING_BUFFER @@ -32,156 +23,8 @@ struct serial_vnd_data { #endif serial_vnd_write_cb_t callback; void *callback_data; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - uart_irq_callback_user_data_t irq_isr; - bool irq_rx_enabled; - bool irq_tx_enabled; -#endif -#ifdef CONFIG_UART_ASYNC_API - uart_callback_t async_cb; - void *async_cb_user_data; - uint8_t *read_buf; - size_t read_size; - size_t read_position; -#endif }; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -static bool is_irq_rx_pending(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - return !ring_buf_is_empty(data->read_queue); -} - -static bool is_irq_tx_pending(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - return ring_buf_space_get(data->written) != 0; -} - -static void irq_process(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - for (;;) { - bool rx_rdy = is_irq_rx_pending(dev); - bool tx_rdy = is_irq_tx_pending(dev); - bool rx_int = rx_rdy && data->irq_rx_enabled; - bool tx_int = tx_rdy && data->irq_tx_enabled; - - LOG_DBG("rx_rdy %d tx_rdy %d", rx_rdy, tx_rdy); - LOG_DBG("rx_int %d tx_int %d", rx_int, tx_int); - - if (!(rx_int || tx_int)) { - break; - } - - LOG_DBG("isr"); - if (!data->irq_isr) { - LOG_ERR("no isr registered"); - break; - } - data->irq_isr(dev, NULL); - }; -} - -static void irq_rx_enable(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - data->irq_rx_enabled = true; - LOG_DBG("rx enabled"); - irq_process(dev); -} - -static void irq_rx_disable(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - data->irq_rx_enabled = false; - LOG_DBG("rx disabled"); -} - -static int irq_rx_ready(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - bool ready = !ring_buf_is_empty(data->read_queue); - - LOG_DBG("rx ready: %d", ready); - return ready; -} - -static void irq_tx_enable(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - LOG_DBG("tx enabled"); - data->irq_tx_enabled = true; - irq_process(dev); -} - -static void irq_tx_disable(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - - data->irq_tx_enabled = false; - LOG_DBG("tx disabled"); -} - -static int irq_tx_ready(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - bool ready = (ring_buf_space_get(data->written) != 0); - - LOG_DBG("tx ready: %d", ready); - return ready; -} - -static void irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, - void *user_data) -{ - struct serial_vnd_data *data = dev->data; - - /* Not implemented. Ok because `user_data` is always NULL in the current - * implementation of core UART API. - */ - __ASSERT_NO_MSG(user_data == NULL); - -#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_ASYNC_API) - if (data->read_buf) { - LOG_ERR("Setting callback to NULL while asynchronous API is in use."); - } - data->async_cb = NULL; - data->async_cb_user_data = NULL; -#endif - - data->irq_isr = cb; - LOG_DBG("callback set"); -} - -static int fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) -{ - struct serial_vnd_data *data = dev->data; - uint32_t write_len = ring_buf_put(data->written, tx_data, size); - - if (data->callback) { - data->callback(dev, data->callback_data); - } - return write_len; -} - -static int fifo_read(const struct device *dev, uint8_t *rx_data, const int size) -{ - struct serial_vnd_data *data = dev->data; - int read_len = ring_buf_get(data->read_queue, rx_data, size); - - LOG_HEXDUMP_DBG(rx_data, read_len, ""); - return read_len; -} -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ - static int serial_vnd_poll_in(const struct device *dev, unsigned char *c) { #ifdef CONFIG_RING_BUFFER @@ -216,35 +59,15 @@ static void serial_vnd_poll_out(const struct device *dev, unsigned char c) } } -#ifdef CONFIG_UART_ASYNC_API -static void async_rx_run(const struct device *dev); -#endif - #ifdef CONFIG_RING_BUFFER -int serial_vnd_queue_in_data(const struct device *dev, const unsigned char *c, uint32_t size) +int serial_vnd_queue_in_data(const struct device *dev, unsigned char *c, uint32_t size) { struct serial_vnd_data *data = dev->data; - int write_size; if (data == NULL || data->read_queue == NULL) { return -ENOTSUP; } - write_size = ring_buf_put(data->read_queue, c, size); - - LOG_DBG("size %u write_size %u", size, write_size); - LOG_HEXDUMP_DBG(c, write_size, ""); - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - if (write_size > 0) { - irq_process(dev); - } -#endif - -#ifdef CONFIG_UART_ASYNC_API - async_rx_run(dev); -#endif - - return write_size; + return ring_buf_put(data->read_queue, c, size); } uint32_t serial_vnd_out_data_size_get(const struct device *dev) @@ -307,128 +130,6 @@ static int serial_vnd_config_get(const struct device *dev, struct uart_config *c } #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ -#ifdef CONFIG_UART_ASYNC_API -static int serial_vnd_callback_set(const struct device *dev, uart_callback_t callback, - void *user_data) -{ - struct serial_vnd_data *data = dev->data; - - if (data == NULL) { - return -ENOTSUP; - } - -#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(CONFIG_UART_INTERRUPT_DRIVEN) - data->irq_isr = cb; -#endif - - if (callback == NULL && data->read_buf) { - LOG_ERR("Setting callback to NULL while asynchronous API is in use."); - } - - data->async_cb = callback; - data->async_cb_user_data = user_data; - - return 0; -} - -static int serial_vnd_api_tx(const struct device *dev, const uint8_t *tx_data, size_t len, - int32_t timeout) -{ - struct serial_vnd_data *data = dev->data; - struct uart_event evt; - uint32_t write_len; - - if (data == NULL) { - return -ENOTSUP; - } - - if (data->async_cb == NULL) { - return -EINVAL; - } - - write_len = ring_buf_put(data->written, tx_data, len); - if (data->callback) { - data->callback(dev, data->callback_data); - } - - __ASSERT(write_len == len, "Ring buffer full. Async wait not implemented."); - - evt = (struct uart_event){ - .type = UART_TX_DONE, - .data.tx.buf = tx_data, - .data.tx.len = len, - }; - data->async_cb(dev, &evt, data->async_cb_user_data); - - return 0; -} - -static void async_rx_run(const struct device *dev) -{ - struct serial_vnd_data *data = dev->data; - struct uart_event evt; - uint32_t read_len; - uint32_t read_remaining; - - if (!data->read_buf) { - return; - } - - __ASSERT_NO_MSG(data->async_cb); - - read_remaining = data->read_size - data->read_position; - - read_len = ring_buf_get(data->read_queue, &data->read_buf[data->read_position], - read_remaining); - - if (read_len != 0) { - evt = (struct uart_event){ - .type = UART_RX_RDY, - .data.rx.buf = data->read_buf, - .data.rx.len = read_len, - .data.rx.offset = data->read_position, - }; - data->async_cb(dev, &evt, data->async_cb_user_data); - } - - data->read_position += read_len; - - if (data->read_position == data->read_size) { - data->read_buf = NULL; - evt = (struct uart_event){ - .type = UART_RX_DISABLED, - }; - data->async_cb(dev, &evt, data->async_cb_user_data); - } -} - -static int serial_vnd_rx_enable(const struct device *dev, uint8_t *read_buf, size_t read_size, - int32_t timeout) -{ - struct serial_vnd_data *data = dev->data; - - LOG_WRN("read_size %d", read_size); - - if (data == NULL) { - return -ENOTSUP; - } - - if (data->async_cb == NULL) { - return -EINVAL; - } - - __ASSERT(timeout == SYS_FOREVER_MS, "Async timeout not implemented."); - - data->read_buf = read_buf; - data->read_size = read_size; - data->read_position = 0; - - async_rx_run(dev); - - return 0; -} -#endif /* CONFIG_UART_ASYNC_API */ - static const struct uart_driver_api serial_vnd_api = { .poll_in = serial_vnd_poll_in, .poll_out = serial_vnd_poll_out, @@ -437,22 +138,6 @@ static const struct uart_driver_api serial_vnd_api = { .configure = serial_vnd_configure, .config_get = serial_vnd_config_get, #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - .irq_callback_set = irq_callback_set, - .irq_rx_enable = irq_rx_enable, - .irq_rx_disable = irq_rx_disable, - .irq_rx_ready = irq_rx_ready, - .irq_tx_enable = irq_tx_enable, - .irq_tx_disable = irq_tx_disable, - .irq_tx_ready = irq_tx_ready, - .fifo_read = fifo_read, - .fifo_fill = fifo_fill, -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#ifdef CONFIG_UART_ASYNC_API - .callback_set = serial_vnd_callback_set, - .tx = serial_vnd_api_tx, - .rx_enable = serial_vnd_rx_enable, -#endif /* CONFIG_UART_ASYNC_API */ }; #define VND_SERIAL_DATA_BUFFER(n) \ diff --git a/include/zephyr/drivers/uart/serial_test.h b/include/zephyr/drivers/uart/serial_test.h index ff1a2ad6181..5e011d40321 100644 --- a/include/zephyr/drivers/uart/serial_test.h +++ b/include/zephyr/drivers/uart/serial_test.h @@ -29,7 +29,7 @@ extern "C" { * * @retval Number of bytes written. */ -int serial_vnd_queue_in_data(const struct device *dev, const unsigned char *data, uint32_t size); +int serial_vnd_queue_in_data(const struct device *dev, unsigned char *data, uint32_t size); /** * @brief Returns size of unread written data. From bb9c3b8af16aa2b69a37dbf8b7b1c4997770979d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:41 +0000 Subject: [PATCH 4107/4498] Revert "[nrf fromtree] dts: bindings: Remove `reg` from `vnd,serial`" This reverts commit 5754cb6632da0d65c448362834f194ceb8b8493e. Signed-off-by: Dominik Ermel --- dts/bindings/test/vnd,serial.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dts/bindings/test/vnd,serial.yaml b/dts/bindings/test/vnd,serial.yaml index c2d931b0ed7..dc2327b4827 100644 --- a/dts/bindings/test/vnd,serial.yaml +++ b/dts/bindings/test/vnd,serial.yaml @@ -5,6 +5,9 @@ compatible: "vnd,serial" include: uart-controller.yaml properties: + reg: + required: true + baud-rate: type: int From 00aa78f7f430e8d43e06281bec9ab31789027424 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:42 +0000 Subject: [PATCH 4108/4498] Revert "[nrf noup] testspec: remove HomeKit from NCS" This reverts commit fabddf3a622625f39a71b9bb0377569e2fe230be. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index c01ae703adf..62b92e74d0f 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -131,6 +131,17 @@ "CI-rs-test": - "**/*" +"CI-homekit-test": + - "modules/openthread/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + "CI-thread-test": - "include/zephyr/net/**/*" - "modules/mbedtls/**/*" From 6c59381599a9af3a50c6d2920223da427484d819 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:42 +0000 Subject: [PATCH 4109/4498] Revert "[nrf fromtree] net: shell: Fix unexpected timeout on loopback ping" This reverts commit 908794942947d049b61603b728f8f15af17e4873. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_shell.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 87995ccabb3..e7af6e16632 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -4535,12 +4535,6 @@ static void ping_work(struct k_work *work) return; } - if (ctx->sequence < ctx->count) { - k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); - } else { - k_work_reschedule(&ctx->work, K_SECONDS(2)); - } - if (ctx->addr.family == AF_INET6) { ret = net_icmpv6_send_echo_request(ctx->iface, &ctx->addr.in6_addr, @@ -4566,6 +4560,12 @@ static void ping_work(struct k_work *work) ping_done(ctx); return; } + + if (ctx->sequence < ctx->count) { + k_work_reschedule(&ctx->work, K_MSEC(ctx->interval)); + } else { + k_work_reschedule(&ctx->work, K_SECONDS(2)); + } } #define ASCII_CTRL_C 0x03 From 9f8b19cfbc8b5bc57e8f5903cee897ef56c833bf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:42 +0000 Subject: [PATCH 4110/4498] Revert "[nrf fromtree] net: core: Set LL address on loopback packet" This reverts commit e73ebd314f6f8a8df179f11fd5f500522acc94e4. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_core.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 1f6dac720af..c94607b4485 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -211,15 +211,6 @@ static void init_rx_queues(void) /* Check if the IPv{4|6} addresses are proper. As this can be expensive, * make this optional. */ - -static inline void copy_ll_addr(struct net_pkt *pkt) -{ - memcpy(net_pkt_lladdr_src(pkt), net_pkt_lladdr_if(pkt), - sizeof(struct net_linkaddr)); - memcpy(net_pkt_lladdr_dst(pkt), net_pkt_lladdr_if(pkt), - sizeof(struct net_linkaddr)); -} - static inline int check_ip_addr(struct net_pkt *pkt) { uint8_t family = net_pkt_family(pkt); @@ -248,9 +239,6 @@ static inline int check_ip_addr(struct net_pkt *pkt) NET_IPV6_HDR(pkt)->dst); net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr); - net_pkt_set_ll_proto_type(pkt, ETH_P_IPV6); - copy_ll_addr(pkt); - return 1; } @@ -298,9 +286,6 @@ static inline int check_ip_addr(struct net_pkt *pkt) NET_IPV4_HDR(pkt)->dst); net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr); - net_pkt_set_ll_proto_type(pkt, ETH_P_IP); - copy_ll_addr(pkt); - return 1; } From a30a56e49ba2d443aaf7b8be4117a0ef26a60725 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:42 +0000 Subject: [PATCH 4111/4498] Revert "[nrf fromtree] soc: arm: nordic_nrf: align nrf_power calls to new scheme" This reverts commit 729573484b5c74e6f4f83ccba5c63f80f96abad0. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf51/soc.c | 2 +- soc/arm/nordic_nrf/nrf52/soc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf51/soc.c b/soc/arm/nordic_nrf/nrf51/soc.c index 2b22c95679f..078a422c06b 100644 --- a/soc/arm/nordic_nrf/nrf51/soc.c +++ b/soc/arm/nordic_nrf/nrf51/soc.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(soc); */ void sys_arch_reboot(int type) { - nrf_power_gpregret_set(NRF_POWER, 0, (uint8_t)type); + nrf_power_gpregret_set(NRF_POWER, (uint8_t)type); NVIC_SystemReset(); } #endif diff --git a/soc/arm/nordic_nrf/nrf52/soc.c b/soc/arm/nordic_nrf/nrf52/soc.c index 5f310e5f945..52b97164e72 100644 --- a/soc/arm/nordic_nrf/nrf52/soc.c +++ b/soc/arm/nordic_nrf/nrf52/soc.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(soc); */ void sys_arch_reboot(int type) { - nrf_power_gpregret_set(NRF_POWER, 0, (uint8_t)type); + nrf_power_gpregret_set(NRF_POWER, (uint8_t)type); NVIC_SystemReset(); } #endif From 132e760eacd0c22e93547c3e671b9bcb87dd8e01 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:42 +0000 Subject: [PATCH 4112/4498] Revert "[nrf fromtree] modules: hal_nordic: nrfx: enable GPIOTE1 for NS builds" This reverts commit bc160058effb4a887acbad987ff44cf6b7db3494. Signed-off-by: Dominik Ermel --- modules/hal_nordic/nrfx/nrfx_config.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 29051ccf754..4b7cabd7a98 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -117,12 +117,6 @@ #ifdef CONFIG_NRFX_GPIOTE #define NRFX_GPIOTE_ENABLED 1 -#if (defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_SERIES_NRF53X)) \ - && defined(NRF_TRUSTZONE_NONSECURE) -#define NRFX_GPIOTE1_ENABLED 1 -#else -#define NRFX_GPIOTE0_ENABLED 1 -#endif #endif #ifdef CONFIG_NRFX_GPIOTE_LOG #define NRFX_GPIOTE_CONFIG_LOG_ENABLED 1 From 29c2a495cf043db8562aa89cd19c2c0c7156186a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:43 +0000 Subject: [PATCH 4113/4498] Revert "[nrf fromtree] samples: boards: nrf: nrfx_prs: align to new nrfx_uarte" This reverts commit 7b453aac8b078f938eefff92e5d0b4d9f481adfb. Signed-off-by: Dominik Ermel --- samples/boards/nrf/nrfx_prs/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/nrf/nrfx_prs/src/main.c b/samples/boards/nrf/nrfx_prs/src/main.c index 934bbbe834d..618c0718143 100644 --- a/samples/boards/nrf/nrfx_prs/src/main.c +++ b/samples/boards/nrf/nrfx_prs/src/main.c @@ -191,7 +191,7 @@ static bool spim_transfer(const uint8_t *tx_data, size_t tx_data_len, static void uarte_handler(const nrfx_uarte_event_t *p_event, void *p_context) { if (p_event->type == NRFX_UARTE_EVT_RX_DONE) { - received = p_event->data.rx.length; + received = p_event->data.rx.bytes; k_sem_give(&transfer_finished); } else if (p_event->type == NRFX_UARTE_EVT_ERROR) { received = 0; From aa763285c1d8b436f3fe7eb2f2da5751cd54fd69 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:43 +0000 Subject: [PATCH 4114/4498] Revert "[nrf fromtree] soc: arm: nordic_nrf: nrf53: align nrf_regulators" This reverts commit 2831d726ec09ce354fca9ff83382f8bf94bfefb5. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/soc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 3542ef3e914..39d64d72cc2 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -554,13 +554,13 @@ static int nordicsemi_nrf53_init(void) #endif #if defined(CONFIG_SOC_DCDC_NRF53X_APP) - nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MAIN, true); + nrf_regulators_dcdcen_set(NRF_REGULATORS, true); #endif #if defined(CONFIG_SOC_DCDC_NRF53X_NET) - nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_RADIO, true); + nrf_regulators_dcdcen_radio_set(NRF_REGULATORS, true); #endif #if defined(CONFIG_SOC_DCDC_NRF53X_HV) - nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_HIGH, true); + nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS, true); #endif #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) From b6f7dc467a18e034d9e7bd78962ca97658842d7c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:43 +0000 Subject: [PATCH 4115/4498] Revert "[nrf fromtree] drivers: sensor: qdec_nrfx: Revert samplerdy workaround" This reverts commit 82e15a98880869aa4a80c2104988480330d8d326. Signed-off-by: Dominik Ermel --- drivers/sensor/qdec_nrfx/qdec_nrfx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/sensor/qdec_nrfx/qdec_nrfx.c b/drivers/sensor/qdec_nrfx/qdec_nrfx.c index b11ce70fb9c..81c3614fc05 100644 --- a/drivers/sensor/qdec_nrfx/qdec_nrfx.c +++ b/drivers/sensor/qdec_nrfx/qdec_nrfx.c @@ -135,6 +135,13 @@ static void qdec_nrfx_event_handler(nrfx_qdec_event_t event, void *p_context) unsigned int key; switch (event.type) { + case NRF_QDEC_EVENT_SAMPLERDY: + /* The underlying HAL driver may improperly forward an samplerdy event even if it's + * disabled in the configuration. Ignore the event to prevent error logs until the + * issue is fixed in HAL. + */ + break; + case NRF_QDEC_EVENT_REPORTRDY: accumulate(dev_data, event.data.report.acc); From e8549b921d17130d44764c49ac84a84d42e1770d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:43 +0000 Subject: [PATCH 4116/4498] Revert "[nrf fromtree] manifest: tf-m: update to have atomics for nrfx port" This reverts commit 7931877e976a0a2a47a99a7701e7e1930b2bde0d. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 1847e94b37c..44098dac030 100644 --- a/west.yml +++ b/west.yml @@ -331,7 +331,7 @@ manifest: groups: - debug - name: trusted-firmware-m - revision: 33c0f47bcb19721a5c33e6fe1eee9225d00bb5bc + revision: 8b6146261fe2c0ad61154e20c7e338601eae2208 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 7c5854973f9c68241d05421ffa927d87bd0ed541 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:43 +0000 Subject: [PATCH 4117/4498] Revert "[nrf fromtree] manifest: hal_nordic: Update hal_nordic revision" This reverts commit 2a12aea553568d2b1683c2b329f0ac648661110a. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 44098dac030..909800d0aab 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 2ff8ce6e6ca131d87699dba260f3c0cc4a6cc365 + revision: 427ee1a519e8a0844d0f78f7cbc8cdfc134ef00d path: modules/hal/nordic groups: - hal From 977540f7a3d1765a9574fc053a9ff4ac72df48d8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:44 +0000 Subject: [PATCH 4118/4498] Revert "[nrf fromtree] scripts: ci: check_compliance: Add sysbuild Kconfig exceptions" This reverts commit 335beb0032206badd6cef214bbd82cdc0c51d49f. Signed-off-by: Dominik Ermel --- scripts/ci/check_compliance.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 07d7431dd65..1499d92eaf9 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -633,8 +633,6 @@ def check_no_undef_outside_kconfig(self, kconf): # toolchain Kconfig which is sourced based on # Zephyr toolchain variant and therefore not # visible to compliance. - "BOOT_ENCRYPTION_KEY_FILE", # Used in sysbuild - "BOOT_ENCRYPT_IMAGE", # Used in sysbuild "BOOT_UPGRADE_ONLY", # Used in example adjusting MCUboot config, but # symbol is defined in MCUboot itself. "BOOT_SERIAL_BOOT_MODE", # Used in (sysbuild-based) test/ From 5855d0887b632ee85f126c438de439d1e22971ea Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:44 +0000 Subject: [PATCH 4119/4498] Revert "[nrf fromtree] sysbuild: Add support for MCUboot/app encryption keys" This reverts commit 4936f55987b49cedd92288f686410f374ed345d2. Signed-off-by: Dominik Ermel --- .../MAIN_image_default.cmake | 3 --- .../sysbuild/images/bootloader/CMakeLists.txt | 4 ---- share/sysbuild/images/bootloader/Kconfig | 20 ++----------------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/share/sysbuild/image_configurations/MAIN_image_default.cmake b/share/sysbuild/image_configurations/MAIN_image_default.cmake index a2ae840ef97..a6bd72d7d1a 100644 --- a/share/sysbuild/image_configurations/MAIN_image_default.cmake +++ b/share/sysbuild/image_configurations/MAIN_image_default.cmake @@ -9,9 +9,6 @@ set_config_bool(${ZCMAKE_APPLICATION} CONFIG_BOOTLOADER_MCUBOOT "${SB_CONFIG_BOO set_config_string(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_SIGNATURE_KEY_FILE "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}" ) -set_config_string(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE - "${SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE}" -) if(SB_CONFIG_BOOTLOADER_MCUBOOT) if("${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") diff --git a/share/sysbuild/images/bootloader/CMakeLists.txt b/share/sysbuild/images/bootloader/CMakeLists.txt index 2a0f12f958d..c00a8e97783 100644 --- a/share/sysbuild/images/bootloader/CMakeLists.txt +++ b/share/sysbuild/images/bootloader/CMakeLists.txt @@ -15,8 +15,4 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT) sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} ${image}) set_config_string(${image} CONFIG_BOOT_SIGNATURE_KEY_FILE "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}") - set_config_bool(${image} CONFIG_BOOT_ENCRYPT_IMAGE "${SB_CONFIG_BOOT_ENCRYPTION}") - if(SB_CONFIG_BOOT_ENCRYPTION) - set_config_string(${image} CONFIG_BOOT_ENCRYPTION_KEY_FILE "${SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE}") - endif() endif() diff --git a/share/sysbuild/images/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig index e8c788f72c5..19924a6ca18 100644 --- a/share/sysbuild/images/bootloader/Kconfig +++ b/share/sysbuild/images/bootloader/Kconfig @@ -56,28 +56,12 @@ config BOOT_SIGNATURE_TYPE_ED25519 endchoice config BOOT_SIGNATURE_KEY_FILE - string "Signing PEM key file" + string "PEM key file" default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ed25519.pem" if BOOT_SIGNATURE_TYPE_ED25519 default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-rsa-2048.pem" if BOOT_SIGNATURE_TYPE_RSA default "" help - Absolute path to signing key file to use with MCUBoot. - -config BOOT_ENCRYPTION - bool "Encrypted image support" - depends on !BOOT_SIGNATURE_TYPE_NONE - help - Support encrypted images. - -config BOOT_ENCRYPTION_KEY_FILE - string "Encryption PEM key file" - depends on BOOT_ENCRYPTION - default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-ec256-priv.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 - default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-x25519-priv.pem" if BOOT_SIGNATURE_TYPE_ED25519 - default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/enc-rsa2048-priv.pem" if BOOT_SIGNATURE_TYPE_RSA - default "" - help - Absolute path to encryption key file to use with MCUBoot. + Absolute path to key file to use with MCUBoot. endif From 17330500b22a4d4251c44d1a8558a0f3297f8569 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:44 +0000 Subject: [PATCH 4120/4498] Revert "[nrf fromtree] scripts: ci: Fix for compliance with multi-user machine" This reverts commit 9058a859d67b19c9d307943d8f206d917a37752a. Signed-off-by: Dominik Ermel --- scripts/ci/check_compliance.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 1499d92eaf9..74ddf19b2fb 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -16,7 +16,6 @@ import tempfile import traceback import shlex -import shutil from yamllint import config, linter @@ -370,8 +369,6 @@ def parse_kconfig(self): if not os.path.exists(kconfig_path): self.error(kconfig_path + " not found") - kconfiglib_dir = tempfile.mkdtemp(prefix="kconfiglib_") - sys.path.insert(0, kconfig_path) # Import globally so that e.g. kconfiglib.Symbol can be referenced in # tests @@ -386,7 +383,7 @@ def parse_kconfig(self): os.environ["ARCH_DIR"] = "arch/" os.environ["BOARD_DIR"] = "boards/*/*" os.environ["ARCH"] = "*" - os.environ["KCONFIG_BINARY_DIR"] = kconfiglib_dir + os.environ["KCONFIG_BINARY_DIR"] = tempfile.gettempdir() os.environ['DEVICETREE_CONF'] = "dummy" os.environ['TOOLCHAIN_HAS_NEWLIB'] = "y" @@ -395,9 +392,10 @@ def parse_kconfig(self): os.environ["GENERATED_DTS_BOARD_CONF"] = "dummy" # For multi repo support - self.get_modules(os.path.join(kconfiglib_dir, "Kconfig.modules")) + self.get_modules(os.path.join(tempfile.gettempdir(), "Kconfig.modules")) + # For Kconfig.dts support - self.get_kconfig_dts(os.path.join(kconfiglib_dir, "Kconfig.dts")) + self.get_kconfig_dts(os.path.join(tempfile.gettempdir(), "Kconfig.dts")) # Tells Kconfiglib to generate warnings for all references to undefined # symbols within Kconfig files @@ -412,9 +410,6 @@ def parse_kconfig(self): except kconfiglib.KconfigError as e: self.failure(str(e)) raise EndTest - finally: - # Clean up the temporary directory - shutil.rmtree(kconfiglib_dir) def get_defined_syms(self, kconf): # Returns a set() with the names of all defined Kconfig symbols (with no From c6c487715597ea2ee18744b84722cd771f1dbacf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:44 +0000 Subject: [PATCH 4121/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Fix GATT read multiple" This reverts commit 2e2523efe52a7ac89f0567b8798fd857b1e71ae3. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_gatt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_gatt.c b/tests/bluetooth/tester/src/btp_gatt.c index 6509ca7fe4b..4d046cc3aad 100644 --- a/tests/bluetooth/tester/src/btp_gatt.c +++ b/tests/bluetooth/tester/src/btp_gatt.c @@ -1651,11 +1651,11 @@ static uint8_t read_multiple(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - if (cp->handles_count == 0 || cp->handles_count > ARRAY_SIZE(handles)) { + if (cp->handles_count > ARRAY_SIZE(handles)) { return BTP_STATUS_FAILED; } - for (i = 0; i < cp->handles_count; i++) { + for (i = 0; i < ARRAY_SIZE(handles); i++) { handles[i] = sys_le16_to_cpu(cp->handles[i]); } @@ -1670,7 +1670,7 @@ static uint8_t read_multiple(const void *cmd, uint16_t cmd_len, } read_params.func = read_cb; - read_params.handle_count = cp->handles_count; + read_params.handle_count = i; read_params.multiple.handles = handles; /* not used in read func */ read_params.multiple.variable = false; read_params.chan_opt = BT_ATT_CHAN_OPT_NONE; From 9600620aecb433f1f1fccd8389f5aaedcc35c5ba Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:45 +0000 Subject: [PATCH 4122/4498] Revert "[nrf fromlist] Bluetooth: Mesh: FU Server should not update internal state on error" This reverts commit 7ac418187369487f6fa633dab6d6c0a99913f479. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfu_srv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/dfu_srv.c b/subsys/bluetooth/mesh/dfu_srv.c index 462a777b46c..282a40074c9 100644 --- a/subsys/bluetooth/mesh/dfu_srv.c +++ b/subsys/bluetooth/mesh/dfu_srv.c @@ -302,10 +302,10 @@ static int handle_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, status = BT_MESH_DFU_ERR_WRONG_PHASE; } else { status = BT_MESH_DFU_SUCCESS; - srv->update.ttl = ttl; - srv->blob.state.xfer.id = blob_id; } + srv->update.ttl = ttl; + srv->blob.state.xfer.id = blob_id; LOG_WRN("Busy. Phase: %u", srv->update.phase); goto rsp; } From 8f5f55e7318f562c42a37e1fe4e7f35092f74e6d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:45 +0000 Subject: [PATCH 4123/4498] Revert "[nrf fromlist] Bluetooth: mesh: update model extension" This reverts commit 32a51d982e0b7eba7e458678a8246440b25c3916. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/access.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 6ca7dbe580b..63c4f76c392 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1678,7 +1678,7 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod /* Check if a's list contains b */ for (it = a; (it != NULL) && (it->next != a); it = it->next) { if (it == b) { - goto register_extension; + return 0; } } @@ -1695,7 +1695,7 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod a->next = b; } -register_extension: + if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { return mod_rel_register(base_mod, extending_mod, RELATION_TYPE_EXT); } From 75708dd6049a7cb697f73c141fe8ff4bcbc69616 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:45 +0000 Subject: [PATCH 4124/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Fix issue where dfu_cli could get stuck" This reverts commit 979569b82b96246889e67a17a4a7987710c4802e. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfu_cli.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/subsys/bluetooth/mesh/dfu_cli.c b/subsys/bluetooth/mesh/dfu_cli.c index 4db7779116b..3805a04e450 100644 --- a/subsys/bluetooth/mesh/dfu_cli.c +++ b/subsys/bluetooth/mesh/dfu_cli.c @@ -305,23 +305,6 @@ static void tx_end(int err, void *cb_data) blob_cli_broadcast_tx_complete(&cli->blob); } -static int tx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, - const struct bt_mesh_send_cb *cb, struct bt_mesh_dfu_cli *cli) -{ - int err; - - err = bt_mesh_model_send(mod, ctx, buf, cb, cli); - if (err) { - LOG_ERR("Send err: %d", err); - if (cb) { - cb->end(err, cli); - } - return err; - } - - return 0; -} - static int info_get(struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, uint8_t idx, uint8_t max_count, const struct bt_mesh_send_cb *cb) @@ -331,7 +314,7 @@ static int info_get(struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, net_buf_simple_add_u8(&buf, idx); net_buf_simple_add_u8(&buf, max_count); - return tx(cli->mod, ctx, &buf, cb, cli); + return bt_mesh_model_send(cli->mod, ctx, &buf, cb, cli); } static void send_info_get(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -369,7 +352,7 @@ static void send_update_start(struct bt_mesh_blob_cli *b, uint16_t dst) net_buf_simple_add_mem(&buf, cli->xfer.slot->metadata, cli->xfer.slot->metadata_len); - (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); + bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_get(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -380,7 +363,7 @@ static void send_update_get(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_GET, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_GET); - (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); + bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_cancel(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -391,7 +374,7 @@ static void send_update_cancel(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_CANCEL, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_CANCEL); - (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); + bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); } static void send_update_apply(struct bt_mesh_blob_cli *b, uint16_t dst) @@ -402,7 +385,7 @@ static void send_update_apply(struct bt_mesh_blob_cli *b, uint16_t dst) BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_APPLY, 0); bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_APPLY); - (void)tx(cli->mod, &ctx, &buf, &send_cb, cli); + bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli); } /******************************************************************************* From 7612012dfcec90ad1b580b40c51ddbe480a57c15 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:45 +0000 Subject: [PATCH 4125/4498] Revert "[nrf fromlist] tests: bluetooth: tester: Allow to compile mesh without LPN" This reverts commit 66324255acd8c12723aaf62b8a61c2e1fb17c8f5. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/testing.c | 2 -- tests/bluetooth/tester/src/btp_mesh.c | 8 -------- 2 files changed, 10 deletions(-) diff --git a/subsys/bluetooth/host/testing.c b/subsys/bluetooth/host/testing.c index 3c118c51e0f..c3121fd230d 100644 --- a/subsys/bluetooth/host/testing.c +++ b/subsys/bluetooth/host/testing.c @@ -102,7 +102,6 @@ void bt_test_mesh_trans_incomp_timer_exp(void) } } -#if defined(CONFIG_BT_MESH_LOW_POWER) int bt_test_mesh_lpn_group_add(uint16_t group) { bt_mesh_lpn_group_add(group); @@ -116,7 +115,6 @@ int bt_test_mesh_lpn_group_remove(uint16_t *groups, size_t groups_count) return 0; } -#endif /* CONFIG_BT_MESH_LOW_POWER */ int bt_test_mesh_rpl_clear(void) { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index bdc37c2f2e5..5eff344540e 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1553,7 +1553,6 @@ static uint8_t ivu_toggle_state(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#if defined(CONFIG_BT_MESH_LOW_POWER) static uint8_t lpn(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1585,7 +1584,6 @@ static uint8_t lpn_poll(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#endif /* CONFIG_BT_MESH_LOW_POWER */ static uint8_t net_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -1767,7 +1765,6 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, } #if defined(CONFIG_BT_TESTING) -#if defined(CONFIG_BT_MESH_LOW_POWER) static uint8_t lpn_subscribe(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1803,7 +1800,6 @@ static uint8_t lpn_unsubscribe(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#endif /* CONFIG_BT_MESH_LOW_POWER */ static uint8_t rpl_clear(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -4583,7 +4579,6 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = ivu_toggle_state, }, -#if defined(CONFIG_BT_MESH_LOW_POWER) { .opcode = BTP_MESH_LPN, .expect_len = sizeof(struct btp_mesh_lpn_set_cmd), @@ -4594,7 +4589,6 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = lpn_poll, }, -#endif /* CONFIG_BT_MESH_LOW_POWER */ { .opcode = BTP_MESH_NET_SEND, .expect_len = BTP_HANDLER_LENGTH_VARIABLE, @@ -4906,7 +4900,6 @@ static const struct btp_handler handlers[] = { .func = va_del, }, #if defined(CONFIG_BT_TESTING) -#if defined(CONFIG_BT_MESH_LOW_POWER) { .opcode = BTP_MESH_LPN_SUBSCRIBE, .expect_len = sizeof(struct btp_mesh_lpn_subscribe_cmd), @@ -4917,7 +4910,6 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_mesh_lpn_unsubscribe_cmd), .func = lpn_unsubscribe, }, -#endif /* CONFIG_BT_MESH_LOW_POWER */ { .opcode = BTP_MESH_RPL_CLEAR, .expect_len = 0, From 307236605e9564aba7068798cb3a807d392e0c04 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:45 +0000 Subject: [PATCH 4126/4498] Revert "[nrf fromlist] Bluetooth: Mesh: Keep sending Partial Block Report message" This reverts commit 834948da4a87ff41241bd325d685e4e474f511f4. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/blob_srv.c | 70 +++++++------------------------- 1 file changed, 14 insertions(+), 56 deletions(-) diff --git a/subsys/bluetooth/mesh/blob_srv.c b/subsys/bluetooth/mesh/blob_srv.c index 1e6cb9bc91a..56a89472ea6 100644 --- a/subsys/bluetooth/mesh/blob_srv.c +++ b/subsys/bluetooth/mesh/blob_srv.c @@ -251,37 +251,6 @@ static void resume(struct bt_mesh_blob_srv *srv) reset_timer(srv); } -static void end(struct bt_mesh_blob_srv *srv) -{ - phase_set(srv, BT_MESH_BLOB_XFER_PHASE_COMPLETE); - k_work_cancel_delayable(&srv->rx_timeout); - k_work_cancel_delayable(&srv->pull.report); - io_close(srv); - erase_state(srv); - - if (srv->cb && srv->cb->end) { - srv->cb->end(srv, srv->state.xfer.id, true); - } -} - -static bool all_blocks_received(struct bt_mesh_blob_srv *srv) -{ - for (int i = 0; i < ARRAY_SIZE(srv->state.blocks); ++i) { - if (srv->state.blocks[i]) { - return false; - } - } - - return true; -} - -static bool pull_mode_xfer_complete(struct bt_mesh_blob_srv *srv) -{ - return srv->state.xfer.mode == BT_MESH_BLOB_XFER_MODE_PULL && - srv->phase == BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK && - all_blocks_received(srv); -} - static void timeout(struct k_work *work) { struct bt_mesh_blob_srv *srv = @@ -291,8 +260,6 @@ static void timeout(struct k_work *work) if (srv->phase == BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START) { cancel(srv); - } else if (pull_mode_xfer_complete(srv)) { - end(srv); } else { suspend(srv); } @@ -421,15 +388,6 @@ static int handle_xfer_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ct struct bt_mesh_blob_srv *srv = mod->user_data; LOG_DBG(""); - - if (pull_mode_xfer_complete(srv)) { - /* The client requested transfer. If we are in Pull mode and all blocks were - * received, we should change the Transfer state here to Complete so that the client - * receives the correct state. - */ - end(srv); - } - xfer_status_rsp(srv, ctx, BT_MESH_BLOB_SUCCESS); return 0; @@ -727,7 +685,7 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_blob_chunk chunk; size_t expected_size = 0; uint16_t idx; - int err; + int i, err; idx = net_buf_simple_pull_le16(buf); chunk.size = buf->len; @@ -787,26 +745,26 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, atomic_clear_bit(srv->state.blocks, srv->block.number); - if (!all_blocks_received(srv)) { + for (i = 0; i < ARRAY_SIZE(srv->state.blocks); ++i) { + if (!srv->state.blocks[i]) { + continue; + } + phase_set(srv, BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK); store_state(srv); return 0; } - if (srv->state.xfer.mode == BT_MESH_BLOB_XFER_MODE_PULL) { - /* By spec (section 5.2.4), the BLOB Server stops sending BLOB Partial Block Report - * messages "If the current block is the last block, then the server determines that - * the client knows the transfer is complete. For example, a higher-layer model may - * indicate that the client considers the transfer complete." - * - * We don't have any way for higher-layer model to indicate that the transfer is - * complete. Therefore we need to keep sending Partial Block Report messages until - * the client sends BLOB Transfer Get message or the Block Timer expires. - */ - return 0; + phase_set(srv, BT_MESH_BLOB_XFER_PHASE_COMPLETE); + k_work_cancel_delayable(&srv->rx_timeout); + k_work_cancel_delayable(&srv->pull.report); + io_close(srv); + erase_state(srv); + + if (srv->cb && srv->cb->end) { + srv->cb->end(srv, srv->state.xfer.id, true); } - end(srv); return 0; } From 479282b516db4cf20a6f07590b0107785a18790b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:46 +0000 Subject: [PATCH 4127/4498] Revert "[nrf fromlist] tests: bluetooth: tester: Fix BLOB server model pointer" This reverts commit d78ae6b7ad3e60ef3a63ad7b6e1ea8a01eb3f963. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 5eff344540e..c43f19f04ce 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -4468,10 +4468,10 @@ static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, struct model_data *model_bound; int err; -#if defined(CONFIG_BT_MESH_DFD_SRV) - struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; -#elif defined(CONFIG_BT_MESH_DFU_SRV) +#if defined(CONFIG_BT_MESH_DFU_SRV) struct bt_mesh_blob_srv *srv = &dfu_srv.blob; +#elif defined(CONFIG_BT_MESH_DFD_SRV) + struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; #endif model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); From 338c2b0fe0c67376f345e33cf963a43e7de23157 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:46 +0000 Subject: [PATCH 4128/4498] Revert "[nrf fromlist] manifest: update hal_nordic to fix nRF52820 nrfx_gpiote" This reverts commit 93c996c9b8653daee0e15d94ff81b8369d9efdeb. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 909800d0aab..f5366678a0e 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 427ee1a519e8a0844d0f78f7cbc8cdfc134ef00d + revision: 568a5e90b858a2e5b640b3fe6ab9b59dd2ce9f7f path: modules/hal/nordic groups: - hal From 5dac69c0d14a486cd99cc35a962df9fddf1cdbb8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:46 +0000 Subject: [PATCH 4129/4498] Revert "[nrf fromtree] dts: arm: nordic: Add support for ieee802154 in the nRF52820 radio" This reverts commit fc7f82d468f64955083d0e8ed307965020c70326. Signed-off-by: Dominik Ermel --- dts/arm/nordic/nrf52820.dtsi | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index c3d05fc6ec1..6d2f5eb02fe 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -88,15 +88,9 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; dfe-supported; - ieee802154-supported; ble-2mbps-supported; ble-coded-phy-supported; tx-high-power-supported; - - ieee802154: ieee802154 { - compatible = "nordic,nrf-ieee802154"; - status = "disabled"; - }; }; uart0: uart@40002000 { From 7f7ff88d584fbb8aa2667b0a754fbefba7de945b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:46 +0000 Subject: [PATCH 4130/4498] Revert "[nrf fromlist] modules: hal_nordic: cmake: Fix checking if uicr DT node is accessible" This reverts commit a0d7c03a96a5ed77ca937491207044d0e538ac38. Signed-off-by: Dominik Ermel --- modules/hal_nordic/nrfx/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index ca325c31770..e98db561906 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -116,7 +116,7 @@ endif() # doing the proper configuration sequence during system init dt_nodelabel(uicr_path NODELABEL "uicr") -if(DEFINED uicr_path) +if(${uicr_path}) dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") if(${nfct_pins_as_gpios}) zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) From 8a4a5f65eff3964f4dbdf8769a603267e2abda05 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:47 +0000 Subject: [PATCH 4131/4498] Revert "[nrf fromlist] tests: bluetooth: tester: add page number to response" This reverts commit ea44fcffcc107ced832752c7f8f91ffc559b8b56. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c43f19f04ce..1d6f696f729 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -2033,9 +2033,8 @@ static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - rp->data[0] = page; - memcpy(rp->data + 1, comp->data, comp->len); - *rsp_len = comp->len + 1; + memcpy(rp->data, comp->data, comp->len); + *rsp_len = comp->len; return BTP_STATUS_SUCCESS; } From 292aca50f662d5b57544787da0fc21a37a7958e4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:47 +0000 Subject: [PATCH 4132/4498] Revert "[nrf fromtree] Bluetooth: Mesh: improve solicitation debug logging" This reverts commit 52be85e04f3633e508156f79c8e13e87362c5a38. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/solicitation.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index e2100fa42db..f6543dcb320 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -190,14 +190,13 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_od_priv_proxy_get() == 0) { - LOG_DBG("Not soliciting"); return; } /* Get rid of ad_type that was checked in bt_mesh_scan_cb */ type = net_buf_simple_pull_u8(buf); if (type != BT_DATA_UUID16_SOME && type != BT_DATA_UUID16_ALL) { - LOG_DBG("Invalid type 0x%x, expected 0x%x or 0x%x", + LOG_ERR("Invalid type 0x%x, expected 0x%x or 0x%x", type, BT_DATA_UUID16_SOME, BT_DATA_UUID16_ALL); return; } @@ -216,7 +215,6 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (!sol_uuid_found) { - LOG_DBG("No solicitation UUID found"); return; } @@ -232,7 +230,6 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (buf->len <= reported_len - 3) { - LOG_DBG("Invalid length (%u) Solicitation PDU", buf->len); return; } @@ -240,13 +237,12 @@ void bt_mesh_sol_recv(struct net_buf_simple *buf, uint8_t uuid_list_len) } if (!svc_data_found) { - LOG_DBG("No solicitation service data found"); return; } type = net_buf_simple_pull_u8(buf); if (type != 0) { - LOG_DBG("Invalid type %d, expected 0x00", type); + LOG_ERR("Invalid type %d, expected 0x00", type); return; } From 3cdf9378c84d382729ce1f10fa2e51da2d6708fc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:47 +0000 Subject: [PATCH 4133/4498] Revert "[nrf fromtree] tests: bluetooth: tester: enable proxy solicitation" This reverts commit 7b5fbe1bc0b575d221003234f7772696fd9978cd. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 1 - tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf index 52045ce34df..978d1acd3df 100644 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ b/tests/bluetooth/tester/overlay-mesh-v1d1.conf @@ -23,7 +23,6 @@ CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_BT_MESH_PRIV_BEACONS=y CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y -CONFIG_BT_MESH_OD_PRIV_PROXY_SRV=y CONFIG_BT_MESH_MODEL_EXTENSIONS=y CONFIG_BT_MESH_COMP_PAGE_1=y CONFIG_BT_MESH_COMP_PAGE_2=y diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 1d6f696f729..81c41dca708 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -5081,7 +5081,7 @@ static const struct btp_handler handlers[] = { .func = srpl_clear }, #endif -#if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) +#if defined(CONFIG_BT_MESH_SOLICITATION) { .opcode = BTP_MESH_PROXY_SOLICIT, .expect_len = sizeof(struct btp_proxy_solicit_cmd), From 13ef034a85b5c3f50efdeb1faab939bce1218d65 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:47 +0000 Subject: [PATCH 4134/4498] Revert "[nrf fromtree] Bluetooth: Mesh: fix proxy solicitation" This reverts commit 5fed002128563c138ff679fdb35ac1b4f9ecb064. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/uuid.h | 2 +- subsys/bluetooth/mesh/crypto.c | 2 +- subsys/bluetooth/mesh/proxy_srv.c | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/zephyr/bluetooth/uuid.h b/include/zephyr/bluetooth/uuid.h index cab12eac74b..1fa8ece6466 100644 --- a/include/zephyr/bluetooth/uuid.h +++ b/include/zephyr/bluetooth/uuid.h @@ -587,7 +587,7 @@ struct bt_uuid_128 { /** * @brief Proxy Solicitation UUID value */ -#define BT_UUID_MESH_PROXY_SOLICITATION_VAL 0x1859 +#define BT_UUID_MESH_PROXY_SOLICITATION_VAL 0x7fcb /** * @brief Reconnection Configuration Service UUID value */ diff --git a/subsys/bluetooth/mesh/crypto.c b/subsys/bluetooth/mesh/crypto.c index b79458f7ea2..e42717475c0 100644 --- a/subsys/bluetooth/mesh/crypto.c +++ b/subsys/bluetooth/mesh/crypto.c @@ -419,7 +419,7 @@ int bt_mesh_net_decrypt(const struct bt_mesh_key *key, struct net_buf_simple *bu if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && type == BT_MESH_NONCE_PROXY) { create_proxy_nonce(nonce, buf->data, iv_index); - } else if (IS_ENABLED(CONFIG_BT_MESH_SOLICITATION) && + } else if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && type == BT_MESH_NONCE_SOLICITATION) { create_proxy_sol_nonce(nonce, buf->data); } else { diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 12775b93651..62c46582fa0 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -698,11 +698,9 @@ static void gatt_proxy_solicited(struct bt_mesh_subnet *sub) if (sub->priv_net_id_sent > 0) { timeout = sub->priv_net_id_sent + MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); - remaining = MIN(timeout - now, INT32_MAX); - } else { - remaining = MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); } + remaining = MIN(timeout - now, INT32_MAX); if ((timeout > 0 && now > timeout) || (remaining / MSEC_PER_SEC < 1)) { LOG_DBG("Advertising Private Network ID timed out " "after solicitation"); From ab472d62eee5ed9c52e4412a63b22b216603fdb5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:47 +0000 Subject: [PATCH 4135/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix failing DFU/SR/FD/BV-08-C test" This reverts commit a17674613fd86db048183888dc1f55f1b72875f2. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 0a9ecba6cec..d225f67bb77 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -412,20 +412,12 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms case -EFBIG: /* Fwid too long */ case -EALREADY: /* Other server is in progress with this fwid */ bt_mesh_dfu_slot_release(srv->upload.slot); - srv->upload.slot = NULL; upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); break; case -EEXIST: /* Img with this fwid already is in list */ srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; bt_mesh_dfu_slot_release(srv->upload.slot); - - err = bt_mesh_dfu_slot_get(fwid, fwid_len, &srv->upload.slot); - if (!err) { - upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); - } else { - srv->upload.slot = NULL; - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); - } + upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); break; case 0: srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; From a42960ee2972fe1e7a445689a429d59e07c58c85 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:48 +0000 Subject: [PATCH 4136/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Capabilities Status message with OOB upload enabled" This reverts commit 1fc4225e4d05cc510aef22d8b69b918f559533f4. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index d225f67bb77..2547c07a5b4 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -233,10 +233,11 @@ static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg net_buf_simple_add_mem(&rsp, srv->oob_schemes.schemes, srv->oob_schemes.count); } else -#endif +#else { net_buf_simple_add_u8(&rsp, 0); } +#endif bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL); From 3719292ec85c0e93c15a9b05c7556bd2b9ba13dd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:48 +0000 Subject: [PATCH 4137/4498] Revert "[nrf fromlist] manifest: update hal_nordic rev to fix nRF91 anomaly 7" This reverts commit 6c895c5d3ee5b98453112f1855a646624211c68c. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f5366678a0e..bed3b47cfe5 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 568a5e90b858a2e5b640b3fe6ab9b59dd2ce9f7f + revision: 092eb78ed1b1551d8f480019b9c05d7371784578 path: modules/hal/nordic groups: - hal From 1ab6c6feead2b3e66ace284d04e73eeeb86b0273 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:48 +0000 Subject: [PATCH 4138/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Print URI and FWID in Upload OOB Start msg" This reverts commit e5ab2f9978ecfdde887735f5e59d28912a5ddb4d. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 2547c07a5b4..cfcc82eb8d1 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -572,10 +572,6 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg fwid_len = buf->len; fwid = net_buf_simple_pull_mem(buf, fwid_len); - LOG_DBG("Upload OOB Start"); - LOG_HEXDUMP_DBG(uri, uri_len, "URI"); - LOG_HEXDUMP_DBG(fwid, fwid_len, "FWID"); - if (upload_is_busy(srv)) { #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD if (srv->upload.is_oob && From 53fd91da8c930af458d52cab93e7ccee894d7fad Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:48 +0000 Subject: [PATCH 4139/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Add Upload OOB support for mesh tester" This reverts commit 5640e9e33ab1bfaca4ed341b0d752518ed181de2. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 119 -------------------------- 1 file changed, 119 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 81c41dca708..662dca238c1 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -162,132 +162,13 @@ static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, return 0; } -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD -static struct { - uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; - uint8_t uri_len; - uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; - uint8_t fwid_len; - const struct bt_mesh_dfu_slot *slot; - uint8_t progress; - bool started; -} dfd_srv_oob_ctx; - -static void oob_check_handler(struct k_work *work); -static K_WORK_DEFINE(oob_check, oob_check_handler); -static void oob_store_handler(struct k_work *work); -static K_WORK_DEFINE(oob_store, oob_store_handler); - -static int dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, - const char *uri, uint8_t uri_len, - const uint8_t *fwid, uint16_t fwid_len) -{ - LOG_DBG("Start OOB Upload"); - - memcpy(dfd_srv_oob_ctx.uri, uri, uri_len); - dfd_srv_oob_ctx.uri_len = uri_len; - memcpy(dfd_srv_oob_ctx.fwid, fwid, fwid_len); - dfd_srv_oob_ctx.fwid_len = fwid_len; - dfd_srv_oob_ctx.slot = slot; - dfd_srv_oob_ctx.progress = 0; - dfd_srv_oob_ctx.started = true; - - k_work_submit(&oob_check); - - return BT_MESH_DFD_SUCCESS; -} - -static void dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot) -{ - LOG_DBG("Cancel OOB Upload"); - - dfd_srv_oob_ctx.started = false; -} - -static uint8_t dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot) -{ - uint8_t progress; - - if (dfd_srv_oob_ctx.started) { - progress = dfd_srv_oob_ctx.progress; - - dfd_srv_oob_ctx.progress = MIN(dfd_srv_oob_ctx.progress + 25, 99); - - if (dfd_srv_oob_ctx.progress == 99) { - k_work_submit(&oob_store); - } - } else { - progress = 0; - } - - LOG_DBG("OOB Progress Get (%sstarted: %d %%)", dfd_srv_oob_ctx.started ? "" : "not ", - progress); - return progress; -} -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ - static struct bt_mesh_dfd_srv_cb dfd_srv_cb = { .recv = dfd_srv_recv, .del = dfd_srv_del, .send = dfd_srv_send, -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - .start_oob_upload = dfd_srv_start_oob_upload, - .cancel_oob_upload = dfd_srv_cancel_oob_upload, - .oob_progress_get = dfd_srv_oob_progress_get, -#endif }; static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb); - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD -#define SUPPORTED_SCHEME "http" - -static void oob_check_handler(struct k_work *work) -{ - uint8_t scheme[10]; - int i; - int status; - int err; - - for (i = 0; i < MIN(dfd_srv_oob_ctx.uri_len, sizeof(scheme)); i++) { - if (IN_RANGE(dfd_srv_oob_ctx.uri[i], 48, 57) || /* DIGIT */ - IN_RANGE(dfd_srv_oob_ctx.uri[i], 65, 90) || /* ALPHA UPPER CASE */ - IN_RANGE(dfd_srv_oob_ctx.uri[i], 97, 122) || /* ALPHA LOWER CASE */ - dfd_srv_oob_ctx.uri[i] == '.' || - dfd_srv_oob_ctx.uri[i] == '+' || - dfd_srv_oob_ctx.uri[i] == '-') { - scheme[i] = dfd_srv_oob_ctx.uri[i]; - } else { - break; - } - } - - if (i == dfd_srv_oob_ctx.uri_len || dfd_srv_oob_ctx.uri[i] != ':') { - status = BT_MESH_DFD_ERR_URI_MALFORMED; - } else if (i != strlen(SUPPORTED_SCHEME) || - memcmp(scheme, SUPPORTED_SCHEME, strlen(SUPPORTED_SCHEME))) { - status = BT_MESH_DFD_ERR_URI_NOT_SUPPORTED; - } else { - status = BT_MESH_DFD_SUCCESS; - } - - err = bt_mesh_dfd_srv_oob_check_complete(&dfd_srv, dfd_srv_oob_ctx.slot, status, - dfd_srv_oob_ctx.fwid, dfd_srv_oob_ctx.fwid_len); - LOG_DBG("OOB check completed (err %d)", err); -} - -static void oob_store_handler(struct k_work *work) -{ - int err; - - err = bt_mesh_dfd_srv_oob_store_complete(&dfd_srv, dfd_srv_oob_ctx.slot, true, - 10000, "metadata", 8); - LOG_DBG("OOB store completed (err %d)", err); -} -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ #endif #if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) From 6c3bea1bf35369fa39339ec575cded547761cfed Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:49 +0000 Subject: [PATCH 4140/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Release previously reserved slot before reserving again" This reverts commit c97f38205f50eceac6b66359799e19df5b6aeb28. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index cfcc82eb8d1..f8dfaf0b97f 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -607,13 +607,6 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg return 0; } - /* This will be a no-op if the slot state isn't RESERVED, which is - * what we want. - */ - if (srv->upload.slot) { - bt_mesh_dfu_slot_release(srv->upload.slot); - } - srv->upload.is_oob = true; srv->upload.slot = slot; memcpy(srv->upload.oob.uri, uri, uri_len); From bfa9e4f7f84f58af8c7eb53f2bb8cb804747c102 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:49 +0000 Subject: [PATCH 4141/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Ignore duplicate OOB upload request" This reverts commit a2744d2bdee2459cd9dd0ebec788a99d82b02f7b. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/mesh/dfd_srv.h | 1 - subsys/bluetooth/mesh/dfd_srv.c | 12 +----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/dfd_srv.h b/include/zephyr/bluetooth/mesh/dfd_srv.h index 666e0d8ad3d..da339c57ec6 100644 --- a/include/zephyr/bluetooth/mesh/dfd_srv.h +++ b/include/zephyr/bluetooth/mesh/dfd_srv.h @@ -228,7 +228,6 @@ struct bt_mesh_dfd_srv { struct bt_mesh_blob_srv blob; #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD bool is_oob; - bool is_pending_oob_check; struct { uint8_t uri_len; uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index f8dfaf0b97f..f060e263ace 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -586,11 +586,6 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg #endif upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD); return 0; -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - } else if (srv->upload.is_oob && srv->upload.is_pending_oob_check) { - /* Ignore the request if we didn't confirm the previous one. */ - return 0; -#endif } #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD @@ -623,8 +618,6 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg if (status != BT_MESH_DFD_SUCCESS) { upload_status_rsp(srv, ctx, status); bt_mesh_dfu_slot_release(srv->upload.slot); - } else { - srv->upload.is_pending_oob_check = true; } #else upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_URI_NOT_SUPPORTED); @@ -1218,16 +1211,13 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, int err; if (slot != srv->upload.slot || !srv->upload.is_oob || - srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE || - !srv->upload.is_pending_oob_check) { + srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) { /* This should not happen, unless the application calls the function with a * "wrong" pointer or at a wrong time. */ return -EINVAL; } - srv->upload.is_pending_oob_check = false; - if (status != BT_MESH_DFD_SUCCESS) { bt_mesh_dfu_slot_release(srv->upload.slot); upload_status_rsp(srv, &srv->upload.oob.ctx, status); From 8266925385206874d57d67a9e9bde2f842f32fde Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:49 +0000 Subject: [PATCH 4142/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Fw Dist Upload OOB Start msg length check" This reverts commit 4491262ebf889bf6bcb1ff2aed0c504a9f3cb17a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index f060e263ace..a67a3a778ca 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -761,7 +761,7 @@ const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[] = { { BT_MESH_DFD_OP_APPLY, BT_MESH_LEN_EXACT(0), handle_apply }, { BT_MESH_DFD_OP_UPLOAD_GET, BT_MESH_LEN_EXACT(0), handle_upload_get }, { BT_MESH_DFD_OP_UPLOAD_START, BT_MESH_LEN_MIN(16), handle_upload_start }, - { BT_MESH_DFD_OP_UPLOAD_START_OOB, BT_MESH_LEN_MIN(2), handle_upload_start_oob }, + { BT_MESH_DFD_OP_UPLOAD_START_OOB, BT_MESH_LEN_EXACT(2), handle_upload_start_oob }, { BT_MESH_DFD_OP_UPLOAD_CANCEL, BT_MESH_LEN_EXACT(0), handle_upload_cancel }, { BT_MESH_DFD_OP_FW_GET, BT_MESH_LEN_MIN(0), handle_fw_get }, { BT_MESH_DFD_OP_FW_GET_BY_INDEX, BT_MESH_LEN_EXACT(2), handle_fw_get_by_index }, From 32374909565a7901bf6760e953e02b511315f9c4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:49 +0000 Subject: [PATCH 4143/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Upload Progress for already received fw" This reverts commit 74bdabf7e57a988ad740da44398cf93f7d5e0c79. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index a67a3a778ca..5d3ada4b4aa 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -342,10 +342,9 @@ static int handle_apply(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, return 0; } -static void upload_status_rsp_with_progress(struct bt_mesh_dfd_srv *srv, - struct bt_mesh_msg_ctx *ctx, - enum bt_mesh_dfd_status status, - uint8_t progress) +static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, + struct bt_mesh_msg_ctx *ctx, + enum bt_mesh_dfd_status status) { BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_UPLOAD_STATUS, DFD_UPLOAD_STATUS_MSG_MAXLEN); @@ -362,13 +361,14 @@ static void upload_status_rsp_with_progress(struct bt_mesh_dfd_srv *srv, #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD if (srv->upload.is_oob) { - net_buf_simple_add_u8(&rsp, progress | BIT(7)); + net_buf_simple_add_u8(&rsp, + srv->cb->oob_progress_get(srv, srv->upload.slot) | BIT(7)); net_buf_simple_add_mem(&rsp, srv->upload.oob.current_fwid, srv->upload.oob.current_fwid_len); } else #endif { - net_buf_simple_add_u8(&rsp, progress); + net_buf_simple_add_u8(&rsp, bt_mesh_blob_srv_progress(&srv->upload.blob)); net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, srv->upload.slot->fwid_len); } @@ -376,24 +376,6 @@ static void upload_status_rsp_with_progress(struct bt_mesh_dfd_srv *srv, bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } -static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, - struct bt_mesh_msg_ctx *ctx, - enum bt_mesh_dfd_status status) -{ - uint8_t progress; - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - if (srv->upload.is_oob) { - progress = srv->cb->oob_progress_get(srv, srv->upload.slot); - } else -#endif - { - progress = bt_mesh_blob_srv_progress(&srv->upload.blob); - } - - upload_status_rsp_with_progress(srv, ctx, status, progress); -} - static int handle_upload_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -418,7 +400,7 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms case -EEXIST: /* Img with this fwid already is in list */ srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100); + upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); break; case 0: srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; From be050cfb258b3df56acd11dac414630101f1314a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:50 +0000 Subject: [PATCH 4144/4498] Revert "[nrf fromtree] bluetooth: common: Kconfig: Add missing dependency for BT_MONITOR" This reverts commit 7e3e8dea4ba07c5730b6d037ba50ddede860bc1b. Signed-off-by: Dominik Ermel --- subsys/bluetooth/common/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index bf4aee75e48..d72ce90afa6 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -282,7 +282,6 @@ endif # BT_ASSERT config BT_MONITOR bool - select LOG_OUTPUT choice BT_DEBUG_TYPE prompt "Bluetooth debug type" From ce5d78f17a4ff51f9c730d668256142d65b78734 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:50 +0000 Subject: [PATCH 4145/4498] Revert "[nrf fromtree] tests: kernel: timer: jitter_drift: Restore initial alignment to tick" This reverts commit a4670ff4eabc3517bda2bc34b25b97e2159c33dd. Signed-off-by: Dominik Ermel --- tests/kernel/timer/timer_behavior/src/jitter_drift.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/kernel/timer/timer_behavior/src/jitter_drift.c b/tests/kernel/timer/timer_behavior/src/jitter_drift.c index 6d3e78d514b..cd6afaea00d 100644 --- a/tests/kernel/timer/timer_behavior/src/jitter_drift.c +++ b/tests/kernel/timer/timer_behavior/src/jitter_drift.c @@ -121,17 +121,6 @@ static void do_test_using(void (*sample_collection_fn)(void)) periodic_idx = 0; k_sem_init(&periodic_sem, 0, 1); - - /* Align to tick boundary. Otherwise the first handler execution - * might turn out to be significantly late and cause the test to - * fail. This can happen if k_timer_start() is called right before - * the upcoming tick boundary and in consequence the tick passes - * between the moment when the kernel decides what tick to use for - * the next timeout and the moment when the system timer actually - * sets up that timeout. - */ - k_sleep(K_TICKS(1)); - sample_collection_fn(); k_sem_take(&periodic_sem, K_FOREVER); From 8149a838c2ad4d1c980938110217d9078d4024cf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:50 +0000 Subject: [PATCH 4146/4498] Revert "[nrf fromtree] drivers: spi_nrfx_spis: Handle empty spi_buf_set structures properly" This reverts commit 495c47634d7c2105b7dd21734ef4a87eb25ea932. Signed-off-by: Dominik Ermel --- drivers/spi/spi_nrfx_spis.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index d2a61530f00..6ba36a139a0 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -170,8 +170,6 @@ static int transceive(const struct device *dev, { struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; - const struct spi_buf *tx_buf = tx_bufs ? tx_bufs->buffers : NULL; - const struct spi_buf *rx_buf = rx_bufs ? rx_bufs->buffers : NULL; int error; spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); @@ -183,7 +181,8 @@ static int transceive(const struct device *dev, (rx_bufs && rx_bufs->count > 1)) { LOG_ERR("Scattered buffers are not supported"); error = -ENOTSUP; - } else if (tx_buf && tx_buf->len && !nrfx_is_in_ram(tx_buf->buf)) { + } else if (tx_bufs && tx_bufs->buffers[0].len && + !nrfx_is_in_ram(tx_bufs->buffers[0].buf)) { LOG_ERR("Only buffers located in RAM are supported"); error = -ENOTSUP; } else { @@ -194,10 +193,10 @@ static int transceive(const struct device *dev, } error = prepare_for_transfer(dev, - tx_buf ? tx_buf->buf : NULL, - tx_buf ? tx_buf->len : 0, - rx_buf ? rx_buf->buf : NULL, - rx_buf ? rx_buf->len : 0); + tx_bufs ? tx_bufs->buffers[0].buf : NULL, + tx_bufs ? tx_bufs->buffers[0].len : 0, + rx_bufs ? rx_bufs->buffers[0].buf : NULL, + rx_bufs ? rx_bufs->buffers[0].len : 0); if (error == 0) { if (dev_config->wake_gpio.port) { /* Set the WAKE line low (tie it to ground) From a4d563dbfa43b58217a4ead6f31b4df2bc90e382 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:50 +0000 Subject: [PATCH 4147/4498] Revert "[nrf fromlist] nrf5340: pretick decoupled from workaround anomaly 160" This reverts commit 009e4d56688790dce25ab360d5add0ef44e92bd5. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 - soc/arm/nordic_nrf/nrf53/soc.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 2cd934af324..87d961d6fb3 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -53,7 +53,6 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND config SOC_NRF53_RTC_PRETICK bool "Pre-tick workaround for nRF5340 anomaly 165" - depends on (SYS_CLOCK_EXISTS && SOC_NRF5340_CPUNET) || SOC_NRF5340_CPUAPP select NRFX_DPPI select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 39d64d72cc2..396ce79f49e 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -133,7 +133,6 @@ static bool nrf53_anomaly_160_check(void) return true; } -#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ #if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) @@ -338,8 +337,6 @@ void z_arm_on_enter_cpu_idle_prepare(void) } #endif /* CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET */ -#if defined(CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND) || \ - (defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET)) bool z_arm_on_enter_cpu_idle(void) { bool ok_to_sleep = true; @@ -360,7 +357,6 @@ bool z_arm_on_enter_cpu_idle(void) } #endif -#if defined(CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND) if (ok_to_sleep) { ok_to_sleep = nrf53_anomaly_160_check(); @@ -375,7 +371,6 @@ bool z_arm_on_enter_cpu_idle(void) } #endif } -#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ #if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) if (!ok_to_sleep) { @@ -387,9 +382,7 @@ bool z_arm_on_enter_cpu_idle(void) return ok_to_sleep; } -#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND || - * (CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET) - */ +#endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ #if CONFIG_SOC_NRF53_RTC_PRETICK #ifdef CONFIG_SOC_NRF5340_CPUAPP From 7b288e716ae07f1fb9d5c7d273c43d1b41880488 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:51 +0000 Subject: [PATCH 4148/4498] Revert "[nrf fromlist] nrf53: fix RTC pretick for RTC rescheduling by other interrupts" This reverts commit fd1e8cfb37ef151b5421694bfde6857a8db18255. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 6 +----- soc/arm/nordic_nrf/nrf53/soc.c | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 87d961d6fb3..87d8a6d0c7a 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -58,11 +58,7 @@ config SOC_NRF53_RTC_PRETICK select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET help Indicates that the pre-tick workaround for the anomaly 165 that affects - the nRF5340 SoC should be applied. The workaround applies to wake ups caused - by EVENTS_COMPARE and EVENTS_OVRFLW on RTC0 and RTC1 for which interrupts are - enabled through INTENSET register. The case when these events are generated - by EVTEN but without interrupts enabled through INTENSET is not handled. - The EVENTS_TICK event is not handled. + the nRF5340 SoC should be applied. if SOC_NRF53_RTC_PRETICK diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 396ce79f49e..c18228ac4fa 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -224,15 +224,6 @@ static bool cpu_idle_prepare_monitor_end(void) return __STREXB(0U, &cpu_idle_prepare_monitor_dummy); } -static void rtc_pretick_finish_previous(void) -{ - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= - ~IPC_PUBLISH_RECEIVE_EN_Msk; - - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); -} - - void z_arm_on_enter_cpu_idle_prepare(void) { bool ok_to_sleep = true; @@ -272,7 +263,6 @@ void z_arm_on_enter_cpu_idle_prepare(void) if (rtc_pretick_cc_val != nrf_rtc_cc_get(NRF_RTC1, RTC1_PRETICK_CC_CHAN)) { /* The CC for pretick needs to be updated. */ - rtc_pretick_finish_previous(); nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, rtc_pretick_cc_val); if (rtc_ticks_to_next_event >= NRF_RTC_COUNTER_MAX/2) { @@ -416,14 +406,22 @@ static int rtc_pretick_cpuapp_init(void) } #else /* CONFIG_SOC_NRF5340_CPUNET */ +static void rtc_pretick_rtc_isr_hook(void) +{ + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= + ~IPC_PUBLISH_RECEIVE_EN_Msk; + + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); +} + void rtc_pretick_rtc0_isr_hook(void) { - rtc_pretick_finish_previous(); + rtc_pretick_rtc_isr_hook(); } void rtc_pretick_rtc1_isr_hook(void) { - rtc_pretick_finish_previous(); + rtc_pretick_rtc_isr_hook(); } static int rtc_pretick_cpunet_init(void) From 0a4cc7cd79755e77725b94b16eb1246f6c813167 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:51 +0000 Subject: [PATCH 4149/4498] Revert "[nrf fromtree] tests: bluetooth: controller: Included kconfigs for ISO-AL logging" This reverts commit d03d84372b9ee34a6d22066899041c0da203d168. Signed-off-by: Dominik Ermel --- tests/bluetooth/ctrl_isoal/Kconfig | 19 ------------------- tests/bluetooth/ctrl_isoal/prj.conf | 2 -- 2 files changed, 21 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/Kconfig b/tests/bluetooth/ctrl_isoal/Kconfig index 30049d53a5e..b7c10723b93 100644 --- a/tests/bluetooth/ctrl_isoal/Kconfig +++ b/tests/bluetooth/ctrl_isoal/Kconfig @@ -12,25 +12,6 @@ config BT_CTLR_CONN_ISO_GROUPS range 1 240 default 1 -config BT_CTLR_DEBUG_ISOAL - bool "[DEPRECATED] Bluetooth ISO-AL debug" - select DEPRECATED - depends on BT_CTLR_ISO - help - This option enables debug support for the Bluetooth ISO-AL. - -module = BT_CTLR_ISOAL -legacy-debug-sym = BT_CTLR_DEBUG_ISOAL -module-str = "Bluetooth Controller ISO-AL" -source "subsys/bluetooth/common/Kconfig.template.log_config_bt" - -config BT_CTLR_ISOAL_LOG_DBG_VERBOSE - bool "ISO-AL verbose debug logging" - depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 - default n - help - Use this option to enable ISO-AL verbose debug logging. - config BT_CTLR_ISOAL_SINKS int "Number of Isochronous Adaptation Layer sinks (for unit tests)" diff --git a/tests/bluetooth/ctrl_isoal/prj.conf b/tests/bluetooth/ctrl_isoal/prj.conf index 2f429dd8c47..5009e2785f8 100644 --- a/tests/bluetooth/ctrl_isoal/prj.conf +++ b/tests/bluetooth/ctrl_isoal/prj.conf @@ -9,5 +9,3 @@ CONFIG_BT_CTLR_CONN_ISO=y CONFIG_BT_CTLR_ISOAL_SINKS=4 CONFIG_BT_CTLR_ISOAL_SOURCES=4 CONFIG_BT_CTLR_ISO_RX_SDU_BUFFERS=4 - -CONFIG_BT_CTLR_ISOAL_LOG_LEVEL_INF=y From 4e4eb70451877f1251490e4f364532e54ab238dc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:51 +0000 Subject: [PATCH 4150/4498] Revert "[nrf fromtree] tests: bluetooth: controller: Updated ISO-AL tests for length of err PDU" This reverts commit d1b4bbfe99dd4cf897c9d72d830ea99a894bc48c. Signed-off-by: Dominik Ermel --- .../ctrl_isoal/src/sub_sets/isoal_test_rx.c | 115 ++++++++++-------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c index fdb86af1f5c..5a3c60e0854 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c @@ -60,19 +60,19 @@ static isoal_status_t custom_sink_sdu_alloc_test(const struct isoal_sink *sink_c #define ZASSERT_ISOAL_SDU_ALLOC_TEST(_typ, _sink, _pdu) \ zassert_equal_ptr(_sink, \ sink_sdu_alloc_test_fake.arg0_##_typ, \ - "\t\tExpected alloc sink at %p, got %p.", \ + "\t\t%p != %p", \ _sink, \ sink_sdu_alloc_test_fake.arg0_##_typ); \ zassert_equal_ptr(_pdu, \ sink_sdu_alloc_test_fake.arg1_##_typ, \ - "\t\tExpected alloc PDU buffer at %p, got %p.", \ + "\t\t%p != %p", \ _pdu, \ sink_sdu_alloc_test_fake.arg1_##_typ) #define ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_alloc_test_fake.call_count, \ - "Expected alloc called %u times, actual %u.", \ + "Expected %u got %u", \ _expected, \ sink_sdu_alloc_test_fake.call_count) @@ -125,59 +125,59 @@ static isoal_status_t custom_sink_sdu_emit_test(const struct isoal_sink *sink_ct _sdu_status) \ zassert_equal_ptr(_sink, \ sink_sdu_emit_test_fake.arg0_##_typ, \ - "\t\tExpected sink at %p, got %p.", \ + "\t\t%p != %p", \ _sink, \ sink_sdu_emit_test_fake.arg0_##_typ); \ zassert_equal(_state, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state, \ - "\t\tExpected SDU state '%s', got '%s'.", \ - STATE_TO_STR(_state), \ - STATE_TO_STR(sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state)); \ + "\t\t%d != %d", \ + _state, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_state); \ zassert_equal(_frag_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_frag_size, \ - "\t\tExpected SDU frag of size %u, got %u.", \ + "\t\t%d != %d", \ _frag_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu_frag_size); \ zassert_equal(_frag_status, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status, \ - "\t\tExpected SDU with status '%s', got '%s'.", \ - DU_ERR_TO_STR(_frag_status), \ - DU_ERR_TO_STR(sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status)); \ + "\t\t%d != %d", \ + _frag_status, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.status); \ zassert_equal(_timestamp, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.timestamp, \ - "\t\tExpected SDU with timestamp %u, got %u.", \ + "\t\t%d != %d", \ _timestamp, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.timestamp); \ zassert_equal(_sn, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.sn, \ - "\t\tExpected SDU with sequence number %u, got %u.", \ + "\t\t%d != %d", \ _sn, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.sn); \ - zassert_equal_ptr(_dbuf, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf, \ - "\t\tExpected SDU data buffer at %p, got %p.", \ - _dbuf, \ - sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf); \ + zassert_equal(_dbuf, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf, \ + "\t\t%p != %p", \ + _dbuf, \ + sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.dbuf); \ zassert_equal(_dbuf_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.size, \ - "\t\tExpected SDU data buffer of size %u, got %u.", \ + "\t\t%d != %d", \ _dbuf_sz, \ sink_sdu_emit_test_handler_fake.arg1_##_typ.sdu.contents.size); \ zassert_equal(_total_sz, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.total_sdu_size, \ - "\t\tExpected total size of SDU %u,got %u.", \ + "\t\t%d != %d", \ _total_sz, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.total_sdu_size); \ zassert_equal(_sdu_status, \ sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status, \ - "\t\tExpected SDU with status '%s', got '%s'.", \ - DU_ERR_TO_STR(_sdu_status), \ - DU_ERR_TO_STR(sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status)) + "\t\t%d != %d", \ + _sdu_status, \ + sink_sdu_emit_test_handler_fake.arg2_##_typ.collated_status) #define ZASSERT_ISOAL_SDU_EMIT_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_emit_test_fake.call_count, \ - "Expected emit called %u times, actual %u.", \ + "Expected %u got %u", \ _expected, \ sink_sdu_emit_test_fake.call_count) @@ -212,24 +212,24 @@ custom_sink_sdu_write_test(void *dbuf, const uint8_t *pdu_payload, const size_t #define ZASSERT_ISOAL_SDU_WRITE_TEST(_typ, _frag_buf, _payload_buf, _length) \ zassert_equal_ptr(_frag_buf, \ sink_sdu_write_test_fake.arg0_##_typ, \ - "\t\tExpected write buffer at %p, got %p.", \ + "\t\t%p != %p", \ _frag_buf, \ sink_sdu_write_test_fake.arg0_##_typ); \ zassert_equal_ptr(_payload_buf, \ sink_sdu_write_test_fake.arg1_##_typ, \ - "\t\tExpected write source at %p, got %p.", \ + "\t\t%p != %p", \ _payload_buf, \ sink_sdu_write_test_fake.arg1_##_typ); \ zassert_equal(_length, \ sink_sdu_write_test_fake.arg2_##_typ, \ - "\t\tExpected write length of %u, got %u.", \ + "\t\t%d != %d", \ _length, \ sink_sdu_write_test_fake.arg2_##_typ) #define ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ sink_sdu_write_test_fake.call_count, \ - "Expected write called %u times, actual %u.", \ + "Expected %u got %u", \ _expected, \ sink_sdu_write_test_fake.call_count) @@ -2767,7 +2767,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) seqn = 0; testdata_indx = 0; testdata_size = 13; - sdu_size = 0; + sdu_size = 13; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -2804,9 +2804,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); - + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -2836,6 +2838,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency); testdata_indx = testdata_size; testdata_size += 10; + sdu_size = 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -2863,9 +2866,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_single_pdu_err) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); - + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -3234,6 +3239,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err1) payload_number++; testdata_indx = testdata_size; testdata_size += 10; + sdu_size += 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -3257,11 +3263,12 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err1) /* Test recombine (Black Box) */ /* A new SDU should not be allocated */ - ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(1); - - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -3528,7 +3535,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err2) payload_number++; testdata_indx = testdata_size; testdata_size += 10; - sdu_size = 0; + sdu_size = 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, 50); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); @@ -3558,9 +3565,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_seq_pdu_err2) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); - + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -4560,7 +4569,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_padding_error1) seqn = 0; testdata_indx = 0; testdata_size = 13; - sdu_size = 0; + sdu_size = 13; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -4598,9 +4607,11 @@ ZTEST(test_rx_unframed, test_rx_unframed_padding_error1) &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); - + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ @@ -5924,6 +5935,7 @@ ZTEST(test_rx_unframed, test_rx_unframed_dbl_pdu_invalid_llid2_pdu_err) payload_number++; testdata_indx = testdata_size; testdata_size += 10; + sdu_size += 10; total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_ERRORS, ISOAL_SDU_STATUS_ERRORS); @@ -5946,11 +5958,12 @@ ZTEST(test_rx_unframed, test_rx_unframed_dbl_pdu_invalid_llid2_pdu_err) /* Test recombine (Black Box) */ /* A new SDU should not be allocated */ - ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(1); - - /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); + /* SDU payload should be written */ + ZASSERT_ISOAL_SDU_WRITE_TEST(val, + &rx_sdu_frag_buf, /* SDU buffer */ + &rx_pdu_meta_buf.pdu[3], /* PDU payload */ + (testdata_size - testdata_indx)); /* Size */ /* SDU should be emitted */ ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ From ef1bb63de84032669397619216bb4538edc4e3e3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:51 +0000 Subject: [PATCH 4151/4498] Revert "[nrf fromtree] tests: bluetooth: controller: ISO-AL selection of TX time stamps" This reverts commit cd59d4f291540089700dc1c04e7dd82f8de345a5. Signed-off-by: Dominik Ermel --- .../ctrl_isoal/src/isoal_test_debug.c | 1 - tests/bluetooth/ctrl_isoal/src/main.c | 2 +- .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 540 +----------------- 3 files changed, 3 insertions(+), 540 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c index 084677cf462..734af1ad7c0 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c @@ -233,7 +233,6 @@ void isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx *tx_sdu) PRINT("%02x ", buf[i]); } PRINT("\n"); - PRINT("Cntr TS. <%10u>\n", tx_sdu->cntr_time_stamp); PRINT(" Ref. <%10u>\n", tx_sdu->grp_ref_point); PRINT(" Event <%10u>\n", (uint32_t)tx_sdu->target_event); PRINT("\n"); diff --git a/tests/bluetooth/ctrl_isoal/src/main.c b/tests/bluetooth/ctrl_isoal/src/main.c index 8cbd36c509a..08175eab153 100644 --- a/tests/bluetooth/ctrl_isoal/src/main.c +++ b/tests/bluetooth/ctrl_isoal/src/main.c @@ -37,7 +37,7 @@ DEFINE_FFF_GLOBALS; ZTEST_SUITE(test_rx_basics, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); ZTEST_SUITE(test_rx_unframed, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); -ZTEST_SUITE(test_rx_framed, NULL, NULL, isoal_test_rx_common_before, NULL, NULL); +ZTEST_SUITE(test_rx_framed, NULL, NULL, NULL, isoal_test_rx_common_before, NULL); ZTEST_SUITE(test_tx_basics, NULL, NULL, isoal_test_tx_common_before, NULL, NULL); ZTEST_SUITE(test_tx_unframed, NULL, NULL, isoal_test_tx_common_before, NULL, NULL); diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index c9a6fe67637..3f57d8bccbc 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -195,14 +195,14 @@ static isoal_status_t custom_source_pdu_write_test(struct isoal_pdu_buffer *pdu_ _consume_len, \ source_pdu_write_test_fake.arg3_##_typ); \ check_next_custom_source_pdu_write_test_sdu_payload((const uint8_t *)_sdu_payload, \ - _consume_len, __LINE__) + _consume_len, __LINE__); #define ZASSERT_PDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ source_pdu_write_test_fake.call_count, \ "Expected %u, got %u", \ _expected, \ - source_pdu_write_test_fake.call_count) + source_pdu_write_test_fake.call_count); /*------------------ PDU Emit Callback --------------------------------------*/ /** @@ -480,7 +480,6 @@ static void isoal_test_create_sdu_fagment(uint8_t sdu_state, uint16_t sdu_total_length, uint16_t packet_number, uint32_t timestamp, - uint32_t cntr_timestamp, uint32_t ref_point, uint64_t target_event, struct isoal_sdu_tx *sdu_tx) @@ -489,7 +488,6 @@ static void isoal_test_create_sdu_fagment(uint8_t sdu_state, sdu_tx->packet_sn = packet_number; sdu_tx->iso_sdu_length = sdu_total_length; sdu_tx->time_stamp = timestamp; - sdu_tx->cntr_time_stamp = cntr_timestamp; sdu_tx->grp_ref_point = ref_point; sdu_tx->target_event = target_event; memcpy(sdu_tx->dbuf, dataptr, length); @@ -794,7 +792,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -923,7 +920,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1039,7 +1035,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1200,7 +1195,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1247,7 +1241,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1291,7 +1284,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1411,7 +1403,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1460,7 +1451,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1527,7 +1517,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1745,7 +1734,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1799,7 +1787,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1929,7 +1916,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -1982,7 +1968,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2045,7 +2030,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2101,7 +2085,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2145,7 +2128,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2208,7 +2190,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2333,7 +2314,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2390,7 +2370,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2453,7 +2432,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2549,7 +2527,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2592,7 +2569,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2655,7 +2631,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2817,7 +2792,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -2978,7 +2952,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3096,7 +3069,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3227,7 +3199,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3298,7 +3269,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3365,7 +3335,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3435,7 +3404,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -3483,470 +3451,6 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) zassert_equal(tx_sync_offset, tx_sync_offset_expected, "%u != %u", tx_sync_seq, 0); } -/** - * Test Suite : TX framed SDU segmentation - * - * Tests framed event selection - */ -#define RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT() \ - out_sdus_skipped = isoal_tx_framed_find_correct_tx_event(source, \ - &tx_sdu_frag_buf.sdu_tx, \ - &out_payload_number, \ - &out_ref_point, \ - &out_time_offset); \ - \ - zassert_equal(out_payload_number, expect_payload_number, "%llu != %llu", \ - out_payload_number, expect_payload_number); \ - zassert_equal(out_ref_point, expect_ref_point, "%u != %u", \ - out_ref_point, expect_ref_point); \ - zassert_equal(out_time_offset, expect_time_offset, "%u != %u", \ - out_time_offset, expect_time_offset); \ - zassert_equal(out_sdus_skipped, expect_sdus_skipped, "%u .!= %u", \ - out_sdus_skipped, expect_sdus_skipped) - -ZTEST(test_tx_framed, test_tx_framed_find_correct_tx_event) -{ - const uint8_t number_of_pdus = 1; - const uint8_t testdata_size_max = MAX_FRAMED_PDU_PAYLOAD(number_of_pdus); - - struct tx_sdu_frag_buffer tx_sdu_frag_buf; - struct isoal_source_session *session; - uint8_t testdata[testdata_size_max]; - isoal_sdu_len_t in_sdu_total_size; - isoal_source_handle_t source_hdl; - struct isoal_pdu_production *pp; - uint64_t expect_payload_number; - struct isoal_source *source; - uint64_t out_payload_number; - uint32_t expect_time_offset; - uint8_t expect_sdus_skipped; - uint32_t expected_timestamp; - uint32_t stream_sync_delay; - uint32_t in_cntr_timestamp; - uint32_t group_sync_delay; - uint64_t in_sdu_packet_sn; - uint32_t in_sdu_timestamp; - uint32_t expect_ref_point; - uint64_t in_target_event; - uint32_t iso_interval_us; - uint8_t iso_interval_int; - uint32_t out_time_offset; - uint8_t out_sdus_skipped; - uint16_t testdata_indx; - uint16_t testdata_size; - uint32_t out_ref_point; - uint32_t sdu_interval; - uint32_t in_ref_point; - uint8_t max_octets; - uint8_t role; - uint8_t BN; - uint8_t FT; - - /* Settings */ - role = BT_CONN_ROLE_PERIPHERAL; - iso_interval_int = 1; - iso_interval_us = iso_interval_int * ISO_INT_UNIT_US; - sdu_interval = iso_interval_us + 50; - max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; - BN = 2; - FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; - - init_test_data_buffer(testdata, testdata_size_max); - - /* Create source */ - source_hdl = basic_tx_test_setup(0xADAD, /* Handle */ - role, /* Role */ - true, /* Framed */ - BN, /* BN */ - FT, /* FT */ - max_octets, /* max_octets */ - sdu_interval, /* SDU Interval */ - iso_interval_int, /* ISO Interval */ - stream_sync_delay, /* Stream Sync Delay */ - group_sync_delay); /* Group Sync Delay */ - - source = &isoal_global.source_state[source_hdl]; - session = &source->session; - pp = &source->pdu_production; - - in_sdu_total_size = testdata_size_max; - testdata_indx = 0; - testdata_size = testdata_size_max; - - /* Test : Selection of event for first SDU where - * -- Last SDU packet number is uninitialized - * -- Last SDU time stamp is uninitialized - * -- Payload number is uninitialized - * -- Target event and reference point are one event ahead - * -- Time stamp is valid - * -- Time stamp indicates that target event is feasible - * Expected: - * -- Target event is used for transmission and calculations are based - * on that - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2000; - in_sdu_timestamp = 9249; - in_cntr_timestamp = in_sdu_timestamp + 200; - in_ref_point = in_sdu_timestamp + iso_interval_us - 50; - - pp->initialized = 0U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = 0; - session->last_input_time_stamp = 0; - pp->payload_number = 0; - - expect_sdus_skipped = 0; - expect_payload_number = in_target_event * BN; - expect_ref_point = in_ref_point; - expected_timestamp = in_sdu_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for first SDU where - * -- Last SDU packet number is uninitialized - * -- Last SDU time stamp is uninitialized - * -- Payload number ahead of target event - * -- Target event and reference point are one event behind - * current payload - * -- Time stamp is valid - * -- Time stamp indicates that target event is feasible - * Expected: - * -- Target event + 1 is selected based on the payload being ahead and - * calculations are based on that reference - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2000; - in_sdu_timestamp = 9249; - in_cntr_timestamp = in_sdu_timestamp + 200; - in_ref_point = in_sdu_timestamp + iso_interval_us - 50; - - pp->initialized = 0U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = 0; - session->last_input_time_stamp = 0; - pp->payload_number = (in_target_event + 1) * BN; - - expect_sdus_skipped = 0; - expect_payload_number = (in_target_event + 1) * BN; - expect_ref_point = in_ref_point + iso_interval_us; - expected_timestamp = in_sdu_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for first SDU where - * -- Last SDU packet number is uninitialized - * -- Last SDU time stamp is uninitialized - * -- Payload number ahead of target event - * -- Target event and reference point are one event behind - * current payload - * -- Time stamp is invalid - * -- Controller time stamp indicates that target event is - * feasible - * Expected: - * -- Target event + 1 is selected based on the payload being ahead and - * calculations are based on that reference - * -- Time offset is based on the controller's capture time - */ - in_sdu_packet_sn = 2000; - in_target_event = 2000; - in_sdu_timestamp = 0; - in_cntr_timestamp = 9249 + 200; - in_ref_point = in_cntr_timestamp + iso_interval_us - 50; - - pp->initialized = 0U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = 0; - session->last_input_time_stamp = 0; - pp->payload_number = (in_target_event + 1) * BN; - - expect_sdus_skipped = 0; - expect_payload_number = (in_target_event + 1) * BN; - expect_ref_point = in_ref_point + iso_interval_us; - expected_timestamp = in_cntr_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for a subsequent SDU where - * -- Last SDU packet number is in sequence - * -- Last SDU time stamp is in sequence - * -- Payload number is in sequence - * -- Target event and reference point are one event ahead of - * current payload - * -- Time stamp is valid - * -- Time stamp indicates that target event is feasible - * Expected: - * -- Target event is selected based on the time stamp and calculations - * are based on that reference - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2000; - in_sdu_timestamp = 9249; - in_cntr_timestamp = 9249 + 200; - in_ref_point = in_sdu_timestamp + iso_interval_us - 50; - - pp->initialized = 1U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = in_sdu_packet_sn - 1; - session->last_input_time_stamp = in_sdu_timestamp - sdu_interval; - pp->payload_number = (in_target_event - 1) * BN; - - expect_sdus_skipped = 0; - expect_payload_number = in_target_event * BN; - expect_ref_point = in_ref_point; - expected_timestamp = in_sdu_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for a subsequent SDU where - * -- Last SDU packet number is not in sequence - * -- Last SDU time stamp is not in sequence - * -- Payload number is not in sequence - * -- Target event and reference point are two events ahead - * -- Time stamp is valid but at the border of the range - * -- Time stamp indicates that target event - 1 is feasible - * Expected: - * -- Target event - 1 is selected based on the time stamp and - * calculations are based on that reference - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2001; - in_sdu_timestamp = 9249; - in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us; - in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; - - pp->initialized = 1U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = in_sdu_packet_sn - 3; - session->last_input_time_stamp = in_sdu_timestamp - (sdu_interval * 2); - pp->payload_number = (in_target_event - 2) * BN; - - expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; - expect_payload_number = (in_target_event - 1) * BN; - expect_ref_point = in_ref_point - iso_interval_us; - expected_timestamp = in_sdu_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for a subsequent SDU where - * -- Last SDU packet number is not in sequence - * -- Last SDU time stamp is not in sequence - * -- Payload number is not in sequence - * -- Target event and reference point are two events ahead - * -- Time stamp is invalid - * Expected: - * -- Target event is selected based on the time stamp calculated - * from the difference between time stamps and calculations are based - * on that reference - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2001; - in_sdu_timestamp = 9249; - in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us + 1; - in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; - - pp->initialized = 1U; - session->tx_time_stamp = in_ref_point - iso_interval_us; - session->tx_time_offset = session->tx_time_stamp - - (in_sdu_timestamp - sdu_interval); - session->last_input_sn = in_sdu_packet_sn - 3; - session->last_input_time_stamp = in_sdu_timestamp - (sdu_interval * 2); - pp->payload_number = (in_target_event - 2) * BN; - - expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; - expect_payload_number = in_target_event * BN; - expect_ref_point = in_ref_point; - expected_timestamp = session->tx_time_stamp - session->tx_time_offset + - (in_sdu_timestamp - session->last_input_time_stamp); - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for a subsequent SDU where - * -- Last SDU packet number is not in sequence - * -- Last SDU time stamp has been projected as part of a - * burst - * -- Payload number is not in sequence - * -- Target event and reference point are two events ahead - * -- Time stamp is invalid - * -- Time stamp delta is invalid - * Expected: - * -- Target event + 1 is selected based on the time stamp calculated - * from the difference in packet sn and calculations are based - * on that reference - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2001; - in_sdu_timestamp = 9249; - in_cntr_timestamp = 9249 + sdu_interval + iso_interval_us + 1; - in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; - - pp->initialized = 1U; - session->tx_time_stamp = in_ref_point - iso_interval_us; - session->tx_time_offset = session->tx_time_stamp - - (in_sdu_timestamp + sdu_interval); - session->last_input_sn = in_sdu_packet_sn - 1; - session->last_input_time_stamp = in_sdu_timestamp + (sdu_interval * 2); - pp->payload_number = (in_target_event - 2) * BN; - - expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; - expect_payload_number = (in_target_event + 1) * BN; - expect_ref_point = in_ref_point + iso_interval_us; - expected_timestamp = session->tx_time_stamp - session->tx_time_offset + sdu_interval; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); - - /* Test : Selection of event for a subsequent SDU where - * -- Last SDU packet number is in sequence - * -- Last SDU time stamp has been projected as part of a - * burst - * -- Payload number is ahead of selected event - * -- Target event and reference point are two events ahead - * -- Time stamp is valid - * -- Time stamp indicates that target event - 1 is feasible - * Expected: - * -- Target event -1 is selected based on the time stamp and - * calculations are based on that reference - * -- Payload number continues from last - * -- Time offset is based on the SDUs time stamp - */ - in_sdu_packet_sn = 2000; - in_target_event = 2001; - in_sdu_timestamp = 9249; - in_cntr_timestamp = 9249; - in_ref_point = in_sdu_timestamp + (iso_interval_us * 2) - 50; - - pp->initialized = 1U; - session->tx_time_stamp = 0; - session->tx_time_offset = 0; - session->last_input_sn = in_sdu_packet_sn - 1; - session->last_input_time_stamp = in_sdu_timestamp - sdu_interval; - pp->payload_number = ((in_target_event - 1) * BN) + 1; - - expect_sdus_skipped = in_sdu_packet_sn - session->last_input_sn - 1; - expect_payload_number = pp->payload_number; - expect_ref_point = in_ref_point - iso_interval_us; - expected_timestamp = in_sdu_timestamp; - expect_time_offset = expect_ref_point - expected_timestamp; - - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - in_sdu_total_size, - in_sdu_packet_sn, - in_sdu_timestamp, - in_cntr_timestamp, - in_ref_point, - in_target_event, - &tx_sdu_frag_buf.sdu_tx); - - RUN_TX_FRAMED_FIND_CORRECT_TX_EVENT(); -} - /** * Test Suite : TX framed SDU segmentation * @@ -4033,7 +3537,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4189,7 +3692,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4334,7 +3836,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4572,7 +4073,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4644,7 +4144,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4699,7 +4198,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4837,7 +4335,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -4911,7 +4408,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5004,7 +4500,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5142,7 +4637,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5218,7 +4712,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5311,7 +4804,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5378,7 +4870,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5445,7 +4936,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5537,7 +5027,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5675,7 +5164,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5748,7 +5236,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5840,7 +5327,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5904,7 +5390,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -5966,7 +5451,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6057,7 +5541,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6228,7 +5711,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6309,7 +5791,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6459,7 +5940,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6616,7 +6096,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6697,7 +6176,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6838,7 +6316,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -6990,7 +6467,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7171,7 +6647,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7300,7 +6775,6 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7447,7 +6921,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7524,7 +6997,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7599,7 +7071,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7763,7 +7234,6 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7839,7 +7309,6 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -7949,7 +7418,6 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -8042,7 +7510,6 @@ ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -8229,7 +7696,6 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -8301,7 +7767,6 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); @@ -8382,7 +7847,6 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_total_size, sdu_packet_number, sdu_timestamp, - sdu_timestamp, ref_point, event_number, &tx_sdu_frag_buf.sdu_tx); From ec869c65367bd72f0d386beb1c57f8d7bc59d6e4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:52 +0000 Subject: [PATCH 4152/4498] Revert "[nrf fromtree] test: bluetooth: controller: Updated ISO-AL tests to cover endianness" This reverts commit 78f271634db1df8383b6e32e46e750c428e264fc. Signed-off-by: Dominik Ermel --- .../ctrl_isoal/src/isoal_test_common.c | 12 +++-- .../ctrl_isoal/src/isoal_test_debug.c | 44 +------------------ tests/bluetooth/ctrl_isoal/src/main.c | 2 - .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 36 +++++++-------- 4 files changed, 24 insertions(+), 70 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c index 35947656336..a20ba5fd084 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_common.c @@ -23,7 +23,6 @@ #include #include -#include #include "util/memq.h" @@ -110,7 +109,7 @@ void isoal_test_create_unframed_pdu(uint8_t llid, uint16_t isoal_test_insert_segment(bool sc, bool cmplt, uint32_t time_offset, uint8_t *dataptr, uint8_t length, struct isoal_pdu_rx *pdu_meta) { - uint8_t seg_hdr[PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE]; + struct pdu_iso_sdu_sh seg_hdr; uint16_t pdu_payload_size; uint8_t hdr_write_size; uint16_t pdu_data_loc; @@ -123,13 +122,12 @@ uint16_t isoal_test_insert_segment(bool sc, bool cmplt, uint32_t time_offset, ui zassert_true(pdu_payload_size <= TEST_RX_PDU_PAYLOAD_MAX, "pdu_payload_size (%d)", pdu_payload_size); - /* Write header independent of endian dependent structures */ - WRITE_BIT(seg_hdr[0], 0, sc); /* sc */ - WRITE_BIT(seg_hdr[0], 1, cmplt); /* cmplt */ - seg_hdr[1] = length + (sc ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); + seg_hdr.sc = sc; + seg_hdr.cmplt = cmplt; + seg_hdr.len = length + (sc ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); if (!sc) { - sys_put_le24(time_offset, &seg_hdr[PDU_ISO_SEG_HDR_SIZE]); + seg_hdr.timeoffset = time_offset; } memcpy(&pdu_meta->pdu->payload[pdu_meta->pdu->len], &seg_hdr, hdr_write_size); diff --git a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c index 734af1ad7c0..464d2586598 100644 --- a/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c +++ b/tests/bluetooth/ctrl_isoal/src/isoal_test_debug.c @@ -52,12 +52,6 @@ void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta) { zassert_not_null(pdu_meta, ""); - struct pdu_iso *pdu; - uint8_t seg_length; - - pdu = pdu_meta->pdu; - seg_length = 0; - PRINT("\n"); PRINT("PDU %04u (%10u) | %12s [%10s] %03u: ", (uint32_t) pdu_meta->meta->payload_number, @@ -66,42 +60,8 @@ void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta) DU_ERR_TO_STR(pdu_meta->meta->status), pdu_meta->pdu->len); - for (uint8_t i = 0U; i < pdu->len; i++) { - if (seg_length == 0U && pdu->ll_id == PDU_BIS_LLID_FRAMED) { - seg_length = pdu->payload[i + 1U]; - PRINT("[%s %s %03u]", - pdu->payload[i] & BIT(0) ? "C" : "S", - pdu->payload[i] & BIT(1) ? "C" : "-", - pdu->payload[i + 1U]); - if ((pdu->payload[i] & BIT(0)) == 0U) { - PRINT("(%8uus)", - ((uint32_t)pdu->payload[i + 2U] + - ((uint32_t)pdu->payload[i + 3U] << 8) + - ((uint32_t)pdu->payload[i + 4U] << 16))); - } - - PRINT(" / "); - PRINT("[%02x %02x]", - pdu->payload[i], - pdu->payload[i + 1U]); - if ((pdu->payload[i] & BIT(0)) == 0U) { - PRINT("(%02x %02x %02x)", - (uint32_t)pdu->payload[i + 4U], - (uint32_t)pdu->payload[i + 3U], - (uint32_t)pdu->payload[i + 2U]); - } - - PRINT(" : "); - seg_length -= pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE; - i += PDU_ISO_SEG_HDR_SIZE + - (pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE); - } - - PRINT("%02x ", pdu->payload[i]); - seg_length--; - if (seg_length == 0 && pdu->ll_id == PDU_BIS_LLID_FRAMED) { - PRINT("\n%44s", ""); - } + for (int i = 0; i < pdu_meta->pdu->len; i++) { + PRINT("%02x ", pdu_meta->pdu->payload[i]); } PRINT("\n"); PRINT("\n"); diff --git a/tests/bluetooth/ctrl_isoal/src/main.c b/tests/bluetooth/ctrl_isoal/src/main.c index 08175eab153..92ca21ff199 100644 --- a/tests/bluetooth/ctrl_isoal/src/main.c +++ b/tests/bluetooth/ctrl_isoal/src/main.c @@ -18,8 +18,6 @@ #include #include -#include - #include DEFINE_FFF_GLOBALS; diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index 3f57d8bccbc..dc21c9b5d61 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -3757,8 +3757,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) * Test Suite : TX framed SDU segmentation * * Tests segmentation of a single SDU contained in a single fragment - * into three PDUs where Max PDU is less than the PDU buffer size. Also tests - * endianness of the segment header. + * into three PDUs where Max PDU is less than the PDU buffer size */ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) { @@ -3855,11 +3854,10 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* Test segmentation (Black Box) */ /* Valid PDUs */ /* PDU 1 */ - /* Test endianness */ - WRITE_BIT(((uint8_t *)&seg_hdr[0])[0], 0, 0); /* sc */ - WRITE_BIT(((uint8_t *)&seg_hdr[0])[0], 1, 0); /* cmplt */ - sys_put_le24(ref_point - sdu_timestamp, (uint8_t *)(&seg_hdr[0]) + PDU_ISO_SEG_HDR_SIZE); - ((uint8_t *)(&seg_hdr[0]))[1] = PDU_ISO_SEG_TIMEOFFSET_SIZE; /* len */ + seg_hdr[0].sc = 0; + seg_hdr[0].cmplt = 0; + seg_hdr[0].timeoffset = ref_point - sdu_timestamp; + seg_hdr[0].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; pdu_hdr_loc = 0; pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; sdu_read_loc = 0; @@ -3879,7 +3877,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[1] = seg_hdr[0]; - ((uint8_t *)(&seg_hdr[1]))[1] += (pdu_write_size - pdu_write_loc); + seg_hdr[1].len += (pdu_write_size - pdu_write_loc); ZASSERT_PDU_WRITE_TEST(history[2], pdu_buffer, @@ -3897,10 +3895,10 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* PDU 2 */ payload_number++; - WRITE_BIT(((uint8_t *)&seg_hdr[2])[0], 0, 1); /* sc */ - WRITE_BIT(((uint8_t *)&seg_hdr[2])[0], 1, 0); /* cmplt */ - sys_put_le24(0, (uint8_t *)(&seg_hdr[2]) + PDU_ISO_SEG_HDR_SIZE); - ((uint8_t *)(&seg_hdr[2]))[1] = 0; /* len */ + seg_hdr[2].sc = 1; + seg_hdr[2].cmplt = 0; + seg_hdr[2].timeoffset = 0; + seg_hdr[2].len = 0; pdu_hdr_loc = 0; sdu_read_loc += (pdu_write_size - pdu_write_loc); pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; @@ -3920,7 +3918,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[3] = seg_hdr[2]; - ((uint8_t *)(&seg_hdr[3]))[1] += (pdu_write_size - pdu_write_loc); /* len */ + seg_hdr[3].len += (pdu_write_size - pdu_write_loc); ZASSERT_PDU_WRITE_TEST(history[5], pdu_buffer, @@ -3938,10 +3936,10 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* PDU 3 */ payload_number++; - WRITE_BIT(((uint8_t *)&seg_hdr[4])[0], 0, 1); /* sc */ - WRITE_BIT(((uint8_t *)&seg_hdr[4])[0], 1, 0); /* cmplt */ - sys_put_le24(0, (uint8_t *)(&seg_hdr[4]) + PDU_ISO_SEG_HDR_SIZE); - ((uint8_t *)(&seg_hdr[4]))[1] = 0; /* len */ + seg_hdr[4].sc = 1; + seg_hdr[4].cmplt = 0; + seg_hdr[4].timeoffset = 0; + seg_hdr[4].len = 0; pdu_hdr_loc = 0; sdu_read_loc += (pdu_write_size - pdu_write_loc); pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; @@ -3964,8 +3962,8 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) (pdu_write_size - pdu_write_loc)); seg_hdr[5] = seg_hdr[4]; - WRITE_BIT(((uint8_t *)&seg_hdr[5])[0], 1, 1); /* cmplt */ - ((uint8_t *)(&seg_hdr[5]))[1] += (pdu_write_size - pdu_write_loc); /* len */ + seg_hdr[5].cmplt = 1; + seg_hdr[5].len += (pdu_write_size - pdu_write_loc); ZASSERT_PDU_WRITE_TEST(history[8], pdu_buffer, From d598726261ba1278e397565901804acac8082890 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:52 +0000 Subject: [PATCH 4153/4498] Revert "[nrf fromtree] tests: bluetooth: controller: Test for framed TX in consecutive events" This reverts commit 9530f3bfb97b911974d607a58bd00cdab7887fa3. Signed-off-by: Dominik Ermel --- .../ctrl_isoal/src/sub_sets/isoal_test_rx.c | 109 ++- .../ctrl_isoal/src/sub_sets/isoal_test_tx.c | 754 ++++-------------- 2 files changed, 181 insertions(+), 682 deletions(-) diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c index 5a3c60e0854..2ce8862e1d4 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_rx.c @@ -8332,30 +8332,27 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err1) */ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) { - const uint8_t test_data_size = 33; - const uint8_t max_sdu_burst = 2; - - struct rx_sdu_frag_buffer rx_sdu_frag_buf[max_sdu_burst]; - struct isoal_sdu_buffer sdu_buffer[max_sdu_burst]; - isoal_sdu_status_t collated_status[max_sdu_burst]; struct rx_pdu_meta_buffer rx_pdu_meta_buf; - isoal_sdu_len_t sdu_size[max_sdu_burst]; - uint16_t total_sdu_size[max_sdu_burst]; - uint32_t sdu_timestamp[max_sdu_burst]; - uint8_t testdata[test_data_size]; + struct rx_sdu_frag_buffer rx_sdu_frag_buf; + struct isoal_sdu_buffer sdu_buffer; + isoal_sdu_status_t collated_status; isoal_sink_handle_t sink_hdl; uint32_t stream_sync_delay; uint32_t group_sync_delay; + isoal_sdu_len_t sdu_size; uint8_t iso_interval_int; uint16_t pdu_data_loc[5]; uint32_t iso_interval_us; uint64_t payload_number; + uint16_t total_sdu_size; uint32_t sdu_timeoffset; uint32_t pdu_timestamp; + uint32_t sdu_timestamp; uint16_t testdata_indx; uint16_t testdata_size; uint32_t sdu_interval; isoal_sdu_cnt_t seqn; + uint8_t testdata[33]; isoal_status_t err; uint32_t latency; uint8_t role; @@ -8374,14 +8371,12 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) /* PDU 1 -------------------------------------------------------------*/ isoal_test_init_rx_pdu_buffer(&rx_pdu_meta_buf); - isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf[0]); - init_test_data_buffer(testdata, test_data_size); + isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf); + init_test_data_buffer(testdata, 33); memset(pdu_data_loc, 0, sizeof(pdu_data_loc)); - sdu_buffer[0].dbuf = &rx_sdu_frag_buf[0]; - sdu_buffer[0].size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; - sdu_buffer[1].dbuf = &rx_sdu_frag_buf[1]; - sdu_buffer[1].size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; + sdu_buffer.dbuf = &rx_sdu_frag_buf; + sdu_buffer.size = TEST_RX_SDU_FRAG_PAYLOAD_MAX; payload_number = 1000 * BN; pdu_timestamp = 9249; latency = calc_rx_latency_by_role(role, @@ -8393,13 +8388,13 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) group_sync_delay); sdu_timeoffset = group_sync_delay - 50; /* PDU will have errors. Time stamp is only an approximation */ - sdu_timestamp[0] = (uint32_t)((int64_t)pdu_timestamp + latency - iso_interval_us); + sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency - iso_interval_us); seqn = 0; testdata_indx = 0; testdata_size = 23; - sdu_size[0] = 0; - total_sdu_size[0] = COLLATED_RX_SDU_INFO(sdu_size[0], sdu_size[0]); - collated_status[0] = + sdu_size = 0; + total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); + collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_LOST_DATA, ISOAL_SDU_STATUS_LOST_DATA); sink_hdl = basic_rx_test_setup(0xADAD, /* Handle */ @@ -8423,7 +8418,7 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) &rx_pdu_meta_buf.pdu_meta); /* Set callback function return values */ - push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer[0]); + push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer); sink_sdu_alloc_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_write_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_emit_test_fake.return_val = ISOAL_STATUS_OK; @@ -8433,14 +8428,25 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); /* Test recombine (Black Box) */ - /* A new SDU should not be allocated */ - ZASSERT_ISOAL_SDU_ALLOC_TEST_CALL_COUNT(0); + /* A new SDU should be allocated */ + ZASSERT_ISOAL_SDU_ALLOC_TEST(val, + &isoal_global.sink_state[sink_hdl], /* Sink */ + &rx_pdu_meta_buf.pdu_meta); /* PDU */ /* SDU payload should not be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(0); - /* SDU should not be emitted */ - ZASSERT_ISOAL_SDU_EMIT_TEST_CALL_COUNT(0); + /* SDU should be emitted */ + ZASSERT_ISOAL_SDU_EMIT_TEST(val, + &isoal_global.sink_state[sink_hdl], /* Sink */ + BT_ISO_SINGLE, /* Frag state */ + sdu_size, /* Frag size */ + ISOAL_SDU_STATUS_LOST_DATA, /* Frag status */ + sdu_timestamp, /* Timestamp */ + seqn, /* Seq. number */ + sdu_buffer.dbuf, /* Buffer */ + sdu_buffer.size, /* Buffer size */ + total_sdu_size, /* Total size */ + collated_status); /* SDU status */ /* Test recombine (White Box) */ zassert_equal(isoal_global.sink_state[sink_hdl].sdu_production.fsm, @@ -8451,17 +8457,18 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) /* PDU 2 -------------------------------------------------------------*/ isoal_test_init_rx_pdu_buffer(&rx_pdu_meta_buf); - isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf[1]); + isoal_test_init_rx_sdu_buffer(&rx_sdu_frag_buf); payload_number++; sdu_timeoffset = get_next_time_offset(sdu_timeoffset, iso_interval_us, sdu_interval, false); - sdu_timestamp[1] = (uint32_t)((int64_t)pdu_timestamp + latency - sdu_timeoffset); + sdu_timestamp = (uint32_t)((int64_t)pdu_timestamp + latency - sdu_timeoffset); + seqn++; testdata_indx = testdata_size; testdata_size += 10; - sdu_size[1] = 10; - total_sdu_size[1] = COLLATED_RX_SDU_INFO(sdu_size[1], sdu_size[1]); - collated_status[1] = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_VALID, ISOAL_SDU_STATUS_VALID); + sdu_size = 10; + total_sdu_size = COLLATED_RX_SDU_INFO(sdu_size, sdu_size); + collated_status = COLLATED_RX_SDU_INFO(ISOAL_SDU_STATUS_VALID, ISOAL_SDU_STATUS_VALID); isoal_test_create_framed_pdu_base(payload_number, pdu_timestamp, @@ -8473,7 +8480,7 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) &rx_pdu_meta_buf.pdu_meta); /* Set callback function return values */ - push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer[1]); + push_custom_sink_sdu_alloc_test_output_buffer(&sdu_buffer); sink_sdu_alloc_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_write_test_fake.return_val = ISOAL_STATUS_OK; sink_sdu_emit_test_fake.return_val = ISOAL_STATUS_OK; @@ -8483,38 +8490,14 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); /* Test recombine (Black Box) */ - /* SDU 0 -------------------------------------------------------------*/ - /* A new SDU should be allocated */ - ZASSERT_ISOAL_SDU_ALLOC_TEST(history[0], - &isoal_global.sink_state[sink_hdl], /* Sink */ - &rx_pdu_meta_buf.pdu_meta); /* PDU */ - - /* SDU payload should not be written */ - - /* SDU should be emitted */ - ZASSERT_ISOAL_SDU_EMIT_TEST(history[0], - &isoal_global.sink_state[sink_hdl], /* Sink */ - BT_ISO_SINGLE, /* Frag state */ - sdu_size[0], /* Frag size */ - ISOAL_SDU_STATUS_LOST_DATA, /* Frag status */ - sdu_timestamp[0], /* Timestamp */ - seqn, /* Seq. number */ - sdu_buffer[0].dbuf, /* Buffer */ - sdu_buffer[0].size, /* Buffer size */ - total_sdu_size[0], /* Total size */ - collated_status[0]); /* SDU status */ - - /* SDU 1 -------------------------------------------------------------*/ - seqn++; /* A new SDU should be allocated */ ZASSERT_ISOAL_SDU_ALLOC_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ &rx_pdu_meta_buf.pdu_meta); /* PDU */ /* SDU payload should be written */ - ZASSERT_ISOAL_SDU_WRITE_TEST_CALL_COUNT(1); ZASSERT_ISOAL_SDU_WRITE_TEST(val, - &rx_sdu_frag_buf[1], /* SDU buffer */ + &rx_sdu_frag_buf, /* SDU buffer */ &rx_pdu_meta_buf.pdu[3 + pdu_data_loc[1]], /* PDU payload */ (testdata_size - testdata_indx)); /* Size */ @@ -8523,14 +8506,14 @@ ZTEST(test_rx_framed, test_rx_framed_dbl_pdu_dbl_sdu_pdu_err2) ZASSERT_ISOAL_SDU_EMIT_TEST(val, &isoal_global.sink_state[sink_hdl], /* Sink */ BT_ISO_SINGLE, /* Frag state */ - sdu_size[1], /* Frag size */ + sdu_size, /* Frag size */ ISOAL_SDU_STATUS_VALID, /* Frag status */ - sdu_timestamp[1], /* Timestamp */ + sdu_timestamp, /* Timestamp */ seqn, /* Seq. number */ - sdu_buffer[1].dbuf, /* Buffer */ - sdu_buffer[1].size, /* Buffer size */ - total_sdu_size[1], /* Total size */ - collated_status[1]); /* SDU status */ + sdu_buffer.dbuf, /* Buffer */ + sdu_buffer.size, /* Buffer size */ + total_sdu_size, /* Total size */ + collated_status); /* SDU status */ /* Test recombine (White Box) */ zassert_equal(isoal_global.sink_state[sink_hdl].sdu_production.fsm, diff --git a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c index dc21c9b5d61..fe375b7accd 100644 --- a/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c +++ b/tests/bluetooth/ctrl_isoal/src/sub_sets/isoal_test_tx.c @@ -111,8 +111,7 @@ static void push_custom_source_pdu_write_test_sdu_payload(const uint8_t *data, c } static void check_next_custom_source_pdu_write_test_sdu_payload(const uint8_t *data, - const size_t length, - const uint32_t line) + const size_t length) { size_t pos = custom_source_pdu_write_test_sdu_payloads.pos; size_t buffer_size = custom_source_pdu_write_test_sdu_payloads.buffer_size; @@ -126,8 +125,7 @@ static void check_next_custom_source_pdu_write_test_sdu_payload(const uint8_t *d for (size_t i = 0; i < custom_source_pdu_write_test_sdu_payloads.out_size[pos]; i++) { zassert_equal(custom_source_pdu_write_test_sdu_payloads.out[pos][i], data[i], - "[Line %lu] deviation at index %u, expected %u, got %u", - line, + "deviation at index %u, expected %u, got %u", i, data[i], custom_source_pdu_write_test_sdu_payloads.out[pos][i]); @@ -195,7 +193,7 @@ static isoal_status_t custom_source_pdu_write_test(struct isoal_pdu_buffer *pdu_ _consume_len, \ source_pdu_write_test_fake.arg3_##_typ); \ check_next_custom_source_pdu_write_test_sdu_payload((const uint8_t *)_sdu_payload, \ - _consume_len, __LINE__); + _consume_len); #define ZASSERT_PDU_WRITE_TEST_CALL_COUNT(_expected) \ zassert_equal(_expected, \ @@ -424,7 +422,7 @@ static isoal_source_handle_t basic_tx_test_setup(uint16_t handle, burst_number, flush_timeout, max_octets, - (iso_interval_int * ISO_INT_UNIT_US), + (iso_interval_int * CONN_INT_UNIT_US), sdu_interval, stream_sync_delay, group_sync_delay); @@ -538,8 +536,8 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_destroy) max_octets = 40; sdu_interval_int = 1; iso_interval_int = 1; - iso_interval = iso_interval_int * ISO_INT_UNIT_US; - sdu_interval = sdu_interval_int * ISO_INT_UNIT_US; + iso_interval = iso_interval_int * CONN_INT_UNIT_US; + sdu_interval = sdu_interval_int * CONN_INT_UNIT_US; stream_sync_delay = iso_interval - 200; group_sync_delay = iso_interval - 50; @@ -608,8 +606,8 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_destroy) max_octets += max_octets / 2; sdu_interval_int++; iso_interval_int = iso_interval_int * sdu_interval_int; - sdu_interval = (sdu_interval_int * ISO_INT_UNIT_US) - (framed ? 100 : 0); - iso_interval = iso_interval_int * ISO_INT_UNIT_US; + sdu_interval = (sdu_interval_int * CONN_INT_UNIT_US) - (framed ? 100 : 0); + iso_interval = iso_interval_int * CONN_INT_UNIT_US; stream_sync_delay = iso_interval - (200 * i); group_sync_delay = iso_interval - 50; } @@ -656,9 +654,9 @@ ZTEST(test_tx_basics, test_source_isoal_test_create_err) flush_timeout = 1; framed = false; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; - stream_sync_delay = ISO_INT_UNIT_US - 200; - group_sync_delay = ISO_INT_UNIT_US - 50; + sdu_interval = CONN_INT_UNIT_US; + stream_sync_delay = CONN_INT_UNIT_US - 200; + group_sync_delay = CONN_INT_UNIT_US - 50; res = isoal_init(); zassert_equal(res, ISOAL_STATUS_OK, "res = 0x%02x", res); @@ -749,12 +747,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -766,7 +764,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -877,12 +875,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -894,7 +892,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_1_pdu_bufSize) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX; @@ -995,12 +993,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1012,7 +1010,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_3_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = 100; testdata_indx = 0; testdata_size = 100; @@ -1154,12 +1152,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1171,7 +1169,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_1_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX / 3; @@ -1359,12 +1357,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -1380,7 +1378,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_3_frag_2_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -1691,12 +1689,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -1823,7 +1821,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Check TX Sync info */ tx_sync_seq_expected = 2; - tx_sync_timestamp_expected = (iso_interval_int * ISO_INT_UNIT_US) - 1; + tx_sync_timestamp_expected = (iso_interval_int * CONN_INT_UNIT_US) - 1; tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -1872,12 +1870,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 4; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -1893,7 +1891,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -2266,12 +2264,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 8; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -2291,7 +2289,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX * 2; testdata_indx = 0; testdata_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) / 3; @@ -2741,12 +2739,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -2766,7 +2764,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_zero_sdu_1_frag_1_pdu_maxPDU_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = 0; testdata_indx = 0; testdata_size = 0; @@ -2909,12 +2907,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -2926,7 +2924,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_alloc_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -3026,12 +3024,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US; + sdu_interval = CONN_INT_UNIT_US; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3043,7 +3041,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_1_sdu_1_frag_pdu_emit_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5; testdata_indx = 0; testdata_size = TEST_TX_PDU_PAYLOAD_MAX - 5; @@ -3155,12 +3153,12 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US / 2; + sdu_interval = CONN_INT_UNIT_US / 2; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ /* Sets initial fragmentation status */ @@ -3173,7 +3171,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) event_number = 2000; sdu_packet_number = (event_number * BN); sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = 23; testdata_indx = 0; testdata_size = 23; @@ -3255,9 +3253,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); sdu_packet_number += 29; - sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) - sdu_interval; + sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) - sdu_interval; event_number += 15; - ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3305,7 +3303,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 29; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3321,9 +3319,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); /* Same SDU packet sequence number for testing */ /* Time stamp just before the exact multiple of the SDU interval */ - sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) - 1; + sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) - 1; event_number += 15; - ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3371,7 +3369,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 30; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3390,9 +3388,9 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) * +1 (reset to exact multiple of SDU interval from the last SDU) * +1 (push the time stamp 1us beyond the multiple mark) */ - sdu_timestamp += ((iso_interval_int * ISO_INT_UNIT_US) * 15) + 1 + 1; + sdu_timestamp += ((iso_interval_int * CONN_INT_UNIT_US) * 15) + 1 + 1; event_number += 15; - ref_point += (iso_interval_int * ISO_INT_UNIT_US) * 15; + ref_point += (iso_interval_int * CONN_INT_UNIT_US) * 15; sdu_total_size = 10; testdata_indx = testdata_size; testdata_size += 10; @@ -3440,7 +3438,7 @@ ZTEST(test_tx_unframed, test_tx_unframed_4_sdu_1_frag_4_pdu_stream_loc) /* Check TX Sync info */ tx_sync_seq_expected += 30; - tx_sync_timestamp_expected = ref_point - (iso_interval_int * ISO_INT_UNIT_US); + tx_sync_timestamp_expected = ref_point - (iso_interval_int * CONN_INT_UNIT_US); tx_sync_offset_expected = 0; err = isoal_tx_get_sync_info(source_hdl, &tx_sync_seq, &tx_sync_timestamp, &tx_sync_offset); @@ -3492,12 +3490,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3512,7 +3510,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -3647,12 +3645,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3667,7 +3665,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_bufSize) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -3793,12 +3791,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -3812,7 +3810,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_3_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = 100 - ((3 * PDU_ISO_SEG_HDR_SIZE) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; testdata_size = 100 - ((3 * PDU_ISO_SEG_HDR_SIZE) + PDU_ISO_SEG_TIMEOFFSET_SIZE); @@ -4024,12 +4022,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -4044,7 +4042,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_1_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4283,12 +4281,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 2; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -4307,7 +4305,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_3_frag_2_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4585,12 +4583,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 4; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -4609,7 +4607,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -4853,7 +4851,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu) sdu_packet_number++; event_number = 2000; sdu_timestamp = 9249 + sdu_interval; - ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = (TEST_TX_PDU_PAYLOAD_MAX * 2) - ((PDU_ISO_SEG_HDR_SIZE * 2) + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -5117,12 +5115,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 2; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 6; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -5139,7 +5137,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = testdata_size_max; testdata_indx = 0; testdata_size = testdata_size_max / number_of_sdu_frags; @@ -5376,7 +5374,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_3_frag_4_pdu_padding) sdu_packet_number++; event_number = 2000; sdu_timestamp = 9249 + sdu_interval; - ref_point = 9249 + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = 9249 + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = testdata_size_max; testdata_indx = 0; testdata_size = testdata_size_max / number_of_sdu_frags; @@ -5663,12 +5661,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -5684,7 +5682,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -5802,7 +5800,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_refPoint2) /* PDU 2 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * ISO_INT_UNIT_US; + ref_point += iso_interval_int * CONN_INT_UNIT_US; payload_number++; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -5892,12 +5890,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -5957,7 +5955,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_1_pdu_refPoint3) /* PDU 1 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * ISO_INT_UNIT_US; + ref_point += iso_interval_int * CONN_INT_UNIT_US; payload_number = event_number * BN; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -6048,12 +6046,12 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6187,7 +6185,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_2_pdu_ts_wrap1) /* PDU 2 */ /* Advance the target event and the reference point to what it should be */ event_number++; - ref_point += iso_interval_int * ISO_INT_UNIT_US; + ref_point += iso_interval_int * CONN_INT_UNIT_US; payload_number++; seg_hdr[0].sc = 0; seg_hdr[0].cmplt = 0; @@ -6272,12 +6270,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6290,7 +6288,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_maxPDU) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6415,12 +6413,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 3; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); @@ -6441,7 +6439,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_zero_sdu_1_frag_1_pdu_padding) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6600,12 +6598,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6620,7 +6618,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_alloc_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6728,12 +6726,12 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) /* Settings */ role = ISOAL_ROLE_PERIPHERAL; iso_interval_int = 1; - sdu_interval = ISO_INT_UNIT_US + 50; + sdu_interval = CONN_INT_UNIT_US + 50; max_octets = TEST_TX_PDU_PAYLOAD_MAX - 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU Frag 1 --------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6748,7 +6746,7 @@ ZTEST(test_tx_framed, test_tx_framed_1_sdu_1_frag_pdu_emit_err) sdu_packet_number = 2000; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - 5 - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -6881,8 +6879,8 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -6895,7 +6893,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) sdu_packet_number = 0; event_number = 2000; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = TEST_TX_PDU_PAYLOAD_MAX - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); testdata_indx = 0; @@ -7058,7 +7056,7 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) event_number++; sdu_packet_number++; sdu_timestamp = sdu_timestamp + sdu_interval; - ref_point = ref_point + (iso_interval_int * ISO_INT_UNIT_US); + ref_point = ref_point + (iso_interval_int * CONN_INT_UNIT_US); sdu_total_size = 20; testdata_indx = testdata_size; testdata_size += 20; @@ -7131,488 +7129,6 @@ ZTEST(test_tx_framed, test_tx_framed_2_sdu_1_frag_pdu_timeout) isoal_global.source_state[source_hdl].session.handle); } -/** - * Test Suite : TX framed SDU segmentation - * - * Tests that consecutive events are used irrespective of the target event info - * as long as they are feasible. - */ -ZTEST(test_tx_framed, test_tx_framed_event_utilization_1) -{ - const uint8_t number_of_pdus = 3; - const uint8_t sdu_fragment_data_size = 25; - const uint8_t testdata_size_max = sdu_fragment_data_size * 4; - /* Two SDUs and one that would overflow into a new PDU */ - const uint8_t number_of_seg_hdr_buf = 3; - - struct tx_pdu_meta_buffer tx_pdu_meta_buf[number_of_pdus]; - struct pdu_iso_sdu_sh seg_hdr[number_of_seg_hdr_buf]; - struct isoal_pdu_buffer pdu_buffer[number_of_pdus]; - struct tx_sdu_frag_buffer tx_sdu_frag_buf; - uint8_t testdata[testdata_size_max]; - isoal_source_handle_t source_hdl; - isoal_sdu_len_t sdu_total_size; - isoal_pdu_len_t pdu_write_end; - uint32_t stream_sync_delay; - uint64_t sdu_packet_number; - uint32_t group_sync_delay; - uint64_t pdu_event_number; - uint8_t iso_interval_int; - uint32_t iso_interval_us; - uint64_t payload_number; - uint32_t pdu_ref_point; - uint32_t sdu_timestamp; - uint16_t testdata_indx; - uint16_t testdata_size; - uint16_t pdu_write_loc; - uint16_t sdu_read_loc; - uint64_t event_number; - uint32_t sdu_interval; - uint8_t sdu_fragments; - uint16_t pdu_hdr_loc; - uint32_t ref_point; - isoal_status_t err; - uint8_t max_octets; - uint8_t role; - uint8_t BN; - uint8_t FT; - - /* Settings */ - role = BT_CONN_ROLE_PERIPHERAL; - iso_interval_int = 1; - iso_interval_us = iso_interval_int * ISO_INT_UNIT_US; - sdu_interval = ISO_INT_UNIT_US - 50; /* Less than an ISO interval */ - max_octets = TEST_TX_PDU_PAYLOAD_MAX; - BN = 2; - FT = 1; - stream_sync_delay = iso_interval_us - 200; - group_sync_delay = iso_interval_us - 50; - - /* SDU 0 -------------------------------------------------------------*/ - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[1]); - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[2]); - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - init_test_data_buffer(testdata, testdata_size_max); - (void)memset(&seg_hdr, 0, sizeof(seg_hdr)); - pdu_buffer[0].handle = (void *)&tx_pdu_meta_buf[0].node_tx; - pdu_buffer[0].pdu = (struct pdu_iso *)tx_pdu_meta_buf[0].node_tx.pdu; - pdu_buffer[0].size = TEST_TX_PDU_PAYLOAD_MAX; - pdu_buffer[1].handle = (void *)&tx_pdu_meta_buf[1].node_tx; - pdu_buffer[1].pdu = (struct pdu_iso *)tx_pdu_meta_buf[1].node_tx.pdu; - pdu_buffer[1].size = TEST_TX_PDU_PAYLOAD_MAX; - pdu_buffer[2].handle = (void *)&tx_pdu_meta_buf[2].node_tx; - pdu_buffer[2].pdu = (struct pdu_iso *)tx_pdu_meta_buf[2].node_tx.pdu; - pdu_buffer[2].size = TEST_TX_PDU_PAYLOAD_MAX; - sdu_packet_number = 0; - event_number = 5; - pdu_event_number = event_number; - sdu_timestamp = 9249; - ref_point = sdu_timestamp + iso_interval_us; - pdu_ref_point = ref_point; - sdu_total_size = sdu_fragment_data_size; - testdata_indx = 0; - testdata_size = sdu_fragment_data_size; - sdu_fragments = 0; - - source_hdl = basic_tx_test_setup(0xADAD, /* Handle */ - role, /* Role */ - true, /* Framed */ - BN, /* BN */ - FT, /* FT */ - max_octets, /* max_octets */ - sdu_interval, /* SDU Interval */ - iso_interval_int, /* ISO Interval */ - stream_sync_delay, /* Stream Sync Delay */ - group_sync_delay); /* Group Sync Delay */ - - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - sdu_total_size, - sdu_packet_number, - sdu_timestamp, - ref_point, - event_number, - &tx_sdu_frag_buf.sdu_tx); - - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[1]); - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[1]); - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[2]); - SET_NEXT_PDU_ALLOC_BUFFER(&pdu_buffer[0]); - PDU_ALLOC_TEST_RETURNS(ISOAL_STATUS_OK); - PDU_WRITE_TEST_RETURNS(ISOAL_STATUS_OK); - PDU_EMIT_TEST_RETURNS(ISOAL_STATUS_OK); - PDU_RELEASE_TEST_RETURNS(ISOAL_STATUS_OK); - - err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); - - zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); - - /* Test segmentation (Black Box) */ - /* Valid PDUs */ - /* PDU 0 */ - payload_number = event_number * BN; - seg_hdr[0].sc = 0; - seg_hdr[0].cmplt = 0; - seg_hdr[0].timeoffset = pdu_ref_point - sdu_timestamp; - seg_hdr[0].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; - pdu_hdr_loc = 0; - pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; - sdu_read_loc = 0; - pdu_write_end = sdu_fragment_data_size + pdu_write_loc; - sdu_fragments++; - - ZASSERT_PDU_WRITE_TEST(history[0], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[0], - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); - - ZASSERT_PDU_WRITE_TEST(history[1], - pdu_buffer[0], - pdu_write_loc, - &testdata[sdu_read_loc], - (pdu_write_end - pdu_write_loc)); - - seg_hdr[0].cmplt = 1; - seg_hdr[0].len += (pdu_write_end - pdu_write_loc); - - ZASSERT_PDU_WRITE_TEST(history[2], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[0], - PDU_ISO_SEG_HDR_SIZE); - - /* PDU should not be emitted */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(0); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* SDU 1 -------------------------------------------------------------*/ - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - sdu_packet_number++; - event_number += 2; - ref_point += iso_interval_us * 2; - sdu_timestamp += sdu_interval; - testdata_indx = testdata_size; - testdata_size += sdu_fragment_data_size; - - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - sdu_total_size, - sdu_packet_number, - sdu_timestamp, - ref_point, - event_number, - &tx_sdu_frag_buf.sdu_tx); - - err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); - - zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); - - /* Test segmentation (Black Box) */ - /* Valid PDUs */ - /* PDU 10 */ - pdu_hdr_loc = pdu_write_end; - seg_hdr[1].sc = 0; - seg_hdr[1].cmplt = 0; - seg_hdr[1].timeoffset = pdu_ref_point - sdu_timestamp; - seg_hdr[1].len = PDU_ISO_SEG_TIMEOFFSET_SIZE; - pdu_write_loc = pdu_write_end + (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); - pdu_write_end = TEST_TX_PDU_PAYLOAD_MAX; - sdu_read_loc = testdata_indx; - - ZASSERT_PDU_WRITE_TEST(history[3], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[1], - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); - - ZASSERT_PDU_WRITE_TEST(history[4], - pdu_buffer[0], - pdu_write_loc, - &testdata[sdu_read_loc], - (pdu_write_end - pdu_write_loc)); - - /* PDU should not be allocated */ - - seg_hdr[1].len += (pdu_write_end - pdu_write_loc); - - ZASSERT_PDU_WRITE_TEST(history[5], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[1], - PDU_ISO_SEG_HDR_SIZE); - - ZASSERT_PDU_EMIT_TEST(history[0], - &tx_pdu_meta_buf[0].node_tx, - payload_number, - sdu_fragments, - PDU_BIS_LLID_FRAMED, - pdu_write_end, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* PDU 11 */ - payload_number++; - seg_hdr[2].sc = 1; - seg_hdr[2].cmplt = 0; - seg_hdr[2].timeoffset = 0; - seg_hdr[2].len = 0; - sdu_read_loc += (pdu_write_end - pdu_write_loc); - pdu_hdr_loc = 0; - pdu_write_end = testdata_size - testdata_indx - (pdu_write_end - pdu_write_loc) + - PDU_ISO_SEG_HDR_SIZE; - pdu_write_loc = PDU_ISO_SEG_HDR_SIZE; - sdu_fragments = 1; - - ZASSERT_PDU_WRITE_TEST(history[6], - pdu_buffer[1], - pdu_hdr_loc, - &seg_hdr[2], - PDU_ISO_SEG_HDR_SIZE); - - ZASSERT_PDU_WRITE_TEST(history[7], - pdu_buffer[1], - pdu_write_loc, - &testdata[sdu_read_loc], - (pdu_write_end - pdu_write_loc)); - - seg_hdr[2].cmplt = 1; - seg_hdr[2].len += (pdu_write_end - pdu_write_loc); - - ZASSERT_PDU_WRITE_TEST(history[8], - pdu_buffer[1], - pdu_hdr_loc, - &seg_hdr[2], - PDU_ISO_SEG_HDR_SIZE); - - /* PDU should not be emitted */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(1); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* SDU 2 -------------------------------------------------------------*/ - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[0]); - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - sdu_packet_number++; - event_number += 2; - ref_point += iso_interval_us * 2; - sdu_timestamp += sdu_interval; - testdata_indx = testdata_size; - testdata_size += sdu_fragment_data_size; - - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - sdu_total_size, - sdu_packet_number, - sdu_timestamp, - ref_point, - event_number, - &tx_sdu_frag_buf.sdu_tx); - - err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); - - zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); - - /* Test segmentation (Black Box) */ - /* Valid PDUs */ - /* PDU 11 */ - - ZASSERT_PDU_EMIT_TEST(history[1], - &tx_pdu_meta_buf[1].node_tx, - payload_number, - sdu_fragments, - PDU_BIS_LLID_FRAMED, - pdu_write_end, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* PDU 12 */ - payload_number++; - pdu_event_number++; - pdu_ref_point += iso_interval_us; - seg_hdr[0].sc = 0; - seg_hdr[0].cmplt = 0; - seg_hdr[0].timeoffset = pdu_ref_point - sdu_timestamp; - seg_hdr[0].len = 3; - sdu_read_loc = testdata_indx; - pdu_hdr_loc = 0; - pdu_write_end = testdata_size - testdata_indx + PDU_ISO_SEG_HDR_SIZE + - PDU_ISO_SEG_TIMEOFFSET_SIZE; - pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; - sdu_fragments = 1; - - ZASSERT_PDU_WRITE_TEST(history[9], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[0], - (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE)); - - ZASSERT_PDU_WRITE_TEST(history[10], - pdu_buffer[0], - pdu_write_loc, - &testdata[sdu_read_loc], - (pdu_write_end - pdu_write_loc)); - - seg_hdr[0].cmplt = 1; - seg_hdr[0].len += (pdu_write_end - pdu_write_loc); - - ZASSERT_PDU_WRITE_TEST(history[11], - pdu_buffer[0], - pdu_hdr_loc, - &seg_hdr[0], - PDU_ISO_SEG_HDR_SIZE); - - /* PDU should not be emitted */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(2); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* Send Event Timeout ----------------------------------------------- */ - isoal_tx_event_prepare(source_hdl, pdu_event_number - 1); - - /* PDU should not be emitted */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(2); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* SDU 3 -------------------------------------------------------------*/ - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[1]); - isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf[2]); - isoal_test_init_tx_sdu_buffer(&tx_sdu_frag_buf); - sdu_packet_number++; - event_number += 2; - ref_point += iso_interval_us * 2; - sdu_timestamp += sdu_interval; - sdu_total_size = sdu_fragment_data_size; - testdata_indx = testdata_size; - testdata_size += sdu_fragment_data_size; - - isoal_test_create_sdu_fagment(BT_ISO_SINGLE, - &testdata[testdata_indx], - (testdata_size - testdata_indx), - sdu_total_size, - sdu_packet_number, - sdu_timestamp, - ref_point, - event_number, - &tx_sdu_frag_buf.sdu_tx); - - err = isoal_tx_sdu_fragment(source_hdl, &tx_sdu_frag_buf.sdu_tx); - - zassert_equal(err, ISOAL_STATUS_OK, "err = 0x%02x", err); - - /* Test segmentation (Black Box) */ - /* Valid PDUs */ - /* PDU 12 */ - ZASSERT_PDU_EMIT_TEST(history[2], - &tx_pdu_meta_buf[0].node_tx, - payload_number, - sdu_fragments, - PDU_BIS_LLID_FRAMED, - pdu_write_end, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU 13 */ - payload_number++; - - /* Padding PDU */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(4); - ZASSERT_PDU_EMIT_TEST(history[3], - &tx_pdu_meta_buf[1].node_tx, - payload_number, - 0, - PDU_BIS_LLID_FRAMED, - 0, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* PDU 14 */ - payload_number++; - pdu_event_number++; - pdu_ref_point += iso_interval_us; - seg_hdr[1].sc = 0; - seg_hdr[1].cmplt = 0; - seg_hdr[1].timeoffset = pdu_ref_point - sdu_timestamp; - seg_hdr[1].len = 3; - sdu_read_loc = testdata_indx; - pdu_hdr_loc = 0; - pdu_write_end = testdata_size - testdata_indx + PDU_ISO_SEG_HDR_SIZE + - PDU_ISO_SEG_TIMEOFFSET_SIZE; - pdu_write_loc = PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE; - sdu_fragments = 1; - - ZASSERT_PDU_WRITE_TEST(history[12], - pdu_buffer[2], - pdu_hdr_loc, - &seg_hdr[1], - PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE); - - ZASSERT_PDU_WRITE_TEST(history[13], - pdu_buffer[2], - pdu_write_loc, - &testdata[sdu_read_loc], - (pdu_write_end - pdu_write_loc)); - - seg_hdr[1].cmplt = 1; - seg_hdr[1].len += (pdu_write_end - pdu_write_loc); - - ZASSERT_PDU_WRITE_TEST(history[14], - pdu_buffer[2], - pdu_hdr_loc, - &seg_hdr[1], - PDU_ISO_SEG_HDR_SIZE); - - /* PDU should not be emitted */ - ZASSERT_PDU_EMIT_TEST_CALL_COUNT(4); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); - - /* Send Event Timeout ----------------------------------------------- */ - isoal_tx_event_prepare(source_hdl, pdu_event_number); - - - ZASSERT_PDU_EMIT_TEST(history[4], - &tx_pdu_meta_buf[2].node_tx, - payload_number, - sdu_fragments, - PDU_BIS_LLID_FRAMED, - pdu_write_end, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU 5 */ - payload_number++; - - /* Padding PDU */ - ZASSERT_PDU_EMIT_TEST(history[5], - &tx_pdu_meta_buf[0].node_tx, - payload_number, - 0, - PDU_BIS_LLID_FRAMED, - 0, - isoal_global.source_state[source_hdl].session.handle); - - /* PDU release not expected (No Error) */ - ZASSERT_PDU_RELEASE_TEST_CALL_COUNT(0); -} - /** * Test Suite : TX framed EBQ test IAL-CIS-FRA-PER-BV07C * @@ -7657,8 +7173,8 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) max_octets = TEST_TX_PDU_PAYLOAD_MAX + 5; BN = 1; FT = 1; - stream_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 200; - group_sync_delay = (iso_interval_int * ISO_INT_UNIT_US) - 50; + stream_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 200; + group_sync_delay = (iso_interval_int * CONN_INT_UNIT_US) - 50; /* SDU 1 Frag 1 ------------------------------------------------------*/ isoal_test_init_tx_pdu_buffer(&tx_pdu_meta_buf); @@ -7671,7 +7187,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) sdu_packet_number = 0; event_number = 0; sdu_timestamp = 9249; - ref_point = sdu_timestamp + (iso_interval_int * ISO_INT_UNIT_US) - 50; + ref_point = sdu_timestamp + (iso_interval_int * CONN_INT_UNIT_US) - 50; sdu_total_size = 10; testdata_indx = 0; testdata_size = 10; @@ -7834,7 +7350,7 @@ ZTEST(test_tx_framed_ebq, test_tx_framed_cis_fra_per_bv07c) event_number++; sdu_packet_number++; sdu_timestamp = sdu_timestamp + sdu_interval; - ref_point = ref_point + (iso_interval_int * ISO_INT_UNIT_US); + ref_point = ref_point + (iso_interval_int * CONN_INT_UNIT_US); sdu_total_size = 20; testdata_indx = testdata_size; testdata_size += 20; From a3204b3b44662a328ba4f90b6760e341ec09fb92 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:52 +0000 Subject: [PATCH 4154/4498] Revert "[nrf fromtree] soc nordic_nrf: Select new compatible kconfig options" This reverts commit ff4e15ae36af8fc8abe680e8a418f882d97e731d. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/Kconfig.series | 1 - soc/arm/nordic_nrf/nrf53/Kconfig.soc | 2 -- 2 files changed, 3 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.series b/soc/arm/nordic_nrf/nrf53/Kconfig.series index 8ab81ad310b..03e47bacf63 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.series @@ -6,7 +6,6 @@ config SOC_SERIES_NRF53X bool "Nordic Semiconductor nRF53 series MCU" select ARM - select SOC_COMPATIBLE_NRF53X select CPU_CORTEX_M33 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 87d8a6d0c7a..2ad4a7add66 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -10,13 +10,11 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_FPU select ARMV8_M_DSP select HAS_POWEROFF - select SOC_COMPATIBLE_NRF5340_CPUAPP imply SOC_NRF53_RTC_PRETICK config SOC_NRF5340_CPUNET bool select ARM_ON_EXIT_CPU_IDLE - select SOC_COMPATIBLE_NRF5340_CPUNET imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED imply SOC_NRF53_RTC_PRETICK if !WDT_NRFX From 7fbab865f66d50e41b14a738975193501bf35eac Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:52 +0000 Subject: [PATCH 4155/4498] Revert "[nrf fromtree] nrf5x_bsim: Add helper kconfig symbols for simulated nrf5340" This reverts commit 7b202de62b4f1ed8938747b4664972b02b565942. Signed-off-by: Dominik Ermel --- boards/posix/nrf52_bsim/Kconfig | 6 ------ soc/Kconfig | 12 ++---------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/boards/posix/nrf52_bsim/Kconfig b/boards/posix/nrf52_bsim/Kconfig index 566520fafa0..ea1b49bea0a 100644 --- a/boards/posix/nrf52_bsim/Kconfig +++ b/boards/posix/nrf52_bsim/Kconfig @@ -26,9 +26,3 @@ config SOC_SERIES_BSIM_NRF52X depends on SOC_SERIES_BSIM_NRFXX help Any NRF52 simulated SOC with BabbleSim, based on the POSIX arch - -config SOC_SERIES_BSIM_NRF53X - bool - depends on SOC_SERIES_BSIM_NRFXX - help - Any NRF53 simulated SOC with BabbleSim, based on the POSIX arch diff --git a/soc/Kconfig b/soc/Kconfig index 33c2d0c29a4..20734c0f51f 100644 --- a/soc/Kconfig +++ b/soc/Kconfig @@ -24,7 +24,8 @@ source "subsys/logging/Kconfig.template.log_config" endmenu # The helper symbols below are put here due to an unusual setup: The simulated -# nrf5x_bsim boards use the POSIX arch, but are compatible with Nordic ARM boards +# nrf52_bsim board uses the POSIX arch, but is compatible with Nordic ARM +# boards config SOC_COMPATIBLE_NRF bool @@ -32,18 +33,9 @@ config SOC_COMPATIBLE_NRF config SOC_COMPATIBLE_NRF52X bool -config SOC_COMPATIBLE_NRF53X - bool - config SOC_COMPATIBLE_NRF52833 bool -config SOC_COMPATIBLE_NRF5340_CPUNET - bool - -config SOC_COMPATIBLE_NRF5340_CPUAPP - bool - # # SOC_*_LD: SoC specific Linker script additions # From f83c39718f7d041d7584c03a6202d580fba70563 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:53 +0000 Subject: [PATCH 4156/4498] Revert "[nrf fromtree] Test: Bluetooth: controller: add CI testing for advertising chaining" This reverts commit 96efa92108ad91cec08e0c23b557433cfc0d6ddb. Signed-off-by: Dominik Ermel --- .../broadcaster_multiple/src/broadcaster_multiple.c | 10 +--------- tests/bsim/bluetooth/host/adv/chain/prj.conf | 6 +++--- tests/bsim/bluetooth/host/adv/chain/src/main.c | 10 +--------- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c index 30fe35d3dec..d1c6d792e95 100644 --- a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c +++ b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c @@ -47,18 +47,11 @@ BT_AD_DATA_FORMAT_LEN_SIZE - \ BT_AD_DATA_FORMAT_TYPE_SIZE - \ BT_DEVICE_NAME_AD_DATA_LEN))) -/* - * Datalength is an integer, so BT_MFG_DATA_LEN can not be larger than 255. - * To ensure that we need to chain PDUs we therefore add manufacturer data - * twice when chaining is enabled - */ + static uint8_t mfg_data[BT_MFG_DATA_LEN] = { 0xFF, 0xFF, }; static const struct bt_data ad[] = { BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), -#if defined(CONFIG_BT_CTLR_ADV_DATA_CHAIN) - BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)), -#endif }; static struct bt_le_ext_adv *adv[CONFIG_BT_EXT_ADV_MAX_ADV_SET]; @@ -82,7 +75,6 @@ int broadcaster_multiple(void) printk("Bluetooth init failed (err %d)\n", err); return err; } - for (int index = 0; index < CONFIG_BT_EXT_ADV_MAX_ADV_SET; index++) { /* Use advertising set instance index as SID */ adv_param.sid = index; diff --git a/tests/bsim/bluetooth/host/adv/chain/prj.conf b/tests/bsim/bluetooth/host/adv/chain/prj.conf index 82eb16e5db0..85861dccd66 100644 --- a/tests/bsim/bluetooth/host/adv/chain/prj.conf +++ b/tests/bsim/bluetooth/host/adv/chain/prj.conf @@ -30,9 +30,9 @@ CONFIG_BT_EXT_SCAN_BUF_SIZE=1650 # Set maximum scan data length for Extended Scanning in Bluetooth LE Controller CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 -# The Zephyr Controller does not combine all the 1650 bytes before -# fragmenting into 8 HCI reports, if a PDU has 255 bytes, -# it will generate 2 HCI reports and so we need to reserve 16 buffers +# Zephyr Controller does not combine all the 1650 bytes before fragmenting them +# into 8 HCI reports, if a PDU has 255 bytes, it will generate 2 HCI reports +# and so we need to reserve 16 buffers CONFIG_BT_BUF_EVT_RX_COUNT=16 # Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain diff --git a/tests/bsim/bluetooth/host/adv/chain/src/main.c b/tests/bsim/bluetooth/host/adv/chain/src/main.c index d58d2a3890f..4475a069535 100644 --- a/tests/bsim/bluetooth/host/adv/chain/src/main.c +++ b/tests/bsim/bluetooth/host/adv/chain/src/main.c @@ -34,12 +34,8 @@ #define NAME_LEN 30 #define BT_AD_DATA_NAME_SIZE (sizeof(CONFIG_BT_DEVICE_NAME) - 1U + 2U) #define BT_AD_DATA_MFG_DATA_SIZE (254U + 2U) -/* - * for testing chaining the manufacturing data is duplicated, hence DATA_LEN needs to - * add twice the size for this element - */ #define DATA_LEN MIN((BT_AD_DATA_NAME_SIZE + \ - BT_AD_DATA_MFG_DATA_SIZE + BT_AD_DATA_MFG_DATA_SIZE), \ + BT_AD_DATA_MFG_DATA_SIZE), \ CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) static K_SEM_DEFINE(sem_recv, 0, 1); @@ -98,7 +94,6 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, data_len = buf->len; if (data_len != DATA_LEN) { - printk("Received datalength: %d\n", data_len); return; } @@ -106,13 +101,11 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, bt_data_parse(buf, data_cb, name); if (strcmp(name, CONFIG_BT_DEVICE_NAME)) { - printk("Wrong name %s\n", name); return; } for (uint8_t i = 0; i < sid_count; i++) { if (sid[i] == info->sid) { - printk("Received SID %d\n", info->sid); return; } } @@ -120,7 +113,6 @@ static void scan_recv(const struct bt_le_scan_recv_info *info, sid[sid_count++] = info->sid; if (sid_count < CONFIG_BT_EXT_ADV_MAX_ADV_SET) { - printk("Received advertising sets: %d\n", sid_count); return; } From d8e69fe789f395c7901aae0d1d2a545be0002410 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:53 +0000 Subject: [PATCH 4157/4498] Revert "[nrf fromtree] Bluetooth: controller: change calc for data in PDU" This reverts commit 8eefe7f80331b72b2bcf00113684fb60fbad906f. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/ll_sw/ull_adv_aux.c | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 2480c286e4b..0754a047207 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -411,9 +411,13 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, /* We could not fit all the data, append as much as possible * ad_len_overflow is how much overflows with the AUX ptr */ + uint8_t ad_len_overflow_first_try; const uint16_t chain_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND | ULL_ADV_PDU_HDR_FIELD_AUX_PTR; + ad_len_overflow_first_try = hdr_data[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + val_ptr = hdr_data; *val_ptr++ = len; (void)memcpy(val_ptr, &data, sizeof(data)); @@ -423,18 +427,18 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, chain_add_fields, 0U, hdr_data); - ad_len_chain = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + - ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + - ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - - /* len is the total amount of datawe want to add - * ad_len_chain is the amount of data that does - * not fit in the current PDU - * the difference of the two is the amount that - * we can fit in the current PDU + ad_len_overflow = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + + ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + + ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + + /* ad_len_overflow - ad_len_overflow_first_try is the size of + * the aux pointer + * ad_len_prev is how much data is already present, ad_len is how + * much data we can add to this PDU */ - ad_len = len - ad_len_chain; + ad_len = PDU_AC_PAYLOAD_SIZE_MAX - ad_len_prev - + (ad_len_overflow - ad_len_overflow_first_try) - 4; val_ptr = hdr_data; *val_ptr++ = ad_len; @@ -453,10 +457,9 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, /* * in the next PDU we still need to add ad_len_chain bytes of data * but we do not have overflow, since we already added - * the exact amount that would fit. We explicitly set overflow to 0. - * FIXME: ad_len_overflow already should be 0, to be verified. We wait - * fixing this until rewriting this whole function + * the exact amount that would fit */ + ad_len_chain = len - ad_len; ad_len_overflow = 0U; } else { ad_len_overflow = 0U; From 2b4f365210aaf1caa7a71b880b7bd9b0a7655f2d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:53 +0000 Subject: [PATCH 4158/4498] Revert "[nrf fromtree] Bluetooth: controller: fix failing EBQ advertising tests" This reverts commit 68a8baa59b3e58f0e88623996868009d4e5f3741. Signed-off-by: Dominik Ermel --- .../src/broadcaster_multiple.c | 1 + .../bluetooth/controller/ll_sw/ull_adv_aux.c | 154 ++++++------------ tests/bsim/bluetooth/host/adv/chain/prj.conf | 5 +- 3 files changed, 49 insertions(+), 111 deletions(-) diff --git a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c index d1c6d792e95..56cc210de78 100644 --- a/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c +++ b/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c @@ -75,6 +75,7 @@ int broadcaster_multiple(void) printk("Bluetooth init failed (err %d)\n", err); return err; } + for (int index = 0; index < CONFIG_BT_EXT_ADV_MAX_ADV_SET; index++) { /* Use advertising set instance index as SID */ adv_param.sid = index; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 0754a047207..302dc6da785 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -117,7 +117,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t ad_len_overflow; uint8_t ad_len_chain; struct pdu_adv *pdu; - uint8_t ad_len = 0U; #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */ /* Get the advertising set instance */ @@ -302,7 +301,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, struct pdu_adv *pdu_chain_prev; struct pdu_adv *pdu_chain; uint16_t ad_len_total; - uint8_t ad_len_prev = 0U; + uint8_t ad_len_prev; /* Traverse to next set clear hdr data parameter */ val_ptr += sizeof(data); @@ -318,23 +317,29 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ad_len_total = 0U; pdu_chain_prev = pdu_prev; pdu_chain = pdu; - /* make a copy of the previous chain, until we reach the end */ do { - val_ptr = hdr_data; - *val_ptr++ = 0U; - (void)memset((void *)val_ptr, 0U, - ULL_ADV_HDR_DATA_DATA_PTR_SIZE); + /* Prepare for aux ptr field reference to be returned, hence + * second parameter will be for AD data field. + */ + *val_ptr = 0U; + (void)memset((void *)&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET], + 0U, ULL_ADV_HDR_DATA_DATA_PTR_SIZE); pdu_prev = pdu_chain_prev; pdu = pdu_chain; + /* Add Aux Ptr field if not already present */ err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, - ULL_ADV_PDU_HDR_FIELD_AD_DATA, - 0U, hdr_data); - ad_len_prev = hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET]; - + (ULL_ADV_PDU_HDR_FIELD_AD_DATA | + ULL_ADV_PDU_HDR_FIELD_AUX_PTR), + 0, hdr_data); LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG)); + /* Get PDUs previous AD data length */ + ad_len_prev = + hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + + ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE]; + /* Check of max supported AD data len */ ad_len_total += ad_len_prev; if ((ad_len_total + len) > @@ -360,10 +365,31 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, (!pdu_chain_prev && !pdu_chain)); } while (pdu_chain_prev); - /* No AD data overflow */ - ad_len_overflow = 0U; - /* No AD data in chain PDU */ - ad_len_chain = 0U; + if (err == BT_HCI_ERR_PACKET_TOO_LONG) { + ad_len_overflow = + hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + + ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + + ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + + ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; + + /* Prepare for aux ptr field reference to be returned, + * hence second parameter will be for AD data field. + * Fill it with reduced AD data length. + */ + *val_ptr = ad_len_prev - ad_len_overflow; + + /* AD data len in chain PDU */ + ad_len_chain = len; + + /* Proceed to add chain PDU */ + err = 0U; + } else { + /* No AD data overflow */ + ad_len_overflow = 0U; + + /* No AD data in chain PDU */ + ad_len_chain = 0U; + } } #else /* !CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */ } else { @@ -385,88 +411,8 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) if ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) || - (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) { - /* in the previous step we duplicated the chain - * the next step is to append new data in the last existing pdu in the chain, - */ - - uint8_t chain_err = 0U; - - val_ptr = hdr_data; - *val_ptr++ = len; - (void)memcpy(val_ptr, &data, sizeof(data)); - - /* Append data to the last PDU */ - chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, - ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND, - 0U, hdr_data); - - LL_ASSERT((!chain_err) || (chain_err == BT_HCI_ERR_PACKET_TOO_LONG)); - - /* FIXME: the code has become quite complex, an alternative and simpler - * implementation would be to first fill an array with all data that - * must be send, and create the chained PDUs from this array - */ - if (chain_err == BT_HCI_ERR_PACKET_TOO_LONG) { - /* We could not fit all the data, append as much as possible - * ad_len_overflow is how much overflows with the AUX ptr - */ - uint8_t ad_len_overflow_first_try; - const uint16_t chain_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND | - ULL_ADV_PDU_HDR_FIELD_AUX_PTR; - - ad_len_overflow_first_try = hdr_data[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - - val_ptr = hdr_data; - *val_ptr++ = len; - (void)memcpy(val_ptr, &data, sizeof(data)); - val_ptr += sizeof(data); - *val_ptr++ = len; - (void)memcpy(val_ptr, &data, sizeof(data)); - chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, - chain_add_fields, - 0U, hdr_data); - ad_len_overflow = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET + - ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE + - ULL_ADV_HDR_DATA_DATA_PTR_OFFSET + - ULL_ADV_HDR_DATA_DATA_PTR_SIZE]; - - /* ad_len_overflow - ad_len_overflow_first_try is the size of - * the aux pointer - * ad_len_prev is how much data is already present, ad_len is how - * much data we can add to this PDU - */ - ad_len = PDU_AC_PAYLOAD_SIZE_MAX - ad_len_prev - - (ad_len_overflow - ad_len_overflow_first_try) - 4; - - val_ptr = hdr_data; - *val_ptr++ = ad_len; - (void)memcpy(val_ptr, &data, sizeof(data)); - val_ptr += sizeof(data); - *val_ptr++ = ad_len; - (void)memcpy(val_ptr, &data, sizeof(data)); - - /* we now know how much data we can add to the - * last PDU without getting an overflow - */ - chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu, - chain_add_fields, - 0U, hdr_data); - LL_ASSERT(chain_err == 0U); - /* - * in the next PDU we still need to add ad_len_chain bytes of data - * but we do not have overflow, since we already added - * the exact amount that would fit - */ - ad_len_chain = len - ad_len; - ad_len_overflow = 0U; - } else { - ad_len_overflow = 0U; - } - } - - if (ad_len_chain || ad_len_overflow) { + (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG) || + ad_len_overflow) { struct pdu_adv_com_ext_adv *com_hdr_chain; struct pdu_adv_com_ext_adv *com_hdr; struct pdu_adv_ext_hdr *hdr_chain; @@ -479,7 +425,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint16_t sec_len; uint8_t *dptr; - len = ad_len_chain; /* Get reference to flags in superior PDU */ com_hdr = &pdu->adv_ext_ind; if (com_hdr->ext_hdr_len) { @@ -505,7 +450,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0]; dptr_chain = (void *)hdr_chain; - LL_ASSERT(dptr_chain); /* Flags */ *dptr_chain = 0U; @@ -554,7 +498,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, if (ad_len_overflow) { uint8_t *ad_overflow; - val_ptr = hdr_data; /* Copy overflowed AD data from previous PDU into this * new chain PDU */ @@ -562,7 +505,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, &val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET], sizeof(ad_overflow)); ad_overflow += *val_ptr; - (void)memcpy(dptr_chain, ad_overflow, ad_len_overflow); dptr_chain += ad_len_overflow; @@ -587,6 +529,8 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, return err; } + /* AD data len in chain PDU besides the overflow */ + len = ad_len_chain; } /* Check AdvData overflow */ @@ -611,13 +555,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, pdu_chain->len = sec_len + ad_len_overflow + len; /* Fill AD Data in chain PDU */ - if (ad_len_overflow != 0U) { - (void)memcpy(dptr_chain, data, ad_len_overflow); - } - - if (ad_len_chain != 0U) { - (void)memcpy(dptr_chain, &data[ad_len + ad_len_overflow], ad_len_chain); - } + (void)memcpy(dptr_chain, data, len); /* Get reference to aux ptr in superior PDU */ (void)memcpy(&aux_ptr, diff --git a/tests/bsim/bluetooth/host/adv/chain/prj.conf b/tests/bsim/bluetooth/host/adv/chain/prj.conf index 85861dccd66..3e7f11009c2 100644 --- a/tests/bsim/bluetooth/host/adv/chain/prj.conf +++ b/tests/bsim/bluetooth/host/adv/chain/prj.conf @@ -30,9 +30,8 @@ CONFIG_BT_EXT_SCAN_BUF_SIZE=1650 # Set maximum scan data length for Extended Scanning in Bluetooth LE Controller CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 -# Zephyr Controller does not combine all the 1650 bytes before fragmenting them -# into 8 HCI reports, if a PDU has 255 bytes, it will generate 2 HCI reports -# and so we need to reserve 16 buffers +# Zephyr Bluetooth LE Controller needs 16 event buffers to generate Extended +# Advertising Report for receiving the complete 1650 bytes of data CONFIG_BT_BUF_EVT_RX_COUNT=16 # Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain From fe9faf985bf62abfd7d1451b6f6f93c7a08e2b6b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:53 +0000 Subject: [PATCH 4159/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix leak in scheduled ticker node" This reverts commit 730249a34382716d6593e50bbd03aa0c3c1561ac. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ticker/ticker.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index 83bd6437d59..9b5bb53a625 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -2337,7 +2337,6 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, while (rescheduling) { struct ticker_node *ticker_resched; uint32_t ticks_to_expire_offset; - uint8_t ticker_id_resched_prev; struct ticker_ext *ext_data; uint32_t ticks_start_offset; uint32_t window_start_ticks; @@ -2351,7 +2350,6 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, rescheduling = 0U; /* Find first pending re-schedule */ - ticker_id_resched_prev = TICKER_NULL; ticker_id_resched = instance->ticker_id_head; while (ticker_id_resched != TICKER_NULL) { ticker_resched = &nodes[ticker_id_resched]; @@ -2359,8 +2357,6 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, /* Pending reschedule found */ break; } - - ticker_id_resched_prev = ticker_id_resched; ticker_id_resched = ticker_resched->next; } if (ticker_id_resched == TICKER_NULL) { @@ -2540,15 +2536,13 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, /* If the node moved in the list, insert it */ if (ticker_id_prev != TICKER_NULL) { - /* Remove node from its current position in list */ - if (ticker_id_resched_prev != TICKER_NULL) { - /* Node was not at the head of the list */ - nodes[ticker_id_resched_prev].next = - ticker_resched->next; - } else { - /* Node was at the head, move head forward */ - instance->ticker_id_head = ticker_resched->next; - } + LL_ASSERT(instance->ticker_id_head == + ticker_id_resched); + + /* Node did not become the first - update head and + * insert node after 'previous' + */ + instance->ticker_id_head = ticker_resched->next; /* Link inserted node */ ticker_resched->next = nodes[ticker_id_prev].next; From a0783e31a298e059fec430318a29671b7b2f91bf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:53 +0000 Subject: [PATCH 4160/4498] Revert "[nrf fromtree] Bluetooth: Controller: Rename ticker reschedule variables" This reverts commit 2b86f49ef42aec7d80c2842da5dc6414d0b0ecc1. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ticker/ticker.c | 123 +++++++++----------- 1 file changed, 54 insertions(+), 69 deletions(-) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index 9b5bb53a625..e5c89dca905 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -2326,46 +2326,43 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, uint32_t ticks_elapsed) { struct ticker_node *nodes; - uint8_t rescheduling; - uint8_t rescheduled; + uint8_t rescheduling = 1U; + uint8_t rescheduled = 0U; nodes = &instance->nodes[0]; /* Do until all pending re-schedules handled */ - rescheduling = 1U; - rescheduled = 0U; while (rescheduling) { - struct ticker_node *ticker_resched; - uint32_t ticks_to_expire_offset; + uint32_t ticks_to_expire_offset = 0U; + uint32_t ticks_start_offset = 0U; + uint32_t window_start_ticks = 0U; + uint32_t ticks_slot_window = 0U; + uint32_t ticks_to_expire = 0U; struct ticker_ext *ext_data; - uint32_t ticks_start_offset; - uint32_t window_start_ticks; - uint32_t ticks_slot_window; - uint8_t ticker_id_resched; - uint32_t ticks_to_expire; + struct ticker_node *ticker; + uint8_t ticker_id_head; uint8_t ticker_id_prev; - uint8_t ticker_id_next; + uint8_t ticker_id_iter; uint32_t ticks_slot; rescheduling = 0U; /* Find first pending re-schedule */ - ticker_id_resched = instance->ticker_id_head; - while (ticker_id_resched != TICKER_NULL) { - ticker_resched = &nodes[ticker_id_resched]; - if (TICKER_RESCHEDULE_PENDING(ticker_resched)) { + ticker_id_head = instance->ticker_id_head; + while (ticker_id_head != TICKER_NULL) { + ticker = &nodes[ticker_id_head]; + if (TICKER_RESCHEDULE_PENDING(ticker)) { /* Pending reschedule found */ break; } - ticker_id_resched = ticker_resched->next; + ticker_id_head = ticker->next; } - if (ticker_id_resched == TICKER_NULL) { + if (ticker_id_head == TICKER_NULL) { /* Done */ break; } /* Check for intersection with already active node */ - window_start_ticks = 0U; if (instance->ticks_slot_previous > ticks_elapsed) { /* Active node intersects - window starts after end of * active slot @@ -2374,7 +2371,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, ticks_elapsed; } - ticker_id_next = ticker_resched->next; + ticker_id_iter = nodes[ticker_id_head].next; /* If drift was applied to this node, this must be * taken into consideration. Reduce the window with @@ -2385,50 +2382,43 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, * ticker would have the best possible window to re-schedule in * and not be restricted to ticks_slot_window - ticks_drift. */ - ext_data = ticker_resched->ext_data; + ext_data = ticker->ext_data; if (ext_data->ticks_drift < ext_data->ticks_slot_window) { ticks_slot_window = ext_data->ticks_slot_window - ext_data->ticks_drift; } else { /* Window has been exhausted - we can't reschedule */ - ticker_id_next = TICKER_NULL; - - /* Assignment will be unused when TICKER_NULL */ - ticks_slot_window = 0U; + ticker_id_iter = TICKER_NULL; } /* Use ticker's reserved time ticks_slot, else for unreserved * tickers use the reschedule margin as ticks_slot. */ - if (ticker_resched->ticks_slot) { - ticks_slot = ticker_resched->ticks_slot; + if (ticker->ticks_slot) { + ticks_slot = ticker->ticks_slot; } else { - LL_ASSERT(TICKER_HAS_SLOT_WINDOW(ticker_resched)); + LL_ASSERT(TICKER_HAS_SLOT_WINDOW(ticker)); ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN; } /* Try to find available slot for re-scheduling */ - ticks_to_expire_offset = 0U; - ticks_start_offset = 0U; - ticks_to_expire = 0U; - while ((ticker_id_next != TICKER_NULL) && + while ((ticker_id_iter != TICKER_NULL) && ((ticks_start_offset + ticks_slot) <= ticks_slot_window)) { - struct ticker_node *ticker_next; - uint32_t window_end_ticks; + uint32_t window_end_ticks = 0U; + struct ticker_node *node; - ticker_next = &nodes[ticker_id_next]; - ticks_to_expire_offset += ticker_next->ticks_to_expire; + node = &nodes[ticker_id_iter]; + ticks_to_expire_offset += node->ticks_to_expire; /* Skip other pending re-schedule nodes and * tickers with no reservation or not periodic */ - if (TICKER_RESCHEDULE_PENDING(ticker_next) || - !ticker_next->ticks_slot || - !ticker_next->ticks_periodic) { - ticker_id_next = ticker_next->next; - + if (TICKER_RESCHEDULE_PENDING(node) || + !node->ticks_slot || + !node->ticks_periodic) { + ticker_id_iter = node->next; continue; } @@ -2454,7 +2444,7 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, */ if (window_end_ticks > (ticks_start_offset + ticks_slot)) { - if (!ticker_resched->ticks_slot) { + if (!ticker->ticks_slot) { /* Place at start of window */ ticks_to_expire = window_start_ticks; } else { @@ -2487,10 +2477,10 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, */ ticks_start_offset += ticks_to_expire_offset; window_start_ticks = ticks_start_offset + - ticker_next->ticks_slot; + node->ticks_slot; ticks_to_expire_offset = 0U; - if (!ticker_resched->ticks_slot) { + if (!ticker->ticks_slot) { /* Try at the end of the next node */ ticks_to_expire = window_start_ticks; } else { @@ -2503,61 +2493,56 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance, ticks_slot; } - ticker_id_next = ticker_next->next; + ticker_id_iter = node->next; } ext_data->ticks_drift += ticks_to_expire - - ticker_resched->ticks_to_expire; - ticker_resched->ticks_to_expire = ticks_to_expire; + ticker->ticks_to_expire; + ticker->ticks_to_expire = ticks_to_expire; + ticker_id_iter = nodes[ticker_id_head].next; + ticker_id_prev = TICKER_NULL; /* Place the ticker node sorted by expiration time and adjust * delta times */ - ticker_id_next = ticker_resched->next; - ticker_id_prev = TICKER_NULL; - while (ticker_id_next != TICKER_NULL) { - struct ticker_node *ticker_next; + while (ticker_id_iter != TICKER_NULL) { + struct ticker_node *node; - ticker_next = &nodes[ticker_id_next]; - if (ticker_resched->ticks_to_expire > - ticker_next->ticks_to_expire) { + node = &nodes[ticker_id_iter]; + if (ticker->ticks_to_expire > node->ticks_to_expire) { /* Node is after this - adjust delta */ - ticker_resched->ticks_to_expire -= - ticker_next->ticks_to_expire; + ticker->ticks_to_expire -= + node->ticks_to_expire; } else { /* Node is before this one */ - ticker_next->ticks_to_expire -= - ticker_resched->ticks_to_expire; + node->ticks_to_expire -= + ticker->ticks_to_expire; break; } - ticker_id_prev = ticker_id_next; - ticker_id_next = ticker_next->next; + ticker_id_prev = ticker_id_iter; + ticker_id_iter = node->next; } - /* If the node moved in the list, insert it */ if (ticker_id_prev != TICKER_NULL) { - LL_ASSERT(instance->ticker_id_head == - ticker_id_resched); - /* Node did not become the first - update head and * insert node after 'previous' */ - instance->ticker_id_head = ticker_resched->next; + instance->ticker_id_head = nodes[ticker_id_head].next; /* Link inserted node */ - ticker_resched->next = nodes[ticker_id_prev].next; - nodes[ticker_id_prev].next = ticker_id_resched; + nodes[ticker_id_head].next = nodes[ticker_id_prev].next; + nodes[ticker_id_prev].next = ticker_id_head; } /* Remove latency added in ticker_worker */ - ticker_resched->lazy_current--; + ticker->lazy_current--; /* Prevent repeated re-scheduling */ ext_data->reschedule_state = TICKER_RESCHEDULE_STATE_DONE; #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) - ticker_mark_expire_info_outdated(instance, ticker_id_resched); + ticker_mark_expire_info_outdated(instance, ticker_id_head); #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ /* Check for other pending re-schedules and set exit flag */ From bdd75c8f0e396799b29865b1caa47d61fd495ef7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:54 +0000 Subject: [PATCH 4161/4498] Revert "[nrf fromtree] Bluetooth: Controller: Remove legacy BT_CTLR_FAST_ENC option" This reverts commit 009025d45d384fd1eacf3669c9a859627058b684. Signed-off-by: Dominik Ermel --- drivers/entropy/entropy_nrf5.c | 5 +++++ drivers/entropy/entropy_smartbond.c | 5 +++++ drivers/entropy/entropy_stm32.c | 9 ++++++++- subsys/bluetooth/controller/Kconfig.ll_sw_split | 12 ++++++++++++ tests/bluetooth/init/prj_ctlr_4_0.conf | 1 + tests/bluetooth/init/prj_ctlr_4_0_dbg.conf | 1 + tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 1 + tests/bluetooth/init/prj_ctlr_dbg.conf | 1 + tests/bluetooth/init/prj_ctlr_ticker.conf | 1 + tests/bluetooth/init/prj_ctlr_tiny.conf | 1 + 10 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_nrf5.c b/drivers/entropy/entropy_nrf5.c index 2f04bc06a37..8febcfacb15 100644 --- a/drivers/entropy/entropy_nrf5.c +++ b/drivers/entropy/entropy_nrf5.c @@ -116,6 +116,10 @@ static int random_byte_get(void) return retval; } +#pragma GCC push_options +#if defined(CONFIG_BT_CTLR_FAST_ENC) +#pragma GCC optimize ("Ofast") +#endif static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -171,6 +175,7 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) return len; } +#pragma GCC pop_options static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/drivers/entropy/entropy_smartbond.c b/drivers/entropy/entropy_smartbond.c index 28b6f08e100..0058baafce5 100644 --- a/drivers/entropy/entropy_smartbond.c +++ b/drivers/entropy/entropy_smartbond.c @@ -100,6 +100,10 @@ static int random_word_get(uint8_t buf[4]) return retval; } +#pragma GCC push_options +#if defined(CONFIG_BT_CTLR_FAST_ENC) +#pragma GCC optimize("Ofast") +#endif static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -155,6 +159,7 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) return len; } +#pragma GCC pop_options static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 7c342a09c23..9f2ad136203 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -377,7 +377,13 @@ static void pool_filling_work_handler(struct k_work *work) } } -static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, +#if defined(CONFIG_BT_CTLR_FAST_ENC) +#define __fast __attribute__((optimize("Ofast"))) +#else +#define __fast +#endif + +__fast static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, uint16_t len) { uint32_t last = rngp->last; @@ -442,6 +448,7 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, return len; } +#undef __fast static int rng_pool_put(struct rng_pool *rngp, uint8_t byte) { diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index e2975107f86..a7dade7a1db 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -760,6 +760,18 @@ config BT_CTLR_PARAM_CHECK if BT_CONN +config BT_CTLR_FAST_ENC + bool "Fast Encryption Setup" + depends on BT_CTLR_LE_ENC + default y if BT_HCI_RAW + help + Enable connection encryption setup in 4 connection events. + Peripheral will respond to Encryption Request with Encryption Response + in the next connection event, and will transmit Start Encryption + Request PDU in the same connection event, hence completing encryption + setup in 4 connection events. Encrypted data would be transmitted as + fast as in 4th connection event from Encryption Request. + config BT_CTLR_LLCP_CONN int "Number of connections with worst-case overlapping procedures" default BT_MAX_CONN diff --git a/tests/bluetooth/init/prj_ctlr_4_0.conf b/tests/bluetooth/init/prj_ctlr_4_0.conf index 4f9ec70d3bb..ff3917be54b 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0.conf @@ -19,6 +19,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=y CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y +CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n diff --git a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf index 5fc61cf98c6..4c101cc6e16 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf @@ -21,6 +21,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=y CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y +CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf index 50f72889476..df0d006a13e 100644 --- a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf @@ -29,6 +29,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=y CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n +CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_dbg.conf b/tests/bluetooth/init/prj_ctlr_dbg.conf index 2f8224cdfea..6aff0965ce9 100644 --- a/tests/bluetooth/init/prj_ctlr_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_dbg.conf @@ -23,6 +23,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n +CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf index 4e5b962231e..d77f519406b 100644 --- a/tests/bluetooth/init/prj_ctlr_ticker.conf +++ b/tests/bluetooth/init/prj_ctlr_ticker.conf @@ -23,6 +23,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y CONFIG_BT_CTLR_TIFS_HW=n +CONFIG_BT_CTLR_FAST_ENC=y CONFIG_BT_CTLR_TX_RETRY_DISABLE=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_ADV_INDICATION=y diff --git a/tests/bluetooth/init/prj_ctlr_tiny.conf b/tests/bluetooth/init/prj_ctlr_tiny.conf index ce75583da16..7679de9a661 100644 --- a/tests/bluetooth/init/prj_ctlr_tiny.conf +++ b/tests/bluetooth/init/prj_ctlr_tiny.conf @@ -22,6 +22,7 @@ CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_SCHED_ADVANCED=n CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n CONFIG_BT_CTLR_TIFS_HW=y +CONFIG_BT_CTLR_FAST_ENC=n CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n From fb0d500cd1fd5304ff35bdbdc58647d99a1a1bc5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:54 +0000 Subject: [PATCH 4162/4498] Revert "[nrf fromtree] Bluetooth: Controller: Add hdl checks in isoal.c" This reverts commit cc06a1088c2186089719036a62762adb9a2d9585. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/isoal.c | 78 ++++++----------------- 1 file changed, 21 insertions(+), 57 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 48ad0835074..d43233f0289 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -226,17 +226,8 @@ static isoal_status_t isoal_sink_allocate(isoal_sink_handle_t *hdl) */ static void isoal_sink_deallocate(isoal_sink_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.sink_allocated)) { - isoal_global.sink_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; - } else { - LL_ASSERT(0); - } - - if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { - (void)memset(&isoal_global.sink_state[hdl], 0, sizeof(struct isoal_sink)); - } else { - LL_ASSERT(0); - } + isoal_global.sink_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; + (void)memset(&isoal_global.sink_state[hdl], 0, sizeof(struct isoal_sink)); } /** @@ -374,16 +365,12 @@ isoal_status_t isoal_sink_create( */ void isoal_sink_enable(isoal_sink_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { - /* Reset bookkeeping state */ - memset(&isoal_global.sink_state[hdl].sdu_production, 0, - sizeof(isoal_global.sink_state[hdl].sdu_production)); + /* Reset bookkeeping state */ + memset(&isoal_global.sink_state[hdl].sdu_production, 0, + sizeof(isoal_global.sink_state[hdl].sdu_production)); - /* Atomically enable */ - isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; - } else { - LL_ASSERT(0); - } + /* Atomically enable */ + isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; } /** @@ -392,12 +379,8 @@ void isoal_sink_enable(isoal_sink_handle_t hdl) */ void isoal_sink_disable(isoal_sink_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.sink_state)) { - /* Atomically disable */ - isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; - } else { - LL_ASSERT(0); - } + /* Atomically disable */ + isoal_global.sink_state[hdl].sdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; } /** @@ -1459,13 +1442,7 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) struct isoal_pdu_production *pp; struct isoal_source *source; - if (hdl < ARRAY_SIZE(isoal_global.source_state)) { - source = &isoal_global.source_state[hdl]; - } else { - LL_ASSERT(0); - return; - } - + source = &isoal_global.source_state[hdl]; pp = &source->pdu_production; if (pp->pdu_available > 0) { @@ -1477,13 +1454,8 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) } } - if (hdl < ARRAY_SIZE(isoal_global.source_allocated)) { - isoal_global.source_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; - } else { - LL_ASSERT(0); - } - - (void)memset(source, 0, sizeof(struct isoal_source)); + isoal_global.source_allocated[hdl] = ISOAL_ALLOC_STATE_FREE; + (void)memset(&isoal_global.source_state[hdl], 0, sizeof(struct isoal_source)); } /** @@ -1493,8 +1465,8 @@ static void isoal_source_deallocate(isoal_source_handle_t hdl) */ static isoal_status_t isoal_check_source_hdl_valid(isoal_source_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.source_allocated) && - isoal_global.source_allocated[hdl] == ISOAL_ALLOC_STATE_TAKEN) { + if (hdl < CONFIG_BT_CTLR_ISOAL_SOURCES && + isoal_global.source_allocated[hdl] == ISOAL_ALLOC_STATE_TAKEN) { return ISOAL_STATUS_OK; } @@ -1588,16 +1560,12 @@ isoal_status_t isoal_source_create( */ void isoal_source_enable(isoal_source_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.source_state)) { - /* Reset bookkeeping state */ - memset(&isoal_global.source_state[hdl].pdu_production, 0, - sizeof(isoal_global.source_state[hdl].pdu_production)); + /* Reset bookkeeping state */ + memset(&isoal_global.source_state[hdl].pdu_production, 0, + sizeof(isoal_global.source_state[hdl].pdu_production)); - /* Atomically enable */ - isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; - } else { - LL_ASSERT(0); - } + /* Atomically enable */ + isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_ENABLED; } /** @@ -1606,12 +1574,8 @@ void isoal_source_enable(isoal_source_handle_t hdl) */ void isoal_source_disable(isoal_source_handle_t hdl) { - if (hdl < ARRAY_SIZE(isoal_global.source_state)) { - /* Atomically disable */ - isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; - } else { - LL_ASSERT(0); - } + /* Atomically disable */ + isoal_global.source_state[hdl].pdu_production.mode = ISOAL_PRODUCTION_MODE_DISABLED; } /** From 371642eb781651216399a73e2f3c696d5d81c366 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:54 +0000 Subject: [PATCH 4163/4498] Revert "[nrf fromtree] Bluetooth: Controller: Make aa in radio_aa_set const" This reverts commit 9e70b2847662239880a1d0f6b69bde41298fbea7. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 2 +- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h | 2 +- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c | 2 +- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index c6becbe322f..a657ab95dfe 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -382,7 +382,7 @@ void radio_whiten_iv_set(uint32_t iv) RADIO_PCNF1_WHITEEN_Msk; } -void radio_aa_set(const uint8_t *aa) +void radio_aa_set(uint8_t *aa) { NRF_RADIO->TXADDRESS = (((0UL) << RADIO_TXADDRESS_TXADDRESS_Pos) & diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index fc355af1edc..4bf833b233a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -70,7 +70,7 @@ int8_t radio_tx_power_max_get(void); int8_t radio_tx_power_floor(int8_t power); void radio_freq_chan_set(uint32_t chan); void radio_whiten_iv_set(uint32_t iv); -void radio_aa_set(const uint8_t *aa); +void radio_aa_set(uint8_t *aa); void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags); void radio_pkt_rx_set(void *rx_packet); void radio_pkt_tx_set(void *tx_packet); diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c index ecdf17bbe43..6107bfc9c68 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.c @@ -684,7 +684,7 @@ void radio_whiten_iv_set(uint32_t iv) GENFSK->WHITEN_SZ_THR |= GENFSK_WHITEN_SZ_THR_WHITEN_SZ_THR(0); } -void radio_aa_set(const uint8_t *aa) +void radio_aa_set(uint8_t *aa) { /* Configure Access Address detection using NETWORK ADDRESS 0 */ GENFSK->NTW_ADR_0 = *((uint32_t *)aa); diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h index cc3fda99964..1168804bbd5 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/radio/radio.h @@ -20,7 +20,7 @@ void radio_tx_power_set(uint32_t power); void radio_tx_power_max_set(void); void radio_freq_chan_set(uint32_t chan); void radio_whiten_iv_set(uint32_t iv); -void radio_aa_set(const uint8_t *aa); +void radio_aa_set(uint8_t *aa); void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags); void radio_pkt_rx_set(void *rx_packet); void radio_pkt_tx_set(void *tx_packet); From 69ecd28a43c340bc577e30efbd60b1ea6a40f635 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:54 +0000 Subject: [PATCH 4164/4498] Revert "[nrf fromtree] Bluetooth: controller: fix comparision of unsigned int to 0" This reverts commit 4eefd65d6bebfcfbb64b0a2fa0b3aa6c882d2452. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_iso_types.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso_types.h b/subsys/bluetooth/controller/ll_sw/ull_iso_types.h index 457ad1d2458..18d9a0f7bfe 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_iso_types.h @@ -9,18 +9,11 @@ #define LL_BIS_ADV_HANDLE_BASE BT_CTLR_ADV_ISO_STREAM_HANDLE_BASE #define LL_BIS_ADV_IDX_FROM_HANDLE(conn_handle) \ ((conn_handle) - (LL_BIS_ADV_HANDLE_BASE)) -/* Conditional compile to prevent coverity issue CWE570, comparison of unsigned int to 0 */ -#if (LL_BIS_ADV_HANDLE_BASE > 0) #define IS_ADV_ISO_HANDLE(conn_handle) \ (((conn_handle) >= (LL_BIS_ADV_HANDLE_BASE)) && \ ((conn_handle) <= ((LL_BIS_ADV_HANDLE_BASE) + \ (BT_CTLR_ADV_ISO_STREAM_MAX) - 1U))) #else -#define IS_ADV_ISO_HANDLE(conn_handle) \ - ((conn_handle) <= ((LL_BIS_ADV_HANDLE_BASE) + \ - (BT_CTLR_ADV_ISO_STREAM_MAX) - 1U)) -#endif /* LL_BIS_ADV_HANDLE_BASE */ -#else #define LL_BIS_ADV_IDX_FROM_HANDLE(conn_handle) 0U #define IS_ADV_ISO_HANDLE(conn_handle) 0U #endif /* CONFIG_BT_CTLR_ADV_ISO */ @@ -30,18 +23,11 @@ #define LL_BIS_SYNC_HANDLE_BASE BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE #define LL_BIS_SYNC_IDX_FROM_HANDLE(conn_handle) \ ((conn_handle) - (LL_BIS_SYNC_HANDLE_BASE)) -/* Conditional compile to prevent coverity issue CWE570, comparison of unsigned int to 0 */ -#if (LL_BIS_SYNC_HANDLE_BASE > 0) #define IS_SYNC_ISO_HANDLE(conn_handle) \ (((conn_handle) >= (LL_BIS_SYNC_HANDLE_BASE)) && \ ((conn_handle) <= ((LL_BIS_SYNC_HANDLE_BASE) + \ (BT_CTLR_SYNC_ISO_STREAM_MAX) - 1U))) #else -#define IS_SYNC_ISO_HANDLE(conn_handle) \ - ((conn_handle) <= ((LL_BIS_SYNC_HANDLE_BASE) + \ - (BT_CTLR_SYNC_ISO_STREAM_MAX) - 1U)) -#endif /* LL_BIS_SYNC_HANDLE_BASE */ -#else #define LL_BIS_SYNC_IDX_FROM_HANDLE(conn_handle) 0U #define IS_SYNC_ISO_HANDLE(conn_handle) 0U #endif /* CONFIG_BT_CTLR_SYNC_ISO */ From 45fac94fbd2ab945a79d6de5495c71c2d7e17725 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:55 +0000 Subject: [PATCH 4165/4498] Revert "[nrf fromtree] Bluetooth: Controll: Fix dead code in ll_setup_iso_path" This reverts commit 5e6ae9f1a206335f50da010532f106693e189ffa. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_iso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index b21a9d20721..70d018e7e0c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -491,11 +491,11 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, pdu_release, &source_handle); if (!err) { - if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && cis != NULL) { + if (cis) { cis->hdr.datapath_in = dp; } - if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO) && adv_stream != NULL) { + if (adv_stream) { adv_stream->dp = dp; } From 53d8965698cd83fb790ed3748717c3bf7667cea0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:55 +0000 Subject: [PATCH 4166/4498] Revert "[nrf fromtree] Bluetooth: Controller: Remove unused terminate_ack" This reverts commit 49afbcceeb53e75ca2be62e895b2b18bd5742993. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_central.c | 2 ++ subsys/bluetooth/controller/ll_sw/ull_conn.c | 6 ++++++ subsys/bluetooth/controller/ll_sw/ull_conn_types.h | 1 + 3 files changed, 9 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 7ea3c600ea6..b189c65fa21 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -291,6 +291,8 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, /* Setup the PRT reload */ ull_cp_prt_reload_set(conn, conn_interval_us); + conn->central.terminate_ack = 0U; + conn->llcp_terminate.reason_final = 0U; /* NOTE: use allocated link for generating dedicated * terminate ind rx node diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 1640c00e87e..9d78af7acc1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1044,6 +1044,12 @@ void ull_conn_done(struct node_rx_event_done *done) lll->latency_event = lll->latency; } #endif /* CONFIG_BT_PERIPHERAL */ + +#if defined(CONFIG_BT_CENTRAL) + } else if (reason_final) { + conn->central.terminate_ack = 1; +#endif /* CONFIG_BT_CENTRAL */ + } /* Reset connection failed to establish countdown */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index 8fabab03378..12e16488f38 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -202,6 +202,7 @@ struct ll_conn { #if defined(CONFIG_BT_CTLR_CONN_META) uint8_t is_must_expire:1; #endif /* CONFIG_BT_CTLR_CONN_META */ + uint8_t terminate_ack:1; } central; #endif /* CONFIG_BT_CENTRAL */ }; From 85c1d711308d56d5a8086392ca76849b6253032c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:55 +0000 Subject: [PATCH 4167/4498] Revert "[nrf fromtree] Bluetooth: Controller: Review rework flush timeout support" This reverts commit a96ce9920c747042b8d5bd3a86c2a854c8e49706. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/hci/hci.c | 44 +--- .../bluetooth/controller/ll_sw/lll_conn_iso.h | 28 +-- .../ll_sw/nordic/lll/lll_central_iso.c | 19 +- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 8 - tests/bsim/bluetooth/ll/cis/src/main.c | 206 +++++++++--------- ...onnected_iso_acl_first_ft_cen_skip_2_se.sh | 2 +- ...onnected_iso_acl_first_ft_per_skip_2_se.sh | 2 +- 7 files changed, 128 insertions(+), 181 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index c3dd070720b..b2c95271b2c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5762,18 +5762,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) /* Catch up local pkt_seq_num with internal pkt_seq_num */ event_count = cis->lll.event_count; pkt_seq_num = event_count + 1U; - /* If pb_flag is BT_ISO_START (0b00) or BT_ISO_SINGLE (0b10) - * then we simply check that the pb_flag is an even value, and - * then pkt_seq_num is a future sequence number value compare - * to last recorded number in cis->pkt_seq_num. - * - * When (pkt_seq_num - stream->pkt_seq_num) is negative then - * BIT64(39) will be set (2's compliment value). The diff value - * less than or equal to BIT64_MASK(38) means the diff value is - * positive and hence pkt_seq_num is greater than - * stream->pkt_seq_num. This calculation is valid for when value - * rollover too. - */ if (!(pb_flag & 0x01) && (((pkt_seq_num - cis->pkt_seq_num) & BIT64_MASK(39)) <= BIT64_MASK(38))) { @@ -5782,17 +5770,12 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) pkt_seq_num = cis->pkt_seq_num; } - /* Pre-increment, when pg_flag is BT_ISO_SINGLE (0b10) or - * BT_ISO_END (0b11) then we simple check if pb_flag has bit 1 - * is set, for next ISO data packet seq num comparison. - */ + /* Pre-increment, for next ISO data packet seq num comparison */ if (pb_flag & 0x10) { cis->pkt_seq_num++; } - /* Target next ISO event to avoid overlapping with, if any, - * current ISO event - */ + /* Target next event to avoid overlapping with current event */ pkt_seq_num++; sdu_frag_tx.target_event = pkt_seq_num; sdu_frag_tx.grp_ref_point = @@ -5834,7 +5817,7 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) #endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ /* Get controller's input data path for CIS */ - hdr = &cis->hdr; + hdr = &(cis->hdr); dp_in = hdr->datapath_in; if (!dp_in || dp_in->path_id != BT_HCI_DATAPATH_ID_HCI) { LOG_ERR("Input data path not set for HCI"); @@ -5901,18 +5884,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) /* Catch up local pkt_seq_num with internal pkt_seq_num */ event_count = lll_iso->payload_count / lll_iso->bn; pkt_seq_num = event_count; - /* If pb_flag is BT_ISO_START (0b00) or BT_ISO_SINGLE (0b10) - * then we simply check that the pb_flag is an even value, and - * then pkt_seq_num is a future sequence number value compare - * to last recorded number in cis->pkt_seq_num. - * - * When (pkt_seq_num - stream->pkt_seq_num) is negative then - * BIT64(39) will be set (2's compliment value). The diff value - * less than or equal to BIT64_MASK(38) means the diff value is - * positive and hence pkt_seq_num is greater than - * stream->pkt_seq_num. This calculation is valid for when value - * rollover too. - */ if (!(pb_flag & 0x01) && (((pkt_seq_num - stream->pkt_seq_num) & BIT64_MASK(39)) <= BIT64_MASK(38))) { @@ -5921,17 +5892,12 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) pkt_seq_num = stream->pkt_seq_num; } - /* Pre-increment, when pg_flag is BT_ISO_SINGLE (0b10) or - * BT_ISO_END (0b11) then we simple check if pb_flag has bit 1 - * is set, for next ISO data packet seq num comparison. - */ + /* Pre-increment, for next ISO data packet seq num comparison */ if (pb_flag & 0x10) { stream->pkt_seq_num++; } - /* Target next ISO event to avoid overlapping with, if any, - * current ISO event - */ + /* Target next event to avoid overlapping with current event */ /* FIXME: Implement ISO Tx ack generation early in done compared * to currently only in prepare. I.e. to ensure upper * layer has the number of completed packet before the diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 8a85ca7c6c9..0321b96f638 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -15,10 +15,8 @@ struct lll_conn_iso_stream_rxtx { uint64_t ft:8; /* Flush timeout (FT) */ uint64_t bn:4; /* Burst number (BN) */ uint64_t phy:3; /* PHY */ - uint64_t rfu0:1; - - uint8_t bn_curr:4; /* Current burst number */ - uint8_t rfu1:4; + uint64_t rfu:1; + uint8_t bn_curr:4; /* Current burst number */ #if defined(CONFIG_BT_CTLR_LE_ENC) struct ccm ccm; @@ -75,26 +73,20 @@ struct lll_conn_iso_group { struct lll_hdr hdr; uint16_t handle; /* CIG handle (internal) */ + uint8_t num_cis:5; /* Number of CISes in this CIG */ + uint8_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ + uint8_t paused:1; /* 1: CIG is paused */ - /* Resumption information */ - uint16_t resume_cis; /* CIS handle to schedule at resume */ - - /* ISO group information */ - uint32_t num_cis:5; /* Number of CISes in this CIG */ - uint32_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ - uint32_t paused:1; /* 1: CIG is paused */ - uint32_t rfu0:1; - - /* ISO interval to calculate timestamp under FT > 1, - * maximum ISO interval of 4 seconds can be represented in 22-bits. - */ - uint32_t iso_interval_us:22; - uint32_t rfu1:2; + /* ISO interval to calculate timestamp under FT > 1 */ + uint32_t iso_interval_us; /* Accumulates LLL prepare callback latencies */ uint16_t latency_prepare; uint16_t latency_event; + /* Resumption information */ + uint16_t resume_cis; /* CIS handle to schedule at resume */ + #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) /* Window widening. Relies on vendor specific conversion macros, e.g. * EVENT_US_FRAC_TO_TICKS(). diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 751c3915fc2..9c2184b9942 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -48,7 +48,7 @@ static void isr_prepare_subevent(void *param); static void isr_done(void *param); static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll); -static void payload_count_lazy_update(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); static uint16_t next_cis_chan_remap_idx; static uint16_t next_cis_chan_prn_s; @@ -183,7 +183,7 @@ static int prepare_cb(struct lll_prepare_param *p) se_curr = 1U; /* Adjust the SN and NESN for skipped CIG events */ - payload_count_lazy_update(cis_lll, lazy); + payload_count_lazy(cis_lll, lazy); /* Start setting up of Radio h/w */ radio_reset(); @@ -370,7 +370,7 @@ static int prepare_cb(struct lll_prepare_param *p) cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy_update(cis_lll, lazy); + payload_count_lazy(cis_lll, lazy); /* Adjust sn and nesn for canceled events */ if (err) { @@ -676,20 +676,11 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done || #if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - /* Used by test code, - * to skip a number of events in every 3 event count when current subevent is less than - * or equal to 2 or when current subevent has completed all its NSE number of subevents. - * OR - * to skip a (number + 1) of events in every 3 event count when current subevent is less - * than or equal to 1 or when current subevent has completed all its NSE number of - * subevents. - */ ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT) && ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || - (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT + 1U)) && ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || -#endif /* CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS */ +#endif false) { payload_count_flush(cis_lll); @@ -1239,7 +1230,7 @@ static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_ } } -static void payload_count_lazy_update(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) +static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) { if (cis_lll->tx.bn) { uint16_t tx_lazy; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 27ed4d1e42c..c33c82d4c70 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -474,14 +474,6 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done || #if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) - /* Used by test code, - * to skip a number of events in every 3 event count when current subevent is less than - * or equal to 2 or when current subevent has completed all its NSE number of subevents. - * OR - * to skip a (number + 1) of events in every 3 event count when current subevent is less - * than or equal to 1 or when current subevent has completed all its NSE number of - * subevents. - */ ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT) && ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT + 1U)) && diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index b544546a404..15e102981d6 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -352,7 +352,7 @@ static void test_cis_central(void) struct bt_conn *conn_list[CONFIG_BT_MAX_CONN]; struct bt_iso_cig_param cig_param; struct bt_iso_cig *cig; - int conn_count; + uint8_t conn_count; int err; printk("Bluetooth initializing..."); @@ -370,12 +370,12 @@ static void test_cis_central(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx[i].phy = BT_GAP_LE_PHY_2M; - iso_tx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_tx[i].rtn = 2U; } else { iso_tx[i].rtn = 0U; } + iso_tx[i].path = NULL; if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { @@ -386,12 +386,12 @@ static void test_cis_central(void) iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU; iso_rx[i].phy = BT_GAP_LE_PHY_2M; - iso_rx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_rx[i].rtn = 2U; } else { iso_rx[i].rtn = 0U; } + iso_rx[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { iso_qos[i].rx = &iso_rx[i]; @@ -413,12 +413,12 @@ static void test_cis_central(void) cig_param.sca = BT_GAP_SCA_UNKNOWN; cig_param.packing = 0U; cig_param.framing = 0U; - cig_param.interval = ISO_INTERVAL_US; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { cig_param.latency = ISO_LATENCY_FT_MS; } else { cig_param.latency = ISO_LATENCY_MS; } + cig_param.interval = ISO_INTERVAL_US; printk("Create CIG..."); err = bt_iso_cig_create(&cig_param, &cig); @@ -428,10 +428,10 @@ static void test_cis_central(void) } printk("success.\n"); - conn_count = 0; + conn_count = 0U; #if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U; } #endif @@ -443,8 +443,8 @@ static void test_cis_central(void) #endif struct bt_conn *conn; - int conn_index; - int chan; + uint8_t conn_index; + uint8_t chan; printk("Start scanning (%d)...", i); err = bt_le_scan_start(BT_LE_SCAN_CUSTOM, NULL); @@ -494,12 +494,12 @@ static void test_cis_central(void) #if defined(CONFIG_TEST_CONNECT_ACL_FIRST) } - for (int chan = 0, conn_index = 0; + for (uint8_t chan = 0U, conn_index = 0U; (conn_index < conn_count) && (chan < CONFIG_BT_ISO_MAX_CHAN); conn_index++, chan++) { #elif defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (int chan = 0, conn_index = 0; + for (uint8_t chan = 0U, conn_index = 0U; (chan < CONFIG_BT_ISO_MAX_CHAN); chan++) { #endif @@ -523,67 +523,70 @@ static void test_cis_central(void) printk("connected to peer %d ISO channel.\n", chan); } - if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || - IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { - for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { - - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; - struct net_buf *buf; - int ret; - - buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT)); - if (!buf) { - FAIL("Data buffer allocate timeout on channel %d\n", chan); - return; - } - - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - sys_put_le16(seq_num, iso_data); - net_buf_add_mem(buf, iso_data, sizeof(iso_data)); - - ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT)); - if (ret) { - FAIL("k_sem_take for ISO data sent failed.\n"); - return; - } - - printk("ISO send: seq_num %u, chan %d\n", seq_num, chan); - ret = bt_iso_chan_send(&iso_chan[chan], buf, - seq_num, BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - FAIL("Unable to send data on channel %d : %d\n", chan, ret); - net_buf_unref(buf); - return; - } +#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) + for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { + + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; + struct net_buf *buf; + int ret; + + buf = net_buf_alloc(&tx_pool, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (!buf) { + FAIL("Data buffer allocate timeout on channel" + " %u\n", chan); + return; + } + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + sys_put_le32(seq_num, iso_data); + net_buf_add_mem(buf, iso_data, sizeof(iso_data)); + + ret = k_sem_take(&sem_iso_data, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (ret) { + FAIL("k_sem_take for ISO data sent failed.\n"); + return; } - if ((seq_num % 100) == 0) { - printk("Sending value %u\n", seq_num); + printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); + ret = bt_iso_chan_send(&iso_chan[chan], buf, + seq_num, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + FAIL("Unable to send data on channel %u" + " : %d\n", chan, ret); + net_buf_unref(buf); + return; } } - k_sleep(K_MSEC(1000)); - } else { - k_sleep(K_SECONDS(11)); + if ((seq_num % 100) == 0) { + printk("Sending value %u\n", seq_num); + } } - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - printk("ISO disconnect channel %d...", chan); + k_sleep(K_MSEC(1000)); +#else + k_sleep(K_SECONDS(11)); +#endif + + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + printk("ISO disconnect channel %u...", chan); err = bt_iso_chan_disconnect(&iso_chan[chan]); if (err) { - FAIL("Failed to disconnect channel %d (%d)\n", chan, err); + FAIL("Failed to disconnect channel %u (%d)\n", + chan, err); return; } printk("success\n"); - printk("Waiting for ISO channel disconnect %d...", chan); + printk("Waiting for ISO channel disconnect %u...", chan); err = k_sem_take(&sem_iso_disc, K_FOREVER); if (err) { FAIL("failed (err %d)\n", err); return; } - printk("disconnected to peer %d ISO channel.\n", chan); + printk("disconnected to peer %u ISO channel.\n", chan); } bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL); @@ -604,15 +607,15 @@ static void test_cis_central(void) } #endif - if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - if (expected_seq_num[chan] < SEQ_NUM_MAX) { - FAIL("ISO Data reception incomplete %u (%u).\n", - expected_seq_num[chan], SEQ_NUM_MAX); - return; - } +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + if (expected_seq_num[chan] < SEQ_NUM_MAX) { + FAIL("ISO Data reception incomplete %u (%u).\n", + expected_seq_num[chan], SEQ_NUM_MAX); + return; } } +#endif PASS("Central ISO tests Passed\n"); } @@ -668,12 +671,12 @@ static void test_cis_peripheral(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx_p[i].phy = BT_GAP_LE_PHY_2M; - iso_tx_p[i].path = NULL; if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { iso_tx_p[i].rtn = 2U; } else { iso_tx_p[i].rtn = 0U; } + iso_tx_p[i].path = NULL; iso_qos_p[i].tx = &iso_tx_p[i]; @@ -738,7 +741,7 @@ static void test_cis_peripheral(void) printk("connected to peer central.\n"); #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif printk("Waiting for ISO channel connection..."); @@ -753,47 +756,50 @@ static void test_cis_peripheral(void) } #endif - if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { - for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; - struct net_buf *buf; - int ret; - - buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT)); - if (!buf) { - FAIL("Data buffer allocate timeout on channel %d\n", chan); - return; - } - - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - sys_put_le16(seq_num, iso_data); - net_buf_add_mem(buf, iso_data, sizeof(iso_data)); - - ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT)); - if (ret) { - FAIL("k_sem_take for ISO data sent failed.\n"); - return; - } - - printk("ISO send: seq_num %u, chan %d\n", seq_num, chan); - ret = bt_iso_chan_send(&iso_chan_p[chan], buf, seq_num, - BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - FAIL("Unable to send data on channel %d : %d\n", chan, ret); - net_buf_unref(buf); - return; - } +#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) + for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; + struct net_buf *buf; + int ret; + + buf = net_buf_alloc(&tx_pool, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (!buf) { + FAIL("Data buffer allocate timeout on channel" + " %u\n", chan); + return; + } + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + sys_put_le32(seq_num, iso_data); + net_buf_add_mem(buf, iso_data, sizeof(iso_data)); + + ret = k_sem_take(&sem_iso_data, + K_MSEC(BUF_ALLOC_TIMEOUT)); + if (ret) { + FAIL("k_sem_take for ISO data sent failed.\n"); + return; } - if ((seq_num % 100) == 0) { - printk("Sending value %u\n", seq_num); + printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); + ret = bt_iso_chan_send(&iso_chan_p[chan], buf, + seq_num, BT_ISO_TIMESTAMP_NONE); + if (ret < 0) { + FAIL("Unable to send data on channel %u" + " : %d\n", chan, ret); + net_buf_unref(buf); + return; } } + + if ((seq_num % 100) == 0) { + printk("Sending value %u\n", seq_num); + } } +#endif #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif printk("Waiting for ISO channel disconnect..."); @@ -818,13 +824,13 @@ static void test_cis_peripheral(void) #if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) - for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { + for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #else - int chan = 0; + uint8_t chan = 0U; #endif if (expected_seq_num[chan] < SEQ_NUM_MAX) { - FAIL("ISO Data reception incomplete %u (%u).\n", expected_seq_num[chan], - SEQ_NUM_MAX); + FAIL("ISO Data reception incomplete %u (%u).\n", + expected_seq_num[chan], SEQ_NUM_MAX); return; } #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh index bb08f582574..04ce474e812 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2023 Nordic Semiconductor ASA +# Copyright 2020 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh index 84d3c5c4ed3..307d865a117 100755 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh +++ b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2023 Nordic Semiconductor ASA +# Copyright 2020 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 source ${ZEPHYR_BASE}/tests/bsim/sh_common.source From 9721ecaa0749b9b9868f331a571cb90d5a9fb95c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:55 +0000 Subject: [PATCH 4168/4498] Revert "[nrf fromtree] tests: bsim: Bluetooth: Test RTN=2, FT=2, Cen skip 2 SE in Controller" This reverts commit 5e04a9f2a3a99b319901d0eca3cdc361c75acc45. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/lll/lll_central_iso.c | 9 +- tests/bsim/bluetooth/ll/cis/Kconfig | 13 -- .../overlay-acl_first_ft_cen_skip_2_se.conf | 9 -- tests/bsim/bluetooth/ll/cis/src/main.c | 114 +----------------- ...onnected_iso_acl_first_ft_cen_skip_2_se.sh | 24 ---- tests/bsim/bluetooth/ll/compile.sh | 2 - 6 files changed, 7 insertions(+), 164 deletions(-) delete mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf delete mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 9c2184b9942..4bf44a42cd9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -674,14 +674,7 @@ static void isr_rx(void *param) cis_lll = param; /* No Rx */ - if (!trx_done || -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT) && - ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || - (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT + 1U)) && - ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || -#endif - false) { + if (!trx_done) { payload_count_flush(cis_lll); goto isr_rx_next_subevent; diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig b/tests/bsim/bluetooth/ll/cis/Kconfig index 6076f88ae3c..532a26f5d52 100644 --- a/tests/bsim/bluetooth/ll/cis/Kconfig +++ b/tests/bsim/bluetooth/ll/cis/Kconfig @@ -35,19 +35,6 @@ config TEST_FT_PER_SKIP_EVENTS_COUNT help Skip peripheral ISO events count where all subevents are skipped. -config TEST_FT_CEN_SKIP_SUBEVENTS - bool "Skip central role subevents to test Flush Timeout" - select TEST_FT_SKIP_SUBEVENTS - help - Skip central role subevent reception to test flush timeout - implementation. - -config TEST_FT_CEN_SKIP_EVENTS_COUNT - int "Skip central ISO events count, all subevents in them" - depends on TEST_FT_CEN_SKIP_SUBEVENTS - help - Skip central ISO events count where all subevents are skipped. - config BT_CTLR_SCAN_UNRESERVED default y if TEST_CONNECT_ACL_FIRST help diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf deleted file mode 100644 index 194a23ffec6..00000000000 --- a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_cen_skip_2_se.conf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG_TEST_USE_LEGACY_ADVERTISING=n -CONFIG_TEST_CONNECT_ACL_FIRST=y -CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS=y -CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT=1 -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_ISO_MAX_CHAN=1 -CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index 15e102981d6..720adc16ef9 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -296,19 +296,15 @@ static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *in seq_num = sys_get_le32(buf->data); if (info->flags & BT_ISO_FLAGS_VALID) { if (seq_num != expected_seq_num[index]) { - if (expected_seq_num[index]) { - FAIL("ISO data miss match, expected %u actual %u\n", - expected_seq_num[index], seq_num); - } + FAIL("ISO data miss match, expected %u actual %u\n", + expected_seq_num[index], seq_num); expected_seq_num[index] = seq_num; } expected_seq_num[index] += 1U; -#if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) +#if defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U); -#elif defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - expected_seq_num[index] += ((CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U); #endif } else if (expected_seq_num[index] && expected_seq_num[index] < SEQ_NUM_MAX) { @@ -346,7 +342,6 @@ static struct bt_iso_chan_ops iso_ops = { static void test_cis_central(void) { struct bt_iso_chan_io_qos iso_tx[CONFIG_BT_ISO_MAX_CHAN]; - struct bt_iso_chan_io_qos iso_rx[CONFIG_BT_ISO_MAX_CHAN]; struct bt_iso_chan_qos iso_qos[CONFIG_BT_ISO_MAX_CHAN]; struct bt_iso_chan *channels[CONFIG_BT_ISO_MAX_CHAN]; struct bt_conn *conn_list[CONFIG_BT_MAX_CONN]; @@ -377,27 +372,8 @@ static void test_cis_central(void) } iso_tx[i].path = NULL; - if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) || - IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) { - iso_qos[i].tx = &iso_tx[i]; - } else { - iso_qos[i].tx = NULL; - } - - iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU; - iso_rx[i].phy = BT_GAP_LE_PHY_2M; - if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { - iso_rx[i].rtn = 2U; - } else { - iso_rx[i].rtn = 0U; - } - iso_rx[i].path = NULL; - - if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) { - iso_qos[i].rx = &iso_rx[i]; - } else { - iso_qos[i].rx = NULL; - } + iso_qos[i].tx = &iso_tx[i]; + iso_qos[i].rx = NULL; iso_chan[i].ops = &iso_ops; iso_chan[i].qos = &iso_qos[i]; @@ -430,12 +406,6 @@ static void test_cis_central(void) conn_count = 0U; -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U; - } -#endif - #if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) { #else @@ -523,7 +493,6 @@ static void test_cis_central(void) printk("connected to peer %d ISO channel.\n", chan); } -#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { @@ -566,9 +535,6 @@ static void test_cis_central(void) } k_sleep(K_MSEC(1000)); -#else - k_sleep(K_SECONDS(11)); -#endif for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { printk("ISO disconnect channel %u...", chan); @@ -607,16 +573,6 @@ static void test_cis_central(void) } #endif -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - if (expected_seq_num[chan] < SEQ_NUM_MAX) { - FAIL("ISO Data reception incomplete %u (%u).\n", - expected_seq_num[chan], SEQ_NUM_MAX); - return; - } - } -#endif - PASS("Central ISO tests Passed\n"); } @@ -657,7 +613,6 @@ static struct bt_iso_server iso_server = { static void test_cis_peripheral(void) { - struct bt_iso_chan_io_qos iso_tx_p[CONFIG_BT_ISO_MAX_CHAN]; int err; printk("Bluetooth initializing..."); @@ -669,18 +624,7 @@ static void test_cis_peripheral(void) printk("success.\n"); for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { - iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; - iso_tx_p[i].phy = BT_GAP_LE_PHY_2M; - if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { - iso_tx_p[i].rtn = 2U; - } else { - iso_tx_p[i].rtn = 0U; - } - iso_tx_p[i].path = NULL; - - iso_qos_p[i].tx = &iso_tx_p[i]; - - iso_rx_p[i].sdu = CONFIG_BT_ISO_RX_MTU; + iso_rx_p[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_qos_p[i].rx = &iso_rx_p[i]; @@ -754,51 +698,7 @@ static void test_cis_peripheral(void) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) } -#endif - -#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS) - for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) { - for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { - uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, }; - struct net_buf *buf; - int ret; - buf = net_buf_alloc(&tx_pool, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (!buf) { - FAIL("Data buffer allocate timeout on channel" - " %u\n", chan); - return; - } - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - sys_put_le32(seq_num, iso_data); - net_buf_add_mem(buf, iso_data, sizeof(iso_data)); - - ret = k_sem_take(&sem_iso_data, - K_MSEC(BUF_ALLOC_TIMEOUT)); - if (ret) { - FAIL("k_sem_take for ISO data sent failed.\n"); - return; - } - - printk("ISO send: seq_num %u, chan %u\n", seq_num, chan); - ret = bt_iso_chan_send(&iso_chan_p[chan], buf, - seq_num, BT_ISO_TIMESTAMP_NONE); - if (ret < 0) { - FAIL("Unable to send data on channel %u" - " : %d\n", chan, ret); - net_buf_unref(buf); - return; - } - } - - if ((seq_num % 100) == 0) { - printk("Sending value %u\n", seq_num); - } - } -#endif - -#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #endif @@ -822,7 +722,6 @@ static void test_cis_peripheral(void) } printk("disconnected from peer device.\n"); -#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { #else @@ -835,7 +734,6 @@ static void test_cis_peripheral(void) } #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS) } -#endif #endif PASS("Peripheral ISO tests Passed\n"); diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh deleted file mode 100755 index 04ce474e812..00000000000 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_cen_skip_2_se.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -source ${ZEPHYR_BASE}/tests/bsim/sh_common.source - -# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, -# FT=2, skips 2 subevents in the central -simulation_id="connected_iso_acl_first_ft_cen_skip_2_se" -verbosity_level=2 -EXECUTE_TIMEOUT=60 - -cd ${BSIM_OUT_PATH}/bin - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_2_se_conf \ - -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_cen_skip_2_se_conf \ - -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral - -Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=30e6 $@ - -wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 6d530d05d72..28ca40b322c 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -40,8 +40,6 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group_acl_first.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile -app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_4_se.conf compile -app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_cen_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From 51767467a0952276f557f28559dd852b662dd78b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:56 +0000 Subject: [PATCH 4169/4498] Revert "[nrf fromtree] tests: bsim: Bluetooth: Test RTN=2, FT=2, Per skip 2 SE in Controller" This reverts commit 227cc39f8b9b67c4f3bce67a3e85df5d24a49073. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 9 +----- tests/bsim/bluetooth/ll/cis/Kconfig | 19 ------------- .../overlay-acl_first_ft_per_skip_2_se.conf | 9 ------ tests/bsim/bluetooth/ll/cis/prj.conf | 1 - tests/bsim/bluetooth/ll/cis/src/main.c | 28 +++++-------------- ...onnected_iso_acl_first_ft_per_skip_2_se.sh | 24 ---------------- tests/bsim/bluetooth/ll/compile.sh | 1 - 7 files changed, 8 insertions(+), 83 deletions(-) delete mode 100644 tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf delete mode 100755 tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index c33c82d4c70..25401f5564e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -472,14 +472,7 @@ static void isr_rx(void *param) cis_lll = param; /* No Rx */ - if (!trx_done || -#if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS) - ((((cis_lll->event_count % 3U) < CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT) && - ((se_curr > cis_lll->nse) || (se_curr <= 2U))) || - (((cis_lll->event_count % 3U) < (CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT + 1U)) && - ((se_curr > cis_lll->nse) || (se_curr <= 1U)))) || -#endif - false) { + if (!trx_done) { payload_count_flush(cis_lll); /* Next subevent or next CIS */ diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig b/tests/bsim/bluetooth/ll/cis/Kconfig index 532a26f5d52..b59a46be4fc 100644 --- a/tests/bsim/bluetooth/ll/cis/Kconfig +++ b/tests/bsim/bluetooth/ll/cis/Kconfig @@ -16,25 +16,6 @@ config TEST_MULTIPLE_PERIPERAL_CIS help Multiple Peripheral CIS establishment. -config TEST_FT_SKIP_SUBEVENTS - bool - help - Skip central and/or peripheral subevent reception to test flush - timeout implementation. - -config TEST_FT_PER_SKIP_SUBEVENTS - bool "Skip peripheral role subevents to test Flush Timeout" - select TEST_FT_SKIP_SUBEVENTS - help - Skip peripheral role subevent reception to test flush timeout - implementation. - -config TEST_FT_PER_SKIP_EVENTS_COUNT - int "Skip peripheral ISO events count, all subevents in them" - depends on TEST_FT_PER_SKIP_SUBEVENTS - help - Skip peripheral ISO events count where all subevents are skipped. - config BT_CTLR_SCAN_UNRESERVED default y if TEST_CONNECT_ACL_FIRST help diff --git a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf b/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf deleted file mode 100644 index bfbe36115f5..00000000000 --- a/tests/bsim/bluetooth/ll/cis/overlay-acl_first_ft_per_skip_2_se.conf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG_TEST_USE_LEGACY_ADVERTISING=n -CONFIG_TEST_CONNECT_ACL_FIRST=y -CONFIG_TEST_FT_PER_SKIP_SUBEVENTS=y -CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT=1 -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_ISO_MAX_CHAN=1 -CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y diff --git a/tests/bsim/bluetooth/ll/cis/prj.conf b/tests/bsim/bluetooth/ll/cis/prj.conf index a4d3c3e8c5f..0b6b764393b 100644 --- a/tests/bsim/bluetooth/ll/cis/prj.conf +++ b/tests/bsim/bluetooth/ll/cis/prj.conf @@ -13,7 +13,6 @@ CONFIG_BT_MAX_CONN=9 CONFIG_BT_ISO_MAX_CHAN=9 CONFIG_BT_ISO_TX_BUF_COUNT=18 CONFIG_BT_ISO_TX_MTU=120 -CONFIG_BT_ISO_RX_MTU=120 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_RX_SIZE=255 diff --git a/tests/bsim/bluetooth/ll/cis/src/main.c b/tests/bsim/bluetooth/ll/cis/src/main.c index 720adc16ef9..a9538e3e9c6 100644 --- a/tests/bsim/bluetooth/ll/cis/src/main.c +++ b/tests/bsim/bluetooth/ll/cis/src/main.c @@ -53,7 +53,6 @@ static bt_addr_le_t peer_addr; #define ISO_INTERVAL_US 10000U #define ISO_LATENCY_MS DIV_ROUND_UP(ISO_INTERVAL_US, USEC_PER_MSEC) -#define ISO_LATENCY_FT_MS 20U #define BT_CONN_US_TO_INTERVAL(t) ((uint16_t)((t) * 4U / 5U / USEC_PER_MSEC)) @@ -104,7 +103,7 @@ static bt_addr_le_t peer_addr; #define NAME_LEN 30 -#define BUF_ALLOC_TIMEOUT (40) /* milliseconds */ +#define BUF_ALLOC_TIMEOUT (30) /* milliseconds */ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL); @@ -301,11 +300,8 @@ static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *in expected_seq_num[index] = seq_num; } - expected_seq_num[index] += 1U; + expected_seq_num[index]++; -#if defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) - expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U); -#endif } else if (expected_seq_num[index] && expected_seq_num[index] < SEQ_NUM_MAX) { FAIL("%s: Invalid ISO data after valid ISO data reception.\n" @@ -365,11 +361,7 @@ static void test_cis_central(void) for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) { iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU; iso_tx[i].phy = BT_GAP_LE_PHY_2M; - if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { - iso_tx[i].rtn = 2U; - } else { - iso_tx[i].rtn = 0U; - } + iso_tx[i].rtn = 0U; iso_tx[i].path = NULL; iso_qos[i].tx = &iso_tx[i]; @@ -389,11 +381,7 @@ static void test_cis_central(void) cig_param.sca = BT_GAP_SCA_UNKNOWN; cig_param.packing = 0U; cig_param.framing = 0U; - if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) { - cig_param.latency = ISO_LATENCY_FT_MS; - } else { - cig_param.latency = ISO_LATENCY_MS; - } + cig_param.latency = ISO_LATENCY_MS; cig_param.interval = ISO_INTERVAL_US; printk("Create CIG..."); @@ -416,7 +404,7 @@ static void test_cis_central(void) uint8_t conn_index; uint8_t chan; - printk("Start scanning (%d)...", i); + printk("Start scanning..."); err = bt_le_scan_start(BT_LE_SCAN_CUSTOM, NULL); if (err) { FAIL("Could not start scan: %d\n", err); @@ -522,7 +510,7 @@ static void test_cis_central(void) ret = bt_iso_chan_send(&iso_chan[chan], buf, seq_num, BT_ISO_TIMESTAMP_NONE); if (ret < 0) { - FAIL("Unable to send data on channel %u" + FAIL("Unable to broadcast data on channel %u" " : %d\n", chan, ret); net_buf_unref(buf); return; @@ -534,7 +522,7 @@ static void test_cis_central(void) } } - k_sleep(K_MSEC(1000)); + k_sleep(K_MSEC(100)); for (uint8_t chan = 0U; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) { printk("ISO disconnect channel %u...", chan); @@ -599,8 +587,6 @@ static int iso_accept(const struct bt_iso_accept_info *info, *chan = &iso_chan_p[chan_count]; chan_count++; - printk("Accepted on channel %p\n", *chan); - return 0; } diff --git a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh b/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh deleted file mode 100755 index 307d865a117..00000000000 --- a/tests/bsim/bluetooth/ll/cis/tests_scripts/connected_iso_acl_first_ft_per_skip_2_se.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -source ${ZEPHYR_BASE}/tests/bsim/sh_common.source - -# Basic Connected ISO test: a Central connects to 1 Peripheral and tests RTN=2, -# FT=2, skips 2 subevents in the peripheral -simulation_id="connected_iso_acl_first_ft_per_skip_2_se" -verbosity_level=2 -EXECUTE_TIMEOUT=60 - -cd ${BSIM_OUT_PATH}/bin - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_2_se_conf \ - -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_cis_prj_conf_overlay-acl_first_ft_per_skip_2_se_conf \ - -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral - -Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=30e6 $@ - -wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 28ca40b322c..2369192e0cc 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -39,7 +39,6 @@ app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-legacy_adv_acl_first.conf c app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group_acl_first.conf compile app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-peripheral_cis.conf compile -app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_first_ft_per_skip_2_se.conf compile app=tests/bsim/bluetooth/ll/edtt/hci_test_app \ conf_file=prj_dut_llcp.conf compile From 3390fc5c328885e520ebb87ca9426afc588226e0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:56 +0000 Subject: [PATCH 4170/4498] Revert "[nrf fromtree] Bluetooth: Controller: Option to ignore Tx ISO Data Packet Seq Num" This reverts commit 41b3a58b1641934eec748c66d57846f0e4ef56e0. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/Kconfig.ll_sw_split | 9 +- subsys/bluetooth/controller/hci/hci.c | 108 +++--------------- .../controller/ll_sw/ull_central_iso.c | 3 - .../controller/ll_sw/ull_conn_iso_types.h | 4 - .../controller/ll_sw/ull_peripheral_iso.c | 3 - 5 files changed, 16 insertions(+), 111 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index a7dade7a1db..3f6f3c10382 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -499,8 +499,7 @@ config BT_CTLR_SCAN_ENABLE_STRICT config BT_CTLR_ISOAL_SN_STRICT bool "Enforce Strict Tx ISO Data Sequence Number use" - depends on !BT_CTLR_ISOAL_PSN_IGNORE && (BT_CTLR_ADV_ISO || \ - BT_CTLR_CONN_ISO) + depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO default y help Enforce strict sequencing of released payloads based on the TX SDU's @@ -518,12 +517,6 @@ config BT_CTLR_ISOAL_SN_STRICT dropped. This will result in better delivery of data to the receiver but at the cost of creating skews in the received stream of SDUs. -config BT_CTLR_ISOAL_PSN_IGNORE - bool "Ignore Tx ISO Data Packet Sequence Number use" - depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO - help - Ignore the use of Tx ISO Data Packet Sequence Number. - config BT_CTLR_ZLI bool "Use Zero Latency IRQs" depends on ZERO_LATENCY_IRQS diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index b2c95271b2c..0adbf5ff70c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5657,6 +5657,8 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) struct bt_hci_iso_data_hdr *iso_data_hdr; struct isoal_sdu_tx sdu_frag_tx; struct bt_hci_iso_hdr *iso_hdr; + struct ll_iso_datapath *dp_in; + struct ll_iso_stream_hdr *hdr; uint32_t *time_stamp; uint16_t handle; uint8_t pb_flag; @@ -5666,6 +5668,8 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) iso_data_hdr = NULL; *evt = NULL; + hdr = NULL; + dp_in = NULL; if (buf->len < sizeof(*iso_hdr)) { LOG_ERR("No HCI ISO header"); @@ -5743,50 +5747,17 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * data path */ } else if (IS_CIS_HANDLE(handle)) { - struct ll_conn_iso_stream *cis; - struct ll_conn_iso_group *cig; - struct ll_iso_stream_hdr *hdr; - struct ll_iso_datapath *dp_in; - - cis = ll_iso_stream_connected_get(handle); + struct ll_conn_iso_stream *cis = + ll_iso_stream_connected_get(handle); if (!cis) { return -EINVAL; } - cig = cis->group; - -#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) - uint64_t event_count; - uint64_t pkt_seq_num; - - /* Catch up local pkt_seq_num with internal pkt_seq_num */ - event_count = cis->lll.event_count; - pkt_seq_num = event_count + 1U; - if (!(pb_flag & 0x01) && - (((pkt_seq_num - cis->pkt_seq_num) & - BIT64_MASK(39)) <= BIT64_MASK(38))) { - cis->pkt_seq_num = pkt_seq_num; - } else { - pkt_seq_num = cis->pkt_seq_num; - } - - /* Pre-increment, for next ISO data packet seq num comparison */ - if (pb_flag & 0x10) { - cis->pkt_seq_num++; - } - - /* Target next event to avoid overlapping with current event */ - pkt_seq_num++; - sdu_frag_tx.target_event = pkt_seq_num; - sdu_frag_tx.grp_ref_point = - isoal_get_wrapped_time_us(cig->cig_ref_point, - ((pkt_seq_num - event_count) * - cig->iso_interval * - ISO_INT_UNIT_US)); - -#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + struct ll_conn_iso_group *cig = cis->group; uint8_t event_offset; + hdr = &(cis->hdr); + /* We must ensure sufficient time for ISO-AL to fragment SDU and * deliver PDUs to the TX queue. By checking ull_ref_get, we * know if we are within the subevents of an ISO event. If so, @@ -5809,15 +5780,11 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) } sdu_frag_tx.target_event = cis->lll.event_count + event_offset; - sdu_frag_tx.grp_ref_point = - isoal_get_wrapped_time_us(cig->cig_ref_point, - (event_offset * - cig->iso_interval * - ISO_INT_UNIT_US)); -#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + sdu_frag_tx.grp_ref_point = isoal_get_wrapped_time_us(cig->cig_ref_point, + (event_offset * cig->iso_interval * + ISO_INT_UNIT_US)); /* Get controller's input data path for CIS */ - hdr = &(cis->hdr); dp_in = hdr->datapath_in; if (!dp_in || dp_in->path_id != BT_HCI_DATAPATH_ID_HCI) { LOG_ERR("Input data path not set for HCI"); @@ -5850,6 +5817,8 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) struct ll_adv_iso_set *adv_iso; struct lll_adv_iso *lll_iso; uint16_t stream_handle; + uint8_t target_event; + uint8_t event_offset; uint16_t slen; /* FIXME: Code only expects header present */ @@ -5875,53 +5844,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) return -EINVAL; } - lll_iso = &adv_iso->lll; - -#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) - uint64_t event_count; - uint64_t pkt_seq_num; - - /* Catch up local pkt_seq_num with internal pkt_seq_num */ - event_count = lll_iso->payload_count / lll_iso->bn; - pkt_seq_num = event_count; - if (!(pb_flag & 0x01) && - (((pkt_seq_num - stream->pkt_seq_num) & - BIT64_MASK(39)) <= BIT64_MASK(38))) { - stream->pkt_seq_num = pkt_seq_num; - } else { - pkt_seq_num = stream->pkt_seq_num; - } - - /* Pre-increment, for next ISO data packet seq num comparison */ - if (pb_flag & 0x10) { - stream->pkt_seq_num++; - } - - /* Target next event to avoid overlapping with current event */ - /* FIXME: Implement ISO Tx ack generation early in done compared - * to currently only in prepare. I.e. to ensure upper - * layer has the number of completed packet before the - * next BIG event, so as to supply new ISO data packets. - * Without which upper layers need extra buffers to - * buffer next ISO data packet. - * - * Enable below increment once early Tx ack is - * implemented. - * - * pkt_seq_num++; - */ - sdu_frag_tx.target_event = pkt_seq_num; - sdu_frag_tx.grp_ref_point = - isoal_get_wrapped_time_us(adv_iso->big_ref_point, - (((pkt_seq_num + 1U) - - event_count) * - lll_iso->iso_interval * - ISO_INT_UNIT_US)); - -#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ - uint8_t target_event; - uint8_t event_offset; - /* Determine the target event and the first event offset after * datapath setup. * event_offset mitigates the possibility of first SDU being @@ -5939,6 +5861,7 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * BIG event by incrementing the previous elapsed big_ref_point * by one additional ISO interval. */ + lll_iso = &adv_iso->lll; target_event = lll_iso->payload_count / lll_iso->bn; event_offset = ull_ref_get(&adv_iso->ull) ? 0U : 1U; event_offset += lll_iso->latency_prepare; @@ -5949,7 +5872,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) ((event_offset + 1U) * lll_iso->iso_interval * ISO_INT_UNIT_US)); -#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ /* Start Fragmentation */ /* FIXME: need to ensure ISO-AL returns proper isoal_status. diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 474b8d0dbe9..62a684bbfa9 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -883,9 +883,6 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ cis->central.instant = instant; -#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) - cis->pkt_seq_num = 0U; -#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h index 39cee21d0b1..e8ca29da7af 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso_types.h @@ -48,10 +48,6 @@ struct ll_conn_iso_stream { */ uint8_t terminate_reason; uint8_t cis_id; - -#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) - uint64_t pkt_seq_num:39; -#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ }; struct ll_conn_iso_group { diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index 843bf877935..a707341f41c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -326,9 +326,6 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, cis->sync_delay = sys_get_le24(ind->cis_sync_delay); cis->offset = cis_offset; memcpy(cis->lll.access_addr, ind->aa, sizeof(ind->aa)); -#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) - cis->pkt_seq_num = 0U; -#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; From c32ef8aa7f674ac8dcceef1755d2505bac64b91e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:56 +0000 Subject: [PATCH 4171/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix ISO Data timestamp when FT > 1" This reverts commit 2694658063e3e5667cd8871632c23b268f71b54a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/lll_conn_iso.h | 3 --- .../controller/ll_sw/nordic/lll/lll_central_iso.c | 7 +------ .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 5 ----- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 1 - subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 1 - 5 files changed, 1 insertion(+), 16 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 0321b96f638..9822066f513 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -77,9 +77,6 @@ struct lll_conn_iso_group { uint8_t role:1; /* 0: CENTRAL, 1: PERIPHERAL*/ uint8_t paused:1; /* 1: CIG is paused */ - /* ISO interval to calculate timestamp under FT > 1 */ - uint32_t iso_interval_us; - /* Accumulates LLL prepare callback latencies */ uint16_t latency_prepare; uint16_t latency_event; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 4bf44a42cd9..d4f4c8c3262 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -716,7 +716,6 @@ static void isr_rx(void *param) (cis_lll->rx.bn_curr <= cis_lll->rx.bn) && (pdu_rx->sn == cis_lll->nesn) && ull_iso_pdu_rx_alloc_peek(2U)) { - struct lll_conn_iso_group *cig_lll; struct node_rx_iso_meta *iso_meta; cis_lll->nesn++; @@ -754,10 +753,6 @@ static void isr_rx(void *param) iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_ready_restore(); - cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); - iso_meta->timestamp -= (cis_lll->event_count - - (cis_lll->rx.payload_count / cis_lll->rx.bn)) * - cig_lll->iso_interval_us; iso_meta->timestamp %= HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); iso_meta->status = 0U; @@ -793,8 +788,8 @@ static void isr_rx(void *param) isr_rx_next_subevent: if (cie || (se_curr == cis_lll->nse)) { - struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *old_cis_lll; + struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_group *cig_lll; struct lll_conn *next_conn_lll; uint8_t phy; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 25401f5564e..75af765f9d0 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -545,7 +545,6 @@ static void isr_rx(void *param) (cis_lll->rx.bn_curr <= cis_lll->rx.bn) && (pdu_rx->sn == cis_lll->nesn) && ull_iso_pdu_rx_alloc_peek(2U)) { - struct lll_conn_iso_group *cig_lll; struct node_rx_iso_meta *iso_meta; cis_lll->nesn++; @@ -585,10 +584,6 @@ static void isr_rx(void *param) HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_aa_restore() - cis_offset_first - addr_us_get(cis_lll->rx.phy); - cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); - iso_meta->timestamp -= (cis_lll->event_count - - (cis_lll->rx.payload_count / cis_lll->rx.bn)) * - cig_lll->iso_interval_us; iso_meta->timestamp %= HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); iso_meta->status = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 62a684bbfa9..8c516826e06 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -254,7 +254,6 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) } iso_interval_us = cig->iso_interval * ISO_INT_UNIT_US; - cig->lll.iso_interval_us = iso_interval_us; lll_hdr_init(&cig->lll, cig); max_se_length = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index a707341f41c..eeef778734b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -191,7 +191,6 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cig->iso_interval = sys_le16_to_cpu(req->iso_interval); iso_interval_us = cig->iso_interval * CONN_INT_UNIT_US; - cig->lll.iso_interval_us = iso_interval_us; cig->cig_id = req->cig_id; cig->lll.handle = LLL_HANDLE_INVALID; From 3c045dade6b419552c3875d67074e3281e3d7e5c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:57 +0000 Subject: [PATCH 4172/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use of payload_count for Flush Timeout" This reverts commit 7c19e78ea41afa3f5b10c001af8bc84042620830. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/ll_sw/lll_conn_iso.h | 3 +- .../ll_sw/nordic/lll/lll_central_iso.c | 379 ++++++---------- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 405 +++++++----------- 3 files changed, 284 insertions(+), 503 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 9822066f513..7fdf6bf48d5 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -16,7 +16,8 @@ struct lll_conn_iso_stream_rxtx { uint64_t bn:4; /* Burst number (BN) */ uint64_t phy:3; /* PHY */ uint64_t rfu:1; - uint8_t bn_curr:4; /* Current burst number */ + uint8_t bn_curr:4; /* Current burst number */ + #if defined(CONFIG_BT_CTLR_LE_ENC) struct ccm ccm; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index d4f4c8c3262..936087369f1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -40,15 +40,14 @@ #include "hal/debug.h" static int init_reset(void); +static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll); +static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll); static int prepare_cb(struct lll_prepare_param *p); static void abort_cb(struct lll_prepare_param *prepare_param, void *param); static void isr_tx(void *param); static void isr_rx(void *param); static void isr_prepare_subevent(void *param); static void isr_done(void *param); -static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); -static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll); -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); static uint16_t next_cis_chan_remap_idx; static uint16_t next_cis_chan_prn_s; @@ -119,6 +118,24 @@ static int init_reset(void) return 0; } +static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll) +{ + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + uint8_t sn_update = cis_lll->tx.bn + 1U - cis_lll->tx.bn_curr; + + /* we'll re-use sn_update when implementing flush timeout */ + cis_lll->sn += sn_update; +} + +static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll) +{ + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + uint8_t nesn_update = cis_lll->rx.bn + 1U - cis_lll->rx.bn_curr; + + /* we'll re-use sn_update when implementing flush timeout */ + cis_lll->nesn += nesn_update; +} + static int prepare_cb(struct lll_prepare_param *p) { struct lll_conn_iso_group *cig_lll = p->param; @@ -180,10 +197,24 @@ static int prepare_cb(struct lll_prepare_param *p) /* Reset accumulated latencies */ cig_lll->latency_prepare = 0U; - se_curr = 1U; - /* Adjust the SN and NESN for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); + if (cis_lll->event_count) { + uint16_t cis_lazy; + + if (lazy > cis_lll->event_count) { + cis_lazy = lazy - cis_lll->event_count; + } else { + cis_lazy = lazy; + } + + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn += cis_lll->tx.bn * cis_lazy; + cis_lll->nesn += cis_lll->rx.bn * cis_lazy; + } + + se_curr = 1U; + cis_lll->tx.bn_curr = 1U; + cis_lll->rx.bn_curr = 1U; /* Start setting up of Radio h/w */ radio_reset(); @@ -217,8 +248,7 @@ static int prepare_cb(struct lll_prepare_param *p) struct node_tx_iso *node_tx; memq_link_t *link; - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; + payload_count = cis_lll->event_count * cis_lll->tx.bn; do { link = memq_peek(cis_lll->memq_tx.head, @@ -369,12 +399,33 @@ static int prepare_cb(struct lll_prepare_param *p) do { cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { - /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); + if (cis_lll->event_count) { + uint16_t cis_lazy; + + if (lazy > cis_lll->event_count) { + cis_lazy = lazy - cis_lll->event_count; + } else { + cis_lazy = lazy; + } - /* Adjust sn and nesn for canceled events */ - if (err) { - payload_count_flush_or_inc_on_close(cis_lll); + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn += cis_lll->tx.bn * cis_lazy; + cis_lll->nesn += cis_lll->rx.bn * cis_lazy; + + /* Adjust sn and nesn for canceled events */ + if (err) { + /* Adjust sn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } + } } } } while (cis_lll); @@ -399,21 +450,9 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) /* NOTE: This is not a prepare being cancelled */ if (!prepare_param) { - struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; - struct lll_conn_iso_group *cig_lll; cis_lll = ull_conn_iso_lll_stream_get(cis_handle_curr); - cig_lll = param; - - /* Adjust the SN, NESN and payload_count on abort for CISes */ - do { - next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, - &cis_handle_curr); - if (next_cis_lll && next_cis_lll->active) { - payload_count_flush_or_inc_on_close(next_cis_lll); - } - } while (next_cis_lll); /* Perform event abort here. * After event has been cleanly aborted, clean up resources @@ -469,8 +508,8 @@ static void isr_tx(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; + payload_count = (cis_lll->event_count * cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; @@ -613,9 +652,7 @@ static void isr_tx(void *param) cis_lll = next_cis_lll; /* Tx Ack stale ISO Data */ - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; - + payload_count = cis_lll->event_count * cis_lll->tx.bn; do { link = memq_peek(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, @@ -650,6 +687,8 @@ static void isr_tx(void *param) static void isr_rx(void *param) { struct lll_conn_iso_stream *cis_lll; + struct node_rx_pdu *node_rx; + struct pdu_cis *pdu_rx; uint8_t ack_pending; uint8_t trx_done; uint8_t crc_ok; @@ -675,8 +714,6 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done) { - payload_count_flush(cis_lll); - goto isr_rx_next_subevent; } @@ -686,23 +723,23 @@ static void isr_rx(void *param) /* Set the bit corresponding to CIS index */ trx_performed_bitmask |= (1U << LL_CIS_IDX_FROM_HANDLE(cis_lll->handle)); - if (crc_ok) { - struct node_rx_pdu *node_rx; - struct pdu_cis *pdu_rx; + /* Get reference to received PDU */ + node_rx = ull_iso_pdu_rx_alloc_peek(1U); + LL_ASSERT(node_rx); - /* Get reference to received PDU */ - node_rx = ull_iso_pdu_rx_alloc_peek(1U); - LL_ASSERT(node_rx); - pdu_rx = (void *)node_rx->pdu; + pdu_rx = (void *)node_rx->pdu; + if (crc_ok) { /* Tx ACK */ - if ((pdu_rx->nesn != cis_lll->sn) && (cis_lll->tx.bn_curr <= cis_lll->tx.bn)) { + if (pdu_rx->nesn != cis_lll->sn) { + /* Increment sequence number */ cis_lll->sn++; - cis_lll->tx.bn_curr++; - if ((cis_lll->tx.bn_curr > cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; + + /* Increment burst number */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + + cis_lll->tx.bn_curr++; + } /* TODO: Implement early Tx Ack. Currently Tx Ack @@ -718,6 +755,7 @@ static void isr_rx(void *param) ull_iso_pdu_rx_alloc_peek(2U)) { struct node_rx_iso_meta *iso_meta; + /* Increment next expected sequence number */ cis_lll->nesn++; #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -748,8 +786,9 @@ static void isr_rx(void *param) node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; node_rx->hdr.handle = cis_lll->handle; iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; + iso_meta->payload_number = (cis_lll->event_count * + cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_ready_restore(); @@ -764,23 +803,36 @@ static void isr_rx(void *param) iso_rx_sched(); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ + /* Increment burst number */ cis_lll->rx.bn_curr++; - if ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } /* Need to be acked */ ack_pending = 1U; + + /* Handle NULL PDU indication received */ + } else if (pdu_rx->npi) { + /* Source could not send ISO data, increment NESN as if + * we received and expect to receive the next PDU in the + * burst. + */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + /* Increment next expected serial number */ + cis_lll->nesn++; + + /* Increment burst number */ + cis_lll->rx.bn_curr++; + } + + /* Not NPI, or more than the BN, or no free Rx ISO PDU buffers. + */ + } else { + /* Do nothing, ignore the Rx buffer */ } /* Close Isochronous Event */ cie = cie || pdu_rx->cie; } - payload_count_flush(cis_lll); - /* Close Isochronous Event */ cie = cie || ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && (cis_lll->tx.bn_curr > cis_lll->tx.bn) && @@ -841,8 +893,7 @@ static void isr_rx(void *param) old_cis_lll = cis_lll; cis_lll = next_cis_lll; - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; + payload_count = cis_lll->event_count * cis_lll->tx.bn; do { link = memq_peek(cis_lll->memq_tx.head, @@ -876,10 +927,22 @@ static void isr_rx(void *param) cis_lll = old_cis_lll; } - payload_count_flush_or_inc_on_close(cis_lll); + /* Adjust sn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } /* Reset indices for the next CIS */ se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */ + next_cis_lll->tx.bn_curr = 1U; + next_cis_lll->rx.bn_curr = 1U; #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) radio_tx_power_set(next_conn_lll->tx_pwr_lvl); @@ -938,7 +1001,8 @@ static void isr_prepare_subevent(void *param) memq_link_t *link; payload_index = cis_lll->tx.bn_curr - 1U; - payload_count = cis_lll->tx.payload_count + payload_index; + payload_count = cis_lll->event_count * cis_lll->tx.bn + + payload_index; link = memq_peek_n(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, payload_index, (void **)&node_tx); @@ -1077,7 +1141,17 @@ static void isr_done(void *param) /* Get reference to CIS LLL context */ cis_lll = param; - payload_count_flush_or_inc_on_close(cis_lll); + /* Adjust sn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } e = ull_event_done_extra_get(); LL_ASSERT(e); @@ -1092,190 +1166,3 @@ static void isr_done(void *param) lll_isr_cleanup(param); } - -static void payload_count_flush(struct lll_conn_iso_stream *cis_lll) -{ - if (cis_lll->tx.bn) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - if ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == - (cis_lll->event_count + 1U)) && (u <= se_curr) && - (((cis_lll->tx.bn_curr < cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) <= cis_lll->event_count)) || - ((cis_lll->tx.bn_curr == cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn++; - cis_lll->tx.bn_curr++; - if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - } - } - - if (cis_lll->rx.bn) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - if ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == - (cis_lll->event_count + 1U)) && (u <= se_curr) && - (((cis_lll->rx.bn_curr < cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) <= cis_lll->event_count)) || - ((cis_lll->rx.bn_curr == cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - } - } -} - -static void payload_count_flush_or_inc_on_close(struct lll_conn_iso_stream *cis_lll) -{ - if (cis_lll->tx.bn) { - uint64_t payload_count; - uint8_t u; - - if (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.bn_curr) > - (cis_lll->event_count + cis_lll->tx.bn)) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - - goto payload_count_flush_or_inc_on_close_rx; - } - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - while ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == - (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn++; - cis_lll->tx.bn_curr++; - if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - } - } - -payload_count_flush_or_inc_on_close_rx: - if (cis_lll->rx.bn) { - uint64_t payload_count; - uint8_t u; - - if (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.bn_curr) > - (cis_lll->event_count + cis_lll->rx.bn)) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - - return; - } - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - while ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == - (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - } - } -} - -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) -{ - if (cis_lll->tx.bn) { - uint16_t tx_lazy; - - tx_lazy = lazy; - while (tx_lazy--) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - while (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < - (cis_lll->event_count + 1U)) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn++; - cis_lll->tx.bn_curr++; - if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - } - } - } - - if (cis_lll->rx.bn) { - while (lazy--) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - while (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < - (cis_lll->event_count + 1U)) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - - payload_count = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - } - } - } -} diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 75af765f9d0..3bbdb5fbf90 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -49,9 +49,8 @@ static void isr_prepare_subevent(void *param); static void isr_prepare_subevent_next_cis(void *param); static void isr_prepare_subevent_common(void *param); static void isr_done(void *param); -static void payload_count_flush(struct lll_conn_iso_stream *cis_lll); -static void payload_count_rx_flush_or_txrx_inc(struct lll_conn_iso_stream *cis_lll); -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy); +static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll); +static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll); static uint8_t next_chan_use; static uint16_t data_chan_id; @@ -62,6 +61,7 @@ static uint32_t trx_performed_bitmask; static uint16_t cis_offset_first; static uint16_t cis_handle_curr; static uint8_t se_curr; +static uint8_t has_tx; #if defined(CONFIG_BT_CTLR_LE_ENC) static uint8_t mic_state; @@ -135,6 +135,24 @@ static int init_reset(void) return 0; } +static inline void lll_flush_tx(struct lll_conn_iso_stream *cis_lll) +{ + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + uint8_t sn_update = cis_lll->tx.bn + 1U - cis_lll->tx.bn_curr; + + /* TODO we'll re-use sn_update when implementing flush timeout */ + cis_lll->sn += sn_update; +} + +static inline void lll_flush_rx(struct lll_conn_iso_stream *cis_lll) +{ + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + uint8_t nesn_update = cis_lll->rx.bn + 1U - cis_lll->rx.bn_curr; + + /* TODO we'll re-use nesn_update when implementing flush timeout */ + cis_lll->nesn += nesn_update; +} + static int prepare_cb(struct lll_prepare_param *p) { struct lll_conn_iso_group *cig_lll = p->param; @@ -207,10 +225,14 @@ static int prepare_cb(struct lll_prepare_param *p) EVENT_US_TO_US_FRAC(cig_lll->window_widening_max_us); } - se_curr = 1U; - /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn += (cis_lll->tx.bn * lazy); + cis_lll->nesn += cis_lll->rx.bn * lazy; + + se_curr = 1U; + cis_lll->rx.bn_curr = 1U; + has_tx = 0U; /* Start setting up of Radio h/w */ radio_reset(); @@ -238,9 +260,8 @@ static int prepare_cb(struct lll_prepare_param *p) uint64_t payload_cnt; uint8_t pkt_flags; - payload_cnt = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; - + payload_cnt = (cis_lll->event_count * cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_cnt; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -351,10 +372,9 @@ static int prepare_cb(struct lll_prepare_param *p) /* Adjust the SN and NESN for skipped CIG events */ uint16_t cis_handle = cis_handle_curr; - do { - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; - + while (true) { + /* FIXME: Update below implementation when supporting Flush Timeout */ + payload_count = cis_lll->event_count * cis_lll->tx.bn; do { link = memq_peek(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, (void **)&tx); @@ -372,22 +392,26 @@ static int prepare_cb(struct lll_prepare_param *p) } } while (link); - do { - cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); - } while (cis_lll && !cis_lll->active); - + cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (!cis_lll) { break; } - /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, lazy); - - /* Adjust sn and nesn for canceled events */ - if (err) { - payload_count_rx_flush_or_txrx_inc(cis_lll); + if (cis_lll->active) { + /* sn and nesn are 1-bit, only Least Significant bit is needed */ + cis_lll->sn += cis_lll->tx.bn * lazy; + cis_lll->nesn += cis_lll->rx.bn * lazy; + + /* Adjust sn and nesn for canceled events */ + if (err) { + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } + } } - } while (cis_lll); + }; /* Return if prepare callback cancelled */ if (err) { @@ -409,21 +433,24 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) /* NOTE: This is not a prepare being cancelled */ if (!prepare_param) { - struct lll_conn_iso_stream *next_cis_lll; + struct lll_conn_iso_group *cig_lll = param; struct lll_conn_iso_stream *cis_lll; - struct lll_conn_iso_group *cig_lll; - cis_lll = ull_conn_iso_lll_stream_get(cis_handle_curr); - cig_lll = param; + cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, NULL); - /* Adjust the SN, NESN and payload_count on abort for CISes */ - do { - next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, - &cis_handle_curr); - if (next_cis_lll && next_cis_lll->active) { - payload_count_rx_flush_or_txrx_inc(next_cis_lll); + /* FIXME: Consider Flush Timeout when resetting current burst number */ + if (!has_tx) { + has_tx = 1U; + + /* Adjust nesn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); } - } while (next_cis_lll); + + /* Set to last burst number in previous event */ + cis_lll->tx.bn_curr = cis_lll->tx.bn; + } /* Perform event abort here. * After event has been cleanly aborted, clean up resources @@ -473,9 +500,20 @@ static void isr_rx(void *param) /* No Rx */ if (!trx_done) { - payload_count_flush(cis_lll); + /* FIXME: Consider Flush Timeout when resetting current burst number */ + if (!has_tx) { + has_tx = 1U; + + /* Adjust nesn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Start transmitting new burst */ + cis_lll->tx.bn_curr = cis_lll->tx.bn; + } - /* Next subevent or next CIS */ if (se_curr < cis_lll->nse) { radio_isr_set(isr_prepare_subevent, param); } else { @@ -524,20 +562,17 @@ static void isr_rx(void *param) pdu_rx = (void *)node_rx->pdu; /* Tx ACK */ - if ((pdu_rx->nesn != cis_lll->sn) && (cis_lll->tx.bn_curr <= cis_lll->tx.bn)) { + if (pdu_rx->nesn != cis_lll->sn) { + /* Increment sequence number */ cis_lll->sn++; - cis_lll->tx.bn_curr++; - if ((cis_lll->tx.bn_curr > cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) < - cis_lll->event_count)) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; + + /* Increment burst number */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + cis_lll->tx.bn_curr++; } - /* TODO: Implement early Tx Ack. Currently Tx Ack - * generated as stale Tx Ack when payload count - * has elapsed. - */ + /* TODO: Tx Ack */ + } /* Handle valid ISO data Rx */ @@ -547,6 +582,7 @@ static void isr_rx(void *param) ull_iso_pdu_rx_alloc_peek(2U)) { struct node_rx_iso_meta *iso_meta; + /* Increment next expected sequence number */ cis_lll->nesn++; #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -578,8 +614,9 @@ static void isr_rx(void *param) node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; node_rx->hdr.handle = cis_lll->handle; iso_meta = &node_rx->hdr.rx_iso_meta; - iso_meta->payload_number = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; + iso_meta->payload_number = (cis_lll->event_count * + cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); iso_meta->timestamp = cis_lll->offset + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + radio_tmr_aa_restore() - cis_offset_first - @@ -595,19 +632,46 @@ static void isr_rx(void *param) iso_rx_sched(); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ + /* Increment burst number */ cis_lll->rx.bn_curr++; - if ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; + + /* Handle NULL PDU indication received */ + } else if (pdu_rx->npi) { + /* Source could not send ISO data, increment NESN as if + * we received and expect to receive the next PDU in the + * burst. + */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + /* Increment next expected serial number */ + cis_lll->nesn++; + + /* Increment burst number */ + cis_lll->rx.bn_curr++; } + + /* Not NPI, or more than the BN, or no free Rx ISO PDU buffers. + */ + } else { + /* Do nothing, ignore the Rx buffer */ } /* Close Isochronous Event */ cie = cie || pdu_rx->cie; } - payload_count_flush(cis_lll); + /* FIXME: Consider Flush Timeout when resetting current burst number */ + if (!has_tx) { + has_tx = 1U; + + /* Adjust nesn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Start transmitting new burst */ + cis_lll->tx.bn_curr = 1U; + } /* Close Isochronous Event */ cie = cie || ((cis_lll->rx.bn_curr > cis_lll->rx.bn) && @@ -632,7 +696,8 @@ static void isr_rx(void *param) memq_link_t *link; payload_index = cis_lll->tx.bn_curr - 1U; - payload_count = cis_lll->tx.payload_count + payload_index; + payload_count = cis_lll->event_count * cis_lll->tx.bn + + payload_index; link = memq_peek_n(cis_lll->memq_tx.head, cis_lll->memq_tx.tail, payload_index, (void **)&tx); @@ -736,7 +801,6 @@ static void isr_rx(void *param) &data_chan_prn_s, &data_chan_remap_idx); } else { - struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_group *cig_lll; uint16_t event_counter; uint16_t cis_handle; @@ -745,34 +809,34 @@ static void isr_rx(void *param) cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); cis_handle = cis_handle_curr; do { - next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); - } while (next_cis_lll && !next_cis_lll->active); + cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + } while (cis_lll && !cis_lll->active); - if (!next_cis_lll) { + if (!cis_lll) { /* ISO Event Done */ radio_isr_set(isr_done, param); return; } - payload_count_rx_flush_or_txrx_inc(cis_lll); - cis_handle_curr = cis_handle; /* Event counter value, 0-15 bit of cisEventCounter */ - event_counter = next_cis_lll->event_count; + event_counter = cis_lll->event_count; /* Calculate the radio channel to use for next CIS ISO event */ - data_chan_id = lll_chan_id(next_cis_lll->access_addr); + data_chan_id = lll_chan_id(cis_lll->access_addr); next_chan_use = lll_chan_iso_event(event_counter, data_chan_id, conn_lll->data_chan_map, conn_lll->data_chan_count, &data_chan_prn_s, &data_chan_remap_idx); - /* Next CIS, se_curr is incremented in isr_tx() */ - cis_lll = next_cis_lll; - se_curr = 0U; + /* Reset indices for the next CIS */ + se_curr = 0U; /* isr_tx() will increase se_curr */ + cis_lll->tx.bn_curr = 1U; /* FIXME: may be this should be previous event value? */ + cis_lll->rx.bn_curr = 1U; + has_tx = 0U; } /* Schedule next subevent reception */ @@ -830,9 +894,8 @@ static void isr_tx(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; - + payload_count = (cis_lll->event_count * cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -933,7 +996,6 @@ static void isr_tx(void *param) static void next_cis_prepare(void *param) { - struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; struct lll_conn_iso_group *cig_lll; uint16_t cis_handle; @@ -943,13 +1005,12 @@ static void next_cis_prepare(void *param) /* Check for next active CIS */ cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll); - next_cis_lll = cis_lll; cis_handle = cis_handle_curr; do { - next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); - } while (next_cis_lll && !next_cis_lll->active); + cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); + } while (cis_lll && !cis_lll->active); - if (!next_cis_lll) { + if (!cis_lll) { /* ISO Event Done */ radio_isr_set(isr_done, param); @@ -958,7 +1019,7 @@ static void next_cis_prepare(void *param) cis_handle_curr = cis_handle; - radio_isr_set(isr_prepare_subevent_next_cis, next_cis_lll); + radio_isr_set(isr_prepare_subevent_next_cis, cis_lll); } static void isr_prepare_subevent(void *param) @@ -1010,8 +1071,11 @@ static void isr_prepare_subevent_next_cis(void *param) &data_chan_prn_s, &data_chan_remap_idx); - /* se_curr is incremented in isr_prepare_subevent_common() */ - se_curr = 0U; + /* Reset indices for the next CIS */ + se_curr = 0U; /* isr_prepare_subevent_common() will increase se_curr */ + cis_lll->tx.bn_curr = 1U; /* FIXME: may be this should be previous event value? */ + cis_lll->rx.bn_curr = 1U; + has_tx = 0U; isr_prepare_subevent_common(param); } @@ -1047,9 +1111,8 @@ static void isr_prepare_subevent_common(void *param) uint64_t payload_count; uint8_t pkt_flags; - payload_count = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; - + payload_count = (cis_lll->event_count * cis_lll->rx.bn) + + (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, @@ -1172,7 +1235,11 @@ static void isr_done(void *param) /* Get reference to CIS LLL context */ cis_lll = param; - payload_count_rx_flush_or_txrx_inc(cis_lll); + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } e = ull_event_done_extra_get(); LL_ASSERT(e); @@ -1208,177 +1275,3 @@ static void isr_done(void *param) lll_isr_cleanup(param); } - -static void payload_count_flush(struct lll_conn_iso_stream *cis_lll) -{ - if (cis_lll->tx.bn) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - while (((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == - (cis_lll->event_count + 1U)) && (u < se_curr))) && - (((cis_lll->tx.bn_curr < cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) <= cis_lll->event_count)) || - ((cis_lll->tx.bn_curr == cis_lll->tx.bn) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) < cis_lll->event_count)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn++; - cis_lll->tx.bn_curr++; - if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - } - } - - if (cis_lll->rx.bn) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - if ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == - (cis_lll->event_count + 1U)) && (u <= se_curr) && - (((cis_lll->rx.bn_curr < cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) <= cis_lll->event_count)) || - ((cis_lll->rx.bn_curr == cis_lll->rx.bn) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) < cis_lll->event_count)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - } - } -} - -static void payload_count_rx_flush_or_txrx_inc(struct lll_conn_iso_stream *cis_lll) -{ - if (cis_lll->tx.bn) { - if (((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.bn_curr) > - (cis_lll->event_count + cis_lll->tx.bn)) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - } - - if (cis_lll->rx.bn) { - uint64_t payload_count; - uint8_t u; - - if (((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.bn_curr) > - (cis_lll->event_count + cis_lll->rx.bn)) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - - return; - } - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - while ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == - (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - } - } -} - -static void payload_count_lazy(struct lll_conn_iso_stream *cis_lll, uint16_t lazy) -{ - if (cis_lll->tx.bn && lazy) { - uint16_t tx_lazy; - - tx_lazy = lazy; - while (tx_lazy--) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->tx.payload_count + cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - while (((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->tx.payload_count / cis_lll->tx.bn) + cis_lll->tx.ft) == - (cis_lll->event_count + 1U)) && (u < (cis_lll->nse + 1U)))) && - ((cis_lll->tx.payload_count / cis_lll->tx.bn) < - cis_lll->event_count)) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->sn++; - cis_lll->tx.bn_curr++; - if (cis_lll->tx.bn_curr > cis_lll->tx.bn) { - cis_lll->tx.payload_count += cis_lll->tx.bn; - cis_lll->tx.bn_curr = 1U; - } - - payload_count = cis_lll->tx.payload_count + - cis_lll->tx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->tx.bn) * - (cis_lll->tx.bn - 1U - - (payload_count % cis_lll->tx.bn))); - } - } - } - - if (cis_lll->rx.bn) { - while (lazy--) { - uint64_t payload_count; - uint8_t u; - - payload_count = cis_lll->rx.payload_count + cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - while (((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) < - (cis_lll->event_count + 1U)) || - ((((cis_lll->rx.payload_count / cis_lll->rx.bn) + cis_lll->rx.ft) == - (cis_lll->event_count + 1U)) && (u <= (cis_lll->nse + 1U)))) && - ((cis_lll->rx.payload_count / cis_lll->rx.bn) < - cis_lll->event_count)) { - /* sn and nesn are 1-bit, only Least Significant bit is needed */ - cis_lll->nesn++; - cis_lll->rx.bn_curr++; - if (cis_lll->rx.bn_curr > cis_lll->rx.bn) { - cis_lll->rx.payload_count += cis_lll->rx.bn; - cis_lll->rx.bn_curr = 1U; - } - - payload_count = cis_lll->rx.payload_count + - cis_lll->rx.bn_curr - 1U; - u = cis_lll->nse - ((cis_lll->nse / cis_lll->rx.bn) * - (cis_lll->rx.bn - 1U - - (payload_count % cis_lll->rx.bn))); - } - } - } -} From a102589e3b426b2fa2f2a0ec5661766877299265 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:57 +0000 Subject: [PATCH 4173/4498] Revert "[nrf fromtree] Bluetooth: Controller: Remove HCI ISO data with invalid status" This reverts commit 495dce2550cd4bba79af1b4429d8ab8f377244d4. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/lll/lll_central_iso.c | 97 +++++++++++++++++-- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 43 ++++++++ 2 files changed, 132 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 936087369f1..46360ef88d7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -845,6 +845,7 @@ static void isr_rx(void *param) struct lll_conn_iso_group *cig_lll; struct lll_conn *next_conn_lll; uint8_t phy; + uint8_t bn; /* Fetch next CIS */ /* TODO: Use a new ull_conn_iso_lll_stream_get_active_by_group() @@ -860,6 +861,18 @@ static void isr_rx(void *param) goto isr_rx_done; } + /* Adjust sn when flushing Tx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { + lll_flush_tx(cis_lll); + } + + /* Adjust nesn when flushing Rx */ + /* FIXME: When Flush Timeout is implemented */ + if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { + lll_flush_rx(cis_lll); + } + /* Get reference to ACL context */ next_conn_lll = ull_conn_lll_get(next_cis_lll->acl_handle); @@ -927,17 +940,45 @@ static void isr_rx(void *param) cis_lll = old_cis_lll; } - /* Adjust sn when flushing Tx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->tx.bn_curr <= cis_lll->tx.bn) { - lll_flush_tx(cis_lll); + /* Generate ISO Data Invalid Status */ + bn = cis_lll->rx.bn_curr; + while (bn <= cis_lll->rx.bn) { + struct node_rx_iso_meta *iso_meta; + struct node_rx_pdu *status_node_rx; + + /* Ensure there is always one free for reception + * of ISO PDU by the radio h/w DMA, hence peek + * for two available ISO PDU when using one for + * generating invalid ISO data. + */ + status_node_rx = ull_iso_pdu_rx_alloc_peek(2U); + if (!status_node_rx) { + break; + } + + status_node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; + status_node_rx->hdr.handle = cis_lll->handle; + iso_meta = &status_node_rx->hdr.rx_iso_meta; + iso_meta->payload_number = (cis_lll->event_count * + cis_lll->rx.bn) + (bn - 1U); + iso_meta->timestamp = + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + + radio_tmr_ready_restore(); + iso_meta->timestamp %= + HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); + iso_meta->status = 1U; + + ull_iso_pdu_rx_alloc(); + iso_rx_put(status_node_rx->hdr.link, status_node_rx); + + bn++; } - /* Adjust nesn when flushing Rx */ - /* FIXME: When Flush Timeout is implemented */ - if (cis_lll->rx.bn_curr <= cis_lll->rx.bn) { - lll_flush_rx(cis_lll); +#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) + if (bn != cis_lll->rx.bn_curr) { + iso_rx_sched(); } +#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ /* Reset indices for the next CIS */ se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */ @@ -1135,6 +1176,7 @@ static void isr_done(void *param) { struct lll_conn_iso_stream *cis_lll; struct event_done_extra *e; + uint8_t bn; lll_isr_status_reset(); @@ -1153,6 +1195,45 @@ static void isr_done(void *param) lll_flush_rx(cis_lll); } + /* Generate ISO Data Invalid Status */ + bn = cis_lll->rx.bn_curr; + while (bn <= cis_lll->rx.bn) { + struct node_rx_iso_meta *iso_meta; + struct node_rx_pdu *node_rx; + + /* Ensure there is always one free for reception of ISO PDU by + * the radio h/w DMA, hence peek for two available ISO PDU when + * using one for generating invalid ISO data. + */ + node_rx = ull_iso_pdu_rx_alloc_peek(2U); + if (!node_rx) { + break; + } + + node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; + node_rx->hdr.handle = cis_lll->handle; + iso_meta = &node_rx->hdr.rx_iso_meta; + iso_meta->payload_number = (cis_lll->event_count * + cis_lll->rx.bn) + (bn - 1U); + iso_meta->timestamp = + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + + radio_tmr_ready_restore(); + iso_meta->timestamp %= + HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); + iso_meta->status = 1U; + + ull_iso_pdu_rx_alloc(); + iso_rx_put(node_rx->hdr.link, node_rx); + + bn++; + } + +#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) + if (bn != cis_lll->rx.bn_curr) { + iso_rx_sched(); + } +#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ + e = ull_event_done_extra_get(); LL_ASSERT(e); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 3bbdb5fbf90..13238c081cf 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -1229,6 +1229,7 @@ static void isr_done(void *param) { struct lll_conn_iso_stream *cis_lll; struct event_done_extra *e; + uint8_t bn; lll_isr_status_reset(); @@ -1241,6 +1242,48 @@ static void isr_done(void *param) lll_flush_rx(cis_lll); } + /* Generate ISO Data Invalid Status */ + bn = cis_lll->rx.bn_curr; + while (bn <= cis_lll->rx.bn) { + struct node_rx_iso_meta *iso_meta; + struct node_rx_pdu *node_rx; + + node_rx = ull_iso_pdu_rx_alloc_peek(2U); + if (!node_rx) { + break; + } + + node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU; + node_rx->hdr.handle = cis_lll->handle; + iso_meta = &node_rx->hdr.rx_iso_meta; + iso_meta->payload_number = (cis_lll->event_count * + cis_lll->rx.bn) + (bn - 1U); + if (trx_performed_bitmask) { + iso_meta->timestamp = cis_lll->offset + + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + + radio_tmr_aa_restore() - cis_offset_first - + addr_us_get(cis_lll->rx.phy); + } else { + iso_meta->timestamp = cis_lll->offset + + HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) + + radio_tmr_ready_restore() - cis_offset_first; + } + iso_meta->timestamp %= + HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U)); + iso_meta->status = 1U; + + ull_iso_pdu_rx_alloc(); + iso_rx_put(node_rx->hdr.link, node_rx); + + bn++; + } + +#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) + if (bn != cis_lll->rx.bn_curr) { + iso_rx_sched(); + } +#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ + e = ull_event_done_extra_get(); LL_ASSERT(e); From 38bf5250815f52d5851332d99dac39788144d699 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:57 +0000 Subject: [PATCH 4174/4498] Revert "[nrf fromtree] Bluetooth controller nrf: Provide radio hal header for simulated nrf5340" This reverts commit 10552082f75c89d7b69b7ad5b4ee815d84348761. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 2 - .../nordic/hal/nrf5/radio/radio_sim_nrf5340.h | 431 ------------------ 2 files changed, 433 deletions(-) delete mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 842b4189184..9e29ab5f70b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -17,8 +17,6 @@ /* SoC specific defines */ #if defined(CONFIG_BOARD_NRF52_BSIM) #include "radio_sim_nrf52.h" -#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) -#include "radio_sim_nrf5340.h" #elif defined(CONFIG_SOC_SERIES_NRF51X) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h deleted file mode 100644 index c0cd88b30b0..00000000000 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * Copyright (c) 2019 Ioannis Glaropoulos - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/* NRF Radio HW timing constants - * - provided in US and NS (for higher granularity) - * - based on the timings configured in the HW models, which are based - * on the product specification - * - Note that this timings are approx. the same as in the real HW, - * but tend to be rounded to the nearest microsecond - */ - -/* Override EVENT_TIMER_ID from 4 to 0, as nRF5340 does not have 4 timer - * instances. - */ -#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) -#undef EVENT_TIMER_ID -#define EVENT_TIMER_ID 0 - -#undef EVENT_TIMER -#define EVENT_TIMER _CONCAT(NRF_TIMER, EVENT_TIMER_ID) - -#undef SW_SWITCH_TIMER -#define SW_SWITCH_TIMER EVENT_TIMER -#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ - -/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) - * in microseconds for LE 1M PHY. - */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS 41000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_US \ - HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS) - -/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) - * in microseconds for LE 1M PHY. - */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS 141000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_US \ - HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS) - -/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode - * and no HW TIFS auto-switch) in microseconds for LE 1M PHY. - */ - /* 129.5 + 0.8 */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS 130000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US \ - HAL_RADIO_NS2US_ROUND( \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS) - -/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) - * in microseconds for LE 2M PHY. - */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS 40000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_US \ - HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS) - -/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) - * in microseconds for LE 2M PHY. - */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS 140000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_US \ - HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS) - -/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and - * no HW TIFS auto-switch) in microseconds for LE 2M PHY. - */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS 129000 -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US \ - HAL_RADIO_NS2US_ROUND( \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) - * in microseconds for LE 1M PHY. - */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS 40000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_US \ - HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) - * in microseconds for LE 1M PHY. - */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS 140000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_US \ - HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and - * no HW TIFS auto-switch) in microseconds for LE 1M PHY. - */ -/* 129.5 + 0.2 */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS 129000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US \ - HAL_RADIO_NS2US_CEIL( \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) - * in microseconds for LE 2M PHY. - */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS 40000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_US \ - HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) - * in microseconds for LE 2M PHY. - */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS 140000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_US \ - HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS) - -/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and - * no HW TIFS auto-switch) in microseconds for LE 2M PHY. - */ -/* 129.5 + 0.2 */ -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS 129000 -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US \ - HAL_RADIO_NS2US_CEIL( \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS) - -#define HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS 1000 -#define HAL_RADIO_NRF5340_TX_CHAIN_DELAY_US \ - HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS) - -#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_US 9 -#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_NS 9000 -#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_US 5 -#define HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_NS 5000 - -#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_FAST_NS - -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_FAST_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_FAST_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_FAST_NS - -#else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ -#if defined(CONFIG_BT_CTLR_TIFS_HW) -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NS - -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NS - -#else /* !CONFIG_BT_CTLR_TIFS_HW */ -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS - -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US -#define HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS \ - HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS - -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US -#define HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS \ - HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS - -#endif /* !CONFIG_BT_CTLR_TIFS_HW */ -#endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ - -/* nRF5340 supports +3dBm Tx Power using high voltage request, define +3dBm - * value for Controller use. - */ -#ifndef RADIO_TXPOWER_TXPOWER_Pos3dBm -#define RADIO_TXPOWER_TXPOWER_Pos3dBm (0x03UL) -#endif - -/* SoC specific NRF_RADIO power-on reset value. Refer to Product Specification, - * RADIO Registers section for the documented reset values. - * - * NOTE: Only implementation used values defined here. - * In the future if MDK or nRFx header include these, use them instead. - */ -#define HAL_RADIO_RESET_VALUE_DFEMODE 0x00000000UL -#define HAL_RADIO_RESET_VALUE_CTEINLINECONF 0x00002800UL - -static inline void hal_radio_tx_power_high_voltage_clear(void); - -static inline void hal_radio_reset(void) -{ -} - -static inline void hal_radio_stop(void) -{ - /* If +3dBm Tx power was used, then turn off high voltage when radio not - * used. - */ - hal_radio_tx_power_high_voltage_clear(); -} - -static inline void hal_radio_ram_prio_setup(void) -{ -} - -static inline uint32_t hal_radio_phy_mode_get(uint8_t phy, uint8_t flags) -{ - uint32_t mode; - - switch (phy) { - case BIT(0): - default: - mode = RADIO_MODE_MODE_Ble_1Mbit; - break; - - case BIT(1): - mode = RADIO_MODE_MODE_Ble_2Mbit; - break; - -#if defined(CONFIG_BT_CTLR_PHY_CODED) - case BIT(2): - if (flags & 0x01) { - mode = RADIO_MODE_MODE_Ble_LR125Kbit; - } else { - mode = RADIO_MODE_MODE_Ble_LR500Kbit; - } - break; -#endif /* CONFIG_BT_CTLR_PHY_CODED */ - } - - return mode; -} - -static inline uint32_t hal_radio_tx_power_max_get(void) -{ - return RADIO_TXPOWER_TXPOWER_0dBm; -} - -static inline uint32_t hal_radio_tx_power_min_get(void) -{ - return RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) -{ - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) { - return RADIO_TXPOWER_TXPOWER_Neg1dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) { - return RADIO_TXPOWER_TXPOWER_Neg2dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { - return RADIO_TXPOWER_TXPOWER_Neg3dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm) { - return RADIO_TXPOWER_TXPOWER_Neg5dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm) { - return RADIO_TXPOWER_TXPOWER_Neg6dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm) { - return RADIO_TXPOWER_TXPOWER_Neg7dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { - return RADIO_TXPOWER_TXPOWER_Neg16dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - /* Note: The -30 dBm power level is deprecated so ignore it! */ - return RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -static inline void hal_radio_tx_power_high_voltage_set(int8_t tx_power_lvl) -{ - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { - nrf_vreqctrl_radio_high_voltage_set(NRF_VREQCTRL, true); - } -} - -static inline void hal_radio_tx_power_high_voltage_clear(void) -{ - nrf_vreqctrl_radio_high_voltage_set(NRF_VREQCTRL, false); -} - -static inline uint32_t hal_radio_tx_ready_delay_us_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_US; - case BIT(1): - return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_US; - } -} - -static inline uint32_t hal_radio_rx_ready_delay_us_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_US; - case BIT(1): - return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_US; - } -} - -static inline uint32_t hal_radio_tx_chain_delay_us_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(phy); - ARG_UNUSED(flags); - - return HAL_RADIO_NRF5340_TX_CHAIN_DELAY_US; -} - -static inline uint32_t hal_radio_rx_chain_delay_us_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_US; - case BIT(1): - return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_US; - } -} - -static inline uint32_t hal_radio_tx_ready_delay_ns_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_1M_NS; - case BIT(1): - return HAL_RADIO_NRF5340_TXEN_TXIDLE_TX_2M_NS; - } -} - -static inline uint32_t hal_radio_rx_ready_delay_ns_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_1M_NS; - case BIT(1): - return HAL_RADIO_NRF5340_RXEN_RXIDLE_RX_2M_NS; - } -} - -static inline uint32_t hal_radio_tx_chain_delay_ns_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(phy); - ARG_UNUSED(flags); - - return HAL_RADIO_NRF5340_TX_CHAIN_DELAY_NS; -} - -static inline uint32_t hal_radio_rx_chain_delay_ns_get(uint8_t phy, uint8_t flags) -{ - ARG_UNUSED(flags); - - switch (phy) { - default: - case BIT(0): - return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_1M_NS; - case BIT(1): - return HAL_RADIO_NRF5340_RX_CHAIN_DELAY_2M_NS; - - } -} From 309de192c5ea78ae783f3557de57085b2ee6fdb2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:57 +0000 Subject: [PATCH 4175/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix clang warning on ull" This reverts commit 4b5aac399c721b01dfd7924ce565d367e526fa59. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 3130978df4e..9811076b9ba 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -1232,8 +1232,10 @@ void ll_rx_dequeue(void) /* FIXME: use the correct adv and scan set to get * enabled status bitmask */ - bm = (IS_ENABLED(CONFIG_BT_OBSERVER)?(ull_scan_is_enabled(0) << 1):0) | - (IS_ENABLED(CONFIG_BT_BROADCASTER)?ull_adv_is_enabled(0):0); + bm = (IS_ENABLED(CONFIG_BT_OBSERVER) && + (ull_scan_is_enabled(0) << 1)) | + (IS_ENABLED(CONFIG_BT_BROADCASTER) && + ull_adv_is_enabled(0)); if (!bm) { ull_filter_adv_scan_state_cb(0); From 10afa7e7695f03b5ed60c74fc2e486c16aac0600 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:58 +0000 Subject: [PATCH 4176/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix regression in Adv PDU overflow calculation" This reverts commit a993ec04f01370731fd9fbdb1eaec298d865beff. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_adv_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 302dc6da785..5349b21dd9f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -1804,7 +1804,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv, /* TODO: need aux_chain_ind support */ if ((sec_len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) { /* return excess length */ - *(uint8_t *)hdr_data = sec_len + ad_len + ad_fragment_len - + *(uint8_t *)hdr_data = sec_len + ad_len - PDU_AC_PAYLOAD_SIZE_MAX; if (pri_pdu == pri_pdu_prev) { @@ -2272,7 +2272,7 @@ uint8_t ull_adv_aux_pdu_set_clear(struct ll_adv_set *adv, /* Check AdvData overflow */ if ((len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) { /* return excess length */ - *(uint8_t *)hdr_data = len + ad_len + ad_fragment_len - + *(uint8_t *)hdr_data = len + ad_len - PDU_AC_PAYLOAD_SIZE_MAX; /* Will use packet too long error to determine fragmenting From 172ea10cdf91b8f60c201f7875bbb2dcdd0a677a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:58 +0000 Subject: [PATCH 4177/4498] Revert "[nrf fromtree] Bluetooth: controller: adding API for unmasking peer features" This reverts commit 340f46a013f08c35562f1aa1d75464e61246b77e. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c | 4 ++-- subsys/bluetooth/controller/ll_sw/ull_llcp_features.h | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c index 59c23e7a0f6..69dc80bda13 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c @@ -921,14 +921,14 @@ static void lp_cc_st_wait_rx_cis_rsp(struct ll_conn *conn, struct proc_ctx *ctx, break; case LP_CC_EVT_UNKNOWN: /* Unsupported in peer, so disable locally for this connection */ - feature_unmask_peer_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); + feature_unmask_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); ctx->data.cis_create.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; lp_cc_complete(conn, ctx, evt, param); break; case LP_CC_EVT_REJECT: if (pdu->llctrl.reject_ext_ind.error_code == BT_HCI_ERR_UNSUPP_REMOTE_FEATURE) { /* Unsupported in peer, so disable locally for this connection */ - feature_unmask_peer_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); + feature_unmask_features(conn, LL_FEAT_BIT_CIS_PERIPHERAL); } ctx->data.cis_create.error = pdu->llctrl.reject_ext_ind.error_code; lp_cc_complete(conn, ctx, evt, param); diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h b/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h index 75d92d5524e..ac60206bc70 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_features.h @@ -9,11 +9,6 @@ static inline void feature_unmask_features(struct ll_conn *conn, uint64_t ll_fea conn->llcp.fex.features_used &= ~ll_feat_mask; } -static inline void feature_unmask_peer_features(struct ll_conn *conn, uint64_t ll_feat_mask) -{ - conn->llcp.fex.features_peer &= ~ll_feat_mask; -} - static inline bool feature_le_encryption(struct ll_conn *conn) { #if defined(CONFIG_BT_CTLR_LE_ENC) From a9a993c13027ae75f750ae4e7dbe843b7c08ae31 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:58 +0000 Subject: [PATCH 4178/4498] Revert "[nrf fromtree] Bluetooth: controller: add missing NTF alloc in central CIS Create" This reverts commit 48accabe1924f7c77291a9cad93c26e92df14447. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/ll_sw/ull_llcp_cc.c | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c index 69dc80bda13..387cc884dea 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c @@ -643,7 +643,6 @@ static void lp_cc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ /* LLCP Local Procedure FSM states */ enum { LP_CC_STATE_IDLE, - LP_CC_STATE_WAIT_NTF_AVAIL, LP_CC_STATE_WAIT_OFFSET_CALC, LP_CC_STATE_WAIT_OFFSET_CALC_TX_REQ, LP_CC_STATE_WAIT_TX_CIS_REQ, @@ -840,7 +839,7 @@ static void lp_cc_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t ev } else { /* Peer doesn't support CIS Peripheral so report unsupported */ ctx->data.cis_create.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; - ctx->state = LP_CC_STATE_WAIT_NTF_AVAIL; + lp_cc_complete(conn, ctx, evt, param); } break; default: @@ -855,26 +854,6 @@ static void lp_cc_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t ev } } -static void lp_cc_state_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, - void *param) -{ - switch (evt) { - case LP_CC_EVT_RUN: - if (llcp_ntf_alloc_is_available()) { - ctx->node_ref.rx = llcp_ntf_alloc(); - /* Mark node as RETAIN to trigger put/sched */ - ctx->node_ref.rx->hdr.type = NODE_RX_TYPE_RETAIN; - - /* Now we're good to complete procedure*/ - lp_cc_complete(conn, ctx, evt, param); - } - break; - default: - /* Ignore other evts */ - break; - } -} - static void cc_prepare_cis_ind(struct ll_conn *conn, struct proc_ctx *ctx) { uint8_t err; @@ -1061,9 +1040,6 @@ static void lp_cc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ case LP_CC_STATE_IDLE: lp_cc_st_idle(conn, ctx, evt, param); break; - case LP_CC_STATE_WAIT_NTF_AVAIL: - lp_cc_state_wait_ntf_avail(conn, ctx, evt, param); - break; case LP_CC_STATE_WAIT_OFFSET_CALC_TX_REQ: lp_cc_st_wait_offset_calc_tx_req(conn, ctx, evt, param); break; From 221791d75f246df2cbac23af7d535eb889151a56 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:58 +0000 Subject: [PATCH 4179/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix connected ISO dynamic tx power" This reverts commit 287777875f227f7ba6b1691973f5ae708ff90d16. Signed-off-by: Dominik Ermel --- .../hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf | 3 --- samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf | 3 --- .../bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c | 4 ++-- .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf b/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf index e9e5ac63483..bb95b6ea74e 100644 --- a/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_rpmsg/nrf5340_cpunet_iso-bt_ll_sw_split.conf @@ -112,6 +112,3 @@ CONFIG_BT_CTLR_ISOAL_SOURCES=2 # ISO Receptions CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 CONFIG_BT_CTLR_ISOAL_SINKS=2 - -# Tx Power Dynamic Control -CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf b/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf index 3774532c424..1f976f75f22 100644 --- a/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_uart/overlay-all-bt_ll_sw_split.conf @@ -104,6 +104,3 @@ CONFIG_BT_CTLR_ISOAL_SOURCES=2 # ISO Receptions CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 CONFIG_BT_CTLR_ISOAL_SINKS=2 - -# Tx Power Dynamic Control -CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 46360ef88d7..d287bc794a6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -220,7 +220,7 @@ static int prepare_cb(struct lll_prepare_param *p) radio_reset(); #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(conn_lll->tx_pwr_lvl); + radio_tx_power_set(cis_lll->tx_pwr_lvl); #else /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ radio_tx_power_set(RADIO_TXP_DEFAULT); #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ @@ -986,7 +986,7 @@ static void isr_rx(void *param) next_cis_lll->rx.bn_curr = 1U; #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(next_conn_lll->tx_pwr_lvl); + radio_tx_power_set(next_cis_lll->tx_pwr_lvl); #else radio_tx_power_set(RADIO_TXP_DEFAULT); #endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 13238c081cf..f089a07bb0b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -238,7 +238,7 @@ static int prepare_cb(struct lll_prepare_param *p) radio_reset(); #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) - radio_tx_power_set(conn_lll->tx_pwr_lvl); + radio_tx_power_set(cis_lll->tx_pwr_lvl); #else /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ radio_tx_power_set(RADIO_TXP_DEFAULT); #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ From c91e24b5847f10924f0952f5ec998c5b7faf3577 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:59 +0000 Subject: [PATCH 4180/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix ULL_HIGH ticker operations count" This reverts commit 6721814fdc868cdc5d4f9fb066c58915741ea9bf. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 9811076b9ba..e6a736f939d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -278,21 +278,22 @@ #define TICKER_USER_ULL_LOW_OPS (1 + TICKER_USER_ULL_LOW_VENDOR_OPS + 1) -/* NOTE: Extended Advertising needs one extra ticker operation being enqueued - * for scheduling the auxiliary PDU reception while there can already - * be three other operations being enqueued. - * - * This value also covers the case were initiator with 1M and Coded PHY - * scan window is stopping the two scan tickers, stopping one scan stop - * ticker and starting one new ticker for establishing an ACL connection. +/* NOTE: When ULL_LOW priority is configured to lower than ULL_HIGH, then extra + * ULL_HIGH operations queue elements are required to buffer the + * requested ticker operations. */ -#if defined(CONFIG_BT_CTLR_ADV_EXT) +#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_ADV_EXT) && \ + defined(CONFIG_BT_CTLR_PHY_CODED) #define TICKER_USER_ULL_HIGH_OPS (4 + TICKER_USER_ULL_HIGH_VENDOR_OPS + \ TICKER_USER_ULL_HIGH_FLASH_OPS + 1) -#else /* !CONFIG_BT_CTLR_ADV_EXT */ +#else /* !CONFIG_BT_CENTRAL || !CONFIG_BT_CTLR_ADV_EXT || + * !CONFIG_BT_CTLR_PHY_CODED + */ #define TICKER_USER_ULL_HIGH_OPS (3 + TICKER_USER_ULL_HIGH_VENDOR_OPS + \ TICKER_USER_ULL_HIGH_FLASH_OPS + 1) -#endif /* !CONFIG_BT_CTLR_ADV_EXT */ +#endif /* !CONFIG_BT_CENTRAL || !CONFIG_BT_CTLR_ADV_EXT || + * !CONFIG_BT_CTLR_PHY_CODED + */ #define TICKER_USER_LLL_OPS (3 + TICKER_USER_LLL_VENDOR_OPS + 1) From fd338e810e116606b981f604ab778d69ed2e0ae0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:59 +0000 Subject: [PATCH 4181/4498] Revert "[nrf fromtree] Bluetooth: Controller: ISO: Fix compile issue with unicast" This reverts commit 6df62154bb91974ca7dfd26683ec98dca62fef2e. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index 4eb7687b97d..38589a2e644 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -321,7 +321,7 @@ static int group_free_slot_get(uint8_t user_id, uint32_t ticks_slot_abs, if (false) { -#if defined(CONFIG_BT_BROADCASTER) && CONFIG_BT_CTLR_ADV_AUX_SET > 0 +#if defined(CONFIG_BT_BROADCASTER) } else if (IN_RANGE(ticker_id, TICKER_ID_ADV_AUX_BASE, TICKER_ID_ADV_AUX_LAST)) { const struct ll_adv_aux_set *aux; @@ -391,7 +391,7 @@ static int group_free_slot_get(uint8_t user_id, uint32_t ticks_slot_abs, #endif /* CONFIG_BT_CTLR_ADV_ISO */ #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */ -#endif /* CONFIG_BT_BROADCASTER && CONFIG_BT_CTLR_ADV_AUX_SET > 0 */ +#endif /* CONFIG_BT_BROADCASTER */ #if defined(CONFIG_BT_CONN) } else if (IN_RANGE(ticker_id, TICKER_ID_CONN_BASE, From 400a63cbc840e1f25711b6ab05207d4e77d00ab9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:59 +0000 Subject: [PATCH 4182/4498] Revert "[nrf fromtree] Bluetooth: Controller: nRF53: Fix back-to-back PDU chaining" This reverts commit cd4014a2feb3e7f3ca2aeec959506dd6002ffca0. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c | 2 +- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c index 6fa0204fb56..ca566a04db4 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c @@ -394,7 +394,7 @@ static void isr_tx_chain(void *param) lll->phy_s, lll->phy_flags); } else { radio_isr_set(isr_done, lll_aux); - radio_switch_complete_and_b2b_tx_disable(); + radio_switch_complete_and_disable(); } radio_pkt_tx_set(pdu); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c index 79a8c6b25cd..1e56f70493c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c @@ -367,7 +367,7 @@ static void isr_tx(void *param) switch_radio_complete_and_b2b_tx(lll_sync, lll->phy_s); } else { radio_isr_set(isr_done, lll_sync); - radio_switch_complete_and_b2b_tx_disable(); + radio_switch_complete_and_disable(); } radio_pkt_tx_set(pdu); From dc4cbbe19a753bcc441a5a3e6b6392bce59fd9e1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:29:59 +0000 Subject: [PATCH 4183/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix BIS payload sliding window overrun check" This reverts commit be0d9e0314e8bbf148d1eb054c04f003b4c04576. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/ll_sw/lll_sync_iso.h | 1 + .../ll_sw/nordic/lll/lll_sync_iso.c | 52 ++++--------------- .../bluetooth/controller/ll_sw/ull_sync_iso.c | 3 +- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h b/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h index c47aa433c63..2426f51105e 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_sync_iso.h @@ -74,6 +74,7 @@ struct lll_sync_iso { struct node_rx_pdu *payload[BT_CTLR_SYNC_ISO_STREAM_MAX] [PDU_BIG_PAYLOAD_COUNT_MAX]; uint8_t payload_count_max; + uint8_t payload_head; uint8_t payload_tail; uint32_t window_widening_periodic_us; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c index 12e9fd342b9..5089c6ccde7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c @@ -489,6 +489,7 @@ static void isr_rx(void *param) uint8_t access_addr[4]; uint16_t data_chan_id; uint8_t data_chan_use; + uint8_t payload_index; uint8_t crc_init[3]; uint8_t rssi_ready; uint32_t start_us; @@ -555,8 +556,6 @@ static void isr_rx(void *param) if (crc_ok) { struct lll_sync_iso_stream *sync_stream; uint16_t stream_handle; - uint8_t payload_offset; - uint8_t payload_index; struct pdu_bis *pdu; /* Check if Control Subevent being received */ @@ -594,28 +593,21 @@ static void isr_rx(void *param) /* TODO: check same CSSN is used in every subevent */ } - /* Check payload buffer overflow */ - payload_offset = (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); - if (payload_offset > lll->payload_count_max) { - goto isr_rx_done; - } - - /* Calculate the payload index in the sliding window */ - payload_index = lll->payload_tail + payload_offset; + /* calculate the payload index in the sliding window */ + payload_index = lll->payload_tail + (lll->bn_curr - 1U) + + (lll->ptc_curr * lll->pto); if (payload_index >= lll->payload_count_max) { payload_index -= lll->payload_count_max; } - /* Get reference to stream context */ stream_handle = lll->stream_handle[lll->stream_curr]; sync_stream = ull_sync_iso_lll_stream_get(stream_handle); - /* Store the received PDU if selected stream and not already - * received (say in previous event as pre-transmitted PDU. - */ + /* store the received PDU */ if ((lll->bis_curr == sync_stream->bis_index) && pdu->len && - !lll->payload[bis_idx][payload_index]) { + !lll->payload[bis_idx][payload_index] && + ((payload_index >= lll->payload_tail) || + (payload_index < lll->payload_head))) { uint16_t handle; if (lll->enc) { @@ -652,23 +644,10 @@ static void isr_rx(void *param) /* Find the next (bn_curr)th subevent to receive PDU */ while (lll->bn_curr < lll->bn) { - uint8_t payload_offset; - uint8_t payload_index; - - /* Next burst number to check for reception required */ lll->bn_curr++; - /* Check payload buffer overflow */ - payload_offset = (lll->bn_curr - 1U); - if (payload_offset > lll->payload_count_max) { - /* (bn_curr)th Rx PDU skip subevent */ - skipped++; - - continue; - } - /* Find the index of the (bn_curr)th Rx PDU buffer */ - payload_index = lll->payload_tail + payload_offset; + payload_index = lll->payload_tail + (lll->bn_curr - 1U); if (payload_index >= lll->payload_count_max) { payload_index -= lll->payload_count_max; } @@ -688,11 +667,6 @@ static void isr_rx(void *param) /* Find the next repetition (irc_curr)th subevent to receive PDU */ if (lll->irc_curr < lll->irc) { if (!new_burst) { - uint8_t payload_index; - - /* Increment to next repetition count and be at first - * burst count for it. - */ lll->bn_curr = 1U; lll->irc_curr++; @@ -741,10 +715,6 @@ static void isr_rx(void *param) if (lll->ptc_curr < lll->ptc) { lll->ptc_curr++; - /* TODO: optimize to skip pre-transmission subevent in case - * of insufficient buffers in sliding window. - */ - /* Receive the (ptc_curr)th Rx PDU of bis_curr */ bis = lll->bis_curr; @@ -763,7 +733,6 @@ static void isr_rx(void *param) stream_handle = lll->stream_handle[lll->stream_curr]; sync_stream = ull_sync_iso_lll_stream_get(stream_handle); if (sync_stream->bis_index <= lll->num_bis) { - uint8_t payload_index; uint8_t bis_idx_new; lll->bis_curr = sync_stream->bis_index; @@ -1089,7 +1058,8 @@ static void isr_rx_done(void *param) bn = lll->bn; while (bn--) { if (lll->payload[bis_idx][payload_tail]) { - node_rx = lll->payload[bis_idx][payload_tail]; + node_rx = + lll->payload[bis_idx][payload_tail]; lll->payload[bis_idx][payload_tail] = NULL; iso_rx_put(node_rx->hdr.link, node_rx); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index 513ee3cdbed..ff3327ce393 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -454,9 +454,10 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, /* Initialize payload pointers */ lll->payload_count_max = PDU_BIG_PAYLOAD_COUNT_MAX; + lll->payload_head = 0U; lll->payload_tail = 0U; for (int i = 0; i < CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX; i++) { - for (int j = 0; j < lll->payload_count_max; j++) { + for (int j = 0; j < PDU_BIG_PAYLOAD_COUNT_MAX; j++) { lll->payload[i][j] = NULL; } } From 2731264651bc86a8f7eaee77550dc5fa9df6e080 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:00 +0000 Subject: [PATCH 4184/4498] Revert "[nrf fromtree] Bluetooth: Controller: Add BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX Kconfig" This reverts commit 34f39e4fa35bfc3af1ba376d8bd04b791503e315. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/Kconfig.ll_sw_split | 11 --- .../bluetooth/controller/ll_sw/ull_central.c | 12 +-- .../controller/ll_sw/ull_central_iso.c | 18 ++--- subsys/bluetooth/controller/ll_sw/ull_conn.c | 18 ++--- .../bluetooth/controller/ll_sw/ull_conn_iso.c | 4 +- .../controller/ll_sw/ull_peripheral.c | 23 ++---- .../controller/ll_sw/ull_peripheral_iso.c | 4 - tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 76 ------------------- tests/bluetooth/init/testcase.yaml | 10 --- 9 files changed, 24 insertions(+), 152 deletions(-) delete mode 100644 tests/bluetooth/init/prj_ctlr_5_x_dbg.conf diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 3f6f3c10382..4cd8e200b63 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -632,17 +632,6 @@ config BT_CTLR_CENTRAL_RESERVE_MAX Note, currently this value is only used to space multiple central connections and not for actual ticker time reservations. -config BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX - bool "Reserve maximum event overhead in time reservations" - default y - help - Use radio event scheduling CPU time overhead in calculations of event - time reservations. - - If this option is disabled, then Peripheral ACL and Peripheral ISO - role will not include CPU time overhead. Other role will continue to - use CPU overheads in their event time reservations. - config BT_CTLR_SLOT_RESERVATION_UPDATE bool "Update event length reservation after PHY or DLE update" depends on (BT_CTLR_DATA_LENGTH || BT_CTLR_PHY) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index b189c65fa21..de14395f840 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -97,7 +97,6 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, uint16_t max_tx_time; uint16_t max_rx_time; memq_link_t *link; - uint32_t slot_us; uint8_t hop; int err; @@ -361,13 +360,10 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, #endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - /* Calculate event time reservation */ - slot_us = max_tx_time + max_rx_time; - slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); - slot_us += ready_delay_us; - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay_us + max_tx_time + EVENT_IFS_US + max_rx_time + + (EVENT_CLOCK_JITTER_US << 1)); #if defined(CONFIG_BT_CTLR_PRIVACY) ull_filter_scan_update(filter_policy); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 8c516826e06..19dec37c937 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -864,15 +864,9 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, } else if (CONFIG_BT_CTLR_CENTRAL_SPACING > 0) { uint32_t cis_offset; - cis_offset = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + - (EVENT_TICKER_RES_MARGIN_US << 1U); - - cis_offset += cig->sync_delay - cis->sync_delay; - - if (cis_offset < *cis_offset_min) { - cis_offset = *cis_offset_min; - } - + cis_offset = MAX((HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + + (EVENT_TICKER_RES_MARGIN_US << 1U) + cig->sync_delay - + cis->sync_delay), *cis_offset_min); cis->offset = cis_offset; #endif /* CONFIG_BT_CTLR_CENTRAL_SPACING */ @@ -948,9 +942,8 @@ int ull_central_iso_cis_offset_get(uint16_t cis_handle, #endif /* CONFIG_BT_CTLR_CENTRAL_SPACING != 0 */ *cis_offset_min = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + - (EVENT_TICKER_RES_MARGIN_US << 1U); - - *cis_offset_min += cig->sync_delay - cis->sync_delay; + (EVENT_TICKER_RES_MARGIN_US << 1U) + + cig->sync_delay - cis->sync_delay; return 0; } @@ -991,6 +984,7 @@ static void mfy_cig_offset_get(void *param) offset_min_us += cig->sync_delay - cis->sync_delay; conn = ll_conn_get(cis->lll.acl_handle); + conn_interval_us = (uint32_t)conn->lll.interval * CONN_INT_UNIT_US; while (offset_min_us >= (conn_interval_us + PDU_CIS_OFFSET_MIN_US)) { offset_min_us -= conn_interval_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 9d78af7acc1..a8d3178e020 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1233,7 +1233,7 @@ void ull_conn_done(struct node_rx_event_done *done) #if defined(CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE) #if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY) if (lll->evt_len_upd) { - uint32_t ready_delay, rx_time, tx_time, ticks_slot, slot_us; + uint32_t ready_delay, rx_time, tx_time, ticks_slot; lll->evt_len_upd = 0; #if defined(CONFIG_BT_CTLR_PHY) @@ -1257,18 +1257,10 @@ void ull_conn_done(struct node_rx_event_done *done) tx_time = PDU_DC_MAX_US(lll->dle.eff.max_tx_octets, 0); rx_time = PDU_DC_MAX_US(lll->dle.eff.max_rx_octets, 0); #endif /* CONFIG_BT_CTLR_PHY */ - - /* Calculate event time reservation */ - slot_us = tx_time + rx_time; - slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); - slot_us += ready_delay; - - if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX) || - !conn->lll.role) { - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - } - - ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay + EVENT_IFS_US + rx_time + tx_time + + (EVENT_CLOCK_JITTER_US << 1)); if (ticks_slot > conn->ull.ticks_slot) { ticks_slot_plus = ticks_slot - conn->ull.ticks_slot; } else { diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 2ec6a73b4a4..46c00c305fe 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -972,9 +972,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, /* Below is time reservation for sequential packing */ slot_us = cis->lll.sub_interval * cis->lll.nse; - if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - } + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; /* FIXME: How to use ready_delay_us in the time reservation? * i.e. when CISes use different PHYs? Is that even diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index 5a34f787ec7..8b813fda9fd 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -89,7 +89,6 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, uint16_t max_rx_time; uint16_t win_offset; memq_link_t *link; - uint32_t slot_us; uint8_t chan_sel; void *node; @@ -361,19 +360,10 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, #endif /* !CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_PHY) - ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy_rx, PHY_FLAGS_S8); -#else /* CONFIG_BT_CTLR_PHY */ - ready_delay_us = lll_radio_rx_ready_delay_get(0U, 0U); -#endif /* CONFIG_BT_CTLR_PHY */ - - /* Calculate event time reservation */ - slot_us = max_rx_time + max_tx_time; - slot_us += EVENT_IFS_US + (EVENT_CLOCK_JITTER_US << 1); - slot_us += ready_delay_us; - - if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { - slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - } + ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy_rx, 1); +#else + ready_delay_us = lll_radio_rx_ready_delay_get(0, 0); +#endif /* TODO: active_to_start feature port */ conn->ull.ticks_active_to_start = 0U; @@ -381,7 +371,10 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); conn->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + + ready_delay_us + max_rx_time + EVENT_IFS_US + max_tx_time + + (EVENT_CLOCK_JITTER_US << 1)); ticks_slot_offset = MAX(conn->ull.ticks_active_to_start, conn->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index eeef778734b..d2627502ac2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -110,10 +110,6 @@ uint8_t ll_cis_accept(uint16_t handle) } else { cis_offset_min = HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + (EVENT_TICKER_RES_MARGIN_US << 1U); - - if (!IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) { - cis_offset_min += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - } } /* Accept request */ diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf deleted file mode 100644 index df0d006a13e..00000000000 --- a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf +++ /dev/null @@ -1,76 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_CTLR=y -CONFIG_BT_LL_SW_SPLIT=y -CONFIG_BT_CTLR_DUP_FILTER_LEN=16 -CONFIG_BT_CTLR_CONN_PARAM_REQ=y -CONFIG_BT_CTLR_LE_PING=y -CONFIG_BT_CTLR_PRIVACY=n -CONFIG_BT_CTLR_EXT_SCAN_FP=n -CONFIG_BT_DATA_LEN_UPDATE=n -CONFIG_BT_PHY_UPDATE=y -CONFIG_BT_CTLR_CHAN_SEL_2=y -CONFIG_BT_CTLR_MIN_USED_CHAN=y -CONFIG_BT_CTLR_ADV_EXT=y -CONFIG_BT_CTLR_ADV_PERIODIC=y -CONFIG_BT_CTLR_ADV_ISO=y -CONFIG_BT_CTLR_SYNC_PERIODIC=y -CONFIG_BT_CTLR_SYNC_ISO=y -CONFIG_BT_CTLR_CENTRAL_ISO=y -CONFIG_BT_CTLR_PERIPHERAL_ISO=y -CONFIG_BT_CTLR_DTM_HCI=y -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_PHY_2M=y -CONFIG_BT_CTLR_PHY_2M_NRF=y -CONFIG_BT_CTLR_PHY_CODED=y -CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y -CONFIG_BT_CTLR_LLL_PRIO=0 -CONFIG_BT_CTLR_ULL_HIGH_PRIO=1 -CONFIG_BT_CTLR_XTAL_ADVANCED=n -CONFIG_BT_CTLR_SCHED_ADVANCED=y -CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y -CONFIG_BT_CTLR_TIFS_HW=n -CONFIG_BT_CTLR_FAST_ENC=y -CONFIG_BT_CTLR_TX_RETRY_DISABLE=y -CONFIG_BT_CTLR_CONN_RSSI=y -CONFIG_BT_CTLR_ADV_INDICATION=y -CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y -CONFIG_BT_CTLR_SCAN_REQ_RSSI=y -CONFIG_BT_CTLR_SCAN_INDICATION=y -CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX=n -CONFIG_BT_CTLR_PROFILE_ISR=y -CONFIG_BT_CTLR_DEBUG_PINS=y -CONFIG_BT_CTLR_TEST=y -CONFIG_BT_HCI_VS_EXT=y -CONFIG_BT_HCI_MESH_EXT=n -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_PER_ADV=y -CONFIG_BT_PER_ADV_SYNC=y -CONFIG_BT_ISO_BROADCASTER=y -CONFIG_BT_ISO_SYNC_RECEIVER=y -CONFIG_BT_ISO_CENTRAL=y -CONFIG_BT_ISO_PERIPHERAL=y -CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y -CONFIG_BT_SMP_SC_ONLY=y -CONFIG_BT_TINYCRYPT_ECC=y -CONFIG_BT_USE_DEBUG_KEYS=y -CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y -CONFIG_BT_GATT_CLIENT=y -CONFIG_BT_DEBUG_MONITOR_UART=y -CONFIG_BT_HCI_CORE_LOG_LEVEL_DBG=y -CONFIG_BT_CONN_LOG_LEVEL_DBG=y -CONFIG_BT_KEYS_LOG_LEVEL_DBG=y -CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y -CONFIG_BT_SMP_LOG_LEVEL_DBG=y -CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=y -CONFIG_BT_SMP_SELFTEST=y -CONFIG_BT_ATT_LOG_LEVEL_DBG=y -CONFIG_BT_GATT_LOG_LEVEL_DBG=y -CONFIG_BT_BREDR=n -CONFIG_DEBUG=y -CONFIG_FLASH=y -CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index 17d57ec9d47..c38f5bed69e 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,16 +122,6 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 - bluetooth.init.test_ctlr_5_x_dbg: - extra_args: - - CONF_FILE=prj_ctlr_5_x_dbg.conf - - DTC_OVERLAY_FILE=pa_lna.overlay - platform_allow: - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 - integration_platforms: - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 bluetooth.init.test_ctlr_sw_switch_single_timer: extra_args: - CONF_FILE=prj_ctlr.conf From a997d1c8b2f77621f67cc9191aba7a617bc424b4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:00 +0000 Subject: [PATCH 4185/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix compile error when BT_CTLR_CENTRAL_SPACING=n" This reverts commit fd76eac8e690a1181d84cba6a89cdfc3808ef3e7. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 19dec37c937..aac5d2057d2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -857,19 +857,13 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, cis->offset = cis_offset; #else /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ - - if (false) { - -#if defined(CONFIG_BT_CTLR_CENTRAL_SPACING) - } else if (CONFIG_BT_CTLR_CENTRAL_SPACING > 0) { + if (IS_ENABLED(CONFIG_BT_CTLR_CENTRAL_SPACING) && (CONFIG_BT_CTLR_CENTRAL_SPACING > 0)) { uint32_t cis_offset; cis_offset = MAX((HAL_TICKER_TICKS_TO_US(conn->ull.ticks_slot) + (EVENT_TICKER_RES_MARGIN_US << 1U) + cig->sync_delay - cis->sync_delay), *cis_offset_min); cis->offset = cis_offset; -#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING */ - } else { cis->offset = *cis_offset_min; } From 430e1defc4ce54ba25ff520580fb5721b3aa9490 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:00 +0000 Subject: [PATCH 4186/4498] Revert "[nrf fromtree] Bluetooth: Controller: nrf53: Fix back-to-back Tx Rx implementation" This reverts commit a91031e38b7c7e412c23636630ae62c0744c6cc9. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 30 +----- .../ll_sw/nordic/hal/nrf5/radio/radio.h | 2 - .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 100 ++++++------------ .../nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 66 +++++------- .../controller/ll_sw/nordic/lll/lll_adv_iso.c | 2 +- 5 files changed, 67 insertions(+), 133 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index a657ab95dfe..0b41a9bbfb6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -718,7 +718,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */ uint32_t delay; - hal_radio_sw_switch_setup(sw_tifs_toggle); + hal_radio_sw_switch_setup(cc, ppi, sw_tifs_toggle); /* NOTE: As constants are passed to dir_curr and dir_next, the * compiler should optimize out the redundant code path @@ -736,7 +736,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla hal_radio_tx_chain_delay_ns_get(phy_curr, flags_curr)); - hal_radio_b2b_txen_on_sw_switch(cc, ppi); + hal_radio_b2b_txen_on_sw_switch(ppi); } else { /* If RX PHY is LE Coded, calculate for S8 coding. * Assumption being, S8 has higher delay. @@ -746,7 +746,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_next) + hal_radio_rx_chain_delay_ns_get(phy_curr, 1)); - hal_radio_txen_on_sw_switch(cc, ppi); + hal_radio_txen_on_sw_switch(ppi); } #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) @@ -839,7 +839,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_curr)) + (EVENT_CLOCK_JITTER_US << 1); - hal_radio_rxen_on_sw_switch(cc, ppi); + hal_radio_rxen_on_sw_switch(ppi); } else { delay = HAL_RADIO_NS2US_CEIL( hal_radio_rx_ready_delay_ns_get(phy_next, @@ -848,7 +848,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla flags_curr)) + (EVENT_CLOCK_JITTER_US << 1); - hal_radio_b2b_rxen_on_sw_switch(cc, ppi); + hal_radio_b2b_rxen_on_sw_switch(ppi); } @@ -982,26 +982,6 @@ void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr, #endif /* !CONFIG_BT_CTLR_TIFS_HW */ } -void radio_switch_complete_and_b2b_tx_disable(void) -{ -#if defined(CONFIG_BT_CTLR_TIFS_HW) - NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); -#else /* CONFIG_BT_CTLR_TIFS_HW */ - NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_PDU_END_DISABLE); - hal_radio_sw_switch_b2b_tx_disable(sw_tifs_toggle); -#endif /* !CONFIG_BT_CTLR_TIFS_HW */ -} - -void radio_switch_complete_and_b2b_rx_disable(void) -{ -#if defined(CONFIG_BT_CTLR_TIFS_HW) - NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); -#else /* CONFIG_BT_CTLR_TIFS_HW */ - NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_PDU_END_DISABLE); - hal_radio_sw_switch_b2b_rx_disable(sw_tifs_toggle); -#endif /* !CONFIG_BT_CTLR_TIFS_HW */ -} - void radio_switch_complete_and_disable(void) { #if defined(CONFIG_BT_CTLR_TIFS_HW) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index 4bf833b233a..600d7e95481 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -106,8 +106,6 @@ void radio_switch_complete_and_b2b_tx(uint8_t phy_curr, uint8_t flags_curr, uint8_t phy_next, uint8_t flags_next); void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr, uint8_t phy_next, uint8_t flags_next); -void radio_switch_complete_and_b2b_tx_disable(void); -void radio_switch_complete_and_b2b_rx_disable(void); void radio_switch_complete_and_disable(void); uint8_t radio_phy_flags_rx_get(void); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 1fdf7d90d30..787755866ab 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -455,7 +455,10 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */ -static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) +static inline void hal_radio_sw_switch_setup( + uint8_t compare_reg, + uint8_t radio_enable_ppi, + uint8_t ppi_group_index) { /* Set up software switch mechanism for next Radio switch. */ @@ -463,7 +466,7 @@ static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) * over PPI[] */ HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; nrf_dppi_subscribe_set(NRF_DPPIC, HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(ppi_group_index)), HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI); @@ -473,70 +476,55 @@ static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) nrf_dppi_subscribe_clear(NRF_DPPIC, HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(other_grp))); -} -static inline void hal_radio_txen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) -{ /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do * not wire the task; it is done by the caller of * the function depending on the desired direction * (TX/RX). */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg) = HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); - - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); } -static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t compare_reg_index, - uint8_t radio_enable_ppi) +static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) { - /* Wire SW Switch timer event to the - * PPI[] for enabling Radio. Do - * not wire the task; it is done by the caller of - * the function depending on the desired direction - * (TX/RX). - */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); - - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; - - radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); } -static inline void hal_radio_rxen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) +static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t ppi) { - /* Wire SW Switch timer event to the - * PPI[] for enabling Radio. Do - * not wire the task; it is done by the caller of - * the function depending on the desired direction - * (TX/RX). + /* NOTE: Calling radio_tmr_start/radio_tmr_start_us/radio_tmr_start_now + * after the radio_switch_complete_and_b2b_tx() call would have + * changed the PPI channel to HAL_RADIO_ENABLE_ON_TICK_PPI as we + * cannot double buffer the subscribe buffer. Hence, lets have + * both DPPI channel enabled (other one was enabled by the DPPI + * group when the Radio End occurred) so that when both timer + * trigger one of the DPPI is correct in the radio tx + * subscription. */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); + nrf_dppi_channels_enable(NRF_DPPIC, BIT(ppi)); +} - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); +static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) +{ + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); } -static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t compare_reg_index, - uint8_t radio_enable_ppi) +static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t ppi) { - /* Wire SW Switch timer event to the - * PPI[] for enabling Radio. Do - * not wire the task; it is done by the caller of - * the function depending on the desired direction - * (TX/RX). + /* NOTE: Calling radio_tmr_start/radio_tmr_start_us/radio_tmr_start_now + * after the radio_switch_complete_and_b2b_rx() call would have + * changed the PPI channel to HAL_RADIO_ENABLE_ON_TICK_PPI as we + * cannot double buffer the subscribe buffer. Hence, lets have + * both DPPI channel enabled (other one was enabled by the DPPI + * group when the Radio End occurred) so that when both timer + * trigger one of the DPPI is correct in the radio rx + * subscription. */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); - - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; - - radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); + nrf_dppi_channels_enable(NRF_DPPIC, BIT(ppi)); } static inline void hal_radio_sw_switch_disable(void) @@ -552,26 +540,6 @@ static inline void hal_radio_sw_switch_disable(void) HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); } -static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index) -{ - hal_radio_sw_switch_disable(); - - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; - uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); - - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); -} - -static inline void hal_radio_sw_switch_b2b_rx_disable(uint8_t compare_reg_index) -{ - hal_radio_sw_switch_disable(); - - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; - uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); - - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); -} - static inline void hal_radio_sw_switch_cleanup(void) { hal_radio_sw_switch_disable(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 44cec4621a3..d964129bfa1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -420,7 +420,10 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX \ ((uint32_t)&(NRF_RADIO->TASKS_RXEN)) -static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) +static inline void hal_radio_sw_switch_setup( + uint8_t compare_reg, + uint8_t radio_enable_ppi, + uint8_t ppi_group_index) { /* Set up software switch mechanism for next Radio switch. */ @@ -432,58 +435,53 @@ static inline void hal_radio_sw_switch_setup(uint8_t ppi_group_index) HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI, HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT, HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK(ppi_group_index)); -} -static inline void hal_radio_txen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) -{ /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do * not wire the task; it is done by the caller of * the function depending on the desired direction * (TX/RX). */ - nrf_ppi_event_endpoint_setup(NRF_PPI, radio_enable_ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg_index)); + nrf_ppi_event_endpoint_setup( + NRF_PPI, + radio_enable_ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg)); +} - nrf_ppi_task_endpoint_setup(NRF_PPI, radio_enable_ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX); +static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) +{ + nrf_ppi_task_endpoint_setup( + NRF_PPI, + ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX); } -static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t compare_reg_index, - uint8_t radio_enable_ppi) +static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t ppi) { /* NOTE: As independent PPI are used to trigger the Radio Tx task, * double buffers implementation works for sw_switch using PPIs, * simply reuse the hal_radio_txen_on_sw_switch() functon to set * the next PPIs task to be Radio Tx enable. */ - hal_radio_txen_on_sw_switch(compare_reg_index, radio_enable_ppi); + hal_radio_txen_on_sw_switch(ppi); } -static inline void hal_radio_rxen_on_sw_switch(uint8_t compare_reg_index, uint8_t radio_enable_ppi) +static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) { - /* Wire SW Switch timer event to the - * PPI[] for enabling Radio. Do - * not wire the task; it is done by the caller of - * the function depending on the desired direction - * (TX/RX). - */ - nrf_ppi_event_endpoint_setup(NRF_PPI, radio_enable_ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(compare_reg_index)); - - nrf_ppi_task_endpoint_setup(NRF_PPI, radio_enable_ppi, - HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX); + nrf_ppi_task_endpoint_setup( + NRF_PPI, + ppi, + HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX); } -static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t compare_reg_index, - uint8_t radio_enable_ppi) +static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t ppi) { - /* NOTE: As independent PPI are used to trigger the Radio Tx task, + /* NOTE: As independent PPI are used to trigger the Radio Rx task, * double buffers implementation works for sw_switch using PPIs, - * simply reuse the hal_radio_txen_on_sw_switch() functon to set - * the next PPIs task to be Radio Tx enable. + * simply reuse the hal_radio_rxen_on_sw_switch() functon to set + * the next PPIs task to be Radio Rx enable. */ - hal_radio_rxen_on_sw_switch(compare_reg_index, radio_enable_ppi); + hal_radio_rxen_on_sw_switch(ppi); } static inline void hal_radio_sw_switch_disable(void) @@ -498,16 +496,6 @@ static inline void hal_radio_sw_switch_disable(void) BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI)); } -static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index) -{ - hal_radio_sw_switch_disable(); -} - -static inline void hal_radio_sw_switch_b2b_rx_disable(uint8_t compare_reg_index) -{ - hal_radio_sw_switch_disable(); -} - static inline void hal_radio_sw_switch_cleanup(void) { hal_radio_sw_switch_disable(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c index 20e3fe528e1..87849d0e1fd 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c @@ -717,7 +717,7 @@ static void isr_tx_common(void *param, pkt_flags); } - radio_switch_complete_and_b2b_tx_disable(); + radio_switch_complete_and_disable(); radio_isr_set(isr_done_term, lll); } else { From cbcd42ebea2bb8fac3df743ab0a08d588c253824 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:01 +0000 Subject: [PATCH 4187/4498] Revert "[nrf fromtree] Bluetooth: Controller: nRF53: Cleanup dppi and dppi resources file" This reverts commit 85b2b7136d56092617648e8bee0e0d860cfbf524. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 4 ++-- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h | 2 +- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 787755866ab..3792111292a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -341,7 +341,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). - * 2 adjacent PPIs (14 & 15) and 2 adjacent PPI groups are used for this wiring; + * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; * must be 0 or 1. must be a valid TIMER CC register offset. */ #define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) \ @@ -429,10 +429,10 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) (SW_SWITCH_TIMER_EVTS_COMP_PHYEND_DELAY_COMPENSATION_BASE + (index)) #define HAL_SW_SWITCH_RADIO_ENABLE_PHYEND_DELAY_COMPENSATION_PPI(index) \ HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) - /* Cancel the SW switch timer running considering PHYEND delay compensation timing: * wire the RADIO EVENTS_CTEPRESENT event to SW_SWITCH_TIMER TASKS_CAPTURE task. */ +#define HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI 16 #define HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI_REGISTER_EVT \ NRF_RADIO->PUBLISH_CTEPRESENT diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h index a8bbe8e63b4..e1b47d03fd7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h @@ -98,7 +98,7 @@ /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). - * 2 adjacent PPIs (14 & 15) and 2 adjacent PPI groups are used for this wiring; + * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; * must be 0 or 1. must be a valid TIMER CC register offset. */ #define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE 14 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h index ab196e17d58..5c5093f4b52 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi_resources.h @@ -143,6 +143,9 @@ #define HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE 12 #endif +#if defined(CONFIG_BT_CTLR_PHY_CODED) && \ + defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) + /* Wire the SW SWITCH TIMER EVENTS_COMPARE[] event * to RADIO TASKS_TXEN/RXEN task. */ @@ -153,6 +156,8 @@ */ #define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI 19 +#endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ + #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) /* Wire the SW SWITCH PHYEND delay compensation TIMER EVENTS_COMPARE[] event to software * switch TIMER0->CLEAR taks task. From fcacad706adbd62ead1ef62f4f0d3e9822609faa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:01 +0000 Subject: [PATCH 4188/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix CIS assymmetric PHY usage" This reverts commit bce70f4a637c8efd602bd72c598182909f5697f0. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/lll/lll_central_iso.c | 12 +++--------- .../controller/ll_sw/nordic/lll/lll_peripheral_iso.c | 11 +---------- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 4 ---- .../bluetooth/controller/ll_sw/ull_peripheral_iso.c | 2 -- 4 files changed, 4 insertions(+), 25 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index d287bc794a6..6135cc9d863 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -488,17 +488,14 @@ static void isr_tx(void *param) /* Get reference to CIS LLL context */ cis_lll = param; - /* Acquire rx node for reception */ - node_rx = ull_iso_pdu_rx_alloc_peek(1U); - LL_ASSERT(node_rx); - #if defined(CONFIG_BT_CTLR_LE_ENC) /* Get reference to ACL context */ const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ - /* PHY */ - radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); + /* Acquire rx node for reception */ + node_rx = ull_iso_pdu_rx_alloc_peek(1U); + LL_ASSERT(node_rx); /* Encryption */ if (false) { @@ -1090,9 +1087,6 @@ static void isr_prepare_subevent(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ - /* PHY */ - radio_phy_set(cis_lll->tx.phy, cis_lll->tx.phy_flags); - /* Encryption */ if (false) { diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index f089a07bb0b..4796696ce73 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -244,7 +244,7 @@ static int prepare_cb(struct lll_prepare_param *p) #endif /* !CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */ phy = cis_lll->rx.phy; - radio_phy_set(phy, PHY_FLAGS_S8); + radio_phy_set(phy, cis_lll->rx.phy_flags); radio_aa_set(cis_lll->access_addr); radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(conn_lll->crc_init)); lll_chan_set(data_chan_use); @@ -738,9 +738,6 @@ static void isr_rx(void *param) pdu_tx->rfu0 = 0U; pdu_tx->rfu1 = 0U; - /* PHY */ - radio_phy_set(cis_lll->tx.phy, cis_lll->tx.phy_flags); - /* Encryption */ if (false) { @@ -883,9 +880,6 @@ static void isr_tx(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ - /* PHY */ - radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); - /* Encryption */ if (false) { @@ -1100,9 +1094,6 @@ static void isr_prepare_subevent_common(void *param) const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle); #endif /* CONFIG_BT_CTLR_LE_ENC */ - /* PHY */ - radio_phy_set(cis_lll->rx.phy, PHY_FLAGS_S8); - /* Encryption */ if (false) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index aac5d2057d2..2a19e03bde5 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -136,9 +136,7 @@ uint8_t ll_cis_parameters_set(uint8_t cis_id, ll_iso_setup.stream[cis_idx].c_max_sdu = c_sdu; ll_iso_setup.stream[cis_idx].p_max_sdu = p_sdu; ll_iso_setup.stream[cis_idx].lll.tx.phy = c_phy; - ll_iso_setup.stream[cis_idx].lll.tx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.rx.phy = p_phy; - ll_iso_setup.stream[cis_idx].lll.rx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].central.c_rtn = c_rtn; ll_iso_setup.stream[cis_idx].central.p_rtn = p_rtn; ll_iso_setup.cis_idx++; @@ -637,9 +635,7 @@ uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t nse, ll_iso_setup.stream[cis_idx].lll.tx.max_pdu = c_bn ? c_pdu : 0U; ll_iso_setup.stream[cis_idx].lll.rx.max_pdu = p_bn ? p_pdu : 0U; ll_iso_setup.stream[cis_idx].lll.tx.phy = c_phy; - ll_iso_setup.stream[cis_idx].lll.tx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.rx.phy = p_phy; - ll_iso_setup.stream[cis_idx].lll.rx.phy_flags = PHY_FLAGS_S8; ll_iso_setup.stream[cis_idx].lll.tx.bn = c_bn; ll_iso_setup.stream[cis_idx].lll.rx.bn = p_bn; ll_iso_setup.cis_idx++; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index d2627502ac2..f68ca66656f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -257,13 +257,11 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->lll.nse = req->nse; cis->lll.rx.phy = req->c_phy; - cis->lll.rx.phy_flags = PHY_FLAGS_S8; cis->lll.rx.bn = req->c_bn; cis->lll.rx.ft = req->c_ft; cis->lll.rx.max_pdu = sys_le16_to_cpu(req->c_max_pdu); cis->lll.tx.phy = req->p_phy; - cis->lll.tx.phy_flags = PHY_FLAGS_S8; cis->lll.tx.bn = req->p_bn; cis->lll.tx.ft = req->p_ft; cis->lll.tx.max_pdu = sys_le16_to_cpu(req->p_max_pdu); From 71df5dc94c08771984f6f48b3b6239e08b56cf46 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:01 +0000 Subject: [PATCH 4189/4498] Revert "[nrf fromtree] Bluetooth: Controller: nRF53: Fix missing NRF_CCM subscribe clear" This reverts commit 2528d7a49d30ff0334b4bf9af48618ddbf359373. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 6 ------ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 8 -------- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 10 ---------- 3 files changed, 24 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 0b41a9bbfb6..3fc76a27bdf 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -1084,8 +1084,6 @@ void radio_tmr_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); - hal_trigger_crypt_ppi_disable(); - hal_radio_nrf_ppi_channels_disable( BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) | BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) | @@ -1118,8 +1116,6 @@ void radio_tmr_tx_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); - hal_trigger_crypt_ppi_disable(); - hal_radio_nrf_ppi_channels_disable( #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \ !defined(DPPI_PRESENT) @@ -1156,8 +1152,6 @@ void radio_tmr_rx_status_reset(void) { nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENCLR_COMPARE2_Msk); - hal_trigger_crypt_ppi_disable(); - hal_radio_nrf_ppi_channels_disable( #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \ !defined(DPPI_PRESENT) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 3792111292a..c28cc35a617 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -127,14 +127,6 @@ static inline void hal_trigger_crypt_ppi_config(void) nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_CRYPT, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); } -/******************************************************************************* - * Disable trigger encryption task - */ -static inline void hal_trigger_crypt_ppi_disable(void) -{ - nrf_ccm_subscribe_clear(NRF_CCM, NRF_CCM_TASK_CRYPT); -} - #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) /******************************************************************************* * Trigger encryption task on Bit counter match: diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index d964129bfa1..866769c95eb 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -205,16 +205,6 @@ static inline void hal_trigger_crypt_ppi_config(void) /* No need to configure anything for the pre-programmed channel. */ } -/******************************************************************************* - * Disable trigger encryption task - */ -static inline void hal_trigger_crypt_ppi_disable(void) -{ - /* No need to disable anything as ppi channel will be disabled in a - * separate disable ppi call by the caller of this function. - */ -} - #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) /******************************************************************************* * Trigger encryption task on Bit counter match: From 4e245fd50dc1b7d0057d2a76e941d42b849d68b4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:02 +0000 Subject: [PATCH 4190/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use unique goto label in scan aux code" This reverts commit ac999bd51ac7d24cb11df0171b137ef6444279a4. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index c8188d87cb6..50bcb0e6662 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -1510,7 +1510,7 @@ static void isr_rx_connect_rsp(void *param) rx = ftr->extra; rx->hdr.type = NODE_RX_TYPE_RELEASE; - goto isr_rx_connect_rsp_do_close; + goto isr_rx_do_close; } /* Update the max Tx and Rx time; and connection PHY based on the @@ -1548,7 +1548,7 @@ static void isr_rx_connect_rsp(void *param) } #endif /* CONFIG_BT_CTLR_PRIVACY */ -isr_rx_connect_rsp_do_close: +isr_rx_do_close: if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { lll_prof_cputime_capture(); } From 205314e10607deb9d41665a69e902354fd6d87c5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:02 +0000 Subject: [PATCH 4191/4498] Revert "[nrf fromtree] Bluetooth controller nrf: nrf52 bsim radio hal fix" This reverts commit 35d5889e89181556ca0b4c16f2cb87ad2bbb51ee. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h index 1b8c1583547..3d53462326a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h @@ -14,10 +14,7 @@ /* NRF Radio HW timing constants * - provided in US and NS (for higher granularity) - * - based on the timings configured in the HW models, which are based - * on the product specification - * - Note that this timings are approx. the same as in the real HW, - * but tend to be rounded to the nearest microsecond + * - based on empirical measurements and sniffer logs */ /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) @@ -364,7 +361,7 @@ static inline uint32_t hal_radio_tx_chain_delay_ns_get(uint8_t phy, uint8_t flag ARG_UNUSED(phy); ARG_UNUSED(flags); - return HAL_RADIO_NRF52833_TX_CHAIN_DELAY_NS; + return HAL_RADIO_NRF52833_TX_CHAIN_DELAY_US; } static inline uint32_t hal_radio_rx_chain_delay_ns_get(uint8_t phy, uint8_t flags) From e1fbe67ba6f3e2fd6c6840f7b9561e4178934245 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:02 +0000 Subject: [PATCH 4192/4498] Revert "[nrf fromtree] Bluetooth controller nrf: nrf52 bsim radio hal header minor updates" This reverts commit 5b8de9becc22ff98ef6eeaa36284417a670942d3. Signed-off-by: Dominik Ermel --- .../nordic/hal/nrf5/radio/radio_sim_nrf52.h | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h index 3d53462326a..a767fe1ab30 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h @@ -185,10 +185,14 @@ static inline void hal_radio_reset(void) { + /* TODO: Add any required setup for each radio event + */ } static inline void hal_radio_stop(void) { + /* TODO: Add any required cleanup of actions taken in hal_radio_reset() + */ } static inline void hal_radio_ram_prio_setup(void) @@ -222,39 +226,25 @@ static inline uint32_t hal_radio_tx_power_min_get(void) static inline uint32_t hal_radio_tx_power_max_get(void) { - return RADIO_TXPOWER_TXPOWER_Pos8dBm; +#if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm) + return RADIO_TXPOWER_TXPOWER_Pos4dBm; +#else + return RADIO_TXPOWER_TXPOWER_0dBm; +#endif } static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) { - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos8dBm) { - return RADIO_TXPOWER_TXPOWER_Pos8dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos7dBm) { - return RADIO_TXPOWER_TXPOWER_Pos7dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos6dBm) { - return RADIO_TXPOWER_TXPOWER_Pos6dBm; - } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos5dBm) { - return RADIO_TXPOWER_TXPOWER_Pos5dBm; - } - +#if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm) if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { return RADIO_TXPOWER_TXPOWER_Pos4dBm; } - +#endif +#if defined(RADIO_TXPOWER_TXPOWER_Pos3dBm) if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { return RADIO_TXPOWER_TXPOWER_Pos3dBm; } - - if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos2dBm) { - return RADIO_TXPOWER_TXPOWER_Pos2dBm; - } - +#endif if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { return RADIO_TXPOWER_TXPOWER_0dBm; } @@ -279,7 +269,10 @@ static inline uint32_t hal_radio_tx_power_floor(int8_t tx_power_lvl) return RADIO_TXPOWER_TXPOWER_Neg20dBm; } - /* Note: The -30 dBm power level is deprecated so ignore it! */ + if (tx_power_lvl >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg30dBm) { + return RADIO_TXPOWER_TXPOWER_Neg30dBm; + } + return RADIO_TXPOWER_TXPOWER_Neg40dBm; } From 5ce4d0c209dcf6b2ff6aa10e3f1a1f4bfcbb7b1b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:02 +0000 Subject: [PATCH 4193/4498] Revert "[nrf fromtree] Bluetooth: Controller: nrf: HAL for DPPI configuration cleanup" This reverts commit 65eaabbf2ff41853284222cf9f6f2776ef3a794c. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index c28cc35a617..69069288141 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -388,6 +388,21 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ & TIMER_PUBLISH_COMPARE_EN_Msk)) +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_TX \ + NRF_RADIO->SUBSCRIBE_TXEN +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_RX \ + NRF_RADIO->SUBSCRIBE_RXEN +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX_SET(chan) \ + (((chan << RADIO_SUBSCRIBE_TXEN_CHIDX_Pos) \ + & RADIO_SUBSCRIBE_TXEN_CHIDX_Msk) | \ + ((RADIO_SUBSCRIBE_TXEN_EN_Enabled << \ + RADIO_SUBSCRIBE_TXEN_EN_Pos) \ + & RADIO_SUBSCRIBE_TXEN_EN_Msk)) +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX_SET(chan) \ + (((chan << RADIO_SUBSCRIBE_RXEN_CHIDX_Pos) \ + & RADIO_SUBSCRIBE_RXEN_CHIDX_Msk) | \ + ((RADIO_SUBSCRIBE_RXEN_EN_Enabled << RADIO_SUBSCRIBE_RXEN_EN_Pos) \ + & RADIO_SUBSCRIBE_RXEN_EN_Msk)) /* Cancel the SW switch timer running considering S8 timing: * wire the RADIO EVENTS_RATEBOOST event to SW_SWITCH_TIMER TASKS_CAPTURE task. From 02a1ce0adc1e984b45ff5e2c03ef9fc7c7db500c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:03 +0000 Subject: [PATCH 4194/4498] Revert "[nrf fromtree] Bluetooth: Controller: nrf: Use HAL for DPPI configuration" This reverts commit 694b89fdbd9a78aedfd9e8521028622b9c54fd52. Signed-off-by: Dominik Ermel --- .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 102 ++++++++---------- 1 file changed, 44 insertions(+), 58 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 69069288141..9ed66dc3442 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -317,20 +317,6 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) #define SW_SWITCH_TIMER_S2_EVTS_COMP(index) \ (SW_SWITCH_TIMER_EVTS_COMP_S2_BASE + (index)) -/* - * Convert a dppi channel group number into the *enable* task enumerate value - * the nrfx hal accepts - */ -#define HAL_SW_DPPI_TASK_EN_FROM_IDX(index) \ - (NRF_DPPI_TASK_CHG0_EN + ((index) * (NRF_DPPI_TASK_CHG1_EN - NRF_DPPI_TASK_CHG0_EN))) - -/* - * Convert a dppi channel group number into the *disable* task enumerate value - * the nrfx hal accepts - */ -#define HAL_SW_DPPI_TASK_DIS_FROM_IDX(index) \ - (NRF_DPPI_TASK_CHG0_DIS + ((index) * (NRF_DPPI_TASK_CHG1_EN - NRF_DPPI_TASK_CHG0_EN))) - /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; @@ -346,10 +332,14 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ & TIMER_PUBLISH_COMPARE_EN_Msk)) -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index, channel) \ - nrf_dppi_subscribe_set(NRF_DPPIC, \ - HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(index)), \ - channel); +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index) \ + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].DIS +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(chan) \ + (((chan << DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Pos) \ + & DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Msk) | \ + ((DPPIC_SUBSCRIBE_CHG_DIS_EN_Enabled << \ + DPPIC_SUBSCRIBE_CHG_DIS_EN_Pos) \ + & DPPIC_SUBSCRIBE_CHG_DIS_EN_Msk)) /* Enable the SW Switch PPI Group on RADIO END Event. * @@ -363,6 +353,15 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) & RADIO_PUBLISH_END_CHIDX_Msk) | \ ((RADIO_PUBLISH_END_EN_Enabled << RADIO_PUBLISH_END_EN_Pos) \ & RADIO_PUBLISH_END_EN_Msk)) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) \ + (NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].EN) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK \ + (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ + DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Pos) \ + & DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Msk) | \ + ((DPPIC_SUBSCRIBE_CHG_EN_EN_Enabled << \ + DPPIC_SUBSCRIBE_CHG_EN_EN_Pos) \ + & DPPIC_SUBSCRIBE_CHG_EN_EN_Msk)) /* Enable Radio on SW Switch timer event. * Wire a SW SWITCH TIMER EVENTS_COMPARE[] event @@ -474,15 +473,12 @@ static inline void hal_radio_sw_switch_setup( */ HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; - nrf_dppi_subscribe_set(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(ppi_group_index)), - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI); + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(ppi_group_index) = + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK; /* We need to un-subscribe the other group from the PPI channel. */ - uint8_t other_grp = (ppi_group_index + 1) & 0x01; - - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(other_grp))); + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK( + (ppi_group_index + 1) & 0x01) = 0; /* Wire SW Switch timer event to the * PPI[] for enabling Radio. Do @@ -541,10 +537,8 @@ static inline void hal_radio_sw_switch_disable(void) * So we simply cancel the task subscription. */ nrf_timer_subscribe_clear(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR); - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; } static inline void hal_radio_sw_switch_cleanup(void) @@ -573,8 +567,8 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_s2) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(ppi_dis); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index, - ppi_dis); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(ppi_dis); /* Capture CC to cancel the timer that has assumed * S8 reception, if packet will be received in S2. @@ -615,7 +609,9 @@ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( ppi_dis); HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK( - group_index, ppi_dis); + group_index) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + ppi_dis); } #endif /* defined(CONFIG_BT_CTLR_PHY_CODED) */ @@ -628,33 +624,21 @@ static inline void hal_radio_sw_switch_ppi_group_setup(void) * registers are written, therefore, we clear the task registers * here. */ - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); - nrf_dppi_subscribe_clear(NRF_DPPIC, - HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); - - nrf_dppi_task_trigger(NRF_DPPIC, - HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0))); - nrf_dppi_task_trigger(NRF_DPPIC, - HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1))); + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].EN = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].EN = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 0; + + NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 1; + NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 1; /* Include the appropriate PPI channels in the two PPI Groups. */ - nrf_dppi_group_clear(NRF_DPPIC, - SW_SWITCH_TIMER_TASK_GROUP(0)); - nrf_dppi_channels_include_in_group(NRF_DPPIC, + NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(0)] = BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)), - SW_SWITCH_TIMER_TASK_GROUP(0)); - nrf_dppi_group_clear(NRF_DPPIC, - SW_SWITCH_TIMER_TASK_GROUP(1)); - nrf_dppi_channels_include_in_group(NRF_DPPIC, + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)); + NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(1)] = BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)), - SW_SWITCH_TIMER_TASK_GROUP(1)); + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)); /* Sanity build-time check that RADIO Enable and Group Disable * tasks are going to be subscribed on the same PPIs. @@ -679,7 +663,8 @@ static inline void hal_radio_group_task_disable_ppi_setup(void) SW_SWITCH_TIMER_EVTS_COMP(0)) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0, + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); /* Wire SW SWITCH TIMER event to @@ -689,8 +674,9 @@ static inline void hal_radio_group_task_disable_ppi_setup(void) SW_SWITCH_TIMER_EVTS_COMP(1)) = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1, - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); } #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) From 41e3ab145f46a6aea945ef2b2b8890f378fc6d4d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:03 +0000 Subject: [PATCH 4195/4498] Revert "[nrf fromtree] Bluetooth: Controller: nRF53: Fix sw switch single timer id regression" This reverts commit c3bc6faf52e3b301e91b62efc1a1763d28f29a46. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h | 14 -------------- tests/bluetooth/init/testcase.yaml | 13 ------------- 2 files changed, 27 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h index 68267490129..e0f43014508 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h @@ -5,20 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* Override EVENT_TIMER_ID from 4 to 0, as nRF5340 does not have 4 timer - * instances. - */ -#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) -#undef EVENT_TIMER_ID -#define EVENT_TIMER_ID 0 - -#undef EVENT_TIMER -#define EVENT_TIMER _CONCAT(NRF_TIMER, EVENT_TIMER_ID) - -#undef SW_SWITCH_TIMER -#define SW_SWITCH_TIMER EVENT_TIMER -#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ - /* NRF Radio HW timing constants * - provided in US and NS (for higher granularity) * - based on empirical measurements and sniffer logs diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index c38f5bed69e..fa30920dc1e 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,19 +122,6 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 - bluetooth.init.test_ctlr_sw_switch_single_timer: - extra_args: - - CONF_FILE=prj_ctlr.conf - - CONFIG_BT_CTLR_ADVANCED_FEATURES=y - - CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER=y - platform_allow: - - nrf5340dk_nrf5340_cpunet - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 - integration_platforms: - - nrf5340dk_nrf5340_cpunet - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 bluetooth.init.test_ctlr_ticker: extra_args: - CONF_FILE=prj_ctlr_ticker.conf From 40f8262ed7d69770d9ac5e45cbf7e0c88b5d391a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:03 +0000 Subject: [PATCH 4196/4498] Revert "[nrf fromtree] Bluetooth controller nrf: Rename bsim radio hal header" This reverts commit 5d1edf1e72deadd5680ed527feed12faeb2ee329. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 4 ++-- .../hal/nrf5/radio/{radio_sim_nrf52.h => radio_sim_nrfxx.h} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/{radio_sim_nrf52.h => radio_sim_nrfxx.h} (100%) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 9e29ab5f70b..a03e55f519d 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -15,8 +15,8 @@ #define HAL_RADIO_NS2US_ROUND(ns) ((ns + 500)/1000) /* SoC specific defines */ -#if defined(CONFIG_BOARD_NRF52_BSIM) -#include "radio_sim_nrf52.h" +#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) +#include "radio_sim_nrfxx.h" #elif defined(CONFIG_SOC_SERIES_NRF51X) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrfxx.h similarity index 100% rename from subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrfxx.h From 4e8f1c2ceaa1ed33811317b28efdfac40c666c87 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:03 +0000 Subject: [PATCH 4197/4498] Revert "[nrf fromtree] Bluetooth controller nrf: ifdef some coded phy only code" This reverts commit 6a7a93c5ff3a44b58457be8b140fec29fb13ebe1. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 9ed66dc3442..71e5ffa0e6f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -551,7 +551,6 @@ static inline void hal_radio_sw_switch_cleanup(void) nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(1)); } -#if defined(CONFIG_BT_CTLR_PHY_CODED) static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index) { @@ -613,7 +612,6 @@ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( ppi_dis); } -#endif /* defined(CONFIG_BT_CTLR_PHY_CODED) */ static inline void hal_radio_sw_switch_ppi_group_setup(void) { From 2cd7f15711379e9c1453360fe087e5ba7d285c3a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:04 +0000 Subject: [PATCH 4198/4498] Revert "[nrf fromtree] Bluetooth controller: nrf: Switch to use SOC_COMPATIBLE" This reverts commit cd06b1c9d643c1b3591a925d03bcc48cd9cbc36e. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/Kconfig.ll_sw_split | 10 +-- .../controller/hci/nordic/hci_vendor.h | 2 +- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 72 +++++++++---------- .../nrf5/radio/radio_nrf5_dppi_resources.h | 4 +- .../controller/ll_sw/nordic/hal/nrf5/swi.h | 8 +-- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 4cd8e200b63..1fa9031d47f 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -643,7 +643,7 @@ config BT_CTLR_SLOT_RESERVATION_UPDATE config BT_CTLR_LLL_PRIO int "Lower Link Layer (Radio) IRQ priority" if (BT_CTLR_ULL_LLL_PRIO_SUPPORT && !BT_CTLR_ZLI) range 0 3 if SOC_SERIES_NRF51X - range 0 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) + range 0 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) default 0 help The interrupt priority for event preparation and radio IRQ. @@ -651,7 +651,7 @@ config BT_CTLR_LLL_PRIO config BT_CTLR_ULL_HIGH_PRIO int "Upper Link Layer High IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT range BT_CTLR_LLL_PRIO 3 if SOC_SERIES_NRF51X - range BT_CTLR_LLL_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) + range BT_CTLR_LLL_PRIO 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) default BT_CTLR_LLL_PRIO if (!BT_CTLR_ULL_LLL_PRIO_SUPPORT || BT_CTLR_ZLI || BT_CTLR_LOW_LAT) default 1 help @@ -661,7 +661,7 @@ config BT_CTLR_ULL_HIGH_PRIO config BT_CTLR_ULL_LOW_PRIO int "Upper Link Layer Low IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT range BT_CTLR_ULL_HIGH_PRIO 3 if SOC_SERIES_NRF51X - range BT_CTLR_ULL_HIGH_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) + range BT_CTLR_ULL_HIGH_PRIO 6 if (SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) default BT_CTLR_ULL_HIGH_PRIO help The interrupt priority for Ticker's Job IRQ and Upper Link Layer @@ -705,7 +705,7 @@ config BT_CTLR_RX_PDU_META config BT_CTLR_RADIO_ENABLE_FAST bool "Use tTXEN/RXEN,FAST ramp-up" - depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X + depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X default y help Enable use of fast radio ramp-up mode. @@ -719,7 +719,7 @@ config BT_CTLR_TIFS_HW config BT_CTLR_SW_SWITCH_SINGLE_TIMER bool "Single TIMER tIFS Trx SW switching" - depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) + depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X) help Implement the tIFS Trx SW switch with the same TIMER instance, as the one used for BLE event timing. Requires diff --git a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h index bea7004f9c9..4d3245728ed 100644 --- a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h +++ b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h @@ -10,7 +10,7 @@ #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF51X #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF52X -#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#elif defined(CONFIG_SOC_SERIES_NRF53X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF53X #endif #else diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 3fc76a27bdf..1875dca7896 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -311,7 +311,7 @@ void radio_phy_set(uint8_t phy, uint8_t flags) void radio_tx_power_set(int8_t power) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) uint32_t value; /* NOTE: TXPOWER register only accepts upto 0dBm, hence use the HAL @@ -322,12 +322,12 @@ void radio_tx_power_set(int8_t power) NRF_RADIO->TXPOWER = value; hal_radio_tx_power_high_voltage_set(power); -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#else /* !CONFIG_SOC_SERIES_NRF53X */ /* NOTE: valid value range is passed by Kconfig define. */ NRF_RADIO->TXPOWER = (uint32_t)power; -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } void radio_tx_power_max_set(void) @@ -345,25 +345,25 @@ int8_t radio_tx_power_min_get(void) int8_t radio_tx_power_max_get(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) return RADIO_TXPOWER_TXPOWER_Pos3dBm; -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#else /* !CONFIG_SOC_SERIES_NRF53X */ return (int8_t)hal_radio_tx_power_max_get(); -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } int8_t radio_tx_power_floor(int8_t power) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) /* NOTE: TXPOWER register only accepts upto 0dBm, +3dBm permitted by * use of high voltage being set for radio when TXPOWER register is set. */ if (power >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { return RADIO_TXPOWER_TXPOWER_Pos3dBm; } -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ return (int8_t)hal_radio_tx_power_floor(power); } @@ -413,7 +413,7 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) bits_s1 = RADIO_PKT_CONF_LENGTH_8BIT - bits_len; #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF53X) + defined(CONFIG_SOC_SERIES_NRF53X) extra = 0U; phy = RADIO_PKT_CONF_PHY_GET(flags); @@ -510,7 +510,7 @@ uint32_t radio_rx_chain_delay_get(uint8_t phy, uint8_t flags) void radio_rx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -523,7 +523,7 @@ void radio_rx_enable(void) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN); @@ -532,7 +532,7 @@ void radio_rx_enable(void) void radio_tx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -545,7 +545,7 @@ void radio_tx_enable(void) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN); @@ -891,13 +891,13 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla * time-stamp. */ hal_radio_end_time_capture_ppi_config(); -#if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if !defined(CONFIG_SOC_SERIES_NRF53X) /* The function is not called for nRF5340 single timer configuration because * HAL_SW_SWITCH_TIMER_CLEAR_PPI is equal to HAL_RADIO_END_TIME_CAPTURE_PPI, * so channel is already enabled. */ hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ sw_tifs_toggle += 1U; @@ -1186,38 +1186,38 @@ void radio_tmr_rx_status_reset(void) void radio_tmr_tx_enable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#if defined(CONFIG_SOC_SERIES_NRF53X) +#else /* !CONFIG_SOC_SERIES_NRF53X */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(1U); #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */ -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } void radio_tmr_rx_enable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#if defined(CONFIG_SOC_SERIES_NRF53X) +#else /* !CONFIG_SOC_SERIES_NRF53X */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(0U); #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */ -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } void radio_tmr_tx_disable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#else /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } void radio_tmr_rx_disable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); -#else /* !CONFIG_SOC_COMPATIBLE_NRF53X */ -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */ +#else /* !CONFIG_SOC_SERIES_NRF53X */ +#endif /* !CONFIG_SOC_SERIES_NRF53X */ } void radio_tmr_tifs_set(uint32_t tifs) @@ -1304,7 +1304,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) last_pdu_end_us = 0U; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1317,7 +1317,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ return remainder_us; @@ -1331,7 +1331,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) last_pdu_end_us = 0U; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53X) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1344,7 +1344,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) * radio event but when the radio event is done. */ hal_sw_switch_timer_clear_ppi_config(); -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ /* start_us could be the current count in the timer */ @@ -1464,12 +1464,12 @@ void radio_tmr_end_capture(void) * hal_sw_switch_timer_clear_ppi_config() and sw_switch(). There is no need to * configure the channel again in this function. */ -#if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \ - (defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) +#if !defined(CONFIG_SOC_SERIES_NRF53X) || \ + (defined(CONFIG_SOC_SERIES_NRF53X) && !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) hal_radio_end_time_capture_ppi_config(); hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); -#endif /* !CONFIG_SOC_COMPATIBLE_NRF53X || - * (CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#endif /* !CONFIG_SOC_SERIES_NRF53X || + * (CONFIG_SOC_SERIES_NRF53X && !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) */ } @@ -1776,7 +1776,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; -#if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X) /* Enable CCM support for 8-bit length field PDUs. */ mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h index e1b47d03fd7..74fb56d9b5c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(DPPI_PRESENT) +#if defined(CONFIG_SOC_NRF5340_CPUNET) || defined(DPPI_PRESENT) /******************************************************************************* * Enable Radio on Event Timer tick: @@ -157,4 +157,4 @@ #define SW_SWITCH_TIMER_TASK_GROUP_BASE 0 #endif /* !CONFIG_BT_CTLR_TIFS_HW */ -#endif /* CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET || DPPI_PRESENT */ +#endif /* CONFIG_SOC_NRF5340_CPUNET || DPPI_PRESENT */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h index 6b364fd349a..eb9da5652ff 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h @@ -18,10 +18,10 @@ #endif /* nRF53 Series IRQ mapping */ -#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#elif defined(CONFIG_SOC_SERIES_NRF53X) /* nRF53 Series Engineering D and Revision 1 IRQ mapping */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) +#if defined(CONFIG_SOC_NRF5340_CPUNET) #define HAL_SWI_RADIO_IRQ SWI2_IRQn #define HAL_SWI_WORKER_IRQ RTC0_IRQn @@ -33,9 +33,9 @@ #define HAL_SWI_JOB_IRQ SWI3_IRQn #endif -#endif /* CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET */ +#endif /* CONFIG_SOC_NRF5340_CPUNET */ -#endif /* CONFIG_SOC_COMPATIBLE_NRF53X */ +#endif /* CONFIG_SOC_SERIES_NRF53X */ static inline void hal_swi_init(void) { From 9e6178ed17e6ef2c8f022784c3beb6894f995ec2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:04 +0000 Subject: [PATCH 4199/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix missing host feature reset" This reverts commit 0cbe44c1bf783f13cf6da1ede4e199771e97f3fd. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ll_feat.c | 5 ----- subsys/bluetooth/controller/ll_sw/ll_feat_internal.h | 7 ------- subsys/bluetooth/controller/ll_sw/ull.c | 7 +------ 3 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 subsys/bluetooth/controller/ll_sw/ll_feat_internal.h diff --git a/subsys/bluetooth/controller/ll_sw/ll_feat.c b/subsys/bluetooth/controller/ll_sw/ll_feat.c index d2ba2fefba0..a1aaa99ba6d 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_feat.c +++ b/subsys/bluetooth/controller/ll_sw/ll_feat.c @@ -70,11 +70,6 @@ uint8_t ll_set_host_feature(uint8_t bit_number, uint8_t bit_value) return BT_HCI_ERR_SUCCESS; } -void ll_feat_reset(void) -{ - host_features = 0U; -} - uint64_t ll_feat_get(void) { return LL_FEAT | (host_features & LL_FEAT_HOST_BIT_MASK); diff --git a/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h b/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h deleted file mode 100644 index 7c23cb1a4e5..00000000000 --- a/subsys/bluetooth/controller/ll_sw/ll_feat_internal.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -void ll_feat_reset(void); diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index e6a736f939d..29cf43cd6d9 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -44,7 +44,6 @@ #include "lll_sync_iso.h" #include "lll_iso_tx.h" #include "lll_conn.h" -#include "lll_conn_iso.h" #include "lll_df.h" #include "ull_adv_types.h" @@ -61,7 +60,6 @@ #endif /* CONFIG_BT_CTLR_USER_EXT */ #include "isoal.h" -#include "ll_feat_internal.h" #include "ull_internal.h" #include "ull_iso_internal.h" #include "ull_adv_internal.h" @@ -71,6 +69,7 @@ #include "ull_central_internal.h" #include "ull_iso_types.h" #include "ull_conn_internal.h" +#include "lll_conn_iso.h" #include "ull_conn_iso_types.h" #include "ull_central_iso_internal.h" #include "ull_llcp.h" @@ -900,10 +899,6 @@ void ll_reset(void) LL_ASSERT(!err); #endif -#if defined(CONFIG_BT_CTLR_SET_HOST_FEATURE) - ll_feat_reset(); -#endif /* CONFIG_BT_CTLR_SET_HOST_FEATURE */ - /* clear static random address */ (void)ll_addr_set(1U, NULL); } From 187b9042929e7a9e592b3bf847627666ad176372 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:04 +0000 Subject: [PATCH 4200/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix assertion due to late PER CIS active set" This reverts commit ca85f44bdbc22337acd4b3ff64b7fab086443271. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index f68ca66656f..d45d89aa009 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -250,8 +250,7 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->p_max_sdu = (uint16_t)(req->p_max_sdu[1] & 0x0F) << 8 | req->p_max_sdu[0]; - cis->lll.active = 0U; - cis->lll.handle = LLL_HANDLE_INVALID; + cis->lll.handle = 0xFFFF; cis->lll.acl_handle = acl->lll.handle; cis->lll.sub_interval = sys_get_le24(req->sub_interval); cis->lll.nse = req->nse; @@ -326,6 +325,7 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, cis->lll.cie = 0U; cis->lll.npi = 0U; cis->lll.flush = LLL_CIS_FLUSH_NONE; + cis->lll.active = 0U; cis->lll.datapath_ready_rx = 0U; cis->lll.tx.payload_count = 0U; cis->lll.rx.payload_count = 0U; From 61e74af480a872ad239a571168d4f47fa84184d3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:04 +0000 Subject: [PATCH 4201/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix PHY value in HCI LE CIS Established Event" This reverts commit 18f4f8597ba8339cb26fde13ac9917d027fca9ec. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/hci/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 0adbf5ff70c..30fb363fc9c 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -4245,8 +4245,8 @@ static void le_cis_established(struct pdu_data *pdu_data, sys_put_le24(cis->sync_delay, sep->cis_sync_delay); sys_put_le24(cig->c_latency, sep->c_latency); sys_put_le24(cig->p_latency, sep->p_latency); - sep->c_phy = find_lsb_set(lll_cis_c->phy); - sep->p_phy = find_lsb_set(lll_cis_p->phy); + sep->c_phy = lll_cis_c->phy; + sep->p_phy = lll_cis_p->phy; sep->nse = lll_cis->nse; sep->c_bn = lll_cis_c->bn; sep->p_bn = lll_cis_p->bn; From 2006e25cd388426d3a55c8bf4f0e06c0cfff6a8e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:05 +0000 Subject: [PATCH 4202/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use max time when scheduling Broadcast ISO" This reverts commit 5f4e7b0cc6f13cd4c8d659fc8833787d8997fa9e. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/ull_adv_internal.h | 3 - .../bluetooth/controller/ll_sw/ull_adv_iso.c | 63 ++++++------------- subsys/bluetooth/controller/ll_sw/ull_sched.c | 5 +- 3 files changed, 19 insertions(+), 52 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h index a2a0db7391f..f4d059e0cd3 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h @@ -322,9 +322,6 @@ struct lll_adv_iso_stream *ull_adv_iso_stream_get(uint16_t handle); /* helper function to release stream instances */ void ull_adv_iso_stream_release(struct ll_adv_iso_set *adv_iso); -/* helper function to return time reservation for Broadcast ISO event */ -uint32_t ull_adv_iso_max_time_get(const struct ll_adv_iso_set *adv_iso); - #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX) /* helper function to release unused DF configuration memory */ void ull_df_adv_cfg_release(struct lll_df_adv_cfg *df_adv_cfg); diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 6191f811311..de78352baa2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -57,7 +57,6 @@ static struct stream *adv_iso_stream_acquire(void); static uint16_t adv_iso_stream_handle_get(struct lll_adv_iso_stream *stream); static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing, uint32_t event_spacing_max); -static uint32_t adv_iso_time_get(const struct ll_adv_iso_set *adv_iso, bool max); static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, uint32_t iso_interval_us); static uint8_t adv_iso_chm_update(uint8_t big_handle); @@ -946,11 +945,6 @@ void ull_adv_iso_stream_release(struct ll_adv_iso_set *adv_iso) lll->adv = NULL; } -uint32_t ull_adv_iso_max_time_get(const struct ll_adv_iso_set *adv_iso) -{ - return adv_iso_time_get(adv_iso, true); -} - static int init_reset(void) { /* Add initializations common to power up initialization and HCI reset @@ -1004,12 +998,22 @@ static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing, return 0U; } -static uint32_t adv_iso_time_get(const struct ll_adv_iso_set *adv_iso, bool max) +static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, + uint32_t iso_interval_us) { - const struct lll_adv_iso *lll_iso; + uint32_t ticks_slot_overhead; + struct lll_adv_iso *lll_iso; + uint32_t ticks_slot_offset; + uint32_t volatile ret_cb; + uint32_t ticks_anchor; uint32_t ctrl_spacing; uint32_t pdu_spacing; - uint32_t time_us; + uint32_t ticks_slot; + uint32_t slot_us; + uint32_t ret; + int err; + + ull_hdr_init(&adv_iso->ull); lll_iso = &adv_iso->lll; @@ -1019,46 +1023,15 @@ static uint32_t adv_iso_time_get(const struct ll_adv_iso_set *adv_iso, bool max) ctrl_spacing = PDU_BIS_US(sizeof(struct pdu_big_ctrl), lll_iso->enc, lll_iso->phy, lll_iso->phy_flags); - /* 1. Maximum PDU transmission time in 1M/2M/S8 PHY is 17040 us, or - * represented in 15-bits. - * 2. NSE in the range 1 to 31 is represented in 5-bits - * 3. num_bis in the range 1 to 31 is represented in 5-bits - * - * Hence, worst case event time can be represented in 25-bits plus - * one each bit for added ctrl_spacing and radio event overheads. I.e. - * 27-bits required and sufficiently covered by using 32-bit data type - * for time_us. - */ - - if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX) || max) { - time_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + + if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX)) { + slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + ctrl_spacing; } else { - time_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - + slot_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - lll_iso->ptc); } - /* Add implementation defined radio event overheads */ - time_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - - return time_us; -} - -static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, - uint32_t iso_interval_us) -{ - uint32_t ticks_slot_overhead; - uint32_t ticks_slot_offset; - volatile uint32_t ret_cb; - uint32_t ticks_anchor; - uint32_t ticks_slot; - uint32_t slot_us; - uint32_t ret; - int err; - - ull_hdr_init(&adv_iso->ull); - - slot_us = adv_iso_time_get(adv_iso, false); + slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; adv_iso->ull.ticks_active_to_start = 0U; adv_iso->ull.ticks_prepare_to_start = @@ -1093,7 +1066,7 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, ret_cb = TICKER_STATUS_BUSY; ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD, - (TICKER_ID_ADV_ISO_BASE + adv_iso->lll.handle), + (TICKER_ID_ADV_ISO_BASE + lll_iso->handle), ticks_anchor, 0U, HAL_TICKER_US_TO_TICKS(iso_interval_us), HAL_TICKER_REMAINDER(iso_interval_us), diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index 38589a2e644..e7ca8a0358b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -701,10 +701,7 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) adv_iso = ull_adv_iso_get(ticker_id - TICKER_ID_ADV_ISO_BASE); if (adv_iso) { - uint32_t time_us; - - time_us = ull_adv_iso_max_time_get(adv_iso); - *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + *ticks_slot = adv_iso->ull.ticks_slot; return &adv_iso->ull; } From 1a9b63edcf9937b9f9fbfb8f87d1dea14bc8ffc7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:05 +0000 Subject: [PATCH 4203/4498] Revert "[nrf fromtree] Bluetooth: Controller: Maximize BIG event length and preempt PTO & CTRL" This reverts commit 15f89d667165914c90f6b5931e3d15b97f624f4a. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/Kconfig.ll_sw_split | 12 ----- .../bluetooth/controller/ll_sw/ull_adv_iso.c | 51 ++++++------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 1fa9031d47f..5fb2c54d085 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -386,18 +386,6 @@ config BT_CTLR_ADV_RESERVE_MAX corresponding to the Advertising Data present at the time of the start/enable of Advertising is used. -config BT_CTLR_ADV_ISO_RESERVE_MAX - bool "Use maximum Broadcast ISO event time reservation" - depends on BT_CTLR_ADV_ISO - default y - help - Use maximum Broadcast ISO event time reservation. If disabled, then - time reservation does not include the pre-transmissions of the last - BIS and any Control subevents. This will allow extended or periodic - advertising events to preempt the BIG events but allow higher radio - utilizations by allowing larger BIG events when not overlapping with - extended or periodic advertising. - config BT_CTLR_ADV_AUX_SYNC_OFFSET int "Pre-defined offset between AUX_ADV_IND and AUX_SYNC_IND" depends on BT_CTLR_ADV_PERIODIC diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index de78352baa2..4551fac228d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -282,41 +282,27 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, event_spacing = latency_packing + ctrl_spacing + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - /* Check if aux context allocated before we are creating ISO */ - if (adv->lll.aux) { - aux = HDR_LLL2ULL(adv->lll.aux); - } else { - aux = NULL; - } - /* Calculate overheads due to extended advertising. */ - if (aux && aux->is_started) { - ticks_slot_aux = aux->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, - aux->ull.ticks_prepare_to_start); - } else { - ticks_slot_overhead = 0U; - } - ticks_slot_aux += ticks_slot_overhead; + aux = HDR_LLL2ULL(adv->lll.aux); + ticks_slot_aux = aux->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, + aux->ull.ticks_prepare_to_start); } else { - ticks_slot_aux = 0U; + ticks_slot_overhead = 0U; } + ticks_slot_aux += ticks_slot_overhead; /* Calculate overheads due to periodic advertising. */ sync = HDR_LLL2ULL(lll_adv_sync); - if (sync->is_started) { - ticks_slot_sync = sync->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, - sync->ull.ticks_prepare_to_start); - } else { - ticks_slot_overhead = 0U; - } - ticks_slot_sync += ticks_slot_overhead; + ticks_slot_sync = sync->ull.ticks_slot; + if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { + ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, + sync->ull.ticks_prepare_to_start); } else { - ticks_slot_sync = 0U; + ticks_slot_overhead = 0U; } + ticks_slot_sync += ticks_slot_overhead; /* Calculate total overheads due to extended and periodic advertising */ if (CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET > 0U) { @@ -1022,15 +1008,8 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, EVENT_MSS_US; ctrl_spacing = PDU_BIS_US(sizeof(struct pdu_big_ctrl), lll_iso->enc, lll_iso->phy, lll_iso->phy_flags); - - if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX)) { - slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + - ctrl_spacing; - } else { - slot_us = pdu_spacing * ((lll_iso->nse * lll_iso->num_bis) - - lll_iso->ptc); - } - + slot_us = (pdu_spacing * lll_iso->nse * lll_iso->num_bis) + + ctrl_spacing; slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; adv_iso->ull.ticks_active_to_start = 0U; From d58bb9f33ece628ffa19496b1efcc5df1e09d5e9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:05 +0000 Subject: [PATCH 4204/4498] Revert "[nrf fromtree] Bluetooth: Controller: Calculate Broadcast ISO event overheads" This reverts commit 5066d19a144b3096e6ee5c6ceb755b7589938a5e. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/ll_sw/ull_adv_iso.c | 52 +++---------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 4551fac228d..cb53f913b01 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -97,19 +97,13 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, struct ll_adv_iso_set *adv_iso; struct pdu_adv *pdu_prev, *pdu; struct pdu_big_info *big_info; - uint32_t ticks_slot_overhead; - struct ll_adv_sync_set *sync; - struct ll_adv_aux_set *aux; uint32_t event_spacing_max; uint8_t pdu_big_info_size; uint32_t iso_interval_us; uint32_t latency_packing; - uint32_t ticks_slot_sync; - uint32_t ticks_slot_aux; memq_link_t *link_cmplt; memq_link_t *link_term; struct ll_adv_set *adv; - uint32_t slot_overhead; uint32_t event_spacing; uint16_t ctrl_spacing; uint8_t sdu_per_event; @@ -281,48 +275,14 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, lll_adv_iso->num_bis; event_spacing = latency_packing + ctrl_spacing + EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US; - - /* Calculate overheads due to extended advertising. */ - aux = HDR_LLL2ULL(adv->lll.aux); - ticks_slot_aux = aux->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, - aux->ull.ticks_prepare_to_start); - } else { - ticks_slot_overhead = 0U; - } - ticks_slot_aux += ticks_slot_overhead; - - /* Calculate overheads due to periodic advertising. */ - sync = HDR_LLL2ULL(lll_adv_sync); - ticks_slot_sync = sync->ull.ticks_slot; - if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { - ticks_slot_overhead = MAX(sync->ull.ticks_active_to_start, - sync->ull.ticks_prepare_to_start); - } else { - ticks_slot_overhead = 0U; - } - ticks_slot_sync += ticks_slot_overhead; - - /* Calculate total overheads due to extended and periodic advertising */ - if (CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET > 0U) { - ticks_slot_overhead = MAX(ticks_slot_aux, ticks_slot_sync); - } else { - ticks_slot_overhead = ticks_slot_aux + ticks_slot_sync; - } - - /* Calculate max available ISO event spacing */ - slot_overhead = HAL_TICKER_TICKS_TO_US(ticks_slot_overhead); - if (slot_overhead < iso_interval_us) { - event_spacing_max = iso_interval_us - slot_overhead; - } else { - event_spacing_max = 0U; - } - - /* Check if ISO interval too small to fit the calculated BIG event - * timing required for the supplied BIG create parameters. + /* FIXME: calculate overheads due to extended and periodic advertising. */ + event_spacing_max = iso_interval_us - 2000U; if (event_spacing > event_spacing_max) { + /* ISO interval too small to fit the calculated BIG event + * timing required for the supplied BIG create parameters. + */ + /* Release allocated link buffers */ ll_rx_link_release(link_cmplt); ll_rx_link_release(link_term); From 11063f255a8b4f147475fa0966d25172a33c78e0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:05 +0000 Subject: [PATCH 4205/4498] Revert "[nrf fromtree] Bluetooth: Controller: Minor rename ull_adv_sync_iso_created()" This reverts commit 46a5b07bbc1d5dd0ed2c5bb7a12d4996d6703795. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_adv_internal.h | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_sync.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h index f4d059e0cd3..00bf3c126df 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_internal.h @@ -205,7 +205,7 @@ ull_adv_aux_hdr_len_fill(struct pdu_adv_com_ext_adv *com_hdr, uint8_t len) void ull_adv_sync_started_stopped(struct ll_adv_aux_set *aux); /* notify adv_sync_set that an iso instance has been created for it */ -void ull_adv_sync_iso_created(struct ll_adv_sync_set *sync); +void ull_adv_iso_created(struct ll_adv_sync_set *sync); #endif /* CONFIG_BT_CTLR_ADV_EXT */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index cb53f913b01..89e66ff99e5 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -487,7 +487,7 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) /* Notify the sync instance */ - ull_adv_sync_iso_created(HDR_LLL2ULL(lll_adv_sync)); + ull_adv_iso_created(HDR_LLL2ULL(lll_adv_sync)); #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ /* Commit the BIGInfo in the ACAD field of Periodic Advertising */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c index f1f521ca235..bbb1b351848 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c @@ -222,7 +222,7 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags) } #if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) -void ull_adv_sync_iso_created(struct ll_adv_sync_set *sync) +void ull_adv_iso_created(struct ll_adv_sync_set *sync) { if (sync->lll.iso && sync->is_started) { uint8_t iso_handle = sync->lll.iso->handle; From f1ae885d8799eda41d34fdc50cfec38496e69887 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:06 +0000 Subject: [PATCH 4206/4498] Revert "[nrf fromtree] Bluetooth: Controller: Revert EVENT_OVERHEAD_START_US for Coded PHY" This reverts commit 064912923c684da6a02b32ebec9a895b4f2ae319. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h index db5f8e3f1d8..7df39f65c8a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h @@ -21,22 +21,22 @@ /* Active connection in peripheral role with extended scanning on 1M and Coded * PHY, scheduling and receiving auxiliary PDUs. */ -#define EVENT_OVERHEAD_START_US 733 /* 24 RTC ticks */ +#define EVENT_OVERHEAD_START_US 458 #else /* !CONFIG_BT_CTLR_PHY_CODED */ /* Active connection in peripheral role with extended scanning on 1M only, * scheduling and receiving auxiliary PDUs. */ -#define EVENT_OVERHEAD_START_US 428 /* 14 RTC ticks */ +#define EVENT_OVERHEAD_START_US 428 #endif /* !CONFIG_BT_CTLR_PHY_CODED */ #else /* !CONFIG_BT_OBSERVER */ /* Active connection in peripheral role with legacy scanning on 1M. */ -#define EVENT_OVERHEAD_START_US 275 /* 9 RTC ticks */ +#define EVENT_OVERHEAD_START_US 275 #endif /* !CONFIG_BT_OBSERVER */ #else /* !CONFIG_BT_CTLR_ADV_EXT */ /* Active connection in peripheral role with additional advertising state. */ -#define EVENT_OVERHEAD_START_US 275 /* 9 RTC ticks */ +#define EVENT_OVERHEAD_START_US 275 #endif /* !CONFIG_BT_CTLR_ADV_EXT */ /* Worst-case time margin needed after event end-time in the air From b3372acfe2f0a9eb5dff5266f1061d261211436f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:06 +0000 Subject: [PATCH 4207/4498] Revert "[nrf fromtree] Bluetooth: Controller: Reduce successive ticker_job() on Extended Scan" This reverts commit c86add5e2012481673862ff86407a15979280e0b. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index ecdfdd60d07..316cec7fec7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -682,13 +682,6 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) ticks_aux_offset = HAL_TICKER_US_TO_TICKS(aux_offset_us); -#if (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) - /* disable ticker job, in order to chain yield and start to reduce - * CPU use by reducing successive calls to ticker_job(). - */ - mayfly_enable(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 0); -#endif - /* Yield the primary scan window or auxiliary or periodic sync event * in ticker. */ @@ -721,13 +714,6 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) ((ticker_status == TICKER_STATUS_FAILURE) && IS_ENABLED(CONFIG_BT_TICKER_LOW_LAT))); -#if (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) - /* enable ticker job, queued ticker operation will be handled - * thereafter. - */ - mayfly_enable(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1); -#endif - return; ull_scan_aux_rx_flush: From f726a15c15ff0eddd9e98adbaf0ae99ab4c1684e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:06 +0000 Subject: [PATCH 4208/4498] Revert "[nrf fromtree] Bluetooth: Controller: Refactor prepare dequeue iteration code" This reverts commit 290662fbfd0c9aecf7067a2440db51b9d6260027. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/lll/lll.c | 165 +++++++++--------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index db8f25a374c..9ccc36e49e5 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -65,9 +65,7 @@ static int init_reset(void); #if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) static inline void done_inc(void); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ -static inline bool is_done_sync(void); -static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx); -static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb); +static struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb); static void isr_race(void *param); #if !defined(CONFIG_BT_CTLR_LOW_LAT) @@ -645,27 +643,52 @@ void lll_isr_early_abort(void *param) lll_done(NULL); } +static int init_reset(void) +{ + return 0; +} + +#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) +static inline void done_inc(void) +{ + event.done.lll_count++; + LL_ASSERT(event.done.lll_count != event.done.ull_count); +} +#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ + +static inline bool is_done_sync(void) +{ +#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) + return event.done.lll_count == event.done.ull_count; +#else /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ + return true; +#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ +} + int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, lll_prepare_cb_t prepare_cb, struct lll_prepare_param *prepare_param, uint8_t is_resume, uint8_t is_dequeue) { - struct lll_event *ready; - struct lll_event *next; + struct lll_event *p; uint8_t idx; int err; /* Find the ready prepare in the pipeline */ idx = UINT8_MAX; - ready = prepare_dequeue_iter_ready_get(&idx); + p = ull_prepare_dequeue_iter(&idx); + while (p && (p->is_aborted || p->is_resume)) { + p = ull_prepare_dequeue_iter(&idx); + } /* Current event active or another prepare is ready in the pipeline */ if ((!is_dequeue && !is_done_sync()) || event.curr.abort_cb || - (ready && is_resume)) { + (p && is_resume)) { #if defined(CONFIG_BT_CTLR_LOW_LAT) lll_prepare_cb_t resume_cb; #endif /* CONFIG_BT_CTLR_LOW_LAT */ + struct lll_event *next; if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) && event.curr.param) { /* early abort */ @@ -683,28 +706,29 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, } /* Always start preempt timeout for first prepare in pipeline */ - struct lll_event *first = ready ? ready : next; + struct lll_event *first = p ? p : next; uint32_t ret; /* Start the preempt timeout */ - ret = preempt_ticker_start(first, ready, next); + ret = preempt_ticker_start(first, p, next); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); #else /* CONFIG_BT_CTLR_LOW_LAT */ next = NULL; - while (ready) { - if (!ready->is_aborted) { - if (event.curr.param == ready->prepare_param.param) { - ready->is_aborted = 1; - ready->abort_cb(&ready->prepare_param, - ready->prepare_param.param); + while (p) { + if (!p->is_aborted) { + if (event.curr.param == + p->prepare_param.param) { + p->is_aborted = 1; + p->abort_cb(&p->prepare_param, + p->prepare_param.param); } else { - next = ready; + next = p; } } - ready = ull_prepare_dequeue_iter(&idx); + p = ull_prepare_dequeue_iter(&idx); } if (next) { @@ -725,7 +749,7 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, return -EINPROGRESS; } - LL_ASSERT(!ready || &ready->prepare_param == prepare_param); + LL_ASSERT(!p || &p->prepare_param == prepare_param); event.curr.param = prepare_param->param; event.curr.is_abort_cb = is_abort_cb; @@ -750,13 +774,15 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, */ /* Find next prepare needing preempt timeout to be setup */ - next = prepare_dequeue_iter_ready_get(&idx); - if (!next) { - return err; - } + do { + p = ull_prepare_dequeue_iter(&idx); + if (!p) { + return err; + } + } while (p->is_aborted || p->is_resume); /* Start the preempt timeout */ - ret = preempt_ticker_start(next, NULL, next); + ret = preempt_ticker_start(p, NULL, p); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); #endif /* !CONFIG_BT_CTLR_LOW_LAT */ @@ -764,40 +790,7 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, return err; } -static int init_reset(void) -{ - return 0; -} - -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) -static inline void done_inc(void) -{ - event.done.lll_count++; - LL_ASSERT(event.done.lll_count != event.done.ull_count); -} -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ - -static inline bool is_done_sync(void) -{ -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) - return event.done.lll_count == event.done.ull_count; -#else /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ - return true; -#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ -} - -static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx) -{ - struct lll_event *ready; - - do { - ready = ull_prepare_dequeue_iter(idx); - } while (ready && (ready->is_aborted || ready->is_resume)); - - return ready; -} - -static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb) +static struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb) { struct lll_prepare_param prepare_param = {0}; @@ -985,7 +978,7 @@ static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, static void preempt(void *param) { lll_prepare_cb_t resume_cb; - struct lll_event *ready; + struct lll_event *next; uint8_t idx; int err; @@ -996,32 +989,35 @@ static void preempt(void *param) /* Find a prepare that is ready and not a resume */ idx = UINT8_MAX; - ready = prepare_dequeue_iter_ready_get(&idx); - if (!ready) { - /* No ready prepare */ + do { + next = ull_prepare_dequeue_iter(&idx); + } while (next && (next->is_aborted || next->is_resume)); + + /* No ready prepare */ + if (!next) { return; } /* Preemptor not in pipeline */ - if (ready->prepare_param.param != param) { - struct lll_event *ready_next = NULL; - struct lll_event *preemptor; + if (next->prepare_param.param != param) { + struct lll_event *next_next = NULL; + struct lll_event *e; uint32_t ret; /* Find if a short prepare request in the pipeline */ do { - preemptor = ull_prepare_dequeue_iter(&idx); - if (!ready_next && preemptor && !preemptor->is_aborted && - !preemptor->is_resume) { - ready_next = preemptor; + e = ull_prepare_dequeue_iter(&idx); + if (!next_next && e && !e->is_aborted && + !e->is_resume) { + next_next = e; } - } while (preemptor && (preemptor->is_aborted || preemptor->is_resume || - (preemptor->prepare_param.param != param))); + } while (e && (e->is_aborted || e->is_resume || + (e->prepare_param.param != param))); /* No short prepare request in pipeline */ - if (!preemptor) { - /* Start the preempt timeout for ready event */ - ret = preempt_ticker_start(ready, NULL, ready); + if (!e) { + /* Start the preempt timeout for next event */ + ret = preempt_ticker_start(next, NULL, next); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); @@ -1032,29 +1028,34 @@ static void preempt(void *param) * prepare event. For now, lets assert when many * enqueued prepares need aborting. */ - LL_ASSERT(preemptor == ready_next); + LL_ASSERT(next_next == e); /* Abort the prepare that is present before the short prepare */ - ready->is_aborted = 1; - ready->abort_cb(&ready->prepare_param, ready->prepare_param.param); + next->is_aborted = 1; + next->abort_cb(&next->prepare_param, next->prepare_param.param); /* As the prepare queue has been refreshed due to the call of * abort_cb which invokes the lll_done, find the latest prepare */ idx = UINT8_MAX; - ready = prepare_dequeue_iter_ready_get(&idx); - if (!ready) { - /* No ready prepare */ + do { + next = ull_prepare_dequeue_iter(&idx); + } while (next && (next->is_aborted || next->is_resume)); + + /* No ready prepare */ + if (!next) { return; } } /* Check if current event want to continue */ - err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); + err = event.curr.is_abort_cb(next->prepare_param.param, + event.curr.param, + &resume_cb); if (!err) { /* Let preemptor LLL know about the cancelled prepare */ - ready->is_aborted = 1; - ready->abort_cb(&ready->prepare_param, ready->prepare_param.param); + next->is_aborted = 1; + next->abort_cb(&next->prepare_param, next->prepare_param.param); return; } From e963e7746ede7015ef4348bd0dd9f695d9f13297 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:06 +0000 Subject: [PATCH 4209/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix short prepare when many enqueued in pipeline" This reverts commit 3cefcc0b7485c4bdf5c494b9dda99921d5a36ae7. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/lll/lll.c | 69 +++++++------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 9ccc36e49e5..b127e60a9f4 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -899,6 +899,15 @@ static uint32_t preempt_ticker_start(struct lll_event *first, LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); + /* Set early as we get called again through the call to + * abort_cb(). + */ + ticks_at_preempt = ticks_at_preempt_new; + + /* Abort previous prepare that set the preempt timeout */ + prev->is_aborted = 1U; + prev->abort_cb(&prev->prepare_param, prev->prepare_param.param); + /* Schedule short preempt timeout */ first = next; } else { @@ -987,11 +996,17 @@ static void preempt(void *param) return; } - /* Find a prepare that is ready and not a resume */ + /* Check if any prepare in pipeline */ idx = UINT8_MAX; - do { + next = ull_prepare_dequeue_iter(&idx); + if (!next) { + return; + } + + /* Find a prepare that is ready and not a resume */ + while (next && (next->is_aborted || next->is_resume)) { next = ull_prepare_dequeue_iter(&idx); - } while (next && (next->is_aborted || next->is_resume)); + } /* No ready prepare */ if (!next) { @@ -1000,52 +1015,14 @@ static void preempt(void *param) /* Preemptor not in pipeline */ if (next->prepare_param.param != param) { - struct lll_event *next_next = NULL; - struct lll_event *e; uint32_t ret; - /* Find if a short prepare request in the pipeline */ - do { - e = ull_prepare_dequeue_iter(&idx); - if (!next_next && e && !e->is_aborted && - !e->is_resume) { - next_next = e; - } - } while (e && (e->is_aborted || e->is_resume || - (e->prepare_param.param != param))); - - /* No short prepare request in pipeline */ - if (!e) { - /* Start the preempt timeout for next event */ - ret = preempt_ticker_start(next, NULL, next); - LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || - (ret == TICKER_STATUS_BUSY)); - - return; - } - - /* FIXME: Abort all events in pipeline before the short - * prepare event. For now, lets assert when many - * enqueued prepares need aborting. - */ - LL_ASSERT(next_next == e); - - /* Abort the prepare that is present before the short prepare */ - next->is_aborted = 1; - next->abort_cb(&next->prepare_param, next->prepare_param.param); - - /* As the prepare queue has been refreshed due to the call of - * abort_cb which invokes the lll_done, find the latest prepare - */ - idx = UINT8_MAX; - do { - next = ull_prepare_dequeue_iter(&idx); - } while (next && (next->is_aborted || next->is_resume)); + /* Start the preempt timeout */ + ret = preempt_ticker_start(next, NULL, next); + LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || + (ret == TICKER_STATUS_BUSY)); - /* No ready prepare */ - if (!next) { - return; - } + return; } /* Check if current event want to continue */ From 0cba24aa81f99b18c40a2dcc7e3c3c57c1f545a0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:07 +0000 Subject: [PATCH 4210/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix ticks_slot_window use in Observer" This reverts commit 368963a73f394687b0fd9b648942d7674213d201. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_scan.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan.c b/subsys/bluetooth/controller/ll_sw/ull_scan.c index 21d6cc9c401..1ee99565a13 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan.c @@ -500,10 +500,6 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan) * enabled. */ } - -#if defined(CONFIG_BT_TICKER_EXT) - ll_scan_ticker_ext[handle].ticks_slot_window = 0U; -#endif /* CONFIG_BT_TICKER_EXT */ } /* 1M scan window starts without any offset */ @@ -563,10 +559,6 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan) } else { ticks_offset = 0U; } - -#if defined(CONFIG_BT_TICKER_EXT) - ll_scan_ticker_ext[handle].ticks_slot_window = 0U; -#endif /* CONFIG_BT_TICKER_EXT */ } else { ticks_offset = 0U; } From 41d95b69595211816a1732f3333b2fc665a631e0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:07 +0000 Subject: [PATCH 4211/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use ticker_ticks_diff_get to check short prepare" This reverts commit 146b77c3f11030a321efb7cf7eec51f76a13e0a8. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index b127e60a9f4..fe0a031d402 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -869,13 +869,6 @@ static uint32_t preempt_ticker_start(struct lll_event *first, (preempt_req != preempt_ack)) { uint32_t diff; - /* preempt timeout already started but no role/state in the head - * of prepare pipeline. - */ - if (!prev || prev->is_aborted) { - return TICKER_STATUS_SUCCESS; - } - /* Calc the preempt timeout */ p = &next->prepare_param; ull = HDR_LLL2ULL(p->param); @@ -888,9 +881,9 @@ static uint32_t preempt_ticker_start(struct lll_event *first, ticks_at_preempt_new &= HAL_TICKER_CNTR_MASK; /* Check for short preempt timeouts */ - diff = ticker_ticks_diff_get(ticks_at_preempt_new, - ticks_at_preempt); - if ((diff & BIT(HAL_TICKER_CNTR_MSBIT)) == 0U) { + diff = ticks_at_preempt_new - ticks_at_preempt; + if (!prev || prev->is_aborted || + ((diff & BIT(HAL_TICKER_CNTR_MSBIT)) == 0U)) { return TICKER_STATUS_SUCCESS; } From 484392a0aff818a2ec6b7240ddaefef2444234c0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:07 +0000 Subject: [PATCH 4212/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use the state/role param in prepare pipeline" This reverts commit cb9acc327517604cbdf672db7e60e09623c0b053. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index fe0a031d402..cde3eaaa6ee 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -930,8 +930,8 @@ static uint32_t preempt_ticker_start(struct lll_event *first, TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, TICKER_NULL_SLOT, - preempt_ticker_cb, first->prepare_param.param, - ticker_start_op_cb, NULL); + preempt_ticker_cb, first, + ticker_start_op_cb, first); return ret; } @@ -1007,7 +1007,7 @@ static void preempt(void *param) } /* Preemptor not in pipeline */ - if (next->prepare_param.param != param) { + if (next != param) { uint32_t ret; /* Start the preempt timeout */ From ae72c59f197634013b38e026191205517e36e2bf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:08 +0000 Subject: [PATCH 4213/4498] Revert "[nrf fromtree] Revert "Bluetooth: Controller: Fix ull_prepare_dequeue for skipped events"" This reverts commit 1d6f3410fd50fe1b4920a95c3928f2e77e77c37d. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/lll/lll.c | 6 +-- subsys/bluetooth/controller/ll_sw/ull.c | 48 ++++++++++++------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index cde3eaaa6ee..fe0a031d402 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -930,8 +930,8 @@ static uint32_t preempt_ticker_start(struct lll_event *first, TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, TICKER_NULL_SLOT, - preempt_ticker_cb, first, - ticker_start_op_cb, first); + preempt_ticker_cb, first->prepare_param.param, + ticker_start_op_cb, NULL); return ret; } @@ -1007,7 +1007,7 @@ static void preempt(void *param) } /* Preemptor not in pipeline */ - if (next != param) { + if (next->prepare_param.param != param) { uint32_t ret; /* Start the preempt timeout */ diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 29cf43cd6d9..6be8bc4759e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2063,6 +2063,8 @@ void *ull_prepare_dequeue_iter(uint8_t *idx) void ull_prepare_dequeue(uint8_t caller_id) { + void *param_normal_head = NULL; + void *param_normal_next = NULL; void *param_resume_head = NULL; void *param_resume_next = NULL; struct lll_event *next; @@ -2103,31 +2105,41 @@ void ull_prepare_dequeue(uint8_t caller_id) /* The prepare element was not a resume event, it would * use the radio or was enqueued back into prepare * pipeline with a preempt timeout being set. + * + * Remember the first encountered and the next element + * in the prepare pipeline so that we do not infinitely + * loop through the resume events in prepare pipeline. */ if (!is_resume) { - break; - } - - /* Remember the first encountered resume and the next - * resume element in the prepare pipeline so that we do - * not infinitely loop through the resume events in - * prepare pipeline. - */ - if (!param_resume_head) { - param_resume_head = param; - } else if (!param_resume_next) { - param_resume_next = param; + if (!param_normal_head) { + param_normal_head = param; + } else if (!param_normal_next) { + param_normal_next = param; + } + } else { + if (!param_resume_head) { + param_resume_head = param; + } else if (!param_resume_next) { + param_resume_next = param; + } } /* Stop traversing the prepare pipeline when we reach - * back to the first or next resume event where we + * back to the first or next event where we * initially started processing the prepare pipeline. */ - if (next->is_resume && - ((next->prepare_param.param == - param_resume_head) || - (next->prepare_param.param == - param_resume_next))) { + if (!next->is_aborted && + ((!next->is_resume && + ((next->prepare_param.param == + param_normal_head) || + (next->prepare_param.param == + param_normal_next))) || + (next->is_resume && + !param_normal_next && + ((next->prepare_param.param == + param_resume_head) || + (next->prepare_param.param == + param_resume_next))))) { break; } } From 50c87cf5d05e2d80ce6b776e6f6aa120df5c8fb3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:08 +0000 Subject: [PATCH 4214/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix LE Set Ext Adv Param Cmd invalid status" This reverts commit 4af51708076cf561df2c53eb8154f39426100718. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_adv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index b5595e5e9c2..d7d5b23f63e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -690,7 +690,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, lll_adv_data_reset(&adv->lll.scan_rsp); err = lll_adv_aux_data_init(&adv->lll.scan_rsp); if (err) { - return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; + return err; } pdu = lll_adv_scan_rsp_peek(&adv->lll); @@ -710,7 +710,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, lll_adv_data_reset(&adv->lll.scan_rsp); err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; + return err; } pdu = lll_adv_scan_rsp_peek(&adv->lll); @@ -926,7 +926,7 @@ uint8_t ll_adv_enable(uint8_t enable) err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; + return err; } pdu_scan = lll_adv_scan_rsp_peek(lll); @@ -1873,7 +1873,7 @@ uint8_t ull_scan_rsp_set(struct ll_adv_set *adv, uint8_t len, err = lll_adv_data_init(&adv->lll.scan_rsp); if (err) { - return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; + return err; } prev = lll_adv_scan_rsp_peek(&adv->lll); From 8ea8caaba3494afbfa68892eda98a55461ce0050 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:08 +0000 Subject: [PATCH 4215/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix order of preempt timeout requested flag" This reverts commit 8246e66a8ecaa438b87a025d7d02312ad239a0ce. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/lll/lll.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index fe0a031d402..1f8031a7c07 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -835,17 +835,11 @@ static void ticker_start_op_cb(uint32_t status, void *param) ARG_UNUSED(param); LL_ASSERT(status == TICKER_STATUS_SUCCESS); - /* Increase preempt requested count before acknowledging that the - * ticker start operation for the preempt timeout has been handled. - */ - LL_ASSERT(preempt_req == preempt_ack); - preempt_req++; - - /* Increase preempt start ack count, to acknowledge that the ticker - * start operation has been handled. - */ LL_ASSERT(preempt_start_req != preempt_start_ack); preempt_start_ack++; + + LL_ASSERT(preempt_req == preempt_ack); + preempt_req++; } static uint32_t preempt_ticker_start(struct lll_event *first, @@ -860,11 +854,7 @@ static uint32_t preempt_ticker_start(struct lll_event *first, uint32_t preempt_to; uint32_t ret; - /* Do not request to start preempt timeout if already requested. - * - * Check if there is pending preempt timeout start requested or if - * preempt timeout ticker has already been scheduled. - */ + /* Do not request to start preempt timeout if already requested */ if ((preempt_start_req != preempt_start_ack) || (preempt_req != preempt_ack)) { uint32_t diff; From 314de51c0c3c79b116400d10f021b7626e120029 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:08 +0000 Subject: [PATCH 4216/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix ticker to prefer ticker node started" This reverts commit 3d9d12428797dd3d53f0d772c611be6e54cb934f. Signed-off-by: Dominik Ermel --- .../bluetooth/controller/Kconfig.ll_sw_split | 17 ----- subsys/bluetooth/controller/ticker/ticker.c | 12 +--- tests/bluetooth/init/prj_ctlr_ticker.conf | 65 ------------------- tests/bluetooth/init/testcase.yaml | 9 --- 4 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 tests/bluetooth/init/prj_ctlr_ticker.conf diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 5fb2c54d085..910c3819f0c 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -55,8 +55,6 @@ config BT_LLL_VENDOR_NORDIC select BT_TICKER_REMAINDER_GET if BT_BROADCASTER && BT_CTLR_ADV_EXT select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CENTRAL_ISO - select BT_TICKER_PREFER_START_BEFORE_STOP if BT_TICKER_SLOT_AGNOSTIC - default y help Use Nordic Lower Link Layer implementation. @@ -1038,21 +1036,6 @@ config BT_TICKER_SLOT_AGNOSTIC reservations and collision handling, and operates as a simple multi-instance programmable timer. -config BT_TICKER_PREFER_START_BEFORE_STOP - bool "Ticker prefer start before stop request" - help - Under race conditions wherein for a given ticker node if a number of - start and stop operations are enqueued towards ticker_job by a said - user execution context, then start operations is preferred to be - processed before stop operations. - - Without this option, the default behavior is to defer all start - requests after all stop requests enqueued by all user context having - been processed. The rationale for default behavior being that under - race conditions, start followed by stop requests, or start before stop - requests, the said ticker node is always scheduled and at timeout the - execution context can take decision based on its execution state. - config BT_CTLR_JIT_SCHEDULING bool "Just-in-Time Scheduling" select BT_TICKER_SLOT_AGNOSTIC diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index e5c89dca905..ead148e85ba 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -55,11 +55,9 @@ struct ticker_node { uint8_t force:1; /* If non-zero, node timeout should * be forced at next expiration */ -#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) uint8_t start_pending:1; /* If non-zero, start is pending for * bottom half of ticker_job. */ -#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ uint32_t ticks_periodic; /* If non-zero, interval * between expirations */ @@ -1909,15 +1907,12 @@ static inline uint8_t ticker_job_list_manage(struct ticker_instance *instance, /* if op is start, then skip update and stop ops */ if (user_op->op < TICKER_USER_OP_TYPE_UPDATE) { -#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) if (user_op->op == TICKER_USER_OP_TYPE_START) { /* Set start pending to validate a * successive, inline stop operation. */ ticker->start_pending = 1U; } -#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ - continue; } @@ -1928,10 +1923,7 @@ static inline uint8_t ticker_job_list_manage(struct ticker_instance *instance, * set status and continue. */ if ((user_op->op > TICKER_USER_OP_TYPE_STOP_ABS) || - ((state == 0U) && -#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) - !ticker->start_pending && -#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ + (((state == 0U) && !ticker->start_pending) && (user_op->op != TICKER_USER_OP_TYPE_YIELD_ABS)) || ((user_op->op == TICKER_USER_OP_TYPE_UPDATE) && (user_op->params.update.ticks_drift_plus == 0U) && @@ -2739,9 +2731,7 @@ static inline void ticker_job_list_insert(struct ticker_instance *instance, continue; } -#if defined(CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP) ticker->start_pending = 0U; -#endif /* CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP */ if (((ticker->req - ticker->ack) & 0xff) != 0U) { diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf deleted file mode 100644 index d77f519406b..00000000000 --- a/tests/bluetooth/init/prj_ctlr_ticker.conf +++ /dev/null @@ -1,65 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_CTLR=y -CONFIG_BT_LL_SW_SPLIT=y -CONFIG_BT_CTLR_DUP_FILTER_LEN=16 -CONFIG_BT_CTLR_CONN_PARAM_REQ=y -CONFIG_BT_CTLR_LE_PING=y -CONFIG_BT_CTLR_PRIVACY=n -CONFIG_BT_CTLR_EXT_SCAN_FP=n -CONFIG_BT_DATA_LEN_UPDATE=n -CONFIG_BT_PHY_UPDATE=y -CONFIG_BT_CTLR_CHAN_SEL_2=y -CONFIG_BT_CTLR_MIN_USED_CHAN=y -CONFIG_BT_CTLR_ADV_EXT=y -CONFIG_BT_CTLR_DTM_HCI=y -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_PHY_2M=y -CONFIG_BT_CTLR_PHY_2M_NRF=y -CONFIG_BT_CTLR_PHY_CODED=y -CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y -CONFIG_BT_CTLR_LLL_PRIO=0 -CONFIG_BT_CTLR_ULL_HIGH_PRIO=1 -CONFIG_BT_CTLR_XTAL_ADVANCED=n -CONFIG_BT_CTLR_SCHED_ADVANCED=n -CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y -CONFIG_BT_CTLR_TIFS_HW=n -CONFIG_BT_CTLR_FAST_ENC=y -CONFIG_BT_CTLR_TX_RETRY_DISABLE=y -CONFIG_BT_CTLR_CONN_RSSI=y -CONFIG_BT_CTLR_ADV_INDICATION=y -CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y -CONFIG_BT_CTLR_SCAN_REQ_RSSI=y -CONFIG_BT_CTLR_SCAN_INDICATION=y -CONFIG_BT_CTLR_PROFILE_ISR=y -CONFIG_BT_CTLR_DEBUG_PINS=y -CONFIG_BT_CTLR_TEST=y -CONFIG_BT_TICKER_EXT=n -CONFIG_BT_TICKER_SLOT_AGNOSTIC=y -CONFIG_BT_TICKER_PREFER_START_BEFORE_STOP=y -CONFIG_BT_HCI_VS_EXT=y -CONFIG_BT_HCI_MESH_EXT=n -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y -CONFIG_BT_SMP_SC_ONLY=y -CONFIG_BT_TINYCRYPT_ECC=y -CONFIG_BT_USE_DEBUG_KEYS=y -CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y -CONFIG_BT_GATT_CLIENT=y -CONFIG_BT_DEBUG_MONITOR_UART=y -CONFIG_BT_HCI_CORE_LOG_LEVEL_DBG=y -CONFIG_BT_CONN_LOG_LEVEL_DBG=y -CONFIG_BT_KEYS_LOG_LEVEL_DBG=y -CONFIG_BT_L2CAP_LOG_LEVEL_DBG=y -CONFIG_BT_SMP_LOG_LEVEL_DBG=y -CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=y -CONFIG_BT_SMP_SELFTEST=y -CONFIG_BT_ATT_LOG_LEVEL_DBG=y -CONFIG_BT_GATT_LOG_LEVEL_DBG=y -CONFIG_BT_BREDR=n -CONFIG_DEBUG=y -CONFIG_FLASH=y -CONFIG_SOC_FLASH_NRF_RADIO_SYNC_TICKER=n -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index fa30920dc1e..4c252115178 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -122,15 +122,6 @@ tests: integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 - bluetooth.init.test_ctlr_ticker: - extra_args: - - CONF_FILE=prj_ctlr_ticker.conf - platform_allow: - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 - integration_platforms: - - nrf52840dk_nrf52840 - - nrf52dk_nrf52832 bluetooth.init.test_ctlr_broadcaster: extra_args: CONF_FILE=prj_ctlr_broadcaster.conf platform_allow: From 06798bf8b64e00b548b77c4839260910ba537b55 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:08 +0000 Subject: [PATCH 4217/4498] Revert "[nrf fromtree] Bluetooth: controller: Included kconfigs for ISO-AL logging" This reverts commit c88e67bb9ad3655d3a5bab013518bf11950eda92. Signed-off-by: Dominik Ermel --- subsys/bluetooth/Kconfig.logging | 17 ----------------- subsys/bluetooth/controller/Kconfig | 7 ------- subsys/bluetooth/controller/ll_sw/isoal.c | 6 +++--- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/subsys/bluetooth/Kconfig.logging b/subsys/bluetooth/Kconfig.logging index addf8eb65fe..67a18afa919 100644 --- a/subsys/bluetooth/Kconfig.logging +++ b/subsys/bluetooth/Kconfig.logging @@ -398,16 +398,6 @@ config BT_DEBUG_SERVICE This option enables debug support for the Bluetooth Services. -# CONTROLLER (subsys/bluetooth/controller/Kconfig) - -config BT_CTLR_DEBUG_ISOAL - bool "[DEPRECATED] Bluetooth ISO-AL debug" - select DEPRECATED - depends on BT_CTLR_ISO - help - This option enables debug support for the Bluetooth ISO-AL. - - endmenu # [DEPRECATED] Others menu "[DEPRECATED] BR/EDR" @@ -910,13 +900,6 @@ legacy-debug-sym = BT_DEBUG_SERVICE module-str = "Bluetooth Services" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" -# CONTROLLER (subsys/bluetooth/controller/Kconfig) - -module = BT_CTLR_ISOAL -legacy-debug-sym = BT_CTLR_DEBUG_ISOAL -module-str = "Bluetooth Controller ISO-AL" -source "subsys/bluetooth/common/Kconfig.template.log_config_bt" - endmenu # Others menu "BR/EDR" diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 9ba67a05768..599a241b84b 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -210,13 +210,6 @@ config BT_CTLR_ISO_TX_BUFFER_SIZE Size of the Isochronous Tx buffers and the value returned in HCI LE Read Buffer Size V2 command response. -config BT_CTLR_ISOAL_LOG_DBG_VERBOSE - bool "ISO-AL verbose debug logging" - depends on BT_CTLR_ISOAL_LOG_LEVEL = 4 - default n - help - Use this option to enable ISO-AL verbose debug logging. - config BT_CTLR_ISOAL_SOURCES int "Number of Isochronous Adaptation Layer sources" depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index d43233f0289..6c1dedd7b9d 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -36,15 +36,15 @@ #include -LOG_MODULE_REGISTER(bt_ctlr_isoal, CONFIG_BT_CTLR_ISOAL_LOG_LEVEL); +LOG_MODULE_REGISTER(bt_ctlr_isoal, LOG_LEVEL_INF); #define ISOAL_LOG_DBG(...) LOG_DBG(__VA_ARGS__) -#if defined(CONFIG_BT_CTLR_ISOAL_LOG_DBG_VERBOSE) +#if defined(ISOAL_DEBUG_VERBOSE) #define ISOAL_LOG_DBGV(...) LOG_DBG(__VA_ARGS__) #else #define ISOAL_LOG_DBGV(...) (void) 0 -#endif /* CONFIG_BT_CTLR_ISOAL_LOG_DBG_VERBOSE */ +#endif /* ISOAL_DEBUG_VERBOSE */ #include "hal/debug.h" From ee49660ceea128610c37503b88c7494091d48c05 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:09 +0000 Subject: [PATCH 4218/4498] Revert "[nrf fromtree] Bluetooth: controller: disregard length field on pdu error" This reverts commit 85f3925dbeea3ffb867ae802773eca323c096322. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/isoal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 6c1dedd7b9d..d4cc61cea6c 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -738,7 +738,7 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, /* If status is not ISOAL_PDU_STATUS_VALID, length and LLID cannot be trusted */ llid = pdu->ll_id; pdu_err = (pdu_meta->meta->status != ISOAL_PDU_STATUS_VALID); - length = pdu_err ? 0U : pdu->len; + length = pdu->len; /* A zero length PDU with LLID 0b01 (PDU_BIS_LLID_START_CONTINUE) would be a padding PDU. * However if there are errors in the PDU, it could be an incorrectly receive non-padding * PDU. Therefore only consider a PDU with errors as padding if received after the end From 46295496a0464a673950d2e3df5c7d3c82010d67 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:09 +0000 Subject: [PATCH 4219/4498] Revert "[nrf fromtree] Bluetooth: Controller: ISO-AL validation and selection of TX time stamps" This reverts commit 4ef38a538433f2ca8df60c605d4047f43f1a529b. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/hci/hci.c | 14 +- subsys/bluetooth/controller/ll_sw/isoal.c | 212 +++++--------------- subsys/bluetooth/controller/ll_sw/isoal.h | 2 - subsys/bluetooth/controller/ll_sw/ull_iso.c | 3 +- 4 files changed, 55 insertions(+), 176 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 30fb363fc9c..9ca905c44e0 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5700,21 +5700,17 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt) * -- A captured time stamp of the SDU * -- A time stamp provided by the higher layer * -- A computed time stamp based on a sequence counter provided by the - * higher layer - * -- Any other method of determining Time_Offset - * (Uses a timestamp computed from the difference in provided - * timestamps, if the timestamp is deemed not based on the - * controller's clock) + * higher layer (Not implemented) + * -- Any other method of determining Time_Offset (Not implemented) */ - sdu_frag_tx.cntr_time_stamp = HAL_TICKER_TICKS_TO_US(ticker_ticks_now_get()); if (ts_flag) { - /* Use HCI provided time stamp */ + /* Overwrite time stamp with HCI provided time stamp */ time_stamp = net_buf_pull_mem(buf, sizeof(*time_stamp)); len -= sizeof(*time_stamp); sdu_frag_tx.time_stamp = sys_le32_to_cpu(*time_stamp); } else { - /* Use controller's capture time */ - sdu_frag_tx.time_stamp = sdu_frag_tx.cntr_time_stamp; + sdu_frag_tx.time_stamp = + HAL_TICKER_TICKS_TO_US(ticker_ticks_now_get()); } /* Extract ISO data header if included (PB_Flag 0b00 or 0b10) */ diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index d4cc61cea6c..00bc40504f7 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -1282,7 +1282,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } /* Update next state */ - ISOAL_LOG_DBGV("[%p] FSM Next State %s", sink, FSM_TO_STR(next_state)); + ISOAL_LOG_DBGV("[%p] Decoding: Next State %s", sink, FSM_TO_STR(next_state)); sp->fsm = next_state; /* Find next segment header, set to null if past end of PDU */ @@ -1350,7 +1350,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, if (error_sdu_pending) { sp->sdu_status = next_sdu_status; - err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0U, 0U, true, false); + err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); } break; @@ -1373,8 +1373,8 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } /* Update next state */ - ISOAL_LOG_DBGV("[%p] FSM Error Next State %s", sink, FSM_TO_STR(next_state)); - sp->fsm = next_state; + ISOAL_LOG_DBGV("[%p] Error: Next State %s", sink, FSM_TO_STR(next_state)); + sink->sdu_production.fsm = next_state; } sp->prev_pdu_id = meta->payload_number; @@ -1591,46 +1591,6 @@ void isoal_source_destroy(isoal_source_handle_t hdl) isoal_source_deallocate(hdl); } -static bool isoal_is_time_stamp_valid(const struct isoal_source *source_ctx, - const uint32_t cntr_time, - const uint32_t time_stamp) -{ - const struct isoal_source_session *session; - uint32_t time_diff; - - session = &source_ctx->session; - - /* This is an arbitrarily defined range. The purpose is to - * decide if the time stamp provided by the host is sensible - * within the controller's clock domain. An SDU interval plus ISO - * interval is expected to provide a good balance between situations - * where either could be significantly larger than the other. - * - * BT Core V5.4 : Vol 6 Low Energy Controller : Part G IS0-AL: - * 3.3 Time Stamp for SDU : - * When an HCI ISO Data packet sent by the Host does not contain - * a Time Stamp or the Time_Stamp value is not based on the - * Controller's clock, the Controller should determine the CIS - * or BIS event to be used to transmit the SDU contained in that - * packet based on the time of arrival of that packet. - */ - const uint32_t sdu_interval_us = session->sdu_interval; - const uint32_t iso_interval_us = session->iso_interval * ISO_INT_UNIT_US; - /* ISO Interval 0x0000_0004 ~ 0x0000_0C80 x 1250 + - * SDU Interval 0x0000_00FF ~ 0x000F_FFFF <= 004D_08FF - */ - const int32_t time_stamp_valid_half_range = sdu_interval_us + iso_interval_us; - const uint32_t time_stamp_valid_min = isoal_get_wrapped_time_us(cntr_time, - (-time_stamp_valid_half_range)); - const uint32_t time_stamp_valid_range = 2 * time_stamp_valid_half_range; - const bool time_stamp_is_valid = isoal_get_time_diff(time_stamp_valid_min, - time_stamp, - &time_diff) && - time_diff <= time_stamp_valid_range; - - return time_stamp_is_valid; -} - /** * Queue the PDU in production in the relevant LL transmit queue. If the * attmept to release the PDU fails, the buffer linked to the PDU will be released @@ -1676,8 +1636,8 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, status = source_ctx->session.pdu_emit(node_tx, handle); ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", - source_ctx, payload_number, status, - produced_pdu->contents.pdu->len, sdu_fragments); + source_ctx, payload_number, status, + produced_pdu->contents.pdu->len, sdu_fragments); if (status != ISOAL_STATUS_OK) { /* If it fails, the node will be released and no further attempt @@ -1881,8 +1841,8 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * @brief Fragment received SDU and produce unframed PDUs * @details Destination source may have an already partially built PDU * - * @param[in] source_hdl Destination source handle - * @param[in] tx_sdu SDU with packet boundary information + * @param source_hdl[in] Destination source handle + * @param tx_sdu[in] SDU with packet boundary information * * @return Status * @@ -2202,7 +2162,7 @@ static isoal_status_t isoal_insert_seg_header_timeoffset(struct isoal_source *so pp->pdu_available -= write_size; ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u TO=%u len=%u", - source, write_size, sc, cmplt, time_offset, seg_hdr.len); + source, write_size, sc, cmplt, time_offset, seg_hdr.len); return err; } @@ -2243,48 +2203,46 @@ static isoal_status_t isoal_update_seg_header_cmplt_length(struct isoal_source * PDU_ISO_SEG_HDR_SIZE); ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u len=%u", - source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); + source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); } /** * Find the earliest feasible event for transmission capacity is not wasted and * return information based on that event. - * - * @param[in] *source_ctx Destination source context + * @param[in] source_hdl Destination source handle * @param[in] tx_sdu SDU with meta data information * @param[out] payload_number Updated payload number for the selected event * @param[out] grp_ref_point Group reference point for the selected event * @param[out] time_offset Segmentation Time offset to selected event * @return The number SDUs skipped from the last */ -static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source *source_ctx, +static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t source_hdl, const struct isoal_sdu_tx *tx_sdu, uint64_t *payload_number, uint32_t *grp_ref_point, uint32_t *time_offset) { - const struct isoal_source_session *session; - const struct isoal_pdu_production *pp; + struct isoal_source_session *session; + struct isoal_pdu_production *pp; uint32_t actual_grp_ref_point; uint64_t next_payload_number; + struct isoal_source *source; uint16_t sdus_skipped; uint64_t actual_event; bool time_diff_valid; uint32_t time_diff; - uint32_t time_stamp_selected; - session = &source_ctx->session; - pp = &source_ctx->pdu_production; + source = &isoal_global.source_state[source_hdl]; + session = &source->session; + pp = &source->pdu_production; - sdus_skipped = 0U; - time_diff = 0U; + sdus_skipped = 0; /* Continue with the current payload unless there is need to change */ next_payload_number = pp->payload_number; actual_event = pp->payload_number / session->burst_number; - ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source_ctx, next_payload_number, - actual_event); + ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source, next_payload_number, actual_event); /* Get the drift updated group reference point for this event based on * the actual event being set. This might introduce some errors as the @@ -2301,35 +2259,29 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source } ISOAL_LOG_DBGV("[%p] Current PL=%llu Evt=%llu Ref=%lu", - source_ctx, next_payload_number, actual_event, actual_grp_ref_point); + source, next_payload_number, actual_event, actual_grp_ref_point); if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { /* Start of a new SDU */ - const bool time_stamp_is_valid = isoal_is_time_stamp_valid(source_ctx, - tx_sdu->cntr_time_stamp, - tx_sdu->time_stamp); - /* Adjust payload number */ if (pp->initialized) { /* Not the first SDU in this session, so reference * information should be valid. . */ - time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, tx_sdu->time_stamp, &time_diff); /* Priority is given to the sequence number */ if (tx_sdu->packet_sn > session->last_input_sn + 1) { - ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source_ctx); + ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source); sdus_skipped = (tx_sdu->packet_sn - session->last_input_sn) - 1; } else if (tx_sdu->packet_sn == session->last_input_sn && - time_diff_valid && time_diff > session->sdu_interval) { - ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", - source_ctx); + time_diff_valid && time_diff > session->sdu_interval) { + ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", source); /* Round at mid-point */ sdus_skipped = ((time_diff + (session->sdu_interval / 2)) / session->sdu_interval) - 1; @@ -2337,58 +2289,12 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source /* SDU is next in sequence */ } - if (time_stamp_is_valid) { - /* Use provided time stamp for time offset - * calcutation - */ - time_stamp_selected = tx_sdu->time_stamp; - ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from SDU", - source_ctx, time_stamp_selected); - } else if (time_diff_valid) { - /* Project a time stamp based on the last time - * stamp and the difference in input time stamps - */ - time_stamp_selected = isoal_get_wrapped_time_us( - session->tx_time_stamp, - time_diff - session->tx_time_offset); - ISOAL_LOG_DBGV("[%p] Projecting Time Stamp (%lu) from SDU delta", - source_ctx, time_stamp_selected); - } else { - /* Project a time stamp based on the last time - * stamp and the number of skipped SDUs - */ - time_stamp_selected = isoal_get_wrapped_time_us( - session->tx_time_stamp, - ((sdus_skipped + 1) * session->sdu_interval) - - session->tx_time_offset); - ISOAL_LOG_DBGV("[%p] Projecting Time Stamp (%lu) from skipped SDUs", - source_ctx, time_stamp_selected); - } - } else { /* First SDU, align with target event */ - if (actual_event < tx_sdu->target_event) { - actual_event = tx_sdu->target_event; - actual_grp_ref_point = tx_sdu->grp_ref_point; - } + actual_event = tx_sdu->target_event; + actual_grp_ref_point = tx_sdu->grp_ref_point; - ISOAL_LOG_DBGV("[%p] Use target_event", source_ctx); - - if (time_stamp_is_valid) { - /* Time stamp is within valid range - - * use provided time stamp - */ - time_stamp_selected = tx_sdu->time_stamp; - ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from SDU", - source_ctx, time_stamp_selected); - } else { - /* Time stamp is out of range - - * use controller's capture time - */ - time_stamp_selected = tx_sdu->cntr_time_stamp; - ISOAL_LOG_DBGV("[%p] Selecting Time Stamp (%lu) from controller", - source_ctx, time_stamp_selected); - } + ISOAL_LOG_DBGV("[%p] Use target_event", source); } /* Selecting the event for transmission is done solely based on @@ -2403,8 +2309,8 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source * 3.1 Time_Offset in framed PDUs : * The Time_Offset shall be a positive value. */ - while (!isoal_get_time_diff(time_stamp_selected, actual_grp_ref_point, &time_diff) - || time_diff == 0) { + while (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || + time_diff == 0) { /* Advance target to next event */ actual_event++; actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, @@ -2412,8 +2318,8 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source } ISOAL_LOG_DBGV("[%p] Chosen PL=%llu Evt=%llu Ref=%lu", - source_ctx, (actual_event * session->burst_number), actual_event, - actual_grp_ref_point); + source, (actual_event * session->burst_number), actual_event, + actual_grp_ref_point); /* If the event selected is the last event segmented for, then * it is possible that that some payloads have already been @@ -2421,23 +2327,23 @@ static uint16_t isoal_tx_framed_find_correct_tx_event(const struct isoal_source * that payload. */ next_payload_number = MAX(pp->payload_number, - (actual_event * session->burst_number)); + (actual_event * session->burst_number)); + } - ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", - source, actual_event, (actual_event * session->burst_number), - actual_grp_ref_point, next_payload_number); + ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", + source, actual_event, (actual_event * session->burst_number), + actual_grp_ref_point, next_payload_number); - /* Calculate the time offset */ - time_diff_valid = isoal_get_time_diff(time_stamp_selected, - actual_grp_ref_point, &time_diff); + /* Calculate the time offset */ + time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, + actual_grp_ref_point, &time_diff); - LL_ASSERT(time_diff_valid); - LL_ASSERT(time_diff > 0); - /* Time difference must be less than the maximum possible - * time-offset of 24-bits. - */ - LL_ASSERT(time_diff <= 0x00FFFFFF); - } + LL_ASSERT(time_diff_valid); + LL_ASSERT(time_diff > 0); + /* Time difference must be less than the maximum possible + * time-offset of 24-bits. + */ + LL_ASSERT(time_diff <= 0x00FFFFFF); *payload_number = next_payload_number; *grp_ref_point = actual_grp_ref_point; @@ -2483,24 +2389,19 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, tx_sdu->sdu_state == BT_ISO_SINGLE); ISOAL_LOG_DBGV("[%p] SDU %u len=%u TS=%lu Ref=%lu Evt=%llu Frag=%u", - source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, - tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); + source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, + tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { uint32_t actual_grp_ref_point; uint64_t next_payload_number; uint16_t sdus_skipped; - bool time_diff_valid; - uint32_t time_diff; /* Start of a new SDU */ - time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, - tx_sdu->time_stamp, - &time_diff); /* Find the best transmission event */ - sdus_skipped = isoal_tx_framed_find_correct_tx_event(source, tx_sdu, + sdus_skipped = isoal_tx_framed_find_correct_tx_event(source_hdl, tx_sdu, &next_payload_number, &actual_grp_ref_point, &time_offset); @@ -2559,22 +2460,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Update input packet number and time stamp */ session->last_input_sn = tx_sdu->packet_sn; - - if (pp->initialized && tx_sdu->time_stamp == tx_sdu->cntr_time_stamp && - (!time_diff_valid || time_diff < session->sdu_interval)) { - /* If the time-stamp is invalid or the difference is - * less than an SDU interval, then set the reference - * time stamp to what should have been received. This is - * done to avoid incorrectly detecting a gap in time - * stamp inputs should there be a burst of SDUs - * clustered together. - */ - session->last_input_time_stamp = isoal_get_wrapped_time_us( - session->last_input_time_stamp, - session->sdu_interval); - } else { - session->last_input_time_stamp = tx_sdu->time_stamp; - } + session->last_input_time_stamp = tx_sdu->time_stamp; } /* PDUs should be created until the SDU fragment has been fragmented or if diff --git a/subsys/bluetooth/controller/ll_sw/isoal.h b/subsys/bluetooth/controller/ll_sw/isoal.h index 61d3773c43d..cc69e4a5d53 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.h +++ b/subsys/bluetooth/controller/ll_sw/isoal.h @@ -189,8 +189,6 @@ struct isoal_sdu_tx { uint16_t iso_sdu_length; /** Time stamp from HCI or vendor specific path (us) */ uint32_t time_stamp; - /** Capture time stamp from controller (us) */ - uint32_t cntr_time_stamp; /** CIG Reference of target event (us, compensated for drift) */ uint32_t grp_ref_point; /** Target Event of SDU */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index 70d018e7e0c..1520bd76963 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -1058,8 +1058,7 @@ void ll_iso_transmit_test_send_sdu(uint16_t handle, uint32_t ticks_at_expire) /* Send all SDU fragments */ do { - sdu.cntr_time_stamp = HAL_TICKER_TICKS_TO_US(ticks_at_expire); - sdu.time_stamp = sdu.cntr_time_stamp; + sdu.time_stamp = HAL_TICKER_TICKS_TO_US(ticks_at_expire); sdu.size = MIN(remaining_tx, ISO_TEST_TX_BUFFER_SIZE); memset(tx_buffer, 0, sdu.size); From 9cada2eaff87d36b99722956875be07bd1d9c455 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:09 +0000 Subject: [PATCH 4220/4498] Revert "[nrf fromtree] Bluetooth: controller: corrected time-offset for endianness" This reverts commit 1fd74b1654859ac2f7c936a6b855667ef34184b2. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/isoal.c | 12 +++++------- subsys/bluetooth/controller/ll_sw/pdu.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 00bc40504f7..110a7aa901e 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -16,8 +16,6 @@ #include #include -#include - #include "util/memq.h" #include "hal/ccm.h" @@ -1160,7 +1158,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, case ISOAL_START: if (!sc) { /* Start segment, included time-offset */ - timeoffset = sys_le24_to_cpu(seg_hdr->timeoffset); + timeoffset = seg_hdr->timeoffset; anchorpoint = meta->timestamp; latency = session->sdu_sync_const; timestamp = isoal_get_wrapped_time_us(anchorpoint, @@ -1217,7 +1215,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, if (!sc) { /* Start segment, included time-offset */ - timeoffset = sys_le24_to_cpu(seg_hdr->timeoffset); + timeoffset = seg_hdr->timeoffset; anchorpoint = meta->timestamp; latency = session->sdu_sync_const; timestamp = isoal_get_wrapped_time_us(anchorpoint, @@ -1636,7 +1634,7 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, status = source_ctx->session.pdu_emit(node_tx, handle); ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", - source_ctx, payload_number, status, + source_ctx, node_tx->payload_count, status, produced_pdu->contents.pdu->len, sdu_fragments); if (status != ISOAL_STATUS_OK) { @@ -2481,7 +2479,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, */ err |= isoal_insert_seg_header_timeoffset(source, false, false, - sys_cpu_to_le24(time_offset)); + time_offset); pp->pdu_state = BT_ISO_CONT; } else if (!padding_pdu && pp->pdu_state == BT_ISO_CONT && pp->pdu_written == 0) { /* Continuing an SDU in a new PDU. Segmentation header @@ -2489,7 +2487,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, */ err |= isoal_insert_seg_header_timeoffset(source, true, false, - sys_cpu_to_le24(0)); + 0); } /* diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index 93e50e1ebcc..ceeb9ca12e7 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -1018,8 +1018,8 @@ struct pdu_iso_sdu_sh { uint8_t len; /* Note, timeoffset only available in first segment of sdu */ - uint32_t timeoffset:24; uint32_t payload:8; + uint32_t timeoffset:24; #endif /* CONFIG_LITTLE_ENDIAN */ } __packed; From af5da850bd2bfe5701cc7405a912361fbf977454 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:09 +0000 Subject: [PATCH 4221/4498] Revert "[nrf fromtree] Bluetooth: controller: Use consecutive event for framed TX and RX bugfix" This reverts commit 788c7ff8e63a7ddcd0e7c8850628c29f208e8937. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/isoal.c | 408 +++++++--------------- subsys/bluetooth/controller/ll_sw/isoal.h | 4 +- 2 files changed, 120 insertions(+), 292 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/isoal.c b/subsys/bluetooth/controller/ll_sw/isoal.c index 110a7aa901e..0a500cfd05e 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.c +++ b/subsys/bluetooth/controller/ll_sw/isoal.c @@ -50,11 +50,6 @@ LOG_MODULE_REGISTER(bt_ctlr_isoal, LOG_LEVEL_INF); (s == ISOAL_CONTINUE ? "CONTINUE" : \ (s == ISOAL_ERR_SPOOL ? "ERR SPOOL" : "???"))) -#define STATE_TO_STR(s) (s == BT_ISO_SINGLE ? "SINGLE" : \ - (s == BT_ISO_START ? "START" : \ - (s == BT_ISO_CONT ? "CONT" : \ - (s == BT_ISO_END ? "END" : "???")))) - #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) /* Given the minimum payload, this defines the minimum number of bytes that * should be remaining in a TX PDU such that it would make inserting a new @@ -191,7 +186,7 @@ static bool isoal_get_time_diff(uint32_t time_before, uint32_t time_after, uint3 #define SET_RX_SDU_TIMESTAMP(_sink, _timestamp, _value) \ _timestamp = _value; \ - ISOAL_LOG_DBGV("[%p] %s updated (%lu)", _sink, #_timestamp, _value); + ISOAL_LOG_DBGV("[%p] %s updated (%ld)", _sink, #_timestamp, _value); static void isoal_rx_framed_update_sdu_release(struct isoal_sink *sink); @@ -420,7 +415,7 @@ static isoal_status_t isoal_rx_allocate_sdu(struct isoal_sink *sink, ); if (err == ISOAL_STATUS_OK) { - sp->sdu_allocated = 1U; + sp->sdu_allocated = true; } /* Nothing has been written into buffer yet */ @@ -604,7 +599,7 @@ static isoal_status_t isoal_rx_try_emit_sdu(struct isoal_sink *sink, bool end_of sdu->status = sp->sdu_status; err = isoal_rx_buffered_emit_sdu(sink, end_of_sdu); - sp->sdu_allocated = 0U; + sp->sdu_allocated = false; if (end_of_sdu) { isoal_rx_framed_update_sdu_release(sink); @@ -734,9 +729,9 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, next_state = ISOAL_START; /* If status is not ISOAL_PDU_STATUS_VALID, length and LLID cannot be trusted */ - llid = pdu->ll_id; + llid = pdu_meta->pdu->ll_id; pdu_err = (pdu_meta->meta->status != ISOAL_PDU_STATUS_VALID); - length = pdu->len; + length = pdu_meta->pdu->len; /* A zero length PDU with LLID 0b01 (PDU_BIS_LLID_START_CONTINUE) would be a padding PDU. * However if there are errors in the PDU, it could be an incorrectly receive non-padding * PDU. Therefore only consider a PDU with errors as padding if received after the end @@ -942,7 +937,7 @@ static isoal_status_t isoal_rx_unframed_consume(struct isoal_sink *sink, sp->prev_pdu_is_end = !pdu_err && llid == PDU_BIS_LLID_COMPLETE_END; sp->prev_pdu_is_padding = !pdu_err && pdu_padding; - sp->initialized = 1U; + sp->initialized = true; return err; } @@ -1298,8 +1293,6 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } if (pdu_err || seq_err || seg_err) { - bool error_sdu_pending = false; - /* When one or more ISO Data PDUs are not received, the receiving device may * discard all SDUs affected by the missing PDUs. Any partially received SDU * may also be discarded. @@ -1328,28 +1321,14 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, switch (sp->fsm) { case ISOAL_START: - /* If errors occur while waiting for the start of an SDU - * then an SDU should should only be released if there - * is confirmation that a reception occurred - * unsuccessfully. In the case of STATUS_LOST_DATA which - * could result from a flush, an SDU should not be - * released as the flush does not necessarily mean that - * part of an SDU has been lost. In this case Lost SDU - * release defaults to the lost SDU detection based on - * the SDU interval. If we have a SDU to release - * following any lost SDUs, lost SDU handling should be - * similar to when a valid timestamp for the next SDU - * exists. + /* First release lost SDUs and then release a new SDU + * with errors. Since we have an SDU to release + * following any lost SDUs, lost SDUs handling should be + * similar to when a valid timestamp exists. */ - error_sdu_pending = seg_err || - (pdu_err && meta->status == ISOAL_SDU_STATUS_ERRORS); - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, - error_sdu_pending, timestamp); - - if (error_sdu_pending) { - sp->sdu_status = next_sdu_status; - err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); - } + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, true, timestamp); + sp->sdu_status = next_sdu_status; + err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); break; case ISOAL_CONTINUE: @@ -1360,13 +1339,11 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, */ sp->sdu_status = next_sdu_status; err |= isoal_rx_append_to_sdu(sink, pdu_meta, 0, 0, true, false); - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, - error_sdu_pending, timestamp); + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, false, timestamp); break; case ISOAL_ERR_SPOOL: - err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, - error_sdu_pending, timestamp); + err |= isoal_rx_framed_release_lost_sdus(sink, pdu_meta, false, timestamp); break; } @@ -1376,7 +1353,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink, } sp->prev_pdu_id = meta->payload_number; - sp->initialized = 1U; + sp->initialized = true; return err; } @@ -1633,10 +1610,6 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx, /* Attempt to enqueue the node towards the LL */ status = source_ctx->session.pdu_emit(node_tx, handle); - ISOAL_LOG_DBG("[%p] PDU %llu err=%X len=%u frags=%u released", - source_ctx, node_tx->payload_count, status, - produced_pdu->contents.pdu->len, sdu_fragments); - if (status != ISOAL_STATUS_OK) { /* If it fails, the node will be released and no further attempt * will be possible @@ -1693,7 +1666,6 @@ static isoal_status_t isoal_tx_allocate_pdu(struct isoal_source *source, /* Nothing has been written into buffer yet */ pp->pdu_written = 0; pp->pdu_available = available_len; - pp->pdu_allocated = 1U; LL_ASSERT(available_len > 0); pp->pdu_cnt++; @@ -1736,7 +1708,6 @@ static isoal_status_t isoal_tx_try_emit_pdu(struct isoal_source *source, pp->pdu_written); pp->payload_number++; pp->sdu_fragments = 0; - pp->pdu_allocated = 0U; } return err; @@ -1780,7 +1751,7 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ time_diff = 0; /* Adjust payload number */ - if (IS_ENABLED(CONFIG_BT_CTLR_ISOAL_SN_STRICT) && pp->initialized) { + if (IS_ENABLED(CONFIG_BT_CTLR_ISOAL_SN_STRICT) && session->sn) { /* Not the first SDU in this session, so reference * information should be valid. At this point, the * current payload number should be at the first PDU of @@ -1835,26 +1806,15 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ return sdus_skipped; } -/** - * @brief Fragment received SDU and produce unframed PDUs - * @details Destination source may have an already partially built PDU +/* NOTE: Use of target_event and grp_ref_point as input from upper layer. * - * @param source_hdl[in] Destination source handle - * @param tx_sdu[in] SDU with packet boundary information - * - * @return Status - * - * @note - * PSN in SDUs for unframed TX: - * - * @par + * For unframed: * Before the modification to use the PSN to decide the position of an SDU in a * stream of SDU, the target event was what was used in deciding the event for * each SDU. This meant that there would possibly have been skews on the - * receiver for each SDU and there were problems with LL/CIS/PER/BV-39-C which + * receiver for each SDU and we had trouble with LL/CIS/PER/BV-39-C which * expects clustering within an event. * - * @par * After the change, the PSN is used to decide the position of an SDU in the * stream anchored at the first PSN received. However for the first SDU * (assume that PSN=0), it will be the target event that decides which event @@ -1863,7 +1823,6 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * impacts the event chosen for the first SDU and all subsequent SDUs will be * decided relative to the first. * - * @par * The target event and related group reference point is still used to provide * the ISO-AL with a notion of time, for example when storing information * required for the TX Sync command. For example if for PSN 4, target event is @@ -1873,17 +1832,26 @@ uint16_t isoal_tx_unframed_get_next_payload_number(isoal_source_handle_t source_ * for event 7. It is also expected that this value is the latest reference and * is drift compensated. * - * @par - * The PSN alone is not sufficient for this because host and controller have no - * common reference time for when CIG / BIG event 0 starts. Therefore it is - * expected that it is possible to receive PSN 0 in event 2 for example. If the - * target event provided is event 3, then PSN 0 will be fragmented into payloads - * for event 3 and that will serve as the anchor for the stream and subsequent - * SDUs. If for example target event provided was event 2 instead, then it could - * very well be that PSN 0 might not be transmitted as is was received midway - * through event 2 and the payloads expired. If this happens then subsequent - * SDUs might also all be late for their transmission slots as they are - * positioned relative to PSN 0. + * The PSN alone is not sufficient for this because as far as I am aware, host + * and controller have no common reference time for when CIG/BIG event 0 starts. + * Therefore I would expect it is possible to receive PSN 0 in event 2 for + * example. If the target event provided is event 3, then PSN 0 will be + * fragmented into payloads for event 3 and that will serve as the anchor for + * the stream and subsequent SDUs. If for example target event provided was + * event 2 instead, then it could very well be that PSN 0 might not be + * transmitted as is was received midway through event 2 and the payloads + * expired. If this happens then subsequent SDUs might also all be late for + * their transmission slots as they are positioned relative to PSN 0. + */ + +/** + * @brief Fragment received SDU and produce unframed PDUs + * @details Destination source may have an already partially built PDU + * + * @param source_hdl[in] Destination source handle + * @param tx_sdu[in] SDU with packet boundary information + * + * @return Status */ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl, const struct isoal_sdu_tx *tx_sdu) @@ -1913,6 +1881,7 @@ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { + /* Initialize to info provided in SDU */ uint32_t actual_grp_ref_point; uint64_t next_payload_number; uint16_t sdus_skipped; @@ -2093,8 +2062,6 @@ static isoal_status_t isoal_tx_unframed_produce(isoal_source_handle_t source_hdl zero_length_sdu = false; } - pp->initialized = 1U; - return err; } @@ -2159,9 +2126,6 @@ static isoal_status_t isoal_insert_seg_header_timeoffset(struct isoal_source *so pp->pdu_written += write_size; pp->pdu_available -= write_size; - ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u TO=%u len=%u", - source, write_size, sc, cmplt, time_offset, seg_hdr.len); - return err; } @@ -2199,155 +2163,6 @@ static isoal_status_t isoal_update_seg_header_cmplt_length(struct isoal_source * pp->last_seg_hdr_loc, (uint8_t *) &seg_hdr, PDU_ISO_SEG_HDR_SIZE); - - ISOAL_LOG_DBGV("[%p] Seg header write size=%u sc=%u cmplt=%u len=%u", - source, PDU_ISO_SEG_HDR_SIZE, seg_hdr.sc, cmplt, seg_hdr.len); -} - -/** - * Find the earliest feasible event for transmission capacity is not wasted and - * return information based on that event. - * @param[in] source_hdl Destination source handle - * @param[in] tx_sdu SDU with meta data information - * @param[out] payload_number Updated payload number for the selected event - * @param[out] grp_ref_point Group reference point for the selected event - * @param[out] time_offset Segmentation Time offset to selected event - * @return The number SDUs skipped from the last - */ -static uint16_t isoal_tx_framed_find_correct_tx_event(isoal_source_handle_t source_hdl, - const struct isoal_sdu_tx *tx_sdu, - uint64_t *payload_number, - uint32_t *grp_ref_point, - uint32_t *time_offset) -{ - struct isoal_source_session *session; - struct isoal_pdu_production *pp; - uint32_t actual_grp_ref_point; - uint64_t next_payload_number; - struct isoal_source *source; - uint16_t sdus_skipped; - uint64_t actual_event; - bool time_diff_valid; - uint32_t time_diff; - - source = &isoal_global.source_state[source_hdl]; - session = &source->session; - pp = &source->pdu_production; - - sdus_skipped = 0; - - /* Continue with the current payload unless there is need to change */ - next_payload_number = pp->payload_number; - actual_event = pp->payload_number / session->burst_number; - - ISOAL_LOG_DBGV("[%p] Start PL=%llu Evt=%lu.", source, next_payload_number, actual_event); - - /* Get the drift updated group reference point for this event based on - * the actual event being set. This might introduce some errors as the - * group refernce point for future events could drift. However as the - * time offset calculation requires an absolute value, this seems to be - * the best candidate. - */ - if (actual_event != tx_sdu->target_event) { - actual_grp_ref_point = isoal_get_wrapped_time_us(tx_sdu->grp_ref_point, - ((actual_event - tx_sdu->target_event) * session->iso_interval * - ISO_INT_UNIT_US)); - } else { - actual_grp_ref_point = tx_sdu->grp_ref_point; - } - - ISOAL_LOG_DBGV("[%p] Current PL=%llu Evt=%llu Ref=%lu", - source, next_payload_number, actual_event, actual_grp_ref_point); - - if (tx_sdu->sdu_state == BT_ISO_START || - tx_sdu->sdu_state == BT_ISO_SINGLE) { - /* Start of a new SDU */ - - /* Adjust payload number */ - if (pp->initialized) { - /* Not the first SDU in this session, so reference - * information should be valid. . - */ - time_diff_valid = isoal_get_time_diff(session->last_input_time_stamp, - tx_sdu->time_stamp, - &time_diff); - - /* Priority is given to the sequence number */ - if (tx_sdu->packet_sn > session->last_input_sn + 1) { - ISOAL_LOG_DBGV("[%p] Using packet_sn for skipped SDUs", source); - sdus_skipped = (tx_sdu->packet_sn - session->last_input_sn) - 1; - - } else if (tx_sdu->packet_sn == session->last_input_sn && - time_diff_valid && time_diff > session->sdu_interval) { - ISOAL_LOG_DBGV("[%p] Using time_stamp for skipped SDUs", source); - /* Round at mid-point */ - sdus_skipped = ((time_diff + (session->sdu_interval / 2)) / - session->sdu_interval) - 1; - } else { - /* SDU is next in sequence */ - } - - } else { - /* First SDU, align with target event */ - actual_event = tx_sdu->target_event; - actual_grp_ref_point = tx_sdu->grp_ref_point; - - ISOAL_LOG_DBGV("[%p] Use target_event", source); - } - - /* Selecting the event for transmission is done solely based on - * the time stamp and the ability to calculate a valid time - * offset. - */ - - /* Check if time stamp on packet is later than the group - * reference point and find next feasible event for transmission. - * - * BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: - * 3.1 Time_Offset in framed PDUs : - * The Time_Offset shall be a positive value. - */ - while (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || - time_diff == 0) { - /* Advance target to next event */ - actual_event++; - actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, - session->iso_interval * ISO_INT_UNIT_US); - } - - ISOAL_LOG_DBGV("[%p] Chosen PL=%llu Evt=%llu Ref=%lu", - source, (actual_event * session->burst_number), actual_event, - actual_grp_ref_point); - - /* If the event selected is the last event segmented for, then - * it is possible that that some payloads have already been - * released for this event. Segmentation should continue from - * that payload. - */ - next_payload_number = MAX(pp->payload_number, - (actual_event * session->burst_number)); - } - - ISOAL_LOG_DBGV("[%p] Final Evt=%llu (PL=%llu) Ref.=%lu Next PL=%llu", - source, actual_event, (actual_event * session->burst_number), - actual_grp_ref_point, next_payload_number); - - /* Calculate the time offset */ - time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, - actual_grp_ref_point, &time_diff); - - LL_ASSERT(time_diff_valid); - LL_ASSERT(time_diff > 0); - /* Time difference must be less than the maximum possible - * time-offset of 24-bits. - */ - LL_ASSERT(time_diff <= 0x00FFFFFF); - - *payload_number = next_payload_number; - *grp_ref_point = actual_grp_ref_point; - *time_offset = time_diff; - - return sdus_skipped; } /** @@ -2371,6 +2186,7 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, bool zero_length_sdu; isoal_status_t err; bool padding_pdu; + uint8_t ll_id; source = &isoal_global.source_state[source_hdl]; session = &source->session; @@ -2386,53 +2202,15 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, zero_length_sdu = (packet_available == 0 && tx_sdu->sdu_state == BT_ISO_SINGLE); - ISOAL_LOG_DBGV("[%p] SDU %u len=%u TS=%lu Ref=%lu Evt=%llu Frag=%u", - source, tx_sdu->packet_sn, tx_sdu->iso_sdu_length, tx_sdu->time_stamp, - tx_sdu->grp_ref_point, tx_sdu->target_event, tx_sdu->sdu_state); - if (tx_sdu->sdu_state == BT_ISO_START || tx_sdu->sdu_state == BT_ISO_SINGLE) { - uint32_t actual_grp_ref_point; - uint64_t next_payload_number; - uint16_t sdus_skipped; - /* Start of a new SDU */ - /* Find the best transmission event */ - sdus_skipped = isoal_tx_framed_find_correct_tx_event(source_hdl, tx_sdu, - &next_payload_number, - &actual_grp_ref_point, - &time_offset); - - ISOAL_LOG_DBGV("[%p] %u SDUs skipped.", source, sdus_skipped); - ISOAL_LOG_DBGV("[%p] Starting SDU %u PL=(%llu->%llu) Grp Ref=%lu TO=%lu", - source, tx_sdu->packet_sn, pp->payload_number, next_payload_number, - actual_grp_ref_point, time_offset); - - - if (next_payload_number > pp->payload_number) { - /* Moving to a new payload */ - if (pp->pdu_allocated) { - /* Current PDU in production should be released before - * moving to new event. - */ - ISOAL_LOG_DBGV("[%p] Pending PDU released.\n"); - err |= isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); - } - - while (err == ISOAL_STATUS_OK && next_payload_number > pp->payload_number && - (pp->payload_number % session->burst_number)) { - /* Release padding PDUs for this event */ - err |= isoal_tx_allocate_pdu(source, tx_sdu); - err |= isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); - } - } - - /* Reset PDU production state */ - pp->pdu_state = BT_ISO_START; - - /* Update to new payload number */ - pp->payload_number = next_payload_number; + /* Initialize to info provided in SDU */ + uint32_t actual_grp_ref_point = tx_sdu->grp_ref_point; + uint64_t actual_event = tx_sdu->target_event; + bool time_diff_valid = false; + uint32_t time_diff = 0; /* Update sequence number for received SDU * @@ -2446,8 +2224,67 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, * with the sequence number in the ISOAL once the Datapath is * configured and the link is established. */ + session->sn++; - session->sn += sdus_skipped + 1; + /* Reset PDU production state */ + pp->pdu_state = BT_ISO_START; + + /* Update payload counter in case time has passed since the last + * SDU. This should mean that event count * burst number should + * be greater than the current payload number. In the event of + * an SDU interval smaller than the ISO interval, multiple SDUs + * will be sent in the same event. As such the current payload + * number should be retained. Payload numbers are indexed at 0 + * and valid until the PDU is emitted. + */ + pp->payload_number = MAX(pp->payload_number, + (tx_sdu->target_event * session->burst_number)); + + /* Get actual event for this payload number */ + actual_event = pp->payload_number / session->burst_number; + + /* Get group reference point for this PDU based on the actual + * event being set. This might introduce some errors as the + * group refernce point for future events could drift. However + * as the time offset calculation requires an absolute value, + * this seems to be the best candidate. + */ + if (actual_event > tx_sdu->target_event) { + actual_grp_ref_point = isoal_get_wrapped_time_us(tx_sdu->grp_ref_point, + ((actual_event - tx_sdu->target_event) * session->iso_interval * + ISO_INT_UNIT_US)); + } + + /* Check if time stamp on packet is later than the group + * reference point and adjust targets. This could happen if the + * SDU has been time-stampped at the controller when received + * via HCI. + * + * BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: + * 3.1 Time_Offset in framed PDUs : + * The Time_Offset shall be a positive value. + */ + if (!isoal_get_time_diff(tx_sdu->time_stamp, actual_grp_ref_point, &time_diff) || + time_diff == 0) { + /* Advance target to next event */ + actual_event++; + actual_grp_ref_point = isoal_get_wrapped_time_us(actual_grp_ref_point, + session->iso_interval * ISO_INT_UNIT_US); + + /* Set payload number */ + pp->payload_number = actual_event * session->burst_number; + } + + /* Calculate the time offset */ + time_diff_valid = isoal_get_time_diff(tx_sdu->time_stamp, + actual_grp_ref_point, &time_diff); + LL_ASSERT(time_diff_valid); + LL_ASSERT(time_diff > 0); + /* Time difference must be less than the maximum possible + * time-offset of 24-bits. + */ + LL_ASSERT(time_diff <= 0x00FFFFFF); + time_offset = time_diff; /* Store timing info for TX Sync command */ session->tx_time_stamp = actual_grp_ref_point; @@ -2455,10 +2292,6 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Reset PDU fragmentation count for this SDU */ pp->pdu_cnt = 0; - - /* Update input packet number and time stamp */ - session->last_input_sn = tx_sdu->packet_sn; - session->last_input_time_stamp = tx_sdu->time_stamp; } /* PDUs should be created until the SDU fragment has been fragmented or if @@ -2472,7 +2305,6 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, err |= err_alloc; - ISOAL_LOG_DBGV("[%p] State %s", source, STATE_TO_STR(pp->pdu_state)); if (pp->pdu_state == BT_ISO_START) { /* Start of a new SDU. Segmentation header and time-offset * should be inserted. @@ -2534,13 +2366,15 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, /* Update complete flag in last segmentation header */ err |= isoal_update_seg_header_cmplt_length(source, end_of_sdu, consume_len); + /* LLID is fixed for framed PDUs */ + ll_id = PDU_BIS_LLID_FRAMED; + /* If there isn't sufficient usable space then release the * PDU when the end of the SDU is reached, instead of waiting * for the next SDU. */ bool release_pdu = end_of_sdu && (pp->pdu_available <= ISOAL_TX_SEGMENT_MIN_SIZE); - const isoal_status_t err_emit = isoal_tx_try_emit_pdu(source, release_pdu, - PDU_BIS_LLID_FRAMED); + const isoal_status_t err_emit = isoal_tx_try_emit_pdu(source, release_pdu, ll_id); err |= err_emit; @@ -2558,8 +2392,6 @@ static isoal_status_t isoal_tx_framed_produce(isoal_source_handle_t source_hdl, zero_length_sdu = false; } - pp->initialized = 1U; - return err; } @@ -2592,9 +2424,9 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t first_event_payload = (session->burst_number * event_count); last_event_payload = (session->burst_number * (event_count + 1ULL)) - 1ULL; - if (pp->pdu_allocated && pp->payload_number <= last_event_payload) { + if (pp->pdu_available > 0 && + pp->payload_number <= last_event_payload) { /* Pending PDU that should be released for framed TX */ - ISOAL_LOG_DBGV("[%p] Prepare PDU released.", source); err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); } @@ -2630,7 +2462,6 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t if (release_padding) { while (!err && !err_alloc && (pp->payload_number < last_event_payload + 1ULL)) { - ISOAL_LOG_DBGV("[%p] Prepare padding PDU release.", source); err_alloc = isoal_tx_allocate_pdu(source, NULL); err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED); @@ -2642,7 +2473,6 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t if (pp->payload_number < last_event_payload + 1ULL) { pp->payload_number = last_event_payload + 1ULL; - ISOAL_LOG_DBGV("[%p] Prepare PL updated to %lu.", source, pp->payload_number); } return err; @@ -2670,7 +2500,7 @@ isoal_status_t isoal_tx_sdu_fragment(isoal_source_handle_t source_hdl, /* Set source context active to mutually exclude ISO Event prepare * kick. */ - source->context_active = 1U; + source->context_active = true; if (source->pdu_production.mode != ISOAL_PRODUCTION_MODE_DISABLED) { /* BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL: @@ -2690,12 +2520,11 @@ isoal_status_t isoal_tx_sdu_fragment(isoal_source_handle_t source_hdl, } } - source->context_active = 0U; + source->context_active = false; if (source->timeout_trigger) { - source->timeout_trigger = 0U; + source->timeout_trigger = false; if (session->framed) { - ISOAL_LOG_DBGV("[%p] Prepare cb flag trigger", source); isoal_tx_framed_event_prepare_handle(source_hdl, source->timeout_event_count); } @@ -2770,14 +2599,13 @@ void isoal_tx_event_prepare(isoal_source_handle_t source_hdl, * is active. */ source->timeout_event_count = event_count; - source->timeout_trigger = 1U; + source->timeout_trigger = true; if (source->context_active) { return; } - source->timeout_trigger = 0U; + source->timeout_trigger = false; if (session->framed) { - ISOAL_LOG_DBGV("[%p] Prepare call back", source); isoal_tx_framed_event_prepare_handle(source_hdl, event_count); } } diff --git a/subsys/bluetooth/controller/ll_sw/isoal.h b/subsys/bluetooth/controller/ll_sw/isoal.h index cc69e4a5d53..44f3504f1a6 100644 --- a/subsys/bluetooth/controller/ll_sw/isoal.h +++ b/subsys/bluetooth/controller/ll_sw/isoal.h @@ -376,6 +376,8 @@ struct isoal_source_session { uint8_t burst_number; uint8_t pdus_per_sdu; uint8_t max_pdu_size; + int32_t latency_unframed; + int32_t latency_framed; }; struct isoal_pdu_production { @@ -390,8 +392,6 @@ struct isoal_pdu_production { uint64_t seg_hdr_sc:1; uint64_t seg_hdr_length:8; uint64_t sdu_fragments:8; - uint64_t initialized:1; - uint64_t pdu_allocated:1; isoal_pdu_len_t pdu_written; isoal_pdu_len_t pdu_available; /* Location (byte index) of last segmentation header */ From b8d42f0f7be3a22acb6f511d9536c6fa2f5ee6d5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:10 +0000 Subject: [PATCH 4222/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use DIV_ROUND_UP macro in HAL ticker" This reverts commit f5d51232a709225b77d6a2e9bfe25213e74637d5. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h | 5 +++-- .../bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h | 5 +++-- .../controller/mock_ctrl/include/hal/ticker_vendor_hal.h | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 10d780a559c..cbb8ae6a8ce 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -38,8 +38,9 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index ab9b14207c1..78aa6362595 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -43,8 +43,9 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index 8cb4e791a30..c2b20050caa 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -37,8 +37,9 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ + ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ HAL_TICKER_CNTR_MASK \ ) From a6d5c8f1afafdf359e9d5c8705e278aedc1edcd4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:10 +0000 Subject: [PATCH 4223/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use defines for femto and pico seconds" This reverts commit fb5d216e14172be3d897607f7e0928459c3b0dd9. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 41 +++++++++---------- .../ll_sw/openisa/hal/RV32M1/ticker.h | 29 ++++++------- .../mock_ctrl/include/hal/ticker_vendor_hal.h | 29 ++++++------- 3 files changed, 45 insertions(+), 54 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index cbb8ae6a8ce..f179dbd0035 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -5,11 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL -#define HAL_TICKER_FSEC_PER_USEC 1000000000UL -#define HAL_TICKER_PSEC_PER_USEC 1000000UL -#define HAL_TICKER_FSEC_PER_PSEC 1000UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -28,8 +25,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -38,35 +35,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ - HAL_TICKER_FSEC_PER_USEC)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ + 1000000000UL)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ + ((uint64_t) (x) * 1000000000UL) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ + HAL_TICKER_CNTR_CLK_UNIT_FS) \ ) \ - / HAL_TICKER_FSEC_PER_PSEC \ + / 1000UL \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) + HAL_TICKER_TICKS_TO_US(1000000) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ @@ -77,24 +74,24 @@ static inline void hal_ticker_remove_jitter(uint32_t *ticks, uint32_t *remainder) { /* Is remainder less than 1 us */ - if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { + if ((*remainder & BIT(31)) || !(*remainder / 1000000UL)) { *ticks -= 1U; - *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; + *remainder += HAL_TICKER_CNTR_CLK_UNIT_FS / 1000UL; } /* pico seconds to micro seconds unit */ - *remainder /= HAL_TICKER_PSEC_PER_USEC; + *remainder /= 1000000UL; } /* Add ticks and return positive remainder value in microseconds */ static inline void hal_ticker_add_jitter(uint32_t *ticks, uint32_t *remainder) { /* Is remainder less than 1 us */ - if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { + if ((*remainder & BIT(31)) || !(*remainder / 1000000UL)) { *ticks += 1U; - *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; + *remainder += HAL_TICKER_CNTR_CLK_UNIT_FS / 1000UL; } /* pico seconds to micro seconds unit */ - *remainder /= HAL_TICKER_PSEC_PER_USEC; + *remainder /= 1000000UL; } diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index 78aa6362595..1f491739185 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -5,11 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL -#define HAL_TICKER_FSEC_PER_USEC 1000000000UL -#define HAL_TICKER_PSEC_PER_USEC 1000000UL -#define HAL_TICKER_FSEC_PER_PSEC 1000UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 2 @@ -33,8 +30,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -43,35 +40,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ - HAL_TICKER_FSEC_PER_USEC)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ + 1000000000UL)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ + ((uint64_t) (x) * 1000000000UL) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ + HAL_TICKER_CNTR_CLK_UNIT_FS) \ ) \ - / HAL_TICKER_FSEC_PER_PSEC \ + / 1000UL \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) + HAL_TICKER_TICKS_TO_US(1000000) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index c2b20050caa..67a46515033 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -4,11 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL -#define HAL_TICKER_FSEC_PER_USEC 1000000000UL -#define HAL_TICKER_PSEC_PER_USEC 1000000UL -#define HAL_TICKER_FSEC_PER_PSEC 1000UL +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U +#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -27,8 +24,8 @@ */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) @@ -37,35 +34,35 @@ */ #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ ( \ - ((uint32_t)(((((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) + \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ + ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ + HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ - HAL_TICKER_FSEC_PER_USEC)) \ + ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ + 1000000000UL)) \ ) /* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ - ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ + ((uint64_t) (x) * 1000000000UL) \ - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ + HAL_TICKER_CNTR_CLK_UNIT_FS) \ ) \ - / HAL_TICKER_FSEC_PER_PSEC \ + / 1000UL \ ) /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ #define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) + HAL_TICKER_TICKS_TO_US(1000000) /* Macro defining the margin for positioning re-scheduled nodes */ #define HAL_TICKER_RESCHEDULE_MARGIN \ From d3deb69671a100df9cfed8f42a7864c8407858bb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:10 +0000 Subject: [PATCH 4224/4498] Revert "[nrf fromtree] Bluetooth: Controller: Use HAL_TICKER_US_TO_TICKS_CEIL for ticks_slot" This reverts commit 4604cde52079bb44a3d2fcfd08c7362969cf3a40. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 11 ----------- .../controller/ll_sw/openisa/hal/RV32M1/ticker.h | 11 ----------- subsys/bluetooth/controller/ll_sw/ull_adv.c | 4 ++-- subsys/bluetooth/controller/ll_sw/ull_adv_aux.c | 6 +++--- subsys/bluetooth/controller/ll_sw/ull_adv_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_adv_sync.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_central.c | 11 +++++++---- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_conn.c | 10 ++++++---- subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 2 +- subsys/bluetooth/controller/ll_sw/ull_peripheral.c | 11 +++++++---- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 10 ++++++---- subsys/bluetooth/controller/ll_sw/ull_sched.c | 10 ++++------ subsys/bluetooth/controller/ll_sw/ull_sync.c | 10 ++++++---- subsys/bluetooth/controller/ll_sw/ull_sync_iso.c | 10 +++++----- .../mock_ctrl/include/hal/ticker_vendor_hal.h | 10 ---------- 16 files changed, 50 insertions(+), 72 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index f179dbd0035..315601ce203 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -30,17 +30,6 @@ HAL_TICKER_CNTR_MASK \ ) -/* Macro to translate microseconds to tick units. - * NOTE: This returns the ceil value. - */ -#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ - ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ - ) - /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index 1f491739185..e4d162eb9d2 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -35,17 +35,6 @@ HAL_TICKER_CNTR_MASK \ ) -/* Macro to translate microseconds to tick units. - * NOTE: This returns the ceil value. - */ -#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ - ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ - ) - /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ ( \ diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index d7d5b23f63e..3797acdc541 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -1251,7 +1251,7 @@ uint8_t ll_adv_enable(uint8_t enable) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); adv->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - adv->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + adv->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); ticks_slot_offset = MAX(adv->ull.ticks_active_to_start, adv->ull.ticks_prepare_to_start); @@ -2145,7 +2145,7 @@ uint8_t ull_adv_time_update(struct ll_adv_set *adv, struct pdu_adv *pdu, chan_map = lll->chan_map; chan_cnt = util_ones_count_get(&chan_map, sizeof(chan_map)); time_us = adv_time_get(pdu, pdu_scan, chan_cnt, phy, phy_flags); - time_ticks = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + time_ticks = HAL_TICKER_US_TO_TICKS(time_us); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) uint32_t volatile ret_cb; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c index 5349b21dd9f..907a69b05c7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_aux.c @@ -2454,7 +2454,7 @@ uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); aux->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) { ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start, @@ -2471,7 +2471,7 @@ uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux, #if defined(CONFIG_BT_CTLR_ADV_RESERVE_MAX) time_us = ull_adv_aux_time_get(aux, PDU_AC_PAYLOAD_SIZE_MAX, PDU_AC_PAYLOAD_SIZE_MAX); - ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); #else ticks_slot = aux->ull.ticks_slot; #endif @@ -2997,7 +2997,7 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu, uint32_t time_us; time_us = aux_time_min_get(aux); - time_ticks = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + time_ticks = HAL_TICKER_US_TO_TICKS(time_us); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) uint32_t volatile ret_cb; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 89e66ff99e5..765e911b208 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -977,7 +977,7 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); adv_iso->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - adv_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + adv_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); ticks_slot_offset = MAX(adv_iso->ull.ticks_active_to_start, adv_iso->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c index bbb1b351848..178116a54ec 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c @@ -1136,7 +1136,7 @@ uint32_t ull_adv_sync_evt_init(struct ll_adv_set *adv, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); ticks_slot_offset = MAX(sync->ull.ticks_active_to_start, sync->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index de14395f840..5effe2ae676 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -360,10 +360,13 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, #endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay_us + max_tx_time + EVENT_IFS_US + max_rx_time + - (EVENT_CLOCK_JITTER_US << 1)); + conn->ull.ticks_slot = + HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + + EVENT_OVERHEAD_END_US + + ready_delay_us + + max_tx_time + + EVENT_IFS_US + + max_rx_time); #if defined(CONFIG_BT_CTLR_PRIVACY) ull_filter_scan_update(filter_policy); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 2a19e03bde5..71b8d742a76 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -559,7 +559,7 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); cig->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Reset params cache */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index a8d3178e020..0b54a5dee79 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1257,10 +1257,12 @@ void ull_conn_done(struct node_rx_event_done *done) tx_time = PDU_DC_MAX_US(lll->dle.eff.max_tx_octets, 0); rx_time = PDU_DC_MAX_US(lll->dle.eff.max_rx_octets, 0); #endif /* CONFIG_BT_CTLR_PHY */ - ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay + EVENT_IFS_US + rx_time + tx_time + - (EVENT_CLOCK_JITTER_US << 1)); + ticks_slot = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + + ready_delay + + EVENT_IFS_US + + rx_time + + tx_time + + 4); if (ticks_slot > conn->ull.ticks_slot) { ticks_slot_plus = ticks_slot - conn->ull.ticks_slot; } else { diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 46c00c305fe..2ee5905b23b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -987,7 +987,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); cig->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us); + cig->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us); } ticks_slot_offset = MAX(cig->ull.ticks_active_to_start, diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index 8b813fda9fd..f1716c06573 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -371,10 +371,13 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); conn->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - conn->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US + - ready_delay_us + max_rx_time + EVENT_IFS_US + max_tx_time + - (EVENT_CLOCK_JITTER_US << 1)); + conn->ull.ticks_slot = + HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + + EVENT_OVERHEAD_END_US + + ready_delay_us + + max_rx_time + + EVENT_IFS_US + + max_tx_time); ticks_slot_offset = MAX(conn->ull.ticks_active_to_start, conn->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 316cec7fec7..26fc6d4806b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -666,10 +666,12 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); aux->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + ready_delay_us + - PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll_aux->phy) + - EVENT_OVERHEAD_END_US); + aux->ull.ticks_slot = + HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + + ready_delay_us + + PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, + lll_aux->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(aux->ull.ticks_active_to_start, aux->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index e7ca8a0358b..a445d986248 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -656,7 +656,7 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) time_us = ull_adv_aux_time_get(aux, PDU_AC_PAYLOAD_SIZE_MAX, PDU_AC_PAYLOAD_SIZE_MAX); - *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); } else { *ticks_slot = aux->ull.ticks_slot; @@ -686,7 +686,7 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) uint32_t time_us; time_us = ull_adv_sync_time_get(sync, PDU_AC_PAYLOAD_SIZE_MAX); - *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); } else { *ticks_slot = sync->ull.ticks_slot; } @@ -745,11 +745,9 @@ static struct ull_hdr *ull_hdr_get_cb(uint8_t ticker_id, uint32_t *ticks_slot) #endif /* !CONFIG_BT_CTLR_PHY_CODED */ time_us = EVENT_OVERHEAD_START_US + - EVENT_OVERHEAD_END_US + ready_delay_us + max_rx_time + - EVENT_IFS_US + max_tx_time + - (EVENT_CLOCK_JITTER_US << 1); - *ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us); + EVENT_IFS_US + max_tx_time; + *ticks_slot = HAL_TICKER_US_TO_TICKS(time_us); } else { *ticks_slot = conn->ull.ticks_slot; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 265475196fd..6c674885810 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -826,10 +826,12 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + ready_delay_us + - PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll->phy) + - EVENT_OVERHEAD_END_US); + sync->ull.ticks_slot = + HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US + + ready_delay_us + + PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, + lll->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(sync->ull.ticks_active_to_start, sync->ull.ticks_prepare_to_start); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index ff3327ce393..fbacb56f8b4 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -509,11 +509,11 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US); sync_iso->ull.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US); - sync_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL( - EVENT_OVERHEAD_START_US + ready_delay_us + - PDU_BIS_MAX_US(PDU_AC_EXT_PAYLOAD_SIZE_MAX, lll->enc, - lll->phy) + - EVENT_OVERHEAD_END_US); + sync_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS( + EVENT_OVERHEAD_START_US + ready_delay_us + + PDU_BIS_MAX_US(PDU_AC_EXT_PAYLOAD_SIZE_MAX, lll->enc, + lll->phy) + + EVENT_OVERHEAD_END_US); ticks_slot_offset = MAX(sync_iso->ull.ticks_active_to_start, sync_iso->ull.ticks_prepare_to_start); diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index 67a46515033..7c3792d848c 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -29,16 +29,6 @@ HAL_TICKER_CNTR_MASK \ ) -/* Macro to translate microseconds to tick units. - * NOTE: This returns the ceil value. - */ -#define HAL_TICKER_US_TO_TICKS_CEIL(x) \ - ( \ - ((uint32_t)(((((uint64_t) (x) * 1000000000UL) + \ - HAL_TICKER_CNTR_CLK_UNIT_FS - 1U)) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ - ) /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ From aedb3750e6f1a507b18b570caf67db8c000f0419 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:10 +0000 Subject: [PATCH 4225/4498] Revert "[nrf fromtree] Bluetooth: Controller: Make openisa and test hal ticker.h consistent" This reverts commit 1734da8febc892c0ad4231495b3425acd192668f. Signed-off-by: Dominik Ermel --- .../controller/ll_sw/nordic/hal/nrf5/ticker.h | 3 +- .../ll_sw/openisa/hal/RV32M1/ticker.h | 36 ++++---------- .../mock_ctrl/include/hal/ticker_vendor_hal.h | 49 ++++++------------- 3 files changed, 26 insertions(+), 62 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 315601ce203..5845d15145a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -26,8 +26,7 @@ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ + HAL_TICKER_CNTR_CLK_UNIT_FS)) & HAL_TICKER_CNTR_MASK \ ) /* Macro to translate tick units to microseconds. */ diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h index e4d162eb9d2..642ca1e608f 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/RV32M1/ticker.h @@ -6,53 +6,37 @@ */ #define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL -/* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 2 -/* Macro defining the max. counter update latency in ticks */ #define HAL_TICKER_CNTR_SET_LATENCY 1 - -/* Macro defines the h/w supported most significant bit */ -#define HAL_TICKER_CNTR_MSBIT 31 - -/* Macro defining the HW supported counter bits */ -#define HAL_TICKER_CNTR_MASK 0xFFFFFFFF - /* * When the LPTMR is enabled, the first increment will take an additional * one or two prescaler clock cycles due to synchronization logic. */ -/* Macro to translate microseconds to tick units. - * NOTE: This returns the floor value. - */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ - ) - -/* Macro to translate tick units to microseconds. */ -#define HAL_TICKER_TICKS_TO_US(x) \ - ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ - 1000000000UL)) \ + ((uint32_t)(((uint64_t) (x) * 1000000000UL) / 30517578125UL)) \ + & HAL_TICKER_CNTR_MASK \ ) -/* Macro returning remainder in picoseconds (to fit in 32-bits) */ #define HAL_TICKER_REMAINDER(x) \ ( \ ( \ ((uint64_t) (x) * 1000000000UL) \ - - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FS) \ + - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * 30517578125UL) \ ) \ / 1000UL \ ) +#define HAL_TICKER_TICKS_TO_US(x) \ + ((uint32_t)(((uint64_t)(x) * 30517578125UL) / 1000000000UL)) + +#define HAL_TICKER_CNTR_MSBIT 31 + +#define HAL_TICKER_CNTR_MASK 0xFFFFFFFF + /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ diff --git a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h index 7c3792d848c..bbd4b3e462c 100644 --- a/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h +++ b/tests/bluetooth/controller/mock_ctrl/include/hal/ticker_vendor_hal.h @@ -3,9 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ - #define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U -#define HAL_TICKER_CNTR_CLK_UNIT_FS 30517578125UL /* Macro defining the minimum counter compare offset */ #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 @@ -13,47 +11,30 @@ /* Macro defining the max. counter update latency in ticks */ #define HAL_TICKER_CNTR_SET_LATENCY 0 -/* Macro defines the h/w supported most significant bit */ -#define HAL_TICKER_CNTR_MSBIT 23 - -/* Macro defining the HW supported counter bits */ -#define HAL_TICKER_CNTR_MASK 0x00FFFFFF - /* Macro to translate microseconds to tick units. * NOTE: This returns the floor value. */ -#define HAL_TICKER_US_TO_TICKS(x) \ - ( \ - ((uint32_t)(((uint64_t) (x) * 1000000000UL) / \ - HAL_TICKER_CNTR_CLK_UNIT_FS)) & \ - HAL_TICKER_CNTR_MASK \ - ) +#define HAL_TICKER_US_TO_TICKS(x) \ + (((uint32_t)(((uint64_t)(x) * 1000000000UL) / 30517578125UL)) & HAL_TICKER_CNTR_MASK) +/* Macro returning remainder in nanoseconds */ +#define HAL_TICKER_REMAINDER(x) \ + ((((uint64_t)(x) * 1000000000UL) - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * 30517578125UL)) /\ + 1000UL) /* Macro to translate tick units to microseconds. */ -#define HAL_TICKER_TICKS_TO_US(x) \ - ( \ - ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FS) / \ - 1000000000UL)) \ - ) - -/* Macro returning remainder in picoseconds (to fit in 32-bits) */ -#define HAL_TICKER_REMAINDER(x) \ - ( \ - ( \ - ((uint64_t) (x) * 1000000000UL) \ - - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ - HAL_TICKER_CNTR_CLK_UNIT_FS) \ - ) \ - / 1000UL \ - ) +#define HAL_TICKER_TICKS_TO_US(x) ((uint32_t)(((uint64_t)(x) * 30517578125UL) / 1000000000UL)) + +/* Macro defines the h/w supported most significant bit */ +#define HAL_TICKER_CNTR_MSBIT 23 + +/* Macro defining the HW supported counter bits */ +#define HAL_TICKER_CNTR_MASK 0x00FFFFFF /* Macro defining the remainder resolution/range * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) */ -#define HAL_TICKER_REMAINDER_RANGE \ - HAL_TICKER_TICKS_TO_US(1000000) +#define HAL_TICKER_REMAINDER_RANGE HAL_TICKER_TICKS_TO_US(1000000) /* Macro defining the margin for positioning re-scheduled nodes */ -#define HAL_TICKER_RESCHEDULE_MARGIN \ - HAL_TICKER_US_TO_TICKS(150) +#define HAL_TICKER_RESCHEDULE_MARGIN HAL_TICKER_US_TO_TICKS(150) From c7a1b88d0216b8922c4575924ae5441d65766551 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:11 +0000 Subject: [PATCH 4226/4498] Revert "[nrf fromtree] Bluetooth: Controller: Revert EVENT_OVERHEAD_END_US to original value" This reverts commit 1845278ad53c15a557ca81895e9e5c89721d573b. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h index 7df39f65c8a..5ee063e4d53 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h @@ -42,7 +42,7 @@ /* Worst-case time margin needed after event end-time in the air * (done/preempt race margin + power-down/chain delay) */ -#define EVENT_OVERHEAD_END_US 40 +#define EVENT_OVERHEAD_END_US 100 /* Sleep Clock Accuracy */ #define EVENT_JITTER_US 16 From d7707e31d290a914527b83c1d10389186f893a9b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:11 +0000 Subject: [PATCH 4227/4498] Revert "[nrf fromtree] bluetooth: controller: coex: convert to DT device" This reverts commit 4259135d4de0b463e3b9e10ab03982d92321e8ca. Signed-off-by: Dominik Ermel --- samples/bluetooth/beacon/prj-coex.conf | 1 + subsys/bluetooth/controller/coex/Kconfig | 4 ++-- subsys/bluetooth/controller/coex/coex_ticker.c | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/samples/bluetooth/beacon/prj-coex.conf b/samples/bluetooth/beacon/prj-coex.conf index eb9cd4bb16e..b16487f3999 100644 --- a/samples/bluetooth/beacon/prj-coex.conf +++ b/samples/bluetooth/beacon/prj-coex.conf @@ -3,4 +3,5 @@ CONFIG_LOG=y CONFIG_BT_DEVICE_NAME="Test beacon" CONFIG_BT_LL_SW_SPLIT=y +CONFIG_BT_CTLR_COEX_DRIVERS=y CONFIG_BT_CTLR_COEX_TICKER=y diff --git a/subsys/bluetooth/controller/coex/Kconfig b/subsys/bluetooth/controller/coex/Kconfig index b7bc7d30681..31754fbf52c 100644 --- a/subsys/bluetooth/controller/coex/Kconfig +++ b/subsys/bluetooth/controller/coex/Kconfig @@ -5,8 +5,8 @@ menuconfig BT_CTLR_COEX_DRIVERS bool "Bluetooth Co-existence Drivers" - default y - depends on BT_CTLR && DT_HAS_GPIO_RADIO_COEX_ENABLED + default n + depends on BT_CTLR if BT_CTLR_COEX_DRIVERS diff --git a/subsys/bluetooth/controller/coex/coex_ticker.c b/subsys/bluetooth/controller/coex/coex_ticker.c index be349622ecd..229e2f9e125 100644 --- a/subsys/bluetooth/controller/coex/coex_ticker.c +++ b/subsys/bluetooth/controller/coex/coex_ticker.c @@ -4,13 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT gpio_radio_coex - #include #include #include #include +#include #include #include #include @@ -196,11 +195,18 @@ static int coex_ticker_init(const struct device *dev) return 0; } +#define RADIO_NODE DT_NODELABEL(radio) +#define COEX_NODE DT_PROP(RADIO_NODE, coex) + +#if DT_NODE_EXISTS(COEX_NODE) static struct coex_ticker_config config = { - .grant_spec = GPIO_DT_SPEC_INST_GET(0, grant_gpios), - .grant_delay_us = DT_INST_PROP(0, grant_delay_us) + .grant_spec = GPIO_DT_SPEC_GET(COEX_NODE, grant_gpios), + .grant_delay_us = DT_PROP(COEX_NODE, grant_delay_us) }; static struct coex_ticker_data data; -DEVICE_DT_INST_DEFINE(0, &coex_ticker_init, NULL, &data, &config, - POST_KERNEL, 90, NULL); +DEVICE_DEFINE(coex_ticker, "COEX_TICKER", &coex_ticker_init, NULL, + &data, &config, + APPLICATION, 90, + NULL); +#endif From 17aa8566f2592e9c1bae98bb55a5acb892923737 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:11 +0000 Subject: [PATCH 4228/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix missing lazy calculation for Central ISO" This reverts commit 1cd5c0c6039be61db9eb5e5f0c95586854fdec52. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/Kconfig.ll_sw_split | 2 +- subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 910c3819f0c..84db5fddb10 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -53,7 +53,7 @@ config BT_LLL_VENDOR_NORDIC (BT_OBSERVER && BT_CTLR_ADV_EXT) select BT_TICKER_REMAINDER if BT_CTLR_CENTRAL_ISO select BT_TICKER_REMAINDER_GET if BT_BROADCASTER && BT_CTLR_ADV_EXT - select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CENTRAL_ISO + select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC default y help diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index 2ee5905b23b..cc76c5219cb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -1042,8 +1042,8 @@ static void mfy_cis_lazy_fill(void *param) uint32_t ticks_to_expire; uint32_t ticks_current; uint32_t remainder; - uint16_t lazy = 0U; uint8_t ticker_id; + uint16_t lazy; uint8_t retry; uint8_t id; From cdf2c9133769087c35ddaa627f1e57a7599de5c5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:11 +0000 Subject: [PATCH 4229/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix initialization of lazy_active" This reverts commit f6496260fc1dc3e873cb55cce34ab1814df1a004. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_conn_iso.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index cc76c5219cb..8b79100d942 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -851,10 +851,6 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, */ if (cig->state == CIG_STATE_ACTIVE) { #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) - /* Initialize CIS event lazy at CIS create */ - cis->lll.lazy_active = 0U; - - /* Deferred fill CIS event lazy value at CIS create */ cis_lazy_fill(cis); #else /* CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Set CIS active in already active CIG */ @@ -1000,9 +996,6 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, } ticks_slot = cig->ull.ticks_slot + ticks_slot_overhead; - - /* Initialize CIS event lazy at CIS create */ - cis->lll.lazy_active = 0U; #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ /* Start CIS peripheral CIG ticker */ @@ -1021,6 +1014,11 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, /* Set CIG and the first CIS state as active */ cig->state = CIG_STATE_ACTIVE; cis->lll.active = 1U; + +#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + /* CIS event lazy at CIS create */ + cis->lll.lazy_active = 0U; +#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ } #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) From e3e0591f0c762fa0c9cfdc3d7cd1cf8079a4e382 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:11 +0000 Subject: [PATCH 4230/4498] Revert "[nrf fromtree] Bluetooth: Controller: Minor clean up of redundant initialization" This reverts commit f3560c3ff5a62f3c8a90ad03cb623c2dea3c9d04. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull_central_iso.c | 10 +++++++++- subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 71b8d742a76..49ab4909e3e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -690,6 +690,15 @@ void ll_cis_create(uint16_t cis_handle, uint16_t acl_handle) /* Initialize stream states */ cis->established = 0; cis->teardown = 0; + cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; + cis->lll.sn = 0; + cis->lll.nesn = 0; + cis->lll.cie = 0; + cis->lll.flush = LLL_CIS_FLUSH_NONE; + cis->lll.active = 0; + cis->lll.datapath_ready_rx = 0; + cis->lll.tx.bn_curr = 1U; + cis->lll.rx.bn_curr = 1U; (void)memset(&cis->hdr, 0U, sizeof(cis->hdr)); @@ -866,7 +875,6 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ cis->central.instant = instant; - cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.sn = 0U; cis->lll.nesn = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index d45d89aa009..5bbac2528d0 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -259,11 +259,15 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl, cis->lll.rx.bn = req->c_bn; cis->lll.rx.ft = req->c_ft; cis->lll.rx.max_pdu = sys_le16_to_cpu(req->c_max_pdu); + cis->lll.rx.payload_count = 0; + cis->lll.rx.bn_curr = 1U; cis->lll.tx.phy = req->p_phy; cis->lll.tx.bn = req->p_bn; cis->lll.tx.ft = req->p_ft; cis->lll.tx.max_pdu = sys_le16_to_cpu(req->p_max_pdu); + cis->lll.tx.payload_count = 0; + cis->lll.tx.bn_curr = 1U; if (!cis->lll.link_tx_free) { cis->lll.link_tx_free = &cis->lll.link_tx; From 085a49d0479698b460d56dd9a16ad82094b044fd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:12 +0000 Subject: [PATCH 4231/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix some compiler instruction re-ordering" This reverts commit f98dcccd9c67ed0c9c8e8d03e6b5fa795489ebce. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ticker/ticker.c | 1 - subsys/bluetooth/controller/util/mayfly.c | 7 ------- 2 files changed, 8 deletions(-) diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index ead148e85ba..679467d148c 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -3149,7 +3149,6 @@ void ticker_job(void *param) instance->job_guard = 0U; /* trigger worker if deferred */ - cpu_dmb(); if (instance->worker_trigger || compare_trigger) { instance->sched_cb(TICKER_CALL_ID_JOB, TICKER_CALL_ID_WORKER, 1, instance); diff --git a/subsys/bluetooth/controller/util/mayfly.c b/subsys/bluetooth/controller/util/mayfly.c index d45569c6a35..e8de3acfd80 100644 --- a/subsys/bluetooth/controller/util/mayfly.c +++ b/subsys/bluetooth/controller/util/mayfly.c @@ -6,13 +6,8 @@ */ #include - -#include #include #include - -#include "hal/cpu.h" - #include "memq.h" #include "mayfly.h" @@ -159,12 +154,10 @@ static void dequeue(uint8_t callee_id, uint8_t caller_id, memq_link_t *link, m->_link = link; /* reset mayfly state to idle */ - cpu_dmb(); ack = m->_ack; m->_ack = req; /* re-insert, if re-pended by interrupt */ - cpu_dmb(); if (((m->_req - ack) & 0x03) == 1U) { #if defined(MAYFLY_UT) printk("%s: RACE\n", __func__); From 6cc10e49b37dda5a89a83319cab82ad1804108c1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:12 +0000 Subject: [PATCH 4232/4498] Revert "[nrf fromtree] Bluetooth: Controller: Nordic LLL: Use HAL to clear EVENTs" This reverts commit e0313b730459f788f15f9e8745f90404ccad1f28. Signed-off-by: Dominik Ermel --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 1875dca7896..7b72b1a4b93 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -568,18 +568,18 @@ void radio_status_reset(void) * register value, PPI task will be triggered. Hence, other * EVENT_* registers are not reset to save code and CPU time. */ - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END); + NRF_RADIO->EVENTS_READY = 0; + NRF_RADIO->EVENTS_END = 0; #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST) /* Clear it only for SoCs supporting DF extension */ - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT); - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); + NRF_RADIO->EVENTS_PHYEND = 0; + NRF_RADIO->EVENTS_CTEPRESENT = 0; + NRF_RADIO->EVENTS_BCMATCH = 0; #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */ - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); + NRF_RADIO->EVENTS_DISABLED = 0; #if defined(CONFIG_BT_CTLR_PHY_CODED) #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST); + NRF_RADIO->EVENTS_RATEBOOST = 0; #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ #endif /* CONFIG_BT_CTLR_PHY_CODED */ } @@ -1019,7 +1019,7 @@ uint32_t radio_rssi_get(void) void radio_rssi_status_reset(void) { - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); + NRF_RADIO->EVENTS_RSSIEND = 0; } uint32_t radio_rssi_is_ready(void) @@ -1051,7 +1051,7 @@ void radio_filter_disable(void) void radio_filter_status_reset(void) { - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH); + NRF_RADIO->EVENTS_DEVMATCH = 0; } uint32_t radio_filter_has_match(void) @@ -1072,7 +1072,7 @@ void radio_bc_configure(uint32_t n) void radio_bc_status_reset(void) { - nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); + NRF_RADIO->EVENTS_BCMATCH = 0; } uint32_t radio_bc_has_match(void) @@ -1356,7 +1356,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) start_us = (now_us << 1) - start_us; /* Setup compare event with min. 1 us offset */ - nrf_timer_event_clear(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0); + EVENT_TIMER->EVENTS_COMPARE[0] = 0U; nrf_timer_cc_set(EVENT_TIMER, 0, start_us + 1U); /* Capture the current time */ @@ -1749,9 +1749,9 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->OUTPTR = (uint32_t)pkt; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = 0; - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDCRYPT); - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); + NRF_CCM->EVENTS_ENDKSGEN = 0; + NRF_CCM->EVENTS_ENDCRYPT = 0; + NRF_CCM->EVENTS_ERROR = 0; nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); @@ -1820,9 +1820,9 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDCRYPT); - nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); + NRF_CCM->EVENTS_ENDKSGEN = 0; + NRF_CCM->EVENTS_ENDCRYPT = 0; + NRF_CCM->EVENTS_ERROR = 0; nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); @@ -1899,9 +1899,9 @@ void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags) NRF_AAR->ADDRPTR = addrptr; NRF_AAR->SCRATCHPTR = (uint32_t)&_aar_scratch[0]; - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END); - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED); - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED); + NRF_AAR->EVENTS_END = 0; + NRF_AAR->EVENTS_RESOLVED = 0; + NRF_AAR->EVENTS_NOTRESOLVED = 0; radio_bc_configure(bcc); radio_bc_status_reset(); @@ -1957,9 +1957,9 @@ uint8_t radio_ar_resolve(const uint8_t *addr) NRF_AAR->ADDRPTR = (uint32_t)addr - 3; - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END); - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED); - nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED); + NRF_AAR->EVENTS_END = 0; + NRF_AAR->EVENTS_RESOLVED = 0; + NRF_AAR->EVENTS_NOTRESOLVED = 0; NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR)); From 333f27be4189911c038148bced6c3a54c2343589 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:12 +0000 Subject: [PATCH 4233/4498] Revert "[nrf fromtree] Bluetooth: Controller: Nordic LLL: Use HAL to clear RTC event" This reverts commit c5545cd918742435c48186f39e70fe806a037c0d. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 1f8031a7c07..bc71bbcd5a6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -8,8 +8,6 @@ #include #include -#include - #include #include @@ -108,7 +106,7 @@ static void rtc0_nrf5_isr(const void *arg) /* On compare0 run ticker worker instance0 */ if (NRF_RTC0->EVENTS_COMPARE[0]) { - nrf_rtc_event_clear(NRF_RTC0, NRF_RTC_EVENT_COMPARE_0); + NRF_RTC0->EVENTS_COMPARE[0] = 0; ticker_trigger(0); } From 2f267a736ebb5be0cba1b84b9dcc4f6a9fddb3b7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:12 +0000 Subject: [PATCH 4234/4498] Revert "[nrf fromtree] Bluetooth: controller: Introduce config for avoiding SDU fragmentation" This reverts commit 78ec3b1294a711606b8302f3f95eef0a7095cb51. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/Kconfig | 11 ---- .../controller/ll_sw/ull_central_iso.c | 59 +++++-------------- 2 files changed, 14 insertions(+), 56 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 599a241b84b..0818ae03a3b 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -914,17 +914,6 @@ config BT_CTLR_CONN_ISO_STREAMS_MAX_FT help Maximum number of CIS flush timeout events. -config BT_CTLR_CONN_ISO_AVOID_SEGMENTATION - bool "Avoid SDU fragmentation for framed mode" - depends on BT_CTLR_CENTRAL_ISO - help - When creating a CIG, the Max_PDU size is calculated according to BT - Core 5.4 Vol 6, Part G, Section 2.2. However, HAP specifies a need for - avoiding segmentation by forcing the Max_PDU to the appropriate value. - Since there is no way to control the Max_PDU using the non-test - interface, the config provides a way to force the Max_PDU to Max_SDU + - 5 (header + offset). - config BT_CTLR_ISO bool default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index 49ab4909e3e..0c7a8e5ef35 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -234,15 +234,6 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles) cig->iso_interval = BT_HCI_ISO_INTERVAL_MIN; } -#if defined(CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION) - /* Check if this is a HAP usecase which requires higher link bandwidth to ensure - * segmentation is not invoked in ISO-AL. - */ - if (cig->central.framing && cig->c_sdu_interval == 10000U) { - cig->iso_interval = 6; /* 7500 us */ - } -#endif - if (!cig->central.framing && (cig->c_sdu_interval % ISO_INT_UNIT_US)) { /* Framing not requested but requirement for unframed is not met. Force * CIG into framed mode. @@ -1140,51 +1131,29 @@ static void set_bn_max_pdu(bool framed, uint32_t iso_interval, uint8_t *max_pdu) { if (framed) { - uint32_t max_drift_us; + uint32_t ceil_f_x_max_sdu; + uint16_t max_pdu_bn1; + uint32_t max_drift; uint32_t ceil_f; - /* BT Core 5.4 Vol 6, Part G, Section 2.2: + /* Framed (From ES-18002): * Max_PDU >= ((ceil(F) x 5 + ceil(F x Max_SDU)) / BN) + 2 * F = (1 + MaxDrift) x ISO_Interval / SDU_Interval * SegmentationHeader + TimeOffset = 5 bytes * Continuation header = 2 bytes * MaxDrift (Max. allowed SDU delivery timing drift) = 100 ppm */ - max_drift_us = DIV_ROUND_UP(SDU_MAX_DRIFT_PPM * sdu_interval, USEC_PER_SEC); - ceil_f = DIV_ROUND_UP((USEC_PER_SEC + max_drift_us) * (uint64_t)iso_interval, - USEC_PER_SEC * (uint64_t)sdu_interval); - if (false) { -#if defined(CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION) - /* To avoid segmentation according to HAP, if the ISO_Interval is less than - * the SDU_Interval, we assume BN=1 and calculate the Max_PDU as: - * Max_PDU = celi(F / BN) x (5 / Max_SDU) - * - * This is in accordance with the "Core enhancement for ISOAL CR". - * - * This ensures that the drift can be contained in the difference between - * SDU_Interval and link bandwidth. For BN=1, ceil(F) == ceil(F/BN). - */ - } else if (iso_interval < sdu_interval) { - *bn = 1; - *max_pdu = ceil_f * (PDU_ISO_SEG_HDR_SIZE + PDU_ISO_SEG_TIMEOFFSET_SIZE + - max_sdu); -#endif - } else { - uint32_t ceil_f_x_max_sdu; - uint16_t max_pdu_bn1; - - ceil_f_x_max_sdu = DIV_ROUND_UP(max_sdu * ((USEC_PER_SEC + max_drift_us) * - (uint64_t)iso_interval), - USEC_PER_SEC * (uint64_t)sdu_interval); + max_drift = DIV_ROUND_UP(SDU_MAX_DRIFT_PPM * sdu_interval, 1000000U); + ceil_f = DIV_ROUND_UP(iso_interval + max_drift, sdu_interval); + ceil_f_x_max_sdu = DIV_ROUND_UP(max_sdu * (iso_interval + max_drift), + sdu_interval); - /* Strategy: Keep lowest possible BN. - * TODO: Implement other strategies, possibly as policies. - */ - max_pdu_bn1 = ceil_f * (PDU_ISO_SEG_HDR_SIZE + - PDU_ISO_SEG_TIMEOFFSET_SIZE) + ceil_f_x_max_sdu; - *bn = DIV_ROUND_UP(max_pdu_bn1, LL_CIS_OCTETS_TX_MAX); - *max_pdu = DIV_ROUND_UP(max_pdu_bn1, *bn) + PDU_ISO_SEG_HDR_SIZE; - } + /* Strategy: Keep lowest possible BN. + * TODO: Implement other strategies, possibly as policies. + */ + max_pdu_bn1 = ceil_f * 5 + ceil_f_x_max_sdu; + *bn = DIV_ROUND_UP(max_pdu_bn1, LL_CIS_OCTETS_TX_MAX); + *max_pdu = DIV_ROUND_UP(max_pdu_bn1, *bn) + 2; } else { /* For unframed, ISO_Interval must be N x SDU_Interval */ LL_ASSERT(iso_interval % sdu_interval == 0); From f476efa5d5119a44cc44811a6ea2a7629d380410 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:13 +0000 Subject: [PATCH 4235/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Reset targets state before starting DFU on DFD srv" This reverts commit 7baae6c87ada53b681730c226d58a37a8ed6c382. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 5d3ada4b4aa..59fe5b830d1 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -1015,13 +1015,6 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv, sys_slist_init(&srv->inputs.targets); for (i = 0; i < srv->target_cnt; i++) { - uint16_t addr = srv->targets[i].blob.addr; - - memset(&srv->targets[i].blob, 0, sizeof(struct bt_mesh_blob_target)); - memset(&srv->pull_ctxs[i], 0, sizeof(struct bt_mesh_blob_target_pull)); - srv->targets[i].blob.addr = addr; - srv->targets[i].blob.pull = &srv->pull_ctxs[i]; - sys_slist_append(&srv->inputs.targets, &srv->targets[i].blob.n); } From e46bbca13848e34559e848ff91bc650599578375 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:13 +0000 Subject: [PATCH 4236/4498] Revert "[nrf fromtree] Bluetooth: mesh: access: Fix model relation register" This reverts commit 0a1f19bfdc8b030f67b8b2ac0c499dc06d2d64d1. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/access.c | 92 +++++++++++++--------------------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 63c4f76c392..2ea7ece90df 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -91,13 +91,17 @@ static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE]; mod_rel_list[(idx)].idx_ext == 0); \ (idx)++) -#define IS_MOD_BASE(mod, idx, offset) \ +#define IS_MOD_BASE(mod, idx) \ (mod_rel_list[(idx)].elem_base == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_base == (mod)->mod_idx + (offset)) + mod_rel_list[(idx)].idx_base == (mod)->mod_idx && \ + !(mod_rel_list[(idx)].elem_ext != (mod)->elem_idx && \ + mod_rel_list[(idx)].idx_ext != (mod)->mod_idx)) -#define IS_MOD_EXTENSION(mod, idx, offset) \ +#define IS_MOD_EXTENSION(mod, idx) \ (mod_rel_list[(idx)].elem_ext == (mod)->elem_idx && \ - mod_rel_list[(idx)].idx_ext == (mod)->mod_idx + (offset)) + mod_rel_list[(idx)].idx_ext == (mod)->mod_idx && \ + !(mod_rel_list[(idx)].elem_base != (mod)->elem_idx && \ + mod_rel_list[(idx)].idx_base != (mod)->mod_idx)) #define RELATION_TYPE_EXT 0xFF @@ -452,14 +456,14 @@ int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset) return 0; } -static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset, uint8_t sig_offset) +static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset) { int i; uint8_t extensions = 0; int8_t offset, offset_record = 0; MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i, sig_offset) && + if (IS_MOD_EXTENSION(mod, i) && mod_rel_list[i].type == RELATION_TYPE_EXT) { extensions++; offset = mod_rel_list[i].elem_ext - @@ -476,18 +480,17 @@ static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset, uin return extensions; } -static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t sig_offset) +static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id) { int i; - MOD_REL_LIST_FOR_EACH(i) - { - if ((IS_MOD_BASE(mod, i, sig_offset) || - IS_MOD_EXTENSION(mod, i, sig_offset)) && + MOD_REL_LIST_FOR_EACH(i) { + if ((IS_MOD_BASE(mod, i) || IS_MOD_EXTENSION(mod, i)) && mod_rel_list[i].type < RELATION_TYPE_EXT) { if (cor_id) { memcpy(cor_id, &mod_rel_list[i].type, sizeof(uint8_t)); } + return true; } } @@ -495,15 +498,15 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t s } static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t *mod_cnt, - struct net_buf_simple *buf, size_t *offset, uint8_t sig_offset) + struct net_buf_simple *buf, size_t *offset) { uint8_t ext_mod_cnt; bool cor_present; uint8_t mod_elem_info = 0; int8_t max_offset; - ext_mod_cnt = count_mod_ext(mod, &max_offset, sig_offset); - cor_present = is_cor_present(mod, cor_id, sig_offset); + ext_mod_cnt = count_mod_ext(mod, &max_offset); + cor_present = is_cor_present(mod, cor_id); mod_elem_info = ext_mod_cnt << 2; if (ext_mod_cnt > 31 || @@ -523,14 +526,13 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, u } static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod, - uint8_t ext_mod_cnt, size_t *offset, uint8_t sig_offset) + uint8_t ext_mod_cnt, size_t *offset) { int i, elem_offset; uint8_t mod_idx; MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i, sig_offset) && - mod_rel_list[i].type == RELATION_TYPE_EXT) { + if (IS_MOD_EXTENSION(mod, i)) { elem_offset = mod->elem_idx - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && @@ -555,18 +557,18 @@ static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model * } } -static size_t mod_items_size(struct bt_mesh_model *mod, uint8_t sig_offset) +static size_t mod_items_size(struct bt_mesh_model *mod) { int i, offset; size_t temp_size = 0; - int ext_mod_cnt = count_mod_ext(mod, NULL, sig_offset); + int ext_mod_cnt = count_mod_ext(mod, NULL); if (!ext_mod_cnt) { return 0; } MOD_REL_LIST_FOR_EACH(i) { - if (IS_MOD_EXTENSION(mod, i, sig_offset)) { + if (IS_MOD_EXTENSION(mod, i)) { offset = mod->elem_idx - mod_rel_list[i].elem_base; temp_size += (ext_mod_cnt < 32 && offset < 4 && offset > -5) ? 1 : 2; } @@ -580,13 +582,13 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) size_t temp_size = 2; for (int i = 0; i < elem->model_count; i++) { - temp_size += is_cor_present(&elem->models[i], NULL, 0) ? 2 : 1; - temp_size += mod_items_size(&elem->models[i], 0); + temp_size += is_cor_present(&elem->models[i], NULL) ? 2 : 1; + temp_size += mod_items_size(&elem->models[i]); } for (int i = 0; i < elem->vnd_model_count; i++) { - temp_size += is_cor_present(&elem->vnd_models[i], NULL, elem->model_count) ? 2 : 1; - temp_size += mod_items_size(&elem->vnd_models[i], elem->model_count); + temp_size += is_cor_present(&elem->vnd_models[i], NULL) ? 2 : 1; + temp_size += mod_items_size(&elem->vnd_models[i]); } return temp_size; @@ -628,22 +630,19 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse data_buf_add_u8_offset(buf, comp->elem[i].vnd_model_count, &offset); for (j = 0; j < comp->elem[i].model_count; j++) { prep_model_item_header(&comp->elem[i].models[j], &cor_id, &ext_mod_cnt, buf, - &offset, 0); + &offset); if (ext_mod_cnt != 0) { add_items_to_page(buf, &comp->elem[i].models[j], ext_mod_cnt, - &offset, - 0); + &offset); } } for (j = 0; j < comp->elem[i].vnd_model_count; j++) { prep_model_item_header(&comp->elem[i].vnd_models[j], &cor_id, &ext_mod_cnt, - buf, &offset, - comp->elem[i].model_count); + buf, &offset); if (ext_mod_cnt != 0) { add_items_to_page(buf, &comp->elem[i].vnd_models[j], ext_mod_cnt, - &offset, - comp->elem[i].model_count); + &offset); } } } @@ -1617,22 +1616,6 @@ void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, } #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS -/* For vendor models, determine the offset within the model relation list - * by counting the number of standard SIG models in the associated element. - */ -static uint8_t get_sig_offset(struct bt_mesh_model *mod) -{ - const struct bt_mesh_elem *elem = bt_mesh_model_elem(mod); - uint8_t i; - - for (i = 0U; i < elem->vnd_model_count; i++) { - if (&elem->vnd_models[i] == mod) { - return elem->model_count; - } - } - return 0; -} - static int mod_rel_register(struct bt_mesh_model *base, struct bt_mesh_model *ext, uint8_t type) @@ -1640,9 +1623,9 @@ static int mod_rel_register(struct bt_mesh_model *base, LOG_DBG(""); struct mod_relation extension = { base->elem_idx, - base->mod_idx + get_sig_offset(base), + base->mod_idx, ext->elem_idx, - ext->mod_idx + get_sig_offset(ext), + ext->mod_idx, type, }; int i; @@ -1713,19 +1696,16 @@ int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod, return -ENOTSUP; } - uint8_t base_offset = get_sig_offset(base_mod); - uint8_t corresponding_offset = get_sig_offset(corresponding_mod); - MOD_REL_LIST_FOR_EACH(i) { if (mod_rel_list[i].type < RELATION_TYPE_EXT && mod_rel_list[i].type > cor_id) { cor_id = mod_rel_list[i].type; } - if ((IS_MOD_BASE(base_mod, i, base_offset) || - IS_MOD_EXTENSION(base_mod, i, base_offset) || - IS_MOD_BASE(corresponding_mod, i, corresponding_offset) || - IS_MOD_EXTENSION(corresponding_mod, i, corresponding_offset)) && + if ((IS_MOD_BASE(base_mod, i) || + IS_MOD_EXTENSION(base_mod, i) || + IS_MOD_BASE(corresponding_mod, i) || + IS_MOD_EXTENSION(corresponding_mod, i)) && mod_rel_list[i].type < RELATION_TYPE_EXT) { return mod_rel_register(base_mod, corresponding_mod, mod_rel_list[i].type); } From 7c5279307360c2f5c3b7a432ff916ce65ebb487f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:13 +0000 Subject: [PATCH 4237/4498] Revert "[nrf fromtree] Bluetooth: mesh: Change cfg_cli buffer length check" This reverts commit 3aa391df864261dbb6c527265634dfdb02682ccd. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index c9f4f98f39d..68af4fae59d 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -2320,7 +2320,7 @@ struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_el struct bt_mesh_comp_p1_elem *bt_mesh_comp_p1_elem_pull(struct net_buf_simple *buf, struct bt_mesh_comp_p1_elem *elem) { - if (buf->len < 4) { + if (buf->len < 6) { LOG_DBG("No more elements to pull or missing data"); return NULL; } From f3304473f9cc245d6decfd5d2193c131fab19661 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:13 +0000 Subject: [PATCH 4238/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Fix prov ctx init in PTS tests" This reverts commit 2da2829689578d541ec3cd43e4e35a6644d385b5. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 -- tests/bluetooth/tester/src/btp_mesh.c | 13 ------------- 2 files changed, 15 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index b5ab169b263..c2636d1445d 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -1038,8 +1038,6 @@ struct btp_proxy_solicit_cmd { uint16_t net_idx; } __packed; -#define BTP_MESH_START 0x78 - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 662dca238c1..c191ed54568 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1305,14 +1305,6 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - return BTP_STATUS_SUCCESS; -} - -static uint8_t start(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - int err; - LOG_DBG(""); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { @@ -4969,11 +4961,6 @@ static const struct btp_handler handlers[] = { .func = proxy_solicit }, #endif - { - .opcode = BTP_MESH_START, - .expect_len = 0, - .func = start - }, }; From 32925c686319dea78806e8fdb28675a6ba64492a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:14 +0000 Subject: [PATCH 4239/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Don't reset mod pointer" This reverts commit 598c6d18cfb77ca4aa47e8699e830a1dce1cea05. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/rpr_srv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index 8fb28e56472..c8639d8b514 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -1337,6 +1337,7 @@ static void rpr_srv_reset(struct bt_mesh_model *mod) atomic_clear(srv.flags); srv.link.dev = NULL; srv.scan.dev = NULL; + srv.mod = NULL; } const struct bt_mesh_model_cb _bt_mesh_rpr_srv_cb = { From b5cdabfb1132b9c925eb76f8d92054155ce76f69 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:14 +0000 Subject: [PATCH 4240/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Common comp page parse func" This reverts commit 688605c9b2174c0086e86c235b0377d54ff0b09a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/access.c | 27 --------------------- subsys/bluetooth/mesh/access.h | 1 - subsys/bluetooth/mesh/cfg_srv.c | 22 ++++++++++++++++- subsys/bluetooth/mesh/large_comp_data_srv.c | 22 ++++++++++++++++- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 2ea7ece90df..24259165e05 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -2562,30 +2562,3 @@ void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod) mod->flags |= BT_MESH_MOD_DATA_PENDING; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); } - -uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf) -{ - uint8_t page = net_buf_simple_pull_u8(buf); - - if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 130U; - } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 129U; - } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 128U; - } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - page = 2U; - } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { - page = 1U; - } else if (page != 0U) { - LOG_DBG("Composition page %u not available", page); - page = 0U; - } - - return page; -} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index f58c6f1d449..6027768ea94 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -64,7 +64,6 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); int bt_mesh_comp_store(void); int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page); -uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf); int bt_mesh_models_metadata_store(void); int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index f65d2cba3c7..eb732a34910 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -59,7 +59,27 @@ static int dev_comp_data_get(struct bt_mesh_model *model, LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - page = bt_mesh_comp_parse_page(buf); + page = net_buf_simple_pull_u8(buf); + + if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 130U; + } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 129U; + } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 128U; + } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + page = 2U; + } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + page = 1U; + } else if (page != 0U) { + LOG_DBG("Composition page %u not available", page); + page = 0U; + } LOG_DBG("Preparing Composition data page %d", page); bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS); diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 4ee591d9efd..12497d053a2 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -53,12 +53,32 @@ static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mes ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - page = bt_mesh_comp_parse_page(buf); + page = net_buf_simple_pull_u8(buf); offset = net_buf_simple_pull_le16(buf); LOG_DBG("page %u offset %u", page, offset); bt_mesh_model_msg_init(&rsp, OP_LARGE_COMP_DATA_STATUS); + if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 130U; + } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 129U; + } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || + IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { + page = 128U; + } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { + page = 2U; + } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + page = 1U; + } else if (page != 0U) { + LOG_DBG("Composition page %u not available", page); + page = 0U; + } + net_buf_simple_add_u8(&rsp, page); net_buf_simple_add_le16(&rsp, offset); From 9b227abf5cd73b579884f05135f9edf5a04e142f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:14 +0000 Subject: [PATCH 4241/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Add missing comp pages to LCD mod" This reverts commit 14095d899da44030014ce550dcc2b7fb4b910d08. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/Kconfig | 10 - subsys/bluetooth/mesh/access.c | 228 ++++++++------------ subsys/bluetooth/mesh/access.h | 2 +- subsys/bluetooth/mesh/large_comp_data_srv.c | 53 +---- 4 files changed, 94 insertions(+), 199 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 605e4608be7..9f24ff81975 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1375,16 +1375,6 @@ config BT_MESH_PRIV_BEACON_CLI endif # BT_MESH_PRIV_BEACONS -config BT_MESH_COMP_PST_BUF_SIZE - int "Composition Data Page persistence buffer size" - default 100 - help - Stack allocated buffer used to temporarily hold Composition - Data Pages during flash operations. Should reflect the size - of the largest Composition Data Page present in the application. - Note that this buffer should still be large enough to restore previously stored - pages after a performed device firmware update. - config BT_MESH_COMP_PAGE_1 bool "Support for Composition Data Page 1" depends on BT_MESH_MODEL_EXTENSIONS diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 24259165e05..b6dab2d67a7 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -173,18 +173,6 @@ static void data_buf_add_le16_offset(struct net_buf_simple *buf, } } -static void data_buf_add_mem_offset(struct net_buf_simple *buf, uint8_t *data, size_t len, - size_t *offset) -{ - if (*offset >= len) { - *offset -= len; - return; - } - - net_buf_simple_add_mem(buf, data + *offset, len - *offset); - *offset = 0; -} - static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, void *user_data) { @@ -199,6 +187,20 @@ static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) +static void data_buf_add_mem_offset(struct net_buf_simple *buf, + const void *mem, size_t len, + size_t *offset) +{ + if (*offset >= len) { + *offset -= len; + return; + } else if (*offset > 0) { + net_buf_simple_add_mem(buf, ((uint8_t *)mem), (len - *offset)); + + } else { + net_buf_simple_add_mem(buf, mem, len); + } +} static size_t metadata_model_size(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd) @@ -364,6 +366,23 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset) } #endif +size_t bt_mesh_comp_page_0_size(void) +{ + const struct bt_mesh_comp *comp; + const struct bt_mesh_elem *elem; + size_t size = 10; + int i; + + comp = bt_mesh_comp_get(); + + for (i = 0; i < comp->elem_count; i++) { + elem = &comp->elem[i]; + size += bt_mesh_comp_elem_size(elem); + } + + return size; +} + static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, size_t *offset) { @@ -379,7 +398,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, return 0; } - if (net_buf_simple_tailroom(buf) < ((elem_size - *offset) + BT_MESH_MIC_SHORT)) { + if (net_buf_simple_tailroom(buf) < (elem_size + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, @@ -497,8 +516,8 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id) return false; } -static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t *mod_cnt, - struct net_buf_simple *buf, size_t *offset) +static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, + uint8_t *mod_cnt, struct net_buf_simple *buf) { uint8_t ext_mod_cnt; bool cor_present; @@ -517,41 +536,41 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id, u if (cor_present) { mod_elem_info |= BIT(0); } - data_buf_add_u8_offset(buf, mod_elem_info, offset); + net_buf_simple_add_u8(buf, mod_elem_info); if (cor_present) { - data_buf_add_u8_offset(buf, *cor_id, offset); + net_buf_simple_add_u8(buf, *cor_id); } memset(mod_cnt, ext_mod_cnt, sizeof(uint8_t)); } static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod, - uint8_t ext_mod_cnt, size_t *offset) + uint8_t ext_mod_cnt) { - int i, elem_offset; + int i, offset; uint8_t mod_idx; MOD_REL_LIST_FOR_EACH(i) { if (IS_MOD_EXTENSION(mod, i)) { - elem_offset = mod->elem_idx - mod_rel_list[i].elem_base; + offset = mod->elem_idx - mod_rel_list[i].elem_base; mod_idx = mod_rel_list[i].idx_base; if (ext_mod_cnt < 32 && - elem_offset < 4 && - elem_offset > -5) { + offset < 4 && + offset > -5) { /* short format */ - if (elem_offset < 0) { - elem_offset += 8; + if (offset < 0) { + offset += 8; } - elem_offset |= mod_idx << 3; - data_buf_add_u8_offset(buf, elem_offset, offset); + offset |= mod_idx << 3; + net_buf_simple_add_u8(buf, offset); } else { /* long format */ - if (elem_offset < 0) { - elem_offset += 256; + if (offset < 0) { + offset += 256; } - data_buf_add_u8_offset(buf, elem_offset, offset); - data_buf_add_u8_offset(buf, mod_idx, offset); + net_buf_simple_add_u8(buf, offset); + net_buf_simple_add_u8(buf, mod_idx); } } } @@ -594,7 +613,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) return temp_size; } -static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offset) +static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) { const struct bt_mesh_comp *comp; uint8_t cor_id = 0; @@ -604,14 +623,8 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse comp = bt_mesh_comp_get(); for (i = 0; i < comp->elem_count; i++) { - size_t elem_size = page1_elem_size(&comp->elem[i]); - - if (offset >= elem_size) { - offset -= elem_size; - continue; - } - - if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { + if (net_buf_simple_tailroom(buf) < + (page1_elem_size(&comp->elem[i]) + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, @@ -626,53 +639,49 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offse return -E2BIG; } - data_buf_add_u8_offset(buf, comp->elem[i].model_count, &offset); - data_buf_add_u8_offset(buf, comp->elem[i].vnd_model_count, &offset); + net_buf_simple_add_u8(buf, comp->elem[i].model_count); + net_buf_simple_add_u8(buf, comp->elem[i].vnd_model_count); for (j = 0; j < comp->elem[i].model_count; j++) { - prep_model_item_header(&comp->elem[i].models[j], &cor_id, &ext_mod_cnt, buf, - &offset); + prep_model_item_header(&comp->elem[i].models[j], + &cor_id, &ext_mod_cnt, buf); if (ext_mod_cnt != 0) { - add_items_to_page(buf, &comp->elem[i].models[j], ext_mod_cnt, - &offset); + add_items_to_page(buf, + &comp->elem[i].models[j], + ext_mod_cnt); } } for (j = 0; j < comp->elem[i].vnd_model_count; j++) { - prep_model_item_header(&comp->elem[i].vnd_models[j], &cor_id, &ext_mod_cnt, - buf, &offset); + prep_model_item_header(&comp->elem[i].vnd_models[j], + &cor_id, &ext_mod_cnt, buf); if (ext_mod_cnt != 0) { - add_items_to_page(buf, &comp->elem[i].vnd_models[j], ext_mod_cnt, - &offset); + add_items_to_page(buf, + &comp->elem[i].vnd_models[j], + ext_mod_cnt); } } } return 0; } -static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offset) +static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf) { if (!dev_comp2) { LOG_ERR("Composition data P2 not registered"); return -ENODEV; } - size_t elem_size; - for (int i = 0; i < dev_comp2->record_cnt; i++) { - elem_size = - 8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len; - if (offset >= elem_size) { - offset -= elem_size; - continue; - } - - if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) { + if (net_buf_simple_tailroom(buf) < + (8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len + + BT_MESH_MIC_SHORT)) { if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { /* Mesh Profile 1.1 Section 4.4.1.2.2: * If the complete list of models does not fit in the Data field, * the element shall not be reported. */ - LOG_DBG("Record 0x%04x didn't fit in the Data field", i); + LOG_DBG("Record 0x%04x didn't fit in the Data field", + i); return 0; } @@ -680,20 +689,20 @@ static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offse return -E2BIG; } - data_buf_add_le16_offset(buf, dev_comp2->record[i].id, &offset); - data_buf_add_u8_offset(buf, dev_comp2->record[i].version.x, &offset); - data_buf_add_u8_offset(buf, dev_comp2->record[i].version.y, &offset); - data_buf_add_u8_offset(buf, dev_comp2->record[i].version.z, &offset); - data_buf_add_u8_offset(buf, dev_comp2->record[i].elem_offset_cnt, &offset); + net_buf_simple_add_le16(buf, dev_comp2->record[i].id); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.x); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.y); + net_buf_simple_add_u8(buf, dev_comp2->record[i].version.z); + net_buf_simple_add_u8(buf, dev_comp2->record[i].elem_offset_cnt); if (dev_comp2->record[i].elem_offset_cnt) { - data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].elem_offset, - dev_comp2->record[i].elem_offset_cnt, &offset); + net_buf_simple_add_mem(buf, dev_comp2->record[i].elem_offset, + dev_comp2->record[i].elem_offset_cnt); } - data_buf_add_le16_offset(buf, dev_comp2->record[i].data_len, &offset); + net_buf_simple_add_le16(buf, dev_comp2->record[i].data_len); if (dev_comp2->record[i].data_len) { - data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].data, - dev_comp2->record[i].data_len, &offset); + net_buf_simple_add_mem(buf, dev_comp2->record[i].data, + dev_comp2->record[i].data_len); } } @@ -2203,89 +2212,20 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o if (page == 0 || page == 128) { return bt_mesh_comp_data_get_page_0(buf, offset); } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { - return bt_mesh_comp_data_get_page_1(buf, offset); + return bt_mesh_comp_data_get_page_1(buf); } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { - return bt_mesh_comp_data_get_page_2(buf, offset); + return bt_mesh_comp_data_get_page_2(buf); } return -EINVAL; } -size_t comp_page_0_size(void) -{ - const struct bt_mesh_comp *comp; - const struct bt_mesh_elem *elem; - size_t size = 10; /* Non-variable length params of comp page 0. */ - - comp = bt_mesh_comp_get(); - - for (int i = 0; i < comp->elem_count; i++) { - elem = &comp->elem[i]; - size += bt_mesh_comp_elem_size(elem); - } - - return size; -} - -size_t comp_page_1_size(void) -{ - const struct bt_mesh_comp *comp; - size_t size = 0; - - comp = bt_mesh_comp_get(); - - for (int i = 0; i < comp->elem_count; i++) { - - size += page1_elem_size(&comp->elem[i]); - } - - return size; -} - -size_t comp_page_2_size(void) -{ - size_t size = 0; - - if (!dev_comp2) { - LOG_ERR("Composition data P2 not registered"); - return size; - } - - for (int i = 0; i < dev_comp2->record_cnt; i++) { - size += 8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len; - } - return size; -} - -size_t bt_mesh_comp_page_size(uint8_t page) -{ - if (page == 0 || page == 128) { - return comp_page_0_size(); - } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { - return comp_page_1_size(); - } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { - return comp_page_2_size(); - } - - return 0; -} - int bt_mesh_comp_store(void) { -#if IS_ENABLED(CONFIG_BT_MESH_V1d1) - NET_BUF_SIMPLE_DEFINE(buf, CONFIG_BT_MESH_COMP_PST_BUF_SIZE); + NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX); int err; for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) { - size_t page_size = bt_mesh_comp_page_size(i); - - if (page_size > CONFIG_BT_MESH_COMP_PST_BUF_SIZE) { - LOG_WRN("CDP%d is larger than the CDP persistence buffer. " - "Please increase the CDP persistence buffer size " - "to the required size (%d bytes)", - i, page_size); - } - net_buf_simple_reset(&buf); err = bt_mesh_comp_data_get_page(&buf, comp_data_pages[i].page, 0); @@ -2302,7 +2242,7 @@ int bt_mesh_comp_store(void) LOG_DBG("Stored CDP%d", comp_data_pages[i].page); } -#endif + return 0; } diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 6027768ea94..4740963dd21 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -23,7 +23,7 @@ enum { void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); uint8_t bt_mesh_elem_count(void); -size_t bt_mesh_comp_page_size(uint8_t page); +size_t bt_mesh_comp_page_0_size(void); int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset); size_t bt_mesh_metadata_page_0_size(void); int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); diff --git a/subsys/bluetooth/mesh/large_comp_data_srv.c b/subsys/bluetooth/mesh/large_comp_data_srv.c index 12497d053a2..9f097f4355a 100644 --- a/subsys/bluetooth/mesh/large_comp_data_srv.c +++ b/subsys/bluetooth/mesh/large_comp_data_srv.c @@ -59,59 +59,24 @@ static int handle_large_comp_data_get(struct bt_mesh_model *model, struct bt_mes LOG_DBG("page %u offset %u", page, offset); bt_mesh_model_msg_init(&rsp, OP_LARGE_COMP_DATA_STATUS); - if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 130U; - } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 129U; - } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 128U; - } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - page = 2U; - } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { - page = 1U; - } else if (page != 0U) { + + if (page != 0U) { LOG_DBG("Composition page %u not available", page); page = 0U; } net_buf_simple_add_u8(&rsp, page); - net_buf_simple_add_le16(&rsp, offset); - if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && page < 128) { - size_t msg_space; + total_size = bt_mesh_comp_page_0_size(); + net_buf_simple_add_le16(&rsp, offset); + net_buf_simple_add_le16(&rsp, total_size); - NET_BUF_SIMPLE_DEFINE(temp_buf, CONFIG_BT_MESH_COMP_PST_BUF_SIZE); - err = bt_mesh_comp_read(&temp_buf, page); - if (err) { - LOG_ERR("Could not read comp data p%d, err: %d", page, err); + if (offset < total_size) { + err = bt_mesh_comp_data_get_page_0(&rsp, offset); + if (err && err != -E2BIG) { + LOG_ERR("comp_get_page_0 returned error"); return err; } - - net_buf_simple_add_le16(&rsp, temp_buf.len); - if (offset > temp_buf.len) { - return 0; - } - - msg_space = net_buf_simple_tailroom(&rsp) - BT_MESH_MIC_SHORT; - net_buf_simple_add_mem( - &rsp, temp_buf.data + offset, - (msg_space < (temp_buf.len - offset)) ? msg_space : temp_buf.len - offset); - } else { - total_size = bt_mesh_comp_page_size(page); - net_buf_simple_add_le16(&rsp, total_size); - - if (offset < total_size) { - err = bt_mesh_comp_data_get_page(&rsp, page, offset); - if (err && err != -E2BIG) { - LOG_ERR("Could not read comp data p%d, err: %d", page, err); - return err; - } - } } if (bt_mesh_model_send(model, ctx, &rsp, NULL, NULL)) { From 793ca0126e66430a5449d598f3675810e2865d68 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:14 +0000 Subject: [PATCH 4242/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Fix self-update test DFU/SR/FD/BV-59-C" This reverts commit 60dc14e371af10a1f549fb3541b5be922217e524. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 33 +-------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c191ed54568..2a74bb03828 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -17,7 +17,6 @@ #include #include #include -#include "mesh/access.h" #include #define LOG_MODULE_NAME bttester_mesh @@ -113,19 +112,6 @@ static const struct bt_mesh_blob_io dummy_blob_io = { #endif #if defined(CONFIG_BT_MESH_DFD_SRV) -static const struct bt_mesh_dfu_slot *dfu_self_update_slot; - -static bool is_self_update(struct bt_mesh_dfd_srv *srv) -{ - for (int i = 0; i < ARRAY_SIZE(srv->targets); i++) { - if (bt_mesh_has_addr(srv->targets[i].blob.addr)) { - return true; - } - } - - return false; -} - /* DFD Model data*/ static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv, const struct bt_mesh_dfu_slot *slot, @@ -152,13 +138,6 @@ static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, *io = &dummy_blob_io; - dfu_self_update_slot = NULL; - - if (is_self_update(srv)) { - LOG_DBG("DFD server starts self-update..."); - dfu_self_update_slot = slot; - } - return 0; } @@ -237,7 +216,7 @@ static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers }; #if defined(CONFIG_BT_MESH_DFU_SRV) const char *metadata_data = "1100000000000011"; -static uint8_t dfu_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { +static uint8_t dfu_fwid[] = { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -305,16 +284,6 @@ static int dfu_apply(struct bt_mesh_dfu_srv *srv, LOG_DBG("Applying DFU transfer..."); -#if defined(CONFIG_BT_MESH_DFD_SRV) - if (is_self_update(&dfd_srv) && dfu_self_update_slot != NULL) { - LOG_DBG("Swapping fwid for self-update"); - /* Simulate self-update by swapping fwid. */ - memcpy(&dfu_fwid[0], dfu_self_update_slot->fwid, dfu_self_update_slot->fwid_len); - dfu_imgs[0].fwid_len = dfu_self_update_slot->fwid_len; - } - -#endif - return 0; } From c4e6f0e40677337eada080057d2e9f8055abde86 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:15 +0000 Subject: [PATCH 4243/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fixed issue with RPR server and client." This reverts commit b043570e6e1a2721b9c4ac566a5f768366196f80. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/provisioner.c | 71 --- .../bsim/bluetooth/mesh/src/test_provision.c | 490 +++++------------- .../pb_remote_client_server_same_dev.sh | 32 -- 3 files changed, 123 insertions(+), 470 deletions(-) delete mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 717cdbee610..361f373cb7b 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -857,72 +857,6 @@ int bt_mesh_pb_remote_open(struct bt_mesh_rpr_cli *cli, return link_open(uuid, &pb_remote_cli, net_idx, addr, 0, &ctx, 0); } -/* Remote Provision done where client and server is on same node, skip open link - * and sending of reprovision message, just execute reprovisioning on it self. - */ -static int reprovision_local_client_server(uint16_t addr) -{ - int err; - const uint8_t *pub_key; - const uint8_t *priv_key = NULL; - - if (atomic_test_and_set_bit(bt_mesh_prov_link.flags, LINK_ACTIVE)) { - return -EBUSY; - } - - LOG_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x", - prov_device.node->net_idx, bt_mesh_cdb.iv_index, addr); - - atomic_set_bit(bt_mesh_prov_link.flags, REPROVISION); - atomic_set_bit(bt_mesh_prov_link.flags, PROVISIONER); - bt_mesh_prov_link.addr = addr; - bt_mesh_prov_link.bearer = &pb_remote_cli; - bt_mesh_prov_link.role = &role_provisioner; - prov_device.net_idx = prov_device.node->net_idx; - prov_device.attention_duration = 0; - - if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) && - bt_mesh_prov->public_key_be && bt_mesh_prov->private_key_be) { - LOG_DBG("Use OOB Public and Private key"); - pub_key = bt_mesh_prov->public_key_be; - priv_key = bt_mesh_prov->private_key_be; - } else { - pub_key = bt_mesh_pub_key_get(); - } - - if (!pub_key) { - LOG_ERR("No public key available"); - return -ENOEXEC; - } - - if (bt_mesh_dhkey_gen(pub_key, priv_key, bt_mesh_prov_link.dhkey)) { - LOG_ERR("Failed to generate DHKey"); - return -ENOEXEC; - } - LOG_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, DH_KEY_SIZE)); - - err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey, - bt_mesh_prov_link.prov_salt, prov_device.new_dev_key); - if (err) { - LOG_ERR("Unable to generate device key"); - return err; - } - - bt_mesh_dev_key_cand(prov_device.new_dev_key); - /* Mark the link that was never opened as closed. */ - atomic_set_bit(bt_mesh_prov_link.flags, COMPLETE); - bt_mesh_reprovision(addr); - bt_mesh_dev_key_cand_activate(); - - if (bt_mesh_prov->reprovisioned) { - LOG_DBG("Application reprovisioned callback 0x%04x", bt_mesh_primary_addr()); - bt_mesh_prov->reprovisioned(bt_mesh_primary_addr()); - } - - prov_link_closed(PROV_BEARER_LINK_STATUS_SUCCESS); - return 0; -} - int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, struct bt_mesh_rpr_node *srv, uint16_t addr, bool composition_change) @@ -943,11 +877,6 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, return -ENOENT; } - /* Check if server is on same device as client */ - if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV) && bt_mesh_has_addr(srv->addr)) { - return reprovision_local_client_server(addr); - } - return link_open(NULL, &pb_remote_cli, prov_device.node->net_idx, addr, 0, &ctx, 0); } diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index c78fe8dc87d..171f8cccbbd 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -139,19 +139,6 @@ static const struct bt_mesh_comp rpr_srv_comp = { .elem_count = 1, }; -static const struct bt_mesh_comp rpr_cli_srv_comp = { - .elem = - (struct bt_mesh_elem[]){ - BT_MESH_ELEM(1, - MODEL_LIST(BT_MESH_MODEL_CFG_SRV, - BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}), - BT_MESH_MODEL_RPR_CLI(&rpr_cli), - BT_MESH_MODEL_RPR_SRV), - BT_MESH_MODEL_NONE), - }, - .elem_count = 1, -}; - static int mock_pdu_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -1056,127 +1043,18 @@ static void test_provisioner_pb_remote_client_provision_timeout(void) PASS(); } -static void reprovision_remote_devkey_client(struct bt_mesh_rpr_node *srv, - struct bt_mesh_cdb_node *node) -{ - uint8_t status; - uint8_t prev_node_dev_key[16]; - - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, false); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check device key by adding appkey. */ - ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, - &status)); - ASSERT_OK(status); - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); -} - -static void reprovision_remote_comp_data_client(struct bt_mesh_rpr_node *srv, - struct bt_mesh_cdb_node *node, - struct net_buf_simple *dev_comp) -{ - NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX); - uint8_t prev_node_dev_key[16]; - uint8_t page; - - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, true); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check that Composition Data Page 128 is now Page 0. */ - net_buf_simple_reset(&new_dev_comp); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, - &new_dev_comp)); - - ASSERT_EQUAL(0, page); - ASSERT_EQUAL(dev_comp->len, new_dev_comp.len); - if (memcmp(dev_comp->data, new_dev_comp.data, dev_comp->len)) { - FAIL("Wrong composition data page 0"); - } - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); -} - -static void reprovision_remote_address_client(struct bt_mesh_rpr_node *srv, - struct bt_mesh_cdb_node *node) -{ - uint8_t status; - uint8_t prev_node_dev_key[16]; - - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr + 1, false); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); - - current_dev_addr++; - srv->addr++; - - /* Check that device doesn't respond to old address with old and new device key. */ - struct bt_mesh_cdb_node *prev_node; - uint8_t tmp[16]; - - prev_node = bt_mesh_cdb_node_alloc((uint8_t[16]) {}, current_dev_addr - 1, 1, 0); - ASSERT_TRUE(node); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, prev_node_dev_key), - "Can't import device key into cdb"); - ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, - test_app_key, &status)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, tmp), - "Can't export device key from cdb"); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, tmp), - "Can't import device key into cdb"); - ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, - test_app_key, &status)); - bt_mesh_cdb_node_del(prev_node, false); - - /* Check that CDB has updated Device Key for the node. */ - ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); - ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), - "Can't export device key from cdb"); - - /* Check new device address by adding appkey. */ - ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, - &status)); - ASSERT_OK(status); - - /* Let RPR Server verify Device Key. */ - k_sleep(K_SECONDS(2)); - -} - /** @brief Verify robustness of NPPI procedures on a RPR Client by running Device Key Refresh, * Node Composition Refresh and Node Address Refresh procedures. */ static void test_provisioner_pb_remote_client_nppi_robustness(void) { NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX); + NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX); uint8_t page; uint16_t pb_remote_server_addr; uint8_t status; struct bt_mesh_cdb_node *node; + uint8_t prev_node_dev_key[16]; provisioner_pb_remote_client_setup(); @@ -1204,23 +1082,96 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void) node = bt_mesh_cdb_node_get(current_dev_addr); ASSERT_TRUE(node); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); LOG_INF("Testing DevKey refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Refreshing device key #%d...\n", i); - reprovision_remote_devkey_client(&srv, node); + bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, false); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check device key by adding appkey. */ + ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, + &status)); + ASSERT_OK(status); + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); } LOG_INF("Testing Composition Data refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Changing Composition Data #%d...\n", i); - reprovision_remote_comp_data_client(&srv, node, &dev_comp); + bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, true); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check that Composition Data Page 128 is now Page 0. */ + net_buf_simple_reset(&new_dev_comp); + ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, + &new_dev_comp)); + ASSERT_EQUAL(0, page); + ASSERT_EQUAL(dev_comp.len, new_dev_comp.len); + if (memcmp(dev_comp.data, new_dev_comp.data, dev_comp.len)) { + FAIL("Wrong composition data page 0"); + } + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); } LOG_INF("Testing address refresh..."); for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Changing address #%d...\n", i); - reprovision_remote_address_client(&srv, node); + bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr + 1, false); + + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20))); + + current_dev_addr++; + srv.addr++; + + /* Check that device doesn't respond to old address with old and new device key. */ + struct bt_mesh_cdb_node *prev_node; + uint8_t tmp[16]; + + prev_node = bt_mesh_cdb_node_alloc((uint8_t[16]) {}, current_dev_addr - 1, 1, 0); + ASSERT_TRUE(node); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, prev_node_dev_key), + "Can't import device key into cdb"); + ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, + test_app_key, &status)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, tmp), + "Can't export device key from cdb"); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, tmp), + "Can't import device key into cdb"); + ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0, + test_app_key, &status)); + bt_mesh_cdb_node_del(prev_node, false); + + /* Check that CDB has updated Device Key for the node. */ + ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key)); + ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key), + "Can't export device key from cdb"); + + /* Check new device address by adding appkey. */ + ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, + &status)); + ASSERT_OK(status); + + /* Let RPR Server verify Device Key. */ + k_sleep(K_SECONDS(2)); } PASS(); @@ -1260,78 +1211,13 @@ static void test_device_pb_remote_server_proved(void) PASS(); } -static void reprovision_remote_devkey_server(const uint16_t initial_addr) -{ - uint8_t prev_dev_key[16]; - uint8_t dev_key[16]; - - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(&prev_dev_key, dev_key, sizeof(dev_key))); -} - -static void reprovision_remote_comp_data_server(const uint16_t initial_addr) -{ - u_int8_t prev_dev_key[16]; - u_int8_t dev_key[16]; - - /* The RPR Server won't let to run Node Composition Refresh procedure without first - * setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a - * "bt/mesh/cmp" entry in settings. The entry is added by the - * `bt_mesh_comp_change_prepare() call. The test suite is not compiled - * with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the - * test is to check RPR Server behavior, but not the actual swap of the Composition - * Data, the flag is toggled directly from the test. - */ - atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - - /* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */ - atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); - - ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); -} - -static void reprovision_remote_address_server(const uint16_t initial_addr) -{ - uint8_t prev_dev_key[16]; - uint8_t dev_key[16]; - - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - - ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); - ASSERT_EQUAL(initial_addr + 1, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key and verify that it has - * been changed. - */ - k_sleep(K_SECONDS(2)); - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); -} - /** @brief Verify robustness of NPPI procedures on a RPR Server by running Device Key Refresh, * Node Composition Refresh and Node Address Refresh procedures multiple times each. */ static void test_device_pb_remote_server_nppi_robustness(void) { + struct bt_mesh_key prev_dev_key; + k_sem_init(&prov_sem, 0, 1); k_sem_init(&reprov_sem, 0, 1); @@ -1344,25 +1230,65 @@ static void test_device_pb_remote_server_nppi_robustness(void) ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); const uint16_t initial_addr = bt_mesh_primary_addr(); + memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); + LOG_INF("Enabling PB-Remote server"); ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); /* Test Device Key Refresh procedure robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Devkey refresh loop #%d, waiting for being reprov ...\n", i); - reprovision_remote_devkey_server(initial_addr); + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); + memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); } /* Test Node Composition Refresh procedure robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { + /* The RPR Server won't let to run Node Composition Refresh procedure without first + * setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a + * "bt/mesh/cmp" entry in settings. The entry is added by the + * `bt_mesh_comp_change_prepare() call. The test suite is not compiled + * with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the + * test is to check RPR Server behavior, but not the actual swap of the Composition + * Data, the flag is toggled directly from the test. + */ + atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); + LOG_INF("Composition data refresh loop #%d, waiting for being reprov ...\n", i); - reprovision_remote_comp_data_server(initial_addr); + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + + /* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */ + atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); + + ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); + memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); } /* Node Address Refresh robustness. */ for (int i = 0; i < PROV_REPROV_COUNT; i++) { LOG_INF("Address refresh loop #%d, waiting for being reprov ...\n", i); - reprovision_remote_address_server(initial_addr+i); + ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30))); + ASSERT_EQUAL(initial_addr + 1 + i, bt_mesh_primary_addr()); + + /* Let Configuration Client activate the new Device Key and verify that it has + * been changed. + */ + k_sleep(K_SECONDS(2)); + ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key))); + memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)); } PASS(); @@ -1399,172 +1325,6 @@ static void test_provisioner_pb_remote_client_ncrp_provision(void) PASS(); } -/** @brief A device running a Remote Provisioning client and server that is used to reprovision - * another device and it self with the client. - */ -static void test_device_pb_remote_client_server_same_dev(void) -{ - NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX); - uint8_t status; - struct bt_mesh_cdb_node *node; - uint8_t page; - uint8_t prev_dev_key[16]; - uint16_t test_vector[] = { 0x0002, 0x0001 }; - - k_sem_init(&prov_sem, 0, 1); - k_sem_init(&reprov_sem, 0, 1); - - bt_mesh_device_setup(&prov, &rpr_cli_srv_comp); - - ASSERT_OK(bt_mesh_cdb_create(test_net_key)); - ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key)); - - LOG_INF("Enabling PB-Remote server"); - ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); - - /* Provision a remote device with RPR Client and Server with local RPR Server. */ - current_dev_addr = 0x0001; - struct bt_mesh_rpr_node srv = { - .addr = current_dev_addr, - .net_idx = 0, - .ttl = 3, - }; - - LOG_INF("Provisioner prov, waiting for prov ...\n"); - ASSERT_OK(provision_remote(&srv, 1, &srv.addr)); - - ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); - - /* Check device key by adding bt_mesh_reprovision_remote appkey. */ - ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, &status)); - ASSERT_OK(status); - - /* Swap callback to catch when device reprovisioned. */ - prov.node_added = prov_node_added_rpr; - - /* Reprovision a device with both RPR Client and Server. */ - for (int i = 0; i < ARRAY_SIZE(test_vector); i++) { - current_dev_addr = test_vector[i]; - srv.addr = current_dev_addr; - bool self_reprov = (bool)(current_dev_addr == bt_mesh_primary_addr()); - - /* Store initial Composition Data Page 0. */ - net_buf_simple_reset(&dev_comp); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp)); - - node = bt_mesh_cdb_node_get(current_dev_addr); - ASSERT_TRUE(node); - - LOG_INF("Refreshing 0x%04x device key ...\n", srv.addr); - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - reprovision_remote_devkey_client(&srv, node); - if (self_reprov) { - uint8_t dev_key[16]; - - ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key - * and verify that it has been changed. - */ - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); - } - - LOG_INF("Changing 0x%04x Composition Data ...\n", srv.addr); - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - reprovision_remote_comp_data_client(&srv, node, &dev_comp); - if (self_reprov) { - uint8_t dev_key[16]; - - ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key - * and verify that it has been changed. - */ - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(struct bt_mesh_key))); - } - - LOG_INF("Changing 0x%04x address ...\n", srv.addr); - ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key)); - reprovision_remote_address_client(&srv, node); - if (self_reprov) { - uint8_t dev_key[16]; - - ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr()); - - /* Let Configuration Client activate the new Device Key - * and verify that it has been changed. - */ - ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key)); - ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key))); - } - } - - PASS(); -} - -/** @brief Verify that the Remote Provisioning client and server is able to be reprovision - * by another device with a Remote Provisioning client and server. - */ -static void test_device_pb_remote_server_same_dev(void) -{ - k_sem_init(&prov_sem, 0, 1); - k_sem_init(&reprov_sem, 0, 1); - - bt_mesh_device_setup(&prov, &rpr_cli_srv_comp); - - ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV)); - - LOG_INF("Waiting for being provisioned..."); - ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); - - LOG_INF("Enabling PB-Remote server"); - ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE)); - - /* Swap callback to catch when device reprovisioned. */ - prov.node_added = prov_node_added_rpr; - - const uint16_t initial_addr = bt_mesh_primary_addr(); - - LOG_INF("Devkey refresh, waiting for being reprov ...\n"); - reprovision_remote_devkey_server(initial_addr); - - LOG_INF("Composition data refresh, waiting for being reprov ...\n"); - reprovision_remote_comp_data_server(initial_addr); - - LOG_INF("Address refresh, waiting for being reprov ...\n"); - reprovision_remote_address_server(initial_addr); - - PASS(); -} - -static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_simple *comp) -{ - uint8_t page_rsp; - - net_buf_simple_reset(comp); - ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page, &page_rsp, comp)); - ASSERT_EQUAL(page, page_rsp); -} - -static void comp_data_compare(struct net_buf_simple *comp1, struct net_buf_simple *comp2, - bool expect_equal) -{ - if (expect_equal) { - ASSERT_EQUAL(comp1->len, comp2->len); - if (memcmp(comp1->data, comp2->data, comp1->len)) { - FAIL("Composition data is not equal"); - } - } else { - if (comp1->len == comp2->len) { - if (!memcmp(comp1->data, comp2->data, comp1->len)) { - FAIL("Composition data is equal"); - } - } - } -} - /** @brief Test Node Composition Refresh procedure on Remote Provisioning client: * - initiate Node Composition Refresh procedure on a 3rd device. */ @@ -1783,10 +1543,6 @@ static const struct bst_test_instance test_connect[] = { "Device: pb-remote reprovisioning, NPPI robustness"), TEST_CASE(device, pb_remote_server_unproved_unresponsive, "Device: used for remote provisioning, starts unprovisioned, stops responding"), - TEST_CASE(device, pb_remote_client_server_same_dev, - "Device: used for remote provisioning, with both client and server"), - TEST_CASE(device, pb_remote_server_same_dev, - "Device: used for remote reprovisioning, with both client and server"), #endif TEST_CASE(provisioner, pb_adv_no_oob, diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh deleted file mode 100755 index 33de74370e1..00000000000 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_client_server_same_dev.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2023 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh - -# Test a node re-provisioning through Remote Provisioning models. Procedure: -# 1. Device (prov_device_pb_remote_client_server_same_dev) provisions it self -# and start scanning for an upprovisioned device, and provisions the the -# second device (prov_device_pb_remote_server_same_dev) with local RPR server. -# 2. The first device (prov_device_pb_remote_client_server_same_dev) execute -# device key refresh procedure the second device (prov_device_pb_remote_server_same_dev). -# 3. The first device (prov_device_pb_remote_client_server_same_dev) execute -# composition refresh procedure the second device (prov_device_pb_remote_server_same_dev). -# 4. The first device (prov_device_pb_remote_client_server_same_dev) execute -# address refresh procedure the second device (prov_device_pb_remote_server_same_dev). -# 5. The first device (prov_device_pb_remote_client_server_same_dev) execute -# device key refresh procedure on it self with local RPR client and server. -# 6. The first device (prov_device_pb_remote_client_server_same_dev) execute -# composition refresh procedure on it self with local RPR client and server. -# 7. The first device (prov_device_pb_remote_client_server_same_dev) execute -# address refresh procedure on it self with local RPR client and server. -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_remote_client_server_same_dev \ - prov_device_pb_remote_client_server_same_dev \ - prov_device_pb_remote_server_same_dev - -conf=prj_mesh1d1_conf -overlay=overlay_psa_conf -RunTest mesh_prov_pb_remote_client_server_same_dev \ - prov_device_pb_remote_client_server_same_dev \ - prov_device_pb_remote_server_same_dev From 791b6358be55ab98312f3b3ed8cfc2a7fb4bf744 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:15 +0000 Subject: [PATCH 4244/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Allow to pass int instead of bool in comp cmd" This reverts commit 0d5459354aa7383a99c7c7681fea795166061817. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index c2636d1445d..6b58d1515dc 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -78,7 +78,7 @@ struct btp_mesh_provision_node_cmd_v2 { #define BTP_MESH_INIT 0x04 struct btp_mesh_init_cmd { - uint8_t comp; + bool comp_alt; } __packed; #define BTP_MESH_RESET 0x05 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 2a74bb03828..dd16e98367b 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1259,7 +1259,7 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, const struct btp_mesh_init_cmd *cp = cmd; int err; - if (cp->comp == 0) { + if (!cp->comp_alt) { LOG_WRN("Loading default comp data"); err = bt_mesh_init(&prov, &comp); } else { From 34b55be7a43f0618a8f5652d0e5ca5baf46b1ab8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:15 +0000 Subject: [PATCH 4245/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Remove comp_alt_set command" This reverts commit 2814689b0005730341054fb7b7de91c0488f320a. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 + tests/bluetooth/tester/src/btp_mesh.c | 48 +++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 6b58d1515dc..bb26524246e 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -849,6 +849,8 @@ struct btp_mesh_opcodes_aggregator_init_cmd { #define BTP_MESH_COMP_CHANGE_PREPARE 0x57 +#define BTP_MESH_SET_COMP_ALT 0x58 + #define BTP_MESH_RPR_SCAN_START 0x59 struct btp_rpr_scan_start_cmd { uint16_t dst; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index dd16e98367b..eea03b0936e 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -318,6 +318,8 @@ static struct { .dst = BT_MESH_ADDR_UNASSIGNED, }; +static bool default_comp = true; + static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1903,6 +1905,47 @@ static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if IS_ENABLED(CONFIG_BT_SETTINGS) +static int comp_alt_set(const char *name, size_t len_rd, + settings_read_cb read_cb, void *store) +{ + ssize_t len; + bool alt_comp_value; + + if (len_rd == 0) { + LOG_DBG("Default composition"); + } + + len = read_cb(store, &alt_comp_value, sizeof(alt_comp_value)); + if (len < 0 || len != len_rd) { + LOG_ERR("Failed to read value (err %zd)", len); + return len; + } + + if (alt_comp_value) { + default_comp = false; + } + + return 0; +} + +SETTINGS_STATIC_HANDLER_DEFINE(tester_comp_alt, "tester/comp_alt", NULL, comp_alt_set, NULL, NULL); +#endif + +static uint8_t set_comp_alt(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ +#if !IS_ENABLED(CONFIG_BT_SETTINGS) + return BTP_STATUS_FAILED; +#else + bool comp_alt_val = true; + + settings_save_one("tester/comp_alt", &comp_alt_val, sizeof(comp_alt_val)); + + return BTP_STATUS_SUCCESS; +#endif +} + static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -4820,6 +4863,11 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = change_prepare }, + { + .opcode = BTP_MESH_SET_COMP_ALT, + .expect_len = 0, + .func = set_comp_alt + }, #if defined(CONFIG_BT_MESH_RPR_CLI) { .opcode = BTP_MESH_RPR_SCAN_START, From 98f32eb5562e9ac0d38fb17155446df0222092e5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:15 +0000 Subject: [PATCH 4246/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Move bt_mesh_init call to BTP_MESH_INIT cmd" This reverts commit b0b28e641a6591433abfdff68770fac327995e35. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 4 --- tests/bluetooth/tester/src/btp_mesh.c | 32 +++++++++++------------ 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bb26524246e..826f0fd0408 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -77,10 +77,6 @@ struct btp_mesh_provision_node_cmd_v2 { } __packed; #define BTP_MESH_INIT 0x04 -struct btp_mesh_init_cmd { - bool comp_alt; -} __packed; - #define BTP_MESH_RESET 0x05 #define BTP_MESH_INPUT_NUMBER 0x06 struct btp_mesh_input_number_cmd { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index eea03b0936e..e83f1a67ba1 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1258,24 +1258,8 @@ static uint8_t provision_adv(const void *cmd, uint16_t cmd_len, static uint8_t init(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_init_cmd *cp = cmd; int err; - if (!cp->comp_alt) { - LOG_WRN("Loading default comp data"); - err = bt_mesh_init(&prov, &comp); - } else { - LOG_WRN("Loading alternative comp data"); -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV - health_srv.metadata = health_srv_meta_alt; -#endif - err = bt_mesh_init(&prov, &comp_alt); - } - - if (err) { - return BTP_STATUS_FAILED; - } - LOG_DBG(""); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { @@ -4435,7 +4419,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_INIT, - .expect_len = sizeof(struct btp_mesh_init_cmd), + .expect_len = 0, .func = init, }, { @@ -5240,6 +5224,8 @@ BT_MESH_LPN_CB_DEFINE(lpn_cb) = { uint8_t tester_init_mesh(void) { + int err; + if (IS_ENABLED(CONFIG_BT_TESTING)) { bt_test_cb_register(&bt_test_cb); } @@ -5250,6 +5236,18 @@ uint8_t tester_init_mesh(void) tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); + if (default_comp) { + err = bt_mesh_init(&prov, &comp); + } else { +#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV + health_srv.metadata = health_srv_meta_alt; +#endif + err = bt_mesh_init(&prov, &comp_alt); + } + + if (err) { + return BTP_STATUS_FAILED; + } return BTP_STATUS_SUCCESS; } From d3bae7a0a1fd6597085477b7db1e14db96168747 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:15 +0000 Subject: [PATCH 4247/4498] Revert "[nrf fromtree] Bluetooth: Mesh: fix settings work queue size for rpr" This reverts commit 7bc30a2760c9c536cd24b1ebe040d1cdcbed6f08. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 9f24ff81975..2dfc125b8fd 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1718,7 +1718,6 @@ config BT_MESH_SETTINGS_WORKQ_PRIO config BT_MESH_SETTINGS_WORKQ_STACK_SIZE int "Stack size of the settings workq" - default 1200 if BT_MESH_RPR_SRV default 880 help Size of the settings workqueue stack. From d02a2dafdb4235c6df05f666df4e1174e73d847f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:16 +0000 Subject: [PATCH 4248/4498] =?UTF-8?q?Revert=20"[nrf=20fromtree]=C2=A0board?= =?UTF-8?q?s:=20arm:=20nrf9161dk=5Fnrf9161:=20Add=20ext=20flash=20support?= =?UTF-8?q?=20for=200.7.0=20version"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 10b0106a4e8771c99908d2b9c783fd9eee2e40bc. Signed-off-by: Dominik Ermel --- .../nrf9161dk_nrf9161_0_7_0.overlay | 7 ----- .../nrf9161dk_nrf9161_common_0_7_0.dtsi | 31 ------------------- .../nrf9161dk_nrf9161_ns_0_7_0.overlay | 7 ----- boards/arm/nrf9161dk_nrf9161/revision.cmake | 8 ----- 4 files changed, 53 deletions(-) delete mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay delete mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi delete mode 100644 boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay delete mode 100644 boards/arm/nrf9161dk_nrf9161/revision.cmake diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay deleted file mode 100644 index 22e9f970dab..00000000000 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_0_7_0.overlay +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "nrf9161dk_nrf9161_common_0_7_0.dtsi" diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi deleted file mode 100644 index ae67df77b22..00000000000 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common_0_7_0.dtsi +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&spi3 { - gd25lb256: gd25lb256e3ir@1 { - compatible = "jedec,spi-nor"; - status = "okay"; - reg = <1>; - spi-max-frequency = <60000000>; - jedec-id = [c8 67 19]; - sfdp-bfp = [ - e5 20 ea ff ff ff ff 0f 44 eb 08 6b 00 3b 00 bb - fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 - 10 d8 00 ff d5 31 b1 fe 82 e4 14 4c ec 60 06 33 - 7a 75 7a 75 04 bd d5 5c 29 06 74 00 08 50 00 01 - ]; - size = <268435456>; - has-dpd; - t-enter-dpd = <3000>; - t-exit-dpd = <30000>; - }; -}; - -/ { - aliases { - spi-flash0 = &gd25lb256; - }; -}; diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay deleted file mode 100644 index 22e9f970dab..00000000000 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns_0_7_0.overlay +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "nrf9161dk_nrf9161_common_0_7_0.dtsi" diff --git a/boards/arm/nrf9161dk_nrf9161/revision.cmake b/boards/arm/nrf9161dk_nrf9161/revision.cmake deleted file mode 100644 index 2a899f61a83..00000000000 --- a/boards/arm/nrf9161dk_nrf9161/revision.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -board_check_revision( - FORMAT MAJOR.MINOR.PATCH - DEFAULT_REVISION 0.9.0 - VALID_REVISIONS 0.7.0 0.9.0 -) From dcadc3f9c9af6f338c64a92d385bd9dbd24992d2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:16 +0000 Subject: [PATCH 4249/4498] Revert "[nrf fromtree] boards: arm: nrf9161dk: update SPI flash" This reverts commit 33a728fe359097894cd94598f2f09f7d883f6b8e. Signed-off-by: Dominik Ermel --- .../nrf9161dk_nrf9161_common.dtsi | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi index a6aeccf34b9..1dee5b1b1a3 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi @@ -128,7 +128,7 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &gd25wb256; + spi-flash0 = &gd25lb256; }; }; @@ -195,22 +195,22 @@ arduino_spi: &spi3 { pinctrl-1 = <&spi3_sleep>; pinctrl-names = "default", "sleep"; - gd25wb256: gd25wb256e3ir@1 { + gd25lb256: gd25lb256e3ir@1 { compatible = "jedec,spi-nor"; status = "disabled"; reg = <1>; - spi-max-frequency = <8000000>; + spi-max-frequency = <60000000>; + jedec-id = [c8 67 19]; + sfdp-bfp = [ + e5 20 ea ff ff ff ff 0f 44 eb 08 6b 00 3b 00 bb + fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 + 10 d8 00 ff d5 31 b1 fe 82 e4 14 4c ec 60 06 33 + 7a 75 7a 75 04 bd d5 5c 29 06 74 00 08 50 00 01 + ]; size = <268435456>; has-dpd; t-enter-dpd = <3000>; - t-exit-dpd = <40000>; - sfdp-bfp = [ - e5 20 f3 ff ff ff ff 0f 44 eb 08 6b 08 3b 42 bb - ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 - 10 d8 00 ff 44 7a c9 fe 83 67 26 62 ec 82 18 44 - 7a 75 7a 75 04 c4 d5 5c 00 06 74 00 08 50 00 01 - ]; - jedec-id = [c8 65 19]; + t-exit-dpd = <30000>; }; }; From 6d08b476d8b353c6668f931d8d70bf5735fad6ba Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:16 +0000 Subject: [PATCH 4250/4498] Revert "[nrf fromtree] Bluetooth: Test: Update `security/ccc_update`" This reverts commit c65b964187a631bd6bce52995599b29ba455b8dd. Signed-off-by: Dominik Ermel --- .../host/security/ccc_update/src/central.c | 9 ++++-- .../host/security/ccc_update/src/peripheral.c | 28 +++++++------------ 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/tests/bsim/bluetooth/host/security/ccc_update/src/central.c b/tests/bsim/bluetooth/host/security/ccc_update/src/central.c index 8f2d2c17dd4..fbdf7ee0108 100644 --- a/tests/bsim/bluetooth/host/security/ccc_update/src/central.c +++ b/tests/bsim/bluetooth/host/security/ccc_update/src/central.c @@ -248,7 +248,7 @@ static void connect_unsubscribe(void) backchannel_sync_wait(SERVER_CLIENT_CHAN, SERVER_ID); } -static void connect_restore_sec(void) +static void connect_restore_sec_unsubscribe(void) { int err; @@ -270,7 +270,10 @@ static void connect_restore_sec(void) /* wait for server to check that the subscribtion has been restored */ backchannel_sync_wait(SERVER_CLIENT_CHAN, SERVER_ID); - /* wait for server to check that the subscription no longer exist */ + /* send unsubscribtion request */ + ccc_unsubscribe(); + + /* wait for server to check that the unsubscribtion has been well registered */ backchannel_sync_send(SERVER_CLIENT_CHAN, SERVER_ID); } @@ -344,7 +347,7 @@ void run_central(void) backchannel_sync_send(CLIENT_CLIENT_CHAN, BAD_CLIENT_ID); backchannel_sync_wait(CLIENT_CLIENT_CHAN, BAD_CLIENT_ID); - connect_restore_sec(); + connect_restore_sec_unsubscribe(); disconnect(); PASS("Central test passed\n"); diff --git a/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c b/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c index ac6307dae6a..b9070361577 100644 --- a/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/ccc_update/src/peripheral.c @@ -194,9 +194,9 @@ static void connect_wait_unsubscribtion(struct bt_le_ext_adv *adv) stop_adv(adv); - /* check that subscribtion is restored for bad client */ - if (!is_peer_subscribed(default_conn)) { - FAIL("Subscribtion has not been restored for bad client\n"); + /* check that subscribtion is not restored for bad client */ + if (is_peer_subscribed(default_conn)) { + FAIL("Subscribtion has been restored for bad client\n"); } /* confirm to bad client that the subscribtion had not been restored */ @@ -204,12 +204,12 @@ static void connect_wait_unsubscribtion(struct bt_le_ext_adv *adv) /* wait for confirmation that bad client requested unsubscribtion */ backchannel_sync_wait(BAD_CLIENT_CHAN, BAD_CLIENT_ID); - /* check that unsubscribtion request didn't fail */ - if (!GET_FLAG(ccc_cfg_changed_flag)) { - FAIL("Bad client didn't manage to update CCC config\n"); + /* check that unsubscribtion request failed */ + if (GET_FLAG(ccc_cfg_changed_flag)) { + FAIL("Bad client updated CCC config\n"); } - /* confirm to bad client that unsubscribtion request has been well registered */ + /* confirm to bad client that unsubscribtion request has been ignored */ backchannel_sync_send(BAD_CLIENT_CHAN, BAD_CLIENT_ID); } @@ -225,9 +225,9 @@ static void connect_restore_sec_check_subscribtion(struct bt_le_ext_adv *adv) /* wait for good client end of security update */ backchannel_sync_wait(GOOD_CLIENT_CHAN, GOOD_CLIENT_ID); - /* check that subscribtion hasn't been restored */ - if (is_peer_subscribed(default_conn)) { - FAIL("Good client is subscribed\n"); + /* check that subscribtion has been restored */ + if (!is_peer_subscribed(default_conn)) { + FAIL("Good client is not subscribed\n"); } /* confirm to good client that the subscribtion has been well restored */ @@ -285,14 +285,6 @@ static void check_ccc_handle(void) void run_peripheral(void) { - /* - * test goal: demonstrate the expected behavior of the GATT server when - * a non-bonded peer try to unsubscribe from a previously subscription - * done in a bonded context - * - * test pass if the bad client manage to unsubscribe - */ - int err; struct bt_le_ext_adv *adv = NULL; From 0b778d104bfe903d2b5abd8bc564d93e1faeed96 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:16 +0000 Subject: [PATCH 4251/4498] Revert "[nrf fromtree] Revert "Bluetooth: Host: Fix GATT server handling of CCC"" This reverts commit c33d528a791c5aa4995e998b07ed8921ac2c04b2. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/gatt.h | 5 ++++ subsys/bluetooth/host/gatt.c | 43 +++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index f0ee8d5981a..e4aae4e4d41 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -736,6 +736,11 @@ struct bt_gatt_ccc_cfg { uint8_t id; /** Remote peer address. */ bt_addr_le_t peer; + /** + * Separate storage for encrypted and unencrypted context. This + * indicate that the link was encrypted when the CCC was written. + */ + bool link_encrypted; /** Configuration value. */ uint16_t value; }; diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 93dfe555580..39f01bc45b4 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -1318,6 +1318,7 @@ static void clear_ccc_cfg(struct bt_gatt_ccc_cfg *cfg) bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY); cfg->id = 0U; cfg->value = 0U; + cfg->link_encrypted = false; } static void gatt_store_ccc_cf(uint8_t id, const bt_addr_le_t *peer_addr); @@ -2049,6 +2050,34 @@ struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr) return next; } +static bool bt_gatt_ccc_cfg_is_matching_conn(const struct bt_conn *conn, + const struct bt_gatt_ccc_cfg *cfg) +{ + bool conn_encrypted = bt_conn_get_security(conn) >= BT_SECURITY_L2; + + if (cfg->link_encrypted && !conn_encrypted) { + return false; + } + + return bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer); +} + +static struct bt_conn *bt_gatt_ccc_cfg_conn_lookup(const struct bt_gatt_ccc_cfg *cfg) +{ + struct bt_conn *conn; + + conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer); + if (conn) { + if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { + return conn; + } + + bt_conn_unref(conn); + } + + return NULL; +} + static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn, struct _bt_gatt_ccc *ccc) { @@ -2056,8 +2085,7 @@ static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn, struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; if (conn) { - if (bt_conn_is_peer_addr_le(conn, cfg->id, - &cfg->peer)) { + if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { return cfg; } } else if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) { @@ -2151,6 +2179,7 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, bt_addr_le_copy(&cfg->peer, &conn->le.dst); cfg->id = conn->id; + cfg->link_encrypted = (bt_conn_get_security(conn) >= BT_SECURITY_L2); } /* Confirm write if cfg is managed by application */ @@ -3230,8 +3259,7 @@ static uint8_t update_ccc(const struct bt_gatt_attr *attr, uint16_t handle, struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; /* Ignore configuration for different peer or not active */ - if (!cfg->value || - !bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) { + if (!cfg->value || !bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { continue; } @@ -3305,11 +3333,11 @@ static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, uint16_t handle, continue; } - if (!bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) { + if (!bt_gatt_ccc_cfg_is_matching_conn(conn, cfg)) { struct bt_conn *tmp; /* Skip if there is another peer connected */ - tmp = bt_conn_lookup_addr_le(cfg->id, &cfg->peer); + tmp = bt_gatt_ccc_cfg_conn_lookup(cfg); if (tmp) { if (tmp->state == BT_CONN_CONNECTED) { value_used = true; @@ -3399,7 +3427,7 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn, for (size_t i = 0; i < BT_GATT_CCC_MAX; i++) { const struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; - if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer) && + if (bt_gatt_ccc_cfg_is_matching_conn(conn, cfg) && (ccc_type & ccc->cfg[i].value)) { return true; } @@ -5550,6 +5578,7 @@ static uint8_t ccc_load(const struct bt_gatt_attr *attr, uint16_t handle, } bt_addr_le_copy(&cfg->peer, load->addr_with_id.addr); cfg->id = load->addr_with_id.id; + cfg->link_encrypted = true; } cfg->value = load->entry->value; From e0c1a0292399fb30d5518e6823a8a4f0cacd3b16 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:17 +0000 Subject: [PATCH 4252/4498] Revert "[nrf fromtree] Bluetooth: Test: SC Indication" This reverts commit 860096c05abbb93e27d3ca0c3a14518cd3a69c5d. Signed-off-by: Dominik Ermel --- tests/bsim/bluetooth/host/compile.sh | 1 - .../host/gatt/sc_indicate/CMakeLists.txt | 25 --- .../bluetooth/host/gatt/sc_indicate/prj.conf | 20 -- .../host/gatt/sc_indicate/src/bs_bt_utils.c | 182 ---------------- .../host/gatt/sc_indicate/src/bs_bt_utils.h | 67 ------ .../host/gatt/sc_indicate/src/central.c | 195 ------------------ .../host/gatt/sc_indicate/src/main.c | 58 ------ .../host/gatt/sc_indicate/src/peripheral.c | 86 -------- .../gatt/sc_indicate/test_scripts/_compile.sh | 18 -- .../sc_indicate/test_scripts/sc_indicate.sh | 24 --- 10 files changed, 676 deletions(-) delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c delete mode 100644 tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c delete mode 100755 tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh delete mode 100755 tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index 98d6c79e3ef..a54dbd26507 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -44,7 +44,6 @@ app=tests/bsim/bluetooth/host/gatt/settings compile app=tests/bsim/bluetooth/host/gatt/settings conf_file=prj_2.conf compile app=tests/bsim/bluetooth/host/gatt/ccc_store compile app=tests/bsim/bluetooth/host/gatt/ccc_store conf_file=prj_2.conf compile -app=tests/bsim/bluetooth/host/gatt/sc_indicate compile app=tests/bsim/bluetooth/host/l2cap/general compile app=tests/bsim/bluetooth/host/l2cap/userdata compile diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt b/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt deleted file mode 100644 index d734b3c054e..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -if (NOT DEFINED ENV{BSIM_COMPONENTS_PATH}) - message(FATAL_ERROR "This test requires the BabbleSim simulator. Please set \ - the environment variable BSIM_COMPONENTS_PATH to point to its \ - components folder. More information can be found in \ - https://babblesim.github.io/folder_structure_and_env.html") -endif() - -find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) -project(bsim_test_auto_seq_req) - -target_sources(app PRIVATE - src/main.c - src/central.c - src/peripheral.c - src/bs_bt_utils.c -) - -zephyr_include_directories( - $ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/ - $ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/ -) diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf b/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf deleted file mode 100644 index 7edaf36d10e..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/prj.conf +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_DEVICE_NAME="SC Indication Test" - -CONFIG_LOG=y -CONFIG_BT_EXT_ADV=y - -CONFIG_BT_SMP=y -CONFIG_BT_GATT_CLIENT=y - -CONFIG_SETTINGS=y -CONFIG_BT_SETTINGS=y -CONFIG_FLASH=y -CONFIG_FLASH_PAGE_LAYOUT=y -CONFIG_NVS=y -CONFIG_FLASH_MAP=y -CONFIG_SETTINGS_NVS=y - -CONFIG_BT_GATT_DYNAMIC_DB=y diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c deleted file mode 100644 index 31952cbe330..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.c +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include -#include - -#include -LOG_MODULE_REGISTER(test_utils, LOG_LEVEL_DBG); - -#include "bs_bt_utils.h" - -struct bt_conn *g_conn; -DEFINE_FLAG(flag_is_connected); - -void wait_connected(void) -{ - LOG_DBG("Wait for connection..."); - WAIT_FOR_FLAG(flag_is_connected); -} - -void wait_disconnected(void) -{ - LOG_DBG("Wait for disconnection..."); - WAIT_FOR_FLAG_UNSET(flag_is_connected); -} - -static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) -{ - LOG_DBG("security changed"); -} - -static void disconnected(struct bt_conn *conn, uint8_t reason) -{ - UNSET_FLAG(flag_is_connected); -} - -struct bt_conn *get_g_conn(void) -{ - return g_conn; -} - -void clear_g_conn(void) -{ - struct bt_conn *conn; - - conn = g_conn; - g_conn = NULL; - BSIM_ASSERT(conn, "Test error: no g_conn!\n"); - bt_conn_unref(conn); -} - -static void connected(struct bt_conn *conn, uint8_t err) -{ - BSIM_ASSERT((!g_conn || (conn == g_conn)), "Unexpected new connection."); - - if (!g_conn) { - g_conn = bt_conn_ref(conn); - } - - if (err != 0) { - clear_g_conn(); - return; - } - - SET_FLAG(flag_is_connected); -} - -BT_CONN_CB_DEFINE(conn_callbacks) = { - .connected = connected, - .disconnected = disconnected, - .security_changed = security_changed, -}; - -static void stop_scan_and_connect(const bt_addr_le_t *addr, - int8_t rssi, - uint8_t type, - struct net_buf_simple *ad) -{ - char addr_str[BT_ADDR_LE_STR_LEN]; - int err; - - if (g_conn != NULL) { - return; - } - - bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); - printk("Got scan result, connecting.. dst %s, RSSI %d\n", addr_str, rssi); - - err = bt_le_scan_stop(); - BSIM_ASSERT(!err, "Err bt_le_scan_stop %d", err); - - err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn); - BSIM_ASSERT(!err, "Err bt_conn_le_create %d", err); -} - -void scan_connect_to_first_result(void) -{ - int err; - - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, stop_scan_and_connect); - BSIM_ASSERT(!err, "Err bt_le_scan_start %d", err); -} - -void disconnect(void) -{ - int err; - - err = bt_conn_disconnect(g_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - BSIM_ASSERT(!err, "bt_conn_disconnect failed (%d)\n", err); -} - -void set_security(bt_security_t sec) -{ - int err; - - err = bt_conn_set_security(g_conn, sec); - BSIM_ASSERT(!err, "Err bt_conn_set_security %d", err); -} - -void create_adv(struct bt_le_ext_adv **adv) -{ - int err; - struct bt_le_adv_param params = {}; - - params.options |= BT_LE_ADV_OPT_CONNECTABLE; - params.options |= BT_LE_ADV_OPT_EXT_ADV; - - params.id = BT_ID_DEFAULT; - params.sid = 0; - params.interval_min = BT_GAP_ADV_FAST_INT_MIN_2; - params.interval_max = BT_GAP_ADV_FAST_INT_MAX_2; - - err = bt_le_ext_adv_create(¶ms, NULL, adv); - BSIM_ASSERT(!err, "bt_le_ext_adv_create failed (%d)\n", err); -} - -void start_adv(struct bt_le_ext_adv *adv) -{ - int err; - - err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); - BSIM_ASSERT(!err, "bt_le_ext_adv_start failed (%d)\n", err); -} - -void stop_adv(struct bt_le_ext_adv *adv) -{ - int err; - - err = bt_le_ext_adv_stop(adv); - BSIM_ASSERT(!err, "bt_le_ext_adv_stop failed (%d)\n", err); -} - -/* The following flags are raised by events and lowered by test code. */ -DEFINE_FLAG(flag_pairing_complete); -DEFINE_FLAG(flag_bonded); -DEFINE_FLAG(flag_not_bonded); - -void pairing_complete(struct bt_conn *conn, bool bonded) -{ - LOG_DBG("pairing complete"); - SET_FLAG(flag_pairing_complete); - - if (bonded) { - SET_FLAG(flag_bonded); - LOG_DBG("Bonded status: true"); - } else { - SET_FLAG(flag_not_bonded); - LOG_DBG("Bonded status: false"); - } -} - -void pairing_failed(struct bt_conn *conn, enum bt_security_err err) -{ - FAIL("Pairing failed\n"); -} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h deleted file mode 100644 index 5ec34005e9f..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/bs_bt_utils.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "bstests.h" -#include "bs_tracing.h" - -#include -#include - -extern enum bst_result_t bst_result; - -#define DECLARE_FLAG(flag) extern atomic_t flag -#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false -#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) -#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) -#define WAIT_FOR_FLAG(flag) \ - while (!(bool)atomic_get(&flag)) { \ - (void)k_sleep(K_MSEC(1)); \ - } -#define WAIT_FOR_FLAG_UNSET(flag) \ - while ((bool)atomic_get(&flag)) { \ - (void)k_sleep(K_MSEC(1)); \ - } -#define TAKE_FLAG(flag) \ - while (!(bool)atomic_cas(&flag, true, false)) { \ - (void)k_sleep(K_MSEC(1)); \ - } -#define GET_FLAG(flag) (bool)atomic_get(&flag) - -#define BSIM_ASSERT(expr, ...) \ - do { \ - if (!(expr)) { \ - FAIL(__VA_ARGS__); \ - } \ - } while (0) - -#define FAIL(...) \ - do { \ - bst_result = Failed; \ - bs_trace_error_time_line(__VA_ARGS__); \ - } while (0) - -#define PASS(...) \ - do { \ - bst_result = Passed; \ - bs_trace_info_time(1, __VA_ARGS__); \ - } while (0) - -DECLARE_FLAG(flag_pairing_complete); -DECLARE_FLAG(flag_bonded); -DECLARE_FLAG(flag_not_bonded); - -void scan_connect_to_first_result(void); -struct bt_conn *get_g_conn(void); -void clear_g_conn(void); -void disconnect(void); -void wait_connected(void); -void wait_disconnected(void); -void create_adv(struct bt_le_ext_adv **adv); -void start_adv(struct bt_le_ext_adv *adv); -void stop_adv(struct bt_le_ext_adv *adv); -void set_security(bt_security_t sec); -void pairing_complete(struct bt_conn *conn, bool bonded); -void pairing_failed(struct bt_conn *conn, enum bt_security_err err); diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c deleted file mode 100644 index ca45874e9cb..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/central.c +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -LOG_MODULE_REGISTER(test_central, LOG_LEVEL_DBG); - -#include "bs_bt_utils.h" - -DEFINE_FLAG(flag_discovered); -DEFINE_FLAG(flag_subscribed); -DEFINE_FLAG(flag_indicated); - -enum GATT_HANDLES { - SC, - CCC, - NUM_HANDLES, -}; - -static uint16_t gatt_handles[NUM_HANDLES] = {0}; - -static struct bt_gatt_subscribe_params subscribe_params; - -static void sc_subscribed(struct bt_conn *conn, - uint8_t err, - struct bt_gatt_subscribe_params *params) -{ - LOG_DBG("subscribed"); - SET_FLAG(flag_subscribed); -} - -static uint8_t sc_indicated(struct bt_conn *conn, - struct bt_gatt_subscribe_params *params, - const void *data, - uint16_t length) -{ - LOG_DBG("indication received"); - - SET_FLAG(flag_indicated); - - return BT_GATT_ITER_CONTINUE; -} - -static void subscribe(void) -{ - int err; - - subscribe_params.ccc_handle = gatt_handles[CCC]; - subscribe_params.value_handle = gatt_handles[SC]; - subscribe_params.value = BT_GATT_CCC_INDICATE; - subscribe_params.subscribe = sc_subscribed; - subscribe_params.notify = sc_indicated; - - err = bt_gatt_subscribe(get_g_conn(), &subscribe_params); - BSIM_ASSERT(!err, "bt_gatt_subscribe failed (%d)\n", err); - - WAIT_FOR_FLAG(flag_subscribed); -} - -static uint8_t discover_func(struct bt_conn *conn, - const struct bt_gatt_attr *attr, - struct bt_gatt_discover_params *params) -{ - if (attr == NULL) { - for (size_t i = 0U; i < ARRAY_SIZE(gatt_handles); i++) { - LOG_DBG("handle[%d] = 0x%x", i, gatt_handles[i]); - BSIM_ASSERT(gatt_handles[i] != 0, "did not find all handles\n"); - } - - (void)memset(params, 0, sizeof(*params)); - SET_FLAG(flag_discovered); - - return BT_GATT_ITER_STOP; - } - - if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) { - const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; - static const struct bt_uuid_16 ccc_uuid = BT_UUID_INIT_16(BT_UUID_GATT_CCC_VAL); - - if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_SC) == 0) { - int err; - - LOG_DBG("found sc"); - gatt_handles[SC] = chrc->value_handle; - - params->uuid = &ccc_uuid.uuid; - params->start_handle = attr->handle + 2; - params->type = BT_GATT_DISCOVER_DESCRIPTOR; - - err = bt_gatt_discover(conn, params); - BSIM_ASSERT(!err, "bt_gatt_discover failed (%d)\n", err); - - return BT_GATT_ITER_STOP; - } - - } else if (params->type == BT_GATT_DISCOVER_DESCRIPTOR && - bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC) == 0) { - LOG_DBG("found ccc"); - gatt_handles[CCC] = attr->handle; - SET_FLAG(flag_discovered); - - return BT_GATT_ITER_STOP; - } - - return BT_GATT_ITER_CONTINUE; -} - -static void gatt_discover(void) -{ - int err; - static struct bt_gatt_discover_params discover_params; - - discover_params.uuid = NULL; - discover_params.func = discover_func; - discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; - - err = bt_gatt_discover(get_g_conn(), &discover_params); - BSIM_ASSERT(!err, "bt_gatt_discover failed (%d)\n", err); - - WAIT_FOR_FLAG(flag_discovered); - - LOG_DBG("sc handle: %d", gatt_handles[SC]); - LOG_DBG("ccc handle: %d", gatt_handles[CCC]); -} - -void central(void) -{ - /* - * test goal: check that service changed indication is sent on - * reconnection when the server's GATT database has been updated since - * last connection - * - * the central will connect, bond with the peripheral and then - * disconnect after doing that, the central will try to connect again, - * this time it will not elevate the security - * - * to pass the test, the central will wait to receive the service - * changed indication - */ - - int err; - struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { - .pairing_failed = pairing_failed, - .pairing_complete = pairing_complete, - }; - - err = bt_enable(NULL); - BSIM_ASSERT(!err, "bt_enable failed (%d)\n", err); - - err = bt_conn_auth_info_cb_register(&bt_conn_auth_info_cb); - BSIM_ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); - - err = settings_load(); - BSIM_ASSERT(!err, "settings_load failed (%d)\n", err); - - scan_connect_to_first_result(); - wait_connected(); - - set_security(BT_SECURITY_L2); - - TAKE_FLAG(flag_pairing_complete); - TAKE_FLAG(flag_bonded); - - /* subscribe to the service changed indication */ - gatt_discover(); - subscribe(); - - disconnect(); - wait_disconnected(); - clear_g_conn(); - - scan_connect_to_first_result(); - wait_connected(); - - /* wait for service change indication */ - WAIT_FOR_FLAG(flag_indicated); - - PASS("PASS\n"); -} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c deleted file mode 100644 index f5ffbbc4677..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/main.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "bstests.h" -#include "bs_bt_utils.h" - -#define BS_SECONDS_TO_US(dur_sec) ((bs_time_t)dur_sec * USEC_PER_SEC) -#define TEST_TIMEOUT_SIMULATED BS_SECONDS_TO_US(60) - -extern void central(void); -extern void peripheral(void); - -static void test_tick(bs_time_t HW_device_time) -{ - bs_trace_debug_time(0, "Simulation ends now.\n"); - if (bst_result != Passed) { - bst_result = Failed; - bs_trace_error("Test did not pass before simulation ended.\n"); - } -} - -static void test_init(void) -{ - bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); - bst_result = In_progress; -} - -static const struct bst_test_instance test_to_add[] = { - { - .test_id = "central", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = central, - }, - { - .test_id = "peripheral", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = peripheral, - }, - BSTEST_END_MARKER, -}; - -static struct bst_test_list *install(struct bst_test_list *tests) -{ - return bst_add_tests(tests, test_to_add); -}; - -bst_test_install_t test_installers[] = {install, NULL}; - -int main(void) -{ - bst_main(); - return 0; -} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c b/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c deleted file mode 100644 index e15c00b60d7..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/src/peripheral.c +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -LOG_MODULE_REGISTER(test_peripheral, LOG_LEVEL_DBG); - -#include "bs_bt_utils.h" - -#define UUID_1 BT_UUID_DECLARE_128(0xdb, 0x1f, 0xe2, 0x52, 0xf3, 0xc6, 0x43, 0x66, \ - 0xb3, 0x92, 0x5d, 0xc6, 0xe7, 0xc9, 0x59, 0x9d) -#define UUID_2 BT_UUID_DECLARE_128(0x3f, 0xa4, 0x7f, 0x44, 0x2e, 0x2a, 0x43, 0x05, \ - 0xab, 0x38, 0x07, 0x8d, 0x16, 0xbf, 0x99, 0xf1) - -static void new_svc_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) -{ - ARG_UNUSED(attr); - - bool notif_enabled = (value == BT_GATT_CCC_NOTIFY); - - LOG_DBG("CCC Update: notification %s", notif_enabled ? "enabled" : "disabled"); -} - -static struct bt_gatt_attr attrs[] = { - BT_GATT_PRIMARY_SERVICE(UUID_1), - BT_GATT_CHARACTERISTIC(UUID_2, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, NULL, NULL, NULL), - BT_GATT_CCC(new_svc_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), -}; - -static struct bt_gatt_service svc = { - .attrs = attrs, - .attr_count = ARRAY_SIZE(attrs), -}; - -void peripheral(void) -{ - /* - * test goal: check that service changed indication is sent on - * reconnection when the server's GATT database has been updated since - * last connection - * - * the peripheral will wait for connection/disconnection, when - * disconnected it will register a new service, when reconnecting, the - * central should receive an indication - */ - - int err; - struct bt_le_ext_adv *adv = NULL; - - err = bt_enable(NULL); - BSIM_ASSERT(!err, "bt_enable failed (%d)\n", err); - - err = settings_load(); - BSIM_ASSERT(!err, "settings_load failed (%d)\n", err); - - create_adv(&adv); - start_adv(adv); - wait_connected(); - - stop_adv(adv); - - wait_disconnected(); - clear_g_conn(); - - /* add a new service to trigger the service changed indication */ - err = bt_gatt_service_register(&svc); - BSIM_ASSERT(!err, "bt_gatt_service_register failed (%d)\n", err); - LOG_DBG("New service added"); - - start_adv(adv); - wait_connected(); - - PASS("Done\n"); -} diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh deleted file mode 100755 index b07577a9878..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/_compile.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/env bash -# Copyright 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -set -eu - -# Terminate running simulations (if any) -${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh - -test_name='sc_indicate' - -: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}" -bsim_bin="${BSIM_OUT_PATH}/bin" -BOARD="${BOARD:-nrf52_bsim}" -test_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_gatt_${test_name}_prj_conf" - -west build -b nrf52_bsim -d build && \ - cp -v build/zephyr/zephyr.exe "${test_exe}" diff --git a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh b/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh deleted file mode 100755 index b46ae13929c..00000000000 --- a/tests/bsim/bluetooth/host/gatt/sc_indicate/test_scripts/sc_indicate.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/env bash -# Copyright 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -source ${ZEPHYR_BASE}/tests/bsim/sh_common.source - -test_name='sc_indicate' -test_exe="bs_${BOARD}_tests_bsim_bluetooth_host_gatt_${test_name}_prj_conf" -simulation_id="${test_name}" -verbosity_level=2 -EXECUTE_TIMEOUT=30 - -cd ${BSIM_OUT_PATH}/bin - -Execute "./${test_exe}" \ - -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central - -Execute "./${test_exe}" \ - -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral - -Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=60e6 - -wait_for_background_jobs From e338ab04c804894e86a514411d74acd28aca582d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:17 +0000 Subject: [PATCH 4253/4498] Revert "[nrf fromtree] modules: openthread: fix unused variable during `otPlatCryptoInit`" This reverts commit f25764149e1e0ce62254cd1759909641077becb5. Signed-off-by: Dominik Ermel --- modules/openthread/platform/crypto_psa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index e5b234ce030..e61177ef4c4 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -137,8 +137,9 @@ void otPlatCryptoInit(void) * PSA with emulated TFM, Settings have to be initialized at the end of otPlatCryptoInit(), * to be available before storing Network Key. */ - __ASSERT_EVAL((void) settings_subsys_init(), int err = settings_subsys_init(), - !err, "Failed to initialize settings"); + int err = settings_subsys_init(); + + __ASSERT(!err, "Failed to initialize settings"); #endif } From fe0980d798a12acce810f0ed4f1e7af76154b48f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:17 +0000 Subject: [PATCH 4254/4498] Revert "[nrf fromtree] doc: migration-guide: inform about GPIO_AS_PINRESET deprecation" This reverts commit 532564650101b3c9a9ccbde8ceb3afe4973fc096. Signed-off-by: Dominik Ermel --- doc/releases/migration-guide-3.5.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 8c059b630c6..3f367ec5e35 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -53,14 +53,3 @@ Recommended Changes &uicr { nfct-pins-as-gpios; }; - -* Nordic nRF based boards using :kconfig:option:`CONFIG_GPIO_AS_PINRESET` - to configure reset GPIO as nRESET, should instead set the new UICR - ``gpio-as-nreset`` property in devicetree. It can be set like this in the - board devicetree files: - - .. code-block:: devicetree - - &uicr { - gpio-as-nreset; - }; From 2a60290acacd15d1af864946f3d475a558fb5a94 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:17 +0000 Subject: [PATCH 4255/4498] Revert "[nrf fromtree] boards: arm: nrf-based: remove redundant GPIO_AS_PINRESET=n" This reverts commit 12bfbfc7d6751e17c63cf190e8bce8eac056c29f. Signed-off-by: Dominik Ermel --- boards/arm/holyiot_yj16019/Kconfig.defconfig | 3 +++ boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/boards/arm/holyiot_yj16019/Kconfig.defconfig b/boards/arm/holyiot_yj16019/Kconfig.defconfig index de2d63ad7c8..99373ad286a 100644 --- a/boards/arm/holyiot_yj16019/Kconfig.defconfig +++ b/boards/arm/holyiot_yj16019/Kconfig.defconfig @@ -8,6 +8,9 @@ if BOARD_HOLYIOT_YJ16019 config BOARD default "holyiot_yj16019" +config GPIO_AS_PINRESET + default n + config BT_CTLR default BT diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig index 7e28dde8423..bd247788458 100644 --- a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig @@ -14,4 +14,8 @@ CONFIG_USE_SEGGER_RTT=y # Enable GPIO CONFIG_GPIO=y +# additional board options +# set y to disable R button +CONFIG_GPIO_AS_PINRESET=n + CONFIG_PINCTRL=y From 4c50091fb262b1fbe7974c019416622f5a6e6875 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:18 +0000 Subject: [PATCH 4256/4498] Revert "[nrf fromtree] soc: arm: nordic_nrf: nrf52: deprecate GPIO_AS_PINRESET" This reverts commit 4c425de49697cf8629615c7f7b25feee45180cf6. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf52/Kconfig.soc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index b2a915f168e..13a2fef932b 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -94,15 +94,8 @@ config SOC_DCDC_NRF52X_HV Enable nRF52 series System on Chip High Voltage DC/DC converter. config GPIO_AS_PINRESET - bool "[DEPRECATED] GPIO as pin reset (reset button)" - select DEPRECATED - help - This option is deprecated, use devicetree instead. Example - configuration: - - &uicr { - gpio-as-nreset; - }; + bool "GPIO as pin reset (reset button)" + default y config NRF_ENABLE_ICACHE bool "The instruction cache (I-Cache)" From eaa563167f6a66a38d0dba1320782ef92d36c7ae Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:18 +0000 Subject: [PATCH 4257/4498] Revert "[nrf fromtree] boards: arm: nrf9160dk_nrf52840: use UICR gpio-as-nreset property" This reverts commit 11cbd4dd27bdabd5191901422a694a273a4afc53. Signed-off-by: Dominik Ermel --- boards/arm/nrf9160dk_nrf52840/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/nrf9160dk_nrf52840/board.c b/boards/arm/nrf9160dk_nrf52840/board.c index cdf00f8f3dd..e01b8eb64e7 100644 --- a/boards/arm/nrf9160dk_nrf52840/board.c +++ b/boards/arm/nrf9160dk_nrf52840/board.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_NRF9160DK_LOG_LEVEL); * exposes the nRESET function (P0.18 in nRF52840), there is no need to * provide any additional GPIO configuration for it. */ -#define RESET_INPUT_IS_PINRESET (DT_PROP(DT_NODELABEL(uicr), gpio_as_nreset) && \ +#define RESET_INPUT_IS_PINRESET (IS_ENABLED(CONFIG_GPIO_AS_PINRESET) && \ GET_PORT(reset_input, gpios, 0) == 0 && \ GET_PIN(reset_input, gpios, 0) == 18) #define USE_RESET_GPIO \ From 7256dd505911f6a4eda7b15e6133047b48496c2a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:18 +0000 Subject: [PATCH 4258/4498] Revert "[nrf fromtree] boards: arm: nrf-based: move all boards to gpio-as-nreset dt property" This reverts commit 8c4003eacd144e0d1e593dd333d5bfa6c7a4d473. Signed-off-by: Dominik Ermel --- boards/arm/96b_nitrogen/96b_nitrogen.dts | 4 ---- boards/arm/96b_nitrogen/96b_nitrogen_defconfig | 3 +++ boards/arm/acn52832/acn52832.dts | 4 ---- boards/arm/acn52832/acn52832_defconfig | 3 +++ .../adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts | 4 ---- .../adafruit_feather_nrf52840_defconfig | 3 +++ .../adafruit_itsybitsy_nrf52840.dts | 4 ---- .../adafruit_itsybitsy_nrf52840_defconfig | 2 ++ .../arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi | 4 ---- boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig | 3 +++ .../arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig | 3 +++ boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts | 4 ---- .../arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig | 3 +++ boards/arm/bl652_dvk/bl652_dvk.dts | 4 ---- boards/arm/bl652_dvk/bl652_dvk_defconfig | 3 +++ boards/arm/bl653_dvk/bl653_dvk.dts | 4 ---- boards/arm/bl653_dvk/bl653_dvk_defconfig | 3 +++ boards/arm/bl654_dvk/bl654_dvk.dts | 4 ---- boards/arm/bl654_dvk/bl654_dvk_defconfig | 3 +++ boards/arm/bl654_sensor_board/bl654_sensor_board.dts | 4 ---- boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig | 3 +++ boards/arm/bl654_usb/bl654_usb.dts | 4 ---- boards/arm/bl654_usb/bl654_usb_defconfig | 3 +++ .../blueclover_plt_demo_v2_nrf52832.dts | 4 ---- .../blueclover_plt_demo_v2_nrf52832_defconfig | 3 +++ boards/arm/bt510/bt510.dts | 4 ---- boards/arm/bt510/bt510_defconfig | 3 +++ boards/arm/bt610/bt610.dts | 1 - boards/arm/bt610/bt610_defconfig | 3 +++ .../contextualelectronics_abc/contextualelectronics_abc.dts | 4 ---- .../contextualelectronics_abc_defconfig | 3 +++ boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts | 4 ---- .../arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig | 3 +++ boards/arm/degu_evk/degu_evk.dts | 4 ---- boards/arm/degu_evk/degu_evk_defconfig | 1 + boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts | 4 ---- .../ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig | 3 +++ boards/arm/mg100/mg100.dts | 4 ---- boards/arm/mg100/mg100_defconfig | 3 +++ boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts | 4 ---- boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig | 3 +++ boards/arm/nrf52832_mdk/nrf52832_mdk.dts | 4 ---- boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig | 3 +++ boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts | 4 ---- boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig | 3 +++ boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts | 4 ---- boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig | 3 +++ boards/arm/nrf52840_blip/nrf52840_blip.dts | 4 ---- boards/arm/nrf52840_blip/nrf52840_blip_defconfig | 3 +++ boards/arm/nrf52840_mdk/nrf52840_mdk.dts | 4 ---- boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig | 3 +++ .../arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts | 1 - .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig | 3 +++ boards/arm/nrf52840_papyr/nrf52840_papyr.dts | 4 ---- boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig | 3 +++ boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts | 4 ---- boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig | 3 +++ boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts | 4 ---- boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig | 3 +++ .../arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts | 1 - .../nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig | 3 +++ boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts | 4 ---- .../nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig | 3 +++ boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts | 4 ---- boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig | 3 +++ boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts | 4 ---- boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig | 3 +++ boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts | 4 ---- boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig | 3 +++ boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts | 4 ---- boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig | 3 +++ boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts | 4 ---- boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig | 3 +++ boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts | 4 ---- boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig | 3 +++ boards/arm/pan1770_evb/pan1770_evb.dts | 4 ---- boards/arm/pan1770_evb/pan1770_evb_defconfig | 3 +++ boards/arm/pan1780_evb/pan1780_evb.dts | 4 ---- boards/arm/pan1780_evb/pan1780_evb_defconfig | 3 +++ boards/arm/pan1781_evb/pan1781_evb.dts | 4 ---- boards/arm/pan1781_evb/pan1781_evb_defconfig | 3 +++ boards/arm/pan1782_evb/pan1782_evb.dts | 4 ---- boards/arm/pan1782_evb/pan1782_evb_defconfig | 3 +++ boards/arm/particle_argon/particle_argon.dts | 4 ---- boards/arm/particle_argon/particle_argon_defconfig | 3 +++ boards/arm/particle_boron/particle_boron.dts | 4 ---- boards/arm/particle_boron/particle_boron_defconfig | 3 +++ boards/arm/particle_xenon/particle_xenon.dts | 4 ---- boards/arm/particle_xenon/particle_xenon_defconfig | 3 +++ boards/arm/pinetime_devkit0/pinetime_devkit0.dts | 4 ---- boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig | 3 +++ boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts | 4 ---- boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig | 3 +++ boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts | 4 ---- boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig | 3 +++ .../raytac_mdbt50q_db_33_nrf52833.dts | 4 ---- .../raytac_mdbt50q_db_33_nrf52833_defconfig | 3 +++ .../raytac_mdbt50q_db_40_nrf52840.dts | 4 ---- .../raytac_mdbt50q_db_40_nrf52840_defconfig | 3 +++ boards/arm/reel_board/dts/reel_board.dtsi | 4 ---- boards/arm/reel_board/reel_board_defconfig | 3 +++ boards/arm/reel_board/reel_board_v2_defconfig | 3 +++ .../arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts | 4 ---- .../ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig | 3 +++ .../arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts | 4 ---- .../ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig | 3 +++ .../arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts | 4 ---- .../ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig | 3 +++ .../arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts | 4 ---- .../ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig | 3 +++ .../arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts | 4 ---- .../ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig | 3 +++ .../arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts | 4 ---- .../ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig | 3 +++ boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts | 4 ---- .../ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig | 3 +++ boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts | 4 ---- .../ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig | 3 +++ boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts | 4 ---- .../ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig | 3 +++ boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts | 4 ---- .../ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig | 3 +++ boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts | 4 ---- .../we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig | 3 +++ boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts | 4 ---- .../we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig | 3 +++ boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts | 4 ---- .../we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig | 3 +++ boards/arm/xiao_ble/xiao_ble_common.dtsi | 4 ---- boards/arm/xiao_ble/xiao_ble_defconfig | 3 +++ boards/arm/xiao_ble/xiao_ble_sense_defconfig | 3 +++ 131 files changed, 198 insertions(+), 247 deletions(-) diff --git a/boards/arm/96b_nitrogen/96b_nitrogen.dts b/boards/arm/96b_nitrogen/96b_nitrogen.dts index 69148a032d7..d5bac1cd6d3 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen.dts +++ b/boards/arm/96b_nitrogen/96b_nitrogen.dts @@ -58,10 +58,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig index e804b43da5c..500c469813b 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen_defconfig +++ b/boards/arm/96b_nitrogen/96b_nitrogen_defconfig @@ -16,4 +16,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/acn52832/acn52832.dts b/boards/arm/acn52832/acn52832.dts index ca9f5046fba..1e01221f652 100644 --- a/boards/arm/acn52832/acn52832.dts +++ b/boards/arm/acn52832/acn52832.dts @@ -45,10 +45,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/acn52832/acn52832_defconfig b/boards/arm/acn52832/acn52832_defconfig index 2bb13882f8c..6b1ae1a7ba7 100644 --- a/boards/arm/acn52832/acn52832_defconfig +++ b/boards/arm/acn52832/acn52832_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Enable P0_21 as RST +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts index 284a4d24542..5024f43fd81 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts @@ -61,10 +61,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig index 1f42d1a0aa4..8d892db30f2 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts index 103e18d8328..6e827388aef 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840.dts @@ -55,10 +55,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig index e5a88c27fb3..bc27efcdd29 100644 --- a/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig +++ b/boards/arm/adafruit_itsybitsy_nrf52840/adafruit_itsybitsy_nrf52840_defconfig @@ -17,6 +17,8 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y CONFIG_PINCTRL=y # Flashing diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi index 200db7f94c7..60c0d63920c 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi @@ -177,10 +177,6 @@ arduino_spi: &spi2 { pinctrl-names = "default", "sleep"; }; -&uicr { - gpio-as-nreset; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig index dcdc0c8a836..2d91725aaf9 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_defconfig @@ -20,4 +20,7 @@ CONFIG_UART_CONSOLE=y CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig index 4604c6bf386..8ef8ece861c 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble_sense_defconfig @@ -20,4 +20,7 @@ CONFIG_UART_CONSOLE=y CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_LEGACY=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts index 2329853a1a3..ada4c76441c 100644 --- a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts +++ b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me.dts @@ -45,10 +45,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig index c2f2b95cc72..396d37d36e0 100644 --- a/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig +++ b/boards/arm/arduino_nicla_sense_me/arduino_nicla_sense_me_defconfig @@ -18,5 +18,8 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # enable pin controller CONFIG_PINCTRL=y diff --git a/boards/arm/bl652_dvk/bl652_dvk.dts b/boards/arm/bl652_dvk/bl652_dvk.dts index f2cffbd819b..5569f1323c0 100644 --- a/boards/arm/bl652_dvk/bl652_dvk.dts +++ b/boards/arm/bl652_dvk/bl652_dvk.dts @@ -68,10 +68,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/bl652_dvk/bl652_dvk_defconfig b/boards/arm/bl652_dvk/bl652_dvk_defconfig index 5302fa8d53f..1ca971e2546 100644 --- a/boards/arm/bl652_dvk/bl652_dvk_defconfig +++ b/boards/arm/bl652_dvk/bl652_dvk_defconfig @@ -21,6 +21,9 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl653_dvk/bl653_dvk.dts b/boards/arm/bl653_dvk/bl653_dvk.dts index ba8fa3658d2..ceb91aeb96f 100644 --- a/boards/arm/bl653_dvk/bl653_dvk.dts +++ b/boards/arm/bl653_dvk/bl653_dvk.dts @@ -91,10 +91,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/bl653_dvk/bl653_dvk_defconfig b/boards/arm/bl653_dvk/bl653_dvk_defconfig index 83b73ef4435..4933055c93c 100644 --- a/boards/arm/bl653_dvk/bl653_dvk_defconfig +++ b/boards/arm/bl653_dvk/bl653_dvk_defconfig @@ -20,6 +20,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl654_dvk/bl654_dvk.dts b/boards/arm/bl654_dvk/bl654_dvk.dts index 7ede69427de..b99435696d1 100644 --- a/boards/arm/bl654_dvk/bl654_dvk.dts +++ b/boards/arm/bl654_dvk/bl654_dvk.dts @@ -91,10 +91,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/bl654_dvk/bl654_dvk_defconfig b/boards/arm/bl654_dvk/bl654_dvk_defconfig index 976495f7e88..aa2238cda87 100644 --- a/boards/arm/bl654_dvk/bl654_dvk_defconfig +++ b/boards/arm/bl654_dvk/bl654_dvk_defconfig @@ -21,6 +21,9 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32kHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board.dts b/boards/arm/bl654_sensor_board/bl654_sensor_board.dts index c43354f2705..1c2949ee2e8 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board.dts +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board.dts @@ -56,10 +56,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig index e92c2c4005f..259fac9d309 100644 --- a/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig +++ b/boards/arm/bl654_sensor_board/bl654_sensor_board_defconfig @@ -17,6 +17,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/bl654_usb/bl654_usb.dts b/boards/arm/bl654_usb/bl654_usb.dts index 80600290dbf..2cc6850a468 100644 --- a/boards/arm/bl654_usb/bl654_usb.dts +++ b/boards/arm/bl654_usb/bl654_usb.dts @@ -47,10 +47,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/bl654_usb/bl654_usb_defconfig b/boards/arm/bl654_usb/bl654_usb_defconfig index 983150c35d9..59c26ddb4d7 100644 --- a/boards/arm/bl654_usb/bl654_usb_defconfig +++ b/boards/arm/bl654_usb/bl654_usb_defconfig @@ -19,6 +19,9 @@ CONFIG_GPIO=y # Enable USB CONFIG_USB_DEVICE_STACK=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts index 4c49979bb0a..cf7dd7a52de 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832.dts @@ -48,10 +48,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status ="okay"; }; diff --git a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig index 301a23af362..52f089ba0d6 100644 --- a/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig +++ b/boards/arm/blueclover_plt_demo_v2_nrf52832/blueclover_plt_demo_v2_nrf52832_defconfig @@ -24,4 +24,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/bt510/bt510.dts b/boards/arm/bt510/bt510.dts index 984b098e5d5..74818be0d7c 100644 --- a/boards/arm/bt510/bt510.dts +++ b/boards/arm/bt510/bt510.dts @@ -72,10 +72,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/bt510/bt510_defconfig b/boards/arm/bt510/bt510_defconfig index eb769cc9465..fd86ea3f0f2 100644 --- a/boards/arm/bt510/bt510_defconfig +++ b/boards/arm/bt510/bt510_defconfig @@ -17,6 +17,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/bt610/bt610.dts b/boards/arm/bt610/bt610.dts index 489401a5fb3..6bbe8d57fe3 100644 --- a/boards/arm/bt610/bt610.dts +++ b/boards/arm/bt610/bt610.dts @@ -145,7 +145,6 @@ &uicr { nfct-pins-as-gpios; - gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/bt610/bt610_defconfig b/boards/arm/bt610/bt610_defconfig index d1d7226fade..1c77ed9e37b 100644 --- a/boards/arm/bt610/bt610_defconfig +++ b/boards/arm/bt610/bt610_defconfig @@ -17,6 +17,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts index 6f60b1ddfed..ebc866afeff 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc.dts @@ -25,10 +25,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig index 7a3055b9c82..bb841469339 100644 --- a/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig +++ b/boards/arm/contextualelectronics_abc/contextualelectronics_abc_defconfig @@ -20,4 +20,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts index a1c415fc299..75510faf4a6 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts @@ -84,10 +84,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig index 4cb6022e7ae..89d31bfd45b 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev_defconfig @@ -21,4 +21,7 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_RTT_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/degu_evk/degu_evk.dts b/boards/arm/degu_evk/degu_evk.dts index eb3329726e9..caa134752e0 100644 --- a/boards/arm/degu_evk/degu_evk.dts +++ b/boards/arm/degu_evk/degu_evk.dts @@ -92,10 +92,6 @@ status ="okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status ="okay"; }; diff --git a/boards/arm/degu_evk/degu_evk_defconfig b/boards/arm/degu_evk/degu_evk_defconfig index e003438c3dc..7b9d7737481 100644 --- a/boards/arm/degu_evk/degu_evk_defconfig +++ b/boards/arm/degu_evk/degu_evk_defconfig @@ -17,6 +17,7 @@ CONFIG_USB_DEVICE_STACK=y # additional board options CONFIG_GPIO=y +CONFIG_GPIO_AS_PINRESET=y # required to enable 3V3 power rail and Vin1 monitor CONFIG_REGULATOR=y diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts index 31eb0cc7524..9fa240cb5ae 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts +++ b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832.dts @@ -75,10 +75,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig index 05acf2ca945..3e1778de525 100644 --- a/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig +++ b/boards/arm/ebyte_e73_tbb_nrf52832/ebyte_e73_tbb_nrf52832_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/mg100/mg100.dts b/boards/arm/mg100/mg100.dts index 0d33fd32151..512ca901010 100644 --- a/boards/arm/mg100/mg100.dts +++ b/boards/arm/mg100/mg100.dts @@ -65,10 +65,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/mg100/mg100_defconfig b/boards/arm/mg100/mg100_defconfig index bb7d09dabf2..93f55f3d0a4 100644 --- a/boards/arm/mg100/mg100_defconfig +++ b/boards/arm/mg100/mg100_defconfig @@ -18,6 +18,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts index af0ea59794c..077eb4a1657 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts @@ -150,10 +150,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig index af230adb18a..56d8497b43a 100644 --- a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts index c51002c6497..348a5b79745 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts @@ -86,10 +86,6 @@ }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig index 8993b59f938..2c283bda97e 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts index 4942dd6daa0..f70d6649aa8 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts @@ -99,10 +99,6 @@ clock-prescaler = <8>; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig index 9ef66860ab3..9bbc4da98cb 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts index b488b5d1ff3..0d1725d5bbb 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts @@ -127,10 +127,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig index 9cbee72b2e7..7fe9f4e480c 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_blip/nrf52840_blip.dts b/boards/arm/nrf52840_blip/nrf52840_blip.dts index e641c60bd1f..112d22799bc 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip.dts +++ b/boards/arm/nrf52840_blip/nrf52840_blip.dts @@ -66,10 +66,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig index 811a88de939..82c0146ecf1 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip_defconfig +++ b/boards/arm/nrf52840_blip/nrf52840_blip_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts index 2439b0c2aca..0ed4addb069 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts @@ -90,10 +90,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig index e4c79a2bf88..f0ed2a2fbad 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts index 4e13783d656..8e835597c78 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts @@ -89,7 +89,6 @@ &uicr { nfct-pins-as-gpios; - gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index 8701863e99a..90850c10e0a 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -13,4 +13,7 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts index 0a9d8ff4724..acbb09d2df2 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts @@ -85,10 +85,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig index 4a5e737cd14..0ad48d7f940 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts index a53a174be15..eb99beca22f 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts @@ -97,10 +97,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig index 2c6b7f2fc82..36553a757eb 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig @@ -22,6 +22,9 @@ CONFIG_UART_CONSOLE=y # enable GPIO CONFIG_GPIO=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # Bluetooth not enabled by default on nRF52811 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index 96006ec4722..ba5d94738a6 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -139,10 +139,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig index 9f1232a8f0a..100d91ed320 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts index dcf9fb690d1..93b59baa920 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts @@ -101,7 +101,6 @@ &uicr { nfct-pins-as-gpios; - gpio-as-nreset; }; &gpio0 { diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index c367a90d5ef..32a9d03b44e 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -13,6 +13,9 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y # Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts index c29ca8000dc..4412d3c492d 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts @@ -70,10 +70,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig index 19aaa3825d1..42948633b2f 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts index 60de01f0bb0..618bd670ad1 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts @@ -50,10 +50,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig index 2a21dc07192..944fc20b9c8 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Enable P0_21 as RST +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts b/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts index b622a1a23ea..8b276c5fed7 100644 --- a/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts +++ b/boards/arm/nrf52_vbluno52/nrf52_vbluno52.dts @@ -49,10 +49,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig index fac5419e6f6..97f4efbc236 100644 --- a/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig +++ b/boards/arm/nrf52_vbluno52/nrf52_vbluno52_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts index e0eaa911a06..29257e7a0b2 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts @@ -89,10 +89,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig index 6e275e63f35..31571f10fb4 100644 --- a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig @@ -20,6 +20,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # Bluetooth not enabled by default on nRF52805 due to RAM limitations when # running the default set of kernel tests. diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts index 4d4600f1222..823a3db7f7e 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts @@ -91,10 +91,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig index 93706e89d0a..5873f1d2e9a 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig @@ -20,6 +20,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # Bluetooth not enabled by default on nRF52810 due to RAM limitations when # running the default set of kernel tests. # Enable this on your prj.conf to include Bluetooth support diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts index 687bba9254a..3002a1841c9 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts @@ -138,10 +138,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig index 23e1f4c249a..547ff67c348 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts index 07dc648b853..c8cc706750c 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts @@ -141,10 +141,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig index 073409dbba1..c15e39669ea 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/pan1770_evb/pan1770_evb.dts b/boards/arm/pan1770_evb/pan1770_evb.dts index 2b2a9d561a7..d8fbe8fe9df 100644 --- a/boards/arm/pan1770_evb/pan1770_evb.dts +++ b/boards/arm/pan1770_evb/pan1770_evb.dts @@ -137,10 +137,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1770_evb/pan1770_evb_defconfig b/boards/arm/pan1770_evb/pan1770_evb_defconfig index 1d90cb82c25..1192aca064e 100644 --- a/boards/arm/pan1770_evb/pan1770_evb_defconfig +++ b/boards/arm/pan1770_evb/pan1770_evb_defconfig @@ -26,5 +26,8 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1780_evb/pan1780_evb.dts b/boards/arm/pan1780_evb/pan1780_evb.dts index da9a7e7fdb8..4f4dbca98ac 100644 --- a/boards/arm/pan1780_evb/pan1780_evb.dts +++ b/boards/arm/pan1780_evb/pan1780_evb.dts @@ -137,10 +137,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1780_evb/pan1780_evb_defconfig b/boards/arm/pan1780_evb/pan1780_evb_defconfig index ca1a58c3b74..0c459f39aac 100644 --- a/boards/arm/pan1780_evb/pan1780_evb_defconfig +++ b/boards/arm/pan1780_evb/pan1780_evb_defconfig @@ -26,5 +26,8 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1781_evb/pan1781_evb.dts b/boards/arm/pan1781_evb/pan1781_evb.dts index 8ab6af51ea9..7d9b7028e35 100644 --- a/boards/arm/pan1781_evb/pan1781_evb.dts +++ b/boards/arm/pan1781_evb/pan1781_evb.dts @@ -98,10 +98,6 @@ clock-prescaler = <8>; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1781_evb/pan1781_evb_defconfig b/boards/arm/pan1781_evb/pan1781_evb_defconfig index dacffd42175..76436dd2ccd 100644 --- a/boards/arm/pan1781_evb/pan1781_evb_defconfig +++ b/boards/arm/pan1781_evb/pan1781_evb_defconfig @@ -26,5 +26,8 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/pan1782_evb/pan1782_evb.dts b/boards/arm/pan1782_evb/pan1782_evb.dts index fdc86f792ec..cf169e41d87 100644 --- a/boards/arm/pan1782_evb/pan1782_evb.dts +++ b/boards/arm/pan1782_evb/pan1782_evb.dts @@ -98,10 +98,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/pan1782_evb/pan1782_evb_defconfig b/boards/arm/pan1782_evb/pan1782_evb_defconfig index e6a6cc1d4a5..0bdeb9d9127 100644 --- a/boards/arm/pan1782_evb/pan1782_evb_defconfig +++ b/boards/arm/pan1782_evb/pan1782_evb_defconfig @@ -26,6 +26,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # using pinctrl CONFIG_PINCTRL=y diff --git a/boards/arm/particle_argon/particle_argon.dts b/boards/arm/particle_argon/particle_argon.dts index a88199fe40b..fa2314b6fb2 100644 --- a/boards/arm/particle_argon/particle_argon.dts +++ b/boards/arm/particle_argon/particle_argon.dts @@ -32,10 +32,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &uart1 { /* ESP32 */ compatible = "nordic,nrf-uarte"; current-speed = <921600>; diff --git a/boards/arm/particle_argon/particle_argon_defconfig b/boards/arm/particle_argon/particle_argon_defconfig index c29f62babd4..784364e9edc 100644 --- a/boards/arm/particle_argon/particle_argon_defconfig +++ b/boards/arm/particle_argon/particle_argon_defconfig @@ -21,4 +21,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/particle_boron/particle_boron.dts b/boards/arm/particle_boron/particle_boron.dts index 06e75a5a52e..3e20eddb94f 100644 --- a/boards/arm/particle_boron/particle_boron.dts +++ b/boards/arm/particle_boron/particle_boron.dts @@ -36,10 +36,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &i2c1 { /* power monitoring */ compatible = "nordic,nrf-twi"; status = "okay"; diff --git a/boards/arm/particle_boron/particle_boron_defconfig b/boards/arm/particle_boron/particle_boron_defconfig index 622a3169073..6963e9d9393 100644 --- a/boards/arm/particle_boron/particle_boron_defconfig +++ b/boards/arm/particle_boron/particle_boron_defconfig @@ -20,6 +20,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y # Fix the priority to enable the modem line's serial buffer diff --git a/boards/arm/particle_xenon/particle_xenon.dts b/boards/arm/particle_xenon/particle_xenon.dts index 2d64ba119b2..22252c077f3 100644 --- a/boards/arm/particle_xenon/particle_xenon.dts +++ b/boards/arm/particle_xenon/particle_xenon.dts @@ -33,10 +33,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &uart1 { /* feather UART2 */ compatible = "nordic,nrf-uarte"; current-speed = <115200>; diff --git a/boards/arm/particle_xenon/particle_xenon_defconfig b/boards/arm/particle_xenon/particle_xenon_defconfig index 2495d886b41..5f90beabba0 100644 --- a/boards/arm/particle_xenon/particle_xenon_defconfig +++ b/boards/arm/particle_xenon/particle_xenon_defconfig @@ -20,4 +20,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts index 207c8934880..fb377fd89e1 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts @@ -83,10 +83,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig index fc8f45eceaa..ad7442afe0d 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -13,4 +13,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# use P0.21 as RST +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts index 19f9e6ff41e..62664e67b5e 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts @@ -88,10 +88,6 @@ status ="okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status ="okay"; }; diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig index 010c72e8c07..7f11757ab5d 100644 --- a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig @@ -22,6 +22,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts index 454c4bb84b1..43b2dd0de28 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840.dts @@ -48,10 +48,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig index 4cc2863efab..80da4e05041 100644 --- a/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig +++ b/boards/arm/rak4631_nrf52840/rak4631_nrf52840_defconfig @@ -22,4 +22,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts index a3ada26e811..6a530e687f6 100644 --- a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts +++ b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833.dts @@ -93,10 +93,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig index 1212ba8928f..7ed9a1ffe8b 100644 --- a/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig +++ b/boards/arm/raytac_mdbt50q_db_33_nrf52833/raytac_mdbt50q_db_33_nrf52833_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts index bd1a2f06855..2414b8ea517 100644 --- a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts +++ b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840.dts @@ -93,10 +93,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig index 438343c6d9b..973b83c9d62 100644 --- a/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig +++ b/boards/arm/raytac_mdbt50q_db_40_nrf52840/raytac_mdbt50q_db_40_nrf52840_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/dts/reel_board.dtsi b/boards/arm/reel_board/dts/reel_board.dtsi index 028a5d86a78..6289cf0ec6d 100644 --- a/boards/arm/reel_board/dts/reel_board.dtsi +++ b/boards/arm/reel_board/dts/reel_board.dtsi @@ -94,10 +94,6 @@ }; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/reel_board/reel_board_defconfig b/boards/arm/reel_board/reel_board_defconfig index 850506692ba..7ec7b36871b 100644 --- a/boards/arm/reel_board/reel_board_defconfig +++ b/boards/arm/reel_board/reel_board_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/reel_board/reel_board_v2_defconfig b/boards/arm/reel_board/reel_board_v2_defconfig index 2ac0610f78c..a7f80f970e8 100644 --- a/boards/arm/reel_board/reel_board_v2_defconfig +++ b/boards/arm/reel_board/reel_board_v2_defconfig @@ -17,4 +17,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts index 9594b760488..a248d8f650e 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832.dts @@ -137,10 +137,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig index 801393790fe..769e28f5846 100644 --- a/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig +++ b/boards/arm/ubx_bmd300eval_nrf52832/ubx_bmd300eval_nrf52832_defconfig @@ -23,4 +23,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts index c65221eb38c..5afd4960694 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810.dts @@ -137,10 +137,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig index 4f8a5c5a8da..6fd69454784 100644 --- a/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig +++ b/boards/arm/ubx_bmd330eval_nrf52810/ubx_bmd330eval_nrf52810_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts index 070730c69d2..f7fbee05909 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840.dts @@ -136,10 +136,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig index 37271c2ce81..4a1d3a6075c 100644 --- a/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd340eval_nrf52840/ubx_bmd340eval_nrf52840_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts index 68b3755123b..2db4e005b04 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts @@ -152,10 +152,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig index 4a35f6e612f..6a6d80f1b2b 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts index 5b8679cc065..842c882ac7f 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811.dts @@ -137,10 +137,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig index 7a63bc69bf2..b2996dba82d 100644 --- a/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig +++ b/boards/arm/ubx_bmd360eval_nrf52811/ubx_bmd360eval_nrf52811_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts index d7a21c98b44..1c4623b52fe 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840.dts @@ -97,10 +97,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig index c20dc6fe9f3..d0a583edbe8 100644 --- a/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd380eval_nrf52840/ubx_bmd380eval_nrf52840_defconfig @@ -27,4 +27,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts index 2c0f051d25f..b183b17bc41 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832.dts @@ -133,10 +133,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig index 93127beefef..4a289cc2597 100644 --- a/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkannab1_nrf52832/ubx_evkannab1_nrf52832_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts index 849c96c5e6f..691705b3a91 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832.dts @@ -133,10 +133,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig index b44e54e3d18..b7064633b25 100644 --- a/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig +++ b/boards/arm/ubx_evkninab1_nrf52832/ubx_evkninab1_nrf52832_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts index 5e15c5cc232..19b4e25a5af 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840.dts @@ -129,10 +129,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig index f9cabe94b4a..ca03d00a8e7 100644 --- a/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig +++ b/boards/arm/ubx_evkninab3_nrf52840/ubx_evkninab3_nrf52840_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts index 521f9f6aa9e..783d69b4788 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833.dts @@ -134,10 +134,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig index c06ad795868..96d99738526 100644 --- a/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig +++ b/boards/arm/ubx_evkninab4_nrf52833/ubx_evkninab4_nrf52833_defconfig @@ -26,4 +26,7 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts index 4d7c3d8cc0b..b9b9bfcedb2 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805.dts @@ -61,10 +61,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig index 88c4ddb2023..d1a44910ced 100644 --- a/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig +++ b/boards/arm/we_ophelia1ev_nrf52805/we_ophelia1ev_nrf52805_defconfig @@ -21,6 +21,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts index ef7eede1f75..4cd193c4162 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832.dts @@ -56,10 +56,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig index 249c4a8e394..ab2356cf412 100644 --- a/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig +++ b/boards/arm/we_proteus2ev_nrf52832/we_proteus2ev_nrf52832_defconfig @@ -24,6 +24,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts index 62cecf7066e..4c64bcaa4d0 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840.dts @@ -57,10 +57,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig index cca27094e6a..b232a355e40 100644 --- a/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig +++ b/boards/arm/we_proteus3ev_nrf52840/we_proteus3ev_nrf52840_defconfig @@ -24,6 +24,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + # Use internal oscillator CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y diff --git a/boards/arm/xiao_ble/xiao_ble_common.dtsi b/boards/arm/xiao_ble/xiao_ble_common.dtsi index d031ce4b5b3..588f381868a 100644 --- a/boards/arm/xiao_ble/xiao_ble_common.dtsi +++ b/boards/arm/xiao_ble/xiao_ble_common.dtsi @@ -62,10 +62,6 @@ status = "okay"; }; -&uicr { - gpio-as-nreset; -}; - &gpiote { status = "okay"; }; diff --git a/boards/arm/xiao_ble/xiao_ble_defconfig b/boards/arm/xiao_ble/xiao_ble_defconfig index 6b6aa3168ec..faef5befa1f 100644 --- a/boards/arm/xiao_ble/xiao_ble_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_defconfig @@ -29,4 +29,7 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y diff --git a/boards/arm/xiao_ble/xiao_ble_sense_defconfig b/boards/arm/xiao_ble/xiao_ble_sense_defconfig index 269f6f7915b..f549e4173dc 100644 --- a/boards/arm/xiao_ble/xiao_ble_sense_defconfig +++ b/boards/arm/xiao_ble/xiao_ble_sense_defconfig @@ -29,6 +29,9 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y +# additional board options +CONFIG_GPIO_AS_PINRESET=y + CONFIG_PINCTRL=y # required to enable LSM6DS3TR-C power From 8827231ed597ad7e23778a0d780892b65f2fbe33 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:19 +0000 Subject: [PATCH 4259/4498] Revert "[nrf fromtree] modules: hal_nordic: nrfx: add support for 'gpio-as-nreset'" This reverts commit 23001717f6451eb5b14588a044525bc7dd7f07a5. Signed-off-by: Dominik Ermel --- modules/hal_nordic/nrfx/CMakeLists.txt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index e98db561906..98ba1961396 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -111,19 +111,14 @@ if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) endif() # Inject HAL "CONFIG_NFCT_PINS_AS_GPIOS" definition if user requests to -# configure the NFCT pins as GPIOS. Do the same with "CONFIG_GPIO_AS_PINRESET" -# to configure the reset GPIO as nRESET. This way, the HAL will take care of -# doing the proper configuration sequence during system init +# configure the NFCT pins as GPIOS. This way, the HAL will take care of doing +# the proper configuration sequence during system init dt_nodelabel(uicr_path NODELABEL "uicr") if(${uicr_path}) dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") + if(${nfct_pins_as_gpios}) zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) endif() - - dt_prop(gpio_as_nreset PATH ${uicr_path} PROPERTY "gpio-as-nreset") - if(${gpio_as_nreset}) - zephyr_library_compile_definitions(CONFIG_GPIO_AS_PINRESET) - endif() endif() From aec500720c39636f9acb7a67a7c4b4a9f15dfb7b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:19 +0000 Subject: [PATCH 4260/4498] Revert "[nrf fromtree] dts: bindings: arm: nordic,nrf-uicr: add gpio-as-nreset" This reverts commit 9fd2a0dff20d7b02531259295db889590566996e. Signed-off-by: Dominik Ermel --- dts/bindings/arm/nordic,nrf-uicr.yaml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dts/bindings/arm/nordic,nrf-uicr.yaml b/dts/bindings/arm/nordic,nrf-uicr.yaml index b39a6ed6855..dbbb34e1265 100644 --- a/dts/bindings/arm/nordic,nrf-uicr.yaml +++ b/dts/bindings/arm/nordic,nrf-uicr.yaml @@ -19,14 +19,3 @@ properties: This setting, once applied, can only be unset by erasing the UICR registers. Refer to the reference manual for more details. - - gpio-as-nreset: - type: boolean - description: | - When enabled, this property will configure the reset GPIO as nRESET. - - nRESET pin in nRF52805/52810/52811/52832 series: P0.21 - nRESET pin in nRF52820/52833/52840 series: P0.18 - - This setting, once applied, can only be unset by erasing the UICR - registers. Refer to the reference manual for more details. From df95edc55556a525a690518cf91ab4d510c24844 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:19 +0000 Subject: [PATCH 4261/4498] Revert "[nrf fromtree] doc: migration-guide: add notes on CONFIG_NFCT_PINS_AS_GPIOS changes" This reverts commit d2aacb763ce42db6b11a46d7617e9a8f9fc5f745. Signed-off-by: Dominik Ermel --- doc/releases/migration-guide-3.5.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index 3f367ec5e35..7ffb16319d1 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -42,14 +42,3 @@ Recommended Changes :kconfig:option:`CONFIG_GIC_V3` directly in Kconfig has been deprecated. The GIC version should now be specified by adding the appropriate compatible, for example :dtcompatible:`arm,gic-v2`, to the GIC node in the device tree. - -* Nordic nRF based boards using :kconfig:option:`CONFIG_NFCT_PINS_AS_GPIOS` - to configure NFCT pins as GPIOs, should instead set the new UICR - ``nfct-pins-as-gpios`` property in devicetree. It can be set like this in the - board devicetree files: - - .. code-block:: devicetree - - &uicr { - nfct-pins-as-gpios; - }; From a3866892b89c6aee4bd52b20071f2b704aaea886 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:19 +0000 Subject: [PATCH 4262/4498] Revert "[nrf fromtree] soc: arm: nordic_nrf: deprecate CONFIG_NFCT_PINS_AS_GPIOS" This reverts commit f18175381579045b4cf9ef9a9cb3d09c33832c70. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/Kconfig | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index c2129db64b3..2c386f99a53 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -47,9 +47,8 @@ config NRF_ACL_FLASH_REGION_SIZE FLASH region size for the NRF_ACL peripheral. config NFCT_PINS_AS_GPIOS - bool "[DEPRECATED] NFCT pins as GPIOs" + bool "NFCT pins as GPIOs" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_NFCT)) - select DEPRECATED help Two pins are usually reserved for NFC in SoCs that implement the NFCT peripheral. This option switches them to normal GPIO mode. @@ -61,13 +60,6 @@ config NFCT_PINS_AS_GPIOS NFC pins in nRF52 series: P0.09 and P0.10 NFC pins in nRF5340: P0.02 and P0.03 - This option is deprecated, please use devicetree to configure NFCT - pins as GPIOS like this: - - &uicr { - nfct-pins-as-gpios; - }; - choice NRF_APPROTECT_HANDLING bool "APPROTECT handling" depends on SOC_SERIES_NRF52X || SOC_NRF5340_CPUNET || \ From c633c0868b3ff7e733dad6ca68c516a796559d94 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:19 +0000 Subject: [PATCH 4263/4498] Revert "[nrf fromtree] boards: arm: nrf: use UICR nfc-pins-as-gpios devicetree property" This reverts commit dda4a3bf0be6c10a1c48516f579b1ae5d6b9ff98. Signed-off-by: Dominik Ermel --- boards/arm/bt610/bt610.dts | 4 ---- boards/arm/bt610/bt610_defconfig | 1 + .../arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts | 4 ---- .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig | 1 + .../arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts | 4 ---- .../nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig | 1 + .../nrf5340_audio_dk_nrf5340_cpuapp.dts | 4 ---- .../nrf5340_audio_dk_nrf5340_cpuapp_defconfig | 1 + boards/arm/pinetime_devkit0/pinetime_devkit0.dts | 4 ---- boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig | 3 +++ 10 files changed, 7 insertions(+), 20 deletions(-) diff --git a/boards/arm/bt610/bt610.dts b/boards/arm/bt610/bt610.dts index 6bbe8d57fe3..3c047a50fcd 100644 --- a/boards/arm/bt610/bt610.dts +++ b/boards/arm/bt610/bt610.dts @@ -143,10 +143,6 @@ status = "okay"; }; -&uicr { - nfct-pins-as-gpios; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/bt610/bt610_defconfig b/boards/arm/bt610/bt610_defconfig index 1c77ed9e37b..64f0fcb85ed 100644 --- a/boards/arm/bt610/bt610_defconfig +++ b/boards/arm/bt610/bt610_defconfig @@ -9,6 +9,7 @@ CONFIG_ARM_MPU=y # Enable GPIO CONFIG_GPIO=y +CONFIG_NFCT_PINS_AS_GPIOS=y # Enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts index 8e835597c78..616af71443c 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts @@ -87,10 +87,6 @@ status = "okay"; }; -&uicr { - nfct-pins-as-gpios; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig index 90850c10e0a..92ec1dc7885 100644 --- a/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig +++ b/boards/arm/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle_defconfig @@ -15,5 +15,6 @@ CONFIG_GPIO=y # additional board options CONFIG_GPIO_AS_PINRESET=y +CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_PINCTRL=y diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts index 93b59baa920..f17ecb8e18a 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts @@ -99,10 +99,6 @@ status = "okay"; }; -&uicr { - nfct-pins-as-gpios; -}; - &gpio0 { status = "okay"; }; diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index 32a9d03b44e..f38880961d5 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -15,6 +15,7 @@ CONFIG_GPIO=y # additional board options CONFIG_GPIO_AS_PINRESET=y +CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_PINCTRL=y diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts index be871800332..8fe46bdd7a3 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp.dts @@ -20,7 +20,3 @@ zephyr,sram-non-secure-partition = &sram0_ns; }; }; - -&uicr { - nfct-pins-as-gpios; -}; diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig index d1b5f551c9b..0f5f1991b6d 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpuapp_defconfig @@ -12,6 +12,7 @@ CONFIG_HW_STACK_PROTECTION=y CONFIG_ARM_TRUSTZONE_M=y CONFIG_GPIO=y +CONFIG_NFCT_PINS_AS_GPIOS=y CONFIG_SERIAL=y diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts index fb377fd89e1..baad177740c 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts @@ -87,10 +87,6 @@ status = "okay"; }; -&uicr { - nfct-pins-as-gpios; -}; - &gpio0 { status = "okay"; diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig index ad7442afe0d..4e48c259730 100644 --- a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -13,6 +13,9 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# use P0.09 and P0.10 as GPIOs +CONFIG_NFCT_PINS_AS_GPIOS=y + # use P0.21 as RST CONFIG_GPIO_AS_PINRESET=y From 641b006debb06b98b4a78081a89742a211ced57c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:20 +0000 Subject: [PATCH 4264/4498] Revert "[nrf fromtree] modules: hal_nordic: inject CONFIG_NFCT_PINS_AS_GPIOS" This reverts commit 6f482d8e6f99115d9bd09d94855f76f491afc03c. Signed-off-by: Dominik Ermel --- modules/hal_nordic/nrfx/CMakeLists.txt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 98ba1961396..5842ae45ad5 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -109,16 +109,3 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_WDT ${SRC_DIR}/nrfx_wdt.c) if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) zephyr_library_sources(${SRC_DIR}/nrfx_twi_twim.c) endif() - -# Inject HAL "CONFIG_NFCT_PINS_AS_GPIOS" definition if user requests to -# configure the NFCT pins as GPIOS. This way, the HAL will take care of doing -# the proper configuration sequence during system init - -dt_nodelabel(uicr_path NODELABEL "uicr") -if(${uicr_path}) - dt_prop(nfct_pins_as_gpios PATH ${uicr_path} PROPERTY "nfct-pins-as-gpios") - - if(${nfct_pins_as_gpios}) - zephyr_library_compile_definitions(CONFIG_NFCT_PINS_AS_GPIOS) - endif() -endif() From 20f2d334f67fea2c1706b8f7d240eed1da258534 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:20 +0000 Subject: [PATCH 4265/4498] Revert "[nrf fromtree] dts: bindings: arm: nordic,nrf-uicr add nfct-pins-as-gpios" This reverts commit aa88cae57f098f7caf7ed4aac6ba2abafbf0afe0. Signed-off-by: Dominik Ermel --- dts/bindings/arm/nordic,nrf-uicr.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dts/bindings/arm/nordic,nrf-uicr.yaml b/dts/bindings/arm/nordic,nrf-uicr.yaml index dbbb34e1265..82ac8fc2089 100644 --- a/dts/bindings/arm/nordic,nrf-uicr.yaml +++ b/dts/bindings/arm/nordic,nrf-uicr.yaml @@ -7,15 +7,3 @@ include: base.yaml properties: reg: required: true - - nfct-pins-as-gpios: - type: boolean - description: | - When enabled this property will configure pins dedicated to NFCT - peripheral as regular GPIOs. - - NFC pins in nRF52 series: P0.09 and P0.10 - NFC pins in nRF5340: P0.02 and P0.03 - - This setting, once applied, can only be unset by erasing the UICR - registers. Refer to the reference manual for more details. From ebfeffd8a1b19732c89c9a667db5456df2f7388f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:20 +0000 Subject: [PATCH 4266/4498] Revert "[nrf fromlist] nrf53: fix RTC pretick power usage for events on RTC0" This reverts commit 7d27517258a04103755733c102e74f11841a1318. Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/soc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index c18228ac4fa..aa93dfd4b54 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -410,8 +410,6 @@ static void rtc_pretick_rtc_isr_hook(void) { NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= ~IPC_PUBLISH_RECEIVE_EN_Msk; - - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); } void rtc_pretick_rtc0_isr_hook(void) @@ -422,6 +420,10 @@ void rtc_pretick_rtc0_isr_hook(void) void rtc_pretick_rtc1_isr_hook(void) { rtc_pretick_rtc_isr_hook(); + + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + } } static int rtc_pretick_cpunet_init(void) From 2fb860661ae316700e904f809c28bb1b1fbb092d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:20 +0000 Subject: [PATCH 4267/4498] Revert "[nrf fromtree] mgmt/MCUmgr/grp/os: Add booloader info support" This reverts commit 8bef82541c679398d9886f211db6a8eb34f34760. Signed-off-by: Dominik Ermel --- .../zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h | 4 -- subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt | 8 +-- subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig | 10 --- subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 70 +------------------ 4 files changed, 2 insertions(+), 90 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h index e1ac45e6389..9c541e11c29 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h @@ -24,7 +24,6 @@ extern "C" { #define OS_MGMT_ID_RESET 5 #define OS_MGMT_ID_MCUMGR_PARAMS 6 #define OS_MGMT_ID_INFO 7 -#define OS_MGMT_ID_BOOTLOADER_INFO 8 /** * Command result codes for OS management group. @@ -38,9 +37,6 @@ enum os_mgmt_err_code_t { /** The provided format value is not valid. */ OS_MGMT_ERR_INVALID_FORMAT, - - /** Query was not recognized. */ - OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER, }; /* Bitmask values used by the os info command handler. Note that the width of this variable is diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt index 35123fa1159..e712acf6e94 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2018-2021 mcumgr authors -# Copyright (c) 2022-2023 Nordic Semiconductor ASA +# Copyright (c) 2022 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # @@ -12,12 +12,6 @@ zephyr_library_sources(src/os_mgmt.c) zephyr_library_include_directories(include) -if (CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) - zephyr_include_directories( - ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include - ) -endif() - if(DEFINED CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME) set(MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR ${PROJECT_BINARY_DIR}/os_mgmt_auto) file(MAKE_DIRECTORY ${MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR}) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index fa743b53caf..897db735982 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -173,16 +173,6 @@ config MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME endif -if BOOTLOADER_MCUBOOT - -config MCUMGR_GRP_OS_BOOTLOADER_INFO - bool "Bootloader information" - help - Allows to query MCUmgr about bootloader used by device and various bootloader - parameters. - -endif # BOOTLOADER_MCUBOOT - module = MCUMGR_GRP_OS module-str = mcumgr_grp_os source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index a42e2f4022f..55a6fa81564 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -33,15 +33,10 @@ #include #endif -#if defined(CONFIG_MCUMGR_GRP_OS_INFO) || defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) +#ifdef CONFIG_MCUMGR_GRP_OS_INFO #include #include -#if defined(CONFIG_MCUMGR_GRP_OS_INFO) #include -#endif -#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) -#include -#endif #include #if defined(CONFIG_NET_HOSTNAME_ENABLE) #include @@ -375,64 +370,6 @@ os_mgmt_mcumgr_params(struct smp_streamer *ctxt) } #endif -#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) - -#if IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP) -#define BOOTLOADER_MODE MCUBOOT_MODE_SINGLE_SLOT -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) -#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_SCRATCH -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) -#define BOOTLOADER_MODE MCUBOOT_MODE_UPGRADE_ONLY -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) -#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_MOVE -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) -#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP -#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) -#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT -#else -#define BOOTLOADER_MODE -1 -#endif - -static int -os_mgmt_bootloader_info(struct smp_streamer *ctxt) -{ - zcbor_state_t *zse = ctxt->writer->zs; - zcbor_state_t *zsd = ctxt->reader->zs; - struct zcbor_string query = { 0 }; - size_t decoded; - bool ok; - - struct zcbor_map_decode_key_val bootloader_info[] = { - ZCBOR_MAP_DECODE_KEY_DECODER("query", zcbor_tstr_decode, &query), - }; - - if (zcbor_map_decode_bulk(zsd, bootloader_info, ARRAY_SIZE(bootloader_info), &decoded)) { - return MGMT_ERR_EINVAL; - } - - /* If no parameter is recognized then just introduce the bootloader. */ - if (decoded == 0) { - ok = zcbor_tstr_put_lit(zse, "bootloader") && - zcbor_tstr_put_lit(zse, "MCUboot"); - } else if (zcbor_map_decode_bulk_key_found(bootloader_info, ARRAY_SIZE(bootloader_info), - "query") && - (sizeof("mode") - 1) == query.len && - memcmp("mode", query.value, query.len) == 0) { - - ok = zcbor_tstr_put_lit(zse, "mode") && - zcbor_int32_put(zse, BOOTLOADER_MODE); -#if IS_ENABLED(MCUBOOT_BOOTLOADER_NO_DOWNGRADE) - ok = zcbor_tstr_put_lit(zse, "no-downgrade") && - zcbor_bool_encode(zse, true); -#endif - } else { - return OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER; - } - - return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; -} -#endif - #ifdef CONFIG_MCUMGR_GRP_OS_INFO /** * Command handler: os info @@ -796,11 +733,6 @@ static const struct mgmt_handler os_mgmt_group_handlers[] = { os_mgmt_info, NULL }, #endif -#ifdef CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO - [OS_MGMT_ID_BOOTLOADER_INFO] = { - os_mgmt_bootloader_info, NULL - }, -#endif }; #define OS_MGMT_GROUP_SZ ARRAY_SIZE(os_mgmt_group_handlers) From eb94ee634137ffbb214fbc36143e2c16e9d92deb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:21 +0000 Subject: [PATCH 4268/4498] Revert "[nrf fromtree] doc/release-notes: MCUboot overwrite mode Kconfig info" This reverts commit b1ab980959dac1486bd6d781ec8b9c80bba21fac. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.5.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 82d2698849b..d22978d8a84 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -344,11 +344,6 @@ MCUboot with downgrade prevention enabled. This option is automatically selected for DirectXIP mode and is available for both swap modes. - * Added :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY` - that allows to inform application that the on-board MCUboot will overwrite - the primary slot with secondary slot contents, without saving the original - image in primary slot. - Storage ******* From 23585b274395eff820b3b46319deffdd9351c50b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:21 +0000 Subject: [PATCH 4269/4498] Revert "[nrf fromtree] doc/services/device_mgmt: Bootloader info request definition" This reverts commit 3d0052713f45333aa094a8c6d8896bd3b9c051ce. Signed-off-by: Dominik Ermel --- .../device_mgmt/smp_groups/smp_group_0.rst | 211 +----------------- 1 file changed, 3 insertions(+), 208 deletions(-) diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index 53907f33bcc..839b0e06be3 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -28,8 +28,6 @@ OS management group defines following commands: +-------------------+-----------------------------------------------+ | ``7`` | OS/Application info | +-------------------+-----------------------------------------------+ - | ``8`` | Bootloader information | - +-------------------+-----------------------------------------------+ Echo command ************ @@ -662,215 +660,12 @@ CBOR data of response: where: -.. table:: - :align: center - - +------------------+-------------------------------------------------------------------------+ - | "output" | Text response including requested parameters. | - +------------------+-------------------------------------------------------------------------+ - | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | - | | appears if an error is returned when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - | "err" -> "rc" | contains the index of the group-based error code. Only appears if | - | | non-zero (error condition) when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | - | | using SMP version 1 or for SMP errors when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - -Bootloader Information -********************** - -Allows retrieving information about the on-board bootloader and its parameters. - -Bootloader Information Request -============================== - -Bootloader information request header: - -.. table:: - :align: center - - +--------+--------------+----------------+ - | ``OP`` | ``Group ID`` | ``Command ID`` | - +========+==============+================+ - | ``0`` | ``0`` | ``8`` | - +--------+--------------+----------------+ - -CBOR data of request: - -.. code-block:: none - - { - (str,opt)"query" : (str) - } - -where: - .. table:: :align: center +--------------+-----------------------------------------------+ - | "query" | Is string representing query for parameters, | - | | with no restrictions how the query looks like | - | | as processing of query is left for bootloader | - | | backend. | - | | If there is no query, then response will | - | | return string identifying the bootloader. | + | "output" | Text response including requested parameters. | +--------------+-----------------------------------------------+ - -Bootloader Information Response -=============================== - -Bootloader information response header: - -.. table:: - :align: center - - +--------+--------------+----------------+ - | ``OP`` | ``Group ID`` | ``Command ID`` | - +========+==============+================+ - | ``1`` | ``0`` | ``8`` | - +--------+--------------+----------------+ - -In case when no "query" has been provided in request, -CBOR data of response: - -.. code-block:: none - - { - (str)"bootloader" : (str) - } - -where: - -.. table:: - :align: center - - +--------------+-----------------------------------------------+ - | "bootloader" | String representing bootloader name | + | "rc" | :c:enum:`mcumgr_err_t` | + | | only appears if non-zero (error condition). | +--------------+-----------------------------------------------+ - -In case when "query" is provided: - -.. code-block:: none - - { - (str,opt) : () - ... - } - -where: - -.. table:: - :align: center - - +------------------+-------------------------------------------------------------------------+ - | | Response to "query". This is optional and may be left out in case when | - | | query yields no response, SMP version 2 error code of | - | | `OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER` is expected. | - | | Response may have more than one parameter reported back or it may be | - | | a map, that is dependent on bootloader backednd and query. | - +------------------+-------------------------------------------------------------------------+ - | ... | Parameter characteristic information. | - +------------------+-------------------------------------------------------------------------+ - -Parameter may be accompanied by additional, parameter specific, information keywords with -assigned values. - -In case of error the CBOR data takes the form: - -.. tabs:: - - .. group-tab:: SMP version 2 - - .. code-block:: none - - { - (str)"err" : { - (str)"group" : (uint) - (str)"rc" : (uint) - } - } - - .. group-tab:: SMP version 1 (and non-group SMP version 2) - - .. code-block:: none - - { - (str)"rc" : (int) - } - -where: - -.. table:: - :align: center - - +------------------+-------------------------------------------------------------------------+ - | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only | - | | appears if an error is returned when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - | "err" -> "rc" | contains the index of the group-based error code. Only appears if | - | | non-zero (error condition) when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - | "rc" | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when | - | | using SMP version 1 or for SMP errors when using SMP version 2. | - +------------------+-------------------------------------------------------------------------+ - -Bootloader Information: MCUboot -=============================== - -In case when MCUboot is application bootloader empty request will -be responded with: - -.. code-block:: none - - { - (str)"bootloader" : (str)"MCUboot" - } - -Currently "MCUboot" supports querying for mode of operation: - -.. code-block:: none - - { - (str)"query" : (str)"mode" - } - -Response to "mode" is: - -.. code-block:: none - - { - (str)"mode" : (int) - (str,opt)"no-downgrade" : (bool) - } - -where "mode" is one of: - -.. table:: - :align: center - - +-----+-----------------------------------------------------+ - | -1 | Unknown mode of MCUboot. | - +-----+-----------------------------------------------------+ - | 0 | MCUboot is in single application mode. | - +-----+-----------------------------------------------------+ - | 1 | MCUboot is in swap using scratch partition mode. | - +-----+-----------------------------------------------------+ - | 2 | MCUboot is in overwrite (upgrade-only) mode. | - +-----+-----------------------------------------------------+ - | 3 | MCUboot is in swap without scratch mode. | - +-----+-----------------------------------------------------+ - | 4 | MCUboot is in DirectXIP without revert mode. | - +-----+-----------------------------------------------------+ - | 5 | MCUboot is in DirectXIP with revert mode. | - +-----+-----------------------------------------------------+ - | 6 | MCUboot is in RAM loader mode. | - +-----+-----------------------------------------------------+ - -The "no-downgrade" is a flag, which is always sent when true, indicating that -mode has downgrade prevention enabled; downgrade prevention means that -if uploaded image has lower version than running, it will notbe taken -for exectuion by MCUboot. -MCUmgr may reject image with lower version in that MCUboot configuration. From e00ae48a5346e9704e6b90d3626529f349ab0ce3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:21 +0000 Subject: [PATCH 4270/4498] Revert "[nrf fromtree] modules/MCUboot: Add overwrite mode for MCUboot" This reverts commit d73788b2457d22003d435da88143ee67881bdc43. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 8df4bde8829..1679bfeb8a9 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -175,18 +175,6 @@ config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. -config MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY - bool "MCUboot has been configured to just overwrite primary slot" - select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE - help - MCUboot will take contents of secondary slot of an image and will - overwrite primary slot with it. - In this mode it is not possible to revert back to previous version - as it is not stored in the secondary slot. - This mode supports MCUBOOT_BOOTLOADER_NO_DOWNGRADE which means - that the overwrite will not happen unless the version of secondary - slot is higher than the version in primary slot. - config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP bool "MCUboot has been configured for DirectXIP operation" select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE From b0f2eca67d88ff7208dcb47e06fdb885058d7863 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:21 +0000 Subject: [PATCH 4271/4498] Revert "[nrf fromtree] bluetooth: tests: Improve bondable_per_connection bsim test" This reverts commit 55f4b17ea515edd707dd2fc3a907911f270e088a. Signed-off-by: Dominik Ermel --- .../host/security/bond_per_connection/src/bs_bt_utils.c | 6 ------ .../host/security/bond_per_connection/src/peripheral.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c index 94b27a50b33..1523e10d8a5 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c @@ -88,11 +88,6 @@ DEFINE_FLAG(flag_pairing_complete); DEFINE_FLAG(flag_bonded); DEFINE_FLAG(flag_not_bonded); -static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) -{ - FAIL("Pairing failed (unexpected): reason %u\n", reason); -} - static void pairing_complete(struct bt_conn *conn, bool bonded) { SET_FLAG(flag_pairing_complete); @@ -105,7 +100,6 @@ static void pairing_complete(struct bt_conn *conn, bool bonded) } static struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { - .pairing_failed = pairing_failed, .pairing_complete = pairing_complete, }; diff --git a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c index 01956d251df..5e11d6ac712 100644 --- a/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c +++ b/tests/bsim/bluetooth/host/security/bond_per_connection/src/peripheral.c @@ -33,8 +33,6 @@ void peripheral(void) wait_connected(); /* Central should bond here and trigger a disconnect. */ wait_disconnected(); - TAKE_FLAG(flag_pairing_complete); - TAKE_FLAG(flag_bonded); unpair(id_a); clear_g_conn(); @@ -45,8 +43,6 @@ void peripheral(void) wait_connected(); /* Central should bond here and trigger a disconnect. */ wait_disconnected(); - TAKE_FLAG(flag_pairing_complete); - TAKE_FLAG(flag_bonded); clear_g_conn(); printk("== Bonding id b - bond per-connection false ==\n"); @@ -55,8 +51,6 @@ void peripheral(void) wait_connected(); /* Central should pair without bond here and trigger a disconnect. */ wait_disconnected(); - TAKE_FLAG(flag_pairing_complete); - TAKE_FLAG(flag_not_bonded); PASS("PASS\n"); } From 7b4e434ad953410d6cb4fc2aefc0fe8bb020fdfb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:21 +0000 Subject: [PATCH 4272/4498] Revert "[nrf fromtree] bluetooth: host: smp: Add runtime check for central-specific path" This reverts commit 27f8c5cbafa199be5c1945ab95bc5cbcff9ab8cd. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/smp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 9643982c421..add06660bf6 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -4706,7 +4706,6 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan, */ if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY) && - conn->role == BT_HCI_ROLE_CENTRAL && !(smp->remote_dist & BT_SMP_DIST_ID_KEY)) { uint8_t smp_err; From 1bcc187c901e74a1f8ec5ba838dbe1a786149220 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:22 +0000 Subject: [PATCH 4273/4498] Revert "[nrf fromlist] bluetooth: tester: add support for variable static oob size" This reverts commit 6319f2cfbe21cd9cac956922ad70595b149220a0. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 8 +++++--- tests/bluetooth/tester/src/btp_mesh.c | 13 ++----------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 826f0fd0408..6c4a5e90106 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -30,12 +30,15 @@ struct btp_mesh_read_supported_commands_rp { #define BTP_MESH_CONFIG_PROVISIONING 0x02 -#define BTP_MESH_PROV_AUTH_MAX_LEN 32 +#if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) +#define BTP_MESH_PROV_AUTH_MAX_LEN 32 +#else +#define BTP_MESH_PROV_AUTH_MAX_LEN 16 +#endif struct btp_mesh_config_provisioning_cmd { uint8_t uuid[16]; uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; - uint8_t static_auth_size; uint8_t out_size; uint16_t out_actions; uint8_t in_size; @@ -45,7 +48,6 @@ struct btp_mesh_config_provisioning_cmd { struct btp_mesh_config_provisioning_cmd_v2 { uint8_t uuid[16]; uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; - uint8_t static_auth_size; uint8_t out_size; uint16_t out_actions; uint8_t in_size; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index e83f1a67ba1..af41c1518d5 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -50,7 +50,6 @@ static uint8_t priv_key[32]; /* Configured provisioning data */ static uint8_t dev_uuid[16]; static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; -static uint8_t static_auth_size; /* Vendor Model data */ #define VND_MODEL_ID_1 0x1234 @@ -1144,21 +1143,13 @@ static uint8_t config_prov(const void *cmd, uint16_t cmd_len, /* TODO consider fix BTP commands to avoid this */ if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) { - LOG_DBG("wrong cmd size"); return BTP_STATUS_FAILED; } LOG_DBG(""); - static_auth_size = cp->static_auth_size; - - if (static_auth_size > BTP_MESH_PROV_AUTH_MAX_LEN || static_auth_size == 0) { - LOG_DBG("wrong static auth length"); - return BTP_STATUS_FAILED; - } - memcpy(dev_uuid, cp->uuid, sizeof(dev_uuid)); - memcpy(static_auth, cp->static_auth, cp->static_auth_size); + memcpy(static_auth, cp->static_auth, sizeof(static_auth)); prov.output_size = cp->out_size; prov.output_actions = sys_le16_to_cpu(cp->out_actions); @@ -1177,7 +1168,7 @@ static uint8_t config_prov(const void *cmd, uint16_t cmd_len, } else if (cp->auth_method == AUTH_METHOD_INPUT) { err = bt_mesh_auth_method_set_input(prov.input_actions, prov.input_size); } else if (cp->auth_method == AUTH_METHOD_STATIC) { - err = bt_mesh_auth_method_set_static(static_auth, static_auth_size); + err = bt_mesh_auth_method_set_static(static_auth, sizeof(static_auth)); } if (err) { From 534769cc77b56211c3d6597a22de8a8313423030 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:22 +0000 Subject: [PATCH 4274/4498] Revert "[nrf fromlist] bluetooth: tester: Enable composition data page 2" This reverts commit 5cb1ed20ab2c98d0e0856219a355a7e7dd51394c. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 2 +- tests/bluetooth/tester/src/btp_mesh.c | 20 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf index 978d1acd3df..7a3907cc78c 100644 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ b/tests/bluetooth/tester/overlay-mesh-v1d1.conf @@ -25,5 +25,5 @@ CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_BT_MESH_MODEL_EXTENSIONS=y CONFIG_BT_MESH_COMP_PAGE_1=y -CONFIG_BT_MESH_COMP_PAGE_2=y + CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index af41c1518d5..1d94eb43cb5 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1103,22 +1103,6 @@ static const struct bt_mesh_comp comp_alt = { .vid = 2, }; -#if defined(CONFIG_BT_MESH_COMP_PAGE_2) -static const uint8_t cmp2_elem_offset[1] = {0}; - -static const struct bt_mesh_comp2_record comp_rec = { - .id = 0x1600, - .version.x = 1, - .version.y = 0, - .version.z = 0, - .elem_offset_cnt = 1, - .elem_offset = cmp2_elem_offset, - .data_len = 0 -}; - -static const struct bt_mesh_comp2 comp_p2 = {.record_cnt = 1, .record = &comp_rec}; -#endif - static struct bt_mesh_prov prov = { .uuid = dev_uuid, .static_val = static_auth, @@ -5221,10 +5205,6 @@ uint8_t tester_init_mesh(void) bt_test_cb_register(&bt_test_cb); } -#if defined(CONFIG_BT_MESH_COMP_PAGE_2) - bt_mesh_comp2_register(&comp_p2); -#endif - tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); if (default_comp) { From 0826530bbdea8134c0bf43c03c2ee81b8713c187 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:22 +0000 Subject: [PATCH 4275/4498] Revert "[nrf fromtree] bluetooth: mesh: fix static oob auth padding" This reverts commit 058c19c5a8644dcb0817d720876bb5265776a7ad. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/prov_device.c | 18 ++++++++---------- subsys/bluetooth/mesh/provisioner.c | 13 +++++-------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 992bf656202..0184463568f 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -192,16 +192,14 @@ static void prov_start(const uint8_t *data) } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { - /* Trim the Auth if it is longer than required length */ - memcpy(bt_mesh_prov_link.auth, bt_mesh_prov->static_val, - bt_mesh_prov->static_val_len > auth_size ? auth_size - : bt_mesh_prov->static_val_len); - - /* Padd with zeros if the Auth is shorter the required length*/ - if (bt_mesh_prov->static_val_len < auth_size) { - memset(bt_mesh_prov_link.auth + bt_mesh_prov->static_val_len, 0, - auth_size - bt_mesh_prov->static_val_len); - } + + uint8_t tail_size = bt_mesh_prov->static_val_len < auth_size + ? auth_size - bt_mesh_prov->static_val_len + : 0; + + memcpy(bt_mesh_prov_link.auth + tail_size, bt_mesh_prov->static_val, + tail_size ? bt_mesh_prov->static_val_len : auth_size); + memset(bt_mesh_prov_link.auth, 0, tail_size); } } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 361f373cb7b..673e14578d2 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -751,20 +751,17 @@ int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size) int bt_mesh_auth_method_set_static(const uint8_t *static_val, uint8_t size) { + uint8_t tail_size = size < PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN - size : 0; + if (!size || !static_val) { return -EINVAL; } prov_set_method(AUTH_METHOD_STATIC, 0, 0); - /* Trim the Auth if it is longer than required length */ - memcpy(bt_mesh_prov_link.auth, static_val, - size > PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN : size); - - /* Padd with zeros if the Auth is shorter the required length*/ - if (size < PROV_AUTH_MAX_LEN) { - memset(bt_mesh_prov_link.auth + size, 0, PROV_AUTH_MAX_LEN - size); - } + memcpy(bt_mesh_prov_link.auth + tail_size, static_val, + tail_size ? size : PROV_AUTH_MAX_LEN); + memset(bt_mesh_prov_link.auth, 0, tail_size); return 0; } From acf33ea999c3f83c3117a2554f3a1f96eccdb93d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:22 +0000 Subject: [PATCH 4276/4498] Revert "[nrf fromtree] tests: btp_mesh: Check correct error code" This reverts commit cbeb833f4470fa050c5c43429298ec72e7a656b2. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 1d94eb43cb5..f02d51c905a 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -3801,7 +3801,7 @@ static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len, return; } - err = bt_mesh_dfu_slot_commit(slot); + bt_mesh_dfu_slot_commit(slot); if (err) { LOG_ERR("Failed to commit slot: %d", err); return; From ac3f491436be3fc81b7a0d5e2c880372f44cc4aa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:23 +0000 Subject: [PATCH 4277/4498] Revert "[nrf fromtree] bluetooth: mesh: check upload slot before release" This reverts commit 1d3d0be5a5684572f422e1b5c9ee3afabe77c7a7. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/dfd_srv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 59fe5b830d1..54de343c94a 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -477,9 +477,7 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx /* This will be a no-op if the slot state isn't RESERVED, which is * what we want. */ - if (srv->upload.slot) { - bt_mesh_dfu_slot_release(srv->upload.slot); - } + bt_mesh_dfu_slot_release(srv->upload.slot); #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD srv->upload.is_oob = false; From a0da100891815d08010d9aee5aa1b7720f0afcfe Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:23 +0000 Subject: [PATCH 4278/4498] Revert "[nrf fromtree] tests: bluetooth: tester: fix improper large comp rsp struct init" This reverts commit 0f4ef37e9e32afb8c4a006df4876d3d27146a75e. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index f02d51c905a..ffd4b69db84 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -1761,12 +1761,7 @@ static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, struct btp_mesh_large_comp_data_get_rp *rp = rsp; int err; - NET_BUF_SIMPLE_DEFINE(data, 500); - net_buf_simple_init(&data, 0); - - struct bt_mesh_large_comp_data_rsp comp = { - .data = &data, - }; + struct bt_mesh_large_comp_data_rsp comp; err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->addr), cp->page, @@ -1790,12 +1785,7 @@ static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len, struct btp_mesh_models_metadata_get_rp *rp = rsp; int err; - NET_BUF_SIMPLE_DEFINE(data, 500); - net_buf_simple_init(&data, 0); - - struct bt_mesh_large_comp_data_rsp metadata = { - .data = &data, - }; + struct bt_mesh_large_comp_data_rsp metadata; err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->addr), cp->page, From 33aa6585d36ae879b62c3afb8dd167bd1fac5ccc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:23 +0000 Subject: [PATCH 4279/4498] Revert "[nrf fromtree] tests: bluetooth: tester: add transfer ttl to mbt inputs" This reverts commit 954d54fef79f1a2f7400098e2a58bf7b64ec9b18. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 2 -- tests/bluetooth/tester/src/btp_mesh.c | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 6c4a5e90106..ea5d89de07a 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -954,7 +954,6 @@ struct btp_mmdl_dfu_firmware_update_rp { struct btp_mmdl_blob_srv_recv_cmd { uint64_t id; uint16_t timeout; - uint8_t ttl; } __packed; #define BTP_MMDL_BLOB_TRANSFER_START 0x66 @@ -964,7 +963,6 @@ struct btp_mmdl_blob_transfer_start_cmd { uint8_t block_size; uint16_t chunk_size; uint16_t timeout; - uint8_t ttl; } __packed; #define BTP_MMDL_BLOB_TRANSFER_CANCEL 0x67 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index ffd4b69db84..b9297474860 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -4228,10 +4228,6 @@ static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len, blob_cli_xfer.inputs.timeout_base = cp->timeout; } - if (cp->ttl) { - blob_cli_xfer.inputs.ttl = cp->ttl; - } - err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs, &blob_cli_xfer.xfer, &dummy_blob_io); @@ -4315,15 +4311,13 @@ static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, uint16_t timeout_base; uint64_t id; - uint8_t ttl; LOG_DBG(""); id = cp->id; timeout_base = cp->timeout; - ttl = cp->ttl; - err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, ttl, + err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, BT_MESH_TTL_MAX, timeout_base); if (err) { From ccef8673e0204940aafe92078f686c30fce6f75c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:23 +0000 Subject: [PATCH 4280/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Move mesh-1.1 features to a separate conf" This reverts commit 991f7b9e250d62a4df1e3322b28127e7ff3cd69e. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh-v1d1.conf | 29 ------------------- tests/bluetooth/tester/overlay-mesh.conf | 29 ++++++++++++++++++- tests/bluetooth/tester/testcase.yaml | 9 ------ 3 files changed, 28 insertions(+), 39 deletions(-) delete mode 100644 tests/bluetooth/tester/overlay-mesh-v1d1.conf diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf deleted file mode 100644 index 7a3907cc78c..00000000000 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ /dev/null @@ -1,29 +0,0 @@ -CONFIG_ENTROPY_GENERATOR=y - -CONFIG_BT_MESH_V1d1=y -CONFIG_BT_MESH_OP_AGG_CLI=y -CONFIG_BT_MESH_OP_AGG_SRV=y -# PTS requires more key slots. -# First one is implicitly taken by Device Key. -CONFIG_BT_MESH_MODEL_KEY_COUNT=3 -CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y -CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y -CONFIG_BT_MESH_SAR_CFG_SRV=y -CONFIG_BT_MESH_SAR_CFG_CLI=y -CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 -CONFIG_BT_MESH_RPR_SRV=y -CONFIG_BT_MESH_RPR_CLI=y -CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 -CONFIG_BT_MESH_BLOB_CLI=y -CONFIG_BT_MESH_DFU_CLI=y -CONFIG_BT_MESH_BLOB_SRV=y -CONFIG_BT_MESH_DFU_SRV=y -CONFIG_BT_MESH_DFD_SRV=y -CONFIG_BT_MESH_DFU_SLOT_CNT=2 -CONFIG_BT_MESH_PRIV_BEACONS=y -CONFIG_BT_MESH_PRIV_BEACON_SRV=y -CONFIG_BT_MESH_PRIV_BEACON_CLI=y -CONFIG_BT_MESH_MODEL_EXTENSIONS=y -CONFIG_BT_MESH_COMP_PAGE_1=y - -CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 840af06c1c0..fe4c9a62fef 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -1,4 +1,5 @@ CONFIG_BT_MESH=y +CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PB_GATT=y @@ -8,14 +9,23 @@ CONFIG_BT_MESH_GATT_PROXY=y CONFIG_BT_MESH_LABEL_COUNT=2 CONFIG_BT_MESH_SUBNET_COUNT=2 CONFIG_BT_MESH_MODEL_GROUP_COUNT=2 +CONFIG_BT_MESH_OP_AGG_CLI=y +CONFIG_BT_MESH_OP_AGG_SRV=y +# PTS requires more key slots. +# First one is implicitly taken by Device Key. +CONFIG_BT_MESH_MODEL_KEY_COUNT=3 CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y +CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y +CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y +CONFIG_BT_MESH_SAR_CFG_SRV=y +CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 -CONFIG_BT_MESH_TX_SEG_MSG_COUNT=3 +CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 CONFIG_BT_MESH_LPN_POLL_TIMEOUT=100 CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_CDB=y @@ -23,3 +33,20 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y +CONFIG_BT_MESH_PROVISIONER=y +CONFIG_BT_MESH_RPR_SRV=y +CONFIG_BT_MESH_RPR_CLI=y +CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 +CONFIG_BT_MESH_BLOB_CLI=y +CONFIG_BT_MESH_DFU_CLI=y +CONFIG_BT_MESH_BLOB_SRV=y +CONFIG_BT_MESH_DFU_SRV=y +CONFIG_BT_MESH_DFD_SRV=y +CONFIG_BT_MESH_DFU_SLOT_CNT=2 +CONFIG_BT_MESH_PRIV_BEACONS=y +CONFIG_BT_MESH_PRIV_BEACON_SRV=y +CONFIG_BT_MESH_PRIV_BEACON_CLI=y +CONFIG_BT_MESH_MODEL_EXTENSIONS=y +CONFIG_BT_MESH_COMP_PAGE_1=y + +CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index dba67716af1..65588568994 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -25,12 +25,3 @@ tests: extra_args: OVERLAY_CONFIG="overlay-mesh.conf" tags: bluetooth harness: bluetooth - bluetooth.general.tester_mesh_v1d1: - build_only: true - platform_allow: - - qemu_x86 - - native_posix - - nrf52840dk_nrf52840 - extra_args: OVERLAY_CONFIG="overlay-mesh.conf;overlay-mesh-v1d1.conf" - tags: bluetooth - harness: bluetooth From d14b38c7e117ab9e99569a501ee15a82cdd15a38 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:24 +0000 Subject: [PATCH 4281/4498] Revert "[nrf fromtree] tests: Bluetooth: tester: add support for Proxy Solicitation" This reverts commit fd0886b30723ba0a0309fd4d6c0e01442dc7dc4f. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 27 ----- tests/bluetooth/tester/src/btp_mesh.c | 138 ---------------------- 2 files changed, 165 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index ea5d89de07a..e93c2ceeb3d 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -1009,33 +1009,6 @@ struct btp_priv_node_id_set_cmd { #define BTP_MESH_PROXY_PRIVATE_IDENTITY 0x72 -#define BTP_MESH_OD_PRIV_PROXY_GET 0x73 -struct btp_od_priv_proxy_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_OD_PRIV_PROXY_SET 0x74 - -struct btp_od_priv_proxy_set_cmd { - uint16_t dst; - uint8_t val; -} __packed; - -#define BTP_MESH_SRPL_CLEAR 0x75 - -struct btp_srpl_clear_cmd { - uint16_t dst; - uint16_t range_start; - uint8_t range_len; - uint8_t acked; -} __packed; - -#define BTP_MESH_PROXY_SOLICIT 0x76 - -struct btp_proxy_solicit_cmd { - uint16_t net_idx; -} __packed; - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index b9297474860..2c837bfb198 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -773,108 +773,6 @@ static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len, } #endif -#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) -static struct bt_mesh_sol_pdu_rpl_cli srpl_cli; -#endif - - -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) -static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli; - -static uint8_t od_priv_proxy_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_od_priv_proxy_get_cmd *cp = cmd; - uint8_t val_rsp; - int err; - - LOG_DBG(""); - - err = bt_mesh_od_priv_proxy_cli_get(net.net_idx, cp->dst, &val_rsp); - if (err) { - LOG_ERR("Failed to get On-Demand Private Proxy state (err %d)", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("On-Demand Private Proxy state: %u", val_rsp); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t od_priv_proxy_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_od_priv_proxy_set_cmd *cp = cmd; - uint8_t val_rsp; - int err; - - LOG_DBG(""); - - err = bt_mesh_od_priv_proxy_cli_set(net.net_idx, cp->dst, cp->val, &val_rsp); - if (err) { - LOG_ERR("Failed to set On-Demand Private Proxy state (err %d)", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("On-Demand Private Proxy set state: %u", val_rsp); - - return BTP_STATUS_SUCCESS; -} - -#endif - -#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) -static uint8_t srpl_clear(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_srpl_clear_cmd *cp = cmd; - uint16_t app_idx = BT_MESH_KEY_UNUSED; - uint16_t start_rsp; - uint8_t len_rsp; - int err; - - /* Lookup source address */ - for (int i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (model_bound[i].model->id == BT_MESH_MODEL_ID_SOL_PDU_RPL_CLI) { - app_idx = model_bound[i].appkey_idx; - break; - } - } - - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(app_idx, cp->dst); - - if (cp->acked) { - err = bt_mesh_sol_pdu_rpl_clear(&ctx, cp->range_start, cp->range_len, &start_rsp, - &len_rsp); - } else { - err = bt_mesh_sol_pdu_rpl_clear_unack(&ctx, cp->range_start, cp->range_len); - } - if (err) { - LOG_ERR("Failed to clear SRPL (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - -#if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) -static uint8_t proxy_solicit(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_proxy_solicit_cmd *cp = cmd; - int err; - - err = bt_mesh_proxy_solicit(cp->net_idx); - if (err) { - LOG_ERR("Failed to advertise solicitation PDU (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */ - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -919,16 +817,6 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), #endif -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) - BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli), -#endif -#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) - BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli), -#endif -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - BT_MESH_MODEL_OD_PRIV_PROXY_SRV, -#endif - }; struct model_data *lookup_model_bound(uint16_t id) { @@ -4895,32 +4783,6 @@ static const struct btp_handler handlers[] = { .func = proxy_private_identity_enable }, #endif -#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI) - { - .opcode = BTP_MESH_OD_PRIV_PROXY_GET, - .expect_len = sizeof(struct btp_od_priv_proxy_get_cmd), - .func = od_priv_proxy_get - }, - { - .opcode = BTP_MESH_OD_PRIV_PROXY_SET, - .expect_len = sizeof(struct btp_od_priv_proxy_set_cmd), - .func = od_priv_proxy_set - }, -#endif -#if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI) - { - .opcode = BTP_MESH_SRPL_CLEAR, - .expect_len = sizeof(struct btp_srpl_clear_cmd), - .func = srpl_clear - }, -#endif -#if defined(CONFIG_BT_MESH_SOLICITATION) - { - .opcode = BTP_MESH_PROXY_SOLICIT, - .expect_len = sizeof(struct btp_proxy_solicit_cmd), - .func = proxy_solicit - }, -#endif }; From b2c031ec985e0d66828654e18f563d6176c93bd1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:24 +0000 Subject: [PATCH 4282/4498] Revert "[nrf fromtree] tests: Bluetooth: tester: Add Models Metadata Page 128" This reverts commit 5237cdd07078a0064c3808f31d263e07f1d9ee42. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp_mesh.c | 33 --------------------------- 1 file changed, 33 deletions(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 2c837bfb198..5a7b4bb5fd7 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -542,31 +542,8 @@ static uint8_t health_tests[] = { BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03), }; -static uint8_t zero_metadata[100]; - static struct bt_mesh_models_metadata_entry health_srv_meta[] = { BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests), - { - .len = ARRAY_SIZE(zero_metadata), - .id = 0xABCD, - .data = zero_metadata, - }, - BT_MESH_MODELS_METADATA_END, -}; - -static uint8_t health_tests_alt[] = { - BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66), - BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x11, 0x22, 0x33), -}; - -static struct bt_mesh_models_metadata_entry health_srv_meta_alt[] = { - BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests_alt), - { - .len = ARRAY_SIZE(zero_metadata), - .id = 0xFEED, - .data = zero_metadata, - }, BT_MESH_MODELS_METADATA_END, }; #endif @@ -1732,13 +1709,6 @@ static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } -#if CONFIG_BT_MESH_LARGE_COMP_DATA_SRV - err = bt_mesh_models_metadata_change_prepare(); - if (err < 0) { - return BTP_STATUS_FAILED; - } -#endif - return BTP_STATUS_SUCCESS; } @@ -5056,9 +5026,6 @@ uint8_t tester_init_mesh(void) if (default_comp) { err = bt_mesh_init(&prov, &comp); } else { -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV - health_srv.metadata = health_srv_meta_alt; -#endif err = bt_mesh_init(&prov, &comp_alt); } From 77cd168ff114808b2c3b61f686e220d07eba6e96 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:24 +0000 Subject: [PATCH 4283/4498] Revert "[nrf fromtree] tests: Bluetooth: tester: enable Composition Data Page 1" This reverts commit d629e26fb5e4ffc8e70de557700d6f98285a9db4. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index fe4c9a62fef..95a61769a1a 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -46,7 +46,5 @@ CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_BT_MESH_PRIV_BEACONS=y CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y -CONFIG_BT_MESH_MODEL_EXTENSIONS=y -CONFIG_BT_MESH_COMP_PAGE_1=y CONFIG_SETTINGS=y From 125d9bcf338aa34a0a634b730de30050a7367886 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:24 +0000 Subject: [PATCH 4284/4498] Revert "[nrf fromtree] Tests: Bluetooth: Tester: Add BTP command to enable Private NID" This reverts commit c77879087eaaae5206ba1274c86636d903ae119c. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 3 - tests/bluetooth/tester/src/btp/btp_mesh.h | 38 ----- tests/bluetooth/tester/src/btp_mesh.c | 177 ---------------------- 3 files changed, 218 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 95a61769a1a..60f809f77e5 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -43,8 +43,5 @@ CONFIG_BT_MESH_BLOB_SRV=y CONFIG_BT_MESH_DFU_SRV=y CONFIG_BT_MESH_DFD_SRV=y CONFIG_BT_MESH_DFU_SLOT_CNT=2 -CONFIG_BT_MESH_PRIV_BEACONS=y -CONFIG_BT_MESH_PRIV_BEACON_SRV=y -CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index e93c2ceeb3d..63fb2adcf12 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -971,44 +971,6 @@ struct btp_mmdl_blob_transfer_start_cmd { #define BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY 0x6A #define BTP_MMDL_DFU_SRV_APPLY 0x6B -#define BTP_MESH_PRIV_BEACON_GET 0x6c -struct btp_priv_beacon_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_PRIV_BEACON_SET 0x6d -struct btp_priv_beacon_set_cmd { - uint16_t dst; - uint8_t enabled; - uint8_t rand_interval; -} __packed; - -#define BTP_MESH_PRIV_GATT_PROXY_GET 0x6e -struct btp_priv_gatt_proxy_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_PRIV_GATT_PROXY_SET 0x6f -struct btp_priv_gatt_proxy_set_cmd { - uint16_t dst; - uint8_t state; -} __packed; - -#define BTP_MESH_PRIV_NODE_ID_GET 0x70 -struct btp_priv_node_id_get_cmd { - uint16_t dst; - uint16_t key_net_idx; -} __packed; - -#define BTP_MESH_PRIV_NODE_ID_SET 0x71 -struct btp_priv_node_id_set_cmd { - uint16_t dst; - uint16_t net_idx; - uint8_t state; -} __packed; - -#define BTP_MESH_PROXY_PRIVATE_IDENTITY 0x72 - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 5a7b4bb5fd7..4f3d181fd1d 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -617,139 +617,6 @@ static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len, } #endif -#ifdef CONFIG_BT_MESH_PRIV_BEACON_CLI -static struct bt_mesh_priv_beacon_cli priv_beacon_cli; - -static uint8_t priv_beacon_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_beacon_get_cmd *cp = cmd; - - struct bt_mesh_priv_beacon val; - int err; - - err = bt_mesh_priv_beacon_cli_get(net.net_idx, cp->dst, &val); - if (err) { - LOG_ERR("Failed to send Private Beacon Get (err %d)", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Private Beacon state: %u, %u", val.enabled, val.rand_interval); - return BTP_STATUS_SUCCESS; -} - -static uint8_t priv_beacon_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_beacon_set_cmd *cp = cmd; - struct bt_mesh_priv_beacon val; - int err; - - val.enabled = cp->enabled; - val.rand_interval = cp->rand_interval; - - err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val); - if (err) { - LOG_ERR("Failed to send Private Beacon Set (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t priv_gatt_proxy_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_gatt_proxy_get_cmd *cp = cmd; - - uint8_t state; - int err; - - err = bt_mesh_priv_beacon_cli_gatt_proxy_get(net.net_idx, cp->dst, &state); - if (err) { - LOG_ERR("Failed to send Private GATT Proxy Get (err %d)", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Private GATT Proxy state: %u", state); - return BTP_STATUS_SUCCESS; -} - -static uint8_t priv_gatt_proxy_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_gatt_proxy_set_cmd *cp = cmd; - - uint8_t state; - int err; - - state = cp->state; - - err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, &state); - if (err) { - LOG_ERR("Failed to send Private GATT Proxy Set (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t priv_node_id_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_node_id_get_cmd *cp = cmd; - struct bt_mesh_priv_node_id val; - uint16_t key_net_idx; - int err; - - key_net_idx = cp->key_net_idx; - - err = bt_mesh_priv_beacon_cli_node_id_get(net.net_idx, cp->dst, key_net_idx, &val); - if (err) { - LOG_ERR("Failed to send Private Node Identity Get (err %d)", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Private Node Identity state: %u %u %u", val.net_idx, val.state, val.status); - return BTP_STATUS_SUCCESS; -} - -static uint8_t priv_node_id_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_priv_node_id_set_cmd *cp = cmd; - struct bt_mesh_priv_node_id val; - int err; - - val.net_idx = cp->net_idx; - val.state = cp->state; - - err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val); - if (err) { - LOG_ERR("Failed to send Private Node Identity Set (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - int err; - - LOG_DBG(""); - - err = bt_mesh_proxy_private_identity_enable(); - if (err) { - LOG_ERR("Failed to enable proxy private identity (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -788,12 +655,6 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) BT_MESH_MODEL_BLOB_CLI(&blob_cli), #endif -#if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV) - BT_MESH_MODEL_PRIV_BEACON_SRV, -#endif -#if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) - BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli), -#endif }; struct model_data *lookup_model_bound(uint16_t id) { @@ -4715,44 +4576,6 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd), .func = rpr_reprov_remote }, -#endif -#if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI) - { - .opcode = BTP_MESH_PRIV_BEACON_GET, - .expect_len = sizeof(struct btp_priv_beacon_get_cmd), - .func = priv_beacon_get - }, - { - .opcode = BTP_MESH_PRIV_BEACON_SET, - .expect_len = sizeof(struct btp_priv_beacon_set_cmd), - .func = priv_beacon_set - }, - { - .opcode = BTP_MESH_PRIV_GATT_PROXY_GET, - .expect_len = sizeof(struct btp_priv_gatt_proxy_get_cmd), - .func = priv_gatt_proxy_get - }, - { - .opcode = BTP_MESH_PRIV_GATT_PROXY_SET, - .expect_len = sizeof(struct btp_priv_gatt_proxy_set_cmd), - .func = priv_gatt_proxy_set - }, - { - .opcode = BTP_MESH_PRIV_NODE_ID_GET, - .expect_len = sizeof(struct btp_priv_node_id_get_cmd), - .func = priv_node_id_get - }, - { - .opcode = BTP_MESH_PRIV_NODE_ID_SET, - .expect_len = sizeof(struct btp_priv_node_id_set_cmd), - .func = priv_node_id_set - }, - { - .opcode = BTP_MESH_PROXY_PRIVATE_IDENTITY, - .expect_len = 0, - .func = proxy_private_identity_enable - }, -#endif }; From 84a90fbf1539c5d600e08da50f96ce3e8ecfa6bc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:24 +0000 Subject: [PATCH 4285/4498] Revert "[nrf fromtree] tests: bluetooth: tester: Add Opcodes Aggregator support" This reverts commit 14e69effb12eee44178feadc4d8e9d0cac0b9cbd. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 5 - tests/bluetooth/tester/src/btp/btp_mesh.h | 10 -- tests/bluetooth/tester/src/btp_mesh.c | 115 +++------------------- 3 files changed, 11 insertions(+), 119 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 60f809f77e5..3352e36f3a4 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -9,11 +9,6 @@ CONFIG_BT_MESH_GATT_PROXY=y CONFIG_BT_MESH_LABEL_COUNT=2 CONFIG_BT_MESH_SUBNET_COUNT=2 CONFIG_BT_MESH_MODEL_GROUP_COUNT=2 -CONFIG_BT_MESH_OP_AGG_CLI=y -CONFIG_BT_MESH_OP_AGG_SRV=y -# PTS requires more key slots. -# First one is implicitly taken by Device Key. -CONFIG_BT_MESH_MODEL_KEY_COUNT=3 CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 63fb2adcf12..66a86bbb128 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -835,16 +835,6 @@ struct btp_mesh_models_metadata_get_rp { uint8_t data[0]; } __packed; -#define BTP_MESH_OPCODES_AGGREGATOR_INIT 0x55 -struct btp_mesh_opcodes_aggregator_init_cmd { - uint16_t net_idx; - uint16_t app_idx; - uint16_t dst; - uint16_t elem_addr; -} __packed; - -#define BTP_MESH_OPCODES_AGGREGATOR_SEND 0x56 - #define BTP_MESH_COMP_CHANGE_PREPARE 0x57 #define BTP_MESH_SET_COMP_ALT 0x58 diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 4f3d181fd1d..8c637320a11 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -634,12 +634,6 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), #endif -#if defined(CONFIG_BT_MESH_OP_AGG_SRV) - BT_MESH_MODEL_OP_AGG_SRV, -#endif -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - BT_MESH_MODEL_OP_AGG_CLI, -#endif #if defined(CONFIG_BT_MESH_RPR_CLI) BT_MESH_MODEL_RPR_CLI(&rpr_cli), #endif @@ -2497,8 +2491,6 @@ static uint8_t config_model_app_bind(const void *cmd, uint16_t cmd_len, LOG_DBG(""); - bt_mesh_cfg_cli_timeout_set(5000); - err = bt_mesh_cfg_cli_mod_app_bind(sys_le16_to_cpu(cp->net_idx), sys_le16_to_cpu(cp->address), sys_le16_to_cpu(cp->elem_address), @@ -2942,7 +2934,7 @@ static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len, .addr = sys_le16_to_cpu(cp->address), .app_idx = sys_le16_to_cpu(cp->app_idx), }; - uint8_t test_id = 0; + uint8_t test_id; size_t fault_count = 16; uint8_t faults[fault_count]; int err; @@ -2952,20 +2944,7 @@ static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_fault_clear(&health_cli, &ctx, sys_le16_to_cpu(cp->cid), -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif - &test_id, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif - faults, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif + &test_id, faults, &fault_count); } else { err = bt_mesh_health_cli_fault_clear_unack(&health_cli, &ctx, @@ -2998,37 +2977,20 @@ static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len, }; size_t fault_count = 16; uint8_t faults[fault_count]; + uint8_t test_id; + uint16_t cid; int err; LOG_DBG(""); + test_id = cp->test_id; + cid = sys_le16_to_cpu(cp->cid); + if (cp->ack) { - err = bt_mesh_health_cli_fault_test(&health_cli, &ctx, - sys_le16_to_cpu(cp->cid), -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - 0 : -#endif - cp->test_id, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif - faults, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif + err = bt_mesh_health_cli_fault_test(&health_cli, &ctx, cid, test_id, faults, &fault_count); -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - if (bt_mesh_op_agg_cli_seq_is_started()) { - fault_count = 0; - } -#endif } else { - err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx, - sys_le16_to_cpu(cp->cid), - cp->test_id); + err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx, cid, test_id); } if (err) { @@ -3039,8 +3001,8 @@ static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len, if (cp->ack) { struct btp_mesh_health_fault_test_rp *rp = rsp; - rp->test_id = cp->test_id; - rp->cid = cp->cid; + rp->test_id = test_id; + rp->cid = sys_cpu_to_le16(cid); (void)memcpy(rp->faults, faults, fault_count); *rsp_len = sizeof(*rp) + fault_count; @@ -3089,10 +3051,6 @@ static uint8_t health_period_set(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_period_set(&health_cli, &ctx, cp->divisor, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif &updated_divisor); } else { err = bt_mesh_health_cli_period_set_unack(&health_cli, &ctx, cp->divisor); @@ -3154,10 +3112,6 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, if (cp->ack) { err = bt_mesh_health_cli_attention_set(&health_cli, &ctx, cp->attention, -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - bt_mesh_op_agg_cli_seq_is_started() ? - NULL : -#endif &updated_attention); } else { err = bt_mesh_health_cli_attention_set_unack(&health_cli, &ctx, cp->attention); @@ -3179,41 +3133,6 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) -static uint8_t opcodes_aggregator_init(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_opcodes_aggregator_init_cmd *cp = cmd; - int err; - - LOG_DBG(""); - - err = bt_mesh_op_agg_cli_seq_start(cp->net_idx, cp->app_idx, cp->dst, cp->elem_addr); - if (err) { - LOG_ERR("Failed to init Opcodes Aggregator Context (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t opcodes_aggregator_send(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - int err; - - LOG_DBG(""); - - err = bt_mesh_op_agg_cli_seq_send(); - if (err) { - LOG_ERR("Failed to send Opcodes Aggregator message (err %d)", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - #if defined(CONFIG_BT_MESH_RPR_CLI) static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -4507,18 +4426,6 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd), .func = models_metadata_get }, -#endif -#if defined(CONFIG_BT_MESH_OP_AGG_CLI) - { - .opcode = BTP_MESH_OPCODES_AGGREGATOR_INIT, - .expect_len = sizeof(struct btp_mesh_opcodes_aggregator_init_cmd), - .func = opcodes_aggregator_init - }, - { - .opcode = BTP_MESH_OPCODES_AGGREGATOR_SEND, - .expect_len = 0, - .func = opcodes_aggregator_send - }, #endif { .opcode = BTP_MESH_COMP_CHANGE_PREPARE, From 6dac39351e9f74e3cdf6e535203bc7c22c1564a0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:25 +0000 Subject: [PATCH 4286/4498] Revert "[nrf fromtree] Bluetooth: Tester: Add Blob, DFU and DFD tests support" This reverts commit 26290321c5f585ca469dd52076fe458045a55d01. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 8 +- tests/bluetooth/tester/src/btp/btp_mesh.h | 68 -- tests/bluetooth/tester/src/btp/bttester.h | 3 - tests/bluetooth/tester/src/btp_core.c | 6 - tests/bluetooth/tester/src/btp_mesh.c | 999 +--------------------- 5 files changed, 2 insertions(+), 1082 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 3352e36f3a4..b537ae0001e 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -20,7 +20,7 @@ CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 -CONFIG_BT_MESH_TX_SEG_MSG_COUNT=10 +CONFIG_BT_MESH_TX_SEG_MSG_COUNT=3 CONFIG_BT_MESH_LPN_POLL_TIMEOUT=100 CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_CDB=y @@ -32,11 +32,5 @@ CONFIG_BT_MESH_PROVISIONER=y CONFIG_BT_MESH_RPR_SRV=y CONFIG_BT_MESH_RPR_CLI=y CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 -CONFIG_BT_MESH_BLOB_CLI=y -CONFIG_BT_MESH_DFU_CLI=y -CONFIG_BT_MESH_BLOB_SRV=y -CONFIG_BT_MESH_DFU_SRV=y -CONFIG_BT_MESH_DFD_SRV=y -CONFIG_BT_MESH_DFU_SLOT_CNT=2 CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 66a86bbb128..29523d02d8c 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -895,72 +895,6 @@ struct btp_rpr_reprov_remote_cmd { bool comp_change; } __packed; -#define BTP_MMDL_DFU_INFO_GET 0x5f -struct btp_mmdl_dfu_info_get_cmd { - uint8_t limit; -} __packed; - -#define BTP_MMDL_BLOB_INFO_GET 0x60 -struct btp_mmdl_blob_info_get_cmd { - uint8_t addr_cnt; - uint8_t addr[]; -} __packed; - -#define BTP_MMDL_DFU_UPDATE_METADATA_CHECK 0x61 -struct btp_mmdl_dfu_metadata_check_cmd { - uint8_t index; - uint8_t slot_idx; - uint8_t slot_size; - uint8_t fwid_len; - uint8_t metadata_len; - uint8_t data[]; -} __packed; - -struct btp_mmdl_dfu_metadata_check_rp { - uint8_t idx; - uint8_t status; - uint8_t effect; -} __packed; - -#define BTP_MMDL_DFU_FIRMWARE_UPDATE_GET 0x62 -#define BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL 0x63 -#define BTP_MMDL_DFU_FIRMWARE_UPDATE_START 0x64 -struct btp_mmdl_dfu_firmware_update_cmd { - uint8_t addr_cnt; - uint8_t slot_idx; - uint8_t slot_size; - uint8_t fwid_len; - uint8_t metadata_len; - uint8_t block_size; - uint16_t chunk_size; - uint8_t data[]; -} __packed; - -struct btp_mmdl_dfu_firmware_update_rp { - uint8_t status; -} __packed; - -#define BTP_MMDL_BLOB_SRV_RECV 0x65 -struct btp_mmdl_blob_srv_recv_cmd { - uint64_t id; - uint16_t timeout; -} __packed; - -#define BTP_MMDL_BLOB_TRANSFER_START 0x66 -struct btp_mmdl_blob_transfer_start_cmd { - uint64_t id; - uint16_t size; - uint8_t block_size; - uint16_t chunk_size; - uint16_t timeout; -} __packed; - -#define BTP_MMDL_BLOB_TRANSFER_CANCEL 0x67 -#define BTP_MMDL_BLOB_TRANSFER_GET 0x68 -#define BTP_MMDL_BLOB_SRV_CANCEL 0x69 -#define BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY 0x6A -#define BTP_MMDL_DFU_SRV_APPLY 0x6B - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { @@ -1062,5 +996,3 @@ struct btp_mesh_model_recv_ev { uint8_t payload_len; uint8_t payload[]; } __packed; - -#define MESH_EV_BLOB_LOST_TARGET 0x90 diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index 84d4722a913..b30eee70d44 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -73,9 +73,6 @@ uint8_t tester_unregister_vocs(void); uint8_t tester_init_ias(void); uint8_t tester_unregister_ias(void); -uint8_t tester_init_mmdl(void); -uint8_t tester_unregister_mmdl(void); - uint8_t tester_init_gap(void); uint8_t tester_unregister_gap(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 7ece1224ed0..36f92619bfc 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -118,9 +118,6 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_init_mesh(); break; - case BTP_SERVICE_ID_MESH_MDL: - status = tester_init_mmdl(); - break; #endif /* CONFIG_BT_MESH */ #if defined(CONFIG_BT_VCP_VOL_REND) case BTP_SERVICE_ID_VCS: @@ -204,9 +201,6 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_unregister_mesh(); break; - case BTP_SERVICE_ID_MESH_MDL: - status = tester_unregister_mmdl(); - break; #endif /* CONFIG_BT_MESH */ #if defined(CONFIG_BT_VCP_VOL_REND) case BTP_SERVICE_ID_VCS: diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 8c637320a11..40ae3a6f038 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -12,18 +12,15 @@ #include #include #include -#include #include #include #include -#include #include #define LOG_MODULE_NAME bttester_mesh LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #include "btp/btp.h" -#include "dfu_slot.h" #define CID_LOCAL 0x05F1 #define COMPANY_ID_LF 0x05F1 @@ -57,245 +54,7 @@ static uint8_t vnd_app_key[16]; static uint16_t vnd_app_key_idx = 0x000f; /* Model send data */ -#define MODEL_BOUNDS_MAX 100 - -#if defined(CONFIG_BT_MESH_BLOB_SRV) || defined(CONFIG_BT_MESH_BLOB_CLI) -/* BLOB Model data*/ -static uint8_t blob_rx_sum; -static bool blob_valid; -static const char *blob_data = "11111111111111111111111111111111"; - -static int blob_io_open(const struct bt_mesh_blob_io *io, - const struct bt_mesh_blob_xfer *xfer, - enum bt_mesh_blob_io_mode mode) -{ - blob_rx_sum = 0; - blob_valid = true; - return 0; -} - -static int blob_chunk_wr(const struct bt_mesh_blob_io *io, - const struct bt_mesh_blob_xfer *xfer, - const struct bt_mesh_blob_block *block, - const struct bt_mesh_blob_chunk *chunk) -{ - for (int i = 0; i < chunk->size; ++i) { - blob_rx_sum += chunk->data[i]; - if (chunk->data[i] != - blob_data[(i + chunk->offset) % strlen(blob_data)]) { - blob_valid = false; - } - } - - return 0; -} - -static int blob_chunk_rd(const struct bt_mesh_blob_io *io, - const struct bt_mesh_blob_xfer *xfer, - const struct bt_mesh_blob_block *block, - const struct bt_mesh_blob_chunk *chunk) -{ - for (int i = 0; i < chunk->size; ++i) { - chunk->data[i] = - blob_data[(i + chunk->offset) % strlen(blob_data)]; - } - - return 0; -} - -static const struct bt_mesh_blob_io dummy_blob_io = { - .open = blob_io_open, - .rd = blob_chunk_rd, - .wr = blob_chunk_wr, -}; -#endif - -#if defined(CONFIG_BT_MESH_DFD_SRV) -/* DFD Model data*/ -static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, - const struct bt_mesh_blob_io **io) -{ - LOG_DBG("Uploading new firmware image to the distributor."); - - *io = &dummy_blob_io; - - return 0; -} - -static void dfd_srv_del(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot) -{ - LOG_DBG("Deleting the firmware image from the distributor."); -} - -static int dfd_srv_send(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, - const struct bt_mesh_blob_io **io) -{ - LOG_DBG("Starting the firmware distribution."); - - *io = &dummy_blob_io; - - return 0; -} - -static struct bt_mesh_dfd_srv_cb dfd_srv_cb = { - .recv = dfd_srv_recv, - .del = dfd_srv_del, - .send = dfd_srv_send, -}; - -static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb); -#endif - -#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) -static struct { - struct bt_mesh_blob_cli_inputs inputs; - struct bt_mesh_blob_target targets[32]; - struct bt_mesh_blob_target_pull pull[32]; - uint8_t target_count; - struct bt_mesh_blob_xfer xfer; -} blob_cli_xfer; - -static void blob_cli_lost_target(struct bt_mesh_blob_cli *cli, - struct bt_mesh_blob_target *target, - enum bt_mesh_blob_status reason) -{ - LOG_DBG("Mesh Blob: Lost target 0x%04x (reason: %u)", target->addr, - reason); - tester_event(BTP_SERVICE_ID_MESH, MESH_EV_BLOB_LOST_TARGET, NULL, 0); -} - -static void blob_cli_caps(struct bt_mesh_blob_cli *cli, - const struct bt_mesh_blob_cli_caps *caps) -{ - const char *const modes[] = { - "none", - "push", - "pull", - "all", - }; - - if (!caps) { - LOG_DBG("None of the targets can be used for BLOB transfer"); - return; - } - - LOG_DBG("Mesh BLOB: capabilities:"); - LOG_DBG("\tMax BLOB size: %u bytes", caps->max_size); - LOG_DBG("\tBlock size: %u-%u (%u-%u bytes)", caps->min_block_size_log, - caps->max_block_size_log, 1 << caps->min_block_size_log, - 1 << caps->max_block_size_log); - LOG_DBG("\tMax chunks: %u", caps->max_chunks); - LOG_DBG("\tChunk size: %u", caps->max_chunk_size); - LOG_DBG("\tMTU size: %u", caps->mtu_size); - LOG_DBG("\tModes: %s", modes[caps->modes]); -} - -static void blob_cli_end(struct bt_mesh_blob_cli *cli, - const struct bt_mesh_blob_xfer *xfer, bool success) -{ - if (success) { - LOG_DBG("Mesh BLOB transfer complete."); - } else { - LOG_DBG("Mesh BLOB transfer failed."); - } -} - -static const struct bt_mesh_blob_cli_cb blob_cli_handlers = { - .lost_target = blob_cli_lost_target, - .caps = blob_cli_caps, - .end = blob_cli_end, -}; - -static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers }; -#endif - -#if defined(CONFIG_BT_MESH_DFU_SRV) -const char *metadata_data = "1100000000000011"; - -static uint8_t dfu_fwid[] = { - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static struct bt_mesh_dfu_img dfu_imgs[] = { { - .fwid = &dfu_fwid, - .fwid_len = sizeof(dfu_fwid), -} }; - -static int dfu_meta_check(struct bt_mesh_dfu_srv *srv, - const struct bt_mesh_dfu_img *img, - struct net_buf_simple *metadata, - enum bt_mesh_dfu_effect *effect) -{ - char string[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1]; - int i; - size_t len; - - len = bin2hex(metadata->data, metadata->len, string, sizeof(string)); - string[len] = '\0'; - - for (i = 0; i <= len; i++) { - if (string[i] != metadata_data[i]) { - LOG_ERR("Wrong Firmware Metadata"); - return -EINVAL; - } - } - - return 0; -} - -static int dfu_start(struct bt_mesh_dfu_srv *srv, - const struct bt_mesh_dfu_img *img, - struct net_buf_simple *metadata, - const struct bt_mesh_blob_io **io) -{ - LOG_DBG("DFU setup"); - - *io = &dummy_blob_io; - - return 0; -} - -static void dfu_end(struct bt_mesh_dfu_srv *srv, - const struct bt_mesh_dfu_img *img, bool success) -{ - if (!success) { - LOG_ERR("DFU failed"); - return; - } - - if (!blob_valid) { - bt_mesh_dfu_srv_rejected(srv); - return; - } - - bt_mesh_dfu_srv_verified(srv); -} - -static int dfu_apply(struct bt_mesh_dfu_srv *srv, - const struct bt_mesh_dfu_img *img) -{ - if (!blob_valid) { - return -EINVAL; - } - - LOG_DBG("Applying DFU transfer..."); - - return 0; -} - -static const struct bt_mesh_dfu_srv_cb dfu_handlers = { - .check = dfu_meta_check, - .start = dfu_start, - .end = dfu_end, - .apply = dfu_apply, -}; - -static struct bt_mesh_dfu_srv dfu_srv = - BT_MESH_DFU_SRV_INIT(&dfu_handlers, dfu_imgs, ARRAY_SIZE(dfu_imgs)); -#endif /* CONFIG_BT_MESH_DFU_SRV */ +#define MODEL_BOUNDS_MAX 2 /* Model Authentication Method */ #define AUTH_METHOD_STATIC 0x01 @@ -607,16 +366,6 @@ static struct bt_mesh_rpr_cli rpr_cli = { }; #endif -#if defined(CONFIG_BT_MESH_DFU_SRV) -static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG("Applying image on server"); - bt_mesh_dfu_srv_applied(&dfu_srv); - return BTP_STATUS_SUCCESS; -} -#endif - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -640,28 +389,8 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_RPR_SRV) BT_MESH_MODEL_RPR_SRV, #endif -#if defined(CONFIG_BT_MESH_DFD_SRV) - BT_MESH_MODEL_DFD_SRV(&dfd_srv), -#endif -#if defined(CONFIG_BT_MESH_DFU_SRV) - BT_MESH_MODEL_DFU_SRV(&dfu_srv), -#endif -#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) - BT_MESH_MODEL_BLOB_CLI(&blob_cli), -#endif }; -struct model_data *lookup_model_bound(uint16_t id) -{ - int i; - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (model_bound[i].model && model_bound[i].model->id == id) { - return &model_bound[i]; - } - } - - return NULL; -} static struct bt_mesh_model vnd_models[] = { BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, NULL), @@ -3360,643 +3089,6 @@ static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len, } #endif -#if defined(CONFIG_BT_MESH_DFD_SRV) -static struct { - struct bt_mesh_dfu_target targets[32]; - struct bt_mesh_blob_target_pull pull[32]; - size_t target_cnt; - struct bt_mesh_blob_cli_inputs inputs; -} dfu_tx; - -static void dfu_tx_prepare(void) -{ - sys_slist_init(&dfu_tx.inputs.targets); - - for (int i = 0; i < dfu_tx.target_cnt; i++) { - /* Reset target context. */ - uint16_t addr = dfu_tx.targets[i].blob.addr; - - memset(&dfu_tx.targets[i].blob, 0, - sizeof(struct bt_mesh_blob_target)); - memset(&dfu_tx.pull[i], 0, - sizeof(struct bt_mesh_blob_target_pull)); - dfu_tx.targets[i].blob.addr = addr; - dfu_tx.targets[i].blob.pull = &dfu_tx.pull[i]; - - sys_slist_append(&dfu_tx.inputs.targets, - &dfu_tx.targets[i].blob.n); - } -} - -static void dfu_target(uint8_t img_idx, uint16_t addr) -{ - if (dfu_tx.target_cnt == ARRAY_SIZE(dfu_tx.targets)) { - LOG_ERR("No room."); - return; - } - - for (int i = 0; i < dfu_tx.target_cnt; i++) { - if (dfu_tx.targets[i].blob.addr == addr) { - LOG_ERR("Target 0x%04x already exists", addr); - return; - } - } - - dfu_tx.targets[dfu_tx.target_cnt].blob.addr = addr; - dfu_tx.targets[dfu_tx.target_cnt].img_idx = img_idx; - sys_slist_append(&dfu_tx.inputs.targets, - &dfu_tx.targets[dfu_tx.target_cnt].blob.n); - dfu_tx.target_cnt++; - - LOG_DBG("Added target 0x%04x", addr); -} -static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len, - uint8_t *metadata, size_t metadata_len) -{ - struct bt_mesh_dfu_slot *slot; - int err; - - slot = bt_mesh_dfu_slot_reserve(); - err = bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len); - if (err) { - LOG_ERR("Failed to set slot info: %d", err); - return; - } - - err = bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len); - if (err) { - LOG_ERR("Failed to set slot fwid: %d", err); - return; - } - - bt_mesh_dfu_slot_commit(slot); - if (err) { - LOG_ERR("Failed to commit slot: %d", err); - return; - } - - LOG_DBG("Slot added."); -} -static enum bt_mesh_dfu_iter dfu_img_cb(struct bt_mesh_dfu_cli *cli, - struct bt_mesh_msg_ctx *ctx, - uint8_t idx, uint8_t total, - const struct bt_mesh_dfu_img *img, - void *cb_data) -{ - char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1]; - size_t len; - - idx = 0xff; - - if (img->fwid_len <= sizeof(fwid)) { - len = bin2hex(img->fwid, img->fwid_len, fwid, sizeof(fwid)); - } else { - LOG_ERR("FWID is too big"); - return BT_MESH_DFU_ITER_STOP; - } - - fwid[len] = '\0'; - - LOG_DBG("Image %u:", idx); - LOG_DBG("\tFWID: "); - if (img->uri) { - LOG_DBG("\tURI: "); - } - - return BT_MESH_DFU_ITER_CONTINUE; -} - -static uint8_t dfu_info_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_dfu_info_get_cmd *cp = cmd; - struct model_data *model_bound; - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - uint8_t max_count; - int err = 0; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - ctx.addr = model_bound->addr; - ctx.app_idx = model_bound->appkey_idx; - - max_count = cp->limit; - - err = bt_mesh_dfu_cli_imgs_get(&dfd_srv.dfu, &ctx, dfu_img_cb, NULL, - max_count); - if (err) { - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t dfu_update_metadata_check(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_dfu_metadata_check_cmd *cp = cmd; - struct btp_mmdl_dfu_metadata_check_rp *rp = rsp; - const struct bt_mesh_dfu_slot *slot; - struct model_data *model_bound; - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - struct bt_mesh_dfu_metadata_status rsp_data; - uint8_t img_idx, slot_idx; - size_t size; - size_t fwid_len; - size_t metadata_len; - uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; - uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - ctx.addr = model_bound->addr; - ctx.app_idx = model_bound->appkey_idx; - img_idx = cp->index; - slot_idx = cp->slot_idx; - size = cp->slot_size; - fwid_len = cp->fwid_len; - metadata_len = cp->metadata_len; - - if ((metadata_len > 0) && - (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) { - memcpy(&metadata, cp->data, metadata_len); - } - - dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len); - - slot = bt_mesh_dfu_slot_at(slot_idx); - if (!slot) { - LOG_ERR("No image in slot %u", slot_idx); - return BTP_STATUS_FAILED; - } - - err = bt_mesh_dfu_cli_metadata_check(&dfd_srv.dfu, &ctx, img_idx, slot, - &rsp_data); - - if (err) { - LOG_ERR("ERR %d", err); - return BTP_STATUS_FAILED; - } - - rp->idx = rsp_data.idx; - rp->status = rsp_data.status; - rp->effect = rsp_data.effect; - - *rsp_len = sizeof(struct btp_mmdl_dfu_metadata_check_rp); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t dfu_firmware_update_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct model_data *model_bound; - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - struct bt_mesh_dfu_target_status rsp_data; - struct btp_mmdl_dfu_firmware_update_rp *rp = rsp; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - ctx.addr = model_bound->addr; - ctx.app_idx = model_bound->appkey_idx; - - err = bt_mesh_dfu_cli_status_get(&dfd_srv.dfu, &ctx, &rsp_data); - if (err) { - LOG_ERR("err %d", err); - return BTP_STATUS_FAILED; - } - - rp->status = rsp_data.status; - *rsp_len = sizeof(struct btp_mmdl_dfu_firmware_update_rp); - return BTP_STATUS_SUCCESS; -} - -static uint8_t dfu_firmware_update_cancel(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct model_data *model_bound; - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - ctx.addr = model_bound->addr; - ctx.app_idx = model_bound->appkey_idx; - - err = bt_mesh_dfu_cli_cancel(&dfd_srv.dfu, &ctx); - if (err) { - LOG_ERR("err %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t dfu_firmware_update_start(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_dfu_firmware_update_cmd *cp = cmd; - struct model_data *model_bound; - struct bt_mesh_dfu_cli_xfer xfer; - uint8_t addr_cnt; - uint16_t addr = BT_MESH_ADDR_UNASSIGNED; - uint8_t slot_idx; - size_t size; - size_t fwid_len; - size_t metadata_len; - uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; - uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; - int err = 0; - int i = 0; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - struct bt_mesh_dfu_cli_xfer_blob_params blob = { - .block_size_log = cp->block_size, - .chunk_size = cp->chunk_size, - }; - - addr_cnt = cp->addr_cnt; - slot_idx = cp->slot_idx; - size = cp->slot_size; - fwid_len = cp->fwid_len; - metadata_len = cp->metadata_len; - xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; - xfer.blob_params = &blob; - - if ((metadata_len > 0) && - (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) { - memcpy(&metadata, cp->data, metadata_len); - } - - bt_mesh_dfu_slot_del_all(); - - dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len); - - xfer.slot = bt_mesh_dfu_slot_at(slot_idx); - if (!xfer.slot) { - LOG_ERR("No image in slot %u", slot_idx); - return BTP_STATUS_FAILED; - } - - for (i = 0; i < addr_cnt; i++) { - addr = cp->data[metadata_len + 1 + i * sizeof(uint16_t)] | - (cp->data[metadata_len + i * sizeof(uint16_t)] << 8); - dfu_target(slot_idx, addr); - } - - dfu_tx_prepare(); - - if (!dfu_tx.target_cnt) { - LOG_ERR("No targets."); - return BTP_STATUS_FAILED; - } - - if (addr_cnt > 1) { - dfu_tx.inputs.group = BT_MESH_ADDR_UNASSIGNED; - } else { - dfu_tx.inputs.group = addr; - } - - dfu_tx.inputs.app_idx = model_bound->appkey_idx; - dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT; - - err = bt_mesh_dfu_cli_send(&dfd_srv.dfu, &dfu_tx.inputs, &dummy_blob_io, &xfer); - - if (err) { - LOG_ERR("err %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t dfu_firmware_update_apply(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct model_data *model_bound; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - err = bt_mesh_dfu_cli_apply(&dfd_srv.dfu); - if (err) { - LOG_ERR("err %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - -#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) -static void blob_cli_inputs_prepare(uint16_t group, uint16_t app_idx) -{ - int i; - - blob_cli_xfer.inputs.ttl = BT_MESH_TTL_DEFAULT; - blob_cli_xfer.inputs.group = group; - blob_cli_xfer.inputs.app_idx = app_idx; - sys_slist_init(&blob_cli_xfer.inputs.targets); - - for (i = 0; i < blob_cli_xfer.target_count; ++i) { - /* Reset target context. */ - uint16_t addr = blob_cli_xfer.targets[i].addr; - - memset(&blob_cli_xfer.targets[i], 0, - sizeof(struct bt_mesh_blob_target)); - memset(&blob_cli_xfer.pull[i], 0, - sizeof(struct bt_mesh_blob_target_pull)); - blob_cli_xfer.targets[i].addr = addr; - blob_cli_xfer.targets[i].pull = &blob_cli_xfer.pull[i]; - - sys_slist_append(&blob_cli_xfer.inputs.targets, - &blob_cli_xfer.targets[i].n); - } -} - -static int cmd_blob_target(uint16_t addr) -{ - struct bt_mesh_blob_target *t; - - if (blob_cli_xfer.target_count == ARRAY_SIZE(blob_cli_xfer.targets)) { - LOG_ERR("No more room"); - return 0; - } - - t = &blob_cli_xfer.targets[blob_cli_xfer.target_count]; - - t->addr = addr; - - LOG_DBG("Added target 0x%04x", t->addr); - - blob_cli_xfer.target_count++; - return 0; -} - -static uint8_t blob_info_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_blob_info_get_cmd *cp = cmd; - struct model_data *model_bound; - uint16_t addr = BT_MESH_ADDR_UNASSIGNED; - uint16_t group = BT_MESH_ADDR_UNASSIGNED; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - for (int i = 0; i < cp->addr_cnt; i++) { - addr = cp->addr[1 + i * sizeof(uint16_t)] | - (cp->addr[i * sizeof(uint16_t)] << 8); - err = cmd_blob_target(addr); - if (err) { - LOG_ERR("err target %d", err); - return BTP_STATUS_FAILED; - } - } - - if (cp->addr_cnt > 1) { - group = BT_MESH_ADDR_UNASSIGNED; - } else { - group = addr; - } - - if (!blob_cli_xfer.target_count) { - LOG_ERR("Failed: No targets"); - return BTP_STATUS_FAILED; - } - - blob_cli_inputs_prepare(group, model_bound->appkey_idx); - - err = bt_mesh_blob_cli_caps_get(&blob_cli, &blob_cli_xfer.inputs); - - if (err) { - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_blob_transfer_start_cmd *cp = cmd; - struct model_data *model_bound; - int err = 0; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - if (!blob_cli_xfer.target_count) { - LOG_ERR("Failed: No targets"); - return BTP_STATUS_FAILED; - } - blob_cli_xfer.xfer.id = cp->id; - blob_cli_xfer.xfer.size = cp->size; - blob_cli_xfer.xfer.block_size_log = cp->block_size; - blob_cli_xfer.xfer.chunk_size = cp->chunk_size; - - if (blob_cli.caps.modes) { - blob_cli_xfer.xfer.mode = blob_cli.caps.modes; - } else { - blob_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; - } - - if (cp->timeout) { - blob_cli_xfer.inputs.timeout_base = cp->timeout; - } - - err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs, - &blob_cli_xfer.xfer, &dummy_blob_io); - - if (err) { - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t blob_transfer_cancel(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - LOG_DBG(""); - - bt_mesh_blob_cli_cancel(&blob_cli); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t blob_transfer_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct model_data *model_bound; - uint16_t group; - int err; - - LOG_DBG(""); - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - group = model_bound->addr; - - err = cmd_blob_target(group); - if (err) { - LOG_ERR("err target %d", err); - return BTP_STATUS_FAILED; - } - - if (!blob_cli_xfer.target_count) { - LOG_ERR("Failed: No targets"); - return BTP_STATUS_FAILED; - } - - blob_cli_inputs_prepare(group, model_bound->appkey_idx); - - err = bt_mesh_blob_cli_xfer_progress_get(&blob_cli, &blob_cli_xfer.inputs); - - if (err) { - LOG_ERR("ERR %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif /* CONFIG_BT_MESH_BLOB_CLI */ - -#if defined(CONFIG_BT_MESH_BLOB_SRV) -static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mmdl_blob_srv_recv_cmd *cp = cmd; - struct model_data *model_bound; - int err; - -#if defined(CONFIG_BT_MESH_DFU_SRV) - struct bt_mesh_blob_srv *srv = &dfu_srv.blob; -#elif defined(CONFIG_BT_MESH_DFD_SRV) - struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; -#endif - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - uint16_t timeout_base; - uint64_t id; - - LOG_DBG(""); - - id = cp->id; - timeout_base = cp->timeout; - - err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, BT_MESH_TTL_MAX, - timeout_base); - - if (err) { - LOG_ERR("ERR %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t blob_srv_cancel(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - struct model_data *model_bound; - int err; - -#if defined(CONFIG_BT_MESH_DFU_SRV) - struct bt_mesh_blob_srv *srv = &dfu_srv.blob; -#elif defined(CONFIG_BT_MESH_DFD_SRV) - struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob; -#endif - - model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV); - if (!model_bound) { - LOG_ERR("Model not found"); - return BTP_STATUS_FAILED; - } - - LOG_DBG(""); - - err = bt_mesh_blob_srv_cancel(srv); - - if (err) { - LOG_ERR("ERR %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - static const struct btp_handler handlers[] = { { .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, @@ -4485,83 +3577,6 @@ static const struct btp_handler handlers[] = { }, }; - -static const struct btp_handler mdl_handlers[] = { -#if defined(CONFIG_BT_MESH_DFD_SRV) - { - .opcode = BTP_MMDL_DFU_INFO_GET, - .expect_len = sizeof(struct btp_mmdl_dfu_info_get_cmd), - .func = dfu_info_get, - }, - { - .opcode = BTP_MMDL_DFU_UPDATE_METADATA_CHECK, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = dfu_update_metadata_check, - }, - { - .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_GET, - .expect_len = 0, - .func = dfu_firmware_update_get, - }, - { - .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL, - .expect_len = 0, - .func = dfu_firmware_update_cancel, - }, - { - .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_START, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = dfu_firmware_update_start, - }, - { - .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY, - .expect_len = 0, - .func = dfu_firmware_update_apply, - }, -#endif -#if defined(CONFIG_BT_MESH_BLOB_CLI) && !defined(CONFIG_BT_MESH_DFD_SRV) - { - .opcode = BTP_MMDL_BLOB_INFO_GET, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = blob_info_get, - }, - { - .opcode = BTP_MMDL_BLOB_TRANSFER_START, - .expect_len = sizeof(struct btp_mmdl_blob_transfer_start_cmd), - .func = blob_transfer_start, - }, - { - .opcode = BTP_MMDL_BLOB_TRANSFER_CANCEL, - .expect_len = 0, - .func = blob_transfer_cancel, - }, - { - .opcode = BTP_MMDL_BLOB_TRANSFER_GET, - .expect_len = 0, - .func = blob_transfer_get, - }, -#endif -#if defined(CONFIG_BT_MESH_BLOB_SRV) - { - .opcode = BTP_MMDL_BLOB_SRV_RECV, - .expect_len = sizeof(struct btp_mmdl_blob_srv_recv_cmd), - .func = blob_srv_recv - }, - { - .opcode = BTP_MMDL_BLOB_SRV_CANCEL, - .expect_len = 0, - .func = blob_srv_cancel - }, -#endif -#if defined(CONFIG_BT_MESH_DFU_SRV) - { - .opcode = BTP_MMDL_DFU_SRV_APPLY, - .expect_len = 0, - .func = dfu_srv_apply - }, -#endif -}; - void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { @@ -4770,15 +3785,3 @@ uint8_t tester_unregister_mesh(void) { return BTP_STATUS_SUCCESS; } - -uint8_t tester_init_mmdl(void) -{ - tester_register_command_handlers(BTP_SERVICE_ID_MESH_MDL, mdl_handlers, - ARRAY_SIZE(mdl_handlers)); - return BTP_STATUS_SUCCESS; -} - -uint8_t tester_unregister_mmdl(void) -{ - return BTP_STATUS_SUCCESS; -} From f5b4ffa8b067ccc60e2cd19700dd5fc120b00e1c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:25 +0000 Subject: [PATCH 4287/4498] Revert "[nrf fromtree] Tests: Bluetooth: tester: enable Remote Provisioning" This reverts commit 2560e34ef5baf2d9a4c0ddadc36e4037a39d5569. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 4 - tests/bluetooth/tester/src/btp/btp_mesh.h | 61 --- tests/bluetooth/tester/src/btp_mesh.c | 434 +--------------------- 3 files changed, 4 insertions(+), 495 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index b537ae0001e..43e666d0eb3 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -28,9 +28,5 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y -CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_RPR_SRV=y -CONFIG_BT_MESH_RPR_CLI=y -CONFIG_BT_MESH_RPR_AD_TYPES_MAX=2 CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 29523d02d8c..67ce612c2ac 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -835,66 +835,6 @@ struct btp_mesh_models_metadata_get_rp { uint8_t data[0]; } __packed; -#define BTP_MESH_COMP_CHANGE_PREPARE 0x57 - -#define BTP_MESH_SET_COMP_ALT 0x58 - -#define BTP_MESH_RPR_SCAN_START 0x59 -struct btp_rpr_scan_start_cmd { - uint16_t dst; - uint8_t timeout; - uint8_t uuid[16]; -} __packed; - -#define BTP_MESH_RPR_EXT_SCAN_START 0x5a -struct btp_rpr_ext_scan_start_cmd { - uint16_t dst; - uint8_t timeout; - uint8_t uuid[16]; - uint8_t ad_count; - uint8_t ad_types[]; -} __packed; - -#define BTP_MESH_RPR_SCAN_CAPS_GET 0x5b -struct btp_rpr_scan_caps_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_RPR_SCAN_GET 0x5c -struct btp_rpr_scan_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_RPR_SCAN_STOP 0x5d -struct btp_rpr_scan_stop_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_RPR_LINK_GET 0x5e -struct btp_rpr_link_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_RPR_LINK_CLOSE 0x5f -struct btp_rpr_link_close_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_RPR_PROV_REMOTE 0x60 -struct btp_rpr_prov_remote_cmd { - uint16_t dst; - uint8_t uuid[16]; - uint16_t net_idx; - uint16_t addr; -} __packed; - -#define BTP_MESH_RPR_REPROV_REMOTE 0x61 -struct btp_rpr_reprov_remote_cmd { - uint16_t dst; - uint16_t addr; - bool comp_change; -} __packed; - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { @@ -918,7 +858,6 @@ struct btp_mesh_in_action_ev { #define BTP_MESH_PROV_BEARER_PB_ADV 0x00 #define BTP_MESH_PROV_BEARER_PB_GATT 0x01 -#define BTP_MESH_PROV_BEARER_REMOTE 0x04 #define BTP_MESH_EV_PROV_LINK_OPEN 0x84 struct btp_mesh_prov_link_open_ev { uint8_t bearer; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 40ae3a6f038..232e3d7d8b4 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -76,7 +76,6 @@ static struct { .dst = BT_MESH_ADDR_UNASSIGNED, }; -static bool default_comp = true; static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -323,49 +322,6 @@ static struct bt_mesh_cfg_cli cfg_cli = { static struct bt_mesh_sar_cfg_cli sar_cfg_cli; #endif -#if defined(CONFIG_BT_MESH_RPR_CLI) -static void rpr_scan_report(struct bt_mesh_rpr_cli *cli, - const struct bt_mesh_rpr_node *srv, - struct bt_mesh_rpr_unprov *unprov, - struct net_buf_simple *adv_data) -{ - char uuid_hex_str[32 + 1]; - - bin2hex(unprov->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str)); - - LOG_DBG("Server 0x%04x:\n" - "\tuuid: %s\n" - "\tOOB: 0x%04x", - srv->addr, uuid_hex_str, unprov->oob); - - while (adv_data && adv_data->len > 2) { - uint8_t len, type; - uint8_t data[31]; - - len = net_buf_simple_pull_u8(adv_data) - 1; - type = net_buf_simple_pull_u8(adv_data); - memcpy(data, net_buf_simple_pull_mem(adv_data, len), len); - data[len] = '\0'; - - if (type == BT_DATA_URI) { - LOG_DBG("\tURI: \"\\x%02x%s\"", - data[0], &data[1]); - } else if (type == BT_DATA_NAME_COMPLETE) { - LOG_DBG("\tName: \"%s\"", data); - } else { - char string[64 + 1]; - - bin2hex(data, len, string, sizeof(string)); - LOG_DBG("\t0x%02x: %s", type, string); - } - } -} - -static struct bt_mesh_rpr_cli rpr_cli = { - .scan_report = rpr_scan_report, -}; -#endif - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), @@ -383,12 +339,6 @@ static struct bt_mesh_model root_models[] = { #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), #endif -#if defined(CONFIG_BT_MESH_RPR_CLI) - BT_MESH_MODEL_RPR_CLI(&rpr_cli), -#endif -#if defined(CONFIG_BT_MESH_RPR_SRV) - BT_MESH_MODEL_RPR_SRV, -#endif }; static struct bt_mesh_model vnd_models[] = { @@ -413,9 +363,6 @@ static void link_open(bt_mesh_prov_bearer_t bearer) case BT_MESH_PROV_GATT: ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; - case BT_MESH_PROV_REMOTE: - ev.bearer = BTP_MESH_PROV_BEARER_REMOTE; - break; default: LOG_ERR("Invalid bearer"); @@ -438,9 +385,6 @@ static void link_close(bt_mesh_prov_bearer_t bearer) case BT_MESH_PROV_GATT: ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; - case BT_MESH_PROV_REMOTE: - ev.bearer = BTP_MESH_PROV_BEARER_REMOTE; - break; default: LOG_ERR("Invalid bearer"); @@ -532,24 +476,12 @@ static void prov_reset(void) LOG_DBG(""); bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); - - if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) { - bt_mesh_prov_enable(BT_MESH_PROV_REMOTE); - } } static const struct bt_mesh_comp comp = { .cid = CID_LOCAL, .elem = elements, .elem_count = ARRAY_SIZE(elements), - .vid = 1, -}; - -static const struct bt_mesh_comp comp_alt = { - .cid = CID_LOCAL, - .elem = elements, - .elem_count = ARRAY_SIZE(elements), - .vid = 2, }; static struct bt_mesh_prov prov = { @@ -564,7 +496,6 @@ static struct bt_mesh_prov prov = { .complete = prov_complete, .node_added = prov_node_added, .reset = prov_reset, - .uri = "Tester", }; static uint8_t config_prov(const void *cmd, uint16_t cmd_len, @@ -686,26 +617,19 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, LOG_DBG(""); - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - printk("Loading stored settings\n"); - settings_load(); + err = bt_mesh_init(&prov, &comp); + if (err) { + return BTP_STATUS_FAILED; } if (addr) { err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, addr, dev_key); - if (err && err != -EALREADY) { + if (err) { return BTP_STATUS_FAILED; } } else { err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); - if (err && err != -EALREADY) { - return BTP_STATUS_FAILED; - } - } - - if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) { - err = bt_mesh_prov_enable(BT_MESH_PROV_REMOTE); if (err) { return BTP_STATUS_FAILED; } @@ -1281,62 +1205,6 @@ static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -static uint8_t change_prepare(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - int err; - - LOG_DBG(""); - - err = bt_mesh_comp_change_prepare(); - if (err < 0) { - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -#if IS_ENABLED(CONFIG_BT_SETTINGS) -static int comp_alt_set(const char *name, size_t len_rd, - settings_read_cb read_cb, void *store) -{ - ssize_t len; - bool alt_comp_value; - - if (len_rd == 0) { - LOG_DBG("Default composition"); - } - - len = read_cb(store, &alt_comp_value, sizeof(alt_comp_value)); - if (len < 0 || len != len_rd) { - LOG_ERR("Failed to read value (err %zd)", len); - return len; - } - - if (alt_comp_value) { - default_comp = false; - } - - return 0; -} - -SETTINGS_STATIC_HANDLER_DEFINE(tester_comp_alt, "tester/comp_alt", NULL, comp_alt_set, NULL, NULL); -#endif - -static uint8_t set_comp_alt(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ -#if !IS_ENABLED(CONFIG_BT_SETTINGS) - return BTP_STATUS_FAILED; -#else - bool comp_alt_val = true; - - settings_save_one("tester/comp_alt", &comp_alt_val, sizeof(comp_alt_val)); - - return BTP_STATUS_SUCCESS; -#endif -} - static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -2862,233 +2730,6 @@ static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -#if defined(CONFIG_BT_MESH_RPR_CLI) -static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_scan_start_cmd *cp = cmd; - - struct bt_mesh_rpr_scan_status status; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - uint8_t uuid[16] = {0}; - int err; - - err = bt_mesh_rpr_scan_start(&rpr_cli, &srv, - memcmp(uuid, cp->uuid, 16) ? cp->uuid : NULL, - cp->timeout, - BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &status); - - if (err) { - LOG_ERR("Scan start failed: %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_ext_scan_start(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_ext_scan_start_cmd *cp = cmd; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_scan_start_ext(&rpr_cli, &srv, cp->uuid, - cp->timeout, cp->ad_types, - cp->ad_count); - if (err) { - LOG_ERR("Scan start failed: %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_scan_caps_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_scan_caps_get_cmd *cp = cmd; - struct bt_mesh_rpr_caps caps; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_scan_caps_get(&rpr_cli, &srv, &caps); - if (err) { - LOG_ERR("Scan capabilities get failed: %d", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Remote Provisioning scan capabilities of 0x%04x:", - net.dst); - LOG_DBG("\tMax devices: %u", caps.max_devs); - LOG_DBG("\tActive scanning: %s", - caps.active_scan ? "true" : "false"); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_scan_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_scan_get_cmd *cp = cmd; - struct bt_mesh_rpr_scan_status status; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_scan_get(&rpr_cli, &srv, &status); - if (err) { - LOG_ERR("Scan get failed: %d", err); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Remote Provisioning scan on 0x%04x:", cp->dst); - LOG_DBG("\tStatus: %u", status.status); - LOG_DBG("\tScan type: %u", status.scan); - LOG_DBG("\tMax devices: %u", status.max_devs); - LOG_DBG("\tRemaining time: %u", status.timeout); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_scan_stop(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_scan_stop_cmd *cp = cmd; - struct bt_mesh_rpr_scan_status status; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_scan_stop(&rpr_cli, &srv, &status); - if (err || status.status) { - LOG_DBG("Scan stop failed: %d %u", err, status.status); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Remote Provisioning scan on 0x%04x stopped.", - net.dst); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_link_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_link_get_cmd *cp = cmd; - struct bt_mesh_rpr_link link; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_link_get(&rpr_cli, &srv, &link); - if (err) { - LOG_ERR("Link get failed: %d %u", err, link.status); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst); - LOG_DBG("\tStatus: %u", link.status); - LOG_DBG("\tState: %u", link.state); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_link_close(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_link_close_cmd *cp = cmd; - struct bt_mesh_rpr_link link; - const struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_rpr_link_close(&rpr_cli, &srv, &link); - if (err) { - LOG_ERR("Link close failed: %d %u", err, link.status); - return BTP_STATUS_FAILED; - } - - LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst); - LOG_DBG("\tStatus: %u", link.status); - LOG_DBG("\tState: %u", link.state); - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_prov_remote(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_prov_remote_cmd *cp = cmd; - struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - err = bt_mesh_provision_remote(&rpr_cli, &srv, cp->uuid, - cp->net_idx, cp->addr); - if (err) { - LOG_ERR("Prov remote start failed: %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_rpr_reprov_remote_cmd *cp = cmd; - struct bt_mesh_rpr_node srv = { - .addr = cp->dst, - .net_idx = net.net_idx, - .ttl = BT_MESH_TTL_DEFAULT, - }; - int err; - - if (!BT_MESH_ADDR_IS_UNICAST(cp->addr)) { - LOG_ERR("Must be a valid unicast address"); - err = -EINVAL; - return BTP_STATUS_FAILED; - } - - err = bt_mesh_reprovision_remote(&rpr_cli, &srv, cp->addr, - cp->comp_change); - if (err) { - LOG_ERR("Reprovisioning failed: %d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - static const struct btp_handler handlers[] = { { .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, @@ -3519,62 +3160,6 @@ static const struct btp_handler handlers[] = { .func = models_metadata_get }, #endif - { - .opcode = BTP_MESH_COMP_CHANGE_PREPARE, - .expect_len = 0, - .func = change_prepare - }, - { - .opcode = BTP_MESH_SET_COMP_ALT, - .expect_len = 0, - .func = set_comp_alt - }, -#if defined(CONFIG_BT_MESH_RPR_CLI) - { - .opcode = BTP_MESH_RPR_SCAN_START, - .expect_len = sizeof(struct btp_rpr_scan_start_cmd), - .func = rpr_scan_start - }, - { - .opcode = BTP_MESH_RPR_EXT_SCAN_START, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = rpr_ext_scan_start - }, - { - .opcode = BTP_MESH_RPR_SCAN_CAPS_GET, - .expect_len = sizeof(struct btp_rpr_scan_caps_get_cmd), - .func = rpr_scan_caps_get - }, - { - .opcode = BTP_MESH_RPR_SCAN_GET, - .expect_len = sizeof(struct btp_rpr_scan_get_cmd), - .func = rpr_scan_get - }, - { - .opcode = BTP_MESH_RPR_SCAN_STOP, - .expect_len = sizeof(struct btp_rpr_scan_stop_cmd), - .func = rpr_scan_stop - }, - { - .opcode = BTP_MESH_RPR_LINK_GET, - .expect_len = sizeof(struct btp_rpr_link_get_cmd), - .func = rpr_link_get - }, - { - .opcode = BTP_MESH_RPR_LINK_CLOSE, - .expect_len = sizeof(struct btp_rpr_link_close_cmd), - .func = rpr_link_close - }, - { - .opcode = BTP_MESH_RPR_PROV_REMOTE, - .expect_len = sizeof(struct btp_rpr_prov_remote_cmd), - .func = rpr_prov_remote - }, - { - .opcode = BTP_MESH_RPR_REPROV_REMOTE, - .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd), - .func = rpr_reprov_remote - }, }; void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, @@ -3760,23 +3345,12 @@ BT_MESH_LPN_CB_DEFINE(lpn_cb) = { uint8_t tester_init_mesh(void) { - int err; - if (IS_ENABLED(CONFIG_BT_TESTING)) { bt_test_cb_register(&bt_test_cb); } tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, ARRAY_SIZE(handlers)); - if (default_comp) { - err = bt_mesh_init(&prov, &comp); - } else { - err = bt_mesh_init(&prov, &comp_alt); - } - - if (err) { - return BTP_STATUS_FAILED; - } return BTP_STATUS_SUCCESS; } From 3d8ca45c22281e165b988cffff2078eab5dbce85 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:25 +0000 Subject: [PATCH 4288/4498] Revert "[nrf fromtree] Bluetooth: tester: Add Transport SAR Configuration models" This reverts commit 9c7ac78741416f601ad8f453f76f5edab0b4d110. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 2 - tests/bluetooth/tester/src/btp/btp_mesh.h | 40 ------- tests/bluetooth/tester/src/btp_mesh.c | 133 +--------------------- 3 files changed, 1 insertion(+), 174 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 43e666d0eb3..937f4d1270e 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -15,8 +15,6 @@ CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y -CONFIG_BT_MESH_SAR_CFG_SRV=y -CONFIG_BT_MESH_SAR_CFG_CLI=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 67ce612c2ac..63984f0b61f 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -773,46 +773,6 @@ struct btp_proxy_connect_cmd { uint16_t net_idx; } __packed; -struct sar_transmitter { - uint8_t seg_int_step; - uint8_t unicast_retrans_count; - uint8_t unicast_retrans_without_prog_count; - uint8_t unicast_retrans_int_step; - uint8_t unicast_retrans_int_inc; - uint8_t multicast_retrans_count; - uint8_t multicast_retrans_int; -} __packed; - -struct sar_receiver { - uint8_t seg_thresh; - uint8_t ack_delay_inc; - uint8_t ack_retrans_count; - uint8_t discard_timeout; - uint8_t rx_seg_int_step; -} __packed; - -#define BTP_MESH_SAR_TRANSMITTER_GET 0x4f -struct btp_mesh_sar_transmitter_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_SAR_TRANSMITTER_SET 0x50 -struct btp_mesh_sar_transmitter_set_cmd { - uint16_t dst; - struct sar_transmitter tx; -} __packed; - -#define BTP_MESH_SAR_RECEIVER_GET 0x51 -struct btp_mesh_sar_receiver_get_cmd { - uint16_t dst; -} __packed; - -#define BTP_MESH_SAR_RECEIVER_SET 0x52 -struct btp_mesh_sar_receiver_set_cmd { - uint16_t dst; - struct sar_receiver rx; -} __packed; - #define BTP_MESH_LARGE_COMP_DATA_GET 0x53 struct btp_mesh_large_comp_data_get_cmd { uint16_t net_idx; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 232e3d7d8b4..a6ccd319b2d 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #define LOG_MODULE_NAME bttester_mesh @@ -318,21 +317,11 @@ BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); static struct bt_mesh_cfg_cli cfg_cli = { }; -#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) -static struct bt_mesh_sar_cfg_cli sar_cfg_cli; -#endif - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL_HEALTH_CLI(&health_cli), -#if defined(CONFIG_BT_MESH_SAR_CFG_SRV) - BT_MESH_MODEL_SAR_CFG_SRV, -#endif -#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) - BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli), -#endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) BT_MESH_MODEL_LARGE_COMP_DATA_SRV, #endif @@ -1027,105 +1016,6 @@ static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len, } #endif -#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) -static uint8_t sar_transmitter_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_sar_transmitter_get_cmd *cp = cmd; - struct bt_mesh_sar_tx tx_rsp; - int err; - - LOG_DBG(""); - - bt_mesh_sar_cfg_cli_timeout_set(5000); - - err = bt_mesh_sar_cfg_cli_transmitter_get( - net_key_idx, sys_le16_to_cpu(cp->dst), &tx_rsp); - if (err) { - LOG_ERR("err=%d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t sar_transmitter_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_sar_transmitter_set_cmd *cp = cmd; - struct bt_mesh_sar_tx set, tx_rsp; - int err; - - LOG_DBG(""); - - bt_mesh_sar_cfg_cli_timeout_set(5000); - - set.seg_int_step = cp->tx.seg_int_step; - set.unicast_retrans_count = cp->tx.unicast_retrans_count; - set.unicast_retrans_int_inc = cp->tx.unicast_retrans_int_inc; - set.unicast_retrans_int_step = cp->tx.unicast_retrans_int_step; - set.unicast_retrans_without_prog_count = - cp->tx.unicast_retrans_without_prog_count; - set.multicast_retrans_count = cp->tx.multicast_retrans_count; - set.multicast_retrans_int = cp->tx.multicast_retrans_int; - - err = bt_mesh_sar_cfg_cli_transmitter_set(net_key_idx, - sys_le16_to_cpu(cp->dst), - &set, &tx_rsp); - if (err) { - LOG_ERR("err=%d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t sar_receiver_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_sar_receiver_get_cmd *cp = cmd; - struct bt_mesh_sar_rx rx_rsp; - int err; - - LOG_DBG(""); - - err = bt_mesh_sar_cfg_cli_receiver_get(net_key_idx, - sys_le16_to_cpu(cp->dst), &rx_rsp); - if (err) { - LOG_ERR("err=%d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - -static uint8_t sar_receiver_set(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_sar_receiver_set_cmd *cp = cmd; - struct bt_mesh_sar_rx set, rx_rsp; - int err; - - LOG_DBG(""); - - set.ack_delay_inc = cp->rx.ack_delay_inc; - set.ack_retrans_count = cp->rx.ack_retrans_count; - set.discard_timeout = cp->rx.discard_timeout; - set.seg_thresh = cp->rx.seg_thresh; - set.rx_seg_int_step = cp->rx.rx_seg_int_step; - - err = bt_mesh_sar_cfg_cli_receiver_set(net_key_idx, - sys_le16_to_cpu(cp->dst), &set, - &rx_rsp); - if (err) { - LOG_ERR("err=%d", err); - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} -#endif - #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -3126,28 +3016,6 @@ static const struct btp_handler handlers[] = { .func = proxy_connect }, #endif -#if defined(CONFIG_BT_MESH_SAR_CFG_CLI) - { - .opcode = BTP_MESH_SAR_TRANSMITTER_GET, - .expect_len = sizeof(struct btp_mesh_sar_transmitter_get_cmd), - .func = sar_transmitter_get - }, - { - .opcode = BTP_MESH_SAR_TRANSMITTER_SET, - .expect_len = sizeof(struct btp_mesh_sar_transmitter_set_cmd), - .func = sar_transmitter_set - }, - { - .opcode = BTP_MESH_SAR_RECEIVER_GET, - .expect_len = sizeof(struct btp_mesh_sar_receiver_get_cmd), - .func = sar_receiver_get - }, - { - .opcode = BTP_MESH_SAR_RECEIVER_SET, - .expect_len = sizeof(struct btp_mesh_sar_receiver_set_cmd), - .func = sar_receiver_set - }, -#endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) { .opcode = BTP_MESH_LARGE_COMP_DATA_GET, @@ -3162,6 +3030,7 @@ static const struct btp_handler handlers[] = { #endif }; + void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { From b615cedf5f50356dcd9f49fff4518c6ae427ba5a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:25 +0000 Subject: [PATCH 4289/4498] Revert "[nrf fromtree] tester: Add Large Comp Data models" This reverts commit 4b5500c758e19a5338dc0bc778975ed94024f0d2. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/overlay-mesh.conf | 5 - tests/bluetooth/tester/src/btp/btp_mesh.h | 22 ----- tests/bluetooth/tester/src/btp_mesh.c | 111 ++-------------------- 3 files changed, 9 insertions(+), 129 deletions(-) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 937f4d1270e..840af06c1c0 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -1,5 +1,4 @@ CONFIG_BT_MESH=y -CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PB_GATT=y @@ -13,8 +12,6 @@ CONFIG_BT_MESH_APP_KEY_COUNT=4 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_CFG_CLI=y CONFIG_BT_MESH_HEALTH_CLI=y -CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y -CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=32 CONFIG_BT_MESH_RX_SEG_MAX=13 @@ -26,5 +23,3 @@ CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 CONFIG_BT_MESH_PROXY_CLIENT=y - -CONFIG_SETTINGS=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 63984f0b61f..bd7af172744 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -773,28 +773,6 @@ struct btp_proxy_connect_cmd { uint16_t net_idx; } __packed; -#define BTP_MESH_LARGE_COMP_DATA_GET 0x53 -struct btp_mesh_large_comp_data_get_cmd { - uint16_t net_idx; - uint16_t addr; - uint8_t page; - uint16_t offset; -} __packed; -struct btp_mesh_large_comp_data_get_rp { - uint8_t data[0]; -} __packed; - -#define BTP_MESH_MODELS_METADATA_GET 0x54 -struct btp_mesh_models_metadata_get_cmd { - uint16_t net_idx; - uint16_t addr; - uint8_t page; - uint16_t offset; -} __packed; -struct btp_mesh_models_metadata_get_rp { - uint8_t data[0]; -} __packed; - /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index a6ccd319b2d..b6ac4d91e1c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -22,8 +22,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #include "btp/btp.h" #define CID_LOCAL 0x05F1 -#define COMPANY_ID_LF 0x05F1 -#define COMPANY_ID_NORDIC_SEMI 0x05F9 /* Health server data */ #define CUR_FAULTS_MAX 4 @@ -256,6 +254,15 @@ static const struct bt_mesh_health_srv_cb health_srv_cb = { .fault_test = fault_test, }; +static struct bt_mesh_health_srv health_srv = { + .cb = &health_srv_cb, +}; + +BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); + +static struct bt_mesh_cfg_cli cfg_cli = { +}; + static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) { size_t i; @@ -282,52 +289,15 @@ static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr, show_faults(test_id, cid, faults, fault_count); } -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) -static struct bt_mesh_large_comp_data_cli lcd_cli = { -}; -#endif - static struct bt_mesh_health_cli health_cli = { .current_status = health_current_status, }; - -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV -static uint8_t health_tests[] = { - BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34, - 0x15), - BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03), -}; - -static struct bt_mesh_models_metadata_entry health_srv_meta[] = { - BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests), - BT_MESH_MODELS_METADATA_END, -}; -#endif - -static struct bt_mesh_health_srv health_srv = { - .cb = &health_srv_cb, -#ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV - .metadata = health_srv_meta, -#endif -}; - -BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); - -static struct bt_mesh_cfg_cli cfg_cli = { -}; - static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL_HEALTH_CLI(&health_cli), -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) - BT_MESH_MODEL_LARGE_COMP_DATA_SRV, -#endif -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) - BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), -#endif }; static struct bt_mesh_model vnd_models[] = { @@ -1016,56 +986,6 @@ static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len, } #endif -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) -static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_large_comp_data_get_cmd *cp = cmd; - struct btp_mesh_large_comp_data_get_rp *rp = rsp; - int err; - - struct bt_mesh_large_comp_data_rsp comp; - - err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx), - sys_le16_to_cpu(cp->addr), cp->page, - sys_le16_to_cpu(cp->offset), &comp); - if (err) { - LOG_ERR("Large Composition Data Get failed (err %d)", err); - - return BTP_STATUS_FAILED; - } - - memcpy(rp->data, comp.data->data, comp.data->len); - *rsp_len = comp.data->len; - - return BTP_STATUS_SUCCESS; -} - -static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_mesh_models_metadata_get_cmd *cp = cmd; - struct btp_mesh_models_metadata_get_rp *rp = rsp; - int err; - - struct bt_mesh_large_comp_data_rsp metadata; - - err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx), - sys_le16_to_cpu(cp->addr), cp->page, - sys_le16_to_cpu(cp->offset), &metadata); - - if (err) { - LOG_ERR("Models Metadata Get failed (err %d)", err); - return BTP_STATUS_FAILED; - } - - memcpy(rp->data, metadata.data->data, metadata.data->len); - *rsp_len = metadata.data->len; - - return BTP_STATUS_SUCCESS; -} -#endif - static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -3016,21 +2936,8 @@ static const struct btp_handler handlers[] = { .func = proxy_connect }, #endif -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) - { - .opcode = BTP_MESH_LARGE_COMP_DATA_GET, - .expect_len = sizeof(struct btp_mesh_large_comp_data_get_cmd), - .func = large_comp_data_get - }, - { - .opcode = BTP_MESH_MODELS_METADATA_GET, - .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd), - .func = models_metadata_get - }, -#endif }; - void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, size_t payload_len) { From d17ece15b4507397f190d6fc30a6be64564d54e2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:26 +0000 Subject: [PATCH 4290/4498] Revert "[nrf fromtree] Bluetooth: tester: Add ttl param to Model Send CMD" This reverts commit 83280e62bcf2d4f9ab18ce82c79ad6103a46cd62. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 1 - tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bd7af172744..e17d8481500 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -127,7 +127,6 @@ struct btp_mesh_lpn_set_cmd { #define BTP_MESH_MODEL_SEND 0x0f struct btp_mesh_model_send_cmd { - uint8_t ttl; uint16_t src; uint16_t dst; uint8_t payload_len; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index b6ac4d91e1c..2796f6418e4 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -861,7 +861,7 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, .addr = sys_le16_to_cpu(cp->dst), - .send_ttl = cp->ttl, + .send_ttl = BT_MESH_TTL_DEFAULT, }; if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) { From e771bcd6dae2d02463e548e21d724de5e082250f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:26 +0000 Subject: [PATCH 4291/4498] Revert "[nrf fromtree] Bluetooth: tester: Use Model Receive testing callback" This reverts commit ab1eb73243f14658b3d50ff2b541516a857ace70. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 8 -------- tests/bluetooth/tester/src/btp_mesh.c | 23 ----------------------- 2 files changed, 31 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index e17d8481500..bf73d6839d2 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -864,11 +864,3 @@ struct btp_mesh_prov_node_added_ev { uint8_t uuid[16]; uint8_t num_elems; } __packed; - -#define BTP_MESH_EV_MODEL_RECV 0x8f -struct btp_mesh_model_recv_ev { - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[]; -} __packed; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 2796f6418e4..c56c0ff9c1c 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -2963,28 +2963,6 @@ void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const voi tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_NET_RECV, buf.data, buf.len); } -void model_recv_ev(uint16_t src, uint16_t dst, const void *payload, - size_t payload_len) -{ - NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX); - struct btp_mesh_model_recv_ev *ev; - - LOG_DBG("src 0x%04x dst 0x%04x payload_len %zu", src, dst, payload_len); - - if (payload_len > net_buf_simple_tailroom(&buf)) { - LOG_ERR("Payload size exceeds buffer size"); - return; - } - - ev = net_buf_simple_add(&buf, sizeof(*ev)); - ev->src = sys_cpu_to_le16(src); - ev->dst = sys_cpu_to_le16(dst); - ev->payload_len = payload_len; - net_buf_simple_add_mem(&buf, payload, payload_len); - - tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_MODEL_RECV, buf.data, buf.len); -} - static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, uint16_t key_idx) { @@ -3045,7 +3023,6 @@ static void incomp_timer_exp_cb(void) static struct bt_test_cb bt_test_cb = { .mesh_net_recv = net_recv_ev, - .mesh_model_recv = model_recv_ev, .mesh_model_bound = model_bound_cb, .mesh_model_unbound = model_unbound_cb, .mesh_prov_invalid_bearer = invalid_bearer_cb, From 51146f2ede01cc40248f5cce3ff0dc82f2c4e525 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:26 +0000 Subject: [PATCH 4292/4498] Revert "[nrf fromtree] tests: Bluetooth: tester: fix mesh1d1 EHP pts tests" This reverts commit b6a8f040d960f817bc4abbb5806aa23d50c4bd07. Signed-off-by: Dominik Ermel --- tests/bluetooth/tester/src/btp/btp_mesh.h | 10 ++-------- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index bf73d6839d2..d7d2b2cdc7b 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -30,15 +30,9 @@ struct btp_mesh_read_supported_commands_rp { #define BTP_MESH_CONFIG_PROVISIONING 0x02 -#if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM) -#define BTP_MESH_PROV_AUTH_MAX_LEN 32 -#else -#define BTP_MESH_PROV_AUTH_MAX_LEN 16 -#endif - struct btp_mesh_config_provisioning_cmd { uint8_t uuid[16]; - uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; + uint8_t static_auth[16]; uint8_t out_size; uint16_t out_actions; uint8_t in_size; @@ -47,7 +41,7 @@ struct btp_mesh_config_provisioning_cmd { } __packed; struct btp_mesh_config_provisioning_cmd_v2 { uint8_t uuid[16]; - uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; + uint8_t static_auth[16]; uint8_t out_size; uint16_t out_actions; uint8_t in_size; diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index c56c0ff9c1c..c922c812631 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -43,7 +43,7 @@ static uint8_t priv_key[32]; /* Configured provisioning data */ static uint8_t dev_uuid[16]; -static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN]; +static uint8_t static_auth[16]; /* Vendor Model data */ #define VND_MODEL_ID_1 0x1234 From 2c6287a4587c2cdf658d0b6af2c70c81cf1c98f6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:26 +0000 Subject: [PATCH 4293/4498] Revert "[nrf fromtree] Bluetooth: Mesh: refactor mandatory oob for mesh1d1" This reverts commit 2ec2e076210bd6c281ead3e1daebbc5ffcb54fc2. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/prov.c | 6 ++++++ subsys/bluetooth/mesh/prov_device.c | 13 ++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/mesh/prov.c b/subsys/bluetooth/mesh/prov.c index fbbcde58185..f44fffde649 100644 --- a/subsys/bluetooth/mesh/prov.c +++ b/subsys/bluetooth/mesh/prov.c @@ -181,6 +181,12 @@ int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8 uint8_t auth_size = bt_mesh_prov_auth_size_get(); int err; + if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && + (method == AUTH_METHOD_NO_OOB || + bt_mesh_prov_link.algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM)) { + return -EINVAL; + } + switch (method) { case AUTH_METHOD_NO_OOB: if (action || size) { diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 0184463568f..a83ace178db 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -94,16 +94,15 @@ static void prov_invite(const uint8_t *data) bt_mesh_prov->input_size > 0 || bt_mesh_prov->static_val; if (IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)) { - WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM, 1); + algorithm_bm |= BIT(BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM); } if (IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM)) { - WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM, 1); + algorithm_bm |= BIT(BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM); } if (oob_availability && IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED)) { oob_type |= BT_MESH_OOB_AUTH_REQUIRED; - WRITE_BIT(algorithm_bm, BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM, 0); } /* Supported algorithms */ @@ -177,18 +176,10 @@ static void prov_start(const uint8_t *data) bt_mesh_prov_link.oob_action = data[3]; bt_mesh_prov_link.oob_size = data[4]; - if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && - (bt_mesh_prov_link.oob_method == AUTH_METHOD_NO_OOB || - bt_mesh_prov_link.algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM)) { - prov_fail(PROV_ERR_NVAL_FMT); - return; - } - if (bt_mesh_prov_auth(false, data[2], data[3], data[4]) < 0) { LOG_ERR("Invalid authentication method: 0x%02x; " "action: 0x%02x; size: 0x%02x", data[2], data[3], data[4]); prov_fail(PROV_ERR_NVAL_FMT); - return; } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { From 369e0834b26e932aa3e23689de94f09957a5c88c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:27 +0000 Subject: [PATCH 4294/4498] Revert "[nrf fromtree] Bluetooth: Mesh: shell supports 32 bytes static oob" This reverts commit 609c593b26ea626d88909f09b7b6df4d26f88363. Signed-off-by: Dominik Ermel --- doc/connectivity/bluetooth/api/mesh/shell.rst | 4 ++-- subsys/bluetooth/mesh/shell/shell.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 6f102b5490f..e6609f40e5c 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -297,7 +297,7 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT * ``String``: Unquoted alphanumeric authentication string. -``mesh prov static-oob [Val(1-32 hex)]`` +``mesh prov static-oob [Val(1-16 hex)]`` ---------------------------------------- Set or clear the static OOB authentication value. The static OOB authentication value must be set before provisioning starts to have any effect. The static OOB value must be same on both participants in the provisioning. To enable this command, the :kconfig:option:`BT_MESH_SHELL_PROV_CTX_INSTANCE` option must be enabled. @@ -358,7 +358,7 @@ To allow a device to provision devices over GATT, the :kconfig:option:`CONFIG_BT ------------------------------------------------ From the provisioner device, instruct the unprovisioned device to use static OOB authentication, and use the given static authentication value when provisioning. - * ``Val`` - Static OOB value. Providing a hex-string shorter than 32 bytes will populate the N most significant bytes of the array and zero-pad the rest. + * ``Val`` - Static OOB value. Providing a hex-string shorter than 16 bytes will populate the N most significant bytes of the array and zero-pad the rest. ``mesh prov auth-method none`` ------------------------------ diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index c5592db02cf..243166441fe 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -611,7 +611,7 @@ static void link_close(bt_mesh_prov_bearer_t bearer) shell_print_ctx("Provisioning link closed on %s", bearer2str(bearer)); } -static uint8_t static_val[32]; +static uint8_t static_val[16]; struct bt_mesh_prov bt_mesh_shell_prov = { .uuid = dev_uuid, @@ -645,7 +645,7 @@ static int cmd_static_oob(const struct shell *sh, size_t argc, char *argv[]) bt_mesh_shell_prov.static_val_len = 0U; } else { bt_mesh_shell_prov.static_val_len = hex2bin(argv[1], strlen(argv[1]), - static_val, 32); + static_val, 16); if (bt_mesh_shell_prov.static_val_len) { bt_mesh_shell_prov.static_val = static_val; } else { @@ -886,7 +886,7 @@ static int cmd_auth_method_set_output(const struct shell *sh, size_t argc, char static int cmd_auth_method_set_static(const struct shell *sh, size_t argc, char *argv[]) { size_t len; - uint8_t static_oob_auth[32]; + uint8_t static_oob_auth[16]; int err = 0; len = hex2bin(argv[1], strlen(argv[1]), static_oob_auth, sizeof(static_oob_auth)); From 65cedbd218bd5b4897d793fb746effa2b7271d5b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:27 +0000 Subject: [PATCH 4295/4498] Revert "[nrf fromtree] Bluetooth: Mesh: fix static oob setting" This reverts commit efc4e52f347da84ba172e23935f3786d9612a781. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/prov_device.c | 11 +++-------- subsys/bluetooth/mesh/provisioner.c | 15 ++++++++------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index a83ace178db..20735f49fa5 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -183,14 +183,9 @@ static void prov_start(const uint8_t *data) } if (atomic_test_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY)) { - - uint8_t tail_size = bt_mesh_prov->static_val_len < auth_size - ? auth_size - bt_mesh_prov->static_val_len - : 0; - - memcpy(bt_mesh_prov_link.auth + tail_size, bt_mesh_prov->static_val, - tail_size ? bt_mesh_prov->static_val_len : auth_size); - memset(bt_mesh_prov_link.auth, 0, tail_size); + memcpy(bt_mesh_prov_link.auth + auth_size - bt_mesh_prov->static_val_len, + bt_mesh_prov->static_val, bt_mesh_prov->static_val_len); + memset(bt_mesh_prov_link.auth, 0, auth_size - bt_mesh_prov->static_val_len); } } diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index 673e14578d2..25f0a299480 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -254,7 +254,8 @@ static void prov_capabilities(const uint8_t *data) return; } - if (caps.oob_type & BT_MESH_OOB_AUTH_REQUIRED) { + if (IS_ENABLED(CONFIG_BT_MESH_OOB_AUTH_REQUIRED) && + (caps.oob_type & BT_MESH_OOB_AUTH_REQUIRED)) { bool oob_availability = caps.output_size > 0 || caps.input_size > 0 || (caps.oob_type & BT_MESH_STATIC_OOB_AVAILABLE); @@ -751,18 +752,18 @@ int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size) int bt_mesh_auth_method_set_static(const uint8_t *static_val, uint8_t size) { - uint8_t tail_size = size < PROV_AUTH_MAX_LEN ? PROV_AUTH_MAX_LEN - size : 0; + uint8_t auth_size = bt_mesh_prov_auth_size_get(); - if (!size || !static_val) { + if (!size || !static_val || size > auth_size) { return -EINVAL; } prov_set_method(AUTH_METHOD_STATIC, 0, 0); - memcpy(bt_mesh_prov_link.auth + tail_size, static_val, - tail_size ? size : PROV_AUTH_MAX_LEN); - memset(bt_mesh_prov_link.auth, 0, tail_size); - + memcpy(bt_mesh_prov_link.auth + auth_size - size, static_val, size); + if (size < auth_size) { + (void)memset(bt_mesh_prov_link.auth, 0, auth_size - size); + } return 0; } From ed1eaa8645619e33c1673ce97790473472358c43 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:27 +0000 Subject: [PATCH 4296/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Use decimals instead of hex nums in DFD shell cmds" This reverts commit cd7dfd7466119b3764545e4af9ae825ee577397e. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/shell/dfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index 0415929dfec..b7daf42af1c 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -29,7 +29,7 @@ static void print_dfd_status(const struct shell *sh, struct bt_mesh_dfd_srv *srv srv->phase); if (srv->phase != BT_MESH_DFD_PHASE_IDLE && srv->dfu.xfer.slot) { - shell_fprintf(sh, SHELL_NORMAL, ", \"group\": %d, \"app_idx\": %d, " + shell_fprintf(sh, SHELL_NORMAL, ", \"group\": 0x%04x, \"app_idx\": %d, " "\"ttl\": %d, \"timeout_base\": %d, \"xfer_mode\": %d, " "\"apply\": %d, \"slot_idx\": %d", srv->inputs.group, srv->inputs.app_idx, srv->inputs.ttl, srv->inputs.timeout_base, @@ -165,7 +165,7 @@ static int cmd_dfd_receivers_get(const struct shell *sh, size_t argc, char *argv for (int i = 0; i < cnt; i++) { const struct bt_mesh_dfu_target *t = &dfd_srv->targets[i + first]; - shell_print(sh, "\t\t\"%d\": { \"blob_addr\": %d, \"phase\": %d, " + shell_print(sh, "\t\t\"%d\": { \"blob_addr\": 0x%04x, \"phase\": %d, " "\"status\": %d, \"blob_status\": %d, \"progress\": %d, " "\"img_idx\": %d }%s", i + first, t->blob.addr, t->phase, t->status, t->blob.status, progress, t->img_idx, (i == cnt - 1) ? "" : ","); From 487a2355dcd32f6f1b33c2f7b01d583964eac99c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:27 +0000 Subject: [PATCH 4297/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix printing device UUID" This reverts commit 7e3caf9f788b375b0eacf2b3c501606d95038ab0. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/prov_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/prov_device.c index 20735f49fa5..48d852cb1a7 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/prov_device.c @@ -675,7 +675,7 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } -#if defined(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) +#if IS_ENABLED(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) if (CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL > 2) { struct bt_uuid_128 uuid = { .uuid = { BT_UUID_TYPE_128 } }; From 7fe7cb0dad2cb10e7af3ee6f91610b9f153e8ee7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:27 +0000 Subject: [PATCH 4298/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Add support for Upload OOB Start" This reverts commit 34e20954d8d64805a6e1cd0c804361ce713da363. Signed-off-by: Dominik Ermel --- doc/connectivity/bluetooth/api/mesh/shell.rst | 5 +- include/zephyr/bluetooth/mesh/dfd_srv.h | 163 +--------- include/zephyr/bluetooth/mesh/dfu.h | 13 +- subsys/bluetooth/mesh/Kconfig | 8 - subsys/bluetooth/mesh/dfd_srv.c | 270 +++------------- subsys/bluetooth/mesh/dfu_slot.c | 294 ++++++++---------- subsys/bluetooth/mesh/dfu_slot.h | 87 ++---- subsys/bluetooth/mesh/shell/dfd.c | 9 +- subsys/bluetooth/mesh/shell/dfu.c | 53 ++-- tests/bsim/bluetooth/mesh/prj_mesh1d1.conf | 3 +- tests/bsim/bluetooth/mesh/src/test_dfu.c | 185 ++++------- .../tests_scripts/dfu/dfu_slot_idempotency.sh | 14 - .../tests_scripts/dfu/dfu_slot_reservation.sh | 14 - 13 files changed, 326 insertions(+), 792 deletions(-) delete mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh delete mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index e6609f40e5c..f9acf24d277 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1034,14 +1034,15 @@ Firmware Update Client model The Firmware Update Client model can be added to the mesh shell by enabling configuration options :kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` and :kconfig:option:`CONFIG_BT_MESH_DFU_CLI`. The Firmware Update Client demonstrates the firmware update Distributor role by transferring a dummy firmware update to a set of Target nodes. -``mesh models dfu slot add []`` +``mesh models dfu slot add [ [ []]]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add a virtual DFU image slot that can be transferred as a DFU image. The image slot will be assigned an image slot index, which is printed as a response, and can be used to reference the slot in other commands. To update the image slot, remove it using the ``mesh models dfu slot del`` shell command and then add it again. * ``Size``: DFU image slot size in bytes. - * ``FwID``: Firmware ID, formatted as a hexstring. + * ``FwID``: Optional firmware ID, formatted as a hexstring. * ``Metadata``: Optional firmware metadata, formatted as a hexstring. + * ``URI``: Optional URI for the firmware. ``mesh models dfu slot del `` diff --git a/include/zephyr/bluetooth/mesh/dfd_srv.h b/include/zephyr/bluetooth/mesh/dfd_srv.h index da339c57ec6..0e281b29186 100644 --- a/include/zephyr/bluetooth/mesh/dfd_srv.h +++ b/include/zephyr/bluetooth/mesh/dfd_srv.h @@ -29,47 +29,11 @@ extern "C" { #define CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 0 #endif -#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE -#define CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 0 -#endif - -#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE -#define CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 0 -#endif - struct bt_mesh_dfd_srv; -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD -/** - * - * @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB - * upload support. - * - * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. - * @param[in] _oob_schemes Array of OOB schemes supported by the server, - * each scheme being a code point from the - * Bluetooth SIG Assigned Numbers document. - * @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes. - */ -#define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \ - { \ - .cb = _cb, \ - .dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \ - .upload = { \ - .blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \ - }, \ - .oob_schemes = { \ - .schemes = _oob_schemes, \ - .count = _oob_schemes_count, \ - }, \ - } -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ - /** * * @brief Initialization parameters for the @ref bt_mesh_dfd_srv. - * - * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. */ #define BT_MESH_DFD_SRV_INIT(_cb) \ { \ @@ -111,64 +75,6 @@ struct bt_mesh_dfd_srv_cb { const struct bt_mesh_dfu_slot *slot, const struct bt_mesh_blob_io **io); -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - /** @brief Firmware upload OOB start callback. - * - * Called at the start of an OOB firmware upload. The application must - * start a firmware check using an OOB mechanism, and then call - * @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return - * value of this function, the application must then start storing the - * firmware image using an OOB mechanism, and call - * @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory - * to support OOB uploads. - * - * @param srv Firmware Distribution Server model instance. - * @param slot Slot to be used for the upload. - * @param uri Pointer to buffer containing the URI used to - * check for new firmware. - * @param uri_len Length of the URI buffer. - * @param fwid Pointer to buffer containing the current - * firmware ID to be used when checking for - * availability of new firmware. - * @param fwid_len Length of the current firmware ID. Must be set - * to the length of the new firmware ID if it is - * available, or to 0 if new firmware is not - * available. - * - * @return BT_MESH_DFD_SUCCESS on success, or error code otherwise. - */ - int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, - const char *uri, uint8_t uri_len, - const uint8_t *fwid, uint16_t fwid_len); - - /** @brief Cancel store OOB callback - * - * Called when an OOB store is cancelled. The application must stop - * any ongoing OOB image transfer. This callback is mandatory to - * support OOB uploads. - * - * @param srv Firmware Distribution Server model instance. - * @param slot DFU image slot to cancel - */ - void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot); - - /** @brief Get the progress of an ongoing OOB store - * - * Called by the Firmware Distribution Server model when it needs to - * get the current progress of an ongoing OOB store from the - * application. This callback is mandatory to support OOB uploads. - * - * @param srv Firmware Distribution Server model instance. - * @param slot DFU image slot to get progress for. - * - * @return The current progress of the ongoing OOB store, in percent. - */ - uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot); -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ - /** @brief Slot delete callback. * * Called when the Firmware Distribution Server is about to delete a DFU image slot. @@ -223,79 +129,12 @@ struct bt_mesh_dfd_srv { struct { enum bt_mesh_dfd_upload_phase phase; - struct bt_mesh_dfu_slot *slot; + const struct bt_mesh_dfu_slot *slot; const struct flash_area *area; struct bt_mesh_blob_srv blob; -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - bool is_oob; - struct { - uint8_t uri_len; - uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; - uint16_t current_fwid_len; - uint8_t current_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; - struct bt_mesh_msg_ctx ctx; - } oob; -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ } upload; - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - struct { - const uint8_t *schemes; - const uint8_t count; - } oob_schemes; -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ }; -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD -/** @brief Call when an OOB check has completed or failed - * - * This should be called by the application after an OOB check started by the @c start_oob_upload - * callback has completed or failed. The @p status param should be set to one of the following - * values: - * - * * @c BT_MESH_DFD_SUCCESS if the check was succesfull and a new firmware ID was found. - * * @c BT_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly. - * * @c BT_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node. - * * @c BT_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached. - * * @c BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new - * firmware is available. - * - * If this function returns 0, the application should then download the firmware to the - * slot. If an error code is returned, the application should abort the OOB upload. - * - * @param srv Firmware Distribution Server model instance. - * @param slot The slot used in the OOB upload. - * @param status The result of the firmware check. - * @param fwid If the check was successful and new firmware found, this should point to a - * buffer containing the new firmware ID to store. - * @param fwid_len The length of the firmware ID pointed to by @p fwid. - * - * @return 0 on success, (negative) error code otherwise. - */ -int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, int status, - uint8_t *fwid, size_t fwid_len); - -/** @brief Call when an OOB store has completed or failed - * - * This should be called by the application after an OOB store started after a succesfull call to - * @c bt_mesh_dfd_srv_oob_check_complete has completed successfully or failed. - * - * @param srv Firmware Distribution Server model instance. - * @param slot The slot used when storing the firmware image. - * @param success @c true if the OOB store completed successfully, @c false otherwise. - * @param size The size of the stored firmware image, in bytes. - * @param metadata Pointer to the metadata received OOB, or @c NULL if no metadata was - * received. - * @param metadata_len Size of the metadata pointed to by @p metadata. - * - * @return 0 on success, (negative) error code otherwise. - */ -int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, bool success, - size_t size, const uint8_t *metadata, size_t metadata_len); -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ - /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[]; extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb; diff --git a/include/zephyr/bluetooth/mesh/dfu.h b/include/zephyr/bluetooth/mesh/dfu.h index 4745355f039..91f36cdbaeb 100644 --- a/include/zephyr/bluetooth/mesh/dfu.h +++ b/include/zephyr/bluetooth/mesh/dfu.h @@ -34,10 +34,6 @@ extern "C" { #define CONFIG_BT_MESH_DFU_URI_MAXLEN 0 #endif -#ifndef CONFIG_BT_MESH_DFU_SLOT_CNT -#define CONFIG_BT_MESH_DFU_SLOT_CNT 0 -#endif - /** DFU transfer phase. */ enum bt_mesh_dfu_phase { /** Ready to start a Receive Firmware procedure. */ @@ -144,7 +140,10 @@ struct bt_mesh_dfu_img { /** Length of the firmware ID. */ size_t fwid_len; - /** Update URI, or NULL. */ + /** Update URI, or NULL. + * + * Must use one of the http: or https: schemes. + */ const char *uri; }; @@ -156,10 +155,14 @@ struct bt_mesh_dfu_slot { size_t fwid_len; /** Length of the metadata. */ size_t metadata_len; + /** Length of the image URI. */ + size_t uri_len; /** Firmware ID. */ uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; /** Metadata. */ uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; + /** Image URI. */ + char uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; }; /** @} */ diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 2dfc125b8fd..b8e26309a28 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1235,14 +1235,6 @@ config BT_MESH_DFD_SRV_TARGETS_MAX This value defines the maximum number of Target nodes the Firmware Distribution Server can target simultaneously. -config BT_MESH_DFD_SRV_OOB_UPLOAD - bool "Support for DFU image OOB upload" - help - This enables support for OOB upload of firmware images for - distribution. This makes several callbacks and use of the init - macro BT_MESH_DFD_SRV_INIT_OOB mandatory. See the API documentation - for bt_mesh_dfd_srv_cb for details about the mandatory callbacks. - endif config BT_MESH_RPR_SRV diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 54de343c94a..2898ca39a39 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -224,20 +224,7 @@ static int handle_capabilities_get(struct bt_mesh_model *mod, struct bt_mesh_msg size = MIN(size, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE); net_buf_simple_add_le32(&rsp, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE - size); - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - struct bt_mesh_dfd_srv *srv = mod->user_data; - - if (srv->oob_schemes.count > 0) { - net_buf_simple_add_u8(&rsp, 1); - net_buf_simple_add_mem(&rsp, srv->oob_schemes.schemes, - srv->oob_schemes.count); - } else -#else - { - net_buf_simple_add_u8(&rsp, 0); - } -#endif + net_buf_simple_add_u8(&rsp, 0U); /* OOB retrieval not supported */ bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL); @@ -359,19 +346,10 @@ static void upload_status_rsp(struct bt_mesh_dfd_srv *srv, return; } -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - if (srv->upload.is_oob) { - net_buf_simple_add_u8(&rsp, - srv->cb->oob_progress_get(srv, srv->upload.slot) | BIT(7)); - net_buf_simple_add_mem(&rsp, srv->upload.oob.current_fwid, - srv->upload.oob.current_fwid_len); - } else -#endif - { - net_buf_simple_add_u8(&rsp, bt_mesh_blob_srv_progress(&srv->upload.blob)); - net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, - srv->upload.slot->fwid_len); - } + net_buf_simple_add_u8(&rsp, + bt_mesh_blob_srv_progress(&srv->upload.blob)); + net_buf_simple_add_mem(&rsp, srv->upload.slot->fwid, + srv->upload.slot->fwid_len); bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL); } @@ -386,42 +364,16 @@ static int handle_upload_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx * return 0; } -static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_msg_ctx *ctx, - const uint8_t *fwid, size_t fwid_len) -{ - int err = bt_mesh_dfu_slot_fwid_set(srv->upload.slot, fwid, fwid_len); - - switch (err) { - case -EFBIG: /* Fwid too long */ - case -EALREADY: /* Other server is in progress with this fwid */ - bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); - break; - case -EEXIST: /* Img with this fwid already is in list */ - srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; - bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); - break; - case 0: - srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE; - break; - case -EINVAL: /* Slot in wrong state. */ - default: - break; - } - - return err; -} - static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; + const struct bt_mesh_dfu_slot *old_slot = srv->upload.slot; size_t meta_len, fwid_len, size; const uint8_t *meta, *fwid; uint16_t timeout_base; uint64_t blob_id; - int err; + int err, idx; uint8_t ttl; ttl = net_buf_simple_pull_u8(buf); @@ -440,7 +392,9 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx LOG_DBG("Upload Start: size: %d, fwid: %s, metadata: %s", size, bt_hex(fwid, fwid_len), bt_hex(meta, meta_len)); - if (size > CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE) { + if (size > CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE || + fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN || + meta_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN) { upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES); return 0; @@ -459,11 +413,7 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx !memcmp(srv->upload.slot->metadata, meta, meta_len) && srv->upload.blob.state.xfer.id == blob_id && srv->upload.blob.state.ttl == ttl && - srv->upload.blob.state.timeout_base == timeout_base -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - && !srv->upload.is_oob -#endif - ) { + srv->upload.blob.state.timeout_base == timeout_base) { LOG_DBG("Duplicate upload start"); upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); return 0; @@ -474,16 +424,23 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } - /* This will be a no-op if the slot state isn't RESERVED, which is - * what we want. - */ - bt_mesh_dfu_slot_release(srv->upload.slot); + idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &srv->upload.slot); + if (idx >= 0 && bt_mesh_dfu_slot_is_valid(srv->upload.slot)) { + LOG_DBG("Already received image"); + srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; + upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); + return 0; + } -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - srv->upload.is_oob = false; -#endif - srv->upload.slot = bt_mesh_dfu_slot_reserve(); + if (old_slot && !bt_mesh_dfu_slot_is_valid(old_slot)) { + LOG_DBG("Deleting old invalid slot"); + slot_del(srv, old_slot); + } + /* TODO Store transfer state before slot is added. */ + + srv->upload.slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, meta, + meta_len, NULL, 0); if (!srv->upload.slot) { LOG_WRN("No space for slot"); upload_status_rsp(srv, ctx, @@ -491,27 +448,11 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx return 0; } - err = set_upload_fwid(srv, ctx, fwid, fwid_len); - if (err) { - return err; - } - - err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, meta, meta_len); - switch (err) { - case -EFBIG: - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); - break; - case 0: - break; - default: - return err; - } - srv->io = NULL; err = srv->cb->recv(srv, srv->upload.slot, &srv->io); if (err || !srv->io) { LOG_ERR("App rejected upload. err: %d io: %p", err, srv->io); - bt_mesh_dfu_slot_release(srv->upload.slot); + slot_del(srv, srv->upload.slot); upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); return 0; } @@ -520,7 +461,7 @@ static int handle_upload_start(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx timeout_base); if (err) { LOG_ERR("BLOB Server rejected upload (err: %d)", err); - bt_mesh_dfu_slot_release(srv->upload.slot); + slot_del(srv, srv->upload.slot); upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); return 0; } @@ -537,71 +478,10 @@ static int handle_upload_start_oob(struct bt_mesh_model *mod, struct bt_mesh_msg struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; - uint8_t uri_len; - uint8_t *uri; - uint16_t fwid_len; - uint8_t *fwid; - - uri_len = net_buf_simple_pull_u8(buf); - - if (uri_len > buf->len) { - return -EINVAL; - } - - uri = net_buf_simple_pull_mem(buf, uri_len); - fwid_len = buf->len; - fwid = net_buf_simple_pull_mem(buf, fwid_len); - if (upload_is_busy(srv)) { -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - if (srv->upload.is_oob && - uri_len == srv->upload.oob.uri_len && - fwid_len == srv->upload.oob.current_fwid_len && - !memcmp(uri, srv->upload.oob.uri, uri_len) && - !memcmp(fwid, srv->upload.oob.current_fwid, fwid_len)) { - /* Same image, return SUCCESS for idempotency */ - upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); - return 0; - } -#endif - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD); - return 0; - } - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - if (uri_len > CONFIG_BT_MESH_DFU_URI_MAXLEN || - fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN) { - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL); - return 0; - } - - struct bt_mesh_dfu_slot *slot = bt_mesh_dfu_slot_reserve(); - - if (slot == NULL) { - upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES); - return 0; - } + LOG_DBG(""); - srv->upload.is_oob = true; - srv->upload.slot = slot; - memcpy(srv->upload.oob.uri, uri, uri_len); - srv->upload.oob.uri_len = uri_len; - memcpy(srv->upload.oob.current_fwid, fwid, fwid_len); - srv->upload.oob.current_fwid_len = fwid_len; - memcpy(&srv->upload.oob.ctx, ctx, sizeof(struct bt_mesh_msg_ctx)); - - int status = srv->cb->start_oob_upload(srv, srv->upload.slot, srv->upload.oob.uri, - srv->upload.oob.uri_len, - srv->upload.oob.current_fwid, - srv->upload.oob.current_fwid_len); - - if (status != BT_MESH_DFD_SUCCESS) { - upload_status_rsp(srv, ctx, status); - bt_mesh_dfu_slot_release(srv->upload.slot); - } -#else upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_URI_NOT_SUPPORTED); -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ return 0; } @@ -612,14 +492,7 @@ static int handle_upload_cancel(struct bt_mesh_model *mod, struct bt_mesh_msg_ct struct bt_mesh_dfd_srv *srv = mod->user_data; srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE; -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD - if (srv->upload.is_oob) { - srv->cb->cancel_oob_upload(srv, srv->upload.slot); - } else -#endif - { - (void)bt_mesh_blob_srv_cancel(&srv->upload.blob); - } + (void)bt_mesh_blob_srv_cancel(&srv->upload.blob); upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); return 0; @@ -635,7 +508,7 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv, bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_FW_STATUS); net_buf_simple_add_u8(&rsp, status); - net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_count()); + net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_foreach(NULL, NULL)); net_buf_simple_add_le16(&rsp, idx); if (fwid) { @@ -649,7 +522,7 @@ static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_dfd_srv *srv = mod->user_data; - struct bt_mesh_dfu_slot *slot; + const struct bt_mesh_dfu_slot *slot; const uint8_t *fwid; size_t fwid_len; int idx; @@ -658,7 +531,7 @@ static int handle_fw_get(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, fwid = net_buf_simple_pull_mem(buf, fwid_len); idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); - if (idx >= 0) { + if (idx >= 0 && bt_mesh_dfu_slot_is_valid(slot)) { fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, fwid, fwid_len); } else { @@ -679,7 +552,7 @@ static int handle_fw_get_by_index(struct bt_mesh_model *mod, struct bt_mesh_msg_ idx = net_buf_simple_pull_le16(buf); slot = bt_mesh_dfu_slot_at(idx); - if (slot) { + if (slot && bt_mesh_dfu_slot_is_valid(slot)) { fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, slot->fwid, slot->fwid_len); } else { @@ -856,7 +729,8 @@ static void upload_end(struct bt_mesh_blob_srv *b, uint64_t id, bool success) LOG_DBG("%u", success); - if (success && (bt_mesh_dfu_slot_commit(srv->upload.slot) == 0)) { + if (success) { + bt_mesh_dfu_slot_valid_set(srv->upload.slot, true); srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; return; } @@ -976,7 +850,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv, xfer.mode = params->xfer_mode; xfer.slot = bt_mesh_dfu_slot_at(params->slot_idx); - if (!xfer.slot) { + if (!xfer.slot || !bt_mesh_dfu_slot_is_valid(xfer.slot)) { return BT_MESH_DFD_ERR_FW_NOT_FOUND; } @@ -1139,7 +1013,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_apply(struct bt_mesh_dfd_srv *srv) enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, size_t *fwid_len, const uint8_t **fwid) { - struct bt_mesh_dfu_slot *slot; + const struct bt_mesh_dfu_slot *slot; int idx, err; if (srv->phase != BT_MESH_DFD_PHASE_IDLE) { @@ -1149,7 +1023,7 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, s } idx = bt_mesh_dfu_slot_get(*fwid, *fwid_len, &slot); - if (idx < 0) { + if (idx < 0 || !bt_mesh_dfu_slot_is_valid(slot)) { return BT_MESH_DFD_SUCCESS; } @@ -1175,69 +1049,3 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete_all(struct bt_mesh_dfd_srv *sr return BT_MESH_DFD_SUCCESS; } - -#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD -int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, int status, - uint8_t *fwid, size_t fwid_len) -{ - int err; - - if (slot != srv->upload.slot || !srv->upload.is_oob || - srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) { - /* This should not happen, unless the application calls the function with a - * "wrong" pointer or at a wrong time. - */ - return -EINVAL; - } - - if (status != BT_MESH_DFD_SUCCESS) { - bt_mesh_dfu_slot_release(srv->upload.slot); - upload_status_rsp(srv, &srv->upload.oob.ctx, status); - return -ECANCELED; - } - - err = set_upload_fwid(srv, &srv->upload.oob.ctx, fwid, fwid_len); - - if (err) { - return err; - } - - upload_status_rsp(srv, &srv->upload.oob.ctx, BT_MESH_DFD_SUCCESS); - return 0; -} - -int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv, - const struct bt_mesh_dfu_slot *slot, bool success, - size_t size, const uint8_t *metadata, size_t metadata_len) -{ - int err = 0; - - if (srv->upload.phase != BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE || - srv->upload.slot != slot || !srv->upload.is_oob) { - return -EINVAL; - } - - if (!success) { - goto error; - } - - err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, metadata, metadata_len); - if (err) { - goto error; - } - - err = bt_mesh_dfu_slot_commit(srv->upload.slot); - if (err) { - goto error; - } - - srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS; - return 0; - -error: - srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR; - bt_mesh_dfu_slot_release(srv->upload.slot); - return err; -} -#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ diff --git a/subsys/bluetooth/mesh/dfu_slot.c b/subsys/bluetooth/mesh/dfu_slot.c index 097d5abcc82..16628793457 100644 --- a/subsys/bluetooth/mesh/dfu_slot.c +++ b/subsys/bluetooth/mesh/dfu_slot.c @@ -20,22 +20,23 @@ LOG_MODULE_REGISTER(bt_mesh_dfu_slot); #define DFU_SLOT_SETTINGS_PATH "bt/mesh-dfu/slot" -#define HEADER_SIZE offsetof(struct slot, slot.fwid) +#define HEADER_SIZE offsetof(struct bt_mesh_dfu_slot, fwid) #define PROP_HEADER "h" #define PROP_FWID "id" #define PROP_METADATA "m" +#define PROP_URI "u" +#define VALID_SLOTS_TAG "v" -static sys_slist_t list; +#define SLOT_IN_ARRAY(_slot) PART_OF_ARRAY(slots, CONTAINER_OF(_slot, struct slot, slot)) +static ATOMIC_DEFINE(valid_slots, CONFIG_BT_MESH_DFU_SLOT_CNT); +static sys_slist_t list; static struct slot { - uint32_t idx; - struct bt_mesh_dfu_slot slot; sys_snode_t n; + struct bt_mesh_dfu_slot slot; } slots[CONFIG_BT_MESH_DFU_SLOT_CNT]; -static uint32_t slot_index; - static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN], const char *property) { @@ -45,29 +46,32 @@ static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN], return buf; } -static bool slot_eq(const struct bt_mesh_dfu_slot *slot, - const uint8_t *fwid, size_t fwid_len) +static inline bool slot_in_use(const struct bt_mesh_dfu_slot *slot) { - return (slot->fwid_len == fwid_len) && - !memcmp(fwid, slot->fwid, fwid_len); + return slot->size > 0U; } -static bool is_slot_committed(struct slot *slot_to_check) +static inline uint16_t slot_idx(const struct bt_mesh_dfu_slot *slot) { - struct slot *s; + return CONTAINER_OF(slot, struct slot, slot) - &slots[0]; +} - SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (s == slot_to_check) { - return true; - } - } +static inline void slot_invalidate(struct slot *slot_to_invalidate) +{ + slot_to_invalidate->slot.size = 0U; + atomic_clear_bit(valid_slots, slot_to_invalidate - &slots[0]); +} - return false; +static bool slot_eq(const struct bt_mesh_dfu_slot *slot, + const uint8_t *fwid, size_t fwid_len) +{ + return (slot->fwid_len == fwid_len) && + !memcmp(fwid, slot->fwid, fwid_len); } static int slot_store(const struct slot *slot_to_store) { - uint16_t idx = ARRAY_INDEX(slots, slot_to_store); + uint16_t idx = slot_to_store - &slots[0]; char buf[SLOT_ENTRY_BUFLEN]; int err; @@ -86,51 +90,55 @@ static int slot_store(const struct slot *slot_to_store) err = settings_save_one(slot_entry_encode(idx, buf, PROP_METADATA), slot_to_store->slot.metadata, slot_to_store->slot.metadata_len); + if (err) { + return err; + } - return err; + return settings_save_one(slot_entry_encode(idx, buf, PROP_URI), + slot_to_store->slot.uri, slot_to_store->slot.uri_len); } static void slot_erase(struct slot *slot_to_erase) { - uint16_t idx = ARRAY_INDEX(slots, slot_to_erase); + uint16_t idx = slot_to_erase - &slots[0]; char buf[SLOT_ENTRY_BUFLEN]; settings_delete(slot_entry_encode(idx, buf, PROP_HEADER)); settings_delete(slot_entry_encode(idx, buf, PROP_FWID)); settings_delete(slot_entry_encode(idx, buf, PROP_METADATA)); + settings_delete(slot_entry_encode(idx, buf, PROP_URI)); } -static void slot_index_defrag(void) +static int valid_slots_store(void) { - slot_index = 0; - struct slot *s; - - SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - s->idx = ++slot_index; - slot_store(s); - } + return settings_save_one(DFU_SLOT_SETTINGS_PATH "/" VALID_SLOTS_TAG, + valid_slots, sizeof(valid_slots)); } -int bt_mesh_dfu_slot_count(void) +const struct bt_mesh_dfu_slot * +bt_mesh_dfu_slot_add(size_t size, const uint8_t *fwid, + size_t fwid_len, const uint8_t *metadata, + size_t metadata_len, const char *uri, size_t uri_len) { - int cnt = 0; - sys_snode_t *n; + struct slot *slot = NULL; + int err, i; - SYS_SLIST_FOR_EACH_NODE(&list, n) { - cnt++; + if (size == 0 || fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN || + metadata_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN || + uri_len > CONFIG_BT_MESH_DFU_URI_MAXLEN) { + LOG_WRN("Param too large: (size: %d, fwid: %d, metadata: %d, uri: %d)", + size, fwid_len, metadata_len, uri_len); + return NULL; } - return cnt; -} - -struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void) -{ - struct slot *slot = NULL; - - for (int i = 0; i < ARRAY_SIZE(slots); ++i) { - if (slots[i].idx == 0) { + for (i = 0; i < ARRAY_SIZE(slots); ++i) { + if (!slot_in_use(&slots[i].slot)) { slot = &slots[i]; - break; + continue; + } + + if (slot_eq(&slots[i].slot, fwid, fwid_len)) { + return &slots[i].slot; } } @@ -139,136 +147,110 @@ struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void) return NULL; } - if (slot_index == UINT32_MAX) { - slot_index_defrag(); - } + slot->slot.fwid_len = fwid_len; + slot->slot.metadata_len = metadata_len; + slot->slot.uri_len = uri_len; + memcpy(slot->slot.fwid, fwid, fwid_len); + memcpy(slot->slot.metadata, metadata, metadata_len); + memcpy(slot->slot.uri, uri, uri_len); + slot->slot.size = size; - slot->slot.fwid_len = 0; - slot->slot.metadata_len = 0; - slot->slot.size = 0; - slot->idx = ++slot_index; + err = slot_store(slot); + if (err) { + slot_invalidate(slot); + LOG_WRN("Store failed (err: %d)", err); + return NULL; + } - LOG_DBG("Reserved slot #%u", slot - &slots[0]); + sys_slist_append(&list, &slot->n); + LOG_DBG("Added slot #%u: %s", slot - &slots[0], + bt_hex(slot->slot.fwid, slot->slot.fwid_len)); return &slot->slot; } -int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size, - const uint8_t *metadata, size_t metadata_len) +int bt_mesh_dfu_slot_valid_set(const struct bt_mesh_dfu_slot *slot, bool valid) { - struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); - - if (metadata_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN) { - return -EFBIG; - } + uint16_t idx; + bool prev; + int err; - if (slot->idx == 0 || is_slot_committed(slot)) { - return -EINVAL; + if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { + return -ENOENT; } - slot->slot.size = size; - slot->slot.metadata_len = metadata_len; - memcpy(slot->slot.metadata, metadata, metadata_len); - return 0; -} - -int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot, - const uint8_t *fwid, size_t fwid_len) -{ - struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); + idx = slot_idx(slot); - if (fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN) { - return -EFBIG; - } + LOG_DBG("%u: %u", idx, valid); - if (slot->idx == 0 || is_slot_committed(slot)) { - return -EINVAL; - } - - for (int i = 0; i < ARRAY_SIZE(slots); i++) { - if (slots[i].idx != 0 && - slot_eq(&slots[i].slot, fwid, fwid_len)) { - return is_slot_committed(&slots[i]) ? - -EEXIST : -EALREADY; - } + if (valid) { + prev = atomic_test_and_set_bit(valid_slots, idx); + } else { + prev = atomic_test_and_clear_bit(valid_slots, idx); } - slot->slot.fwid_len = fwid_len; - memcpy(slot->slot.fwid, fwid, fwid_len); - return 0; -} - -int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot) -{ - int err; - struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); - - if (slot->idx == 0 || - slot->slot.fwid_len == 0 || - slot->slot.size == 0 || - is_slot_committed(slot)) { - return -EINVAL; + if (valid == prev) { + return 0; } - err = slot_store(slot); + err = valid_slots_store(); if (err) { - LOG_WRN("Store failed (err: %d)", err); - return err; + LOG_WRN("Storage failed. err: %d", err); + atomic_set_bit_to(valid_slots, idx, prev); } - sys_slist_append(&list, &slot->n); - - LOG_DBG("Stored slot #%u: %s", ARRAY_INDEX(slots, slot), - bt_hex(slot->slot.fwid, slot->slot.fwid_len)); - return 0; + return err; } -void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot) +bool bt_mesh_dfu_slot_is_valid(const struct bt_mesh_dfu_slot *slot) { - struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); + uint16_t idx; - if (is_slot_committed(slot)) { - return; + if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { + return false; } - slot->idx = 0; + idx = slot_idx(slot); + return atomic_test_bit(valid_slots, idx); } -int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *dfu_slot) +int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *slot) { - struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot); + struct slot *s = CONTAINER_OF(slot, struct slot, slot); - if (!sys_slist_find_and_remove(&list, &slot->n)) { - return -EINVAL; + if (!SLOT_IN_ARRAY(slot) || !slot_in_use(slot)) { + return -ENOENT; } - int idx = ARRAY_INDEX(slots, slot); + LOG_DBG("%u", s - &slots[0]); - LOG_DBG("%u", idx); - - slot_erase(slot); - slot->idx = 0; + slot_erase(s); + slot_invalidate(s); + sys_slist_find_and_remove(&list, &s->n); return 0; } -void bt_mesh_dfu_slot_del_all(void) +int bt_mesh_dfu_slot_del_all(void) { struct slot *s; + SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { slot_erase(s); - s->idx = 0; + slot_invalidate(s); } sys_slist_init(&list); + + return 0; } -const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx) +const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx) { struct slot *s; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (!img_idx--) { + if (!idx--) { return &s->slot; } } @@ -276,33 +258,34 @@ const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx) return NULL; } -int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot) +int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, + const struct bt_mesh_dfu_slot **slot) { struct slot *s; int idx = 0; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { if (slot_eq(&s->slot, fwid, fwid_len)) { - if (slot) { - *slot = &s->slot; - } + *slot = &s->slot; return idx; } + idx++; } return -ENOENT; } -int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *dfu_slot) +int bt_mesh_dfu_slot_idx_get(const struct bt_mesh_dfu_slot *slot) { struct slot *s; int idx = 0; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (&s->slot == dfu_slot) { + if (&s->slot == slot) { return idx; } + idx++; } @@ -312,12 +295,11 @@ int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *dfu_slot) size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data) { enum bt_mesh_dfu_iter iter; - size_t cnt = 0; struct slot *s; + size_t cnt = 0; SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { cnt++; - if (!cb) { continue; } @@ -338,6 +320,15 @@ static int slot_data_load(const char *key, size_t len_rd, size_t len; uint16_t idx; + if (!strncmp(key, VALID_SLOTS_TAG, 1)) { + if (read_cb(cb_arg, valid_slots, + MIN(sizeof(valid_slots), len_rd)) < 0) { + return -EINVAL; + } + + return 0; + } + idx = strtol(key, NULL, 16); if (idx >= ARRAY_SIZE(slots)) { @@ -348,34 +339,16 @@ static int slot_data_load(const char *key, size_t len_rd, if (!strncmp(prop, PROP_HEADER, len)) { if (read_cb(cb_arg, &slots[idx], HEADER_SIZE) > 0) { - struct slot *s, *prev = NULL; - - SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) { - if (s->idx > slots[idx].idx) { - break; - } - - prev = s; - } - - if (prev == NULL) { - sys_slist_prepend(&list, &slots[idx].n); - } else { - sys_slist_insert(&list, &prev->n, &slots[idx].n); - } - - if (slots[idx].idx >= slot_index) { - slot_index = slots[idx].idx + 1; - } + sys_slist_append(&list, &slots[idx].n); } + return 0; } if (!strncmp(prop, PROP_FWID, len)) { if (read_cb(cb_arg, &slots[idx].slot.fwid, sizeof(slots[idx].slot.fwid)) < 0) { - slots[idx].idx = 0; - sys_slist_find_and_remove(&list, &slots[idx].n); + slot_invalidate(&slots[idx]); return 0; } @@ -386,8 +359,7 @@ static int slot_data_load(const char *key, size_t len_rd, if (!strncmp(prop, PROP_METADATA, len)) { if (read_cb(cb_arg, &slots[idx].slot.metadata, sizeof(slots[idx].slot.metadata)) < 0) { - slots[idx].idx = 0; - sys_slist_find_and_remove(&list, &slots[idx].n); + slot_invalidate(&slots[idx]); return 0; } @@ -395,6 +367,16 @@ static int slot_data_load(const char *key, size_t len_rd, return 0; } + if (!strncmp(prop, PROP_URI, len)) { + if (read_cb(cb_arg, &slots[idx].slot.uri, + sizeof(slots[idx].slot.uri)) < 0) { + slot_invalidate(&slots[idx]); + return 0; + } + + slots[idx].slot.uri_len = len_rd; + } + return 0; } diff --git a/subsys/bluetooth/mesh/dfu_slot.h b/subsys/bluetooth/mesh/dfu_slot.h index 969c6d3d25b..1bc58f64de9 100644 --- a/subsys/bluetooth/mesh/dfu_slot.h +++ b/subsys/bluetooth/mesh/dfu_slot.h @@ -16,69 +16,50 @@ typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_slot_cb_t)( const struct bt_mesh_dfu_slot *slot, void *user_data); -/** @brief Get the number of slots committed to the firmware list. - * - * @return Number of committed slots. - */ -int bt_mesh_dfu_slot_count(void); - -/** @brief Reserve a new DFU image slot for a distributable image. +/** @brief Register a new DFU image slot for a distributable image. * * A DFU image slot represents a single distributable DFU image with all its - * metadata. The slot data must be set using @ref bt_mesh_dfu_slot_info_set and - * @ref bt_mesh_dfu_slot_fwid_set, and the slot committed using - * @ref bt_mesh_dfu_slot_commit for the slot to be considered part of the slot - * list. + * metadata. * - * @return A pointer to the reserved slot, or NULL if allocation failed. - */ -struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void); - -/** @brief Set the size and metadata for a reserved slot. + * @note The slot is allocated as invalid. Call + * @ref bt_mesh_dfu_slot_valid_set to make it valid. * - * @param dfu_slot Pointer to the reserved slot for which to set the - * metadata. - * @param size The size of the image. + * @param size Size of the image in bytes. + * @param fwid Firmware ID. + * @param fwid_len Length of the firmware ID, at most @c + * CONFIG_BT_MESH_DFU_FWID_MAXLEN. * @param metadata Metadata or NULL. * @param metadata_len Length of the metadata, at most @c * CONFIG_BT_MESH_DFU_METADATA_MAXLEN. + * @param uri Image URI or NULL. + * @param uri_len Length of the image URI, at most @c + * CONFIG_BT_MESH_DFU_URI_MAXLEN. * - * @return 0 on success, (negative) error code otherwise. + * @return A pointer to the allocated slot, or NULL if allocation failed. */ -int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size, - const uint8_t *metadata, size_t metadata_len); +const struct bt_mesh_dfu_slot * +bt_mesh_dfu_slot_add(size_t size, const uint8_t *fwid, size_t fwid_len, + const uint8_t *metadata, size_t metadata_len, + const char *uri, size_t uri_len); -/** @brief Set the new fwid for the incoming image for a reserved slot. +/** @brief Set whether the given slot is valid. * - * @param dfu_slot Pointer to the reserved slot for which to set the fwid. - * @param fwid Fwid to set. - * @param fwid_len Length of the fwid, at most @c - * CONFIG_BT_MESH_DFU_FWID_MAXLEN. + * @param slot Allocated DFU image slot. + * @param valid New valid state of the slot. * - * @return 0 on success, (negative) error code otherwise. + * @return 0 on success, or (negative) error code on failure. */ -int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot, - const uint8_t *fwid, size_t fwid_len); +int bt_mesh_dfu_slot_valid_set(const struct bt_mesh_dfu_slot *slot, bool valid); -/** @brief Commit the reserved slot to the list of slots, and store it - * persistently. - * - * If the commit fails for any reason, the slot will still be in the reserved - * state after this call. - * - * @param dfu_slot Pointer to the reserved slot. +/** @brief Check whether a slot is valid. * - * @return 0 on success, (negative) error code otherwise. - */ -int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot); - -/** @brief Release a reserved slot so that it can be reserved again. + * @param slot Slot to check. * - * @param dfu_slot Pointer to the reserved slot. + * @return true if the slot is valid, false otherwise. */ -void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot); +bool bt_mesh_dfu_slot_is_valid(const struct bt_mesh_dfu_slot *slot); -/** @brief Delete a committed DFU image slot. +/** @brief Delete an allocated DFU image slot. * * @param slot Slot to delete. Must be a valid pointer acquired from this * module. @@ -91,19 +72,18 @@ int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *slot); * * @return 0 on success, or (negative) error code on failure. */ -void bt_mesh_dfu_slot_del_all(void); +int bt_mesh_dfu_slot_del_all(void); -/** @brief Get the DFU image slot at the given firmware image list index. +/** @brief Get the DFU image slot at the given index. * * @param idx DFU image slot index. * * @return The DFU image slot at the given index, or NULL if no slot exists with the * given index. */ -const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx); +const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t idx); -/** @brief Get the committed DFU image slot for the image with the given - * firmware ID. +/** @brief Get the DFU image slot for the image with the given firmware ID. * * @param fwid Firmware ID. * @param fwid_len Firmware ID length. @@ -111,15 +91,16 @@ const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx); * * @return Slot index on success, or negative error code on failure. */ -int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot); +int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, + const struct bt_mesh_dfu_slot **slot); -/** @brief Get the index in the firmware image list for the given slot. +/** @brief Get the DFU image slot index of the given slot. * * @param slot Slot to find. * * @return Slot index on success, or negative error code on failure. */ -int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *slot); +int bt_mesh_dfu_slot_idx_get(const struct bt_mesh_dfu_slot *slot); /** @brief Iterate through all DFU image slots. * diff --git a/subsys/bluetooth/mesh/shell/dfd.c b/subsys/bluetooth/mesh/shell/dfd.c index b7daf42af1c..94d656f3689 100644 --- a/subsys/bluetooth/mesh/shell/dfd.c +++ b/subsys/bluetooth/mesh/shell/dfd.c @@ -43,7 +43,7 @@ static void print_fw_status(const struct shell *sh, enum bt_mesh_dfd_status stat uint16_t idx, const uint8_t *fwid, size_t fwid_len) { shell_fprintf(sh, SHELL_NORMAL, "{ \"status\": %d, \"slot_cnt\": %d, \"idx\": %d", - status, bt_mesh_dfu_slot_count(), idx); + status, bt_mesh_dfu_slot_foreach(NULL, NULL), idx); if (fwid) { shell_fprintf(sh, SHELL_NORMAL, ", \"fwid\": \""); for (size_t i = 0; i < fwid_len; i++) { @@ -325,9 +325,10 @@ static int cmd_dfd_fw_get(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, NULL); + const struct bt_mesh_dfu_slot *slot; + int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); - if (idx >= 0) { + if (idx >= 0 && bt_mesh_dfu_slot_is_valid(slot)) { print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, fwid, fwid_len); } else { print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, 0xffff, fwid, fwid_len); @@ -348,7 +349,7 @@ static int cmd_dfd_fw_get_by_idx(const struct shell *sh, size_t argc, char *argv return err; } - if (slot) { + if (slot && bt_mesh_dfu_slot_is_valid(slot)) { print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, slot->fwid, slot->fwid_len); } else { print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, idx, NULL, 0); diff --git a/subsys/bluetooth/mesh/shell/dfu.c b/subsys/bluetooth/mesh/shell/dfu.c index 8d7fc96e014..71d27b158e4 100644 --- a/subsys/bluetooth/mesh/shell/dfu.c +++ b/subsys/bluetooth/mesh/shell/dfu.c @@ -375,12 +375,13 @@ static int cmd_dfu_metadata_encode(const struct shell *sh, size_t argc, char *ar static int cmd_dfu_slot_add(const struct shell *sh, size_t argc, char *argv[]) { - struct bt_mesh_dfu_slot *slot; + const struct bt_mesh_dfu_slot *slot; size_t size; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; size_t fwid_len = 0; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN]; size_t metadata_len = 0; + const char *uri = ""; int err = 0; size = shell_strtoul(argv[1], 0, &err); @@ -389,33 +390,32 @@ static int cmd_dfu_slot_add(const struct shell *sh, size_t argc, char *argv[]) return err; } - shell_print(sh, "Adding slot (size: %u)", size); - slot = bt_mesh_dfu_slot_reserve(); - - if (!slot) { - shell_print(sh, "Failed to reserve slot."); - return 0; + if (argc > 2) { + fwid_len = hex2bin(argv[2], strlen(argv[2]), fwid, + sizeof(fwid)); } - fwid_len = hex2bin(argv[2], strlen(argv[2]), fwid, - sizeof(fwid)); - bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len); - if (argc > 3) { metadata_len = hex2bin(argv[3], strlen(argv[3]), metadata, sizeof(metadata)); } - bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len); + if (argc > 4) { + uri = argv[4]; + } - err = bt_mesh_dfu_slot_commit(slot); - if (err) { - shell_print(sh, "Failed to commit slot: %d", err); - bt_mesh_dfu_slot_release(slot); - return err; + shell_print(sh, "Adding slot (size: %u)", size); + + slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, + metadata_len, uri, strlen(uri)); + if (!slot) { + shell_print(sh, "Failed."); + return 0; } - shell_print(sh, "Slot added. Index: %u", bt_mesh_dfu_slot_img_idx_get(slot)); + bt_mesh_dfu_slot_valid_set(slot, true); + + shell_print(sh, "Slot added. ID: %u", bt_mesh_dfu_slot_idx_get(slot)); return 0; } @@ -451,7 +451,14 @@ static int cmd_dfu_slot_del(const struct shell *sh, size_t argc, char *argv[]) static int cmd_dfu_slot_del_all(const struct shell *sh, size_t argc, char *argv[]) { - bt_mesh_dfu_slot_del_all(); + int err; + + err = bt_mesh_dfu_slot_del_all(); + if (err) { + shell_print(sh, "Failed deleting all slots (err: %d)", err); + return 0; + } + shell_print(sh, "All slots deleted."); return 0; } @@ -461,6 +468,7 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo { char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1]; char metadata[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1]; + char uri[CONFIG_BT_MESH_DFU_URI_MAXLEN + 1]; size_t len; len = bin2hex(slot->fwid, slot->fwid_len, fwid, sizeof(fwid)); @@ -468,6 +476,8 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo len = bin2hex(slot->metadata, slot->metadata_len, metadata, sizeof(metadata)); metadata[len] = '\0'; + memcpy(uri, slot->uri, slot->uri_len); + uri[slot->uri_len] = '\0'; if (idx != NULL) { shell_print(sh, "Slot %u:", *idx); @@ -477,6 +487,7 @@ static void slot_info_print(const struct shell *sh, const struct bt_mesh_dfu_slo shell_print(sh, "\tSize: %u bytes", slot->size); shell_print(sh, "\tFWID: %s", fwid); shell_print(sh, "\tMetadata: %s", metadata); + shell_print(sh, "\tURI: %s", uri); } static int cmd_dfu_slot_get(const struct shell *sh, size_t argc, char *argv[]) @@ -959,8 +970,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_STATIC_SUBCMD_SET_CREATE( dfu_slot_cmds, SHELL_CMD_ARG(add, NULL, - " []", - cmd_dfu_slot_add, 3, 1), + " [ [ []]]", + cmd_dfu_slot_add, 2, 3), SHELL_CMD_ARG(del, NULL, "", cmd_dfu_slot_del, 2, 0), SHELL_CMD_ARG(del-all, NULL, NULL, cmd_dfu_slot_del_all, 1, 0), SHELL_CMD_ARG(get, NULL, "", cmd_dfu_slot_get, 2, 0), diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index 2e08329b7ef..e870e190481 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -58,8 +58,7 @@ CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y CONFIG_BT_MESH_DFU_SRV=y CONFIG_BT_MESH_DFU_CLI=y CONFIG_BT_MESH_DFD_SRV=y -CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD=y -CONFIG_BT_MESH_DFU_SLOT_CNT=4 +CONFIG_BT_MESH_DFU_SLOT_CNT=3 CONFIG_BT_MESH_PRIV_BEACON_SRV=y CONFIG_BT_MESH_PRIV_BEACON_CLI=y CONFIG_BT_MESH_COMP_PAGE_1=y diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index a235e86eeec..f7c4ca6f4f0 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -434,50 +434,25 @@ static void target_prov_and_conf_default(void) target_prov_and_conf(addr, bind_params, ARRAY_SIZE(bind_params)); } -static struct bt_mesh_dfu_slot *slot_reserve_and_set(size_t size, uint8_t *fwid, size_t fwid_len, - uint8_t *metadata, size_t metadata_len) -{ - struct bt_mesh_dfu_slot *new_slot = bt_mesh_dfu_slot_reserve(); - - if (!new_slot) { - LOG_WRN("Reserving slot failed"); - return NULL; - } - - int err = bt_mesh_dfu_slot_fwid_set(new_slot, fwid, fwid_len); - - if (err) { - return NULL; - } - - err = bt_mesh_dfu_slot_info_set(new_slot, size, metadata, metadata_len); - - if (err) { - return NULL; - } - - return new_slot; -} - static bool slot_add(const struct bt_mesh_dfu_slot **slot) { - struct bt_mesh_dfu_slot *new_slot; + const struct bt_mesh_dfu_slot *new_slot; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; size_t metadata_len = 4; + const char *uri = ""; ASSERT_EQUAL(sizeof(target_fw_ver_new), fwid_len); - new_slot = slot_reserve_and_set(size, fwid, fwid_len, metadata, metadata_len); + new_slot = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len, uri, + strlen(uri)); if (!new_slot) { return false; } - if (bt_mesh_dfu_slot_commit(new_slot) != 0) { - return false; - } + bt_mesh_dfu_slot_valid_set(new_slot, true); if (slot) { *slot = new_slot; @@ -593,12 +568,13 @@ static void test_dist_dfu_self_update(void) static void test_dist_dfu_slot_create(void) { - struct bt_mesh_dfu_slot *slot[CONFIG_BT_MESH_DFU_SLOT_CNT]; + const struct bt_mesh_dfu_slot *slot[3]; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; + const char *uri = "test"; int err, i; ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, @@ -608,26 +584,36 @@ static void test_dist_dfu_slot_create(void) bt_mesh_device_setup(&prov, &dist_comp); dist_prov_and_conf(DIST_ADDR); - for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { + for (i = CONFIG_BT_MESH_DFU_SLOT_CNT - 1; i >= 0; i--) { fwid[0] = i; metadata[0] = i; - slot[i] = slot_reserve_and_set(size, fwid, fwid_len, metadata, metadata_len); + slot[i] = bt_mesh_dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len, uri, + strlen(uri)); ASSERT_FALSE(slot[i] == NULL, "Failed to add slot"); + } - if (i > 0) { - /* All but first slot are committed */ - err = bt_mesh_dfu_slot_commit(slot[i]); - if (err) { - FAIL("Committing slot failed (err %d)", err); - } - } + /* First slot is set as valid */ + err = bt_mesh_dfu_slot_valid_set(slot[0], true); + if (err) { + FAIL("Setting slot to valid state failed (err %d)", err); + return; + } + ASSERT_TRUE(bt_mesh_dfu_slot_is_valid(slot[0])); + + /* Second slot is set as invalid */ + err = bt_mesh_dfu_slot_valid_set(slot[1], false); + if (err) { + FAIL("Setting slot to invalid state failed (err %d)", err); + return; } + ASSERT_TRUE(!bt_mesh_dfu_slot_is_valid(slot[1])); - /* Second slot is deleted */ - err = bt_mesh_dfu_slot_del(slot[1]); + /* Last slot is deleted */ + err = bt_mesh_dfu_slot_del(slot[CONFIG_BT_MESH_DFU_SLOT_CNT - 1]); if (err) { FAIL("Slot delete failed (err %d)", err); + return; } PASS(); @@ -640,17 +626,20 @@ enum bt_mesh_dfu_iter check_slot(const struct bt_mesh_dfu_slot *slot, void *data size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; - int idx = bt_mesh_dfu_slot_img_idx_get(slot); - int *i = data; + const char *uri = "test"; + int idx = bt_mesh_dfu_slot_idx_get(slot); + + ASSERT_TRUE(idx >= 0, "Failed to retrieve slot index"); - ASSERT_EQUAL(idx, (*i)++); ASSERT_EQUAL(size, slot->size); + ASSERT_TRUE(strcmp(uri, slot->uri) == 0); + + fwid[0] = idx; - fwid[0] = idx + 2; ASSERT_EQUAL(fwid_len, slot->fwid_len); ASSERT_TRUE(memcmp(fwid, slot->fwid, fwid_len) == 0); - metadata[0] = idx + 2; + metadata[0] = idx; ASSERT_EQUAL(metadata_len, slot->metadata_len); ASSERT_TRUE(memcmp(metadata, slot->metadata, metadata_len) == 0); @@ -660,12 +649,13 @@ enum bt_mesh_dfu_iter check_slot(const struct bt_mesh_dfu_slot *slot, void *data static void test_dist_dfu_slot_create_recover(void) { size_t slot_count; - struct bt_mesh_dfu_slot *slot; + const struct bt_mesh_dfu_slot *slot; size_t size = 100; uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; size_t fwid_len = 4; uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN] = { 0 }; size_t metadata_len = 4; + const char *uri = "test"; int i, idx; ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 3, @@ -674,17 +664,26 @@ static void test_dist_dfu_slot_create_recover(void) bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &dist_comp); - i = 0; - slot_count = bt_mesh_dfu_slot_foreach(check_slot, &i); - ASSERT_EQUAL(CONFIG_BT_MESH_DFU_SLOT_CNT - 2, slot_count); + slot_count = bt_mesh_dfu_slot_foreach(check_slot, NULL); + ASSERT_EQUAL(CONFIG_BT_MESH_DFU_SLOT_CNT - 1, slot_count); + + slot = bt_mesh_dfu_slot_at(0); + ASSERT_EQUAL(true, bt_mesh_dfu_slot_is_valid(slot)); - for (i = 2; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { + slot = bt_mesh_dfu_slot_at(1); + ASSERT_TRUE(slot != NULL); + ASSERT_EQUAL(false, bt_mesh_dfu_slot_is_valid(slot)); + + for (i = 0; i < (CONFIG_BT_MESH_DFU_SLOT_CNT - 1); i++) { fwid[0] = i; idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); - ASSERT_EQUAL(idx, i - 2); + ASSERT_TRUE(idx >= 0); + ASSERT_EQUAL(idx, bt_mesh_dfu_slot_idx_get(slot)); + ASSERT_EQUAL(size, slot->size); + ASSERT_TRUE(strcmp(uri, slot->uri) == 0); - metadata[0] = i; + metadata[0] = idx; ASSERT_EQUAL(metadata_len, slot->metadata_len); ASSERT_TRUE(memcmp(metadata, slot->metadata, metadata_len) == 0); } @@ -694,7 +693,7 @@ static void test_dist_dfu_slot_create_recover(void) static void check_delete_all(void) { - int i; + int i, idx, err; const struct bt_mesh_dfu_slot *slot; size_t slot_count; @@ -707,6 +706,14 @@ static void check_delete_all(void) for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT - 1; i++) { slot = bt_mesh_dfu_slot_at(i); ASSERT_TRUE(slot == NULL); + + idx = bt_mesh_dfu_slot_idx_get(slot); + ASSERT_TRUE(idx < 0); + + err = bt_mesh_dfu_slot_valid_set(slot, true); + ASSERT_EQUAL(err, -ENOENT); + + ASSERT_TRUE(!bt_mesh_dfu_slot_is_valid(slot)); } } @@ -719,6 +726,7 @@ static void test_dist_dfu_slot_delete_all(void) bt_mesh_device_setup(&prov, &dist_comp); bt_mesh_dfu_slot_del_all(); + check_delete_all(); PASS(); @@ -734,63 +742,6 @@ static void test_dist_dfu_slot_check_delete_all(void) PASS(); } -static void test_dist_dfu_slot_reservation(void) -{ - int i; - struct bt_mesh_dfu_slot *slots[CONFIG_BT_MESH_DFU_SLOT_CNT]; - - bt_mesh_test_cfg_set(NULL, WAIT_TIME); - bt_mesh_device_setup(&prov, &dist_comp); - - for (i = 0; i < CONFIG_BT_MESH_DFU_SLOT_CNT; i++) { - slots[i] = bt_mesh_dfu_slot_reserve(); - ASSERT_TRUE(slots[i] != NULL); - } - - ASSERT_EQUAL(NULL, bt_mesh_dfu_slot_reserve()); - bt_mesh_dfu_slot_release(slots[0]); - /* Release twice to check idempotency with empty pool */ - bt_mesh_dfu_slot_release(slots[0]); - ASSERT_TRUE(bt_mesh_dfu_slot_reserve() != NULL); - ASSERT_EQUAL(NULL, bt_mesh_dfu_slot_reserve()); - - PASS(); -} - -static void test_dist_dfu_slot_idempotency(void) -{ - uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0 }; - size_t fwid_len = 4; - struct bt_mesh_dfu_slot *slot; - - ASSERT_TRUE(CONFIG_BT_MESH_DFU_SLOT_CNT >= 1, - "CONFIG_BT_MESH_DFU_SLOT_CNT must be at least 1"); - - bt_mesh_test_cfg_set(NULL, WAIT_TIME); - bt_mesh_device_setup(&prov, &dist_comp); - dist_prov_and_conf(DIST_ADDR); - - slot = bt_mesh_dfu_slot_reserve(); - ASSERT_TRUE(slot != NULL); - - bt_mesh_dfu_slot_release(slot); - bt_mesh_dfu_slot_release(slot); - - slot = bt_mesh_dfu_slot_reserve(); - ASSERT_TRUE(slot != NULL); - - ASSERT_EQUAL(0, bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len)); - ASSERT_EQUAL(0, bt_mesh_dfu_slot_info_set(slot, 100, NULL, 0)); - - ASSERT_EQUAL(0, bt_mesh_dfu_slot_commit(slot)); - ASSERT_EQUAL(-EINVAL, bt_mesh_dfu_slot_commit(slot)); - - ASSERT_EQUAL(0, bt_mesh_dfu_slot_del(slot)); - ASSERT_EQUAL(-EINVAL, bt_mesh_dfu_slot_del(slot)); - - PASS(); -} - static void target_test_effect(enum bt_mesh_dfu_effect effect) { dfu_target_effect = effect; @@ -970,14 +921,12 @@ static void cli_common_fail_on_init(void) static void cli_common_init_recover(void) { - struct bt_mesh_dfu_slot *slot; - uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = { 0xAA, 0xBB, 0xCC, 0xDD }; - size_t fwid_len = 4; + const struct bt_mesh_dfu_slot *slot; bt_mesh_test_cfg_set(NULL, 300); bt_mesh_device_setup(&prov, &cli_comp); - ASSERT_TRUE(bt_mesh_dfu_slot_get(fwid, fwid_len, &slot) >= 0); + ASSERT_TRUE(slot_add(&slot)); dfu_cli_inputs_prepare(0); dfu_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH; @@ -1646,10 +1595,6 @@ static const struct bst_test_instance test_dfu[] = { TEST_CASE(dist, dfu_slot_delete_all, "Distributor deletes all image slots"), TEST_CASE(dist, dfu_slot_check_delete_all, "Distributor checks if all slots are removed from persistent storage"), - TEST_CASE(dist, dfu_slot_reservation, - "Distributor checks that the correct number of slots can be reserved"), - TEST_CASE(dist, dfu_slot_idempotency, - "Distributor checks that the the DFU slot APIs are idempotent"), TEST_CASE(cli, stop, "DFU Client stops at configured point of Firmware Distribution"), TEST_CASE(cli, fail_on_persistency, "DFU Client doesn't give up DFU Transfer"), TEST_CASE(cli, all_targets_lost_on_metadata, diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh deleted file mode 100755 index 3f18f1a2651..00000000000 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2023 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh - -# Test DFU Slot API. This test tests that the APIs are idempotent. -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest dfu_slot_idempotency dfu_dist_dfu_slot_idempotency - -conf=prj_mesh1d1_conf -overlay="overlay_pst_conf_overlay_psa_conf" -RunTest dfu_slot_idempotency_psa dfu_dist_dfu_slot_idempotency diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh deleted file mode 100755 index ddd7d0123f5..00000000000 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2023 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh - -# Test DFU Slot API. This test tests slot reservation APIs. -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest dfu_slot_reservation dfu_dist_dfu_slot_reservation - -conf=prj_mesh1d1_conf -overlay="overlay_pst_conf_overlay_psa_conf" -RunTest dfu_slot_reservation_psa dfu_dist_dfu_slot_reservation From a06eaede9acd272c40c09aac4d06378d3da7be25 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:28 +0000 Subject: [PATCH 4299/4498] Revert "[nrf fromtree] Bluetooth: Mesh: add optional OOB info to ext scan report" This reverts commit 96ac408fa71a6310e2a7565377854c1886cf5e42. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/rpr_srv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index c8639d8b514..b38bec4cd40 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -267,15 +267,13 @@ static void scan_ext_report_send(void) bt_mesh_model_msg_init(&buf, RPR_OP_EXTENDED_SCAN_REPORT); net_buf_simple_add_u8(&buf, BT_MESH_RPR_SUCCESS); net_buf_simple_add_mem(&buf, srv.scan.dev->uuid, 16); - - if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND) { - net_buf_simple_add_le16(&buf, srv.scan.dev->oob); - } else { + if (!(srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND)) { LOG_DBG("not found"); goto send; } if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD) { + net_buf_simple_add_le16(&buf, srv.scan.dev->oob); net_buf_simple_add_mem(&buf, srv.scan.adv_data->data, srv.scan.adv_data->len); LOG_DBG("adv data: %s", From 0ca394e9e2e1fb5f02df02c14395f801501bfceb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:28 +0000 Subject: [PATCH 4300/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Store priv proxy in sep entry" This reverts commit fbbfa43fae8509eef87eb3151281c3f10ed6265a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/cfg.c | 15 ++++-- subsys/bluetooth/mesh/od_priv_proxy.h | 7 --- subsys/bluetooth/mesh/od_priv_proxy_srv.c | 65 ----------------------- 3 files changed, 12 insertions(+), 75 deletions(-) delete mode 100644 subsys/bluetooth/mesh/od_priv_proxy.h diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index c7bea0d29b0..4a59f76bbbd 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -16,7 +16,6 @@ #include "friend.h" #include "adv.h" #include "cfg.h" -#include "od_priv_proxy.h" #include "priv_beacon.h" #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL @@ -32,6 +31,9 @@ struct cfg_val { uint8_t gatt_proxy; uint8_t frnd; uint8_t default_ttl; +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + uint8_t on_demand_state; +#endif }; void bt_mesh_beacon_set(bool beacon) @@ -155,9 +157,9 @@ int bt_mesh_od_priv_proxy_set(uint8_t on_demand_proxy) bt_mesh.on_demand_state = on_demand_proxy; } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_od_priv_proxy_srv_store_schedule(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; #endif @@ -447,6 +449,9 @@ static int cfg_set(const char *name, size_t len_rd, bt_mesh_gatt_proxy_set(cfg.gatt_proxy); bt_mesh_friend_set(cfg.frnd); bt_mesh_default_ttl_set(cfg.default_ttl); +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + bt_mesh_od_priv_proxy_set(cfg.on_demand_state); +#endif LOG_DBG("Restored configuration state"); @@ -479,6 +484,10 @@ static void store_pending_cfg(void) val.gatt_proxy = bt_mesh_gatt_proxy_get(); val.frnd = bt_mesh_friend_get(); val.default_ttl = bt_mesh_default_ttl_get(); +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + val.on_demand_state = bt_mesh_od_priv_proxy_get(); +#endif + err = settings_save_one("bt/mesh/Cfg", &val, sizeof(val)); if (err) { diff --git a/subsys/bluetooth/mesh/od_priv_proxy.h b/subsys/bluetooth/mesh/od_priv_proxy.h deleted file mode 100644 index 7baa7f067fc..00000000000 --- a/subsys/bluetooth/mesh/od_priv_proxy.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -void bt_mesh_od_priv_proxy_srv_store_schedule(void); diff --git a/subsys/bluetooth/mesh/od_priv_proxy_srv.c b/subsys/bluetooth/mesh/od_priv_proxy_srv.c index b18a8ec7530..32f5ea44179 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_srv.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_srv.c @@ -9,28 +9,11 @@ #include "access.h" #include "cfg.h" #include "foundation.h" -#include "settings.h" #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_od_priv_proxy_srv); - -static struct bt_mesh_model *od_priv_proxy_srv; -static uint8_t on_demand_state; - -static int od_priv_proxy_store(bool delete) -{ - if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { - return 0; - } - - const void *data = delete ? NULL : &on_demand_state; - size_t len = delete ? 0 : sizeof(uint8_t); - - return bt_mesh_model_data_store(od_priv_proxy_srv, false, "pp", data, len); -} - static int proxy_status_rsp(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { @@ -81,8 +64,6 @@ const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_srv_op[] = { static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) { - od_priv_proxy_srv = mod; - struct bt_mesh_model *priv_beacon_srv = bt_mesh_model_find( bt_mesh_model_elem(mod), BT_MESH_MODEL_ID_PRIV_BEACON_SRV); struct bt_mesh_model *sol_pdu_rpl_srv = bt_mesh_model_find( @@ -108,52 +89,6 @@ static int od_priv_proxy_srv_init(struct bt_mesh_model *mod) return 0; } -static void od_priv_proxy_srv_reset(struct bt_mesh_model *model) -{ - on_demand_state = 0; - od_priv_proxy_store(true); -} - -#ifdef CONFIG_BT_SETTINGS -static int od_priv_proxy_srv_settings_set(struct bt_mesh_model *model, const char *name, - size_t len_rd, settings_read_cb read_cb, void *cb_data) -{ - int err; - - if (len_rd == 0) { - LOG_DBG("Cleared configuration state"); - return 0; - } - - err = bt_mesh_settings_set(read_cb, cb_data, &on_demand_state, sizeof(uint8_t)); - if (err) { - LOG_ERR("Failed to set OD private proxy state"); - return err; - } - - bt_mesh_od_priv_proxy_set(on_demand_state); - return 0; -} - -static void od_priv_proxy_srv_pending_store(struct bt_mesh_model *model) -{ - on_demand_state = bt_mesh_od_priv_proxy_get(); - od_priv_proxy_store(false); -} -#endif - const struct bt_mesh_model_cb _bt_mesh_od_priv_proxy_srv_cb = { .init = od_priv_proxy_srv_init, - .reset = od_priv_proxy_srv_reset, -#ifdef CONFIG_BT_SETTINGS - .settings_set = od_priv_proxy_srv_settings_set, - .pending_store = od_priv_proxy_srv_pending_store, -#endif }; - -void bt_mesh_od_priv_proxy_srv_store_schedule(void) -{ - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_model_data_store_schedule(od_priv_proxy_srv); - } -} From e614cbab4386b870a20bc3b497212ed01a1eb94a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:28 +0000 Subject: [PATCH 4301/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Store priv beacon in sep entry" This reverts commit 6e082b4141d1dc295dbf9359cacb342fba06aa9f. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/cfg.c | 27 +++++++-- subsys/bluetooth/mesh/priv_beacon.h | 7 --- subsys/bluetooth/mesh/priv_beacon_srv.c | 74 ------------------------- 3 files changed, 21 insertions(+), 87 deletions(-) delete mode 100644 subsys/bluetooth/mesh/priv_beacon.h diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index 4a59f76bbbd..287023afa68 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -16,7 +16,6 @@ #include "friend.h" #include "adv.h" #include "cfg.h" -#include "priv_beacon.h" #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL #include @@ -31,6 +30,11 @@ struct cfg_val { uint8_t gatt_proxy; uint8_t frnd; uint8_t default_ttl; +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + uint8_t priv_beacon; + uint8_t priv_beacon_int; + uint8_t priv_gatt_proxy; +#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) uint8_t on_demand_state; #endif @@ -105,9 +109,9 @@ int bt_mesh_priv_beacon_set(enum bt_mesh_feat_state priv_beacon) /* Beacon timer will stop automatically when all beacons are disabled. */ } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_priv_beacon_srv_store_schedule(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; @@ -240,9 +244,9 @@ int bt_mesh_priv_gatt_proxy_set(enum bt_mesh_feat_state priv_gatt_proxy) bt_mesh_adv_gatt_update(); } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_priv_beacon_srv_store_schedule(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; @@ -257,6 +261,7 @@ enum bt_mesh_feat_state bt_mesh_priv_gatt_proxy_get(void) return feature_get(BT_MESH_PRIV_GATT_PROXY); } + int bt_mesh_default_ttl_set(uint8_t default_ttl) { if (default_ttl == 1 || default_ttl > BT_MESH_TTL_MAX) { @@ -449,6 +454,11 @@ static int cfg_set(const char *name, size_t len_rd, bt_mesh_gatt_proxy_set(cfg.gatt_proxy); bt_mesh_friend_set(cfg.frnd); bt_mesh_default_ttl_set(cfg.default_ttl); +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + bt_mesh_priv_beacon_set(cfg.priv_beacon); + bt_mesh_priv_beacon_update_interval_set(cfg.priv_beacon_int); + bt_mesh_priv_gatt_proxy_set(cfg.priv_gatt_proxy); +#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) bt_mesh_od_priv_proxy_set(cfg.on_demand_state); #endif @@ -466,7 +476,7 @@ static void clear_cfg(void) err = settings_delete("bt/mesh/Cfg"); if (err) { - LOG_ERR("Failed to clear configuration (err: %d)", err); + LOG_ERR("Failed to clear configuration"); } else { LOG_DBG("Cleared configuration"); } @@ -484,6 +494,11 @@ static void store_pending_cfg(void) val.gatt_proxy = bt_mesh_gatt_proxy_get(); val.frnd = bt_mesh_friend_get(); val.default_ttl = bt_mesh_default_ttl_get(); +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + val.priv_beacon = bt_mesh_priv_beacon_get(); + val.priv_beacon_int = bt_mesh_priv_beacon_update_interval_get(); + val.priv_gatt_proxy = bt_mesh_priv_gatt_proxy_get(); +#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) val.on_demand_state = bt_mesh_od_priv_proxy_get(); #endif diff --git a/subsys/bluetooth/mesh/priv_beacon.h b/subsys/bluetooth/mesh/priv_beacon.h deleted file mode 100644 index 0cbbdafd0b1..00000000000 --- a/subsys/bluetooth/mesh/priv_beacon.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -void bt_mesh_priv_beacon_srv_store_schedule(void); diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index 377703e8352..a1478efff80 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -11,33 +11,11 @@ #include "foundation.h" #include "beacon.h" #include "cfg.h" -#include "settings.h" #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_priv_beacon_srv); -static struct bt_mesh_model *priv_beacon_srv; - -/* Private Beacon configuration server model states */ -struct { - uint8_t state; - uint8_t interval; - uint8_t proxy_state; -} priv_beacon_state; - -static int priv_beacon_store(bool delete) -{ - if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { - return 0; - } - - const void *data = delete ? NULL : &priv_beacon_state; - size_t len = delete ? 0 : sizeof(priv_beacon_state); - - return bt_mesh_model_data_store(priv_beacon_srv, false, "pb", data, len); -} - static int beacon_status_rsp(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { @@ -201,63 +179,11 @@ static int priv_beacon_srv_init(struct bt_mesh_model *mod) return -EINVAL; } - priv_beacon_srv = mod; mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; return 0; } -static void priv_beacon_srv_reset(struct bt_mesh_model *model) -{ - (void)memset(&priv_beacon_state, 0, sizeof(priv_beacon_state)); - priv_beacon_store(true); -} - -#ifdef CONFIG_BT_SETTINGS -static int priv_beacon_srv_settings_set(struct bt_mesh_model *model, const char *name, - size_t len_rd, settings_read_cb read_cb, void *cb_data) -{ - int err; - - if (len_rd == 0) { - LOG_DBG("Cleared configuration state"); - return 0; - } - - err = bt_mesh_settings_set(read_cb, cb_data, &priv_beacon_state, sizeof(priv_beacon_state)); - if (err) { - LOG_ERR("Failed to set Private Beacon state"); - return err; - } - - bt_mesh_priv_beacon_set(priv_beacon_state.state); - bt_mesh_priv_beacon_update_interval_set(priv_beacon_state.interval); - bt_mesh_priv_gatt_proxy_set(priv_beacon_state.proxy_state); - return 0; -} - -static void priv_beacon_srv_pending_store(struct bt_mesh_model *model) -{ - priv_beacon_state.state = bt_mesh_priv_beacon_get(); - priv_beacon_state.interval = bt_mesh_priv_beacon_update_interval_get(); - priv_beacon_state.proxy_state = bt_mesh_priv_gatt_proxy_get(); - - priv_beacon_store(false); -} -#endif - const struct bt_mesh_model_cb bt_mesh_priv_beacon_srv_cb = { .init = priv_beacon_srv_init, - .reset = priv_beacon_srv_reset, -#ifdef CONFIG_BT_SETTINGS - .settings_set = priv_beacon_srv_settings_set, - .pending_store = priv_beacon_srv_pending_store, -#endif }; - -void bt_mesh_priv_beacon_srv_store_schedule(void) -{ - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_model_data_store_schedule(priv_beacon_srv); - } -} From f8a72033af25c5b402be60e19cc8567bdb3cb575 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:28 +0000 Subject: [PATCH 4302/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Solicitation Mesh crypto API use" This reverts commit e99b89aedb7c7f2ece20244d5283d858b31ab29a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/solicitation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index f6543dcb320..1bf9f9a465a 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -304,7 +304,7 @@ static int sol_pdu_create(struct bt_mesh_subnet *sub, struct net_buf_simple *pdu /* DST = 0x0000 */ net_buf_simple_add_le16(pdu, 0x0000); - err = bt_mesh_net_encrypt(&sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.enc, + err = bt_mesh_net_encrypt(sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.enc, pdu, 0, BT_MESH_NONCE_SOLICITATION); if (err) { @@ -313,7 +313,7 @@ static int sol_pdu_create(struct bt_mesh_subnet *sub, struct net_buf_simple *pdu } err = bt_mesh_net_obfuscate(pdu->data, 0, - &sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.privacy); + sub->keys[SUBNET_KEY_TX_IDX(sub)].msg.privacy); if (err) { LOG_ERR("Obfuscation failed, err=%d", err); return err; From 9385973946cb212264ff48c7e9ed27daa02aa6e8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:28 +0000 Subject: [PATCH 4303/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Shell support for comp data page2" This reverts commit c227d927cb85b7bf66c151063a15092a06a7850d. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/mesh/cfg_cli.h | 34 -------------------- subsys/bluetooth/mesh/cfg_cli.c | 35 --------------------- subsys/bluetooth/mesh/shell/cfg.c | 42 ++----------------------- 3 files changed, 3 insertions(+), 108 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index d2221da38da..e6fd31d7c3a 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -1786,40 +1786,6 @@ struct bt_mesh_comp_p1_model_item *bt_mesh_comp_p1_item_pull( struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item( struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_ext_item *ext_item); -/** Composition data page 2 record parsing structure. */ -struct bt_mesh_comp_p2_record { - /** Mesh profile ID. */ - uint16_t id; - /** Mesh Profile Version. */ - struct { - /** Major version. */ - uint8_t x; - /** Minor version. */ - uint8_t y; - /** Z version. */ - uint8_t z; - } version; - /** Element offset buffer. */ - struct net_buf_simple *elem_buf; - /** Additional data buffer. */ - struct net_buf_simple *data_buf; -}; - -/** @brief Pull a Composition Data Page 2 Record from a composition data page 2 - * instance. - * - * Each call to this function will pull out a new element from the composition - * data page, until all elements have been pulled. - * - * @param buf Composition data page 2 buffer - * @param record Record to fill. - * - * @return A pointer to @c record on success, or NULL if no more elements could - * be pulled. - */ -struct bt_mesh_comp_p2_record *bt_mesh_comp_p2_record_pull(struct net_buf_simple *buf, - struct bt_mesh_comp_p2_record *record); - /** @brief Unpack a list of key index entries from a buffer. * * On success, @c dst_cnt is set to the amount of unpacked key index entries. diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 68af4fae59d..a5ad80193f3 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -2443,38 +2443,3 @@ struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item( } return ext_item; } - -struct bt_mesh_comp_p2_record *bt_mesh_comp_p2_record_pull(struct net_buf_simple *buf, - struct bt_mesh_comp_p2_record *record) -{ - if (buf->len < 8) { - LOG_DBG("No more elements to pull or missing data"); - return NULL; - } - - uint8_t elem_offset_cnt; - uint16_t data_len; - - record->id = net_buf_simple_pull_le16(buf); - record->version.x = net_buf_simple_pull_u8(buf); - record->version.y = net_buf_simple_pull_u8(buf); - record->version.z = net_buf_simple_pull_u8(buf); - elem_offset_cnt = net_buf_simple_pull_u8(buf); - if (buf->len < elem_offset_cnt + 2) { - LOG_WRN("Invalid composition data offset count"); - return NULL; - } - - net_buf_simple_init_with_data(record->elem_buf, - net_buf_simple_pull_mem(buf, elem_offset_cnt), - elem_offset_cnt); - data_len = net_buf_simple_pull_le16(buf); - if (buf->len < data_len) { - LOG_WRN("Invalid composition data additional data length"); - return NULL; - } - - net_buf_simple_init_with_data(record->data_buf, - net_buf_simple_pull_mem(buf, data_len), data_len); - return record; -} diff --git a/subsys/bluetooth/mesh/shell/cfg.c b/subsys/bluetooth/mesh/shell/cfg.c index c4a62a996e3..d47f04bcc00 100644 --- a/subsys/bluetooth/mesh/shell/cfg.c +++ b/subsys/bluetooth/mesh/shell/cfg.c @@ -98,10 +98,9 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[]) return 0; } - if (page != 0 && page != 128 && - ((page != 1 && page != 129) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) && - ((page != 2 && page != 130) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2))) { - shell_print(sh, "Got page %d. No parser available.", page); + if (page != 0 && page != 1 && page != 128 && page != 129) { + shell_print(sh, "Got page %d. No parser available.", + page); return 0; } @@ -255,41 +254,6 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[]) } } - if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { - /* size of 32 is chosen arbitrary, as sufficient for testing purposes */ - NET_BUF_SIMPLE_DEFINE(p2_elem_offset_buf, 32); - NET_BUF_SIMPLE_DEFINE(p2_data_buf, 32); - struct bt_mesh_comp_p2_record p2_elem = { - .elem_buf = &p2_elem_offset_buf, - .data_buf = &p2_data_buf - }; - - if (!buf.len) { - shell_error(sh, "Composition data empty"); - return 0; - } - shell_print(sh, "Got Composition Data for 0x%04x, page: %d:", - bt_mesh_shell_target_ctx.dst, page); - - while (bt_mesh_comp_p2_record_pull(&buf, &p2_elem)) { - - shell_print(sh, "\tMesh Profile id: %04x ", p2_elem.id); - shell_print(sh, "\t\tVersion: %d.%d.%d ", p2_elem.version.x, - p2_elem.version.y, p2_elem.version.z); - shell_print(sh, "\t\tElement offsets:"); - - while (p2_elem.elem_buf->len) { - shell_print(sh, "\t\t\t%d ", - net_buf_simple_pull_u8(p2_elem.elem_buf)); - } - - if (p2_elem.data_buf->len) { - shell_print(sh, "\t\t%d bytes of additional data is available", - p2_elem.data_buf->len); - } - } - } - if (buf.len) { shell_print(sh, "\t\t...truncated data!"); } From b3f7098d48a5d12db982a75b78777b1f72f88920 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:29 +0000 Subject: [PATCH 4304/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Support for comp data page 2" This reverts commit ced31ee9859ad299cf1a154124adef5bd9d25cda. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/mesh/access.h | 45 ------------------ subsys/bluetooth/mesh/Kconfig | 5 -- subsys/bluetooth/mesh/access.c | 66 +------------------------- subsys/bluetooth/mesh/access.h | 1 + subsys/bluetooth/mesh/cfg_srv.c | 8 +--- 5 files changed, 4 insertions(+), 121 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 5b1653c2487..f3b6c373128 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -1137,51 +1137,6 @@ struct bt_mesh_comp { struct bt_mesh_elem *elem; /**< List of elements. */ }; -/** Composition data page 2 record. */ -struct bt_mesh_comp2_record { - /** Mesh profile ID. */ - uint16_t id; - /** Mesh Profile Version. */ - struct { - /** Major version. */ - uint8_t x; - /** Minor version. */ - uint8_t y; - /** Z version. */ - uint8_t z; - } version; - /** Element offset count. */ - uint8_t elem_offset_cnt; - /** Element offset list. */ - const uint8_t *elem_offset; - /** Length of additional data. */ - uint16_t data_len; - /** Additional data. */ - const void *data; -}; - -/** Node Composition data page 2 */ -struct bt_mesh_comp2 { - /** The number of Mesh Profile records on a device. */ - size_t record_cnt; - /** List of records. */ - const struct bt_mesh_comp2_record *record; -}; - -/** @brief Register composition data page 2 of the device. - * - * Register Mesh Profiles information (Ref section 3.12 in - * Bluetooth SIG Assigned Numbers) for composition data - * page 2 of the device. - * - * @note There must be at least one record present in @c comp2 - * - * @param comp2 Pointer to composition data page 2. - * - * @return Zero on success or (negative) error code otherwise. - */ -int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2); - #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index b8e26309a28..9b0c4bd80f0 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1373,11 +1373,6 @@ config BT_MESH_COMP_PAGE_1 help Enable support for Composition Data Page 1. -config BT_MESH_COMP_PAGE_2 - bool "Support for Composition Data Page 2" - help - Enable support for Composition Data Page 2. - config BT_MESH_MODEL_EXTENSION_LIST_SIZE int "Model extensions list size" depends on BT_MESH_COMP_PAGE_1 diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index b6dab2d67a7..c022eedbadc 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -53,7 +53,6 @@ struct comp_foreach_model_arg { }; static const struct bt_mesh_comp *dev_comp; -static const struct bt_mesh_comp2 *dev_comp2; static uint16_t dev_primary_addr; static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); @@ -113,9 +112,6 @@ static const struct { #if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) { "bt/mesh/cmp/1", 1, }, #endif -#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) - { "bt/mesh/cmp/2", 2, }, -#endif }; void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, @@ -613,7 +609,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem) return temp_size; } -static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) +int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) { const struct bt_mesh_comp *comp; uint8_t cor_id = 0; @@ -664,51 +660,6 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf) return 0; } -static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf) -{ - if (!dev_comp2) { - LOG_ERR("Composition data P2 not registered"); - return -ENODEV; - } - - for (int i = 0; i < dev_comp2->record_cnt; i++) { - if (net_buf_simple_tailroom(buf) < - (8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len + - BT_MESH_MIC_SHORT)) { - if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) { - /* Mesh Profile 1.1 Section 4.4.1.2.2: - * If the complete list of models does not fit in the Data field, - * the element shall not be reported. - */ - LOG_DBG("Record 0x%04x didn't fit in the Data field", - i); - return 0; - } - - LOG_ERR("Too large device composition"); - return -E2BIG; - } - - net_buf_simple_add_le16(buf, dev_comp2->record[i].id); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.x); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.y); - net_buf_simple_add_u8(buf, dev_comp2->record[i].version.z); - net_buf_simple_add_u8(buf, dev_comp2->record[i].elem_offset_cnt); - if (dev_comp2->record[i].elem_offset_cnt) { - net_buf_simple_add_mem(buf, dev_comp2->record[i].elem_offset, - dev_comp2->record[i].elem_offset_cnt); - } - - net_buf_simple_add_le16(buf, dev_comp2->record[i].data_len); - if (dev_comp2->record[i].data_len) { - net_buf_simple_add_mem(buf, dev_comp2->record[i].data, - dev_comp2->record[i].data_len); - } - } - - return 0; -} - int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) { int32_t period; @@ -1043,17 +994,6 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) return err; } -int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2) -{ - if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - return -EINVAL; - } - - dev_comp2 = comp2; - - return 0; -} - void bt_mesh_comp_provision(uint16_t addr) { int i; @@ -2211,10 +2151,8 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o { if (page == 0 || page == 128) { return bt_mesh_comp_data_get_page_0(buf, offset); - } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) { + } else if (page == 1 || page == 129) { return bt_mesh_comp_data_get_page_1(buf); - } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) { - return bt_mesh_comp_data_get_page_2(buf); } return -EINVAL; diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 4740963dd21..a7d3ffe5865 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -27,6 +27,7 @@ size_t bt_mesh_comp_page_0_size(void); int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset); size_t bt_mesh_metadata_page_0_size(void); int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset); +int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf); /* Find local element based on unicast address */ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index eb732a34910..2fba9360206 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -61,19 +61,13 @@ static int dev_comp_data_get(struct bt_mesh_model *model, page = net_buf_simple_pull_u8(buf); - if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && - (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || - IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { - page = 130U; - } else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && + if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { page = 129U; } else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { page = 128U; - } else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) { - page = 2U; } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { page = 1U; } else if (page != 0U) { From ac7ba6d459c268aafa5383187e45d85dc3bfcfde Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:29 +0000 Subject: [PATCH 4305/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Send od priv proxy with devkey" This reverts commit 915c64c22fc212ef2f5b25e62682179159ce97c5. Signed-off-by: Dominik Ermel --- include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h | 11 +++++------ subsys/bluetooth/mesh/od_priv_proxy_cli.c | 12 +++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h index f9734d78d3e..89e63c177a0 100644 --- a/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h +++ b/include/zephyr/bluetooth/mesh/od_priv_proxy_cli.h @@ -47,6 +47,7 @@ struct bt_mesh_od_priv_proxy_cli { _bt_mesh_od_priv_proxy_cli_op, NULL, cli_data, \ &_bt_mesh_od_priv_proxy_cli_cb) + /** @brief Get the target's On-Demand Private GATT Proxy state. * * This method can be used asynchronously by setting @p val_rsp as NULL. @@ -56,13 +57,12 @@ struct bt_mesh_od_priv_proxy_cli { * To process the response arguments of an async method, register * the @c od_status callback in @c bt_mesh_od_priv_proxy_cli struct. * - * @param net_idx Network index to encrypt with. - * @param addr Target node address. + * @param ctx Message context for the message. * @param val_rsp Response buffer for On-Demand Private GATT Proxy value. * * @return 0 on success, or (negative) error code otherwise. */ -int bt_mesh_od_priv_proxy_cli_get(uint16_t net_idx, uint16_t addr, uint8_t *val_rsp); +int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val_rsp); /** @brief Set the target's On-Demand Private GATT Proxy state. * @@ -73,14 +73,13 @@ int bt_mesh_od_priv_proxy_cli_get(uint16_t net_idx, uint16_t addr, uint8_t *val_ * To process the response arguments of an async method, register * the @c od_status callback in @c bt_mesh_od_priv_proxy_cli struct. * - * @param net_idx Network index to encrypt with. - * @param addr Target node address. + * @param ctx Message context for the message. * @param val On-Demand Private GATT Proxy state to be set * @param val_rsp Response buffer for On-Demand Private GATT Proxy value. * * @return 0 on success, or (negative) error code otherwise. */ -int bt_mesh_od_priv_proxy_cli_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *val_rsp); +int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint8_t *val_rsp); /** @brief Set the transmission timeout value. * diff --git a/subsys/bluetooth/mesh/od_priv_proxy_cli.c b/subsys/bluetooth/mesh/od_priv_proxy_cli.c index 67f5ac961ad..3dc8722ff72 100644 --- a/subsys/bluetooth/mesh/od_priv_proxy_cli.c +++ b/subsys/bluetooth/mesh/od_priv_proxy_cli.c @@ -54,25 +54,23 @@ const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_cli_op[] = { BT_MESH_MODEL_OP_END }; -int bt_mesh_od_priv_proxy_cli_get(uint16_t net_idx, uint16_t addr, uint8_t *val_rsp) +int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val) { - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp = { .ack = &cli->ack_ctx, .op = OP_OD_PRIV_PROXY_STATUS, - .user_data = val_rsp, + .user_data = val, .timeout = msg_timeout, }; BT_MESH_MODEL_BUF_DEFINE(msg, OP_OD_PRIV_PROXY_GET, 0); bt_mesh_model_msg_init(&msg, OP_OD_PRIV_PROXY_GET); - return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, val_rsp ? &rsp : NULL); + return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val ? &rsp : NULL); } -int bt_mesh_od_priv_proxy_cli_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *val_rsp) +int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint8_t *val_rsp) { - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); const struct bt_mesh_msg_rsp_ctx rsp = { .ack = &cli->ack_ctx, .op = OP_OD_PRIV_PROXY_STATUS, @@ -85,7 +83,7 @@ int bt_mesh_od_priv_proxy_cli_set(uint16_t net_idx, uint16_t addr, uint8_t val, net_buf_simple_add_u8(&msg, val); - return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, val_rsp ? &rsp : NULL); + return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val_rsp ? &rsp : NULL); } void bt_mesh_od_priv_proxy_cli_timeout_set(int32_t timeout) From 831ae0e2a84194dee0e81f73a5d66209c81e0fdf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:29 +0000 Subject: [PATCH 4306/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Solicitation RPL PDU Server compilation" This reverts commit 4d987d3dcba621380f6714dd2cfa405dc78ad6fa. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/solicitation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index 1bf9f9a465a..3f639fbf0d6 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -153,12 +153,12 @@ static bool sol_pdu_decrypt(struct bt_mesh_subnet *sub, void *data) net_buf_simple_init(out, 0); net_buf_simple_add_mem(out, in->data, in->len); - err = bt_mesh_net_obfuscate(out->data, 0, &sub->keys[i].msg.privacy); + err = bt_mesh_net_obfuscate(out->data, 0, sub->keys[i].msg.privacy); if (err) { LOG_DBG("obfuscation err %d", err); continue; } - err = bt_mesh_net_decrypt(&sub->keys[i].msg.enc, out, + err = bt_mesh_net_decrypt(sub->keys[i].msg.enc, out, 0, BT_MESH_NONCE_SOLICITATION); if (!err) { LOG_DBG("Decrypted PDU %s", bt_hex(out->data, out->len)); From b11cd9257aa23884b6f83593e6b00b778e523373 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:30 +0000 Subject: [PATCH 4307/4498] Revert "[nrf fromtree] Bluetooth: Mesh: Fix Opcode Aggregator Server compilation" This reverts commit 079d1b105a61c46f7a8ffea881de673092a44b65. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/op_agg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/bluetooth/mesh/op_agg.c b/subsys/bluetooth/mesh/op_agg.c index 1580c7f0847..4f6baacc898 100644 --- a/subsys/bluetooth/mesh/op_agg.c +++ b/subsys/bluetooth/mesh/op_agg.c @@ -17,7 +17,10 @@ LOG_MODULE_REGISTER(bt_mesh_op_agg); #define LENGTH_SHORT_MAX BIT_MASK(7) NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX); + +#if IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX); +#endif static struct op_agg_ctx agg_ctx = { .sdu = &sdu, From c0e800a8ebde16448395f30cf521c3f8156bbf0e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:31 +0000 Subject: [PATCH 4308/4498] Revert "[nrf fromtree] Bluetooth: att: don't re-use the ATT buffer for confirmations" This reverts commit 577db5cae9568f33fb5a1bb3fc6ab1a4725813f7. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/att.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index f5ae3768cec..d2c41eaa928 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -670,12 +670,10 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t switch (att_op_get_type(op)) { case ATT_RESPONSE: - /* Use a timeout only when responding */ - timeout = BT_ATT_TIMEOUT; - re_use = true; - break; case ATT_CONFIRMATION: + /* Use a timeout only when responding/confirming */ timeout = BT_ATT_TIMEOUT; + re_use = true; break; default: timeout = K_FOREVER; @@ -703,7 +701,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t * This is better than an assert as an assert would * allow a peer to DoS us. */ - LOG_ERR("already processing a REQ/RSP on chan %p", chan); + LOG_ERR("already processing a transaction on chan %p", chan); return NULL; } From ae3b2bf29783da3ac45691f113c7e515e2f42827 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:31 +0000 Subject: [PATCH 4309/4498] Revert "[nrf fromtree] net: dhcpv6: Fix params check" This reverts commit 3c8028b93d9392629b9b5a123850d1ddea6b66a3. Signed-off-by: Dominik Ermel --- subsys/net/ip/dhcpv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index fdfef3c5147..6fae4f320bf 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -2100,7 +2100,7 @@ void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) goto out; } - if (!params->request_addr && !params->request_prefix) { + if (!params->request_addr && !params->request_addr) { NET_ERR("Information Request not supported yet"); goto out; } From b56fe82ca25874726e384cc58eb71b8dc4d93e68 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:31 +0000 Subject: [PATCH 4310/4498] Revert "[nrf fromtree] net: shell: Add DHCPv6 support" This reverts commit 0258a9960c452a3e0f69004ed421a8838108ad9c. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_shell.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index e7af6e16632..c5b07afd6aa 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -719,19 +719,6 @@ static void iface_cb(struct net_if *iface, void *user_data) iface->config.dhcpv4.attempts); #endif /* CONFIG_NET_DHCPV4 */ -#if defined(CONFIG_NET_DHCPV6) - PR("DHCPv6 address requested : %s\n", - iface->config.dhcpv6.params.request_addr ? - net_sprint_ipv6_addr(&iface->config.dhcpv6.addr) : "none"); - PR("DHCPv6 prefix requested : %s\n", - iface->config.dhcpv6.params.request_prefix ? - net_sprint_ipv6_addr(&iface->config.dhcpv6.prefix) : "none"); - PR("DHCPv6 state : %s\n", - net_dhcpv6_state_name(iface->config.dhcpv6.state)); - PR("DHCPv6 attempts : %d\n", - iface->config.dhcpv6.retransmissions + 1); -#endif /* CONFIG_NET_DHCPV6 */ - #else ARG_UNUSED(iface); ARG_UNUSED(user_data); @@ -2526,29 +2513,6 @@ static char *get_l3_desc(struct event_msg *msg, info = net_addr_ntop(AF_INET6, msg->data, extra_info, extra_info_len); break; - case NET_EVENT_IPV6_DHCP_START: - *desc = "DHCPv6"; - *desc2 = "start"; - break; - case NET_EVENT_IPV6_DHCP_BOUND: - *desc = "DHCPv6"; - *desc2 = "bound"; -#if defined(CONFIG_NET_DHCPV6) - struct net_if_dhcpv6 *data = (struct net_if_dhcpv6 *)msg->data; - - if (data->params.request_addr) { - info = net_addr_ntop(AF_INET6, &data->addr, extra_info, - extra_info_len); - } else if (data->params.request_prefix) { - info = net_addr_ntop(AF_INET6, &data->prefix, extra_info, - extra_info_len); - } -#endif - break; - case NET_EVENT_IPV6_DHCP_STOP: - *desc = "DHCPv6"; - *desc2 = "stop"; - break; case NET_EVENT_IPV4_ADDR_ADD: *desc = "IPv4 address"; *desc2 = "add"; From 3704f2bbbb4549dfd103cf1d2b35b7284ee448a6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:32 +0000 Subject: [PATCH 4311/4498] Revert "[nrf fromtree] net: config: Add DHCPv6 support" This reverts commit 7b858ff1a5bb1cd919249412bdb1c8be3f7424d9. Signed-off-by: Dominik Ermel --- subsys/net/lib/config/Kconfig | 17 ------------- subsys/net/lib/config/init.c | 46 ++++------------------------------- 2 files changed, 5 insertions(+), 58 deletions(-) diff --git a/subsys/net/lib/config/Kconfig b/subsys/net/lib/config/Kconfig index 5ca788cebf1..0f1e3c50544 100644 --- a/subsys/net/lib/config/Kconfig +++ b/subsys/net/lib/config/Kconfig @@ -188,23 +188,6 @@ config NET_CONFIG_BT_NODE endif # NET_CONFIG_SETTINGS -if NET_DHCPV6 - -config NET_CONFIG_DHCPV6_REQUEST_ADDR - bool "Request IPv6 address when configuring DHCPv6 client" - default y - help - When DHCPv6 is enabled this will configure the DHCPv6 client to - request IPv6 address from the DHCPv6 server. - -config NET_CONFIG_DHCPV6_REQUEST_PREFIX - bool "Request IPv6 prefix when configuring DHCPv6 client" - help - When DHCPv6 is enabled this will configure the DHCPv6 client to - request IPv6 prefix from the DHCPv6 server. - -endif # NET_DHCPV6 - config NET_CONFIG_CLOCK_SNTP_INIT bool "Initialize system clock using SNTP on application startup" depends on SNTP && POSIX_CLOCK diff --git a/subsys/net/lib/config/init.c b/subsys/net/lib/config/init.c index 098003b79b3..cd2bf711a7d 100644 --- a/subsys/net/lib/config/init.c +++ b/subsys/net/lib/config/init.c @@ -21,7 +21,6 @@ LOG_MODULE_REGISTER(net_config, CONFIG_NET_CONFIG_LOG_LEVEL); #include #include #include -#include #include #include @@ -204,26 +203,8 @@ static void setup_ipv4(struct net_if *iface) #endif /* CONFIG_NET_IPV4 && !CONFIG_NET_DHCPV4 */ #if defined(CONFIG_NET_NATIVE_IPV6) - -#if defined(CONFIG_NET_DHCPV6) -static void setup_dhcpv6(struct net_if *iface) -{ - struct net_dhcpv6_params params = { - .request_addr = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR), - .request_prefix = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_PREFIX), - }; - - NET_INFO("Running dhcpv6 client..."); - - net_dhcpv6_start(iface, ¶ms); -} -#else /* CONFIG_NET_DHCPV6 */ -#define setup_dhcpv6(...) -#endif /* CONFIG_NET_DHCPV6 */ - -#if !defined(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR) && \ - !defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR) -#error "You need to define an IPv6 address or enable DHCPv6!" +#if !defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR) +#error "You need to define an IPv6 address!" #endif static struct net_mgmt_event_callback mgmt6_cb; @@ -268,21 +249,6 @@ static void ipv6_event_handler(struct net_mgmt_event_callback *cb, #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF NET_INFO("IPv6 address: %s", net_addr_ntop(AF_INET6, &laddr, hr_addr, NET_IPV6_ADDR_LEN)); - - if (ifaddr->addr_type == NET_ADDR_DHCP) { - char remaining_str[] = "infinite"; - uint32_t remaining; - - remaining = net_timeout_remaining(&ifaddr->lifetime, - k_uptime_get_32()); - - if (!ifaddr->is_infinite) { - snprintk(remaining_str, sizeof(remaining_str), - "%u", remaining); - } - - NET_INFO("Lifetime: %s seconds", remaining_str); - } #endif services_notify_ready(NET_CONFIG_NEED_IPV6); @@ -298,9 +264,6 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) struct net_if_addr *ifaddr; uint32_t mask = NET_EVENT_IPV6_DAD_SUCCEED; - net_mgmt_init_event_callback(&mgmt6_cb, ipv6_event_handler, mask); - net_mgmt_add_event_callback(&mgmt6_cb); - if (sizeof(CONFIG_NET_CONFIG_MY_IPV6_ADDR) == 1) { /* Empty address, skip setting ANY address in this case */ goto exit; @@ -316,6 +279,9 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) mask |= NET_EVENT_IPV6_ROUTER_ADD; } + net_mgmt_init_event_callback(&mgmt6_cb, ipv6_event_handler, mask); + net_mgmt_add_event_callback(&mgmt6_cb); + /* * check for CMD_ADDR_ADD bit here, NET_EVENT_IPV6_ADDR_ADD is * a combination of _NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_ADDR_ADD @@ -344,7 +310,6 @@ static void setup_ipv6(struct net_if *iface, uint32_t flags) #else #define setup_ipv6(...) -#define setup_dhcpv6(...) #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_NATIVE) @@ -435,7 +400,6 @@ int net_config_init_by_iface(struct net_if *iface, const char *app_info, setup_ipv4(iface); setup_dhcpv4(iface); setup_ipv6(iface, flags); - setup_dhcpv6(iface); /* Network interface did not come up. */ if (timeout > 0 && count < 0) { From 0d5839b825d036ed282f1edd1ddbbed0a068f5ff Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:32 +0000 Subject: [PATCH 4312/4498] Revert "[nrf fromtree] net: dhcpv6: Introduce net events for DHCPv6" This reverts commit 542166fc77cf4c9d8eb90bdfcb27984b17668017. Signed-off-by: Dominik Ermel --- include/zephyr/net/net_event.h | 12 ------------ subsys/net/ip/dhcpv6.c | 8 -------- subsys/net/ip/net_private.h | 3 --- 3 files changed, 23 deletions(-) diff --git a/include/zephyr/net/net_event.h b/include/zephyr/net/net_event.h index 34856aec6af..819a5ae6639 100644 --- a/include/zephyr/net/net_event.h +++ b/include/zephyr/net/net_event.h @@ -79,9 +79,6 @@ enum net_event_ipv6_cmd { NET_EVENT_IPV6_CMD_DAD_FAILED, NET_EVENT_IPV6_CMD_NBR_ADD, NET_EVENT_IPV6_CMD_NBR_DEL, - NET_EVENT_IPV6_CMD_DHCP_START, - NET_EVENT_IPV6_CMD_DHCP_BOUND, - NET_EVENT_IPV6_CMD_DHCP_STOP, }; #define NET_EVENT_IPV6_ADDR_ADD \ @@ -132,15 +129,6 @@ enum net_event_ipv6_cmd { #define NET_EVENT_IPV6_NBR_DEL \ (_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_NBR_DEL) -#define NET_EVENT_IPV6_DHCP_START \ - (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_START) - -#define NET_EVENT_IPV6_DHCP_BOUND \ - (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_BOUND) - -#define NET_EVENT_IPV6_DHCP_STOP \ - (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV6_CMD_DHCP_STOP) - /* IPv4 Events*/ #define _NET_IPV4_LAYER NET_MGMT_LAYER_L3 #define _NET_IPV4_CORE_CODE 0x004 diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c index 6fae4f320bf..040c9fa0e06 100644 --- a/subsys/net/ip/dhcpv6.c +++ b/subsys/net/ip/dhcpv6.c @@ -1374,10 +1374,6 @@ static void dhcpv6_enter_confirming(struct net_if *iface) static void dhcpv6_enter_bound(struct net_if *iface) { iface->config.dhcpv6.timeout = iface->config.dhcpv6.t1; - - net_mgmt_event_notify_with_info(NET_EVENT_IPV6_DHCP_BOUND, iface, - &iface->config.dhcpv6, - sizeof(iface->config.dhcpv6)); } static void dhcpv6_enter_state(struct net_if *iface, enum net_dhcpv6_state state) @@ -2105,8 +2101,6 @@ void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) goto out; } - net_mgmt_event_notify(NET_EVENT_IPV6_DHCP_START, iface); - NET_DBG("Starting DHCPv6 on iface %p", iface); iface->config.dhcpv6.params = *params; @@ -2166,8 +2160,6 @@ void net_dhcpv6_stop(struct net_if *iface) break; } - net_mgmt_event_notify(NET_EVENT_IPV6_DHCP_STOP, iface); - k_mutex_unlock(&lock); } diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index c2b80aa4f05..be0466fc98b 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -30,9 +30,6 @@ union net_mgmt_events { #if defined(CONFIG_NET_DHCPV4) struct net_if_dhcpv4 dhcpv4; #endif /* CONFIG_NET_DHCPV4 */ -#if defined(CONFIG_NET_DHCPV6) - struct net_if_dhcpv6 dhcpv6; -#endif /* CONFIG_NET_DHCPV6 */ #if defined(CONFIG_NET_L2_WIFI_MGMT) union wifi_mgmt_events wifi; #endif /* CONFIG_NET_L2_WIFI_MGMT */ From 91a77c98c986b7a1af1511989a78c61004224d72 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:32 +0000 Subject: [PATCH 4313/4498] Revert "[nrf fromtree] net: dhcpv6: Add Zephyr DHCPv6 client" This reverts commit 04cd082a7d7b34ee66b07682e158ccbfafd93d8f. Signed-off-by: Dominik Ermel --- include/zephyr/net/dhcpv6.h | 116 -- include/zephyr/net/net_if.h | 70 - subsys/net/ip/CMakeLists.txt | 1 - subsys/net/ip/Kconfig.ipv6 | 14 - subsys/net/ip/dhcpv6.c | 2196 ------------------------------- subsys/net/ip/dhcpv6_internal.h | 196 --- subsys/net/ip/net_core.c | 6 - 7 files changed, 2599 deletions(-) delete mode 100644 include/zephyr/net/dhcpv6.h delete mode 100644 subsys/net/ip/dhcpv6.c delete mode 100644 subsys/net/ip/dhcpv6_internal.h diff --git a/include/zephyr/net/dhcpv6.h b/include/zephyr/net/dhcpv6.h deleted file mode 100644 index 95b59f530b5..00000000000 --- a/include/zephyr/net/dhcpv6.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief DHCPv6 client - */ - -#ifndef ZEPHYR_INCLUDE_NET_DHCPV6_H_ -#define ZEPHYR_INCLUDE_NET_DHCPV6_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief DHCPv6 - * @defgroup dhcpv6 DHCPv6 - * @ingroup networking - * @{ - */ - -/** @cond INTERNAL_HIDDEN */ - -/** Current state of DHCPv6 client address/prefix negotiation. */ -enum net_dhcpv6_state { - NET_DHCPV6_DISABLED, - NET_DHCPV6_INIT, - NET_DHCPV6_SOLICITING, - NET_DHCPV6_REQUESTING, - NET_DHCPV6_CONFIRMING, - NET_DHCPV6_RENEWING, - NET_DHCPV6_REBINDING, - NET_DHCPV6_INFO_REQUESTING, - NET_DHCPV6_BOUND, -} __packed; - -#define DHCPV6_TID_SIZE 3 -#define DHCPV6_DUID_MAX_SIZE 20 - -struct net_dhcpv6_duid_raw { - uint16_t type; - uint8_t buf[DHCPV6_DUID_MAX_SIZE]; -} __packed; - -struct net_dhcpv6_duid_storage { - struct net_dhcpv6_duid_raw duid; - uint8_t length; -}; - -struct net_if; - -/** @endcond */ - -/** @brief DHCPv6 client configuration parameters. */ -struct net_dhcpv6_params { - bool request_addr : 1; /**< Request IPv6 address. */ - bool request_prefix : 1; /**< Request IPv6 prefix. */ -}; - -/** - * @brief Start DHCPv6 client on an iface - * - * @details Start DHCPv6 client on a given interface. DHCPv6 client will start - * negotiation for IPv6 address and/or prefix, depending on the configuration. - * Once the negotiation is complete, IPv6 address/prefix details will be added - * to the interface. - * - * @param iface A valid pointer to a network interface - * @param params DHCPv6 client configuration parameters. - */ -void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params); - -/** - * @brief Stop DHCPv6 client on an iface - * - * @details Stop DHCPv6 client on a given interface. DHCPv6 client - * will remove all configuration obtained from a DHCP server from the - * interface and stop any further negotiation with the server. - * - * @param iface A valid pointer to a network interface - */ -void net_dhcpv6_stop(struct net_if *iface); - -/** - * @brief Restart DHCPv6 client on an iface - * - * @details Restart DHCPv6 client on a given interface. DHCPv6 client - * will restart the state machine without any of the initial delays. - * - * @param iface A valid pointer to a network interface - */ -void net_dhcpv6_restart(struct net_if *iface); - -/** @cond INTERNAL_HIDDEN */ - -/** - * @brief DHCPv6 state name - * - * @internal - */ -const char *net_dhcpv6_state_name(enum net_dhcpv6_state state); - -/** @endcond */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_NET_DHCPV6_H_ */ diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index b06bf74de03..cced3557b84 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -33,9 +33,6 @@ #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4) #include #endif -#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) -#include -#endif #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4) #include #endif @@ -278,69 +275,6 @@ struct net_if_ipv6 { uint8_t hop_limit; }; -#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) -struct net_if_dhcpv6 { - /** Used for timer list. */ - sys_snode_t node; - - /** Generated Client ID. */ - struct net_dhcpv6_duid_storage clientid; - - /** Server ID of the selected server. */ - struct net_dhcpv6_duid_storage serverid; - - /** DHCPv6 client state. */ - enum net_dhcpv6_state state; - - /** DHCPv6 client configuration parameters. */ - struct net_dhcpv6_params params; - - /** Timeout for the next event, absolute time, milliseconds. */ - uint64_t timeout; - - /** Time of the current exchange start, absolute time, milliseconds */ - uint64_t exchange_start; - - /** Renewal time, absolute time, milliseconds. */ - uint64_t t1; - - /** Rebinding time, absolute time, milliseconds. */ - uint64_t t2; - - /** The time when the last lease expires (terminates rebinding, - * DHCPv6 RFC8415, ch. 18.2.5). Absolute time, milliseconds. - */ - uint64_t expire; - - /** Generated IAID for IA_NA. */ - uint32_t addr_iaid; - - /** Generated IAID for IA_PD. */ - uint32_t prefix_iaid; - - /** Retransmit timeout for the current message, milliseconds. */ - uint32_t retransmit_timeout; - - /** Current best server preference received. */ - int16_t server_preference; - - /** Retransmission counter. */ - uint8_t retransmissions; - - /** Transaction ID for current exchange. */ - uint8_t tid[DHCPV6_TID_SIZE]; - - /** Prefix length. */ - uint8_t prefix_len; - - /** Assigned IPv6 prefix. */ - struct in6_addr prefix; - - /** Assigned IPv6 address. */ - struct in6_addr addr; -}; -#endif /* defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) */ - /** @cond INTERNAL_HIDDEN */ #if defined(CONFIG_NET_NATIVE_IPV4) #define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT @@ -479,10 +413,6 @@ struct net_if_config { struct net_if_dhcpv4 dhcpv4; #endif /* CONFIG_NET_DHCPV4 */ -#if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) - struct net_if_dhcpv6 dhcpv6; -#endif /* CONFIG_NET_DHCPV6 */ - #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4) struct net_if_ipv4_autoconf ipv4auto; #endif /* CONFIG_NET_IPV4_AUTO */ diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index 7dc54935c5c..70655e2f61c 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -31,7 +31,6 @@ zephyr_library_sources(net_tc.c) zephyr_library_sources_ifdef(CONFIG_NET_IP connection.c) zephyr_library_sources_ifdef(CONFIG_NET_6LO 6lo.c) zephyr_library_sources_ifdef(CONFIG_NET_DHCPV4 dhcpv4.c) -zephyr_library_sources_ifdef(CONFIG_NET_DHCPV6 dhcpv6.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4_AUTO ipv4_autoconf.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4 icmpv4.c ipv4.c) zephyr_library_sources_ifdef(CONFIG_NET_IPV4_IGMP igmp.c) diff --git a/subsys/net/ip/Kconfig.ipv6 b/subsys/net/ip/Kconfig.ipv6 index 18fb4b0ccc4..b776d3756eb 100644 --- a/subsys/net/ip/Kconfig.ipv6 +++ b/subsys/net/ip/Kconfig.ipv6 @@ -166,12 +166,6 @@ config NET_MAX_6LO_CONTEXTS 6lowpan context options table size. The value depends on your network and memory consumption. More 6CO options uses more memory. -config NET_DHCPV6 - bool "DHCPv6 client" - select NET_MGMT - select NET_MGMT_EVENT - depends on NET_UDP - if NET_6LO module = NET_6LO module-dep = NET_LOG @@ -198,13 +192,5 @@ module-str = Log level for IPv6 neighbor cache module-help = Enables IPv6 Neighbor Cache code to output debug messages. source "subsys/net/Kconfig.template.log_config.net" -if NET_DHCPV6 -module = NET_DHCPV6 -module-dep = NET_LOG -module-str = Log level for DHCPv6 client -module-help = Enables DHCPv6 client code to output debug messages. -source "subsys/net/Kconfig.template.log_config.net" -endif # NET_DHCPV6 - endif # NET_NATIVE_IPV6 endif # NET_IPV6 diff --git a/subsys/net/ip/dhcpv6.c b/subsys/net/ip/dhcpv6.c deleted file mode 100644 index 040c9fa0e06..00000000000 --- a/subsys/net/ip/dhcpv6.c +++ /dev/null @@ -1,2196 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief DHCPv6 client implementation - */ - -#include -LOG_MODULE_REGISTER(net_dhcpv6, CONFIG_NET_DHCPV6_LOG_LEVEL); - -#include -#include -#include -#include - -#include "dhcpv6_internal.h" -#include "ipv6.h" -#include "net_private.h" -#include "udp_internal.h" - -/* Maximum number of options client can request. */ -#define DHCPV6_MAX_OPTION_REQUEST 2 - -struct dhcpv6_options_include { - bool clientid : 1; - bool serverid : 1; - bool elapsed_time : 1; - bool ia_na : 1; - bool iaaddr : 1; - bool ia_pd : 1; - bool iaprefix : 1; - uint16_t oro[DHCPV6_MAX_OPTION_REQUEST]; -}; - -static K_MUTEX_DEFINE(lock); - -/* All_DHCP_Relay_Agents_and_Servers (ff02::1:2) */ -static const struct in6_addr all_dhcpv6_ra_and_servers = { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x01, 0, 0x02 } } }; - -static sys_slist_t dhcpv6_ifaces = SYS_SLIST_STATIC_INIT(&dhcpv6_ifaces); -static struct k_work_delayable dhcpv6_timeout_work; -static struct net_mgmt_event_callback dhcpv6_mgmt_cb; - -const char *net_dhcpv6_state_name(enum net_dhcpv6_state state) -{ - static const char * const name[] = { - "disabled", - "init", - "soliciting", - "requesting", - "confirming", - "renewing", - "rebinding", - "information requesting", - "bound", - }; - - __ASSERT_NO_MSG(state >= 0 && state < sizeof(name)); - return name[state]; -} - -static void dhcpv6_generate_tid(struct net_if *iface) -{ - sys_rand_get(iface->config.dhcpv6.tid, sizeof(iface->config.dhcpv6.tid)); -} - -static void dhcvp6_update_deadlines(struct net_if *iface, int64_t now, - uint32_t t1, uint32_t t2, - uint32_t preferred_lifetime, - uint32_t valid_lifetime) -{ - uint64_t t1_abs, t2_abs, expire_abs; - - /* In case server does not set T1/T2 values, the time choice is left to - * the client discretion. - * Here, we use recommendations for the servers, where it's advised to - * set T1/T2 as 0.5 and 0.8 of the preferred lifetime. - */ - if (t1 == 0 && t2 == 0) { - if (preferred_lifetime == DHCPV6_INFINITY) { - t1 = DHCPV6_INFINITY; - t2 = DHCPV6_INFINITY; - } else { - t1 = preferred_lifetime * 0.5; - t2 = preferred_lifetime * 0.8; - } - } else if (t1 == 0) { - if (t2 == DHCPV6_INFINITY) { - t1 = DHCPV6_INFINITY; - } else { - t1 = t2 * 0.625; /* 0.5 / 0.8 */ - } - } else if (t2 == 0) { - if (t1 == DHCPV6_INFINITY) { - t2 = DHCPV6_INFINITY; - } else { - t2 = t1 * 1.6; /* 0.8 / 0.5 */ - /* Overflow check. */ - if (t2 < t1) { - t2 = DHCPV6_INFINITY; - } - } - } else if (t1 >= t2) { - NET_ERR("Invalid T1(%u)/T2(%u) values.", t1, t2); - return; - } - - if (t1 == DHCPV6_INFINITY || - u64_add_overflow(now, 1000ULL * t1, &t1_abs)) { - t1_abs = UINT64_MAX; - } - - if (t2 == DHCPV6_INFINITY || - u64_add_overflow(now, 1000ULL * t2, &t2_abs)) { - t2_abs = UINT64_MAX; - } - - if (valid_lifetime == DHCPV6_INFINITY || - u64_add_overflow(now, 1000ULL * valid_lifetime, &expire_abs)) { - expire_abs = UINT64_MAX; - } - - if (iface->config.dhcpv6.t1 > t1_abs) { - iface->config.dhcpv6.t1 = t1_abs; - } - - if (iface->config.dhcpv6.t2 > t2_abs) { - iface->config.dhcpv6.t2 = t2_abs; - } - - if (iface->config.dhcpv6.expire < expire_abs) { - iface->config.dhcpv6.expire = expire_abs; - } -} - -static void dhcpv6_set_timeout(struct net_if *iface, uint64_t timeout) -{ - int64_t now = k_uptime_get(); - - NET_DBG("sched dhcpv6 timeout iface=%p timeout=%llums", iface, timeout); - - if (u64_add_overflow(now, timeout, &iface->config.dhcpv6.timeout)) { - iface->config.dhcpv6.timeout = UINT64_MAX; - } -} - -static void dhcpv6_reschedule(void) -{ - k_work_reschedule(&dhcpv6_timeout_work, K_NO_WAIT); -} - -static int randomize_timeout(int multiplier, int timeout) -{ - int factor; - - /* DHCPv6 RFC8415, ch. 15. the randomization factor should be a random - * number between -0.1 nand +0.1. As we operate on integers here, we - * scale it to -100 and +100, and divide the result by 1000. - */ - factor = (int)(sys_rand32_get() % 201) - 100; - - return (multiplier * timeout) + ((factor * timeout) / 1000); -} - -static int dhcpv6_initial_retransmit_time(int init_retransmit_time) -{ - /* DHCPv6 RFC8415, ch. 15. Retransmission time for the first msg. */ - return randomize_timeout(1, init_retransmit_time); -} - -static uint32_t dhcpv6_next_retransmit_time(int prev_retransmit_time, - int max_retransmit_time) -{ - int retransmit_time; - - /* DHCPv6 RFC8415, ch. 15. Retransmission time for the subsequent msg. */ - retransmit_time = randomize_timeout(2, prev_retransmit_time); - - if (max_retransmit_time == 0) { - return retransmit_time; - } - - if (retransmit_time > max_retransmit_time) { - retransmit_time = randomize_timeout(1, max_retransmit_time); - } - - return retransmit_time; -} - -/* DHCPv6 packet encoding functions */ - -static int dhcpv6_add_header(struct net_pkt *pkt, enum dhcpv6_msg_type type, - uint8_t *tid) -{ - int ret; - - ret = net_pkt_write_u8(pkt, type); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write(pkt, tid, DHCPV6_TID_SIZE); - - return ret; -} - -static int dhcpv6_add_option_header(struct net_pkt *pkt, - enum dhcpv6_option_code code, - uint16_t length) -{ - int ret; - - ret = net_pkt_write_be16(pkt, code); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be16(pkt, length); - - return ret; -} - -static int dhcpv6_add_option_clientid(struct net_pkt *pkt, - struct net_dhcpv6_duid_storage *clientid) -{ - int ret; - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_CLIENTID, - clientid->length); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write(pkt, &clientid->duid, clientid->length); - - return ret; -} - -static int dhcpv6_add_option_serverid(struct net_pkt *pkt, - struct net_dhcpv6_duid_storage *serverid) -{ - int ret; - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_SERVERID, - serverid->length); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write(pkt, &serverid->duid, serverid->length); - - return ret; -} - - -static int dhcpv6_add_option_elapsed_time(struct net_pkt *pkt, uint64_t since) -{ - uint64_t elapsed; - int ret; - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_ELAPSED_TIME, - DHCPV6_OPTION_ELAPSED_TIME_SIZE); - if (ret < 0) { - return ret; - } - - /* Elapsed time should be expressed in hundredths of a second. */ - elapsed = (k_uptime_get() - since) / 10ULL; - if (elapsed > 0xFFFF) { - elapsed = 0xFFFF; - } - - ret = net_pkt_write_be16(pkt, (uint16_t)elapsed); - - return ret; -} - -static int dhcpv6_add_option_ia_na(struct net_pkt *pkt, struct dhcpv6_ia_na *ia_na, - bool include_addr) -{ - uint16_t optlen; - int ret; - - if (!include_addr) { - optlen = DHCPV6_OPTION_IA_NA_HEADER_SIZE; - } else { - optlen = DHCPV6_OPTION_IA_NA_HEADER_SIZE + - DHCPV6_OPTION_HEADER_SIZE + - DHCPV6_OPTION_IAADDR_HEADER_SIZE; - } - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IA_NA, optlen); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_na->iaid); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_na->t1); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_na->t2); - if (ret < 0) { - return ret; - } - - if (!include_addr) { - return 0; - } - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IAADDR, - DHCPV6_OPTION_IAADDR_HEADER_SIZE); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write(pkt, &ia_na->iaaddr.addr, sizeof(ia_na->iaaddr.addr)); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_na->iaaddr.preferred_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_na->iaaddr.valid_lifetime); - - return ret; -} - -static int dhcpv6_add_option_ia_pd(struct net_pkt *pkt, struct dhcpv6_ia_pd *ia_pd, - bool include_prefix) -{ - uint16_t optlen; - int ret; - - if (!include_prefix) { - optlen = DHCPV6_OPTION_IA_PD_HEADER_SIZE; - } else { - optlen = DHCPV6_OPTION_IA_PD_HEADER_SIZE + - DHCPV6_OPTION_HEADER_SIZE + - DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; - } - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IA_PD, - optlen); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_pd->iaid); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_pd->t1); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_pd->t2); - if (ret < 0) { - return ret; - } - - if (!include_prefix) { - return 0; - } - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_IAPREFIX, - DHCPV6_OPTION_IAPREFIX_HEADER_SIZE); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_pd->iaprefix.preferred_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_be32(pkt, ia_pd->iaprefix.valid_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write_u8(pkt, ia_pd->iaprefix.prefix_len); - if (ret < 0) { - return ret; - } - - ret = net_pkt_write(pkt, &ia_pd->iaprefix.prefix, - sizeof(ia_pd->iaprefix.prefix)); - - return ret; -} - -static int dhcpv6_add_option_oro(struct net_pkt *pkt, uint16_t *codes, - int code_cnt) -{ - int ret; - - ret = dhcpv6_add_option_header(pkt, DHCPV6_OPTION_CODE_ORO, - sizeof(uint16_t) * code_cnt); - if (ret < 0) { - return ret; - } - - for (int i = 0; i < code_cnt; i++) { - ret = net_pkt_write_be16(pkt, codes[i]); - if (ret < 0) { - return ret; - } - } - - return ret; -} - -static size_t dhcpv6_calculate_message_size(struct dhcpv6_options_include *options) -{ - size_t msg_size = sizeof(struct dhcpv6_msg_hdr); - uint8_t oro_cnt = 0; - - if (options->clientid) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += sizeof(struct net_dhcpv6_duid_storage); - } - - if (options->serverid) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += sizeof(struct net_dhcpv6_duid_storage); - } - - if (options->elapsed_time) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += DHCPV6_OPTION_ELAPSED_TIME_SIZE; - } - - if (options->ia_na) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += DHCPV6_OPTION_IA_NA_HEADER_SIZE; - } - - if (options->iaaddr) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += DHCPV6_OPTION_IAADDR_HEADER_SIZE; - } - - if (options->ia_pd) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += DHCPV6_OPTION_IA_PD_HEADER_SIZE; - } - - if (options->iaprefix) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; - } - - for (uint8_t i = 0; i < ARRAY_SIZE(options->oro); i++) { - if (options->oro[i] == 0) { - break; - } - - oro_cnt++; - } - - if (oro_cnt > 0) { - msg_size += DHCPV6_OPTION_HEADER_SIZE; - msg_size += oro_cnt * sizeof(uint16_t); - } - - return msg_size; -} - -static int dhcpv6_add_options(struct net_if *iface, struct net_pkt *pkt, - struct dhcpv6_options_include *options) -{ - uint8_t oro_cnt = 0; - int ret; - - if (options->clientid) { - ret = dhcpv6_add_option_clientid( - pkt, &iface->config.dhcpv6.clientid); - if (ret < 0) { - goto fail; - } - } - - if (options->serverid) { - ret = dhcpv6_add_option_serverid( - pkt, &iface->config.dhcpv6.serverid); - if (ret < 0) { - goto fail; - } - } - - if (options->elapsed_time) { - ret = dhcpv6_add_option_elapsed_time( - pkt, iface->config.dhcpv6.exchange_start); - if (ret < 0) { - goto fail; - } - } - - if (options->ia_na) { - struct dhcpv6_ia_na ia_na = { - .iaid = iface->config.dhcpv6.addr_iaid, - }; - - if (options->iaaddr) { - memcpy(&ia_na.iaaddr.addr, &iface->config.dhcpv6.addr, - sizeof(ia_na.iaaddr.addr)); - } - - ret = dhcpv6_add_option_ia_na(pkt, &ia_na, options->iaaddr); - if (ret < 0) { - goto fail; - } - } - - if (options->ia_pd) { - struct dhcpv6_ia_pd ia_pd = { - .iaid = iface->config.dhcpv6.prefix_iaid, - }; - - if (options->iaprefix) { - memcpy(&ia_pd.iaprefix.prefix, &iface->config.dhcpv6.prefix, - sizeof(ia_pd.iaprefix.prefix)); - ia_pd.iaprefix.prefix_len = iface->config.dhcpv6.prefix_len; - } - - ret = dhcpv6_add_option_ia_pd(pkt, &ia_pd, options->iaprefix); - if (ret < 0) { - goto fail; - } - } - - for (uint8_t i = 0; i < ARRAY_SIZE(options->oro); i++) { - if (options->oro[i] == 0) { - break; - } - - oro_cnt++; - } - - if (oro_cnt > 0) { - ret = dhcpv6_add_option_oro(pkt, options->oro, oro_cnt); - if (ret < 0) { - goto fail; - } - } - - return 0; - -fail: - return ret; -} - -static struct net_pkt *dhcpv6_create_message(struct net_if *iface, - enum dhcpv6_msg_type msg_type, - struct dhcpv6_options_include *options) -{ - struct in6_addr *local_addr; - struct net_pkt *pkt; - size_t msg_size; - - local_addr = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE); - if (local_addr == NULL) { - NET_ERR("No LL address"); - return NULL; - } - - msg_size = dhcpv6_calculate_message_size(options); - - pkt = net_pkt_alloc_with_buffer(iface, msg_size, AF_INET6, - IPPROTO_UDP, K_FOREVER); - if (pkt == NULL) { - return NULL; - } - - if (net_ipv6_create(pkt, local_addr, &all_dhcpv6_ra_and_servers) < 0 || - net_udp_create(pkt, htons(DHCPV6_CLIENT_PORT), - htons(DHCPV6_SERVER_PORT)) < 0) { - goto fail; - } - - dhcpv6_generate_tid(iface); - - if (dhcpv6_add_header(pkt, msg_type, iface->config.dhcpv6.tid) < 0) { - goto fail; - } - - if (dhcpv6_add_options(iface, pkt, options) < 0) { - goto fail; - } - - net_pkt_cursor_init(pkt); - net_ipv6_finalize(pkt, IPPROTO_UDP); - - return pkt; - -fail: - net_pkt_unref(pkt); - - return NULL; -} - -static int dhcpv6_send_solicit(struct net_if *iface) -{ - int ret; - struct net_pkt *pkt; - struct dhcpv6_options_include options = { - .clientid = true, - .elapsed_time = true, - .ia_na = iface->config.dhcpv6.params.request_addr, - .ia_pd = iface->config.dhcpv6.params.request_prefix, - .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, - }; - - pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_SOLICIT, &options); - if (pkt == NULL) { - return -ENOMEM; - } - - ret = net_send_data(pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } - - return ret; -} - -static int dhcpv6_send_request(struct net_if *iface) -{ - int ret; - struct net_pkt *pkt; - struct dhcpv6_options_include options = { - .clientid = true, - .serverid = true, - .elapsed_time = true, - .ia_na = iface->config.dhcpv6.params.request_addr, - .ia_pd = iface->config.dhcpv6.params.request_prefix, - .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, - }; - - pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_REQUEST, &options); - if (pkt == NULL) { - return -ENOMEM; - } - - ret = net_send_data(pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } - - return ret; -} - -static int dhcpv6_send_renew(struct net_if *iface) -{ - int ret; - struct net_pkt *pkt; - struct dhcpv6_options_include options = { - .clientid = true, - .serverid = true, - .elapsed_time = true, - .ia_na = iface->config.dhcpv6.params.request_addr, - .iaaddr = iface->config.dhcpv6.params.request_addr, - .ia_pd = iface->config.dhcpv6.params.request_prefix, - .iaprefix = iface->config.dhcpv6.params.request_prefix, - .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, - }; - - pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_RENEW, &options); - if (pkt == NULL) { - return -ENOMEM; - } - - ret = net_send_data(pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } - - return ret; -} - -static int dhcpv6_send_rebind(struct net_if *iface) -{ - int ret; - struct net_pkt *pkt; - struct dhcpv6_options_include options = { - .clientid = true, - .elapsed_time = true, - .ia_na = iface->config.dhcpv6.params.request_addr, - .iaaddr = iface->config.dhcpv6.params.request_addr, - .ia_pd = iface->config.dhcpv6.params.request_prefix, - .iaprefix = iface->config.dhcpv6.params.request_prefix, - .oro = { DHCPV6_OPTION_CODE_SOL_MAX_RT }, - }; - - pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_REBIND, &options); - if (pkt == NULL) { - return -ENOMEM; - } - - ret = net_send_data(pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } - - return ret; -} - -static int dhcpv6_send_confirm(struct net_if *iface) -{ - int ret; - struct net_pkt *pkt; - struct dhcpv6_options_include options = { - .clientid = true, - .elapsed_time = true, - .ia_na = true, - .iaaddr = true, - }; - - pkt = dhcpv6_create_message(iface, DHCPV6_MSG_TYPE_CONFIRM, &options); - if (pkt == NULL) { - return -ENOMEM; - } - - ret = net_send_data(pkt); - if (ret < 0) { - net_pkt_unref(pkt); - } - - return ret; -} - -/* DHCPv6 packet parsing functions */ - -static int dhcpv6_parse_option_clientid(struct net_pkt *pkt, uint16_t length, - struct net_dhcpv6_duid_storage *clientid) -{ - struct net_dhcpv6_duid_raw duid; - int ret; - - if (length > sizeof(struct net_dhcpv6_duid_raw)) { - NET_ERR("DUID too large to handle"); - return -EMSGSIZE; - } - - ret = net_pkt_read(pkt, &duid, length); - if (ret < 0) { - return ret; - } - - clientid->length = length; - memcpy(&clientid->duid, &duid, length); - - return 0; -} - -static int dhcpv6_parse_option_serverid(struct net_pkt *pkt, uint16_t length, - struct net_dhcpv6_duid_storage *serverid) -{ - struct net_dhcpv6_duid_raw duid; - int ret; - - if (length > sizeof(struct net_dhcpv6_duid_raw)) { - NET_ERR("DUID too large to handle"); - return -EMSGSIZE; - } - - ret = net_pkt_read(pkt, &duid, length); - if (ret < 0) { - return ret; - } - - serverid->length = length; - memcpy(&serverid->duid, &duid, length); - - return 0; -} - -static int dhcpv6_parse_option_preference(struct net_pkt *pkt, uint16_t length, - uint8_t *preference) -{ - if (length != DHCPV6_OPTION_PREFERENCE_SIZE) { - return -EBADMSG; - } - - if (net_pkt_read_u8(pkt, preference) < 0) { - return -EBADMSG; - } - - return 0; -} - -static int dhcpv6_parse_option_status_code(struct net_pkt *pkt, - uint16_t length, uint16_t *status) -{ - int ret; - - if (length < DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE) { - NET_ERR("Invalid IAADDR option size"); - return -EMSGSIZE; - } - - ret = net_pkt_read_be16(pkt, status); - if (ret < 0) { - return ret; - } - - NET_DBG("status code %d", *status); - - length -= DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE; - if (length > 0) { - /* Ignore status message */ - ret = net_pkt_skip(pkt, length); - } - - return ret; -} - -static int dhcpv6_parse_option_iaaddr(struct net_pkt *pkt, uint16_t length, - struct dhcpv6_iaaddr *iaaddr) -{ - int ret; - - if (length < DHCPV6_OPTION_IAADDR_HEADER_SIZE) { - NET_ERR("Invalid IAADDR option size"); - return -EMSGSIZE; - } - - ret = net_pkt_read(pkt, &iaaddr->addr, sizeof(iaaddr->addr)); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &iaaddr->preferred_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &iaaddr->valid_lifetime); - if (ret < 0) { - return ret; - } - - /* DHCPv6 RFC8415, ch. 21.6 The client MUST discard any addresses for - * which the preferred lifetime is greater than the valid lifetime. - */ - if (iaaddr->preferred_lifetime > iaaddr->valid_lifetime) { - return -EBADMSG; - } - - NET_DBG("addr %s preferred_lifetime %d valid_lifetime %d", - net_sprint_ipv6_addr(&iaaddr->addr), iaaddr->preferred_lifetime, - iaaddr->valid_lifetime); - - iaaddr->status = DHCPV6_STATUS_SUCCESS; - - length -= DHCPV6_OPTION_IAADDR_HEADER_SIZE; - while (length > 0) { - uint16_t code, sublen; - - ret = net_pkt_read_be16(pkt, &code); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be16(pkt, &sublen); - if (ret < 0) { - return ret; - } - - switch (code) { - case DHCPV6_OPTION_CODE_STATUS_CODE: - ret = dhcpv6_parse_option_status_code(pkt, sublen, - &iaaddr->status); - if (ret < 0) { - return ret; - } - - break; - default: - net_pkt_skip(pkt, sublen); - NET_DBG("Unexpected option %d length %d", code, sublen); - break; - } - - length -= (sublen + 4); - } - - return 0; -} - -static int dhcpv6_parse_option_ia_na(struct net_pkt *pkt, uint16_t length, - struct dhcpv6_ia_na *ia_na) -{ - int ret; - - if (length < DHCPV6_OPTION_IA_NA_HEADER_SIZE) { - NET_ERR("Invalid IA_NA option size"); - return -EMSGSIZE; - } - - ret = net_pkt_read_be32(pkt, &ia_na->iaid); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &ia_na->t1); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &ia_na->t2); - if (ret < 0) { - return ret; - } - - /* DHCPv6 RFC8415, ch. 21.4 If a client receives an IA_NA with T1 - * greater than T2 and both T1 and T2 are greater than 0, the client - * discards the IA_NA option and processes the remainder of the message - * as though the server had not included the invalid IA_NA option. - */ - if (ia_na->t1 != 0 && ia_na->t2 != 0 && ia_na->t1 > ia_na->t2) { - return -ENOENT; - } - - NET_DBG("iaid %d t1 %d t2 %d", ia_na->iaid, ia_na->t1, ia_na->t2); - - /* In case there's no IAADDR option, make this visible be setting - * error status. If the option is present, option parser will overwrite - * the value. - */ - ia_na->iaaddr.status = DHCPV6_STATUS_NO_ADDR_AVAIL; - ia_na->status = DHCPV6_STATUS_SUCCESS; - - length -= DHCPV6_OPTION_IA_NA_HEADER_SIZE; - while (length > 0) { - uint16_t code, sublen; - - ret = net_pkt_read_be16(pkt, &code); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be16(pkt, &sublen); - if (ret < 0) { - return ret; - } - - switch (code) { - case DHCPV6_OPTION_CODE_IAADDR: - ret = dhcpv6_parse_option_iaaddr(pkt, sublen, - &ia_na->iaaddr); - if (ret < 0) { - return ret; - } - - break; - - case DHCPV6_OPTION_CODE_STATUS_CODE: - ret = dhcpv6_parse_option_status_code(pkt, sublen, - &ia_na->status); - if (ret < 0) { - return ret; - } - - break; - - default: - net_pkt_skip(pkt, sublen); - NET_DBG("Unexpected option %d length %d", code, sublen); - break; - } - - length -= (sublen + 4); - } - - return 0; -} - -static int dhcpv6_parse_option_iaprefix(struct net_pkt *pkt, uint16_t length, - struct dhcpv6_iaprefix *iaprefix) -{ - int ret; - - if (length < DHCPV6_OPTION_IAPREFIX_HEADER_SIZE) { - NET_ERR("Invalid IAPREFIX option size"); - return -EMSGSIZE; - } - - ret = net_pkt_read_be32(pkt, &iaprefix->preferred_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &iaprefix->valid_lifetime); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_u8(pkt, &iaprefix->prefix_len); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read(pkt, &iaprefix->prefix, sizeof(iaprefix->prefix)); - if (ret < 0) { - return ret; - } - - /* DHCPv6 RFC8415, ch. 21.22 The client MUST discard any prefixes for - * which the preferred lifetime is greater than the valid lifetime. - */ - if (iaprefix->preferred_lifetime > iaprefix->valid_lifetime) { - return -EBADMSG; - } - - NET_DBG("prefix %s/%u preferred_lifetime %d valid_lifetime %d", - net_sprint_ipv6_addr(&iaprefix->prefix), iaprefix->prefix_len, - iaprefix->preferred_lifetime, iaprefix->valid_lifetime); - - iaprefix->status = DHCPV6_STATUS_SUCCESS; - - length -= DHCPV6_OPTION_IAPREFIX_HEADER_SIZE; - while (length > 0) { - uint16_t code, sublen; - - ret = net_pkt_read_be16(pkt, &code); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be16(pkt, &sublen); - if (ret < 0) { - return ret; - } - - switch (code) { - case DHCPV6_OPTION_CODE_STATUS_CODE: - ret = dhcpv6_parse_option_status_code(pkt, sublen, - &iaprefix->status); - if (ret < 0) { - return ret; - } - - break; - default: - net_pkt_skip(pkt, sublen); - NET_DBG("Unexpected option %d length %d", code, sublen); - break; - } - - length -= (sublen + 4); - } - - return 0; -} - -static int dhcpv6_parse_option_ia_pd(struct net_pkt *pkt, uint16_t length, - struct dhcpv6_ia_pd *ia_pd) -{ - int ret; - - if (length < DHCPV6_OPTION_IA_PD_HEADER_SIZE) { - NET_ERR("Invalid IA_PD option size"); - return -EMSGSIZE; - } - - ret = net_pkt_read_be32(pkt, &ia_pd->iaid); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &ia_pd->t1); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be32(pkt, &ia_pd->t2); - if (ret < 0) { - return ret; - } - - /* DHCPv6 RFC8415, ch. 21.21 If a client receives an IA_PD with T1 - * greater than T2 and both T1 and T2 are greater than 0, the client - * discards the IA_PD option and processes the remainder of the message - * as though the server had not included the IA_PD option. - */ - if (ia_pd->t1 != 0 && ia_pd->t2 != 0 && ia_pd->t1 > ia_pd->t2) { - return -ENOENT; - } - - NET_DBG("iaid %d t1 %d t2 %d", ia_pd->iaid, ia_pd->t1, ia_pd->t2); - - /* In case there's no IAPREFIX option, make this visible be setting - * error status. If the option is present, option parser will overwrite - * the value. - */ - ia_pd->iaprefix.status = DHCPV6_STATUS_NO_PREFIX_AVAIL; - ia_pd->status = DHCPV6_STATUS_SUCCESS; - - length -= DHCPV6_OPTION_IA_PD_HEADER_SIZE; - while (length > 0) { - uint16_t code, sublen; - - ret = net_pkt_read_be16(pkt, &code); - if (ret < 0) { - return ret; - } - - ret = net_pkt_read_be16(pkt, &sublen); - if (ret < 0) { - return ret; - } - - switch (code) { - case DHCPV6_OPTION_CODE_IAPREFIX: - ret = dhcpv6_parse_option_iaprefix(pkt, sublen, - &ia_pd->iaprefix); - if (ret < 0) { - return ret; - } - - break; - - case DHCPV6_OPTION_CODE_STATUS_CODE: - ret = dhcpv6_parse_option_status_code(pkt, sublen, - &ia_pd->status); - if (ret < 0) { - return ret; - } - - break; - default: - net_pkt_skip(pkt, sublen); - NET_DBG("Unexpected option %d length %d", code, sublen); - break; - } - - length -= (sublen + 4); - } - - return 0; -} - -static int dhcpv6_find_option(struct net_pkt *pkt, enum dhcpv6_option_code opt_code, - uint16_t *opt_len) -{ - uint16_t length; - uint16_t code; - - while (net_pkt_read_be16(pkt, &code) == 0) { - if (net_pkt_read_be16(pkt, &length) < 0) { - return -EBADMSG; - } - - if (code == opt_code) { - *opt_len = length; - return 0; - } - - net_pkt_skip(pkt, length); - } - - return -ENOENT; -} - -static int dhcpv6_find_clientid(struct net_pkt *pkt, - struct net_dhcpv6_duid_storage *clientid) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_CLIENTID, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_clientid(pkt, length, clientid); - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -static int dhcpv6_find_serverid(struct net_pkt *pkt, - struct net_dhcpv6_duid_storage *serverid) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_SERVERID, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_serverid(pkt, length, serverid); - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -static int dhcpv6_find_server_preference(struct net_pkt *pkt, - uint8_t *preference) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_PREFERENCE, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_preference(pkt, length, preference); - } else if (ret == -ENOENT) { - /* In case no preference option is present, default to 0. - * DHCPv6 RFC8415, ch. 18.2.1. - */ - *preference = 0; - ret = 0; - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -static int dhcpv6_find_ia_na(struct net_pkt *pkt, struct dhcpv6_ia_na *ia_na) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_IA_NA, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_ia_na(pkt, length, ia_na); - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -static int dhcpv6_find_ia_pd(struct net_pkt *pkt, struct dhcpv6_ia_pd *ia_pd) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_IA_PD, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_ia_pd(pkt, length, ia_pd); - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -static int dhcpv6_find_status_code(struct net_pkt *pkt, uint16_t *status) -{ - struct net_pkt_cursor backup; - uint16_t length; - int ret; - - net_pkt_cursor_backup(pkt, &backup); - - ret = dhcpv6_find_option(pkt, DHCPV6_OPTION_CODE_STATUS_CODE, &length); - if (ret == 0) { - ret = dhcpv6_parse_option_status_code(pkt, length, status); - } else if (ret == -ENOENT) { - /* In case no status option is present, default to success. - * DHCPv6 RFC8415, ch. 21.13. - */ - *status = DHCPV6_STATUS_SUCCESS; - ret = 0; - } - - net_pkt_cursor_restore(pkt, &backup); - - return ret; -} - -/* DHCPv6 state changes */ - -static void dhcpv6_enter_init(struct net_if *iface) -{ - uint32_t timeout; - - /* RFC8415 requires to wait a random period up to 1 second before - * sending the initial solicit/information request/confirm. - */ - timeout = sys_rand32_get() % DHCPV6_SOL_MAX_DELAY; - - dhcpv6_set_timeout(iface, timeout); -} - -static void dhcpv6_enter_soliciting(struct net_if *iface) -{ - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_initial_retransmit_time(DHCPV6_SOL_TIMEOUT); - iface->config.dhcpv6.retransmissions = 0; - iface->config.dhcpv6.server_preference = -1; - iface->config.dhcpv6.exchange_start = k_uptime_get(); - - (void)dhcpv6_send_solicit(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); -} - -static void dhcpv6_enter_requesting(struct net_if *iface) -{ - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_initial_retransmit_time(DHCPV6_REQ_TIMEOUT); - iface->config.dhcpv6.retransmissions = 0; - iface->config.dhcpv6.exchange_start = k_uptime_get(); - - (void)dhcpv6_send_request(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); -} - -static void dhcpv6_enter_renewing(struct net_if *iface) -{ - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_initial_retransmit_time(DHCPV6_REN_TIMEOUT); - iface->config.dhcpv6.retransmissions = 0; - iface->config.dhcpv6.exchange_start = k_uptime_get(); - - (void)dhcpv6_send_renew(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); -} - -static void dhcpv6_enter_rebinding(struct net_if *iface) -{ - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_initial_retransmit_time(DHCPV6_REB_TIMEOUT); - iface->config.dhcpv6.retransmissions = 0; - iface->config.dhcpv6.exchange_start = k_uptime_get(); - - (void)dhcpv6_send_rebind(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); -} - -static void dhcpv6_enter_confirming(struct net_if *iface) -{ - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_initial_retransmit_time(DHCPV6_CNF_TIMEOUT); - iface->config.dhcpv6.retransmissions = 0; - iface->config.dhcpv6.exchange_start = k_uptime_get(); - - (void)dhcpv6_send_confirm(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); -} - -static void dhcpv6_enter_bound(struct net_if *iface) -{ - iface->config.dhcpv6.timeout = iface->config.dhcpv6.t1; -} - -static void dhcpv6_enter_state(struct net_if *iface, enum net_dhcpv6_state state) -{ - iface->config.dhcpv6.state = state; - - NET_DBG("enter state=%s", - net_dhcpv6_state_name(iface->config.dhcpv6.state)); - - switch (iface->config.dhcpv6.state) { - case NET_DHCPV6_DISABLED: - break; - case NET_DHCPV6_INIT: - return dhcpv6_enter_init(iface); - case NET_DHCPV6_SOLICITING: - return dhcpv6_enter_soliciting(iface); - case NET_DHCPV6_REQUESTING: - return dhcpv6_enter_requesting(iface); - case NET_DHCPV6_CONFIRMING: - return dhcpv6_enter_confirming(iface); - case NET_DHCPV6_RENEWING: - return dhcpv6_enter_renewing(iface); - case NET_DHCPV6_REBINDING: - return dhcpv6_enter_rebinding(iface); - case NET_DHCPV6_INFO_REQUESTING: - break; - case NET_DHCPV6_BOUND: - return dhcpv6_enter_bound(iface); - } -} - -/* DHCPv6 input processing */ - -static int dhcpv6_handle_advertise(struct net_if *iface, struct net_pkt *pkt, - uint8_t *tid) -{ - struct net_dhcpv6_duid_storage duid = { 0 }; - struct dhcpv6_ia_pd ia_pd = { 0 }; - struct dhcpv6_ia_na ia_na = { 0 }; - uint8_t server_preference = 0; - uint16_t status = 0; - int ret; - - if (iface->config.dhcpv6.state != NET_DHCPV6_SOLICITING) { - return -EINVAL; - } - - /* Verify client ID. */ - ret = dhcpv6_find_clientid(pkt, &duid); - if (ret < 0) { - NET_ERR("Client ID missing"); - return ret; - } - - if (iface->config.dhcpv6.clientid.length != duid.length || - memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, - iface->config.dhcpv6.clientid.length) != 0) { - NET_ERR("Client ID mismatch"); - return -EBADMSG; - } - - /* Verify server ID is present. */ - memset(&duid, 0, sizeof(duid)); - ret = dhcpv6_find_serverid(pkt, &duid); - if (ret < 0) { - NET_ERR("Server ID missing"); - return ret; - } - - /* Verify TID. */ - if (memcmp(iface->config.dhcpv6.tid, tid, - sizeof(iface->config.dhcpv6.tid)) != 0) { - NET_INFO("TID mismatch"); - return -EBADMSG; - } - - /* Verify status code. */ - ret = dhcpv6_find_status_code(pkt, &status); - if (ret < 0) { - return ret; - } - - if (status != DHCPV6_STATUS_SUCCESS) { - /* Ignore. */ - return 0; - } - - /* TODO Process SOL_MAX_RT/INF_MAX_RT options. */ - - /* Verify server preference. */ - ret = dhcpv6_find_server_preference(pkt, &server_preference); - if (ret < 0) { - return ret; - } - - if ((int16_t)server_preference < iface->config.dhcpv6.server_preference) { - /* Ignore. */ - return 0; - } - - /* Find/verify address. */ - if (iface->config.dhcpv6.params.request_addr) { - ret = dhcpv6_find_ia_na(pkt, &ia_na); - if (ret < 0) { - NET_ERR("Address missing"); - return ret; - } - - if (ia_na.status != DHCPV6_STATUS_SUCCESS || - ia_na.iaaddr.status != DHCPV6_STATUS_SUCCESS) { - /* Ignore. */ - return 0; - } - } - - /* Find/verify prefix. */ - if (iface->config.dhcpv6.params.request_prefix) { - ret = dhcpv6_find_ia_pd(pkt, &ia_pd); - if (ret < 0) { - NET_ERR("Prefix missing"); - return ret; - } - - if (ia_pd.status != DHCPV6_STATUS_SUCCESS || - ia_pd.iaprefix.status != DHCPV6_STATUS_SUCCESS) { - /* Ignore. */ - return 0; - } - } - - /* Valid advertisement received, store received offer. */ - memcpy(&iface->config.dhcpv6.serverid, &duid, - sizeof(iface->config.dhcpv6.serverid)); - iface->config.dhcpv6.server_preference = server_preference; - - /* DHCPv6 RFC8415, ch. 18.2.1, if client received Advertise - * message with maximum preference, or after the first - * retransmission period, it should proceed with the exchange, - * w/o further wait. - */ - if (server_preference == DHCPV6_MAX_SERVER_PREFERENCE || - iface->config.dhcpv6.retransmissions > 0) { - /* Reschedule immediately */ - dhcpv6_enter_state(iface, NET_DHCPV6_REQUESTING); - dhcpv6_reschedule(); - } - - return 0; -} - -static int dhcpv6_handle_reply(struct net_if *iface, struct net_pkt *pkt, - uint8_t *tid) -{ - struct net_dhcpv6_duid_storage duid = { 0 }; - struct dhcpv6_ia_pd ia_pd = { 0 }; - struct dhcpv6_ia_na ia_na = { 0 }; - int64_t now = k_uptime_get(); - uint16_t status = 0; - bool rediscover = false; - int ret; - - if (iface->config.dhcpv6.state != NET_DHCPV6_REQUESTING && - iface->config.dhcpv6.state != NET_DHCPV6_CONFIRMING && - iface->config.dhcpv6.state != NET_DHCPV6_RENEWING && - iface->config.dhcpv6.state != NET_DHCPV6_REBINDING) { - return -EINVAL; - } - - /* Verify client ID. */ - ret = dhcpv6_find_clientid(pkt, &duid); - if (ret < 0) { - NET_ERR("Client ID missing"); - return ret; - } - - if (iface->config.dhcpv6.clientid.length != duid.length || - memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, - iface->config.dhcpv6.clientid.length) != 0) { - NET_ERR("Client ID mismatch"); - return -EBADMSG; - } - - /* Verify server ID is present. */ - memset(&duid, 0, sizeof(duid)); - ret = dhcpv6_find_serverid(pkt, &duid); - if (ret < 0) { - NET_ERR("Server ID missing"); - return ret; - } - - /* Verify TID. */ - if (memcmp(iface->config.dhcpv6.tid, tid, - sizeof(iface->config.dhcpv6.tid)) != 0) { - NET_INFO("TID mismatch"); - return -EBADMSG; - } - - /* TODO Process SOL_MAX_RT/INF_MAX_RT options. */ - - /* Verify status code. */ - ret = dhcpv6_find_status_code(pkt, &status); - if (ret < 0) { - return ret; - } - - if (status == DHCPV6_STATUS_UNSPEC_FAIL) { - /* Ignore and try again later. */ - return 0; - } - - /* DHCPv6 RFC8415, ch. 18.2.10.1. If the client receives a NotOnLink - * status from the server in response to (...) Request, the client can - * either reissue the message without specifying any addresses or - * restart the DHCP server discovery process. - * - * Restart discovery for our case. - */ - if (iface->config.dhcpv6.state == NET_DHCPV6_REQUESTING && - status == DHCPV6_STATUS_NOT_ON_LINK) { - rediscover = true; - goto out; - } - - /* In case of Confirm Reply, status success indicates the client can - * still use the address. - */ - if (iface->config.dhcpv6.state == NET_DHCPV6_CONFIRMING) { - if (status != DHCPV6_STATUS_SUCCESS) { - rediscover = true; - } - - goto out; - } - - /* Find/verify address. */ - if (iface->config.dhcpv6.params.request_addr) { - ret = dhcpv6_find_ia_na(pkt, &ia_na); - if (ret < 0) { - NET_ERR("Address missing"); - return ret; - } - - if (iface->config.dhcpv6.addr_iaid != ia_na.iaid) { - return -EBADMSG; - } - } - - /* Find/verify prefix. */ - if (iface->config.dhcpv6.params.request_prefix) { - ret = dhcpv6_find_ia_pd(pkt, &ia_pd); - if (ret < 0) { - NET_ERR("Prefix missing"); - return ret; - } - - if (iface->config.dhcpv6.prefix_iaid != ia_pd.iaid) { - return -EBADMSG; - } - } - - /* Valid response received, store received data. */ - iface->config.dhcpv6.t1 = UINT64_MAX; - iface->config.dhcpv6.t2 = UINT64_MAX; - iface->config.dhcpv6.expire = now; - - if (iface->config.dhcpv6.params.request_addr) { - struct net_if_addr *ifaddr; - - if (ia_na.status == DHCPV6_STATUS_NO_ADDR_AVAIL || - ia_na.iaaddr.status == DHCPV6_STATUS_NO_ADDR_AVAIL || - ia_na.iaaddr.valid_lifetime == 0) { - /* Remove old lease. */ - net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); - memset(&iface->config.dhcpv6.addr, 0, sizeof(struct in6_addr)); - rediscover = true; - goto prefix; - } - - /* TODO On nobiding (renew/rebind) go to requesting */ - - if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, - net_ipv6_unspecified_address()) && - !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, - &ia_na.iaaddr.addr)) { - /* Remove old lease. */ - net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); - } - - memcpy(&iface->config.dhcpv6.addr, &ia_na.iaaddr.addr, - sizeof(iface->config.dhcpv6.addr)); - - dhcvp6_update_deadlines(iface, now, ia_na.t1, ia_na.t2, - ia_na.iaaddr.preferred_lifetime, - ia_na.iaaddr.valid_lifetime); - - ifaddr = net_if_ipv6_addr_lookup_by_iface(iface, &ia_na.iaaddr.addr); - if (ifaddr != NULL) { - net_if_ipv6_addr_update_lifetime( - ifaddr, ia_na.iaaddr.valid_lifetime); - } else if (net_if_ipv6_addr_add(iface, &ia_na.iaaddr.addr, NET_ADDR_DHCP, - ia_na.iaaddr.valid_lifetime) == NULL) { - NET_ERR("Failed to configure DHCPv6 address"); - net_dhcpv6_stop(iface); - return -EFAULT; - } - } - -prefix: - if (iface->config.dhcpv6.params.request_prefix) { - struct net_if_ipv6_prefix *ifprefix; - - if (ia_pd.status == DHCPV6_STATUS_NO_PREFIX_AVAIL || - ia_pd.iaprefix.status == DHCPV6_STATUS_NO_PREFIX_AVAIL || - ia_pd.iaprefix.valid_lifetime == 0) { - /* Remove old lease. */ - net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, - iface->config.dhcpv6.prefix_len); - memset(&iface->config.dhcpv6.prefix, 0, sizeof(struct in6_addr)); - iface->config.dhcpv6.prefix_len = 0; - rediscover = true; - goto out; - } - - if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, - net_ipv6_unspecified_address()) && - (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, - &ia_pd.iaprefix.prefix) || - iface->config.dhcpv6.prefix_len != ia_pd.iaprefix.prefix_len)) { - /* Remove old lease. */ - net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, - iface->config.dhcpv6.prefix_len); - } - - iface->config.dhcpv6.prefix_len = ia_pd.iaprefix.prefix_len; - - memcpy(&iface->config.dhcpv6.prefix, &ia_pd.iaprefix.prefix, - sizeof(iface->config.dhcpv6.prefix)); - - dhcvp6_update_deadlines(iface, now, ia_pd.t1, ia_pd.t2, - ia_pd.iaprefix.preferred_lifetime, - ia_pd.iaprefix.valid_lifetime); - - ifprefix = net_if_ipv6_prefix_lookup(iface, &ia_pd.iaprefix.prefix, - ia_pd.iaprefix.prefix_len); - if (ifprefix != NULL) { - net_if_ipv6_prefix_set_timer(ifprefix, ia_pd.iaprefix.valid_lifetime); - } else if (net_if_ipv6_prefix_add(iface, &ia_pd.iaprefix.prefix, - ia_pd.iaprefix.prefix_len, - ia_pd.iaprefix.valid_lifetime) == NULL) { - NET_ERR("Failed to configure DHCPv6 prefix"); - net_dhcpv6_stop(iface); - return -EFAULT; - } - } - -out: - if (rediscover) { - dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); - } else { - dhcpv6_enter_state(iface, NET_DHCPV6_BOUND); - } - - dhcpv6_reschedule(); - - return 0; -} - -static int dhcpv6_handle_reconfigure(struct net_if *iface, struct net_pkt *pkt) -{ - /* Reconfigure not supported yet. */ - return -ENOTSUP; -} - -static enum net_verdict dhcpv6_input(struct net_conn *conn, - struct net_pkt *pkt, - union net_ip_header *ip_hdr, - union net_proto_header *proto_hdr, - void *user_data) -{ - struct net_if *iface; - uint8_t msg_type; - uint8_t tid[DHCPV6_TID_SIZE]; - int ret; - - if (!conn) { - NET_ERR("Invalid connection"); - return NET_DROP; - } - - if (!pkt) { - NET_ERR("Invalid packet"); - return NET_DROP; - } - - iface = net_pkt_iface(pkt); - if (!iface) { - NET_ERR("No interface"); - return NET_DROP; - } - - net_pkt_cursor_init(pkt); - - if (net_pkt_skip(pkt, NET_IPV6UDPH_LEN)) { - NET_ERR("Missing IPv6/UDP header"); - return NET_DROP; - } - - if (net_pkt_read_u8(pkt, &msg_type) < 0) { - NET_ERR("Missing message type"); - return NET_DROP; - } - - if (net_pkt_read(pkt, tid, sizeof(tid)) < 0) { - NET_ERR("Missing transaction ID"); - return NET_DROP; - } - - NET_DBG("Received DHCPv6 packet [type=%d, tid=0x%02x%02x%02x]", - msg_type, tid[0], tid[1], tid[2]); - - switch (msg_type) { - case DHCPV6_MSG_TYPE_ADVERTISE: - ret = dhcpv6_handle_advertise(iface, pkt, tid); - break; - case DHCPV6_MSG_TYPE_REPLY: - ret = dhcpv6_handle_reply(iface, pkt, tid); - break; - case DHCPV6_MSG_TYPE_RECONFIGURE: - ret = dhcpv6_handle_reconfigure(iface, pkt); - break; - case DHCPV6_MSG_TYPE_SOLICIT: - case DHCPV6_MSG_TYPE_REQUEST: - case DHCPV6_MSG_TYPE_CONFIRM: - case DHCPV6_MSG_TYPE_RENEW: - case DHCPV6_MSG_TYPE_REBIND: - case DHCPV6_MSG_TYPE_RELEASE: - case DHCPV6_MSG_TYPE_DECLINE: - case DHCPV6_MSG_TYPE_INFORMATION_REQUEST: - case DHCPV6_MSG_TYPE_RELAY_FORW: - case DHCPV6_MSG_TYPE_RELAY_REPL: - default: - goto drop; - } - - if (ret < 0) { - goto drop; - } - - net_pkt_unref(pkt); - - return NET_OK; - -drop: - return NET_DROP; -} - -/* DHCPv6 timer management */ - -static uint64_t dhcpv6_timeleft(struct net_if *iface, int64_t now) -{ - uint64_t timeout = iface->config.dhcpv6.timeout; - - if (timeout > now) { - return timeout - now; - } - - return 0; -} - -static uint64_t dhcpv6_manage_timers(struct net_if *iface, int64_t now) -{ - uint64_t timeleft = dhcpv6_timeleft(iface, now); - - NET_DBG("iface %p state=%s timeleft=%llu", iface, - net_dhcpv6_state_name(iface->config.dhcpv6.state), timeleft); - - if (timeleft != 0U) { - return iface->config.dhcpv6.timeout; - } - - if (!net_if_is_up(iface)) { - /* An interface is down, the registered event handler will - * restart DHCP procedure when the interface is back up. - */ - return UINT64_MAX; - } - - switch (iface->config.dhcpv6.state) { - case NET_DHCPV6_DISABLED: - break; - case NET_DHCPV6_INIT: { - bool have_addr = false; - bool have_prefix = false; - - if (iface->config.dhcpv6.params.request_addr && - !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, - net_ipv6_unspecified_address())) { - have_addr = true; - } - - if (iface->config.dhcpv6.params.request_prefix && - !net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, - net_ipv6_unspecified_address())) { - have_prefix = true; - } - - if ((have_addr || have_prefix) && now < iface->config.dhcpv6.expire) { - /* Try to confirm the address/prefix. In case - * prefix is requested, Rebind is used with - * Confirm timings. - */ - iface->config.dhcpv6.expire = now + DHCPV6_CNF_MAX_RD; - - if (!iface->config.dhcpv6.params.request_prefix) { - dhcpv6_enter_state(iface, NET_DHCPV6_CONFIRMING); - } else { - dhcpv6_enter_state(iface, NET_DHCPV6_REBINDING); - } - } else { - dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); - } - - return iface->config.dhcpv6.timeout; - } - case NET_DHCPV6_SOLICITING: - if (iface->config.dhcpv6.server_preference >= 0) { - dhcpv6_enter_state(iface, NET_DHCPV6_REQUESTING); - return iface->config.dhcpv6.timeout; - } - - iface->config.dhcpv6.retransmissions++; - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_next_retransmit_time( - iface->config.dhcpv6.retransmit_timeout, - DHCPV6_SOL_MAX_RT); - - (void)dhcpv6_send_solicit(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); - - return iface->config.dhcpv6.timeout; - case NET_DHCPV6_REQUESTING: - if (iface->config.dhcpv6.retransmissions >= DHCPV6_REQ_MAX_RC) { - /* Back to soliciting. */ - dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); - return iface->config.dhcpv6.timeout; - } - - iface->config.dhcpv6.retransmissions++; - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_next_retransmit_time( - iface->config.dhcpv6.retransmit_timeout, - DHCPV6_REQ_MAX_RT); - - (void)dhcpv6_send_request(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); - - return iface->config.dhcpv6.timeout; - case NET_DHCPV6_CONFIRMING: - if (now >= iface->config.dhcpv6.expire) { - dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); - return iface->config.dhcpv6.timeout; - } - - iface->config.dhcpv6.retransmissions++; - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_next_retransmit_time( - iface->config.dhcpv6.retransmit_timeout, - DHCPV6_CNF_MAX_RT); - - (void)dhcpv6_send_confirm(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); - - if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { - iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; - } - - return iface->config.dhcpv6.timeout; - case NET_DHCPV6_RENEWING: - if (now >= iface->config.dhcpv6.t2) { - dhcpv6_enter_state(iface, NET_DHCPV6_REBINDING); - return iface->config.dhcpv6.timeout; - } - - iface->config.dhcpv6.retransmissions++; - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_next_retransmit_time( - iface->config.dhcpv6.retransmit_timeout, - DHCPV6_REN_MAX_RT); - - (void)dhcpv6_send_renew(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); - - if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.t2) { - iface->config.dhcpv6.timeout = iface->config.dhcpv6.t2; - } - - return iface->config.dhcpv6.timeout; - case NET_DHCPV6_REBINDING: - if (now >= iface->config.dhcpv6.expire) { - dhcpv6_enter_state(iface, NET_DHCPV6_SOLICITING); - return iface->config.dhcpv6.timeout; - } - - iface->config.dhcpv6.retransmissions++; - iface->config.dhcpv6.retransmit_timeout = - dhcpv6_next_retransmit_time( - iface->config.dhcpv6.retransmit_timeout, - DHCPV6_REB_MAX_RT); - - (void)dhcpv6_send_rebind(iface); - dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); - - if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { - iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; - } - - return iface->config.dhcpv6.timeout; - case NET_DHCPV6_INFO_REQUESTING: - break; - case NET_DHCPV6_BOUND: - dhcpv6_enter_state(iface, NET_DHCPV6_RENEWING); - return iface->config.dhcpv6.timeout; - } - - return UINT64_MAX; -} - -static void dhcpv6_timeout(struct k_work *work) -{ - uint64_t timeout_update = UINT64_MAX; - int64_t now = k_uptime_get(); - struct net_if_dhcpv6 *current, *next; - - ARG_UNUSED(work); - - k_mutex_lock(&lock, K_FOREVER); - - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dhcpv6_ifaces, current, next, node) { - struct net_if *iface = CONTAINER_OF( - CONTAINER_OF(current, struct net_if_config, dhcpv6), - struct net_if, config); - uint64_t next_timeout; - - next_timeout = dhcpv6_manage_timers(iface, now); - if (next_timeout < timeout_update) { - timeout_update = next_timeout; - } - } - - k_mutex_unlock(&lock); - - if (timeout_update != UINT64_MAX) { - if (now > timeout_update) { - timeout_update = 0ULL; - } else { - timeout_update -= now; - } - - NET_DBG("Waiting for %llums", timeout_update); - k_work_reschedule(&dhcpv6_timeout_work, K_MSEC(timeout_update)); - } -} - -static void dhcpv6_iface_event_handler(struct net_mgmt_event_callback *cb, - uint32_t mgmt_event, struct net_if *iface) -{ - sys_snode_t *node = NULL; - - k_mutex_lock(&lock, K_FOREVER); - - SYS_SLIST_FOR_EACH_NODE(&dhcpv6_ifaces, node) { - if (node == &iface->config.dhcpv6.node) { - break; - } - } - - if (node == NULL) { - goto out; - } - - if (mgmt_event == NET_EVENT_IF_DOWN) { - NET_DBG("Interface %p going down", iface); - dhcpv6_set_timeout(iface, UINT64_MAX); - } else if (mgmt_event == NET_EVENT_IF_UP) { - NET_DBG("Interface %p coming up", iface); - dhcpv6_enter_state(iface, NET_DHCPV6_INIT); - } - - dhcpv6_reschedule(); - -out: - k_mutex_unlock(&lock); -} - -static void dhcpv6_generate_client_duid(struct net_if *iface) -{ - struct net_linkaddr *lladdr = net_if_get_link_addr(iface); - struct net_dhcpv6_duid_storage *clientid = &iface->config.dhcpv6.clientid; - struct dhcpv6_duid_ll *duid_ll = - (struct dhcpv6_duid_ll *)&clientid->duid.buf; - - memset(clientid, 0, sizeof(*clientid)); - - UNALIGNED_PUT(htons(DHCPV6_DUID_TYPE_LL), &clientid->duid.type); - UNALIGNED_PUT(htons(DHCPV6_HARDWARE_ETHERNET_TYPE), &duid_ll->hw_type); - memcpy(duid_ll->ll_addr, lladdr->addr, lladdr->len); - - clientid->length = DHCPV6_DUID_LL_HEADER_SIZE + lladdr->len; -} - -/* DHCPv6 public API */ - -void net_dhcpv6_start(struct net_if *iface, struct net_dhcpv6_params *params) -{ - k_mutex_lock(&lock, K_FOREVER); - - if (iface->config.dhcpv6.state != NET_DHCPV6_DISABLED) { - NET_ERR("DHCPv6 already running on iface %p, state %s", iface, - net_dhcpv6_state_name(iface->config.dhcpv6.state)); - goto out; - } - - if (!params->request_addr && !params->request_addr) { - NET_ERR("Information Request not supported yet"); - goto out; - } - - NET_DBG("Starting DHCPv6 on iface %p", iface); - - iface->config.dhcpv6.params = *params; - - if (sys_slist_is_empty(&dhcpv6_ifaces)) { - net_mgmt_add_event_callback(&dhcpv6_mgmt_cb); - } - - sys_slist_append(&dhcpv6_ifaces, &iface->config.dhcpv6.node); - - if (params->request_addr) { - iface->config.dhcpv6.addr_iaid = net_if_get_by_iface(iface); - } - - if (params->request_prefix) { - iface->config.dhcpv6.prefix_iaid = net_if_get_by_iface(iface); - } - - dhcpv6_generate_client_duid(iface); - dhcpv6_enter_state(iface, NET_DHCPV6_INIT); - dhcpv6_reschedule(); - -out: - k_mutex_unlock(&lock); -} - -void net_dhcpv6_stop(struct net_if *iface) -{ - k_mutex_lock(&lock, K_FOREVER); - - switch (iface->config.dhcpv6.state) { - case NET_DHCPV6_DISABLED: - NET_INFO("DHCPv6 already disabled on iface %p", iface); - break; - - case NET_DHCPV6_INIT: - case NET_DHCPV6_SOLICITING: - case NET_DHCPV6_REQUESTING: - case NET_DHCPV6_CONFIRMING: - case NET_DHCPV6_RENEWING: - case NET_DHCPV6_REBINDING: - case NET_DHCPV6_INFO_REQUESTING: - case NET_DHCPV6_BOUND: - NET_DBG("Stopping DHCPv6 on iface %p, state %s", iface, - net_dhcpv6_state_name(iface->config.dhcpv6.state)); - - (void)dhcpv6_enter_state(iface, NET_DHCPV6_DISABLED); - - sys_slist_find_and_remove(&dhcpv6_ifaces, - &iface->config.dhcpv6.node); - - if (sys_slist_is_empty(&dhcpv6_ifaces)) { - (void)k_work_cancel_delayable(&dhcpv6_timeout_work); - net_mgmt_del_event_callback(&dhcpv6_mgmt_cb); - } - - break; - } - - k_mutex_unlock(&lock); -} - -void net_dhcpv6_restart(struct net_if *iface) -{ - struct net_dhcpv6_params params = iface->config.dhcpv6.params; - - net_dhcpv6_stop(iface); - net_dhcpv6_start(iface, ¶ms); -} - -int net_dhcpv6_init(void) -{ - struct sockaddr unspec_addr; - int ret; - - net_ipaddr_copy(&net_sin6(&unspec_addr)->sin6_addr, - net_ipv6_unspecified_address()); - unspec_addr.sa_family = AF_INET6; - - ret = net_udp_register(AF_INET6, NULL, &unspec_addr, - DHCPV6_SERVER_PORT, DHCPV6_CLIENT_PORT, - NULL, dhcpv6_input, NULL, NULL); - if (ret < 0) { - NET_DBG("UDP callback registration failed"); - return ret; - } - - k_work_init_delayable(&dhcpv6_timeout_work, dhcpv6_timeout); - net_mgmt_init_event_callback(&dhcpv6_mgmt_cb, dhcpv6_iface_event_handler, - NET_EVENT_IF_DOWN | NET_EVENT_IF_UP); - - return 0; -} diff --git a/subsys/net/ip/dhcpv6_internal.h b/subsys/net/ip/dhcpv6_internal.h deleted file mode 100644 index 5ec129e601f..00000000000 --- a/subsys/net/ip/dhcpv6_internal.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief DHCPv6 internal header - * - * This header should not be included by the application. - */ - -#ifndef DHCPV6_INTERNAL_H_ -#define DHCPV6_INTERNAL_H_ - -#include - -#define DHCPV6_DUID_TYPE_SIZE 2 -#define DHVPV6_DUID_LL_HW_TYPE_SIZE 2 -#define DHCPV6_DUID_LL_HEADER_SIZE (DHCPV6_DUID_TYPE_SIZE + \ - DHVPV6_DUID_LL_HW_TYPE_SIZE) - -#define DHCPV6_MSG_TYPE_SIZE 1 -#define DHCPV6_HEADER_SIZE (DHCPV6_MSG_TYPE_SIZE + DHCPV6_TID_SIZE) - -#define DHCPV6_OPTION_CODE_SIZE 2 -#define DHCPV6_OPTION_LENGTH_SIZE 2 -#define DHCPV6_OPTION_HEADER_SIZE (DHCPV6_OPTION_CODE_SIZE + \ - DHCPV6_OPTION_LENGTH_SIZE) - -#define DHCPV6_OPTION_PREFERENCE_SIZE 1 -#define DHCPV6_OPTION_ELAPSED_TIME_SIZE 2 -#define DHCPV6_OPTION_ELAPSED_TIME_SIZE 2 -#define DHCPV6_OPTION_IA_NA_HEADER_SIZE 12 -#define DHCPV6_OPTION_IAADDR_HEADER_SIZE 24 -#define DHCPV6_OPTION_IA_PD_HEADER_SIZE 12 -#define DHCPV6_OPTION_IAPREFIX_HEADER_SIZE 25 -#define DHCPV6_OPTION_IAADDR_HEADER_SIZE 24 -#define DHCPV6_OPTION_IAPREFIX_HEADER_SIZE 25 -#define DHCPV6_OPTION_STATUS_CODE_HEADER_SIZE 2 - -#define DHCPV6_INFINITY UINT32_MAX -#define DHCPV6_MAX_SERVER_PREFERENCE 255 - -#define DHCPV6_HARDWARE_ETHERNET_TYPE 1 - -#define DHCPV6_CLIENT_PORT 546 -#define DHCPV6_SERVER_PORT 547 - -/* DHCPv6 Transmission/retransmission timeouts */ -#define DHCPV6_SOL_MAX_DELAY 1000 /* Max delay of first Solicit, milliseconds */ -#define DHCPV6_SOL_TIMEOUT 1000 /* Initial Solicit timeout, milliseconds */ -#define DHCPV6_SOL_MAX_RT 3600000 /* Max Solicit timeout value, milliseconds */ -#define DHCPV6_REQ_TIMEOUT 1000 /* Initial Request timeout, milliseconds */ -#define DHCPV6_REQ_MAX_RT 30000 /* Max Request timeout value, milliseconds */ -#define DHCPV6_REQ_MAX_RC 10 /* Max Request retry attempts */ -#define DHCPV6_CNF_MAX_DELAY 1000 /* Max delay of first Confirm, milliseconds */ -#define DHCPV6_CNF_TIMEOUT 1000 /* Initial Confirm timeout, milliseconds */ -#define DHCPV6_CNF_MAX_RT 4000 /* Max Confirm timeout, milliseconds */ -#define DHCPV6_CNF_MAX_RD 10000 /* Max Confirm duration, milliseconds */ -#define DHCPV6_REN_TIMEOUT 10000 /* Initial Renew timeout, milliseconds */ -#define DHCPV6_REN_MAX_RT 600000 /* Max Renew timeout value, milliseconds */ -#define DHCPV6_REB_TIMEOUT 10000 /* Initial Rebind timeout, milliseconds */ -#define DHCPV6_REB_MAX_RT 600000 /* Max Rebind timeout value, milliseconds */ - -/* DUID structures */ -struct dhcpv6_duid_llt { - uint16_t hw_type; - uint32_t time; - uint8_t ll_addr[]; -} __packed; - -struct dhcpv6_duid_en { - uint32_t enterprise_number; - uint8_t identifier[]; -} __packed; - -struct dhcpv6_duid_ll { - uint16_t hw_type; - uint8_t ll_addr[]; -} __packed; - -struct dhcpv6_duid_uuid { - uint8_t uuid[16]; -} __packed; - -struct dhcpv6_msg_hdr { - uint8_t type; /* Message type */ - uint8_t tid[3]; /* Transaction ID */ -} __packed; - -struct dhcpv6_iaaddr { - uint32_t preferred_lifetime; - uint32_t valid_lifetime; - struct in6_addr addr; - uint16_t status; -}; - -struct dhcpv6_ia_na { - uint32_t iaid; - uint32_t t1; - uint32_t t2; - uint16_t status; - struct dhcpv6_iaaddr iaaddr; -}; - -struct dhcpv6_iaprefix { - uint32_t preferred_lifetime; - uint32_t valid_lifetime; - struct in6_addr prefix; - uint8_t prefix_len; - uint16_t status; -}; - -struct dhcpv6_ia_pd { - uint32_t iaid; - uint32_t t1; - uint32_t t2; - uint16_t status; - struct dhcpv6_iaprefix iaprefix; -}; - -/* DHCPv6 message types, RFC8415, ch. 7.3. */ -enum dhcpv6_msg_type { - DHCPV6_MSG_TYPE_SOLICIT = 1, - DHCPV6_MSG_TYPE_ADVERTISE = 2, - DHCPV6_MSG_TYPE_REQUEST = 3, - DHCPV6_MSG_TYPE_CONFIRM = 4, - DHCPV6_MSG_TYPE_RENEW = 5, - DHCPV6_MSG_TYPE_REBIND = 6, - DHCPV6_MSG_TYPE_REPLY = 7, - DHCPV6_MSG_TYPE_RELEASE = 8, - DHCPV6_MSG_TYPE_DECLINE = 9, - DHCPV6_MSG_TYPE_RECONFIGURE = 10, - DHCPV6_MSG_TYPE_INFORMATION_REQUEST = 11, - DHCPV6_MSG_TYPE_RELAY_FORW = 12, - DHCPV6_MSG_TYPE_RELAY_REPL = 13, -}; - -/* DHCPv6 option codes, RFC8415, ch. 21. */ -enum dhcpv6_option_code { - DHCPV6_OPTION_CODE_CLIENTID = 1, - DHCPV6_OPTION_CODE_SERVERID = 2, - DHCPV6_OPTION_CODE_IA_NA = 3, - DHCPV6_OPTION_CODE_IA_TA = 4, - DHCPV6_OPTION_CODE_IAADDR = 5, - DHCPV6_OPTION_CODE_ORO = 6, - DHCPV6_OPTION_CODE_PREFERENCE = 7, - DHCPV6_OPTION_CODE_ELAPSED_TIME = 8, - DHCPV6_OPTION_CODE_RELAY_MSG = 9, - DHCPV6_OPTION_CODE_AUTH = 11, - DHCPV6_OPTION_CODE_UNICAST = 12, - DHCPV6_OPTION_CODE_STATUS_CODE = 13, - DHCPV6_OPTION_CODE_RAPID_COMMIT = 14, - DHCPV6_OPTION_CODE_USER_CLASS = 15, - DHCPV6_OPTION_CODE_VENDOR_CLASS = 16, - DHCPV6_OPTION_CODE_VENDOR_OPTS = 17, - DHCPV6_OPTION_CODE_INTERFACE_ID = 18, - DHCPV6_OPTION_CODE_RECONF_MSG = 19, - DHCPV6_OPTION_CODE_RECONF_ACCEPT = 20, - DHCPV6_OPTION_CODE_IA_PD = 25, - DHCPV6_OPTION_CODE_IAPREFIX = 26, - DHCPV6_OPTION_CODE_INFORMATION_REFRESH_TIME = 32, - DHCPV6_OPTION_CODE_SOL_MAX_RT = 82, - DHCPV6_OPTION_CODE_INF_MAX_RT = 83, -}; - -/* DHCPv6 option codes, RFC8415, ch. 21.13. */ -enum dhcpv6_status_code { - DHCPV6_STATUS_SUCCESS = 0, - DHCPV6_STATUS_UNSPEC_FAIL = 1, - DHCPV6_STATUS_NO_ADDR_AVAIL = 2, - DHCPV6_STATUS_NO_BINDING = 3, - DHCPV6_STATUS_NOT_ON_LINK = 4, - DHCPV6_STATUS_USE_MULTICAST = 5, - DHCPV6_STATUS_NO_PREFIX_AVAIL = 6, -}; - -/* DHCPv6 Unique Identifier types, RFC8415, ch. 11.1. */ -enum dhcpv6_duid_type { - DHCPV6_DUID_TYPE_LLT = 1, /* Based on Link-Layer Address Plus Time */ - DHCPV6_DUID_TYPE_EN = 2, /* Assigned by Vendor Based on Enterprise Number */ - DHCPV6_DUID_TYPE_LL = 3, /* Based on Link-Layer Address */ - DHCPV6_DUID_TYPE_UUID = 4, /* Based on Universally Unique Identifier */ -}; - -#if defined(CONFIG_NET_DHCPV6) -int net_dhcpv6_init(void); -#else -static inline int net_dhcpv6_init(void) -{ - return 0; -} -#endif /* CONFIG_NET_DHCPV6 */ - -#endif /* DHCPV6_INTERNAL_H_ */ diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index c94607b4485..00829dfcf90 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -45,7 +45,6 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL); #include "ipv4.h" #include "dhcpv4.h" -#include "dhcpv6_internal.h" #include "route.h" @@ -476,11 +475,6 @@ static inline int services_init(void) return status; } - status = net_dhcpv6_init(); - if (status != 0) { - return status; - } - dns_init_resolver(); websocket_init(); From 935c78e222eda7fb0dd612b1d201e6ae7efba7ba Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:32 +0000 Subject: [PATCH 4314/4498] Revert "[nrf noup] mgmt/MCUmgr/grp/img: Move out label to make compiler happy" This reverts commit 45ac1f809fef282566c124dc676c951428d707bc. Signed-off-by: Dominik Ermel --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 61515c14655..0968694c614 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -290,14 +290,13 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) return_slot = other_slot; } } -out: - #else if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &over) < 0) { return_slot = other_slot; } #endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ +out: if (type != NULL) { *type = lt; } From 965571eb172a2c9e2c273b88699227708ef537bd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:33 +0000 Subject: [PATCH 4315/4498] Revert "[nrf fromtree] modules/MCUboot: Fix missing dependency" This reverts commit 8b829dcc8fdcd8d95fea171110fb3bec07a6f616. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 1679bfeb8a9..ab1dd44fbd5 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -192,7 +192,6 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT bool "MCUboot has been configured for DirectXIP with revert" select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP - select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. From 57324dc7a033224bbedc0fca1a4199f95b7fc0cb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:33 +0000 Subject: [PATCH 4316/4498] Revert "[nrf fromtree] doc/release-notes: Add info on downgrade prevention Kconfig" This reverts commit c43324fe1614052517c8037351231e715c7f7d18. Signed-off-by: Dominik Ermel --- doc/releases/release-notes-3.5.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index d22978d8a84..4f9a8ab1793 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -339,11 +339,6 @@ HALs MCUboot ******* - * Added :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_NO_DOWNGRADE` - that allows to inform application that the on-board MCUboot has been configured - with downgrade prevention enabled. This option is automatically selected for - DirectXIP mode and is available for both swap modes. - Storage ******* From ecac00de5e846efacfef81312cb7cdb7964dc8ec Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:34 +0000 Subject: [PATCH 4317/4498] Revert "[nrf fromtree] modules/MCUboot: Add new Kconfig indicating downgrade prevention" This reverts commit 8f6ede70c0db2e328b72e350ec5e6b79040d557c. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index ab1dd44fbd5..5f83098a577 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -116,7 +116,7 @@ config MCUBOOT_EXTRA_IMGTOOL_ARGS help When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty string) you can use this option to pass extra options to - imgtool. For example, you could set this to "--version 1.2". + imgtool. For example, you could set this to "--version 1.2". config MCUBOOT_GENERATE_UNSIGNED_IMAGE bool "Generate unsigned binary image bootable with MCUboot" @@ -136,8 +136,6 @@ config MCUBOOT_GENERATE_CONFIRMED_IMAGE The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN and CONFIG_BUILD_OUTPUT_HEX. -menu "On board MCUboot operation mode" - choice MCUBOOT_BOOTLOADER_MODE prompt "Application assumed MCUboot mode of operation" default MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH # MCUBOOT_BOOTLOADER_MODE @@ -156,43 +154,31 @@ config MCUBOOT_BOOTLOADER_MODE_SINGLE_APP config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH bool "MCUboot has been configured for swap without scratch operation" - select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to be present in DT and application will boot from slot0_partition. - MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected - if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH bool "MCUboot has been configured for swap using scratch operation" - select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE help MCUboot expects slot0_partition, slot1_partition and scratch_partition to be present in DT, and application will boot from slot0_partition. In this mode scratch_partition is used as temporary storage when MCUboot swaps application from the secondary slot to the primary slot. - MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected - if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP bool "MCUboot has been configured for DirectXIP operation" - select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE - select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. In this mode MCUboot can boot from either partition and will select one with higher application image version, which usually means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER is also selected that enables comparison of build number. - This option automatically selectes - MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible - to swap back to older version of application. config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT bool "MCUboot has been configured for DirectXIP with revert" select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP - select MCUBOOT_BOOTLOADER_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to exist in DT. In this mode MCUboot will boot the application with the higher version @@ -204,30 +190,9 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT This mode does not allow freely switching between application versions, as, once higher version application is approved, it is not possible to select lower version for boot. - This mode selects MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible - to downgrade running application, but note that MCUboot may do that - if application with higher version will not get confirmed. endchoice # MCUBOOT_BOOTLOADER_MODE -config MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE - bool - help - Selected mode supports downgrade prevention, where you cannot switch to - an application with lower version than the currently running application. - -if MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE -config MCUBOOT_BOOTLOADER_NO_DOWNGRADE - bool "MCUboot mode has downgrade prevention enabled" - help - Selected MCUboot mode has downgrade prevention enabled, where you are not - able to change back to image with lower version number. - This options should be selected when MCUboot has been built with - MCUBOOT_DOWNGRADE_PREVENTION option enabled. -endif - -endmenu # On board MCUboot operation mode - endif # BOOTLOADER_MCUBOOT menuconfig MCUBOOT_BOOTUTIL_LIB From 8c2b4befd3c7ee478fb83f8d9e2371812ac5d8d9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:34 +0000 Subject: [PATCH 4318/4498] Revert "[nrf fromtree] samples/mcumgr/smp_svr: Build for DirectXIP with revert" This reverts commit 0e63631f6734ba12b8d5a8c02eeb706796d9f046. Signed-off-by: Dominik Ermel --- samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index a13270e5845..ed7ffe8f33e 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -43,19 +43,6 @@ tests: - mg100 integration_platforms: - nrf52840dk_nrf52840 - # In mcuboot_flags test overlay-serial.conf is used for convenience as it is the simplest - # transport. Transport does not affect flags so it does not really matter which is selected, - # flags should affect any transport the same way. - sample.mcumgr.smp_svr.mcuboot_flags.direct_xip_withrevert: - extra_args: OVERLAY_CONFIG="overlay-serial.conf" - extra_configs: - - CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT=y - platform_allow: - - nrf52840dk_nrf52840 - - pinnacle_100_dvk - - mg100 - integration_platforms: - - nrf52840dk_nrf52840 sample.mcumgr.smp_svr.serial-console: extra_args: OVERLAY_CONFIG="overlay-serial-console.conf" platform_allow: From 8dbb168dd4d4bf2ce58a0163273eb399c2d82ad0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:34 +0000 Subject: [PATCH 4319/4498] Revert "[nrf fromtree] mgmt/MCUmgr/grp/img: Add support for DirectXIP with revert" This reverts commit 38f9d7e6f240c55d996e510e9a9d5deca27753cd. Signed-off-by: Dominik Ermel --- modules/Kconfig.mcuboot | 24 --- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 201 ++++-------------- 2 files changed, 40 insertions(+), 185 deletions(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 5f83098a577..0bb47d8854c 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -176,21 +176,6 @@ config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER is also selected that enables comparison of build number. -config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT - bool "MCUboot has been configured for DirectXIP with revert" - select MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP - help - MCUboot expects slot0_partition and slot1_partition to exist in DT. - In this mode MCUboot will boot the application with the higher version - from either slot, as long as it has been marked to be boot - next time for test or permanently. In case when application is marked - for test it needs to confirm itself, on the first boot, or it will - be removed and MCUboot will revert to booting previously approved - application. - This mode does not allow freely switching between application - versions, as, once higher version application is approved, it is - not possible to select lower version for boot. - endchoice # MCUBOOT_BOOTLOADER_MODE endif # BOOTLOADER_MCUBOOT @@ -223,13 +208,4 @@ config BOOT_IMAGE_ACCESS_HOOKS It is up to the application project to add source file which implements hooks to the build. -if MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT - -config MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP - bool - help - Adds support for setting for test and confirming images - when bootloader is in DirectXIP-revert mode. -endif - endif # MCUBOOT_BOOTUTIL_LIB diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 0968694c614..a782acb92ee 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -55,14 +55,6 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); #define REPORT_SLOT_PENDING BIT(1) #define REPORT_SLOT_CONFIRMED BIT(2) #define REPORT_SLOT_PERMANENT BIT(3) - -#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) -#define DIRECT_XIP_BOOT_UNSET 0 -#define DIRECT_XIP_BOOT_ONCE 1 -#define DIRECT_XIP_BOOT_REVERT 2 -#define DIRECT_XIP_BOOT_FOREVER 3 -#endif - /** * Collects information about the specified image slot. */ @@ -147,8 +139,7 @@ img_mgmt_state_flags(int query_slot) } #endif -#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \ - !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) +#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) { const int active_slot = img_mgmt_active_slot(image); @@ -197,115 +188,27 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) return slot; } #else - -#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) - -static int read_directxip_state(int slot) -{ - struct boot_swap_state bss; - int fa_id = img_mgmt_flash_area_id(slot); - const struct flash_area *fa; - int rc = 0; - - __ASSERT(fa_id != -1, "Could not map slot to area ID"); - - rc = flash_area_open(fa_id, &fa); - if (rc < 0) { - return rc; - } - rc = boot_read_swap_state(fa, &bss); - flash_area_close(fa); - if (rc != 0) { - LOG_ERR("Failed to read state of slot %d with error %d", slot, rc); - return -1; - } - - if (bss.magic == BOOT_MAGIC_GOOD) { - if (bss.image_ok == BOOT_FLAG_SET) { - return DIRECT_XIP_BOOT_FOREVER; - } else if (bss.copy_done == BOOT_FLAG_SET) { - return DIRECT_XIP_BOOT_REVERT; - } - return DIRECT_XIP_BOOT_ONCE; - } - return DIRECT_XIP_BOOT_UNSET; -} -#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ - int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) { struct image_version aver; struct image_version over; int active_slot = img_mgmt_active_slot(image); int other_slot = img_mgmt_get_opposite_slot(active_slot); -#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) - int active_slot_state; - int other_slot_state; -#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ - enum img_mgmt_next_boot_type lt = NEXT_BOOT_TYPE_NORMAL; - int return_slot = active_slot; + if (type != NULL) { + *type = NEXT_BOOT_TYPE_NORMAL; + } int rcs = img_mgmt_read_info(other_slot, &over, NULL, NULL); int rca = img_mgmt_read_info(active_slot, &aver, NULL, NULL); -#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) - active_slot_state = read_directxip_state(active_slot); - other_slot_state = read_directxip_state(other_slot); - if (rca != 0 || - (rcs != 0 && rcs != IMG_MGMT_ERR_NO_IMAGE)) { - /* We do not really know what will happen, as we can not - * read states from bootloader. - */ - LOG_ERR("img_mgmt_read_info_failed rca = %d, rcs = %d", - rca, rcs); - goto out; - } - if (other_slot_state < 0 || active_slot_state < 0) { - LOG_ERR("Slot state read failed with status: active %d, other %d", - active_slot_state, other_slot_state); - /* We do not really know what will happen, as we can not - * read states from bootloader. - */ - goto out; - } - - /* There is not other image, the active one will boot next time */ - if (rcs == IMG_MGMT_ERR_NO_IMAGE) { - goto out; - } - - if (active_slot_state == DIRECT_XIP_BOOT_REVERT) { - lt = NEXT_BOOT_TYPE_REVERT; - return_slot = other_slot; - } else if (other_slot_state == DIRECT_XIP_BOOT_UNSET) { - if (active_slot_state == DIRECT_XIP_BOOT_ONCE) { - lt = NEXT_BOOT_TYPE_TEST; - } - } else if (img_mgmt_vercmp(&aver, &over) < 0) { - if (other_slot_state == DIRECT_XIP_BOOT_FOREVER) { - return_slot = other_slot; - } else if (other_slot_state == DIRECT_XIP_BOOT_ONCE) { - lt = NEXT_BOOT_TYPE_TEST; - return_slot = other_slot; - } - } -#else if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &over) < 0) { - return_slot = other_slot; + return other_slot; } -#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ -out: - if (type != NULL) { - *type = lt; - } - - return return_slot; + return active_slot; } -#endif /* !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \ - * !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) - */ +#endif /** @@ -519,53 +422,11 @@ img_mgmt_state_read(struct smp_streamer *ctxt) return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } -static int img_mgmt_set_next_boot_slot_common(int slot, int active_slot, bool confirm) +int img_mgmt_set_next_boot_slot(int slot, bool confirm) { const struct flash_area *fa; int area_id = img_mgmt_flash_area_id(slot); int rc = 0; - - if (flash_area_open(area_id, &fa) != 0) { - return IMG_MGMT_ERR_FLASH_OPEN_FAILED; - } - - rc = boot_set_next(fa, slot == active_slot, confirm); - if (rc != 0) { - /* Failed to set next slot for boot as desired */ - LOG_ERR("Faled boot_set_next with code %d, for slot %d," - " with active slot %d and confirm %d", - rc, slot, active_slot, confirm); - - /* Translate from boot util error code to IMG mgmt group error code */ - if (rc == BOOT_EFLASH) { - rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED; - } else if (rc == BOOT_EBADVECT) { - rc = IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE; - } else if (rc == BOOT_EBADIMAGE) { - rc = IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC; - } else { - rc = IMG_MGMT_ERR_UNKNOWN; - } - } - flash_area_close(fa); - -#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) - if (rc == 0 && slot == active_slot && confirm) { - int32_t err_rc; - uint16_t err_group; - - /* Confirm event is only sent for active slot */ - (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0, &err_rc, - &err_group); - } -#endif - - return rc; -} - -#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT -int img_mgmt_set_next_boot_slot(int slot, bool confirm) -{ /* image the requested slot is defined within */ int image = img_mgmt_slot_to_image(slot); /* active_slot is slot that is considered active/primary/executing @@ -637,26 +498,44 @@ int img_mgmt_set_next_boot_slot(int slot, bool confirm) /* Allow confirming slot == active_slot */ } - return img_mgmt_set_next_boot_slot_common(slot, active_slot, confirm); -} -#else -int img_mgmt_set_next_boot_slot(int slot, bool confirm) -{ - int active_image = img_mgmt_active_image(); - int active_slot = img_mgmt_active_slot(active_image); + if (flash_area_open(area_id, &fa) != 0) { + return IMG_MGMT_ERR_FLASH_OPEN_FAILED; + } - LOG_DBG("(%d, %s)", slot, confirm ? "confirm" : "test"); - LOG_DBG("aimg = %d, aslot = %d, slot = %d", - active_image, active_slot, slot); + rc = boot_set_next(fa, slot == active_slot, confirm); + if (rc != 0) { + /* Failed to set next slot for boot as desired */ + LOG_ERR("Faled boot_set_next with code %d, for slot %d," + " with active slot %d and confirm %d", + rc, slot, active_slot, confirm); - if (slot == active_slot && !confirm) { - return IMG_MGMT_ERR_IMAGE_SETTING_TEST_TO_ACTIVE_DENIED; + /* Translate from boot util error code to IMG mgmt group error code */ + if (rc == BOOT_EFLASH) { + rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED; + } else if (rc == BOOT_EBADVECT) { + rc = IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE; + } else if (rc == BOOT_EBADIMAGE) { + rc = IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC; + } else { + rc = IMG_MGMT_ERR_UNKNOWN; + } } + flash_area_close(fa); - return img_mgmt_set_next_boot_slot_common(slot, active_slot, confirm); -} +#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) + if (slot == active_slot && confirm) { + int32_t err_rc; + uint16_t err_group; + + /* Confirm event is only sent for active slot */ + (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0, &err_rc, + &err_group); + } #endif + return rc; +} + /** * Command handler: image state write */ From 0780e653d8c7bd98ea40edf7a360b83f48c71a8a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:35 +0000 Subject: [PATCH 4320/4498] Revert "[nrf fromtree] drivers/flash/nrf: Workaround for nrf91 errata 7" This reverts commit 885245b9c1eb4ecd0a3eb6825a70e97422ea2db9. Signed-off-by: Dominik Ermel --- drivers/flash/soc_flash_nrf.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index ea76ae1e3f8..f38492a41d1 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2023 Nordic Semiconductor ASA + * Copyright (c) 2017-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Linaro Limited * Copyright (c) 2016 Intel Corporation * @@ -121,26 +121,6 @@ static inline bool is_uicr_addr_valid(off_t addr, size_t len) #endif /* CONFIG_SOC_FLASH_NRF_UICR */ } -#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND) -static inline void nrf91_errata_7_enter(void) -{ - __disable_irq(); -} - -static inline void nrf91_errata_7_exit(void) -{ - __DSB(); - __enable_irq(); -} - -static void nrf_buffer_read_91_uicr(void *data, off_t addr, size_t len) -{ - nrf91_errata_7_enter(); - nrf_nvmc_buffer_read(data, (uint32_t)addr, len); - nrf91_errata_7_exit(); -} -#endif - static void nvmc_wait_ready(void) { while (!nrfx_nvmc_write_done_check()) { @@ -150,11 +130,9 @@ static void nvmc_wait_ready(void) static int flash_nrf_read(const struct device *dev, off_t addr, void *data, size_t len) { - const bool within_uicr = is_uicr_addr_valid(addr, len); - if (is_regular_addr_valid(addr, len)) { addr += DT_REG_ADDR(SOC_NV_FLASH_NODE); - } else if (!within_uicr) { + } else if (!is_uicr_addr_valid(addr, len)) { LOG_ERR("invalid address: 0x%08lx:%zu", (unsigned long)addr, len); return -EINVAL; @@ -169,12 +147,6 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return soc_secure_mem_read(data, (void *)addr, len); } #endif -#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND) - if (within_uicr) { - nrf_buffer_read_91_uicr(data, (uint32_t)addr, len); - return 0; - } -#endif nrf_nvmc_buffer_read(data, (uint32_t)addr, len); From 7700c8b43fa015e8643ba7d6dc5fd5495ce7f70e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:35 +0000 Subject: [PATCH 4321/4498] Revert "[nrf fromtree] twister: pytest: Allow list of pytest testpaths" This reverts commit 29ccece157fa10782a41b8fa1eee15759174e24d. Signed-off-by: Dominik Ermel --- scripts/pylib/twister/twisterlib/harness.py | 5 +- scripts/schemas/twister/testsuite-schema.yaml | 8 +-- .../pytest_integration/test_harness_pytest.py | 61 ------------------- 3 files changed, 4 insertions(+), 70 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 6ae2622c810..96b4a2e3461 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -245,20 +245,19 @@ def pytest_run(self, timeout): def generate_command(self): config = self.instance.testsuite.harness_config - pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] + pytest_root = config.get('pytest_root', 'pytest') if config else 'pytest' pytest_args = config.get('pytest_args', []) if config else [] command = [ 'pytest', '--twister-harness', '-s', '-v', + os.path.join(self.source_dir, pytest_root), f'--build-dir={self.running_dir}', f'--junit-xml={self.report_file}', '--log-file-level=DEBUG', '--log-file-format=%(asctime)s.%(msecs)d:%(levelname)s:%(name)s: %(message)s', f'--log-file={self.pytest_log_file_path}' ] - command.extend([os.path.normpath(os.path.join( - self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) command.extend(pytest_args) handler: Handler = self.instance.handler diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 96a121767a5..116c1a43379 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -95,10 +95,8 @@ mapping: type: int required: false "pytest_root": - type: seq + type: str required: false - sequence: - - type: str "pytest_args": type: seq required: false @@ -295,10 +293,8 @@ mapping: type: int required: false "pytest_root": - type: seq + type: str required: false - sequence: - - type: str "pytest_args": type: seq required: false diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index e1b27a0cf02..db7bf389fbd 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -48,67 +48,6 @@ def test_pytest_command(testinstance: TestInstance, device_type): assert c in command -@pytest.mark.parametrize( - ('pytest_root', 'expected'), - [ - ( - ['pytest/test_shell_help.py'], - ['samples/hello/pytest/test_shell_help.py'] - ), - ( - ['pytest/test_shell_help.py', 'pytest/test_shell_version.py', 'test_dir'], - ['samples/hello/pytest/test_shell_help.py', - 'samples/hello/pytest/test_shell_version.py', - 'samples/hello/test_dir'] - ), - ( - ['../shell/pytest/test_shell.py'], - ['samples/shell/pytest/test_shell.py'] - ), - ( - ['/tmp/test_temp.py'], - ['/tmp/test_temp.py'] - ), - ( - ['~/tmp/test_temp.py'], - ['/home/joe/tmp/test_temp.py'] - ), - ( - ['$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest'], - ['/zephyr_base/samples/subsys/testsuite/pytest/shell/pytest'] - ), - ( - ['pytest/test_shell_help.py::test_A', 'pytest/test_shell_help.py::test_B'], - ['samples/hello/pytest/test_shell_help.py::test_A', - 'samples/hello/pytest/test_shell_help.py::test_B'] - ), - ( - ['pytest/test_shell_help.py::test_A[param_a]'], - ['samples/hello/pytest/test_shell_help.py::test_A[param_a]'] - ) - ], - ids=[ - 'one_file', - 'more_files', - 'relative_path', - 'absollute_path', - 'user_dir', - 'with_env_var', - 'subtests', - 'subtest_with_param' - ] -) -def test_pytest_handle_source_list(testinstance: TestInstance, monkeypatch, pytest_root, expected): - monkeypatch.setenv('ZEPHYR_BASE', '/zephyr_base') - monkeypatch.setenv('HOME', '/home/joe') - testinstance.testsuite.harness_config['pytest_root'] = pytest_root - pytest_harness = Pytest() - pytest_harness.configure(testinstance) - command = pytest_harness.generate_command() - for pytest_src in expected: - assert pytest_src in command - - def test_if_report_is_parsed(pytester, testinstance: TestInstance): test_file_content = textwrap.dedent(""" def test_1(): From 8eb0b81f23fd53225fd9914e64569d9541448cde Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:35 +0000 Subject: [PATCH 4322/4498] Revert "[nrf fromtree] twister: doc: Update pytest and twister docs" This reverts commit 801a64e6d1acfaac7bf1f5ebb2d647500464186e. Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 55 +++++++++++++----------------------- doc/develop/test/twister.rst | 26 ++++++----------- 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index d0fad4d6be6..97737ce0ae2 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -49,47 +49,28 @@ How to create a pytest test An example of a pytest test is given at :zephyr_file:`samples/subsys/testsuite/pytest/shell/pytest/test_shell.py`. Twister calls pytest for each configuration from the .yaml file which uses ``harness: pytest``. By default, it points to ``pytest`` directory, located next to a directory with binary sources. -A keyword ``pytest_root`` placed under ``harness_config`` section can be used to point to other -files, directories or subtests. +A keyword ``pytest_root`` placed under ``harness_config`` section can be used to point to another +location. -Pytest scans the given locations looking for tests, following its default +Pytest scans the given folder looking for tests, following its default `discovery rules `_ One can also pass some extra arguments to the pytest from yaml file using ``pytest_args`` keyword under ``harness_config``, e.g.: ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. -Helpers & fixtures -================== - -dut ---- - -Give access to a DeviceAdapter type object, that represents Device Under Test. -This fixture is the core of pytest harness plugin. It is required to launch -DUT (initialize logging, flash device, connect serial etc). -This fixture yields a device prepared according to the requested type -(native posix, qemu, hardware, etc.). All types of devices share the same API. -This allows for writing tests which are device-type-agnostic. +Following import is required to include in .py sources: .. code-block:: python - from twister_harness import DeviceAdapter - - def test_sample(dut: DeviceAdapter): - dut.readlines_until('Hello world') - -shell ------ + from twister_harness import Device -Provide an object with methods used to interact with shell application. -It calls `wait_for_promt` method, to not start scenario until DUT is ready. -Note that it uses `dut` fixture, so `dut` can be skipped when `shell` is used. +It is important for type checking and enabling IDE hints for ``dut`` s (objects representing +Devices Under Test). The ``dut`` fixture is the core of pytest harness plugin. When used as an +argument of a test function it gives access to a DeviceAbstract type object. The fixture yields a +device prepared according to the requested type (native posix, qemu, hardware, etc.). All types of +devices share the same API. This allows for writing tests which are device-type-agnostic. -.. code-block:: python - - from twister_harness import Shell - - def test_shell(shell: Shell): - shell.exec_command('help') +Helpers & fixtures +================== mcumgr ------ @@ -101,15 +82,16 @@ More information about MCUmgr can be found here :ref:`mcu_mgr`. This fixture requires the ``mcumgr`` available in the system PATH Only selected functionality of MCUmgr is wrapped by this fixture. + For example, here is a test with a fixture ``mcumgr`` .. code-block:: python - from twister_harness import DeviceAdapter, Shell, McuMgr + from twister_harness import Device, McuMgr - def test_upgrade(dut: DeviceAdapter, shell: Shell, mcumgr: McuMgr): - # free the serial port for mcumgr - dut.disconnect() + def test_upgrade(dut: Device, mcumgr: McuMgr): + # wait for dut is up + time.sleep(2) # upload the signed image mcumgr.image_upload('path/to/zephyr.signed.bin') # obtain the hash of uploaded image from the device @@ -123,4 +105,7 @@ For example, here is a test with a fixture ``mcumgr`` Limitations *********** +* Device adapters in pytest plugin provide `iter_stdout` method to read from devices. In some + cases, it is not the most convenient way, and it will be considered how to improve this + (for example replace it with a simple read function with a given byte size and timeout arguments). * Not every platform type is supported in the plugin (yet). diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 4456386b77c..a29890c7899 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -492,11 +492,10 @@ harness_config: Only one fixture can be defined per testcase and the fixture name has to be unique across all tests in the test suite. - pytest_root: (default pytest) - Specify a list of pytest directories, files or subtests that need to be executed - when test case begin to running, default pytest directory is pytest. - After pytest finished, twister will check if this case pass or fail according - to the pytest report. + pytest_root: (default pytest) + Specify a pytest directory which need to execute when test case begin to running, + default pytest directory name is pytest, after pytest finished, twister will + check if this case pass or fail according the pytest report. pytest_args: (default empty) Specify a list of additional arguments to pass to ``pytest``. @@ -527,24 +526,15 @@ harness_config: The following is an example yaml file with pytest harness_config options, default pytest_root name "pytest" will be used if pytest_root not specified. - please refer the examples in samples/subsys/testsuite/pytest/. + please refer the example in samples/subsys/testsuite/pytest/. :: - common: - harness: pytest tests: - pytest.example.directories: - harness_config: - pytest_root: - - pytest_dir1 - - $ENV_VAR/samples/test/pytest_dir2 - pytest.example.files_and_subtests: + pytest.example: + harness: pytest harness_config: - pytest_root: - - pytest/test_file_1.py - - test_file_2.py::test_A - - test_file_2.py::test_B[param_a] + pytest_root: [pytest directory name] The following is an example yaml file with robot harness_config options. From b368cf97e5780cc7bee67543c37875029a9c27de Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:35 +0000 Subject: [PATCH 4323/4498] Revert "[nrf fromtree] twister: pytest: Fix problems with no prompt in tests with shell" This reverts commit 90d276b0cd557bf7f3e35119e43106b09681194e. Signed-off-by: Dominik Ermel --- .../src/twister_harness/device/hardware_adapter.py | 1 - .../pytest-twister-harness/src/twister_harness/helpers/shell.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 403978eed9a..3a3f242fa85 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -250,7 +250,6 @@ def _clear_internal_resources(self) -> None: super()._clear_internal_resources() self._serial_connection = None self._serial_pty_proc = None - self._serial_buffer.clear() @staticmethod def _run_custom_script(script_path: str | Path, timeout: float) -> None: diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index 37f8ad432cf..fc8009d12fe 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -57,7 +57,7 @@ def exec_command(self, command: str, timeout: float | None = None, print_output: timeout = timeout or self.base_timeout command_ext = f'{command}\n\n' regex_prompt = re.escape(self.prompt) - regex_command = f'.*{command}' + regex_command = f'{regex_prompt}.*{command}' self._device.clear_buffer() self._device.write(command_ext.encode()) lines: list[str] = [] From 7d756d53d9e6a05c31e749c4cf18364a9777b333 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:36 +0000 Subject: [PATCH 4324/4498] Revert "[nrf fromtree] scripts: domains: Convert Domain to a dataclass" This reverts commit 2cdbabc898855f447b8f17cd81548b16dfb6d045. Signed-off-by: Dominik Ermel --- scripts/pylib/build_helpers/domains.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 978569d9547..475844e9a61 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -8,8 +8,6 @@ Domain class. ''' -from dataclasses import dataclass - import yaml import pykwalify.core import logging @@ -121,8 +119,24 @@ def get_top_build_dir(self): return self._build_dir -@dataclass class Domain: - name: str - build_dir: str + def __init__(self, name, build_dir): + self.name = name + self.build_dir = build_dir + + @property + def name(self): + return self._name + + @name.setter + def name(self, value): + self._name = value + + @property + def build_dir(self): + return self._build_dir + + @build_dir.setter + def build_dir(self, value): + self._build_dir = value From 6fe9c05faad898fb5eabdcbe4159afa9a9a359a3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:36 +0000 Subject: [PATCH 4325/4498] Revert "[nrf fromtree] scripts: domains: Support initialization only from YAML" This reverts commit f943f54c83a9ae04467dccdb01b33707bdcfffc0. Signed-off-by: Dominik Ermel --- scripts/pylib/build_helpers/domains.py | 32 ++++++++++++++------------ scripts/west_commands/build_helpers.py | 13 ++++------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 475844e9a61..f4c2f085fd2 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -56,15 +56,7 @@ class Domains: - def __init__(self, domains_yaml): - try: - data = yaml.safe_load(domains_yaml) - pykwalify.core.Core(source_data=data, - schema_data=schema).validate() - except (yaml.YAMLError, pykwalify.errors.SchemaError): - logger.critical(f'malformed domains.yaml') - exit(1) - + def __init__(self, data): self._build_dir = data['build_dir'] self._domains = { d['name']: Domain(d['name'], d['build_dir']) @@ -80,22 +72,32 @@ def __init__(self, domains_yaml): @staticmethod def from_file(domains_file): - '''Load domains from a domains.yaml file. + '''Load domains from domains.yaml. + + Exception raised: + - ``FileNotFoundError`` if the domains file is not found. ''' try: with open(domains_file, 'r') as f: - domains_yaml = f.read() + domains = yaml.safe_load(f.read()) except FileNotFoundError: logger.critical(f'domains.yaml file not found: {domains_file}') exit(1) - return Domains(domains_yaml) + try: + pykwalify.core.Core(source_data=domains, schema_data=schema)\ + .validate() + except pykwalify.errors.SchemaError: + logger.critical(f'ERROR: Malformed yaml in file: {domains_file}') + exit(1) + + return Domains(domains) @staticmethod - def from_yaml(domains_yaml): - '''Load domains from a string with YAML contents. + def from_data(domains_data): + '''Load domains from domains dictionary. ''' - return Domains(domains_yaml) + return Domains(domains_data) def get_domains(self, names=None, default_flash_order=False): if names is None: diff --git a/scripts/west_commands/build_helpers.py b/scripts/west_commands/build_helpers.py index ca6845f01da..88845e50f4b 100644 --- a/scripts/west_commands/build_helpers.py +++ b/scripts/west_commands/build_helpers.py @@ -151,14 +151,9 @@ def load_domains(path): domains_file = Path(path) / 'domains.yaml' if not domains_file.is_file(): - return Domains.from_yaml(f'''\ -default: app -build_dir: {path} -domains: - - name: app - build_dir: {path} -flash_order: - - app -''') + return Domains.from_data({'default': 'app', + 'build_dir': path, + 'domains': [{'name': 'app', 'build_dir': path}], + 'flash_order': ['app']}) return Domains.from_file(domains_file) From 6da59f61e5897b9205670be2e4555eb3e7ca95f5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:36 +0000 Subject: [PATCH 4326/4498] Revert "[nrf fromtree] scripts: domains: Tighten up initialization" This reverts commit 6df09b137cd799e5fdc1ef2371a70609f175e8c4. Signed-off-by: Dominik Ermel --- scripts/pylib/build_helpers/domains.py | 39 ++++++++++++++------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index f4c2f085fd2..8cacac7b4e8 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -27,7 +27,7 @@ required: true type: str domains: - required: true + required: false type: seq sequence: - type: map @@ -57,18 +57,19 @@ class Domains: def __init__(self, data): - self._build_dir = data['build_dir'] + self._build_dir = data.get('build_dir') + domain_list = data.get('domains') or [] + if not domain_list: + logger.warning("no domains defined; this probably won't work") + self._domains = { d['name']: Domain(d['name'], d['build_dir']) - for d in data['domains'] + for d in domain_list } + self._default_domain = self._domains.get(data['default']) - # In the YAML data, the values for "default" and "flash_order" - # must not name any domains that aren't listed under "domains". - # Now that self._domains has been initialized, we can leverage - # the common checks in self.get_domain to verify this. - self._default_domain = self.get_domain(data['default']) - self._flash_order = self.get_domains(data['flash_order'] or []) + domains_flash_order = data.get('flash_order') or [] + self._flash_order = list(map(self._domains.get, domains_flash_order)) @staticmethod def from_file(domains_file): @@ -100,19 +101,21 @@ def from_data(domains_data): return Domains(domains_data) def get_domains(self, names=None, default_flash_order=False): - if names is None: + ret = [] + + if not names: if default_flash_order: return self._flash_order return list(self._domains.values()) - return list(map(self.get_domain, names)) - def get_domain(self, name): - found = self._domains.get(name) - if not found: - logger.critical(f'domain "{name}" not found, ' - f'valid domains are: {", ".join(self._domains)}') - exit(1) - return found + for n in names: + found = self._domains.get(n) + if not found: + logger.critical(f'domain {n} not found, ' + f'valid domains are: {", ".join(self._domains)}') + exit(1) + ret.append(found) + return ret def get_default_domain(self): return self._default_domain From 9fbef9dff521ac56b93f07da59e262653457421f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:36 +0000 Subject: [PATCH 4327/4498] Revert "[nrf fromtree] doc: sysbuild: Update documentation about BUILD_ONLY" This reverts commit 49df79f70077cc7a69125e7c9812c2764c24a501. Signed-off-by: Dominik Ermel --- doc/build/sysbuild/index.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index e09ee3e5617..2c53cb0e88a 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -569,19 +569,13 @@ You can mark ``my_sample`` as a build-only application in this manner: ) As a result, ``my_sample`` will be built as part of the sysbuild build invocation, -but it will be excluded from the default image sequence used by ``west flash``. +but neither ``west flash`` nor ``west debug`` will be aware of this application. Instead, you may use the outputs of this domain for other purposes - for example, to produce a secondary image for DFU, or to merge multiple images together. You can also replace ``TRUE`` with another boolean constant in CMake, such as a Kconfig option, which would make ``my_sample`` conditionally build-only. -.. note:: - - Applications marked as build-only can still be flashed manually, using - ``west flash --domain my_sample``. As such, the ``BUILD_ONLY`` option only - controls the default behavior of ``west flash``. - Zephyr application configuration ================================ From 3f299762f7e08675dd17ef898b0dddc63e211e2a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:37 +0000 Subject: [PATCH 4328/4498] Revert "[nrf fromtree] sysbuild: Do not exclude images from domains.yaml" This reverts commit 020dcdc2ab9118bf2960ef1feb396b79e6924b77. Signed-off-by: Dominik Ermel --- scripts/pylib/build_helpers/domains.py | 43 +++++++++++++------------- scripts/west_commands/build_helpers.py | 3 +- scripts/west_commands/flash.py | 3 +- share/sysbuild/cmake/domains.cmake | 11 +++---- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/scripts/pylib/build_helpers/domains.py b/scripts/pylib/build_helpers/domains.py index 8cacac7b4e8..c748a94a14f 100644 --- a/scripts/pylib/build_helpers/domains.py +++ b/scripts/pylib/build_helpers/domains.py @@ -38,11 +38,6 @@ build_dir: required: true type: str - flash_order: - required: false - type: seq - sequence: - - type: str ''' schema = yaml.safe_load(DOMAINS_SCHEMA) @@ -57,19 +52,21 @@ class Domains: def __init__(self, data): + self._domains = [] + self._domain_names = [] + self._domain_default = [] + self._build_dir = data.get('build_dir') - domain_list = data.get('domains') or [] + domain_list = data.get('domains') if not domain_list: logger.warning("no domains defined; this probably won't work") - self._domains = { - d['name']: Domain(d['name'], d['build_dir']) - for d in domain_list - } - self._default_domain = self._domains.get(data['default']) - - domains_flash_order = data.get('flash_order') or [] - self._flash_order = list(map(self._domains.get, domains_flash_order)) + for d in domain_list: + domain = Domain(d['name'], d['build_dir']) + self._domains.append(domain) + self._domain_names.append(domain.name) + if domain.name == data['default']: + self._default_domain = domain @staticmethod def from_file(domains_file): @@ -100,21 +97,25 @@ def from_data(domains_data): ''' return Domains(domains_data) - def get_domains(self, names=None, default_flash_order=False): + def get_domains(self, names=None): ret = [] if not names: - if default_flash_order: - return self._flash_order - return list(self._domains.values()) + return self._domains for n in names: - found = self._domains.get(n) + found = False + for d in self._domains: + if n == d.name: + ret.append(d) + found = True + break + # Getting here means the domain was not found. + # Todo: throw an error. if not found: logger.critical(f'domain {n} not found, ' - f'valid domains are: {", ".join(self._domains)}') + f'valid domains are:', *self._domain_names) exit(1) - ret.append(found) return ret def get_default_domain(self): diff --git a/scripts/west_commands/build_helpers.py b/scripts/west_commands/build_helpers.py index 88845e50f4b..e4352ff1f28 100644 --- a/scripts/west_commands/build_helpers.py +++ b/scripts/west_commands/build_helpers.py @@ -153,7 +153,6 @@ def load_domains(path): if not domains_file.is_file(): return Domains.from_data({'default': 'app', 'build_dir': path, - 'domains': [{'name': 'app', 'build_dir': path}], - 'flash_order': ['app']}) + 'domains': [{'name': 'app', 'build_dir': path}]}) return Domains.from_file(domains_file) diff --git a/scripts/west_commands/flash.py b/scripts/west_commands/flash.py index 4f173535be8..073a1ab2a28 100644 --- a/scripts/west_commands/flash.py +++ b/scripts/west_commands/flash.py @@ -28,6 +28,5 @@ def do_add_parser(self, parser_adder): def do_run(self, my_args, runner_args): build_dir = get_build_dir(my_args) - domains = load_domains(build_dir).get_domains(my_args.domain, - default_flash_order=True) + domains = load_domains(build_dir).get_domains(my_args.domain) do_run_common(self, my_args, runner_args, domains=domains) diff --git a/share/sysbuild/cmake/domains.cmake b/share/sysbuild/cmake/domains.cmake index 1d197059bf1..c46d261aff2 100644 --- a/share/sysbuild/cmake/domains.cmake +++ b/share/sysbuild/cmake/domains.cmake @@ -7,13 +7,12 @@ sysbuild_images_order(IMAGES_FLASHING_ORDER FLASH IMAGES ${IMAGES}) set(domains_yaml "default: ${DEFAULT_IMAGE}") set(domains_yaml "${domains_yaml}\nbuild_dir: ${CMAKE_BINARY_DIR}") set(domains_yaml "${domains_yaml}\ndomains:") -foreach(image ${IMAGES}) +foreach(image ${IMAGES_FLASHING_ORDER}) + get_target_property(image_is_build_only ${image} BUILD_ONLY) + if(image_is_build_only) + continue() + endif() set(domains_yaml "${domains_yaml}\n - name: ${image}") set(domains_yaml "${domains_yaml}\n build_dir: $") endforeach() -set(domains_yaml "${domains_yaml}\nflash_order:") -foreach(image ${IMAGES_FLASHING_ORDER}) - set(flash_cond "$>>") - set(domains_yaml "${domains_yaml}$<${flash_cond}:\n - ${image}>") -endforeach() file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/domains.yaml CONTENT "${domains_yaml}") From 19920767b1a2f83f0accd2d0a1ef5e78fa9fb589 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:37 +0000 Subject: [PATCH 4329/4498] Revert "[nrf fromtree] Bluetooth: documentation change of kconfig.iso configs" This reverts commit a977ac68d2b32f2c1c326c82467a6b3bf0d5882f. Signed-off-by: Dominik Ermel --- subsys/bluetooth/Kconfig.iso | 6 ------ 1 file changed, 6 deletions(-) diff --git a/subsys/bluetooth/Kconfig.iso b/subsys/bluetooth/Kconfig.iso index 304c408f42f..553ff3a7fb4 100644 --- a/subsys/bluetooth/Kconfig.iso +++ b/subsys/bluetooth/Kconfig.iso @@ -99,10 +99,6 @@ config BT_ISO_TX_MTU range 1 4095 help Maximum MTU for Isochronous channels TX buffers. - This is the actual data payload. It doesn't include the optional - HCI ISO Data packet fields (e.g. `struct bt_hci_iso_ts_data_hdr`). - Set this value to 247 to fit 247 bytes of data within a single - HCI ISO Data packet with a size of 255, without utilizing timestamps. config BT_ISO_RX_BUF_COUNT int "Number of Isochronous RX buffers" @@ -117,8 +113,6 @@ config BT_ISO_RX_MTU range 23 4095 help Maximum MTU for Isochronous channels RX buffers. - This is the actual data payload. It doesn't include the optional - HCI ISO Data packet fields (e.g. `struct bt_hci_iso_ts_data_hdr`) config BT_ISO_ADVANCED bool "Advanced ISO parameters" From 0c9b969be060d0b8975d5180d15665b31f7fb9fd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:37 +0000 Subject: [PATCH 4330/4498] Revert "[nrf fromtree] Bluetooth: fix iso_has_ts field for SDU fragmented to multiple HCI packets" This reverts commit f70cd160196e6e346321bb88243743eeb1c807a1. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/conn.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 0e355c36390..96bb2097854 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -711,7 +711,6 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) /* Fragments never have a TX completion callback */ tx_data(frag)->tx = NULL; tx_data(frag)->is_cont = false; - tx_data(frag)->iso_has_ts = tx_data(buf)->iso_has_ts; return frag; } From 78d59e1fc7287882f4fdc697a9325cb1b106fa07 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:37 +0000 Subject: [PATCH 4331/4498] Revert "[nrf fromtree] Bluetooth: fix HCI ISO Data packets fragmentation" This reverts commit 865d0bb25b68360e203d68069c2f964041944a12. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/conn.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 96bb2097854..82c3aa91e17 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -655,6 +655,21 @@ static int do_send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags return err; } +static size_t iso_hdr_len(struct net_buf *buf, struct bt_conn *conn) +{ +#if defined(CONFIG_BT_ISO) + if (conn->type == BT_CONN_TYPE_ISO) { + if (tx_data(buf)->iso_has_ts) { + return BT_HCI_ISO_TS_DATA_HDR_SIZE; + } else { + return BT_HCI_ISO_DATA_HDR_SIZE; + } + } +#endif + + return 0; +} + static int send_frag(struct bt_conn *conn, struct net_buf *buf, struct net_buf *frag, uint8_t flags) @@ -667,7 +682,9 @@ static int send_frag(struct bt_conn *conn, /* Add the data to the buffer */ if (frag) { - uint16_t frag_len = MIN(conn_mtu(conn), net_buf_tailroom(frag)); + size_t iso_hdr = flags == FRAG_START ? iso_hdr_len(buf, conn) : 0; + uint16_t frag_len = MIN(conn_mtu(conn) + iso_hdr, + net_buf_tailroom(frag)); net_buf_add_mem(frag, buf->data, frag_len); net_buf_pull(buf, frag_len); @@ -715,6 +732,11 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) return frag; } +static bool fits_single_ctlr_buf(struct net_buf *buf, struct bt_conn *conn) +{ + return buf->len - iso_hdr_len(buf, conn) <= conn_mtu(conn); +} + static int send_buf(struct bt_conn *conn, struct net_buf *buf) { struct net_buf *frag; @@ -724,7 +746,7 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf) LOG_DBG("conn %p buf %p len %u", conn, buf, buf->len); /* Send directly if the packet fits the ACL MTU */ - if (buf->len <= conn_mtu(conn) && !tx_data(buf)->is_cont) { + if (fits_single_ctlr_buf(buf, conn) && !tx_data(buf)->is_cont) { LOG_DBG("send single"); return send_frag(conn, buf, NULL, FRAG_SINGLE); } From 61e0cec37d90801fe7e4265c7015db4cea7782b9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:38 +0000 Subject: [PATCH 4332/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix num cmplt for BIS HCI ISO Data fragments" This reverts commit 355032b839e85838fdd50baee5b645fb038c5068. Signed-off-by: Dominik Ermel --- subsys/bluetooth/controller/ll_sw/ull.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 6be8bc4759e..2f325f1a86b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2582,10 +2582,18 @@ static uint8_t tx_cmplt_get(uint16_t *handle, uint8_t *first, uint8_t last) /* We must count each SDU HCI fragment */ tx_node = tx->node; if (IS_NODE_TX_PTR(tx_node)) { - /* We count each SDU fragment completed - * by this PDU. - */ - sdu_fragments = tx_node->sdu_fragments; + if (IS_ADV_ISO_HANDLE(tx->handle)) { + /* FIXME: ADV_ISO shall be updated to + * use ISOAL for TX. Until then, assume + * 1 node equals 1 fragment. + */ + sdu_fragments = 1U; + } else { + /* We count each SDU fragment completed + * by this PDU. + */ + sdu_fragments = tx_node->sdu_fragments; + } /* Replace node reference with fragments * count From e5701f9376b177770f41764f811b9af8bf8b5e9f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:38 +0000 Subject: [PATCH 4333/4498] Revert "[nrf fromtree] net: tcp: Fix goto condition in case of RST/packet error" This reverts commit 1907327297f59993d41f2f7f5af50968b0316289. Signed-off-by: Dominik Ermel --- subsys/net/ip/tcp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index ad9cd1e4c98..c90f7b92c20 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2276,7 +2276,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto out; + goto next_state; } if (FL(&fl, &, RST)) { @@ -2292,7 +2292,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) net_stats_update_tcp_seg_rst(net_pkt_iface(pkt)); do_close = true; close_status = -ECONNRESET; - goto out; + goto next_state; } if (tcp_options_len && !tcp_options_check(&conn->recv_options, pkt, @@ -2301,7 +2301,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto out; + goto next_state; } if (th && (conn->state != TCP_LISTEN) && (conn->state != TCP_SYN_SENT) && @@ -2316,7 +2316,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_out(conn, RST); do_close = true; close_status = -ECONNRESET; - goto out; + goto next_state; } if (th) { @@ -2904,7 +2904,6 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) tcp_state_to_str(conn->state, true)); } -out: if (pkt) { if (verdict == NET_OK) { net_pkt_unref(pkt); From 6c8e91bcb77abbbd7ebff3ecce0caf3190d2dd8d Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:38 +0000 Subject: [PATCH 4334/4498] Revert "[nrf fromlist] net: lwm2m: Allow configuring update period" This reverts commit bd268c7f0e0b6c301a34df53c0d41075dd844d3d. Signed-off-by: Dominik Ermel --- .../api/images/lwm2m_lifetime_both.png | Bin 17612 -> 0 bytes .../images/lwm2m_lifetime_seconds_early.png | Bin 14563 -> 0 bytes doc/connectivity/networking/api/lwm2m.rst | 47 ------------------ samples/net/lwm2m_client/overlay-queue.conf | 6 +-- subsys/net/lib/lwm2m/Kconfig | 12 +---- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 22 +++----- tests/net/lib/lwm2m/interop/prj.conf | 2 - .../lib/lwm2m/lwm2m_rd_client/CMakeLists.txt | 1 - 8 files changed, 8 insertions(+), 82 deletions(-) delete mode 100644 doc/connectivity/networking/api/images/lwm2m_lifetime_both.png delete mode 100644 doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png deleted file mode 100644 index 1cdf0bbb662965d525b6b24f6dade674d9b2f0fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17612 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 Il7{~O3l2&u4FCWD diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png deleted file mode 100644 index 119005ce5c7f0ea96030961a6f8c04cbf6ec4d11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14563 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 client.lifetime) { - early = client.lifetime; - } - - next = MIN(period, client.lifetime - early); - next = MAX(next, MINIMUM_PERIOD); - - return client.last_update + next * MSEC_PER_SEC; + /* + * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY + * so that we can update early and avoid lifetime timeout + */ + return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * MSEC_PER_SEC; } static int64_t next_rx_off(void) diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 66d6334264f..5d255e0513e 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -61,8 +61,6 @@ CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 # Use QUEUE mode by default CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 -CONFIG_LWM2M_UPDATE_PERIOD=30 -CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10 # LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 2a8e8959c25..81e129c56c1 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -32,4 +32,3 @@ add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_ENABLED=1) add_compile_definitions(CONFIG_LWM2M_TLS_SESSION_CACHING=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=1) -add_compile_definitions(CONFIG_LWM2M_UPDATE_PERIOD=0) From 6fb13649ad9a711b12c613b656900536836f062b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:39 +0000 Subject: [PATCH 4335/4498] Revert "[nrf fromlist] net: coap: release non-confirmable messages" This reverts commit db7577339d36b3f44997d478cb10207df51fc23a. Signed-off-by: Dominik Ermel --- subsys/net/lib/coap/coap_client.c | 79 +++++++++++++++++++--------- tests/net/lib/coap_client/src/main.c | 4 +- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index e78aafd6829..d096e39c62f 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -308,6 +308,12 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr reset_internal_request(internal_req); + if (retries == -1) { + internal_req->retry_count = DEFAULT_RETRY_AMOUNT; + } else { + internal_req->retry_count = retries; + } + if (k_mutex_lock(&client->send_mutex, K_NO_WAIT)) { return -EAGAIN; } @@ -326,26 +332,17 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr goto out; } - /* only TYPE_CON messages need pending tracking */ - if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { - if (retries == -1) { - internal_req->retry_count = DEFAULT_RETRY_AMOUNT; - } else { - internal_req->retry_count = retries; - } - - ret = coap_pending_init(&internal_req->pending, &internal_req->request, - &client->address, internal_req->retry_count); - - if (ret < 0) { - LOG_ERR("Failed to initialize pending struct"); - k_mutex_unlock(&client->send_mutex); - goto out; - } + ret = coap_pending_init(&internal_req->pending, &internal_req->request, &client->address, + internal_req->retry_count); - coap_pending_cycle(&internal_req->pending); + if (ret < 0) { + LOG_ERR("Failed to initialize pending struct"); + k_mutex_unlock(&client->send_mutex); + goto out; } + coap_pending_cycle(&internal_req->pending); + ret = send_request(sock, internal_req->request.data, internal_req->request.offset, 0, &client->address, client->socklen); @@ -371,10 +368,6 @@ static void report_callback_error(struct coap_client_internal_request *internal_ static bool timeout_expired(struct coap_client_internal_request *internal_req) { - if (internal_req->pending.timeout == 0) { - return false; - } - return (internal_req->request_ongoing && internal_req->pending.timeout <= (k_uptime_get() - internal_req->pending.t0)); } @@ -554,6 +547,35 @@ static int send_ack(struct coap_client *client, const struct coap_packet *req, return 0; } +static int send_reset(struct coap_client *client, const struct coap_packet *req, + uint8_t response_code) +{ + int ret; + uint16_t id; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; + struct coap_packet reset; + + id = coap_header_get_id(req); + tkl = response_code ? coap_header_get_token(req, token) : 0; + ret = coap_packet_init(&reset, client->send_buf, MAX_COAP_MSG_LEN, COAP_VERSION, + COAP_TYPE_RESET, tkl, token, response_code, id); + + if (ret < 0) { + LOG_ERR("Error creating CoAP reset message"); + return ret; + } + + ret = send_request(client->fd, reset.data, reset.offset, 0, + &client->address, client->socklen); + if (ret < 0) { + LOG_ERR("Error sending CoAP reset message"); + return ret; + } + + return 0; +} + struct coap_client_internal_request *get_request_with_id(struct coap_client *client, uint16_t message_id) { @@ -609,7 +631,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet */ response_type = coap_header_get_type(response); - internal_req = get_request_with_token(client, response); + internal_req = get_request_with_id(client, coap_header_get_id(response)); /* Reset and Ack need to match the message ID with request */ if ((response_type == COAP_TYPE_ACK || response_type == COAP_TYPE_RESET) && internal_req == NULL) { @@ -633,8 +655,17 @@ static int handle_response(struct coap_client *client, const struct coap_packet return 1; } + /* Check for tokens + * Separate response doesn't match with message ID, + * check if there is a separate request waiting with matching token + */ + if (internal_req == NULL) { + internal_req = get_request_with_token(client, response); + } + if (internal_req == NULL || !token_compare(internal_req, response)) { - LOG_WRN("Not matching tokens"); + LOG_ERR("Not matching tokens, respond with reset"); + ret = send_reset(client, response, COAP_RESPONSE_CODE_NOT_FOUND); return 1; } @@ -764,7 +795,7 @@ void coap_client_recv(void *coap_cl, void *a, void *b) ret = handle_response(clients[i], &response); if (ret < 0) { - LOG_ERR("Error handling response"); + LOG_ERR("Error handling respnse"); } clients[i]->response_ready = false; diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index bb9d9fc38c5..a3862852c21 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -392,5 +392,7 @@ ZTEST(coap_client, test_unmatching_tokens) k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1)); clear_socket_events(); - k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_NOT_FOUND, "Unexpected response %d", + last_response_code); + k_sleep(K_MSEC(1)); } From ad141108e7b09da8c03795dd6295983b0e3acbbc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:39 +0000 Subject: [PATCH 4336/4498] Revert "[nrf fromtree] tests: mcumgr: Updated MCUmg & smp client tests" This reverts commit 63548546a8126ab0b0c7c780cf9add80d00c2c73. Signed-off-by: Dominik Ermel --- .../subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt | 2 +- tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf | 7 ++----- .../mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c | 10 ++-------- tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c | 12 ++++++------ tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml | 11 ----------- tests/subsys/mgmt/mcumgr/smp_client/src/main.c | 6 +++--- tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml | 11 ----------- 7 files changed, 14 insertions(+), 45 deletions(-) delete mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml delete mode 100644 tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt index 20a96480514..a0f76554629 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt @@ -14,4 +14,4 @@ FILE(GLOB app_sources target_sources(app PRIVATE ${app_sources}) -zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) +add_compile_definitions(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1) diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf index 461a0ec9477..46835a49dc7 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf @@ -12,17 +12,14 @@ CONFIG_NET_BUF=y CONFIG_BASE64=y CONFIG_ZCBOR=y CONFIG_CRC=y -# Enable MCUboot util library -CONFIG_MCUBOOT_BOOTUTIL_LIB=y -# Enable mcumgr client +# Enable mcumgr CONFIG_MCUMGR=y CONFIG_SMP_CLIENT=y +CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1 CONFIG_MCUMGR_GRP_OS_CLIENT=y CONFIG_MCUMGR_GRP_IMG_CLIENT=y CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO=y CONFIG_MCUMGR_GRP_OS_CLIENT_RESET=y -# disable default image group build -CONFIG_IMG_MANAGER=n # Extend System Workqueue stack size CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c index aea03935fe6..5bd784a3954 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c @@ -24,12 +24,6 @@ static struct mcumgr_image_data image_dummy_info[2]; static size_t test_offset; static uint8_t *image_hash_ptr; -#ifdef CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER -#define IMG_UPDATABLE_IMAGE_COUNT CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER -#else -#define IMG_UPDATABLE_IMAGE_COUNT 1 -#endif - #define ZCBOR_ENCODE_FLAG(zse, label, value) \ (zcbor_tstr_put_lit(zse, label) && zcbor_bool_put(zse, value)) @@ -123,7 +117,7 @@ void img_read_response(int count) zcbor_tstr_put_term(zse, image_dummy_info[i].version) && zcbor_tstr_put_term(zse, "hash") && - zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_DATA_SHA_LEN) && + zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_HASH_LEN) && ZCBOR_ENCODE_FLAG(zse, "bootable", image_dummy_info[i].flags.bootable) && ZCBOR_ENCODE_FLAG(zse, "pending", image_dummy_info[i].flags.pending) && ZCBOR_ENCODE_FLAG(zse, "confirmed", image_dummy_info[i].flags.confirmed) && @@ -132,7 +126,7 @@ void img_read_response(int count) zcbor_map_end_encode(zse, 15); } - ok = ok && zcbor_list_end_encode(zse, 2 * IMG_UPDATABLE_IMAGE_COUNT); + ok = ok && zcbor_list_end_encode(zse, 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER); ok = ok && zcbor_map_end_encode(zse, 15); diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c index bf70f178fe7..a15e82f17a6 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c @@ -27,7 +27,7 @@ static struct smp_client_object smp_client; static struct img_mgmt_client img_client; static struct os_mgmt_client os_client; -ZTEST(mcumgr_client, test_img_upload) +ZTEST(mcumgr_client, img_upload) { int rc; struct mcumgr_image_upload response; @@ -108,7 +108,7 @@ ZTEST(mcumgr_client, test_img_upload) response.image_upload_offset); } -ZTEST(mcumgr_client, test_img_erase) +ZTEST(mcumgr_client, img_erase) { int rc; @@ -130,7 +130,7 @@ ZTEST(mcumgr_client, test_img_erase) zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); } -ZTEST(mcumgr_client, test_image_state_read) +ZTEST(mcumgr_client, image_state_read) { int rc; struct mcumgr_image_state res_buf; @@ -153,7 +153,7 @@ ZTEST(mcumgr_client, test_image_state_read) res_buf.image_list_length); } -ZTEST(mcumgr_client, test_image_state_set) +ZTEST(mcumgr_client, image_state_set) { int rc; char hash[32]; @@ -199,7 +199,7 @@ ZTEST(mcumgr_client, test_image_state_set) true, image_info[0].flags.confirmed); } -ZTEST(mcumgr_client, test_os_reset) +ZTEST(mcumgr_client, os_reset) { int rc; @@ -217,7 +217,7 @@ ZTEST(mcumgr_client, test_os_reset) zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); } -ZTEST(mcumgr_client, test_os_echo) +ZTEST(mcumgr_client, os_echo) { int rc; diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml b/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml deleted file mode 100644 index 99b9fac34ad..00000000000 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/testcase.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# -tests: - mgmt.mcumgr.mcumgr.client: - platform_allow: native_posix - tags: - - mcumgr - - mcumgr_client diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c index 7b6ad8eafa8..be1a3968274 100644 --- a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c @@ -32,7 +32,7 @@ int smp_client_res_cb(struct net_buf *nb, void *user_data) return 0; } -ZTEST(smp_client, test_buf_alloc) +ZTEST(smp_client, buf_alloc) { struct smp_client_object smp_client; @@ -56,7 +56,7 @@ ZTEST(smp_client, test_buf_alloc) } } -ZTEST(smp_client, test_msg_send_timeout) +ZTEST(smp_client, msg_send_timeout) { struct net_buf *nb; @@ -72,7 +72,7 @@ ZTEST(smp_client, test_msg_send_timeout) zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); } -ZTEST(smp_client, test_msg_response_handler) +ZTEST(smp_client, msg_response_handler) { struct smp_hdr dst_hdr; int rc; diff --git a/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml b/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml deleted file mode 100644 index 49971116251..00000000000 --- a/tests/subsys/mgmt/mcumgr/smp_client/testcase.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# -tests: - mgmt.mcumgr.smp.client: - platform_allow: native_posix - tags: - - mcumgr - - smp_client From 6ca557ee335956aeb85603d00700f1e910d7d786 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:40 +0000 Subject: [PATCH 4337/4498] Revert "[nrf fromtree] mgmt: mcumgr: Image management client fix" This reverts commit 7f84783145206883918b27572dcd32f25698e265. Signed-off-by: Dominik Ermel --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h | 4 ++-- .../mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt | 1 - .../mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c | 12 ++++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h index 8cede40d64e..6ee12fb5a61 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h @@ -40,7 +40,7 @@ struct mcumgr_image_data { /** Image number */ uint32_t img_num; /** Image SHA256 checksum */ - char hash[IMG_MGMT_DATA_SHA_LEN]; + char hash[IMG_MGMT_HASH_LEN]; /** Image Version */ char version[IMG_MGMT_VER_MAX_STR_LEN + 1]; /** Image Flags */ @@ -76,7 +76,7 @@ struct mcumgr_image_upload { */ struct img_gr_upload { /** Image 256-bit hash */ - char sha256[IMG_MGMT_DATA_SHA_LEN]; + char sha256[IMG_MGMT_HASH_LEN]; /** True when Hash is configured, false when not */ bool hash_initialized; /** Image size */ diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt index cae17e865ff..693891896d8 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt @@ -13,4 +13,3 @@ zephyr_library_sources( ) zephyr_library_include_directories(include) -zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c index 9ab8ee02dcd..b0e38640e8c 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c @@ -126,7 +126,7 @@ static int image_state_res_fn(struct net_buf *nb, void *user_data) goto out; } /* Check that mandatory parameters have decoded */ - if (hash.len != IMG_MGMT_DATA_SHA_LEN || !version.len || + if (hash.len != IMG_MGMT_HASH_LEN || !version.len || !zcbor_map_decode_bulk_key_found(list_res_decode, ARRAY_SIZE(list_res_decode), "slot")) { LOG_ERR("Missing mandatory parametrs"); @@ -138,7 +138,7 @@ static int image_state_res_fn(struct net_buf *nb, void *user_data) image_info->image_list[image_info->image_list_length].img_num = img_num; image_info->image_list[image_info->image_list_length].slot_num = slot_num; memcpy(image_info->image_list[image_info->image_list_length].hash, - hash.value, IMG_MGMT_DATA_SHA_LEN); + hash.value, IMG_MGMT_HASH_LEN); if (version.len > IMG_MGMT_VER_MAX_STR_LEN) { LOG_WRN("Version truncated len %d -> %d", version.len, IMG_MGMT_VER_MAX_STR_LEN); @@ -277,7 +277,7 @@ static size_t upload_message_header_size(struct img_gr_upload *upload_state) /* Write hash when it defined and offset is 0 */ if (ok && upload_state->hash_initialized) { ok = zcbor_tstr_put_lit(zse, "sha") && - zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_DATA_SHA_LEN); + zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_HASH_LEN); } if (ok) { @@ -311,7 +311,7 @@ int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_siz client->upload.offset = 0; client->upload.image_num = image_num; if (image_hash) { - memcpy(client->upload.sha256, image_hash, IMG_MGMT_DATA_SHA_LEN); + memcpy(client->upload.sha256, image_hash, IMG_MGMT_HASH_LEN); client->upload.hash_initialized = true; } else { client->upload.hash_initialized = false; @@ -395,7 +395,7 @@ int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, if (ok && active_client->upload.hash_initialized) { ok = zcbor_tstr_put_lit(zse, "sha") && zcbor_bstr_encode_ptr(zse, active_client->upload.sha256, - IMG_MGMT_DATA_SHA_LEN); + IMG_MGMT_HASH_LEN); } } @@ -485,7 +485,7 @@ int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool /* Write hash data */ if (ok && hash) { ok = zcbor_tstr_put_lit(zse, "hash") && - zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_DATA_SHA_LEN); + zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_HASH_LEN); } /* Close map */ if (ok) { From 86210cc1a121ef9115779a64cf14644badc09824 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:41 +0000 Subject: [PATCH 4338/4498] Revert "[nrf fromtree] net: coap: Improve CoAP Doxygen comments" This reverts commit 2158801356d3cfc3ed113afdc34b0e149446d9a3. Signed-off-by: Dominik Ermel --- include/zephyr/net/coap.h | 156 +++++++++++++++----------------------- 1 file changed, 61 insertions(+), 95 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 6fc21a6280b..5952cf77d83 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -42,25 +42,25 @@ extern "C" { * Refer to RFC 7252, section 12.2 for more information. */ enum coap_option_num { - COAP_OPTION_IF_MATCH = 1, /**< If-Match */ - COAP_OPTION_URI_HOST = 3, /**< Uri-Host */ - COAP_OPTION_ETAG = 4, /**< ETag */ - COAP_OPTION_IF_NONE_MATCH = 5, /**< If-None-Match */ - COAP_OPTION_OBSERVE = 6, /**< Observe (RFC 7641) */ - COAP_OPTION_URI_PORT = 7, /**< Uri-Port */ - COAP_OPTION_LOCATION_PATH = 8, /**< Location-Path */ - COAP_OPTION_URI_PATH = 11, /**< Uri-Path */ - COAP_OPTION_CONTENT_FORMAT = 12, /**< Content-Format */ - COAP_OPTION_MAX_AGE = 14, /**< Max-Age */ - COAP_OPTION_URI_QUERY = 15, /**< Uri-Query */ - COAP_OPTION_ACCEPT = 17, /**< Accept */ - COAP_OPTION_LOCATION_QUERY = 20, /**< Location-Query */ - COAP_OPTION_BLOCK2 = 23, /**< Block2 (RFC 7959) */ - COAP_OPTION_BLOCK1 = 27, /**< Block1 (RFC 7959) */ - COAP_OPTION_SIZE2 = 28, /**< Size2 (RFC 7959) */ - COAP_OPTION_PROXY_URI = 35, /**< Proxy-Uri */ - COAP_OPTION_PROXY_SCHEME = 39, /**< Proxy-Scheme */ - COAP_OPTION_SIZE1 = 60 /**< Size1 */ + COAP_OPTION_IF_MATCH = 1, + COAP_OPTION_URI_HOST = 3, + COAP_OPTION_ETAG = 4, + COAP_OPTION_IF_NONE_MATCH = 5, + COAP_OPTION_OBSERVE = 6, + COAP_OPTION_URI_PORT = 7, + COAP_OPTION_LOCATION_PATH = 8, + COAP_OPTION_URI_PATH = 11, + COAP_OPTION_CONTENT_FORMAT = 12, + COAP_OPTION_MAX_AGE = 14, + COAP_OPTION_URI_QUERY = 15, + COAP_OPTION_ACCEPT = 17, + COAP_OPTION_LOCATION_QUERY = 20, + COAP_OPTION_BLOCK2 = 23, + COAP_OPTION_BLOCK1 = 27, + COAP_OPTION_SIZE2 = 28, + COAP_OPTION_PROXY_URI = 35, + COAP_OPTION_PROXY_SCHEME = 39, + COAP_OPTION_SIZE1 = 60, }; /** @@ -69,13 +69,13 @@ enum coap_option_num { * To be used when creating a request or a response. */ enum coap_method { - COAP_METHOD_GET = 1, /**< GET */ - COAP_METHOD_POST = 2, /**< POST */ - COAP_METHOD_PUT = 3, /**< PUT */ - COAP_METHOD_DELETE = 4, /**< DELETE */ - COAP_METHOD_FETCH = 5, /**< FETCH */ - COAP_METHOD_PATCH = 6, /**< PATCH */ - COAP_METHOD_IPATCH = 7, /**< IPATCH */ + COAP_METHOD_GET = 1, + COAP_METHOD_POST = 2, + COAP_METHOD_PUT = 3, + COAP_METHOD_DELETE = 4, + COAP_METHOD_FETCH = 5, + COAP_METHOD_PATCH = 6, + COAP_METHOD_IPATCH = 7, }; #define COAP_REQUEST_MASK 0x07 @@ -120,7 +120,7 @@ enum coap_msgtype { * @param class Class of the response code (ex. 2, 4, 5, ...) * @param det Detail of the response code * @return Response code literal - */ +*/ #define COAP_MAKE_RESPONSE_CODE(class, det) ((class << 5) | (det)) /** @@ -129,60 +129,33 @@ enum coap_msgtype { * To be used when creating a response. */ enum coap_response_code { - /** 2.00 - OK */ COAP_RESPONSE_CODE_OK = COAP_MAKE_RESPONSE_CODE(2, 0), - /** 2.01 - Created */ COAP_RESPONSE_CODE_CREATED = COAP_MAKE_RESPONSE_CODE(2, 1), - /** 2.02 - Deleted */ COAP_RESPONSE_CODE_DELETED = COAP_MAKE_RESPONSE_CODE(2, 2), - /** 2.03 - Valid */ COAP_RESPONSE_CODE_VALID = COAP_MAKE_RESPONSE_CODE(2, 3), - /** 2.04 - Changed */ COAP_RESPONSE_CODE_CHANGED = COAP_MAKE_RESPONSE_CODE(2, 4), - /** 2.05 - Content */ COAP_RESPONSE_CODE_CONTENT = COAP_MAKE_RESPONSE_CODE(2, 5), - /** 2.31 - Continue */ COAP_RESPONSE_CODE_CONTINUE = COAP_MAKE_RESPONSE_CODE(2, 31), - /** 4.00 - Bad Request */ COAP_RESPONSE_CODE_BAD_REQUEST = COAP_MAKE_RESPONSE_CODE(4, 0), - /** 4.01 - Unauthorized */ COAP_RESPONSE_CODE_UNAUTHORIZED = COAP_MAKE_RESPONSE_CODE(4, 1), - /** 4.02 - Bad Option */ COAP_RESPONSE_CODE_BAD_OPTION = COAP_MAKE_RESPONSE_CODE(4, 2), - /** 4.03 - Forbidden */ COAP_RESPONSE_CODE_FORBIDDEN = COAP_MAKE_RESPONSE_CODE(4, 3), - /** 4.04 - Not Found */ COAP_RESPONSE_CODE_NOT_FOUND = COAP_MAKE_RESPONSE_CODE(4, 4), - /** 4.05 - Method Not Allowed */ COAP_RESPONSE_CODE_NOT_ALLOWED = COAP_MAKE_RESPONSE_CODE(4, 5), - /** 4.06 - Not Acceptable */ COAP_RESPONSE_CODE_NOT_ACCEPTABLE = COAP_MAKE_RESPONSE_CODE(4, 6), - /** 4.08 - Request Entity Incomplete */ COAP_RESPONSE_CODE_INCOMPLETE = COAP_MAKE_RESPONSE_CODE(4, 8), - /** 4.12 - Precondition Failed */ COAP_RESPONSE_CODE_CONFLICT = COAP_MAKE_RESPONSE_CODE(4, 9), - /** 4.12 - Precondition Failed */ COAP_RESPONSE_CODE_PRECONDITION_FAILED = COAP_MAKE_RESPONSE_CODE(4, 12), - /** 4.13 - Request Entity Too Large */ COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = COAP_MAKE_RESPONSE_CODE(4, 13), - /** 4.15 - Unsupported Content-Format */ COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = COAP_MAKE_RESPONSE_CODE(4, 15), - /** 4.22 - Unprocessable Entity */ COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = COAP_MAKE_RESPONSE_CODE(4, 22), - /** 4.29 - Too Many Requests */ COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = COAP_MAKE_RESPONSE_CODE(4, 29), - /** 5.00 - Internal Server Error */ COAP_RESPONSE_CODE_INTERNAL_ERROR = COAP_MAKE_RESPONSE_CODE(5, 0), - /** 5.01 - Not Implemented */ COAP_RESPONSE_CODE_NOT_IMPLEMENTED = COAP_MAKE_RESPONSE_CODE(5, 1), - /** 5.02 - Bad Gateway */ COAP_RESPONSE_CODE_BAD_GATEWAY = COAP_MAKE_RESPONSE_CODE(5, 2), - /** 5.03 - Service Unavailable */ COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = COAP_MAKE_RESPONSE_CODE(5, 3), - /** 5.04 - Gateway Timeout */ COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = COAP_MAKE_RESPONSE_CODE(5, 4), - /** 5.05 - Proxying Not Supported */ COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED = COAP_MAKE_RESPONSE_CODE(5, 5) }; @@ -197,15 +170,15 @@ enum coap_response_code { * To be used when encoding or decoding a Content-Format option. */ enum coap_content_format { - COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /**< text/plain;charset=utf-8 */ - COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40, /**< application/link-format */ - COAP_CONTENT_FORMAT_APP_XML = 41, /**< application/xml */ - COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42, /**< application/octet-stream */ - COAP_CONTENT_FORMAT_APP_EXI = 47, /**< application/exi */ - COAP_CONTENT_FORMAT_APP_JSON = 50, /**< application/json */ - COAP_CONTENT_FORMAT_APP_JSON_PATCH_JSON = 51, /**< application/json-patch+json */ - COAP_CONTENT_FORMAT_APP_MERGE_PATCH_JSON = 52, /**< application/merge-patch+json */ - COAP_CONTENT_FORMAT_APP_CBOR = 60 /**< application/cbor */ + COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /* charset=urf-8 */ + COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40, + COAP_CONTENT_FORMAT_APP_XML = 41, + COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42, + COAP_CONTENT_FORMAT_APP_EXI = 47, + COAP_CONTENT_FORMAT_APP_JSON = 50, + COAP_CONTENT_FORMAT_APP_JSON_PATCH_JSON = 51, + COAP_CONTENT_FORMAT_APP_MERGE_PATCH_JSON = 52, + COAP_CONTENT_FORMAT_APP_CBOR = 60, }; /* block option helper */ @@ -266,32 +239,25 @@ struct coap_observer { * @brief Representation of a CoAP Packet. */ struct coap_packet { - uint8_t *data; /**< User allocated buffer */ - uint16_t offset; /**< CoAP lib maintains offset while adding data */ - uint16_t max_len; /**< Max CoAP packet data length */ - uint8_t hdr_len; /**< CoAP header length */ - uint16_t opt_len; /**< Total options length (delta + len + value) */ - uint16_t delta; /**< Used for delta calculation in CoAP packet */ -#if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(DOXGEN) - /** - * Application specific user data. - * Only available when @kconfig{CONFIG_COAP_KEEP_USER_DATA} is enabled. - */ - void *user_data; + uint8_t *data; /* User allocated buffer */ + uint16_t offset; /* CoAP lib maintains offset while adding data */ + uint16_t max_len; /* Max CoAP packet data length */ + uint8_t hdr_len; /* CoAP header length */ + uint16_t opt_len; /* Total options length (delta + len + value) */ + uint16_t delta; /* Used for delta calculation in CoAP packet */ +#if defined(CONFIG_COAP_KEEP_USER_DATA) + void *user_data; /* Application specific user data */ #endif }; -/** - * @brief Representation of a CoAP option. - */ struct coap_option { - uint16_t delta; /**< Option delta */ + uint16_t delta; #if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN) uint16_t len; uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE]; #else - uint8_t len; /**< Option length */ - uint8_t value[12]; /**< Option value */ + uint8_t len; + uint8_t value[12]; #endif }; @@ -311,13 +277,13 @@ typedef int (*coap_reply_t)(const struct coap_packet *response, * @brief Represents a request awaiting for an acknowledgment (ACK). */ struct coap_pending { - struct sockaddr addr; /**< Remote address */ - int64_t t0; /**< Time when the request was sent */ - uint32_t timeout; /**< Timeout in ms */ - uint16_t id; /**< Message id */ - uint8_t *data; /**< User allocated buffer */ - uint16_t len; /**< Length of the CoAP packet */ - uint8_t retries; /**< Number of times the request has been sent */ + struct sockaddr addr; + int64_t t0; + uint32_t timeout; + uint16_t id; + uint8_t *data; + uint16_t len; + uint8_t retries; }; /** @@ -597,13 +563,13 @@ int coap_handle_request(struct coap_packet *cpkt, * https://tools.ietf.org/html/rfc7959 */ enum coap_block_size { - COAP_BLOCK_16, /**< 16-byte block size */ - COAP_BLOCK_32, /**< 32-byte block size */ - COAP_BLOCK_64, /**< 64-byte block size */ - COAP_BLOCK_128, /**< 128-byte block size */ - COAP_BLOCK_256, /**< 256-byte block size */ - COAP_BLOCK_512, /**< 512-byte block size */ - COAP_BLOCK_1024, /**< 1024-byte block size */ + COAP_BLOCK_16, + COAP_BLOCK_32, + COAP_BLOCK_64, + COAP_BLOCK_128, + COAP_BLOCK_256, + COAP_BLOCK_512, + COAP_BLOCK_1024, }; /** From bad438ac4646c2c6d49567a1247f01983f08096a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:41 +0000 Subject: [PATCH 4339/4498] Revert "[nrf fromtree] net: coap: Capitalize and document COAP_MAKE_RESPONSE_CODE macro" This reverts commit 4baf98b57ba7177839d831e35aa56696f50a598a. Signed-off-by: Dominik Ermel --- include/zephyr/net/coap.h | 62 ++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 5952cf77d83..55776bfc6d8 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -115,13 +115,7 @@ enum coap_msgtype { COAP_TYPE_RESET = 3 }; -/** - * Utility macro to create a CoAP response code. - * @param class Class of the response code (ex. 2, 4, 5, ...) - * @param det Detail of the response code - * @return Response code literal -*/ -#define COAP_MAKE_RESPONSE_CODE(class, det) ((class << 5) | (det)) +#define coap_make_response_code(class, det) ((class << 5) | (det)) /** * @brief Set of response codes available for a response packet. @@ -129,35 +123,35 @@ enum coap_msgtype { * To be used when creating a response. */ enum coap_response_code { - COAP_RESPONSE_CODE_OK = COAP_MAKE_RESPONSE_CODE(2, 0), - COAP_RESPONSE_CODE_CREATED = COAP_MAKE_RESPONSE_CODE(2, 1), - COAP_RESPONSE_CODE_DELETED = COAP_MAKE_RESPONSE_CODE(2, 2), - COAP_RESPONSE_CODE_VALID = COAP_MAKE_RESPONSE_CODE(2, 3), - COAP_RESPONSE_CODE_CHANGED = COAP_MAKE_RESPONSE_CODE(2, 4), - COAP_RESPONSE_CODE_CONTENT = COAP_MAKE_RESPONSE_CODE(2, 5), - COAP_RESPONSE_CODE_CONTINUE = COAP_MAKE_RESPONSE_CODE(2, 31), - COAP_RESPONSE_CODE_BAD_REQUEST = COAP_MAKE_RESPONSE_CODE(4, 0), - COAP_RESPONSE_CODE_UNAUTHORIZED = COAP_MAKE_RESPONSE_CODE(4, 1), - COAP_RESPONSE_CODE_BAD_OPTION = COAP_MAKE_RESPONSE_CODE(4, 2), - COAP_RESPONSE_CODE_FORBIDDEN = COAP_MAKE_RESPONSE_CODE(4, 3), - COAP_RESPONSE_CODE_NOT_FOUND = COAP_MAKE_RESPONSE_CODE(4, 4), - COAP_RESPONSE_CODE_NOT_ALLOWED = COAP_MAKE_RESPONSE_CODE(4, 5), - COAP_RESPONSE_CODE_NOT_ACCEPTABLE = COAP_MAKE_RESPONSE_CODE(4, 6), - COAP_RESPONSE_CODE_INCOMPLETE = COAP_MAKE_RESPONSE_CODE(4, 8), - COAP_RESPONSE_CODE_CONFLICT = COAP_MAKE_RESPONSE_CODE(4, 9), - COAP_RESPONSE_CODE_PRECONDITION_FAILED = COAP_MAKE_RESPONSE_CODE(4, 12), - COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = COAP_MAKE_RESPONSE_CODE(4, 13), + COAP_RESPONSE_CODE_OK = coap_make_response_code(2, 0), + COAP_RESPONSE_CODE_CREATED = coap_make_response_code(2, 1), + COAP_RESPONSE_CODE_DELETED = coap_make_response_code(2, 2), + COAP_RESPONSE_CODE_VALID = coap_make_response_code(2, 3), + COAP_RESPONSE_CODE_CHANGED = coap_make_response_code(2, 4), + COAP_RESPONSE_CODE_CONTENT = coap_make_response_code(2, 5), + COAP_RESPONSE_CODE_CONTINUE = coap_make_response_code(2, 31), + COAP_RESPONSE_CODE_BAD_REQUEST = coap_make_response_code(4, 0), + COAP_RESPONSE_CODE_UNAUTHORIZED = coap_make_response_code(4, 1), + COAP_RESPONSE_CODE_BAD_OPTION = coap_make_response_code(4, 2), + COAP_RESPONSE_CODE_FORBIDDEN = coap_make_response_code(4, 3), + COAP_RESPONSE_CODE_NOT_FOUND = coap_make_response_code(4, 4), + COAP_RESPONSE_CODE_NOT_ALLOWED = coap_make_response_code(4, 5), + COAP_RESPONSE_CODE_NOT_ACCEPTABLE = coap_make_response_code(4, 6), + COAP_RESPONSE_CODE_INCOMPLETE = coap_make_response_code(4, 8), + COAP_RESPONSE_CODE_CONFLICT = coap_make_response_code(4, 9), + COAP_RESPONSE_CODE_PRECONDITION_FAILED = coap_make_response_code(4, 12), + COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = coap_make_response_code(4, 13), COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = - COAP_MAKE_RESPONSE_CODE(4, 15), - COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = COAP_MAKE_RESPONSE_CODE(4, 22), - COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = COAP_MAKE_RESPONSE_CODE(4, 29), - COAP_RESPONSE_CODE_INTERNAL_ERROR = COAP_MAKE_RESPONSE_CODE(5, 0), - COAP_RESPONSE_CODE_NOT_IMPLEMENTED = COAP_MAKE_RESPONSE_CODE(5, 1), - COAP_RESPONSE_CODE_BAD_GATEWAY = COAP_MAKE_RESPONSE_CODE(5, 2), - COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = COAP_MAKE_RESPONSE_CODE(5, 3), - COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = COAP_MAKE_RESPONSE_CODE(5, 4), + coap_make_response_code(4, 15), + COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = coap_make_response_code(4, 22), + COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = coap_make_response_code(4, 29), + COAP_RESPONSE_CODE_INTERNAL_ERROR = coap_make_response_code(5, 0), + COAP_RESPONSE_CODE_NOT_IMPLEMENTED = coap_make_response_code(5, 1), + COAP_RESPONSE_CODE_BAD_GATEWAY = coap_make_response_code(5, 2), + COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = coap_make_response_code(5, 3), + COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = coap_make_response_code(5, 4), COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED = - COAP_MAKE_RESPONSE_CODE(5, 5) + coap_make_response_code(5, 5) }; #define COAP_CODE_EMPTY (0) From f7ff592debfc0bf15c98bd6bb8f46ba85e5b3257 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:42 +0000 Subject: [PATCH 4340/4498] Revert "[nrf fromtree] net: lwm2m: RD client Deregister event indicate" This reverts commit a63c627ac67cc7b2849f508113bebbf5db3370de. Signed-off-by: Dominik Ermel --- doc/connectivity/networking/api/lwm2m.rst | 8 -------- doc/releases/release-notes-3.5.rst | 1 - include/zephyr/net/lwm2m.h | 1 - samples/net/lwm2m_client/src/lwm2m-client.c | 3 --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 2 -- tests/net/lib/lwm2m/interop/src/lwm2m-client.c | 3 --- tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c | 6 ------ 7 files changed, 24 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 8d727d48bf5..c630ea7785a 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -318,14 +318,6 @@ events, setup a callback function: LOG_DBG("Disconnected"); break; - case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: - LOG_DBG("Registration update"); - break; - - case LWM2M_RD_CLIENT_EVENT_DEREGISTER: - LOG_DBG("Deregistration client"); - break; - } } diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 4f9a8ab1793..1c2a38edcf2 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -255,7 +255,6 @@ Networking * Added support for tickless mode. This removes the 500 ms timeout from the socket loop so the engine does not constantly wake up the CPU. This can be enabled by :kconfig:option:`CONFIG_LWM2M_TICKLESS`. - * Added new :c:macro:`LWM2M_RD_CLIENT_EVENT_DEREGISTER` event. * Wi-Fi * Added Passive scan support. diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index 6262f6d103d..e94297d3550 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -2073,7 +2073,6 @@ enum lwm2m_rd_client_event { LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED, LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, LWM2M_RD_CLIENT_EVENT_REG_UPDATE, - LWM2M_RD_CLIENT_EVENT_DEREGISTER, }; /** diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index 748f654d9ee..e20008c2f66 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -231,9 +231,6 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_DBG("Registration update"); break; - case LWM2M_RD_CLIENT_EVENT_DEREGISTER: - LOG_DBG("Client De-register"); - break; } } diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index db8a84ce0b8..feebcaeea17 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -215,8 +215,6 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) } } else if (sm_state == ENGINE_UPDATE_REGISTRATION) { event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE; - } else if (sm_state == ENGINE_DEREGISTER) { - event = LWM2M_RD_CLIENT_EVENT_DEREGISTER; } if (sm_is_suspended()) { diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 983fea79f3e..1278d807b71 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -117,9 +117,6 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_DBG("Registration update"); break; - case LWM2M_RD_CLIENT_EVENT_DEREGISTER: - LOG_DBG("Deregistration client"); - break; } } diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 03d0dce7f49..08c0820d5e9 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -106,9 +106,6 @@ static void lwm2m_event_cb(struct lwm2m_ctx *client, enum lwm2m_rd_client_event case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_REG_UPDATE"); break; - case LWM2M_RD_CLIENT_EVENT_DEREGISTER: - LOG_INF("*** LWM2M_RD_CLIENT_EVENT_DEREGISTER"); - break; } show_lwm2m_event(client_event); @@ -214,7 +211,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); - zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); zassert_true(!lwm2m_rd_client_is_registred(&ctx), NULL); } @@ -429,7 +425,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) test_prepare_pending_message_cb(&message_reply_timeout_cb_default); zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); - zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE)); } @@ -534,7 +529,6 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) zassert_equal(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, false), 0); zassert_true(lwm2m_rd_client_resume() == 0, NULL); - zassert_false(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DEREGISTER), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); } From d8fb5f36e428d928e17b6aac158e223a31afb172 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:42 +0000 Subject: [PATCH 4341/4498] Revert "[nrf fromtree] net: coap: Fix coap client timeout" This reverts commit b65d00b7190dbccc6b7998f6ef868c19fc9f982f. Signed-off-by: Dominik Ermel --- subsys/net/lib/coap/coap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index d096e39c62f..f8ba4283648 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -369,7 +369,7 @@ static void report_callback_error(struct coap_client_internal_request *internal_ static bool timeout_expired(struct coap_client_internal_request *internal_req) { return (internal_req->request_ongoing && - internal_req->pending.timeout <= (k_uptime_get() - internal_req->pending.t0)); + internal_req->pending.timeout <= k_uptime_get_32()); } static int resend_request(struct coap_client *client, @@ -649,7 +649,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet /* Separate response coming */ if (payload_len == 0 && response_type == COAP_TYPE_ACK && response_code == COAP_CODE_EMPTY) { - internal_req->pending.t0 = k_uptime_get(); + internal_req->pending.t0 = k_uptime_get_32(); internal_req->pending.timeout = internal_req->pending.t0 + COAP_SEPARATE_TIMEOUT; internal_req->pending.retries = 0; return 1; From cad98d139b71138ce5a03a6e57db1a505f35d8a4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:42 +0000 Subject: [PATCH 4342/4498] Revert "[nrf fromtree] net: lwm2m: Generate new tokens for LwM2M SEND blocks" This reverts commit d96b34effcd3ec9010f7e80a564e5fbd93e4c995. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 678f358d1ee..7aaa42c20ab 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -307,13 +307,12 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu /* reuse message for next block. Copy token from the new query to allow * CoAP clients to use new token for every query of ongoing transaction */ + tkl = coap_header_get_token(msg->in.in_cpkt, token); lwm2m_reset_message(msg, false); if (msg->type == COAP_TYPE_ACK) { msg->mid = coap_header_get_id(msg->in.in_cpkt); - tkl = coap_header_get_token(msg->in.in_cpkt, token); } else { msg->mid = coap_next_id(); - tkl = LWM2M_MSG_TOKEN_GENERATE_NEW; } msg->token = token; msg->tkl = tkl; From a2d4cccf43905b74e1856c2c3a9189901a28e9a2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:43 +0000 Subject: [PATCH 4343/4498] Revert "[nrf fromtree] net: lwm2m: Append CoAP Etag to protect integrity of blockwise" This reverts commit 821e53edec9e15d97e6248342daed14ebb97b5ee. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/Kconfig | 2 -- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 14 +------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index d826e5cd599..41ac5bcf1ce 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -83,8 +83,6 @@ config LWM2M_COAP_BLOCK_TRANSFER help LwM2M messages with a big body that exceed the block size will be split into blocks for sending. - To append CoAP ETag option into outgoing block transfers, CONFIG_SYS_HASH_FUNC32 should - be enabled. config LWM2M_CANCEL_OBSERVE_BY_PATH bool "Use path matching as fallback for cancel-observe" diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 7aaa42c20ab..06cc1b5ecf8 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -33,7 +33,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include #if defined(CONFIG_LWM2M_DTLS_SUPPORT) #include @@ -379,7 +378,6 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) { int ret; uint16_t len; - const uint8_t *payload; /* save the big buffer for later use (splitting blocks) */ msg->body_encode_buffer = msg->cpkt; @@ -389,7 +387,7 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) msg->cpkt.offset = 0; msg->cpkt.max_len = MAX_PACKET_SIZE; - payload = coap_packet_get_payload(&msg->body_encode_buffer, &len); + coap_packet_get_payload(&msg->body_encode_buffer, &len); if (len <= CONFIG_LWM2M_COAP_MAX_MSG_SIZE) { /* copy the packet */ @@ -408,16 +406,6 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) NET_ASSERT(msg->out.block_ctx == NULL, "Expecting to have no context to release"); } else { - /* Before splitting the content, append Etag option to protect the integrity of - * the payload. - */ - if (IS_ENABLED(CONFIG_SYS_HASH_FUNC32)) { - uint32_t hash = sys_hash32(payload, len); - - coap_packet_append_option(&msg->body_encode_buffer, COAP_OPTION_ETAG, - (const uint8_t *)&hash, sizeof(hash)); - } - ret = build_msg_block_for_send(msg, 0); if (ret != 0) { return ret; From def02a6d8f068b9c5cc3c4778f1e3fa5f208b26e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:43 +0000 Subject: [PATCH 4344/4498] Revert "[nrf fromtree] net: lwm2m: Fix composite read on SenML-CBOR" This reverts commit 73a6d196160abe543c52944c07953dafdc338ea6. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 6 ++++++ subsys/net/lib/lwm2m/lwm2m_message_handling.h | 6 +----- subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c | 5 +---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 06cc1b5ecf8..df940cf4adb 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -417,6 +417,12 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) #endif +bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) +{ + return msg->block_send; +} + + void lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx) { struct lwm2m_message *msg; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index c41fbbac0ee..fd6c4470d84 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -75,10 +75,6 @@ enum coap_block_size lwm2m_default_block_size(void); int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri); void lwm2m_clear_block_contexts(void); - -static inline bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) -{ - return msg->block_send; -} +bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg); #endif /* LWM2M_MESSAGE_HANDLING_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c index 15dc9a9451e..d62af88200b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c @@ -836,15 +836,12 @@ static uint8_t parse_composite_read_paths(struct lwm2m_message *msg, uint_fast8_t dret; int len; int ret; - char *payload; - uint16_t in_len; setup_in_fmt_data(msg); fd = engine_get_in_user_data(&msg->in); - payload = (char *)coap_packet_get_payload(msg->in.in_cpkt, &in_len); - dret = cbor_decode_lwm2m_senml(payload, in_len, &fd->dcd, &isize); + dret = cbor_decode_lwm2m_senml(ICTX_BUF_R_REGION(&msg->in), &fd->dcd, &isize); if (dret != ZCBOR_SUCCESS) { __ASSERT_NO_MSG(false); From ff64559f0d0be5073fd2eac5ac68c25a75a804e3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:44 +0000 Subject: [PATCH 4345/4498] Revert "[nrf fromtree] net: lwm2m: Refactor blockwise SEND to support GET and FETCH" This reverts commit a65e10df9b91edd5198495d3bc13e928c314aa38. Signed-off-by: Dominik Ermel --- include/zephyr/net/coap.h | 14 --- subsys/net/lib/coap/coap.c | 13 --- subsys/net/lib/lwm2m/lwm2m_engine.c | 4 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 92 ++----------------- subsys/net/lib/lwm2m/lwm2m_message_handling.h | 1 - subsys/net/lib/lwm2m/lwm2m_object.h | 5 +- 6 files changed, 8 insertions(+), 121 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 55776bfc6d8..95bb0b45c65 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -713,20 +713,6 @@ int coap_get_option_int(const struct coap_packet *cpkt, uint16_t code); */ int coap_get_block1_option(const struct coap_packet *cpkt, bool *has_more, uint8_t *block_number); -/** - * @brief Get values from CoAP block2 option. - * - * Decode block number and block size from option. Ignore the has_more flag - * as it should always be zero on queries. - * - * @param cpkt Packet to be inspected - * @param block_number Is set to the number of the block - * - * @return Integer value of the block size in case of success - * or negative in case of error. - */ -int coap_get_block2_option(const struct coap_packet *cpkt, uint8_t *block_number); - /** * @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a cpkt and updates * @a ctx accordingly. diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index e3427844bb5..a5c300bf0e2 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1303,19 +1303,6 @@ int coap_get_block1_option(const struct coap_packet *cpkt, bool *has_more, uint8 return ret; } -int coap_get_block2_option(const struct coap_packet *cpkt, uint8_t *block_number) -{ - int ret = coap_get_option_int(cpkt, COAP_OPTION_BLOCK2); - - if (ret < 0) { - return ret; - } - - *block_number = GET_NUM(ret); - ret = 1 << (GET_BLOCK_SIZE(ret) + 4); - return ret; -} - int insert_option(struct coap_packet *cpkt, uint16_t code, const uint8_t *value, uint16_t len) { uint16_t offset = cpkt->hdr_len; diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 651baa30ff6..d38c081ed34 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -675,9 +675,7 @@ static int socket_send_message(struct lwm2m_ctx *client_ctx) } if (msg->type != COAP_TYPE_CON) { - if (!lwm2m_outgoing_is_part_of_blockwise(msg)) { - lwm2m_reset_message(msg, true); - } + lwm2m_reset_message(msg, true); } return rc; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index df940cf4adb..4eea849750b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -81,7 +81,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* Shared set of in-flight LwM2M messages */ static struct lwm2m_message messages[CONFIG_LWM2M_ENGINE_MAX_MESSAGES]; static struct lwm2m_block_context block1_contexts[NUM_BLOCK1_CONTEXT]; -static struct lwm2m_message *ongoing_block2_tx; #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) /* we need 1 more buffer as the payload is encoded in that buffer first even if @@ -100,7 +99,6 @@ sys_slist_t *lwm2m_engine_obj_inst_list(void); static int handle_request(struct coap_packet *request, struct lwm2m_message *msg); #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) -STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num); struct coap_block_context *lwm2m_output_block_context(void); #endif @@ -303,16 +301,10 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu } msg->cpkt.hdr_len = msg->body_encode_buffer.hdr_len; } else { - /* reuse message for next block. Copy token from the new query to allow - * CoAP clients to use new token for every query of ongoing transaction - */ - tkl = coap_header_get_token(msg->in.in_cpkt, token); + /* reuse message for next block */ + tkl = coap_header_get_token(&msg->cpkt, token); lwm2m_reset_message(msg, false); - if (msg->type == COAP_TYPE_ACK) { - msg->mid = coap_header_get_id(msg->in.in_cpkt); - } else { - msg->mid = coap_next_id(); - } + msg->mid = coap_next_id(); msg->token = token; msg->tkl = tkl; ret = lwm2m_init_message(msg); @@ -341,14 +333,10 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu return ret; } ret = coap_block_transfer_init(msg->out.block_ctx, lwm2m_default_block_size(), - complete_payload_len); + msg->body_encode_buffer.offset); if (ret < 0) { return ret; } - if (msg->type == COAP_TYPE_ACK) { - ongoing_block2_tx = msg; - } - msg->block_send = true; } else { /* update block context */ msg->out.block_ctx->current = block_num * block_size_bytes; @@ -414,15 +402,8 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg) return 0; } - #endif -bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg) -{ - return msg->block_send; -} - - void lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx) { struct lwm2m_message *msg; @@ -2576,56 +2557,6 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) return ret; } -static struct lwm2m_message *find_ongoing_block2_tx(void) -{ - /* TODO: I could try to check if there is Request-Tags attached, and then match queries - * for those, but currently popular LwM2M servers don't attach those tags, so in reality - * I have no way of properly matching query with BLOCK2 option to a previous query. - * Therefore we can only support one ongoing BLOCK2 transfer and assume all BLOCK2 requests - * are part of currently ongoing one. - */ - return ongoing_block2_tx; -} - -static void clear_ongoing_block2_tx(void) -{ - if (ongoing_block2_tx) { - LOG_DBG("clear"); - lwm2m_reset_message(ongoing_block2_tx, true); - ongoing_block2_tx = NULL; - } -} - -static void handle_ongoing_block2_tx(struct lwm2m_message *msg, struct coap_packet *cpkt) -{ -#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) - int r; - uint8_t block; - - r = coap_get_block2_option(cpkt, &block); - if (r < 0) { - LOG_ERR("Failed to parse BLOCK2"); - return; - } - - msg->in.in_cpkt = cpkt; - - r = build_msg_block_for_send(msg, block); - if (r < 0) { - clear_ongoing_block2_tx(); - LOG_ERR("Unable to build next block of lwm2m message! r=%d", r); - return; - } - - r = lwm2m_send_message_async(msg); - if (r < 0) { - clear_ongoing_block2_tx(); - LOG_ERR("Unable to send next block of lwm2m message!"); - return; - } -#endif -} - void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, struct sockaddr *from_addr) { @@ -2634,12 +2565,12 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ struct coap_reply *reply; struct coap_packet response; int r; + uint8_t token[8]; #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) bool more_blocks = false; uint8_t block_num; uint8_t last_block_num; #endif - bool has_block2; r = coap_packet_parse(&response, buf, buf_len, NULL, 0); if (r < 0) { @@ -2647,7 +2578,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ return; } - has_block2 = coap_get_option_int(&response, COAP_OPTION_BLOCK2) > 0 ? true : false; + (void)coap_header_get_token(&response, token); pending = coap_pending_received(&response, client_ctx->pendings, ARRAY_SIZE(client_ctx->pendings)); if (pending && coap_header_get_type(&response) == COAP_TYPE_ACK) { @@ -2755,17 +2686,6 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ } if (coap_header_get_type(&response) == COAP_TYPE_CON) { - if (has_block2 && IS_ENABLED(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)) { - msg = find_ongoing_block2_tx(); - if (msg) { - return handle_ongoing_block2_tx(msg, &response); - } - return; - } - - /* Clear out existing Block2 transfers when new requests come */ - clear_ongoing_block2_tx(); - msg = lwm2m_get_message(client_ctx); if (!msg) { LOG_ERR("Unable to get a lwm2m message!"); diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index fd6c4470d84..a98be3f8dc2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -75,6 +75,5 @@ enum coap_block_size lwm2m_default_block_size(void); int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri); void lwm2m_clear_block_contexts(void); -bool lwm2m_outgoing_is_part_of_blockwise(struct lwm2m_message *msg); #endif /* LWM2M_MESSAGE_HANDLING_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index 170a99c023d..05bc818c99c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -521,11 +521,8 @@ struct lwm2m_message { /** Incoming message action */ uint8_t operation; - /** Information whether the message was acknowledged. */ + /* Information whether the message was acknowledged. */ bool acknowledged : 1; - - /** Indicate that this is part of outgoing block transfer. */ - bool block_send : 1; }; /* LWM2M format writer for the various formats supported */ From a90d1d40fe24a115e32dedb0158e06f34e169345 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:44 +0000 Subject: [PATCH 4346/4498] Revert "[nrf fromtree] net: lwm2m: Remove unneeded function pointer parameter" This reverts commit 58210f1e7f681cd8faf5f4a1a0d273bb7d7ec43f. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_engine.c | 2 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 14 +++++++++----- subsys/net/lib/lwm2m/lwm2m_message_handling.h | 6 +++++- tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 4 ++-- tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index d38c081ed34..91d8c3bd605 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -642,7 +642,7 @@ static int socket_recv_message(struct lwm2m_ctx *client_ctx) } in_buf[len] = 0U; - lwm2m_udp_receive(client_ctx, in_buf, len, &from_addr); + lwm2m_udp_receive(client_ctx, in_buf, len, &from_addr, handle_request); return 0; } diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 4eea849750b..299b0330c0b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -97,7 +97,6 @@ sys_slist_t *lwm2m_engine_obj_list(void); sys_slist_t *lwm2m_engine_obj_inst_list(void); -static int handle_request(struct coap_packet *request, struct lwm2m_message *msg); #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) struct coap_block_context *lwm2m_output_block_context(void); #endif @@ -2194,7 +2193,7 @@ static int lwm2m_exec_handler(struct lwm2m_message *msg) return -ENOENT; } -static int handle_request(struct coap_packet *request, struct lwm2m_message *msg) +int handle_request(struct coap_packet *request, struct lwm2m_message *msg) { int r; uint8_t code; @@ -2558,7 +2557,7 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) } void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, - struct sockaddr *from_addr) + struct sockaddr *from_addr, udp_request_handler_cb_t udp_request_handler) { struct lwm2m_message *msg = NULL; struct coap_pending *pending; @@ -2685,7 +2684,12 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ return; } - if (coap_header_get_type(&response) == COAP_TYPE_CON) { + /* + * If no normal response handler is found, then this is + * a new request coming from the server. Let's look + * at registered objects to find a handler. + */ + if (udp_request_handler && coap_header_get_type(&response) == COAP_TYPE_CON) { msg = lwm2m_get_message(client_ctx); if (!msg) { LOG_ERR("Unable to get a lwm2m message!"); @@ -2703,7 +2707,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_ lwm2m_registry_lock(); /* process the response to this request */ - r = handle_request(&response, msg); + r = udp_request_handler(&response, msg); lwm2m_registry_unlock(); if (r < 0) { return; diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index a98be3f8dc2..12ba9e762fd 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -39,6 +39,8 @@ #define NUM_OUTPUT_BLOCK_CONTEXT CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT #endif +/* Establish a request handler callback type */ +typedef int (*udp_request_handler_cb_t)(struct coap_packet *request, struct lwm2m_message *msg); /* LwM2M message functions */ struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx); struct lwm2m_message *find_msg(struct coap_pending *pending, struct coap_reply *reply); @@ -47,8 +49,10 @@ void lm2m_message_clear_allocations(struct lwm2m_message *msg); int lwm2m_init_message(struct lwm2m_message *msg); int lwm2m_send_message_async(struct lwm2m_message *msg); +int handle_request(struct coap_packet *request, struct lwm2m_message *msg); + void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_len, - struct sockaddr *from_addr); + struct sockaddr *from_addr, udp_request_handler_cb_t udp_request_handler); int generate_notify_message(struct lwm2m_ctx *ctx, struct observe_node *obs, void *user_data); /* Notification and Send operation */ diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 5db155f1e29..93f5cce1012 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -24,8 +24,8 @@ DEFINE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct DEFINE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t, const int64_t); DEFINE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *); -DEFINE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, - struct sockaddr *); +DEFINE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, struct sockaddr *, + udp_request_handler_cb_t); DEFINE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *); DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *, diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h index 7b8ca481f85..088d72d4623 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h @@ -39,7 +39,7 @@ DECLARE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct obser const int64_t); DECLARE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *); DECLARE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, - struct sockaddr *); + struct sockaddr *, udp_request_handler_cb_t); DECLARE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *, From 9c7ad158f5f35f47868bb2feaab61f4345f35cee Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:45 +0000 Subject: [PATCH 4347/4498] Revert "[nrf fromtree] net: lwm2m: Only parse block1 option for WRITE operation" This reverts commit 142c5e169eaff5e0ef611f95556e5bc8b3ee2d9b. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 398 ++++++++---------- 1 file changed, 185 insertions(+), 213 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 299b0330c0b..8b18f918752 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -1926,179 +1926,50 @@ static int do_discover_op(struct lwm2m_message *msg, uint16_t content_format) static int do_write_op(struct lwm2m_message *msg, uint16_t format) { - int r; - switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: - r = do_write_op_opaque(msg); - break; + return do_write_op_opaque(msg); case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: - r = do_write_op_plain_text(msg); - break; + return do_write_op_plain_text(msg); #ifdef CONFIG_LWM2M_RW_OMA_TLV_SUPPORT case LWM2M_FORMAT_OMA_TLV: case LWM2M_FORMAT_OMA_OLD_TLV: - r = do_write_op_tlv(msg); - break; + return do_write_op_tlv(msg); #endif #ifdef CONFIG_LWM2M_RW_JSON_SUPPORT case LWM2M_FORMAT_OMA_JSON: case LWM2M_FORMAT_OMA_OLD_JSON: - r = do_write_op_json(msg); - break; + return do_write_op_json(msg); #endif #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) case LWM2M_FORMAT_APP_SEML_JSON: - r = do_write_op_senml_json(msg); - break; + return do_write_op_senml_json(msg); #endif #ifdef CONFIG_LWM2M_RW_CBOR_SUPPORT case LWM2M_FORMAT_APP_CBOR: - r = do_write_op_cbor(msg); - break; + return do_write_op_cbor(msg); #endif #ifdef CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT case LWM2M_FORMAT_APP_SENML_CBOR: - r = do_write_op_senml_cbor(msg); - break; + return do_write_op_senml_cbor(msg); #endif default: LOG_ERR("Unsupported format: %u", format); - r = -ENOMSG; - break; - } - - return r; -} - -static int parse_write_op(struct lwm2m_message *msg, uint16_t format) -{ - int block_opt, block_num; - struct lwm2m_block_context *block_ctx = NULL; - enum coap_block_size block_size; - bool last_block = false; - int r; - uint16_t payload_len = 0U; - const uint8_t *payload_start; - - /* setup incoming data */ - payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); - if (payload_len > 0) { - msg->in.offset = payload_start - msg->in.in_cpkt->data; - } else { - msg->in.offset = msg->in.in_cpkt->offset; - } - - /* Check for block transfer */ - block_opt = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1); - if (block_opt > 0) { - last_block = !GET_MORE(block_opt); - - /* RFC7252: 4.6. Message Size */ - block_size = GET_BLOCK_SIZE(block_opt); - if (!last_block && coap_block_size_to_bytes(block_size) > payload_len) { - LOG_DBG("Trailing payload is discarded!"); - return -EFBIG; - } - - block_num = GET_BLOCK_NUM(block_opt); - - /* Try to retrieve existing block context. If one not exists, - * and we've received first block, allocate new context. - */ - r = get_block_ctx(&msg->path, &block_ctx); - if (r < 0 && block_num == 0) { - r = init_block_ctx(&msg->path, &block_ctx); - } - - if (r < 0) { - LOG_ERR("Cannot find block context"); - return r; - } - - msg->in.block_ctx = block_ctx; - - if (block_num < block_ctx->expected) { - LOG_WRN("Block already handled %d, expected %d", block_num, - block_ctx->expected); - return 0; - } - if (block_num > block_ctx->expected) { - LOG_WRN("Block out of order %d, expected %d", block_num, - block_ctx->expected); - r = -EFAULT; - return r; - } - r = coap_update_from_block(msg->in.in_cpkt, &block_ctx->ctx); - if (r < 0) { - LOG_ERR("Error from block update: %d", r); - return r; - } - - block_ctx->last_block = last_block; - - /* Initial block sent by the server might be larger than - * our block size therefore it is needed to take this - * into account when calculating next expected block - * number. - */ - block_ctx->expected += GET_BLOCK_SIZE(block_opt) - block_ctx->ctx.block_size + 1; - - /* Handle blockwise 1 (Part 1): Set response code */ - if (!last_block) { - msg->code = COAP_RESPONSE_CODE_CONTINUE; - } - } - - r = do_write_op(msg, format); - - /* Handle blockwise 1 (Part 2): Append BLOCK1 option / free context */ - if (block_ctx) { - if (r >= 0 && !last_block) { - /* More to come, ack with correspond block # */ - r = coap_append_block1_option(msg->out.out_cpkt, &block_ctx->ctx); - if (r < 0) { - /* report as internal server error */ - LOG_ERR("Fail adding block1 option: %d", r); - r = -EINVAL; - } - } - if (r < 0 || last_block) { - /* Free context when finished or when there is error */ - free_block_ctx(block_ctx); - - } + return -ENOMSG; } - - return r; } static int do_composite_write_op(struct lwm2m_message *msg, uint16_t format) { - uint16_t payload_len = 0U; - const uint8_t *payload_start; - - /* setup incoming data */ - payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); - if (payload_len > 0) { - msg->in.offset = payload_start - msg->in.in_cpkt->data; - } else { - msg->in.offset = msg->in.in_cpkt->offset; - } - - if (coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1) >= 0) { - return -ENOTSUP; - } - switch (format) { #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) case LWM2M_FORMAT_APP_SEML_JSON: @@ -2203,6 +2074,13 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) uint8_t tkl = 0U; uint16_t format = LWM2M_FORMAT_NONE, accept; int observe = -1; /* default to -1, 0 = ENABLE, 1 = DISABLE */ + int block_opt, block_num; + struct lwm2m_block_context *block_ctx = NULL; + enum coap_block_size block_size; + uint16_t payload_len = 0U; + bool last_block = false; + bool ignore = false; + const uint8_t *payload_start; /* set CoAP request / message */ msg->in.in_cpkt = request; @@ -2374,111 +2252,202 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) break; } + /* setup incoming data */ + payload_start = coap_packet_get_payload(msg->in.in_cpkt, &payload_len); + if (payload_len > 0) { + msg->in.offset = payload_start - msg->in.in_cpkt->data; + } else { + msg->in.offset = msg->in.in_cpkt->offset; + } + + /* Check for block transfer */ + + block_opt = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1); + if (block_opt > 0) { + last_block = !GET_MORE(block_opt); + + /* RFC7252: 4.6. Message Size */ + block_size = GET_BLOCK_SIZE(block_opt); + if (!last_block && coap_block_size_to_bytes(block_size) > payload_len) { + LOG_DBG("Trailing payload is discarded!"); + r = -EFBIG; + goto error; + } + + block_num = GET_BLOCK_NUM(block_opt); + + /* Try to retrieve existing block context. If one not exists, + * and we've received first block, allocate new context. + */ + r = get_block_ctx(&msg->path, &block_ctx); + if (r < 0 && block_num == 0) { + r = init_block_ctx(&msg->path, &block_ctx); + } + + if (r < 0) { + LOG_ERR("Cannot find block context"); + goto error; + } + + msg->in.block_ctx = block_ctx; + + if (block_num < block_ctx->expected) { + LOG_WRN("Block already handled %d, expected %d", block_num, + block_ctx->expected); + ignore = true; + } else if (block_num > block_ctx->expected) { + LOG_WRN("Block out of order %d, expected %d", block_num, + block_ctx->expected); + r = -EFAULT; + goto error; + } else { + r = coap_update_from_block(msg->in.in_cpkt, &block_ctx->ctx); + if (r < 0) { + LOG_ERR("Error from block update: %d", r); + goto error; + } + + block_ctx->last_block = last_block; + + /* Initial block sent by the server might be larger than + * our block size therefore it is needed to take this + * into account when calculating next expected block + * number. + */ + block_ctx->expected += + GET_BLOCK_SIZE(block_opt) - block_ctx->ctx.block_size + 1; + } + + /* Handle blockwise 1 (Part 1): Set response code */ + if (!last_block) { + msg->code = COAP_RESPONSE_CODE_CONTINUE; + } + } + /* render CoAP packet header */ r = lwm2m_init_message(msg); if (r < 0) { goto error; } + if (!ignore) { #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) - r = access_control_check_access(msg->path.obj_id, msg->path.obj_inst_id, - msg->ctx->srv_obj_inst, msg->operation, - msg->ctx->bootstrap_mode); - if (r < 0) { - LOG_ERR("Access denied - Server obj %u does not have proper access to " - "resource", - msg->ctx->srv_obj_inst); - goto error; - } + r = access_control_check_access(msg->path.obj_id, msg->path.obj_inst_id, + msg->ctx->srv_obj_inst, msg->operation, + msg->ctx->bootstrap_mode); + if (r < 0) { + LOG_ERR("Access denied - Server obj %u does not have proper access to " + "resource", + msg->ctx->srv_obj_inst); + goto error; + } #endif - if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { - r = -EACCES; - goto error; - } - - switch (msg->operation) { + if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { + r = -EACCES; + goto error; + } - case LWM2M_OP_READ: - if (observe >= 0) { - /* Validate That Token is valid for Observation */ - if (!msg->token) { - LOG_ERR("OBSERVE request missing token"); - r = -EINVAL; - goto error; - } + switch (msg->operation) { - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { - /* Normal Observation Request or Cancel */ - r = lwm2m_engine_observation_handler(msg, observe, accept, - false); - if (r < 0) { + case LWM2M_OP_READ: + if (observe >= 0) { + /* Validate That Token is valid for Observation */ + if (!msg->token) { + LOG_ERR("OBSERVE request missing token"); + r = -EINVAL; goto error; } - r = do_read_op(msg, accept); - } else { - /* Composite Observation request & cancel handler */ - r = lwm2m_engine_observation_handler(msg, observe, accept, - true); - if (r < 0) { - goto error; + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { + /* Normal Observation Request or Cancel */ + r = lwm2m_engine_observation_handler(msg, observe, accept, + false); + if (r < 0) { + goto error; + } + + r = do_read_op(msg, accept); + } else { + /* Composite Observation request & cancel handler */ + r = lwm2m_engine_observation_handler(msg, observe, accept, + true); + if (r < 0) { + goto error; + } } - } - } else { - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { - r = do_read_op(msg, accept); } else { - r = do_composite_read_op(msg, accept); + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_GET) { + r = do_read_op(msg, accept); + } else { + r = do_composite_read_op(msg, accept); + } } - } - break; + break; - case LWM2M_OP_DISCOVER: - r = do_discover_op(msg, accept); - break; + case LWM2M_OP_DISCOVER: + r = do_discover_op(msg, accept); + break; - case LWM2M_OP_WRITE: - case LWM2M_OP_CREATE: - if ((code & COAP_REQUEST_MASK) == COAP_METHOD_IPATCH) { - /* iPATCH is for Composite purpose */ - r = do_composite_write_op(msg, format); - } else { - /* Single resource write Operation */ - r = parse_write_op(msg, format); - } + case LWM2M_OP_WRITE: + case LWM2M_OP_CREATE: + if ((code & COAP_REQUEST_MASK) == COAP_METHOD_IPATCH) { + /* iPATCH is for Composite purpose */ + r = do_composite_write_op(msg, format); + } else { + /* Single resource write Operation */ + r = do_write_op(msg, format); + } #if defined(CONFIG_LWM2M_ACCESS_CONTROL_ENABLE) - if (msg->operation == LWM2M_OP_CREATE && r >= 0) { - access_control_add(msg->path.obj_id, msg->path.obj_inst_id, - msg->ctx->srv_obj_inst); - } + if (msg->operation == LWM2M_OP_CREATE && r >= 0) { + access_control_add(msg->path.obj_id, msg->path.obj_inst_id, + msg->ctx->srv_obj_inst); + } #endif - break; + break; - case LWM2M_OP_WRITE_ATTR: - r = lwm2m_write_attr_handler(obj, msg); - break; + case LWM2M_OP_WRITE_ATTR: + r = lwm2m_write_attr_handler(obj, msg); + break; - case LWM2M_OP_EXECUTE: - r = lwm2m_exec_handler(msg); - break; + case LWM2M_OP_EXECUTE: + r = lwm2m_exec_handler(msg); + break; - case LWM2M_OP_DELETE: + case LWM2M_OP_DELETE: #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (msg->ctx->bootstrap_mode) { - r = bootstrap_delete(msg); + if (msg->ctx->bootstrap_mode) { + r = bootstrap_delete(msg); + break; + } +#endif + r = lwm2m_delete_handler(msg); break; + + default: + LOG_ERR("Unknown operation: %u", msg->operation); + r = -EINVAL; } -#endif - r = lwm2m_delete_handler(msg); - break; - default: - LOG_ERR("Unknown operation: %u", msg->operation); - r = -EINVAL; + if (r < 0) { + goto error; + } } - if (r < 0) { - goto error; + /* Handle blockwise 1 (Part 2): Append BLOCK1 option / free context */ + if (block_ctx) { + if (!last_block) { + /* More to come, ack with correspond block # */ + r = coap_append_block1_option(msg->out.out_cpkt, &block_ctx->ctx); + if (r < 0) { + /* report as internal server error */ + LOG_ERR("Fail adding block1 option: %d", r); + r = -EINVAL; + goto error; + } + } else { + /* Free context when finished */ + free_block_ctx(block_ctx); + } } return 0; @@ -2513,6 +2482,9 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) LOG_ERR("Error recreating message: %d", r); } + /* Free block context when error happened */ + free_block_ctx(block_ctx); + return 0; } From f1ed3e0c1b1c3381998b228c0504cad0dc29c862 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:45 +0000 Subject: [PATCH 4348/4498] Revert "[nrf fromtree] net: lwm2m: Separate opaque content format into its own" This reverts commit 6f6fd46e43ba5b13d47f4940d82652bfe91a4fee. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/CMakeLists.txt | 1 - subsys/net/lib/lwm2m/lwm2m_message_handling.c | 12 -- subsys/net/lib/lwm2m/lwm2m_rw_opaque.c | 165 ------------------ subsys/net/lib/lwm2m/lwm2m_rw_opaque.h | 18 -- subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c | 44 +++++ .../lib/lwm2m/content_plain_text/src/main.c | 31 ++++ 6 files changed, 75 insertions(+), 196 deletions(-) delete mode 100644 subsys/net/lib/lwm2m/lwm2m_rw_opaque.c delete mode 100644 subsys/net/lib/lwm2m/lwm2m_rw_opaque.h diff --git a/subsys/net/lib/lwm2m/CMakeLists.txt b/subsys/net/lib/lwm2m/CMakeLists.txt index 2e895ec381b..5cb0ab158d5 100644 --- a/subsys/net/lib/lwm2m/CMakeLists.txt +++ b/subsys/net/lib/lwm2m/CMakeLists.txt @@ -14,7 +14,6 @@ zephyr_library_sources( lwm2m_obj_device.c lwm2m_rw_link_format.c lwm2m_rw_plain_text.c - lwm2m_rw_opaque.c lwm2m_util.c lwm2m_rd_client.c ) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 8b18f918752..1a7d023ceb2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -47,7 +47,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_rw_link_format.h" #include "lwm2m_rw_oma_tlv.h" #include "lwm2m_rw_plain_text.h" -#include "lwm2m_rw_opaque.h" #include "lwm2m_util.h" #include "lwm2m_rd_client.h" #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) @@ -808,10 +807,6 @@ static int select_writer(struct lwm2m_output_context *out, uint16_t accept) out->writer = &link_format_writer; break; - case LWM2M_FORMAT_APP_OCTET_STREAM: - out->writer = &opaque_writer; - break; - case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: out->writer = &plain_text_writer; @@ -862,9 +857,6 @@ static int select_reader(struct lwm2m_input_context *in, uint16_t format) switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: - in->reader = &opaque_reader; - break; - case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: in->reader = &plain_text_reader; @@ -1545,8 +1537,6 @@ static int do_read_op(struct lwm2m_message *msg, uint16_t content_format) switch (content_format) { case LWM2M_FORMAT_APP_OCTET_STREAM: - return do_read_op_opaque(msg, content_format); - case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: return do_read_op_plain_text(msg, content_format); @@ -1929,8 +1919,6 @@ static int do_write_op(struct lwm2m_message *msg, uint16_t format) switch (format) { case LWM2M_FORMAT_APP_OCTET_STREAM: - return do_write_op_opaque(msg); - case LWM2M_FORMAT_PLAIN_TEXT: case LWM2M_FORMAT_OMA_PLAIN_TEXT: return do_write_op_plain_text(msg); diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c deleted file mode 100644 index 90cb4619d9a..00000000000 --- a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * Copyright (c) 2015, Yanzi Networks AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define LOG_MODULE_NAME net_lwm2m_opaque -#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL - -#include -LOG_MODULE_REGISTER(LOG_MODULE_NAME); - -#include -#include -#include -#include -#include - -#include "lwm2m_object.h" -#include "lwm2m_rw_opaque.h" -#include "lwm2m_engine.h" -#include "lwm2m_util.h" - -static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, - size_t buflen, struct lwm2m_opaque_context *opaque, - bool *last_block) -{ - uint16_t in_len; - - if (opaque->remaining == 0) { - coap_packet_get_payload(in->in_cpkt, &in_len); - - if (in_len == 0) { - return -ENODATA; - } - - if (in->block_ctx != NULL) { - uint32_t block_num = - in->block_ctx->ctx.current / - coap_block_size_to_bytes( - in->block_ctx->ctx.block_size); - - if (block_num == 0) { - opaque->len = in->block_ctx->ctx.total_size; - } - - if (opaque->len == 0) { - /* No size1 option provided, use current - * payload size. This will reset on next packet - * received. - */ - opaque->remaining = in_len; - } else { - opaque->remaining = opaque->len; - } - - } else { - opaque->len = in_len; - opaque->remaining = in_len; - } - } - - return lwm2m_engine_get_opaque_more(in, value, buflen, - opaque, last_block); -} - -static int put_opaque(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, char *buf, - size_t buflen) -{ - int ret; - - ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), buf, buflen); - if (ret < 0) { - return ret; - } - - return buflen; -} - - -const struct lwm2m_writer opaque_writer = { - .put_opaque = put_opaque, -}; - -const struct lwm2m_reader opaque_reader = { - .get_opaque = get_opaque, -}; - -int do_read_op_opaque(struct lwm2m_message *msg, int content_format) -{ - /* Opaque can only return single resource (instance) */ - if (msg->path.level < LWM2M_PATH_LEVEL_RESOURCE) { - return -EPERM; - } else if (msg->path.level > LWM2M_PATH_LEVEL_RESOURCE) { - if (!IS_ENABLED(CONFIG_LWM2M_VERSION_1_1)) { - return -ENOENT; - } else if (msg->path.level > LWM2M_PATH_LEVEL_RESOURCE_INST) { - return -ENOENT; - } - } - - return lwm2m_perform_read_op(msg, content_format); -} - -int do_write_op_opaque(struct lwm2m_message *msg) -{ - struct lwm2m_engine_obj_inst *obj_inst = NULL; - struct lwm2m_engine_obj_field *obj_field; - struct lwm2m_engine_res *res = NULL; - struct lwm2m_engine_res_inst *res_inst = NULL; - int ret; - uint8_t created = 0U; - - ret = lwm2m_get_or_create_engine_obj(msg, &obj_inst, &created); - if (ret < 0) { - return ret; - } - - ret = lwm2m_engine_validate_write_access(msg, obj_inst, &obj_field); - if (ret < 0) { - return ret; - } - - ret = lwm2m_engine_get_create_res_inst(&msg->path, &res, &res_inst); - if (ret < 0) { - return -ENOENT; - } - - if (msg->path.level < LWM2M_PATH_LEVEL_RESOURCE) { - msg->path.level = LWM2M_PATH_LEVEL_RESOURCE; - } - - return lwm2m_write_handler(obj_inst, res, res_inst, obj_field, msg); -} diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h b/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h deleted file mode 100644 index 4118049efe8..00000000000 --- a/subsys/net/lib/lwm2m/lwm2m_rw_opaque.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef LWM2M_RW_OPAQUE_H_ -#define LWM2M_RW_OPAQUE_H_ - -#include "lwm2m_object.h" - -extern const struct lwm2m_writer opaque_writer; -extern const struct lwm2m_reader opaque_reader; - -int do_read_op_opaque(struct lwm2m_message *msg, int content_format); -int do_write_op_opaque(struct lwm2m_message *msg); - -#endif /* LWM2M_RW_OPAQUE_H_ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c index 3ec69e8db82..9650b33fc29 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c @@ -341,6 +341,49 @@ static int get_bool(struct lwm2m_input_context *in, bool *value) return sizeof(uint8_t); } +static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, + size_t buflen, struct lwm2m_opaque_context *opaque, + bool *last_block) +{ + uint16_t in_len; + + if (opaque->remaining == 0) { + coap_packet_get_payload(in->in_cpkt, &in_len); + + if (in_len == 0) { + return -ENODATA; + } + + if (in->block_ctx != NULL) { + uint32_t block_num = + in->block_ctx->ctx.current / + coap_block_size_to_bytes( + in->block_ctx->ctx.block_size); + + if (block_num == 0) { + opaque->len = in->block_ctx->ctx.total_size; + } + + if (opaque->len == 0) { + /* No size1 option provided, use current + * payload size. This will reset on next packet + * received. + */ + opaque->remaining = in_len; + } else { + opaque->remaining = opaque->len; + } + + } else { + opaque->len = in_len; + opaque->remaining = in_len; + } + } + + return lwm2m_engine_get_opaque_more(in, value, buflen, + opaque, last_block); +} + static int get_objlnk(struct lwm2m_input_context *in, struct lwm2m_objlnk *value) { @@ -389,6 +432,7 @@ const struct lwm2m_reader plain_text_reader = { .get_time = get_time, .get_float = get_float, .get_bool = get_bool, + .get_opaque = get_opaque, .get_objlnk = get_objlnk, }; diff --git a/tests/net/lib/lwm2m/content_plain_text/src/main.c b/tests/net/lib/lwm2m/content_plain_text/src/main.c index 7bc77a82327..c7cc857224c 100644 --- a/tests/net/lib/lwm2m/content_plain_text/src/main.c +++ b/tests/net/lib/lwm2m/content_plain_text/src/main.c @@ -470,6 +470,37 @@ ZTEST(net_content_plain_text_nodata, test_get_bool_nodata) zassert_equal(ret, -ENODATA, "Invalid error code returned"); } +ZTEST(net_content_plain_text, test_get_opaque) +{ + int ret; + const char *payload = "test_payload"; + uint8_t buf[16]; + bool last_block; + struct lwm2m_opaque_context ctx = { 0 }; + + test_payload_set(payload); + + ret = plain_text_reader.get_opaque(&test_in, buf, sizeof(buf), + &ctx, &last_block); + zassert_equal(ret, strlen(payload), "Invalid length returned"); + zassert_mem_equal(buf, payload, strlen(payload), + "Invalid value parsed"); + zassert_equal(test_in.offset, strlen(payload) + 1, + "Invalid packet offset"); +} + +ZTEST(net_content_plain_text_nodata, test_get_opaque_nodata) +{ + int ret; + uint8_t value[4]; + bool last_block; + struct lwm2m_opaque_context ctx = { 0 }; + + ret = plain_text_reader.get_opaque(&test_in, value, sizeof(value), + &ctx, &last_block); + zassert_equal(ret, 0, "Invalid error code returned"); +} + ZTEST(net_content_plain_text, test_get_objlnk) { int ret; From ca4a35bb8ff8cfe02a55c070ce9e7c856a79ad70 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:45 +0000 Subject: [PATCH 4349/4498] Revert "[nrf fromtree] net: lwm2m: Allow content formats to support only some data types" This reverts commit 5f6827522ce81d9091dcd0bf43d48e2e45ee1150. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_object.h | 143 ++++++++++------------------ 1 file changed, 52 insertions(+), 91 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index 05bc818c99c..ca8fdf12fd0 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -705,95 +705,71 @@ static inline int engine_put_end_ri(struct lwm2m_output_context *out, return 0; } -static inline int engine_put_s8(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - int8_t value) +static inline int engine_put_s8(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, int8_t value) { - if (out->writer->put_s8) { - return out->writer->put_s8(out, path, value); - } - return -ENOTSUP; + return out->writer->put_s8(out, path, value); } -static inline int engine_put_s16(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - int16_t value) +static inline int engine_put_s16(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, int16_t value) { - if (out->writer->put_s16) { - return out->writer->put_s16(out, path, value); - } - return -ENOTSUP; + return out->writer->put_s16(out, path, value); } -static inline int engine_put_s32(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - int32_t value) +static inline int engine_put_s32(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, int32_t value) { - if (out->writer->put_s32) { - return out->writer->put_s32(out, path, value); - } - return -ENOTSUP; + return out->writer->put_s32(out, path, value); } -static inline int engine_put_s64(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - int64_t value) +static inline int engine_put_s64(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, int64_t value) { - if (out->writer->put_s64) { - return out->writer->put_s64(out, path, value); - } - return -ENOTSUP; + return out->writer->put_s64(out, path, value); } -static inline int engine_put_string(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - char *buf, size_t buflen) +static inline int engine_put_string(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, char *buf, + size_t buflen) { - if (out->writer->put_string) { - return out->writer->put_string(out, path, buf, buflen); - } - return -ENOTSUP; + return out->writer->put_string(out, path, buf, buflen); } -static inline int engine_put_float(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - double *value) +static inline int engine_put_float(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, double *value) { - if (out->writer->put_float) { - return out->writer->put_float(out, path, value); - } - return -ENOTSUP; + return out->writer->put_float(out, path, value); } -static inline int engine_put_time(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - time_t value) +static inline int engine_put_time(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, time_t value) { - if (out->writer->put_time) { - return out->writer->put_time(out, path, value); - } - return -ENOTSUP; + return out->writer->put_time(out, path, value); } -static inline int engine_put_bool(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - bool value) +static inline int engine_put_bool(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, bool value) { - if (out->writer->put_bool) { - return out->writer->put_bool(out, path, value); - } - return -ENOTSUP; + return out->writer->put_bool(out, path, value); } -static inline int engine_put_opaque(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - char *buf, size_t buflen) +static inline int engine_put_opaque(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, char *buf, + size_t buflen) { if (out->writer->put_opaque) { return out->writer->put_opaque(out, path, buf, buflen); } - return -ENOTSUP; + return 0; } -static inline int engine_put_objlnk(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, +static inline int engine_put_objlnk(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, struct lwm2m_objlnk *value) { - if (out->writer->put_objlnk) { - return out->writer->put_objlnk(out, path, value); - } - return -ENOTSUP; + return out->writer->put_objlnk(out, path, value); } static inline int engine_put_corelink(struct lwm2m_output_context *out, @@ -817,68 +793,53 @@ static inline int engine_put_timestamp(struct lwm2m_output_context *out, time_t static inline int engine_get_s32(struct lwm2m_input_context *in, int32_t *value) { - if (in->reader->get_s32) { - return in->reader->get_s32(in, value); - } - return -ENOTSUP; + return in->reader->get_s32(in, value); } static inline int engine_get_s64(struct lwm2m_input_context *in, int64_t *value) { - if (in->reader->get_s64) { - return in->reader->get_s64(in, value); - } - return -ENOTSUP; + return in->reader->get_s64(in, value); } -static inline int engine_get_string(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen) +static inline int engine_get_string(struct lwm2m_input_context *in, + uint8_t *buf, size_t buflen) { - if (in->reader->get_string) { - return in->reader->get_string(in, buf, buflen); - } - return -ENOTSUP; + return in->reader->get_string(in, buf, buflen); } static inline int engine_get_time(struct lwm2m_input_context *in, time_t *value) { - if (in->reader->get_time) { - return in->reader->get_time(in, value); - } - return -ENOTSUP; + return in->reader->get_time(in, value); } -static inline int engine_get_float(struct lwm2m_input_context *in, double *value) +static inline int engine_get_float(struct lwm2m_input_context *in, + double *value) { - if (in->reader->get_float) { - return in->reader->get_float(in, value); - } - return -ENOTSUP; + return in->reader->get_float(in, value); } static inline int engine_get_bool(struct lwm2m_input_context *in, bool *value) { - if (in->reader->get_bool) { - return in->reader->get_bool(in, value); - } - return -ENOTSUP; + return in->reader->get_bool(in, value); } -static inline int engine_get_opaque(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen, - struct lwm2m_opaque_context *opaque, bool *last_block) +static inline int engine_get_opaque(struct lwm2m_input_context *in, + uint8_t *buf, size_t buflen, + struct lwm2m_opaque_context *opaque, + bool *last_block) { if (in->reader->get_opaque) { - return in->reader->get_opaque(in, buf, buflen, opaque, last_block); + return in->reader->get_opaque(in, buf, buflen, + opaque, last_block); } - return -ENOTSUP; + return 0; } -static inline int engine_get_objlnk(struct lwm2m_input_context *in, struct lwm2m_objlnk *value) +static inline int engine_get_objlnk(struct lwm2m_input_context *in, + struct lwm2m_objlnk *value) { - if (in->reader->get_objlnk) { - return in->reader->get_objlnk(in, value); - } - return -ENOTSUP; + return in->reader->get_objlnk(in, value); } #endif /* LWM2M_OBJECT_H_ */ From 075fc5fc14ae96d890cd654643bb97b8086368fa Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:45 +0000 Subject: [PATCH 4350/4498] Revert "[nrf fromtree] net: lwm2m: Clean up shell documentation" This reverts commit 79d70889263c4965c760e5835d1b2d1f7e69fbe9. Signed-off-by: Dominik Ermel --- doc/connectivity/networking/api/lwm2m.rst | 68 +++++++++-------------- subsys/net/lib/lwm2m/lwm2m_shell.c | 22 ++++---- 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index c630ea7785a..6d26205511e 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -633,58 +633,40 @@ required actions from the server side. .. code-block:: console - uart:~$ lwm2m - lwm2m - LwM2M commands - Subcommands: - send :send PATHS - LwM2M SEND operation - - exec :exec PATH [PARAM] - Execute a resource - - read :read PATH [OPTIONS] - Read value from LwM2M resource - -x Read value as hex stream (default) - -s Read value as string + uart:~$ lwm2m + lwm2m - LwM2M commands + Subcommands: + exec :Execute a resource + exec PATH + + read :Read value from LwM2M resource + read PATH [OPTIONS] + -s Read value as string (default) -b Read value as bool (1/0) -uX Read value as uintX_t -sX Read value as intX_t -f Read value as float - -t Read value as time_t - - write :write PATH [OPTIONS] VALUE - Write into LwM2M resource - -s Write value as string (default) - -b Write value as bool - -uX Write value as uintX_t - -sX Write value as intX_t - -f Write value as float - -t Write value as time_t - - create :create PATH - Create object instance - - cache :cache PATH NUM - Enable data cache for resource - PATH is LwM2M path - NUM how many elements to cache - - start :start EP_NAME [BOOTSTRAP FLAG] - Start the LwM2M RD (Registration / Discovery) Client - -b Set the bootstrap flag (default 0) - stop :stop [OPTIONS] - Stop the LwM2M RD (De-register) Client - -f Force close the connection + write :Write into LwM2M resource + write PATH [OPTIONS] VALUE + -s Value as string (default) + -b Value as bool + -uX Value as uintX_t + -sX Value as intX_t + -f Value as float - update :Trigger Registration Update of the LwM2M RD Client + start :Start the LwM2M RD (Registration / Discovery) Client + start EP_NAME [BOOTSTRAP FLAG] + -b Set the bootstrap flag (default 0) - pause :LwM2M engine thread pause - resume :LwM2M engine thread resume - lock :Lock the LwM2M registry - unlock :Unlock the LwM2M registry + stop :Stop the LwM2M RD (De-register) Client + stop [OPTIONS] + -f Force close the connection + update :Trigger Registration Update of the LwM2M RD Client + pause :LwM2M engine thread pause + resume :LwM2M engine thread resume .. _lwm2m_api_reference: diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index 335004ec5d5..2a86aa88d69 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -22,9 +22,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #define LWM2M_HELP_CMD "LwM2M commands" -#define LWM2M_HELP_SEND "send PATHS\nLwM2M SEND operation\n" -#define LWM2M_HELP_EXEC "exec PATH [PARAM]\nExecute a resource\n" -#define LWM2M_HELP_READ "read PATH [OPTIONS]\nRead value from LwM2M resource\n" \ +#define LWM2M_HELP_SEND "LwM2M SEND operation\nsend [OPTION]... [PATH]...\n" \ + "Root-level operation is unsupported" +#define LWM2M_HELP_EXEC "Execute a resource\nexec PATH [PARAM]\n" +#define LWM2M_HELP_READ "Read value from LwM2M resource\nread PATH [OPTIONS]\n" \ "-x \tRead value as hex stream (default)\n" \ "-s \tRead value as string\n" \ "-b \tRead value as bool (1/0)\n" \ @@ -32,25 +33,26 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "-sX\tRead value as intX_t\n" \ "-f \tRead value as float\n" \ "-t \tRead value as time_t\n" -#define LWM2M_HELP_WRITE "write PATH [OPTIONS] VALUE\nWrite into LwM2M resource\n" \ +#define LWM2M_HELP_WRITE "Write into LwM2M resource\nwrite PATH [OPTIONS] VALUE\n" \ "-s \tWrite value as string (default)\n" \ "-b \tWrite value as bool\n" \ "-uX\tWrite value as uintX_t\n" \ "-sX\tWrite value as intX_t\n" \ "-f \tWrite value as float\n" \ "-t \tWrite value as time_t\n" -#define LWM2M_HELP_CREATE "create PATH\nCreate object instance\n" -#define LWM2M_HELP_START "start EP_NAME [BOOTSTRAP FLAG]\n" \ - "Start the LwM2M RD (Registration / Discovery) Client\n" \ +#define LWM2M_HELP_CREATE "Create object instance\ncreate PATH\n" +#define LWM2M_HELP_START "Start the LwM2M RD (Registration / Discovery) Client\n" \ + "start EP_NAME [BOOTSTRAP FLAG]\n" \ "-b \tSet the bootstrap flag (default 0)\n" -#define LWM2M_HELP_STOP "stop [OPTIONS]\nStop the LwM2M RD (De-register) Client\n" \ +#define LWM2M_HELP_STOP "Stop the LwM2M RD (De-register) Client\nstop [OPTIONS]\n" \ "-f \tForce close the connection\n" #define LWM2M_HELP_UPDATE "Trigger Registration Update of the LwM2M RD Client\n" #define LWM2M_HELP_PAUSE "LwM2M engine thread pause" #define LWM2M_HELP_RESUME "LwM2M engine thread resume" #define LWM2M_HELP_LOCK "Lock the LwM2M registry" #define LWM2M_HELP_UNLOCK "Unlock the LwM2M registry" -#define LWM2M_HELP_CACHE "cache PATH NUM\nEnable data cache for resource\n" \ +#define LWM2M_HELP_CACHE "Enable data cache for resource\n" \ + "cache PATH NUM\n" \ "PATH is LwM2M path\n" \ "NUM how many elements to cache\n" \ @@ -595,7 +597,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(read, NULL, LWM2M_HELP_READ, cmd_read, 2, 1), SHELL_CMD_ARG(write, NULL, LWM2M_HELP_WRITE, cmd_write, 3, 1), SHELL_CMD_ARG(create, NULL, LWM2M_HELP_CREATE, cmd_create, 2, 0), - SHELL_CMD_ARG(cache, NULL, LWM2M_HELP_CACHE, cmd_cache, 3, 0), SHELL_CMD_ARG(start, NULL, LWM2M_HELP_START, cmd_start, 2, 2), SHELL_CMD_ARG(stop, NULL, LWM2M_HELP_STOP, cmd_stop, 1, 1), SHELL_CMD_ARG(update, NULL, LWM2M_HELP_UPDATE, cmd_update, 1, 0), @@ -603,6 +604,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(resume, NULL, LWM2M_HELP_RESUME, cmd_resume, 1, 0), SHELL_CMD_ARG(lock, NULL, LWM2M_HELP_LOCK, cmd_lock, 1, 0), SHELL_CMD_ARG(unlock, NULL, LWM2M_HELP_UNLOCK, cmd_unlock, 1, 0), + SHELL_CMD_ARG(cache, NULL, LWM2M_HELP_CACHE, cmd_cache, 3, 0), SHELL_SUBCMD_SET_END); SHELL_COND_CMD_ARG_REGISTER(CONFIG_LWM2M_SHELL, lwm2m, &sub_lwm2m, From 88b110357ca3be4353735a9f79ad5cdfa3858621 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:46 +0000 Subject: [PATCH 4351/4498] Revert "[nrf fromtree] net: lwm2m: Add functional tests for LwM2M against Leshan" This reverts commit 70a65804527ea66bf30a353d12ab4a348cf54cd8. Signed-off-by: Dominik Ermel --- tests/net/lib/lwm2m/interop/CMakeLists.txt | 10 - tests/net/lib/lwm2m/interop/README.md | 103 ---- .../lwm2m/interop/boards/native_posix.conf | 7 - .../lwm2m/interop/boards/qemu_cortex_m3.conf | 20 - tests/net/lib/lwm2m/interop/prj.conf | 90 ---- tests/net/lib/lwm2m/interop/pytest/leshan.py | 104 ---- .../lib/lwm2m/interop/pytest/test_lwm2m.py | 446 ------------------ tests/net/lib/lwm2m/interop/requirements.txt | 1 - .../net/lib/lwm2m/interop/src/lwm2m-client.c | 171 ------- tests/net/lib/lwm2m/interop/testcase.yaml | 14 - 10 files changed, 966 deletions(-) delete mode 100644 tests/net/lib/lwm2m/interop/CMakeLists.txt delete mode 100644 tests/net/lib/lwm2m/interop/README.md delete mode 100644 tests/net/lib/lwm2m/interop/boards/native_posix.conf delete mode 100644 tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf delete mode 100644 tests/net/lib/lwm2m/interop/prj.conf delete mode 100644 tests/net/lib/lwm2m/interop/pytest/leshan.py delete mode 100644 tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py delete mode 100644 tests/net/lib/lwm2m/interop/requirements.txt delete mode 100644 tests/net/lib/lwm2m/interop/src/lwm2m-client.c delete mode 100644 tests/net/lib/lwm2m/interop/testcase.yaml diff --git a/tests/net/lib/lwm2m/interop/CMakeLists.txt b/tests/net/lib/lwm2m/interop/CMakeLists.txt deleted file mode 100644 index 89c4d33e43e..00000000000 --- a/tests/net/lib/lwm2m/interop/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(lwm2m_interop_tests) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) - -include(${ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md deleted file mode 100644 index 858f5007f64..00000000000 --- a/tests/net/lib/lwm2m/interop/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# LwM2M Interoperability tests using Leshan demo server - -This directory contains list of testcases that use -the Twister's Pytest integration to run testcases against Leshan demo server. -These tests use emulated hardware (native_posix). - -These tests require setup that is not done in Twister run, so follow this documentation to set -up the test environment. - -## Network setup - -As with typical network samples, host machine uses IP address `192.0.2.2` and the emulated device -running Zephyr is using address `192.0.2.1`. - -Follow [Networking with the host system](https://docs.zephyrproject.org/latest/connectivity/networking/networking_with_host.html#networking-with-the-host-system) -from Zephyr's documentation how to set it up, or follow [Create NAT and routing for Zephyr native network on Linux](https://github.com/zephyrproject-rtos/net-tools/blob/master/README%20NAT.md). - -### Leshan server setup - -* Leshan server must be reachable from the device using IP address `192.0.2.2`. - Configure the port forwarding, if you use Docker to run Leshan. -* Leshan demo server REST API must be reachable from localhost. -* tcp/8080 Leshan web interface and REST API -* tcp/8081 Leshan bootstrap server REST API -* udp/5683 Leshan non-secure CoAP -* udp/5684 Leshan DTLS CoAP -* udp/5783 non-secure Bootstrap CoAP -* udp/5684 DTLS Bootstrap CoAP -* Download Leshan JAR file from https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar -* Download Leshan Bootstrap server JAR file from https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar - -Both server can be started like this: -``` -java -jar ./leshan-server-demo.jar -wp 8080 -vv -java -jar ./leshan-bsserver-demo.jar -lp=5783 -slp=5784 -wp 8081 -``` - -Or create a helper script that does everything, including download: -``` -#!/bin/sh -eu - -# Download Leshan if needed -if [ ! -f leshan-server-demo.jar ]; then - wget https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar -fi - -if [ ! -f leshan-bsserver-demo.jar ]; then - wget 'https://ci.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar' -fi - -mkdir -p log - -start-stop-daemon --make-pidfile --pidfile log/leshan.pid --chdir $(pwd) --background --start \ - --startas /bin/bash -- -c "exec java -jar ./leshan-server-demo.jar -wp 8080 -vv --models-folder objects >log/leshan.log 2>&1" - -start-stop-daemon --make-pidfile --pidfile log/leshan_bs.pid --chdir $(pwd) --background --start \ - --startas /bin/bash -- -c "exec java -jar ./leshan-bsserver-demo.jar -lp=5783 -slp=5784 -wp 8081 -vv >log/leshan_bs.log 2>&1" -``` - -Then stopping would require similar script: -``` -#!/bin/sh -eu - -start-stop-daemon --remove-pidfile --pidfile log/leshan.pid --stop -start-stop-daemon --remove-pidfile --pidfile log/leshan_bs.pid --stop -``` - -## Python package requirements - -These tests require extra package that is not installed when you follow the Zephyr's setup. -Install with `pip install CoAPthon3` - -## Running tests - -``` -twister -p native_posix -vv --enable-slow -T tests/net/lib/lwm2m/interop -`````` - -## Test specification - -Tests are written from test spec; -[OMA Enabler Test Specification (Interoperability) for Lightweight M2M](https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf) - -Following tests are implemented: -* LightweightM2M-1.1-int-0 – Client Initiated Bootstrap -* LightweightM2M-1.1-int-1 – Client Initiated Bootstrap Full (PSK) -* LightweightM2M-1.1-int-101 – Initial Registration -* LightweightM2M-1.1-int-102 – Registration Update -* LightweightM2M-1.1-int-104 – Registration Update Trigge -* LightweightM2M-1.1-int-105 - Discarded Register Update -* LightweightM2M-1.1-int-107 – Extending the lifetime of a registration -* LightweightM2M-1.1-int-108 – Turn on Queue Mode -* LightweightM2M-1.1-int-109 – Behavior in Queue Mode -* LightweightM2M-1.1-int-201 – Querying basic information in Plain Text -* LightweightM2M-1.1-int-203 – Querying basic information in TLV format -* LightweightM2M-1.1-int-204 – Querying basic information in JSON format -* LightweightM2M-1.1-int-205 – Setting basic information in Plain Text -* LightweightM2M-1.1-int-211 – Querying basic information in CBOR format -* LightweightM2M-1.1-int-212 – Setting basic information in CBOR format -* LightweightM2M-1.1-int-215 – Setting basic information in TLV format -* LightweightM2M-1.1-int-220 – Setting basic information in JSON format -* LightweightM2M-1.1-int-221 – Attempt to perform operations on Security -* LightweightM2M-1.1-int-401 – UDP Channel Security – PSK Mode diff --git a/tests/net/lib/lwm2m/interop/boards/native_posix.conf b/tests/net/lib/lwm2m/interop/boards/native_posix.conf deleted file mode 100644 index 44346db12ed..00000000000 --- a/tests/net/lib/lwm2m/interop/boards/native_posix.conf +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG_DNS_RESOLVER=y -CONFIG_DNS_SERVER_IP_ADDRESSES=y -CONFIG_DNS_SERVER1="192.0.2.2" -CONFIG_LWM2M_DNS_SUPPORT=y -CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" -CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y -CONFIG_NATIVE_UART_0_ON_STDINOUT=y diff --git a/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf b/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf deleted file mode 100644 index 7a3fd344e50..00000000000 --- a/tests/net/lib/lwm2m/interop/boards/qemu_cortex_m3.conf +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG_NET_L2_ETHERNET=y -CONFIG_ETH_DRIVER=y -CONFIG_ETH_STELLARIS=y -CONFIG_NET_QEMU_ETHERNET=y - -# RAM/ROM tuning -CONFIG_IDLE_STACK_SIZE=128 -CONFIG_MBEDTLS_HEAP_SIZE=7000 -CONFIG_ISR_STACK_SIZE=512 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1024 -CONFIG_LWM2M_ENGINE_STACK_SIZE=2000 -CONFIG_LWM2M_LOG_LEVEL_INF=y -CONFIG_LWM2M_ENGINE_MAX_MESSAGES=3 -CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE=0 -CONFIG_LWM2M_ENGINE_MAX_OBSERVER=5 -CONFIG_LWM2M_SECURITY_DTLS_TLS_CIPHERSUITE_MAX=3 -CONFIG_LWM2M_DEVICE_PWRSRC_MAX=2 -CONFIG_LWM2M_DEVICE_ERROR_CODE_MAX=5 -CONFIG_LWM2M_DEVICE_EXT_DEV_INFO_MAX=2 -CONFIG_LWM2M_NUM_ATTR=10 diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf deleted file mode 100644 index 5d255e0513e..00000000000 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ /dev/null @@ -1,90 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_LOG=y -CONFIG_LWM2M_LOG_LEVEL_DBG=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NET_IPV6=y -CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 -CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=2 -CONFIG_NET_IPV4=y -CONFIG_NET_DHCPV4=n -CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 -CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT=2 -CONFIG_PRINTK=y -CONFIG_NET_PKT_RX_COUNT=10 -CONFIG_NET_PKT_TX_COUNT=10 -CONFIG_NET_BUF_RX_COUNT=10 -CONFIG_NET_BUF_TX_COUNT=10 -CONFIG_NET_MAX_CONTEXTS=5 -CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" -CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" -CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" -CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" - -CONFIG_NET_LOG=y - -CONFIG_NET_CONFIG_NEED_IPV6=y -CONFIG_NET_CONFIG_NEED_IPV4=y -CONFIG_NET_CONFIG_SETTINGS=y - -CONFIG_LWM2M=y -CONFIG_LWM2M_COAP_BLOCK_SIZE=512 -CONFIG_LWM2M_IPSO_SUPPORT=y -CONFIG_LWM2M_SHELL=y -CONFIG_LWM2M_ACCESS_CONTROL_ENABLE=n - -#Enable Portfolio object -CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y - -#LwM2M v1.1 configure -CONFIG_LWM2M_VERSION_1_1=y -CONFIG_LWM2M_DTLS_SUPPORT=y -CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=y - -#Enable SenML JSON content format -CONFIG_JSON_LIBRARY=y -CONFIG_BASE64=y -CONFIG_LWM2M_RW_SENML_JSON_SUPPORT=y - -#Enable SenML CBOR content format -CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT=y -CONFIG_LWM2M_RW_SENML_CBOR_RECORDS=60 -CONFIG_ZCBOR_CANONICAL=y - -#Enable legacy content formats -CONFIG_LWM2M_RW_JSON_SUPPORT=y -CONFIG_LWM2M_RW_OMA_TLV_SUPPORT=y - -# Longer endpoint name might be returned in a registration reply -CONFIG_COAP_EXTENDED_OPTIONS_LEN=y -CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 - -# Use QUEUE mode by default -CONFIG_LWM2M_QUEUE_MODE_ENABLED=y -CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 - -# LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 -CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 -CONFIG_LWM2M_SERVER_DEFAULT_PMIN=1 -CONFIG_LWM2M_SERVER_DEFAULT_PMAX=10 - -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_TLS_VERSION_1_2=y - -# Special MbedTLS changes -CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=8192 -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1500 -CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y - -# Disable RSA, we don't parse certs: saves flash/memory -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n -# Enable PSK instead -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y - -CONFIG_NET_SOCKETS_SOCKOPT_TLS=y -CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 -CONFIG_NET_SOCKETS_ENABLE_DTLS=y - -# MbedTLS needs a larger stack -CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py deleted file mode 100644 index 4d69a3a977f..00000000000 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import json -import requests -import binascii - -class Leshan: - def __init__(self, url: str): - self.api_url = url - self.timeout = 10 - self.format = 'TLV' - # self.format = "SENML_CBOR" - try: - resp = self.get('/security/clients') - if not isinstance(resp, list): - raise RuntimeError('Did not receive list of endpoints') - except requests.exceptions.ConnectionError: - raise RuntimeError('Leshan not responding') - - @staticmethod - def handle_response(resp: requests.models.Response): - """Generic response handler for all queries""" - if resp.status_code >= 300 or resp.status_code < 200: - raise RuntimeError(f'Error {resp.status_code}: {resp.text}') - if len(resp.text): - obj = json.loads(resp.text) - return obj - else: - return None - - def get(self, path: str): - """Send HTTP GET query""" - resp = requests.get(f'{self.api_url}{path}?timeout={self.timeout}&format={self.format}') - return Leshan.handle_response(resp) - - def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): - resp = requests.put(f'{self.api_url}{path}', data=data, headers=headers) - return Leshan.handle_response(resp) - - def put(self, path: str, data: str | dict, uri_options: str = ''): - if isinstance(data, dict): - data = json.dumps(data) - return self.put_raw(f'{path}?timeout={self.timeout}&format={self.format}' + uri_options, data=data, headers={'content-type': 'application/json'}) - - def post(self, path: str, data: str | dict | None = None): - resp = requests.post(f'{self.api_url}{path}', data=data, headers={'content-type': 'application/json'}) - return Leshan.handle_response(resp) - - def delete(self, path: str): - resp = requests.delete(f'{self.api_url}{path}') - return Leshan.handle_response(resp) - - def execute(self, endpoint: str, path: str): - return self.post(f'/clients/{endpoint}/{path}') - - def write(self, endpoint: str, path: str, value: bool | int | str): - if isinstance(value, bool): - type = 'boolean' - value = "true" if value else "false" - elif isinstance(value, int): - type = 'integer' - value = str(value) - elif isinstance(value, str): - type = 'string' - value = '"' + value + '"' - id = path.split('/')[2] - return self.put(f'/clients/{endpoint}/{path}', f'{{"id":{id},"kind":"singleResource","value":{value},"type":"{type}"}}') - - def read(self, endpoint: str, path: str): - resp = self.get(f'/clients/{endpoint}/{path}') - if not resp['success']: - return resp - content = resp['content'] - if content['kind'] == 'instance': - return content['resources'] - elif content['kind'] == 'singleResource': - return content['value'] - elif content['kind'] == 'multiResource': - return content['values'] - raise RuntimeError(f'Unhandled type {content["kind"]}') - - def create_psk_device(self, endpoint: str, passwd: str): - psk = binascii.b2a_hex(passwd.encode()).decode() - self.put('/security/clients/', f'{{"endpoint":"{endpoint}","tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}} }} }}') - - def delete_device(self, endpoint: str): - self.delete(f'/security/clients/{endpoint}') - - def create_bs_device(self, endpoint: str, server_uri: str, passwd: str): - psk = binascii.b2a_hex(passwd.encode()).decode() - data = f'{{"tls":{{"mode":"psk","details":{{"identity":"{endpoint}","key":"{psk}"}}}},"endpoint":"{endpoint}"}}' - self.put('/security/clients/', data) - id = str([ord(n) for n in endpoint]) - key = str([ord(n) for n in passwd]) - content = '{"servers":{"0":{"binding":"U","defaultMinPeriod":1,"lifetime":86400,"notifIfDisabled":false,"shortId":1}},"security":{"1":{"bootstrapServer":false,"clientOldOffTime":1,"publicKeyOrId":' + id + ',"secretKey":' + key + ',"securityMode":"PSK","serverId":1,"serverSmsNumber":"","smsBindingKeyParam":[],"smsBindingKeySecret":[],"smsSecurityMode":"NO_SEC","uri":"'+server_uri+'"}},"oscore":{},"toDelete":["/0","/1"]}' - self.post(f'/bootstrap/{endpoint}', content) - - def delete_bs_device(self, endpoint: str): - self.delete(f'/security/clients/{endpoint}') - self.delete(f'/bootstrap/{endpoint}') diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py deleted file mode 100644 index 21ed51ef1e6..00000000000 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ /dev/null @@ -1,446 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -import time -import logging -import pytest -from leshan import Leshan -import os -import binascii -import random -import string - -from twister_harness import Shell - -LESHAN_IP: str = '192.0.2.2' -COAP_PORT: int = 5683 -COAPS_PORT: int = 5684 -BOOTSTRAP_COAPS_PORT: int = 5784 - -logger = logging.getLogger(__name__) - -@pytest.fixture(scope='module') -def helperclient() -> object: - try: - from coapthon.client.helperclient import HelperClient - except ModuleNotFoundError: - pytest.skip('CoAPthon3 package not installed') - return HelperClient(server=('127.0.0.1', COAP_PORT)) - -@pytest.fixture(scope='session') -def leshan() -> Leshan: - try: - return Leshan("http://localhost:8080/api") - except RuntimeError: - pytest.skip('Leshan server not available') - -@pytest.fixture(scope='session') -def leshan_bootstrap() -> Leshan: - try: - return Leshan("http://localhost:8081/api") - except RuntimeError: - pytest.skip('Leshan Bootstrap server not available') - -# -# Test specification: -# https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf -# - -def verify_LightweightM2M_1_1_int_0(shell: Shell): - logger.info("LightweightM2M-1.1-int-0 - Client Initiated Bootstrap") - shell._device.readlines_until(regex='.*Bootstrap started with endpoint', timeout=5.0) - shell._device.readlines_until(regex='.*Bootstrap registration done', timeout=5.0) - shell._device.readlines_until(regex='.*Bootstrap data transfer done', timeout=5.0) - -def verify_LightweightM2M_1_1_int_1(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)") - verify_LightweightM2M_1_1_int_0(shell) - verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint) - -def verify_LightweightM2M_1_1_int_101(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-101 - Initial Registration") - shell._device.readlines_until(regex='.*Registration Done', timeout=5.0) - assert leshan.get(f'/clients/{endpoint}') - -def verify_LightweightM2M_1_1_int_102(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-102 - Registration Update") - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) - litetime = int(lines[0]) - lifetime = litetime + 10 - start_time = time.time() * 1000 - leshan.write(endpoint, '1/0/1', lifetime) - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - latest = leshan.get(f'/clients/{endpoint}') - assert latest["lastUpdate"] > start_time - assert latest["lastUpdate"] <= time.time()*1000 - assert latest["lifetime"] == lifetime - shell.exec_command('lwm2m write 1/0/1 -u32 86400') - -def verify_LightweightM2M_1_1_int_103(): - """LightweightM2M-1.1-int-103 - Deregistration""" - # Unsupported. We don't have "disabled" functionality in server object - -def verify_LightweightM2M_1_1_int_104(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-104 - Registration Update Trigger") - shell.exec_command('lwm2m update') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - leshan.execute(endpoint, '1/0/8') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - -def verify_LightweightM2M_1_1_int_105(shell: Shell, leshan: Leshan, endpoint: str, helperclient: object): - logger.info("LightweightM2M-1.1-int-105 - Discarded Register Update") - status = leshan.get(f'/clients/{endpoint}') - if status["secure"]: - logger.debug("Skip, requires non-secure connection") - return - id = status["registrationId"] - assert id - # Fake unregister message - helperclient.delete(f'rd/{id}', timeout=0.1) - helperclient.stop() - time.sleep(1) - shell.exec_command('lwm2m update') - shell._device.readlines_until(regex=r'.*Failed with code 4\.4', timeout=5.0) - shell._device.readlines_until(regex='.*Registration Done', timeout=10.0) - -def verify_LightweightM2M_1_1_int_107(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-107 - Extending the lifetime of a registration") - leshan.write(endpoint, '1/0/1', 120) - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/1 -u32')) - lifetime = int(lines[0]) - assert lifetime == 120 - logger.debug(f'sleeping for {lifetime} s') - shell._device.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=lifetime) - assert leshan.get(f'/clients/{endpoint}') - -def verify_LightweightM2M_1_1_int_108(leshan, endpoint): - logger.info("LightweightM2M-1.1-int-108 - Turn on Queue Mode") - assert leshan.get(f'/clients/{endpoint}')["queuemode"] - -def verify_LightweightM2M_1_1_int_109(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-109 - Behavior in Queue Mode") - verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) - shell._device.readlines_until(regex='.*Queue mode RX window closed', timeout=120) - # Restore previous value - shell.exec_command('lwm2m write 1/0/1 -u32 86400') - shell._device.readlines_until(regex='.*Registration update complete', timeout=10) - -def verify_LightweightM2M_1_1_int_201(shell: Shell, leshan: Leshan, endpoint: str): - - logger.info("LightweightM2M-1.1-int-201 - Querying basic information in Plain Text format") - fmt = leshan.format - leshan.format = 'TEXT' - assert leshan.get(f'/clients/{endpoint}/3/0/0')['content']['value'] == 'Zephyr' - assert leshan.get(f'/clients/{endpoint}/3/0/1')['content']['value'] == 'client-1' - assert leshan.get(f'/clients/{endpoint}/3/0/2')['content']['value'] == 'serial-1' - leshan.format = fmt - -def verify_device_object(resp): - ''' Verify that Device object match Configuration 3 ''' - assert resp['valid'] is True - found = 0 - for res in resp['content']['resources']: - if res['id'] == 0: - assert res['value'] == 'Zephyr' - found += 1 - elif res['id'] == 1: - assert res['value'] == 'client-1' - found += 1 - elif res['id'] == 2: - assert res['value'] == 'serial-1' - found += 1 - elif res['id'] == 3: - assert res['value'] == '1.2.3' - found += 1 - elif res['id'] == 11: - assert res['kind'] == 'multiResource' - assert res['values']['0'] == '0' - found += 1 - elif res['id'] == 16: - assert res['value'] == 'U' - found += 1 - assert found == 6 - -def verify_server_object(obj): - ''' Verify that server object match Configuration 3 ''' - found = 0 - for res in obj['resources']: - if res['id'] == 0: - assert res['value'] == '1' - found += 1 - elif res['id'] == 1: - assert res['value'] == '86400' - found += 1 - elif res['id'] == 2: - assert res['value'] == '1' - found += 1 - elif res['id'] == 3: - assert res['value'] == '10' - found += 1 - elif res['id'] == 5: - assert res['value'] == '86400' - found += 1 - elif res['id'] == 6: - assert res['value'] is False - found += 1 - elif res['id'] == 7: - assert res['value'] == 'U' - found += 1 - assert found == 7 - -def verify_LightweightM2M_1_1_int_203(shell: Shell, leshan: Leshan, endpoint: str): - shell.exec_command('lwm2m update') - logger.info('LightweightM2M-1.1-int-203 - Querying basic information in TLV format') - fmt = leshan.format - leshan.format = 'TLV' - resp = leshan.get(f'/clients/{endpoint}/3/0') - verify_device_object(resp) - leshan.format = fmt - -def verify_LightweightM2M_1_1_int_204(shell: Shell, leshan: Leshan, endpoint: str): - shell.exec_command('lwm2m update') - logger.info('LightweightM2M-1.1-int-204 - Querying basic information in JSON format') - fmt = leshan.format - leshan.format = 'JSON' - resp = leshan.get(f'/clients/{endpoint}/3/0') - verify_device_object(resp) - leshan.format = fmt - -def verify_LightweightM2M_1_1_int_205(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-205 - Setting basic information in Plain Text format') - fmt = leshan.format - leshan.format = 'TEXT' - leshan.write(endpoint, '1/0/2', 101) - leshan.write(endpoint, '1/0/3', 1010) - leshan.write(endpoint, '1/0/5', 2000) - assert leshan.read(endpoint, '1/0/2') == '101' - assert leshan.read(endpoint, '1/0/3') == '1010' - assert leshan.read(endpoint, '1/0/5') == '2000' - leshan.write(endpoint, '1/0/2', 1) - leshan.write(endpoint, '1/0/3', 10) - leshan.write(endpoint, '1/0/5', 86400) - assert leshan.read(endpoint, '1/0/2') == '1' - assert leshan.read(endpoint, '1/0/3') == '10' - assert leshan.read(endpoint, '1/0/5') == '86400' - leshan.format = fmt - -def verify_LightweightM2M_1_1_int_211(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-211 - Querying basic information in CBOR format') - fmt = leshan.format - leshan.format = 'CBOR' - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 1/0/0 -u16')) - id = lines[0] - assert leshan.read(endpoint, '1/0/0') == id - assert leshan.read(endpoint, '1/0/6') is False - assert leshan.read(endpoint, '1/0/7') == 'U' - leshan.format = fmt - -def verify_LightweightM2M_1_1_int_212(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-212 - Setting basic information in CBOR format') - fmt = leshan.format - leshan.format = 'CBOR' - leshan.write(endpoint, '1/0/2', 101) - leshan.write(endpoint, '1/0/3', 1010) - leshan.write(endpoint, '1/0/6', True) - assert leshan.read(endpoint, '1/0/2') == '101' - assert leshan.read(endpoint, '1/0/3') == '1010' - assert leshan.read(endpoint, '1/0/6') is True - leshan.write(endpoint, '1/0/2', 1) - leshan.write(endpoint, '1/0/3', 10) - leshan.write(endpoint, '1/0/6', False) - leshan.format = fmt - -def verify_setting_basic_in_format(shell, leshan, endpoint, format): - fmt = leshan.format - leshan.format = format - server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] - verify_server_object(server_obj) - # Remove Read-Only resources, so we don't end up writing those - for res in server_obj['resources']: - if res['id'] in (0, 11, 12): - server_obj['resources'].remove(res) - data = '''{ - "kind": "instance", - "id": 0, - "resources": [ - { - "id": 2, - "kind": "singleResource", - "value": "101", - "type": "integer" - }, - { - "id": 3, - "kind": "singleResource", - "value": "1010", - "type": "integer" - }, - { - "id": 5, - "kind": "singleResource", - "value": "2000", - "type": "integer" - }, - { - "id": 6, - "kind": "singleResource", - "value": true, - "type": "boolean" - }, - { - "id": 7, - "kind": "singleResource", - "value": "U", - "type": "string" - } - ] - }''' - assert leshan.put(f'/clients/{endpoint}/1/0', data, uri_options = '&replace=false')['status'] == 'CHANGED(204)' - resp = leshan.get(f'/clients/{endpoint}/1/0') - assert resp['valid'] is True - found = 0 - for res in resp['content']['resources']: - if res['id'] == 2: - assert res['value'] == '101' - found += 1 - elif res['id'] == 3: - assert res['value'] == '1010' - found += 1 - elif res['id'] == 5: - assert res['value'] == '2000' - found += 1 - elif res['id'] == 6: - assert res['value'] is True - found += 1 - elif res['id'] == 7: - assert res['value'] == 'U' - found += 1 - assert found == 5 - assert leshan.put(f'/clients/{endpoint}/1/0', data = server_obj, uri_options = '&replace=true')['status'] == 'CHANGED(204)' - server_obj = leshan.get(f'/clients/{endpoint}/1/0')['content'] - verify_server_object(server_obj) - leshan.format = fmt - -def verify_LightweightM2M_1_1_int_215(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-215 - Setting basic information in TLV format') - verify_setting_basic_in_format(shell, leshan, endpoint, 'TLV') - -def verify_LightweightM2M_1_1_int_220(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-220 - Setting basic information in JSON format') - verify_setting_basic_in_format(shell, leshan, endpoint, 'JSON') - -def verify_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: str): - logger.info('LightweightM2M-1.1-int-221 - Attempt to perform operations on Security') - assert leshan.read(endpoint, '0/0')['status'] == 'UNAUTHORIZED(401)' - assert leshan.write(endpoint, '0/0/0', 'coap://localhost')['status'] == 'UNAUTHORIZED(401)' - assert leshan.put_raw(f'/clients/{endpoint}/0/attributes?pmin=10')['status'] == 'UNAUTHORIZED(401)' - -def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): - logger.info("LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode") - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) - host = lines[0] - assert 'coaps://' in host - lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/2 -u8')) - mode = int(lines[0]) - assert mode == 0 - resp = leshan.get(f'/clients/{endpoint}') - assert resp["secure"] - -def test_lwm2m_bootstrap_psk(shell: Shell, leshan, leshan_bootstrap): - try: - # Generate randon device id and password (PSK key) - endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() - passwd = ''.join(random.choice(string.ascii_lowercase) for i in range(16)) - - - # Create device entries in Leshan and Bootstrap server - leshan_bootstrap.create_bs_device(endpoint, f'coaps://{LESHAN_IP}:{COAPS_PORT}', passwd) - leshan.create_psk_device(endpoint, passwd) - - # Allow engine to start & stop once. - time.sleep(2) - - # - # Verify PSK security using Bootstrap - # - - # Write bootsrap server information and PSK keys - shell.exec_command(f'lwm2m write 0/0/0 -s coaps://{LESHAN_IP}:{BOOTSTRAP_COAPS_PORT}') - shell.exec_command('lwm2m write 0/0/1 -b 1') - shell.exec_command('lwm2m write 0/0/2 -u8 0') - shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') - shell.exec_command(f'lwm2m write 0/0/5 -s {passwd}') - shell.exec_command(f'lwm2m start {endpoint} -b 1') - - - # - # Bootstrap Interface test cases - # LightweightM2M-1.1-int-0 (included) - # LightweightM2M-1.1-int-401 (included) - verify_LightweightM2M_1_1_int_1(shell, leshan, endpoint) - - # - # Registration Interface test cases (using PSK security) - # - verify_LightweightM2M_1_1_int_102(shell, leshan, endpoint) - # skip, not implemented verify_LightweightM2M_1_1_int_103() - verify_LightweightM2M_1_1_int_104(shell, leshan, endpoint) - # skip, included in 109: verify_LightweightM2M_1_1_int_107(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_108(leshan, endpoint) - verify_LightweightM2M_1_1_int_109(shell, leshan, endpoint) - - # - # Device management & Service Enablement Interface test cases - # - verify_LightweightM2M_1_1_int_201(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_203(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_204(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_205(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_211(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_212(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) - - shell.exec_command('lwm2m stop') - shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) - - finally: - # Remove device and bootstrap information - # Leshan does not accept non-secure connection if device information is provided with PSK - leshan.delete_device(endpoint) - leshan_bootstrap.delete_bs_device(endpoint) - - -def test_lwm2m_nosecure(shell: Shell, leshan, helperclient): - - # Allow engine to start & stop once. - time.sleep(2) - - # Generate randon device id and password (PSK key) - endpoint = 'client_' + binascii.b2a_hex(os.urandom(1)).decode() - - # - # Registration Interface test cases (using Non-secure mode) - # - shell.exec_command(f'lwm2m write 0/0/0 -s coap://{LESHAN_IP}:{COAP_PORT}') - shell.exec_command('lwm2m write 0/0/1 -b 0') - shell.exec_command('lwm2m write 0/0/2 -u8 3') - shell.exec_command(f'lwm2m write 0/0/3 -s {endpoint}') - shell.exec_command('lwm2m create 1/0') - shell.exec_command('lwm2m write 0/0/10 -u16 1') - shell.exec_command('lwm2m write 1/0/0 -u16 1') - shell.exec_command('lwm2m write 1/0/1 -u32 86400') - shell.exec_command(f'lwm2m start {endpoint} -b 0') - shell._device.readlines_until(regex=f"RD Client started with endpoint '{endpoint}'", timeout=10.0) - - verify_LightweightM2M_1_1_int_101(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_105(shell, leshan, endpoint, helperclient) # needs no-security - verify_LightweightM2M_1_1_int_215(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_220(shell, leshan, endpoint) - verify_LightweightM2M_1_1_int_221(shell, leshan, endpoint) - - # All done - shell.exec_command('lwm2m stop') - shell._device.readlines_until(regex=r'.*Deregistration success', timeout=10.0) diff --git a/tests/net/lib/lwm2m/interop/requirements.txt b/tests/net/lib/lwm2m/interop/requirements.txt deleted file mode 100644 index 38c501218ee..00000000000 --- a/tests/net/lib/lwm2m/interop/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -CoAPthon3 diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c deleted file mode 100644 index 1278d807b71..00000000000 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2017 Linaro Limited - * Copyright (c) 2017-2019 Foundries.io - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define LOG_MODULE_NAME net_lwm2m_client_app -#define LOG_LEVEL LOG_LEVEL_DBG - -#include -LOG_MODULE_REGISTER(LOG_MODULE_NAME); -#include -#include -#include -#include -#include -#include - -#define APP_BANNER "Run LWM2M client" - -#define WAIT_TIME K_SECONDS(10) -#define CONNECT_TIME K_SECONDS(10) - -#define NAME "Zephyr" -#define MODEL "client-1" -#define SERIAL "serial-1" -#define VERSION "1.2.3" - -static struct lwm2m_ctx client; - -static int device_reboot_cb(uint16_t obj_inst_id, - uint8_t *args, uint16_t args_len) -{ - LOG_INF("DEVICE: REBOOT"); - return 0; -} - - -static int lwm2m_setup(void) -{ - /* setup DEVICE object */ - - lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 0), NAME, sizeof(NAME), - sizeof(NAME), LWM2M_RES_DATA_FLAG_RO); - lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 1), MODEL, sizeof(MODEL), - sizeof(MODEL), LWM2M_RES_DATA_FLAG_RO); - lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 2), SERIAL, sizeof(SERIAL), - sizeof(SERIAL), LWM2M_RES_DATA_FLAG_RO); - lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 3), VERSION, sizeof(VERSION), - sizeof(VERSION), LWM2M_RES_DATA_FLAG_RO); - lwm2m_register_exec_callback(&LWM2M_OBJ(3, 0, 4), device_reboot_cb); - lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 17), CONFIG_BOARD, sizeof(CONFIG_BOARD), - sizeof(CONFIG_BOARD), LWM2M_RES_DATA_FLAG_RO); - - return 0; -} - -static void rd_client_event(struct lwm2m_ctx *client, - enum lwm2m_rd_client_event client_event) -{ - switch (client_event) { - - case LWM2M_RD_CLIENT_EVENT_NONE: - /* do nothing */ - break; - - case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: - LOG_DBG("Bootstrap registration failure!"); - break; - - case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE: - LOG_DBG("Bootstrap registration complete"); - break; - - case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE: - LOG_DBG("Bootstrap transfer complete"); - break; - - case LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE: - LOG_DBG("Registration failure!"); - break; - - case LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE: - LOG_DBG("Registration complete"); - break; - - case LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT: - LOG_DBG("Registration timeout!"); - break; - - case LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE: - LOG_DBG("Registration update complete"); - break; - - case LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE: - LOG_DBG("Deregister failure!"); - break; - - case LWM2M_RD_CLIENT_EVENT_DISCONNECT: - LOG_DBG("Disconnected"); - break; - - case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF: - LOG_DBG("Queue mode RX window closed"); - break; - - case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED: - LOG_DBG("LwM2M engine suspended"); - break; - - case LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR: - LOG_ERR("LwM2M engine reported a network error."); - lwm2m_rd_client_stop(client, rd_client_event, true); - break; - - case LWM2M_RD_CLIENT_EVENT_REG_UPDATE: - LOG_DBG("Registration update"); - break; - } -} - -static void observe_cb(enum lwm2m_observe_event event, - struct lwm2m_obj_path *path, void *user_data) -{ - char buf[LWM2M_MAX_PATH_STR_SIZE]; - - switch (event) { - - case LWM2M_OBSERVE_EVENT_OBSERVER_ADDED: - LOG_INF("Observer added for %s", lwm2m_path_log_buf(buf, path)); - break; - - case LWM2M_OBSERVE_EVENT_OBSERVER_REMOVED: - LOG_INF("Observer removed for %s", lwm2m_path_log_buf(buf, path)); - break; - - case LWM2M_OBSERVE_EVENT_NOTIFY_ACK: - LOG_INF("Notify acknowledged for %s", lwm2m_path_log_buf(buf, path)); - break; - - case LWM2M_OBSERVE_EVENT_NOTIFY_TIMEOUT: - LOG_INF("Notify timeout for %s, trying registration update", - lwm2m_path_log_buf(buf, path)); - - lwm2m_rd_client_update(); - break; - } -} - -int main(void) -{ - int ret; - -#if defined(CONFIG_BOARD_NATIVE_POSIX) - srandom(time(NULL)); -#endif - - ret = lwm2m_setup(); - if (ret < 0) { - LOG_ERR("Cannot setup LWM2M fields (%d)", ret); - return 0; - } - - client.tls_tag = 1; - - lwm2m_rd_client_start(&client, CONFIG_BOARD, 0, rd_client_event, observe_cb); - lwm2m_rd_client_stop(&client, rd_client_event, false); - - return 0; -} diff --git a/tests/net/lib/lwm2m/interop/testcase.yaml b/tests/net/lib/lwm2m/interop/testcase.yaml deleted file mode 100644 index aeba64748df..00000000000 --- a/tests/net/lib/lwm2m/interop/testcase.yaml +++ /dev/null @@ -1,14 +0,0 @@ -tests: - net.lwm2m.interop: - harness: pytest - timeout: 300 - slow: true - integration_platforms: - - native_posix - platform_allow: - - native_posix - - qemu_cortex_m3 - tags: - - testing - - pytest - - shell From 49ffa81ed3a257901b5c11733601e883be266f39 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:46 +0000 Subject: [PATCH 4352/4498] Revert "[nrf fromtree] net: lwm2m: Add shell command to create object instances" This reverts commit 52d120825d49c1d37430162fbf9c1d4a8edd1bb9. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_shell.c | 36 ------------------------------ 1 file changed, 36 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index 2a86aa88d69..f8374eb34f2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -40,7 +40,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); "-sX\tWrite value as intX_t\n" \ "-f \tWrite value as float\n" \ "-t \tWrite value as time_t\n" -#define LWM2M_HELP_CREATE "Create object instance\ncreate PATH\n" #define LWM2M_HELP_START "Start the LwM2M RD (Registration / Discovery) Client\n" \ "start EP_NAME [BOOTSTRAP FLAG]\n" \ "-b \tSet the bootstrap flag (default 0)\n" @@ -373,40 +372,6 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) return 0; } -static int cmd_create(const struct shell *sh, size_t argc, char **argv) -{ - struct lwm2m_obj_path path; - struct lwm2m_engine_obj_inst *obj_inst; - int ret; - - if (argc < 2) { - shell_error(sh, "No object ID given\n"); - shell_help(sh); - return -EINVAL; - } - - ret = lwm2m_string_to_path(argv[1], &path, '/'); - if (ret < 0) { - shell_error(sh, "failed to read path (%d)\n", ret); - return -ENOEXEC; - } - - if (path.level != LWM2M_PATH_LEVEL_OBJECT_INST) { - shell_error(sh, "path is not an object instance\n"); - shell_help(sh); - return -EINVAL; - } - - ret = lwm2m_create_obj_inst(path.obj_id, path.obj_inst_id, &obj_inst); - if (ret < 0) { - shell_error(sh, "Failed to create object instance %d/%d, ret=%d", path.obj_id, - path.obj_inst_id, ret); - return -ENOEXEC; - } - - return 0; -} - static int cmd_start(const struct shell *sh, size_t argc, char **argv) { struct lwm2m_ctx *ctx = lwm2m_rd_client_ctx(); @@ -596,7 +561,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(exec, NULL, LWM2M_HELP_EXEC, cmd_exec, 2, 1), SHELL_CMD_ARG(read, NULL, LWM2M_HELP_READ, cmd_read, 2, 1), SHELL_CMD_ARG(write, NULL, LWM2M_HELP_WRITE, cmd_write, 3, 1), - SHELL_CMD_ARG(create, NULL, LWM2M_HELP_CREATE, cmd_create, 2, 0), SHELL_CMD_ARG(start, NULL, LWM2M_HELP_START, cmd_start, 2, 2), SHELL_CMD_ARG(stop, NULL, LWM2M_HELP_STOP, cmd_stop, 1, 1), SHELL_CMD_ARG(update, NULL, LWM2M_HELP_UPDATE, cmd_update, 1, 0), From 3a43bf79655ff04b4e399ed03ea6b8e7b49e2274 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:46 +0000 Subject: [PATCH 4353/4498] Revert "[nrf fromtree] net: lwm2m: Don't allow operations on security object" This reverts commit 98a073881f16b6f656f52c697e333a38a25c0d3d. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 1a7d023ceb2..952a3d9c130 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2330,11 +2330,6 @@ int handle_request(struct coap_packet *request, struct lwm2m_message *msg) goto error; } #endif - if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID && !msg->ctx->bootstrap_mode) { - r = -EACCES; - goto error; - } - switch (msg->operation) { case LWM2M_OP_READ: From 555769dd1944eac90607ea856a5c609b4f39b936 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:46 +0000 Subject: [PATCH 4354/4498] Revert "[nrf fromtree] net: lwm2m: Fix build warning on access-control object" This reverts commit 2ea372c8833205e30b5986a1567ab48e735f1726. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_obj_access_control.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c b/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c index 383dbe9b539..1a83ef5ad29 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_access_control.c @@ -432,10 +432,10 @@ static int ac_control_init(void) ac_obj.create_cb = ac_create; lwm2m_register_obj(&ac_obj); - if (!IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { - /* add the objects/object instances that were created before the ac control */ - add_existing_objects(); - } +#if !IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) + /* add the objects/object instances that were created before the ac control object */ + add_existing_objects(); +#endif /* CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP */ return 0; } From 277e2837d2f5518d50878d2685b325df3f677d66 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:46 +0000 Subject: [PATCH 4355/4498] Revert "[nrf fromtree] net: lwm2m: Allow Bootstrap server to close DTLS connection" This reverts commit 2a642c8d8dace1cfe3ea52f80dcfd41bd0832d92. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index feebcaeea17..fca3f7d560f 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -89,10 +89,12 @@ static void set_sm_state(uint8_t sm_state); enum sm_engine_state { ENGINE_IDLE, ENGINE_INIT, +#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) ENGINE_DO_BOOTSTRAP_REG, ENGINE_BOOTSTRAP_REG_SENT, ENGINE_BOOTSTRAP_REG_DONE, ENGINE_BOOTSTRAP_TRANS_DONE, +#endif ENGINE_DO_REGISTRATION, ENGINE_SEND_REGISTRATION, ENGINE_REGISTRATION_SENT, @@ -353,21 +355,15 @@ static void sm_handle_failure_state(enum sm_engine_state sm_state) static void socket_fault_cb(int error) { LOG_ERR("RD Client socket error: %d", error); - lwm2m_socket_close(client.ctx); - if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) && sm_is_bootstrap()) { + if (sm_is_bootstrap()) { client.ctx->sec_obj_inst = -1; /* force full registration */ client.last_update = 0; - - if (get_sm_state() == ENGINE_BOOTSTRAP_TRANS_DONE) { - /* Ignore the error, some servers close the connection immediately - * after receiving Ack to Bootstrap-Finish command. - */ - return; - } } + lwm2m_socket_close(client.ctx); + /* Network error state causes engine to re-register, * so only trigger that state if we are not stopping the * engine. From 8a80faa616f89a1345c3ec9c497af9c0397d8ad9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:47 +0000 Subject: [PATCH 4356/4498] Revert "[nrf fromtree] net: lwm2m: Add timeouts to state machine" This reverts commit 8ff85348030453c3562bf8edcc4f9a583f168f22. Signed-off-by: Dominik Ermel --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index fca3f7d560f..0f4405bfc92 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -70,7 +70,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_QUEUE_LEN sizeof("Q") #define DELAY_BEFORE_CLOSING (1 * MSEC_PER_SEC) #define DELAY_FOR_ACK 100U -#define EXCHANGE_LIFETIME 247U static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -121,7 +120,6 @@ struct lwm2m_rd_client_info { int64_t last_update; int64_t last_tx; int64_t next_event; - int64_t last_state_change; char ep_name[CLIENT_EP_LEN]; char server_ep[CLIENT_EP_LEN]; @@ -174,7 +172,6 @@ void engine_update_tx_time(void) static void next_event_at(int64_t timestamp) { - client.next_event = timestamp; (void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp); } @@ -239,7 +236,6 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) lwm2m_close_socket(client.ctx); } } - client.last_state_change = k_uptime_get(); next_event_at(k_uptime_get() + delay_ms); k_mutex_unlock(&client.mutex); } @@ -1292,11 +1288,8 @@ static void lwm2m_rd_client_service(struct k_work *work) { k_mutex_lock(&client.mutex, K_FOREVER); - int64_t timeout = 0; - if (client.ctx) { LOG_DBG("State: %d", get_sm_state()); - client.next_event = INT64_MAX; switch (get_sm_state()) { case ENGINE_IDLE: if (client.ctx->sock_fd > -1) { @@ -1319,12 +1312,10 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_BOOTSTRAP_REG_SENT: /* wait for bootstrap registration done */ - timeout = EXCHANGE_LIFETIME; break; case ENGINE_BOOTSTRAP_REG_DONE: /* wait for transfer done */ - timeout = EXCHANGE_LIFETIME; break; case ENGINE_BOOTSTRAP_TRANS_DONE: @@ -1342,7 +1333,6 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_REGISTRATION_SENT: /* wait registration to be done or timeout */ - timeout = EXCHANGE_LIFETIME; break; case ENGINE_REGISTRATION_DONE: @@ -1356,7 +1346,6 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_UPDATE_SENT: /* wait update to be done or abort */ - timeout = EXCHANGE_LIFETIME; break; case ENGINE_DEREGISTER: @@ -1365,7 +1354,6 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_DEREGISTER_SENT: /* wait for deregister to be done or reset */ - timeout = EXCHANGE_LIFETIME; break; case ENGINE_DEREGISTERED: @@ -1381,17 +1369,6 @@ static void lwm2m_rd_client_service(struct k_work *work) LOG_ERR("Unhandled state: %d", get_sm_state()); } - - if (timeout) { - int64_t end = client.last_state_change + timeout * MSEC_PER_SEC; - - if (end < k_uptime_get()) { - LOG_DBG("State machine have timed out"); - sm_handle_timeout_state(NULL, ENGINE_INIT); - } else if (client.next_event > end) { - next_event_at(end); - } - } } k_mutex_unlock(&client.mutex); From 5eba083e6471a6b8d5a45f0ffbd733b1c74b9794 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:47 +0000 Subject: [PATCH 4357/4498] Revert "[nrf fromtree] test: lwm2m: Fix minor timing issue" This reverts commit 09bcf9d88014ee367f0db56ff244754b306efe31. Signed-off-by: Dominik Ermel --- tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt | 2 +- tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 81e129c56c1..5f29bdad0dd 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -23,7 +23,7 @@ add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH=32) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES=2) add_compile_definitions(CONFIG_LWM2M_COAP_BLOCK_SIZE=256) add_compile_definitions(CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512) -add_compile_definitions(CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=20) +add_compile_definitions(CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=60) add_compile_definitions(CONFIG_LWM2M_SECURITY_INSTANCE_COUNT=1) add_compile_definitions(CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10) add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_UPTIME=10) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index 41789e20340..58f64f4984d 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -117,12 +117,10 @@ uint16_t counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; struct lwm2m_message *pending_message; void *(*pending_message_cb)(); static bool running; -K_SEM_DEFINE(srv_sem, 0, 1); static void service_work_fn(struct k_work *work) { while (running) { - k_sleep(K_MSEC(10)); if (pending_message != NULL && pending_message_cb != NULL) { pending_message_cb(pending_message); pending_message = NULL; @@ -131,9 +129,8 @@ static void service_work_fn(struct k_work *work) if (next && next < k_uptime_get()) { next = 0; service(NULL); - k_sem_give(&srv_sem); } - + k_sleep(K_MSEC(10)); counter--; /* avoid endless loop if rd client is stuck somewhere */ @@ -146,8 +143,10 @@ static void service_work_fn(struct k_work *work) void wait_for_service(uint16_t cycles) { - while (cycles--) { - k_sem_take(&srv_sem, K_MSEC(100)); + uint16_t end = counter - cycles; + + while (counter > end) { + k_sleep(K_MSEC(10)); } } @@ -158,7 +157,6 @@ void test_lwm2m_engine_start_service(void) running = true; counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; k_work_submit(&service_work); - k_sem_reset(&srv_sem); } void test_lwm2m_engine_stop_service(void) From c5dfc5ee01425876076bb18be1161fb0abbe8bb5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:47 +0000 Subject: [PATCH 4358/4498] Revert "[nrf fromtree] nrf53: pretick with NRF_802154_RADIO_DRIVER" This reverts commit d4e8b1eeae72a627d38c3cf08736dfe436efdac5. Signed-off-by: Dominik Ermel --- drivers/timer/Kconfig.nrf_rtc | 1 - soc/arm/nordic_nrf/nrf53/Kconfig.soc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index acb6f123afe..cda05d4dabe 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -19,7 +19,6 @@ if NRF_RTC_TIMER config NRF_RTC_TIMER_USER_CHAN_COUNT int "Additional channels that can be used" - default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 0 help diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 2ad4a7add66..9bb4caf2bb9 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -51,6 +51,7 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND config SOC_NRF53_RTC_PRETICK bool "Pre-tick workaround for nRF5340 anomaly 165" + depends on !NRF_802154_RADIO_DRIVER select NRFX_DPPI select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET @@ -201,7 +202,6 @@ config NRF53_SYNC_RTC_INIT_PRIORITY nRF53 Synchronized RTC initialization priority. config NRF_RTC_TIMER_USER_CHAN_COUNT - default 2 if NRF_802154_RADIO_DRIVER && SOC_NRF5340_CPUNET default 3 if NRF_802154_RADIO_DRIVER default 1 From bc5f3901f483e2a1982ef7b15fa41193d8157633 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:47 +0000 Subject: [PATCH 4359/4498] Revert "[nrf fromtree] nrf53: RTC pretick allows user channels and require just one CC" This reverts commit 0704fb1e49aef4c6d9f892b0d46c771f0081e360. Signed-off-by: Dominik Ermel --- drivers/timer/nrf_rtc_timer.c | 18 +- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 9 +- soc/arm/nordic_nrf/nrf53/soc.c | 274 +++++---------------------- 3 files changed, 62 insertions(+), 239 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index 9241c5b7a10..e8ba5bd42a5 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -17,18 +17,20 @@ #include #include -#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ - IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) - #define EXT_CHAN_COUNT CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT #define CHAN_COUNT (EXT_CHAN_COUNT + 1) #define RTC NRF_RTC1 #define RTC_IRQn NRFX_IRQ_NUMBER_GET(RTC) #define RTC_LABEL rtc1 -#define CHAN_COUNT_MAX (RTC1_CC_NUM - (RTC_PRETICK ? 1 : 0)) +#define RTC_CH_COUNT RTC1_CC_NUM -BUILD_ASSERT(CHAN_COUNT <= CHAN_COUNT_MAX, "Not enough compare channels"); +#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ + IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) + +BUILD_ASSERT(!RTC_PRETICK || !(RTC_PRETICK && (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT > 0)), + "Cannot use user channels when RTC pretick is used"); +BUILD_ASSERT(CHAN_COUNT <= RTC_CH_COUNT, "Not enough compare channels"); /* Ensure that counter driver for RTC1 is not enabled. */ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), "Counter for RTC1 must be disabled"); @@ -47,6 +49,7 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), #define ANCHOR_RANGE_END (7 * COUNTER_SPAN / 8) #define TARGET_TIME_INVALID (UINT64_MAX) +extern void rtc_pretick_rtc1_cc0_set_hook(uint32_t val); extern void rtc_pretick_rtc1_isr_hook(void); static volatile uint32_t overflow_cnt; @@ -265,7 +268,7 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) * This never happens when the written value is N+3. Use 3 cycles as * the nearest possible scheduling then. */ - enum { MIN_CYCLES_FROM_NOW = 3 }; + enum { MIN_CYCLES_FROM_NOW = RTC_PRETICK ? 4 : 3 }; uint32_t cc_val = req_cc; uint32_t cc_inc = MIN_CYCLES_FROM_NOW; @@ -282,6 +285,9 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) for (;;) { uint32_t now; + if (RTC_PRETICK) { + rtc_pretick_rtc1_cc0_set_hook(cc_val); + } set_comparator(chan, cc_val); /* Enable event routing after the required CC value was set. * Even though the above operation may get repeated (see below), diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 9bb4caf2bb9..b84985d57eb 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -16,7 +16,7 @@ config SOC_NRF5340_CPUNET bool select ARM_ON_EXIT_CPU_IDLE imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED - imply SOC_NRF53_RTC_PRETICK if !WDT_NRFX + imply SOC_NRF53_RTC_PRETICK choice prompt "nRF53x MCU Selection" @@ -50,14 +50,9 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND select ARM_ON_ENTER_CPU_IDLE_HOOK config SOC_NRF53_RTC_PRETICK - bool "Pre-tick workaround for nRF5340 anomaly 165" + bool depends on !NRF_802154_RADIO_DRIVER select NRFX_DPPI - select ARM_ON_ENTER_CPU_IDLE_HOOK if SOC_NRF5340_CPUNET - select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET - help - Indicates that the pre-tick workaround for the anomaly 165 that affects - the nRF5340 SoC should be applied. if SOC_NRF53_RTC_PRETICK diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index aa93dfd4b54..50f00932be9 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -43,11 +42,8 @@ #define PIN_XL1 0 #define PIN_XL2 1 -#define RTC1_PRETICK_CC_CHAN (RTC1_CC_NUM - 1) - -/* Mask of CC channels capable of generating interrupts, see nrf_rtc_timer.c */ -#define RTC1_PRETICK_SELECTED_CC_MASK BIT_MASK(CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT + 1U) -#define RTC0_PRETICK_SELECTED_CC_MASK BIT_MASK(NRF_RTC_CC_COUNT_MAX) +#define RTC1_PRETICK_CC_CHAN 1 +#define RTC1_PRETICK_OVERFLOW_CHAN 2 #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) #define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ @@ -134,240 +130,39 @@ static bool nrf53_anomaly_160_check(void) return true; } -#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) - -BUILD_ASSERT(!IS_ENABLED(CONFIG_WDT_NRFX), - "For CONFIG_SOC_NRF53_RTC_PRETICK watchdog is used internally for the pre-tick workaround on nRF5340 cpunet. Application cannot use the watchdog."); - -static inline uint32_t rtc_counter_sub(uint32_t a, uint32_t b) -{ - return (a - b) & NRF_RTC_COUNTER_MAX; -} - -static bool rtc_ticks_to_next_event_get(NRF_RTC_Type *rtc, uint32_t selected_cc_mask, uint32_t cntr, - uint32_t *ticks_to_next_event) -{ - bool result = false; - - /* Let's preload register to speed-up. */ - uint32_t reg_intenset = rtc->INTENSET; - - /* Note: TICK event not handled. */ - - if (reg_intenset & NRF_RTC_INT_OVERFLOW_MASK) { - /* Overflow can generate an interrupt. */ - *ticks_to_next_event = NRF_RTC_COUNTER_MAX + 1U - cntr; - result = true; - } - - for (uint32_t chan = 0; chan < NRF_RTC_CC_COUNT_MAX; chan++) { - if ((selected_cc_mask & (1U << chan)) && - (reg_intenset & NRF_RTC_CHANNEL_INT_MASK(chan))) { - /* The CC is in selected mask and is can generate an interrupt. */ - uint32_t cc = nrf_rtc_cc_get(rtc, chan); - uint32_t ticks_to_fire = rtc_counter_sub(cc, cntr); - - if (ticks_to_fire == 0U) { - /* When ticks_to_fire == 0, the event should have been just - * generated the interrupt can be already handled or be pending. - * However the next event is expected to be after counter wraps. - */ - ticks_to_fire = NRF_RTC_COUNTER_MAX + 1U; - } - - if (!result) { - *ticks_to_next_event = ticks_to_fire; - result = true; - } else if (ticks_to_fire < *ticks_to_next_event) { - *ticks_to_next_event = ticks_to_fire; - result = true; - } else { - /* CC that fires no earlier than already found. */ - } - } - } - - return result; -} - -static void rtc_counter_synchronized_get(NRF_RTC_Type *rtc_a, NRF_RTC_Type *rtc_b, - uint32_t *counter_a, uint32_t *counter_b) -{ - do { - *counter_a = nrf_rtc_counter_get(rtc_a); - barrier_dmem_fence_full(); - *counter_b = nrf_rtc_counter_get(rtc_b); - barrier_dmem_fence_full(); - } while (*counter_a != nrf_rtc_counter_get(rtc_a)); -} - -static uint8_t cpu_idle_prepare_monitor_dummy; -static bool cpu_idle_prepare_allows_sleep; - -static void cpu_idle_prepare_monitor_begin(void) -{ - __LDREXB(&cpu_idle_prepare_monitor_dummy); -} - -/* Returns 0 if no exception preempted since the last call to cpu_idle_prepare_monitor_begin. */ -static bool cpu_idle_prepare_monitor_end(void) -{ - /* The value stored is irrelevant. If any exception took place after - * cpu_idle_prepare_monitor_begin, the the local monitor is cleared and - * the store fails returning 1. - * See Arm v8-M Architecture Reference Manual: - * Chapter B9.2 The local monitors - * Chapter B9.4 Exclusive access instructions and the monitors - * See Arm Cortex-M33 Processor Technical Reference Manual - * Chapter 3.5 Exclusive monitor - */ - return __STREXB(0U, &cpu_idle_prepare_monitor_dummy); -} - -void z_arm_on_enter_cpu_idle_prepare(void) +bool z_arm_on_enter_cpu_idle(void) { - bool ok_to_sleep = true; - - cpu_idle_prepare_monitor_begin(); - - uint32_t rtc_counter = 0U; - uint32_t rtc_ticks_to_next_event = 0U; - uint32_t rtc0_counter = 0U; - uint32_t rtc0_ticks_to_next_event = 0U; - - rtc_counter_synchronized_get(NRF_RTC1, NRF_RTC0, &rtc_counter, &rtc0_counter); - - bool rtc_scheduled = rtc_ticks_to_next_event_get(NRF_RTC1, RTC1_PRETICK_SELECTED_CC_MASK, - rtc_counter, &rtc_ticks_to_next_event); - - if (rtc_ticks_to_next_event_get(NRF_RTC0, RTC0_PRETICK_SELECTED_CC_MASK, rtc0_counter, - &rtc0_ticks_to_next_event)) { - /* An event is scheduled on RTC0. */ - if (!rtc_scheduled) { - rtc_ticks_to_next_event = rtc0_ticks_to_next_event; - rtc_scheduled = true; - } else if (rtc0_ticks_to_next_event < rtc_ticks_to_next_event) { - rtc_ticks_to_next_event = rtc0_ticks_to_next_event; - } else { - /* Event on RTC0 will not happen earlier than already found. */ - } - } + bool ok_to_sleep = nrf53_anomaly_160_check(); - if (rtc_scheduled) { - static bool rtc_pretick_cc_set_on_time; - /* The pretick should happen 1 tick before the earliest scheduled event - * that can trigger an interrupt. - */ - uint32_t rtc_pretick_cc_val = (rtc_counter + rtc_ticks_to_next_event - 1U) - & NRF_RTC_COUNTER_MAX; - - if (rtc_pretick_cc_val != nrf_rtc_cc_get(NRF_RTC1, RTC1_PRETICK_CC_CHAN)) { - /* The CC for pretick needs to be updated. */ - nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, rtc_pretick_cc_val); - - if (rtc_ticks_to_next_event >= NRF_RTC_COUNTER_MAX/2) { - /* Pretick is scheduled so far in the future, assumed on time. */ - rtc_pretick_cc_set_on_time = true; - } else { - /* Let's check if we updated CC on time, so that the CC can - * take effect. - */ - barrier_dmem_fence_full(); - rtc_counter = nrf_rtc_counter_get(NRF_RTC1); - uint32_t pretick_cc_to_counter = - rtc_counter_sub(rtc_pretick_cc_val, rtc_counter); - - if ((pretick_cc_to_counter < 3) || - (pretick_cc_to_counter >= NRF_RTC_COUNTER_MAX/2)) { - /* The COUNTER value is close enough to the expected - * pretick CC or has just expired, so the pretick event - * generation is not guaranteed. - */ - rtc_pretick_cc_set_on_time = false; - } else { - /* The written rtc_pretick_cc is guaranteed to to trigger - * compare event. - */ - rtc_pretick_cc_set_on_time = true; - } - } - } else { - /* The CC for pretick doesn't need to be updated, however - * rtc_pretick_cc_set_on_time still holds if we managed to set it on time. - */ - } +#if (LOG_LEVEL >= LOG_LEVEL_DBG) + static bool suppress_message; - /* If the CC for pretick is set on time, so the pretick CC event can be reliably - * generated then allow to sleep. Otherwise (the CC for pretick cannot be reliably - * generated, because CC was set very short to it's fire time) sleep not at all. - */ - ok_to_sleep = rtc_pretick_cc_set_on_time; - } else { - /* No events on any RTC timers are scheduled. */ + if (ok_to_sleep) { + suppress_message = false; + } else if (!suppress_message) { + LOG_DBG("Anomaly 160 trigger conditions detected."); + suppress_message = true; } - +#endif +#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) if (ok_to_sleep) { NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] |= IPC_PUBLISH_RECEIVE_EN_Msk; - if (!nrf_rtc_event_check(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN))) { + if (!nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) && + !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) && + !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { NRF_WDT->TASKS_STOP = 1; /* Check if any event did not occur after we checked for * stopping condition. If yes, we might have stopped WDT * when it should be running. Restart it. */ - if (nrf_rtc_event_check(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN))) { + if (nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) || + nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) || + nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { NRF_WDT->TASKS_START = 1; } } } - - cpu_idle_prepare_allows_sleep = ok_to_sleep; -} -#endif /* CONFIG_SOC_NRF53_RTC_PRETICK && CONFIG_SOC_NRF5340_CPUNET */ - -bool z_arm_on_enter_cpu_idle(void) -{ - bool ok_to_sleep = true; - -#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) - if (cpu_idle_prepare_monitor_end() == 0) { - /* No exception happened since cpu_idle_prepare_monitor_begin. - * We can trust the outcome of. z_arm_on_enter_cpu_idle_prepare - */ - ok_to_sleep = cpu_idle_prepare_allows_sleep; - } else { - /* Exception happened since cpu_idle_prepare_monitor_begin. - * The values which z_arm_on_enter_cpu_idle_prepare could be changed - * by the exception, so we can not trust to it's outcome. - * Do not sleep at all, let's try in the next iteration of idle loop. - */ - ok_to_sleep = false; - } -#endif - - if (ok_to_sleep) { - ok_to_sleep = nrf53_anomaly_160_check(); - -#if (LOG_LEVEL >= LOG_LEVEL_DBG) - static bool suppress_message; - - if (ok_to_sleep) { - suppress_message = false; - } else if (!suppress_message) { - LOG_DBG("Anomaly 160 trigger conditions detected."); - suppress_message = true; - } -#endif - } - -#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) - if (!ok_to_sleep) { - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= - ~IPC_PUBLISH_RECEIVE_EN_Msk; - NRF_WDT->TASKS_STOP = 1; - } #endif return ok_to_sleep; @@ -417,12 +212,25 @@ void rtc_pretick_rtc0_isr_hook(void) rtc_pretick_rtc_isr_hook(); } +void rtc_pretick_rtc1_cc0_set_hook(uint32_t val) +{ + nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, val - 1); +} + void rtc_pretick_rtc1_isr_hook(void) { rtc_pretick_rtc_isr_hook(); - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW)) { + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); + } + } + if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_COMPARE_0)) { + if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + } } } @@ -436,8 +244,11 @@ static int rtc_pretick_cpunet_init(void) uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); uint32_t task_wdt = nrf_wdt_task_address_get(NRF_WDT, NRF_WDT_TASK_START); + uint32_t evt_mpsl_cc = nrf_rtc_event_address_get(NRF_RTC0, NRF_RTC_EVENT_COMPARE_3); uint32_t evt_cc = nrf_rtc_event_address_get(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + uint32_t evt_overflow = nrf_rtc_event_address_get(NRF_RTC1, + NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); /* Configure Watchdog to allow stopping. */ nrf_wdt_behaviour_set(NRF_WDT, WDT_CONFIG_STOPEN_Msk | BIT(4)); @@ -456,14 +267,24 @@ static int rtc_pretick_cpunet_init(void) return -ENOMEM; } + /* Setup a PPI connection between RTC "pretick" events and IPC task. */ + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE)) { + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_mpsl_cc); + } nrfx_gppi_event_endpoint_setup(ppi_ch, evt_cc); + nrfx_gppi_event_endpoint_setup(ppi_ch, evt_overflow); nrfx_gppi_task_endpoint_setup(ppi_ch, task_ipc); nrfx_gppi_event_endpoint_setup(ppi_ch, evt_ipc); nrfx_gppi_task_endpoint_setup(ppi_ch, task_wdt); nrfx_gppi_channels_enable(BIT(ppi_ch)); nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_CC_CHAN)); + nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_OVERFLOW_CHAN)); + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); + /* Set event 1 tick before overflow. */ + nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_OVERFLOW_CHAN, 0x00FFFFFF); return 0; } @@ -471,6 +292,7 @@ static int rtc_pretick_cpunet_init(void) static int rtc_pretick_init(void) { + ARG_UNUSED(unused); #ifdef CONFIG_SOC_NRF5340_CPUAPP return rtc_pretick_cpuapp_init(); #else From bc38ac400916728f358d2dced03f7e722c0a9111 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:48 +0000 Subject: [PATCH 4360/4498] Revert "[nrf fromtree] arch: arm: aarch32: Introduce z_arm_on_enter_cpu_idle_prepare() hook" This reverts commit b2a1ffbe848082f67c50e094dc065d6d17f5dcc6. Signed-off-by: Dominik Ermel --- arch/arm/Kconfig | 10 ---------- arch/arm/core/aarch32/cpu_idle.S | 25 +++++-------------------- include/zephyr/arch/arm/aarch32/misc.h | 9 --------- 3 files changed, 5 insertions(+), 39 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ef9a20d0cc9..e17cf3f9b31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -53,16 +53,6 @@ config ARM_ON_ENTER_CPU_IDLE_HOOK If needed, this hook can be used to prevent the CPU from actually entering sleep by skipping the WFE/WFI instruction. -config ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK - bool - help - Enables a hook (z_arm_on_enter_cpu_idle_prepare()) that is called when - the CPU is made idle (by k_cpu_idle() or k_cpu_atomic_idle()). - If needed, this hook can prepare data to upcoming call to - z_arm_on_enter_cpu_idle(). The z_arm_on_enter_cpu_idle_prepare differs - from z_arm_on_enter_cpu_idle because it is called before interrupts are - disabled. - config ARM_ON_EXIT_CPU_IDLE bool help diff --git a/arch/arm/core/aarch32/cpu_idle.S b/arch/arm/core/aarch32/cpu_idle.S index 95e37917180..8164959ab29 100644 --- a/arch/arm/core/aarch32/cpu_idle.S +++ b/arch/arm/core/aarch32/cpu_idle.S @@ -85,24 +85,16 @@ _skip_\@: .endm SECTION_FUNC(TEXT, arch_cpu_idle) -#if defined(CONFIG_TRACING) || \ - defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) - push {r0, lr} - #ifdef CONFIG_TRACING + push {r0, lr} bl sys_trace_idle -#endif -#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK - bl z_arm_on_enter_cpu_idle_prepare -#endif - #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 #else pop {r0, lr} #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#endif +#endif /* CONFIG_TRACING */ #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* @@ -146,24 +138,17 @@ SECTION_FUNC(TEXT, arch_cpu_idle) bx lr SECTION_FUNC(TEXT, arch_cpu_atomic_idle) -#if defined(CONFIG_TRACING) || \ - defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) - push {r0, lr} - #ifdef CONFIG_TRACING + push {r0, lr} bl sys_trace_idle -#endif -#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK - bl z_arm_on_enter_cpu_idle_prepare -#endif - #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 #else pop {r0, lr} #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -#endif +#endif /* CONFIG_TRACING */ + /* * Lock PRIMASK while sleeping: wfe will still get interrupted by * incoming interrupts but the CPU will not service them right away. diff --git a/include/zephyr/arch/arm/aarch32/misc.h b/include/zephyr/arch/arm/aarch32/misc.h index ab67a35e94c..24ed69f663c 100644 --- a/include/zephyr/arch/arm/aarch32/misc.h +++ b/include/zephyr/arch/arm/aarch32/misc.h @@ -51,15 +51,6 @@ extern bool z_arm_thread_is_in_user_mode(void); bool z_arm_on_enter_cpu_idle(void); #endif -#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK) -/* Prototype of a hook that can be enabled to be called every time the CPU is - * made idle (the calls will be done from k_cpu_idle() and k_cpu_atomic_idle()). - * The function is called before interrupts are disabled and can prepare to - * upcoming call to z_arm_on_enter_cpu_idle. - */ -void z_arm_on_enter_cpu_idle_prepare(void); -#endif - #endif #ifdef __cplusplus From 52549a5be97225317179133636ac7341e8d96675 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:48 +0000 Subject: [PATCH 4361/4498] Revert "[nrf fromtree] nrf53: Add RTC pretick" This reverts commit 3d2da670428f177fdbe761db49783cdff83503ee. Signed-off-by: Dominik Ermel --- drivers/timer/nrf_rtc_timer.c | 17 +-- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 21 ---- soc/arm/nordic_nrf/nrf53/soc.c | 164 --------------------------- 3 files changed, 1 insertion(+), 201 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index e8ba5bd42a5..4410529608b 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -25,11 +25,6 @@ #define RTC_LABEL rtc1 #define RTC_CH_COUNT RTC1_CC_NUM -#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \ - IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET)) - -BUILD_ASSERT(!RTC_PRETICK || !(RTC_PRETICK && (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT > 0)), - "Cannot use user channels when RTC pretick is used"); BUILD_ASSERT(CHAN_COUNT <= RTC_CH_COUNT, "Not enough compare channels"); /* Ensure that counter driver for RTC1 is not enabled. */ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), @@ -49,9 +44,6 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(RTC_LABEL), disabled), #define ANCHOR_RANGE_END (7 * COUNTER_SPAN / 8) #define TARGET_TIME_INVALID (UINT64_MAX) -extern void rtc_pretick_rtc1_cc0_set_hook(uint32_t val); -extern void rtc_pretick_rtc1_isr_hook(void); - static volatile uint32_t overflow_cnt; static volatile uint64_t anchor; static uint64_t last_count; @@ -268,7 +260,7 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) * This never happens when the written value is N+3. Use 3 cycles as * the nearest possible scheduling then. */ - enum { MIN_CYCLES_FROM_NOW = RTC_PRETICK ? 4 : 3 }; + enum { MIN_CYCLES_FROM_NOW = 3 }; uint32_t cc_val = req_cc; uint32_t cc_inc = MIN_CYCLES_FROM_NOW; @@ -285,9 +277,6 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) for (;;) { uint32_t now; - if (RTC_PRETICK) { - rtc_pretick_rtc1_cc0_set_hook(cc_val); - } set_comparator(chan, cc_val); /* Enable event routing after the required CC value was set. * Even though the above operation may get repeated (see below), @@ -570,10 +559,6 @@ void rtc_nrf_isr(const void *arg) { ARG_UNUSED(arg); - if (RTC_PRETICK) { - rtc_pretick_rtc1_isr_hook(); - } - if (nrf_rtc_int_enable_check(RTC, NRF_RTC_INT_OVERFLOW_MASK) && nrf_rtc_event_check(RTC, NRF_RTC_EVENT_OVERFLOW)) { nrf_rtc_event_clear(RTC, NRF_RTC_EVENT_OVERFLOW); diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index b84985d57eb..122c36988e5 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -10,13 +10,11 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_FPU select ARMV8_M_DSP select HAS_POWEROFF - imply SOC_NRF53_RTC_PRETICK config SOC_NRF5340_CPUNET bool select ARM_ON_EXIT_CPU_IDLE imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED - imply SOC_NRF53_RTC_PRETICK choice prompt "nRF53x MCU Selection" @@ -49,25 +47,6 @@ config SOC_NRF53_ANOMALY_160_WORKAROUND depends on SYS_CLOCK_EXISTS select ARM_ON_ENTER_CPU_IDLE_HOOK -config SOC_NRF53_RTC_PRETICK - bool - depends on !NRF_802154_RADIO_DRIVER - select NRFX_DPPI - -if SOC_NRF53_RTC_PRETICK - -config SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET - int "IPC 0 channel for RTC pretick" - range 0 15 - default 10 - -config SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET - int "IPC 1 channel for RTC pretick" - range 0 15 - default 11 - -endif - if SOC_NRF5340_CPUAPP config SOC_DCDC_NRF53X_APP diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index 50f00932be9..6552f9d4bb1 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #if defined(CONFIG_SOC_NRF5340_CPUAPP) #include #include @@ -33,8 +31,6 @@ #if defined(CONFIG_PM_S2RAM) #include #endif -#include -#include #include #include @@ -42,9 +38,6 @@ #define PIN_XL1 0 #define PIN_XL2 1 -#define RTC1_PRETICK_CC_CHAN 1 -#define RTC1_PRETICK_OVERFLOW_CHAN 2 - #if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) #define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ NRF_DT_GPIOS_TO_PSEL_BY_IDX(node_id, prop, idx), @@ -144,164 +137,11 @@ bool z_arm_on_enter_cpu_idle(void) suppress_message = true; } #endif -#if defined(CONFIG_SOC_NRF53_RTC_PRETICK) && defined(CONFIG_SOC_NRF5340_CPUNET) - if (ok_to_sleep) { - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] |= - IPC_PUBLISH_RECEIVE_EN_Msk; - if (!nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) && - !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) && - !nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { - NRF_WDT->TASKS_STOP = 1; - /* Check if any event did not occur after we checked for - * stopping condition. If yes, we might have stopped WDT - * when it should be running. Restart it. - */ - if (nrf_rtc_event_check(NRF_RTC0, NRF_RTC_CHANNEL_EVENT_ADDR(3)) || - nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)) || - nrf_rtc_event_check(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN))) { - NRF_WDT->TASKS_START = 1; - } - } - } -#endif return ok_to_sleep; } #endif /* CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND */ -#if CONFIG_SOC_NRF53_RTC_PRETICK -#ifdef CONFIG_SOC_NRF5340_CPUAPP -/* RTC pretick - application core part. */ -static int rtc_pretick_cpuapp_init(void) -{ - uint8_t ch; - nrfx_err_t err; - nrf_ipc_event_t ipc_event = - nrf_ipc_receive_event_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET); - nrf_ipc_task_t ipc_task = - nrf_ipc_send_task_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET); - uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); - uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); - - err = nrfx_gppi_channel_alloc(&ch); - if (err != NRFX_SUCCESS) { - return -ENOMEM; - } - - nrf_ipc_receive_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET, - BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET)); - nrf_ipc_send_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET, - BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET)); - - nrfx_gppi_task_endpoint_setup(ch, task_ipc); - nrfx_gppi_event_endpoint_setup(ch, evt_ipc); - nrfx_gppi_channels_enable(BIT(ch)); - - return 0; -} -#else /* CONFIG_SOC_NRF5340_CPUNET */ - -static void rtc_pretick_rtc_isr_hook(void) -{ - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= - ~IPC_PUBLISH_RECEIVE_EN_Msk; -} - -void rtc_pretick_rtc0_isr_hook(void) -{ - rtc_pretick_rtc_isr_hook(); -} - -void rtc_pretick_rtc1_cc0_set_hook(uint32_t val) -{ - nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, val - 1); -} - -void rtc_pretick_rtc1_isr_hook(void) -{ - rtc_pretick_rtc_isr_hook(); - - if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW)) { - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); - } - } - if (nrf_rtc_event_check(NRF_RTC1, NRF_RTC_EVENT_COMPARE_0)) { - if (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK)) { - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - } - } -} - -static int rtc_pretick_cpunet_init(void) -{ - uint8_t ppi_ch; - nrf_ipc_task_t ipc_task = - nrf_ipc_send_task_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET); - nrf_ipc_event_t ipc_event = - nrf_ipc_receive_event_get(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET); - uint32_t task_ipc = nrf_ipc_task_address_get(NRF_IPC, ipc_task); - uint32_t evt_ipc = nrf_ipc_event_address_get(NRF_IPC, ipc_event); - uint32_t task_wdt = nrf_wdt_task_address_get(NRF_WDT, NRF_WDT_TASK_START); - uint32_t evt_mpsl_cc = nrf_rtc_event_address_get(NRF_RTC0, NRF_RTC_EVENT_COMPARE_3); - uint32_t evt_cc = nrf_rtc_event_address_get(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - uint32_t evt_overflow = nrf_rtc_event_address_get(NRF_RTC1, - NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); - - /* Configure Watchdog to allow stopping. */ - nrf_wdt_behaviour_set(NRF_WDT, WDT_CONFIG_STOPEN_Msk | BIT(4)); - *((volatile uint32_t *)0x41203120) = 0x14; - - /* Configure IPC */ - nrf_ipc_receive_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET, - BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET)); - nrf_ipc_send_config_set(NRF_IPC, CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET, - BIT(CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_FROM_NET)); - - /* Allocate PPI channel for RTC Compare event publishers that starts WDT. */ - nrfx_err_t err = nrfx_gppi_channel_alloc(&ppi_ch); - - if (err != NRFX_SUCCESS) { - return -ENOMEM; - } - - /* Setup a PPI connection between RTC "pretick" events and IPC task. */ - if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE)) { - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_mpsl_cc); - } - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_cc); - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_overflow); - nrfx_gppi_task_endpoint_setup(ppi_ch, task_ipc); - nrfx_gppi_event_endpoint_setup(ppi_ch, evt_ipc); - nrfx_gppi_task_endpoint_setup(ppi_ch, task_wdt); - nrfx_gppi_channels_enable(BIT(ppi_ch)); - - nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_CC_CHAN)); - nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_CHANNEL_INT_MASK(RTC1_PRETICK_OVERFLOW_CHAN)); - - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_OVERFLOW_CHAN)); - /* Set event 1 tick before overflow. */ - nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_OVERFLOW_CHAN, 0x00FFFFFF); - - return 0; -} -#endif /* CONFIG_SOC_NRF5340_CPUNET */ - -static int rtc_pretick_init(void) -{ - ARG_UNUSED(unused); -#ifdef CONFIG_SOC_NRF5340_CPUAPP - return rtc_pretick_cpuapp_init(); -#else - return rtc_pretick_cpunet_init(); -#endif -} -#endif /* CONFIG_SOC_NRF53_RTC_PRETICK */ - - static int nordicsemi_nrf53_init(void) { #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF_ENABLE_CACHE) @@ -402,7 +242,3 @@ void arch_busy_wait(uint32_t time_us) } SYS_INIT(nordicsemi_nrf53_init, PRE_KERNEL_1, 0); - -#ifdef CONFIG_SOC_NRF53_RTC_PRETICK -SYS_INIT(rtc_pretick_init, POST_KERNEL, 0); -#endif From ebd2ab7acc23aca2871fe6dfe71ac6f64ecf2778 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:48 +0000 Subject: [PATCH 4362/4498] Revert "[nrf fromtree] logging: Unused arg in log_msg_get_tid" This reverts commit 1b5ab89ed6d031cea80269cb38a512800e46fb59. Signed-off-by: Dominik Ermel --- include/zephyr/logging/log_msg.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index 0279fb0d2cd..4eee566bdc5 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -669,7 +669,6 @@ static inline void *log_msg_get_tid(struct log_msg *msg) #if CONFIG_LOG_THREAD_ID_PREFIX return msg->hdr.tid; #else - ARG_UNUSED(msg); return NULL; #endif } From 8f55883711c4eab59b75f06f0ad555dea1090341 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:48 +0000 Subject: [PATCH 4363/4498] Revert "[nrf fromtree] net: l2: wifi: Fix Wi-Fi mode get command bug" This reverts commit 9df3b459e3b507bccc1cbedc43617fdd56b98c93. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9e521fcf028..f1c512304bf 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1302,7 +1302,7 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, mode->mode |= WIFI_SOFTAP_MODE; break; case 'g': - mode->oper = WIFI_MGMT_GET; + mode->oper = true; break; case 'i': mode->if_index = (uint8_t)atoi(optarg); From 4fa650403eae5df1af00e7903738c3d264227153 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:49 +0000 Subject: [PATCH 4364/4498] Revert "[nrf fromtree] modules: openthread: radio: OT now uses standard TX timestamp" This reverts commit 0b79df6d821b2f77d65f80c5fe411ec15b273768. Signed-off-by: Dominik Ermel --- modules/openthread/CMakeLists.txt | 12 ------------ modules/openthread/Kconfig.features | 13 ------------- modules/openthread/platform/radio.c | 4 +++- tests/subsys/openthread/radio_test.c | 10 ++++++---- west.yml | 2 +- 5 files changed, 10 insertions(+), 31 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 83995aba72f..e32354bcc73 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -160,12 +160,6 @@ else() set(OT_DATASET_UPDATER OFF CACHE BOOL "Enable Dataset updater" FORCE) endif() -if(CONFIG_OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT) - set(OT_DEVICE_PROP_LEADER_WEIGHT ON CACHE BOOL "Enable device props for leader weight" FORCE) -else() - set(OT_DEVICE_PROP_LEADER_WEIGHT OFF CACHE BOOL "Enable device props for leader weight" FORCE) -endif() - if(CONFIG_OPENTHREAD_DHCP6_CLIENT) set(OT_DHCP6_CLIENT ON CACHE BOOL "Enable DHCPv6 Client" FORCE) else() @@ -286,12 +280,6 @@ else() set(OT_LINK_METRICS_INITIATOR OFF CACHE BOOL "Enable Link Metrics initiator for Thread 1.2" FORCE) endif() -if(CONFIG_OPENTHREAD_LINK_METRICS_MANAGER) - set(OT_LINK_METRICS_MANAGER ON CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) -else() - set(OT_LINK_METRICS_MANAGER OFF CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) -endif() - if(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT) set(OT_LINK_METRICS_SUBJECT ON CACHE BOOL "Enable Link Metrics subject for Thread 1.2" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index cd57844370e..55256098487 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -96,16 +96,6 @@ config OPENTHREAD_CSL_RECEIVER help Enable CSL Receiver support for Thread 1.2 -config OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT - bool "Device props for leader weight" - default n if (OPENTHREAD_THREAD_VERSION_1_1 || \ - OPENTHREAD_THREAD_VERSION_1_2 || \ - OPENTHREAD_THREAD_VERSION_1_3) - default y - help - Enable the device properties which are then used to determine and set - the Leader Weight. - config OPENTHREAD_DATASET_UPDATER bool "Dataset updater" @@ -179,9 +169,6 @@ config OPENTHREAD_LEGACY config OPENTHREAD_LINK_METRICS_INITIATOR bool "Link Metrics initiator" -config OPENTHREAD_LINK_METRICS_MANAGER - bool "Link Metrics manager" - config OPENTHREAD_LINK_METRICS_SUBJECT bool "Link Metrics subject" diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index e64e47a5fa9..36e74c6a225 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -58,6 +58,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #define CHANNEL_COUNT OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN + 1 +#define PHY_SHR_DURATION 160 /* duration of SHR in us */ + enum pending_events { PENDING_EVENT_FRAME_TO_SEND, /* There is a tx frame to send */ PENDING_EVENT_FRAME_RECEIVED, /* Radio has received new frame */ @@ -395,7 +397,7 @@ void transmit_message(struct k_work *tx_job) (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) { #if defined(CONFIG_NET_PKT_TXTIME) uint32_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + - sTransmitFrame.mInfo.mTxInfo.mTxDelay; + sTransmitFrame.mInfo.mTxInfo.mTxDelay + PHY_SHR_DURATION; struct net_ptp_time timestamp = ns_to_net_ptp_time(convert_32bit_us_wrapped_to_64bit_ns(tx_at)); net_pkt_set_timestamp(tx_pkt, ×tamp); diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index 87a7013a0d5..fb6c8755039 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -30,6 +30,8 @@ DEFINE_FFF_GLOBALS; #define FRAME_TYPE_MASK 0x07 #define FRAME_TYPE_ACK 0x02 +#define PHY_SHR_DURATION 160 + K_SEM_DEFINE(ot_sem, 0, 1); /** @@ -293,10 +295,10 @@ ZTEST(openthread_radio, test_tx_test) get_time_mock_fake.return_val = (int64_t)UINT32_MAX * NSEC_PER_USEC + 1000; frm->mInfo.mTxInfo.mTxDelayBaseTime = 3U; frm->mInfo.mTxInfo.mTxDelay = 5U; - expected_target_time = - get_time_mock_fake.return_val + - (frm->mInfo.mTxInfo.mTxDelayBaseTime + frm->mInfo.mTxInfo.mTxDelay) * - NSEC_PER_USEC; + expected_target_time = get_time_mock_fake.return_val + + (frm->mInfo.mTxInfo.mTxDelayBaseTime + + frm->mInfo.mTxInfo.mTxDelay + PHY_SHR_DURATION) * + NSEC_PER_USEC; } /* ACKed frame */ diff --git a/west.yml b/west.yml index bed3b47cfe5..b4f874a87c5 100644 --- a/west.yml +++ b/west.yml @@ -303,7 +303,7 @@ manifest: revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 path: modules/lib/open-amp - name: openthread - revision: d62167ee34b091e7025c9ec2820aae71e17a3944 + revision: f7690fe7e9d638341921808cba6a3e695ec0131e path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 6ce6260ed1a6012957736dc2a45d98a304f0320f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:49 +0000 Subject: [PATCH 4365/4498] Revert "[nrf fromtree] Bluetooth: ASCS: Modify the ACL disconnect behavior" This reverts commit 71c7ace4d8da9c5e88b729e3f1dabde5f330f184. Signed-off-by: Dominik Ermel --- subsys/bluetooth/audio/ascs.c | 14 +------------- tests/bluetooth/audio/ascs/src/main.c | 4 ++++ tests/bluetooth/audio/mocks/src/kernel.c | 7 ------- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index d85a90ec77a..9b45754fe90 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -119,8 +119,6 @@ static void ase_free(struct bt_ascs_ase *ase) bt_conn_unref(ase->conn); ase->conn = NULL; - - (void)k_work_cancel(&ase->state_transition_work); } static void ase_status_changed(struct bt_ascs_ase *ase, uint8_t state) @@ -1096,17 +1094,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) } if (ase->ep.status.state != BT_BAP_EP_STATE_IDLE) { - /* We must set the state to idle when the ACL is disconnected immediately, - * as when the ACL disconnect callbacks have been called, the application - * should expect there to be only a single reference to the bt_conn pointer - * from the stack. - * We trigger the work handler directly rather than e.g. calling - * ase_set_state_idle to trigger "regular" state change behavior (such) as - * calling stream->stopped when leaving the streaming state. - */ - ase->ep.reason = reason; - ase->state_pending = BT_BAP_EP_STATE_IDLE; - state_transition_work_handler(&ase->state_transition_work); + ase_release(ase, reason, BT_BAP_ASCS_RSP_NULL); /* At this point, `ase` object have been free'd */ } } diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index 126c82d63bb..b0bc7f88150 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -250,6 +250,7 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_client_terminates mock_bt_iso_disconnected(chan, BT_HCI_ERR_REMOTE_USER_TERM_CONN); /* Expected to notify the upper layers */ + expect_bt_bap_unicast_server_cb_release_called_once(stream); expect_bt_bap_stream_ops_released_called_once(stream); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); @@ -287,6 +288,7 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_server_terminates k_sleep(K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY)); /* Expected to notify the upper layers */ + expect_bt_bap_unicast_server_cb_release_called_once(stream); expect_bt_bap_stream_ops_released_called_once(stream); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); @@ -349,6 +351,7 @@ ZTEST_F(ascs_test_suite, test_release_stream_pair_on_acl_disconnection_client_te const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream }; expect_bt_bap_stream_ops_released_called_twice(streams); + expect_bt_bap_unicast_server_cb_release_called_twice(streams); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); } @@ -410,6 +413,7 @@ ZTEST_F(ascs_test_suite, test_release_stream_pair_on_acl_disconnection_server_te const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream }; expect_bt_bap_stream_ops_released_called_twice(streams); + expect_bt_bap_unicast_server_cb_release_called_twice(streams); bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); } diff --git a/tests/bluetooth/audio/mocks/src/kernel.c b/tests/bluetooth/audio/mocks/src/kernel.c index 03dc2cf582d..ce9dcab5d3a 100644 --- a/tests/bluetooth/audio/mocks/src/kernel.c +++ b/tests/bluetooth/audio/mocks/src/kernel.c @@ -56,13 +56,6 @@ int k_work_cancel_delayable(struct k_work_delayable *dwork) return 0; } -int k_work_cancel(struct k_work *work) -{ - (void)sys_slist_find_and_remove(&work_pending, &work->node); - - return 0; -} - void k_work_init(struct k_work *work, k_work_handler_t handler) { work->handler = handler; From efdcfd8b6b5417aeeaa87101217a6de5c14898af Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:49 +0000 Subject: [PATCH 4366/4498] Revert "[nrf fromtree] tests: bsim: Bluetooth: Add BAP unicast disconnect test" This reverts commit 44ae4b554d43483324be575a189a4640a98437b6. Signed-off-by: Dominik Ermel --- tests/bsim/bluetooth/audio/prj.conf | 5 +- .../audio/src/bap_unicast_client_test.c | 149 +------------ .../audio/src/bap_unicast_server_test.c | 201 +++++------------- .../bap_unicast_audio_acl_disconnect.sh | 27 --- 4 files changed, 54 insertions(+), 328 deletions(-) delete mode 100755 tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index 8f2d6a585a9..2077143452b 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -9,9 +9,8 @@ CONFIG_BT_DEVICE_NAME="bsim_test_audio" # TBS Client may require up to 12 buffers CONFIG_BT_L2CAP_TX_BUF_COUNT=12 CONFIG_BT_ATT_PREPARE_COUNT=5 -CONFIG_BT_MAX_CONN=3 -CONFIG_BT_MAX_PAIRED=3 -CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 +CONFIG_BT_MAX_CONN=5 +CONFIG_BT_MAX_PAIRED=5 CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_SMP=y CONFIG_BT_L2CAP_TX_MTU=100 diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index 3fbd70458b9..72aa1cfcd96 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -306,92 +306,6 @@ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = att_mtu_updated, }; -static bool parse_ascs_ad_data(struct bt_data *data, void *user_data) -{ - const struct bt_le_scan_recv_info *info = user_data; - uint16_t available_source_context; - uint16_t available_sink_context; - struct net_buf_simple net_buf; - struct bt_uuid_16 adv_uuid; - uint8_t announcement_type; - void *uuid; - int err; - - const size_t min_data_len = BT_UUID_SIZE_16 + sizeof(announcement_type) + - sizeof(available_sink_context) + - sizeof(available_source_context); - - if (data->type != BT_DATA_SVC_DATA16) { - return true; - } - - if (data->data_len < min_data_len) { - - return true; - } - - net_buf_simple_init_with_data(&net_buf, (void *)data->data, data->data_len); - - uuid = net_buf_simple_pull_mem(&net_buf, BT_UUID_SIZE_16); - if (!bt_uuid_create(&adv_uuid.uuid, uuid, BT_UUID_SIZE_16)) { - return true; - } - - if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_ASCS)) { - return true; - } - - announcement_type = net_buf_simple_pull_u8(&net_buf); - available_sink_context = net_buf_simple_pull_le16(&net_buf); - available_source_context = net_buf_simple_pull_le16(&net_buf); - - printk("Found ASCS with announcement type 0x%02X, sink ctx 0x%04X, source ctx 0x%04X\n", - announcement_type, available_sink_context, available_source_context); - - printk("Stopping scan\n"); - if (bt_le_scan_stop()) { - FAIL("Could not stop scan"); - return false; - } - - err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, - &default_conn); - if (err) { - FAIL("Could not connect to peer: %d", err); - return false; - } - - /* Stop parsing */ - return false; -} - -static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) -{ - char addr_str[BT_ADDR_LE_STR_LEN]; - - if (default_conn) { - return; - } - - /* We're only interested in connectable events */ - if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0) { - return; - } - /* connect only to devices in close proximity */ - if (info->rssi < -70) { - return; - } - - bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); - printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi); - - bt_data_parse(ad, parse_ascs_ad_data, (void *)info); -} - -static struct bt_le_scan_cb bap_scan_cb = { - .recv = broadcast_scan_recv, -}; - static void init(void) { int err; @@ -406,7 +320,7 @@ static void init(void) g_streams[i].ops = &stream_ops; } - bt_le_scan_cb_register(&bap_scan_cb); + bt_le_scan_cb_register(&common_scan_cb); bt_gatt_cb_register(&gatt_callbacks); err = bt_bap_unicast_client_register_cb(&unicast_client_cbs); @@ -853,71 +767,14 @@ static void test_main(void) PASS("Unicast client passed\n"); } -static void test_main_acl_disconnect(void) -{ - struct bt_bap_unicast_group *unicast_group; - size_t stream_cnt; - - init(); - - scan_and_connect(); - - exchange_mtu(); - - discover_sinks(); - - discover_sources(); - - /* Run the stream setup multiple time to ensure states are properly - * set and reset - */ - - printk("Creating unicast group\n"); - stream_cnt = create_unicast_group(&unicast_group); - - printk("Codec configuring streams\n"); - codec_configure_streams(stream_cnt); - - printk("QoS configuring streams\n"); - qos_configure_streams(unicast_group, stream_cnt); - - printk("Enabling streams\n"); - enable_streams(stream_cnt); - - printk("Metadata update streams\n"); - metadata_update_streams(stream_cnt); - - printk("Starting streams\n"); - start_streams(); - - disconnect_acl(); - - printk("Deleting unicast group\n"); - delete_unicast_group(unicast_group); - unicast_group = NULL; - - /* Reconnect */ - scan_and_connect(); - - disconnect_acl(); - - PASS("Unicast client ACL disconnect passed\n"); -} - static const struct bst_test_instance test_unicast_client[] = { { .test_id = "unicast_client", .test_post_init_f = test_init, .test_tick_f = test_tick, - .test_main_f = test_main, - }, - { - .test_id = "unicast_client_acl_disconnect", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = test_main_acl_disconnect, + .test_main_f = test_main }, - BSTEST_END_MARKER, + BSTEST_END_MARKER }; struct bst_test_list *test_unicast_client_install(struct bst_test_list *tests) diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index 58acdc1726c..c302ec320ab 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -48,20 +48,11 @@ static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASC static const struct bt_audio_codec_qos_pref qos_pref = BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000); -static uint8_t unicast_server_addata[] = { - BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */ - BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */ - BT_BYTES_LIST_LE16(PREF_CONTEXT), - BT_BYTES_LIST_LE16(PREF_CONTEXT), - 0x00, /* Metadata length */ -}; - +/* TODO: Expand with BAP data */ static const struct bt_data unicast_server_ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL)), - BT_DATA(BT_DATA_SVC_DATA16, unicast_server_addata, ARRAY_SIZE(unicast_server_addata)), }; -static struct bt_le_ext_adv *ext_adv; CREATE_FLAG(flag_stream_configured); @@ -239,6 +230,47 @@ static struct bt_bap_stream_ops stream_ops = { .recv = stream_recv }; +static void init(void) +{ + static struct bt_pacs_cap cap = { + .codec_cap = &lc3_codec_cap, + }; + int err; + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth enable failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + bt_bap_unicast_server_register_cb(&unicast_server_cb); + + err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); + if (err != 0) { + FAIL("Failed to register capabilities: %d", err); + return; + } + + err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap); + if (err != 0) { + FAIL("Failed to register capabilities: %d", err); + return; + } + + for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { + bt_bap_stream_cb_register(&streams[i], &stream_ops); + } + + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, unicast_server_ad, ARRAY_SIZE(unicast_server_ad), + NULL, 0); + if (err != 0) { + FAIL("Advertising failed to start (err %d)\n", err); + return; + } +} + static void set_location(void) { int err; @@ -300,160 +332,25 @@ static void set_available_contexts(void) printk("Available contexts successfully set\n"); } -static void init(void) +static void test_main(void) { - static struct bt_pacs_cap cap = { - .codec_cap = &lc3_codec_cap, - }; - int err; - - err = bt_enable(NULL); - if (err != 0) { - FAIL("Bluetooth enable failed (err %d)\n", err); - return; - } - - printk("Bluetooth initialized\n"); - - bt_bap_unicast_server_register_cb(&unicast_server_cb); - - err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); - if (err != 0) { - FAIL("Failed to register capabilities: %d", err); - return; - } - - err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap); - if (err != 0) { - FAIL("Failed to register capabilities: %d", err); - return; - } + init(); set_location(); set_available_contexts(); - for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { - bt_bap_stream_cb_register(&streams[i], &stream_ops); - } - - /* Create a non-connectable non-scannable advertising set */ - err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN_NAME, NULL, &ext_adv); - if (err != 0) { - FAIL("Failed to create advertising set (err %d)\n", err); - return; - } - - err = bt_le_ext_adv_set_data(ext_adv, unicast_server_ad, ARRAY_SIZE(unicast_server_ad), - NULL, 0); - if (err != 0) { - FAIL("Failed to set advertising data (err %d)\n", err); - return; - } - - err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err != 0) { - FAIL("Failed to start advertising set (err %d)\n", err); - return; - } - printk("Advertising started\n"); -} - -static void test_main(void) -{ - init(); - /* TODO: When babblesim supports ISO, wait for audio stream to pass */ WAIT_FOR_FLAG(flag_connected); WAIT_FOR_FLAG(flag_stream_configured); - - WAIT_FOR_UNSET_FLAG(flag_connected); - PASS("Unicast server passed\n"); } -static void restart_adv_cb(struct k_work *work) -{ - int err; - - printk("Restarting ext_adv after disconnect\n"); - - err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err != 0) { - FAIL("Failed to start advertising set (err %d)\n", err); - return; - } -} - -static K_WORK_DEFINE(restart_adv_work, restart_adv_cb); - -static void acl_disconnected(struct bt_conn *conn, uint8_t reason) -{ - if (conn != default_conn) { - return; - } - - k_work_submit(&restart_adv_work); -} - -static void test_main_acl_disconnect(void) -{ - struct bt_le_ext_adv *dummy_ext_adv[CONFIG_BT_MAX_CONN - 1]; - static struct bt_conn_cb conn_callbacks = { - .disconnected = acl_disconnected, - }; - - init(); - - /* Create CONFIG_BT_MAX_CONN - 1 dummy advertising sets, to ensure that we only have 1 free - * connection when attempting to restart advertising, which should ensure that the - * bt_conn object is properly unref'ed by the stack - */ - for (size_t i = 0U; i < ARRAY_SIZE(dummy_ext_adv); i++) { - const struct bt_le_adv_param param = BT_LE_ADV_PARAM_INIT( - (BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CONNECTABLE), - BT_GAP_ADV_SLOW_INT_MAX, BT_GAP_ADV_SLOW_INT_MAX, NULL); - int err; - - err = bt_le_ext_adv_create(¶m, NULL, &dummy_ext_adv[i]); - if (err != 0) { - FAIL("Failed to create advertising set[%zu] (err %d)\n", i, err); - return; - } - - err = bt_le_ext_adv_start(dummy_ext_adv[i], BT_LE_EXT_ADV_START_DEFAULT); - if (err != 0) { - FAIL("Failed to start advertising set[%zu] (err %d)\n", i, err); - return; - } - } - - bt_conn_cb_register(&conn_callbacks); - - WAIT_FOR_FLAG(flag_connected); - WAIT_FOR_FLAG(flag_stream_configured); - - /* The client will reconnect */ - WAIT_FOR_UNSET_FLAG(flag_connected); - WAIT_FOR_FLAG(flag_connected); - PASS("Unicast server ACL disconnect passed\n"); -} - -static const struct bst_test_instance test_unicast_server[] = { - { - .test_id = "unicast_server", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = test_main, - }, - { - .test_id = "unicast_server_acl_disconnect", - .test_post_init_f = test_init, - .test_tick_f = test_tick, - .test_main_f = test_main_acl_disconnect, - }, - BSTEST_END_MARKER, -}; +static const struct bst_test_instance test_unicast_server[] = {{.test_id = "unicast_server", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main}, + BSTEST_END_MARKER}; struct bst_test_list *test_unicast_server_install(struct bst_test_list *tests) { diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh deleted file mode 100755 index 875a2b752dc..00000000000 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -SIMULATION_ID="unicast_audio_acl_disconnect" -VERBOSITY_LEVEL=2 -EXECUTE_TIMEOUT=20 - -source ${ZEPHYR_BASE}/tests/bsim/sh_common.source - -cd ${BSIM_OUT_PATH}/bin - -printf "\n\n======== Unicast Audio ACL Disconnect test =========\n\n" - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client_acl_disconnect -rs=23 - -Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \ - -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server_acl_disconnect -rs=28 - -# Simulation time should be larger than the WAIT_TIME in common.h -Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ - -D=2 -sim_length=60e6 $@ - -wait_for_background_jobs From 66a516ec4a5d3b49ff9f591846af5f6ef6756211 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:49 +0000 Subject: [PATCH 4367/4498] Revert "[nrf fromtree] tests: Bluetooth: Audio: Modify bsim tests to use bt_le_scan_cb_register" This reverts commit 83e1ffa903da471f7d065edfeb59c990b695ae25. Signed-off-by: Dominik Ermel --- .../audio/src/bap_broadcast_assistant_test.c | 3 +-- .../audio/src/bap_unicast_client_test.c | 17 +---------------- tests/bsim/bluetooth/audio/src/common.c | 19 ++++++++----------- tests/bsim/bluetooth/audio/src/common.h | 3 ++- .../bluetooth/audio/src/has_client_test.c | 4 +--- .../bluetooth/audio/src/ias_client_test.c | 4 +--- tests/bsim/bluetooth/audio/src/mcc_test.c | 4 +--- .../audio/src/media_controller_test.c | 4 +--- .../bluetooth/audio/src/micp_mic_ctlr_test.c | 4 +--- .../audio/src/pacs_notify_client_test.c | 6 ++---- tests/bsim/bluetooth/audio/src/tbs_test.c | 3 +-- .../bluetooth/audio/src/vcp_vol_ctlr_test.c | 3 +-- 12 files changed, 21 insertions(+), 53 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c index 9964bd29c0a..381810d68db 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_assistant_test.c @@ -490,10 +490,9 @@ static int common_init(void) bt_gatt_cb_register(&gatt_callbacks); bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cbs); bt_le_per_adv_sync_cb_register(&sync_callbacks); - bt_le_scan_cb_register(&common_scan_cb); printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return err; diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index 72aa1cfcd96..e31c092684a 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -320,7 +320,6 @@ static void init(void) g_streams[i].ops = &stream_ops; } - bt_le_scan_cb_register(&common_scan_cb); bt_gatt_cb_register(&gatt_callbacks); err = bt_bap_unicast_client_register_cb(&unicast_client_cbs); @@ -334,7 +333,7 @@ static void scan_and_connect(void) { int err; - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; @@ -344,19 +343,6 @@ static void scan_and_connect(void) WAIT_FOR_FLAG(flag_connected); } -static void disconnect_acl(void) -{ - int err; - - err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - if (err != 0) { - FAIL("Failed to disconnect (err %d)\n", err); - return; - } - - WAIT_FOR_UNSET_FLAG(flag_connected); -} - static void exchange_mtu(void) { WAIT_FOR_FLAG(flag_mtu_exchanged); @@ -762,7 +748,6 @@ static void test_main(void) unicast_group = NULL; } - disconnect_acl(); PASS("Unicast client passed\n"); } diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 90a8cb98efa..30758e01732 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -16,7 +16,8 @@ const struct bt_data ad[AD_SIZE] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) }; -static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) +void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) { char addr_str[BT_ADDR_LE_STR_LEN]; int err; @@ -26,15 +27,15 @@ static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf } /* We're only interested in connectable events */ - if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0) { + if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) { return; } - bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); - printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi); + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (info->rssi < -70) { + if (rssi < -70) { FAIL("RSSI too low"); return; } @@ -45,17 +46,13 @@ static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf return; } - err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, - &default_conn); + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &default_conn); if (err) { FAIL("Could not connect to peer: %d", err); } } -struct bt_le_scan_cb common_scan_cb = { - .recv = device_found, -}; - static void connected(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 14d6dbbc092..917a024b724 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -65,12 +65,13 @@ #define SYNC_RETRY_COUNT 6 /* similar to retries for connections */ #define PA_SYNC_SKIP 5 -extern struct bt_le_scan_cb common_scan_cb; extern const struct bt_data ad[AD_SIZE]; extern struct bt_conn *default_conn; extern atomic_t flag_connected; extern atomic_t flag_conn_updated; +void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad); void disconnected(struct bt_conn *conn, uint8_t reason); void test_tick(bs_time_t HW_device_time); void test_init(void); diff --git a/tests/bsim/bluetooth/audio/src/has_client_test.c b/tests/bsim/bluetooth/audio/src/has_client_test.c index 6690c6b032e..9d63463e0ce 100644 --- a/tests/bsim/bluetooth/audio/src/has_client_test.c +++ b/tests/bsim/bluetooth/audio/src/has_client_test.c @@ -157,9 +157,7 @@ static void test_main(void) return; } - bt_le_scan_cb_register(&common_scan_cb); - - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err < 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/ias_client_test.c b/tests/bsim/bluetooth/audio/src/ias_client_test.c index 7c24b1a172a..2c5dbd40bd0 100644 --- a/tests/bsim/bluetooth/audio/src/ias_client_test.c +++ b/tests/bsim/bluetooth/audio/src/ias_client_test.c @@ -83,9 +83,7 @@ static void test_main(void) return; } - bt_le_scan_cb_register(&common_scan_cb); - - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err < 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/mcc_test.c b/tests/bsim/bluetooth/audio/src/mcc_test.c index 9e8cd95806b..8a32e33bf16 100644 --- a/tests/bsim/bluetooth/audio/src/mcc_test.c +++ b/tests/bsim/bluetooth/audio/src/mcc_test.c @@ -2396,8 +2396,6 @@ void test_main(void) printk("Bluetooth initialized\n"); - bt_le_scan_cb_register(&common_scan_cb); - /* Initialize MCC ********************************************/ err = do_mcc_init(); if (err != 0) { @@ -2416,7 +2414,7 @@ void test_main(void) printk("\n########### Running iteration #%u\n\n", i); UNSET_FLAG(flag_connected); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Failed to start scanning (err %d\n)", err); } else { diff --git a/tests/bsim/bluetooth/audio/src/media_controller_test.c b/tests/bsim/bluetooth/audio/src/media_controller_test.c index ad91cffb939..9c1df656fd1 100644 --- a/tests/bsim/bluetooth/audio/src/media_controller_test.c +++ b/tests/bsim/bluetooth/audio/src/media_controller_test.c @@ -1585,8 +1585,6 @@ void initialize_bluetooth(void) WAIT_FOR_FLAG(ble_is_initialized); printk("Bluetooth initialized\n"); - - bt_le_scan_cb_register(&common_scan_cb); } void scan_and_connect(void) @@ -1594,7 +1592,7 @@ void scan_and_connect(void) char addr[BT_ADDR_LE_STR_LEN]; int err; - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err) { FAIL("Failed to start scanning (err %d\n)", err); return; diff --git a/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c b/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c index 5cefd31d099..1074c8c2cef 100644 --- a/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c +++ b/tests/bsim/bluetooth/audio/src/micp_mic_ctlr_test.c @@ -357,13 +357,11 @@ static void test_main(void) return; } - bt_le_scan_cb_register(&common_scan_cb); - bt_micp_mic_ctlr_cb_register(&micp_mic_ctlr_cbs); WAIT_FOR_COND(g_bt_init); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c b/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c index 9910f6f2c8c..7cbe5feaa22 100644 --- a/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c +++ b/tests/bsim/bluetooth/audio/src/pacs_notify_client_test.c @@ -490,10 +490,8 @@ static void test_main(void) return; } - bt_le_scan_cb_register(&common_scan_cb); - printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Could not start scanning (err %d)\n", err); return; @@ -538,7 +536,7 @@ static void test_main(void) WAIT_FOR_UNSET_FLAG(flag_connected); printk("Starting scan\n"); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Could not start scanning (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/tbs_test.c b/tests/bsim/bluetooth/audio/src/tbs_test.c index a1bf1e035c0..b20dca26608 100644 --- a/tests/bsim/bluetooth/audio/src/tbs_test.c +++ b/tests/bsim/bluetooth/audio/src/tbs_test.c @@ -331,10 +331,9 @@ static void test_main(void) printk("Audio Client: Bluetooth initialized\n"); bt_conn_cb_register(&conn_callbacks); - bt_le_scan_cb_register(&common_scan_cb); bt_tbs_register_cb(&tbs_cbs); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; diff --git a/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c b/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c index 77feaa4bfb5..52ba2f072ab 100644 --- a/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c +++ b/tests/bsim/bluetooth/audio/src/vcp_vol_ctlr_test.c @@ -1153,10 +1153,9 @@ static void test_main(void) return; } - bt_le_scan_cb_register(&common_scan_cb); test_cb_register(); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err != 0) { FAIL("Scanning failed to start (err %d)\n", err); return; From 5afd86d5626acd370af73d32fdc4e1b909ddb169 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:49 +0000 Subject: [PATCH 4368/4498] Revert "[nrf fromtree] drivers: serial: uart_nrfx_uarte: coexisting async and interrupt API" This reverts commit c606de126612153b2c036b730d66ec622c88aec9. Signed-off-by: Dominik Ermel --- drivers/serial/uart_nrfx_uarte.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 017efa6a2e5..bdafe6c7d4c 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -937,6 +937,11 @@ static int uarte_nrfx_callback_set(const struct device *dev, data->async->user_callback = callback; data->async->user_data = user_data; +#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) && defined(UARTE_INTERRUPT_DRIVEN) + data->int_driven->cb = NULL; + data->int_driven->cb_data = NULL; +#endif + return 0; } @@ -1675,6 +1680,11 @@ static void uarte_nrfx_irq_callback_set(const struct device *dev, data->int_driven->cb = cb; data->int_driven->cb_data = cb_data; + +#if defined(UARTE_ANY_ASYNC) && defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) + data->async->user_callback = NULL; + data->async->user_data = NULL; +#endif } #endif /* UARTE_INTERRUPT_DRIVEN */ From df448f82e8f0d45f57262828669e597971f82695 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:50 +0000 Subject: [PATCH 4369/4498] Revert "[nrf fromtree] mgmt: mcumgr: Split mgmt defines to new file" This reverts commit b0cfad5a121d46969e682eb77ea91b1a2720960d. Signed-off-by: Dominik Ermel --- include/zephyr/mgmt/mcumgr/mgmt/mgmt.h | 119 +++++++++++++- .../zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h | 150 ------------------ 2 files changed, 118 insertions(+), 151 deletions(-) delete mode 100644 include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h index e681ea2b939..eb9ecfcf2a9 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/mgmt.h @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { @@ -24,6 +23,124 @@ extern "C" { * @{ */ +/** + * Used at end of MCUmgr handlers to return an error if the message size limit was reached, + * or OK if it was not + */ +#define MGMT_RETURN_CHECK(ok) ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE + +/** Opcodes; encoded in first byte of header. */ +enum mcumgr_op_t { + /** Read op-code */ + MGMT_OP_READ = 0, + + /** Read response op-code */ + MGMT_OP_READ_RSP, + + /** Write op-code */ + MGMT_OP_WRITE, + + /** Write response op-code */ + MGMT_OP_WRITE_RSP, +}; + +/** + * MCUmgr groups. The first 64 groups are reserved for system level mcumgr + * commands. Per-user commands are then defined after group 64. + */ +enum mcumgr_group_t { + /** OS (operating system) group */ + MGMT_GROUP_ID_OS = 0, + + /** Image management group, used for uploading firmware images */ + MGMT_GROUP_ID_IMAGE, + + /** Statistic management group, used for retieving statistics */ + MGMT_GROUP_ID_STAT, + + /** Settings management (config) group, used for reading/writing settings */ + MGMT_GROUP_ID_SETTINGS, + + /** Log management group (unused) */ + MGMT_GROUP_ID_LOG, + + /** Crash group (unused) */ + MGMT_GROUP_ID_CRASH, + + /** Split image management group (unused) */ + MGMT_GROUP_ID_SPLIT, + + /** Run group (unused) */ + MGMT_GROUP_ID_RUN, + + /** FS (file system) group, used for performing file IO operations */ + MGMT_GROUP_ID_FS, + + /** Shell management group, used for executing shell commands */ + MGMT_GROUP_ID_SHELL, + + /** User groups defined from 64 onwards */ + MGMT_GROUP_ID_PERUSER = 64, + + /** Zephyr-specific groups decrease from PERUSER to avoid collision with upstream and + * user-defined groups. + * Zephyr-specific: Basic group + */ + ZEPHYR_MGMT_GRP_BASIC = (MGMT_GROUP_ID_PERUSER - 1), +}; + +/** + * MCUmgr error codes. + */ +enum mcumgr_err_t { + /** No error (success). */ + MGMT_ERR_EOK = 0, + + /** Unknown error. */ + MGMT_ERR_EUNKNOWN, + + /** Insufficient memory (likely not enough space for CBOR object). */ + MGMT_ERR_ENOMEM, + + /** Error in input value. */ + MGMT_ERR_EINVAL, + + /** Operation timed out. */ + MGMT_ERR_ETIMEOUT, + + /** No such file/entry. */ + MGMT_ERR_ENOENT, + + /** Current state disallows command. */ + MGMT_ERR_EBADSTATE, + + /** Response too large. */ + MGMT_ERR_EMSGSIZE, + + /** Command not supported. */ + MGMT_ERR_ENOTSUP, + + /** Corrupt */ + MGMT_ERR_ECORRUPT, + + /** Command blocked by processing of other command */ + MGMT_ERR_EBUSY, + + /** Access to specific function, command or resource denied */ + MGMT_ERR_EACCESSDENIED, + + /** Requested SMP MCUmgr protocol version is not supported (too old) */ + MGMT_ERR_UNSUPPORTED_TOO_OLD, + + /** Requested SMP MCUmgr protocol version is not supported (too new) */ + MGMT_ERR_UNSUPPORTED_TOO_NEW, + + /** User errors defined from 256 onwards */ + MGMT_ERR_EPERUSER = 256 +}; + +#define MGMT_HDR_SIZE 8 + /** @typedef mgmt_alloc_rsp_fn * @brief Allocates a buffer suitable for holding a response. * diff --git a/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h b/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h deleted file mode 100644 index 2f33b6d22a1..00000000000 --- a/include/zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022-2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef H_MGMT_MGMT_DEFINES_ -#define H_MGMT_MGMT_DEFINES_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief MCUmgr mgmt API - * @defgroup mcumgr_mgmt_api MCUmgr mgmt API - * @ingroup mcumgr - * @{ - */ - -/** - * Used at end of MCUmgr handlers to return an error if the message size limit was reached, - * or OK if it was not - */ -#define MGMT_RETURN_CHECK(ok) ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE - -/** Opcodes; encoded in first byte of header. */ -enum mcumgr_op_t { - /** Read op-code */ - MGMT_OP_READ = 0, - - /** Read response op-code */ - MGMT_OP_READ_RSP, - - /** Write op-code */ - MGMT_OP_WRITE, - - /** Write response op-code */ - MGMT_OP_WRITE_RSP, -}; - -/** - * MCUmgr groups. The first 64 groups are reserved for system level mcumgr - * commands. Per-user commands are then defined after group 64. - */ -enum mcumgr_group_t { - /** OS (operating system) group */ - MGMT_GROUP_ID_OS = 0, - - /** Image management group, used for uploading firmware images */ - MGMT_GROUP_ID_IMAGE, - - /** Statistic management group, used for retieving statistics */ - MGMT_GROUP_ID_STAT, - - /** Settings management (config) group, used for reading/writing settings */ - MGMT_GROUP_ID_SETTINGS, - - /** Log management group (unused) */ - MGMT_GROUP_ID_LOG, - - /** Crash group (unused) */ - MGMT_GROUP_ID_CRASH, - - /** Split image management group (unused) */ - MGMT_GROUP_ID_SPLIT, - - /** Run group (unused) */ - MGMT_GROUP_ID_RUN, - - /** FS (file system) group, used for performing file IO operations */ - MGMT_GROUP_ID_FS, - - /** Shell management group, used for executing shell commands */ - MGMT_GROUP_ID_SHELL, - - /** User groups defined from 64 onwards */ - MGMT_GROUP_ID_PERUSER = 64, - - /** Zephyr-specific groups decrease from PERUSER to avoid collision with upstream and - * user-defined groups. - * Zephyr-specific: Basic group - */ - ZEPHYR_MGMT_GRP_BASIC = (MGMT_GROUP_ID_PERUSER - 1), -}; - -/** - * MCUmgr error codes. - */ -enum mcumgr_err_t { - /** No error (success). */ - MGMT_ERR_EOK = 0, - - /** Unknown error. */ - MGMT_ERR_EUNKNOWN, - - /** Insufficient memory (likely not enough space for CBOR object). */ - MGMT_ERR_ENOMEM, - - /** Error in input value. */ - MGMT_ERR_EINVAL, - - /** Operation timed out. */ - MGMT_ERR_ETIMEOUT, - - /** No such file/entry. */ - MGMT_ERR_ENOENT, - - /** Current state disallows command. */ - MGMT_ERR_EBADSTATE, - - /** Response too large. */ - MGMT_ERR_EMSGSIZE, - - /** Command not supported. */ - MGMT_ERR_ENOTSUP, - - /** Corrupt */ - MGMT_ERR_ECORRUPT, - - /** Command blocked by processing of other command */ - MGMT_ERR_EBUSY, - - /** Access to specific function, command or resource denied */ - MGMT_ERR_EACCESSDENIED, - - /** Requested SMP MCUmgr protocol version is not supported (too old) */ - MGMT_ERR_UNSUPPORTED_TOO_OLD, - - /** Requested SMP MCUmgr protocol version is not supported (too new) */ - MGMT_ERR_UNSUPPORTED_TOO_NEW, - - /** User errors defined from 256 onwards */ - MGMT_ERR_EPERUSER = 256 -}; - -#define MGMT_HDR_SIZE 8 - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* MGMT_MGMT_DEFINES_H_ */ From caa1e7aa5f361685437dfb24388f29282e35353f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:50 +0000 Subject: [PATCH 4370/4498] Revert "[nrf fromtree] net: Fix usage of strncpy in net_if_get_name and net_if_set_name" This reverts commit 9aa9bb98607f6f7232adedb5e7e15f7663f58498. Signed-off-by: Dominik Ermel --- subsys/net/ip/net_if.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 828e48ecf78..e6e3512e4b2 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4747,8 +4747,7 @@ int net_if_get_name(struct net_if *iface, char *buf, int len) return -ERANGE; } - /* Copy string and null terminator */ - memcpy(buf, net_if_get_config(iface)->name, name_len + 1); + strncpy(buf, net_if_get_config(iface)->name, name_len); return name_len; #else @@ -4770,8 +4769,7 @@ int net_if_set_name(struct net_if *iface, const char *buf) return -ENAMETOOLONG; } - /* Copy string and null terminator */ - memcpy(net_if_get_config(iface)->name, buf, name_len + 1); + strncpy(net_if_get_config(iface)->name, buf, name_len); return 0; #else From b50d63fb52c8a888fb3ed0481c61da4a72362df6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:50 +0000 Subject: [PATCH 4371/4498] Revert "[nrf fromtree] drivers: gpio_nrfx: Allow to disable interrupt support" This reverts commit 1cba00a409f64a96f3a0c75bd3cb15c146829077. Signed-off-by: Dominik Ermel --- drivers/gpio/Kconfig.nrfx | 11 +--------- drivers/gpio/gpio_nrfx.c | 42 ++++++++++++++------------------------- 2 files changed, 16 insertions(+), 37 deletions(-) diff --git a/drivers/gpio/Kconfig.nrfx b/drivers/gpio/Kconfig.nrfx index 356c43cb5fa..6757b6b12e9 100644 --- a/drivers/gpio/Kconfig.nrfx +++ b/drivers/gpio/Kconfig.nrfx @@ -1,19 +1,10 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -menuconfig GPIO_NRFX +config GPIO_NRFX bool "nRF GPIO driver" default y depends on DT_HAS_NORDIC_NRF_GPIO_ENABLED select NRFX_GPIOTE help Enable GPIO driver for nRF line of MCUs. - -config GPIO_NRFX_INTERRUPT - bool "Interrupt support" - depends on GPIO_NRFX - default y - help - The option can be used to disable the GPIO interrupt support to - significantly reduce memory footprint in case of application that does - not need GPIO interrupts. diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 0aa282dda37..1683b8b2cea 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -85,19 +85,17 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { - nrfx_err_t err = NRFX_SUCCESS; + nrfx_err_t err; uint8_t ch; - bool free_ch = false; + bool free_ch; const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); /* Get the GPIOTE channel associated with this pin, if any. It needs * to be freed when the pin is reconfigured or disconnected. */ - if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - err = nrfx_gpiote_channel_get(abs_pin, &ch); - free_ch = (err == NRFX_SUCCESS); - } + err = nrfx_gpiote_channel_get(abs_pin, &ch); + free_ch = (err == NRFX_SUCCESS); if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { /* Ignore the error code. The pin may not have been used. */ @@ -111,21 +109,19 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, return 0; } - if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - nrfx_gpiote_trigger_config_t trigger_config = { - .trigger = NRFX_GPIOTE_TRIGGER_NONE - }; + nrfx_gpiote_trigger_config_t trigger_config = { + .trigger = NRFX_GPIOTE_TRIGGER_NONE + }; - /* Remove previously configured trigger when pin is reconfigured. */ - err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); - if (err != NRFX_SUCCESS) { - return -EINVAL; - } + /* Remove previously configured trigger when pin is reconfigured. */ + err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); + if (err != NRFX_SUCCESS) { + return -EINVAL; + } - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); - } + if (free_ch) { + err = nrfx_gpiote_channel_free(ch); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); } if (flags & GPIO_OUTPUT) { @@ -223,7 +219,6 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port, return 0; } -#ifdef CONFIG_GPIO_NRFX_INTERRUPT static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode, enum gpio_int_trig trig) { @@ -290,7 +285,6 @@ static int gpio_nrfx_manage_callback(const struct device *port, return gpio_manage_callback(&get_port_data(port)->callbacks, callback, set); } -#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ #ifdef CONFIG_GPIO_GET_DIRECTION static int gpio_nrfx_port_get_direction(const struct device *port, @@ -328,7 +322,6 @@ static int gpio_nrfx_port_get_direction(const struct device *port, } #endif /* CONFIG_GPIO_GET_DIRECTION */ -#ifdef CONFIG_GPIO_NRFX_INTERRUPT /* Get port device from port id. */ static const struct device *get_dev(uint32_t port_id) { @@ -365,7 +358,6 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, gpio_fire_callbacks(list, port, BIT(pin)); } -#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ #define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote) @@ -382,12 +374,10 @@ static int gpio_nrfx_init(const struct device *port) return -EIO; } -#ifdef CONFIG_GPIO_NRFX_INTERRUPT nrfx_gpiote_global_callback_set(nrfx_gpio_handler, NULL); IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), nrfx_isr, nrfx_gpiote_irq_handler, 0); -#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ return 0; } @@ -399,10 +389,8 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { .port_set_bits_raw = gpio_nrfx_port_set_bits_raw, .port_clear_bits_raw = gpio_nrfx_port_clear_bits_raw, .port_toggle_bits = gpio_nrfx_port_toggle_bits, -#ifdef CONFIG_GPIO_NRFX_INTERRUPT .pin_interrupt_configure = gpio_nrfx_pin_interrupt_configure, .manage_callback = gpio_nrfx_manage_callback, -#endif #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_nrfx_port_get_direction, #endif From e04177f3998ed4cac4294f18d20e1b9233c65eac Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:51 +0000 Subject: [PATCH 4372/4498] Revert "[nrf fromtree] drivers: gpio: fix optional operations usage" This reverts commit cf88137e48d93f97b16354ce0a41e1323478bbb7. Signed-off-by: Dominik Ermel --- drivers/gpio/gpio_ads114s0x.c | 12 ++++++++++++ drivers/gpio/gpio_axp192.c | 12 ++++++++++++ drivers/gpio/gpio_bd8lb600fs.c | 7 +++++++ drivers/gpio/gpio_creg_gpio.c | 9 +++++++++ drivers/gpio/gpio_cy8c95xx.c | 9 +++++++++ drivers/gpio/gpio_fxl6408.c | 10 ++++++++++ drivers/gpio/gpio_lmp90xxx.c | 14 ++++++++++++++ drivers/gpio/gpio_mcp23s17.c | 9 +++++++++ drivers/gpio/gpio_mmio32.c | 13 +++++++++++++ drivers/gpio/gpio_neorv32.c | 14 ++++++++++++++ drivers/gpio/gpio_npm1300.c | 12 ++++++++++++ drivers/gpio/gpio_npm6001.c | 14 ++++++++++++++ drivers/gpio/gpio_nxp_s32.c | 29 ++++++++++++++++++++++++++--- drivers/gpio/gpio_pca95xx.c | 14 ++++++++++++-- drivers/gpio/gpio_sc18im704.c | 12 ++++++++++++ drivers/gpio/gpio_sn74hc595.c | 11 +++++++++++ drivers/gpio/gpio_stmpe1600.c | 9 +++++++++ drivers/gpio/gpio_sx1509b.c | 11 ++++++++--- drivers/gpio/gpio_test.c | 23 +++++++++++++++++++++++ drivers/gpio/gpio_xlnx_axi.c | 4 +--- drivers/gpio/gpio_xmc4xxx.c | 15 ++++++++++----- 21 files changed, 247 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio_ads114s0x.c b/drivers/gpio/gpio_ads114s0x.c index 13f4f7f1266..79383d38154 100644 --- a/drivers/gpio/gpio_ads114s0x.c +++ b/drivers/gpio/gpio_ads114s0x.c @@ -106,6 +106,17 @@ static int gpio_ads114s0x_port_toggle_bits(const struct device *dev, gpio_port_p return ads114s0x_gpio_port_toggle_bits(config->parent, pins); } +static int gpio_ads114s0x_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static int gpio_ads114s0x_init(const struct device *dev) { const struct gpio_ads114s0x_config *config = dev->config; @@ -124,6 +135,7 @@ static const struct gpio_driver_api gpio_ads114s0x_api = { .port_set_bits_raw = gpio_ads114s0x_port_set_bits_raw, .port_clear_bits_raw = gpio_ads114s0x_port_clear_bits_raw, .port_toggle_bits = gpio_ads114s0x_port_toggle_bits, + .pin_interrupt_configure = gpio_ads114s0x_pin_interrupt_configure, .port_get_raw = gpio_ads114s0x_port_get_raw, }; diff --git a/drivers/gpio/gpio_axp192.c b/drivers/gpio/gpio_axp192.c index 95625d99dfe..ee75fe9b276 100644 --- a/drivers/gpio/gpio_axp192.c +++ b/drivers/gpio/gpio_axp192.c @@ -159,6 +159,17 @@ static int gpio_axp192_port_toggle_bits(const struct device *dev, gpio_port_pins return ret; } +static int gpio_axp192_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + #ifdef CONFIG_GPIO_GET_CONFIG static int gpio_axp192_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *out_flags) { @@ -265,6 +276,7 @@ static const struct gpio_driver_api gpio_axp192_api = { .port_set_bits_raw = gpio_axp192_port_set_bits_raw, .port_clear_bits_raw = gpio_axp192_port_clear_bits_raw, .port_toggle_bits = gpio_axp192_port_toggle_bits, + .pin_interrupt_configure = gpio_axp192_pin_interrupt_configure, .manage_callback = gpio_axp192_manage_callback, #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_axp192_port_get_direction, diff --git a/drivers/gpio/gpio_bd8lb600fs.c b/drivers/gpio/gpio_bd8lb600fs.c index 30ae851d90b..555a63b91fd 100644 --- a/drivers/gpio/gpio_bd8lb600fs.c +++ b/drivers/gpio/gpio_bd8lb600fs.c @@ -193,6 +193,12 @@ static int bd8lb600fs_port_toggle_bits(const struct device *dev, uint32_t mask) return result; } +static int bd8lb600fs_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + static const struct gpio_driver_api api_table = { .pin_configure = bd8lb600fs_pin_configure, .port_get_raw = bd8lb600fs_port_get_raw, @@ -200,6 +206,7 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = bd8lb600fs_port_set_bits_raw, .port_clear_bits_raw = bd8lb600fs_port_clear_bits_raw, .port_toggle_bits = bd8lb600fs_port_toggle_bits, + .pin_interrupt_configure = bd8lb600fs_pin_interrupt_configure, }; static int bd8lb600fs_init(const struct device *dev) diff --git a/drivers/gpio/gpio_creg_gpio.c b/drivers/gpio/gpio_creg_gpio.c index 1b9f4d63a50..05b09184df9 100644 --- a/drivers/gpio/gpio_creg_gpio.c +++ b/drivers/gpio/gpio_creg_gpio.c @@ -104,6 +104,14 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } +static int pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + static int pin_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) @@ -155,6 +163,7 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, + .pin_interrupt_configure = pin_interrupt_configure, }; static const struct creg_gpio_config creg_gpio_cfg = { diff --git a/drivers/gpio/gpio_cy8c95xx.c b/drivers/gpio/gpio_cy8c95xx.c index 155bfb4988a..b540a7b96bf 100644 --- a/drivers/gpio/gpio_cy8c95xx.c +++ b/drivers/gpio/gpio_cy8c95xx.c @@ -214,6 +214,14 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } +static int pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + /** * @brief Initialization function of CY8C95XX * @@ -269,6 +277,7 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, + .pin_interrupt_configure = pin_interrupt_configure, }; static struct k_sem cy8c95xx_lock = Z_SEM_INITIALIZER(cy8c95xx_lock, 1, 1); diff --git a/drivers/gpio/gpio_fxl6408.c b/drivers/gpio/gpio_fxl6408.c index 7352390e371..164a4396c13 100644 --- a/drivers/gpio/gpio_fxl6408.c +++ b/drivers/gpio/gpio_fxl6408.c @@ -377,6 +377,15 @@ static int gpio_fxl6408_port_toggle_bits(const struct device *dev, return ret; } +static int gpio_fxl6408_pin_interrupt_configure(const struct device *port, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + LOG_DBG("Pin interrupts not supported."); + return -ENOTSUP; +} + int gpio_fxl6408_init(const struct device *dev) { struct gpio_fxl6408_drv_data *const drv_data = @@ -400,6 +409,7 @@ static const struct gpio_driver_api gpio_fxl_driver = { .port_set_bits_raw = gpio_fxl6408_port_set_bits_raw, .port_clear_bits_raw = gpio_fxl6408_port_clear_bits_raw, .port_toggle_bits = gpio_fxl6408_port_toggle_bits, + .pin_interrupt_configure = gpio_fxl6408_pin_interrupt_configure }; #define GPIO_FXL6408_DEVICE_INSTANCE(inst) \ diff --git a/drivers/gpio/gpio_lmp90xxx.c b/drivers/gpio/gpio_lmp90xxx.c index 2514ef35211..1bd99d88cf2 100644 --- a/drivers/gpio/gpio_lmp90xxx.c +++ b/drivers/gpio/gpio_lmp90xxx.c @@ -122,6 +122,19 @@ static int gpio_lmp90xxx_port_toggle_bits(const struct device *dev, return lmp90xxx_gpio_port_toggle_bits(config->parent, pins); } +static int gpio_lmp90xxx_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static int gpio_lmp90xxx_init(const struct device *dev) { const struct gpio_lmp90xxx_config *config = dev->config; @@ -141,6 +154,7 @@ static const struct gpio_driver_api gpio_lmp90xxx_api = { .port_set_bits_raw = gpio_lmp90xxx_port_set_bits_raw, .port_clear_bits_raw = gpio_lmp90xxx_port_clear_bits_raw, .port_toggle_bits = gpio_lmp90xxx_port_toggle_bits, + .pin_interrupt_configure = gpio_lmp90xxx_pin_interrupt_configure, .port_get_raw = gpio_lmp90xxx_port_get_raw, }; diff --git a/drivers/gpio/gpio_mcp23s17.c b/drivers/gpio/gpio_mcp23s17.c index 4849c3a02fe..96a266fdf6d 100644 --- a/drivers/gpio/gpio_mcp23s17.c +++ b/drivers/gpio/gpio_mcp23s17.c @@ -340,6 +340,14 @@ static int mcp23s17_port_toggle_bits(const struct device *dev, uint32_t mask) return ret; } +static int mcp23s17_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + static const struct gpio_driver_api api_table = { .pin_configure = mcp23s17_config, .port_get_raw = mcp23s17_port_get_raw, @@ -347,6 +355,7 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = mcp23s17_port_set_bits_raw, .port_clear_bits_raw = mcp23s17_port_clear_bits_raw, .port_toggle_bits = mcp23s17_port_toggle_bits, + .pin_interrupt_configure = mcp23s17_pin_interrupt_configure, }; static int mcp23s17_init(const struct device *dev) diff --git a/drivers/gpio/gpio_mmio32.c b/drivers/gpio/gpio_mmio32.c index 0fe5e9fedd8..e9e58373b5b 100644 --- a/drivers/gpio/gpio_mmio32.c +++ b/drivers/gpio/gpio_mmio32.c @@ -147,6 +147,18 @@ static int gpio_mmio32_port_toggle_bits(const struct device *dev, return 0; } +static int gpio_mmio32_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + if (mode != GPIO_INT_MODE_DISABLED) { + return -ENOTSUP; + } + + return 0; +} + const struct gpio_driver_api gpio_mmio32_api = { .pin_configure = gpio_mmio32_config, .port_get_raw = gpio_mmio32_port_get_raw, @@ -154,6 +166,7 @@ const struct gpio_driver_api gpio_mmio32_api = { .port_set_bits_raw = gpio_mmio32_port_set_bits_raw, .port_clear_bits_raw = gpio_mmio32_port_clear_bits_raw, .port_toggle_bits = gpio_mmio32_port_toggle_bits, + .pin_interrupt_configure = gpio_mmio32_pin_interrupt_configure, }; int gpio_mmio32_init(const struct device *dev) diff --git a/drivers/gpio/gpio_neorv32.c b/drivers/gpio/gpio_neorv32.c index b14c51c1471..b448962bde7 100644 --- a/drivers/gpio/gpio_neorv32.c +++ b/drivers/gpio/gpio_neorv32.c @@ -151,6 +151,19 @@ static int neorv32_gpio_port_toggle_bits(const struct device *dev, return 0; } +static int neorv32_gpio_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static int neorv32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set) @@ -202,6 +215,7 @@ static const struct gpio_driver_api neorv32_gpio_driver_api = { .port_set_bits_raw = neorv32_gpio_port_set_bits_raw, .port_clear_bits_raw = neorv32_gpio_port_clear_bits_raw, .port_toggle_bits = neorv32_gpio_port_toggle_bits, + .pin_interrupt_configure = neorv32_gpio_pin_interrupt_configure, .manage_callback = neorv32_gpio_manage_callback, .get_pending_int = neorv32_gpio_get_pending_int, }; diff --git a/drivers/gpio/gpio_npm1300.c b/drivers/gpio/gpio_npm1300.c index 65c3cdd6fda..37e7f99c936 100644 --- a/drivers/gpio/gpio_npm1300.c +++ b/drivers/gpio/gpio_npm1300.c @@ -185,6 +185,17 @@ static int gpio_npm1300_port_toggle_bits(const struct device *dev, gpio_port_pin return gpio_npm1300_port_set_masked_raw(dev, pins, ~value); } +static int gpio_npm1300_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static const struct gpio_driver_api gpio_npm1300_api = { .pin_configure = gpio_npm1300_configure, .port_get_raw = gpio_npm1300_port_get_raw, @@ -192,6 +203,7 @@ static const struct gpio_driver_api gpio_npm1300_api = { .port_set_bits_raw = gpio_npm1300_port_set_bits_raw, .port_clear_bits_raw = gpio_npm1300_port_clear_bits_raw, .port_toggle_bits = gpio_npm1300_port_toggle_bits, + .pin_interrupt_configure = gpio_npm1300_pin_interrupt_configure, }; static int gpio_npm1300_init(const struct device *dev) diff --git a/drivers/gpio/gpio_npm6001.c b/drivers/gpio/gpio_npm6001.c index f722c4275d6..98bd4db49e0 100644 --- a/drivers/gpio/gpio_npm6001.c +++ b/drivers/gpio/gpio_npm6001.c @@ -192,6 +192,19 @@ static int gpio_npm6001_port_toggle_bits(const struct device *dev, ~val & NPM6001_PIN_MSK); } +static int gpio_npm6001_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static const struct gpio_driver_api gpio_npm6001_api = { .pin_configure = gpio_npm6001_configure, .port_get_raw = gpio_npm6001_port_get_raw, @@ -199,6 +212,7 @@ static const struct gpio_driver_api gpio_npm6001_api = { .port_set_bits_raw = gpio_npm6001_port_set_bits_raw, .port_clear_bits_raw = gpio_npm6001_port_clear_bits_raw, .port_toggle_bits = gpio_npm6001_port_toggle_bits, + .pin_interrupt_configure = gpio_npm6001_pin_interrupt_configure, }; static int gpio_npm6001_init(const struct device *dev) diff --git a/drivers/gpio/gpio_nxp_s32.c b/drivers/gpio/gpio_nxp_s32.c index de5dbd39dd7..3bdf9f4599d 100644 --- a/drivers/gpio/gpio_nxp_s32.c +++ b/drivers/gpio/gpio_nxp_s32.c @@ -205,12 +205,14 @@ static void nxp_s32_gpio_isr(uint8_t pin, void *arg) gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); } +#endif /* CONFIG_NXP_S32_EIRQ */ static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { +#ifdef CONFIG_NXP_S32_EIRQ const struct gpio_nxp_s32_config *config = dev->config; const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; @@ -253,18 +255,35 @@ static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev, } return 0; +#else + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +#endif } static int nxp_s32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set) { +#ifdef CONFIG_NXP_S32_EIRQ struct gpio_nxp_s32_data *data = dev->data; return gpio_manage_callback(&data->callbacks, cb, set); +#else + ARG_UNUSED(dev); + ARG_UNUSED(cb); + ARG_UNUSED(set); + + return -ENOTSUP; +#endif } static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) { +#ifdef CONFIG_NXP_S32_EIRQ const struct gpio_nxp_s32_config *config = dev->config; const struct eirq_nxp_s32_info *eirq_info = config->eirq_info; @@ -281,8 +300,14 @@ static uint32_t nxp_s32_gpio_get_pending_int(const struct device *dev) * that GPIO port belongs to */ return eirq_nxp_s32_get_pending(eirq_info->eirq_dev); + +#else + ARG_UNUSED(dev); + + return -ENOTSUP; +#endif } -#endif /* CONFIG_NXP_S32_EIRQ */ + #ifdef CONFIG_GPIO_GET_CONFIG static int nxp_s32_gpio_pin_get_config(const struct device *dev, @@ -375,11 +400,9 @@ static const struct gpio_driver_api gpio_nxp_s32_driver_api = { .port_set_bits_raw = nxp_s32_gpio_port_set_bits_raw, .port_clear_bits_raw = nxp_s32_gpio_port_clear_bits_raw, .port_toggle_bits = nxp_s32_gpio_port_toggle_bits, -#ifdef CONFIG_NXP_S32_EIRQ .pin_interrupt_configure = nxp_s32_gpio_pin_interrupt_configure, .manage_callback = nxp_s32_gpio_manage_callback, .get_pending_int = nxp_s32_gpio_get_pending_int, -#endif #ifdef CONFIG_GPIO_GET_CONFIG .pin_get_config = nxp_s32_gpio_pin_get_config, #endif diff --git a/drivers/gpio/gpio_pca95xx.c b/drivers/gpio/gpio_pca95xx.c index f8489128332..66b21fd5b88 100644 --- a/drivers/gpio/gpio_pca95xx.c +++ b/drivers/gpio/gpio_pca95xx.c @@ -644,6 +644,7 @@ static void gpio_pca95xx_interrupt_callback(const struct device *dev, /* Cannot read PCA95xx registers from ISR context, queue worker */ k_work_submit(&drv_data->interrupt_worker); } +#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, @@ -651,6 +652,13 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, enum gpio_int_trig trig) { int ret = 0; + + if (!IS_ENABLED(CONFIG_GPIO_PCA95XX_INTERRUPT) + && (mode != GPIO_INT_MODE_DISABLED)) { + return -ENOTSUP; + } + +#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT const struct gpio_pca95xx_config * const config = dev->config; struct gpio_pca95xx_drv_data * const drv_data = (struct gpio_pca95xx_drv_data * const)dev->data; @@ -734,9 +742,11 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev, err: k_sem_give(&drv_data->lock); +#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ return ret; } +#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT static int gpio_pca95xx_manage_callback(const struct device *dev, struct gpio_callback *callback, bool set) @@ -756,7 +766,7 @@ static int gpio_pca95xx_manage_callback(const struct device *dev, k_sem_give(&drv_data->lock); return 0; } -#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */ +#endif static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = { .pin_configure = gpio_pca95xx_config, @@ -765,8 +775,8 @@ static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = { .port_set_bits_raw = gpio_pca95xx_port_set_bits_raw, .port_clear_bits_raw = gpio_pca95xx_port_clear_bits_raw, .port_toggle_bits = gpio_pca95xx_port_toggle_bits, -#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT .pin_interrupt_configure = gpio_pca95xx_pin_interrupt_configure, +#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT .manage_callback = gpio_pca95xx_manage_callback, #endif }; diff --git a/drivers/gpio/gpio_sc18im704.c b/drivers/gpio/gpio_sc18im704.c index c45e9d51a60..96fd56cadb6 100644 --- a/drivers/gpio/gpio_sc18im704.c +++ b/drivers/gpio/gpio_sc18im704.c @@ -239,6 +239,17 @@ static int gpio_sc18im_port_toggle_bits(const struct device *port, gpio_port_pin return gpio_sc18im_port_set_raw(port, 0, 0, (uint8_t)pins); } +static int gpio_sc18im_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(port); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; +} + static int gpio_sc18im_init(const struct device *dev) { const struct gpio_sc18im_config *cfg = dev->config; @@ -261,6 +272,7 @@ static const struct gpio_driver_api gpio_sc18im_driver_api = { .port_set_bits_raw = gpio_sc18im_port_set_bits_raw, .port_clear_bits_raw = gpio_sc18im_port_clear_bits_raw, .port_toggle_bits = gpio_sc18im_port_toggle_bits, + .pin_interrupt_configure = gpio_sc18im_pin_interrupt_configure, }; #define CHECK_COMPAT(node) \ diff --git a/drivers/gpio/gpio_sn74hc595.c b/drivers/gpio/gpio_sn74hc595.c index 16eb35bb690..38f5de94d38 100644 --- a/drivers/gpio/gpio_sn74hc595.c +++ b/drivers/gpio/gpio_sn74hc595.c @@ -134,6 +134,16 @@ static int gpio_sn74hc595_port_toggle_bits(const struct device *dev, uint32_t ma return ret; } +static int gpio_sn74hc595_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + return -ENOTSUP; +} + static const struct gpio_driver_api gpio_sn74hc595_drv_api_funcs = { .pin_configure = gpio_sn74hc595_config, .port_get_raw = gpio_sn74hc595_port_get_raw, @@ -141,6 +151,7 @@ static const struct gpio_driver_api gpio_sn74hc595_drv_api_funcs = { .port_set_bits_raw = gpio_sn74hc595_port_set_bits_raw, .port_clear_bits_raw = gpio_sn74hc595_port_clear_bits_raw, .port_toggle_bits = gpio_sn74hc595_port_toggle_bits, + .pin_interrupt_configure = gpio_sn74hc595_pin_interrupt_configure, }; /** diff --git a/drivers/gpio/gpio_stmpe1600.c b/drivers/gpio/gpio_stmpe1600.c index 2331fdf9fed..518b41c7c57 100644 --- a/drivers/gpio/gpio_stmpe1600.c +++ b/drivers/gpio/gpio_stmpe1600.c @@ -249,6 +249,14 @@ static int stmpe1600_port_toggle_bits(const struct device *dev, uint32_t mask) return ret; } +static int stmpe1600_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + static int stmpe1600_init(const struct device *dev) { const struct stmpe1600_config *const config = dev->config; @@ -292,6 +300,7 @@ static const struct gpio_driver_api stmpe1600_drv_api = { .port_set_bits_raw = stmpe1600_port_set_bits_raw, .port_clear_bits_raw = stmpe1600_port_clear_bits_raw, .port_toggle_bits = stmpe1600_port_toggle_bits, + .pin_interrupt_configure = stmpe1600_pin_interrupt_configure, }; #define STMPE1600_INIT(inst) \ diff --git a/drivers/gpio/gpio_sx1509b.c b/drivers/gpio/gpio_sx1509b.c index b8ecdf4d772..c62f803e307 100644 --- a/drivers/gpio/gpio_sx1509b.c +++ b/drivers/gpio/gpio_sx1509b.c @@ -468,7 +468,6 @@ static int port_toggle_bits(const struct device *dev, return port_write(dev, 0, 0, pins); } -#ifdef CONFIG_GPIO_SX1509B_INTERRUPT static int pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, @@ -476,6 +475,12 @@ static int pin_interrupt_configure(const struct device *dev, { int rc = 0; + if (!IS_ENABLED(CONFIG_GPIO_SX1509B_INTERRUPT) + && (mode != GPIO_INT_MODE_DISABLED)) { + return -ENOTSUP; + } + +#ifdef CONFIG_GPIO_SX1509B_INTERRUPT /* Device does not support level-triggered interrupts. */ if (mode == GPIO_INT_MODE_LEVEL) { return -ENOTSUP; @@ -526,10 +531,10 @@ static int pin_interrupt_configure(const struct device *dev, rc = i2c_write_dt(&cfg->bus, &irq_buf.reg, sizeof(irq_buf)); k_sem_give(&drv_data->lock); +#endif /* CONFIG_GPIO_SX1509B_INTERRUPT */ return rc; } -#endif /* CONFIG_GPIO_SX1509B_INTERRUPT */ /** * @brief Initialization function of SX1509B @@ -642,8 +647,8 @@ static const struct gpio_driver_api api_table = { .port_set_bits_raw = port_set_bits, .port_clear_bits_raw = port_clear_bits, .port_toggle_bits = port_toggle_bits, -#ifdef CONFIG_GPIO_SX1509B_INTERRUPT .pin_interrupt_configure = pin_interrupt_configure, +#ifdef CONFIG_GPIO_SX1509B_INTERRUPT .manage_callback = gpio_sx1509b_manage_callback, #endif }; diff --git a/drivers/gpio/gpio_test.c b/drivers/gpio/gpio_test.c index 3befab37fc2..192028acac0 100644 --- a/drivers/gpio/gpio_test.c +++ b/drivers/gpio/gpio_test.c @@ -63,6 +63,26 @@ static int vnd_gpio_port_toggle_bits(const struct device *port, return -ENOTSUP; } +static int vnd_gpio_pin_interrupt_configure(const struct device *port, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + +static int vnd_gpio_manage_callback(const struct device *port, + struct gpio_callback *cb, + bool set) +{ + return -ENOTSUP; +} + +static uint32_t vnd_gpio_get_pending_int(const struct device *dev) +{ + return 0; +} + static const struct gpio_driver_api vnd_gpio_api = { .pin_configure = vnd_gpio_pin_configure, .port_get_raw = vnd_gpio_port_get_raw, @@ -70,6 +90,9 @@ static const struct gpio_driver_api vnd_gpio_api = { .port_set_bits_raw = vnd_gpio_port_set_bits_raw, .port_clear_bits_raw = vnd_gpio_port_clear_bits_raw, .port_toggle_bits = vnd_gpio_port_toggle_bits, + .pin_interrupt_configure = vnd_gpio_pin_interrupt_configure, + .manage_callback = vnd_gpio_manage_callback, + .get_pending_int = vnd_gpio_get_pending_int }; #define VND_GPIO_INIT(n) \ diff --git a/drivers/gpio/gpio_xlnx_axi.c b/drivers/gpio/gpio_xlnx_axi.c index f070e691e5d..99e9e350aa2 100644 --- a/drivers/gpio/gpio_xlnx_axi.c +++ b/drivers/gpio/gpio_xlnx_axi.c @@ -198,7 +198,6 @@ static int gpio_xlnx_axi_port_toggle_bits(const struct device *dev, gpio_port_pi return 0; } -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) /** * Enables interrupts for the given pins on the channel * The axi gpio can only enable interrupts for an entire port, so we need to track @@ -207,6 +206,7 @@ static int gpio_xlnx_axi_port_toggle_bits(const struct device *dev, gpio_port_pi static int gpio_xlnx_axi_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) const struct gpio_xlnx_axi_config *config = dev->config; struct gpio_xlnx_axi_data *data = dev->data; const uint32_t pin_mask = BIT(pin); @@ -390,11 +390,9 @@ static const struct gpio_driver_api gpio_xlnx_axi_driver_api = { .port_set_bits_raw = gpio_xlnx_axi_port_set_bits_raw, .port_clear_bits_raw = gpio_xlnx_axi_port_clear_bits_raw, .port_toggle_bits = gpio_xlnx_axi_port_toggle_bits, -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) .pin_interrupt_configure = gpio_xlnx_axi_pin_interrupt_configure, .manage_callback = gpio_xlnx_axi_manage_callback, .get_pending_int = gpio_xlnx_axi_get_pending_int, -#endif }; #define GPIO_XLNX_AXI_GPIO2_HAS_COMPAT_STATUS_OKAY(n) \ diff --git a/drivers/gpio/gpio_xmc4xxx.c b/drivers/gpio/gpio_xmc4xxx.c index d90f68d3b32..29462308481 100644 --- a/drivers/gpio/gpio_xmc4xxx.c +++ b/drivers/gpio/gpio_xmc4xxx.c @@ -117,10 +117,10 @@ static void gpio_xmc4xxx_isr(const struct device *dev, int pin) } #endif -#ifdef CONFIG_XMC4XXX_INTC static int gpio_xmc4xxx_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode, enum gpio_int_trig trig) { +#if defined(CONFIG_XMC4XXX_INTC) const struct gpio_xmc4xxx_config *config = dev->config; int port_id = PORT_TO_PORT_ID(config->port); @@ -132,8 +132,15 @@ static int gpio_xmc4xxx_pin_interrupt_configure(const struct device *dev, gpio_p } else { return -EINVAL; } -} +#else + ARG_UNUSED(dev); + ARG_UNUSED(pin); + ARG_UNUSED(mode); + ARG_UNUSED(trig); + + return -ENOTSUP; #endif +} static int gpio_xmc4xxx_get_raw(const struct device *dev, gpio_port_value_t *value) { @@ -208,10 +215,8 @@ static const struct gpio_driver_api gpio_xmc4xxx_driver_api = { .port_set_bits_raw = gpio_xmc4xxx_set_bits_raw, .port_clear_bits_raw = gpio_xmc4xxx_clear_bits_raw, .port_toggle_bits = gpio_xmc4xxx_toggle_bits, -#ifdef CONFIG_XMC4XXX_INTC .pin_interrupt_configure = gpio_xmc4xxx_pin_interrupt_configure, - .manage_callback = gpio_xmc4xxx_manage_callback, -#endif + .manage_callback = IS_ENABLED(CONFIG_XMC4XXX_INTC) ? gpio_xmc4xxx_manage_callback : NULL, }; #define GPIO_XMC4XXX_INIT(index) \ From 65bcdc974c463c587b49b3fbd6ee9020d88294be Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:52 +0000 Subject: [PATCH 4373/4498] Revert "[nrf fromtree] boards: arm: (mimx|vmu_)rt1170: fix documentation issues" This reverts commit 3f54ea307c5d2ff2b956ecb191a3bba57e457b63. Signed-off-by: Dominik Ermel --- boards/arm/mimxrt1170_evk/doc/index.rst | 8 ++++++-- boards/arm/vmu_rt1170/doc/index.rst | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index 1582861ffc9..51d5053e360 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -317,8 +317,10 @@ reprogrammed with JLink firmware. - MIMXRT1170-EVKB: :ref:`mcu-link-cmsis-onboard-debug-probe` - MIMXRT1170-EVK: :ref:`opensda-daplink-onboard-debug-probe` +.. _Using J-Link RT1170: + Using J-Link ------------- +--------------------------------- JLink is the default runner for this board. Install the :ref:`jlink-debug-host-tools` and make sure they are in your search path. @@ -328,8 +330,10 @@ J-Link firmware, or :ref:`jlink-external-debug-probe` can be attached to the EVK. See `Using J-Link with MIMXRT1170-EVKB`_ or `Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. +.. _Using LinkServer RT1170: + Using LinkServer ----------------- +---------------------------------- Known limitations with LinkServer and these boards include: - ``west debug`` does not yet work correctly, and the application image is not diff --git a/boards/arm/vmu_rt1170/doc/index.rst b/boards/arm/vmu_rt1170/doc/index.rst index 28d57464b4f..3514bf15893 100644 --- a/boards/arm/vmu_rt1170/doc/index.rst +++ b/boards/arm/vmu_rt1170/doc/index.rst @@ -216,8 +216,10 @@ Configuring a Debug Probe A debug probe is used for both flashing and debugging the board. +.. _Using J-Link RT1170: + Using J-Link ------------- +--------------------------------- Install the :ref:`jlink-debug-host-tools` and make sure they are in your search path. From 56503409542224d86b0746f244d6fcafbf806c07 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:53 +0000 Subject: [PATCH 4374/4498] Revert "[nrf fromtree] linkserver: doc: updates for NXP's mimxrt1170" This reverts commit 2e321f2c6155adc5d32142a5235bd72ea55df2c3. Signed-off-by: Dominik Ermel --- boards/arm/mimxrt1170_evk/doc/index.rst | 102 ++++++++---------------- doc/develop/flash_debug/host-tools.rst | 25 ++---- doc/develop/flash_debug/probes.rst | 61 -------------- 3 files changed, 40 insertions(+), 148 deletions(-) diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index 51d5053e360..90f192c3870 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -1,4 +1,4 @@ -.. _mimxrt1170_evk: +.. _mimxrt1170_evk: NXP MIMXRT1170-EVK/EVKB ####################### @@ -9,7 +9,7 @@ Overview The dual core i.MX RT1170 runs on the Cortex-M7 core at 1 GHz and on the Cortex-M4 at 400 MHz. The i.MX RT1170 MCU offers support over a wide temperature range and is qualified for consumer, industrial and automotive markets. Zephyr -supports the initial revision of this EVK, as well as rev EVKB. +supports the initial revision of this EVK, as well as EVK rev B. .. image:: mimxrt1170_evk.jpg :align: center @@ -59,7 +59,7 @@ Hardware - Debug - JTAG 20-pin connector - - on-board debugger + - OpenSDA with DAPLink - Sensor @@ -90,17 +90,16 @@ This platform has the following external memories: | Device | Controller | Status | +====================+============+=====================================+ | W9825G6KH | SEMC | Enabled via device configuration | -| SDRAM | | data (DCD) block, which sets up | -| | | the SEMC at boot time | +| | | data block, which sets up SEMC at | +| | | boot time | +--------------------+------------+-------------------------------------+ -| IS25WP128 | FLEXSPI | Enabled via flash configuration | -| QSPI flash | | block (FCB), which sets up the | -| (RT1170 EVK) | | FLEXSPI at boot time. | +| IS25WP128 | FLEXSPI | Enabled via flash configurationn | +| (RT1170 EVK) | | block, which sets up FLEXSPI at | +| | | boot time. | +--------------------+------------+-------------------------------------+ -| W25Q512NWEIQ | FLEXSPI | Enabled via flash configuration | -| QSPI flash | | block (FCB), which sets up the | -| (RT1170 EVKB) | | FLEXSPI at boot time. Supported for | -| | | XIP only. | +| W25Q512NWEIQ | FLEXSPI | Enabled via flash configurationn | +| (RT1170 EVKB) | | block, which sets up FLEXSPI at | +| | | boot time. Supported for XIP only. | +--------------------+------------+-------------------------------------+ Supported Features @@ -124,8 +123,6 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | COUNTER | on-chip | gpt | Supported | Supported | +-----------+------------+-------------------------------------+-----------------+-----------------+ -| TIMER | on-chip | gpt | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ | CAN | on-chip | flexcan | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ | SPI | on-chip | spi | Supported (M7) | Supported | @@ -142,10 +139,11 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | DMA | on-chip | dma | Supported | Supported | +-----------+------------+-------------------------------------+-----------------+-----------------+ +| GPT | on-chip | gpt | Supported | Supported | ++-----------+------------+-------------------------------------+-----------------+-----------------+ | WATCHDOG | on-chip | watchdog | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ -| ENET | on-chip | ethernet - 10/100M (ENET_QOS or | Supported (M7) | No support | -| ENET1G | | GigE not supported yet) | | | +| ENET | on-chip | ethernet | Supported (M7) | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ | SAI | on-chip | i2s | Supported | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ @@ -167,9 +165,10 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) | SDHC | on-chip | SD host controller | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ -The default configuration can be found in the defconfig files: +The default configuration can be found in the defconfig file: ``boards/arm/mimxrt1170_evk/mimxrt1170_evk_cm7_defconfig`` -``boards/arm/mimxrt1170_evk/mimxrt1170_evkb_cm7_defconfig`` + +Other hardware features are not currently supported by the port. Connections and I/Os ==================== @@ -311,62 +310,33 @@ secondary core should be placed into a loop, then a debugger can be attached Configuring a Debug Probe ========================= -A debug probe is used for both flashing and debugging the board. The on-board -debugger listed below works with the LinkServer runner by default, or can be -reprogrammed with JLink firmware. -- MIMXRT1170-EVKB: :ref:`mcu-link-cmsis-onboard-debug-probe` -- MIMXRT1170-EVK: :ref:`opensda-daplink-onboard-debug-probe` +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the :ref:`opensda-daplink-onboard-debug-probe`, +however the :ref:`pyocd-debug-host-tools` do not yet support programming the +external flashes on this board so you must reconfigure the board for one of the +following debug probes instead. .. _Using J-Link RT1170: Using J-Link --------------------------------- -JLink is the default runner for this board. Install the -:ref:`jlink-debug-host-tools` and make sure they are in your search path. +Install the :ref:`jlink-debug-host-tools` and make sure they are in your search +path. There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or :ref:`jlink-external-debug-probe` can be attached to the -EVK. See `Using J-Link with MIMXRT1170-EVKB`_ or -`Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. - -.. _Using LinkServer RT1170: - -Using LinkServer ----------------------------------- - -Known limitations with LinkServer and these boards include: -- ``west debug`` does not yet work correctly, and the application image is not -properly written to the memory. `NXP MCUXpresso for Visual Studio Code`_ -can be used to debug Zephyr applications with LinkServer. -- ``west flash`` will not write images to non-flash locations. The flash -command only works when all data in the image is written to flash memory -regions. - -Install the :ref:`linkserver-debug-host-tools` and make sure they are in your -search path. LinkServer works with the default CMSIS-DAP firmware included in -the on-board debugger. - -Use the ``-r linkserver`` option with West to use the LinkServer runner. - -.. code-block:: console - - west flash -r linkserver - +EVK. See `Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK`_ for more details. Configuring a Console ===================== -We will use the on-board debugger -microcontroller as a usb-to-serial adapter for the serial console. The following -jumper settings are default on these boards, and are required to connect the -UART signals to the USB bridge circuit: -- MIMXRT1170-EVKB: JP2 open (default) -- MIMXRT1170-EVK: J31 and J32 shorted (default) +Regardless of your choice in debug probe, we will use the OpenSDA +microcontroller as a usb-to-serial adapter for the serial console. Check that +jumpers J5 and J8 are **on** (they are on by default when boards ship from +the factory) to connect UART signals to the OpenSDA microcontroller. -Connect a USB cable from your PC to the on-board debugger USB port: -- MIMXRT1170-EVKB: J86 -- MIMXRT1170-EVK: J11 +Connect a USB cable from your PC to J11. Use the following settings with your serial terminal of choice (minicom, putty, etc.): @@ -381,7 +351,7 @@ Flashing Here is an example for the :ref:`hello_world` application. -Before powering the board, make sure SW1 is set to 0001b +Before power on the board, make sure SW1 is set to 0001b .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -394,7 +364,7 @@ see the following message in the terminal: .. code-block:: console - ***** Booting Zephyr OS v3.4.0-xxxx-xxxxxxxxxxxxx ***** + ***** Booting Zephyr OS v2.4.0-xxxx-xxxxxxxxxxxxx ***** Hello World! mimxrt1170_evk_cm7 Debugging @@ -412,7 +382,7 @@ should see the following message in the terminal: .. code-block:: console - ***** Booting Zephyr OS v3.4.0-xxxx-xxxxxxxxxxxxx ***** + ***** Booting Zephyr OS v2.4.0-xxxx-xxxxxxxxxxxxx ***** Hello World! mimxrt1170_evk_cm7 .. _MIMXRT1170-EVK Website: @@ -433,11 +403,5 @@ should see the following message in the terminal: .. _Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK: https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Using-J-Link-with-MIMXRT1160-EVK-or-MIMXRT1170-EVK/ta-p/1529760 -.. _Using J-Link with MIMXRT1170-EVKB: - https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Using-J-Link-with-MIMXRT1170-EVKB/ta-p/1715138 - .. _AN13264: https://www.nxp.com/docs/en/application-note/AN13264.pdf - -.. _NXP MCUXpresso for Visual Studio Code: - https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-for-visual-studio-code:MCUXPRESSO-VSC diff --git a/doc/develop/flash_debug/host-tools.rst b/doc/develop/flash_debug/host-tools.rst index 981c89ce686..e93ee618f55 100644 --- a/doc/develop/flash_debug/host-tools.rst +++ b/doc/develop/flash_debug/host-tools.rst @@ -206,20 +206,17 @@ LinkServer Debug Host Tools Linkserver is a utility for launching and managing GDB servers for NXP debug probes, which also provides a command-line target flash programming capabilities. -Linkserver can be used with the `NXP MCUXpresso for Visual Studio Code`_ implementation, +Linkserver can be used with NXP MCUXpresso for Visual Studio Code implementation, with custom debug configurations based on GNU tools or as part of a headless solution -for continuous integration and test. LinkServer can be used with MCU-Link, LPC-Link2, +for continuous integration and test. Linkserver can be used with MCU-Link, LPC-Link2, LPC11U35-based and OpenSDA based standalone or on-board debug probes from NXP. - -NXP recommends installing LinkServer by using NXP's `MCUXpresso Installer`_. -This method will also install the tools supporting the debug probes below, -including NXP's MCU-Link and LPCScrypt tools. +The Linkserver installer also includes the firmware update utilities for MCU-Link and +the LPCScrypt utility for use with LPC-Link2. Linkserver can also be installed using +the MCUXpresso Installer. LinkServer is compatible with the following debug probes: - :ref:`lpclink2-cmsis-onboard-debug-probe` -- :ref:`mcu-link-cmsis-onboard-debug-probe` -- :ref:`opensda-daplink-onboard-debug-probe` Supported west commands: @@ -237,14 +234,13 @@ Notes: LinkServer probes -2. With multiple debug probes attached to the host, use the -LinkServer west runner ``--probe`` option to pass the probe index. +2. Use the LinkServer west runner ``--probe`` option to pass the probe index. .. code-block:: console west flash --runner=linkserver --probe=3 -3. Device-specific settings can be overridden with the west runner for LinkServer with +3. device specific settings can be overridden with the west runner for LinkServer with the option '--override'. May be used multiple times. The format is dictated by LinkServer, e.g.: @@ -269,7 +265,6 @@ These debug host tools are compatible with the following debug probes: - :ref:`lpclink2-jlink-onboard-debug-probe` - :ref:`opensda-jlink-onboard-debug-probe` -- :ref:`mcu-link-jlink-onboard-debug-probe` - :ref:`jlink-external-debug-probe` - :ref:`stlink-v21-onboard-debug-probe` @@ -410,9 +405,3 @@ To enable Zephyr RTOS awareness follow the steps described in .. _BOSSA official releases: https://github.com/shumatech/BOSSA/releases - -.. _NXP MCUXpresso for Visual Studio Code: - https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-for-visual-studio-code:MCUXPRESSO-VSC - -.. _MCUXpresso Installer: - https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe diff --git a/doc/develop/flash_debug/probes.rst b/doc/develop/flash_debug/probes.rst index 83f355aadba..78a068d6ac4 100644 --- a/doc/develop/flash_debug/probes.rst +++ b/doc/develop/flash_debug/probes.rst @@ -58,64 +58,6 @@ onboard debug probe may have limitations, such as lack of support for advanced debuggers or high-speed tracing. You may need to adjust jumpers to prevent the onboard debug probe from interfering with the external debug probe. -.. _mcu-link-cmsis-onboard-debug-probe: - -MCU-Link CMSIS-DAP Onboard Debug Probe -*************************************** - -The CMSIS-DAP debug probes allow debugging from any compatible toolchain, -including IAR EWARM, Keil MDK, NXP’s MCUXpresso IDE and -MCUXpresso extension for VS Code. In addition to debug probe functionality, the -MCU-Link probes may also provide: - -1. SWO trace end point: this virtual device is used by MCUXpresso to retrieve - SWO trace data. See the MCUXpresso IDE documentation for more information. -#. Virtual COM (VCOM) port / UART bridge connected to the target processor -#. USB to UART, SPI and/or I2C interfaces (depending on MCU-Link - type/implementation) -#. Energy measurements of the target MCU - -This debug probe is compatible with the following debug host tools: - -- :ref:`linkserver-debug-host-tools` - -This probe is realized by programming the MCU-Link microcontroller with the -CMSIS-DAP MCU-Link firmware, which is already installed by default. NXP -recommends using NXP's `MCUXpresso Installer`_, which installs both the MCU-Link -host tools plus the :ref:`linkserver-debug-host-tools`. - -1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. - -#. Run the ``program_CMSIS`` script, found in the installed MCU-Link ``scripts`` - folder. - -#. Remove the DFU jumper and power cycle the board. - -.. _mcu-link-jlink-onboard-debug-probe: - -MCU-Link JLink Onboard Debug Probe -************************************ - -The MCU-Link J-Link is an onboard debug probe and usb-to-serial adapter -supported on many NXP development boards. - -This debug probe is compatible with the following debug host tools: - -- :ref:`jlink-debug-host-tools` - -These probes do not have JLink firmware installed by default, and must be -updated. NXP recommends using NXP's `MCUXpresso Installer`_, which installs both -the :ref:`jlink-debug-host-tools` plus the MCU-Link host tools. - -1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. - -#. Run the ``program_JLINK`` script, found in the installed MCU-Link ``scripts`` - folder. - -#. Remove the DFU jumper and power cycle the board. - .. _lpclink2-cmsis-onboard-debug-probe: LPC-LINK2 CMSIS DAP Onboard Debug Probe @@ -399,6 +341,3 @@ option. For more information about twister and available options, see .. _STM32CubeProgrammer Tool: https://www.st.com/en/development-tools/stm32cubeprog.html - -.. _MCUXpresso Installer: - https://www.nxp.com/lgfiles/updates/mcuxpresso/MCUXpressoInstaller.exe From 183f0083a23f1098913352d106b6d70759fe86d5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:54 +0000 Subject: [PATCH 4375/4498] Revert "[nrf fromtree] manifest: hal_nordic: update to prevent USBD bad DMA" This reverts commit 0985ab67282f633fe616fb499248c225a75cfe24. Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b4f874a87c5..727d6d807ab 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 092eb78ed1b1551d8f480019b9c05d7371784578 + revision: 9ae7c765985ebdea3d9b98c0d3b154794f0b47cf path: modules/hal/nordic groups: - hal From aeb36c063d0429999f0b73a87e266ea51825228c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:54 +0000 Subject: [PATCH 4376/4498] Revert "[nrf fromlist] Bluetooth: Host: Use memcpy instad of strncpy in bt_set_name" This reverts commit 7ff9fc19e1337526ed731f643d716ddcc55c9e9a. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 40e1b44e960..260865e6a36 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -4144,7 +4144,7 @@ int bt_set_name(const char *name) return 0; } - memcpy(bt_dev.name, name, len); + strncpy(bt_dev.name, name, len); bt_dev.name[len] = '\0'; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { From 134849dc9483bbcca152f61429e7fc4605e94dc7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:54 +0000 Subject: [PATCH 4377/4498] Revert "[nrf fromtree] tests: net: lib: lwm2m: fix the missing float support" This reverts commit 61e999db7b38eff9939f51860a0a2e2a7fe87138. Signed-off-by: Dominik Ermel --- tests/net/lib/lwm2m/content_json/prj.conf | 2 -- tests/net/lib/lwm2m/content_plain_text/prj.conf | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/net/lib/lwm2m/content_json/prj.conf b/tests/net/lib/lwm2m/content_json/prj.conf index 7ff07df9897..3f2cd3e60f2 100644 --- a/tests/net/lib/lwm2m/content_json/prj.conf +++ b/tests/net/lib/lwm2m/content_json/prj.conf @@ -9,5 +9,3 @@ CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 CONFIG_LWM2M_RW_JSON_SUPPORT=y CONFIG_JSON_LIBRARY=y - -CONFIG_PICOLIBC_IO_FLOAT=y diff --git a/tests/net/lib/lwm2m/content_plain_text/prj.conf b/tests/net/lib/lwm2m/content_plain_text/prj.conf index 877c969958f..6041addad83 100644 --- a/tests/net/lib/lwm2m/content_plain_text/prj.conf +++ b/tests/net/lib/lwm2m/content_plain_text/prj.conf @@ -6,5 +6,3 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_LWM2M=y - -CONFIG_PICOLIBC_IO_FLOAT=y From 2d2595b7008b4f222e6843626b4f82d857973858 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:55 +0000 Subject: [PATCH 4378/4498] Revert "[nrf fromtree] Bluetooth: Controller: Fix missing PHY_CODED cond compile" This reverts commit 2069e2a621432e875a488200ef7a4d95285f5864. Signed-off-by: Dominik Ermel --- samples/bluetooth/hci_rpmsg/sample.yaml | 10 ---------- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 2 -- 2 files changed, 12 deletions(-) diff --git a/samples/bluetooth/hci_rpmsg/sample.yaml b/samples/bluetooth/hci_rpmsg/sample.yaml index 7cecb12be67..3330002a59d 100644 --- a/samples/bluetooth/hci_rpmsg/sample.yaml +++ b/samples/bluetooth/hci_rpmsg/sample.yaml @@ -82,16 +82,6 @@ tests: platform_allow: nrf5340dk_nrf5340_cpunet integration_platforms: - nrf5340dk_nrf5340_cpunet - sample.bluetooth.hci_rpmsg.df.no_phy_coded.bt_ll_sw_split: - harness: bluetooth - tags: bluetooth - extra_args: - - CONF_FILE="nrf5340_cpunet_df-bt_ll_sw_split.conf" - - DTC_OVERLAY_FILE="nrf5340_cpunet_df-bt_ll_sw_split.overlay" - - CONFIG_BT_CTLR_PHY_CODED=n - platform_allow: nrf5340dk_nrf5340_cpunet - integration_platforms: - - nrf5340dk_nrf5340_cpunet sample.bluetooth.hci_rpmsg.mesh.bt_ll_sw_split: harness: bluetooth tags: bluetooth diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 71e5ffa0e6f..085b881d47e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -582,7 +582,6 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI)); } -#if defined(CONFIG_BT_CTLR_PHY_CODED) && defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) { @@ -595,7 +594,6 @@ static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT( SW_SWITCH_TIMER_S2_EVTS_COMP(group_index)) = 0; } -#endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ static inline void hal_radio_sw_switch_disable_group_clear(uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) From cb046402c3ba6bca0db04a27205524583b0aa9d4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:55 +0000 Subject: [PATCH 4379/4498] Revert "[nrf fromtree] net: wifi: Move function from shell to mgmt" This reverts commit 4a36c92e39aae11a7736b872dd9f0c8d34235af5. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_mgmt.c | 218 -------------------------------- subsys/net/l2/wifi/wifi_shell.c | 218 ++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 218 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 0751f5d2b8c..dba18f8154f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -18,224 +18,6 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #endif /* CONFIG_WIFI_NM */ -const char * const wifi_security_txt(enum wifi_security_type security) -{ - switch (security) { - case WIFI_SECURITY_TYPE_NONE: - return "OPEN"; - case WIFI_SECURITY_TYPE_WEP: - return "WEP"; - case WIFI_SECURITY_TYPE_WPA_PSK: - return "WPA-PSK"; - case WIFI_SECURITY_TYPE_PSK: - return "WPA2-PSK"; - case WIFI_SECURITY_TYPE_PSK_SHA256: - return "WPA2-PSK-SHA256"; - case WIFI_SECURITY_TYPE_SAE: - return "WPA3-SAE"; - case WIFI_SECURITY_TYPE_WAPI: - return "WAPI"; - case WIFI_SECURITY_TYPE_EAP: - return "EAP"; - case WIFI_SECURITY_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) -{ - switch (mfp) { - case WIFI_MFP_DISABLE: - return "Disable"; - case WIFI_MFP_OPTIONAL: - return "Optional"; - case WIFI_MFP_REQUIRED: - return "Required"; - case WIFI_MFP_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_band_txt(enum wifi_frequency_bands band) -{ - switch (band) { - case WIFI_FREQ_BAND_2_4_GHZ: - return "2.4GHz"; - case WIFI_FREQ_BAND_5_GHZ: - return "5GHz"; - case WIFI_FREQ_BAND_6_GHZ: - return "6GHz"; - case WIFI_FREQ_BAND_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_state_txt(enum wifi_iface_state state) -{ - switch (state) { - case WIFI_STATE_DISCONNECTED: - return "DISCONNECTED"; - case WIFI_STATE_INACTIVE: - return "INACTIVE"; - case WIFI_STATE_INTERFACE_DISABLED: - return "INTERFACE_DISABLED"; - case WIFI_STATE_SCANNING: - return "SCANNING"; - case WIFI_STATE_AUTHENTICATING: - return "AUTHENTICATING"; - case WIFI_STATE_ASSOCIATING: - return "ASSOCIATING"; - case WIFI_STATE_ASSOCIATED: - return "ASSOCIATED"; - case WIFI_STATE_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case WIFI_STATE_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case WIFI_STATE_COMPLETED: - return "COMPLETED"; - case WIFI_STATE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mode_txt(enum wifi_iface_mode mode) -{ - switch (mode) { - case WIFI_MODE_INFRA: - return "STATION"; - case WIFI_MODE_IBSS: - return "ADHOC"; - case WIFI_MODE_AP: - return "ACCESS POINT"; - case WIFI_MODE_P2P_GO: - return "P2P GROUP OWNER"; - case WIFI_MODE_P2P_GROUP_FORMATION: - return "P2P GROUP FORMATION"; - case WIFI_MODE_MESH: - return "MESH"; - case WIFI_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) -{ - switch (link_mode) { - case WIFI_0: - return "WIFI 0 (802.11)"; - case WIFI_1: - return "WIFI 1 (802.11b)"; - case WIFI_2: - return "WIFI 2 (802.11a)"; - case WIFI_3: - return "WIFI 3 (802.11g)"; - case WIFI_4: - return "WIFI 4 (802.11n/HT)"; - case WIFI_5: - return "WIFI 5 (802.11ac/VHT)"; - case WIFI_6: - return "WIFI 6 (802.11ax/HE)"; - case WIFI_6E: - return "WIFI 6E (802.11ax 6GHz/HE)"; - case WIFI_7: - return "WIFI 7 (802.11be/EHT)"; - case WIFI_LINK_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_txt(enum wifi_ps ps_name) -{ - switch (ps_name) { - case WIFI_PS_DISABLED: - return "Power save disabled"; - case WIFI_PS_ENABLED: - return "Power save enabled"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) -{ - switch (ps_mode) { - case WIFI_PS_MODE_LEGACY: - return "Legacy power save"; - case WIFI_PS_MODE_WMM: - return "WMM power save"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) -{ - switch (twt_operation) { - case WIFI_TWT_SETUP: - return "TWT setup"; - case WIFI_TWT_TEARDOWN: - return "TWT teardown"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) -{ - switch (twt_negotiation) { - case WIFI_TWT_INDIVIDUAL: - return "TWT individual negotiation"; - case WIFI_TWT_BROADCAST: - return "TWT broadcast negotiation"; - case WIFI_TWT_WAKE_TBTT: - return "TWT wake TBTT negotiation"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) -{ - switch (twt_setup) { - case WIFI_TWT_SETUP_CMD_REQUEST: - return "TWT request"; - case WIFI_TWT_SETUP_CMD_SUGGEST: - return "TWT suggest"; - case WIFI_TWT_SETUP_CMD_DEMAND: - return "TWT demand"; - case WIFI_TWT_SETUP_CMD_GROUPING: - return "TWT grouping"; - case WIFI_TWT_SETUP_CMD_ACCEPT: - return "TWT accept"; - case WIFI_TWT_SETUP_CMD_ALTERNATE: - return "TWT alternate"; - case WIFI_TWT_SETUP_CMD_DICTATE: - return "TWT dictate"; - case WIFI_TWT_SETUP_CMD_REJECT: - return "TWT reject"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) -{ - switch (ps_wakeup_mode) { - case WIFI_PS_WAKEUP_MODE_DTIM: - return "PS wakeup mode DTIM"; - case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: - return "PS wakeup mode listen interval"; - default: - return "UNKNOWN"; - } -} - static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index f1c512304bf..1fd2a537952 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -97,6 +97,224 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi return true; } +const char * const wifi_security_txt(enum wifi_security_type security) +{ + switch (security) { + case WIFI_SECURITY_TYPE_NONE: + return "OPEN"; + case WIFI_SECURITY_TYPE_WEP: + return "WEP"; + case WIFI_SECURITY_TYPE_WPA_PSK: + return "WPA-PSK"; + case WIFI_SECURITY_TYPE_PSK: + return "WPA2-PSK"; + case WIFI_SECURITY_TYPE_PSK_SHA256: + return "WPA2-PSK-SHA256"; + case WIFI_SECURITY_TYPE_SAE: + return "WPA3-SAE"; + case WIFI_SECURITY_TYPE_WAPI: + return "WAPI"; + case WIFI_SECURITY_TYPE_EAP: + return "EAP"; + case WIFI_SECURITY_TYPE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) +{ + switch (mfp) { + case WIFI_MFP_DISABLE: + return "Disable"; + case WIFI_MFP_OPTIONAL: + return "Optional"; + case WIFI_MFP_REQUIRED: + return "Required"; + case WIFI_MFP_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_band_txt(enum wifi_frequency_bands band) +{ + switch (band) { + case WIFI_FREQ_BAND_2_4_GHZ: + return "2.4GHz"; + case WIFI_FREQ_BAND_5_GHZ: + return "5GHz"; + case WIFI_FREQ_BAND_6_GHZ: + return "6GHz"; + case WIFI_FREQ_BAND_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_state_txt(enum wifi_iface_state state) +{ + switch (state) { + case WIFI_STATE_DISCONNECTED: + return "DISCONNECTED"; + case WIFI_STATE_INACTIVE: + return "INACTIVE"; + case WIFI_STATE_INTERFACE_DISABLED: + return "INTERFACE_DISABLED"; + case WIFI_STATE_SCANNING: + return "SCANNING"; + case WIFI_STATE_AUTHENTICATING: + return "AUTHENTICATING"; + case WIFI_STATE_ASSOCIATING: + return "ASSOCIATING"; + case WIFI_STATE_ASSOCIATED: + return "ASSOCIATED"; + case WIFI_STATE_4WAY_HANDSHAKE: + return "4WAY_HANDSHAKE"; + case WIFI_STATE_GROUP_HANDSHAKE: + return "GROUP_HANDSHAKE"; + case WIFI_STATE_COMPLETED: + return "COMPLETED"; + case WIFI_STATE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_mode_txt(enum wifi_iface_mode mode) +{ + switch (mode) { + case WIFI_MODE_INFRA: + return "STATION"; + case WIFI_MODE_IBSS: + return "ADHOC"; + case WIFI_MODE_AP: + return "ACCESS POINT"; + case WIFI_MODE_P2P_GO: + return "P2P GROUP OWNER"; + case WIFI_MODE_P2P_GROUP_FORMATION: + return "P2P GROUP FORMATION"; + case WIFI_MODE_MESH: + return "MESH"; + case WIFI_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) +{ + switch (link_mode) { + case WIFI_0: + return "WIFI 0 (802.11)"; + case WIFI_1: + return "WIFI 1 (802.11b)"; + case WIFI_2: + return "WIFI 2 (802.11a)"; + case WIFI_3: + return "WIFI 3 (802.11g)"; + case WIFI_4: + return "WIFI 4 (802.11n/HT)"; + case WIFI_5: + return "WIFI 5 (802.11ac/VHT)"; + case WIFI_6: + return "WIFI 6 (802.11ax/HE)"; + case WIFI_6E: + return "WIFI 6E (802.11ax 6GHz/HE)"; + case WIFI_7: + return "WIFI 7 (802.11be/EHT)"; + case WIFI_LINK_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_txt(enum wifi_ps ps_name) +{ + switch (ps_name) { + case WIFI_PS_DISABLED: + return "Power save disabled"; + case WIFI_PS_ENABLED: + return "Power save enabled"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) +{ + switch (ps_mode) { + case WIFI_PS_MODE_LEGACY: + return "Legacy power save"; + case WIFI_PS_MODE_WMM: + return "WMM power save"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) +{ + switch (twt_operation) { + case WIFI_TWT_SETUP: + return "TWT setup"; + case WIFI_TWT_TEARDOWN: + return "TWT teardown"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) +{ + switch (twt_negotiation) { + case WIFI_TWT_INDIVIDUAL: + return "TWT individual negotiation"; + case WIFI_TWT_BROADCAST: + return "TWT broadcast negotiation"; + case WIFI_TWT_WAKE_TBTT: + return "TWT wake TBTT negotiation"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) +{ + switch (twt_setup) { + case WIFI_TWT_SETUP_CMD_REQUEST: + return "TWT request"; + case WIFI_TWT_SETUP_CMD_SUGGEST: + return "TWT suggest"; + case WIFI_TWT_SETUP_CMD_DEMAND: + return "TWT demand"; + case WIFI_TWT_SETUP_CMD_GROUPING: + return "TWT grouping"; + case WIFI_TWT_SETUP_CMD_ACCEPT: + return "TWT accept"; + case WIFI_TWT_SETUP_CMD_ALTERNATE: + return "TWT alternate"; + case WIFI_TWT_SETUP_CMD_DICTATE: + return "TWT dictate"; + case WIFI_TWT_SETUP_CMD_REJECT: + return "TWT reject"; + default: + return "UNKNOWN"; + } +} + +const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) +{ + switch (ps_wakeup_mode) { + case WIFI_PS_WAKEUP_MODE_DTIM: + return "PS wakeup mode DTIM"; + case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: + return "PS wakeup mode listen interval"; + default: + return "UNKNOWN"; + } +} + static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) { const struct wifi_scan_result *entry = From 066149286b504a72ad4a4f6f282ed623ce390629 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:55 +0000 Subject: [PATCH 4380/4498] Revert "[nrf fromtree] net: l2: wifi: Change arrays to functions" This reverts commit ff771d084177ffb3595bf855fb0fb26cef6c225e. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi.h | 187 ++++++++++++++++++++--- subsys/net/l2/wifi/wifi_shell.c | 258 +++----------------------------- 2 files changed, 189 insertions(+), 256 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 294fdc53c5d..55bd8d71a3a 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -52,7 +52,30 @@ enum wifi_security_type { }; /** Helper function to get user-friendly security type name. */ -const char * const wifi_security_txt(enum wifi_security_type security); +static inline const char *wifi_security_txt(enum wifi_security_type security) +{ + switch (security) { + case WIFI_SECURITY_TYPE_NONE: + return "OPEN"; + case WIFI_SECURITY_TYPE_WEP: + return "WEP"; + case WIFI_SECURITY_TYPE_WPA_PSK: + return "WPA-PSK"; + case WIFI_SECURITY_TYPE_PSK: + return "WPA2-PSK"; + case WIFI_SECURITY_TYPE_PSK_SHA256: + return "WPA2-PSK-SHA256"; + case WIFI_SECURITY_TYPE_SAE: + return "WPA3-SAE"; + case WIFI_SECURITY_TYPE_WAPI: + return "WAPI"; + case WIFI_SECURITY_TYPE_EAP: + return "EAP"; + case WIFI_SECURITY_TYPE_UNKNOWN: + default: + return "UNKNOWN"; + } +} /** IEEE 802.11w - Management frame protection. */ enum wifi_mfp_options { @@ -69,7 +92,20 @@ enum wifi_mfp_options { }; /** Helper function to get user-friendly MFP name.*/ -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp); +static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp) +{ + switch (mfp) { + case WIFI_MFP_DISABLE: + return "Disable"; + case WIFI_MFP_OPTIONAL: + return "Optional"; + case WIFI_MFP_REQUIRED: + return "Required"; + case WIFI_MFP_UNKNOWN: + default: + return "UNKNOWN"; + } +} /** * @brief IEEE 802.11 operational frequency bands (not exhaustive). @@ -91,7 +127,20 @@ enum wifi_frequency_bands { }; /** Helper function to get user-friendly frequency band name. */ -const char * const wifi_band_txt(enum wifi_frequency_bands band); +static inline const char *wifi_band_txt(enum wifi_frequency_bands band) +{ + switch (band) { + case WIFI_FREQ_BAND_2_4_GHZ: + return "2.4GHz"; + case WIFI_FREQ_BAND_5_GHZ: + return "5GHz"; + case WIFI_FREQ_BAND_6_GHZ: + return "6GHz"; + case WIFI_FREQ_BAND_UNKNOWN: + default: + return "UNKNOWN"; + } +} #define WIFI_SSID_MAX_LEN 32 #define WIFI_PSK_MIN_LEN 8 @@ -135,7 +184,34 @@ enum wifi_iface_state { }; /** Helper function to get user-friendly interface state name. */ -const char * const wifi_state_txt(enum wifi_iface_state state); +static inline const char *wifi_state_txt(enum wifi_iface_state state) +{ + switch (state) { + case WIFI_STATE_DISCONNECTED: + return "DISCONNECTED"; + case WIFI_STATE_INACTIVE: + return "INACTIVE"; + case WIFI_STATE_INTERFACE_DISABLED: + return "INTERFACE_DISABLED"; + case WIFI_STATE_SCANNING: + return "SCANNING"; + case WIFI_STATE_AUTHENTICATING: + return "AUTHENTICATING"; + case WIFI_STATE_ASSOCIATING: + return "ASSOCIATING"; + case WIFI_STATE_ASSOCIATED: + return "ASSOCIATED"; + case WIFI_STATE_4WAY_HANDSHAKE: + return "4WAY_HANDSHAKE"; + case WIFI_STATE_GROUP_HANDSHAKE: + return "GROUP_HANDSHAKE"; + case WIFI_STATE_COMPLETED: + return "COMPLETED"; + case WIFI_STATE_UNKNOWN: + default: + return "UNKNOWN"; + } +} /** Wi-Fi interface modes. * @@ -161,7 +237,26 @@ enum wifi_iface_mode { }; /** Helper function to get user-friendly interface mode name. */ -const char * const wifi_mode_txt(enum wifi_iface_mode mode); +static inline const char *wifi_mode_txt(enum wifi_iface_mode mode) +{ + switch (mode) { + case WIFI_MODE_INFRA: + return "STATION"; + case WIFI_MODE_IBSS: + return "ADHOC"; + case WIFI_MODE_AP: + return "ACCESS POINT"; + case WIFI_MODE_P2P_GO: + return "P2P GROUP OWNER"; + case WIFI_MODE_P2P_GROUP_FORMATION: + return "P2P GROUP FORMATION"; + case WIFI_MODE_MESH: + return "MESH"; + case WIFI_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} /** Wi-Fi link operating modes * @@ -193,7 +288,32 @@ enum wifi_link_mode { }; /** Helper function to get user-friendly link mode name. */ -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode); +static inline const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) +{ + switch (link_mode) { + case WIFI_0: + return "WIFI 0 (802.11)"; + case WIFI_1: + return "WIFI 1 (802.11b)"; + case WIFI_2: + return "WIFI 2 (802.11a)"; + case WIFI_3: + return "WIFI 3 (802.11g)"; + case WIFI_4: + return "WIFI 4 (802.11n/HT)"; + case WIFI_5: + return "WIFI 5 (802.11ac/VHT)"; + case WIFI_6: + return "WIFI 6 (802.11ax/HE)"; + case WIFI_6E: + return "WIFI 6E (802.11ax 6GHz/HE)"; + case WIFI_7: + return "WIFI 7 (802.11be/EHT)"; + case WIFI_LINK_MODE_UNKNOWN: + default: + return "UNKNOWN"; + } +} /** Wi-Fi scanning types. */ enum wifi_scan_type { @@ -211,8 +331,12 @@ enum wifi_ps { WIFI_PS_ENABLED, }; -/** Helper function to get user-friendly ps name. */ -const char * const wifi_ps_txt(enum wifi_ps ps_name); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_ps2str[] = { + [WIFI_PS_DISABLED] = "Power save disabled", + [WIFI_PS_ENABLED] = "Power save enabled", +}; +/** @endcond */ /** Wi-Fi power save modes. */ enum wifi_ps_mode { @@ -225,8 +349,12 @@ enum wifi_ps_mode { WIFI_PS_MODE_WMM, }; -/** Helper function to get user-friendly ps mode name. */ -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_ps_mode2str[] = { + [WIFI_PS_MODE_LEGACY] = "Legacy power save", + [WIFI_PS_MODE_WMM] = "WMM power save", +}; +/** @endcond */ /* Interface index Min and Max values */ #define WIFI_INTERFACE_INDEX_MIN 1 @@ -268,8 +396,12 @@ enum wifi_twt_operation { WIFI_TWT_TEARDOWN, }; -/** Helper function to get user-friendly twt operation name. */ -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_twt_operation2str[] = { + [WIFI_TWT_SETUP] = "TWT setup", + [WIFI_TWT_TEARDOWN] = "TWT teardown", +}; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { @@ -281,8 +413,13 @@ enum wifi_twt_negotiation_type { WIFI_TWT_WAKE_TBTT }; -/** Helper function to get user-friendly twt negotiation type name. */ -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_twt_negotiation_type2str[] = { + [WIFI_TWT_INDIVIDUAL] = "TWT individual negotiation", + [WIFI_TWT_BROADCAST] = "TWT broadcast negotiation", + [WIFI_TWT_WAKE_TBTT] = "TWT wake TBTT negotiation", +}; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { @@ -304,8 +441,18 @@ enum wifi_twt_setup_cmd { WIFI_TWT_SETUP_CMD_REJECT, }; -/** Helper function to get user-friendly twt setup cmd name. */ -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_twt_setup_cmd2str[] = { + [WIFI_TWT_SETUP_CMD_REQUEST] = "TWT request", + [WIFI_TWT_SETUP_CMD_SUGGEST] = "TWT suggest", + [WIFI_TWT_SETUP_CMD_DEMAND] = "TWT demand", + [WIFI_TWT_SETUP_CMD_GROUPING] = "TWT grouping", + [WIFI_TWT_SETUP_CMD_ACCEPT] = "TWT accept", + [WIFI_TWT_SETUP_CMD_ALTERNATE] = "TWT alternate", + [WIFI_TWT_SETUP_CMD_DICTATE] = "TWT dictate", + [WIFI_TWT_SETUP_CMD_REJECT] = "TWT reject", +}; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) negotiation status. */ enum wifi_twt_setup_resp_status { @@ -396,8 +543,12 @@ enum wifi_ps_wakeup_mode { WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, }; -/** Helper function to get user-friendly ps wakeup mode name. */ -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode); +/** @cond INTERNAL_HIDDEN */ +static const char * const wifi_ps_wakeup_mode2str[] = { + [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", + [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", +}; +/** @endcond */ /** Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 1fd2a537952..236fb32ee83 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -97,224 +97,6 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi return true; } -const char * const wifi_security_txt(enum wifi_security_type security) -{ - switch (security) { - case WIFI_SECURITY_TYPE_NONE: - return "OPEN"; - case WIFI_SECURITY_TYPE_WEP: - return "WEP"; - case WIFI_SECURITY_TYPE_WPA_PSK: - return "WPA-PSK"; - case WIFI_SECURITY_TYPE_PSK: - return "WPA2-PSK"; - case WIFI_SECURITY_TYPE_PSK_SHA256: - return "WPA2-PSK-SHA256"; - case WIFI_SECURITY_TYPE_SAE: - return "WPA3-SAE"; - case WIFI_SECURITY_TYPE_WAPI: - return "WAPI"; - case WIFI_SECURITY_TYPE_EAP: - return "EAP"; - case WIFI_SECURITY_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mfp_txt(enum wifi_mfp_options mfp) -{ - switch (mfp) { - case WIFI_MFP_DISABLE: - return "Disable"; - case WIFI_MFP_OPTIONAL: - return "Optional"; - case WIFI_MFP_REQUIRED: - return "Required"; - case WIFI_MFP_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_band_txt(enum wifi_frequency_bands band) -{ - switch (band) { - case WIFI_FREQ_BAND_2_4_GHZ: - return "2.4GHz"; - case WIFI_FREQ_BAND_5_GHZ: - return "5GHz"; - case WIFI_FREQ_BAND_6_GHZ: - return "6GHz"; - case WIFI_FREQ_BAND_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_state_txt(enum wifi_iface_state state) -{ - switch (state) { - case WIFI_STATE_DISCONNECTED: - return "DISCONNECTED"; - case WIFI_STATE_INACTIVE: - return "INACTIVE"; - case WIFI_STATE_INTERFACE_DISABLED: - return "INTERFACE_DISABLED"; - case WIFI_STATE_SCANNING: - return "SCANNING"; - case WIFI_STATE_AUTHENTICATING: - return "AUTHENTICATING"; - case WIFI_STATE_ASSOCIATING: - return "ASSOCIATING"; - case WIFI_STATE_ASSOCIATED: - return "ASSOCIATED"; - case WIFI_STATE_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case WIFI_STATE_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case WIFI_STATE_COMPLETED: - return "COMPLETED"; - case WIFI_STATE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_mode_txt(enum wifi_iface_mode mode) -{ - switch (mode) { - case WIFI_MODE_INFRA: - return "STATION"; - case WIFI_MODE_IBSS: - return "ADHOC"; - case WIFI_MODE_AP: - return "ACCESS POINT"; - case WIFI_MODE_P2P_GO: - return "P2P GROUP OWNER"; - case WIFI_MODE_P2P_GROUP_FORMATION: - return "P2P GROUP FORMATION"; - case WIFI_MODE_MESH: - return "MESH"; - case WIFI_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_link_mode_txt(enum wifi_link_mode link_mode) -{ - switch (link_mode) { - case WIFI_0: - return "WIFI 0 (802.11)"; - case WIFI_1: - return "WIFI 1 (802.11b)"; - case WIFI_2: - return "WIFI 2 (802.11a)"; - case WIFI_3: - return "WIFI 3 (802.11g)"; - case WIFI_4: - return "WIFI 4 (802.11n/HT)"; - case WIFI_5: - return "WIFI 5 (802.11ac/VHT)"; - case WIFI_6: - return "WIFI 6 (802.11ax/HE)"; - case WIFI_6E: - return "WIFI 6E (802.11ax 6GHz/HE)"; - case WIFI_7: - return "WIFI 7 (802.11be/EHT)"; - case WIFI_LINK_MODE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_txt(enum wifi_ps ps_name) -{ - switch (ps_name) { - case WIFI_PS_DISABLED: - return "Power save disabled"; - case WIFI_PS_ENABLED: - return "Power save enabled"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_mode_txt(enum wifi_ps_mode ps_mode) -{ - switch (ps_mode) { - case WIFI_PS_MODE_LEGACY: - return "Legacy power save"; - case WIFI_PS_MODE_WMM: - return "WMM power save"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_operation_txt(enum wifi_twt_operation twt_operation) -{ - switch (twt_operation) { - case WIFI_TWT_SETUP: - return "TWT setup"; - case WIFI_TWT_TEARDOWN: - return "TWT teardown"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation) -{ - switch (twt_negotiation) { - case WIFI_TWT_INDIVIDUAL: - return "TWT individual negotiation"; - case WIFI_TWT_BROADCAST: - return "TWT broadcast negotiation"; - case WIFI_TWT_WAKE_TBTT: - return "TWT wake TBTT negotiation"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup) -{ - switch (twt_setup) { - case WIFI_TWT_SETUP_CMD_REQUEST: - return "TWT request"; - case WIFI_TWT_SETUP_CMD_SUGGEST: - return "TWT suggest"; - case WIFI_TWT_SETUP_CMD_DEMAND: - return "TWT demand"; - case WIFI_TWT_SETUP_CMD_GROUPING: - return "TWT grouping"; - case WIFI_TWT_SETUP_CMD_ACCEPT: - return "TWT accept"; - case WIFI_TWT_SETUP_CMD_ALTERNATE: - return "TWT alternate"; - case WIFI_TWT_SETUP_CMD_DICTATE: - return "TWT dictate"; - case WIFI_TWT_SETUP_CMD_REJECT: - return "TWT reject"; - default: - return "UNKNOWN"; - } -} - -const char * const wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode) -{ - switch (ps_wakeup_mode) { - case WIFI_PS_WAKEUP_MODE_DTIM: - return "PS wakeup mode DTIM"; - case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL: - return "PS wakeup mode listen interval"; - default: - return "UNKNOWN"; - } -} - static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) { const struct wifi_scan_result *entry = @@ -475,7 +257,7 @@ static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, print(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", flow_id); print(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", - wifi_twt_negotiation_type_txt(negotiation_type)); + wifi_twt_negotiation_type2str[negotiation_type]); print(context.sh, SHELL_NORMAL, "TWT responder: %s\n", responder ? "true" : "false"); print(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", @@ -504,7 +286,7 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", - wifi_twt_setup_cmd_txt(resp->setup_cmd)); + wifi_twt_setup_cmd2str[resp->setup_cmd]); print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, @@ -954,10 +736,10 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) } shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", - wifi_ps_txt(config.ps_params.enabled)); + wifi_ps2str[config.ps_params.enabled]); if (config.ps_params.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", - wifi_ps_mode_txt(config.ps_params.mode)); + wifi_ps_mode2str[config.ps_params.mode]); } shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", @@ -1012,7 +794,7 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_txt(params.enabled)); + shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps2str[params.enabled]); return 0; } @@ -1037,12 +819,12 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s failed Reason : %s\n", - wifi_ps_mode_txt(params.mode), + wifi_ps_mode2str[params.mode], wifi_ps_get_config_err_code_str(params.fail_reason)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_mode_txt(params.mode)); + shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_mode2str[params.mode]); return 0; } @@ -1121,15 +903,15 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation_txt(params.operation), - wifi_twt_negotiation_type_txt(params.negotiation_type), + wifi_twt_operation2str[params.operation], + wifi_twt_negotiation_type2str[params.negotiation_type], wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", - wifi_twt_operation_txt(params.operation), + wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); return 0; @@ -1208,15 +990,15 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed. reason : %s\n", - wifi_twt_operation_txt(params.operation), - wifi_twt_negotiation_type_txt(params.negotiation_type), + wifi_twt_operation2str[params.operation], + wifi_twt_negotiation_type2str[params.negotiation_type], wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", - wifi_twt_operation_txt(params.operation), + wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); return 0; @@ -1264,15 +1046,15 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation_txt(params.operation), - wifi_twt_negotiation_type_txt(params.negotiation_type), + wifi_twt_operation2str[params.operation], + wifi_twt_negotiation_type2str[params.negotiation_type], wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d success\n", - wifi_twt_operation_txt(params.operation), + wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); return 0; @@ -1291,15 +1073,15 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", - wifi_twt_operation_txt(params.operation), - wifi_twt_negotiation_type_txt(params.negotiation_type), + wifi_twt_operation2str[params.operation], + wifi_twt_negotiation_type2str[params.negotiation_type], wifi_twt_get_err_code_str(params.fail_reason)); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows success\n", - wifi_twt_operation_txt(params.operation)); + wifi_twt_operation2str[params.operation]); return 0; } @@ -1476,7 +1258,7 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar } shell_fprintf(sh, SHELL_NORMAL, "%s\n", - wifi_ps_wakeup_mode_txt(params.wakeup_mode)); + wifi_ps_wakeup_mode2str[params.wakeup_mode]); return 0; } From eaf6208a997b7a0e3c4baac0f2102986259c8633 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:56 +0000 Subject: [PATCH 4381/4498] Revert "[nrf fromtree] mgmt/MCUmgr/grp/img: Add support for three image configuration" This reverts commit 622ccbce57fab78fd9527f0099207f84a2582459. Signed-off-by: Dominik Ermel --- subsys/dfu/Kconfig | 2 +- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 2 +- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 65 ++++++++++--------- .../mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 36 ++-------- 4 files changed, 42 insertions(+), 63 deletions(-) diff --git a/subsys/dfu/Kconfig b/subsys/dfu/Kconfig index 121fa3964f6..f998b2ef9f2 100644 --- a/subsys/dfu/Kconfig +++ b/subsys/dfu/Kconfig @@ -89,7 +89,7 @@ if !MCUBOOT config UPDATEABLE_IMAGE_NUMBER int "Number of updateable images" default 1 - range 1 3 + range 1 2 help If value is set to 2 or greater then, this enables support needed when application is combined with MCUboot multi-image boot. diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 81fc57d9238..641e16bd703 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -46,7 +46,7 @@ endif config MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER int "Number of supported images" default UPDATEABLE_IMAGE_NUMBER - range 1 3 + range 1 2 help Sets how many application images are supported (pairs of secondary and primary slots). Setting this to 2 requires MCUMGR_TRANSPORT_NETBUF_SIZE to be at least 512b. diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 305cad41c44..b2bb39aca86 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -59,38 +59,43 @@ BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); (FIXED_PARTITION_OFFSET(label) == CONFIG_FLASH_LOAD_OFFSET) #endif /* USE_PARTITION_MANAGER */ -BUILD_ASSERT(sizeof(struct image_header) == IMAGE_HEADER_SIZE, - "struct image_header not required size"); - -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 -#if FIXED_PARTITION_EXISTS(slot0_ns_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) -#define ACTIVE_IMAGE_IS 0 -#elif FIXED_PARTITION_EXISTS(slot0_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) -#define ACTIVE_IMAGE_IS 0 -#elif FIXED_PARTITION_EXISTS(slot1_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) -#define ACTIVE_IMAGE_IS 0 -#elif FIXED_PARTITION_EXISTS(slot2_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition) -#define ACTIVE_IMAGE_IS 1 -#elif FIXED_PARTITION_EXISTS(slot3_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot3_partition) -#define ACTIVE_IMAGE_IS 1 -#elif FIXED_PARTITION_EXISTS(slot4_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot4_partition) -#define ACTIVE_IMAGE_IS 2 -#elif FIXED_PARTITION_EXISTS(slot5_partition) && \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot5_partition) -#define ACTIVE_IMAGE_IS 2 -#else -#define ACTIVE_IMAGE_IS 0 +#if FIXED_PARTITION_EXISTS(slot0_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot0_ns_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 #endif -#else -#define ACTIVE_IMAGE_IS 0 #endif +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot1_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot2_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition) +#define NUMBER_OF_ACTIVE_IMAGE 1 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot3_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot3_partition) +#define NUMBER_OF_ACTIVE_IMAGE 1 +#endif +#endif + +#ifndef NUMBER_OF_ACTIVE_IMAGE +#error "Unsupported code parition is set as active application partition" +#endif + +_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, + "struct image_header not required size"); + LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; @@ -172,7 +177,7 @@ int img_mgmt_active_slot(int image) int img_mgmt_active_image(void) { - return ACTIVE_IMAGE_IS; + return NUMBER_OF_ACTIVE_IMAGE; } /* diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index addde1e9a2c..c3641986fd2 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -25,26 +25,12 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); #define SLOT1_PARTITION slot1_partition #define SLOT2_PARTITION slot2_partition #define SLOT3_PARTITION slot3_partition -#define SLOT4_PARTITION slot4_partition -#define SLOT5_PARTITION slot5_partition - -/* SLOT0_PARTITION and SLOT1_PARTITION are not checked because - * there is not conditional code that depends on them. If they do - * not exist compilation will fail, but in case if some of other - * partitions do not exist, code will compile and will not work - * properly. - */ -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 -BUILD_ASSERT(FIXED_PARTITION_EXISTS(SLOT2_PARTITION) && - FIXED_PARTITION_EXISTS(SLOT3_PARTITION), - "Missing partitions?"); -#endif -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 3 -BUILD_ASSERT(FIXED_PARTITION_EXISTS(SLOT4_PARTITION) && - FIXED_PARTITION_EXISTS(SLOT5_PARTITION), +BUILD_ASSERT(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 1 || + (CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 && + FIXED_PARTITION_EXISTS(SLOT2_PARTITION) && + FIXED_PARTITION_EXISTS(SLOT3_PARTITION)), "Missing partitions?"); -#endif /** * Determines if the specified area of flash is completely unwritten. @@ -151,18 +137,6 @@ img_mgmt_flash_area_id(int slot) break; #endif -#if FIXED_PARTITION_EXISTS(SLOT4_PARTITION) - case 4: - fa_id = FIXED_PARTITION_ID(SLOT4_PARTITION); - break; -#endif - -#if FIXED_PARTITION_EXISTS(SLOT5_PARTITION) - case 5: - fa_id = FIXED_PARTITION_ID(SLOT5_PARTITION); - break; -#endif - default: fa_id = -1; break; @@ -220,7 +194,7 @@ static int img_mgmt_get_unused_slot_area_id(int slot) return slot != -1 ? img_mgmt_flash_area_id(slot) : -1; #endif } -#elif CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER >= 2 +#elif CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 static int img_mgmt_get_unused_slot_area_id(int image) { int area_id = -1; From 60cd04569f2473753126f099c6e023417831e1ef Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:56 +0000 Subject: [PATCH 4382/4498] Revert "[nrf fromtree] twister: handle quotes for configuration options" This reverts commit 45e05e2d8f3ffb0b46a0fa055cb5b3ded64e13f7. Signed-off-by: Dominik Ermel --- scripts/pylib/twister/twisterlib/runner.py | 10 ++-------- scripts/tests/twister/test_runner.py | 5 ++--- scripts/west_commands/build.py | 6 +----- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index ef41084cdd4..bbbdb18d05a 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -978,15 +978,9 @@ def report_out(self, results): sys.stdout.flush() @staticmethod - def cmake_assemble_args(extra_args, handler, extra_conf_files, extra_overlay_confs, + def cmake_assemble_args(args, handler, extra_conf_files, extra_overlay_confs, extra_dtc_overlay_files, cmake_extra_args, build_dir): - # Retain quotes around config options - config_options = [arg for arg in extra_args if arg.startswith("CONFIG_")] - args = [arg for arg in extra_args if not arg.startswith("CONFIG_")] - - args_expanded = ["-D{}".format(a.replace('"', '\"')) for a in config_options] - if handler.ready: args.extend(handler.args) @@ -1009,7 +1003,7 @@ def cmake_assemble_args(extra_args, handler, extra_conf_files, extra_overlay_con args.append("OVERLAY_CONFIG=\"%s\"" % (" ".join(overlays))) # Build the final argument list - args_expanded.extend(["-D{}".format(a.replace('"', '\"')) for a in cmake_extra_args]) + args_expanded = ["-D{}".format(a.replace('"', '\"')) for a in cmake_extra_args] args_expanded.extend(["-D{}".format(a.replace('"', '')) for a in args]) return args_expanded diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 37c02b6d17b..7540da04394 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -90,7 +90,7 @@ class MockHandler: handler.ready = True assert(ProjectBuilder.cmake_assemble_args( - ["basearg1", "CONFIG_t=\"test\"", "SNIPPET_t=\"test\""], + ["basearg1"], handler, ["a.conf;b.conf", "c.conf"], ["extra_overlay.conf"], @@ -98,9 +98,8 @@ class MockHandler: ["cmake1=foo", "cmake2=bar"], "/builddir/", ) == [ - "-DCONFIG_t=\"test\"", "-Dcmake1=foo", "-Dcmake2=bar", - "-Dbasearg1", "-DSNIPPET_t=test", + "-Dbasearg1", "-Dhandler_arg1", "-Dhandler_arg2", "-DCONF_FILE=a.conf;b.conf;c.conf", "-DDTC_OVERLAY_FILE=x.overlay;y.overlay;z.overlay", diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index f7a605f4d7f..bcc5106f8ca 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -317,11 +317,7 @@ def _parse_test_item(self, test_item): if data == 'extra_configs': args = ["-D{}".format(arg.replace('"', '\"')) for arg in arg_list] elif data == 'extra_args': - # Retain quotes around config options - config_options = [arg for arg in arg_list if arg.startswith("CONFIG_")] - non_config_options = [arg for arg in arg_list if not arg.startswith("CONFIG_")] - args = ["-D{}".format(a.replace('"', '\"')) for a in config_options] - args.extend(["-D{}".format(arg.replace('"', '')) for arg in non_config_options]) + args = ["-D{}".format(arg.replace('"', '')) for arg in arg_list] elif data == 'extra_conf_files': extra_conf_files.extend(arg_list) continue From bee9b3bbd69b643e2e2c5e86b7a80da52a295365 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:56 +0000 Subject: [PATCH 4383/4498] Revert "[nrf fromtree] twister: Add support for required snippets" This reverts commit 5327c5408115ece4c62baaa0eb9fdd8086f78f1b. Signed-off-by: Dominik Ermel --- .../pylib/twister/twisterlib/config_parser.py | 1 - scripts/pylib/twister/twisterlib/runner.py | 4 -- scripts/pylib/twister/twisterlib/testplan.py | 42 ------------------- scripts/schemas/twister/testsuite-schema.yaml | 10 ----- scripts/snippets.py | 16 ------- scripts/twister | 3 -- scripts/west_commands/build.py | 11 +---- 7 files changed, 1 insertion(+), 86 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index f431e2d57c2..c822e9dfc77 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -48,7 +48,6 @@ class TwisterConfigParser: "extra_conf_files": {"type": "list", "default": []}, "extra_overlay_confs" : {"type": "list", "default": []}, "extra_dtc_overlay_files": {"type": "list", "default": []}, - "required_snippets": {"type": "list"}, "build_only": {"type": "bool", "default": False}, "build_on_all": {"type": "bool", "default": False}, "skip": {"type": "bool", "default": False}, diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index bbbdb18d05a..ad93145db38 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -359,10 +359,6 @@ def run_cmake(self, args="", filter_stages=[]): cmake_opts = ['-DBOARD={}'.format(self.platform.name)] cmake_args.extend(cmake_opts) - if self.instance.testsuite.required_snippets: - cmake_opts = ['-DSNIPPET={}'.format(';'.join(self.instance.testsuite.required_snippets))] - cmake_args.extend(cmake_opts) - cmake = shutil.which('cmake') cmd = [cmake] + cmake_args diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 1d9c625b28a..85340885dbb 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -16,8 +16,6 @@ import copy import shutil import random -import snippets -from pathlib import Path logger = logging.getLogger('twister') logger.setLevel(logging.DEBUG) @@ -821,46 +819,6 @@ def apply_filters(self, **kwargs): if plat.only_tags and not set(plat.only_tags) & ts.tags: instance.add_filter("Excluded tags per platform (only_tags)", Filters.PLATFORM) - if ts.required_snippets: - missing_snippet = False - snippet_args = {"snippets": ts.required_snippets} - found_snippets = snippets.find_snippets_in_roots(snippet_args, [Path(ZEPHYR_BASE), Path(ts.source_dir)]) - - # Search and check that all required snippet files are found - for this_snippet in snippet_args['snippets']: - if this_snippet not in found_snippets: - logger.error(f"Can't find snippet '%s' for test '%s'", this_snippet, ts.name) - instance.status = "error" - instance.reason = f"Snippet {this_snippet} not found" - missing_snippet = True - break - - if not missing_snippet: - # Look for required snippets and check that they are applicable for these - # platforms/boards - for this_snippet in found_snippets: - matched_snippet_board = False - - # If the "appends" key is present with at least one entry then this - # snippet applies to all boards and further platform-specific checks - # are not required - if found_snippets[this_snippet].appends: - continue - - for this_board in found_snippets[this_snippet].board2appends: - if this_board.startswith('/'): - match = re.search(this_board[1:-1], plat.name) - if match is not None: - matched_snippet_board = True - break - elif this_board == plat.name: - matched_snippet_board = True - break - - if matched_snippet_board is False: - instance.add_filter("Snippet not supported", Filters.PLATFORM) - break - # platform_key is a list of unique platform attributes that form a unique key a test # will match against to determine if it should be scheduled to run. A key containing a # field name that the platform does not have will filter the platform. diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 116c1a43379..4d67fe71706 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -145,11 +145,6 @@ mapping: matching: "all" sequence: - type: str - "required_snippets": - type: seq - required: false - sequence: - - type: str "tags": type: any required: false @@ -248,11 +243,6 @@ mapping: "extra_sections": type: any required: false - "required_snippets": - type: seq - required: false - sequence: - - type: str "filter": type: str required: false diff --git a/scripts/snippets.py b/scripts/snippets.py index 78ab896e85b..9662f3edcec 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -238,22 +238,6 @@ def process_snippets(args: argparse.Namespace) -> Snippets: return snippets -def find_snippets_in_roots(requested_snippets, snippet_roots) -> Snippets: - '''Process snippet.yml files under each *snippet_root* - by recursive search. Return a Snippets object describing - the results of the search. - ''' - # This will contain information about all the snippets - # we discover in each snippet_root element. - snippets = Snippets(requested=requested_snippets) - - # Process each path in snippet_root in order, adjusting - # snippets as needed for each one. - for root in snippet_roots: - process_snippets_in(root, snippets) - - return snippets - def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: '''Process snippet.yml files in *root_dir*, updating *snippets* as needed.''' diff --git a/scripts/twister b/scripts/twister index f41349871ed..0f5e622011f 100755 --- a/scripts/twister +++ b/scripts/twister @@ -44,9 +44,6 @@ pairs: Extra configuration options to be merged with a master prj.conf when building or running the test case. - required_snippets: - Snippets that must be applied for the test case to run. - sysbuild: (default False) If true, build the sample using the sysbuild infrastructure. Filtering will only be enabled for the main project, and is not supported for diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index bcc5106f8ca..65dbe963cd4 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -293,7 +293,6 @@ def _parse_test_item(self, test_item): extra_dtc_overlay_files = [] extra_overlay_confs = [] extra_conf_files = [] - required_snippets = [] for section in [common, item]: if not section: continue @@ -303,8 +302,7 @@ def _parse_test_item(self, test_item): 'extra_configs', 'extra_conf_files', 'extra_overlay_confs', - 'extra_dtc_overlay_files', - 'required_snippets' + 'extra_dtc_overlay_files' ]: extra = section.get(data) if not extra: @@ -327,9 +325,6 @@ def _parse_test_item(self, test_item): elif data == 'extra_dtc_overlay_files': extra_dtc_overlay_files.extend(arg_list) continue - elif data == 'required_snippets': - required_snippets.extend(arg_list) - continue if self.args.cmake_opts: self.args.cmake_opts.extend(args) @@ -348,10 +343,6 @@ def _parse_test_item(self, test_item): if extra_overlay_confs: args.append(f"OVERLAY_CONFIG=\"{';'.join(extra_overlay_confs)}\"") - - if required_snippets: - args.append(f"SNIPPET=\"{';'.join(required_snippets)}\"") - # Build the final argument list args_expanded = ["-D{}".format(a.replace('"', '')) for a in args] From 14770de0a7dd8bfa7d89ea43de4ed562cc8f4033 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:57 +0000 Subject: [PATCH 4384/4498] Revert "[nrf fromtree] net: socketpair: Fix use after free" This reverts commit 4ea2d10cee590392888695101091446a4c4605d5. Signed-off-by: Dominik Ermel --- subsys/net/lib/sockets/socketpair.c | 8 ++++---- tests/net/socket/socketpair/testcase.yaml | 8 -------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index 9207f4b659e..f3bbb46f6c8 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -191,10 +191,6 @@ static void spair_delete(struct spair *spair) res = k_poll_signal_raise(&spair->writeable, SPAIR_SIG_CANCEL); __ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res); - if (remote != NULL && have_remote_sem) { - k_sem_give(&remote->sem); - } - /* ensure no private information is released to the memory pool */ memset(spair, 0, sizeof(*spair)); #ifdef CONFIG_NET_SOCKETPAIR_STATIC @@ -204,6 +200,10 @@ static void spair_delete(struct spair *spair) #else k_free(spair); #endif + + if (remote != NULL && have_remote_sem) { + k_sem_give(&remote->sem); + } } /** diff --git a/tests/net/socket/socketpair/testcase.yaml b/tests/net/socket/socketpair/testcase.yaml index d2b4462ce2d..e771e7c61d4 100644 --- a/tests/net/socket/socketpair/testcase.yaml +++ b/tests/net/socket/socketpair/testcase.yaml @@ -18,11 +18,3 @@ tests: extra_configs: - CONFIG_PICOLIBC=y platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 - net.socket.socketpair.high_mem: - min_ram: 64 - extra_configs: - # Low buffer sizes (e.g., 8192) will verify the crash fix, but tests will still - # fail due to insufficient memory. So, use high buffer sizes. - - CONFIG_NET_SOCKETPAIR_BUFFER_SIZE=4096 - - CONFIG_HEAP_MEM_POOL_SIZE=32768 - platform_exclude: vmu_rt1170 mimxrt1160_evk_cm7 # See #61246 From 4c5e075124f8cad7c399f8341b2afa6160452fa7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:57 +0000 Subject: [PATCH 4385/4498] Revert "[nrf fromtree] net: l2: wifi: Add support for W-Fi mode setting and selection" This reverts commit 0feef90eb0216678f3cfe10bbeae034d79ad9840. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi.h | 33 --- include/zephyr/net/wifi_mgmt.h | 76 ------- subsys/net/l2/wifi/wifi_mgmt.c | 60 ----- subsys/net/l2/wifi/wifi_shell.c | 388 +------------------------------- 4 files changed, 1 insertion(+), 556 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 55bd8d71a3a..aa3096fc5ac 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -148,7 +148,6 @@ static inline const char *wifi_band_txt(enum wifi_frequency_bands band) #define WIFI_SAE_PSWD_MAX_LEN 128 #define WIFI_MAC_ADDR_LEN 6 -#define WIFI_CHANNEL_MIN 1 #define WIFI_CHANNEL_MAX 233 #define WIFI_CHANNEL_ANY 255 @@ -356,38 +355,6 @@ static const char * const wifi_ps_mode2str[] = { }; /** @endcond */ -/* Interface index Min and Max values */ -#define WIFI_INTERFACE_INDEX_MIN 1 -#define WIFI_INTERFACE_INDEX_MAX 255 - -/** Wifi operational mode */ -enum wifi_operational_modes { - /** STA mode setting enable */ - WIFI_STA_MODE = BIT(0), - /** Monitor mode setting enable */ - WIFI_MONITOR_MODE = BIT(1), - /** TX injection mode setting enable */ - WIFI_TX_INJECTION_MODE = BIT(2), - /** Promiscuous mode setting enable */ - WIFI_PROMISCUOUS_MODE = BIT(3), - /** AP mode setting enable */ - WIFI_AP_MODE = BIT(4), - /** Softap mode setting enable */ - WIFI_SOFTAP_MODE = BIT(5), -}; - -/** Mode filter settings */ -enum wifi_filter { - /** Support management, data and control packet sniffing */ - WIFI_PACKET_FILTER_ALL = BIT(0), - /** Support only sniffing of management packets */ - WIFI_PACKET_FILTER_MGMT = BIT(1), - /** Support only sniffing of data packets */ - WIFI_PACKET_FILTER_DATA = BIT(2), - /** Support only sniffing of control packets */ - WIFI_PACKET_FILTER_CTRL = BIT(3), -}; - /** Wi-Fi Target Wake Time (TWT) operations. */ enum wifi_twt_operation { /** TWT setup operation */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 1be98b927cb..7a572eb673d 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -69,12 +69,6 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_REG_DOMAIN, /** Set power save timeout */ NET_REQUEST_WIFI_CMD_PS_TIMEOUT, - /** Set or get Mode of operation */ - NET_REQUEST_WIFI_CMD_MODE, - /** Set or get packet filter setting for current mode */ - NET_REQUEST_WIFI_CMD_PACKET_FILTER, - /** Set or get Wi-Fi channel for Monitor or TX-Injection mode */ - NET_REQUEST_WIFI_CMD_CHANNEL, NET_REQUEST_WIFI_CMD_MAX }; @@ -137,21 +131,6 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT); -#define NET_REQUEST_WIFI_MODE \ - (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_MODE) - -NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE); - -#define NET_REQUEST_WIFI_PACKET_FILTER \ - (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PACKET_FILTER) - -NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER); - -#define NET_REQUEST_WIFI_CHANNEL \ - (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_CHANNEL) - -NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL); - /** Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -530,37 +509,6 @@ union wifi_mgmt_events { struct wifi_twt_params twt_params; }; -/** Wi-Fi mode setup */ -struct wifi_mode_info { - /** Mode setting for a specific mode of operation */ - uint8_t mode; - /** Interface index */ - uint8_t if_index; - /** Get or set operation */ - enum wifi_mgmt_op oper; -}; - -/** Wi-Fi filter setting for monitor, prmoiscuous, TX-injection modes */ -struct wifi_filter_info { - /** Filter setting */ - uint8_t filter; - /** Interface index */ - uint8_t if_index; - /** Filter buffer size */ - uint16_t buffer_size; - /** Get or set operation */ - enum wifi_mgmt_op oper; -}; - -/** Wi-Fi channel setting for monitor and TX-injection modes */ -struct wifi_channel_info { - /** Channel value to set */ - uint16_t channel; - /** Interface index */ - uint8_t if_index; - /** Get or set operation */ - enum wifi_mgmt_op oper; -}; #include @@ -682,30 +630,6 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); - /** Set or get packet filter settings for monitor and promiscuous modes - * - * @param dev Pointer to the device structure for the driver instance. - * @param packet filter settings - * - * @return 0 if ok, < 0 if error - */ - int (*filter)(const struct device *dev, struct wifi_filter_info *filter); - /** Set or get mode of operation - * - * @param dev Pointer to the device structure for the driver instance. - * @param mode settings - * - * @return 0 if ok, < 0 if error - */ - int (*mode)(const struct device *dev, struct wifi_mode_info *mode); - /** Set or get current channel of operation - * - * @param dev Pointer to the device structure for the driver instance. - * @param channel settings - * - * @return 0 if ok, < 0 if error - */ - int (*channel)(const struct device *dev, struct wifi_channel_info *channel); }; /** Wi-Fi management offload API */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index dba18f8154f..80f01b14e42 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -447,66 +447,6 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, sizeof(twt_sleep_state)); } -static int wifi_mode(uint32_t mgmt_request, struct net_if *iface, - void *data, size_t len) -{ - const struct device *dev = net_if_get_device(iface); - const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); - struct wifi_mode_info *mode_info = data; - - if (dev == NULL) { - return -ENODEV; - } - - if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) { - return -ENOTSUP; - } - - return wifi_mgmt_api->mode(dev, mode_info); -} - -NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode); - -static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface, - void *data, size_t len) -{ - const struct device *dev = net_if_get_device(iface); - const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); - struct wifi_filter_info *filter_info = data; - - if (dev == NULL) { - return -ENODEV; - } - - if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) { - return -ENOTSUP; - } - - return wifi_mgmt_api->filter(dev, filter_info); -} - -NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter); - -static int wifi_channel(uint32_t mgmt_request, struct net_if *iface, - void *data, size_t len) -{ - const struct device *dev = net_if_get_device(iface); - const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); - struct wifi_channel_info *channel_info = data; - - if (dev == NULL) { - return -ENODEV; - } - - if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) { - return -ENOTSUP; - } - - return wifi_mgmt_api->channel(dev, channel_info); -} - -NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel); - #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_result) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 236fb32ee83..34dab2f9460 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -75,20 +75,12 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi { char *endptr; char *str_tmp = str; - long num = 0; - - if ((str_tmp[0] == '0') && (str_tmp[1] == 'x')) { - /* Hexadecimal numbers take base 0 in strtol */ - num = strtol(str_tmp, &endptr, 0); - } else { - num = strtol(str_tmp, &endptr, 10); - } + long num = strtol(str_tmp, &endptr, 10); if (*endptr != '\0') { print(sh, SHELL_ERROR, "Invalid number: %s", str_tmp); return false; } - if ((num) < (min) || (num) > (max)) { print(sh, SHELL_WARNING, "Value out of range: %s, (%ld-%ld)", str_tmp, min, max); return false; @@ -1263,335 +1255,6 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar return 0; } -void parse_mode_args_to_params(const struct shell *sh, int argc, - char *argv[], struct wifi_mode_info *mode, - bool *do_mode_oper) -{ - int opt; - int option_index = 0; - - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, - {"sta", no_argument, 0, 's'}, - {"monitor", no_argument, 0, 'm'}, - {"TX-injection", no_argument, 0, 't'}, - {"promiscuous", no_argument, 0, 'p'}, - {"ap", no_argument, 0, 'a'}, - {"softap", no_argument, 0, 'k'}, - {"get", no_argument, 0, 'g'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0}}; - - while ((opt = getopt_long(argc, argv, "i:smtpakgh", long_options, &option_index)) != -1) { - switch (opt) { - case 's': - mode->mode |= WIFI_STA_MODE; - break; - case 'm': - mode->mode |= WIFI_MONITOR_MODE; - break; - case 't': - mode->mode |= WIFI_TX_INJECTION_MODE; - break; - case 'p': - mode->mode |= WIFI_PROMISCUOUS_MODE; - break; - case 'a': - mode->mode |= WIFI_AP_MODE; - break; - case 'k': - mode->mode |= WIFI_SOFTAP_MODE; - break; - case 'g': - mode->oper = true; - break; - case 'i': - mode->if_index = (uint8_t)atoi(optarg); - break; - case 'h': - shell_help(sh); - *do_mode_oper = false; - break; - case '?': - default: - break; - } - } -} - -static int cmd_wifi_mode(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface; - struct wifi_mode_info mode_info = {0}; - int ret; - bool do_mode_oper = true; - - if (argc > 1) { - mode_info.oper = WIFI_MGMT_SET; - parse_mode_args_to_params(sh, argc, argv, &mode_info, &do_mode_oper); - } else { - shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); - return -EINVAL; - } - - if (do_mode_oper) { - /* Check interface index value. Mode validation must be performed by - * lower layer - */ - if (mode_info.if_index == 0) { - iface = net_if_get_first_wifi(); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find the default wifi interface\n"); - return -ENOEXEC; - } - mode_info.if_index = net_if_get_by_iface(iface); - } else { - iface = net_if_get_by_index(mode_info.if_index); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find interface for if_index %d\n", - mode_info.if_index); - return -ENOEXEC; - } - } - - ret = net_mgmt(NET_REQUEST_WIFI_MODE, iface, &mode_info, sizeof(mode_info)); - - if (ret) { - shell_fprintf(sh, SHELL_ERROR, "mode %s operation failed with reason %d\n", - mode_info.oper == WIFI_MGMT_GET ? "get" : "set", ret); - return -ENOEXEC; - } - - if (mode_info.oper == WIFI_MGMT_GET) { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current mode is %x\n", - mode_info.mode); - } else { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi mode set to %x\n", mode_info.mode); - } - } - return 0; -} - -void parse_channel_args_to_params(const struct shell *sh, int argc, - char *argv[], struct wifi_channel_info *channel, - bool *do_channel_oper) -{ - int opt; - int option_index = 0; - - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, - {"channel", required_argument, 0, 'c'}, - {"get", no_argument, 0, 'g'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0}}; - - while ((opt = getopt_long(argc, argv, "i:c:gh", long_options, &option_index)) != -1) { - switch (opt) { - case 'c': - channel->channel = (uint16_t)atoi(optarg); - break; - case 'i': - channel->if_index = (uint8_t)atoi(optarg); - break; - case 'g': - channel->oper = WIFI_MGMT_GET; - break; - case 'h': - shell_help(sh); - *do_channel_oper = false; - break; - case '?': - default: - break; - } - } -} - -static int cmd_wifi_channel(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface; - struct wifi_channel_info channel_info = {0}; - int ret; - bool do_channel_oper = true; - - if (argc > 1) { - channel_info.oper = WIFI_MGMT_SET; - parse_channel_args_to_params(sh, argc, argv, &channel_info, &do_channel_oper); - } else { - shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); - return -EINVAL; - } - - if (do_channel_oper) { - /* - * Validate parameters before sending to lower layer. - * Do it here instead of parse_channel_args_to_params - * as this is right before sending the parameters to - * the lower layer. - */ - - if (channel_info.if_index == 0) { - iface = net_if_get_first_wifi(); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find the default wifi interface\n"); - return -ENOEXEC; - } - channel_info.if_index = net_if_get_by_iface(iface); - } else { - iface = net_if_get_by_index(channel_info.if_index); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find interface for if_index %d\n", - channel_info.if_index); - return -ENOEXEC; - } - } - - if (channel_info.oper == WIFI_MGMT_SET) { - if ((channel_info.channel < WIFI_CHANNEL_MIN) || - (channel_info.channel > WIFI_CHANNEL_MAX)) { - shell_fprintf(sh, SHELL_ERROR, - "Invalid channel number. Range is (1-233)\n"); - return -ENOEXEC; - } - } - - ret = net_mgmt(NET_REQUEST_WIFI_CHANNEL, iface, - &channel_info, sizeof(channel_info)); - - if (ret) { - shell_fprintf(sh, SHELL_ERROR, - "channel %s operation failed with reason %d\n", - channel_info.oper == WIFI_MGMT_GET ? "get" : "set", ret); - return -ENOEXEC; - } - - if (channel_info.oper == WIFI_MGMT_GET) { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current channel is: %d\n", - channel_info.channel); - } else { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi channel set to %d\n", - channel_info.channel); - } - } - return 0; -} - -void parse_filter_args_to_params(const struct shell *sh, int argc, - char *argv[], struct wifi_filter_info *filter, - bool *do_filter_oper) -{ - int opt; - int option_index = 0; - - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, - {"capture_len", optional_argument, 0, 'b'}, - {"all", no_argument, 0, 'a'}, - {"mgmt", no_argument, 0, 'm'}, - {"ctrl", no_argument, 0, 'c'}, - {"data", no_argument, 0, 'd'}, - {"get", no_argument, 0, 'g'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0}}; - - while ((opt = getopt_long(argc, argv, "i:b:amcdgh", long_options, &option_index)) != -1) { - switch (opt) { - case 'a': - filter->filter |= WIFI_PACKET_FILTER_ALL; - break; - case 'm': - filter->filter |= WIFI_PACKET_FILTER_MGMT; - break; - case 'c': - filter->filter |= WIFI_PACKET_FILTER_DATA; - break; - case 'd': - filter->filter |= WIFI_PACKET_FILTER_CTRL; - break; - case 'i': - filter->if_index = (uint8_t)atoi(optarg); - break; - case 'b': - filter->buffer_size = (uint16_t)atoi(optarg); - break; - case 'h': - shell_help(sh); - *do_filter_oper = false; - break; - case 'g': - filter->oper = WIFI_MGMT_GET; - break; - case '?': - default: - break; - } - } -} - -static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface; - struct wifi_filter_info packet_filter = {0}; - int ret; - bool do_filter_oper = true; - - if (argc > 1) { - packet_filter.oper = WIFI_MGMT_SET; - parse_filter_args_to_params(sh, argc, argv, &packet_filter, &do_filter_oper); - } else { - shell_fprintf(sh, SHELL_ERROR, "Invalid number of arguments\n"); - return -EINVAL; - } - - if (do_filter_oper) { - /* - * Validate parameters before sending to lower layer. - * Do it here instead of parse_filter_args_to_params - * as this is right before sending the parameters to - * the lower layer. filter and packet capture length - * value to be verified by the lower layer. - */ - if (packet_filter.if_index == 0) { - iface = net_if_get_first_wifi(); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find the default wifi interface\n"); - return -ENOEXEC; - } - packet_filter.if_index = net_if_get_by_iface(iface); - } else { - iface = net_if_get_by_index(packet_filter.if_index); - if (iface == NULL) { - shell_fprintf(sh, SHELL_ERROR, - "Cannot find interface for if_index %d\n", - packet_filter.if_index); - return -ENOEXEC; - } - } - - ret = net_mgmt(NET_REQUEST_WIFI_PACKET_FILTER, iface, - &packet_filter, sizeof(packet_filter)); - - if (ret) { - shell_fprintf(sh, SHELL_ERROR, - "Wi-Fi packet filter %s operation failed with reason %d\n", - packet_filter.oper == WIFI_MGMT_GET ? "get" : "set", ret); - return -ENOEXEC; - } - - if (packet_filter.oper == WIFI_MGMT_GET) { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi current mode packet filter is %d\n", - packet_filter.filter); - } else { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi mode packet filter set to %d\n", - packet_filter.filter); - } - } - return 0; -} - SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, "Disable Access Point mode", @@ -1665,55 +1328,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "-f: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), - SHELL_CMD(mode, NULL, "mode operational setting\n" - "This command may be used to set the Wi-Fi device into a specific mode of operation\n" - "parameters:" - "[-i : Interface index - optional argument\n" - "[-s : Station mode.\n" - "[-m : Monitor mode.\n" - "[-p : Promiscuous mode.\n" - "[-t : TX-Injection mode.\n" - "[-a : AP mode.\n" - "[-k : Softap mode.\n" - "[-h : Help.\n" - "[-g : Get current mode for a specific interface index.\n" - "Usage: Get operation example for interface index 1\n" - "wifi mode -g -i1\n" - "Set operation example for interface index 1 - set station+promiscuous\n" - "wifi mode -i1 -sp\n", - cmd_wifi_mode), - SHELL_CMD(packet_filter, NULL, "mode filter setting\n" - "This command is used to set packet filter setting when\n" - "monitor, TX-Injection and promiscuous mode is enabled.\n" - "The different packet filter modes are control, management, data and enable all filters\n" - "parameters:" - "[-i : Interface index - optional argument.\n" - "[-a : Enable all packet filter modes\n" - "[-m : Enable management packets to allowed up the stack.\n" - "[-c : Enable control packets to be allowed up the stack.\n" - "[-d : Enable Data packets to be allowed up the stack.\n" - "[-g : Get current filter settings for a specific interface index.\n" - "<-b : Capture length buffer size for each packet to be captured - optional argument.\n" - "<-h : Help.\n" - "Usage: Get operation example for interface index 1\n" - "wifi packet_filter -g -i1\n" - "Set operation example for interface index 1 - set data+management frame filter\n" - "wifi packet_filter -i1 -md\n", - cmd_wifi_packet_filter), - SHELL_CMD(channel, NULL, "wifi channel setting\n" - "This command is used to set the channel when\n" - "monitor or TX-Injection mode is enabled.\n" - "Currently 20 MHz is only supported and no BW parameter is provided\n" - "parameters:" - "[-i : Interface index - optional argument.\n" - "[-c : Set a specific channel number to the lower layer.\n" - "[-g : Get current set channel number from the lower layer.\n" - "[-h : Help.\n" - "Usage: Get operation example for interface index 1\n" - "wifi channel -g -i1\n" - "Set operation example for interface index 1 (setting channel 5)\n" - "wifi -i1 -c5\n", - cmd_wifi_channel), SHELL_CMD_ARG(ps_timeout, NULL, " - PS inactivity timer(in ms)", From dc6cb1e3f7304c3dc0452d29ad79c4a2bb0e8ef0 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:57 +0000 Subject: [PATCH 4386/4498] Revert "[nrf fromtree] net: wifi: Fix crash in wifi_utils_parse_scan_ssids" This reverts commit e4ee01d63ffcf8405d868827ea7e1916b883c760. Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/Kconfig | 1 - subsys/net/l2/wifi/wifi_utils.c | 17 +---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 6623456d84b..e034a745b5e 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -76,7 +76,6 @@ config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE config WIFI_MGMT_SCAN_SSID_FILT_MAX int "Maximum number of SSIDs that can be specified for SSID filtering" default 1 - range 1 4 help Maximum number of SSIDs that can be specified for SSID filtering. This can be set based on the underlying chipsets limitations. diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index ea0e42def47..6151f480d21 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -259,30 +259,15 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) int wifi_utils_parse_scan_ssids(char *scan_ssids_str, char ssids[][WIFI_SSID_MAX_LEN + 1]) { - char parse_str[(WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1)) + 1]; char *ssid = NULL; char *ctx = NULL; uint8_t i = 0; - int len; if (!scan_ssids_str) { return -EINVAL; } - len = strlen(scan_ssids_str); - - if (len > (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))) { - NET_ERR("SSID string (%s) size (%d) exceeds maximum allowed value (%d)", - scan_ssids_str, - len, - (WIFI_MGMT_SCAN_SSID_FILT_MAX * (WIFI_SSID_MAX_LEN + 1))); - return -EINVAL; - } - - strncpy(parse_str, scan_ssids_str, len); - parse_str[len] = '\0'; - - ssid = strtok_r(parse_str, ",", &ctx); + ssid = strtok_r(scan_ssids_str, ",", &ctx); while (ssid) { if (strlen(ssid) > WIFI_SSID_MAX_LEN) { From 697c641b99f778e516ec35b5ef4a7621cdfbe723 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:57 +0000 Subject: [PATCH 4387/4498] Revert "[nrf fromtree] net: wifi: Fix crash in wifi_utils_parse_scan_bands" This reverts commit 09864f357bd2a56dc37c693b7bfe8e47df788e1f. Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 2 -- subsys/net/l2/wifi/wifi_utils.c | 17 +---------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 7a572eb673d..57077a1c2f5 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -41,8 +41,6 @@ extern "C" { #define WIFI_MGMT_SCAN_SSID_FILT_MAX 0 #endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ -#define WIFI_MGMT_BAND_STR_SIZE_MAX 8 - /** Wi-Fi management commands */ enum net_request_wifi_cmd { /** Scan for Wi-Fi networks */ diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 6151f480d21..f7e9d9af4dc 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -215,30 +215,15 @@ static int wifi_utils_validate_chan_str(char *chan_str) int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) { - char parse_str[WIFI_MGMT_BAND_STR_SIZE_MAX + 1]; char *band_str = NULL; char *ctx = NULL; enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN; - int len; if (!scan_bands_str) { return -EINVAL; } - len = strlen(scan_bands_str); - - if (len > WIFI_MGMT_BAND_STR_SIZE_MAX) { - NET_ERR("Band string (%s) size (%d) exceeds maximum allowed value (%d)", - scan_bands_str, - len, - WIFI_MGMT_BAND_STR_SIZE_MAX); - return -EINVAL; - } - - strncpy(parse_str, scan_bands_str, len); - parse_str[len] = '\0'; - - band_str = strtok_r(parse_str, ",", &ctx); + band_str = strtok_r(scan_bands_str, ",", &ctx); while (band_str) { band = wifi_utils_map_band_str_to_idx(band_str); From ace40a3687ca2676ef5df149a5fef70267f4812f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:58 +0000 Subject: [PATCH 4388/4498] Revert "[nrf fromlist] cmake: Zephyr kernel version.h and app_version.h creation" This reverts commit be7e604c73b30a27bb9ff61353e2c833bb982f25. Signed-off-by: Dominik Ermel --- CMakeLists.txt | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e23650f262f..64e4fda5c2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -551,9 +551,31 @@ if(ZEPHYR_GIT_INDEX) set(git_dependency ${ZEPHYR_GIT_INDEX}) endif() +add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/include/generated/version.h + COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} + -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/version.h + -DVERSION_TYPE=KERNEL + -DVERSION_FILE=${ZEPHYR_BASE}/VERSION + -DKERNEL_VERSION_CUSTOMIZATION="${KERNEL_VERSION_CUSTOMIZATION}" + ${build_version_argument} + -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake + DEPENDS ${ZEPHYR_BASE}/VERSION ${git_dependency} +) add_custom_target(version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/version.h) if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION) + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/include/generated/app_version.h + COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} + -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/app_version.h + -DVERSION_TYPE=APP + -DVERSION_FILE=${APPLICATION_SOURCE_DIR}/VERSION + -DAPP_VERSION_CUSTOMIZATION="${APP_VERSION_CUSTOMIZATION}" + ${build_version_argument} + -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake + DEPENDS ${APPLICATION_SOURCE_DIR}/VERSION ${git_dependency} + ) add_custom_target(app_version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/app_version.h) add_dependencies(zephyr_interface app_version_h) endif() @@ -604,32 +626,6 @@ endforeach() set(ZEPHYR_CURRENT_MODULE_DIR) set(ZEPHYR_CURRENT_CMAKE_DIR) -add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/include/generated/version.h - COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} - -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/version.h - -DVERSION_TYPE=KERNEL - -DVERSION_FILE=${ZEPHYR_BASE}/VERSION - -DKERNEL_VERSION_CUSTOMIZATION="${KERNEL_VERSION_CUSTOMIZATION}" - ${build_version_argument} - -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake - DEPENDS ${ZEPHYR_BASE}/VERSION ${git_dependency} -) - -if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION) - add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/include/generated/app_version.h - COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} - -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/app_version.h - -DVERSION_TYPE=APP - -DVERSION_FILE=${APPLICATION_SOURCE_DIR}/VERSION - -DAPP_VERSION_CUSTOMIZATION="${APP_VERSION_CUSTOMIZATION}" - ${build_version_argument} - -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake - DEPENDS ${APPLICATION_SOURCE_DIR}/VERSION ${git_dependency} - ) -endif() - get_property(LIBC_LINK_LIBRARIES TARGET zephyr_interface PROPERTY LIBC_LINK_LIBRARIES) zephyr_link_libraries(${LIBC_LINK_LIBRARIES}) From 13a0477d6b3f5319b6c0579567f93873618a5831 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:59 +0000 Subject: [PATCH 4389/4498] Revert "[nrf noup] ci: doc-build: use ubuntu-22.04 runner" This reverts commit 1479b0fc10df3b7542bb56c8b760287eb58ed3f2. Signed-off-by: Dominik Ermel --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index a18507e028d..40e170ddc8a 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -35,7 +35,7 @@ env: jobs: doc-build-html: name: "Documentation Build (HTML)" - runs-on: ubuntu-22.04 + runs-on: zephyr-runner-linux-x64-4xlarge timeout-minutes: 45 concurrency: group: doc-build-html-${{ github.ref }} From b0b14087bda15d17ba548f11572d1fdab18c93c2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:30:59 +0000 Subject: [PATCH 4390/4498] Revert "[nrf noup] tree-wide: support NCS Partition Manager (PM) definitions" This reverts commit d1fa3da6c37763e1ae9306c43bfaf5cf965af594. Signed-off-by: Dominik Ermel --- cmake/modules/kernel.cmake | 4 -- drivers/flash/soc_flash_nrf.c | 11 ----- .../arm/aarch32/cortex_m/scripts/linker.ld | 46 ------------------- include/zephyr/storage/flash_map.h | 6 --- lib/libc/common/source/stdlib/malloc.c | 18 +------- lib/os/Kconfig.heap | 2 +- soc/arm/common/cortex_m/arm_mpu_regions.c | 13 ------ subsys/fs/littlefs_fs.c | 7 +-- subsys/ipc/rpmsg_service/rpmsg_backend.h | 27 ----------- 9 files changed, 4 insertions(+), 130 deletions(-) diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 28ee922d40b..7e65c9cd186 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -242,7 +242,3 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() - -if(ZEPHYR_NRF_MODULE_DIR) - include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) -endif() diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index f38492a41d1..fa433d1044b 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,11 +37,6 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) -#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER -#include -#include -#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ - #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -142,12 +137,6 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return 0; } -#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS - if (addr < PM_APP_ADDRESS) { - return soc_secure_mem_read(data, (void *)addr, len); - } -#endif - nrf_nvmc_buffer_read(data, (uint32_t)addr, len); return 0; diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld index 85d55b2de29..92b6f02d029 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -26,35 +26,6 @@ #endif #define RAMABLE_REGION RAM -#if USE_PARTITION_MANAGER - -#include - -#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) -/* We are linking against S1, create symbol containing the flash ID of S0. - * This is used when writing code operating on the "other" slot. - */ -_image_1_primary_slot_id = PM_S0_ID; - -#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ - -#ifdef PM_S1_ID -/* We are linking against S0, create symbol containing the flash ID of S1. - * This is used when writing code operating on the "other" slot. - */ -_image_1_primary_slot_id = PM_S1_ID; -#endif /* PM_S1_ID */ - -#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ - -#define ROM_ADDR PM_ADDRESS -#define ROM_SIZE PM_SIZE - -#define RAM_SIZE PM_SRAM_SIZE -#define RAM_ADDR PM_SRAM_ADDRESS - -#else /* ! USE_PARTITION_MANAGER */ - #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -81,23 +52,6 @@ _image_1_primary_slot_id = PM_S1_ID; #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif -#endif /* USE_PARTITION_MANAGER */ - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) -#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) -#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) -#endif - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) -#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) -#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) -#endif - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) -#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) -#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) -#endif - #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index cc4a246105d..380e58691e9 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -271,10 +271,6 @@ const char *flash_area_label(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); -#if USE_PARTITION_MANAGER -#include -#else - #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -347,8 +343,6 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) -#endif /* USE_PARTITION_MANAGER */ - #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 47583982838..50c688fa7f2 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -23,20 +23,6 @@ #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -#if USE_PARTITION_MANAGER - -#include - -#define RAM_SIZE PM_SRAM_SIZE -#define RAM_ADDR PM_SRAM_ADDRESS - -#else /* ! USE_PARTITION_MANAGER */ - -#define RAM_SIZE (KB((size_t) CONFIG_SRAM_SIZE)) -#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS - -#endif /* USE_PARTITION_MANAGER */ - #ifdef CONFIG_COMMON_LIBC_MALLOC #if (CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE != 0) @@ -118,8 +104,8 @@ static POOL_SECTION unsigned char __aligned(HEAP_ALIGN) malloc_arena[HEAP_SIZE]; extern char _heap_sentry[]; # define HEAP_SIZE ROUND_DOWN((POINTER_TO_UINT(_heap_sentry) - HEAP_BASE), HEAP_ALIGN) # else -# define HEAP_SIZE ROUND_DOWN((RAM_SIZE - \ - ((size_t) HEAP_BASE - (size_t) RAM_ADDR)), HEAP_ALIGN) +# define HEAP_SIZE ROUND_DOWN((KB((size_t) CONFIG_SRAM_SIZE) - \ + ((size_t) HEAP_BASE - (size_t) CONFIG_SRAM_BASE_ADDRESS)), HEAP_ALIGN) # endif /* else CONFIG_XTENSA */ # endif /* else CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE > 0 */ diff --git a/lib/os/Kconfig.heap b/lib/os/Kconfig.heap index 1fa84ff41db..14fba87470b 100644 --- a/lib/os/Kconfig.heap +++ b/lib/os/Kconfig.heap @@ -51,7 +51,7 @@ config HEAP_LISTENER choice prompt "Supported heap sizes" depends on !64BIT - default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) && !PARTITION_MANAGER_ENABLED + default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) default SYS_HEAP_AUTO help Heaps using reduced-size chunk headers can accommodate so called diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index a7df11a19e1..557079ef5bc 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -9,9 +9,6 @@ #include #include -#if USE_PARTITION_MANAGER -#include -#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -25,14 +22,6 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", -#if USE_PARTITION_MANAGER - PM_SRAM_ADDRESS, -#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) - REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), -#else - REGION_RAM_ATTR(REGION_SRAM_SIZE)), -#endif -#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -41,8 +30,6 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif -#endif /* USE_PARTITION_MANAGER */ - /* DT-defined regions */ DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index c4c75bb48c4..3058f402d73 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1054,12 +1054,7 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *) \ - COND_CODE_1(USE_PARTITION_MANAGER, \ - (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ - (FIXED_PARTITION_ID(littlefs_storage)), \ - (FIXED_PARTITION_ID(storage)))), \ - (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ + .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index 9996e1d74d9..a74e46b8520 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,35 +13,8 @@ extern "C" { #endif -#if CONFIG_PARTITION_MANAGER_ENABLED - -#include "pm_config.h" - -#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) - -#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) -#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS -#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE -#else -/* The current image is a child image in a different domain than the image - * which defined the required values. To reach the values of the parent domain - * we use the 'PM__' variant of the define. - */ -#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS -#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE -#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ - -#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) -#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ - -#else - -#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) -#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) - -#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 From af1a0352a1b35a23e4d9803abac5151410659e5c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:00 +0000 Subject: [PATCH 4391/4498] Revert "[nrf noup] mgmt/mcumgr: Bootutil hooks to handle image-1" This reverts commit 063b584e78395eb02a1e7cbd82a0ed3251b383f3. Signed-off-by: Dominik Ermel --- subsys/mgmt/mcumgr/CMakeLists.txt | 8 ------ subsys/mgmt/mcumgr/Kconfig | 1 - .../mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c | 27 ------------------- 3 files changed, 36 deletions(-) delete mode 100644 subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index ad088eca067..39d4a4ca8ce 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -16,11 +16,3 @@ add_subdirectory(transport) add_subdirectory_ifdef(CONFIG_SMP_CLIENT smp_client) zephyr_library_link_libraries(mgmt_mcumgr) - -if (CONFIG_BOOT_IMAGE_ACCESS_HOOKS) - zephyr_include_directories( - ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include - ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/include - ) - zephyr_library_sources(bootutil_hooks/nrf53_hooks.c) -endif() diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index a25ee0dc625..8af4ffe2738 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -7,7 +7,6 @@ menuconfig MCUMGR depends on NET_BUF depends on ZCBOR imply CRC - imply BOOT_IMAGE_ACCESS_HOOKS if (SOC_NRF5340_CPUAPP_QKAA && MCUMGR_GRP_IMG) help This option enables the mcumgr management library. diff --git a/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c deleted file mode 100644 index 9971a4e0843..00000000000 --- a/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2022 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "bootutil/bootutil_public.h" - -int boot_read_swap_state_primary_slot_hook(int image_index, - struct boot_swap_state *state) -{ - if (image_index == 1) { - /* Pretend that primary slot of image 1 unpopulated */ - state->magic = BOOT_MAGIC_UNSET; - state->swap_type = BOOT_SWAP_TYPE_NONE; - state->image_num = image_index; - state->copy_done = BOOT_FLAG_UNSET; - state->image_ok = BOOT_FLAG_UNSET; - - /* Prevent bootutil from trying to obtain true info */ - return 0; - } - - return BOOT_HOOK_REGULAR; -} From 100d91d7ff7a4499cffe58cc9b3973f112e0a52a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:00 +0000 Subject: [PATCH 4392/4498] Revert "[nrf fromtree] drivers: flash: nrf_qspi_nor: Add support for XIP at boot" This reverts commit f769ab6e3e3a96d83aa9ba22bf827840da97e5b9. Signed-off-by: Dominik Ermel --- drivers/flash/Kconfig.nordic_qspi_nor | 14 ++------------ drivers/flash/nrf_qspi_nor.c | 21 +-------------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index 7b9fa05eb7f..16252e0812c 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -14,8 +14,8 @@ menuconfig NORDIC_QSPI_NOR if NORDIC_QSPI_NOR config NORDIC_QSPI_NOR_INIT_PRIORITY - int "Init priority" - default 41 + int + default 80 help Device driver initialization priority. @@ -39,14 +39,4 @@ config NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE if the data is larger than the configured size. Must be a multiple of 4. When set to 0, the feature is disabled. -config NORDIC_QSPI_NOR_XIP - bool "XIP (eXecute in place)" - depends on SOC_NRF5340_CPUAPP - help - Enable setting up the QSPI NOR driver to allow for execution of code - stored in QSPI XIP region. Note that for this functionality to work, - the QSPI NOR init priority must be set so that no XIP code in the - QSPI NOR flash chip is executed until the driver has been setup. - This will also disable power management for the QSPI NOR flash chip. - endif # NORDIC_QSPI_NOR diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index e2ce6e6a706..b2455ba3c6f 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -179,8 +179,6 @@ static bool qspi_initialized; static int qspi_device_init(const struct device *dev); static void qspi_device_uninit(const struct device *dev); -void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); -void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); #define WORD_SIZE 4 @@ -1231,7 +1229,6 @@ static int qspi_nor_configure(const struct device *dev) */ static int qspi_nor_init(const struct device *dev) { - int rc; const struct qspi_nor_config *dev_config = dev->config; int ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); @@ -1241,19 +1238,7 @@ static int qspi_nor_init(const struct device *dev) IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), nrfx_isr, nrfx_qspi_irq_handler, 0); - - rc = qspi_nor_configure(dev); - -#ifdef CONFIG_NORDIC_QSPI_NOR_XIP - if (!rc) { - /* Enable XIP mode for QSPI NOR flash, this will prevent the - * flash from being powered down - */ - z_impl_nrf_qspi_nor_xip_enable(dev, true); - } -#endif - - return rc; + return qspi_nor_configure(dev); } #if defined(CONFIG_FLASH_PAGE_LAYOUT) @@ -1384,10 +1369,6 @@ static int qspi_nor_pm_action(const struct device *dev, } #endif - if (dev_data->xip_enabled) { - return -EBUSY; - } - if (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { return -EBUSY; } From f70576bb2f2f359d84934eb41488d4bd8ee6f2b5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:01 +0000 Subject: [PATCH 4393/4498] Revert "[nrf fromtree] bluetooth: Make long workqueue init priority configurable" This reverts commit 41b1428e720e72bdbea7b811840038b41be5e12b. Signed-off-by: Dominik Ermel --- subsys/bluetooth/host/Kconfig | 7 ------- subsys/bluetooth/host/long_wq.c | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index a4cf2e0959b..19754705200 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -23,13 +23,6 @@ config BT_LONG_WQ_PRIO int "Long workqueue priority. Should be pre-emptible." default 10 range 0 NUM_PREEMPT_PRIORITIES - -config BT_LONG_WQ_INIT_PRIO - int "Long workqueue init priority" - default 50 - help - Init priority level to setup the long workqueue. - endif # BT_LONG_WQ config BT_HCI_HOST diff --git a/subsys/bluetooth/host/long_wq.c b/subsys/bluetooth/host/long_wq.c index 2136739c243..61f86d0c909 100644 --- a/subsys/bluetooth/host/long_wq.c +++ b/subsys/bluetooth/host/long_wq.c @@ -40,4 +40,4 @@ static int long_wq_init(void) return 0; } -SYS_INIT(long_wq_init, POST_KERNEL, CONFIG_BT_LONG_WQ_INIT_PRIO); +SYS_INIT(long_wq_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); From 482704ae428703befde2897f2b8c13dde9c9319b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:01 +0000 Subject: [PATCH 4394/4498] Revert "[nrf noup] ci: Update Thread test-spec entry" This reverts commit 488716469816d193dd5b7ffb53d9eb57dfa36c5a. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 62b92e74d0f..03e02441069 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -132,24 +132,25 @@ - "**/*" "CI-homekit-test": - - "modules/openthread/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" - "soc/arm/nordic_nrf/**/*" - - "subsys/net/**/*" + - "subsys/dfu/**/*" - "subsys/settings/**/*" + - "subsys/net/lib/openthread/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - any: - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" - - "!subsys/bluetooth/audio/**/*" "CI-thread-test": - - "include/zephyr/net/**/*" + - "subsys/net/**/*" - "modules/mbedtls/**/*" + - "include/zephyr/net/**/*" - "modules/openthread/**/*" - "samples/net/openthread/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/net/**/*" - - "subsys/settings/**/*" "CI-nfc-test": - "**/*" From a4039d0271878b29785dc797963720ac879c8a38 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:01 +0000 Subject: [PATCH 4395/4498] Revert "[nrf noup] ci: Update Thread test-spec entry" This reverts commit 6340daeb1824fa7f92d2e847d0eb68be53b21d51. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 03e02441069..f81ac31cf75 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -146,11 +146,7 @@ - "!subsys/bluetooth/mesh/**/*" "CI-thread-test": - - "subsys/net/**/*" - - "modules/mbedtls/**/*" - - "include/zephyr/net/**/*" - - "modules/openthread/**/*" - - "samples/net/openthread/**/*" + - "**/*" "CI-nfc-test": - "**/*" From 655e8d408601aac59a96f597046890f0778010cf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:01 +0000 Subject: [PATCH 4396/4498] Revert "[nrf fromlist] zperf: Add support to configure context priority" This reverts commit 427badb22bfd80c63a691163b2d355bb1e3028a5. Signed-off-by: Dominik Ermel --- include/zephyr/net/zperf.h | 1 - subsys/net/lib/zperf/zperf_common.c | 20 +----------- subsys/net/lib/zperf/zperf_internal.h | 2 +- subsys/net/lib/zperf/zperf_shell.c | 39 ----------------------- subsys/net/lib/zperf/zperf_tcp_uploader.c | 2 +- subsys/net/lib/zperf/zperf_udp_uploader.c | 2 +- 6 files changed, 4 insertions(+), 62 deletions(-) diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index cd86541721e..447ffec670c 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -37,7 +37,6 @@ struct zperf_upload_params { struct { uint8_t tos; int tcp_nodelay; - int priority; } options; }; diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index efe36cf69cd..aa29bc99043 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -131,7 +131,7 @@ const struct in6_addr *zperf_get_default_if_in6_addr(void) } int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, - int priority, int proto) + int proto) { socklen_t addrlen = peer_addr->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : @@ -192,24 +192,6 @@ int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, return -EINVAL; } - if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY) && priority >= 0) { - uint8_t prio = priority; - - if (!IS_ENABLED(CONFIG_NET_ALLOW_ANY_PRIORITY) && - (prio > NET_MAX_PRIORITIES)) { - NET_ERR("Priority %d is too large, maximum is %d", - priority, NET_MAX_PRIORITIES); - return -EINVAL; - } - - if (zsock_setsockopt(sock, SOL_SOCKET, SO_PRIORITY, - &prio, - sizeof(prio)) != 0) { - NET_WARN("Failed to set SOL_SOCKET - SO_PRIORITY socket option."); - return -EINVAL; - } - } - ret = zsock_connect(sock, peer_addr, addrlen); if (ret < 0) { NET_ERR("Connect failed (%d)", errno); diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 96dd9ea9123..5bef0331f6f 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -99,7 +99,7 @@ const struct in_addr *zperf_get_default_if_in4_addr(void); const struct in6_addr *zperf_get_default_if_in6_addr(void); int zperf_prepare_upload_sock(const struct sockaddr *peer_addr, int tos, - int priority, int proto); + int proto); uint32_t zperf_packet_duration(uint32_t packet_size, uint32_t rate_in_kbps); diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 3a8a9c61c4b..d3bf11a7b33 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -642,7 +642,6 @@ static int shell_cmd_upload(const struct shell *sh, size_t argc, int start = 0; size_t opt_cnt = 0; - param.options.priority = -1; is_udp = proto == IPPROTO_UDP; /* Parse options */ @@ -681,19 +680,6 @@ static int shell_cmd_upload(const struct shell *sh, size_t argc, opt_cnt += 1; break; -#ifdef CONFIG_NET_CONTEXT_PRIORITY - case 'p': - param.options.priority = parse_arg(&i, argc, argv); - if (param.options.priority < 0 || - param.options.priority > UINT8_MAX) { - shell_fprintf(sh, SHELL_WARNING, - "Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - opt_cnt += 2; - break; -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ - default: shell_fprintf(sh, SHELL_WARNING, "Unrecognized argument: %s\n", argv[i]); @@ -867,19 +853,6 @@ static int shell_cmd_upload2(const struct shell *sh, size_t argc, opt_cnt += 1; break; -#ifdef CONFIG_NET_CONTEXT_PRIORITY - case 'p': - param.options.priority = parse_arg(&i, argc, argv); - if (param.options.priority == -1 || - param.options.priority > UINT8_MAX) { - shell_fprintf(sh, SHELL_WARNING, - "Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - opt_cnt += 2; - break; -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ - default: shell_fprintf(sh, SHELL_WARNING, "Unrecognized argument: %s\n", argv[i]); @@ -1173,9 +1146,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" "-n: Disable Nagle's algorithm\n" -#ifdef CONFIG_NET_CONTEXT_PRIORITY - "-p: Specify custom packet priority\n" -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: tcp upload 192.0.2.2 1111 1 1K\n" "Example: tcp upload 2001:db8::2\n", cmd_tcp_upload), @@ -1189,9 +1159,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" -#ifdef CONFIG_NET_CONTEXT_PRIORITY - "-p: Specify custom packet priority\n" -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: tcp upload2 v6 1 1K\n" "Example: tcp upload2 v4\n" "-n: Disable Nagle's algorithm\n" @@ -1231,9 +1198,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" -#ifdef CONFIG_NET_CONTEXT_PRIORITY - "-p: Specify custom packet priority\n" -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: udp upload 192.0.2.2 1111 1 1K 1M\n" "Example: udp upload 2001:db8::2\n", cmd_udp_upload), @@ -1248,9 +1212,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp, "Available options:\n" "-S tos: Specify IPv4/6 type of service\n" "-a: Asynchronous call (shell will not block for the upload)\n" -#ifdef CONFIG_NET_CONTEXT_PRIORITY - "-p: Specify custom packet priority\n" -#endif /* CONFIG_NET_CONTEXT_PRIORITY */ "Example: udp upload2 v4 1 1K 1M\n" "Example: udp upload2 v6\n" #if defined(CONFIG_NET_IPV6) && defined(MY_IP6ADDR_SET) diff --git a/subsys/net/lib/zperf/zperf_tcp_uploader.c b/subsys/net/lib/zperf/zperf_tcp_uploader.c index 3e72f81e54b..97fd4f57f71 100644 --- a/subsys/net/lib/zperf/zperf_tcp_uploader.c +++ b/subsys/net/lib/zperf/zperf_tcp_uploader.c @@ -117,7 +117,7 @@ int zperf_tcp_upload(const struct zperf_upload_params *param, } sock = zperf_prepare_upload_sock(¶m->peer_addr, param->options.tos, - param->options.priority, IPPROTO_TCP); + IPPROTO_TCP); if (sock < 0) { return sock; } diff --git a/subsys/net/lib/zperf/zperf_udp_uploader.c b/subsys/net/lib/zperf/zperf_udp_uploader.c index e7e2efb9a08..1310063437b 100644 --- a/subsys/net/lib/zperf/zperf_udp_uploader.c +++ b/subsys/net/lib/zperf/zperf_udp_uploader.c @@ -284,7 +284,7 @@ int zperf_udp_upload(const struct zperf_upload_params *param, } sock = zperf_prepare_upload_sock(¶m->peer_addr, param->options.tos, - param->options.priority, IPPROTO_UDP); + IPPROTO_UDP); if (sock < 0) { return sock; } From 0f80969a75658e1ebdf0589472046fb823a770a3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:02 +0000 Subject: [PATCH 4397/4498] Revert "[nrf fromlist] net: Add configuration option to allow any priority" This reverts commit 1675a8a5e9536587b9225953e08dcb286425d79d. Signed-off-by: Dominik Ermel --- subsys/net/ip/Kconfig | 6 ------ subsys/net/ip/icmpv4.c | 3 +-- subsys/net/ip/icmpv6.c | 2 -- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index d2ca36b845c..d7edb988553 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -290,12 +290,6 @@ config NET_RX_DEFAULT_PRIORITY What is the default network RX packet priority if user has not set one. The value 0 means lowest priority and 7 is the highest. -config NET_ALLOW_ANY_PRIORITY - bool "Allow any network packet priority to be used" - help - If this is set, then any user given network packet priority can be used. Otherwise - the network packet priorities are limited to 0-7 range. - config NET_IP_ADDR_CHECK bool "Check IP address validity before sending IP packet" default y diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index ed69903bd8e..058233a7f97 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -538,13 +538,12 @@ int net_icmpv4_send_echo_request(struct net_if *iface, return -ENOMEM; } -#if !defined(CONFIG_NET_ALLOW_ANY_PRIORITY) if (priority > NET_MAX_PRIORITIES) { NET_ERR("Priority %d is too large, maximum is %d", priority, NET_MAX_PRIORITIES); return -EINVAL; } -#endif /* !CONFIG_NET_ALLOW_ANY_PRIORITY */ + if (priority < 0) { net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index 9abc034e1fb..f1286229536 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -363,13 +363,11 @@ int net_icmpv6_send_echo_request(struct net_if *iface, return -ENOMEM; } -#if !defined(CONFIG_NET_ALLOW_ANY_PRIORITY) if (priority > NET_MAX_PRIORITIES) { NET_ERR("Priority %d is too large, maximum is %d", priority, NET_MAX_PRIORITIES); return -EINVAL; } -#endif /* !CONFIG_NET_ALLOW_ANY_PRIORITY */ if (priority < 0) { net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); From faa20cbf738c5283c5bf58ebeed39fa9b4114cb6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:02 +0000 Subject: [PATCH 4398/4498] Revert "[nrf fromlist] net: Add priority to ping" This reverts commit 83d5224ee0287aa5a9fe75a3cf90263a5f6fa8f0. Signed-off-by: Dominik Ermel --- subsys/net/ip/icmpv4.c | 15 ++------------- subsys/net/ip/icmpv4.h | 3 --- subsys/net/ip/icmpv6.c | 15 ++------------- subsys/net/ip/icmpv6.h | 3 --- subsys/net/ip/net_shell.c | 15 +-------------- subsys/net/lib/zperf/zperf_shell.c | 2 +- 6 files changed, 6 insertions(+), 47 deletions(-) diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 058233a7f97..5c3d844be8a 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -507,7 +507,6 @@ int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, - int priority, const void *data, size_t data_size) { @@ -538,18 +537,8 @@ int net_icmpv4_send_echo_request(struct net_if *iface, return -ENOMEM; } - if (priority > NET_MAX_PRIORITIES) { - NET_ERR("Priority %d is too large, maximum is %d", - priority, NET_MAX_PRIORITIES); - return -EINVAL; - } - - if (priority < 0) { - net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); - net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); - } else { - net_pkt_set_priority(pkt, priority); - } + net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(tos)); + net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(tos)); if (net_ipv4_create(pkt, src, dst) || icmpv4_create(pkt, NET_ICMPV4_ECHO_REQUEST, 0)) { diff --git a/subsys/net/ip/icmpv4.h b/subsys/net/ip/icmpv4.h index 492fc6e84a0..bfce2e8d9e6 100644 --- a/subsys/net/ip/icmpv4.h +++ b/subsys/net/ip/icmpv4.h @@ -82,7 +82,6 @@ int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, - int priority, const void *data, size_t data_size); #else @@ -91,7 +90,6 @@ static inline int net_icmpv4_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tos, - int priority, const void *data, size_t data_size) { @@ -100,7 +98,6 @@ static inline int net_icmpv4_send_echo_request(struct net_if *iface, ARG_UNUSED(identifier); ARG_UNUSED(sequence); ARG_UNUSED(tos); - ARG_UNUSED(priority); ARG_UNUSED(data); ARG_UNUSED(data_size); diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index f1286229536..95252a7c156 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -341,7 +341,6 @@ int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, - int priority, const void *data, size_t data_size) { @@ -363,18 +362,8 @@ int net_icmpv6_send_echo_request(struct net_if *iface, return -ENOMEM; } - if (priority > NET_MAX_PRIORITIES) { - NET_ERR("Priority %d is too large, maximum is %d", - priority, NET_MAX_PRIORITIES); - return -EINVAL; - } - - if (priority < 0) { - net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); - net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(tc)); - } else { - net_pkt_set_priority(pkt, priority); - } + net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(tc)); + net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(tc)); if (net_ipv6_create(pkt, src, dst) || net_icmpv6_create(pkt, NET_ICMPV6_ECHO_REQUEST, 0)) { diff --git a/subsys/net/ip/icmpv6.h b/subsys/net/ip/icmpv6.h index d71d9959c14..f0c586a7cf8 100644 --- a/subsys/net/ip/icmpv6.h +++ b/subsys/net/ip/icmpv6.h @@ -222,7 +222,6 @@ int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, - int priority, const void *data, size_t data_size); #else @@ -231,7 +230,6 @@ static inline int net_icmpv6_send_echo_request(struct net_if *iface, uint16_t identifier, uint16_t sequence, uint8_t tc, - int priority, const void *data, size_t data_size) { @@ -240,7 +238,6 @@ static inline int net_icmpv6_send_echo_request(struct net_if *iface, ARG_UNUSED(identifier); ARG_UNUSED(sequence); ARG_UNUSED(tc); - ARG_UNUSED(priority); ARG_UNUSED(data); ARG_UNUSED(data_size); diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index c5b07afd6aa..286d0eca8a9 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -4279,7 +4279,6 @@ static struct ping_context { uint32_t sequence; uint16_t payload_size; uint8_t tos; - int priority; } ping_ctx; static void ping_done(struct ping_context *ctx); @@ -4505,7 +4504,6 @@ static void ping_work(struct k_work *work) sys_rand32_get(), ctx->sequence, ctx->tos, - ctx->priority, NULL, ctx->payload_size); } else { @@ -4514,7 +4512,6 @@ static void ping_work(struct k_work *work) sys_rand32_get(), ctx->sequence, ctx->tos, - ctx->priority, NULL, ctx->payload_size); } @@ -4615,7 +4612,6 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) int iface_idx = -1; int tos = 0; int payload_size = 4; - int priority = -1; for (size_t i = 1; i < argc; ++i) { @@ -4651,14 +4647,6 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) } break; - case 'p': - priority = parse_arg(&i, argc, argv); - if (priority < 0 || priority > UINT8_MAX) { - PR_WARNING("Parse error: %s\n", argv[i]); - return -ENOEXEC; - } - break; - case 'Q': tos = parse_arg(&i, argc, argv); if (tos < 0 || tos > UINT8_MAX) { @@ -4695,7 +4683,6 @@ static int cmd_net_ping(const struct shell *sh, size_t argc, char *argv[]) ping_ctx.sh = sh; ping_ctx.count = count; ping_ctx.interval = interval; - ping_ctx.priority = priority; ping_ctx.tos = tos; ping_ctx.payload_size = payload_size; @@ -6597,7 +6584,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan, SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ping, SHELL_CMD(--help, NULL, "'net ping [-c count] [-i interval ms] [-I ] " - "[-Q tos] [-s payload size] [-p priority] ' " + "[-Q tos] [-s payload size] ' " "Send ICMPv4 or ICMPv6 Echo-Request to a network host.", cmd_net_ping), SHELL_SUBCMD_SET_END diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index d3bf11a7b33..a30caf08074 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -526,7 +526,7 @@ static int execute_upload(const struct shell *sh, * some time and start the test after that. */ net_icmpv6_send_echo_request(net_if_get_default(), - &ipv6->sin6_addr, 0, 0, 0, -1, NULL, 0); + &ipv6->sin6_addr, 0, 0, 0, NULL, 0); k_sleep(K_SECONDS(1)); } From 68deac814482858b9d9905f61d2e73209b12a7f7 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:02 +0000 Subject: [PATCH 4399/4498] Revert "[nrf noup] ci: Update ble and mesh test-spec entry" This reverts commit d6bb133392a74f9e71a39f8d8cd0ff99501edd8a. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index f81ac31cf75..7c4d93cd038 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -40,31 +40,11 @@ - "samples/tfm_integration/**/*" "CI-ble-test": - - any: - - "drivers/bluetooth/**/*" - - any: - - "dts/arm/nordic/nrf5*" - - any: - - "subsys/bluetooth/**/*" - - "!subsys/bluetooth/mesh/**/*" - - "!subsys/bluetooth/audio/**/*" - - any: - - "include/zephyr/bluetooth/**/*" - - "!include/zephyr/bluetooth/mesh/**/*" - - any: - - "samples/bluetooth/**/*" - - "!samples/bluetooth/mesh/**/*" - - "!samples/bluetooth/mesh_demo/**/*" - - "!samples/bluetooth/mesh_provisioner/**/*" - - any: - - "tests/bluetooth/**/*" - - "!tests/bluetooth/mesh/**/*" - - "!tests/bluetooth/mesh_shell/**/*" - - "!tests/bluetooth/audio/**/*" + - "**/*" "CI-mesh-test": - "subsys/bluetooth/mesh/**/*" - - "include/zephyr/bluetooth/mesh/**/*" + - "include/bluetooth/mesh/**/*" - "samples/bluetooth/mesh/**/*" - "samples/bluetooth/mesh_demo/**/*" - "samples/bluetooth/mesh_provisioner/**/*" From 9f95a3ca852af4d8ffa8a6227ebc7a62b99702d5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:02 +0000 Subject: [PATCH 4400/4498] Revert "[nrf noup] ci: Add Sidewalk to test-spec" This reverts commit 090fedd22fbc95498a3540ed63832934d0e66da6. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 7c4d93cd038..102642d4216 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -119,7 +119,7 @@ - "subsys/settings/**/*" - "subsys/net/lib/openthread/**/*" - "subsys/mgmt/mcumgr/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" + - "samples/hci_rpmsg/**/*" - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - any: - "subsys/bluetooth/**/*" @@ -140,7 +140,7 @@ - "subsys/net/**/*" - "subsys/mgmt/mcumgr/**/*" - "drivers/net/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" + - "samples/hci_rpmsg/**/*" - any: - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" @@ -193,16 +193,3 @@ "CI-wifi": - "subsys/net/l2/wifi/**/*" - "subsys/net/l2/ethernet/**/*" - -"CI-sidewalk-test": - - "include/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/dfu/**/*" - - "subsys/settings/**/*" - - "subsys/mgmt/mcumgr/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" - - any: - - "subsys/bluetooth/**/*" - - "!subsys/bluetooth/mesh/**/*" - - "!subsys/bluetooth/audio/**/*" From 0abf7953e13cdd1dadfe24b5191dfe6f97c5382a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:03 +0000 Subject: [PATCH 4401/4498] Revert "[nrf noup] ci: Only run crypto and tf-m tests when needed" This reverts commit fe45e34a7acb0709bbe9d0acf15d35405fdb03e5. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 102642d4216..ce1d40b330e 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -31,13 +31,7 @@ - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" "CI-tfm-test": - - "boards/arm/nrf5340dk_nrf5340/**/*" - - "boards/arm/nrf9160dk_nrf9160/**/*" - - "drivers/entropy/*" - - "dts/arm/nordic/nrf5340*" - - "dts/arm/nordic/nrf9160*" - - "modules/trusted-firmware-m/**/*" - - "samples/tfm_integration/**/*" + - "**/*" "CI-ble-test": - "**/*" @@ -94,16 +88,7 @@ - "**/*" "CI-crypto-test": - - "boards/arm/nrf52840dk_nrf52840/**/*" - - "boards/arm/nrf5340dk_nrf5340/**/*" - - "boards/arm/nrf9160dk_nrf9160/**/*" - - "drivers/entropy/*" - - "drivers/serial/**/*" - - "dts/arm/nordic/nrf52840*" - - "dts/arm/nordic/nrf5340*" - - "dts/arm/nordic/nrf9160*" - - "include/drivers/serial/**/*" - - "modules/mbedtls/**/*" + - "**/*" "CI-fem-test": - "**/*" From d92ce58da907b8bf6b62da45b0521816c7588b84 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:03 +0000 Subject: [PATCH 4402/4498] Revert "[nrf noup] ci: Update Thingy91 test-spec entry" This reverts commit 00175bd6e6a27a9b52875cf417398f657889c535. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index ce1d40b330e..53b811f9ae0 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -52,37 +52,7 @@ - "include/dfu/**/*" "CI-thingy91-test": - - "boards/arm/nrf9160dk_nrf9160/**/*" - - "arch/x86/core/**/*" - - "arch/x86/include/**/*" - - "drivers/console/**/*" - - "drivers/ethernet/**/*" - - "drivers/flash/**/*" - - "drivers/hwinfo/**/*" - - "drivers/interrupt_controller/**/*" - - "drivers/net/**/*" - - "drivers/serial/**/*" - - "drivers/timer/**/*" - - "include/**/*" - - "kernel/**/*" - - "lib/libc/common/source/stdlib/**/*" - - "lib/libc/newlib/**/*" - - "lib/libc/picolibc/**/*" - - "lib/os/**/*" - - "lib/posix/**/*" - - "misc/**/*" - - "modules/mbedtls/**/*" - - "soc/x86/ia32/**/*" - - "subsys/fs/fcb/**/*" - - "subsys/logging/**/*" - - "subsys/net/**/*" - - "subsys/random/**/*" - - "subsys/settings/include/**/*" - - "subsys/settings/src/**/*" - - "subsys/stats/**/*" - - "subsys/storage/flash_map/**/*" - - "subsys/storage/stream/**/*" - - "subsys/tracing/**/*" + - "**/*" "CI-desktop-test": - "**/*" From 9bf76260819e3cb87240aabf1f7f682789cd587f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:03 +0000 Subject: [PATCH 4403/4498] Revert "[nrf noup] ci: Only run lwm2m tests when needed" This reverts commit d44fdf9127f611edd051a893c85992d0ace9be7f. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 53b811f9ae0..5dd281919bc 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -21,7 +21,7 @@ - "subsys/testsuite/ztest/**/*" "CI-lwm2m-test": -# Not necessary to run tests on changes to this repo. + - "**/*" "CI-boot-dfu-test": - "subsys/mgmt/mcumgr/**/*" From 42d2488d72bff7c40638c3db37a140be1169ba06 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:03 +0000 Subject: [PATCH 4404/4498] Revert "[nrf noup] ci: Update test-spec.yml with adding FEM to CI" This reverts commit f3aa7126214fdf6a77afd316a5c0f3e48257f62f. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 5dd281919bc..3fe9ba5fbec 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -60,9 +60,6 @@ "CI-crypto-test": - "**/*" -"CI-fem-test": - - "**/*" - "CI-rs-test": - "**/*" From d084eed0a7fa0f3b08089bc1b0a6cb6fcecdd858 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:03 +0000 Subject: [PATCH 4405/4498] Revert "[nrf noup] Bluetooth: Mesh: Fix adv randomness bug" This reverts commit 62a4cadefae85308a801698f8a164eaecaea2358. Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/adv_ext.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 5c1a2bc3c32..831149bf79e 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -499,9 +499,7 @@ int bt_mesh_adv_enable(void) return err; } - if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && - IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tag == BT_MESH_FRIEND_ADV) { + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && adv->tag & BT_MESH_FRIEND_ADV) { err = set_adv_randomness(adv->instance->handle, 0); if (err) { LOG_ERR("Failed to set zero randomness: %d", err); From 6e2b4c1526bd94971353a5fe0308c9bf7a6b47b9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:04 +0000 Subject: [PATCH 4406/4498] Revert "[nrf noup] samples&tests: Restore a few CONFIG_NEWLIB_LIBC_NANO=n" This reverts commit 9eb6436610f0a0cde6d1ffc6c1cfd70ec1377a15. Signed-off-by: Dominik Ermel --- samples/posix/eventfd/prj.conf | 1 - tests/lib/newlib/heap_listener/prj.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/samples/posix/eventfd/prj.conf b/samples/posix/eventfd/prj.conf index a0bfcdf747b..7ff74543b2f 100644 --- a/samples/posix/eventfd/prj.conf +++ b/samples/posix/eventfd/prj.conf @@ -1,6 +1,5 @@ # General config CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_NANO=n CONFIG_POSIX_API=y CONFIG_EVENTFD=y diff --git a/tests/lib/newlib/heap_listener/prj.conf b/tests/lib/newlib/heap_listener/prj.conf index 8d8ebf99baf..31bc1ca7e76 100644 --- a/tests/lib/newlib/heap_listener/prj.conf +++ b/tests/lib/newlib/heap_listener/prj.conf @@ -1,5 +1,4 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y -CONFIG_NEWLIB_LIBC_NANO=n CONFIG_NEWLIB_LIBC_HEAP_LISTENER=y CONFIG_ZTEST_NEW_API=y From 7f4043fc1fcdddd0e609f997c648ebdd1ae49afc Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:04 +0000 Subject: [PATCH 4407/4498] Revert "[nrf noup] ipc: backends: rpmsg: initialize shared memory to zero" This reverts commit a3139d834c6bd8ee1228ec5f054661683f21612a. Signed-off-by: Dominik Ermel --- .../backends/ipc_rpmsg_static_vrings.c | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c index 5d04d029e8c..41f0a77ea22 100644 --- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c +++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c @@ -774,8 +774,8 @@ static int backend_init(const struct device *instance) return 0; } -#define BACKEND_CONFIG_POPULATE(i) \ - { \ +#define DEFINE_BACKEND_DEVICE(i) \ + static struct backend_config_t backend_config_##i = { \ .role = DT_ENUM_IDX_OR(DT_DRV_INST(i), role, ROLE_HOST), \ .shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, memory_region)), \ .shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \ @@ -790,10 +790,8 @@ static int backend_init(const struct device *instance) .buffer_size = DT_INST_PROP_OR(i, zephyr_buffer_size, \ RPMSG_BUFFER_SIZE), \ .id = i, \ - } - -#define BACKEND_DEVICE_DEFINE(i) \ - static struct backend_config_t backend_config_##i = BACKEND_CONFIG_POPULATE(i); \ + }; \ + \ static struct backend_data_t backend_data_##i; \ \ DEVICE_DT_INST_DEFINE(i, \ @@ -805,23 +803,20 @@ static int backend_init(const struct device *instance) CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY, \ &backend_ops); -DT_INST_FOREACH_STATUS_OKAY(BACKEND_DEVICE_DEFINE) +DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE) -#define BACKEND_CONFIG_DEFINE(i) BACKEND_CONFIG_POPULATE(i), +#define BACKEND_CONFIG_INIT(n) &backend_config_##n, #if defined(CONFIG_IPC_SERVICE_BACKEND_RPMSG_SHMEM_RESET) static int shared_memory_prepare(void) { - const struct backend_config_t *backend_config; - const struct backend_config_t backend_configs[] = { - DT_INST_FOREACH_STATUS_OKAY(BACKEND_CONFIG_DEFINE) + static const struct backend_config_t *config[] = { + DT_INST_FOREACH_STATUS_OKAY(BACKEND_CONFIG_INIT) }; - for (backend_config = backend_configs; - backend_config < backend_configs + ARRAY_SIZE(backend_configs); - backend_config++) { - if (backend_config->role == ROLE_HOST) { - memset((void *) backend_config->shm_addr, 0, VDEV_STATUS_SIZE); + for (int i = 0; i < DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT); i++) { + if (config[i]->role == ROLE_HOST) { + memset((void *) config[i]->shm_addr, 0, VDEV_STATUS_SIZE); } } From 7023bb422a7e24367dccbab66a3d355002fdf706 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:04 +0000 Subject: [PATCH 4408/4498] Revert "[nrf noup] dts: choose cryptocell for entropy when available" This reverts commit 910bb5fe9e14e8afcf0c8b65c846e294821d693e. Signed-off-by: Dominik Ermel --- dts/arm/nordic/nrf52840.dtsi | 2 +- dts/arm/nordic/nrf5340_cpuapp.dtsi | 2 +- dts/arm/nordic/nrf91.dtsi | 1 - soc/arm/nordic_nrf/Kconfig.peripherals | 6 ++---- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index f4209c67d19..8c89968c108 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -5,7 +5,7 @@ / { chosen { - zephyr,entropy = &cryptocell; + zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 1294203f00a..7a32c5398db 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -33,7 +33,7 @@ }; chosen { - zephyr,entropy = &cryptocell; + zephyr,entropy = &rng_hci; zephyr,flash-controller = &flash_controller; }; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index a2a490ab0b1..d872680fb20 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -28,7 +28,6 @@ }; chosen { - zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index 1645cf34ea0..c7bfb552409 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -13,12 +13,10 @@ config HAS_HW_NRF_BPROT def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_BPROT)) config HAS_HW_NRF_CC310 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC310)) || \ - ($(dt_nodelabel_enabled,psa_rng) && SOC_SERIES_NRF91X) + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC310)) config HAS_HW_NRF_CC312 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC312)) || \ - ($(dt_nodelabel_enabled,psa_rng) && SOC_NRF5340_CPUAPP) + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC312)) config HAS_HW_NRF_CCM def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CCM)) From f0c0f30a75b77976c5edaaa0ccdfd1a8d82b1fe1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:04 +0000 Subject: [PATCH 4409/4498] Revert "[nrf noup] ci: NCS-specific CI tweaks" This reverts commit 9b9ec58b0c575e15c57cb1e5de2d1c4ac5266a1f. Signed-off-by: Dominik Ermel --- .github/workflows/commit-tags.yml | 31 ------------------------------- .github/workflows/compliance.yml | 8 ++++---- .gitlint | 4 ++-- Jenkinsfile | 5 ----- 4 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 .github/workflows/commit-tags.yml delete mode 100644 Jenkinsfile diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml deleted file mode 100644 index 9e0323f9498..00000000000 --- a/.github/workflows/commit-tags.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Commit tags - -on: pull_request - -jobs: - commit_tags: - runs-on: ubuntu-22.04 - name: Run commit tags checks on patch series (PR) - steps: - - name: Update PATH for west - run: | - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Checkout the code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Install python dependencies - run: | - pip3 install setuptools - pip3 install wheel - pip3 install gitlint - - - name: Run the commit tags - uses: nrfconnect/action-commit-tags@main - with: - target: '.' - baserev: origin/${{ github.base_ref }} - revrange: 'none' diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index f17780c38e3..f84faff3e4a 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -38,8 +38,8 @@ jobs: git config --global user.name "Your Name" git remote -v # Ensure there's no merge commits in the PR - #[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ - #(echo "::error ::Merge commits not allowed, rebase instead";false) + [[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ + (echo "::error ::Merge commits not allowed, rebase instead";false) git rebase origin/${BASE_REF} # debug git log --pretty=oneline | head -n 10 @@ -56,8 +56,8 @@ jobs: # debug ls -la git log --pretty=oneline | head -n 10 - ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e Kconfig \ - -e KconfigBasicNoModules -c origin/${BASE_REF}.. + ./scripts/ci/check_compliance.py --annotate -e KconfigBasic \ + -c origin/${BASE_REF}.. - name: upload-results uses: actions/upload-artifact@v3 diff --git a/.gitlint b/.gitlint index 8a33f140b2a..b8d25ce49b9 100644 --- a/.gitlint +++ b/.gitlint @@ -16,7 +16,7 @@ debug = false extra-path=scripts/gitlint [title-max-length-no-revert] -line-length=120 +line-length=75 [body-min-line-count] min-line-count=1 @@ -42,7 +42,7 @@ words=wip [max-line-length-with-exceptions] # B1 = body-max-line-length -line-length=120 +line-length=75 [body-min-length] min-length=3 diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 3b9cf002239..00000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,5 +0,0 @@ -@Library("CI_LIB") _ - -def pipeline = new ncs.sdk_zephyr.Main() - -pipeline.run(JOB_NAME) From 0c20bca62ee38081b108bc2921061117b5f12689 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 8 Jan 2024 12:31:05 +0000 Subject: [PATCH 4410/4498] Revert "[nrf noup] ci: add .github/test-spec.yml" This reverts commit ed6a2048c3ab68de67b3fc37275fff453bfe5dfa. Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 147 ------------------------------------------ CODEOWNERS | 1 - 2 files changed, 148 deletions(-) delete mode 100644 .github/test-spec.yml diff --git a/.github/test-spec.yml b/.github/test-spec.yml deleted file mode 100644 index 3fe9ba5fbec..00000000000 --- a/.github/test-spec.yml +++ /dev/null @@ -1,147 +0,0 @@ -# This is the Jenkins ci variant of the .github/labler.yaml -"CI-iot-zephyr-lwm2m-test": - - "drivers/console/**/*" - - "drivers/flash/**/*" - - "subsys/dfu/boot/**/*" - - "subsys/net/ip/**/*" - - "subsys/net/lib/http/**/*" - - "subsys/net/lib/lwm2m//**/*" - - "subsys/net/**/*" - -"CI-iot-samples-test": - - "boards/arm/nrf9160dk_nrf9160/**/*" - - "dts/arm/nordic/nrf9160*" - - "include/net/**/*" - - "subsys/net/lib/**/*" - -"CI-iot-libraries-test": - - "boards/arm/nrf9160dk_nrf9160/**/*" - - "dts/arm/nordic/nrf9160*" - - "include/net/socket_ncs.h" - - "subsys/testsuite/ztest/**/*" - -"CI-lwm2m-test": - - "**/*" - -"CI-boot-dfu-test": - - "subsys/mgmt/mcumgr/**/*" - - "subsys/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "include/dfu/**/*" - - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - -"CI-tfm-test": - - "**/*" - -"CI-ble-test": - - "**/*" - -"CI-mesh-test": - - "subsys/bluetooth/mesh/**/*" - - "include/bluetooth/mesh/**/*" - - "samples/bluetooth/mesh/**/*" - - "samples/bluetooth/mesh_demo/**/*" - - "samples/bluetooth/mesh_provisioner/**/*" - - "tests/bluetooth/mesh/**/*" - - "tests/bluetooth/mesh_shell/**/*" - -"CI-zigbee-test": - - "subsys/mgmt/mcumgr/**/*" - - "subsys/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "include/dfu/**/*" - -"CI-thingy91-test": - - "**/*" - -"CI-desktop-test": - - "**/*" - -"CI-crypto-test": - - "**/*" - -"CI-rs-test": - - "**/*" - -"CI-homekit-test": - - "include/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/dfu/**/*" - - "subsys/settings/**/*" - - "subsys/net/lib/openthread/**/*" - - "subsys/mgmt/mcumgr/**/*" - - "samples/hci_rpmsg/**/*" - - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - - any: - - "subsys/bluetooth/**/*" - - "!subsys/bluetooth/mesh/**/*" - -"CI-thread-test": - - "**/*" - -"CI-nfc-test": - - "**/*" - -"CI-matter-test": - - "include/dfu/**/*" - - "include/mgmt/mcumgr/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/dfu/**/*" - - "subsys/settings/**/*" - - "subsys/net/**/*" - - "subsys/mgmt/mcumgr/**/*" - - "drivers/net/**/*" - - "samples/hci_rpmsg/**/*" - - any: - - "subsys/bluetooth/**/*" - - "!subsys/bluetooth/mesh/**/*" - - "!subsys/bluetooth/audio/**/*" - -"CI-find-my-test": - - "**/*" - -"CI-gazell-test": - - "**/*" - -"CI-rpc-test": - - "**/*" - -"CI-modemshell-test": - - "include/net/**/*" - - "include/posix/**/*" - - "include/shell/**/*" - - "drivers/net/**/*" - - "drivers/serial/**/*" - - "drivers/wifi/**/*" - - "subsys/shell/**/*" - - "subsys/net/**/*" - - "subsys/settings/**/*" - -"CI-positioning-test": - - "include/net/**/*" - - "include/posix/**/*" - - "drivers/net/**/*" - - "drivers/wifi/**/*" - - "subsys/net/**/*" - - "subsys/settings/**/*" - -"CI-cloud-test": - - "include/zephyr/dfu/**/*" - - "include/zephyr/net/**/*" - - "include/zephyr/posix/**/*" - - "include/zephyr/settings/**/*" - - "drivers/led/**/*" - - "drivers/net/**/*" - - "drivers/sensor/**/*" - - "drivers/serial/**/*" - - "drivers/wifi/**/*" - - "lib/posix/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/dfu/**/*" - - "subsys/net/**/*" - - "subsys/settings/**/*" - -"CI-wifi": - - "subsys/net/l2/wifi/**/*" - - "subsys/net/l2/ethernet/**/*" diff --git a/CODEOWNERS b/CODEOWNERS index a670048c779..25cf3791114 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,7 +14,6 @@ # * @galak @nashif /.github/ @nashif @stephanosio -/.github/test-spec.yml @nrfconnect/ncs-test-leads /.github/workflows/ @galak @nashif /MAINTAINERS.yml @MaureenHelm /arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev From 605f129e42d2a04086e819f3e446bdb4fd22b539 Mon Sep 17 00:00:00 2001 From: Sebastian Wezel Date: Tue, 15 Mar 2022 13:12:25 +0100 Subject: [PATCH 4411/4498] [nrf noup] ci: add .github/test-spec.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file is used for NCS-specific testing configuration based on modifications to files in this repository. Signed-off-by: Alperen Sener Signed-off-by: Elisabeth Solheim Klakken Signed-off-by: Mariusz Poslinski Signed-off-by: Markus Swarowsky Signed-off-by: Robert Lubos Signed-off-by: Sebastian Wezel Signed-off-by: Tomasz Tyzenhauz Signed-off-by: Fredrik Ås Signed-off-by: Michał Szablowski Signed-off-by: Tony Le Signed-off-by: Krishna T (cherry picked from commit 2a59fbdf425895a357fc6bff919d3108b6e35469) (cherry picked from commit acb96b140c95e933546acc41cc6df22b609342db) (cherry picked from commit e102ad15b3804c9d71447dda2bf4e321ec4185fb) (cherry picked from commit f9eac37be8ef89db5b2cbb06e38aef09e13fc448) (cherry picked from commit ed6a2048c3ab68de67b3fc37275fff453bfe5dfa) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 147 ++++++++++++++++++++++++++++++++++++++++++ CODEOWNERS | 1 + 2 files changed, 148 insertions(+) create mode 100644 .github/test-spec.yml diff --git a/.github/test-spec.yml b/.github/test-spec.yml new file mode 100644 index 00000000000..3fe9ba5fbec --- /dev/null +++ b/.github/test-spec.yml @@ -0,0 +1,147 @@ +# This is the Jenkins ci variant of the .github/labler.yaml +"CI-iot-zephyr-lwm2m-test": + - "drivers/console/**/*" + - "drivers/flash/**/*" + - "subsys/dfu/boot/**/*" + - "subsys/net/ip/**/*" + - "subsys/net/lib/http/**/*" + - "subsys/net/lib/lwm2m//**/*" + - "subsys/net/**/*" + +"CI-iot-samples-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/**/*" + - "subsys/net/lib/**/*" + +"CI-iot-libraries-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/socket_ncs.h" + - "subsys/testsuite/ztest/**/*" + +"CI-lwm2m-test": + - "**/*" + +"CI-boot-dfu-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" + +"CI-tfm-test": + - "**/*" + +"CI-ble-test": + - "**/*" + +"CI-mesh-test": + - "subsys/bluetooth/mesh/**/*" + - "include/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh_demo/**/*" + - "samples/bluetooth/mesh_provisioner/**/*" + - "tests/bluetooth/mesh/**/*" + - "tests/bluetooth/mesh_shell/**/*" + +"CI-zigbee-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + +"CI-thingy91-test": + - "**/*" + +"CI-desktop-test": + - "**/*" + +"CI-crypto-test": + - "**/*" + +"CI-rs-test": + - "**/*" + +"CI-homekit-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/lib/openthread/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/hci_rpmsg/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + +"CI-thread-test": + - "**/*" + +"CI-nfc-test": + - "**/*" + +"CI-matter-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "drivers/net/**/*" + - "samples/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + +"CI-find-my-test": + - "**/*" + +"CI-gazell-test": + - "**/*" + +"CI-rpc-test": + - "**/*" + +"CI-modemshell-test": + - "include/net/**/*" + - "include/posix/**/*" + - "include/shell/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "subsys/shell/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-positioning-test": + - "include/net/**/*" + - "include/posix/**/*" + - "drivers/net/**/*" + - "drivers/wifi/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-cloud-test": + - "include/zephyr/dfu/**/*" + - "include/zephyr/net/**/*" + - "include/zephyr/posix/**/*" + - "include/zephyr/settings/**/*" + - "drivers/led/**/*" + - "drivers/net/**/*" + - "drivers/sensor/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "lib/posix/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-wifi": + - "subsys/net/l2/wifi/**/*" + - "subsys/net/l2/ethernet/**/*" diff --git a/CODEOWNERS b/CODEOWNERS index 8872e7381c5..2c8b9db3961 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,6 +18,7 @@ # component or code. This file is going to be deprecated and currently only had # entries that are not covered by the MAINTAINERS file. +/.github/test-spec.yml @nrfconnect/ncs-test-leads /soc/arm/aspeed/ @aspeeddylan /soc/arm/atmel_sam/common/*_sam4l_*.c @nandojve /soc/arm/atmel_sam/sam3x/ @ioannisg From 6b014316c607f99f927c6e05917ee73167e08f03 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 30 Nov 2018 14:07:56 +0100 Subject: [PATCH 4412/4498] [nrf noup] ci: NCS-specific CI tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Necessary changes for NCS CI. - Add a Jenkinsfile - compliance.yml: Disable check for merge commits, since we have upmerges downstream. Add an additional check for sauce tags (details in scripts/gitlint) Also, since in the code we refer to Kconfig symbols that are defined in the sdk-nrf repository, the Kconfig checks (Kconfig and KconfigBasic) will not pass so exclude them. - Extend the max commit line lengths for Gitlint to account for sauce tags - Add a commit-tags workflow: This enables sauce tag checking in sdk-zephyr - scripts/gitlint: Add support for sauce tags checks. In order to not interfere with CI in other repos (namely sdk-nrf) this is run as an independent gitlint invocation and not as part of check_compliance.py. This invocation enables the ncs-sauce-tags rule and, since it runs before rebasing and thus will run on merge commits, disables the title-starts-with-subsystem rule by setting a catch-all regex. Signed-off-by: Carles Cufi Signed-off-by: Dominik Ermel Signed-off-by: Martí Bolívar Signed-off-by: Vinayak Kariappa Chettimada Signed-off-by: Krishna T (cherry picked from commit d34b035bcc569431b7008c72edc55db1b29bccf3) (cherry picked from commit 4a6d5fc57fe7589b2585ee5e44341f50821cc653) (cherry picked from commit a01c3a4caccb6964a29078172ba7f590bcdbe790) (cherry picked from commit 9b9ec58b0c575e15c57cb1e5de2d1c4ac5266a1f) Signed-off-by: Dominik Ermel --- .github/workflows/commit-tags.yml | 31 +++++++++++++++++++++++++++++++ .github/workflows/compliance.yml | 8 ++++---- Jenkinsfile | 5 +++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/commit-tags.yml create mode 100644 Jenkinsfile diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml new file mode 100644 index 00000000000..9e0323f9498 --- /dev/null +++ b/.github/workflows/commit-tags.yml @@ -0,0 +1,31 @@ +name: Commit tags + +on: pull_request + +jobs: + commit_tags: + runs-on: ubuntu-22.04 + name: Run commit tags checks on patch series (PR) + steps: + - name: Update PATH for west + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Checkout the code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Install python dependencies + run: | + pip3 install setuptools + pip3 install wheel + pip3 install gitlint + + - name: Run the commit tags + uses: nrfconnect/action-commit-tags@main + with: + target: '.' + baserev: origin/${{ github.base_ref }} + revrange: 'none' diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index de1decb2cc6..d70990ff2c1 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -38,8 +38,8 @@ jobs: git config --global user.name "Your Name" git remote -v # Ensure there's no merge commits in the PR - [[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ - (echo "::error ::Merge commits not allowed, rebase instead";false) + #[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ + #(echo "::error ::Merge commits not allowed, rebase instead";false) git rebase origin/${BASE_REF} # debug git log --pretty=oneline | head -n 10 @@ -57,8 +57,8 @@ jobs: # debug ls -la git log --pretty=oneline | head -n 10 - ./scripts/ci/check_compliance.py --annotate -e KconfigBasic \ - -c origin/${BASE_REF}.. + ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e Kconfig \ + -e KconfigBasicNoModules -c origin/${BASE_REF}.. - name: upload-results uses: actions/upload-artifact@v3 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000000..3b9cf002239 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,5 @@ +@Library("CI_LIB") _ + +def pipeline = new ncs.sdk_zephyr.Main() + +pipeline.run(JOB_NAME) From 499041d072580ae79d4fe967f0df52e60e43966b Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Mon, 16 Jan 2023 14:15:22 +0100 Subject: [PATCH 4413/4498] [nrf noup] dts: choose cryptocell for entropy when available This is a long-term noup patch because driver support is NCS-only. Set HAS_HW_NRF_CC3XX to be defined in NS build when cryptocell is accessed through the PSA API. We need to know which CC3XX features are available. Signed-off-by: Georgios Vasilakis Signed-off-by: Joakim Andersson (cherry picked from commit c76cf8776d7bcbb7eef8023191a941f8e9410cb4) (cherry picked from commit 214533fa69601f52933977a39fff855d955c886f) (cherry picked from commit 3819c4ae701f0b4265bbd3409e37e5bba5c4abcb) (cherry picked from commit 910bb5fe9e14e8afcf0c8b65c846e294821d693e) Signed-off-by: Dominik Ermel --- dts/arm/nordic/nrf52840.dtsi | 4 ++-- dts/arm/nordic/nrf5340_cpuapp.dtsi | 4 ++-- dts/arm/nordic/nrf91.dtsi | 3 ++- soc/arm/nordic_nrf/Kconfig.peripherals | 6 ++++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 24710e8e0ff..9e3b79b3abd 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -5,7 +5,7 @@ / { chosen { - zephyr,entropy = &rng; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -543,7 +543,7 @@ reg = <0x5002a000 0x1000>, <0x5002b000 0x1000>; reg-names = "wrapper", "core"; interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 77762990e13..a6ae5d4a316 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -33,7 +33,7 @@ }; chosen { - zephyr,entropy = &rng_hci; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -91,7 +91,7 @@ reg = <0x50844000 0x1000>, <0x50845000 0x1000>; reg-names = "wrapper", "core"; interrupts = <68 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index 46024011166..23d2c7cf20e 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -28,6 +28,7 @@ }; chosen { + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -51,7 +52,7 @@ reg = <0x50840000 0x1000>, <0x50841000 0x1000>; reg-names = "wrapper", "core"; interrupts = <64 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; ctrlap: ctrlap@50006000 { diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index 3aacc35a08a..2b7791bf5e6 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -13,10 +13,12 @@ config HAS_HW_NRF_BPROT def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_BPROT)) config HAS_HW_NRF_CC310 - def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_310)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_310)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_SERIES_NRF91X) config HAS_HW_NRF_CC312 - def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_312)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_312)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_NRF5340_CPUAPP) config HAS_HW_NRF_CCM def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CCM)) From 275c2a7e51b4e1038d3052d3411d22aa48949360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 1 Dec 2022 14:41:13 +0100 Subject: [PATCH 4414/4498] [nrf noup] samples&tests: Restore a few CONFIG_NEWLIB_LIBC_NANO=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 9dd570f8a2207a02c886480b0065cd5a0e3a2e94. Since in NCS, unlike in vanilla Zephyr, the nano variant of newlib is the default one, restore entries that disable the nano variant in one sample and one test that require the full newlib variant. This patch is supposed to be removed when picolibc becomes the default. Signed-off-by: Andrzej Głąbek (cherry picked from commit 56204202e86fb7fa89f7ae74c916f73a00a22044) (cherry picked from commit 4edd3681905057c345eb622ffe144fac958593e0) (cherry picked from commit 9eb6436610f0a0cde6d1ffc6c1cfd70ec1377a15) Signed-off-by: Dominik Ermel --- tests/lib/newlib/heap_listener/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/newlib/heap_listener/prj.conf b/tests/lib/newlib/heap_listener/prj.conf index e5a5dc6df4c..7282777ff1c 100644 --- a/tests/lib/newlib/heap_listener/prj.conf +++ b/tests/lib/newlib/heap_listener/prj.conf @@ -1,3 +1,4 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n CONFIG_NEWLIB_LIBC_HEAP_LISTENER=y From 3afe29330d959ee78d57db509a7380f0e05b6bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 8 Mar 2023 12:17:09 +0100 Subject: [PATCH 4415/4498] [nrf noup] Bluetooth: Mesh: Fix adv randomness bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue where randomness can be removed for advertising sets that have to handle other adv types than the BT_MESH_FRIEND_ADV tag type. Signed-off-by: Anders Storrø (cherry picked from commit f8f113382356934cb6d1ef4cdad95a843f922085) (cherry picked from commit 996037de254a91a9b2da4a288f48c09e90427501) (cherry picked from commit 62a4cadefae85308a801698f8a164eaecaea2358) Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/adv_ext.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 0c11fc0053a..525e5ee5066 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -527,7 +527,9 @@ int bt_mesh_adv_enable(void) return err; } - if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && adv->tag & BT_MESH_FRIEND_ADV) { + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && + IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && + adv->tag == BT_MESH_FRIEND_ADV) { err = set_adv_randomness(adv->instance->handle, 0); if (err) { LOG_ERR("Failed to set zero randomness: %d", err); From 817446221498fe6e6f585768fe4f9136a18fc0f2 Mon Sep 17 00:00:00 2001 From: Dawid Przybylo Date: Fri, 23 Jun 2023 08:15:25 +0200 Subject: [PATCH 4416/4498] [nrf noup] ci: Update test-spec.yml with adding FEM to CI Extend sdk-zephyr CI with FEM test label. Signed-off-by: Dawid Przybylo (cherry picked from commit d2bc2c3c6ce3d08628a93c3bd246fd688dc6a446) (cherry picked from commit f3aa7126214fdf6a77afd316a5c0f3e48257f62f) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 3fe9ba5fbec..5dd281919bc 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -60,6 +60,9 @@ "CI-crypto-test": - "**/*" +"CI-fem-test": + - "**/*" + "CI-rs-test": - "**/*" From d53a1c962551409a9db38d711f5e076804170d79 Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Fri, 11 Aug 2023 15:37:25 +0200 Subject: [PATCH 4417/4498] [nrf noup] ci: Only run lwm2m tests when needed There is no need to run those for all PRs. For example: When there are only changes to Bluetooth, we don't want this CI to run. Adding these filters may speedup the time to merge for PRs to sdk-nrf Signed-off-by: Rubin Gerritsen (cherry picked from commit 78106c74f4ac7936ef78dcddb8c6e1e578fe41dd) (cherry picked from commit d44fdf9127f611edd051a893c85992d0ace9be7f) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 5dd281919bc..53b811f9ae0 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -21,7 +21,7 @@ - "subsys/testsuite/ztest/**/*" "CI-lwm2m-test": - - "**/*" +# Not necessary to run tests on changes to this repo. "CI-boot-dfu-test": - "subsys/mgmt/mcumgr/**/*" From 255ee9dbefa18142e395f4b8abfd4fd20a80ad53 Mon Sep 17 00:00:00 2001 From: Jorgen Kvalvaag Date: Thu, 24 Aug 2023 10:03:43 +0200 Subject: [PATCH 4418/4498] [nrf noup] ci: Update Thingy91 test-spec entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thingy91 CI tests dependencies added. Signed-off-by: Jørgen Kvalvaag (cherry picked from commit 6a0df6f20645130ef3bf90b8c2ec605510d9b125) (cherry picked from commit 00175bd6e6a27a9b52875cf417398f657889c535) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 53b811f9ae0..ce1d40b330e 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -52,7 +52,37 @@ - "include/dfu/**/*" "CI-thingy91-test": - - "**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "arch/x86/core/**/*" + - "arch/x86/include/**/*" + - "drivers/console/**/*" + - "drivers/ethernet/**/*" + - "drivers/flash/**/*" + - "drivers/hwinfo/**/*" + - "drivers/interrupt_controller/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/timer/**/*" + - "include/**/*" + - "kernel/**/*" + - "lib/libc/common/source/stdlib/**/*" + - "lib/libc/newlib/**/*" + - "lib/libc/picolibc/**/*" + - "lib/os/**/*" + - "lib/posix/**/*" + - "misc/**/*" + - "modules/mbedtls/**/*" + - "soc/x86/ia32/**/*" + - "subsys/fs/fcb/**/*" + - "subsys/logging/**/*" + - "subsys/net/**/*" + - "subsys/random/**/*" + - "subsys/settings/include/**/*" + - "subsys/settings/src/**/*" + - "subsys/stats/**/*" + - "subsys/storage/flash_map/**/*" + - "subsys/storage/stream/**/*" + - "subsys/tracing/**/*" "CI-desktop-test": - "**/*" From 5e158827055b624583817e226972f2f8e2c1f030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magne=20V=C3=A6rnes?= Date: Wed, 23 Aug 2023 16:10:42 +0200 Subject: [PATCH 4419/4498] [nrf noup] ci: Only run crypto and tf-m tests when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extended the github CI filter for crypto and TF-M tests to reduce the CI load and possibly speed up PRs. Signed-off-by: Magne Værnes (cherry picked from commit c0d21ea8df1bce0d1bc2774a8e7348f3fc90271f) (cherry picked from commit fe45e34a7acb0709bbe9d0acf15d35405fdb03e5) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index ce1d40b330e..102642d4216 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -31,7 +31,13 @@ - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" "CI-tfm-test": - - "**/*" + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "modules/trusted-firmware-m/**/*" + - "samples/tfm_integration/**/*" "CI-ble-test": - "**/*" @@ -88,7 +94,16 @@ - "**/*" "CI-crypto-test": - - "**/*" + - "boards/arm/nrf52840dk_nrf52840/**/*" + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "drivers/serial/**/*" + - "dts/arm/nordic/nrf52840*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "include/drivers/serial/**/*" + - "modules/mbedtls/**/*" "CI-fem-test": - "**/*" From 23b8a13a04d81fe92a185b15c60fdb10ac52578d Mon Sep 17 00:00:00 2001 From: Tomasz Tyzenhauz Date: Fri, 25 Aug 2023 13:27:53 +0200 Subject: [PATCH 4420/4498] [nrf noup] ci: Add Sidewalk to test-spec Add Sidewalk to be trigger on changes in this repo. Correct entry path for hci_rpmsg samples for Matter and Homekit. Signed-off-by: Tomasz Tyzenhauz (cherry picked from commit cd4e36f63fd444d1e850894ca743ee8e9654fc1a) (cherry picked from commit 090fedd22fbc95498a3540ed63832934d0e66da6) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 102642d4216..7c4d93cd038 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -119,7 +119,7 @@ - "subsys/settings/**/*" - "subsys/net/lib/openthread/**/*" - "subsys/mgmt/mcumgr/**/*" - - "samples/hci_rpmsg/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - any: - "subsys/bluetooth/**/*" @@ -140,7 +140,7 @@ - "subsys/net/**/*" - "subsys/mgmt/mcumgr/**/*" - "drivers/net/**/*" - - "samples/hci_rpmsg/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" - any: - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" @@ -193,3 +193,16 @@ "CI-wifi": - "subsys/net/l2/wifi/**/*" - "subsys/net/l2/ethernet/**/*" + +"CI-sidewalk-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" From 660313bbc996648d6a617a5c65c618b68b0c6686 Mon Sep 17 00:00:00 2001 From: Lang Xie Date: Fri, 8 Sep 2023 13:13:41 +0200 Subject: [PATCH 4421/4498] [nrf noup] ci: Update ble and mesh test-spec entry Add BLE CI test dependency and update the include path of mesh. Signed-off-by: Lang Xie (cherry picked from commit 02956222c991e2c036810a5e39fd60e72aa75866) (cherry picked from commit d6bb133392a74f9e71a39f8d8cd0ff99501edd8a) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 7c4d93cd038..f81ac31cf75 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -40,11 +40,31 @@ - "samples/tfm_integration/**/*" "CI-ble-test": - - "**/*" + - any: + - "drivers/bluetooth/**/*" + - any: + - "dts/arm/nordic/nrf5*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + - any: + - "include/zephyr/bluetooth/**/*" + - "!include/zephyr/bluetooth/mesh/**/*" + - any: + - "samples/bluetooth/**/*" + - "!samples/bluetooth/mesh/**/*" + - "!samples/bluetooth/mesh_demo/**/*" + - "!samples/bluetooth/mesh_provisioner/**/*" + - any: + - "tests/bluetooth/**/*" + - "!tests/bluetooth/mesh/**/*" + - "!tests/bluetooth/mesh_shell/**/*" + - "!tests/bluetooth/audio/**/*" "CI-mesh-test": - "subsys/bluetooth/mesh/**/*" - - "include/bluetooth/mesh/**/*" + - "include/zephyr/bluetooth/mesh/**/*" - "samples/bluetooth/mesh/**/*" - "samples/bluetooth/mesh_demo/**/*" - "samples/bluetooth/mesh_provisioner/**/*" From 14a865b41c6f51ba8786c7eae23a1a3ff70a3727 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Tue, 5 Sep 2023 09:43:10 +0200 Subject: [PATCH 4422/4498] [nrf noup] ci: Update Thread test-spec entry Update Thread test-spec entry. Signed-off-by: Mariusz Poslinski (cherry picked from commit 81c640bcccce83f83573234ca1725e6d5576e9c2) (cherry picked from commit 6340daeb1824fa7f92d2e847d0eb68be53b21d51) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index f81ac31cf75..03e02441069 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -146,7 +146,11 @@ - "!subsys/bluetooth/mesh/**/*" "CI-thread-test": - - "**/*" + - "subsys/net/**/*" + - "modules/mbedtls/**/*" + - "include/zephyr/net/**/*" + - "modules/openthread/**/*" + - "samples/net/openthread/**/*" "CI-nfc-test": - "**/*" From ddedbc9e833fa5f326a7d3d7d1fd0a27349d6208 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Mon, 18 Sep 2023 12:48:52 +0200 Subject: [PATCH 4423/4498] [nrf noup] ci: Update Thread test-spec entry Update Thread and HomeKit test-spec entries. Signed-off-by: Mariusz Poslinski (cherry picked from commit 4c741f1e2d2542ab23891fff46ed93add2893740) (cherry picked from commit 488716469816d193dd5b7ffb53d9eb57dfa36c5a) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 03e02441069..62b92e74d0f 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -132,25 +132,24 @@ - "**/*" "CI-homekit-test": - - "include/dfu/**/*" - - "include/mgmt/mcumgr/**/*" + - "modules/openthread/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" - "soc/arm/nordic_nrf/**/*" - - "subsys/dfu/**/*" + - "subsys/net/**/*" - "subsys/settings/**/*" - - "subsys/net/lib/openthread/**/*" - - "subsys/mgmt/mcumgr/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" - - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - any: - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" "CI-thread-test": - - "subsys/net/**/*" - - "modules/mbedtls/**/*" - "include/zephyr/net/**/*" + - "modules/mbedtls/**/*" - "modules/openthread/**/*" - "samples/net/openthread/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" "CI-nfc-test": - "**/*" From 041e804add1e154ea95da502842df792e603cda5 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 23 Jun 2022 14:10:01 +0000 Subject: [PATCH 4424/4498] [nrf noup] mgmt/mcumgr: Bootutil hooks to handle image-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit adds bootutil hook, for nrf5340, to allow it handling the non-accessible image-1/primary slot. Signed-off-by: Andrzej Głąbek Signed-off-by: Vinayak Kariappa Chettimada Signed-off-by: Johann Fischer (cherry picked from commit 840b8fa1dba3ddda02fa1652a9408b08b7c310de) (cherry picked from commit 9af7d7ad2f70cee26ccc98b4daadd2260662ff78) (cherry picked from commit 298d8037d2b60b4ca4dd8b2a7727196e33054dd8) (cherry picked from commit d3aa849948ce548ba46ddb7f6ec0b4422fa53db4) (cherry picked from commit 063b584e78395eb02a1e7cbd82a0ed3251b383f3) Signed-off-by: Dominik Ermel --- subsys/mgmt/mcumgr/CMakeLists.txt | 8 ++++++ subsys/mgmt/mcumgr/Kconfig | 1 + .../mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index 39d4a4ca8ce..ad088eca067 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -16,3 +16,11 @@ add_subdirectory(transport) add_subdirectory_ifdef(CONFIG_SMP_CLIENT smp_client) zephyr_library_link_libraries(mgmt_mcumgr) + +if (CONFIG_BOOT_IMAGE_ACCESS_HOOKS) + zephyr_include_directories( + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/include + ) + zephyr_library_sources(bootutil_hooks/nrf53_hooks.c) +endif() diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index 49bd17f4669..1c6a3a2a516 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -6,6 +6,7 @@ menuconfig MCUMGR bool "mcumgr Support" depends on NET_BUF depends on ZCBOR + imply BOOT_IMAGE_ACCESS_HOOKS if (SOC_NRF5340_CPUAPP_QKAA && MCUMGR_GRP_IMG) help This option enables the mcumgr management library. diff --git a/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c new file mode 100644 index 00000000000..9971a4e0843 --- /dev/null +++ b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "bootutil/bootutil_public.h" + +int boot_read_swap_state_primary_slot_hook(int image_index, + struct boot_swap_state *state) +{ + if (image_index == 1) { + /* Pretend that primary slot of image 1 unpopulated */ + state->magic = BOOT_MAGIC_UNSET; + state->swap_type = BOOT_SWAP_TYPE_NONE; + state->image_num = image_index; + state->copy_done = BOOT_FLAG_UNSET; + state->image_ok = BOOT_FLAG_UNSET; + + /* Prevent bootutil from trying to obtain true info */ + return 0; + } + + return BOOT_HOOK_REGULAR; +} From a7fb26837763ee7c21fb666fe2faa8c7503a17f1 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 3 May 2019 14:21:52 +0200 Subject: [PATCH 4425/4498] [nrf noup] tree-wide: support NCS Partition Manager (PM) definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager (PM) is a component of the nRF Connect SDK (NCS) which uses yaml files to resolve flash partition placement with a holistic view of the entire device, including each firmware image present on the flash device, and various subsystems, such as settings and NFFS. When this NCS extension is used, various source files which would use partition information from devicetree in "vanilla" zephyr instead use defines generated by PM instead. This commit removes support for HEX_FILES_TO_MERGE, as it conflicts with PM. The settings subsystem pm.yml defines a partition 'settings_storage'. The nffs subsystem pm.yml defines 'nffs_storage'. Leverage label translation to avoid patching partition names. Refer to the NCS documentation page for this feature for more details. This is a long-running out of tree patch which has been worked on by several people. The following sign-offs are in alphabetical order by first name. Signed-off-by: Andrzej Głąbek Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Joakim Andersson Signed-off-by: Johann Fischer Signed-off-by: Martí Bolívar Signed-off-by: Ole Sæther Signed-off-by: Robert Lubos Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Thomas Stenersen Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Trond Einar Snekvik Signed-off-by: Gerard Marull-Paretas Signed-off-by: Tomasz Moń (cherry picked from commit ba54fe88dcfe3b25aca4c02f01e47f232b0f8bf7) (cherry picked from commit 68110ee5a75167e8e2c65746211571315618a3e1) (cherry picked from commit 12d1ebfb98a4f89dc018af4e7872382222b3b74a) (cherry picked from commit 5e8e748917649fc0a4a44a02c2c91c581007856d) (cherry picked from commit d1fa3da6c37763e1ae9306c43bfaf5cf965af594) Signed-off-by: Dominik Ermel --- arch/arm/core/mpu/arm_mpu_regions.c | 13 ++++++ cmake/modules/kernel.cmake | 4 ++ drivers/flash/soc_flash_nrf.c | 11 +++++ .../arch/arm/cortex_m/scripts/linker.ld | 46 +++++++++++++++++++ include/zephyr/storage/flash_map.h | 6 +++ lib/libc/common/source/stdlib/malloc.c | 18 +++++++- lib/os/Kconfig.heap | 2 +- subsys/fs/littlefs_fs.c | 7 ++- subsys/ipc/rpmsg_service/rpmsg_backend.h | 27 +++++++++++ 9 files changed, 130 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/mpu/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c index 6af62f84078..cfe1230c907 100644 --- a/arch/arm/core/mpu/arm_mpu_regions.c +++ b/arch/arm/core/mpu/arm_mpu_regions.c @@ -8,6 +8,9 @@ #include #include +#if USE_PARTITION_MANAGER +#include +#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -21,6 +24,14 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", +#if USE_PARTITION_MANAGER + PM_SRAM_ADDRESS, +#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) + REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), +#else + REGION_RAM_ATTR(REGION_SRAM_SIZE)), +#endif +#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -28,6 +39,8 @@ static const struct arm_mpu_region mpu_regions[] = { #else REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif + +#endif /* USE_PARTITION_MANAGER */ }; const struct arm_mpu_config mpu_config = { diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index a093d46691f..06e1642f362 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -243,3 +243,7 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() + +if(ZEPHYR_NRF_MODULE_DIR) + include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) +endif() diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index cc840309264..b5a3fefa1e5 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,6 +37,11 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER +#include +#include +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ + #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -166,6 +171,12 @@ static int flash_nrf_read(const struct device *dev, off_t addr, } #endif +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS + if (addr < PM_APP_ADDRESS) { + return soc_secure_mem_read(data, (void *)addr, len); + } +#endif + nrf_nvmc_buffer_read(data, (uint32_t)addr, len); return 0; diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 13c2747f5a3..5050c778627 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -26,6 +26,35 @@ #endif #define RAMABLE_REGION RAM +#if USE_PARTITION_MANAGER + +#include + +#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) +/* We are linking against S1, create symbol containing the flash ID of S0. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S0_ID; + +#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ + +#ifdef PM_S1_ID +/* We are linking against S0, create symbol containing the flash ID of S1. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S1_ID; +#endif /* PM_S1_ID */ + +#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ + +#define ROM_ADDR PM_ADDRESS +#define ROM_SIZE PM_SIZE + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -52,6 +81,23 @@ #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif +#endif /* USE_PARTITION_MANAGER */ + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) +#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) +#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) +#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) +#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) +#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) +#endif + #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 380e58691e9..cc4a246105d 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -271,6 +271,10 @@ const char *flash_area_label(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); +#if USE_PARTITION_MANAGER +#include +#else + #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -343,6 +347,8 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) +#endif /* USE_PARTITION_MANAGER */ + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index e3a5db6f7d5..2f469d673e4 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -25,6 +25,20 @@ #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); +#if USE_PARTITION_MANAGER + +#include + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + +#define RAM_SIZE (KB((size_t) CONFIG_SRAM_SIZE)) +#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS + +#endif /* USE_PARTITION_MANAGER */ + #ifdef CONFIG_COMMON_LIBC_MALLOC #if (CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE != 0) @@ -106,8 +120,8 @@ static POOL_SECTION unsigned char __aligned(HEAP_ALIGN) malloc_arena[HEAP_SIZE]; extern char _heap_sentry[]; # define HEAP_SIZE ROUND_DOWN((POINTER_TO_UINT(_heap_sentry) - HEAP_BASE), HEAP_ALIGN) # else -# define HEAP_SIZE ROUND_DOWN((KB((size_t) CONFIG_SRAM_SIZE) - \ - ((size_t) HEAP_BASE - (size_t) CONFIG_SRAM_BASE_ADDRESS)), HEAP_ALIGN) +# define HEAP_SIZE ROUND_DOWN((RAM_SIZE - \ + ((size_t) HEAP_BASE - (size_t) RAM_ADDR)), HEAP_ALIGN) # endif /* else CONFIG_XTENSA */ # endif /* else CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE > 0 */ diff --git a/lib/os/Kconfig.heap b/lib/os/Kconfig.heap index b913d6100dc..f6e8d93ae50 100644 --- a/lib/os/Kconfig.heap +++ b/lib/os/Kconfig.heap @@ -51,7 +51,7 @@ config HEAP_LISTENER choice prompt "Supported heap sizes" depends on !64BIT - default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) + default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) && !PARTITION_MANAGER_ENABLED default SYS_HEAP_AUTO help Heaps using reduced-size chunk headers can accommodate so called diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index 3058f402d73..c4c75bb48c4 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1054,7 +1054,12 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ + .storage_dev = (void *) \ + COND_CODE_1(USE_PARTITION_MANAGER, \ + (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ + (FIXED_PARTITION_ID(littlefs_storage)), \ + (FIXED_PARTITION_ID(storage)))), \ + (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index a74e46b8520..9996e1d74d9 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,8 +13,35 @@ extern "C" { #endif +#if CONFIG_PARTITION_MANAGER_ENABLED + +#include "pm_config.h" + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) +#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE +#else +/* The current image is a child image in a different domain than the image + * which defined the required values. To reach the values of the parent domain + * we use the 'PM__' variant of the define. + */ +#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ + +#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ + +#else + +#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) +#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) + +#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 From 16d6edb4367f02f14e63706ed22ff6901796ab6f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 28 Sep 2023 11:10:55 +0000 Subject: [PATCH 4426/4498] [nrf noup] mgmt/MCUmgr/grp/img: Move out label to make compiler happy Move it inside ifdef. (cherry picked from commit 2fb8d761dbe3aeecc9285205cb9760701134463a) (cherry picked from commit 45ac1f809fef282566c124dc676c951428d707bc) Signed-off-by: Dominik Ermel --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 0968694c614..61515c14655 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -290,13 +290,14 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) return_slot = other_slot; } } +out: + #else if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &over) < 0) { return_slot = other_slot; } #endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ -out: if (type != NULL) { *type = lt; } From caae0dffc7de62bbe7188c85b92ba83ac05b44c8 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Thu, 26 Oct 2023 15:53:52 +0200 Subject: [PATCH 4427/4498] [nrf noup] testspec: remove HomeKit from NCS HomeKit Accessory Development Kit has been deprecated and removed from NCS. Signed-off-by: Mariusz Poslinski (cherry picked from commit fabddf3a622625f39a71b9bb0377569e2fe230be) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 62b92e74d0f..c01ae703adf 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -131,17 +131,6 @@ "CI-rs-test": - "**/*" -"CI-homekit-test": - - "modules/openthread/**/*" - - "samples/bluetooth/hci_rpmsg/**/*" - - "soc/arm/nordic_nrf/**/*" - - "subsys/net/**/*" - - "subsys/settings/**/*" - - any: - - "subsys/bluetooth/**/*" - - "!subsys/bluetooth/mesh/**/*" - - "!subsys/bluetooth/audio/**/*" - "CI-thread-test": - "include/zephyr/net/**/*" - "modules/mbedtls/**/*" From fe461000fe30fd556bc9aca96314775e74c723e6 Mon Sep 17 00:00:00 2001 From: Alexander Svensen Date: Mon, 6 Nov 2023 10:39:08 +0100 Subject: [PATCH 4428/4498] [nrf noup] testspec: Add audio - Add filter for audio tests Signed-off-by: Alexander Svensen (cherry picked from commit 2b1d418a6c8b17e028204bbefe4500f0286d46d4) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index c01ae703adf..007f4307aa9 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -218,3 +218,25 @@ - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" - "!subsys/bluetooth/audio/**/*" + +"CI-audio-test": + - "boards/arm/nrf5340_audio_dk_nrf5340/**/*" + - "drivers/flash/**/*" + - "drivers/spi/**/*" + - "drivers/gpio/**/*" + - "drivers/i2c/**/*" + - "drivers/watchdog/**/*" + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/bluetooth/audio/**/*" + - "subsys/bluetooth/host/**/*" + - "subsys/dfu/**/*" + - "subsys/fs/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "subsys/sd/**/*" + - "subsys/storage/**/*" + - "subsys/task_wdt/**/*" + - "subsys/usb/**/*" + - "subsys/zbus/**/*" From 22735e0e29f6331a97202d2aa284377d0f6a998a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ga=C5=82da?= Date: Mon, 6 Nov 2023 18:44:48 +0100 Subject: [PATCH 4429/4498] [nrf noup] ci: Add CI-run-zephyr-twister test spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI-run-zephyr-twister is used to determine if twister tests from sdk-zephyr should be run on PR to sdk-nrf repository. Signed-off-by: Jan Gałda (cherry picked from commit ede86123951b7f824f91f6ebd1ea15f307f9a208) Signed-off-by: Dominik Ermel --- .github/test-spec.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 007f4307aa9..789f1a4e235 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -1,4 +1,19 @@ # This is the Jenkins ci variant of the .github/labler.yaml + +"CI-run-zephyr-twister": + - any: + - "!.github/**/*" + - "!doc/**/*" + - "!CODEOWNERS" + - "!LICENSE" + - "!**/*.rst" + - "!VERSION" + - "!submanifests/**/*" + - "!MAINTAINERS.yml" + - "!version.h.in" + - "!Jenkinsfile" + - "!**/*.md" + "CI-iot-zephyr-lwm2m-test": - "drivers/console/**/*" - "drivers/flash/**/*" From 36710dee098619426dcadcecdb7f217c12d01910 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 9 Nov 2023 13:30:15 +0100 Subject: [PATCH 4430/4498] [nrf noup] Bluetooth: Mesh: adapt SDC specific api usage Usage of the Softdevice specific api has been adapted to upstream adv changes. Signed-off-by: Aleksandr Khromykh (cherry picked from commit 533baa16b5a6750cf59a7ce7257bc09bcac09637) Signed-off-by: Dominik Ermel --- subsys/bluetooth/mesh/adv_ext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 525e5ee5066..fe9fc4fd403 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -529,8 +529,8 @@ int bt_mesh_adv_enable(void) if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tag == BT_MESH_FRIEND_ADV) { - err = set_adv_randomness(adv->instance->handle, 0); + advs[i].tags == BT_MESH_ADV_TAG_BIT_FRIEND) { + err = set_adv_randomness(advs[i].instance->handle, 0); if (err) { LOG_ERR("Failed to set zero randomness: %d", err); } From d0b22f5deb110cbe508a847faf79d4b7add5b4bf Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Wed, 15 Nov 2023 12:55:40 +0100 Subject: [PATCH 4431/4498] [nrf noup] boards: arm: nrf9131ek: enable tfm This patch backports the nrf9131ek to a time before tfm was refactored. To be reverted when TF-M is updated. Signed-off-by: Maximilian Deubel (cherry picked from commit 6755c4785640afb19f4973563f9737eece9f57c4) Signed-off-by: Dominik Ermel --- boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig index 0ece4f9a2ac..378a58fb6e3 100644 --- a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig +++ b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig @@ -8,6 +8,22 @@ if BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS config BOARD default "nrf9131ek_nrf9131" + +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF9131EK_NRF9131_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- From 26cebfca894cccafb2237dfdc0eaf7fde354f457 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 21 Nov 2023 19:02:47 +0100 Subject: [PATCH 4432/4498] [nrf fromlist] tfm: Remove limitation of enabling FP when build TF-M NS application Remove limitation of enabling FP when building TF-M NS application. FP support have been fixed in the tf-m-tests repository for NS application. Board support for NS executable may still be lacking for some boards. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/65537 Signed-off-by: Joakim Andersson (cherry picked from commit 90a72daae2c8715d760d974a7d294aa2eb6b38c4) Signed-off-by: Dominik Ermel --- arch/arm/core/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index 75a64ea90eb..4afe6c06ab5 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -268,9 +268,6 @@ choice config FP_HARDABI bool "Floating point Hard ABI" - # TF-M build system does not build the NS app and libraries correctly with Hard ABI. - # This limitation should be removed in the next TF-M synchronization. - depends on !TFM_BUILD_NS help This option selects the Floating point ABI in which hardware floating point instructions are generated and uses FPU-specific calling From 03b90ac09da07502981123dc46a63a8cb283b7ab Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 10:29:53 +0530 Subject: [PATCH 4433/4498] [nrf fromlist] wifi: shell: Fix unbalanced braces Fix the typo in braces for help. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit e3429fadeece82ab46940a23edf4dc0954d9a718) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5f7eb5ba0ee..c50175e086f 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1673,15 +1673,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" - "[-i : Interface index - optional argument\n" - "[-s : Station mode.\n" - "[-m : Monitor mode.\n" - "[-p : Promiscuous mode.\n" - "[-t : TX-Injection mode.\n" - "[-a : AP mode.\n" - "[-k : Softap mode.\n" - "[-h : Help.\n" - "[-g : Get current mode for a specific interface index.\n" + "[-i] : Interface index - optional argument\n" + "[-s] : Station mode.\n" + "[-m] : Monitor mode.\n" + "[-p] : Promiscuous mode.\n" + "[-t] : TX-Injection mode.\n" + "[-a] : AP mode.\n" + "[-k] : Softap mode.\n" + "[-h] : Help.\n" + "[-g] : Get current mode for a specific interface index.\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" @@ -1692,14 +1692,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" "parameters:" - "[-i : Interface index - optional argument.\n" - "[-a : Enable all packet filter modes\n" - "[-m : Enable management packets to allowed up the stack.\n" - "[-c : Enable control packets to be allowed up the stack.\n" - "[-d : Enable Data packets to be allowed up the stack.\n" - "[-g : Get current filter settings for a specific interface index.\n" - "<-b : Capture length buffer size for each packet to be captured - optional argument.\n" - "<-h : Help.\n" + "[-i] : Interface index - optional argument.\n" + "[-a] : Enable all packet filter modes\n" + "[-m] : Enable management packets to allowed up the stack.\n" + "[-c] : Enable control packets to be allowed up the stack.\n" + "[-d] : Enable Data packets to be allowed up the stack.\n" + "[-g] : Get current filter settings for a specific interface index.\n" + "<-b> : Capture length buffer size for each packet to be captured - optional argument.\n" + "<-h> : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" @@ -1710,10 +1710,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" "parameters:" - "[-i : Interface index - optional argument.\n" - "[-c : Set a specific channel number to the lower layer.\n" - "[-g : Get current set channel number from the lower layer.\n" - "[-h : Help.\n" + "[-i] : Interface index - optional argument.\n" + "[-c] : Set a specific channel number to the lower layer.\n" + "[-g] : Get current set channel number from the lower layer.\n" + "[-h] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" From ea492ab1190b2fd08cba1119b40ee525bd0455ed Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 10:36:06 +0530 Subject: [PATCH 4434/4498] [nrf fromlist] wifi: shell: Fix brackets type for optional params General notation for Optional params is to use square brackets. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit ad503caacd6004efb4f386ce526f8f1f8e1952a0) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index c50175e086f..64f125dea01 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1631,11 +1631,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" - "\n" - "\n" - "\n" + "[channel number: 0 means all]\n" + "[PSK: valid only for secure SSIDs]\n" + "[Security type: valid only for secure SSIDs]\n" "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" - "\n" + "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect), SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", @@ -1667,7 +1667,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" - "-f: Force to use this regulatory hint over any other regulatory hints\n" + "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), SHELL_CMD(mode, NULL, "mode operational setting\n" From b16198a61fb3225013e1b2a0791ed2289ff978c0 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 10:37:21 +0530 Subject: [PATCH 4435/4498] [nrf fromlist] wifi: shell: Fix PS mode help There is only a single parameter called "mode" that takes two possible values. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit 9c2c52a44a28f974fa1280b35f06875b067c69ea) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 64f125dea01..cd3390828d1 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1644,8 +1644,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_ps), SHELL_CMD_ARG(ps_mode, NULL, - "\n" - "", + "\n", cmd_wifi_ps_mode, 2, 0), @@ -1733,8 +1732,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD_ARG(ps_wakeup_mode, NULL, - " : Set PS wake up mode to DTIM interval\n" - " : Set PS wake up mode to listen interval", + "\n", cmd_wifi_ps_wakeup_mode, 2, 0), From d20bbab16aec2aaca8ce716723c3fc641b9cedf8 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 10:40:25 +0530 Subject: [PATCH 4436/4498] [nrf fromlist] wifi: shell: Add missing security options Newly added security types are missing from the help. Also, now that we have two variants of PSK, use the prefix to disambiguate. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit 7c23186c1282125353cacca44899f030706b2b68) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index cd3390828d1..767ac3eaf05 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1634,7 +1634,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[channel number: 0 means all]\n" "[PSK: valid only for secure SSIDs]\n" "[Security type: valid only for secure SSIDs]\n" - "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" + "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect), From 4ffdc9cb53bf752a13a6ee1ef6ad3f08b96159d1 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 10:57:40 +0530 Subject: [PATCH 4437/4498] [nrf fromlist] wifi: shell: Enforce argument count checks Use the proper API to enforce argument count checks as per mandatory or optional params. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit bebc385d82e4fd230ac7afd0d580a8045624e921) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 74 ++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 767ac3eaf05..d0cd0551897 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1598,37 +1598,43 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg } SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, - SHELL_CMD(disable, NULL, + SHELL_CMD_ARG(disable, NULL, "Disable Access Point mode", - cmd_wifi_ap_disable), - SHELL_CMD(enable, NULL, " [channel] [PSK]", - cmd_wifi_ap_enable), + cmd_wifi_ap_disable, + 1, 0), + SHELL_CMD_ARG(enable, NULL, " [channel] [PSK]", + cmd_wifi_ap_enable, + 2, 1), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, - SHELL_CMD(quick_setup, NULL, " Start a TWT flow with defaults:\n" + SHELL_CMD_ARG(quick_setup, NULL, " Start a TWT flow with defaults:\n" " \n", - cmd_wifi_twt_setup_quick), - SHELL_CMD(setup, NULL, " Start a TWT flow:\n" + cmd_wifi_twt_setup_quick, + 3, 0), + SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " " \n", - cmd_wifi_twt_setup), - SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" + cmd_wifi_twt_setup, + 11, 0), + SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" " \n", - cmd_wifi_twt_teardown), - SHELL_CMD(teardown_all, NULL, " Teardown all TWT flows\n", - cmd_wifi_twt_teardown_all), + cmd_wifi_twt_teardown, + 5, 0), + SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows\n", + cmd_wifi_twt_teardown_all, + 1, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands", NULL), - SHELL_CMD(connect, NULL, + SHELL_CMD_ARG(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" "[channel number: 0 means all]\n" @@ -1637,18 +1643,21 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", - cmd_wifi_connect), - SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", - cmd_wifi_disconnect), - SHELL_CMD(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", - cmd_wifi_ps), + cmd_wifi_connect, + 2, 5), + SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", + cmd_wifi_disconnect, + 1, 0), + SHELL_CMD_ARG(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", + cmd_wifi_ps, + 1, 1), SHELL_CMD_ARG(ps_mode, NULL, "\n", cmd_wifi_ps_mode, 2, 0), - SHELL_CMD(scan, NULL, + SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" "OPTIONAL PARAMETERS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" @@ -1659,17 +1668,19 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" "[-h, --help] : Print out the help for the scan command.", - cmd_wifi_scan), - SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), - SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), + cmd_wifi_scan, + 1, 8), + SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats, 1, 0), + SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status, 1, 0), SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), - SHELL_CMD(reg_domain, NULL, + SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", - cmd_wifi_reg_domain), - SHELL_CMD(mode, NULL, "mode operational setting\n" + cmd_wifi_reg_domain, + 2, 1), + SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" "[-i] : Interface index - optional argument\n" @@ -1685,8 +1696,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" "wifi mode -i1 -sp\n", - cmd_wifi_mode), - SHELL_CMD(packet_filter, NULL, "mode filter setting\n" + cmd_wifi_mode, + 1, 9), + SHELL_CMD_ARG(packet_filter, NULL, "mode filter setting\n" "This command is used to set packet filter setting when\n" "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" @@ -1703,8 +1715,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" "wifi packet_filter -i1 -md\n", - cmd_wifi_packet_filter), - SHELL_CMD(channel, NULL, "wifi channel setting\n" + cmd_wifi_packet_filter, + 1, 8), + SHELL_CMD_ARG(channel, NULL, "wifi channel setting\n" "This command is used to set the channel when\n" "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" @@ -1717,7 +1730,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" "wifi -i1 -c5\n", - cmd_wifi_channel), + cmd_wifi_channel, + 1, 4), SHELL_CMD_ARG(ps_timeout, NULL, " - PS inactivity timer(in ms)", From 893e58ca65abc6f5da237733ef7a4ebdecb0bc29 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 1 Dec 2023 11:06:51 +0530 Subject: [PATCH 4438/4498] [nrf fromlist] wifi: shell: Add long arguments to help Long arguments are handy for new users. Also use hyphen's rather than underscore to follow the convention. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66005 Signed-off-by: Chaitanya Tata (cherry picked from commit f721e835805a6e6bae6e7c491f3d4369d64412e4) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d0cd0551897..c5b8f60d933 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1275,10 +1275,10 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, {"sta", no_argument, 0, 's'}, {"monitor", no_argument, 0, 'm'}, - {"TX-injection", no_argument, 0, 't'}, + {"tx-injection", no_argument, 0, 't'}, {"promiscuous", no_argument, 0, 'p'}, {"ap", no_argument, 0, 'a'}, {"softap", no_argument, 0, 'k'}, @@ -1385,7 +1385,7 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, {"channel", required_argument, 0, 'c'}, {"get", no_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, @@ -1491,8 +1491,8 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, - {"capture_len", optional_argument, 0, 'b'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, + {"capture-len", optional_argument, 0, 'b'}, {"all", no_argument, 0, 'a'}, {"mgmt", no_argument, 0, 'm'}, {"ctrl", no_argument, 0, 'c'}, @@ -1683,15 +1683,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" - "[-i] : Interface index - optional argument\n" - "[-s] : Station mode.\n" - "[-m] : Monitor mode.\n" - "[-p] : Promiscuous mode.\n" - "[-t] : TX-Injection mode.\n" - "[-a] : AP mode.\n" - "[-k] : Softap mode.\n" - "[-h] : Help.\n" - "[-g] : Get current mode for a specific interface index.\n" + "[-i, --if-index ] : Interface index.\n" + "[-s, --sta] : Station mode.\n" + "[-m, --monitor] : Monitor mode.\n" + "[-p, --promiscuous] : Promiscuous mode.\n" + "[-t, --tx-injection] : TX-Injection mode.\n" + "[-a, --ap] : AP mode.\n" + "[-k, --softap] : Softap mode.\n" + "[-h, --help] : Help.\n" + "[-g, --get] : Get current mode for a specific interface index.\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" @@ -1703,14 +1703,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" "parameters:" - "[-i] : Interface index - optional argument.\n" - "[-a] : Enable all packet filter modes\n" - "[-m] : Enable management packets to allowed up the stack.\n" - "[-c] : Enable control packets to be allowed up the stack.\n" - "[-d] : Enable Data packets to be allowed up the stack.\n" - "[-g] : Get current filter settings for a specific interface index.\n" - "<-b> : Capture length buffer size for each packet to be captured - optional argument.\n" - "<-h> : Help.\n" + "[-i, --if-index ] : Interface index.\n" + "[-a, --all] : Enable all packet filter modes\n" + "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" + "[-c, --ctrl] : Enable control packets to be allowed up the stack.\n" + "[-d, --data] : Enable Data packets to be allowed up the stack.\n" + "[-g, --get] : Get current filter settings for a specific interface index.\n" + "[-b, --capture-len ] : Capture length buffer size for each packet to be captured\n" + "[-h, --help] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" @@ -1722,10 +1722,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" "parameters:" - "[-i] : Interface index - optional argument.\n" - "[-c] : Set a specific channel number to the lower layer.\n" - "[-g] : Get current set channel number from the lower layer.\n" - "[-h] : Help.\n" + "[-i, --if-index ] : Interface index.\n" + "[-c, --channel ] : Set a specific channel number to the lower layer.\n" + "[-g, --get] : Get current set channel number from the lower layer.\n" + "[-h, --help] : Help.\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" From 130824afa4d94bf56a6c3ea9e83384744eb7d9c4 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 21 Nov 2023 11:01:17 +0100 Subject: [PATCH 4439/4498] [nrf fromtree] twister: pytest: Add --pytest-args to Twister command line Extend Twister command line with --pytest-args. This parameter is passed to pytest subprocess. It allows to select a specific testcase from a test suite. Signed-off-by: Grzegorz Chwierut (cherry picked from commit a1698b691d9bfd25dfd70fc1ed42e819cdec61a3) (cherry picked from commit 9566a94fc5175eae833af9ec264f68bcf16bc3f6) Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 10 +++ .../pylib/twister/twisterlib/environment.py | 5 ++ scripts/pylib/twister/twisterlib/harness.py | 19 ++++-- .../pytest_integration/test_harness_pytest.py | 66 +++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index e644882191e..f3db6fcee89 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -56,6 +56,16 @@ Pytest scans the given locations looking for tests, following its default `discovery rules `_ One can also pass some extra arguments to the pytest from yaml file using ``pytest_args`` keyword under ``harness_config``, e.g.: ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. +There is also an option to pass ``--pytest-args`` through Twister command line parameters. +This can be particularly useful when one wants to select a specific testcase from a test suite. +For instance, one can use a command: + +.. code-block:: console + + $ ./scripts/twister --platform native_sim -T samples/subsys/testsuite/pytest/shell \ + -s samples/subsys/testsuite/pytest/shell/sample.pytest.shell \ + --pytest-args='-k test_shell_print_version' + Helpers & fixtures ================== diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 86965f1f9cf..b7e11406cd4 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -216,6 +216,11 @@ def add_parse_arguments(parser = None): and 'fifo_loop' is a name of a function found in main.c without test prefix. """) + parser.add_argument("--pytest-args", + help="""Pass additional arguments to the pytest subprocess. This parameter + will override the pytest_args from the harness_config in YAML file. + """) + valgrind_asan_group.add_argument( "--enable-valgrind", action="store_true", help="""Run binary through valgrind and check for several memory access diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 052def7162a..dece1673c7a 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -309,8 +309,9 @@ def pytest_run(self, timeout): def generate_command(self): config = self.instance.testsuite.harness_config + handler: Handler = self.instance.handler pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] - pytest_args = config.get('pytest_args', []) if config else [] + pytest_args_yaml = config.get('pytest_args', []) if config else [] pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None command = [ 'pytest', @@ -324,12 +325,19 @@ def generate_command(self): ] command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) - command.extend(pytest_args) + + if handler.options.pytest_args: + command.append(handler.options.pytest_args) + if pytest_args_yaml: + logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' + 'in the command line will override the pytest_args defined ' + f'in the YAML file {pytest_args_yaml}') + else: + command.extend(pytest_args_yaml) + if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') - handler: Handler = self.instance.handler - if handler.options.verbose > 1: command.extend([ '--log-cli-level=DEBUG', @@ -489,6 +497,9 @@ def _parse_report_file(self, report): tc.status = 'error' tc.reason = elem.get('message') tc.output = elem.text + else: + self.state = 'skipped' + self.instance.reason = 'No tests collected' class Gtest(Harness): diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index 150980059b3..fc60b99e0d1 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -25,6 +25,7 @@ def testinstance() -> TestInstance: testinstance.handler = mock.Mock() testinstance.handler.options = mock.Mock() testinstance.handler.options.verbose = 1 + testinstance.handler.options.pytest_args = None testinstance.handler.type_str = 'native' return testinstance @@ -67,6 +68,18 @@ def test_pytest_command_extra_args(testinstance: TestInstance): assert c in command +def test_pytest_command_extra_args_in_options(testinstance: TestInstance): + pytest_harness = Pytest() + pytest_args_from_yaml = '-k test_from_yaml' + pytest_args_from_cmd = '-k test_from_cmd' + testinstance.testsuite.harness_config['pytest_args'] = [pytest_args_from_yaml] + testinstance.handler.options.pytest_args = pytest_args_from_cmd + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + assert pytest_args_from_cmd in command + assert pytest_args_from_yaml not in command + + @pytest.mark.parametrize( ('pytest_root', 'expected'), [ @@ -222,3 +235,56 @@ def test_skip_2(): assert len(testinstance.testcases) == 2 for tc in testinstance.testcases: assert tc.status == "skipped" + + +def test_if_report_with_filter(pytester, testinstance: TestInstance): + test_file_content = textwrap.dedent(""" + import pytest + def test_A(): + pass + def test_B(): + pass + """) + test_file = pytester.path / 'test_filter.py' + test_file.write_text(test_file_content) + report_file = pytester.path / 'report.xml' + result = pytester.runpytest( + str(test_file), + '-k', 'test_B', + f'--junit-xml={str(report_file)}' + ) + result.assert_outcomes(passed=1) + assert report_file.is_file() + + pytest_harness = Pytest() + pytest_harness.configure(testinstance) + pytest_harness.report_file = report_file + pytest_harness._update_test_status() + assert pytest_harness.state == "passed" + assert testinstance.status == "passed" + assert len(testinstance.testcases) == 1 + + +def test_if_report_with_no_collected(pytester, testinstance: TestInstance): + test_file_content = textwrap.dedent(""" + import pytest + def test_A(): + pass + """) + test_file = pytester.path / 'test_filter.py' + test_file.write_text(test_file_content) + report_file = pytester.path / 'report.xml' + result = pytester.runpytest( + str(test_file), + '-k', 'test_B', + f'--junit-xml={str(report_file)}' + ) + result.assert_outcomes(passed=0) + assert report_file.is_file() + + pytest_harness = Pytest() + pytest_harness.configure(testinstance) + pytest_harness.report_file = report_file + pytest_harness._update_test_status() + assert pytest_harness.state == "skipped" + assert testinstance.status == "skipped" From 2837a3c6bd07e5920bfd0dcbab9392086f1769f3 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 27 Nov 2023 17:09:07 -0800 Subject: [PATCH 4440/4498] [nrf fromtree] scripts/pylib/twister/twisterlib: Support multiple `--pytest-args` One can not even replace sucessfully pytest basic sample `pytest-args` with command line "--pytest-args", as all it does is to append a single string to current list of commands, making it impossible to send several arguments. This patch fixes that by allowing several instances of `--pytest-args` to compose the whole list of arguments to be passed to pytest. Signed-off-by: Ederson de Souza (cherry picked from commit 10ec2b129c9102a867d1ce26eb8cb986f95b6d98) (cherry picked from commit ad95bc81b8b9d44431c092a3cee4e7204dfceba4) Signed-off-by: Dominik Ermel --- doc/develop/test/pytest.rst | 2 ++ .../pylib/twister/twisterlib/environment.py | 3 ++- scripts/pylib/twister/twisterlib/harness.py | 19 ++++++++++--------- .../pytest_integration/test_harness_pytest.py | 5 +++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index f3db6fcee89..f6ba54fa52e 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -67,6 +67,8 @@ For instance, one can use a command: --pytest-args='-k test_shell_print_version' +Note that ``--pytest-args`` can be passed multiple times to pass several arguments to the pytest. + Helpers & fixtures ================== diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index b7e11406cd4..16e19c85fec 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -216,7 +216,8 @@ def add_parse_arguments(parser = None): and 'fifo_loop' is a name of a function found in main.c without test prefix. """) - parser.add_argument("--pytest-args", + parser.add_argument( + "--pytest-args", action="append", help="""Pass additional arguments to the pytest subprocess. This parameter will override the pytest_args from the harness_config in YAML file. """) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index dece1673c7a..8b8ad92fc51 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -326,15 +326,6 @@ def generate_command(self): command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) - if handler.options.pytest_args: - command.append(handler.options.pytest_args) - if pytest_args_yaml: - logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' - 'in the command line will override the pytest_args defined ' - f'in the YAML file {pytest_args_yaml}') - else: - command.extend(pytest_args_yaml) - if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') @@ -354,6 +345,16 @@ def generate_command(self): command.append('--device-type=custom') else: raise PytestHarnessException(f'Handling of handler {handler.type_str} not implemented yet') + + if handler.options.pytest_args: + command.extend(handler.options.pytest_args) + if pytest_args_yaml: + logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' + 'in the command line will override the pytest_args defined ' + f'in the YAML file {pytest_args_yaml}') + else: + command.extend(pytest_args_yaml) + return command def _generate_parameters_for_hardware(self, handler: Handler): diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index fc60b99e0d1..befd384be37 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -71,12 +71,13 @@ def test_pytest_command_extra_args(testinstance: TestInstance): def test_pytest_command_extra_args_in_options(testinstance: TestInstance): pytest_harness = Pytest() pytest_args_from_yaml = '-k test_from_yaml' - pytest_args_from_cmd = '-k test_from_cmd' + pytest_args_from_cmd = ['-k', 'test_from_cmd'] testinstance.testsuite.harness_config['pytest_args'] = [pytest_args_from_yaml] testinstance.handler.options.pytest_args = pytest_args_from_cmd pytest_harness.configure(testinstance) command = pytest_harness.generate_command() - assert pytest_args_from_cmd in command + assert pytest_args_from_cmd[0] in command + assert pytest_args_from_cmd[1] in command assert pytest_args_from_yaml not in command From 85997eb5ce6d0dcebdc02488e347b0dc59aa2303 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Fri, 1 Dec 2023 14:53:27 +0100 Subject: [PATCH 4441/4498] [nrf fromlist] manifest: hal_nordic: Update revision with fixed workaround in nrfx_qspi Pulls update in nrfx_qspi driver with fixed order of applying workaround for anomaly 215 on nRF52840 and anomaly 43 on nRF5340. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66034 Signed-off-by: Adam Wojasinski (cherry picked from commit e0dc936a4af5550f15d9e37ab9b44db5de452ee0) Signed-off-by: Dominik Ermel --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 14847109194..ed84e713620 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 56e0b052dff311c2f8eb08c6804e60fc79feb56f + revision: b9633ecea67bf52925d4c61455046223b46402b1 path: modules/hal/nordic groups: - hal From 414a63955a3e0e60301b1970266b7c659553eff3 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Tue, 5 Dec 2023 13:48:37 +0100 Subject: [PATCH 4442/4498] [nrf fromtree] net: openthread: Openthread upmerge to `4ed44bc` This commit bumps openthread commit to `4ed44bc` and implements `CONFIG_OPENTHREAD_MULTIPAN_RCP` option. Signed-off-by: Przemyslaw Bida (cherry picked from commit 8f2b7a121bbf7b64fdf46c5c19231a12f96c4166) (cherry picked from commit 919457f5c1d9d491033b23efcf77197d687422a6) Signed-off-by: Dominik Ermel --- modules/openthread/CMakeLists.txt | 6 ++++++ modules/openthread/Kconfig.features | 3 +++ west.yml | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 8afa1aec440..646b086ef1e 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -340,6 +340,12 @@ else() set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) endif() +if(CONFIG_OPENTHREAD_MULTIPAN_RCP) + set(OT_MULTIPAN_RCP ON CACHE BOOL "Enable Multi-PAN RCP" FORCE) +else() + set(OT_MULTIPAN_RCP OFF CACHE BOOL "Enable Multi-PAN RCP" FORCE) +endif() + if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index bd8a05ed9b9..2be5332cde3 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -218,6 +218,9 @@ config OPENTHREAD_MLR help Enable Multicast Listener Registration support for Thread 1.2 +config OPENTHREAD_MULTIPAN_RCP + bool "OpenThread multipan rcp" + config OPENTHREAD_MULTIPLE_INSTANCE bool "OpenThread multiple instances" diff --git a/west.yml b/west.yml index ed84e713620..c99118074eb 100644 --- a/west.yml +++ b/west.yml @@ -301,7 +301,7 @@ manifest: revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread - revision: 193e77e40ec2387d458eaebd1e03902d86f484a5 + revision: 4ed44bc7d58d9a98c6cca13a50d38129045ab3df path: modules/lib/openthread - name: percepio path: modules/debug/percepio From 8e3a9faff9e21e2f92bc3f7a01bd77311c58087c Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 7 Dec 2023 15:05:13 +0100 Subject: [PATCH 4443/4498] [nrf fromlist] soc: nordic_nrf: Enable the TF-M NS storage partition for nordic boards Enable the TF-M NS storage partition for nordic boards. This partition is otherwise not used, and configured as secure. Fixes: #59376 Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66279 Signed-off-by: Joakim Andersson (cherry picked from commit 462ad3659295cc639b3c159573136731141a06cc) Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/CMakeLists.txt | 4 ++++ soc/arm/nordic_nrf/Kconfig | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 47364b35ffb..3b097d73569 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -25,4 +25,8 @@ if(CONFIG_BUILD_WITH_TFM) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} ) + + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DNRF_NS_STORAGE=${CONFIG_TFM_NRF_NS_STORAGE} + ) endif() diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 19e49c05454..0372492cd7d 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -45,6 +45,10 @@ config TFM_LOG_LEVEL_SILENCE Disable TF-M secure output if the uart1 node has not assigned GPIO pins using pinctrl. +config TFM_NRF_NS_STORAGE + bool "TF-M non-secure storage partition" + default y + endif # BUILD_WITH_TFM From 90826581f1ee32b99f1cafdffc2e634a495d8ee3 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Mon, 4 Dec 2023 15:27:08 +0100 Subject: [PATCH 4444/4498] [nrf noup] soc: arm: nRF53: Add SPU Flash/RAM alignment TF-M will uses SPU alignment during build time to make sure all partitions can be locked down with the SPU. So adding them for nRF53 Signed-off-by: Markus Swarowsky (cherry picked from commit 1f49692993f6ad7f1ee1e19ff27d3ff56659b23e) Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 3afcd96f70d..f72ae5ab004 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -104,12 +104,26 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral +config NRF_SPU_FLASH_REGION_ALIGNMENT + hex + default 0x4000 + help + FLASH regions must be aligned to this value due to SPU HW + limitations. + config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral +config NRF_SPU_RAM_REGION_ALIGNMENT + hex + default 0x2000 + help + RAM regions must be aligned to this value due to SPU HW + limitations. + config SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 bool depends on NRF_SOC_SECURE_SUPPORTED From 83be41dde2e00776f02e583d8e6e55743b6c2ef7 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Mon, 4 Dec 2023 15:27:14 +0100 Subject: [PATCH 4445/4498] [nrf noup] soc: arm: nRF91: Add SPU Flash/RAM alignment TF-M will uses SPU alignment during build time to make sure all partitions can be locked down with the SPU. So adding them for nRF91 Signed-off-by: Markus Swarowsky (cherry picked from commit 89be4330a38498731fe612f1343624fc3d0a098e) Signed-off-by: Dominik Ermel --- soc/arm/nordic_nrf/nrf91/Kconfig.series | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 1be69c377e5..08d36e5b48c 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -27,9 +27,23 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral +config NRF_SPU_FLASH_REGION_ALIGNMENT + hex + default 0x8000 + help + FLASH regions must be aligned to this value due to SPU HW + limitations. + config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral + +config NRF_SPU_RAM_REGION_ALIGNMENT + hex + default 0x2000 + help + RAM regions must be aligned to this value due to SPU HW + limitations. endif From 80251a66e6ddacbd9fc2855f2ae5fd25c0e1a143 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 25 Aug 2023 13:44:29 +0200 Subject: [PATCH 4446/4498] [nrf fromtree] tfm: Harded build against TF-M built with unsecure keys Introduce Kconfig option in zephyr build system that reflects the TF-M cmake config variable with the same default value for dummy provisioning and have it satisfy the IAK present requirement. This configuration is not suitable for production, and by having this in zephyr configuration we can have this as part of the hardened configuration check. Signed-off-by: Joakim Andersson (cherry picked from commit 25787e2df66aef6979503d613c292043ac5f6291) (cherry picked from commit ec48dcb2ee4973bee58fbe610750fe62635a0e3f) Signed-off-by: Dominik Ermel --- boards/arm/b_u585i_iot02a/Kconfig.defconfig | 7 +++++++ modules/trusted-firmware-m/CMakeLists.txt | 17 ++++++++++++++++- modules/trusted-firmware-m/Kconfig.tfm | 11 +++++++++++ scripts/kconfig/hardened.csv | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index ae1e57aba8e..e8224106dae 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -16,4 +16,11 @@ config SPI_STM32_INTERRUPT config USE_DT_CODE_PARTITION default y if TRUSTED_EXECUTION_NONSECURE +if BUILD_WITH_TFM + +config TFM_DUMMY_PROVISIONING + default n + +endif # BUILD_WITH_TFM + endif # BOARD_B_U585I_IOT02A diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 177a47e28d6..ad1109d849b 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -95,6 +95,12 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_NUMBER=${CONFIG_TFM_MCUBOOT_IMAGE_NUMBER}) endif() + if (CONFIG_TFM_DUMMY_PROVISIONING) + list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=ON) + else() + list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=OFF) + endif() + if (CONFIG_TFM_EXCEPTION_INFO_DUMP) list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=ON) else() @@ -579,4 +585,13 @@ if (CONFIG_BUILD_WITH_TFM) ${MERGED_FILE} ) endif() -endif() + + if(CONFIG_TFM_DUMMY_PROVISIONING) + message(WARNING + "TFM_DUMMY_PROVISIONING is enabled: + The device will be provisioned using dummy keys and is NOT secure! + This is not suitable for production" + ) + endif() + +endif() # CONFIG_BUILD_WITH_TFM diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index b635347b6e1..fed6ae4f485 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -177,6 +177,17 @@ config TFM_PARTITION_PLATFORM_CUSTOM_REBOOT Instead the application will have to override the weak ARM implementation of sys_arch_reset(). +config TFM_DUMMY_PROVISIONING + bool "Provision with dummy values. NOT to be used in production" + default y + help + If this option is enabled (as it is by default), a set of dummy + keys / data will be provisioned. The dummy IAK matches the IAK tested + by the TF-M tests, and the dummy bl2 ROTPKs match the dummy bl2 keys + used by default. + This option MUST not be used in production hardware, as the keys are + insecure. + config TFM_BL2_NOT_SUPPORTED bool help diff --git a/scripts/kconfig/hardened.csv b/scripts/kconfig/hardened.csv index ee95b54b3a7..6cc978f7e56 100644 --- a/scripts/kconfig/hardened.csv +++ b/scripts/kconfig/hardened.csv @@ -39,6 +39,7 @@ TEST_RANDOM_GENERATOR,n TEST_SHELL,n TEST_USERSPACE,n TFM_CMAKE_BUILD_TYPE_DEBUG,n +TFM_DUMMY_PROVISIONING,n THREAD_MONITOR,n THREAD_NAME,n TIMER_RANDOM_GENERATOR,n From cf3cec5e97911a6a1e4b4d1b93b48f2508a46d34 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 25 Aug 2023 13:55:49 +0200 Subject: [PATCH 4447/4498] [nrf fromtree] tfm: Enforce initial attestation with required key provisioned Enforce that the initial attestation partition has the required initial attestation key provisioned. If the initial attestation key (IAK) is not present during boot of TF-M the system will panic during initialization. Signed-off-by: Joakim Andersson (cherry picked from commit 2687376effac881c550e2c568c3d4ad10a67385b) (cherry picked from commit 2ac74ca47b0ae06ff19755985e01b07b150f53b5) Signed-off-by: Dominik Ermel --- boards/arm/b_u585i_iot02a/Kconfig.defconfig | 4 ++++ modules/trusted-firmware-m/Kconfig.tfm | 8 ++++++++ modules/trusted-firmware-m/Kconfig.tfm.partitions | 1 + 3 files changed, 13 insertions(+) diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index e8224106dae..6b3b72554ff 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -18,6 +18,10 @@ config USE_DT_CODE_PARTITION if BUILD_WITH_TFM +# Initial Attestation key provisioned by the BL1 bootloader +config TFM_INITIAL_ATTESTATION_KEY + default y + config TFM_DUMMY_PROVISIONING default n diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index fed6ae4f485..a0d71328540 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -179,6 +179,7 @@ config TFM_PARTITION_PLATFORM_CUSTOM_REBOOT config TFM_DUMMY_PROVISIONING bool "Provision with dummy values. NOT to be used in production" + select TFM_INITIAL_ATTESTATION_KEY default y help If this option is enabled (as it is by default), a set of dummy @@ -188,6 +189,13 @@ config TFM_DUMMY_PROVISIONING This option MUST not be used in production hardware, as the keys are insecure. +config TFM_INITIAL_ATTESTATION_KEY + bool + help + Hidden option to mark that the TF-M platform has an initial + attestation key, which is a requirement for the Initial Attestation + partition. + config TFM_BL2_NOT_SUPPORTED bool help diff --git a/modules/trusted-firmware-m/Kconfig.tfm.partitions b/modules/trusted-firmware-m/Kconfig.tfm.partitions index cd9aaadb1ec..67b46f5328b 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.partitions +++ b/modules/trusted-firmware-m/Kconfig.tfm.partitions @@ -44,6 +44,7 @@ config TFM_PARTITION_CRYPTO config TFM_PARTITION_INITIAL_ATTESTATION bool "Secure partition 'Initial Attestation'" depends on TFM_PARTITION_CRYPTO + depends on TFM_INITIAL_ATTESTATION_KEY default n help Setting this option will cause '-DTFM_PARTITION_INITIAL_ATTESTATION' From de501648fc3071d44bb0b6169c09ad9ed3d71b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 3 Nov 2023 12:08:09 +0100 Subject: [PATCH 4448/4498] [nrf fromtree] drivers: nrf_qspi_nor: Prevent reading status before sending RDPD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After entering the Deep Power-down mode, some flash chips ignore all commands except from the one that releases the chip from the DP mode and it is not possible to successfully read their Status Register then. Since the QSPI peripheral tries to read this register when it is being activated, it consequently fails to send the actual command that would release the flash chip from the DP mode if that is to be done right after QSPI initialization. Prevent this problem by performing the QSPI activation with all pins disconnected. This causes that the Status Register value is read as all zeros and allows the activation to always finish successfully, and the RDPD command to be properly sent. Signed-off-by: Andrzej Głąbek (cherry picked from commit 1727bbcc7046eb5870df7409310d58e0c9483233) (cherry picked from commit 93e398cd1fdd7abb0a6ec347ebaa09f1ff5172ab) Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 28c705f6707..467d0643d48 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -1339,15 +1339,34 @@ static int enter_dpd(const struct device *const dev) static int exit_dpd(const struct device *const dev) { if (IS_ENABLED(DT_INST_PROP(0, has_dpd))) { + nrf_qspi_pins_t pins; + nrf_qspi_pins_t disconnected_pins = { + .sck_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .csn_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io0_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, + }; struct qspi_cmd cmd = { .op_code = SPI_NOR_CMD_RDPD, }; uint32_t t_exit_dpd = DT_INST_PROP_OR(0, t_exit_dpd, 0); - int ret; + nrfx_err_t res; + int rc; - ret = qspi_send_cmd(dev, &cmd, false); - if (ret < 0) { - return ret; + nrf_qspi_pins_get(NRF_QSPI, &pins); + nrf_qspi_pins_set(NRF_QSPI, &disconnected_pins); + res = nrfx_qspi_activate(true); + nrf_qspi_pins_set(NRF_QSPI, &pins); + + if (res != NRFX_SUCCESS) { + return -EIO; + } + + rc = qspi_send_cmd(dev, &cmd, false); + if (rc < 0) { + return rc; } if (t_exit_dpd) { From 3ae035a26abc2d5fe064e12c18c2496f4f51ff00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 6 Nov 2023 14:31:56 +0100 Subject: [PATCH 4449/4498] [nrf fromtree] drivers: nrf_qspi_nor: Clean up handling of return values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consistently use `res` for results of calls to nrfx functions and `rc` for Zephyr return codes, to avoid mixing up those two and for example calling `qspi_get_zephyr_ret_code()` for a value that is already a Zephyr return code. Correct also such call in `qspi_nor_write()`. Signed-off-by: Andrzej Głąbek (cherry picked from commit 4a4558128848b3cc01a153ab128fb6aa09316a99) (cherry picked from commit 72a0fceed9941275c0c5b666363360a99f293d1e) Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 248 ++++++++++++++++++----------------- 1 file changed, 125 insertions(+), 123 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 467d0643d48..ca4673e8aa2 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -371,7 +371,7 @@ static int qspi_device_init(const struct device *dev) return pm_device_runtime_get(dev); #else nrfx_err_t res; - int ret = 0; + int rc = 0; qspi_lock(dev); @@ -389,13 +389,13 @@ static int qspi_device_init(const struct device *dev) res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - ret = qspi_get_zephyr_ret_code(res); - qspi_initialized = (ret == 0); + rc = qspi_get_zephyr_ret_code(res); + qspi_initialized = (rc == 0); } qspi_unlock(dev); - return ret; + return rc; #endif } @@ -408,10 +408,10 @@ static void qspi_device_uninit(const struct device *dev) } #ifdef CONFIG_PM_DEVICE_RUNTIME - int ret = pm_device_runtime_put(dev); + int rc = pm_device_runtime_put(dev); - if (ret < 0) { - LOG_ERR("Failed to schedule device sleep: %d", ret); + if (rc < 0) { + LOG_ERR("Failed to schedule device sleep: %d", rc); } #else bool last = true; @@ -526,27 +526,27 @@ static int qspi_rdsr(const struct device *dev, uint8_t sr_num) .op_code = opcode, .rx_buf = &sr_buf, }; - int ret = qspi_send_cmd(dev, &cmd, false); + int rc = qspi_send_cmd(dev, &cmd, false); - return (ret < 0) ? ret : sr; + return (rc < 0) ? rc : sr; } /* Wait until RDSR confirms write is not in progress. */ static int qspi_wait_while_writing(const struct device *dev) { - int ret; + int rc; do { - ret = qspi_rdsr(dev, 1); - } while ((ret >= 0) - && ((ret & SPI_NOR_WIP_BIT) != 0U)); + rc = qspi_rdsr(dev, 1); + } while ((rc >= 0) + && ((rc & SPI_NOR_WIP_BIT) != 0U)); - return (ret < 0) ? ret : 0; + return (rc < 0) ? rc : 0; } static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) { - int ret = 0; + int rc = 0; uint8_t opcode = SPI_NOR_CMD_WRSR; uint8_t length = 1; uint8_t sr_array[2] = {0}; @@ -559,12 +559,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) sr_array[0] = sr_val; #if SR1_WRITE_CLEARS_SR2 /* Writing sr1 clears sr2. need to read/modify/write both. */ - ret = qspi_rdsr(dev, 2); - if (ret < 0) { - LOG_ERR("RDSR for WRSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, 2); + if (rc < 0) { + LOG_ERR("RDSR for WRSR failed: %d", rc); + return rc; } - sr_array[1] = ret; + sr_array[1] = rc; length = 2; #endif } else { /* sr_num == 2 */ @@ -574,12 +574,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) * Uses standard WRSR opcode */ sr_array[1] = sr_val; - ret = qspi_rdsr(dev, 1); - if (ret < 0) { - LOG_ERR("RDSR for WRSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, 1); + if (rc < 0) { + LOG_ERR("RDSR for WRSR failed: %d", rc); + return rc; } - sr_array[0] = ret; + sr_array[0] = rc; length = 2; #elif IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_S2B1v6) /* Writing sr2 uses a dedicated WRSR2 command */ @@ -600,17 +600,17 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) .tx_buf = &sr_buf, }; - ret = qspi_send_cmd(dev, &cmd, true); + rc = qspi_send_cmd(dev, &cmd, true); /* Writing SR can take some time, and further * commands sent while it's happening can be * corrupted. Wait. */ - if (ret == 0) { - ret = qspi_wait_while_writing(dev); + if (rc == 0) { + rc = qspi_wait_while_writing(dev); } - return ret; + return rc; } #endif /* !IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_NONE) */ @@ -627,16 +627,16 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) return -EINVAL; } - int rv = 0; const struct qspi_nor_config *params = dev->config; + int rc, rc2; - rv = qspi_device_init(dev); - if (rv != 0) { + rc = qspi_device_init(dev); + if (rc != 0) { goto out; } qspi_trans_lock(dev); - rv = qspi_nor_write_protection_set(dev, false); - if (rv != 0) { + rc = qspi_nor_write_protection_set(dev, false); + if (rc != 0) { goto out_trans_unlock; } qspi_lock(dev); @@ -670,16 +670,16 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) size -= adj; } else { LOG_ERR("erase error at 0x%lx size %zu", (long)addr, size); - rv = qspi_get_zephyr_ret_code(res); + rc = qspi_get_zephyr_ret_code(res); break; } } qspi_unlock(dev); - int rv2 = qspi_nor_write_protection_set(dev, true); + rc2 = qspi_nor_write_protection_set(dev, true); - if (!rv) { - rv = rv2; + if (!rc) { + rc = rc2; } out_trans_unlock: @@ -687,7 +687,7 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) out: qspi_device_uninit(dev); - return rv; + return rc; } /* Configures QSPI memory for the transfer */ @@ -695,6 +695,8 @@ static int qspi_nrfx_configure(const struct device *dev) { struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; + nrfx_err_t res; + int rc; #if defined(CONFIG_SOC_SERIES_NRF53X) /* When the QSPI peripheral is activated, during the nrfx_qspi driver @@ -705,18 +707,16 @@ static int qspi_nrfx_configure(const struct device *dev) nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); #endif - nrfx_err_t res = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); #if defined(CONFIG_SOC_SERIES_NRF53X) /* Restore the default /4 divider after the QSPI initialization. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); #endif - int ret = qspi_get_zephyr_ret_code(res); - if (ret < 0) { - return ret; + rc = qspi_get_zephyr_ret_code(res); + if (rc < 0) { + return rc; } #if DT_INST_NODE_HAS_PROP(0, rx_delay) @@ -736,9 +736,9 @@ static int qspi_nrfx_configure(const struct device *dev) * bootloader) might have set DPD mode before reboot. As a result, * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. */ - ret = exit_dpd(dev); - if (ret < 0) { - return ret; + rc = exit_dpd(dev); + if (rc < 0) { + return rc; } /* Set QE to match transfer mode. If not using quad @@ -769,28 +769,28 @@ static int qspi_nrfx_configure(const struct device *dev) return -EINVAL; #endif - ret = qspi_rdsr(dev, sr_num); - if (ret < 0) { - LOG_ERR("RDSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, sr_num); + if (rc < 0) { + LOG_ERR("RDSR failed: %d", rc); + return rc; } - uint8_t sr = (uint8_t)ret; + uint8_t sr = (uint8_t)rc; bool qe_state = ((sr & qe_mask) != 0U); LOG_DBG("RDSR %02x QE %d need %d: %s", sr, qe_state, qe_value, (qe_state != qe_value) ? "updating" : "no-change"); - ret = 0; + rc = 0; if (qe_state != qe_value) { sr ^= qe_mask; - ret = qspi_wrsr(dev, sr, sr_num); + rc = qspi_wrsr(dev, sr, sr_num); } - if (ret < 0) { + if (rc < 0) { LOG_ERR("QE %s failed: %d", qe_value ? "set" : "clear", - ret); - return ret; + rc); + return rc; } #endif @@ -802,16 +802,16 @@ static int qspi_nrfx_configure(const struct device *dev) /* Call will send write enable before instruction if that * requirement is encoded in INST_0_4BA. */ - ret = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); + rc = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); - if (ret < 0) { - LOG_ERR("E4BA cmd issue failed: %d.", ret); + if (rc < 0) { + LOG_ERR("E4BA cmd issue failed: %d.", rc); } else { LOG_DBG("E4BA cmd issued."); } } - return ret; + return rc; } static int qspi_read_jedec_id(const struct device *dev, @@ -826,14 +826,14 @@ static int qspi_read_jedec_id(const struct device *dev, .rx_buf = &rx_buf, }; - int ret = qspi_device_init(dev); + int rc = qspi_device_init(dev); - if (ret == 0) { - ret = qspi_send_cmd(dev, &cmd, false); + if (rc == 0) { + rc = qspi_send_cmd(dev, &cmd, false); } qspi_device_uninit(dev); - return ret; + return rc; } #if defined(CONFIG_FLASH_JESD216_API) @@ -856,13 +856,13 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io3_level = true, }; - int ret = qspi_device_init(dev); + int rc = qspi_device_init(dev); nrfx_err_t res = NRFX_SUCCESS; - if (ret != 0) { - LOG_DBG("qspi_device_init: %d", ret); + if (rc != 0) { + LOG_DBG("qspi_device_init: %d", rc); qspi_device_uninit(dev); - return ret; + return rc; } qspi_lock(dev); @@ -901,9 +901,9 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, static inline int qspi_nor_read_id(const struct device *dev) { uint8_t id[SPI_NOR_MAX_ID_LEN]; - int ret = qspi_read_jedec_id(dev, id); + int rc = qspi_read_jedec_id(dev, id); - if (ret != 0) { + if (rc != 0) { return -EIO; } @@ -1109,6 +1109,7 @@ static int qspi_nor_write(const struct device *dev, off_t addr, } const struct qspi_nor_config *params = dev->config; + int rc, rc2; /* affected region should be within device */ if (addr < 0 || @@ -1119,18 +1120,18 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - nrfx_err_t res = NRFX_SUCCESS; - - int rc = qspi_device_init(dev); + rc = qspi_device_init(dev); if (rc != 0) { goto out; } qspi_trans_lock(dev); - res = qspi_nor_write_protection_set(dev, false); + rc = qspi_nor_write_protection_set(dev, false); qspi_lock(dev); - if (!res) { + if (rc == 0) { + nrfx_err_t res; + if (size < 4U) { res = write_sub_word(dev, addr, src, size); } else if (!nrfx_is_in_ram(src) || @@ -1140,17 +1141,18 @@ static int qspi_nor_write(const struct device *dev, off_t addr, res = nrfx_qspi_write(src, size, addr); qspi_wait_for_completion(dev, res); } + + rc = qspi_get_zephyr_ret_code(res); } qspi_unlock(dev); - int res2 = qspi_nor_write_protection_set(dev, true); + rc2 = qspi_nor_write_protection_set(dev, true); qspi_trans_unlock(dev); - if (!res) { - res = res2; + if (rc == 0) { + rc = rc2; } - rc = qspi_get_zephyr_ret_code(res); out: qspi_device_uninit(dev); return rc; @@ -1169,24 +1171,24 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - int ret = qspi_erase(dev, addr, size); + int rc = qspi_erase(dev, addr, size); - return ret; + return rc; } static int qspi_nor_write_protection_set(const struct device *dev, bool write_protect) { - int ret = 0; + int rc = 0; struct qspi_cmd cmd = { .op_code = ((write_protect) ? SPI_NOR_CMD_WRDI : SPI_NOR_CMD_WREN), }; if (qspi_send_cmd(dev, &cmd, false) != 0) { - ret = -EIO; + rc = -EIO; } - return ret; + return rc; } /** @@ -1198,16 +1200,16 @@ static int qspi_nor_write_protection_set(const struct device *dev, */ static int qspi_nor_configure(const struct device *dev) { - int ret = qspi_nrfx_configure(dev); + int rc = qspi_nrfx_configure(dev); - if (ret != 0) { - return ret; + if (rc != 0) { + return rc; } #ifdef CONFIG_PM_DEVICE_RUNTIME - ret = pm_device_runtime_enable(dev); - if (ret < 0) { - LOG_ERR("Failed to enable runtime power management: %d", ret); + rc = pm_device_runtime_enable(dev); + if (rc < 0) { + LOG_ERR("Failed to enable runtime power management: %d", rc); } else { LOG_DBG("Runtime power management enabled"); } @@ -1231,12 +1233,12 @@ static int qspi_nor_configure(const struct device *dev) */ static int qspi_nor_init(const struct device *dev) { - int rc; const struct qspi_nor_config *dev_config = dev->config; - int ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + int rc; - if (ret < 0) { - return ret; + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; } IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), @@ -1317,11 +1319,11 @@ static int enter_dpd(const struct device *const dev) .op_code = SPI_NOR_CMD_DPD, }; uint32_t t_enter_dpd = DT_INST_PROP_OR(0, t_enter_dpd, 0); - int ret; + int rc; - ret = qspi_send_cmd(dev, &cmd, false); - if (ret < 0) { - return ret; + rc = qspi_send_cmd(dev, &cmd, false); + if (rc < 0) { + return rc; } if (t_enter_dpd) { @@ -1386,8 +1388,8 @@ static int qspi_nor_pm_action(const struct device *dev, { struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - int ret; - nrfx_err_t err; + int rc; + nrfx_err_t res; if (pm_device_is_busy(dev)) { return -EBUSY; @@ -1397,9 +1399,9 @@ static int qspi_nor_pm_action(const struct device *dev, case PM_DEVICE_ACTION_SUSPEND: #ifndef CONFIG_PM_DEVICE_RUNTIME /* If PM_DEVICE_RUNTIME, we don't uninit after RESUME */ - ret = qspi_device_init(dev); - if (ret < 0) { - return ret; + rc = qspi_device_init(dev); + if (rc < 0) { + return rc; } #endif @@ -1411,35 +1413,35 @@ static int qspi_nor_pm_action(const struct device *dev, return -EBUSY; } - ret = enter_dpd(dev); - if (ret < 0) { - return ret; + rc = enter_dpd(dev); + if (rc < 0) { + return rc; } nrfx_qspi_uninit(); - ret = pinctrl_apply_state(dev_config->pcfg, + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; + if (rc < 0) { + return rc; } break; case PM_DEVICE_ACTION_RESUME: - ret = pinctrl_apply_state(dev_config->pcfg, + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; + if (rc < 0) { + return rc; } - err = nrfx_qspi_init(&dev_config->nrfx_cfg, + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - if (err != NRFX_SUCCESS) { + if (res != NRFX_SUCCESS) { return -EIO; } - ret = exit_dpd(dev); - if (ret < 0) { - return ret; + rc = exit_dpd(dev); + if (rc < 0) { + return rc; } #ifndef CONFIG_PM_DEVICE_RUNTIME @@ -1459,16 +1461,16 @@ static int qspi_nor_pm_action(const struct device *dev, void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { struct qspi_nor_data *dev_data = dev->data; - int ret; + int rc; if (dev_data->xip_enabled == enable) { return; } - ret = qspi_device_init(dev); + rc = qspi_device_init(dev); - if (ret != 0) { - LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", ret); + if (rc != 0) { + LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", rc); return; } From 24e7218a2b0831b0f2d162d858d2556ff661d012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 6 Nov 2023 14:10:19 +0100 Subject: [PATCH 4450/4498] [nrf fromtree] drivers: nrf_qspi_nor: Refactor deactivation and locking access to QSPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After integration of nrfx 3.2.0, it is no longer needed to deinitialize the nrfx_qspi driver to avoid increased power consumption when the QSPI peripheral is idle. Now it is enough to call `nrfx_qspi_dectivate()` when a given operation is done. The driver will automatically activate the QSPI peripheral again when a next operation is requested. This commit applies the following changes: - `qspi_device_init` and `qspi_device_uninit` functions are replaced by `qspi_acquire` and `qspi_release`, respectively; those handle exclusive access to the QSPI peripheral and deactivation of it or runtime device power management - locking is removed from `qspi_send_cmd` as it is the resposibility of the caller of that function - `trans_lock` and `trans_unlock` functions are removed together with the related semaphore as they are no longer needed - checking of input parameters is moved from `qspi_erase` to its caller, `qspi_nor_erase` - `qspi_nor_pm_action` is refactored to properly handle locking of the QSPI peripheral; checking of the `xip_enabled` flag is removed from that function as now the call to `pm_device_is_busy()` covers that (when XIP is enabled, the device is kept indicated as busy) Signed-off-by: Andrzej Głąbek (cherry picked from commit 8c3df0aa9e9a8e7fe864b07ece840610009b3069) (cherry picked from commit 9a0aca0df38a10f19296c26fe6df9bc5b5b52c29) Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 507 +++++++++++++---------------------- 1 file changed, 193 insertions(+), 314 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index ca4673e8aa2..aa6449763be 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -26,15 +26,15 @@ LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL); #include struct qspi_nor_data { +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + /* A semaphore to control QSPI deactivation. */ + struct k_sem count; +#endif #ifdef CONFIG_MULTITHREADING - /* The semaphore to control exclusive access on write/erase. */ - struct k_sem trans; /* The semaphore to control exclusive access to the device. */ struct k_sem sem; /* The semaphore to indicate that transfer has completed. */ struct k_sem sync; - /* The semaphore to control driver init/uninit. */ - struct k_sem count; #else /* CONFIG_MULTITHREADING */ /* A flag that signals completed transfer when threads are * not enabled. @@ -173,12 +173,6 @@ BUILD_ASSERT(DT_INST_PROP(0, address_size_32), "After entering 4 byte addressing mode, 4 byte addressing is expected"); #endif -#ifndef CONFIG_PM_DEVICE_RUNTIME -static bool qspi_initialized; -#endif - -static int qspi_device_init(const struct device *dev); -static void qspi_device_uninit(const struct device *dev); void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); @@ -245,72 +239,99 @@ static inline int qspi_get_zephyr_ret_code(nrfx_err_t res) static inline void qspi_lock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - pm_device_busy_set(dev); - -#ifdef CONFIG_MULTITHREADING k_sem_take(&dev_data->sem, K_FOREVER); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev_data); -#endif /* CONFIG_MULTITHREADING */ - - /* - * Change the base clock divider only for the time the driver is locked - * to perform a QSPI operation, otherwise the power consumption would be - * increased also when the QSPI peripheral is idle. - * When XIP is enabled, there is nothing to do here as the changed - * divider is kept all the time. - */ -#if defined(CONFIG_SOC_SERIES_NRF53X) - if (!dev_data->xip_enabled) { - nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); - } #endif } static inline void qspi_unlock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* Restore the default base clock divider to reduce power consumption. - * Unless XIP is enabled, then the changed divider needs to be kept. - */ - if (!dev_data->xip_enabled) { - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); - } + k_sem_give(&dev_data->sem); #endif +} -#ifdef CONFIG_MULTITHREADING - k_sem_give(&dev_data->sem); -#else - ARG_UNUSED(dev_data); +static inline void qspi_clock_div_change(void) +{ +#ifdef CONFIG_SOC_SERIES_NRF53X + /* Make sure the base clock divider is changed accordingly + * before a QSPI transfer is performed. + */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); #endif +} - pm_device_busy_clear(dev); +static inline void qspi_clock_div_restore(void) +{ +#ifdef CONFIG_SOC_SERIES_NRF53X + /* Restore the default base clock divider to reduce power + * consumption when the QSPI peripheral is idle. + */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); +#endif } -static inline void qspi_trans_lock(const struct device *dev) +static void qspi_acquire(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - k_sem_take(&dev_data->trans, K_FOREVER); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev); -#endif /* CONFIG_MULTITHREADING */ +#if defined(CONFIG_PM_DEVICE_RUNTIME) + int rc = pm_device_runtime_get(dev); + + if (rc < 0) { + LOG_ERR("pm_device_runtime_get failed: %d", rc); + } +#elif defined(CONFIG_MULTITHREADING) + /* In multithreading, the driver can call qspi_acquire more than once + * before calling qspi_release. Keeping count, so QSPI is deactivated + * only at the last call (count == 0). + */ + k_sem_give(&dev_data->count); +#endif + + qspi_lock(dev); + + if (!dev_data->xip_enabled) { + qspi_clock_div_change(); + + pm_device_busy_set(dev); + } } -static inline void qspi_trans_unlock(const struct device *dev) +static void qspi_release(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; + bool deactivate = true; - k_sem_give(&dev_data->trans); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev); -#endif /* CONFIG_MULTITHREADING */ +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + /* The last thread to finish using the driver deactivates the QSPI */ + (void) k_sem_take(&dev_data->count, K_NO_WAIT); + deactivate = (k_sem_count_get(&dev_data->count) == 0); +#endif + + if (!dev_data->xip_enabled) { + qspi_clock_div_restore(); + + if (deactivate && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + (void) nrfx_qspi_deactivate(); + } + + pm_device_busy_clear(dev); + } + + qspi_unlock(dev); + +#if defined(CONFIG_PM_DEVICE_RUNTIME) + int rc = pm_device_runtime_put(dev); + + if (rc < 0) { + LOG_ERR("pm_device_runtime_put failed: %d", rc); + } +#endif } static inline void qspi_wait_for_completion(const struct device *dev, @@ -359,89 +380,6 @@ static void qspi_handler(nrfx_qspi_evt_t event, void *p_context) } } -static int qspi_device_init(const struct device *dev) -{ - struct qspi_nor_data *dev_data = dev->data; - - if (dev_data->xip_enabled) { - return 0; - } - -#ifdef CONFIG_PM_DEVICE_RUNTIME - return pm_device_runtime_get(dev); -#else - nrfx_err_t res; - int rc = 0; - - qspi_lock(dev); - - /* In multithreading, driver can call qspi_device_init more than once - * before calling qspi_device_uninit. Keepping count, so QSPI is - * uninitialized only at the last call (count == 0). - */ -#ifdef CONFIG_MULTITHREADING - k_sem_give(&dev_data->count); -#endif - - if (!qspi_initialized) { - const struct qspi_nor_config *dev_config = dev->config; - - res = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - rc = qspi_get_zephyr_ret_code(res); - qspi_initialized = (rc == 0); - } - - qspi_unlock(dev); - - return rc; -#endif -} - -static void qspi_device_uninit(const struct device *dev) -{ - struct qspi_nor_data *dev_data = dev->data; - - if (dev_data->xip_enabled) { - return; - } - -#ifdef CONFIG_PM_DEVICE_RUNTIME - int rc = pm_device_runtime_put(dev); - - if (rc < 0) { - LOG_ERR("Failed to schedule device sleep: %d", rc); - } -#else - bool last = true; - - qspi_lock(dev); - -#ifdef CONFIG_MULTITHREADING - /* The last thread to finish using the driver uninit the QSPI */ - (void) k_sem_take(&dev_data->count, K_NO_WAIT); - last = (k_sem_count_get(&dev_data->count) == 0); -#endif - - if (last) { - while (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { - if (IS_ENABLED(CONFIG_MULTITHREADING)) { - k_msleep(50); - } else { - k_busy_wait(50000); - } - } - - nrfx_qspi_uninit(); - - qspi_initialized = false; - } - - qspi_unlock(dev); -#endif -} - /* QSPI send custom command. * * If this is used for both send and receive the buffer sizes must be @@ -497,11 +435,8 @@ static int qspi_send_cmd(const struct device *dev, const struct qspi_cmd *cmd, .wren = wren, }; - qspi_lock(dev); - int res = nrfx_qspi_cinstr_xfer(&cinstr_cfg, tx_buf, rx_buf); - qspi_unlock(dev); return qspi_get_zephyr_ret_code(res); } @@ -617,29 +552,13 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) /* QSPI erase */ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) { - /* address must be sector-aligned */ - if ((addr % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } - - /* size must be a non-zero multiple of sectors */ - if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } - const struct qspi_nor_config *params = dev->config; int rc, rc2; - rc = qspi_device_init(dev); - if (rc != 0) { - goto out; - } - qspi_trans_lock(dev); rc = qspi_nor_write_protection_set(dev, false); if (rc != 0) { - goto out_trans_unlock; + return rc; } - qspi_lock(dev); while (size > 0) { nrfx_err_t res = !NRFX_SUCCESS; uint32_t adj = 0; @@ -674,20 +593,10 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) break; } } - qspi_unlock(dev); rc2 = qspi_nor_write_protection_set(dev, true); - if (!rc) { - rc = rc2; - } - -out_trans_unlock: - qspi_trans_unlock(dev); - -out: - qspi_device_uninit(dev); - return rc; + return rc != 0 ? rc : rc2; } /* Configures QSPI memory for the transfer */ @@ -698,22 +607,7 @@ static int qspi_nrfx_configure(const struct device *dev) nrfx_err_t res; int rc; -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* When the QSPI peripheral is activated, during the nrfx_qspi driver - * initialization, it reads the status of the connected flash chip. - * Make sure this transaction is performed with a valid base clock - * divider. - */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); -#endif - res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* Restore the default /4 divider after the QSPI initialization. */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); -#endif - rc = qspi_get_zephyr_ret_code(res); if (rc < 0) { return rc; @@ -814,8 +708,7 @@ static int qspi_nrfx_configure(const struct device *dev) return rc; } -static int qspi_read_jedec_id(const struct device *dev, - uint8_t *id) +static int qspi_rdid(const struct device *dev, uint8_t *id) { const struct qspi_buf rx_buf = { .buf = id, @@ -826,18 +719,24 @@ static int qspi_read_jedec_id(const struct device *dev, .rx_buf = &rx_buf, }; - int rc = qspi_device_init(dev); + return qspi_send_cmd(dev, &cmd, false); +} - if (rc == 0) { - rc = qspi_send_cmd(dev, &cmd, false); - } - qspi_device_uninit(dev); +#if defined(CONFIG_FLASH_JESD216_API) + +static int qspi_read_jedec_id(const struct device *dev, uint8_t *id) +{ + int rc; + + qspi_acquire(dev); + + rc = qspi_rdid(dev, id); + + qspi_release(dev); return rc; } -#if defined(CONFIG_FLASH_JESD216_API) - static int qspi_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { @@ -855,17 +754,10 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io2_level = true, .io3_level = true, }; + nrfx_err_t res; - int rc = qspi_device_init(dev); - nrfx_err_t res = NRFX_SUCCESS; - - if (rc != 0) { - LOG_DBG("qspi_device_init: %d", rc); - qspi_device_uninit(dev); - return rc; - } + qspi_acquire(dev); - qspi_lock(dev); res = nrfx_qspi_lfm_start(&cinstr_cfg); if (res != NRFX_SUCCESS) { LOG_DBG("lfm_start: %x", res); @@ -885,8 +777,8 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, } out: - qspi_unlock(dev); - qspi_device_uninit(dev); + qspi_release(dev); + return qspi_get_zephyr_ret_code(res); } @@ -901,7 +793,7 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, static inline int qspi_nor_read_id(const struct device *dev) { uint8_t id[SPI_NOR_MAX_ID_LEN]; - int rc = qspi_read_jedec_id(dev, id); + int rc = qspi_rdid(dev, id); if (rc != 0) { return -EIO; @@ -993,6 +885,9 @@ static inline nrfx_err_t read_non_aligned(const struct device *dev, static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, size_t size) { + const struct qspi_nor_config *params = dev->config; + nrfx_err_t res; + if (!dest) { return -EINVAL; } @@ -1002,8 +897,6 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return 0; } - const struct qspi_nor_config *params = dev->config; - /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1013,23 +906,13 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return -EINVAL; } - int rc = qspi_device_init(dev); - - if (rc != 0) { - goto out; - } - - qspi_lock(dev); - - nrfx_err_t res = read_non_aligned(dev, addr, dest, size); + qspi_acquire(dev); - qspi_unlock(dev); + res = read_non_aligned(dev, addr, dest, size); - rc = qspi_get_zephyr_ret_code(res); + qspi_release(dev); -out: - qspi_device_uninit(dev); - return rc; + return qspi_get_zephyr_ret_code(res); } /* addr aligned, sptr not null, slen less than 4 */ @@ -1094,6 +977,9 @@ static int qspi_nor_write(const struct device *dev, off_t addr, const void *src, size_t size) { + const struct qspi_nor_config *params = dev->config; + int rc, rc2; + if (!src) { return -EINVAL; } @@ -1108,9 +994,6 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - const struct qspi_nor_config *params = dev->config; - int rc, rc2; - /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1120,15 +1003,9 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } + qspi_acquire(dev); - rc = qspi_device_init(dev); - if (rc != 0) { - goto out; - } - - qspi_trans_lock(dev); rc = qspi_nor_write_protection_set(dev, false); - qspi_lock(dev); if (rc == 0) { nrfx_err_t res; @@ -1144,23 +1021,28 @@ static int qspi_nor_write(const struct device *dev, off_t addr, rc = qspi_get_zephyr_ret_code(res); } - qspi_unlock(dev); rc2 = qspi_nor_write_protection_set(dev, true); - qspi_trans_unlock(dev); - if (rc == 0) { - rc = rc2; - } + qspi_release(dev); -out: - qspi_device_uninit(dev); - return rc; + return rc != 0 ? rc : rc2; } static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) { const struct qspi_nor_config *params = dev->config; + int rc; + + /* address must be sector-aligned */ + if ((addr % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } + + /* size must be a non-zero multiple of sectors */ + if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } /* affected region should be within device */ if (addr < 0 || @@ -1171,7 +1053,11 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - int rc = qspi_erase(dev, addr, size); + qspi_acquire(dev); + + rc = qspi_erase(dev, addr, size); + + qspi_release(dev); return rc; } @@ -1206,17 +1092,6 @@ static int qspi_nor_configure(const struct device *dev) return rc; } -#ifdef CONFIG_PM_DEVICE_RUNTIME - rc = pm_device_runtime_enable(dev); - if (rc < 0) { - LOG_ERR("Failed to enable runtime power management: %d", rc); - } else { - LOG_DBG("Runtime power management enabled"); - } -#else - qspi_device_uninit(dev); -#endif - /* now the spi bus is configured, we can verify the flash id */ if (qspi_nor_read_id(dev) != 0) { return -ENODEV; @@ -1244,10 +1119,24 @@ static int qspi_nor_init(const struct device *dev) IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), nrfx_isr, nrfx_qspi_irq_handler, 0); + qspi_clock_div_change(); + rc = qspi_nor_configure(dev); + qspi_clock_div_restore(); + +#ifdef CONFIG_PM_DEVICE_RUNTIME + int rc2 = pm_device_runtime_enable(dev); + + if (rc2 < 0) { + LOG_ERR("Failed to enable runtime power management: %d", rc2); + } else { + LOG_DBG("Runtime power management enabled"); + } +#endif + #ifdef CONFIG_NORDIC_QSPI_NOR_XIP - if (!rc) { + if (rc == 0) { /* Enable XIP mode for QSPI NOR flash, this will prevent the * flash from being powered down */ @@ -1383,108 +1272,97 @@ static int exit_dpd(const struct device *const dev) } #ifdef CONFIG_PM_DEVICE -static int qspi_nor_pm_action(const struct device *dev, - enum pm_device_action action) +static int qspi_suspend(const struct device *dev) { - struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - int rc; nrfx_err_t res; + int rc; - if (pm_device_is_busy(dev)) { + res = nrfx_qspi_mem_busy_check(); + if (res != NRFX_SUCCESS) { return -EBUSY; } - switch (action) { - case PM_DEVICE_ACTION_SUSPEND: -#ifndef CONFIG_PM_DEVICE_RUNTIME - /* If PM_DEVICE_RUNTIME, we don't uninit after RESUME */ - rc = qspi_device_init(dev); - if (rc < 0) { - return rc; - } -#endif + rc = enter_dpd(dev); + if (rc < 0) { + return rc; + } - if (dev_data->xip_enabled) { - return -EBUSY; - } + nrfx_qspi_uninit(); - if (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { - return -EBUSY; - } + return pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); +} - rc = enter_dpd(dev); - if (rc < 0) { - return rc; - } +static int qspi_resume(const struct device *dev) +{ + const struct qspi_nor_config *dev_config = dev->config; + nrfx_err_t res; + int rc; - nrfx_qspi_uninit(); - rc = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_SLEEP); - if (rc < 0) { - return rc; - } - break; + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; + } - case PM_DEVICE_ACTION_RESUME: - rc = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_DEFAULT); - if (rc < 0) { - return rc; - } - res = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - if (res != NRFX_SUCCESS) { - return -EIO; - } + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + if (res != NRFX_SUCCESS) { + return -EIO; + } - rc = exit_dpd(dev); - if (rc < 0) { - return rc; - } + return exit_dpd(dev); +} -#ifndef CONFIG_PM_DEVICE_RUNTIME - /* If PM_DEVICE_RUNTIME, we're immediately going to use the device */ - qspi_device_uninit(dev); -#endif +static int qspi_nor_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int rc; + + if (pm_device_is_busy(dev)) { + return -EBUSY; + } + + qspi_lock(dev); + qspi_clock_div_change(); + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + rc = qspi_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + rc = qspi_resume(dev); break; default: - return -ENOTSUP; + rc = -ENOTSUP; } - return 0; + qspi_clock_div_restore(); + qspi_unlock(dev); + + return rc; } #endif /* CONFIG_PM_DEVICE */ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { struct qspi_nor_data *dev_data = dev->data; - int rc; if (dev_data->xip_enabled == enable) { return; } - rc = qspi_device_init(dev); - - if (rc != 0) { - LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", rc); - return; - } + qspi_acquire(dev); #if NRF_QSPI_HAS_XIPEN nrf_qspi_xip_set(NRF_QSPI, enable); #endif - qspi_lock(dev); if (enable) { (void)nrfx_qspi_activate(false); } dev_data->xip_enabled = enable; - qspi_unlock(dev); - qspi_device_uninit(dev); + qspi_release(dev); } #ifdef CONFIG_USERSPACE @@ -1502,11 +1380,12 @@ void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) #endif /* CONFIG_USERSPACE */ static struct qspi_nor_data qspi_nor_dev_data = { +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), +#endif #ifdef CONFIG_MULTITHREADING - .trans = Z_SEM_INITIALIZER(qspi_nor_dev_data.trans, 1, 1), .sem = Z_SEM_INITIALIZER(qspi_nor_dev_data.sem, 1, 1), .sync = Z_SEM_INITIALIZER(qspi_nor_dev_data.sync, 0, 1), - .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), #endif /* CONFIG_MULTITHREADING */ }; From 05688141d94c0cb28ab1cb48a653d733a4133001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 10 Nov 2023 16:52:12 +0100 Subject: [PATCH 4451/4498] [nrf fromtree] drivers: nrf_qspi_nor: Fix and refactor driver initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far the driver first changed the configuration of the flash chip and after that checked the signature of that chip. This could lead to improper change of the chip configuration if the actually found one was different than that specified in devicetree. This commit reverses the order of these two initialization steps and also restructures a bit the initialization code. Signed-off-by: Andrzej Głąbek (cherry picked from commit ea1be7f242b9348863a27adb17215014f15b318a) (cherry picked from commit 86146714949810fd451dace302bd42ea4ecb3927) Signed-off-by: Dominik Ermel --- drivers/flash/nrf_qspi_nor.c | 125 +++++++++++++---------------------- 1 file changed, 45 insertions(+), 80 deletions(-) diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index aa6449763be..d6695989857 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -599,41 +599,10 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) return rc != 0 ? rc : rc2; } -/* Configures QSPI memory for the transfer */ -static int qspi_nrfx_configure(const struct device *dev) +static int configure_chip(const struct device *dev) { - struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - nrfx_err_t res; - int rc; - - res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev_data); - rc = qspi_get_zephyr_ret_code(res); - if (rc < 0) { - return rc; - } - -#if DT_INST_NODE_HAS_PROP(0, rx_delay) - if (!nrf53_errata_121()) { - nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); - } -#endif - - /* It may happen that after the flash chip was previously put into - * the DPD mode, the system was reset but the flash chip was not. - * Consequently, the flash chip can be in the DPD mode at this point. - * Some flash chips will just exit the DPD mode on the first CS pulse, - * but some need to receive the dedicated command to do it, so send it. - * This can be the case even if the current image does not have - * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image - * (for example the main image if the currently executing image is the - * bootloader) might have set DPD mode before reboot. As a result, - * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. - */ - rc = exit_dpd(dev); - if (rc < 0) { - return rc; - } + int rc = 0; /* Set QE to match transfer mode. If not using quad * it's OK to leave QE set, but doing so prevents use @@ -784,33 +753,6 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, #endif /* CONFIG_FLASH_JESD216_API */ -/** - * @brief Retrieve the Flash JEDEC ID and compare it with the one expected - * - * @param dev The device structure - * @return 0 on success, negative errno code otherwise - */ -static inline int qspi_nor_read_id(const struct device *dev) -{ - uint8_t id[SPI_NOR_MAX_ID_LEN]; - int rc = qspi_rdid(dev, id); - - if (rc != 0) { - return -EIO; - } - - const struct qspi_nor_config *qnc = dev->config; - - if (memcmp(qnc->id, id, SPI_NOR_MAX_ID_LEN) != 0) { - LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", - id[0], id[1], id[2], - qnc->id[0], qnc->id[1], qnc->id[2]); - return -ENODEV; - } - - return 0; -} - static inline nrfx_err_t read_non_aligned(const struct device *dev, off_t addr, void *dest, size_t size) @@ -1077,35 +1019,58 @@ static int qspi_nor_write_protection_set(const struct device *dev, return rc; } -/** - * @brief Configure the flash - * - * @param dev The flash device structure - * @param info The flash info structure - * @return 0 on success, negative errno code otherwise - */ -static int qspi_nor_configure(const struct device *dev) +static int qspi_init(const struct device *dev) { - int rc = qspi_nrfx_configure(dev); + const struct qspi_nor_config *dev_config = dev->config; + uint8_t id[SPI_NOR_MAX_ID_LEN]; + nrfx_err_t res; + int rc; - if (rc != 0) { + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + rc = qspi_get_zephyr_ret_code(res); + if (rc < 0) { + return rc; + } + +#if DT_INST_NODE_HAS_PROP(0, rx_delay) + if (!nrf53_errata_121()) { + nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); + } +#endif + + /* It may happen that after the flash chip was previously put into + * the DPD mode, the system was reset but the flash chip was not. + * Consequently, the flash chip can be in the DPD mode at this point. + * Some flash chips will just exit the DPD mode on the first CS pulse, + * but some need to receive the dedicated command to do it, so send it. + * This can be the case even if the current image does not have + * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image + * (for example the main image if the currently executing image is the + * bootloader) might have set DPD mode before reboot. As a result, + * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. + */ + rc = exit_dpd(dev); + if (rc < 0) { + return rc; + } + + /* Retrieve the Flash JEDEC ID and compare it with the one expected. */ + rc = qspi_rdid(dev, id); + if (rc < 0) { return rc; } - /* now the spi bus is configured, we can verify the flash id */ - if (qspi_nor_read_id(dev) != 0) { + if (memcmp(dev_config->id, id, SPI_NOR_MAX_ID_LEN) != 0) { + LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", + id[0], id[1], id[2], dev_config->id[0], + dev_config->id[1], dev_config->id[2]); return -ENODEV; } - return 0; + /* The chip is correct, it can be configured now. */ + return configure_chip(dev); } -/** - * @brief Initialize and configure the flash - * - * @param name The flash name - * @return 0 on success, negative errno code otherwise - */ static int qspi_nor_init(const struct device *dev) { const struct qspi_nor_config *dev_config = dev->config; @@ -1121,7 +1086,7 @@ static int qspi_nor_init(const struct device *dev) qspi_clock_div_change(); - rc = qspi_nor_configure(dev); + rc = qspi_init(dev); qspi_clock_div_restore(); From 915ea12b7c706f7c9667aa85b2fb90b406d36e19 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 14 Dec 2023 21:13:44 +0530 Subject: [PATCH 4452/4498] [nrf fromtree] wifi: shell: Fix AP argument checks and help AP enable takes the same parameters as connect, so, update the help and also fix the optional parameter count when security is involved. Signed-off-by: Chaitanya Tata (cherry picked from commit 9736cc7f29668542a85b5c775b368a6a30c7f8c0) (cherry picked from commit 85a25485d25f7da05e0d6c707b326a487b3a9e6b) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index c5b8f60d933..e243a9de4e4 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1602,9 +1602,16 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, "Disable Access Point mode", cmd_wifi_ap_disable, 1, 0), - SHELL_CMD_ARG(enable, NULL, " [channel] [PSK]", + SHELL_CMD_ARG(enable, NULL, + "\"\"\n" + "[channel number: 0 means all]\n" + "[PSK: valid only for secure SSIDs]\n" + "[Security type: valid only for secure SSIDs]\n" + "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" + "[MFP (optional: needs security type to be specified)]\n" + ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_ap_enable, - 2, 1), + 2, 4), SHELL_SUBCMD_SET_END ); From 620bad8edd3f13a77595747002554fec3ff60ed2 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 14 Dec 2023 21:17:07 +0530 Subject: [PATCH 4453/4498] [nrf fromtree] wifi: shell: Display RSSI only for station mode RSSI makes sense only for modes that have a single peer, so, add a station mode check. Signed-off-by: Chaitanya Tata (cherry picked from commit eaba47445a4e9cd1bee7d6adb9b9c62f159f3088) (cherry picked from commit b65e77cdb79c3deb22395874d3079f850a6dffd0) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index e243a9de4e4..f1a98105204 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -660,7 +660,9 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) wifi_security_txt(status.security)); shell_fprintf(sh, SHELL_NORMAL, "MFP: %s\n", wifi_mfp_txt(status.mfp)); - shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); + if (status.iface_mode == WIFI_MODE_INFRA) { + shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); + } shell_fprintf(sh, SHELL_NORMAL, "Beacon Interval: %d\n", status.beacon_interval); shell_fprintf(sh, SHELL_NORMAL, "DTIM: %d\n", status.dtim_period); shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", From 9fb63a841e1dc54b7ed3a28bff90aa8ce41ceb8c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 18 Dec 2023 17:42:43 +0530 Subject: [PATCH 4454/4498] [nrf fromlist] wifi: shell: Fix arg count for regulatory domain Regulatory domain supports both get and set, so, fix the argument counts. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66616 Signed-off-by: Chaitanya Tata (cherry picked from commit 426213023e08965311421143ca3abe2ec25b39a4) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index f1a98105204..3aa674e73b7 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1688,7 +1688,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, - 2, 1), + 1, 1), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" From 277b6e66bc52f5bdf22a140c8db748054e93a38c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 13:55:12 +0530 Subject: [PATCH 4455/4498] [nrf fromlist] wifi: shell: Fix the arg count for reg domain Missed accounting for "-f" option. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit bf821e930748f94977af135540235b76dad32ee9) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3aa674e73b7..c3100c9ad2c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1688,7 +1688,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, - 1, 1), + 1, 2), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" "parameters:" From ee07a2d47bae600063b0e048355a9d8a44243a3a Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 13:57:20 +0530 Subject: [PATCH 4456/4498] [nrf fromlist] wifi: shell: Fix optional arg count for connect Fix an extra optional arg. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit 16d86216eb95cbc5e173db576ebee9c7d72d0569) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index c3100c9ad2c..dbec138fea0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1653,7 +1653,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[MFP (optional: needs security type to be specified)]\n" ": 0:Disable, 1:Optional, 2:Required", cmd_wifi_connect, - 2, 5), + 2, 4), SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect, 1, 0), From f076140f55d70269c733b633a9ca2dc5612500c5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 13:59:52 +0530 Subject: [PATCH 4457/4498] [nrf fromlist] wifi: shell: Fix help for PS command Clearly mark the args as optional. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit 0fc24a59c702c89f6fa04feb552d5bb1eee5e6df) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index dbec138fea0..6ef745670ab 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1657,7 +1657,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect, 1, 0), - SHELL_CMD_ARG(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", + SHELL_CMD_ARG(ps, NULL, "Configure or display Wi-Fi power save state\n" + "[on/off]\n", cmd_wifi_ps, 1, 1), SHELL_CMD_ARG(ps_mode, From 6f6774acf02d236c1a67dd4783ad2d7c5fed3919 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 14:00:50 +0530 Subject: [PATCH 4458/4498] [nrf fromlist] wifi: shell: Remove the unnecessary text in scan We are using standard notation to differentiate optional and mandatory, so, no need for a heading. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit e8a952b68db6cd8d097e169a56284bf0ff42c2a0) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 6ef745670ab..d6d14c86bf1 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1669,7 +1669,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" - "OPTIONAL PARAMETERS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" From b86194298032cf0ffc53d990b8d71e0a08aa6012 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 14:02:42 +0530 Subject: [PATCH 4459/4498] [nrf fromlist] wifi: shell: Fix the help for reg domain Separate the two optional parameters and add help. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit 6be67b3199e68acff52e8d09d231d0f4d5afec4d) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d6d14c86bf1..890bb8f121e 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1684,7 +1684,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" - "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" + "[ISO/IEC 3166-1 alpha2]: Regulatory domain\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain, From fd36c75dc0124f043c8875aef3163e8b40a99ec9 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 14:07:36 +0530 Subject: [PATCH 4460/4498] [nrf fromlist] wifi: shell: Remove the unnecessary text The parameters heading is implied and doesn't have the newline, so, just remove it. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit f9f9f83293267465b05927bc3756e1d22accab05) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 890bb8f121e..a983e5c18f5 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1691,7 +1691,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 1, 2), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" - "parameters:" "[-i, --if-index ] : Interface index.\n" "[-s, --sta] : Station mode.\n" "[-m, --monitor] : Monitor mode.\n" @@ -1711,7 +1710,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "This command is used to set packet filter setting when\n" "monitor, TX-Injection and promiscuous mode is enabled.\n" "The different packet filter modes are control, management, data and enable all filters\n" - "parameters:" "[-i, --if-index ] : Interface index.\n" "[-a, --all] : Enable all packet filter modes\n" "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" @@ -1730,7 +1728,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "This command is used to set the channel when\n" "monitor or TX-Injection mode is enabled.\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" - "parameters:" "[-i, --if-index ] : Interface index.\n" "[-c, --channel ] : Set a specific channel number to the lower layer.\n" "[-g, --get] : Get current set channel number from the lower layer.\n" From 260afe3c20a494877fb38bc691c401c721870da2 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 14:15:11 +0530 Subject: [PATCH 4461/4498] [nrf fromlist] wifi: shell: Fix the inconsistency in commands separation For better readability, below rules will help: * Each command should be separated by a newline * Each command should end with a full stop (intermediate statements shouldn't have full stops) Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit 1353dd144af6aaaa71649c82db287525a72da343) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 98 ++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a983e5c18f5..9bf33e827ec 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1601,7 +1601,7 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD_ARG(disable, NULL, - "Disable Access Point mode", + "Disable Access Point mode.\n", cmd_wifi_ap_disable, 1, 0), SHELL_CMD_ARG(enable, NULL, @@ -1611,7 +1611,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, "[Security type: valid only for secure SSIDs]\n" "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" - ": 0:Disable, 1:Optional, 2:Required", + ": 0:Disable, 1:Optional, 2:Required.\n", cmd_wifi_ap_enable, 2, 4), SHELL_SUBCMD_SET_END @@ -1619,30 +1619,30 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD_ARG(quick_setup, NULL, " Start a TWT flow with defaults:\n" - " \n", + " .\n", cmd_wifi_twt_setup_quick, 3, 0), SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " - " \n", + " .\n", cmd_wifi_twt_setup, 11, 0), SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " \n", + " .\n", cmd_wifi_twt_teardown, 5, 0), - SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows\n", + SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows.\n", cmd_wifi_twt_teardown_all, 1, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, - SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands", NULL), + SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands.\n", NULL), SHELL_CMD_ARG(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" @@ -1651,108 +1651,108 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[Security type: valid only for secure SSIDs]\n" "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" "[MFP (optional: needs security type to be specified)]\n" - ": 0:Disable, 1:Optional, 2:Required", + ": 0:Disable, 1:Optional, 2:Required.\n", cmd_wifi_connect, 2, 4), - SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP", + SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP.\n", cmd_wifi_disconnect, 1, 0), SHELL_CMD_ARG(ps, NULL, "Configure or display Wi-Fi power save state\n" - "[on/off]\n", + "[on/off].\n", cmd_wifi_ps, 1, 1), SHELL_CMD_ARG(ps_mode, NULL, - "\n", + ".\n", cmd_wifi_ps_mode, 2, 0), SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" - "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" - "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" - "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" - "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" - "[-s, --ssid : SSID to scan for. Can be provided multiple times.\n" - "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" + "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active\n" + "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz\n" + "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms\n" + "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms\n" + "[-s, --ssid : SSID to scan for. Can be provided multiple times\n" + "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535\n" "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" - "[-h, --help] : Print out the help for the scan command.", + "[-h, --help] : Print out the help for the scan command.\n", cmd_wifi_scan, 1, 8), - SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats, 1, 0), - SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status, 1, 0), - SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), + SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics.\n", cmd_wifi_stats, 1, 0), + SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface.\n", cmd_wifi_status, 1, 0), + SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows.\n", NULL), SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" "[ISO/IEC 3166-1 alpha2]: Regulatory domain\n" "[-f]: Force to use this regulatory hint over any other regulatory hints\n" - "Note: This may cause regulatory compliance issues, use it at your own risk.", + "Note: This may cause regulatory compliance issues, use it at your own risk.\n", cmd_wifi_reg_domain, 1, 2), SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" - "[-i, --if-index ] : Interface index.\n" - "[-s, --sta] : Station mode.\n" - "[-m, --monitor] : Monitor mode.\n" - "[-p, --promiscuous] : Promiscuous mode.\n" - "[-t, --tx-injection] : TX-Injection mode.\n" - "[-a, --ap] : AP mode.\n" - "[-k, --softap] : Softap mode.\n" - "[-h, --help] : Help.\n" - "[-g, --get] : Get current mode for a specific interface index.\n" + "[-i, --if-index ] : Interface index\n" + "[-s, --sta] : Station mode\n" + "[-m, --monitor] : Monitor mode\n" + "[-p, --promiscuous] : Promiscuous mode\n" + "[-t, --tx-injection] : TX-Injection mode\n" + "[-a, --ap] : AP mode\n" + "[-k, --softap] : Softap mode\n" + "[-h, --help] : Help\n" + "[-g, --get] : Get current mode for a specific interface index\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" - "wifi mode -i1 -sp\n", + "wifi mode -i1 -sp.\n", cmd_wifi_mode, 1, 9), SHELL_CMD_ARG(packet_filter, NULL, "mode filter setting\n" "This command is used to set packet filter setting when\n" - "monitor, TX-Injection and promiscuous mode is enabled.\n" + "monitor, TX-Injection and promiscuous mode is enabled\n" "The different packet filter modes are control, management, data and enable all filters\n" - "[-i, --if-index ] : Interface index.\n" + "[-i, --if-index ] : Interface index\n" "[-a, --all] : Enable all packet filter modes\n" - "[-m, --mgmt] : Enable management packets to allowed up the stack.\n" - "[-c, --ctrl] : Enable control packets to be allowed up the stack.\n" - "[-d, --data] : Enable Data packets to be allowed up the stack.\n" - "[-g, --get] : Get current filter settings for a specific interface index.\n" + "[-m, --mgmt] : Enable management packets to allowed up the stack\n" + "[-c, --ctrl] : Enable control packets to be allowed up the stack\n" + "[-d, --data] : Enable Data packets to be allowed up the stack\n" + "[-g, --get] : Get current filter settings for a specific interface index\n" "[-b, --capture-len ] : Capture length buffer size for each packet to be captured\n" - "[-h, --help] : Help.\n" + "[-h, --help] : Help\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" - "wifi packet_filter -i1 -md\n", + "wifi packet_filter -i1 -md.\n", cmd_wifi_packet_filter, 1, 8), SHELL_CMD_ARG(channel, NULL, "wifi channel setting\n" "This command is used to set the channel when\n" - "monitor or TX-Injection mode is enabled.\n" + "monitor or TX-Injection mode is enabled\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" - "[-i, --if-index ] : Interface index.\n" - "[-c, --channel ] : Set a specific channel number to the lower layer.\n" - "[-g, --get] : Get current set channel number from the lower layer.\n" - "[-h, --help] : Help.\n" + "[-i, --if-index ] : Interface index\n" + "[-c, --channel ] : Set a specific channel number to the lower layer\n" + "[-g, --get] : Get current set channel number from the lower layer\n" + "[-h, --help] : Help\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" - "wifi -i1 -c5\n", + "wifi -i1 -c5.\n", cmd_wifi_channel, 1, 4), SHELL_CMD_ARG(ps_timeout, NULL, - " - PS inactivity timer(in ms)", + " - PS inactivity timer(in ms).\n", cmd_wifi_ps_timeout, 2, 0), SHELL_CMD_ARG(ps_listen_interval, NULL, - " - Listen interval in the range of <0-65535>", + " - Listen interval in the range of <0-65535>.\n", cmd_wifi_listen_interval, 2, 0), SHELL_CMD_ARG(ps_wakeup_mode, NULL, - "\n", + ".\n", cmd_wifi_ps_wakeup_mode, 2, 0), From 89aa0c510361acbbf4704d97b2db33f39671a491 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 22 Dec 2023 14:20:22 +0530 Subject: [PATCH 4462/4498] [nrf fromlist] shell: Add a space after colon Just a cosmetic change, but IMHO the help looks much better now :). Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66876 Signed-off-by: Chaitanya Tata (cherry picked from commit 72453d6a4d48e08ec07e86d2fb5cf38a3fe628df) Signed-off-by: Dominik Ermel --- subsys/shell/shell_help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/shell/shell_help.c b/subsys/shell/shell_help.c index 53bf00953c1..235e2111032 100644 --- a/subsys/shell/shell_help.c +++ b/subsys/shell/shell_help.c @@ -139,7 +139,7 @@ static void help_item_print(const struct shell *sh, const char *item_name, z_cursor_next_line_move(sh); return; } else { - z_shell_fprintf(sh, SHELL_NORMAL, "%s:", tabulator); + z_shell_fprintf(sh, SHELL_NORMAL, "%s: ", tabulator); } /* print option help */ formatted_text_print(sh, item_help, offset, false); From c0ea30dbc132c23d11c863fda9592ad7bfde6843 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 26 Dec 2023 21:27:32 +0530 Subject: [PATCH 4463/4498] [nrf fromlist] wifi: Fix duplication Use a common set of events and then add specific ones as per the configuration. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67015 Signed-off-by: Chaitanya Tata (cherry picked from commit 0646c56102d167a6ef533095d5603e7d411b1f54) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/wifi_shell.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9bf33e827ec..236e5cd05b8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -29,19 +29,17 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #define WIFI_SHELL_MODULE "wifi" +#define WIFI_SHELL_MGMT_EVENTS_COMMON (NET_EVENT_WIFI_SCAN_DONE |\ + NET_EVENT_WIFI_CONNECT_RESULT |\ + NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_TWT |\ + NET_EVENT_WIFI_RAW_SCAN_RESULT) + #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY -#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT | \ - NET_EVENT_WIFI_SCAN_DONE | \ - NET_EVENT_WIFI_CONNECT_RESULT | \ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT) +#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) #else -#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | \ - NET_EVENT_WIFI_SCAN_DONE | \ - NET_EVENT_WIFI_CONNECT_RESULT | \ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT | \ - NET_EVENT_WIFI_RAW_SCAN_RESULT) +#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON |\ + NET_EVENT_WIFI_SCAN_RESULT) #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ static struct { From 15fe6c5d4ecfdf5d2e6ab9ebc5d6d41bcf74648a Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 25 Dec 2023 20:09:45 +0530 Subject: [PATCH 4464/4498] [nrf fromlist] wifi: ap: Add status events These events communicate the status of AP mode operations (enable or disable) with few pre-defined enumerations. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67015 Signed-off-by: Chaitanya Tata (cherry picked from commit af9dc97de19890aa30dc04c1dbd889ef43453747) Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 47 +++++++++++++++++++++++++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 24 +++++++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 41 +++++++++++++++++++++++++--- 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index babf67722c1..0897bdd5715 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -180,6 +180,10 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, /** Disconnect complete */ NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, + /** AP mode enable result */ + NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT, + /** AP mode disable result */ + NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -209,6 +213,12 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) +#define NET_EVENT_WIFI_AP_ENABLE_RESULT \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT) + +#define NET_EVENT_WIFI_AP_DISABLE_RESULT \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT) + /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -351,12 +361,35 @@ enum wifi_disconn_reason { WIFI_REASON_DISCONN_INACTIVITY, }; +/** Wi-Fi AP mode result codes. To be overlaid on top of \ref wifi_status + * in the AP mode enable or disable result event for detailed status. + */ +enum wifi_ap_status { + /** AP mode enable or disable successful */ + WIFI_STATUS_AP_SUCCESS = 0, + /** AP mode enable or disable failed - generic failure */ + WIFI_STATUS_AP_FAIL, + /** AP mode enable failed - channel not supported */ + WIFI_STATUS_AP_CHANNEL_NOT_SUPPORTED, + /** AP mode enable failed - channel not allowed */ + WIFI_STATUS_AP_CHANNEL_NOT_ALLOWED, + /** AP mode enable failed - SSID not allowed */ + WIFI_STATUS_AP_SSID_NOT_ALLOWED, + /** AP mode enable failed - authentication type not supported */ + WIFI_STATUS_AP_AUTH_TYPE_NOT_SUPPORTED, + /** AP mode enable failed - operation not supported */ + WIFI_STATUS_AP_OP_NOT_SUPPORTED, + /** AP mode enable failed - operation not permitted */ + WIFI_STATUS_AP_OP_NOT_PERMITTED, +}; + /** Generic Wi-Fi status for commands and events */ struct wifi_status { union { int status; enum wifi_conn_status conn_status; enum wifi_disconn_reason disconn_reason; + enum wifi_ap_status ap_status; }; }; @@ -802,6 +835,20 @@ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, */ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); +/** Wi-Fi management AP mode enable result event + * + * @param iface Network interface + * @param status AP mode enable result status + */ +void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, enum wifi_ap_status status); + +/** Wi-Fi management AP mode disable result event + * + * @param iface Network interface + * @param status AP mode disable result status + */ +void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, enum wifi_ap_status status); + /** * @} */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 1a866d4c47c..21a426d794d 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -707,3 +707,27 @@ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, iface, &cnx_status, sizeof(struct wifi_status)); } + +void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, + enum wifi_ap_status status) +{ + struct wifi_status cnx_status = { + .status = status, + }; + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT, + iface, &cnx_status, + sizeof(enum wifi_ap_status)); +} + +void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, + enum wifi_ap_status status) +{ + struct wifi_status cnx_status = { + .status = status, + }; + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT, + iface, &cnx_status, + sizeof(enum wifi_ap_status)); +} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 236e5cd05b8..217e4c703c0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -33,7 +33,9 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); NET_EVENT_WIFI_CONNECT_RESULT |\ NET_EVENT_WIFI_DISCONNECT_RESULT | \ NET_EVENT_WIFI_TWT |\ - NET_EVENT_WIFI_RAW_SCAN_RESULT) + NET_EVENT_WIFI_RAW_SCAN_RESULT |\ + NET_EVENT_WIFI_AP_ENABLE_RESULT |\ + NET_EVENT_WIFI_AP_DISABLE_RESULT) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY #define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) @@ -300,6 +302,32 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) } } +static void handle_wifi_ap_enable_result(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = + (const struct wifi_status *)cb->info; + + if (status->status) { + print(context.sh, SHELL_WARNING, + "AP enable request failed (%d)\n", status->status); + } else { + print(context.sh, SHELL_NORMAL, "AP enabled\n"); + } +} + +static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = + (const struct wifi_status *)cb->info; + + if (status->status) { + print(context.sh, SHELL_WARNING, + "AP disable request failed (%d)\n", status->status); + } else { + print(context.sh, SHELL_NORMAL, "AP disabled\n"); + } +} + static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { @@ -324,6 +352,12 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, handle_wifi_raw_scan_result(cb); break; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + case NET_EVENT_WIFI_AP_ENABLE_RESULT: + handle_wifi_ap_enable_result(cb); + break; + case NET_EVENT_WIFI_AP_DISABLE_RESULT: + handle_wifi_ap_disable_result(cb); + break; default: break; } @@ -1112,7 +1146,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode enabled\n"); + shell_fprintf(sh, SHELL_NORMAL, "AP mode enable requested\n"); return 0; } @@ -1129,8 +1163,7 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode disabled\n"); - + shell_fprintf(sh, SHELL_NORMAL, "AP mode disable requested\n"); return 0; } From 9a5a739cde1ed10fab5a0c989b991390d0412236 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 26 Dec 2023 21:17:51 +0530 Subject: [PATCH 4465/4498] [nrf fromlist] wifi: ap: Add client side events These are helpful to track clients being added and deleted. Applications can actions based on these events. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67015 Signed-off-by: Chaitanya Tata (cherry picked from commit 81038eb0200a36600381bfd7120c9105111b9cb0) Signed-off-by: Dominik Ermel --- include/zephyr/net/wifi_mgmt.h | 38 +++++++++++++++++++++++++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 16 ++++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 32 ++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 0897bdd5715..78800f451e7 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -184,6 +184,10 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT, /** AP mode disable result */ NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, + /** STA connected to AP */ + NET_EVENT_WIFI_CMD_AP_STA_CONNECTED, + /** STA disconnected from AP */ + NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -219,6 +223,12 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_AP_DISABLE_RESULT \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT) +#define NET_EVENT_WIFI_AP_STA_CONNECTED \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) + +#define NET_EVENT_WIFI_AP_STA_DISCONNECTED \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED) + /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -568,6 +578,18 @@ struct wifi_raw_scan_result { }; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ +/** AP mode - connected STA details */ +struct wifi_ap_sta_info { + /** Link mode, see enum wifi_link_mode */ + enum wifi_link_mode link_mode; + /** MAC address */ + uint8_t mac[WIFI_MAC_ADDR_LEN]; + /** MAC address length */ + uint8_t mac_length; + /** is TWT capable ? */ + bool twt_capable; +}; + /* for use in max info size calculations */ union wifi_mgmt_events { struct wifi_scan_result scan_result; @@ -577,6 +599,7 @@ union wifi_mgmt_events { struct wifi_raw_scan_result raw_scan_result; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct wifi_twt_params twt_params; + struct wifi_ap_sta_info ap_sta_info; }; /** Wi-Fi mode setup */ @@ -849,6 +872,21 @@ void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, enum wifi_ap_s */ void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, enum wifi_ap_status status); +/** Wi-Fi management AP mode STA connected event + * + * @param iface Network interface + * @param sta_info STA information + */ +void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info); + +/** Wi-Fi management AP mode STA disconnected event + * @param iface Network interface + * @param sta_info STA information + */ +void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info); + /** * @} */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 21a426d794d..6e0cb761dbf 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -731,3 +731,19 @@ void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, iface, &cnx_status, sizeof(enum wifi_ap_status)); } + +void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info) +{ + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED, + iface, sta_info, + sizeof(struct wifi_ap_sta_info)); +} + +void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info) +{ + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED, + iface, sta_info, + sizeof(struct wifi_ap_sta_info)); +} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 217e4c703c0..045fbed197e 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -35,7 +35,9 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); NET_EVENT_WIFI_TWT |\ NET_EVENT_WIFI_RAW_SCAN_RESULT |\ NET_EVENT_WIFI_AP_ENABLE_RESULT |\ - NET_EVENT_WIFI_AP_DISABLE_RESULT) + NET_EVENT_WIFI_AP_DISABLE_RESULT |\ + NET_EVENT_WIFI_AP_STA_CONNECTED |\ + NET_EVENT_WIFI_AP_STA_DISCONNECTED) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY #define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) @@ -328,6 +330,28 @@ static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) } } +static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + print(context.sh, SHELL_NORMAL, "Station connected: %s\n", + net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, sizeof(mac_string_buf))); +} + +static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + print(context.sh, SHELL_NORMAL, "Station disconnected: %s\n", + net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, sizeof(mac_string_buf))); +} + static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { @@ -358,6 +382,12 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, case NET_EVENT_WIFI_AP_DISABLE_RESULT: handle_wifi_ap_disable_result(cb); break; + case NET_EVENT_WIFI_AP_STA_CONNECTED: + handle_wifi_ap_sta_connected(cb); + break; + case NET_EVENT_WIFI_AP_STA_DISCONNECTED: + handle_wifi_ap_sta_disconnected(cb); + break; default: break; } From b5c01369df121c4a9ee23f4c9c51ccdf4edb16d1 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 27 Dec 2023 00:06:45 +0530 Subject: [PATCH 4466/4498] [nrf fromlist] wifi: shell: Add a shell command to list stations In AP mode maintain the database of connected stations based on the Wi-Fi management events and dump the list. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67015 Signed-off-by: Chaitanya Tata (cherry picked from commit 3dab922e5d0561d37823058b0fa5fad18376cb33) Signed-off-by: Dominik Ermel --- subsys/net/l2/wifi/Kconfig | 8 +++ subsys/net/l2/wifi/wifi_shell.c | 90 +++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 134448aa57f..2816be56d74 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -64,6 +64,14 @@ config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL There are approximately 100 channels allocated across the three supported bands. The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. +config WIFI_SHELL_MAX_AP_STA + int "Maximum number of APs and STAs that can be managed in Wi-Fi shell" + range 1 5 + default 1 + help + This option defines the maximum number of APs and STAs that can be managed + in Wi-Fi shell. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 045fbed197e..1ee94304781 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -24,6 +24,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include "net_private.h" @@ -64,6 +65,13 @@ static uint32_t scan_result; static struct net_mgmt_event_callback wifi_shell_mgmt_cb; +static K_MUTEX_DEFINE(wifi_ap_sta_list_lock); +struct wifi_ap_sta_node { + bool valid; + struct wifi_ap_sta_info sta_info; +}; +static struct wifi_ap_sta_node sta_list[CONFIG_WIFI_SHELL_MAX_AP_STA]; + #define print(sh, level, fmt, ...) \ do { \ if (sh) { \ @@ -328,6 +336,10 @@ static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) } else { print(context.sh, SHELL_NORMAL, "AP disabled\n"); } + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + memset(&sta_list, 0, sizeof(sta_list)); + k_mutex_unlock(&wifi_ap_sta_list_lock); } static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) @@ -335,10 +347,25 @@ static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) const struct wifi_ap_sta_info *sta_info = (const struct wifi_ap_sta_info *)cb->info; uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + int i; print(context.sh, SHELL_NORMAL, "Station connected: %s\n", net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf))); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + if (!sta_list[i].valid) { + sta_list[i].sta_info = *sta_info; + sta_list[i].valid = true; + break; + } + } + if (i == CONFIG_WIFI_SHELL_MAX_AP_STA) { + print(context.sh, SHELL_WARNING, "No space to store station info: " + "Increase CONFIG_WIFI_SHELL_MAX_AP_STA\n"); + } + k_mutex_unlock(&wifi_ap_sta_list_lock); } static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) @@ -350,6 +377,20 @@ static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) print(context.sh, SHELL_NORMAL, "Station disconnected: %s\n", net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf))); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + if (!sta_list[i].valid) { + continue; + } + + if (!memcmp(sta_list[i].sta_info.mac, sta_info->mac, + WIFI_MAC_ADDR_LEN)) { + sta_list[i].valid = false; + break; + } + } + k_mutex_unlock(&wifi_ap_sta_list_lock); } static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, @@ -1169,6 +1210,8 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, context.sh = sh; + k_mutex_init(&wifi_ap_sta_list_lock); + ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, iface, &cnx_params, sizeof(struct wifi_connect_req_params)); if (ret) { @@ -1197,6 +1240,49 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, return 0; } +static int cmd_wifi_ap_stations(const struct shell *sh, size_t argc, + char *argv[]) +{ + size_t id = 1; + + ARG_UNUSED(argv); + ARG_UNUSED(argc); + + shell_fprintf(sh, SHELL_NORMAL, "AP stations:\n"); + shell_fprintf(sh, SHELL_NORMAL, "============\n"); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + struct wifi_ap_sta_info *sta; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + if (!sta_list[i].valid) { + continue; + } + + sta = &sta_list[i].sta_info; + + shell_fprintf(sh, SHELL_NORMAL, "Station %zu:\n", id++); + shell_fprintf(sh, SHELL_NORMAL, "==========\n"); + shell_fprintf(sh, SHELL_NORMAL, "MAC: %s\n", + net_sprint_ll_addr_buf(sta->mac, + WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf))); + shell_fprintf(sh, SHELL_NORMAL, "Link mode: %s\n", + wifi_link_mode_txt(sta->link_mode)); + shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", + sta->twt_capable ? "Supported" : "Not supported"); + } + + if (id == 1) { + shell_fprintf(sh, SHELL_NORMAL, "No stations connected\n"); + } + k_mutex_unlock(&wifi_ap_sta_list_lock); + + return 0; +} + static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) @@ -1675,6 +1761,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, ": 0:Disable, 1:Optional, 2:Required.\n", cmd_wifi_ap_enable, 2, 4), + SHELL_CMD_ARG(stations, NULL, + "List stations connected to the AP", + cmd_wifi_ap_stations, + 1, 0), SHELL_SUBCMD_SET_END ); From 7300a52ddc328f6ba9b8d081a2224143f74c869d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 20 Nov 2023 15:00:59 +0000 Subject: [PATCH 4467/4498] [nrf fromlist] drivers: ieee802154: nrf5: Fix missed variable rename Fixes and issue with a variable that has been renamed but whose reference in the source file has not Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/65480 Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel --- drivers/ieee802154/ieee802154_nrf5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index defbc90cd07..df01f530abf 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -933,9 +933,9 @@ static int nrf5_configure(const struct device *dev, #if defined(CONFIG_NRF_802154_SER_HOST) net_time_t period_ns = nrf5_data.csl_period * NSEC_PER_TEN_SYMBOLS; - bool changed = (config->csl_rx_time - nrf5_data.csl_rx_time) % period_ns; + bool changed = (config->expected_rx_time - nrf5_data.csl_rx_time) % period_ns; - nrf5_data.csl_rx_time = config->csl_rx_time; + nrf5_data.csl_rx_time = config->expected_rx_time; if (changed) #endif /* CONFIG_NRF_802154_SER_HOST */ From 7513bd8b9de3664eea8dc02121fa083dbae9e188 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 23 Nov 2023 12:54:12 +0100 Subject: [PATCH 4468/4498] [nrf fromtree] sysbuild: introduce Kconfig setting for controlling HCI IPC inclusion Follow-up: #64704 Introducing NET_CORE_IMAGE_HCI_IPC Kconfig setting to control inclusion of HCI IPC image when building through sysbuild. This allows users with custom netcore applications to avoid inclusion of the default HCI IPC image. Signed-off-by: Torsten Rasmussen (cherry picked from commit 13f3c6d0bda59855b8928fb510cb1cd3687c4dce) Signed-off-by: Dominik Ermel --- samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild | 5 +++++ samples/bluetooth/broadcast_audio_sink/sysbuild.cmake | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild index 37a6b66c7f4..f434010f81d 100644 --- a/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild +++ b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake index c150913cc55..ed30d7f31f3 100644 --- a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) # For builds in the nrf5340, we build the netcore image with the controller set(NET_APP hci_ipc) From 7086c624dbd5fd627891e1a7ee683a182370657f Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Mon, 27 Nov 2023 19:31:30 +0100 Subject: [PATCH 4469/4498] [nrf fromtree] soc: arm: nrf52: Configurable EGU instance for anomaly 109 workaround Change makes EGU instance used for anomaly 109 workaround configurable. The default EGU instance (5) may be used for other purpose. Signed-off-by: Marek Pieta (cherry picked from commit 00d8263a935dbfed3088f0fdc911aab7eb801587) Signed-off-by: Dominik Ermel --- modules/hal_nordic/nrfx/nrfx_config.h | 2 ++ soc/arm/nordic_nrf/nrf52/Kconfig.soc | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index aaf31751004..b5b09b96078 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -586,6 +586,8 @@ #define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 #define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 #define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE \ + CONFIG_NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE #endif #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index 517b4ce2baa..de6a16129d3 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -147,4 +147,12 @@ config NRF52_ANOMALY_109_WORKAROUND 64MHz clock at the same time as the peripheral that is using DMA is started. This anomaly applies to IC revisions up to "3", the most recent one. +config NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE + int "Anomaly 109 workaround EGU instance" + depends on NRF52_ANOMALY_109_WORKAROUND + range 0 5 + default 5 + help + EGU instance used by the nRF52 Anomaly 109 workaround for PWM. + endif # SOC_SERIES_NRF52X From 23f410daa5232429398b95350a82c5368b4d32eb Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Tue, 28 Nov 2023 13:31:01 +0100 Subject: [PATCH 4470/4498] [nrf fromlist] drivers: usb: nrf_usbd_common: Remove unneeded assertion Code uses local RAM buffer to properly handle the case where provided USB transfer TX data is not in RAM. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/65865 Signed-off-by: Marek Pieta Signed-off-by: Dominik Ermel --- drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 9045e1ded70..3db193ee2f0 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -376,8 +376,6 @@ static bool nrf_usbd_common_feeder(nrf_usbd_common_ep_transfer_t *p_next, nrf_usbd_common_transfer_t *p_transfer, size_t ep_size) { - __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); - size_t tx_size = p_transfer->size; if (tx_size > ep_size) { From 6f609a096e5ecc3ac2a993de4b2bbc33c4fe3a98 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Tue, 5 Dec 2023 13:30:39 +0100 Subject: [PATCH 4471/4498] [nrf fromlist] logging: Fix using simplified message creation mode Change fixes marcos used to determine if argument types allow simplified message creation mode. Both arguments types must be proper. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/66156 Signed-off-by: Marek Pieta Signed-off-by: Dominik Ermel --- include/zephyr/logging/log_msg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index fabc7a16b0c..39cbf1cedbc 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -241,7 +241,7 @@ enum z_log_msg_mode { #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_0(fmt) 1 #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_1(fmt, arg) Z_CBPRINTF_IS_WORD_NUM(arg) #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_2(fmt, arg0, arg1) \ - Z_CBPRINTF_IS_WORD_NUM(arg0) || Z_CBPRINTF_IS_WORD_NUM(arg1) + Z_CBPRINTF_IS_WORD_NUM(arg0) && Z_CBPRINTF_IS_WORD_NUM(arg1) /** brief Determine if string arguments types allow to use simplified message creation mode. * From 6da4c914b11a8a5c0441ee2c50e9450908ca9a51 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 24 Nov 2023 12:45:11 +0100 Subject: [PATCH 4472/4498] [nrf fromtree] samples/bluetooth: sysbuild: Add Kconfig setting for HCI IPC inclusion Introduce NET_CORE_IMAGE_HCI_IPC Kconfig setting to control inclusion of HCI IPC image when building through sysbuild. This allows users with custom netcore applications to avoid inclusion of the default HCI IPC image. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit 8f78b7148ce5234aa877b2653ae99ddcab3a5c75) Signed-off-by: Dominik Ermel --- samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild | 5 +++++ samples/bluetooth/broadcast_audio_source/sysbuild.cmake | 2 +- samples/bluetooth/unicast_audio_client/Kconfig.sysbuild | 5 +++++ samples/bluetooth/unicast_audio_client/sysbuild.cmake | 2 +- samples/bluetooth/unicast_audio_server/Kconfig.sysbuild | 5 +++++ samples/bluetooth/unicast_audio_server/sysbuild.cmake | 2 +- 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild index 37a6b66c7f4..f434010f81d 100644 --- a/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild +++ b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake index c150913cc55..ed30d7f31f3 100644 --- a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) # For builds in the nrf5340, we build the netcore image with the controller set(NET_APP hci_ipc) diff --git a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild index 37a6b66c7f4..f434010f81d 100644 --- a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/unicast_audio_client/sysbuild.cmake b/samples/bluetooth/unicast_audio_client/sysbuild.cmake index c150913cc55..ed30d7f31f3 100644 --- a/samples/bluetooth/unicast_audio_client/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_client/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) # For builds in the nrf5340, we build the netcore image with the controller set(NET_APP hci_ipc) diff --git a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild index 37a6b66c7f4..f434010f81d 100644 --- a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/unicast_audio_server/sysbuild.cmake b/samples/bluetooth/unicast_audio_server/sysbuild.cmake index c150913cc55..ed30d7f31f3 100644 --- a/samples/bluetooth/unicast_audio_server/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_server/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) # For builds in the nrf5340, we build the netcore image with the controller set(NET_APP hci_ipc) From cebd9529012a78d5d15738b91b2556bfddc1c0ed Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 24 Nov 2023 12:02:14 +0100 Subject: [PATCH 4473/4498] [nrf fromtree] tests: bsim: Bluetooth: Enable nrf5340bsim CIS ACL group test Enable testing CIS ACL group test on nrf5340bsim. Signed-off-by: Vinayak Kariappa Chettimada (cherry picked from commit 411731f778b771f0130b2d7d39e7dfd326305f61) Signed-off-by: Dominik Ermel --- .../compile.nrf5340bsim_nrf5340_cpuapp.sh | 1 + tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild | 14 ++ tests/bsim/bluetooth/ll/cis/sysbuild.cmake | 47 +++++++ ...0_cpunet_iso_acl_group-bt_ll_sw_split.conf | 122 ++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild create mode 100644 tests/bsim/bluetooth/ll/cis/sysbuild.cmake create mode 100644 tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh index 4f175540347..65769185867 100755 --- a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh @@ -21,6 +21,7 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/bis sysbuild=1 compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf sysbuild=1 compile run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild b/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild new file mode 100644 index 00000000000..6c89fddc9f3 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild @@ -0,0 +1,14 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild.cmake b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake new file mode 100644 index 00000000000..495c3f4a20d --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake @@ -0,0 +1,47 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${APP_DIR}/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + # For the simulated board, the application core build will produce the final executable + # for that, we give it the path to the netcore image + set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" + ) + + if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + endif() + + # Let's build the net core library first + add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe +add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${DEFAULT_IMAGE} +) diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf new file mode 100644 index 00000000000..a3c8f43c71f --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf @@ -0,0 +1,122 @@ +CONFIG_IPC_SERVICE=y +CONFIG_MBOX=y + +CONFIG_ISR_STACK_SIZE=1024 +CONFIG_IDLE_STACK_SIZE=256 +CONFIG_MAIN_STACK_SIZE=512 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 +CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE=512 +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_CBPRINTF_REDUCED_INTEGRAL=y + +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_RESERVE=1 +CONFIG_BT_MAX_CONN=4 + +# Workaround: Unable to allocate command buffer when using K_NO_WAIT since +# Host number of completed commands does not follow normal flow control. +CONFIG_BT_BUF_CMD_TX_COUNT=10 + +CONFIG_BT_BUF_EVT_RX_COUNT=16 + +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 + +# Tx/Rx Thread Stack Sizes +CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y +CONFIG_BT_HCI_TX_STACK_SIZE=1152 +CONFIG_BT_RX_STACK_SIZE=640 +CONFIG_BT_CTLR_RX_PRIO_STACK_SIZE=448 + +# Host features +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV=y +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_PER_ADV_SYNC_MAX=2 + +# Broadcast and Connected ISO +CONFIG_BT_ISO_BROADCASTER=y +CONFIG_BT_ISO_SYNC_RECEIVER=y +CONFIG_BT_ISO_CENTRAL=y +CONFIG_BT_ISO_PERIPHERAL=y + +# ISO Streams +CONFIG_BT_ISO_MAX_CHAN=4 + +# Controller +CONFIG_BT_LL_SW_SPLIT=y +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_CTLR_DTM_HCI=y + +# Rx ACL and Adv Reports +CONFIG_BT_CTLR_RX_BUFFERS=9 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 + +# Coded PHY support +CONFIG_BT_CTLR_PHY_CODED=n + +# Advertising Sets and Extended Scanning +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_SET=3 +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 +CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 + +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_AUX_SET=3 +CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y +CONFIG_BT_CTLR_ADV_SYNC_SET=3 +CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=6 + +# Increase the below to receive interleaved advertising chains +CONFIG_BT_CTLR_SCAN_AUX_SET=1 + +CONFIG_BT_CTLR_ADV_RESERVE_MAX=n +CONFIG_BT_CTLR_CENTRAL_RESERVE_MAX=n +# CONFIG_BT_CTLR_CENTRAL_SPACING=10000 +CONFIG_BT_CTLR_CENTRAL_SPACING=0 +CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE=n +CONFIG_BT_CTLR_SCAN_UNRESERVED=n +CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH=y +CONFIG_BT_TICKER_EXT=y +CONFIG_BT_TICKER_EXT_SLOT_WINDOW_YIELD=y + +# Control Procedure +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 + +# ISO Broadcaster Controller +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_PERIODIC=y +CONFIG_BT_CTLR_ADV_ISO=y +CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_ADV_ISO_STREAM_MAX=2 + +# ISO Receive Controller +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_SYNC_PERIODIC=y +CONFIG_BT_CTLR_SYNC_ISO=y +CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=2 + +# ISO Connection Oriented +CONFIG_BT_CTLR_CENTRAL_ISO=y +CONFIG_BT_CTLR_PERIPHERAL_ISO=y +CONFIG_BT_CTLR_CONN_ISO_SDU_LEN_MAX=251 +CONFIG_BT_CTLR_CONN_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_CONN_ISO_STREAMS=4 +CONFIG_BT_CTLR_CONN_ISO_STREAMS_PER_GROUP=4 + +# ISO Transmissions +CONFIG_BT_CTLR_ISO_TX_BUFFERS=18 +CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=251 +CONFIG_BT_CTLR_ISOAL_SOURCES=4 + +# ISO Receptions +CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 +CONFIG_BT_CTLR_ISOAL_SINKS=4 + +# Tx Power Dynamic Control +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y From 2076afcd51b67a313fd5813bb74efe7ebe313c7e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 16:50:37 +0100 Subject: [PATCH 4474/4498] [nrf fromtree] sysbuild: Add extensions for native_simulator based targets Add 3 new functions to perform functions typically needed for native_simulator based targes and reduce the amount of boilerplate. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit 94cdfa60dc17cd4fea77f73b9654e0c0f3263175) Signed-off-by: Dominik Ermel --- share/sysbuild/CMakeLists.txt | 7 ++- .../native_simulator_sb_extensions.cmake | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index 7bbfe138760..8a15da9cef5 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023 Nordic Semiconductor +# Copyright (c) 2023 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 @@ -18,7 +18,10 @@ set(APP_DIR ${APP_DIR} CACHE PATH "Main Application Source Directory") list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) # List of Zephyr and sysbuild CMake modules we need for sysbuild. # Note: sysbuild_kconfig will internally load kconfig CMake module. -set(zephyr_modules extensions sysbuild_extensions python west root zephyr_module boards shields sysbuild_kconfig) +set(zephyr_modules extensions + sysbuild_extensions python west root zephyr_module boards shields + sysbuild_kconfig native_simulator_sb_extensions + ) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS ${zephyr_modules}) diff --git a/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake b/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake new file mode 100644 index 00000000000..3d888d1775e --- /dev/null +++ b/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake @@ -0,0 +1,62 @@ +# Copyright (c) 2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Usage: +# native_simulator_set_final_executable() +# +# When building for a native_simulator based target (including bsim targets), +# this function adds an extra build target which will copy the executable produced by +# `` to the top level, as zephyr/zephyr.exe +# +# This final image is expected to have been set to assemble other dependent images into +# itself if necessary, by calling native_simulator_set_child_images() +# This will allow other tools, like twister, or the bsim test scripts, as well as users to find +# this final executable in the same place as for non-sysbuild builds. +# +function(native_simulator_set_final_executable final_image) + if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${final_image}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${final_image} + ) + endif() +endfunction() + +# Usage: +# native_simulator_set_child_images( ) +# +# When building for a native_simulator based target (including bsim targets), +# this function sets a `` as dependencies of `` +# and configures the final image to assemble the child images into its final executable. +# +function(native_simulator_set_child_images final_image child_image) + if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + add_dependencies(${final_image} ${child_image}) + + set(CHILD_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${child_image}/zephyr/zephyr.elf) + set_property(TARGET ${final_image} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${CHILD_LIBRARY_PATH}\"\n" + ) + endif() +endfunction() + +# Usage: +# native_simulator_set_primary_mcu_index( [ ...]) +# +# Propagate the SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX setting, +# if it is set, to each given image CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX +# +function(native_simulator_set_primary_mcu_index) + if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + foreach(arg IN LISTS ARGV) + set_property(TARGET ${arg} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + endforeach() + endif() +endfunction() From c4fefa79ee03bf2c4b9c8d49012c50888ae43e09 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 18:44:30 +0100 Subject: [PATCH 4475/4498] [nrf fromtree] samples/bluetooth: Reduce sysbuild boilerplate Reduce the sysbuild boilerplate required for the nrf5340bsim targets. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit 8b70d98dcb1eb4f24ea5971cf81204f942c2804e) Signed-off-by: Dominik Ermel --- .../broadcast_audio_sink/sysbuild.cmake | 24 ++----------------- .../broadcast_audio_source/sysbuild.cmake | 24 ++----------------- .../unicast_audio_client/sysbuild.cmake | 24 ++----------------- .../unicast_audio_server/sysbuild.cmake | 24 ++----------------- 4 files changed, 8 insertions(+), 88 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake index ed30d7f31f3..2523aac8ea7 100644 --- a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake @@ -18,27 +18,7 @@ if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake index ed30d7f31f3..2523aac8ea7 100644 --- a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake @@ -18,27 +18,7 @@ if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/unicast_audio_client/sysbuild.cmake b/samples/bluetooth/unicast_audio_client/sysbuild.cmake index ed30d7f31f3..2523aac8ea7 100644 --- a/samples/bluetooth/unicast_audio_client/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_client/sysbuild.cmake @@ -18,27 +18,7 @@ if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/unicast_audio_server/sysbuild.cmake b/samples/bluetooth/unicast_audio_server/sysbuild.cmake index ed30d7f31f3..2523aac8ea7 100644 --- a/samples/bluetooth/unicast_audio_server/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_server/sysbuild.cmake @@ -18,27 +18,7 @@ if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) From 273508cf01151f3ab8d13e4df580f0b941fdcdeb Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 18:46:21 +0100 Subject: [PATCH 4476/4498] [nrf fromtree] tests/bsim/bluetooth: Reduce sysbuild boilerplate Reduce the sysbuild boilerplate required for the nrf5340bsim targets. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit 41f4826f272ae38dd1043bfda0c38cc8b6e7128f) Signed-off-by: Dominik Ermel --- .../broadcast_audio_sink/sysbuild.cmake | 9 +----- .../unicast_audio_client/sysbuild.cmake | 9 +----- tests/bsim/bluetooth/ll/bis/sysbuild.cmake | 29 ++----------------- tests/bsim/bluetooth/ll/cis/sysbuild.cmake | 29 ++----------------- tests/bsim/bluetooth/ll/conn/sysbuild.cmake | 29 ++----------------- 5 files changed, 11 insertions(+), 94 deletions(-) diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake index a922830546d..2bf2920a476 100644 --- a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake @@ -3,11 +3,4 @@ include(${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake) -if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) -endif() +native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake index 9686cde1bce..85b85b7cb63 100644 --- a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake @@ -3,11 +3,4 @@ include(${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/sysbuild.cmake) -if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) -endif() +native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) diff --git a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake index eb75debccd3..69397264edf 100644 --- a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake @@ -16,32 +16,9 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - - if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - endif() + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe -add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} -) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild.cmake b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake index 495c3f4a20d..a1258ecf1f2 100644 --- a/tests/bsim/bluetooth/ll/cis/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake @@ -16,32 +16,9 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - - if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - endif() + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe -add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} -) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake index 2294fd5bb5e..4dfa34ef519 100644 --- a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake @@ -11,32 +11,9 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) BOARD ${SB_CONFIG_NET_CORE_BOARD} ) - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - - if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - endif() + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe -add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} -) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) From bbbf671ef88cdf8c3b064fc79a38eec317a780c6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 18:46:52 +0100 Subject: [PATCH 4477/4498] [nrf fromtree] samples/subsys/logging/multidomain: Reduce sysbuild boilerplate Reduce the sysbuild boilerplate required for the nrf5340bsim targets Signed-off-by: Alberto Escolar Piedras (cherry picked from commit b02fc27464c46076a62e2401e51ce7ae0302de95) Signed-off-by: Dominik Ermel --- .../subsys/logging/multidomain/sysbuild.cmake | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/samples/subsys/logging/multidomain/sysbuild.cmake b/samples/subsys/logging/multidomain/sysbuild.cmake index e50f47b6db1..496a7a03f9d 100644 --- a/samples/subsys/logging/multidomain/sysbuild.cmake +++ b/samples/subsys/logging/multidomain/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_NET_CORE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) From e4b78eddab9555b80726f00dfae9139f7f85cc35 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 18:47:45 +0100 Subject: [PATCH 4478/4498] [nrf fromtree] samples/boards/nrf/nrf53_sync_rtc: Reduce sysbuild boilerplate Reduce the sysbuild boilerplate required for the nrf5340bsim targets Signed-off-by: Alberto Escolar Piedras (cherry picked from commit cbce3383d1e7cbdb23c6caac6d1bf9a5d8236091) Signed-off-by: Dominik Ermel --- .../boards/nrf/nrf53_sync_rtc/sysbuild.cmake | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake index a5d1eb9874f..0c97244fd7b 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake +++ b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_NET_CORE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${REMOTE_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) From ab3ed158d57b033b08ed76952e3112b9802c7d67 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 29 Nov 2023 18:48:02 +0100 Subject: [PATCH 4479/4498] [nrf fromtree] samples/drivers/mbox: Reduce sysbuild boilerplate Reduce the sysbuild boilerplate required for the nrf5340bsim targets Signed-off-by: Alberto Escolar Piedras (cherry picked from commit d2151aa114cbf389fdec972119b218f7b39f3c9b) Signed-off-by: Dominik Ermel --- samples/drivers/mbox/sysbuild.cmake | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake index 1bd6a00ae9e..a8dfb8ebdf4 100644 --- a/samples/drivers/mbox/sysbuild.cmake +++ b/samples/drivers/mbox/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_REMOTE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${REMOTE_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) From 53f7c555705ef394fbbf154770c6be493c23ded4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 15 Dec 2023 07:57:14 +0000 Subject: [PATCH 4480/4498] [nrf noup] samples/tests: Disable PM for some sysbuild builds Disables partition manager when building some samples and tests which use sysbuild to prevent build issues Signed-off-by: Jamie McCrae --- samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf | 1 + samples/drivers/mbox/sysbuild.conf | 1 + samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf | 1 + samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf | 1 + samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf | 1 + samples/subsys/logging/multidomain/sysbuild.conf | 1 + tests/boot/mcuboot_recovery_retention/sysbuild.conf | 1 + tests/boot/test_mcuboot/sysbuild.conf | 1 + 8 files changed, 8 insertions(+) create mode 100644 samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf create mode 100644 samples/drivers/mbox/sysbuild.conf create mode 100644 samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf create mode 100644 samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf create mode 100644 samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf create mode 100644 samples/subsys/logging/multidomain/sysbuild.conf diff --git a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/drivers/mbox/sysbuild.conf b/samples/drivers/mbox/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/drivers/mbox/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/logging/multidomain/sysbuild.conf b/samples/subsys/logging/multidomain/sysbuild.conf new file mode 100644 index 00000000000..6408669a847 --- /dev/null +++ b/samples/subsys/logging/multidomain/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/tests/boot/mcuboot_recovery_retention/sysbuild.conf b/tests/boot/mcuboot_recovery_retention/sysbuild.conf index 47f00ff3cff..3b5b3c96380 100644 --- a/tests/boot/mcuboot_recovery_retention/sysbuild.conf +++ b/tests/boot/mcuboot_recovery_retention/sysbuild.conf @@ -1 +1,2 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_PARTITION_MANAGER=n diff --git a/tests/boot/test_mcuboot/sysbuild.conf b/tests/boot/test_mcuboot/sysbuild.conf index 47f00ff3cff..3b5b3c96380 100644 --- a/tests/boot/test_mcuboot/sysbuild.conf +++ b/tests/boot/test_mcuboot/sysbuild.conf @@ -1 +1,2 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_PARTITION_MANAGER=n From 4a03d8a097843a324fe7746fb5383476b341671a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 13 Dec 2023 15:46:45 +0200 Subject: [PATCH 4481/4498] [nrf fromtree] net: shell: Rename the common.h to be more unique As the common.h is only meant to be used by the network shell files, rename it to be more descriptive in order to avoid possible conflicts with any other common.h file. Signed-off-by: Jukka Rissanen (cherry picked from commit 477a4a5d34042f49830fc8aff94ffc16a98cce10) --- subsys/net/lib/shell/allocs.c | 2 +- subsys/net/lib/shell/arp.c | 2 +- subsys/net/lib/shell/capture.c | 2 +- subsys/net/lib/shell/conn.c | 2 +- subsys/net/lib/shell/dns.c | 2 +- subsys/net/lib/shell/events.c | 2 +- subsys/net/lib/shell/gptp.c | 2 +- subsys/net/lib/shell/iface.c | 2 +- subsys/net/lib/shell/ipv4.c | 2 +- subsys/net/lib/shell/ipv6.c | 2 +- subsys/net/lib/shell/mem.c | 2 +- subsys/net/lib/shell/nbr.c | 2 +- subsys/net/lib/shell/net_shell.c | 2 +- subsys/net/lib/shell/{common.h => net_shell_private.h} | 0 subsys/net/lib/shell/ping.c | 2 +- subsys/net/lib/shell/pkt.c | 2 +- subsys/net/lib/shell/ppp.c | 2 +- subsys/net/lib/shell/resume.c | 2 +- subsys/net/lib/shell/route.c | 2 +- subsys/net/lib/shell/sockets.c | 2 +- subsys/net/lib/shell/stats.c | 2 +- subsys/net/lib/shell/suspend.c | 2 +- subsys/net/lib/shell/tcp.c | 2 +- subsys/net/lib/shell/udp.c | 2 +- subsys/net/lib/shell/virtual.c | 2 +- subsys/net/lib/shell/vlan.c | 2 +- subsys/net/lib/shell/websocket.c | 2 +- 27 files changed, 26 insertions(+), 26 deletions(-) rename subsys/net/lib/shell/{common.h => net_shell_private.h} (100%) diff --git a/subsys/net/lib/shell/allocs.c b/subsys/net/lib/shell/allocs.c index 1c6e7288003..a2669590520 100644 --- a/subsys/net/lib/shell/allocs.c +++ b/subsys/net/lib/shell/allocs.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) static void allocs_cb(struct net_pkt *pkt, diff --git a/subsys/net/lib/shell/arp.c b/subsys/net/lib/shell/arp.c index fb1582411e9..58889f27d5c 100644 --- a/subsys/net/lib/shell/arp.c +++ b/subsys/net/lib/shell/arp.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_ARP) #include "ethernet/arp.h" diff --git a/subsys/net/lib/shell/capture.c b/subsys/net/lib/shell/capture.c index f05531562ae..0c7347f8774 100644 --- a/subsys/net/lib/shell/capture.c +++ b/subsys/net/lib/shell/capture.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include diff --git a/subsys/net/lib/shell/conn.c b/subsys/net/lib/shell/conn.c index 36831809eb8..24b528537bd 100644 --- a/subsys/net/lib/shell/conn.c +++ b/subsys/net/lib/shell/conn.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_TCP) #include "tcp_internal.h" diff --git a/subsys/net/lib/shell/dns.c b/subsys/net/lib/shell/dns.c index 24a52f5e8a2..54c768cecd1 100644 --- a/subsys/net/lib/shell/dns.c +++ b/subsys/net/lib/shell/dns.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_DNS_RESOLVER) static void dns_result_cb(enum dns_resolve_status status, diff --git a/subsys/net/lib/shell/events.c b/subsys/net/lib/shell/events.c index 047fd1e2186..5a5d0f38f7d 100644 --- a/subsys/net/lib/shell/events.c +++ b/subsys/net/lib/shell/events.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(net_shell); #include #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_MGMT_EVENT_MONITOR) #define EVENT_MON_STACK_SIZE 1024 diff --git a/subsys/net/lib/shell/gptp.c b/subsys/net/lib/shell/gptp.c index a156637e3af..0de653e26cd 100644 --- a/subsys/net/lib/shell/gptp.c +++ b/subsys/net/lib/shell/gptp.c @@ -19,7 +19,7 @@ LOG_MODULE_DECLARE(net_shell); #include "ethernet/gptp/gptp_private.h" #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_GPTP) static const char *selected_role_str(int port); diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index 89983bd4839..53d4e99bd21 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_NATIVE) struct ethernet_capabilities { diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index 8fc88168c9a..e8584b205fb 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/ipv4.h" #if defined(CONFIG_NET_NATIVE_IPV4) diff --git a/subsys/net/lib/shell/ipv6.c b/subsys/net/lib/shell/ipv6.c index f81b8dcae23..04efda65d0f 100644 --- a/subsys/net/lib/shell/ipv6.c +++ b/subsys/net/lib/shell/ipv6.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include "../ip/ipv6.h" #if defined(CONFIG_NET_IPV6_FRAGMENT) diff --git a/subsys/net/lib/shell/mem.c b/subsys/net/lib/shell/mem.c index cf58cda6bd6..47058f92767 100644 --- a/subsys/net/lib/shell/mem.c +++ b/subsys/net/lib/shell/mem.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" struct ctx_info { int pos; diff --git a/subsys/net/lib/shell/nbr.c b/subsys/net/lib/shell/nbr.c index fd420b818ae..63b62406702 100644 --- a/subsys/net/lib/shell/nbr.c +++ b/subsys/net/lib/shell/nbr.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 19bab12e029..9f932cb1bc4 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include -#include "common.h" +#include "net_shell_private.h" #include "net_shell.h" int get_iface_idx(const struct shell *sh, char *index_str) diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/net_shell_private.h similarity index 100% rename from subsys/net/lib/shell/common.h rename to subsys/net/lib/shell/net_shell_private.h diff --git a/subsys/net/lib/shell/ping.c b/subsys/net/lib/shell/ping.c index 8b52df110be..833c6eb8d54 100644 --- a/subsys/net/lib/shell/ping.c +++ b/subsys/net/lib/shell/ping.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(net_shell); #include #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/icmpv6.h" #include "../ip/icmpv4.h" diff --git a/subsys/net/lib/shell/pkt.c b/subsys/net/lib/shell/pkt.c index 09d7ae6738a..3306b05d1a7 100644 --- a/subsys/net/lib/shell/pkt.c +++ b/subsys/net/lib/shell/pkt.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) { diff --git a/subsys/net/lib/shell/ppp.c b/subsys/net/lib/shell/ppp.c index 9b5f8355d47..f63c6ca3324 100644 --- a/subsys/net/lib/shell/ppp.c +++ b/subsys/net/lib/shell/ppp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_PPP) #include diff --git a/subsys/net/lib/shell/resume.c b/subsys/net/lib/shell/resume.c index 585d421efab..dcd3fbf309d 100644 --- a/subsys/net/lib/shell/resume.c +++ b/subsys/net/lib/shell/resume.c @@ -9,7 +9,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_resume(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/route.c b/subsys/net/lib/shell/route.c index d48c442ed41..035b56f6dfc 100644 --- a/subsys/net/lib/shell/route.c +++ b/subsys/net/lib/shell/route.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include "../ip/route.h" diff --git a/subsys/net/lib/shell/sockets.c b/subsys/net/lib/shell/sockets.c index 792e34efc21..8be67fc5faf 100644 --- a/subsys/net/lib/shell/sockets.c +++ b/subsys/net/lib/shell/sockets.c @@ -7,7 +7,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include #if defined(CONFIG_NET_SOCKETS_OBJ_CORE) diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c index 455f5d7decd..666a98e35d7 100644 --- a/subsys/net/lib/shell/stats.c +++ b/subsys/net/lib/shell/stats.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/net_stats.h" diff --git a/subsys/net/lib/shell/suspend.c b/subsys/net/lib/shell/suspend.c index 326eb602077..cfa01375cac 100644 --- a/subsys/net/lib/shell/suspend.c +++ b/subsys/net/lib/shell/suspend.c @@ -9,7 +9,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_suspend(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index f90e16b3b66..e2839af36ba 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) static struct net_context *tcp_ctx; diff --git a/subsys/net/lib/shell/udp.c b/subsys/net/lib/shell/udp.c index 9eaf3254514..7bccbf93ba3 100644 --- a/subsys/net/lib/shell/udp.c +++ b/subsys/net/lib/shell/udp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_NATIVE_UDP) static struct net_context *udp_ctx; diff --git a/subsys/net/lib/shell/virtual.c b/subsys/net/lib/shell/virtual.c index 19c9b1c1b0e..4eaabaa9916 100644 --- a/subsys/net/lib/shell/virtual.c +++ b/subsys/net/lib/shell/virtual.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_VIRTUAL) static void virtual_iface_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c index 0a980caa11f..ea7103ef1c9 100644 --- a/subsys/net/lib/shell/vlan.c +++ b/subsys/net/lib/shell/vlan.c @@ -15,7 +15,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_VLAN) static void iface_vlan_del_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/lib/shell/websocket.c b/subsys/net/lib/shell/websocket.c index f3e77187627..56e705199e3 100644 --- a/subsys/net/lib/shell/websocket.c +++ b/subsys/net/lib/shell/websocket.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #include "websocket/websocket_internal.h" From 85a31e7c746db6023bced4cc9c997431f119d007 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 15 Dec 2023 09:35:22 +0000 Subject: [PATCH 4482/4498] [nrf noup] cmake: modules: kconfig: Add hide child/parent variable Adds a variable to Kconfig which, when set, will disable showing child/parent Kconfig values in builds (enabled when Sysbuild is used) Signed-off-by: Jamie McCrae --- cmake/modules/kconfig.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 632e9a72422..1a78b3ebd02 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -147,6 +147,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} TOOLCHAIN_HAS_NEWLIB=${_local_TOOLCHAIN_HAS_NEWLIB} TOOLCHAIN_HAS_PICOLIBC=${_local_TOOLCHAIN_HAS_PICOLIBC} + HIDE_CHILD_PARENT_CONFIG=${SYSBUILD} EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} From e3c172a8be333da55dc7802cb83eff23e786c81c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 7 Sep 2023 17:53:19 +0200 Subject: [PATCH 4483/4498] [nrf fromtree] llext: add support for shared objects Add support for linking PIC shared object, which only require linking, using their PLT and GOT lists and don't need any relocation otherwise. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit d6a5a6e04c0a6f64b93d341af4b8f04bd698401c) --- subsys/llext/llext.c | 112 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 3 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 3d99c8af4fa..7b8099a9190 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -446,6 +446,105 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) return 0; } +/* + * Find the section, containing the supplied offset and return file offset for + * that value + */ +static size_t llext_file_offset(struct llext_loader *ldr, size_t offset) +{ + unsigned int i; + + for (i = 0; i < LLEXT_SECT_COUNT; i++) + if (ldr->sects[i].sh_addr <= offset && + ldr->sects[i].sh_addr + ldr->sects[i].sh_size > offset) + return offset - ldr->sects[i].sh_addr + ldr->sects[i].sh_offset; + + return offset; +} + +static void llext_link_plt(struct llext_loader *ldr, struct llext *ext, elf_shdr_t *shdr) +{ + unsigned int sh_cnt = shdr->sh_size / shdr->sh_entsize; + /* + * CPU address where the .text section is stored, we use .text just as a + * reference point + */ + uint8_t *text = ext->mem[LLEXT_MEM_TEXT]; + + LOG_DBG("Found %p in PLT %u size %u cnt %u text %p", + (void *)llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr->sh_name), + shdr->sh_type, shdr->sh_entsize, sh_cnt, (void *)text); + + const elf_shdr_t *sym_shdr = ldr->sects + LLEXT_SECT_SYMTAB; + unsigned int sym_cnt = sym_shdr->sh_size / sym_shdr->sh_entsize; + + for (unsigned int i = 0; i < sh_cnt; i++) { + elf_rela_t rela; + + int ret = llext_seek(ldr, shdr->sh_offset + i * shdr->sh_entsize); + + if (!ret) { + ret = llext_read(ldr, &rela, sizeof(rela)); + } + + if (ret < 0) { + LOG_ERR("PLT: failed to read RELA #%u, trying to continue", i); + continue; + } + + /* Index in the symbol table */ + unsigned int j = ELF32_R_SYM(rela.r_info); + + if (j >= sym_cnt) { + LOG_WRN("PLT: idx %u >= %u", j, sym_cnt); + continue; + } + + elf_sym_t sym_tbl; + + ret = llext_seek(ldr, sym_shdr->sh_offset + j * sizeof(elf_sym_t)); + if (!ret) { + ret = llext_read(ldr, &sym_tbl, sizeof(sym_tbl)); + } + + if (ret < 0) { + LOG_ERR("PLT: failed to read symbol table #%u RELA #%u, trying to continue", + j, i); + continue; + } + + uint32_t stt = ELF_ST_TYPE(sym_tbl.st_info); + const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym_tbl.st_name); + /* + * Both r_offset and sh_addr are addresses for which the extension + * has been built. + */ + size_t got_offset = llext_file_offset(ldr, rela.r_offset) - + ldr->sects[LLEXT_SECT_TEXT].sh_offset; + + if (stt == STT_NOTYPE && sym_tbl.st_shndx == SHN_UNDEF && name[0] != '\0') { + const void *link_addr = llext_find_sym(NULL, name); + + if (!link_addr) { + LOG_WRN("PLT: cannot find idx %u name %s", j, name); + continue; + } + + if (!rela.r_offset) { + LOG_WRN("PLT: zero offset idx %u name %s", j, name); + continue; + } + + LOG_DBG("symbol %s offset %#x r-offset %#x .text offset %#x", + name, got_offset, + rela.r_offset, ldr->sects[LLEXT_SECT_TEXT].sh_offset); + + /* Resolve the symbol */ + *(const void **)(text + got_offset) = link_addr; + } + } +} + __weak void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval) { } @@ -486,12 +585,19 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) if (strcmp(name, ".rel.text") == 0 || strcmp(name, ".rela.text") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_TEXT]; - } else if (strcmp(name, ".rel.bss") == 0) { + } else if (strcmp(name, ".rel.bss") == 0 || + strcmp(name, ".rela.bss") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_BSS]; - } else if (strcmp(name, ".rel.rodata") == 0) { + } else if (strcmp(name, ".rel.rodata") == 0 || + strcmp(name, ".rela.rodata") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_RODATA]; - } else if (strcmp(name, ".rel.data") == 0) { + } else if (strcmp(name, ".rel.data") == 0 || + strcmp(name, ".rela.data") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_DATA]; + } else if (strcmp(name, ".rela.plt") == 0 || + strcmp(name, ".rela.dyn") == 0) { + llext_link_plt(ldr, ext, &shdr); + continue; } LOG_DBG("relocation section %s (%d) linked to section %d has %d relocations", From 3ffae176371cc9aaf673e1ae05c3498e08f9fec9 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 6 Sep 2023 15:52:46 +0200 Subject: [PATCH 4484/4498] [nrf fromtree] llext: export some symbols Export some symbols for loadable modules. Also add an EXPORT_SYSCALL() helper macro for exporting system calls by their official names. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit 69cdc3289279f476a495e6920a954fc194eec043) --- include/zephyr/llext/symbol.h | 10 ++++++++++ kernel/mutex.c | 3 +++ kernel/thread.c | 2 ++ lib/os/assert.c | 4 +++- subsys/llext/CMakeLists.txt | 3 +-- subsys/llext/llext_export.c | 17 +++++++++++++++++ subsys/logging/log_msg.c | 2 ++ 7 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 subsys/llext/llext_export.c diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index b1aef67413e..84e43d22b5b 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -78,6 +78,16 @@ struct llext_symtable { .name = STRINGIFY(x), .addr = &x, \ } +/** + * @brief Export a system call to a table of symbols + * + * Takes a system call name and uses @a EXPORT_SYMBOL() to export the respective + * function. + * + * @param x System call to export + */ +#define EXPORT_SYSCALL(x) EXPORT_SYMBOL(z_impl_ ## x) + /** * @} */ diff --git a/kernel/mutex.c b/kernel/mutex.c index 6d22ce83f22..622422aef7b 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -37,6 +37,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); /* We use a global spinlock here because some of the synchronization @@ -195,6 +196,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) return -EAGAIN; } +EXPORT_SYSCALL(k_mutex_lock); #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_lock(struct k_mutex *mutex, @@ -280,6 +282,7 @@ int z_impl_k_mutex_unlock(struct k_mutex *mutex) return 0; } +EXPORT_SYSCALL(k_mutex_unlock); #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) diff --git a/kernel/thread.c b/kernel/thread.c index 8f60054e798..fc31f4b36d8 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -29,6 +29,7 @@ #include #include #include +#include #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -141,6 +142,7 @@ bool k_is_in_isr(void) { return arch_is_in_isr(); } +EXPORT_SYMBOL(k_is_in_isr); /* * This function tags the current thread as essential to system operation. diff --git a/lib/os/assert.c b/lib/os/assert.c index b6a33ae7320..1fee487bff6 100644 --- a/lib/os/assert.c +++ b/lib/os/assert.c @@ -7,7 +7,7 @@ #include #include #include - +#include /** * @brief Assert Action Handler @@ -42,6 +42,7 @@ __weak void assert_post_action(const char *file, unsigned int line) k_panic(); } +EXPORT_SYMBOL(assert_post_action); void assert_print(const char *fmt, ...) { @@ -53,3 +54,4 @@ void assert_print(const char *fmt, ...) va_end(ap); } +EXPORT_SYMBOL(assert_print); diff --git a/subsys/llext/CMakeLists.txt b/subsys/llext/CMakeLists.txt index ac54f3172c3..b129dc7f943 100644 --- a/subsys/llext/CMakeLists.txt +++ b/subsys/llext/CMakeLists.txt @@ -1,6 +1,5 @@ if(CONFIG_LLEXT) zephyr_library() - zephyr_library_sources(llext.c) - zephyr_library_sources(buf_loader.c) + zephyr_library_sources(llext.c llext_export.c buf_loader.c) zephyr_library_sources_ifdef(CONFIG_LLEXT_SHELL shell.c) endif() diff --git a/subsys/llext/llext_export.c b/subsys/llext/llext_export.c new file mode 100644 index 00000000000..0ec7fe4ac0a --- /dev/null +++ b/subsys/llext/llext_export.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memset); diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 8023cefbf8c..da9dffdc62e 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -10,6 +10,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(log); BUILD_ASSERT(sizeof(struct log_msg_desc) == sizeof(uint32_t), @@ -270,6 +271,7 @@ void z_impl_z_log_msg_static_create(const void *source, z_log_msg_finalize(msg, source, out_desc, data); } +EXPORT_SYSCALL(z_log_msg_static_create); #ifdef CONFIG_USERSPACE static inline void z_vrfy_z_log_msg_static_create(const void *source, From 710df4fbe059934005a8c7399658b9e6ac6fd346 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 28 Sep 2023 16:45:34 +0200 Subject: [PATCH 4485/4498] [nrf fromtree] llext: make buffer access functions accessible externally llext_seek(), llext_read() and llext_peek() are needed outside of the extension code too, move them to a header. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit a2a62b46a32bb6f4dcf8a21ee229e8eeea2c594d) --- include/zephyr/llext/loader.h | 19 +++++++++++++++++++ subsys/llext/llext.c | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index 3cc53da7d88..3102f17cf1a 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -97,6 +97,25 @@ struct llext_loader { /** @endcond */ }; +static inline int llext_read(struct llext_loader *l, void *buf, size_t len) +{ + return l->read(l, buf, len); +} + +static inline int llext_seek(struct llext_loader *l, size_t pos) +{ + return l->seek(l, pos); +} + +static inline void *llext_peek(struct llext_loader *l, size_t pos) +{ + if (l->peek) { + return l->peek(l, pos); + } + + return NULL; +} + /** * @} */ diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 7b8099a9190..6c47ddf29c6 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -21,25 +21,6 @@ K_HEAP_DEFINE(llext_heap, CONFIG_LLEXT_HEAP_SIZE * 1024); static const char ELF_MAGIC[] = {0x7f, 'E', 'L', 'F'}; -static inline int llext_read(struct llext_loader *l, void *buf, size_t len) -{ - return l->read(l, buf, len); -} - -static inline int llext_seek(struct llext_loader *l, size_t pos) -{ - return l->seek(l, pos); -} - -static inline void *llext_peek(struct llext_loader *l, size_t pos) -{ - if (l->peek) { - return l->peek(l, pos); - } - - return NULL; -} - static sys_slist_t _llext_list = SYS_SLIST_STATIC_INIT(&_llext_list); sys_slist_t *llext_list(void) From 94e99e2116f5370aee0d56bc4e52fcd5c0415bc9 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 29 Sep 2023 09:56:47 +0200 Subject: [PATCH 4486/4498] [nrf fromtree] llext: add Xtensa test support Add support for running a modular "Hello world" example on Xtensa. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit e5c8d181d46f948e35851dd826637e32e48b77f6) --- tests/subsys/llext/hello_world/CMakeLists.txt | 23 +++++++++++++++---- tests/subsys/llext/src/test_llext_simple.c | 4 ++-- tests/subsys/llext/testcase.yaml | 5 ++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/subsys/llext/hello_world/CMakeLists.txt b/tests/subsys/llext/hello_world/CMakeLists.txt index 1a16d4be26b..6519075e2f4 100644 --- a/tests/subsys/llext/hello_world/CMakeLists.txt +++ b/tests/subsys/llext/hello_world/CMakeLists.txt @@ -6,11 +6,26 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(hello_world) # TODO check which architecture is being used -set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb") +if(CONFIG_ARM) + set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb") -add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext - COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c -o ${PROJECT_BINARY_DIR}/hello_world.llext ${PROJECT_SOURCE_DIR}/hello_world.c -) + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c + -o ${PROJECT_BINARY_DIR}/hello_world.llext + ${PROJECT_SOURCE_DIR}/hello_world.c + ) +elseif(CONFIG_XTENSA) + set(CMAKE_C_FLAGS "-shared" "-fPIC" "-nostdlib" "-nodefaultlibs") + + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} + -o ${PROJECT_BINARY_DIR}/hello_world.pre.llext + ${PROJECT_SOURCE_DIR}/hello_world.c + COMMAND ${CROSS_COMPILE}strip -R .xt.* + -o ${PROJECT_BINARY_DIR}/hello_world.llext + ${PROJECT_BINARY_DIR}/hello_world.pre.llext + ) +endif() set(HELLO_WORLD_LLEXT ${PROJECT_BINARY_DIR}/hello_world.llext PARENT_SCOPE) diff --git a/tests/subsys/llext/src/test_llext_simple.c b/tests/subsys/llext/src/test_llext_simple.c index ef0e62b93b5..d96191c1d72 100644 --- a/tests/subsys/llext/src/test_llext_simple.c +++ b/tests/subsys/llext/src/test_llext_simple.c @@ -9,7 +9,7 @@ #include #include -#ifdef CONFIG_ARM /* ARMV7 */ +#if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA) const static uint8_t hello_world_elf[] __aligned(4) = { #include "hello_world.inc" }; @@ -24,7 +24,7 @@ const static uint8_t hello_world_elf[] __aligned(4) = { */ ZTEST(llext, test_llext_simple) { - const char name[16] = {'h', 'e', 'l', 'l', 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const char name[16] = "hello"; struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(hello_world_elf, ARRAY_SIZE(hello_world_elf)); struct llext_loader *loader = &buf_loader.loader; diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index 79d8f5a1fd9..0bbccd5e1ca 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -9,3 +9,8 @@ tests: # Broken platforms platform_exclude: - nuvoton_pfm_m487 # See #63167 + llext.simple.xtensa: + arch_allow: xtensa + # Broken platforms + platform_exclude: + - qemu_xtensa_mmu # ELF sections are read-only, and without peek() .text copy isn't executable From 7459728d37f039ded52d174b9597112676d7a5b5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 15 Nov 2023 17:19:57 +0100 Subject: [PATCH 4487/4498] [nrf fromtree] llext: clarify section map allocation size Use an element size explicitly when calculating the array size and use the calculated size for memset(). Signed-off-by: Guennadi Liakhovetski (cherry picked from commit b5ce5012e29d5c1c2e2d5c1dac7fa15766db79e5) --- subsys/llext/llext.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 6c47ddf29c6..4f43dc17a1d 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -670,7 +670,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) memset(ldr->sects, 0, sizeof(ldr->sects)); ldr->sect_cnt = 0; - size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(uint32_t); + size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(ldr->sect_map[0]); ldr->sect_map = k_heap_alloc(&llext_heap, sect_map_sz, K_NO_WAIT); if (!ldr->sect_map) { @@ -678,7 +678,8 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) ret = -ENOMEM; goto out; } - memset(ldr->sect_map, 0, ldr->hdr.e_shnum*sizeof(uint32_t)); + memset(ldr->sect_map, 0, sect_map_sz); + ldr->sect_cnt = ldr->hdr.e_shnum; ext->mem_size += sect_map_sz; From 1f1048a9e98c1b11a9caa0628ab63c2af4200e93 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 20 Nov 2023 15:21:46 +0100 Subject: [PATCH 4488/4498] [nrf fromtree] llext: remove redundant initialisation a new llext object is completely initialised with zeros after allocation, no need to additionally set members of an embedded into it array to NULL. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit b5506feed5a6fc3c1b9a44343deb62ce4445b240) --- subsys/llext/llext.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 4f43dc17a1d..a24d2b0833f 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -792,10 +792,6 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) } memset(*ext, 0, sizeof(struct llext)); - for (int i = 0; i < LLEXT_MEM_COUNT; i++) { - (*ext)->mem[i] = NULL; - } - ldr->hdr = ehdr; ret = do_llext_load(ldr, *ext); break; From fa777ddca7d6c7a37f512d324c7c8ce69221ddfb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 23 Nov 2023 16:50:20 +0100 Subject: [PATCH 4489/4498] [nrf fromtree] llext: fix read-only extension image When using the LLEXT buffer loader we now avoid copying extensions from storage to allocated memory by pointing directly into the stored image. We then also perform linking and relocation in that memory, which modifies its contents. However, this is impossible if that storage is read-only. Add a Kconfig flag to distinguish between writable and read-only storage types. Also use that flag to decide, whether the extension image in test_llext_simple.c should be defined as const or not. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit dbea13a1c7b10afdb6293b643e3cede34dfa3345) --- subsys/llext/Kconfig | 6 ++++++ subsys/llext/llext.c | 3 ++- tests/subsys/llext/src/test_llext_simple.c | 5 ++++- tests/subsys/llext/testcase.yaml | 2 ++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index 9fec16cb230..b1210b8f2e8 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -27,6 +27,12 @@ config LLEXT_SHELL_MAX_SIZE help When loading llext with shell it is stored in a temporary buffer of this size +config LLEXT_STORAGE_WRITABLE + bool "llext storage is writable" + help + Select if LLEXT storage is writable, i.e. if extensions are stored in + RAM and can be modified in place + module = LLEXT module-str = llext source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index a24d2b0833f..8dd5801bc95 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -242,7 +242,8 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, return 0; } - if (ldr->sects[sect_idx].sh_type != SHT_NOBITS) { + if (ldr->sects[sect_idx].sh_type != SHT_NOBITS && + IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) { ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset); if (ext->mem[mem_idx]) { ext->mem_on_heap[mem_idx] = false; diff --git a/tests/subsys/llext/src/test_llext_simple.c b/tests/subsys/llext/src/test_llext_simple.c index d96191c1d72..557697f576c 100644 --- a/tests/subsys/llext/src/test_llext_simple.c +++ b/tests/subsys/llext/src/test_llext_simple.c @@ -10,7 +10,10 @@ #include #if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA) -const static uint8_t hello_world_elf[] __aligned(4) = { +#ifndef CONFIG_LLEXT_STORAGE_WRITABLE +const +#endif +static uint8_t hello_world_elf[] __aligned(4) = { #include "hello_world.inc" }; #endif diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index 0bbccd5e1ca..2747edf8d0c 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -11,6 +11,8 @@ tests: - nuvoton_pfm_m487 # See #63167 llext.simple.xtensa: arch_allow: xtensa + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=y # Broken platforms platform_exclude: - qemu_xtensa_mmu # ELF sections are read-only, and without peek() .text copy isn't executable From de1f9a6bec791ecf6c6d3002bd143a719b3ad069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Tue, 21 Nov 2023 08:27:07 +0100 Subject: [PATCH 4490/4498] [nrf fromtree] boards: nrf52840dk_nrf52840: Fix reserved GPIO lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 7a83724e0f18d7f2400517407150f9e9a1ecd6e6. There is no reason to mark that many GPIO lines as reserved on this board. And doing so causes several existing tests to fail as they are configured to use some of those now unavailable GPIO lines. Limit reservation to the lines that actually cannot be used as GPIOs without changes in the default configuration of the board or its physical modification (via solder bridges), i.e.: - XL1 and XL2 (connections for the 32.768 kHz crystal) - NFC1 and NFC2 (NFC antenna connections) - RESET - TXD and RXD (lines used by the console UART) - QSPI lines: CS, CLK, and DIO0-3 Provide names for all the GPIO lines that are described on the board. Even for the reserved ones, so that it is clear why they are reserved. Signed-off-by: Andrzej Głąbek (cherry picked from commit b172e5133b09ec0c32dbbe74dafa9ef8f2d9da33) --- .../nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index dcee7b0db5f..60c3ecf55a1 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -149,18 +149,18 @@ &gpio0 { status = "okay"; - gpio-reserved-ranges = <0 11>, <17 7>, <26 6>; - gpio-line-names = "", "", "", "", "", "", "", "", - "", "", "", "BUTTON1", "BUTTON2", "LED1", "LED2", "LED3", - "LED4", "", "", "", "", "", "", "", - "BUTTON3", "BUTTON4", "", "", "", "", "", ""; + gpio-reserved-ranges = <0 2>, <6 1>, <8 3>, <17 7>; + gpio-line-names = "XL1", "XL2", "AREF", "A0", "A1", "RTS", "TXD", + "CTS", "RXD", "NFC1", "NFC2", "BUTTON1", "BUTTON2", "LED1", + "LED2", "LED3", "LED4", "QSPI CS", "RESET", "QSPI CLK", + "QSPI DIO0", "QSPI DIO1", "QSPI DIO2", "QSPI DIO3","BUTTON3", + "BUTTON4", "SDA", "SCL", "A2", "A3", "A4", "A5"; }; &gpio1 { status = "okay"; - gpio-reserved-ranges = <0 1>, <9 1>, <12 4>; gpio-line-names = "", "D0", "D1", "D2", "D3", "D4", "D5", "D6", - "D7", "", "D8", "D9", "", "", "", ""; + "D7", "", "D8", "D9", "D10", "D11", "D12", "D13"; }; &uart0 { From 1a7010954b184b1e29c9ad1a9a19600f213e4c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Tue, 21 Nov 2023 17:36:52 +0100 Subject: [PATCH 4491/4498] [nrf fromtree] tests: drivers: flash: Update nrf52840dk_mx25r_high_perf.overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 7a83724e0f18d7f2400517407150f9e9a1ecd6e6. This overlay uses an alternative connection (via spi2) for the external flash present on the nRF52840 DK and it needs to use one of the QSPI pins as GPIO, to get CS line control in the SPI communication. To make it possible, that GPIO must be removed from those marked as reserved. Signed-off-by: Andrzej Głąbek (cherry picked from commit 4a262c3947e745fff542a2d78dbedfe460cc2541) --- .../flash/common/boards/nrf52840dk_mx25r_high_perf.overlay | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay b/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay index eabb26ebda6..a67f25e46c0 100644 --- a/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay +++ b/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay @@ -1,5 +1,9 @@ /delete-node/ &qspi; +&gpio0 { + gpio-reserved-ranges = <0 2>, <6 1>, <8 3>, <18 6>; +}; + &spi2 { compatible = "nordic,nrf-spim"; status = "okay"; From bea8d6bcc98289cf500718f87b303a3127bcca54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Tue, 21 Nov 2023 17:43:35 +0100 Subject: [PATCH 4492/4498] [nrf fromtree] tests: drivers: flash: Use fixtures for tests requiring external chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several scenarios in this test require specific external flash chips to be connected to the nRF52840 DK. Specify proper fixture for them so that they are not performed on the board without those required external components connected. Signed-off-by: Andrzej Głąbek (cherry picked from commit c949018d36bd6a2b0453a52062adcc108060cce4) --- tests/drivers/flash/common/testcase.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index 9aa13bb40d5..88ce0a40e07 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -21,7 +21,7 @@ tests: - OVERLAY_CONFIG=boards/nrf52840_flash_qspi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_mx25l51245g.overlay harness_config: - fixture: external_flash + fixture: external_flash_mx25l51245g integration_platforms: - nrf52840dk_nrf52840 drivers.flash.common.soc_flash_nrf: @@ -78,11 +78,15 @@ tests: extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor.overlay + harness_config: + fixture: external_flash_mx25v1635f drivers.flash.common.spi_nor_wp_hold: platform_allow: nrf52840dk_nrf52840 extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor_wp_hold.overlay + harness_config: + fixture: external_flash_mx25v1635f drivers.flash.common.sam0: platform_allow: - atsamd20_xpro From a5fa2ffb399f2d98727848c2d37a4d3cfc9af53b Mon Sep 17 00:00:00 2001 From: Marcin Jelinski Date: Thu, 4 Jan 2024 14:23:54 +0100 Subject: [PATCH 4493/4498] [nrf fromtree] samples: ipc: multi_endpoint: Fix synchronisation of data receiving The incorrect semaphore was used for the ipc1 instance to synchronise the data receiving. This commit fixes it. Signed-off-by: Marcin Jelinski (cherry picked from commit 7815e52fd15d49c47b4201470b0fe52dab3e3c9c) Signed-off-by: Dominik Ermel --- samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c | 2 +- samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c index 9b288f8a6a1..f285f4b6d23 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c @@ -193,7 +193,7 @@ static void ipc1_ept_recv(const void *data, size_t len, void *priv) { ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc0B_data_sem); + k_sem_give(&ipc1_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c index 78d7af05288..4ad5659df38 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c @@ -190,7 +190,7 @@ static void ipc1_ept_recv(const void *data, size_t len, void *priv) { ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc0B_data_sem); + k_sem_give(&ipc1_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { From 6946f4c6748eebe6c048074c2f1fa0cda9f25cb9 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 4 Dec 2023 14:26:17 -0800 Subject: [PATCH 4494/4498] [nrf fromtree] doc: ext/gh_utils: pass MAINTAINERS.yml to Maintainers This changes to pass full path of MAINTAINERS.yml to get_maintainer.Maintainers(). Without this, Maintainers would use git to find the top level of Zephyr tree. This restricts building of doc only when the build directory is under Zephyr root. Since we have ZEPHYR_BASE in gh_utils, we can pass full path of MAINTAINERS.yml to Maintainers() so that doc build directory no longer has to be under Zephyr root. Fixes #65037 Signed-off-by: Daniel Leung (cherry picked from commit ede9b0337c72ca5312d35961c2bdd4ad9334f42c) --- doc/_extensions/zephyr/gh_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 6ba75ce5ab7..2c992436c87 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -53,7 +53,7 @@ from get_maintainer import Maintainers -MAINTAINERS : Final[Maintainers] = Maintainers() +MAINTAINERS : Final[Maintainers] = Maintainers(filename=f"{ZEPHYR_BASE}/MAINTAINERS.yml") __version__ = "0.1.0" From ed20dd66fdd81408bc26a693c299f829fb05214f Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 9 Jan 2024 15:23:54 +0100 Subject: [PATCH 4495/4498] [nrf fromlist] doc: extensions: zephyr-domain: fix object descriptions Zephyr's domain code-sample object description was incorrectly yielded, making Sphinx inventory (objects.inv) unusable on other projects that need to use the domain via Intersphinx. Ref. https://www.sphinx-doc.org/en/master/extdev/domainapi.html Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67384 Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 139f7c8bb14f14a772ee0d9343bd06d727d9cca3) --- doc/_extensions/zephyr/domain.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 8c395142818..beb94eb4d2f 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -249,7 +249,7 @@ class ZephyrDomain(Domain): directives = {"code-sample": CodeSampleDirective} object_types: Dict[str, ObjType] = { - "code-sample": ObjType("code sample", "code-sample"), + "code-sample": ObjType("code-sample", "code-sample"), } initial_data: Dict[str, Any] = {"code-samples": {}} @@ -267,9 +267,9 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: def get_objects(self): for _, code_sample in self.data["code-samples"].items(): yield ( + code_sample["id"], code_sample["name"], - code_sample["name"], - "code sample", + "code-sample", code_sample["docname"], code_sample["id"], 1, From 774a528ecbc8aae382cc969d8b944b59e4bb9dde Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 9 Jan 2024 15:34:14 +0100 Subject: [PATCH 4496/4498] [nrf fromlist] doc: extensions: zephyr-domain: make transforms optional So that external users of the domain only interested in e.g. referencing roles, can skip such unneeded transformations. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/67384 Signed-off-by: Gerard Marull-Paretas (cherry picked from commit bc7baa515ac10f07592777b76ca4dd8b3139dccc) --- doc/_extensions/zephyr/domain.py | 14 +++++++++++++- doc/conf.py | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index beb94eb4d2f..053965e26e3 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -80,6 +80,9 @@ class ConvertCodeSampleNode(SphinxTransform): default_priority = 100 def apply(self): + if not self.config.zephyr_domain_apply_transforms: + return + matcher = NodeMatcher(CodeSampleNode) for node in self.document.traverse(matcher): self.convert_node(node) @@ -140,6 +143,9 @@ class ProcessRelatedCodeSamplesNode(SphinxPostTransform): default_priority = 5 # before ReferencesResolver def run(self, **kwargs: Any) -> None: + if not self.config.zephyr_domain_apply_transforms: + return + matcher = NodeMatcher(RelatedCodeSamplesNode) for node in self.document.traverse(matcher): id = node["id"] # the ID of the node is the name of the doxygen group for which we @@ -308,10 +314,16 @@ class CustomDoxygenGroupDirective(DoxygenGroupDirective): def run(self) -> List[Node]: nodes = super().run() - return [RelatedCodeSamplesNode(id=self.arguments[0]), *nodes] + + if self.config.zephyr_domain_apply_transforms: + return [RelatedCodeSamplesNode(id=self.arguments[0]), *nodes] + else: + return nodes def setup(app): + app.add_config_value("zephyr_domain_apply_transforms", False, "env") + app.add_domain(ZephyrDomain) app.add_transform(ConvertCodeSampleNode) diff --git a/doc/conf.py b/doc/conf.py index 85488318a0a..4bab42dcc90 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -302,6 +302,10 @@ "build/dts/api/compatibles/**/*", ] +# -- Options for zephyr.domain -------------------------------------------- + +zephyr_domain_apply_transforms = True + # -- Options for sphinx.ext.graphviz -------------------------------------- graphviz_dot = os.environ.get("DOT_EXECUTABLE", "dot") From ead6b4d1db7209abda3c81a7bd8312eb42ef7a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 21 Nov 2023 15:59:33 +0100 Subject: [PATCH 4497/4498] [nrf fromtree] tests: logging: log_backend_uart: Disable backends other than UART MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test expects that there are no other backends enabled and some may be enabled by default. Signed-off-by: Krzysztof Chruściński (cherry picked from commit c143daf98dbdc88f2154f86c05c4256d01cb79f2) Signed-off-by: Dominik Ermel --- tests/subsys/logging/log_backend_uart/prj.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/subsys/logging/log_backend_uart/prj.conf b/tests/subsys/logging/log_backend_uart/prj.conf index ef6894f355e..c8615a65adb 100644 --- a/tests/subsys/logging/log_backend_uart/prj.conf +++ b/tests/subsys/logging/log_backend_uart/prj.conf @@ -9,3 +9,8 @@ CONFIG_LOG=y CONFIG_LOG_BACKEND_UART=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_PRINTK=n +# +# Disable all potential other default backends +CONFIG_LOG_BACKEND_NATIVE_POSIX=n +CONFIG_LOG_BACKEND_RTT=n +CONFIG_LOG_BACKEND_XTENSA_SIM=n From 883c3709f9c8fd845a8dfa39d2583d5c665a915b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 23 Nov 2023 12:18:17 +0100 Subject: [PATCH 4498/4498] [nrf fromtree] tests: modem: backend: uart: Add fixture to test suite Add fixture to test suite to allow for and signal that the test must be run on real hardware. Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit bec7789862ea5449a63626de9c943678c95a13e8) Signed-off-by: Dominik Ermel --- .../uart/boards/b_u585i_iot02a.overlay | 35 +++------------- .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 42 ++++++++----------- tests/subsys/modem/backends/uart/src/main.c | 2 +- .../subsys/modem/backends/uart/testcase.yaml | 18 ++++---- 4 files changed, 33 insertions(+), 64 deletions(-) diff --git a/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay index 394facef7bb..30402e6e9d2 100644 --- a/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay +++ b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay @@ -1,34 +1,11 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + /* - * Pins 2 and 3 must be connected to each other on the STMOD+1 connector to - * loopback RX/TX. + * The Arduino D0 and D1 must be connected to each other to loopback RX/TX. */ -/ { - aliases { - test-uart = &usart2; - }; -}; - -&gpioh { - misc_fixed_usart2 { - gpio-hog; - gpios = <13 GPIO_ACTIVE_HIGH>; - output-high; - }; -}; - -&gpdma1 { - status = "okay"; -}; - -&usart2 { - pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3 &usart2_rts_pa1 &usart2_cts_pa0>; - pinctrl-names = "default"; - current-speed = <115200>; - - dmas = <&gpdma1 0 27 STM32_DMA_PERIPH_TX - &gpdma1 1 26 STM32_DMA_PERIPH_RX>; +dut: &usart3 { + dmas = <&gpdma1 0 29 STM32_DMA_PERIPH_TX + &gpdma1 1 28 STM32_DMA_PERIPH_RX>; dma-names = "tx", "rx"; - - status = "okay"; }; diff --git a/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay index 2d47b0f0744..777aebd8d3b 100644 --- a/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -1,37 +1,31 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + /* - * Pins P1.10 and P1.11 must be connected to each other to loopback RX/TX. + * Pins P0.4 and P0.5 must be connected to each other to loopback RX/TX. */ -/ { - aliases { - test-uart = &uart1; - }; -}; - -&uart1 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&uart1_default>; - pinctrl-1 = <&uart1_sleep>; - hw-flow-control; - pinctrl-names = "default", "sleep"; -}; - &pinctrl { - uart1_default: uart1_default { + uart1_default_alt: uart1_default_alt { group1 { - psels = ; - }; - group2 { - psels = ; + psels = , + ; }; }; - uart1_sleep: uart1_sleep { + uart1_sleep_alt: uart1_sleep_alt { group1 { - psels = , - ; + psels = , + ; low-power-enable; }; }; }; + +dut: &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart1_default_alt>; + pinctrl-1 = <&uart1_sleep_alt>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/subsys/modem/backends/uart/src/main.c b/tests/subsys/modem/backends/uart/src/main.c index 8a6c4c2813a..dffc203bb21 100644 --- a/tests/subsys/modem/backends/uart/src/main.c +++ b/tests/subsys/modem/backends/uart/src/main.c @@ -28,7 +28,7 @@ /*************************************************************************************************/ /* Mock pipe */ /*************************************************************************************************/ -static const struct device *uart = DEVICE_DT_GET(DT_ALIAS(test_uart)); +static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(dut)); static struct modem_backend_uart uart_backend; static struct modem_pipe *pipe; K_SEM_DEFINE(receive_ready_sem, 0, 1); diff --git a/tests/subsys/modem/backends/uart/testcase.yaml b/tests/subsys/modem/backends/uart/testcase.yaml index 626ca639f75..54d8a6b9470 100644 --- a/tests/subsys/modem/backends/uart/testcase.yaml +++ b/tests/subsys/modem/backends/uart/testcase.yaml @@ -1,21 +1,19 @@ # Copyright (c) 2023 Trackunit Corporation # SPDX-License-Identifier: Apache-2.0 +common: + harness: ztest + harness_config: + fixture: gpio_loopback + platform_allow: + - b_u585i_iot02a + - nrf5340dk_nrf5340_cpuapp + tests: modem.backends.uart.async: - tags: modem_backend - harness: ztest - platform_allow: - - b_u585i_iot02a - - nrf5340dk_nrf5340_cpuapp extra_configs: - CONFIG_UART_ASYNC_API=y modem.backends.uart.isr: - tags: modem_backend - harness: ztest - platform_allow: - - b_u585i_iot02a - - nrf5340dk_nrf5340_cpuapp extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=y
  • *d-AAXhl-I#L^zTm)A?z zeyQ^6I`G{Nzp1HgZ$ckz9nqk{2a*^m zt-RoRP}b?I`=EU>_-#b@k_WqBQCnp624T1ANJuSkz~$N6XMlcm5aBn3>lzO%yc6mO z$UizegX-0`uYpu&8X{wmwv4X3y~{oip!gOf2PqN(BHLTFz;SJg0dGv|IEkC*X#ktD z!6GBB4}xlI#w5Z%&9LLtx&L4B%*`S*Mc;m7F7tajTSkODMGdy8yS>#6=nr6r%)h@n zBOR*@u&1Y-{6sNY<@z>+Ss2zuq45l@rF{T^EAd%XsOoCXGVsa`B^UU@+=Mck6HTFJ)c+^c!b9k^xuLM7}Xtl z5E!UYkwdIiJ)a3rG4iZpEd_zKmL`^xfr|%99Af7NrOYIG%r#JfFvt~=J!BSdiQy@~ zipqjU5TR73v1x*la^ypt7kkdU^TbiOc^vvXkywoUZ#n?TP#|&VNB}^`b)n9 z4w6PO`GujeBV zeswNUg&G5@YAEWkkcElvBE1#OAcUJGuVFcqi&PBAEKbL8gNQrI)@>uaM9--Gvo;j} zHfr9-e+0K~p*^{=ezAczJ9#G72HRaWq=@bVGLn_n;ta-hfo4(Xpvsk z@D0i}l54GS(d}LNI>9>0+%NEIuYOjkMW=@`n6?3Kqupa5_FTXLYt!iMP1>|PnBd?$ ztE8MRu#M>MM)wpm`}gs9dBNYPEsY~t^pgiKG%?6}dx6#QCclb)k|Vy1ZjvLtf?gg{ z6*D*;x|kY*4nY(_Ql8>JRSdc~=iDXdVZ!Ql-&oyi$YXUNi$kY6ixojb((qyvm4_J8 zit?H?lU^Aa56$I}q#a6z0(!ex>~_URDbT9NMUtP&Jlq@>N@lxaf3P`7j|mPl6cV0? z>;hT^vM8%@yYO_ZU#F>7aVusP`bxpjM&$>nBhPBXQ7Z`F$q?|~6o*3HAeuK~aup^X z)AMqKm-!5LAEsa@!p=%_H~Gm|G-V24%NDw4uRL*R?Z26jKJQ)2EfyJ zoEKVjj1}jj_|GzV;|G&Qj%OAHh#{%z(ndA<-3&@#`X7MIcrB<#DDXd1EYFx)~Ot%3Z2JS@y8=Eo0o)bVVU9?ccP7un1_V0Kt=IjE8jxx@=M zWP>t07tO-1Jr-!=BsCB@<>9(o@07E_Gm%~HFo_$(vp>#dRbhapsApN=0er&92x&M+ z%nSXn`!DkDzq<=U91E9n3Q1Ny3Lxd|vd?xlK^~5;b01KW{sB-BH|5z9IlhN-_wq(Q zLb5@QAD%;wTawjWIP_wpQrKQj>!}=AUId`tv)T3qn$!6$)Pmo**eitoq>9nn%j71$ zruyakR*Z$!i}H~(TSB&;=kK9>m4DW)$Wp$>q-hWA1)A&pWR82qb^EQQ?wJ8L$zfO? z#qVieu5*2xC|qABe8{W#gU}TMb%WlN9`&D7{M3Ak#Bk*%I@KLp7jBeT3KitaubtTh zI6o`NvxH1+P|a1#jPDt&xy7hO-Jrin0f(FiNjg?d`KRr|ez){sELhKqLHde85W1C^ zu_wy(#AJhthBHn#ODN9V?UAN!W=5D?p1s)CeecCT8RSiCjdv$X6ld7hq%{>tj`Ln0 zvw%H8UN!J@E}4iqpx8B+D-_cRlG5GT)??l+Uq@F|+WJH`y{bDF`b70UV_Tb-n9c`|~XQb2}EPyCN>R)VuQ_TYiOCKuDb{_MLzj z3SU*SZ{J^uDbn)OOd30!igP=oAp?V+)I(-)#NJr^h=5L2w2U=$0q1qT1;#Z`ydn=W z^vA12&SVy_Smy!6qw7%T327N;!~0^N_u-o<_cl4dvI`ntkFBXnkKtYp<tOODI zKY+BVWFF!Vzo*wBZ%v_vA|3)E=~PjQr&NUvexECDXmS)KuotKt;c;kkwK5q%Xf68% z3;FuY*X}6pMAb7d>WTiIxI=etO3&K0nkBO8M{iVql{Tn8v}ChW|9QiUR9M_hvN+@+ zym*~k@+vg0sV@agZs$nbnuhP2n72ob%CC!o9QE1sd_K^Gl;c3ha~)e_=St>Ut; zIAm^ItxQLQMU7ph8%!+MtH|AGgld!_)VE>Ik&*};GdOsJ)zKugBk)7e<9^B+6AaZK zo%_pKzE4!CCMVQ795i9uFR4a^%=-p2X(5IUFdD{$z1xPW^iL0KJjV|&f&Vm)tuTZw z*eIXUpun!1R`3AXZf=BZv)d0sjX$}@=Kw>sv-Wh>K8T4RWSMSn$QuGdP^XVwjM2PCPvK?olp@6^@e zD%>uQ{FH0SOc`1<+YUx6E+KxsDYVG-0%%|`KGgZA)q-(VUSqeh^T=x9(n6J*x0e9y z;v~X+K~8Tan-=6@9ztn*%U%y`_)vw0(bA*a5mo|ANpmj71=E9ad`m^hwx!mg1*OIu zkV37PA(nEz(s^;qZhYDsAQ%0NS=#DFXbSdoYlHougO#7fhil&6a!^ z7iqcrEjaWU{qGz$IOYs;>V~DOeU2>7jf)<(1+_s)V`SU>AU&^$WM;_P!h>mQ zaQFE^dix>7agpyqaw;&Mx2ab_A7O;P%NWjvf-z;4|$;y>EALjZDWUo4vm?`MFB?ZV^DOEgL^G7rR-%db=-7( z`1)bGekz%-(;CtB-RL&LG{Sc6@Z5yK+oc*#`Eg~;;!IeNRt`B|@e}4$m%qtp`cXG1 zU3?)pbwi4zQ&#b;Iz`aVpmEJFfny!EKBsHeVeC-9`1HwiuDdJ(7;l_bC>d~*Q>J4P z%1J5T7EH+9Me5NrzoFedpE5-8+s3vufvNBtM~39Kv{$pKZ?84JESo;^q={q~h1#&) zX+fG$J5Q@Uomr2(hkI06oC8)yke zcJWk-`hDm2x1JfJtVIp&HvU18i#7wcUp;EQp3+kUXRHrg?O@f>*;85dm$Elp?@(`* zd(MZ9mz@1SfIUH-7ZqrqlbGn6SuVlWZi7kF;8{c;dRP~eLCb-`nIdJ(AG;74q-ioi z8D#@B-~=UcJ+joo}3Kg}xrEicL~N`)|Er6WT|!vE_Q>9K{tk z=O@LJk3ikaTxU@$nldfgc9pXKr?0mFi>mAThldy%q#G$|L^?$nx}{sX89D`&?hwf# zM!LJCq)UcQi6JD0kOmPH@f*E;@8^B~?{$4}V#n;Y&t7NO+3UB~rh2x;!oTU4af#FV z3sA};Vz=fFNMFhnC(bA0Dpw^rif_LzJt<$@Q&y+dEp}||I?^4-pyThFG+nFnSPT$O zKJb<#yUc?OUX`ja5EIB$y)-9o)-rh_qhR@J<>XCL#fuTS(o&t{aSPT`;oj4Uyp^$s zCw%EquUU+C0fVv?bxQ2N0D}Jx)a-|@<<~oGG3aM`hxW&~Uj_Pq0lNL`uHF$|J}2(U z@F>`Y!q#=Lr)69MCvuc%6hAyq%G0`y9Z0@UMjB5UzW0f~U8LVL42D_ygX{?)cxNkq45q?$g9t>YVHP$Or$*$Kv9Xy$(_NzXM1GOFHHr9~a zmdy(By7t+&ON*)JRW~hv5BQ4IJA3(IiGel(7l}UBPv6I>CF)=b1epm*)H3JKFWG(i zuKI#9Op(ySJWZ9$mBA!;Hh*sWL{i6&<^fgof!QZv5&+CeShsD(4zmbHnPsn-H!QS} zqtMB7MUoSZLu~yTawnuRAFWi0X1bI2{dJSxRGy0o8evs8PZimwQMMRnKxNbFcE;-& zr7$6MJEV0XNweQ8;6rpWnAhppY@1DkB>lk^dCgDer!entw|Zt>1ViWvKSis3H97IH zu-kr~jr*E+r7wD-SsvGN(uFtAr)?sq7w#V;eJ7?8y(cxRDTE&m6%e$^3gYb0nw+oB*+R#mMhsLN4?&dl{)>X8-tkz%LP9Lw|&)|XT$kcmXB`t0{u!ytI&z*G0!cA1r4rh0ZhQf+P_!d7{x8q z8U-Q1~8X_?fiO&D#YCn5ddr^l;=yle z)NcrQVA~G*`R@v5H)BYT1V(hz+&&-K4`vp*6#g!F1AnF16O(b*vt~bFUT~KXy!Q*> zurYN%eJMiQ8-0t^0T)36ZkvM<$Y7+h#Qn?^^85wJ`H2*piu_QNLZ0_-*E#-u)<~5# zMI&_3_#o|gsaTep7ayhoN0Ob+UmrgNVJkH_q4l1s$8sA#W@+PXwk~}Fb>fWbLCsJN z%<{f5^v)LT2By|Rel5&uawDS+yH$bLx;z*r8`CaiHiImwU8(C?CUnk!^dy}E)Q?y_ zJ>}}C!xs{N1k7M_I@5 z{Vw!eq=>*~0`%2!9xe4jG1~3skH{%rtB22jTG6NXRLhS3Juh0n#=I2y8uMEJzTw%) zbZpsR-#62xsW(riVzOVYO0C9ZwtcRkpH~RZAbvGyOw}6w3xLBzFe9P6YMC8ge;#sB zA7f0OFq17X>_0_!tKiSA-EwP}pqB=+A)Ce?3MyLoE81H>kwOs>%@kic>%rEC3V5X- z8jo_pb>!qU4~=^;0##ouHGHnFgi^PB=Z2N6hLe16tYmND2ZIijR|w7>9xU3_qD6VA z<>U70Vs$#Qe0$Sxpz@w;pVT#af^B3UpF6}zSd+?6&Xr{t7%LHN@C~1Ce4dL; z49G+EhYa`^0B^|RN1Mu$PdRUvn@>HHs1-ZIYmskn3;1SeOazXMv`}^A#=Y2-jc4>+ zkHDQ6otR75G9^9UgA6c@u|QJ}CY|84UMq4ocSt~cu=h{{4d_dOm8hDKrsSc;p|*8R zEed~l`TN=8fXKcTHm4l0fTr)mXH`GGfBNb_a(@v0h%TCEshB9X3<2G}c=NYiYN7=s zHZM7mg49Ug2hNjI<+Bf$mx4ZV2+S_}2y@L$Dd&BrI-seMa%ntzmntOk%rZN|HF)!?~z>CZnuS1ucqT8;WwgB#<`~yz~9X?&KF5Lb_A)(ReW7qc|KP%~`J2sgu%f>@?W3DmIy*|Vu?Fpms zmzc*0LN16K%BzkY-)3%!s417Wa3VJ_0YO4o87VV9g5_a|h*$SDpcOVpyvI}p4##vw z&Av%9D@Ze{y;RCh0{E)9Kl|x_F6;=Ae0W+2#`r5c;u2yJ>u)pd70zh;%ylIzp8e`E z_x>hc@!KbF&tv3w1zgj6>G81>YtKMLJkIPUy`J#v_g}Ci23Nb$8h@}(dAHMpJ`B{M z73BD$3}Y~NRYdd72g$i;tiEDwCGSNv6zfzvzGaFX;7m?5@F|rD+S1 z#=XIiw*X*LQvx8m?O8Lqs!v_Smn)l4P06QzNF!pJLx6c!gCs@=jtU$WL6%T=H{mTap z8xdu~4W+pihD6SqX)$=<*|ig!TgJK;COt^r=xaow&x9(zYEcTHg=_f~3> zrQc;ttl78ZB*?^aVmrDSejclt`Bl8^h}tgq`GT8KY3C<#0gy(>Bl5R6RuRzi-G_C* zzX6e$_E+6ue!t7NJUf3$ZxC3~?=GWfkR1LiSdt08$! zA`qW?A8AyCrIR>snNg07kYGh&W`h_WK&JE04j}R?W;ELr7E#MMN zS%-;^s_{7Lokm#sOk1_o@)wP|Hu8=hxb-gcl1F(1{MBqaQ()iKu7g{}vu|FHXT=wg zw$nZw+KO|h^YeM==wVq#QT{oI4p-al4;RwOd)1|@QJCW$MeF`9IK+u(KAQKic+zek z({!D!b*!vz&$fAn3T%8Q;1RVzA!2h1a18;yCzLhAFMOu;Hpa2V7|tWwSKrT*Rr|g> zj)BIW61F@_jh_+jkR_j-1I?D^iCPH=;Vcdxv<*X5h|)6-J#FI2xRF*S8j=WK6%WO- zsIl;0eVy!}z8&(B=7&J@_YA_p?#;)JKe%2g>i=-XNxZ+^|K$59y}F#>%)aOa^pLnE z1^^UpNb8d-^;*=|N_B#(_|VII!Ui{1O%IwFR|;_5pQXD$KW!%=r9CM_f}~=$j>y2R zt)1KAy7{qd40fz`?IN8nlJeun;qDYkg%;E?UNa%6PCMfd_7B}Bg~nD`;Y@(87|Ogg zXTvw%3YXsg?3^foz_i zDbNaqe5npw5umT!YwaBK&qUQeG4K-MX8o=jqINkxL!y%y^{yHG_eWVVF&i}UV;*jH z)5NbS(x%vl3<46-&HFjXLk9UwURX6Ngf_)1|3H-3-p(Hy`=r-^a2H=kLjR0phiiNvl^OpK!s^L;2K;z|F$EfByqzK zEX#p;!e8UwqDjg!<)l+PrWsQD!|h=WQ<}O?fv5B)`f&1#3l2_CI22*!1eAWVB>XKOddQ_Tx&eEw?-ZmxyuS_KVIKH-| z#6mZPr_RG?g+<2bBU%d=ic=J%b5-DsxGHG2%BBoFA`+l?twewZFL23B&p|*!Avr*M zhAg9Qhp&`O2v6*K!UbPc#PDNF)p+4tAwr|56DgZ?FACKzVkld0^iLzR$b-c?3-0!h zm2Q?C^9H4k6jqpyQ*}1WZC~HiNs3!oRu?mCxh`E3OkdRCq;JepXsv?O2uQnPSAQdyZ%9*>t(v8N>0m1k#KvSS=6?_pVOvVc z1KoZpQ(vNXm^Cu>V_G<^e=UZ4aovS|-b1x`!VYy8L6sY4mFinvg0>fR^b)0)fH=_< z0cDYys4tDkQYb$#>{8{GECfswmB-0Qs-|O_sQ4TdYH|`8NlU9~qW}Ot!dfo2%vu;j zv=-G<`i0NznZL@-Qz?&?GMBIkg|0cIb4TU~yv;FEk3$;rB{e)X>WS=}#6)R(%~`IbEG1$?#ETy2YCW<8 z4rq&&h)n3Vgfh&TvUSO+?a(X7k?6C56vsIy%+vDFv!l;OYFy{ ztGkFO{r`&CboCMu%gddbwBHk?G0bYTEY~&mgPE!kkXyLd0~YWpM0(_iY$68%I-W46jLj+6Mq3tT)%BD^Vt3oAAi%*|kdUNZNYKO=ss_&J>GA55K zaQLrFDWH&gOurmY16;UBf~`3{WWyt{9I6DRx7E}Bk!Ec7fqbjGrDylLaNx)-@cfU| zbBIp;_z0BXPkERhf4+>;%dB_A(C+CCJ&Wbn`hR z+Qd%!-U$UsS7{7zIfa@Cs`RYdz>K1@ggz-na}2O>VXWul!k$|O9ppK{F&_lkj3aii z#;AfRb(;t=2Zu{x-n-?pXL> zI(IBm{r~Uf-st(Q?UUW~g^*%??N%ILPWfiY%rpxHzFf`nuqp~g%L#FjlqC;0KQqRM zt3--HEj?}NnUg&jD^KJyJMre*BV68eo~haP$_^Y*C@e;FT-8{Ov8Q%?lkrr{9Tc%ZczAr9|sMu+RI)}M(;tfrMfMPE+One2(4o- zLf>QJ*gIR28yMSp+VgGR1u6l&KG3`xos(018qWe6oSOwFk0Z@|mp}1&+PIKDDO@Oo zX-5rcQes>um*RaOpX4GG65ji>zAfpcBHy?d?a0%T(RDxeE!!a3d3DkX^4jT%sKS?wxTDSMYE9@nkh{Dy3i z1*G#c3&8IHyq{nT(?S=yo)kh(SI|T7 zo43?_=T~m)aLIiExTpM8cV4?ay@vhj;kS6@dio{WLVz6Mv1Xx0A_G272{H07T>1yR zSMZizm$69lPfK(PIp~uEoIU5>&;cLl^WfL4) z?1W-lDb&MrS(u)aeBp(O`c;M{YviI93CNeWe~F_4FYE3A8&%}L?5Jfa)jhrjiN@@#X87*8M@Ek_70NWvI<^9>SQP&Yicu{N;zU(i+!}=en zl7>#)G&m7(XGm@G^gWJ>Xh4~VlZBcjj*x)qTQz#Y$_#Gxjz z%gdcy?&glPtm{e7)B!#HqUFlKm>iCJyJrWnptmlV7DWuZ)Z@;2v>;$9!r9170ankC{)se2-7gz&OGV9J=mnhP>y*>bkzRMw)SIDOniSr|V9t zuZNv9f7jykEglhNs%#3Qkj)5C64x!7gGviI`IZ$!Ic7=}T3FjmsOP9h^|+{^MDFj= zcQCj4;%E0ORv-96Dnn-)bvxq81ryDtmL4x1OQd=5)#=y<{6cQ>1f-O4EE`O&&tatg zIc;jUC<(z}f@lqfVmE{s!4eiR+1YfeYdP(#2ttCeP{k{L0S@-P#HNA35+`&*^=HfX z^T4U4^zu0oO>u?yR;z$?_IjDZLaw#sR!S{gb0#sy4bHt;A%5E2EaThA&~eE%ofB_( zKf&b6ykEf&slW68mpxAmIpGAEM8G(DZY^@HYO@-KJ;n{*r3#gfMd=~0sfT4b(meOmIOf`^ zl-b2wi07rTe`cGiY%F)3@Fym?%GEeCT>RD)VnVL!s!4~s_Z;VZ*DC9)@!%y zt^S`~`INW0A-Ep(ttLU}x)%5Wt5YjT>AVZJGhcm9w#T#D)2obn>Qt<*vLn*h)AtuA zmMC&VW>+`#4S)M(5Z381Ck8{Pc#RNlKq%lJvm=?msrCQ}Z%aUW* z+w+$`4=N+&8NFyKs6FDq+}Q6k`P1bUu1zZdcX--*E?zFcpDN0%y;#*sn2nhDJr*w4 ztltyuJ;e7;T21WtNh1Pv_LqH32ek2PIL)$ftt!%RaShREz=Jwu6C$Wr${w%!3Phfk z=&RU9+2ML((x~+Hlh0`81BUlM_QG@Q>eYs=h7Q9VP$TSNS(C0ugE(L?p$(5=R;;2o zY1TAaepTa0P_2V*VH_euZAGeys|I9X?7Q*Y>t{4|p7q~#z*7@&%koS|NvC z`fxP zOW#ZHjK0X*=&_YwMu;ddRCQ@7p;Wg@Bc#lx(m;UNRIH7-MVB&2M%3$QzQ-?{p6)XTyVz*+u^A);c*G|9=Ai`zQa) zhl<7ge)g?>J;kKl|Dyl<@&1$BfBDoT{t%xd*pT?`k4H?1EBReS+&XS58 zDF;Ejz$-WvpVMQ68Bq%hHd1!tAr?FzOcqS%zu00 zyn2Ae-||mHo?gg!pCS@Qa9MaX)@0}Ax54{$F{S4^90`4Rhp~eu?qz5hT4H}q+hqHM zQ&*B$_oJ+najQd6YO!EWp`MQBb*kfw5@%7bIbn~cMBCrQekZK`47g*YbDSd`zE@pY8;8;Ek`{6m&!Ww+8d_`>9 z2!iD_r&4gZAzW@qN_w>^6gtD{dx*E*CvCvq8Yn9+Q(W$qV^Q!Sc%DDq#c}pyBy8n= zG0r#UD@u)a34SqQwHGEeG=xf}%#94vvXoHb8$xNu;_Dg~gZ?Zu^R?&o0 z_-vDs59`5x-=)}uho(KlMud>(RSRf*H(Ig9%2Y@z7aD5NQa8MqraT%xq@{r_Z2A^v z4Asg7fR)HGE)wMw_VtkC(Xx7NYug*6j|EZKI($Hw*pz>IQ-Zo84A;2iM7oV{LSSYA z7=kevYT*V{VFz-@pjcFrzQCSvoZTVoR9lYc9s7U*_g7f}QK~qrj}bXRt5Q&)kNGs` zdBTn~_eqv4$(!oy)Wgk2li6_3V?JsiR>XoY2MmP|t)eg;n9g27DCn&UqEVk9!P(D| z_QnK>04QiEKumO0R1|bH0P+t7fJ%f$NKC@Wht9wc($cnM67UGMddpitD&y`MCaaV3 z$EFx63d(PrV%8Pln}n_aiW}=Lx?I#(@)ja(1@dKz)#PgChWMw3Xk8W}|G!5Q(h5E) zwRb=--59`+ezxB}fYjLAvzKnjf?)f*AzE8C3Orc#cT6wc$W^_fhaq#@eFor!>vvG! z-yk$(5Z3P?GNdYd*jy1Zo_*S30an7>i#L7(e)nlDotAo=V*x!V;!{hhH0Px?k1~phJBOk3?ok+4x<7^-B}a?rXa{Ro z{tjND5i3X+j@A4CQxF@RLKt+h=bVR*r5*%HGAZe0(+dmVsXp>KQ7K+0nGtZxAF0TLyg4=*y^XR_FQ70t<#`DCl%f73 zW#9v}NlTC9k%87|aQroqA7>6?3m40%9`mfCPY{=s5z6^Mwl$>h}_FTJ*l zu&A;PyEOn`aP?wYcO$FI{SBT8C4Lb=!S@KswKwy3l^t*5Q7357t7qy}1lY$Jc_XTK z1*F5g;;mT%&#*#hMD$Mk1XE!|#P8pWpBkE=X>j;4klAH|Pm?rEB$O){Y)~CVWPrN6 z7m(f&G=H0Svu0aZ6MXq$Pth+-2=RPm3X;iQXl(`G#TBw_$-05uJ{dVDMTA!v$PMPt@Uchw$)i<<#Ouw|aPFsjR7^M!u?sTHd@O`ts#7zNgeQOu zIDO=Zmw=Y@Uw)Q`2?^^_O?pE5yzONAX=4?V9e7n9FfeF_705hrxVqFcX8OjPGf1XI zRS58XHS&Yq2Lp@ao13~K@oN&=epjT`nO$)A`U{ukS9P8AgRk|L4UB8?^?Ku_LEU7% z@wyEB1~T|^DiPGE9XK)dCXn}?wWF~gSw&MoXm67fW$@TKjINTV-5^w`1*M;97mSDM z7>gM6Fwr3UWG`@X`;1#=D@HvlL04tqf=eD*TYN&C-kpcgrsv;(0ZLTfk?>4(K56-8 z{ib3=BH9~8;IjE>9bu~HozP=OJa!RG<>x7zxzk3^ zNXqBQn1p07D4&MaC~sBetEGclfg32g9dasd%(2pVv1*RMXIVVzrFw&oX^0mN@ZSZb zmDG4%X{bULpC92HCWKwbBmcRb^x@VfQDhpUWm9(9Fomz_SB=pcaE&3Ykdw8InHbF3 zO=kn}tN1SJG(G+L(+#t>ykje@Gr!YMTYoK0d+%+r>WOSKwF zIcI!2bAFes?G4P|!xtob8$o^5`?7MST)coa7vEMVd3@ebzjE^gJ2Zb{hX>%bAiT-{ zLW~{UhUpX`)PrMkDAJ-i`w>eAN(aP$pru8s9uRsGR^?<`pm1j8 zL^12?hF}|vIC)3`-Y{JTDR(C5&(^lnuO3dN-kfYRWD74=Jo7Sa=hTQ-9E zbKbiXlBM44(ZuLp8jj(IEadIOvMSa}7y(OoOCmz(Ts0pa?VTmr;ZD1H2}?wj%{}Uz z+;3x8)rr3d6NTp--C4vcTsEz6R+fXVw0k09GR{(&+W1Nvl@98neb&OFO-3B zQrA@~Z7U+fV;e&$t}$rI-^E=zSBlU-t;KX#nvIzGk%2-38)DNb%)_Z*d< zMK%Zam^4ex=ZP?&)^_s)g<8Z480>2z3fe?~5r&Vk^1;IBhM%13R}zzRUkK}erk4m` zk-E_JmsvsAT`RQGWZ$9PwD0#ZXwj+M`plm7lc|&>_scTr9Mjn8!Gvo5PDF2xf-jMU z@E40_!vkk!g$ic5l}r$po@d}%5DK-1Q+zDSFe^@_Z6X|rZ}WSU!N0pY1s|`dczuy|$G-kSjs!TQG4p-8C ztwdqlN!*tXP6ayaP$tw@B5A{7wJC`qD(uFOvA;(ggkxvcq0b9q8QzneReG?se~PnN zBhH#a%n^V|57hvO9Oa~x+$AOfnPh*0oMP5yzP_Sly&IFu_9mgycNR{yB87qIosX!A zEDTWF2(3Z0qdMRd)Hv!TZ?onf%g%)znh(i7c>+0Nuek?l_e50-H)W+%j40z6> zVF4o-C7wm~qW9ah%lHg00e5e# zy;&ITh|rSz1pr{WW6Q~xeq!KGXY=$Es2B9suvbgJ7Q|>X6DV{J&&8TOtm)r?PGlm- zneXimIL>43Om|yiWst~cSrN2qJ9T#Pg}UFBBl_vYxON~BPJ~+CsM&7V2F0OR9XRub zcud6{IEs1<&YjF}8)e>(`Bw`|@P8>)N?VL-6ZHPWw#FakzPeuFP!!$3P^t^i$zk}~ zf*8Wnv)lFDF8gv~jA%{gojn`Zj-YHp{&sG=`6GnZOQ_b%(Ci12A0_7owkKgbJEjD z@6^IJy#*{F5bzS{BgigE>u79Ju*c*wfha*C# z@zQ>tbhwX78b$wqih0j$=}uh%v}tU%iCIT`vi(v_#^rW$qx1RMznr-F0QMQ>*PS~| zqGzg&$DzhH^3ixi+X~o7CTH8y|8wld-n2iBR?tvmY)VZ7*kH0#oihRwa_jC{%s8yfX5bAn6EJOSjcYpZ*{zr zSBh}5T%S*|KzG^zBbaPd$W%88X)S3>SQHJZhaWD#1dz^}z~Jk^f(gk=$FbAn zc+M#8hnHpSoMxRm zHNkj_)ezwaAqq~8Up>hT#jEvS8dhI480{jXhV0Yhrnt!7>2p2(KfxR=)YKTx{~afG zJ%a*hfhLSy73Bt|D8W#HGc^k4#MTZI7y1Z6_sGV|&bkV(sGTDbq2p`-mXLq9u7 zozuX}&CM+S1sKh{={X_DaCiv9RAKwhc)%?(qSGvCZcu!zxDPG=Nzy`J=v(>=kmOr* zr7{0HcIC~CgsR?GuiwELt5v^$(cC&Cfn0bVwmeY7C;gKouh16>2ut$Kxcx(=`X`}x z(beR__2j4D$G~jWce!J8@b5#)0a|qoE&eIcoLB0bdNn!w8Y0lX%s4sVjU>e68!a`% zXUj84R!KKCAN=+vhE<5C@I%B%WUP2R#xpi2Jh?;oW5aUDQh6cX;iw(?d+Q=i^u#^p zn!G4h;VN`G%VFex2UfJU#-rqxin~mUh1LP+WKfgLPI6`ot3^X2z6LQJ8(qConYi(C zStq}AF2hBQZCNVWX*|JbY(UPfhguNKFuQ!Izk*@Cr5E}AmgfMaBy04E2I#d}&RXwO zxrxOPym*Q*<=K}eX|RorU68I==(@24sy~z}4`x0mbR$j9H{D++er5S7WG?hm$h04c z{KGZ)*2k!zEm6$@t(qU>Y?%TLKoCZA7KB&GF71nHz%w2nYJ5b{3+*scA__`-J*0LIvHv-Skh+B(K8LXLb_G)2c5Q##*H zD0fnAx6Qa5-WU7tcKRq>le{-M>qI)3v0bGKJjK9uYbSYh8WOH_&Q}N)DirSNO}$2J zNDyBT^NLgitl$FK^{npg;f zE46@c?ftFvF-7)h+cKw5%^uO4A+iK+u=H?|Sm?(U3RVg>FSPolu?X27n(dj{p@0!h zK%HTm-r~`?<9%H|uhoq_)Hd(UEGvU9NjvnB=cjgvkB4WZE(2byj2(cnht;4BG)KxWs5VlwmijN| zCl$Y|k*n(#bv=(s>~=5Oh=2+Cpr+RI!gx{mGIwb^FQ0z}(e6!JoymFfr{5ZdGm&;i zo7FE~l2i zq=+!i)hlD#6r_cqxh&xl>@KpDH~lE582p=`a>1hgB@axR7`S*Uas+qIf0@iZ4Wx3Yli~5POq~q!^p5gOc zdPvP{&&hXZ#8}M!CAadaUO7*y_h2Hd1y-wBVPSdxI9e-`o)9@|+2%I9UYFI?e;y9q zc-P!9G5N`$y|DQ7B-oqBmLb&43u9#6aD|$R`&fsC;t}YBL@!Wb-KVCNv4Ov-@ghQe zU@=phJT7L@Mn7}u{SqRx9qSdN|P_D&k-SgBx>=e zWTch*J~Z(C>$^qe3W%mVwgd>!q*Lj1F83nHVuZZsG2@B18%dy_)Sn6zpZ{_IJc#mQ=jp%>YY%JZ=xQ<}^tB}!D$~Dk z<0lMLjl>Kj-Zwo?OtP|+oJ`zubNzg;_*vj)d_Vu|3;4zyVY$27-mrQKvoMojg{s~A z=ztJMn%DcAa$JBgT_)WM%@=N1&%DeBf3w${Lu<*e}Fm~Rs zy#ia+34$CY0i6_Hbiegk;WjH1r;wNjOE}?iB@-J<kB0}KHErD8v2xcimQEoIDy3^#RFpNDi#gS{L}ep26l z0kCsTvS#|Q>-;#Tv1Xn+pHg^;D;`6hX}VzVx?6RN*OVEerBV&BqY4ogQfLa+>?T>8 z$W~+S@-gurvT416`A~MpE->7x6>U9r4>3g(PlIYmmHLR@mHO!AGdu-|$Z*;qC<1Rs zOe2y^!l9rBkCzjR;i`+J&bz|+mm0shw@Xl;_ul&rc`DGyio#rMvfC>wXpjGPyamP> z4~kGLXElxcDE&^ylHMQhDY|8^EMJONPcz|y;!@zqIi(_=!DJKug)|TelxRIW!@%GK z%a0F+I0%!M3-bYF8`+W3xROW|#{34wF2(Fx5gcrn< zZ`Ksmptw$h)Jgcvoe4$j{pX}QBf|%2BOg&#YQ5@m8}`I9C#4e3hWR{$Ool`|`t-z- zg9Z@~y&x|q-x?c`G6+Fxb4NCm#`9}pEfRr4A7czj6qU2m!^u{&|F#RHL9;;+Nq^4@ zrKssHuX_ReOLx1(y}supYcfx^crTpKWv$TMCv4S&c3JaCMeL1UyT@&YLqe>!H8&*j zZ1D8QcX9Bk!-<75=Jz@6q~m&D=@j|r{O$%$?|J3Us-IFAVg`lwp3y3G<2FA*NZfRU&q0V4ZF?NpPF<;{>UQd34XAuuIe55!6bD&yCM~BNHD7>tD zzwZfhu5Pd7bD-!4jzP zOaba+CkBwcl1I&(C|YNQ2+EYm>WKuL0*qX|{zFoDx!fb{)M2=Lwg+hyE=gvTC$<>{ zk6{K&OqP~Bi9%?5dN_vVSB=DNH`l%Af8NRm^$c$}6l7bNwn-56l$y1BWL0y*uujYz zCjBjm;|-wN7sFbA?*%IhXR`%U!Tfmd()B3{2{msc_cWORXSqeE*Pn{~mm1$u6Gr^~ z#8@UuCU$1=M{8*(-#72A$E$orcvKaN_m0S+O}Ne`1X0$IfJG z(QWtK9m~XEb$MB?NiB3MAMSF9sfjs+As;%3_!>Eg_jHf9OKoqF z{6YYtf5v+Yp+P!%yTgqpz9};ASe`I@whSN@xXap2Iem&?e27P|bWYvfbU{=ei=v?m zY9fA7+jApUZ#SAiKk?wxUjR#t%ZFnGGkQt05Ov#!6xbnSnf*5;JlNVLD#(Q8pGxw|%yHiE#X0BpXV3z)3C8pV^;LgB7iK&naE;#g#Ab!uO>FYsJw^Q;=Rp6ef|<^X$^YbmzjdRC z2bR_rYrcxSf2?X$IZKQd8@Y?Mr>}sY1@vB z_Gi&;y#x4Y+cn)k)RgzL1Z)x7oca4y9~KGTq=d}++Fugs@P`0p-!L*9h@q=)rs z{4UPUGwsFzm0%^Uj}jUsKiM?zt$ZFJkU!x2Luvi(Sp!qdim%^q`Vc7eZg3=_$_UK~ Y2|!rj)UEiZR{gmlw{rgl__h510gG;}-~a#s literal 0 HcmV?d00001 diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst b/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst new file mode 100644 index 00000000000..a63714a5349 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/doc/index.rst @@ -0,0 +1,274 @@ +.. _raytac_mdbt53_db_40_nrf5340: + +Raytac MDBT53-DB-40 +################### + +Overview +******** + +Raytac MDBT53-DB-40 demo board is a development board based on the Raytac MDBT53-1M module, +using Nordic Semiconductor nRF5340 ARM Cortex-M33 SoC. Its design concept is to connect all +of the module's pins to 2.54mm pin headers. It is convenient for developers to verify whether +the modules are connected to other peripheral devices or sensors as a tool for software development. + +The nRF5340 inside the MDBT53-1M module is a +dual-core SoC based on the Arm® Cortex®-M33 architecture, with: + +* a full-featured Arm Cortex-M33F core with DSP instructions, FPU, and + Armv8-M Security Extension, running at up to 128 MHz, referred to as + the **application core** +* a secondary Arm Cortex-M33 core, with a reduced feature set, running + at a fixed 64 MHz, referred to as the **network core**. + +The raytac_mdbt53_db_40_nrf5340_cpuapp build target provides support for the application +core on the nRF5340 SoC. The raytac_mdbt53_db_40_nrf5340_cpuapp build target provides +support for the network core on the nRF5340 SoC. + +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + +nRF5340 SoC provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* :abbr:`QSPI (Quad Serial Peripheral Interface)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/MDBT53-DB-40.jpg + :width: 442px + :align: center + :alt: MDBT53-DB-40 + + MDBT53-DB-40 (Credit: Raytac Corporation) + +More information about the board can be found at the `MDBT53-DB-40 website`_. +The `MDBT53-DB-40 Specification`_ contains the demo board's datasheet. +The `MDBT53-DB-40 Schematic`_ contains the demo board's schematic. + +Hardware +******** +- Module Demo Board build by MDBT53-1M +- Nordic nRF5340 SoC Solution +- A recommnded 3rd-party module by Nordic Semiconductor. +- Dual-core Arm® Cortex® M33 +- 1MB/256KB Flash Memory; 512kB/ 64kB RAM +- Supports BT5 Long Range Features +- Bluetooth specification v5.2 +- Supports Bluetooth Direction Finding & Mesh +- Supports Bluetooth low energy audio +- Certifications: FCC, IC, CE, Telec (MIC), KC, SRRC, NCC, RCM, WPC +- RoHs & Reach Compiant. +- 48 GPIO +- Chip Antenna +- Interfaces: SPI, UART, I2C, I2S, PWM, ADC, NFC, and USB +- Highly flexible multiprotocol SoC ideally suited for Bluetooth® Low Energy, ANT+, Zigbee, Thread (802.15.4) ultra low-power wireless applications. +- 4 User LEDs +- 4 User buttons +- 1 Mini USB connector for power supply +- SWD connector for FW programing +- J-Link interface for FW programing +- UART interface for UART communication + +Supported Features +================== + +The raytac_mdbt53_db_40_nrf52840_cpuapp board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| QSPI(M) | on-chip | nor | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +The raytac_mdbt53_db_40_nrf5340_cpunet board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. +See `MDBT53-DB-40 website`_ and `MDBT53-DB-40 Specification`_ +for a complete list of Raytac MDBT53-DB-40 board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.28 +* LED2 (red) = P0.30 +* LED3 = P0.31 +* LED4 = P0.29 + +Push buttons +------------ + +* BUTTON1 = SW1 = P0.24 +* BUTTON2 = SW2 = P0.08 +* BUTTON3 = SW3 = P0.23 +* BUTTON4 = SW4 = P0.09 + +UART +---- +* RX = P0.22 +* TX = P0.20 +* RTS = P0.19 +* CTS = P0.21 + + +Security components +=================== + +- Implementation Defined Attribution Unit (`IDAU`_) on the application core. + The IDAU is implemented with the System Protection Unit and is used to + define secure and non-secure memory maps. By default, all of the memory + space (Flash, SRAM, and peripheral address space) is defined to be secure + accessible only. +- Secure boot. + +Programming and Debugging +************************* + +nRF5340 application core supports the Armv8-M Security Extension. +Applications built for the raytac_mdbt53_db_40_nrf5340_cpuapp board by +default boot in the Secure state. + +nRF5340 network core does not support the Armv8-M Security Extension. +nRF5340 IDAU may configure bus accesses by the nRF5340 network core +to have Secure attribute set; the latter allows to build and run +Secure only applications on the nRF5340 SoC. + +Applications for the ``raytac_mdbt53_db_40_nrf5340`` board configuration can be +built, flashed, and debugged in the usual way. See :ref:`build_an_application` and +:ref:`application_run` for more details on building and running. + +.. note:: + Flashing and Debugging Zephyr onto the raytac_mdbt53_db_40_nrf5340 board + requires an external J-Link programmer. The programmer is attached to the J1 + or J9 SWD connector. + + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. warning:: + + The nRF5340 has a flash read-back protection feature. When flash read-back + protection is active, you will need to recover the chip before reflashing. + If you are flashing with :ref:`west `, run + this command for more details on the related ``--recover`` option: + +Here is an example for the :ref:`hello_world` application. + +Use a USB to TTL converter to connect the computer and raytac_mdbt53_db_40_nrf5340 +J10 connector. Then run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the USB to TTL converter +can be found. For example, under Linux, :code:`/dev/ttyUSB0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: raytac_mdbt53_db_40_nrf5340 + :goals: build flash + +Debugging +========= + +The ``raytac_mdbt53_db_40_nrf5340`` board does not have an on-board-J-Link debug IC, +however, instructions from the :ref:`nordic_segger` page also apply to this board. +Use the Debug out connector of nRF52x DK to connect to the J1 connector, and use SEGGER +J-Link OB IF to debug. + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic +boards with a Segger IC. + + +References +********** + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _MDBT53-DB-40 website: + https://www.raytac.com/product/ins.php?index_id=139 +.. _MDBT53-DB-40 Specification: + https://www.raytac.com/download/index.php?index_id=60 +.. _MDBT53-DB-40 Schematic: + https://www.raytac.com/upload/catalog_b/8b5e364600a9cc8c53a869733e97f07e.jpg +.. _J-Link Software and documentation pack: + https://www.segger.com/jlink-software.html diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/pre_dt_board.cmake b/boards/arm/raytac_mdbt53_db_40_nrf5340/pre_dt_board.cmake new file mode 100644 index 00000000000..fb045e38545 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/pre_dt_board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - flash-controller@39000 & kmu@39000 +# - power@5000 & clock@5000 +# - /reserved-memory/image@20000000 & /reserved-memory/image_s@20000000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.dts new file mode 100644 index 00000000000..aed84474a38 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts" + +/ { + model = "Raytac MDBT53-DB-40 NRF5340 Application"; + compatible = "raytac,raytac-mdbt53-db-40-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_image; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; + +zephyr_udc0: &usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml new file mode 100644 index 00000000000..4f70a9e375d --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml @@ -0,0 +1,22 @@ +identifier: raytac_mdbt53_db_40_nrf5340_cpuapp +name: RAYTAC-MDBT53-DB-40-NRF5340-application-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 448 +flash: 1024 +supported: + - gpio + - i2c + - i2s + - pwm + - qspi + - spi + - uart + - watchdog + - usb_cdc + - usb_device + - netif:openthread diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi new file mode 100644 index 00000000000..dabb02cc3c4 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c1_default: i2c1_default { + group1 { + psels = , + ; + }; + }; + + i2c1_sleep: i2c1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart0_default: uart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + uart1_default: uart1_default { + group1 { + psels = ; + }; + group2 { + psels = ; + bias-pull-up; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = ; + }; + }; + + pwm0_sleep: pwm0_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; + + qspi_default: qspi_default { + group1 { + psels = , + , + , + , + , + ; + }; + }; + + qspi_sleep: qspi_sleep { + group1 { + psels = , + , + , + , + , + ; + low-power-enable; + }; + }; + + spi2_default: spi2_default { + group1 { + psels = , + , + ; + }; + }; + + spi2_sleep: spi2_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + spi3_default: spi3_default { + group1 { + psels = , + , + ; + }; + }; + + spi3_sleep: spi3_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + spi4_default: spi4_default { + group1 { + psels = , + , + ; + }; + }; + + spi4_sleep: spi4_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts new file mode 100644 index 00000000000..5c67687a002 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "raytac_mdbt53_db_40_nrf5340_cpuapp_common-pinctrl.dtsi" + +/ { + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + nordic,802154-spinel-ipc = &ipc0; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "Red LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + label = "LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "LED 3"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1 (SW1)"; + }; + button1: button_1 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2 (SW2)"; + }; + button2: button_2 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3 (SW3)"; + }; + button3: button_3 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 4 (SW4)"; + }; + }; + + gpio_fwd: nrf-gpio-forwarder { + compatible = "nordic,nrf-gpio-forwarder"; + status = "okay"; + uart { + gpios = <&gpio1 1 0>, <&gpio1 0 0>, <&gpio0 11 0>, <&gpio0 10 0>; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + pwm-led0 = &pwm_led0; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + bootloader-led0 = &led0; + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; + watchdog0 = &wdt0; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c1 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&qspi { + status = "okay"; + pinctrl-0 = <&qspi_default>; + pinctrl-1 = <&qspi_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi2 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&spi2_default>; + pinctrl-1 = <&spi2_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi4 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&spi4_default>; + pinctrl-1 = <&spi4_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@50000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@80000 { + label = "image-1"; + }; + slot1_ns_partition: partition@c0000 { + label = "image-1-nonsecure"; + }; + }; +}; + +&ieee802154 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_image: image@20000000 { + /* Zephyr image(s) memory */ + }; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_ns: image_ns@20040000 { + /* Non-Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "raytac_mdbt53_db_40_nrf5340_cpuapp_partition_conf.dts" diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig new file mode 100644 index 00000000000..86ab484940a --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts new file mode 100644 index 00000000000..541de94d8cc --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts" + +/ { + model = "Raytac MDBT53-DB-40 NRF5340 Application"; + compatible = "raytac,raytac-mdbt53-db-40-cpuapp"; + + chosen { + zephyr,sram = &sram0_ns; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; +}; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml new file mode 100644 index 00000000000..5c402d46273 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml @@ -0,0 +1,21 @@ +identifier: raytac_mdbt53_db_40_nrf5340_cpuapp_ns +name: RAYTAC-MDBT53-DB-40-NRF52840-application-MCU-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 192 +flash: 192 +supported: + - counter + - i2c + - pwm + - watchdog + - spi + - uart + - usb_cdc + - usb_device + - netif:openthread + - gpio diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig new file mode 100644 index 00000000000..26f206727c9 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_ns_defconfig @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_partition_conf.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_partition_conf.dts new file mode 100644 index 00000000000..74788769f01 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpuapp_partition_conf.dts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for raytac_mdbt53_db_40_nrf5340 CPUAPP (Application MCU). + * + * Zephyr build for nRF5340 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot0_ns_partition { + reg = <0x00050000 0x30000>; +}; + +&slot1_partition { + reg = <0x00080000 0x40000>; +}; + +&slot1_ns_partition { + reg = <0x000c0000 0x30000>; +}; + +/* Default SRAM planning when building for nRF5340 with + * ARM TrustZone-M support + * - Lowest 256 kB SRAM allocated to Secure image (sram0_s) + * - Middle 192 kB allocated to Non-Secure image (sram0_ns) + * - Upper 64 kB SRAM allocated as Shared memory (sram0_shared) + * (see raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts) + */ +&sram0_image { + reg = <0x20000000 DT_SIZE_K(448)>; +}; + +&sram0_s { + reg = <0x20000000 0x40000>; +}; + +&sram0_ns { + reg = <0x20040000 0x30000>; +}; + +/* Include shared RAM configuration file */ +#include "raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi new file mode 100644 index 00000000000..33b38bb76db --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts new file mode 100644 index 00000000000..b10848e4a28 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.dts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "raytac_mdbt53_db_40_nrf5340_cpunet-pinctrl.dtsi" +#include "raytac_mdbt53_db_40_nrf5340_cpunet_common.dts" + +/ { + model = "Raytac MDBT53-DB-40 NRF5340 Network"; + compatible = "raytac,raytac-mdbt53-db-40-nrf5340-cpunet"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,sram = &sram1; + zephyr,flash = &flash1; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci-rpmsg-ipc = &ipc0; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + watchdog0 = &wdt0; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.yaml b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.yaml new file mode 100644 index 00000000000..bf82a0627c1 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet.yaml @@ -0,0 +1,21 @@ +# Raytac MDBT53_DB_40_NRF5340 board configuration + +# Copyright (c) 2023 Raytac Corporation +# SPDX-License-Identifier: Apache-2.0 +identifier: raytac_mdbt53_db_40_nrf5340_cpunet +name: RAYTAC MDBT53-DB-40-NRF5340-network-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - watchdog + - gpio + - i2c + - spi + - uart + - counter diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_common.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_common.dts new file mode 100644 index 00000000000..c04101e11c1 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_common.dts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&flash1 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x17000>; + }; + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 0x17000>; + }; + storage_partition: partition@3a000 { + label = "storage"; + reg = <0x0003a000 0x6000>; + }; + }; +}; + +/* Include shared RAM configuration file */ +#include "raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig new file mode 100644 index 00000000000..ed5249f0a0d --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUNET_QKAA=y +CONFIG_BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUNET=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_reset.c b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_reset.c new file mode 100644 index 00000000000..97ae3fc1bd0 --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_cpunet_reset.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2021 Nordic Semiconductor ASA. + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(raytac_mdbt53_db_40_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); + +#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) +#include <../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h> +#else +#define DEBUG_SETUP() +#endif + +static void remoteproc_mgr_config(void) +{ +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) + /* Route Bluetooth Controller Debug Pins */ + DEBUG_SETUP(); +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) */ + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Retain nRF5340 Network MCU in Secure domain (bus + * accesses by Network MCU will have Secure attribute set). + */ + NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; +#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) */ +} + +static int remoteproc_mgr_boot(const struct device *dev) +{ + + /* Secure domain may configure permissions for the Network MCU. */ + remoteproc_mgr_config(); + +#if !defined(CONFIG_TRUSTED_EXECUTION_SECURE) + /* + * Building Zephyr with CONFIG_TRUSTED_EXECUTION_SECURE=y implies + * building also a Non-Secure image. The Non-Secure image will, in + * this case do the remainder of actions to properly configure and + * boot the Network MCU. + */ + + /* Release the Network MCU, 'Release force off signal' */ + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + + LOG_DBG("Network MCU released."); +#endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ + + return 0; +} + +SYS_INIT(remoteproc_mgr_boot, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts new file mode 100644 index 00000000000..aa162f85a5a --- /dev/null +++ b/boards/arm/raytac_mdbt53_db_40_nrf5340/raytac_mdbt53_db_40_nrf5340_shared_sram_planning_conf.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Raytac Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default shared SRAM planning when building for nRF5340. + * This file is included by both nRF5340 CPUAPP (Application MCU) + * and nRF5340 CPUNET (Network MCU). + * - 64 kB SRAM allocated as Shared memory (sram0_shared) + * - Region defined after the image SRAM of Application MCU + */ + +/ { + chosen { + /* shared memory reserved for the inter-processor communication */ + zephyr,ipc_shm = &sram0_shared; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_shared: memory@20070000 { + /* SRAM allocated to shared memory */ + reg = <0x20070000 0x10000>; + }; + }; +}; From 73a87d14dfc4e00f1722aa35f8644194eef3081d Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Mon, 5 Jun 2023 17:04:01 +0800 Subject: [PATCH 0327/4498] boards: arm: add raytac_mdbt53v_db_40_nrf5340 Adds new raytac_mdbt53_db_40_nrf5340 board. Signed-off-by: Stanley Huang --- .../CMakeLists.txt | 7 + .../arm/raytac_mdbt53v_db_40_nrf5340/Kconfig | 58 ++++ .../Kconfig.board | 18 ++ .../Kconfig.defconfig | 100 +++++++ .../raytac_mdbt53v_db_40_nrf5340/board.cmake | 12 + .../doc/img/MDBT53V-DB-40.jpg | Bin 0 -> 48287 bytes .../doc/index.rst | 264 ++++++++++++++++++ .../pre_dt_board.cmake | 8 + .../raytac_mdbt53v_db_40_nrf5340_cpuapp.dts | 22 ++ .../raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml | 20 ++ ...v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi | 95 +++++++ ...ac_mdbt53v_db_40_nrf5340_cpuapp_common.dts | 186 ++++++++++++ ...tac_mdbt53v_db_40_nrf5340_cpuapp_defconfig | 26 ++ ...raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts | 20 ++ ...aytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml | 16 ++ ..._mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig | 29 ++ ...3v_db_40_nrf5340_cpuapp_partition_conf.dts | 60 ++++ ..._mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi | 27 ++ .../raytac_mdbt53v_db_40_nrf5340_cpunet.dts | 40 +++ .../raytac_mdbt53v_db_40_nrf5340_cpunet.yaml | 20 ++ ...ac_mdbt53v_db_40_nrf5340_cpunet_common.dts | 60 ++++ ...tac_mdbt53v_db_40_nrf5340_cpunet_defconfig | 23 ++ ...aytac_mdbt53v_db_40_nrf5340_cpunet_reset.c | 60 ++++ ...b_40_nrf5340_shared_sram_planning_conf.dts | 30 ++ samples/net/wpan_serial/sample.yaml | 10 +- samples/net/wpanusb/sample.yaml | 8 +- 26 files changed, 1208 insertions(+), 11 deletions(-) create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/CMakeLists.txt create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.board create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/board.cmake create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/img/MDBT53V-DB-40.jpg create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/index.rst create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/pre_dt_board.cmake create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common-pinctrl.dtsi create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_defconfig create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns_defconfig create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpuapp_partition_conf.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet-pinctrl.dtsi create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_common.dts create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_defconfig create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_cpunet_reset.c create mode 100644 boards/arm/raytac_mdbt53v_db_40_nrf5340/raytac_mdbt53v_db_40_nrf5340_shared_sram_planning_conf.dts diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/CMakeLists.txt b/boards/arm/raytac_mdbt53v_db_40_nrf5340/CMakeLists.txt new file mode 100644 index 00000000000..556e084598c --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +if ((CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP OR CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS) + AND CONFIG_BOARD_ENABLE_CPUNET) + zephyr_library() + zephyr_library_sources(raytac_mdbt53v_db_40_nrf5340_cpunet_reset.c) +endif() diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig new file mode 100644 index 00000000000..5443d2b8486 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig @@ -0,0 +1,58 @@ +# Ratac MDBT53V-DB-40 nRF5340 board configuration + +# Copyright (c) 2019 - 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +config BOARD_ENABLE_DCDC_APP + bool "Application MCU DCDC converter" + select SOC_DCDC_NRF53X_APP + default y + +config BOARD_ENABLE_DCDC_NET + bool "Network MCU DCDC converter" + select SOC_DCDC_NRF53X_NET + default y + +config BOARD_ENABLE_DCDC_HV + bool "High Voltage DCDC converter" + select SOC_DCDC_NRF53X_HV + default y + +config BOARD_ENABLE_CPUNET + bool "NRF53 Network MCU" + select SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 if \ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GPIO_FORWARDER)) + help + This option enables releasing the Network 'force off' signal, which + as a consequence will power up the Network MCU during system boot. + Additionally, the option allocates GPIO pins that will be used by UARTE + of the Network MCU. + Note: GPIO pin allocation can only be configured by the secure Application + MCU firmware, so when this option is used with the non-secure version of + the board, the application needs to take into consideration, that the + secure firmware image must already have configured GPIO allocation for the + Network MCU. + default y if (BT || NRF_802154_SER_HOST) + +config DOMAIN_CPUNET_BOARD + string + default "raytac_mdbt53v_db_40_nrf5340_cpunet" + depends on BOARD_ENABLE_CPUNET + help + The board which will be used for CPUNET domain when creating a multi + image application where one or more images should be located on + another board. For example hci_rpmsg on the nRF5340_cpunet for + Bluetooth applications. + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +config DOMAIN_CPUAPP_BOARD + string + default "raytac_mdbt53v_db_40_nrf5340_cpuapp" + depends on BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET + help + The board which will be used for CPUAPP domain when creating a multi + image application where one or more images should be located on + another board. diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.board b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.board new file mode 100644 index 00000000000..69bb4b876ea --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.board @@ -0,0 +1,18 @@ +# Raytac MDBT53-DB-40 NRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF5340_CPUAPP_QKAA + +config BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP + bool "Raytac MDBT53V-DB-40 nRF5340 Application MCU" + +config BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + bool "Raytac MDBT53V-DB-40 nRF5340 Application MCU non-secure" + +endif # SOC_NRF5340_CPUAPP_QKAA + +config BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET + bool "Raytac MDBT53V-DB-40 NRF5340 Network MCU" + depends on SOC_NRF5340_CPUNET_QKAA diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig new file mode 100644 index 00000000000..54c3d6cccf0 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/Kconfig.defconfig @@ -0,0 +1,100 @@ +# Raytac MDBT53V-DB-40 nRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +config BOARD + default "raytac_mdbt53v_db_40_nrf5340_cpuapp" if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default n if BOARD_BL5340_DVK_CPUAPP_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default n + +endif # BUILD_WITH_TFM + +# Code Partition: +# +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# SRAM Partition: +# +# If the secure firmware is to be combined with a non-secure image +# (TRUSTED_EXECUTION_SECURE=y), the secure FW image SRAM shall always +# be restricted to the secure image SRAM partition (sram-secure-partition). +# Otherwise (if TRUSTED_EXECUTION_SECURE is not set) the whole zephyr,sram +# may be used by the image. +# +# For the non-secure version of the board, the firmware image SRAM is +# always restricted to the allocated non-secure SRAM partition. +# +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition +DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config SRAM_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_SRAM_PARTITION),0,K) + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +config BOARD + default "raytac_mdbt53v_dv_40_nrf5340_cpunet" if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET + +config IPM_NRFX + default IPM + +config MBOX_NRFX_IPC + default MBOX + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +choice BT_HCI_BUS_TYPE + default BT_RPMSG if BT +endchoice + +config HEAP_MEM_POOL_SIZE + default 4096 if BT_RPMSG + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP || BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS + +if BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET + +config BT_CTLR + default y if BT + +endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/board.cmake b/boards/arm/raytac_mdbt53v_db_40_nrf5340/board.cmake new file mode 100644 index 00000000000..8662675aba3 --- /dev/null +++ b/boards/arm/raytac_mdbt53v_db_40_nrf5340/board.cmake @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP OR CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS) + board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") +endif() + +if(CONFIG_BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUNET) + board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/img/MDBT53V-DB-40.jpg b/boards/arm/raytac_mdbt53v_db_40_nrf5340/doc/img/MDBT53V-DB-40.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e53ce08021813ec1cb662ec3996ee51a622ec3ca GIT binary patch literal 48287 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